From 10e29413bc92c2b4d17ab497353604a9015cd705 Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Fri, 8 Nov 2024 19:44:55 -0500 Subject: [PATCH 001/991] Remove unncesssary `compile-flags` directive --- .../conf_disallowed_methods.rs | 2 -- .../conf_disallowed_methods.stderr | 28 +++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs index 17fceae01780..0986290bb0e6 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs @@ -1,5 +1,3 @@ -//@compile-flags: --crate-name conf_disallowed_methods - #![allow(clippy::needless_raw_strings)] #![warn(clippy::disallowed_methods)] #![allow(clippy::useless_vec)] diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr index e77b2b959497..edda35d647ab 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr @@ -1,5 +1,5 @@ error: use of a disallowed method `regex::Regex::new` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:35:14 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:33:14 | LL | let re = Regex::new(r"ab.*c").unwrap(); | ^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let re = Regex::new(r"ab.*c").unwrap(); = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]` error: use of a disallowed method `regex::Regex::is_match` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:36:8 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:34:8 | LL | re.is_match("abc"); | ^^^^^^^^ @@ -16,73 +16,73 @@ LL | re.is_match("abc"); = note: no matching allowed error: use of a disallowed method `std::iter::Iterator::sum` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:39:14 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:37:14 | LL | a.iter().sum::(); | ^^^ error: use of a disallowed method `slice::sort_unstable` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:41:7 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:39:7 | LL | a.sort_unstable(); | ^^^^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:44:20 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:42:20 | LL | let _ = 2.0f32.clamp(3.0f32, 4.0f32); | ^^^^^ error: use of a disallowed method `regex::Regex::new` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:47:61 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:45:61 | LL | let indirect: fn(&str) -> Result = Regex::new; | ^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:50:28 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:48:28 | LL | let in_call = Box::new(f32::clamp); | ^^^^^^^^^^ error: use of a disallowed method `regex::Regex::new` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:51:53 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:49:53 | LL | let in_method_call = ["^", "$"].into_iter().map(Regex::new); | ^^^^^^^^^^ error: use of a disallowed method `futures::stream::select_all` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:54:31 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:52:31 | LL | let same_name_as_module = select_all(vec![empty::<()>()]); | ^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_fn` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:56:5 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:54:5 | LL | local_fn(); | ^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_mod::f` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:57:5 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:55:5 | LL | local_mod::f(); | ^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Struct::method` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:59:7 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:57:7 | LL | s.method(); | ^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::provided_method` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:60:7 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:58:7 | LL | s.provided_method(); | ^^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::implemented_method` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:61:7 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:59:7 | LL | s.implemented_method(); | ^^^^^^^^^^^^^^^^^^ From f159a3eb1dfc3b81088fce364a09e8a79968adda Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Fri, 8 Nov 2024 19:40:55 -0500 Subject: [PATCH 002/991] Support replacements in `disallowed_methods` --- clippy_config/src/types.rs | 38 +++++++++++++++++-- clippy_lints/src/await_holding_invalid.rs | 16 +++----- clippy_lints/src/disallowed_macros.rs | 13 ++----- clippy_lints/src/disallowed_methods.rs | 14 +++---- .../clippy.toml | 4 ++ .../replaceable_disallowed_methods.fixed | 8 ++++ .../replaceable_disallowed_methods.rs | 8 ++++ .../replaceable_disallowed_methods.stderr | 17 +++++++++ 8 files changed, 87 insertions(+), 31 deletions(-) create mode 100644 tests/ui-toml/toml_replaceable_disallowed_methods/clippy.toml create mode 100644 tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.fixed create mode 100644 tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs create mode 100644 tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.stderr diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index c949db9109de..70d9073b59ca 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -1,6 +1,8 @@ use clippy_utils::def_path_def_ids; +use rustc_errors::{Applicability, Diag}; use rustc_hir::def_id::DefIdMap; use rustc_middle::ty::TyCtxt; +use rustc_span::Span; use serde::de::{self, Deserializer, Visitor}; use serde::{Deserialize, Serialize, ser}; use std::collections::HashMap; @@ -16,7 +18,11 @@ pub struct Rename { #[serde(untagged)] pub enum DisallowedPath { Simple(String), - WithReason { path: String, reason: Option }, + WithReason { + path: String, + reason: Option, + replacement: Option, + }, } impl DisallowedPath { @@ -26,23 +32,47 @@ impl DisallowedPath { path } + pub fn diag_amendment(&self, span: Span) -> impl FnOnce(&mut Diag<'_, ()>) + use<'_> { + move |diag| { + if let Some(replacement) = self.replacement() { + diag.span_suggestion( + span, + self.reason().map_or_else(|| String::from("use"), ToOwned::to_owned), + replacement, + Applicability::MachineApplicable, + ); + } else if let Some(reason) = self.reason() { + diag.note(reason.to_owned()); + } + } + } + pub fn reason(&self) -> Option<&str> { match &self { Self::WithReason { reason, .. } => reason.as_deref(), Self::Simple(_) => None, } } + + fn replacement(&self) -> Option<&str> { + match &self { + Self::WithReason { replacement, .. } => replacement.as_deref(), + Self::Simple(_) => None, + } + } } /// Creates a map of disallowed items to the reason they were disallowed. pub fn create_disallowed_map( tcx: TyCtxt<'_>, disallowed: &'static [DisallowedPath], -) -> DefIdMap<(&'static str, Option<&'static str>)> { +) -> DefIdMap<(&'static str, &'static DisallowedPath)> { disallowed .iter() - .map(|x| (x.path(), x.path().split("::").collect::>(), x.reason())) - .flat_map(|(name, path, reason)| def_path_def_ids(tcx, &path).map(move |id| (id, (name, reason)))) + .map(|x| (x.path(), x.path().split("::").collect::>(), x)) + .flat_map(|(name, path, disallowed_path)| { + def_path_def_ids(tcx, &path).map(move |id| (id, (name, disallowed_path))) + }) .collect() } diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs index 2eb0566bf9a6..3ae7ab969150 100644 --- a/clippy_lints/src/await_holding_invalid.rs +++ b/clippy_lints/src/await_holding_invalid.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::create_disallowed_map; +use clippy_config::types::{DisallowedPath, create_disallowed_map}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::{match_def_path, paths}; use rustc_hir as hir; @@ -174,7 +174,7 @@ declare_clippy_lint! { impl_lint_pass!(AwaitHolding => [AWAIT_HOLDING_LOCK, AWAIT_HOLDING_REFCELL_REF, AWAIT_HOLDING_INVALID_TYPE]); pub struct AwaitHolding { - def_ids: DefIdMap<(&'static str, Option<&'static str>)>, + def_ids: DefIdMap<(&'static str, &'static DisallowedPath)>, } impl AwaitHolding { @@ -247,25 +247,21 @@ impl AwaitHolding { ); }, ); - } else if let Some(&(path, reason)) = self.def_ids.get(&adt.did()) { - emit_invalid_type(cx, ty_cause.source_info.span, path, reason); + } else if let Some(&(path, disallowed_path)) = self.def_ids.get(&adt.did()) { + emit_invalid_type(cx, ty_cause.source_info.span, path, disallowed_path); } } } } } -fn emit_invalid_type(cx: &LateContext<'_>, span: Span, path: &'static str, reason: Option<&'static str>) { +fn emit_invalid_type(cx: &LateContext<'_>, span: Span, path: &'static str, disallowed_path: &'static DisallowedPath) { span_lint_and_then( cx, AWAIT_HOLDING_INVALID_TYPE, span, format!("holding a disallowed type across an await point `{path}`"), - |diag| { - if let Some(reason) = reason { - diag.note(reason); - } - }, + disallowed_path.diag_amendment(span), ); } diff --git a/clippy_lints/src/disallowed_macros.rs b/clippy_lints/src/disallowed_macros.rs index a0cb36f88dc0..fe0870e8282f 100644 --- a/clippy_lints/src/disallowed_macros.rs +++ b/clippy_lints/src/disallowed_macros.rs @@ -1,9 +1,8 @@ use clippy_config::Conf; -use clippy_config::types::create_disallowed_map; +use clippy_config::types::{DisallowedPath, create_disallowed_map}; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::macros::macro_backtrace; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::Diag; use rustc_hir::def_id::DefIdMap; use rustc_hir::{ Expr, ExprKind, ForeignItem, HirId, ImplItem, Item, ItemKind, OwnerId, Pat, Path, Stmt, TraitItem, Ty, @@ -60,7 +59,7 @@ declare_clippy_lint! { } pub struct DisallowedMacros { - disallowed: DefIdMap<(&'static str, Option<&'static str>)>, + disallowed: DefIdMap<(&'static str, &'static DisallowedPath)>, seen: FxHashSet, // Track the most recently seen node that can have a `derive` attribute. // Needed to use the correct lint level. @@ -91,13 +90,9 @@ impl DisallowedMacros { return; } - if let Some(&(path, reason)) = self.disallowed.get(&mac.def_id) { + if let Some(&(path, disallowed_path)) = self.disallowed.get(&mac.def_id) { let msg = format!("use of a disallowed macro `{path}`"); - let add_note = |diag: &mut Diag<'_, _>| { - if let Some(reason) = reason { - diag.note(reason); - } - }; + let add_note = disallowed_path.diag_amendment(mac.span); if matches!(mac.kind, MacroKind::Derive) && let Some(derive_src) = derive_src { diff --git a/clippy_lints/src/disallowed_methods.rs b/clippy_lints/src/disallowed_methods.rs index 1e660b1957a4..0cd9ea13f2e5 100644 --- a/clippy_lints/src/disallowed_methods.rs +++ b/clippy_lints/src/disallowed_methods.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::create_disallowed_map; +use clippy_config::types::{DisallowedPath, create_disallowed_map}; use clippy_utils::diagnostics::span_lint_and_then; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefIdMap; @@ -31,6 +31,8 @@ declare_clippy_lint! { /// # When using an inline table, can add a `reason` for why the method /// # is disallowed. /// { path = "std::vec::Vec::leak", reason = "no leaking memory" }, + /// # Can also add a `replacement` that will be offered as a suggestion. + /// { path = "std::sync::Mutex::new", reason = "prefer faster & simpler non-poisonable mutex", replacement = "parking_lot::Mutex::new" }, /// ] /// ``` /// @@ -58,7 +60,7 @@ declare_clippy_lint! { } pub struct DisallowedMethods { - disallowed: DefIdMap<(&'static str, Option<&'static str>)>, + disallowed: DefIdMap<(&'static str, &'static DisallowedPath)>, } impl DisallowedMethods { @@ -85,17 +87,13 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods { }, _ => return, }; - if let Some(&(path, reason)) = self.disallowed.get(&id) { + if let Some(&(path, disallowed_path)) = self.disallowed.get(&id) { span_lint_and_then( cx, DISALLOWED_METHODS, span, format!("use of a disallowed method `{path}`"), - |diag| { - if let Some(reason) = reason { - diag.note(reason); - } - }, + disallowed_path.diag_amendment(span), ); } } diff --git a/tests/ui-toml/toml_replaceable_disallowed_methods/clippy.toml b/tests/ui-toml/toml_replaceable_disallowed_methods/clippy.toml new file mode 100644 index 000000000000..dc393f1355b5 --- /dev/null +++ b/tests/ui-toml/toml_replaceable_disallowed_methods/clippy.toml @@ -0,0 +1,4 @@ +disallowed-methods = [ + { path = "replaceable_disallowed_methods::bad", replacement = "good" }, + { path = "replaceable_disallowed_methods::questionable", replacement = "good", reason = "a better function exists" }, +] diff --git a/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.fixed b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.fixed new file mode 100644 index 000000000000..dae7ce76ba28 --- /dev/null +++ b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.fixed @@ -0,0 +1,8 @@ +fn bad() {} +fn questionable() {} +fn good() {} + +fn main() { + good(); + good(); +} diff --git a/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs new file mode 100644 index 000000000000..53678ffdf1c9 --- /dev/null +++ b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs @@ -0,0 +1,8 @@ +fn bad() {} +fn questionable() {} +fn good() {} + +fn main() { + bad(); + questionable(); +} diff --git a/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.stderr b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.stderr new file mode 100644 index 000000000000..b85592029420 --- /dev/null +++ b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.stderr @@ -0,0 +1,17 @@ +error: use of a disallowed method `replaceable_disallowed_methods::bad` + --> tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs:6:5 + | +LL | bad(); + | ^^^ help: use: `good` + | + = note: `-D clippy::disallowed-methods` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]` + +error: use of a disallowed method `replaceable_disallowed_methods::questionable` + --> tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs:7:5 + | +LL | questionable(); + | ^^^^^^^^^^^^ help: a better function exists: `good` + +error: aborting due to 2 previous errors + From d0f35777205090e24d5822e668cc280cab78e4ec Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Wed, 13 Nov 2024 10:16:59 -0500 Subject: [PATCH 003/991] Properly handle `disallowed_types` --- clippy_config/src/types.rs | 2 +- clippy_lints/src/disallowed_types.rs | 25 ++++++++----------- .../replaceable_disallowed_types/clippy.toml | 3 +++ .../replaceable_disallowed_types.fixed | 16 ++++++++++++ .../replaceable_disallowed_types.rs | 16 ++++++++++++ .../replaceable_disallowed_types.stderr | 11 ++++++++ 6 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 tests/ui-toml/replaceable_disallowed_types/clippy.toml create mode 100644 tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed create mode 100644 tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs create mode 100644 tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.stderr diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index 70d9073b59ca..122fdca726d5 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -47,7 +47,7 @@ impl DisallowedPath { } } - pub fn reason(&self) -> Option<&str> { + fn reason(&self) -> Option<&str> { match &self { Self::WithReason { reason, .. } => reason.as_deref(), Self::Simple(_) => None, diff --git a/clippy_lints/src/disallowed_types.rs b/clippy_lints/src/disallowed_types.rs index 3265404f2b27..a34ec4616e51 100644 --- a/clippy_lints/src/disallowed_types.rs +++ b/clippy_lints/src/disallowed_types.rs @@ -1,4 +1,5 @@ use clippy_config::Conf; +use clippy_config::types::DisallowedPath; use clippy_utils::diagnostics::span_lint_and_then; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::Res; @@ -31,7 +32,8 @@ declare_clippy_lint! { /// # When using an inline table, can add a `reason` for why the type /// # is disallowed. /// { path = "std::net::Ipv4Addr", reason = "no IPv4 allowed" }, - /// ] + /// # Can also add a `replacement` that will be offered as a suggestion. + /// { path = "std::sync::Mutex", reason = "prefer faster & simpler non-poisonable mutex", replacement = "parking_lot::Mutex" }, /// ] /// ``` /// /// ```rust,ignore @@ -51,24 +53,23 @@ declare_clippy_lint! { } pub struct DisallowedTypes { - def_ids: DefIdMap<(&'static str, Option<&'static str>)>, - prim_tys: FxHashMap)>, + def_ids: DefIdMap<(&'static str, &'static DisallowedPath)>, + prim_tys: FxHashMap, } impl DisallowedTypes { pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self { let mut def_ids = DefIdMap::default(); let mut prim_tys = FxHashMap::default(); - for x in &conf.disallowed_types { - let path: Vec<_> = x.path().split("::").collect::>(); - let reason = x.reason(); + for disallowed_path in &conf.disallowed_types { + let path: Vec<_> = disallowed_path.path().split("::").collect::>(); for res in clippy_utils::def_path_res(tcx, &path) { match res { Res::Def(_, id) => { - def_ids.insert(id, (x.path(), reason)); + def_ids.insert(id, (disallowed_path.path(), disallowed_path)); }, Res::PrimTy(ty) => { - prim_tys.insert(ty, (x.path(), reason)); + prim_tys.insert(ty, (disallowed_path.path(), disallowed_path)); }, _ => {}, } @@ -78,7 +79,7 @@ impl DisallowedTypes { } fn check_res_emit(&self, cx: &LateContext<'_>, res: &Res, span: Span) { - let (path, reason) = match res { + let (path, disallowed_path) = match res { Res::Def(_, did) if let Some(&x) = self.def_ids.get(did) => x, Res::PrimTy(prim) if let Some(&x) = self.prim_tys.get(prim) => x, _ => return, @@ -88,11 +89,7 @@ impl DisallowedTypes { DISALLOWED_TYPES, span, format!("use of a disallowed type `{path}`"), - |diag| { - if let Some(reason) = reason { - diag.note(reason); - } - }, + disallowed_path.diag_amendment(span), ); } } diff --git a/tests/ui-toml/replaceable_disallowed_types/clippy.toml b/tests/ui-toml/replaceable_disallowed_types/clippy.toml new file mode 100644 index 000000000000..a08a2f00f506 --- /dev/null +++ b/tests/ui-toml/replaceable_disallowed_types/clippy.toml @@ -0,0 +1,3 @@ +disallowed-types = [ + { path = "std::string::String", replacement = "wrapper::String" }, +] diff --git a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed new file mode 100644 index 000000000000..6546981bd81c --- /dev/null +++ b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed @@ -0,0 +1,16 @@ +#![warn(clippy::disallowed_types)] + +#[allow(clippy::disallowed_types)] +mod wrapper { + pub struct String(std::string::String); + + impl From<&str> for String { + fn from(value: &str) -> Self { + Self(std::string::String::from(value)) + } + } +} + +fn main() { + let _ = wrapper::String::from("x"); +} diff --git a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs new file mode 100644 index 000000000000..d76f1af481de --- /dev/null +++ b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs @@ -0,0 +1,16 @@ +#![warn(clippy::disallowed_types)] + +#[allow(clippy::disallowed_types)] +mod wrapper { + pub struct String(std::string::String); + + impl From<&str> for String { + fn from(value: &str) -> Self { + Self(std::string::String::from(value)) + } + } +} + +fn main() { + let _ = String::from("x"); +} diff --git a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.stderr b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.stderr new file mode 100644 index 000000000000..bb63e6970a16 --- /dev/null +++ b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.stderr @@ -0,0 +1,11 @@ +error: use of a disallowed type `std::string::String` + --> tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs:15:13 + | +LL | let _ = String::from("x"); + | ^^^^^^ help: use: `wrapper::String` + | + = note: `-D clippy::disallowed-types` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::disallowed_types)]` + +error: aborting due to 1 previous error + From b97ad4eccdfa8b360df243ecf21eec1fd05cb92a Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Wed, 13 Nov 2024 18:34:08 -0500 Subject: [PATCH 004/991] Add const parameter `REPLACEMENT_ALLOWED` to `DisallowedPath` --- clippy_config/src/conf.rs | 2 +- clippy_config/src/types.rs | 73 +++++++++++++------ clippy_lints/src/await_holding_invalid.rs | 9 ++- .../await_holding_invalid_type.rs | 1 + .../await_holding_invalid_type.stderr | 11 +++ .../clippy.toml | 3 + 6 files changed, 74 insertions(+), 25 deletions(-) create mode 100644 tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.rs create mode 100644 tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.stderr create mode 100644 tests/ui-toml/await_holding_invalid_type_with_replacement/clippy.toml diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index c3b1fc83af0a..82ab08530e1a 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -445,7 +445,7 @@ define_Conf! { avoid_breaking_exported_api: bool = true, /// The list of types which may not be held across an await point. #[lints(await_holding_invalid_type)] - await_holding_invalid_types: Vec = Vec::new(), + await_holding_invalid_types: Vec> = Vec::new(), /// DEPRECATED LINT: BLACKLISTED_NAME. /// /// Use the Disallowed Names lint instead diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index 122fdca726d5..6a0f7aa75f25 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -14,9 +14,33 @@ pub struct Rename { pub rename: String, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Serialize)] +pub struct DisallowedPath { + path: String, + reason: Option, + replacement: Option, +} + +impl<'de, const REPLACEMENT_ALLOWED: bool> Deserialize<'de> for DisallowedPath { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let enum_ = DisallowedPathEnum::deserialize(deserializer)?; + if !REPLACEMENT_ALLOWED && enum_.replacement().is_some() { + return Err(de::Error::custom("replacement not allowed for this configuration")); + } + Ok(Self { + path: enum_.path().to_owned(), + reason: enum_.reason().map(ToOwned::to_owned), + replacement: enum_.replacement().map(ToOwned::to_owned), + }) + } +} + +#[derive(Debug, Deserialize, Serialize)] #[serde(untagged)] -pub enum DisallowedPath { +pub enum DisallowedPathEnum { Simple(String), WithReason { path: String, @@ -25,28 +49,34 @@ pub enum DisallowedPath { }, } -impl DisallowedPath { +impl DisallowedPath { + pub fn path(&self) -> &str { + &self.path + } + + pub fn diag_amendment(&self, span: Span) -> impl FnOnce(&mut Diag<'_, ()>) + use<'_, REPLACEMENT_ALLOWED> { + move |diag| { + if let Some(replacement) = &self.replacement { + diag.span_suggestion( + span, + self.reason.as_ref().map_or_else(|| String::from("use"), Clone::clone), + replacement, + Applicability::MachineApplicable, + ); + } else if let Some(reason) = &self.reason { + diag.note(reason.clone()); + } + } + } +} + +impl DisallowedPathEnum { pub fn path(&self) -> &str { let (Self::Simple(path) | Self::WithReason { path, .. }) = self; path } - pub fn diag_amendment(&self, span: Span) -> impl FnOnce(&mut Diag<'_, ()>) + use<'_> { - move |diag| { - if let Some(replacement) = self.replacement() { - diag.span_suggestion( - span, - self.reason().map_or_else(|| String::from("use"), ToOwned::to_owned), - replacement, - Applicability::MachineApplicable, - ); - } else if let Some(reason) = self.reason() { - diag.note(reason.to_owned()); - } - } - } - fn reason(&self) -> Option<&str> { match &self { Self::WithReason { reason, .. } => reason.as_deref(), @@ -63,10 +93,10 @@ impl DisallowedPath { } /// Creates a map of disallowed items to the reason they were disallowed. -pub fn create_disallowed_map( +pub fn create_disallowed_map( tcx: TyCtxt<'_>, - disallowed: &'static [DisallowedPath], -) -> DefIdMap<(&'static str, &'static DisallowedPath)> { + disallowed: &'static [DisallowedPath], +) -> DefIdMap<(&'static str, &'static DisallowedPath)> { disallowed .iter() .map(|x| (x.path(), x.path().split("::").collect::>(), x)) @@ -466,7 +496,6 @@ macro_rules! unimplemented_serialize { } unimplemented_serialize! { - DisallowedPath, Rename, MacroMatcher, } diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs index 3ae7ab969150..bf7f81f2f3e6 100644 --- a/clippy_lints/src/await_holding_invalid.rs +++ b/clippy_lints/src/await_holding_invalid.rs @@ -174,7 +174,7 @@ declare_clippy_lint! { impl_lint_pass!(AwaitHolding => [AWAIT_HOLDING_LOCK, AWAIT_HOLDING_REFCELL_REF, AWAIT_HOLDING_INVALID_TYPE]); pub struct AwaitHolding { - def_ids: DefIdMap<(&'static str, &'static DisallowedPath)>, + def_ids: DefIdMap<(&'static str, &'static DisallowedPath)>, } impl AwaitHolding { @@ -255,7 +255,12 @@ impl AwaitHolding { } } -fn emit_invalid_type(cx: &LateContext<'_>, span: Span, path: &'static str, disallowed_path: &'static DisallowedPath) { +fn emit_invalid_type( + cx: &LateContext<'_>, + span: Span, + path: &'static str, + disallowed_path: &'static DisallowedPath, +) { span_lint_and_then( cx, AWAIT_HOLDING_INVALID_TYPE, diff --git a/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.rs b/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.rs new file mode 100644 index 000000000000..f328e4d9d04c --- /dev/null +++ b/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.stderr b/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.stderr new file mode 100644 index 000000000000..86e30409af06 --- /dev/null +++ b/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.stderr @@ -0,0 +1,11 @@ +error: error reading Clippy's configuration file: replacement not allowed for this configuration + --> $DIR/tests/ui-toml/await_holding_invalid_type_with_replacement/clippy.toml:1:31 + | +LL | await-holding-invalid-types = [ + | _______________________________^ +LL | | { path = "std::string::String", replacement = "std::net::Ipv4Addr" }, +LL | | ] + | |_^ + +error: aborting due to 1 previous error + diff --git a/tests/ui-toml/await_holding_invalid_type_with_replacement/clippy.toml b/tests/ui-toml/await_holding_invalid_type_with_replacement/clippy.toml new file mode 100644 index 000000000000..f6bc59672ed7 --- /dev/null +++ b/tests/ui-toml/await_holding_invalid_type_with_replacement/clippy.toml @@ -0,0 +1,3 @@ +await-holding-invalid-types = [ + { path = "std::string::String", replacement = "std::net::Ipv4Addr" }, +] From fef10d42a330a8d6f746e07f1307124520df3b92 Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Wed, 18 Dec 2024 18:49:47 -0500 Subject: [PATCH 005/991] Use two structs rather than a const generic --- clippy_config/src/conf.rs | 8 +-- clippy_config/src/types.rs | 82 +++++++++++++++++------ clippy_lints/src/await_holding_invalid.rs | 8 +-- clippy_lints/src/disallowed_macros.rs | 9 +-- clippy_lints/src/disallowed_methods.rs | 4 +- clippy_lints/src/disallowed_types.rs | 4 +- 6 files changed, 78 insertions(+), 37 deletions(-) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 82ab08530e1a..7bfd32b32cd6 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -1,8 +1,8 @@ use crate::ClippyConfiguration; use crate::types::{ - DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename, SourceItemOrdering, - SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind, - SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds, + DisallowedPath, DisallowedPathWithoutReplacement, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, + Rename, SourceItemOrdering, SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings, + SourceItemOrderingModuleItemKind, SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds, }; use clippy_utils::msrvs::Msrv; use rustc_errors::Applicability; @@ -445,7 +445,7 @@ define_Conf! { avoid_breaking_exported_api: bool = true, /// The list of types which may not be held across an await point. #[lints(await_holding_invalid_type)] - await_holding_invalid_types: Vec> = Vec::new(), + await_holding_invalid_types: Vec = Vec::new(), /// DEPRECATED LINT: BLACKLISTED_NAME. /// /// Use the Disallowed Names lint instead diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index 6a0f7aa75f25..ef3d46892a47 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -15,21 +15,40 @@ pub struct Rename { } #[derive(Debug, Serialize)] -pub struct DisallowedPath { +pub struct DisallowedPathWithoutReplacement { + path: String, + reason: Option, +} + +#[derive(Clone, Debug, Serialize)] +pub struct DisallowedPath { path: String, reason: Option, replacement: Option, } -impl<'de, const REPLACEMENT_ALLOWED: bool> Deserialize<'de> for DisallowedPath { +impl<'de> Deserialize<'de> for DisallowedPathWithoutReplacement { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { let enum_ = DisallowedPathEnum::deserialize(deserializer)?; - if !REPLACEMENT_ALLOWED && enum_.replacement().is_some() { + if enum_.replacement().is_some() { return Err(de::Error::custom("replacement not allowed for this configuration")); } + Ok(Self { + path: enum_.path().to_owned(), + reason: enum_.reason().map(ToOwned::to_owned), + }) + } +} + +impl<'de> Deserialize<'de> for DisallowedPath { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let enum_ = DisallowedPathEnum::deserialize(deserializer)?; Ok(Self { path: enum_.path().to_owned(), reason: enum_.reason().map(ToOwned::to_owned), @@ -49,24 +68,45 @@ pub enum DisallowedPathEnum { }, } -impl DisallowedPath { - pub fn path(&self) -> &str { +pub trait AmendDiag { + fn path(&self) -> &str; + fn reason(&self) -> Option<&str>; + fn replacement(&self) -> Option<&str>; + fn amend_diag(&self, span: Span, diag: &mut Diag<'_, ()>) { + if let Some(replacement) = &self.replacement() { + diag.span_suggestion( + span, + self.reason().map_or_else(|| String::from("use"), ToOwned::to_owned), + replacement, + Applicability::MachineApplicable, + ); + } else if let Some(reason) = self.reason() { + diag.note(reason.to_owned()); + } + } +} + +impl AmendDiag for DisallowedPathWithoutReplacement { + fn path(&self) -> &str { &self.path } + fn reason(&self) -> Option<&str> { + self.reason.as_deref() + } + fn replacement(&self) -> Option<&str> { + None + } +} - pub fn diag_amendment(&self, span: Span) -> impl FnOnce(&mut Diag<'_, ()>) + use<'_, REPLACEMENT_ALLOWED> { - move |diag| { - if let Some(replacement) = &self.replacement { - diag.span_suggestion( - span, - self.reason.as_ref().map_or_else(|| String::from("use"), Clone::clone), - replacement, - Applicability::MachineApplicable, - ); - } else if let Some(reason) = &self.reason { - diag.note(reason.clone()); - } - } +impl AmendDiag for DisallowedPath { + fn path(&self) -> &str { + &self.path + } + fn reason(&self) -> Option<&str> { + self.reason.as_deref() + } + fn replacement(&self) -> Option<&str> { + self.replacement.as_deref() } } @@ -93,10 +133,10 @@ impl DisallowedPathEnum { } /// Creates a map of disallowed items to the reason they were disallowed. -pub fn create_disallowed_map( +pub fn create_disallowed_map( tcx: TyCtxt<'_>, - disallowed: &'static [DisallowedPath], -) -> DefIdMap<(&'static str, &'static DisallowedPath)> { + disallowed: &'static [T], +) -> DefIdMap<(&'static str, &'static T)> { disallowed .iter() .map(|x| (x.path(), x.path().split("::").collect::>(), x)) diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs index bf7f81f2f3e6..3eb87e05a236 100644 --- a/clippy_lints/src/await_holding_invalid.rs +++ b/clippy_lints/src/await_holding_invalid.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::{DisallowedPath, create_disallowed_map}; +use clippy_config::types::{AmendDiag, DisallowedPathWithoutReplacement, create_disallowed_map}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::{match_def_path, paths}; use rustc_hir as hir; @@ -174,7 +174,7 @@ declare_clippy_lint! { impl_lint_pass!(AwaitHolding => [AWAIT_HOLDING_LOCK, AWAIT_HOLDING_REFCELL_REF, AWAIT_HOLDING_INVALID_TYPE]); pub struct AwaitHolding { - def_ids: DefIdMap<(&'static str, &'static DisallowedPath)>, + def_ids: DefIdMap<(&'static str, &'static DisallowedPathWithoutReplacement)>, } impl AwaitHolding { @@ -259,14 +259,14 @@ fn emit_invalid_type( cx: &LateContext<'_>, span: Span, path: &'static str, - disallowed_path: &'static DisallowedPath, + disallowed_path: &'static DisallowedPathWithoutReplacement, ) { span_lint_and_then( cx, AWAIT_HOLDING_INVALID_TYPE, span, format!("holding a disallowed type across an await point `{path}`"), - disallowed_path.diag_amendment(span), + |diag| disallowed_path.amend_diag(span, diag), ); } diff --git a/clippy_lints/src/disallowed_macros.rs b/clippy_lints/src/disallowed_macros.rs index fe0870e8282f..629bf416515c 100644 --- a/clippy_lints/src/disallowed_macros.rs +++ b/clippy_lints/src/disallowed_macros.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::{DisallowedPath, create_disallowed_map}; +use clippy_config::types::{AmendDiag, DisallowedPath, create_disallowed_map}; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::macros::macro_backtrace; use rustc_data_structures::fx::FxHashSet; @@ -92,7 +92,6 @@ impl DisallowedMacros { if let Some(&(path, disallowed_path)) = self.disallowed.get(&mac.def_id) { let msg = format!("use of a disallowed macro `{path}`"); - let add_note = disallowed_path.diag_amendment(mac.span); if matches!(mac.kind, MacroKind::Derive) && let Some(derive_src) = derive_src { @@ -102,10 +101,12 @@ impl DisallowedMacros { cx.tcx.local_def_id_to_hir_id(derive_src.def_id), mac.span, msg, - add_note, + |diag| disallowed_path.amend_diag(mac.span, diag), ); } else { - span_lint_and_then(cx, DISALLOWED_MACROS, mac.span, msg, add_note); + span_lint_and_then(cx, DISALLOWED_MACROS, mac.span, msg, |diag| { + disallowed_path.amend_diag(mac.span, diag); + }); } } } diff --git a/clippy_lints/src/disallowed_methods.rs b/clippy_lints/src/disallowed_methods.rs index 0cd9ea13f2e5..e6503b310537 100644 --- a/clippy_lints/src/disallowed_methods.rs +++ b/clippy_lints/src/disallowed_methods.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::{DisallowedPath, create_disallowed_map}; +use clippy_config::types::{AmendDiag, DisallowedPath, create_disallowed_map}; use clippy_utils::diagnostics::span_lint_and_then; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefIdMap; @@ -93,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods { DISALLOWED_METHODS, span, format!("use of a disallowed method `{path}`"), - disallowed_path.diag_amendment(span), + |diag| disallowed_path.amend_diag(span, diag), ); } } diff --git a/clippy_lints/src/disallowed_types.rs b/clippy_lints/src/disallowed_types.rs index a34ec4616e51..15e5b8bb4c5a 100644 --- a/clippy_lints/src/disallowed_types.rs +++ b/clippy_lints/src/disallowed_types.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::DisallowedPath; +use clippy_config::types::{AmendDiag, DisallowedPath}; use clippy_utils::diagnostics::span_lint_and_then; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::Res; @@ -89,7 +89,7 @@ impl DisallowedTypes { DISALLOWED_TYPES, span, format!("use of a disallowed type `{path}`"), - disallowed_path.diag_amendment(span), + |diag| disallowed_path.amend_diag(span, diag), ); } } From adaa756b555f751201440bca4ba65fc9b5691ace Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 29 Dec 2024 10:56:36 -0800 Subject: [PATCH 006/991] Add more ranges parsing tests --- stderr ------------------------------- error: expected expression, found `..` --> tests/ui/parser/ranges-precedence.rs:75:12 | LL | ($e:expr) => {}; | ------- while parsing argument for this `expr` macro fragment LL | } LL | expr!(!..0); | ^^ expected expression error: expected expression, found `..` --> tests/ui/parser/ranges-precedence.rs:76:12 | LL | ($e:expr) => {}; | ------- while parsing argument for this `expr` macro fragment ... LL | expr!(-..0); | ^^ expected expression error: expected expression, found `..` --> tests/ui/parser/ranges-precedence.rs:77:12 | LL | ($e:expr) => {}; | ------- while parsing argument for this `expr` macro fragment ... LL | expr!(*..0); | ^^ expected expression error: aborting due to 3 previous errors ------------------------------------------ --- tests/ui/parser/ranges-precedence.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/ui/parser/ranges-precedence.rs b/tests/ui/parser/ranges-precedence.rs index 14dd6488ff26..783799f70998 100644 --- a/tests/ui/parser/ranges-precedence.rs +++ b/tests/ui/parser/ranges-precedence.rs @@ -1,7 +1,8 @@ //@ run-pass +//@ edition: 2021 // Test that the precedence of ranges is correct - +use core::ops::{Add, RangeTo}; struct Foo { foo: usize, @@ -11,6 +12,13 @@ impl Foo { fn bar(&self) -> usize { 5 } } +impl Add> for Foo { + type Output = usize; + fn add(self, range: RangeTo) -> Self::Output { + self.foo + range.end + } +} + fn main() { let x = 1+3..4+5; assert_eq!(x, (4..9)); @@ -49,4 +57,22 @@ fn main() { let y = ..; assert_eq!(y, (..)); + + let reference = &..0; + assert_eq!(*reference, ..0); + let reference2 = &&..0; + assert_eq!(**reference2, ..0); + + let closure = || ..0; + assert_eq!(closure(), ..0); + + let sum = Foo { foo: 3 } + ..4; + assert_eq!(sum, 7); + + macro_rules! expr { + ($e:expr) => {}; + } + expr!(!..0); + expr!(-..0); + expr!(*..0); } From 462604d8256348901e042ad0de600c76d4c8d029 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 29 Dec 2024 11:04:49 -0800 Subject: [PATCH 007/991] Fix parsing of ranges after unary operators --- compiler/rustc_parse/src/parser/expr.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7533e75ffe26..3405733f39fb 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -605,7 +605,11 @@ impl<'a> Parser<'a> { fn parse_expr_prefix_common(&mut self, lo: Span) -> PResult<'a, (Span, P)> { self.bump(); let attrs = self.parse_outer_attributes()?; - let expr = self.parse_expr_prefix(attrs)?; + let expr = if self.token.is_range_separator() { + self.parse_expr_prefix_range(attrs) + } else { + self.parse_expr_prefix(attrs) + }?; let span = self.interpolated_or_expr_span(&expr); Ok((lo.to(span), expr)) } From 7061551498ce6a20265517f517449026356240dd Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Mon, 30 Dec 2024 23:48:53 +0000 Subject: [PATCH 008/991] Add FileCheck annotations to mir-opt/issues From #123067, this test should ensure that there is no duplicated basic block against or-patterns. Signed-off-by: Shunpoco --- tests/mir-opt/issues/issue_75439.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/issues/issue_75439.rs b/tests/mir-opt/issues/issue_75439.rs index ea763dd1b10d..d7883f0dc71f 100644 --- a/tests/mir-opt/issues/issue_75439.rs +++ b/tests/mir-opt/issues/issue_75439.rs @@ -1,10 +1,14 @@ -// skip-filecheck // EMIT_MIR issue_75439.foo.MatchBranchSimplification.diff //@ ignore-endian-big use std::mem::transmute; pub fn foo(bytes: [u8; 16]) -> Option<[u8; 4]> { + // CHECK-LABEL: fn foo( + // CHECK: bb2: { + // CHECK-NEXT: 0: [[bb:bb[0-9]+]], + // CHECK-SAME: {{[0-9]+}}: [[bb]], + // big endian `u32`s let dwords: [u32; 4] = unsafe { transmute(bytes) }; const FF: u32 = 0x0000_ffff_u32.to_be(); From 17f9344a9689d57813d56ee35d95c97f05e6c5e0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 6 Jan 2025 19:03:55 +0100 Subject: [PATCH 009/991] Fix `literal_string_with_formatting_args` lint emitted when it should not --- .../literal_string_with_formatting_args.rs | 2 +- .../ui/literal_string_with_formatting_arg.rs | 19 ++++++++++++ .../literal_string_with_formatting_arg.stderr | 30 +++++++++++-------- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/clippy_lints/src/literal_string_with_formatting_args.rs b/clippy_lints/src/literal_string_with_formatting_args.rs index 49353a1b76be..4c8063ee6e63 100644 --- a/clippy_lints/src/literal_string_with_formatting_args.rs +++ b/clippy_lints/src/literal_string_with_formatting_args.rs @@ -81,7 +81,7 @@ fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, spans: &[(Span, Option for LiteralStringWithFormattingArg { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if expr.span.from_expansion() { + if expr.span.from_expansion() || expr.span.is_dummy() { return; } if let ExprKind::Lit(lit) = expr.kind { diff --git a/tests/ui/literal_string_with_formatting_arg.rs b/tests/ui/literal_string_with_formatting_arg.rs index f257c66f59d3..c9731e592e59 100644 --- a/tests/ui/literal_string_with_formatting_arg.rs +++ b/tests/ui/literal_string_with_formatting_arg.rs @@ -1,6 +1,24 @@ #![warn(clippy::literal_string_with_formatting_args)] #![allow(clippy::unnecessary_literal_unwrap)] +// Regression test for . +// It's not supposed to emit the lint in this case (in `assert!` expansion). +fn compiler_macro() { + fn parse(_: &str) -> Result<(), i32> { + unimplemented!() + } + + assert!( + parse( + #[allow(clippy::literal_string_with_formatting_args)] + "foo {:}" + ) + .is_err() + ); + let value = 0; + assert!(format!("{value}").is_ascii()); +} + fn main() { let x: Option = None; let y = "hello"; @@ -13,6 +31,7 @@ fn main() { x.expect(r"{y:?} {y:?} "); //~ literal_string_with_formatting_args x.expect(r"{y:?} y:?}"); //~ literal_string_with_formatting_args x.expect(r##" {y:?} {y:?} "##); //~ literal_string_with_formatting_args + assert!("{y}".is_ascii()); //~ literal_string_with_formatting_args // Ensure that it doesn't try to go in the middle of a unicode character. x.expect("———{:?}"); //~ literal_string_with_formatting_args diff --git a/tests/ui/literal_string_with_formatting_arg.stderr b/tests/ui/literal_string_with_formatting_arg.stderr index 32a84f600da7..1898f4f57b82 100644 --- a/tests/ui/literal_string_with_formatting_arg.stderr +++ b/tests/ui/literal_string_with_formatting_arg.stderr @@ -1,5 +1,5 @@ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:7:15 + --> tests/ui/literal_string_with_formatting_arg.rs:25:15 | LL | x.expect("{y} {}"); | ^^^ @@ -8,64 +8,70 @@ LL | x.expect("{y} {}"); = help: to override `-D warnings` add `#[allow(clippy::literal_string_with_formatting_args)]` error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:8:16 + --> tests/ui/literal_string_with_formatting_arg.rs:26:16 | LL | x.expect(" {y} bla"); | ^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:9:15 + --> tests/ui/literal_string_with_formatting_arg.rs:27:15 | LL | x.expect("{:?}"); | ^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:10:15 + --> tests/ui/literal_string_with_formatting_arg.rs:28:15 | LL | x.expect("{y:?}"); | ^^^^^ error: these look like formatting arguments but are not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:11:16 + --> tests/ui/literal_string_with_formatting_arg.rs:29:16 | LL | x.expect(" {y:?} {y:?} "); | ^^^^^ ^^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:12:23 + --> tests/ui/literal_string_with_formatting_arg.rs:30:23 | LL | x.expect(" {y:..} {y:?} "); | ^^^^^ error: these look like formatting arguments but are not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:13:16 + --> tests/ui/literal_string_with_formatting_arg.rs:31:16 | LL | x.expect(r"{y:?} {y:?} "); | ^^^^^ ^^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:14:16 + --> tests/ui/literal_string_with_formatting_arg.rs:32:16 | LL | x.expect(r"{y:?} y:?}"); | ^^^^^ error: these look like formatting arguments but are not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:15:19 + --> tests/ui/literal_string_with_formatting_arg.rs:33:19 | LL | x.expect(r##" {y:?} {y:?} "##); | ^^^^^ ^^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:17:18 + --> tests/ui/literal_string_with_formatting_arg.rs:34:14 + | +LL | assert!("{y}".is_ascii()); + | ^^^ + +error: this looks like a formatting argument but it is not part of a formatting macro + --> tests/ui/literal_string_with_formatting_arg.rs:36:18 | LL | x.expect("———{:?}"); | ^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:27:19 + --> tests/ui/literal_string_with_formatting_arg.rs:46:19 | LL | x.expect(r##" {x:?} "##); // `x` doesn't exist so we shoud not lint | ^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 12 previous errors From a7fb37c1d832bea651f29b4676a816635dc11894 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 7 Jan 2025 15:55:41 +0100 Subject: [PATCH 010/991] Correctly handle expanded macros for `literal_string_with_formatting_args` lint --- .../src/literal_string_with_formatting_args.rs | 9 +++++++++ tests/ui/{literal_string_with_formatting_args}.rs | 14 ++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/ui/{literal_string_with_formatting_args}.rs diff --git a/clippy_lints/src/literal_string_with_formatting_args.rs b/clippy_lints/src/literal_string_with_formatting_args.rs index 4c8063ee6e63..c0d016ce08b0 100644 --- a/clippy_lints/src/literal_string_with_formatting_args.rs +++ b/clippy_lints/src/literal_string_with_formatting_args.rs @@ -8,6 +8,7 @@ use rustc_span::{BytePos, Span}; use clippy_utils::diagnostics::span_lint; use clippy_utils::mir::enclosing_mir; +use clippy_utils::source::snippet_opt; declare_clippy_lint! { /// ### What it does @@ -95,7 +96,15 @@ impl LateLintPass<'_> for LiteralStringWithFormattingArg { }, _ => return, }; + let Some(snippet) = snippet_opt(cx, expr.span) else { + return; + }; let fmt_str = symbol.as_str(); + // If the literal has been generated by the macro, the snippet should not contain it, + // allowing us to skip it. + if !snippet.contains(fmt_str) { + return; + } let lo = expr.span.lo(); let mut current = fmt_str; let mut diff_len = 0; diff --git a/tests/ui/{literal_string_with_formatting_args}.rs b/tests/ui/{literal_string_with_formatting_args}.rs new file mode 100644 index 000000000000..8a06d0c7b360 --- /dev/null +++ b/tests/ui/{literal_string_with_formatting_args}.rs @@ -0,0 +1,14 @@ +// Regression test for . +// The `dbg` macro generates a literal with the name of the current file, so +// we need to ensure the lint is not emitted in this case. + +#![crate_name = "foo"] +#![allow(unused)] +#![warn(clippy::literal_string_with_formatting_args)] + +fn another_bad() { + let literal_string_with_formatting_args = 0; + dbg!("something"); +} + +fn main() {} From 00104a4167d2dd295e3639163dea393f7cd310d1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2025 16:42:56 +0100 Subject: [PATCH 011/991] Add more detailed explanations for #13885 regression test --- .../{literal_string_with_formatting_args}.rs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/ui/{literal_string_with_formatting_args}.rs b/tests/ui/{literal_string_with_formatting_args}.rs index 8a06d0c7b360..0f5b36e67503 100644 --- a/tests/ui/{literal_string_with_formatting_args}.rs +++ b/tests/ui/{literal_string_with_formatting_args}.rs @@ -2,6 +2,38 @@ // The `dbg` macro generates a literal with the name of the current file, so // we need to ensure the lint is not emitted in this case. +// Clippy sets `-Zflatten_format_args=no`, which changes the default behavior of how format args +// are lowered and only that one has this non-macro span. Adding the flag makes it repro on +// godbolt and shows a root context span for the file name string. +// +// So instead of having: +// +// ``` +// Lit( +// Spanned { +// node: Str( +// "[/app/example.rs:2:5] \"something\" = ", +// Cooked, +// ), +// span: /rustc/eb54a50837ad4bcc9842924f27e7287ca66e294c/library/std/src/macros.rs:365:35: 365:58 (#4), +// }, +// ), +// ``` +// +// We get: +// +// ``` +// Lit( +// Spanned { +// node: Str( +// "/app/example.rs", +// Cooked, +// ), +// span: /app/example.rs:2:5: 2:22 (#0), +// }, +// ) +// ``` + #![crate_name = "foo"] #![allow(unused)] #![warn(clippy::literal_string_with_formatting_args)] From e35330cabeaf312cefb4370560fd473d47eabe2d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2025 16:52:46 +0100 Subject: [PATCH 012/991] Use `is_from_proc_macro` instead of checking if the snippet contains the literal --- .../src/literal_string_with_formatting_args.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/clippy_lints/src/literal_string_with_formatting_args.rs b/clippy_lints/src/literal_string_with_formatting_args.rs index c0d016ce08b0..21066a00eaf5 100644 --- a/clippy_lints/src/literal_string_with_formatting_args.rs +++ b/clippy_lints/src/literal_string_with_formatting_args.rs @@ -7,8 +7,8 @@ use rustc_session::declare_lint_pass; use rustc_span::{BytePos, Span}; use clippy_utils::diagnostics::span_lint; +use clippy_utils::is_from_proc_macro; use clippy_utils::mir::enclosing_mir; -use clippy_utils::source::snippet_opt; declare_clippy_lint! { /// ### What it does @@ -80,8 +80,8 @@ fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, spans: &[(Span, Option for LiteralStringWithFormattingArg { - fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for LiteralStringWithFormattingArg { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { if expr.span.from_expansion() || expr.span.is_dummy() { return; } @@ -96,15 +96,10 @@ impl LateLintPass<'_> for LiteralStringWithFormattingArg { }, _ => return, }; - let Some(snippet) = snippet_opt(cx, expr.span) else { - return; - }; - let fmt_str = symbol.as_str(); - // If the literal has been generated by the macro, the snippet should not contain it, - // allowing us to skip it. - if !snippet.contains(fmt_str) { + if is_from_proc_macro(cx, expr) { return; } + let fmt_str = symbol.as_str(); let lo = expr.span.lo(); let mut current = fmt_str; let mut diff_len = 0; From 3921ed67b20a4541b1fa378de95c1dbe3d5cc5ef Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 16 Jan 2025 18:12:36 +0100 Subject: [PATCH 013/991] [`path_buf_push_overwrite`]: mark suggestion as `MaybeIncorrect` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Proposing to replace ```rust let mut x = PathBuf::from("/foo"); x.push("/bar"); ``` by ```rust let mut x = PathBuf::from("/foo"); x.push("bar"); ``` changes the content of `x` (`/bar` ⇒ `/foo/bar`). --- clippy_lints/src/methods/path_buf_push_overwrite.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/methods/path_buf_push_overwrite.rs b/clippy_lints/src/methods/path_buf_push_overwrite.rs index 2d3007e50b81..38d9c5f16778 100644 --- a/clippy_lints/src/methods/path_buf_push_overwrite.rs +++ b/clippy_lints/src/methods/path_buf_push_overwrite.rs @@ -28,7 +28,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t "calling `push` with '/' or '\\' (file system root) will overwrite the previous path definition", "try", format!("\"{}\"", pushed_path_lit.trim_start_matches(['/', '\\'])), - Applicability::MachineApplicable, + Applicability::MaybeIncorrect, ); } } From 76bc88c40fb467dc211ea38b79e1d37bb987e632 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 15 Dec 2024 23:21:47 +0100 Subject: [PATCH 014/991] More tests for `large_enum_variant` --- tests/ui/large_enum_variant.32bit.stderr | 18 +++++++++++++++++- tests/ui/large_enum_variant.64bit.stderr | 18 +++++++++++++++++- tests/ui/large_enum_variant.rs | 15 +++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/tests/ui/large_enum_variant.32bit.stderr b/tests/ui/large_enum_variant.32bit.stderr index ff4f1a7f312c..7edff0df10f8 100644 --- a/tests/ui/large_enum_variant.32bit.stderr +++ b/tests/ui/large_enum_variant.32bit.stderr @@ -276,5 +276,21 @@ help: consider boxing the large fields to reduce the total size of the enum LL | Error(Box>), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 16 previous errors +error: large size difference between variants + --> tests/ui/large_enum_variant.rs:158:1 + | +LL | / enum WithRecursion { +LL | | Large([u64; 64]), + | | ---------------- the largest variant contains at least 512 bytes +LL | | Recursive(Box), + | | ----------------------------- the second-largest variant contains at least 0 bytes +LL | | } + | |_^ the entire enum is at least 0 bytes + | +help: consider boxing the large fields to reduce the total size of the enum + | +LL | Large(Box<[u64; 64]>), + | ~~~~~~~~~~~~~~ + +error: aborting due to 17 previous errors diff --git a/tests/ui/large_enum_variant.64bit.stderr b/tests/ui/large_enum_variant.64bit.stderr index 805cb406f834..a52967d962f7 100644 --- a/tests/ui/large_enum_variant.64bit.stderr +++ b/tests/ui/large_enum_variant.64bit.stderr @@ -276,5 +276,21 @@ help: consider boxing the large fields to reduce the total size of the enum LL | Error(Box>), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 16 previous errors +error: large size difference between variants + --> tests/ui/large_enum_variant.rs:158:1 + | +LL | / enum WithRecursion { +LL | | Large([u64; 64]), + | | ---------------- the largest variant contains at least 512 bytes +LL | | Recursive(Box), + | | ----------------------------- the second-largest variant contains at least 0 bytes +LL | | } + | |_^ the entire enum is at least 0 bytes + | +help: consider boxing the large fields to reduce the total size of the enum + | +LL | Large(Box<[u64; 64]>), + | ~~~~~~~~~~~~~~ + +error: aborting due to 17 previous errors diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs index 3625c011dbfa..fec4a1ee79f2 100644 --- a/tests/ui/large_enum_variant.rs +++ b/tests/ui/large_enum_variant.rs @@ -155,6 +155,21 @@ enum LargeEnumOfConst { Error(PossiblyLargeEnumWithConst<256>), } +enum WithRecursion { + Large([u64; 64]), + Recursive(Box), +} + +enum WithRecursionAndGenerics { + Large([T; 64]), + Recursive(Box>), +} + +enum LargeEnumWithGenericsAndRecursive { + Ok(), + Error(WithRecursionAndGenerics), +} + fn main() { external!( enum LargeEnumInMacro { From 19ddb6922c6bd270b092d8be1ea64ce3d7a5b485 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 15 Dec 2024 23:21:47 +0100 Subject: [PATCH 015/991] Handle more cases in `is_normalizable` By assuming that a recursive type is normalizable within the deeper calls to `is_normalizable_helper()`, more cases can be handled by this function. In order to fix stack overflows, a recursion limit has also been added for recursive generic type instantiations. --- clippy_utils/src/ty/mod.rs | 16 ++++-- tests/ui/crashes/ice-10508a.rs | 19 ++++++++ tests/ui/crashes/ice-10508b.rs | 24 +++++++++ tests/ui/crashes/ice-10508c.rs | 7 +++ tests/ui/large_enum_variant.32bit.stderr | 22 +++++++-- tests/ui/large_enum_variant.64bit.stderr | 54 +++++++++++++++++++-- tests/ui/large_enum_variant.rs | 62 ++++++++++++++++++++++++ 7 files changed, 193 insertions(+), 11 deletions(-) create mode 100644 tests/ui/crashes/ice-10508a.rs create mode 100644 tests/ui/crashes/ice-10508b.rs create mode 100644 tests/ui/crashes/ice-10508c.rs diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index 260d1b801e3d..45dff91e8773 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -351,20 +351,26 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { /// Checks if `Ty` is normalizable. This function is useful /// to avoid crashes on `layout_of`. pub fn is_normalizable<'tcx>(cx: &LateContext<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { - is_normalizable_helper(cx, param_env, ty, &mut FxHashMap::default()) + is_normalizable_helper(cx, param_env, ty, 0, &mut FxHashMap::default()) } fn is_normalizable_helper<'tcx>( cx: &LateContext<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, + depth: usize, cache: &mut FxHashMap, bool>, ) -> bool { if let Some(&cached_result) = cache.get(&ty) { return cached_result; } - // prevent recursive loops, false-negative is better than endless loop leading to stack overflow - cache.insert(ty, false); + if !cx.tcx.recursion_limit().value_within_limit(depth) { + return false; + } + // Prevent recursive loops by answering `true` to recursive requests with the same + // type. This will be adjusted when the outermost call analyzes all the type + // components. + cache.insert(ty, true); let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); let cause = ObligationCause::dummy(); let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() { @@ -373,11 +379,11 @@ fn is_normalizable_helper<'tcx>( variant .fields .iter() - .all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, args), cache)) + .all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, args), depth + 1, cache)) }), _ => ty.walk().all(|generic_arg| match generic_arg.unpack() { GenericArgKind::Type(inner_ty) if inner_ty != ty => { - is_normalizable_helper(cx, param_env, inner_ty, cache) + is_normalizable_helper(cx, param_env, inner_ty, depth + 1, cache) }, _ => true, // if inner_ty == ty, we've already checked it }), diff --git a/tests/ui/crashes/ice-10508a.rs b/tests/ui/crashes/ice-10508a.rs new file mode 100644 index 000000000000..f45057217b43 --- /dev/null +++ b/tests/ui/crashes/ice-10508a.rs @@ -0,0 +1,19 @@ +// Used to overflow in `is_normalizable` + +use std::marker::PhantomData; + +struct Node { + m: PhantomData<&'static T>, +} + +struct Digit { + elem: T, +} + +enum FingerTree { + Single(T), + + Deep(Digit, Box>>), +} + +fn main() {} diff --git a/tests/ui/crashes/ice-10508b.rs b/tests/ui/crashes/ice-10508b.rs new file mode 100644 index 000000000000..41d4f0234b94 --- /dev/null +++ b/tests/ui/crashes/ice-10508b.rs @@ -0,0 +1,24 @@ +use std::marker::PhantomData; + +struct Digit { + elem: T, +} + +struct Node { + m: PhantomData<&'static T>, +} + +enum FingerTree { + Single(T), + + Deep(Digit, Node>>), +} + +enum Wrapper { + Simple, + Other(FingerTree), +} + +fn main() { + let w = Some(Wrapper::Simple::); +} diff --git a/tests/ui/crashes/ice-10508c.rs b/tests/ui/crashes/ice-10508c.rs new file mode 100644 index 000000000000..fb84d85fd675 --- /dev/null +++ b/tests/ui/crashes/ice-10508c.rs @@ -0,0 +1,7 @@ +#[derive(Debug)] +struct S { + t: T, + s: Box>, +} + +fn main() {} diff --git a/tests/ui/large_enum_variant.32bit.stderr b/tests/ui/large_enum_variant.32bit.stderr index 7edff0df10f8..36f3d930b535 100644 --- a/tests/ui/large_enum_variant.32bit.stderr +++ b/tests/ui/large_enum_variant.32bit.stderr @@ -283,14 +283,30 @@ LL | / enum WithRecursion { LL | | Large([u64; 64]), | | ---------------- the largest variant contains at least 512 bytes LL | | Recursive(Box), - | | ----------------------------- the second-largest variant contains at least 0 bytes + | | ----------------------------- the second-largest variant contains at least 4 bytes LL | | } - | |_^ the entire enum is at least 0 bytes + | |_^ the entire enum is at least 516 bytes | help: consider boxing the large fields to reduce the total size of the enum | LL | Large(Box<[u64; 64]>), | ~~~~~~~~~~~~~~ -error: aborting due to 17 previous errors +error: large size difference between variants + --> tests/ui/large_enum_variant.rs:168:1 + | +LL | / enum LargeEnumWithGenericsAndRecursive { +LL | | Ok(), + | | ---- the second-largest variant carries no data at all +LL | | Error(WithRecursionAndGenerics), + | | ------------------------------------ the largest variant contains at least 516 bytes +LL | | } + | |_^ the entire enum is at least 516 bytes + | +help: consider boxing the large fields to reduce the total size of the enum + | +LL | Error(Box>), + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 18 previous errors diff --git a/tests/ui/large_enum_variant.64bit.stderr b/tests/ui/large_enum_variant.64bit.stderr index a52967d962f7..31576a5863fc 100644 --- a/tests/ui/large_enum_variant.64bit.stderr +++ b/tests/ui/large_enum_variant.64bit.stderr @@ -283,14 +283,62 @@ LL | / enum WithRecursion { LL | | Large([u64; 64]), | | ---------------- the largest variant contains at least 512 bytes LL | | Recursive(Box), - | | ----------------------------- the second-largest variant contains at least 0 bytes + | | ----------------------------- the second-largest variant contains at least 8 bytes LL | | } - | |_^ the entire enum is at least 0 bytes + | |_^ the entire enum is at least 520 bytes | help: consider boxing the large fields to reduce the total size of the enum | LL | Large(Box<[u64; 64]>), | ~~~~~~~~~~~~~~ -error: aborting due to 17 previous errors +error: large size difference between variants + --> tests/ui/large_enum_variant.rs:168:1 + | +LL | / enum LargeEnumWithGenericsAndRecursive { +LL | | Ok(), + | | ---- the second-largest variant carries no data at all +LL | | Error(WithRecursionAndGenerics), + | | ------------------------------------ the largest variant contains at least 520 bytes +LL | | } + | |_^ the entire enum is at least 520 bytes + | +help: consider boxing the large fields to reduce the total size of the enum + | +LL | Error(Box>), + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: large size difference between variants + --> tests/ui/large_enum_variant.rs:203:5 + | +LL | / enum NoWarnings { +LL | | BigBoi(PublishWithBytes), + | | ------------------------ the largest variant contains at least 296 bytes +LL | | _SmallBoi(u8), + | | ------------- the second-largest variant contains at least 1 bytes +LL | | } + | |_____^ the entire enum is at least 296 bytes + | +help: consider boxing the large fields to reduce the total size of the enum + | +LL | BigBoi(Box), + | ~~~~~~~~~~~~~~~~~~~~~ + +error: large size difference between variants + --> tests/ui/large_enum_variant.rs:208:5 + | +LL | / enum MakesClippyAngry { +LL | | BigBoi(PublishWithVec), + | | ---------------------- the largest variant contains at least 224 bytes +LL | | _SmallBoi(u8), + | | ------------- the second-largest variant contains at least 1 bytes +LL | | } + | |_____^ the entire enum is at least 224 bytes + | +help: consider boxing the large fields to reduce the total size of the enum + | +LL | BigBoi(Box), + | ~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 20 previous errors diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs index fec4a1ee79f2..57722f63b225 100644 --- a/tests/ui/large_enum_variant.rs +++ b/tests/ui/large_enum_variant.rs @@ -178,3 +178,65 @@ fn main() { } ); } + +mod issue11915 { + use std::sync::atomic::AtomicPtr; + + pub struct Bytes { + ptr: *const u8, + len: usize, + // inlined "trait object" + data: AtomicPtr<()>, + vtable: &'static Vtable, + } + pub(crate) struct Vtable { + /// fn(data, ptr, len) + pub clone: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Bytes, + /// fn(data, ptr, len) + /// + /// takes `Bytes` to value + pub to_vec: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Vec, + /// fn(data, ptr, len) + pub drop: unsafe fn(&mut AtomicPtr<()>, *const u8, usize), + } + + enum NoWarnings { + BigBoi(PublishWithBytes), + _SmallBoi(u8), + } + + enum MakesClippyAngry { + BigBoi(PublishWithVec), + _SmallBoi(u8), + } + + struct PublishWithBytes { + _dup: bool, + _retain: bool, + _topic: Bytes, + __topic: Bytes, + ___topic: Bytes, + ____topic: Bytes, + _pkid: u16, + _payload: Bytes, + __payload: Bytes, + ___payload: Bytes, + ____payload: Bytes, + _____payload: Bytes, + } + + struct PublishWithVec { + _dup: bool, + _retain: bool, + _topic: Vec, + __topic: Vec, + ___topic: Vec, + ____topic: Vec, + _pkid: u16, + _payload: Vec, + __payload: Vec, + ___payload: Vec, + ____payload: Vec, + _____payload: Vec, + } +} From 277bf089b36db59dbc2c2efa279fbe52a3fe1c4b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 18 Jan 2025 17:13:53 +0100 Subject: [PATCH 016/991] Fix regression #14007 --- .../literal_string_with_formatting_args.rs | 6 +++- .../ui/literal_string_with_formatting_arg.rs | 7 ++++ .../literal_string_with_formatting_arg.stderr | 36 +++++++++++-------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/literal_string_with_formatting_args.rs b/clippy_lints/src/literal_string_with_formatting_args.rs index 21066a00eaf5..7e3cc444a817 100644 --- a/clippy_lints/src/literal_string_with_formatting_args.rs +++ b/clippy_lints/src/literal_string_with_formatting_args.rs @@ -128,7 +128,11 @@ impl<'tcx> LateLintPass<'tcx> for LiteralStringWithFormattingArg { pos.start += diff_len; pos.end += diff_len; - let start = fmt_str[..pos.start].rfind('{').unwrap_or(pos.start); + let mut start = pos.start; + while start < fmt_str.len() && !fmt_str.is_char_boundary(start) { + start += 1; + } + let start = fmt_str[..start].rfind('{').unwrap_or(start); // If this is a unicode character escape, we don't want to lint. if start > 1 && fmt_str[..start].ends_with("\\u") { continue; diff --git a/tests/ui/literal_string_with_formatting_arg.rs b/tests/ui/literal_string_with_formatting_arg.rs index c9731e592e59..b9a6654d4276 100644 --- a/tests/ui/literal_string_with_formatting_arg.rs +++ b/tests/ui/literal_string_with_formatting_arg.rs @@ -19,6 +19,13 @@ fn compiler_macro() { assert!(format!("{value}").is_ascii()); } +// Regression test for . +fn regression_14007() { + let s = "{и}"; + let ш = 12; + let s = "{ш}"; //~ literal_string_with_formatting_args +} + fn main() { let x: Option = None; let y = "hello"; diff --git a/tests/ui/literal_string_with_formatting_arg.stderr b/tests/ui/literal_string_with_formatting_arg.stderr index 1898f4f57b82..021983056bf6 100644 --- a/tests/ui/literal_string_with_formatting_arg.stderr +++ b/tests/ui/literal_string_with_formatting_arg.stderr @@ -1,77 +1,83 @@ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:25:15 + --> tests/ui/literal_string_with_formatting_arg.rs:26:14 | -LL | x.expect("{y} {}"); - | ^^^ +LL | let s = "{ш}"; + | ^^^ | = note: `-D clippy::literal-string-with-formatting-args` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::literal_string_with_formatting_args)]` error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:26:16 + --> tests/ui/literal_string_with_formatting_arg.rs:32:15 + | +LL | x.expect("{y} {}"); + | ^^^ + +error: this looks like a formatting argument but it is not part of a formatting macro + --> tests/ui/literal_string_with_formatting_arg.rs:33:16 | LL | x.expect(" {y} bla"); | ^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:27:15 + --> tests/ui/literal_string_with_formatting_arg.rs:34:15 | LL | x.expect("{:?}"); | ^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:28:15 + --> tests/ui/literal_string_with_formatting_arg.rs:35:15 | LL | x.expect("{y:?}"); | ^^^^^ error: these look like formatting arguments but are not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:29:16 + --> tests/ui/literal_string_with_formatting_arg.rs:36:16 | LL | x.expect(" {y:?} {y:?} "); | ^^^^^ ^^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:30:23 + --> tests/ui/literal_string_with_formatting_arg.rs:37:23 | LL | x.expect(" {y:..} {y:?} "); | ^^^^^ error: these look like formatting arguments but are not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:31:16 + --> tests/ui/literal_string_with_formatting_arg.rs:38:16 | LL | x.expect(r"{y:?} {y:?} "); | ^^^^^ ^^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:32:16 + --> tests/ui/literal_string_with_formatting_arg.rs:39:16 | LL | x.expect(r"{y:?} y:?}"); | ^^^^^ error: these look like formatting arguments but are not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:33:19 + --> tests/ui/literal_string_with_formatting_arg.rs:40:19 | LL | x.expect(r##" {y:?} {y:?} "##); | ^^^^^ ^^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:34:14 + --> tests/ui/literal_string_with_formatting_arg.rs:41:14 | LL | assert!("{y}".is_ascii()); | ^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:36:18 + --> tests/ui/literal_string_with_formatting_arg.rs:43:18 | LL | x.expect("———{:?}"); | ^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:46:19 + --> tests/ui/literal_string_with_formatting_arg.rs:53:19 | LL | x.expect(r##" {x:?} "##); // `x` doesn't exist so we shoud not lint | ^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 13 previous errors From 06221e653ca57a51b94a794cd99c49c8cba68ff9 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sat, 18 Jan 2025 17:14:33 +0100 Subject: [PATCH 017/991] Deprecate the `option_map_or_err_ok` lint --- clippy_lints/src/declared_lints.rs | 1 - clippy_lints/src/deprecated_lints.rs | 2 + clippy_lints/src/methods/mod.rs | 28 ------------- .../src/methods/option_map_or_err_ok.rs | 41 ------------------- tests/ui/deprecated.rs | 1 + tests/ui/deprecated.stderr | 8 +++- tests/ui/manual_ok_or.stderr | 11 +---- tests/ui/option_map_or_err_ok.fixed | 7 ---- tests/ui/option_map_or_err_ok.rs | 7 ---- tests/ui/option_map_or_err_ok.stderr | 11 ----- 10 files changed, 11 insertions(+), 106 deletions(-) delete mode 100644 clippy_lints/src/methods/option_map_or_err_ok.rs delete mode 100644 tests/ui/option_map_or_err_ok.fixed delete mode 100644 tests/ui/option_map_or_err_ok.rs delete mode 100644 tests/ui/option_map_or_err_ok.stderr diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 6d6b415f8cdd..01d0c919b216 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -449,7 +449,6 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::methods::OPTION_AS_REF_CLONED_INFO, crate::methods::OPTION_AS_REF_DEREF_INFO, crate::methods::OPTION_FILTER_MAP_INFO, - crate::methods::OPTION_MAP_OR_ERR_OK_INFO, crate::methods::OPTION_MAP_OR_NONE_INFO, crate::methods::OR_FUN_CALL_INFO, crate::methods::OR_THEN_UNWRAP_INFO, diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs index 3ea792d8b835..9d0ad3a63987 100644 --- a/clippy_lints/src/deprecated_lints.rs +++ b/clippy_lints/src/deprecated_lints.rs @@ -40,6 +40,8 @@ declare_with_version! { DEPRECATED(DEPRECATED_VERSION): &[(&str, &str)] = &[ ("clippy::pub_enum_variant_names", "`clippy::enum_variant_names` now covers this case via the `avoid-breaking-exported-api` config"), #[clippy::version = "1.54.0"] ("clippy::wrong_pub_self_convention", "`clippy::wrong_self_convention` now covers this case via the `avoid-breaking-exported-api` config"), + #[clippy::version = "1.86.0"] + ("clippy::option_map_or_err_ok", "`clippy::manual_ok_or` covers this case"), // end deprecated lints. used by `cargo dev deprecate_lint` ]} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 9bfa59479905..5dad6c2e5dfd 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -82,7 +82,6 @@ mod ok_expect; mod open_options; mod option_as_ref_cloned; mod option_as_ref_deref; -mod option_map_or_err_ok; mod option_map_or_none; mod option_map_unwrap_or; mod or_fun_call; @@ -3782,31 +3781,6 @@ declare_clippy_lint! { "calls to `Path::join` which will overwrite the original path" } -declare_clippy_lint! { - /// ### What it does - /// Checks for usage of `_.map_or(Err(_), Ok)`. - /// - /// ### Why is this bad? - /// Readability, this can be written more concisely as - /// `_.ok_or(_)`. - /// - /// ### Example - /// ```no_run - /// # let opt = Some(1); - /// opt.map_or(Err("error"), Ok); - /// ``` - /// - /// Use instead: - /// ```no_run - /// # let opt = Some(1); - /// opt.ok_or("error"); - /// ``` - #[clippy::version = "1.76.0"] - pub OPTION_MAP_OR_ERR_OK, - style, - "using `Option.map_or(Err(_), Ok)`, which is more succinctly expressed as `Option.ok_or(_)`" -} - declare_clippy_lint! { /// ### What it does /// Checks for iterators of `Result`s using `.filter(Result::is_ok).map(Result::unwrap)` that may @@ -4510,7 +4484,6 @@ impl_lint_pass!(Methods => [ WAKER_CLONE_WAKE, UNNECESSARY_FALLIBLE_CONVERSIONS, JOIN_ABSOLUTE_PATHS, - OPTION_MAP_OR_ERR_OK, RESULT_FILTER_MAP, ITER_FILTER_IS_SOME, ITER_FILTER_IS_OK, @@ -5069,7 +5042,6 @@ impl Methods { ("map_or", [def, map]) => { option_map_or_none::check(cx, expr, recv, def, map); manual_ok_or::check(cx, expr, recv, def, map); - option_map_or_err_ok::check(cx, expr, recv, def, map); unnecessary_map_or::check(cx, expr, recv, def, map, span, &self.msrv); }, ("map_or_else", [def, map]) => { diff --git a/clippy_lints/src/methods/option_map_or_err_ok.rs b/clippy_lints/src/methods/option_map_or_err_ok.rs deleted file mode 100644 index 4e424d4c066a..000000000000 --- a/clippy_lints/src/methods/option_map_or_err_ok.rs +++ /dev/null @@ -1,41 +0,0 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet; -use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::{is_res_lang_ctor, path_res}; -use rustc_errors::Applicability; -use rustc_hir::LangItem::{ResultErr, ResultOk}; -use rustc_hir::{Expr, ExprKind}; -use rustc_lint::LateContext; -use rustc_span::symbol::sym; - -use super::OPTION_MAP_OR_ERR_OK; - -pub(super) fn check<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx Expr<'tcx>, - recv: &'tcx Expr<'_>, - or_expr: &'tcx Expr<'_>, - map_expr: &'tcx Expr<'_>, -) { - // We check that it's called on an `Option` type. - if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option) - // We check that first we pass an `Err`. - && let ExprKind::Call(call, &[arg]) = or_expr.kind - && is_res_lang_ctor(cx, path_res(cx, call), ResultErr) - // And finally we check that it is mapped as `Ok`. - && is_res_lang_ctor(cx, path_res(cx, map_expr), ResultOk) - { - let msg = "called `map_or(Err(_), Ok)` on an `Option` value"; - let self_snippet = snippet(cx, recv.span, ".."); - let err_snippet = snippet(cx, arg.span, ".."); - span_lint_and_sugg( - cx, - OPTION_MAP_OR_ERR_OK, - expr.span, - msg, - "consider using `ok_or`", - format!("{self_snippet}.ok_or({err_snippet})"), - Applicability::MachineApplicable, - ); - } -} diff --git a/tests/ui/deprecated.rs b/tests/ui/deprecated.rs index 5617db90a470..35646e1c2391 100644 --- a/tests/ui/deprecated.rs +++ b/tests/ui/deprecated.rs @@ -15,5 +15,6 @@ #![warn(clippy::regex_macro)] //~ ERROR: lint `clippy::regex_macro` #![warn(clippy::pub_enum_variant_names)] //~ ERROR: lint `clippy::pub_enum_variant_names` #![warn(clippy::wrong_pub_self_convention)] //~ ERROR: lint `clippy::wrong_pub_self_convention` +#![warn(clippy::option_map_or_err_ok)] //~ ERROR: lint `clippy::option_map_or_err_ok` fn main() {} diff --git a/tests/ui/deprecated.stderr b/tests/ui/deprecated.stderr index b3e1646c8045..d7be1e583b08 100644 --- a/tests/ui/deprecated.stderr +++ b/tests/ui/deprecated.stderr @@ -79,5 +79,11 @@ error: lint `clippy::wrong_pub_self_convention` has been removed: `clippy::wrong LL | #![warn(clippy::wrong_pub_self_convention)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 13 previous errors +error: lint `clippy::option_map_or_err_ok` has been removed: `clippy::manual_ok_or` covers this case + --> tests/ui/deprecated.rs:18:9 + | +LL | #![warn(clippy::option_map_or_err_ok)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 14 previous errors diff --git a/tests/ui/manual_ok_or.stderr b/tests/ui/manual_ok_or.stderr index 2441a75b5c46..4722f53580f1 100644 --- a/tests/ui/manual_ok_or.stderr +++ b/tests/ui/manual_ok_or.stderr @@ -13,15 +13,6 @@ error: this pattern reimplements `Option::ok_or` LL | foo.map_or(Err("error"), Ok); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or("error")` -error: called `map_or(Err(_), Ok)` on an `Option` value - --> tests/ui/manual_ok_or.rs:14:5 - | -LL | foo.map_or(Err("error"), Ok); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok_or`: `foo.ok_or("error")` - | - = note: `-D clippy::option-map-or-err-ok` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]` - error: this pattern reimplements `Option::ok_or` --> tests/ui/manual_ok_or.rs:17:5 | @@ -47,5 +38,5 @@ LL + "{}{}{}{}{}{}{}", LL ~ "Alice", "Bob", "Sarah", "Marc", "Sandra", "Eric", "Jenifer")); | -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/option_map_or_err_ok.fixed b/tests/ui/option_map_or_err_ok.fixed deleted file mode 100644 index 131f4b2093e7..000000000000 --- a/tests/ui/option_map_or_err_ok.fixed +++ /dev/null @@ -1,7 +0,0 @@ -#![warn(clippy::option_map_or_err_ok)] - -fn main() { - let x = Some("a"); - let _ = x.ok_or("a"); - //~^ ERROR: called `map_or(Err(_), Ok)` on an `Option` value -} diff --git a/tests/ui/option_map_or_err_ok.rs b/tests/ui/option_map_or_err_ok.rs deleted file mode 100644 index 0f07a592ae5f..000000000000 --- a/tests/ui/option_map_or_err_ok.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![warn(clippy::option_map_or_err_ok)] - -fn main() { - let x = Some("a"); - let _ = x.map_or(Err("a"), Ok); - //~^ ERROR: called `map_or(Err(_), Ok)` on an `Option` value -} diff --git a/tests/ui/option_map_or_err_ok.stderr b/tests/ui/option_map_or_err_ok.stderr deleted file mode 100644 index 1971af80aa8d..000000000000 --- a/tests/ui/option_map_or_err_ok.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: called `map_or(Err(_), Ok)` on an `Option` value - --> tests/ui/option_map_or_err_ok.rs:5:13 - | -LL | let _ = x.map_or(Err("a"), Ok); - | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok_or`: `x.ok_or("a")` - | - = note: `-D clippy::option-map-or-err-ok` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]` - -error: aborting due to 1 previous error - From a03242f8e0e7ac1d15b2e78568dcbb5e92e9f258 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sat, 18 Jan 2025 17:17:41 +0100 Subject: [PATCH 018/991] Move `manual_ok_or` from pedantic to style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `manual_ok_or` covers the same case that were covered by `option_map_or_err_ok` which is not deprecated. The latter was in the "style" category. Also, the lint is machine applicable, and leads to shorter and more readable code, so "style" is appropriate. The only difference is that the η-expanded form of `Result::Ok()` was not covered by `option_map_or_err_ok` while it is by `manual_ok_or`, so the category change may expose some new occurrences. --- clippy_lints/src/methods/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 5dad6c2e5dfd..7625057368e9 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2639,7 +2639,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.49.0"] pub MANUAL_OK_OR, - pedantic, + style, "finds patterns that can be encoded more concisely with `Option::ok_or`" } From ac87b0cb73dc16df9413421119100001bf370d20 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Thu, 23 Jan 2025 12:40:12 +0900 Subject: [PATCH 019/991] fix ICE in `unnecessary_mut_passed` --- clippy_lints/src/mut_reference.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index c382fb8fce1b..2fd1049f42e1 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -54,8 +54,9 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { ); } }, - ExprKind::MethodCall(path, receiver, arguments, _) => { - let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap(); + ExprKind::MethodCall(path, receiver, arguments, _) + if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) => + { let args = cx.typeck_results().node_args(e.hir_id); let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args); check_arguments( From 40c2c641c2ddf4eaf1e9e8c0991d4f8644c267ec Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Sun, 26 Jan 2025 15:43:48 +0900 Subject: [PATCH 020/991] fix broken link of UI test in the book --- book/src/development/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/development/basics.md b/book/src/development/basics.md index 166b6aab9fb3..931e5c3a2942 100644 --- a/book/src/development/basics.md +++ b/book/src/development/basics.md @@ -75,7 +75,7 @@ or if you modify a test file to add a test case. > _Note:_ This command may update more files than you intended. In that case > only commit the files you wanted to update. -[UI test]: https://rustc-dev-guide.rust-lang.org/tests/adding.html#guide-to-the-ui-tests +[UI test]: https://rustc-dev-guide.rust-lang.org/tests/adding.html#ui-test-walkthrough ## `cargo dev` From 665e78f20febeef66a05a6509154646c4eb09145 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Mon, 27 Jan 2025 23:10:42 +0900 Subject: [PATCH 021/991] add MSRV check for `manual_flatten` --- book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_lints/src/loops/manual_flatten.rs | 3 +++ clippy_lints/src/loops/mod.rs | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 999df0efaac1..59530dbc4b20 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -743,6 +743,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits) * [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals) * [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp) +* [`manual_flatten`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten) * [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one) * [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check) * [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 4b0fcbfc3bc6..9d8678848c8b 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -612,6 +612,7 @@ define_Conf! { manual_bits, manual_c_str_literals, manual_clamp, + manual_flatten, manual_hash_one, manual_is_ascii_check, manual_let_else, diff --git a/clippy_lints/src/loops/manual_flatten.rs b/clippy_lints/src/loops/manual_flatten.rs index 366c310592f5..ffeb7e889c2e 100644 --- a/clippy_lints/src/loops/manual_flatten.rs +++ b/clippy_lints/src/loops/manual_flatten.rs @@ -1,6 +1,7 @@ use super::MANUAL_FLATTEN; use super::utils::make_iterator_snippet; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::visitors::is_local_used; use clippy_utils::{higher, path_to_local_id, peel_blocks_with_stmt}; use rustc_errors::Applicability; @@ -18,6 +19,7 @@ pub(super) fn check<'tcx>( arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>, span: Span, + msrv: &Msrv, ) { let inner_expr = peel_blocks_with_stmt(body); if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else: None, .. }) @@ -34,6 +36,7 @@ pub(super) fn check<'tcx>( && (some_ctor || ok_ctor) // Ensure expr in `if let` is not used afterwards && !is_local_used(cx, if_then, pat_hir_id) + && msrv.meets(msrvs::ITER_FLATTEN) { let if_let_type = if some_ctor { "Some" } else { "Ok" }; // Prepare the error message diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index c5e75af2303c..80afb4f266d4 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -831,7 +831,7 @@ impl Loops { mut_range_bound::check(cx, arg, body); single_element_loop::check(cx, pat, arg, body, expr); same_item_push::check(cx, pat, arg, body, expr, &self.msrv); - manual_flatten::check(cx, pat, arg, body, span); + manual_flatten::check(cx, pat, arg, body, span, &self.msrv); manual_find::check(cx, pat, arg, body, span, expr); unused_enumerate_index::check(cx, pat, arg, body); } From 16e2196fc2d9aa87d261e6163e6a13bc9d761f60 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Tue, 28 Jan 2025 00:03:00 +0100 Subject: [PATCH 022/991] `useless_asref`: no lint if in a closure to change the ref depth Removing the `.as_ref()` or `.as_mut()` as the top-level expression in a closure may change the type of the result. In this case, it may be better not to lint rather than proposing a fix that would not work. --- clippy_lints/src/methods/useless_asref.rs | 19 +++++++++++++------ tests/ui/useless_asref.fixed | 5 +++++ tests/ui/useless_asref.rs | 5 +++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs index 82313257e5c4..6d3da42775f4 100644 --- a/clippy_lints/src/methods/useless_asref.rs +++ b/clippy_lints/src/methods/useless_asref.rs @@ -55,12 +55,19 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty); let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty); if base_rcv_ty == base_res_ty && rcv_depth >= res_depth { - // allow the `as_ref` or `as_mut` if it is followed by another method call - if let Some(parent) = get_parent_expr(cx, expr) - && let hir::ExprKind::MethodCall(segment, ..) = parent.kind - && segment.ident.span != expr.span - { - return; + if let Some(parent) = get_parent_expr(cx, expr) { + // allow the `as_ref` or `as_mut` if it is followed by another method call + if let hir::ExprKind::MethodCall(segment, ..) = parent.kind + && segment.ident.span != expr.span + { + return; + } + + // allow the `as_ref` or `as_mut` if they belong to a closure that changes + // the number of references + if matches!(parent.kind, hir::ExprKind::Closure(..)) && rcv_depth != res_depth { + return; + } } let mut applicability = Applicability::MachineApplicable; diff --git a/tests/ui/useless_asref.fixed b/tests/ui/useless_asref.fixed index ddbb9255b466..2f179200bb37 100644 --- a/tests/ui/useless_asref.fixed +++ b/tests/ui/useless_asref.fixed @@ -198,6 +198,11 @@ fn issue_12528() { let _ = opt.as_ref().map(RcWeak::clone); } +fn issue_14088() { + let s = Some("foo"); + let _: Option<&str> = s.as_ref().map(|x| x.as_ref()); +} + fn main() { not_ok(); ok(); diff --git a/tests/ui/useless_asref.rs b/tests/ui/useless_asref.rs index b0405e930a25..9851a0caac4f 100644 --- a/tests/ui/useless_asref.rs +++ b/tests/ui/useless_asref.rs @@ -198,6 +198,11 @@ fn issue_12528() { let _ = opt.as_ref().map(RcWeak::clone); } +fn issue_14088() { + let s = Some("foo"); + let _: Option<&str> = s.as_ref().map(|x| x.as_ref()); +} + fn main() { not_ok(); ok(); From 736ac3d30f89d0c2709605d8f58094a833ebf934 Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Tue, 28 Jan 2025 18:33:40 -0500 Subject: [PATCH 023/991] Undo most of last commit and add type alias --- clippy_config/src/types.rs | 88 +++++++---------------- clippy_lints/src/await_holding_invalid.rs | 4 +- clippy_lints/src/disallowed_macros.rs | 9 ++- clippy_lints/src/disallowed_methods.rs | 4 +- clippy_lints/src/disallowed_types.rs | 4 +- 5 files changed, 35 insertions(+), 74 deletions(-) diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index ef3d46892a47..b07188a2b0f6 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -14,41 +14,24 @@ pub struct Rename { pub rename: String, } -#[derive(Debug, Serialize)] -pub struct DisallowedPathWithoutReplacement { - path: String, - reason: Option, -} +pub type DisallowedPathWithoutReplacement = DisallowedPath; -#[derive(Clone, Debug, Serialize)] -pub struct DisallowedPath { +#[derive(Debug, Serialize)] +pub struct DisallowedPath { path: String, reason: Option, replacement: Option, } -impl<'de> Deserialize<'de> for DisallowedPathWithoutReplacement { +impl<'de, const REPLACEMENT_ALLOWED: bool> Deserialize<'de> for DisallowedPath { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { let enum_ = DisallowedPathEnum::deserialize(deserializer)?; - if enum_.replacement().is_some() { + if !REPLACEMENT_ALLOWED && enum_.replacement().is_some() { return Err(de::Error::custom("replacement not allowed for this configuration")); } - Ok(Self { - path: enum_.path().to_owned(), - reason: enum_.reason().map(ToOwned::to_owned), - }) - } -} - -impl<'de> Deserialize<'de> for DisallowedPath { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let enum_ = DisallowedPathEnum::deserialize(deserializer)?; Ok(Self { path: enum_.path().to_owned(), reason: enum_.reason().map(ToOwned::to_owned), @@ -68,48 +51,27 @@ pub enum DisallowedPathEnum { }, } -pub trait AmendDiag { - fn path(&self) -> &str; - fn reason(&self) -> Option<&str>; - fn replacement(&self) -> Option<&str>; - fn amend_diag(&self, span: Span, diag: &mut Diag<'_, ()>) { - if let Some(replacement) = &self.replacement() { - diag.span_suggestion( - span, - self.reason().map_or_else(|| String::from("use"), ToOwned::to_owned), - replacement, - Applicability::MachineApplicable, - ); - } else if let Some(reason) = self.reason() { - diag.note(reason.to_owned()); +impl DisallowedPath { + pub fn path(&self) -> &str { + &self.path + } + + pub fn diag_amendment(&self, span: Span) -> impl FnOnce(&mut Diag<'_, ()>) + use<'_, REPLACEMENT_ALLOWED> { + move |diag| { + if let Some(replacement) = &self.replacement { + diag.span_suggestion( + span, + self.reason.as_ref().map_or_else(|| String::from("use"), Clone::clone), + replacement, + Applicability::MachineApplicable, + ); + } else if let Some(reason) = &self.reason { + diag.note(reason.clone()); + } } } } -impl AmendDiag for DisallowedPathWithoutReplacement { - fn path(&self) -> &str { - &self.path - } - fn reason(&self) -> Option<&str> { - self.reason.as_deref() - } - fn replacement(&self) -> Option<&str> { - None - } -} - -impl AmendDiag for DisallowedPath { - fn path(&self) -> &str { - &self.path - } - fn reason(&self) -> Option<&str> { - self.reason.as_deref() - } - fn replacement(&self) -> Option<&str> { - self.replacement.as_deref() - } -} - impl DisallowedPathEnum { pub fn path(&self) -> &str { let (Self::Simple(path) | Self::WithReason { path, .. }) = self; @@ -133,10 +95,10 @@ impl DisallowedPathEnum { } /// Creates a map of disallowed items to the reason they were disallowed. -pub fn create_disallowed_map( +pub fn create_disallowed_map( tcx: TyCtxt<'_>, - disallowed: &'static [T], -) -> DefIdMap<(&'static str, &'static T)> { + disallowed: &'static [DisallowedPath], +) -> DefIdMap<(&'static str, &'static DisallowedPath)> { disallowed .iter() .map(|x| (x.path(), x.path().split("::").collect::>(), x)) diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs index 3eb87e05a236..92a0c7f9acbc 100644 --- a/clippy_lints/src/await_holding_invalid.rs +++ b/clippy_lints/src/await_holding_invalid.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::{AmendDiag, DisallowedPathWithoutReplacement, create_disallowed_map}; +use clippy_config::types::{DisallowedPathWithoutReplacement, create_disallowed_map}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::{match_def_path, paths}; use rustc_hir as hir; @@ -266,7 +266,7 @@ fn emit_invalid_type( AWAIT_HOLDING_INVALID_TYPE, span, format!("holding a disallowed type across an await point `{path}`"), - |diag| disallowed_path.amend_diag(span, diag), + disallowed_path.diag_amendment(span), ); } diff --git a/clippy_lints/src/disallowed_macros.rs b/clippy_lints/src/disallowed_macros.rs index 629bf416515c..fe0870e8282f 100644 --- a/clippy_lints/src/disallowed_macros.rs +++ b/clippy_lints/src/disallowed_macros.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::{AmendDiag, DisallowedPath, create_disallowed_map}; +use clippy_config::types::{DisallowedPath, create_disallowed_map}; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::macros::macro_backtrace; use rustc_data_structures::fx::FxHashSet; @@ -92,6 +92,7 @@ impl DisallowedMacros { if let Some(&(path, disallowed_path)) = self.disallowed.get(&mac.def_id) { let msg = format!("use of a disallowed macro `{path}`"); + let add_note = disallowed_path.diag_amendment(mac.span); if matches!(mac.kind, MacroKind::Derive) && let Some(derive_src) = derive_src { @@ -101,12 +102,10 @@ impl DisallowedMacros { cx.tcx.local_def_id_to_hir_id(derive_src.def_id), mac.span, msg, - |diag| disallowed_path.amend_diag(mac.span, diag), + add_note, ); } else { - span_lint_and_then(cx, DISALLOWED_MACROS, mac.span, msg, |diag| { - disallowed_path.amend_diag(mac.span, diag); - }); + span_lint_and_then(cx, DISALLOWED_MACROS, mac.span, msg, add_note); } } } diff --git a/clippy_lints/src/disallowed_methods.rs b/clippy_lints/src/disallowed_methods.rs index e6503b310537..0cd9ea13f2e5 100644 --- a/clippy_lints/src/disallowed_methods.rs +++ b/clippy_lints/src/disallowed_methods.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::{AmendDiag, DisallowedPath, create_disallowed_map}; +use clippy_config::types::{DisallowedPath, create_disallowed_map}; use clippy_utils::diagnostics::span_lint_and_then; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefIdMap; @@ -93,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods { DISALLOWED_METHODS, span, format!("use of a disallowed method `{path}`"), - |diag| disallowed_path.amend_diag(span, diag), + disallowed_path.diag_amendment(span), ); } } diff --git a/clippy_lints/src/disallowed_types.rs b/clippy_lints/src/disallowed_types.rs index 15e5b8bb4c5a..a34ec4616e51 100644 --- a/clippy_lints/src/disallowed_types.rs +++ b/clippy_lints/src/disallowed_types.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_config::types::{AmendDiag, DisallowedPath}; +use clippy_config::types::DisallowedPath; use clippy_utils::diagnostics::span_lint_and_then; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::Res; @@ -89,7 +89,7 @@ impl DisallowedTypes { DISALLOWED_TYPES, span, format!("use of a disallowed type `{path}`"), - |diag| disallowed_path.amend_diag(span, diag), + disallowed_path.diag_amendment(span), ); } } From b8275293bab64910de43919d114e5ba8ff8619a5 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 29 Jan 2025 17:21:06 +0100 Subject: [PATCH 024/991] Don't use labeled block as top-level blocks Labeled blocks cannot be used as-is in the "then" or "else" part of an `if` expression. They must be enclosed in an anonymous block. --- clippy_utils/src/source.rs | 4 ++-- tests/ui/match_bool.fixed | 6 ++++++ tests/ui/match_bool.rs | 10 ++++++++++ tests/ui/match_bool.stderr | 21 ++++++++++++++++++++- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index eecbfb3936ac..8f9f27ff4048 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -293,7 +293,7 @@ impl SourceFileRange { } } -/// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`. +/// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block` with no label. pub fn expr_block( sess: &impl HasSession, expr: &Expr<'_>, @@ -304,7 +304,7 @@ pub fn expr_block( ) -> String { let (code, from_macro) = snippet_block_with_context(sess, expr.span, outer, default, indent_relative_to, app); if !from_macro - && let ExprKind::Block(block, _) = expr.kind + && let ExprKind::Block(block, None) = expr.kind && block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) { format!("{code}") diff --git a/tests/ui/match_bool.fixed b/tests/ui/match_bool.fixed index 61a8e54fa10c..1dfb82db1206 100644 --- a/tests/ui/match_bool.fixed +++ b/tests/ui/match_bool.fixed @@ -55,4 +55,10 @@ fn match_bool() { if !(!test && option == 5) { println!("Hello") }; } +fn issue14099() { + if true { 'a: { + break 'a; + } } +} + fn main() {} diff --git a/tests/ui/match_bool.rs b/tests/ui/match_bool.rs index 9c81d2917869..e77f0304feda 100644 --- a/tests/ui/match_bool.rs +++ b/tests/ui/match_bool.rs @@ -103,4 +103,14 @@ fn match_bool() { }; } +fn issue14099() { + match true { + //~^ ERROR: `match` on a boolean expression + true => 'a: { + break 'a; + }, + _ => (), + } +} + fn main() {} diff --git a/tests/ui/match_bool.stderr b/tests/ui/match_bool.stderr index a4e504a0a82e..c05742e56339 100644 --- a/tests/ui/match_bool.stderr +++ b/tests/ui/match_bool.stderr @@ -164,5 +164,24 @@ LL | | _ => println!("Hello"), LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if !(!test && option == 5) { println!("Hello") }` -error: aborting due to 12 previous errors +error: `match` on a boolean expression + --> tests/ui/match_bool.rs:107:5 + | +LL | / match true { +LL | | +LL | | true => 'a: { +LL | | break 'a; +LL | | }, +LL | | _ => (), +LL | | } + | |_____^ + | +help: consider using an `if`/`else` expression + | +LL ~ if true { 'a: { +LL + break 'a; +LL + } } + | + +error: aborting due to 13 previous errors From d13897b829c57e7435bb58b310a5639e129075f5 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Thu, 30 Jan 2025 11:56:49 +0900 Subject: [PATCH 025/991] change the applicability of `if_then_some_else_none` to `MachineApplicable` --- clippy_lints/src/if_then_some_else_none.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs index 3fc0a6965224..869b425b2f0c 100644 --- a/clippy_lints/src/if_then_some_else_none.rs +++ b/clippy_lints/src/if_then_some_else_none.rs @@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { expr.span, format!("this could be simplified with `bool::{method_name}`"), |diag| { - let mut app = Applicability::Unspecified; + let mut app = Applicability::MachineApplicable; let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app) .maybe_par() .to_string(); From 045e36d6a7b797e2eef8ee92bce11a499c319a5b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 30 Jan 2025 14:57:09 -0700 Subject: [PATCH 026/991] doc_link_code: add check for `text`[`adjacent`] style links This is the lint described at https://github.com/rust-lang/rust/pull/136308#issuecomment-2625485331 that recommends using HTML to nest links inside code. --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/doc/mod.rs | 62 +++++++++++++++ tests/ui/doc/link_adjacent.fixed | 52 ++++++++++++ tests/ui/doc/link_adjacent.rs | 52 ++++++++++++ tests/ui/doc/link_adjacent.stderr | 124 +++++++++++++++++++++++++++++ 6 files changed, 292 insertions(+) create mode 100644 tests/ui/doc/link_adjacent.fixed create mode 100644 tests/ui/doc/link_adjacent.rs create mode 100644 tests/ui/doc/link_adjacent.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index cb149ccfeead..4909f15ecaea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5530,6 +5530,7 @@ Released 2018-09-13 [`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression [`doc_include_without_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_include_without_cfg [`doc_lazy_continuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation +[`doc_link_code`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_code [`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes [`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown [`doc_nested_refdefs`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_nested_refdefs diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 1ce6f1256177..95dcd2c16482 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -139,6 +139,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::disallowed_types::DISALLOWED_TYPES_INFO, crate::doc::DOC_INCLUDE_WITHOUT_CFG_INFO, crate::doc::DOC_LAZY_CONTINUATION_INFO, + crate::doc::DOC_LINK_CODE_INFO, crate::doc::DOC_LINK_WITH_QUOTES_INFO, crate::doc::DOC_MARKDOWN_INFO, crate::doc::DOC_NESTED_REFDEFS_INFO, diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 15530c3dbc50..c0ee904002c9 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -84,6 +84,28 @@ declare_clippy_lint! { "presence of `_`, `::` or camel-case outside backticks in documentation" } +declare_clippy_lint! { + /// ### What it does + /// Checks for links with code directly adjacent to code text: + /// `` [`MyItem`]`<`[`u32`]`>` ``. + /// + /// ### Why is this bad? + /// It can be written more simply using HTML-style `` tags. + /// + /// ### Example + /// ```no_run + /// //! [`first`](x)`second` + /// ``` + /// Use instead: + /// ```no_run + /// //! [first](x)second + /// ``` + #[clippy::version = "1.86.0"] + pub DOC_LINK_CODE, + nursery, + "link with code back-to-back with other code" +} + declare_clippy_lint! { /// ### What it does /// Checks for the doc comments of publicly visible @@ -638,6 +660,7 @@ impl Documentation { } impl_lint_pass!(Documentation => [ + DOC_LINK_CODE, DOC_LINK_WITH_QUOTES, DOC_MARKDOWN, DOC_NESTED_REFDEFS, @@ -844,6 +867,14 @@ enum Container { List(usize), } +#[derive(Clone, Copy, Eq, PartialEq)] +enum CodeCluster { + // true means already in a link, so only needs to be followed by code + // false means we've hit code, and need to find a link + First(usize, bool), + Nth(usize, usize), +} + /// Checks parsed documentation. /// This walks the "events" (think sections of markdown) produced by `pulldown_cmark`, /// so lints here will generally access that information. @@ -875,9 +906,40 @@ fn check_doc<'a, Events: Iterator, Range { + Some(CodeCluster::First(range.start - 1, true)) + }, + (None, Code(_)) => Some(CodeCluster::First(range.start, false)), + (Some(CodeCluster::First(pos, _)), Start(Link { .. })) | (Some(CodeCluster::First(pos, true)), Code(_)) => { + Some(CodeCluster::Nth(pos, range.end)) + }, + (Some(CodeCluster::Nth(start, end)), Code(_) | Start(Link { .. })) => { + Some(CodeCluster::Nth(start, range.end.max(end))) + }, + (code_cluster @ Some(_), Code(_) | End(TagEnd::Link)) => code_cluster, + (Some(CodeCluster::First(_, _)) | None, _) => None, + (Some(CodeCluster::Nth(start, end)), _) => { + if let Some(span) = fragments.span(cx, start..end) { + span_lint_and_then(cx, DOC_LINK_CODE, span, "code link adjacent to code text", |diag| { + let sugg = format!("{}", doc[start..end].replace('`', "")); + diag.span_suggestion_verbose( + span, + "wrap the entire group in `` tags", + sugg, + Applicability::MaybeIncorrect, + ); + diag.help("separate code snippets will be shown with a gap"); + }); + } + None + }, + }; match event { Html(tag) | InlineHtml(tag) => { if tag.starts_with("[first](x)second +//~^ ERROR: adjacent +//! +//! So is this first[second](x) +//~^ ERROR: adjacent +//! +//! So is this [first](x)[second](x) +//~^ ERROR: adjacent +//! +//! So is this [first](x)[second](x)[third](x) +//~^ ERROR: adjacent +//! +//! So is this [first](x)second[third](x) +//~^ ERROR: adjacent + +/// Test case for code links that are adjacent to code text. +/// +/// This is not an example: `first``second` arst +/// +/// Neither is this: [`first`](x) arst +/// +/// Neither is this: [`first`](x) `second` arst +/// +/// Neither is this: [first](x)`second` arst +/// +/// This is: [first](x)second arst +//~^ ERROR: adjacent +/// +/// So is this first[second](x) arst +//~^ ERROR: adjacent +/// +/// So is this [first](x)[second](x) arst +//~^ ERROR: adjacent +/// +/// So is this [first](x)[second](x)[third](x) arst +//~^ ERROR: adjacent +/// +/// So is this [first](x)second[third](x) arst +//~^ ERROR: adjacent +pub struct WithTrailing; diff --git a/tests/ui/doc/link_adjacent.rs b/tests/ui/doc/link_adjacent.rs new file mode 100644 index 000000000000..af6755eeff61 --- /dev/null +++ b/tests/ui/doc/link_adjacent.rs @@ -0,0 +1,52 @@ +#![warn(clippy::doc_link_code)] + +//! Test case for code links that are adjacent to code text. +//! +//! This is not an example: `first``second` +//! +//! Neither is this: [`first`](x) +//! +//! Neither is this: [`first`](x) `second` +//! +//! Neither is this: [first](x)`second` +//! +//! This is: [`first`](x)`second` +//~^ ERROR: adjacent +//! +//! So is this `first`[`second`](x) +//~^ ERROR: adjacent +//! +//! So is this [`first`](x)[`second`](x) +//~^ ERROR: adjacent +//! +//! So is this [`first`](x)[`second`](x)[`third`](x) +//~^ ERROR: adjacent +//! +//! So is this [`first`](x)`second`[`third`](x) +//~^ ERROR: adjacent + +/// Test case for code links that are adjacent to code text. +/// +/// This is not an example: `first``second` arst +/// +/// Neither is this: [`first`](x) arst +/// +/// Neither is this: [`first`](x) `second` arst +/// +/// Neither is this: [first](x)`second` arst +/// +/// This is: [`first`](x)`second` arst +//~^ ERROR: adjacent +/// +/// So is this `first`[`second`](x) arst +//~^ ERROR: adjacent +/// +/// So is this [`first`](x)[`second`](x) arst +//~^ ERROR: adjacent +/// +/// So is this [`first`](x)[`second`](x)[`third`](x) arst +//~^ ERROR: adjacent +/// +/// So is this [`first`](x)`second`[`third`](x) arst +//~^ ERROR: adjacent +pub struct WithTrailing; diff --git a/tests/ui/doc/link_adjacent.stderr b/tests/ui/doc/link_adjacent.stderr new file mode 100644 index 000000000000..f09762fb6a0b --- /dev/null +++ b/tests/ui/doc/link_adjacent.stderr @@ -0,0 +1,124 @@ +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:13:14 + | +LL | //! This is: [`first`](x)`second` + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap + = note: `-D clippy::doc-link-code` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_link_code)]` +help: wrap the entire group in `` tags + | +LL | //! This is: [first](x)second + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:16:16 + | +LL | //! So is this `first`[`second`](x) + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap +help: wrap the entire group in `` tags + | +LL | //! So is this first[second](x) + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:19:16 + | +LL | //! So is this [`first`](x)[`second`](x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap +help: wrap the entire group in `` tags + | +LL | //! So is this [first](x)[second](x) + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:22:16 + | +LL | //! So is this [`first`](x)[`second`](x)[`third`](x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap +help: wrap the entire group in `` tags + | +LL | //! So is this [first](x)[second](x)[third](x) + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:25:16 + | +LL | //! So is this [`first`](x)`second`[`third`](x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap +help: wrap the entire group in `` tags + | +LL | //! So is this [first](x)second[third](x) + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:38:14 + | +LL | /// This is: [`first`](x)`second` arst + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap +help: wrap the entire group in `` tags + | +LL | /// This is: [first](x)second arst + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:41:16 + | +LL | /// So is this `first`[`second`](x) arst + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap +help: wrap the entire group in `` tags + | +LL | /// So is this first[second](x) arst + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:44:16 + | +LL | /// So is this [`first`](x)[`second`](x) arst + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap +help: wrap the entire group in `` tags + | +LL | /// So is this [first](x)[second](x) arst + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:47:16 + | +LL | /// So is this [`first`](x)[`second`](x)[`third`](x) arst + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap +help: wrap the entire group in `` tags + | +LL | /// So is this [first](x)[second](x)[third](x) arst + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: code link adjacent to code text + --> tests/ui/doc/link_adjacent.rs:50:16 + | +LL | /// So is this [`first`](x)`second`[`third`](x) arst + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: separate code snippets will be shown with a gap +help: wrap the entire group in `` tags + | +LL | /// So is this [first](x)second[third](x) arst + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 10 previous errors + From 58d483409705aa4063eec5edbe6bb020adcacb59 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sat, 1 Feb 2025 02:30:50 +0300 Subject: [PATCH 027/991] Resolve projections during internal mutability analysis --- clippy_lints/src/non_copy_const.rs | 6 +++ clippy_utils/src/ty/mod.rs | 4 ++ .../projections.rs | 42 ++++++++++++++++++ .../projections.stderr | 44 +++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 tests/ui/borrow_interior_mutable_const/projections.rs create mode 100644 tests/ui/borrow_interior_mutable_const/projections.stderr diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 147654675ec9..0d89b4e85350 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -215,6 +215,12 @@ impl<'tcx> NonCopyConst<'tcx> { .iter() .zip(tys) .any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)), + ty::Alias(ty::Projection, _) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) { + Ok(normalized_ty) if ty != normalized_ty => { + Self::is_value_unfrozen_raw_inner(cx, ty::ValTree::Branch(val), normalized_ty) + }, + _ => false, + }, _ => false, } } diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index f2bbdda70585..5201036d84d3 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -1227,6 +1227,10 @@ impl<'tcx> InteriorMut<'tcx> { .find_map(|f| self.interior_mut_ty_chain(cx, f.ty(cx.tcx, args))) } }, + ty::Alias(ty::Projection, _) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) { + Ok(normalized_ty) if ty != normalized_ty => self.interior_mut_ty_chain(cx, normalized_ty), + _ => None, + }, _ => None, }; diff --git a/tests/ui/borrow_interior_mutable_const/projections.rs b/tests/ui/borrow_interior_mutable_const/projections.rs new file mode 100644 index 000000000000..bbe5538fbe12 --- /dev/null +++ b/tests/ui/borrow_interior_mutable_const/projections.rs @@ -0,0 +1,42 @@ +#![deny(clippy::borrow_interior_mutable_const)] +#![deny(clippy::declare_interior_mutable_const)] + +// Inspired by https://github.com/rust-lang/rust/pull/130543#issuecomment-2364828139 + +use std::cell::UnsafeCell; + +trait Trait { + type Assoc; +} + +type Assoc = ::Assoc; + +impl Trait for u8 { + type Assoc = UnsafeCell; +} + +impl Trait for () { + type Assoc = (); +} + +enum MaybeMutable { + Mutable(Assoc), + Immutable(Assoc<()>), +} + +const CELL: Assoc = UnsafeCell::new(0); //~ ERROR: interior mutable +const UNIT: Assoc<()> = (); +const MUTABLE: MaybeMutable = MaybeMutable::Mutable(CELL); //~ ERROR: interior mutable +const IMMUTABLE: MaybeMutable = MaybeMutable::Immutable(UNIT); + +fn print_ref(t: &T) { + let p: *const T = t; + println!("{p:p}") +} + +fn main() { + print_ref(&CELL); //~ ERROR: interior mutability + print_ref(&UNIT); + print_ref(&MUTABLE); //~ ERROR: interior mutability + print_ref(&IMMUTABLE); +} diff --git a/tests/ui/borrow_interior_mutable_const/projections.stderr b/tests/ui/borrow_interior_mutable_const/projections.stderr new file mode 100644 index 000000000000..eabaf66560ad --- /dev/null +++ b/tests/ui/borrow_interior_mutable_const/projections.stderr @@ -0,0 +1,44 @@ +error: a `const` item should not be interior mutable + --> tests/ui/borrow_interior_mutable_const/projections.rs:27:1 + | +LL | const CELL: Assoc = UnsafeCell::new(0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider making this `Sync` so that it can go in a static item or using a `thread_local` +note: the lint level is defined here + --> tests/ui/borrow_interior_mutable_const/projections.rs:2:9 + | +LL | #![deny(clippy::declare_interior_mutable_const)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a `const` item should not be interior mutable + --> tests/ui/borrow_interior_mutable_const/projections.rs:29:1 + | +LL | const MUTABLE: MaybeMutable = MaybeMutable::Mutable(CELL); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider making this `Sync` so that it can go in a static item or using a `thread_local` + +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/projections.rs:38:16 + | +LL | print_ref(&CELL); + | ^^^^ + | + = help: assign this const to a local or static variable, and use the variable here +note: the lint level is defined here + --> tests/ui/borrow_interior_mutable_const/projections.rs:1:9 + | +LL | #![deny(clippy::borrow_interior_mutable_const)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/projections.rs:40:16 + | +LL | print_ref(&MUTABLE); + | ^^^^^^^ + | + = help: assign this const to a local or static variable, and use the variable here + +error: aborting due to 4 previous errors + From 2a52fbe5daaa0f9e583b6f75067c0ef16bf1be9c Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Sat, 1 Feb 2025 12:42:39 +0900 Subject: [PATCH 028/991] add MSRV check for `repeat_vec_with_capacity` --- book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_lints/src/lib.rs | 2 +- clippy_lints/src/repeat_vec_with_capacity.rs | 24 +++++++++++++++++--- tests/ui/repeat_vec_with_capacity.fixed | 5 ++++ tests/ui/repeat_vec_with_capacity.rs | 5 ++++ 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index b8f9fff9c613..dfce429a8eeb 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -769,6 +769,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr) * [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names) * [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes) +* [`repeat_vec_with_capacity`](https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity) * [`same_item_push`](https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push) * [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current) * [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 552141476f3a..c2e97498f4df 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -638,6 +638,7 @@ define_Conf! { ptr_as_ptr, redundant_field_names, redundant_static_lifetimes, + repeat_vec_with_capacity, same_item_push, seek_from_current, seek_rewind, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 4b700673d0f8..7f7755015ffc 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -944,7 +944,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::>::default()); store.register_late_pass(|_| Box::new(iter_over_hash_type::IterOverHashType)); store.register_late_pass(|_| Box::new(impl_hash_with_borrow_str_and_bytes::ImplHashWithBorrowStrBytes)); - store.register_late_pass(|_| Box::new(repeat_vec_with_capacity::RepeatVecWithCapacity)); + store.register_late_pass(move |_| Box::new(repeat_vec_with_capacity::RepeatVecWithCapacity::new(conf))); store.register_late_pass(|_| Box::new(uninhabited_references::UninhabitedReferences)); store.register_late_pass(|_| Box::new(ineffective_open_options::IneffectiveOpenOptions)); store.register_late_pass(|_| Box::::default()); diff --git a/clippy_lints/src/repeat_vec_with_capacity.rs b/clippy_lints/src/repeat_vec_with_capacity.rs index 5dddf9263a35..40263afd28f1 100644 --- a/clippy_lints/src/repeat_vec_with_capacity.rs +++ b/clippy_lints/src/repeat_vec_with_capacity.rs @@ -1,15 +1,29 @@ +use clippy_config::Conf; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::VecArgs; use clippy_utils::macros::matching_root_macro_call; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet; use clippy_utils::{expr_or_init, fn_def_id, std_or_core}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::declare_lint_pass; +use rustc_session::impl_lint_pass; use rustc_span::{Span, sym}; +pub struct RepeatVecWithCapacity { + msrv: Msrv, +} + +impl RepeatVecWithCapacity { + pub fn new(conf: &'static Conf) -> Self { + Self { + msrv: conf.msrv.clone(), + } + } +} + declare_clippy_lint! { /// ### What it does /// Looks for patterns such as `vec![Vec::with_capacity(x); n]` or `iter::repeat(Vec::with_capacity(x))`. @@ -48,7 +62,7 @@ declare_clippy_lint! { "repeating a `Vec::with_capacity` expression which does not retain capacity" } -declare_lint_pass!(RepeatVecWithCapacity => [REPEAT_VEC_WITH_CAPACITY]); +impl_lint_pass!(RepeatVecWithCapacity => [REPEAT_VEC_WITH_CAPACITY]); fn emit_lint(cx: &LateContext<'_>, span: Span, kind: &str, note: &'static str, sugg_msg: &'static str, sugg: String) { span_lint_and_then( @@ -112,6 +126,10 @@ fn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>) { impl LateLintPass<'_> for RepeatVecWithCapacity { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { check_vec_macro(cx, expr); - check_repeat_fn(cx, expr); + if self.msrv.meets(msrvs::REPEAT_WITH) { + check_repeat_fn(cx, expr); + } } + + extract_msrv_attr!(LateContext); } diff --git a/tests/ui/repeat_vec_with_capacity.fixed b/tests/ui/repeat_vec_with_capacity.fixed index f72b61b5f6cd..34d9d7c3d71d 100644 --- a/tests/ui/repeat_vec_with_capacity.fixed +++ b/tests/ui/repeat_vec_with_capacity.fixed @@ -37,3 +37,8 @@ fn main() { from_macro!(Vec::<()>::with_capacity(42)); } } + +#[clippy::msrv = "1.27.0"] +fn msrv_check() { + std::iter::repeat(Vec::<()>::with_capacity(42)); +} diff --git a/tests/ui/repeat_vec_with_capacity.rs b/tests/ui/repeat_vec_with_capacity.rs index c0cc81f78436..6c7740b198aa 100644 --- a/tests/ui/repeat_vec_with_capacity.rs +++ b/tests/ui/repeat_vec_with_capacity.rs @@ -37,3 +37,8 @@ fn main() { from_macro!(Vec::<()>::with_capacity(42)); } } + +#[clippy::msrv = "1.27.0"] +fn msrv_check() { + std::iter::repeat(Vec::<()>::with_capacity(42)); +} From f9669e4caf219512b34546a13f39d80179511259 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Sat, 1 Feb 2025 15:20:34 +0900 Subject: [PATCH 029/991] add MSRV check for `lines_filter_map_ok` --- book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_lints/src/lib.rs | 2 +- clippy_lints/src/lines_filter_map_ok.rs | 24 +++++++++++++++++++++--- clippy_utils/src/msrvs.rs | 1 + tests/ui/lines_filter_map_ok.fixed | 7 +++++++ tests/ui/lines_filter_map_ok.rs | 7 +++++++ 7 files changed, 39 insertions(+), 4 deletions(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index b8f9fff9c613..998668fabf02 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -740,6 +740,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice) * [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map) * [`legacy_numeric_constants`](https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants) +* [`lines_filter_map_ok`](https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok) * [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits) * [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals) * [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 552141476f3a..cefcf81bcf06 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -609,6 +609,7 @@ define_Conf! { index_refutable_slice, iter_kv_map, legacy_numeric_constants, + lines_filter_map_ok, manual_bits, manual_c_str_literals, manual_clamp, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 4b700673d0f8..4da3160ee24e 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -900,7 +900,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(conf))); store.register_late_pass(|_| Box::new(unnecessary_struct_initialization::UnnecessaryStruct)); store.register_late_pass(move |_| Box::new(unnecessary_box_returns::UnnecessaryBoxReturns::new(conf))); - store.register_late_pass(|_| Box::new(lines_filter_map_ok::LinesFilterMapOk)); + store.register_late_pass(move |_| Box::new(lines_filter_map_ok::LinesFilterMapOk::new(conf))); store.register_late_pass(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule)); store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation)); store.register_early_pass(move || Box::new(excessive_nesting::ExcessiveNesting::new(conf))); diff --git a/clippy_lints/src/lines_filter_map_ok.rs b/clippy_lints/src/lines_filter_map_ok.rs index 8206c75927b7..8c237191405a 100644 --- a/clippy_lints/src/lines_filter_map_ok.rs +++ b/clippy_lints/src/lines_filter_map_ok.rs @@ -1,12 +1,26 @@ +use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{is_diag_item_method, is_trait_method, path_to_local_id}; use rustc_errors::Applicability; use rustc_hir::{Body, Closure, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::declare_lint_pass; +use rustc_session::impl_lint_pass; use rustc_span::sym; +pub struct LinesFilterMapOk { + msrv: Msrv, +} + +impl LinesFilterMapOk { + pub fn new(conf: &Conf) -> Self { + Self { + msrv: conf.msrv.clone(), + } + } +} + declare_clippy_lint! { /// ### What it does /// Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` @@ -55,11 +69,13 @@ declare_clippy_lint! { suspicious, "filtering `std::io::Lines` with `filter_map()`, `flat_map()`, or `flatten()` might cause an infinite loop" } -declare_lint_pass!(LinesFilterMapOk => [LINES_FILTER_MAP_OK]); + +impl_lint_pass!(LinesFilterMapOk => [LINES_FILTER_MAP_OK]); impl LateLintPass<'_> for LinesFilterMapOk { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if let ExprKind::MethodCall(fm_method, fm_receiver, fm_args, fm_span) = expr.kind + if self.msrv.meets(msrvs::MAP_WHILE) + && let ExprKind::MethodCall(fm_method, fm_receiver, fm_args, fm_span) = expr.kind && is_trait_method(cx, expr, sym::Iterator) && let fm_method_str = fm_method.ident.as_str() && matches!(fm_method_str, "filter_map" | "flat_map" | "flatten") @@ -85,6 +101,8 @@ impl LateLintPass<'_> for LinesFilterMapOk { ); } } + + extract_msrv_attr!(LateContext); } fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> bool { diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index d73cb7e35611..34c575c66be5 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -34,6 +34,7 @@ msrv_aliases! { 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_C_FN } 1,59,0 { THREAD_LOCAL_CONST_INIT } 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY, CONST_RAW_PTR_DEREF } + 1,57,0 { MAP_WHILE } 1,56,0 { CONST_FN_UNION } 1,55,0 { SEEK_REWIND } 1,54,0 { INTO_KEYS } diff --git a/tests/ui/lines_filter_map_ok.fixed b/tests/ui/lines_filter_map_ok.fixed index 621115cc1325..ae388ec39a15 100644 --- a/tests/ui/lines_filter_map_ok.fixed +++ b/tests/ui/lines_filter_map_ok.fixed @@ -31,3 +31,10 @@ fn main() -> io::Result<()> { io::stdin().lines().filter_map(|x| x.err()).for_each(|_| ()); Ok(()) } + +#[clippy::msrv = "1.56"] +fn msrv_check() { + let _lines = BufReader::new(std::fs::File::open("some-path").unwrap()) + .lines() + .filter_map(Result::ok); +} diff --git a/tests/ui/lines_filter_map_ok.rs b/tests/ui/lines_filter_map_ok.rs index a86efbd66862..4f486534e9b0 100644 --- a/tests/ui/lines_filter_map_ok.rs +++ b/tests/ui/lines_filter_map_ok.rs @@ -31,3 +31,10 @@ fn main() -> io::Result<()> { io::stdin().lines().filter_map(|x| x.err()).for_each(|_| ()); Ok(()) } + +#[clippy::msrv = "1.56"] +fn msrv_check() { + let _lines = BufReader::new(std::fs::File::open("some-path").unwrap()) + .lines() + .filter_map(Result::ok); +} From 2a7d1d4c0b1b6b06ffa6868cf10ace2a7b634129 Mon Sep 17 00:00:00 2001 From: alexey semenyuk Date: Sat, 1 Feb 2025 23:52:12 +0500 Subject: [PATCH 030/991] Remove `Known problems` section `invalid_upcast_comparisons` --- clippy_lints/src/invalid_upcast_comparisons.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/clippy_lints/src/invalid_upcast_comparisons.rs b/clippy_lints/src/invalid_upcast_comparisons.rs index 1929fbded3b5..b42664340d1c 100644 --- a/clippy_lints/src/invalid_upcast_comparisons.rs +++ b/clippy_lints/src/invalid_upcast_comparisons.rs @@ -22,9 +22,6 @@ declare_clippy_lint! { /// will mistakenly imply that it is possible for `x` to be outside the range of /// `u8`. /// - /// ### Known problems - /// https://github.com/rust-lang/rust-clippy/issues/886 - /// /// ### Example /// ```no_run /// let x: u8 = 1; From a5329bd8d38983a57fd66098745099048fa90a2a Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Sun, 2 Feb 2025 23:44:22 +0900 Subject: [PATCH 031/991] autofix for `range_zip_with_len` --- clippy_lints/src/methods/range_zip_with_len.rs | 13 +++++++------ tests/ui/range.fixed | 18 ++++++++++++++++++ tests/ui/range.rs | 3 +-- tests/ui/range.stderr | 4 ++-- 4 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 tests/ui/range.fixed diff --git a/clippy_lints/src/methods/range_zip_with_len.rs b/clippy_lints/src/methods/range_zip_with_len.rs index f4d206c5307c..3a5e32172086 100644 --- a/clippy_lints/src/methods/range_zip_with_len.rs +++ b/clippy_lints/src/methods/range_zip_with_len.rs @@ -1,6 +1,7 @@ -use clippy_utils::diagnostics::span_lint; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; use clippy_utils::{SpanlessEq, higher, is_integer_const, is_trait_method}; +use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::LateContext; use rustc_span::sym; @@ -20,14 +21,14 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &' && let ExprKind::Path(QPath::Resolved(_, len_path)) = len_recv.kind && SpanlessEq::new(cx).eq_path_segments(iter_path.segments, len_path.segments) { - span_lint( + span_lint_and_sugg( cx, RANGE_ZIP_WITH_LEN, expr.span, - format!( - "it is more idiomatic to use `{}.iter().enumerate()`", - snippet(cx, recv.span, "_") - ), + "using `.zip()` with a range and `.len()`", + "try", + format!("{}.iter().enumerate()", snippet(cx, recv.span, "_")), + Applicability::MachineApplicable, ); } } diff --git a/tests/ui/range.fixed b/tests/ui/range.fixed new file mode 100644 index 000000000000..82aa1b5f94fd --- /dev/null +++ b/tests/ui/range.fixed @@ -0,0 +1,18 @@ +#![allow(clippy::useless_vec)] +#[warn(clippy::range_zip_with_len)] +fn main() { + let v1 = vec![1, 2, 3]; + let v2 = vec![4, 5]; + let _x = v1.iter().enumerate(); + //~^ ERROR: using `.zip()` with a range and `.len()` + let _y = v1.iter().zip(0..v2.len()); // No error +} + +#[allow(unused)] +fn no_panic_with_fake_range_types() { + struct Range { + foo: i32, + } + + let _ = Range { foo: 0 }; +} diff --git a/tests/ui/range.rs b/tests/ui/range.rs index 9541812b0691..a7d5cf38dfb5 100644 --- a/tests/ui/range.rs +++ b/tests/ui/range.rs @@ -4,8 +4,7 @@ fn main() { let v1 = vec![1, 2, 3]; let v2 = vec![4, 5]; let _x = v1.iter().zip(0..v1.len()); - //~^ ERROR: it is more idiomatic to use `v1.iter().enumerate()` - //~| NOTE: `-D clippy::range-zip-with-len` implied by `-D warnings` + //~^ ERROR: using `.zip()` with a range and `.len()` let _y = v1.iter().zip(0..v2.len()); // No error } diff --git a/tests/ui/range.stderr b/tests/ui/range.stderr index 8c71a209700e..798ce1842d8b 100644 --- a/tests/ui/range.stderr +++ b/tests/ui/range.stderr @@ -1,8 +1,8 @@ -error: it is more idiomatic to use `v1.iter().enumerate()` +error: using `.zip()` with a range and `.len()` --> tests/ui/range.rs:6:14 | LL | let _x = v1.iter().zip(0..v1.len()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v1.iter().enumerate()` | = note: `-D clippy::range-zip-with-len` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::range_zip_with_len)]` From 3f57fc170aab2da57ff0c695051bfd26571b9391 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 3 Feb 2025 04:55:59 +0000 Subject: [PATCH 032/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 6e84524c8aa8..b62959720764 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -6dd75f0d6802f56564f5f9c947a85ded286d3986 +613bdd49978298648ed05ace086bd1ecad54b44a From 5884fd0325325bcdfddb2dc431827c8b4656be1c Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Mon, 3 Feb 2025 06:44:41 +0300 Subject: [PATCH 033/991] tree-wide: parallel: Fully removed all `Lrc`, replaced with `Arc` --- clippy_lints/src/attrs/mixed_attributes_style.rs | 6 +++--- clippy_lints/src/doc/needless_doctest_main.rs | 6 +++--- clippy_lints/src/undocumented_unsafe_blocks.rs | 10 +++++----- clippy_lints/src/utils/attr_collector.rs | 5 ++--- clippy_utils/src/consts.rs | 7 ++++--- clippy_utils/src/macros.rs | 6 ++++-- clippy_utils/src/source.rs | 7 ++++--- 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/clippy_lints/src/attrs/mixed_attributes_style.rs b/clippy_lints/src/attrs/mixed_attributes_style.rs index 3e4bcfbfc190..5a26ba8bf932 100644 --- a/clippy_lints/src/attrs/mixed_attributes_style.rs +++ b/clippy_lints/src/attrs/mixed_attributes_style.rs @@ -1,8 +1,8 @@ +use std::sync::Arc; use super::MIXED_ATTRIBUTES_STYLE; use clippy_utils::diagnostics::span_lint; use rustc_ast::{AttrKind, AttrStyle, Attribute}; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::sync::Lrc; use rustc_lint::{EarlyContext, LintContext}; use rustc_span::source_map::SourceMap; use rustc_span::{SourceFile, Span, Symbol}; @@ -79,7 +79,7 @@ fn lint_mixed_attrs(cx: &EarlyContext<'_>, attrs: &[Attribute]) { ); } -fn attr_in_same_src_as_item(source_map: &SourceMap, item_src: &Lrc, attr_span: Span) -> bool { +fn attr_in_same_src_as_item(source_map: &SourceMap, item_src: &Arc, attr_span: Span) -> bool { let attr_src = source_map.lookup_source_file(attr_span.lo()); - Lrc::ptr_eq(item_src, &attr_src) + Arc::ptr_eq(item_src, &attr_src) } diff --git a/clippy_lints/src/doc/needless_doctest_main.rs b/clippy_lints/src/doc/needless_doctest_main.rs index 9ba2723157ad..ce5beab24bfa 100644 --- a/clippy_lints/src/doc/needless_doctest_main.rs +++ b/clippy_lints/src/doc/needless_doctest_main.rs @@ -1,10 +1,10 @@ use std::ops::Range; use std::{io, thread}; +use std::sync::Arc; use crate::doc::{NEEDLESS_DOCTEST_MAIN, TEST_ATTR_IN_DOCTEST}; use clippy_utils::diagnostics::span_lint; use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind}; -use rustc_data_structures::sync::Lrc; use rustc_errors::emitter::HumanEmitter; use rustc_errors::{Diag, DiagCtxt}; use rustc_lint::LateContext; @@ -46,8 +46,8 @@ pub fn check( rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false); let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle); let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings(); - #[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_dcx - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + #[expect(clippy::arc_with_non_send_sync)] // `Arc` is expected by with_dcx + let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); let psess = ParseSess::with_dcx(dcx, sm); let mut parser = match new_parser_from_source_str(&psess, filename, code) { diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index 5e5d6a9e333b..b3d269080930 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -1,3 +1,4 @@ +use std::sync::Arc; use std::ops::ControlFlow; use clippy_config::Conf; @@ -6,7 +7,6 @@ use clippy_utils::is_lint_allowed; use clippy_utils::source::walk_span_to_context; use clippy_utils::visitors::{Descend, for_each_expr}; use hir::HirId; -use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource}; use rustc_lexer::{TokenKind, tokenize}; @@ -480,7 +480,7 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf if let Some(comment_start) = comment_start && let Ok(unsafe_line) = source_map.lookup_line(item.span.lo()) && let Ok(comment_start_line) = source_map.lookup_line(comment_start) - && Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf) + && Arc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf) && let Some(src) = unsafe_line.sf.src.as_deref() { return if comment_start_line.line >= unsafe_line.line { @@ -520,7 +520,7 @@ fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> H if let Some(comment_start) = comment_start && let Ok(unsafe_line) = source_map.lookup_line(span.lo()) && let Ok(comment_start_line) = source_map.lookup_line(comment_start) - && Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf) + && Arc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf) && let Some(src) = unsafe_line.sf.src.as_deref() { return if comment_start_line.line >= unsafe_line.line { @@ -580,7 +580,7 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span // ^--------------------------------------------^ if let Ok(unsafe_line) = source_map.lookup_line(span.lo()) && let Ok(macro_line) = source_map.lookup_line(ctxt.outer_expn_data().def_site.lo()) - && Lrc::ptr_eq(&unsafe_line.sf, ¯o_line.sf) + && Arc::ptr_eq(&unsafe_line.sf, ¯o_line.sf) && let Some(src) = unsafe_line.sf.src.as_deref() { if macro_line.line < unsafe_line.line { @@ -641,7 +641,7 @@ fn span_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { if let Ok(unsafe_line) = source_map.lookup_line(span.lo()) && let Some(body_span) = walk_span_to_context(search_span, SyntaxContext::root()) && let Ok(body_line) = source_map.lookup_line(body_span.lo()) - && Lrc::ptr_eq(&unsafe_line.sf, &body_line.sf) + && Arc::ptr_eq(&unsafe_line.sf, &body_line.sf) && let Some(src) = unsafe_line.sf.src.as_deref() { // Get the text from the start of function body to the unsafe block. diff --git a/clippy_lints/src/utils/attr_collector.rs b/clippy_lints/src/utils/attr_collector.rs index 1522553bbf52..169429811d32 100644 --- a/clippy_lints/src/utils/attr_collector.rs +++ b/clippy_lints/src/utils/attr_collector.rs @@ -1,14 +1,13 @@ use std::mem; -use std::sync::OnceLock; +use std::sync::{Arc, OnceLock}; use rustc_ast::{Attribute, Crate}; -use rustc_data_structures::sync::Lrc; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::impl_lint_pass; use rustc_span::Span; #[derive(Clone, Default)] -pub struct AttrStorage(pub Lrc>>); +pub struct AttrStorage(pub Arc>>); pub struct AttrCollector { storage: AttrStorage, diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index a660623f4185..fab1db05d2e5 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -4,13 +4,14 @@ //! executable MIR bodies, so we have to do this instead. #![allow(clippy::float_cmp)] +use std::sync::Arc; + use crate::source::{SpanRangeExt, walk_span_to_context}; use crate::{clip, is_direct_expn_of, sext, unsext}; use rustc_apfloat::Float; use rustc_apfloat::ieee::{Half, Quad}; use rustc_ast::ast::{self, LitFloatType, LitKind}; -use rustc_data_structures::sync::Lrc; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{ BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp, @@ -37,7 +38,7 @@ pub enum Constant<'tcx> { /// A `String` (e.g., "abc"). Str(String), /// A binary string (e.g., `b"abc"`). - Binary(Lrc<[u8]>), + Binary(Arc<[u8]>), /// A single `char` (e.g., `'a'`). Char(char), /// An integer's bit representation. @@ -305,7 +306,7 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option>) -> Constan match *lit { LitKind::Str(ref is, _) => Constant::Str(is.to_string()), LitKind::Byte(b) => Constant::Int(u128::from(b)), - LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(Lrc::clone(s)), + LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(Arc::clone(s)), LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, _) => Constant::Int(n.get()), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index f4c730ef118b..30fd48fc0605 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -1,12 +1,14 @@ #![allow(clippy::similar_names)] // `expr` and `expn` +use std::sync::Arc; + use crate::get_unique_attr; use crate::visitors::{Descend, for_each_expr_without_closures}; use arrayvec::ArrayVec; use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::{Lrc, OnceLock}; +use rustc_data_structures::sync::OnceLock; use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath}; use rustc_lint::{LateContext, LintContext}; use rustc_span::def_id::DefId; @@ -393,7 +395,7 @@ fn is_assert_arg(cx: &LateContext<'_>, expr: &Expr<'_>, assert_expn: ExpnId) -> /// Stores AST [`FormatArgs`] nodes for use in late lint passes, as they are in a desugared form in /// the HIR #[derive(Default, Clone)] -pub struct FormatArgsStorage(Lrc>>); +pub struct FormatArgsStorage(Arc>>); impl FormatArgsStorage { /// Returns an AST [`FormatArgs`] node if a `format_args` expansion is found as a descendant of diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index eecbfb3936ac..2700ef139e6f 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -2,8 +2,9 @@ #![allow(clippy::module_name_repetitions)] +use std::sync::Arc; + use rustc_ast::{LitKind, StrStyle}; -use rustc_data_structures::sync::Lrc; use rustc_errors::Applicability; use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource}; use rustc_lint::{EarlyContext, LateContext}; @@ -204,7 +205,7 @@ impl fmt::Display for SourceText { fn get_source_range(sm: &SourceMap, sp: Range) -> Option { let start = sm.lookup_byte_offset(sp.start); let end = sm.lookup_byte_offset(sp.end); - if !Lrc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos { + if !Arc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos { return None; } sm.ensure_source_file_source_present(&start.sf); @@ -277,7 +278,7 @@ fn trim_start(sm: &SourceMap, sp: Range) -> Range { } pub struct SourceFileRange { - pub sf: Lrc, + pub sf: Arc, pub range: Range, } impl SourceFileRange { From 64dec0760e652878399155e4621063ecce88b12b Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 29 Jan 2025 17:28:03 +0100 Subject: [PATCH 034/991] Simplify `reindent_multiline()` signature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `reindent_multiline()` always returns the result of `reindent_multiline_inner()` which returns a `String`. Make `reindent_multiline()` return a `String` as well, instead of a systematically owned `Cow<'_, str>`. - There is no reason for `reindent_multiline()` to force a caller to build a `Cow<'_, str>` instead of passing a `&str` directly, especially considering that a `String` will always be returned. Also, both the input parameter and return value (of type `Cow<'_, str>`) shared the same (elided) lifetime for no reason: this worked only because the result was always the `Cow::Owned` variant which is compatible with any lifetime. As a consequence, the signature changes from: ```rust fn reindent_multiline(s: Cow<'_, str>, …) -> Cow<'_, str> { … } ``` to ```rust fn reindent_multiline(s: &str, …) -> String { … } ``` --- clippy_lints/src/copies.rs | 11 ++-- clippy_lints/src/entry.rs | 4 +- clippy_lints/src/if_not_else.rs | 5 +- clippy_lints/src/matches/manual_unwrap_or.rs | 2 +- ...se_sensitive_file_extension_comparisons.rs | 5 +- clippy_lints/src/methods/filter_map.rs | 5 +- clippy_lints/src/methods/iter_filter.rs | 5 +- clippy_lints/src/methods/manual_ok_or.rs | 2 +- clippy_lints/src/methods/return_and_then.rs | 2 +- clippy_lints/src/needless_continue.rs | 2 +- clippy_lints/src/redundant_else.rs | 10 +--- clippy_lints/src/unit_types/unit_arg.rs | 5 +- clippy_utils/src/source.rs | 52 ++++++++----------- 13 files changed, 46 insertions(+), 64 deletions(-) diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 89808d38b9f3..7c783df4f805 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -18,7 +18,6 @@ use rustc_session::impl_lint_pass; use rustc_span::hygiene::walk_chain; use rustc_span::source_map::SourceMap; use rustc_span::{Span, Symbol}; -use std::borrow::Cow; declare_clippy_lint! { /// ### What it does @@ -248,18 +247,18 @@ fn lint_branches_sharing_code<'tcx>( let first_line_span = first_line_of_span(cx, expr.span); let replace_span = first_line_span.with_hi(span.hi()); let cond_span = first_line_span.until(first_block.span); - let cond_snippet = reindent_multiline(snippet(cx, cond_span, "_"), false, None); + let cond_snippet = reindent_multiline(&snippet(cx, cond_span, "_"), false, None); let cond_indent = indent_of(cx, cond_span); - let moved_snippet = reindent_multiline(snippet(cx, span, "_"), true, None); + let moved_snippet = reindent_multiline(&snippet(cx, span, "_"), true, None); let suggestion = moved_snippet.to_string() + "\n" + &cond_snippet + "{"; - let suggestion = reindent_multiline(Cow::Borrowed(&suggestion), true, cond_indent); + let suggestion = reindent_multiline(&suggestion, true, cond_indent); (replace_span, suggestion.to_string()) }); let end_suggestion = res.end_span(last_block, sm).map(|span| { - let moved_snipped = reindent_multiline(snippet(cx, span, "_"), true, None); + let moved_snipped = reindent_multiline(&snippet(cx, span, "_"), true, None); let indent = indent_of(cx, expr.span.shrink_to_hi()); let suggestion = "}\n".to_string() + &moved_snipped; - let suggestion = reindent_multiline(Cow::Borrowed(&suggestion), true, indent); + let suggestion = reindent_multiline(&suggestion, true, indent); let span = span.with_hi(last_block.span.hi()); // Improve formatting if the inner block has indention (i.e. normal Rust formatting) diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index 2bec4f2f99e5..99d635aa5cc0 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -135,8 +135,8 @@ impl<'tcx> LateLintPass<'tcx> for HashMapPass { format!( "match {map_str}.entry({key_str}) {{\n{indent_str} {entry}::{then_entry} => {}\n\ {indent_str} {entry}::{else_entry} => {}\n{indent_str}}}", - reindent_multiline(then_str.into(), true, Some(4 + indent_str.len())), - reindent_multiline(else_str.into(), true, Some(4 + indent_str.len())), + reindent_multiline(&then_str, true, Some(4 + indent_str.len())), + reindent_multiline(&else_str, true, Some(4 + indent_str.len())), entry = map_ty.entry_path(), ) } diff --git a/clippy_lints/src/if_not_else.rs b/clippy_lints/src/if_not_else.rs index 2806d4d0e5d6..45f9aa0a53e4 100644 --- a/clippy_lints/src/if_not_else.rs +++ b/clippy_lints/src/if_not_else.rs @@ -7,7 +7,6 @@ use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::Span; -use std::borrow::Cow; declare_clippy_lint! { /// ### What it does @@ -107,7 +106,7 @@ fn make_sugg<'a>( els_span: Span, default: &'a str, indent_relative_to: Option, -) -> Cow<'a, str> { +) -> String { let cond_inner_snip = snippet(sess, cond_inner, default); let els_snip = snippet(sess, els_span, default); let indent = indent_relative_to.and_then(|s| indent_of(sess, s)); @@ -130,5 +129,5 @@ fn make_sugg<'a>( _ => String::new(), }; - reindent_multiline(suggestion.into(), true, indent) + reindent_multiline(&suggestion, true, indent) } diff --git a/clippy_lints/src/matches/manual_unwrap_or.rs b/clippy_lints/src/matches/manual_unwrap_or.rs index 59d375200117..c8c045d86d3d 100644 --- a/clippy_lints/src/matches/manual_unwrap_or.rs +++ b/clippy_lints/src/matches/manual_unwrap_or.rs @@ -113,7 +113,7 @@ fn lint<'tcx>( or_body_snippet: &str, indent: usize, ) { - let reindented_or_body = reindent_multiline(or_body_snippet.into(), true, Some(indent)); + let reindented_or_body = reindent_multiline(or_body_snippet, true, Some(indent)); let mut app = Applicability::MachineApplicable; let suggestion = sugg::Sugg::hir_with_context(cx, scrutinee, expr.span.ctxt(), "..", &mut app).maybe_par(); diff --git a/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs index 76bdbe55e2f3..18568e3661fe 100644 --- a/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs +++ b/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs @@ -57,14 +57,13 @@ pub(super) fn check<'tcx>( }; let suggestion_source = reindent_multiline( - format!( + &format!( "std::path::Path::new({}) .extension() .map_or(false, |ext| ext.eq_ignore_ascii_case(\"{}\"))", recv_source, ext_str.strip_prefix('.').unwrap() - ) - .into(), + ), true, Some(indent_of(cx, call_span).unwrap_or(0) + 4), ); diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs index c1653b65e982..15a14c61d2bc 100644 --- a/clippy_lints/src/methods/filter_map.rs +++ b/clippy_lints/src/methods/filter_map.rs @@ -12,7 +12,6 @@ use rustc_lint::LateContext; use rustc_middle::ty::adjustment::Adjust; use rustc_span::Span; use rustc_span::symbol::{Ident, Symbol, sym}; -use std::borrow::Cow; use super::{MANUAL_FILTER_MAP, MANUAL_FIND_MAP, OPTION_FILTER_MAP, RESULT_FILTER_MAP}; @@ -302,7 +301,7 @@ pub(super) fn check( filter_span.with_hi(expr.span.hi()), "`filter` for `Some` followed by `unwrap`", "consider using `flatten` instead", - reindent_multiline(Cow::Borrowed("flatten()"), true, indent_of(cx, map_span)).into_owned(), + reindent_multiline("flatten()", true, indent_of(cx, map_span)), Applicability::MachineApplicable, ); @@ -316,7 +315,7 @@ pub(super) fn check( filter_span.with_hi(expr.span.hi()), "`filter` for `Ok` followed by `unwrap`", "consider using `flatten` instead", - reindent_multiline(Cow::Borrowed("flatten()"), true, indent_of(cx, map_span)).into_owned(), + reindent_multiline("flatten()", true, indent_of(cx, map_span)), Applicability::MachineApplicable, ); diff --git a/clippy_lints/src/methods/iter_filter.rs b/clippy_lints/src/methods/iter_filter.rs index 30387ba62a73..a6308dd9be0f 100644 --- a/clippy_lints/src/methods/iter_filter.rs +++ b/clippy_lints/src/methods/iter_filter.rs @@ -12,7 +12,6 @@ use rustc_hir as hir; use rustc_hir::QPath; use rustc_span::Span; use rustc_span::symbol::{Ident, Symbol, sym}; -use std::borrow::Cow; /// /// Returns true if the expression is a method call to `method_name` @@ -181,7 +180,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_arg: &hir filter_span.with_hi(expr.span.hi()), "`filter` for `is_ok` on iterator over `Result`s", "consider using `flatten` instead", - reindent_multiline(Cow::Borrowed("flatten()"), true, indent_of(cx, filter_span)).into_owned(), + reindent_multiline("flatten()", true, indent_of(cx, filter_span)), Applicability::HasPlaceholders, ), Some(FilterType::IsSome) => span_lint_and_sugg( @@ -190,7 +189,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_arg: &hir filter_span.with_hi(expr.span.hi()), "`filter` for `is_some` on iterator over `Option`", "consider using `flatten` instead", - reindent_multiline(Cow::Borrowed("flatten()"), true, indent_of(cx, filter_span)).into_owned(), + reindent_multiline("flatten()", true, indent_of(cx, filter_span)), Applicability::HasPlaceholders, ), } diff --git a/clippy_lints/src/methods/manual_ok_or.rs b/clippy_lints/src/methods/manual_ok_or.rs index 4321dd6b0e09..8da9c6b38094 100644 --- a/clippy_lints/src/methods/manual_ok_or.rs +++ b/clippy_lints/src/methods/manual_ok_or.rs @@ -27,7 +27,7 @@ pub(super) fn check<'tcx>( && let Some(err_arg_snippet) = err_arg.span.get_source_text(cx) && let Some(indent) = indent_of(cx, expr.span) { - let reindented_err_arg_snippet = reindent_multiline(err_arg_snippet.as_str().into(), true, Some(indent + 4)); + let reindented_err_arg_snippet = reindent_multiline(err_arg_snippet.as_str(), true, Some(indent + 4)); span_lint_and_sugg( cx, MANUAL_OK_OR, diff --git a/clippy_lints/src/methods/return_and_then.rs b/clippy_lints/src/methods/return_and_then.rs index 7b1199ad1e2d..3c7b54dd8db9 100644 --- a/clippy_lints/src/methods/return_and_then.rs +++ b/clippy_lints/src/methods/return_and_then.rs @@ -60,7 +60,7 @@ pub(super) fn check<'tcx>( "let {} = {}?;\n{}", arg_snip, recv_snip, - reindent_multiline(inner.into(), false, indent_of(cx, expr.span)) + reindent_multiline(inner, false, indent_of(cx, expr.span)) ); span_lint_and_sugg(cx, RETURN_AND_THEN, expr.span, msg, "try", sugg, applicability); diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 05b31fc84b9b..b8601f77e249 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -356,7 +356,7 @@ fn suggestion_snippet_for_continue_inside_else(cx: &EarlyContext<'_>, data: &Lin .iter() .map(|stmt| { let span = cx.sess().source_map().stmt_span(stmt.span, data.loop_block.span); - let snip = snippet_block(cx, span, "..", None).into_owned(); + let snip = snippet_block(cx, span, "..", None); snip.lines() .map(|line| format!("{}{line}", " ".repeat(indent))) .collect::>() diff --git a/clippy_lints/src/redundant_else.rs b/clippy_lints/src/redundant_else.rs index 2995cd8d9f7a..2b5c33c5cbd1 100644 --- a/clippy_lints/src/redundant_else.rs +++ b/clippy_lints/src/redundant_else.rs @@ -7,7 +7,6 @@ use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::declare_lint_pass; use rustc_span::Span; -use std::borrow::Cow; declare_clippy_lint! { /// ### What it does @@ -164,14 +163,9 @@ fn extract_else_block(mut block: &str) -> String { block.trim_end().to_string() } -fn make_sugg<'a>( - cx: &EarlyContext<'_>, - els_span: Span, - default: &'a str, - indent_relative_to: Option, -) -> Cow<'a, str> { +fn make_sugg(cx: &EarlyContext<'_>, els_span: Span, default: &str, indent_relative_to: Option) -> String { let extracted = extract_else_block(&snippet(cx, els_span, default)); let indent = indent_relative_to.and_then(|s| indent_of(cx, s)); - reindent_multiline(extracted.into(), false, indent) + reindent_multiline(&extracted, false, indent) } diff --git a/clippy_lints/src/unit_types/unit_arg.rs b/clippy_lints/src/unit_types/unit_arg.rs index 47d6fe7db766..019ae16ca859 100644 --- a/clippy_lints/src/unit_types/unit_arg.rs +++ b/clippy_lints/src/unit_types/unit_arg.rs @@ -177,7 +177,7 @@ fn fmt_stmts_and_call( stmts_and_call.push(call_snippet_with_replacements); stmts_and_call = stmts_and_call .into_iter() - .map(|v| reindent_multiline(v.into(), true, Some(call_expr_indent)).into_owned()) + .map(|v| reindent_multiline(&v, true, Some(call_expr_indent))) .collect(); let mut stmts_and_call_snippet = stmts_and_call.join(&format!("{}{}", ";\n", " ".repeat(call_expr_indent))); @@ -185,8 +185,7 @@ fn fmt_stmts_and_call( let parent_node = cx.tcx.parent_hir_node(call_expr.hir_id); if !matches!(parent_node, Node::Block(_)) && !matches!(parent_node, Node::Stmt(_)) { let block_indent = call_expr_indent + 4; - stmts_and_call_snippet = - reindent_multiline(stmts_and_call_snippet.into(), true, Some(block_indent)).into_owned(); + stmts_and_call_snippet = reindent_multiline(&stmts_and_call_snippet, true, Some(block_indent)); stmts_and_call_snippet = format!( "{{\n{}{}\n{}}}", " ".repeat(block_indent), diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index eecbfb3936ac..096a2f8b9e0c 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -307,7 +307,7 @@ pub fn expr_block( && let ExprKind::Block(block, _) = expr.kind && block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) { - format!("{code}") + code } else { // FIXME: add extra indent for the unsafe blocks: // original code: unsafe { ... } @@ -420,11 +420,10 @@ pub fn position_before_rarrow(s: &str) -> Option { } /// Reindent a multiline string with possibility of ignoring the first line. -#[expect(clippy::needless_pass_by_value)] -pub fn reindent_multiline(s: Cow<'_, str>, ignore_first: bool, indent: Option) -> Cow<'_, str> { - let s_space = reindent_multiline_inner(&s, ignore_first, indent, ' '); +pub fn reindent_multiline(s: &str, ignore_first: bool, indent: Option) -> String { + let s_space = reindent_multiline_inner(s, ignore_first, indent, ' '); let s_tab = reindent_multiline_inner(&s_space, ignore_first, indent, '\t'); - reindent_multiline_inner(&s_tab, ignore_first, indent, ' ').into() + reindent_multiline_inner(&s_tab, ignore_first, indent, ' ') } fn reindent_multiline_inner(s: &str, ignore_first: bool, indent: Option, ch: char) -> String { @@ -552,42 +551,37 @@ pub fn snippet_opt(sess: &impl HasSession, span: Span) -> Option { /// } // aligned with `if` /// ``` /// Note that the first line of the snippet always has 0 indentation. -pub fn snippet_block<'a>( - sess: &impl HasSession, - span: Span, - default: &'a str, - indent_relative_to: Option, -) -> Cow<'a, str> { +pub fn snippet_block(sess: &impl HasSession, span: Span, default: &str, indent_relative_to: Option) -> String { let snip = snippet(sess, span, default); let indent = indent_relative_to.and_then(|s| indent_of(sess, s)); - reindent_multiline(snip, true, indent) + reindent_multiline(&snip, true, indent) } /// Same as `snippet_block`, but adapts the applicability level by the rules of /// `snippet_with_applicability`. -pub fn snippet_block_with_applicability<'a>( +pub fn snippet_block_with_applicability( sess: &impl HasSession, span: Span, - default: &'a str, + default: &str, indent_relative_to: Option, applicability: &mut Applicability, -) -> Cow<'a, str> { +) -> String { let snip = snippet_with_applicability(sess, span, default, applicability); let indent = indent_relative_to.and_then(|s| indent_of(sess, s)); - reindent_multiline(snip, true, indent) + reindent_multiline(&snip, true, indent) } -pub fn snippet_block_with_context<'a>( +pub fn snippet_block_with_context( sess: &impl HasSession, span: Span, outer: SyntaxContext, - default: &'a str, + default: &str, indent_relative_to: Option, app: &mut Applicability, -) -> (Cow<'a, str>, bool) { +) -> (String, bool) { let (snip, from_macro) = snippet_with_context(sess, span, outer, default, app); let indent = indent_relative_to.and_then(|s| indent_of(sess, s)); - (reindent_multiline(snip, true, indent), from_macro) + (reindent_multiline(&snip, true, indent), from_macro) } /// Same as `snippet_with_applicability`, but first walks the span up to the given context. @@ -745,11 +739,11 @@ mod test { #[test] fn test_reindent_multiline_single_line() { - assert_eq!("", reindent_multiline("".into(), false, None)); - assert_eq!("...", reindent_multiline("...".into(), false, None)); - assert_eq!("...", reindent_multiline(" ...".into(), false, None)); - assert_eq!("...", reindent_multiline("\t...".into(), false, None)); - assert_eq!("...", reindent_multiline("\t\t...".into(), false, None)); + assert_eq!("", reindent_multiline("", false, None)); + assert_eq!("...", reindent_multiline("...", false, None)); + assert_eq!("...", reindent_multiline(" ...", false, None)); + assert_eq!("...", reindent_multiline("\t...", false, None)); + assert_eq!("...", reindent_multiline("\t\t...", false, None)); } #[test] @@ -764,7 +758,7 @@ mod test { y } else { z - }".into(), false, None)); + }", false, None)); assert_eq!("\ if x { \ty @@ -774,7 +768,7 @@ mod test { \ty } else { \tz - }".into(), false, None)); + }", false, None)); } #[test] @@ -791,7 +785,7 @@ mod test { } else { z - }".into(), false, None)); + }", false, None)); } #[test] @@ -807,6 +801,6 @@ mod test { y } else { z - }".into(), true, Some(8))); + }", true, Some(8))); } } From 4220dbd4b34f0c4cf1c9de1628c6d8b5d20bfd99 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Tue, 4 Feb 2025 12:19:04 +0900 Subject: [PATCH 035/991] allow `assign_op_pattern` in the test of `string_add` --- tests/ui/string_add.rs | 2 +- tests/ui/string_add.stderr | 17 +---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/tests/ui/string_add.rs b/tests/ui/string_add.rs index c535f2ebbfcb..61c812f16c8c 100644 --- a/tests/ui/string_add.rs +++ b/tests/ui/string_add.rs @@ -4,7 +4,7 @@ extern crate proc_macros; use proc_macros::external; #[warn(clippy::string_add)] -#[allow(clippy::string_add_assign, unused)] +#[allow(clippy::assign_op_pattern, clippy::string_add_assign, unused)] fn main() { // ignores assignment distinction let mut x = String::new(); diff --git a/tests/ui/string_add.stderr b/tests/ui/string_add.stderr index fe6849b894b5..74ff7372e21a 100644 --- a/tests/ui/string_add.stderr +++ b/tests/ui/string_add.stderr @@ -1,12 +1,3 @@ -error: manual implementation of an assign operation - --> tests/ui/string_add.rs:13:9 - | -LL | x = x + "."; - | ^^^^^^^^^^^ help: replace it with: `x += "."` - | - = note: `-D clippy::assign-op-pattern` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]` - error: you added something to a string. Consider using `String::push_str()` instead --> tests/ui/string_add.rs:13:13 | @@ -22,11 +13,5 @@ error: you added something to a string. Consider using `String::push_str()` inst LL | let z = y + "..."; | ^^^^^^^^^ -error: manual implementation of an assign operation - --> tests/ui/string_add.rs:22:5 - | -LL | x = x + 1; - | ^^^^^^^^^ help: replace it with: `x += 1` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors From 9a858faf691e8627a96b0413106d8b6dd44401eb Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 4 Feb 2025 05:04:47 +0000 Subject: [PATCH 036/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index b62959720764..7f1aa78169d8 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -613bdd49978298648ed05ace086bd1ecad54b44a +affdb59607566c1615c829eea9e7b27a093994ec From 8f1c4a33b7b95e923924b97a5d7bb9fe6c2c913b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Feb 2025 12:05:02 +0100 Subject: [PATCH 037/991] update JSON target spec to declare softfloat ABI --- src/tools/miri/tests/x86_64-unknown-kernel.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/miri/tests/x86_64-unknown-kernel.json b/src/tools/miri/tests/x86_64-unknown-kernel.json index 8135b618d0d3..8da67d3a1c6b 100644 --- a/src/tools/miri/tests/x86_64-unknown-kernel.json +++ b/src/tools/miri/tests/x86_64-unknown-kernel.json @@ -10,6 +10,7 @@ "vendor": "unknown", "linker": "rust-lld", "linker-flavor": "gnu-lld", + "rustc-abi": "x86-softfloat", "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float", "dynamic-linking": false, "executables": true, From a2f9861df8a817f3e3dd07a228b37d0569b67ece Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Tue, 2 Jul 2024 16:09:13 +0800 Subject: [PATCH 038/991] fix [`manual_map`] not catching type adjustment --- clippy_lints/src/matches/manual_utils.rs | 88 ++++++++++++++++++--- tests/ui/manual_map_option_2.fixed | 93 +++++++++++++++++++++- tests/ui/manual_map_option_2.rs | 99 +++++++++++++++++++++++- tests/ui/manual_map_option_2.stderr | 39 +++++++++- 4 files changed, 302 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/matches/manual_utils.rs b/clippy_lints/src/matches/manual_utils.rs index 0b57740064c1..c15e9a50a8e0 100644 --- a/clippy_lints/src/matches/manual_utils.rs +++ b/clippy_lints/src/matches/manual_utils.rs @@ -73,7 +73,7 @@ where } // `map` won't perform any adjustments. - if !cx.typeck_results().expr_adjustments(some_expr.expr).is_empty() { + if expr_has_type_coercion(cx, expr) { return None; } @@ -124,6 +124,12 @@ where }; let closure_expr_snip = some_expr.to_snippet_with_context(cx, expr_ctxt, &mut app); + let closure_body = if some_expr.needs_unsafe_block { + format!("unsafe {}", closure_expr_snip.blockify()) + } else { + closure_expr_snip.to_string() + }; + let body_str = if let PatKind::Binding(annotation, id, some_binding, None) = some_pat.kind { if !some_expr.needs_unsafe_block && let Some(func) = can_pass_as_func(cx, id, some_expr.expr) @@ -145,20 +151,12 @@ where "" }; - if some_expr.needs_unsafe_block { - format!("|{annotation}{some_binding}| unsafe {{ {closure_expr_snip} }}") - } else { - format!("|{annotation}{some_binding}| {closure_expr_snip}") - } + format!("|{annotation}{some_binding}| {closure_body}") } } else if !is_wild_none && explicit_ref.is_none() { // TODO: handle explicit reference annotations. let pat_snip = snippet_with_context(cx, some_pat.span, expr_ctxt, "..", &mut app).0; - if some_expr.needs_unsafe_block { - format!("|{pat_snip}| unsafe {{ {closure_expr_snip} }}") - } else { - format!("|{pat_snip}| {closure_expr_snip}") - } + format!("|{pat_snip}| {closure_body}") } else { // Refutable bindings and mixed reference annotations can't be handled by `map`. return None; @@ -274,3 +272,71 @@ pub(super) fn try_parse_pattern<'tcx>( fn is_none_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { is_res_lang_ctor(cx, path_res(cx, peel_blocks(expr)), OptionNone) } + +fn expr_ty_adjusted(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + cx.typeck_results() + .expr_adjustments(expr) + .iter() + // We do not care about exprs with `NeverToAny` adjustments, such as `panic!` call. + .any(|adj| !matches!(adj.kind, Adjust::NeverToAny)) +} + +fn expr_has_type_coercion<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool { + if expr.span.from_expansion() { + return false; + } + if expr_ty_adjusted(cx, expr) { + return true; + } + + // Identify coercion sites and recursively check it those sites + // actually has type adjustments. + match expr.kind { + // Function/method calls, including enum initialization. + ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) if let Some(def_id) = fn_def_id(cx, expr) => { + let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + if !fn_sig.output().skip_binder().has_type_flags(TypeFlags::HAS_TY_PARAM) { + return false; + } + let mut args_with_ty_param = fn_sig + .inputs() + .skip_binder() + .iter() + .zip(args) + .filter_map(|(arg_ty, arg)| if arg_ty.has_type_flags(TypeFlags::HAS_TY_PARAM) { + Some(arg) + } else { + None + }); + args_with_ty_param.any(|arg| expr_has_type_coercion(cx, arg)) + }, + // Struct/union initialization. + ExprKind::Struct(_, fields, _) => { + fields.iter().map(|expr_field| expr_field.expr).any(|ex| expr_has_type_coercion(cx, ex)) + }, + // those two `ref` keywords cannot be removed + #[allow(clippy::needless_borrow)] + // Function results, including the final line of a block or a `return` expression. + ExprKind::Block(hir::Block { expr: Some(ref ret_expr), .. }, _) | + ExprKind::Ret(Some(ref ret_expr)) => expr_has_type_coercion(cx, ret_expr), + + // ===== Coercion-propagation expressions ===== + + // Array, where the type is `[U; n]`. + ExprKind::Array(elems) | + // Tuple, `(U_0, U_1, ..., U_n)`. + ExprKind::Tup(elems) => { + elems.iter().any(|elem| expr_has_type_coercion(cx, elem)) + }, + // Array but with repeating syntax. + ExprKind::Repeat(rep_elem, _) => expr_has_type_coercion(cx, rep_elem), + // Others that may contain coercion sites. + ExprKind::If(_, then, maybe_else) => { + expr_has_type_coercion(cx, then) || maybe_else.is_some_and(|e| expr_has_type_coercion(cx, e)) + } + ExprKind::Match(_, arms, _) => { + arms.iter().map(|arm| arm.body).any(|body| expr_has_type_coercion(cx, body)) + } + _ => false + } +} diff --git a/tests/ui/manual_map_option_2.fixed b/tests/ui/manual_map_option_2.fixed index f5bb4e0af1ba..49b9e77b441f 100644 --- a/tests/ui/manual_map_option_2.fixed +++ b/tests/ui/manual_map_option_2.fixed @@ -40,9 +40,14 @@ fn main() { None => None, }; - // Lint. `s` is captured by reference, so no lifetime issues. let s = Some(String::new()); + // Lint. `s` is captured by reference, so no lifetime issues. let _ = s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }); + // Don't lint this, type of `s` is coercioned from `&String` to `&str` + let x: Option<(String, &str)> = match &s { + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), + None => None, + }; // Issue #7820 unsafe fn f(x: u32) -> u32 { @@ -54,3 +59,89 @@ fn main() { let _ = Some(0).map(|x| unsafe { f(x) }); let _ = Some(0).map(|x| unsafe { f(x) }); } + +// issue #12659 +mod with_type_coercion { + trait DummyTrait {} + + fn foo Result>(f: F) { + // Don't lint + let _: Option, ()>> = match Some(0) { + Some(_) => Some(match f() { + Ok(res) => Ok(Box::new(res)), + _ => Err(()), + }), + None => None, + }; + + let _: Option> = match Some(()) { + Some(_) => Some(Box::new(b"1234")), + None => None, + }; + + let x = String::new(); + let _: Option> = match Some(()) { + Some(_) => Some(Box::new(&x)), + None => None, + }; + + let _: Option<&str> = match Some(()) { + Some(_) => Some(&x), + None => None, + }; + + //~v ERROR: manual implementation of `Option::map` + let _ = Some(0).map(|_| match f() { + Ok(res) => Ok(Box::new(res)), + _ => Err(()), + }); + } + + #[allow(clippy::redundant_allocation)] + fn bar() { + fn f(_: Option>) {} + fn g(b: &[u8]) -> Box<&[u8]> { + Box::new(b) + } + + let x: &[u8; 4] = b"1234"; + f(match Some(()) { + Some(_) => Some(Box::new(x)), + None => None, + }); + + //~v ERROR: manual implementation of `Option::map` + let _: Option> = Some(0).map(|_| g(x)); + } + + fn with_fn_ret(s: &Option) -> Option<(String, &str)> { + // Don't lint, `map` doesn't work as the return type is adjusted. + match s { + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), + None => None, + } + } + + fn with_fn_ret_2(s: &Option) -> Option<(String, &str)> { + if true { + // Don't lint, `map` doesn't work as the return type is adjusted. + return match s { + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), + None => None, + }; + } + None + } + + #[allow(clippy::needless_late_init)] + fn with_fn_ret_3<'a>(s: &'a Option) -> Option<(String, &'a str)> { + let x: Option<(String, &'a str)>; + x = { + match s { + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), + None => None, + } + }; + x + } +} diff --git a/tests/ui/manual_map_option_2.rs b/tests/ui/manual_map_option_2.rs index cbc2356e0a2d..962455daf7ba 100644 --- a/tests/ui/manual_map_option_2.rs +++ b/tests/ui/manual_map_option_2.rs @@ -43,12 +43,17 @@ fn main() { None => None, }; - // Lint. `s` is captured by reference, so no lifetime issues. let s = Some(String::new()); + // Lint. `s` is captured by reference, so no lifetime issues. let _ = match &s { Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), None => None, }; + // Don't lint this, type of `s` is coercioned from `&String` to `&str` + let x: Option<(String, &str)> = match &s { + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), + None => None, + }; // Issue #7820 unsafe fn f(x: u32) -> u32 { @@ -69,3 +74,95 @@ fn main() { None => None, }; } + +// issue #12659 +mod with_type_coercion { + trait DummyTrait {} + + fn foo Result>(f: F) { + // Don't lint + let _: Option, ()>> = match Some(0) { + Some(_) => Some(match f() { + Ok(res) => Ok(Box::new(res)), + _ => Err(()), + }), + None => None, + }; + + let _: Option> = match Some(()) { + Some(_) => Some(Box::new(b"1234")), + None => None, + }; + + let x = String::new(); + let _: Option> = match Some(()) { + Some(_) => Some(Box::new(&x)), + None => None, + }; + + let _: Option<&str> = match Some(()) { + Some(_) => Some(&x), + None => None, + }; + + //~v ERROR: manual implementation of `Option::map` + let _ = match Some(0) { + Some(_) => Some(match f() { + Ok(res) => Ok(Box::new(res)), + _ => Err(()), + }), + None => None, + }; + } + + #[allow(clippy::redundant_allocation)] + fn bar() { + fn f(_: Option>) {} + fn g(b: &[u8]) -> Box<&[u8]> { + Box::new(b) + } + + let x: &[u8; 4] = b"1234"; + f(match Some(()) { + Some(_) => Some(Box::new(x)), + None => None, + }); + + //~v ERROR: manual implementation of `Option::map` + let _: Option> = match Some(0) { + Some(_) => Some(g(x)), + None => None, + }; + } + + fn with_fn_ret(s: &Option) -> Option<(String, &str)> { + // Don't lint, `map` doesn't work as the return type is adjusted. + match s { + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), + None => None, + } + } + + fn with_fn_ret_2(s: &Option) -> Option<(String, &str)> { + if true { + // Don't lint, `map` doesn't work as the return type is adjusted. + return match s { + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), + None => None, + }; + } + None + } + + #[allow(clippy::needless_late_init)] + fn with_fn_ret_3<'a>(s: &'a Option) -> Option<(String, &'a str)> { + let x: Option<(String, &'a str)>; + x = { + match s { + Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), + None => None, + } + }; + x + } +} diff --git a/tests/ui/manual_map_option_2.stderr b/tests/ui/manual_map_option_2.stderr index 78e4677544bc..db048221db6a 100644 --- a/tests/ui/manual_map_option_2.stderr +++ b/tests/ui/manual_map_option_2.stderr @@ -32,7 +32,7 @@ LL | | }; | |_____^ help: try: `s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } })` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option_2.rs:58:17 + --> tests/ui/manual_map_option_2.rs:63:17 | LL | let _ = match Some(0) { | _________________^ @@ -42,7 +42,7 @@ LL | | }; | |_________^ help: try: `Some(0).map(|x| f(x))` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option_2.rs:63:13 + --> tests/ui/manual_map_option_2.rs:68:13 | LL | let _ = match Some(0) { | _____________^ @@ -52,7 +52,7 @@ LL | | }; | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option_2.rs:67:13 + --> tests/ui/manual_map_option_2.rs:72:13 | LL | let _ = match Some(0) { | _____________^ @@ -61,5 +61,36 @@ LL | | None => None, LL | | }; | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })` -error: aborting due to 5 previous errors +error: manual implementation of `Option::map` + --> tests/ui/manual_map_option_2.rs:109:17 + | +LL | let _ = match Some(0) { + | _________________^ +LL | | Some(_) => Some(match f() { +LL | | Ok(res) => Ok(Box::new(res)), +LL | | _ => Err(()), +LL | | }), +LL | | None => None, +LL | | }; + | |_________^ + | +help: try + | +LL ~ let _ = Some(0).map(|_| match f() { +LL + Ok(res) => Ok(Box::new(res)), +LL + _ => Err(()), +LL ~ }); + | + +error: manual implementation of `Option::map` + --> tests/ui/manual_map_option_2.rs:132:37 + | +LL | let _: Option> = match Some(0) { + | _____________________________________^ +LL | | Some(_) => Some(g(x)), +LL | | None => None, +LL | | }; + | |_________^ help: try: `Some(0).map(|_| g(x))` + +error: aborting due to 7 previous errors From 2a4be5365abeb75ead816c8a2493af3f4d60aba4 Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Sat, 14 Sep 2024 00:11:11 +0800 Subject: [PATCH 039/991] move `expr_requires_coercion` to clippy_utils & some other adjustments --- clippy_lints/src/matches/manual_utils.rs | 74 +------------------- clippy_utils/src/lib.rs | 89 +++++++++++++++++++++++- tests/ui/manual_map_option.fixed | 11 ++- tests/ui/manual_map_option.rs | 6 ++ tests/ui/manual_map_option.stderr | 17 ++--- 5 files changed, 111 insertions(+), 86 deletions(-) diff --git a/clippy_lints/src/matches/manual_utils.rs b/clippy_lints/src/matches/manual_utils.rs index c15e9a50a8e0..c5690e9588ca 100644 --- a/clippy_lints/src/matches/manual_utils.rs +++ b/clippy_lints/src/matches/manual_utils.rs @@ -4,8 +4,8 @@ use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_copy, is_type_diagnostic_item, peel_mid_ty_refs_is_mutable, type_is_unsafe_function}; use clippy_utils::{ - CaptureKind, can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res, - path_to_local_id, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, + CaptureKind, can_move_expr_to_closure, expr_requires_coercion, is_else_clause, is_lint_allowed, is_res_lang_ctor, + path_res, path_to_local_id, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, }; use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::Applicability; @@ -73,7 +73,7 @@ where } // `map` won't perform any adjustments. - if expr_has_type_coercion(cx, expr) { + if expr_requires_coercion(cx, expr) { return None; } @@ -272,71 +272,3 @@ pub(super) fn try_parse_pattern<'tcx>( fn is_none_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { is_res_lang_ctor(cx, path_res(cx, peel_blocks(expr)), OptionNone) } - -fn expr_ty_adjusted(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - cx.typeck_results() - .expr_adjustments(expr) - .iter() - // We do not care about exprs with `NeverToAny` adjustments, such as `panic!` call. - .any(|adj| !matches!(adj.kind, Adjust::NeverToAny)) -} - -fn expr_has_type_coercion<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool { - if expr.span.from_expansion() { - return false; - } - if expr_ty_adjusted(cx, expr) { - return true; - } - - // Identify coercion sites and recursively check it those sites - // actually has type adjustments. - match expr.kind { - // Function/method calls, including enum initialization. - ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) if let Some(def_id) = fn_def_id(cx, expr) => { - let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); - if !fn_sig.output().skip_binder().has_type_flags(TypeFlags::HAS_TY_PARAM) { - return false; - } - let mut args_with_ty_param = fn_sig - .inputs() - .skip_binder() - .iter() - .zip(args) - .filter_map(|(arg_ty, arg)| if arg_ty.has_type_flags(TypeFlags::HAS_TY_PARAM) { - Some(arg) - } else { - None - }); - args_with_ty_param.any(|arg| expr_has_type_coercion(cx, arg)) - }, - // Struct/union initialization. - ExprKind::Struct(_, fields, _) => { - fields.iter().map(|expr_field| expr_field.expr).any(|ex| expr_has_type_coercion(cx, ex)) - }, - // those two `ref` keywords cannot be removed - #[allow(clippy::needless_borrow)] - // Function results, including the final line of a block or a `return` expression. - ExprKind::Block(hir::Block { expr: Some(ref ret_expr), .. }, _) | - ExprKind::Ret(Some(ref ret_expr)) => expr_has_type_coercion(cx, ret_expr), - - // ===== Coercion-propagation expressions ===== - - // Array, where the type is `[U; n]`. - ExprKind::Array(elems) | - // Tuple, `(U_0, U_1, ..., U_n)`. - ExprKind::Tup(elems) => { - elems.iter().any(|elem| expr_has_type_coercion(cx, elem)) - }, - // Array but with repeating syntax. - ExprKind::Repeat(rep_elem, _) => expr_has_type_coercion(cx, rep_elem), - // Others that may contain coercion sites. - ExprKind::If(_, then, maybe_else) => { - expr_has_type_coercion(cx, then) || maybe_else.is_some_and(|e| expr_has_type_coercion(cx, e)) - } - ExprKind::Match(_, arms, _) => { - arms.iter().map(|arm| arm.body).any(|body| expr_has_type_coercion(cx, body)) - } - _ => false - } -} diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 2f5639b686b8..3ed9313d82bc 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -117,7 +117,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgKind, GenericArgsRef, IntTy, Ty, - TyCtxt, TypeVisitableExt, UintTy, UpvarCapture, + TyCtxt, TypeFlags, TypeVisitableExt, UintTy, UpvarCapture, }; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; @@ -3489,3 +3489,90 @@ pub fn leaks_droppable_temporary_with_limited_lifetime<'tcx>(cx: &LateContext<'t }) .is_break() } + +/// Returns true if the specified `expr` requires coercion, +/// meaning that it either has a coercion or propagates a coercion from one of its sub expressions. +/// +/// Similar to [`is_adjusted`], this not only checks if an expression's type was adjusted, +/// but also going through extra steps to see if it fits the description of [coercion sites]. +/// +/// You should used this when you want to avoid suggesting replacing an expression that is currently +/// a coercion site or coercion propagating expression with one that is not. +/// +/// [coercion sites]: https://doc.rust-lang.org/stable/reference/type-coercions.html#coercion-sites +pub fn expr_requires_coercion<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool { + let expr_ty_is_adjusted = cx + .typeck_results() + .expr_adjustments(expr) + .iter() + // ignore `NeverToAny` adjustments, such as `panic!` call. + .any(|adj| !matches!(adj.kind, Adjust::NeverToAny)); + if expr_ty_is_adjusted { + return true; + } + + // Identify coercion sites and recursively check if those sites + // actually have type adjustments. + match expr.kind { + ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) if let Some(def_id) = fn_def_id(cx, expr) => { + let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + + if !fn_sig.output().skip_binder().has_type_flags(TypeFlags::HAS_TY_PARAM) { + return false; + } + + let self_arg_count = usize::from(matches!(expr.kind, ExprKind::MethodCall(..))); + let mut args_with_ty_param = { + fn_sig + .inputs() + .skip_binder() + .iter() + .skip(self_arg_count) + .zip(args) + .filter_map(|(arg_ty, arg)| { + if arg_ty.has_type_flags(TypeFlags::HAS_TY_PARAM) { + Some(arg) + } else { + None + } + }) + }; + args_with_ty_param.any(|arg| expr_requires_coercion(cx, arg)) + }, + // Struct/union initialization. + ExprKind::Struct(qpath, _, _) => { + let res = cx.typeck_results().qpath_res(qpath, expr.hir_id); + if let Some((_, v_def)) = adt_and_variant_of_res(cx, res) { + let generic_args = cx.typeck_results().node_args(expr.hir_id); + v_def + .fields + .iter() + .any(|field| field.ty(cx.tcx, generic_args).has_type_flags(TypeFlags::HAS_TY_PARAM)) + } else { + false + } + }, + // Function results, including the final line of a block or a `return` expression. + ExprKind::Block( + &Block { + expr: Some(ret_expr), .. + }, + _, + ) + | ExprKind::Ret(Some(ret_expr)) => expr_requires_coercion(cx, ret_expr), + + // ===== Coercion-propagation expressions ===== + ExprKind::Array(elems) | ExprKind::Tup(elems) => elems.iter().any(|elem| expr_requires_coercion(cx, elem)), + // Array but with repeating syntax. + ExprKind::Repeat(rep_elem, _) => expr_requires_coercion(cx, rep_elem), + // Others that may contain coercion sites. + ExprKind::If(_, then, maybe_else) => { + expr_requires_coercion(cx, then) || maybe_else.is_some_and(|e| expr_requires_coercion(cx, e)) + }, + ExprKind::Match(_, arms, _) => arms + .iter() + .map(|arm| arm.body) + .any(|body| expr_requires_coercion(cx, body)), + _ => false, + } +} diff --git a/tests/ui/manual_map_option.fixed b/tests/ui/manual_map_option.fixed index 16cee3fd3823..3586979ab358 100644 --- a/tests/ui/manual_map_option.fixed +++ b/tests/ui/manual_map_option.fixed @@ -113,7 +113,16 @@ fn main() { } // #6811 - Some(0).map(|x| vec![x]); + match Some(0) { + Some(x) => Some(vec![x]), + None => None, + }; + + // Don't lint, coercion + let x: Option> = match Some(()) { + Some(_) => Some(vec![b"1234"]), + None => None, + }; option_env!("").map(String::from); diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs index 4655acf1406c..2f21628977cf 100644 --- a/tests/ui/manual_map_option.rs +++ b/tests/ui/manual_map_option.rs @@ -170,6 +170,12 @@ fn main() { None => None, }; + // Don't lint, coercion + let x: Option> = match Some(()) { + Some(_) => Some(vec![b"1234"]), + None => None, + }; + match option_env!("") { Some(x) => Some(String::from(x)), None => None, diff --git a/tests/ui/manual_map_option.stderr b/tests/ui/manual_map_option.stderr index 47cc18303ba5..c496752e2f6d 100644 --- a/tests/ui/manual_map_option.stderr +++ b/tests/ui/manual_map_option.stderr @@ -156,16 +156,7 @@ LL | | }; | |_____^ help: try: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:168:5 - | -LL | / match Some(0) { -LL | | Some(x) => Some(vec![x]), -LL | | None => None, -LL | | }; - | |_____^ help: try: `Some(0).map(|x| vec![x])` - -error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:173:5 + --> tests/ui/manual_map_option.rs:179:5 | LL | / match option_env!("") { LL | | Some(x) => Some(String::from(x)), @@ -174,7 +165,7 @@ LL | | }; | |_____^ help: try: `option_env!("").map(String::from)` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:193:12 + --> tests/ui/manual_map_option.rs:199:12 | LL | } else if let Some(x) = Some(0) { | ____________^ @@ -185,7 +176,7 @@ LL | | }; | |_____^ help: try: `{ Some(0).map(|x| x + 1) }` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:201:12 + --> tests/ui/manual_map_option.rs:207:12 | LL | } else if let Some(x) = Some(0) { | ____________^ @@ -195,5 +186,5 @@ LL | | None LL | | }; | |_____^ help: try: `{ Some(0).map(|x| x + 1) }` -error: aborting due to 21 previous errors +error: aborting due to 20 previous errors From 60f94459002db4d8674008877fabd98782617104 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Tue, 4 Feb 2025 12:10:49 +0900 Subject: [PATCH 040/991] don't emit lint inside macro in `manual_async_fn` --- clippy_lints/src/manual_async_fn.rs | 1 + tests/ui/manual_async_fn.fixed | 26 ++++++++++++++++++++++++++ tests/ui/manual_async_fn.rs | 26 ++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs index 9f3b0957eab1..ba63f980316e 100644 --- a/clippy_lints/src/manual_async_fn.rs +++ b/clippy_lints/src/manual_async_fn.rs @@ -62,6 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { && let Some(closure_body) = desugared_async_block(cx, block) && let Node::Item(Item {vis_span, ..}) | Node::ImplItem(ImplItem {vis_span, ..}) = cx.tcx.hir_node_by_def_id(fn_def_id) + && !span.from_expansion() { let header_span = span.with_hi(ret_ty.span.hi()); diff --git a/tests/ui/manual_async_fn.fixed b/tests/ui/manual_async_fn.fixed index dc1cb8e11fca..ad0266d39e98 100644 --- a/tests/ui/manual_async_fn.fixed +++ b/tests/ui/manual_async_fn.fixed @@ -113,4 +113,30 @@ pub(crate) async fn issue_10450_2() -> i32 { 42 } pub(self) async fn issue_10450_3() -> i32 { 42 } +macro_rules! issue_12407 { + ( + $( + $(#[$m:meta])* + $v:vis $(override($($overrides:tt),* $(,)?))? fn $name:ident $([$($params:tt)*])? ( + $($arg_name:ident: $arg_typ:ty),* $(,)? + ) $(-> $ret_ty:ty)? = $e:expr; + )* + ) => { + $( + $(#[$m])* + $v $($($overrides)*)? fn $name$(<$($params)*>)?( + $($arg_name: $arg_typ),* + ) $(-> $ret_ty)? { + $e + } + )* + }; +} + +issue_12407! { + fn _hello() -> impl Future = async {}; + fn non_async() = println!("hello"); + fn foo() = non_async(); +} + fn main() {} diff --git a/tests/ui/manual_async_fn.rs b/tests/ui/manual_async_fn.rs index 9ca7654a3688..87973222c0bb 100644 --- a/tests/ui/manual_async_fn.rs +++ b/tests/ui/manual_async_fn.rs @@ -139,4 +139,30 @@ pub(self) fn issue_10450_3() -> impl Future { async { 42 } } +macro_rules! issue_12407 { + ( + $( + $(#[$m:meta])* + $v:vis $(override($($overrides:tt),* $(,)?))? fn $name:ident $([$($params:tt)*])? ( + $($arg_name:ident: $arg_typ:ty),* $(,)? + ) $(-> $ret_ty:ty)? = $e:expr; + )* + ) => { + $( + $(#[$m])* + $v $($($overrides)*)? fn $name$(<$($params)*>)?( + $($arg_name: $arg_typ),* + ) $(-> $ret_ty)? { + $e + } + )* + }; +} + +issue_12407! { + fn _hello() -> impl Future = async {}; + fn non_async() = println!("hello"); + fn foo() = non_async(); +} + fn main() {} From 9673d8d543c5fa8f14b168beed8280b98baf64cf Mon Sep 17 00:00:00 2001 From: Petr Sumbera Date: Tue, 4 Feb 2025 11:51:08 +0000 Subject: [PATCH 041/991] Fix build on Solaris where is no flock(). --- src/tools/miri/src/shims/unix/fs.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index c7399b00d3fe..924dbb887999 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -178,7 +178,7 @@ impl UnixFileDescription for FileHandle { op: FlockOp, ) -> InterpResult<'tcx, io::Result<()>> { assert!(communicate_allowed, "isolation should have prevented even opening a file"); - #[cfg(target_family = "unix")] + #[cfg(all(target_family = "unix", not(target_os = "solaris")))] { use std::os::fd::AsRawFd; @@ -260,10 +260,15 @@ impl UnixFileDescription for FileHandle { interp_ok(res) } - #[cfg(not(any(target_family = "unix", target_family = "windows")))] + #[cfg(not(any( + all(target_family = "unix", not(target_os = "solaris")), + target_family = "windows" + )))] { let _ = op; - compile_error!("flock is supported only on UNIX and Windows hosts"); + throw_unsup_format!( + "flock is supported only on UNIX (except Solaris) and Windows hosts" + ); } } } From a058e1a5df545f3ea0b8cf4c46e06760816b571a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 5 Feb 2025 09:02:16 +0100 Subject: [PATCH 042/991] use cfg_match --- src/tools/miri/src/lib.rs | 1 + src/tools/miri/src/shims/unix/fs.rs | 164 ++++++++++++++-------------- 2 files changed, 80 insertions(+), 85 deletions(-) diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 45054c37c40e..feab5a9a2f7f 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -1,4 +1,5 @@ #![feature(rustc_private)] +#![feature(cfg_match)] #![feature(cell_update)] #![feature(float_gamma)] #![feature(map_try_insert)] diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 924dbb887999..f8e0c638c90d 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -178,97 +178,91 @@ impl UnixFileDescription for FileHandle { op: FlockOp, ) -> InterpResult<'tcx, io::Result<()>> { assert!(communicate_allowed, "isolation should have prevented even opening a file"); - #[cfg(all(target_family = "unix", not(target_os = "solaris")))] - { - use std::os::fd::AsRawFd; + cfg_match! { + all(target_family = "unix", not(target_os = "solaris")) => { + use std::os::fd::AsRawFd; - use FlockOp::*; - // We always use non-blocking call to prevent interpreter from being blocked - let (host_op, lock_nb) = match op { - SharedLock { nonblocking } => (libc::LOCK_SH | libc::LOCK_NB, nonblocking), - ExclusiveLock { nonblocking } => (libc::LOCK_EX | libc::LOCK_NB, nonblocking), - Unlock => (libc::LOCK_UN, false), - }; + use FlockOp::*; + // We always use non-blocking call to prevent interpreter from being blocked + let (host_op, lock_nb) = match op { + SharedLock { nonblocking } => (libc::LOCK_SH | libc::LOCK_NB, nonblocking), + ExclusiveLock { nonblocking } => (libc::LOCK_EX | libc::LOCK_NB, nonblocking), + Unlock => (libc::LOCK_UN, false), + }; - let fd = self.file.as_raw_fd(); - let ret = unsafe { libc::flock(fd, host_op) }; - let res = match ret { - 0 => Ok(()), - -1 => { - let err = io::Error::last_os_error(); - if !lock_nb && err.kind() == io::ErrorKind::WouldBlock { - throw_unsup_format!("blocking `flock` is not currently supported"); - } - Err(err) - } - ret => panic!("Unexpected return value from flock: {ret}"), - }; - interp_ok(res) - } - - #[cfg(target_family = "windows")] - { - use std::os::windows::io::AsRawHandle; - - use windows_sys::Win32::Foundation::{ - ERROR_IO_PENDING, ERROR_LOCK_VIOLATION, FALSE, HANDLE, TRUE, - }; - use windows_sys::Win32::Storage::FileSystem::{ - LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, LockFileEx, UnlockFile, - }; - - let fh = self.file.as_raw_handle() as HANDLE; - - use FlockOp::*; - let (ret, lock_nb) = match op { - SharedLock { nonblocking } | ExclusiveLock { nonblocking } => { - // We always use non-blocking call to prevent interpreter from being blocked - let mut flags = LOCKFILE_FAIL_IMMEDIATELY; - if matches!(op, ExclusiveLock { .. }) { - flags |= LOCKFILE_EXCLUSIVE_LOCK; - } - let ret = unsafe { LockFileEx(fh, flags, 0, !0, !0, &mut std::mem::zeroed()) }; - (ret, nonblocking) - } - Unlock => { - let ret = unsafe { UnlockFile(fh, 0, 0, !0, !0) }; - (ret, false) - } - }; - - let res = match ret { - TRUE => Ok(()), - FALSE => { - let mut err = io::Error::last_os_error(); - // This only runs on Windows hosts so we can use `raw_os_error`. - // We have to be careful not to forward that error code to target code. - let code: u32 = err.raw_os_error().unwrap().try_into().unwrap(); - if matches!(code, ERROR_IO_PENDING | ERROR_LOCK_VIOLATION) { - if lock_nb { - // The io error mapping does not know about these error codes, - // so we translate it to `WouldBlock` manually. - let desc = format!("LockFileEx wouldblock error: {err}"); - err = io::Error::new(io::ErrorKind::WouldBlock, desc); - } else { + let fd = self.file.as_raw_fd(); + let ret = unsafe { libc::flock(fd, host_op) }; + let res = match ret { + 0 => Ok(()), + -1 => { + let err = io::Error::last_os_error(); + if !lock_nb && err.kind() == io::ErrorKind::WouldBlock { throw_unsup_format!("blocking `flock` is not currently supported"); } + Err(err) } - Err(err) - } - _ => panic!("Unexpected return value: {ret}"), - }; - interp_ok(res) - } + ret => panic!("Unexpected return value from flock: {ret}"), + }; + interp_ok(res) + } + target_family = "windows" => { + use std::os::windows::io::AsRawHandle; - #[cfg(not(any( - all(target_family = "unix", not(target_os = "solaris")), - target_family = "windows" - )))] - { - let _ = op; - throw_unsup_format!( - "flock is supported only on UNIX (except Solaris) and Windows hosts" - ); + use windows_sys::Win32::Foundation::{ + ERROR_IO_PENDING, ERROR_LOCK_VIOLATION, FALSE, HANDLE, TRUE, + }; + use windows_sys::Win32::Storage::FileSystem::{ + LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, LockFileEx, UnlockFile, + }; + + let fh = self.file.as_raw_handle() as HANDLE; + + use FlockOp::*; + let (ret, lock_nb) = match op { + SharedLock { nonblocking } | ExclusiveLock { nonblocking } => { + // We always use non-blocking call to prevent interpreter from being blocked + let mut flags = LOCKFILE_FAIL_IMMEDIATELY; + if matches!(op, ExclusiveLock { .. }) { + flags |= LOCKFILE_EXCLUSIVE_LOCK; + } + let ret = unsafe { LockFileEx(fh, flags, 0, !0, !0, &mut std::mem::zeroed()) }; + (ret, nonblocking) + } + Unlock => { + let ret = unsafe { UnlockFile(fh, 0, 0, !0, !0) }; + (ret, false) + } + }; + + let res = match ret { + TRUE => Ok(()), + FALSE => { + let mut err = io::Error::last_os_error(); + // This only runs on Windows hosts so we can use `raw_os_error`. + // We have to be careful not to forward that error code to target code. + let code: u32 = err.raw_os_error().unwrap().try_into().unwrap(); + if matches!(code, ERROR_IO_PENDING | ERROR_LOCK_VIOLATION) { + if lock_nb { + // The io error mapping does not know about these error codes, + // so we translate it to `WouldBlock` manually. + let desc = format!("LockFileEx wouldblock error: {err}"); + err = io::Error::new(io::ErrorKind::WouldBlock, desc); + } else { + throw_unsup_format!("blocking `flock` is not currently supported"); + } + } + Err(err) + } + _ => panic!("Unexpected return value: {ret}"), + }; + interp_ok(res) + } + _ => { + let _ = op; + throw_unsup_format!( + "flock is supported only on UNIX (except Solaris) and Windows hosts" + ); + } } } } From 6b969d799cc783fdcb63b08e88abb5d0d5f8c4a3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 5 Feb 2025 09:36:22 +0100 Subject: [PATCH 043/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 7f1aa78169d8..e695fc4004b5 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -affdb59607566c1615c829eea9e7b27a093994ec +8df89d1cb077cd76013d3f9f5a4e92c5b5a9280c From e58e3d5182959e3d78d0494c4186dde46249c477 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 5 Feb 2025 09:44:43 +0100 Subject: [PATCH 044/991] bump default max parallelism up to 20 --- src/tools/miri/src/bin/miri.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 685f5670ab4e..71a225faf9de 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -721,8 +721,8 @@ fn main() { // Ensure we have parallelism for many-seeds mode. if many_seeds.is_some() && !rustc_args.iter().any(|arg| arg.starts_with("-Zthreads=")) { - // Clamp to 10 threads; things get a lot less efficient beyond that due to lock contention. - let threads = std::thread::available_parallelism().map_or(1, |n| n.get()).min(10); + // Clamp to 20 threads; things get a less efficient beyond that due to lock contention. + let threads = std::thread::available_parallelism().map_or(1, |n| n.get()).min(20); rustc_args.push(format!("-Zthreads={threads}")); } let many_seeds = From 44fda914d3c9f448765283a80d1e19793c4e7e1b Mon Sep 17 00:00:00 2001 From: Yutaro Ohno Date: Wed, 5 Feb 2025 19:16:50 +0900 Subject: [PATCH 045/991] Correct version of `doc_overindented_list_items` --- clippy_lints/src/doc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 15530c3dbc50..fce46537793d 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -455,7 +455,7 @@ declare_clippy_lint! { /// /// and this line is overindented. /// # fn foo() {} /// ``` - #[clippy::version = "1.80.0"] + #[clippy::version = "1.86.0"] pub DOC_OVERINDENTED_LIST_ITEMS, style, "ensure list items are not overindented" From f3e292da0bd1ca81f8ea8efb2f7ead5d23a4bbb0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Sat, 1 Feb 2025 10:06:35 +0000 Subject: [PATCH 046/991] Uniformly handle HIR literals in visitors and lints --- clippy_lints/src/approx_const.rs | 38 ++++++++++++++------------------ 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs index 95c85f250e98..95f64b74044b 100644 --- a/clippy_lints/src/approx_const.rs +++ b/clippy_lints/src/approx_const.rs @@ -3,10 +3,10 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::msrvs::{self, Msrv}; use rustc_ast::ast::{FloatTy, LitFloatType, LitKind}; use rustc_attr_parsing::RustcVersion; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::{HirId, Lit}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::symbol; +use rustc_span::{Span, symbol}; use std::f64::consts as f64; declare_clippy_lint! { @@ -73,22 +73,28 @@ impl ApproxConstant { msrv: conf.msrv.clone(), } } +} - fn check_lit(&self, cx: &LateContext<'_>, lit: &LitKind, e: &Expr<'_>) { - match *lit { +impl<'tcx> LateLintPass<'tcx> for ApproxConstant { + fn check_lit(&mut self, cx: &LateContext<'_>, _hir_id: HirId, lit: &Lit, _negated: bool) { + match lit.node { LitKind::Float(s, LitFloatType::Suffixed(fty)) => match fty { - FloatTy::F16 => self.check_known_consts(cx, e, s, "f16"), - FloatTy::F32 => self.check_known_consts(cx, e, s, "f32"), - FloatTy::F64 => self.check_known_consts(cx, e, s, "f64"), - FloatTy::F128 => self.check_known_consts(cx, e, s, "f128"), + FloatTy::F16 => self.check_known_consts(cx, lit.span, s, "f16"), + FloatTy::F32 => self.check_known_consts(cx, lit.span, s, "f32"), + FloatTy::F64 => self.check_known_consts(cx, lit.span, s, "f64"), + FloatTy::F128 => self.check_known_consts(cx, lit.span, s, "f128"), }, // FIXME(f16_f128): add `f16` and `f128` when these types become stable. - LitKind::Float(s, LitFloatType::Unsuffixed) => self.check_known_consts(cx, e, s, "f{32, 64}"), + LitKind::Float(s, LitFloatType::Unsuffixed) => self.check_known_consts(cx, lit.span, s, "f{32, 64}"), _ => (), } } - fn check_known_consts(&self, cx: &LateContext<'_>, e: &Expr<'_>, s: symbol::Symbol, module: &str) { + extract_msrv_attr!(LateContext); +} + +impl ApproxConstant { + fn check_known_consts(&self, cx: &LateContext<'_>, span: Span, s: symbol::Symbol, module: &str) { let s = s.as_str(); if s.parse::().is_ok() { for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS { @@ -96,7 +102,7 @@ impl ApproxConstant { span_lint_and_help( cx, APPROX_CONSTANT, - e.span, + span, format!("approximate value of `{module}::consts::{name}` found"), None, "consider using the constant directly", @@ -110,16 +116,6 @@ impl ApproxConstant { impl_lint_pass!(ApproxConstant => [APPROX_CONSTANT]); -impl<'tcx> LateLintPass<'tcx> for ApproxConstant { - fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { - if let ExprKind::Lit(lit) = &e.kind { - self.check_lit(cx, &lit.node, e); - } - } - - extract_msrv_attr!(LateContext); -} - /// Returns `false` if the number of significant figures in `value` are /// less than `min_digits`; otherwise, returns true if `value` is equal /// to `constant`, rounded to the number of digits present in `value`. From 5f6dd7a8eb8ea3cea3c53368c5e924bbf799483e Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Thu, 6 Feb 2025 12:47:47 +0900 Subject: [PATCH 047/991] remove an outdated line --- clippy_lints/src/transmute/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 1cb0f837227d..7c83a2187990 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -49,7 +49,6 @@ declare_clippy_lint! { "transmutes that are confusing at best, undefined behavior at worst and always useless" } -// FIXME: Move this to `complexity` again, after #5343 is fixed declare_clippy_lint! { /// ### What it does /// Checks for transmutes to the original type of the object From 2d7f2ff4b304f0fad8a5116c7155608b8c5f14eb Mon Sep 17 00:00:00 2001 From: Slava Barinov Date: Thu, 6 Feb 2025 13:43:54 +0900 Subject: [PATCH 048/991] allow code to call geteuid() --- src/tools/miri/src/shims/unix/foreign_items.rs | 2 +- src/tools/miri/tests/pass-dep/libc/libc-misc.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index d459ec7cb774..09757071075a 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -815,7 +815,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } - "getuid" => { + "getuid" | "geteuid" => { let [] = this.check_shim(abi, Conv::C, link_name, args)?; // For now, just pretend we always have this fixed UID. this.write_int(UID, dest)?; diff --git a/src/tools/miri/tests/pass-dep/libc/libc-misc.rs b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs index f07007fa7054..d1c0085b024a 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-misc.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs @@ -78,11 +78,16 @@ fn test_getuid() { let _val = unsafe { libc::getuid() }; } +fn test_geteuid() { + let _val = unsafe { libc::geteuid() }; +} + fn main() { test_thread_local_errno(); test_environ(); test_dlsym(); test_getuid(); + test_geteuid(); #[cfg(target_os = "linux")] test_sigrt(); From eb414585d2e92fd684e734ef681ca2e57ede1ddb Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 6 Feb 2025 04:54:51 +0000 Subject: [PATCH 049/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index e695fc4004b5..6e2344a92eec 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -8df89d1cb077cd76013d3f9f5a4e92c5b5a9280c +30865107cb8942ab8eaf9baf8d3aa2a6dec2643f From daab21ef9d161cc6b70f9e51f0a70cebd1628dc0 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 19 Jul 2024 21:39:46 +0700 Subject: [PATCH 050/991] Pulicize `clippy_utils::ty::ty_from_hir_ty` And use it in the next commit to avoid ICE. --- clippy_lints/src/zero_sized_map_values.rs | 17 ++--------------- clippy_utils/src/lib.rs | 1 + clippy_utils/src/ty/mod.rs | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/clippy_lints/src/zero_sized_map_values.rs b/clippy_lints/src/zero_sized_map_values.rs index 1221abec1abf..3f64d18e1ad4 100644 --- a/clippy_lints/src/zero_sized_map_values.rs +++ b/clippy_lints/src/zero_sized_map_values.rs @@ -1,10 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item}; +use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item, ty_from_hir_ty}; use rustc_hir::{self as hir, AmbigArg, HirId, ItemKind, Node}; -use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf as _; -use rustc_middle::ty::{self, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, TypeVisitableExt}; use rustc_session::declare_lint_pass; use rustc_span::sym; @@ -82,15 +81,3 @@ fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool { } false } - -fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { - cx.maybe_typeck_results() - .and_then(|results| { - if results.hir_owner == hir_ty.hir_id.owner { - results.node_type_opt(hir_ty.hir_id) - } else { - None - } - }) - .unwrap_or_else(|| lower_ty(cx.tcx, hir_ty)) -} diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 2f5639b686b8..23bb44dc1f13 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -39,6 +39,7 @@ extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; extern crate rustc_hir; +extern crate rustc_hir_analysis; extern crate rustc_hir_typeck; extern crate rustc_index; extern crate rustc_infer; diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index f2bbdda70585..befca19f485e 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -10,6 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, FnDecl, LangItem, TyKind}; +use rustc_hir_analysis::lower_ty; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::ConstValue; @@ -36,6 +37,19 @@ use crate::{def_path_def_ids, match_def_path, path_res}; mod type_certainty; pub use type_certainty::expr_type_is_certain; +/// Lower a [`hir::Ty`] to a [`rustc_middle::Ty`]. +pub fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { + cx.maybe_typeck_results() + .and_then(|results| { + if results.hir_owner == hir_ty.hir_id.owner { + results.node_type_opt(hir_ty.hir_id) + } else { + None + } + }) + .unwrap_or_else(|| lower_ty(cx.tcx, hir_ty)) +} + /// Checks if the given type implements copy. pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { cx.type_is_copy_modulo_regions(ty) From 83b97ae7139933bc17de6b5ccc8b01073e3d4949 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 19 Jul 2024 21:42:54 +0700 Subject: [PATCH 051/991] Use `clippy_utils::ty::ty_from_hir_ty` to avoid ICE --- clippy_lints/src/use_self.rs | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 84b6430294f3..e0efc536e34b 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -2,7 +2,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_from_proc_macro; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::ty::same_type_and_consts; +use clippy_utils::ty::{same_type_and_consts, ty_from_hir_ty}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir::def::{CtorOf, DefKind, Res}; @@ -12,7 +12,6 @@ use rustc_hir::{ self as hir, AmbigArg, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl, ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind, }; -use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty as MiddleTy; use rustc_session::impl_lint_pass; @@ -73,7 +72,6 @@ impl UseSelf { enum StackItem { Check { impl_id: LocalDefId, - in_body: u32, types_to_skip: FxHashSet, }, NoCheck, @@ -117,7 +115,6 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { .collect(); StackItem::Check { impl_id: item.owner_id.def_id, - in_body: 0, types_to_skip, } } else { @@ -186,27 +183,12 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { } } - fn check_body(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) { - // `lower_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies - // we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`. - // However the `node_type()` method can *only* be called in bodies. - if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() { - *in_body = in_body.saturating_add(1); - } - } - - fn check_body_post(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) { - if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() { - *in_body = in_body.saturating_sub(1); - } - } fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) { if !hir_ty.span.from_expansion() && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS) && let Some(&StackItem::Check { impl_id, - in_body, ref types_to_skip, }) = self.stack.last() && let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind @@ -215,12 +197,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Def(DefKind::TyParam, _) ) && !types_to_skip.contains(&hir_ty.hir_id) - && let ty = if in_body > 0 { - cx.typeck_results().node_type(hir_ty.hir_id) - } else { - // We don't care about ignoring infer vars here - lower_ty(cx.tcx, hir_ty.as_unambig_ty()) - } + && let ty = ty_from_hir_ty(cx, hir_ty) && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity() && same_type_and_consts(ty, impl_ty) // Ensure the type we encounter and the one from the impl have the same lifetime parameters. It may be that From 925718d8eb586d143de73e7eb3428cafb25077db Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sun, 21 Jul 2024 00:24:35 +0700 Subject: [PATCH 052/991] Make the "expensive" comment belong to a branch --- clippy_lints/src/use_self.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index e0efc536e34b..994ca9b66906 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -94,8 +94,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { .as_ref() .is_none_or(|params| params.parenthesized == GenericArgsParentheses::No) && !item.span.from_expansion() + // expensive, should be last check && !is_from_proc_macro(cx, item) - // expensive, should be last check { // Self cannot be used inside const generic parameters let types_to_skip = generics From e3e6e6ea4131db92ff23a0e32eb40a353f50f8f6 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 25 Jul 2024 04:13:15 +0700 Subject: [PATCH 053/991] add bug 13092 --- tests/ui/use_self.fixed | 24 ++++++++++++++++++++++++ tests/ui/use_self.rs | 24 ++++++++++++++++++++++++ tests/ui/use_self.stderr | 22 +++++++++++++++++++++- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index ffc5b74d7bd6..c6358a90f1e5 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -667,3 +667,27 @@ mod issue_10371 { } } } + +mod issue_13092 { + use std::cell::RefCell; + macro_rules! macro_inner_item { + ($ty:ty) => { + fn foo(_: $ty) { + fn inner(_: $ty) {} + } + }; + } + + #[derive(Default)] + struct MyStruct; + + impl MyStruct { + macro_inner_item!(Self); + } + + impl MyStruct { + thread_local! { + static SPECIAL: RefCell = RefCell::default(); + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index eb9d96168bcd..c900341cadd8 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -667,3 +667,27 @@ mod issue_10371 { } } } + +mod issue_13092 { + use std::cell::RefCell; + macro_rules! macro_inner_item { + ($ty:ty) => { + fn foo(_: $ty) { + fn inner(_: $ty) {} + } + }; + } + + #[derive(Default)] + struct MyStruct; + + impl MyStruct { + macro_inner_item!(MyStruct); + } + + impl MyStruct { + thread_local! { + static SPECIAL: RefCell = RefCell::default(); + } + } +} diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index bd5b685b45d5..06260a598be2 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -259,5 +259,25 @@ error: unnecessary structure name repetition LL | E::A => {}, | ^ help: use the applicable keyword: `Self` -error: aborting due to 43 previous errors +error: unnecessary structure name repetition + --> tests/ui/use_self.rs:685:27 + | +LL | macro_inner_item!(MyStruct); + | ^^^^^^^^ help: use the applicable keyword: `Self` + +error: unnecessary structure name repetition + --> tests/ui/use_self.rs:690:37 + | +LL | static SPECIAL: RefCell = RefCell::default(); + | ^^^^^^^^ help: use the applicable keyword: `Self` + +error: unnecessary structure name repetition + --> tests/ui/use_self.rs:690:37 + | +LL | static SPECIAL: RefCell = RefCell::default(); + | ^^^^^^^^ help: use the applicable keyword: `Self` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 46 previous errors From bcfd0d1aba7b63dd2b571771885375f9e1f66d1f Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 5 Sep 2024 00:58:33 +0700 Subject: [PATCH 054/991] Skip `use_self` inside macro expansion of `impl Self` items --- clippy_lints/src/use_self.rs | 14 +++++++++++++- tests/ui/use_self.fixed | 4 ++-- tests/ui/use_self.stderr | 22 +--------------------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 994ca9b66906..0d56cf5c2b27 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -128,6 +128,11 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { } fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { + // Checking items of `impl Self` blocks in which macro expands into. + if impl_item.span.from_expansion() { + self.stack.push(StackItem::NoCheck); + return; + } // We want to skip types in trait `impl`s that aren't declared as `Self` in the trait // declaration. The collection of those types is all this method implementation does. if let ImplItemKind::Fn(FnSig { decl, .. }, ..) = impl_item.kind @@ -183,6 +188,13 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { } } + fn check_impl_item_post(&mut self, _: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { + if impl_item.span.from_expansion() + && let Some(StackItem::NoCheck) = self.stack.last() + { + self.stack.pop(); + } + } fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) { if !hir_ty.span.from_expansion() @@ -197,7 +209,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Def(DefKind::TyParam, _) ) && !types_to_skip.contains(&hir_ty.hir_id) - && let ty = ty_from_hir_ty(cx, hir_ty) + && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty()) && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity() && same_type_and_consts(ty, impl_ty) // Ensure the type we encounter and the one from the impl have the same lifetime parameters. It may be that diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index c6358a90f1e5..572e919fb2d2 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -682,12 +682,12 @@ mod issue_13092 { struct MyStruct; impl MyStruct { - macro_inner_item!(Self); + macro_inner_item!(MyStruct); } impl MyStruct { thread_local! { - static SPECIAL: RefCell = RefCell::default(); + static SPECIAL: RefCell = RefCell::default(); } } } diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index 06260a598be2..bd5b685b45d5 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -259,25 +259,5 @@ error: unnecessary structure name repetition LL | E::A => {}, | ^ help: use the applicable keyword: `Self` -error: unnecessary structure name repetition - --> tests/ui/use_self.rs:685:27 - | -LL | macro_inner_item!(MyStruct); - | ^^^^^^^^ help: use the applicable keyword: `Self` - -error: unnecessary structure name repetition - --> tests/ui/use_self.rs:690:37 - | -LL | static SPECIAL: RefCell = RefCell::default(); - | ^^^^^^^^ help: use the applicable keyword: `Self` - -error: unnecessary structure name repetition - --> tests/ui/use_self.rs:690:37 - | -LL | static SPECIAL: RefCell = RefCell::default(); - | ^^^^^^^^ help: use the applicable keyword: `Self` - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 46 previous errors +error: aborting due to 43 previous errors From 9ea2b6501e3bd3a6a3d030e1215593f00d8f9ed8 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sat, 7 Sep 2024 01:15:55 +0700 Subject: [PATCH 055/991] add test to check for popping wrong items co-authored-by: Alex Macleod --- tests/ui/use_self.fixed | 21 +++++++++++++++++++++ tests/ui/use_self.rs | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index 572e919fb2d2..b44840d440b2 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -691,3 +691,24 @@ mod issue_13092 { } } } + +mod crash_check_13128 { + struct A; + + impl A { + fn a() { + struct B; + + // pushes a NoCheck + impl Iterator for &B { + // Pops the NoCheck + type Item = A; + + // Lints A -> Self + fn next(&mut self) -> Option { + Some(A) + } + } + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index c900341cadd8..342c724c8e48 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -691,3 +691,24 @@ mod issue_13092 { } } } + +mod crash_check_13128 { + struct A; + + impl A { + fn a() { + struct B; + + // pushes a NoCheck + impl Iterator for &B { + // Pops the NoCheck + type Item = A; + + // Lints A -> Self + fn next(&mut self) -> Option { + Some(A) + } + } + } + } +} From 5aa9d7ae7f33a21842c532aa7dcbe98e1df91a15 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 6 Feb 2025 15:00:24 +0100 Subject: [PATCH 056/991] Merge commit '3e3715c31236bff56f1c63a1de2c7bbdfcfb0923' into clippy-subtree-update --- CHANGELOG.md | 4 + book/src/attribs.md | 2 +- book/src/lint_configuration.md | 1 + book/src/lints.md | 13 + clippy_config/src/conf.rs | 1 + clippy_dev/src/new_lint.rs | 28 ++- clippy_dev/src/update_lints.rs | 28 ++- clippy_lints/src/declared_lints.rs | 4 + clippy_lints/src/dereference.rs | 67 ++++-- clippy_lints/src/doc/empty_line_after.rs | 11 +- clippy_lints/src/endian_bytes.rs | 3 +- clippy_lints/src/eta_reduction.rs | 13 +- clippy_lints/src/excessive_nesting.rs | 4 +- clippy_lints/src/format_push_string.rs | 4 +- clippy_lints/src/large_stack_arrays.rs | 2 +- clippy_lints/src/lib.rs | 2 + clippy_lints/src/loops/manual_slice_fill.rs | 111 +++++++++ clippy_lints/src/loops/mod.rs | 28 +++ clippy_lints/src/manual_div_ceil.rs | 15 +- clippy_lints/src/manual_option_as_slice.rs | 225 ++++++++++++++++++ clippy_lints/src/manual_unwrap_or_default.rs | 34 ++- clippy_lints/src/matches/match_as_ref.rs | 12 +- clippy_lints/src/methods/mod.rs | 68 +++++- .../src/methods/needless_option_take.rs | 18 +- clippy_lints/src/methods/return_and_then.rs | 67 ++++++ clippy_lints/src/methods/unnecessary_fold.rs | 68 ++++-- .../src/methods/unnecessary_lazy_eval.rs | 6 +- clippy_lints/src/misc.rs | 2 +- .../src/multiple_unsafe_ops_per_block.rs | 23 +- clippy_lints/src/mutex_atomic.rs | 30 ++- clippy_lints/src/needless_pass_by_value.rs | 11 +- clippy_lints/src/operators/mod.rs | 3 - clippy_lints/src/precedence.rs | 68 ++++-- clippy_lints/src/ptr.rs | 30 ++- clippy_lints/src/redundant_clone.rs | 12 +- clippy_lints/src/redundant_else.rs | 46 +++- clippy_lints/src/same_name_method.rs | 11 +- clippy_lints/src/size_of_in_element_count.rs | 10 +- clippy_lints/src/to_digit_is_some.rs | 12 +- clippy_lints/src/types/mod.rs | 64 +++-- clippy_lints/src/unconditional_recursion.rs | 11 +- clippy_lints/src/unnecessary_semicolon.rs | 38 ++- clippy_lints/src/unneeded_struct_pattern.rs | 2 +- clippy_lints/src/write.rs | 2 +- clippy_utils/README.md | 2 +- clippy_utils/src/ast_utils/mod.rs | 6 +- clippy_utils/src/lib.rs | 9 + clippy_utils/src/mir/mod.rs | 12 +- clippy_utils/src/msrvs.rs | 5 +- clippy_utils/src/qualify_min_const_fn.rs | 5 +- clippy_utils/src/source.rs | 15 +- clippy_utils/src/str_utils.rs | 10 +- lintcheck/src/config.rs | 9 + lintcheck/src/main.rs | 53 ++++- rust-toolchain | 2 +- tests/ui/cmp_null.fixed | 32 +++ tests/ui/cmp_null.rs | 12 + tests/ui/cmp_null.stderr | 26 +- tests/ui/eta.fixed | 5 + tests/ui/eta.rs | 5 + tests/ui/eta.stderr | 54 +++-- tests/ui/ignored_unit_patterns.fixed | 15 +- tests/ui/ignored_unit_patterns.rs | 15 +- tests/ui/ignored_unit_patterns.stderr | 18 +- .../ui/manual_memcpy/without_loop_counters.rs | 7 +- .../without_loop_counters.stderr | 36 +-- tests/ui/manual_option_as_slice.fixed | 62 +++++ tests/ui/manual_option_as_slice.rs | 71 ++++++ tests/ui/manual_option_as_slice.stderr | 58 +++++ tests/ui/manual_slice_fill.fixed | 101 ++++++++ tests/ui/manual_slice_fill.rs | 110 +++++++++ tests/ui/manual_slice_fill.stderr | 38 +++ .../ui/manual_unwrap_or_default_unfixable.rs | 15 ++ .../manual_unwrap_or_default_unfixable.stderr | 34 +++ tests/ui/needless_option_take.fixed | 58 +++++ tests/ui/needless_option_take.stderr | 36 ++- tests/ui/needless_range_loop.rs | 3 +- tests/ui/needless_range_loop.stderr | 28 +-- tests/ui/precedence.fixed | 8 +- tests/ui/precedence.stderr | 26 +- tests/ui/precedence_bits.fixed | 35 +++ tests/ui/precedence_bits.rs | 35 +++ tests/ui/precedence_bits.stderr | 29 +++ tests/ui/print_literal.fixed | 14 ++ tests/ui/print_literal.rs | 15 ++ tests/ui/print_literal.stderr | 38 ++- tests/ui/redundant_else.fixed | 154 ++++++++++++ tests/ui/redundant_else.stderr | 77 ++++-- tests/ui/return_and_then.fixed | 67 ++++++ tests/ui/return_and_then.rs | 63 +++++ tests/ui/return_and_then.stderr | 101 ++++++++ .../size_of_in_element_count/expressions.rs | 17 +- .../expressions.stderr | 12 +- .../ui/size_of_in_element_count/functions.rs | 45 ++-- .../size_of_in_element_count/functions.stderr | 110 ++++----- tests/ui/toplevel_ref_arg_non_rustfix.stderr | 4 +- .../unnecessary_semicolon.edition2021.fixed | 6 + .../unnecessary_semicolon.edition2024.fixed | 6 + tests/ui/unnecessary_semicolon.rs | 6 + tests/ui/write_literal.fixed | 16 ++ tests/ui/write_literal.rs | 17 ++ tests/ui/write_literal.stderr | 38 ++- util/gh-pages/index_template.html | 23 +- util/gh-pages/script.js | 87 ++++--- util/gh-pages/style.css | 8 +- util/gh-pages/theme.js | 9 + 106 files changed, 2681 insertions(+), 566 deletions(-) create mode 100644 clippy_lints/src/loops/manual_slice_fill.rs create mode 100644 clippy_lints/src/manual_option_as_slice.rs create mode 100644 clippy_lints/src/methods/return_and_then.rs create mode 100644 tests/ui/cmp_null.fixed create mode 100644 tests/ui/manual_option_as_slice.fixed create mode 100644 tests/ui/manual_option_as_slice.rs create mode 100644 tests/ui/manual_option_as_slice.stderr create mode 100644 tests/ui/manual_slice_fill.fixed create mode 100644 tests/ui/manual_slice_fill.rs create mode 100644 tests/ui/manual_slice_fill.stderr create mode 100644 tests/ui/manual_unwrap_or_default_unfixable.rs create mode 100644 tests/ui/manual_unwrap_or_default_unfixable.stderr create mode 100644 tests/ui/needless_option_take.fixed create mode 100644 tests/ui/precedence_bits.fixed create mode 100644 tests/ui/precedence_bits.rs create mode 100644 tests/ui/precedence_bits.stderr create mode 100644 tests/ui/redundant_else.fixed create mode 100644 tests/ui/return_and_then.fixed create mode 100644 tests/ui/return_and_then.rs create mode 100644 tests/ui/return_and_then.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index bc42c07224e1..fa03c953aa59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5765,6 +5765,7 @@ Released 2018-09-13 [`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive [`manual_ok_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_err [`manual_ok_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_or +[`manual_option_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_as_slice [`manual_pattern_char_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison [`manual_range_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains [`manual_range_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_patterns @@ -5773,6 +5774,7 @@ Released 2018-09-13 [`manual_retain`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain [`manual_rotate`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rotate [`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_saturating_arithmetic +[`manual_slice_fill`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_fill [`manual_slice_size_calculation`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_size_calculation [`manual_split_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once [`manual_str_repeat`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat @@ -5954,6 +5956,7 @@ Released 2018-09-13 [`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters [`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_comma [`precedence`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence +[`precedence_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence_bits [`print_in_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_in_format_impl [`print_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_literal [`print_stderr`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr @@ -6026,6 +6029,7 @@ Released 2018-09-13 [`result_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unwrap_or_else [`result_unit_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unit_err [`result_unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unwrap_used +[`return_and_then`]: https://rust-lang.github.io/rust-clippy/master/index.html#return_and_then [`return_self_not_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#return_self_not_must_use [`reverse_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#reverse_range_loop [`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#reversed_empty_ranges diff --git a/book/src/attribs.md b/book/src/attribs.md index cf99497bc0fc..9b7f59705041 100644 --- a/book/src/attribs.md +++ b/book/src/attribs.md @@ -5,7 +5,7 @@ To do this, Clippy provides attributes that can be applied to items in the 3rd p ## `#[clippy::format_args]` -_Available since Clippy v1.84_ +_Available since Clippy v1.85_ This attribute can be added to a macro that supports `format!`, `println!`, or similar syntax. It tells Clippy that the macro is a formatting macro, and that the arguments to the macro diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index b8f9fff9c613..dab2630a56fc 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -752,6 +752,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid) * [`manual_repeat_n`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_repeat_n) * [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain) +* [`manual_slice_fill`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_fill) * [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once) * [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat) * [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip) diff --git a/book/src/lints.md b/book/src/lints.md index 442dc63914e9..1dd517976601 100644 --- a/book/src/lints.md +++ b/book/src/lints.md @@ -101,5 +101,18 @@ The `clippy::cargo` group gives you suggestions on how to improve your your crate and are not sure if you have all useful information in your `Cargo.toml`. +## Nursery + +The `clippy::nursery` group contains lints which are buggy or need more work. It is **not** +recommended to enable the whole group, but rather cherry-pick lints that are useful for your +code base and your use case. + +## Deprecated + +The `clippy::deprecated` is empty lints that exist to ensure that `#[allow(lintname)]` still +compiles after the lint was deprecated. Deprecation "removes" lints by removing their +functionality and marking them as deprecated, which may cause further warnings but cannot +cause a compiler error. + [Clippy lint documentation]: https://rust-lang.github.io/rust-clippy/ [Clippy 1.0 RFC]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#lint-audit-and-categories diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 552141476f3a..a1591188bee7 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -621,6 +621,7 @@ define_Conf! { manual_rem_euclid, manual_repeat_n, manual_retain, + manual_slice_fill, manual_split_once, manual_str_repeat, manual_strip, diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index 35dd986ff614..cc4b26867a20 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -255,8 +255,9 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { let name_camel = to_camel_case(lint.name); let name_upper = lint_name.to_uppercase(); - result.push_str(&if enable_msrv { - formatdoc!( + if enable_msrv { + let _: fmt::Result = writedoc!( + result, r" use clippy_utils::msrvs::{{self, Msrv}}; use clippy_config::Conf; @@ -265,22 +266,24 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { use rustc_session::impl_lint_pass; " - ) + ); } else { - formatdoc!( + let _: fmt::Result = writedoc!( + result, r" {pass_import} use rustc_lint::{{{context_import}, {pass_type}}}; use rustc_session::declare_lint_pass; " - ) - }); + ); + } let _: fmt::Result = writeln!(result, "{}", get_lint_declaration(&name_upper, category)); - result.push_str(&if enable_msrv { - formatdoc!( + if enable_msrv { + let _: fmt::Result = writedoc!( + result, r" pub struct {name_camel} {{ msrv: Msrv, @@ -301,16 +304,17 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { // TODO: Add MSRV level to `clippy_config/src/msrvs.rs` if needed. // TODO: Update msrv config comment in `clippy_config/src/conf.rs` " - ) + ); } else { - formatdoc!( + let _: fmt::Result = writedoc!( + result, r" declare_lint_pass!({name_camel} => [{name_upper}]); impl {pass_type}{pass_lifetimes} for {name_camel} {{}} " - ) - }); + ); + } result } diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs index fc0780f89a7f..b80ee5aac7e7 100644 --- a/clippy_dev/src/update_lints.rs +++ b/clippy_dev/src/update_lints.rs @@ -985,17 +985,23 @@ mod tests { Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()), ]; let mut expected: HashMap> = HashMap::new(); - expected.insert("group1".to_string(), vec![ - Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()), - Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()), - ]); - expected.insert("group2".to_string(), vec![Lint::new( - "should_assert_eq2", - "group2", - "\"abc\"", - "module_name", - Range::default(), - )]); + expected.insert( + "group1".to_string(), + vec![ + Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()), + Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()), + ], + ); + expected.insert( + "group2".to_string(), + vec![Lint::new( + "should_assert_eq2", + "group2", + "\"abc\"", + "module_name", + Range::default(), + )], + ); assert_eq!(expected, Lint::by_lint_group(lints.into_iter())); } } diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 86bcf8edd578..9fbeab5bf2e1 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -292,6 +292,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::loops::MANUAL_FIND_INFO, crate::loops::MANUAL_FLATTEN_INFO, crate::loops::MANUAL_MEMCPY_INFO, + crate::loops::MANUAL_SLICE_FILL_INFO, crate::loops::MANUAL_WHILE_LET_SOME_INFO, crate::loops::MISSING_SPIN_LOOP_INFO, crate::loops::MUT_RANGE_BOUND_INFO, @@ -321,6 +322,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::manual_let_else::MANUAL_LET_ELSE_INFO, crate::manual_main_separator_str::MANUAL_MAIN_SEPARATOR_STR_INFO, crate::manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE_INFO, + crate::manual_option_as_slice::MANUAL_OPTION_AS_SLICE_INFO, crate::manual_range_patterns::MANUAL_RANGE_PATTERNS_INFO, crate::manual_rem_euclid::MANUAL_REM_EUCLID_INFO, crate::manual_retain::MANUAL_RETAIN_INFO, @@ -463,6 +465,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::methods::REPEAT_ONCE_INFO, crate::methods::RESULT_FILTER_MAP_INFO, crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO, + crate::methods::RETURN_AND_THEN_INFO, crate::methods::SEARCH_IS_SOME_INFO, crate::methods::SEEK_FROM_CURRENT_INFO, crate::methods::SEEK_TO_START_INSTEAD_OF_REWIND_INFO, @@ -626,6 +629,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::permissions_set_readonly_false::PERMISSIONS_SET_READONLY_FALSE_INFO, crate::pointers_in_nomem_asm_block::POINTERS_IN_NOMEM_ASM_BLOCK_INFO, crate::precedence::PRECEDENCE_INFO, + crate::precedence::PRECEDENCE_BITS_INFO, crate::ptr::CMP_NULL_INFO, crate::ptr::INVALID_NULL_PTR_USAGE_INFO, crate::ptr::MUT_FROM_REF_INFO, diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 123e358d7c3d..233ebe00d8e7 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -291,10 +291,13 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { && let Some(ty) = use_node.defined_ty(cx) && TyCoercionStability::for_defined_ty(cx, ty, use_node.is_return()).is_deref_stable() { - self.state = Some((State::ExplicitDeref { mutability: None }, StateData { - first_expr: expr, - adjusted_ty, - })); + self.state = Some(( + State::ExplicitDeref { mutability: None }, + StateData { + first_expr: expr, + adjusted_ty, + }, + )); } }, RefOp::Method { mutbl, is_ufcs } @@ -456,10 +459,13 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { && next_adjust.is_none_or(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_))) && iter.all(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_))) { - self.state = Some((State::Borrow { mutability }, StateData { - first_expr: expr, - adjusted_ty, - })); + self.state = Some(( + State::Borrow { mutability }, + StateData { + first_expr: expr, + adjusted_ty, + }, + )); } }, _ => {}, @@ -503,10 +509,13 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { let stability = state.stability; report(cx, expr, State::DerefedBorrow(state), data, typeck); if stability.is_deref_stable() { - self.state = Some((State::Borrow { mutability }, StateData { - first_expr: expr, - adjusted_ty, - })); + self.state = Some(( + State::Borrow { mutability }, + StateData { + first_expr: expr, + adjusted_ty, + }, + )); } }, (Some((State::DerefedBorrow(state), data)), RefOp::Deref) => { @@ -531,10 +540,13 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { } else if stability.is_deref_stable() && let Some(parent) = get_parent_expr(cx, expr) { - self.state = Some((State::ExplicitDeref { mutability: None }, StateData { - first_expr: parent, - adjusted_ty, - })); + self.state = Some(( + State::ExplicitDeref { mutability: None }, + StateData { + first_expr: parent, + adjusted_ty, + }, + )); } }, @@ -1124,17 +1136,20 @@ impl<'tcx> Dereferencing<'tcx> { if let Some(outer_pat) = self.ref_locals.get_mut(&local) { if let Some(pat) = outer_pat { // Check for auto-deref - if !matches!(cx.typeck_results().expr_adjustments(e), [ - Adjustment { - kind: Adjust::Deref(_), + if !matches!( + cx.typeck_results().expr_adjustments(e), + [ + Adjustment { + kind: Adjust::Deref(_), + .. + }, + Adjustment { + kind: Adjust::Deref(_), + .. + }, .. - }, - Adjustment { - kind: Adjust::Deref(_), - .. - }, - .. - ]) { + ] + ) { match get_parent_expr(cx, e) { // Field accesses are the same no matter the number of references. Some(Expr { diff --git a/clippy_lints/src/doc/empty_line_after.rs b/clippy_lints/src/doc/empty_line_after.rs index 099194d4e746..6e85c6af642b 100644 --- a/clippy_lints/src/doc/empty_line_after.rs +++ b/clippy_lints/src/doc/empty_line_after.rs @@ -233,10 +233,13 @@ fn check_gaps(cx: &LateContext<'_>, gaps: &[Gap<'_>]) -> bool { if let Some(owner) = cx.last_node_with_lint_attrs.as_owner() { let def_id = owner.to_def_id(); let def_descr = cx.tcx.def_descr(def_id); - diag.span_label(cx.tcx.def_span(def_id), match kind { - StopKind::Attr => format!("the attribute applies to this {def_descr}"), - StopKind::Doc(_) => format!("the comment documents this {def_descr}"), - }); + diag.span_label( + cx.tcx.def_span(def_id), + match kind { + StopKind::Attr => format!("the attribute applies to this {def_descr}"), + StopKind::Doc(_) => format!("the comment documents this {def_descr}"), + }, + ); } diag.multipart_suggestion_with_style( diff --git a/clippy_lints/src/endian_bytes.rs b/clippy_lints/src/endian_bytes.rs index 29deaaf3bc7a..a7670ffce887 100644 --- a/clippy_lints/src/endian_bytes.rs +++ b/clippy_lints/src/endian_bytes.rs @@ -6,6 +6,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::Ty; use rustc_session::declare_lint_pass; use rustc_span::Symbol; +use std::fmt::Write; declare_clippy_lint! { /// ### What it does @@ -183,7 +184,7 @@ fn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: Prefix help_str.push_str("either of "); } - help_str.push_str(&format!("`{ty}::{}` ", lint.as_name(prefix))); + write!(help_str, "`{ty}::{}` ", lint.as_name(prefix)).unwrap(); if i != len && !only_one { help_str.push_str("or "); diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 52b699274bbb..f90bf9157aad 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -1,13 +1,13 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::higher::VecArgs; -use clippy_utils::source::snippet_opt; +use clippy_utils::source::{snippet_opt, snippet_with_applicability}; use clippy_utils::ty::get_type_diagnostic_name; use clippy_utils::usage::{local_used_after_expr, local_used_in}; use clippy_utils::{ get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local, path_to_local_id, }; use rustc_errors::Applicability; -use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, Safety, TyKind}; +use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{ @@ -239,6 +239,11 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx && !cx.tcx.has_attr(method_def_id, sym::track_caller) && check_sig(closure_sig, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder()) { + let mut app = Applicability::MachineApplicable; + let generic_args = match path.args.and_then(GenericArgs::span_ext) { + Some(span) => format!("::{}", snippet_with_applicability(cx, span, "<..>", &mut app)), + None => String::new(), + }; span_lint_and_then( cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, @@ -251,8 +256,8 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx diag.span_suggestion( expr.span, "replace the closure with the method itself", - format!("{}::{}", type_name, path.ident.name), - Applicability::MachineApplicable, + format!("{}::{}{}", type_name, path.ident.name, generic_args), + app, ); }, ); diff --git a/clippy_lints/src/excessive_nesting.rs b/clippy_lints/src/excessive_nesting.rs index 36567b3ded0b..1d3ae8949441 100644 --- a/clippy_lints/src/excessive_nesting.rs +++ b/clippy_lints/src/excessive_nesting.rs @@ -124,7 +124,9 @@ struct NestingVisitor<'conf, 'cx> { impl NestingVisitor<'_, '_> { fn check_indent(&mut self, span: Span, id: NodeId) -> bool { - if self.nest_level > self.conf.excessive_nesting_threshold && !span.in_external_macro(self.cx.sess().source_map()) { + if self.nest_level > self.conf.excessive_nesting_threshold + && !span.in_external_macro(self.cx.sess().source_map()) + { self.conf.nodes.insert(id); return true; diff --git a/clippy_lints/src/format_push_string.rs b/clippy_lints/src/format_push_string.rs index 8b1f86cbb913..68cc50f39391 100644 --- a/clippy_lints/src/format_push_string.rs +++ b/clippy_lints/src/format_push_string.rs @@ -11,7 +11,7 @@ declare_clippy_lint! { /// Detects cases where the result of a `format!` call is /// appended to an existing `String`. /// - /// ### Why restrict this? + /// ### Why is this bad? /// Introduces an extra, avoidable heap allocation. /// /// ### Known problems @@ -35,7 +35,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.62.0"] pub FORMAT_PUSH_STRING, - restriction, + pedantic, "`format!(..)` appended to existing `String`" } declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]); diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index 6f5c5d6b3ea3..c68499ce9f78 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -7,8 +7,8 @@ use clippy_utils::macros::macro_backtrace; use clippy_utils::source::snippet; use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty; +use rustc_middle::ty::layout::LayoutOf; use rustc_session::impl_lint_pass; use rustc_span::{Span, sym}; diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 4b700673d0f8..8887ab7ec0d7 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -217,6 +217,7 @@ mod manual_is_power_of_two; mod manual_let_else; mod manual_main_separator_str; mod manual_non_exhaustive; +mod manual_option_as_slice; mod manual_range_patterns; mod manual_rem_euclid; mod manual_retain; @@ -976,5 +977,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::new(unneeded_struct_pattern::UnneededStructPattern)); store.register_late_pass(|_| Box::::default()); store.register_late_pass(move |_| Box::new(non_std_lazy_statics::NonStdLazyStatic::new(conf))); + store.register_late_pass(|_| Box::new(manual_option_as_slice::ManualOptionAsSlice::new(conf))); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/loops/manual_slice_fill.rs b/clippy_lints/src/loops/manual_slice_fill.rs new file mode 100644 index 000000000000..7c6564235796 --- /dev/null +++ b/clippy_lints/src/loops/manual_slice_fill.rs @@ -0,0 +1,111 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::eager_or_lazy::switch_to_eager_eval; +use clippy_utils::macros::span_is_local; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::source::{HasSession, snippet_with_applicability}; +use clippy_utils::ty::implements_trait; +use clippy_utils::{higher, peel_blocks_with_stmt, span_contains_comment}; +use rustc_ast::ast::LitKind; +use rustc_ast::{RangeLimits, UnOp}; +use rustc_data_structures::packed::Pu128; +use rustc_errors::Applicability; +use rustc_hir::QPath::Resolved; +use rustc_hir::def::Res; +use rustc_hir::{Expr, ExprKind, Pat}; +use rustc_lint::LateContext; +use rustc_span::source_map::Spanned; +use rustc_span::sym; + +use super::MANUAL_SLICE_FILL; + +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + expr: &'tcx Expr<'_>, + msrv: &Msrv, +) { + if !msrv.meets(msrvs::SLICE_FILL) { + return; + } + + // `for _ in 0..slice.len() { slice[_] = value; }` + if let Some(higher::Range { + start: Some(start), + end: Some(end), + limits: RangeLimits::HalfOpen, + }) = higher::Range::hir(arg) + && let ExprKind::Lit(Spanned { + node: LitKind::Int(Pu128(0), _), + .. + }) = start.kind + && let ExprKind::Block(..) = body.kind + // Check if the body is an assignment to a slice element. + && let ExprKind::Assign(assignee, assignval, _) = peel_blocks_with_stmt(body).kind + && let ExprKind::Index(slice, _, _) = assignee.kind + // Check if `len()` is used for the range end. + && let ExprKind::MethodCall(path, recv,..) = end.kind + && path.ident.name == sym::len + // Check if the slice which is being assigned to is the same as the one being iterated over. + && let ExprKind::Path(Resolved(_, recv_path)) = recv.kind + && let ExprKind::Path(Resolved(_, slice_path)) = slice.kind + && recv_path.res == slice_path.res + && !assignval.span.from_expansion() + // It is generally not equivalent to use the `fill` method if `assignval` can have side effects + && switch_to_eager_eval(cx, assignval) + && span_is_local(assignval.span) + // The `fill` method requires that the slice's element type implements the `Clone` trait. + && let Some(clone_trait) = cx.tcx.lang_items().clone_trait() + && implements_trait(cx, cx.typeck_results().expr_ty(slice), clone_trait, &[]) + { + sugg(cx, body, expr, slice.span, assignval.span); + } + // `for _ in &mut slice { *_ = value; }` + else if let ExprKind::AddrOf(_, _, recv) = arg.kind + // Check if the body is an assignment to a slice element. + && let ExprKind::Assign(assignee, assignval, _) = peel_blocks_with_stmt(body).kind + && let ExprKind::Unary(UnOp::Deref, slice_iter) = assignee.kind + && let ExprKind::Path(Resolved(_, recv_path)) = recv.kind + // Check if the slice which is being assigned to is the same as the one being iterated over. + && let ExprKind::Path(Resolved(_, slice_path)) = slice_iter.kind + && let Res::Local(local) = slice_path.res + && local == pat.hir_id + && !assignval.span.from_expansion() + && switch_to_eager_eval(cx, assignval) + && span_is_local(assignval.span) + // The `fill` method cannot be used if the slice's element type does not implement the `Clone` trait. + && let Some(clone_trait) = cx.tcx.lang_items().clone_trait() + && implements_trait(cx, cx.typeck_results().expr_ty(recv), clone_trait, &[]) + { + sugg(cx, body, expr, recv_path.span, assignval.span); + } +} + +fn sugg<'tcx>( + cx: &LateContext<'tcx>, + body: &'tcx Expr<'_>, + expr: &'tcx Expr<'_>, + slice_span: rustc_span::Span, + assignval_span: rustc_span::Span, +) { + let mut app = if span_contains_comment(cx.sess().source_map(), body.span) { + Applicability::MaybeIncorrect // Comments may be informational. + } else { + Applicability::MachineApplicable + }; + + span_lint_and_sugg( + cx, + MANUAL_SLICE_FILL, + expr.span, + "manually filling a slice", + "try", + format!( + "{}.fill({});", + snippet_with_applicability(cx, slice_span, "..", &mut app), + snippet_with_applicability(cx, assignval_span, "..", &mut app), + ), + app, + ); +} diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index c5e75af2303c..cdc8c18c3b74 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -8,6 +8,7 @@ mod iter_next_loop; mod manual_find; mod manual_flatten; mod manual_memcpy; +mod manual_slice_fill; mod manual_while_let_some; mod missing_spin_loop; mod mut_range_bound; @@ -714,6 +715,31 @@ declare_clippy_lint! { "possibly unintended infinite loop" } +declare_clippy_lint! { + /// ### What it does + /// Checks for manually filling a slice with a value. + /// + /// ### Why is this bad? + /// Using the `fill` method is more idiomatic and concise. + /// + /// ### Example + /// ```no_run + /// let mut some_slice = [1, 2, 3, 4, 5]; + /// for i in 0..some_slice.len() { + /// some_slice[i] = 0; + /// } + /// ``` + /// Use instead: + /// ```no_run + /// let mut some_slice = [1, 2, 3, 4, 5]; + /// some_slice.fill(0); + /// ``` + #[clippy::version = "1.86.0"] + pub MANUAL_SLICE_FILL, + style, + "manually filling a slice with a value" +} + pub struct Loops { msrv: Msrv, enforce_iter_loop_reborrow: bool, @@ -750,6 +776,7 @@ impl_lint_pass!(Loops => [ MANUAL_WHILE_LET_SOME, UNUSED_ENUMERATE_INDEX, INFINITE_LOOP, + MANUAL_SLICE_FILL, ]); impl<'tcx> LateLintPass<'tcx> for Loops { @@ -823,6 +850,7 @@ impl Loops { ) { let is_manual_memcpy_triggered = manual_memcpy::check(cx, pat, arg, body, expr); if !is_manual_memcpy_triggered { + manual_slice_fill::check(cx, pat, arg, body, expr, &self.msrv); needless_range_loop::check(cx, pat, arg, body, expr); explicit_counter_loop::check(cx, pat, arg, body, expr, label); } diff --git a/clippy_lints/src/manual_div_ceil.rs b/clippy_lints/src/manual_div_ceil.rs index 816ca17b3d2d..04357cdd8f66 100644 --- a/clippy_lints/src/manual_div_ceil.rs +++ b/clippy_lints/src/manual_div_ceil.rs @@ -181,13 +181,16 @@ fn build_suggestion( ExprKind::Lit(Spanned { node: LitKind::Int(_, LitIntType::Unsuffixed), .. - }) | ExprKind::Unary(UnOp::Neg, Expr { - kind: ExprKind::Lit(Spanned { - node: LitKind::Int(_, LitIntType::Unsuffixed), + }) | ExprKind::Unary( + UnOp::Neg, + Expr { + kind: ExprKind::Lit(Spanned { + node: LitKind::Int(_, LitIntType::Unsuffixed), + .. + }), .. - }), - .. - }) + } + ) ) { format!("_{}", cx.typeck_results().expr_ty(rhs)) } else { diff --git a/clippy_lints/src/manual_option_as_slice.rs b/clippy_lints/src/manual_option_as_slice.rs new file mode 100644 index 000000000000..5c40c945c690 --- /dev/null +++ b/clippy_lints/src/manual_option_as_slice.rs @@ -0,0 +1,225 @@ +use clippy_config::Conf; +use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::{is_none_arm, msrvs, peel_hir_expr_refs}; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{Arm, Expr, ExprKind, LangItem, Pat, PatKind, QPath, is_range_literal}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; +use rustc_session::impl_lint_pass; +use rustc_span::{Span, Symbol, sym}; + +declare_clippy_lint! { + /// ### What it does + /// This detects various manual reimplementations of `Option::as_slice`. + /// + /// ### Why is this bad? + /// Those implementations are both more complex than calling `as_slice` + /// and unlike that incur a branch, pessimizing performance and leading + /// to more generated code. + /// + /// ### Example + /// ```no_run + ///# let opt = Some(1); + /// _ = opt.as_ref().map_or(&[][..], std::slice::from_ref); + /// _ = match opt.as_ref() { + /// Some(f) => std::slice::from_ref(f), + /// None => &[], + /// }; + /// ``` + /// Use instead: + /// ```no_run + ///# let opt = Some(1); + /// _ = opt.as_slice(); + /// _ = opt.as_slice(); + /// ``` + #[clippy::version = "1.85.0"] + pub MANUAL_OPTION_AS_SLICE, + complexity, + "manual `Option::as_slice`" +} + +pub struct ManualOptionAsSlice { + msrv: msrvs::Msrv, +} + +impl ManualOptionAsSlice { + pub fn new(conf: &Conf) -> Self { + Self { + msrv: conf.msrv.clone(), + } + } +} + +impl_lint_pass!(ManualOptionAsSlice => [MANUAL_OPTION_AS_SLICE]); + +impl LateLintPass<'_> for ManualOptionAsSlice { + extract_msrv_attr!(LateContext); + + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + let span = expr.span; + if span.from_expansion() + || !self.msrv.meets(if clippy_utils::is_in_const_context(cx) { + msrvs::CONST_OPTION_AS_SLICE + } else { + msrvs::OPTION_AS_SLICE + }) + { + return; + } + match expr.kind { + ExprKind::Match(scrutinee, [arm1, arm2], _) => { + if is_none_arm(cx, arm2) && check_arms(cx, arm2, arm1) + || is_none_arm(cx, arm1) && check_arms(cx, arm1, arm2) + { + check_as_ref(cx, scrutinee, span); + } + }, + ExprKind::If(cond, then, Some(other)) => { + if let ExprKind::Let(let_expr) = cond.kind + && let Some(binding) = extract_ident_from_some_pat(cx, let_expr.pat) + && check_some_body(cx, binding, then) + && is_empty_slice(cx, other.peel_blocks()) + { + check_as_ref(cx, let_expr.init, span); + } + }, + ExprKind::MethodCall(seg, callee, [], _) => { + if seg.ident.name.as_str() == "unwrap_or_default" { + check_map(cx, callee, span); + } + }, + ExprKind::MethodCall(seg, callee, [or], _) => match seg.ident.name.as_str() { + "unwrap_or" => { + if is_empty_slice(cx, or) { + check_map(cx, callee, span); + } + }, + "unwrap_or_else" => { + if returns_empty_slice(cx, or) { + check_map(cx, callee, span); + } + }, + _ => {}, + }, + ExprKind::MethodCall(seg, callee, [or_else, map], _) => match seg.ident.name.as_str() { + "map_or" => { + if is_empty_slice(cx, or_else) && is_slice_from_ref(cx, map) { + check_as_ref(cx, callee, span); + } + }, + "map_or_else" => { + if returns_empty_slice(cx, or_else) && is_slice_from_ref(cx, map) { + check_as_ref(cx, callee, span); + } + }, + _ => {}, + }, + _ => {}, + } + } +} + +fn check_map(cx: &LateContext<'_>, map: &Expr<'_>, span: Span) { + if let ExprKind::MethodCall(seg, callee, [mapping], _) = map.kind + && seg.ident.name == sym::map + && is_slice_from_ref(cx, mapping) + { + check_as_ref(cx, callee, span); + } +} + +fn check_as_ref(cx: &LateContext<'_>, expr: &Expr<'_>, span: Span) { + if let ExprKind::MethodCall(seg, callee, [], _) = expr.kind + && seg.ident.name == sym::as_ref + && let ty::Adt(adtdef, ..) = cx.typeck_results().expr_ty(callee).kind() + && cx.tcx.is_diagnostic_item(sym::Option, adtdef.did()) + { + if let Some(snippet) = clippy_utils::source::snippet_opt(cx, callee.span) { + span_lint_and_sugg( + cx, + MANUAL_OPTION_AS_SLICE, + span, + "use `Option::as_slice`", + "use", + format!("{snippet}.as_slice()"), + Applicability::MachineApplicable, + ); + } else { + span_lint(cx, MANUAL_OPTION_AS_SLICE, span, "use `Option_as_slice`"); + } + } +} + +fn extract_ident_from_some_pat(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option { + if let PatKind::TupleStruct(QPath::Resolved(None, path), [binding], _) = pat.kind + && let Res::Def(DefKind::Ctor(..), def_id) = path.res + && let PatKind::Binding(_mode, _hir_id, ident, _inner_pat) = binding.kind + && clippy_utils::is_lang_item_or_ctor(cx, def_id, LangItem::OptionSome) + { + Some(ident.name) + } else { + None + } +} + +/// Returns true if `expr` is `std::slice::from_ref()`. Used in `if let`s. +fn check_some_body(cx: &LateContext<'_>, name: Symbol, expr: &Expr<'_>) -> bool { + if let ExprKind::Call(slice_from_ref, [arg]) = expr.peel_blocks().kind + && is_slice_from_ref(cx, slice_from_ref) + && let ExprKind::Path(QPath::Resolved(None, path)) = arg.kind + && let [seg] = path.segments + { + seg.ident.name == name + } else { + false + } +} + +fn check_arms(cx: &LateContext<'_>, none_arm: &Arm<'_>, some_arm: &Arm<'_>) -> bool { + if none_arm.guard.is_none() + && some_arm.guard.is_none() + && is_empty_slice(cx, none_arm.body) + && let Some(name) = extract_ident_from_some_pat(cx, some_arm.pat) + { + check_some_body(cx, name, some_arm.body) + } else { + false + } +} + +fn returns_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + match expr.kind { + ExprKind::Path(_) => clippy_utils::is_path_diagnostic_item(cx, expr, sym::default_fn), + ExprKind::Closure(cl) => is_empty_slice(cx, cx.tcx.hir().body(cl.body).value), + _ => false, + } +} + +/// Returns if expr returns an empty slice. If: +/// - An indexing operation to an empty array with a built-in range. `[][..]` +/// - An indexing operation with a zero-ended range. `expr[..0]` +/// - A reference to an empty array. `&[]` +/// - Or a call to `Default::default`. +fn is_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + let expr = peel_hir_expr_refs(expr.peel_blocks()).0; + match expr.kind { + ExprKind::Index(arr, range, _) => match arr.kind { + ExprKind::Array([]) => is_range_literal(range), + ExprKind::Array(_) => { + let Some(range) = clippy_utils::higher::Range::hir(range) else { + return false; + }; + range.end.is_some_and(|e| clippy_utils::is_integer_const(cx, e, 0)) + }, + _ => false, + }, + ExprKind::Array([]) => true, + ExprKind::Call(def, []) => clippy_utils::is_path_diagnostic_item(cx, def, sym::default_fn), + _ => false, + } +} + +fn is_slice_from_ref(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + clippy_utils::is_expr_path_def_path(cx, expr, &["core", "slice", "raw", "from_ref"]) +} diff --git a/clippy_lints/src/manual_unwrap_or_default.rs b/clippy_lints/src/manual_unwrap_or_default.rs index 7b95399c907c..87d2faa225c5 100644 --- a/clippy_lints/src/manual_unwrap_or_default.rs +++ b/clippy_lints/src/manual_unwrap_or_default.rs @@ -9,8 +9,8 @@ use rustc_span::sym; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::higher::IfLetOrMatch; use clippy_utils::sugg::Sugg; -use clippy_utils::ty::implements_trait; -use clippy_utils::{is_default_equivalent, is_in_const_context, peel_blocks, span_contains_comment}; +use clippy_utils::ty::{expr_type_is_certain, implements_trait}; +use clippy_utils::{is_default_equivalent, is_in_const_context, path_res, peel_blocks, span_contains_comment}; declare_clippy_lint! { /// ### What it does @@ -158,6 +158,36 @@ fn handle<'tcx>(cx: &LateContext<'tcx>, if_let_or_match: IfLetOrMatch<'tcx>, exp } else { Applicability::MachineApplicable }; + + // We now check if the condition is a None variant, in which case we need to specify the type + if path_res(cx, condition) + .opt_def_id() + .is_some_and(|id| Some(cx.tcx.parent(id)) == cx.tcx.lang_items().option_none_variant()) + { + return span_lint_and_sugg( + cx, + MANUAL_UNWRAP_OR_DEFAULT, + expr.span, + format!("{expr_name} can be simplified with `.unwrap_or_default()`"), + "replace it with", + format!("{receiver}::<{expr_type}>.unwrap_or_default()"), + applicability, + ); + } + + // We check if the expression type is still uncertain, in which case we ask the user to specify it + if !expr_type_is_certain(cx, condition) { + return span_lint_and_sugg( + cx, + MANUAL_UNWRAP_OR_DEFAULT, + expr.span, + format!("{expr_name} can be simplified with `.unwrap_or_default()`"), + format!("ascribe the type {expr_type} and replace your expression with"), + format!("{receiver}.unwrap_or_default()"), + Applicability::Unspecified, + ); + } + span_lint_and_sugg( cx, MANUAL_UNWRAP_OR_DEFAULT, diff --git a/clippy_lints/src/matches/match_as_ref.rs b/clippy_lints/src/matches/match_as_ref.rs index b1889d26c932..1cb4b512a30e 100644 --- a/clippy_lints/src/matches/match_as_ref.rs +++ b/clippy_lints/src/matches/match_as_ref.rs @@ -1,8 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{is_res_lang_ctor, path_res, peel_blocks}; +use clippy_utils::{is_none_arm, is_res_lang_ctor, path_res, peel_blocks}; use rustc_errors::Applicability; -use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, LangItem, Mutability, PatExpr, PatExprKind, PatKind, QPath}; +use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath}; use rustc_lint::LateContext; use rustc_middle::ty; @@ -55,14 +55,6 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: } } -// Checks if arm has the form `None => None` -fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool { - matches!( - arm.pat.kind, - PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), .. }) if is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), LangItem::OptionNone) - ) -} - // Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`) fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option { if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 2f447775fa5b..f501cf060c2a 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -95,6 +95,7 @@ mod readonly_write_lock; mod redundant_as_str; mod repeat_once; mod result_map_or_else_none; +mod return_and_then; mod search_is_some; mod seek_from_current; mod seek_to_start_instead_of_rewind; @@ -3517,7 +3518,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.73.0"] pub FORMAT_COLLECT, - perf, + pedantic, "`format!`ing every element in a collection, then collecting the strings into a new `String`" } @@ -4365,7 +4366,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for string slices immediantly followed by `as_bytes`. + /// Checks for string slices immediately followed by `as_bytes`. /// /// ### Why is this bad? /// It involves doing an unnecessary UTF-8 alignment check which is less efficient, and can cause a panic. @@ -4391,6 +4392,46 @@ declare_clippy_lint! { "slicing a string and immediately calling as_bytes is less efficient and can lead to panics" } +declare_clippy_lint! { + /// ### What it does + /// + /// Detect functions that end with `Option::and_then` or `Result::and_then`, and suggest using a question mark (`?`) instead. + /// + /// ### Why is this bad? + /// + /// The `and_then` method is used to chain a computation that returns an `Option` or a `Result`. + /// This can be replaced with the `?` operator, which is more concise and idiomatic. + /// + /// ### Example + /// + /// ```no_run + /// fn test(opt: Option) -> Option { + /// opt.and_then(|n| { + /// if n > 1 { + /// Some(n + 1) + /// } else { + /// None + /// } + /// }) + /// } + /// ``` + /// Use instead: + /// ```no_run + /// fn test(opt: Option) -> Option { + /// let n = opt?; + /// if n > 1 { + /// Some(n + 1) + /// } else { + /// None + /// } + /// } + /// ``` + #[clippy::version = "1.86.0"] + pub RETURN_AND_THEN, + restriction, + "using `Option::and_then` or `Result::and_then` to chain a computation that returns an `Option` or a `Result`" +} + pub struct Methods { avoid_breaking_exported_api: bool, msrv: Msrv, @@ -4560,6 +4601,7 @@ impl_lint_pass!(Methods => [ USELESS_NONZERO_NEW_UNCHECKED, MANUAL_REPEAT_N, SLICED_STRING_AS_BYTES, + RETURN_AND_THEN, ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -4789,7 +4831,10 @@ impl Methods { let biom_option_linted = bind_instead_of_map::check_and_then_some(cx, expr, recv, arg); let biom_result_linted = bind_instead_of_map::check_and_then_ok(cx, expr, recv, arg); if !biom_option_linted && !biom_result_linted { - unnecessary_lazy_eval::check(cx, expr, recv, arg, "and"); + let ule_and_linted = unnecessary_lazy_eval::check(cx, expr, recv, arg, "and"); + if !ule_and_linted { + return_and_then::check(cx, expr, recv, arg); + } } }, ("any", [arg]) => { @@ -5003,7 +5048,9 @@ impl Methods { get_first::check(cx, expr, recv, arg); get_last_with_len::check(cx, expr, recv, arg); }, - ("get_or_insert_with", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"), + ("get_or_insert_with", [arg]) => { + unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"); + }, ("hash", [arg]) => { unit_hash::check(cx, expr, recv, arg); }, @@ -5144,7 +5191,9 @@ impl Methods { }, _ => iter_nth_zero::check(cx, expr, recv, n_arg), }, - ("ok_or_else", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"), + ("ok_or_else", [arg]) => { + unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"); + }, ("open", [_]) => { open_options::check(cx, expr, recv); }, @@ -5437,9 +5486,12 @@ impl ShouldImplTraitCase { fn lifetime_param_cond(&self, impl_item: &hir::ImplItem<'_>) -> bool { self.lint_explicit_lifetime || !impl_item.generics.params.iter().any(|p| { - matches!(p.kind, hir::GenericParamKind::Lifetime { - kind: hir::LifetimeParamKind::Explicit - }) + matches!( + p.kind, + hir::GenericParamKind::Lifetime { + kind: hir::LifetimeParamKind::Explicit + } + ) }) } } diff --git a/clippy_lints/src/methods/needless_option_take.rs b/clippy_lints/src/methods/needless_option_take.rs index c41ce2481d74..88b9c69f6f94 100644 --- a/clippy_lints/src/methods/needless_option_take.rs +++ b/clippy_lints/src/methods/needless_option_take.rs @@ -1,5 +1,6 @@ -use clippy_utils::diagnostics::span_lint_and_note; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::is_type_diagnostic_item; +use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::LateContext; use rustc_span::sym; @@ -10,13 +11,22 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &' // Checks if expression type is equal to sym::Option and if the expr is not a syntactic place if !recv.is_syntactic_place_expr() && is_expr_option(cx, recv) { if let Some(function_name) = source_of_temporary_value(recv) { - span_lint_and_note( + span_lint_and_then( cx, NEEDLESS_OPTION_TAKE, expr.span, "called `Option::take()` on a temporary value", - None, - format!("`{function_name}` creates a temporary value, so calling take() has no effect"), + |diag| { + diag.note(format!( + "`{function_name}` creates a temporary value, so calling take() has no effect" + )); + diag.span_suggestion( + expr.span.with_lo(recv.span.hi()), + "remove", + "", + Applicability::MachineApplicable, + ); + }, ); } } diff --git a/clippy_lints/src/methods/return_and_then.rs b/clippy_lints/src/methods/return_and_then.rs new file mode 100644 index 000000000000..7b1199ad1e2d --- /dev/null +++ b/clippy_lints/src/methods/return_and_then.rs @@ -0,0 +1,67 @@ +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, GenericArg, Ty}; +use rustc_span::sym; +use std::ops::ControlFlow; + +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability}; +use clippy_utils::ty::get_type_diagnostic_name; +use clippy_utils::visitors::for_each_unconsumed_temporary; +use clippy_utils::{is_expr_final_block_expr, peel_blocks}; + +use super::RETURN_AND_THEN; + +/// lint if `and_then` is the last expression in a block, and +/// there are no references or temporaries in the receiver +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &hir::Expr<'_>, + recv: &'tcx hir::Expr<'tcx>, + arg: &'tcx hir::Expr<'_>, +) { + if !is_expr_final_block_expr(cx.tcx, expr) { + return; + } + + let recv_type = cx.typeck_results().expr_ty(recv); + if !matches!(get_type_diagnostic_name(cx, recv_type), Some(sym::Option | sym::Result)) { + return; + } + + let has_ref_type = matches!(recv_type.kind(), ty::Adt(_, args) if args + .first() + .and_then(|arg0: &GenericArg<'tcx>| GenericArg::as_type(*arg0)) + .is_some_and(Ty::is_ref)); + let has_temporaries = for_each_unconsumed_temporary(cx, recv, |_| ControlFlow::Break(())).is_break(); + if has_ref_type && has_temporaries { + return; + } + + let hir::ExprKind::Closure(&hir::Closure { body, fn_decl, .. }) = arg.kind else { + return; + }; + + let closure_arg = fn_decl.inputs[0]; + let closure_expr = peel_blocks(cx.tcx.hir().body(body).value); + + let mut applicability = Applicability::MachineApplicable; + let arg_snip = snippet_with_applicability(cx, closure_arg.span, "_", &mut applicability); + let recv_snip = snippet_with_applicability(cx, recv.span, "_", &mut applicability); + let body_snip = snippet_with_applicability(cx, closure_expr.span, "..", &mut applicability); + let inner = match body_snip.strip_prefix('{').and_then(|s| s.strip_suffix('}')) { + Some(s) => s.trim_start_matches('\n').trim_end(), + None => &body_snip, + }; + + let msg = "use the question mark operator instead of an `and_then` call"; + let sugg = format!( + "let {} = {}?;\n{}", + arg_snip, + recv_snip, + reindent_multiline(inner.into(), false, indent_of(cx, expr.span)) + ); + + span_lint_and_sugg(cx, RETURN_AND_THEN, expr.span, msg, "try", sugg, applicability); +} diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index c27d1fb4903b..e7adf3b43ba5 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -123,32 +123,60 @@ pub(super) fn check( if let hir::ExprKind::Lit(lit) = init.kind { match lit.node { ast::LitKind::Bool(false) => { - check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Or, Replacement { - method_name: "any", - has_args: true, - has_generic_return: false, - }); + check_fold_with_op( + cx, + expr, + acc, + fold_span, + hir::BinOpKind::Or, + Replacement { + method_name: "any", + has_args: true, + has_generic_return: false, + }, + ); }, ast::LitKind::Bool(true) => { - check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, Replacement { - method_name: "all", - has_args: true, - has_generic_return: false, - }); + check_fold_with_op( + cx, + expr, + acc, + fold_span, + hir::BinOpKind::And, + Replacement { + method_name: "all", + has_args: true, + has_generic_return: false, + }, + ); }, ast::LitKind::Int(Pu128(0), _) => { - check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Add, Replacement { - method_name: "sum", - has_args: false, - has_generic_return: needs_turbofish(cx, expr), - }); + check_fold_with_op( + cx, + expr, + acc, + fold_span, + hir::BinOpKind::Add, + Replacement { + method_name: "sum", + has_args: false, + has_generic_return: needs_turbofish(cx, expr), + }, + ); }, ast::LitKind::Int(Pu128(1), _) => { - check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, Replacement { - method_name: "product", - has_args: false, - has_generic_return: needs_turbofish(cx, expr), - }); + check_fold_with_op( + cx, + expr, + acc, + fold_span, + hir::BinOpKind::Mul, + Replacement { + method_name: "product", + has_args: false, + has_generic_return: needs_turbofish(cx, expr), + }, + ); }, _ => (), } diff --git a/clippy_lints/src/methods/unnecessary_lazy_eval.rs b/clippy_lints/src/methods/unnecessary_lazy_eval.rs index 1673a6f8b3a4..7af550fa7c68 100644 --- a/clippy_lints/src/methods/unnecessary_lazy_eval.rs +++ b/clippy_lints/src/methods/unnecessary_lazy_eval.rs @@ -18,7 +18,7 @@ pub(super) fn check<'tcx>( recv: &'tcx hir::Expr<'_>, arg: &'tcx hir::Expr<'_>, simplify_using: &str, -) { +) -> bool { let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option); let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result); let is_bool = cx.typeck_results().expr_ty(recv).is_bool(); @@ -29,7 +29,7 @@ pub(super) fn check<'tcx>( let body_expr = &body.value; if usage::BindingUsageFinder::are_params_used(cx, body) || is_from_proc_macro(cx, expr) { - return; + return false; } if eager_or_lazy::switch_to_eager_eval(cx, body_expr) { @@ -71,8 +71,10 @@ pub(super) fn check<'tcx>( applicability, ); }); + return true; } } } } + false } diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index fa0eb9a94b73..fca416d9e64c 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -168,7 +168,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass { TOPLEVEL_REF_ARG, arg.hir_id, arg.pat.span, - "`ref` directly on a function argument is ignored. \ + "`ref` directly on a function parameter does not prevent taking ownership of the passed argument. \ Consider using a reference type instead", ); } diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 302db2c914ca..9acede4f32d6 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -152,16 +152,19 @@ fn collect_unsafe_exprs<'tcx>( ExprKind::AssignOp(_, lhs, rhs) | ExprKind::Assign(lhs, rhs, _) => { if matches!( lhs.kind, - ExprKind::Path(QPath::Resolved(_, hir::Path { - res: Res::Def( - DefKind::Static { - mutability: Mutability::Mut, - .. - }, - _ - ), - .. - })) + ExprKind::Path(QPath::Resolved( + _, + hir::Path { + res: Res::Def( + DefKind::Static { + mutability: Mutability::Mut, + .. + }, + _ + ), + .. + } + )) ) { unsafe_ops.push(("modification of a mutable static occurs here", expr.span)); collect_unsafe_exprs(cx, rhs, unsafe_ops); diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index 86c084423b71..49fd29d1dd6d 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -18,11 +18,14 @@ declare_clippy_lint! { /// /// On the other hand, `Mutex`es are, in general, easier to /// verify correctness. An atomic does not behave the same as - /// an equivalent mutex. See [this issue](https://github.com/rust-lang/rust-clippy/issues/4295)'s commentary for more details. + /// an equivalent mutex. See [this issue](https://github.com/rust-lang/rust-clippy/issues/4295)'s + /// commentary for more details. /// /// ### Known problems - /// This lint cannot detect if the mutex is actually used - /// for waiting before a critical section. + /// * This lint cannot detect if the mutex is actually used + /// for waiting before a critical section. + /// * This lint has a false positive that warns without considering the case + /// where `Mutex` is used together with `Condvar`. /// /// ### Example /// ```no_run @@ -48,14 +51,23 @@ declare_clippy_lint! { /// Checks for usage of `Mutex` where `X` is an integral /// type. /// - /// ### Why is this bad? + /// ### Why restrict this? /// Using a mutex just to make access to a plain integer /// sequential is /// shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster. /// + /// On the other hand, `Mutex`es are, in general, easier to + /// verify correctness. An atomic does not behave the same as + /// an equivalent mutex. See [this issue](https://github.com/rust-lang/rust-clippy/issues/4295)'s + /// commentary for more details. + /// /// ### Known problems - /// This lint cannot detect if the mutex is actually used - /// for waiting before a critical section. + /// * This lint cannot detect if the mutex is actually used + /// for waiting before a critical section. + /// * This lint has a false positive that warns without considering the case + /// where `Mutex` is used together with `Condvar`. + /// * This lint suggest using `AtomicU64` instead of `Mutex`, but + /// `AtomicU64` is not available on some 32-bit platforms. /// /// ### Example /// ```no_run @@ -70,7 +82,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "pre 1.29.0"] pub MUTEX_INTEGER, - nursery, + restriction, "using a mutex for an integer type" } @@ -108,7 +120,7 @@ fn get_atomic_name(ty: Ty<'_>) -> Option<&'static str> { UintTy::U32 => Some("AtomicU32"), UintTy::U64 => Some("AtomicU64"), UintTy::Usize => Some("AtomicUsize"), - // There's no `AtomicU128`. + // `AtomicU128` is unstable and only available on a few platforms: https://github.com/rust-lang/rust/issues/99069 UintTy::U128 => None, } }, @@ -119,7 +131,7 @@ fn get_atomic_name(ty: Ty<'_>) -> Option<&'static str> { IntTy::I32 => Some("AtomicI32"), IntTy::I64 => Some("AtomicI64"), IntTy::Isize => Some("AtomicIsize"), - // There's no `AtomicI128`. + // `AtomicU128` is unstable and only available on a few platforms: https://github.com/rust-lang/rust/issues/99069 IntTy::I128 => None, } }, diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 30846fb46ac1..2855703b9d56 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -181,9 +181,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { && !is_copy(cx, ty) && ty.is_sized(cx.tcx, cx.typing_env()) && !allowed_traits.iter().any(|&t| { - implements_trait_with_env_from_iter(cx.tcx, cx.typing_env(), ty, t, None, [None::< - ty::GenericArg<'tcx>, - >]) + implements_trait_with_env_from_iter( + cx.tcx, + cx.typing_env(), + ty, + t, + None, + [None::>], + ) }) && !implements_borrow_trait && !all_borrowable_trait diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index d9845bc3b0f7..9ad32c2bd396 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -265,9 +265,6 @@ declare_clippy_lint! { /// `x.trailing_zeros() >= 4` is much clearer than `x & 15 /// == 0` /// - /// ### Known problems - /// llvm generates better code for `x & 15 == 0` on x86 - /// /// ### Example /// ```no_run /// # let x = 1; diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index 421b2b747555..ec6835db897e 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -3,17 +3,14 @@ use clippy_utils::source::snippet_with_applicability; use rustc_ast::ast::BinOpKind::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub}; use rustc_ast::ast::{BinOpKind, Expr, ExprKind}; use rustc_errors::Applicability; -use rustc_lint::{EarlyContext, EarlyLintPass}; +use rustc_lint::{EarlyContext, EarlyLintPass, Lint}; use rustc_session::declare_lint_pass; use rustc_span::source_map::Spanned; declare_clippy_lint! { /// ### What it does - /// Checks for operations where precedence may be unclear - /// and suggests to add parentheses. Currently it catches the following: - /// * mixed usage of arithmetic and bit shifting/combining operators without - /// parentheses - /// * mixed usage of bitmasking and bit shifting operators without parentheses + /// Checks for operations where precedence may be unclear and suggests to add parentheses. + /// It catches a mixed usage of arithmetic and bit shifting/combining operators without parentheses /// /// ### Why is this bad? /// Not everyone knows the precedence of those operators by @@ -21,15 +18,32 @@ declare_clippy_lint! { /// code. /// /// ### Example - /// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7 - /// * `0x2345 & 0xF000 >> 12` equals 5, while `(0x2345 & 0xF000) >> 12` equals 2 + /// `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7 #[clippy::version = "pre 1.29.0"] pub PRECEDENCE, complexity, "operations where precedence may be unclear" } -declare_lint_pass!(Precedence => [PRECEDENCE]); +declare_clippy_lint! { + /// ### What it does + /// Checks for bit shifting operations combined with bit masking/combining operators + /// and suggest using parentheses. + /// + /// ### Why restrict this? + /// Not everyone knows the precedence of those operators by + /// heart, so expressions like these may trip others trying to reason about the + /// code. + /// + /// ### Example + /// `0x2345 & 0xF000 >> 12` equals 5, while `(0x2345 & 0xF000) >> 12` equals 2 + #[clippy::version = "1.86.0"] + pub PRECEDENCE_BITS, + restriction, + "operations mixing bit shifting with bit combining/masking" +} + +declare_lint_pass!(Precedence => [PRECEDENCE, PRECEDENCE_BITS]); impl EarlyLintPass for Precedence { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { @@ -38,10 +52,10 @@ impl EarlyLintPass for Precedence { } if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.kind { - let span_sugg = |expr: &Expr, sugg, appl| { + let span_sugg = |lint: &'static Lint, expr: &Expr, sugg, appl| { span_lint_and_sugg( cx, - PRECEDENCE, + lint, expr.span, "operator precedence might not be obvious", "consider parenthesizing your expression", @@ -57,37 +71,41 @@ impl EarlyLintPass for Precedence { match (op, get_bin_opt(left), get_bin_opt(right)) { ( BitAnd | BitOr | BitXor, - Some(Shl | Shr | Add | Div | Mul | Rem | Sub), - Some(Shl | Shr | Add | Div | Mul | Rem | Sub), + Some(left_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)), + Some(right_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)), ) - | (Shl | Shr, Some(Add | Div | Mul | Rem | Sub), Some(Add | Div | Mul | Rem | Sub)) => { + | ( + Shl | Shr, + Some(left_op @ (Add | Div | Mul | Rem | Sub)), + Some(right_op @ (Add | Div | Mul | Rem | Sub)), + ) => { let sugg = format!( "({}) {} ({})", snippet_with_applicability(cx, left.span, "..", &mut applicability), op.as_str(), snippet_with_applicability(cx, right.span, "..", &mut applicability) ); - span_sugg(expr, sugg, applicability); + span_sugg(lint_for(&[op, left_op, right_op]), expr, sugg, applicability); }, - (BitAnd | BitOr | BitXor, Some(Shl | Shr | Add | Div | Mul | Rem | Sub), _) - | (Shl | Shr, Some(Add | Div | Mul | Rem | Sub), _) => { + (BitAnd | BitOr | BitXor, Some(side_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)), _) + | (Shl | Shr, Some(side_op @ (Add | Div | Mul | Rem | Sub)), _) => { let sugg = format!( "({}) {} {}", snippet_with_applicability(cx, left.span, "..", &mut applicability), op.as_str(), snippet_with_applicability(cx, right.span, "..", &mut applicability) ); - span_sugg(expr, sugg, applicability); + span_sugg(lint_for(&[op, side_op]), expr, sugg, applicability); }, - (BitAnd | BitOr | BitXor, _, Some(Shl | Shr | Add | Div | Mul | Rem | Sub)) - | (Shl | Shr, _, Some(Add | Div | Mul | Rem | Sub)) => { + (BitAnd | BitOr | BitXor, _, Some(side_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub))) + | (Shl | Shr, _, Some(side_op @ (Add | Div | Mul | Rem | Sub))) => { let sugg = format!( "{} {} ({})", snippet_with_applicability(cx, left.span, "..", &mut applicability), op.as_str(), snippet_with_applicability(cx, right.span, "..", &mut applicability) ); - span_sugg(expr, sugg, applicability); + span_sugg(lint_for(&[op, side_op]), expr, sugg, applicability); }, _ => (), } @@ -106,3 +124,11 @@ fn get_bin_opt(expr: &Expr) -> Option { fn is_bit_op(op: BinOpKind) -> bool { matches!(op, BitXor | BitAnd | BitOr | Shl | Shr) } + +fn lint_for(ops: &[BinOpKind]) -> &'static Lint { + if ops.iter().all(|op| is_bit_op(*op)) { + PRECEDENCE_BITS + } else { + PRECEDENCE + } +} diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 506adf0f2cc5..0b67594a9b19 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -1,5 +1,6 @@ -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then}; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::source::SpanRangeExt; +use clippy_utils::sugg::Sugg; use clippy_utils::visitors::contains_unsafe_block; use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_id, path_to_local, std_or_core}; use hir::LifetimeName; @@ -250,15 +251,24 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { } fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if let ExprKind::Binary(ref op, l, r) = expr.kind { - if (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne) && (is_null_path(cx, l) || is_null_path(cx, r)) { - span_lint( - cx, - CMP_NULL, - expr.span, - "comparing with null is better expressed by the `.is_null()` method", - ); - } + if let ExprKind::Binary(op, l, r) = expr.kind + && (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne) + { + let non_null_path_snippet = match (is_null_path(cx, l), is_null_path(cx, r)) { + (true, false) if let Some(sugg) = Sugg::hir_opt(cx, r) => sugg.maybe_par(), + (false, true) if let Some(sugg) = Sugg::hir_opt(cx, l) => sugg.maybe_par(), + _ => return, + }; + + span_lint_and_sugg( + cx, + CMP_NULL, + expr.span, + "comparing with null is better expressed by the `.is_null()` method", + "try", + format!("{non_null_path_snippet}.is_null()"), + Applicability::MachineApplicable, + ); } else { check_invalid_ptr_usage(cx, expr); } diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index b9e0106fc86b..fb1bc494bd94 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -349,10 +349,14 @@ fn visit_clone_usage(cloned: mir::Local, clone: mir::Local, mir: &mir::Body<'_>, local_use_locs: _, local_consume_or_mutate_locs: clone_consume_or_mutate_locs, }, - )) = visit_local_usage(&[cloned, clone], mir, mir::Location { - block: bb, - statement_index: mir.basic_blocks[bb].statements.len(), - }) + )) = visit_local_usage( + &[cloned, clone], + mir, + mir::Location { + block: bb, + statement_index: mir.basic_blocks[bb].statements.len(), + }, + ) .map(|mut vec| (vec.remove(0), vec.remove(0))) { CloneUsage { diff --git a/clippy_lints/src/redundant_else.rs b/clippy_lints/src/redundant_else.rs index 3476f56cf338..a1b5a3aff323 100644 --- a/clippy_lints/src/redundant_else.rs +++ b/clippy_lints/src/redundant_else.rs @@ -1,8 +1,12 @@ -use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::{indent_of, reindent_multiline, snippet}; use rustc_ast::ast::{Block, Expr, ExprKind, Stmt, StmtKind}; use rustc_ast::visit::{Visitor, walk_expr}; +use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_session::declare_lint_pass; +use rustc_span::Span; +use std::borrow::Cow; declare_clippy_lint! { /// ### What it does @@ -75,13 +79,27 @@ impl EarlyLintPass for RedundantElse { _ => break, } } - span_lint_and_help( + + let mut app = Applicability::MachineApplicable; + if let ExprKind::Block(block, _) = &els.kind { + for stmt in &block.stmts { + // If the `else` block contains a local binding or a macro invocation, Clippy shouldn't auto-fix it + if matches!(&stmt.kind, StmtKind::Let(_) | StmtKind::MacCall(_)) { + app = Applicability::Unspecified; + break; + } + } + } + + // FIXME: The indentation of the suggestion would be the same as the one of the macro invocation in this implementation, see https://github.com/rust-lang/rust-clippy/pull/13936#issuecomment-2569548202 + span_lint_and_sugg( cx, REDUNDANT_ELSE, - els.span, + els.span.with_lo(then.span.hi()), "redundant else block", - None, "remove the `else` block and move the contents out", + make_sugg(cx, els.span, "..", Some(expr.span)).to_string(), + app, ); } } @@ -136,3 +154,23 @@ impl BreakVisitor { self.check(stmt, Self::visit_stmt) } } + +// Extract the inner contents of an `else` block str +// e.g. `{ foo(); bar(); }` -> `foo(); bar();` +fn extract_else_block(mut block: &str) -> String { + block = block.strip_prefix("{").unwrap_or(block); + block = block.strip_suffix("}").unwrap_or(block); + block.trim_end().to_string() +} + +fn make_sugg<'a>( + cx: &EarlyContext<'_>, + els_span: Span, + default: &'a str, + indent_relative_to: Option, +) -> Cow<'a, str> { + let extracted = extract_else_block(&snippet(cx, els_span, default)); + let indent = indent_relative_to.and_then(|s| indent_of(cx, s)); + + reindent_multiline(extracted.into(), false, indent) +} diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs index 8d31641d4836..29914d4379fe 100644 --- a/clippy_lints/src/same_name_method.rs +++ b/clippy_lints/src/same_name_method.rs @@ -62,10 +62,13 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { && let TyKind::Path(QPath::Resolved(_, Path { res, .. })) = self_ty.kind { if !map.contains_key(res) { - map.insert(*res, ExistingName { - impl_methods: BTreeMap::new(), - trait_methods: BTreeMap::new(), - }); + map.insert( + *res, + ExistingName { + impl_methods: BTreeMap::new(), + trait_methods: BTreeMap::new(), + }, + ); } let existing_name = map.get_mut(res).unwrap(); diff --git a/clippy_lints/src/size_of_in_element_count.rs b/clippy_lints/src/size_of_in_element_count.rs index f72ff10dd43c..b22c638fc363 100644 --- a/clippy_lints/src/size_of_in_element_count.rs +++ b/clippy_lints/src/size_of_in_element_count.rs @@ -63,8 +63,7 @@ fn get_pointee_ty_and_count_expr<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, ) -> Option<(Ty<'tcx>, &'tcx Expr<'tcx>)> { - const METHODS: [&str; 11] = [ - "write_bytes", + const METHODS: [&str; 10] = [ "copy_to", "copy_from", "copy_to_nonoverlapping", @@ -79,7 +78,7 @@ fn get_pointee_ty_and_count_expr<'tcx>( if let ExprKind::Call(func, [.., count]) = expr.kind // Find calls to ptr::{copy, copy_nonoverlapping} - // and ptr::{swap_nonoverlapping, write_bytes}, + // and ptr::swap_nonoverlapping, && let ExprKind::Path(ref func_qpath) = func.kind && let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id() && matches!(cx.tcx.get_diagnostic_name(def_id), Some( @@ -88,7 +87,6 @@ fn get_pointee_ty_and_count_expr<'tcx>( | sym::ptr_slice_from_raw_parts | sym::ptr_slice_from_raw_parts_mut | sym::ptr_swap_nonoverlapping - | sym::ptr_write_bytes | sym::slice_from_raw_parts | sym::slice_from_raw_parts_mut )) @@ -99,7 +97,7 @@ fn get_pointee_ty_and_count_expr<'tcx>( return Some((pointee_ty, count)); } if let ExprKind::MethodCall(method_path, ptr_self, [.., count], _) = expr.kind - // Find calls to copy_{from,to}{,_nonoverlapping} and write_bytes methods + // Find calls to copy_{from,to}{,_nonoverlapping} && let method_ident = method_path.ident.as_str() && METHODS.iter().any(|m| *m == method_ident) @@ -121,6 +119,8 @@ impl<'tcx> LateLintPass<'tcx> for SizeOfInElementCount { instead of a count of elements of `T`"; if let Some((pointee_ty, count_expr)) = get_pointee_ty_and_count_expr(cx, expr) + // Using a number of bytes for a byte type isn't suspicious + && pointee_ty != cx.tcx.types.u8 // Find calls to functions with an element count parameter and get // the pointee type and count parameter expression diff --git a/clippy_lints/src/to_digit_is_some.rs b/clippy_lints/src/to_digit_is_some.rs index 569812d81065..9993e6ae18b9 100644 --- a/clippy_lints/src/to_digit_is_some.rs +++ b/clippy_lints/src/to_digit_is_some.rs @@ -55,13 +55,11 @@ impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome { if let hir::ExprKind::Path(to_digits_path) = &to_digits_call.kind && let to_digits_call_res = cx.qpath_res(to_digits_path, to_digits_call.hir_id) && let Some(to_digits_def_id) = to_digits_call_res.opt_def_id() - && match_def_path(cx, to_digits_def_id, &[ - "core", - "char", - "methods", - "", - "to_digit", - ]) + && match_def_path( + cx, + to_digits_def_id, + &["core", "char", "methods", "", "to_digit"], + ) { Some((false, char_arg, radix_arg)) } else { diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 391c36df492c..579cbf447a2b 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -386,22 +386,30 @@ impl<'tcx> LateLintPass<'tcx> for Types { let is_exported = cx.effective_visibilities.is_exported(def_id); - self.check_fn_decl(cx, decl, CheckTyContext { - is_in_trait_impl, - in_body: matches!(fn_kind, FnKind::Closure), - is_exported, - ..CheckTyContext::default() - }); + self.check_fn_decl( + cx, + decl, + CheckTyContext { + is_in_trait_impl, + in_body: matches!(fn_kind, FnKind::Closure), + is_exported, + ..CheckTyContext::default() + }, + ); } fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id); match item.kind { - ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _, _) => self.check_ty(cx, ty, CheckTyContext { - is_exported, - ..CheckTyContext::default() - }), + ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _, _) => self.check_ty( + cx, + ty, + CheckTyContext { + is_exported, + ..CheckTyContext::default() + }, + ), // functions, enums, structs, impls and traits are covered _ => (), } @@ -419,10 +427,14 @@ impl<'tcx> LateLintPass<'tcx> for Types { false }; - self.check_ty(cx, ty, CheckTyContext { - is_in_trait_impl, - ..CheckTyContext::default() - }); + self.check_ty( + cx, + ty, + CheckTyContext { + is_in_trait_impl, + ..CheckTyContext::default() + }, + ); }, // Methods are covered by check_fn. // Type aliases are ignored because oftentimes it's impossible to @@ -438,10 +450,14 @@ impl<'tcx> LateLintPass<'tcx> for Types { let is_exported = cx.effective_visibilities.is_exported(field.def_id); - self.check_ty(cx, field.ty, CheckTyContext { - is_exported, - ..CheckTyContext::default() - }); + self.check_ty( + cx, + field.ty, + CheckTyContext { + is_exported, + ..CheckTyContext::default() + }, + ); } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'tcx>) { @@ -469,10 +485,14 @@ impl<'tcx> LateLintPass<'tcx> for Types { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) { if let Some(ty) = local.ty { - self.check_ty(cx, ty, CheckTyContext { - in_body: true, - ..CheckTyContext::default() - }); + self.check_ty( + cx, + ty, + CheckTyContext { + in_body: true, + ..CheckTyContext::default() + }, + ); } } } diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs index 3fc08e8192d4..207f2ef4563a 100644 --- a/clippy_lints/src/unconditional_recursion.rs +++ b/clippy_lints/src/unconditional_recursion.rs @@ -257,10 +257,13 @@ fn is_default_method_on_current_ty<'tcx>(tcx: TyCtxt<'tcx>, qpath: QPath<'tcx>, } if matches!( ty.kind, - TyKind::Path(QPath::Resolved(_, hir::Path { - res: Res::SelfTyAlias { .. }, - .. - },)) + TyKind::Path(QPath::Resolved( + _, + hir::Path { + res: Res::SelfTyAlias { .. }, + .. + }, + )) ) { return true; } diff --git a/clippy_lints/src/unnecessary_semicolon.rs b/clippy_lints/src/unnecessary_semicolon.rs index efbc536dcb4d..e5267620c4fb 100644 --- a/clippy_lints/src/unnecessary_semicolon.rs +++ b/clippy_lints/src/unnecessary_semicolon.rs @@ -37,7 +37,7 @@ declare_clippy_lint! { #[derive(Default)] pub struct UnnecessarySemicolon { - last_statements: Vec, + last_statements: Vec<(HirId, bool)>, } impl_lint_pass!(UnnecessarySemicolon => [UNNECESSARY_SEMICOLON]); @@ -45,27 +45,25 @@ impl_lint_pass!(UnnecessarySemicolon => [UNNECESSARY_SEMICOLON]); impl UnnecessarySemicolon { /// Enter or leave a block, remembering the last statement of the block. fn handle_block(&mut self, cx: &LateContext<'_>, block: &Block<'_>, enter: bool) { - // Up to edition 2021, removing the semicolon of the last statement of a block - // may result in the scrutinee temporary values to live longer than the block - // variables. To avoid this problem, we do not lint the last statement of an - // expressionless block. - if cx.tcx.sess.edition() <= Edition2021 - && block.expr.is_none() + // The last statement of an expressionless block deserves a special treatment. + if block.expr.is_none() && let Some(last_stmt) = block.stmts.last() { if enter { - self.last_statements.push(last_stmt.hir_id); + let block_ty = cx.typeck_results().node_type(block.hir_id); + self.last_statements.push((last_stmt.hir_id, block_ty.is_unit())); } else { self.last_statements.pop(); } } } - /// Checks if `stmt` is the last statement in an expressionless block for edition ≤ 2021. - fn is_last_in_block(&self, stmt: &Stmt<'_>) -> bool { + /// Checks if `stmt` is the last statement in an expressionless block. In this case, + /// return `Some` with a boolean which is `true` if the block type is `()`. + fn is_last_in_block(&self, stmt: &Stmt<'_>) -> Option { self.last_statements .last() - .is_some_and(|last_stmt_id| last_stmt_id == &stmt.hir_id) + .and_then(|&(stmt_id, is_unit)| (stmt_id == stmt.hir_id).then_some(is_unit)) } } @@ -90,8 +88,22 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessarySemicolon { ) && cx.typeck_results().expr_ty(expr) == cx.tcx.types.unit { - if self.is_last_in_block(stmt) && leaks_droppable_temporary_with_limited_lifetime(cx, expr) { - return; + if let Some(block_is_unit) = self.is_last_in_block(stmt) { + if cx.tcx.sess.edition() <= Edition2021 && leaks_droppable_temporary_with_limited_lifetime(cx, expr) { + // The expression contains temporaries with limited lifetimes in edition lower than 2024. Those may + // survive until after the end of the current scope instead of until the end of the statement, so do + // not lint this situation. + return; + } + + if !block_is_unit { + // Although the expression returns `()`, the block doesn't. This may happen if the expression + // returns early in all code paths, such as a `return value` in the condition of an `if` statement, + // in which case the block type would be `!`. Do not lint in this case, as the statement would + // become the block expression; the block type would become `()` and this may not type correctly + // if the expected type for the block is not `()`. + return; + } } let semi_span = expr.span.shrink_to_hi().to(stmt.span.shrink_to_hi()); diff --git a/clippy_lints/src/unneeded_struct_pattern.rs b/clippy_lints/src/unneeded_struct_pattern.rs index 40ba70d451db..a74eab8b6ae5 100644 --- a/clippy_lints/src/unneeded_struct_pattern.rs +++ b/clippy_lints/src/unneeded_struct_pattern.rs @@ -32,7 +32,7 @@ declare_clippy_lint! { /// None => 0, /// }; /// ``` - #[clippy::version = "1.83.0"] + #[clippy::version = "1.86.0"] pub UNNEEDED_STRUCT_PATTERN, style, "using struct pattern to match against unit variant" diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 31ae002e47d9..11c14c147776 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -522,7 +522,7 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) { let replacement = match (format_string_is_raw, replace_raw) { (false, false) => Some(replacement), - (false, true) => Some(replacement.replace('"', "\\\"").replace('\\', "\\\\")), + (false, true) => Some(replacement.replace('\\', "\\\\").replace('"', "\\\"")), (true, false) => match conservative_unescape(&replacement) { Ok(unescaped) => Some(unescaped), Err(UnescapeErr::Lint) => None, diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 251e3dfe41be..41f3b1cbd507 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-01-28 +nightly-2025-02-06 ``` diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index 798f4575c2e1..ab5f97199ce3 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -662,12 +662,12 @@ pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool { && eq_ext(&l.ext, &r.ext) } +#[expect(clippy::ref_option, reason = "This is the type how it is stored in the AST")] pub fn eq_opt_fn_contract(l: &Option>, r: &Option>) -> bool { match (l, r) { (Some(l), Some(r)) => { - eq_expr_opt(l.requires.as_ref(), r.requires.as_ref()) - && eq_expr_opt(l.ensures.as_ref(), r.ensures.as_ref()) - } + eq_expr_opt(l.requires.as_ref(), r.requires.as_ref()) && eq_expr_opt(l.ensures.as_ref(), r.ensures.as_ref()) + }, (None, None) => true, (Some(_), None) | (None, Some(_)) => false, } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 5a5227af9074..337684b68f86 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -341,6 +341,15 @@ pub fn is_wild(pat: &Pat<'_>) -> bool { matches!(pat.kind, PatKind::Wild) } +// Checks if arm has the form `None => None` +pub fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool { + matches!( + arm.pat.kind, + PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), .. }) + if is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone) + ) +} + /// Checks if the given `QPath` belongs to a type alias. pub fn is_ty_alias(qpath: &QPath<'_>) -> bool { match *qpath { diff --git a/clippy_utils/src/mir/mod.rs b/clippy_utils/src/mir/mod.rs index ccbbccd0dbff..85250f81dc47 100644 --- a/clippy_utils/src/mir/mod.rs +++ b/clippy_utils/src/mir/mod.rs @@ -112,10 +112,14 @@ pub fn block_in_cycle(body: &Body<'_>, block: BasicBlock) -> bool { /// Convenience wrapper around `visit_local_usage`. pub fn used_exactly_once(mir: &Body<'_>, local: Local) -> Option { - visit_local_usage(&[local], mir, Location { - block: START_BLOCK, - statement_index: 0, - }) + visit_local_usage( + &[local], + mir, + Location { + block: START_BLOCK, + statement_index: 0, + }, + ) .map(|mut vec| { let LocalUsage { local_use_locs, .. } = vec.remove(0); let mut locations = local_use_locs diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index d73cb7e35611..24f73b9df268 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -1,4 +1,5 @@ use rustc_ast::attr::AttributeExt; + use rustc_attr_parsing::{RustcVersion, parse_version}; use rustc_session::Session; use rustc_span::{Symbol, sym}; @@ -18,12 +19,14 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { + 1,84,0 { CONST_OPTION_AS_SLICE } 1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP } 1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP } 1,81,0 { LINT_REASONS_STABILIZATION, ERROR_IN_CORE, EXPLICIT_SELF_TYPE_ELISION } 1,80,0 { BOX_INTO_ITER, LAZY_CELL } 1,77,0 { C_STR_LITERALS } 1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT } + 1,75,0 { OPTION_AS_SLICE } 1,74,0 { REPR_RUST } 1,73,0 { MANUAL_DIV_CEIL } 1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE } @@ -40,7 +43,7 @@ msrv_aliases! { 1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR } 1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST } 1,51,0 { BORROW_AS_PTR, SEEK_FROM_CURRENT, UNSIGNED_ABS } - 1,50,0 { BOOL_THEN, CLAMP } + 1,50,0 { BOOL_THEN, CLAMP, SLICE_FILL } 1,47,0 { TAU, IS_ASCII_DIGIT_CONST, ARRAY_IMPL_ANY_LEN, SATURATING_SUB_CONST } 1,46,0 { CONST_IF_MATCH } 1,45,0 { STR_STRIP_PREFIX } diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 5a3a3d0cedc4..c7890f33f27e 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -179,7 +179,10 @@ fn check_rvalue<'tcx>( )) } }, - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, _) + Rvalue::NullaryOp( + NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, + _, + ) | Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, tcx); diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index eecbfb3936ac..b8b800b93cea 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -726,12 +726,15 @@ pub fn str_literal_to_char_literal( &snip[1..(snip.len() - 1)] }; - let hint = format!("'{}'", match ch { - "'" => "\\'", - r"\" => "\\\\", - "\\\"" => "\"", // no need to escape `"` in `'"'` - _ => ch, - }); + let hint = format!( + "'{}'", + match ch { + "'" => "\\'", + r"\" => "\\\\", + "\\\"" => "\"", // no need to escape `"` in `'"'` + _ => ch, + } + ); Some(hint) } else { diff --git a/clippy_utils/src/str_utils.rs b/clippy_utils/src/str_utils.rs index 1588ee452dae..421b25a77fe8 100644 --- a/clippy_utils/src/str_utils.rs +++ b/clippy_utils/src/str_utils.rs @@ -370,11 +370,9 @@ mod test { assert_eq!(camel_case_split("AbcDef"), vec!["Abc", "Def"]); assert_eq!(camel_case_split("Abc"), vec!["Abc"]); assert_eq!(camel_case_split("abcDef"), vec!["abc", "Def"]); - assert_eq!(camel_case_split("\u{f6}\u{f6}AabABcd"), vec![ - "\u{f6}\u{f6}", - "Aab", - "A", - "Bcd" - ]); + assert_eq!( + camel_case_split("\u{f6}\u{f6}AabABcd"), + vec!["\u{f6}\u{f6}", "Aab", "A", "Bcd"] + ); } } diff --git a/lintcheck/src/config.rs b/lintcheck/src/config.rs index af243f94274d..83c3d7aba021 100644 --- a/lintcheck/src/config.rs +++ b/lintcheck/src/config.rs @@ -2,6 +2,7 @@ use clap::{Parser, Subcommand, ValueEnum}; use std::num::NonZero; use std::path::PathBuf; +#[allow(clippy::struct_excessive_bools)] #[derive(Parser, Clone, Debug)] #[command(args_conflicts_with_subcommands = true)] pub(crate) struct LintcheckConfig { @@ -11,6 +12,9 @@ pub(crate) struct LintcheckConfig { short = 'j', value_name = "N", default_value_t = 0, + default_value_if("perf", "true", Some("1")), // Limit jobs to 1 when benchmarking + conflicts_with("perf"), + required = false, hide_default_value = true )] pub max_jobs: usize, @@ -46,6 +50,11 @@ pub(crate) struct LintcheckConfig { /// Run clippy on the dependencies of crates specified in crates-toml #[clap(long, conflicts_with("max_jobs"))] pub recursive: bool, + /// Also produce a `perf.data` file, implies --jobs=1, + /// the `perf.data` file can be found at + /// `target/lintcheck/sources/-/perf.data` + #[clap(long)] + pub perf: bool, #[command(subcommand)] pub subcommand: Option, } diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index e88d9f427bec..8d0d41ab9450 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -116,7 +116,25 @@ impl Crate { clippy_args.extend(lint_levels_args.iter().map(String::as_str)); - let mut cmd = Command::new("cargo"); + let mut cmd; + + if config.perf { + cmd = Command::new("perf"); + cmd.args(&[ + "record", + "-e", + "instructions", // Only count instructions + "-g", // Enable call-graph, useful for flamegraphs and produces richer reports + "--quiet", // Do not tamper with lintcheck's normal output + "-o", + "perf.data", + "--", + "cargo", + ]); + } else { + cmd = Command::new("cargo"); + } + cmd.arg(if config.fix { "fix" } else { "check" }) .arg("--quiet") .current_dir(&self.path) @@ -234,12 +252,22 @@ fn normalize_diag( } /// Builds clippy inside the repo to make sure we have a clippy executable we can use. -fn build_clippy() -> String { - let output = Command::new("cargo") - .args(["run", "--bin=clippy-driver", "--", "--version"]) - .stderr(Stdio::inherit()) - .output() - .unwrap(); +fn build_clippy(release_build: bool) -> String { + let mut build_cmd = Command::new("cargo"); + build_cmd.args([ + "run", + "--bin=clippy-driver", + if release_build { "-r" } else { "" }, + "--", + "--version", + ]); + + if release_build { + build_cmd.env("CARGO_PROFILE_RELEASE_DEBUG", "true"); + } + + let output = build_cmd.stderr(Stdio::inherit()).output().unwrap(); + if !output.status.success() { eprintln!("Error: Failed to compile Clippy!"); std::process::exit(1); @@ -270,13 +298,18 @@ fn main() { #[allow(clippy::too_many_lines)] fn lintcheck(config: LintcheckConfig) { - let clippy_ver = build_clippy(); - let clippy_driver_path = fs::canonicalize(format!("target/debug/clippy-driver{EXE_SUFFIX}")).unwrap(); + let clippy_ver = build_clippy(config.perf); + let clippy_driver_path = fs::canonicalize(format!( + "target/{}/clippy-driver{EXE_SUFFIX}", + if config.perf { "release" } else { "debug" } + )) + .unwrap(); // assert that clippy is found assert!( clippy_driver_path.is_file(), - "target/debug/clippy-driver binary not found! {}", + "target/{}/clippy-driver binary not found! {}", + if config.perf { "release" } else { "debug" }, clippy_driver_path.display() ); diff --git a/rust-toolchain b/rust-toolchain index c15d1fe6cd34..ab760287e83a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-01-28" +channel = "nightly-2025-02-06" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" diff --git a/tests/ui/cmp_null.fixed b/tests/ui/cmp_null.fixed new file mode 100644 index 000000000000..e5ab765bc861 --- /dev/null +++ b/tests/ui/cmp_null.fixed @@ -0,0 +1,32 @@ +#![warn(clippy::cmp_null)] +#![allow(unused_mut)] + +use std::ptr; + +fn main() { + let x = 0; + let p: *const usize = &x; + if p.is_null() { + //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + //~| NOTE: `-D clippy::cmp-null` implied by `-D warnings` + println!("This is surprising!"); + } + if p.is_null() { + //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + println!("This is surprising!"); + } + + let mut y = 0; + let mut m: *mut usize = &mut y; + if m.is_null() { + //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + println!("This is surprising, too!"); + } + if m.is_null() { + //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + println!("This is surprising, too!"); + } + + let _ = (x as *const ()).is_null(); + //~^ ERROR: comparing with null is better expressed by the `.is_null()` method +} diff --git a/tests/ui/cmp_null.rs b/tests/ui/cmp_null.rs index ef1d93940aa6..257f7ba26627 100644 --- a/tests/ui/cmp_null.rs +++ b/tests/ui/cmp_null.rs @@ -11,10 +11,22 @@ fn main() { //~| NOTE: `-D clippy::cmp-null` implied by `-D warnings` println!("This is surprising!"); } + if ptr::null() == p { + //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + println!("This is surprising!"); + } + let mut y = 0; let mut m: *mut usize = &mut y; if m == ptr::null_mut() { //~^ ERROR: comparing with null is better expressed by the `.is_null()` method println!("This is surprising, too!"); } + if ptr::null_mut() == m { + //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + println!("This is surprising, too!"); + } + + let _ = x as *const () == ptr::null(); + //~^ ERROR: comparing with null is better expressed by the `.is_null()` method } diff --git a/tests/ui/cmp_null.stderr b/tests/ui/cmp_null.stderr index 8362904a5ba9..f3b35f3afba8 100644 --- a/tests/ui/cmp_null.stderr +++ b/tests/ui/cmp_null.stderr @@ -2,16 +2,34 @@ error: comparing with null is better expressed by the `.is_null()` method --> tests/ui/cmp_null.rs:9:8 | LL | if p == ptr::null() { - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: try: `p.is_null()` | = note: `-D clippy::cmp-null` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cmp_null)]` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:16:8 + --> tests/ui/cmp_null.rs:14:8 + | +LL | if ptr::null() == p { + | ^^^^^^^^^^^^^^^^ help: try: `p.is_null()` + +error: comparing with null is better expressed by the `.is_null()` method + --> tests/ui/cmp_null.rs:21:8 | LL | if m == ptr::null_mut() { - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()` -error: aborting due to 2 previous errors +error: comparing with null is better expressed by the `.is_null()` method + --> tests/ui/cmp_null.rs:25:8 + | +LL | if ptr::null_mut() == m { + | ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()` + +error: comparing with null is better expressed by the `.is_null()` method + --> tests/ui/cmp_null.rs:30:13 + | +LL | let _ = x as *const () == ptr::null(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(x as *const ()).is_null()` + +error: aborting due to 5 previous errors diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed index f1baf28200e9..abccc30ef87d 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -116,6 +116,11 @@ fn test_redundant_closures_containing_method_calls() { t.iter().filter(|x| x.trait_foo_ref()); t.iter().map(|x| x.trait_foo_ref()); } + + fn issue14096() { + let x = Some("42"); + let _ = x.map(str::parse::); + } } struct Thunk(Box T>); diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index c52a51880bfc..9bcee4eba340 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -116,6 +116,11 @@ fn test_redundant_closures_containing_method_calls() { t.iter().filter(|x| x.trait_foo_ref()); t.iter().map(|x| x.trait_foo_ref()); } + + fn issue14096() { + let x = Some("42"); + let _ = x.map(|x| x.parse::()); + } } struct Thunk(Box T>); diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index 1731a4377f53..ac58e87bc5ec 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -71,142 +71,148 @@ LL | let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_as | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase` error: redundant closure - --> tests/ui/eta.rs:169:22 + --> tests/ui/eta.rs:122:23 + | +LL | let _ = x.map(|x| x.parse::()); + | ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `str::parse::` + +error: redundant closure + --> tests/ui/eta.rs:174:22 | LL | requires_fn_once(|| x()); | ^^^^^^ help: replace the closure with the function itself: `x` error: redundant closure - --> tests/ui/eta.rs:176:27 + --> tests/ui/eta.rs:181:27 | LL | let a = Some(1u8).map(|a| foo_ptr(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr` error: redundant closure - --> tests/ui/eta.rs:181:27 + --> tests/ui/eta.rs:186:27 | LL | let a = Some(1u8).map(|a| closure(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure` error: redundant closure - --> tests/ui/eta.rs:213:28 + --> tests/ui/eta.rs:218:28 | LL | x.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> tests/ui/eta.rs:214:28 + --> tests/ui/eta.rs:219:28 | LL | y.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> tests/ui/eta.rs:215:28 + --> tests/ui/eta.rs:220:28 | LL | z.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res` error: redundant closure - --> tests/ui/eta.rs:222:21 + --> tests/ui/eta.rs:227:21 | LL | Some(1).map(|n| closure(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure` error: redundant closure - --> tests/ui/eta.rs:226:21 + --> tests/ui/eta.rs:231:21 | LL | Some(1).map(|n| in_loop(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop` error: redundant closure - --> tests/ui/eta.rs:319:18 + --> tests/ui/eta.rs:324:18 | LL | takes_fn_mut(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> tests/ui/eta.rs:322:19 + --> tests/ui/eta.rs:327:19 | LL | takes_fn_once(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> tests/ui/eta.rs:326:26 + --> tests/ui/eta.rs:331:26 | LL | move || takes_fn_mut(|| f_used_once()) | ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once` error: redundant closure - --> tests/ui/eta.rs:338:19 + --> tests/ui/eta.rs:343:19 | LL | array_opt.map(|a| a.as_slice()); | ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice` error: redundant closure - --> tests/ui/eta.rs:341:19 + --> tests/ui/eta.rs:346:19 | LL | slice_opt.map(|s| s.len()); | ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len` error: redundant closure - --> tests/ui/eta.rs:344:17 + --> tests/ui/eta.rs:349:17 | LL | ptr_opt.map(|p| p.is_null()); | ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null` error: redundant closure - --> tests/ui/eta.rs:348:17 + --> tests/ui/eta.rs:353:17 | LL | dyn_opt.map(|d| d.method_on_dyn()); | ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `::method_on_dyn` error: redundant closure - --> tests/ui/eta.rs:408:19 + --> tests/ui/eta.rs:413:19 | LL | let _ = f(&0, |x, y| f2(x, y)); | ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2` error: redundant closure - --> tests/ui/eta.rs:436:22 + --> tests/ui/eta.rs:441:22 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Test::method` error: redundant closure - --> tests/ui/eta.rs:440:22 + --> tests/ui/eta.rs:445:22 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `super::Outer::method` error: redundant closure - --> tests/ui/eta.rs:453:18 + --> tests/ui/eta.rs:458:18 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `test_mod::Test::method` error: redundant closure - --> tests/ui/eta.rs:460:30 + --> tests/ui/eta.rs:465:30 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method` error: redundant closure - --> tests/ui/eta.rs:479:38 + --> tests/ui/eta.rs:484:38 | LL | let x = Box::new(|| None.map(|x| f(x))); | ^^^^^^^^ help: replace the closure with the function itself: `&f` error: redundant closure - --> tests/ui/eta.rs:483:38 + --> tests/ui/eta.rs:488:38 | LL | let x = Box::new(|| None.map(|x| f(x))); | ^^^^^^^^ help: replace the closure with the function itself: `f` error: redundant closure - --> tests/ui/eta.rs:500:35 + --> tests/ui/eta.rs:505:35 | LL | let _field = bind.or_else(|| get_default()).unwrap(); | ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default` -error: aborting due to 34 previous errors +error: aborting due to 35 previous errors diff --git a/tests/ui/ignored_unit_patterns.fixed b/tests/ui/ignored_unit_patterns.fixed index fde404373098..118f0b488952 100644 --- a/tests/ui/ignored_unit_patterns.fixed +++ b/tests/ui/ignored_unit_patterns.fixed @@ -21,12 +21,15 @@ fn main() { let _ = foo().map_err(|()| todo!()); //~^ ERROR: matching over `()` is more explicit - println!("{:?}", match foo() { - Ok(()) => {}, - //~^ ERROR: matching over `()` is more explicit - Err(()) => {}, - //~^ ERROR: matching over `()` is more explicit - }); + println!( + "{:?}", + match foo() { + Ok(()) => {}, + //~^ ERROR: matching over `()` is more explicit + Err(()) => {}, + //~^ ERROR: matching over `()` is more explicit + } + ); } // ignored_unit_patterns in derive macro should be ok diff --git a/tests/ui/ignored_unit_patterns.rs b/tests/ui/ignored_unit_patterns.rs index 528844d76e05..92feb9e6c281 100644 --- a/tests/ui/ignored_unit_patterns.rs +++ b/tests/ui/ignored_unit_patterns.rs @@ -21,12 +21,15 @@ fn main() { let _ = foo().map_err(|_| todo!()); //~^ ERROR: matching over `()` is more explicit - println!("{:?}", match foo() { - Ok(_) => {}, - //~^ ERROR: matching over `()` is more explicit - Err(_) => {}, - //~^ ERROR: matching over `()` is more explicit - }); + println!( + "{:?}", + match foo() { + Ok(_) => {}, + //~^ ERROR: matching over `()` is more explicit + Err(_) => {}, + //~^ ERROR: matching over `()` is more explicit + } + ); } // ignored_unit_patterns in derive macro should be ok diff --git a/tests/ui/ignored_unit_patterns.stderr b/tests/ui/ignored_unit_patterns.stderr index 54ff4454d6bd..00a254e39192 100644 --- a/tests/ui/ignored_unit_patterns.stderr +++ b/tests/ui/ignored_unit_patterns.stderr @@ -26,31 +26,31 @@ LL | let _ = foo().map_err(|_| todo!()); | ^ help: use `()` instead of `_`: `()` error: matching over `()` is more explicit - --> tests/ui/ignored_unit_patterns.rs:25:12 + --> tests/ui/ignored_unit_patterns.rs:27:16 | -LL | Ok(_) => {}, - | ^ help: use `()` instead of `_`: `()` +LL | Ok(_) => {}, + | ^ help: use `()` instead of `_`: `()` error: matching over `()` is more explicit - --> tests/ui/ignored_unit_patterns.rs:27:13 + --> tests/ui/ignored_unit_patterns.rs:29:17 | -LL | Err(_) => {}, - | ^ help: use `()` instead of `_`: `()` +LL | Err(_) => {}, + | ^ help: use `()` instead of `_`: `()` error: matching over `()` is more explicit - --> tests/ui/ignored_unit_patterns.rs:38:9 + --> tests/ui/ignored_unit_patterns.rs:41:9 | LL | let _ = foo().unwrap(); | ^ help: use `()` instead of `_`: `()` error: matching over `()` is more explicit - --> tests/ui/ignored_unit_patterns.rs:47:13 + --> tests/ui/ignored_unit_patterns.rs:50:13 | LL | (1, _) => unimplemented!(), | ^ help: use `()` instead of `_`: `()` error: matching over `()` is more explicit - --> tests/ui/ignored_unit_patterns.rs:54:13 + --> tests/ui/ignored_unit_patterns.rs:57:13 | LL | for (x, _) in v { | ^ help: use `()` instead of `_`: `()` diff --git a/tests/ui/manual_memcpy/without_loop_counters.rs b/tests/ui/manual_memcpy/without_loop_counters.rs index c917fa7f2d0b..2f8640cd3f50 100644 --- a/tests/ui/manual_memcpy/without_loop_counters.rs +++ b/tests/ui/manual_memcpy/without_loop_counters.rs @@ -1,5 +1,10 @@ #![warn(clippy::manual_memcpy)] -#![allow(clippy::assigning_clones, clippy::useless_vec, clippy::needless_range_loop)] +#![allow( + clippy::assigning_clones, + clippy::useless_vec, + clippy::needless_range_loop, + clippy::manual_slice_fill +)] //@no-rustfix const LOOP_OFFSET: usize = 5000; diff --git a/tests/ui/manual_memcpy/without_loop_counters.stderr b/tests/ui/manual_memcpy/without_loop_counters.stderr index 803053b2db2e..c881e3fac769 100644 --- a/tests/ui/manual_memcpy/without_loop_counters.stderr +++ b/tests/ui/manual_memcpy/without_loop_counters.stderr @@ -1,5 +1,5 @@ error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:9:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:14:5 | LL | / for i in 0..src.len() { LL | | @@ -12,7 +12,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:16:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:21:5 | LL | / for i in 0..src.len() { LL | | @@ -21,7 +21,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[10..(src.len() + 10)].copy_from_slice(&src[..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:22:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:27:5 | LL | / for i in 0..src.len() { LL | | @@ -30,7 +30,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:28:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:33:5 | LL | / for i in 11..src.len() { LL | | @@ -39,7 +39,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:34:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:39:5 | LL | / for i in 0..dst.len() { LL | | @@ -48,7 +48,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..dst.len()]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:48:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:53:5 | LL | / for i in 10..256 { LL | | @@ -64,7 +64,7 @@ LL + dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]); | error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:61:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:66:5 | LL | / for i in 10..LOOP_OFFSET { LL | | @@ -73,7 +73,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:75:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:80:5 | LL | / for i in 0..src_vec.len() { LL | | @@ -82,7 +82,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:105:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:110:5 | LL | / for i in from..from + src.len() { LL | | @@ -91,7 +91,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:110:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:115:5 | LL | / for i in from..from + 3 { LL | | @@ -100,7 +100,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:116:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:121:5 | LL | / for i in 0..5 { LL | | @@ -109,7 +109,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:122:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:127:5 | LL | / for i in 0..0 { LL | | @@ -118,7 +118,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..0].copy_from_slice(&src[..0]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:146:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:151:5 | LL | / for i in 0..4 { LL | | @@ -127,7 +127,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..4]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:152:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:157:5 | LL | / for i in 0..5 { LL | | @@ -136,7 +136,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:158:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:163:5 | LL | / for i in 0..5 { LL | | @@ -145,7 +145,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:205:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:210:5 | LL | / for i in 0..5 { LL | | @@ -154,7 +154,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:211:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:216:5 | LL | / for i in 0..5 { LL | | @@ -163,7 +163,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0][1]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:219:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:224:5 | LL | / for i in 0..src.len() { LL | | diff --git a/tests/ui/manual_option_as_slice.fixed b/tests/ui/manual_option_as_slice.fixed new file mode 100644 index 000000000000..48337d7654de --- /dev/null +++ b/tests/ui/manual_option_as_slice.fixed @@ -0,0 +1,62 @@ +#![warn(clippy::manual_option_as_slice)] +#![allow(clippy::redundant_closure, clippy::unwrap_or_default)] + +fn check(x: Option) { + _ = x.as_slice(); + + _ = x.as_slice(); + + _ = x.as_slice(); + //~^ manual_option_as_slice + + _ = x.as_slice(); + //~^ manual_option_as_slice + + _ = x.as_slice(); + //~^ manual_option_as_slice + + _ = x.as_slice(); + //~^ manual_option_as_slice + + { + use std::slice::from_ref; + _ = x.as_slice(); + //~^ manual_option_as_slice + } + + // possible false positives + let y = x.as_ref(); + _ = match y { + // as_ref outside + Some(f) => &[f][..], + None => &[][..], + }; + _ = match x.as_ref() { + Some(f) => std::slice::from_ref(f), + None => &[0], + }; + _ = match x.as_ref() { + Some(42) => &[23], + Some(f) => std::slice::from_ref(f), + None => &[], + }; + let b = &[42]; + _ = if let Some(_f) = x.as_ref() { + std::slice::from_ref(b) + } else { + &[] + }; + _ = x.as_ref().map_or(&[42][..], std::slice::from_ref); + _ = x.as_ref().map_or_else(|| &[42][..1], std::slice::from_ref); + _ = x.as_ref().map(|f| std::slice::from_ref(f)).unwrap_or_default(); +} + +#[clippy::msrv = "1.74"] +fn check_msrv(x: Option) { + _ = x.as_ref().map_or(&[][..], std::slice::from_ref); +} + +fn main() { + check(Some(1)); + check_msrv(Some(175)); +} diff --git a/tests/ui/manual_option_as_slice.rs b/tests/ui/manual_option_as_slice.rs new file mode 100644 index 000000000000..561a8b534014 --- /dev/null +++ b/tests/ui/manual_option_as_slice.rs @@ -0,0 +1,71 @@ +#![warn(clippy::manual_option_as_slice)] +#![allow(clippy::redundant_closure, clippy::unwrap_or_default)] + +fn check(x: Option) { + _ = match x.as_ref() { + //~^ manual_option_as_slice + Some(f) => std::slice::from_ref(f), + None => &[], + }; + + _ = if let Some(f) = x.as_ref() { + //~^ manual_option_as_slice + std::slice::from_ref(f) + } else { + &[] + }; + + _ = x.as_ref().map_or(&[][..], std::slice::from_ref); + //~^ manual_option_as_slice + + _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref); + //~^ manual_option_as_slice + + _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default(); + //~^ manual_option_as_slice + + _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref); + //~^ manual_option_as_slice + + { + use std::slice::from_ref; + _ = x.as_ref().map_or_else(<&[_]>::default, from_ref); + //~^ manual_option_as_slice + } + + // possible false positives + let y = x.as_ref(); + _ = match y { + // as_ref outside + Some(f) => &[f][..], + None => &[][..], + }; + _ = match x.as_ref() { + Some(f) => std::slice::from_ref(f), + None => &[0], + }; + _ = match x.as_ref() { + Some(42) => &[23], + Some(f) => std::slice::from_ref(f), + None => &[], + }; + let b = &[42]; + _ = if let Some(_f) = x.as_ref() { + std::slice::from_ref(b) + } else { + &[] + }; + _ = x.as_ref().map_or(&[42][..], std::slice::from_ref); + _ = x.as_ref().map_or_else(|| &[42][..1], std::slice::from_ref); + _ = x.as_ref().map(|f| std::slice::from_ref(f)).unwrap_or_default(); +} + +#[clippy::msrv = "1.74"] +fn check_msrv(x: Option) { + _ = x.as_ref().map_or(&[][..], std::slice::from_ref); +} + +fn main() { + check(Some(1)); + check_msrv(Some(175)); +} diff --git a/tests/ui/manual_option_as_slice.stderr b/tests/ui/manual_option_as_slice.stderr new file mode 100644 index 000000000000..569269d3e2b7 --- /dev/null +++ b/tests/ui/manual_option_as_slice.stderr @@ -0,0 +1,58 @@ +error: use `Option::as_slice` + --> tests/ui/manual_option_as_slice.rs:5:9 + | +LL | _ = match x.as_ref() { + | _________^ +LL | | +LL | | Some(f) => std::slice::from_ref(f), +LL | | None => &[], +LL | | }; + | |_____^ help: use: `x.as_slice()` + | + = note: `-D clippy::manual-option-as-slice` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_option_as_slice)]` + +error: use `Option::as_slice` + --> tests/ui/manual_option_as_slice.rs:11:9 + | +LL | _ = if let Some(f) = x.as_ref() { + | _________^ +LL | | +LL | | std::slice::from_ref(f) +LL | | } else { +LL | | &[] +LL | | }; + | |_____^ help: use: `x.as_slice()` + +error: use `Option::as_slice` + --> tests/ui/manual_option_as_slice.rs:18:9 + | +LL | _ = x.as_ref().map_or(&[][..], std::slice::from_ref); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` + +error: use `Option::as_slice` + --> tests/ui/manual_option_as_slice.rs:21:9 + | +LL | _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` + +error: use `Option::as_slice` + --> tests/ui/manual_option_as_slice.rs:24:9 + | +LL | _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` + +error: use `Option::as_slice` + --> tests/ui/manual_option_as_slice.rs:27:9 + | +LL | _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` + +error: use `Option::as_slice` + --> tests/ui/manual_option_as_slice.rs:32:13 + | +LL | _ = x.as_ref().map_or_else(<&[_]>::default, from_ref); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` + +error: aborting due to 7 previous errors + diff --git a/tests/ui/manual_slice_fill.fixed b/tests/ui/manual_slice_fill.fixed new file mode 100644 index 000000000000..397a156a2dc7 --- /dev/null +++ b/tests/ui/manual_slice_fill.fixed @@ -0,0 +1,101 @@ +#![warn(clippy::manual_slice_fill)] +#![allow(clippy::needless_range_loop)] + +macro_rules! assign_element { + ($slice:ident, $index:expr) => { + $slice[$index] = 0; + }; +} + +macro_rules! assign_element_2 { + ($i:expr) => { + $i = 0; + }; +} + +struct NoClone; + +fn num() -> usize { + 5 +} + +fn should_lint() { + let mut some_slice = [1, 2, 3, 4, 5]; + + some_slice.fill(0); + + let x = 5; + some_slice.fill(x); + + some_slice.fill(0); + + // This should trigger `manual_slice_fill`, but the applicability is `MaybeIncorrect` since comments + // within the loop might be purely informational. + some_slice.fill(0); +} + +fn should_not_lint() { + let mut some_slice = [1, 2, 3, 4, 5]; + + // Should not lint because we can't determine if the scope of the loop is intended to access all the + // elements of the slice. + for i in 0..5 { + some_slice[i] = 0; + } + + // Should not lint, as using a function to assign values to elements might be + // intentional. For example, the contents of `num()` could be temporary and subject to change + // later. + for i in 0..some_slice.len() { + some_slice[i] = num(); + } + + // Should not lint because this loop isn't equivalent to `fill`. + for i in 0..some_slice.len() { + some_slice[i] = 0; + println!("foo"); + } + + // Should not lint because it may be intentional to use a macro to perform an operation equivalent + // to `fill`. + for i in 0..some_slice.len() { + assign_element!(some_slice, i); + } + + let another_slice = [1, 2, 3]; + // Should not lint because the range is not for `some_slice`. + for i in 0..another_slice.len() { + some_slice[i] = 0; + } + + let mut vec: Vec> = Vec::with_capacity(5); + // Should not lint because `NoClone` does not have `Clone` trait. + for i in 0..vec.len() { + vec[i] = None; + } + + // Should not lint, as using a function to assign values to elements might be + // intentional. For example, the contents of `num()` could be temporary and subject to change + // later. + for i in &mut some_slice { + *i = num(); + } + + // Should not lint because this loop isn't equivalent to `fill`. + for i in &mut some_slice { + *i = 0; + println!("foo"); + } + + // Should not lint because it may be intentional to use a macro to perform an operation equivalent + // to `fill`. + for i in &mut some_slice { + assign_element_2!(*i); + } + + let mut vec: Vec> = Vec::with_capacity(5); + // Should not lint because `NoClone` does not have `Clone` trait. + for i in &mut vec { + *i = None; + } +} diff --git a/tests/ui/manual_slice_fill.rs b/tests/ui/manual_slice_fill.rs new file mode 100644 index 000000000000..c25127ca613a --- /dev/null +++ b/tests/ui/manual_slice_fill.rs @@ -0,0 +1,110 @@ +#![warn(clippy::manual_slice_fill)] +#![allow(clippy::needless_range_loop)] + +macro_rules! assign_element { + ($slice:ident, $index:expr) => { + $slice[$index] = 0; + }; +} + +macro_rules! assign_element_2 { + ($i:expr) => { + $i = 0; + }; +} + +struct NoClone; + +fn num() -> usize { + 5 +} + +fn should_lint() { + let mut some_slice = [1, 2, 3, 4, 5]; + + for i in 0..some_slice.len() { + some_slice[i] = 0; + } + + let x = 5; + for i in 0..some_slice.len() { + some_slice[i] = x; + } + + for i in &mut some_slice { + *i = 0; + } + + // This should trigger `manual_slice_fill`, but the applicability is `MaybeIncorrect` since comments + // within the loop might be purely informational. + for i in 0..some_slice.len() { + some_slice[i] = 0; + // foo + } +} + +fn should_not_lint() { + let mut some_slice = [1, 2, 3, 4, 5]; + + // Should not lint because we can't determine if the scope of the loop is intended to access all the + // elements of the slice. + for i in 0..5 { + some_slice[i] = 0; + } + + // Should not lint, as using a function to assign values to elements might be + // intentional. For example, the contents of `num()` could be temporary and subject to change + // later. + for i in 0..some_slice.len() { + some_slice[i] = num(); + } + + // Should not lint because this loop isn't equivalent to `fill`. + for i in 0..some_slice.len() { + some_slice[i] = 0; + println!("foo"); + } + + // Should not lint because it may be intentional to use a macro to perform an operation equivalent + // to `fill`. + for i in 0..some_slice.len() { + assign_element!(some_slice, i); + } + + let another_slice = [1, 2, 3]; + // Should not lint because the range is not for `some_slice`. + for i in 0..another_slice.len() { + some_slice[i] = 0; + } + + let mut vec: Vec> = Vec::with_capacity(5); + // Should not lint because `NoClone` does not have `Clone` trait. + for i in 0..vec.len() { + vec[i] = None; + } + + // Should not lint, as using a function to assign values to elements might be + // intentional. For example, the contents of `num()` could be temporary and subject to change + // later. + for i in &mut some_slice { + *i = num(); + } + + // Should not lint because this loop isn't equivalent to `fill`. + for i in &mut some_slice { + *i = 0; + println!("foo"); + } + + // Should not lint because it may be intentional to use a macro to perform an operation equivalent + // to `fill`. + for i in &mut some_slice { + assign_element_2!(*i); + } + + let mut vec: Vec> = Vec::with_capacity(5); + // Should not lint because `NoClone` does not have `Clone` trait. + for i in &mut vec { + *i = None; + } +} diff --git a/tests/ui/manual_slice_fill.stderr b/tests/ui/manual_slice_fill.stderr new file mode 100644 index 000000000000..3aa980f69191 --- /dev/null +++ b/tests/ui/manual_slice_fill.stderr @@ -0,0 +1,38 @@ +error: manually filling a slice + --> tests/ui/manual_slice_fill.rs:25:5 + | +LL | / for i in 0..some_slice.len() { +LL | | some_slice[i] = 0; +LL | | } + | |_____^ help: try: `some_slice.fill(0);` + | + = note: `-D clippy::manual-slice-fill` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_slice_fill)]` + +error: manually filling a slice + --> tests/ui/manual_slice_fill.rs:30:5 + | +LL | / for i in 0..some_slice.len() { +LL | | some_slice[i] = x; +LL | | } + | |_____^ help: try: `some_slice.fill(x);` + +error: manually filling a slice + --> tests/ui/manual_slice_fill.rs:34:5 + | +LL | / for i in &mut some_slice { +LL | | *i = 0; +LL | | } + | |_____^ help: try: `some_slice.fill(0);` + +error: manually filling a slice + --> tests/ui/manual_slice_fill.rs:40:5 + | +LL | / for i in 0..some_slice.len() { +LL | | some_slice[i] = 0; +LL | | // foo +LL | | } + | |_____^ help: try: `some_slice.fill(0);` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/manual_unwrap_or_default_unfixable.rs b/tests/ui/manual_unwrap_or_default_unfixable.rs new file mode 100644 index 000000000000..acc54b52816c --- /dev/null +++ b/tests/ui/manual_unwrap_or_default_unfixable.rs @@ -0,0 +1,15 @@ +//@no-rustfix +fn issue_12670() { + // no auto: type not found + #[allow(clippy::match_result_ok)] + let _ = if let Some(x) = "1".parse().ok() { + x + } else { + i32::default() + }; + let _ = if let Some(x) = None { x } else { i32::default() }; + // auto fix with unwrap_or_default + let a: Option = None; + let _ = if let Some(x) = a { x } else { i32::default() }; + let _ = if let Some(x) = Some(99) { x } else { i32::default() }; +} diff --git a/tests/ui/manual_unwrap_or_default_unfixable.stderr b/tests/ui/manual_unwrap_or_default_unfixable.stderr new file mode 100644 index 000000000000..3849d33cf254 --- /dev/null +++ b/tests/ui/manual_unwrap_or_default_unfixable.stderr @@ -0,0 +1,34 @@ +error: if let can be simplified with `.unwrap_or_default()` + --> tests/ui/manual_unwrap_or_default_unfixable.rs:5:13 + | +LL | let _ = if let Some(x) = "1".parse().ok() { + | _____________^ +LL | | x +LL | | } else { +LL | | i32::default() +LL | | }; + | |_____^ help: ascribe the type i32 and replace your expression with: `"1".parse().ok().unwrap_or_default()` + | + = note: `-D clippy::manual-unwrap-or-default` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or_default)]` + +error: if let can be simplified with `.unwrap_or_default()` + --> tests/ui/manual_unwrap_or_default_unfixable.rs:10:13 + | +LL | let _ = if let Some(x) = None { x } else { i32::default() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `None::.unwrap_or_default()` + +error: if let can be simplified with `.unwrap_or_default()` + --> tests/ui/manual_unwrap_or_default_unfixable.rs:13:13 + | +LL | let _ = if let Some(x) = a { x } else { i32::default() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.unwrap_or_default()` + +error: if let can be simplified with `.unwrap_or_default()` + --> tests/ui/manual_unwrap_or_default_unfixable.rs:14:13 + | +LL | let _ = if let Some(x) = Some(99) { x } else { i32::default() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(99).unwrap_or_default()` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/needless_option_take.fixed b/tests/ui/needless_option_take.fixed new file mode 100644 index 000000000000..6514b67ef7a7 --- /dev/null +++ b/tests/ui/needless_option_take.fixed @@ -0,0 +1,58 @@ +struct MyStruct; + +impl MyStruct { + pub fn get_option() -> Option { + todo!() + } +} + +fn return_option() -> Option { + todo!() +} + +fn main() { + println!("Testing non erroneous option_take_on_temporary"); + let mut option = Some(1); + let _ = Box::new(move || option.take().unwrap()); + + println!("Testing non erroneous option_take_on_temporary"); + let x = Some(3); + x.as_ref(); + + let x = Some(3); + x.as_ref(); + //~^ ERROR: called `Option::take()` on a temporary value + + println!("Testing non erroneous option_take_on_temporary"); + let mut x = Some(3); + let y = x.as_mut(); + + let mut x = Some(3); + let y = x.as_mut(); + //~^ ERROR: called `Option::take()` on a temporary value + let y = x.replace(289); + //~^ ERROR: called `Option::take()` on a temporary value + + let y = Some(3).as_mut(); + //~^ ERROR: called `Option::take()` on a temporary value + + let y = Option::as_mut(&mut x); + //~^ ERROR: called `Option::take()` on a temporary value + + let x = return_option(); + let x = return_option(); + //~^ ERROR: called `Option::take()` on a temporary value + + let x = MyStruct::get_option(); + let x = MyStruct::get_option(); + //~^ ERROR: called `Option::take()` on a temporary value + + let mut my_vec = vec![1, 2, 3]; + my_vec.push(4); + let y = my_vec.first(); + let y = my_vec.first(); + //~^ ERROR: called `Option::take()` on a temporary value + + let y = my_vec.first(); + //~^ ERROR: called `Option::take()` on a temporary value +} diff --git a/tests/ui/needless_option_take.stderr b/tests/ui/needless_option_take.stderr index e036bd53170a..3fc339ed79e2 100644 --- a/tests/ui/needless_option_take.stderr +++ b/tests/ui/needless_option_take.stderr @@ -2,7 +2,9 @@ error: called `Option::take()` on a temporary value --> tests/ui/needless_option_take.rs:23:5 | LL | x.as_ref().take(); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^------- + | | + | help: remove | = note: `as_ref` creates a temporary value, so calling take() has no effect = note: `-D clippy::needless-option-take` implied by `-D warnings` @@ -12,7 +14,9 @@ error: called `Option::take()` on a temporary value --> tests/ui/needless_option_take.rs:31:13 | LL | let y = x.as_mut().take(); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^------- + | | + | help: remove | = note: `as_mut` creates a temporary value, so calling take() has no effect @@ -20,7 +24,9 @@ error: called `Option::take()` on a temporary value --> tests/ui/needless_option_take.rs:33:13 | LL | let y = x.replace(289).take(); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^------- + | | + | help: remove | = note: `replace` creates a temporary value, so calling take() has no effect @@ -28,7 +34,9 @@ error: called `Option::take()` on a temporary value --> tests/ui/needless_option_take.rs:36:13 | LL | let y = Some(3).as_mut().take(); - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^------- + | | + | help: remove | = note: `as_mut` creates a temporary value, so calling take() has no effect @@ -36,7 +44,9 @@ error: called `Option::take()` on a temporary value --> tests/ui/needless_option_take.rs:39:13 | LL | let y = Option::as_mut(&mut x).take(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^------- + | | + | help: remove | = note: `as_mut` creates a temporary value, so calling take() has no effect @@ -44,7 +54,9 @@ error: called `Option::take()` on a temporary value --> tests/ui/needless_option_take.rs:43:13 | LL | let x = return_option().take(); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^------- + | | + | help: remove | = note: `return_option` creates a temporary value, so calling take() has no effect @@ -52,7 +64,9 @@ error: called `Option::take()` on a temporary value --> tests/ui/needless_option_take.rs:47:13 | LL | let x = MyStruct::get_option().take(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^------- + | | + | help: remove | = note: `get_option` creates a temporary value, so calling take() has no effect @@ -60,7 +74,9 @@ error: called `Option::take()` on a temporary value --> tests/ui/needless_option_take.rs:53:13 | LL | let y = my_vec.first().take(); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^------- + | | + | help: remove | = note: `first` creates a temporary value, so calling take() has no effect @@ -68,7 +84,9 @@ error: called `Option::take()` on a temporary value --> tests/ui/needless_option_take.rs:56:13 | LL | let y = my_vec.first().take(); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^------- + | | + | help: remove | = note: `first` creates a temporary value, so calling take() has no effect diff --git a/tests/ui/needless_range_loop.rs b/tests/ui/needless_range_loop.rs index 3f2421953301..75f1896eded1 100644 --- a/tests/ui/needless_range_loop.rs +++ b/tests/ui/needless_range_loop.rs @@ -2,7 +2,8 @@ #![allow( clippy::uninlined_format_args, clippy::unnecessary_literal_unwrap, - clippy::useless_vec + clippy::useless_vec, + clippy::manual_slice_fill )] //@no-rustfix static STATIC: [usize; 4] = [0, 1, 8, 16]; diff --git a/tests/ui/needless_range_loop.stderr b/tests/ui/needless_range_loop.stderr index dc2cf437e02e..503d796e5e8d 100644 --- a/tests/ui/needless_range_loop.stderr +++ b/tests/ui/needless_range_loop.stderr @@ -1,5 +1,5 @@ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:15:14 + --> tests/ui/needless_range_loop.rs:16:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | for in &vec { | ~~~~~~ ~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:26:14 + --> tests/ui/needless_range_loop.rs:27:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | for in &vec { | ~~~~~~ ~~~~ error: the loop variable `j` is only used to index `STATIC` - --> tests/ui/needless_range_loop.rs:32:14 + --> tests/ui/needless_range_loop.rs:33:14 | LL | for j in 0..4 { | ^^^^ @@ -34,7 +34,7 @@ LL | for in &STATIC { | ~~~~~~ ~~~~~~~ error: the loop variable `j` is only used to index `CONST` - --> tests/ui/needless_range_loop.rs:37:14 + --> tests/ui/needless_range_loop.rs:38:14 | LL | for j in 0..4 { | ^^^^ @@ -45,7 +45,7 @@ LL | for in &CONST { | ~~~~~~ ~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:42:14 + --> tests/ui/needless_range_loop.rs:43:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | for (i, ) in vec.iter().enumerate() { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec2` - --> tests/ui/needless_range_loop.rs:51:14 + --> tests/ui/needless_range_loop.rs:52:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | for in vec2.iter().take(vec.len()) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:56:14 + --> tests/ui/needless_range_loop.rs:57:14 | LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | for in vec.iter().skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:61:14 + --> tests/ui/needless_range_loop.rs:62:14 | LL | for i in 0..MAX_LEN { | ^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | for in vec.iter().take(MAX_LEN) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:66:14 + --> tests/ui/needless_range_loop.rs:67:14 | LL | for i in 0..=MAX_LEN { | ^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | for in vec.iter().take(MAX_LEN + 1) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:71:14 + --> tests/ui/needless_range_loop.rs:72:14 | LL | for i in 5..10 { | ^^^^^ @@ -111,7 +111,7 @@ LL | for in vec.iter().take(10).skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:76:14 + --> tests/ui/needless_range_loop.rs:77:14 | LL | for i in 5..=10 { | ^^^^^^ @@ -122,7 +122,7 @@ LL | for in vec.iter().take(10 + 1).skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:81:14 + --> tests/ui/needless_range_loop.rs:82:14 | LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | for (i, ) in vec.iter().enumerate().skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:86:14 + --> tests/ui/needless_range_loop.rs:87:14 | LL | for i in 5..10 { | ^^^^^ @@ -144,7 +144,7 @@ LL | for (i, ) in vec.iter().enumerate().take(10).skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:92:14 + --> tests/ui/needless_range_loop.rs:93:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ diff --git a/tests/ui/precedence.fixed b/tests/ui/precedence.fixed index 9864dd2550b6..52144a18bac0 100644 --- a/tests/ui/precedence.fixed +++ b/tests/ui/precedence.fixed @@ -20,10 +20,10 @@ fn main() { 1 ^ (1 - 1); 3 | (2 - 1); 3 & (5 - 2); - 0x0F00 & (0x00F0 << 4); - 0x0F00 & (0xF000 >> 4); - (0x0F00 << 1) ^ 3; - (0x0F00 << 1) | 2; + 0x0F00 & 0x00F0 << 4; + 0x0F00 & 0xF000 >> 4; + 0x0F00 << 1 ^ 3; + 0x0F00 << 1 | 2; let b = 3; trip!(b * 8); diff --git a/tests/ui/precedence.stderr b/tests/ui/precedence.stderr index 329422cb8a69..68ad5cb4829a 100644 --- a/tests/ui/precedence.stderr +++ b/tests/ui/precedence.stderr @@ -43,29 +43,5 @@ error: operator precedence might not be obvious LL | 3 & 5 - 2; | ^^^^^^^^^ help: consider parenthesizing your expression: `3 & (5 - 2)` -error: operator precedence might not be obvious - --> tests/ui/precedence.rs:23:5 - | -LL | 0x0F00 & 0x00F0 << 4; - | ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0x00F0 << 4)` - -error: operator precedence might not be obvious - --> tests/ui/precedence.rs:24:5 - | -LL | 0x0F00 & 0xF000 >> 4; - | ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0xF000 >> 4)` - -error: operator precedence might not be obvious - --> tests/ui/precedence.rs:25:5 - | -LL | 0x0F00 << 1 ^ 3; - | ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) ^ 3` - -error: operator precedence might not be obvious - --> tests/ui/precedence.rs:26:5 - | -LL | 0x0F00 << 1 | 2; - | ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) | 2` - -error: aborting due to 11 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/precedence_bits.fixed b/tests/ui/precedence_bits.fixed new file mode 100644 index 000000000000..82fea0d14e43 --- /dev/null +++ b/tests/ui/precedence_bits.fixed @@ -0,0 +1,35 @@ +#![warn(clippy::precedence_bits)] +#![allow( + unused_must_use, + clippy::no_effect, + clippy::unnecessary_operation, + clippy::precedence +)] +#![allow(clippy::identity_op)] +#![allow(clippy::eq_op)] + +macro_rules! trip { + ($a:expr) => { + match $a & 0b1111_1111u8 { + 0 => println!("a is zero ({})", $a), + _ => println!("a is {}", $a), + } + }; +} + +fn main() { + 1 << 2 + 3; + 1 + 2 << 3; + 4 >> 1 + 1; + 1 + 3 >> 2; + 1 ^ 1 - 1; + 3 | 2 - 1; + 3 & 5 - 2; + 0x0F00 & (0x00F0 << 4); + 0x0F00 & (0xF000 >> 4); + (0x0F00 << 1) ^ 3; + (0x0F00 << 1) | 2; + + let b = 3; + trip!(b * 8); +} diff --git a/tests/ui/precedence_bits.rs b/tests/ui/precedence_bits.rs new file mode 100644 index 000000000000..9b353308b6ee --- /dev/null +++ b/tests/ui/precedence_bits.rs @@ -0,0 +1,35 @@ +#![warn(clippy::precedence_bits)] +#![allow( + unused_must_use, + clippy::no_effect, + clippy::unnecessary_operation, + clippy::precedence +)] +#![allow(clippy::identity_op)] +#![allow(clippy::eq_op)] + +macro_rules! trip { + ($a:expr) => { + match $a & 0b1111_1111u8 { + 0 => println!("a is zero ({})", $a), + _ => println!("a is {}", $a), + } + }; +} + +fn main() { + 1 << 2 + 3; + 1 + 2 << 3; + 4 >> 1 + 1; + 1 + 3 >> 2; + 1 ^ 1 - 1; + 3 | 2 - 1; + 3 & 5 - 2; + 0x0F00 & 0x00F0 << 4; + 0x0F00 & 0xF000 >> 4; + 0x0F00 << 1 ^ 3; + 0x0F00 << 1 | 2; + + let b = 3; + trip!(b * 8); +} diff --git a/tests/ui/precedence_bits.stderr b/tests/ui/precedence_bits.stderr new file mode 100644 index 000000000000..f468186b363c --- /dev/null +++ b/tests/ui/precedence_bits.stderr @@ -0,0 +1,29 @@ +error: operator precedence might not be obvious + --> tests/ui/precedence_bits.rs:28:5 + | +LL | 0x0F00 & 0x00F0 << 4; + | ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0x00F0 << 4)` + | + = note: `-D clippy::precedence-bits` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::precedence_bits)]` + +error: operator precedence might not be obvious + --> tests/ui/precedence_bits.rs:29:5 + | +LL | 0x0F00 & 0xF000 >> 4; + | ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0xF000 >> 4)` + +error: operator precedence might not be obvious + --> tests/ui/precedence_bits.rs:30:5 + | +LL | 0x0F00 << 1 ^ 3; + | ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) ^ 3` + +error: operator precedence might not be obvious + --> tests/ui/precedence_bits.rs:31:5 + | +LL | 0x0F00 << 1 | 2; + | ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) | 2` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/print_literal.fixed b/tests/ui/print_literal.fixed index 1705a7ff01bb..328e9a9b999f 100644 --- a/tests/ui/print_literal.fixed +++ b/tests/ui/print_literal.fixed @@ -66,3 +66,17 @@ fn main() { println!("mixed: {{hello}} {world}"); } + +fn issue_13959() { + println!("\""); + println!( + " + foo + \\ + \\\\ + \" + \\\" + bar +" + ); +} diff --git a/tests/ui/print_literal.rs b/tests/ui/print_literal.rs index d10b26b5887c..3130d0b6998e 100644 --- a/tests/ui/print_literal.rs +++ b/tests/ui/print_literal.rs @@ -66,3 +66,18 @@ fn main() { println!("mixed: {} {world}", "{hello}"); } + +fn issue_13959() { + println!("{}", r#"""#); + println!( + "{}", + r#" + foo + \ + \\ + " + \" + bar +"# + ); +} diff --git a/tests/ui/print_literal.stderr b/tests/ui/print_literal.stderr index c4cbb8bed707..d967b7c24070 100644 --- a/tests/ui/print_literal.stderr +++ b/tests/ui/print_literal.stderr @@ -192,5 +192,41 @@ LL - println!("mixed: {} {world}", "{hello}"); LL + println!("mixed: {{hello}} {world}"); | -error: aborting due to 16 previous errors +error: literal with an empty format string + --> tests/ui/print_literal.rs:71:20 + | +LL | println!("{}", r#"""#); + | ^^^^^^ + | +help: try + | +LL - println!("{}", r#"""#); +LL + println!("\""); + | + +error: literal with an empty format string + --> tests/ui/print_literal.rs:74:9 + | +LL | / r#" +LL | | foo +LL | | \ +LL | | \\ +... | +LL | | bar +LL | | "# + | |__^ + | +help: try + | +LL ~ " +LL + foo +LL + \\ +LL + \\\\ +LL + \" +LL + \\\" +LL + bar +LL ~ " + | + +error: aborting due to 18 previous errors diff --git a/tests/ui/redundant_else.fixed b/tests/ui/redundant_else.fixed new file mode 100644 index 000000000000..47aa79302d2c --- /dev/null +++ b/tests/ui/redundant_else.fixed @@ -0,0 +1,154 @@ +#![warn(clippy::redundant_else)] +#![allow(clippy::needless_return, clippy::if_same_then_else, clippy::needless_late_init)] + +fn main() { + loop { + // break + if foo() { + println!("Love your neighbor;"); + break; + } + //~^ ERROR: redundant else block + println!("yet don't pull down your hedge."); + // continue + if foo() { + println!("He that lies down with Dogs,"); + continue; + } + //~^ ERROR: redundant else block + println!("shall rise up with fleas."); + // match block + if foo() { + match foo() { + 1 => break, + _ => return, + } + } + //~^ ERROR: redundant else block + println!("You may delay, but time will not."); + } + // else if + if foo() { + return; + } else if foo() { + return; + } + //~^ ERROR: redundant else block + println!("A fat kitchen makes a lean will."); + // let binding outside of block + let _ = { + if foo() { + return; + } + //~^ ERROR: redundant else block + 1 + }; + // else if with let binding outside of block + let _ = { + if foo() { + return; + } else if foo() { + return; + } + //~^ ERROR: redundant else block + 2 + }; + // inside if let + let _ = if let Some(1) = foo() { + let _ = 1; + if foo() { + return; + } + //~^ ERROR: redundant else block + 1 + } else { + 1 + }; + + // + // non-lint cases + // + + // sanity check + if foo() { + let _ = 1; + } else { + println!("Who is wise? He that learns from every one."); + } + // else if without else + if foo() { + return; + } else if foo() { + foo() + }; + // nested if return + if foo() { + if foo() { + return; + } + } else { + foo() + }; + // match with non-breaking branch + if foo() { + match foo() { + 1 => foo(), + _ => return, + } + } else { + println!("Three may keep a secret, if two of them are dead."); + } + // let binding + let _ = if foo() { + return; + } else { + 1 + }; + // assign + let mut a; + a = if foo() { + return; + } else { + 1 + }; + // assign-op + a += if foo() { + return; + } else { + 1 + }; + // if return else if else + if foo() { + return; + } else if foo() { + 1 + } else { + 2 + }; + // if else if return else + if foo() { + 1 + } else if foo() { + return; + } else { + 2 + }; + // else if with let binding + let _ = if foo() { + return; + } else if foo() { + return; + } else { + 2 + }; + // inside function call + Box::new(if foo() { + return; + } else { + 1 + }); +} + +fn foo() -> T { + unimplemented!("I'm not Santa Claus") +} diff --git a/tests/ui/redundant_else.stderr b/tests/ui/redundant_else.stderr index b649a210b5fa..ecc16f7cda5e 100644 --- a/tests/ui/redundant_else.stderr +++ b/tests/ui/redundant_else.stderr @@ -1,88 +1,123 @@ error: redundant else block - --> tests/ui/redundant_else.rs:10:16 + --> tests/ui/redundant_else.rs:10:10 | LL | } else { - | ________________^ + | __________^ LL | | LL | | println!("yet don't pull down your hedge."); LL | | } | |_________^ | - = help: remove the `else` block and move the contents out = note: `-D clippy::redundant-else` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::redundant_else)]` +help: remove the `else` block and move the contents out + | +LL ~ } +LL + +LL + println!("yet don't pull down your hedge."); + | error: redundant else block - --> tests/ui/redundant_else.rs:18:16 + --> tests/ui/redundant_else.rs:18:10 | LL | } else { - | ________________^ + | __________^ LL | | LL | | println!("shall rise up with fleas."); LL | | } | |_________^ | - = help: remove the `else` block and move the contents out +help: remove the `else` block and move the contents out + | +LL ~ } +LL + +LL + println!("shall rise up with fleas."); + | error: redundant else block - --> tests/ui/redundant_else.rs:28:16 + --> tests/ui/redundant_else.rs:28:10 | LL | } else { - | ________________^ + | __________^ LL | | LL | | println!("You may delay, but time will not."); LL | | } | |_________^ | - = help: remove the `else` block and move the contents out +help: remove the `else` block and move the contents out + | +LL ~ } +LL + +LL + println!("You may delay, but time will not."); + | error: redundant else block - --> tests/ui/redundant_else.rs:38:12 + --> tests/ui/redundant_else.rs:38:6 | LL | } else { - | ____________^ + | ______^ LL | | LL | | println!("A fat kitchen makes a lean will."); LL | | } | |_____^ | - = help: remove the `else` block and move the contents out +help: remove the `else` block and move the contents out + | +LL ~ } +LL + +LL + println!("A fat kitchen makes a lean will."); + | error: redundant else block - --> tests/ui/redundant_else.rs:46:16 + --> tests/ui/redundant_else.rs:46:10 | LL | } else { - | ________________^ + | __________^ LL | | LL | | 1 LL | | } | |_________^ | - = help: remove the `else` block and move the contents out +help: remove the `else` block and move the contents out + | +LL ~ } +LL + +LL + 1 + | error: redundant else block - --> tests/ui/redundant_else.rs:57:16 + --> tests/ui/redundant_else.rs:57:10 | LL | } else { - | ________________^ + | __________^ LL | | LL | | 2 LL | | } | |_________^ | - = help: remove the `else` block and move the contents out +help: remove the `else` block and move the contents out + | +LL ~ } +LL + +LL + 2 + | error: redundant else block - --> tests/ui/redundant_else.rs:67:16 + --> tests/ui/redundant_else.rs:67:10 | LL | } else { - | ________________^ + | __________^ LL | | LL | | 1 LL | | } | |_________^ | - = help: remove the `else` block and move the contents out +help: remove the `else` block and move the contents out + | +LL ~ } +LL + +LL + 1 + | error: aborting due to 7 previous errors diff --git a/tests/ui/return_and_then.fixed b/tests/ui/return_and_then.fixed new file mode 100644 index 000000000000..9736a51ac868 --- /dev/null +++ b/tests/ui/return_and_then.fixed @@ -0,0 +1,67 @@ +#![warn(clippy::return_and_then)] + +fn main() { + fn test_opt_block(opt: Option) -> Option { + let n = opt?; + let mut ret = n + 1; + ret += n; + if n > 1 { Some(ret) } else { None } + } + + fn test_opt_func(opt: Option) -> Option { + let n = opt?; + test_opt_block(Some(n)) + } + + fn test_call_chain() -> Option { + let n = gen_option(1)?; + test_opt_block(Some(n)) + } + + fn test_res_block(opt: Result) -> Result { + let n = opt?; + if n > 1 { Ok(n + 1) } else { Err(n) } + } + + fn test_res_func(opt: Result) -> Result { + let n = opt?; + test_res_block(Ok(n)) + } + + fn test_ref_only() -> Option { + // ref: empty string + let x = Some("")?; + if x.len() > 2 { Some(3) } else { None } + } + + fn test_tmp_only() -> Option { + // unused temporary: vec![1, 2, 4] + let x = Some(match (vec![1, 2, 3], vec![1, 2, 4]) { + (a, _) if a.len() > 1 => a, + (_, b) => b, + })?; + if x.len() > 2 { Some(3) } else { None } + } + + // should not lint + fn test_tmp_ref() -> Option { + String::from("") + .strip_prefix("<") + .and_then(|s| s.strip_suffix(">").map(String::from)) + } + + // should not lint + fn test_unconsumed_tmp() -> Option { + [1, 2, 3] + .iter() + .map(|x| x + 1) + .collect::>() // temporary Vec created here + .as_slice() // creates temporary slice + .first() // creates temporary reference + .and_then(|x| test_opt_block(Some(*x))) + } +} + +fn gen_option(n: i32) -> Option { + Some(n) +} diff --git a/tests/ui/return_and_then.rs b/tests/ui/return_and_then.rs new file mode 100644 index 000000000000..8bcbdfc3a632 --- /dev/null +++ b/tests/ui/return_and_then.rs @@ -0,0 +1,63 @@ +#![warn(clippy::return_and_then)] + +fn main() { + fn test_opt_block(opt: Option) -> Option { + opt.and_then(|n| { + let mut ret = n + 1; + ret += n; + if n > 1 { Some(ret) } else { None } + }) + } + + fn test_opt_func(opt: Option) -> Option { + opt.and_then(|n| test_opt_block(Some(n))) + } + + fn test_call_chain() -> Option { + gen_option(1).and_then(|n| test_opt_block(Some(n))) + } + + fn test_res_block(opt: Result) -> Result { + opt.and_then(|n| if n > 1 { Ok(n + 1) } else { Err(n) }) + } + + fn test_res_func(opt: Result) -> Result { + opt.and_then(|n| test_res_block(Ok(n))) + } + + fn test_ref_only() -> Option { + // ref: empty string + Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None }) + } + + fn test_tmp_only() -> Option { + // unused temporary: vec![1, 2, 4] + Some(match (vec![1, 2, 3], vec![1, 2, 4]) { + (a, _) if a.len() > 1 => a, + (_, b) => b, + }) + .and_then(|x| if x.len() > 2 { Some(3) } else { None }) + } + + // should not lint + fn test_tmp_ref() -> Option { + String::from("") + .strip_prefix("<") + .and_then(|s| s.strip_suffix(">").map(String::from)) + } + + // should not lint + fn test_unconsumed_tmp() -> Option { + [1, 2, 3] + .iter() + .map(|x| x + 1) + .collect::>() // temporary Vec created here + .as_slice() // creates temporary slice + .first() // creates temporary reference + .and_then(|x| test_opt_block(Some(*x))) + } +} + +fn gen_option(n: i32) -> Option { + Some(n) +} diff --git a/tests/ui/return_and_then.stderr b/tests/ui/return_and_then.stderr new file mode 100644 index 000000000000..b2e8bf2ca45a --- /dev/null +++ b/tests/ui/return_and_then.stderr @@ -0,0 +1,101 @@ +error: use the question mark operator instead of an `and_then` call + --> tests/ui/return_and_then.rs:5:9 + | +LL | / opt.and_then(|n| { +LL | | let mut ret = n + 1; +LL | | ret += n; +LL | | if n > 1 { Some(ret) } else { None } +LL | | }) + | |__________^ + | + = note: `-D clippy::return-and-then` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::return_and_then)]` +help: try + | +LL ~ let n = opt?; +LL + let mut ret = n + 1; +LL + ret += n; +LL + if n > 1 { Some(ret) } else { None } + | + +error: use the question mark operator instead of an `and_then` call + --> tests/ui/return_and_then.rs:13:9 + | +LL | opt.and_then(|n| test_opt_block(Some(n))) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ let n = opt?; +LL + test_opt_block(Some(n)) + | + +error: use the question mark operator instead of an `and_then` call + --> tests/ui/return_and_then.rs:17:9 + | +LL | gen_option(1).and_then(|n| test_opt_block(Some(n))) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ let n = gen_option(1)?; +LL + test_opt_block(Some(n)) + | + +error: use the question mark operator instead of an `and_then` call + --> tests/ui/return_and_then.rs:21:9 + | +LL | opt.and_then(|n| if n > 1 { Ok(n + 1) } else { Err(n) }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ let n = opt?; +LL + if n > 1 { Ok(n + 1) } else { Err(n) } + | + +error: use the question mark operator instead of an `and_then` call + --> tests/ui/return_and_then.rs:25:9 + | +LL | opt.and_then(|n| test_res_block(Ok(n))) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ let n = opt?; +LL + test_res_block(Ok(n)) + | + +error: use the question mark operator instead of an `and_then` call + --> tests/ui/return_and_then.rs:30:9 + | +LL | Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ let x = Some("")?; +LL + if x.len() > 2 { Some(3) } else { None } + | + +error: use the question mark operator instead of an `and_then` call + --> tests/ui/return_and_then.rs:35:9 + | +LL | / Some(match (vec![1, 2, 3], vec![1, 2, 4]) { +LL | | (a, _) if a.len() > 1 => a, +LL | | (_, b) => b, +LL | | }) +LL | | .and_then(|x| if x.len() > 2 { Some(3) } else { None }) + | |_______________________________________________________________^ + | +help: try + | +LL ~ let x = Some(match (vec![1, 2, 3], vec![1, 2, 4]) { +LL + (a, _) if a.len() > 1 => a, +LL + (_, b) => b, +LL + })?; +LL + if x.len() > 2 { Some(3) } else { None } + | + +error: aborting due to 7 previous errors + diff --git a/tests/ui/size_of_in_element_count/expressions.rs b/tests/ui/size_of_in_element_count/expressions.rs index 91b7ea3922c5..f405ba200acd 100644 --- a/tests/ui/size_of_in_element_count/expressions.rs +++ b/tests/ui/size_of_in_element_count/expressions.rs @@ -8,11 +8,11 @@ fn main() { const SIZE: usize = 128; const HALF_SIZE: usize = SIZE / 2; const DOUBLE_SIZE: usize = SIZE * 2; - let mut x = [2u8; SIZE]; - let mut y = [2u8; SIZE]; + let mut x = [2u16; SIZE]; + let mut y = [2u16; SIZE]; // Count expression involving multiplication of size_of (Should trigger the lint) - unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::() * SIZE) }; + unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::() * SIZE) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` // Count expression involving nested multiplications of size_of (Should trigger the lint) @@ -20,22 +20,19 @@ fn main() { //~^ ERROR: found a count of bytes instead of a count of elements of `T` // Count expression involving divisions of size_of (Should trigger the lint) - unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::() / 2) }; + unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::() / 2) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` // Count expression involving divisions by size_of (Should not trigger the lint) - unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / size_of::()) }; + unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / size_of::()) }; // Count expression involving divisions by multiple size_of (Should not trigger the lint) - unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 * size_of::())) }; + unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 * size_of::())) }; // Count expression involving recursive divisions by size_of (Should trigger the lint) - unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::())) }; + unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::())) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` // No size_of calls (Should not trigger the lint) unsafe { copy(x.as_ptr(), y.as_mut_ptr(), SIZE) }; - - // Different types for pointee and size_of (Should not trigger the lint) - unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::() / 2 * SIZE) }; } diff --git a/tests/ui/size_of_in_element_count/expressions.stderr b/tests/ui/size_of_in_element_count/expressions.stderr index 6396afd7f395..74be0d7773df 100644 --- a/tests/ui/size_of_in_element_count/expressions.stderr +++ b/tests/ui/size_of_in_element_count/expressions.stderr @@ -1,8 +1,8 @@ error: found a count of bytes instead of a count of elements of `T` --> tests/ui/size_of_in_element_count/expressions.rs:15:62 | -LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::() * SIZE) }; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::() * SIZE) }; + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type = note: `-D clippy::size-of-in-element-count` implied by `-D warnings` @@ -19,16 +19,16 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * si error: found a count of bytes instead of a count of elements of `T` --> tests/ui/size_of_in_element_count/expressions.rs:23:47 | -LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::() / 2) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::() / 2) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` --> tests/ui/size_of_in_element_count/expressions.rs:33:47 | -LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::())) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::())) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type diff --git a/tests/ui/size_of_in_element_count/functions.rs b/tests/ui/size_of_in_element_count/functions.rs index 3501cbdf81cf..af18136a1dbe 100644 --- a/tests/ui/size_of_in_element_count/functions.rs +++ b/tests/ui/size_of_in_element_count/functions.rs @@ -11,57 +11,52 @@ fn main() { const SIZE: usize = 128; const HALF_SIZE: usize = SIZE / 2; const DOUBLE_SIZE: usize = SIZE * 2; - let mut x = [2u8; SIZE]; - let mut y = [2u8; SIZE]; + let mut x = [2u16; SIZE]; + let mut y = [2u16; SIZE]; // Count is size_of (Should trigger the lint) - unsafe { copy_nonoverlapping::(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; + unsafe { copy_nonoverlapping::(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; + unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::()) }; + unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::()) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::()) }; + unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::()) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::()) }; + unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::()) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; + unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::() * SIZE) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { write_bytes(y.as_mut_ptr(), 0u8, size_of::() * SIZE) }; + unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::() * SIZE) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::() * SIZE) }; + slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); + //~^ ERROR: found a count of bytes instead of a count of elements of `T` + slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); //~^ ERROR: found a count of bytes instead of a count of elements of `T` - slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); + unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); + unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; + unsafe { y.as_mut_ptr().sub(size_of::()) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; + y.as_ptr().wrapping_sub(size_of::()); //~^ ERROR: found a count of bytes instead of a count of elements of `T` - - unsafe { y.as_mut_ptr().sub(size_of::()) }; + unsafe { y.as_ptr().add(size_of::()) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - y.as_ptr().wrapping_sub(size_of::()); + y.as_mut_ptr().wrapping_add(size_of::()); //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { y.as_ptr().add(size_of::()) }; + unsafe { y.as_ptr().offset(size_of::() as isize) }; //~^ ERROR: found a count of bytes instead of a count of elements of `T` - y.as_mut_ptr().wrapping_add(size_of::()); - //~^ ERROR: found a count of bytes instead of a count of elements of `T` - unsafe { y.as_ptr().offset(size_of::() as isize) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` - y.as_mut_ptr().wrapping_offset(size_of::() as isize); + y.as_mut_ptr().wrapping_offset(size_of::() as isize); //~^ ERROR: found a count of bytes instead of a count of elements of `T` } diff --git a/tests/ui/size_of_in_element_count/functions.stderr b/tests/ui/size_of_in_element_count/functions.stderr index abde7dc7cd2d..de54789b2251 100644 --- a/tests/ui/size_of_in_element_count/functions.stderr +++ b/tests/ui/size_of_in_element_count/functions.stderr @@ -1,8 +1,8 @@ error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:18:68 + --> tests/ui/size_of_in_element_count/functions.rs:18:69 | -LL | unsafe { copy_nonoverlapping::(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; - | ^^^^^^^^^^^^^^^ +LL | unsafe { copy_nonoverlapping::(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type = note: `-D clippy::size-of-in-element-count` implied by `-D warnings` @@ -19,40 +19,40 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x error: found a count of bytes instead of a count of elements of `T` --> tests/ui/size_of_in_element_count/functions.rs:23:49 | -LL | unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; - | ^^^^^^^^^^^^^^^ +LL | unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` --> tests/ui/size_of_in_element_count/functions.rs:25:64 | -LL | unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::()) }; - | ^^^^^^^^^^^^^^^ +LL | unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::()) }; + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` --> tests/ui/size_of_in_element_count/functions.rs:27:51 | -LL | unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::()) }; - | ^^^^^^^^^^^^^^^ +LL | unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::()) }; + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` --> tests/ui/size_of_in_element_count/functions.rs:29:66 | -LL | unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::()) }; - | ^^^^^^^^^^^^^^^ +LL | unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::()) }; + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` --> tests/ui/size_of_in_element_count/functions.rs:32:47 | -LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; - | ^^^^^^^^^^^^^^^ +LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type @@ -65,108 +65,92 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:37:46 + --> tests/ui/size_of_in_element_count/functions.rs:37:66 | -LL | unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::() * SIZE) }; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::() * SIZE) }; + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:39:47 + --> tests/ui/size_of_in_element_count/functions.rs:40:46 | -LL | unsafe { write_bytes(y.as_mut_ptr(), 0u8, size_of::() * SIZE) }; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:42:66 + --> tests/ui/size_of_in_element_count/functions.rs:42:38 | -LL | unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::() * SIZE) }; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:45:46 + --> tests/ui/size_of_in_element_count/functions.rs:45:49 | -LL | slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:47:38 + --> tests/ui/size_of_in_element_count/functions.rs:47:41 | -LL | slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:50:49 + --> tests/ui/size_of_in_element_count/functions.rs:50:33 | -LL | unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { y.as_mut_ptr().sub(size_of::()) }; + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:52:41 + --> tests/ui/size_of_in_element_count/functions.rs:52:29 | -LL | unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | y.as_ptr().wrapping_sub(size_of::()); + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:55:33 + --> tests/ui/size_of_in_element_count/functions.rs:54:29 | -LL | unsafe { y.as_mut_ptr().sub(size_of::()) }; - | ^^^^^^^^^^^^^^^ +LL | unsafe { y.as_ptr().add(size_of::()) }; + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:57:29 + --> tests/ui/size_of_in_element_count/functions.rs:56:33 | -LL | y.as_ptr().wrapping_sub(size_of::()); - | ^^^^^^^^^^^^^^^ +LL | y.as_mut_ptr().wrapping_add(size_of::()); + | ^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:59:29 + --> tests/ui/size_of_in_element_count/functions.rs:58:32 | -LL | unsafe { y.as_ptr().add(size_of::()) }; - | ^^^^^^^^^^^^^^^ +LL | unsafe { y.as_ptr().offset(size_of::() as isize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:61:33 + --> tests/ui/size_of_in_element_count/functions.rs:60:36 | -LL | y.as_mut_ptr().wrapping_add(size_of::()); - | ^^^^^^^^^^^^^^^ +LL | y.as_mut_ptr().wrapping_offset(size_of::() as isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type -error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:63:32 - | -LL | unsafe { y.as_ptr().offset(size_of::() as isize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type - -error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:65:36 - | -LL | y.as_mut_ptr().wrapping_offset(size_of::() as isize); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type - -error: aborting due to 21 previous errors +error: aborting due to 19 previous errors diff --git a/tests/ui/toplevel_ref_arg_non_rustfix.stderr b/tests/ui/toplevel_ref_arg_non_rustfix.stderr index fb8fb1a00901..26166e2fc8da 100644 --- a/tests/ui/toplevel_ref_arg_non_rustfix.stderr +++ b/tests/ui/toplevel_ref_arg_non_rustfix.stderr @@ -1,4 +1,4 @@ -error: `ref` directly on a function argument is ignored. Consider using a reference type instead +error: `ref` directly on a function parameter does not prevent taking ownership of the passed argument. Consider using a reference type instead --> tests/ui/toplevel_ref_arg_non_rustfix.rs:9:15 | LL | fn the_answer(ref mut x: u8) { @@ -7,7 +7,7 @@ LL | fn the_answer(ref mut x: u8) { = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::toplevel_ref_arg)]` -error: `ref` directly on a function argument is ignored. Consider using a reference type instead +error: `ref` directly on a function parameter does not prevent taking ownership of the passed argument. Consider using a reference type instead --> tests/ui/toplevel_ref_arg_non_rustfix.rs:20:24 | LL | fn fun_example(ref _x: usize) {} diff --git a/tests/ui/unnecessary_semicolon.edition2021.fixed b/tests/ui/unnecessary_semicolon.edition2021.fixed index 7a3b79553dea..343c88b98155 100644 --- a/tests/ui/unnecessary_semicolon.edition2021.fixed +++ b/tests/ui/unnecessary_semicolon.edition2021.fixed @@ -55,3 +55,9 @@ fn no_borrow_issue(a: u32, b: u32) { None => {}, } } + +fn issue14100() -> bool { + // Removing the `;` would make the block type be `()` instead of `!`, and this could no longer be + // cast into the `bool` function return type. + if return true {}; +} diff --git a/tests/ui/unnecessary_semicolon.edition2024.fixed b/tests/ui/unnecessary_semicolon.edition2024.fixed index d186d5e7ebc4..1cba5760eb0a 100644 --- a/tests/ui/unnecessary_semicolon.edition2024.fixed +++ b/tests/ui/unnecessary_semicolon.edition2024.fixed @@ -55,3 +55,9 @@ fn no_borrow_issue(a: u32, b: u32) { None => {}, } } + +fn issue14100() -> bool { + // Removing the `;` would make the block type be `()` instead of `!`, and this could no longer be + // cast into the `bool` function return type. + if return true {}; +} diff --git a/tests/ui/unnecessary_semicolon.rs b/tests/ui/unnecessary_semicolon.rs index 3028c5b27b34..6abbbd79aaf2 100644 --- a/tests/ui/unnecessary_semicolon.rs +++ b/tests/ui/unnecessary_semicolon.rs @@ -55,3 +55,9 @@ fn no_borrow_issue(a: u32, b: u32) { None => {}, }; } + +fn issue14100() -> bool { + // Removing the `;` would make the block type be `()` instead of `!`, and this could no longer be + // cast into the `bool` function return type. + if return true {}; +} diff --git a/tests/ui/write_literal.fixed b/tests/ui/write_literal.fixed index 3d216b76cbf3..f1def776e1bc 100644 --- a/tests/ui/write_literal.fixed +++ b/tests/ui/write_literal.fixed @@ -62,3 +62,19 @@ fn main() { writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4); //~^ ERROR: literal with an empty format string } + +fn issue_13959() { + let mut v = Vec::new(); + writeln!(v, "\""); + writeln!( + v, + " + foo + \\ + \\\\ + \" + \\\" + bar +" + ); +} diff --git a/tests/ui/write_literal.rs b/tests/ui/write_literal.rs index 79d6daa2e3b5..1b7df91b47e1 100644 --- a/tests/ui/write_literal.rs +++ b/tests/ui/write_literal.rs @@ -62,3 +62,20 @@ fn main() { writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4); //~^ ERROR: literal with an empty format string } + +fn issue_13959() { + let mut v = Vec::new(); + writeln!(v, "{}", r#"""#); + writeln!( + v, + "{}", + r#" + foo + \ + \\ + " + \" + bar +"# + ); +} diff --git a/tests/ui/write_literal.stderr b/tests/ui/write_literal.stderr index 9f4cdfd91e8a..35c93d567cd3 100644 --- a/tests/ui/write_literal.stderr +++ b/tests/ui/write_literal.stderr @@ -144,5 +144,41 @@ LL - writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4); LL + writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4); | -error: aborting due to 12 previous errors +error: literal with an empty format string + --> tests/ui/write_literal.rs:68:23 + | +LL | writeln!(v, "{}", r#"""#); + | ^^^^^^ + | +help: try + | +LL - writeln!(v, "{}", r#"""#); +LL + writeln!(v, "\""); + | + +error: literal with an empty format string + --> tests/ui/write_literal.rs:72:9 + | +LL | / r#" +LL | | foo +LL | | \ +LL | | \\ +... | +LL | | bar +LL | | "# + | |__^ + | +help: try + | +LL ~ " +LL + foo +LL + \\ +LL + \\\\ +LL + \" +LL + \\\" +LL + bar +LL ~ " + | + +error: aborting due to 14 previous errors diff --git a/util/gh-pages/index_template.html b/util/gh-pages/index_template.html index deb0ef0b4996..a9b646280030 100644 --- a/util/gh-pages/index_template.html +++ b/util/gh-pages/index_template.html @@ -24,14 +24,16 @@ Otherwise, have a great day =^.^= {# #} {# #} {# #} + {# #} + {# #} + {# #} {# #} {# #} - {# #}
{# #} {# #}
{# #}
Theme
{# #} - {# #} {# #} {# #} {# #} @@ -39,11 +41,12 @@ Otherwise, have a great day =^.^= {# #} {# #} {# #}
{# #}
{# #} + {# #}
{# #} {# #}
{# #}
{# #} - {# #} - {# #}
{# #} @@ -145,13 +148,13 @@ Otherwise, have a great day =^.^= {% for lint in lints %}
{# #} {# #} -
{# #}

{# #} {# #} @@ -227,9 +230,5 @@ Otherwise, have a great day =^.^= > {# #} {# #} {# #} - - {# #} - {# #} - {# #} {# #} {# #} diff --git a/util/gh-pages/script.js b/util/gh-pages/script.js index 34d76ad642ec..c942a6a05a10 100644 --- a/util/gh-pages/script.js +++ b/util/gh-pages/script.js @@ -1,3 +1,5 @@ +"use strict"; + window.searchState = { timeout: null, inputElem: document.getElementById("search-input"), @@ -124,13 +126,6 @@ function toggleElements(filter, value) { } } -function changeSetting(elem) { - if (elem.id === "disable-shortcuts") { - disableShortcuts = elem.checked; - storeValue(elem.id, elem.checked); - } -} - function onEachLazy(lazyArray, func) { const arr = Array.prototype.slice.call(lazyArray); for (const el of arr) { @@ -138,17 +133,9 @@ function onEachLazy(lazyArray, func) { } } -function highlightIfNeeded(lintId) { - onEachLazy(document.querySelectorAll(`#${lintId} pre > code:not(.hljs)`), el => { - hljs.highlightElement(el.parentElement) - el.classList.add("highlighted"); - }); -} - function expandLint(lintId) { const elem = document.querySelector(`#${lintId} > input[type="checkbox"]`); elem.checked = true; - highlightIfNeeded(lintId); } function lintAnchor(event) { @@ -194,13 +181,9 @@ function handleBlur(event, elementId) { } function toggleExpansion(expand) { - onEachLazy( - document.querySelectorAll("article"), - expand ? el => { - el.classList.remove("collapsed"); - highlightIfNeeded(el); - } : el => el.classList.add("collapsed"), - ); + for (const checkbox of document.querySelectorAll("article input[type=checkbox]")) { + checkbox.checked = expand; + } } // Returns the current URL without any query parameter or hash. @@ -535,7 +518,7 @@ function parseURLFilters() { for (const [corres_key, corres_value] of Object.entries(URL_PARAMS_CORRESPONDENCE)) { if (corres_value === key) { if (key !== "versions") { - const settings = new Set(value.split(",")); + const settings = new Set(value.split(",")); onEachLazy(document.querySelectorAll(`#lint-${key} ul input`), elem => { elem.checked = settings.has(elem.getAttribute("data-value")); updateFilter(elem, corres_key, true); @@ -555,12 +538,60 @@ function parseURLFilters() { } } -document.getElementById(`theme-choice`).value = loadValue("theme"); -let disableShortcuts = loadValue('disable-shortcuts') === "true"; -document.getElementById("disable-shortcuts").checked = disableShortcuts; +function addListeners() { + disableShortcutsButton.addEventListener("change", () => { + disableShortcuts = disableShortcutsButton.checked; + storeValue("disable-shortcuts", disableShortcuts); + }); -document.addEventListener("keypress", handleShortcut); -document.addEventListener("keydown", handleShortcut); + document.getElementById("expand-all").addEventListener("click", () => toggleExpansion(true)); + document.getElementById("collapse-all").addEventListener("click", () => toggleExpansion(false)); + + // A delegated listener to avoid the upfront cost of >1000 listeners + document.addEventListener("click", event => { + if (!event.target instanceof HTMLAnchorElement) { + return; + } + + if (event.target.classList.contains("lint-anchor")) { + lintAnchor(event); + } else if (event.target.classList.contains("copy-to-clipboard")) { + copyToClipboard(event); + } + }); + + document.addEventListener("keypress", handleShortcut); + document.addEventListener("keydown", handleShortcut); +} + +// Highlight code blocks only when they approach the viewport so that clicking the "Expand All" +// button doesn't take a long time +function highlightLazily() { + if (!'IntersectionObserver' in window) { + return; + } + const observer = new IntersectionObserver((entries) => { + for (const entry of entries) { + if (entry.isIntersecting) { + observer.unobserve(entry.target); + for (const code of entry.target.querySelectorAll("pre code")) { + hljs.highlightElement(code); + } + } + } + }); + for (const docs of document.querySelectorAll(".lint-docs")) { + observer.observe(docs); + } +} + +let disableShortcuts = loadValue("disable-shortcuts") === "true"; + +const disableShortcutsButton = document.getElementById("disable-shortcuts"); +disableShortcutsButton.checked = disableShortcuts; + +addListeners(); +highlightLazily(); generateSettings(); generateSearch(); diff --git a/util/gh-pages/style.css b/util/gh-pages/style.css index 896f2fdac767..3cc7a919c23a 100644 --- a/util/gh-pages/style.css +++ b/util/gh-pages/style.css @@ -1,9 +1,5 @@ blockquote { font-size: 1em; } -[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { - display: none !important; -} - .dropdown-menu { color: var(--fg); background: var(--theme-popup-bg); @@ -188,8 +184,8 @@ details { padding: .5em .5em 0; } -code { - white-space: pre !important; +pre { + padding: 0; } summary { diff --git a/util/gh-pages/theme.js b/util/gh-pages/theme.js index 90f57d4469d1..a5dfeed9e8c8 100644 --- a/util/gh-pages/theme.js +++ b/util/gh-pages/theme.js @@ -1,3 +1,5 @@ +"use strict"; + function storeValue(settingName, value) { try { localStorage.setItem(`clippy-lint-list-${settingName}`, value); @@ -57,4 +59,11 @@ function setTheme(theme, store) { } else { setTheme(theme, false); } + + const themeChoice = document.getElementById("theme-choice"); + + themeChoice.value = loadValue("theme"); + document.getElementById("theme-choice").addEventListener("change", (e) => { + setTheme(themeChoice.value, true); + }); })(); From 046451d0b4c3bf098afd0ea3bfa497ef665005c1 Mon Sep 17 00:00:00 2001 From: tiif Date: Thu, 6 Feb 2025 14:45:35 +0800 Subject: [PATCH 057/991] Throw ub error when invoking non-vararg shim with vararg import --- src/tools/miri/src/helpers.rs | 5 +++++ .../miri/src/shims/unix/linux/foreign_items.rs | 4 ++-- .../shims/vararg_caller_signature_mismatch.rs | 14 ++++++++++++++ .../shims/vararg_caller_signature_mismatch.stderr | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs create mode 100644 src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index a26f12cdfb1e..3815da9ad066 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -999,6 +999,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>, { self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?; + if abi.c_variadic { + throw_ub_format!( + "calling a non-variadic function with a variadic caller-side signature" + ); + } check_arg_count(args) } diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 10af245dcc08..f5da7b0170b6 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -133,8 +133,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(ptr, dest)?; } "mremap" => { - let [old_address, old_size, new_size, flags] = - this.check_shim(abi, Conv::C, link_name, args)?; + let ([old_address, old_size, new_size, flags], _) = + this.check_shim_variadic(abi, Conv::C, link_name, args)?; let ptr = this.mremap(old_address, old_size, new_size, flags)?; this.write_scalar(ptr, dest)?; } diff --git a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs new file mode 100644 index 000000000000..515e467fb54d --- /dev/null +++ b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs @@ -0,0 +1,14 @@ +//@ignore-target: windows # No libc pipe on Windows + +// Declare a non-variadic function as variadic. +extern "C" { + fn pipe(fds: *mut std::ffi::c_int, ...) -> std::ffi::c_int; +} + +// Test the error caused by invoking non-vararg shim with a vararg import. +fn main() { + let mut fds = [-1, -1]; + let res = unsafe { pipe(fds.as_mut_ptr()) }; + //~^ ERROR: calling a non-variadic function with a variadic caller-side signature + assert_eq!(res, 0); +} diff --git a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr new file mode 100644 index 000000000000..2782f3b3269c --- /dev/null +++ b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: calling a non-variadic function with a variadic caller-side signature + --> tests/fail/shims/vararg_caller_signature_mismatch.rs:LL:CC + | +LL | let res = unsafe { pipe(fds.as_mut_ptr()) }; + | ^^^^^^^^^^^^^^^^^^^^^^ calling a non-variadic function with a variadic caller-side signature + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/shims/vararg_caller_signature_mismatch.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From 550d2175500b806827afcd13e190ad3e1e2bdaa8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 6 Feb 2025 17:20:51 +0100 Subject: [PATCH 058/991] inline a once-used function --- src/tools/miri/src/helpers.rs | 45 +++++++++++++---------------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 3815da9ad066..c1fed82f5288 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1020,7 +1020,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>, { self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?; - check_vargarg_fixed_arg_count(link_name, abi, args) + if !abi.c_variadic { + throw_ub_format!( + "calling a variadic function with a non-variadic caller-side signature" + ); + } + if abi.fixed_count != u32::try_from(N).unwrap() { + throw_ub_format!( + "incorrect number of fixed arguments for variadic function `{}`: got {}, expected {N}", + link_name.as_str(), + abi.fixed_count + ) + } + if let Some(args) = args.split_first_chunk() { + return interp_ok(args); + } + panic!("mismatch between signature and `args` slice"); } /// Mark a machine allocation that was just created as immutable. @@ -1233,34 +1248,6 @@ pub fn check_min_vararg_count<'a, 'tcx, const N: usize>( ) } -/// Check the number of fixed args of a vararg function. -/// Returns a tuple that consisting of an array of fixed args, and a slice of varargs. -fn check_vargarg_fixed_arg_count<'a, 'tcx, const N: usize>( - link_name: Symbol, - abi: &FnAbi<'tcx, Ty<'tcx>>, - args: &'a [OpTy<'tcx>], -) -> InterpResult<'tcx, (&'a [OpTy<'tcx>; N], &'a [OpTy<'tcx>])> { - if !abi.c_variadic { - throw_ub_format!("calling a variadic function with a non-variadic caller-side signature"); - } - if abi.fixed_count != u32::try_from(N).unwrap() { - throw_ub_format!( - "incorrect number of fixed arguments for variadic function `{}`: got {}, expected {N}", - link_name.as_str(), - abi.fixed_count - ) - } - if let Some(args) = args.split_first_chunk() { - return interp_ok(args); - } - throw_ub_format!( - "incorrect number of arguments for `{}`: got {}, expected at least {}", - link_name.as_str(), - args.len(), - N - ) -} - pub fn isolation_abort_error<'tcx>(name: &str) -> InterpResult<'tcx> { throw_machine_stop!(TerminationInfo::UnsupportedInIsolation(format!( "{name} not available when isolation is enabled", From 8a9d55012d48d121e8552ccd72d86f1f5a420abf Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 5 Feb 2025 18:33:33 +0100 Subject: [PATCH 059/991] Use edition 2024 when running `cargo dev lint` --- clippy_dev/src/lint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_dev/src/lint.rs b/clippy_dev/src/lint.rs index 125195397e6c..beae7be7b304 100644 --- a/clippy_dev/src/lint.rs +++ b/clippy_dev/src/lint.rs @@ -17,7 +17,7 @@ pub fn run<'a>(path: &str, args: impl Iterator) { .args(["run", "--bin", "clippy-driver", "--"]) .args(["-L", "./target/debug"]) .args(["-Z", "no-codegen"]) - .args(["--edition", "2021"]) + .args(["--edition", "2024"]) .arg(path) .args(args) // Prevent rustc from creating `rustc-ice-*` files the console output is enough. From af04c0dfa1c32799762935c25554909b1ea53b23 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 6 Feb 2025 17:24:44 +0100 Subject: [PATCH 060/991] some more argument checking cleanup --- src/tools/miri/src/helpers.rs | 19 ++++++-- src/tools/miri/src/intrinsics/atomic.rs | 16 +++---- src/tools/miri/src/intrinsics/mod.rs | 48 +++++++++---------- src/tools/miri/src/intrinsics/simd.rs | 34 ++++++------- src/tools/miri/src/shims/panic.rs | 4 +- .../miri/src/shims/unix/linux_like/sync.rs | 8 ---- .../function_calls/check_arg_count_abort.rs | 2 +- .../check_arg_count_abort.stderr | 4 +- .../check_arg_count_too_few_args.rs | 2 +- .../check_arg_count_too_few_args.stderr | 4 +- .../check_arg_count_too_many_args.rs | 2 +- .../check_arg_count_too_many_args.stderr | 4 +- 12 files changed, 77 insertions(+), 70 deletions(-) diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index c1fed82f5288..12e7d0f1a62c 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -999,12 +999,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>, { self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?; + if abi.c_variadic { throw_ub_format!( "calling a non-variadic function with a variadic caller-side signature" ); } - check_arg_count(args) + if let Ok(ops) = args.try_into() { + return interp_ok(ops); + } + throw_ub_format!( + "incorrect number of arguments for `{link_name}`: got {}, expected {}", + args.len(), + N + ) } /// Check shim for variadic function. @@ -1020,6 +1028,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>, { self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?; + if !abi.c_variadic { throw_ub_format!( "calling a variadic function with a non-variadic caller-side signature" @@ -1219,7 +1228,7 @@ impl<'tcx> MiriMachine<'tcx> { } /// Check that the number of args is what we expect. -pub fn check_arg_count<'a, 'tcx, const N: usize>( +pub fn check_intrinsic_arg_count<'a, 'tcx, const N: usize>( args: &'a [OpTy<'tcx>], ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> where @@ -1228,7 +1237,11 @@ where if let Ok(ops) = args.try_into() { return interp_ok(ops); } - throw_ub_format!("incorrect number of arguments: got {}, expected {}", args.len(), N) + throw_ub_format!( + "incorrect number of arguments for intrinsic: got {}, expected {}", + args.len(), + N + ) } /// Check that the number of varargs is at least the minimum what we expect. diff --git a/src/tools/miri/src/intrinsics/atomic.rs b/src/tools/miri/src/intrinsics/atomic.rs index 8507b0f49ded..e1e9ebb4e9d9 100644 --- a/src/tools/miri/src/intrinsics/atomic.rs +++ b/src/tools/miri/src/intrinsics/atomic.rs @@ -1,7 +1,7 @@ use rustc_middle::mir::BinOp; use rustc_middle::{mir, ty}; -use self::helpers::check_arg_count; +use self::helpers::check_intrinsic_arg_count; use crate::*; pub enum AtomicOp { @@ -131,7 +131,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [place] = check_arg_count(args)?; + let [place] = check_intrinsic_arg_count(args)?; let place = this.deref_pointer(place)?; // Perform atomic load. @@ -144,7 +144,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { fn atomic_store(&mut self, args: &[OpTy<'tcx>], atomic: AtomicWriteOrd) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [place, val] = check_arg_count(args)?; + let [place, val] = check_intrinsic_arg_count(args)?; let place = this.deref_pointer(place)?; // Perform regular load. @@ -159,7 +159,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { args: &[OpTy<'tcx>], atomic: AtomicFenceOrd, ) -> InterpResult<'tcx> { - let [] = check_arg_count(args)?; + let [] = check_intrinsic_arg_count(args)?; let _ = atomic; //FIXME: compiler fences are currently ignored interp_ok(()) @@ -171,7 +171,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { atomic: AtomicFenceOrd, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [] = check_arg_count(args)?; + let [] = check_intrinsic_arg_count(args)?; this.atomic_fence(atomic)?; interp_ok(()) } @@ -185,7 +185,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [place, rhs] = check_arg_count(args)?; + let [place, rhs] = check_intrinsic_arg_count(args)?; let place = this.deref_pointer(place)?; let rhs = this.read_immediate(rhs)?; @@ -226,7 +226,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [place, new] = check_arg_count(args)?; + let [place, new] = check_intrinsic_arg_count(args)?; let place = this.deref_pointer(place)?; let new = this.read_scalar(new)?; @@ -245,7 +245,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [place, expect_old, new] = check_arg_count(args)?; + let [place, expect_old, new] = check_intrinsic_arg_count(args)?; let place = this.deref_pointer(place)?; let expect_old = this.read_immediate(expect_old)?; // read as immediate for the sake of `binary_op()` let new = this.read_scalar(new)?; diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index bce78adcaea4..ec4fdfe0bacf 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::{self, FloatTy}; use rustc_span::{Symbol, sym}; use self::atomic::EvalContextExt as _; -use self::helpers::{ToHost, ToSoft, check_arg_count}; +use self::helpers::{ToHost, ToSoft, check_intrinsic_arg_count}; use self::simd::EvalContextExt as _; use crate::*; @@ -104,24 +104,24 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Raw memory accesses "volatile_load" => { - let [place] = check_arg_count(args)?; + let [place] = check_intrinsic_arg_count(args)?; let place = this.deref_pointer(place)?; this.copy_op(&place, dest)?; } "volatile_store" => { - let [place, dest] = check_arg_count(args)?; + let [place, dest] = check_intrinsic_arg_count(args)?; let place = this.deref_pointer(place)?; this.copy_op(dest, &place)?; } "volatile_set_memory" => { - let [ptr, val_byte, count] = check_arg_count(args)?; + let [ptr, val_byte, count] = check_intrinsic_arg_count(args)?; this.write_bytes_intrinsic(ptr, val_byte, count, "volatile_set_memory")?; } // Memory model / provenance manipulation "ptr_mask" => { - let [ptr, mask] = check_arg_count(args)?; + let [ptr, mask] = check_intrinsic_arg_count(args)?; let ptr = this.read_pointer(ptr)?; let mask = this.read_target_usize(mask)?; @@ -137,7 +137,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // ``` // Would not be considered UB, or the other way around (`is_val_statically_known(0)`). "is_val_statically_known" => { - let [_arg] = check_arg_count(args)?; + let [_arg] = check_intrinsic_arg_count(args)?; // FIXME: should we check for validity here? It's tricky because we do not have a // place. Codegen does not seem to set any attributes like `noundef` for intrinsic // calls, so we don't *have* to do anything. @@ -146,7 +146,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "floorf16" | "ceilf16" | "truncf16" | "roundf16" | "rintf16" => { - let [f] = check_arg_count(args)?; + let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f16()?; let mode = match intrinsic_name { "floorf16" => Round::TowardNegative, @@ -161,7 +161,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => { - let [f] = check_arg_count(args)?; + let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; let mode = match intrinsic_name { "floorf32" => Round::TowardNegative, @@ -176,7 +176,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "floorf64" | "ceilf64" | "truncf64" | "roundf64" | "rintf64" => { - let [f] = check_arg_count(args)?; + let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; let mode = match intrinsic_name { "floorf64" => Round::TowardNegative, @@ -191,7 +191,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "floorf128" | "ceilf128" | "truncf128" | "roundf128" | "rintf128" => { - let [f] = check_arg_count(args)?; + let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f128()?; let mode = match intrinsic_name { "floorf128" => Round::TowardNegative, @@ -216,7 +216,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "log10f32" | "log2f32" => { - let [f] = check_arg_count(args)?; + let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; // Using host floats except for sqrt (but it's fine, these operations do not have // guaranteed precision). @@ -244,7 +244,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "log10f64" | "log2f64" => { - let [f] = check_arg_count(args)?; + let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; // Using host floats except for sqrt (but it's fine, these operations do not have // guaranteed precision). @@ -264,7 +264,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "fmaf32" => { - let [a, b, c] = check_arg_count(args)?; + let [a, b, c] = check_intrinsic_arg_count(args)?; let a = this.read_scalar(a)?.to_f32()?; let b = this.read_scalar(b)?.to_f32()?; let c = this.read_scalar(c)?.to_f32()?; @@ -274,7 +274,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "fmaf64" => { - let [a, b, c] = check_arg_count(args)?; + let [a, b, c] = check_intrinsic_arg_count(args)?; let a = this.read_scalar(a)?.to_f64()?; let b = this.read_scalar(b)?.to_f64()?; let c = this.read_scalar(c)?.to_f64()?; @@ -285,7 +285,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "fmuladdf32" => { - let [a, b, c] = check_arg_count(args)?; + let [a, b, c] = check_intrinsic_arg_count(args)?; let a = this.read_scalar(a)?.to_f32()?; let b = this.read_scalar(b)?.to_f32()?; let c = this.read_scalar(c)?.to_f32()?; @@ -300,7 +300,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "fmuladdf64" => { - let [a, b, c] = check_arg_count(args)?; + let [a, b, c] = check_intrinsic_arg_count(args)?; let a = this.read_scalar(a)?.to_f64()?; let b = this.read_scalar(b)?.to_f64()?; let c = this.read_scalar(c)?.to_f64()?; @@ -316,7 +316,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "powf32" => { - let [f1, f2] = check_arg_count(args)?; + let [f1, f2] = check_intrinsic_arg_count(args)?; let f1 = this.read_scalar(f1)?.to_f32()?; let f2 = this.read_scalar(f2)?.to_f32()?; // Using host floats (but it's fine, this operation does not have guaranteed precision). @@ -325,7 +325,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "powf64" => { - let [f1, f2] = check_arg_count(args)?; + let [f1, f2] = check_intrinsic_arg_count(args)?; let f1 = this.read_scalar(f1)?.to_f64()?; let f2 = this.read_scalar(f2)?.to_f64()?; // Using host floats (but it's fine, this operation does not have guaranteed precision). @@ -335,7 +335,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "powif32" => { - let [f, i] = check_arg_count(args)?; + let [f, i] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; let i = this.read_scalar(i)?.to_i32()?; // Using host floats (but it's fine, this operation does not have guaranteed precision). @@ -344,7 +344,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "powif64" => { - let [f, i] = check_arg_count(args)?; + let [f, i] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; let i = this.read_scalar(i)?.to_i32()?; // Using host floats (but it's fine, this operation does not have guaranteed precision). @@ -360,7 +360,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "fdiv_algebraic" | "frem_algebraic" => { - let [a, b] = check_arg_count(args)?; + let [a, b] = check_intrinsic_arg_count(args)?; let a = this.read_immediate(a)?; let b = this.read_immediate(b)?; let op = match intrinsic_name { @@ -383,7 +383,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "fdiv_fast" | "frem_fast" => { - let [a, b] = check_arg_count(args)?; + let [a, b] = check_intrinsic_arg_count(args)?; let a = this.read_immediate(a)?; let b = this.read_immediate(b)?; let op = match intrinsic_name { @@ -427,7 +427,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "float_to_int_unchecked" => { - let [val] = check_arg_count(args)?; + let [val] = check_intrinsic_arg_count(args)?; let val = this.read_immediate(val)?; let res = this @@ -444,7 +444,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Other "breakpoint" => { - let [] = check_arg_count(args)?; + let [] = check_intrinsic_arg_count(args)?; // normally this would raise a SIGTRAP, which aborts if no debugger is connected throw_machine_stop!(TerminationInfo::Abort(format!("trace/breakpoint trap"))) } diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index 45e316b190a6..339d7161374b 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -7,7 +7,9 @@ use rustc_middle::ty::layout::LayoutOf; use rustc_middle::{mir, ty}; use rustc_span::{Symbol, sym}; -use crate::helpers::{ToHost, ToSoft, bool_to_simd_element, check_arg_count, simd_element_to_bool}; +use crate::helpers::{ + ToHost, ToSoft, bool_to_simd_element, check_intrinsic_arg_count, simd_element_to_bool, +}; use crate::*; #[derive(Copy, Clone)] @@ -50,7 +52,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "bswap" | "bitreverse" => { - let [op] = check_arg_count(args)?; + let [op] = check_intrinsic_arg_count(args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -197,7 +199,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { => { use mir::BinOp; - let [left, right] = check_arg_count(args)?; + let [left, right] = check_intrinsic_arg_count(args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -288,7 +290,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "fma" | "relaxed_fma" => { - let [a, b, c] = check_arg_count(args)?; + let [a, b, c] = check_intrinsic_arg_count(args)?; let (a, a_len) = this.project_to_simd(a)?; let (b, b_len) = this.project_to_simd(b)?; let (c, c_len) = this.project_to_simd(c)?; @@ -352,7 +354,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "reduce_min" => { use mir::BinOp; - let [op] = check_arg_count(args)?; + let [op] = check_intrinsic_arg_count(args)?; let (op, op_len) = this.project_to_simd(op)?; let imm_from_bool = @@ -415,7 +417,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "reduce_mul_ordered" => { use mir::BinOp; - let [op, init] = check_arg_count(args)?; + let [op, init] = check_intrinsic_arg_count(args)?; let (op, op_len) = this.project_to_simd(op)?; let init = this.read_immediate(init)?; @@ -433,7 +435,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_immediate(*res, dest)?; } "select" => { - let [mask, yes, no] = check_arg_count(args)?; + let [mask, yes, no] = check_intrinsic_arg_count(args)?; let (mask, mask_len) = this.project_to_simd(mask)?; let (yes, yes_len) = this.project_to_simd(yes)?; let (no, no_len) = this.project_to_simd(no)?; @@ -455,7 +457,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Variant of `select` that takes a bitmask rather than a "vector of bool". "select_bitmask" => { - let [mask, yes, no] = check_arg_count(args)?; + let [mask, yes, no] = check_intrinsic_arg_count(args)?; let (yes, yes_len) = this.project_to_simd(yes)?; let (no, no_len) = this.project_to_simd(no)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -529,7 +531,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Converts a "vector of bool" into a bitmask. "bitmask" => { - let [op] = check_arg_count(args)?; + let [op] = check_intrinsic_arg_count(args)?; let (op, op_len) = this.project_to_simd(op)?; let bitmask_len = op_len.next_multiple_of(8); if bitmask_len > 64 { @@ -577,7 +579,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "cast" | "as" | "cast_ptr" | "expose_provenance" | "with_exposed_provenance" => { - let [op] = check_arg_count(args)?; + let [op] = check_intrinsic_arg_count(args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -634,7 +636,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "shuffle_generic" => { - let [left, right] = check_arg_count(args)?; + let [left, right] = check_intrinsic_arg_count(args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -664,7 +666,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "shuffle" => { - let [left, right, index] = check_arg_count(args)?; + let [left, right, index] = check_intrinsic_arg_count(args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; let (index, index_len) = this.project_to_simd(index)?; @@ -695,7 +697,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "gather" => { - let [passthru, ptrs, mask] = check_arg_count(args)?; + let [passthru, ptrs, mask] = check_intrinsic_arg_count(args)?; let (passthru, passthru_len) = this.project_to_simd(passthru)?; let (ptrs, ptrs_len) = this.project_to_simd(ptrs)?; let (mask, mask_len) = this.project_to_simd(mask)?; @@ -721,7 +723,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "scatter" => { - let [value, ptrs, mask] = check_arg_count(args)?; + let [value, ptrs, mask] = check_intrinsic_arg_count(args)?; let (value, value_len) = this.project_to_simd(value)?; let (ptrs, ptrs_len) = this.project_to_simd(ptrs)?; let (mask, mask_len) = this.project_to_simd(mask)?; @@ -741,7 +743,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "masked_load" => { - let [mask, ptr, default] = check_arg_count(args)?; + let [mask, ptr, default] = check_intrinsic_arg_count(args)?; let (mask, mask_len) = this.project_to_simd(mask)?; let ptr = this.read_pointer(ptr)?; let (default, default_len) = this.project_to_simd(default)?; @@ -767,7 +769,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "masked_store" => { - let [mask, ptr, vals] = check_arg_count(args)?; + let [mask, ptr, vals] = check_intrinsic_arg_count(args)?; let (mask, mask_len) = this.project_to_simd(mask)?; let ptr = this.read_pointer(ptr)?; let (vals, vals_len) = this.project_to_simd(vals)?; diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index 83f331bb173d..fc58d88591f8 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -15,7 +15,7 @@ use rustc_abi::ExternAbi; use rustc_middle::{mir, ty}; use rustc_target::spec::PanicStrategy; -use self::helpers::check_arg_count; +use self::helpers::check_intrinsic_arg_count; use crate::*; /// Holds all of the relevant data for when unwinding hits a `try` frame. @@ -77,7 +77,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // a pointer to `Box`. // Get all the arguments. - let [try_fn, data, catch_fn] = check_arg_count(args)?; + let [try_fn, data, catch_fn] = check_intrinsic_arg_count(args)?; let try_fn = this.read_pointer(try_fn)?; let data = this.read_immediate(data)?; let catch_fn = this.read_pointer(catch_fn)?; diff --git a/src/tools/miri/src/shims/unix/linux_like/sync.rs b/src/tools/miri/src/shims/unix/linux_like/sync.rs index 280bee4800fe..86e8b57824c2 100644 --- a/src/tools/miri/src/shims/unix/linux_like/sync.rs +++ b/src/tools/miri/src/shims/unix/linux_like/sync.rs @@ -13,14 +13,6 @@ pub fn futex<'tcx>( varargs: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { - // The amount of arguments used depends on the type of futex operation. - // The full futex syscall takes six arguments (excluding the syscall - // number), which is also the maximum amount of arguments a linux syscall - // can take on most architectures. - // However, not all futex operations use all six arguments. The unused ones - // may or may not be left out from the `syscall()` call. - // Therefore we don't use `check_arg_count` here, but only check for the - // number of arguments to fall within a range. let [addr, op, val] = check_min_vararg_count("`syscall(SYS_futex, ...)`", varargs)?; // The first three arguments (after the syscall number itself) are the same to all futex operations: diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.rs b/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.rs index 967a78bf8318..db7bd223bd45 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.rs +++ b/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.rs @@ -5,6 +5,6 @@ fn main() { unsafe { abort(1); - //~^ ERROR: Undefined Behavior: incorrect number of arguments: got 1, expected 0 + //~^ ERROR: Undefined Behavior: incorrect number of arguments for `abort`: got 1, expected 0 } } diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.stderr b/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.stderr index 687d0538b3c7..3c81ba4e1417 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.stderr +++ b/src/tools/miri/tests/fail/function_calls/check_arg_count_abort.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: incorrect number of arguments: got 1, expected 0 +error: Undefined Behavior: incorrect number of arguments for `abort`: got 1, expected 0 --> tests/fail/function_calls/check_arg_count_abort.rs:LL:CC | LL | abort(1); - | ^^^^^^^^ incorrect number of arguments: got 1, expected 0 + | ^^^^^^^^ incorrect number of arguments for `abort`: got 1, expected 0 | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.rs b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.rs index 223c95ffca46..41aebea2d8ad 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.rs +++ b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.rs @@ -4,6 +4,6 @@ fn main() { } unsafe { - let _ = malloc(); //~ ERROR: Undefined Behavior: incorrect number of arguments: got 0, expected 1 + let _ = malloc(); //~ ERROR: Undefined Behavior: incorrect number of arguments for `malloc`: got 0, expected 1 }; } diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.stderr b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.stderr index d778eae64fa4..eacd4045ae05 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.stderr +++ b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_few_args.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: incorrect number of arguments: got 0, expected 1 +error: Undefined Behavior: incorrect number of arguments for `malloc`: got 0, expected 1 --> tests/fail/function_calls/check_arg_count_too_few_args.rs:LL:CC | LL | let _ = malloc(); - | ^^^^^^^^ incorrect number of arguments: got 0, expected 1 + | ^^^^^^^^ incorrect number of arguments for `malloc`: got 0, expected 1 | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.rs b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.rs index 7ee9c40bf7a4..1f5c509c6666 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.rs +++ b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.rs @@ -4,6 +4,6 @@ fn main() { } unsafe { - let _ = malloc(1, 2); //~ ERROR: Undefined Behavior: incorrect number of arguments: got 2, expected 1 + let _ = malloc(1, 2); //~ ERROR: Undefined Behavior: incorrect number of arguments for `malloc`: got 2, expected 1 }; } diff --git a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.stderr b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.stderr index dfec2a862870..42d5e98c01af 100644 --- a/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.stderr +++ b/src/tools/miri/tests/fail/function_calls/check_arg_count_too_many_args.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: incorrect number of arguments: got 2, expected 1 +error: Undefined Behavior: incorrect number of arguments for `malloc`: got 2, expected 1 --> tests/fail/function_calls/check_arg_count_too_many_args.rs:LL:CC | LL | let _ = malloc(1, 2); - | ^^^^^^^^^^^^ incorrect number of arguments: got 2, expected 1 + | ^^^^^^^^^^^^ incorrect number of arguments for `malloc`: got 2, expected 1 | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information From 0e42ba908c6b58674a979ff705bd517ad6cb03f0 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 5 Feb 2025 18:33:33 +0100 Subject: [PATCH 061/991] Permit specifying a non-default edition when linting file `cargo dev lint /tmp/file.rs -- --edition 2021` will select edition 2021. --- clippy_dev/src/lint.rs | 4 ++-- clippy_dev/src/main.rs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/clippy_dev/src/lint.rs b/clippy_dev/src/lint.rs index beae7be7b304..e0e036757d56 100644 --- a/clippy_dev/src/lint.rs +++ b/clippy_dev/src/lint.rs @@ -2,7 +2,7 @@ use crate::utils::{cargo_clippy_path, exit_if_err}; use std::process::{self, Command}; use std::{env, fs}; -pub fn run<'a>(path: &str, args: impl Iterator) { +pub fn run<'a>(path: &str, edition: &str, args: impl Iterator) { let is_file = match fs::metadata(path) { Ok(metadata) => metadata.is_file(), Err(e) => { @@ -17,7 +17,7 @@ pub fn run<'a>(path: &str, args: impl Iterator) { .args(["run", "--bin", "clippy-driver", "--"]) .args(["-L", "./target/debug"]) .args(["-Z", "no-codegen"]) - .args(["--edition", "2024"]) + .args(["--edition", edition]) .arg(path) .args(args) // Prevent rustc from creating `rustc-ice-*` files the console output is enough. diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs index 56ed60256f16..93a74ba83871 100644 --- a/clippy_dev/src/main.rs +++ b/clippy_dev/src/main.rs @@ -68,7 +68,7 @@ fn main() { RemoveSubcommand::VscodeTasks => setup::vscode::remove_tasks(), }, DevCommand::Serve { port, lint } => serve::run(port, lint), - DevCommand::Lint { path, args } => lint::run(&path, args.iter()), + DevCommand::Lint { path, edition, args } => lint::run(&path, &edition, args.iter()), DevCommand::RenameLint { old_name, new_name, @@ -206,6 +206,9 @@ enum DevCommand { /// cargo dev lint file.rs -- -W clippy::pedantic {n} /// cargo dev lint ~/my-project -- -- -W clippy::pedantic Lint { + /// The Rust edition to use + #[arg(long, default_value = "2024")] + edition: String, /// The path to a file or package directory to lint path: String, /// Pass extra arguments to cargo/clippy-driver From 93ef8089afa10c86a03627f6f3291451343f28e6 Mon Sep 17 00:00:00 2001 From: Aphek Date: Thu, 6 Feb 2025 23:40:49 -0300 Subject: [PATCH 062/991] Revert vita's c_char back to i8 --- library/core/src/ffi/primitives.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/core/src/ffi/primitives.rs b/library/core/src/ffi/primitives.rs index ece3c7538dab..6495e61b346f 100644 --- a/library/core/src/ffi/primitives.rs +++ b/library/core/src/ffi/primitives.rs @@ -39,7 +39,6 @@ mod c_char_definition { // These are the targets on which c_char is unsigned. Usually the // signedness is the same for all target_os values on a given architecture // but there are some exceptions (see isSignedCharDefault() in clang). - // // aarch64: // Section 10 "Arm C and C++ language mappings" in Procedure Call Standard for the Arm® // 64-bit Architecture (AArch64) says C/C++ char is unsigned byte. @@ -97,14 +96,19 @@ mod c_char_definition { // are promoted to int as if from type signed char by default, unless the /J compilation // option is used." // https://learn.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-170#character-types + // Vita: + // Chars are signed by default on the Vita, and VITASDK follows that convention. + // https://github.com/vitasdk/buildscripts/blob/09c533b771591ecde88864b6acad28ffb688dbd4/patches/gcc/0001-gcc-10.patch#L33-L34 + // // L4Re: - // The kernel builds with -funsigned-char on all targets (but useserspace follows the + // The kernel builds with -funsigned-char on all targets (but userspace follows the // architecture defaults). As we only have a target for userspace apps so there are no // special cases for L4Re below. // https://github.com/rust-lang/rust/pull/132975#issuecomment-2484645240 if #[cfg(all( not(windows), not(target_vendor = "apple"), + not(target_os = "vita"), any( target_arch = "aarch64", target_arch = "arm", From 89fd6d0e26fd198051b458501a349c4b439e8c32 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 7 Feb 2025 04:55:39 +0000 Subject: [PATCH 063/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 6e2344a92eec..04b9f1c3fa3e 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -30865107cb8942ab8eaf9baf8d3aa2a6dec2643f +942db6782f4a28c55b0b75b38fd4394d0483390f From 1a6fece5fe88864f1c2c2b283d4d08fe51d6b4c4 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 7 Feb 2025 05:03:43 +0000 Subject: [PATCH 064/991] fmt --- src/tools/miri/src/bin/miri.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 56658f9bd4ca..56ee96502b3e 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -29,8 +29,8 @@ use std::num::NonZero; use std::ops::Range; use std::path::PathBuf; use std::str::FromStr; -use std::sync::{Arc, Once}; use std::sync::atomic::{AtomicI32, AtomicU32, Ordering}; +use std::sync::{Arc, Once}; use miri::{ BacktraceStyle, BorrowTrackerMethod, MiriConfig, MiriEntryFnType, ProvenanceMode, RetagFields, From 16781bf29d2da41fd1b67a5dfffbe40dfdf312eb Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Fri, 7 Feb 2025 20:57:11 +0900 Subject: [PATCH 065/991] add `manual_option_as_slice` to the lint documentation --- book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index dab2630a56fc..f662595d91e8 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -747,6 +747,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check) * [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) * [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive) +* [`manual_option_as_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_as_slice) * [`manual_pattern_char_comparison`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison) * [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains) * [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index a1591188bee7..c08cc53db0c2 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -616,6 +616,7 @@ define_Conf! { manual_is_ascii_check, manual_let_else, manual_non_exhaustive, + manual_option_as_slice, manual_pattern_char_comparison, manual_range_contains, manual_rem_euclid, From 7c94744afb8e9c1ad1b4f08ea7823596c720e125 Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Fri, 7 Feb 2025 09:13:59 -0500 Subject: [PATCH 066/991] Address additional review comments --- clippy_config/src/types.rs | 4 +++- clippy_lints/src/disallowed_types.rs | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index b07188a2b0f6..c72291e9799f 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -40,9 +40,11 @@ impl<'de, const REPLACEMENT_ALLOWED: bool> Deserialize<'de> for DisallowedPath Date: Thu, 6 Feb 2025 21:15:51 +0100 Subject: [PATCH 067/991] Convert `EMPTY_LINE_AFTER_OUTER_ATTR` and `EMPTY_LINE_AFTER_OUTER_ATTR` lint into early lints --- clippy_lints/src/declared_lints.rs | 4 +- clippy_lints/src/doc/empty_line_after.rs | 345 ----------------- clippy_lints/src/doc/mod.rs | 81 +--- clippy_lints/src/empty_line_after.rs | 453 +++++++++++++++++++++++ clippy_lints/src/lib.rs | 2 + 5 files changed, 458 insertions(+), 427 deletions(-) delete mode 100644 clippy_lints/src/doc/empty_line_after.rs create mode 100644 clippy_lints/src/empty_line_after.rs diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 9fbeab5bf2e1..5c5978b55598 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -144,8 +144,6 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::doc::DOC_NESTED_REFDEFS_INFO, crate::doc::DOC_OVERINDENTED_LIST_ITEMS_INFO, crate::doc::EMPTY_DOCS_INFO, - crate::doc::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO, - crate::doc::EMPTY_LINE_AFTER_OUTER_ATTR_INFO, crate::doc::MISSING_ERRORS_DOC_INFO, crate::doc::MISSING_PANICS_DOC_INFO, crate::doc::MISSING_SAFETY_DOC_INFO, @@ -162,6 +160,8 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO, crate::empty_drop::EMPTY_DROP_INFO, crate::empty_enum::EMPTY_ENUM_INFO, + crate::empty_line_after::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO, + crate::empty_line_after::EMPTY_LINE_AFTER_OUTER_ATTR_INFO, crate::empty_with_brackets::EMPTY_ENUM_VARIANTS_WITH_BRACKETS_INFO, crate::empty_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO, crate::endian_bytes::BIG_ENDIAN_BYTES_INFO, diff --git a/clippy_lints/src/doc/empty_line_after.rs b/clippy_lints/src/doc/empty_line_after.rs deleted file mode 100644 index 6e85c6af642b..000000000000 --- a/clippy_lints/src/doc/empty_line_after.rs +++ /dev/null @@ -1,345 +0,0 @@ -use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::source::{SpanRangeExt, snippet_indent}; -use clippy_utils::tokenize_with_text; -use itertools::Itertools; -use rustc_ast::AttrStyle; -use rustc_ast::token::CommentKind; -use rustc_errors::{Applicability, Diag, SuggestionStyle}; -use rustc_hir::{AttrKind, Attribute, ItemKind, Node}; -use rustc_lexer::TokenKind; -use rustc_lint::LateContext; -use rustc_span::{BytePos, ExpnKind, InnerSpan, Span, SpanData}; - -use super::{EMPTY_LINE_AFTER_DOC_COMMENTS, EMPTY_LINE_AFTER_OUTER_ATTR}; - -#[derive(Debug, PartialEq, Clone, Copy)] -enum StopKind { - Attr, - Doc(CommentKind), -} - -impl StopKind { - fn is_doc(self) -> bool { - matches!(self, StopKind::Doc(_)) - } -} - -#[derive(Debug)] -struct Stop { - span: Span, - kind: StopKind, - first: usize, - last: usize, -} - -impl Stop { - fn convert_to_inner(&self) -> (Span, String) { - let inner = match self.kind { - // #|[...] - StopKind::Attr => InnerSpan::new(1, 1), - // /// or /** - // ^ ^ - StopKind::Doc(_) => InnerSpan::new(2, 3), - }; - (self.span.from_inner(inner), "!".into()) - } - - fn comment_out(&self, cx: &LateContext<'_>, suggestions: &mut Vec<(Span, String)>) { - match self.kind { - StopKind::Attr => { - if cx.tcx.sess.source_map().is_multiline(self.span) { - suggestions.extend([ - (self.span.shrink_to_lo(), "/* ".into()), - (self.span.shrink_to_hi(), " */".into()), - ]); - } else { - suggestions.push((self.span.shrink_to_lo(), "// ".into())); - } - }, - StopKind::Doc(CommentKind::Line) => suggestions.push((self.span.shrink_to_lo(), "// ".into())), - StopKind::Doc(CommentKind::Block) => { - // /** outer */ /*! inner */ - // ^ ^ - let asterisk = self.span.from_inner(InnerSpan::new(1, 2)); - suggestions.push((asterisk, String::new())); - }, - } - } - - fn from_attr(cx: &LateContext<'_>, attr: &Attribute) -> Option { - let SpanData { lo, hi, .. } = attr.span.data(); - let file = cx.tcx.sess.source_map().lookup_source_file(lo); - - Some(Self { - span: attr.span, - kind: match attr.kind { - AttrKind::Normal(_) => StopKind::Attr, - AttrKind::DocComment(comment_kind, _) => StopKind::Doc(comment_kind), - }, - first: file.lookup_line(file.relative_position(lo))?, - last: file.lookup_line(file.relative_position(hi))?, - }) - } -} - -/// Represents a set of attrs/doc comments separated by 1 or more empty lines -/// -/// ```ignore -/// /// chunk 1 docs -/// // not an empty line so also part of chunk 1 -/// #[chunk_1_attrs] // <-- prev_stop -/// -/// /* gap */ -/// -/// /// chunk 2 docs // <-- next_stop -/// #[chunk_2_attrs] -/// ``` -struct Gap<'a> { - /// The span of individual empty lines including the newline at the end of the line - empty_lines: Vec, - has_comment: bool, - next_stop: &'a Stop, - prev_stop: &'a Stop, - /// The chunk that includes [`prev_stop`](Self::prev_stop) - prev_chunk: &'a [Stop], -} - -impl<'a> Gap<'a> { - fn new(cx: &LateContext<'_>, prev_chunk: &'a [Stop], next_chunk: &'a [Stop]) -> Option { - let prev_stop = prev_chunk.last()?; - let next_stop = next_chunk.first()?; - let gap_span = prev_stop.span.between(next_stop.span); - let gap_snippet = gap_span.get_source_text(cx)?; - - let mut has_comment = false; - let mut empty_lines = Vec::new(); - - for (token, source, inner_span) in tokenize_with_text(&gap_snippet) { - match token { - TokenKind::BlockComment { - doc_style: None, - terminated: true, - } - | TokenKind::LineComment { doc_style: None } => has_comment = true, - TokenKind::Whitespace => { - let newlines = source.bytes().positions(|b| b == b'\n'); - empty_lines.extend( - newlines - .tuple_windows() - .map(|(a, b)| InnerSpan::new(inner_span.start + a + 1, inner_span.start + b)) - .map(|inner_span| gap_span.from_inner(inner_span)), - ); - }, - // Ignore cfg_attr'd out attributes as they may contain empty lines, could also be from macro - // shenanigans - _ => return None, - } - } - - (!empty_lines.is_empty()).then_some(Self { - empty_lines, - has_comment, - next_stop, - prev_stop, - prev_chunk, - }) - } - - fn contiguous_empty_lines(&self) -> impl Iterator + '_ { - self.empty_lines - // The `+ BytePos(1)` means "next line", because each empty line span is "N:1-N:1". - .chunk_by(|a, b| a.hi() + BytePos(1) == b.lo()) - .map(|chunk| { - let first = chunk.first().expect("at least one empty line"); - let last = chunk.last().expect("at least one empty line"); - // The BytePos subtraction here is safe, as before an empty line, there must be at least one - // attribute/comment. The span needs to start at the end of the previous line. - first.with_lo(first.lo() - BytePos(1)).with_hi(last.hi()) - }) - } -} - -/// If the node the attributes/docs apply to is the first in the module/crate suggest converting -/// them to inner attributes/docs -fn suggest_inner(cx: &LateContext<'_>, diag: &mut Diag<'_, ()>, kind: StopKind, gaps: &[Gap<'_>]) { - let Some(owner) = cx.last_node_with_lint_attrs.as_owner() else { - return; - }; - let parent_desc = match cx.tcx.parent_hir_node(owner.into()) { - Node::Item(item) - if let ItemKind::Mod(parent_mod) = item.kind - && let [first, ..] = parent_mod.item_ids - && first.owner_id == owner => - { - "parent module" - }, - Node::Crate(crate_mod) - if let Some(first) = crate_mod - .item_ids - .iter() - .map(|&id| cx.tcx.hir().item(id)) - // skip prelude imports - .find(|item| !matches!(item.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_))) - && first.owner_id == owner => - { - "crate" - }, - _ => return, - }; - - diag.multipart_suggestion_verbose( - match kind { - StopKind::Attr => format!("if the attribute should apply to the {parent_desc} use an inner attribute"), - StopKind::Doc(_) => format!("if the comment should document the {parent_desc} use an inner doc comment"), - }, - gaps.iter() - .flat_map(|gap| gap.prev_chunk) - .map(Stop::convert_to_inner) - .collect(), - Applicability::MaybeIncorrect, - ); -} - -fn check_gaps(cx: &LateContext<'_>, gaps: &[Gap<'_>]) -> bool { - let Some(first_gap) = gaps.first() else { - return false; - }; - let empty_lines = || gaps.iter().flat_map(|gap| gap.empty_lines.iter().copied()); - let contiguous_empty_lines = || gaps.iter().flat_map(Gap::contiguous_empty_lines); - let mut has_comment = false; - let mut has_attr = false; - for gap in gaps { - has_comment |= gap.has_comment; - if !has_attr { - has_attr = gap.prev_chunk.iter().any(|stop| stop.kind == StopKind::Attr); - } - } - let kind = first_gap.prev_stop.kind; - let (lint, kind_desc) = match kind { - StopKind::Attr => (EMPTY_LINE_AFTER_OUTER_ATTR, "outer attribute"), - StopKind::Doc(_) => (EMPTY_LINE_AFTER_DOC_COMMENTS, "doc comment"), - }; - let (lines, are, them) = if empty_lines().nth(1).is_some() { - ("lines", "are", "them") - } else { - ("line", "is", "it") - }; - span_lint_and_then( - cx, - lint, - first_gap.prev_stop.span.to(empty_lines().last().unwrap()), - format!("empty {lines} after {kind_desc}"), - |diag| { - if let Some(owner) = cx.last_node_with_lint_attrs.as_owner() { - let def_id = owner.to_def_id(); - let def_descr = cx.tcx.def_descr(def_id); - diag.span_label( - cx.tcx.def_span(def_id), - match kind { - StopKind::Attr => format!("the attribute applies to this {def_descr}"), - StopKind::Doc(_) => format!("the comment documents this {def_descr}"), - }, - ); - } - - diag.multipart_suggestion_with_style( - format!("if the empty {lines} {are} unintentional remove {them}"), - contiguous_empty_lines() - .map(|empty_lines| (empty_lines, String::new())) - .collect(), - Applicability::MaybeIncorrect, - SuggestionStyle::HideCodeAlways, - ); - - if has_comment && kind.is_doc() { - // Likely doc comments that applied to some now commented out code - // - // /// Old docs for Foo - // // struct Foo; - - let mut suggestions = Vec::new(); - for stop in gaps.iter().flat_map(|gap| gap.prev_chunk) { - stop.comment_out(cx, &mut suggestions); - } - let name = match cx.tcx.hir().opt_name(cx.last_node_with_lint_attrs) { - Some(name) => format!("`{name}`"), - None => "this".into(), - }; - diag.multipart_suggestion_verbose( - format!("if the doc comment should not document {name} comment it out"), - suggestions, - Applicability::MaybeIncorrect, - ); - } else { - suggest_inner(cx, diag, kind, gaps); - } - - if kind == StopKind::Doc(CommentKind::Line) - && gaps - .iter() - .all(|gap| !gap.has_comment && gap.next_stop.kind == StopKind::Doc(CommentKind::Line)) - { - // Commentless empty gaps between line doc comments, possibly intended to be part of the markdown - - let indent = snippet_indent(cx, first_gap.prev_stop.span).unwrap_or_default(); - diag.multipart_suggestion_verbose( - format!("if the documentation should include the empty {lines} include {them} in the comment"), - empty_lines() - .map(|empty_line| (empty_line, format!("{indent}///"))) - .collect(), - Applicability::MaybeIncorrect, - ); - } - }, - ); - kind.is_doc() -} - -/// Returns `true` if [`EMPTY_LINE_AFTER_DOC_COMMENTS`] triggered, used to skip other doc comment -/// lints where they would be confusing -/// -/// [`EMPTY_LINE_AFTER_OUTER_ATTR`] is also here to share an implementation but does not return -/// `true` if it triggers -pub(super) fn check(cx: &LateContext<'_>, attrs: &[Attribute]) -> bool { - let mut outer = attrs - .iter() - .filter(|attr| attr.style == AttrStyle::Outer && !attr.span.from_expansion()) - .map(|attr| Stop::from_attr(cx, attr)) - .collect::>>() - .unwrap_or_default(); - - if outer.is_empty() { - return false; - } - - // Push a fake attribute Stop for the item itself so we check for gaps between the last outer - // attr/doc comment and the item they apply to - let span = cx.tcx.hir().span(cx.last_node_with_lint_attrs); - if !span.from_expansion() - && let Ok(line) = cx.tcx.sess.source_map().lookup_line(span.lo()) - { - outer.push(Stop { - span, - kind: StopKind::Attr, - first: line.line, - // last doesn't need to be accurate here, we don't compare it with anything - last: line.line, - }); - } - - let mut gaps = Vec::new(); - let mut last = 0; - for pos in outer - .array_windows() - .positions(|[a, b]| b.first.saturating_sub(a.last) > 1) - { - // we want to be after the first stop in the window - let pos = pos + 1; - if let Some(gap) = Gap::new(cx, &outer[last..pos], &outer[pos..]) { - last = pos; - gaps.push(gap); - } - } - - check_gaps(cx, &gaps) -} diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 3d8ce7becdbd..42e1f7fd950d 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -33,7 +33,6 @@ use rustc_span::{Span, sym}; use std::ops::Range; use url::Url; -mod empty_line_after; mod include_in_doc_without_cfg; mod link_with_quotes; mod markdown; @@ -491,82 +490,6 @@ declare_clippy_lint! { "ensure the first documentation paragraph is short" } -declare_clippy_lint! { - /// ### What it does - /// Checks for empty lines after outer attributes - /// - /// ### Why is this bad? - /// The attribute may have meant to be an inner attribute (`#![attr]`). If - /// it was meant to be an outer attribute (`#[attr]`) then the empty line - /// should be removed - /// - /// ### Example - /// ```no_run - /// #[allow(dead_code)] - /// - /// fn not_quite_good_code() {} - /// ``` - /// - /// Use instead: - /// ```no_run - /// // Good (as inner attribute) - /// #![allow(dead_code)] - /// - /// fn this_is_fine() {} - /// - /// // or - /// - /// // Good (as outer attribute) - /// #[allow(dead_code)] - /// fn this_is_fine_too() {} - /// ``` - #[clippy::version = "pre 1.29.0"] - pub EMPTY_LINE_AFTER_OUTER_ATTR, - suspicious, - "empty line after outer attribute" -} - -declare_clippy_lint! { - /// ### What it does - /// Checks for empty lines after doc comments. - /// - /// ### Why is this bad? - /// The doc comment may have meant to be an inner doc comment, regular - /// comment or applied to some old code that is now commented out. If it was - /// intended to be a doc comment, then the empty line should be removed. - /// - /// ### Example - /// ```no_run - /// /// Some doc comment with a blank line after it. - /// - /// fn f() {} - /// - /// /// Docs for `old_code` - /// // fn old_code() {} - /// - /// fn new_code() {} - /// ``` - /// - /// Use instead: - /// ```no_run - /// //! Convert it to an inner doc comment - /// - /// // Or a regular comment - /// - /// /// Or remove the empty line - /// fn f() {} - /// - /// // /// Docs for `old_code` - /// // fn old_code() {} - /// - /// fn new_code() {} - /// ``` - #[clippy::version = "1.70.0"] - pub EMPTY_LINE_AFTER_DOC_COMMENTS, - suspicious, - "empty line after doc comments" -} - declare_clippy_lint! { /// ### What it does /// Checks if included files in doc comments are included only for `cfg(doc)`. @@ -650,8 +573,6 @@ impl_lint_pass!(Documentation => [ EMPTY_DOCS, DOC_LAZY_CONTINUATION, DOC_OVERINDENTED_LIST_ITEMS, - EMPTY_LINE_AFTER_OUTER_ATTR, - EMPTY_LINE_AFTER_DOC_COMMENTS, TOO_LONG_FIRST_DOC_PARAGRAPH, DOC_INCLUDE_WITHOUT_CFG, ]); @@ -784,7 +705,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ } include_in_doc_without_cfg::check(cx, attrs); - if suspicious_doc_comments::check(cx, attrs) || empty_line_after::check(cx, attrs) || is_doc_hidden(attrs) { + if suspicious_doc_comments::check(cx, attrs) || is_doc_hidden(attrs) { return None; } diff --git a/clippy_lints/src/empty_line_after.rs b/clippy_lints/src/empty_line_after.rs new file mode 100644 index 000000000000..7e0a2690d54e --- /dev/null +++ b/clippy_lints/src/empty_line_after.rs @@ -0,0 +1,453 @@ +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::{SpanRangeExt, snippet_indent}; +use clippy_utils::tokenize_with_text; +use itertools::Itertools; +use rustc_ast::token::CommentKind; +use rustc_ast::{AttrKind, AttrStyle, Attribute, Crate, Item, ItemKind, ModKind, NodeId}; +use rustc_errors::{Applicability, Diag, SuggestionStyle}; +use rustc_lexer::TokenKind; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; +use rustc_session::impl_lint_pass; +use rustc_span::symbol::kw; +use rustc_span::{BytePos, ExpnKind, InnerSpan, Span, SpanData, Symbol}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for empty lines after outer attributes + /// + /// ### Why is this bad? + /// The attribute may have meant to be an inner attribute (`#![attr]`). If + /// it was meant to be an outer attribute (`#[attr]`) then the empty line + /// should be removed + /// + /// ### Example + /// ```no_run + /// #[allow(dead_code)] + /// + /// fn not_quite_good_code() {} + /// ``` + /// + /// Use instead: + /// ```no_run + /// // Good (as inner attribute) + /// #![allow(dead_code)] + /// + /// fn this_is_fine() {} + /// + /// // or + /// + /// // Good (as outer attribute) + /// #[allow(dead_code)] + /// fn this_is_fine_too() {} + /// ``` + #[clippy::version = "pre 1.29.0"] + pub EMPTY_LINE_AFTER_OUTER_ATTR, + suspicious, + "empty line after outer attribute" +} + +declare_clippy_lint! { + /// ### What it does + /// Checks for empty lines after doc comments. + /// + /// ### Why is this bad? + /// The doc comment may have meant to be an inner doc comment, regular + /// comment or applied to some old code that is now commented out. If it was + /// intended to be a doc comment, then the empty line should be removed. + /// + /// ### Example + /// ```no_run + /// /// Some doc comment with a blank line after it. + /// + /// fn f() {} + /// + /// /// Docs for `old_code` + /// // fn old_code() {} + /// + /// fn new_code() {} + /// ``` + /// + /// Use instead: + /// ```no_run + /// //! Convert it to an inner doc comment + /// + /// // Or a regular comment + /// + /// /// Or remove the empty line + /// fn f() {} + /// + /// // /// Docs for `old_code` + /// // fn old_code() {} + /// + /// fn new_code() {} + /// ``` + #[clippy::version = "1.70.0"] + pub EMPTY_LINE_AFTER_DOC_COMMENTS, + suspicious, + "empty line after doc comments" +} + +#[derive(Debug)] +struct ItemInfo { + kind: &'static str, + name: Symbol, + span: Span, + mod_items: Vec, +} + +pub struct EmptyLineAfter { + items: Vec, +} + +impl_lint_pass!(EmptyLineAfter => [ + EMPTY_LINE_AFTER_OUTER_ATTR, + EMPTY_LINE_AFTER_DOC_COMMENTS, +]); + +impl EmptyLineAfter { + pub fn new() -> Self { + Self { items: Vec::new() } + } +} + +#[derive(Debug, PartialEq, Clone, Copy)] +enum StopKind { + Attr, + Doc(CommentKind), +} + +impl StopKind { + fn is_doc(self) -> bool { + matches!(self, StopKind::Doc(_)) + } +} + +#[derive(Debug)] +struct Stop { + span: Span, + kind: StopKind, + first: usize, + last: usize, +} + +impl Stop { + fn convert_to_inner(&self) -> (Span, String) { + let inner = match self.kind { + // #|[...] + StopKind::Attr => InnerSpan::new(1, 1), + // /// or /** + // ^ ^ + StopKind::Doc(_) => InnerSpan::new(2, 3), + }; + (self.span.from_inner(inner), "!".into()) + } + + fn comment_out(&self, cx: &EarlyContext<'_>, suggestions: &mut Vec<(Span, String)>) { + match self.kind { + StopKind::Attr => { + if cx.sess().source_map().is_multiline(self.span) { + suggestions.extend([ + (self.span.shrink_to_lo(), "/* ".into()), + (self.span.shrink_to_hi(), " */".into()), + ]); + } else { + suggestions.push((self.span.shrink_to_lo(), "// ".into())); + } + }, + StopKind::Doc(CommentKind::Line) => suggestions.push((self.span.shrink_to_lo(), "// ".into())), + StopKind::Doc(CommentKind::Block) => { + // /** outer */ /*! inner */ + // ^ ^ + let asterisk = self.span.from_inner(InnerSpan::new(1, 2)); + suggestions.push((asterisk, String::new())); + }, + } + } + + fn from_attr(cx: &EarlyContext<'_>, attr: &Attribute) -> Option { + let SpanData { lo, hi, .. } = attr.span.data(); + let file = cx.sess().source_map().lookup_source_file(lo); + + Some(Self { + span: attr.span, + kind: match attr.kind { + AttrKind::Normal(_) => StopKind::Attr, + AttrKind::DocComment(comment_kind, _) => StopKind::Doc(comment_kind), + }, + first: file.lookup_line(file.relative_position(lo))?, + last: file.lookup_line(file.relative_position(hi))?, + }) + } +} + +/// Represents a set of attrs/doc comments separated by 1 or more empty lines +/// +/// ```ignore +/// /// chunk 1 docs +/// // not an empty line so also part of chunk 1 +/// #[chunk_1_attrs] // <-- prev_stop +/// +/// /* gap */ +/// +/// /// chunk 2 docs // <-- next_stop +/// #[chunk_2_attrs] +/// ``` +struct Gap<'a> { + /// The span of individual empty lines including the newline at the end of the line + empty_lines: Vec, + has_comment: bool, + next_stop: &'a Stop, + prev_stop: &'a Stop, + /// The chunk that includes [`prev_stop`](Self::prev_stop) + prev_chunk: &'a [Stop], +} + +impl<'a> Gap<'a> { + fn new(cx: &EarlyContext<'_>, prev_chunk: &'a [Stop], next_chunk: &'a [Stop]) -> Option { + let prev_stop = prev_chunk.last()?; + let next_stop = next_chunk.first()?; + let gap_span = prev_stop.span.between(next_stop.span); + let gap_snippet = gap_span.get_source_text(cx)?; + + let mut has_comment = false; + let mut empty_lines = Vec::new(); + + for (token, source, inner_span) in tokenize_with_text(&gap_snippet) { + match token { + TokenKind::BlockComment { + doc_style: None, + terminated: true, + } + | TokenKind::LineComment { doc_style: None } => has_comment = true, + TokenKind::Whitespace => { + let newlines = source.bytes().positions(|b| b == b'\n'); + empty_lines.extend( + newlines + .tuple_windows() + .map(|(a, b)| InnerSpan::new(inner_span.start + a + 1, inner_span.start + b)) + .map(|inner_span| gap_span.from_inner(inner_span)), + ); + }, + // Ignore cfg_attr'd out attributes as they may contain empty lines, could also be from macro + // shenanigans + _ => return None, + } + } + + (!empty_lines.is_empty()).then_some(Self { + empty_lines, + has_comment, + next_stop, + prev_stop, + prev_chunk, + }) + } + + fn contiguous_empty_lines(&self) -> impl Iterator + '_ { + self.empty_lines + // The `+ BytePos(1)` means "next line", because each empty line span is "N:1-N:1". + .chunk_by(|a, b| a.hi() + BytePos(1) == b.lo()) + .map(|chunk| { + let first = chunk.first().expect("at least one empty line"); + let last = chunk.last().expect("at least one empty line"); + // The BytePos subtraction here is safe, as before an empty line, there must be at least one + // attribute/comment. The span needs to start at the end of the previous line. + first.with_lo(first.lo() - BytePos(1)).with_hi(last.hi()) + }) + } +} + +impl EmptyLineAfter { + fn check_gaps(&self, cx: &EarlyContext<'_>, gaps: &[Gap<'_>], id: NodeId) { + let Some(first_gap) = gaps.first() else { + return; + }; + let empty_lines = || gaps.iter().flat_map(|gap| gap.empty_lines.iter().copied()); + let contiguous_empty_lines = || gaps.iter().flat_map(Gap::contiguous_empty_lines); + let mut has_comment = false; + let mut has_attr = false; + for gap in gaps { + has_comment |= gap.has_comment; + if !has_attr { + has_attr = gap.prev_chunk.iter().any(|stop| stop.kind == StopKind::Attr); + } + } + let kind = first_gap.prev_stop.kind; + let (lint, kind_desc) = match kind { + StopKind::Attr => (EMPTY_LINE_AFTER_OUTER_ATTR, "outer attribute"), + StopKind::Doc(_) => (EMPTY_LINE_AFTER_DOC_COMMENTS, "doc comment"), + }; + let (lines, are, them) = if empty_lines().nth(1).is_some() { + ("lines", "are", "them") + } else { + ("line", "is", "it") + }; + span_lint_and_then( + cx, + lint, + first_gap.prev_stop.span.to(empty_lines().last().unwrap()), + format!("empty {lines} after {kind_desc}"), + |diag| { + let info = self.items.last().unwrap(); + diag.span_label(info.span, match kind { + StopKind::Attr => format!("the attribute applies to this {}", info.kind), + StopKind::Doc(_) => format!("the comment documents this {}", info.kind), + }); + + diag.multipart_suggestion_with_style( + format!("if the empty {lines} {are} unintentional remove {them}"), + contiguous_empty_lines() + .map(|empty_lines| (empty_lines, String::new())) + .collect(), + Applicability::MaybeIncorrect, + SuggestionStyle::HideCodeAlways, + ); + + if has_comment && kind.is_doc() { + // Likely doc comments that applied to some now commented out code + // + // /// Old docs for Foo + // // struct Foo; + + let mut suggestions = Vec::new(); + for stop in gaps.iter().flat_map(|gap| gap.prev_chunk) { + stop.comment_out(cx, &mut suggestions); + } + diag.multipart_suggestion_verbose( + format!("if the doc comment should not document `{}` comment it out", info.name), + suggestions, + Applicability::MaybeIncorrect, + ); + } else { + self.suggest_inner(diag, kind, gaps, id); + } + + if kind == StopKind::Doc(CommentKind::Line) + && gaps + .iter() + .all(|gap| !gap.has_comment && gap.next_stop.kind == StopKind::Doc(CommentKind::Line)) + { + // Commentless empty gaps between line doc comments, possibly intended to be part of the markdown + + let indent = snippet_indent(cx, first_gap.prev_stop.span).unwrap_or_default(); + diag.multipart_suggestion_verbose( + format!("if the documentation should include the empty {lines} include {them} in the comment"), + empty_lines() + .map(|empty_line| (empty_line, format!("{indent}///"))) + .collect(), + Applicability::MaybeIncorrect, + ); + } + }, + ); + } + + /// If the node the attributes/docs apply to is the first in the module/crate suggest converting + /// them to inner attributes/docs + fn suggest_inner(&self, diag: &mut Diag<'_, ()>, kind: StopKind, gaps: &[Gap<'_>], id: NodeId) { + if let Some(parent) = self.items.iter().rev().nth(1) + && (parent.kind == "module" || parent.kind == "crate") + && parent.mod_items.first() == Some(&id) + { + let desc = if parent.kind == "module" { + "parent module" + } else { + parent.kind + }; + diag.multipart_suggestion_verbose( + match kind { + StopKind::Attr => format!("if the attribute should apply to the {desc} use an inner attribute"), + StopKind::Doc(_) => format!("if the comment should document the {desc} use an inner doc comment"), + }, + gaps.iter() + .flat_map(|gap| gap.prev_chunk) + .map(Stop::convert_to_inner) + .collect(), + Applicability::MaybeIncorrect, + ); + } + } +} + +impl EarlyLintPass for EmptyLineAfter { + fn check_crate(&mut self, _: &EarlyContext<'_>, krate: &Crate) { + self.items.push(ItemInfo { + kind: "crate", + name: kw::Crate, + span: krate.spans.inner_span.with_hi(krate.spans.inner_span.lo()), + mod_items: krate + .items + .iter() + .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_))) + .map(|i| i.id) + .collect::>(), + }); + } + + fn check_item_post(&mut self, _: &EarlyContext<'_>, _: &Item) { + self.items.pop(); + } + + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + self.items.push(ItemInfo { + kind: item.kind.descr(), + name: item.ident.name, + span: if item.span.contains(item.ident.span) { + item.span.with_hi(item.ident.span.hi()) + } else { + item.span.with_hi(item.span.lo()) + }, + mod_items: match item.kind { + ItemKind::Mod(_, ModKind::Loaded(ref items, _, _, _)) => items + .iter() + .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_))) + .map(|i| i.id) + .collect::>(), + _ => Vec::new(), + }, + }); + + let mut outer = item + .attrs + .iter() + .filter(|attr| attr.style == AttrStyle::Outer && !attr.span.from_expansion()) + .map(|attr| Stop::from_attr(cx, attr)) + .collect::>>() + .unwrap_or_default(); + + if outer.is_empty() { + return; + } + + // Push a fake attribute Stop for the item itself so we check for gaps between the last outer + // attr/doc comment and the item they apply to + let span = self.items.last().unwrap().span; + if !span.from_expansion() + && let Ok(line) = cx.sess().source_map().lookup_line(span.lo()) + { + outer.push(Stop { + span, + kind: StopKind::Attr, + first: line.line, + // last doesn't need to be accurate here, we don't compare it with anything + last: line.line, + }); + } + + let mut gaps = Vec::new(); + let mut last = 0; + for pos in outer + .array_windows() + .positions(|[a, b]| b.first.saturating_sub(a.last) > 1) + { + // we want to be after the first stop in the window + let pos = pos + 1; + if let Some(gap) = Gap::new(cx, &outer[last..pos], &outer[pos..]) { + last = pos; + gaps.push(gap); + } + } + + self.check_gaps(cx, &gaps, item.id); + } +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 8887ab7ec0d7..13218331a67b 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -126,6 +126,7 @@ mod duplicate_mod; mod else_if_without_else; mod empty_drop; mod empty_enum; +mod empty_line_after; mod empty_with_brackets; mod endian_bytes; mod entry; @@ -973,6 +974,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(move |_| Box::new(unused_trait_names::UnusedTraitNames::new(conf))); store.register_late_pass(|_| Box::new(manual_ignore_case_cmp::ManualIgnoreCaseCmp)); store.register_late_pass(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound)); + store.register_early_pass(|| Box::new(empty_line_after::EmptyLineAfter::new())); store.register_late_pass(move |_| Box::new(arbitrary_source_item_ordering::ArbitrarySourceItemOrdering::new(conf))); store.register_late_pass(|_| Box::new(unneeded_struct_pattern::UnneededStructPattern)); store.register_late_pass(|_| Box::::default()); From 42453bd73a39ef96727774159d300f0a27aec73d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 6 Feb 2025 21:28:44 +0100 Subject: [PATCH 068/991] Update UI tests --- clippy_lints/src/empty_line_after.rs | 2 +- tests/ui/empty_line_after/doc_comments.stderr | 18 +++++++++--------- .../ui/empty_line_after/outer_attribute.stderr | 12 ++++++------ tests/ui/suspicious_doc_comments.fixed | 1 + tests/ui/suspicious_doc_comments.rs | 1 + tests/ui/suspicious_doc_comments.stderr | 18 +++++++++--------- 6 files changed, 27 insertions(+), 25 deletions(-) diff --git a/clippy_lints/src/empty_line_after.rs b/clippy_lints/src/empty_line_after.rs index 7e0a2690d54e..4f1c6186cfe8 100644 --- a/clippy_lints/src/empty_line_after.rs +++ b/clippy_lints/src/empty_line_after.rs @@ -133,7 +133,7 @@ struct Stop { impl Stop { fn convert_to_inner(&self) -> (Span, String) { let inner = match self.kind { - // #|[...] + // #![...] StopKind::Attr => InnerSpan::new(1, 1), // /// or /** // ^ ^ diff --git a/tests/ui/empty_line_after/doc_comments.stderr b/tests/ui/empty_line_after/doc_comments.stderr index c5d5f3d37594..d71c888e1966 100644 --- a/tests/ui/empty_line_after/doc_comments.stderr +++ b/tests/ui/empty_line_after/doc_comments.stderr @@ -5,7 +5,7 @@ LL | / /// for the crate LL | | | |_^ LL | fn first_in_crate() {} - | ------------------- the comment documents this function + | ----------------- the comment documents this function | = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]` @@ -24,7 +24,7 @@ LL | / /// for the module LL | | | |_^ LL | fn first_in_module() {} - | -------------------- the comment documents this function + | ------------------ the comment documents this function | = help: if the empty line is unintentional remove it help: if the comment should document the parent module use an inner doc comment @@ -42,7 +42,7 @@ LL | | | |_^ LL | /// Blank line LL | fn indented() {} - | ------------- the comment documents this function + | ----------- the comment documents this function | = help: if the empty line is unintentional remove it help: if the documentation should include the empty line include it in the comment @@ -57,7 +57,7 @@ LL | / /// This should produce a warning LL | | | |_^ LL | fn with_doc_and_newline() {} - | ------------------------- the comment documents this function + | ----------------------- the comment documents this function | = help: if the empty line is unintentional remove it @@ -72,7 +72,7 @@ LL | | | |_^ ... LL | fn three_attributes() {} - | --------------------- the comment documents this function + | ------------------- the comment documents this function | = help: if the empty lines are unintentional remove them @@ -84,7 +84,7 @@ LL | | // fn old_code() {} LL | | | |_^ LL | fn new_code() {} - | ------------- the comment documents this function + | ----------- the comment documents this function | = help: if the empty line is unintentional remove it help: if the doc comment should not document `new_code` comment it out @@ -126,7 +126,7 @@ LL | | */ LL | | | |_^ LL | fn first_in_module() {} - | -------------------- the comment documents this function + | ------------------ the comment documents this function | = help: if the empty line is unintentional remove it help: if the comment should document the parent module use an inner doc comment @@ -145,7 +145,7 @@ LL | | | |_^ ... LL | fn new_code() {} - | ------------- the comment documents this function + | ----------- the comment documents this function | = help: if the empty line is unintentional remove it help: if the doc comment should not document `new_code` comment it out @@ -163,7 +163,7 @@ LL | | | |_^ LL | /// Docs for `new_code2` LL | fn new_code2() {} - | -------------- the comment documents this function + | ------------ the comment documents this function | = help: if the empty line is unintentional remove it help: if the doc comment should not document `new_code2` comment it out diff --git a/tests/ui/empty_line_after/outer_attribute.stderr b/tests/ui/empty_line_after/outer_attribute.stderr index a95306e2fa33..b4c49d0b3166 100644 --- a/tests/ui/empty_line_after/outer_attribute.stderr +++ b/tests/ui/empty_line_after/outer_attribute.stderr @@ -5,7 +5,7 @@ LL | / #[crate_type = "lib"] LL | | | |_^ LL | fn first_in_crate() {} - | ------------------- the attribute applies to this function + | ----------------- the attribute applies to this function | = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]` @@ -23,7 +23,7 @@ LL | | | |_^ LL | /// some comment LL | fn with_one_newline_and_comment() {} - | --------------------------------- the attribute applies to this function + | ------------------------------- the attribute applies to this function | = help: if the empty line is unintentional remove it @@ -34,7 +34,7 @@ LL | / #[inline] LL | | | |_^ LL | fn with_one_newline() {} - | --------------------- the attribute applies to this function + | ------------------- the attribute applies to this function | = help: if the empty line is unintentional remove it @@ -46,7 +46,7 @@ LL | | LL | | | |_^ LL | fn with_two_newlines() {} - | ---------------------- the attribute applies to this function + | -------------------- the attribute applies to this function | = help: if the empty lines are unintentional remove them help: if the attribute should apply to the parent module use an inner attribute @@ -95,7 +95,7 @@ LL | | // Still lint cases where the empty line does not immediately follow the LL | | | |_^ LL | fn comment_before_empty_line() {} - | ------------------------------ the attribute applies to this function + | ---------------------------- the attribute applies to this function | = help: if the empty line is unintentional remove it @@ -107,7 +107,7 @@ LL | / #[allow(unused)] LL | | | |_^ LL | pub fn isolated_comment() {} - | ------------------------- the attribute applies to this function + | ----------------------- the attribute applies to this function | = help: if the empty lines are unintentional remove them diff --git a/tests/ui/suspicious_doc_comments.fixed b/tests/ui/suspicious_doc_comments.fixed index 614fc03571e5..d3df6a41cb12 100644 --- a/tests/ui/suspicious_doc_comments.fixed +++ b/tests/ui/suspicious_doc_comments.fixed @@ -1,5 +1,6 @@ #![allow(unused)] #![warn(clippy::suspicious_doc_comments)] +#![allow(clippy::empty_line_after_doc_comments)] //! Real module documentation. //! Fake module documentation. diff --git a/tests/ui/suspicious_doc_comments.rs b/tests/ui/suspicious_doc_comments.rs index 7dcba0fefc98..04db2b199c09 100644 --- a/tests/ui/suspicious_doc_comments.rs +++ b/tests/ui/suspicious_doc_comments.rs @@ -1,5 +1,6 @@ #![allow(unused)] #![warn(clippy::suspicious_doc_comments)] +#![allow(clippy::empty_line_after_doc_comments)] //! Real module documentation. ///! Fake module documentation. diff --git a/tests/ui/suspicious_doc_comments.stderr b/tests/ui/suspicious_doc_comments.stderr index f12053b1595a..c34e39cd0fcb 100644 --- a/tests/ui/suspicious_doc_comments.stderr +++ b/tests/ui/suspicious_doc_comments.stderr @@ -1,5 +1,5 @@ error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:5:1 + --> tests/ui/suspicious_doc_comments.rs:6:1 | LL | ///! Fake module documentation. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | //! Fake module documentation. | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:9:5 + --> tests/ui/suspicious_doc_comments.rs:10:5 | LL | ///! This module contains useful functions. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | //! This module contains useful functions. | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:21:5 + --> tests/ui/suspicious_doc_comments.rs:22:5 | LL | / /**! This module contains useful functions. LL | | */ @@ -36,7 +36,7 @@ LL + */ | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:35:5 + --> tests/ui/suspicious_doc_comments.rs:36:5 | LL | / ///! This module LL | | ///! contains @@ -51,7 +51,7 @@ LL ~ //! useful functions. | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:43:5 + --> tests/ui/suspicious_doc_comments.rs:44:5 | LL | / ///! a LL | | ///! b @@ -64,7 +64,7 @@ LL ~ //! b | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:51:5 + --> tests/ui/suspicious_doc_comments.rs:52:5 | LL | ///! a | ^^^^^^ @@ -75,7 +75,7 @@ LL | //! a | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:57:5 + --> tests/ui/suspicious_doc_comments.rs:58:5 | LL | / ///! a LL | | @@ -90,7 +90,7 @@ LL ~ //! b | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:69:5 + --> tests/ui/suspicious_doc_comments.rs:70:5 | LL | ///! Very cool macro | ^^^^^^^^^^^^^^^^^^^^ @@ -101,7 +101,7 @@ LL | //! Very cool macro | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:76:5 + --> tests/ui/suspicious_doc_comments.rs:77:5 | LL | ///! Huh. | ^^^^^^^^^ From 4044c1aa496e39e4fc1ec34d646d84ea639253ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20D=C3=B6nszelmann?= Date: Thu, 6 Feb 2025 21:44:00 +0100 Subject: [PATCH 069/991] fix empty after lint on impl/trait items Co-authored-by: Guillaume Gomez --- clippy_lints/src/empty_line_after.rs | 113 ++++++++++++------ .../ui/empty_line_after/doc_comments.1.fixed | 9 ++ .../ui/empty_line_after/doc_comments.2.fixed | 9 ++ tests/ui/empty_line_after/doc_comments.rs | 10 ++ tests/ui/empty_line_after/doc_comments.stderr | 13 +- 5 files changed, 116 insertions(+), 38 deletions(-) diff --git a/clippy_lints/src/empty_line_after.rs b/clippy_lints/src/empty_line_after.rs index 4f1c6186cfe8..89ddd885b6e4 100644 --- a/clippy_lints/src/empty_line_after.rs +++ b/clippy_lints/src/empty_line_after.rs @@ -3,13 +3,13 @@ use clippy_utils::source::{SpanRangeExt, snippet_indent}; use clippy_utils::tokenize_with_text; use itertools::Itertools; use rustc_ast::token::CommentKind; -use rustc_ast::{AttrKind, AttrStyle, Attribute, Crate, Item, ItemKind, ModKind, NodeId}; +use rustc_ast::{AssocItemKind, AttrKind, AttrStyle, Attribute, Crate, Item, ItemKind, ModKind, NodeId}; use rustc_errors::{Applicability, Diag, SuggestionStyle}; use rustc_lexer::TokenKind; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_session::impl_lint_pass; use rustc_span::symbol::kw; -use rustc_span::{BytePos, ExpnKind, InnerSpan, Span, SpanData, Symbol}; +use rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol}; declare_clippy_lint! { /// ### What it does @@ -92,7 +92,7 @@ struct ItemInfo { kind: &'static str, name: Symbol, span: Span, - mod_items: Vec, + mod_items: Option, } pub struct EmptyLineAfter { @@ -347,7 +347,7 @@ impl EmptyLineAfter { fn suggest_inner(&self, diag: &mut Diag<'_, ()>, kind: StopKind, gaps: &[Gap<'_>], id: NodeId) { if let Some(parent) = self.items.iter().rev().nth(1) && (parent.kind == "module" || parent.kind == "crate") - && parent.mod_items.first() == Some(&id) + && parent.mod_items == Some(id) { let desc = if parent.kind == "module" { "parent module" @@ -367,48 +367,35 @@ impl EmptyLineAfter { ); } } -} -impl EarlyLintPass for EmptyLineAfter { - fn check_crate(&mut self, _: &EarlyContext<'_>, krate: &Crate) { + fn check_item_kind( + &mut self, + cx: &EarlyContext<'_>, + kind: &ItemKind, + ident: &Ident, + span: Span, + attrs: &[Attribute], + id: NodeId, + ) { self.items.push(ItemInfo { - kind: "crate", - name: kw::Crate, - span: krate.spans.inner_span.with_hi(krate.spans.inner_span.lo()), - mod_items: krate - .items - .iter() - .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_))) - .map(|i| i.id) - .collect::>(), - }); - } - - fn check_item_post(&mut self, _: &EarlyContext<'_>, _: &Item) { - self.items.pop(); - } - - fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { - self.items.push(ItemInfo { - kind: item.kind.descr(), - name: item.ident.name, - span: if item.span.contains(item.ident.span) { - item.span.with_hi(item.ident.span.hi()) + kind: kind.descr(), + name: ident.name, + span: if span.contains(ident.span) { + span.with_hi(ident.span.hi()) } else { - item.span.with_hi(item.span.lo()) + span.with_hi(span.lo()) }, - mod_items: match item.kind { - ItemKind::Mod(_, ModKind::Loaded(ref items, _, _, _)) => items + mod_items: match kind { + ItemKind::Mod(_, ModKind::Loaded(items, _, _, _)) => items .iter() .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_))) .map(|i| i.id) - .collect::>(), - _ => Vec::new(), + .next(), + _ => None, }, }); - let mut outer = item - .attrs + let mut outer = attrs .iter() .filter(|attr| attr.style == AttrStyle::Outer && !attr.span.from_expansion()) .map(|attr| Stop::from_attr(cx, attr)) @@ -448,6 +435,58 @@ impl EarlyLintPass for EmptyLineAfter { } } - self.check_gaps(cx, &gaps, item.id); + self.check_gaps(cx, &gaps, id); + } +} + +impl EarlyLintPass for EmptyLineAfter { + fn check_crate(&mut self, _: &EarlyContext<'_>, krate: &Crate) { + self.items.push(ItemInfo { + kind: "crate", + name: kw::Crate, + span: krate.spans.inner_span.with_hi(krate.spans.inner_span.lo()), + mod_items: krate + .items + .iter() + .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_))) + .map(|i| i.id) + .next(), + }); + } + + fn check_item_post(&mut self, _: &EarlyContext<'_>, _: &Item) { + self.items.pop(); + } + fn check_impl_item_post(&mut self, _: &EarlyContext<'_>, _: &Item) { + self.items.pop(); + } + fn check_trait_item_post(&mut self, _: &EarlyContext<'_>, _: &Item) { + self.items.pop(); + } + + fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + self.check_item_kind( + cx, + &item.kind.clone().into(), + &item.ident, + item.span, + &item.attrs, + item.id, + ); + } + + fn check_trait_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + self.check_item_kind( + cx, + &item.kind.clone().into(), + &item.ident, + item.span, + &item.attrs, + item.id, + ); + } + + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + self.check_item_kind(cx, &item.kind, &item.ident, item.span, &item.attrs, item.id); } } diff --git a/tests/ui/empty_line_after/doc_comments.1.fixed b/tests/ui/empty_line_after/doc_comments.1.fixed index fd6a94b6a80c..3772b465fdb2 100644 --- a/tests/ui/empty_line_after/doc_comments.1.fixed +++ b/tests/ui/empty_line_after/doc_comments.1.fixed @@ -132,4 +132,13 @@ pub struct BlockComment; ))] fn empty_line_in_cfg_attr() {} +trait Foo { + fn bar(); +} + +impl Foo for LineComment { + /// comment on assoc item + fn bar() {} +} + fn main() {} diff --git a/tests/ui/empty_line_after/doc_comments.2.fixed b/tests/ui/empty_line_after/doc_comments.2.fixed index 7a57dcd92332..3028d03b6699 100644 --- a/tests/ui/empty_line_after/doc_comments.2.fixed +++ b/tests/ui/empty_line_after/doc_comments.2.fixed @@ -141,4 +141,13 @@ pub struct BlockComment; ))] fn empty_line_in_cfg_attr() {} +trait Foo { + fn bar(); +} + +impl Foo for LineComment { + /// comment on assoc item + fn bar() {} +} + fn main() {} diff --git a/tests/ui/empty_line_after/doc_comments.rs b/tests/ui/empty_line_after/doc_comments.rs index 1da761a5c3d5..ae4ebc271fa1 100644 --- a/tests/ui/empty_line_after/doc_comments.rs +++ b/tests/ui/empty_line_after/doc_comments.rs @@ -144,4 +144,14 @@ pub struct BlockComment; ))] fn empty_line_in_cfg_attr() {} +trait Foo { + fn bar(); +} + +impl Foo for LineComment { + /// comment on assoc item + + fn bar() {} +} + fn main() {} diff --git a/tests/ui/empty_line_after/doc_comments.stderr b/tests/ui/empty_line_after/doc_comments.stderr index d71c888e1966..10189665f014 100644 --- a/tests/ui/empty_line_after/doc_comments.stderr +++ b/tests/ui/empty_line_after/doc_comments.stderr @@ -171,5 +171,16 @@ help: if the doc comment should not document `new_code2` comment it out LL | // /// Docs for `old_code2` | ++ -error: aborting due to 10 previous errors +error: empty line after doc comment + --> tests/ui/empty_line_after/doc_comments.rs:152:5 + | +LL | / /// comment on assoc item +LL | | + | |_^ +LL | fn bar() {} + | ------ the comment documents this function + | + = help: if the empty line is unintentional remove it + +error: aborting due to 11 previous errors From 8ebc52e0321053a3e7e4693ab7ba05b293871dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 7 Feb 2025 16:00:27 +0100 Subject: [PATCH 070/991] fix typo --- clippy_lints/src/empty_line_after.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/empty_line_after.rs b/clippy_lints/src/empty_line_after.rs index 89ddd885b6e4..578ff6e38a6a 100644 --- a/clippy_lints/src/empty_line_after.rs +++ b/clippy_lints/src/empty_line_after.rs @@ -295,7 +295,7 @@ impl EmptyLineAfter { }); diag.multipart_suggestion_with_style( - format!("if the empty {lines} {are} unintentional remove {them}"), + format!("if the empty {lines} {are} unintentional, remove {them}"), contiguous_empty_lines() .map(|empty_lines| (empty_lines, String::new())) .collect(), From 477be9470a6555c467ca63ba445bcdb25d74db01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 7 Feb 2025 16:42:20 +0100 Subject: [PATCH 071/991] add tests for spurious failure and fix typo --- tests/ui/doc/unbalanced_ticks.rs | 16 ++++++++++++++ tests/ui/doc/unbalanced_ticks.stderr | 14 +++++++++++- tests/ui/empty_line_after/doc_comments.stderr | 22 +++++++++---------- .../empty_line_after/outer_attribute.stderr | 18 +++++++-------- 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/tests/ui/doc/unbalanced_ticks.rs b/tests/ui/doc/unbalanced_ticks.rs index 04446787b6c2..a065654e319d 100644 --- a/tests/ui/doc/unbalanced_ticks.rs +++ b/tests/ui/doc/unbalanced_ticks.rs @@ -66,3 +66,19 @@ fn escape_3() {} /// Backslashes ` \` within code blocks don't count. fn escape_4() {} + +trait Foo { + fn bar(); +} + +struct Bar; +impl Foo for Bar { + // NOTE: false positive + /// Returns an `Option` from a i64, assuming a 1-index, January = 1. + /// + /// `Month::from_i64(n: i64)`: | `1` | `2` | ... | `12` + /// ---------------------------| -------------------- | --------------------- | ... | ----- + /// ``: | Some(Month::January) | Some(Month::February) | ... | + /// Some(Month::December) + fn bar() {} +} diff --git a/tests/ui/doc/unbalanced_ticks.stderr b/tests/ui/doc/unbalanced_ticks.stderr index 50324010e97f..c9fd25eb1a1c 100644 --- a/tests/ui/doc/unbalanced_ticks.stderr +++ b/tests/ui/doc/unbalanced_ticks.stderr @@ -94,5 +94,17 @@ LL | /// Escaped \` ` backticks don't count, but unescaped backticks do. | = help: a backtick may be missing a pair -error: aborting due to 10 previous errors +error: backticks are unbalanced + --> tests/ui/doc/unbalanced_ticks.rs:79:9 + | +LL | /// `Month::from_i64(n: i64)`: | `1` | `2` | ... | `12` + | _________^ +LL | | /// ---------------------------| -------------------- | --------------------- | ... | ----- +LL | | /// ``: | Some(Month::January) | Some(Month::February) | ... | +LL | | /// Some(Month::December) + | |_____________________________^ + | + = help: a backtick may be missing a pair + +error: aborting due to 11 previous errors diff --git a/tests/ui/empty_line_after/doc_comments.stderr b/tests/ui/empty_line_after/doc_comments.stderr index 10189665f014..7b197ae67e00 100644 --- a/tests/ui/empty_line_after/doc_comments.stderr +++ b/tests/ui/empty_line_after/doc_comments.stderr @@ -9,7 +9,7 @@ LL | fn first_in_crate() {} | = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]` - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it help: if the comment should document the crate use an inner doc comment | LL ~ //! Meant to be an @@ -26,7 +26,7 @@ LL | | LL | fn first_in_module() {} | ------------------ the comment documents this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it help: if the comment should document the parent module use an inner doc comment | LL ~ //! Meant to be an @@ -44,7 +44,7 @@ LL | /// Blank line LL | fn indented() {} | ----------- the comment documents this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it help: if the documentation should include the empty line include it in the comment | LL | /// @@ -59,7 +59,7 @@ LL | | LL | fn with_doc_and_newline() {} | ----------------------- the comment documents this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it error: empty lines after doc comment --> tests/ui/empty_line_after/doc_comments.rs:44:1 @@ -74,7 +74,7 @@ LL | | LL | fn three_attributes() {} | ------------------- the comment documents this function | - = help: if the empty lines are unintentional remove them + = help: if the empty lines are unintentional, remove them error: empty line after doc comment --> tests/ui/empty_line_after/doc_comments.rs:56:5 @@ -86,7 +86,7 @@ LL | | LL | fn new_code() {} | ----------- the comment documents this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it help: if the doc comment should not document `new_code` comment it out | LL | // /// docs for `old_code` @@ -106,7 +106,7 @@ LL | | LL | struct Multiple; | --------------- the comment documents this struct | - = help: if the empty lines are unintentional remove them + = help: if the empty lines are unintentional, remove them help: if the doc comment should not document `Multiple` comment it out | LL ~ // /// Docs @@ -128,7 +128,7 @@ LL | | LL | fn first_in_module() {} | ------------------ the comment documents this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it help: if the comment should document the parent module use an inner doc comment | LL | /*! @@ -147,7 +147,7 @@ LL | | LL | fn new_code() {} | ----------- the comment documents this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it help: if the doc comment should not document `new_code` comment it out | LL - /** @@ -165,7 +165,7 @@ LL | /// Docs for `new_code2` LL | fn new_code2() {} | ------------ the comment documents this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it help: if the doc comment should not document `new_code2` comment it out | LL | // /// Docs for `old_code2` @@ -180,7 +180,7 @@ LL | | LL | fn bar() {} | ------ the comment documents this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it error: aborting due to 11 previous errors diff --git a/tests/ui/empty_line_after/outer_attribute.stderr b/tests/ui/empty_line_after/outer_attribute.stderr index b4c49d0b3166..519ba6e67615 100644 --- a/tests/ui/empty_line_after/outer_attribute.stderr +++ b/tests/ui/empty_line_after/outer_attribute.stderr @@ -9,7 +9,7 @@ LL | fn first_in_crate() {} | = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]` - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it help: if the attribute should apply to the crate use an inner attribute | LL | #![crate_type = "lib"] @@ -25,7 +25,7 @@ LL | /// some comment LL | fn with_one_newline_and_comment() {} | ------------------------------- the attribute applies to this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it error: empty line after outer attribute --> tests/ui/empty_line_after/outer_attribute.rs:23:1 @@ -36,7 +36,7 @@ LL | | LL | fn with_one_newline() {} | ------------------- the attribute applies to this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it error: empty lines after outer attribute --> tests/ui/empty_line_after/outer_attribute.rs:30:5 @@ -48,7 +48,7 @@ LL | | LL | fn with_two_newlines() {} | -------------------- the attribute applies to this function | - = help: if the empty lines are unintentional remove them + = help: if the empty lines are unintentional, remove them help: if the attribute should apply to the parent module use an inner attribute | LL | #![crate_type = "lib"] @@ -63,7 +63,7 @@ LL | | LL | enum Baz { | -------- the attribute applies to this enum | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it error: empty line after outer attribute --> tests/ui/empty_line_after/outer_attribute.rs:45:1 @@ -74,7 +74,7 @@ LL | | LL | struct Foo { | ---------- the attribute applies to this struct | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it error: empty line after outer attribute --> tests/ui/empty_line_after/outer_attribute.rs:53:1 @@ -85,7 +85,7 @@ LL | | LL | mod foo {} | ------- the attribute applies to this module | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it error: empty line after outer attribute --> tests/ui/empty_line_after/outer_attribute.rs:58:1 @@ -97,7 +97,7 @@ LL | | LL | fn comment_before_empty_line() {} | ---------------------------- the attribute applies to this function | - = help: if the empty line is unintentional remove it + = help: if the empty line is unintentional, remove it error: empty lines after outer attribute --> tests/ui/empty_line_after/outer_attribute.rs:64:1 @@ -109,7 +109,7 @@ LL | | LL | pub fn isolated_comment() {} | ----------------------- the attribute applies to this function | - = help: if the empty lines are unintentional remove them + = help: if the empty lines are unintentional, remove them error: aborting due to 9 previous errors From b18bb0a48347e5d98c30027ebbdee010a8fee48c Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 4 Feb 2025 22:20:45 -0800 Subject: [PATCH 072/991] clippy: directly use rustc_abi instead of reexports --- clippy_lints/src/casts/cast_possible_truncation.rs | 2 +- clippy_lints/src/escape.rs | 4 ++-- clippy_lints/src/eta_reduction.rs | 4 ++-- clippy_lints/src/excessive_bools.rs | 6 +++--- clippy_lints/src/functions/too_many_arguments.rs | 8 ++++---- clippy_lints/src/inherent_to_string.rs | 4 ++-- clippy_lints/src/large_futures.rs | 2 +- clippy_lints/src/methods/mod.rs | 3 ++- clippy_lints/src/missing_const_for_fn.rs | 9 +++++---- clippy_lints/src/needless_pass_by_ref_mut.rs | 4 ++-- clippy_lints/src/needless_pass_by_value.rs | 4 ++-- clippy_lints/src/no_mangle_with_rust_abi.rs | 4 ++-- clippy_lints/src/non_copy_const.rs | 2 +- clippy_lints/src/pass_by_ref_or_value.rs | 4 ++-- clippy_lints/src/ptr.rs | 6 +++--- clippy_lints/src/types/type_complexity.rs | 4 ++-- clippy_utils/src/check_proc_macro.rs | 6 +++--- clippy_utils/src/consts.rs | 2 +- clippy_utils/src/lib.rs | 4 ++-- clippy_utils/src/ty/mod.rs | 2 +- 20 files changed, 43 insertions(+), 41 deletions(-) diff --git a/clippy_lints/src/casts/cast_possible_truncation.rs b/clippy_lints/src/casts/cast_possible_truncation.rs index 48e9f1d690ee..ca973f4bb1aa 100644 --- a/clippy_lints/src/casts/cast_possible_truncation.rs +++ b/clippy_lints/src/casts/cast_possible_truncation.rs @@ -4,13 +4,13 @@ use clippy_utils::expr_or_init; use clippy_utils::source::snippet; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize}; +use rustc_abi::IntegerType; use rustc_errors::{Applicability, Diag}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty::{self, FloatTy, Ty}; use rustc_span::Span; -use rustc_target::abi::IntegerType; use super::{CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION, utils}; diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index a89f0d9c4327..c55d4387d696 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -10,7 +10,7 @@ use rustc_session::impl_lint_pass; use rustc_span::Span; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; pub struct BoxedLocal { too_large_for_stack: u64, @@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { fn_def_id: LocalDefId, ) { if let Some(header) = fn_kind.header() { - if header.abi != Abi::Rust { + if header.abi != ExternAbi::Rust { return; } } diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index f90bf9157aad..ae3acc1c4b19 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ }; use rustc_session::declare_lint_pass; use rustc_span::symbol::sym; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; use rustc_trait_selection::error_reporting::InferCtxtErrorExt as _; declare_clippy_lint! { @@ -172,7 +172,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx && let output = typeck.expr_ty(body.value) && let ty::Tuple(tys) = *subs.type_at(1).kind() { - cx.tcx.mk_fn_sig(tys, output, false, Safety::Safe, Abi::Rust) + cx.tcx.mk_fn_sig(tys, output, false, Safety::Safe, ExternAbi::Rust) } else { return; } diff --git a/clippy_lints/src/excessive_bools.rs b/clippy_lints/src/excessive_bools.rs index 0011da03dda7..15afe3e8c145 100644 --- a/clippy_lints/src/excessive_bools.rs +++ b/clippy_lints/src/excessive_bools.rs @@ -7,7 +7,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::Span; use rustc_span::def_id::LocalDefId; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; declare_clippy_lint! { /// ### What it does @@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'tcx>) { // functions with a body are already checked by `check_fn` if let TraitItemKind::Fn(fn_sig, TraitFn::Required(_)) = &trait_item.kind - && fn_sig.header.abi == Abi::Rust + && fn_sig.header.abi == ExternAbi::Rust && fn_sig.decl.inputs.len() as u64 > self.max_fn_params_bools { check_fn_decl(cx, fn_sig.decl, fn_sig.span, self.max_fn_params_bools); @@ -162,7 +162,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools { def_id: LocalDefId, ) { if let Some(fn_header) = fn_kind.header() - && fn_header.abi == Abi::Rust + && fn_header.abi == ExternAbi::Rust && fn_decl.inputs.len() as u64 > self.max_fn_params_bools && get_parent_as_impl(cx.tcx, cx.tcx.local_def_id_to_hir_id(def_id)) .is_none_or(|impl_item| impl_item.of_trait.is_none()) diff --git a/clippy_lints/src/functions/too_many_arguments.rs b/clippy_lints/src/functions/too_many_arguments.rs index e72a2ad49d82..f17f687719f2 100644 --- a/clippy_lints/src/functions/too_many_arguments.rs +++ b/clippy_lints/src/functions/too_many_arguments.rs @@ -1,7 +1,7 @@ use rustc_hir::{self as hir, intravisit}; use rustc_lint::LateContext; use rustc_span::Span; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_trait_impl_item; @@ -23,11 +23,11 @@ pub(super) fn check_fn( intravisit::FnKind::Method( _, &hir::FnSig { - header: hir::FnHeader { abi: Abi::Rust, .. }, + header: hir::FnHeader { abi: ExternAbi::Rust, .. }, .. }, ) - | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }) => check_arg_number( + | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: ExternAbi::Rust, .. }) => check_arg_number( cx, decl, span.with_hi(decl.output.span().hi()), @@ -41,7 +41,7 @@ pub(super) fn check_fn( pub(super) fn check_trait_item(cx: &LateContext<'_>, item: &hir::TraitItem<'_>, too_many_arguments_threshold: u64) { if let hir::TraitItemKind::Fn(ref sig, _) = item.kind { // don't lint extern functions decls, it's not their fault - if sig.header.abi == Abi::Rust { + if sig.header.abi == ExternAbi::Rust { check_arg_number( cx, sig.decl, diff --git a/clippy_lints/src/inherent_to_string.rs b/clippy_lints/src/inherent_to_string.rs index 415b47adac5a..c58e8773e3a2 100644 --- a/clippy_lints/src/inherent_to_string.rs +++ b/clippy_lints/src/inherent_to_string.rs @@ -5,7 +5,7 @@ use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::sym; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; declare_clippy_lint! { /// ### What it does @@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString { // #11201 && let header = signature.header && header.is_safe() - && header.abi == Abi::Rust + && header.abi == ExternAbi::Rust && impl_item.ident.name == sym::to_string && let decl = signature.decl && decl.implicit_self.has_implicit_self() diff --git a/clippy_lints/src/large_futures.rs b/clippy_lints/src/large_futures.rs index 593704f206a1..fd7965d564d5 100644 --- a/clippy_lints/src/large_futures.rs +++ b/clippy_lints/src/large_futures.rs @@ -2,11 +2,11 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; use clippy_utils::ty::implements_trait; +use rustc_abi::Size; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, LangItem, MatchSource, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_target::abi::Size; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index f501cf060c2a..0a8eafad0e84 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -149,6 +149,7 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item}; use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty}; pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES; +use rustc_abi::ExternAbi; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind}; @@ -5447,7 +5448,7 @@ const FN_HEADER: hir::FnHeader = hir::FnHeader { safety: hir::HeaderSafety::Normal(hir::Safety::Safe), constness: hir::Constness::NotConst, asyncness: hir::IsAsync::NotAsync, - abi: rustc_target::spec::abi::Abi::Rust, + abi: ExternAbi::Rust, }; struct ShouldImplTraitCase { diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index 962d85c6a9d3..ba4af134ccd0 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -1,3 +1,4 @@ + use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::{self, Msrv}; @@ -12,7 +13,7 @@ use rustc_middle::ty; use rustc_session::impl_lint_pass; use rustc_span::Span; use rustc_span::def_id::LocalDefId; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; declare_clippy_lint! { /// ### What it does @@ -183,11 +184,11 @@ fn already_const(header: hir::FnHeader) -> bool { header.constness == Constness::Const } -fn could_be_const_with_abi(msrv: &Msrv, abi: Abi) -> bool { +fn could_be_const_with_abi(msrv: &Msrv, abi: ExternAbi) -> bool { match abi { - Abi::Rust => true, + ExternAbi::Rust => true, // `const extern "C"` was stabilized after 1.62.0 - Abi::C { unwind: false } => msrv.meets(msrvs::CONST_EXTERN_C_FN), + ExternAbi::C { unwind: false } => msrv.meets(msrvs::CONST_EXTERN_C_FN), // Rest ABIs are still unstable and need the `const_extern_fn` feature enabled. _ => msrv.meets(msrvs::CONST_EXTERN_FN), } diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index b7dc269061cf..996251fdf162 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -20,7 +20,7 @@ use rustc_session::impl_lint_pass; use rustc_span::Span; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; declare_clippy_lint! { /// ### What it does @@ -149,7 +149,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { return; } let attrs = cx.tcx.hir().attrs(hir_id); - if header.abi != Abi::Rust || requires_exact_signature(attrs) { + if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) { return; } header.is_async() diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 2855703b9d56..40c65d1ef9e8 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -19,7 +19,7 @@ use rustc_session::declare_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; use rustc_span::{Span, sym}; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; use rustc_trait_selection::traits; use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy; @@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { match kind { FnKind::ItemFn(.., header) => { let attrs = cx.tcx.hir().attrs(hir_id); - if header.abi != Abi::Rust || requires_exact_signature(attrs) { + if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) { return; } }, diff --git a/clippy_lints/src/no_mangle_with_rust_abi.rs b/clippy_lints/src/no_mangle_with_rust_abi.rs index 2e2916c957da..b73b9083a991 100644 --- a/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -5,7 +5,7 @@ use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::{BytePos, Pos}; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; declare_clippy_lint! { /// ### What it does @@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { for attr in attrs { if let Some(ident) = attr.ident() && ident.name == rustc_span::sym::no_mangle - && fn_sig.header.abi == Abi::Rust + && fn_sig.header.abi == ExternAbi::Rust && let Some((fn_attrs, _)) = fn_snippet.rsplit_once("fn") && !fn_attrs.contains("extern") { diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 147654675ec9..405bbfc9c6fa 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -5,6 +5,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_in_const_context; use clippy_utils::macros::macro_backtrace; use clippy_utils::ty::{InteriorMut, implements_trait}; +use rustc_abi::VariantIdx; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{ @@ -16,7 +17,6 @@ use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::{DUMMY_SP, Span, sym}; -use rustc_target::abi::VariantIdx; // FIXME: this is a correctness problem but there's no suitable // warn-by-default category. diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index b2089487a9f4..a3e89671eecd 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -19,7 +19,7 @@ use rustc_middle::ty::{self, RegionKind, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, sym}; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; declare_clippy_lint! { /// ### What it does @@ -277,7 +277,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { let hir_id = cx.tcx.local_def_id_to_hir_id(def_id); match kind { FnKind::ItemFn(.., header) => { - if header.abi != Abi::Rust { + if header.abi != ExternAbi::Rust { return; } let attrs = cx.tcx.hir().attrs(hir_id); diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 0b67594a9b19..7fba4b6a6c8b 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -19,7 +19,7 @@ use rustc_middle::ty::{self, Binder, ClauseKind, ExistentialPredicate, List, Pre use rustc_session::declare_lint_pass; use rustc_span::symbol::Symbol; use rustc_span::{Span, sym}; -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use std::{fmt, iter}; @@ -160,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { check_mut_from_ref(cx, sig, None); - if !matches!(sig.header.abi, Abi::Rust) { + if !matches!(sig.header.abi, ExternAbi::Rust) { // Ignore `extern` functions with non-Rust calling conventions return; } @@ -220,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { check_mut_from_ref(cx, sig, Some(body)); - if !matches!(sig.header.abi, Abi::Rust) { + if !matches!(sig.header.abi, ExternAbi::Rust) { // Ignore `extern` functions with non-Rust calling conventions return; } diff --git a/clippy_lints/src/types/type_complexity.rs b/clippy_lints/src/types/type_complexity.rs index 7f51660293b5..0704653385f1 100644 --- a/clippy_lints/src/types/type_complexity.rs +++ b/clippy_lints/src/types/type_complexity.rs @@ -1,9 +1,9 @@ use clippy_utils::diagnostics::span_lint; +use rustc_abi::ExternAbi; use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty}; use rustc_hir::{self as hir, AmbigArg, GenericParamKind, TyKind}; use rustc_lint::LateContext; use rustc_span::Span; -use rustc_target::spec::abi::Abi; use super::TYPE_COMPLEXITY; @@ -50,7 +50,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { TyKind::Path(..) | TyKind::Slice(..) | TyKind::Tup(..) | TyKind::Array(..) => (10 * self.nest, 1), // function types bring a lot of overhead - TyKind::BareFn(bare) if bare.abi == Abi::Rust => (50 * self.nest, 1), + TyKind::BareFn(bare) if bare.abi == ExternAbi::Rust => (50 * self.nest, 1), TyKind::TraitObject(param_bounds, _) => { let has_lifetime_parameters = param_bounds.iter().any(|bound| { diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 179d42a8b5dc..59aaaa3d9fb7 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -12,6 +12,7 @@ //! code was written, and check if the span contains that text. Note this will only work correctly //! if the span is not from a `macro_rules` based macro. +use rustc_abi::ExternAbi; use rustc_ast::AttrStyle; use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, TraitObjectSyntax, UintTy}; use rustc_ast::token::CommentKind; @@ -26,7 +27,6 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::symbol::{Ident, kw}; use rustc_span::{Span, Symbol}; -use rustc_target::spec::abi::Abi; /// The search pattern to look for. Used by `span_matches_pat` #[derive(Clone)] @@ -233,7 +233,7 @@ fn fn_header_search_pat(header: FnHeader) -> Pat { Pat::Str("const") } else if header.is_unsafe() { Pat::Str("unsafe") - } else if header.abi != Abi::Rust { + } else if header.abi != ExternAbi::Rust { Pat::Str("extern") } else { Pat::MultiStr(&["fn", "extern"]) @@ -375,7 +375,7 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) { TyKind::BareFn(bare_fn) => ( if bare_fn.safety.is_unsafe() { Pat::Str("unsafe") - } else if bare_fn.abi != Abi::Rust { + } else if bare_fn.abi != ExternAbi::Rust { Pat::Str("extern") } else { Pat::MultiStr(&["fn", "extern"]) diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index fab1db05d2e5..db82c458f703 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -9,6 +9,7 @@ use std::sync::Arc; use crate::source::{SpanRangeExt, walk_span_to_context}; use crate::{clip, is_direct_expn_of, sext, unsext}; +use rustc_abi::Size; use rustc_apfloat::Float; use rustc_apfloat::ieee::{Half, Quad}; use rustc_ast::ast::{self, LitFloatType, LitKind}; @@ -25,7 +26,6 @@ use rustc_middle::{bug, mir, span_bug}; use rustc_span::def_id::DefId; use rustc_span::symbol::Ident; use rustc_span::{SyntaxContext, sym}; -use rustc_target::abi::Size; use std::cell::Cell; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 337684b68f86..79cc50665800 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -29,6 +29,7 @@ // FIXME: switch to something more ergonomic here, once available. // (Currently there is no way to opt into sysroot crates without `extern crate`.) +extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_ast_pretty; extern crate rustc_attr_parsing; @@ -48,7 +49,6 @@ extern crate rustc_middle; extern crate rustc_mir_dataflow; extern crate rustc_session; extern crate rustc_span; -extern crate rustc_target; extern crate rustc_trait_selection; extern crate smallvec; @@ -123,7 +123,7 @@ use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{Ident, Symbol, kw}; use rustc_span::{InnerSpan, Span, sym}; -use rustc_target::abi::Integer; +use rustc_abi::Integer; use visitors::{Visitable, for_each_unconsumed_temporary}; use crate::consts::{ConstEvalCtxt, Constant, mir_to_const}; diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index e9a05c45747d..a5374f6904e3 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -4,6 +4,7 @@ use core::ops::ControlFlow; use itertools::Itertools; +use rustc_abi::VariantIdx; use rustc_ast::ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; @@ -23,7 +24,6 @@ use rustc_middle::ty::{ }; use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; -use rustc_target::abi::VariantIdx; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::{Obligation, ObligationCause}; From 2a60a25c5b93fc86bf3d5ec174c1b19ee5dca0e1 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 8 Feb 2025 04:56:56 +0000 Subject: [PATCH 073/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 04b9f1c3fa3e..dd48038e07a0 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -942db6782f4a28c55b0b75b38fd4394d0483390f +e0607238c95df66e3d25a6c17aebe18c6726fc74 From 5e3b968da05a24d3e29a574b24eddf1181795b3c Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Sun, 9 Feb 2025 06:49:38 +0900 Subject: [PATCH 074/991] remove "Known problems" section for `branches_sharing_code` --- clippy_lints/src/copies.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 7c783df4f805..03ed9c657b30 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -129,11 +129,6 @@ declare_clippy_lint! { /// ### Why is this bad? /// Duplicate code is less maintainable. /// - /// ### Known problems - /// * The lint doesn't check if the moved expressions modify values that are being used in - /// the if condition. The suggestion can in that case modify the behavior of the program. - /// See [rust-clippy#7452](https://github.com/rust-lang/rust-clippy/issues/7452) - /// /// ### Example /// ```ignore /// let foo = if … { From aad3686823ea20280dc461dfae935fdffdaf5162 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 9 Feb 2025 01:53:19 +0100 Subject: [PATCH 075/991] Add error markers for `obfuscated_if_else` lint --- tests/ui/obfuscated_if_else.fixed | 6 ++++++ tests/ui/obfuscated_if_else.rs | 6 ++++++ tests/ui/obfuscated_if_else.stderr | 10 +++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/ui/obfuscated_if_else.fixed b/tests/ui/obfuscated_if_else.fixed index bfe1c5e10cf8..4fe48c5ca543 100644 --- a/tests/ui/obfuscated_if_else.fixed +++ b/tests/ui/obfuscated_if_else.fixed @@ -3,16 +3,22 @@ fn main() { if true { "a" } else { "b" }; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` if true { "a" } else { "b" }; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` let a = 1; if a == 1 { "a" } else { "b" }; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` if a == 1 { "a" } else { "b" }; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` let partial = (a == 1).then_some("a"); partial.unwrap_or("b"); // not lint let mut a = 0; if true { a += 1 } else { () }; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` if true { () } else { a += 2 }; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` } diff --git a/tests/ui/obfuscated_if_else.rs b/tests/ui/obfuscated_if_else.rs index 0ded2a2ceedf..e1de6d0f4cff 100644 --- a/tests/ui/obfuscated_if_else.rs +++ b/tests/ui/obfuscated_if_else.rs @@ -3,16 +3,22 @@ fn main() { true.then_some("a").unwrap_or("b"); + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` true.then(|| "a").unwrap_or("b"); + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` let a = 1; (a == 1).then_some("a").unwrap_or("b"); + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` (a == 1).then(|| "a").unwrap_or("b"); + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` let partial = (a == 1).then_some("a"); partial.unwrap_or("b"); // not lint let mut a = 0; true.then_some(a += 1).unwrap_or(()); + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` true.then_some(()).unwrap_or(a += 2); + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` } diff --git a/tests/ui/obfuscated_if_else.stderr b/tests/ui/obfuscated_if_else.stderr index 9ce1f475c480..175d57b49570 100644 --- a/tests/ui/obfuscated_if_else.stderr +++ b/tests/ui/obfuscated_if_else.stderr @@ -8,31 +8,31 @@ LL | true.then_some("a").unwrap_or("b"); = help: to override `-D warnings` add `#[allow(clippy::obfuscated_if_else)]` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:6:5 + --> tests/ui/obfuscated_if_else.rs:7:5 | LL | true.then(|| "a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:9:5 + --> tests/ui/obfuscated_if_else.rs:11:5 | LL | (a == 1).then_some("a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:10:5 + --> tests/ui/obfuscated_if_else.rs:13:5 | LL | (a == 1).then(|| "a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:16:5 + --> tests/ui/obfuscated_if_else.rs:20:5 | LL | true.then_some(a += 1).unwrap_or(()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { a += 1 } else { () }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:17:5 + --> tests/ui/obfuscated_if_else.rs:22:5 | LL | true.then_some(()).unwrap_or(a += 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { a += 2 }` From ac0a11a8bc80befca52af0712e015b4c42ee3769 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 31 Jan 2025 23:25:26 +0100 Subject: [PATCH 076/991] Fix `obfuscated_if_else` suggestion on left side of a binary expr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An `if … { … } else { … }` used as the left operand of a binary expression requires parentheses to be parsed as an expression. --- .../src/methods/obfuscated_if_else.rs | 12 +++++ tests/ui/obfuscated_if_else.fixed | 26 ++++++++++ tests/ui/obfuscated_if_else.rs | 26 ++++++++++ tests/ui/obfuscated_if_else.stderr | 50 ++++++++++++++++++- 4 files changed, 113 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/methods/obfuscated_if_else.rs b/clippy_lints/src/methods/obfuscated_if_else.rs index b71f79f84824..2272e03ef26e 100644 --- a/clippy_lints/src/methods/obfuscated_if_else.rs +++ b/clippy_lints/src/methods/obfuscated_if_else.rs @@ -1,6 +1,7 @@ use super::OBFUSCATED_IF_ELSE; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::eager_or_lazy::switch_to_eager_eval; +use clippy_utils::get_parent_expr; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; @@ -41,6 +42,17 @@ pub(super) fn check<'tcx>( snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability) ); + // To be parsed as an expression, the `if { … } else { … }` as the left operand of a binary operator + // requires parentheses. + let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr) + && let ExprKind::Binary(_, left, _) = parent_expr.kind + && left.hir_id == expr.hir_id + { + format!("({sugg})") + } else { + sugg + }; + span_lint_and_sugg( cx, OBFUSCATED_IF_ELSE, diff --git a/tests/ui/obfuscated_if_else.fixed b/tests/ui/obfuscated_if_else.fixed index 4fe48c5ca543..2cdbee90d52d 100644 --- a/tests/ui/obfuscated_if_else.fixed +++ b/tests/ui/obfuscated_if_else.fixed @@ -22,3 +22,29 @@ fn main() { if true { () } else { a += 2 }; //~^ ERROR: this method chain can be written more clearly with `if .. else ..` } + +fn issue11141() { + // Parentheses are required around the left side of a binary expression + let _ = (if true { 40 } else { 17 }) | 2; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are required only for the leftmost expression + let _ = (if true { 30 } else { 17 }) | if true { 2 } else { 3 } | if true { 10 } else { 1 }; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are not required around the right side of a binary expression + let _ = 2 | if true { 40 } else { 17 }; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are not required for a cast + let _ = if true { 42 } else { 17 } as u8; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are not required for a deref + let _ = *if true { &42 } else { &17 }; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are not required for a deref followed by a cast + let _ = *if true { &42 } else { &17 } as u8; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` +} diff --git a/tests/ui/obfuscated_if_else.rs b/tests/ui/obfuscated_if_else.rs index e1de6d0f4cff..20c67e729926 100644 --- a/tests/ui/obfuscated_if_else.rs +++ b/tests/ui/obfuscated_if_else.rs @@ -22,3 +22,29 @@ fn main() { true.then_some(()).unwrap_or(a += 2); //~^ ERROR: this method chain can be written more clearly with `if .. else ..` } + +fn issue11141() { + // Parentheses are required around the left side of a binary expression + let _ = true.then_some(40).unwrap_or(17) | 2; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are required only for the leftmost expression + let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are not required around the right side of a binary expression + let _ = 2 | true.then_some(40).unwrap_or(17); + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are not required for a cast + let _ = true.then_some(42).unwrap_or(17) as u8; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are not required for a deref + let _ = *true.then_some(&42).unwrap_or(&17); + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + + // Parentheses are not required for a deref followed by a cast + let _ = *true.then_some(&42).unwrap_or(&17) as u8; + //~^ ERROR: this method chain can be written more clearly with `if .. else ..` +} diff --git a/tests/ui/obfuscated_if_else.stderr b/tests/ui/obfuscated_if_else.stderr index 175d57b49570..9b1aebb58940 100644 --- a/tests/ui/obfuscated_if_else.stderr +++ b/tests/ui/obfuscated_if_else.stderr @@ -37,5 +37,53 @@ error: this method chain can be written more clearly with `if .. else ..` LL | true.then_some(()).unwrap_or(a += 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { a += 2 }` -error: aborting due to 6 previous errors +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:28:13 + | +LL | let _ = true.then_some(40).unwrap_or(17) | 2; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 40 } else { 17 })` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:32:13 + | +LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 30 } else { 17 })` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:32:48 + | +LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 2 } else { 3 }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:32:81 + | +LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 10 } else { 1 }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:36:17 + | +LL | let _ = 2 | true.then_some(40).unwrap_or(17); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 40 } else { 17 }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:40:13 + | +LL | let _ = true.then_some(42).unwrap_or(17) as u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 42 } else { 17 }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:44:14 + | +LL | let _ = *true.then_some(&42).unwrap_or(&17); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:48:14 + | +LL | let _ = *true.then_some(&42).unwrap_or(&17) as u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` + +error: aborting due to 14 previous errors From 657dda7b5091001a22722b4eeacdeddfe62b3b54 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 9 Feb 2025 17:45:09 +0100 Subject: [PATCH 077/991] `let_and_return`: look for non-static references in expansion as well One cannot avoid descending into expansion results when looking for non-static references, or there is a risk of false negative which would then trigger the `let_and_return` lint. --- clippy_lints/src/returns.rs | 4 ++-- tests/ui/let_and_return.fixed | 10 ++++++++++ tests/ui/let_and_return.rs | 10 ++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index a1cf16e6ce9f..3fcab6a766b8 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::source::{SpanRangeExt, snippet_with_context}; use clippy_utils::sugg::has_enclosing_paren; -use clippy_utils::visitors::{Descend, for_each_expr}; +use clippy_utils::visitors::for_each_expr; use clippy_utils::{ binary_expr_needs_parentheses, fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, leaks_droppable_temporary_with_limited_lifetime, path_res, path_to_local_id, span_contains_cfg, @@ -483,7 +483,7 @@ fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { ControlFlow::Break(()) } else { - ControlFlow::Continue(Descend::from(!e.span.from_expansion())) + ControlFlow::Continue(()) } }) .is_some() diff --git a/tests/ui/let_and_return.fixed b/tests/ui/let_and_return.fixed index b68b41cdca23..e22e66eb522e 100644 --- a/tests/ui/let_and_return.fixed +++ b/tests/ui/let_and_return.fixed @@ -244,4 +244,14 @@ fn issue12801() { } } +// Do not lint +fn issue14164() -> Result { + let v = std::cell::RefCell::new(Some(vec![1])); + let r = match &*v.borrow() { + Some(v) => Ok(Ok(v[0])), + None => Ok(Ok(0)), + }?; + r +} + fn main() {} diff --git a/tests/ui/let_and_return.rs b/tests/ui/let_and_return.rs index 6b9035f94288..f9da55946c0b 100644 --- a/tests/ui/let_and_return.rs +++ b/tests/ui/let_and_return.rs @@ -244,4 +244,14 @@ fn issue12801() { } } +// Do not lint +fn issue14164() -> Result { + let v = std::cell::RefCell::new(Some(vec![1])); + let r = match &*v.borrow() { + Some(v) => Ok(Ok(v[0])), + None => Ok(Ok(0)), + }?; + r +} + fn main() {} From 5d2fe079ab8cbc8aaea26932d978d76b09b24f3f Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 9 Feb 2025 18:06:11 +0100 Subject: [PATCH 078/991] =?UTF-8?q?`let=5Fand=5Freturn`:=20lint=20more=20c?= =?UTF-8?q?ases=20in=20edition=20=E2=89=A5=202024?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matches/significant_drop_in_scrutinee.rs | 6 +- clippy_lints/src/returns.rs | 3 +- tests/ui/let_and_return.edition2021.fixed | 265 ++++++++++++++++++ tests/ui/let_and_return.edition2021.stderr | 152 ++++++++++ tests/ui/let_and_return.edition2024.fixed | 265 ++++++++++++++++++ tests/ui/let_and_return.edition2024.stderr | 228 +++++++++++++++ tests/ui/let_and_return.rs | 10 +- 7 files changed, 923 insertions(+), 6 deletions(-) create mode 100644 tests/ui/let_and_return.edition2021.fixed create mode 100644 tests/ui/let_and_return.edition2021.stderr create mode 100644 tests/ui/let_and_return.edition2024.fixed create mode 100644 tests/ui/let_and_return.edition2024.stderr diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index 35f2e780d2e2..37bac561a6e0 100644 --- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -199,7 +199,7 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> { return false; } - let result = match ty.kind() { + match ty.kind() { rustc_middle::ty::Adt(adt, args) => { // if some field has significant drop, adt.all_fields() @@ -223,9 +223,7 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> { rustc_middle::ty::Tuple(tys) => tys.iter().any(|ty| self.has_sig_drop_attr_impl(ty)), rustc_middle::ty::Array(ty, _) | rustc_middle::ty::Slice(ty) => self.has_sig_drop_attr_impl(*ty), _ => false, - }; - - result + } } } diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 3fcab6a766b8..0286c9843a94 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -21,6 +21,7 @@ use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_session::declare_lint_pass; use rustc_span::def_id::LocalDefId; +use rustc_span::edition::Edition; use rustc_span::{BytePos, Pos, Span, sym}; use std::borrow::Cow; use std::fmt::Display; @@ -235,7 +236,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { && let Some(initexpr) = &local.init && let PatKind::Binding(_, local_id, _, _) = local.pat.kind && path_to_local_id(retexpr, local_id) - && !last_statement_borrows(cx, initexpr) + && (cx.sess().edition() >= Edition::Edition2024 || !last_statement_borrows(cx, initexpr)) && !initexpr.span.in_external_macro(cx.sess().source_map()) && !retexpr.span.in_external_macro(cx.sess().source_map()) && !local.span.from_expansion() diff --git a/tests/ui/let_and_return.edition2021.fixed b/tests/ui/let_and_return.edition2021.fixed new file mode 100644 index 000000000000..c160d5df30fd --- /dev/null +++ b/tests/ui/let_and_return.edition2021.fixed @@ -0,0 +1,265 @@ +//@revisions: edition2021 edition2024 +//@[edition2021] edition:2021 +//@[edition2024] edition:2024 + +#![allow(unused)] +#![warn(clippy::let_and_return)] + +use std::cell::RefCell; + +fn test() -> i32 { + let _y = 0; // no warning + + 5 + //~^ ERROR: returning the result of a `let` binding from a block + //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings` +} + +fn test_inner() -> i32 { + if true { + + 5 + //~^ ERROR: returning the result of a `let` binding from a block + } else { + 0 + } +} + +fn test_nowarn_1() -> i32 { + let mut x = 5; + x += 1; + x +} + +fn test_nowarn_2() -> i32 { + let x = 5; + x + 1 +} + +fn test_nowarn_3() -> (i32, i32) { + // this should technically warn, but we do not compare complex patterns + let (x, y) = (5, 9); + (x, y) +} + +fn test_nowarn_4() -> i32 { + // this should technically warn, but not b/c of clippy::let_and_return, but b/c of useless type + let x: i32 = 5; + x +} + +fn test_nowarn_5(x: i16) -> u16 { + #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] + let x = x as u16; + x +} + +// False positive example +trait Decode { + fn decode(d: D) -> Result + where + Self: Sized; +} + +macro_rules! tuple_encode { + ($($x:ident),*) => ( + impl<$($x: Decode),*> Decode for ($($x),*) { + #[inline] + #[allow(non_snake_case)] + fn decode(mut d: D) -> Result { + // Shouldn't trigger lint + Ok(($({let $x = Decode::decode(&mut d)?; $x }),*)) + } + } + ); +} + +fn issue_3792() -> String { + use std::io::{self, BufRead, Stdin}; + + let stdin = io::stdin(); + // `Stdin::lock` returns `StdinLock<'static>` so `line` doesn't borrow from `stdin` + // https://github.com/rust-lang/rust/pull/93965 + + stdin.lock().lines().next().unwrap().unwrap() + //~^ ERROR: returning the result of a `let` binding from a block +} + +tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7); + +mod no_lint_if_stmt_borrows { + use std::cell::RefCell; + use std::rc::{Rc, Weak}; + struct Bar; + + impl Bar { + fn new() -> Self { + Bar {} + } + fn baz(&self) -> u32 { + 0 + } + } + + fn issue_3324(value: Weak>) -> u32 { + let value = value.upgrade().unwrap(); + let ret = value.borrow().baz(); + ret + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + } + + fn borrows_in_closure(value: Weak>) -> u32 { + fn f(mut x: impl FnMut() -> u32) -> impl FnMut() -> u32 { + x + } + + let value = value.upgrade().unwrap(); + let ret = f(|| value.borrow().baz())(); + ret + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + } + + mod free_function { + struct Inner; + + struct Foo<'a> { + inner: &'a Inner, + } + + impl Drop for Foo<'_> { + fn drop(&mut self) {} + } + + impl<'a> Foo<'a> { + fn new(inner: &'a Inner) -> Self { + Self { inner } + } + + fn value(&self) -> i32 { + 42 + } + } + + fn some_foo(inner: &Inner) -> Foo<'_> { + Foo { inner } + } + + fn test() -> i32 { + let x = Inner {}; + let value = some_foo(&x).value(); + value + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + } + + fn test2() -> i32 { + let x = Inner {}; + let value = Foo::new(&x).value(); + value + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + } + } +} + +mod issue_5729 { + use std::sync::Arc; + + trait Foo {} + + trait FooStorage { + fn foo_cloned(&self) -> Arc; + } + + struct FooStorageImpl { + foo: Arc, + } + + impl FooStorage for FooStorageImpl { + fn foo_cloned(&self) -> Arc { + + (Arc::clone(&self.foo)) as _ + //~^ ERROR: returning the result of a `let` binding from a block + } + } +} + +mod issue_11335 { + pub enum E { + A(T), + B(T), + } + + impl E { + pub fn inner(&self) -> &T { + + + (match self { + E::A(x) => x, + E::B(x) => x, + }) as _ + //~^ ERROR: returning the result of a `let` binding from a block + } + } +} + +// https://github.com/rust-lang/rust-clippy/issues/11167 +macro_rules! fn_in_macro { + ($b:block) => { + fn f() -> usize $b + } +} +fn_in_macro!({ + return 1; +}); + +fn issue9150() -> usize { + let x = 1; + #[cfg(any())] + panic!("can't see me"); + x +} + +fn issue12801() { + fn left_is_if() -> String { + + (if true { "a".to_string() } else { "b".to_string() } + "c") + //~^ ERROR: returning the result of a `let` binding from a block + } + + fn no_par_needed() -> String { + + "c".to_string() + if true { "a" } else { "b" } + //~^ ERROR: returning the result of a `let` binding from a block + } + + fn conjunctive_blocks() -> String { + + ({ "a".to_string() } + "b" + { "c" } + "d") + //~^ ERROR: returning the result of a `let` binding from a block + } + + #[allow(clippy::overly_complex_bool_expr)] + fn other_ops() { + let _ = || { + + (if true { 2 } else { 3 } << 4) + //~^ ERROR: returning the result of a `let` binding from a block + }; + let _ = || { + + ({ true } || { false } && { 2 <= 3 }) + //~^ ERROR: returning the result of a `let` binding from a block + }; + } +} + +fn issue14164() -> Result { + let v = std::cell::RefCell::new(Some(vec![1])); + let r = match &*v.borrow() { + Some(v) => Ok(Ok(v[0])), + None => Ok(Ok(0)), + }?; + r + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block +} + +fn main() {} diff --git a/tests/ui/let_and_return.edition2021.stderr b/tests/ui/let_and_return.edition2021.stderr new file mode 100644 index 000000000000..105fa7a722d7 --- /dev/null +++ b/tests/ui/let_and_return.edition2021.stderr @@ -0,0 +1,152 @@ +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:13:5 + | +LL | let x = 5; + | ---------- unnecessary `let` binding +LL | x + | ^ + | + = note: `-D clippy::let-and-return` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]` +help: return the expression directly + | +LL ~ +LL ~ 5 + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:21:9 + | +LL | let x = 5; + | ---------- unnecessary `let` binding +LL | x + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ 5 + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:84:5 + | +LL | let line = stdin.lock().lines().next().unwrap().unwrap(); + | --------------------------------------------------------- unnecessary `let` binding +LL | line + | ^^^^ + | +help: return the expression directly + | +LL ~ +LL ~ stdin.lock().lines().next().unwrap().unwrap() + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:179:13 + | +LL | let clone = Arc::clone(&self.foo); + | ---------------------------------- unnecessary `let` binding +LL | clone + | ^^^^^ + | +help: return the expression directly + | +LL ~ +LL ~ (Arc::clone(&self.foo)) as _ + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:198:13 + | +LL | / let result = match self { +LL | | E::A(x) => x, +LL | | E::B(x) => x, +LL | | }; + | |______________- unnecessary `let` binding +LL | +LL | result + | ^^^^^^ + | +help: return the expression directly + | +LL ~ +LL | +LL ~ (match self { +LL + E::A(x) => x, +LL + E::B(x) => x, +LL + }) as _ + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:224:9 + | +LL | let s = if true { "a".to_string() } else { "b".to_string() } + "c"; + | ------------------------------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ (if true { "a".to_string() } else { "b".to_string() } + "c") + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:230:9 + | +LL | let s = "c".to_string() + if true { "a" } else { "b" }; + | ------------------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ "c".to_string() + if true { "a" } else { "b" } + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:236:9 + | +LL | let s = { "a".to_string() } + "b" + { "c" } + "d"; + | -------------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ ({ "a".to_string() } + "b" + { "c" } + "d") + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:244:13 + | +LL | let s = if true { 2 } else { 3 } << 4; + | -------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ (if true { 2 } else { 3 } << 4) + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:249:13 + | +LL | let s = { true } || { false } && { 2 <= 3 }; + | -------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ ({ true } || { false } && { 2 <= 3 }) + | + +error: aborting due to 10 previous errors + diff --git a/tests/ui/let_and_return.edition2024.fixed b/tests/ui/let_and_return.edition2024.fixed new file mode 100644 index 000000000000..f958f70e1dcf --- /dev/null +++ b/tests/ui/let_and_return.edition2024.fixed @@ -0,0 +1,265 @@ +//@revisions: edition2021 edition2024 +//@[edition2021] edition:2021 +//@[edition2024] edition:2024 + +#![allow(unused)] +#![warn(clippy::let_and_return)] + +use std::cell::RefCell; + +fn test() -> i32 { + let _y = 0; // no warning + + 5 + //~^ ERROR: returning the result of a `let` binding from a block + //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings` +} + +fn test_inner() -> i32 { + if true { + + 5 + //~^ ERROR: returning the result of a `let` binding from a block + } else { + 0 + } +} + +fn test_nowarn_1() -> i32 { + let mut x = 5; + x += 1; + x +} + +fn test_nowarn_2() -> i32 { + let x = 5; + x + 1 +} + +fn test_nowarn_3() -> (i32, i32) { + // this should technically warn, but we do not compare complex patterns + let (x, y) = (5, 9); + (x, y) +} + +fn test_nowarn_4() -> i32 { + // this should technically warn, but not b/c of clippy::let_and_return, but b/c of useless type + let x: i32 = 5; + x +} + +fn test_nowarn_5(x: i16) -> u16 { + #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] + let x = x as u16; + x +} + +// False positive example +trait Decode { + fn decode(d: D) -> Result + where + Self: Sized; +} + +macro_rules! tuple_encode { + ($($x:ident),*) => ( + impl<$($x: Decode),*> Decode for ($($x),*) { + #[inline] + #[allow(non_snake_case)] + fn decode(mut d: D) -> Result { + // Shouldn't trigger lint + Ok(($({let $x = Decode::decode(&mut d)?; $x }),*)) + } + } + ); +} + +fn issue_3792() -> String { + use std::io::{self, BufRead, Stdin}; + + let stdin = io::stdin(); + // `Stdin::lock` returns `StdinLock<'static>` so `line` doesn't borrow from `stdin` + // https://github.com/rust-lang/rust/pull/93965 + + stdin.lock().lines().next().unwrap().unwrap() + //~^ ERROR: returning the result of a `let` binding from a block +} + +tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7); + +mod no_lint_if_stmt_borrows { + use std::cell::RefCell; + use std::rc::{Rc, Weak}; + struct Bar; + + impl Bar { + fn new() -> Self { + Bar {} + } + fn baz(&self) -> u32 { + 0 + } + } + + fn issue_3324(value: Weak>) -> u32 { + let value = value.upgrade().unwrap(); + + value.borrow().baz() + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + } + + fn borrows_in_closure(value: Weak>) -> u32 { + fn f(mut x: impl FnMut() -> u32) -> impl FnMut() -> u32 { + x + } + + let value = value.upgrade().unwrap(); + + f(|| value.borrow().baz())() + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + } + + mod free_function { + struct Inner; + + struct Foo<'a> { + inner: &'a Inner, + } + + impl Drop for Foo<'_> { + fn drop(&mut self) {} + } + + impl<'a> Foo<'a> { + fn new(inner: &'a Inner) -> Self { + Self { inner } + } + + fn value(&self) -> i32 { + 42 + } + } + + fn some_foo(inner: &Inner) -> Foo<'_> { + Foo { inner } + } + + fn test() -> i32 { + let x = Inner {}; + + some_foo(&x).value() + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + } + + fn test2() -> i32 { + let x = Inner {}; + + Foo::new(&x).value() + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + } + } +} + +mod issue_5729 { + use std::sync::Arc; + + trait Foo {} + + trait FooStorage { + fn foo_cloned(&self) -> Arc; + } + + struct FooStorageImpl { + foo: Arc, + } + + impl FooStorage for FooStorageImpl { + fn foo_cloned(&self) -> Arc { + + (Arc::clone(&self.foo)) as _ + //~^ ERROR: returning the result of a `let` binding from a block + } + } +} + +mod issue_11335 { + pub enum E { + A(T), + B(T), + } + + impl E { + pub fn inner(&self) -> &T { + + + (match self { + E::A(x) => x, + E::B(x) => x, + }) as _ + //~^ ERROR: returning the result of a `let` binding from a block + } + } +} + +// https://github.com/rust-lang/rust-clippy/issues/11167 +macro_rules! fn_in_macro { + ($b:block) => { + fn f() -> usize $b + } +} +fn_in_macro!({ + return 1; +}); + +fn issue9150() -> usize { + let x = 1; + #[cfg(any())] + panic!("can't see me"); + x +} + +fn issue12801() { + fn left_is_if() -> String { + + (if true { "a".to_string() } else { "b".to_string() } + "c") + //~^ ERROR: returning the result of a `let` binding from a block + } + + fn no_par_needed() -> String { + + "c".to_string() + if true { "a" } else { "b" } + //~^ ERROR: returning the result of a `let` binding from a block + } + + fn conjunctive_blocks() -> String { + + ({ "a".to_string() } + "b" + { "c" } + "d") + //~^ ERROR: returning the result of a `let` binding from a block + } + + #[allow(clippy::overly_complex_bool_expr)] + fn other_ops() { + let _ = || { + + (if true { 2 } else { 3 } << 4) + //~^ ERROR: returning the result of a `let` binding from a block + }; + let _ = || { + + ({ true } || { false } && { 2 <= 3 }) + //~^ ERROR: returning the result of a `let` binding from a block + }; + } +} + +fn issue14164() -> Result { + let v = std::cell::RefCell::new(Some(vec![1])); + + match &*v.borrow() { + Some(v) => Ok(Ok(v[0])), + None => Ok(Ok(0)), + }? + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block +} + +fn main() {} diff --git a/tests/ui/let_and_return.edition2024.stderr b/tests/ui/let_and_return.edition2024.stderr new file mode 100644 index 000000000000..ec87e32b582d --- /dev/null +++ b/tests/ui/let_and_return.edition2024.stderr @@ -0,0 +1,228 @@ +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:13:5 + | +LL | let x = 5; + | ---------- unnecessary `let` binding +LL | x + | ^ + | + = note: `-D clippy::let-and-return` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]` +help: return the expression directly + | +LL ~ +LL ~ 5 + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:21:9 + | +LL | let x = 5; + | ---------- unnecessary `let` binding +LL | x + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ 5 + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:84:5 + | +LL | let line = stdin.lock().lines().next().unwrap().unwrap(); + | --------------------------------------------------------- unnecessary `let` binding +LL | line + | ^^^^ + | +help: return the expression directly + | +LL ~ +LL ~ stdin.lock().lines().next().unwrap().unwrap() + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:107:9 + | +LL | let ret = value.borrow().baz(); + | ------------------------------- unnecessary `let` binding +LL | ret + | ^^^ + | +help: return the expression directly + | +LL ~ +LL ~ value.borrow().baz() + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:118:9 + | +LL | let ret = f(|| value.borrow().baz())(); + | --------------------------------------- unnecessary `let` binding +LL | ret + | ^^^ + | +help: return the expression directly + | +LL ~ +LL ~ f(|| value.borrow().baz())() + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:150:13 + | +LL | let value = some_foo(&x).value(); + | --------------------------------- unnecessary `let` binding +LL | value + | ^^^^^ + | +help: return the expression directly + | +LL ~ +LL ~ some_foo(&x).value() + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:157:13 + | +LL | let value = Foo::new(&x).value(); + | --------------------------------- unnecessary `let` binding +LL | value + | ^^^^^ + | +help: return the expression directly + | +LL ~ +LL ~ Foo::new(&x).value() + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:179:13 + | +LL | let clone = Arc::clone(&self.foo); + | ---------------------------------- unnecessary `let` binding +LL | clone + | ^^^^^ + | +help: return the expression directly + | +LL ~ +LL ~ (Arc::clone(&self.foo)) as _ + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:198:13 + | +LL | / let result = match self { +LL | | E::A(x) => x, +LL | | E::B(x) => x, +LL | | }; + | |______________- unnecessary `let` binding +LL | +LL | result + | ^^^^^^ + | +help: return the expression directly + | +LL ~ +LL | +LL ~ (match self { +LL + E::A(x) => x, +LL + E::B(x) => x, +LL + }) as _ + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:224:9 + | +LL | let s = if true { "a".to_string() } else { "b".to_string() } + "c"; + | ------------------------------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ (if true { "a".to_string() } else { "b".to_string() } + "c") + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:230:9 + | +LL | let s = "c".to_string() + if true { "a" } else { "b" }; + | ------------------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ "c".to_string() + if true { "a" } else { "b" } + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:236:9 + | +LL | let s = { "a".to_string() } + "b" + { "c" } + "d"; + | -------------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ ({ "a".to_string() } + "b" + { "c" } + "d") + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:244:13 + | +LL | let s = if true { 2 } else { 3 } << 4; + | -------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ (if true { 2 } else { 3 } << 4) + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:249:13 + | +LL | let s = { true } || { false } && { 2 <= 3 }; + | -------------------------------------------- unnecessary `let` binding +LL | s + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ ({ true } || { false } && { 2 <= 3 }) + | + +error: returning the result of a `let` binding from a block + --> tests/ui/let_and_return.rs:261:5 + | +LL | / let r = match &*v.borrow() { +LL | | Some(v) => Ok(Ok(v[0])), +LL | | None => Ok(Ok(0)), +LL | | }?; + | |_______- unnecessary `let` binding +LL | r + | ^ + | +help: return the expression directly + | +LL ~ +LL ~ match &*v.borrow() { +LL + Some(v) => Ok(Ok(v[0])), +LL + None => Ok(Ok(0)), +LL + }? + | + +error: aborting due to 15 previous errors + diff --git a/tests/ui/let_and_return.rs b/tests/ui/let_and_return.rs index f9da55946c0b..0b7a1e26890f 100644 --- a/tests/ui/let_and_return.rs +++ b/tests/ui/let_and_return.rs @@ -1,3 +1,7 @@ +//@revisions: edition2021 edition2024 +//@[edition2021] edition:2021 +//@[edition2024] edition:2024 + #![allow(unused)] #![warn(clippy::let_and_return)] @@ -101,6 +105,7 @@ mod no_lint_if_stmt_borrows { let value = value.upgrade().unwrap(); let ret = value.borrow().baz(); ret + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block } fn borrows_in_closure(value: Weak>) -> u32 { @@ -111,6 +116,7 @@ mod no_lint_if_stmt_borrows { let value = value.upgrade().unwrap(); let ret = f(|| value.borrow().baz())(); ret + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block } mod free_function { @@ -142,12 +148,14 @@ mod no_lint_if_stmt_borrows { let x = Inner {}; let value = some_foo(&x).value(); value + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block } fn test2() -> i32 { let x = Inner {}; let value = Foo::new(&x).value(); value + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block } } } @@ -244,7 +252,6 @@ fn issue12801() { } } -// Do not lint fn issue14164() -> Result { let v = std::cell::RefCell::new(Some(vec![1])); let r = match &*v.borrow() { @@ -252,6 +259,7 @@ fn issue14164() -> Result { None => Ok(Ok(0)), }?; r + //~[edition2024]^ ERROR: returning the result of a `let` binding from a block } fn main() {} From 4d4ef0000c16fa89a51e39e022e5a2ebb891906d Mon Sep 17 00:00:00 2001 From: Yusuf Raji Date: Sun, 19 Jan 2025 16:30:58 +0100 Subject: [PATCH 079/991] Add single_option_map lint --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + clippy_lints/src/single_option_map.rs | 91 +++++++++++++++++++++++++++ tests/ui/single_option_map.rs | 69 ++++++++++++++++++++ tests/ui/single_option_map.stderr | 37 +++++++++++ 6 files changed, 201 insertions(+) create mode 100644 clippy_lints/src/single_option_map.rs create mode 100644 tests/ui/single_option_map.rs create mode 100644 tests/ui/single_option_map.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index fa03c953aa59..ea1119aca984 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6067,6 +6067,7 @@ Released 2018-09-13 [`single_element_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_element_loop [`single_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match [`single_match_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else +[`single_option_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_option_map [`single_range_in_vec_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_range_in_vec_init [`size_of_in_element_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_in_element_count [`size_of_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_ref diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 9fbeab5bf2e1..3d4ca4faecb4 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -684,6 +684,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::single_call_fn::SINGLE_CALL_FN_INFO, crate::single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES_INFO, crate::single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS_INFO, + crate::single_option_map::SINGLE_OPTION_MAP_INFO, crate::single_range_in_vec_init::SINGLE_RANGE_IN_VEC_INIT_INFO, crate::size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT_INFO, crate::size_of_ref::SIZE_OF_REF_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 8887ab7ec0d7..53a05a5a5586 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -339,6 +339,7 @@ mod significant_drop_tightening; mod single_call_fn; mod single_char_lifetime_names; mod single_component_path_imports; +mod single_option_map; mod single_range_in_vec_init; mod size_of_in_element_count; mod size_of_ref; @@ -978,5 +979,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::::default()); store.register_late_pass(move |_| Box::new(non_std_lazy_statics::NonStdLazyStatic::new(conf))); store.register_late_pass(|_| Box::new(manual_option_as_slice::ManualOptionAsSlice::new(conf))); + store.register_late_pass(|_| Box::new(single_option_map::SingleOptionMap)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/single_option_map.rs b/clippy_lints/src/single_option_map.rs new file mode 100644 index 000000000000..ad8463870a68 --- /dev/null +++ b/clippy_lints/src/single_option_map.rs @@ -0,0 +1,91 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::{path_res, peel_blocks}; +use rustc_hir::def::Res; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::intravisit::FnKind; +use rustc_hir::{Body, ExprKind, FnDecl, FnRetTy}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; +use rustc_span::{Span, sym}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for functions with method calls to `.map(_)` on an arg + /// of type `Option` as the outermost expression. + /// + /// ### Why is this bad? + /// Taking and returning an `Option` may require additional + /// `Some(_)` and `unwrap` if all you have is a `T`. + /// + /// ### Example + /// ```no_run + /// fn double(param: Option) -> Option { + /// param.map(|x| x * 2) + /// } + /// ``` + /// Use instead: + /// ```no_run + /// fn double(param: u32) -> u32 { + /// param * 2 + /// } + /// ``` + #[clippy::version = "1.86.0"] + pub SINGLE_OPTION_MAP, + nursery, + "Checks for functions with method calls to `.map(_)` on an arg of type `Option` as the outermost expression." +} + +declare_lint_pass!(SingleOptionMap => [SINGLE_OPTION_MAP]); + +impl<'tcx> LateLintPass<'tcx> for SingleOptionMap { + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + kind: FnKind<'tcx>, + decl: &'tcx FnDecl<'tcx>, + body: &'tcx Body<'tcx>, + span: Span, + _fn_def: LocalDefId, + ) { + if let FnRetTy::Return(_ret) = decl.output + && matches!(kind, FnKind::ItemFn(_, _, _) | FnKind::Method(_, _)) + { + let func_body = peel_blocks(body.value); + if let ExprKind::MethodCall(method_name, callee, args, _span) = func_body.kind + && method_name.ident.name == sym::map + && let callee_type = cx.typeck_results().expr_ty(callee) + && is_type_diagnostic_item(cx, callee_type, sym::Option) + && let ExprKind::Path(_path) = callee.kind + && let Res::Local(_id) = path_res(cx, callee) + && matches!(path_res(cx, callee), Res::Local(_id)) + && !matches!(args[0].kind, ExprKind::Path(_)) + { + if let ExprKind::Closure(closure) = args[0].kind { + let Body { params: [..], value } = cx.tcx.hir().body(closure.body); + if let ExprKind::Call(func, f_args) = value.kind + && matches!(func.kind, ExprKind::Path(_)) + && f_args.iter().all(|arg| matches!(arg.kind, ExprKind::Path(_))) + { + return; + } else if let ExprKind::MethodCall(_segment, receiver, method_args, _span) = value.kind + && matches!(receiver.kind, ExprKind::Path(_)) + && method_args.iter().all(|arg| matches!(arg.kind, ExprKind::Path(_))) + && method_args.iter().all(|arg| matches!(path_res(cx, arg), Res::Local(_))) + { + return; + } + } + + span_lint_and_help( + cx, + SINGLE_OPTION_MAP, + span, + "`fn` that only maps over argument", + None, + "move the `.map` to the caller or to an `_opt` function", + ); + } + } + } +} diff --git a/tests/ui/single_option_map.rs b/tests/ui/single_option_map.rs new file mode 100644 index 000000000000..571beec54799 --- /dev/null +++ b/tests/ui/single_option_map.rs @@ -0,0 +1,69 @@ +#![warn(clippy::single_option_map)] + +use std::sync::atomic::{AtomicUsize, Ordering}; + +static ATOM: AtomicUsize = AtomicUsize::new(42); +static MAYBE_ATOMIC: Option<&AtomicUsize> = Some(&ATOM); + +fn h(arg: Option) -> Option { + //~^ ERROR: `fn` that only maps over argument + arg.map(|x| x * 2) +} + +fn j(arg: Option) -> Option { + //~^ ERROR: `fn` that only maps over argument + arg.map(|x| x * 2) +} + +fn mul_args(a: String, b: u64) -> String { + a +} + +fn mul_args_opt(a: Option, b: u64) -> Option { + //~^ ERROR: `fn` that only maps over argument + a.map(|val| mul_args(val, b + 1)) +} + +// No lint: no `Option` argument argument +fn maps_static_option() -> Option { + MAYBE_ATOMIC.map(|a| a.load(Ordering::Relaxed)) +} + +// No lint: wrapped by another function +fn manipulate(i: i32) -> i32 { + i + 1 +} +// No lint: wraps another function to do the optional thing +fn manipulate_opt(opt_i: Option) -> Option { + opt_i.map(manipulate) +} + +// No lint: maps other than the receiver +fn map_not_arg(arg: Option) -> Option { + maps_static_option().map(|_| arg.unwrap()) +} + +// No lint: wrapper function with η-expanded form +#[allow(clippy::redundant_closure)] +fn manipulate_opt_explicit(opt_i: Option) -> Option { + opt_i.map(|x| manipulate(x)) +} + +// No lint +fn multi_args(a: String, b: bool, c: u64) -> String { + a +} + +// No lint: contains only map of a closure that binds other arguments +fn multi_args_opt(a: Option, b: bool, c: u64) -> Option { + a.map(|a| multi_args(a, b, c)) +} + +fn main() { + let answer = Some(42u32); + let h_result = h(answer); + + let answer = Some(42u64); + let j_result = j(answer); + maps_static_option(); +} diff --git a/tests/ui/single_option_map.stderr b/tests/ui/single_option_map.stderr new file mode 100644 index 000000000000..f7d48eba71e8 --- /dev/null +++ b/tests/ui/single_option_map.stderr @@ -0,0 +1,37 @@ +error: `fn` that only maps over argument + --> tests/ui/single_option_map.rs:8:1 + | +LL | / fn h(arg: Option) -> Option { +LL | | +LL | | arg.map(|x| x * 2) +LL | | } + | |_^ + | + = help: move the `.map` to the caller or to an `_opt` function + = note: `-D clippy::single-option-map` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::single_option_map)]` + +error: `fn` that only maps over argument + --> tests/ui/single_option_map.rs:13:1 + | +LL | / fn j(arg: Option) -> Option { +LL | | +LL | | arg.map(|x| x * 2) +LL | | } + | |_^ + | + = help: move the `.map` to the caller or to an `_opt` function + +error: `fn` that only maps over argument + --> tests/ui/single_option_map.rs:22:1 + | +LL | / fn mul_args_opt(a: Option, b: u64) -> Option { +LL | | +LL | | a.map(|val| mul_args(val, b + 1)) +LL | | } + | |_^ + | + = help: move the `.map` to the caller or to an `_opt` function + +error: aborting due to 3 previous errors + From 749eb371bf498224a03541980d4635db232c71b4 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Mon, 10 Feb 2025 20:13:21 +0900 Subject: [PATCH 080/991] correct "Affected lints" for `allow-one-hash-in-raw-strings` --- book/src/lint_configuration.md | 2 +- clippy_config/src/conf.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 6803a1db2bbd..f43c3a280727 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -108,7 +108,7 @@ Whether to allow `r#""#` when `r""` can be used --- **Affected lints:** -* [`unnecessary_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_raw_string_hashes) +* [`needless_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes) ## `allow-panic-in-tests` diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 10a17da15172..28e42c67d980 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -298,7 +298,7 @@ define_Conf! { #[lints(uninlined_format_args)] allow_mixed_uninlined_format_args: bool = true, /// Whether to allow `r#""#` when `r""` can be used - #[lints(unnecessary_raw_string_hashes)] + #[lints(needless_raw_string_hashes)] allow_one_hash_in_raw_strings: bool = false, /// Whether `panic` should be allowed in test functions or `#[cfg(test)]` #[lints(panic)] From b32ad4ce0a7f4aeb4dbb63032d8f42f67b773b14 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Mon, 10 Feb 2025 10:47:50 +0100 Subject: [PATCH 081/991] Use parentheses when needed in `nonminimal_bool` lint Since comparisons on types not implementing `Ord` (such as `f32`) are not inverted, they must be enclosed in parentheses when they are negated. --- clippy_lints/src/booleans.rs | 4 +++- tests/ui/nonminimal_bool.rs | 6 ++++++ tests/ui/nonminimal_bool.stderr | 8 +++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index f8c30d1c881d..ee21f9379a52 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -3,6 +3,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::eq_expr_value; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; +use clippy_utils::sugg::Sugg; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use rustc_ast::ast::LitKind; use rustc_attr_parsing::RustcVersion; @@ -353,7 +354,8 @@ impl SuggestContext<'_, '_, '_> { self.output.push_str(&str); } else { self.output.push('!'); - self.output.push_str(&terminal.span.get_source_text(self.cx)?); + self.output + .push_str(&Sugg::hir_opt(self.cx, terminal)?.maybe_par().to_string()); } }, True | False | Not(_) => { diff --git a/tests/ui/nonminimal_bool.rs b/tests/ui/nonminimal_bool.rs index 52b0155a762e..9d0a475064ed 100644 --- a/tests/ui/nonminimal_bool.rs +++ b/tests/ui/nonminimal_bool.rs @@ -183,3 +183,9 @@ fn issue_12371(x: usize) -> bool { fn many_ops(a: bool, b: bool, c: bool, d: bool, e: bool, f: bool) -> bool { (a && c && f) || (!a && b && !d) || (!b && !c && !e) || (d && e && !f) } + +fn issue14184(a: f32, b: bool) { + if !(a < 2.0 && !b) { + println!("Hi"); + } +} diff --git a/tests/ui/nonminimal_bool.stderr b/tests/ui/nonminimal_bool.stderr index 578f918f0139..129dadf315e4 100644 --- a/tests/ui/nonminimal_bool.stderr +++ b/tests/ui/nonminimal_bool.stderr @@ -213,5 +213,11 @@ error: this boolean expression can be simplified LL | if !b != !c {} | ^^^^^^^^ help: try: `b != c` -error: aborting due to 29 previous errors +error: this boolean expression can be simplified + --> tests/ui/nonminimal_bool.rs:188:8 + | +LL | if !(a < 2.0 && !b) { + | ^^^^^^^^^^^^^^^^ help: try: `!(a < 2.0) || b` + +error: aborting due to 30 previous errors From 91ff190391b33cb686381f49d568d3270b0de475 Mon Sep 17 00:00:00 2001 From: Bastian Kersting Date: Fri, 24 Jan 2025 14:08:30 +0000 Subject: [PATCH 082/991] Rename rustc_middle::Ty::is_unsafe_ptr to is_raw_ptr The wording unsafe pointer is less common and not mentioned in a lot of places, instead this is usually called a "raw pointer". For the sake of uniformity, we rename this method. This came up during the review of https://github.com/rust-lang/rust/pull/134424. --- clippy_lints/src/casts/cast_ptr_alignment.rs | 2 +- clippy_lints/src/dereference.rs | 2 +- clippy_lints/src/multiple_unsafe_ops_per_block.rs | 2 +- clippy_lints/src/pass_by_ref_or_value.rs | 6 +++--- clippy_lints/src/ptr_offset_with_cast.rs | 2 +- clippy_utils/src/eager_or_lazy.rs | 2 +- clippy_utils/src/visitors.rs | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/clippy_lints/src/casts/cast_ptr_alignment.rs b/clippy_lints/src/casts/cast_ptr_alignment.rs index e4c0db5d9ef0..57a135abc2e2 100644 --- a/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -66,7 +66,7 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { if matches!(name.ident.as_str(), "read_unaligned" | "write_unaligned") && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id) && let Some(def_id) = cx.tcx.impl_of_method(def_id) - && cx.tcx.type_of(def_id).instantiate_identity().is_unsafe_ptr() + && cx.tcx.type_of(def_id).instantiate_identity().is_raw_ptr() { true } else { diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 233ebe00d8e7..849c60b89b97 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -682,7 +682,7 @@ fn try_parse_ref_op<'tcx>( }, [arg], ) => (true, typeck.qpath_res(path, *hir_id).opt_def_id()?, arg), - ExprKind::Unary(UnOp::Deref, sub_expr) if !typeck.expr_ty(sub_expr).is_unsafe_ptr() => { + ExprKind::Unary(UnOp::Deref, sub_expr) if !typeck.expr_ty(sub_expr).is_raw_ptr() => { return Some((RefOp::Deref, sub_expr)); }, ExprKind::AddrOf(BorrowKind::Ref, mutability, sub_expr) => return Some((RefOp::AddrOf(mutability), sub_expr)), diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 9acede4f32d6..2adc27c0b709 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -122,7 +122,7 @@ fn collect_unsafe_exprs<'tcx>( unsafe_ops.push(("access of a mutable static occurs here", expr.span)); }, - ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty_adjusted(e).is_unsafe_ptr() => { + ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty_adjusted(e).is_raw_ptr() => { unsafe_ops.push(("raw pointer dereference occurs here", expr.span)); }, diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index a3e89671eecd..95403403217a 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -179,10 +179,10 @@ impl PassByRefOrValue { && let hir::TyKind::Ref(_, MutTy { ty: decl_ty, .. }) = input.kind { if let Some(typeck) = cx.maybe_typeck_results() { - // Don't lint if an unsafe pointer is created. - // TODO: Limit the check only to unsafe pointers to the argument (or part of the argument) + // Don't lint if a raw pointer is created. + // TODO: Limit the check only to raw pointers to the argument (or part of the argument) // which escape the current function. - if typeck.node_types().items().any(|(_, &ty)| ty.is_unsafe_ptr()) + if typeck.node_types().items().any(|(_, &ty)| ty.is_raw_ptr()) || typeck .adjustments() .items() diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs index 808a7e005c67..68ae575c9063 100644 --- a/clippy_lints/src/ptr_offset_with_cast.rs +++ b/clippy_lints/src/ptr_offset_with_cast.rs @@ -111,7 +111,7 @@ fn is_expr_ty_usize(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { // Is the type of the expression a raw pointer? fn is_expr_ty_raw_ptr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - cx.typeck_results().expr_ty(expr).is_unsafe_ptr() + cx.typeck_results().expr_ty(expr).is_raw_ptr() } fn build_suggestion( diff --git a/clippy_utils/src/eager_or_lazy.rs b/clippy_utils/src/eager_or_lazy.rs index b5bb174e737a..aaea8d71efbe 100644 --- a/clippy_utils/src/eager_or_lazy.rs +++ b/clippy_utils/src/eager_or_lazy.rs @@ -217,7 +217,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS self.eagerness |= NoChange; }, // Dereferences should be cheap, but dereferencing a raw pointer earlier may not be safe. - ExprKind::Unary(UnOp::Deref, e) if !self.cx.typeck_results().expr_ty(e).is_unsafe_ptr() => (), + ExprKind::Unary(UnOp::Deref, e) if !self.cx.typeck_results().expr_ty(e).is_raw_ptr() => (), ExprKind::Unary(UnOp::Deref, _) => self.eagerness |= NoChange, ExprKind::Unary(_, e) if matches!( diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs index 99984c41714b..70910f5bf52d 100644 --- a/clippy_utils/src/visitors.rs +++ b/clippy_utils/src/visitors.rs @@ -417,7 +417,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { } fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result { match e.kind { - ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_unsafe_ptr() => { + ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_raw_ptr() => { ControlFlow::Break(()) }, ExprKind::MethodCall(..) From 15d08ef98e9b2d28f0534804239122537a5893c8 Mon Sep 17 00:00:00 2001 From: Bastian Kersting Date: Fri, 24 Jan 2025 15:13:37 +0000 Subject: [PATCH 083/991] Convert two missed places --- clippy_lints/src/operators/ptr_eq.rs | 2 +- clippy_lints/src/swap_ptr_to_ref.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/operators/ptr_eq.rs b/clippy_lints/src/operators/ptr_eq.rs index 861564d54569..8118ad59bb71 100644 --- a/clippy_lints/src/operators/ptr_eq.rs +++ b/clippy_lints/src/operators/ptr_eq.rs @@ -53,7 +53,7 @@ fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_> // If the given expression is a cast to a `*const` pointer, return the lhs of the cast // E.g., `foo as *const _` returns `foo`. fn expr_as_cast_to_raw_pointer<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { - if cx.typeck_results().expr_ty(cast_expr).is_unsafe_ptr() { + if cx.typeck_results().expr_ty(cast_expr).is_raw_ptr() { if let ExprKind::Cast(expr, _) = cast_expr.kind { return Some(expr); } diff --git a/clippy_lints/src/swap_ptr_to_ref.rs b/clippy_lints/src/swap_ptr_to_ref.rs index 8c5cf93ab6e8..ff196355a2e3 100644 --- a/clippy_lints/src/swap_ptr_to_ref.rs +++ b/clippy_lints/src/swap_ptr_to_ref.rs @@ -76,7 +76,7 @@ impl LateLintPass<'_> for SwapPtrToRef { fn is_ptr_to_ref(cx: &LateContext<'_>, e: &Expr<'_>, ctxt: SyntaxContext) -> (bool, Option) { if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, borrowed_expr) = e.kind && let ExprKind::Unary(UnOp::Deref, derefed_expr) = borrowed_expr.kind - && cx.typeck_results().expr_ty(derefed_expr).is_unsafe_ptr() + && cx.typeck_results().expr_ty(derefed_expr).is_raw_ptr() { ( true, From 3a0b1ae59ddf210f6d9594035f74eb42bca8b27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Jul 2024 22:30:26 +0000 Subject: [PATCH 084/991] Show diff suggestion format on verbose replacement ``` error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> $DIR/attempted-access-non-fatal.rs:7:15 | LL | let _ = 2.l; | ^ | help: if intended to be a floating point literal, consider adding a `0` after the period and a `f64` suffix | LL - let _ = 2.l; LL + let _ = 2.0f64; | ``` --- tests/ui-toml/dbg_macro/dbg_macro.stderr | 31 +- .../doc_markdown.stderr | 5 +- .../doc_markdown.stderr | 15 +- .../enum_variant_size.stderr | 5 +- .../renamed_function_params.default.stderr | 5 +- .../renamed_function_params.extend.stderr | 5 +- tests/ui-toml/unwrap_used/unwrap_used.stderr | 75 +++-- tests/ui/assign_ops2.stderr | 90 +++-- tests/ui/bind_instead_of_map_multipart.stderr | 20 +- tests/ui/borrow_deref_ref_unfixable.stderr | 10 +- tests/ui/cast.stderr | 103 +++--- tests/ui/cast_lossless_bool.stderr | 75 +++-- tests/ui/cast_lossless_float.stderr | 65 ++-- tests/ui/cast_lossless_integer.stderr | 198 ++++++----- tests/ui/cast_size.64bit.stderr | 45 ++- tests/ui/create_dir.stderr | 10 +- tests/ui/dbg_macro/dbg_macro.stderr | 81 +++-- tests/ui/dbg_macro/dbg_macro_unfixable.stderr | 25 +- tests/ui/doc/doc-fixable.stderr | 161 +++++---- tests/ui/doc/doc_markdown-issue_13097.stderr | 5 +- tests/ui/doc/issue_10262.stderr | 5 +- tests/ui/doc/issue_12795.stderr | 20 +- tests/ui/doc/issue_9473.stderr | 5 +- tests/ui/doc/unbalanced_ticks.stderr | 15 +- tests/ui/eager_transmute.stderr | 85 +++-- tests/ui/empty_line_after/doc_comments.stderr | 5 +- tests/ui/excessive_precision.stderr | 80 +++-- tests/ui/fn_to_numeric_cast_any.stderr | 81 +++-- tests/ui/for_kv_map.stderr | 30 +- tests/ui/four_forward_slashes.stderr | 8 + .../ui/four_forward_slashes_first_line.stderr | 2 + tests/ui/get_unwrap.stderr | 85 +++-- tests/ui/implicit_hasher.stderr | 15 +- tests/ui/implicit_return.stderr | 67 ++-- tests/ui/iter_nth.stderr | 40 ++- tests/ui/join_absolute_paths.stderr | 40 ++- tests/ui/large_enum_variant.64bit.stderr | 65 ++-- tests/ui/legacy_numeric_constants.stderr | 80 +++-- tests/ui/literals.stderr | 35 +- tests/ui/lossy_float_literal.stderr | 55 +-- tests/ui/manual_assert.edition2018.stderr | 10 +- tests/ui/manual_assert.edition2021.stderr | 10 +- tests/ui/manual_async_fn.stderr | 60 ++-- tests/ui/manual_float_methods.stderr | 45 ++- tests/ui/manual_ignore_case_cmp.stderr | 245 ++++++++------ tests/ui/manual_is_ascii_check.stderr | 20 +- tests/ui/map_all_any_identity.stderr | 10 +- ...ap_with_unused_argument_over_ranges.stderr | 10 +- ...h_unused_argument_over_ranges_nostd.stderr | 5 +- tests/ui/match_result_ok.stderr | 15 +- tests/ui/match_str_case_mismatch.stderr | 35 +- tests/ui/needless_borrow_pat.stderr | 10 +- tests/ui/needless_for_each_unfixable.stderr | 5 +- tests/ui/needless_pass_by_value.stderr | 20 +- tests/ui/needless_range_loop.stderr | 70 ++-- tests/ui/needless_range_loop2.stderr | 40 ++- tests/ui/needless_return.stderr | 50 +-- tests/ui/never_loop.stderr | 10 +- .../ui/non_canonical_partial_ord_impl.stderr | 5 +- .../non_std_lazy_static_fixable.stderr | 15 +- .../non_std_lazy_static_unfixable.stderr | 15 +- tests/ui/nonminimal_bool.stderr | 50 +-- tests/ui/octal_escapes.stderr | 110 +++--- tests/ui/op_ref.stderr | 5 +- tests/ui/option_as_ref_cloned.stderr | 15 +- tests/ui/redundant_guards.stderr | 5 +- tests/ui/ref_binding_to_reference.stderr | 10 +- tests/ui/ref_option/ref_option.all.stderr | 10 +- tests/ui/ref_option/ref_option.private.stderr | 5 +- tests/ui/repeat_vec_with_capacity.stderr | 15 +- .../ui/repeat_vec_with_capacity_nostd.stderr | 5 +- tests/ui/reversed_empty_ranges_fixable.stderr | 20 +- ...reversed_empty_ranges_loops_fixable.stderr | 30 +- tests/ui/single_range_in_vec_init.stderr | 90 +++-- tests/ui/string_lit_chars_any.stderr | 25 +- tests/ui/suspicious_command_arg_space.stderr | 10 +- tests/ui/suspicious_doc_comments.stderr | 15 +- tests/ui/suspicious_to_owned.stderr | 40 ++- tests/ui/suspicious_xor_used_as_pow.stderr | 35 +- tests/ui/transmute_ptr_to_ptr.stderr | 55 +-- ...transmutes_expressible_as_ptr_casts.stderr | 10 +- tests/ui/unit_arg.stderr | 18 +- tests/ui/unknown_clippy_lints.stderr | 10 +- tests/ui/unnecessary_lazy_eval.stderr | 315 +++++++++++------- .../ui/unnecessary_lazy_eval_unfixable.stderr | 20 +- tests/ui/unnecessary_literal_unwrap.stderr | 50 +-- tests/ui/unnecessary_map_or.stderr | 48 ++- tests/ui/unnecessary_wraps.stderr | 44 ++- tests/ui/unnested_or_patterns.stderr | 85 +++-- tests/ui/unnested_or_patterns2.stderr | 40 ++- tests/ui/unused_enumerate_index.stderr | 10 +- tests/ui/unused_format_specs.stderr | 20 +- tests/ui/unused_result_ok.stderr | 20 +- 93 files changed, 2292 insertions(+), 1500 deletions(-) diff --git a/tests/ui-toml/dbg_macro/dbg_macro.stderr b/tests/ui-toml/dbg_macro/dbg_macro.stderr index 129fab5ff97a..f0d7104a57dd 100644 --- a/tests/ui-toml/dbg_macro/dbg_macro.stderr +++ b/tests/ui-toml/dbg_macro/dbg_macro.stderr @@ -8,8 +8,9 @@ LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]` help: remove the invocation before committing it to a version control system | -LL | if let Some(n) = n.checked_sub(4) { n } else { n } - | ~~~~~~~~~~~~~~~~ +LL - if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } +LL + if let Some(n) = n.checked_sub(4) { n } else { n } + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui-toml/dbg_macro/dbg_macro.rs:10:8 @@ -19,8 +20,9 @@ LL | if dbg!(n <= 1) { | help: remove the invocation before committing it to a version control system | -LL | if n <= 1 { - | ~~~~~~ +LL - if dbg!(n <= 1) { +LL + if n <= 1 { + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui-toml/dbg_macro/dbg_macro.rs:11:9 @@ -30,7 +32,8 @@ LL | dbg!(1) | help: remove the invocation before committing it to a version control system | -LL | 1 +LL - dbg!(1) +LL + 1 | error: the `dbg!` macro is intended as a debugging tool @@ -41,7 +44,8 @@ LL | dbg!(n * factorial(n - 1)) | help: remove the invocation before committing it to a version control system | -LL | n * factorial(n - 1) +LL - dbg!(n * factorial(n - 1)) +LL + n * factorial(n - 1) | error: the `dbg!` macro is intended as a debugging tool @@ -52,8 +56,9 @@ LL | dbg!(42); | help: remove the invocation before committing it to a version control system | -LL | 42; - | ~~ +LL - dbg!(42); +LL + 42; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui-toml/dbg_macro/dbg_macro.rs:19:14 @@ -63,8 +68,9 @@ LL | foo(3) + dbg!(factorial(4)); | help: remove the invocation before committing it to a version control system | -LL | foo(3) + factorial(4); - | ~~~~~~~~~~~~ +LL - foo(3) + dbg!(factorial(4)); +LL + foo(3) + factorial(4); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui-toml/dbg_macro/dbg_macro.rs:20:5 @@ -74,8 +80,9 @@ LL | dbg!(1, 2, 3, 4, 5); | help: remove the invocation before committing it to a version control system | -LL | (1, 2, 3, 4, 5); - | ~~~~~~~~~~~~~~~ +LL - dbg!(1, 2, 3, 4, 5); +LL + (1, 2, 3, 4, 5); + | error: aborting due to 7 previous errors diff --git a/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr b/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr index a6e0ad0f804c..8ba237ee75cf 100644 --- a/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr +++ b/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr @@ -8,8 +8,9 @@ LL | /// TestItemThingyOfCoolness might sound cool but is not on the list and sh = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted. +LL + /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. + | error: aborting due to 1 previous error diff --git a/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr b/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr index d4d8a579798c..9f2d7cf54e0d 100644 --- a/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr +++ b/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr @@ -8,8 +8,9 @@ LL | /// OAuth and LaTeX are inside Clippy's default list. = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// `OAuth` and LaTeX are inside Clippy's default list. - | ~~~~~~~ +LL - /// OAuth and LaTeX are inside Clippy's default list. +LL + /// `OAuth` and LaTeX are inside Clippy's default list. + | error: item in documentation is missing backticks --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:6:15 @@ -19,8 +20,9 @@ LL | /// OAuth and LaTeX are inside Clippy's default list. | help: try | -LL | /// OAuth and `LaTeX` are inside Clippy's default list. - | ~~~~~~~ +LL - /// OAuth and LaTeX are inside Clippy's default list. +LL + /// OAuth and `LaTeX` are inside Clippy's default list. + | error: item in documentation is missing backticks --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:9:5 @@ -30,8 +32,9 @@ LL | /// TestItemThingyOfCoolness might sound cool but is not on the list and sh | help: try | -LL | /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted. +LL + /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. + | error: aborting due to 3 previous errors diff --git a/tests/ui-toml/enum_variant_size/enum_variant_size.stderr b/tests/ui-toml/enum_variant_size/enum_variant_size.stderr index 8f7ebbd9546c..020b3cc78782 100644 --- a/tests/ui-toml/enum_variant_size/enum_variant_size.stderr +++ b/tests/ui-toml/enum_variant_size/enum_variant_size.stderr @@ -14,8 +14,9 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]` help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<[u8; 501]>), - | ~~~~~~~~~~~~~~ +LL - B([u8; 501]), +LL + B(Box<[u8; 501]>), + | error: aborting due to 1 previous error diff --git a/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr b/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr index 2d700f607592..de9f17520ff7 100644 --- a/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr +++ b/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr @@ -33,8 +33,9 @@ LL | fn hash_slice(date: &[Self], states: &mut H) { | help: consider using the default names | -LL | fn hash_slice(data: &[Self], state: &mut H) { - | ~~~~ ~~~~~ +LL - fn hash_slice(date: &[Self], states: &mut H) { +LL + fn hash_slice(data: &[Self], state: &mut H) { + | error: renamed function parameter of trait impl --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:80:18 diff --git a/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr b/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr index e57554fa613a..bdc4eeaad80f 100644 --- a/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr +++ b/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr @@ -27,8 +27,9 @@ LL | fn hash_slice(date: &[Self], states: &mut H) { | help: consider using the default names | -LL | fn hash_slice(data: &[Self], state: &mut H) { - | ~~~~ ~~~~~ +LL - fn hash_slice(date: &[Self], states: &mut H) { +LL + fn hash_slice(data: &[Self], state: &mut H) { + | error: aborting due to 4 previous errors diff --git a/tests/ui-toml/unwrap_used/unwrap_used.stderr b/tests/ui-toml/unwrap_used/unwrap_used.stderr index b58ce9b8af3e..2aff276a4a12 100644 --- a/tests/ui-toml/unwrap_used/unwrap_used.stderr +++ b/tests/ui-toml/unwrap_used/unwrap_used.stderr @@ -8,8 +8,9 @@ LL | let _ = boxed_slice.get(1).unwrap(); = help: to override `-D warnings` add `#[allow(clippy::get_unwrap)]` help: using `[]` is clearer and more concise | -LL | let _ = &boxed_slice[1]; - | ~~~~~~~~~~~~~~~ +LL - let _ = boxed_slice.get(1).unwrap(); +LL + let _ = &boxed_slice[1]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:38:17 @@ -30,8 +31,9 @@ LL | let _ = some_slice.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_slice[0]; - | ~~~~~~~~~~~~~~ +LL - let _ = some_slice.get(0).unwrap(); +LL + let _ = &some_slice[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:39:17 @@ -50,8 +52,9 @@ LL | let _ = some_vec.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_vec[0]; - | ~~~~~~~~~~~~ +LL - let _ = some_vec.get(0).unwrap(); +LL + let _ = &some_vec[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:40:17 @@ -70,8 +73,9 @@ LL | let _ = some_vecdeque.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_vecdeque[0]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = some_vecdeque.get(0).unwrap(); +LL + let _ = &some_vecdeque[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17 @@ -90,8 +94,9 @@ LL | let _ = some_hashmap.get(&1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_hashmap[&1]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = some_hashmap.get(&1).unwrap(); +LL + let _ = &some_hashmap[&1]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:42:17 @@ -110,8 +115,9 @@ LL | let _ = some_btreemap.get(&1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_btreemap[&1]; - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = some_btreemap.get(&1).unwrap(); +LL + let _ = &some_btreemap[&1]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:43:17 @@ -130,8 +136,9 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _: u8 = boxed_slice[1]; - | ~~~~~~~~~~~~~~ +LL - let _: u8 = *boxed_slice.get(1).unwrap(); +LL + let _: u8 = boxed_slice[1]; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:47:22 @@ -150,8 +157,9 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | boxed_slice[0] = 1; - | ~~~~~~~~~~~~~~ +LL - *boxed_slice.get_mut(0).unwrap() = 1; +LL + boxed_slice[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:52:10 @@ -170,8 +178,9 @@ LL | *some_slice.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_slice[0] = 1; - | ~~~~~~~~~~~~~ +LL - *some_slice.get_mut(0).unwrap() = 1; +LL + some_slice[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:53:10 @@ -190,8 +199,9 @@ LL | *some_vec.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_vec[0] = 1; - | ~~~~~~~~~~~ +LL - *some_vec.get_mut(0).unwrap() = 1; +LL + some_vec[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:54:10 @@ -210,8 +220,9 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_vecdeque[0] = 1; - | ~~~~~~~~~~~~~~~~ +LL - *some_vecdeque.get_mut(0).unwrap() = 1; +LL + some_vecdeque[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:55:10 @@ -230,8 +241,9 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | help: using `[]` is clearer and more concise | -LL | let _ = some_vec[0..1].to_vec(); - | ~~~~~~~~~~~~~~ +LL - let _ = some_vec.get(0..1).unwrap().to_vec(); +LL + let _ = some_vec[0..1].to_vec(); + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:67:17 @@ -250,8 +262,9 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | help: using `[]` is clearer and more concise | -LL | let _ = some_vec[0..1].to_vec(); - | ~~~~~~~~~~~~~~ +LL - let _ = some_vec.get_mut(0..1).unwrap().to_vec(); +LL + let _ = some_vec[0..1].to_vec(); + | error: used `unwrap()` on an `Option` value --> tests/ui-toml/unwrap_used/unwrap_used.rs:68:17 @@ -270,8 +283,9 @@ LL | let _ = boxed_slice.get(1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &boxed_slice[1]; - | ~~~~~~~~~~~~~~~ +LL - let _ = boxed_slice.get(1).unwrap(); +LL + let _ = &boxed_slice[1]; + | error: called `.get().unwrap()` on a slice --> tests/ui-toml/unwrap_used/unwrap_used.rs:94:17 @@ -281,8 +295,9 @@ LL | let _ = Box::new([0]).get(1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &Box::new([0])[1]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = Box::new([0]).get(1).unwrap(); +LL + let _ = &Box::new([0])[1]; + | error: aborting due to 28 previous errors diff --git a/tests/ui/assign_ops2.stderr b/tests/ui/assign_ops2.stderr index ddeba2b2ff8f..09b101b216a5 100644 --- a/tests/ui/assign_ops2.stderr +++ b/tests/ui/assign_ops2.stderr @@ -8,12 +8,14 @@ LL | a += a + 1; = help: to override `-D warnings` add `#[allow(clippy::misrefactored_assign_op)]` help: did you mean `a = a + 1` or `a = a + a + 1`? Consider replacing it with | -LL | a += 1; - | ~~~~~~ +LL - a += a + 1; +LL + a += 1; + | help: or | -LL | a = a + a + 1; - | ~~~~~~~~~~~~~ +LL - a += a + 1; +LL + a = a + a + 1; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:11:5 @@ -23,12 +25,14 @@ LL | a += 1 + a; | help: did you mean `a = a + 1` or `a = a + 1 + a`? Consider replacing it with | -LL | a += 1; - | ~~~~~~ +LL - a += 1 + a; +LL + a += 1; + | help: or | -LL | a = a + 1 + a; - | ~~~~~~~~~~~~~ +LL - a += 1 + a; +LL + a = a + 1 + a; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:13:5 @@ -38,12 +42,14 @@ LL | a -= a - 1; | help: did you mean `a = a - 1` or `a = a - (a - 1)`? Consider replacing it with | -LL | a -= 1; - | ~~~~~~ +LL - a -= a - 1; +LL + a -= 1; + | help: or | -LL | a = a - (a - 1); - | ~~~~~~~~~~~~~~~ +LL - a -= a - 1; +LL + a = a - (a - 1); + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:15:5 @@ -53,12 +59,14 @@ LL | a *= a * 99; | help: did you mean `a = a * 99` or `a = a * a * 99`? Consider replacing it with | -LL | a *= 99; - | ~~~~~~~ +LL - a *= a * 99; +LL + a *= 99; + | help: or | -LL | a = a * a * 99; - | ~~~~~~~~~~~~~~ +LL - a *= a * 99; +LL + a = a * a * 99; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:17:5 @@ -68,12 +76,14 @@ LL | a *= 42 * a; | help: did you mean `a = a * 42` or `a = a * 42 * a`? Consider replacing it with | -LL | a *= 42; - | ~~~~~~~ +LL - a *= 42 * a; +LL + a *= 42; + | help: or | -LL | a = a * 42 * a; - | ~~~~~~~~~~~~~~ +LL - a *= 42 * a; +LL + a = a * 42 * a; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:19:5 @@ -83,12 +93,14 @@ LL | a /= a / 2; | help: did you mean `a = a / 2` or `a = a / (a / 2)`? Consider replacing it with | -LL | a /= 2; - | ~~~~~~ +LL - a /= a / 2; +LL + a /= 2; + | help: or | -LL | a = a / (a / 2); - | ~~~~~~~~~~~~~~~ +LL - a /= a / 2; +LL + a = a / (a / 2); + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:21:5 @@ -98,12 +110,14 @@ LL | a %= a % 5; | help: did you mean `a = a % 5` or `a = a % (a % 5)`? Consider replacing it with | -LL | a %= 5; - | ~~~~~~ +LL - a %= a % 5; +LL + a %= 5; + | help: or | -LL | a = a % (a % 5); - | ~~~~~~~~~~~~~~~ +LL - a %= a % 5; +LL + a = a % (a % 5); + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:23:5 @@ -113,12 +127,14 @@ LL | a &= a & 1; | help: did you mean `a = a & 1` or `a = a & a & 1`? Consider replacing it with | -LL | a &= 1; - | ~~~~~~ +LL - a &= a & 1; +LL + a &= 1; + | help: or | -LL | a = a & a & 1; - | ~~~~~~~~~~~~~ +LL - a &= a & 1; +LL + a = a & a & 1; + | error: variable appears on both sides of an assignment operation --> tests/ui/assign_ops2.rs:25:5 @@ -128,12 +144,14 @@ LL | a *= a * a; | help: did you mean `a = a * a` or `a = a * a * a`? Consider replacing it with | -LL | a *= a; - | ~~~~~~ +LL - a *= a * a; +LL + a *= a; + | help: or | -LL | a = a * a * a; - | ~~~~~~~~~~~~~ +LL - a *= a * a; +LL + a = a * a * a; + | error: manual implementation of an assign operation --> tests/ui/assign_ops2.rs:63:5 diff --git a/tests/ui/bind_instead_of_map_multipart.stderr b/tests/ui/bind_instead_of_map_multipart.stderr index d271381adea2..7c5882d4296e 100644 --- a/tests/ui/bind_instead_of_map_multipart.stderr +++ b/tests/ui/bind_instead_of_map_multipart.stderr @@ -11,8 +11,9 @@ LL | #![deny(clippy::bind_instead_of_map)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `map` instead | -LL | let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); - | ~~~ ~ ~~~~~~~ +LL - let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) }); +LL + let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); + | error: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as `map(|x| y)` --> tests/ui/bind_instead_of_map_multipart.rs:8:13 @@ -22,8 +23,9 @@ LL | let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { | help: use `map` instead | -LL | let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); - | ~~~ ~ ~~~~~~~ +LL - let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) }); +LL + let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); + | error: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as `map_err(|x| y)` --> tests/ui/bind_instead_of_map_multipart.rs:11:13 @@ -33,8 +35,9 @@ LL | let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + | help: use `map_err` instead | -LL | let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() }); - | ~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~ +LL - let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) }); +LL + let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() }); + | error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)` --> tests/ui/bind_instead_of_map_multipart.rs:19:5 @@ -83,8 +86,9 @@ LL | let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { So | help: use `map` instead | -LL | let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) }); - | ~~~ ~~~~ ~~~~~~~~ +LL - let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) }); +LL + let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) }); + | error: aborting due to 5 previous errors diff --git a/tests/ui/borrow_deref_ref_unfixable.stderr b/tests/ui/borrow_deref_ref_unfixable.stderr index 7d3a5c84a820..71f43af46c24 100644 --- a/tests/ui/borrow_deref_ref_unfixable.stderr +++ b/tests/ui/borrow_deref_ref_unfixable.stderr @@ -8,12 +8,14 @@ LL | let x: &str = &*s; = help: to override `-D warnings` add `#[allow(clippy::borrow_deref_ref)]` help: if you would like to reborrow, try removing `&*` | -LL | let x: &str = s; - | ~ +LL - let x: &str = &*s; +LL + let x: &str = s; + | help: if you would like to deref, try using `&**` | -LL | let x: &str = &**s; - | ~~~~ +LL - let x: &str = &*s; +LL + let x: &str = &**s; + | error: aborting due to 1 previous error diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 452482fc88e2..901447c738ed 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -81,8 +81,9 @@ LL | 1i32 as i8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i8::try_from(1i32); - | ~~~~~~~~~~~~~~~~~~ +LL - 1i32 as i8; +LL + i8::try_from(1i32); + | error: casting `i32` to `u8` may truncate the value --> tests/ui/cast.rs:52:5 @@ -93,8 +94,9 @@ LL | 1i32 as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u8::try_from(1i32); - | ~~~~~~~~~~~~~~~~~~ +LL - 1i32 as u8; +LL + u8::try_from(1i32); + | error: casting `f64` to `isize` may truncate the value --> tests/ui/cast.rs:54:5 @@ -127,8 +129,9 @@ LL | 1f32 as u32 as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u16::try_from(1f32 as u32); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - 1f32 as u32 as u16; +LL + u16::try_from(1f32 as u32); + | error: casting `f32` to `u32` may truncate the value --> tests/ui/cast.rs:59:5 @@ -153,8 +156,9 @@ LL | let _x: i8 = 1i32 as _; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _x: i8 = 1i32.try_into(); - | ~~~~~~~~~~~~~~~ +LL - let _x: i8 = 1i32 as _; +LL + let _x: i8 = 1i32.try_into(); + | error: casting `f32` to `i32` may truncate the value --> tests/ui/cast.rs:66:9 @@ -228,8 +232,9 @@ LL | 1usize as i8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i8::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as i8; +LL + i8::try_from(1usize); + | error: casting `usize` to `i16` may truncate the value --> tests/ui/cast.rs:90:5 @@ -240,8 +245,9 @@ LL | 1usize as i16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i16::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as i16; +LL + i16::try_from(1usize); + | error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers --> tests/ui/cast.rs:90:5 @@ -261,8 +267,9 @@ LL | 1usize as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i32::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as i32; +LL + i32::try_from(1usize); + | error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers --> tests/ui/cast.rs:95:5 @@ -300,8 +307,9 @@ LL | 1u64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | isize::try_from(1u64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1u64 as isize; +LL + isize::try_from(1u64); + | error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers --> tests/ui/cast.rs:111:5 @@ -360,8 +368,9 @@ LL | (-99999999999i64).min(1) as i8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i8::try_from((-99999999999i64).min(1)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - (-99999999999i64).min(1) as i8; +LL + i8::try_from((-99999999999i64).min(1)); + | error: casting `u64` to `u8` may truncate the value --> tests/ui/cast.rs:222:5 @@ -372,8 +381,9 @@ LL | 999999u64.clamp(0, 256) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u8::try_from(999999u64.clamp(0, 256)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - 999999u64.clamp(0, 256) as u8; +LL + u8::try_from(999999u64.clamp(0, 256)); + | error: casting `main::E2` to `u8` may truncate the value --> tests/ui/cast.rs:245:21 @@ -384,8 +394,9 @@ LL | let _ = self as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = u8::try_from(self); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = self as u8; +LL + let _ = u8::try_from(self); + | error: casting `main::E2::B` to `u8` will truncate the value --> tests/ui/cast.rs:247:21 @@ -405,8 +416,9 @@ LL | let _ = self as i8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = i8::try_from(self); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = self as i8; +LL + let _ = i8::try_from(self); + | error: casting `main::E5::A` to `i8` will truncate the value --> tests/ui/cast.rs:291:21 @@ -423,8 +435,9 @@ LL | let _ = self as i16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = i16::try_from(self); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = self as i16; +LL + let _ = i16::try_from(self); + | error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers --> tests/ui/cast.rs:327:21 @@ -435,8 +448,9 @@ LL | let _ = self as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = usize::try_from(self); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = self as usize; +LL + let _ = usize::try_from(self); + | error: casting `main::E10` to `u16` may truncate the value --> tests/ui/cast.rs:374:21 @@ -447,8 +461,9 @@ LL | let _ = self as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let _ = u16::try_from(self); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = self as u16; +LL + let _ = u16::try_from(self); + | error: casting `u32` to `u8` may truncate the value --> tests/ui/cast.rs:385:13 @@ -459,8 +474,9 @@ LL | let c = (q >> 16) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let c = u8::try_from(q >> 16); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let c = (q >> 16) as u8; +LL + let c = u8::try_from(q >> 16); + | error: casting `u32` to `u8` may truncate the value --> tests/ui/cast.rs:389:13 @@ -471,8 +487,9 @@ LL | let c = (q / 1000) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | let c = u8::try_from(q / 1000); - | ~~~~~~~~~~~~~~~~~~~~~~ +LL - let c = (q / 1000) as u8; +LL + let c = u8::try_from(q / 1000); + | error: casting `i32` to `u32` may lose the sign of the value --> tests/ui/cast.rs:401:9 @@ -674,8 +691,9 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) help: ... or use `try_from` and handle the error accordingly | -LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation - | ~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = u32::MAX as u8; // cast_possible_truncation +LL + let _ = u8::try_from(u32::MAX); // cast_possible_truncation + | error: casting `f64` to `f32` may truncate the value --> tests/ui/cast.rs:474:21 @@ -698,7 +716,8 @@ LL | bar.unwrap().unwrap() as usize = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | usize::try_from(bar.unwrap().unwrap()) +LL - bar.unwrap().unwrap() as usize +LL + usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value @@ -716,8 +735,9 @@ LL | (256 & 999999u64) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u8::try_from(256 & 999999u64); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - (256 & 999999u64) as u8; +LL + u8::try_from(256 & 999999u64); + | error: casting `u64` to `u8` may truncate the value --> tests/ui/cast.rs:500:5 @@ -728,8 +748,9 @@ LL | (255 % 999999u64) as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u8::try_from(255 % 999999u64); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - (255 % 999999u64) as u8; +LL + u8::try_from(255 % 999999u64); + | error: aborting due to 92 previous errors diff --git a/tests/ui/cast_lossless_bool.stderr b/tests/ui/cast_lossless_bool.stderr index 82d6b2e4b8e6..689922717623 100644 --- a/tests/ui/cast_lossless_bool.stderr +++ b/tests/ui/cast_lossless_bool.stderr @@ -9,8 +9,9 @@ LL | let _ = true as u8; = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]` help: use `u8::from` instead | -LL | let _ = u8::from(true); - | ~~~~~~~~~~~~~~ +LL - let _ = true as u8; +LL + let _ = u8::from(true); + | error: casts from `bool` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:9:13 @@ -21,8 +22,9 @@ LL | let _ = true as u16; = help: an `as` cast can become silently lossy if the types change in the future help: use `u16::from` instead | -LL | let _ = u16::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as u16; +LL + let _ = u16::from(true); + | error: casts from `bool` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:10:13 @@ -33,8 +35,9 @@ LL | let _ = true as u32; = help: an `as` cast can become silently lossy if the types change in the future help: use `u32::from` instead | -LL | let _ = u32::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as u32; +LL + let _ = u32::from(true); + | error: casts from `bool` to `u64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:11:13 @@ -45,8 +48,9 @@ LL | let _ = true as u64; = help: an `as` cast can become silently lossy if the types change in the future help: use `u64::from` instead | -LL | let _ = u64::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as u64; +LL + let _ = u64::from(true); + | error: casts from `bool` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:12:13 @@ -57,8 +61,9 @@ LL | let _ = true as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | let _ = u128::from(true); - | ~~~~~~~~~~~~~~~~ +LL - let _ = true as u128; +LL + let _ = u128::from(true); + | error: casts from `bool` to `usize` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:13:13 @@ -69,8 +74,9 @@ LL | let _ = true as usize; = help: an `as` cast can become silently lossy if the types change in the future help: use `usize::from` instead | -LL | let _ = usize::from(true); - | ~~~~~~~~~~~~~~~~~ +LL - let _ = true as usize; +LL + let _ = usize::from(true); + | error: casts from `bool` to `i8` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:15:13 @@ -81,8 +87,9 @@ LL | let _ = true as i8; = help: an `as` cast can become silently lossy if the types change in the future help: use `i8::from` instead | -LL | let _ = i8::from(true); - | ~~~~~~~~~~~~~~ +LL - let _ = true as i8; +LL + let _ = i8::from(true); + | error: casts from `bool` to `i16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:16:13 @@ -93,8 +100,9 @@ LL | let _ = true as i16; = help: an `as` cast can become silently lossy if the types change in the future help: use `i16::from` instead | -LL | let _ = i16::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as i16; +LL + let _ = i16::from(true); + | error: casts from `bool` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:17:13 @@ -105,8 +113,9 @@ LL | let _ = true as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | let _ = i32::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as i32; +LL + let _ = i32::from(true); + | error: casts from `bool` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:18:13 @@ -117,8 +126,9 @@ LL | let _ = true as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | let _ = i64::from(true); - | ~~~~~~~~~~~~~~~ +LL - let _ = true as i64; +LL + let _ = i64::from(true); + | error: casts from `bool` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:19:13 @@ -129,8 +139,9 @@ LL | let _ = true as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | let _ = i128::from(true); - | ~~~~~~~~~~~~~~~~ +LL - let _ = true as i128; +LL + let _ = i128::from(true); + | error: casts from `bool` to `isize` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:20:13 @@ -141,8 +152,9 @@ LL | let _ = true as isize; = help: an `as` cast can become silently lossy if the types change in the future help: use `isize::from` instead | -LL | let _ = isize::from(true); - | ~~~~~~~~~~~~~~~~~ +LL - let _ = true as isize; +LL + let _ = isize::from(true); + | error: casts from `bool` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:23:13 @@ -153,8 +165,9 @@ LL | let _ = (true | false) as u16; = help: an `as` cast can become silently lossy if the types change in the future help: use `u16::from` instead | -LL | let _ = u16::from(true | false); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = (true | false) as u16; +LL + let _ = u16::from(true | false); + | error: casts from `bool` to `u8` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:25:13 @@ -165,8 +178,9 @@ LL | let _ = true as U8; = help: an `as` cast can become silently lossy if the types change in the future help: use `U8::from` instead | -LL | let _ = U8::from(true); - | ~~~~~~~~~~~~~~ +LL - let _ = true as U8; +LL + let _ = U8::from(true); + | error: casts from `bool` to `u8` can be expressed infallibly using `From` --> tests/ui/cast_lossless_bool.rs:53:13 @@ -177,8 +191,9 @@ LL | let _ = true as u8; = help: an `as` cast can become silently lossy if the types change in the future help: use `u8::from` instead | -LL | let _ = u8::from(true); - | ~~~~~~~~~~~~~~ +LL - let _ = true as u8; +LL + let _ = u8::from(true); + | error: aborting due to 15 previous errors diff --git a/tests/ui/cast_lossless_float.stderr b/tests/ui/cast_lossless_float.stderr index b36f8bcecf58..3f405e3f402f 100644 --- a/tests/ui/cast_lossless_float.stderr +++ b/tests/ui/cast_lossless_float.stderr @@ -9,8 +9,9 @@ LL | let _ = x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]` help: use `f32::from` instead | -LL | let _ = f32::from(x0); - | ~~~~~~~~~~~~~ +LL - let _ = x0 as f32; +LL + let _ = f32::from(x0); + | error: casts from `i8` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:13:13 @@ -21,8 +22,9 @@ LL | let _ = x0 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x0); - | ~~~~~~~~~~~~~ +LL - let _ = x0 as f64; +LL + let _ = f64::from(x0); + | error: casts from `i8` to `f32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:14:13 @@ -33,8 +35,9 @@ LL | let _ = x0 as F32; = help: an `as` cast can become silently lossy if the types change in the future help: use `F32::from` instead | -LL | let _ = F32::from(x0); - | ~~~~~~~~~~~~~ +LL - let _ = x0 as F32; +LL + let _ = F32::from(x0); + | error: casts from `i8` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:15:13 @@ -45,8 +48,9 @@ LL | let _ = x0 as F64; = help: an `as` cast can become silently lossy if the types change in the future help: use `F64::from` instead | -LL | let _ = F64::from(x0); - | ~~~~~~~~~~~~~ +LL - let _ = x0 as F64; +LL + let _ = F64::from(x0); + | error: casts from `u8` to `f32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:17:13 @@ -57,8 +61,9 @@ LL | let _ = x1 as f32; = help: an `as` cast can become silently lossy if the types change in the future help: use `f32::from` instead | -LL | let _ = f32::from(x1); - | ~~~~~~~~~~~~~ +LL - let _ = x1 as f32; +LL + let _ = f32::from(x1); + | error: casts from `u8` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:18:13 @@ -69,8 +74,9 @@ LL | let _ = x1 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x1); - | ~~~~~~~~~~~~~ +LL - let _ = x1 as f64; +LL + let _ = f64::from(x1); + | error: casts from `i16` to `f32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:20:13 @@ -81,8 +87,9 @@ LL | let _ = x2 as f32; = help: an `as` cast can become silently lossy if the types change in the future help: use `f32::from` instead | -LL | let _ = f32::from(x2); - | ~~~~~~~~~~~~~ +LL - let _ = x2 as f32; +LL + let _ = f32::from(x2); + | error: casts from `i16` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:21:13 @@ -93,8 +100,9 @@ LL | let _ = x2 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x2); - | ~~~~~~~~~~~~~ +LL - let _ = x2 as f64; +LL + let _ = f64::from(x2); + | error: casts from `u16` to `f32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:23:13 @@ -105,8 +113,9 @@ LL | let _ = x3 as f32; = help: an `as` cast can become silently lossy if the types change in the future help: use `f32::from` instead | -LL | let _ = f32::from(x3); - | ~~~~~~~~~~~~~ +LL - let _ = x3 as f32; +LL + let _ = f32::from(x3); + | error: casts from `u16` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:24:13 @@ -117,8 +126,9 @@ LL | let _ = x3 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x3); - | ~~~~~~~~~~~~~ +LL - let _ = x3 as f64; +LL + let _ = f64::from(x3); + | error: casts from `i32` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:26:13 @@ -129,8 +139,9 @@ LL | let _ = x4 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x4); - | ~~~~~~~~~~~~~ +LL - let _ = x4 as f64; +LL + let _ = f64::from(x4); + | error: casts from `u32` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:28:13 @@ -141,8 +152,9 @@ LL | let _ = x5 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(x5); - | ~~~~~~~~~~~~~ +LL - let _ = x5 as f64; +LL + let _ = f64::from(x5); + | error: casts from `f32` to `f64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_float.rs:31:13 @@ -153,8 +165,9 @@ LL | let _ = 1.0f32 as f64; = help: an `as` cast can become silently lossy if the types change in the future help: use `f64::from` instead | -LL | let _ = f64::from(1.0f32); - | ~~~~~~~~~~~~~~~~~ +LL - let _ = 1.0f32 as f64; +LL + let _ = f64::from(1.0f32); + | error: aborting due to 13 previous errors diff --git a/tests/ui/cast_lossless_integer.stderr b/tests/ui/cast_lossless_integer.stderr index c93ecb8fb561..d2580913bb54 100644 --- a/tests/ui/cast_lossless_integer.stderr +++ b/tests/ui/cast_lossless_integer.stderr @@ -9,8 +9,9 @@ LL | 0u8 as u16; = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]` help: use `u16::from` instead | -LL | u16::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as u16; +LL + u16::from(0u8); + | error: casts from `u8` to `i16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:10:5 @@ -21,8 +22,9 @@ LL | 0u8 as i16; = help: an `as` cast can become silently lossy if the types change in the future help: use `i16::from` instead | -LL | i16::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as i16; +LL + i16::from(0u8); + | error: casts from `u8` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:12:5 @@ -33,8 +35,9 @@ LL | 0u8 as u32; = help: an `as` cast can become silently lossy if the types change in the future help: use `u32::from` instead | -LL | u32::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as u32; +LL + u32::from(0u8); + | error: casts from `u8` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:14:5 @@ -45,8 +48,9 @@ LL | 0u8 as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | i32::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as i32; +LL + i32::from(0u8); + | error: casts from `u8` to `u64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:16:5 @@ -57,8 +61,9 @@ LL | 0u8 as u64; = help: an `as` cast can become silently lossy if the types change in the future help: use `u64::from` instead | -LL | u64::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as u64; +LL + u64::from(0u8); + | error: casts from `u8` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:18:5 @@ -69,8 +74,9 @@ LL | 0u8 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0u8); - | ~~~~~~~~~~~~~~ +LL - 0u8 as i64; +LL + i64::from(0u8); + | error: casts from `u8` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:20:5 @@ -81,8 +87,9 @@ LL | 0u8 as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | u128::from(0u8); - | ~~~~~~~~~~~~~~~ +LL - 0u8 as u128; +LL + u128::from(0u8); + | error: casts from `u8` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:22:5 @@ -93,8 +100,9 @@ LL | 0u8 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0u8); - | ~~~~~~~~~~~~~~~ +LL - 0u8 as i128; +LL + i128::from(0u8); + | error: casts from `u16` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:25:5 @@ -105,8 +113,9 @@ LL | 0u16 as u32; = help: an `as` cast can become silently lossy if the types change in the future help: use `u32::from` instead | -LL | u32::from(0u16); - | ~~~~~~~~~~~~~~~ +LL - 0u16 as u32; +LL + u32::from(0u16); + | error: casts from `u16` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:27:5 @@ -117,8 +126,9 @@ LL | 0u16 as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | i32::from(0u16); - | ~~~~~~~~~~~~~~~ +LL - 0u16 as i32; +LL + i32::from(0u16); + | error: casts from `u16` to `u64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:29:5 @@ -129,8 +139,9 @@ LL | 0u16 as u64; = help: an `as` cast can become silently lossy if the types change in the future help: use `u64::from` instead | -LL | u64::from(0u16); - | ~~~~~~~~~~~~~~~ +LL - 0u16 as u64; +LL + u64::from(0u16); + | error: casts from `u16` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:31:5 @@ -141,8 +152,9 @@ LL | 0u16 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0u16); - | ~~~~~~~~~~~~~~~ +LL - 0u16 as i64; +LL + i64::from(0u16); + | error: casts from `u16` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:33:5 @@ -153,8 +165,9 @@ LL | 0u16 as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | u128::from(0u16); - | ~~~~~~~~~~~~~~~~ +LL - 0u16 as u128; +LL + u128::from(0u16); + | error: casts from `u16` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:35:5 @@ -165,8 +178,9 @@ LL | 0u16 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0u16); - | ~~~~~~~~~~~~~~~~ +LL - 0u16 as i128; +LL + i128::from(0u16); + | error: casts from `u32` to `u64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:38:5 @@ -177,8 +191,9 @@ LL | 0u32 as u64; = help: an `as` cast can become silently lossy if the types change in the future help: use `u64::from` instead | -LL | u64::from(0u32); - | ~~~~~~~~~~~~~~~ +LL - 0u32 as u64; +LL + u64::from(0u32); + | error: casts from `u32` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:40:5 @@ -189,8 +204,9 @@ LL | 0u32 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0u32); - | ~~~~~~~~~~~~~~~ +LL - 0u32 as i64; +LL + i64::from(0u32); + | error: casts from `u32` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:42:5 @@ -201,8 +217,9 @@ LL | 0u32 as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | u128::from(0u32); - | ~~~~~~~~~~~~~~~~ +LL - 0u32 as u128; +LL + u128::from(0u32); + | error: casts from `u32` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:44:5 @@ -213,8 +230,9 @@ LL | 0u32 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0u32); - | ~~~~~~~~~~~~~~~~ +LL - 0u32 as i128; +LL + i128::from(0u32); + | error: casts from `u64` to `u128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:47:5 @@ -225,8 +243,9 @@ LL | 0u64 as u128; = help: an `as` cast can become silently lossy if the types change in the future help: use `u128::from` instead | -LL | u128::from(0u64); - | ~~~~~~~~~~~~~~~~ +LL - 0u64 as u128; +LL + u128::from(0u64); + | error: casts from `u64` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:49:5 @@ -237,8 +256,9 @@ LL | 0u64 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0u64); - | ~~~~~~~~~~~~~~~~ +LL - 0u64 as i128; +LL + i128::from(0u64); + | error: casts from `i8` to `i16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:52:5 @@ -249,8 +269,9 @@ LL | 0i8 as i16; = help: an `as` cast can become silently lossy if the types change in the future help: use `i16::from` instead | -LL | i16::from(0i8); - | ~~~~~~~~~~~~~~ +LL - 0i8 as i16; +LL + i16::from(0i8); + | error: casts from `i8` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:54:5 @@ -261,8 +282,9 @@ LL | 0i8 as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | i32::from(0i8); - | ~~~~~~~~~~~~~~ +LL - 0i8 as i32; +LL + i32::from(0i8); + | error: casts from `i8` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:56:5 @@ -273,8 +295,9 @@ LL | 0i8 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0i8); - | ~~~~~~~~~~~~~~ +LL - 0i8 as i64; +LL + i64::from(0i8); + | error: casts from `i8` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:58:5 @@ -285,8 +308,9 @@ LL | 0i8 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0i8); - | ~~~~~~~~~~~~~~~ +LL - 0i8 as i128; +LL + i128::from(0i8); + | error: casts from `i16` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:61:5 @@ -297,8 +321,9 @@ LL | 0i16 as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | i32::from(0i16); - | ~~~~~~~~~~~~~~~ +LL - 0i16 as i32; +LL + i32::from(0i16); + | error: casts from `i16` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:63:5 @@ -309,8 +334,9 @@ LL | 0i16 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0i16); - | ~~~~~~~~~~~~~~~ +LL - 0i16 as i64; +LL + i64::from(0i16); + | error: casts from `i16` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:65:5 @@ -321,8 +347,9 @@ LL | 0i16 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0i16); - | ~~~~~~~~~~~~~~~~ +LL - 0i16 as i128; +LL + i128::from(0i16); + | error: casts from `i32` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:68:5 @@ -333,8 +360,9 @@ LL | 0i32 as i64; = help: an `as` cast can become silently lossy if the types change in the future help: use `i64::from` instead | -LL | i64::from(0i32); - | ~~~~~~~~~~~~~~~ +LL - 0i32 as i64; +LL + i64::from(0i32); + | error: casts from `i32` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:70:5 @@ -345,8 +373,9 @@ LL | 0i32 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0i32); - | ~~~~~~~~~~~~~~~~ +LL - 0i32 as i128; +LL + i128::from(0i32); + | error: casts from `i64` to `i128` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:73:5 @@ -357,8 +386,9 @@ LL | 0i64 as i128; = help: an `as` cast can become silently lossy if the types change in the future help: use `i128::from` instead | -LL | i128::from(0i64); - | ~~~~~~~~~~~~~~~~ +LL - 0i64 as i128; +LL + i128::from(0i64); + | error: casts from `u8` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:77:13 @@ -369,8 +399,9 @@ LL | let _ = (1u8 + 1u8) as u16; = help: an `as` cast can become silently lossy if the types change in the future help: use `u16::from` instead | -LL | let _ = u16::from(1u8 + 1u8); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = (1u8 + 1u8) as u16; +LL + let _ = u16::from(1u8 + 1u8); + | error: casts from `i8` to `i64` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:80:13 @@ -381,8 +412,9 @@ LL | let _ = 1i8 as I64Alias; = help: an `as` cast can become silently lossy if the types change in the future help: use `I64Alias::from` instead | -LL | let _ = I64Alias::from(1i8); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = 1i8 as I64Alias; +LL + let _ = I64Alias::from(1i8); + | error: casts from `u8` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:83:18 @@ -393,8 +425,9 @@ LL | let _: u16 = 0u8 as _; = help: an `as` cast can become silently lossy if the types change in the future help: use `Into::into` instead | -LL | let _: u16 = 0u8.into(); - | ~~~~~~~~~~ +LL - let _: u16 = 0u8 as _; +LL + let _: u16 = 0u8.into(); + | error: casts from `i8` to `i16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:85:18 @@ -405,8 +438,9 @@ LL | let _: i16 = -1i8 as _; = help: an `as` cast can become silently lossy if the types change in the future help: use `Into::into` instead | -LL | let _: i16 = (-1i8).into(); - | ~~~~~~~~~~~~~ +LL - let _: i16 = -1i8 as _; +LL + let _: i16 = (-1i8).into(); + | error: casts from `u8` to `u16` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:87:18 @@ -417,8 +451,9 @@ LL | let _: u16 = (1u8 + 2) as _; = help: an `as` cast can become silently lossy if the types change in the future help: use `Into::into` instead | -LL | let _: u16 = (1u8 + 2).into(); - | ~~~~~~~~~~~~~~~~ +LL - let _: u16 = (1u8 + 2) as _; +LL + let _: u16 = (1u8 + 2).into(); + | error: casts from `u16` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:89:18 @@ -429,8 +464,9 @@ LL | let _: u32 = 1i8 as u16 as _; = help: an `as` cast can become silently lossy if the types change in the future help: use `Into::into` instead | -LL | let _: u32 = (1i8 as u16).into(); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _: u32 = 1i8 as u16 as _; +LL + let _: u32 = (1i8 as u16).into(); + | error: casts from `i8` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:124:13 @@ -441,8 +477,9 @@ LL | let _ = sign_cast!(x, u8, i8) as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | let _ = i32::from(sign_cast!(x, u8, i8)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = sign_cast!(x, u8, i8) as i32; +LL + let _ = i32::from(sign_cast!(x, u8, i8)); + | error: casts from `i8` to `i32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:126:13 @@ -453,8 +490,9 @@ LL | let _ = (sign_cast!(x, u8, i8) + 1) as i32; = help: an `as` cast can become silently lossy if the types change in the future help: use `i32::from` instead | -LL | let _ = i32::from(sign_cast!(x, u8, i8) + 1); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = (sign_cast!(x, u8, i8) + 1) as i32; +LL + let _ = i32::from(sign_cast!(x, u8, i8) + 1); + | error: casts from `u8` to `u32` can be expressed infallibly using `From` --> tests/ui/cast_lossless_integer.rs:133:13 @@ -469,7 +507,8 @@ LL | let _ = in_macro!(); = note: this error originates in the macro `in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) help: use `u32::from` instead | -LL | u32::from(1u8) +LL - 1u8 as u32 +LL + u32::from(1u8) | error: casts from `u8` to `u32` can be expressed infallibly using `From` @@ -481,8 +520,9 @@ LL | let _ = 0u8 as ty!(); = help: an `as` cast can become silently lossy if the types change in the future help: use `::from` instead | -LL | let _ = ::from(0u8); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = 0u8 as ty!(); +LL + let _ = ::from(0u8); + | error: aborting due to 40 previous errors diff --git a/tests/ui/cast_size.64bit.stderr b/tests/ui/cast_size.64bit.stderr index bc37107d80e3..6b9919f8a105 100644 --- a/tests/ui/cast_size.64bit.stderr +++ b/tests/ui/cast_size.64bit.stderr @@ -9,8 +9,9 @@ LL | 1isize as i8; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]` help: ... or use `try_from` and handle the error accordingly | -LL | i8::try_from(1isize); - | ~~~~~~~~~~~~~~~~~~~~ +LL - 1isize as i8; +LL + i8::try_from(1isize); + | error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:21:5 @@ -48,8 +49,9 @@ LL | 1isize as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i32::try_from(1isize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1isize as i32; +LL + i32::try_from(1isize); + | error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:29:5 @@ -60,8 +62,9 @@ LL | 1isize as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u32::try_from(1isize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1isize as u32; +LL + u32::try_from(1isize); + | error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:30:5 @@ -72,8 +75,9 @@ LL | 1usize as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u32::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as u32; +LL + u32::try_from(1usize); + | error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:31:5 @@ -84,8 +88,9 @@ LL | 1usize as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i32::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as i32; +LL + i32::try_from(1usize); + | error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:31:5 @@ -105,8 +110,9 @@ LL | 1i64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | isize::try_from(1i64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1i64 as isize; +LL + isize::try_from(1i64); + | error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:33:5 @@ -117,8 +123,9 @@ LL | 1i64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | usize::try_from(1i64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1i64 as usize; +LL + usize::try_from(1i64); + | error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:34:5 @@ -129,8 +136,9 @@ LL | 1u64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | isize::try_from(1u64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1u64 as isize; +LL + isize::try_from(1u64); + | error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:34:5 @@ -147,8 +155,9 @@ LL | 1u64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | usize::try_from(1u64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1u64 as usize; +LL + usize::try_from(1u64); + | error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:36:5 diff --git a/tests/ui/create_dir.stderr b/tests/ui/create_dir.stderr index ab51705bb55a..9bb98a2606dd 100644 --- a/tests/ui/create_dir.stderr +++ b/tests/ui/create_dir.stderr @@ -8,8 +8,9 @@ LL | std::fs::create_dir("foo"); = help: to override `-D warnings` add `#[allow(clippy::create_dir)]` help: consider calling `std::fs::create_dir_all` instead | -LL | create_dir_all("foo"); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - std::fs::create_dir("foo"); +LL + create_dir_all("foo"); + | error: calling `std::fs::create_dir` where there may be a better way --> tests/ui/create_dir.rs:11:5 @@ -19,8 +20,9 @@ LL | std::fs::create_dir("bar").unwrap(); | help: consider calling `std::fs::create_dir_all` instead | -LL | create_dir_all("bar").unwrap(); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - std::fs::create_dir("bar").unwrap(); +LL + create_dir_all("bar").unwrap(); + | error: aborting due to 2 previous errors diff --git a/tests/ui/dbg_macro/dbg_macro.stderr b/tests/ui/dbg_macro/dbg_macro.stderr index b3d74b9ff617..f218614fdd62 100644 --- a/tests/ui/dbg_macro/dbg_macro.stderr +++ b/tests/ui/dbg_macro/dbg_macro.stderr @@ -8,8 +8,9 @@ LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]` help: remove the invocation before committing it to a version control system | -LL | if let Some(n) = n.checked_sub(4) { n } else { n } - | ~~~~~~~~~~~~~~~~ +LL - if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } +LL + if let Some(n) = n.checked_sub(4) { n } else { n } + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:11:8 @@ -19,8 +20,9 @@ LL | if dbg!(n <= 1) { | help: remove the invocation before committing it to a version control system | -LL | if n <= 1 { - | ~~~~~~ +LL - if dbg!(n <= 1) { +LL + if n <= 1 { + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:13:9 @@ -30,7 +32,8 @@ LL | dbg!(1) | help: remove the invocation before committing it to a version control system | -LL | 1 +LL - dbg!(1) +LL + 1 | error: the `dbg!` macro is intended as a debugging tool @@ -41,7 +44,8 @@ LL | dbg!(n * factorial(n - 1)) | help: remove the invocation before committing it to a version control system | -LL | n * factorial(n - 1) +LL - dbg!(n * factorial(n - 1)) +LL + n * factorial(n - 1) | error: the `dbg!` macro is intended as a debugging tool @@ -52,8 +56,9 @@ LL | dbg!(42); | help: remove the invocation before committing it to a version control system | -LL | 42; - | ~~ +LL - dbg!(42); +LL + 42; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:24:14 @@ -63,8 +68,9 @@ LL | foo(3) + dbg!(factorial(4)); | help: remove the invocation before committing it to a version control system | -LL | foo(3) + factorial(4); - | ~~~~~~~~~~~~ +LL - foo(3) + dbg!(factorial(4)); +LL + foo(3) + factorial(4); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:26:5 @@ -74,8 +80,9 @@ LL | dbg!(1, 2, 3, 4, 5); | help: remove the invocation before committing it to a version control system | -LL | (1, 2, 3, 4, 5); - | ~~~~~~~~~~~~~~~ +LL - dbg!(1, 2, 3, 4, 5); +LL + (1, 2, 3, 4, 5); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:48:5 @@ -96,8 +103,9 @@ LL | let _ = dbg!(); | help: remove the invocation before committing it to a version control system | -LL | let _ = (); - | ~~ +LL - let _ = dbg!(); +LL + let _ = (); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:53:9 @@ -107,8 +115,9 @@ LL | bar(dbg!()); | help: remove the invocation before committing it to a version control system | -LL | bar(()); - | ~~ +LL - bar(dbg!()); +LL + bar(()); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:55:10 @@ -118,8 +127,9 @@ LL | foo!(dbg!()); | help: remove the invocation before committing it to a version control system | -LL | foo!(()); - | ~~ +LL - foo!(dbg!()); +LL + foo!(()); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:57:16 @@ -129,8 +139,9 @@ LL | foo2!(foo!(dbg!())); | help: remove the invocation before committing it to a version control system | -LL | foo2!(foo!(())); - | ~~ +LL - foo2!(foo!(dbg!())); +LL + foo2!(foo!(())); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:43:13 @@ -155,8 +166,9 @@ LL | dbg!(2); | help: remove the invocation before committing it to a version control system | -LL | 2; - | ~ +LL - dbg!(2); +LL + 2; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:86:5 @@ -166,8 +178,9 @@ LL | dbg!(1); | help: remove the invocation before committing it to a version control system | -LL | 1; - | ~ +LL - dbg!(1); +LL + 1; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:92:5 @@ -177,8 +190,9 @@ LL | dbg!(1); | help: remove the invocation before committing it to a version control system | -LL | 1; - | ~ +LL - dbg!(1); +LL + 1; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:99:9 @@ -188,8 +202,9 @@ LL | dbg!(1); | help: remove the invocation before committing it to a version control system | -LL | 1; - | ~ +LL - dbg!(1); +LL + 1; + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:106:31 @@ -199,8 +214,9 @@ LL | println!("dbg: {:?}", dbg!(s)); | help: remove the invocation before committing it to a version control system | -LL | println!("dbg: {:?}", s); - | ~ +LL - println!("dbg: {:?}", dbg!(s)); +LL + println!("dbg: {:?}", s); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:108:22 @@ -210,8 +226,9 @@ LL | print!("{}", dbg!(s)); | help: remove the invocation before committing it to a version control system | -LL | print!("{}", s); - | ~ +LL - print!("{}", dbg!(s)); +LL + print!("{}", s); + | error: aborting due to 19 previous errors diff --git a/tests/ui/dbg_macro/dbg_macro_unfixable.stderr b/tests/ui/dbg_macro/dbg_macro_unfixable.stderr index b8e91906b931..e8d5f9f2f46f 100644 --- a/tests/ui/dbg_macro/dbg_macro_unfixable.stderr +++ b/tests/ui/dbg_macro/dbg_macro_unfixable.stderr @@ -19,8 +19,9 @@ LL | dbg!(dbg!(dbg!(42))); | help: remove the invocation before committing it to a version control system | -LL | dbg!(dbg!(42)); - | ~~~~~~~~~~~~~~ +LL - dbg!(dbg!(dbg!(42))); +LL + dbg!(dbg!(42)); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:8:10 @@ -30,8 +31,9 @@ LL | dbg!(dbg!(dbg!(42))); | help: remove the invocation before committing it to a version control system | -LL | dbg!(dbg!(42)); - | ~~~~~~~~ +LL - dbg!(dbg!(dbg!(42))); +LL + dbg!(dbg!(42)); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:8:15 @@ -41,8 +43,9 @@ LL | dbg!(dbg!(dbg!(42))); | help: remove the invocation before committing it to a version control system | -LL | dbg!(dbg!(42)); - | ~~ +LL - dbg!(dbg!(dbg!(42))); +LL + dbg!(dbg!(42)); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:10:5 @@ -52,8 +55,9 @@ LL | dbg!(1, 2, dbg!(3, 4)); | help: remove the invocation before committing it to a version control system | -LL | (1, 2, dbg!(3, 4)); - | ~~~~~~~~~~~~~~~~~~ +LL - dbg!(1, 2, dbg!(3, 4)); +LL + (1, 2, dbg!(3, 4)); + | error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:10:16 @@ -63,8 +67,9 @@ LL | dbg!(1, 2, dbg!(3, 4)); | help: remove the invocation before committing it to a version control system | -LL | dbg!(1, 2, (3, 4)); - | ~~~~~~ +LL - dbg!(1, 2, dbg!(3, 4)); +LL + dbg!(1, 2, (3, 4)); + | error: aborting due to 6 previous errors diff --git a/tests/ui/doc/doc-fixable.stderr b/tests/ui/doc/doc-fixable.stderr index 27a04e4b5583..54d735814855 100644 --- a/tests/ui/doc/doc-fixable.stderr +++ b/tests/ui/doc/doc-fixable.stderr @@ -8,8 +8,9 @@ LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot t = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// The `foo_bar` function does _nothing_. See also foo::bar. (note the dot there) - | ~~~~~~~~~ +LL - /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there) +LL + /// The `foo_bar` function does _nothing_. See also foo::bar. (note the dot there) + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:9:51 @@ -19,8 +20,9 @@ LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot t | help: try | -LL | /// The foo_bar function does _nothing_. See also `foo::bar`. (note the dot there) - | ~~~~~~~~~~ +LL - /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there) +LL + /// The foo_bar function does _nothing_. See also `foo::bar`. (note the dot there) + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:10:83 @@ -30,8 +32,9 @@ LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. B | help: try | -LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun` - | ~~~~~~~~~~~~~~~ +LL - /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun +LL + /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:12:13 @@ -41,8 +44,9 @@ LL | /// Here be ::a::global:path, and _::another::global::path_. :: is not a p | help: try | -LL | /// Here be `::a::global:path`, and _::another::global::path_. :: is not a path though. - | ~~~~~~~~~~~~~~~~~~ +LL - /// Here be ::a::global:path, and _::another::global::path_. :: is not a path though. +LL + /// Here be `::a::global:path`, and _::another::global::path_. :: is not a path though. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:12:36 @@ -52,8 +56,9 @@ LL | /// Here be ::a::global:path, and _::another::global::path_. :: is not a p | help: try | -LL | /// Here be ::a::global:path, and _`::another::global::path`_. :: is not a path though. - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// Here be ::a::global:path, and _::another::global::path_. :: is not a path though. +LL + /// Here be ::a::global:path, and _`::another::global::path`_. :: is not a path though. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:13:25 @@ -63,8 +68,9 @@ LL | /// Import an item from ::awesome::global::blob:: (Intended postfix) | help: try | -LL | /// Import an item from `::awesome::global::blob::` (Intended postfix) - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// Import an item from ::awesome::global::blob:: (Intended postfix) +LL + /// Import an item from `::awesome::global::blob::` (Intended postfix) + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:14:31 @@ -74,8 +80,9 @@ LL | /// These are the options for ::Cat: (Intended trailing single colon, shoul | help: try | -LL | /// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted) - | ~~~~~~~ +LL - /// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted) +LL + /// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted) + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:15:22 @@ -85,8 +92,9 @@ LL | /// That's not code ~NotInCodeBlock~. | help: try | -LL | /// That's not code ~`NotInCodeBlock`~. - | ~~~~~~~~~~~~~~~~ +LL - /// That's not code ~NotInCodeBlock~. +LL + /// That's not code ~`NotInCodeBlock`~. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:16:5 @@ -96,8 +104,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:30:5 @@ -107,8 +116,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:37:5 @@ -118,8 +128,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:51:5 @@ -129,8 +140,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:79:5 @@ -140,8 +152,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:96:5 @@ -151,8 +164,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:104:8 @@ -162,8 +176,9 @@ LL | /// ## CamelCaseThing | help: try | -LL | /// ## `CamelCaseThing` - | ~~~~~~~~~~~~~~~~ +LL - /// ## CamelCaseThing +LL + /// ## `CamelCaseThing` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:107:7 @@ -173,8 +188,9 @@ LL | /// # CamelCaseThing | help: try | -LL | /// # `CamelCaseThing` - | ~~~~~~~~~~~~~~~~ +LL - /// # CamelCaseThing +LL + /// # `CamelCaseThing` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:109:22 @@ -184,8 +200,9 @@ LL | /// Not a title #897 CamelCaseThing | help: try | -LL | /// Not a title #897 `CamelCaseThing` - | ~~~~~~~~~~~~~~~~ +LL - /// Not a title #897 CamelCaseThing +LL + /// Not a title #897 `CamelCaseThing` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:110:5 @@ -195,8 +212,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:117:5 @@ -206,8 +224,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:130:5 @@ -217,8 +236,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:141:43 @@ -228,8 +248,9 @@ LL | /** E.g., serialization of an empty list: FooBar | help: try | -LL | /** E.g., serialization of an empty list: `FooBar` - | ~~~~~~~~ +LL - /** E.g., serialization of an empty list: FooBar +LL + /** E.g., serialization of an empty list: `FooBar` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:146:5 @@ -239,8 +260,9 @@ LL | And BarQuz too. | help: try | -LL | And `BarQuz` too. - | ~~~~~~~~ +LL - And BarQuz too. +LL + And `BarQuz` too. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:147:1 @@ -250,7 +272,8 @@ LL | be_sure_we_got_to_the_end_of_it | help: try | -LL | `be_sure_we_got_to_the_end_of_it` +LL - be_sure_we_got_to_the_end_of_it +LL + `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks @@ -261,8 +284,9 @@ LL | /** E.g., serialization of an empty list: FooBar | help: try | -LL | /** E.g., serialization of an empty list: `FooBar` - | ~~~~~~~~ +LL - /** E.g., serialization of an empty list: FooBar +LL + /** E.g., serialization of an empty list: `FooBar` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:157:5 @@ -272,8 +296,9 @@ LL | And BarQuz too. | help: try | -LL | And `BarQuz` too. - | ~~~~~~~~ +LL - And BarQuz too. +LL + And `BarQuz` too. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:158:1 @@ -283,7 +308,8 @@ LL | be_sure_we_got_to_the_end_of_it | help: try | -LL | `be_sure_we_got_to_the_end_of_it` +LL - be_sure_we_got_to_the_end_of_it +LL + `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks @@ -294,8 +320,9 @@ LL | /// be_sure_we_got_to_the_end_of_it | help: try | -LL | /// `be_sure_we_got_to_the_end_of_it` - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - /// be_sure_we_got_to_the_end_of_it +LL + /// `be_sure_we_got_to_the_end_of_it` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:188:22 @@ -305,8 +332,9 @@ LL | /// An iterator over mycrate::Collection's values. | help: try | -LL | /// An iterator over `mycrate::Collection`'s values. - | ~~~~~~~~~~~~~~~~~~~~~ +LL - /// An iterator over mycrate::Collection's values. +LL + /// An iterator over `mycrate::Collection`'s values. + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:212:34 @@ -316,8 +344,9 @@ LL | /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint | help: try | -LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint` - | ~~~~~~~~~~~~~~~~~ +LL - /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint +LL + /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:235:22 @@ -327,8 +356,9 @@ LL | /// There is no try (do() or do_not()). | help: try | -LL | /// There is no try (`do()` or do_not()). - | ~~~~~~ +LL - /// There is no try (do() or do_not()). +LL + /// There is no try (`do()` or do_not()). + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:235:30 @@ -338,8 +368,9 @@ LL | /// There is no try (do() or do_not()). | help: try | -LL | /// There is no try (do() or `do_not()`). - | ~~~~~~~~~~ +LL - /// There is no try (do() or do_not()). +LL + /// There is no try (do() or `do_not()`). + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:238:5 @@ -349,8 +380,9 @@ LL | /// ABes | help: try | -LL | /// `ABes` - | ~~~~~~ +LL - /// ABes +LL + /// `ABes` + | error: item in documentation is missing backticks --> tests/ui/doc/doc-fixable.rs:244:9 @@ -360,8 +392,9 @@ LL | /// foo() | help: try | -LL | /// `foo()` - | ~~~~~~~ +LL - /// foo() +LL + /// `foo()` + | error: you should put bare URLs between `<`/`>` or make a proper Markdown link --> tests/ui/doc/doc-fixable.rs:248:5 diff --git a/tests/ui/doc/doc_markdown-issue_13097.stderr b/tests/ui/doc/doc_markdown-issue_13097.stderr index ae68a767ec93..65b8f2ed80b6 100644 --- a/tests/ui/doc/doc_markdown-issue_13097.stderr +++ b/tests/ui/doc/doc_markdown-issue_13097.stderr @@ -11,8 +11,9 @@ LL | #![deny(clippy::doc_markdown)] | ^^^^^^^^^^^^^^^^^^^^ help: try | -LL | /// `HumaNified` - | ~~~~~~~~~~~~ +LL - /// HumaNified +LL + /// `HumaNified` + | error: aborting due to 1 previous error diff --git a/tests/ui/doc/issue_10262.stderr b/tests/ui/doc/issue_10262.stderr index f43d9551e94e..f9ecb3de219b 100644 --- a/tests/ui/doc/issue_10262.stderr +++ b/tests/ui/doc/issue_10262.stderr @@ -8,8 +8,9 @@ LL | /// AviSynth documentation: = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// `AviSynth` documentation: - | ~~~~~~~~~~ +LL - /// AviSynth documentation: +LL + /// `AviSynth` documentation: + | error: aborting due to 1 previous error diff --git a/tests/ui/doc/issue_12795.stderr b/tests/ui/doc/issue_12795.stderr index 5700145ec8f7..047de915ed4c 100644 --- a/tests/ui/doc/issue_12795.stderr +++ b/tests/ui/doc/issue_12795.stderr @@ -8,8 +8,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b( = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | //! A comment with `a_b(x)` and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) - | ~~~~~~~~ +LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) +LL + //! A comment with `a_b(x)` and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) + | error: item in documentation is missing backticks --> tests/ui/doc/issue_12795.rs:3:31 @@ -19,8 +20,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b( | help: try | -LL | //! A comment with a_b(x) and `a_c` in it and (a_b((c)) ) too and (maybe a_b((c))) - | ~~~~~ +LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) +LL + //! A comment with a_b(x) and `a_c` in it and (a_b((c)) ) too and (maybe a_b((c))) + | error: item in documentation is missing backticks --> tests/ui/doc/issue_12795.rs:3:46 @@ -30,8 +32,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b( | help: try | -LL | //! A comment with a_b(x) and a_c in it and (`a_b((c))` ) too and (maybe a_b((c))) - | ~~~~~~~~~~ +LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) +LL + //! A comment with a_b(x) and a_c in it and (`a_b((c))` ) too and (maybe a_b((c))) + | error: item in documentation is missing backticks --> tests/ui/doc/issue_12795.rs:3:72 @@ -41,8 +44,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b( | help: try | -LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe `a_b((c))`) - | ~~~~~~~~~~ +LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) +LL + //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe `a_b((c))`) + | error: aborting due to 4 previous errors diff --git a/tests/ui/doc/issue_9473.stderr b/tests/ui/doc/issue_9473.stderr index 35aa2884cc11..744c8dc8c838 100644 --- a/tests/ui/doc/issue_9473.stderr +++ b/tests/ui/doc/issue_9473.stderr @@ -8,8 +8,9 @@ LL | /// Blah blah blah [FooBar]<[FooBar]>[FooBar]. = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` help: try | -LL | /// Blah blah blah [FooBar]<[FooBar]>[`FooBar`]. - | ~~~~~~~~ +LL - /// Blah blah blah [FooBar]<[FooBar]>[FooBar]. +LL + /// Blah blah blah [FooBar]<[FooBar]>[`FooBar`]. + | error: aborting due to 1 previous error diff --git a/tests/ui/doc/unbalanced_ticks.stderr b/tests/ui/doc/unbalanced_ticks.stderr index c9fd25eb1a1c..4114a823822c 100644 --- a/tests/ui/doc/unbalanced_ticks.stderr +++ b/tests/ui/doc/unbalanced_ticks.stderr @@ -29,8 +29,9 @@ LL | /// This paragraph is fine and should_be linted normally. | help: try | -LL | /// This paragraph is fine and `should_be` linted normally. - | ~~~~~~~~~~~ +LL - /// This paragraph is fine and should_be linted normally. +LL + /// This paragraph is fine and `should_be` linted normally. + | error: backticks are unbalanced --> tests/ui/doc/unbalanced_ticks.rs:20:5 @@ -48,8 +49,9 @@ LL | /// ## not_fine | help: try | -LL | /// ## `not_fine` - | ~~~~~~~~~~ +LL - /// ## not_fine +LL + /// ## `not_fine` + | error: backticks are unbalanced --> tests/ui/doc/unbalanced_ticks.rs:37:5 @@ -75,8 +77,9 @@ LL | /// - This item needs backticks_here | help: try | -LL | /// - This item needs `backticks_here` - | ~~~~~~~~~~~~~~~~ +LL - /// - This item needs backticks_here +LL + /// - This item needs `backticks_here` + | error: backticks are unbalanced --> tests/ui/doc/unbalanced_ticks.rs:53:5 diff --git a/tests/ui/eager_transmute.stderr b/tests/ui/eager_transmute.stderr index 5cf7bd49a929..68690c3730d8 100644 --- a/tests/ui/eager_transmute.stderr +++ b/tests/ui/eager_transmute.stderr @@ -8,8 +8,9 @@ LL | (op < 4).then_some(unsafe { std::mem::transmute(op) }) = help: to override `-D warnings` add `#[allow(clippy::eager_transmute)]` help: consider using `bool::then` to only transmute if the condition holds | -LL | (op < 4).then(|| unsafe { std::mem::transmute(op) }) - | ~~~~ ++ +LL - (op < 4).then_some(unsafe { std::mem::transmute(op) }) +LL + (op < 4).then(|| unsafe { std::mem::transmute(op) }) + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:27:33 @@ -19,8 +20,9 @@ LL | (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); | help: consider using `bool::then` to only transmute if the condition holds | -LL | (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); - | ~~~~ ++ +LL - (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); +LL + (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:28:33 @@ -30,8 +32,9 @@ LL | (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); | help: consider using `bool::then` to only transmute if the condition holds | -LL | (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); - | ~~~~ ++ +LL - (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); +LL + (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:29:34 @@ -41,8 +44,9 @@ LL | (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); | help: consider using `bool::then` to only transmute if the condition holds | -LL | (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); - | ~~~~ ++ +LL - (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); +LL + (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:31:68 @@ -52,8 +56,9 @@ LL | let _: Option = (op > 0 && op < 10).then_some(unsafe { std::mem | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (op > 0 && op < 10).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option = (op > 0 && op < 10).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option = (op > 0 && op < 10).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:32:86 @@ -63,8 +68,9 @@ LL | let _: Option = (op > 0 && op < 10 && unrelated == 0).then_some | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (op > 0 && op < 10 && unrelated == 0).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option = (op > 0 && op < 10 && unrelated == 0).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option = (op > 0 && op < 10 && unrelated == 0).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:35:84 @@ -74,8 +80,9 @@ LL | let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(u | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| unsafe { std::mem::transmute(op2.foo[0]) }); - | ~~~~ ++ +LL - let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[0]) }); +LL + let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| unsafe { std::mem::transmute(op2.foo[0]) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:47:70 @@ -85,8 +92,9 @@ LL | let _: Option = (1..=3).contains(&op).then_some(unsafe { std::m | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (1..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option = (1..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option = (1..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:48:83 @@ -96,8 +104,9 @@ LL | let _: Option = ((1..=3).contains(&op) || op == 4).then_some(un | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = ((1..=3).contains(&op) || op == 4).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option = ((1..=3).contains(&op) || op == 4).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option = ((1..=3).contains(&op) || op == 4).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:49:69 @@ -107,8 +116,9 @@ LL | let _: Option = (1..3).contains(&op).then_some(unsafe { std::me | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (1..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option = (1..3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option = (1..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:50:68 @@ -118,8 +128,9 @@ LL | let _: Option = (1..).contains(&op).then_some(unsafe { std::mem | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (1..).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option = (1..).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option = (1..).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:51:68 @@ -129,8 +140,9 @@ LL | let _: Option = (..3).contains(&op).then_some(unsafe { std::mem | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option = (..3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option = (..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:52:69 @@ -140,8 +152,9 @@ LL | let _: Option = (..=3).contains(&op).then_some(unsafe { std::me | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); - | ~~~~ ++ +LL - let _: Option = (..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); +LL + let _: Option = (..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:61:24 @@ -151,8 +164,9 @@ LL | (op < 4).then_some(std::mem::transmute::<_, Opcode>(op)); | help: consider using `bool::then` to only transmute if the condition holds | -LL | (op < 4).then(|| std::mem::transmute::<_, Opcode>(op)); - | ~~~~ ++ +LL - (op < 4).then_some(std::mem::transmute::<_, Opcode>(op)); +LL + (op < 4).then(|| std::mem::transmute::<_, Opcode>(op)); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:90:62 @@ -162,8 +176,9 @@ LL | let _: Option> = (v1 > 0).then_some(unsafe { std::mem::tran | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) }); - | ~~~~ ++ +LL - let _: Option> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) }); +LL + let _: Option> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:96:86 @@ -173,8 +188,9 @@ LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); - | ~~~~ ++ +LL - let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); +LL + let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); + | error: this transmute is always evaluated eagerly, even if the condition is false --> tests/ui/eager_transmute.rs:102:93 @@ -184,8 +200,9 @@ LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).th | help: consider using `bool::then` to only transmute if the condition holds | -LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); - | ~~~~ ++ +LL - let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); +LL + let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); + | error: aborting due to 17 previous errors diff --git a/tests/ui/empty_line_after/doc_comments.stderr b/tests/ui/empty_line_after/doc_comments.stderr index 7b197ae67e00..ca05a1b03eb1 100644 --- a/tests/ui/empty_line_after/doc_comments.stderr +++ b/tests/ui/empty_line_after/doc_comments.stderr @@ -131,8 +131,9 @@ LL | fn first_in_module() {} = help: if the empty line is unintentional, remove it help: if the comment should document the parent module use an inner doc comment | -LL | /*! - | ~ +LL - /** +LL + /*! + | error: empty line after doc comment --> tests/ui/empty_line_after/doc_comments.rs:85:5 diff --git a/tests/ui/excessive_precision.stderr b/tests/ui/excessive_precision.stderr index 81e4fb6765d0..b1f12eed4200 100644 --- a/tests/ui/excessive_precision.stderr +++ b/tests/ui/excessive_precision.stderr @@ -8,8 +8,9 @@ LL | const BAD32_1: f32 = 0.123_456_789_f32; = help: to override `-D warnings` add `#[allow(clippy::excessive_precision)]` help: consider changing the type or truncating it to | -LL | const BAD32_1: f32 = 0.123_456_79_f32; - | ~~~~~~~~~~~~~~~~ +LL - const BAD32_1: f32 = 0.123_456_789_f32; +LL + const BAD32_1: f32 = 0.123_456_79_f32; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:21:26 @@ -19,8 +20,9 @@ LL | const BAD32_2: f32 = 0.123_456_789; | help: consider changing the type or truncating it to | -LL | const BAD32_2: f32 = 0.123_456_79; - | ~~~~~~~~~~~~ +LL - const BAD32_2: f32 = 0.123_456_789; +LL + const BAD32_2: f32 = 0.123_456_79; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:22:26 @@ -30,8 +32,9 @@ LL | const BAD32_3: f32 = 0.100_000_000_000_1; | help: consider changing the type or truncating it to | -LL | const BAD32_3: f32 = 0.1; - | ~~~ +LL - const BAD32_3: f32 = 0.100_000_000_000_1; +LL + const BAD32_3: f32 = 0.1; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:23:29 @@ -41,8 +44,9 @@ LL | const BAD32_EDGE: f32 = 1.000_000_9; | help: consider changing the type or truncating it to | -LL | const BAD32_EDGE: f32 = 1.000_001; - | ~~~~~~~~~ +LL - const BAD32_EDGE: f32 = 1.000_000_9; +LL + const BAD32_EDGE: f32 = 1.000_001; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:27:26 @@ -52,8 +56,9 @@ LL | const BAD64_3: f64 = 0.100_000_000_000_000_000_1; | help: consider changing the type or truncating it to | -LL | const BAD64_3: f64 = 0.1; - | ~~~ +LL - const BAD64_3: f64 = 0.100_000_000_000_000_000_1; +LL + const BAD64_3: f64 = 0.1; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:30:22 @@ -63,8 +68,9 @@ LL | println!("{:?}", 8.888_888_888_888_888_888_888); | help: consider changing the type or truncating it to | -LL | println!("{:?}", 8.888_888_888_888_89); - | ~~~~~~~~~~~~~~~~~~~~ +LL - println!("{:?}", 8.888_888_888_888_888_888_888); +LL + println!("{:?}", 8.888_888_888_888_89); + | error: float has excessive precision --> tests/ui/excessive_precision.rs:41:22 @@ -74,8 +80,9 @@ LL | let bad32: f32 = 1.123_456_789; | help: consider changing the type or truncating it to | -LL | let bad32: f32 = 1.123_456_8; - | ~~~~~~~~~~~ +LL - let bad32: f32 = 1.123_456_789; +LL + let bad32: f32 = 1.123_456_8; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:42:26 @@ -85,8 +92,9 @@ LL | let bad32_suf: f32 = 1.123_456_789_f32; | help: consider changing the type or truncating it to | -LL | let bad32_suf: f32 = 1.123_456_8_f32; - | ~~~~~~~~~~~~~~~ +LL - let bad32_suf: f32 = 1.123_456_789_f32; +LL + let bad32_suf: f32 = 1.123_456_8_f32; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:43:21 @@ -96,8 +104,9 @@ LL | let bad32_inf = 1.123_456_789_f32; | help: consider changing the type or truncating it to | -LL | let bad32_inf = 1.123_456_8_f32; - | ~~~~~~~~~~~~~~~ +LL - let bad32_inf = 1.123_456_789_f32; +LL + let bad32_inf = 1.123_456_8_f32; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:53:36 @@ -107,8 +116,9 @@ LL | let bad_vec32: Vec = vec![0.123_456_789]; | help: consider changing the type or truncating it to | -LL | let bad_vec32: Vec = vec![0.123_456_79]; - | ~~~~~~~~~~~~ +LL - let bad_vec32: Vec = vec![0.123_456_789]; +LL + let bad_vec32: Vec = vec![0.123_456_79]; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:54:36 @@ -118,8 +128,9 @@ LL | let bad_vec64: Vec = vec![0.123_456_789_123_456_789]; | help: consider changing the type or truncating it to | -LL | let bad_vec64: Vec = vec![0.123_456_789_123_456_78]; - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let bad_vec64: Vec = vec![0.123_456_789_123_456_789]; +LL + let bad_vec64: Vec = vec![0.123_456_789_123_456_78]; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:58:24 @@ -129,8 +140,9 @@ LL | let bad_e32: f32 = 1.123_456_788_888e-10; | help: consider changing the type or truncating it to | -LL | let bad_e32: f32 = 1.123_456_8e-10; - | ~~~~~~~~~~~~~~~ +LL - let bad_e32: f32 = 1.123_456_788_888e-10; +LL + let bad_e32: f32 = 1.123_456_8e-10; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:61:27 @@ -140,8 +152,9 @@ LL | let bad_bige32: f32 = 1.123_456_788_888E-10; | help: consider changing the type or truncating it to | -LL | let bad_bige32: f32 = 1.123_456_8E-10; - | ~~~~~~~~~~~~~~~ +LL - let bad_bige32: f32 = 1.123_456_788_888E-10; +LL + let bad_bige32: f32 = 1.123_456_8E-10; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:70:13 @@ -151,8 +164,9 @@ LL | let _ = 2.225_073_858_507_201_1e-308_f64; | help: consider changing the type or truncating it to | -LL | let _ = 2.225_073_858_507_201e-308_f64; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = 2.225_073_858_507_201_1e-308_f64; +LL + let _ = 2.225_073_858_507_201e-308_f64; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:73:13 @@ -162,8 +176,9 @@ LL | let _ = 1.000_000_000_000_001e-324_f64; | help: consider changing the type or truncating it to | -LL | let _ = 0_f64; - | ~~~~~ +LL - let _ = 1.000_000_000_000_001e-324_f64; +LL + let _ = 0_f64; + | error: float has excessive precision --> tests/ui/excessive_precision.rs:83:20 @@ -173,8 +188,9 @@ LL | const _: f64 = 3.0000000000000000e+00; | help: consider changing the type or truncating it to | -LL | const _: f64 = 3.0; - | ~~~ +LL - const _: f64 = 3.0000000000000000e+00; +LL + const _: f64 = 3.0; + | error: aborting due to 16 previous errors diff --git a/tests/ui/fn_to_numeric_cast_any.stderr b/tests/ui/fn_to_numeric_cast_any.stderr index a05b7138bc99..c069c9d1672d 100644 --- a/tests/ui/fn_to_numeric_cast_any.stderr +++ b/tests/ui/fn_to_numeric_cast_any.stderr @@ -8,8 +8,9 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_any)]` help: did you mean to invoke the function? | -LL | let _ = foo() as i8; - | ~~~~~~~~~~~ +LL - let _ = foo as i8; +LL + let _ = foo() as i8; + | error: casting function pointer `foo` to `i16` --> tests/ui/fn_to_numeric_cast_any.rs:26:13 @@ -19,8 +20,9 @@ LL | let _ = foo as i16; | help: did you mean to invoke the function? | -LL | let _ = foo() as i16; - | ~~~~~~~~~~~~ +LL - let _ = foo as i16; +LL + let _ = foo() as i16; + | error: casting function pointer `foo` to `i32` --> tests/ui/fn_to_numeric_cast_any.rs:28:13 @@ -30,8 +32,9 @@ LL | let _ = foo as i32; | help: did you mean to invoke the function? | -LL | let _ = foo() as i32; - | ~~~~~~~~~~~~ +LL - let _ = foo as i32; +LL + let _ = foo() as i32; + | error: casting function pointer `foo` to `i64` --> tests/ui/fn_to_numeric_cast_any.rs:30:13 @@ -41,8 +44,9 @@ LL | let _ = foo as i64; | help: did you mean to invoke the function? | -LL | let _ = foo() as i64; - | ~~~~~~~~~~~~ +LL - let _ = foo as i64; +LL + let _ = foo() as i64; + | error: casting function pointer `foo` to `i128` --> tests/ui/fn_to_numeric_cast_any.rs:32:13 @@ -52,8 +56,9 @@ LL | let _ = foo as i128; | help: did you mean to invoke the function? | -LL | let _ = foo() as i128; - | ~~~~~~~~~~~~~ +LL - let _ = foo as i128; +LL + let _ = foo() as i128; + | error: casting function pointer `foo` to `isize` --> tests/ui/fn_to_numeric_cast_any.rs:34:13 @@ -63,8 +68,9 @@ LL | let _ = foo as isize; | help: did you mean to invoke the function? | -LL | let _ = foo() as isize; - | ~~~~~~~~~~~~~~ +LL - let _ = foo as isize; +LL + let _ = foo() as isize; + | error: casting function pointer `foo` to `u8` --> tests/ui/fn_to_numeric_cast_any.rs:37:13 @@ -74,8 +80,9 @@ LL | let _ = foo as u8; | help: did you mean to invoke the function? | -LL | let _ = foo() as u8; - | ~~~~~~~~~~~ +LL - let _ = foo as u8; +LL + let _ = foo() as u8; + | error: casting function pointer `foo` to `u16` --> tests/ui/fn_to_numeric_cast_any.rs:39:13 @@ -85,8 +92,9 @@ LL | let _ = foo as u16; | help: did you mean to invoke the function? | -LL | let _ = foo() as u16; - | ~~~~~~~~~~~~ +LL - let _ = foo as u16; +LL + let _ = foo() as u16; + | error: casting function pointer `foo` to `u32` --> tests/ui/fn_to_numeric_cast_any.rs:41:13 @@ -96,8 +104,9 @@ LL | let _ = foo as u32; | help: did you mean to invoke the function? | -LL | let _ = foo() as u32; - | ~~~~~~~~~~~~ +LL - let _ = foo as u32; +LL + let _ = foo() as u32; + | error: casting function pointer `foo` to `u64` --> tests/ui/fn_to_numeric_cast_any.rs:43:13 @@ -107,8 +116,9 @@ LL | let _ = foo as u64; | help: did you mean to invoke the function? | -LL | let _ = foo() as u64; - | ~~~~~~~~~~~~ +LL - let _ = foo as u64; +LL + let _ = foo() as u64; + | error: casting function pointer `foo` to `u128` --> tests/ui/fn_to_numeric_cast_any.rs:45:13 @@ -118,8 +128,9 @@ LL | let _ = foo as u128; | help: did you mean to invoke the function? | -LL | let _ = foo() as u128; - | ~~~~~~~~~~~~~ +LL - let _ = foo as u128; +LL + let _ = foo() as u128; + | error: casting function pointer `foo` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:47:13 @@ -129,8 +140,9 @@ LL | let _ = foo as usize; | help: did you mean to invoke the function? | -LL | let _ = foo() as usize; - | ~~~~~~~~~~~~~~ +LL - let _ = foo as usize; +LL + let _ = foo() as usize; + | error: casting function pointer `Struct::static_method` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:52:13 @@ -140,8 +152,9 @@ LL | let _ = Struct::static_method as usize; | help: did you mean to invoke the function? | -LL | let _ = Struct::static_method() as usize; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Struct::static_method as usize; +LL + let _ = Struct::static_method() as usize; + | error: casting function pointer `f` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:57:5 @@ -151,7 +164,8 @@ LL | f as usize | help: did you mean to invoke the function? | -LL | f() as usize +LL - f as usize +LL + f() as usize | error: casting function pointer `T::static_method` to `usize` @@ -162,7 +176,8 @@ LL | T::static_method as usize | help: did you mean to invoke the function? | -LL | T::static_method() as usize +LL - T::static_method as usize +LL + T::static_method() as usize | error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` @@ -173,8 +188,9 @@ LL | let _ = (clos as fn(u32) -> u32) as usize; | help: did you mean to invoke the function? | -LL | let _ = (clos as fn(u32) -> u32)() as usize; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = (clos as fn(u32) -> u32) as usize; +LL + let _ = (clos as fn(u32) -> u32)() as usize; + | error: casting function pointer `foo` to `*const ()` --> tests/ui/fn_to_numeric_cast_any.rs:74:13 @@ -184,8 +200,9 @@ LL | let _ = foo as *const (); | help: did you mean to invoke the function? | -LL | let _ = foo() as *const (); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = foo as *const (); +LL + let _ = foo() as *const (); + | error: aborting due to 17 previous errors diff --git a/tests/ui/for_kv_map.stderr b/tests/ui/for_kv_map.stderr index adcc3ab8fdb9..11b61c8cbc64 100644 --- a/tests/ui/for_kv_map.stderr +++ b/tests/ui/for_kv_map.stderr @@ -8,8 +8,9 @@ LL | for (_, v) in &m { = help: to override `-D warnings` add `#[allow(clippy::for_kv_map)]` help: use the corresponding method | -LL | for v in m.values() { - | ~ ~~~~~~~~~~ +LL - for (_, v) in &m { +LL + for v in m.values() { + | error: you seem to want to iterate on a map's values --> tests/ui/for_kv_map.rs:16:19 @@ -19,8 +20,9 @@ LL | for (_, v) in &*m { | help: use the corresponding method | -LL | for v in (*m).values() { - | ~ ~~~~~~~~~~~~~ +LL - for (_, v) in &*m { +LL + for v in (*m).values() { + | error: you seem to want to iterate on a map's values --> tests/ui/for_kv_map.rs:25:19 @@ -30,8 +32,9 @@ LL | for (_, v) in &mut m { | help: use the corresponding method | -LL | for v in m.values_mut() { - | ~ ~~~~~~~~~~~~~~ +LL - for (_, v) in &mut m { +LL + for v in m.values_mut() { + | error: you seem to want to iterate on a map's values --> tests/ui/for_kv_map.rs:31:19 @@ -41,8 +44,9 @@ LL | for (_, v) in &mut *m { | help: use the corresponding method | -LL | for v in (*m).values_mut() { - | ~ ~~~~~~~~~~~~~~~~~ +LL - for (_, v) in &mut *m { +LL + for v in (*m).values_mut() { + | error: you seem to want to iterate on a map's keys --> tests/ui/for_kv_map.rs:38:24 @@ -52,8 +56,9 @@ LL | for (k, _value) in rm { | help: use the corresponding method | -LL | for k in rm.keys() { - | ~ ~~~~~~~~~ +LL - for (k, _value) in rm { +LL + for k in rm.keys() { + | error: you seem to want to iterate on a map's keys --> tests/ui/for_kv_map.rs:45:32 @@ -63,8 +68,9 @@ LL | 'label: for (k, _value) in rm { | help: use the corresponding method | -LL | 'label: for k in rm.keys() { - | ~ ~~~~~~~~~ +LL - 'label: for (k, _value) in rm { +LL + 'label: for k in rm.keys() { + | error: aborting due to 6 previous errors diff --git a/tests/ui/four_forward_slashes.stderr b/tests/ui/four_forward_slashes.stderr index 3606a2227a00..d5bf71fadc7d 100644 --- a/tests/ui/four_forward_slashes.stderr +++ b/tests/ui/four_forward_slashes.stderr @@ -9,6 +9,8 @@ LL | | fn a() {} = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]` help: make this a doc comment by removing one `/` | +LL - //// whoops +LL - fn a() {} LL + /// whoops | @@ -22,6 +24,8 @@ LL | | fn b() {} | help: make this a doc comment by removing one `/` | +LL - //// whoops +LL - #[allow(dead_code)] LL + /// whoops | @@ -50,6 +54,8 @@ LL | | fn g() {} | help: make this a doc comment by removing one `/` | +LL - //// between attributes +LL - #[allow(dead_code)] LL + /// between attributes | @@ -62,6 +68,8 @@ LL | | fn h() {} | help: make this a doc comment by removing one `/` | +LL - //// not very start of contents +LL - fn h() {} LL + /// not very start of contents | diff --git a/tests/ui/four_forward_slashes_first_line.stderr b/tests/ui/four_forward_slashes_first_line.stderr index 81732346412a..83bfb60eb16f 100644 --- a/tests/ui/four_forward_slashes_first_line.stderr +++ b/tests/ui/four_forward_slashes_first_line.stderr @@ -9,6 +9,8 @@ LL | | fn a() {} = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]` help: make this a doc comment by removing one `/` | +LL - //// borked doc comment on the first line. doesn't combust! +LL - fn a() {} LL + /// borked doc comment on the first line. doesn't combust! | diff --git a/tests/ui/get_unwrap.stderr b/tests/ui/get_unwrap.stderr index 8eacb249c60c..fc6c0b9299c4 100644 --- a/tests/ui/get_unwrap.stderr +++ b/tests/ui/get_unwrap.stderr @@ -11,8 +11,9 @@ LL | #![deny(clippy::get_unwrap)] | ^^^^^^^^^^^^^^^^^^ help: using `[]` is clearer and more concise | -LL | let _ = &boxed_slice[1]; - | ~~~~~~~~~~~~~~~ +LL - let _ = boxed_slice.get(1).unwrap(); +LL + let _ = &boxed_slice[1]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:37:17 @@ -33,8 +34,9 @@ LL | let _ = some_slice.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_slice[0]; - | ~~~~~~~~~~~~~~ +LL - let _ = some_slice.get(0).unwrap(); +LL + let _ = &some_slice[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:38:17 @@ -53,8 +55,9 @@ LL | let _ = some_vec.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_vec[0]; - | ~~~~~~~~~~~~ +LL - let _ = some_vec.get(0).unwrap(); +LL + let _ = &some_vec[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:39:17 @@ -73,8 +76,9 @@ LL | let _ = some_vecdeque.get(0).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_vecdeque[0]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = some_vecdeque.get(0).unwrap(); +LL + let _ = &some_vecdeque[0]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:40:17 @@ -93,8 +97,9 @@ LL | let _ = some_hashmap.get(&1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_hashmap[&1]; - | ~~~~~~~~~~~~~~~~~ +LL - let _ = some_hashmap.get(&1).unwrap(); +LL + let _ = &some_hashmap[&1]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:41:17 @@ -113,8 +118,9 @@ LL | let _ = some_btreemap.get(&1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _ = &some_btreemap[&1]; - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = some_btreemap.get(&1).unwrap(); +LL + let _ = &some_btreemap[&1]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:42:17 @@ -133,8 +139,9 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _: u8 = boxed_slice[1]; - | ~~~~~~~~~~~~~~ +LL - let _: u8 = *boxed_slice.get(1).unwrap(); +LL + let _: u8 = boxed_slice[1]; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:46:22 @@ -153,8 +160,9 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | boxed_slice[0] = 1; - | ~~~~~~~~~~~~~~ +LL - *boxed_slice.get_mut(0).unwrap() = 1; +LL + boxed_slice[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:51:10 @@ -173,8 +181,9 @@ LL | *some_slice.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_slice[0] = 1; - | ~~~~~~~~~~~~~ +LL - *some_slice.get_mut(0).unwrap() = 1; +LL + some_slice[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:52:10 @@ -193,8 +202,9 @@ LL | *some_vec.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_vec[0] = 1; - | ~~~~~~~~~~~ +LL - *some_vec.get_mut(0).unwrap() = 1; +LL + some_vec[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:53:10 @@ -213,8 +223,9 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1; | help: using `[]` is clearer and more concise | -LL | some_vecdeque[0] = 1; - | ~~~~~~~~~~~~~~~~ +LL - *some_vecdeque.get_mut(0).unwrap() = 1; +LL + some_vecdeque[0] = 1; + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:54:10 @@ -233,8 +244,9 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | help: using `[]` is clearer and more concise | -LL | let _ = some_vec[0..1].to_vec(); - | ~~~~~~~~~~~~~~ +LL - let _ = some_vec.get(0..1).unwrap().to_vec(); +LL + let _ = some_vec[0..1].to_vec(); + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:66:17 @@ -253,8 +265,9 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | help: using `[]` is clearer and more concise | -LL | let _ = some_vec[0..1].to_vec(); - | ~~~~~~~~~~~~~~ +LL - let _ = some_vec.get_mut(0..1).unwrap().to_vec(); +LL + let _ = some_vec[0..1].to_vec(); + | error: used `unwrap()` on an `Option` value --> tests/ui/get_unwrap.rs:67:17 @@ -273,8 +286,9 @@ LL | let _x: &i32 = f.get(1 + 2).unwrap(); | help: using `[]` is clearer and more concise | -LL | let _x: &i32 = &f[1 + 2]; - | ~~~~~~~~~ +LL - let _x: &i32 = f.get(1 + 2).unwrap(); +LL + let _x: &i32 = &f[1 + 2]; + | error: called `.get().unwrap()` on a slice --> tests/ui/get_unwrap.rs:81:18 @@ -284,8 +298,9 @@ LL | let _x = f.get(1 + 2).unwrap().to_string(); | help: using `[]` is clearer and more concise | -LL | let _x = f[1 + 2].to_string(); - | ~~~~~~~~ +LL - let _x = f.get(1 + 2).unwrap().to_string(); +LL + let _x = f[1 + 2].to_string(); + | error: called `.get().unwrap()` on a slice --> tests/ui/get_unwrap.rs:84:18 @@ -295,8 +310,9 @@ LL | let _x = f.get(1 + 2).unwrap().abs(); | help: using `[]` is clearer and more concise | -LL | let _x = f[1 + 2].abs(); - | ~~~~~~~~ +LL - let _x = f.get(1 + 2).unwrap().abs(); +LL + let _x = f[1 + 2].abs(); + | error: called `.get_mut().unwrap()` on a slice --> tests/ui/get_unwrap.rs:101:33 @@ -306,8 +322,9 @@ LL | let b = rest.get_mut(linidx(j, k) - linidx(i, k) - | help: using `[]` is clearer and more concise | -LL | let b = &mut rest[linidx(j, k) - linidx(i, k) - 1]; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); +LL + let b = &mut rest[linidx(j, k) - linidx(i, k) - 1]; + | error: aborting due to 30 previous errors diff --git a/tests/ui/implicit_hasher.stderr b/tests/ui/implicit_hasher.stderr index 442f4789aacf..6e964c65a2e4 100644 --- a/tests/ui/implicit_hasher.stderr +++ b/tests/ui/implicit_hasher.stderr @@ -78,8 +78,9 @@ LL | pub fn map(map: &mut HashMap) {} | help: add a type parameter for `BuildHasher` | -LL | pub fn map(map: &mut HashMap) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ +LL - pub fn map(map: &mut HashMap) {} +LL + pub fn map(map: &mut HashMap) {} + | error: parameter of type `HashSet` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:70:22 @@ -89,8 +90,9 @@ LL | pub fn set(set: &mut HashSet) {} | help: add a type parameter for `BuildHasher` | -LL | pub fn set(set: &mut HashSet) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ +LL - pub fn set(set: &mut HashSet) {} +LL + pub fn set(set: &mut HashSet) {} + | error: impl for `HashMap` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:76:43 @@ -114,8 +116,9 @@ LL | pub async fn election_vote(_data: HashMap) {} | help: add a type parameter for `BuildHasher` | -LL | pub async fn election_vote(_data: HashMap) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ +LL - pub async fn election_vote(_data: HashMap) {} +LL + pub async fn election_vote(_data: HashMap) {} + | error: aborting due to 9 previous errors diff --git a/tests/ui/implicit_return.stderr b/tests/ui/implicit_return.stderr index 3b06f26f5a05..0d2faa5e067b 100644 --- a/tests/ui/implicit_return.stderr +++ b/tests/ui/implicit_return.stderr @@ -8,7 +8,8 @@ LL | true = help: to override `-D warnings` add `#[allow(clippy::implicit_return)]` help: add `return` as shown | -LL | return true +LL - true +LL + return true | error: missing `return` statement @@ -19,8 +20,9 @@ LL | if true { true } else { false } | help: add `return` as shown | -LL | if true { return true } else { false } - | ~~~~~~~~~~~ +LL - if true { true } else { false } +LL + if true { return true } else { false } + | error: missing `return` statement --> tests/ui/implicit_return.rs:19:29 @@ -30,8 +32,9 @@ LL | if true { true } else { false } | help: add `return` as shown | -LL | if true { true } else { return false } - | ~~~~~~~~~~~~ +LL - if true { true } else { false } +LL + if true { true } else { return false } + | error: missing `return` statement --> tests/ui/implicit_return.rs:25:17 @@ -41,8 +44,9 @@ LL | true => false, | help: add `return` as shown | -LL | true => return false, - | ~~~~~~~~~~~~ +LL - true => false, +LL + true => return false, + | error: missing `return` statement --> tests/ui/implicit_return.rs:26:20 @@ -52,8 +56,9 @@ LL | false => { true }, | help: add `return` as shown | -LL | false => { return true }, - | ~~~~~~~~~~~ +LL - false => { true }, +LL + false => { return true }, + | error: missing `return` statement --> tests/ui/implicit_return.rs:39:9 @@ -63,8 +68,9 @@ LL | break true; | help: change `break` to `return` as shown | -LL | return true; - | ~~~~~~~~~~~ +LL - break true; +LL + return true; + | error: missing `return` statement --> tests/ui/implicit_return.rs:46:13 @@ -74,8 +80,9 @@ LL | break true; | help: change `break` to `return` as shown | -LL | return true; - | ~~~~~~~~~~~ +LL - break true; +LL + return true; + | error: missing `return` statement --> tests/ui/implicit_return.rs:54:13 @@ -85,8 +92,9 @@ LL | break true; | help: change `break` to `return` as shown | -LL | return true; - | ~~~~~~~~~~~ +LL - break true; +LL + return true; + | error: missing `return` statement --> tests/ui/implicit_return.rs:72:18 @@ -96,8 +104,9 @@ LL | let _ = || { true }; | help: add `return` as shown | -LL | let _ = || { return true }; - | ~~~~~~~~~~~ +LL - let _ = || { true }; +LL + let _ = || { return true }; + | error: missing `return` statement --> tests/ui/implicit_return.rs:73:16 @@ -107,8 +116,9 @@ LL | let _ = || true; | help: add `return` as shown | -LL | let _ = || return true; - | ~~~~~~~~~~~ +LL - let _ = || true; +LL + let _ = || return true; + | error: missing `return` statement --> tests/ui/implicit_return.rs:81:5 @@ -118,7 +128,8 @@ LL | format!("test {}", "test") | help: add `return` as shown | -LL | return format!("test {}", "test") +LL - format!("test {}", "test") +LL + return format!("test {}", "test") | error: missing `return` statement @@ -129,7 +140,8 @@ LL | m!(true, false) | help: add `return` as shown | -LL | return m!(true, false) +LL - m!(true, false) +LL + return m!(true, false) | error: missing `return` statement @@ -140,8 +152,9 @@ LL | break true; | help: change `break` to `return` as shown | -LL | return true; - | ~~~~~~~~~~~ +LL - break true; +LL + return true; + | error: missing `return` statement --> tests/ui/implicit_return.rs:101:17 @@ -151,8 +164,9 @@ LL | break 'outer false; | help: change `break` to `return` as shown | -LL | return false; - | ~~~~~~~~~~~~ +LL - break 'outer false; +LL + return false; + | error: missing `return` statement --> tests/ui/implicit_return.rs:116:5 @@ -177,7 +191,8 @@ LL | true | help: add `return` as shown | -LL | return true +LL - true +LL + return true | error: aborting due to 16 previous errors diff --git a/tests/ui/iter_nth.stderr b/tests/ui/iter_nth.stderr index 178463f53475..1167a604ecdc 100644 --- a/tests/ui/iter_nth.stderr +++ b/tests/ui/iter_nth.stderr @@ -8,8 +8,9 @@ LL | let bad_vec = some_vec.iter().nth(3); = help: to override `-D warnings` add `#[allow(clippy::iter_nth)]` help: `get` is equivalent but more concise | -LL | let bad_vec = some_vec.get(3); - | ~~~ +LL - let bad_vec = some_vec.iter().nth(3); +LL + let bad_vec = some_vec.get(3); + | error: called `.iter().nth()` on a slice --> tests/ui/iter_nth.rs:35:26 @@ -19,8 +20,9 @@ LL | let bad_slice = &some_vec[..].iter().nth(3); | help: `get` is equivalent but more concise | -LL | let bad_slice = &some_vec[..].get(3); - | ~~~ +LL - let bad_slice = &some_vec[..].iter().nth(3); +LL + let bad_slice = &some_vec[..].get(3); + | error: called `.iter().nth()` on a slice --> tests/ui/iter_nth.rs:36:31 @@ -30,8 +32,9 @@ LL | let bad_boxed_slice = boxed_slice.iter().nth(3); | help: `get` is equivalent but more concise | -LL | let bad_boxed_slice = boxed_slice.get(3); - | ~~~ +LL - let bad_boxed_slice = boxed_slice.iter().nth(3); +LL + let bad_boxed_slice = boxed_slice.get(3); + | error: called `.iter().nth()` on a `VecDeque` --> tests/ui/iter_nth.rs:37:29 @@ -41,8 +44,9 @@ LL | let bad_vec_deque = some_vec_deque.iter().nth(3); | help: `get` is equivalent but more concise | -LL | let bad_vec_deque = some_vec_deque.get(3); - | ~~~ +LL - let bad_vec_deque = some_vec_deque.iter().nth(3); +LL + let bad_vec_deque = some_vec_deque.get(3); + | error: called `.iter_mut().nth()` on a `Vec` --> tests/ui/iter_nth.rs:42:23 @@ -52,8 +56,9 @@ LL | let bad_vec = some_vec.iter_mut().nth(3); | help: `get_mut` is equivalent but more concise | -LL | let bad_vec = some_vec.get_mut(3); - | ~~~~~~~ +LL - let bad_vec = some_vec.iter_mut().nth(3); +LL + let bad_vec = some_vec.get_mut(3); + | error: called `.iter_mut().nth()` on a slice --> tests/ui/iter_nth.rs:45:26 @@ -63,8 +68,9 @@ LL | let bad_slice = &some_vec[..].iter_mut().nth(3); | help: `get_mut` is equivalent but more concise | -LL | let bad_slice = &some_vec[..].get_mut(3); - | ~~~~~~~ +LL - let bad_slice = &some_vec[..].iter_mut().nth(3); +LL + let bad_slice = &some_vec[..].get_mut(3); + | error: called `.iter_mut().nth()` on a `VecDeque` --> tests/ui/iter_nth.rs:48:29 @@ -74,8 +80,9 @@ LL | let bad_vec_deque = some_vec_deque.iter_mut().nth(3); | help: `get_mut` is equivalent but more concise | -LL | let bad_vec_deque = some_vec_deque.get_mut(3); - | ~~~~~~~ +LL - let bad_vec_deque = some_vec_deque.iter_mut().nth(3); +LL + let bad_vec_deque = some_vec_deque.get_mut(3); + | error: called `.iter().nth()` on a `Vec` --> tests/ui/iter_nth.rs:52:5 @@ -85,8 +92,9 @@ LL | vec_ref.iter().nth(3); | help: `get` is equivalent but more concise | -LL | vec_ref.get(3); - | ~~~ +LL - vec_ref.iter().nth(3); +LL + vec_ref.get(3); + | error: aborting due to 8 previous errors diff --git a/tests/ui/join_absolute_paths.stderr b/tests/ui/join_absolute_paths.stderr index e7fd5508823a..300946bf3b5f 100644 --- a/tests/ui/join_absolute_paths.stderr +++ b/tests/ui/join_absolute_paths.stderr @@ -9,12 +9,14 @@ LL | path.join("/sh"); = help: to override `-D warnings` add `#[allow(clippy::join_absolute_paths)]` help: if this is unintentional, try removing the starting separator | -LL | path.join("sh"); - | ~~~~ +LL - path.join("/sh"); +LL + path.join("sh"); + | help: if this is intentional, consider using `Path::new` | -LL | PathBuf::from("/sh"); - | ~~~~~~~~~~~~~~~~~~~~ +LL - path.join("/sh"); +LL + PathBuf::from("/sh"); + | error: argument to `Path::join` starts with a path separator --> tests/ui/join_absolute_paths.rs:14:15 @@ -25,12 +27,14 @@ LL | path.join("\\user"); = note: joining a path starting with separator will replace the path instead help: if this is unintentional, try removing the starting separator | -LL | path.join("\user"); - | ~~~~~~~ +LL - path.join("\\user"); +LL + path.join("\user"); + | help: if this is intentional, consider using `Path::new` | -LL | PathBuf::from("\\user"); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - path.join("\\user"); +LL + PathBuf::from("\\user"); + | error: argument to `Path::join` starts with a path separator --> tests/ui/join_absolute_paths.rs:18:15 @@ -41,12 +45,14 @@ LL | path.join("/sh"); = note: joining a path starting with separator will replace the path instead help: if this is unintentional, try removing the starting separator | -LL | path.join("sh"); - | ~~~~ +LL - path.join("/sh"); +LL + path.join("sh"); + | help: if this is intentional, consider using `Path::new` | -LL | PathBuf::from("/sh"); - | ~~~~~~~~~~~~~~~~~~~~ +LL - path.join("/sh"); +LL + PathBuf::from("/sh"); + | error: argument to `Path::join` starts with a path separator --> tests/ui/join_absolute_paths.rs:22:15 @@ -57,12 +63,14 @@ LL | path.join(r#"/sh"#); = note: joining a path starting with separator will replace the path instead help: if this is unintentional, try removing the starting separator | -LL | path.join(r#"sh"#); - | ~~~~~~~ +LL - path.join(r#"/sh"#); +LL + path.join(r#"sh"#); + | help: if this is intentional, consider using `Path::new` | -LL | PathBuf::from(r#"/sh"#); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - path.join(r#"/sh"#); +LL + PathBuf::from(r#"/sh"#); + | error: aborting due to 4 previous errors diff --git a/tests/ui/large_enum_variant.64bit.stderr b/tests/ui/large_enum_variant.64bit.stderr index 805cb406f834..60653b4abfb5 100644 --- a/tests/ui/large_enum_variant.64bit.stderr +++ b/tests/ui/large_enum_variant.64bit.stderr @@ -13,8 +13,9 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]` help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<[i32; 8000]>), - | ~~~~~~~~~~~~~~~~ +LL - B([i32; 8000]), +LL + B(Box<[i32; 8000]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:35:1 @@ -29,8 +30,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | ContainingLargeEnum(Box), - | ~~~~~~~~~~~~~~ +LL - ContainingLargeEnum(LargeEnum), +LL + ContainingLargeEnum(Box), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:40:1 @@ -46,8 +48,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), - | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), +LL + ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:46:1 @@ -62,8 +65,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, - | ~~~~~~~~~~~~~~~~ +LL - StructLikeLarge { x: [i32; 8000], y: i32 }, +LL + StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:51:1 @@ -78,8 +82,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | StructLikeLarge2 { x: Box<[i32; 8000]> }, - | ~~~~~~~~~~~~~~~~ +LL - StructLikeLarge2 { x: [i32; 8000] }, +LL + StructLikeLarge2 { x: Box<[i32; 8000]> }, + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:67:1 @@ -95,8 +100,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<[u8; 1255]>), - | ~~~~~~~~~~~~~~~ +LL - B([u8; 1255]), +LL + B(Box<[u8; 1255]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:73:1 @@ -111,8 +117,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]), - | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), +LL + ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:78:1 @@ -127,8 +134,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box), - | ~~~~~~~~~~~~ +LL - B(Struct2), +LL + B(Box), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:83:1 @@ -143,8 +151,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box), - | ~~~~~~~~~~~~ +LL - B(Struct2), +LL + B(Box), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:88:1 @@ -159,8 +168,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box), - | ~~~~~~~~~~~~ +LL - B(Struct2), +LL + B(Box), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:103:1 @@ -241,8 +251,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Large(Box<(T, [u8; 512])>), - | ~~~~~~~~~~~~~~~~~~~ +LL - Large((T, [u8; 512])), +LL + Large(Box<(T, [u8; 512])>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:143:1 @@ -257,8 +268,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Large(Box<[Foo; 64]>), - | ~~~~~~~~~~~~~~~~~~~ +LL - Large([Foo; 64]), +LL + Large(Box<[Foo; 64]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:153:1 @@ -273,8 +285,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Error(Box>), - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - Error(PossiblyLargeEnumWithConst<256>), +LL + Error(Box>), + | error: aborting due to 16 previous errors diff --git a/tests/ui/legacy_numeric_constants.stderr b/tests/ui/legacy_numeric_constants.stderr index 267b9ac8e4d1..74fe09e0f5c6 100644 --- a/tests/ui/legacy_numeric_constants.stderr +++ b/tests/ui/legacy_numeric_constants.stderr @@ -8,8 +8,9 @@ LL | std::f32::EPSILON; = help: to override `-D warnings` add `#[allow(clippy::legacy_numeric_constants)]` help: use the associated constant instead | -LL | f32::EPSILON; - | ~~~~~~~~~~~~ +LL - std::f32::EPSILON; +LL + f32::EPSILON; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:34:5 @@ -19,8 +20,9 @@ LL | std::u8::MIN; | help: use the associated constant instead | -LL | u8::MIN; - | ~~~~~~~ +LL - std::u8::MIN; +LL + u8::MIN; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:37:5 @@ -30,8 +32,9 @@ LL | std::usize::MIN; | help: use the associated constant instead | -LL | usize::MIN; - | ~~~~~~~~~~ +LL - std::usize::MIN; +LL + usize::MIN; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:40:5 @@ -41,8 +44,9 @@ LL | std::u32::MAX; | help: use the associated constant instead | -LL | u32::MAX; - | ~~~~~~~~ +LL - std::u32::MAX; +LL + u32::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:43:5 @@ -52,8 +56,9 @@ LL | core::u32::MAX; | help: use the associated constant instead | -LL | u32::MAX; - | ~~~~~~~~ +LL - core::u32::MAX; +LL + u32::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:46:5 @@ -63,8 +68,9 @@ LL | MAX; | help: use the associated constant instead | -LL | u32::MAX; - | ~~~~~~~~ +LL - MAX; +LL + u32::MAX; + | error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:49:10 @@ -74,8 +80,9 @@ LL | i32::max_value(); | help: use the associated constant instead | -LL | i32::MAX; - | ~~~ +LL - i32::max_value(); +LL + i32::MAX; + | error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:52:9 @@ -85,8 +92,9 @@ LL | u8::max_value(); | help: use the associated constant instead | -LL | u8::MAX; - | ~~~ +LL - u8::max_value(); +LL + u8::MAX; + | error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:55:9 @@ -96,8 +104,9 @@ LL | u8::min_value(); | help: use the associated constant instead | -LL | u8::MIN; - | ~~~ +LL - u8::min_value(); +LL + u8::MIN; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:58:5 @@ -107,8 +116,9 @@ LL | ::std::u8::MIN; | help: use the associated constant instead | -LL | u8::MIN; - | ~~~~~~~ +LL - ::std::u8::MIN; +LL + u8::MIN; + | error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:61:27 @@ -118,8 +128,9 @@ LL | ::std::primitive::u8::min_value(); | help: use the associated constant instead | -LL | ::std::primitive::u8::MIN; - | ~~~ +LL - ::std::primitive::u8::min_value(); +LL + ::std::primitive::u8::MIN; + | error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:64:26 @@ -129,8 +140,9 @@ LL | std::primitive::i32::max_value(); | help: use the associated constant instead | -LL | std::primitive::i32::MAX; - | ~~~ +LL - std::primitive::i32::max_value(); +LL + std::primitive::i32::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:67:5 @@ -140,8 +152,9 @@ LL | self::a::u128::MAX; | help: use the associated constant instead | -LL | u128::MAX; - | ~~~~~~~~~ +LL - self::a::u128::MAX; +LL + u128::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:17:25 @@ -155,8 +168,9 @@ LL | b!(); = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the associated constant instead | -LL | let x = u64::MAX; - | ~~~~~~~~ +LL - let x = std::u64::MAX; +LL + let x = u64::MAX; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:81:14 @@ -166,8 +180,9 @@ LL | [(0, "", std::i128::MAX)]; | help: use the associated constant instead | -LL | [(0, "", i128::MAX)]; - | ~~~~~~~~~ +LL - [(0, "", std::i128::MAX)]; +LL + [(0, "", i128::MAX)]; + | error: usage of a legacy numeric constant --> tests/ui/legacy_numeric_constants.rs:115:5 @@ -177,8 +192,9 @@ LL | std::u32::MAX; | help: use the associated constant instead | -LL | u32::MAX; - | ~~~~~~~~ +LL - std::u32::MAX; +LL + u32::MAX; + | error: aborting due to 16 previous errors diff --git a/tests/ui/literals.stderr b/tests/ui/literals.stderr index 564e0bc4f747..a9192825b354 100644 --- a/tests/ui/literals.stderr +++ b/tests/ui/literals.stderr @@ -71,12 +71,14 @@ LL | let fail_multi_zero = 000_123usize; = help: to override `-D warnings` add `#[allow(clippy::zero_prefixed_literal)]` help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let fail_multi_zero = 123usize; - | ~~~~~~~~ +LL - let fail_multi_zero = 000_123usize; +LL + let fail_multi_zero = 123usize; + | help: if you mean to use an octal constant, use `0o` | -LL | let fail_multi_zero = 0o123usize; - | ~~~~~~~~~~ +LL - let fail_multi_zero = 000_123usize; +LL + let fail_multi_zero = 0o123usize; + | error: integer type suffix should not be separated by an underscore --> tests/ui/literals.rs:36:16 @@ -92,12 +94,14 @@ LL | let fail8 = 0123; | help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let fail8 = 123; - | ~~~ +LL - let fail8 = 0123; +LL + let fail8 = 123; + | help: if you mean to use an octal constant, use `0o` | -LL | let fail8 = 0o123; - | ~~~~~ +LL - let fail8 = 0123; +LL + let fail8 = 0o123; + | error: integer type suffix should not be separated by an underscore --> tests/ui/literals.rs:48:16 @@ -143,8 +147,9 @@ LL | let _ = 08; | help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let _ = 8; - | ~ +LL - let _ = 08; +LL + let _ = 8; + | error: this is a decimal constant --> tests/ui/literals.rs:72:13 @@ -154,8 +159,9 @@ LL | let _ = 09; | help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let _ = 9; - | ~ +LL - let _ = 09; +LL + let _ = 9; + | error: this is a decimal constant --> tests/ui/literals.rs:74:13 @@ -165,8 +171,9 @@ LL | let _ = 089; | help: if you mean to use a decimal constant, remove the `0` to avoid confusion | -LL | let _ = 89; - | ~~ +LL - let _ = 089; +LL + let _ = 89; + | error: aborting due to 20 previous errors diff --git a/tests/ui/lossy_float_literal.stderr b/tests/ui/lossy_float_literal.stderr index 3026854e317a..118351a62d00 100644 --- a/tests/ui/lossy_float_literal.stderr +++ b/tests/ui/lossy_float_literal.stderr @@ -8,8 +8,9 @@ LL | let _: f32 = 16_777_217.0; = help: to override `-D warnings` add `#[allow(clippy::lossy_float_literal)]` help: consider changing the type or replacing it with | -LL | let _: f32 = 16_777_216.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = 16_777_217.0; +LL + let _: f32 = 16_777_216.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:15:18 @@ -19,8 +20,9 @@ LL | let _: f32 = 16_777_219.0; | help: consider changing the type or replacing it with | -LL | let _: f32 = 16_777_220.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = 16_777_219.0; +LL + let _: f32 = 16_777_220.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:16:18 @@ -30,8 +32,9 @@ LL | let _: f32 = 16_777_219.; | help: consider changing the type or replacing it with | -LL | let _: f32 = 16_777_220.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = 16_777_219.; +LL + let _: f32 = 16_777_220.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:17:18 @@ -41,8 +44,9 @@ LL | let _: f32 = 16_777_219.000; | help: consider changing the type or replacing it with | -LL | let _: f32 = 16_777_220.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = 16_777_219.000; +LL + let _: f32 = 16_777_220.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:18:13 @@ -52,8 +56,9 @@ LL | let _ = 16_777_219f32; | help: consider changing the type or replacing it with | -LL | let _ = 16_777_220_f32; - | ~~~~~~~~~~~~~~ +LL - let _ = 16_777_219f32; +LL + let _ = 16_777_220_f32; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:19:19 @@ -63,8 +68,9 @@ LL | let _: f32 = -16_777_219.0; | help: consider changing the type or replacing it with | -LL | let _: f32 = -16_777_220.0; - | ~~~~~~~~~~~~ +LL - let _: f32 = -16_777_219.0; +LL + let _: f32 = -16_777_220.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:21:18 @@ -74,8 +80,9 @@ LL | let _: f64 = 9_007_199_254_740_993.0; | help: consider changing the type or replacing it with | -LL | let _: f64 = 9_007_199_254_740_992.0; - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: f64 = 9_007_199_254_740_993.0; +LL + let _: f64 = 9_007_199_254_740_992.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:22:18 @@ -85,8 +92,9 @@ LL | let _: f64 = 9_007_199_254_740_993.; | help: consider changing the type or replacing it with | -LL | let _: f64 = 9_007_199_254_740_992.0; - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: f64 = 9_007_199_254_740_993.; +LL + let _: f64 = 9_007_199_254_740_992.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:23:18 @@ -96,8 +104,9 @@ LL | let _: f64 = 9_007_199_254_740_993.00; | help: consider changing the type or replacing it with | -LL | let _: f64 = 9_007_199_254_740_992.0; - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: f64 = 9_007_199_254_740_993.00; +LL + let _: f64 = 9_007_199_254_740_992.0; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:24:13 @@ -107,8 +116,9 @@ LL | let _ = 9_007_199_254_740_993f64; | help: consider changing the type or replacing it with | -LL | let _ = 9_007_199_254_740_992_f64; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = 9_007_199_254_740_993f64; +LL + let _ = 9_007_199_254_740_992_f64; + | error: literal cannot be represented as the underlying type without loss of precision --> tests/ui/lossy_float_literal.rs:25:19 @@ -118,8 +128,9 @@ LL | let _: f64 = -9_007_199_254_740_993.0; | help: consider changing the type or replacing it with | -LL | let _: f64 = -9_007_199_254_740_992.0; - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: f64 = -9_007_199_254_740_993.0; +LL + let _: f64 = -9_007_199_254_740_992.0; + | error: aborting due to 11 previous errors diff --git a/tests/ui/manual_assert.edition2018.stderr b/tests/ui/manual_assert.edition2018.stderr index 004463720e26..dfccf7e99396 100644 --- a/tests/ui/manual_assert.edition2018.stderr +++ b/tests/ui/manual_assert.edition2018.stderr @@ -79,7 +79,15 @@ LL | | } | help: try instead | -LL | assert!(!(a > 2), "panic with comment"); +LL - if a > 2 { +LL - // comment +LL - /* this is a +LL - multiline +LL - comment */ +LL - /// Doc comment +LL - panic!("panic with comment") // comment after `panic!` +LL - } +LL + assert!(!(a > 2), "panic with comment"); | error: only a `panic!` in `if`-then statement diff --git a/tests/ui/manual_assert.edition2021.stderr b/tests/ui/manual_assert.edition2021.stderr index 004463720e26..dfccf7e99396 100644 --- a/tests/ui/manual_assert.edition2021.stderr +++ b/tests/ui/manual_assert.edition2021.stderr @@ -79,7 +79,15 @@ LL | | } | help: try instead | -LL | assert!(!(a > 2), "panic with comment"); +LL - if a > 2 { +LL - // comment +LL - /* this is a +LL - multiline +LL - comment */ +LL - /// Doc comment +LL - panic!("panic with comment") // comment after `panic!` +LL - } +LL + assert!(!(a > 2), "panic with comment"); | error: only a `panic!` in `if`-then statement diff --git a/tests/ui/manual_async_fn.stderr b/tests/ui/manual_async_fn.stderr index 68a97243436d..a7cfc30fb69c 100644 --- a/tests/ui/manual_async_fn.stderr +++ b/tests/ui/manual_async_fn.stderr @@ -8,8 +8,9 @@ LL | fn fut() -> impl Future { = help: to override `-D warnings` add `#[allow(clippy::manual_async_fn)]` help: make the function `async` and return the output of the future directly | -LL | async fn fut() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn fut() -> impl Future { +LL + async fn fut() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:11:1 @@ -19,8 +20,9 @@ LL | fn fut2() ->impl Future { | help: make the function `async` and return the output of the future directly | -LL | async fn fut2() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn fut2() ->impl Future { +LL + async fn fut2() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:16:1 @@ -30,8 +32,9 @@ LL | fn fut3()-> impl Future { | help: make the function `async` and return the output of the future directly | -LL | async fn fut3() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn fut3()-> impl Future { +LL + async fn fut3() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:20:1 @@ -41,8 +44,9 @@ LL | fn empty_fut() -> impl Future { | help: make the function `async` and return the output of the future directly | -LL | async fn empty_fut() {} - | ~~~~~~~~~~~~~~~~~~~~ ~~ +LL - fn empty_fut() -> impl Future { +LL + async fn empty_fut() {} + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:25:1 @@ -52,8 +56,9 @@ LL | fn empty_fut2() ->impl Future { | help: make the function `async` and return the output of the future directly | -LL | async fn empty_fut2() {} - | ~~~~~~~~~~~~~~~~~~~~~ ~~ +LL - fn empty_fut2() ->impl Future { +LL + async fn empty_fut2() {} + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:30:1 @@ -63,8 +68,9 @@ LL | fn empty_fut3()-> impl Future { | help: make the function `async` and return the output of the future directly | -LL | async fn empty_fut3() {} - | ~~~~~~~~~~~~~~~~~~~~~ ~~ +LL - fn empty_fut3()-> impl Future { +LL + async fn empty_fut3() {} + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:34:1 @@ -74,8 +80,9 @@ LL | fn core_fut() -> impl core::future::Future { | help: make the function `async` and return the output of the future directly | -LL | async fn core_fut() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn core_fut() -> impl core::future::Future { +LL + async fn core_fut() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:56:5 @@ -108,8 +115,9 @@ LL | fn elided(_: &i32) -> impl Future + '_ { | help: make the function `async` and return the output of the future directly | -LL | async fn elided(_: &i32) -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn elided(_: &i32) -> impl Future + '_ { +LL + async fn elided(_: &i32) -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:101:1 @@ -119,8 +127,9 @@ LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + | help: make the function `async` and return the output of the future directly | -LL | async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { +LL + async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:130:1 @@ -130,8 +139,9 @@ LL | pub fn issue_10450() -> impl Future { | help: make the function `async` and return the output of the future directly | -LL | pub async fn issue_10450() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - pub fn issue_10450() -> impl Future { +LL + pub async fn issue_10450() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:134:1 @@ -141,8 +151,9 @@ LL | pub(crate) fn issue_10450_2() -> impl Future { | help: make the function `async` and return the output of the future directly | -LL | pub(crate) async fn issue_10450_2() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - pub(crate) fn issue_10450_2() -> impl Future { +LL + pub(crate) async fn issue_10450_2() -> i32 { 42 } + | error: this function can be simplified using the `async fn` syntax --> tests/ui/manual_async_fn.rs:138:1 @@ -152,8 +163,9 @@ LL | pub(self) fn issue_10450_3() -> impl Future { | help: make the function `async` and return the output of the future directly | -LL | pub(self) async fn issue_10450_3() -> i32 { 42 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ +LL - pub(self) fn issue_10450_3() -> impl Future { +LL + pub(self) async fn issue_10450_3() -> i32 { 42 } + | error: aborting due to 13 previous errors diff --git a/tests/ui/manual_float_methods.stderr b/tests/ui/manual_float_methods.stderr index 676a4485ab4d..1352c5e73cab 100644 --- a/tests/ui/manual_float_methods.stderr +++ b/tests/ui/manual_float_methods.stderr @@ -17,16 +17,19 @@ LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {} = help: to override `-D warnings` add `#[allow(clippy::manual_is_finite)]` help: use the dedicated method instead | -LL | if x.is_finite() {} - | ~~~~~~~~~~~~~ +LL - if x != f32::INFINITY && x != f32::NEG_INFINITY {} +LL + if x.is_finite() {} + | help: this will alter how it handles NaN; if that is a problem, use instead | -LL | if x.is_finite() || x.is_nan() {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if x != f32::INFINITY && x != f32::NEG_INFINITY {} +LL + if x.is_finite() || x.is_nan() {} + | help: or, for conciseness | -LL | if !x.is_infinite() {} - | ~~~~~~~~~~~~~~~~ +LL - if x != f32::INFINITY && x != f32::NEG_INFINITY {} +LL + if !x.is_infinite() {} + | error: manually checking if a float is infinite --> tests/ui/manual_float_methods.rs:26:8 @@ -42,16 +45,19 @@ LL | if x != INFINITE && x != NEG_INFINITE {} | help: use the dedicated method instead | -LL | if x.is_finite() {} - | ~~~~~~~~~~~~~ +LL - if x != INFINITE && x != NEG_INFINITE {} +LL + if x.is_finite() {} + | help: this will alter how it handles NaN; if that is a problem, use instead | -LL | if x.is_finite() || x.is_nan() {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if x != INFINITE && x != NEG_INFINITE {} +LL + if x.is_finite() || x.is_nan() {} + | help: or, for conciseness | -LL | if !x.is_infinite() {} - | ~~~~~~~~~~~~~~~~ +LL - if x != INFINITE && x != NEG_INFINITE {} +LL + if !x.is_infinite() {} + | error: manually checking if a float is infinite --> tests/ui/manual_float_methods.rs:29:8 @@ -67,16 +73,19 @@ LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {} | help: use the dedicated method instead | -LL | if x.is_finite() {} - | ~~~~~~~~~~~~~ +LL - if x != f64::INFINITY && x != f64::NEG_INFINITY {} +LL + if x.is_finite() {} + | help: this will alter how it handles NaN; if that is a problem, use instead | -LL | if x.is_finite() || x.is_nan() {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if x != f64::INFINITY && x != f64::NEG_INFINITY {} +LL + if x.is_finite() || x.is_nan() {} + | help: or, for conciseness | -LL | if !x.is_infinite() {} - | ~~~~~~~~~~~~~~~~ +LL - if x != f64::INFINITY && x != f64::NEG_INFINITY {} +LL + if !x.is_infinite() {} + | error: manually checking if a float is infinite --> tests/ui/manual_float_methods.rs:44:12 diff --git a/tests/ui/manual_ignore_case_cmp.stderr b/tests/ui/manual_ignore_case_cmp.stderr index 11e8b8aebb54..bc6393b66d5c 100644 --- a/tests/ui/manual_ignore_case_cmp.stderr +++ b/tests/ui/manual_ignore_case_cmp.stderr @@ -11,8 +11,9 @@ LL | #![deny(clippy::manual_ignore_case_cmp)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.eq_ignore_ascii_case()` instead | -LL | if a.eq_ignore_ascii_case(b) { - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if a.to_ascii_lowercase() == b.to_ascii_lowercase() { +LL + if a.eq_ignore_ascii_case(b) { + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:12:8 @@ -22,8 +23,9 @@ LL | if a.to_ascii_uppercase() == b.to_ascii_uppercase() { | help: consider using `.eq_ignore_ascii_case()` instead | -LL | if a.eq_ignore_ascii_case(b) { - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if a.to_ascii_uppercase() == b.to_ascii_uppercase() { +LL + if a.eq_ignore_ascii_case(b) { + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:15:13 @@ -33,8 +35,9 @@ LL | let r = a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | let r = a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let r = a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + let r = a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:16:18 @@ -44,8 +47,9 @@ LL | let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | let r = r || a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase(); +LL + let r = r || a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:17:10 @@ -55,8 +59,9 @@ LL | r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | r && a.eq_ignore_ascii_case(&b.to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase(); +LL + r && a.eq_ignore_ascii_case(&b.to_uppercase()); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:19:8 @@ -66,8 +71,9 @@ LL | if a.to_ascii_lowercase() != b.to_ascii_lowercase() { | help: consider using `.eq_ignore_ascii_case()` instead | -LL | if !a.eq_ignore_ascii_case(b) { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if a.to_ascii_lowercase() != b.to_ascii_lowercase() { +LL + if !a.eq_ignore_ascii_case(b) { + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:22:8 @@ -77,8 +83,9 @@ LL | if a.to_ascii_uppercase() != b.to_ascii_uppercase() { | help: consider using `.eq_ignore_ascii_case()` instead | -LL | if !a.eq_ignore_ascii_case(b) { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if a.to_ascii_uppercase() != b.to_ascii_uppercase() { +LL + if !a.eq_ignore_ascii_case(b) { + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:25:13 @@ -88,8 +95,9 @@ LL | let r = a.to_ascii_lowercase() != b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | let r = !a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let r = a.to_ascii_lowercase() != b.to_ascii_lowercase(); +LL + let r = !a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:26:18 @@ -99,8 +107,9 @@ LL | let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | let r = r || !a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase(); +LL + let r = r || !a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:27:10 @@ -110,8 +119,9 @@ LL | r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | r && !a.eq_ignore_ascii_case(&b.to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase(); +LL + r && !a.eq_ignore_ascii_case(&b.to_uppercase()); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:38:5 @@ -121,8 +131,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:41:5 @@ -132,8 +143,9 @@ LL | a.to_ascii_lowercase() == 'a'; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&'a'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == 'a'; +LL + a.eq_ignore_ascii_case(&'a'); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:42:5 @@ -143,8 +155,9 @@ LL | 'a' == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | 'a'.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - 'a' == b.to_ascii_lowercase(); +LL + 'a'.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:45:5 @@ -154,8 +167,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:46:5 @@ -165,8 +179,9 @@ LL | a.to_ascii_lowercase() == b'a'; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b'a'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b'a'; +LL + a.eq_ignore_ascii_case(&b'a'); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:47:5 @@ -176,8 +191,9 @@ LL | b'a' == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b'a'.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b'a' == b.to_ascii_lowercase(); +LL + b'a'.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:50:5 @@ -187,8 +203,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:51:5 @@ -198,8 +215,9 @@ LL | a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.to_uppercase().eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.to_uppercase().eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:52:5 @@ -209,8 +227,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:53:5 @@ -220,8 +239,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:56:5 @@ -231,8 +251,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:57:5 @@ -242,8 +263,9 @@ LL | a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.to_uppercase().eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.to_uppercase().eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:58:5 @@ -253,8 +275,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:59:5 @@ -264,8 +287,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:62:5 @@ -275,8 +299,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:63:5 @@ -286,8 +311,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:64:5 @@ -297,8 +323,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:67:5 @@ -308,8 +335,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:68:5 @@ -319,8 +347,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:71:5 @@ -330,8 +359,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:72:5 @@ -341,8 +371,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:73:5 @@ -352,8 +383,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:75:5 @@ -363,8 +395,9 @@ LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); +LL + b.eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:76:5 @@ -374,8 +407,9 @@ LL | b.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == "a"; +LL + b.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:77:5 @@ -385,8 +419,9 @@ LL | "a" == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == a.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:80:5 @@ -396,8 +431,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:81:5 @@ -407,8 +443,9 @@ LL | a.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == "a"; +LL + a.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:82:5 @@ -418,8 +455,9 @@ LL | "a" == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == b.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:84:5 @@ -429,8 +467,9 @@ LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); +LL + b.eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:85:5 @@ -440,8 +479,9 @@ LL | b.to_ascii_lowercase() == "a"; | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == "a"; +LL + b.eq_ignore_ascii_case("a"); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:86:5 @@ -451,8 +491,9 @@ LL | "a" == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "a" == a.to_ascii_lowercase(); +LL + "a".eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:89:5 @@ -462,8 +503,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:92:5 @@ -473,8 +515,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(&b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:95:5 @@ -484,8 +527,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:96:5 @@ -495,8 +539,9 @@ LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); +LL + b.eq_ignore_ascii_case(&a); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:99:5 @@ -506,8 +551,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:102:5 @@ -517,8 +563,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:105:5 @@ -528,8 +575,9 @@ LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL + a.eq_ignore_ascii_case(b); + | error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:106:5 @@ -539,8 +587,9 @@ LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case(a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); +LL + b.eq_ignore_ascii_case(a); + | error: aborting due to 49 previous errors diff --git a/tests/ui/manual_is_ascii_check.stderr b/tests/ui/manual_is_ascii_check.stderr index 92d93208006a..7b3f0c938b0d 100644 --- a/tests/ui/manual_is_ascii_check.stderr +++ b/tests/ui/manual_is_ascii_check.stderr @@ -153,8 +153,9 @@ LL | take_while(|c| ('A'..='Z').contains(&c)); | help: try | -LL | take_while(|c: char| c.is_ascii_uppercase()); - | ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ +LL - take_while(|c| ('A'..='Z').contains(&c)); +LL + take_while(|c: char| c.is_ascii_uppercase()); + | error: manual check for common ascii range --> tests/ui/manual_is_ascii_check.rs:82:20 @@ -164,8 +165,9 @@ LL | take_while(|c| (b'A'..=b'Z').contains(&c)); | help: try | -LL | take_while(|c: u8| c.is_ascii_uppercase()); - | ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ +LL - take_while(|c| (b'A'..=b'Z').contains(&c)); +LL + take_while(|c: u8| c.is_ascii_uppercase()); + | error: manual check for common ascii range --> tests/ui/manual_is_ascii_check.rs:83:26 @@ -181,8 +183,9 @@ LL | let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').c | help: try | -LL | let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect(); - | ~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect(); +LL + let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect(); + | error: manual check for common ascii range --> tests/ui/manual_is_ascii_check.rs:88:71 @@ -192,8 +195,9 @@ LL | let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'. | help: try | -LL | let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect(); - | ~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect(); +LL + let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect(); + | error: aborting due to 29 previous errors diff --git a/tests/ui/map_all_any_identity.stderr b/tests/ui/map_all_any_identity.stderr index 98fdcc2a9393..39df2a3d9616 100644 --- a/tests/ui/map_all_any_identity.stderr +++ b/tests/ui/map_all_any_identity.stderr @@ -8,8 +8,9 @@ LL | let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a); = help: to override `-D warnings` add `#[allow(clippy::map_all_any_identity)]` help: use `.any(...)` instead | -LL | let _ = ["foo"].into_iter().any(|s| s == "foo"); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a); +LL + let _ = ["foo"].into_iter().any(|s| s == "foo"); + | error: usage of `.map(...).all(identity)` --> tests/ui/map_all_any_identity.rs:6:33 @@ -19,8 +20,9 @@ LL | let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::ident | help: use `.all(...)` instead | -LL | let _ = ["foo"].into_iter().all(|s| s == "foo"); - | ~~~~~~~~~~~~~~~~~~~ +LL - let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity); +LL + let _ = ["foo"].into_iter().all(|s| s == "foo"); + | error: aborting due to 2 previous errors diff --git a/tests/ui/map_with_unused_argument_over_ranges.stderr b/tests/ui/map_with_unused_argument_over_ranges.stderr index 0b56c6d95219..840515f95df4 100644 --- a/tests/ui/map_with_unused_argument_over_ranges.stderr +++ b/tests/ui/map_with_unused_argument_over_ranges.stderr @@ -68,8 +68,9 @@ LL | (0..10).map(|_| 3); | help: remove the explicit range and use `repeat_n` | -LL | std::iter::repeat_n(3, 10); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~ +LL - (0..10).map(|_| 3); +LL + std::iter::repeat_n(3, 10); + | error: map of a closure that does not depend on its parameter over a range --> tests/ui/map_with_unused_argument_over_ranges.rs:31:5 @@ -216,8 +217,9 @@ LL | (0..10).map(|_| 3); | help: remove the explicit range and use `repeat` and `take` | -LL | std::iter::repeat(3).take(10); - | ~~~~~~~~~~~~~~~~~ ~ +++++++++ +LL - (0..10).map(|_| 3); +LL + std::iter::repeat(3).take(10); + | error: aborting due to 18 previous errors diff --git a/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr b/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr index d47f3d09175b..975ded83560f 100644 --- a/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr +++ b/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr @@ -8,8 +8,9 @@ LL | let _: Vec<_> = (0..10).map(|_| 3 + 1).collect(); = help: to override `-D warnings` add `#[allow(clippy::map_with_unused_argument_over_ranges)]` help: remove the explicit range and use `repeat_n` | -LL | let _: Vec<_> = core::iter::repeat_n(3 + 1, 10).collect(); - | ~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~ +LL - let _: Vec<_> = (0..10).map(|_| 3 + 1).collect(); +LL + let _: Vec<_> = core::iter::repeat_n(3 + 1, 10).collect(); + | error: aborting due to 1 previous error diff --git a/tests/ui/match_result_ok.stderr b/tests/ui/match_result_ok.stderr index b5b91cbe5534..18b23bd78454 100644 --- a/tests/ui/match_result_ok.stderr +++ b/tests/ui/match_result_ok.stderr @@ -8,8 +8,9 @@ LL | if let Some(y) = x.parse().ok() { y } else { 0 } = help: to override `-D warnings` add `#[allow(clippy::match_result_ok)]` help: consider matching on `Ok(y)` and removing the call to `ok` instead | -LL | if let Ok(y) = x.parse() { y } else { 0 } - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(y) = x.parse().ok() { y } else { 0 } +LL + if let Ok(y) = x.parse() { y } else { 0 } + | error: matching on `Some` with `ok()` is redundant --> tests/ui/match_result_ok.rs:23:9 @@ -19,8 +20,9 @@ LL | if let Some(y) = x . parse() . ok () { | help: consider matching on `Ok(y)` and removing the call to `ok` instead | -LL | if let Ok(y) = x . parse() { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(y) = x . parse() . ok () { +LL + if let Ok(y) = x . parse() { + | error: matching on `Some` with `ok()` is redundant --> tests/ui/match_result_ok.rs:49:5 @@ -30,8 +32,9 @@ LL | while let Some(a) = wat.next().ok() { | help: consider matching on `Ok(a)` and removing the call to `ok` instead | -LL | while let Ok(a) = wat.next() { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - while let Some(a) = wat.next().ok() { +LL + while let Ok(a) = wat.next() { + | error: aborting due to 3 previous errors diff --git a/tests/ui/match_str_case_mismatch.stderr b/tests/ui/match_str_case_mismatch.stderr index 67e9ccaf6d2f..5b14fd13a53b 100644 --- a/tests/ui/match_str_case_mismatch.stderr +++ b/tests/ui/match_str_case_mismatch.stderr @@ -8,8 +8,9 @@ LL | "Bar" => {}, = help: to override `-D warnings` add `#[allow(clippy::match_str_case_mismatch)]` help: consider changing the case of this arm to respect `to_ascii_lowercase` | -LL | "bar" => {}, - | ~~~~~ +LL - "Bar" => {}, +LL + "bar" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:122:9 @@ -19,8 +20,9 @@ LL | "~!@#$%^&*()-_=+Foo" => {}, | help: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization difference) | -LL | "~!@#$%^&*()-_=+foo" => {}, - | ~~~~~~~~~~~~~~~~~~~~ +LL - "~!@#$%^&*()-_=+Foo" => {}, +LL + "~!@#$%^&*()-_=+foo" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:134:9 @@ -30,8 +32,9 @@ LL | "Воды" => {}, | help: consider changing the case of this arm to respect `to_lowercase` | -LL | "воды" => {}, - | ~~~~~~ +LL - "Воды" => {}, +LL + "воды" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:145:9 @@ -41,8 +44,9 @@ LL | "barDz" => {}, | help: consider changing the case of this arm to respect `to_lowercase` | -LL | "bardz" => {}, - | ~~~~~~ +LL - "barDz" => {}, +LL + "bardz" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:155:9 @@ -52,8 +56,9 @@ LL | "bARʁ" => {}, | help: consider changing the case of this arm to respect `to_uppercase` | -LL | "BARʁ" => {}, - | ~~~~~~ +LL - "bARʁ" => {}, +LL + "BARʁ" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:165:9 @@ -63,8 +68,9 @@ LL | "Bar" => {}, | help: consider changing the case of this arm to respect `to_ascii_lowercase` | -LL | "bar" => {}, - | ~~~~~ +LL - "Bar" => {}, +LL + "bar" => {}, + | error: this `match` arm has a differing case than its expression --> tests/ui/match_str_case_mismatch.rs:180:9 @@ -74,8 +80,9 @@ LL | "bAR" => {}, | help: consider changing the case of this arm to respect `to_ascii_uppercase` | -LL | "BAR" => {}, - | ~~~~~ +LL - "bAR" => {}, +LL + "BAR" => {}, + | error: aborting due to 7 previous errors diff --git a/tests/ui/needless_borrow_pat.stderr b/tests/ui/needless_borrow_pat.stderr index 2ad694490396..035376cabaf4 100644 --- a/tests/ui/needless_borrow_pat.stderr +++ b/tests/ui/needless_borrow_pat.stderr @@ -15,8 +15,9 @@ LL | Some(ref x) => *x, | help: try | -LL | Some(x) => x, - | ~ ~ +LL - Some(ref x) => *x, +LL + Some(x) => x, + | error: this pattern creates a reference to a reference --> tests/ui/needless_borrow_pat.rs:74:14 @@ -71,8 +72,9 @@ LL | E::A(ref x) | E::B(ref x) => *x, | help: try | -LL | E::A(x) | E::B(x) => x, - | ~ ~ ~ +LL - E::A(ref x) | E::B(ref x) => *x, +LL + E::A(x) | E::B(x) => x, + | error: this pattern creates a reference to a reference --> tests/ui/needless_borrow_pat.rs:126:21 diff --git a/tests/ui/needless_for_each_unfixable.stderr b/tests/ui/needless_for_each_unfixable.stderr index 682140a1dfda..722016b12125 100644 --- a/tests/ui/needless_for_each_unfixable.stderr +++ b/tests/ui/needless_for_each_unfixable.stderr @@ -25,8 +25,9 @@ LL + } | help: ...and replace `return` with `continue` | -LL | continue; - | ~~~~~~~~ +LL - return; +LL + continue; + | error: aborting due to 1 previous error diff --git a/tests/ui/needless_pass_by_value.stderr b/tests/ui/needless_pass_by_value.stderr index 2587d3f8c52f..2c90da51252a 100644 --- a/tests/ui/needless_pass_by_value.stderr +++ b/tests/ui/needless_pass_by_value.stderr @@ -63,12 +63,14 @@ LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | help: consider changing the type to | -LL | fn issue_2114(s: String, t: &str, u: Vec, v: Vec) { - | ~~~~ +LL - fn issue_2114(s: String, t: String, u: Vec, v: Vec) { +LL + fn issue_2114(s: String, t: &str, u: Vec, v: Vec) { + | help: change `t.clone()` to | -LL | let _ = t.to_string(); - | ~~~~~~~~~~~~~ +LL - let _ = t.clone(); +LL + let _ = t.to_string(); + | error: this argument is passed by value, but not consumed in the function body --> tests/ui/needless_pass_by_value.rs:91:40 @@ -84,12 +86,14 @@ LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | help: consider changing the type to | -LL | fn issue_2114(s: String, t: String, u: Vec, v: &[i32]) { - | ~~~~~~ +LL - fn issue_2114(s: String, t: String, u: Vec, v: Vec) { +LL + fn issue_2114(s: String, t: String, u: Vec, v: &[i32]) { + | help: change `v.clone()` to | -LL | let _ = v.to_owned(); - | ~~~~~~~~~~~~ +LL - let _ = v.clone(); +LL + let _ = v.to_owned(); + | error: this argument is passed by value, but not consumed in the function body --> tests/ui/needless_pass_by_value.rs:108:12 diff --git a/tests/ui/needless_range_loop.stderr b/tests/ui/needless_range_loop.stderr index 503d796e5e8d..831b8511e434 100644 --- a/tests/ui/needless_range_loop.stderr +++ b/tests/ui/needless_range_loop.stderr @@ -8,8 +8,9 @@ LL | for i in 0..vec.len() { = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]` help: consider using an iterator | -LL | for in &vec { - | ~~~~~~ ~~~~ +LL - for i in 0..vec.len() { +LL + for in &vec { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:27:14 @@ -19,8 +20,9 @@ LL | for i in 0..vec.len() { | help: consider using an iterator | -LL | for in &vec { - | ~~~~~~ ~~~~ +LL - for i in 0..vec.len() { +LL + for in &vec { + | error: the loop variable `j` is only used to index `STATIC` --> tests/ui/needless_range_loop.rs:33:14 @@ -30,8 +32,9 @@ LL | for j in 0..4 { | help: consider using an iterator | -LL | for in &STATIC { - | ~~~~~~ ~~~~~~~ +LL - for j in 0..4 { +LL + for in &STATIC { + | error: the loop variable `j` is only used to index `CONST` --> tests/ui/needless_range_loop.rs:38:14 @@ -41,8 +44,9 @@ LL | for j in 0..4 { | help: consider using an iterator | -LL | for in &CONST { - | ~~~~~~ ~~~~~~ +LL - for j in 0..4 { +LL + for in &CONST { + | error: the loop variable `i` is used to index `vec` --> tests/ui/needless_range_loop.rs:43:14 @@ -52,8 +56,9 @@ LL | for i in 0..vec.len() { | help: consider using an iterator and enumerate() | -LL | for (i, ) in vec.iter().enumerate() { - | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..vec.len() { +LL + for (i, ) in vec.iter().enumerate() { + | error: the loop variable `i` is only used to index `vec2` --> tests/ui/needless_range_loop.rs:52:14 @@ -63,8 +68,9 @@ LL | for i in 0..vec.len() { | help: consider using an iterator | -LL | for in vec2.iter().take(vec.len()) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..vec.len() { +LL + for in vec2.iter().take(vec.len()) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:57:14 @@ -74,8 +80,9 @@ LL | for i in 5..vec.len() { | help: consider using an iterator | -LL | for in vec.iter().skip(5) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - for i in 5..vec.len() { +LL + for in vec.iter().skip(5) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:62:14 @@ -85,8 +92,9 @@ LL | for i in 0..MAX_LEN { | help: consider using an iterator | -LL | for in vec.iter().take(MAX_LEN) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..MAX_LEN { +LL + for in vec.iter().take(MAX_LEN) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:67:14 @@ -96,8 +104,9 @@ LL | for i in 0..=MAX_LEN { | help: consider using an iterator | -LL | for in vec.iter().take(MAX_LEN + 1) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..=MAX_LEN { +LL + for in vec.iter().take(MAX_LEN + 1) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:72:14 @@ -107,8 +116,9 @@ LL | for i in 5..10 { | help: consider using an iterator | -LL | for in vec.iter().take(10).skip(5) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 5..10 { +LL + for in vec.iter().take(10).skip(5) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop.rs:77:14 @@ -118,8 +128,9 @@ LL | for i in 5..=10 { | help: consider using an iterator | -LL | for in vec.iter().take(10 + 1).skip(5) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 5..=10 { +LL + for in vec.iter().take(10 + 1).skip(5) { + | error: the loop variable `i` is used to index `vec` --> tests/ui/needless_range_loop.rs:82:14 @@ -129,8 +140,9 @@ LL | for i in 5..vec.len() { | help: consider using an iterator and enumerate() | -LL | for (i, ) in vec.iter().enumerate().skip(5) { - | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 5..vec.len() { +LL + for (i, ) in vec.iter().enumerate().skip(5) { + | error: the loop variable `i` is used to index `vec` --> tests/ui/needless_range_loop.rs:87:14 @@ -140,8 +152,9 @@ LL | for i in 5..10 { | help: consider using an iterator and enumerate() | -LL | for (i, ) in vec.iter().enumerate().take(10).skip(5) { - | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 5..10 { +LL + for (i, ) in vec.iter().enumerate().take(10).skip(5) { + | error: the loop variable `i` is used to index `vec` --> tests/ui/needless_range_loop.rs:93:14 @@ -151,8 +164,9 @@ LL | for i in 0..vec.len() { | help: consider using an iterator and enumerate() | -LL | for (i, ) in vec.iter_mut().enumerate() { - | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 0..vec.len() { +LL + for (i, ) in vec.iter_mut().enumerate() { + | error: aborting due to 14 previous errors diff --git a/tests/ui/needless_range_loop2.stderr b/tests/ui/needless_range_loop2.stderr index 353f30b1b26d..f37e1f2872d0 100644 --- a/tests/ui/needless_range_loop2.stderr +++ b/tests/ui/needless_range_loop2.stderr @@ -8,8 +8,9 @@ LL | for i in 3..10 { = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]` help: consider using an iterator | -LL | for in ns.iter().take(10).skip(3) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in 3..10 { +LL + for in ns.iter().take(10).skip(3) { + | error: the loop variable `i` is only used to index `ms` --> tests/ui/needless_range_loop2.rs:34:14 @@ -19,8 +20,9 @@ LL | for i in 0..ms.len() { | help: consider using an iterator | -LL | for in &mut ms { - | ~~~~~~ ~~~~~~~ +LL - for i in 0..ms.len() { +LL + for in &mut ms { + | error: the loop variable `i` is only used to index `ms` --> tests/ui/needless_range_loop2.rs:41:14 @@ -30,8 +32,9 @@ LL | for i in 0..ms.len() { | help: consider using an iterator | -LL | for in &mut ms { - | ~~~~~~ ~~~~~~~ +LL - for i in 0..ms.len() { +LL + for in &mut ms { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop2.rs:66:14 @@ -41,8 +44,9 @@ LL | for i in x..x + 4 { | help: consider using an iterator | -LL | for in vec.iter_mut().skip(x).take(4) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in x..x + 4 { +LL + for in vec.iter_mut().skip(x).take(4) { + | error: the loop variable `i` is only used to index `vec` --> tests/ui/needless_range_loop2.rs:74:14 @@ -52,8 +56,9 @@ LL | for i in x..=x + 4 { | help: consider using an iterator | -LL | for in vec.iter_mut().skip(x).take(4 + 1) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in x..=x + 4 { +LL + for in vec.iter_mut().skip(x).take(4 + 1) { + | error: the loop variable `i` is only used to index `arr` --> tests/ui/needless_range_loop2.rs:81:14 @@ -63,8 +68,9 @@ LL | for i in 0..3 { | help: consider using an iterator | -LL | for in &arr { - | ~~~~~~ ~~~~ +LL - for i in 0..3 { +LL + for in &arr { + | error: the loop variable `i` is only used to index `arr` --> tests/ui/needless_range_loop2.rs:86:14 @@ -74,8 +80,9 @@ LL | for i in 0..2 { | help: consider using an iterator | -LL | for in arr.iter().take(2) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - for i in 0..2 { +LL + for in arr.iter().take(2) { + | error: the loop variable `i` is only used to index `arr` --> tests/ui/needless_range_loop2.rs:91:14 @@ -85,8 +92,9 @@ LL | for i in 1..3 { | help: consider using an iterator | -LL | for in arr.iter().skip(1) { - | ~~~~~~ ~~~~~~~~~~~~~~~~~~ +LL - for i in 1..3 { +LL + for in arr.iter().skip(1) { + | error: aborting due to 8 previous errors diff --git a/tests/ui/needless_return.stderr b/tests/ui/needless_return.stderr index d3c2a6badc0f..8d8b5b9e713d 100644 --- a/tests/ui/needless_return.stderr +++ b/tests/ui/needless_return.stderr @@ -80,8 +80,9 @@ LL | true => return false, | help: remove `return` | -LL | true => false, - | ~~~~~ +LL - true => return false, +LL + true => false, + | error: unneeded `return` statement --> tests/ui/needless_return.rs:58:13 @@ -115,8 +116,9 @@ LL | let _ = || return true; | help: remove `return` | -LL | let _ = || true; - | ~~~~ +LL - let _ = || return true; +LL + let _ = || true; + | error: unneeded `return` statement --> tests/ui/needless_return.rs:71:5 @@ -183,8 +185,9 @@ LL | _ => return, | help: replace `return` with a unit value | -LL | _ => (), - | ~~ +LL - _ => return, +LL + _ => (), + | error: unneeded `return` statement --> tests/ui/needless_return.rs:97:24 @@ -209,8 +212,9 @@ LL | _ => return, | help: replace `return` with a unit value | -LL | _ => (), - | ~~ +LL - _ => return, +LL + _ => (), + | error: unneeded `return` statement --> tests/ui/needless_return.rs:113:9 @@ -244,8 +248,9 @@ LL | bar.unwrap_or_else(|_| return) | help: replace `return` with an empty block | -LL | bar.unwrap_or_else(|_| {}) - | ~~ +LL - bar.unwrap_or_else(|_| return) +LL + bar.unwrap_or_else(|_| {}) + | error: unneeded `return` statement --> tests/ui/needless_return.rs:141:21 @@ -270,8 +275,9 @@ LL | let _ = || return; | help: replace `return` with an empty block | -LL | let _ = || {}; - | ~~ +LL - let _ = || return; +LL + let _ = || {}; + | error: unneeded `return` statement --> tests/ui/needless_return.rs:150:32 @@ -281,8 +287,9 @@ LL | res.unwrap_or_else(|_| return Foo) | help: remove `return` | -LL | res.unwrap_or_else(|_| Foo) - | ~~~ +LL - res.unwrap_or_else(|_| return Foo) +LL + res.unwrap_or_else(|_| Foo) + | error: unneeded `return` statement --> tests/ui/needless_return.rs:159:5 @@ -340,8 +347,9 @@ LL | true => return false, | help: remove `return` | -LL | true => false, - | ~~~~~ +LL - true => return false, +LL + true => false, + | error: unneeded `return` statement --> tests/ui/needless_return.rs:178:13 @@ -375,8 +383,9 @@ LL | let _ = || return true; | help: remove `return` | -LL | let _ = || true; - | ~~~~ +LL - let _ = || return true; +LL + let _ = || true; + | error: unneeded `return` statement --> tests/ui/needless_return.rs:191:5 @@ -443,8 +452,9 @@ LL | _ => return, | help: replace `return` with a unit value | -LL | _ => (), - | ~~ +LL - _ => return, +LL + _ => (), + | error: unneeded `return` statement --> tests/ui/needless_return.rs:222:9 diff --git a/tests/ui/never_loop.stderr b/tests/ui/never_loop.stderr index dab3488af106..203e33258225 100644 --- a/tests/ui/never_loop.stderr +++ b/tests/ui/never_loop.stderr @@ -77,8 +77,9 @@ LL | | } | help: if you need the first element of the iterator, try writing | -LL | if let Some(x) = (0..10).next() { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for x in 0..10 { +LL + if let Some(x) = (0..10).next() { + | error: this loop never actually loops --> tests/ui/never_loop.rs:167:5 @@ -145,8 +146,9 @@ LL | | } | help: if you need the first element of the iterator, try writing | -LL | if let Some(_) = (0..20).next() { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for _ in 0..20 { +LL + if let Some(_) = (0..20).next() { + | error: this loop never actually loops --> tests/ui/never_loop.rs:378:13 diff --git a/tests/ui/non_canonical_partial_ord_impl.stderr b/tests/ui/non_canonical_partial_ord_impl.stderr index a15379c5b1a5..9f0c2ec43015 100644 --- a/tests/ui/non_canonical_partial_ord_impl.stderr +++ b/tests/ui/non_canonical_partial_ord_impl.stderr @@ -25,8 +25,9 @@ LL | | } | help: change this to | -LL | fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } - | ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - fn partial_cmp(&self, _: &Self) -> Option { +LL + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } + | error: aborting due to 2 previous errors diff --git a/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr b/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr index f956f4b8d52a..333052ae1c11 100644 --- a/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr +++ b/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr @@ -8,8 +8,9 @@ LL | static LAZY_FOO: Lazy = Lazy::new(|| "foo".to_uppercase()); = help: to override `-D warnings` add `#[allow(clippy::non_std_lazy_statics)]` help: use `std::sync::LazyLock` instead | -LL | static LAZY_FOO: std::sync::LazyLock = std::sync::LazyLock::new(|| "foo".to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static LAZY_FOO: Lazy = Lazy::new(|| "foo".to_uppercase()); +LL + static LAZY_FOO: std::sync::LazyLock = std::sync::LazyLock::new(|| "foo".to_uppercase()); + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:13:18 @@ -19,8 +20,9 @@ LL | static LAZY_BAR: Lazy = Lazy::new(|| { | help: use `std::sync::LazyLock` instead | -LL | static LAZY_BAR: std::sync::LazyLock = std::sync::LazyLock::new(|| { - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static LAZY_BAR: Lazy = Lazy::new(|| { +LL + static LAZY_BAR: std::sync::LazyLock = std::sync::LazyLock::new(|| { + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:18:18 @@ -30,8 +32,9 @@ LL | static LAZY_BAZ: Lazy = { Lazy::new(|| "baz".to_uppercase()) }; | help: use `std::sync::LazyLock` instead | -LL | static LAZY_BAZ: std::sync::LazyLock = { std::sync::LazyLock::new(|| "baz".to_uppercase()) }; - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static LAZY_BAZ: Lazy = { Lazy::new(|| "baz".to_uppercase()) }; +LL + static LAZY_BAZ: std::sync::LazyLock = { std::sync::LazyLock::new(|| "baz".to_uppercase()) }; + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:20:18 diff --git a/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr b/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr index 66dc435f9823..216190ae4ca3 100644 --- a/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr +++ b/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr @@ -37,8 +37,9 @@ LL | static LAZY_FOO: Lazy = Lazy::new(|| "foo".to_uppercase()); | help: use `std::sync::LazyLock` instead | -LL | static LAZY_FOO: std::sync::LazyLock = std::sync::LazyLock::new(|| "foo".to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static LAZY_FOO: Lazy = Lazy::new(|| "foo".to_uppercase()); +LL + static LAZY_FOO: std::sync::LazyLock = std::sync::LazyLock::new(|| "foo".to_uppercase()); + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:13:26 @@ -48,8 +49,9 @@ LL | static mut LAZY_BAR: Lazy = Lazy::new(|| "bar".to_uppercase()); | help: use `std::sync::LazyLock` instead | -LL | static mut LAZY_BAR: std::sync::LazyLock = std::sync::LazyLock::new(|| "bar".to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static mut LAZY_BAR: Lazy = Lazy::new(|| "bar".to_uppercase()); +LL + static mut LAZY_BAR: std::sync::LazyLock = std::sync::LazyLock::new(|| "bar".to_uppercase()); + | error: this type has been superceded by `LazyLock` in the standard library --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:15:26 @@ -59,8 +61,9 @@ LL | static mut LAZY_BAZ: Lazy = Lazy::new(|| "baz".to_uppercase()); | help: use `std::sync::LazyLock` instead | -LL | static mut LAZY_BAZ: std::sync::LazyLock = std::sync::LazyLock::new(|| "baz".to_uppercase()); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - static mut LAZY_BAZ: Lazy = Lazy::new(|| "baz".to_uppercase()); +LL + static mut LAZY_BAZ: std::sync::LazyLock = std::sync::LazyLock::new(|| "baz".to_uppercase()); + | error: aborting due to 6 previous errors diff --git a/tests/ui/nonminimal_bool.stderr b/tests/ui/nonminimal_bool.stderr index 578f918f0139..56d6eb10ac03 100644 --- a/tests/ui/nonminimal_bool.stderr +++ b/tests/ui/nonminimal_bool.stderr @@ -51,10 +51,12 @@ LL | let _ = a == b && c == 5 && a == b; | help: try | -LL | let _ = !(a != b || c != 5); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a == b && c == 5; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a == b && c == 5 && a == b; +LL + let _ = !(a != b || c != 5); + | +LL - let _ = a == b && c == 5 && a == b; +LL + let _ = a == b && c == 5; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:44:13 @@ -64,10 +66,12 @@ LL | let _ = a == b || c == 5 || a == b; | help: try | -LL | let _ = !(a != b && c != 5); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a == b || c == 5; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a == b || c == 5 || a == b; +LL + let _ = !(a != b && c != 5); + | +LL - let _ = a == b || c == 5 || a == b; +LL + let _ = a == b || c == 5; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:46:13 @@ -77,10 +81,12 @@ LL | let _ = a == b && c == 5 && b == a; | help: try | -LL | let _ = !(a != b || c != 5); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a == b && c == 5; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a == b && c == 5 && b == a; +LL + let _ = !(a != b || c != 5); + | +LL - let _ = a == b && c == 5 && b == a; +LL + let _ = a == b && c == 5; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:48:13 @@ -90,10 +96,12 @@ LL | let _ = a != b || !(a != b || c == d); | help: try | -LL | let _ = !(a == b && c == d); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a != b || c != d; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a != b || !(a != b || c == d); +LL + let _ = !(a == b && c == d); + | +LL - let _ = a != b || !(a != b || c == d); +LL + let _ = a != b || c != d; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:50:13 @@ -103,10 +111,12 @@ LL | let _ = a != b && !(a != b && c == d); | help: try | -LL | let _ = !(a == b || c == d); - | ~~~~~~~~~~~~~~~~~~~ -LL | let _ = a != b && c != d; - | ~~~~~~~~~~~~~~~~ +LL - let _ = a != b && !(a != b && c == d); +LL + let _ = !(a == b || c == d); + | +LL - let _ = a != b && !(a != b && c == d); +LL + let _ = a != b && c != d; + | error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:81:8 diff --git a/tests/ui/octal_escapes.stderr b/tests/ui/octal_escapes.stderr index 9343ba64a30b..c8a89ac8bea4 100644 --- a/tests/ui/octal_escapes.stderr +++ b/tests/ui/octal_escapes.stderr @@ -9,12 +9,14 @@ LL | let _bad1 = "\033[0m"; = help: to override `-D warnings` add `#[allow(clippy::octal_escapes)]` help: if an octal escape is intended, use a hex escape instead | -LL | let _bad1 = "\x1b[0m"; - | ~~~~ +LL - let _bad1 = "\033[0m"; +LL + let _bad1 = "\x1b[0m"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad1 = "\x0033[0m"; - | ~~~~~~ +LL - let _bad1 = "\033[0m"; +LL + let _bad1 = "\x0033[0m"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:6:19 @@ -24,12 +26,14 @@ LL | let _bad2 = b"\033[0m"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad2 = b"\x1b[0m"; - | ~~~~ +LL - let _bad2 = b"\033[0m"; +LL + let _bad2 = b"\x1b[0m"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad2 = b"\x0033[0m"; - | ~~~~~~ +LL - let _bad2 = b"\033[0m"; +LL + let _bad2 = b"\x0033[0m"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:7:20 @@ -39,12 +43,14 @@ LL | let _bad3 = "\\\033[0m"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad3 = "\\\x1b[0m"; - | ~~~~ +LL - let _bad3 = "\\\033[0m"; +LL + let _bad3 = "\\\x1b[0m"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad3 = "\\\x0033[0m"; - | ~~~~~~ +LL - let _bad3 = "\\\033[0m"; +LL + let _bad3 = "\\\x0033[0m"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:9:18 @@ -54,12 +60,14 @@ LL | let _bad4 = "\01234567"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad4 = "\x0a34567"; - | ~~~~ +LL - let _bad4 = "\01234567"; +LL + let _bad4 = "\x0a34567"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad4 = "\x001234567"; - | ~~~~~~ +LL - let _bad4 = "\01234567"; +LL + let _bad4 = "\x001234567"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:10:20 @@ -69,12 +77,14 @@ LL | let _bad5 = "\0\03"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad5 = "\0\x03"; - | ~~~~ +LL - let _bad5 = "\0\03"; +LL + let _bad5 = "\0\x03"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad5 = "\0\x0003"; - | ~~~~~~ +LL - let _bad5 = "\0\03"; +LL + let _bad5 = "\0\x0003"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:23 @@ -84,12 +94,14 @@ LL | let _bad6 = "Text-\055\077-MoreText"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad6 = "Text-\x2d\077-MoreText"; - | ~~~~ +LL - let _bad6 = "Text-\055\077-MoreText"; +LL + let _bad6 = "Text-\x2d\077-MoreText"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad6 = "Text-\x0055\077-MoreText"; - | ~~~~~~ +LL - let _bad6 = "Text-\055\077-MoreText"; +LL + let _bad6 = "Text-\x0055\077-MoreText"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:27 @@ -99,12 +111,14 @@ LL | let _bad6 = "Text-\055\077-MoreText"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad6 = "Text-\055\x3f-MoreText"; - | ~~~~ +LL - let _bad6 = "Text-\055\077-MoreText"; +LL + let _bad6 = "Text-\055\x3f-MoreText"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad6 = "Text-\055\x0077-MoreText"; - | ~~~~~~ +LL - let _bad6 = "Text-\055\077-MoreText"; +LL + let _bad6 = "Text-\055\x0077-MoreText"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:31 @@ -114,12 +128,14 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; - | ~~~~ +LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; +LL + let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; - | ~~~~~~ +LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; +LL + let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:34 @@ -129,12 +145,14 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; - | ~~~~ +LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; +LL + let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; - | ~~~~~~ +LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; +LL + let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:17:19 @@ -144,12 +162,14 @@ LL | let _bad8 = "锈\01锈"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad8 = "锈\x01锈"; - | ~~~~ +LL - let _bad8 = "锈\01锈"; +LL + let _bad8 = "锈\x01锈"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad8 = "锈\x0001锈"; - | ~~~~~~ +LL - let _bad8 = "锈\01锈"; +LL + let _bad8 = "锈\x0001锈"; + | error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:18:19 @@ -159,12 +179,14 @@ LL | let _bad9 = "锈\011锈"; | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad9 = "锈\x09锈"; - | ~~~~ +LL - let _bad9 = "锈\011锈"; +LL + let _bad9 = "锈\x09锈"; + | help: if a null escape is intended, disambiguate using | -LL | let _bad9 = "锈\x0011锈"; - | ~~~~~~ +LL - let _bad9 = "锈\011锈"; +LL + let _bad9 = "锈\x0011锈"; + | error: aborting due to 11 previous errors diff --git a/tests/ui/op_ref.stderr b/tests/ui/op_ref.stderr index c5b68730a8f2..ad002437c0c6 100644 --- a/tests/ui/op_ref.stderr +++ b/tests/ui/op_ref.stderr @@ -8,8 +8,9 @@ LL | let foo = &5 - &6; = help: to override `-D warnings` add `#[allow(clippy::op_ref)]` help: use the values directly | -LL | let foo = 5 - 6; - | ~ ~ +LL - let foo = &5 - &6; +LL + let foo = 5 - 6; + | error: taken reference of right operand --> tests/ui/op_ref.rs:58:13 diff --git a/tests/ui/option_as_ref_cloned.stderr b/tests/ui/option_as_ref_cloned.stderr index 5892f2bdec56..0eda42b91b96 100644 --- a/tests/ui/option_as_ref_cloned.stderr +++ b/tests/ui/option_as_ref_cloned.stderr @@ -8,8 +8,9 @@ LL | let _: Option = x.as_ref().cloned(); = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_cloned)]` help: this can be written more concisely by cloning the `Option<_>` directly | -LL | let _: Option = x.clone(); - | ~~~~~ +LL - let _: Option = x.as_ref().cloned(); +LL + let _: Option = x.clone(); + | error: cloning an `Option<_>` using `.as_mut().cloned()` --> tests/ui/option_as_ref_cloned.rs:8:31 @@ -19,8 +20,9 @@ LL | let _: Option = x.as_mut().cloned(); | help: this can be written more concisely by cloning the `Option<_>` directly | -LL | let _: Option = x.clone(); - | ~~~~~ +LL - let _: Option = x.as_mut().cloned(); +LL + let _: Option = x.clone(); + | error: cloning an `Option<_>` using `.as_ref().cloned()` --> tests/ui/option_as_ref_cloned.rs:11:32 @@ -30,8 +32,9 @@ LL | let _: Option<&String> = y.as_ref().cloned(); | help: this can be written more concisely by cloning the `Option<_>` directly | -LL | let _: Option<&String> = y.clone(); - | ~~~~~ +LL - let _: Option<&String> = y.as_ref().cloned(); +LL + let _: Option<&String> = y.clone(); + | error: aborting due to 3 previous errors diff --git a/tests/ui/redundant_guards.stderr b/tests/ui/redundant_guards.stderr index 7512546450b2..a10cd5c2f481 100644 --- a/tests/ui/redundant_guards.stderr +++ b/tests/ui/redundant_guards.stderr @@ -44,8 +44,9 @@ LL | Some(x) if matches!(x, Some(1) if true) => .., | help: try | -LL | Some(Some(1)) if true => .., - | ~~~~~~~ ~~~~~~~ +LL - Some(x) if matches!(x, Some(1) if true) => .., +LL + Some(Some(1)) if true => .., + | error: redundant guard --> tests/ui/redundant_guards.rs:50:20 diff --git a/tests/ui/ref_binding_to_reference.stderr b/tests/ui/ref_binding_to_reference.stderr index 25ab98223827..233416351a0a 100644 --- a/tests/ui/ref_binding_to_reference.stderr +++ b/tests/ui/ref_binding_to_reference.stderr @@ -8,8 +8,9 @@ LL | Some(ref x) => x, = help: to override `-D warnings` add `#[allow(clippy::ref_binding_to_reference)]` help: try | -LL | Some(x) => &x, - | ~ ~~ +LL - Some(ref x) => x, +LL + Some(x) => &x, + | error: this pattern creates a reference to a reference --> tests/ui/ref_binding_to_reference.rs:38:14 @@ -34,8 +35,9 @@ LL | Some(ref x) => m2!(x), | help: try | -LL | Some(x) => m2!(&x), - | ~ ~~ +LL - Some(ref x) => m2!(x), +LL + Some(x) => m2!(&x), + | error: this pattern creates a reference to a reference --> tests/ui/ref_binding_to_reference.rs:55:15 diff --git a/tests/ui/ref_option/ref_option.all.stderr b/tests/ui/ref_option/ref_option.all.stderr index b4c69ac62962..fd30628bdd81 100644 --- a/tests/ui/ref_option/ref_option.all.stderr +++ b/tests/ui/ref_option/ref_option.all.stderr @@ -55,8 +55,9 @@ LL | fn mult_string(a: &Option, b: &Option>) {} | help: change this to | -LL | fn mult_string(a: Option<&String>, b: Option<&Vec>) {} - | ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - fn mult_string(a: &Option, b: &Option>) {} +LL + fn mult_string(a: Option<&String>, b: Option<&Vec>) {} + | error: it is more idiomatic to use `Option<&T>` instead of `&Option` --> tests/ui/ref_option/ref_option.rs:18:1 @@ -85,8 +86,9 @@ LL | pub fn pub_mult_string(a: &Option, b: &Option>) {} | help: change this to | -LL | pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec>) {} - | ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - pub fn pub_mult_string(a: &Option, b: &Option>) {} +LL + pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec>) {} + | error: it is more idiomatic to use `Option<&T>` instead of `&Option` --> tests/ui/ref_option/ref_option.rs:26:5 diff --git a/tests/ui/ref_option/ref_option.private.stderr b/tests/ui/ref_option/ref_option.private.stderr index 17c90536da34..d3428f1891f3 100644 --- a/tests/ui/ref_option/ref_option.private.stderr +++ b/tests/ui/ref_option/ref_option.private.stderr @@ -55,8 +55,9 @@ LL | fn mult_string(a: &Option, b: &Option>) {} | help: change this to | -LL | fn mult_string(a: Option<&String>, b: Option<&Vec>) {} - | ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - fn mult_string(a: &Option, b: &Option>) {} +LL + fn mult_string(a: Option<&String>, b: Option<&Vec>) {} + | error: it is more idiomatic to use `Option<&T>` instead of `&Option` --> tests/ui/ref_option/ref_option.rs:18:1 diff --git a/tests/ui/repeat_vec_with_capacity.stderr b/tests/ui/repeat_vec_with_capacity.stderr index 43027c9cb892..05513a8859a4 100644 --- a/tests/ui/repeat_vec_with_capacity.stderr +++ b/tests/ui/repeat_vec_with_capacity.stderr @@ -9,8 +9,9 @@ LL | vec![Vec::<()>::with_capacity(42); 123]; = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]` help: if you intended to initialize multiple `Vec`s with an initial capacity, try | -LL | (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![Vec::<()>::with_capacity(42); 123]; +LL + (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::>(); + | error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity --> tests/ui/repeat_vec_with_capacity.rs:12:9 @@ -21,8 +22,9 @@ LL | vec![Vec::<()>::with_capacity(42); n]; = note: only the last `Vec` will have the capacity help: if you intended to initialize multiple `Vec`s with an initial capacity, try | -LL | (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![Vec::<()>::with_capacity(42); n]; +LL + (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::>(); + | error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity --> tests/ui/repeat_vec_with_capacity.rs:27:9 @@ -33,8 +35,9 @@ LL | std::iter::repeat(Vec::<()>::with_capacity(42)); = note: none of the yielded `Vec`s will have the requested capacity help: if you intended to create an iterator that yields `Vec`s with an initial capacity, try | -LL | std::iter::repeat_with(|| Vec::<()>::with_capacity(42)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - std::iter::repeat(Vec::<()>::with_capacity(42)); +LL + std::iter::repeat_with(|| Vec::<()>::with_capacity(42)); + | error: aborting due to 3 previous errors diff --git a/tests/ui/repeat_vec_with_capacity_nostd.stderr b/tests/ui/repeat_vec_with_capacity_nostd.stderr index 39364d09b961..092167485ced 100644 --- a/tests/ui/repeat_vec_with_capacity_nostd.stderr +++ b/tests/ui/repeat_vec_with_capacity_nostd.stderr @@ -9,8 +9,9 @@ LL | let _: Vec> = iter::repeat(Vec::with_capacity(42)).take(123).co = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]` help: if you intended to create an iterator that yields `Vec`s with an initial capacity, try | -LL | let _: Vec> = core::iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Vec> = iter::repeat(Vec::with_capacity(42)).take(123).collect(); +LL + let _: Vec> = core::iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect(); + | error: aborting due to 1 previous error diff --git a/tests/ui/reversed_empty_ranges_fixable.stderr b/tests/ui/reversed_empty_ranges_fixable.stderr index 3747eb9deebc..24cb959c96af 100644 --- a/tests/ui/reversed_empty_ranges_fixable.stderr +++ b/tests/ui/reversed_empty_ranges_fixable.stderr @@ -8,8 +8,9 @@ LL | (42..=21).for_each(|x| println!("{}", x)); = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]` help: consider using the following if you are attempting to iterate over this range in reverse | -LL | (21..=42).rev().for_each(|x| println!("{}", x)); - | ~~~~~~~~~~~~~~~ +LL - (42..=21).for_each(|x| println!("{}", x)); +LL + (21..=42).rev().for_each(|x| println!("{}", x)); + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_fixable.rs:10:13 @@ -19,8 +20,9 @@ LL | let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::>( | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | let _ = (21..ANSWER).rev().filter(|x| x % 2 == 0).take(10).collect::>(); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::>(); +LL + let _ = (21..ANSWER).rev().filter(|x| x % 2 == 0).take(10).collect::>(); + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_fixable.rs:12:14 @@ -30,8 +32,9 @@ LL | for _ in -21..=-42 {} | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for _ in (-42..=-21).rev() {} - | ~~~~~~~~~~~~~~~~~ +LL - for _ in -21..=-42 {} +LL + for _ in (-42..=-21).rev() {} + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_fixable.rs:13:14 @@ -41,8 +44,9 @@ LL | for _ in 42u32..21u32 {} | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for _ in (21u32..42u32).rev() {} - | ~~~~~~~~~~~~~~~~~~~~ +LL - for _ in 42u32..21u32 {} +LL + for _ in (21u32..42u32).rev() {} + | error: aborting due to 4 previous errors diff --git a/tests/ui/reversed_empty_ranges_loops_fixable.stderr b/tests/ui/reversed_empty_ranges_loops_fixable.stderr index d5df34c42f4f..3e9ccb653fe7 100644 --- a/tests/ui/reversed_empty_ranges_loops_fixable.stderr +++ b/tests/ui/reversed_empty_ranges_loops_fixable.stderr @@ -8,8 +8,9 @@ LL | for i in 10..0 { = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]` help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (0..10).rev() { - | ~~~~~~~~~~~~~ +LL - for i in 10..0 { +LL + for i in (0..10).rev() { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:11:14 @@ -19,8 +20,9 @@ LL | for i in 10..=0 { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (0..=10).rev() { - | ~~~~~~~~~~~~~~ +LL - for i in 10..=0 { +LL + for i in (0..=10).rev() { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:15:14 @@ -30,8 +32,9 @@ LL | for i in MAX_LEN..0 { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (0..MAX_LEN).rev() { - | ~~~~~~~~~~~~~~~~~~ +LL - for i in MAX_LEN..0 { +LL + for i in (0..MAX_LEN).rev() { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:34:14 @@ -41,8 +44,9 @@ LL | for i in (10..0).map(|x| x * 2) { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (0..10).rev().map(|x| x * 2) { - | ~~~~~~~~~~~~~ +LL - for i in (10..0).map(|x| x * 2) { +LL + for i in (0..10).rev().map(|x| x * 2) { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:39:14 @@ -52,8 +56,9 @@ LL | for i in 10..5 + 4 { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in (5 + 4..10).rev() { - | ~~~~~~~~~~~~~~~~~ +LL - for i in 10..5 + 4 { +LL + for i in (5 + 4..10).rev() { + | error: this range is empty so it will yield no values --> tests/ui/reversed_empty_ranges_loops_fixable.rs:43:14 @@ -63,8 +68,9 @@ LL | for i in (5 + 2)..(3 - 1) { | help: consider using the following if you are attempting to iterate over this range in reverse | -LL | for i in ((3 - 1)..(5 + 2)).rev() { - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - for i in (5 + 2)..(3 - 1) { +LL + for i in ((3 - 1)..(5 + 2)).rev() { + | error: aborting due to 6 previous errors diff --git a/tests/ui/single_range_in_vec_init.stderr b/tests/ui/single_range_in_vec_init.stderr index 9c125adb51a7..b3bc8dd4aca1 100644 --- a/tests/ui/single_range_in_vec_init.stderr +++ b/tests/ui/single_range_in_vec_init.stderr @@ -8,12 +8,14 @@ LL | [0..200]; = help: to override `-D warnings` add `#[allow(clippy::single_range_in_vec_init)]` help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0..200]; +LL + (0..200).collect::>(); + | help: if you wanted an array of len 200, try | -LL | [0; 200]; - | ~~~~~~ +LL - [0..200]; +LL + [0; 200]; + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:27:5 @@ -23,12 +25,14 @@ LL | vec![0..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0..200]; +LL + (0..200).collect::>(); + | help: if you wanted a `Vec` of len 200, try | -LL | vec![0; 200]; - | ~~~~~~ +LL - vec![0..200]; +LL + vec![0; 200]; + | error: an array of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:28:5 @@ -38,12 +42,14 @@ LL | [0u8..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0u8..200).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0u8..200]; +LL + (0u8..200).collect::>(); + | help: if you wanted an array of len 200, try | -LL | [0u8; 200]; - | ~~~~~~~~ +LL - [0u8..200]; +LL + [0u8; 200]; + | error: an array of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:29:5 @@ -53,12 +59,14 @@ LL | [0usize..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0usize..200).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0usize..200]; +LL + (0usize..200).collect::>(); + | help: if you wanted an array of len 200, try | -LL | [0usize; 200]; - | ~~~~~~~~~~~ +LL - [0usize..200]; +LL + [0usize; 200]; + | error: an array of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:30:5 @@ -68,12 +76,14 @@ LL | [0..200usize]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200usize).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0..200usize]; +LL + (0..200usize).collect::>(); + | help: if you wanted an array of len 200usize, try | -LL | [0; 200usize]; - | ~~~~~~~~~~~ +LL - [0..200usize]; +LL + [0; 200usize]; + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:31:5 @@ -83,12 +93,14 @@ LL | vec![0u8..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0u8..200).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0u8..200]; +LL + (0u8..200).collect::>(); + | help: if you wanted a `Vec` of len 200, try | -LL | vec![0u8; 200]; - | ~~~~~~~~ +LL - vec![0u8..200]; +LL + vec![0u8; 200]; + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:32:5 @@ -98,12 +110,14 @@ LL | vec![0usize..200]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0usize..200).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0usize..200]; +LL + (0usize..200).collect::>(); + | help: if you wanted a `Vec` of len 200, try | -LL | vec![0usize; 200]; - | ~~~~~~~~~~~ +LL - vec![0usize..200]; +LL + vec![0usize; 200]; + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:33:5 @@ -113,12 +127,14 @@ LL | vec![0..200usize]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200usize).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0..200usize]; +LL + (0..200usize).collect::>(); + | help: if you wanted a `Vec` of len 200usize, try | -LL | vec![0; 200usize]; - | ~~~~~~~~~~~ +LL - vec![0..200usize]; +LL + vec![0; 200usize]; + | error: an array of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:35:5 @@ -128,8 +144,9 @@ LL | [0..200isize]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200isize).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - [0..200isize]; +LL + (0..200isize).collect::>(); + | error: a `Vec` of `Range` that is only one element --> tests/ui/single_range_in_vec_init.rs:36:5 @@ -139,8 +156,9 @@ LL | vec![0..200isize]; | help: if you wanted a `Vec` that contains the entire range, try | -LL | (0..200isize).collect::>(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - vec![0..200isize]; +LL + (0..200isize).collect::>(); + | error: aborting due to 10 previous errors diff --git a/tests/ui/string_lit_chars_any.stderr b/tests/ui/string_lit_chars_any.stderr index 4d3ca98e6237..1e28ae7b163e 100644 --- a/tests/ui/string_lit_chars_any.stderr +++ b/tests/ui/string_lit_chars_any.stderr @@ -8,8 +8,9 @@ LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == c); = help: to override `-D warnings` add `#[allow(clippy::string_lit_chars_any)]` help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == c); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: usage of `.chars().any(...)` to check if a char matches any from a string literal --> tests/ui/string_lit_chars_any.rs:19:5 @@ -19,8 +20,9 @@ LL | r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c); | help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: usage of `.chars().any(...)` to check if a char matches any from a string literal --> tests/ui/string_lit_chars_any.rs:20:5 @@ -30,8 +32,9 @@ LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| c == x); | help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "\\.+*?()|[]{}^$#&-~".chars().any(|x| c == x); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: usage of `.chars().any(...)` to check if a char matches any from a string literal --> tests/ui/string_lit_chars_any.rs:21:5 @@ -41,8 +44,9 @@ LL | r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x); | help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: usage of `.chars().any(...)` to check if a char matches any from a string literal --> tests/ui/string_lit_chars_any.rs:23:5 @@ -52,8 +56,9 @@ LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| { x == c }); | help: use `matches!(...)` instead | -LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - "\\.+*?()|[]{}^$#&-~".chars().any(|x| { x == c }); +LL + matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + | error: aborting due to 5 previous errors diff --git a/tests/ui/suspicious_command_arg_space.stderr b/tests/ui/suspicious_command_arg_space.stderr index 6fd07d07d7be..8952a3ffe4b8 100644 --- a/tests/ui/suspicious_command_arg_space.stderr +++ b/tests/ui/suspicious_command_arg_space.stderr @@ -8,8 +8,9 @@ LL | std::process::Command::new("echo").arg("-n hello").spawn().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_command_arg_space)]` help: consider splitting the argument | -LL | std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); - | ~~~~ ~~~~~~~~~~~~~~~ +LL - std::process::Command::new("echo").arg("-n hello").spawn().unwrap(); +LL + std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); + | error: single argument that looks like it should be multiple arguments --> tests/ui/suspicious_command_arg_space.rs:7:43 @@ -19,8 +20,9 @@ LL | std::process::Command::new("cat").arg("--number file").spawn().unwrap() | help: consider splitting the argument | -LL | std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap(); - | ~~~~ ~~~~~~~~~~~~~~~~~~~~ +LL - std::process::Command::new("cat").arg("--number file").spawn().unwrap(); +LL + std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap(); + | error: aborting due to 2 previous errors diff --git a/tests/ui/suspicious_doc_comments.stderr b/tests/ui/suspicious_doc_comments.stderr index c34e39cd0fcb..7e5933df2376 100644 --- a/tests/ui/suspicious_doc_comments.stderr +++ b/tests/ui/suspicious_doc_comments.stderr @@ -8,7 +8,8 @@ LL | ///! Fake module documentation. = help: to override `-D warnings` add `#[allow(clippy::suspicious_doc_comments)]` help: use an inner doc comment to document the parent module or crate | -LL | //! Fake module documentation. +LL - ///! Fake module documentation. +LL + //! Fake module documentation. | error: this is an outer doc comment and does not apply to the parent module or crate @@ -19,7 +20,8 @@ LL | ///! This module contains useful functions. | help: use an inner doc comment to document the parent module or crate | -LL | //! This module contains useful functions. +LL - ///! This module contains useful functions. +LL + //! This module contains useful functions. | error: this is an outer doc comment and does not apply to the parent module or crate @@ -71,7 +73,8 @@ LL | ///! a | help: use an inner doc comment to document the parent module or crate | -LL | //! a +LL - ///! a +LL + //! a | error: this is an outer doc comment and does not apply to the parent module or crate @@ -97,7 +100,8 @@ LL | ///! Very cool macro | help: use an inner doc comment to document the parent module or crate | -LL | //! Very cool macro +LL - ///! Very cool macro +LL + //! Very cool macro | error: this is an outer doc comment and does not apply to the parent module or crate @@ -108,7 +112,8 @@ LL | ///! Huh. | help: use an inner doc comment to document the parent module or crate | -LL | //! Huh. +LL - ///! Huh. +LL + //! Huh. | error: aborting due to 9 previous errors diff --git a/tests/ui/suspicious_to_owned.stderr b/tests/ui/suspicious_to_owned.stderr index 255f211e6550..74bbcfcca51e 100644 --- a/tests/ui/suspicious_to_owned.stderr +++ b/tests/ui/suspicious_to_owned.stderr @@ -8,12 +8,14 @@ LL | let _ = cow.to_owned(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_to_owned)]` help: depending on intent, either make the Cow an Owned variant | -LL | let _ = cow.into_owned(); - | ~~~~~~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.into_owned(); + | help: or clone the Cow itself | -LL | let _ = cow.clone(); - | ~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.clone(); + | error: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cause the Cow<'_, [char; 3]> contents to become owned --> tests/ui/suspicious_to_owned.rs:29:13 @@ -23,12 +25,14 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL | let _ = cow.into_owned(); - | ~~~~~~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.into_owned(); + | help: or clone the Cow itself | -LL | let _ = cow.clone(); - | ~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.clone(); + | error: this `to_owned` call clones the Cow<'_, Vec> itself and does not cause the Cow<'_, Vec> contents to become owned --> tests/ui/suspicious_to_owned.rs:40:13 @@ -38,12 +42,14 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL | let _ = cow.into_owned(); - | ~~~~~~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.into_owned(); + | help: or clone the Cow itself | -LL | let _ = cow.clone(); - | ~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.clone(); + | error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned --> tests/ui/suspicious_to_owned.rs:51:13 @@ -53,12 +59,14 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL | let _ = cow.into_owned(); - | ~~~~~~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.into_owned(); + | help: or clone the Cow itself | -LL | let _ = cow.clone(); - | ~~~~~~~~~~~ +LL - let _ = cow.to_owned(); +LL + let _ = cow.clone(); + | error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type --> tests/ui/suspicious_to_owned.rs:66:13 diff --git a/tests/ui/suspicious_xor_used_as_pow.stderr b/tests/ui/suspicious_xor_used_as_pow.stderr index 43b03676b1db..2a153169bd34 100644 --- a/tests/ui/suspicious_xor_used_as_pow.stderr +++ b/tests/ui/suspicious_xor_used_as_pow.stderr @@ -8,8 +8,9 @@ LL | let _ = 2 ^ 5; = help: to override `-D warnings` add `#[allow(clippy::suspicious_xor_used_as_pow)]` help: did you mean to write | -LL | let _ = 2.pow(5); - | ~~~~~~~~ +LL - let _ = 2 ^ 5; +LL + let _ = 2.pow(5); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:22:13 @@ -19,8 +20,9 @@ LL | let _ = 2i32 ^ 9i32; | help: did you mean to write | -LL | let _ = 2i32.pow(9i32); - | ~~~~~~~~~~~~~~ +LL - let _ = 2i32 ^ 9i32; +LL + let _ = 2i32.pow(9i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:24:13 @@ -30,8 +32,9 @@ LL | let _ = 2i32 ^ 2i32; | help: did you mean to write | -LL | let _ = 2i32.pow(2i32); - | ~~~~~~~~~~~~~~ +LL - let _ = 2i32 ^ 2i32; +LL + let _ = 2i32.pow(2i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:26:13 @@ -41,8 +44,9 @@ LL | let _ = 50i32 ^ 3i32; | help: did you mean to write | -LL | let _ = 50i32.pow(3i32); - | ~~~~~~~~~~~~~~~ +LL - let _ = 50i32 ^ 3i32; +LL + let _ = 50i32.pow(3i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:28:13 @@ -52,8 +56,9 @@ LL | let _ = 5i32 ^ 8i32; | help: did you mean to write | -LL | let _ = 5i32.pow(8i32); - | ~~~~~~~~~~~~~~ +LL - let _ = 5i32 ^ 8i32; +LL + let _ = 5i32.pow(8i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:30:13 @@ -63,8 +68,9 @@ LL | let _ = 2i32 ^ 32i32; | help: did you mean to write | -LL | let _ = 2i32.pow(32i32); - | ~~~~~~~~~~~~~~~ +LL - let _ = 2i32 ^ 32i32; +LL + let _ = 2i32.pow(32i32); + | error: `^` is not the exponentiation operator --> tests/ui/suspicious_xor_used_as_pow.rs:13:9 @@ -78,8 +84,9 @@ LL | macro_test_inside!(); = note: this error originates in the macro `macro_test_inside` (in Nightly builds, run with -Z macro-backtrace for more info) help: did you mean to write | -LL | 1.pow(2) // should warn even if inside macro - | ~~~~~~~~ +LL - 1 ^ 2 // should warn even if inside macro +LL + 1.pow(2) // should warn even if inside macro + | error: aborting due to 7 previous errors diff --git a/tests/ui/transmute_ptr_to_ptr.stderr b/tests/ui/transmute_ptr_to_ptr.stderr index 8801eb943ce8..f4f83cd7ac6a 100644 --- a/tests/ui/transmute_ptr_to_ptr.stderr +++ b/tests/ui/transmute_ptr_to_ptr.stderr @@ -8,8 +8,9 @@ LL | let _: *const f32 = transmute(ptr); = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]` help: use `pointer::cast` instead | -LL | let _: *const f32 = ptr.cast::(); - | ~~~~~~~~~~~~~~~~~ +LL - let _: *const f32 = transmute(ptr); +LL + let _: *const f32 = ptr.cast::(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:34:27 @@ -19,8 +20,9 @@ LL | let _: *mut f32 = transmute(mut_ptr); | help: use `pointer::cast` instead | -LL | let _: *mut f32 = mut_ptr.cast::(); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _: *mut f32 = transmute(mut_ptr); +LL + let _: *mut f32 = mut_ptr.cast::(); + | error: transmute from a reference to a reference --> tests/ui/transmute_ptr_to_ptr.rs:37:23 @@ -60,8 +62,9 @@ LL | let _: *const u32 = transmute(mut_ptr); | help: use `pointer::cast_const` instead | -LL | let _: *const u32 = mut_ptr.cast_const(); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _: *const u32 = transmute(mut_ptr); +LL + let _: *const u32 = mut_ptr.cast_const(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:52:27 @@ -71,8 +74,9 @@ LL | let _: *mut u32 = transmute(ptr); | help: use `pointer::cast_mut` instead | -LL | let _: *mut u32 = ptr.cast_mut(); - | ~~~~~~~~~~~~~~ +LL - let _: *mut u32 = transmute(ptr); +LL + let _: *mut u32 = ptr.cast_mut(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:64:14 @@ -82,8 +86,9 @@ LL | unsafe { transmute(v) } | help: use an `as` cast instead | -LL | unsafe { v as *const &() } - | ~~~~~~~~~~~~~~~ +LL - unsafe { transmute(v) } +LL + unsafe { v as *const &() } + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:79:28 @@ -93,8 +98,9 @@ LL | let _: *const i8 = transmute(ptr); | help: use an `as` cast instead | -LL | let _: *const i8 = ptr as *const i8; - | ~~~~~~~~~~~~~~~~ +LL - let _: *const i8 = transmute(ptr); +LL + let _: *const i8 = ptr as *const i8; + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:86:28 @@ -104,8 +110,9 @@ LL | let _: *const i8 = transmute(ptr); | help: use `pointer::cast` instead | -LL | let _: *const i8 = ptr.cast::(); - | ~~~~~~~~~~~~~~~~ +LL - let _: *const i8 = transmute(ptr); +LL + let _: *const i8 = ptr.cast::(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:93:26 @@ -115,8 +122,9 @@ LL | let _: *mut u8 = transmute(ptr); | help: use an `as` cast instead | -LL | let _: *mut u8 = ptr as *mut u8; - | ~~~~~~~~~~~~~~ +LL - let _: *mut u8 = transmute(ptr); +LL + let _: *mut u8 = ptr as *mut u8; + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:94:28 @@ -126,8 +134,9 @@ LL | let _: *const u8 = transmute(mut_ptr); | help: use an `as` cast instead | -LL | let _: *const u8 = mut_ptr as *const u8; - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _: *const u8 = transmute(mut_ptr); +LL + let _: *const u8 = mut_ptr as *const u8; + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:101:26 @@ -137,8 +146,9 @@ LL | let _: *mut u8 = transmute(ptr); | help: use `pointer::cast_mut` instead | -LL | let _: *mut u8 = ptr.cast_mut(); - | ~~~~~~~~~~~~~~ +LL - let _: *mut u8 = transmute(ptr); +LL + let _: *mut u8 = ptr.cast_mut(); + | error: transmute from a pointer to a pointer --> tests/ui/transmute_ptr_to_ptr.rs:102:28 @@ -148,8 +158,9 @@ LL | let _: *const u8 = transmute(mut_ptr); | help: use `pointer::cast_const` instead | -LL | let _: *const u8 = mut_ptr.cast_const(); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _: *const u8 = transmute(mut_ptr); +LL + let _: *const u8 = mut_ptr.cast_const(); + | error: aborting due to 16 previous errors diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.stderr b/tests/ui/transmutes_expressible_as_ptr_casts.stderr index 2d74967ede56..21edd39e7ad6 100644 --- a/tests/ui/transmutes_expressible_as_ptr_casts.stderr +++ b/tests/ui/transmutes_expressible_as_ptr_casts.stderr @@ -17,8 +17,9 @@ LL | let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]` help: use `pointer::cast` instead | -LL | let _ptr_i8_transmute = unsafe { ptr_i32.cast::() }; - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) }; +LL + let _ptr_i8_transmute = unsafe { ptr_i32.cast::() }; + | error: transmute from a pointer to a pointer --> tests/ui/transmutes_expressible_as_ptr_casts.rs:27:46 @@ -28,8 +29,9 @@ LL | let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *con | help: use an `as` cast instead | -LL | let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] }; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) }; +LL + let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] }; + | error: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead --> tests/ui/transmutes_expressible_as_ptr_casts.rs:33:50 diff --git a/tests/ui/unit_arg.stderr b/tests/ui/unit_arg.stderr index 41ad1a2d3834..bf79e93e4440 100644 --- a/tests/ui/unit_arg.stderr +++ b/tests/ui/unit_arg.stderr @@ -10,7 +10,8 @@ LL | | }); = help: to override `-D warnings` add `#[allow(clippy::unit_arg)]` help: remove the semicolon from the last statement in the block | -LL | 1 +LL - 1; +LL + 1 | help: or move the expression in front of the call and replace it with the unit literal `()` | @@ -43,7 +44,8 @@ LL | | }); | help: remove the semicolon from the last statement in the block | -LL | foo(2) +LL - foo(2); +LL + foo(2) | help: or move the expression in front of the call and replace it with the unit literal `()` | @@ -64,7 +66,8 @@ LL | | }); | help: remove the semicolon from the last statement in the block | -LL | 1 +LL - 1; +LL + 1 | help: or move the expression in front of the call and replace it with the unit literal `()` | @@ -98,7 +101,8 @@ LL | | }); | help: remove the semicolon from the last statement in the block | -LL | foo(2) +LL - foo(2); +LL + foo(2) | help: or move the expressions in front of the call and replace them with the unit literal `()` | @@ -124,11 +128,13 @@ LL | | ); | help: remove the semicolon from the last statement in the block | -LL | foo(1) +LL - foo(1); +LL + foo(1) | help: remove the semicolon from the last statement in the block | -LL | foo(3) +LL - foo(3); +LL + foo(3) | help: or move the expressions in front of the call and replace them with the unit literal `()` | diff --git a/tests/ui/unknown_clippy_lints.stderr b/tests/ui/unknown_clippy_lints.stderr index aa2c2f3c0e20..ea925cd3a9fc 100644 --- a/tests/ui/unknown_clippy_lints.stderr +++ b/tests/ui/unknown_clippy_lints.stderr @@ -39,8 +39,9 @@ LL | #[warn(clippy::dead_cod)] | help: a lint with a similar name exists in `rustc` lints | -LL | #[warn(dead_code)] - | ~~~~~~~~~ +LL - #[warn(clippy::dead_cod)] +LL + #[warn(dead_code)] + | error: unknown lint: `clippy::unused_colle` --> tests/ui/unknown_clippy_lints.rs:13:8 @@ -62,8 +63,9 @@ LL | #[warn(clippy::missing_docs)] | help: a lint with a similar name exists in `rustc` lints | -LL | #[warn(missing_docs)] - | ~~~~~~~~~~~~ +LL - #[warn(clippy::missing_docs)] +LL + #[warn(missing_docs)] + | error: aborting due to 9 previous errors diff --git a/tests/ui/unnecessary_lazy_eval.stderr b/tests/ui/unnecessary_lazy_eval.stderr index 35a2144c389f..9bb1b71f0ed5 100644 --- a/tests/ui/unnecessary_lazy_eval.stderr +++ b/tests/ui/unnecessary_lazy_eval.stderr @@ -8,8 +8,9 @@ LL | let _ = opt.unwrap_or_else(|| 2); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]` help: use `unwrap_or` instead | -LL | let _ = opt.unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = opt.unwrap_or_else(|| 2); +LL + let _ = opt.unwrap_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:84:13 @@ -19,8 +20,9 @@ LL | let _ = opt.unwrap_or_else(|| astronomers_pi); | help: use `unwrap_or` instead | -LL | let _ = opt.unwrap_or(astronomers_pi); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = opt.unwrap_or_else(|| astronomers_pi); +LL + let _ = opt.unwrap_or(astronomers_pi); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:85:13 @@ -30,8 +32,9 @@ LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); | help: use `unwrap_or` instead | -LL | let _ = opt.unwrap_or(ext_str.some_field); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = opt.unwrap_or_else(|| ext_str.some_field); +LL + let _ = opt.unwrap_or(ext_str.some_field); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:87:13 @@ -41,8 +44,9 @@ LL | let _ = opt.and_then(|_| ext_opt); | help: use `and` instead | -LL | let _ = opt.and(ext_opt); - | ~~~~~~~~~~~~ +LL - let _ = opt.and_then(|_| ext_opt); +LL + let _ = opt.and(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:88:13 @@ -52,8 +56,9 @@ LL | let _ = opt.or_else(|| ext_opt); | help: use `or` instead | -LL | let _ = opt.or(ext_opt); - | ~~~~~~~~~~~ +LL - let _ = opt.or_else(|| ext_opt); +LL + let _ = opt.or(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:89:13 @@ -63,8 +68,9 @@ LL | let _ = opt.or_else(|| None); | help: use `or` instead | -LL | let _ = opt.or(None); - | ~~~~~~~~ +LL - let _ = opt.or_else(|| None); +LL + let _ = opt.or(None); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:90:13 @@ -74,8 +80,9 @@ LL | let _ = opt.get_or_insert_with(|| 2); | help: use `get_or_insert` instead | -LL | let _ = opt.get_or_insert(2); - | ~~~~~~~~~~~~~~~~ +LL - let _ = opt.get_or_insert_with(|| 2); +LL + let _ = opt.get_or_insert(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:91:13 @@ -85,8 +92,9 @@ LL | let _ = opt.ok_or_else(|| 2); | help: use `ok_or` instead | -LL | let _ = opt.ok_or(2); - | ~~~~~~~~ +LL - let _ = opt.ok_or_else(|| 2); +LL + let _ = opt.ok_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:92:13 @@ -96,8 +104,9 @@ LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); | help: use `unwrap_or` instead | -LL | let _ = nested_tuple_opt.unwrap_or(Some((1, 2))); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); +LL + let _ = nested_tuple_opt.unwrap_or(Some((1, 2))); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:93:13 @@ -107,8 +116,9 @@ LL | let _ = cond.then(|| astronomers_pi); | help: use `then_some` instead | -LL | let _ = cond.then_some(astronomers_pi); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = cond.then(|| astronomers_pi); +LL + let _ = cond.then_some(astronomers_pi); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:94:13 @@ -118,8 +128,9 @@ LL | let _ = true.then(|| -> _ {}); | help: use `then_some` instead | -LL | let _ = true.then_some({}); - | ~~~~~~~~~~~~~ +LL - let _ = true.then(|| -> _ {}); +LL + let _ = true.then_some({}); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:95:13 @@ -129,8 +140,9 @@ LL | let _ = true.then(|| {}); | help: use `then_some` instead | -LL | let _ = true.then_some({}); - | ~~~~~~~~~~~~~ +LL - let _ = true.then(|| {}); +LL + let _ = true.then_some({}); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:99:13 @@ -140,8 +152,9 @@ LL | let _ = Some(1).unwrap_or_else(|| *r); | help: use `unwrap_or` instead | -LL | let _ = Some(1).unwrap_or(*r); - | ~~~~~~~~~~~~~ +LL - let _ = Some(1).unwrap_or_else(|| *r); +LL + let _ = Some(1).unwrap_or(*r); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:101:13 @@ -151,8 +164,9 @@ LL | let _ = Some(1).unwrap_or_else(|| *b); | help: use `unwrap_or` instead | -LL | let _ = Some(1).unwrap_or(*b); - | ~~~~~~~~~~~~~ +LL - let _ = Some(1).unwrap_or_else(|| *b); +LL + let _ = Some(1).unwrap_or(*b); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:103:13 @@ -162,8 +176,9 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); | help: use `unwrap_or` instead | -LL | let _ = Some(1).as_ref().unwrap_or(&r); - | ~~~~~~~~~~~~~ +LL - let _ = Some(1).as_ref().unwrap_or_else(|| &r); +LL + let _ = Some(1).as_ref().unwrap_or(&r); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:104:13 @@ -173,8 +188,9 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); | help: use `unwrap_or` instead | -LL | let _ = Some(1).as_ref().unwrap_or(&b); - | ~~~~~~~~~~~~~ +LL - let _ = Some(1).as_ref().unwrap_or_else(|| &b); +LL + let _ = Some(1).as_ref().unwrap_or(&b); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:107:13 @@ -184,8 +200,9 @@ LL | let _ = Some(10).unwrap_or_else(|| 2); | help: use `unwrap_or` instead | -LL | let _ = Some(10).unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = Some(10).unwrap_or_else(|| 2); +LL + let _ = Some(10).unwrap_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:108:13 @@ -195,8 +212,9 @@ LL | let _ = Some(10).and_then(|_| ext_opt); | help: use `and` instead | -LL | let _ = Some(10).and(ext_opt); - | ~~~~~~~~~~~~ +LL - let _ = Some(10).and_then(|_| ext_opt); +LL + let _ = Some(10).and(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:109:28 @@ -206,8 +224,9 @@ LL | let _: Option = None.or_else(|| ext_opt); | help: use `or` instead | -LL | let _: Option = None.or(ext_opt); - | ~~~~~~~~~~~ +LL - let _: Option = None.or_else(|| ext_opt); +LL + let _: Option = None.or(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:110:13 @@ -217,8 +236,9 @@ LL | let _ = None.get_or_insert_with(|| 2); | help: use `get_or_insert` instead | -LL | let _ = None.get_or_insert(2); - | ~~~~~~~~~~~~~~~~ +LL - let _ = None.get_or_insert_with(|| 2); +LL + let _ = None.get_or_insert(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:111:35 @@ -228,8 +248,9 @@ LL | let _: Result = None.ok_or_else(|| 2); | help: use `ok_or` instead | -LL | let _: Result = None.ok_or(2); - | ~~~~~~~~ +LL - let _: Result = None.ok_or_else(|| 2); +LL + let _: Result = None.ok_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:112:28 @@ -239,8 +260,9 @@ LL | let _: Option = None.or_else(|| None); | help: use `or` instead | -LL | let _: Option = None.or(None); - | ~~~~~~~~ +LL - let _: Option = None.or_else(|| None); +LL + let _: Option = None.or(None); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:115:13 @@ -250,8 +272,9 @@ LL | let _ = deep.0.unwrap_or_else(|| 2); | help: use `unwrap_or` instead | -LL | let _ = deep.0.unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = deep.0.unwrap_or_else(|| 2); +LL + let _ = deep.0.unwrap_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:116:13 @@ -261,8 +284,9 @@ LL | let _ = deep.0.and_then(|_| ext_opt); | help: use `and` instead | -LL | let _ = deep.0.and(ext_opt); - | ~~~~~~~~~~~~ +LL - let _ = deep.0.and_then(|_| ext_opt); +LL + let _ = deep.0.and(ext_opt); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:117:13 @@ -272,8 +296,9 @@ LL | let _ = deep.0.or_else(|| None); | help: use `or` instead | -LL | let _ = deep.0.or(None); - | ~~~~~~~~ +LL - let _ = deep.0.or_else(|| None); +LL + let _ = deep.0.or(None); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:118:13 @@ -283,8 +308,9 @@ LL | let _ = deep.0.get_or_insert_with(|| 2); | help: use `get_or_insert` instead | -LL | let _ = deep.0.get_or_insert(2); - | ~~~~~~~~~~~~~~~~ +LL - let _ = deep.0.get_or_insert_with(|| 2); +LL + let _ = deep.0.get_or_insert(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:119:13 @@ -294,8 +320,9 @@ LL | let _ = deep.0.ok_or_else(|| 2); | help: use `ok_or` instead | -LL | let _ = deep.0.ok_or(2); - | ~~~~~~~~ +LL - let _ = deep.0.ok_or_else(|| 2); +LL + let _ = deep.0.ok_or(2); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:150:28 @@ -305,8 +332,9 @@ LL | let _: Option = None.or_else(|| Some(3)); | help: use `or` instead | -LL | let _: Option = None.or(Some(3)); - | ~~~~~~~~~~~ +LL - let _: Option = None.or_else(|| Some(3)); +LL + let _: Option = None.or(Some(3)); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:151:13 @@ -316,8 +344,9 @@ LL | let _ = deep.0.or_else(|| Some(3)); | help: use `or` instead | -LL | let _ = deep.0.or(Some(3)); - | ~~~~~~~~~~~ +LL - let _ = deep.0.or_else(|| Some(3)); +LL + let _ = deep.0.or(Some(3)); + | error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:152:13 @@ -327,8 +356,9 @@ LL | let _ = opt.or_else(|| Some(3)); | help: use `or` instead | -LL | let _ = opt.or(Some(3)); - | ~~~~~~~~~~~ +LL - let _ = opt.or_else(|| Some(3)); +LL + let _ = opt.or(Some(3)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:158:13 @@ -338,8 +368,9 @@ LL | let _ = res2.unwrap_or_else(|_| 2); | help: use `unwrap_or` instead | -LL | let _ = res2.unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = res2.unwrap_or_else(|_| 2); +LL + let _ = res2.unwrap_or(2); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:159:13 @@ -349,8 +380,9 @@ LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); | help: use `unwrap_or` instead | -LL | let _ = res2.unwrap_or(astronomers_pi); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = res2.unwrap_or_else(|_| astronomers_pi); +LL + let _ = res2.unwrap_or(astronomers_pi); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:160:13 @@ -360,8 +392,9 @@ LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); | help: use `unwrap_or` instead | -LL | let _ = res2.unwrap_or(ext_str.some_field); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = res2.unwrap_or_else(|_| ext_str.some_field); +LL + let _ = res2.unwrap_or(ext_str.some_field); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:182:35 @@ -371,8 +404,9 @@ LL | let _: Result = res.and_then(|_| Err(2)); | help: use `and` instead | -LL | let _: Result = res.and(Err(2)); - | ~~~~~~~~~~~ +LL - let _: Result = res.and_then(|_| Err(2)); +LL + let _: Result = res.and(Err(2)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:183:35 @@ -382,8 +416,9 @@ LL | let _: Result = res.and_then(|_| Err(astronomers_pi)); | help: use `and` instead | -LL | let _: Result = res.and(Err(astronomers_pi)); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Result = res.and_then(|_| Err(astronomers_pi)); +LL + let _: Result = res.and(Err(astronomers_pi)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:184:35 @@ -393,8 +428,9 @@ LL | let _: Result = res.and_then(|_| Err(ext_str.some_field)) | help: use `and` instead | -LL | let _: Result = res.and(Err(ext_str.some_field)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Result = res.and_then(|_| Err(ext_str.some_field)); +LL + let _: Result = res.and(Err(ext_str.some_field)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:186:35 @@ -404,8 +440,9 @@ LL | let _: Result = res.or_else(|_| Ok(2)); | help: use `or` instead | -LL | let _: Result = res.or(Ok(2)); - | ~~~~~~~~~ +LL - let _: Result = res.or_else(|_| Ok(2)); +LL + let _: Result = res.or(Ok(2)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:187:35 @@ -415,8 +452,9 @@ LL | let _: Result = res.or_else(|_| Ok(astronomers_pi)); | help: use `or` instead | -LL | let _: Result = res.or(Ok(astronomers_pi)); - | ~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Result = res.or_else(|_| Ok(astronomers_pi)); +LL + let _: Result = res.or(Ok(astronomers_pi)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:188:35 @@ -426,8 +464,9 @@ LL | let _: Result = res.or_else(|_| Ok(ext_str.some_field)); | help: use `or` instead | -LL | let _: Result = res.or(Ok(ext_str.some_field)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Result = res.or_else(|_| Ok(ext_str.some_field)); +LL + let _: Result = res.or(Ok(ext_str.some_field)); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:189:35 @@ -440,8 +479,9 @@ LL | | or_else(|_| Ok(ext_str.some_field)); | help: use `or` instead | -LL | or(Ok(ext_str.some_field)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - or_else(|_| Ok(ext_str.some_field)); +LL + or(Ok(ext_str.some_field)); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:219:14 @@ -451,8 +491,9 @@ LL | let _x = false.then(|| i32::MAX + 1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MAX + 1); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MAX + 1); +LL + let _x = false.then_some(i32::MAX + 1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:221:14 @@ -462,8 +503,9 @@ LL | let _x = false.then(|| i32::MAX * 2); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MAX * 2); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MAX * 2); +LL + let _x = false.then_some(i32::MAX * 2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:223:14 @@ -473,8 +515,9 @@ LL | let _x = false.then(|| i32::MAX - 1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MAX - 1); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MAX - 1); +LL + let _x = false.then_some(i32::MAX - 1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:225:14 @@ -484,8 +527,9 @@ LL | let _x = false.then(|| i32::MIN - 1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MIN - 1); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MIN - 1); +LL + let _x = false.then_some(i32::MIN - 1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:227:14 @@ -495,8 +539,9 @@ LL | let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); | help: use `then_some` instead | -LL | let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); +LL + let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:229:14 @@ -506,8 +551,9 @@ LL | let _x = false.then(|| 255u8 << 7); | help: use `then_some` instead | -LL | let _x = false.then_some(255u8 << 7); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255u8 << 7); +LL + let _x = false.then_some(255u8 << 7); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:231:14 @@ -517,8 +563,9 @@ LL | let _x = false.then(|| 255u8 << 8); | help: use `then_some` instead | -LL | let _x = false.then_some(255u8 << 8); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255u8 << 8); +LL + let _x = false.then_some(255u8 << 8); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:233:14 @@ -528,8 +575,9 @@ LL | let _x = false.then(|| 255u8 >> 8); | help: use `then_some` instead | -LL | let _x = false.then_some(255u8 >> 8); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255u8 >> 8); +LL + let _x = false.then_some(255u8 >> 8); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:236:14 @@ -539,8 +587,9 @@ LL | let _x = false.then(|| i32::MAX + -1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MAX + -1); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MAX + -1); +LL + let _x = false.then_some(i32::MAX + -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:238:14 @@ -550,8 +599,9 @@ LL | let _x = false.then(|| -i32::MAX); | help: use `then_some` instead | -LL | let _x = false.then_some(-i32::MAX); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| -i32::MAX); +LL + let _x = false.then_some(-i32::MAX); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:240:14 @@ -561,8 +611,9 @@ LL | let _x = false.then(|| -i32::MIN); | help: use `then_some` instead | -LL | let _x = false.then_some(-i32::MIN); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| -i32::MIN); +LL + let _x = false.then_some(-i32::MIN); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:243:14 @@ -572,8 +623,9 @@ LL | let _x = false.then(|| 255 >> -7); | help: use `then_some` instead | -LL | let _x = false.then_some(255 >> -7); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255 >> -7); +LL + let _x = false.then_some(255 >> -7); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:245:14 @@ -583,8 +635,9 @@ LL | let _x = false.then(|| 255 << -1); | help: use `then_some` instead | -LL | let _x = false.then_some(255 << -1); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 255 << -1); +LL + let _x = false.then_some(255 << -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:247:14 @@ -594,8 +647,9 @@ LL | let _x = false.then(|| 1 / 0); | help: use `then_some` instead | -LL | let _x = false.then_some(1 / 0); - | ~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 1 / 0); +LL + let _x = false.then_some(1 / 0); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:249:14 @@ -605,8 +659,9 @@ LL | let _x = false.then(|| x << -1); | help: use `then_some` instead | -LL | let _x = false.then_some(x << -1); - | ~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| x << -1); +LL + let _x = false.then_some(x << -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:251:14 @@ -616,8 +671,9 @@ LL | let _x = false.then(|| x << 2); | help: use `then_some` instead | -LL | let _x = false.then_some(x << 2); - | ~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| x << 2); +LL + let _x = false.then_some(x << 2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:261:14 @@ -627,8 +683,9 @@ LL | let _x = false.then(|| x / 0); | help: use `then_some` instead | -LL | let _x = false.then_some(x / 0); - | ~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| x / 0); +LL + let _x = false.then_some(x / 0); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:263:14 @@ -638,8 +695,9 @@ LL | let _x = false.then(|| x % 0); | help: use `then_some` instead | -LL | let _x = false.then_some(x % 0); - | ~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| x % 0); +LL + let _x = false.then_some(x % 0); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:266:14 @@ -649,8 +707,9 @@ LL | let _x = false.then(|| 1 / -1); | help: use `then_some` instead | -LL | let _x = false.then_some(1 / -1); - | ~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 1 / -1); +LL + let _x = false.then_some(1 / -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:268:14 @@ -660,8 +719,9 @@ LL | let _x = false.then(|| i32::MIN / -1); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MIN / -1); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MIN / -1); +LL + let _x = false.then_some(i32::MIN / -1); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:271:14 @@ -671,8 +731,9 @@ LL | let _x = false.then(|| i32::MIN / 0); | help: use `then_some` instead | -LL | let _x = false.then_some(i32::MIN / 0); - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| i32::MIN / 0); +LL + let _x = false.then_some(i32::MIN / 0); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:273:14 @@ -682,8 +743,9 @@ LL | let _x = false.then(|| 4 / 2); | help: use `then_some` instead | -LL | let _x = false.then_some(4 / 2); - | ~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| 4 / 2); +LL + let _x = false.then_some(4 / 2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:281:14 @@ -693,8 +755,9 @@ LL | let _x = false.then(|| f1 + f2); | help: use `then_some` instead | -LL | let _x = false.then_some(f1 + f2); - | ~~~~~~~~~~~~~~~~~~ +LL - let _x = false.then(|| f1 + f2); +LL + let _x = false.then_some(f1 + f2); + | error: aborting due to 63 previous errors diff --git a/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/tests/ui/unnecessary_lazy_eval_unfixable.stderr index 390235b21247..9688c44c9145 100644 --- a/tests/ui/unnecessary_lazy_eval_unfixable.stderr +++ b/tests/ui/unnecessary_lazy_eval_unfixable.stderr @@ -8,8 +8,9 @@ LL | let _ = Ok(1).unwrap_or_else(|()| 2); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]` help: use `unwrap_or` instead | -LL | let _ = Ok(1).unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = Ok(1).unwrap_or_else(|()| 2); +LL + let _ = Ok(1).unwrap_or(2); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:19:13 @@ -19,8 +20,9 @@ LL | let _ = Ok(1).unwrap_or_else(|e::E| 2); | help: use `unwrap_or` instead | -LL | let _ = Ok(1).unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = Ok(1).unwrap_or_else(|e::E| 2); +LL + let _ = Ok(1).unwrap_or(2); + | error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:21:13 @@ -30,8 +32,9 @@ LL | let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); | help: use `unwrap_or` instead | -LL | let _ = Ok(1).unwrap_or(2); - | ~~~~~~~~~~~~ +LL - let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); +LL + let _ = Ok(1).unwrap_or(2); + | error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:31:13 @@ -41,8 +44,9 @@ LL | let _ = true.then(|| -> &[u8] { &[] }); | help: use `then_some` instead | -LL | let _ = true.then_some({ &[] }); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = true.then(|| -> &[u8] { &[] }); +LL + let _ = true.then_some({ &[] }); + | error: aborting due to 4 previous errors diff --git a/tests/ui/unnecessary_literal_unwrap.stderr b/tests/ui/unnecessary_literal_unwrap.stderr index 37ee9195fce6..631bf0837266 100644 --- a/tests/ui/unnecessary_literal_unwrap.stderr +++ b/tests/ui/unnecessary_literal_unwrap.stderr @@ -62,8 +62,9 @@ LL | let _val = None::<()>.expect("this always happens"); | help: remove the `None` and `expect()` | -LL | let _val = panic!("this always happens"); - | ~~~~~~~ +LL - let _val = None::<()>.expect("this always happens"); +LL + let _val = panic!("this always happens"); + | error: used `unwrap_or_default()` on `None` value --> tests/ui/unnecessary_literal_unwrap.rs:22:24 @@ -133,8 +134,9 @@ LL | None::<()>.expect("this always happens"); | help: remove the `None` and `expect()` | -LL | panic!("this always happens"); - | ~~~~~~~ +LL - None::<()>.expect("this always happens"); +LL + panic!("this always happens"); + | error: used `unwrap_or_default()` on `None` value --> tests/ui/unnecessary_literal_unwrap.rs:30:5 @@ -222,8 +224,9 @@ LL | let _val = Ok::<_, ()>(1).unwrap_err(); | help: remove the `Ok` and `unwrap_err()` | -LL | let _val = panic!("{:?}", 1); - | ~~~~~~~~~~~~~~ ~ +LL - let _val = Ok::<_, ()>(1).unwrap_err(); +LL + let _val = panic!("{:?}", 1); + | error: used `expect_err()` on `Ok` value --> tests/ui/unnecessary_literal_unwrap.rs:41:16 @@ -233,8 +236,9 @@ LL | let _val = Ok::<_, ()>(1).expect_err("this always happens"); | help: remove the `Ok` and `expect_err()` | -LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); - | ~~~~~~~~~~~~~~~~~~~ ~ +LL - let _val = Ok::<_, ()>(1).expect_err("this always happens"); +LL + let _val = panic!("{1}: {:?}", 1, "this always happens"); + | error: used `unwrap()` on `Ok` value --> tests/ui/unnecessary_literal_unwrap.rs:43:5 @@ -268,8 +272,9 @@ LL | Ok::<_, ()>(1).unwrap_err(); | help: remove the `Ok` and `unwrap_err()` | -LL | panic!("{:?}", 1); - | ~~~~~~~~~~~~~~ ~ +LL - Ok::<_, ()>(1).unwrap_err(); +LL + panic!("{:?}", 1); + | error: used `expect_err()` on `Ok` value --> tests/ui/unnecessary_literal_unwrap.rs:46:5 @@ -279,8 +284,9 @@ LL | Ok::<_, ()>(1).expect_err("this always happens"); | help: remove the `Ok` and `expect_err()` | -LL | panic!("{1}: {:?}", 1, "this always happens"); - | ~~~~~~~~~~~~~~~~~~~ ~ +LL - Ok::<_, ()>(1).expect_err("this always happens"); +LL + panic!("{1}: {:?}", 1, "this always happens"); + | error: used `unwrap_err()` on `Err` value --> tests/ui/unnecessary_literal_unwrap.rs:50:16 @@ -314,8 +320,9 @@ LL | let _val = Err::<(), _>(1).unwrap(); | help: remove the `Err` and `unwrap()` | -LL | let _val = panic!("{:?}", 1); - | ~~~~~~~~~~~~~~ ~ +LL - let _val = Err::<(), _>(1).unwrap(); +LL + let _val = panic!("{:?}", 1); + | error: used `expect()` on `Err` value --> tests/ui/unnecessary_literal_unwrap.rs:53:16 @@ -325,8 +332,9 @@ LL | let _val = Err::<(), _>(1).expect("this always happens"); | help: remove the `Err` and `expect()` | -LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); - | ~~~~~~~~~~~~~~~~~~~ ~ +LL - let _val = Err::<(), _>(1).expect("this always happens"); +LL + let _val = panic!("{1}: {:?}", 1, "this always happens"); + | error: used `unwrap_err()` on `Err` value --> tests/ui/unnecessary_literal_unwrap.rs:55:5 @@ -360,8 +368,9 @@ LL | Err::<(), _>(1).unwrap(); | help: remove the `Err` and `unwrap()` | -LL | panic!("{:?}", 1); - | ~~~~~~~~~~~~~~ ~ +LL - Err::<(), _>(1).unwrap(); +LL + panic!("{:?}", 1); + | error: used `expect()` on `Err` value --> tests/ui/unnecessary_literal_unwrap.rs:58:5 @@ -371,8 +380,9 @@ LL | Err::<(), _>(1).expect("this always happens"); | help: remove the `Err` and `expect()` | -LL | panic!("{1}: {:?}", 1, "this always happens"); - | ~~~~~~~~~~~~~~~~~~~ ~ +LL - Err::<(), _>(1).expect("this always happens"); +LL + panic!("{1}: {:?}", 1, "this always happens"); + | error: used `unwrap_or()` on `Some` value --> tests/ui/unnecessary_literal_unwrap.rs:62:16 diff --git a/tests/ui/unnecessary_map_or.stderr b/tests/ui/unnecessary_map_or.stderr index 2ae327f0bf88..9f38b8c8d93a 100644 --- a/tests/ui/unnecessary_map_or.stderr +++ b/tests/ui/unnecessary_map_or.stderr @@ -8,8 +8,9 @@ LL | let _ = Some(5).map_or(false, |n| n == 5); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_or)]` help: use a standard comparison instead | -LL | let _ = Some(5) == Some(5); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| n == 5); +LL + let _ = Some(5) == Some(5); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:14:13 @@ -19,8 +20,9 @@ LL | let _ = Some(5).map_or(true, |n| n != 5); | help: use a standard comparison instead | -LL | let _ = Some(5) != Some(5); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(true, |n| n != 5); +LL + let _ = Some(5) != Some(5); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:15:13 @@ -34,8 +36,12 @@ LL | | }); | help: use a standard comparison instead | -LL | let _ = Some(5) == Some(5); - | ~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| { +LL - let _ = 1; +LL - n == 5 +LL - }); +LL + let _ = Some(5) == Some(5); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:19:13 @@ -121,8 +127,9 @@ LL | let _ = Ok::(5).map_or(false, |n| n == 5); | help: use a standard comparison instead | -LL | let _ = Ok::(5) == Ok(5); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Ok::(5).map_or(false, |n| n == 5); +LL + let _ = Ok::(5) == Ok(5); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:29:13 @@ -132,8 +139,9 @@ LL | let _ = Some(5).map_or(false, |n| n == 5).then(|| 1); | help: use a standard comparison instead | -LL | let _ = (Some(5) == Some(5)).then(|| 1); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| n == 5).then(|| 1); +LL + let _ = (Some(5) == Some(5)).then(|| 1); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:30:13 @@ -167,8 +175,9 @@ LL | let _ = !Some(5).map_or(false, |n| n == 5); | help: use a standard comparison instead | -LL | let _ = !(Some(5) == Some(5)); - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = !Some(5).map_or(false, |n| n == 5); +LL + let _ = !(Some(5) == Some(5)); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:33:13 @@ -178,8 +187,9 @@ LL | let _ = Some(5).map_or(false, |n| n == 5) || false; | help: use a standard comparison instead | -LL | let _ = (Some(5) == Some(5)) || false; - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| n == 5) || false; +LL + let _ = (Some(5) == Some(5)) || false; + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:34:13 @@ -189,8 +199,9 @@ LL | let _ = Some(5).map_or(false, |n| n == 5) as usize; | help: use a standard comparison instead | -LL | let _ = (Some(5) == Some(5)) as usize; - | ~~~~~~~~~~~~~~~~~~~~ +LL - let _ = Some(5).map_or(false, |n| n == 5) as usize; +LL + let _ = (Some(5) == Some(5)) as usize; + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:58:13 @@ -248,8 +259,9 @@ LL | let _ = r.map_or(false, |x| x == 8); | help: use a standard comparison instead | -LL | let _ = r == Ok(8); - | ~~~~~~~~~~ +LL - let _ = r.map_or(false, |x| x == 8); +LL + let _ = r == Ok(8); + | error: this `map_or` can be simplified --> tests/ui/unnecessary_map_or.rs:90:5 diff --git a/tests/ui/unnecessary_wraps.stderr b/tests/ui/unnecessary_wraps.stderr index b304d4dce6ea..b06ab91dc8de 100644 --- a/tests/ui/unnecessary_wraps.stderr +++ b/tests/ui/unnecessary_wraps.stderr @@ -13,8 +13,9 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::unnecessary_wraps)]` help: remove `Option` from the return type... | -LL | fn func1(a: bool, b: bool) -> i32 { - | ~~~ +LL - fn func1(a: bool, b: bool) -> Option { +LL + fn func1(a: bool, b: bool) -> i32 { + | help: ...and then change returning expressions | LL ~ return 42; @@ -40,8 +41,9 @@ LL | | } | help: remove `Option` from the return type... | -LL | fn func2(a: bool, b: bool) -> i32 { - | ~~~ +LL - fn func2(a: bool, b: bool) -> Option { +LL + fn func2(a: bool, b: bool) -> i32 { + | help: ...and then change returning expressions | LL ~ return 10; @@ -60,11 +62,13 @@ LL | | } | help: remove `Option` from the return type... | -LL | fn func5() -> i32 { - | ~~~ +LL - fn func5() -> Option { +LL + fn func5() -> i32 { + | help: ...and then change returning expressions | -LL | 1 +LL - Some(1) +LL + 1 | error: this function's return value is unnecessarily wrapped by `Result` @@ -78,11 +82,13 @@ LL | | } | help: remove `Result` from the return type... | -LL | fn func7() -> i32 { - | ~~~ +LL - fn func7() -> Result { +LL + fn func7() -> i32 { + | help: ...and then change returning expressions | -LL | 1 +LL - Ok(1) +LL + 1 | error: this function's return value is unnecessarily wrapped by `Option` @@ -96,11 +102,13 @@ LL | | } | help: remove `Option` from the return type... | -LL | fn func12() -> i32 { - | ~~~ +LL - fn func12() -> Option { +LL + fn func12() -> i32 { + | help: ...and then change returning expressions | -LL | 1 +LL - Some(1) +LL + 1 | error: this function's return value is unnecessary @@ -116,8 +124,9 @@ LL | | } | help: remove the return type... | -LL | fn issue_6640_1(a: bool, b: bool) -> () { - | ~~ +LL - fn issue_6640_1(a: bool, b: bool) -> Option<()> { +LL + fn issue_6640_1(a: bool, b: bool) -> () { + | help: ...and then remove returned values | LL ~ return ; @@ -142,8 +151,9 @@ LL | | } | help: remove the return type... | -LL | fn issue_6640_2(a: bool, b: bool) -> () { - | ~~ +LL - fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { +LL + fn issue_6640_2(a: bool, b: bool) -> () { + | help: ...and then remove returned values | LL ~ return ; diff --git a/tests/ui/unnested_or_patterns.stderr b/tests/ui/unnested_or_patterns.stderr index bd15ef62368e..4325df143042 100644 --- a/tests/ui/unnested_or_patterns.stderr +++ b/tests/ui/unnested_or_patterns.stderr @@ -8,8 +8,9 @@ LL | if let box 0 | box 2 = Box::new(0) {} = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]` help: nest the patterns | -LL | if let box (0 | 2) = Box::new(0) {} - | ~~~~~~~~~~~ +LL - if let box 0 | box 2 = Box::new(0) {} +LL + if let box (0 | 2) = Box::new(0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:17:12 @@ -19,8 +20,9 @@ LL | if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} | help: nest the patterns | -LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} +LL + if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:19:12 @@ -30,8 +32,9 @@ LL | if let Some(1) | C0 | Some(2) = None {} | help: nest the patterns | -LL | if let Some(1 | 2) | C0 = None {} - | ~~~~~~~~~~~~~~~~ +LL - if let Some(1) | C0 | Some(2) = None {} +LL + if let Some(1 | 2) | C0 = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:20:12 @@ -41,8 +44,9 @@ LL | if let &mut 0 | &mut 2 = &mut 0 {} | help: nest the patterns | -LL | if let &mut (0 | 2) = &mut 0 {} - | ~~~~~~~~~~~~ +LL - if let &mut 0 | &mut 2 = &mut 0 {} +LL + if let &mut (0 | 2) = &mut 0 {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:21:12 @@ -52,8 +56,9 @@ LL | if let x @ 0 | x @ 2 = 0 {} | help: nest the patterns | -LL | if let x @ (0 | 2) = 0 {} - | ~~~~~~~~~~~ +LL - if let x @ 0 | x @ 2 = 0 {} +LL + if let x @ (0 | 2) = 0 {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:22:12 @@ -63,8 +68,9 @@ LL | if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {} | help: nest the patterns | -LL | if let (0, 1 | 2 | 3) = (0, 0) {} - | ~~~~~~~~~~~~~~ +LL - if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {} +LL + if let (0, 1 | 2 | 3) = (0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:23:12 @@ -74,8 +80,9 @@ LL | if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {} | help: nest the patterns | -LL | if let (1 | 2 | 3, 0) = (0, 0) {} - | ~~~~~~~~~~~~~~ +LL - if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {} +LL + if let (1 | 2 | 3, 0) = (0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:24:12 @@ -85,8 +92,9 @@ LL | if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {} | help: nest the patterns | -LL | if let (x, ..) | (x, 1 | 2) = (0, 1) {} - | ~~~~~~~~~~~~~~~~~~~~ +LL - if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {} +LL + if let (x, ..) | (x, 1 | 2) = (0, 1) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:25:12 @@ -96,8 +104,9 @@ LL | if let [0] | [1] = [0] {} | help: nest the patterns | -LL | if let [0 | 1] = [0] {} - | ~~~~~~~ +LL - if let [0] | [1] = [0] {} +LL + if let [0 | 1] = [0] {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:26:12 @@ -107,8 +116,9 @@ LL | if let [x, 0] | [x, 1] = [0, 1] {} | help: nest the patterns | -LL | if let [x, 0 | 1] = [0, 1] {} - | ~~~~~~~~~~ +LL - if let [x, 0] | [x, 1] = [0, 1] {} +LL + if let [x, 0 | 1] = [0, 1] {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:27:12 @@ -118,8 +128,9 @@ LL | if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {} | help: nest the patterns | -LL | if let [x, 0 | 1 | 2] = [0, 1] {} - | ~~~~~~~~~~~~~~ +LL - if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {} +LL + if let [x, 0 | 1 | 2] = [0, 1] {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:28:12 @@ -129,8 +140,9 @@ LL | if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {} | help: nest the patterns | -LL | if let [x, ..] | [x, 1 | 2] = [0, 1] {} - | ~~~~~~~~~~~~~~~~~~~~ +LL - if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {} +LL + if let [x, ..] | [x, 1 | 2] = [0, 1] {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:30:12 @@ -140,8 +152,9 @@ LL | if let TS(0, x) | TS(1, x) = TS(0, 0) {} | help: nest the patterns | -LL | if let TS(0 | 1, x) = TS(0, 0) {} - | ~~~~~~~~~~~~ +LL - if let TS(0, x) | TS(1, x) = TS(0, 0) {} +LL + if let TS(0 | 1, x) = TS(0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:31:12 @@ -151,8 +164,9 @@ LL | if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {} | help: nest the patterns | -LL | if let TS(1 | 2 | 3, 0) = TS(0, 0) {} - | ~~~~~~~~~~~~~~~~ +LL - if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {} +LL + if let TS(1 | 2 | 3, 0) = TS(0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:32:12 @@ -162,8 +176,9 @@ LL | if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {} | help: nest the patterns | -LL | if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {} - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {} +LL + if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:37:12 @@ -173,8 +188,9 @@ LL | if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {} | help: nest the patterns | -LL | if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {} - | ~~~~~~~~~~~~~~~~~ +LL - if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {} +LL + if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns.rs:48:12 @@ -184,8 +200,9 @@ LL | if let [1] | [53] = [0] {} | help: nest the patterns | -LL | if let [1 | 53] = [0] {} - | ~~~~~~~~ +LL - if let [1] | [53] = [0] {} +LL + if let [1 | 53] = [0] {} + | error: aborting due to 17 previous errors diff --git a/tests/ui/unnested_or_patterns2.stderr b/tests/ui/unnested_or_patterns2.stderr index 54f03937508a..3d8968551b96 100644 --- a/tests/ui/unnested_or_patterns2.stderr +++ b/tests/ui/unnested_or_patterns2.stderr @@ -8,8 +8,9 @@ LL | if let Some(Some(0)) | Some(Some(1)) = None {} = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]` help: nest the patterns | -LL | if let Some(Some(0 | 1)) = None {} - | ~~~~~~~~~~~~~~~~~ +LL - if let Some(Some(0)) | Some(Some(1)) = None {} +LL + if let Some(Some(0 | 1)) = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:13:12 @@ -19,8 +20,9 @@ LL | if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {} | help: nest the patterns | -LL | if let Some(Some(0 | 1 | 2)) = None {} - | ~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {} +LL + if let Some(Some(0 | 1 | 2)) = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:14:12 @@ -30,8 +32,9 @@ LL | if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {} | help: nest the patterns | -LL | if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {} +LL + if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:15:12 @@ -41,8 +44,9 @@ LL | if let Some(Some(0) | Some(1 | 2)) = None {} | help: nest the patterns | -LL | if let Some(Some(0 | 1 | 2)) = None {} - | ~~~~~~~~~~~~~~~~~~~~~ +LL - if let Some(Some(0) | Some(1 | 2)) = None {} +LL + if let Some(Some(0 | 1 | 2)) = None {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:16:12 @@ -52,8 +56,9 @@ LL | if let ((0,),) | ((1,) | (2,),) = ((0,),) {} | help: nest the patterns | -LL | if let ((0 | 1 | 2,),) = ((0,),) {} - | ~~~~~~~~~~~~~~~ +LL - if let ((0,),) | ((1,) | (2,),) = ((0,),) {} +LL + if let ((0 | 1 | 2,),) = ((0,),) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:17:12 @@ -63,8 +68,9 @@ LL | if let 0 | (1 | 2) = 0 {} | help: nest the patterns | -LL | if let 0 | 1 | 2 = 0 {} - | ~~~~~~~~~ +LL - if let 0 | (1 | 2) = 0 {} +LL + if let 0 | 1 | 2 = 0 {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:18:12 @@ -74,8 +80,9 @@ LL | if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} | help: nest the patterns | -LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} - | ~~~~~~~~~~~~~~~~~~~~~~~ +LL - if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} +LL + if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} + | error: unnested or-patterns --> tests/ui/unnested_or_patterns2.rs:19:12 @@ -85,8 +92,9 @@ LL | if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} | help: nest the patterns | -LL | if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {} - | ~~~~~~~~~~~~~~~~~~~ +LL - if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} +LL + if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {} + | error: aborting due to 8 previous errors diff --git a/tests/ui/unused_enumerate_index.stderr b/tests/ui/unused_enumerate_index.stderr index 6ec07dcbff0a..02d65f064308 100644 --- a/tests/ui/unused_enumerate_index.stderr +++ b/tests/ui/unused_enumerate_index.stderr @@ -8,8 +8,9 @@ LL | for (_, x) in v.iter().enumerate() { = help: to override `-D warnings` add `#[allow(clippy::unused_enumerate_index)]` help: remove the `.enumerate()` call | -LL | for x in v.iter() { - | ~ ~~~~~~~~ +LL - for (_, x) in v.iter().enumerate() { +LL + for x in v.iter() { + | error: you seem to use `.enumerate()` and immediately discard the index --> tests/ui/unused_enumerate_index.rs:59:19 @@ -19,8 +20,9 @@ LL | for (_, x) in dummy.enumerate() { | help: remove the `.enumerate()` call | -LL | for x in dummy { - | ~ ~~~~~ +LL - for (_, x) in dummy.enumerate() { +LL + for x in dummy { + | error: you seem to use `.enumerate()` and immediately discard the index --> tests/ui/unused_enumerate_index.rs:63:39 diff --git a/tests/ui/unused_format_specs.stderr b/tests/ui/unused_format_specs.stderr index df61d59130ef..d3c0530ced46 100644 --- a/tests/ui/unused_format_specs.stderr +++ b/tests/ui/unused_format_specs.stderr @@ -8,8 +8,9 @@ LL | println!("{:5}.", format_args!("")); = help: to override `-D warnings` add `#[allow(clippy::unused_format_specs)]` help: for the width to apply consider using `format!()` | -LL | println!("{:5}.", format!("")); - | ~~~~~~ +LL - println!("{:5}.", format_args!("")); +LL + println!("{:5}.", format!("")); + | help: if the current behavior is intentional, remove the format specifiers | LL - println!("{:5}.", format_args!("")); @@ -24,8 +25,9 @@ LL | println!("{:.3}", format_args!("abcde")); | help: for the precision to apply consider using `format!()` | -LL | println!("{:.3}", format!("abcde")); - | ~~~~~~ +LL - println!("{:.3}", format_args!("abcde")); +LL + println!("{:.3}", format!("abcde")); + | help: if the current behavior is intentional, remove the format specifiers | LL - println!("{:.3}", format_args!("abcde")); @@ -66,8 +68,9 @@ LL | usr_println!(true, "{:5}.", format_args!("")); | help: for the width to apply consider using `format!()` | -LL | usr_println!(true, "{:5}.", format!("")); - | ~~~~~~ +LL - usr_println!(true, "{:5}.", format_args!("")); +LL + usr_println!(true, "{:5}.", format!("")); + | help: if the current behavior is intentional, remove the format specifiers | LL - usr_println!(true, "{:5}.", format_args!("")); @@ -82,8 +85,9 @@ LL | usr_println!(true, "{:.3}", format_args!("abcde")); | help: for the precision to apply consider using `format!()` | -LL | usr_println!(true, "{:.3}", format!("abcde")); - | ~~~~~~ +LL - usr_println!(true, "{:.3}", format_args!("abcde")); +LL + usr_println!(true, "{:.3}", format!("abcde")); + | help: if the current behavior is intentional, remove the format specifiers | LL - usr_println!(true, "{:.3}", format_args!("abcde")); diff --git a/tests/ui/unused_result_ok.stderr b/tests/ui/unused_result_ok.stderr index 241e0c71261e..024aafa6bbb8 100644 --- a/tests/ui/unused_result_ok.stderr +++ b/tests/ui/unused_result_ok.stderr @@ -8,8 +8,9 @@ LL | x.parse::().ok(); = help: to override `-D warnings` add `#[allow(clippy::unused_result_ok)]` help: consider using `let _ =` and removing the call to `.ok()` instead | -LL | let _ = x.parse::(); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - x.parse::().ok(); +LL + let _ = x.parse::(); + | error: ignoring a result with `.ok()` is misleading --> tests/ui/unused_result_ok.rs:18:5 @@ -19,8 +20,9 @@ LL | x . parse::() . ok (); | help: consider using `let _ =` and removing the call to `.ok()` instead | -LL | let _ = x . parse::(); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - x . parse::() . ok (); +LL + let _ = x . parse::(); + | error: ignoring a result with `.ok()` is misleading --> tests/ui/unused_result_ok.rs:34:5 @@ -30,8 +32,9 @@ LL | v!().ok(); | help: consider using `let _ =` and removing the call to `.ok()` instead | -LL | let _ = v!(); - | ~~~~~~~~~~~~ +LL - v!().ok(); +LL + let _ = v!(); + | error: ignoring a result with `.ok()` is misleading --> tests/ui/unused_result_ok.rs:29:9 @@ -45,8 +48,9 @@ LL | w!(); = note: this error originates in the macro `w` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using `let _ =` and removing the call to `.ok()` instead | -LL | let _ = Ok::<(), ()>(()); - | ~~~~~~~~~~~~~~~~~~~~~~~~ +LL - Ok::<(), ()>(()).ok(); +LL + let _ = Ok::<(), ()>(()); + | error: aborting due to 4 previous errors From aff497f17f4264fcaaa36d4db83968bbe2b8ef19 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 10 Feb 2025 14:32:36 -0700 Subject: [PATCH 085/991] Use a separate loop to drive the check for code clusters By using a separate loop, I can just skip nodes that I don't want to process twice, instead of having to hand-build a state machine with an enum. --- clippy_lints/src/doc/mod.rs | 110 ++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 37 deletions(-) diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index c0ee904002c9..fc6d6c4282cd 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -844,6 +844,21 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ let mut cb = fake_broken_link_callback; + check_for_code_clusters( + cx, + pulldown_cmark::Parser::new_with_broken_link_callback( + &doc, + main_body_opts() - Options::ENABLE_SMART_PUNCTUATION, + Some(&mut cb), + ) + .into_offset_iter(), + &doc, + Fragments { + doc: &doc, + fragments: &fragments, + }, + ); + // disable smart punctuation to pick up ['link'] more easily let opts = main_body_opts() - Options::ENABLE_SMART_PUNCTUATION; let parser = pulldown_cmark::Parser::new_with_broken_link_callback(&doc, opts, Some(&mut cb)); @@ -867,12 +882,64 @@ enum Container { List(usize), } -#[derive(Clone, Copy, Eq, PartialEq)] -enum CodeCluster { - // true means already in a link, so only needs to be followed by code - // false means we've hit code, and need to find a link - First(usize, bool), - Nth(usize, usize), +/// Scan the documentation for code links that are back-to-back with code spans. +/// +/// This is done separately from the rest of the docs, because that makes it easier to produce +/// the correct messages. +fn check_for_code_clusters<'a, Events: Iterator, Range)>>( + cx: &LateContext<'_>, + events: Events, + doc: &str, + fragments: Fragments<'_>, +) { + let mut events = events.peekable(); + let mut code_starts_at = None; + let mut code_ends_at = None; + let mut code_includes_link = false; + while let Some((event, range)) = events.next() { + match event { + Start(Link { .. }) if matches!(events.peek(), Some((Code(_), _range))) => { + if code_starts_at.is_some() { + code_ends_at = Some(range.end); + } else { + code_starts_at = Some(range.start); + } + code_includes_link = true; + // skip the nested "code", because we're already handling it here + let _ = events.next(); + }, + Code(_) => { + if code_starts_at.is_some() { + code_ends_at = Some(range.end); + } else { + code_starts_at = Some(range.start); + } + }, + End(TagEnd::Link) => {}, + _ => { + if let Some(start) = code_starts_at + && let Some(end) = code_ends_at + && code_includes_link + { + if let Some(span) = fragments.span(cx, start..end) { + span_lint_and_then(cx, DOC_LINK_CODE, span, "code link adjacent to code text", |diag| { + let sugg = format!("{}", doc[start..end].replace('`', "")); + diag.span_suggestion_verbose( + span, + "wrap the entire group in `` tags", + sugg, + Applicability::MaybeIncorrect, + ); + diag.help("separate code snippets will be shown with a gap"); + }); + } + } + code_includes_link = false; + code_starts_at = None; + code_ends_at = None; + }, + } + } } /// Checks parsed documentation. @@ -906,40 +973,9 @@ fn check_doc<'a, Events: Iterator, Range { - Some(CodeCluster::First(range.start - 1, true)) - }, - (None, Code(_)) => Some(CodeCluster::First(range.start, false)), - (Some(CodeCluster::First(pos, _)), Start(Link { .. })) | (Some(CodeCluster::First(pos, true)), Code(_)) => { - Some(CodeCluster::Nth(pos, range.end)) - }, - (Some(CodeCluster::Nth(start, end)), Code(_) | Start(Link { .. })) => { - Some(CodeCluster::Nth(start, range.end.max(end))) - }, - (code_cluster @ Some(_), Code(_) | End(TagEnd::Link)) => code_cluster, - (Some(CodeCluster::First(_, _)) | None, _) => None, - (Some(CodeCluster::Nth(start, end)), _) => { - if let Some(span) = fragments.span(cx, start..end) { - span_lint_and_then(cx, DOC_LINK_CODE, span, "code link adjacent to code text", |diag| { - let sugg = format!("{}", doc[start..end].replace('`', "")); - diag.span_suggestion_verbose( - span, - "wrap the entire group in `` tags", - sugg, - Applicability::MaybeIncorrect, - ); - diag.help("separate code snippets will be shown with a gap"); - }); - } - None - }, - }; match event { Html(tag) | InlineHtml(tag) => { if tag.starts_with(" Date: Sun, 12 Jan 2025 00:01:53 +0000 Subject: [PATCH 086/991] Use MIR body to identify more "default equivalent" calls When looking for `Default` impls that could be derived, we look at the body of their `fn default()` and if it is an fn call or literal we check if they are equivalent to what `#[derive(Default)]` would have used. Now, when checking those fn calls in the `fn default()` body, we also compare against the corresponding type's `Default::default` body to see if our call is equivalent to that one. For example, given ```rust struct S; impl S { fn new() -> S { S } } impl Default for S { fn default() -> S { S::new() } } ``` `::default()` and `S::new()` are considered equivalent. Given that, if the user also writes ```rust struct R { s: S, } impl Default for R { fn default() -> R { R { s: S::new() } } } ``` the `derivable_impls` lint will now trigger. --- clippy_lints/src/methods/or_fun_call.rs | 2 +- clippy_utils/src/lib.rs | 96 ++++++++++++++++++++++--- tests/ui/derivable_impls.fixed | 34 +++++++++ tests/ui/derivable_impls.rs | 49 +++++++++++++ tests/ui/derivable_impls.stderr | 57 ++++++++++++++- tests/ui/mem_replace.fixed | 2 + tests/ui/mem_replace.rs | 2 + tests/ui/mem_replace.stderr | 56 +++++++++------ 8 files changed, 264 insertions(+), 34 deletions(-) diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index 6b39b753885e..f00e4b87a7df 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -104,7 +104,7 @@ pub(super) fn check<'tcx>( if (is_new(fun) && output_type_implements_default(fun)) || match call_expr { Some(call_expr) => is_default_equivalent(cx, call_expr), - None => is_default_equivalent_call(cx, fun) || closure_body_returns_empty_to_string(cx, fun), + None => is_default_equivalent_call(cx, fun, None) || closure_body_returns_empty_to_string(cx, fun), } { span_lint_and_sugg( diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 80d52a26e223..0d9502c50db6 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -113,6 +113,7 @@ use rustc_hir::{ use rustc_lexer::{TokenKind, tokenize}; use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::place::PlaceBase; +use rustc_middle::mir::{AggregateKind, Operand, RETURN_PLACE, Rvalue, StatementKind, TerminatorKind}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::layout::IntegerExt; @@ -919,22 +920,101 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath< } /// Returns true if the expr is equal to `Default::default` when evaluated. -pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) -> bool { +pub fn is_default_equivalent_call( + cx: &LateContext<'_>, + repl_func: &Expr<'_>, + whole_call_expr: Option<&Expr<'_>>, +) -> bool { if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind && let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id() && (is_diag_trait_item(cx, repl_def_id, sym::Default) || is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath)) { - true - } else { - false + return true; } + + // Get the type of the whole method call expression, find the exact method definition, look at + // its body and check if it is similar to the corresponding `Default::default()` body. + let Some(e) = whole_call_expr else { return false }; + let Some(default_fn_def_id) = cx.tcx.get_diagnostic_item(sym::default_fn) else { + return false; + }; + let Some(ty) = cx.tcx.typeck(e.hir_id.owner.def_id).expr_ty_adjusted_opt(e) else { + return false; + }; + let args = rustc_ty::GenericArgs::for_item(cx.tcx, default_fn_def_id, |param, _| { + if let rustc_ty::GenericParamDefKind::Lifetime = param.kind { + cx.tcx.lifetimes.re_erased.into() + } else if param.index == 0 && param.name == kw::SelfUpper { + ty.into() + } else { + param.to_error(cx.tcx) + } + }); + let instance = rustc_ty::Instance::try_resolve(cx.tcx, cx.typing_env(), default_fn_def_id, args); + + let Ok(Some(instance)) = instance else { return false }; + if let rustc_ty::InstanceKind::Item(def) = instance.def + && !cx.tcx.is_mir_available(def) + { + return false; + } + let ExprKind::Path(ref repl_func_qpath) = repl_func.kind else { + return false; + }; + let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id() else { + return false; + }; + + // Get the MIR Body for the `::default()` function. + // If it is a value or call (either fn or ctor), we compare its `DefId` against the one for the + // resolution of the expression we had in the path. This lets us identify, for example, that + // the body of ` as Default>::default()` is a `Vec::new()`, and the field was being + // initialized to `Vec::new()` as well. + let body = cx.tcx.instance_mir(instance.def); + for block_data in body.basic_blocks.iter() { + if block_data.statements.len() == 1 + && let StatementKind::Assign(assign) = &block_data.statements[0].kind + && assign.0.local == RETURN_PLACE + && let Rvalue::Aggregate(kind, _places) = &assign.1 + && let AggregateKind::Adt(did, variant_index, _, _, _) = &**kind + && let def = cx.tcx.adt_def(did) + && let variant = &def.variant(*variant_index) + && variant.fields.is_empty() + && let Some((_, did)) = variant.ctor + && did == repl_def_id + { + return true; + } else if block_data.statements.is_empty() + && let Some(term) = &block_data.terminator + { + match &term.kind { + TerminatorKind::Call { + func: Operand::Constant(c), + .. + } if let rustc_ty::FnDef(did, _args) = c.ty().kind() + && *did == repl_def_id => + { + return true; + }, + TerminatorKind::TailCall { + func: Operand::Constant(c), + .. + } if let rustc_ty::FnDef(did, _args) = c.ty().kind() + && *did == repl_def_id => + { + return true; + }, + _ => {}, + } + } + } + false } -/// Returns true if the expr is equal to `Default::default()` of it's type when evaluated. +/// Returns true if the expr is equal to `Default::default()` of its type when evaluated. /// -/// It doesn't cover all cases, for example indirect function calls (some of std -/// functions are supported) but it is the best we have. +/// It doesn't cover all cases, like struct literals, but it is a close approximation. pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { match &e.kind { ExprKind::Lit(lit) => match lit.node { @@ -955,7 +1035,7 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { false } }, - ExprKind::Call(repl_func, []) => is_default_equivalent_call(cx, repl_func), + ExprKind::Call(repl_func, []) => is_default_equivalent_call(cx, repl_func, Some(e)), ExprKind::Call(from_func, [arg]) => is_default_equivalent_from(cx, from_func, arg), ExprKind::Path(qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, e.hir_id), OptionNone), ExprKind::AddrOf(rustc_hir::BorrowKind::Ref, _, expr) => matches!(expr.kind, ExprKind::Array([])), diff --git a/tests/ui/derivable_impls.fixed b/tests/ui/derivable_impls.fixed index c85f384fd6eb..65bfded38835 100644 --- a/tests/ui/derivable_impls.fixed +++ b/tests/ui/derivable_impls.fixed @@ -144,6 +144,40 @@ impl Default for SpecializedImpl2 { } } +#[derive(Default)] +pub struct DirectDefaultDefaultCall { + v: Vec, +} + + +#[derive(Default)] +pub struct EquivalentToDefaultDefaultCallVec { + v: Vec, +} + + +pub struct S { + x: i32, +} + +impl S { + fn new() -> S { + S { x: 42 } + } +} + +impl Default for S { + fn default() -> Self { + Self::new() + } +} + +#[derive(Default)] +pub struct EquivalentToDefaultDefaultCallLocal { + v: S, +} + + // https://github.com/rust-lang/rust-clippy/issues/7654 pub struct Color { diff --git a/tests/ui/derivable_impls.rs b/tests/ui/derivable_impls.rs index 21d73ba8b777..eb9a007bf10f 100644 --- a/tests/ui/derivable_impls.rs +++ b/tests/ui/derivable_impls.rs @@ -181,6 +181,55 @@ impl Default for SpecializedImpl2 { } } +pub struct DirectDefaultDefaultCall { + v: Vec, +} + +impl Default for DirectDefaultDefaultCall { + fn default() -> Self { + // When calling `Default::default()` in all fields, we know it is the same as deriving. + Self { v: Default::default() } + } +} + +pub struct EquivalentToDefaultDefaultCallVec { + v: Vec, +} + +impl Default for EquivalentToDefaultDefaultCallVec { + fn default() -> Self { + // The body of `::default()` is `Vec::new()`, so they are equivalent. + Self { v: Vec::new() } + } +} + +pub struct S { + x: i32, +} + +impl S { + fn new() -> S { + S { x: 42 } + } +} + +impl Default for S { + fn default() -> Self { + Self::new() + } +} + +pub struct EquivalentToDefaultDefaultCallLocal { + v: S, +} + +impl Default for EquivalentToDefaultDefaultCallLocal { + fn default() -> Self { + // The body of `::default()` is `S::new()`, so they are equivalent. + Self { v: S::new() } + } +} + // https://github.com/rust-lang/rust-clippy/issues/7654 pub struct Color { diff --git a/tests/ui/derivable_impls.stderr b/tests/ui/derivable_impls.stderr index 0caea892358a..a14c0b28c4ea 100644 --- a/tests/ui/derivable_impls.stderr +++ b/tests/ui/derivable_impls.stderr @@ -98,7 +98,58 @@ LL ~ struct WithoutSelfParan(bool); | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:216:1 + --> tests/ui/derivable_impls.rs:188:1 + | +LL | / impl Default for DirectDefaultDefaultCall { +LL | | fn default() -> Self { +LL | | // When calling `Default::default()` in all fields, we know it is the same as deriving. +LL | | Self { v: Default::default() } +LL | | } +LL | | } + | |_^ + | +help: replace the manual implementation with a derive attribute + | +LL + #[derive(Default)] +LL ~ pub struct DirectDefaultDefaultCall { + | + +error: this `impl` can be derived + --> tests/ui/derivable_impls.rs:199:1 + | +LL | / impl Default for EquivalentToDefaultDefaultCallVec { +LL | | fn default() -> Self { +LL | | // The body of `::default()` is `Vec::new()`, so they are equivalent. +LL | | Self { v: Vec::new() } +LL | | } +LL | | } + | |_^ + | +help: replace the manual implementation with a derive attribute + | +LL + #[derive(Default)] +LL ~ pub struct EquivalentToDefaultDefaultCallVec { + | + +error: this `impl` can be derived + --> tests/ui/derivable_impls.rs:226:1 + | +LL | / impl Default for EquivalentToDefaultDefaultCallLocal { +LL | | fn default() -> Self { +LL | | // The body of `::default()` is `S::new()`, so they are equivalent. +LL | | Self { v: S::new() } +LL | | } +LL | | } + | |_^ + | +help: replace the manual implementation with a derive attribute + | +LL + #[derive(Default)] +LL ~ pub struct EquivalentToDefaultDefaultCallLocal { + | + +error: this `impl` can be derived + --> tests/ui/derivable_impls.rs:265:1 | LL | / impl Default for RepeatDefault1 { LL | | fn default() -> Self { @@ -114,7 +165,7 @@ LL ~ pub struct RepeatDefault1 { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:250:1 + --> tests/ui/derivable_impls.rs:299:1 | LL | / impl Default for SimpleEnum { LL | | fn default() -> Self { @@ -132,5 +183,5 @@ LL ~ #[default] LL ~ Bar, | -error: aborting due to 8 previous errors +error: aborting due to 11 previous errors diff --git a/tests/ui/mem_replace.fixed b/tests/ui/mem_replace.fixed index 4210dbbe82d3..248ecd5d85f4 100644 --- a/tests/ui/mem_replace.fixed +++ b/tests/ui/mem_replace.fixed @@ -18,10 +18,12 @@ fn replace_option_with_none() { fn replace_with_default() { let mut s = String::from("foo"); let _ = std::mem::take(&mut s); + let _ = std::mem::take(&mut s); let s = &mut String::from("foo"); let _ = std::mem::take(s); let _ = std::mem::take(s); + let _ = std::mem::take(s); let mut v = vec![123]; let _ = std::mem::take(&mut v); diff --git a/tests/ui/mem_replace.rs b/tests/ui/mem_replace.rs index bd7ad78b2af2..486d2ba1b6a5 100644 --- a/tests/ui/mem_replace.rs +++ b/tests/ui/mem_replace.rs @@ -18,9 +18,11 @@ fn replace_option_with_none() { fn replace_with_default() { let mut s = String::from("foo"); let _ = std::mem::replace(&mut s, String::default()); + let _ = std::mem::replace(&mut s, String::new()); let s = &mut String::from("foo"); let _ = std::mem::replace(s, String::default()); + let _ = std::mem::replace(s, String::new()); let _ = std::mem::replace(s, Default::default()); let mut v = vec![123]; diff --git a/tests/ui/mem_replace.stderr b/tests/ui/mem_replace.stderr index c33f80b01b85..a60f2253d13e 100644 --- a/tests/ui/mem_replace.stderr +++ b/tests/ui/mem_replace.stderr @@ -23,130 +23,142 @@ LL | let _ = std::mem::replace(&mut s, String::default()); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:23:13 + --> tests/ui/mem_replace.rs:21:13 + | +LL | let _ = std::mem::replace(&mut s, String::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)` + +error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` + --> tests/ui/mem_replace.rs:24:13 | LL | let _ = std::mem::replace(s, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:24:13 + --> tests/ui/mem_replace.rs:25:13 + | +LL | let _ = std::mem::replace(s, String::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)` + +error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` + --> tests/ui/mem_replace.rs:26:13 | LL | let _ = std::mem::replace(s, Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:27:13 + --> tests/ui/mem_replace.rs:29:13 | LL | let _ = std::mem::replace(&mut v, Vec::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:28:13 + --> tests/ui/mem_replace.rs:30:13 | LL | let _ = std::mem::replace(&mut v, Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:29:13 + --> tests/ui/mem_replace.rs:31:13 | LL | let _ = std::mem::replace(&mut v, Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:30:13 + --> tests/ui/mem_replace.rs:32:13 | LL | let _ = std::mem::replace(&mut v, vec![]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:33:13 + --> tests/ui/mem_replace.rs:35:13 | LL | let _ = std::mem::replace(&mut hash_map, HashMap::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_map)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:36:13 + --> tests/ui/mem_replace.rs:38:13 | LL | let _ = std::mem::replace(&mut btree_map, BTreeMap::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_map)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:39:13 + --> tests/ui/mem_replace.rs:41:13 | LL | let _ = std::mem::replace(&mut vd, VecDeque::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut vd)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:42:13 + --> tests/ui/mem_replace.rs:44:13 | LL | let _ = std::mem::replace(&mut hash_set, HashSet::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_set)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:45:13 + --> tests/ui/mem_replace.rs:47:13 | LL | let _ = std::mem::replace(&mut btree_set, BTreeSet::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_set)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:48:13 + --> tests/ui/mem_replace.rs:50:13 | LL | let _ = std::mem::replace(&mut list, LinkedList::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut list)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:51:13 + --> tests/ui/mem_replace.rs:53:13 | LL | let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut binary_heap)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:54:13 + --> tests/ui/mem_replace.rs:56:13 | LL | let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut tuple)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:57:13 + --> tests/ui/mem_replace.rs:59:13 | LL | let _ = std::mem::replace(&mut refstr, ""); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut refstr)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:60:13 + --> tests/ui/mem_replace.rs:62:13 | LL | let _ = std::mem::replace(&mut slice, &[]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut slice)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:96:13 + --> tests/ui/mem_replace.rs:98:13 | LL | let _ = std::mem::replace(&mut s, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)` error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:126:13 + --> tests/ui/mem_replace.rs:128:13 | LL | let _ = std::mem::replace(&mut f.0, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()` error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:127:13 + --> tests/ui/mem_replace.rs:129:13 | LL | let _ = std::mem::replace(&mut *f, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()` error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:128:13 + --> tests/ui/mem_replace.rs:130:13 | LL | let _ = std::mem::replace(&mut b.opt, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:130:13 + --> tests/ui/mem_replace.rs:132:13 | LL | let _ = std::mem::replace(&mut b.val, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)` -error: aborting due to 24 previous errors +error: aborting due to 26 previous errors From 005508ef054a40a1437e61768b52fe1149d5b98d Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 11 Feb 2025 05:05:16 +0000 Subject: [PATCH 087/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index dd48038e07a0..48458cdcbc3d 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -e0607238c95df66e3d25a6c17aebe18c6726fc74 +6171d944aea415a3023d4262e0895aa3b18c771f From 7139436f98045b515db7f15a65cafe5afc5b7527 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Tue, 11 Feb 2025 03:13:16 +0900 Subject: [PATCH 088/991] add index checks for the slice in `manual_slice_fill` --- clippy_lints/src/loops/manual_slice_fill.rs | 7 ++++++- tests/ui/manual_slice_fill.fixed | 18 +++++++++++++++++- tests/ui/manual_slice_fill.rs | 18 +++++++++++++++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/loops/manual_slice_fill.rs b/clippy_lints/src/loops/manual_slice_fill.rs index 7c6564235796..bece83eaf3d8 100644 --- a/clippy_lints/src/loops/manual_slice_fill.rs +++ b/clippy_lints/src/loops/manual_slice_fill.rs @@ -4,6 +4,7 @@ use clippy_utils::macros::span_is_local; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{HasSession, snippet_with_applicability}; use clippy_utils::ty::implements_trait; +use clippy_utils::visitors::is_local_used; use clippy_utils::{higher, peel_blocks_with_stmt, span_contains_comment}; use rustc_ast::ast::LitKind; use rustc_ast::{RangeLimits, UnOp}; @@ -43,7 +44,7 @@ pub(super) fn check<'tcx>( && let ExprKind::Block(..) = body.kind // Check if the body is an assignment to a slice element. && let ExprKind::Assign(assignee, assignval, _) = peel_blocks_with_stmt(body).kind - && let ExprKind::Index(slice, _, _) = assignee.kind + && let ExprKind::Index(slice, idx, _) = assignee.kind // Check if `len()` is used for the range end. && let ExprKind::MethodCall(path, recv,..) = end.kind && path.ident.name == sym::len @@ -58,6 +59,10 @@ pub(super) fn check<'tcx>( // The `fill` method requires that the slice's element type implements the `Clone` trait. && let Some(clone_trait) = cx.tcx.lang_items().clone_trait() && implements_trait(cx, cx.typeck_results().expr_ty(slice), clone_trait, &[]) + // https://github.com/rust-lang/rust-clippy/issues/14192 + && let ExprKind::Path(Resolved(_, idx_path)) = idx.kind + && let Res::Local(idx_hir) = idx_path.res + && !is_local_used(cx, assignval, idx_hir) { sugg(cx, body, expr, slice.span, assignval.span); } diff --git a/tests/ui/manual_slice_fill.fixed b/tests/ui/manual_slice_fill.fixed index 397a156a2dc7..80e271117fc1 100644 --- a/tests/ui/manual_slice_fill.fixed +++ b/tests/ui/manual_slice_fill.fixed @@ -1,5 +1,5 @@ #![warn(clippy::manual_slice_fill)] -#![allow(clippy::needless_range_loop)] +#![allow(clippy::needless_range_loop, clippy::useless_vec)] macro_rules! assign_element { ($slice:ident, $index:expr) => { @@ -99,3 +99,19 @@ fn should_not_lint() { *i = None; } } + +fn issue_14192() { + let mut tmp = vec![0; 3]; + + for i in 0..tmp.len() { + tmp[i] = i; + } + + for i in 0..tmp.len() { + tmp[i] = 2 + i; + } + + for i in 0..tmp.len() { + tmp[0] = i; + } +} diff --git a/tests/ui/manual_slice_fill.rs b/tests/ui/manual_slice_fill.rs index c25127ca613a..75a391f4243c 100644 --- a/tests/ui/manual_slice_fill.rs +++ b/tests/ui/manual_slice_fill.rs @@ -1,5 +1,5 @@ #![warn(clippy::manual_slice_fill)] -#![allow(clippy::needless_range_loop)] +#![allow(clippy::needless_range_loop, clippy::useless_vec)] macro_rules! assign_element { ($slice:ident, $index:expr) => { @@ -108,3 +108,19 @@ fn should_not_lint() { *i = None; } } + +fn issue_14192() { + let mut tmp = vec![0; 3]; + + for i in 0..tmp.len() { + tmp[i] = i; + } + + for i in 0..tmp.len() { + tmp[i] = 2 + i; + } + + for i in 0..tmp.len() { + tmp[0] = i; + } +} From ac15a10b55580065320e48b29b6ff0ea36d8093a Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 6 Feb 2025 15:38:28 -0700 Subject: [PATCH 089/991] just_underscores_and_digits: ignore empty ident Empty idents come from error recovery, and should imply that a better error has already been emitted. --- clippy_dev/src/fmt.rs | 9 +++++++-- clippy_lints/src/non_expressive_names.rs | 3 ++- .../non_expressive_names_error_recovery.fixed | 8 ++++++++ .../non_expressive_names_error_recovery.rs | 8 ++++++++ .../non_expressive_names_error_recovery.stderr | 13 +++++++++++++ 5 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.fixed create mode 100644 tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.rs create mode 100644 tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.stderr diff --git a/clippy_dev/src/fmt.rs b/clippy_dev/src/fmt.rs index 790dafa811f9..bdddf46a2cb1 100644 --- a/clippy_dev/src/fmt.rs +++ b/clippy_dev/src/fmt.rs @@ -290,8 +290,13 @@ fn run_rustfmt(context: &FmtContext) -> Result<(), Error> { .filter_map(|entry| { let entry = entry.expect("failed to find tests"); let path = entry.path(); - - if path.extension() != Some("rs".as_ref()) || entry.file_name() == "ice-3891.rs" { + if path.extension() != Some("rs".as_ref()) + || path + .components() + .nth_back(1) + .is_some_and(|c| c.as_os_str() == "syntax-error-recovery") + || entry.file_name() == "ice-3891.rs" + { None } else { Some(entry.into_path().into_os_string()) diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index 1a3b43cbb10a..c5873589b26f 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -208,7 +208,8 @@ impl SimilarNamesNameVisitor<'_, '_, '_> { fn check_ident(&mut self, ident: Ident) { let interned_name = ident.name.as_str(); - if interned_name.chars().any(char::is_uppercase) { + // name can be empty if it comes from recovery + if interned_name.chars().any(char::is_uppercase) || interned_name.is_empty() { return; } if interned_name.chars().all(|c| c.is_ascii_digit() || c == '_') { diff --git a/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.fixed b/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.fixed new file mode 100644 index 000000000000..5e5821a140de --- /dev/null +++ b/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.fixed @@ -0,0 +1,8 @@ +// https://github.com/rust-lang/rust-clippy/issues/12302 +use std::marker::PhantomData; + +pub struct Aa(PhantomData); + +fn aa(a: Aa) { + +} diff --git a/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.rs b/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.rs new file mode 100644 index 000000000000..d6e1da0e0898 --- /dev/null +++ b/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.rs @@ -0,0 +1,8 @@ +// https://github.com/rust-lang/rust-clippy/issues/12302 +use std::marker::PhantomData; + +pub struct Aa(PhantomData); + +fn aa(a: Aa`, found `)` + --> tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.rs:6:19 + | +LL | fn aa(a: Aa) { + | + + +error: aborting due to 1 previous error + From da6a05977dd0a9a8fd973b3d08937e9b81d7e2ab Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Tue, 11 Feb 2025 18:32:10 +0100 Subject: [PATCH 090/991] `{expect,unwrap}_used`: add options to lint at compilation time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default, do not lint `.unwrap()` and `.expect(…)` in always const contexts, as a failure would be detected at compile time anyway. New options `allow_expect_in_consts` and `allow_unwrap_in_consts`, defaulting to `true`, can be turned unset to still lint in always const contexts. --- CHANGELOG.md | 2 ++ book/src/lint_configuration.md | 20 +++++++++++++++++ clippy_config/src/conf.rs | 6 +++++ clippy_lints/src/methods/mod.rs | 9 ++++++++ .../src/methods/unwrap_expect_used.rs | 7 +++++- tests/ui-toml/expect_used/clippy.toml | 1 + tests/ui-toml/expect_used/expect_used.rs | 9 ++++++++ tests/ui-toml/expect_used/expect_used.stderr | 22 ++++++++++++++++--- .../toml_unknown_key/conf_unknown_key.stderr | 6 +++++ tests/ui-toml/unwrap_used/clippy.toml | 1 + .../ui-toml/unwrap_used/unwrap_used_const.rs | 11 ++++++++++ .../unwrap_used/unwrap_used_const.stderr | 22 +++++++++++++++++++ tests/ui/unwrap_expect_used.rs | 11 ++++++++++ 13 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 tests/ui-toml/unwrap_used/unwrap_used_const.rs create mode 100644 tests/ui-toml/unwrap_used/unwrap_used_const.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index ea1119aca984..14f61fb1cd91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6268,6 +6268,7 @@ Released 2018-09-13 [`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement [`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero [`allow-dbg-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-dbg-in-tests +[`allow-expect-in-consts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-consts [`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests [`allow-indexing-slicing-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-indexing-slicing-in-tests [`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args @@ -6276,6 +6277,7 @@ Released 2018-09-13 [`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests [`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception [`allow-renamed-params-for`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-renamed-params-for +[`allow-unwrap-in-consts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-consts [`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests [`allow-useless-vec-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-useless-vec-in-tests [`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index f43c3a280727..978fb4f3b34d 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -71,6 +71,16 @@ Whether `dbg!` should be allowed in test functions or `#[cfg(test)]` * [`dbg_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro) +## `allow-expect-in-consts` +Whether `expect` should be allowed in code always evaluated at compile time + +**Default Value:** `true` + +--- +**Affected lints:** +* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used) + + ## `allow-expect-in-tests` Whether `expect` should be allowed in test functions or `#[cfg(test)]` @@ -164,6 +174,16 @@ default configuration of Clippy. By default, any configuration will replace the * [`renamed_function_params`](https://rust-lang.github.io/rust-clippy/master/index.html#renamed_function_params) +## `allow-unwrap-in-consts` +Whether `unwrap` should be allowed in code always evaluated at compile time + +**Default Value:** `true` + +--- +**Affected lints:** +* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used) + + ## `allow-unwrap-in-tests` Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 28e42c67d980..e2f5574d5669 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -288,6 +288,9 @@ define_Conf! { /// Whether `dbg!` should be allowed in test functions or `#[cfg(test)]` #[lints(dbg_macro)] allow_dbg_in_tests: bool = false, + /// Whether `expect` should be allowed in code always evaluated at compile time + #[lints(expect_used)] + allow_expect_in_consts: bool = true, /// Whether `expect` should be allowed in test functions or `#[cfg(test)]` #[lints(expect_used)] allow_expect_in_tests: bool = false, @@ -325,6 +328,9 @@ define_Conf! { #[lints(renamed_function_params)] allow_renamed_params_for: Vec = DEFAULT_ALLOWED_TRAITS_WITH_RENAMED_PARAMS.iter().map(ToString::to_string).collect(), + /// Whether `unwrap` should be allowed in code always evaluated at compile time + #[lints(unwrap_used)] + allow_unwrap_in_consts: bool = true, /// Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` #[lints(unwrap_used)] allow_unwrap_in_tests: bool = false, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index f151dedc2448..7d33f3de57d6 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -4406,11 +4406,14 @@ declare_clippy_lint! { "using `Option::and_then` or `Result::and_then` to chain a computation that returns an `Option` or a `Result`" } +#[expect(clippy::struct_excessive_bools)] pub struct Methods { avoid_breaking_exported_api: bool, msrv: Msrv, allow_expect_in_tests: bool, allow_unwrap_in_tests: bool, + allow_expect_in_consts: bool, + allow_unwrap_in_consts: bool, allowed_dotfiles: FxHashSet<&'static str>, format_args: FormatArgsStorage, } @@ -4425,6 +4428,8 @@ impl Methods { msrv: conf.msrv.clone(), allow_expect_in_tests: conf.allow_expect_in_tests, allow_unwrap_in_tests: conf.allow_unwrap_in_tests, + allow_expect_in_consts: conf.allow_expect_in_consts, + allow_unwrap_in_consts: conf.allow_unwrap_in_consts, allowed_dotfiles, format_args, } @@ -4918,6 +4923,7 @@ impl Methods { expr, recv, false, + self.allow_expect_in_consts, self.allow_expect_in_tests, unwrap_expect_used::Variant::Expect, ), @@ -4931,6 +4937,7 @@ impl Methods { expr, recv, true, + self.allow_expect_in_consts, self.allow_expect_in_tests, unwrap_expect_used::Variant::Expect, ); @@ -5304,6 +5311,7 @@ impl Methods { expr, recv, false, + self.allow_unwrap_in_consts, self.allow_unwrap_in_tests, unwrap_expect_used::Variant::Unwrap, ); @@ -5315,6 +5323,7 @@ impl Methods { expr, recv, true, + self.allow_unwrap_in_consts, self.allow_unwrap_in_tests, unwrap_expect_used::Variant::Unwrap, ); diff --git a/clippy_lints/src/methods/unwrap_expect_used.rs b/clippy_lints/src/methods/unwrap_expect_used.rs index 5b0bd0f716ab..027215e3b4d7 100644 --- a/clippy_lints/src/methods/unwrap_expect_used.rs +++ b/clippy_lints/src/methods/unwrap_expect_used.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::{is_never_like, is_type_diagnostic_item}; -use clippy_utils::{is_in_test, is_lint_allowed}; +use clippy_utils::{is_in_test, is_inside_always_const_context, is_lint_allowed}; use rustc_hir::Expr; use rustc_lint::{LateContext, Lint}; use rustc_middle::ty; @@ -39,6 +39,7 @@ pub(super) fn check( expr: &Expr<'_>, recv: &Expr<'_>, is_err: bool, + allow_unwrap_in_consts: bool, allow_unwrap_in_tests: bool, variant: Variant, ) { @@ -65,6 +66,10 @@ pub(super) fn check( return; } + if allow_unwrap_in_consts && is_inside_always_const_context(cx.tcx, expr.hir_id) { + return; + } + span_lint_and_then( cx, variant.lint(), diff --git a/tests/ui-toml/expect_used/clippy.toml b/tests/ui-toml/expect_used/clippy.toml index 6933b8164195..895de8357cf7 100644 --- a/tests/ui-toml/expect_used/clippy.toml +++ b/tests/ui-toml/expect_used/clippy.toml @@ -1 +1,2 @@ +allow-expect-in-consts = false allow-expect-in-tests = true diff --git a/tests/ui-toml/expect_used/expect_used.rs b/tests/ui-toml/expect_used/expect_used.rs index 206788e19f02..f0b92329f97a 100644 --- a/tests/ui-toml/expect_used/expect_used.rs +++ b/tests/ui-toml/expect_used/expect_used.rs @@ -1,4 +1,5 @@ //@compile-flags: --test +//@no-rustfix #![warn(clippy::expect_used)] #![allow(clippy::unnecessary_literal_unwrap)] @@ -15,6 +16,14 @@ fn expect_result() { fn main() { expect_option(); expect_result(); + + const SOME: Option = Some(3); + const UNWRAPPED: i32 = SOME.expect("Not three?"); + //~^ ERROR: used `expect()` on an `Option` value + const { + SOME.expect("Still not three?"); + //~^ ERROR: used `expect()` on an `Option` value + } } #[test] diff --git a/tests/ui-toml/expect_used/expect_used.stderr b/tests/ui-toml/expect_used/expect_used.stderr index 81691f8ac6c0..b28bb7b7e0d1 100644 --- a/tests/ui-toml/expect_used/expect_used.stderr +++ b/tests/ui-toml/expect_used/expect_used.stderr @@ -1,5 +1,5 @@ error: used `expect()` on an `Option` value - --> tests/ui-toml/expect_used/expect_used.rs:7:13 + --> tests/ui-toml/expect_used/expect_used.rs:8:13 | LL | let _ = opt.expect(""); | ^^^^^^^^^^^^^^ @@ -9,12 +9,28 @@ LL | let _ = opt.expect(""); = help: to override `-D warnings` add `#[allow(clippy::expect_used)]` error: used `expect()` on a `Result` value - --> tests/ui-toml/expect_used/expect_used.rs:12:13 + --> tests/ui-toml/expect_used/expect_used.rs:13:13 | LL | let _ = res.expect(""); | ^^^^^^^^^^^^^^ | = note: if this value is an `Err`, it will panic -error: aborting due to 2 previous errors +error: used `expect()` on an `Option` value + --> tests/ui-toml/expect_used/expect_used.rs:21:28 + | +LL | const UNWRAPPED: i32 = SOME.expect("Not three?"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: if this value is `None`, it will panic + +error: used `expect()` on an `Option` value + --> tests/ui-toml/expect_used/expect_used.rs:24:9 + | +LL | SOME.expect("Still not three?"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: if this value is `None`, it will panic + +error: aborting due to 4 previous errors diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 01e9f5c26a37..842059df1e92 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -5,6 +5,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect accept-comment-above-statement allow-comparison-to-zero allow-dbg-in-tests + allow-expect-in-consts allow-expect-in-tests allow-indexing-slicing-in-tests allow-mixed-uninlined-format-args @@ -13,6 +14,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect allow-print-in-tests allow-private-module-inception allow-renamed-params-for + allow-unwrap-in-consts allow-unwrap-in-tests allow-useless-vec-in-tests allowed-dotfiles @@ -94,6 +96,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect accept-comment-above-statement allow-comparison-to-zero allow-dbg-in-tests + allow-expect-in-consts allow-expect-in-tests allow-indexing-slicing-in-tests allow-mixed-uninlined-format-args @@ -102,6 +105,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect allow-print-in-tests allow-private-module-inception allow-renamed-params-for + allow-unwrap-in-consts allow-unwrap-in-tests allow-useless-vec-in-tests allowed-dotfiles @@ -183,6 +187,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni accept-comment-above-statement allow-comparison-to-zero allow-dbg-in-tests + allow-expect-in-consts allow-expect-in-tests allow-indexing-slicing-in-tests allow-mixed-uninlined-format-args @@ -191,6 +196,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni allow-print-in-tests allow-private-module-inception allow-renamed-params-for + allow-unwrap-in-consts allow-unwrap-in-tests allow-useless-vec-in-tests allowed-dotfiles diff --git a/tests/ui-toml/unwrap_used/clippy.toml b/tests/ui-toml/unwrap_used/clippy.toml index 154626ef4e81..6fd1eb6f8d0d 100644 --- a/tests/ui-toml/unwrap_used/clippy.toml +++ b/tests/ui-toml/unwrap_used/clippy.toml @@ -1 +1,2 @@ +allow-unwrap-in-consts = false allow-unwrap-in-tests = true diff --git a/tests/ui-toml/unwrap_used/unwrap_used_const.rs b/tests/ui-toml/unwrap_used/unwrap_used_const.rs new file mode 100644 index 000000000000..c7d8e8c1ffb5 --- /dev/null +++ b/tests/ui-toml/unwrap_used/unwrap_used_const.rs @@ -0,0 +1,11 @@ +#![warn(clippy::unwrap_used)] + +fn main() { + const SOME: Option = Some(3); + const UNWRAPPED: i32 = SOME.unwrap(); + //~^ ERROR: used `unwrap()` on an `Option` value + const { + SOME.unwrap(); + //~^ ERROR: used `unwrap()` on an `Option` value + } +} diff --git a/tests/ui-toml/unwrap_used/unwrap_used_const.stderr b/tests/ui-toml/unwrap_used/unwrap_used_const.stderr new file mode 100644 index 000000000000..362b41bc1bff --- /dev/null +++ b/tests/ui-toml/unwrap_used/unwrap_used_const.stderr @@ -0,0 +1,22 @@ +error: used `unwrap()` on an `Option` value + --> tests/ui-toml/unwrap_used/unwrap_used_const.rs:5:28 + | +LL | const UNWRAPPED: i32 = SOME.unwrap(); + | ^^^^^^^^^^^^^ + | + = note: if this value is `None`, it will panic + = help: consider using `expect()` to provide a better panic message + = note: `-D clippy::unwrap-used` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]` + +error: used `unwrap()` on an `Option` value + --> tests/ui-toml/unwrap_used/unwrap_used_const.rs:8:9 + | +LL | SOME.unwrap(); + | ^^^^^^^^^^^^^ + | + = note: if this value is `None`, it will panic + = help: consider using `expect()` to provide a better panic message + +error: aborting due to 2 previous errors + diff --git a/tests/ui/unwrap_expect_used.rs b/tests/ui/unwrap_expect_used.rs index a56bd0a8d079..bab99f2ffbdd 100644 --- a/tests/ui/unwrap_expect_used.rs +++ b/tests/ui/unwrap_expect_used.rs @@ -50,4 +50,15 @@ fn main() { //~^ ERROR: used `unwrap_err()` on a `Result` value a.expect_err("Hello error!"); //~^ ERROR: used `expect_err()` on a `Result` value + + // Don't trigger in compile time contexts by default + const SOME: Option = Some(3); + const UNWRAPPED: i32 = SOME.unwrap(); + const EXPECTED: i32 = SOME.expect("Not three?"); + const { + SOME.unwrap(); + } + const { + SOME.expect("Still not three?"); + } } From 8b6de49ef74de5bc5485ccb507178fa72dff9c87 Mon Sep 17 00:00:00 2001 From: jonathan Date: Mon, 27 Jan 2025 21:50:22 +0100 Subject: [PATCH 091/991] New lint: `unbuffered_bytes` --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/methods/mod.rs | 30 ++++++++++++++++ clippy_lints/src/methods/unbuffered_bytes.rs | 31 ++++++++++++++++ clippy_utils/src/paths.rs | 1 + tests/ui/bytes_count_to_len.fixed | 6 ++-- tests/ui/bytes_count_to_len.rs | 6 ++-- tests/ui/unbuffered_bytes.rs | 37 ++++++++++++++++++++ tests/ui/unbuffered_bytes.stderr | 36 +++++++++++++++++++ 9 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 clippy_lints/src/methods/unbuffered_bytes.rs create mode 100644 tests/ui/unbuffered_bytes.rs create mode 100644 tests/ui/unbuffered_bytes.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f61fb1cd91..2d37e0da37f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6144,6 +6144,7 @@ Released 2018-09-13 [`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity [`type_id_on_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_id_on_box [`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds +[`unbuffered_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#unbuffered_bytes [`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction [`unconditional_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#unconditional_recursion [`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index d5a8f875e472..ac3e4bd90dc1 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -482,6 +482,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::methods::SUSPICIOUS_SPLITN_INFO, crate::methods::SUSPICIOUS_TO_OWNED_INFO, crate::methods::TYPE_ID_ON_BOX_INFO, + crate::methods::UNBUFFERED_BYTES_INFO, crate::methods::UNINIT_ASSUMED_INIT_INFO, crate::methods::UNIT_HASH_INFO, crate::methods::UNNECESSARY_FALLIBLE_CONVERSIONS_INFO, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 7d33f3de57d6..7e9db66ff864 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -113,6 +113,7 @@ mod suspicious_map; mod suspicious_splitn; mod suspicious_to_owned; mod type_id_on_box; +mod unbuffered_bytes; mod uninit_assumed_init; mod unit_hash; mod unnecessary_fallible_conversions; @@ -4406,6 +4407,33 @@ declare_clippy_lint! { "using `Option::and_then` or `Result::and_then` to chain a computation that returns an `Option` or a `Result`" } +declare_clippy_lint! { + /// ### What it does + /// Checks for calls to `Read::bytes` on types which don't implement `BufRead`. + /// + /// ### Why is this bad? + /// The default implementation calls `read` for each byte, which can be very inefficient for data that’s not in memory, such as `File`. + /// + /// ### Example + /// ```no_run + /// use std::io::Read; + /// use std::fs::File; + /// let file = File::open("./bytes.txt").unwrap(); + /// file.bytes(); + /// ``` + /// Use instead: + /// ```no_run + /// use std::io::{BufReader, Read}; + /// use std::fs::File; + /// let file = BufReader::new(std::fs::File::open("./bytes.txt").unwrap()); + /// file.bytes(); + /// ``` + #[clippy::version = "1.86.0"] + pub UNBUFFERED_BYTES, + perf, + "calling .bytes() is very inefficient when data is not in memory" +} + #[expect(clippy::struct_excessive_bools)] pub struct Methods { avoid_breaking_exported_api: bool, @@ -4580,6 +4608,7 @@ impl_lint_pass!(Methods => [ MANUAL_REPEAT_N, SLICED_STRING_AS_BYTES, RETURN_AND_THEN, + UNBUFFERED_BYTES, ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -4856,6 +4885,7 @@ impl Methods { ("as_ptr", []) => manual_c_str_literals::check_as_ptr(cx, expr, recv, &self.msrv), ("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv), ("assume_init", []) => uninit_assumed_init::check(cx, expr, recv), + ("bytes", []) => unbuffered_bytes::check(cx, expr, recv), ("cloned", []) => { cloned_instead_of_copied::check(cx, expr, recv, span, &self.msrv); option_as_ref_cloned::check(cx, recv, span); diff --git a/clippy_lints/src/methods/unbuffered_bytes.rs b/clippy_lints/src/methods/unbuffered_bytes.rs new file mode 100644 index 000000000000..71c23d256ac6 --- /dev/null +++ b/clippy_lints/src/methods/unbuffered_bytes.rs @@ -0,0 +1,31 @@ +use super::UNBUFFERED_BYTES; +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::ty::implements_trait; +use clippy_utils::{get_trait_def_id, is_trait_method, paths}; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::sym; + +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) { + let ty = cx.typeck_results().expr_ty_adjusted(recv); + + // If the .bytes() call is a call from the Read trait + if is_trait_method(cx, expr, sym::IoRead) { + // Retrieve the DefId of the BufRead trait + // FIXME: add a diagnostic item for `BufRead` + let Some(buf_read) = get_trait_def_id(cx.tcx, &paths::BUF_READ) else { + return; + }; + // And the implementor of the trait is not buffered + if !implements_trait(cx, ty, buf_read, &[]) { + span_lint_and_help( + cx, + UNBUFFERED_BYTES, + expr.span, + "calling .bytes() is very inefficient when data is not in memory", + None, + "consider using `BufReader`", + ); + } + } +} diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index f15fffc09e8d..74a392354894 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -29,6 +29,7 @@ pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"] // Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items. pub const ABORT: [&str; 3] = ["std", "process", "abort"]; +pub const BUF_READ: [&str; 3] = ["std", "io", "BufRead"]; pub const CHILD: [&str; 3] = ["std", "process", "Child"]; pub const CHILD_ID: [&str; 4] = ["std", "process", "Child", "id"]; pub const CHILD_KILL: [&str; 4] = ["std", "process", "Child", "kill"]; diff --git a/tests/ui/bytes_count_to_len.fixed b/tests/ui/bytes_count_to_len.fixed index d20af22535a0..fb31ceaad7c4 100644 --- a/tests/ui/bytes_count_to_len.fixed +++ b/tests/ui/bytes_count_to_len.fixed @@ -1,6 +1,6 @@ #![warn(clippy::bytes_count_to_len)] use std::fs::File; -use std::io::Read; +use std::io::{BufReader, Read}; fn main() { // should fix, because type is String @@ -26,8 +26,8 @@ fn main() { bytes.bytes().count(); // The type is File, so should not fix - let _ = File::open("foobar").unwrap().bytes().count(); + let _ = BufReader::new(File::open("foobar").unwrap()).bytes().count(); - let f = File::open("foobar").unwrap(); + let f = BufReader::new(File::open("foobar").unwrap()); let _ = f.bytes().count(); } diff --git a/tests/ui/bytes_count_to_len.rs b/tests/ui/bytes_count_to_len.rs index 340e6b412556..0250059afeb2 100644 --- a/tests/ui/bytes_count_to_len.rs +++ b/tests/ui/bytes_count_to_len.rs @@ -1,6 +1,6 @@ #![warn(clippy::bytes_count_to_len)] use std::fs::File; -use std::io::Read; +use std::io::{BufReader, Read}; fn main() { // should fix, because type is String @@ -26,8 +26,8 @@ fn main() { bytes.bytes().count(); // The type is File, so should not fix - let _ = File::open("foobar").unwrap().bytes().count(); + let _ = BufReader::new(File::open("foobar").unwrap()).bytes().count(); - let f = File::open("foobar").unwrap(); + let f = BufReader::new(File::open("foobar").unwrap()); let _ = f.bytes().count(); } diff --git a/tests/ui/unbuffered_bytes.rs b/tests/ui/unbuffered_bytes.rs new file mode 100644 index 000000000000..82c8839e8391 --- /dev/null +++ b/tests/ui/unbuffered_bytes.rs @@ -0,0 +1,37 @@ +#![warn(clippy::unbuffered_bytes)] + +use std::fs::File; +use std::io::{BufReader, Cursor, Read, Stdin, stdin}; +use std::net::TcpStream; + +fn main() { + // File is not buffered, should complain + let file = File::open("./bytes.txt").unwrap(); + file.bytes(); + + // TcpStream is not buffered, should complain + let tcp_stream: TcpStream = TcpStream::connect("127.0.0.1:80").unwrap(); + tcp_stream.bytes(); + + // BufReader is buffered, should not complain + let file = BufReader::new(File::open("./bytes.txt").unwrap()); + file.bytes(); + + // Cursor is buffered, should not complain + let cursor = Cursor::new(Vec::new()); + cursor.bytes(); + + // Stdio would acquire the lock for every byte, should complain + let s: Stdin = stdin(); + s.bytes(); + + // But when locking stdin, this is fine so should not complain + let s: Stdin = stdin(); + let s = s.lock(); + s.bytes(); +} + +fn use_read(r: R) { + // Callers of `use_read` may choose a `R` that is not buffered + r.bytes(); +} diff --git a/tests/ui/unbuffered_bytes.stderr b/tests/ui/unbuffered_bytes.stderr new file mode 100644 index 000000000000..3303d579fedc --- /dev/null +++ b/tests/ui/unbuffered_bytes.stderr @@ -0,0 +1,36 @@ +error: calling .bytes() is very inefficient when data is not in memory + --> tests/ui/unbuffered_bytes.rs:10:5 + | +LL | file.bytes(); + | ^^^^^^^^^^^^ + | + = help: consider using `BufReader` + = note: `-D clippy::unbuffered-bytes` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unbuffered_bytes)]` + +error: calling .bytes() is very inefficient when data is not in memory + --> tests/ui/unbuffered_bytes.rs:14:5 + | +LL | tcp_stream.bytes(); + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider using `BufReader` + +error: calling .bytes() is very inefficient when data is not in memory + --> tests/ui/unbuffered_bytes.rs:26:5 + | +LL | s.bytes(); + | ^^^^^^^^^ + | + = help: consider using `BufReader` + +error: calling .bytes() is very inefficient when data is not in memory + --> tests/ui/unbuffered_bytes.rs:36:5 + | +LL | r.bytes(); + | ^^^^^^^^^ + | + = help: consider using `BufReader` + +error: aborting due to 4 previous errors + From 8573725a030a8e17b1f687061f46822234e21cb1 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 12 Feb 2025 15:22:32 +0100 Subject: [PATCH 092/991] Remove ignored `#[must_use]` attributes from Clippy The `#[must_use]` attribute has no effect when applied to methods in trait implementations. --- clippy_lints/src/infinite_iter.rs | 1 - clippy_utils/src/consts.rs | 3 --- 2 files changed, 4 deletions(-) diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index d3aade31f14f..7210f4b438db 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -94,7 +94,6 @@ impl Finiteness { } impl From for Finiteness { - #[must_use] fn from(b: bool) -> Self { if b { Infinite } else { Finite } } diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index db82c458f703..21909896c33e 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -351,21 +351,18 @@ pub enum FullInt { } impl PartialEq for FullInt { - #[must_use] fn eq(&self, other: &Self) -> bool { self.cmp(other) == Ordering::Equal } } impl PartialOrd for FullInt { - #[must_use] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for FullInt { - #[must_use] fn cmp(&self, other: &Self) -> Ordering { use FullInt::{S, U}; From 39bde6d46a5c7dbebdc66afb8ac166a4e9087231 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 12 Feb 2025 17:15:27 +0100 Subject: [PATCH 093/991] Reorganize code in `mem_replace.rs` Make each lint be more self-contained, and trigger only the next lint when the previous one didn't already rewrite the expression. --- clippy_lints/src/mem_replace.rs | 86 +++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 41528c5dee3a..4f3279d292d1 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -103,26 +103,31 @@ declare_clippy_lint! { impl_lint_pass!(MemReplace => [MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]); -fn check_replace_option_with_none(cx: &LateContext<'_>, dest: &Expr<'_>, expr_span: Span) { - // Since this is a late pass (already type-checked), - // and we already know that the second argument is an - // `Option`, we do not need to check the first - // argument's type. All that's left is to get - // the replacee's expr after peeling off the `&mut` - let sugg_expr = peel_ref_operators(cx, dest); - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - MEM_REPLACE_OPTION_WITH_NONE, - expr_span, - "replacing an `Option` with `None`", - "consider `Option::take()` instead", - format!( - "{}.take()", - Sugg::hir_with_context(cx, sugg_expr, expr_span.ctxt(), "", &mut applicability).maybe_par() - ), - applicability, - ); +fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) -> bool { + if is_res_lang_ctor(cx, path_res(cx, src), OptionNone) { + // Since this is a late pass (already type-checked), + // and we already know that the second argument is an + // `Option`, we do not need to check the first + // argument's type. All that's left is to get + // the replacee's expr after peeling off the `&mut` + let sugg_expr = peel_ref_operators(cx, dest); + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + MEM_REPLACE_OPTION_WITH_NONE, + expr_span, + "replacing an `Option` with `None`", + "consider `Option::take()` instead", + format!( + "{}.take()", + Sugg::hir_with_context(cx, sugg_expr, expr_span.ctxt(), "", &mut applicability).maybe_par() + ), + applicability, + ); + true + } else { + false + } } fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { @@ -181,27 +186,34 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<' } } -fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { - // disable lint for primitives - let expr_type = cx.typeck_results().expr_ty_adjusted(src); - if is_non_aggregate_primitive_type(expr_type) { - return; - } - if is_default_equivalent(cx, src) && !expr_span.in_external_macro(cx.tcx.sess.source_map()) { - let Some(top_crate) = std_or_core(cx) else { return }; +fn check_replace_with_default( + cx: &LateContext<'_>, + src: &Expr<'_>, + dest: &Expr<'_>, + expr: &Expr<'_>, + msrv: &Msrv, +) -> bool { + if msrv.meets(msrvs::MEM_TAKE) && is_expr_used_or_unified(cx.tcx, expr) + // disable lint for primitives + && let expr_type = cx.typeck_results().expr_ty_adjusted(src) + && !is_non_aggregate_primitive_type(expr_type) + && is_default_equivalent(cx, src) + && !expr.span.in_external_macro(cx.tcx.sess.source_map()) + && let Some(top_crate) = std_or_core(cx) + { span_lint_and_then( cx, MEM_REPLACE_WITH_DEFAULT, - expr_span, + expr.span, format!( "replacing a value of type `T` with `T::default()` is better expressed using `{top_crate}::mem::take`" ), |diag| { - if !expr_span.from_expansion() { + if !expr.span.from_expansion() { let suggestion = format!("{top_crate}::mem::take({})", snippet(cx, dest.span, "")); diag.span_suggestion( - expr_span, + expr.span, "consider using", suggestion, Applicability::MachineApplicable, @@ -209,6 +221,9 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr< } }, ); + true + } else { + false } } @@ -233,12 +248,11 @@ impl<'tcx> LateLintPass<'tcx> for MemReplace { && cx.tcx.is_diagnostic_item(sym::mem_replace, def_id) { // Check that second argument is `Option::None` - if is_res_lang_ctor(cx, path_res(cx, src), OptionNone) { - check_replace_option_with_none(cx, dest, expr.span); - } else if self.msrv.meets(msrvs::MEM_TAKE) && is_expr_used_or_unified(cx.tcx, expr) { - check_replace_with_default(cx, src, dest, expr.span); + if !check_replace_option_with_none(cx, src, dest, expr.span) + && !check_replace_with_default(cx, src, dest, expr, &self.msrv) + { + check_replace_with_uninit(cx, src, dest, expr.span); } - check_replace_with_uninit(cx, src, dest, expr.span); } } extract_msrv_attr!(LateContext); From b167895a19dd8c634c66b5c672a83cdb610ab8a9 Mon Sep 17 00:00:00 2001 From: WeiTheShinobi Date: Thu, 13 Feb 2025 01:06:32 +0800 Subject: [PATCH 094/991] Fix `used_underscore_items` lint uses of foreign functions --- clippy_lints/src/misc.rs | 4 ++-- tests/ui/used_underscore_items.rs | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 8dbc41085532..646145997bc3 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -7,7 +7,6 @@ use clippy_utils::{ }; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::intravisit::FnKind; use rustc_hir::{ BinOpKind, BindingMode, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind, @@ -287,7 +286,8 @@ fn used_underscore_items<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if name.starts_with('_') && !name.starts_with("__") && !definition_span.from_expansion() - && def_id.krate == LOCAL_CRATE + && def_id.is_local() + && !cx.tcx.is_foreign_item(def_id) { span_lint_and_then( cx, diff --git a/tests/ui/used_underscore_items.rs b/tests/ui/used_underscore_items.rs index 223016a5c966..ed76f4e68dc9 100644 --- a/tests/ui/used_underscore_items.rs +++ b/tests/ui/used_underscore_items.rs @@ -61,3 +61,13 @@ fn external_item_call() { external_item::_exernal_foo(); } + +// should not lint foreign functions. +// issue #14156 +extern "C" { + pub fn _exit(code: i32) -> !; +} + +fn _f() { + unsafe { _exit(1) } +} From 342ac8ee289abbc28da41daa6cbb3e60586fe42b Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Tue, 11 Feb 2025 13:46:55 +0100 Subject: [PATCH 095/991] New lint: `mem_replace_option_with_some` `mem::replace(opt, Some(v))` can be replaced by `opt.replace(v)`. --- CHANGELOG.md | 1 + book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/mem_replace.rs | 64 +++++++++++++++++++++++++++++- clippy_utils/src/msrvs.rs | 1 + tests/ui/mem_replace.fixed | 22 ++++++++++ tests/ui/mem_replace.rs | 22 ++++++++++ tests/ui/mem_replace.stderr | 23 ++++++++++- 9 files changed, 133 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea1119aca984..232e1e6c3761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5812,6 +5812,7 @@ Released 2018-09-13 [`mem_discriminant_non_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_discriminant_non_enum [`mem_forget`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_forget [`mem_replace_option_with_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_none +[`mem_replace_option_with_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_some [`mem_replace_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default [`mem_replace_with_uninit`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_uninit [`min_ident_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index f43c3a280727..6168a3313ce3 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -764,6 +764,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or) * [`map_with_unused_argument_over_ranges`](https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges) * [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro) +* [`mem_replace_option_with_some`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_some) * [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default) * [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn) * [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 28e42c67d980..e7f27250da04 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -633,6 +633,7 @@ define_Conf! { map_unwrap_or, map_with_unused_argument_over_ranges, match_like_matches_macro, + mem_replace_option_with_some, mem_replace_with_default, missing_const_for_fn, needless_borrow, diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index d5a8f875e472..f733809b90de 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -362,6 +362,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::matches::WILDCARD_ENUM_MATCH_ARM_INFO, crate::matches::WILDCARD_IN_OR_PATTERNS_INFO, crate::mem_replace::MEM_REPLACE_OPTION_WITH_NONE_INFO, + crate::mem_replace::MEM_REPLACE_OPTION_WITH_SOME_INFO, crate::mem_replace::MEM_REPLACE_WITH_DEFAULT_INFO, crate::mem_replace::MEM_REPLACE_WITH_UNINIT_INFO, crate::methods::BIND_INSTEAD_OF_MAP_INFO, diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 4f3279d292d1..2fe5f6a3a37a 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -8,7 +8,7 @@ use clippy_utils::{ is_default_equivalent, is_expr_used_or_unified, is_res_lang_ctor, path_res, peel_ref_operators, std_or_core, }; use rustc_errors::Applicability; -use rustc_hir::LangItem::OptionNone; +use rustc_hir::LangItem::{OptionNone, OptionSome}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; @@ -43,6 +43,31 @@ declare_clippy_lint! { "replacing an `Option` with `None` instead of `take()`" } +declare_clippy_lint! { + /// ### What it does + /// Checks for `mem::replace()` on an `Option` with `Some(…)`. + /// + /// ### Why is this bad? + /// `Option` already has the method `replace()` for + /// taking its current value (Some(…) or None) and replacing it with + /// `Some(…)`. + /// + /// ### Example + /// ```no_run + /// let mut an_option = Some(0); + /// let replaced = std::mem::replace(&mut an_option, Some(1)); + /// ``` + /// Is better expressed with: + /// ```no_run + /// let mut an_option = Some(0); + /// let taken = an_option.replace(1); + /// ``` + #[clippy::version = "1.86.0"] + pub MEM_REPLACE_OPTION_WITH_SOME, + style, + "replacing an `Option` with `Some` instead of `replace()`" +} + declare_clippy_lint! { /// ### What it does /// Checks for `mem::replace(&mut _, mem::uninitialized())` @@ -101,7 +126,7 @@ declare_clippy_lint! { } impl_lint_pass!(MemReplace => - [MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]); + [MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_OPTION_WITH_SOME, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]); fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) -> bool { if is_res_lang_ctor(cx, path_res(cx, src), OptionNone) { @@ -130,6 +155,40 @@ fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &E } } +fn check_replace_option_with_some( + cx: &LateContext<'_>, + src: &Expr<'_>, + dest: &Expr<'_>, + expr_span: Span, + msrv: &Msrv, +) -> bool { + if msrv.meets(msrvs::OPTION_REPLACE) + && let ExprKind::Call(src_func, [src_arg]) = src.kind + && is_res_lang_ctor(cx, path_res(cx, src_func), OptionSome) + { + // We do not have to check for a `const` context here, because `core::mem::replace()` and + // `Option::replace()` have been const-stabilized simultaneously in version 1.83.0. + let sugg_expr = peel_ref_operators(cx, dest); + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + MEM_REPLACE_OPTION_WITH_SOME, + expr_span, + "replacing an `Option` with `Some(..)`", + "consider `Option::replace()` instead", + format!( + "{}.replace({})", + Sugg::hir_with_context(cx, sugg_expr, expr_span.ctxt(), "_", &mut applicability).maybe_par(), + snippet_with_applicability(cx, src_arg.span, "_", &mut applicability) + ), + applicability, + ); + true + } else { + false + } +} + fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(src.hir_id) // check if replacement is mem::MaybeUninit::uninit().assume_init() @@ -249,6 +308,7 @@ impl<'tcx> LateLintPass<'tcx> for MemReplace { { // Check that second argument is `Option::None` if !check_replace_option_with_none(cx, src, dest, expr.span) + && !check_replace_option_with_some(cx, src, dest, expr.span, &self.msrv) && !check_replace_with_default(cx, src, dest, expr, &self.msrv) { check_replace_with_uninit(cx, src, dest, expr.span); diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 87c8165eae25..2e8bcfaa7af0 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -58,6 +58,7 @@ msrv_aliases! { 1,35,0 { OPTION_COPIED, RANGE_CONTAINS } 1,34,0 { TRY_FROM } 1,33,0 { UNDERSCORE_IMPORTS } + 1,31,0 { OPTION_REPLACE } 1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES } 1,29,0 { ITER_FLATTEN } 1,28,0 { FROM_BOOL, REPEAT_WITH } diff --git a/tests/ui/mem_replace.fixed b/tests/ui/mem_replace.fixed index 248ecd5d85f4..02b0d9c7045f 100644 --- a/tests/ui/mem_replace.fixed +++ b/tests/ui/mem_replace.fixed @@ -131,3 +131,25 @@ fn issue9824() { // replace with default let _ = std::mem::take(&mut b.val); } + +#[clippy::msrv = "1.31"] +fn mem_replace_option_with_some() { + let mut an_option = Some(0); + let replaced = an_option.replace(1); + //~^ ERROR: replacing an `Option` with `Some(..)` + + let mut an_option = &mut Some(0); + let replaced = an_option.replace(1); + //~^ ERROR: replacing an `Option` with `Some(..)` + + let (mut opt1, mut opt2) = (Some(0), Some(0)); + let b = true; + let replaced = (if b { &mut opt1 } else { &mut opt2 }).replace(1); + //~^ ERROR: replacing an `Option` with `Some(..)` +} + +#[clippy::msrv = "1.30"] +fn mem_replace_option_with_some_bad_msrv() { + let mut an_option = Some(0); + let replaced = mem::replace(&mut an_option, Some(1)); +} diff --git a/tests/ui/mem_replace.rs b/tests/ui/mem_replace.rs index 486d2ba1b6a5..1bb72b5de239 100644 --- a/tests/ui/mem_replace.rs +++ b/tests/ui/mem_replace.rs @@ -131,3 +131,25 @@ fn issue9824() { // replace with default let _ = std::mem::replace(&mut b.val, String::default()); } + +#[clippy::msrv = "1.31"] +fn mem_replace_option_with_some() { + let mut an_option = Some(0); + let replaced = mem::replace(&mut an_option, Some(1)); + //~^ ERROR: replacing an `Option` with `Some(..)` + + let mut an_option = &mut Some(0); + let replaced = mem::replace(an_option, Some(1)); + //~^ ERROR: replacing an `Option` with `Some(..)` + + let (mut opt1, mut opt2) = (Some(0), Some(0)); + let b = true; + let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1)); + //~^ ERROR: replacing an `Option` with `Some(..)` +} + +#[clippy::msrv = "1.30"] +fn mem_replace_option_with_some_bad_msrv() { + let mut an_option = Some(0); + let replaced = mem::replace(&mut an_option, Some(1)); +} diff --git a/tests/ui/mem_replace.stderr b/tests/ui/mem_replace.stderr index a60f2253d13e..42ab546a5d77 100644 --- a/tests/ui/mem_replace.stderr +++ b/tests/ui/mem_replace.stderr @@ -160,5 +160,26 @@ error: replacing a value of type `T` with `T::default()` is better expressed usi LL | let _ = std::mem::replace(&mut b.val, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)` -error: aborting due to 26 previous errors +error: replacing an `Option` with `Some(..)` + --> tests/ui/mem_replace.rs:138:20 + | +LL | let replaced = mem::replace(&mut an_option, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `an_option.replace(1)` + | + = note: `-D clippy::mem-replace-option-with-some` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_some)]` + +error: replacing an `Option` with `Some(..)` + --> tests/ui/mem_replace.rs:142:20 + | +LL | let replaced = mem::replace(an_option, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `an_option.replace(1)` + +error: replacing an `Option` with `Some(..)` + --> tests/ui/mem_replace.rs:147:20 + | +LL | let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `(if b { &mut opt1 } else { &mut opt2 }).replace(1)` + +error: aborting due to 29 previous errors From a75cc61f99c029c22fd100af524de7e2ba600d5e Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 7 Feb 2025 19:33:58 +0100 Subject: [PATCH 096/991] intern valtrees --- clippy_lints/src/non_copy_const.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 405bbfc9c6fa..f965ab90da23 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -179,8 +179,8 @@ impl<'tcx> NonCopyConst<'tcx> { } fn is_value_unfrozen_raw_inner(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool { - // No branch that we check (yet) should continue if val isn't a ValTree::Branch - let ty::ValTree::Branch(val) = val else { return false }; + // No branch that we check (yet) should continue if val isn't a branch + let Some(val) = val.try_to_branch() else { return false }; match *ty.kind() { // the fact that we have to dig into every structs to search enums // leads us to the point checking `UnsafeCell` directly is the only option. @@ -192,9 +192,10 @@ impl<'tcx> NonCopyConst<'tcx> { .iter() .any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)), ty::Adt(def, args) if def.is_enum() => { - let Some((&ty::ValTree::Leaf(variant_index), fields)) = val.split_first() else { + let Some((&variant_valtree, fields)) = val.split_first() else { return false; }; + let variant_index = variant_valtree.unwrap_leaf(); let variant_index = VariantIdx::from_u32(variant_index.to_u32()); fields .iter() From 3cee0724eea6f99c674cae99e85588cd98d3db65 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 13 Feb 2025 04:56:10 +0000 Subject: [PATCH 097/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 48458cdcbc3d..1f451b8c0caa 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -6171d944aea415a3023d4262e0895aa3b18c771f +6dce9f8c2d8dde4c9ea20bab981cd70229c37fdc From c47746ca67d53d5d8fc3ae9fd7ad144463a69e7d Mon Sep 17 00:00:00 2001 From: yanglsh Date: Thu, 13 Feb 2025 15:26:11 +0800 Subject: [PATCH 098/991] fix: `needless_option_as_deref` FP in trait --- clippy_utils/src/lib.rs | 6 +++++- tests/ui/needless_option_as_deref.fixed | 13 +++++++++++++ tests/ui/needless_option_as_deref.rs | 13 +++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 0d9502c50db6..d1b3d5508b09 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -107,7 +107,7 @@ use rustc_hir::{ self as hir, Arm, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat, - PatExpr, PatExprKind, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, + PatExpr, PatExprKind, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitFn, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, def, }; use rustc_lexer::{TokenKind, tokenize}; @@ -1505,6 +1505,10 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio | Node::ImplItem(&ImplItem { kind: ImplItemKind::Fn(_, eid), .. + }) + | Node::TraitItem(&TraitItem { + kind: TraitItemKind::Fn(_, TraitFn::Provided(eid)), + .. }) => match cx.tcx.hir().body(eid).value.kind { ExprKind::Block(block, _) => Some(block), _ => None, diff --git a/tests/ui/needless_option_as_deref.fixed b/tests/ui/needless_option_as_deref.fixed index 84eaf12fc139..577deb2793c1 100644 --- a/tests/ui/needless_option_as_deref.fixed +++ b/tests/ui/needless_option_as_deref.fixed @@ -70,3 +70,16 @@ mod issue_non_copy_13077 { pub field: (), } } + +mod issue14148 { + pub trait SomeTrait { + fn something(&self, mut maybe_side_effect: Option<&mut String>) { + other(maybe_side_effect.as_deref_mut()); + other(maybe_side_effect); + } + } + + fn other(_maybe_side_effect: Option<&mut String>) { + unimplemented!() + } +} diff --git a/tests/ui/needless_option_as_deref.rs b/tests/ui/needless_option_as_deref.rs index fff1e45d846f..47f1f90b21b3 100644 --- a/tests/ui/needless_option_as_deref.rs +++ b/tests/ui/needless_option_as_deref.rs @@ -70,3 +70,16 @@ mod issue_non_copy_13077 { pub field: (), } } + +mod issue14148 { + pub trait SomeTrait { + fn something(&self, mut maybe_side_effect: Option<&mut String>) { + other(maybe_side_effect.as_deref_mut()); + other(maybe_side_effect); + } + } + + fn other(_maybe_side_effect: Option<&mut String>) { + unimplemented!() + } +} From 8cac5b03f3fdc6906a037ccdd656161e4263e898 Mon Sep 17 00:00:00 2001 From: Sebastian Jeltsch Date: Fri, 31 Jan 2025 15:17:45 +0100 Subject: [PATCH 099/991] rustc_tools_util: Change release channel default to stable Fixes the exposed release channel Bump version to 0.4.1 --- Cargo.toml | 4 +-- rustc_tools_util/Cargo.toml | 2 +- rustc_tools_util/README.md | 4 +-- rustc_tools_util/src/lib.rs | 55 ++++++++++++++++++++++--------------- tests/versioncheck.rs | 6 ++++ 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b615bb9e6f6b..263f2a4aab70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ path = "src/driver.rs" [dependencies] clippy_config = { path = "clippy_config" } clippy_lints = { path = "clippy_lints" } -rustc_tools_util = "0.4.0" +rustc_tools_util = { path = "rustc_tools_util", version = "0.4.1" } tempfile = { version = "3.3", optional = true } termize = "0.1" color-print = "0.3.4" @@ -54,7 +54,7 @@ parking_lot = "0.12" tokio = { version = "1", features = ["io-util"] } [build-dependencies] -rustc_tools_util = "0.4.0" +rustc_tools_util = { path = "rustc_tools_util", version = "0.4.1" } [features] integration = ["tempfile"] diff --git a/rustc_tools_util/Cargo.toml b/rustc_tools_util/Cargo.toml index cba025639482..189f34dd2a65 100644 --- a/rustc_tools_util/Cargo.toml +++ b/rustc_tools_util/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustc_tools_util" -version = "0.4.0" +version = "0.4.1" description = "small helper to generate version information for git packages" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/rustc_tools_util/README.md b/rustc_tools_util/README.md index 1b11dfe06191..455654c10900 100644 --- a/rustc_tools_util/README.md +++ b/rustc_tools_util/README.md @@ -13,10 +13,10 @@ build = "build.rs" List rustc_tools_util as regular AND build dependency. ````toml [dependencies] -rustc_tools_util = "0.4.0" +rustc_tools_util = "0.4.1" [build-dependencies] -rustc_tools_util = "0.4.0" +rustc_tools_util = "0.4.1" ```` In `build.rs`, generate the data in your `main()` diff --git a/rustc_tools_util/src/lib.rs b/rustc_tools_util/src/lib.rs index 16be02f4a40f..cabd9dfa0c7c 100644 --- a/rustc_tools_util/src/lib.rs +++ b/rustc_tools_util/src/lib.rs @@ -28,9 +28,8 @@ macro_rules! get_version_info { }}; } -/// This macro can be used in `build.rs` to automatically set the needed -/// environment values, namely `GIT_HASH`, `COMMIT_DATE` and -/// `RUSTC_RELEASE_CHANNEL` +/// This macro can be used in `build.rs` to automatically set the needed environment values, namely +/// `GIT_HASH`, `COMMIT_DATE` and `RUSTC_RELEASE_CHANNEL` #[macro_export] macro_rules! setup_version_info { () => {{ @@ -43,7 +42,11 @@ macro_rules! setup_version_info { "cargo:rustc-env=COMMIT_DATE={}", $crate::get_commit_date().unwrap_or_default() ); - println!("cargo:rustc-env=RUSTC_RELEASE_CHANNEL={}", $crate::get_channel()); + let compiler_version = $crate::get_compiler_version(); + println!( + "cargo:rustc-env=RUSTC_RELEASE_CHANNEL={}", + $crate::get_channel(compiler_version) + ); }}; } @@ -87,16 +90,17 @@ impl std::fmt::Debug for VersionInfo { "VersionInfo {{ crate_name: \"{}\", major: {}, minor: {}, patch: {}", self.crate_name, self.major, self.minor, self.patch, )?; - if self.commit_hash.is_some() { - write!( - f, - ", commit_hash: \"{}\", commit_date: \"{}\" }}", - self.commit_hash.clone().unwrap_or_default().trim(), - self.commit_date.clone().unwrap_or_default().trim() - )?; - } else { - write!(f, " }}")?; + if let Some(ref commit_hash) = self.commit_hash { + write!(f, ", commit_hash: \"{}\"", commit_hash.trim(),)?; } + if let Some(ref commit_date) = self.commit_date { + write!(f, ", commit_date: \"{}\"", commit_date.trim())?; + } + if let Some(ref host_compiler) = self.host_compiler { + write!(f, ", host_compiler: \"{}\"", host_compiler.trim())?; + } + + write!(f, " }}")?; Ok(()) } @@ -152,22 +156,27 @@ pub fn get_commit_date() -> Option { } #[must_use] -pub fn get_channel() -> String { +pub fn get_compiler_version() -> Option { + get_output("rustc", &["-V"]) +} + +#[must_use] +pub fn get_channel(compiler_version: Option) -> String { if let Ok(channel) = std::env::var("CFG_RELEASE_CHANNEL") { return channel; } // if that failed, try to ask rustc -V, do some parsing and find out - if let Some(rustc_output) = get_output("rustc", &["-V"]) { + if let Some(rustc_output) = compiler_version { if rustc_output.contains("beta") { return String::from("beta"); - } else if rustc_output.contains("stable") { - return String::from("stable"); + } else if rustc_output.contains("nightly") { + return String::from("nightly"); } } - // default to nightly - String::from("nightly") + // default to stable + String::from("stable") } #[cfg(test)] @@ -179,17 +188,19 @@ mod test { let vi = get_version_info!(); assert_eq!(vi.major, 0); assert_eq!(vi.minor, 4); - assert_eq!(vi.patch, 0); + assert_eq!(vi.patch, 1); assert_eq!(vi.crate_name, "rustc_tools_util"); // hard to make positive tests for these since they will always change assert!(vi.commit_hash.is_none()); assert!(vi.commit_date.is_none()); + + assert!(vi.host_compiler.is_none()); } #[test] fn test_display_local() { let vi = get_version_info!(); - assert_eq!(vi.to_string(), "rustc_tools_util 0.4.0"); + assert_eq!(vi.to_string(), "rustc_tools_util 0.4.1"); } #[test] @@ -198,7 +209,7 @@ mod test { let s = format!("{vi:?}"); assert_eq!( s, - "VersionInfo { crate_name: \"rustc_tools_util\", major: 0, minor: 4, patch: 0 }" + "VersionInfo { crate_name: \"rustc_tools_util\", major: 0, minor: 4, patch: 1 }" ); } } diff --git a/tests/versioncheck.rs b/tests/versioncheck.rs index ed357137095b..ea540d48a2b9 100644 --- a/tests/versioncheck.rs +++ b/tests/versioncheck.rs @@ -90,3 +90,9 @@ fn check_that_clippy_has_the_same_major_version_as_rustc() { }, } } + +#[test] +fn check_host_compiler() { + let version = rustc_tools_util::get_version_info!(); + assert_eq!(version.host_compiler, Some("nightly".to_string())); +} From f826193aec2d58f64c4592818dd2d855a5bbc597 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 12 Feb 2025 20:44:22 +0100 Subject: [PATCH 100/991] `unnecessary_map_or`: do not consume the non-`Copy` comparison value --- .../src/methods/unnecessary_map_or.rs | 6 +++-- tests/ui/unnecessary_map_or.fixed | 6 +++++ tests/ui/unnecessary_map_or.rs | 6 +++++ tests/ui/unnecessary_map_or.stderr | 26 ++++++++++++++++++- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_map_or.rs b/clippy_lints/src/methods/unnecessary_map_or.rs index 6dea1506d0e3..c307e8c951d0 100644 --- a/clippy_lints/src/methods/unnecessary_map_or.rs +++ b/clippy_lints/src/methods/unnecessary_map_or.rs @@ -4,7 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg::{Sugg, make_binop}; -use clippy_utils::ty::{get_type_diagnostic_name, implements_trait}; +use clippy_utils::ty::{get_type_diagnostic_name, implements_trait, is_copy}; use clippy_utils::visitors::is_local_used; use clippy_utils::{get_parent_expr, is_from_proc_macro, path_to_local_id}; use rustc_ast::LitKind::Bool; @@ -81,9 +81,11 @@ pub(super) fn check<'a>( && (path_to_local_id(l, hir_id) ^ path_to_local_id(r, hir_id)) && !is_local_used(cx, non_binding_location, hir_id) && let typeck_results = cx.typeck_results() - && typeck_results.expr_ty(l) == typeck_results.expr_ty(r) + && let l_ty = typeck_results.expr_ty(l) + && l_ty == typeck_results.expr_ty(r) && let Some(partial_eq) = cx.tcx.get_diagnostic_item(sym::PartialEq) && implements_trait(cx, recv_ty, partial_eq, &[recv_ty.into()]) + && is_copy(cx, l_ty) { let wrap = variant.variant_name(); diff --git a/tests/ui/unnecessary_map_or.fixed b/tests/ui/unnecessary_map_or.fixed index 5a6e77a06b8f..27532373a7b9 100644 --- a/tests/ui/unnecessary_map_or.fixed +++ b/tests/ui/unnecessary_map_or.fixed @@ -99,3 +99,9 @@ impl std::ops::Deref for S { fn with_deref(o: &S) -> bool { o.is_none_or(|n| n > 5) } + +fn issue14201(a: Option, b: Option, s: &String) -> bool { + let x = a.is_some_and(|a| a == *s); + let y = b.is_none_or(|b| b == *s); + x && y +} diff --git a/tests/ui/unnecessary_map_or.rs b/tests/ui/unnecessary_map_or.rs index 5ba63121659f..6496defe1300 100644 --- a/tests/ui/unnecessary_map_or.rs +++ b/tests/ui/unnecessary_map_or.rs @@ -102,3 +102,9 @@ impl std::ops::Deref for S { fn with_deref(o: &S) -> bool { o.map_or(true, |n| n > 5) } + +fn issue14201(a: Option, b: Option, s: &String) -> bool { + let x = a.map_or(false, |a| a == *s); + let y = b.map_or(true, |b| b == *s); + x && y +} diff --git a/tests/ui/unnecessary_map_or.stderr b/tests/ui/unnecessary_map_or.stderr index 2ae327f0bf88..f672f55dd04d 100644 --- a/tests/ui/unnecessary_map_or.stderr +++ b/tests/ui/unnecessary_map_or.stderr @@ -287,5 +287,29 @@ LL - o.map_or(true, |n| n > 5) LL + o.is_none_or(|n| n > 5) | -error: aborting due to 24 previous errors +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or.rs:107:13 + | +LL | let x = a.map_or(false, |a| a == *s); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use is_some_and instead + | +LL - let x = a.map_or(false, |a| a == *s); +LL + let x = a.is_some_and(|a| a == *s); + | + +error: this `map_or` can be simplified + --> tests/ui/unnecessary_map_or.rs:108:13 + | +LL | let y = b.map_or(true, |b| b == *s); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use is_none_or instead + | +LL - let y = b.map_or(true, |b| b == *s); +LL + let y = b.is_none_or(|b| b == *s); + | + +error: aborting due to 26 previous errors From 1cac5fa5f9f371db4789ea928e1d2769d4cd921b Mon Sep 17 00:00:00 2001 From: jyn Date: Thu, 13 Feb 2025 10:14:06 -0500 Subject: [PATCH 101/991] Look for `python3` first on MacOS, not `py` `py` is not installed by default *and* trying to run it results in a popup asking if you want to install it. `python3` is installed by default. This hopefully should not be too disruptive to people on Windows, since they should be going through `x.ps1` instead anyway. Just in case, I've added a check for Cygwin and Msys (i'm not sure how else you'd get a bash shell on windows). --- x | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/x b/x index e656d37c1e45..551cfe6efbf3 100755 --- a/x +++ b/x @@ -25,7 +25,13 @@ xpy=$(dirname "$(realpath "$0")")/x.py # On Windows, `py -3` sometimes works. We need to try it first because `python3` # sometimes tries to launch the app store on Windows. -for SEARCH_PYTHON in py python3 python python2; do +# On MacOS, `py` tries to install "Developer command line tools". Try `python3` first. +# NOTE: running `bash -c ./x` from Windows doesn't set OSTYPE. +case ${OSTYPE:-} in + cygwin*|msys*) SEARCH="py python3 python python2";; + *) SEARCH="python3 python py python2";; +esac +for SEARCH_PYTHON in $SEARCH; do if python=$(command -v $SEARCH_PYTHON) && [ -x "$python" ]; then if [ $SEARCH_PYTHON = py ]; then extra_arg="-3" From 756013f3e94b7389981aec093053e0c1324c2958 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Mon, 28 Oct 2024 23:25:27 +0100 Subject: [PATCH 102/991] fixed wast version was released, remove randomization exemption --- src/bootstrap/src/core/builder/cargo.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 59680af00622..ea702c41cd83 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -611,11 +611,10 @@ impl Builder<'_> { } // FIXME: the following components don't build with `-Zrandomize-layout` yet: - // - wasm-component-ld, due to the `wast`crate // - rust-analyzer, due to the rowan crate - // so we exclude entire categories of steps here due to lack of fine-grained control over + // so we exclude an entire category of steps here due to lack of fine-grained control over // rustflags. - if self.config.rust_randomize_layout && mode != Mode::ToolStd && mode != Mode::ToolRustc { + if self.config.rust_randomize_layout && mode != Mode::ToolRustc { rustflags.arg("-Zrandomize-layout"); } From fc532c5b322106e8ddc6485451cd5f14c4e995bd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 13 Feb 2025 03:21:25 +0000 Subject: [PATCH 103/991] Trim suggestion parts to the subset that is purely additive --- tests/ui/implicit_return.stderr | 42 +++++++++--------------- tests/ui/legacy_numeric_constants.stderr | 5 ++- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/tests/ui/implicit_return.stderr b/tests/ui/implicit_return.stderr index 0d2faa5e067b..7ea72307450c 100644 --- a/tests/ui/implicit_return.stderr +++ b/tests/ui/implicit_return.stderr @@ -8,8 +8,7 @@ LL | true = help: to override `-D warnings` add `#[allow(clippy::implicit_return)]` help: add `return` as shown | -LL - true -LL + return true +LL | return true | error: missing `return` statement @@ -20,9 +19,8 @@ LL | if true { true } else { false } | help: add `return` as shown | -LL - if true { true } else { false } -LL + if true { return true } else { false } - | +LL | if true { return true } else { false } + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:19:29 @@ -32,9 +30,8 @@ LL | if true { true } else { false } | help: add `return` as shown | -LL - if true { true } else { false } -LL + if true { true } else { return false } - | +LL | if true { true } else { return false } + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:25:17 @@ -44,9 +41,8 @@ LL | true => false, | help: add `return` as shown | -LL - true => false, -LL + true => return false, - | +LL | true => return false, + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:26:20 @@ -56,9 +52,8 @@ LL | false => { true }, | help: add `return` as shown | -LL - false => { true }, -LL + false => { return true }, - | +LL | false => { return true }, + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:39:9 @@ -104,9 +99,8 @@ LL | let _ = || { true }; | help: add `return` as shown | -LL - let _ = || { true }; -LL + let _ = || { return true }; - | +LL | let _ = || { return true }; + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:73:16 @@ -116,9 +110,8 @@ LL | let _ = || true; | help: add `return` as shown | -LL - let _ = || true; -LL + let _ = || return true; - | +LL | let _ = || return true; + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:81:5 @@ -128,8 +121,7 @@ LL | format!("test {}", "test") | help: add `return` as shown | -LL - format!("test {}", "test") -LL + return format!("test {}", "test") +LL | return format!("test {}", "test") | error: missing `return` statement @@ -140,8 +132,7 @@ LL | m!(true, false) | help: add `return` as shown | -LL - m!(true, false) -LL + return m!(true, false) +LL | return m!(true, false) | error: missing `return` statement @@ -191,8 +182,7 @@ LL | true | help: add `return` as shown | -LL - true -LL + return true +LL | return true | error: aborting due to 16 previous errors diff --git a/tests/ui/legacy_numeric_constants.stderr b/tests/ui/legacy_numeric_constants.stderr index 74fe09e0f5c6..91dfe79d55ba 100644 --- a/tests/ui/legacy_numeric_constants.stderr +++ b/tests/ui/legacy_numeric_constants.stderr @@ -68,9 +68,8 @@ LL | MAX; | help: use the associated constant instead | -LL - MAX; -LL + u32::MAX; - | +LL | u32::MAX; + | +++++ error: usage of a legacy numeric method --> tests/ui/legacy_numeric_constants.rs:49:10 From 736ef0a4cee37e35caa6efb1121a776e00a9de4a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 14 Feb 2025 09:19:10 +0000 Subject: [PATCH 104/991] Don't error when adding a staticlib with bitcode files compiled by newer LLVM --- .../rustc_codegen_llvm/src/back/archive.rs | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 93553f3f3648..91dce57ed1ef 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -132,23 +132,39 @@ fn get_llvm_object_symbols( if err.is_null() { return Ok(true); } else { - return Err(unsafe { *Box::from_raw(err as *mut io::Error) }); + let error = unsafe { *Box::from_raw(err as *mut String) }; + // These are the magic constants for LLVM bitcode files: + // https://github.com/llvm/llvm-project/blob/7eadc1960d199676f04add402bb0aa6f65b7b234/llvm/lib/BinaryFormat/Magic.cpp#L90-L97 + if buf.starts_with(&[0xDE, 0xCE, 0x17, 0x0B]) || buf.starts_with(&[b'B', b'C', 0xC0, 0xDE]) + { + // For LLVM bitcode, failure to read the symbols is not fatal. The bitcode may have been + // produced by a newer LLVM version that the one linked to rustc. This is fine provided + // that the linker does use said newer LLVM version. We skip writing the symbols for the + // bitcode to the symbol table of the archive. Traditional linkers don't like this, but + // newer linkers like lld, mold and wild ignore the symbol table anyway, so if they link + // against a new enough LLVM it will work out in the end. + // LLVM's archive writer also has this same behavior of only warning about invalid + // bitcode since https://github.com/llvm/llvm-project/pull/96848 + + // We don't have access to the DiagCtxt here to produce a nice warning in the correct format. + eprintln!("warning: Failed to read symbol table from LLVM bitcode: {}", error); + return Ok(true); + } else { + return Err(io::Error::new(io::ErrorKind::Other, format!("LLVM error: {}", error))); + } } unsafe extern "C" fn callback(state: *mut c_void, symbol_name: *const c_char) -> *mut c_void { let f = unsafe { &mut *(state as *mut &mut dyn FnMut(&[u8]) -> io::Result<()>) }; match f(unsafe { CStr::from_ptr(symbol_name) }.to_bytes()) { Ok(()) => std::ptr::null_mut(), - Err(err) => Box::into_raw(Box::new(err)) as *mut c_void, + Err(err) => Box::into_raw(Box::new(err.to_string()) as Box) as *mut c_void, } } unsafe extern "C" fn error_callback(error: *const c_char) -> *mut c_void { let error = unsafe { CStr::from_ptr(error) }; - Box::into_raw(Box::new(io::Error::new( - io::ErrorKind::Other, - format!("LLVM error: {}", error.to_string_lossy()), - ))) as *mut c_void + Box::into_raw(Box::new(error.to_string_lossy().into_owned()) as Box) as *mut c_void } } From 9147b6dd2878763208d90b41bca18d9144fd5bf8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 14 Feb 2025 10:04:19 +0000 Subject: [PATCH 105/991] Add test --- .../staticlib-broken-bitcode/rmake.rs | 23 +++++++++++++++++++ .../staticlib-broken-bitcode/rust_lib.rs | 6 +++++ 2 files changed, 29 insertions(+) create mode 100644 tests/run-make/staticlib-broken-bitcode/rmake.rs create mode 100644 tests/run-make/staticlib-broken-bitcode/rust_lib.rs diff --git a/tests/run-make/staticlib-broken-bitcode/rmake.rs b/tests/run-make/staticlib-broken-bitcode/rmake.rs new file mode 100644 index 000000000000..f8c61d708191 --- /dev/null +++ b/tests/run-make/staticlib-broken-bitcode/rmake.rs @@ -0,0 +1,23 @@ +// Regression test for https://github.com/rust-lang/rust/issues/128955#issuecomment-2657811196 +// which checks that rustc can read an archive containing LLVM bitcode with a +// newer version from the one rustc links against. +use run_make_support::{llvm_ar, path, rfs, rustc, static_lib_name}; + +fn main() { + rfs::create_dir("archive"); + + let mut bitcode = b"BC\xC0\xDE".to_vec(); + bitcode.extend(std::iter::repeat(b'a').take(50)); + rfs::write("archive/invalid_bitcode.o", &bitcode); + + llvm_ar() + .obj_to_thin_ar() + .output_input( + path("archive").join(static_lib_name("thin_archive")), + "archive/invalid_bitcode.o", + ) + .run(); + + // Build an rlib which includes the members of this thin archive + rustc().input("rust_lib.rs").library_search_path("archive").run(); +} diff --git a/tests/run-make/staticlib-broken-bitcode/rust_lib.rs b/tests/run-make/staticlib-broken-bitcode/rust_lib.rs new file mode 100644 index 000000000000..c76b0f254337 --- /dev/null +++ b/tests/run-make/staticlib-broken-bitcode/rust_lib.rs @@ -0,0 +1,6 @@ +#![crate_type = "rlib"] + +#[link(name = "thin_archive", kind = "static")] +extern "C" { + pub fn simple_fn(); +} From f1b4a1d0d135f4aa8c338b1dc98b8296c972ce69 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 14 Feb 2025 12:24:06 +0000 Subject: [PATCH 106/991] Remove the build script for miri Setting the TARGET env var can be replaced with using rustc_session::config::host_tuple at runtime. And the check-cfg can be replaced with using the lints section in Cargo.toml. --- src/tools/miri/Cargo.toml | 4 ++++ src/tools/miri/build.rs | 10 ---------- src/tools/miri/src/machine.rs | 5 +++-- 3 files changed, 7 insertions(+), 12 deletions(-) delete mode 100644 src/tools/miri/build.rs diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index de80722fc3df..728a7552fd8c 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -67,6 +67,10 @@ default = ["stack-cache"] stack-cache = [] stack-cache-consistency-check = ["stack-cache"] +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ['cfg(bootstrap)'] + # Be aware that this file is inside a workspace when used via the # submodule in the rustc repo. That means there are many cargo features # we cannot use, such as profiles. diff --git a/src/tools/miri/build.rs b/src/tools/miri/build.rs deleted file mode 100644 index 0918c9b13214..000000000000 --- a/src/tools/miri/build.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn main() { - // Don't rebuild miri when nothing changed. - println!("cargo:rerun-if-changed=build.rs"); - // Re-export the TARGET environment variable so it can be accessed by miri. Needed to know the - // "host" triple inside Miri. - let target = std::env::var("TARGET").unwrap(); - println!("cargo:rustc-env=TARGET={target}"); - // Allow some cfgs. - println!("cargo::rustc-check-cfg=cfg(bootstrap)"); -} diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 6bd1076a8a84..4ece8f7895de 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -713,12 +713,13 @@ impl<'tcx> MiriMachine<'tcx> { clock: Clock::new(config.isolated_op == IsolatedOp::Allow), #[cfg(unix)] native_lib: config.native_lib.as_ref().map(|lib_file_path| { + let host_triple = rustc_session::config::host_tuple(); let target_triple = tcx.sess.opts.target_triple.tuple(); // Check if host target == the session target. - if env!("TARGET") != target_triple { + if host_triple != target_triple { panic!( "calling external C functions in linked .so file requires host and target to be the same: host={}, target={}", - env!("TARGET"), + host_triple, target_triple, ); } From f7f78880414aec9ba22d03d894f8ca026b63dd84 Mon Sep 17 00:00:00 2001 From: Sebastian Jeltsch Date: Thu, 13 Feb 2025 14:51:04 +0100 Subject: [PATCH 107/991] Make rust_tools_util package compatible with current stable by lowering rust edition to 2021. --- Cargo.toml | 4 ++-- rustc_tools_util/Cargo.toml | 4 ++-- rustc_tools_util/README.md | 4 ++-- rustc_tools_util/src/lib.rs | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 263f2a4aab70..6c19e7af5f8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ path = "src/driver.rs" [dependencies] clippy_config = { path = "clippy_config" } clippy_lints = { path = "clippy_lints" } -rustc_tools_util = { path = "rustc_tools_util", version = "0.4.1" } +rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" } tempfile = { version = "3.3", optional = true } termize = "0.1" color-print = "0.3.4" @@ -54,7 +54,7 @@ parking_lot = "0.12" tokio = { version = "1", features = ["io-util"] } [build-dependencies] -rustc_tools_util = { path = "rustc_tools_util", version = "0.4.1" } +rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" } [features] integration = ["tempfile"] diff --git a/rustc_tools_util/Cargo.toml b/rustc_tools_util/Cargo.toml index 189f34dd2a65..716b1ed61443 100644 --- a/rustc_tools_util/Cargo.toml +++ b/rustc_tools_util/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "rustc_tools_util" -version = "0.4.1" +version = "0.4.2" description = "small helper to generate version information for git packages" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" license = "MIT OR Apache-2.0" keywords = ["rustc", "tool", "git", "version", "hash"] categories = ["development-tools"] -edition = "2024" +edition = "2021" # Keep this, for this crate's MSRV to stay low [dependencies] diff --git a/rustc_tools_util/README.md b/rustc_tools_util/README.md index 455654c10900..ff4ca6f830e6 100644 --- a/rustc_tools_util/README.md +++ b/rustc_tools_util/README.md @@ -13,10 +13,10 @@ build = "build.rs" List rustc_tools_util as regular AND build dependency. ````toml [dependencies] -rustc_tools_util = "0.4.1" +rustc_tools_util = "0.4.2" [build-dependencies] -rustc_tools_util = "0.4.1" +rustc_tools_util = "0.4.2" ```` In `build.rs`, generate the data in your `main()` diff --git a/rustc_tools_util/src/lib.rs b/rustc_tools_util/src/lib.rs index cabd9dfa0c7c..423154a69fa0 100644 --- a/rustc_tools_util/src/lib.rs +++ b/rustc_tools_util/src/lib.rs @@ -188,7 +188,7 @@ mod test { let vi = get_version_info!(); assert_eq!(vi.major, 0); assert_eq!(vi.minor, 4); - assert_eq!(vi.patch, 1); + assert_eq!(vi.patch, 2); assert_eq!(vi.crate_name, "rustc_tools_util"); // hard to make positive tests for these since they will always change assert!(vi.commit_hash.is_none()); @@ -200,7 +200,7 @@ mod test { #[test] fn test_display_local() { let vi = get_version_info!(); - assert_eq!(vi.to_string(), "rustc_tools_util 0.4.1"); + assert_eq!(vi.to_string(), "rustc_tools_util 0.4.2"); } #[test] @@ -209,7 +209,7 @@ mod test { let s = format!("{vi:?}"); assert_eq!( s, - "VersionInfo { crate_name: \"rustc_tools_util\", major: 0, minor: 4, patch: 1 }" + "VersionInfo { crate_name: \"rustc_tools_util\", major: 0, minor: 4, patch: 2 }" ); } } From 87fbd4e5df460c683cef6d772e3d55af09ab8ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 24 Jan 2025 14:16:56 +0100 Subject: [PATCH 108/991] Remove `build-gccjit.sh` script --- .../host-x86_64/x86_64-gnu-llvm-18/Dockerfile | 3 -- .../host-x86_64/x86_64-gnu-llvm-19/Dockerfile | 3 -- .../host-x86_64/x86_64-gnu-tools/Dockerfile | 3 -- src/ci/docker/scripts/build-gccjit.sh | 37 ------------------- 4 files changed, 46 deletions(-) delete mode 100755 src/ci/docker/scripts/build-gccjit.sh diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile index 0a58f337d9dd..374d12cc087e 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile @@ -55,9 +55,6 @@ ENV RUST_CONFIGURE_ARGS \ --set rust.thin-lto-import-instr-limit=10 COPY scripts/shared.sh /scripts/ -COPY scripts/build-gccjit.sh /scripts/ - -RUN /scripts/build-gccjit.sh /scripts ARG SCRIPT_ARG diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile index 092847cdfe04..e0ed2e227f81 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile @@ -55,9 +55,6 @@ ENV RUST_CONFIGURE_ARGS \ --set rust.thin-lto-import-instr-limit=10 COPY scripts/shared.sh /scripts/ -COPY scripts/build-gccjit.sh /scripts/ - -RUN /scripts/build-gccjit.sh /scripts ARG SCRIPT_ARG diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile index ab749b3fdd5a..89806634c6c2 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile @@ -90,9 +90,6 @@ ENV HOST_TARGET x86_64-unknown-linux-gnu #ENV FORCE_CI_RUSTC 1 COPY scripts/shared.sh /scripts/ -COPY scripts/build-gccjit.sh /scripts/ - -RUN /scripts/build-gccjit.sh /scripts # For now, we need to use `--unsafe-perm=true` to go around an issue when npm tries # to create a new folder. For reference: diff --git a/src/ci/docker/scripts/build-gccjit.sh b/src/ci/docker/scripts/build-gccjit.sh deleted file mode 100755 index 43ed2270d313..000000000000 --- a/src/ci/docker/scripts/build-gccjit.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -GIT_REPO="https://github.com/rust-lang/gcc" - -# This commit hash needs to be updated to use a more recent gcc fork version. -GIT_COMMIT="45648c2edd4ecd862d9f08196d3d6c6ccba79f07" - -set -ex - -cd $1 - -source shared.sh - -# Setting up folders for GCC -curl -L "$GIT_REPO/archive/$GIT_COMMIT.tar.gz" | - tar -xz --transform "s/gcc-$GIT_COMMIT/gcc-src/" - -mkdir gcc-build gcc-install -pushd gcc-build - -# Building GCC. -hide_output \ - ../gcc-src/configure \ - --enable-host-shared \ - --enable-languages=jit \ - --enable-checking=release \ - --disable-bootstrap \ - --disable-multilib \ - --prefix=$(pwd)/../gcc-install \ - -hide_output make -j$(nproc) -hide_output make install - -popd -rm -rf gcc-src gcc-build -ln -s /scripts/gcc-install/lib/libgccjit.so /usr/lib/x86_64-linux-gnu/libgccjit.so -ln -s /scripts/gcc-install/lib/libgccjit.so /usr/lib/x86_64-linux-gnu/libgccjit.so.0 From a0cf0f2eb42252f58729ce30b13eec9fd0716a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 12 Feb 2025 10:31:55 +0100 Subject: [PATCH 109/991] Update GCC submodule --- src/gcc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gcc b/src/gcc index fd3498bff0b9..e607be166673 160000 --- a/src/gcc +++ b/src/gcc @@ -1 +1 @@ -Subproject commit fd3498bff0b939dda91d56960acc33d55f2f9cdf +Subproject commit e607be166673a8de9fc07f6f02c60426e556c5f2 From 932f7fd8e4f1c2b695fdf402d370a21bb3f78038 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Sat, 15 Feb 2025 00:47:49 +0000 Subject: [PATCH 110/991] Make phantom variance markers transparent --- library/core/src/marker/variance.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/core/src/marker/variance.rs b/library/core/src/marker/variance.rs index 23334e6575dd..235f8a3bb79f 100644 --- a/library/core/src/marker/variance.rs +++ b/library/core/src/marker/variance.rs @@ -136,6 +136,8 @@ phantom_lifetime! { /// For all `'a`, the following are guaranteed: /// * `size_of::>() == 0` /// * `align_of::>() == 1` + #[rustc_pub_transparent] + #[repr(transparent)] pub struct PhantomCovariantLifetime<'a>(PhantomCovariant<&'a ()>); /// Zero-sized type used to mark a lifetime as contravariant. /// @@ -149,6 +151,8 @@ phantom_lifetime! { /// For all `'a`, the following are guaranteed: /// * `size_of::>() == 0` /// * `align_of::>() == 1` + #[rustc_pub_transparent] + #[repr(transparent)] pub struct PhantomContravariantLifetime<'a>(PhantomContravariant<&'a ()>); /// Zero-sized type used to mark a lifetime as invariant. /// @@ -162,6 +166,8 @@ phantom_lifetime! { /// For all `'a`, the following are guaranteed: /// * `size_of::>() == 0` /// * `align_of::>() == 1` + #[rustc_pub_transparent] + #[repr(transparent)] pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>); } @@ -179,6 +185,8 @@ phantom_type! { /// For all `T`, the following are guaranteed: /// * `size_of::>() == 0` /// * `align_of::>() == 1` + #[rustc_pub_transparent] + #[repr(transparent)] pub struct PhantomCovariant(PhantomData T>); /// Zero-sized type used to mark a type parameter as contravariant. /// @@ -193,6 +201,8 @@ phantom_type! { /// For all `T`, the following are guaranteed: /// * `size_of::>() == 0` /// * `align_of::>() == 1` + #[rustc_pub_transparent] + #[repr(transparent)] pub struct PhantomContravariant(PhantomData); /// Zero-sized type used to mark a type parameter as invariant. /// @@ -206,6 +216,8 @@ phantom_type! { /// For all `T`, the following are guaranteed: /// * `size_of::>() == 0` /// * `align_of::>() == 1` + #[rustc_pub_transparent] + #[repr(transparent)] pub struct PhantomInvariant(PhantomData T>); } From 8b3506c7d1e1535811e3e7f48892fbab401d696c Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 15 Feb 2025 05:09:23 +0000 Subject: [PATCH 111/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 1f451b8c0caa..9f84dda4397e 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -6dce9f8c2d8dde4c9ea20bab981cd70229c37fdc +54a0f387ea8c7bcb79b8e40c074a484d31b51990 From 133882920bdea4fb8c6d598f85e2a2296cce242e Mon Sep 17 00:00:00 2001 From: alexey semenyuk Date: Sat, 15 Feb 2025 14:47:18 +0500 Subject: [PATCH 112/991] Add example for macro_use --- clippy_lints/src/macro_use.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs index 374128665392..bb6e22d9e5c7 100644 --- a/clippy_lints/src/macro_use.rs +++ b/clippy_lints/src/macro_use.rs @@ -21,7 +21,21 @@ declare_clippy_lint! { /// ### Example /// ```rust,ignore /// #[macro_use] - /// use some_macro; + /// extern crate some_crate; + /// + /// fn main() { + /// some_macro!(); + /// } + /// ``` + /// + /// Use instead: + /// + /// ```rust,ignore + /// use some_crate::some_macro; + /// + /// fn main() { + /// some_macro!(); + /// } /// ``` #[clippy::version = "1.44.0"] pub MACRO_USE_IMPORTS, From 4f87987e3f361a7d38bdf59d6542ba621f100c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 15 Feb 2025 02:30:24 +0800 Subject: [PATCH 113/991] bootstrap: build compiler libs with version number of libs being built Previously, on a non-stable channel, it's possible for two builds from different versioned sources (e.g. 1.84.0 vs 1.84.1) to produce `librustc_driver*.so` with the same filename hashes. This causes problems with side-by-side installs wrt. linker search paths because 1.84.1 rustc bin and 1.84.0 may try to link to the "same" `librustc_driver*.so` (same filename hash) but fail because the contents of the so is actually different. We try to mitigate this by including the version number of artifacts being built via `__CARGO_DEFAULT_LIB_METADATA`. --- src/bootstrap/src/core/builder/cargo.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 59680af00622..5064a83159e8 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -779,6 +779,12 @@ impl Builder<'_> { Mode::Codegen => metadata.push_str("codegen"), _ => {} } + // `rustc_driver`'s version number is always `0.0.0`, which can cause linker search path + // problems on side-by-side installs because we don't include the version number of the + // `rustc_driver` being built. This can cause builds of different version numbers to produce + // `librustc_driver*.so` artifacts that end up with identical filename hashes. + metadata.push_str(&self.version); + cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata); if cmd_kind == Kind::Clippy { From 95c6866dd4ab3de3b21aa02ca93741c0010836f8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 Feb 2025 15:56:15 +0100 Subject: [PATCH 114/991] Make UI tests annotations mandatory --- tests/compile-test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/compile-test.rs b/tests/compile-test.rs index d1b1a1d23232..838ca2919a26 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -153,7 +153,7 @@ impl TestContext { }; let defaults = config.comment_defaults.base(); defaults.exit_status = None.into(); - defaults.require_annotations = None.into(); + defaults.require_annotations = Some(Spanned::dummy(true)).into(); defaults.diagnostic_code_prefix = Some(Spanned::dummy("clippy::".into())).into(); defaults.set_custom("rustfix", RustfixMode::Everything); if let Some(collector) = self.diagnostic_collector.clone() { From f666fd6417a87fcb69f7e62ac0c41712099046a4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 Feb 2025 17:57:08 +0100 Subject: [PATCH 115/991] Update UI tests --- tests/ui/absurd-extreme-comparisons.rs | 56 +- tests/ui/absurd-extreme-comparisons.stderr | 34 +- tests/ui/allow_attributes.fixed | 3 + tests/ui/allow_attributes.rs | 3 + tests/ui/allow_attributes.stderr | 4 +- tests/ui/allow_attributes_without_reason.rs | 5 + .../ui/allow_attributes_without_reason.stderr | 8 +- tests/ui/almost_complete_range.fixed | 27 + tests/ui/almost_complete_range.rs | 27 + tests/ui/almost_complete_range.stderr | 52 +- tests/ui/approx_const.rs | 69 ++- tests/ui/approx_const.stderr | 44 +- tests/ui/arc_with_non_send_sync.rs | 3 + tests/ui/arc_with_non_send_sync.stderr | 4 +- tests/ui/arithmetic_side_effects.rs | 128 +++++ tests/ui/arithmetic_side_effects.stderr | 254 ++++----- tests/ui/as_conversions.rs | 4 +- tests/ui/as_pointer_underscore.fixed | 6 +- tests/ui/as_pointer_underscore.rs | 6 +- tests/ui/as_pointer_underscore.stderr | 2 +- tests/ui/as_ptr_cast_mut.rs | 8 +- tests/ui/as_ptr_cast_mut.stderr | 2 +- tests/ui/as_underscore.fixed | 2 + tests/ui/as_underscore.rs | 2 + tests/ui/as_underscore.stderr | 2 +- tests/ui/asm_syntax_not_x86.rs | 5 + tests/ui/asm_syntax_x86.rs | 24 +- tests/ui/asm_syntax_x86.stderr | 14 +- tests/ui/assertions_on_constants.rs | 36 +- tests/ui/assertions_on_constants.stderr | 22 +- tests/ui/assertions_on_result_states.fixed | 7 + tests/ui/assertions_on_result_states.rs | 7 + tests/ui/assertions_on_result_states.stderr | 12 +- tests/ui/assign_ops.fixed | 11 + tests/ui/assign_ops.rs | 11 + tests/ui/assign_ops.stderr | 20 +- tests/ui/assign_ops2.rs | 34 +- tests/ui/assign_ops2.stderr | 18 +- tests/ui/assigning_clones.fixed | 30 ++ tests/ui/assigning_clones.rs | 30 ++ tests/ui/assigning_clones.stderr | 58 +- tests/ui/async_yields_async.fixed | 6 + tests/ui/async_yields_async.rs | 6 + tests/ui/async_yields_async.stderr | 10 +- tests/ui/attrs.rs | 13 +- tests/ui/attrs.stderr | 48 +- tests/ui/author.rs | 2 + tests/ui/author/blocks.rs | 1 + tests/ui/author/call.rs | 2 + tests/ui/author/if.rs | 2 + tests/ui/author/issue_3849.rs | 2 + tests/ui/author/loop.rs | 2 + tests/ui/author/macro_in_closure.rs | 2 + tests/ui/author/macro_in_loop.rs | 2 + tests/ui/author/matches.rs | 2 + tests/ui/author/repeat.rs | 2 + tests/ui/author/struct.rs | 2 + tests/ui/await_holding_refcell_ref.rs | 18 +- tests/ui/await_holding_refcell_ref.stderr | 22 +- tests/ui/bind_instead_of_map.fixed | 3 + tests/ui/bind_instead_of_map.rs | 3 + tests/ui/bind_instead_of_map.stderr | 4 +- tests/ui/bind_instead_of_map_multipart.fixed | 5 + tests/ui/bind_instead_of_map_multipart.rs | 5 + tests/ui/bind_instead_of_map_multipart.stderr | 11 +- tests/ui/bit_masks.rs | 57 +- tests/ui/bit_masks.stderr | 30 +- tests/ui/blanket_clippy_restriction_lints.rs | 10 +- .../blanket_clippy_restriction_lints.stderr | 6 +- tests/ui/blocks_in_conditions.fixed | 1 + tests/ui/blocks_in_conditions.rs | 1 + tests/ui/blocks_in_conditions.stderr | 2 +- tests/ui/bool_assert_comparison.fixed | 33 ++ tests/ui/bool_assert_comparison.rs | 33 ++ tests/ui/bool_assert_comparison.stderr | 64 +-- tests/ui/bool_comparison.fixed | 25 + tests/ui/bool_comparison.rs | 25 + tests/ui/bool_comparison.stderr | 48 +- tests/ui/bool_to_int_with_if.fixed | 1 + tests/ui/bool_to_int_with_if.rs | 9 + tests/ui/bool_to_int_with_if.stderr | 24 +- tests/ui/borrow_and_ref_as_ptr.fixed | 2 + tests/ui/borrow_and_ref_as_ptr.rs | 2 + tests/ui/borrow_and_ref_as_ptr.stderr | 2 +- tests/ui/borrow_as_ptr.fixed | 4 + tests/ui/borrow_as_ptr.rs | 4 + tests/ui/borrow_as_ptr.stderr | 6 +- tests/ui/borrow_as_ptr_no_std.fixed | 2 + tests/ui/borrow_as_ptr_no_std.rs | 2 + tests/ui/borrow_as_ptr_no_std.stderr | 2 +- tests/ui/borrow_as_ptr_raw_ref.fixed | 2 + tests/ui/borrow_as_ptr_raw_ref.rs | 2 + tests/ui/borrow_as_ptr_raw_ref.stderr | 2 +- tests/ui/borrow_box.fixed | 30 +- tests/ui/borrow_box.rs | 30 +- tests/ui/borrow_box.stderr | 18 +- tests/ui/borrow_deref_ref.fixed | 3 + tests/ui/borrow_deref_ref.rs | 3 + tests/ui/borrow_deref_ref.stderr | 4 +- tests/ui/borrow_deref_ref_unfixable.rs | 5 +- .../borrow_interior_mutable_const/others.rs | 42 +- .../others.stderr | 112 ++-- .../borrow_interior_mutable_const/traits.rs | 51 +- .../traits.stderr | 102 ++-- tests/ui/box_collection.rs | 27 +- tests/ui/box_collection.stderr | 16 +- tests/ui/box_default.fixed | 10 + tests/ui/box_default.rs | 10 + tests/ui/box_default.stderr | 18 +- tests/ui/box_default_no_std.rs | 2 + tests/ui/boxed_local.rs | 14 +- tests/ui/boxed_local.stderr | 6 +- .../branches_sharing_code/false_positives.rs | 2 + .../branches_sharing_code/shared_at_bottom.rs | 33 +- .../shared_at_bottom.stderr | 33 +- .../ui/branches_sharing_code/shared_at_top.rs | 21 +- .../shared_at_top.stderr | 21 +- .../shared_at_top_and_bottom.rs | 15 +- .../shared_at_top_and_bottom.stderr | 25 +- .../branches_sharing_code/valid_if_blocks.rs | 15 +- .../valid_if_blocks.stderr | 16 +- tests/ui/builtin_type_shadow.rs | 3 +- tests/ui/builtin_type_shadow.stderr | 3 +- tests/ui/byte_char_slices.fixed | 5 + tests/ui/byte_char_slices.rs | 5 + tests/ui/byte_char_slices.stderr | 8 +- tests/ui/bytecount.rs | 9 +- tests/ui/bytecount.stderr | 4 +- tests/ui/bytes_count_to_len.fixed | 4 + tests/ui/bytes_count_to_len.rs | 4 + tests/ui/bytes_count_to_len.stderr | 6 +- tests/ui/bytes_nth.fixed | 3 + tests/ui/bytes_nth.rs | 3 + tests/ui/bytes_nth.stderr | 4 +- ...sensitive_file_extension_comparisons.fixed | 6 + ...se_sensitive_file_extension_comparisons.rs | 6 + ...ensitive_file_extension_comparisons.stderr | 10 +- tests/ui/cast.rs | 250 ++++++--- tests/ui/cast.stderr | 182 +++---- tests/ui/cast_abs_to_unsigned.fixed | 18 + tests/ui/cast_abs_to_unsigned.rs | 18 + tests/ui/cast_abs_to_unsigned.stderr | 42 +- tests/ui/cast_alignment.rs | 14 +- tests/ui/cast_alignment.stderr | 6 +- tests/ui/cast_enum_constructor.rs | 8 +- tests/ui/cast_enum_constructor.stderr | 2 +- tests/ui/cast_lossless_bool.fixed | 15 + tests/ui/cast_lossless_bool.rs | 15 + tests/ui/cast_lossless_bool.stderr | 28 +- tests/ui/cast_lossless_float.fixed | 13 + tests/ui/cast_lossless_float.rs | 13 + tests/ui/cast_lossless_float.stderr | 24 +- tests/ui/cast_lossless_integer.fixed | 40 ++ tests/ui/cast_lossless_integer.rs | 40 ++ tests/ui/cast_lossless_integer.stderr | 78 +-- tests/ui/cast_nan_to_int.rs | 30 +- tests/ui/cast_nan_to_int.stderr | 10 +- tests/ui/cast_raw_slice_pointer_cast.fixed | 7 + tests/ui/cast_raw_slice_pointer_cast.rs | 7 + tests/ui/cast_raw_slice_pointer_cast.stderr | 12 +- tests/ui/cast_size.64bit.stderr | 34 +- tests/ui/cast_size.rs | 18 + tests/ui/cast_slice_different_sizes.rs | 44 +- tests/ui/cast_slice_different_sizes.stderr | 37 +- tests/ui/cfg_attr_cargo_clippy.fixed | 21 +- tests/ui/cfg_attr_cargo_clippy.rs | 21 +- tests/ui/cfg_attr_cargo_clippy.stderr | 12 +- tests/ui/cfg_attr_rustfmt.fixed | 3 + tests/ui/cfg_attr_rustfmt.rs | 3 + tests/ui/cfg_attr_rustfmt.stderr | 4 +- tests/ui/cfg_not_test.rs | 5 + tests/ui/cfg_not_test.stderr | 8 +- tests/ui/char_lit_as_u8.rs | 5 +- tests/ui/char_lit_as_u8_suggestions.fixed | 4 + tests/ui/char_lit_as_u8_suggestions.rs | 4 + tests/ui/char_lit_as_u8_suggestions.stderr | 6 +- tests/ui/checked_conversions.fixed | 17 + tests/ui/checked_conversions.rs | 17 + tests/ui/checked_conversions.stderr | 32 +- .../ui/checked_unwrap/complex_conditionals.rs | 60 ++- .../complex_conditionals.stderr | 38 +- .../complex_conditionals_nested.rs | 4 +- .../ui/checked_unwrap/simple_conditionals.rs | 74 ++- .../checked_unwrap/simple_conditionals.stderr | 50 +- tests/ui/clear_with_drain.fixed | 21 + tests/ui/clear_with_drain.rs | 21 + tests/ui/clear_with_drain.stderr | 40 +- tests/ui/clone_on_copy.fixed | 9 + tests/ui/clone_on_copy.rs | 9 + tests/ui/clone_on_copy.stderr | 16 +- tests/ui/clone_on_copy_impl.rs | 2 + tests/ui/cloned_instead_of_copied.fixed | 8 + tests/ui/cloned_instead_of_copied.rs | 8 + tests/ui/cloned_instead_of_copied.stderr | 14 +- tests/ui/cmp_null.fixed | 17 +- tests/ui/cmp_null.rs | 17 +- tests/ui/cmp_null.stderr | 8 +- .../ui/cmp_owned/asymmetric_partial_eq.fixed | 6 + tests/ui/cmp_owned/asymmetric_partial_eq.rs | 6 + .../ui/cmp_owned/asymmetric_partial_eq.stderr | 10 +- tests/ui/cmp_owned/comparison_flip.fixed | 2 + tests/ui/cmp_owned/comparison_flip.rs | 2 + tests/ui/cmp_owned/comparison_flip.stderr | 2 +- tests/ui/cmp_owned/with_suggestion.fixed | 6 + tests/ui/cmp_owned/with_suggestion.rs | 6 + tests/ui/cmp_owned/with_suggestion.stderr | 10 +- tests/ui/cmp_owned/without_suggestion.rs | 11 +- tests/ui/cmp_owned/without_suggestion.stderr | 4 +- tests/ui/cognitive_complexity.rs | 60 ++- tests/ui/cognitive_complexity.stderr | 38 +- tests/ui/cognitive_complexity_attr_used.rs | 3 +- tests/ui/collapsible_else_if.fixed | 8 + tests/ui/collapsible_else_if.rs | 8 + tests/ui/collapsible_else_if.stderr | 154 ------ tests/ui/collapsible_if.fixed | 9 + tests/ui/collapsible_if.rs | 9 + tests/ui/collapsible_if.stderr | 139 ----- tests/ui/collapsible_match.rs | 37 +- tests/ui/collapsible_match.stderr | 70 ++- tests/ui/collapsible_match2.rs | 13 +- tests/ui/collapsible_match2.stderr | 61 ++- tests/ui/collapsible_str_replace.fixed | 13 + tests/ui/collapsible_str_replace.rs | 14 + tests/ui/collapsible_str_replace.stderr | 27 +- tests/ui/collection_is_never_read.rs | 62 ++- tests/ui/collection_is_never_read.stderr | 38 +- tests/ui/comparison_chain.rs | 24 +- tests/ui/comparison_chain.stderr | 28 +- tests/ui/comparison_to_empty.fixed | 13 + tests/ui/comparison_to_empty.rs | 13 + tests/ui/comparison_to_empty.stderr | 24 +- tests/ui/const_comparisons.rs | 113 ++-- tests/ui/const_comparisons.stderr | 60 +-- tests/ui/const_is_empty.rs | 79 ++- tests/ui/const_is_empty.stderr | 52 +- tests/ui/copy_iterator.rs | 5 +- tests/ui/copy_iterator.stderr | 3 - tests/ui/crashes/associated-constant-ice.rs | 1 + tests/ui/crashes/cc_seme.rs | 1 + tests/ui/crashes/enum-glob-import-crate.rs | 2 + tests/ui/crashes/ice-10148.rs | 1 + tests/ui/crashes/ice-10508a.rs | 1 + tests/ui/crashes/ice-10508b.rs | 2 + tests/ui/crashes/ice-10508c.rs | 2 + tests/ui/crashes/ice-10972-tait.rs | 1 + tests/ui/crashes/ice-11065.rs | 2 + tests/ui/crashes/ice-11230.fixed | 2 + tests/ui/crashes/ice-11230.rs | 2 + tests/ui/crashes/ice-11230.stderr | 2 +- tests/ui/crashes/ice-11337.rs | 2 + tests/ui/crashes/ice-11422.fixed | 1 + tests/ui/crashes/ice-11422.rs | 1 + tests/ui/crashes/ice-11755.rs | 2 + tests/ui/crashes/ice-11803.rs | 2 + tests/ui/crashes/ice-11939.rs | 2 + tests/ui/crashes/ice-12253.rs | 2 + tests/ui/crashes/ice-12491.fixed | 1 + tests/ui/crashes/ice-12491.rs | 1 + tests/ui/crashes/ice-12585.rs | 2 + tests/ui/crashes/ice-12616.fixed | 1 + tests/ui/crashes/ice-12616.rs | 1 + tests/ui/crashes/ice-13862.rs | 2 + tests/ui/crashes/ice-1588.rs | 2 + tests/ui/crashes/ice-1782.rs | 2 + tests/ui/crashes/ice-1969.rs | 2 + tests/ui/crashes/ice-2499.rs | 2 + tests/ui/crashes/ice-2594.rs | 2 + tests/ui/crashes/ice-2727.rs | 1 + tests/ui/crashes/ice-2760.rs | 2 + tests/ui/crashes/ice-2774.fixed | 5 +- tests/ui/crashes/ice-2774.rs | 5 +- tests/ui/crashes/ice-2862.rs | 1 + tests/ui/crashes/ice-2865.rs | 2 + tests/ui/crashes/ice-3151.rs | 1 + tests/ui/crashes/ice-3462.rs | 2 + tests/ui/crashes/ice-360.rs | 11 +- tests/ui/crashes/ice-360.stderr | 2 +- tests/ui/crashes/ice-3717.fixed | 3 +- tests/ui/crashes/ice-3717.rs | 3 +- tests/ui/crashes/ice-3717.stderr | 1 + tests/ui/crashes/ice-3741.rs | 1 + tests/ui/crashes/ice-3747.rs | 1 + tests/ui/crashes/ice-3969.rs | 11 +- tests/ui/crashes/ice-3969.stderr | 8 +- tests/ui/crashes/ice-4121.rs | 2 + tests/ui/crashes/ice-4545.rs | 2 + tests/ui/crashes/ice-4579.rs | 2 + tests/ui/crashes/ice-4671.rs | 2 + tests/ui/crashes/ice-4727.rs | 2 + tests/ui/crashes/ice-4760.rs | 2 + tests/ui/crashes/ice-4775.rs | 2 + tests/ui/crashes/ice-4968.rs | 1 + tests/ui/crashes/ice-5207.rs | 1 + tests/ui/crashes/ice-5223.rs | 1 + tests/ui/crashes/ice-5238.rs | 1 + tests/ui/crashes/ice-5389.rs | 2 + tests/ui/crashes/ice-5579.rs | 2 + tests/ui/crashes/ice-5835.fixed | 11 - tests/ui/crashes/ice-5835.rs | 6 +- tests/ui/crashes/ice-5835.stderr | 18 +- tests/ui/crashes/ice-5872.fixed | 5 +- tests/ui/crashes/ice-5872.rs | 5 +- tests/ui/crashes/ice-5944.rs | 2 + tests/ui/crashes/ice-6139.rs | 2 + tests/ui/crashes/ice-6153.rs | 2 + tests/ui/crashes/ice-6179.rs | 1 + tests/ui/crashes/ice-6250.rs | 2 + tests/ui/crashes/ice-6251.rs | 3 + tests/ui/crashes/ice-6252.rs | 3 + tests/ui/crashes/ice-6252.stderr | 4 +- tests/ui/crashes/ice-6254.rs | 1 + tests/ui/crashes/ice-6332.rs | 2 + tests/ui/crashes/ice-6539.rs | 1 + tests/ui/crashes/ice-6792.rs | 1 + tests/ui/crashes/ice-6793.rs | 1 + tests/ui/crashes/ice-6840.rs | 1 + tests/ui/crashes/ice-700.rs | 2 + tests/ui/crashes/ice-7012.rs | 2 + tests/ui/crashes/ice-7126.rs | 1 + tests/ui/crashes/ice-7169.fixed | 5 +- tests/ui/crashes/ice-7169.rs | 5 +- tests/ui/crashes/ice-7231.rs | 2 + tests/ui/crashes/ice-7272.rs | 1 + tests/ui/crashes/ice-7340.rs | 2 + tests/ui/crashes/ice-7410.rs | 1 + tests/ui/crashes/ice-7423.rs | 2 + tests/ui/crashes/ice-7868.rs | 1 + tests/ui/crashes/ice-7869.rs | 3 +- tests/ui/crashes/ice-7869.stderr | 1 + tests/ui/crashes/ice-7934.rs | 2 + tests/ui/crashes/ice-8250.fixed | 5 +- tests/ui/crashes/ice-8250.rs | 5 +- tests/ui/crashes/ice-8386.rs | 2 + tests/ui/crashes/ice-8681.rs | 1 + tests/ui/crashes/ice-8821.rs | 2 + tests/ui/crashes/ice-8850.fixed | 7 +- tests/ui/crashes/ice-8850.rs | 7 +- tests/ui/crashes/ice-8850.stderr | 4 +- tests/ui/crashes/ice-9041.rs | 5 +- tests/ui/crashes/ice-9238.rs | 2 + tests/ui/crashes/ice-9242.rs | 2 + tests/ui/crashes/ice-9405.rs | 2 + tests/ui/crashes/ice-9405.stderr | 2 +- tests/ui/crashes/ice-9414.rs | 2 + tests/ui/crashes/ice-9445.rs | 1 + tests/ui/crashes/ice-9459.rs | 2 + tests/ui/crashes/ice-9463.rs | 3 +- tests/ui/crashes/ice-9625.rs | 2 + tests/ui/crashes/ice-9746.rs | 1 + tests/ui/crashes/ice-rust-107877.rs | 2 + tests/ui/crashes/ice_exact_size.rs | 2 + tests/ui/crashes/if_same_then_else.rs | 2 + tests/ui/crashes/implements-trait.rs | 2 + tests/ui/crashes/inherent_impl.rs | 2 + tests/ui/crashes/issue-825.rs | 2 + tests/ui/crashes/issues_loop_mut_cond.rs | 2 + tests/ui/crashes/match_same_arms_const.rs | 2 + tests/ui/crashes/needless_borrow_fp.rs | 2 + .../needless_lifetimes_impl_trait.fixed | 4 +- .../crashes/needless_lifetimes_impl_trait.rs | 4 +- .../needless_lifetimes_impl_trait.stderr | 2 +- .../needless_pass_by_value-w-late-bound.fixed | 3 +- .../needless_pass_by_value-w-late-bound.rs | 3 +- tests/ui/crashes/regressions.rs | 2 + tests/ui/crashes/returns.rs | 1 + tests/ui/crashes/shadow.rs | 2 + tests/ui/crashes/single-match-else.rs | 2 + .../crashes/third-party/conf_allowlisted.rs | 2 + tests/ui/crashes/trivial_bounds.rs | 2 + .../ui/crashes/unreachable-array-or-slice.rs | 1 + .../crashes/used_underscore_binding_macro.rs | 2 + tests/ui/crate_in_macro_def.fixed | 1 + tests/ui/crate_in_macro_def.rs | 1 + .../entrypoint_recursion.rs | 1 + tests/ui/crate_level_checks/no_std_swap.rs | 5 +- .../crate_level_checks/std_main_recursion.rs | 3 +- tests/ui/create_dir.fixed | 2 + tests/ui/create_dir.rs | 2 + tests/ui/create_dir.stderr | 2 +- tests/ui/dbg_macro/dbg_macro.fixed | 57 +- tests/ui/dbg_macro/dbg_macro.rs | 57 +- tests/ui/dbg_macro/dbg_macro.stderr | 36 +- tests/ui/dbg_macro/dbg_macro_unfixable.rs | 10 +- tests/ui/dbg_macro/dbg_macro_unfixable.stderr | 10 +- tests/ui/debug_assert_with_mut_call.rs | 86 ++- tests/ui/debug_assert_with_mut_call.stderr | 54 +- tests/ui/decimal_literal_representation.fixed | 7 + tests/ui/decimal_literal_representation.rs | 7 + .../ui/decimal_literal_representation.stderr | 12 +- .../declare_interior_mutable_const/enums.rs | 36 +- .../enums.stderr | 58 +- .../declare_interior_mutable_const/others.rs | 13 +- .../others.stderr | 8 +- .../declare_interior_mutable_const/traits.rs | 39 +- .../traits.stderr | 72 +-- .../ui/default_constructed_unit_structs.fixed | 6 + tests/ui/default_constructed_unit_structs.rs | 6 + .../default_constructed_unit_structs.stderr | 10 +- tests/ui/default_instead_of_iter_empty.fixed | 3 + tests/ui/default_instead_of_iter_empty.rs | 3 + tests/ui/default_instead_of_iter_empty.stderr | 4 +- ...default_instead_of_iter_empty_no_std.fixed | 2 + .../default_instead_of_iter_empty_no_std.rs | 2 + ...efault_instead_of_iter_empty_no_std.stderr | 2 +- tests/ui/default_numeric_fallback_f64.fixed | 23 + tests/ui/default_numeric_fallback_f64.rs | 23 + tests/ui/default_numeric_fallback_f64.stderr | 44 +- tests/ui/default_numeric_fallback_i32.fixed | 28 + tests/ui/default_numeric_fallback_i32.rs | 28 + tests/ui/default_numeric_fallback_i32.stderr | 54 +- tests/ui/default_trait_access.fixed | 8 + tests/ui/default_trait_access.rs | 8 + tests/ui/default_trait_access.stderr | 14 +- tests/ui/default_union_representation.rs | 12 +- tests/ui/default_union_representation.stderr | 10 +- tests/ui/deref_addrof.fixed | 11 + tests/ui/deref_addrof.rs | 11 + tests/ui/deref_addrof.stderr | 20 +- tests/ui/deref_addrof_double_trigger.rs | 11 +- tests/ui/deref_addrof_double_trigger.stderr | 4 +- tests/ui/deref_addrof_macro.rs | 1 + tests/ui/deref_by_slicing.fixed | 10 + tests/ui/deref_by_slicing.rs | 10 + tests/ui/deref_by_slicing.stderr | 18 +- tests/ui/derivable_impls.rs | 11 + tests/ui/derivable_impls.stderr | 44 +- tests/ui/derive.rs | 15 +- tests/ui/derive.stderr | 56 +- tests/ui/derive_ord_xor_partial_ord.rs | 12 +- tests/ui/derive_ord_xor_partial_ord.stderr | 22 +- tests/ui/derive_partial_eq_without_eq.fixed | 17 +- tests/ui/derive_partial_eq_without_eq.rs | 17 +- tests/ui/derive_partial_eq_without_eq.stderr | 32 +- tests/ui/derived_hash_with_manual_eq.rs | 6 +- tests/ui/derived_hash_with_manual_eq.stderr | 6 +- tests/ui/disallowed_names.rs | 44 +- tests/ui/disallowed_names.stderr | 26 +- tests/ui/disallowed_script_idents.rs | 6 +- tests/ui/disallowed_script_idents.stderr | 2 +- tests/ui/diverging_sub_expression.rs | 35 +- tests/ui/diverging_sub_expression.stderr | 20 +- tests/ui/doc/doc-fixable.fixed | 34 ++ tests/ui/doc/doc-fixable.rs | 34 ++ tests/ui/doc/doc-fixable.stderr | 64 +-- tests/ui/doc/doc_include_without_cfg.fixed | 6 +- tests/ui/doc/doc_include_without_cfg.rs | 6 +- tests/ui/doc/doc_include_without_cfg.stderr | 2 +- tests/ui/doc/footnote_issue_13183.rs | 1 + tests/ui/doc/issue_12795.fixed | 12 +- tests/ui/doc/issue_12795.rs | 12 +- tests/ui/doc/issue_1832.rs | 1 + tests/ui/doc/issue_902.rs | 1 + tests/ui/doc/issue_9473.fixed | 1 + tests/ui/doc/issue_9473.rs | 1 + tests/ui/doc/needless_doctest_main.rs | 2 + tests/ui/doc/unbalanced_ticks.rs | 25 +- tests/ui/doc/unbalanced_ticks.stderr | 172 +++--- tests/ui/doc_errors.rs | 23 +- tests/ui/doc_errors.stderr | 12 +- tests/ui/doc_link_with_quotes.rs | 6 +- tests/ui/doc_link_with_quotes.stderr | 2 +- tests/ui/doc_unsafe.rs | 6 + tests/ui/doc_unsafe.stderr | 10 +- tests/ui/double_comparison.fixed | 8 + tests/ui/double_comparison.rs | 8 + tests/ui/double_comparison.stderr | 14 +- tests/ui/double_ended_iterator_last.fixed | 2 + tests/ui/double_ended_iterator_last.rs | 2 + tests/ui/double_ended_iterator_last.stderr | 2 +- tests/ui/double_must_use.rs | 12 +- tests/ui/double_must_use.stderr | 6 +- tests/ui/double_parens.rs | 20 +- tests/ui/double_parens.stderr | 10 +- tests/ui/drain_collect.fixed | 10 + tests/ui/drain_collect.rs | 10 + tests/ui/drain_collect.stderr | 26 +- tests/ui/drain_collect_nostd.fixed | 1 + tests/ui/drain_collect_nostd.rs | 1 + tests/ui/drop_non_drop.rs | 6 +- tests/ui/drop_non_drop.stderr | 4 +- tests/ui/duplicate_underscore_argument.rs | 5 +- tests/ui/duration_subsec.fixed | 5 + tests/ui/duration_subsec.rs | 5 + tests/ui/duration_subsec.stderr | 8 +- tests/ui/eager_transmute.fixed | 17 + tests/ui/eager_transmute.rs | 17 + tests/ui/eager_transmute.stderr | 32 +- tests/ui/else_if_without_else.rs | 12 +- tests/ui/else_if_without_else.stderr | 10 +- tests/ui/empty_docs.rs | 9 + tests/ui/empty_docs.stderr | 16 +- tests/ui/empty_drop.rs | 2 + tests/ui/empty_drop.stderr | 4 +- tests/ui/empty_enum.rs | 3 +- .../empty_enum_variants_with_brackets.fixed | 12 +- tests/ui/empty_enum_variants_with_brackets.rs | 12 +- .../empty_enum_variants_with_brackets.stderr | 24 +- tests/ui/empty_enum_without_never_type.rs | 2 + .../ui/empty_line_after/doc_comments.1.fixed | 30 +- .../ui/empty_line_after/doc_comments.2.fixed | 55 +- tests/ui/empty_line_after/doc_comments.rs | 30 +- tests/ui/empty_line_after/doc_comments.stderr | 65 ++- tests/ui/empty_loop.rs | 3 + tests/ui/empty_loop.stderr | 4 +- tests/ui/empty_loop_no_std.rs | 3 +- tests/ui/empty_structs_with_brackets.fixed | 2 + tests/ui/empty_structs_with_brackets.rs | 2 + tests/ui/empty_structs_with_brackets.stderr | 2 +- tests/ui/endian_bytes.rs | 86 +++ tests/ui/endian_bytes.stderr | 170 +++--- tests/ui/entry.fixed | 9 + tests/ui/entry.rs | 11 + tests/ui/entry.stderr | 48 +- tests/ui/entry_btree.fixed | 1 + tests/ui/entry_btree.rs | 1 + tests/ui/entry_btree.stderr | 2 + tests/ui/entry_with_else.fixed | 7 + tests/ui/entry_with_else.rs | 7 + tests/ui/entry_with_else.stderr | 26 +- tests/ui/enum_clike_unportable_variant.rs | 29 +- tests/ui/enum_clike_unportable_variant.stderr | 16 +- tests/ui/enum_glob_use.fixed | 3 + tests/ui/enum_glob_use.rs | 3 + tests/ui/enum_glob_use.stderr | 4 +- tests/ui/enum_variants.rs | 34 +- tests/ui/enum_variants.stderr | 11 +- tests/ui/eprint_with_newline.fixed | 29 +- tests/ui/eprint_with_newline.rs | 29 +- tests/ui/eprint_with_newline.stderr | 20 +- tests/ui/eq_op.rs | 91 ++-- tests/ui/eq_op.stderr | 56 +- tests/ui/eq_op_macros.rs | 28 +- tests/ui/eq_op_macros.stderr | 22 +- tests/ui/equatable_if_let.fixed | 14 + tests/ui/equatable_if_let.rs | 14 + tests/ui/equatable_if_let.stderr | 26 +- tests/ui/erasing_op.rs | 17 +- tests/ui/erasing_op.stderr | 8 +- tests/ui/err_expect.fixed | 2 + tests/ui/err_expect.rs | 2 + tests/ui/err_expect.stderr | 2 +- tests/ui/error_impl_error.rs | 12 +- tests/ui/error_impl_error.stderr | 12 +- tests/ui/eta.fixed | 35 ++ tests/ui/eta.rs | 35 ++ tests/ui/eta.stderr | 68 +-- tests/ui/eta_nostd.fixed | 1 + tests/ui/eta_nostd.rs | 1 + tests/ui/excessive_precision.fixed | 16 + tests/ui/excessive_precision.rs | 16 + tests/ui/excessive_precision.stderr | 30 +- tests/ui/exhaustive_items.fixed | 3 + tests/ui/exhaustive_items.rs | 3 + tests/ui/exhaustive_items.stderr | 7 +- tests/ui/exit1.rs | 5 +- tests/ui/exit2.rs | 5 +- tests/ui/exit3.rs | 2 + tests/ui/expect.rs | 9 +- tests/ui/expect.stderr | 4 +- tests/ui/expect_fun_call.fixed | 15 + tests/ui/expect_fun_call.rs | 15 + tests/ui/expect_fun_call.stderr | 28 +- tests/ui/explicit_auto_deref.fixed | 46 ++ tests/ui/explicit_auto_deref.rs | 46 ++ tests/ui/explicit_auto_deref.stderr | 90 ++-- tests/ui/explicit_counter_loop.rs | 32 +- tests/ui/explicit_counter_loop.stderr | 18 +- tests/ui/explicit_deref_methods.fixed | 12 + tests/ui/explicit_deref_methods.rs | 12 + tests/ui/explicit_deref_methods.stderr | 22 +- tests/ui/explicit_into_iter_loop.fixed | 6 + tests/ui/explicit_into_iter_loop.rs | 6 + tests/ui/explicit_into_iter_loop.stderr | 10 +- tests/ui/explicit_iter_loop.fixed | 18 + tests/ui/explicit_iter_loop.rs | 18 + tests/ui/explicit_iter_loop.stderr | 34 +- tests/ui/explicit_write.fixed | 13 + tests/ui/explicit_write.rs | 13 + tests/ui/explicit_write.stderr | 24 +- tests/ui/extend_with_drain.fixed | 4 + tests/ui/extend_with_drain.rs | 4 + tests/ui/extend_with_drain.stderr | 6 +- tests/ui/extra_unused_lifetimes.rs | 7 + tests/ui/extra_unused_lifetimes.stderr | 12 +- tests/ui/extra_unused_type_parameters.fixed | 8 + tests/ui/extra_unused_type_parameters.rs | 8 + tests/ui/extra_unused_type_parameters.stderr | 14 +- .../extra_unused_type_parameters_unfixable.rs | 9 +- ...ra_unused_type_parameters_unfixable.stderr | 4 +- tests/ui/fallible_impl_from.rs | 12 +- tests/ui/fallible_impl_from.stderr | 24 +- tests/ui/field_reassign_with_default.rs | 11 + tests/ui/field_reassign_with_default.stderr | 58 +- tests/ui/field_scoped_visibility_modifiers.rs | 3 + .../field_scoped_visibility_modifiers.stderr | 4 +- tests/ui/filetype_is_file.rs | 9 +- tests/ui/filetype_is_file.stderr | 4 +- tests/ui/filter_map_bool_then.fixed | 10 + tests/ui/filter_map_bool_then.rs | 10 + tests/ui/filter_map_bool_then.stderr | 18 +- tests/ui/filter_map_identity.fixed | 68 ++- tests/ui/filter_map_identity.rs | 66 ++- tests/ui/filter_map_identity.stderr | 112 ++-- tests/ui/filter_map_next.rs | 5 +- tests/ui/filter_map_next.stderr | 3 - tests/ui/filter_map_next_fixable.fixed | 2 + tests/ui/filter_map_next_fixable.rs | 2 + tests/ui/filter_map_next_fixable.stderr | 2 +- tests/ui/find_map.rs | 2 + tests/ui/flat_map_identity.fixed | 3 + tests/ui/flat_map_identity.rs | 3 + tests/ui/flat_map_identity.stderr | 4 +- tests/ui/flat_map_option.fixed | 2 + tests/ui/flat_map_option.rs | 2 + tests/ui/flat_map_option.stderr | 2 +- tests/ui/float_arithmetic.rs | 53 +- tests/ui/float_arithmetic.stderr | 32 +- tests/ui/float_cmp.rs | 18 +- tests/ui/float_cmp.stderr | 10 +- tests/ui/float_cmp_const.rs | 24 +- tests/ui/float_cmp_const.stderr | 14 +- tests/ui/float_equality_without_abs.rs | 35 +- tests/ui/float_equality_without_abs.stderr | 20 +- tests/ui/floating_point_abs.fixed | 8 + tests/ui/floating_point_abs.rs | 8 + tests/ui/floating_point_abs.stderr | 14 +- tests/ui/floating_point_arithmetic_nostd.rs | 2 + tests/ui/floating_point_exp.fixed | 5 + tests/ui/floating_point_exp.rs | 5 + tests/ui/floating_point_exp.stderr | 8 +- tests/ui/floating_point_hypot.fixed | 3 + tests/ui/floating_point_hypot.rs | 3 + tests/ui/floating_point_hypot.stderr | 4 +- tests/ui/floating_point_log.fixed | 29 + tests/ui/floating_point_log.rs | 29 + tests/ui/floating_point_log.stderr | 144 ++--- tests/ui/floating_point_logbase.fixed | 5 + tests/ui/floating_point_logbase.rs | 5 + tests/ui/floating_point_logbase.stderr | 8 +- tests/ui/floating_point_mul_add.fixed | 13 + tests/ui/floating_point_mul_add.rs | 13 + tests/ui/floating_point_mul_add.stderr | 24 +- tests/ui/floating_point_powf.fixed | 32 ++ tests/ui/floating_point_powf.rs | 32 ++ tests/ui/floating_point_powf.stderr | 62 +-- tests/ui/floating_point_powi.fixed | 14 + tests/ui/floating_point_powi.rs | 14 + tests/ui/floating_point_powi.stderr | 26 +- tests/ui/floating_point_rad.fixed | 8 + tests/ui/floating_point_rad.rs | 8 + tests/ui/floating_point_rad.stderr | 14 +- tests/ui/fn_to_numeric_cast.64bit.stderr | 44 +- tests/ui/fn_to_numeric_cast.rs | 23 + tests/ui/fn_to_numeric_cast_any.rs | 53 +- tests/ui/fn_to_numeric_cast_any.stderr | 32 +- tests/ui/for_kv_map.fixed | 20 +- tests/ui/for_kv_map.rs | 20 +- tests/ui/for_kv_map.stderr | 10 +- tests/ui/forget_non_drop.rs | 6 +- tests/ui/forget_non_drop.stderr | 4 +- tests/ui/format.fixed | 14 + tests/ui/format.rs | 15 + tests/ui/format.stderr | 29 +- tests/ui/format_args.fixed | 26 + tests/ui/format_args.rs | 26 + tests/ui/format_args.stderr | 50 +- tests/ui/format_args_unfixable.rs | 75 ++- tests/ui/format_args_unfixable.stderr | 50 +- tests/ui/format_collect.rs | 9 +- tests/ui/format_collect.stderr | 16 +- tests/ui/format_push_string.rs | 15 +- tests/ui/format_push_string.stderr | 11 +- tests/ui/formatting.rs | 30 +- tests/ui/formatting.stderr | 10 +- tests/ui/four_forward_slashes.fixed | 6 +- tests/ui/four_forward_slashes.rs | 6 +- tests/ui/four_forward_slashes.stderr | 13 +- .../ui/four_forward_slashes_first_line.fixed | 1 + tests/ui/four_forward_slashes_first_line.rs | 1 + .../ui/four_forward_slashes_first_line.stderr | 1 + tests/ui/from_iter_instead_of_collect.fixed | 15 + tests/ui/from_iter_instead_of_collect.rs | 15 + tests/ui/from_iter_instead_of_collect.stderr | 28 +- tests/ui/from_over_into.fixed | 7 + tests/ui/from_over_into.rs | 7 + tests/ui/from_over_into.stderr | 19 +- tests/ui/from_over_into_unfixable.rs | 12 +- tests/ui/from_over_into_unfixable.stderr | 6 +- tests/ui/from_raw_with_void_ptr.rs | 15 +- tests/ui/from_raw_with_void_ptr.stderr | 16 +- tests/ui/from_str_radix_10.fixed | 26 +- tests/ui/from_str_radix_10.rs | 26 +- tests/ui/from_str_radix_10.stderr | 14 +- tests/ui/functions.rs | 52 +- tests/ui/functions.stderr | 32 +- tests/ui/functions_maxlines.rs | 5 +- tests/ui/functions_maxlines.stderr | 3 - tests/ui/future_not_send.rs | 24 +- tests/ui/future_not_send.stderr | 41 +- tests/ui/get_first.fixed | 15 +- tests/ui/get_first.rs | 15 +- tests/ui/get_first.stderr | 8 +- tests/ui/get_last_with_len.fixed | 6 + tests/ui/get_last_with_len.rs | 6 + tests/ui/get_last_with_len.stderr | 10 +- tests/ui/get_unwrap.fixed | 30 ++ tests/ui/get_unwrap.rs | 30 ++ tests/ui/get_unwrap.stderr | 56 +- tests/ui/identity_op.fixed | 187 ++++--- tests/ui/identity_op.rs | 187 ++++--- tests/ui/identity_op.stderr | 124 ++--- tests/ui/if_let_mutex.rs | 4 + tests/ui/if_not_else.fixed | 10 +- tests/ui/if_not_else.rs | 10 +- tests/ui/if_not_else.stderr | 23 +- tests/ui/if_not_else_bittest.rs | 2 + tests/ui/if_same_then_else.rs | 16 +- tests/ui/if_same_then_else.stderr | 20 +- tests/ui/if_same_then_else2.rs | 18 +- tests/ui/if_same_then_else2.stderr | 20 +- tests/ui/if_then_some_else_none.fixed | 7 +- tests/ui/if_then_some_else_none.rs | 16 +- tests/ui/if_then_some_else_none.stderr | 22 +- tests/ui/ifs_same_cond.rs | 12 +- tests/ui/ifs_same_cond.stderr | 12 +- tests/ui/impl.rs | 12 +- tests/ui/impl.stderr | 13 +- tests/ui/impl_trait_in_params.rs | 12 +- tests/ui/impl_trait_in_params.stderr | 22 +- tests/ui/implicit_clone.fixed | 11 + tests/ui/implicit_clone.rs | 11 + tests/ui/implicit_clone.stderr | 20 +- tests/ui/implicit_hasher.fixed | 9 + tests/ui/implicit_hasher.rs | 9 + tests/ui/implicit_hasher.stderr | 23 +- tests/ui/implicit_return.fixed | 16 + tests/ui/implicit_return.rs | 16 + tests/ui/implicit_return.stderr | 30 +- tests/ui/implicit_saturating_add.rs | 24 + tests/ui/implicit_saturating_add.stderr | 204 ++++---- tests/ui/implicit_saturating_sub.rs | 24 + tests/ui/implicit_saturating_sub.stderr | 110 ++-- tests/ui/implied_bounds_in_impls.fixed | 23 + tests/ui/implied_bounds_in_impls.rs | 23 + tests/ui/implied_bounds_in_impls.stderr | 44 +- tests/ui/incompatible_msrv.rs | 9 +- tests/ui/incompatible_msrv.stderr | 4 +- tests/ui/inconsistent_digit_grouping.fixed | 10 + tests/ui/inconsistent_digit_grouping.rs | 10 + tests/ui/inconsistent_digit_grouping.stderr | 10 +- .../ui/inconsistent_struct_constructor.fixed | 2 + tests/ui/inconsistent_struct_constructor.rs | 2 + .../ui/inconsistent_struct_constructor.stderr | 2 +- .../if_let_slice_binding.fixed | 30 +- .../if_let_slice_binding.rs | 30 +- .../if_let_slice_binding.stderr | 52 +- tests/ui/indexing_slicing_index.rs | 6 + tests/ui/indexing_slicing_index.stderr | 26 +- tests/ui/indexing_slicing_slice.rs | 36 +- tests/ui/indexing_slicing_slice.stderr | 22 +- tests/ui/ineffective_open_options.fixed | 4 +- tests/ui/ineffective_open_options.rs | 6 +- tests/ui/ineffective_open_options.stderr | 12 +- tests/ui/inefficient_to_string.fixed | 6 + tests/ui/inefficient_to_string.rs | 6 + tests/ui/inefficient_to_string.stderr | 10 +- tests/ui/infallible_destructuring_match.rs | 4 + .../ui/infallible_destructuring_match.stderr | 10 +- tests/ui/infinite_iter.rs | 44 +- tests/ui/infinite_iter.stderr | 33 +- tests/ui/infinite_loop.rs | 55 +- tests/ui/infinite_loop.stderr | 36 +- tests/ui/infinite_loops.rs | 39 +- tests/ui/infinite_loops.stderr | 37 +- tests/ui/inherent_to_string.rs | 6 +- tests/ui/inherent_to_string.stderr | 4 +- tests/ui/init_numbered_fields.fixed | 1 + tests/ui/init_numbered_fields.rs | 3 + tests/ui/init_numbered_fields.stderr | 6 +- tests/ui/inline_fn_without_body.fixed | 3 + tests/ui/inline_fn_without_body.rs | 3 + tests/ui/inline_fn_without_body.stderr | 10 +- tests/ui/inspect_for_each.rs | 3 +- tests/ui/inspect_for_each.stderr | 1 + tests/ui/int_plus_one.fixed | 4 + tests/ui/int_plus_one.rs | 4 + tests/ui/int_plus_one.stderr | 6 +- tests/ui/integer_division.rs | 9 +- tests/ui/integer_division.stderr | 4 +- tests/ui/integer_division_remainder_used.rs | 9 + .../ui/integer_division_remainder_used.stderr | 16 +- tests/ui/into_iter_on_ref.fixed | 78 ++- tests/ui/into_iter_on_ref.rs | 78 ++- tests/ui/into_iter_on_ref.stderr | 172 +++--- tests/ui/into_iter_without_iter.rs | 11 +- tests/ui/into_iter_without_iter.stderr | 2 +- tests/ui/invalid_null_ptr_usage.fixed | 22 + tests/ui/invalid_null_ptr_usage.rs | 22 + tests/ui/invalid_null_ptr_usage.stderr | 42 +- tests/ui/invalid_null_ptr_usage_no_std.fixed | 22 + tests/ui/invalid_null_ptr_usage_no_std.rs | 22 + tests/ui/invalid_null_ptr_usage_no_std.stderr | 42 +- tests/ui/invalid_upcast_comparisons.rs | 83 ++- tests/ui/invalid_upcast_comparisons.stderr | 52 +- tests/ui/is_digit_ascii_radix.fixed | 3 + tests/ui/is_digit_ascii_radix.rs | 3 + tests/ui/is_digit_ascii_radix.stderr | 4 +- tests/ui/issue-111399.rs | 2 + tests/ui/issue-7447.rs | 8 +- tests/ui/issue-7447.stderr | 2 +- tests/ui/issue_2356.fixed | 1 + tests/ui/issue_2356.rs | 1 + tests/ui/issue_4266.rs | 11 +- tests/ui/issue_4266.stderr | 4 +- tests/ui/items_after_statement.rs | 9 +- tests/ui/items_after_statement.stderr | 10 +- .../after_proc_macros.rs | 1 + .../imported_module.rs | 1 + .../items_after_test_module/in_submodule.rs | 1 + .../multiple_modules.rs | 2 + .../items_after_test_module/root_module.fixed | 1 + .../ui/items_after_test_module/root_module.rs | 1 + tests/ui/iter_cloned_collect.fixed | 4 + tests/ui/iter_cloned_collect.rs | 5 + tests/ui/iter_cloned_collect.stderr | 9 +- tests/ui/iter_count.fixed | 25 + tests/ui/iter_count.rs | 25 + tests/ui/iter_count.stderr | 48 +- tests/ui/iter_filter_is_ok.fixed | 36 +- tests/ui/iter_filter_is_ok.rs | 36 +- tests/ui/iter_filter_is_ok.stderr | 30 +- tests/ui/iter_filter_is_some.fixed | 30 +- tests/ui/iter_filter_is_some.rs | 30 +- tests/ui/iter_filter_is_some.stderr | 18 +- tests/ui/iter_kv_map.fixed | 58 +- tests/ui/iter_kv_map.rs | 58 +- tests/ui/iter_kv_map.stderr | 142 ++--- tests/ui/iter_next_loop.rs | 1 + tests/ui/iter_next_slice.fixed | 4 + tests/ui/iter_next_slice.rs | 4 + tests/ui/iter_next_slice.stderr | 6 +- tests/ui/iter_not_returning_iterator.rs | 11 +- tests/ui/iter_not_returning_iterator.stderr | 4 +- tests/ui/iter_nth.fixed | 8 + tests/ui/iter_nth.rs | 8 + tests/ui/iter_nth.stderr | 14 +- tests/ui/iter_nth_zero.fixed | 3 + tests/ui/iter_nth_zero.rs | 3 + tests/ui/iter_nth_zero.stderr | 4 +- tests/ui/iter_on_empty_collections.fixed | 7 + tests/ui/iter_on_empty_collections.rs | 7 + tests/ui/iter_on_empty_collections.stderr | 12 +- tests/ui/iter_on_single_items.fixed | 6 + tests/ui/iter_on_single_items.rs | 6 + tests/ui/iter_on_single_items.stderr | 10 +- tests/ui/iter_out_of_bounds.rs | 42 +- tests/ui/iter_out_of_bounds.stderr | 26 +- tests/ui/iter_over_hash_type.rs | 13 + tests/ui/iter_over_hash_type.stderr | 65 ++- tests/ui/iter_overeager_cloned.fixed | 19 + tests/ui/iter_overeager_cloned.rs | 19 + tests/ui/iter_overeager_cloned.stderr | 37 +- tests/ui/iter_skip_next.fixed | 7 + tests/ui/iter_skip_next.rs | 7 + tests/ui/iter_skip_next.stderr | 12 +- tests/ui/iter_skip_next_unfixable.rs | 9 +- tests/ui/iter_skip_next_unfixable.stderr | 8 +- tests/ui/iter_skip_zero.fixed | 5 + tests/ui/iter_skip_zero.rs | 5 + tests/ui/iter_skip_zero.stderr | 8 +- tests/ui/iter_with_drain.fixed | 6 + tests/ui/iter_with_drain.rs | 6 + tests/ui/iter_with_drain.stderr | 10 +- tests/ui/iter_without_into_iter.rs | 14 +- tests/ui/iter_without_into_iter.stderr | 8 +- tests/ui/iterator_step_by_zero.rs | 23 +- tests/ui/iterator_step_by_zero.stderr | 12 +- tests/ui/join_absolute_paths.rs | 12 +- tests/ui/join_absolute_paths.stderr | 6 +- tests/ui/large_const_arrays.fixed | 10 + tests/ui/large_const_arrays.rs | 10 + tests/ui/large_const_arrays.stderr | 18 +- tests/ui/large_digit_groups.fixed | 5 + tests/ui/large_digit_groups.rs | 5 + tests/ui/large_digit_groups.stderr | 8 +- tests/ui/large_enum_variant.64bit.stderr | 70 ++- tests/ui/large_enum_variant.rs | 20 + tests/ui/large_futures.fixed | 24 +- tests/ui/large_futures.rs | 24 +- tests/ui/large_futures.stderr | 18 +- tests/ui/large_stack_frames.rs | 12 +- tests/ui/large_stack_frames.stderr | 6 +- tests/ui/large_types_passed_by_value.rs | 8 + tests/ui/large_types_passed_by_value.stderr | 14 +- tests/ui/legacy_numeric_constants.fixed | 1 + tests/ui/legacy_numeric_constants.rs | 1 + tests/ui/legacy_numeric_constants.stderr | 32 +- .../ui/legacy_numeric_constants_unfixable.rs | 1 + .../legacy_numeric_constants_unfixable.stderr | 18 +- tests/ui/len_without_is_empty.rs | 50 +- tests/ui/len_without_is_empty.stderr | 42 +- tests/ui/len_zero.fixed | 27 + tests/ui/len_zero.rs | 27 + tests/ui/len_zero.stderr | 52 +- tests/ui/len_zero_ranges.fixed | 2 + tests/ui/len_zero_ranges.rs | 2 + tests/ui/len_zero_ranges.stderr | 2 +- tests/ui/let_and_return.edition2021.fixed | 42 +- tests/ui/let_and_return.edition2021.stderr | 18 +- tests/ui/let_and_return.edition2024.fixed | 42 +- tests/ui/let_and_return.edition2024.stderr | 28 +- tests/ui/let_and_return.rs | 42 +- tests/ui/let_if_seq.rs | 18 +- tests/ui/let_if_seq.stderr | 21 +- tests/ui/let_underscore_future.rs | 9 +- tests/ui/let_underscore_future.stderr | 4 +- tests/ui/let_underscore_must_use.rs | 36 +- tests/ui/let_underscore_must_use.stderr | 22 +- tests/ui/let_underscore_untyped.rs | 5 + tests/ui/let_underscore_untyped.stderr | 16 +- tests/ui/let_unit.fixed | 4 + tests/ui/let_unit.rs | 4 + tests/ui/let_unit.stderr | 14 +- tests/ui/let_with_type_underscore.rs | 5 + tests/ui/let_with_type_underscore.stderr | 16 +- tests/ui/lines_filter_map_ok.fixed | 6 + tests/ui/lines_filter_map_ok.rs | 6 + tests/ui/lines_filter_map_ok.stderr | 20 +- tests/ui/linkedlist.rs | 27 +- tests/ui/linkedlist.stderr | 16 +- .../ui/literal_string_with_formatting_arg.rs | 4 +- .../literal_string_with_formatting_arg.stderr | 2 +- tests/ui/literals.rs | 72 ++- tests/ui/literals.stderr | 38 +- tests/ui/lossy_float_literal.fixed | 11 + tests/ui/lossy_float_literal.rs | 11 + tests/ui/lossy_float_literal.stderr | 20 +- tests/ui/macro_use_imports.fixed | 4 + tests/ui/macro_use_imports.rs | 4 + tests/ui/macro_use_imports.stderr | 6 +- tests/ui/macro_use_imports_expect.rs | 1 + tests/ui/manual_arithmetic_check-2.rs | 18 +- tests/ui/manual_arithmetic_check-2.stderr | 20 +- tests/ui/manual_arithmetic_check.fixed | 14 +- tests/ui/manual_arithmetic_check.rs | 12 +- tests/ui/manual_arithmetic_check.stderr | 6 +- tests/ui/manual_assert.edition2018.stderr | 99 +++- tests/ui/manual_assert.edition2021.stderr | 99 +++- tests/ui/manual_assert.rs | 10 + tests/ui/manual_async_fn.rs | 13 + tests/ui/manual_async_fn.stderr | 24 +- tests/ui/manual_bits.fixed | 29 + tests/ui/manual_bits.rs | 29 + tests/ui/manual_bits.stderr | 56 +- .../manual_c_str_literals.edition2021.fixed | 14 + .../manual_c_str_literals.edition2021.stderr | 26 +- tests/ui/manual_c_str_literals.rs | 14 + tests/ui/manual_clamp.fixed | 90 ++-- tests/ui/manual_clamp.rs | 175 ++++--- tests/ui/manual_clamp.stderr | 129 ++--- tests/ui/manual_div_ceil.fixed | 26 +- tests/ui/manual_div_ceil.rs | 26 +- tests/ui/manual_div_ceil.stderr | 52 +- tests/ui/manual_div_ceil_with_feature.fixed | 23 + tests/ui/manual_div_ceil_with_feature.rs | 23 + tests/ui/manual_div_ceil_with_feature.stderr | 44 +- tests/ui/manual_filter.rs | 15 + tests/ui/manual_filter.stderr | 55 +- tests/ui/manual_filter_map.fixed | 14 + tests/ui/manual_filter_map.rs | 29 + tests/ui/manual_filter_map.stderr | 87 +-- tests/ui/manual_find.rs | 10 +- tests/ui/manual_find.stderr | 8 +- tests/ui/manual_find_fixable.rs | 12 + tests/ui/manual_find_fixable.stderr | 34 +- tests/ui/manual_find_map.fixed | 17 + tests/ui/manual_find_map.rs | 30 ++ tests/ui/manual_find_map.stderr | 87 +-- tests/ui/manual_flatten.rs | 27 +- tests/ui/manual_flatten.stderr | 66 +-- tests/ui/manual_float_methods.rs | 7 + tests/ui/manual_float_methods.stderr | 12 +- tests/ui/manual_hash_one.fixed | 4 + tests/ui/manual_hash_one.rs | 4 + tests/ui/manual_hash_one.stderr | 6 +- tests/ui/manual_ignore_case_cmp.fixed | 49 ++ tests/ui/manual_ignore_case_cmp.rs | 49 ++ tests/ui/manual_ignore_case_cmp.stderr | 494 +++++++++--------- tests/ui/manual_inspect.fixed | 13 + tests/ui/manual_inspect.rs | 13 + tests/ui/manual_inspect.stderr | 47 +- tests/ui/manual_instant_elapsed.fixed | 2 + tests/ui/manual_instant_elapsed.rs | 2 + tests/ui/manual_instant_elapsed.stderr | 2 +- tests/ui/manual_is_ascii_check.fixed | 29 + tests/ui/manual_is_ascii_check.rs | 29 + tests/ui/manual_is_ascii_check.stderr | 56 +- tests/ui/manual_is_power_of_two.fixed | 6 + tests/ui/manual_is_power_of_two.rs | 6 + tests/ui/manual_is_power_of_two.stderr | 10 +- tests/ui/manual_is_variant_and.fixed | 5 + tests/ui/manual_is_variant_and.rs | 8 + tests/ui/manual_is_variant_and.stderr | 22 +- tests/ui/manual_let_else.rs | 89 +++- tests/ui/manual_let_else.stderr | 96 ++-- tests/ui/manual_let_else_match.rs | 32 +- tests/ui/manual_let_else_match.stderr | 31 +- tests/ui/manual_let_else_question_mark.fixed | 5 + tests/ui/manual_let_else_question_mark.rs | 7 + tests/ui/manual_let_else_question_mark.stderr | 14 +- tests/ui/manual_main_separator_str.fixed | 4 + tests/ui/manual_main_separator_str.rs | 4 + tests/ui/manual_main_separator_str.stderr | 6 +- tests/ui/manual_map_option.rs | 20 + tests/ui/manual_map_option.stderr | 58 +- tests/ui/manual_map_option_2.fixed | 2 - tests/ui/manual_map_option_2.rs | 9 +- tests/ui/manual_map_option_2.stderr | 25 +- tests/ui/manual_memcpy/with_loop_counters.rs | 35 +- .../manual_memcpy/with_loop_counters.stderr | 37 +- .../ui/manual_memcpy/without_loop_counters.rs | 56 +- .../without_loop_counters.stderr | 55 +- tests/ui/manual_next_back.fixed | 2 + tests/ui/manual_next_back.rs | 2 + tests/ui/manual_next_back.stderr | 2 +- tests/ui/manual_non_exhaustive_enum.rs | 3 +- tests/ui/manual_non_exhaustive_enum.stderr | 3 +- tests/ui/manual_ok_err.rs | 24 +- tests/ui/manual_ok_err.stderr | 22 +- tests/ui/manual_ok_or.fixed | 3 + tests/ui/manual_ok_or.rs | 4 + tests/ui/manual_ok_or.stderr | 10 +- tests/ui/manual_option_as_slice.fixed | 9 +- tests/ui/manual_option_as_slice.rs | 11 +- tests/ui/manual_option_as_slice.stderr | 14 +- tests/ui/manual_pattern_char_comparison.fixed | 10 + tests/ui/manual_pattern_char_comparison.rs | 10 + .../ui/manual_pattern_char_comparison.stderr | 18 +- tests/ui/manual_range_patterns.fixed | 19 + tests/ui/manual_range_patterns.rs | 19 + tests/ui/manual_range_patterns.stderr | 36 +- tests/ui/manual_rem_euclid.fixed | 10 + tests/ui/manual_rem_euclid.rs | 10 + tests/ui/manual_rem_euclid.stderr | 18 +- tests/ui/manual_repeat_n.fixed | 5 + tests/ui/manual_repeat_n.rs | 5 + tests/ui/manual_repeat_n.stderr | 8 +- tests/ui/manual_retain.fixed | 36 ++ tests/ui/manual_retain.rs | 38 ++ tests/ui/manual_retain.stderr | 76 +-- tests/ui/manual_rotate.fixed | 11 + tests/ui/manual_rotate.rs | 11 + tests/ui/manual_rotate.stderr | 20 +- tests/ui/manual_saturating_arithmetic.fixed | 19 + tests/ui/manual_saturating_arithmetic.rs | 24 + tests/ui/manual_saturating_arithmetic.stderr | 51 +- tests/ui/manual_slice_fill.rs | 4 + tests/ui/manual_slice_fill.stderr | 10 +- tests/ui/manual_slice_size_calculation.fixed | 9 + tests/ui/manual_slice_size_calculation.rs | 9 + tests/ui/manual_slice_size_calculation.stderr | 16 +- tests/ui/manual_split_once.fixed | 19 + tests/ui/manual_split_once.rs | 19 + tests/ui/manual_split_once.stderr | 54 +- tests/ui/manual_str_repeat.fixed | 10 + tests/ui/manual_str_repeat.rs | 10 + tests/ui/manual_str_repeat.stderr | 18 +- tests/ui/manual_string_new.fixed | 9 + tests/ui/manual_string_new.rs | 9 + tests/ui/manual_string_new.stderr | 16 +- tests/ui/manual_strip.rs | 24 +- tests/ui/manual_strip.stderr | 32 +- tests/ui/manual_swap_auto_fix.rs | 12 +- tests/ui/manual_swap_auto_fix.stderr | 22 +- tests/ui/manual_try_fold.rs | 4 + tests/ui/manual_try_fold.stderr | 6 +- tests/ui/manual_unwrap_or.rs | 16 + tests/ui/manual_unwrap_or.stderr | 48 +- tests/ui/manual_unwrap_or_default.rs | 22 +- tests/ui/manual_unwrap_or_default.stderr | 22 +- .../ui/manual_unwrap_or_default_unfixable.rs | 4 + .../manual_unwrap_or_default_unfixable.stderr | 7 +- tests/ui/manual_while_let_some.fixed | 7 + tests/ui/manual_while_let_some.rs | 7 + tests/ui/manual_while_let_some.stderr | 12 +- tests/ui/many_single_char_names.rs | 17 +- tests/ui/many_single_char_names.stderr | 4 +- tests/ui/map_all_any_identity.fixed | 2 + tests/ui/map_all_any_identity.rs | 2 + tests/ui/map_all_any_identity.stderr | 2 +- tests/ui/map_clone.fixed | 49 +- tests/ui/map_clone.rs | 49 +- tests/ui/map_clone.stderr | 28 +- tests/ui/map_collect_result_unit.fixed | 2 + tests/ui/map_collect_result_unit.rs | 2 + tests/ui/map_collect_result_unit.stderr | 2 +- tests/ui/map_err.rs | 3 +- tests/ui/map_flatten.rs | 17 +- tests/ui/map_flatten.stderr | 23 +- tests/ui/map_flatten_fixable.fixed | 9 + tests/ui/map_flatten_fixable.rs | 9 + tests/ui/map_flatten_fixable.stderr | 20 +- tests/ui/map_identity.fixed | 11 + tests/ui/map_identity.rs | 13 + tests/ui/map_identity.stderr | 26 +- tests/ui/map_unit_fn.rs | 2 + tests/ui/map_unwrap_or.rs | 15 + tests/ui/map_unwrap_or.stderr | 40 +- tests/ui/map_unwrap_or_fixable.rs | 2 + tests/ui/map_unwrap_or_fixable.stderr | 6 +- ...map_with_unused_argument_over_ranges.fixed | 18 + .../map_with_unused_argument_over_ranges.rs | 18 + ...ap_with_unused_argument_over_ranges.stderr | 36 +- ...th_unused_argument_over_ranges_nostd.fixed | 1 + ..._with_unused_argument_over_ranges_nostd.rs | 1 + tests/ui/match_as_ref.rs | 3 + tests/ui/match_as_ref.stderr | 7 +- tests/ui/match_bool.rs | 39 +- tests/ui/match_bool.stderr | 50 +- tests/ui/match_expr_like_matches_macro.fixed | 14 + tests/ui/match_expr_like_matches_macro.rs | 14 + tests/ui/match_expr_like_matches_macro.stderr | 26 +- tests/ui/match_on_vec_items.rs | 26 +- tests/ui/match_on_vec_items.stderr | 14 +- tests/ui/match_overlapping_arm.rs | 24 +- tests/ui/match_overlapping_arm.stderr | 30 +- tests/ui/match_ref_pats.fixed | 5 + tests/ui/match_ref_pats.rs | 5 + tests/ui/match_ref_pats.stderr | 14 +- tests/ui/match_result_ok.fixed | 3 + tests/ui/match_result_ok.rs | 3 + tests/ui/match_result_ok.stderr | 4 +- tests/ui/match_same_arms.rs | 24 +- tests/ui/match_same_arms.stderr | 65 +-- tests/ui/match_same_arms2.fixed | 40 +- tests/ui/match_same_arms2.rs | 40 +- tests/ui/match_same_arms2.stderr | 93 ++-- tests/ui/match_same_arms_non_exhaustive.fixed | 6 +- tests/ui/match_same_arms_non_exhaustive.rs | 6 +- .../ui/match_same_arms_non_exhaustive.stderr | 6 +- tests/ui/match_single_binding.rs | 24 + tests/ui/match_single_binding.stderr | 72 ++- tests/ui/match_single_binding2.fixed | 1 + tests/ui/match_single_binding2.rs | 4 + tests/ui/match_single_binding2.stderr | 11 +- tests/ui/match_str_case_mismatch.fixed | 7 + tests/ui/match_str_case_mismatch.rs | 7 + tests/ui/match_str_case_mismatch.stderr | 12 +- tests/ui/match_wild_err_arm.rs | 20 +- tests/ui/match_wild_err_arm.stderr | 6 +- .../match_wildcard_for_single_variants.fixed | 10 + .../ui/match_wildcard_for_single_variants.rs | 10 + .../match_wildcard_for_single_variants.stderr | 18 +- tests/ui/mem_forget.rs | 20 +- tests/ui/mem_forget.stderr | 6 +- tests/ui/mem_replace.fixed | 26 + tests/ui/mem_replace.rs | 26 + tests/ui/mem_replace.stderr | 50 +- tests/ui/mem_replace_macro.rs | 1 + tests/ui/mem_replace_no_std.fixed | 7 + tests/ui/mem_replace_no_std.rs | 7 + tests/ui/mem_replace_no_std.stderr | 12 +- tests/ui/methods.rs | 2 + tests/ui/methods.stderr | 4 +- tests/ui/methods_fixable.fixed | 1 + tests/ui/methods_fixable.rs | 1 + tests/ui/methods_unfixable.rs | 3 +- tests/ui/min_ident_chars.rs | 32 ++ tests/ui/min_ident_chars.stderr | 62 +-- tests/ui/min_max.rs | 41 +- tests/ui/min_max.stderr | 24 +- tests/ui/min_rust_version_attr.rs | 18 +- tests/ui/min_rust_version_attr.stderr | 10 +- tests/ui/mismatching_type_param_order.rs | 30 +- tests/ui/mismatching_type_param_order.stderr | 16 +- tests/ui/misnamed_getters.fixed | 56 +- tests/ui/misnamed_getters.rs | 56 +- tests/ui/misnamed_getters.stderr | 54 +- tests/ui/missing_asserts_for_indexing.fixed | 33 +- tests/ui/missing_asserts_for_indexing.rs | 33 +- tests/ui/missing_asserts_for_indexing.stderr | 86 +-- .../missing_asserts_for_indexing_unfixable.rs | 18 +- ...sing_asserts_for_indexing_unfixable.stderr | 47 +- .../ui/missing_const_for_fn/cant_be_const.rs | 1 + .../missing_const_for_fn/could_be_const.fixed | 47 +- .../ui/missing_const_for_fn/could_be_const.rs | 47 +- .../could_be_const.stderr | 50 +- tests/ui/missing_const_for_thread_local.fixed | 18 +- tests/ui/missing_const_for_thread_local.rs | 18 +- .../ui/missing_const_for_thread_local.stderr | 10 +- tests/ui/missing_doc.rs | 14 + tests/ui/missing_doc.stderr | 32 +- tests/ui/missing_doc_crate.rs | 2 + tests/ui/missing_doc_crate_missing.rs | 5 +- tests/ui/missing_doc_impl.rs | 7 + tests/ui/missing_doc_impl.stderr | 17 +- tests/ui/missing_fields_in_debug.rs | 9 +- tests/ui/missing_fields_in_debug.stderr | 20 +- tests/ui/missing_inline.rs | 20 +- tests/ui/missing_inline.stderr | 10 +- tests/ui/missing_inline_executable.rs | 2 + tests/ui/missing_inline_proc_macro.rs | 2 + tests/ui/missing_panics_doc.rs | 12 + tests/ui/missing_panics_doc.stderr | 46 +- tests/ui/missing_spin_loop.fixed | 6 + tests/ui/missing_spin_loop.rs | 6 + tests/ui/missing_spin_loop.stderr | 10 +- tests/ui/missing_spin_loop_no_std.fixed | 1 + tests/ui/missing_spin_loop_no_std.rs | 1 + tests/ui/missing_trait_methods.rs | 9 +- tests/ui/missing_trait_methods.stderr | 52 +- tests/ui/mistyped_literal_suffix.fixed | 16 + tests/ui/mistyped_literal_suffix.rs | 16 + tests/ui/mistyped_literal_suffix.stderr | 30 +- .../auxiliary/submodule.rs | 3 +- .../ui/mixed_attributes_style/global_allow.rs | 2 + .../mixed_attributes_style/mod_declaration.rs | 3 + .../mod_declaration.stderr | 21 +- tests/ui/mixed_read_write_in_expression.rs | 12 +- .../ui/mixed_read_write_in_expression.stderr | 12 +- tests/ui/module_inception.rs | 14 +- tests/ui/module_inception.stderr | 13 +- tests/ui/module_name_repetitions.rs | 20 +- tests/ui/module_name_repetitions.stderr | 10 +- tests/ui/modulo_arithmetic_float.rs | 80 +-- tests/ui/modulo_arithmetic_float.stderr | 30 +- tests/ui/modulo_arithmetic_integral.rs | 85 +-- tests/ui/modulo_arithmetic_integral.stderr | 32 +- tests/ui/modulo_arithmetic_integral_const.rs | 85 +-- .../modulo_arithmetic_integral_const.stderr | 32 +- tests/ui/modulo_one.rs | 23 +- tests/ui/modulo_one.stderr | 28 +- tests/ui/multi_assignments.rs | 20 +- tests/ui/multi_assignments.stderr | 10 +- tests/ui/multiple_bound_locations.rs | 18 +- tests/ui/multiple_bound_locations.stderr | 10 +- tests/ui/multiple_unsafe_ops_per_block.rs | 8 + tests/ui/multiple_unsafe_ops_per_block.stderr | 64 ++- tests/ui/must_use_candidates.fixed | 5 + tests/ui/must_use_candidates.rs | 5 + tests/ui/must_use_candidates.stderr | 8 +- tests/ui/must_use_unit.fixed | 5 + tests/ui/must_use_unit.rs | 5 + tests/ui/must_use_unit.stderr | 8 +- tests/ui/mut_from_ref.rs | 18 +- tests/ui/mut_from_ref.stderr | 20 +- tests/ui/mut_key.rs | 47 +- tests/ui/mut_key.stderr | 26 +- tests/ui/mut_mut.rs | 9 + tests/ui/mut_mut.stderr | 16 +- tests/ui/mut_mutex_lock.fixed | 2 + tests/ui/mut_mutex_lock.rs | 2 + tests/ui/mut_mutex_lock.stderr | 2 +- tests/ui/mut_range_bound.rs | 35 +- tests/ui/mut_range_bound.stderr | 12 +- tests/ui/mut_reference.rs | 11 +- tests/ui/mut_reference.stderr | 4 +- tests/ui/mutex_atomic.rs | 37 +- tests/ui/mutex_atomic.stderr | 20 +- tests/ui/needless_arbitrary_self_type.fixed | 8 + tests/ui/needless_arbitrary_self_type.rs | 8 + tests/ui/needless_arbitrary_self_type.stderr | 14 +- ...edless_arbitrary_self_type_unfixable.fixed | 1 + .../needless_arbitrary_self_type_unfixable.rs | 1 + tests/ui/needless_as_bytes.fixed | 16 +- tests/ui/needless_as_bytes.rs | 16 +- tests/ui/needless_as_bytes.stderr | 14 +- tests/ui/needless_bitwise_bool.fixed | 1 + tests/ui/needless_bitwise_bool.rs | 1 + tests/ui/needless_bool/fixable.fixed | 24 + tests/ui/needless_bool/fixable.rs | 24 + tests/ui/needless_bool/fixable.stderr | 46 +- tests/ui/needless_bool/simple.rs | 4 + tests/ui/needless_bool/simple.stderr | 45 -- tests/ui/needless_bool_assign.fixed | 4 + tests/ui/needless_bool_assign.rs | 4 + tests/ui/needless_bool_assign.stderr | 55 -- tests/ui/needless_borrow.fixed | 30 +- tests/ui/needless_borrow.rs | 30 +- tests/ui/needless_borrow.stderr | 54 +- tests/ui/needless_borrow_pat.fixed | 38 +- tests/ui/needless_borrow_pat.rs | 38 +- tests/ui/needless_borrow_pat.stderr | 26 +- tests/ui/needless_borrowed_ref.fixed | 17 + tests/ui/needless_borrowed_ref.rs | 17 + tests/ui/needless_borrowed_ref.stderr | 34 +- .../needless_borrows_for_generic_args.fixed | 11 + tests/ui/needless_borrows_for_generic_args.rs | 11 + .../needless_borrows_for_generic_args.stderr | 20 +- tests/ui/needless_character_iteration.fixed | 21 +- tests/ui/needless_character_iteration.rs | 27 +- tests/ui/needless_character_iteration.stderr | 18 +- tests/ui/needless_collect.fixed | 19 + tests/ui/needless_collect.rs | 19 + tests/ui/needless_collect.stderr | 36 +- tests/ui/needless_collect_indirect.rs | 49 +- tests/ui/needless_collect_indirect.stderr | 87 +-- tests/ui/needless_continue.rs | 35 +- tests/ui/needless_continue.stderr | 42 +- tests/ui/needless_doc_main.rs | 1 - tests/ui/needless_doc_main.stderr | 7 +- tests/ui/needless_else.fixed | 1 + tests/ui/needless_else.rs | 1 + tests/ui/needless_else.stderr | 13 - tests/ui/needless_for_each_fixable.fixed | 8 + tests/ui/needless_for_each_fixable.rs | 8 + tests/ui/needless_for_each_fixable.stderr | 30 +- tests/ui/needless_for_each_unfixable.rs | 5 +- tests/ui/needless_for_each_unfixable.stderr | 6 +- tests/ui/needless_if.fixed | 7 + tests/ui/needless_if.rs | 7 + tests/ui/needless_if.stderr | 16 +- tests/ui/needless_late_init.fixed | 16 + tests/ui/needless_late_init.rs | 16 + tests/ui/needless_late_init.stderr | 87 +-- tests/ui/needless_lifetimes.fixed | 58 +- tests/ui/needless_lifetimes.rs | 58 +- tests/ui/needless_lifetimes.stderr | 131 +++-- tests/ui/needless_match.fixed | 3 + tests/ui/needless_match.rs | 14 + tests/ui/needless_match.stderr | 42 +- tests/ui/needless_maybe_sized.fixed | 20 + tests/ui/needless_maybe_sized.rs | 20 + tests/ui/needless_maybe_sized.stderr | 76 +-- tests/ui/needless_option_as_deref.fixed | 3 + tests/ui/needless_option_as_deref.rs | 3 + tests/ui/needless_option_as_deref.stderr | 4 +- tests/ui/needless_option_take.fixed | 27 +- tests/ui/needless_option_take.rs | 27 +- tests/ui/needless_option_take.stderr | 16 +- .../needless_parens_on_range_literals.fixed | 6 + tests/ui/needless_parens_on_range_literals.rs | 6 + .../needless_parens_on_range_literals.stderr | 8 +- tests/ui/needless_pass_by_ref_mut.rs | 82 ++- tests/ui/needless_pass_by_ref_mut.stderr | 66 +-- tests/ui/needless_pass_by_ref_mut2.fixed | 6 +- tests/ui/needless_pass_by_ref_mut2.rs | 6 +- tests/ui/needless_pass_by_ref_mut2.stderr | 2 +- tests/ui/needless_pass_by_value.rs | 68 ++- tests/ui/needless_pass_by_value.stderr | 50 +- tests/ui/needless_pass_by_value_proc_macro.rs | 2 + tests/ui/needless_pub_self.fixed | 3 + tests/ui/needless_pub_self.rs | 3 + tests/ui/needless_pub_self.stderr | 4 +- tests/ui/needless_question_mark.fixed | 15 + tests/ui/needless_question_mark.rs | 15 + tests/ui/needless_question_mark.stderr | 28 +- tests/ui/needless_range_loop.rs | 44 +- tests/ui/needless_range_loop.stderr | 26 +- tests/ui/needless_range_loop2.rs | 26 +- tests/ui/needless_range_loop2.stderr | 14 +- tests/ui/needless_raw_string.fixed | 10 + tests/ui/needless_raw_string.rs | 10 + tests/ui/needless_raw_string.stderr | 23 +- tests/ui/needless_raw_string_hashes.fixed | 18 + tests/ui/needless_raw_string_hashes.rs | 18 + tests/ui/needless_raw_string_hashes.stderr | 39 +- tests/ui/needless_return.fixed | 54 ++ tests/ui/needless_return.rs | 55 +- tests/ui/needless_return.stderr | 124 ++--- .../needless_return_with_question_mark.fixed | 1 + .../ui/needless_return_with_question_mark.rs | 1 + .../needless_return_with_question_mark.stderr | 2 +- tests/ui/needless_splitn.fixed | 13 + tests/ui/needless_splitn.rs | 13 + tests/ui/needless_splitn.stderr | 24 +- tests/ui/needless_update.rs | 5 +- tests/ui/neg_cmp_op_on_partial_ord.rs | 14 +- tests/ui/neg_cmp_op_on_partial_ord.stderr | 6 +- tests/ui/neg_multiply.fixed | 8 + tests/ui/neg_multiply.rs | 8 + tests/ui/neg_multiply.stderr | 14 +- tests/ui/never_loop.rs | 52 +- tests/ui/never_loop.stderr | 63 +-- tests/ui/new_ret_no_self.rs | 38 +- tests/ui/new_ret_no_self.stderr | 64 ++- tests/ui/new_ret_no_self_overflow.rs | 1 + tests/ui/new_without_default.fixed | 25 +- tests/ui/new_without_default.rs | 25 +- tests/ui/new_without_default.stderr | 28 +- tests/ui/no_effect.rs | 83 ++- tests/ui/no_effect.stderr | 52 +- tests/ui/no_effect_async_fn.rs | 12 +- tests/ui/no_effect_async_fn.stderr | 6 +- tests/ui/no_effect_replace.rs | 26 +- tests/ui/no_effect_replace.stderr | 14 +- tests/ui/no_effect_return.rs | 29 +- tests/ui/no_effect_return.stderr | 16 +- tests/ui/no_mangle_with_rust_abi.rs | 12 +- tests/ui/no_mangle_with_rust_abi.stderr | 10 +- tests/ui/no_mangle_with_rust_abi_2021.rs | 11 +- tests/ui/no_mangle_with_rust_abi_2021.stderr | 8 +- tests/ui/non_canonical_clone_impl.rs | 4 + tests/ui/non_canonical_clone_impl.stderr | 10 +- tests/ui/non_canonical_partial_ord_impl.fixed | 2 + tests/ui/non_canonical_partial_ord_impl.rs | 2 + .../ui/non_canonical_partial_ord_impl.stderr | 4 +- ...n_canonical_partial_ord_impl_fully_qual.rs | 2 + ...nonical_partial_ord_impl_fully_qual.stderr | 4 +- tests/ui/non_expressive_names.rs | 18 +- tests/ui/non_expressive_names.stderr | 36 +- tests/ui/non_minimal_cfg.fixed | 4 + tests/ui/non_minimal_cfg.rs | 4 + tests/ui/non_minimal_cfg.stderr | 6 +- tests/ui/non_minimal_cfg2.rs | 1 + tests/ui/non_minimal_cfg2.stderr | 2 +- tests/ui/non_octal_unix_permissions.fixed | 4 + tests/ui/non_octal_unix_permissions.rs | 4 + tests/ui/non_octal_unix_permissions.stderr | 6 +- .../non_std_lazy_static_no_std.rs | 1 + .../non_std_lazy_static_other_once_cell.rs | 1 + tests/ui/non_zero_suggestions.fixed | 18 +- tests/ui/non_zero_suggestions.rs | 18 +- tests/ui/non_zero_suggestions.stderr | 10 +- tests/ui/non_zero_suggestions_unfixable.rs | 9 +- .../ui/non_zero_suggestions_unfixable.stderr | 4 +- tests/ui/nonminimal_bool.rs | 78 ++- tests/ui/nonminimal_bool.stderr | 122 ++--- tests/ui/nonminimal_bool_methods.fixed | 93 +++- tests/ui/nonminimal_bool_methods.rs | 93 +++- tests/ui/nonminimal_bool_methods.stderr | 192 +++---- tests/ui/nonminimal_bool_methods_unfixable.rs | 4 +- .../nonminimal_bool_methods_unfixable.stderr | 12 +- tests/ui/obfuscated_if_else.fixed | 38 +- tests/ui/obfuscated_if_else.rs | 38 +- tests/ui/obfuscated_if_else.stderr | 26 +- tests/ui/octal_escapes.rs | 25 +- tests/ui/octal_escapes.stderr | 106 ++-- tests/ui/ok_expect.rs | 15 +- tests/ui/ok_expect.stderr | 8 +- tests/ui/only_used_in_recursion.rs | 48 +- tests/ui/only_used_in_recursion.stderr | 62 +-- tests/ui/only_used_in_recursion2.rs | 15 +- tests/ui/only_used_in_recursion2.stderr | 18 +- tests/ui/op_ref.fixed | 14 +- tests/ui/op_ref.rs | 14 +- tests/ui/op_ref.stderr | 6 +- tests/ui/open_options.rs | 26 +- tests/ui/open_options.stderr | 14 +- tests/ui/open_options_fixable.fixed | 3 +- tests/ui/open_options_fixable.rs | 3 +- tests/ui/option_as_ref_cloned.fixed | 3 + tests/ui/option_as_ref_cloned.rs | 3 + tests/ui/option_as_ref_cloned.stderr | 4 +- tests/ui/option_as_ref_deref.fixed | 17 + tests/ui/option_as_ref_deref.rs | 18 + tests/ui/option_as_ref_deref.stderr | 35 +- tests/ui/option_env_unwrap.rs | 7 + tests/ui/option_env_unwrap.stderr | 12 +- tests/ui/option_filter_map.fixed | 18 +- tests/ui/option_filter_map.rs | 24 +- tests/ui/option_filter_map.stderr | 18 +- tests/ui/option_if_let_else.fixed | 13 + tests/ui/option_if_let_else.rs | 25 + tests/ui/option_if_let_else.stderr | 80 ++- tests/ui/option_map_or_none.fixed | 4 + tests/ui/option_map_or_none.rs | 5 + tests/ui/option_map_or_none.stderr | 11 +- tests/ui/option_map_unit_fn_fixable.fixed | 19 + tests/ui/option_map_unit_fn_fixable.rs | 19 + tests/ui/option_map_unit_fn_fixable.stderr | 36 +- tests/ui/option_map_unit_fn_unfixable.rs | 4 + tests/ui/option_map_unit_fn_unfixable.stderr | 6 +- tests/ui/or_fun_call.fixed | 50 +- tests/ui/or_fun_call.rs | 50 +- tests/ui/or_fun_call.stderr | 76 +-- tests/ui/or_then_unwrap.fixed | 3 + tests/ui/or_then_unwrap.rs | 3 + tests/ui/or_then_unwrap.stderr | 4 +- tests/ui/out_of_bounds_indexing/issue-3102.rs | 8 +- .../out_of_bounds_indexing/issue-3102.stderr | 2 +- tests/ui/out_of_bounds_indexing/simple.rs | 20 +- tests/ui/out_of_bounds_indexing/simple.stderr | 10 +- tests/ui/overly_complex_bool_expr.fixed | 15 +- tests/ui/overly_complex_bool_expr.rs | 15 +- tests/ui/overly_complex_bool_expr.stderr | 16 +- tests/ui/panic_in_result_fn.rs | 7 +- tests/ui/panic_in_result_fn.stderr | 19 +- tests/ui/panic_in_result_fn_assertions.rs | 9 +- tests/ui/panic_in_result_fn_assertions.stderr | 22 +- .../ui/panic_in_result_fn_debug_assertions.rs | 2 + tests/ui/panicking_macros.rs | 56 +- tests/ui/panicking_macros.stderr | 30 +- tests/ui/panicking_overflow_checks.rs | 18 +- tests/ui/panicking_overflow_checks.stderr | 36 +- tests/ui/partial_pub_fields.rs | 12 +- tests/ui/partial_pub_fields.stderr | 6 +- tests/ui/partialeq_ne_impl.rs | 5 +- tests/ui/partialeq_ne_impl.stderr | 4 +- tests/ui/partialeq_to_none.fixed | 15 + tests/ui/partialeq_to_none.rs | 15 + tests/ui/partialeq_to_none.stderr | 30 +- tests/ui/path_buf_push_overwrite.fixed | 1 + tests/ui/path_buf_push_overwrite.rs | 1 + tests/ui/path_ends_with_ext.fixed | 6 +- tests/ui/path_ends_with_ext.rs | 6 +- tests/ui/path_ends_with_ext.stderr | 2 +- tests/ui/pathbuf_init_then_push.fixed | 8 +- tests/ui/pathbuf_init_then_push.rs | 12 +- tests/ui/pathbuf_init_then_push.stderr | 20 +- tests/ui/pattern_type_mismatch/mutability.rs | 6 +- .../pattern_type_mismatch/mutability.stderr | 2 +- .../pattern_alternatives.rs | 9 +- .../pattern_alternatives.stderr | 4 +- .../pattern_type_mismatch/pattern_structs.rs | 24 +- .../pattern_structs.stderr | 14 +- .../pattern_type_mismatch/pattern_tuples.rs | 30 +- .../pattern_tuples.stderr | 18 +- tests/ui/pattern_type_mismatch/syntax.rs | 25 +- tests/ui/pattern_type_mismatch/syntax.stderr | 16 +- tests/ui/patterns.fixed | 3 + tests/ui/patterns.rs | 3 + tests/ui/patterns.stderr | 4 +- tests/ui/permissions_set_readonly_false.rs | 5 +- tests/ui/pointers_in_nomem_asm_block.rs | 9 +- tests/ui/pointers_in_nomem_asm_block.stderr | 4 +- tests/ui/precedence.fixed | 7 + tests/ui/precedence.rs | 7 + tests/ui/precedence.stderr | 12 +- tests/ui/precedence_bits.fixed | 4 + tests/ui/precedence_bits.rs | 4 + tests/ui/precedence_bits.stderr | 6 +- tests/ui/print.rs | 28 +- tests/ui/print.stderr | 14 +- tests/ui/print_in_format_impl.rs | 23 +- tests/ui/print_in_format_impl.stderr | 12 +- tests/ui/print_literal.fixed | 36 +- tests/ui/print_literal.rs | 36 +- tests/ui/print_literal.stderr | 37 +- tests/ui/print_stderr.rs | 8 +- tests/ui/print_stderr.stderr | 2 +- tests/ui/print_stdout_build_script.rs | 1 + tests/ui/print_with_newline.fixed | 29 +- tests/ui/print_with_newline.rs | 29 +- tests/ui/print_with_newline.stderr | 20 +- tests/ui/println_empty_string.fixed | 4 + tests/ui/println_empty_string.rs | 4 + tests/ui/println_empty_string.stderr | 6 +- tests/ui/ptr_arg.rs | 78 ++- tests/ui/ptr_arg.stderr | 59 ++- tests/ui/ptr_as_ptr.fixed | 33 ++ tests/ui/ptr_as_ptr.rs | 33 ++ tests/ui/ptr_as_ptr.stderr | 82 +-- tests/ui/ptr_cast_constness.fixed | 13 + tests/ui/ptr_cast_constness.rs | 13 + tests/ui/ptr_cast_constness.stderr | 24 +- tests/ui/ptr_eq.fixed | 2 + tests/ui/ptr_eq.rs | 2 + tests/ui/ptr_eq.stderr | 2 +- tests/ui/ptr_eq_no_std.fixed | 2 + tests/ui/ptr_eq_no_std.rs | 2 + tests/ui/ptr_eq_no_std.stderr | 2 +- tests/ui/ptr_offset_with_cast.fixed | 2 + tests/ui/ptr_offset_with_cast.rs | 2 + tests/ui/ptr_offset_with_cast.stderr | 2 +- tests/ui/pub_use.rs | 3 +- tests/ui/pub_with_shorthand.fixed | 4 + tests/ui/pub_with_shorthand.rs | 4 + tests/ui/pub_with_shorthand.stderr | 6 +- tests/ui/pub_without_shorthand.fixed | 3 + tests/ui/pub_without_shorthand.rs | 3 + tests/ui/pub_without_shorthand.stderr | 4 +- tests/ui/question_mark.fixed | 2 + tests/ui/question_mark.rs | 22 + tests/ui/question_mark.stderr | 62 ++- tests/ui/question_mark_used.rs | 3 +- tests/ui/range.fixed | 3 +- tests/ui/range.rs | 3 +- tests/ui/range_contains.fixed | 21 + tests/ui/range_contains.rs | 21 + tests/ui/range_contains.stderr | 40 +- tests/ui/range_plus_minus_one.fixed | 9 + tests/ui/range_plus_minus_one.rs | 9 + tests/ui/range_plus_minus_one.stderr | 16 +- tests/ui/rc_buffer.fixed | 8 + tests/ui/rc_buffer.rs | 8 + tests/ui/rc_buffer.stderr | 14 +- tests/ui/rc_buffer_arc.fixed | 8 + tests/ui/rc_buffer_arc.rs | 8 + tests/ui/rc_buffer_arc.stderr | 14 +- tests/ui/rc_buffer_redefined_string.rs | 2 + tests/ui/rc_clone_in_vec_init/arc.rs | 20 +- tests/ui/rc_clone_in_vec_init/arc.stderr | 12 +- tests/ui/rc_clone_in_vec_init/rc.rs | 20 +- tests/ui/rc_clone_in_vec_init/rc.stderr | 12 +- tests/ui/rc_clone_in_vec_init/weak.rs | 40 +- tests/ui/rc_clone_in_vec_init/weak.stderr | 20 +- tests/ui/rc_mutex.rs | 11 +- tests/ui/rc_mutex.stderr | 4 +- tests/ui/read_line_without_trim.fixed | 7 + tests/ui/read_line_without_trim.rs | 7 + tests/ui/read_line_without_trim.stderr | 24 +- tests/ui/read_zero_byte_vec.rs | 1 + tests/ui/read_zero_byte_vec.stderr | 22 +- tests/ui/readonly_write_lock.fixed | 8 +- tests/ui/readonly_write_lock.rs | 8 +- tests/ui/readonly_write_lock.stderr | 2 +- tests/ui/recursive_format_impl.rs | 32 +- tests/ui/recursive_format_impl.stderr | 18 +- tests/ui/redundant_allocation.rs | 100 ++-- tests/ui/redundant_allocation.stderr | 38 +- tests/ui/redundant_allocation_fixable.fixed | 12 + tests/ui/redundant_allocation_fixable.rs | 12 + tests/ui/redundant_allocation_fixable.stderr | 22 +- tests/ui/redundant_as_str.fixed | 2 + tests/ui/redundant_as_str.rs | 2 + tests/ui/redundant_as_str.stderr | 2 +- tests/ui/redundant_async_block.fixed | 10 + tests/ui/redundant_async_block.rs | 10 + tests/ui/redundant_async_block.stderr | 26 +- tests/ui/redundant_at_rest_pattern.fixed | 6 + tests/ui/redundant_at_rest_pattern.rs | 6 + tests/ui/redundant_at_rest_pattern.stderr | 10 +- tests/ui/redundant_clone.fixed | 15 + tests/ui/redundant_clone.rs | 15 + tests/ui/redundant_clone.stderr | 56 +- tests/ui/redundant_closure_call_early.rs | 8 +- tests/ui/redundant_closure_call_early.stderr | 2 +- tests/ui/redundant_closure_call_fixable.fixed | 17 + tests/ui/redundant_closure_call_fixable.rs | 17 + .../ui/redundant_closure_call_fixable.stderr | 36 +- tests/ui/redundant_closure_call_late.rs | 11 +- tests/ui/redundant_closure_call_late.stderr | 4 +- tests/ui/redundant_else.fixed | 35 +- tests/ui/redundant_else.rs | 21 +- tests/ui/redundant_else.stderr | 40 +- tests/ui/redundant_field_names.fixed | 9 + tests/ui/redundant_field_names.rs | 9 + tests/ui/redundant_field_names.stderr | 16 +- tests/ui/redundant_guards.fixed | 28 + tests/ui/redundant_guards.rs | 28 + tests/ui/redundant_guards.stderr | 58 +- tests/ui/redundant_locals.rs | 14 + tests/ui/redundant_locals.stderr | 108 ++-- ...edundant_pattern_matching_drop_order.fixed | 22 + .../redundant_pattern_matching_drop_order.rs | 22 + ...dundant_pattern_matching_drop_order.stderr | 42 +- ...dundant_pattern_matching_if_let_true.fixed | 7 + .../redundant_pattern_matching_if_let_true.rs | 7 + ...undant_pattern_matching_if_let_true.stderr | 12 +- .../redundant_pattern_matching_ipaddr.fixed | 14 + tests/ui/redundant_pattern_matching_ipaddr.rs | 20 + .../redundant_pattern_matching_ipaddr.stderr | 44 +- .../redundant_pattern_matching_option.fixed | 22 + tests/ui/redundant_pattern_matching_option.rs | 31 ++ .../redundant_pattern_matching_option.stderr | 69 +-- .../ui/redundant_pattern_matching_poll.fixed | 15 + tests/ui/redundant_pattern_matching_poll.rs | 20 + .../ui/redundant_pattern_matching_poll.stderr | 43 +- .../redundant_pattern_matching_result.fixed | 18 + tests/ui/redundant_pattern_matching_result.rs | 28 + .../redundant_pattern_matching_result.stderr | 64 ++- tests/ui/redundant_pub_crate.fixed | 16 + tests/ui/redundant_pub_crate.rs | 16 + tests/ui/redundant_pub_crate.stderr | 30 +- tests/ui/redundant_slicing.fixed | 3 + tests/ui/redundant_slicing.rs | 3 + tests/ui/redundant_slicing.stderr | 4 +- tests/ui/redundant_static_lifetimes.fixed | 18 + tests/ui/redundant_static_lifetimes.rs | 18 + tests/ui/redundant_static_lifetimes.stderr | 34 +- .../ui/redundant_static_lifetimes_multiple.rs | 32 +- ...redundant_static_lifetimes_multiple.stderr | 16 +- tests/ui/redundant_type_annotations.rs | 53 +- tests/ui/redundant_type_annotations.stderr | 32 +- tests/ui/ref_as_ptr.fixed | 44 ++ tests/ui/ref_as_ptr.rs | 44 ++ tests/ui/ref_as_ptr.stderr | 86 +-- tests/ui/ref_binding_to_reference.rs | 23 +- tests/ui/ref_binding_to_reference.stderr | 17 +- tests/ui/ref_option/ref_option.all.fixed | 17 + tests/ui/ref_option/ref_option.all.stderr | 37 +- tests/ui/ref_option/ref_option.private.fixed | 17 + tests/ui/ref_option/ref_option.private.stderr | 24 +- tests/ui/ref_option/ref_option.rs | 17 + .../ref_option/ref_option_traits.all.stderr | 6 +- .../ref_option_traits.private.stderr | 4 +- tests/ui/ref_option/ref_option_traits.rs | 4 + tests/ui/ref_option_ref.rs | 35 +- tests/ui/ref_option_ref.stderr | 20 +- tests/ui/ref_patterns.rs | 9 +- tests/ui/ref_patterns.stderr | 4 +- tests/ui/regex.rs | 7 + tests/ui/regex.stderr | 64 +-- tests/ui/renamed_builtin_attr.fixed | 1 + tests/ui/renamed_builtin_attr.rs | 1 + tests/ui/repeat_once.fixed | 6 + tests/ui/repeat_once.rs | 6 + tests/ui/repeat_once.stderr | 10 +- tests/ui/repeat_vec_with_capacity.fixed | 9 +- tests/ui/repeat_vec_with_capacity.rs | 9 +- tests/ui/repeat_vec_with_capacity.stderr | 4 +- tests/ui/repeat_vec_with_capacity_nostd.fixed | 1 + tests/ui/repeat_vec_with_capacity_nostd.rs | 1 + tests/ui/repl_uninit.rs | 14 +- tests/ui/repl_uninit.stderr | 6 +- tests/ui/repr_packed_without_abi.rs | 2 + tests/ui/repr_packed_without_abi.stderr | 4 +- tests/ui/reserve_after_initialization.rs | 3 + tests/ui/reserve_after_initialization.stderr | 7 +- tests/ui/rest_pat_in_fully_bound_structs.rs | 9 +- .../ui/rest_pat_in_fully_bound_structs.stderr | 4 +- tests/ui/result_filter_map.rs | 12 +- tests/ui/result_filter_map.stderr | 14 +- tests/ui/result_large_err.rs | 36 +- tests/ui/result_large_err.stderr | 22 +- tests/ui/result_map_or_into_option.fixed | 9 +- tests/ui/result_map_or_into_option.rs | 9 +- tests/ui/result_map_or_into_option.stderr | 4 +- tests/ui/result_map_unit_fn_fixable.fixed | 18 + tests/ui/result_map_unit_fn_fixable.rs | 18 + tests/ui/result_map_unit_fn_fixable.stderr | 34 +- tests/ui/result_map_unit_fn_unfixable.rs | 20 +- tests/ui/result_map_unit_fn_unfixable.stderr | 11 +- tests/ui/result_unit_error.rs | 15 +- tests/ui/result_unit_error.stderr | 8 +- tests/ui/result_unit_error_no_std.rs | 1 + tests/ui/return_and_then.fixed | 13 +- tests/ui/return_and_then.rs | 7 + tests/ui/return_and_then.stderr | 22 +- tests/ui/return_self_not_must_use.rs | 9 +- tests/ui/return_self_not_must_use.stderr | 6 +- tests/ui/reversed_empty_ranges_fixable.fixed | 4 + tests/ui/reversed_empty_ranges_fixable.rs | 4 + tests/ui/reversed_empty_ranges_fixable.stderr | 6 +- .../reversed_empty_ranges_loops_fixable.fixed | 6 + .../ui/reversed_empty_ranges_loops_fixable.rs | 6 + ...reversed_empty_ranges_loops_fixable.stderr | 10 +- .../reversed_empty_ranges_loops_unfixable.rs | 8 +- ...versed_empty_ranges_loops_unfixable.stderr | 2 +- tests/ui/reversed_empty_ranges_unfixable.rs | 11 +- .../ui/reversed_empty_ranges_unfixable.stderr | 4 +- tests/ui/same_functions_in_if_condition.rs | 18 +- .../ui/same_functions_in_if_condition.stderr | 20 +- tests/ui/same_item_push.rs | 18 +- tests/ui/same_item_push.stderr | 10 +- tests/ui/same_name_method.rs | 18 +- tests/ui/same_name_method.stderr | 22 +- tests/ui/search_is_some.rs | 8 + tests/ui/search_is_some.stderr | 20 +- tests/ui/search_is_some_fixable_none.fixed | 54 ++ tests/ui/search_is_some_fixable_none.rs | 55 ++ tests/ui/search_is_some_fixable_none.stderr | 113 ++-- tests/ui/search_is_some_fixable_some.fixed | 44 ++ tests/ui/search_is_some_fixable_some.rs | 47 ++ tests/ui/search_is_some_fixable_some.stderr | 95 ++-- tests/ui/seek_from_current.fixed | 1 + tests/ui/seek_from_current.rs | 1 + .../ui/seek_to_start_instead_of_rewind.fixed | 3 + tests/ui/seek_to_start_instead_of_rewind.rs | 3 + .../ui/seek_to_start_instead_of_rewind.stderr | 4 +- tests/ui/self_assignment.rs | 35 +- tests/ui/self_assignment.stderr | 20 +- tests/ui/self_named_constructors.rs | 5 +- tests/ui/self_named_constructors.stderr | 4 +- tests/ui/semicolon_if_nothing_returned.fixed | 5 + tests/ui/semicolon_if_nothing_returned.rs | 5 + tests/ui/semicolon_if_nothing_returned.stderr | 8 +- tests/ui/semicolon_inside_block.fixed | 4 + tests/ui/semicolon_inside_block.rs | 4 + tests/ui/semicolon_inside_block.stderr | 7 +- tests/ui/semicolon_outside_block.fixed | 6 + tests/ui/semicolon_outside_block.rs | 6 + tests/ui/semicolon_outside_block.stderr | 13 +- tests/ui/serde.rs | 3 +- tests/ui/serde.stderr | 4 +- tests/ui/set_contains_or_insert.rs | 14 + tests/ui/set_contains_or_insert.stderr | 40 +- tests/ui/shadow.rs | 26 + tests/ui/shadow.stderr | 216 ++++---- tests/ui/short_circuit_statement.fixed | 21 +- tests/ui/short_circuit_statement.rs | 21 +- tests/ui/short_circuit_statement.stderr | 12 +- tests/ui/should_impl_trait/corner_cases.rs | 2 + tests/ui/should_impl_trait/method_list_1.rs | 45 +- .../ui/should_impl_trait/method_list_1.stderr | 43 +- tests/ui/should_impl_trait/method_list_2.rs | 45 +- .../ui/should_impl_trait/method_list_2.stderr | 43 +- tests/ui/should_panic_without_expect.rs | 1 + tests/ui/significant_drop_in_scrutinee.rs | 87 ++- tests/ui/significant_drop_in_scrutinee.stderr | 68 ++- tests/ui/significant_drop_tightening.fixed | 4 + tests/ui/significant_drop_tightening.rs | 4 + tests/ui/significant_drop_tightening.stderr | 15 +- tests/ui/similar_names.rs | 15 +- tests/ui/similar_names.stderr | 16 +- tests/ui/single_call_fn.rs | 6 + tests/ui/single_call_fn.stderr | 23 +- tests/ui/single_char_add_str.fixed | 21 + tests/ui/single_char_add_str.rs | 21 + tests/ui/single_char_add_str.stderr | 40 +- tests/ui/single_char_lifetime_names.rs | 15 +- tests/ui/single_char_lifetime_names.stderr | 6 +- tests/ui/single_char_pattern.fixed | 35 ++ tests/ui/single_char_pattern.rs | 35 ++ tests/ui/single_char_pattern.stderr | 68 +-- tests/ui/single_component_path_imports.fixed | 2 + tests/ui/single_component_path_imports.rs | 2 + tests/ui/single_component_path_imports.stderr | 2 +- .../ui/single_component_path_imports_macro.rs | 2 + ...gle_component_path_imports_nested_first.rs | 11 +- ...component_path_imports_nested_first.stderr | 4 +- ...ingle_component_path_imports_self_after.rs | 2 + ...ngle_component_path_imports_self_before.rs | 2 + tests/ui/single_element_loop.fixed | 8 + tests/ui/single_element_loop.rs | 8 + tests/ui/single_element_loop.stderr | 23 +- tests/ui/single_match.fixed | 26 + tests/ui/single_match.rs | 26 + tests/ui/single_match.stderr | 282 ---------- tests/ui/single_match_else.fixed | 10 + tests/ui/single_match_else.rs | 10 + tests/ui/single_match_else.stderr | 211 -------- tests/ui/single_option_map.rs | 9 +- tests/ui/single_option_map.stderr | 7 +- tests/ui/single_range_in_vec_init.rs | 10 + tests/ui/single_range_in_vec_init.stderr | 18 +- .../size_of_in_element_count/expressions.rs | 12 +- .../expressions.stderr | 6 +- .../ui/size_of_in_element_count/functions.rs | 57 +- .../size_of_in_element_count/functions.stderr | 36 +- tests/ui/size_of_ref.rs | 9 +- tests/ui/size_of_ref.stderr | 4 +- tests/ui/skip_while_next.rs | 2 + tests/ui/skip_while_next.stderr | 3 +- tests/ui/sliced_string_as_bytes.fixed | 3 + tests/ui/sliced_string_as_bytes.rs | 3 + tests/ui/sliced_string_as_bytes.stderr | 4 +- tests/ui/slow_vector_initialization.rs | 41 +- tests/ui/slow_vector_initialization.stderr | 48 +- tests/ui/stable_sort_primitive.fixed | 7 + tests/ui/stable_sort_primitive.rs | 7 + tests/ui/stable_sort_primitive.stderr | 24 +- tests/ui/starts_ends_with.fixed | 16 + tests/ui/starts_ends_with.rs | 16 + tests/ui/starts_ends_with.stderr | 30 +- tests/ui/std_instead_of_core.fixed | 1 + tests/ui/std_instead_of_core.rs | 1 + tests/ui/str_split.fixed | 10 + tests/ui/str_split.rs | 10 + tests/ui/str_split.stderr | 18 +- tests/ui/str_to_string.fixed | 6 +- tests/ui/str_to_string.rs | 6 +- tests/ui/str_to_string.stderr | 2 +- tests/ui/string_add.rs | 2 + tests/ui/string_add.stderr | 2 +- tests/ui/string_add_assign.fixed | 3 + tests/ui/string_add_assign.rs | 3 + tests/ui/string_add_assign.stderr | 2 +- tests/ui/string_extend.fixed | 4 + tests/ui/string_extend.rs | 4 + tests/ui/string_extend.stderr | 6 +- tests/ui/string_from_utf8_as_bytes.fixed | 1 + tests/ui/string_from_utf8_as_bytes.rs | 1 + tests/ui/string_lit_as_bytes.fixed | 7 + tests/ui/string_lit_as_bytes.rs | 7 + tests/ui/string_lit_as_bytes.stderr | 12 +- tests/ui/string_lit_chars_any.fixed | 5 + tests/ui/string_lit_chars_any.rs | 5 + tests/ui/string_lit_chars_any.stderr | 8 +- tests/ui/string_slice.rs | 14 +- tests/ui/string_slice.stderr | 6 +- tests/ui/string_to_string.rs | 3 +- tests/ui/strlen_on_c_strings.fixed | 7 + tests/ui/strlen_on_c_strings.rs | 7 + tests/ui/strlen_on_c_strings.stderr | 12 +- tests/ui/struct_excessive_bools.rs | 6 +- tests/ui/struct_excessive_bools.stderr | 10 +- tests/ui/struct_fields.rs | 2 + tests/ui/struct_fields.stderr | 2 +- tests/ui/suspicious_arithmetic_impl.rs | 31 +- tests/ui/suspicious_arithmetic_impl.stderr | 16 +- tests/ui/suspicious_command_arg_space.fixed | 8 +- tests/ui/suspicious_command_arg_space.rs | 8 +- tests/ui/suspicious_command_arg_space.stderr | 2 +- tests/ui/suspicious_doc_comments.fixed | 9 + tests/ui/suspicious_doc_comments.rs | 9 + tests/ui/suspicious_doc_comments.stderr | 67 +-- tests/ui/suspicious_doc_comments_unfixable.rs | 8 +- .../suspicious_doc_comments_unfixable.stderr | 9 +- tests/ui/suspicious_else_formatting.rs | 9 +- tests/ui/suspicious_else_formatting.stderr | 44 +- tests/ui/suspicious_map.rs | 6 +- tests/ui/suspicious_map.stderr | 2 +- tests/ui/suspicious_operation_groupings.fixed | 26 + tests/ui/suspicious_operation_groupings.rs | 26 + .../ui/suspicious_operation_groupings.stderr | 58 +- tests/ui/suspicious_splitn.rs | 45 +- tests/ui/suspicious_splitn.stderr | 16 +- tests/ui/suspicious_to_owned.rs | 22 +- tests/ui/suspicious_to_owned.stderr | 10 +- tests/ui/suspicious_unary_op_formatting.rs | 12 +- .../ui/suspicious_unary_op_formatting.stderr | 6 +- tests/ui/suspicious_xor_used_as_pow.rs | 21 +- tests/ui/suspicious_xor_used_as_pow.stderr | 12 +- tests/ui/swap.rs | 17 + tests/ui/swap.stderr | 49 +- tests/ui/swap_ptr_to_ref.fixed | 4 + tests/ui/swap_ptr_to_ref.rs | 4 + tests/ui/swap_ptr_to_ref.stderr | 6 +- tests/ui/swap_ptr_to_ref_unfixable.rs | 11 +- tests/ui/swap_ptr_to_ref_unfixable.stderr | 4 +- tests/ui/tabs_in_doc_comments.fixed | 8 + tests/ui/tabs_in_doc_comments.rs | 8 + tests/ui/tabs_in_doc_comments.stderr | 12 +- tests/ui/temporary_assignment.rs | 14 +- tests/ui/temporary_assignment.stderr | 10 +- tests/ui/test_attr_in_doctest.rs | 3 + tests/ui/test_attr_in_doctest.stderr | 7 +- tests/ui/tests_outside_test_module.rs | 1 + tests/ui/tests_outside_test_module.stderr | 2 +- tests/ui/to_digit_is_some.fixed | 2 + tests/ui/to_digit_is_some.rs | 2 + tests/ui/to_digit_is_some.stderr | 2 +- ...to_string_in_format_args_incremental.fixed | 1 + .../to_string_in_format_args_incremental.rs | 1 + tests/ui/to_string_trait_impl.rs | 1 + tests/ui/to_string_trait_impl.stderr | 1 + .../ui/too_long_first_doc_paragraph-fix.fixed | 2 + tests/ui/too_long_first_doc_paragraph-fix.rs | 1 + .../too_long_first_doc_paragraph-fix.stderr | 3 + tests/ui/too_long_first_doc_paragraph.rs | 3 + tests/ui/too_long_first_doc_paragraph.stderr | 9 +- tests/ui/toplevel_ref_arg.fixed | 6 + tests/ui/toplevel_ref_arg.rs | 6 + tests/ui/toplevel_ref_arg.stderr | 10 +- tests/ui/toplevel_ref_arg_non_rustfix.rs | 2 + tests/ui/toplevel_ref_arg_non_rustfix.stderr | 2 +- tests/ui/track-diagnostics.rs | 1 + tests/ui/trailing_empty_array.rs | 33 +- tests/ui/trailing_empty_array.stderr | 30 +- tests/ui/trailing_zeros.fixed | 8 +- tests/ui/trailing_zeros.rs | 8 +- tests/ui/trailing_zeros.stderr | 2 +- tests/ui/trait_duplication_in_bounds.fixed | 12 + tests/ui/trait_duplication_in_bounds.rs | 12 + tests/ui/trait_duplication_in_bounds.stderr | 22 +- .../trait_duplication_in_bounds_unfixable.rs | 24 +- ...ait_duplication_in_bounds_unfixable.stderr | 12 +- tests/ui/transmute.rs | 174 +++--- tests/ui/transmute.stderr | 114 ++-- tests/ui/transmute_64bit.rs | 8 +- tests/ui/transmute_64bit.stderr | 2 +- tests/ui/transmute_collection.rs | 56 +- tests/ui/transmute_collection.stderr | 34 +- tests/ui/transmute_float_to_int.fixed | 44 +- tests/ui/transmute_float_to_int.rs | 44 +- tests/ui/transmute_float_to_int.stderr | 26 +- tests/ui/transmute_int_to_char.fixed | 8 +- tests/ui/transmute_int_to_char.rs | 8 +- tests/ui/transmute_int_to_char.stderr | 2 +- tests/ui/transmute_int_to_char_no_std.fixed | 8 +- tests/ui/transmute_int_to_char_no_std.rs | 8 +- tests/ui/transmute_int_to_char_no_std.stderr | 2 +- tests/ui/transmute_int_to_non_zero.fixed | 32 +- tests/ui/transmute_int_to_non_zero.rs | 32 +- tests/ui/transmute_int_to_non_zero.stderr | 18 +- tests/ui/transmute_null_to_fn.rs | 18 +- tests/ui/transmute_null_to_fn.stderr | 10 +- tests/ui/transmute_ptr_to_ptr.fixed | 16 + tests/ui/transmute_ptr_to_ptr.rs | 16 + tests/ui/transmute_ptr_to_ptr.stderr | 30 +- tests/ui/transmute_ptr_to_ref.fixed | 22 + tests/ui/transmute_ptr_to_ref.rs | 22 + tests/ui/transmute_ptr_to_ref.stderr | 42 +- tests/ui/transmute_ref_to_ref.rs | 9 +- tests/ui/transmute_ref_to_ref.stderr | 4 +- tests/ui/transmute_ref_to_ref_no_std.rs | 9 +- tests/ui/transmute_ref_to_ref_no_std.stderr | 4 +- tests/ui/transmute_undefined_repr.rs | 58 +- tests/ui/transmute_undefined_repr.stderr | 22 +- .../transmutes_expressible_as_ptr_casts.fixed | 10 + .../ui/transmutes_expressible_as_ptr_casts.rs | 10 + ...transmutes_expressible_as_ptr_casts.stderr | 18 +- tests/ui/transmuting_null.rs | 11 +- tests/ui/transmuting_null.stderr | 4 +- tests/ui/trim_split_whitespace.fixed | 8 + tests/ui/trim_split_whitespace.rs | 8 + tests/ui/trim_split_whitespace.stderr | 14 +- tests/ui/trivially_copy_pass_by_ref.rs | 1 + tests/ui/trivially_copy_pass_by_ref.stderr | 30 +- tests/ui/try_err.fixed | 11 + tests/ui/try_err.rs | 11 + tests/ui/try_err.stderr | 20 +- tests/ui/tuple_array_conversions.rs | 10 + tests/ui/tuple_array_conversions.stderr | 18 +- tests/ui/ty_fn_sig.rs | 1 + tests/ui/type_complexity.rs | 47 +- tests/ui/type_complexity.stderr | 28 +- tests/ui/type_id_on_box.fixed | 12 +- tests/ui/type_id_on_box.rs | 12 +- tests/ui/type_id_on_box.stderr | 6 +- tests/ui/type_id_on_box_unfixable.rs | 6 +- tests/ui/type_id_on_box_unfixable.stderr | 2 +- tests/ui/unchecked_duration_subtraction.fixed | 4 + tests/ui/unchecked_duration_subtraction.rs | 4 + .../ui/unchecked_duration_subtraction.stderr | 6 +- tests/ui/unconditional_recursion.rs | 51 +- tests/ui/unconditional_recursion.stderr | 138 ++--- tests/ui/unicode.fixed | 8 + tests/ui/unicode.rs | 8 + tests/ui/unicode.stderr | 18 +- tests/ui/uninhabited_references.rs | 4 + tests/ui/uninhabited_references.stderr | 6 +- tests/ui/uninit.rs | 11 +- tests/ui/uninit.stderr | 4 +- tests/ui/uninit_vec.rs | 36 +- tests/ui/uninit_vec.stderr | 31 +- tests/ui/uninlined_format_args.fixed | 75 +++ tests/ui/uninlined_format_args.rs | 75 +++ tests/ui/uninlined_format_args.stderr | 154 +++--- ...nlined_format_args_panic.edition2018.fixed | 6 + ...nlined_format_args_panic.edition2021.fixed | 6 + ...lined_format_args_panic.edition2021.stderr | 10 +- tests/ui/uninlined_format_args_panic.rs | 6 + tests/ui/unit_arg.rs | 10 + tests/ui/unit_arg.stderr | 29 +- tests/ui/unit_arg_empty_blocks.fixed | 4 + tests/ui/unit_arg_empty_blocks.rs | 4 + tests/ui/unit_arg_empty_blocks.stderr | 6 +- tests/ui/unit_cmp.rs | 20 +- tests/ui/unit_cmp.stderr | 28 +- tests/ui/unit_hash.fixed | 15 +- tests/ui/unit_hash.rs | 15 +- tests/ui/unit_hash.stderr | 4 +- tests/ui/unit_return_expecting_ord.rs | 12 +- tests/ui/unit_return_expecting_ord.stderr | 10 +- tests/ui/unknown_clippy_lints.fixed | 9 + tests/ui/unknown_clippy_lints.rs | 9 + tests/ui/unknown_clippy_lints.stderr | 16 +- tests/ui/unnecessary_box_returns.rs | 12 +- tests/ui/unnecessary_box_returns.stderr | 6 +- tests/ui/unnecessary_cast.fixed | 41 ++ tests/ui/unnecessary_cast.rs | 41 ++ tests/ui/unnecessary_cast.stderr | 80 +-- tests/ui/unnecessary_cast_unfixable.rs | 8 +- tests/ui/unnecessary_cast_unfixable.stderr | 2 +- tests/ui/unnecessary_clippy_cfg.rs | 26 +- tests/ui/unnecessary_clippy_cfg.stderr | 26 +- tests/ui/unnecessary_clone.rs | 31 +- tests/ui/unnecessary_clone.stderr | 16 +- .../ui/unnecessary_fallible_conversions.fixed | 30 +- tests/ui/unnecessary_fallible_conversions.rs | 30 +- .../unnecessary_fallible_conversions.stderr | 18 +- tests/ui/unnecessary_filter_map.rs | 18 +- tests/ui/unnecessary_filter_map.stderr | 19 +- tests/ui/unnecessary_find_map.rs | 15 +- tests/ui/unnecessary_find_map.stderr | 13 +- tests/ui/unnecessary_first_then_check.fixed | 7 + tests/ui/unnecessary_first_then_check.rs | 7 + tests/ui/unnecessary_first_then_check.stderr | 12 +- tests/ui/unnecessary_fold.fixed | 16 + tests/ui/unnecessary_fold.rs | 16 + tests/ui/unnecessary_fold.stderr | 30 +- tests/ui/unnecessary_get_then_check.fixed | 30 +- tests/ui/unnecessary_get_then_check.rs | 30 +- tests/ui/unnecessary_get_then_check.stderr | 80 +-- tests/ui/unnecessary_iter_cloned.fixed | 15 +- tests/ui/unnecessary_iter_cloned.rs | 15 +- tests/ui/unnecessary_iter_cloned.stderr | 16 +- tests/ui/unnecessary_join.rs | 2 + tests/ui/unnecessary_join.stderr | 4 +- tests/ui/unnecessary_lazy_eval.fixed | 86 ++- tests/ui/unnecessary_lazy_eval.rs | 86 ++- tests/ui/unnecessary_lazy_eval.stderr | 124 ++--- tests/ui/unnecessary_lazy_eval_unfixable.rs | 12 +- .../ui/unnecessary_lazy_eval_unfixable.stderr | 6 +- tests/ui/unnecessary_literal_bound.fixed | 3 + tests/ui/unnecessary_literal_bound.rs | 3 + tests/ui/unnecessary_literal_bound.stderr | 4 +- tests/ui/unnecessary_literal_unwrap.fixed | 53 ++ tests/ui/unnecessary_literal_unwrap.rs | 53 ++ tests/ui/unnecessary_literal_unwrap.stderr | 104 ++-- .../unnecessary_literal_unwrap_unfixable.rs | 156 ++++-- ...nnecessary_literal_unwrap_unfixable.stderr | 198 +++---- tests/ui/unnecessary_map_on_constructor.fixed | 8 + tests/ui/unnecessary_map_on_constructor.rs | 8 + .../ui/unnecessary_map_on_constructor.stderr | 14 +- tests/ui/unnecessary_map_or.fixed | 23 + tests/ui/unnecessary_map_or.rs | 24 + tests/ui/unnecessary_map_or.stderr | 48 +- tests/ui/unnecessary_min_or_max.fixed | 17 + tests/ui/unnecessary_min_or_max.rs | 17 + tests/ui/unnecessary_min_or_max.stderr | 32 +- tests/ui/unnecessary_operation.fixed | 20 +- tests/ui/unnecessary_operation.rs | 22 +- tests/ui/unnecessary_operation.stderr | 40 +- .../ui/unnecessary_owned_empty_strings.fixed | 2 + tests/ui/unnecessary_owned_empty_strings.rs | 2 + .../ui/unnecessary_owned_empty_strings.stderr | 2 +- tests/ui/unnecessary_result_map_or_else.fixed | 9 +- tests/ui/unnecessary_result_map_or_else.rs | 12 +- .../ui/unnecessary_result_map_or_else.stderr | 22 +- tests/ui/unnecessary_safety_comment.rs | 25 +- tests/ui/unnecessary_safety_comment.stderr | 50 +- tests/ui/unnecessary_self_imports.fixed | 2 + tests/ui/unnecessary_self_imports.rs | 2 + tests/ui/unnecessary_self_imports.stderr | 2 +- .../unnecessary_semicolon.edition2021.fixed | 8 +- .../unnecessary_semicolon.edition2021.stderr | 4 +- .../unnecessary_semicolon.edition2024.fixed | 8 +- .../unnecessary_semicolon.edition2024.stderr | 6 +- tests/ui/unnecessary_semicolon.rs | 8 +- tests/ui/unnecessary_sort_by.fixed | 12 + tests/ui/unnecessary_sort_by.rs | 12 + tests/ui/unnecessary_sort_by.stderr | 22 +- tests/ui/unnecessary_sort_by_no_std.fixed | 2 + tests/ui/unnecessary_sort_by_no_std.rs | 2 + tests/ui/unnecessary_sort_by_no_std.stderr | 2 +- .../unnecessary_struct_initialization.fixed | 9 + tests/ui/unnecessary_struct_initialization.rs | 11 + .../unnecessary_struct_initialization.stderr | 22 +- tests/ui/unnecessary_to_owned.fixed | 98 +++- tests/ui/unnecessary_to_owned.rs | 98 +++- tests/ui/unnecessary_to_owned.stderr | 205 ++++---- tests/ui/unnecessary_to_owned_on_split.fixed | 27 +- tests/ui/unnecessary_to_owned_on_split.rs | 27 +- tests/ui/unnecessary_to_owned_on_split.stderr | 16 +- tests/ui/unnecessary_unsafety_doc.rs | 7 + tests/ui/unnecessary_unsafety_doc.stderr | 12 +- tests/ui/unnecessary_wraps.rs | 23 +- tests/ui/unnecessary_wraps.stderr | 26 +- tests/ui/unneeded_field_pattern.rs | 2 + tests/ui/unneeded_field_pattern.stderr | 2 +- tests/ui/unneeded_struct_pattern.fixed | 62 +-- tests/ui/unneeded_struct_pattern.rs | 47 +- tests/ui/unneeded_struct_pattern.stderr | 152 ++---- tests/ui/unneeded_wildcard_pattern.fixed | 14 + tests/ui/unneeded_wildcard_pattern.rs | 14 + tests/ui/unneeded_wildcard_pattern.stderr | 26 +- tests/ui/unnested_or_patterns.fixed | 17 + tests/ui/unnested_or_patterns.rs | 17 + tests/ui/unnested_or_patterns.stderr | 32 +- tests/ui/unnested_or_patterns2.fixed | 8 + tests/ui/unnested_or_patterns2.rs | 8 + tests/ui/unnested_or_patterns2.stderr | 14 +- tests/ui/unreadable_literal.fixed | 10 + tests/ui/unreadable_literal.rs | 10 + tests/ui/unreadable_literal.stderr | 12 +- tests/ui/unsafe_removed_from_name.rs | 17 +- tests/ui/unsafe_removed_from_name.stderr | 8 +- tests/ui/unseparated_prefix_literals.fixed | 9 + tests/ui/unseparated_prefix_literals.rs | 9 + tests/ui/unseparated_prefix_literals.stderr | 16 +- tests/ui/unused_async.rs | 12 +- tests/ui/unused_async.stderr | 11 +- tests/ui/unused_enumerate_index.fixed | 8 + tests/ui/unused_enumerate_index.rs | 8 + tests/ui/unused_enumerate_index.stderr | 38 +- tests/ui/unused_format_specs.1.fixed | 26 +- tests/ui/unused_format_specs.2.fixed | 26 +- tests/ui/unused_format_specs.rs | 26 +- tests/ui/unused_format_specs.stderr | 14 +- tests/ui/unused_io_amount.rs | 59 +-- tests/ui/unused_io_amount.stderr | 32 +- tests/ui/unused_peekable.rs | 24 +- tests/ui/unused_peekable.stderr | 14 +- tests/ui/unused_result_ok.fixed | 4 + tests/ui/unused_result_ok.rs | 4 + tests/ui/unused_result_ok.stderr | 6 +- tests/ui/unused_rounding.fixed | 5 + tests/ui/unused_rounding.rs | 5 + tests/ui/unused_rounding.stderr | 8 +- tests/ui/unused_self.rs | 27 +- tests/ui/unused_self.stderr | 16 +- tests/ui/unused_trait_names.fixed | 10 + tests/ui/unused_trait_names.rs | 10 + tests/ui/unused_trait_names.stderr | 18 +- tests/ui/unused_unit.fixed | 19 + tests/ui/unused_unit.rs | 19 + tests/ui/unused_unit.stderr | 62 +-- tests/ui/unwrap.rs | 9 +- tests/ui/unwrap.stderr | 4 +- tests/ui/unwrap_expect_used.rs | 17 +- tests/ui/unwrap_expect_used.stderr | 10 +- tests/ui/unwrap_in_result.rs | 7 +- tests/ui/unwrap_in_result.stderr | 16 +- tests/ui/unwrap_or.fixed | 8 +- tests/ui/unwrap_or.rs | 8 +- tests/ui/unwrap_or.stderr | 2 +- tests/ui/unwrap_or_else_default.fixed | 16 + tests/ui/unwrap_or_else_default.rs | 16 + tests/ui/unwrap_or_else_default.stderr | 56 +- tests/ui/upper_case_acronyms.fixed | 38 +- tests/ui/upper_case_acronyms.rs | 38 +- tests/ui/upper_case_acronyms.stderr | 22 +- tests/ui/use_self.fixed | 43 ++ tests/ui/use_self.rs | 43 ++ tests/ui/use_self.stderr | 84 +-- tests/ui/use_self_trait.fixed | 16 + tests/ui/use_self_trait.rs | 16 + tests/ui/use_self_trait.stderr | 28 +- tests/ui/used_underscore_binding.rs | 6 + tests/ui/used_underscore_binding.stderr | 20 +- tests/ui/used_underscore_items.rs | 9 + tests/ui/used_underscore_items.stderr | 16 +- tests/ui/useful_asref.rs | 2 + tests/ui/useless_asref.fixed | 32 +- tests/ui/useless_asref.rs | 32 +- tests/ui/useless_asref.stderr | 34 +- tests/ui/useless_attribute.fixed | 3 + tests/ui/useless_attribute.rs | 3 + tests/ui/useless_attribute.stderr | 4 +- tests/ui/useless_conversion.fixed | 47 +- tests/ui/useless_conversion.rs | 41 ++ tests/ui/useless_conversion.stderr | 108 ++-- tests/ui/useless_conversion_try.rs | 27 +- tests/ui/useless_conversion_try.stderr | 16 +- tests/ui/useless_nonzero_new_unchecked.fixed | 15 +- tests/ui/useless_nonzero_new_unchecked.rs | 15 +- tests/ui/useless_nonzero_new_unchecked.stderr | 8 +- tests/ui/useless_vec.rs | 3 +- tests/ui/useless_vec.stderr | 1 + tests/ui/vec.fixed | 23 +- tests/ui/vec.rs | 23 +- tests/ui/vec.stderr | 64 +-- tests/ui/vec_box_sized.rs | 9 + tests/ui/vec_box_sized.stderr | 16 +- tests/ui/vec_init_then_push.rs | 26 +- tests/ui/vec_init_then_push.stderr | 26 +- tests/ui/vec_resize_to_zero.fixed | 3 +- tests/ui/vec_resize_to_zero.rs | 3 +- tests/ui/verbose_file_reads.rs | 6 +- tests/ui/verbose_file_reads.stderr | 2 +- tests/ui/waker_clone_wake.fixed | 2 + tests/ui/waker_clone_wake.rs | 2 + tests/ui/waker_clone_wake.stderr | 2 +- tests/ui/while_float.rs | 2 + tests/ui/while_float.stderr | 2 +- tests/ui/while_let_loop.rs | 17 +- tests/ui/while_let_loop.stderr | 21 +- tests/ui/while_let_on_iterator.fixed | 28 + tests/ui/while_let_on_iterator.rs | 28 + tests/ui/while_let_on_iterator.stderr | 62 +-- tests/ui/wild_in_or_pats.rs | 14 +- tests/ui/wild_in_or_pats.stderr | 10 +- tests/ui/wildcard_enum_match_arm.fixed | 6 + tests/ui/wildcard_enum_match_arm.rs | 6 + tests/ui/wildcard_enum_match_arm.stderr | 10 +- tests/ui/wildcard_imports.fixed | 21 + tests/ui/wildcard_imports.rs | 22 + tests/ui/wildcard_imports.stderr | 43 +- .../wildcard_imports_2021.edition2018.fixed | 21 + .../wildcard_imports_2021.edition2018.stderr | 43 +- .../wildcard_imports_2021.edition2021.fixed | 21 + .../wildcard_imports_2021.edition2021.stderr | 43 +- tests/ui/wildcard_imports_2021.rs | 22 + tests/ui/wildcard_imports_cfgtest.rs | 1 + tests/ui/write_literal.fixed | 40 +- tests/ui/write_literal.rs | 40 +- tests/ui/write_literal.stderr | 29 +- tests/ui/write_literal_2.rs | 42 +- tests/ui/write_literal_2.stderr | 28 +- tests/ui/write_with_newline.fixed | 29 +- tests/ui/write_with_newline.rs | 29 +- tests/ui/write_with_newline.stderr | 20 +- tests/ui/writeln_empty_string.fixed | 2 + tests/ui/writeln_empty_string.rs | 2 + tests/ui/writeln_empty_string.stderr | 2 +- tests/ui/wrong_self_convention.rs | 72 ++- tests/ui/wrong_self_convention.stderr | 46 +- tests/ui/wrong_self_convention2.rs | 6 +- tests/ui/wrong_self_convention2.stderr | 2 +- tests/ui/wrong_self_conventions_mut.rs | 6 +- tests/ui/wrong_self_conventions_mut.stderr | 2 +- tests/ui/zero_div_zero.rs | 12 +- tests/ui/zero_div_zero.stderr | 6 +- tests/ui/zero_offset.rs | 26 +- tests/ui/zero_offset.stderr | 14 +- tests/ui/zero_ptr.fixed | 5 + tests/ui/zero_ptr.rs | 5 + tests/ui/zero_ptr.stderr | 8 +- tests/ui/zero_ptr_no_std.fixed | 3 + tests/ui/zero_ptr_no_std.rs | 3 + tests/ui/zero_ptr_no_std.stderr | 4 +- tests/ui/zero_repeat_side_effects.fixed | 9 + tests/ui/zero_repeat_side_effects.rs | 9 + tests/ui/zero_repeat_side_effects.stderr | 16 +- tests/ui/zero_sized_btreemap_values.rs | 39 +- tests/ui/zero_sized_btreemap_values.stderr | 24 +- tests/ui/zero_sized_hashmap_values.rs | 39 +- tests/ui/zero_sized_hashmap_values.stderr | 24 +- tests/ui/zombie_processes.rs | 8 + tests/ui/zombie_processes.stderr | 30 +- tests/ui/zombie_processes_fixable.fixed | 10 +- tests/ui/zombie_processes_fixable.rs | 10 +- tests/ui/zombie_processes_fixable.stderr | 6 +- 2287 files changed, 29493 insertions(+), 15906 deletions(-) delete mode 100644 tests/ui/collapsible_else_if.stderr delete mode 100644 tests/ui/collapsible_if.stderr delete mode 100644 tests/ui/crashes/ice-5835.fixed delete mode 100644 tests/ui/needless_bool/simple.stderr delete mode 100644 tests/ui/needless_bool_assign.stderr delete mode 100644 tests/ui/needless_else.stderr delete mode 100644 tests/ui/single_match.stderr delete mode 100644 tests/ui/single_match_else.stderr diff --git a/tests/ui/absurd-extreme-comparisons.rs b/tests/ui/absurd-extreme-comparisons.rs index 60f2ba4abcff..793961d30f0d 100644 --- a/tests/ui/absurd-extreme-comparisons.rs +++ b/tests/ui/absurd-extreme-comparisons.rs @@ -12,46 +12,64 @@ fn main() { const Z: u32 = 0; let u: u32 = 42; u <= 0; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + u <= Z; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + u < Z; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + Z >= u; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + Z > u; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + u > u32::MAX; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + u >= u32::MAX; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + u32::MAX < u; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + u32::MAX <= u; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + 1-1 > u; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + u >= !0; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + u <= 12 - 2*6; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + let i: i8 = 0; i < -127 - 1; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + i8::MAX >= i; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + 3-7 < i32::MIN; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + let b = false; b >= true; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + false > b; - //~^ ERROR: this comparison involving the minimum or maximum element for this type con + //~^ absurd_extreme_comparisons + u > 0; // ok // this is handled by clippy::unit_cmp () < {}; - //~^ ERROR: <-comparison of unit values detected. This will always be false - //~| NOTE: `#[deny(clippy::unit_cmp)]` on by default + //~^ unit_cmp + + } use std::cmp::{Ordering, PartialEq, PartialOrd}; diff --git a/tests/ui/absurd-extreme-comparisons.stderr b/tests/ui/absurd-extreme-comparisons.stderr index f98114c0000a..6df50c15e8cd 100644 --- a/tests/ui/absurd-extreme-comparisons.stderr +++ b/tests/ui/absurd-extreme-comparisons.stderr @@ -9,7 +9,7 @@ LL | u <= 0; = help: to override `-D warnings` add `#[allow(clippy::absurd_extreme_comparisons)]` error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:16:5 + --> tests/ui/absurd-extreme-comparisons.rs:17:5 | LL | u <= Z; | ^^^^^^ @@ -17,7 +17,7 @@ LL | u <= Z; = help: because `Z` is the minimum value for this type, the case where the two sides are not equal never occurs, consider using `u == Z` instead error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:18:5 + --> tests/ui/absurd-extreme-comparisons.rs:20:5 | LL | u < Z; | ^^^^^ @@ -25,7 +25,7 @@ LL | u < Z; = help: because `Z` is the minimum value for this type, this comparison is always false error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:20:5 + --> tests/ui/absurd-extreme-comparisons.rs:23:5 | LL | Z >= u; | ^^^^^^ @@ -33,7 +33,7 @@ LL | Z >= u; = help: because `Z` is the minimum value for this type, the case where the two sides are not equal never occurs, consider using `Z == u` instead error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:22:5 + --> tests/ui/absurd-extreme-comparisons.rs:26:5 | LL | Z > u; | ^^^^^ @@ -41,7 +41,7 @@ LL | Z > u; = help: because `Z` is the minimum value for this type, this comparison is always false error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:24:5 + --> tests/ui/absurd-extreme-comparisons.rs:29:5 | LL | u > u32::MAX; | ^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | u > u32::MAX; = help: because `u32::MAX` is the maximum value for this type, this comparison is always false error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:26:5 + --> tests/ui/absurd-extreme-comparisons.rs:32:5 | LL | u >= u32::MAX; | ^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | u >= u32::MAX; = help: because `u32::MAX` is the maximum value for this type, the case where the two sides are not equal never occurs, consider using `u == u32::MAX` instead error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:28:5 + --> tests/ui/absurd-extreme-comparisons.rs:35:5 | LL | u32::MAX < u; | ^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | u32::MAX < u; = help: because `u32::MAX` is the maximum value for this type, this comparison is always false error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:30:5 + --> tests/ui/absurd-extreme-comparisons.rs:38:5 | LL | u32::MAX <= u; | ^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | u32::MAX <= u; = help: because `u32::MAX` is the maximum value for this type, the case where the two sides are not equal never occurs, consider using `u32::MAX == u` instead error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:32:5 + --> tests/ui/absurd-extreme-comparisons.rs:41:5 | LL | 1-1 > u; | ^^^^^^^ @@ -81,7 +81,7 @@ LL | 1-1 > u; = help: because `1-1` is the minimum value for this type, this comparison is always false error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:34:5 + --> tests/ui/absurd-extreme-comparisons.rs:44:5 | LL | u >= !0; | ^^^^^^^ @@ -89,7 +89,7 @@ LL | u >= !0; = help: because `!0` is the maximum value for this type, the case where the two sides are not equal never occurs, consider using `u == !0` instead error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:36:5 + --> tests/ui/absurd-extreme-comparisons.rs:47:5 | LL | u <= 12 - 2*6; | ^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | u <= 12 - 2*6; = help: because `12 - 2*6` is the minimum value for this type, the case where the two sides are not equal never occurs, consider using `u == 12 - 2*6` instead error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:39:5 + --> tests/ui/absurd-extreme-comparisons.rs:51:5 | LL | i < -127 - 1; | ^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | i < -127 - 1; = help: because `-127 - 1` is the minimum value for this type, this comparison is always false error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:41:5 + --> tests/ui/absurd-extreme-comparisons.rs:54:5 | LL | i8::MAX >= i; | ^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | i8::MAX >= i; = help: because `i8::MAX` is the maximum value for this type, this comparison is always true error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:43:5 + --> tests/ui/absurd-extreme-comparisons.rs:57:5 | LL | 3-7 < i32::MIN; | ^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | 3-7 < i32::MIN; = help: because `i32::MIN` is the minimum value for this type, this comparison is always false error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:46:5 + --> tests/ui/absurd-extreme-comparisons.rs:61:5 | LL | b >= true; | ^^^^^^^^^ @@ -129,7 +129,7 @@ LL | b >= true; = help: because `true` is the maximum value for this type, the case where the two sides are not equal never occurs, consider using `b == true` instead error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> tests/ui/absurd-extreme-comparisons.rs:48:5 + --> tests/ui/absurd-extreme-comparisons.rs:64:5 | LL | false > b; | ^^^^^^^^^ @@ -137,7 +137,7 @@ LL | false > b; = help: because `false` is the minimum value for this type, this comparison is always false error: <-comparison of unit values detected. This will always be false - --> tests/ui/absurd-extreme-comparisons.rs:52:5 + --> tests/ui/absurd-extreme-comparisons.rs:69:5 | LL | () < {}; | ^^^^^^^ diff --git a/tests/ui/allow_attributes.fixed b/tests/ui/allow_attributes.fixed index 8f6c962e2f5b..56a98cca3404 100644 --- a/tests/ui/allow_attributes.fixed +++ b/tests/ui/allow_attributes.fixed @@ -11,6 +11,7 @@ use proc_macros::{external, with_span}; // Should lint #[expect(dead_code)] +//~^ allow_attributes struct T1; struct T2; // Should not lint @@ -20,6 +21,7 @@ struct T3; struct T4; // `panic = "unwind"` should always be true #[cfg_attr(panic = "unwind", expect(dead_code))] +//~^ allow_attributes struct CfgT; #[allow(clippy::allow_attributes, unused)] @@ -51,6 +53,7 @@ fn ignore_inner_attr() { #[clippy::msrv = "1.81"] fn msrv_1_81() { #[expect(unused)] + //~^ allow_attributes let x = 1; } diff --git a/tests/ui/allow_attributes.rs b/tests/ui/allow_attributes.rs index cb6c4dcf7158..65a0a6b5a108 100644 --- a/tests/ui/allow_attributes.rs +++ b/tests/ui/allow_attributes.rs @@ -11,6 +11,7 @@ use proc_macros::{external, with_span}; // Should lint #[allow(dead_code)] +//~^ allow_attributes struct T1; struct T2; // Should not lint @@ -20,6 +21,7 @@ struct T3; struct T4; // `panic = "unwind"` should always be true #[cfg_attr(panic = "unwind", allow(dead_code))] +//~^ allow_attributes struct CfgT; #[allow(clippy::allow_attributes, unused)] @@ -51,6 +53,7 @@ fn ignore_inner_attr() { #[clippy::msrv = "1.81"] fn msrv_1_81() { #[allow(unused)] + //~^ allow_attributes let x = 1; } diff --git a/tests/ui/allow_attributes.stderr b/tests/ui/allow_attributes.stderr index 5a4ff287acd2..dd5fb21ffeaf 100644 --- a/tests/ui/allow_attributes.stderr +++ b/tests/ui/allow_attributes.stderr @@ -8,13 +8,13 @@ LL | #[allow(dead_code)] = help: to override `-D warnings` add `#[allow(clippy::allow_attributes)]` error: #[allow] attribute found - --> tests/ui/allow_attributes.rs:22:30 + --> tests/ui/allow_attributes.rs:23:30 | LL | #[cfg_attr(panic = "unwind", allow(dead_code))] | ^^^^^ help: replace it with: `expect` error: #[allow] attribute found - --> tests/ui/allow_attributes.rs:53:7 + --> tests/ui/allow_attributes.rs:55:7 | LL | #[allow(unused)] | ^^^^^ help: replace it with: `expect` diff --git a/tests/ui/allow_attributes_without_reason.rs b/tests/ui/allow_attributes_without_reason.rs index 334e7ddd9d23..ea89511ebb46 100644 --- a/tests/ui/allow_attributes_without_reason.rs +++ b/tests/ui/allow_attributes_without_reason.rs @@ -1,14 +1,18 @@ //@aux-build:proc_macros.rs #![deny(clippy::allow_attributes_without_reason)] #![allow(unfulfilled_lint_expectations, clippy::duplicated_attributes)] +//~^ allow_attributes_without_reason extern crate proc_macros; use proc_macros::{external, with_span}; // These should trigger the lint #[allow(dead_code)] +//~^ allow_attributes_without_reason #[allow(dead_code, deprecated)] +//~^ allow_attributes_without_reason #[expect(dead_code)] +//~^ allow_attributes_without_reason // These should be fine #[allow(dead_code, reason = "This should be allowed")] #[warn(dyn_drop, reason = "Warnings can also have reasons")] @@ -44,6 +48,7 @@ pub fn trigger_fp_result() -> Result<(), &'static str> { #[clippy::msrv = "1.81"] fn msrv_1_81() { #[allow(unused)] + //~^ allow_attributes_without_reason let _ = 1; } diff --git a/tests/ui/allow_attributes_without_reason.stderr b/tests/ui/allow_attributes_without_reason.stderr index 9c1ac5af91b0..07e74839b769 100644 --- a/tests/ui/allow_attributes_without_reason.stderr +++ b/tests/ui/allow_attributes_without_reason.stderr @@ -12,7 +12,7 @@ LL | #![deny(clippy::allow_attributes_without_reason)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `allow` attribute without specifying a reason - --> tests/ui/allow_attributes_without_reason.rs:9:1 + --> tests/ui/allow_attributes_without_reason.rs:10:1 | LL | #[allow(dead_code)] | ^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | #[allow(dead_code)] = help: try adding a reason at the end with `, reason = ".."` error: `allow` attribute without specifying a reason - --> tests/ui/allow_attributes_without_reason.rs:10:1 + --> tests/ui/allow_attributes_without_reason.rs:12:1 | LL | #[allow(dead_code, deprecated)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | #[allow(dead_code, deprecated)] = help: try adding a reason at the end with `, reason = ".."` error: `expect` attribute without specifying a reason - --> tests/ui/allow_attributes_without_reason.rs:11:1 + --> tests/ui/allow_attributes_without_reason.rs:14:1 | LL | #[expect(dead_code)] | ^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | #[expect(dead_code)] = help: try adding a reason at the end with `, reason = ".."` error: `allow` attribute without specifying a reason - --> tests/ui/allow_attributes_without_reason.rs:46:5 + --> tests/ui/allow_attributes_without_reason.rs:50:5 | LL | #[allow(unused)] | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/almost_complete_range.fixed b/tests/ui/almost_complete_range.fixed index 6c2b2f117437..7591508b8350 100644 --- a/tests/ui/almost_complete_range.fixed +++ b/tests/ui/almost_complete_range.fixed @@ -15,8 +15,11 @@ fn main() { #[rustfmt::skip] { let _ = ('a') ..='z'; + //~^ almost_complete_range let _ = 'A' ..= ('Z'); + //~^ almost_complete_range let _ = ((('0'))) ..= ('9'); + //~^ almost_complete_range } let _ = 'b'..'z'; @@ -24,21 +27,30 @@ fn main() { let _ = '1'..'9'; let _ = (b'a')..=(b'z'); + //~^ almost_complete_range let _ = b'A'..=b'Z'; + //~^ almost_complete_range let _ = b'0'..=b'9'; + //~^ almost_complete_range let _ = b'b'..b'z'; let _ = b'B'..b'Z'; let _ = b'1'..b'9'; let _ = inline!('a')..='z'; + //~^ almost_complete_range let _ = inline!('A')..='Z'; + //~^ almost_complete_range let _ = inline!('0')..='9'; + //~^ almost_complete_range let _ = match 0u8 { b'a'..=b'z' if true => 1, + //~^ almost_complete_range b'A'..=b'Z' if true => 2, + //~^ almost_complete_range b'0'..=b'9' if true => 3, + //~^ almost_complete_range b'b'..b'z' => 4, b'B'..b'Z' => 5, b'1'..b'9' => 6, @@ -47,8 +59,11 @@ fn main() { let _ = match 'x' { 'a'..='z' if true => 1, + //~^ almost_complete_range 'A'..='Z' if true => 2, + //~^ almost_complete_range '0'..='9' if true => 3, + //~^ almost_complete_range 'b'..'z' => 4, 'B'..'Z' => 5, '1'..'9' => 6, @@ -62,8 +77,11 @@ fn main() { ); inline!( let _ = 'a'..='z'; + //~^ almost_complete_range let _ = 'A'..='Z'; + //~^ almost_complete_range let _ = '0'..='9'; + //~^ almost_complete_range ); } @@ -71,8 +89,11 @@ fn main() { fn _under_msrv() { let _ = match 'a' { 'a'...'z' => 1, + //~^ almost_complete_range 'A'...'Z' => 2, + //~^ almost_complete_range '0'...'9' => 3, + //~^ almost_complete_range _ => 4, }; } @@ -80,12 +101,18 @@ fn _under_msrv() { #[clippy::msrv = "1.26"] fn _meets_msrv() { let _ = 'a'..='z'; + //~^ almost_complete_range let _ = 'A'..='Z'; + //~^ almost_complete_range let _ = '0'..='9'; + //~^ almost_complete_range let _ = match 'a' { 'a'..='z' => 1, + //~^ almost_complete_range 'A'..='Z' => 1, + //~^ almost_complete_range '0'..='9' => 3, + //~^ almost_complete_range _ => 4, }; } diff --git a/tests/ui/almost_complete_range.rs b/tests/ui/almost_complete_range.rs index 813668a53096..907f70bd8156 100644 --- a/tests/ui/almost_complete_range.rs +++ b/tests/ui/almost_complete_range.rs @@ -15,8 +15,11 @@ fn main() { #[rustfmt::skip] { let _ = ('a') ..'z'; + //~^ almost_complete_range let _ = 'A' .. ('Z'); + //~^ almost_complete_range let _ = ((('0'))) .. ('9'); + //~^ almost_complete_range } let _ = 'b'..'z'; @@ -24,21 +27,30 @@ fn main() { let _ = '1'..'9'; let _ = (b'a')..(b'z'); + //~^ almost_complete_range let _ = b'A'..b'Z'; + //~^ almost_complete_range let _ = b'0'..b'9'; + //~^ almost_complete_range let _ = b'b'..b'z'; let _ = b'B'..b'Z'; let _ = b'1'..b'9'; let _ = inline!('a')..'z'; + //~^ almost_complete_range let _ = inline!('A')..'Z'; + //~^ almost_complete_range let _ = inline!('0')..'9'; + //~^ almost_complete_range let _ = match 0u8 { b'a'..b'z' if true => 1, + //~^ almost_complete_range b'A'..b'Z' if true => 2, + //~^ almost_complete_range b'0'..b'9' if true => 3, + //~^ almost_complete_range b'b'..b'z' => 4, b'B'..b'Z' => 5, b'1'..b'9' => 6, @@ -47,8 +59,11 @@ fn main() { let _ = match 'x' { 'a'..'z' if true => 1, + //~^ almost_complete_range 'A'..'Z' if true => 2, + //~^ almost_complete_range '0'..'9' if true => 3, + //~^ almost_complete_range 'b'..'z' => 4, 'B'..'Z' => 5, '1'..'9' => 6, @@ -62,8 +77,11 @@ fn main() { ); inline!( let _ = 'a'..'z'; + //~^ almost_complete_range let _ = 'A'..'Z'; + //~^ almost_complete_range let _ = '0'..'9'; + //~^ almost_complete_range ); } @@ -71,8 +89,11 @@ fn main() { fn _under_msrv() { let _ = match 'a' { 'a'..'z' => 1, + //~^ almost_complete_range 'A'..'Z' => 2, + //~^ almost_complete_range '0'..'9' => 3, + //~^ almost_complete_range _ => 4, }; } @@ -80,12 +101,18 @@ fn _under_msrv() { #[clippy::msrv = "1.26"] fn _meets_msrv() { let _ = 'a'..'z'; + //~^ almost_complete_range let _ = 'A'..'Z'; + //~^ almost_complete_range let _ = '0'..'9'; + //~^ almost_complete_range let _ = match 'a' { 'a'..'z' => 1, + //~^ almost_complete_range 'A'..'Z' => 1, + //~^ almost_complete_range '0'..'9' => 3, + //~^ almost_complete_range _ => 4, }; } diff --git a/tests/ui/almost_complete_range.stderr b/tests/ui/almost_complete_range.stderr index bfc2beb07d85..217df7f4883f 100644 --- a/tests/ui/almost_complete_range.stderr +++ b/tests/ui/almost_complete_range.stderr @@ -10,7 +10,7 @@ LL | let _ = ('a') ..'z'; = help: to override `-D warnings` add `#[allow(clippy::almost_complete_range)]` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:18:17 + --> tests/ui/almost_complete_range.rs:19:17 | LL | let _ = 'A' .. ('Z'); | ^^^^--^^^^^^ @@ -18,7 +18,7 @@ LL | let _ = 'A' .. ('Z'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:19:17 + --> tests/ui/almost_complete_range.rs:21:17 | LL | let _ = ((('0'))) .. ('9'); | ^^^^^^^^^^--^^^^^^ @@ -26,7 +26,7 @@ LL | let _ = ((('0'))) .. ('9'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:26:13 + --> tests/ui/almost_complete_range.rs:29:13 | LL | let _ = (b'a')..(b'z'); | ^^^^^^--^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = (b'a')..(b'z'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:27:13 + --> tests/ui/almost_complete_range.rs:31:13 | LL | let _ = b'A'..b'Z'; | ^^^^--^^^^ @@ -42,7 +42,7 @@ LL | let _ = b'A'..b'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:28:13 + --> tests/ui/almost_complete_range.rs:33:13 | LL | let _ = b'0'..b'9'; | ^^^^--^^^^ @@ -50,7 +50,7 @@ LL | let _ = b'0'..b'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:34:13 + --> tests/ui/almost_complete_range.rs:40:13 | LL | let _ = inline!('a')..'z'; | ^^^^^^^^^^^^--^^^ @@ -58,7 +58,7 @@ LL | let _ = inline!('a')..'z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:35:13 + --> tests/ui/almost_complete_range.rs:42:13 | LL | let _ = inline!('A')..'Z'; | ^^^^^^^^^^^^--^^^ @@ -66,7 +66,7 @@ LL | let _ = inline!('A')..'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:36:13 + --> tests/ui/almost_complete_range.rs:44:13 | LL | let _ = inline!('0')..'9'; | ^^^^^^^^^^^^--^^^ @@ -74,7 +74,7 @@ LL | let _ = inline!('0')..'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:39:9 + --> tests/ui/almost_complete_range.rs:48:9 | LL | b'a'..b'z' if true => 1, | ^^^^--^^^^ @@ -82,7 +82,7 @@ LL | b'a'..b'z' if true => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:40:9 + --> tests/ui/almost_complete_range.rs:50:9 | LL | b'A'..b'Z' if true => 2, | ^^^^--^^^^ @@ -90,7 +90,7 @@ LL | b'A'..b'Z' if true => 2, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:41:9 + --> tests/ui/almost_complete_range.rs:52:9 | LL | b'0'..b'9' if true => 3, | ^^^^--^^^^ @@ -98,7 +98,7 @@ LL | b'0'..b'9' if true => 3, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:49:9 + --> tests/ui/almost_complete_range.rs:61:9 | LL | 'a'..'z' if true => 1, | ^^^--^^^ @@ -106,7 +106,7 @@ LL | 'a'..'z' if true => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:50:9 + --> tests/ui/almost_complete_range.rs:63:9 | LL | 'A'..'Z' if true => 2, | ^^^--^^^ @@ -114,7 +114,7 @@ LL | 'A'..'Z' if true => 2, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:51:9 + --> tests/ui/almost_complete_range.rs:65:9 | LL | '0'..'9' if true => 3, | ^^^--^^^ @@ -122,7 +122,7 @@ LL | '0'..'9' if true => 3, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:64:17 + --> tests/ui/almost_complete_range.rs:79:17 | LL | let _ = 'a'..'z'; | ^^^--^^^ @@ -132,7 +132,7 @@ LL | let _ = 'a'..'z'; = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:65:17 + --> tests/ui/almost_complete_range.rs:81:17 | LL | let _ = 'A'..'Z'; | ^^^--^^^ @@ -142,7 +142,7 @@ LL | let _ = 'A'..'Z'; = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:66:17 + --> tests/ui/almost_complete_range.rs:83:17 | LL | let _ = '0'..'9'; | ^^^--^^^ @@ -152,7 +152,7 @@ LL | let _ = '0'..'9'; = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:73:9 + --> tests/ui/almost_complete_range.rs:91:9 | LL | 'a'..'z' => 1, | ^^^--^^^ @@ -160,7 +160,7 @@ LL | 'a'..'z' => 1, | help: use an inclusive range: `...` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:74:9 + --> tests/ui/almost_complete_range.rs:93:9 | LL | 'A'..'Z' => 2, | ^^^--^^^ @@ -168,7 +168,7 @@ LL | 'A'..'Z' => 2, | help: use an inclusive range: `...` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:75:9 + --> tests/ui/almost_complete_range.rs:95:9 | LL | '0'..'9' => 3, | ^^^--^^^ @@ -176,7 +176,7 @@ LL | '0'..'9' => 3, | help: use an inclusive range: `...` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:82:13 + --> tests/ui/almost_complete_range.rs:103:13 | LL | let _ = 'a'..'z'; | ^^^--^^^ @@ -184,7 +184,7 @@ LL | let _ = 'a'..'z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:83:13 + --> tests/ui/almost_complete_range.rs:105:13 | LL | let _ = 'A'..'Z'; | ^^^--^^^ @@ -192,7 +192,7 @@ LL | let _ = 'A'..'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:84:13 + --> tests/ui/almost_complete_range.rs:107:13 | LL | let _ = '0'..'9'; | ^^^--^^^ @@ -200,7 +200,7 @@ LL | let _ = '0'..'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:86:9 + --> tests/ui/almost_complete_range.rs:110:9 | LL | 'a'..'z' => 1, | ^^^--^^^ @@ -208,7 +208,7 @@ LL | 'a'..'z' => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:87:9 + --> tests/ui/almost_complete_range.rs:112:9 | LL | 'A'..'Z' => 1, | ^^^--^^^ @@ -216,7 +216,7 @@ LL | 'A'..'Z' => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> tests/ui/almost_complete_range.rs:88:9 + --> tests/ui/almost_complete_range.rs:114:9 | LL | '0'..'9' => 3, | ^^^--^^^ diff --git a/tests/ui/approx_const.rs b/tests/ui/approx_const.rs index 3c4ed0367894..6461666be8f5 100644 --- a/tests/ui/approx_const.rs +++ b/tests/ui/approx_const.rs @@ -1,86 +1,109 @@ #[warn(clippy::approx_constant)] fn main() { let my_e = 2.7182; - //~^ ERROR: approximate value of `f{32, 64}::consts::E` found + //~^ approx_constant + let almost_e = 2.718; - //~^ ERROR: approximate value of `f{32, 64}::consts::E` found + //~^ approx_constant + let no_e = 2.71; let my_1_frac_pi = 0.3183; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_1_PI` found + //~^ approx_constant + let no_1_frac_pi = 0.31; let my_frac_1_sqrt_2 = 0.70710678; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found + //~^ approx_constant + let almost_frac_1_sqrt_2 = 0.70711; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found + //~^ approx_constant + let my_frac_1_sqrt_2 = 0.707; let my_frac_2_pi = 0.63661977; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_2_PI` found + //~^ approx_constant + let no_frac_2_pi = 0.636; let my_frac_2_sq_pi = 1.128379; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_2_SQRT_PI` found + //~^ approx_constant + let no_frac_2_sq_pi = 1.128; let my_frac_pi_2 = 1.57079632679; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_2` found + //~^ approx_constant + let no_frac_pi_2 = 1.5705; let my_frac_pi_3 = 1.04719755119; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_3` found + //~^ approx_constant + let no_frac_pi_3 = 1.047; let my_frac_pi_4 = 0.785398163397; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_4` found + //~^ approx_constant + let no_frac_pi_4 = 0.785; let my_frac_pi_6 = 0.523598775598; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_6` found + //~^ approx_constant + let no_frac_pi_6 = 0.523; let my_frac_pi_8 = 0.3926990816987; - //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_8` found + //~^ approx_constant + let no_frac_pi_8 = 0.392; let my_ln_10 = 2.302585092994046; - //~^ ERROR: approximate value of `f{32, 64}::consts::LN_10` found + //~^ approx_constant + let no_ln_10 = 2.303; let my_ln_2 = 0.6931471805599453; - //~^ ERROR: approximate value of `f{32, 64}::consts::LN_2` found + //~^ approx_constant + let no_ln_2 = 0.693; let my_log10_e = 0.4342944819032518; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG10_E` found + //~^ approx_constant + let no_log10_e = 0.434; let my_log2_e = 1.4426950408889634; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_E` found + //~^ approx_constant + let no_log2_e = 1.442; let log2_10 = 3.321928094887362; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found + //~^ approx_constant + let no_log2_10 = 3.321; let log10_2 = 0.301029995663981; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG10_2` found + //~^ approx_constant + let no_log10_2 = 0.301; let my_pi = 3.1415; - //~^ ERROR: approximate value of `f{32, 64}::consts::PI` found + //~^ approx_constant + let almost_pi = 3.14; - //~^ ERROR: approximate value of `f{32, 64}::consts::PI` found + //~^ approx_constant + let no_pi = 3.15; let my_sq2 = 1.4142; - //~^ ERROR: approximate value of `f{32, 64}::consts::SQRT_2` found + //~^ approx_constant + let no_sq2 = 1.414; let my_tau = 6.2832; - //~^ ERROR: approximate value of `f{32, 64}::consts::TAU` found + //~^ approx_constant + let almost_tau = 6.28; - //~^ ERROR: approximate value of `f{32, 64}::consts::TAU` found + //~^ approx_constant + let no_tau = 6.3; } diff --git a/tests/ui/approx_const.stderr b/tests/ui/approx_const.stderr index 5e82d51edf20..f7bda0468cbd 100644 --- a/tests/ui/approx_const.stderr +++ b/tests/ui/approx_const.stderr @@ -9,7 +9,7 @@ LL | let my_e = 2.7182; = help: to override `-D warnings` add `#[allow(clippy::approx_constant)]` error: approximate value of `f{32, 64}::consts::E` found - --> tests/ui/approx_const.rs:5:20 + --> tests/ui/approx_const.rs:6:20 | LL | let almost_e = 2.718; | ^^^^^ @@ -17,7 +17,7 @@ LL | let almost_e = 2.718; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_1_PI` found - --> tests/ui/approx_const.rs:9:24 + --> tests/ui/approx_const.rs:11:24 | LL | let my_1_frac_pi = 0.3183; | ^^^^^^ @@ -25,7 +25,7 @@ LL | let my_1_frac_pi = 0.3183; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found - --> tests/ui/approx_const.rs:13:28 + --> tests/ui/approx_const.rs:16:28 | LL | let my_frac_1_sqrt_2 = 0.70710678; | ^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let my_frac_1_sqrt_2 = 0.70710678; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found - --> tests/ui/approx_const.rs:15:32 + --> tests/ui/approx_const.rs:19:32 | LL | let almost_frac_1_sqrt_2 = 0.70711; | ^^^^^^^ @@ -41,7 +41,7 @@ LL | let almost_frac_1_sqrt_2 = 0.70711; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_2_PI` found - --> tests/ui/approx_const.rs:19:24 + --> tests/ui/approx_const.rs:24:24 | LL | let my_frac_2_pi = 0.63661977; | ^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let my_frac_2_pi = 0.63661977; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_2_SQRT_PI` found - --> tests/ui/approx_const.rs:23:27 + --> tests/ui/approx_const.rs:29:27 | LL | let my_frac_2_sq_pi = 1.128379; | ^^^^^^^^ @@ -57,7 +57,7 @@ LL | let my_frac_2_sq_pi = 1.128379; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_PI_2` found - --> tests/ui/approx_const.rs:27:24 + --> tests/ui/approx_const.rs:34:24 | LL | let my_frac_pi_2 = 1.57079632679; | ^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | let my_frac_pi_2 = 1.57079632679; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_PI_3` found - --> tests/ui/approx_const.rs:31:24 + --> tests/ui/approx_const.rs:39:24 | LL | let my_frac_pi_3 = 1.04719755119; | ^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let my_frac_pi_3 = 1.04719755119; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_PI_4` found - --> tests/ui/approx_const.rs:35:24 + --> tests/ui/approx_const.rs:44:24 | LL | let my_frac_pi_4 = 0.785398163397; | ^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | let my_frac_pi_4 = 0.785398163397; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_PI_6` found - --> tests/ui/approx_const.rs:39:24 + --> tests/ui/approx_const.rs:49:24 | LL | let my_frac_pi_6 = 0.523598775598; | ^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let my_frac_pi_6 = 0.523598775598; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::FRAC_PI_8` found - --> tests/ui/approx_const.rs:43:24 + --> tests/ui/approx_const.rs:54:24 | LL | let my_frac_pi_8 = 0.3926990816987; | ^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let my_frac_pi_8 = 0.3926990816987; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LN_10` found - --> tests/ui/approx_const.rs:47:20 + --> tests/ui/approx_const.rs:59:20 | LL | let my_ln_10 = 2.302585092994046; | ^^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | let my_ln_10 = 2.302585092994046; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LN_2` found - --> tests/ui/approx_const.rs:51:19 + --> tests/ui/approx_const.rs:64:19 | LL | let my_ln_2 = 0.6931471805599453; | ^^^^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | let my_ln_2 = 0.6931471805599453; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG10_E` found - --> tests/ui/approx_const.rs:55:22 + --> tests/ui/approx_const.rs:69:22 | LL | let my_log10_e = 0.4342944819032518; | ^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | let my_log10_e = 0.4342944819032518; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_E` found - --> tests/ui/approx_const.rs:59:21 + --> tests/ui/approx_const.rs:74:21 | LL | let my_log2_e = 1.4426950408889634; | ^^^^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | let my_log2_e = 1.4426950408889634; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/approx_const.rs:63:19 + --> tests/ui/approx_const.rs:79:19 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ LL | let log2_10 = 3.321928094887362; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG10_2` found - --> tests/ui/approx_const.rs:67:19 + --> tests/ui/approx_const.rs:84:19 | LL | let log10_2 = 0.301029995663981; | ^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | let log10_2 = 0.301029995663981; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::PI` found - --> tests/ui/approx_const.rs:71:17 + --> tests/ui/approx_const.rs:89:17 | LL | let my_pi = 3.1415; | ^^^^^^ @@ -153,7 +153,7 @@ LL | let my_pi = 3.1415; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::PI` found - --> tests/ui/approx_const.rs:73:21 + --> tests/ui/approx_const.rs:92:21 | LL | let almost_pi = 3.14; | ^^^^ @@ -161,7 +161,7 @@ LL | let almost_pi = 3.14; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::SQRT_2` found - --> tests/ui/approx_const.rs:77:18 + --> tests/ui/approx_const.rs:97:18 | LL | let my_sq2 = 1.4142; | ^^^^^^ @@ -169,7 +169,7 @@ LL | let my_sq2 = 1.4142; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::TAU` found - --> tests/ui/approx_const.rs:81:18 + --> tests/ui/approx_const.rs:102:18 | LL | let my_tau = 6.2832; | ^^^^^^ @@ -177,7 +177,7 @@ LL | let my_tau = 6.2832; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::TAU` found - --> tests/ui/approx_const.rs:83:22 + --> tests/ui/approx_const.rs:105:22 | LL | let almost_tau = 6.28; | ^^^^ diff --git a/tests/ui/arc_with_non_send_sync.rs b/tests/ui/arc_with_non_send_sync.rs index c287480bb1fd..07025ccc42fd 100644 --- a/tests/ui/arc_with_non_send_sync.rs +++ b/tests/ui/arc_with_non_send_sync.rs @@ -33,9 +33,12 @@ fn main() { let _ = Arc::new(42); let _ = Arc::new(RefCell::new(42)); + //~^ arc_with_non_send_sync let mutex = Mutex::new(1); let _ = Arc::new(mutex.lock().unwrap()); + //~^ arc_with_non_send_sync let _ = Arc::new(&42 as *const i32); + //~^ arc_with_non_send_sync } diff --git a/tests/ui/arc_with_non_send_sync.stderr b/tests/ui/arc_with_non_send_sync.stderr index da363a3ebdd9..5556b0df88c9 100644 --- a/tests/ui/arc_with_non_send_sync.stderr +++ b/tests/ui/arc_with_non_send_sync.stderr @@ -11,7 +11,7 @@ LL | let _ = Arc::new(RefCell::new(42)); = help: to override `-D warnings` add `#[allow(clippy::arc_with_non_send_sync)]` error: usage of an `Arc` that is not `Send` and `Sync` - --> tests/ui/arc_with_non_send_sync.rs:38:13 + --> tests/ui/arc_with_non_send_sync.rs:39:13 | LL | let _ = Arc::new(mutex.lock().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL | let _ = Arc::new(mutex.lock().unwrap()); = help: otherwise make `MutexGuard<'_, i32>` `Send` and `Sync` or consider a wrapper type such as `Mutex` error: usage of an `Arc` that is not `Send` and `Sync` - --> tests/ui/arc_with_non_send_sync.rs:40:13 + --> tests/ui/arc_with_non_send_sync.rs:42:13 | LL | let _ = Arc::new(&42 as *const i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/arithmetic_side_effects.rs b/tests/ui/arithmetic_side_effects.rs index f09106773c7e..21be2af201f0 100644 --- a/tests/ui/arithmetic_side_effects.rs +++ b/tests/ui/arithmetic_side_effects.rs @@ -164,13 +164,16 @@ pub fn association_with_structures_should_not_trigger_the_lint() { pub fn hard_coded_allowed() { let _ = 1f16 + 1f16; + //~^ arithmetic_side_effects let _ = 1f32 + 1f32; let _ = 1f64 + 1f64; let _ = 1f128 + 1f128; + //~^ arithmetic_side_effects let _ = Saturating(0u32) + Saturating(0u32); let _ = String::new() + ""; let _ = String::new() + &String::new(); + //~^ arithmetic_side_effects let _ = Wrapping(0u32) + Wrapping(0u32); let saturating: Saturating = Saturating(0u32); @@ -306,117 +309,221 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() { // Assign _n += 1; + //~^ arithmetic_side_effects _n += &1; + //~^ arithmetic_side_effects _n -= 1; + //~^ arithmetic_side_effects _n -= &1; + //~^ arithmetic_side_effects _n /= 0; + //~^ arithmetic_side_effects _n /= &0; + //~^ arithmetic_side_effects _n %= 0; + //~^ arithmetic_side_effects _n %= &0; + //~^ arithmetic_side_effects _n *= 2; + //~^ arithmetic_side_effects _n *= &2; + //~^ arithmetic_side_effects _n += -1; + //~^ arithmetic_side_effects _n += &-1; + //~^ arithmetic_side_effects _n -= -1; + //~^ arithmetic_side_effects _n -= &-1; + //~^ arithmetic_side_effects _n /= -0; + //~^ arithmetic_side_effects _n /= &-0; + //~^ arithmetic_side_effects _n %= -0; + //~^ arithmetic_side_effects _n %= &-0; + //~^ arithmetic_side_effects _n *= -2; + //~^ arithmetic_side_effects _n *= &-2; + //~^ arithmetic_side_effects _custom += Custom; + //~^ arithmetic_side_effects _custom += &Custom; + //~^ arithmetic_side_effects _custom -= Custom; + //~^ arithmetic_side_effects _custom -= &Custom; + //~^ arithmetic_side_effects _custom /= Custom; + //~^ arithmetic_side_effects _custom /= &Custom; + //~^ arithmetic_side_effects _custom %= Custom; + //~^ arithmetic_side_effects _custom %= &Custom; + //~^ arithmetic_side_effects _custom *= Custom; + //~^ arithmetic_side_effects _custom *= &Custom; + //~^ arithmetic_side_effects _custom >>= Custom; + //~^ arithmetic_side_effects _custom >>= &Custom; + //~^ arithmetic_side_effects _custom <<= Custom; + //~^ arithmetic_side_effects _custom <<= &Custom; + //~^ arithmetic_side_effects _custom += -Custom; + //~^ arithmetic_side_effects _custom += &-Custom; + //~^ arithmetic_side_effects _custom -= -Custom; + //~^ arithmetic_side_effects _custom -= &-Custom; + //~^ arithmetic_side_effects _custom /= -Custom; + //~^ arithmetic_side_effects _custom /= &-Custom; + //~^ arithmetic_side_effects _custom %= -Custom; + //~^ arithmetic_side_effects _custom %= &-Custom; + //~^ arithmetic_side_effects _custom *= -Custom; + //~^ arithmetic_side_effects _custom *= &-Custom; + //~^ arithmetic_side_effects _custom >>= -Custom; + //~^ arithmetic_side_effects _custom >>= &-Custom; + //~^ arithmetic_side_effects _custom <<= -Custom; + //~^ arithmetic_side_effects _custom <<= &-Custom; + //~^ arithmetic_side_effects // Binary _n = _n + 1; + //~^ arithmetic_side_effects _n = _n + &1; + //~^ arithmetic_side_effects _n = 1 + _n; + //~^ arithmetic_side_effects _n = &1 + _n; + //~^ arithmetic_side_effects _n = _n - 1; + //~^ arithmetic_side_effects _n = _n - &1; + //~^ arithmetic_side_effects _n = 1 - _n; + //~^ arithmetic_side_effects _n = &1 - _n; + //~^ arithmetic_side_effects _n = _n / 0; + //~^ arithmetic_side_effects _n = _n / &0; + //~^ arithmetic_side_effects _n = _n % 0; + //~^ arithmetic_side_effects _n = _n % &0; + //~^ arithmetic_side_effects _n = _n * 2; + //~^ arithmetic_side_effects _n = _n * &2; + //~^ arithmetic_side_effects _n = 2 * _n; + //~^ arithmetic_side_effects _n = &2 * _n; + //~^ arithmetic_side_effects _n = 23 + &85; + //~^ arithmetic_side_effects _n = &23 + 85; + //~^ arithmetic_side_effects _n = &23 + &85; + //~^ arithmetic_side_effects _custom = _custom + _custom; + //~^ arithmetic_side_effects _custom = _custom + &_custom; + //~^ arithmetic_side_effects _custom = Custom + _custom; + //~^ arithmetic_side_effects _custom = &Custom + _custom; + //~^ arithmetic_side_effects _custom = _custom - Custom; + //~^ arithmetic_side_effects _custom = _custom - &Custom; + //~^ arithmetic_side_effects _custom = Custom - _custom; + //~^ arithmetic_side_effects _custom = &Custom - _custom; + //~^ arithmetic_side_effects _custom = _custom / Custom; + //~^ arithmetic_side_effects _custom = _custom / &Custom; + //~^ arithmetic_side_effects _custom = _custom % Custom; + //~^ arithmetic_side_effects _custom = _custom % &Custom; + //~^ arithmetic_side_effects _custom = _custom * Custom; + //~^ arithmetic_side_effects _custom = _custom * &Custom; + //~^ arithmetic_side_effects _custom = Custom * _custom; + //~^ arithmetic_side_effects _custom = &Custom * _custom; + //~^ arithmetic_side_effects _custom = Custom + &Custom; + //~^ arithmetic_side_effects _custom = &Custom + Custom; + //~^ arithmetic_side_effects _custom = &Custom + &Custom; + //~^ arithmetic_side_effects _custom = _custom >> _custom; + //~^ arithmetic_side_effects _custom = _custom >> &_custom; + //~^ arithmetic_side_effects _custom = Custom << _custom; + //~^ arithmetic_side_effects _custom = &Custom << _custom; + //~^ arithmetic_side_effects // Method _n.saturating_div(0); + //~^ arithmetic_side_effects _n.wrapping_div(0); + //~^ arithmetic_side_effects _n.wrapping_rem(0); + //~^ arithmetic_side_effects _n.wrapping_rem_euclid(0); + //~^ arithmetic_side_effects _n.saturating_div(_n); + //~^ arithmetic_side_effects _n.wrapping_div(_n); + //~^ arithmetic_side_effects _n.wrapping_rem(_n); + //~^ arithmetic_side_effects _n.wrapping_rem_euclid(_n); + //~^ arithmetic_side_effects _n.saturating_div(*Box::new(_n)); + //~^ arithmetic_side_effects // Unary _n = -_n; + //~^ arithmetic_side_effects _n = -&_n; + //~^ arithmetic_side_effects _custom = -_custom; + //~^ arithmetic_side_effects _custom = -&_custom; + //~^ arithmetic_side_effects _ = -*Box::new(_n); + //~^ arithmetic_side_effects } // Copied and pasted from the `integer_arithmetic` lint for comparison. @@ -426,10 +533,15 @@ pub fn integer_arithmetic() { let mut var2 = -1i32; 1 + i; + //~^ arithmetic_side_effects i * 2; + //~^ arithmetic_side_effects 1 % i / 2; + //~^ arithmetic_side_effects i - 2 + 2 - i; + //~^ arithmetic_side_effects -i; + //~^ arithmetic_side_effects i >> 1; i << 1; @@ -441,18 +553,27 @@ pub fn integer_arithmetic() { i ^ 1; i += 1; + //~^ arithmetic_side_effects i -= 1; + //~^ arithmetic_side_effects i *= 2; + //~^ arithmetic_side_effects i /= 2; i /= 0; + //~^ arithmetic_side_effects i /= -1; i /= var1; + //~^ arithmetic_side_effects i /= var2; + //~^ arithmetic_side_effects i %= 2; i %= 0; + //~^ arithmetic_side_effects i %= -1; i %= var1; + //~^ arithmetic_side_effects i %= var2; + //~^ arithmetic_side_effects i <<= 3; i >>= 2; @@ -463,6 +584,7 @@ pub fn integer_arithmetic() { pub fn issue_10583(a: u16) -> u16 { 10 / a + //~^ arithmetic_side_effects } pub fn issue_10767() { @@ -517,10 +639,12 @@ pub fn issue_11392() { pub fn issue_11393() { fn example_div(x: Wrapping, maybe_zero: Wrapping) -> Wrapping { x / maybe_zero + //~^ arithmetic_side_effects } fn example_rem(x: Wrapping, maybe_zero: Wrapping) -> Wrapping { x % maybe_zero + //~^ arithmetic_side_effects } let [x, maybe_zero] = [1, 0].map(Wrapping); @@ -532,17 +656,21 @@ pub fn issue_12318() { use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign}; let mut one: i32 = 1; one.add_assign(1); + //~^ arithmetic_side_effects one.div_assign(1); one.mul_assign(1); one.rem_assign(1); one.sub_assign(1); + //~^ arithmetic_side_effects } pub fn explicit_methods() { use core::ops::Add; let one: i32 = 1; one.add(&one); + //~^ arithmetic_side_effects Box::new(one).add(one); + //~^ arithmetic_side_effects } fn main() {} diff --git a/tests/ui/arithmetic_side_effects.stderr b/tests/ui/arithmetic_side_effects.stderr index 9b4cfb83fbb2..e15fb612be5e 100644 --- a/tests/ui/arithmetic_side_effects.stderr +++ b/tests/ui/arithmetic_side_effects.stderr @@ -8,763 +8,763 @@ LL | let _ = 1f16 + 1f16; = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]` error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:169:13 + --> tests/ui/arithmetic_side_effects.rs:170:13 | LL | let _ = 1f128 + 1f128; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:173:13 + --> tests/ui/arithmetic_side_effects.rs:175:13 | LL | let _ = String::new() + &String::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:308:5 + --> tests/ui/arithmetic_side_effects.rs:311:5 | LL | _n += 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:309:5 + --> tests/ui/arithmetic_side_effects.rs:313:5 | LL | _n += &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:310:5 + --> tests/ui/arithmetic_side_effects.rs:315:5 | LL | _n -= 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:311:5 + --> tests/ui/arithmetic_side_effects.rs:317:5 | LL | _n -= &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:312:5 + --> tests/ui/arithmetic_side_effects.rs:319:5 | LL | _n /= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:313:5 + --> tests/ui/arithmetic_side_effects.rs:321:5 | LL | _n /= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:314:5 + --> tests/ui/arithmetic_side_effects.rs:323:5 | LL | _n %= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:315:5 + --> tests/ui/arithmetic_side_effects.rs:325:5 | LL | _n %= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:316:5 + --> tests/ui/arithmetic_side_effects.rs:327:5 | LL | _n *= 2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:317:5 + --> tests/ui/arithmetic_side_effects.rs:329:5 | LL | _n *= &2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:318:5 + --> tests/ui/arithmetic_side_effects.rs:331:5 | LL | _n += -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:319:5 + --> tests/ui/arithmetic_side_effects.rs:333:5 | LL | _n += &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:320:5 + --> tests/ui/arithmetic_side_effects.rs:335:5 | LL | _n -= -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:321:5 + --> tests/ui/arithmetic_side_effects.rs:337:5 | LL | _n -= &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:322:5 + --> tests/ui/arithmetic_side_effects.rs:339:5 | LL | _n /= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:323:5 + --> tests/ui/arithmetic_side_effects.rs:341:5 | LL | _n /= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:324:5 + --> tests/ui/arithmetic_side_effects.rs:343:5 | LL | _n %= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:325:5 + --> tests/ui/arithmetic_side_effects.rs:345:5 | LL | _n %= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:326:5 + --> tests/ui/arithmetic_side_effects.rs:347:5 | LL | _n *= -2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:327:5 + --> tests/ui/arithmetic_side_effects.rs:349:5 | LL | _n *= &-2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:328:5 + --> tests/ui/arithmetic_side_effects.rs:351:5 | LL | _custom += Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:329:5 + --> tests/ui/arithmetic_side_effects.rs:353:5 | LL | _custom += &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:330:5 + --> tests/ui/arithmetic_side_effects.rs:355:5 | LL | _custom -= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:331:5 + --> tests/ui/arithmetic_side_effects.rs:357:5 | LL | _custom -= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:332:5 + --> tests/ui/arithmetic_side_effects.rs:359:5 | LL | _custom /= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:333:5 + --> tests/ui/arithmetic_side_effects.rs:361:5 | LL | _custom /= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:334:5 + --> tests/ui/arithmetic_side_effects.rs:363:5 | LL | _custom %= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:335:5 + --> tests/ui/arithmetic_side_effects.rs:365:5 | LL | _custom %= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:336:5 + --> tests/ui/arithmetic_side_effects.rs:367:5 | LL | _custom *= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:337:5 + --> tests/ui/arithmetic_side_effects.rs:369:5 | LL | _custom *= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:338:5 + --> tests/ui/arithmetic_side_effects.rs:371:5 | LL | _custom >>= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:339:5 + --> tests/ui/arithmetic_side_effects.rs:373:5 | LL | _custom >>= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:340:5 + --> tests/ui/arithmetic_side_effects.rs:375:5 | LL | _custom <<= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:341:5 + --> tests/ui/arithmetic_side_effects.rs:377:5 | LL | _custom <<= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:342:5 + --> tests/ui/arithmetic_side_effects.rs:379:5 | LL | _custom += -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:343:5 + --> tests/ui/arithmetic_side_effects.rs:381:5 | LL | _custom += &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:344:5 + --> tests/ui/arithmetic_side_effects.rs:383:5 | LL | _custom -= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:345:5 + --> tests/ui/arithmetic_side_effects.rs:385:5 | LL | _custom -= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:346:5 + --> tests/ui/arithmetic_side_effects.rs:387:5 | LL | _custom /= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:347:5 + --> tests/ui/arithmetic_side_effects.rs:389:5 | LL | _custom /= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:348:5 + --> tests/ui/arithmetic_side_effects.rs:391:5 | LL | _custom %= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:349:5 + --> tests/ui/arithmetic_side_effects.rs:393:5 | LL | _custom %= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:350:5 + --> tests/ui/arithmetic_side_effects.rs:395:5 | LL | _custom *= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:351:5 + --> tests/ui/arithmetic_side_effects.rs:397:5 | LL | _custom *= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:352:5 + --> tests/ui/arithmetic_side_effects.rs:399:5 | LL | _custom >>= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:353:5 + --> tests/ui/arithmetic_side_effects.rs:401:5 | LL | _custom >>= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:354:5 + --> tests/ui/arithmetic_side_effects.rs:403:5 | LL | _custom <<= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:355:5 + --> tests/ui/arithmetic_side_effects.rs:405:5 | LL | _custom <<= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:358:10 + --> tests/ui/arithmetic_side_effects.rs:409:10 | LL | _n = _n + 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:359:10 + --> tests/ui/arithmetic_side_effects.rs:411:10 | LL | _n = _n + &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:360:10 + --> tests/ui/arithmetic_side_effects.rs:413:10 | LL | _n = 1 + _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:361:10 + --> tests/ui/arithmetic_side_effects.rs:415:10 | LL | _n = &1 + _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:362:10 + --> tests/ui/arithmetic_side_effects.rs:417:10 | LL | _n = _n - 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:363:10 + --> tests/ui/arithmetic_side_effects.rs:419:10 | LL | _n = _n - &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:364:10 + --> tests/ui/arithmetic_side_effects.rs:421:10 | LL | _n = 1 - _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:365:10 + --> tests/ui/arithmetic_side_effects.rs:423:10 | LL | _n = &1 - _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:366:10 + --> tests/ui/arithmetic_side_effects.rs:425:10 | LL | _n = _n / 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:367:10 + --> tests/ui/arithmetic_side_effects.rs:427:10 | LL | _n = _n / &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:368:10 + --> tests/ui/arithmetic_side_effects.rs:429:10 | LL | _n = _n % 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:369:10 + --> tests/ui/arithmetic_side_effects.rs:431:10 | LL | _n = _n % &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:370:10 + --> tests/ui/arithmetic_side_effects.rs:433:10 | LL | _n = _n * 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:371:10 + --> tests/ui/arithmetic_side_effects.rs:435:10 | LL | _n = _n * &2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:372:10 + --> tests/ui/arithmetic_side_effects.rs:437:10 | LL | _n = 2 * _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:373:10 + --> tests/ui/arithmetic_side_effects.rs:439:10 | LL | _n = &2 * _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:374:10 + --> tests/ui/arithmetic_side_effects.rs:441:10 | LL | _n = 23 + &85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:375:10 + --> tests/ui/arithmetic_side_effects.rs:443:10 | LL | _n = &23 + 85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:376:10 + --> tests/ui/arithmetic_side_effects.rs:445:10 | LL | _n = &23 + &85; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:377:15 + --> tests/ui/arithmetic_side_effects.rs:447:15 | LL | _custom = _custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:378:15 + --> tests/ui/arithmetic_side_effects.rs:449:15 | LL | _custom = _custom + &_custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:379:15 + --> tests/ui/arithmetic_side_effects.rs:451:15 | LL | _custom = Custom + _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:380:15 + --> tests/ui/arithmetic_side_effects.rs:453:15 | LL | _custom = &Custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:381:15 + --> tests/ui/arithmetic_side_effects.rs:455:15 | LL | _custom = _custom - Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:382:15 + --> tests/ui/arithmetic_side_effects.rs:457:15 | LL | _custom = _custom - &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:383:15 + --> tests/ui/arithmetic_side_effects.rs:459:15 | LL | _custom = Custom - _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:384:15 + --> tests/ui/arithmetic_side_effects.rs:461:15 | LL | _custom = &Custom - _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:385:15 + --> tests/ui/arithmetic_side_effects.rs:463:15 | LL | _custom = _custom / Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:386:15 + --> tests/ui/arithmetic_side_effects.rs:465:15 | LL | _custom = _custom / &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:387:15 + --> tests/ui/arithmetic_side_effects.rs:467:15 | LL | _custom = _custom % Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:388:15 + --> tests/ui/arithmetic_side_effects.rs:469:15 | LL | _custom = _custom % &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:389:15 + --> tests/ui/arithmetic_side_effects.rs:471:15 | LL | _custom = _custom * Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:390:15 + --> tests/ui/arithmetic_side_effects.rs:473:15 | LL | _custom = _custom * &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:391:15 + --> tests/ui/arithmetic_side_effects.rs:475:15 | LL | _custom = Custom * _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:392:15 + --> tests/ui/arithmetic_side_effects.rs:477:15 | LL | _custom = &Custom * _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:393:15 + --> tests/ui/arithmetic_side_effects.rs:479:15 | LL | _custom = Custom + &Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:394:15 + --> tests/ui/arithmetic_side_effects.rs:481:15 | LL | _custom = &Custom + Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:395:15 + --> tests/ui/arithmetic_side_effects.rs:483:15 | LL | _custom = &Custom + &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:396:15 + --> tests/ui/arithmetic_side_effects.rs:485:15 | LL | _custom = _custom >> _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:397:15 + --> tests/ui/arithmetic_side_effects.rs:487:15 | LL | _custom = _custom >> &_custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:398:15 + --> tests/ui/arithmetic_side_effects.rs:489:15 | LL | _custom = Custom << _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:399:15 + --> tests/ui/arithmetic_side_effects.rs:491:15 | LL | _custom = &Custom << _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:402:23 + --> tests/ui/arithmetic_side_effects.rs:495:23 | LL | _n.saturating_div(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:403:21 + --> tests/ui/arithmetic_side_effects.rs:497:21 | LL | _n.wrapping_div(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:404:21 + --> tests/ui/arithmetic_side_effects.rs:499:21 | LL | _n.wrapping_rem(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:405:28 + --> tests/ui/arithmetic_side_effects.rs:501:28 | LL | _n.wrapping_rem_euclid(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:407:23 + --> tests/ui/arithmetic_side_effects.rs:504:23 | LL | _n.saturating_div(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:408:21 + --> tests/ui/arithmetic_side_effects.rs:506:21 | LL | _n.wrapping_div(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:409:21 + --> tests/ui/arithmetic_side_effects.rs:508:21 | LL | _n.wrapping_rem(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:410:28 + --> tests/ui/arithmetic_side_effects.rs:510:28 | LL | _n.wrapping_rem_euclid(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:412:23 + --> tests/ui/arithmetic_side_effects.rs:513:23 | LL | _n.saturating_div(*Box::new(_n)); | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:415:10 + --> tests/ui/arithmetic_side_effects.rs:517:10 | LL | _n = -_n; | ^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:416:10 + --> tests/ui/arithmetic_side_effects.rs:519:10 | LL | _n = -&_n; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:417:15 + --> tests/ui/arithmetic_side_effects.rs:521:15 | LL | _custom = -_custom; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:418:15 + --> tests/ui/arithmetic_side_effects.rs:523:15 | LL | _custom = -&_custom; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:419:9 + --> tests/ui/arithmetic_side_effects.rs:525:9 | LL | _ = -*Box::new(_n); | ^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:428:5 + --> tests/ui/arithmetic_side_effects.rs:535:5 | LL | 1 + i; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:429:5 + --> tests/ui/arithmetic_side_effects.rs:537:5 | LL | i * 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:430:5 + --> tests/ui/arithmetic_side_effects.rs:539:5 | LL | 1 % i / 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:431:5 + --> tests/ui/arithmetic_side_effects.rs:541:5 | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:432:5 + --> tests/ui/arithmetic_side_effects.rs:543:5 | LL | -i; | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:443:5 + --> tests/ui/arithmetic_side_effects.rs:555:5 | LL | i += 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:444:5 + --> tests/ui/arithmetic_side_effects.rs:557:5 | LL | i -= 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:445:5 + --> tests/ui/arithmetic_side_effects.rs:559:5 | LL | i *= 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:447:5 + --> tests/ui/arithmetic_side_effects.rs:562:5 | LL | i /= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:449:5 + --> tests/ui/arithmetic_side_effects.rs:565:5 | LL | i /= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:450:5 + --> tests/ui/arithmetic_side_effects.rs:567:5 | LL | i /= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:452:5 + --> tests/ui/arithmetic_side_effects.rs:570:5 | LL | i %= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:454:5 + --> tests/ui/arithmetic_side_effects.rs:573:5 | LL | i %= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:455:5 + --> tests/ui/arithmetic_side_effects.rs:575:5 | LL | i %= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:465:5 + --> tests/ui/arithmetic_side_effects.rs:586:5 | LL | 10 / a | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:519:9 + --> tests/ui/arithmetic_side_effects.rs:641:9 | LL | x / maybe_zero | ^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:523:9 + --> tests/ui/arithmetic_side_effects.rs:646:9 | LL | x % maybe_zero | ^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:534:5 + --> tests/ui/arithmetic_side_effects.rs:658:5 | LL | one.add_assign(1); | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:538:5 + --> tests/ui/arithmetic_side_effects.rs:663:5 | LL | one.sub_assign(1); | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:544:5 + --> tests/ui/arithmetic_side_effects.rs:670:5 | LL | one.add(&one); | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:545:5 + --> tests/ui/arithmetic_side_effects.rs:672:5 | LL | Box::new(one).add(one); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/as_conversions.rs b/tests/ui/as_conversions.rs index 8499c0ac5a0f..fba8913a2097 100644 --- a/tests/ui/as_conversions.rs +++ b/tests/ui/as_conversions.rs @@ -7,9 +7,11 @@ extern crate proc_macros; use proc_macros::{external, with_span}; fn main() { - let i = 0u32 as u64; + let i = 0u32 as u64; //~ as_conversions let j = &i as *const u64 as *mut u64; + //~^ as_conversions + //~| as_conversions external!(0u32 as u64); } diff --git a/tests/ui/as_pointer_underscore.fixed b/tests/ui/as_pointer_underscore.fixed index db06486ecb04..374c8a7f611a 100644 --- a/tests/ui/as_pointer_underscore.fixed +++ b/tests/ui/as_pointer_underscore.fixed @@ -6,10 +6,12 @@ struct S; fn f(s: &S) -> usize { &s as *const &S as usize - //~^ ERROR: using inferred pointer cast + //~^ as_pointer_underscore + } fn g(s: &mut S) -> usize { s as *mut S as usize - //~^ ERROR: using inferred pointer cast + //~^ as_pointer_underscore + } diff --git a/tests/ui/as_pointer_underscore.rs b/tests/ui/as_pointer_underscore.rs index 955c702ccc99..b194b3f473e2 100644 --- a/tests/ui/as_pointer_underscore.rs +++ b/tests/ui/as_pointer_underscore.rs @@ -6,10 +6,12 @@ struct S; fn f(s: &S) -> usize { &s as *const _ as usize - //~^ ERROR: using inferred pointer cast + //~^ as_pointer_underscore + } fn g(s: &mut S) -> usize { s as *mut _ as usize - //~^ ERROR: using inferred pointer cast + //~^ as_pointer_underscore + } diff --git a/tests/ui/as_pointer_underscore.stderr b/tests/ui/as_pointer_underscore.stderr index 270056f36454..fd9f061322b5 100644 --- a/tests/ui/as_pointer_underscore.stderr +++ b/tests/ui/as_pointer_underscore.stderr @@ -8,7 +8,7 @@ LL | &s as *const _ as usize = help: to override `-D warnings` add `#[allow(clippy::as_pointer_underscore)]` error: using inferred pointer cast - --> tests/ui/as_pointer_underscore.rs:13:10 + --> tests/ui/as_pointer_underscore.rs:14:10 | LL | s as *mut _ as usize | ^^^^^^ help: use explicit type: `*mut S` diff --git a/tests/ui/as_ptr_cast_mut.rs b/tests/ui/as_ptr_cast_mut.rs index 9e862320f4ef..751e4a70b0fa 100644 --- a/tests/ui/as_ptr_cast_mut.rs +++ b/tests/ui/as_ptr_cast_mut.rs @@ -20,10 +20,12 @@ impl Covariant { fn main() { let mut string = String::new(); let _ = string.as_ptr() as *mut u8; - //~^ ERROR: casting the result of `as_ptr` to *mut u8 - //~| NOTE: `-D clippy::as-ptr-cast-mut` implied by `-D warnings` + //~^ as_ptr_cast_mut + + let _: *mut i8 = string.as_ptr() as *mut _; - //~^ ERROR: casting the result of `as_ptr` to *mut i8 + //~^ as_ptr_cast_mut + let _ = string.as_ptr() as *const i8; let _ = string.as_mut_ptr(); let _ = string.as_mut_ptr() as *mut u8; diff --git a/tests/ui/as_ptr_cast_mut.stderr b/tests/ui/as_ptr_cast_mut.stderr index b3fc223ccdba..67dd7ddb8291 100644 --- a/tests/ui/as_ptr_cast_mut.stderr +++ b/tests/ui/as_ptr_cast_mut.stderr @@ -8,7 +8,7 @@ LL | let _ = string.as_ptr() as *mut u8; = help: to override `-D warnings` add `#[allow(clippy::as_ptr_cast_mut)]` error: casting the result of `as_ptr` to *mut i8 - --> tests/ui/as_ptr_cast_mut.rs:25:22 + --> tests/ui/as_ptr_cast_mut.rs:26:22 | LL | let _: *mut i8 = string.as_ptr() as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `string.as_mut_ptr()` diff --git a/tests/ui/as_underscore.fixed b/tests/ui/as_underscore.fixed index c7f26e64cce7..ca2a7f043286 100644 --- a/tests/ui/as_underscore.fixed +++ b/tests/ui/as_underscore.fixed @@ -5,7 +5,9 @@ fn foo(_n: usize) {} fn main() { let n: u16 = 256; foo(n as usize); + //~^ as_underscore let n = 0_u128; let _n: u8 = n as u8; + //~^ as_underscore } diff --git a/tests/ui/as_underscore.rs b/tests/ui/as_underscore.rs index 70f3b386631c..df500c4c4df1 100644 --- a/tests/ui/as_underscore.rs +++ b/tests/ui/as_underscore.rs @@ -5,7 +5,9 @@ fn foo(_n: usize) {} fn main() { let n: u16 = 256; foo(n as _); + //~^ as_underscore let n = 0_u128; let _n: u8 = n as _; + //~^ as_underscore } diff --git a/tests/ui/as_underscore.stderr b/tests/ui/as_underscore.stderr index dba56a2a8af3..02c10feb78eb 100644 --- a/tests/ui/as_underscore.stderr +++ b/tests/ui/as_underscore.stderr @@ -10,7 +10,7 @@ LL | foo(n as _); = help: to override `-D warnings` add `#[allow(clippy::as_underscore)]` error: using `as _` conversion - --> tests/ui/as_underscore.rs:10:18 + --> tests/ui/as_underscore.rs:11:18 | LL | let _n: u8 = n as _; | ^^^^^- diff --git a/tests/ui/asm_syntax_not_x86.rs b/tests/ui/asm_syntax_not_x86.rs index a7d29cc239e5..91fde12680cc 100644 --- a/tests/ui/asm_syntax_not_x86.rs +++ b/tests/ui/asm_syntax_not_x86.rs @@ -8,12 +8,17 @@ mod dont_warn { pub(super) unsafe fn use_asm() { asm!(""); + //~^ inline_asm_x86_intel_syntax asm!("", options()); + //~^ inline_asm_x86_intel_syntax asm!("", options(nostack)); + //~^ inline_asm_x86_intel_syntax } global_asm!(""); + //~^ inline_asm_x86_intel_syntax global_asm!("", options()); + //~^ inline_asm_x86_intel_syntax } fn main() { diff --git a/tests/ui/asm_syntax_x86.rs b/tests/ui/asm_syntax_x86.rs index 5ceaceb7527b..0d30b95dcf5e 100644 --- a/tests/ui/asm_syntax_x86.rs +++ b/tests/ui/asm_syntax_x86.rs @@ -6,19 +6,24 @@ mod warn_intel { pub(super) unsafe fn use_asm() { asm!(""); - //~^ ERROR: Intel x86 assembly syntax used + //~^ inline_asm_x86_intel_syntax + asm!("", options()); - //~^ ERROR: Intel x86 assembly syntax used + //~^ inline_asm_x86_intel_syntax + asm!("", options(nostack)); - //~^ ERROR: Intel x86 assembly syntax used + //~^ inline_asm_x86_intel_syntax + asm!("", options(att_syntax)); asm!("", options(nostack, att_syntax)); } global_asm!(""); - //~^ ERROR: Intel x86 assembly syntax used + //~^ inline_asm_x86_intel_syntax + global_asm!("", options()); - //~^ ERROR: Intel x86 assembly syntax used + //~^ inline_asm_x86_intel_syntax + global_asm!("", options(att_syntax)); } @@ -31,15 +36,18 @@ mod warn_att { asm!("", options()); asm!("", options(nostack)); asm!("", options(att_syntax)); - //~^ ERROR: AT&T x86 assembly syntax used + //~^ inline_asm_x86_att_syntax + asm!("", options(nostack, att_syntax)); - //~^ ERROR: AT&T x86 assembly syntax used + //~^ inline_asm_x86_att_syntax + } global_asm!(""); global_asm!("", options()); global_asm!("", options(att_syntax)); - //~^ ERROR: AT&T x86 assembly syntax used + //~^ inline_asm_x86_att_syntax + } fn main() { diff --git a/tests/ui/asm_syntax_x86.stderr b/tests/ui/asm_syntax_x86.stderr index 1911ef66e239..8e1992b66bca 100644 --- a/tests/ui/asm_syntax_x86.stderr +++ b/tests/ui/asm_syntax_x86.stderr @@ -9,7 +9,7 @@ LL | asm!(""); = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_intel_syntax)]` error: Intel x86 assembly syntax used - --> tests/ui/asm_syntax_x86.rs:10:9 + --> tests/ui/asm_syntax_x86.rs:11:9 | LL | asm!("", options()); | ^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | asm!("", options()); = help: use AT&T x86 assembly syntax error: Intel x86 assembly syntax used - --> tests/ui/asm_syntax_x86.rs:12:9 + --> tests/ui/asm_syntax_x86.rs:14:9 | LL | asm!("", options(nostack)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | asm!("", options(nostack)); = help: use AT&T x86 assembly syntax error: Intel x86 assembly syntax used - --> tests/ui/asm_syntax_x86.rs:18:5 + --> tests/ui/asm_syntax_x86.rs:21:5 | LL | global_asm!(""); | ^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | global_asm!(""); = help: use AT&T x86 assembly syntax error: Intel x86 assembly syntax used - --> tests/ui/asm_syntax_x86.rs:20:5 + --> tests/ui/asm_syntax_x86.rs:24:5 | LL | global_asm!("", options()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | global_asm!("", options()); = help: use AT&T x86 assembly syntax error: AT&T x86 assembly syntax used - --> tests/ui/asm_syntax_x86.rs:33:9 + --> tests/ui/asm_syntax_x86.rs:38:9 | LL | asm!("", options(att_syntax)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | asm!("", options(att_syntax)); = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_att_syntax)]` error: AT&T x86 assembly syntax used - --> tests/ui/asm_syntax_x86.rs:35:9 + --> tests/ui/asm_syntax_x86.rs:41:9 | LL | asm!("", options(nostack, att_syntax)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | asm!("", options(nostack, att_syntax)); = help: use Intel x86 assembly syntax error: AT&T x86 assembly syntax used - --> tests/ui/asm_syntax_x86.rs:41:5 + --> tests/ui/asm_syntax_x86.rs:48:5 | LL | global_asm!("", options(att_syntax)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/assertions_on_constants.rs b/tests/ui/assertions_on_constants.rs index 957154e60dec..96b9c16d4303 100644 --- a/tests/ui/assertions_on_constants.rs +++ b/tests/ui/assertions_on_constants.rs @@ -8,30 +8,39 @@ macro_rules! assert_const { } fn main() { assert!(true); - //~^ ERROR: `assert!(true)` will be optimized out by the compiler + //~^ assertions_on_constants + assert!(false); - //~^ ERROR: `assert!(false)` should probably be replaced + //~^ assertions_on_constants + assert!(true, "true message"); - //~^ ERROR: `assert!(true)` will be optimized out by the compiler + //~^ assertions_on_constants + assert!(false, "false message"); - //~^ ERROR: `assert!(false, ..)` should probably be replaced + //~^ assertions_on_constants + let msg = "panic message"; assert!(false, "{}", msg.to_uppercase()); - //~^ ERROR: `assert!(false, ..)` should probably be replaced + //~^ assertions_on_constants + const B: bool = true; assert!(B); - //~^ ERROR: `assert!(true)` will be optimized out by the compiler + //~^ assertions_on_constants + const C: bool = false; assert!(C); - //~^ ERROR: `assert!(false)` should probably be replaced + //~^ assertions_on_constants + assert!(C, "C message"); - //~^ ERROR: `assert!(false, ..)` should probably be replaced + //~^ assertions_on_constants + debug_assert!(true); - //~^ ERROR: `debug_assert!(true)` will be optimized out by the compiler + //~^ assertions_on_constants + // Don't lint this, since there is no better way for expressing "Only panic in debug mode". debug_assert!(false); // #3948 assert_const!(3); @@ -47,10 +56,12 @@ fn main() { assert!(!CFG_FLAG); const _: () = assert!(true); - //~^ ERROR: `assert!(true)` will be optimized out by the compiler + //~^ assertions_on_constants + assert!(8 == (7 + 1)); - //~^ ERROR: `assert!(true)` will be optimized out by the compiler + //~^ assertions_on_constants + // Don't lint if the value is dependent on a defined constant: const N: usize = 1024; @@ -59,6 +70,7 @@ fn main() { const _: () = { assert!(true); - //~^ ERROR: `assert!(true)` will be optimized out by the compiler + //~^ assertions_on_constants + assert!(8 == (7 + 1)); }; diff --git a/tests/ui/assertions_on_constants.stderr b/tests/ui/assertions_on_constants.stderr index e164a999c43e..b0e6496982f9 100644 --- a/tests/ui/assertions_on_constants.stderr +++ b/tests/ui/assertions_on_constants.stderr @@ -9,7 +9,7 @@ LL | assert!(true); = help: to override `-D warnings` add `#[allow(clippy::assertions_on_constants)]` error: `assert!(false)` should probably be replaced - --> tests/ui/assertions_on_constants.rs:12:5 + --> tests/ui/assertions_on_constants.rs:13:5 | LL | assert!(false); | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | assert!(false); = help: use `panic!()` or `unreachable!()` error: `assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:14:5 + --> tests/ui/assertions_on_constants.rs:16:5 | LL | assert!(true, "true message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | assert!(true, "true message"); = help: remove it error: `assert!(false, ..)` should probably be replaced - --> tests/ui/assertions_on_constants.rs:16:5 + --> tests/ui/assertions_on_constants.rs:19:5 | LL | assert!(false, "false message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | assert!(false, "false message"); = help: use `panic!(..)` or `unreachable!(..)` error: `assert!(false, ..)` should probably be replaced - --> tests/ui/assertions_on_constants.rs:20:5 + --> tests/ui/assertions_on_constants.rs:24:5 | LL | assert!(false, "{}", msg.to_uppercase()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | assert!(false, "{}", msg.to_uppercase()); = help: use `panic!(..)` or `unreachable!(..)` error: `assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:24:5 + --> tests/ui/assertions_on_constants.rs:29:5 | LL | assert!(B); | ^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | assert!(B); = help: remove it error: `assert!(false)` should probably be replaced - --> tests/ui/assertions_on_constants.rs:28:5 + --> tests/ui/assertions_on_constants.rs:34:5 | LL | assert!(C); | ^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | assert!(C); = help: use `panic!()` or `unreachable!()` error: `assert!(false, ..)` should probably be replaced - --> tests/ui/assertions_on_constants.rs:30:5 + --> tests/ui/assertions_on_constants.rs:37:5 | LL | assert!(C, "C message"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | assert!(C, "C message"); = help: use `panic!(..)` or `unreachable!(..)` error: `debug_assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:33:5 + --> tests/ui/assertions_on_constants.rs:41:5 | LL | debug_assert!(true); | ^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | debug_assert!(true); = help: remove it error: `assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:49:19 + --> tests/ui/assertions_on_constants.rs:58:19 | LL | const _: () = assert!(true); | ^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | const _: () = assert!(true); = help: remove it error: `assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:52:5 + --> tests/ui/assertions_on_constants.rs:62:5 | LL | assert!(8 == (7 + 1)); | ^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | assert!(8 == (7 + 1)); = help: remove it error: `assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:61:5 + --> tests/ui/assertions_on_constants.rs:72:5 | LL | assert!(true); | ^^^^^^^^^^^^^ diff --git a/tests/ui/assertions_on_result_states.fixed b/tests/ui/assertions_on_result_states.fixed index 14d9b8b99d5e..09c1a8d0ed1d 100644 --- a/tests/ui/assertions_on_result_states.fixed +++ b/tests/ui/assertions_on_result_states.fixed @@ -22,6 +22,7 @@ fn main() { let r: Result = Ok(Foo); debug_assert!(r.is_ok()); r.unwrap(); + //~^ assertions_on_result_states // test ok with non-debug error type let r: Result = Ok(Foo); @@ -40,9 +41,11 @@ fn main() { Ok(Foo) } get_ok().unwrap(); + //~^ assertions_on_result_states // test macro ok get_ok_macro!().unwrap(); + //~^ assertions_on_result_states // test ok that shouldn't be moved let r: Result = Ok(CopyFoo); @@ -56,12 +59,14 @@ fn main() { // test ok that is copied let r: Result = Ok(CopyFoo); r.unwrap(); + //~^ assertions_on_result_states r.unwrap(); // test reference to ok let r: Result = Ok(CopyFoo); fn test_ref_copy_ok(r: &Result) { r.unwrap(); + //~^ assertions_on_result_states } test_ref_copy_ok(&r); r.unwrap(); @@ -70,6 +75,7 @@ fn main() { let r: Result = Err(Foo); debug_assert!(r.is_err()); r.unwrap_err(); + //~^ assertions_on_result_states // test err with non-debug value type let r: Result = Err(Foo); @@ -80,4 +86,5 @@ fn main() { fn issue9450() { let res: Result = Ok(1); res.unwrap_err(); + //~^ assertions_on_result_states } diff --git a/tests/ui/assertions_on_result_states.rs b/tests/ui/assertions_on_result_states.rs index ac1911d87c93..c63c2502b537 100644 --- a/tests/ui/assertions_on_result_states.rs +++ b/tests/ui/assertions_on_result_states.rs @@ -22,6 +22,7 @@ fn main() { let r: Result = Ok(Foo); debug_assert!(r.is_ok()); assert!(r.is_ok()); + //~^ assertions_on_result_states // test ok with non-debug error type let r: Result = Ok(Foo); @@ -40,9 +41,11 @@ fn main() { Ok(Foo) } assert!(get_ok().is_ok()); + //~^ assertions_on_result_states // test macro ok assert!(get_ok_macro!().is_ok()); + //~^ assertions_on_result_states // test ok that shouldn't be moved let r: Result = Ok(CopyFoo); @@ -56,12 +59,14 @@ fn main() { // test ok that is copied let r: Result = Ok(CopyFoo); assert!(r.is_ok()); + //~^ assertions_on_result_states r.unwrap(); // test reference to ok let r: Result = Ok(CopyFoo); fn test_ref_copy_ok(r: &Result) { assert!(r.is_ok()); + //~^ assertions_on_result_states } test_ref_copy_ok(&r); r.unwrap(); @@ -70,6 +75,7 @@ fn main() { let r: Result = Err(Foo); debug_assert!(r.is_err()); assert!(r.is_err()); + //~^ assertions_on_result_states // test err with non-debug value type let r: Result = Err(Foo); @@ -80,4 +86,5 @@ fn main() { fn issue9450() { let res: Result = Ok(1); assert!(res.is_err()) + //~^ assertions_on_result_states } diff --git a/tests/ui/assertions_on_result_states.stderr b/tests/ui/assertions_on_result_states.stderr index a2bddc7025a9..3bf811588c69 100644 --- a/tests/ui/assertions_on_result_states.stderr +++ b/tests/ui/assertions_on_result_states.stderr @@ -8,37 +8,37 @@ LL | assert!(r.is_ok()); = help: to override `-D warnings` add `#[allow(clippy::assertions_on_result_states)]` error: called `assert!` with `Result::is_ok` - --> tests/ui/assertions_on_result_states.rs:42:5 + --> tests/ui/assertions_on_result_states.rs:43:5 | LL | assert!(get_ok().is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok().unwrap()` error: called `assert!` with `Result::is_ok` - --> tests/ui/assertions_on_result_states.rs:45:5 + --> tests/ui/assertions_on_result_states.rs:47:5 | LL | assert!(get_ok_macro!().is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok_macro!().unwrap()` error: called `assert!` with `Result::is_ok` - --> tests/ui/assertions_on_result_states.rs:58:5 + --> tests/ui/assertions_on_result_states.rs:61:5 | LL | assert!(r.is_ok()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()` error: called `assert!` with `Result::is_ok` - --> tests/ui/assertions_on_result_states.rs:64:9 + --> tests/ui/assertions_on_result_states.rs:68:9 | LL | assert!(r.is_ok()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()` error: called `assert!` with `Result::is_err` - --> tests/ui/assertions_on_result_states.rs:72:5 + --> tests/ui/assertions_on_result_states.rs:77:5 | LL | assert!(r.is_err()); | ^^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap_err()` error: called `assert!` with `Result::is_err` - --> tests/ui/assertions_on_result_states.rs:82:5 + --> tests/ui/assertions_on_result_states.rs:88:5 | LL | assert!(res.is_err()) | ^^^^^^^^^^^^^^^^^^^^^ help: replace with: `res.unwrap_err();` diff --git a/tests/ui/assign_ops.fixed b/tests/ui/assign_ops.fixed index 2bd0807f4262..18f0e04a8807 100644 --- a/tests/ui/assign_ops.fixed +++ b/tests/ui/assign_ops.fixed @@ -5,25 +5,36 @@ use core::num::Wrapping; fn main() { let mut a = 5; a += 1; + //~^ assign_op_pattern a += 1; + //~^ assign_op_pattern a -= 1; + //~^ assign_op_pattern a *= 99; + //~^ assign_op_pattern a *= 42; + //~^ assign_op_pattern a /= 2; + //~^ assign_op_pattern a %= 5; + //~^ assign_op_pattern a &= 1; + //~^ assign_op_pattern a = 1 - a; a = 5 / a; a = 42 % a; a = 6 << a; let mut s = String::new(); s += "bla"; + //~^ assign_op_pattern // Issue #9180 let mut a = Wrapping(0u32); a += Wrapping(1u32); + //~^ assign_op_pattern let mut v = vec![0u32, 1u32]; v[0] += v[1]; + //~^ assign_op_pattern let mut v = vec![Wrapping(0u32), Wrapping(1u32)]; v[0] = v[0] + v[1]; let _ = || v[0] = v[0] + v[1]; diff --git a/tests/ui/assign_ops.rs b/tests/ui/assign_ops.rs index be3491a44c7e..8b05c74d8604 100644 --- a/tests/ui/assign_ops.rs +++ b/tests/ui/assign_ops.rs @@ -5,25 +5,36 @@ use core::num::Wrapping; fn main() { let mut a = 5; a = a + 1; + //~^ assign_op_pattern a = 1 + a; + //~^ assign_op_pattern a = a - 1; + //~^ assign_op_pattern a = a * 99; + //~^ assign_op_pattern a = 42 * a; + //~^ assign_op_pattern a = a / 2; + //~^ assign_op_pattern a = a % 5; + //~^ assign_op_pattern a = a & 1; + //~^ assign_op_pattern a = 1 - a; a = 5 / a; a = 42 % a; a = 6 << a; let mut s = String::new(); s = s + "bla"; + //~^ assign_op_pattern // Issue #9180 let mut a = Wrapping(0u32); a = a + Wrapping(1u32); + //~^ assign_op_pattern let mut v = vec![0u32, 1u32]; v[0] = v[0] + v[1]; + //~^ assign_op_pattern let mut v = vec![Wrapping(0u32), Wrapping(1u32)]; v[0] = v[0] + v[1]; let _ = || v[0] = v[0] + v[1]; diff --git a/tests/ui/assign_ops.stderr b/tests/ui/assign_ops.stderr index 4975ac5911fd..17f216ee4a07 100644 --- a/tests/ui/assign_ops.stderr +++ b/tests/ui/assign_ops.stderr @@ -8,61 +8,61 @@ LL | a = a + 1; = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:8:5 + --> tests/ui/assign_ops.rs:9:5 | LL | a = 1 + a; | ^^^^^^^^^ help: replace it with: `a += 1` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:9:5 + --> tests/ui/assign_ops.rs:11:5 | LL | a = a - 1; | ^^^^^^^^^ help: replace it with: `a -= 1` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:10:5 + --> tests/ui/assign_ops.rs:13:5 | LL | a = a * 99; | ^^^^^^^^^^ help: replace it with: `a *= 99` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:11:5 + --> tests/ui/assign_ops.rs:15:5 | LL | a = 42 * a; | ^^^^^^^^^^ help: replace it with: `a *= 42` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:12:5 + --> tests/ui/assign_ops.rs:17:5 | LL | a = a / 2; | ^^^^^^^^^ help: replace it with: `a /= 2` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:13:5 + --> tests/ui/assign_ops.rs:19:5 | LL | a = a % 5; | ^^^^^^^^^ help: replace it with: `a %= 5` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:14:5 + --> tests/ui/assign_ops.rs:21:5 | LL | a = a & 1; | ^^^^^^^^^ help: replace it with: `a &= 1` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:20:5 + --> tests/ui/assign_ops.rs:28:5 | LL | s = s + "bla"; | ^^^^^^^^^^^^^ help: replace it with: `s += "bla"` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:24:5 + --> tests/ui/assign_ops.rs:33:5 | LL | a = a + Wrapping(1u32); | ^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a += Wrapping(1u32)` error: manual implementation of an assign operation - --> tests/ui/assign_ops.rs:26:5 + --> tests/ui/assign_ops.rs:36:5 | LL | v[0] = v[0] + v[1]; | ^^^^^^^^^^^^^^^^^^ help: replace it with: `v[0] += v[1]` diff --git a/tests/ui/assign_ops2.rs b/tests/ui/assign_ops2.rs index a53556425849..7cac9f51ea4e 100644 --- a/tests/ui/assign_ops2.rs +++ b/tests/ui/assign_ops2.rs @@ -6,24 +6,33 @@ fn main() { let mut a = 5; a += a + 1; - //~^ ERROR: variable appears on both sides of an assignment operation - //~| NOTE: `-D clippy::misrefactored-assign-op` implied by `-D warnings` + //~^ misrefactored_assign_op + + a += 1 + a; - //~^ ERROR: variable appears on both sides of an assignment operation + //~^ misrefactored_assign_op + a -= a - 1; - //~^ ERROR: variable appears on both sides of an assignment operation + //~^ misrefactored_assign_op + a *= a * 99; - //~^ ERROR: variable appears on both sides of an assignment operation + //~^ misrefactored_assign_op + a *= 42 * a; - //~^ ERROR: variable appears on both sides of an assignment operation + //~^ misrefactored_assign_op + a /= a / 2; - //~^ ERROR: variable appears on both sides of an assignment operation + //~^ misrefactored_assign_op + a %= a % 5; - //~^ ERROR: variable appears on both sides of an assignment operation + //~^ misrefactored_assign_op + a &= a & 1; - //~^ ERROR: variable appears on both sides of an assignment operation + //~^ misrefactored_assign_op + a *= a * a; - //~^ ERROR: variable appears on both sides of an assignment operation + //~^ misrefactored_assign_op + a = a * a * a; a = a * 42 * a; a = a * 2 + a; @@ -61,8 +70,9 @@ fn cow_add_assign() { // this can be linted buf = buf + cows.clone(); - //~^ ERROR: manual implementation of an assign operation - //~| NOTE: `-D clippy::assign-op-pattern` implied by `-D warnings` + //~^ assign_op_pattern + + // this should not as cow Add is not commutative buf = cows + buf; diff --git a/tests/ui/assign_ops2.stderr b/tests/ui/assign_ops2.stderr index ddeba2b2ff8f..56b5219dd646 100644 --- a/tests/ui/assign_ops2.stderr +++ b/tests/ui/assign_ops2.stderr @@ -16,7 +16,7 @@ LL | a = a + a + 1; | ~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:11:5 + --> tests/ui/assign_ops2.rs:12:5 | LL | a += 1 + a; | ^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | a = a + 1 + a; | ~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:13:5 + --> tests/ui/assign_ops2.rs:15:5 | LL | a -= a - 1; | ^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | a = a - (a - 1); | ~~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:15:5 + --> tests/ui/assign_ops2.rs:18:5 | LL | a *= a * 99; | ^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | a = a * a * 99; | ~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:17:5 + --> tests/ui/assign_ops2.rs:21:5 | LL | a *= 42 * a; | ^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | a = a * 42 * a; | ~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:19:5 + --> tests/ui/assign_ops2.rs:24:5 | LL | a /= a / 2; | ^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | a = a / (a / 2); | ~~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:21:5 + --> tests/ui/assign_ops2.rs:27:5 | LL | a %= a % 5; | ^^^^^^^^^^ @@ -106,7 +106,7 @@ LL | a = a % (a % 5); | ~~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:23:5 + --> tests/ui/assign_ops2.rs:30:5 | LL | a &= a & 1; | ^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | a = a & a & 1; | ~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:25:5 + --> tests/ui/assign_ops2.rs:33:5 | LL | a *= a * a; | ^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | a = a * a * a; | ~~~~~~~~~~~~~ error: manual implementation of an assign operation - --> tests/ui/assign_ops2.rs:63:5 + --> tests/ui/assign_ops2.rs:72:5 | LL | buf = buf + cows.clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `buf += cows.clone()` diff --git a/tests/ui/assigning_clones.fixed b/tests/ui/assigning_clones.fixed index 09732d1a50ce..9e44008e6fab 100644 --- a/tests/ui/assigning_clones.fixed +++ b/tests/ui/assigning_clones.fixed @@ -23,60 +23,73 @@ impl Clone for HasCloneFrom { fn clone_method_rhs_val(mut_thing: &mut HasCloneFrom, value_thing: HasCloneFrom) { mut_thing.clone_from(&value_thing); + //~^ assigning_clones } fn clone_method_rhs_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { mut_thing.clone_from(ref_thing); + //~^ assigning_clones } fn clone_method_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) { mut_thing.clone_from(ref_thing); + //~^ assigning_clones } fn clone_function_lhs_mut_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { Clone::clone_from(mut_thing, ref_thing); + //~^ assigning_clones } fn clone_function_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) { Clone::clone_from(&mut mut_thing, ref_thing); + //~^ assigning_clones } fn clone_function_through_trait(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { Clone::clone_from(mut_thing, ref_thing); + //~^ assigning_clones } fn clone_function_through_type(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { Clone::clone_from(mut_thing, ref_thing); + //~^ assigning_clones } fn clone_function_fully_qualified(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { Clone::clone_from(mut_thing, ref_thing); + //~^ assigning_clones } fn clone_method_lhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { // These parens should be kept as necessary for a receiver (mut_thing + &mut HasCloneFrom).clone_from(ref_thing); + //~^ assigning_clones } fn clone_method_rhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { // These parens should be removed since they are not needed in a function argument mut_thing.clone_from(ref_thing + ref_thing); + //~^ assigning_clones } fn clone_method_macro() { let mut s = String::from(""); s.clone_from(&format!("{} {}", "hello", "world")); + //~^ assigning_clones } fn clone_function_macro() { let mut s = String::from(""); Clone::clone_from(&mut s, &format!("{} {}", "hello", "world")); + //~^ assigning_clones } fn assign_to_init_mut_var(b: HasCloneFrom) -> HasCloneFrom { let mut a = HasCloneFrom; for _ in 1..10 { a.clone_from(&b); + //~^ assigning_clones } a } @@ -148,6 +161,7 @@ fn ignore_generic_clone(a: &mut T, b: &T) { #[clippy::msrv = "1.62"] fn msrv_1_62(mut a: String, b: String, c: &str) { a.clone_from(&b); + //~^ assigning_clones // Should not be linted, as clone_into wasn't stabilized until 1.63 a = c.to_owned(); } @@ -155,7 +169,9 @@ fn msrv_1_62(mut a: String, b: String, c: &str) { #[clippy::msrv = "1.63"] fn msrv_1_63(mut a: String, b: String, c: &str) { a.clone_from(&b); + //~^ assigning_clones c.clone_into(&mut a); + //~^ assigning_clones } macro_rules! clone_inside { @@ -186,35 +202,43 @@ impl Clone for AvoidRecursiveCloneFrom { // Deref handling fn clone_into_deref_method(mut a: DerefWrapper, b: HasCloneFrom) { (*a).clone_from(&b); + //~^ assigning_clones } fn clone_into_deref_with_clone_method(mut a: DerefWrapperWithClone, b: HasCloneFrom) { (*a).clone_from(&b); + //~^ assigning_clones } fn clone_into_box_method(mut a: Box, b: HasCloneFrom) { (*a).clone_from(&b); + //~^ assigning_clones } fn clone_into_self_deref_method(a: &mut DerefWrapperWithClone, b: DerefWrapperWithClone) { a.clone_from(&b); + //~^ assigning_clones } fn clone_into_deref_function(mut a: DerefWrapper, b: HasCloneFrom) { Clone::clone_from(&mut *a, &b); + //~^ assigning_clones } fn clone_into_box_function(mut a: Box, b: HasCloneFrom) { Clone::clone_from(&mut *a, &b); + //~^ assigning_clones } // ToOwned fn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) { ref_str.clone_into(mut_string); + //~^ assigning_clones } fn owned_method_val(mut mut_string: String, ref_str: &str) { ref_str.clone_into(&mut mut_string); + //~^ assigning_clones } struct HasDeref { @@ -236,28 +260,34 @@ impl DerefMut for HasDeref { fn owned_method_box(mut_box_string: &mut Box, ref_str: &str) { ref_str.clone_into(&mut (*mut_box_string)); + //~^ assigning_clones } fn owned_method_deref(mut_box_string: &mut HasDeref, ref_str: &str) { ref_str.clone_into(&mut (*mut_box_string)); + //~^ assigning_clones } fn owned_function_mut_ref(mut_thing: &mut String, ref_str: &str) { ToOwned::clone_into(ref_str, mut_thing); + //~^ assigning_clones } fn owned_function_val(mut mut_thing: String, ref_str: &str) { ToOwned::clone_into(ref_str, &mut mut_thing); + //~^ assigning_clones } fn owned_method_macro() { let mut s = String::from(""); format!("{} {}", "hello", "world").clone_into(&mut s); + //~^ assigning_clones } fn owned_function_macro() { let mut s = String::from(""); ToOwned::clone_into(&format!("{} {}", "hello", "world"), &mut s); + //~^ assigning_clones } struct FakeToOwned; diff --git a/tests/ui/assigning_clones.rs b/tests/ui/assigning_clones.rs index 6be25ae17a55..8ae8abfed367 100644 --- a/tests/ui/assigning_clones.rs +++ b/tests/ui/assigning_clones.rs @@ -23,60 +23,73 @@ impl Clone for HasCloneFrom { fn clone_method_rhs_val(mut_thing: &mut HasCloneFrom, value_thing: HasCloneFrom) { *mut_thing = value_thing.clone(); + //~^ assigning_clones } fn clone_method_rhs_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { *mut_thing = ref_thing.clone(); + //~^ assigning_clones } fn clone_method_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) { mut_thing = ref_thing.clone(); + //~^ assigning_clones } fn clone_function_lhs_mut_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { *mut_thing = Clone::clone(ref_thing); + //~^ assigning_clones } fn clone_function_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) { mut_thing = Clone::clone(ref_thing); + //~^ assigning_clones } fn clone_function_through_trait(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { *mut_thing = Clone::clone(ref_thing); + //~^ assigning_clones } fn clone_function_through_type(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { *mut_thing = HasCloneFrom::clone(ref_thing); + //~^ assigning_clones } fn clone_function_fully_qualified(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { *mut_thing = ::clone(ref_thing); + //~^ assigning_clones } fn clone_method_lhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { // These parens should be kept as necessary for a receiver *(mut_thing + &mut HasCloneFrom) = ref_thing.clone(); + //~^ assigning_clones } fn clone_method_rhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) { // These parens should be removed since they are not needed in a function argument *mut_thing = (ref_thing + ref_thing).clone(); + //~^ assigning_clones } fn clone_method_macro() { let mut s = String::from(""); s = format!("{} {}", "hello", "world").clone(); + //~^ assigning_clones } fn clone_function_macro() { let mut s = String::from(""); s = Clone::clone(&format!("{} {}", "hello", "world")); + //~^ assigning_clones } fn assign_to_init_mut_var(b: HasCloneFrom) -> HasCloneFrom { let mut a = HasCloneFrom; for _ in 1..10 { a = b.clone(); + //~^ assigning_clones } a } @@ -148,6 +161,7 @@ fn ignore_generic_clone(a: &mut T, b: &T) { #[clippy::msrv = "1.62"] fn msrv_1_62(mut a: String, b: String, c: &str) { a = b.clone(); + //~^ assigning_clones // Should not be linted, as clone_into wasn't stabilized until 1.63 a = c.to_owned(); } @@ -155,7 +169,9 @@ fn msrv_1_62(mut a: String, b: String, c: &str) { #[clippy::msrv = "1.63"] fn msrv_1_63(mut a: String, b: String, c: &str) { a = b.clone(); + //~^ assigning_clones a = c.to_owned(); + //~^ assigning_clones } macro_rules! clone_inside { @@ -186,35 +202,43 @@ impl Clone for AvoidRecursiveCloneFrom { // Deref handling fn clone_into_deref_method(mut a: DerefWrapper, b: HasCloneFrom) { *a = b.clone(); + //~^ assigning_clones } fn clone_into_deref_with_clone_method(mut a: DerefWrapperWithClone, b: HasCloneFrom) { *a = b.clone(); + //~^ assigning_clones } fn clone_into_box_method(mut a: Box, b: HasCloneFrom) { *a = b.clone(); + //~^ assigning_clones } fn clone_into_self_deref_method(a: &mut DerefWrapperWithClone, b: DerefWrapperWithClone) { *a = b.clone(); + //~^ assigning_clones } fn clone_into_deref_function(mut a: DerefWrapper, b: HasCloneFrom) { *a = Clone::clone(&b); + //~^ assigning_clones } fn clone_into_box_function(mut a: Box, b: HasCloneFrom) { *a = Clone::clone(&b); + //~^ assigning_clones } // ToOwned fn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) { *mut_string = ref_str.to_owned(); + //~^ assigning_clones } fn owned_method_val(mut mut_string: String, ref_str: &str) { mut_string = ref_str.to_owned(); + //~^ assigning_clones } struct HasDeref { @@ -236,28 +260,34 @@ impl DerefMut for HasDeref { fn owned_method_box(mut_box_string: &mut Box, ref_str: &str) { **mut_box_string = ref_str.to_owned(); + //~^ assigning_clones } fn owned_method_deref(mut_box_string: &mut HasDeref, ref_str: &str) { **mut_box_string = ref_str.to_owned(); + //~^ assigning_clones } fn owned_function_mut_ref(mut_thing: &mut String, ref_str: &str) { *mut_thing = ToOwned::to_owned(ref_str); + //~^ assigning_clones } fn owned_function_val(mut mut_thing: String, ref_str: &str) { mut_thing = ToOwned::to_owned(ref_str); + //~^ assigning_clones } fn owned_method_macro() { let mut s = String::from(""); s = format!("{} {}", "hello", "world").to_owned(); + //~^ assigning_clones } fn owned_function_macro() { let mut s = String::from(""); s = ToOwned::to_owned(&format!("{} {}", "hello", "world")); + //~^ assigning_clones } struct FakeToOwned; diff --git a/tests/ui/assigning_clones.stderr b/tests/ui/assigning_clones.stderr index 19724a6d4ec2..2714d599b28a 100644 --- a/tests/ui/assigning_clones.stderr +++ b/tests/ui/assigning_clones.stderr @@ -8,175 +8,175 @@ LL | *mut_thing = value_thing.clone(); = help: to override `-D warnings` add `#[allow(clippy::assigning_clones)]` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:29:5 + --> tests/ui/assigning_clones.rs:30:5 | LL | *mut_thing = ref_thing.clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:33:5 + --> tests/ui/assigning_clones.rs:35:5 | LL | mut_thing = ref_thing.clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:37:5 + --> tests/ui/assigning_clones.rs:40:5 | LL | *mut_thing = Clone::clone(ref_thing); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:41:5 + --> tests/ui/assigning_clones.rs:45:5 | LL | mut_thing = Clone::clone(ref_thing); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut mut_thing, ref_thing)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:45:5 + --> tests/ui/assigning_clones.rs:50:5 | LL | *mut_thing = Clone::clone(ref_thing); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:49:5 + --> tests/ui/assigning_clones.rs:55:5 | LL | *mut_thing = HasCloneFrom::clone(ref_thing); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:53:5 + --> tests/ui/assigning_clones.rs:60:5 | LL | *mut_thing = ::clone(ref_thing); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:58:5 + --> tests/ui/assigning_clones.rs:66:5 | LL | *(mut_thing + &mut HasCloneFrom) = ref_thing.clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `(mut_thing + &mut HasCloneFrom).clone_from(ref_thing)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:63:5 + --> tests/ui/assigning_clones.rs:72:5 | LL | *mut_thing = (ref_thing + ref_thing).clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing + ref_thing)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:68:5 + --> tests/ui/assigning_clones.rs:78:5 | LL | s = format!("{} {}", "hello", "world").clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `s.clone_from(&format!("{} {}", "hello", "world"))` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:73:5 + --> tests/ui/assigning_clones.rs:84:5 | LL | s = Clone::clone(&format!("{} {}", "hello", "world")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut s, &format!("{} {}", "hello", "world"))` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:79:9 + --> tests/ui/assigning_clones.rs:91:9 | LL | a = b.clone(); | ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:150:5 + --> tests/ui/assigning_clones.rs:163:5 | LL | a = b.clone(); | ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:157:5 + --> tests/ui/assigning_clones.rs:171:5 | LL | a = b.clone(); | ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)` error: assigning the result of `ToOwned::to_owned()` may be inefficient - --> tests/ui/assigning_clones.rs:158:5 + --> tests/ui/assigning_clones.rs:173:5 | LL | a = c.to_owned(); | ^^^^^^^^^^^^^^^^ help: use `clone_into()`: `c.clone_into(&mut a)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:188:5 + --> tests/ui/assigning_clones.rs:204:5 | LL | *a = b.clone(); | ^^^^^^^^^^^^^^ help: use `clone_from()`: `(*a).clone_from(&b)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:192:5 + --> tests/ui/assigning_clones.rs:209:5 | LL | *a = b.clone(); | ^^^^^^^^^^^^^^ help: use `clone_from()`: `(*a).clone_from(&b)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:196:5 + --> tests/ui/assigning_clones.rs:214:5 | LL | *a = b.clone(); | ^^^^^^^^^^^^^^ help: use `clone_from()`: `(*a).clone_from(&b)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:200:5 + --> tests/ui/assigning_clones.rs:219:5 | LL | *a = b.clone(); | ^^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:204:5 + --> tests/ui/assigning_clones.rs:224:5 | LL | *a = Clone::clone(&b); | ^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut *a, &b)` error: assigning the result of `Clone::clone()` may be inefficient - --> tests/ui/assigning_clones.rs:208:5 + --> tests/ui/assigning_clones.rs:229:5 | LL | *a = Clone::clone(&b); | ^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut *a, &b)` error: assigning the result of `ToOwned::to_owned()` may be inefficient - --> tests/ui/assigning_clones.rs:213:5 + --> tests/ui/assigning_clones.rs:235:5 | LL | *mut_string = ref_str.to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(mut_string)` error: assigning the result of `ToOwned::to_owned()` may be inefficient - --> tests/ui/assigning_clones.rs:217:5 + --> tests/ui/assigning_clones.rs:240:5 | LL | mut_string = ref_str.to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut mut_string)` error: assigning the result of `ToOwned::to_owned()` may be inefficient - --> tests/ui/assigning_clones.rs:238:5 + --> tests/ui/assigning_clones.rs:262:5 | LL | **mut_box_string = ref_str.to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))` error: assigning the result of `ToOwned::to_owned()` may be inefficient - --> tests/ui/assigning_clones.rs:242:5 + --> tests/ui/assigning_clones.rs:267:5 | LL | **mut_box_string = ref_str.to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))` error: assigning the result of `ToOwned::to_owned()` may be inefficient - --> tests/ui/assigning_clones.rs:246:5 + --> tests/ui/assigning_clones.rs:272:5 | LL | *mut_thing = ToOwned::to_owned(ref_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, mut_thing)` error: assigning the result of `ToOwned::to_owned()` may be inefficient - --> tests/ui/assigning_clones.rs:250:5 + --> tests/ui/assigning_clones.rs:277:5 | LL | mut_thing = ToOwned::to_owned(ref_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, &mut mut_thing)` error: assigning the result of `ToOwned::to_owned()` may be inefficient - --> tests/ui/assigning_clones.rs:255:5 + --> tests/ui/assigning_clones.rs:283:5 | LL | s = format!("{} {}", "hello", "world").to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `format!("{} {}", "hello", "world").clone_into(&mut s)` error: assigning the result of `ToOwned::to_owned()` may be inefficient - --> tests/ui/assigning_clones.rs:260:5 + --> tests/ui/assigning_clones.rs:289:5 | LL | s = ToOwned::to_owned(&format!("{} {}", "hello", "world")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(&format!("{} {}", "hello", "world"), &mut s)` diff --git a/tests/ui/async_yields_async.fixed b/tests/ui/async_yields_async.fixed index 48402164a827..93c573d30863 100644 --- a/tests/ui/async_yields_async.fixed +++ b/tests/ui/async_yields_async.fixed @@ -38,9 +38,11 @@ fn main() { 3 }.await }; + //~^^^^ async_yields_async let _i = async { CustomFutureType.await }; + //~^^ async_yields_async let _i = async || { 3 }; @@ -49,10 +51,13 @@ fn main() { 3 }.await }; + //~^^^^ async_yields_async let _k = async || { CustomFutureType.await }; + //~^^ async_yields_async let _l = async || CustomFutureType.await; + //~^ async_yields_async let _m = async || { println!("I'm bored"); // Some more stuff @@ -60,6 +65,7 @@ fn main() { // Finally something to await CustomFutureType.await }; + //~^^ async_yields_async let _n = async || custom_future_type_ctor(); let _o = async || f(); } diff --git a/tests/ui/async_yields_async.rs b/tests/ui/async_yields_async.rs index 8ad016b6bb4e..166d522e1c04 100644 --- a/tests/ui/async_yields_async.rs +++ b/tests/ui/async_yields_async.rs @@ -38,9 +38,11 @@ fn main() { 3 } }; + //~^^^^ async_yields_async let _i = async { CustomFutureType }; + //~^^ async_yields_async let _i = async || { 3 }; @@ -49,10 +51,13 @@ fn main() { 3 } }; + //~^^^^ async_yields_async let _k = async || { CustomFutureType }; + //~^^ async_yields_async let _l = async || CustomFutureType; + //~^ async_yields_async let _m = async || { println!("I'm bored"); // Some more stuff @@ -60,6 +65,7 @@ fn main() { // Finally something to await CustomFutureType }; + //~^^ async_yields_async let _n = async || custom_future_type_ctor(); let _o = async || f(); } diff --git a/tests/ui/async_yields_async.stderr b/tests/ui/async_yields_async.stderr index 474914299d06..01533268a515 100644 --- a/tests/ui/async_yields_async.stderr +++ b/tests/ui/async_yields_async.stderr @@ -20,7 +20,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:42:9 + --> tests/ui/async_yields_async.rs:43:9 | LL | let _i = async { | ____________________- @@ -33,7 +33,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:48:9 + --> tests/ui/async_yields_async.rs:50:9 | LL | let _j = async || { | ________________________- @@ -52,7 +52,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:53:9 + --> tests/ui/async_yields_async.rs:56:9 | LL | let _k = async || { | _______________________- @@ -65,7 +65,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:55:23 + --> tests/ui/async_yields_async.rs:59:23 | LL | let _l = async || CustomFutureType; | ^^^^^^^^^^^^^^^^ @@ -75,7 +75,7 @@ LL | let _l = async || CustomFutureType; | help: consider awaiting this value: `CustomFutureType.await` error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:61:9 + --> tests/ui/async_yields_async.rs:66:9 | LL | let _m = async || { | _______________________- diff --git a/tests/ui/attrs.rs b/tests/ui/attrs.rs index da96eabede17..6f08bb304260 100644 --- a/tests/ui/attrs.rs +++ b/tests/ui/attrs.rs @@ -3,8 +3,9 @@ #![allow(clippy::missing_docs_in_private_items, clippy::panic, clippy::unreachable)] #[inline(always)] -//~^ ERROR: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a b -//~| NOTE: `-D clippy::inline-always` implied by `-D warnings` +//~^ inline_always + + fn test_attr_lint() { assert!(true) } @@ -25,12 +26,14 @@ fn empty_and_false_positive_stmt() { } #[deprecated(since = "forever")] -//~^ ERROR: the since field must contain a semver-compliant version -//~| NOTE: `-D clippy::deprecated-semver` implied by `-D warnings` +//~^ deprecated_semver + + pub const SOME_CONST: u8 = 42; #[deprecated(since = "1")] -//~^ ERROR: the since field must contain a semver-compliant version +//~^ deprecated_semver + pub const ANOTHER_CONST: u8 = 23; #[deprecated(since = "0.1.1")] diff --git a/tests/ui/attrs.stderr b/tests/ui/attrs.stderr index a7fdceaba6f3..74d4068f6331 100644 --- a/tests/ui/attrs.stderr +++ b/tests/ui/attrs.stderr @@ -1,5 +1,5 @@ error: the since field must contain a semver-compliant version - --> tests/ui/attrs.rs:27:14 + --> tests/ui/attrs.rs:28:14 | LL | #[deprecated(since = "forever")] | ^^^^^^^^^^^^^^^^^ @@ -8,11 +8,29 @@ LL | #[deprecated(since = "forever")] = help: to override `-D warnings` add `#[allow(clippy::deprecated_semver)]` error: the since field must contain a semver-compliant version - --> tests/ui/attrs.rs:32:14 + --> tests/ui/attrs.rs:34:14 | LL | #[deprecated(since = "1")] | ^^^^^^^^^^^ +error: empty lines after outer attribute + --> tests/ui/attrs.rs:5:1 + | +LL | / #[inline(always)] +... | +LL | | + | |_^ +LL | fn test_attr_lint() { + | ------------------- the attribute applies to this function + | + = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]` + = help: if the empty lines are unintentional remove them +help: if the attribute should apply to the crate use an inner attribute + | +LL | #![inline(always)] + | + + error: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a bad idea --> tests/ui/attrs.rs:5:1 | @@ -22,5 +40,29 @@ LL | #[inline(always)] = note: `-D clippy::inline-always` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::inline_always)]` -error: aborting due to 3 previous errors +error: empty lines after outer attribute + --> tests/ui/attrs.rs:28:1 + | +LL | / #[deprecated(since = "forever")] +... | +LL | | + | |_^ +LL | pub const SOME_CONST: u8 = 42; + | ------------------------ the attribute applies to this constant + | + = help: if the empty lines are unintentional remove them + +error: empty line after outer attribute + --> tests/ui/attrs.rs:34:1 + | +LL | / #[deprecated(since = "1")] +LL | | +LL | | + | |_^ +LL | pub const ANOTHER_CONST: u8 = 23; + | --------------------------- the attribute applies to this constant + | + = help: if the empty line is unintentional remove it + +error: aborting due to 6 previous errors diff --git a/tests/ui/author.rs b/tests/ui/author.rs index 0a1be3568967..faab114852fb 100644 --- a/tests/ui/author.rs +++ b/tests/ui/author.rs @@ -1,3 +1,5 @@ +//@ check-pass + fn main() { #[clippy::author] let x: char = 0x45 as char; diff --git a/tests/ui/author/blocks.rs b/tests/ui/author/blocks.rs index e9db611a2aa9..73e921e4c75d 100644 --- a/tests/ui/author/blocks.rs +++ b/tests/ui/author/blocks.rs @@ -1,3 +1,4 @@ +//@ check-pass //@edition:2018 #![allow(redundant_semicolons, clippy::no_effect)] diff --git a/tests/ui/author/call.rs b/tests/ui/author/call.rs index e99c3c41dc4e..8d48eb7bd3e3 100644 --- a/tests/ui/author/call.rs +++ b/tests/ui/author/call.rs @@ -1,3 +1,5 @@ +//@ check-pass + fn main() { #[clippy::author] let _ = ::std::cmp::min(3, 4); diff --git a/tests/ui/author/if.rs b/tests/ui/author/if.rs index 946088ab3461..59bc9f5bfa5c 100644 --- a/tests/ui/author/if.rs +++ b/tests/ui/author/if.rs @@ -1,3 +1,5 @@ +//@ check-pass + #[allow(clippy::all)] fn main() { diff --git a/tests/ui/author/issue_3849.rs b/tests/ui/author/issue_3849.rs index 5f65746d71f2..dbd63b21af29 100644 --- a/tests/ui/author/issue_3849.rs +++ b/tests/ui/author/issue_3849.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(dead_code)] #![allow(clippy::zero_ptr)] #![allow(clippy::transmute_ptr_to_ref)] diff --git a/tests/ui/author/loop.rs b/tests/ui/author/loop.rs index ff5b61001179..dcf6fbd72027 100644 --- a/tests/ui/author/loop.rs +++ b/tests/ui/author/loop.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(stmt_expr_attributes)] #![allow( clippy::never_loop, diff --git a/tests/ui/author/macro_in_closure.rs b/tests/ui/author/macro_in_closure.rs index 444e6a12165d..8a02f38fad87 100644 --- a/tests/ui/author/macro_in_closure.rs +++ b/tests/ui/author/macro_in_closure.rs @@ -1,3 +1,5 @@ +//@ check-pass + fn main() { #[clippy::author] let print_text = |x| println!("{}", x); diff --git a/tests/ui/author/macro_in_loop.rs b/tests/ui/author/macro_in_loop.rs index 8a520501f8dd..84ffe416e839 100644 --- a/tests/ui/author/macro_in_loop.rs +++ b/tests/ui/author/macro_in_loop.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(stmt_expr_attributes)] fn main() { diff --git a/tests/ui/author/matches.rs b/tests/ui/author/matches.rs index 674e07ec2d3d..e80d9c51023a 100644 --- a/tests/ui/author/matches.rs +++ b/tests/ui/author/matches.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::let_and_return)] fn main() { diff --git a/tests/ui/author/repeat.rs b/tests/ui/author/repeat.rs index d8e9d589e689..872f99844a01 100644 --- a/tests/ui/author/repeat.rs +++ b/tests/ui/author/repeat.rs @@ -1,3 +1,5 @@ +//@ check-pass + #[allow(clippy::no_effect)] fn main() { #[clippy::author] diff --git a/tests/ui/author/struct.rs b/tests/ui/author/struct.rs index a99bdfc13137..73db44b73319 100644 --- a/tests/ui/author/struct.rs +++ b/tests/ui/author/struct.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow( clippy::unnecessary_operation, clippy::single_match, diff --git a/tests/ui/await_holding_refcell_ref.rs b/tests/ui/await_holding_refcell_ref.rs index b0c92d8c1f6e..258e16c07e04 100644 --- a/tests/ui/await_holding_refcell_ref.rs +++ b/tests/ui/await_holding_refcell_ref.rs @@ -4,13 +4,15 @@ use std::cell::RefCell; async fn bad(x: &RefCell) -> u32 { let b = x.borrow(); - //~^ ERROR: this `RefCell` reference is held across an await point + //~^ await_holding_refcell_ref + baz().await } async fn bad_mut(x: &RefCell) -> u32 { let b = x.borrow_mut(); - //~^ ERROR: this `RefCell` reference is held across an await point + //~^ await_holding_refcell_ref + baz().await } @@ -32,7 +34,8 @@ async fn also_bad(x: &RefCell) -> u32 { let first = baz().await; let b = x.borrow_mut(); - //~^ ERROR: this `RefCell` reference is held across an await point + //~^ await_holding_refcell_ref + let second = baz().await; @@ -45,7 +48,8 @@ async fn less_bad(x: &RefCell) -> u32 { let first = baz().await; let b = x.borrow_mut(); - //~^ ERROR: this `RefCell` reference is held across an await point + //~^ await_holding_refcell_ref + let second = baz().await; @@ -61,7 +65,8 @@ async fn not_good(x: &RefCell) -> u32 { let second = { let b = x.borrow_mut(); - //~^ ERROR: this `RefCell` reference is held across an await point + //~^ await_holding_refcell_ref + baz().await }; @@ -74,7 +79,8 @@ async fn not_good(x: &RefCell) -> u32 { fn block_bad(x: &RefCell) -> impl std::future::Future + '_ { async move { let b = x.borrow_mut(); - //~^ ERROR: this `RefCell` reference is held across an await point + //~^ await_holding_refcell_ref + baz().await } } diff --git a/tests/ui/await_holding_refcell_ref.stderr b/tests/ui/await_holding_refcell_ref.stderr index 6c7209c9ff9e..ce7c71ae8fec 100644 --- a/tests/ui/await_holding_refcell_ref.stderr +++ b/tests/ui/await_holding_refcell_ref.stderr @@ -6,7 +6,7 @@ LL | let b = x.borrow(); | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:8:11 + --> tests/ui/await_holding_refcell_ref.rs:9:11 | LL | baz().await | ^^^^^ @@ -14,27 +14,27 @@ LL | baz().await = help: to override `-D warnings` add `#[allow(clippy::await_holding_refcell_ref)]` error: this `RefCell` reference is held across an await point - --> tests/ui/await_holding_refcell_ref.rs:12:9 + --> tests/ui/await_holding_refcell_ref.rs:13:9 | LL | let b = x.borrow_mut(); | ^ | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:14:11 + --> tests/ui/await_holding_refcell_ref.rs:16:11 | LL | baz().await | ^^^^^ error: this `RefCell` reference is held across an await point - --> tests/ui/await_holding_refcell_ref.rs:34:9 + --> tests/ui/await_holding_refcell_ref.rs:36:9 | LL | let b = x.borrow_mut(); | ^ | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:37:24 + --> tests/ui/await_holding_refcell_ref.rs:40:24 | LL | let second = baz().await; | ^^^^^ @@ -43,40 +43,40 @@ LL | let third = baz().await; | ^^^^^ error: this `RefCell` reference is held across an await point - --> tests/ui/await_holding_refcell_ref.rs:47:9 + --> tests/ui/await_holding_refcell_ref.rs:50:9 | LL | let b = x.borrow_mut(); | ^ | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:50:24 + --> tests/ui/await_holding_refcell_ref.rs:54:24 | LL | let second = baz().await; | ^^^^^ error: this `RefCell` reference is held across an await point - --> tests/ui/await_holding_refcell_ref.rs:63:13 + --> tests/ui/await_holding_refcell_ref.rs:67:13 | LL | let b = x.borrow_mut(); | ^ | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:65:15 + --> tests/ui/await_holding_refcell_ref.rs:70:15 | LL | baz().await | ^^^^^ error: this `RefCell` reference is held across an await point - --> tests/ui/await_holding_refcell_ref.rs:76:13 + --> tests/ui/await_holding_refcell_ref.rs:81:13 | LL | let b = x.borrow_mut(); | ^ | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:78:15 + --> tests/ui/await_holding_refcell_ref.rs:84:15 | LL | baz().await | ^^^^^ diff --git a/tests/ui/bind_instead_of_map.fixed b/tests/ui/bind_instead_of_map.fixed index 910cec2f203d..80e010e2dfd7 100644 --- a/tests/ui/bind_instead_of_map.fixed +++ b/tests/ui/bind_instead_of_map.fixed @@ -6,13 +6,16 @@ pub fn main() { let x = Some(5); // the easiest cases let _ = x; + //~^ bind_instead_of_map let _ = x.map(|o| o + 1); + //~^ bind_instead_of_map // and an easy counter-example let _ = x.and_then(|o| if o < 32 { Some(o) } else { None }); // Different type let x: Result = Ok(1); let _ = x; + //~^ bind_instead_of_map } pub fn foo() -> Option { diff --git a/tests/ui/bind_instead_of_map.rs b/tests/ui/bind_instead_of_map.rs index 6d66f659ba78..09aa8480cbd9 100644 --- a/tests/ui/bind_instead_of_map.rs +++ b/tests/ui/bind_instead_of_map.rs @@ -6,13 +6,16 @@ pub fn main() { let x = Some(5); // the easiest cases let _ = x.and_then(Some); + //~^ bind_instead_of_map let _ = x.and_then(|o| Some(o + 1)); + //~^ bind_instead_of_map // and an easy counter-example let _ = x.and_then(|o| if o < 32 { Some(o) } else { None }); // Different type let x: Result = Ok(1); let _ = x.and_then(Ok); + //~^ bind_instead_of_map } pub fn foo() -> Option { diff --git a/tests/ui/bind_instead_of_map.stderr b/tests/ui/bind_instead_of_map.stderr index 57e0e4fb8475..08f85fb58549 100644 --- a/tests/ui/bind_instead_of_map.stderr +++ b/tests/ui/bind_instead_of_map.stderr @@ -11,13 +11,13 @@ LL | #![deny(clippy::bind_instead_of_map)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)` - --> tests/ui/bind_instead_of_map.rs:9:13 + --> tests/ui/bind_instead_of_map.rs:10:13 | LL | let _ = x.and_then(|o| Some(o + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map(|o| o + 1)` error: using `Result.and_then(Ok)`, which is a no-op - --> tests/ui/bind_instead_of_map.rs:15:13 + --> tests/ui/bind_instead_of_map.rs:17:13 | LL | let _ = x.and_then(Ok); | ^^^^^^^^^^^^^^ help: use the expression directly: `x` diff --git a/tests/ui/bind_instead_of_map_multipart.fixed b/tests/ui/bind_instead_of_map_multipart.fixed index 8c77039b3c01..a1da2cfc9fc6 100644 --- a/tests/ui/bind_instead_of_map_multipart.fixed +++ b/tests/ui/bind_instead_of_map_multipart.fixed @@ -3,12 +3,15 @@ pub fn main() { let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); + //~^ bind_instead_of_map let _ = Some("42").and_then(|s| if s.len() < 42 { None } else { Some(s.len()) }); let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); + //~^ bind_instead_of_map let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Err(()) } else { Ok(s.len()) }); let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() }); + //~^ bind_instead_of_map let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Ok(()) } else { Err(s.len()) }); hard_example(); @@ -17,6 +20,7 @@ pub fn main() { fn hard_example() { Some("42").map(|s| { + //~^ bind_instead_of_map if { if s == "43" { return 43; @@ -58,4 +62,5 @@ macro_rules! m { fn macro_example() { let _ = Some("").and_then(|s| if s.len() == 20 { m!() } else { Some(20) }); let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) }); + //~^ bind_instead_of_map } diff --git a/tests/ui/bind_instead_of_map_multipart.rs b/tests/ui/bind_instead_of_map_multipart.rs index 44257f3a4698..5710254ddf6e 100644 --- a/tests/ui/bind_instead_of_map_multipart.rs +++ b/tests/ui/bind_instead_of_map_multipart.rs @@ -3,12 +3,15 @@ pub fn main() { let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) }); + //~^ bind_instead_of_map let _ = Some("42").and_then(|s| if s.len() < 42 { None } else { Some(s.len()) }); let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) }); + //~^ bind_instead_of_map let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Err(()) } else { Ok(s.len()) }); let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) }); + //~^ bind_instead_of_map let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Ok(()) } else { Err(s.len()) }); hard_example(); @@ -17,6 +20,7 @@ pub fn main() { fn hard_example() { Some("42").and_then(|s| { + //~^ bind_instead_of_map if { if s == "43" { return Some(43); @@ -58,4 +62,5 @@ macro_rules! m { fn macro_example() { let _ = Some("").and_then(|s| if s.len() == 20 { m!() } else { Some(20) }); let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) }); + //~^ bind_instead_of_map } diff --git a/tests/ui/bind_instead_of_map_multipart.stderr b/tests/ui/bind_instead_of_map_multipart.stderr index d271381adea2..336b19433a68 100644 --- a/tests/ui/bind_instead_of_map_multipart.stderr +++ b/tests/ui/bind_instead_of_map_multipart.stderr @@ -15,7 +15,7 @@ LL | let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); | ~~~ ~ ~~~~~~~ error: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as `map(|x| y)` - --> tests/ui/bind_instead_of_map_multipart.rs:8:13 + --> tests/ui/bind_instead_of_map_multipart.rs:9:13 | LL | let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() | ~~~ ~ ~~~~~~~ error: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as `map_err(|x| y)` - --> tests/ui/bind_instead_of_map_multipart.rs:11:13 + --> tests/ui/bind_instead_of_map_multipart.rs:13:13 | LL | let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,12 +37,12 @@ LL | let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } | ~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~ error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)` - --> tests/ui/bind_instead_of_map_multipart.rs:19:5 + --> tests/ui/bind_instead_of_map_multipart.rs:22:5 | LL | / Some("42").and_then(|s| { +LL | | LL | | if { LL | | if s == "43" { -LL | | return Some(43); ... | LL | | }); | |______^ @@ -50,6 +50,7 @@ LL | | }); help: use `map` instead | LL ~ Some("42").map(|s| { +LL | LL | if { LL | if s == "43" { LL ~ return 43; @@ -76,7 +77,7 @@ LL ~ _ => 1, | error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)` - --> tests/ui/bind_instead_of_map_multipart.rs:60:13 + --> tests/ui/bind_instead_of_map_multipart.rs:64:13 | LL | let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/bit_masks.rs b/tests/ui/bit_masks.rs index 8e1d066c25e4..b38523a03960 100644 --- a/tests/ui/bit_masks.rs +++ b/tests/ui/bit_masks.rs @@ -12,27 +12,33 @@ fn main() { let x = 5; x & 0 == 0; - //~^ ERROR: &-masking with zero - //~| NOTE: `-D clippy::bad-bit-mask` implied by `-D warnings` - //~| ERROR: this operation will always return zero. This is likely not the intended ou - //~| NOTE: `#[deny(clippy::erasing_op)]` on by default + //~^ bad_bit_mask + //~| erasing_op + + + + x & 1 == 1; //ok, distinguishes bit 0 x & 1 == 0; //ok, compared with zero x & 2 == 1; - //~^ ERROR: incompatible bit mask: `_ & 2` can never be equal to `1` + //~^ bad_bit_mask + x | 0 == 0; //ok, equals x == 0 (maybe warn?) x | 1 == 3; //ok, equals x == 2 || x == 3 x | 3 == 3; //ok, equals x <= 3 x | 3 == 2; - //~^ ERROR: incompatible bit mask: `_ | 3` can never be equal to `2` + //~^ bad_bit_mask + x & 1 > 1; - //~^ ERROR: incompatible bit mask: `_ & 1` will never be higher than `1` + //~^ bad_bit_mask + x & 2 > 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0 x & 2 < 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0 x | 1 > 1; // ok (if a bit silly), equals x > 1 x | 2 > 1; - //~^ ERROR: incompatible bit mask: `_ | 2` will always be higher than `1` + //~^ bad_bit_mask + x | 2 <= 2; // ok (if a bit silly), equals x <= 2 x & 192 == 128; // ok, tests for bit 7 and not bit 6 @@ -40,22 +46,29 @@ fn main() { // this also now works with constants x & THREE_BITS == 8; - //~^ ERROR: incompatible bit mask: `_ & 7` can never be equal to `8` + //~^ bad_bit_mask + x | EVEN_MORE_REDIRECTION < 7; - //~^ ERROR: incompatible bit mask: `_ | 7` will never be lower than `7` + //~^ bad_bit_mask + 0 & x == 0; - //~^ ERROR: &-masking with zero - //~| ERROR: this operation will always return zero. This is likely not the intended ou + //~^ bad_bit_mask + //~| erasing_op + + 1 | x > 1; // and should now also match uncommon usage 1 < 2 | x; - //~^ ERROR: incompatible bit mask: `_ | 2` will always be higher than `1` + //~^ bad_bit_mask + 2 == 3 | x; - //~^ ERROR: incompatible bit mask: `_ | 3` can never be equal to `2` + //~^ bad_bit_mask + 1 == x & 2; - //~^ ERROR: incompatible bit mask: `_ & 2` can never be equal to `1` + //~^ bad_bit_mask + x | 1 > 2; // no error, because we allowed ineffective bit masks ineffective(); @@ -67,14 +80,18 @@ fn ineffective() { let x = 5; x | 1 > 3; - //~^ ERROR: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared d - //~| NOTE: `-D clippy::ineffective-bit-mask` implied by `-D warnings` + //~^ ineffective_bit_mask + + x | 1 < 4; - //~^ ERROR: ineffective bit mask: `x | 1` compared to `4`, is the same as x compared d + //~^ ineffective_bit_mask + x | 1 <= 3; - //~^ ERROR: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared d + //~^ ineffective_bit_mask + x | 1 >= 8; - //~^ ERROR: ineffective bit mask: `x | 1` compared to `8`, is the same as x compared d + //~^ ineffective_bit_mask + x | 1 > 2; // not an error (yet), better written as x >= 2 x | 1 >= 7; // not an error (yet), better written as x >= 6 diff --git a/tests/ui/bit_masks.stderr b/tests/ui/bit_masks.stderr index 004f6ad94841..300c93df9250 100644 --- a/tests/ui/bit_masks.stderr +++ b/tests/ui/bit_masks.stderr @@ -16,73 +16,73 @@ LL | x & 0 == 0; = note: `#[deny(clippy::erasing_op)]` on by default error: incompatible bit mask: `_ & 2` can never be equal to `1` - --> tests/ui/bit_masks.rs:21:5 + --> tests/ui/bit_masks.rs:23:5 | LL | x & 2 == 1; | ^^^^^^^^^^ error: incompatible bit mask: `_ | 3` can never be equal to `2` - --> tests/ui/bit_masks.rs:26:5 + --> tests/ui/bit_masks.rs:29:5 | LL | x | 3 == 2; | ^^^^^^^^^^ error: incompatible bit mask: `_ & 1` will never be higher than `1` - --> tests/ui/bit_masks.rs:29:5 + --> tests/ui/bit_masks.rs:33:5 | LL | x & 1 > 1; | ^^^^^^^^^ error: incompatible bit mask: `_ | 2` will always be higher than `1` - --> tests/ui/bit_masks.rs:34:5 + --> tests/ui/bit_masks.rs:39:5 | LL | x | 2 > 1; | ^^^^^^^^^ error: incompatible bit mask: `_ & 7` can never be equal to `8` - --> tests/ui/bit_masks.rs:42:5 + --> tests/ui/bit_masks.rs:48:5 | LL | x & THREE_BITS == 8; | ^^^^^^^^^^^^^^^^^^^ error: incompatible bit mask: `_ | 7` will never be lower than `7` - --> tests/ui/bit_masks.rs:44:5 + --> tests/ui/bit_masks.rs:51:5 | LL | x | EVEN_MORE_REDIRECTION < 7; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: &-masking with zero - --> tests/ui/bit_masks.rs:47:5 + --> tests/ui/bit_masks.rs:55:5 | LL | 0 & x == 0; | ^^^^^^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/bit_masks.rs:47:5 + --> tests/ui/bit_masks.rs:55:5 | LL | 0 & x == 0; | ^^^^^ error: incompatible bit mask: `_ | 2` will always be higher than `1` - --> tests/ui/bit_masks.rs:53:5 + --> tests/ui/bit_masks.rs:63:5 | LL | 1 < 2 | x; | ^^^^^^^^^ error: incompatible bit mask: `_ | 3` can never be equal to `2` - --> tests/ui/bit_masks.rs:55:5 + --> tests/ui/bit_masks.rs:66:5 | LL | 2 == 3 | x; | ^^^^^^^^^^ error: incompatible bit mask: `_ & 2` can never be equal to `1` - --> tests/ui/bit_masks.rs:57:5 + --> tests/ui/bit_masks.rs:69:5 | LL | 1 == x & 2; | ^^^^^^^^^^ error: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly - --> tests/ui/bit_masks.rs:69:5 + --> tests/ui/bit_masks.rs:82:5 | LL | x | 1 > 3; | ^^^^^^^^^ @@ -91,19 +91,19 @@ LL | x | 1 > 3; = help: to override `-D warnings` add `#[allow(clippy::ineffective_bit_mask)]` error: ineffective bit mask: `x | 1` compared to `4`, is the same as x compared directly - --> tests/ui/bit_masks.rs:72:5 + --> tests/ui/bit_masks.rs:86:5 | LL | x | 1 < 4; | ^^^^^^^^^ error: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly - --> tests/ui/bit_masks.rs:74:5 + --> tests/ui/bit_masks.rs:89:5 | LL | x | 1 <= 3; | ^^^^^^^^^^ error: ineffective bit mask: `x | 1` compared to `8`, is the same as x compared directly - --> tests/ui/bit_masks.rs:76:5 + --> tests/ui/bit_masks.rs:92:5 | LL | x | 1 >= 8; | ^^^^^^^^^^ diff --git a/tests/ui/blanket_clippy_restriction_lints.rs b/tests/ui/blanket_clippy_restriction_lints.rs index 2bfaadf8df94..16e2e62c523d 100644 --- a/tests/ui/blanket_clippy_restriction_lints.rs +++ b/tests/ui/blanket_clippy_restriction_lints.rs @@ -1,13 +1,17 @@ //@compile-flags: -W clippy::restriction +//@error-in-other-file: restriction #![warn(clippy::blanket_clippy_restriction_lints)] //! Test that the whole restriction group is not enabled #![warn(clippy::restriction)] -//~^ ERROR: `clippy::restriction` is not meant to be enabled as a group +//~^ blanket_clippy_restriction_lints + #![deny(clippy::restriction)] -//~^ ERROR: `clippy::restriction` is not meant to be enabled as a group +//~^ blanket_clippy_restriction_lints + #![forbid(clippy::restriction)] -//~^ ERROR: `clippy::restriction` is not meant to be enabled as a group +//~^ blanket_clippy_restriction_lints + fn main() {} diff --git a/tests/ui/blanket_clippy_restriction_lints.stderr b/tests/ui/blanket_clippy_restriction_lints.stderr index 1bad259b09a3..5bfd7d208307 100644 --- a/tests/ui/blanket_clippy_restriction_lints.stderr +++ b/tests/ui/blanket_clippy_restriction_lints.stderr @@ -6,7 +6,7 @@ error: `clippy::restriction` is not meant to be enabled as a group = help: to override `-D warnings` add `#[allow(clippy::blanket_clippy_restriction_lints)]` error: `clippy::restriction` is not meant to be enabled as a group - --> tests/ui/blanket_clippy_restriction_lints.rs:6:9 + --> tests/ui/blanket_clippy_restriction_lints.rs:7:9 | LL | #![warn(clippy::restriction)] | ^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | #![warn(clippy::restriction)] = help: enable the restriction lints you need individually error: `clippy::restriction` is not meant to be enabled as a group - --> tests/ui/blanket_clippy_restriction_lints.rs:8:9 + --> tests/ui/blanket_clippy_restriction_lints.rs:10:9 | LL | #![deny(clippy::restriction)] | ^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | #![deny(clippy::restriction)] = help: enable the restriction lints you need individually error: `clippy::restriction` is not meant to be enabled as a group - --> tests/ui/blanket_clippy_restriction_lints.rs:10:11 + --> tests/ui/blanket_clippy_restriction_lints.rs:13:11 | LL | #![forbid(clippy::restriction)] | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/blocks_in_conditions.fixed b/tests/ui/blocks_in_conditions.fixed index af8e65270d09..df375e370573 100644 --- a/tests/ui/blocks_in_conditions.fixed +++ b/tests/ui/blocks_in_conditions.fixed @@ -46,6 +46,7 @@ fn condition_has_block_with_single_expression() -> i32 { fn condition_is_normal() -> i32 { let x = 3; if x == 3 { 6 } else { 10 } + //~^ nonminimal_bool } fn condition_is_unsafe_block() { diff --git a/tests/ui/blocks_in_conditions.rs b/tests/ui/blocks_in_conditions.rs index 6adae951a290..1d9c9dd42460 100644 --- a/tests/ui/blocks_in_conditions.rs +++ b/tests/ui/blocks_in_conditions.rs @@ -46,6 +46,7 @@ fn condition_has_block_with_single_expression() -> i32 { fn condition_is_normal() -> i32 { let x = 3; if true && x == 3 { 6 } else { 10 } + //~^ nonminimal_bool } fn condition_is_unsafe_block() { diff --git a/tests/ui/blocks_in_conditions.stderr b/tests/ui/blocks_in_conditions.stderr index a55e1efb575e..da21344a8428 100644 --- a/tests/ui/blocks_in_conditions.stderr +++ b/tests/ui/blocks_in_conditions.stderr @@ -35,7 +35,7 @@ LL | if true && x == 3 { 6 } else { 10 } = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> tests/ui/blocks_in_conditions.rs:75:5 + --> tests/ui/blocks_in_conditions.rs:76:5 | LL | / match { LL | | diff --git a/tests/ui/bool_assert_comparison.fixed b/tests/ui/bool_assert_comparison.fixed index b05166a055ee..721d8b2c2dcd 100644 --- a/tests/ui/bool_assert_comparison.fixed +++ b/tests/ui/bool_assert_comparison.fixed @@ -85,65 +85,90 @@ fn main() { assert_eq!("a".len(), 1); assert!(!"a".is_empty()); + //~^ bool_assert_comparison assert!("".is_empty()); + //~^ bool_assert_comparison assert!("".is_empty()); + //~^ bool_assert_comparison assert_eq!(a!(), b!()); assert_eq!(a!(), "".is_empty()); assert_eq!("".is_empty(), b!()); assert_eq!(a, true); assert!(b); + //~^ bool_assert_comparison assert_ne!("a".len(), 1); assert!("a".is_empty()); + //~^ bool_assert_comparison assert!(!"".is_empty()); + //~^ bool_assert_comparison assert!(!"".is_empty()); + //~^ bool_assert_comparison assert_ne!(a!(), b!()); assert_ne!(a!(), "".is_empty()); assert_ne!("".is_empty(), b!()); assert_ne!(a, true); assert!(!b); + //~^ bool_assert_comparison debug_assert_eq!("a".len(), 1); debug_assert!(!"a".is_empty()); + //~^ bool_assert_comparison debug_assert!("".is_empty()); + //~^ bool_assert_comparison debug_assert!("".is_empty()); + //~^ bool_assert_comparison debug_assert_eq!(a!(), b!()); debug_assert_eq!(a!(), "".is_empty()); debug_assert_eq!("".is_empty(), b!()); debug_assert_eq!(a, true); debug_assert!(b); + //~^ bool_assert_comparison debug_assert_ne!("a".len(), 1); debug_assert!("a".is_empty()); + //~^ bool_assert_comparison debug_assert!(!"".is_empty()); + //~^ bool_assert_comparison debug_assert!(!"".is_empty()); + //~^ bool_assert_comparison debug_assert_ne!(a!(), b!()); debug_assert_ne!(a!(), "".is_empty()); debug_assert_ne!("".is_empty(), b!()); debug_assert_ne!(a, true); debug_assert!(!b); + //~^ bool_assert_comparison // assert with error messages assert_eq!("a".len(), 1, "tadam {}", 1); assert_eq!("a".len(), 1, "tadam {}", true); assert!(!"a".is_empty(), "tadam {}", 1); + //~^ bool_assert_comparison assert!(!"a".is_empty(), "tadam {}", true); + //~^ bool_assert_comparison assert!(!"a".is_empty(), "tadam {}", true); + //~^ bool_assert_comparison assert_eq!(a, true, "tadam {}", false); debug_assert_eq!("a".len(), 1, "tadam {}", 1); debug_assert_eq!("a".len(), 1, "tadam {}", true); debug_assert!(!"a".is_empty(), "tadam {}", 1); + //~^ bool_assert_comparison debug_assert!(!"a".is_empty(), "tadam {}", true); + //~^ bool_assert_comparison debug_assert!(!"a".is_empty(), "tadam {}", true); + //~^ bool_assert_comparison debug_assert_eq!(a, true, "tadam {}", false); assert!(a!()); + //~^ bool_assert_comparison assert!(b!()); + //~^ bool_assert_comparison use debug_assert_eq as renamed; renamed!(a, true); debug_assert!(b); + //~^ bool_assert_comparison let non_copy = NonCopy; assert_eq!(non_copy, true); @@ -158,12 +183,20 @@ fn main() { in_macro!(a); assert!("".is_empty()); + //~^ bool_assert_comparison assert!("".is_empty()); + //~^ bool_assert_comparison assert!(!"requires negation".is_empty()); + //~^ bool_assert_comparison assert!(!"requires negation".is_empty()); + //~^ bool_assert_comparison debug_assert!("".is_empty()); + //~^ bool_assert_comparison debug_assert!("".is_empty()); + //~^ bool_assert_comparison debug_assert!(!"requires negation".is_empty()); + //~^ bool_assert_comparison debug_assert!(!"requires negation".is_empty()); + //~^ bool_assert_comparison } diff --git a/tests/ui/bool_assert_comparison.rs b/tests/ui/bool_assert_comparison.rs index dc51fcf1d36b..5ab4f475b063 100644 --- a/tests/ui/bool_assert_comparison.rs +++ b/tests/ui/bool_assert_comparison.rs @@ -85,65 +85,90 @@ fn main() { assert_eq!("a".len(), 1); assert_eq!("a".is_empty(), false); + //~^ bool_assert_comparison assert_eq!("".is_empty(), true); + //~^ bool_assert_comparison assert_eq!(true, "".is_empty()); + //~^ bool_assert_comparison assert_eq!(a!(), b!()); assert_eq!(a!(), "".is_empty()); assert_eq!("".is_empty(), b!()); assert_eq!(a, true); assert_eq!(b, true); + //~^ bool_assert_comparison assert_ne!("a".len(), 1); assert_ne!("a".is_empty(), false); + //~^ bool_assert_comparison assert_ne!("".is_empty(), true); + //~^ bool_assert_comparison assert_ne!(true, "".is_empty()); + //~^ bool_assert_comparison assert_ne!(a!(), b!()); assert_ne!(a!(), "".is_empty()); assert_ne!("".is_empty(), b!()); assert_ne!(a, true); assert_ne!(b, true); + //~^ bool_assert_comparison debug_assert_eq!("a".len(), 1); debug_assert_eq!("a".is_empty(), false); + //~^ bool_assert_comparison debug_assert_eq!("".is_empty(), true); + //~^ bool_assert_comparison debug_assert_eq!(true, "".is_empty()); + //~^ bool_assert_comparison debug_assert_eq!(a!(), b!()); debug_assert_eq!(a!(), "".is_empty()); debug_assert_eq!("".is_empty(), b!()); debug_assert_eq!(a, true); debug_assert_eq!(b, true); + //~^ bool_assert_comparison debug_assert_ne!("a".len(), 1); debug_assert_ne!("a".is_empty(), false); + //~^ bool_assert_comparison debug_assert_ne!("".is_empty(), true); + //~^ bool_assert_comparison debug_assert_ne!(true, "".is_empty()); + //~^ bool_assert_comparison debug_assert_ne!(a!(), b!()); debug_assert_ne!(a!(), "".is_empty()); debug_assert_ne!("".is_empty(), b!()); debug_assert_ne!(a, true); debug_assert_ne!(b, true); + //~^ bool_assert_comparison // assert with error messages assert_eq!("a".len(), 1, "tadam {}", 1); assert_eq!("a".len(), 1, "tadam {}", true); assert_eq!("a".is_empty(), false, "tadam {}", 1); + //~^ bool_assert_comparison assert_eq!("a".is_empty(), false, "tadam {}", true); + //~^ bool_assert_comparison assert_eq!(false, "a".is_empty(), "tadam {}", true); + //~^ bool_assert_comparison assert_eq!(a, true, "tadam {}", false); debug_assert_eq!("a".len(), 1, "tadam {}", 1); debug_assert_eq!("a".len(), 1, "tadam {}", true); debug_assert_eq!("a".is_empty(), false, "tadam {}", 1); + //~^ bool_assert_comparison debug_assert_eq!("a".is_empty(), false, "tadam {}", true); + //~^ bool_assert_comparison debug_assert_eq!(false, "a".is_empty(), "tadam {}", true); + //~^ bool_assert_comparison debug_assert_eq!(a, true, "tadam {}", false); assert_eq!(a!(), true); + //~^ bool_assert_comparison assert_eq!(true, b!()); + //~^ bool_assert_comparison use debug_assert_eq as renamed; renamed!(a, true); renamed!(b, true); + //~^ bool_assert_comparison let non_copy = NonCopy; assert_eq!(non_copy, true); @@ -158,12 +183,20 @@ fn main() { in_macro!(a); assert_eq!("".is_empty(), true); + //~^ bool_assert_comparison assert_ne!("".is_empty(), false); + //~^ bool_assert_comparison assert_ne!("requires negation".is_empty(), true); + //~^ bool_assert_comparison assert_eq!("requires negation".is_empty(), false); + //~^ bool_assert_comparison debug_assert_eq!("".is_empty(), true); + //~^ bool_assert_comparison debug_assert_ne!("".is_empty(), false); + //~^ bool_assert_comparison debug_assert_ne!("requires negation".is_empty(), true); + //~^ bool_assert_comparison debug_assert_eq!("requires negation".is_empty(), false); + //~^ bool_assert_comparison } diff --git a/tests/ui/bool_assert_comparison.stderr b/tests/ui/bool_assert_comparison.stderr index 41183c61ee01..a1d0af543617 100644 --- a/tests/ui/bool_assert_comparison.stderr +++ b/tests/ui/bool_assert_comparison.stderr @@ -13,7 +13,7 @@ LL + assert!(!"a".is_empty()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:88:5 + --> tests/ui/bool_assert_comparison.rs:89:5 | LL | assert_eq!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + assert!("".is_empty()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:89:5 + --> tests/ui/bool_assert_comparison.rs:91:5 | LL | assert_eq!(true, "".is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + assert!("".is_empty()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:94:5 + --> tests/ui/bool_assert_comparison.rs:97:5 | LL | assert_eq!(b, true); | ^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + assert!(b); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:97:5 + --> tests/ui/bool_assert_comparison.rs:101:5 | LL | assert_ne!("a".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + assert!("a".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:98:5 + --> tests/ui/bool_assert_comparison.rs:103:5 | LL | assert_ne!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + assert!(!"".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:99:5 + --> tests/ui/bool_assert_comparison.rs:105:5 | LL | assert_ne!(true, "".is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + assert!(!"".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:104:5 + --> tests/ui/bool_assert_comparison.rs:111:5 | LL | assert_ne!(b, true); | ^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL + assert!(!b); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:107:5 + --> tests/ui/bool_assert_comparison.rs:115:5 | LL | debug_assert_eq!("a".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL + debug_assert!(!"a".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:108:5 + --> tests/ui/bool_assert_comparison.rs:117:5 | LL | debug_assert_eq!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL + debug_assert!("".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:109:5 + --> tests/ui/bool_assert_comparison.rs:119:5 | LL | debug_assert_eq!(true, "".is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL + debug_assert!("".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:114:5 + --> tests/ui/bool_assert_comparison.rs:125:5 | LL | debug_assert_eq!(b, true); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL + debug_assert!(b); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:117:5 + --> tests/ui/bool_assert_comparison.rs:129:5 | LL | debug_assert_ne!("a".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL + debug_assert!("a".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:118:5 + --> tests/ui/bool_assert_comparison.rs:131:5 | LL | debug_assert_ne!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL + debug_assert!(!"".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:119:5 + --> tests/ui/bool_assert_comparison.rs:133:5 | LL | debug_assert_ne!(true, "".is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + debug_assert!(!"".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:124:5 + --> tests/ui/bool_assert_comparison.rs:139:5 | LL | debug_assert_ne!(b, true); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL + debug_assert!(!b); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:129:5 + --> tests/ui/bool_assert_comparison.rs:145:5 | LL | assert_eq!("a".is_empty(), false, "tadam {}", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -205,7 +205,7 @@ LL + assert!(!"a".is_empty(), "tadam {}", 1); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:130:5 + --> tests/ui/bool_assert_comparison.rs:147:5 | LL | assert_eq!("a".is_empty(), false, "tadam {}", true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL + assert!(!"a".is_empty(), "tadam {}", true); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:131:5 + --> tests/ui/bool_assert_comparison.rs:149:5 | LL | assert_eq!(false, "a".is_empty(), "tadam {}", true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -229,7 +229,7 @@ LL + assert!(!"a".is_empty(), "tadam {}", true); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:136:5 + --> tests/ui/bool_assert_comparison.rs:155:5 | LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +241,7 @@ LL + debug_assert!(!"a".is_empty(), "tadam {}", 1); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:137:5 + --> tests/ui/bool_assert_comparison.rs:157:5 | LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL + debug_assert!(!"a".is_empty(), "tadam {}", true); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:138:5 + --> tests/ui/bool_assert_comparison.rs:159:5 | LL | debug_assert_eq!(false, "a".is_empty(), "tadam {}", true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -265,7 +265,7 @@ LL + debug_assert!(!"a".is_empty(), "tadam {}", true); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:141:5 + --> tests/ui/bool_assert_comparison.rs:163:5 | LL | assert_eq!(a!(), true); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -277,7 +277,7 @@ LL + assert!(a!()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:142:5 + --> tests/ui/bool_assert_comparison.rs:165:5 | LL | assert_eq!(true, b!()); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -289,7 +289,7 @@ LL + assert!(b!()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:146:5 + --> tests/ui/bool_assert_comparison.rs:170:5 | LL | renamed!(b, true); | ^^^^^^^^^^^^^^^^^ @@ -301,7 +301,7 @@ LL + debug_assert!(b); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:160:5 + --> tests/ui/bool_assert_comparison.rs:185:5 | LL | assert_eq!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -313,7 +313,7 @@ LL + assert!("".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:161:5 + --> tests/ui/bool_assert_comparison.rs:187:5 | LL | assert_ne!("".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -325,7 +325,7 @@ LL + assert!("".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:162:5 + --> tests/ui/bool_assert_comparison.rs:189:5 | LL | assert_ne!("requires negation".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -337,7 +337,7 @@ LL + assert!(!"requires negation".is_empty()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:163:5 + --> tests/ui/bool_assert_comparison.rs:191:5 | LL | assert_eq!("requires negation".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -349,7 +349,7 @@ LL + assert!(!"requires negation".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:165:5 + --> tests/ui/bool_assert_comparison.rs:194:5 | LL | debug_assert_eq!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -361,7 +361,7 @@ LL + debug_assert!("".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:166:5 + --> tests/ui/bool_assert_comparison.rs:196:5 | LL | debug_assert_ne!("".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -373,7 +373,7 @@ LL + debug_assert!("".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:167:5 + --> tests/ui/bool_assert_comparison.rs:198:5 | LL | debug_assert_ne!("requires negation".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -385,7 +385,7 @@ LL + debug_assert!(!"requires negation".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:168:5 + --> tests/ui/bool_assert_comparison.rs:200:5 | LL | debug_assert_eq!("requires negation".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/bool_comparison.fixed b/tests/ui/bool_comparison.fixed index 3db91eec8fa7..724bf9253d33 100644 --- a/tests/ui/bool_comparison.fixed +++ b/tests/ui/bool_comparison.fixed @@ -5,72 +5,86 @@ fn main() { let x = true; if x { + //~^ bool_comparison "yes" } else { "no" }; if !x { + //~^ bool_comparison "yes" } else { "no" }; if x { + //~^ bool_comparison "yes" } else { "no" }; if !x { + //~^ bool_comparison "yes" } else { "no" }; if !x { + //~^ bool_comparison "yes" } else { "no" }; if x { + //~^ bool_comparison "yes" } else { "no" }; if !x { + //~^ bool_comparison "yes" } else { "no" }; if x { + //~^ bool_comparison "yes" } else { "no" }; if !x { + //~^ bool_comparison "yes" } else { "no" }; if x { + //~^ bool_comparison "yes" } else { "no" }; if x { + //~^ bool_comparison "yes" } else { "no" }; if !x { + //~^ bool_comparison "yes" } else { "no" }; let y = true; if !x & y { + //~^ bool_comparison "yes" } else { "no" }; if x & !y { + //~^ bool_comparison "yes" } else { "no" @@ -119,12 +133,16 @@ fn issue4983() { let b = false; if a != b {}; + //~^ bool_comparison if a != b {}; + //~^ bool_comparison if a == b {}; if !a == !b {}; if b != a {}; + //~^ bool_comparison if b != a {}; + //~^ bool_comparison if b == a {}; if !b == !a {}; } @@ -149,9 +167,13 @@ fn issue3973() { // lint, could be simplified if !m!(func) {} + //~^ bool_comparison if !m!(func) {} + //~^ bool_comparison if m!(func) {} + //~^ bool_comparison if m!(func) {} + //~^ bool_comparison // no lint with a variable let is_debug = false; @@ -169,8 +191,11 @@ fn issue3973() { #[allow(clippy::unnecessary_cast)] fn issue9907() { let _ = (1 >= 2) as usize; + //~^ bool_comparison let _ = (!m!(func)) as usize; + //~^ bool_comparison // This is not part of the issue, but an unexpected found when fixing the issue, // the provided span was inside of macro rather than the macro callsite. let _ = ((1 < 2) != m!(func)) as usize; + //~^ bool_comparison } diff --git a/tests/ui/bool_comparison.rs b/tests/ui/bool_comparison.rs index fbcfb1cee7bf..6d11f9efe569 100644 --- a/tests/ui/bool_comparison.rs +++ b/tests/ui/bool_comparison.rs @@ -5,72 +5,86 @@ fn main() { let x = true; if x == true { + //~^ bool_comparison "yes" } else { "no" }; if x == false { + //~^ bool_comparison "yes" } else { "no" }; if true == x { + //~^ bool_comparison "yes" } else { "no" }; if false == x { + //~^ bool_comparison "yes" } else { "no" }; if x != true { + //~^ bool_comparison "yes" } else { "no" }; if x != false { + //~^ bool_comparison "yes" } else { "no" }; if true != x { + //~^ bool_comparison "yes" } else { "no" }; if false != x { + //~^ bool_comparison "yes" } else { "no" }; if x < true { + //~^ bool_comparison "yes" } else { "no" }; if false < x { + //~^ bool_comparison "yes" } else { "no" }; if x > false { + //~^ bool_comparison "yes" } else { "no" }; if true > x { + //~^ bool_comparison "yes" } else { "no" }; let y = true; if x < y { + //~^ bool_comparison "yes" } else { "no" }; if x > y { + //~^ bool_comparison "yes" } else { "no" @@ -119,12 +133,16 @@ fn issue4983() { let b = false; if a == !b {}; + //~^ bool_comparison if !a == b {}; + //~^ bool_comparison if a == b {}; if !a == !b {}; if b == !a {}; + //~^ bool_comparison if !b == a {}; + //~^ bool_comparison if b == a {}; if !b == !a {}; } @@ -149,9 +167,13 @@ fn issue3973() { // lint, could be simplified if false == m!(func) {} + //~^ bool_comparison if m!(func) == false {} + //~^ bool_comparison if true == m!(func) {} + //~^ bool_comparison if m!(func) == true {} + //~^ bool_comparison // no lint with a variable let is_debug = false; @@ -169,8 +191,11 @@ fn issue3973() { #[allow(clippy::unnecessary_cast)] fn issue9907() { let _ = ((1 < 2) == false) as usize; + //~^ bool_comparison let _ = (false == m!(func)) as usize; + //~^ bool_comparison // This is not part of the issue, but an unexpected found when fixing the issue, // the provided span was inside of macro rather than the macro callsite. let _ = ((1 < 2) == !m!(func)) as usize; + //~^ bool_comparison } diff --git a/tests/ui/bool_comparison.stderr b/tests/ui/bool_comparison.stderr index 7c8b906221fa..ddbb9ff78edb 100644 --- a/tests/ui/bool_comparison.stderr +++ b/tests/ui/bool_comparison.stderr @@ -8,145 +8,145 @@ LL | if x == true { = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]` error: equality checks against false can be replaced by a negation - --> tests/ui/bool_comparison.rs:12:8 + --> tests/ui/bool_comparison.rs:13:8 | LL | if x == false { | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: equality checks against true are unnecessary - --> tests/ui/bool_comparison.rs:17:8 + --> tests/ui/bool_comparison.rs:19:8 | LL | if true == x { | ^^^^^^^^^ help: try simplifying it as shown: `x` error: equality checks against false can be replaced by a negation - --> tests/ui/bool_comparison.rs:22:8 + --> tests/ui/bool_comparison.rs:25:8 | LL | if false == x { | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: inequality checks against true can be replaced by a negation - --> tests/ui/bool_comparison.rs:27:8 + --> tests/ui/bool_comparison.rs:31:8 | LL | if x != true { | ^^^^^^^^^ help: try simplifying it as shown: `!x` error: inequality checks against false are unnecessary - --> tests/ui/bool_comparison.rs:32:8 + --> tests/ui/bool_comparison.rs:37:8 | LL | if x != false { | ^^^^^^^^^^ help: try simplifying it as shown: `x` error: inequality checks against true can be replaced by a negation - --> tests/ui/bool_comparison.rs:37:8 + --> tests/ui/bool_comparison.rs:43:8 | LL | if true != x { | ^^^^^^^^^ help: try simplifying it as shown: `!x` error: inequality checks against false are unnecessary - --> tests/ui/bool_comparison.rs:42:8 + --> tests/ui/bool_comparison.rs:49:8 | LL | if false != x { | ^^^^^^^^^^ help: try simplifying it as shown: `x` error: less than comparison against true can be replaced by a negation - --> tests/ui/bool_comparison.rs:47:8 + --> tests/ui/bool_comparison.rs:55:8 | LL | if x < true { | ^^^^^^^^ help: try simplifying it as shown: `!x` error: greater than checks against false are unnecessary - --> tests/ui/bool_comparison.rs:52:8 + --> tests/ui/bool_comparison.rs:61:8 | LL | if false < x { | ^^^^^^^^^ help: try simplifying it as shown: `x` error: greater than checks against false are unnecessary - --> tests/ui/bool_comparison.rs:57:8 + --> tests/ui/bool_comparison.rs:67:8 | LL | if x > false { | ^^^^^^^^^ help: try simplifying it as shown: `x` error: less than comparison against true can be replaced by a negation - --> tests/ui/bool_comparison.rs:62:8 + --> tests/ui/bool_comparison.rs:73:8 | LL | if true > x { | ^^^^^^^^ help: try simplifying it as shown: `!x` error: order comparisons between booleans can be simplified - --> tests/ui/bool_comparison.rs:68:8 + --> tests/ui/bool_comparison.rs:80:8 | LL | if x < y { | ^^^^^ help: try simplifying it as shown: `!x & y` error: order comparisons between booleans can be simplified - --> tests/ui/bool_comparison.rs:73:8 + --> tests/ui/bool_comparison.rs:86:8 | LL | if x > y { | ^^^^^ help: try simplifying it as shown: `x & !y` error: this comparison might be written more concisely - --> tests/ui/bool_comparison.rs:121:8 + --> tests/ui/bool_comparison.rs:135:8 | LL | if a == !b {}; | ^^^^^^^ help: try simplifying it as shown: `a != b` error: this comparison might be written more concisely - --> tests/ui/bool_comparison.rs:122:8 + --> tests/ui/bool_comparison.rs:137:8 | LL | if !a == b {}; | ^^^^^^^ help: try simplifying it as shown: `a != b` error: this comparison might be written more concisely - --> tests/ui/bool_comparison.rs:126:8 + --> tests/ui/bool_comparison.rs:142:8 | LL | if b == !a {}; | ^^^^^^^ help: try simplifying it as shown: `b != a` error: this comparison might be written more concisely - --> tests/ui/bool_comparison.rs:127:8 + --> tests/ui/bool_comparison.rs:144:8 | LL | if !b == a {}; | ^^^^^^^ help: try simplifying it as shown: `b != a` error: equality checks against false can be replaced by a negation - --> tests/ui/bool_comparison.rs:151:8 + --> tests/ui/bool_comparison.rs:169:8 | LL | if false == m!(func) {} | ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)` error: equality checks against false can be replaced by a negation - --> tests/ui/bool_comparison.rs:152:8 + --> tests/ui/bool_comparison.rs:171:8 | LL | if m!(func) == false {} | ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)` error: equality checks against true are unnecessary - --> tests/ui/bool_comparison.rs:153:8 + --> tests/ui/bool_comparison.rs:173:8 | LL | if true == m!(func) {} | ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `m!(func)` error: equality checks against true are unnecessary - --> tests/ui/bool_comparison.rs:154:8 + --> tests/ui/bool_comparison.rs:175:8 | LL | if m!(func) == true {} | ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `m!(func)` error: equality checks against false can be replaced by a negation - --> tests/ui/bool_comparison.rs:171:14 + --> tests/ui/bool_comparison.rs:193:14 | LL | let _ = ((1 < 2) == false) as usize; | ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `1 >= 2` error: equality checks against false can be replaced by a negation - --> tests/ui/bool_comparison.rs:172:14 + --> tests/ui/bool_comparison.rs:195:14 | LL | let _ = (false == m!(func)) as usize; | ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)` error: this comparison might be written more concisely - --> tests/ui/bool_comparison.rs:175:14 + --> tests/ui/bool_comparison.rs:199:14 | LL | let _ = ((1 < 2) == !m!(func)) as usize; | ^^^^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `(1 < 2) != m!(func)` diff --git a/tests/ui/bool_to_int_with_if.fixed b/tests/ui/bool_to_int_with_if.fixed index f7dad28b0369..0080801d46b7 100644 --- a/tests/ui/bool_to_int_with_if.fixed +++ b/tests/ui/bool_to_int_with_if.fixed @@ -88,6 +88,7 @@ fn main() { // Lint returns and type inference fn some_fn(a: bool) -> u8 { u8::from(a) + //~^ bool_to_int_with_if } fn side_effect() {} diff --git a/tests/ui/bool_to_int_with_if.rs b/tests/ui/bool_to_int_with_if.rs index d22871d2c8f2..d12b0af5312e 100644 --- a/tests/ui/bool_to_int_with_if.rs +++ b/tests/ui/bool_to_int_with_if.rs @@ -12,31 +12,37 @@ fn main() { // Should lint // precedence if a { + //~^ bool_to_int_with_if 1 } else { 0 }; if a { + //~^ bool_to_int_with_if 0 } else { 1 }; if !a { + //~^ bool_to_int_with_if 1 } else { 0 }; if a || b { + //~^ bool_to_int_with_if 1 } else { 0 }; if cond(a, b) { + //~^ bool_to_int_with_if 1 } else { 0 }; if x + y < 4 { + //~^ bool_to_int_with_if 1 } else { 0 @@ -46,6 +52,7 @@ fn main() { if a { 123 } else if b { + //~^ bool_to_int_with_if 1 } else { 0 @@ -55,6 +62,7 @@ fn main() { if a { 123 } else if b { + //~^ bool_to_int_with_if 0 } else { 1 @@ -120,6 +128,7 @@ fn main() { // Lint returns and type inference fn some_fn(a: bool) -> u8 { if a { 1 } else { 0 } + //~^ bool_to_int_with_if } fn side_effect() {} diff --git a/tests/ui/bool_to_int_with_if.stderr b/tests/ui/bool_to_int_with_if.stderr index 1e4a843071a1..415e80f8d73d 100644 --- a/tests/ui/bool_to_int_with_if.stderr +++ b/tests/ui/bool_to_int_with_if.stderr @@ -2,6 +2,7 @@ error: boolean to int conversion using if --> tests/ui/bool_to_int_with_if.rs:14:5 | LL | / if a { +LL | | LL | | 1 LL | | } else { LL | | 0 @@ -13,9 +14,10 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::bool_to_int_with_if)]` error: boolean to int conversion using if - --> tests/ui/bool_to_int_with_if.rs:19:5 + --> tests/ui/bool_to_int_with_if.rs:20:5 | LL | / if a { +LL | | LL | | 0 LL | | } else { LL | | 1 @@ -25,9 +27,10 @@ LL | | }; = note: `!a as i32` or `(!a).into()` can also be valid options error: boolean to int conversion using if - --> tests/ui/bool_to_int_with_if.rs:24:5 + --> tests/ui/bool_to_int_with_if.rs:26:5 | LL | / if !a { +LL | | LL | | 1 LL | | } else { LL | | 0 @@ -37,9 +40,10 @@ LL | | }; = note: `!a as i32` or `(!a).into()` can also be valid options error: boolean to int conversion using if - --> tests/ui/bool_to_int_with_if.rs:29:5 + --> tests/ui/bool_to_int_with_if.rs:32:5 | LL | / if a || b { +LL | | LL | | 1 LL | | } else { LL | | 0 @@ -49,9 +53,10 @@ LL | | }; = note: `(a || b) as i32` or `(a || b).into()` can also be valid options error: boolean to int conversion using if - --> tests/ui/bool_to_int_with_if.rs:34:5 + --> tests/ui/bool_to_int_with_if.rs:38:5 | LL | / if cond(a, b) { +LL | | LL | | 1 LL | | } else { LL | | 0 @@ -61,9 +66,10 @@ LL | | }; = note: `cond(a, b) as i32` or `cond(a, b).into()` can also be valid options error: boolean to int conversion using if - --> tests/ui/bool_to_int_with_if.rs:39:5 + --> tests/ui/bool_to_int_with_if.rs:44:5 | LL | / if x + y < 4 { +LL | | LL | | 1 LL | | } else { LL | | 0 @@ -73,10 +79,11 @@ LL | | }; = note: `(x + y < 4) as i32` or `(x + y < 4).into()` can also be valid options error: boolean to int conversion using if - --> tests/ui/bool_to_int_with_if.rs:48:12 + --> tests/ui/bool_to_int_with_if.rs:54:12 | LL | } else if b { | ____________^ +LL | | LL | | 1 LL | | } else { LL | | 0 @@ -86,10 +93,11 @@ LL | | }; = note: `b as i32` or `b.into()` can also be valid options error: boolean to int conversion using if - --> tests/ui/bool_to_int_with_if.rs:57:12 + --> tests/ui/bool_to_int_with_if.rs:64:12 | LL | } else if b { | ____________^ +LL | | LL | | 0 LL | | } else { LL | | 1 @@ -99,7 +107,7 @@ LL | | }; = note: `!b as i32` or `(!b).into()` can also be valid options error: boolean to int conversion using if - --> tests/ui/bool_to_int_with_if.rs:122:5 + --> tests/ui/bool_to_int_with_if.rs:130:5 | LL | if a { 1 } else { 0 } | ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)` diff --git a/tests/ui/borrow_and_ref_as_ptr.fixed b/tests/ui/borrow_and_ref_as_ptr.fixed index 2950b158deb6..b7ee4c6165a7 100644 --- a/tests/ui/borrow_and_ref_as_ptr.fixed +++ b/tests/ui/borrow_and_ref_as_ptr.fixed @@ -7,5 +7,7 @@ fn f(_: T) {} fn main() { let mut val = 0; f(&raw const val); + //~^ borrow_as_ptr f(&raw mut val); + //~^ borrow_as_ptr } diff --git a/tests/ui/borrow_and_ref_as_ptr.rs b/tests/ui/borrow_and_ref_as_ptr.rs index 19eb8f292337..d16ed5aa7b29 100644 --- a/tests/ui/borrow_and_ref_as_ptr.rs +++ b/tests/ui/borrow_and_ref_as_ptr.rs @@ -7,5 +7,7 @@ fn f(_: T) {} fn main() { let mut val = 0; f(&val as *const _); + //~^ borrow_as_ptr f(&mut val as *mut i32); + //~^ borrow_as_ptr } diff --git a/tests/ui/borrow_and_ref_as_ptr.stderr b/tests/ui/borrow_and_ref_as_ptr.stderr index 82a27af303c2..e02f3d8bed97 100644 --- a/tests/ui/borrow_and_ref_as_ptr.stderr +++ b/tests/ui/borrow_and_ref_as_ptr.stderr @@ -8,7 +8,7 @@ LL | f(&val as *const _); = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]` error: borrow as raw pointer - --> tests/ui/borrow_and_ref_as_ptr.rs:10:7 + --> tests/ui/borrow_and_ref_as_ptr.rs:11:7 | LL | f(&mut val as *mut i32); | ^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut val` diff --git a/tests/ui/borrow_as_ptr.fixed b/tests/ui/borrow_as_ptr.fixed index 5365f3dd443c..3dca06fce4b8 100644 --- a/tests/ui/borrow_as_ptr.fixed +++ b/tests/ui/borrow_as_ptr.fixed @@ -9,6 +9,7 @@ fn a() -> i32 { fn main() { let val = 1; let _p = std::ptr::addr_of!(val); + //~^ borrow_as_ptr let _p = &0 as *const i32; let _p = &a() as *const i32; let vec = vec![1]; @@ -16,12 +17,15 @@ fn main() { let mut val_mut = 1; let _p_mut = std::ptr::addr_of_mut!(val_mut); + //~^ borrow_as_ptr let mut x: [i32; 2] = [42, 43]; let _raw = std::ptr::addr_of_mut!(x[1]).wrapping_offset(-1); + //~^ borrow_as_ptr } fn issue_13882() { let mut x: [i32; 2] = [42, 43]; let _raw = (&raw mut x[1]).wrapping_offset(-1); + //~^ borrow_as_ptr } diff --git a/tests/ui/borrow_as_ptr.rs b/tests/ui/borrow_as_ptr.rs index 261894f1341c..3559dc23d018 100644 --- a/tests/ui/borrow_as_ptr.rs +++ b/tests/ui/borrow_as_ptr.rs @@ -9,6 +9,7 @@ fn a() -> i32 { fn main() { let val = 1; let _p = &val as *const i32; + //~^ borrow_as_ptr let _p = &0 as *const i32; let _p = &a() as *const i32; let vec = vec![1]; @@ -16,12 +17,15 @@ fn main() { let mut val_mut = 1; let _p_mut = &mut val_mut as *mut i32; + //~^ borrow_as_ptr let mut x: [i32; 2] = [42, 43]; let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1); + //~^ borrow_as_ptr } fn issue_13882() { let mut x: [i32; 2] = [42, 43]; let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1); + //~^ borrow_as_ptr } diff --git a/tests/ui/borrow_as_ptr.stderr b/tests/ui/borrow_as_ptr.stderr index 4595fa4f2487..4a9f2ed4aa00 100644 --- a/tests/ui/borrow_as_ptr.stderr +++ b/tests/ui/borrow_as_ptr.stderr @@ -8,19 +8,19 @@ LL | let _p = &val as *const i32; = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]` error: borrow as raw pointer - --> tests/ui/borrow_as_ptr.rs:18:18 + --> tests/ui/borrow_as_ptr.rs:19:18 | LL | let _p_mut = &mut val_mut as *mut i32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of_mut!(val_mut)` error: borrow as raw pointer - --> tests/ui/borrow_as_ptr.rs:21:16 + --> tests/ui/borrow_as_ptr.rs:23:16 | LL | let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of_mut!(x[1])` error: borrow as raw pointer - --> tests/ui/borrow_as_ptr.rs:26:17 + --> tests/ui/borrow_as_ptr.rs:29:17 | LL | let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut x[1]` diff --git a/tests/ui/borrow_as_ptr_no_std.fixed b/tests/ui/borrow_as_ptr_no_std.fixed index 26c6a5033d16..8972fc0a5e0d 100644 --- a/tests/ui/borrow_as_ptr_no_std.fixed +++ b/tests/ui/borrow_as_ptr_no_std.fixed @@ -6,8 +6,10 @@ pub fn main(_argc: isize, _argv: *const *const u8) -> isize { let val = 1; let _p = core::ptr::addr_of!(val); + //~^ borrow_as_ptr let mut val_mut = 1; let _p_mut = core::ptr::addr_of_mut!(val_mut); + //~^ borrow_as_ptr 0 } diff --git a/tests/ui/borrow_as_ptr_no_std.rs b/tests/ui/borrow_as_ptr_no_std.rs index d8d8b4c380ce..6b4c732dc56e 100644 --- a/tests/ui/borrow_as_ptr_no_std.rs +++ b/tests/ui/borrow_as_ptr_no_std.rs @@ -6,8 +6,10 @@ pub fn main(_argc: isize, _argv: *const *const u8) -> isize { let val = 1; let _p = &val as *const i32; + //~^ borrow_as_ptr let mut val_mut = 1; let _p_mut = &mut val_mut as *mut i32; + //~^ borrow_as_ptr 0 } diff --git a/tests/ui/borrow_as_ptr_no_std.stderr b/tests/ui/borrow_as_ptr_no_std.stderr index 488e0bd96776..6012577559d0 100644 --- a/tests/ui/borrow_as_ptr_no_std.stderr +++ b/tests/ui/borrow_as_ptr_no_std.stderr @@ -8,7 +8,7 @@ LL | let _p = &val as *const i32; = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]` error: borrow as raw pointer - --> tests/ui/borrow_as_ptr_no_std.rs:11:18 + --> tests/ui/borrow_as_ptr_no_std.rs:12:18 | LL | let _p_mut = &mut val_mut as *mut i32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of_mut!(val_mut)` diff --git a/tests/ui/borrow_as_ptr_raw_ref.fixed b/tests/ui/borrow_as_ptr_raw_ref.fixed index d6842e60a3e9..7fbb942b5bc7 100644 --- a/tests/ui/borrow_as_ptr_raw_ref.fixed +++ b/tests/ui/borrow_as_ptr_raw_ref.fixed @@ -9,6 +9,7 @@ fn a() -> i32 { fn main() { let val = 1; let _p = &raw const val; + //~^ borrow_as_ptr let _p = &0 as *const i32; let _p = &a() as *const i32; let vec = vec![1]; @@ -16,4 +17,5 @@ fn main() { let mut val_mut = 1; let _p_mut = &raw mut val_mut; + //~^ borrow_as_ptr } diff --git a/tests/ui/borrow_as_ptr_raw_ref.rs b/tests/ui/borrow_as_ptr_raw_ref.rs index 3c9daed18f15..9cbf2e5c266d 100644 --- a/tests/ui/borrow_as_ptr_raw_ref.rs +++ b/tests/ui/borrow_as_ptr_raw_ref.rs @@ -9,6 +9,7 @@ fn a() -> i32 { fn main() { let val = 1; let _p = &val as *const i32; + //~^ borrow_as_ptr let _p = &0 as *const i32; let _p = &a() as *const i32; let vec = vec![1]; @@ -16,4 +17,5 @@ fn main() { let mut val_mut = 1; let _p_mut = &mut val_mut as *mut i32; + //~^ borrow_as_ptr } diff --git a/tests/ui/borrow_as_ptr_raw_ref.stderr b/tests/ui/borrow_as_ptr_raw_ref.stderr index 5611fcae8d4b..e5c8aec77986 100644 --- a/tests/ui/borrow_as_ptr_raw_ref.stderr +++ b/tests/ui/borrow_as_ptr_raw_ref.stderr @@ -8,7 +8,7 @@ LL | let _p = &val as *const i32; = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]` error: borrow as raw pointer - --> tests/ui/borrow_as_ptr_raw_ref.rs:18:18 + --> tests/ui/borrow_as_ptr_raw_ref.rs:19:18 | LL | let _p_mut = &mut val_mut as *mut i32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut val_mut` diff --git a/tests/ui/borrow_box.fixed b/tests/ui/borrow_box.fixed index 08ea60583ea4..4529138c0edc 100644 --- a/tests/ui/borrow_box.fixed +++ b/tests/ui/borrow_box.fixed @@ -23,17 +23,20 @@ pub fn test1(foo: &mut Box) { pub fn test2() { let foo: &bool; - //~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` + //~^ borrowed_box + } struct Test3<'a> { foo: &'a bool, - //~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` + //~^ borrowed_box + } trait Test4 { fn test4(a: &bool); - //~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` + //~^ borrowed_box + } use std::any::Any; @@ -94,24 +97,31 @@ pub fn test13(boxed_slice: &mut Box<[i32]>) { // The suggestion should include proper parentheses to avoid a syntax error. pub fn test14(_display: &dyn Display) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test15(_display: &(dyn Display + Send)) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test16<'a>(_display: &'a (dyn Display + 'a)) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test17(_display: &impl Display) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test18(_display: &(impl Display + Send)) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test19<'a>(_display: &'a (impl Display + 'a)) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + // This exists only to check what happens when parentheses are already present. // Even though the current implementation doesn't put extra parentheses, // it's fine that unnecessary parentheses appear in the future for some reason. pub fn test20(_display: &(dyn Display + Send)) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + #[allow(clippy::borrowed_box)] trait Trait { diff --git a/tests/ui/borrow_box.rs b/tests/ui/borrow_box.rs index b55de1701daa..3f2a0168ef42 100644 --- a/tests/ui/borrow_box.rs +++ b/tests/ui/borrow_box.rs @@ -23,17 +23,20 @@ pub fn test1(foo: &mut Box) { pub fn test2() { let foo: &Box; - //~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` + //~^ borrowed_box + } struct Test3<'a> { foo: &'a Box, - //~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` + //~^ borrowed_box + } trait Test4 { fn test4(a: &Box); - //~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` + //~^ borrowed_box + } use std::any::Any; @@ -94,24 +97,31 @@ pub fn test13(boxed_slice: &mut Box<[i32]>) { // The suggestion should include proper parentheses to avoid a syntax error. pub fn test14(_display: &Box) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test15(_display: &Box) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test16<'a>(_display: &'a Box) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test17(_display: &Box) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test18(_display: &Box) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + pub fn test19<'a>(_display: &'a Box) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + // This exists only to check what happens when parentheses are already present. // Even though the current implementation doesn't put extra parentheses, // it's fine that unnecessary parentheses appear in the future for some reason. pub fn test20(_display: &Box<(dyn Display + Send)>) {} -//~^ ERROR: you seem to be trying to use `&Box`. Consider using just `&T` +//~^ borrowed_box + #[allow(clippy::borrowed_box)] trait Trait { diff --git a/tests/ui/borrow_box.stderr b/tests/ui/borrow_box.stderr index 6f80f86c3b3d..e23e49f1c88b 100644 --- a/tests/ui/borrow_box.stderr +++ b/tests/ui/borrow_box.stderr @@ -11,55 +11,55 @@ LL | #![deny(clippy::borrowed_box)] | ^^^^^^^^^^^^^^^^^^^^ error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:30:10 + --> tests/ui/borrow_box.rs:31:10 | LL | foo: &'a Box, | ^^^^^^^^^^^^^ help: try: `&'a bool` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:35:17 + --> tests/ui/borrow_box.rs:37:17 | LL | fn test4(a: &Box); | ^^^^^^^^^^ help: try: `&bool` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:96:25 + --> tests/ui/borrow_box.rs:99:25 | LL | pub fn test14(_display: &Box) {} | ^^^^^^^^^^^^^^^^^ help: try: `&dyn Display` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:98:25 + --> tests/ui/borrow_box.rs:102:25 | LL | pub fn test15(_display: &Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:100:29 + --> tests/ui/borrow_box.rs:105:29 | LL | pub fn test16<'a>(_display: &'a Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (dyn Display + 'a)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:103:25 + --> tests/ui/borrow_box.rs:109:25 | LL | pub fn test17(_display: &Box) {} | ^^^^^^^^^^^^^^^^^^ help: try: `&impl Display` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:105:25 + --> tests/ui/borrow_box.rs:112:25 | LL | pub fn test18(_display: &Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(impl Display + Send)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:107:29 + --> tests/ui/borrow_box.rs:115:29 | LL | pub fn test19<'a>(_display: &'a Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (impl Display + 'a)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:113:25 + --> tests/ui/borrow_box.rs:122:25 | LL | pub fn test20(_display: &Box<(dyn Display + Send)>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)` diff --git a/tests/ui/borrow_deref_ref.fixed b/tests/ui/borrow_deref_ref.fixed index 22e984c46d24..93cd3e3b5e59 100644 --- a/tests/ui/borrow_deref_ref.fixed +++ b/tests/ui/borrow_deref_ref.fixed @@ -11,8 +11,10 @@ mod should_lint { fn one_help() { let a = &12; let b = a; + //~^ borrow_deref_ref let b = &mut bar(&12); + //~^ borrow_deref_ref } fn bar(x: &u32) -> &u32 { @@ -67,6 +69,7 @@ mod false_negative { let x = &12; let addr_x = &x as *const _ as usize; let addr_y = &x as *const _ as usize; // assert ok + //~^ borrow_deref_ref // let addr_y = &x as *const _ as usize; // assert fail assert_ne!(addr_x, addr_y); } diff --git a/tests/ui/borrow_deref_ref.rs b/tests/ui/borrow_deref_ref.rs index 61d89193f42f..1e41d24998f9 100644 --- a/tests/ui/borrow_deref_ref.rs +++ b/tests/ui/borrow_deref_ref.rs @@ -11,8 +11,10 @@ mod should_lint { fn one_help() { let a = &12; let b = &*a; + //~^ borrow_deref_ref let b = &mut &*bar(&12); + //~^ borrow_deref_ref } fn bar(x: &u32) -> &u32 { @@ -67,6 +69,7 @@ mod false_negative { let x = &12; let addr_x = &x as *const _ as usize; let addr_y = &&*x as *const _ as usize; // assert ok + //~^ borrow_deref_ref // let addr_y = &x as *const _ as usize; // assert fail assert_ne!(addr_x, addr_y); } diff --git a/tests/ui/borrow_deref_ref.stderr b/tests/ui/borrow_deref_ref.stderr index 7fa43ef49cf7..f5868aa87490 100644 --- a/tests/ui/borrow_deref_ref.stderr +++ b/tests/ui/borrow_deref_ref.stderr @@ -8,13 +8,13 @@ LL | let b = &*a; = help: to override `-D warnings` add `#[allow(clippy::borrow_deref_ref)]` error: deref on an immutable reference - --> tests/ui/borrow_deref_ref.rs:15:22 + --> tests/ui/borrow_deref_ref.rs:16:22 | LL | let b = &mut &*bar(&12); | ^^^^^^^^^^ help: if you would like to reborrow, try removing `&*`: `bar(&12)` error: deref on an immutable reference - --> tests/ui/borrow_deref_ref.rs:69:23 + --> tests/ui/borrow_deref_ref.rs:71:23 | LL | let addr_y = &&*x as *const _ as usize; // assert ok | ^^^ help: if you would like to reborrow, try removing `&*`: `x` diff --git a/tests/ui/borrow_deref_ref_unfixable.rs b/tests/ui/borrow_deref_ref_unfixable.rs index be9887339597..e51d9912b308 100644 --- a/tests/ui/borrow_deref_ref_unfixable.rs +++ b/tests/ui/borrow_deref_ref_unfixable.rs @@ -7,7 +7,8 @@ mod should_lint { fn two_helps() { let s = &String::new(); let x: &str = &*s; - //~^ ERROR: deref on an immutable reference - //~| NOTE: `-D clippy::borrow-deref-ref` implied by `-D warnings` + //~^ borrow_deref_ref + + } } diff --git a/tests/ui/borrow_interior_mutable_const/others.rs b/tests/ui/borrow_interior_mutable_const/others.rs index a49d53fbbd38..eaf90ce6a8dd 100644 --- a/tests/ui/borrow_interior_mutable_const/others.rs +++ b/tests/ui/borrow_interior_mutable_const/others.rs @@ -62,14 +62,20 @@ mod issue12979 { const CELL_REF: StaticRef<(UnsafeCell,)> = unsafe { StaticRef::new(std::ptr::null()) }; fn main() { - ATOMIC.store(1, Ordering::SeqCst); //~ ERROR: interior mutability - assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR: interior mutability +ATOMIC.store(1, Ordering::SeqCst); +//~^ borrow_interior_mutable_const +assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); +//~^ borrow_interior_mutable_const let _once = ONCE_INIT; - let _once_ref = &ONCE_INIT; //~ ERROR: interior mutability - let _once_ref_2 = &&ONCE_INIT; //~ ERROR: interior mutability - let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR: interior mutability - let _once_mut = &mut ONCE_INIT; //~ ERROR: interior mutability +let _once_ref = &ONCE_INIT; +//~^ borrow_interior_mutable_const +let _once_ref_2 = &&ONCE_INIT; +//~^ borrow_interior_mutable_const +let _once_ref_4 = &&&&ONCE_INIT; +//~^ borrow_interior_mutable_const +let _once_mut = &mut ONCE_INIT; +//~^ borrow_interior_mutable_const let _atomic_into_inner = ATOMIC.into_inner(); // these should be all fine. let _twice = (ONCE_INIT, ONCE_INIT); @@ -80,22 +86,30 @@ fn main() { let _ref_array_once = &[ONCE_INIT, ONCE_INIT][0]; // referencing projection is still bad. - let _ = &ATOMIC_TUPLE; //~ ERROR: interior mutability - let _ = &ATOMIC_TUPLE.0; //~ ERROR: interior mutability - let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR: interior mutability - let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR: interior mutability - let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR: interior mutability +let _ = &ATOMIC_TUPLE; +//~^ borrow_interior_mutable_const +let _ = &ATOMIC_TUPLE.0; +//~^ borrow_interior_mutable_const +let _ = &(&&&&ATOMIC_TUPLE).0; +//~^ borrow_interior_mutable_const +let _ = &ATOMIC_TUPLE.0[0]; +//~^ borrow_interior_mutable_const +let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); +//~^ borrow_interior_mutable_const let _ = &ATOMIC_TUPLE.2; let _ = (&&&&ATOMIC_TUPLE).0; let _ = (&&&&ATOMIC_TUPLE).2; let _ = ATOMIC_TUPLE.0; - let _ = ATOMIC_TUPLE.0[0]; //~ ERROR: interior mutability +let _ = ATOMIC_TUPLE.0[0]; +//~^ borrow_interior_mutable_const let _ = ATOMIC_TUPLE.1.into_iter(); let _ = ATOMIC_TUPLE.2; let _ = &{ ATOMIC_TUPLE }; - CELL.set(2); //~ ERROR: interior mutability - assert_eq!(CELL.get(), 6); //~ ERROR: interior mutability +CELL.set(2); +//~^ borrow_interior_mutable_const +assert_eq!(CELL.get(), 6); +//~^ borrow_interior_mutable_const assert_eq!(INTEGER, 8); assert!(STRING.is_empty()); diff --git a/tests/ui/borrow_interior_mutable_const/others.stderr b/tests/ui/borrow_interior_mutable_const/others.stderr index 4cefcc28008d..f15664030151 100644 --- a/tests/ui/borrow_interior_mutable_const/others.stderr +++ b/tests/ui/borrow_interior_mutable_const/others.stderr @@ -1,8 +1,8 @@ error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:65:5 + --> tests/ui/borrow_interior_mutable_const/others.rs:65:1 | -LL | ATOMIC.store(1, Ordering::SeqCst); - | ^^^^^^ +LL | ATOMIC.store(1, Ordering::SeqCst); + | ^^^^^^ | = help: assign this const to a local or static variable, and use the variable here note: the lint level is defined here @@ -12,106 +12,106 @@ LL | #![deny(clippy::borrow_interior_mutable_const)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:66:16 + --> tests/ui/borrow_interior_mutable_const/others.rs:67:12 | -LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); - | ^^^^^^ +LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); + | ^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:69:22 + --> tests/ui/borrow_interior_mutable_const/others.rs:71:18 | -LL | let _once_ref = &ONCE_INIT; +LL | let _once_ref = &ONCE_INIT; + | ^^^^^^^^^ + | + = help: assign this const to a local or static variable, and use the variable here + +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/others.rs:73:21 + | +LL | let _once_ref_2 = &&ONCE_INIT; + | ^^^^^^^^^ + | + = help: assign this const to a local or static variable, and use the variable here + +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/others.rs:75:23 + | +LL | let _once_ref_4 = &&&&ONCE_INIT; + | ^^^^^^^^^ + | + = help: assign this const to a local or static variable, and use the variable here + +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/others.rs:77:22 + | +LL | let _once_mut = &mut ONCE_INIT; | ^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:70:25 + --> tests/ui/borrow_interior_mutable_const/others.rs:89:10 | -LL | let _once_ref_2 = &&ONCE_INIT; - | ^^^^^^^^^ +LL | let _ = &ATOMIC_TUPLE; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:71:27 + --> tests/ui/borrow_interior_mutable_const/others.rs:91:10 | -LL | let _once_ref_4 = &&&&ONCE_INIT; - | ^^^^^^^^^ +LL | let _ = &ATOMIC_TUPLE.0; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:72:26 + --> tests/ui/borrow_interior_mutable_const/others.rs:93:15 | -LL | let _once_mut = &mut ONCE_INIT; - | ^^^^^^^^^ +LL | let _ = &(&&&&ATOMIC_TUPLE).0; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:83:14 + --> tests/ui/borrow_interior_mutable_const/others.rs:95:10 | -LL | let _ = &ATOMIC_TUPLE; - | ^^^^^^^^^^^^ +LL | let _ = &ATOMIC_TUPLE.0[0]; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:84:14 + --> tests/ui/borrow_interior_mutable_const/others.rs:97:9 | -LL | let _ = &ATOMIC_TUPLE.0; - | ^^^^^^^^^^^^ +LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:85:19 + --> tests/ui/borrow_interior_mutable_const/others.rs:103:9 | -LL | let _ = &(&&&&ATOMIC_TUPLE).0; - | ^^^^^^^^^^^^ +LL | let _ = ATOMIC_TUPLE.0[0]; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:86:14 + --> tests/ui/borrow_interior_mutable_const/others.rs:109:1 | -LL | let _ = &ATOMIC_TUPLE.0[0]; - | ^^^^^^^^^^^^ +LL | CELL.set(2); + | ^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:87:13 + --> tests/ui/borrow_interior_mutable_const/others.rs:111:12 | -LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); - | ^^^^^^^^^^^^ - | - = help: assign this const to a local or static variable, and use the variable here - -error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:92:13 - | -LL | let _ = ATOMIC_TUPLE.0[0]; - | ^^^^^^^^^^^^ - | - = help: assign this const to a local or static variable, and use the variable here - -error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:97:5 - | -LL | CELL.set(2); - | ^^^^ - | - = help: assign this const to a local or static variable, and use the variable here - -error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:98:16 - | -LL | assert_eq!(CELL.get(), 6); - | ^^^^ +LL | assert_eq!(CELL.get(), 6); + | ^^^^ | = help: assign this const to a local or static variable, and use the variable here diff --git a/tests/ui/borrow_interior_mutable_const/traits.rs b/tests/ui/borrow_interior_mutable_const/traits.rs index 5570e7cd6d2e..8e2b7ffd554f 100644 --- a/tests/ui/borrow_interior_mutable_const/traits.rs +++ b/tests/ui/borrow_interior_mutable_const/traits.rs @@ -12,7 +12,8 @@ trait ConcreteTypes { const STRING: String; fn function() { - let _ = &Self::ATOMIC; //~ ERROR: interior mutability +let _ = &Self::ATOMIC; +//~^ borrow_interior_mutable_const let _ = &Self::STRING; } } @@ -23,7 +24,8 @@ impl ConcreteTypes for u64 { fn function() { // Lint this again since implementers can choose not to borrow it. - let _ = &Self::ATOMIC; //~ ERROR: interior mutability +let _ = &Self::ATOMIC; +//~^ borrow_interior_mutable_const let _ = &Self::STRING; } } @@ -48,7 +50,8 @@ impl GenericTypes for Vec { fn function() { let _ = &Self::TO_REMAIN_GENERIC; - let _ = &Self::TO_BE_CONCRETE; //~ ERROR: interior mutability +let _ = &Self::TO_BE_CONCRETE; +//~^ borrow_interior_mutable_const } } @@ -83,8 +86,10 @@ impl AssocTypes for Vec { fn function() { let _ = &Self::TO_BE_FROZEN; - let _ = &Self::TO_BE_UNFROZEN; //~ ERROR: interior mutability - let _ = &Self::WRAPPED_TO_BE_UNFROZEN; //~ ERROR: interior mutability +let _ = &Self::TO_BE_UNFROZEN; +//~^ borrow_interior_mutable_const +let _ = &Self::WRAPPED_TO_BE_UNFROZEN; +//~^ borrow_interior_mutable_const let _ = &Self::WRAPPED_TO_BE_GENERIC_PARAM; } } @@ -106,7 +111,8 @@ where fn function() { let _ = &Self::NOT_BOUNDED; - let _ = &Self::BOUNDED; //~ ERROR: interior mutability +let _ = &Self::BOUNDED; +//~^ borrow_interior_mutable_const } } @@ -119,7 +125,8 @@ where fn function() { let _ = &Self::NOT_BOUNDED; - let _ = &Self::BOUNDED; //~ ERROR: interior mutability +let _ = &Self::BOUNDED; +//~^ borrow_interior_mutable_const } } @@ -148,8 +155,10 @@ impl SelfType for AtomicUsize { const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); fn function() { - let _ = &Self::SELF; //~ ERROR: interior mutability - let _ = &Self::WRAPPED_SELF; //~ ERROR: interior mutability +let _ = &Self::SELF; +//~^ borrow_interior_mutable_const +let _ = &Self::WRAPPED_SELF; +//~^ borrow_interior_mutable_const } } @@ -158,8 +167,10 @@ trait BothOfCellAndGeneric { const INDIRECT: Cell<*const T>; fn function() { - let _ = &Self::DIRECT; //~ ERROR: interior mutability - let _ = &Self::INDIRECT; //~ ERROR: interior mutability +let _ = &Self::DIRECT; +//~^ borrow_interior_mutable_const +let _ = &Self::INDIRECT; +//~^ borrow_interior_mutable_const } } @@ -168,8 +179,10 @@ impl BothOfCellAndGeneric for Vec { const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null()); fn function() { - let _ = &Self::DIRECT; //~ ERROR: interior mutability - let _ = &Self::INDIRECT; //~ ERROR: interior mutability +let _ = &Self::DIRECT; +//~^ borrow_interior_mutable_const +let _ = &Self::INDIRECT; +//~^ borrow_interior_mutable_const } } @@ -188,15 +201,19 @@ where const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); fn function() { - let _ = &Self::ATOMIC; //~ ERROR: interior mutability +let _ = &Self::ATOMIC; +//~^ borrow_interior_mutable_const let _ = &Self::COW; let _ = &Self::GENERIC_TYPE; let _ = &Self::ASSOC_TYPE; - let _ = &Self::BOUNDED_ASSOC_TYPE; //~ ERROR: interior mutability +let _ = &Self::BOUNDED_ASSOC_TYPE; +//~^ borrow_interior_mutable_const } } fn main() { - u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR: interior mutability - assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR: interior mutability +u64::ATOMIC.store(5, Ordering::SeqCst); +//~^ borrow_interior_mutable_const +assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); +//~^ borrow_interior_mutable_const } diff --git a/tests/ui/borrow_interior_mutable_const/traits.stderr b/tests/ui/borrow_interior_mutable_const/traits.stderr index 8602b46b0dcf..6998ba6fc090 100644 --- a/tests/ui/borrow_interior_mutable_const/traits.stderr +++ b/tests/ui/borrow_interior_mutable_const/traits.stderr @@ -1,8 +1,8 @@ error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:15:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:15:10 | -LL | let _ = &Self::ATOMIC; - | ^^^^^^^^^^^^ +LL | let _ = &Self::ATOMIC; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here note: the lint level is defined here @@ -12,130 +12,130 @@ LL | #![deny(clippy::borrow_interior_mutable_const)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:26:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:27:10 | -LL | let _ = &Self::ATOMIC; - | ^^^^^^^^^^^^ +LL | let _ = &Self::ATOMIC; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:51:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:53:10 | -LL | let _ = &Self::TO_BE_CONCRETE; - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::TO_BE_CONCRETE; + | ^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:86:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:89:10 | -LL | let _ = &Self::TO_BE_UNFROZEN; - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::TO_BE_UNFROZEN; + | ^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:87:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:91:10 | -LL | let _ = &Self::WRAPPED_TO_BE_UNFROZEN; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::WRAPPED_TO_BE_UNFROZEN; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:109:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:114:10 | -LL | let _ = &Self::BOUNDED; - | ^^^^^^^^^^^^^ +LL | let _ = &Self::BOUNDED; + | ^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:122:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:128:10 | -LL | let _ = &Self::BOUNDED; - | ^^^^^^^^^^^^^ +LL | let _ = &Self::BOUNDED; + | ^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:151:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:158:10 | -LL | let _ = &Self::SELF; - | ^^^^^^^^^^ +LL | let _ = &Self::SELF; + | ^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:152:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:160:10 | -LL | let _ = &Self::WRAPPED_SELF; - | ^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::WRAPPED_SELF; + | ^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:161:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:170:10 | -LL | let _ = &Self::DIRECT; - | ^^^^^^^^^^^^ +LL | let _ = &Self::DIRECT; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:162:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:172:10 | -LL | let _ = &Self::INDIRECT; - | ^^^^^^^^^^^^^^ +LL | let _ = &Self::INDIRECT; + | ^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:171:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:182:10 | -LL | let _ = &Self::DIRECT; - | ^^^^^^^^^^^^ +LL | let _ = &Self::DIRECT; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:172:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:184:10 | -LL | let _ = &Self::INDIRECT; - | ^^^^^^^^^^^^^^ +LL | let _ = &Self::INDIRECT; + | ^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:191:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:204:10 | -LL | let _ = &Self::ATOMIC; - | ^^^^^^^^^^^^ +LL | let _ = &Self::ATOMIC; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:195:18 + --> tests/ui/borrow_interior_mutable_const/traits.rs:209:10 | -LL | let _ = &Self::BOUNDED_ASSOC_TYPE; - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::BOUNDED_ASSOC_TYPE; + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:200:5 + --> tests/ui/borrow_interior_mutable_const/traits.rs:215:1 | -LL | u64::ATOMIC.store(5, Ordering::SeqCst); - | ^^^^^^^^^^^ +LL | u64::ATOMIC.store(5, Ordering::SeqCst); + | ^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:201:16 + --> tests/ui/borrow_interior_mutable_const/traits.rs:217:12 | -LL | assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); - | ^^^^^^^^^^^ +LL | assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); + | ^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here diff --git a/tests/ui/box_collection.rs b/tests/ui/box_collection.rs index 499625ea9c31..61117412016a 100644 --- a/tests/ui/box_collection.rs +++ b/tests/ui/box_collection.rs @@ -19,7 +19,8 @@ fn test_macro() { } fn test1(foo: Box>) {} -//~^ ERROR: you seem to be trying to use `Box>`. Consider using just `Vec<..>` +//~^ box_collection + fn test2(foo: Box)>) { // pass if #31 is fixed @@ -27,28 +28,36 @@ fn test2(foo: Box)>) { } fn test3(foo: Box) {} -//~^ ERROR: you seem to be trying to use `Box`. Consider using just `String` +//~^ box_collection + fn test4(foo: Box>) {} -//~^ ERROR: you seem to be trying to use `Box>`. Consider using just `HashMap< +//~^ box_collection + fn test5(foo: Box>) {} -//~^ ERROR: you seem to be trying to use `Box>`. Consider using just `HashSet< +//~^ box_collection + fn test6(foo: Box>) {} -//~^ ERROR: you seem to be trying to use `Box>`. Consider using just `VecDequ +//~^ box_collection + fn test7(foo: Box>) {} -//~^ ERROR: you seem to be trying to use `Box>`. Consider using just `Linke +//~^ box_collection + fn test8(foo: Box>) {} -//~^ ERROR: you seem to be trying to use `Box>`. Consider using just `BTreeMa +//~^ box_collection + fn test9(foo: Box>) {} -//~^ ERROR: you seem to be trying to use `Box>`. Consider using just `BTreeSe +//~^ box_collection + fn test10(foo: Box>) {} -//~^ ERROR: you seem to be trying to use `Box>`. Consider using just `Binar +//~^ box_collection + fn test_local_not_linted() { let _: Box>; diff --git a/tests/ui/box_collection.stderr b/tests/ui/box_collection.stderr index ebbc3d92b57f..644556edd572 100644 --- a/tests/ui/box_collection.stderr +++ b/tests/ui/box_collection.stderr @@ -9,7 +9,7 @@ LL | fn test1(foo: Box>) {} = help: to override `-D warnings` add `#[allow(clippy::box_collection)]` error: you seem to be trying to use `Box`. Consider using just `String` - --> tests/ui/box_collection.rs:29:15 + --> tests/ui/box_collection.rs:30:15 | LL | fn test3(foo: Box) {} | ^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn test3(foo: Box) {} = help: `String` is already on the heap, `Box` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `HashMap<..>` - --> tests/ui/box_collection.rs:32:15 + --> tests/ui/box_collection.rs:34:15 | LL | fn test4(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | fn test4(foo: Box>) {} = help: `HashMap<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `HashSet<..>` - --> tests/ui/box_collection.rs:35:15 + --> tests/ui/box_collection.rs:38:15 | LL | fn test5(foo: Box>) {} | ^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | fn test5(foo: Box>) {} = help: `HashSet<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `VecDeque<..>` - --> tests/ui/box_collection.rs:38:15 + --> tests/ui/box_collection.rs:42:15 | LL | fn test6(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | fn test6(foo: Box>) {} = help: `VecDeque<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `LinkedList<..>` - --> tests/ui/box_collection.rs:41:15 + --> tests/ui/box_collection.rs:46:15 | LL | fn test7(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | fn test7(foo: Box>) {} = help: `LinkedList<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `BTreeMap<..>` - --> tests/ui/box_collection.rs:44:15 + --> tests/ui/box_collection.rs:50:15 | LL | fn test8(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn test8(foo: Box>) {} = help: `BTreeMap<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `BTreeSet<..>` - --> tests/ui/box_collection.rs:47:15 + --> tests/ui/box_collection.rs:54:15 | LL | fn test9(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | fn test9(foo: Box>) {} = help: `BTreeSet<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `BinaryHeap<..>` - --> tests/ui/box_collection.rs:50:16 + --> tests/ui/box_collection.rs:58:16 | LL | fn test10(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/box_default.fixed b/tests/ui/box_default.fixed index 1f2f57c2507d..80000f5de4fd 100644 --- a/tests/ui/box_default.fixed +++ b/tests/ui/box_default.fixed @@ -32,14 +32,22 @@ macro_rules! box_new { fn main() { let string1: Box = Box::default(); + //~^ box_default let string2: Box = Box::default(); + //~^ box_default let impl1: Box = Box::default(); + //~^ box_default let vec: Box> = Box::default(); + //~^ box_default let byte: Box = Box::default(); + //~^ box_default let vec2: Box> = Box::default(); + //~^ box_default let vec3: Box> = Box::default(); + //~^ box_default let plain_default = Box::default(); + //~^ box_default let _: Box = plain_default; let _: Box = Box::new(default!()); @@ -57,6 +65,7 @@ fn main() { let vec4: Box<_> = Box::new(Vec::from([false; 0])); let more = ret_ty_fn(); call_ty_fn(Box::default()); + //~^ box_default issue_10381(); // `Box::>::default()` would be valid here, but not `Box::default()` or @@ -84,6 +93,7 @@ impl X { fn same_generic_param() { Self::x(Box::default()); + //~^ box_default } } diff --git a/tests/ui/box_default.rs b/tests/ui/box_default.rs index addfebc24f58..4681016d7cd3 100644 --- a/tests/ui/box_default.rs +++ b/tests/ui/box_default.rs @@ -32,14 +32,22 @@ macro_rules! box_new { fn main() { let string1: Box = Box::new(Default::default()); + //~^ box_default let string2: Box = Box::new(String::new()); + //~^ box_default let impl1: Box = Box::new(Default::default()); + //~^ box_default let vec: Box> = Box::new(Vec::new()); + //~^ box_default let byte: Box = Box::new(u8::default()); + //~^ box_default let vec2: Box> = Box::new(vec![]); + //~^ box_default let vec3: Box> = Box::new(Vec::from([])); + //~^ box_default let plain_default = Box::new(Default::default()); + //~^ box_default let _: Box = plain_default; let _: Box = Box::new(default!()); @@ -57,6 +65,7 @@ fn main() { let vec4: Box<_> = Box::new(Vec::from([false; 0])); let more = ret_ty_fn(); call_ty_fn(Box::new(u8::default())); + //~^ box_default issue_10381(); // `Box::>::default()` would be valid here, but not `Box::default()` or @@ -84,6 +93,7 @@ impl X { fn same_generic_param() { Self::x(Box::new(T::default())); + //~^ box_default } } diff --git a/tests/ui/box_default.stderr b/tests/ui/box_default.stderr index 39fd0d29bbf9..f63d97665b34 100644 --- a/tests/ui/box_default.stderr +++ b/tests/ui/box_default.stderr @@ -8,55 +8,55 @@ LL | let string1: Box = Box::new(Default::default()); = help: to override `-D warnings` add `#[allow(clippy::box_default)]` error: `Box::new(_)` of default value - --> tests/ui/box_default.rs:35:32 + --> tests/ui/box_default.rs:36:32 | LL | let string2: Box = Box::new(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> tests/ui/box_default.rs:36:41 + --> tests/ui/box_default.rs:38:41 | LL | let impl1: Box = Box::new(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> tests/ui/box_default.rs:37:29 + --> tests/ui/box_default.rs:40:29 | LL | let vec: Box> = Box::new(Vec::new()); | ^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> tests/ui/box_default.rs:38:25 + --> tests/ui/box_default.rs:42:25 | LL | let byte: Box = Box::new(u8::default()); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> tests/ui/box_default.rs:39:45 + --> tests/ui/box_default.rs:44:45 | LL | let vec2: Box> = Box::new(vec![]); | ^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> tests/ui/box_default.rs:40:32 + --> tests/ui/box_default.rs:46:32 | LL | let vec3: Box> = Box::new(Vec::from([])); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> tests/ui/box_default.rs:42:25 + --> tests/ui/box_default.rs:49:25 | LL | let plain_default = Box::new(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> tests/ui/box_default.rs:59:16 + --> tests/ui/box_default.rs:67:16 | LL | call_ty_fn(Box::new(u8::default())); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> tests/ui/box_default.rs:86:17 + --> tests/ui/box_default.rs:95:17 | LL | Self::x(Box::new(T::default())); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` diff --git a/tests/ui/box_default_no_std.rs b/tests/ui/box_default_no_std.rs index edb701fcd084..2881caf0c185 100644 --- a/tests/ui/box_default_no_std.rs +++ b/tests/ui/box_default_no_std.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::box_default)] #![no_std] #![crate_type = "lib"] diff --git a/tests/ui/boxed_local.rs b/tests/ui/boxed_local.rs index 4f361f5162be..fa234dce1a99 100644 --- a/tests/ui/boxed_local.rs +++ b/tests/ui/boxed_local.rs @@ -38,8 +38,9 @@ fn warn_call() { } fn warn_arg(x: Box) { - //~^ ERROR: local variable doesn't need to be boxed here - //~| NOTE: `-D clippy::boxed-local` implied by `-D warnings` +//~^ boxed_local + + x.foo(); } @@ -121,7 +122,8 @@ pub struct PeekableSeekable { } pub fn new(_needs_name: Box>) -> () {} -//~^ ERROR: local variable doesn't need to be boxed here +//~^ boxed_local + /// Regression for #916, #1123 /// @@ -187,7 +189,8 @@ mod issue4804 { // warn on `x: Box` fn default_impl_x(self: Box, x: Box) -> u32 { - //~^ ERROR: local variable doesn't need to be boxed here + //~^ boxed_local + 4 } } @@ -195,7 +198,8 @@ mod issue4804 { trait WarnTrait { // warn on `x: Box` fn foo(x: Box) {} - //~^ ERROR: local variable doesn't need to be boxed here + //~^ boxed_local + } } diff --git a/tests/ui/boxed_local.stderr b/tests/ui/boxed_local.stderr index 08fe375afb23..5ce2c8083f15 100644 --- a/tests/ui/boxed_local.stderr +++ b/tests/ui/boxed_local.stderr @@ -8,19 +8,19 @@ LL | fn warn_arg(x: Box) { = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]` error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:123:12 + --> tests/ui/boxed_local.rs:124:12 | LL | pub fn new(_needs_name: Box>) -> () {} | ^^^^^^^^^^^ error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:189:44 + --> tests/ui/boxed_local.rs:191:44 | LL | fn default_impl_x(self: Box, x: Box) -> u32 { | ^ error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:197:16 + --> tests/ui/boxed_local.rs:200:16 | LL | fn foo(x: Box) {} | ^ diff --git a/tests/ui/branches_sharing_code/false_positives.rs b/tests/ui/branches_sharing_code/false_positives.rs index 5e3a1a29693f..49496e631fb1 100644 --- a/tests/ui/branches_sharing_code/false_positives.rs +++ b/tests/ui/branches_sharing_code/false_positives.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(dead_code)] #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.rs b/tests/ui/branches_sharing_code/shared_at_bottom.rs index 549908b8770e..050c8c0d53f2 100644 --- a/tests/ui/branches_sharing_code/shared_at_bottom.rs +++ b/tests/ui/branches_sharing_code/shared_at_bottom.rs @@ -33,8 +33,9 @@ fn simple_examples() { // The rest is self contained and moveable => Only lint the rest let result = false; - //~^ ERROR: all if blocks contain the same code at the end - //~| NOTE: the end suggestion probably needs some adjustments to use the expressio + //~^ branches_sharing_code + + println!("Block end!"); result }; @@ -53,7 +54,8 @@ fn simple_examples() { } else { println!("This is also eq with the else block"); println!("Same end of block"); - //~^ ERROR: all if blocks contain the same code at the end + //~^ branches_sharing_code + } // Use of outer scope value @@ -71,7 +73,8 @@ fn simple_examples() { println!("I'm a local because I use the value `z`: `{}`", z); println!( - //~^ ERROR: all if blocks contain the same code at the end + //~^ branches_sharing_code + "I'm moveable because I know: `outer_scope_value`: '{}'", outer_scope_value ); @@ -84,7 +87,8 @@ fn simple_examples() { println!("Hello World"); } else { println!("Hello World"); - //~^ ERROR: all if blocks contain the same code at the end + //~^ branches_sharing_code + } } } @@ -101,7 +105,8 @@ fn simple_but_suggestion_is_invalid() { println!("{}", later_used_value); } else { let later_used_value = "A string value"; - //~^ ERROR: all if blocks contain the same code at the end + //~^ branches_sharing_code + println!("{}", later_used_value); // I'm expecting a note about this } @@ -115,7 +120,8 @@ fn simple_but_suggestion_is_invalid() { println!("Separator print statement"); let simple_examples = "I now identify as a &str :)"; - //~^ ERROR: all if blocks contain the same code at the end + //~^ branches_sharing_code + println!("This is the new simple_example: {}", simple_examples); } simple_examples(); @@ -181,8 +187,9 @@ fn added_note_for_expression_use() -> u32 { } else { let _ = 6; x << 2 - //~^ ERROR: all if blocks contain the same code at the end - //~| NOTE: the end suggestion probably needs some adjustments to use the expressio + //~^ branches_sharing_code + + }; if x == 9 { @@ -190,8 +197,9 @@ fn added_note_for_expression_use() -> u32 { } else { let _ = 17; x * 4 - //~^ ERROR: all if blocks contain the same code at the end - //~| NOTE: the end suggestion probably needs some adjustments to use the expressio + //~^ branches_sharing_code + + } } @@ -204,7 +212,8 @@ fn test_suggestion_with_weird_formatting() { // The error message still looks weird tbh but this is the best I can do // for weird formatting if x == 17 { b = 1; a = 0x99; } else { a = 0x99; } - //~^ ERROR: all if blocks contain the same code at the end + //~^ branches_sharing_code + } fn fp_test() { diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/tests/ui/branches_sharing_code/shared_at_bottom.stderr index 36b177739732..b7bb07775241 100644 --- a/tests/ui/branches_sharing_code/shared_at_bottom.stderr +++ b/tests/ui/branches_sharing_code/shared_at_bottom.stderr @@ -2,9 +2,7 @@ error: all if blocks contain the same code at the end --> tests/ui/branches_sharing_code/shared_at_bottom.rs:35:5 | LL | / let result = false; -LL | | -LL | | -LL | | println!("Block end!"); +... | LL | | result LL | | }; | |_____^ @@ -20,16 +18,17 @@ help: consider moving these statements after the if LL ~ } LL + let result = false; LL + -LL + +LL + +LL + LL + println!("Block end!"); LL ~ result; | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:55:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:56:5 | LL | / println!("Same end of block"); -LL | | +... | LL | | } | |_____^ | @@ -40,10 +39,11 @@ LL + println!("Same end of block"); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:73:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:75:5 | LL | / println!( LL | | +LL | | LL | | "I'm moveable because I know: `outer_scope_value`: '{}'", LL | | outer_scope_value LL | | ); @@ -55,16 +55,17 @@ help: consider moving these statements after the if LL ~ } LL + println!( LL + +LL + LL + "I'm moveable because I know: `outer_scope_value`: '{}'", LL + outer_scope_value LL + ); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:86:9 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:89:9 | LL | / println!("Hello World"); -LL | | +... | LL | | } | |_________^ | @@ -75,10 +76,11 @@ LL + println!("Hello World"); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:103:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:107:5 | LL | / let later_used_value = "A string value"; LL | | +LL | | LL | | println!("{}", later_used_value); LL | | // I'm expecting a note about this LL | | } @@ -90,14 +92,16 @@ help: consider moving these statements after the if LL ~ } LL + let later_used_value = "A string value"; LL + +LL + LL + println!("{}", later_used_value); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:117:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:122:5 | LL | / let simple_examples = "I now identify as a &str :)"; LL | | +LL | | LL | | println!("This is the new simple_example: {}", simple_examples); LL | | } | |_____^ @@ -108,11 +112,12 @@ help: consider moving these statements after the if LL ~ } LL + let simple_examples = "I now identify as a &str :)"; LL + +LL + LL + println!("This is the new simple_example: {}", simple_examples); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:183:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:189:5 | LL | / x << 2 ... | @@ -127,7 +132,7 @@ LL ~ x << 2; | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:192:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:199:5 | LL | / x * 4 ... | @@ -142,7 +147,7 @@ LL + x * 4 | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:206:44 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:214:44 | LL | if x == 17 { b = 1; a = 0x99; } else { a = 0x99; } | ^^^^^^^^^^^ diff --git a/tests/ui/branches_sharing_code/shared_at_top.rs b/tests/ui/branches_sharing_code/shared_at_top.rs index 9af81f6f7cdd..a6f8ce8a3816 100644 --- a/tests/ui/branches_sharing_code/shared_at_top.rs +++ b/tests/ui/branches_sharing_code/shared_at_top.rs @@ -9,16 +9,18 @@ fn simple_examples() { // Simple if true { + //~^ branches_sharing_code println!("Hello World!"); println!("I'm branch nr: 1"); } else { println!("Hello World!"); println!("I'm branch nr: 2"); } - //~^^^^^^^ ERROR: all if blocks contain the same code at the start + // Else if if x == 0 { + //~^ branches_sharing_code let y = 9; println!("The value y was set to: `{}`", y); let _z = y; @@ -37,11 +39,12 @@ fn simple_examples() { println!("Ha, Pascal allows you to start the array where you want") } - //~^^^^^^^^^^^^^^^^^^^ ERROR: all if blocks contain the same code at the start + // Return a value let _ = if x == 7 { - //~^ ERROR: all if blocks contain the same code at the start + //~^ branches_sharing_code + let y = 16; println!("What can I say except: \"you're welcome?\""); let _ = y; @@ -60,6 +63,7 @@ fn simple_but_suggestion_is_invalid() { // Can't be automatically moved because used_value_name is getting used again let used_value_name = 19; if x == 10 { + //~^ branches_sharing_code let used_value_name = "Different type"; println!("Str: {}", used_value_name); let _ = 1; @@ -68,14 +72,15 @@ fn simple_but_suggestion_is_invalid() { println!("Str: {}", used_value_name); let _ = 2; } - //~^^^^^^^^^ ERROR: all if blocks contain the same code at the start + let _ = used_value_name; // This can be automatically moved as `can_be_overridden` is not used again let can_be_overridden = 8; let _ = can_be_overridden; if x == 11 { - //~^ ERROR: all if blocks contain the same code at the start + //~^ branches_sharing_code + let can_be_overridden = "Move me"; println!("I'm also moveable"); let _ = 111; @@ -92,7 +97,8 @@ fn check_if_same_than_else_mask() { #[allow(clippy::if_same_then_else)] if x == 2020 { - //~^ ERROR: all if blocks contain the same code at the start + //~^ branches_sharing_code + println!("This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint."); println!("Because `IF_SAME_THEN_ELSE` is allowed here"); } else { @@ -105,7 +111,8 @@ fn check_if_same_than_else_mask() { } else { println!("This should trigger `IS_SAME_THAN_ELSE` as usual"); } - //~^^^^^ ERROR: this `if` has identical blocks + //~^^^^^ if_same_then_else + } #[allow(clippy::vec_init_then_push)] diff --git a/tests/ui/branches_sharing_code/shared_at_top.stderr b/tests/ui/branches_sharing_code/shared_at_top.stderr index 0d4e19be1f52..5b0422d5df18 100644 --- a/tests/ui/branches_sharing_code/shared_at_top.stderr +++ b/tests/ui/branches_sharing_code/shared_at_top.stderr @@ -2,6 +2,7 @@ error: all if blocks contain the same code at the start --> tests/ui/branches_sharing_code/shared_at_top.rs:11:5 | LL | / if true { +LL | | LL | | println!("Hello World!"); | |_________________________________^ | @@ -17,9 +18,10 @@ LL + if true { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:21:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:22:5 | LL | / if x == 0 { +LL | | LL | | let y = 9; LL | | println!("The value y was set to: `{}`", y); LL | | let _z = y; @@ -35,10 +37,10 @@ LL + if x == 0 { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:43:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:45:5 | LL | / let _ = if x == 7 { -LL | | +... | LL | | let y = 16; | |___________________^ | @@ -49,9 +51,10 @@ LL + let _ = if x == 7 { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:62:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:65:5 | LL | / if x == 10 { +LL | | LL | | let used_value_name = "Different type"; LL | | println!("Str: {}", used_value_name); | |_____________________________________________^ @@ -65,10 +68,11 @@ LL + if x == 10 { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:77:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:81:5 | LL | / if x == 11 { LL | | +LL | | LL | | let can_be_overridden = "Move me"; LL | | println!("I'm also moveable"); | |______________________________________^ @@ -82,10 +86,11 @@ LL + if x == 11 { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:94:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:99:5 | LL | / if x == 2020 { LL | | +LL | | LL | | println!("This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint."); LL | | println!("Because `IF_SAME_THEN_ELSE` is allowed here"); | |________________________________________________________________^ @@ -98,7 +103,7 @@ LL + if x == 2020 { | error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/shared_at_top.rs:103:18 + --> tests/ui/branches_sharing_code/shared_at_top.rs:109:18 | LL | if x == 2019 { | __________________^ @@ -107,7 +112,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/branches_sharing_code/shared_at_top.rs:105:12 + --> tests/ui/branches_sharing_code/shared_at_top.rs:111:12 | LL | } else { | ____________^ diff --git a/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs index 36620ee1a9bf..799f58d28430 100644 --- a/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs +++ b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs @@ -15,7 +15,8 @@ fn overlapping_eq_regions() { // Overlap with separator if x == 7 { - //~^ ERROR: all if blocks contain the same code at both the start and the end + //~^ branches_sharing_code + let t = 7; let _overlap_start = t * 2; let _overlap_end = 2 * t; @@ -32,7 +33,8 @@ fn overlapping_eq_regions() { // Overlap with separator if x == 99 { - //~^ ERROR: all if blocks contain the same code at both the start and the end + //~^ branches_sharing_code + let r = 7; let _overlap_start = r; let _overlap_middle = r * r; @@ -62,7 +64,8 @@ fn complexer_example() { let x = 8; let y = 9; if (x > 7 && y < 13) || (x + y) % 2 == 1 { - //~^ ERROR: all if blocks contain the same code at both the start and the end + //~^ branches_sharing_code + let a = 0xcafe; let b = 0xffff00ff; let e_id = gen_id(a, b); @@ -96,7 +99,8 @@ fn added_note_for_expression_use() -> u32 { let x = 9; let _ = if x == 7 { - //~^ ERROR: all if blocks contain the same code at both the start and the end + //~^ branches_sharing_code + let _ = 19; let _splitter = 6; @@ -109,7 +113,8 @@ fn added_note_for_expression_use() -> u32 { }; if x == 9 { - //~^ ERROR: all if blocks contain the same code at both the start and the end + //~^ branches_sharing_code + let _ = 17; let _splitter = 6; diff --git a/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr index b79307f96778..2200ab450890 100644 --- a/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr +++ b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr @@ -3,13 +3,14 @@ error: all if blocks contain the same code at both the start and the end | LL | / if x == 7 { LL | | +LL | | LL | | let t = 7; LL | | let _overlap_start = t * 2; LL | | let _overlap_end = 2 * t; | |_________________________________^ | note: this code is shared at the end - --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:30:5 + --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:31:5 | LL | / let _u = 9; LL | | } @@ -33,17 +34,18 @@ LL + let _u = 9; | error: all if blocks contain the same code at both the start and the end - --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:34:5 + --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:35:5 | LL | / if x == 99 { LL | | +LL | | LL | | let r = 7; LL | | let _overlap_start = r; LL | | let _overlap_middle = r * r; | |____________________________________^ | note: this code is shared at the end - --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:46:5 + --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:48:5 | LL | / let _overlap_end = r * r * r; LL | | let z = "end"; @@ -65,17 +67,18 @@ LL + let z = "end"; | error: all if blocks contain the same code at both the start and the end - --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:64:5 + --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:66:5 | LL | / if (x > 7 && y < 13) || (x + y) % 2 == 1 { LL | | +LL | | LL | | let a = 0xcafe; LL | | let b = 0xffff00ff; LL | | let e_id = gen_id(a, b); | |________________________________^ | note: this code is shared at the end - --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:85:5 + --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:88:5 | LL | / let pack = DataPack { LL | | id: e_id, @@ -105,15 +108,15 @@ LL + process_data(pack); | error: all if blocks contain the same code at both the start and the end - --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:98:5 + --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:101:5 | LL | / let _ = if x == 7 { -LL | | +... | LL | | let _ = 19; | |___________________^ | note: this code is shared at the end - --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:108:5 + --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:112:5 | LL | / x << 2 LL | | }; @@ -131,15 +134,15 @@ LL ~ x << 2; | error: all if blocks contain the same code at both the start and the end - --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:111:5 + --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:115:5 | LL | / if x == 9 { -LL | | +... | LL | | let _ = 17; | |___________________^ | note: this code is shared at the end - --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:121:5 + --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:126:5 | LL | / x * 4 LL | | } diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.rs b/tests/ui/branches_sharing_code/valid_if_blocks.rs index b63819d7c393..23ea86c88f54 100644 --- a/tests/ui/branches_sharing_code/valid_if_blocks.rs +++ b/tests/ui/branches_sharing_code/valid_if_blocks.rs @@ -109,7 +109,8 @@ fn valid_examples() { if false { } else { } - //~^^^ ERROR: this `if` has identical blocks + //~^^^ if_same_then_else + } /// This makes sure that the `if_same_then_else` masks the `shared_code_in_if_blocks` lint @@ -127,11 +128,13 @@ fn trigger_other_lint() { println!("How are u today?"); let _ = "This is a string"; } - //~^^^^^^^^^ ERROR: this `if` has identical blocks + //~^^^^^^^^^ if_same_then_else + // Only same expression let _ = if x == 6 { 7 } else { 7 }; - //~^ ERROR: this `if` has identical blocks + //~^ if_same_then_else + // Same in else if block let _ = if x == 67 { @@ -146,7 +149,8 @@ fn trigger_other_lint() { if y == 90 { "=^.^=" } else { ":D" } }; - //~^^^^^^^^^ ERROR: this `if` has identical blocks + //~^^^^^^^^^ if_same_then_else + if x == 0 { println!("I'm single"); @@ -155,7 +159,8 @@ fn trigger_other_lint() { } else { println!("I'm a doppelgänger"); } - //~^^^^^ ERROR: this `if` has identical blocks + //~^^^^^ if_same_then_else + } fn main() {} diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.stderr b/tests/ui/branches_sharing_code/valid_if_blocks.stderr index 4c7e4141b629..a0c4dd24d6b4 100644 --- a/tests/ui/branches_sharing_code/valid_if_blocks.stderr +++ b/tests/ui/branches_sharing_code/valid_if_blocks.stderr @@ -20,7 +20,7 @@ LL | #![deny(clippy::branches_sharing_code, clippy::if_same_then_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:121:15 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:122:15 | LL | if x == 0 { | _______________^ @@ -31,7 +31,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:125:12 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:126:12 | LL | } else { | ____________^ @@ -42,19 +42,19 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:133:23 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:135:23 | LL | let _ = if x == 6 { 7 } else { 7 }; | ^^^^^ | note: same as this - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:133:34 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:135:34 | LL | let _ = if x == 6 { 7 } else { 7 }; | ^^^^^ error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:140:23 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:143:23 | LL | } else if x == 68 { | _______________________^ @@ -65,7 +65,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:144:12 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:147:12 | LL | } else { | ____________^ @@ -76,7 +76,7 @@ LL | | }; | |_____^ error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:153:23 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:157:23 | LL | } else if x == 68 { | _______________________^ @@ -85,7 +85,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:155:12 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:159:12 | LL | } else { | ____________^ diff --git a/tests/ui/builtin_type_shadow.rs b/tests/ui/builtin_type_shadow.rs index c5addd53434c..41d6207ea3f5 100644 --- a/tests/ui/builtin_type_shadow.rs +++ b/tests/ui/builtin_type_shadow.rs @@ -2,8 +2,9 @@ #![allow(non_camel_case_types)] fn foo(a: u32) -> u32 { +//~^ builtin_type_shadow 42 - //~^ ERROR: mismatched types + } fn main() {} diff --git a/tests/ui/builtin_type_shadow.stderr b/tests/ui/builtin_type_shadow.stderr index 033204af9255..a62b41d5c271 100644 --- a/tests/ui/builtin_type_shadow.stderr +++ b/tests/ui/builtin_type_shadow.stderr @@ -8,12 +8,13 @@ LL | fn foo(a: u32) -> u32 { = help: to override `-D warnings` add `#[allow(clippy::builtin_type_shadow)]` error[E0308]: mismatched types - --> tests/ui/builtin_type_shadow.rs:5:5 + --> tests/ui/builtin_type_shadow.rs:6:5 | LL | fn foo(a: u32) -> u32 { | --- --- expected `u32` because of return type | | | expected this type parameter +LL | LL | 42 | ^^ expected type parameter `u32`, found integer | diff --git a/tests/ui/byte_char_slices.fixed b/tests/ui/byte_char_slices.fixed index d1db58f9363e..b0c1b1f034b4 100644 --- a/tests/ui/byte_char_slices.fixed +++ b/tests/ui/byte_char_slices.fixed @@ -3,11 +3,16 @@ fn main() { let bad = b"abc"; + //~^ byte_char_slices let quotes = b"\"Hi"; + //~^ byte_char_slices let quotes = b"'Sup"; + //~^ byte_char_slices let escapes = b"\x42Esc"; + //~^ byte_char_slices let good = &[b'a', 0x42]; let good = [b'a', b'a']; + //~^ useless_vec let good: u8 = [b'a', b'c'].into_iter().sum(); } diff --git a/tests/ui/byte_char_slices.rs b/tests/ui/byte_char_slices.rs index 18648fffceb4..0d6953dda97e 100644 --- a/tests/ui/byte_char_slices.rs +++ b/tests/ui/byte_char_slices.rs @@ -3,11 +3,16 @@ fn main() { let bad = &[b'a', b'b', b'c']; + //~^ byte_char_slices let quotes = &[b'"', b'H', b'i']; + //~^ byte_char_slices let quotes = &[b'\'', b'S', b'u', b'p']; + //~^ byte_char_slices let escapes = &[b'\x42', b'E', b's', b'c']; + //~^ byte_char_slices let good = &[b'a', 0x42]; let good = vec![b'a', b'a']; + //~^ useless_vec let good: u8 = [b'a', b'c'].into_iter().sum(); } diff --git a/tests/ui/byte_char_slices.stderr b/tests/ui/byte_char_slices.stderr index 4e2b5d8a7329..2556aa9c0f76 100644 --- a/tests/ui/byte_char_slices.stderr +++ b/tests/ui/byte_char_slices.stderr @@ -8,25 +8,25 @@ LL | let bad = &[b'a', b'b', b'c']; = help: to override `-D warnings` add `#[allow(clippy::byte_char_slices)]` error: can be more succinctly written as a byte str - --> tests/ui/byte_char_slices.rs:6:18 + --> tests/ui/byte_char_slices.rs:7:18 | LL | let quotes = &[b'"', b'H', b'i']; | ^^^^^^^^^^^^^^^^^^^ help: try: `b"\"Hi"` error: can be more succinctly written as a byte str - --> tests/ui/byte_char_slices.rs:7:18 + --> tests/ui/byte_char_slices.rs:9:18 | LL | let quotes = &[b'\'', b'S', b'u', b'p']; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b"'Sup"` error: can be more succinctly written as a byte str - --> tests/ui/byte_char_slices.rs:8:19 + --> tests/ui/byte_char_slices.rs:11:19 | LL | let escapes = &[b'\x42', b'E', b's', b'c']; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b"\x42Esc"` error: useless use of `vec!` - --> tests/ui/byte_char_slices.rs:11:16 + --> tests/ui/byte_char_slices.rs:15:16 | LL | let good = vec![b'a', b'a']; | ^^^^^^^^^^^^^^^^ help: you can use an array directly: `[b'a', b'a']` diff --git a/tests/ui/bytecount.rs b/tests/ui/bytecount.rs index f3b02fda8a81..bad39fcf8f66 100644 --- a/tests/ui/bytecount.rs +++ b/tests/ui/bytecount.rs @@ -8,11 +8,13 @@ fn main() { // naive byte count let _ = x.iter().filter(|&&a| a == 0).count(); - //~^ ERROR: you appear to be counting bytes the naive way + //~^ naive_bytecount + // naive byte count let _ = (&x[..]).iter().filter(|&a| *a == 0).count(); - //~^ ERROR: you appear to be counting bytes the naive way + //~^ naive_bytecount + // not an equality count, OK. let _ = x.iter().filter(|a| **a > 0).count(); @@ -30,7 +32,8 @@ fn main() { // naive byte count let _ = x.iter().filter(|a| b + 1 == **a).count(); - //~^ ERROR: you appear to be counting bytes the naive way + //~^ naive_bytecount + let y = vec![0_u16; 3]; diff --git a/tests/ui/bytecount.stderr b/tests/ui/bytecount.stderr index d1a73fe98358..9a0986f56478 100644 --- a/tests/ui/bytecount.stderr +++ b/tests/ui/bytecount.stderr @@ -11,13 +11,13 @@ LL | #[deny(clippy::naive_bytecount)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: you appear to be counting bytes the naive way - --> tests/ui/bytecount.rs:14:13 + --> tests/ui/bytecount.rs:15:13 | LL | let _ = (&x[..]).iter().filter(|&a| *a == 0).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count((&x[..]), 0)` error: you appear to be counting bytes the naive way - --> tests/ui/bytecount.rs:32:13 + --> tests/ui/bytecount.rs:34:13 | LL | let _ = x.iter().filter(|a| b + 1 == **a).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count(x, b + 1)` diff --git a/tests/ui/bytes_count_to_len.fixed b/tests/ui/bytes_count_to_len.fixed index fb31ceaad7c4..aa0484a83110 100644 --- a/tests/ui/bytes_count_to_len.fixed +++ b/tests/ui/bytes_count_to_len.fixed @@ -5,15 +5,19 @@ use std::io::{BufReader, Read}; fn main() { // should fix, because type is String let _ = String::from("foo").len(); + //~^ bytes_count_to_len let s1 = String::from("foo"); let _ = s1.len(); + //~^ bytes_count_to_len // should fix, because type is &str let _ = "foo".len(); + //~^ bytes_count_to_len let s2 = "foo"; let _ = s2.len(); + //~^ bytes_count_to_len // make sure using count() normally doesn't trigger warning let vector = [0, 1, 2]; diff --git a/tests/ui/bytes_count_to_len.rs b/tests/ui/bytes_count_to_len.rs index 0250059afeb2..7e38858bf783 100644 --- a/tests/ui/bytes_count_to_len.rs +++ b/tests/ui/bytes_count_to_len.rs @@ -5,15 +5,19 @@ use std::io::{BufReader, Read}; fn main() { // should fix, because type is String let _ = String::from("foo").bytes().count(); + //~^ bytes_count_to_len let s1 = String::from("foo"); let _ = s1.bytes().count(); + //~^ bytes_count_to_len // should fix, because type is &str let _ = "foo".bytes().count(); + //~^ bytes_count_to_len let s2 = "foo"; let _ = s2.bytes().count(); + //~^ bytes_count_to_len // make sure using count() normally doesn't trigger warning let vector = [0, 1, 2]; diff --git a/tests/ui/bytes_count_to_len.stderr b/tests/ui/bytes_count_to_len.stderr index b80f3af18f78..999da9ca1365 100644 --- a/tests/ui/bytes_count_to_len.stderr +++ b/tests/ui/bytes_count_to_len.stderr @@ -8,19 +8,19 @@ LL | let _ = String::from("foo").bytes().count(); = help: to override `-D warnings` add `#[allow(clippy::bytes_count_to_len)]` error: using long and hard to read `.bytes().count()` - --> tests/ui/bytes_count_to_len.rs:10:13 + --> tests/ui/bytes_count_to_len.rs:11:13 | LL | let _ = s1.bytes().count(); | ^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `s1.len()` error: using long and hard to read `.bytes().count()` - --> tests/ui/bytes_count_to_len.rs:13:13 + --> tests/ui/bytes_count_to_len.rs:15:13 | LL | let _ = "foo".bytes().count(); | ^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `"foo".len()` error: using long and hard to read `.bytes().count()` - --> tests/ui/bytes_count_to_len.rs:16:13 + --> tests/ui/bytes_count_to_len.rs:19:13 | LL | let _ = s2.bytes().count(); | ^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `s2.len()` diff --git a/tests/ui/bytes_nth.fixed b/tests/ui/bytes_nth.fixed index da35fcb55e5a..6f4c2e7116e9 100644 --- a/tests/ui/bytes_nth.fixed +++ b/tests/ui/bytes_nth.fixed @@ -5,6 +5,9 @@ fn main() { let s = String::from("String"); let _ = s.as_bytes().get(3).copied(); + //~^ bytes_nth let _ = &s.as_bytes()[3]; + //~^ bytes_nth let _ = s[..].as_bytes().get(3).copied(); + //~^ bytes_nth } diff --git a/tests/ui/bytes_nth.rs b/tests/ui/bytes_nth.rs index 5dbe84ecec8b..27655bebb264 100644 --- a/tests/ui/bytes_nth.rs +++ b/tests/ui/bytes_nth.rs @@ -5,6 +5,9 @@ fn main() { let s = String::from("String"); let _ = s.bytes().nth(3); + //~^ bytes_nth let _ = &s.bytes().nth(3).unwrap(); + //~^ bytes_nth let _ = s[..].bytes().nth(3); + //~^ bytes_nth } diff --git a/tests/ui/bytes_nth.stderr b/tests/ui/bytes_nth.stderr index c5f341cb37f6..c421839ff3f5 100644 --- a/tests/ui/bytes_nth.stderr +++ b/tests/ui/bytes_nth.stderr @@ -8,13 +8,13 @@ LL | let _ = s.bytes().nth(3); = help: to override `-D warnings` add `#[allow(clippy::bytes_nth)]` error: called `.bytes().nth().unwrap()` on a `String` - --> tests/ui/bytes_nth.rs:8:14 + --> tests/ui/bytes_nth.rs:9:14 | LL | let _ = &s.bytes().nth(3).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.as_bytes()[3]` error: called `.bytes().nth()` on a `str` - --> tests/ui/bytes_nth.rs:9:13 + --> tests/ui/bytes_nth.rs:11:13 | LL | let _ = s[..].bytes().nth(3); | ^^^^^^^^^^^^^^^^^^^^ help: try: `s[..].as_bytes().get(3).copied()` diff --git a/tests/ui/case_sensitive_file_extension_comparisons.fixed b/tests/ui/case_sensitive_file_extension_comparisons.fixed index c4d77f24f126..bf7635fdf09b 100644 --- a/tests/ui/case_sensitive_file_extension_comparisons.fixed +++ b/tests/ui/case_sensitive_file_extension_comparisons.fixed @@ -14,6 +14,7 @@ fn is_rust_file(filename: &str) -> bool { std::path::Path::new(filename) .extension() .map_or(false, |ext| ext.eq_ignore_ascii_case("rs")) + //~^ case_sensitive_file_extension_comparisons } fn main() { @@ -21,15 +22,18 @@ fn main() { let _ = std::path::Path::new(&String::new()) .extension() .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); + //~^ case_sensitive_file_extension_comparisons let _ = std::path::Path::new("str") .extension() .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); + //~^ case_sensitive_file_extension_comparisons // The fixup should preserve the indentation level { let _ = std::path::Path::new("str") .extension() .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); + //~^ case_sensitive_file_extension_comparisons } // The test struct should not trigger the lint failure with .ext12 @@ -39,9 +43,11 @@ fn main() { let _ = std::path::Path::new(&String::new()) .extension() .map_or(false, |ext| ext.eq_ignore_ascii_case("EXT12")); + //~^ case_sensitive_file_extension_comparisons let _ = std::path::Path::new("str") .extension() .map_or(false, |ext| ext.eq_ignore_ascii_case("EXT12")); + //~^ case_sensitive_file_extension_comparisons // Should not trigger the lint failure because of the calls to to_lowercase and to_uppercase let _ = String::new().to_lowercase().ends_with(".EXT12"); diff --git a/tests/ui/case_sensitive_file_extension_comparisons.rs b/tests/ui/case_sensitive_file_extension_comparisons.rs index 690e93c2639a..0c4070a42d4b 100644 --- a/tests/ui/case_sensitive_file_extension_comparisons.rs +++ b/tests/ui/case_sensitive_file_extension_comparisons.rs @@ -12,16 +12,20 @@ impl TestStruct { #[allow(dead_code)] fn is_rust_file(filename: &str) -> bool { filename.ends_with(".rs") + //~^ case_sensitive_file_extension_comparisons } fn main() { // std::string::String and &str should trigger the lint failure with .ext12 let _ = String::new().ends_with(".ext12"); + //~^ case_sensitive_file_extension_comparisons let _ = "str".ends_with(".ext12"); + //~^ case_sensitive_file_extension_comparisons // The fixup should preserve the indentation level { let _ = "str".ends_with(".ext12"); + //~^ case_sensitive_file_extension_comparisons } // The test struct should not trigger the lint failure with .ext12 @@ -29,7 +33,9 @@ fn main() { // std::string::String and &str should trigger the lint failure with .EXT12 let _ = String::new().ends_with(".EXT12"); + //~^ case_sensitive_file_extension_comparisons let _ = "str".ends_with(".EXT12"); + //~^ case_sensitive_file_extension_comparisons // Should not trigger the lint failure because of the calls to to_lowercase and to_uppercase let _ = String::new().to_lowercase().ends_with(".EXT12"); diff --git a/tests/ui/case_sensitive_file_extension_comparisons.stderr b/tests/ui/case_sensitive_file_extension_comparisons.stderr index e21815f251b7..e035534d2699 100644 --- a/tests/ui/case_sensitive_file_extension_comparisons.stderr +++ b/tests/ui/case_sensitive_file_extension_comparisons.stderr @@ -15,7 +15,7 @@ LL + .map_or(false, |ext| ext.eq_ignore_ascii_case("rs")) | error: case-sensitive file extension comparison - --> tests/ui/case_sensitive_file_extension_comparisons.rs:19:13 + --> tests/ui/case_sensitive_file_extension_comparisons.rs:20:13 | LL | let _ = String::new().ends_with(".ext12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); | error: case-sensitive file extension comparison - --> tests/ui/case_sensitive_file_extension_comparisons.rs:20:13 + --> tests/ui/case_sensitive_file_extension_comparisons.rs:22:13 | LL | let _ = "str".ends_with(".ext12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); | error: case-sensitive file extension comparison - --> tests/ui/case_sensitive_file_extension_comparisons.rs:24:17 + --> tests/ui/case_sensitive_file_extension_comparisons.rs:27:17 | LL | let _ = "str".ends_with(".ext12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); | error: case-sensitive file extension comparison - --> tests/ui/case_sensitive_file_extension_comparisons.rs:31:13 + --> tests/ui/case_sensitive_file_extension_comparisons.rs:35:13 | LL | let _ = String::new().ends_with(".EXT12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("EXT12")); | error: case-sensitive file extension comparison - --> tests/ui/case_sensitive_file_extension_comparisons.rs:32:13 + --> tests/ui/case_sensitive_file_extension_comparisons.rs:37:13 | LL | let _ = "str".ends_with(".EXT12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index 0de53a75c623..b2e92d36f402 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -23,101 +23,141 @@ fn main() { // Test clippy::cast_precision_loss let x0 = 1i32; x0 as f32; - //~^ ERROR: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, - //~| NOTE: `-D clippy::cast-precision-loss` implied by `-D warnings` + //~^ cast_precision_loss + + let x1 = 1i64; x1 as f32; - //~^ ERROR: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, + //~^ cast_precision_loss + x1 as f64; - //~^ ERROR: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, + //~^ cast_precision_loss + let x2 = 1u32; x2 as f32; - //~^ ERROR: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, + //~^ cast_precision_loss + let x3 = 1u64; x3 as f32; - //~^ ERROR: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, + //~^ cast_precision_loss + x3 as f64; - //~^ ERROR: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, + //~^ cast_precision_loss + // Test clippy::cast_possible_truncation 1f32 as i32; - //~^ ERROR: casting `f32` to `i32` may truncate the value + //~^ cast_possible_truncation + 1f32 as u32; - //~^ ERROR: casting `f32` to `u32` may truncate the value - //~| ERROR: casting `f32` to `u32` may lose the sign of the value - //~| NOTE: `-D clippy::cast-sign-loss` implied by `-D warnings` + //~^ cast_possible_truncation + //~| cast_sign_loss + + + 1f64 as f32; - //~^ ERROR: casting `f64` to `f32` may truncate the value + //~^ cast_possible_truncation + 1i32 as i8; - //~^ ERROR: casting `i32` to `i8` may truncate the value + //~^ cast_possible_truncation + 1i32 as u8; - //~^ ERROR: casting `i32` to `u8` may truncate the value + //~^ cast_possible_truncation + 1f64 as isize; - //~^ ERROR: casting `f64` to `isize` may truncate the value + //~^ cast_possible_truncation + 1f64 as usize; - //~^ ERROR: casting `f64` to `usize` may truncate the value - //~| ERROR: casting `f64` to `usize` may lose the sign of the value + //~^ cast_possible_truncation + //~| cast_sign_loss + + 1f32 as u32 as u16; - //~^ ERROR: casting `u32` to `u16` may truncate the value - //~| ERROR: casting `f32` to `u32` may truncate the value - //~| ERROR: casting `f32` to `u32` may lose the sign of the value + //~^ cast_possible_truncation + //~| cast_possible_truncation + //~| cast_sign_loss + + + { let _x: i8 = 1i32 as _; - //~^ ERROR: casting `i32` to `i8` may truncate the value + //~^ cast_possible_truncation + 1f32 as i32; - //~^ ERROR: casting `f32` to `i32` may truncate the value + //~^ cast_possible_truncation + 1f64 as i32; - //~^ ERROR: casting `f64` to `i32` may truncate the value + //~^ cast_possible_truncation + 1f32 as u8; - //~^ ERROR: casting `f32` to `u8` may truncate the value - //~| ERROR: casting `f32` to `u8` may lose the sign of the value + //~^ cast_possible_truncation + //~| cast_sign_loss + + } // Test clippy::cast_possible_wrap 1u8 as i8; - //~^ ERROR: casting `u8` to `i8` may wrap around the value - //~| NOTE: `-D clippy::cast-possible-wrap` implied by `-D warnings` + //~^ cast_possible_wrap + + 1u16 as i16; - //~^ ERROR: casting `u16` to `i16` may wrap around the value + //~^ cast_possible_wrap + 1u32 as i32; - //~^ ERROR: casting `u32` to `i32` may wrap around the value + //~^ cast_possible_wrap + 1u64 as i64; - //~^ ERROR: casting `u64` to `i64` may wrap around the value + //~^ cast_possible_wrap + 1usize as isize; - //~^ ERROR: casting `usize` to `isize` may wrap around the value + //~^ cast_possible_wrap + // should not wrap, usize is never 8 bits 1usize as i8; - //~^ ERROR: casting `usize` to `i8` may truncate the value + //~^ cast_possible_truncation + // wraps on 16 bit ptr size 1usize as i16; - //~^ ERROR: casting `usize` to `i16` may truncate the value - //~| ERROR: casting `usize` to `i16` may wrap around the value on targets with 16-bit - //~| NOTE: `usize` and `isize` may be as small as 16 bits on some platforms + //~^ cast_possible_truncation + //~| cast_possible_wrap + + + // wraps on 32 bit ptr size 1usize as i32; - //~^ ERROR: casting `usize` to `i32` may truncate the value on targets with 64-bit wid - //~| ERROR: casting `usize` to `i32` may wrap around the value on targets with 32-bit + //~^ cast_possible_truncation + //~| cast_possible_wrap + + // wraps on 64 bit ptr size 1usize as i64; - //~^ ERROR: casting `usize` to `i64` may wrap around the value on targets with 64-bit + //~^ cast_possible_wrap + // should not wrap, isize is never 8 bits 1u8 as isize; // wraps on 16 bit ptr size 1u16 as isize; - //~^ ERROR: casting `u16` to `isize` may wrap around the value on targets with 16-bit - //~| NOTE: `usize` and `isize` may be as small as 16 bits on some platforms + //~^ cast_possible_wrap + + // wraps on 32 bit ptr size 1u32 as isize; - //~^ ERROR: casting `u32` to `isize` may wrap around the value on targets with 32-bit + //~^ cast_possible_wrap + // wraps on 64 bit ptr size 1u64 as isize; - //~^ ERROR: casting `u64` to `isize` may truncate the value on targets with 32-bit wid - //~| ERROR: casting `u64` to `isize` may wrap around the value on targets with 64-bit + //~^ cast_possible_truncation + //~| cast_possible_wrap + + // Test clippy::cast_sign_loss 1i32 as u32; -1i32 as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + 1isize as usize; -1isize as usize; - //~^ ERROR: casting `isize` to `usize` may lose the sign of the value + //~^ cast_sign_loss + 0i8 as u8; i8::MAX as u8; i16::MAX as u16; @@ -128,11 +168,14 @@ fn main() { (-1i8).saturating_abs() as u8; // abs() can return a negative value in release builds (i8::MIN).abs() as u8; - //~^ ERROR: casting `i8` to `u8` may lose the sign of the value + //~^ cast_sign_loss + (-1i16).saturating_abs() as u16; (-1i32).saturating_abs() as u32; (-1i64).abs() as u64; + //~^ cast_sign_loss (-1isize).abs() as usize; + //~^ cast_sign_loss (-1i8).checked_abs().unwrap() as u8; (i8::MIN).checked_abs().unwrap() as u8; @@ -140,6 +183,7 @@ fn main() { (-1i32).checked_abs().unwrap() as u32; // SAFETY: -1 is a small number which will always return Some (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64; + //~^ cast_sign_loss (-1isize).checked_abs().expect("-1 is a small number") as usize; (-1i8).isqrt() as u8; @@ -155,6 +199,7 @@ fn main() { (-1i32).checked_isqrt().unwrap() as u32; // SAFETY: -1 is a small number which will always return Some (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64; + //~^ cast_sign_loss (-1isize).checked_isqrt().expect("-1 is a small number") as usize; (-1i8).rem_euclid(1i8) as u8; @@ -206,7 +251,8 @@ fn main() { // Test for signed min // should be linted because signed (-99999999999i64).min(1) as i8; - //~^ ERROR: casting `i64` to `i8` may truncate the value + //~^ cast_possible_truncation + // Test for various operations that remove enough bits for the result to fit (999999u64 & 1) as u8; @@ -220,7 +266,8 @@ fn main() { 999999u64.clamp(0, 255) as u8; // should still be linted 999999u64.clamp(0, 256) as u8; - //~^ ERROR: casting `u64` to `u8` may truncate the value + //~^ cast_possible_truncation + #[derive(Clone, Copy)] enum E1 { @@ -243,10 +290,12 @@ fn main() { impl E2 { fn test(self) { let _ = self as u8; - //~^ ERROR: casting `main::E2` to `u8` may truncate the value + //~^ cast_possible_truncation + let _ = Self::B as u8; - //~^ ERROR: casting `main::E2::B` to `u8` will truncate the value - //~| NOTE: `-D clippy::cast-enum-truncation` implied by `-D warnings` + //~^ cast_enum_truncation + + // Don't lint. `255..=256` fits in i16 let _ = self as i16; // Don't lint. @@ -287,9 +336,11 @@ fn main() { impl E5 { fn test(self) { let _ = self as i8; - //~^ ERROR: casting `main::E5` to `i8` may truncate the value + //~^ cast_possible_truncation + let _ = Self::A as i8; - //~^ ERROR: casting `main::E5::A` to `i8` will truncate the value + //~^ cast_enum_truncation + // Don't lint. `-129..=127` fits in i16 let _ = self as i16; // Don't lint. @@ -306,7 +357,8 @@ fn main() { impl E6 { fn test(self) { let _ = self as i16; - //~^ ERROR: casting `main::E6` to `i16` may truncate the value + //~^ cast_possible_truncation + // Don't lint. `2^16-1` fits in u16 let _ = Self::A as u16; // Don't lint. `2^16-1..=2^16` fits in u32 @@ -325,7 +377,8 @@ fn main() { impl E7 { fn test(self) { let _ = self as usize; - //~^ ERROR: casting `main::E7` to `usize` may truncate the value on targets wi + //~^ cast_possible_truncation + // Don't lint. let _ = Self::A as usize; // Don't lint. `2^32-1..=2^32` fits in u64 @@ -372,7 +425,8 @@ fn main() { impl E10 { fn test(self) { let _ = self as u16; - //~^ ERROR: casting `main::E10` to `u16` may truncate the value + //~^ cast_possible_truncation + // Don't lint. let _ = Self::B as u32; // Don't lint. @@ -383,11 +437,13 @@ fn main() { fn avoid_subtract_overflow(q: u32) { let c = (q >> 16) as u8; - //~^ ERROR: casting `u32` to `u8` may truncate the value + //~^ cast_possible_truncation + c as usize; let c = (q / 1000) as u8; - //~^ ERROR: casting `u32` to `u8` may truncate the value + //~^ cast_possible_truncation + c as usize; } @@ -399,70 +455,99 @@ fn issue11642() { fn square(x: i16) -> u32 { let x = x as i32; (x * x) as u32; + //~^ cast_sign_loss x.pow(2) as u32; (-2_i32).saturating_pow(2) as u32 } let _a = |x: i32| -> u32 { (x * x * x * x) as u32 }; + //~^ cast_sign_loss (2_i32).checked_pow(3).unwrap() as u32; + //~^ cast_sign_loss (-2_i32).pow(3) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + (3_i32 % 2) as u32; (3_i32 % -2) as u32; (-5_i32 % 2) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + (-5_i32 % -2) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + (2_i32 >> 1) as u32; (-2_i32 >> 1) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + let x: i32 = 10; (x * x) as u32; + //~^ cast_sign_loss (x * x * x) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + let y: i16 = -2; (y * y * y * y * -2) as u16; - //~^ ERROR: casting `i16` to `u16` may lose the sign of the value + //~^ cast_sign_loss + (y * y * y / y * 2) as u16; + //~^ cast_sign_loss (y * y / y * 2) as u16; - //~^ ERROR: casting `i16` to `u16` may lose the sign of the value + //~^ cast_sign_loss + (y / y * y * -2) as u16; - //~^ ERROR: casting `i16` to `u16` may lose the sign of the value + //~^ cast_sign_loss + //~| eq_op + (y + y + y + -2) as u16; - //~^ ERROR: casting `i16` to `u16` may lose the sign of the value + //~^ cast_sign_loss + (y + y + y + 2) as u16; - //~^ ERROR: casting `i16` to `u16` may lose the sign of the value + //~^ cast_sign_loss + let z: i16 = 2; (z + -2) as u16; - //~^ ERROR: casting `i16` to `u16` may lose the sign of the value + //~^ cast_sign_loss + (z + z + 2) as u16; + //~^ cast_sign_loss fn foo(a: i32, b: i32, c: i32) -> u32 { (a * a * b * b * c * c) as u32; + //~^ cast_sign_loss (a * b * c) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + (a * -b * c) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + (a * b * c * c) as u32; + //~^ cast_sign_loss (a * -2) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + (a * b * c * -2) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + (a / b) as u32; + //~^ cast_sign_loss (a / b * c) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + (a / b + b * c) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + a.saturating_pow(3) as u32; - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + (a.abs() * b.pow(2) / c.abs()) as u32 - //~^ ERROR: casting `i32` to `u32` may lose the sign of the value + //~^ cast_sign_loss + } } @@ -470,8 +555,11 @@ fn issue11738() { macro_rules! m { () => { let _ = i32::MIN as u32; // cast_sign_loss + //~^ cast_sign_loss let _ = u32::MAX as u8; // cast_possible_truncation + //~^ cast_possible_truncation let _ = std::f64::consts::PI as f32; // cast_possible_truncation + //~^ cast_possible_truncation let _ = 0i8 as i32; // cast_lossless }; } @@ -481,6 +569,8 @@ fn issue11738() { fn issue12506() -> usize { let bar: Result, u32> = Ok(Some(10)); bar.unwrap().unwrap() as usize + //~^ cast_possible_truncation + //~| cast_sign_loss } fn issue12721() { @@ -496,7 +586,9 @@ fn issue12721() { let _ = (999999 & (x() & 255)) as u8; (256 & 999999u64) as u8; - //~^ ERROR: casting `u64` to `u8` may truncate the value + //~^ cast_possible_truncation + (255 % 999999u64) as u8; - //~^ ERROR: casting `u64` to `u8` may truncate the value + //~^ cast_possible_truncation + } diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 452482fc88e2..daabb8192141 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -8,37 +8,37 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:29:5 + --> tests/ui/cast.rs:30:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:31:5 + --> tests/ui/cast.rs:33:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:34:5 + --> tests/ui/cast.rs:37:5 | LL | x2 as f32; | ^^^^^^^^^ error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:37:5 + --> tests/ui/cast.rs:41:5 | LL | x3 as f32; | ^^^^^^^^^ error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:39:5 + --> tests/ui/cast.rs:44:5 | LL | x3 as f64; | ^^^^^^^^^ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:42:5 + --> tests/ui/cast.rs:48:5 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | 1f32 as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]` error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:44:5 + --> tests/ui/cast.rs:51:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | 1f32 as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:44:5 + --> tests/ui/cast.rs:51:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | 1f32 as u32; = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]` error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:48:5 + --> tests/ui/cast.rs:57:5 | LL | 1f64 as f32; | ^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | 1f64 as f32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:50:5 + --> tests/ui/cast.rs:60:5 | LL | 1i32 as i8; | ^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | i8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u8` may truncate the value - --> tests/ui/cast.rs:52:5 + --> tests/ui/cast.rs:63:5 | LL | 1i32 as u8; | ^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | u8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `f64` to `isize` may truncate the value - --> tests/ui/cast.rs:54:5 + --> tests/ui/cast.rs:66:5 | LL | 1f64 as isize; | ^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | 1f64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may truncate the value - --> tests/ui/cast.rs:56:5 + --> tests/ui/cast.rs:69:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ @@ -113,13 +113,13 @@ LL | 1f64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:56:5 + --> tests/ui/cast.rs:69:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ error: casting `u32` to `u16` may truncate the value - --> tests/ui/cast.rs:59:5 + --> tests/ui/cast.rs:74:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | u16::try_from(1f32 as u32); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:59:5 + --> tests/ui/cast.rs:74:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ @@ -139,13 +139,13 @@ LL | 1f32 as u32 as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:59:5 + --> tests/ui/cast.rs:74:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:64:22 + --> tests/ui/cast.rs:82:22 | LL | let _x: i8 = 1i32 as _; | ^^^^^^^^^ @@ -157,7 +157,7 @@ LL | let _x: i8 = 1i32.try_into(); | ~~~~~~~~~~~~~~~ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:66:9 + --> tests/ui/cast.rs:85:9 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | 1f32 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `i32` may truncate the value - --> tests/ui/cast.rs:68:9 + --> tests/ui/cast.rs:88:9 | LL | 1f64 as i32; | ^^^^^^^^^^^ @@ -173,7 +173,7 @@ LL | 1f64 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may truncate the value - --> tests/ui/cast.rs:70:9 + --> tests/ui/cast.rs:91:9 | LL | 1f32 as u8; | ^^^^^^^^^^ @@ -181,13 +181,13 @@ LL | 1f32 as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:70:9 + --> tests/ui/cast.rs:91:9 | LL | 1f32 as u8; | ^^^^^^^^^^ error: casting `u8` to `i8` may wrap around the value - --> tests/ui/cast.rs:75:5 + --> tests/ui/cast.rs:98:5 | LL | 1u8 as i8; | ^^^^^^^^^ @@ -196,31 +196,31 @@ LL | 1u8 as i8; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `u16` to `i16` may wrap around the value - --> tests/ui/cast.rs:78:5 + --> tests/ui/cast.rs:102:5 | LL | 1u16 as i16; | ^^^^^^^^^^^ error: casting `u32` to `i32` may wrap around the value - --> tests/ui/cast.rs:80:5 + --> tests/ui/cast.rs:105:5 | LL | 1u32 as i32; | ^^^^^^^^^^^ error: casting `u64` to `i64` may wrap around the value - --> tests/ui/cast.rs:82:5 + --> tests/ui/cast.rs:108:5 | LL | 1u64 as i64; | ^^^^^^^^^^^ error: casting `usize` to `isize` may wrap around the value - --> tests/ui/cast.rs:84:5 + --> tests/ui/cast.rs:111:5 | LL | 1usize as isize; | ^^^^^^^^^^^^^^^ error: casting `usize` to `i8` may truncate the value - --> tests/ui/cast.rs:87:5 + --> tests/ui/cast.rs:115:5 | LL | 1usize as i8; | ^^^^^^^^^^^^ @@ -232,7 +232,7 @@ LL | i8::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may truncate the value - --> tests/ui/cast.rs:90:5 + --> tests/ui/cast.rs:119:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -244,7 +244,7 @@ LL | i16::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:90:5 + --> tests/ui/cast.rs:119:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | 1usize as i16; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:95:5 + --> tests/ui/cast.rs:126:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -265,19 +265,19 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:95:5 + --> tests/ui/cast.rs:126:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:99:5 + --> tests/ui/cast.rs:132:5 | LL | 1usize as i64; | ^^^^^^^^^^^^^ error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:104:5 + --> tests/ui/cast.rs:138:5 | LL | 1u16 as isize; | ^^^^^^^^^^^^^ @@ -286,13 +286,13 @@ LL | 1u16 as isize; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:108:5 + --> tests/ui/cast.rs:143:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:111:5 + --> tests/ui/cast.rs:147:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -304,55 +304,55 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:111:5 + --> tests/ui/cast.rs:147:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:116:5 + --> tests/ui/cast.rs:154:5 | LL | -1i32 as u32; | ^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:119:5 + --> tests/ui/cast.rs:158:5 | LL | -1isize as usize; | ^^^^^^^^^^^^^^^^ error: casting `i8` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:130:5 + --> tests/ui/cast.rs:170:5 | LL | (i8::MIN).abs() as u8; | ^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:134:5 + --> tests/ui/cast.rs:175:5 | LL | (-1i64).abs() as u64; | ^^^^^^^^^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:135:5 + --> tests/ui/cast.rs:177:5 | LL | (-1isize).abs() as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:142:5 + --> tests/ui/cast.rs:185:5 | LL | (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:157:5 + --> tests/ui/cast.rs:201:5 | LL | (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `i8` may truncate the value - --> tests/ui/cast.rs:208:5 + --> tests/ui/cast.rs:253:5 | LL | (-99999999999i64).min(1) as i8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -364,7 +364,7 @@ LL | i8::try_from((-99999999999i64).min(1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:222:5 + --> tests/ui/cast.rs:268:5 | LL | 999999u64.clamp(0, 256) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -376,7 +376,7 @@ LL | u8::try_from(999999u64.clamp(0, 256)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E2` to `u8` may truncate the value - --> tests/ui/cast.rs:245:21 + --> tests/ui/cast.rs:292:21 | LL | let _ = self as u8; | ^^^^^^^^^^ @@ -388,7 +388,7 @@ LL | let _ = u8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E2::B` to `u8` will truncate the value - --> tests/ui/cast.rs:247:21 + --> tests/ui/cast.rs:295:21 | LL | let _ = Self::B as u8; | ^^^^^^^^^^^^^ @@ -397,7 +397,7 @@ LL | let _ = Self::B as u8; = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]` error: casting `main::E5` to `i8` may truncate the value - --> tests/ui/cast.rs:289:21 + --> tests/ui/cast.rs:338:21 | LL | let _ = self as i8; | ^^^^^^^^^^ @@ -409,13 +409,13 @@ LL | let _ = i8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E5::A` to `i8` will truncate the value - --> tests/ui/cast.rs:291:21 + --> tests/ui/cast.rs:341:21 | LL | let _ = Self::A as i8; | ^^^^^^^^^^^^^ error: casting `main::E6` to `i16` may truncate the value - --> tests/ui/cast.rs:308:21 + --> tests/ui/cast.rs:359:21 | LL | let _ = self as i16; | ^^^^^^^^^^^ @@ -427,7 +427,7 @@ LL | let _ = i16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:327:21 + --> tests/ui/cast.rs:379:21 | LL | let _ = self as usize; | ^^^^^^^^^^^^^ @@ -439,7 +439,7 @@ LL | let _ = usize::try_from(self); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E10` to `u16` may truncate the value - --> tests/ui/cast.rs:374:21 + --> tests/ui/cast.rs:427:21 | LL | let _ = self as u16; | ^^^^^^^^^^^ @@ -451,7 +451,7 @@ LL | let _ = u16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:385:13 + --> tests/ui/cast.rs:439:13 | LL | let c = (q >> 16) as u8; | ^^^^^^^^^^^^^^^ @@ -463,7 +463,7 @@ LL | let c = u8::try_from(q >> 16); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:389:13 + --> tests/ui/cast.rs:444:13 | LL | let c = (q / 1000) as u8; | ^^^^^^^^^^^^^^^^ @@ -475,85 +475,85 @@ LL | let c = u8::try_from(q / 1000); | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:401:9 + --> tests/ui/cast.rs:457:9 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:406:32 + --> tests/ui/cast.rs:463:32 | LL | let _a = |x: i32| -> u32 { (x * x * x * x) as u32 }; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:408:5 + --> tests/ui/cast.rs:466:5 | LL | (2_i32).checked_pow(3).unwrap() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:409:5 + --> tests/ui/cast.rs:468:5 | LL | (-2_i32).pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:414:5 + --> tests/ui/cast.rs:474:5 | LL | (-5_i32 % 2) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:416:5 + --> tests/ui/cast.rs:477:5 | LL | (-5_i32 % -2) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:419:5 + --> tests/ui/cast.rs:481:5 | LL | (-2_i32 >> 1) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:423:5 + --> tests/ui/cast.rs:486:5 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:424:5 + --> tests/ui/cast.rs:488:5 | LL | (x * x * x) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:428:5 + --> tests/ui/cast.rs:493:5 | LL | (y * y * y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:430:5 + --> tests/ui/cast.rs:496:5 | LL | (y * y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:431:5 + --> tests/ui/cast.rs:498:5 | LL | (y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:433:5 + --> tests/ui/cast.rs:501:5 | LL | (y / y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `/` - --> tests/ui/cast.rs:433:6 + --> tests/ui/cast.rs:501:6 | LL | (y / y * y * -2) as u16; | ^^^^^ @@ -561,97 +561,97 @@ LL | (y / y * y * -2) as u16; = note: `#[deny(clippy::eq_op)]` on by default error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:436:5 + --> tests/ui/cast.rs:506:5 | LL | (y + y + y + -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:438:5 + --> tests/ui/cast.rs:509:5 | LL | (y + y + y + 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:442:5 + --> tests/ui/cast.rs:514:5 | LL | (z + -2) as u16; | ^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:444:5 + --> tests/ui/cast.rs:517:5 | LL | (z + z + 2) as u16; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:447:9 + --> tests/ui/cast.rs:521:9 | LL | (a * a * b * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:448:9 + --> tests/ui/cast.rs:523:9 | LL | (a * b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:450:9 + --> tests/ui/cast.rs:526:9 | LL | (a * -b * c) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:452:9 + --> tests/ui/cast.rs:529:9 | LL | (a * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:453:9 + --> tests/ui/cast.rs:531:9 | LL | (a * -2) as u32; | ^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:455:9 + --> tests/ui/cast.rs:534:9 | LL | (a * b * c * -2) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:457:9 + --> tests/ui/cast.rs:537:9 | LL | (a / b) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:458:9 + --> tests/ui/cast.rs:539:9 | LL | (a / b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:460:9 + --> tests/ui/cast.rs:542:9 | LL | (a / b + b * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:462:9 + --> tests/ui/cast.rs:545:9 | LL | a.saturating_pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:464:9 + --> tests/ui/cast.rs:548:9 | LL | (a.abs() * b.pow(2) / c.abs()) as u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:472:21 + --> tests/ui/cast.rs:557:21 | LL | let _ = i32::MIN as u32; // cast_sign_loss | ^^^^^^^^^^^^^^^ @@ -662,7 +662,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:473:21 + --> tests/ui/cast.rs:559:21 | LL | let _ = u32::MAX as u8; // cast_possible_truncation | ^^^^^^^^^^^^^^ @@ -678,7 +678,7 @@ LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:474:21 + --> tests/ui/cast.rs:561:21 | LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -690,7 +690,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:483:5 + --> tests/ui/cast.rs:571:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -702,13 +702,13 @@ LL | usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:483:5 + --> tests/ui/cast.rs:571:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:498:5 + --> tests/ui/cast.rs:588:5 | LL | (256 & 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ LL | u8::try_from(256 & 999999u64); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:500:5 + --> tests/ui/cast.rs:591:5 | LL | (255 % 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_abs_to_unsigned.fixed b/tests/ui/cast_abs_to_unsigned.fixed index 6ca01b7cc367..b55c22f5ca83 100644 --- a/tests/ui/cast_abs_to_unsigned.fixed +++ b/tests/ui/cast_abs_to_unsigned.fixed @@ -4,30 +4,47 @@ fn main() { let x: i32 = -42; let y: u32 = x.unsigned_abs(); + //~^ cast_abs_to_unsigned println!("The absolute value of {} is {}", x, y); let a: i32 = -3; let _: usize = a.unsigned_abs() as usize; + //~^ cast_abs_to_unsigned let _: usize = a.unsigned_abs() as _; + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as usize; + //~^ cast_abs_to_unsigned let a: i64 = -3; let _ = a.unsigned_abs() as usize; + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as u8; + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as u16; + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as u32; + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs(); + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as u128; + //~^ cast_abs_to_unsigned let a: isize = -3; let _ = a.unsigned_abs(); + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as u8; + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as u16; + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as u32; + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as u64; + //~^ cast_abs_to_unsigned let _ = a.unsigned_abs() as u128; + //~^ cast_abs_to_unsigned let _ = (x as i64 - y as i64).unsigned_abs() as u32; + //~^ cast_abs_to_unsigned } #[clippy::msrv = "1.50"] @@ -40,4 +57,5 @@ fn msrv_1_50() { fn msrv_1_51() { let x: i32 = 10; assert_eq!(10u32, x.unsigned_abs()); + //~^ cast_abs_to_unsigned } diff --git a/tests/ui/cast_abs_to_unsigned.rs b/tests/ui/cast_abs_to_unsigned.rs index 190a77c10232..466aa6aeb1fb 100644 --- a/tests/ui/cast_abs_to_unsigned.rs +++ b/tests/ui/cast_abs_to_unsigned.rs @@ -4,30 +4,47 @@ fn main() { let x: i32 = -42; let y: u32 = x.abs() as u32; + //~^ cast_abs_to_unsigned println!("The absolute value of {} is {}", x, y); let a: i32 = -3; let _: usize = a.abs() as usize; + //~^ cast_abs_to_unsigned let _: usize = a.abs() as _; + //~^ cast_abs_to_unsigned let _ = a.abs() as usize; + //~^ cast_abs_to_unsigned let a: i64 = -3; let _ = a.abs() as usize; + //~^ cast_abs_to_unsigned let _ = a.abs() as u8; + //~^ cast_abs_to_unsigned let _ = a.abs() as u16; + //~^ cast_abs_to_unsigned let _ = a.abs() as u32; + //~^ cast_abs_to_unsigned let _ = a.abs() as u64; + //~^ cast_abs_to_unsigned let _ = a.abs() as u128; + //~^ cast_abs_to_unsigned let a: isize = -3; let _ = a.abs() as usize; + //~^ cast_abs_to_unsigned let _ = a.abs() as u8; + //~^ cast_abs_to_unsigned let _ = a.abs() as u16; + //~^ cast_abs_to_unsigned let _ = a.abs() as u32; + //~^ cast_abs_to_unsigned let _ = a.abs() as u64; + //~^ cast_abs_to_unsigned let _ = a.abs() as u128; + //~^ cast_abs_to_unsigned let _ = (x as i64 - y as i64).abs() as u32; + //~^ cast_abs_to_unsigned } #[clippy::msrv = "1.50"] @@ -40,4 +57,5 @@ fn msrv_1_50() { fn msrv_1_51() { let x: i32 = 10; assert_eq!(10u32, x.abs() as u32); + //~^ cast_abs_to_unsigned } diff --git a/tests/ui/cast_abs_to_unsigned.stderr b/tests/ui/cast_abs_to_unsigned.stderr index 96e5c1724a51..26220693969c 100644 --- a/tests/ui/cast_abs_to_unsigned.stderr +++ b/tests/ui/cast_abs_to_unsigned.stderr @@ -8,103 +8,103 @@ LL | let y: u32 = x.abs() as u32; = help: to override `-D warnings` add `#[allow(clippy::cast_abs_to_unsigned)]` error: casting the result of `i32::abs()` to usize - --> tests/ui/cast_abs_to_unsigned.rs:10:20 + --> tests/ui/cast_abs_to_unsigned.rs:11:20 | LL | let _: usize = a.abs() as usize; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `i32::abs()` to usize - --> tests/ui/cast_abs_to_unsigned.rs:11:20 + --> tests/ui/cast_abs_to_unsigned.rs:13:20 | LL | let _: usize = a.abs() as _; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `i32::abs()` to usize - --> tests/ui/cast_abs_to_unsigned.rs:12:13 - | -LL | let _ = a.abs() as usize; - | ^^^^^^^ help: replace with: `a.unsigned_abs()` - -error: casting the result of `i64::abs()` to usize --> tests/ui/cast_abs_to_unsigned.rs:15:13 | LL | let _ = a.abs() as usize; | ^^^^^^^ help: replace with: `a.unsigned_abs()` +error: casting the result of `i64::abs()` to usize + --> tests/ui/cast_abs_to_unsigned.rs:19:13 + | +LL | let _ = a.abs() as usize; + | ^^^^^^^ help: replace with: `a.unsigned_abs()` + error: casting the result of `i64::abs()` to u8 - --> tests/ui/cast_abs_to_unsigned.rs:16:13 + --> tests/ui/cast_abs_to_unsigned.rs:21:13 | LL | let _ = a.abs() as u8; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `i64::abs()` to u16 - --> tests/ui/cast_abs_to_unsigned.rs:17:13 + --> tests/ui/cast_abs_to_unsigned.rs:23:13 | LL | let _ = a.abs() as u16; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `i64::abs()` to u32 - --> tests/ui/cast_abs_to_unsigned.rs:18:13 + --> tests/ui/cast_abs_to_unsigned.rs:25:13 | LL | let _ = a.abs() as u32; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `i64::abs()` to u64 - --> tests/ui/cast_abs_to_unsigned.rs:19:13 + --> tests/ui/cast_abs_to_unsigned.rs:27:13 | LL | let _ = a.abs() as u64; | ^^^^^^^^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `i64::abs()` to u128 - --> tests/ui/cast_abs_to_unsigned.rs:20:13 + --> tests/ui/cast_abs_to_unsigned.rs:29:13 | LL | let _ = a.abs() as u128; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `isize::abs()` to usize - --> tests/ui/cast_abs_to_unsigned.rs:23:13 + --> tests/ui/cast_abs_to_unsigned.rs:33:13 | LL | let _ = a.abs() as usize; | ^^^^^^^^^^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `isize::abs()` to u8 - --> tests/ui/cast_abs_to_unsigned.rs:24:13 + --> tests/ui/cast_abs_to_unsigned.rs:35:13 | LL | let _ = a.abs() as u8; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `isize::abs()` to u16 - --> tests/ui/cast_abs_to_unsigned.rs:25:13 + --> tests/ui/cast_abs_to_unsigned.rs:37:13 | LL | let _ = a.abs() as u16; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `isize::abs()` to u32 - --> tests/ui/cast_abs_to_unsigned.rs:26:13 + --> tests/ui/cast_abs_to_unsigned.rs:39:13 | LL | let _ = a.abs() as u32; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `isize::abs()` to u64 - --> tests/ui/cast_abs_to_unsigned.rs:27:13 + --> tests/ui/cast_abs_to_unsigned.rs:41:13 | LL | let _ = a.abs() as u64; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `isize::abs()` to u128 - --> tests/ui/cast_abs_to_unsigned.rs:28:13 + --> tests/ui/cast_abs_to_unsigned.rs:43:13 | LL | let _ = a.abs() as u128; | ^^^^^^^ help: replace with: `a.unsigned_abs()` error: casting the result of `i64::abs()` to u32 - --> tests/ui/cast_abs_to_unsigned.rs:30:13 + --> tests/ui/cast_abs_to_unsigned.rs:46:13 | LL | let _ = (x as i64 - y as i64).abs() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `(x as i64 - y as i64).unsigned_abs()` error: casting the result of `i32::abs()` to u32 - --> tests/ui/cast_abs_to_unsigned.rs:42:23 + --> tests/ui/cast_abs_to_unsigned.rs:59:23 | LL | assert_eq!(10u32, x.abs() as u32); | ^^^^^^^^^^^^^^ help: replace with: `x.unsigned_abs()` diff --git a/tests/ui/cast_alignment.rs b/tests/ui/cast_alignment.rs index 72f5d4268cc1..1f14cb8a8452 100644 --- a/tests/ui/cast_alignment.rs +++ b/tests/ui/cast_alignment.rs @@ -17,16 +17,20 @@ fn main() { // cast to more-strictly-aligned type (&1u8 as *const u8) as *const u16; - //~^ ERROR: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) - //~| NOTE: `-D clippy::cast-ptr-alignment` implied by `-D warnings` + //~^ cast_ptr_alignment + + (&mut 1u8 as *mut u8) as *mut u16; - //~^ ERROR: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 + //~^ cast_ptr_alignment + // cast to more-strictly-aligned type, but with the `pointer::cast` function. (&1u8 as *const u8).cast::(); - //~^ ERROR: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) + //~^ cast_ptr_alignment + (&mut 1u8 as *mut u8).cast::(); - //~^ ERROR: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 + //~^ cast_ptr_alignment + /* These should be ok */ diff --git a/tests/ui/cast_alignment.stderr b/tests/ui/cast_alignment.stderr index b32624f958fc..a1598eb1b6b4 100644 --- a/tests/ui/cast_alignment.stderr +++ b/tests/ui/cast_alignment.stderr @@ -8,19 +8,19 @@ LL | (&1u8 as *const u8) as *const u16; = help: to override `-D warnings` add `#[allow(clippy::cast_ptr_alignment)]` error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:22:5 + --> tests/ui/cast_alignment.rs:23:5 | LL | (&mut 1u8 as *mut u8) as *mut u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:26:5 + --> tests/ui/cast_alignment.rs:28:5 | LL | (&1u8 as *const u8).cast::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:28:5 + --> tests/ui/cast_alignment.rs:31:5 | LL | (&mut 1u8 as *mut u8).cast::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_enum_constructor.rs b/tests/ui/cast_enum_constructor.rs index 3226f487b3af..9de5b4095556 100644 --- a/tests/ui/cast_enum_constructor.rs +++ b/tests/ui/cast_enum_constructor.rs @@ -11,10 +11,12 @@ fn main() { } let _ = Foo::Y as usize; - //~^ ERROR: cast of an enum tuple constructor to an integer - //~| NOTE: `-D clippy::cast-enum-constructor` implied by `-D warnings` + //~^ cast_enum_constructor + + let _ = Foo::Y as isize; - //~^ ERROR: cast of an enum tuple constructor to an integer + //~^ cast_enum_constructor + let _ = Foo::Y as fn(u32) -> Foo; let _ = Bar::X as usize; } diff --git a/tests/ui/cast_enum_constructor.stderr b/tests/ui/cast_enum_constructor.stderr index 67cca6807315..890d88cacdf2 100644 --- a/tests/ui/cast_enum_constructor.stderr +++ b/tests/ui/cast_enum_constructor.stderr @@ -8,7 +8,7 @@ LL | let _ = Foo::Y as usize; = help: to override `-D warnings` add `#[allow(clippy::cast_enum_constructor)]` error: cast of an enum tuple constructor to an integer - --> tests/ui/cast_enum_constructor.rs:16:13 + --> tests/ui/cast_enum_constructor.rs:17:13 | LL | let _ = Foo::Y as isize; | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_lossless_bool.fixed b/tests/ui/cast_lossless_bool.fixed index 51a38a60cf6b..21dc280a5864 100644 --- a/tests/ui/cast_lossless_bool.fixed +++ b/tests/ui/cast_lossless_bool.fixed @@ -6,23 +6,37 @@ type U8 = u8; fn main() { // Test clippy::cast_lossless with casts to integer types let _ = u8::from(true); + //~^ cast_lossless let _ = u16::from(true); + //~^ cast_lossless let _ = u32::from(true); + //~^ cast_lossless let _ = u64::from(true); + //~^ cast_lossless let _ = u128::from(true); + //~^ cast_lossless let _ = usize::from(true); + //~^ cast_lossless let _ = i8::from(true); + //~^ cast_lossless let _ = i16::from(true); + //~^ cast_lossless let _ = i32::from(true); + //~^ cast_lossless let _ = i64::from(true); + //~^ cast_lossless let _ = i128::from(true); + //~^ cast_lossless let _ = isize::from(true); + //~^ cast_lossless // Test with an expression wrapped in parens let _ = u16::from(true | false); + //~^ cast_lossless let _ = U8::from(true); + //~^ cast_lossless } // The lint would suggest using `u32::from(input)` here but the `XX::from` function is not const, @@ -51,4 +65,5 @@ fn msrv_1_27() { #[clippy::msrv = "1.28"] fn msrv_1_28() { let _ = u8::from(true); + //~^ cast_lossless } diff --git a/tests/ui/cast_lossless_bool.rs b/tests/ui/cast_lossless_bool.rs index cb307bd68e43..d03badd9a7bc 100644 --- a/tests/ui/cast_lossless_bool.rs +++ b/tests/ui/cast_lossless_bool.rs @@ -6,23 +6,37 @@ type U8 = u8; fn main() { // Test clippy::cast_lossless with casts to integer types let _ = true as u8; + //~^ cast_lossless let _ = true as u16; + //~^ cast_lossless let _ = true as u32; + //~^ cast_lossless let _ = true as u64; + //~^ cast_lossless let _ = true as u128; + //~^ cast_lossless let _ = true as usize; + //~^ cast_lossless let _ = true as i8; + //~^ cast_lossless let _ = true as i16; + //~^ cast_lossless let _ = true as i32; + //~^ cast_lossless let _ = true as i64; + //~^ cast_lossless let _ = true as i128; + //~^ cast_lossless let _ = true as isize; + //~^ cast_lossless // Test with an expression wrapped in parens let _ = (true | false) as u16; + //~^ cast_lossless let _ = true as U8; + //~^ cast_lossless } // The lint would suggest using `u32::from(input)` here but the `XX::from` function is not const, @@ -51,4 +65,5 @@ fn msrv_1_27() { #[clippy::msrv = "1.28"] fn msrv_1_28() { let _ = true as u8; + //~^ cast_lossless } diff --git a/tests/ui/cast_lossless_bool.stderr b/tests/ui/cast_lossless_bool.stderr index 82d6b2e4b8e6..54edab2856cb 100644 --- a/tests/ui/cast_lossless_bool.stderr +++ b/tests/ui/cast_lossless_bool.stderr @@ -13,7 +13,7 @@ LL | let _ = u8::from(true); | ~~~~~~~~~~~~~~ error: casts from `bool` to `u16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:9:13 + --> tests/ui/cast_lossless_bool.rs:10:13 | LL | let _ = true as u16; | ^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = u16::from(true); | ~~~~~~~~~~~~~~~ error: casts from `bool` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:10:13 + --> tests/ui/cast_lossless_bool.rs:12:13 | LL | let _ = true as u32; | ^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | let _ = u32::from(true); | ~~~~~~~~~~~~~~~ error: casts from `bool` to `u64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:11:13 + --> tests/ui/cast_lossless_bool.rs:14:13 | LL | let _ = true as u64; | ^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = u64::from(true); | ~~~~~~~~~~~~~~~ error: casts from `bool` to `u128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:12:13 + --> tests/ui/cast_lossless_bool.rs:16:13 | LL | let _ = true as u128; | ^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | let _ = u128::from(true); | ~~~~~~~~~~~~~~~~ error: casts from `bool` to `usize` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:13:13 + --> tests/ui/cast_lossless_bool.rs:18:13 | LL | let _ = true as usize; | ^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let _ = usize::from(true); | ~~~~~~~~~~~~~~~~~ error: casts from `bool` to `i8` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:15:13 + --> tests/ui/cast_lossless_bool.rs:21:13 | LL | let _ = true as i8; | ^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | let _ = i8::from(true); | ~~~~~~~~~~~~~~ error: casts from `bool` to `i16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:16:13 + --> tests/ui/cast_lossless_bool.rs:23:13 | LL | let _ = true as i16; | ^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _ = i16::from(true); | ~~~~~~~~~~~~~~~ error: casts from `bool` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:17:13 + --> tests/ui/cast_lossless_bool.rs:25:13 | LL | let _ = true as i32; | ^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | let _ = i32::from(true); | ~~~~~~~~~~~~~~~ error: casts from `bool` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:18:13 + --> tests/ui/cast_lossless_bool.rs:27:13 | LL | let _ = true as i64; | ^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | let _ = i64::from(true); | ~~~~~~~~~~~~~~~ error: casts from `bool` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:19:13 + --> tests/ui/cast_lossless_bool.rs:29:13 | LL | let _ = true as i128; | ^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let _ = i128::from(true); | ~~~~~~~~~~~~~~~~ error: casts from `bool` to `isize` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:20:13 + --> tests/ui/cast_lossless_bool.rs:31:13 | LL | let _ = true as isize; | ^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | let _ = isize::from(true); | ~~~~~~~~~~~~~~~~~ error: casts from `bool` to `u16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:23:13 + --> tests/ui/cast_lossless_bool.rs:35:13 | LL | let _ = (true | false) as u16; | ^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | let _ = u16::from(true | false); | ~~~~~~~~~~~~~~~~~~~~~~~ error: casts from `bool` to `u8` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:25:13 + --> tests/ui/cast_lossless_bool.rs:38:13 | LL | let _ = true as U8; | ^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | let _ = U8::from(true); | ~~~~~~~~~~~~~~ error: casts from `bool` to `u8` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_bool.rs:53:13 + --> tests/ui/cast_lossless_bool.rs:67:13 | LL | let _ = true as u8; | ^^^^^^^^^^ diff --git a/tests/ui/cast_lossless_float.fixed b/tests/ui/cast_lossless_float.fixed index 163432631e13..6ddd5f10a2ca 100644 --- a/tests/ui/cast_lossless_float.fixed +++ b/tests/ui/cast_lossless_float.fixed @@ -10,25 +10,38 @@ fn main() { // Test clippy::cast_lossless with casts to floating-point types let x0 = 1i8; let _ = f32::from(x0); + //~^ cast_lossless let _ = f64::from(x0); + //~^ cast_lossless let _ = F32::from(x0); + //~^ cast_lossless let _ = F64::from(x0); + //~^ cast_lossless let x1 = 1u8; let _ = f32::from(x1); + //~^ cast_lossless let _ = f64::from(x1); + //~^ cast_lossless let x2 = 1i16; let _ = f32::from(x2); + //~^ cast_lossless let _ = f64::from(x2); + //~^ cast_lossless let x3 = 1u16; let _ = f32::from(x3); + //~^ cast_lossless let _ = f64::from(x3); + //~^ cast_lossless let x4 = 1i32; let _ = f64::from(x4); + //~^ cast_lossless let x5 = 1u32; let _ = f64::from(x5); + //~^ cast_lossless // Test with casts from floating-point types let _ = f64::from(1.0f32); + //~^ cast_lossless } // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, diff --git a/tests/ui/cast_lossless_float.rs b/tests/ui/cast_lossless_float.rs index afb2a3d890ee..fe5a90544538 100644 --- a/tests/ui/cast_lossless_float.rs +++ b/tests/ui/cast_lossless_float.rs @@ -10,25 +10,38 @@ fn main() { // Test clippy::cast_lossless with casts to floating-point types let x0 = 1i8; let _ = x0 as f32; + //~^ cast_lossless let _ = x0 as f64; + //~^ cast_lossless let _ = x0 as F32; + //~^ cast_lossless let _ = x0 as F64; + //~^ cast_lossless let x1 = 1u8; let _ = x1 as f32; + //~^ cast_lossless let _ = x1 as f64; + //~^ cast_lossless let x2 = 1i16; let _ = x2 as f32; + //~^ cast_lossless let _ = x2 as f64; + //~^ cast_lossless let x3 = 1u16; let _ = x3 as f32; + //~^ cast_lossless let _ = x3 as f64; + //~^ cast_lossless let x4 = 1i32; let _ = x4 as f64; + //~^ cast_lossless let x5 = 1u32; let _ = x5 as f64; + //~^ cast_lossless // Test with casts from floating-point types let _ = 1.0f32 as f64; + //~^ cast_lossless } // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, diff --git a/tests/ui/cast_lossless_float.stderr b/tests/ui/cast_lossless_float.stderr index b36f8bcecf58..c983d4ccc6be 100644 --- a/tests/ui/cast_lossless_float.stderr +++ b/tests/ui/cast_lossless_float.stderr @@ -13,7 +13,7 @@ LL | let _ = f32::from(x0); | ~~~~~~~~~~~~~ error: casts from `i8` to `f64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:13:13 + --> tests/ui/cast_lossless_float.rs:14:13 | LL | let _ = x0 as f64; | ^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = f64::from(x0); | ~~~~~~~~~~~~~ error: casts from `i8` to `f32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:14:13 + --> tests/ui/cast_lossless_float.rs:16:13 | LL | let _ = x0 as F32; | ^^^^^^^^^ @@ -37,7 +37,7 @@ LL | let _ = F32::from(x0); | ~~~~~~~~~~~~~ error: casts from `i8` to `f64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:15:13 + --> tests/ui/cast_lossless_float.rs:18:13 | LL | let _ = x0 as F64; | ^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = F64::from(x0); | ~~~~~~~~~~~~~ error: casts from `u8` to `f32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:17:13 + --> tests/ui/cast_lossless_float.rs:21:13 | LL | let _ = x1 as f32; | ^^^^^^^^^ @@ -61,7 +61,7 @@ LL | let _ = f32::from(x1); | ~~~~~~~~~~~~~ error: casts from `u8` to `f64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:18:13 + --> tests/ui/cast_lossless_float.rs:23:13 | LL | let _ = x1 as f64; | ^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let _ = f64::from(x1); | ~~~~~~~~~~~~~ error: casts from `i16` to `f32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:20:13 + --> tests/ui/cast_lossless_float.rs:26:13 | LL | let _ = x2 as f32; | ^^^^^^^^^ @@ -85,7 +85,7 @@ LL | let _ = f32::from(x2); | ~~~~~~~~~~~~~ error: casts from `i16` to `f64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:21:13 + --> tests/ui/cast_lossless_float.rs:28:13 | LL | let _ = x2 as f64; | ^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _ = f64::from(x2); | ~~~~~~~~~~~~~ error: casts from `u16` to `f32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:23:13 + --> tests/ui/cast_lossless_float.rs:31:13 | LL | let _ = x3 as f32; | ^^^^^^^^^ @@ -109,7 +109,7 @@ LL | let _ = f32::from(x3); | ~~~~~~~~~~~~~ error: casts from `u16` to `f64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:24:13 + --> tests/ui/cast_lossless_float.rs:33:13 | LL | let _ = x3 as f64; | ^^^^^^^^^ @@ -121,7 +121,7 @@ LL | let _ = f64::from(x3); | ~~~~~~~~~~~~~ error: casts from `i32` to `f64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:26:13 + --> tests/ui/cast_lossless_float.rs:36:13 | LL | let _ = x4 as f64; | ^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let _ = f64::from(x4); | ~~~~~~~~~~~~~ error: casts from `u32` to `f64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:28:13 + --> tests/ui/cast_lossless_float.rs:39:13 | LL | let _ = x5 as f64; | ^^^^^^^^^ @@ -145,7 +145,7 @@ LL | let _ = f64::from(x5); | ~~~~~~~~~~~~~ error: casts from `f32` to `f64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_float.rs:31:13 + --> tests/ui/cast_lossless_float.rs:43:13 | LL | let _ = 1.0f32 as f64; | ^^^^^^^^^^^^^ diff --git a/tests/ui/cast_lossless_integer.fixed b/tests/ui/cast_lossless_integer.fixed index cdb065678368..cd689801702a 100644 --- a/tests/ui/cast_lossless_integer.fixed +++ b/tests/ui/cast_lossless_integer.fixed @@ -7,87 +7,123 @@ fn main() { // Test clippy::cast_lossless with casts to integer types u16::from(0u8); //~^ cast_lossless + i16::from(0u8); //~^ cast_lossless + u32::from(0u8); //~^ cast_lossless + i32::from(0u8); //~^ cast_lossless + u64::from(0u8); //~^ cast_lossless + i64::from(0u8); //~^ cast_lossless + u128::from(0u8); //~^ cast_lossless + i128::from(0u8); //~^ cast_lossless + u32::from(0u16); //~^ cast_lossless + i32::from(0u16); //~^ cast_lossless + u64::from(0u16); //~^ cast_lossless + i64::from(0u16); //~^ cast_lossless + u128::from(0u16); //~^ cast_lossless + i128::from(0u16); //~^ cast_lossless + u64::from(0u32); //~^ cast_lossless + i64::from(0u32); //~^ cast_lossless + u128::from(0u32); //~^ cast_lossless + i128::from(0u32); //~^ cast_lossless + u128::from(0u64); //~^ cast_lossless + i128::from(0u64); //~^ cast_lossless + i16::from(0i8); //~^ cast_lossless + i32::from(0i8); //~^ cast_lossless + i64::from(0i8); //~^ cast_lossless + i128::from(0i8); //~^ cast_lossless + i32::from(0i16); //~^ cast_lossless + i64::from(0i16); //~^ cast_lossless + i128::from(0i16); //~^ cast_lossless + i64::from(0i32); //~^ cast_lossless + i128::from(0i32); //~^ cast_lossless + i128::from(0i64); //~^ cast_lossless + // Test with an expression wrapped in parens let _ = u16::from(1u8 + 1u8); //~^ cast_lossless + let _ = I64Alias::from(1i8); //~^ cast_lossless + let _: u16 = 0u8.into(); //~^ cast_lossless + let _: i16 = (-1i8).into(); //~^ cast_lossless + let _: u16 = (1u8 + 2).into(); //~^ cast_lossless + let _: u32 = (1i8 as u16).into(); //~^ cast_lossless + } // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, @@ -123,8 +159,10 @@ fn issue11458() { let x = 10_u128; let _ = i32::from(sign_cast!(x, u8, i8)); //~^ cast_lossless + let _ = i32::from(sign_cast!(x, u8, i8) + 1); //~^ cast_lossless + } fn issue12695() { @@ -132,6 +170,7 @@ fn issue12695() { () => { u32::from(1u8) //~^ cast_lossless + }; } @@ -146,6 +185,7 @@ fn ty_from_macro() { } let _ = ::from(0u8); + //~^ cast_lossless } const IN_CONST: u64 = 0u8 as u64; diff --git a/tests/ui/cast_lossless_integer.rs b/tests/ui/cast_lossless_integer.rs index 1f510b1a3036..03c1a77c34ad 100644 --- a/tests/ui/cast_lossless_integer.rs +++ b/tests/ui/cast_lossless_integer.rs @@ -7,87 +7,123 @@ fn main() { // Test clippy::cast_lossless with casts to integer types 0u8 as u16; //~^ cast_lossless + 0u8 as i16; //~^ cast_lossless + 0u8 as u32; //~^ cast_lossless + 0u8 as i32; //~^ cast_lossless + 0u8 as u64; //~^ cast_lossless + 0u8 as i64; //~^ cast_lossless + 0u8 as u128; //~^ cast_lossless + 0u8 as i128; //~^ cast_lossless + 0u16 as u32; //~^ cast_lossless + 0u16 as i32; //~^ cast_lossless + 0u16 as u64; //~^ cast_lossless + 0u16 as i64; //~^ cast_lossless + 0u16 as u128; //~^ cast_lossless + 0u16 as i128; //~^ cast_lossless + 0u32 as u64; //~^ cast_lossless + 0u32 as i64; //~^ cast_lossless + 0u32 as u128; //~^ cast_lossless + 0u32 as i128; //~^ cast_lossless + 0u64 as u128; //~^ cast_lossless + 0u64 as i128; //~^ cast_lossless + 0i8 as i16; //~^ cast_lossless + 0i8 as i32; //~^ cast_lossless + 0i8 as i64; //~^ cast_lossless + 0i8 as i128; //~^ cast_lossless + 0i16 as i32; //~^ cast_lossless + 0i16 as i64; //~^ cast_lossless + 0i16 as i128; //~^ cast_lossless + 0i32 as i64; //~^ cast_lossless + 0i32 as i128; //~^ cast_lossless + 0i64 as i128; //~^ cast_lossless + // Test with an expression wrapped in parens let _ = (1u8 + 1u8) as u16; //~^ cast_lossless + let _ = 1i8 as I64Alias; //~^ cast_lossless + let _: u16 = 0u8 as _; //~^ cast_lossless + let _: i16 = -1i8 as _; //~^ cast_lossless + let _: u16 = (1u8 + 2) as _; //~^ cast_lossless + let _: u32 = 1i8 as u16 as _; //~^ cast_lossless + } // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, @@ -123,8 +159,10 @@ fn issue11458() { let x = 10_u128; let _ = sign_cast!(x, u8, i8) as i32; //~^ cast_lossless + let _ = (sign_cast!(x, u8, i8) + 1) as i32; //~^ cast_lossless + } fn issue12695() { @@ -132,6 +170,7 @@ fn issue12695() { () => { 1u8 as u32 //~^ cast_lossless + }; } @@ -146,6 +185,7 @@ fn ty_from_macro() { } let _ = 0u8 as ty!(); + //~^ cast_lossless } const IN_CONST: u64 = 0u8 as u64; diff --git a/tests/ui/cast_lossless_integer.stderr b/tests/ui/cast_lossless_integer.stderr index c93ecb8fb561..3bec773ff861 100644 --- a/tests/ui/cast_lossless_integer.stderr +++ b/tests/ui/cast_lossless_integer.stderr @@ -13,7 +13,7 @@ LL | u16::from(0u8); | ~~~~~~~~~~~~~~ error: casts from `u8` to `i16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:10:5 + --> tests/ui/cast_lossless_integer.rs:11:5 | LL | 0u8 as i16; | ^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | i16::from(0u8); | ~~~~~~~~~~~~~~ error: casts from `u8` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:12:5 + --> tests/ui/cast_lossless_integer.rs:14:5 | LL | 0u8 as u32; | ^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | u32::from(0u8); | ~~~~~~~~~~~~~~ error: casts from `u8` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:14:5 + --> tests/ui/cast_lossless_integer.rs:17:5 | LL | 0u8 as i32; | ^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | i32::from(0u8); | ~~~~~~~~~~~~~~ error: casts from `u8` to `u64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:16:5 + --> tests/ui/cast_lossless_integer.rs:20:5 | LL | 0u8 as u64; | ^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | u64::from(0u8); | ~~~~~~~~~~~~~~ error: casts from `u8` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:18:5 + --> tests/ui/cast_lossless_integer.rs:23:5 | LL | 0u8 as i64; | ^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | i64::from(0u8); | ~~~~~~~~~~~~~~ error: casts from `u8` to `u128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:20:5 + --> tests/ui/cast_lossless_integer.rs:26:5 | LL | 0u8 as u128; | ^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | u128::from(0u8); | ~~~~~~~~~~~~~~~ error: casts from `u8` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:22:5 + --> tests/ui/cast_lossless_integer.rs:29:5 | LL | 0u8 as i128; | ^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | i128::from(0u8); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:25:5 + --> tests/ui/cast_lossless_integer.rs:33:5 | LL | 0u16 as u32; | ^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | u32::from(0u16); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:27:5 + --> tests/ui/cast_lossless_integer.rs:36:5 | LL | 0u16 as i32; | ^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | i32::from(0u16); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `u64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:29:5 + --> tests/ui/cast_lossless_integer.rs:39:5 | LL | 0u16 as u64; | ^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | u64::from(0u16); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:31:5 + --> tests/ui/cast_lossless_integer.rs:42:5 | LL | 0u16 as i64; | ^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | i64::from(0u16); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `u128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:33:5 + --> tests/ui/cast_lossless_integer.rs:45:5 | LL | 0u16 as u128; | ^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | u128::from(0u16); | ~~~~~~~~~~~~~~~~ error: casts from `u16` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:35:5 + --> tests/ui/cast_lossless_integer.rs:48:5 | LL | 0u16 as i128; | ^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | i128::from(0u16); | ~~~~~~~~~~~~~~~~ error: casts from `u32` to `u64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:38:5 + --> tests/ui/cast_lossless_integer.rs:52:5 | LL | 0u32 as u64; | ^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | u64::from(0u32); | ~~~~~~~~~~~~~~~ error: casts from `u32` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:40:5 + --> tests/ui/cast_lossless_integer.rs:55:5 | LL | 0u32 as i64; | ^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL | i64::from(0u32); | ~~~~~~~~~~~~~~~ error: casts from `u32` to `u128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:42:5 + --> tests/ui/cast_lossless_integer.rs:58:5 | LL | 0u32 as u128; | ^^^^^^^^^^^^ @@ -205,7 +205,7 @@ LL | u128::from(0u32); | ~~~~~~~~~~~~~~~~ error: casts from `u32` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:44:5 + --> tests/ui/cast_lossless_integer.rs:61:5 | LL | 0u32 as i128; | ^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | i128::from(0u32); | ~~~~~~~~~~~~~~~~ error: casts from `u64` to `u128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:47:5 + --> tests/ui/cast_lossless_integer.rs:65:5 | LL | 0u64 as u128; | ^^^^^^^^^^^^ @@ -229,7 +229,7 @@ LL | u128::from(0u64); | ~~~~~~~~~~~~~~~~ error: casts from `u64` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:49:5 + --> tests/ui/cast_lossless_integer.rs:68:5 | LL | 0u64 as i128; | ^^^^^^^^^^^^ @@ -241,7 +241,7 @@ LL | i128::from(0u64); | ~~~~~~~~~~~~~~~~ error: casts from `i8` to `i16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:52:5 + --> tests/ui/cast_lossless_integer.rs:72:5 | LL | 0i8 as i16; | ^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | i16::from(0i8); | ~~~~~~~~~~~~~~ error: casts from `i8` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:54:5 + --> tests/ui/cast_lossless_integer.rs:75:5 | LL | 0i8 as i32; | ^^^^^^^^^^ @@ -265,7 +265,7 @@ LL | i32::from(0i8); | ~~~~~~~~~~~~~~ error: casts from `i8` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:56:5 + --> tests/ui/cast_lossless_integer.rs:78:5 | LL | 0i8 as i64; | ^^^^^^^^^^ @@ -277,7 +277,7 @@ LL | i64::from(0i8); | ~~~~~~~~~~~~~~ error: casts from `i8` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:58:5 + --> tests/ui/cast_lossless_integer.rs:81:5 | LL | 0i8 as i128; | ^^^^^^^^^^^ @@ -289,7 +289,7 @@ LL | i128::from(0i8); | ~~~~~~~~~~~~~~~ error: casts from `i16` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:61:5 + --> tests/ui/cast_lossless_integer.rs:85:5 | LL | 0i16 as i32; | ^^^^^^^^^^^ @@ -301,7 +301,7 @@ LL | i32::from(0i16); | ~~~~~~~~~~~~~~~ error: casts from `i16` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:63:5 + --> tests/ui/cast_lossless_integer.rs:88:5 | LL | 0i16 as i64; | ^^^^^^^^^^^ @@ -313,7 +313,7 @@ LL | i64::from(0i16); | ~~~~~~~~~~~~~~~ error: casts from `i16` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:65:5 + --> tests/ui/cast_lossless_integer.rs:91:5 | LL | 0i16 as i128; | ^^^^^^^^^^^^ @@ -325,7 +325,7 @@ LL | i128::from(0i16); | ~~~~~~~~~~~~~~~~ error: casts from `i32` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:68:5 + --> tests/ui/cast_lossless_integer.rs:95:5 | LL | 0i32 as i64; | ^^^^^^^^^^^ @@ -337,7 +337,7 @@ LL | i64::from(0i32); | ~~~~~~~~~~~~~~~ error: casts from `i32` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:70:5 + --> tests/ui/cast_lossless_integer.rs:98:5 | LL | 0i32 as i128; | ^^^^^^^^^^^^ @@ -349,7 +349,7 @@ LL | i128::from(0i32); | ~~~~~~~~~~~~~~~~ error: casts from `i64` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:73:5 + --> tests/ui/cast_lossless_integer.rs:102:5 | LL | 0i64 as i128; | ^^^^^^^^^^^^ @@ -361,7 +361,7 @@ LL | i128::from(0i64); | ~~~~~~~~~~~~~~~~ error: casts from `u8` to `u16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:77:13 + --> tests/ui/cast_lossless_integer.rs:107:13 | LL | let _ = (1u8 + 1u8) as u16; | ^^^^^^^^^^^^^^^^^^ @@ -373,7 +373,7 @@ LL | let _ = u16::from(1u8 + 1u8); | ~~~~~~~~~~~~~~~~~~~~ error: casts from `i8` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:80:13 + --> tests/ui/cast_lossless_integer.rs:111:13 | LL | let _ = 1i8 as I64Alias; | ^^^^^^^^^^^^^^^ @@ -385,7 +385,7 @@ LL | let _ = I64Alias::from(1i8); | ~~~~~~~~~~~~~~~~~~~ error: casts from `u8` to `u16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:83:18 + --> tests/ui/cast_lossless_integer.rs:115:18 | LL | let _: u16 = 0u8 as _; | ^^^^^^^^ @@ -397,7 +397,7 @@ LL | let _: u16 = 0u8.into(); | ~~~~~~~~~~ error: casts from `i8` to `i16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:85:18 + --> tests/ui/cast_lossless_integer.rs:118:18 | LL | let _: i16 = -1i8 as _; | ^^^^^^^^^ @@ -409,7 +409,7 @@ LL | let _: i16 = (-1i8).into(); | ~~~~~~~~~~~~~ error: casts from `u8` to `u16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:87:18 + --> tests/ui/cast_lossless_integer.rs:121:18 | LL | let _: u16 = (1u8 + 2) as _; | ^^^^^^^^^^^^^^ @@ -421,7 +421,7 @@ LL | let _: u16 = (1u8 + 2).into(); | ~~~~~~~~~~~~~~~~ error: casts from `u16` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:89:18 + --> tests/ui/cast_lossless_integer.rs:124:18 | LL | let _: u32 = 1i8 as u16 as _; | ^^^^^^^^^^^^^^^ @@ -433,7 +433,7 @@ LL | let _: u32 = (1i8 as u16).into(); | ~~~~~~~~~~~~~~~~~~~ error: casts from `i8` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:124:13 + --> tests/ui/cast_lossless_integer.rs:160:13 | LL | let _ = sign_cast!(x, u8, i8) as i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -445,7 +445,7 @@ LL | let _ = i32::from(sign_cast!(x, u8, i8)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casts from `i8` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:126:13 + --> tests/ui/cast_lossless_integer.rs:163:13 | LL | let _ = (sign_cast!(x, u8, i8) + 1) as i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -457,7 +457,7 @@ LL | let _ = i32::from(sign_cast!(x, u8, i8) + 1); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casts from `u8` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:133:13 + --> tests/ui/cast_lossless_integer.rs:171:13 | LL | 1u8 as u32 | ^^^^^^^^^^ @@ -473,7 +473,7 @@ LL | u32::from(1u8) | error: casts from `u8` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:148:13 + --> tests/ui/cast_lossless_integer.rs:187:13 | LL | let _ = 0u8 as ty!(); | ^^^^^^^^^^^^ diff --git a/tests/ui/cast_nan_to_int.rs b/tests/ui/cast_nan_to_int.rs index aee38da9a159..227dae3b1c4b 100644 --- a/tests/ui/cast_nan_to_int.rs +++ b/tests/ui/cast_nan_to_int.rs @@ -5,24 +5,30 @@ fn main() { let _ = (0.0_f32 / -0.0) as usize; - //~^ ERROR: casting a known NaN to usize - //~| NOTE: this always evaluates to 0 + //~^ cast_nan_to_int + + let _ = (f64::INFINITY * -0.0) as usize; - //~^ ERROR: casting a known NaN to usize - //~| NOTE: this always evaluates to 0 + //~^ cast_nan_to_int + + let _ = (0.0 * f32::INFINITY) as usize; - //~^ ERROR: casting a known NaN to usize - //~| NOTE: this always evaluates to 0 + //~^ cast_nan_to_int + + let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize; - //~^ ERROR: casting a known NaN to usize - //~| NOTE: this always evaluates to 0 + //~^ cast_nan_to_int + + let _ = (f32::INFINITY - f32::INFINITY) as usize; - //~^ ERROR: casting a known NaN to usize - //~| NOTE: this always evaluates to 0 + //~^ cast_nan_to_int + + let _ = (f32::INFINITY / f32::NEG_INFINITY) as usize; - //~^ ERROR: casting a known NaN to usize - //~| NOTE: this always evaluates to 0 + //~^ cast_nan_to_int + + // those won't be linted: let _ = (1.0_f32 / 0.0) as usize; diff --git a/tests/ui/cast_nan_to_int.stderr b/tests/ui/cast_nan_to_int.stderr index 3aeb2d545251..0f9b3565485f 100644 --- a/tests/ui/cast_nan_to_int.stderr +++ b/tests/ui/cast_nan_to_int.stderr @@ -9,7 +9,7 @@ LL | let _ = (0.0_f32 / -0.0) as usize; = help: to override `-D warnings` add `#[allow(clippy::cast_nan_to_int)]` error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:10:13 + --> tests/ui/cast_nan_to_int.rs:11:13 | LL | let _ = (f64::INFINITY * -0.0) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = (f64::INFINITY * -0.0) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:13:13 + --> tests/ui/cast_nan_to_int.rs:15:13 | LL | let _ = (0.0 * f32::INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = (0.0 * f32::INFINITY) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:17:13 + --> tests/ui/cast_nan_to_int.rs:20:13 | LL | let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:20:13 + --> tests/ui/cast_nan_to_int.rs:24:13 | LL | let _ = (f32::INFINITY - f32::INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = (f32::INFINITY - f32::INFINITY) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:23:13 + --> tests/ui/cast_nan_to_int.rs:28:13 | LL | let _ = (f32::INFINITY / f32::NEG_INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_raw_slice_pointer_cast.fixed b/tests/ui/cast_raw_slice_pointer_cast.fixed index e78bd66c3cb5..bddcb0ebf64e 100644 --- a/tests/ui/cast_raw_slice_pointer_cast.fixed +++ b/tests/ui/cast_raw_slice_pointer_cast.fixed @@ -6,18 +6,25 @@ fn main() { let ptr: *const u8 = vec.as_ptr(); let mptr = vec.as_mut_ptr(); let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(ptr, 1) }; + //~^ cast_slice_from_raw_parts let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(mptr, 1) }; + //~^ cast_slice_from_raw_parts let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + //~^ cast_slice_from_raw_parts { use core::slice; let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + //~^ cast_slice_from_raw_parts use slice as one; let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + //~^ cast_slice_from_raw_parts } { use std::slice; let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + //~^ cast_slice_from_raw_parts use slice as one; let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1); + //~^ cast_slice_from_raw_parts } } diff --git a/tests/ui/cast_raw_slice_pointer_cast.rs b/tests/ui/cast_raw_slice_pointer_cast.rs index c3d8c7bee989..0a1eb276d5e9 100644 --- a/tests/ui/cast_raw_slice_pointer_cast.rs +++ b/tests/ui/cast_raw_slice_pointer_cast.rs @@ -6,18 +6,25 @@ fn main() { let ptr: *const u8 = vec.as_ptr(); let mptr = vec.as_mut_ptr(); let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *const [u8] }; + //~^ cast_slice_from_raw_parts let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] }; + //~^ cast_slice_from_raw_parts let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8]; + //~^ cast_slice_from_raw_parts { use core::slice; let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8]; + //~^ cast_slice_from_raw_parts use slice as one; let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8]; + //~^ cast_slice_from_raw_parts } { use std::slice; let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8]; + //~^ cast_slice_from_raw_parts use slice as one; let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8]; + //~^ cast_slice_from_raw_parts } } diff --git a/tests/ui/cast_raw_slice_pointer_cast.stderr b/tests/ui/cast_raw_slice_pointer_cast.stderr index 2aedd320a428..60794a988db7 100644 --- a/tests/ui/cast_raw_slice_pointer_cast.stderr +++ b/tests/ui/cast_raw_slice_pointer_cast.stderr @@ -8,37 +8,37 @@ LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *co = help: to override `-D warnings` add `#[allow(clippy::cast_slice_from_raw_parts)]` error: casting the result of `from_raw_parts_mut` to *mut [u8] - --> tests/ui/cast_raw_slice_pointer_cast.rs:9:35 + --> tests/ui/cast_raw_slice_pointer_cast.rs:10:35 | LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts_mut(mptr, 1)` error: casting the result of `from_raw_parts` to *const [u8] - --> tests/ui/cast_raw_slice_pointer_cast.rs:10:26 + --> tests/ui/cast_raw_slice_pointer_cast.rs:12:26 | LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` error: casting the result of `from_raw_parts` to *const [u8] - --> tests/ui/cast_raw_slice_pointer_cast.rs:13:30 + --> tests/ui/cast_raw_slice_pointer_cast.rs:16:30 | LL | let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` error: casting the result of `from_raw_parts` to *const [u8] - --> tests/ui/cast_raw_slice_pointer_cast.rs:15:30 + --> tests/ui/cast_raw_slice_pointer_cast.rs:19:30 | LL | let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` error: casting the result of `from_raw_parts` to *const [u8] - --> tests/ui/cast_raw_slice_pointer_cast.rs:19:30 + --> tests/ui/cast_raw_slice_pointer_cast.rs:24:30 | LL | let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` error: casting the result of `from_raw_parts` to *const [u8] - --> tests/ui/cast_raw_slice_pointer_cast.rs:21:30 + --> tests/ui/cast_raw_slice_pointer_cast.rs:27:30 | LL | let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)` diff --git a/tests/ui/cast_size.64bit.stderr b/tests/ui/cast_size.64bit.stderr index bc37107d80e3..d67040bcc1cb 100644 --- a/tests/ui/cast_size.64bit.stderr +++ b/tests/ui/cast_size.64bit.stderr @@ -13,7 +13,7 @@ LL | i8::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:21:5 + --> tests/ui/cast_size.rs:22:5 | LL | x0 as f32; | ^^^^^^^^^ @@ -22,25 +22,25 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:22:5 + --> tests/ui/cast_size.rs:24:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:23:5 + --> tests/ui/cast_size.rs:26:5 | LL | x0 as f64; | ^^^^^^^^^ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:24:5 + --> tests/ui/cast_size.rs:28:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `isize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:28:5 + --> tests/ui/cast_size.rs:33:5 | LL | 1isize as i32; | ^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | i32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:29:5 + --> tests/ui/cast_size.rs:35:5 | LL | 1isize as u32; | ^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | u32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:30:5 + --> tests/ui/cast_size.rs:37:5 | LL | 1usize as u32; | ^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | u32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:31:5 + --> tests/ui/cast_size.rs:39:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:31:5 + --> tests/ui/cast_size.rs:39:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | 1usize as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `i64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:32:5 + --> tests/ui/cast_size.rs:42:5 | LL | 1i64 as isize; | ^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | isize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:33:5 + --> tests/ui/cast_size.rs:44:5 | LL | 1i64 as usize; | ^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | usize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:34:5 + --> tests/ui/cast_size.rs:46:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -133,13 +133,13 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:34:5 + --> tests/ui/cast_size.rs:46:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:35:5 + --> tests/ui/cast_size.rs:49:5 | LL | 1u64 as usize; | ^^^^^^^^^^^^^ @@ -151,19 +151,19 @@ LL | usize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:36:5 + --> tests/ui/cast_size.rs:51:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:43:5 + --> tests/ui/cast_size.rs:59:5 | LL | 999_999_999 as f32; | ^^^^^^^^^^^^^^^^^^ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:44:5 + --> tests/ui/cast_size.rs:61:5 | LL | 9_999_999_999_999_999usize as f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_size.rs b/tests/ui/cast_size.rs index d0ed8e57d7ae..9fc07b2ae4fd 100644 --- a/tests/ui/cast_size.rs +++ b/tests/ui/cast_size.rs @@ -13,27 +13,43 @@ fn main() { // Casting from *size 1isize as i8; + //~^ cast_possible_truncation let x0 = 1isize; let x1 = 1usize; // FIXME(f16_f128): enable f16 and f128 conversions once const eval supports them // x0 as f16; // x1 as f16; x0 as f32; + //~^ cast_precision_loss x1 as f32; + //~^ cast_precision_loss x0 as f64; + //~^ cast_precision_loss x1 as f64; + //~^ cast_precision_loss // x0 as f128; // x1 as f128; 1isize as i32; + //~^ cast_possible_truncation 1isize as u32; + //~^ cast_possible_truncation 1usize as u32; + //~^ cast_possible_truncation 1usize as i32; + //~^ cast_possible_truncation + //~| cast_possible_wrap 1i64 as isize; + //~^ cast_possible_truncation 1i64 as usize; + //~^ cast_possible_truncation 1u64 as isize; + //~^ cast_possible_truncation + //~| cast_possible_wrap 1u64 as usize; + //~^ cast_possible_truncation 1u32 as isize; + //~^ cast_possible_wrap 1u32 as usize; // Should not trigger any lint 1i32 as isize; // Neither should this 1i32 as usize; @@ -41,6 +57,8 @@ fn main() { // Big integer literal to float // 999_999 as f16; 999_999_999 as f32; + //~^ cast_precision_loss 9_999_999_999_999_999usize as f64; + //~^ cast_precision_loss // 999_999_999_999_999_999_999_999_999_999u128 as f128; } diff --git a/tests/ui/cast_slice_different_sizes.rs b/tests/ui/cast_slice_different_sizes.rs index d8101030a8a2..2db14d4f2515 100644 --- a/tests/ui/cast_slice_different_sizes.rs +++ b/tests/ui/cast_slice_different_sizes.rs @@ -8,14 +8,17 @@ fn main() { // Because it's separate, it does not check the cast back to something of the same size let a = r_x as *const [i32]; let b = a as *const [u8]; - //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme - //~| NOTE: `#[deny(clippy::cast_slice_different_sizes)]` on by default + //~^ cast_slice_different_sizes + + let c = b as *const [u32]; - //~^ ERROR: casting between raw pointers to `[u8]` (element size 1) and `[u32]` (eleme + //~^ cast_slice_different_sizes + // loses data let loss = r_x as *const [i32] as *const [u8]; - //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme + //~^ cast_slice_different_sizes + // Cast back to same size but different type loses no data, just type conversion // This is weird code but there's no reason for this lint specifically to fire *twice* on it @@ -23,9 +26,11 @@ fn main() { // Check casting through blocks is detected let loss_block_1 = { r_x as *const [i32] } as *const [u8]; - //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme + //~^ cast_slice_different_sizes + let loss_block_2 = { - //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme + //~^ cast_slice_different_sizes + let _ = (); r_x as *const [i32] } as *const [u8]; @@ -43,7 +48,8 @@ fn main() { // Check that the result of a long chain of casts is detected let long_chain_loss = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8]; - //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme + //~^ cast_slice_different_sizes + let long_chain_restore = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8] as *const [u32]; } @@ -59,40 +65,48 @@ fn foo2(x: *mut [u8]) -> *mut [u8] { // Test that casts as part of function returns work fn bar(x: *mut [u16]) -> *mut [u8] { - //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s +//~^ cast_slice_different_sizes + x as *mut [u8] } fn uwu(x: *mut [u16]) -> *mut [u8] { - //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s +//~^ cast_slice_different_sizes + x as *mut _ } fn bar2(x: *mut [u16]) -> *mut [u8] { - //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s +//~^ cast_slice_different_sizes + x as _ } // constify fn bar3(x: *mut [u16]) -> *const [u8] { - //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s +//~^ cast_slice_different_sizes + x as _ } // unconstify fn bar4(x: *const [u16]) -> *mut [u8] { - //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s +//~^ cast_slice_different_sizes + x as _ } // function returns plus blocks fn blocks(x: *mut [u16]) -> *mut [u8] { - //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s +//~^ cast_slice_different_sizes + ({ x }) as _ } fn more_blocks(x: *mut [u16]) -> *mut [u8] { - //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s +//~^ cast_slice_different_sizes + { ({ x }) as _ } - //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (eleme + //~^ cast_slice_different_sizes + } diff --git a/tests/ui/cast_slice_different_sizes.stderr b/tests/ui/cast_slice_different_sizes.stderr index 625de4a8359b..e028e13db616 100644 --- a/tests/ui/cast_slice_different_sizes.stderr +++ b/tests/ui/cast_slice_different_sizes.stderr @@ -7,29 +7,30 @@ LL | let b = a as *const [u8]; = note: `#[deny(clippy::cast_slice_different_sizes)]` on by default error: casting between raw pointers to `[u8]` (element size 1) and `[u32]` (element size 4) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:13:13 + --> tests/ui/cast_slice_different_sizes.rs:14:13 | LL | let c = b as *const [u32]; | ^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(b as *const u32, ..)` error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:17:16 + --> tests/ui/cast_slice_different_sizes.rs:19:16 | LL | let loss = r_x as *const [i32] as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)` error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:25:24 + --> tests/ui/cast_slice_different_sizes.rs:28:24 | LL | let loss_block_1 = { r_x as *const [i32] } as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts({ r_x as *const [i32] } as *const u8, ..)` error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:27:24 + --> tests/ui/cast_slice_different_sizes.rs:31:24 | LL | let loss_block_2 = { | ________________________^ LL | | +LL | | LL | | let _ = (); LL | | r_x as *const [i32] LL | | } as *const [u8]; @@ -39,90 +40,98 @@ help: replace with `ptr::slice_from_raw_parts` | LL ~ let loss_block_2 = core::ptr::slice_from_raw_parts({ LL + +LL + LL + let _ = (); LL + r_x as *const [i32] LL ~ } as *const u8, ..); | error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:45:27 + --> tests/ui/cast_slice_different_sizes.rs:50:27 | LL | let long_chain_loss = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:61:36 + --> tests/ui/cast_slice_different_sizes.rs:67:36 | LL | fn bar(x: *mut [u16]) -> *mut [u8] { | ____________________________________^ LL | | +LL | | LL | | x as *mut [u8] LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:66:36 + --> tests/ui/cast_slice_different_sizes.rs:73:36 | LL | fn uwu(x: *mut [u16]) -> *mut [u8] { | ____________________________________^ LL | | +LL | | LL | | x as *mut _ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:71:37 + --> tests/ui/cast_slice_different_sizes.rs:79:37 | LL | fn bar2(x: *mut [u16]) -> *mut [u8] { | _____________________________________^ LL | | +LL | | LL | | x as _ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:77:39 + --> tests/ui/cast_slice_different_sizes.rs:86:39 | LL | fn bar3(x: *mut [u16]) -> *const [u8] { | _______________________________________^ LL | | +LL | | LL | | x as _ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(x as *const u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:83:39 + --> tests/ui/cast_slice_different_sizes.rs:93:39 | LL | fn bar4(x: *const [u16]) -> *mut [u8] { | _______________________________________^ LL | | +LL | | LL | | x as _ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:89:39 + --> tests/ui/cast_slice_different_sizes.rs:100:39 | LL | fn blocks(x: *mut [u16]) -> *mut [u8] { | _______________________________________^ LL | | +LL | | LL | | ({ x }) as _ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:94:44 + --> tests/ui/cast_slice_different_sizes.rs:106:44 | LL | fn more_blocks(x: *mut [u16]) -> *mut [u8] { | ____________________________________________^ LL | | -LL | | { ({ x }) as _ } LL | | +LL | | { ({ x }) as _ } +... | LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:96:5 + --> tests/ui/cast_slice_different_sizes.rs:109:5 | LL | { ({ x }) as _ } | ^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)` diff --git a/tests/ui/cfg_attr_cargo_clippy.fixed b/tests/ui/cfg_attr_cargo_clippy.fixed index 89815ffe9cbc..f55920db5503 100644 --- a/tests/ui/cfg_attr_cargo_clippy.fixed +++ b/tests/ui/cfg_attr_cargo_clippy.fixed @@ -1,13 +1,20 @@ #![warn(clippy::deprecated_clippy_cfg_attr)] #![allow(clippy::non_minimal_cfg)] -#![cfg_attr(clippy, doc = "a")] //~ ERROR: `feature = "cargo-clippy"` was +#![cfg_attr(clippy, doc = "a")] +//~^ deprecated_clippy_cfg_attr -#[cfg_attr(clippy, derive(Debug))] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg_attr(not(clippy), derive(Debug))] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg(clippy)] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg(not(clippy))] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg(any(clippy))] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg(all(clippy))] //~ ERROR: `feature = "cargo-clippy"` was +#[cfg_attr(clippy, derive(Debug))] +//~^ deprecated_clippy_cfg_attr +#[cfg_attr(not(clippy), derive(Debug))] +//~^ deprecated_clippy_cfg_attr +#[cfg(clippy)] +//~^ deprecated_clippy_cfg_attr +#[cfg(not(clippy))] +//~^ deprecated_clippy_cfg_attr +#[cfg(any(clippy))] +//~^ deprecated_clippy_cfg_attr +#[cfg(all(clippy))] +//~^ deprecated_clippy_cfg_attr pub struct Bar; fn main() {} diff --git a/tests/ui/cfg_attr_cargo_clippy.rs b/tests/ui/cfg_attr_cargo_clippy.rs index 745f8957641e..faf36d98f2b3 100644 --- a/tests/ui/cfg_attr_cargo_clippy.rs +++ b/tests/ui/cfg_attr_cargo_clippy.rs @@ -1,13 +1,20 @@ #![warn(clippy::deprecated_clippy_cfg_attr)] #![allow(clippy::non_minimal_cfg)] -#![cfg_attr(feature = "cargo-clippy", doc = "a")] //~ ERROR: `feature = "cargo-clippy"` was +#![cfg_attr(feature = "cargo-clippy", doc = "a")] +//~^ deprecated_clippy_cfg_attr -#[cfg_attr(feature = "cargo-clippy", derive(Debug))] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg_attr(not(feature = "cargo-clippy"), derive(Debug))] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg(feature = "cargo-clippy")] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg(not(feature = "cargo-clippy"))] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg(any(feature = "cargo-clippy"))] //~ ERROR: `feature = "cargo-clippy"` was -#[cfg(all(feature = "cargo-clippy"))] //~ ERROR: `feature = "cargo-clippy"` was +#[cfg_attr(feature = "cargo-clippy", derive(Debug))] +//~^ deprecated_clippy_cfg_attr +#[cfg_attr(not(feature = "cargo-clippy"), derive(Debug))] +//~^ deprecated_clippy_cfg_attr +#[cfg(feature = "cargo-clippy")] +//~^ deprecated_clippy_cfg_attr +#[cfg(not(feature = "cargo-clippy"))] +//~^ deprecated_clippy_cfg_attr +#[cfg(any(feature = "cargo-clippy"))] +//~^ deprecated_clippy_cfg_attr +#[cfg(all(feature = "cargo-clippy"))] +//~^ deprecated_clippy_cfg_attr pub struct Bar; fn main() {} diff --git a/tests/ui/cfg_attr_cargo_clippy.stderr b/tests/ui/cfg_attr_cargo_clippy.stderr index 0a358f1a6847..4f5c39b78415 100644 --- a/tests/ui/cfg_attr_cargo_clippy.stderr +++ b/tests/ui/cfg_attr_cargo_clippy.stderr @@ -8,37 +8,37 @@ LL | #![cfg_attr(feature = "cargo-clippy", doc = "a")] = help: to override `-D warnings` add `#[allow(clippy::deprecated_clippy_cfg_attr)]` error: `feature = "cargo-clippy"` was replaced by `clippy` - --> tests/ui/cfg_attr_cargo_clippy.rs:5:12 + --> tests/ui/cfg_attr_cargo_clippy.rs:6:12 | LL | #[cfg_attr(feature = "cargo-clippy", derive(Debug))] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` error: `feature = "cargo-clippy"` was replaced by `clippy` - --> tests/ui/cfg_attr_cargo_clippy.rs:6:16 + --> tests/ui/cfg_attr_cargo_clippy.rs:8:16 | LL | #[cfg_attr(not(feature = "cargo-clippy"), derive(Debug))] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` error: `feature = "cargo-clippy"` was replaced by `clippy` - --> tests/ui/cfg_attr_cargo_clippy.rs:7:7 + --> tests/ui/cfg_attr_cargo_clippy.rs:10:7 | LL | #[cfg(feature = "cargo-clippy")] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` error: `feature = "cargo-clippy"` was replaced by `clippy` - --> tests/ui/cfg_attr_cargo_clippy.rs:8:11 + --> tests/ui/cfg_attr_cargo_clippy.rs:12:11 | LL | #[cfg(not(feature = "cargo-clippy"))] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` error: `feature = "cargo-clippy"` was replaced by `clippy` - --> tests/ui/cfg_attr_cargo_clippy.rs:9:11 + --> tests/ui/cfg_attr_cargo_clippy.rs:14:11 | LL | #[cfg(any(feature = "cargo-clippy"))] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` error: `feature = "cargo-clippy"` was replaced by `clippy` - --> tests/ui/cfg_attr_cargo_clippy.rs:10:11 + --> tests/ui/cfg_attr_cargo_clippy.rs:16:11 | LL | #[cfg(all(feature = "cargo-clippy"))] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` diff --git a/tests/ui/cfg_attr_rustfmt.fixed b/tests/ui/cfg_attr_rustfmt.fixed index 05d5b3d10eaf..401476a9c1fe 100644 --- a/tests/ui/cfg_attr_rustfmt.fixed +++ b/tests/ui/cfg_attr_rustfmt.fixed @@ -16,10 +16,12 @@ fn foo( fn skip_on_statements() { #[rustfmt::skip] + //~^ deprecated_cfg_attr 5+3; } #[rustfmt::skip] +//~^ deprecated_cfg_attr fn main() { foo::f(); } @@ -39,5 +41,6 @@ fn msrv_1_29() { #[clippy::msrv = "1.30"] fn msrv_1_30() { #[rustfmt::skip] + //~^ deprecated_cfg_attr 1+30; } diff --git a/tests/ui/cfg_attr_rustfmt.rs b/tests/ui/cfg_attr_rustfmt.rs index bc29e20210e8..3cf368129fd8 100644 --- a/tests/ui/cfg_attr_rustfmt.rs +++ b/tests/ui/cfg_attr_rustfmt.rs @@ -16,10 +16,12 @@ fn foo( fn skip_on_statements() { #[cfg_attr(rustfmt, rustfmt::skip)] + //~^ deprecated_cfg_attr 5+3; } #[cfg_attr(rustfmt, rustfmt_skip)] +//~^ deprecated_cfg_attr fn main() { foo::f(); } @@ -39,5 +41,6 @@ fn msrv_1_29() { #[clippy::msrv = "1.30"] fn msrv_1_30() { #[cfg_attr(rustfmt, rustfmt::skip)] + //~^ deprecated_cfg_attr 1+30; } diff --git a/tests/ui/cfg_attr_rustfmt.stderr b/tests/ui/cfg_attr_rustfmt.stderr index 24b6ed1b0458..d7825f854be5 100644 --- a/tests/ui/cfg_attr_rustfmt.stderr +++ b/tests/ui/cfg_attr_rustfmt.stderr @@ -8,13 +8,13 @@ LL | #[cfg_attr(rustfmt, rustfmt::skip)] = help: to override `-D warnings` add `#[allow(clippy::deprecated_cfg_attr)]` error: `cfg_attr` is deprecated for rustfmt and got replaced by tool attributes - --> tests/ui/cfg_attr_rustfmt.rs:22:1 + --> tests/ui/cfg_attr_rustfmt.rs:23:1 | LL | #[cfg_attr(rustfmt, rustfmt_skip)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `#[rustfmt::skip]` error: `cfg_attr` is deprecated for rustfmt and got replaced by tool attributes - --> tests/ui/cfg_attr_rustfmt.rs:41:5 + --> tests/ui/cfg_attr_rustfmt.rs:43:5 | LL | #[cfg_attr(rustfmt, rustfmt::skip)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `#[rustfmt::skip]` diff --git a/tests/ui/cfg_not_test.rs b/tests/ui/cfg_not_test.rs index da3e29d28966..d93e16f3b185 100644 --- a/tests/ui/cfg_not_test.rs +++ b/tests/ui/cfg_not_test.rs @@ -6,10 +6,12 @@ fn important_check() {} fn main() { // Statement #[cfg(not(test))] + //~^ cfg_not_test let answer = 42; // Expression #[cfg(not(test))] + //~^ cfg_not_test important_check(); // Make sure only not(test) are checked, not other attributes @@ -22,10 +24,13 @@ struct CfgNotTest; // Deeply nested `not(test)` #[cfg(not(test))] +//~^ cfg_not_test fn foo() {} #[cfg(all(debug_assertions, not(test)))] +//~^ cfg_not_test fn bar() {} #[cfg(not(any(not(debug_assertions), test)))] +//~^ cfg_not_test fn baz() {} #[cfg(test)] diff --git a/tests/ui/cfg_not_test.stderr b/tests/ui/cfg_not_test.stderr index c1bf626887af..e452ef2b5ab6 100644 --- a/tests/ui/cfg_not_test.stderr +++ b/tests/ui/cfg_not_test.stderr @@ -10,7 +10,7 @@ LL | #[cfg(not(test))] = help: to override `-D warnings` add `#[allow(clippy::cfg_not_test)]` error: code is excluded from test builds - --> tests/ui/cfg_not_test.rs:12:5 + --> tests/ui/cfg_not_test.rs:13:5 | LL | #[cfg(not(test))] | ^^^^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | #[cfg(not(test))] = help: consider not excluding any code from test builds error: code is excluded from test builds - --> tests/ui/cfg_not_test.rs:24:1 + --> tests/ui/cfg_not_test.rs:26:1 | LL | #[cfg(not(test))] | ^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | #[cfg(not(test))] = help: consider not excluding any code from test builds error: code is excluded from test builds - --> tests/ui/cfg_not_test.rs:26:1 + --> tests/ui/cfg_not_test.rs:29:1 | LL | #[cfg(all(debug_assertions, not(test)))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | #[cfg(all(debug_assertions, not(test)))] = help: consider not excluding any code from test builds error: code is excluded from test builds - --> tests/ui/cfg_not_test.rs:28:1 + --> tests/ui/cfg_not_test.rs:32:1 | LL | #[cfg(not(any(not(debug_assertions), test)))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/char_lit_as_u8.rs b/tests/ui/char_lit_as_u8.rs index 7bb3daf0f1e7..41e3c5e545cb 100644 --- a/tests/ui/char_lit_as_u8.rs +++ b/tests/ui/char_lit_as_u8.rs @@ -3,6 +3,7 @@ fn main() { // no suggestion, since a byte literal won't work. let _ = '❤' as u8; - //~^ ERROR: casting a character literal to `u8` truncates - //~| NOTE: `char` is four bytes wide, but `u8` is a single byte + //~^ char_lit_as_u8 + + } diff --git a/tests/ui/char_lit_as_u8_suggestions.fixed b/tests/ui/char_lit_as_u8_suggestions.fixed index 6f13078a3ae9..64aacedfd36a 100644 --- a/tests/ui/char_lit_as_u8_suggestions.fixed +++ b/tests/ui/char_lit_as_u8_suggestions.fixed @@ -2,7 +2,11 @@ fn main() { let _ = b'a'; + //~^ char_lit_as_u8 let _ = b'\n'; + //~^ char_lit_as_u8 let _ = b'\0'; + //~^ char_lit_as_u8 let _ = b'\x01'; + //~^ char_lit_as_u8 } diff --git a/tests/ui/char_lit_as_u8_suggestions.rs b/tests/ui/char_lit_as_u8_suggestions.rs index 7737eb5135fb..a8f39e27605e 100644 --- a/tests/ui/char_lit_as_u8_suggestions.rs +++ b/tests/ui/char_lit_as_u8_suggestions.rs @@ -2,7 +2,11 @@ fn main() { let _ = 'a' as u8; + //~^ char_lit_as_u8 let _ = '\n' as u8; + //~^ char_lit_as_u8 let _ = '\0' as u8; + //~^ char_lit_as_u8 let _ = '\x01' as u8; + //~^ char_lit_as_u8 } diff --git a/tests/ui/char_lit_as_u8_suggestions.stderr b/tests/ui/char_lit_as_u8_suggestions.stderr index 4826aca42e1c..158dfd6bed26 100644 --- a/tests/ui/char_lit_as_u8_suggestions.stderr +++ b/tests/ui/char_lit_as_u8_suggestions.stderr @@ -9,7 +9,7 @@ LL | let _ = 'a' as u8; = help: to override `-D warnings` add `#[allow(clippy::char_lit_as_u8)]` error: casting a character literal to `u8` truncates - --> tests/ui/char_lit_as_u8_suggestions.rs:5:13 + --> tests/ui/char_lit_as_u8_suggestions.rs:6:13 | LL | let _ = '\n' as u8; | ^^^^^^^^^^ help: use a byte literal instead: `b'\n'` @@ -17,7 +17,7 @@ LL | let _ = '\n' as u8; = note: `char` is four bytes wide, but `u8` is a single byte error: casting a character literal to `u8` truncates - --> tests/ui/char_lit_as_u8_suggestions.rs:6:13 + --> tests/ui/char_lit_as_u8_suggestions.rs:8:13 | LL | let _ = '\0' as u8; | ^^^^^^^^^^ help: use a byte literal instead: `b'\0'` @@ -25,7 +25,7 @@ LL | let _ = '\0' as u8; = note: `char` is four bytes wide, but `u8` is a single byte error: casting a character literal to `u8` truncates - --> tests/ui/char_lit_as_u8_suggestions.rs:7:13 + --> tests/ui/char_lit_as_u8_suggestions.rs:10:13 | LL | let _ = '\x01' as u8; | ^^^^^^^^^^^^ help: use a byte literal instead: `b'\x01'` diff --git a/tests/ui/checked_conversions.fixed b/tests/ui/checked_conversions.fixed index 1e8da3316141..279a5b6e1ff8 100644 --- a/tests/ui/checked_conversions.fixed +++ b/tests/ui/checked_conversions.fixed @@ -13,46 +13,62 @@ pub fn i64_to_u32(value: i64) { let _ = u32::try_from(value).is_ok(); + //~^ checked_conversions let _ = u32::try_from(value).is_ok(); + //~^ checked_conversions } pub fn i64_to_u16(value: i64) { let _ = u16::try_from(value).is_ok(); + //~^ checked_conversions let _ = u16::try_from(value).is_ok(); + //~^ checked_conversions } pub fn isize_to_u8(value: isize) { let _ = u8::try_from(value).is_ok(); + //~^ checked_conversions let _ = u8::try_from(value).is_ok(); + //~^ checked_conversions } // Signed to signed pub fn i64_to_i32(value: i64) { let _ = i32::try_from(value).is_ok(); + //~^ checked_conversions let _ = i32::try_from(value).is_ok(); + //~^ checked_conversions } pub fn i64_to_i16(value: i64) { let _ = i16::try_from(value).is_ok(); + //~^ checked_conversions let _ = i16::try_from(value).is_ok(); + //~^ checked_conversions } // Unsigned to X pub fn u32_to_i32(value: u32) { let _ = i32::try_from(value).is_ok(); + //~^ checked_conversions let _ = i32::try_from(value).is_ok(); + //~^ checked_conversions } pub fn usize_to_isize(value: usize) { let _ = isize::try_from(value).is_ok() && value as i32 == 5; + //~^ checked_conversions let _ = isize::try_from(value).is_ok() && value as i32 == 5; + //~^ checked_conversions } pub fn u32_to_u16(value: u32) { let _ = u16::try_from(value).is_ok() && value as i32 == 5; + //~^ checked_conversions let _ = u16::try_from(value).is_ok() && value as i32 == 5; + //~^ checked_conversions } // Negative tests @@ -86,6 +102,7 @@ fn msrv_1_33() { fn msrv_1_34() { let value: i64 = 34; let _ = u32::try_from(value).is_ok(); + //~^ checked_conversions } fn main() {} diff --git a/tests/ui/checked_conversions.rs b/tests/ui/checked_conversions.rs index 67a9adc049ea..c339bc674bbb 100644 --- a/tests/ui/checked_conversions.rs +++ b/tests/ui/checked_conversions.rs @@ -13,46 +13,62 @@ pub fn i64_to_u32(value: i64) { let _ = value <= (u32::max_value() as i64) && value >= 0; + //~^ checked_conversions let _ = value <= (u32::MAX as i64) && value >= 0; + //~^ checked_conversions } pub fn i64_to_u16(value: i64) { let _ = value <= i64::from(u16::max_value()) && value >= 0; + //~^ checked_conversions let _ = value <= i64::from(u16::MAX) && value >= 0; + //~^ checked_conversions } pub fn isize_to_u8(value: isize) { let _ = value <= (u8::max_value() as isize) && value >= 0; + //~^ checked_conversions let _ = value <= (u8::MAX as isize) && value >= 0; + //~^ checked_conversions } // Signed to signed pub fn i64_to_i32(value: i64) { let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64); + //~^ checked_conversions let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64); + //~^ checked_conversions } pub fn i64_to_i16(value: i64) { let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value()); + //~^ checked_conversions let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN); + //~^ checked_conversions } // Unsigned to X pub fn u32_to_i32(value: u32) { let _ = value <= i32::max_value() as u32; + //~^ checked_conversions let _ = value <= i32::MAX as u32; + //~^ checked_conversions } pub fn usize_to_isize(value: usize) { let _ = value <= isize::max_value() as usize && value as i32 == 5; + //~^ checked_conversions let _ = value <= isize::MAX as usize && value as i32 == 5; + //~^ checked_conversions } pub fn u32_to_u16(value: u32) { let _ = value <= u16::max_value() as u32 && value as i32 == 5; + //~^ checked_conversions let _ = value <= u16::MAX as u32 && value as i32 == 5; + //~^ checked_conversions } // Negative tests @@ -86,6 +102,7 @@ fn msrv_1_33() { fn msrv_1_34() { let value: i64 = 34; let _ = value <= (u32::MAX as i64) && value >= 0; + //~^ checked_conversions } fn main() {} diff --git a/tests/ui/checked_conversions.stderr b/tests/ui/checked_conversions.stderr index 453cd7fcf016..3841b9d5a4dd 100644 --- a/tests/ui/checked_conversions.stderr +++ b/tests/ui/checked_conversions.stderr @@ -8,97 +8,97 @@ LL | let _ = value <= (u32::max_value() as i64) && value >= 0; = help: to override `-D warnings` add `#[allow(clippy::checked_conversions)]` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:16:13 + --> tests/ui/checked_conversions.rs:17:13 | LL | let _ = value <= (u32::MAX as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:20:13 + --> tests/ui/checked_conversions.rs:22:13 | LL | let _ = value <= i64::from(u16::max_value()) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:21:13 + --> tests/ui/checked_conversions.rs:24:13 | LL | let _ = value <= i64::from(u16::MAX) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:25:13 + --> tests/ui/checked_conversions.rs:29:13 | LL | let _ = value <= (u8::max_value() as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:26:13 + --> tests/ui/checked_conversions.rs:31:13 | LL | let _ = value <= (u8::MAX as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:32:13 + --> tests/ui/checked_conversions.rs:38:13 | LL | let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:33:13 + --> tests/ui/checked_conversions.rs:40:13 | LL | let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:37:13 + --> tests/ui/checked_conversions.rs:45:13 | LL | let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:38:13 + --> tests/ui/checked_conversions.rs:47:13 | LL | let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:44:13 + --> tests/ui/checked_conversions.rs:54:13 | LL | let _ = value <= i32::max_value() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:45:13 + --> tests/ui/checked_conversions.rs:56:13 | LL | let _ = value <= i32::MAX as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:49:13 + --> tests/ui/checked_conversions.rs:61:13 | LL | let _ = value <= isize::max_value() as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:50:13 + --> tests/ui/checked_conversions.rs:63:13 | LL | let _ = value <= isize::MAX as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:54:13 + --> tests/ui/checked_conversions.rs:68:13 | LL | let _ = value <= u16::max_value() as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:55:13 + --> tests/ui/checked_conversions.rs:70:13 | LL | let _ = value <= u16::MAX as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:88:13 + --> tests/ui/checked_conversions.rs:104:13 | LL | let _ = value <= (u32::MAX as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` diff --git a/tests/ui/checked_unwrap/complex_conditionals.rs b/tests/ui/checked_unwrap/complex_conditionals.rs index 323dae380633..3eedb659ebf6 100644 --- a/tests/ui/checked_unwrap/complex_conditionals.rs +++ b/tests/ui/checked_unwrap/complex_conditionals.rs @@ -11,16 +11,20 @@ fn test_complex_conditions() { if x.is_ok() && y.is_err() { // unnecessary x.unwrap(); - //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + // will panic x.unwrap_err(); - //~^ ERROR: this call to `unwrap_err()` will always panic + //~^ panicking_unwrap + // will panic y.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + // unnecessary y.unwrap_err(); - //~^ ERROR: called `unwrap_err` on `y` after checking its variant with `is_err` + //~^ unnecessary_unwrap + } else { // not statically determinable whether any of the following will always succeed or always fail: x.unwrap(); @@ -36,37 +40,47 @@ fn test_complex_conditions() { } else { // will panic x.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + // unnecessary x.unwrap_err(); - //~^ ERROR: called `unwrap_err` on `x` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + // will panic y.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + // unnecessary y.unwrap_err(); - //~^ ERROR: called `unwrap_err` on `y` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + } let z: Result<(), ()> = Ok(()); if x.is_ok() && !(y.is_ok() || z.is_err()) { // unnecessary x.unwrap(); - //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + // will panic x.unwrap_err(); - //~^ ERROR: this call to `unwrap_err()` will always panic + //~^ panicking_unwrap + // will panic y.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + // unnecessary y.unwrap_err(); - //~^ ERROR: called `unwrap_err` on `y` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + // unnecessary z.unwrap(); - //~^ ERROR: called `unwrap` on `z` after checking its variant with `is_err` + //~^ unnecessary_unwrap + // will panic z.unwrap_err(); - //~^ ERROR: this call to `unwrap_err()` will always panic + //~^ panicking_unwrap + } if x.is_ok() || !(y.is_ok() && z.is_err()) { // not statically determinable whether any of the following will always succeed or always fail: @@ -76,22 +90,28 @@ fn test_complex_conditions() { } else { // will panic x.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + // unnecessary x.unwrap_err(); - //~^ ERROR: called `unwrap_err` on `x` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + // unnecessary y.unwrap(); - //~^ ERROR: called `unwrap` on `y` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + // will panic y.unwrap_err(); - //~^ ERROR: this call to `unwrap_err()` will always panic + //~^ panicking_unwrap + // will panic z.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + // unnecessary z.unwrap_err(); - //~^ ERROR: called `unwrap_err` on `z` after checking its variant with `is_err` + //~^ unnecessary_unwrap + } } diff --git a/tests/ui/checked_unwrap/complex_conditionals.stderr b/tests/ui/checked_unwrap/complex_conditionals.stderr index aa72e8cce590..02118affe731 100644 --- a/tests/ui/checked_unwrap/complex_conditionals.stderr +++ b/tests/ui/checked_unwrap/complex_conditionals.stderr @@ -15,7 +15,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:16:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:17:9 | LL | if x.is_ok() && y.is_err() { | --------- because of this check @@ -30,7 +30,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:19:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:21:9 | LL | if x.is_ok() && y.is_err() { | ---------- because of this check @@ -39,7 +39,7 @@ LL | y.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/complex_conditionals.rs:22:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:25:9 | LL | if x.is_ok() && y.is_err() { | ---------- the check is happening here @@ -50,7 +50,7 @@ LL | y.unwrap_err(); = help: try using `if let` or `match` error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:38:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:42:9 | LL | if x.is_ok() || y.is_ok() { | --------- because of this check @@ -59,7 +59,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:41:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:46:9 | LL | if x.is_ok() || y.is_ok() { | --------- the check is happening here @@ -70,7 +70,7 @@ LL | x.unwrap_err(); = help: try using `if let` or `match` error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:44:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:50:9 | LL | if x.is_ok() || y.is_ok() { | --------- because of this check @@ -79,7 +79,7 @@ LL | y.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:47:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:54:9 | LL | if x.is_ok() || y.is_ok() { | --------- the check is happening here @@ -90,7 +90,7 @@ LL | y.unwrap_err(); = help: try using `if let` or `match` error: called `unwrap` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:53:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:61:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- the check is happening here @@ -101,7 +101,7 @@ LL | x.unwrap(); = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:56:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:65:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- because of this check @@ -110,7 +110,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:59:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:69:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- because of this check @@ -119,7 +119,7 @@ LL | y.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:62:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:73:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- the check is happening here @@ -130,7 +130,7 @@ LL | y.unwrap_err(); = help: try using `if let` or `match` error: called `unwrap` on `z` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/complex_conditionals.rs:65:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:77:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | ---------- the check is happening here @@ -141,7 +141,7 @@ LL | z.unwrap(); = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:68:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:81:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | ---------- because of this check @@ -150,7 +150,7 @@ LL | z.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:78:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:92:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- because of this check @@ -159,7 +159,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:81:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:96:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- the check is happening here @@ -170,7 +170,7 @@ LL | x.unwrap_err(); = help: try using `if let` or `match` error: called `unwrap` on `y` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:84:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:100:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- the check is happening here @@ -181,7 +181,7 @@ LL | y.unwrap(); = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:87:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:104:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- because of this check @@ -190,7 +190,7 @@ LL | y.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:90:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:108:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | ---------- because of this check @@ -199,7 +199,7 @@ LL | z.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `z` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/complex_conditionals.rs:93:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:112:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | ---------- the check is happening here diff --git a/tests/ui/checked_unwrap/complex_conditionals_nested.rs b/tests/ui/checked_unwrap/complex_conditionals_nested.rs index 68923793dcdf..145885702a9b 100644 --- a/tests/ui/checked_unwrap/complex_conditionals_nested.rs +++ b/tests/ui/checked_unwrap/complex_conditionals_nested.rs @@ -11,11 +11,11 @@ fn test_nested() { if x.is_some() { // unnecessary x.unwrap(); - //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_some` + //~^ unnecessary_unwrap } else { // will panic x.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap } } } diff --git a/tests/ui/checked_unwrap/simple_conditionals.rs b/tests/ui/checked_unwrap/simple_conditionals.rs index c3c8562edffb..7736643d894c 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.rs +++ b/tests/ui/checked_unwrap/simple_conditionals.rs @@ -11,6 +11,7 @@ macro_rules! m { if $a.is_some() { // unnecessary $a.unwrap(); + //~^ unnecessary_unwrap } }; } @@ -44,26 +45,32 @@ fn main() { if x.is_some() { // unnecessary x.unwrap(); - //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_some` + //~^ unnecessary_unwrap + // unnecessary x.expect("an error message"); - //~^ ERROR: called `expect` on `x` after checking its variant with `is_some` + //~^ unnecessary_unwrap + } else { // will panic x.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + // will panic x.expect("an error message"); - //~^ ERROR: this call to `expect()` will always panic + //~^ panicking_unwrap + } if x.is_none() { // will panic x.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + } else { // unnecessary x.unwrap(); - //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_none` + //~^ unnecessary_unwrap + } m!(x); // ok @@ -76,38 +83,48 @@ fn main() { if x.is_ok() { // unnecessary x.unwrap(); - //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + // unnecessary x.expect("an error message"); - //~^ ERROR: called `expect` on `x` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + // will panic x.unwrap_err(); - //~^ ERROR: this call to `unwrap_err()` will always panic + //~^ panicking_unwrap + } else { // will panic x.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + // will panic x.expect("an error message"); - //~^ ERROR: this call to `expect()` will always panic + //~^ panicking_unwrap + // unnecessary x.unwrap_err(); - //~^ ERROR: called `unwrap_err` on `x` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + } if x.is_err() { // will panic x.unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + // unnecessary x.unwrap_err(); - //~^ ERROR: called `unwrap_err` on `x` after checking its variant with `is_err` + //~^ unnecessary_unwrap + } else { // unnecessary x.unwrap(); - //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_err` + //~^ unnecessary_unwrap + // will panic x.unwrap_err(); - //~^ ERROR: this call to `unwrap_err()` will always panic + //~^ panicking_unwrap + } if x.is_ok() { x = Err(()); @@ -132,38 +149,46 @@ fn issue11371() { if option.is_some() { option.as_ref().unwrap(); - //~^ ERROR: called `unwrap` on `option` after checking its variant with `is_some` + //~^ unnecessary_unwrap + } else { option.as_ref().unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + } let result = Ok::<(), ()>(()); if result.is_ok() { result.as_ref().unwrap(); - //~^ ERROR: called `unwrap` on `result` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + } else { result.as_ref().unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + } let mut option = Some(()); if option.is_some() { option.as_mut().unwrap(); - //~^ ERROR: called `unwrap` on `option` after checking its variant with `is_some` + //~^ unnecessary_unwrap + } else { option.as_mut().unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + } let mut result = Ok::<(), ()>(()); if result.is_ok() { result.as_mut().unwrap(); - //~^ ERROR: called `unwrap` on `result` after checking its variant with `is_ok` + //~^ unnecessary_unwrap + } else { result.as_mut().unwrap(); - //~^ ERROR: this call to `unwrap()` will always panic + //~^ panicking_unwrap + } // This should not lint. Statics are, at the time of writing, not linted on anyway, @@ -172,6 +197,7 @@ fn issue11371() { static mut X: Option = Some(123); unsafe { if X.is_some() { + //~^ ERROR: creating a shared reference X = None; X.unwrap(); } diff --git a/tests/ui/checked_unwrap/simple_conditionals.stderr b/tests/ui/checked_unwrap/simple_conditionals.stderr index d92c03f48881..789a4a8f92bc 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.stderr +++ b/tests/ui/checked_unwrap/simple_conditionals.stderr @@ -1,5 +1,5 @@ error: called `unwrap` on `x` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:46:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:47:9 | LL | if x.is_some() { | -------------- help: try: `if let Some() = x` @@ -14,7 +14,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `expect` on `x` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:49:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:51:9 | LL | if x.is_some() { | -------------- help: try: `if let Some() = x` @@ -23,7 +23,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:53:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:56:9 | LL | if x.is_some() { | ----------- because of this check @@ -38,7 +38,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `expect()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:56:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:60:9 | LL | if x.is_some() { | ----------- because of this check @@ -47,7 +47,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:61:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:66:9 | LL | if x.is_none() { | ----------- because of this check @@ -56,7 +56,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_none` - --> tests/ui/checked_unwrap/simple_conditionals.rs:65:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:71:9 | LL | if x.is_none() { | -------------- help: try: `if let Some() = x` @@ -79,7 +79,7 @@ LL | m!(x); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: called `unwrap` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:78:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:85:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok() = x` @@ -88,7 +88,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `expect` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:81:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:89:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok() = x` @@ -97,7 +97,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:84:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:93:9 | LL | if x.is_ok() { | --------- because of this check @@ -106,7 +106,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:88:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:98:9 | LL | if x.is_ok() { | --------- because of this check @@ -115,7 +115,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: this call to `expect()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:91:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:102:9 | LL | if x.is_ok() { | --------- because of this check @@ -124,7 +124,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:94:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:106:9 | LL | if x.is_ok() { | ------------ help: try: `if let Err() = x` @@ -133,7 +133,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:99:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:112:9 | LL | if x.is_err() { | ---------- because of this check @@ -142,7 +142,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/simple_conditionals.rs:102:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:116:9 | LL | if x.is_err() { | ------------- help: try: `if let Err() = x` @@ -151,7 +151,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/simple_conditionals.rs:106:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:121:9 | LL | if x.is_err() { | ------------- help: try: `if let Ok() = x` @@ -160,7 +160,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:109:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:125:9 | LL | if x.is_err() { | ---------- because of this check @@ -169,7 +169,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:134:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:151:9 | LL | if option.is_some() { | ------------------- help: try: `if let Some() = &option` @@ -177,7 +177,7 @@ LL | option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:137:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:155:9 | LL | if option.is_some() { | ---------------- because of this check @@ -186,7 +186,7 @@ LL | option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:144:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:163:9 | LL | if result.is_ok() { | ----------------- help: try: `if let Ok() = &result` @@ -194,7 +194,7 @@ LL | result.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:147:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:167:9 | LL | if result.is_ok() { | -------------- because of this check @@ -203,7 +203,7 @@ LL | result.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:153:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:174:9 | LL | if option.is_some() { | ------------------- help: try: `if let Some() = &mut option` @@ -211,7 +211,7 @@ LL | option.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:156:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:178:9 | LL | if option.is_some() { | ---------------- because of this check @@ -220,7 +220,7 @@ LL | option.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:162:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:185:9 | LL | if result.is_ok() { | ----------------- help: try: `if let Ok() = &mut result` @@ -228,7 +228,7 @@ LL | result.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:165:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:189:9 | LL | if result.is_ok() { | -------------- because of this check @@ -237,7 +237,7 @@ LL | result.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: creating a shared reference to mutable static is discouraged - --> tests/ui/checked_unwrap/simple_conditionals.rs:174:12 + --> tests/ui/checked_unwrap/simple_conditionals.rs:199:12 | LL | if X.is_some() { | ^^^^^^^^^^^ shared reference to mutable static diff --git a/tests/ui/clear_with_drain.fixed b/tests/ui/clear_with_drain.fixed index 15777a4ea5b3..92fd86668b76 100644 --- a/tests/ui/clear_with_drain.fixed +++ b/tests/ui/clear_with_drain.fixed @@ -20,10 +20,12 @@ fn vec_range() { // Do lint let mut v = vec![1, 2, 3]; v.clear(); + //~^ clear_with_drain // Do lint let mut v = vec![1, 2, 3]; v.clear(); + //~^ clear_with_drain } fn vec_range_from() { @@ -43,10 +45,12 @@ fn vec_range_from() { // Do lint let mut v = vec![1, 2, 3]; v.clear(); + //~^ clear_with_drain // Do lint let mut v = vec![1, 2, 3]; v.clear(); + //~^ clear_with_drain } fn vec_range_full() { @@ -63,6 +67,7 @@ fn vec_range_full() { // Do lint let mut v = vec![1, 2, 3]; v.clear(); + //~^ clear_with_drain } fn vec_range_to() { @@ -80,6 +85,7 @@ fn vec_range_to() { // Do lint let mut v = vec![1, 2, 3]; v.clear(); + //~^ clear_with_drain } fn vec_partial_drains() { @@ -118,10 +124,12 @@ fn vec_deque_range() { // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.clear(); + //~^ clear_with_drain // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.clear(); + //~^ clear_with_drain } fn vec_deque_range_from() { @@ -141,10 +149,12 @@ fn vec_deque_range_from() { // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.clear(); + //~^ clear_with_drain // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.clear(); + //~^ clear_with_drain } fn vec_deque_range_full() { @@ -161,6 +171,7 @@ fn vec_deque_range_full() { // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.clear(); + //~^ clear_with_drain } fn vec_deque_range_to() { @@ -178,6 +189,7 @@ fn vec_deque_range_to() { // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.clear(); + //~^ clear_with_drain } fn vec_deque_partial_drains() { @@ -216,10 +228,12 @@ fn string_range() { // Do lint let mut s = String::from("Hello, world!"); s.clear(); + //~^ clear_with_drain // Do lint let mut s = String::from("Hello, world!"); s.clear(); + //~^ clear_with_drain } fn string_range_from() { @@ -239,10 +253,12 @@ fn string_range_from() { // Do lint let mut s = String::from("Hello, world!"); s.clear(); + //~^ clear_with_drain // Do lint let mut s = String::from("Hello, world!"); s.clear(); + //~^ clear_with_drain } fn string_range_full() { @@ -259,6 +275,7 @@ fn string_range_full() { // Do lint let mut s = String::from("Hello, world!"); s.clear(); + //~^ clear_with_drain } fn string_range_to() { @@ -276,6 +293,7 @@ fn string_range_to() { // Do lint let mut s = String::from("Hello, world!"); s.clear(); + //~^ clear_with_drain } fn string_partial_drains() { @@ -314,6 +332,7 @@ fn hash_set() { // Do lint let mut set = HashSet::from([1, 2, 3]); set.clear(); + //~^ clear_with_drain } fn hash_map() { @@ -333,6 +352,7 @@ fn hash_map() { // Do lint let mut map = HashMap::from([(1, "a"), (2, "b")]); map.clear(); + //~^ clear_with_drain } fn binary_heap() { @@ -352,6 +372,7 @@ fn binary_heap() { // Do lint let mut heap = BinaryHeap::from([1, 2]); heap.clear(); + //~^ clear_with_drain } fn main() {} diff --git a/tests/ui/clear_with_drain.rs b/tests/ui/clear_with_drain.rs index 1dea7235ef66..28122fcaeded 100644 --- a/tests/ui/clear_with_drain.rs +++ b/tests/ui/clear_with_drain.rs @@ -20,10 +20,12 @@ fn vec_range() { // Do lint let mut v = vec![1, 2, 3]; v.drain(0..v.len()); + //~^ clear_with_drain // Do lint let mut v = vec![1, 2, 3]; v.drain(usize::MIN..v.len()); + //~^ clear_with_drain } fn vec_range_from() { @@ -43,10 +45,12 @@ fn vec_range_from() { // Do lint let mut v = vec![1, 2, 3]; v.drain(0..); + //~^ clear_with_drain // Do lint let mut v = vec![1, 2, 3]; v.drain(usize::MIN..); + //~^ clear_with_drain } fn vec_range_full() { @@ -63,6 +67,7 @@ fn vec_range_full() { // Do lint let mut v = vec![1, 2, 3]; v.drain(..); + //~^ clear_with_drain } fn vec_range_to() { @@ -80,6 +85,7 @@ fn vec_range_to() { // Do lint let mut v = vec![1, 2, 3]; v.drain(..v.len()); + //~^ clear_with_drain } fn vec_partial_drains() { @@ -118,10 +124,12 @@ fn vec_deque_range() { // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.drain(0..deque.len()); + //~^ clear_with_drain // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.drain(usize::MIN..deque.len()); + //~^ clear_with_drain } fn vec_deque_range_from() { @@ -141,10 +149,12 @@ fn vec_deque_range_from() { // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.drain(0..); + //~^ clear_with_drain // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.drain(usize::MIN..); + //~^ clear_with_drain } fn vec_deque_range_full() { @@ -161,6 +171,7 @@ fn vec_deque_range_full() { // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.drain(..); + //~^ clear_with_drain } fn vec_deque_range_to() { @@ -178,6 +189,7 @@ fn vec_deque_range_to() { // Do lint let mut deque = VecDeque::from([1, 2, 3]); deque.drain(..deque.len()); + //~^ clear_with_drain } fn vec_deque_partial_drains() { @@ -216,10 +228,12 @@ fn string_range() { // Do lint let mut s = String::from("Hello, world!"); s.drain(0..s.len()); + //~^ clear_with_drain // Do lint let mut s = String::from("Hello, world!"); s.drain(usize::MIN..s.len()); + //~^ clear_with_drain } fn string_range_from() { @@ -239,10 +253,12 @@ fn string_range_from() { // Do lint let mut s = String::from("Hello, world!"); s.drain(0..); + //~^ clear_with_drain // Do lint let mut s = String::from("Hello, world!"); s.drain(usize::MIN..); + //~^ clear_with_drain } fn string_range_full() { @@ -259,6 +275,7 @@ fn string_range_full() { // Do lint let mut s = String::from("Hello, world!"); s.drain(..); + //~^ clear_with_drain } fn string_range_to() { @@ -276,6 +293,7 @@ fn string_range_to() { // Do lint let mut s = String::from("Hello, world!"); s.drain(..s.len()); + //~^ clear_with_drain } fn string_partial_drains() { @@ -314,6 +332,7 @@ fn hash_set() { // Do lint let mut set = HashSet::from([1, 2, 3]); set.drain(); + //~^ clear_with_drain } fn hash_map() { @@ -333,6 +352,7 @@ fn hash_map() { // Do lint let mut map = HashMap::from([(1, "a"), (2, "b")]); map.drain(); + //~^ clear_with_drain } fn binary_heap() { @@ -352,6 +372,7 @@ fn binary_heap() { // Do lint let mut heap = BinaryHeap::from([1, 2]); heap.drain(); + //~^ clear_with_drain } fn main() {} diff --git a/tests/ui/clear_with_drain.stderr b/tests/ui/clear_with_drain.stderr index 3c7d22192dc7..0f060fa9dade 100644 --- a/tests/ui/clear_with_drain.stderr +++ b/tests/ui/clear_with_drain.stderr @@ -8,121 +8,121 @@ LL | v.drain(0..v.len()); = help: to override `-D warnings` add `#[allow(clippy::clear_with_drain)]` error: `drain` used to clear a `Vec` - --> tests/ui/clear_with_drain.rs:26:7 + --> tests/ui/clear_with_drain.rs:27:7 | LL | v.drain(usize::MIN..v.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `Vec` - --> tests/ui/clear_with_drain.rs:45:7 + --> tests/ui/clear_with_drain.rs:47:7 | LL | v.drain(0..); | ^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `Vec` - --> tests/ui/clear_with_drain.rs:49:7 + --> tests/ui/clear_with_drain.rs:52:7 | LL | v.drain(usize::MIN..); | ^^^^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `Vec` - --> tests/ui/clear_with_drain.rs:65:7 + --> tests/ui/clear_with_drain.rs:69:7 | LL | v.drain(..); | ^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `Vec` - --> tests/ui/clear_with_drain.rs:82:7 + --> tests/ui/clear_with_drain.rs:87:7 | LL | v.drain(..v.len()); | ^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `VecDeque` - --> tests/ui/clear_with_drain.rs:120:11 + --> tests/ui/clear_with_drain.rs:126:11 | LL | deque.drain(0..deque.len()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `VecDeque` - --> tests/ui/clear_with_drain.rs:124:11 + --> tests/ui/clear_with_drain.rs:131:11 | LL | deque.drain(usize::MIN..deque.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `VecDeque` - --> tests/ui/clear_with_drain.rs:143:11 + --> tests/ui/clear_with_drain.rs:151:11 | LL | deque.drain(0..); | ^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `VecDeque` - --> tests/ui/clear_with_drain.rs:147:11 + --> tests/ui/clear_with_drain.rs:156:11 | LL | deque.drain(usize::MIN..); | ^^^^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `VecDeque` - --> tests/ui/clear_with_drain.rs:163:11 + --> tests/ui/clear_with_drain.rs:173:11 | LL | deque.drain(..); | ^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `VecDeque` - --> tests/ui/clear_with_drain.rs:180:11 + --> tests/ui/clear_with_drain.rs:191:11 | LL | deque.drain(..deque.len()); | ^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `String` - --> tests/ui/clear_with_drain.rs:218:7 + --> tests/ui/clear_with_drain.rs:230:7 | LL | s.drain(0..s.len()); | ^^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `String` - --> tests/ui/clear_with_drain.rs:222:7 + --> tests/ui/clear_with_drain.rs:235:7 | LL | s.drain(usize::MIN..s.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `String` - --> tests/ui/clear_with_drain.rs:241:7 + --> tests/ui/clear_with_drain.rs:255:7 | LL | s.drain(0..); | ^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `String` - --> tests/ui/clear_with_drain.rs:245:7 + --> tests/ui/clear_with_drain.rs:260:7 | LL | s.drain(usize::MIN..); | ^^^^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `String` - --> tests/ui/clear_with_drain.rs:261:7 + --> tests/ui/clear_with_drain.rs:277:7 | LL | s.drain(..); | ^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `String` - --> tests/ui/clear_with_drain.rs:278:7 + --> tests/ui/clear_with_drain.rs:295:7 | LL | s.drain(..s.len()); | ^^^^^^^^^^^^^^^^ help: try: `clear()` error: `drain` used to clear a `HashSet` - --> tests/ui/clear_with_drain.rs:316:9 + --> tests/ui/clear_with_drain.rs:334:9 | LL | set.drain(); | ^^^^^^^ help: try: `clear()` error: `drain` used to clear a `HashMap` - --> tests/ui/clear_with_drain.rs:335:9 + --> tests/ui/clear_with_drain.rs:354:9 | LL | map.drain(); | ^^^^^^^ help: try: `clear()` error: `drain` used to clear a `BinaryHeap` - --> tests/ui/clear_with_drain.rs:354:10 + --> tests/ui/clear_with_drain.rs:374:10 | LL | heap.drain(); | ^^^^^^^ help: try: `clear()` diff --git a/tests/ui/clone_on_copy.fixed b/tests/ui/clone_on_copy.fixed index 9d9a5bf20f43..f965aa5c182d 100644 --- a/tests/ui/clone_on_copy.fixed +++ b/tests/ui/clone_on_copy.fixed @@ -21,16 +21,20 @@ fn is_ascii(ch: char) -> bool { fn clone_on_copy() -> Option<(i32)> { 42; + //~^ clone_on_copy vec![1].clone(); // ok, not a Copy type Some(vec![1]).clone(); // ok, not a Copy type *(&42); + //~^ clone_on_copy let rc = RefCell::new(0); *rc.borrow(); + //~^ clone_on_copy let x = 0u32; x.rotate_left(1); + //~^ clone_on_copy #[derive(Clone, Copy)] struct Foo; @@ -45,6 +49,7 @@ fn clone_on_copy() -> Option<(i32)> { ($e:expr) => {{ $e }}; } m!(42); + //~^ clone_on_copy struct Wrap([u32; 2]); impl core::ops::Deref for Wrap { @@ -55,6 +60,7 @@ fn clone_on_copy() -> Option<(i32)> { } let x = Wrap([0, 0]); (*x)[0]; + //~^ clone_on_copy let x = 42; let ref y = x.clone(); // ok, binds by reference @@ -65,13 +71,16 @@ fn clone_on_copy() -> Option<(i32)> { let _ = &x.clone(); // ok, getting a ref 'a'.clone().make_ascii_uppercase(); // ok, clone and then mutate is_ascii('z'); + //~^ clone_on_copy // Issue #5436 let mut vec = Vec::new(); vec.push(42); + //~^ clone_on_copy // Issue #9277 let opt: &Option = &None; let value = (*opt)?; // operator precedence needed (*opt)? + //~^ clone_on_copy None } diff --git a/tests/ui/clone_on_copy.rs b/tests/ui/clone_on_copy.rs index 305bc6816e1b..f6a542296de1 100644 --- a/tests/ui/clone_on_copy.rs +++ b/tests/ui/clone_on_copy.rs @@ -21,16 +21,20 @@ fn is_ascii(ch: char) -> bool { fn clone_on_copy() -> Option<(i32)> { 42.clone(); + //~^ clone_on_copy vec![1].clone(); // ok, not a Copy type Some(vec![1]).clone(); // ok, not a Copy type (&42).clone(); + //~^ clone_on_copy let rc = RefCell::new(0); rc.borrow().clone(); + //~^ clone_on_copy let x = 0u32; x.clone().rotate_left(1); + //~^ clone_on_copy #[derive(Clone, Copy)] struct Foo; @@ -45,6 +49,7 @@ fn clone_on_copy() -> Option<(i32)> { ($e:expr) => {{ $e }}; } m!(42).clone(); + //~^ clone_on_copy struct Wrap([u32; 2]); impl core::ops::Deref for Wrap { @@ -55,6 +60,7 @@ fn clone_on_copy() -> Option<(i32)> { } let x = Wrap([0, 0]); x.clone()[0]; + //~^ clone_on_copy let x = 42; let ref y = x.clone(); // ok, binds by reference @@ -65,13 +71,16 @@ fn clone_on_copy() -> Option<(i32)> { let _ = &x.clone(); // ok, getting a ref 'a'.clone().make_ascii_uppercase(); // ok, clone and then mutate is_ascii('z'.clone()); + //~^ clone_on_copy // Issue #5436 let mut vec = Vec::new(); vec.push(42.clone()); + //~^ clone_on_copy // Issue #9277 let opt: &Option = &None; let value = opt.clone()?; // operator precedence needed (*opt)? + //~^ clone_on_copy None } diff --git a/tests/ui/clone_on_copy.stderr b/tests/ui/clone_on_copy.stderr index 314fd13afca4..92cdd635d20a 100644 --- a/tests/ui/clone_on_copy.stderr +++ b/tests/ui/clone_on_copy.stderr @@ -8,49 +8,49 @@ LL | 42.clone(); = help: to override `-D warnings` add `#[allow(clippy::clone_on_copy)]` error: using `clone` on type `i32` which implements the `Copy` trait - --> tests/ui/clone_on_copy.rs:27:5 + --> tests/ui/clone_on_copy.rs:28:5 | LL | (&42).clone(); | ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)` error: using `clone` on type `i32` which implements the `Copy` trait - --> tests/ui/clone_on_copy.rs:30:5 + --> tests/ui/clone_on_copy.rs:32:5 | LL | rc.borrow().clone(); | ^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*rc.borrow()` error: using `clone` on type `u32` which implements the `Copy` trait - --> tests/ui/clone_on_copy.rs:33:5 + --> tests/ui/clone_on_copy.rs:36:5 | LL | x.clone().rotate_left(1); | ^^^^^^^^^ help: try removing the `clone` call: `x` error: using `clone` on type `i32` which implements the `Copy` trait - --> tests/ui/clone_on_copy.rs:47:5 + --> tests/ui/clone_on_copy.rs:51:5 | LL | m!(42).clone(); | ^^^^^^^^^^^^^^ help: try removing the `clone` call: `m!(42)` error: using `clone` on type `[u32; 2]` which implements the `Copy` trait - --> tests/ui/clone_on_copy.rs:57:5 + --> tests/ui/clone_on_copy.rs:62:5 | LL | x.clone()[0]; | ^^^^^^^^^ help: try dereferencing it: `(*x)` error: using `clone` on type `char` which implements the `Copy` trait - --> tests/ui/clone_on_copy.rs:67:14 + --> tests/ui/clone_on_copy.rs:73:14 | LL | is_ascii('z'.clone()); | ^^^^^^^^^^^ help: try removing the `clone` call: `'z'` error: using `clone` on type `i32` which implements the `Copy` trait - --> tests/ui/clone_on_copy.rs:71:14 + --> tests/ui/clone_on_copy.rs:78:14 | LL | vec.push(42.clone()); | ^^^^^^^^^^ help: try removing the `clone` call: `42` error: using `clone` on type `Option` which implements the `Copy` trait - --> tests/ui/clone_on_copy.rs:75:17 + --> tests/ui/clone_on_copy.rs:83:17 | LL | let value = opt.clone()?; // operator precedence needed (*opt)? | ^^^^^^^^^^^ help: try dereferencing it: `(*opt)` diff --git a/tests/ui/clone_on_copy_impl.rs b/tests/ui/clone_on_copy_impl.rs index 2d03544ad8b6..33375aead4d5 100644 --- a/tests/ui/clone_on_copy_impl.rs +++ b/tests/ui/clone_on_copy_impl.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::non_canonical_clone_impl)] use std::fmt; diff --git a/tests/ui/cloned_instead_of_copied.fixed b/tests/ui/cloned_instead_of_copied.fixed index bc939bb3dbb9..94784b4747e8 100644 --- a/tests/ui/cloned_instead_of_copied.fixed +++ b/tests/ui/cloned_instead_of_copied.fixed @@ -5,10 +5,15 @@ fn main() { // yay let _ = [1].iter().copied(); + //~^ cloned_instead_of_copied let _ = vec!["hi"].iter().copied(); + //~^ cloned_instead_of_copied let _ = Some(&1).copied(); + //~^ cloned_instead_of_copied let _ = Box::new([1].iter()).copied(); + //~^ cloned_instead_of_copied let _ = Box::new(Some(&1)).copied(); + //~^ cloned_instead_of_copied // nay let _ = [String::new()].iter().cloned(); @@ -25,10 +30,13 @@ fn msrv_1_34() { fn msrv_1_35() { let _ = [1].iter().cloned(); let _ = Some(&1).copied(); // Option::copied needs 1.35 + //~^ cloned_instead_of_copied } #[clippy::msrv = "1.36"] fn msrv_1_36() { let _ = [1].iter().copied(); // Iterator::copied needs 1.36 + //~^ cloned_instead_of_copied let _ = Some(&1).copied(); + //~^ cloned_instead_of_copied } diff --git a/tests/ui/cloned_instead_of_copied.rs b/tests/ui/cloned_instead_of_copied.rs index 27346adbfbf1..54e01e369f9d 100644 --- a/tests/ui/cloned_instead_of_copied.rs +++ b/tests/ui/cloned_instead_of_copied.rs @@ -5,10 +5,15 @@ fn main() { // yay let _ = [1].iter().cloned(); + //~^ cloned_instead_of_copied let _ = vec!["hi"].iter().cloned(); + //~^ cloned_instead_of_copied let _ = Some(&1).cloned(); + //~^ cloned_instead_of_copied let _ = Box::new([1].iter()).cloned(); + //~^ cloned_instead_of_copied let _ = Box::new(Some(&1)).cloned(); + //~^ cloned_instead_of_copied // nay let _ = [String::new()].iter().cloned(); @@ -25,10 +30,13 @@ fn msrv_1_34() { fn msrv_1_35() { let _ = [1].iter().cloned(); let _ = Some(&1).cloned(); // Option::copied needs 1.35 + //~^ cloned_instead_of_copied } #[clippy::msrv = "1.36"] fn msrv_1_36() { let _ = [1].iter().cloned(); // Iterator::copied needs 1.36 + //~^ cloned_instead_of_copied let _ = Some(&1).cloned(); + //~^ cloned_instead_of_copied } diff --git a/tests/ui/cloned_instead_of_copied.stderr b/tests/ui/cloned_instead_of_copied.stderr index ad857c4ef7d0..70ac0a767daf 100644 --- a/tests/ui/cloned_instead_of_copied.stderr +++ b/tests/ui/cloned_instead_of_copied.stderr @@ -8,43 +8,43 @@ LL | let _ = [1].iter().cloned(); = help: to override `-D warnings` add `#[allow(clippy::cloned_instead_of_copied)]` error: used `cloned` where `copied` could be used instead - --> tests/ui/cloned_instead_of_copied.rs:8:31 + --> tests/ui/cloned_instead_of_copied.rs:9:31 | LL | let _ = vec!["hi"].iter().cloned(); | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> tests/ui/cloned_instead_of_copied.rs:9:22 + --> tests/ui/cloned_instead_of_copied.rs:11:22 | LL | let _ = Some(&1).cloned(); | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> tests/ui/cloned_instead_of_copied.rs:10:34 + --> tests/ui/cloned_instead_of_copied.rs:13:34 | LL | let _ = Box::new([1].iter()).cloned(); | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> tests/ui/cloned_instead_of_copied.rs:11:32 + --> tests/ui/cloned_instead_of_copied.rs:15:32 | LL | let _ = Box::new(Some(&1)).cloned(); | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> tests/ui/cloned_instead_of_copied.rs:27:22 + --> tests/ui/cloned_instead_of_copied.rs:32:22 | LL | let _ = Some(&1).cloned(); // Option::copied needs 1.35 | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> tests/ui/cloned_instead_of_copied.rs:32:24 + --> tests/ui/cloned_instead_of_copied.rs:38:24 | LL | let _ = [1].iter().cloned(); // Iterator::copied needs 1.36 | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> tests/ui/cloned_instead_of_copied.rs:33:22 + --> tests/ui/cloned_instead_of_copied.rs:40:22 | LL | let _ = Some(&1).cloned(); | ^^^^^^ help: try: `copied` diff --git a/tests/ui/cmp_null.fixed b/tests/ui/cmp_null.fixed index e5ab765bc861..27b831950dc7 100644 --- a/tests/ui/cmp_null.fixed +++ b/tests/ui/cmp_null.fixed @@ -7,26 +7,31 @@ fn main() { let x = 0; let p: *const usize = &x; if p.is_null() { - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method - //~| NOTE: `-D clippy::cmp-null` implied by `-D warnings` + //~^ cmp_null + + println!("This is surprising!"); } if p.is_null() { - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + //~^ cmp_null + println!("This is surprising!"); } let mut y = 0; let mut m: *mut usize = &mut y; if m.is_null() { - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + //~^ cmp_null + println!("This is surprising, too!"); } if m.is_null() { - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + //~^ cmp_null + println!("This is surprising, too!"); } let _ = (x as *const ()).is_null(); - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + //~^ cmp_null + } diff --git a/tests/ui/cmp_null.rs b/tests/ui/cmp_null.rs index 257f7ba26627..ac1bf83e094c 100644 --- a/tests/ui/cmp_null.rs +++ b/tests/ui/cmp_null.rs @@ -7,26 +7,31 @@ fn main() { let x = 0; let p: *const usize = &x; if p == ptr::null() { - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method - //~| NOTE: `-D clippy::cmp-null` implied by `-D warnings` + //~^ cmp_null + + println!("This is surprising!"); } if ptr::null() == p { - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + //~^ cmp_null + println!("This is surprising!"); } let mut y = 0; let mut m: *mut usize = &mut y; if m == ptr::null_mut() { - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + //~^ cmp_null + println!("This is surprising, too!"); } if ptr::null_mut() == m { - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + //~^ cmp_null + println!("This is surprising, too!"); } let _ = x as *const () == ptr::null(); - //~^ ERROR: comparing with null is better expressed by the `.is_null()` method + //~^ cmp_null + } diff --git a/tests/ui/cmp_null.stderr b/tests/ui/cmp_null.stderr index f3b35f3afba8..a44dd8067613 100644 --- a/tests/ui/cmp_null.stderr +++ b/tests/ui/cmp_null.stderr @@ -8,25 +8,25 @@ LL | if p == ptr::null() { = help: to override `-D warnings` add `#[allow(clippy::cmp_null)]` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:14:8 + --> tests/ui/cmp_null.rs:15:8 | LL | if ptr::null() == p { | ^^^^^^^^^^^^^^^^ help: try: `p.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:21:8 + --> tests/ui/cmp_null.rs:23:8 | LL | if m == ptr::null_mut() { | ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:25:8 + --> tests/ui/cmp_null.rs:28:8 | LL | if ptr::null_mut() == m { | ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:30:13 + --> tests/ui/cmp_null.rs:34:13 | LL | let _ = x as *const () == ptr::null(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(x as *const ()).is_null()` diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.fixed b/tests/ui/cmp_owned/asymmetric_partial_eq.fixed index 9fc70ab6f4a0..8d543b042200 100644 --- a/tests/ui/cmp_owned/asymmetric_partial_eq.fixed +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.fixed @@ -44,7 +44,9 @@ mod borrowed_eq_owned { let borrowed = Borrowed {}; if borrowed == owned {} + //~^ cmp_owned if borrowed == owned {} + //~^ cmp_owned } } @@ -63,7 +65,9 @@ mod owned_eq_borrowed { let borrowed = Borrowed {}; if owned == borrowed {} + //~^ cmp_owned if owned == borrowed {} + //~^ cmp_owned } } @@ -90,7 +94,9 @@ mod issue_4874 { let borrowed = Borrowed {}; if borrowed == "Hi" {} + //~^ cmp_owned if borrowed == "Hi" {} + //~^ cmp_owned } } diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.rs b/tests/ui/cmp_owned/asymmetric_partial_eq.rs index 5cd43ea1d411..6da311c50ee7 100644 --- a/tests/ui/cmp_owned/asymmetric_partial_eq.rs +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.rs @@ -44,7 +44,9 @@ mod borrowed_eq_owned { let borrowed = Borrowed {}; if borrowed.to_owned() == owned {} + //~^ cmp_owned if owned == borrowed.to_owned() {} + //~^ cmp_owned } } @@ -63,7 +65,9 @@ mod owned_eq_borrowed { let borrowed = Borrowed {}; if owned == borrowed.to_owned() {} + //~^ cmp_owned if borrowed.to_owned() == owned {} + //~^ cmp_owned } } @@ -90,7 +94,9 @@ mod issue_4874 { let borrowed = Borrowed {}; if "Hi" == borrowed.to_string() {} + //~^ cmp_owned if borrowed.to_string() == "Hi" {} + //~^ cmp_owned } } diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.stderr b/tests/ui/cmp_owned/asymmetric_partial_eq.stderr index e230d5f06bb0..1d2645d358f3 100644 --- a/tests/ui/cmp_owned/asymmetric_partial_eq.stderr +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.stderr @@ -8,7 +8,7 @@ LL | if borrowed.to_owned() == owned {} = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:47:21 + --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:48:21 | LL | if owned == borrowed.to_owned() {} | ---------^^^^^^^^^^^^^^^^^^^ @@ -16,13 +16,13 @@ LL | if owned == borrowed.to_owned() {} | help: try: `borrowed == owned` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:65:21 + --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:67:21 | LL | if owned == borrowed.to_owned() {} | ^^^^^^^^^^^^^^^^^^^ help: try: `borrowed` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:66:12 + --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:69:12 | LL | if borrowed.to_owned() == owned {} | ^^^^^^^^^^^^^^^^^^^--------- @@ -30,7 +30,7 @@ LL | if borrowed.to_owned() == owned {} | help: try: `owned == borrowed` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:92:20 + --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:96:20 | LL | if "Hi" == borrowed.to_string() {} | --------^^^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | if "Hi" == borrowed.to_string() {} | help: try: `borrowed == "Hi"` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:93:12 + --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:98:12 | LL | if borrowed.to_string() == "Hi" {} | ^^^^^^^^^^^^^^^^^^^^ help: try: `borrowed` diff --git a/tests/ui/cmp_owned/comparison_flip.fixed b/tests/ui/cmp_owned/comparison_flip.fixed index 40d7b5e49fcd..a926857c78a1 100644 --- a/tests/ui/cmp_owned/comparison_flip.fixed +++ b/tests/ui/cmp_owned/comparison_flip.fixed @@ -4,10 +4,12 @@ fn main() { let a = Foo; if a != "bar" { + //~^ cmp_owned println!("foo"); } if a != "bar" { + //~^ cmp_owned println!("foo"); } } diff --git a/tests/ui/cmp_owned/comparison_flip.rs b/tests/ui/cmp_owned/comparison_flip.rs index 59a945668b2e..169d472203c5 100644 --- a/tests/ui/cmp_owned/comparison_flip.rs +++ b/tests/ui/cmp_owned/comparison_flip.rs @@ -4,10 +4,12 @@ fn main() { let a = Foo; if a.to_string() != "bar" { + //~^ cmp_owned println!("foo"); } if "bar" != a.to_string() { + //~^ cmp_owned println!("foo"); } } diff --git a/tests/ui/cmp_owned/comparison_flip.stderr b/tests/ui/cmp_owned/comparison_flip.stderr index cfb6978158b3..ca571837039d 100644 --- a/tests/ui/cmp_owned/comparison_flip.stderr +++ b/tests/ui/cmp_owned/comparison_flip.stderr @@ -8,7 +8,7 @@ LL | if a.to_string() != "bar" { = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/comparison_flip.rs:10:17 + --> tests/ui/cmp_owned/comparison_flip.rs:11:17 | LL | if "bar" != a.to_string() { | ---------^^^^^^^^^^^^^ diff --git a/tests/ui/cmp_owned/with_suggestion.fixed b/tests/ui/cmp_owned/with_suggestion.fixed index ab72e096cc7c..eb01633a25fd 100644 --- a/tests/ui/cmp_owned/with_suggestion.fixed +++ b/tests/ui/cmp_owned/with_suggestion.fixed @@ -3,8 +3,10 @@ fn main() { fn with_to_string(x: &str) { x != "foo"; + //~^ cmp_owned "foo" != x; + //~^ cmp_owned } let x = "oh"; @@ -12,14 +14,18 @@ fn main() { with_to_string(x); x != "foo"; + //~^ cmp_owned x != "foo"; + //~^ cmp_owned 42.to_string() == "42"; Foo == Foo; + //~^ cmp_owned "abc".chars().filter(|c| *c != 'X'); + //~^ cmp_owned "abc".chars().filter(|c| *c != 'X'); } diff --git a/tests/ui/cmp_owned/with_suggestion.rs b/tests/ui/cmp_owned/with_suggestion.rs index cb5268734d32..82409f27b129 100644 --- a/tests/ui/cmp_owned/with_suggestion.rs +++ b/tests/ui/cmp_owned/with_suggestion.rs @@ -3,8 +3,10 @@ fn main() { fn with_to_string(x: &str) { x != "foo".to_string(); + //~^ cmp_owned "foo".to_string() != x; + //~^ cmp_owned } let x = "oh"; @@ -12,14 +14,18 @@ fn main() { with_to_string(x); x != "foo".to_owned(); + //~^ cmp_owned x != String::from("foo"); + //~^ cmp_owned 42.to_string() == "42"; Foo.to_owned() == Foo; + //~^ cmp_owned "abc".chars().filter(|c| c.to_owned() != 'X'); + //~^ cmp_owned "abc".chars().filter(|c| *c != 'X'); } diff --git a/tests/ui/cmp_owned/with_suggestion.stderr b/tests/ui/cmp_owned/with_suggestion.stderr index 41448e012003..ca2ab4484727 100644 --- a/tests/ui/cmp_owned/with_suggestion.stderr +++ b/tests/ui/cmp_owned/with_suggestion.stderr @@ -8,31 +8,31 @@ LL | x != "foo".to_string(); = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/with_suggestion.rs:7:9 + --> tests/ui/cmp_owned/with_suggestion.rs:8:9 | LL | "foo".to_string() != x; | ^^^^^^^^^^^^^^^^^ help: try: `"foo"` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/with_suggestion.rs:14:10 + --> tests/ui/cmp_owned/with_suggestion.rs:16:10 | LL | x != "foo".to_owned(); | ^^^^^^^^^^^^^^^^ help: try: `"foo"` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/with_suggestion.rs:16:10 + --> tests/ui/cmp_owned/with_suggestion.rs:19:10 | LL | x != String::from("foo"); | ^^^^^^^^^^^^^^^^^^^ help: try: `"foo"` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/with_suggestion.rs:20:5 + --> tests/ui/cmp_owned/with_suggestion.rs:24:5 | LL | Foo.to_owned() == Foo; | ^^^^^^^^^^^^^^ help: try: `Foo` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/with_suggestion.rs:22:30 + --> tests/ui/cmp_owned/with_suggestion.rs:27:30 | LL | "abc".chars().filter(|c| c.to_owned() != 'X'); | ^^^^^^^^^^^^ help: try: `*c` diff --git a/tests/ui/cmp_owned/without_suggestion.rs b/tests/ui/cmp_owned/without_suggestion.rs index 913aab727471..71bcac44ed7c 100644 --- a/tests/ui/cmp_owned/without_suggestion.rs +++ b/tests/ui/cmp_owned/without_suggestion.rs @@ -5,13 +5,15 @@ fn main() { let x = &Baz; let y = &Baz; y.to_owned() == *x; - //~^ ERROR: this creates an owned instance just for comparison - //~| NOTE: `-D clippy::cmp-owned` implied by `-D warnings` + //~^ cmp_owned + + let x = &&Baz; let y = &Baz; y.to_owned() == **x; - //~^ ERROR: this creates an owned instance just for comparison + //~^ cmp_owned + let x = 0u32; let y = U32Wrapper(x); @@ -23,7 +25,8 @@ struct Foo; impl PartialEq for Foo { fn eq(&self, other: &Self) -> bool { self.to_owned() == *other - //~^ ERROR: this creates an owned instance just for comparison + //~^ cmp_owned + } } diff --git a/tests/ui/cmp_owned/without_suggestion.stderr b/tests/ui/cmp_owned/without_suggestion.stderr index 13ca699b9fd3..6efaf9688e20 100644 --- a/tests/ui/cmp_owned/without_suggestion.stderr +++ b/tests/ui/cmp_owned/without_suggestion.stderr @@ -8,13 +8,13 @@ LL | y.to_owned() == *x; = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/without_suggestion.rs:13:5 + --> tests/ui/cmp_owned/without_suggestion.rs:14:5 | LL | y.to_owned() == **x; | ^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/without_suggestion.rs:25:9 + --> tests/ui/cmp_owned/without_suggestion.rs:27:9 | LL | self.to_owned() == *other | ^^^^^^^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating diff --git a/tests/ui/cognitive_complexity.rs b/tests/ui/cognitive_complexity.rs index e8fd063a98f2..d750202d00ec 100644 --- a/tests/ui/cognitive_complexity.rs +++ b/tests/ui/cognitive_complexity.rs @@ -4,7 +4,8 @@ #[rustfmt::skip] fn main() { -//~^ ERROR: the function has a cognitive complexity of (28/25) +//~^ cognitive_complexity + if true { println!("a"); } @@ -90,7 +91,8 @@ fn main() { #[clippy::cognitive_complexity = "1"] fn kaboom() { - //~^ ERROR: the function has a cognitive complexity of (7/1) +//~^ cognitive_complexity + let n = 0; 'a: for i in 0..20 { 'b: for j in i..20 { @@ -149,9 +151,11 @@ fn lots_of_short_circuits2() -> bool { #[clippy::cognitive_complexity = "1"] fn baa() { - //~^ ERROR: the function has a cognitive complexity of (2/1) +//~^ cognitive_complexity + let x = || match 99 { - //~^ ERROR: the function has a cognitive complexity of (2/1) + //~^ cognitive_complexity + 0 => 0, 1 => 1, 2 => 2, @@ -169,7 +173,8 @@ fn baa() { #[clippy::cognitive_complexity = "1"] fn bar() { - //~^ ERROR: the function has a cognitive complexity of (2/1) +//~^ cognitive_complexity + match 99 { 0 => println!("hi"), _ => println!("bye"), @@ -181,7 +186,8 @@ fn bar() { /// Tests are usually complex but simple at the same time. `clippy::cognitive_complexity` used to /// give lots of false-positives in tests. fn dont_warn_on_tests() { - //~^ ERROR: the function has a cognitive complexity of (2/1) +//~^ cognitive_complexity + match 99 { 0 => println!("hi"), _ => println!("bye"), @@ -190,7 +196,8 @@ fn dont_warn_on_tests() { #[clippy::cognitive_complexity = "1"] fn barr() { - //~^ ERROR: the function has a cognitive complexity of (2/1) +//~^ cognitive_complexity + match 99 { 0 => println!("hi"), 1 => println!("bla"), @@ -201,7 +208,8 @@ fn barr() { #[clippy::cognitive_complexity = "1"] fn barr2() { - //~^ ERROR: the function has a cognitive complexity of (3/1) +//~^ cognitive_complexity + match 99 { 0 => println!("hi"), 1 => println!("bla"), @@ -218,7 +226,8 @@ fn barr2() { #[clippy::cognitive_complexity = "1"] fn barrr() { - //~^ ERROR: the function has a cognitive complexity of (2/1) +//~^ cognitive_complexity + match 99 { 0 => println!("hi"), 1 => panic!("bla"), @@ -229,7 +238,8 @@ fn barrr() { #[clippy::cognitive_complexity = "1"] fn barrr2() { - //~^ ERROR: the function has a cognitive complexity of (3/1) +//~^ cognitive_complexity + match 99 { 0 => println!("hi"), 1 => panic!("bla"), @@ -246,7 +256,8 @@ fn barrr2() { #[clippy::cognitive_complexity = "1"] fn barrrr() { - //~^ ERROR: the function has a cognitive complexity of (2/1) +//~^ cognitive_complexity + match 99 { 0 => println!("hi"), 1 => println!("bla"), @@ -257,7 +268,8 @@ fn barrrr() { #[clippy::cognitive_complexity = "1"] fn barrrr2() { - //~^ ERROR: the function has a cognitive complexity of (3/1) +//~^ cognitive_complexity + match 99 { 0 => println!("hi"), 1 => println!("bla"), @@ -274,7 +286,8 @@ fn barrrr2() { #[clippy::cognitive_complexity = "1"] fn cake() { - //~^ ERROR: the function has a cognitive complexity of (2/1) +//~^ cognitive_complexity + if 4 == 5 { println!("yea"); } else { @@ -285,7 +298,8 @@ fn cake() { #[clippy::cognitive_complexity = "1"] pub fn read_file(input_path: &str) -> String { - //~^ ERROR: the function has a cognitive complexity of (4/1) +//~^ cognitive_complexity + use std::fs::File; use std::io::{Read, Write}; use std::path::Path; @@ -317,7 +331,8 @@ enum Void {} #[clippy::cognitive_complexity = "1"] fn void(void: Void) { - //~^ ERROR: the function has a cognitive complexity of (2/1) +//~^ cognitive_complexity + if true { match void {} } @@ -369,7 +384,8 @@ fn early() -> Result { #[rustfmt::skip] #[clippy::cognitive_complexity = "1"] fn early_ret() -> i32 { -//~^ ERROR: the function has a cognitive complexity of (8/1) +//~^ cognitive_complexity + let a = if true { 42 } else { return 0; }; let a = if a < 99 { 42 } else { return 0; }; let a = if a < 99 { 42 } else { return 0; }; @@ -391,7 +407,8 @@ fn early_ret() -> i32 { #[clippy::cognitive_complexity = "1"] fn closures() { let x = |a: i32, b: i32| -> i32 { - //~^ ERROR: the function has a cognitive complexity of (2/1) + //~^ cognitive_complexity + if true { println!("moo"); } @@ -405,7 +422,8 @@ struct Moo; #[clippy::cognitive_complexity = "1"] impl Moo { fn moo(&self) { - //~^ ERROR: the function has a cognitive complexity of (2/1) + //~^ cognitive_complexity + if true { println!("moo"); } @@ -415,7 +433,8 @@ impl Moo { #[clippy::cognitive_complexity = "1"] mod issue9300 { async fn a() { - //~^ ERROR: the function has a cognitive complexity of (2/1) + //~^ cognitive_complexity + let a = 0; if a == 0 {} } @@ -423,7 +442,8 @@ mod issue9300 { pub struct S; impl S { pub async fn async_method() { - //~^ ERROR: the function has a cognitive complexity of (2/1) + //~^ cognitive_complexity + let a = 0; if a == 0 {} } diff --git a/tests/ui/cognitive_complexity.stderr b/tests/ui/cognitive_complexity.stderr index 1e60247e5f58..60a834765a6b 100644 --- a/tests/ui/cognitive_complexity.stderr +++ b/tests/ui/cognitive_complexity.stderr @@ -9,7 +9,7 @@ LL | fn main() { = help: to override `-D warnings` add `#[allow(clippy::cognitive_complexity)]` error: the function has a cognitive complexity of (7/1) - --> tests/ui/cognitive_complexity.rs:92:4 + --> tests/ui/cognitive_complexity.rs:93:4 | LL | fn kaboom() { | ^^^^^^ @@ -17,7 +17,7 @@ LL | fn kaboom() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:151:4 + --> tests/ui/cognitive_complexity.rs:153:4 | LL | fn baa() { | ^^^ @@ -25,7 +25,7 @@ LL | fn baa() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:153:13 + --> tests/ui/cognitive_complexity.rs:156:13 | LL | let x = || match 99 { | ^^ @@ -33,7 +33,7 @@ LL | let x = || match 99 { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:171:4 + --> tests/ui/cognitive_complexity.rs:175:4 | LL | fn bar() { | ^^^ @@ -41,7 +41,7 @@ LL | fn bar() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:183:4 + --> tests/ui/cognitive_complexity.rs:188:4 | LL | fn dont_warn_on_tests() { | ^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | fn dont_warn_on_tests() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:192:4 + --> tests/ui/cognitive_complexity.rs:198:4 | LL | fn barr() { | ^^^^ @@ -57,7 +57,7 @@ LL | fn barr() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (3/1) - --> tests/ui/cognitive_complexity.rs:203:4 + --> tests/ui/cognitive_complexity.rs:210:4 | LL | fn barr2() { | ^^^^^ @@ -65,7 +65,7 @@ LL | fn barr2() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:220:4 + --> tests/ui/cognitive_complexity.rs:228:4 | LL | fn barrr() { | ^^^^^ @@ -73,7 +73,7 @@ LL | fn barrr() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (3/1) - --> tests/ui/cognitive_complexity.rs:231:4 + --> tests/ui/cognitive_complexity.rs:240:4 | LL | fn barrr2() { | ^^^^^^ @@ -81,7 +81,7 @@ LL | fn barrr2() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:248:4 + --> tests/ui/cognitive_complexity.rs:258:4 | LL | fn barrrr() { | ^^^^^^ @@ -89,7 +89,7 @@ LL | fn barrrr() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (3/1) - --> tests/ui/cognitive_complexity.rs:259:4 + --> tests/ui/cognitive_complexity.rs:270:4 | LL | fn barrrr2() { | ^^^^^^^ @@ -97,7 +97,7 @@ LL | fn barrrr2() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:276:4 + --> tests/ui/cognitive_complexity.rs:288:4 | LL | fn cake() { | ^^^^ @@ -105,7 +105,7 @@ LL | fn cake() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (4/1) - --> tests/ui/cognitive_complexity.rs:287:8 + --> tests/ui/cognitive_complexity.rs:300:8 | LL | pub fn read_file(input_path: &str) -> String { | ^^^^^^^^^ @@ -113,7 +113,7 @@ LL | pub fn read_file(input_path: &str) -> String { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:319:4 + --> tests/ui/cognitive_complexity.rs:333:4 | LL | fn void(void: Void) { | ^^^^ @@ -121,7 +121,7 @@ LL | fn void(void: Void) { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (8/1) - --> tests/ui/cognitive_complexity.rs:371:4 + --> tests/ui/cognitive_complexity.rs:386:4 | LL | fn early_ret() -> i32 { | ^^^^^^^^^ @@ -129,7 +129,7 @@ LL | fn early_ret() -> i32 { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:393:13 + --> tests/ui/cognitive_complexity.rs:409:13 | LL | let x = |a: i32, b: i32| -> i32 { | ^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ LL | let x = |a: i32, b: i32| -> i32 { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:407:8 + --> tests/ui/cognitive_complexity.rs:424:8 | LL | fn moo(&self) { | ^^^ @@ -145,7 +145,7 @@ LL | fn moo(&self) { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:417:14 + --> tests/ui/cognitive_complexity.rs:435:14 | LL | async fn a() { | ^ @@ -153,7 +153,7 @@ LL | async fn a() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:425:22 + --> tests/ui/cognitive_complexity.rs:444:22 | LL | pub async fn async_method() { | ^^^^^^^^^^^^ diff --git a/tests/ui/cognitive_complexity_attr_used.rs b/tests/ui/cognitive_complexity_attr_used.rs index 6f6e89983d2b..ed62dd7b933e 100644 --- a/tests/ui/cognitive_complexity_attr_used.rs +++ b/tests/ui/cognitive_complexity_attr_used.rs @@ -7,7 +7,8 @@ fn main() { #[clippy::cognitive_complexity = "0"] fn kaboom() { - //~^ ERROR: the function has a cognitive complexity of (3/0) +//~^ cognitive_complexity + if 42 == 43 { panic!(); } else if "cake" == "lie" { diff --git a/tests/ui/collapsible_else_if.fixed b/tests/ui/collapsible_else_if.fixed index c2d76146c641..9f530ad670a0 100644 --- a/tests/ui/collapsible_else_if.fixed +++ b/tests/ui/collapsible_else_if.fixed @@ -11,12 +11,14 @@ fn main() { } else if y == "world" { println!("world!") } + //~^^^^^ collapsible_else_if if x == "hello" { print!("Hello "); } else if let Some(42) = Some(42) { println!("world!") } + //~^^^^^ collapsible_else_if if x == "hello" { print!("Hello "); @@ -26,6 +28,7 @@ fn main() { else { println!("!") } + //~^^^^^^^^ collapsible_else_if if x == "hello" { print!("Hello "); @@ -35,6 +38,7 @@ fn main() { else { println!("!") } + //~^^^^^^^^ collapsible_else_if if let Some(42) = Some(42) { print!("Hello "); @@ -44,6 +48,7 @@ fn main() { else { println!("!") } + //~^^^^^^^^ collapsible_else_if if let Some(42) = Some(42) { print!("Hello "); @@ -53,6 +58,7 @@ fn main() { else { println!("!") } + //~^^^^^^^^ collapsible_else_if if let Some(42) = Some(42) { print!("Hello "); @@ -62,6 +68,7 @@ fn main() { else { println!("!") } + //~^^^^^^^^ collapsible_else_if if x == "hello" { print!("Hello "); @@ -77,4 +84,5 @@ fn main() { fn issue_7318() { if true { println!("I've been resolved!") }else if false {} + //~^^^ collapsible_else_if } diff --git a/tests/ui/collapsible_else_if.rs b/tests/ui/collapsible_else_if.rs index 3579e46cd447..2c646cd1d4da 100644 --- a/tests/ui/collapsible_else_if.rs +++ b/tests/ui/collapsible_else_if.rs @@ -13,6 +13,7 @@ fn main() { println!("world!") } } + //~^^^^^ collapsible_else_if if x == "hello" { print!("Hello "); @@ -21,6 +22,7 @@ fn main() { println!("world!") } } + //~^^^^^ collapsible_else_if if x == "hello" { print!("Hello "); @@ -32,6 +34,7 @@ fn main() { println!("!") } } + //~^^^^^^^^ collapsible_else_if if x == "hello" { print!("Hello "); @@ -43,6 +46,7 @@ fn main() { println!("!") } } + //~^^^^^^^^ collapsible_else_if if let Some(42) = Some(42) { print!("Hello "); @@ -54,6 +58,7 @@ fn main() { println!("!") } } + //~^^^^^^^^ collapsible_else_if if let Some(42) = Some(42) { print!("Hello "); @@ -65,6 +70,7 @@ fn main() { println!("!") } } + //~^^^^^^^^ collapsible_else_if if let Some(42) = Some(42) { print!("Hello "); @@ -76,6 +82,7 @@ fn main() { println!("!") } } + //~^^^^^^^^ collapsible_else_if if x == "hello" { print!("Hello "); @@ -93,4 +100,5 @@ fn issue_7318() { }else{ if false {} } + //~^^^ collapsible_else_if } diff --git a/tests/ui/collapsible_else_if.stderr b/tests/ui/collapsible_else_if.stderr deleted file mode 100644 index 45566a78bd81..000000000000 --- a/tests/ui/collapsible_else_if.stderr +++ /dev/null @@ -1,154 +0,0 @@ -error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:11:12 - | -LL | } else { - | ____________^ -LL | | if y == "world" { -LL | | println!("world!") -LL | | } -LL | | } - | |_____^ - | - = note: `-D clippy::collapsible-else-if` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::collapsible_else_if)]` -help: collapse nested if block - | -LL ~ } else if y == "world" { -LL + println!("world!") -LL + } - | - -error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:19:12 - | -LL | } else { - | ____________^ -LL | | if let Some(42) = Some(42) { -LL | | println!("world!") -LL | | } -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ } else if let Some(42) = Some(42) { -LL + println!("world!") -LL + } - | - -error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:27:12 - | -LL | } else { - | ____________^ -LL | | if y == "world" { -LL | | println!("world") -... | -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ } else if y == "world" { -LL + println!("world") -LL + } -LL + else { -LL + println!("!") -LL + } - | - -error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:38:12 - | -LL | } else { - | ____________^ -LL | | if let Some(42) = Some(42) { -LL | | println!("world") -... | -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ } else if let Some(42) = Some(42) { -LL + println!("world") -LL + } -LL + else { -LL + println!("!") -LL + } - | - -error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:49:12 - | -LL | } else { - | ____________^ -LL | | if let Some(42) = Some(42) { -LL | | println!("world") -... | -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ } else if let Some(42) = Some(42) { -LL + println!("world") -LL + } -LL + else { -LL + println!("!") -LL + } - | - -error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:60:12 - | -LL | } else { - | ____________^ -LL | | if x == "hello" { -LL | | println!("world") -... | -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ } else if x == "hello" { -LL + println!("world") -LL + } -LL + else { -LL + println!("!") -LL + } - | - -error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:71:12 - | -LL | } else { - | ____________^ -LL | | if let Some(42) = Some(42) { -LL | | println!("world") -... | -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ } else if let Some(42) = Some(42) { -LL + println!("world") -LL + } -LL + else { -LL + println!("!") -LL + } - | - -error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:93:10 - | -LL | }else{ - | __________^ -LL | | if false {} -LL | | } - | |_____^ help: collapse nested if block: `if false {}` - -error: aborting due to 8 previous errors - diff --git a/tests/ui/collapsible_if.fixed b/tests/ui/collapsible_if.fixed index 44b0b6e73915..6e994018aef0 100644 --- a/tests/ui/collapsible_if.fixed +++ b/tests/ui/collapsible_if.fixed @@ -15,26 +15,32 @@ fn main() { if x == "hello" && y == "world" { println!("Hello world!"); } + //~^^^^^ collapsible_if if (x == "hello" || x == "world") && (y == "world" || y == "hello") { println!("Hello world!"); } + //~^^^^^ collapsible_if if x == "hello" && x == "world" && (y == "world" || y == "hello") { println!("Hello world!"); } + //~^^^^^ collapsible_if if (x == "hello" || x == "world") && y == "world" && y == "hello" { println!("Hello world!"); } + //~^^^^^ collapsible_if if x == "hello" && x == "world" && y == "world" && y == "hello" { println!("Hello world!"); } + //~^^^^^ collapsible_if if 42 == 1337 && 'a' != 'A' { println!("world!") } + //~^^^^^ collapsible_if // Works because any if with an else statement cannot be collapsed. if x == "hello" { @@ -89,6 +95,7 @@ fn main() { if x == "hello" && y == "world" { // Collapsible println!("Hello world!"); } + //~^^^^^ collapsible_if if x == "hello" { print!("Hello "); @@ -144,9 +151,11 @@ fn main() { // Fix #5962 if matches!(true, true) && matches!(true, true) {} + //~^^^ collapsible_if // Issue #9375 if matches!(true, true) && truth() && matches!(true, true) {} + //~^^^ collapsible_if if true { #[cfg(not(teehee))] diff --git a/tests/ui/collapsible_if.rs b/tests/ui/collapsible_if.rs index 563a273dcddd..5cf591a658c7 100644 --- a/tests/ui/collapsible_if.rs +++ b/tests/ui/collapsible_if.rs @@ -17,36 +17,42 @@ fn main() { println!("Hello world!"); } } + //~^^^^^ collapsible_if if x == "hello" || x == "world" { if y == "world" || y == "hello" { println!("Hello world!"); } } + //~^^^^^ collapsible_if if x == "hello" && x == "world" { if y == "world" || y == "hello" { println!("Hello world!"); } } + //~^^^^^ collapsible_if if x == "hello" || x == "world" { if y == "world" && y == "hello" { println!("Hello world!"); } } + //~^^^^^ collapsible_if if x == "hello" && x == "world" { if y == "world" && y == "hello" { println!("Hello world!"); } } + //~^^^^^ collapsible_if if 42 == 1337 { if 'a' != 'A' { println!("world!") } } + //~^^^^^ collapsible_if // Works because any if with an else statement cannot be collapsed. if x == "hello" { @@ -103,6 +109,7 @@ fn main() { println!("Hello world!"); } } + //~^^^^^ collapsible_if if x == "hello" { print!("Hello "); @@ -160,11 +167,13 @@ fn main() { if matches!(true, true) { if matches!(true, true) {} } + //~^^^ collapsible_if // Issue #9375 if matches!(true, true) && truth() { if matches!(true, true) {} } + //~^^^ collapsible_if if true { #[cfg(not(teehee))] diff --git a/tests/ui/collapsible_if.stderr b/tests/ui/collapsible_if.stderr deleted file mode 100644 index 5bcbdf2fd08d..000000000000 --- a/tests/ui/collapsible_if.stderr +++ /dev/null @@ -1,139 +0,0 @@ -error: this `if` statement can be collapsed - --> tests/ui/collapsible_if.rs:15:5 - | -LL | / if x == "hello" { -LL | | if y == "world" { -LL | | println!("Hello world!"); -LL | | } -LL | | } - | |_____^ - | - = note: `-D clippy::collapsible-if` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::collapsible_if)]` -help: collapse nested if block - | -LL ~ if x == "hello" && y == "world" { -LL + println!("Hello world!"); -LL + } - | - -error: this `if` statement can be collapsed - --> tests/ui/collapsible_if.rs:21:5 - | -LL | / if x == "hello" || x == "world" { -LL | | if y == "world" || y == "hello" { -LL | | println!("Hello world!"); -LL | | } -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ if (x == "hello" || x == "world") && (y == "world" || y == "hello") { -LL + println!("Hello world!"); -LL + } - | - -error: this `if` statement can be collapsed - --> tests/ui/collapsible_if.rs:27:5 - | -LL | / if x == "hello" && x == "world" { -LL | | if y == "world" || y == "hello" { -LL | | println!("Hello world!"); -LL | | } -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ if x == "hello" && x == "world" && (y == "world" || y == "hello") { -LL + println!("Hello world!"); -LL + } - | - -error: this `if` statement can be collapsed - --> tests/ui/collapsible_if.rs:33:5 - | -LL | / if x == "hello" || x == "world" { -LL | | if y == "world" && y == "hello" { -LL | | println!("Hello world!"); -LL | | } -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ if (x == "hello" || x == "world") && y == "world" && y == "hello" { -LL + println!("Hello world!"); -LL + } - | - -error: this `if` statement can be collapsed - --> tests/ui/collapsible_if.rs:39:5 - | -LL | / if x == "hello" && x == "world" { -LL | | if y == "world" && y == "hello" { -LL | | println!("Hello world!"); -LL | | } -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ if x == "hello" && x == "world" && y == "world" && y == "hello" { -LL + println!("Hello world!"); -LL + } - | - -error: this `if` statement can be collapsed - --> tests/ui/collapsible_if.rs:45:5 - | -LL | / if 42 == 1337 { -LL | | if 'a' != 'A' { -LL | | println!("world!") -LL | | } -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ if 42 == 1337 && 'a' != 'A' { -LL + println!("world!") -LL + } - | - -error: this `if` statement can be collapsed - --> tests/ui/collapsible_if.rs:101:5 - | -LL | / if x == "hello" { -LL | | if y == "world" { // Collapsible -LL | | println!("Hello world!"); -LL | | } -LL | | } - | |_____^ - | -help: collapse nested if block - | -LL ~ if x == "hello" && y == "world" { // Collapsible -LL + println!("Hello world!"); -LL + } - | - -error: this `if` statement can be collapsed - --> tests/ui/collapsible_if.rs:160:5 - | -LL | / if matches!(true, true) { -LL | | if matches!(true, true) {} -LL | | } - | |_____^ help: collapse nested if block: `if matches!(true, true) && matches!(true, true) {}` - -error: this `if` statement can be collapsed - --> tests/ui/collapsible_if.rs:165:5 - | -LL | / if matches!(true, true) && truth() { -LL | | if matches!(true, true) {} -LL | | } - | |_____^ help: collapse nested if block: `if matches!(true, true) && truth() && matches!(true, true) {}` - -error: aborting due to 9 previous errors - diff --git a/tests/ui/collapsible_match.rs b/tests/ui/collapsible_match.rs index 2264b560791a..14e3ab95dbd1 100644 --- a/tests/ui/collapsible_match.rs +++ b/tests/ui/collapsible_match.rs @@ -12,7 +12,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // match without block match res_opt { Ok(val) => match val { - //~^ ERROR: this `match` can be collapsed into the outer `match` + //~^ collapsible_match + Some(n) => foo(n), _ => return, }, @@ -22,7 +23,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // match with block match res_opt { Ok(val) => match val { - //~^ ERROR: this `match` can be collapsed into the outer `match` + //~^ collapsible_match + Some(n) => foo(n), _ => return, }, @@ -32,7 +34,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // if let, if let if let Ok(val) = res_opt { if let Some(n) = val { - //~^ ERROR: this `if let` can be collapsed into the outer `if let` + //~^ collapsible_match + take(n); } } @@ -40,7 +43,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // if let else, if let else if let Ok(val) = res_opt { if let Some(n) = val { - //~^ ERROR: this `if let` can be collapsed into the outer `if let` + //~^ collapsible_match + take(n); } else { return; @@ -52,7 +56,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // if let, match if let Ok(val) = res_opt { match val { - //~^ ERROR: this `match` can be collapsed into the outer `if let` + //~^ collapsible_match + Some(n) => foo(n), _ => (), } @@ -62,7 +67,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> match res_opt { Ok(val) => { if let Some(n) = val { - //~^ ERROR: this `if let` can be collapsed into the outer `match` + //~^ collapsible_match + take(n); } }, @@ -72,7 +78,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // if let else, match if let Ok(val) = res_opt { match val { - //~^ ERROR: this `match` can be collapsed into the outer `if let` + //~^ collapsible_match + Some(n) => foo(n), _ => return, } @@ -84,7 +91,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> match res_opt { Ok(val) => { if let Some(n) = val { - //~^ ERROR: this `if let` can be collapsed into the outer `match` + //~^ collapsible_match + take(n); } else { return; @@ -96,7 +104,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // None in inner match same as outer wild branch match res_opt { Ok(val) => match val { - //~^ ERROR: this `match` can be collapsed into the outer `match` + //~^ collapsible_match + Some(n) => foo(n), None => return, }, @@ -106,7 +115,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // None in outer match same as inner wild branch match opt_opt { Some(val) => match val { - //~^ ERROR: this `match` can be collapsed into the outer `match` + //~^ collapsible_match + Some(n) => foo(n), _ => return, }, @@ -250,6 +260,7 @@ fn negative_cases(res_opt: Result, String>, res_res: Result>>() { Some(val) => match val { + //~^ collapsible_match E::A(val) | E::B(val) => foo(val), _ => return, }, @@ -281,7 +292,8 @@ pub enum Issue9647 { pub fn test_1(x: Issue9647) { if let Issue9647::A { a, .. } = x { if let Some(u) = a { - //~^ ERROR: this `if let` can be collapsed into the outer `if let` + //~^ collapsible_match + println!("{u:?}") } } @@ -290,7 +302,8 @@ pub fn test_1(x: Issue9647) { pub fn test_2(x: Issue9647) { if let Issue9647::A { a: Some(a), .. } = x { if let Some(u) = a { - //~^ ERROR: this `if let` can be collapsed into the outer `if let` + //~^ collapsible_match + println!("{u}") } } diff --git a/tests/ui/collapsible_match.stderr b/tests/ui/collapsible_match.stderr index 1da78b56239c..471e58f27770 100644 --- a/tests/ui/collapsible_match.stderr +++ b/tests/ui/collapsible_match.stderr @@ -4,6 +4,7 @@ error: this `match` can be collapsed into the outer `match` LL | Ok(val) => match val { | ____________________^ LL | | +LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, @@ -14,43 +15,45 @@ help: the outer pattern can be modified to include the inner pattern | LL | Ok(val) => match val { | ^^^ replace this binding -LL | +... LL | Some(n) => foo(n), | ^^^^^^^ with this pattern = note: `-D clippy::collapsible-match` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]` error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:24:20 + --> tests/ui/collapsible_match.rs:25:20 | LL | Ok(val) => match val { | ____________________^ LL | | +LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:24:12 + --> tests/ui/collapsible_match.rs:25:12 | LL | Ok(val) => match val { | ^^^ replace this binding -LL | +... LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:34:9 + --> tests/ui/collapsible_match.rs:36:9 | LL | / if let Some(n) = val { LL | | +LL | | LL | | take(n); LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:33:15 + --> tests/ui/collapsible_match.rs:35:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -58,10 +61,11 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:42:9 + --> tests/ui/collapsible_match.rs:45:9 | LL | / if let Some(n) = val { LL | | +LL | | LL | | take(n); LL | | } else { LL | | return; @@ -69,7 +73,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:41:15 + --> tests/ui/collapsible_match.rs:44:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -77,17 +81,18 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:54:9 + --> tests/ui/collapsible_match.rs:58:9 | LL | / match val { LL | | +LL | | LL | | Some(n) => foo(n), LL | | _ => (), LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:53:15 + --> tests/ui/collapsible_match.rs:57:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -96,16 +101,17 @@ LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:64:13 + --> tests/ui/collapsible_match.rs:69:13 | LL | / if let Some(n) = val { LL | | +LL | | LL | | take(n); LL | | } | |_____________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:63:12 + --> tests/ui/collapsible_match.rs:68:12 | LL | Ok(val) => { | ^^^ replace this binding @@ -113,17 +119,18 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:74:9 + --> tests/ui/collapsible_match.rs:80:9 | LL | / match val { LL | | +LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:73:15 + --> tests/ui/collapsible_match.rs:79:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -132,10 +139,11 @@ LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:86:13 + --> tests/ui/collapsible_match.rs:93:13 | LL | / if let Some(n) = val { LL | | +LL | | LL | | take(n); LL | | } else { LL | | return; @@ -143,7 +151,7 @@ LL | | } | |_____________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:85:12 + --> tests/ui/collapsible_match.rs:92:12 | LL | Ok(val) => { | ^^^ replace this binding @@ -151,74 +159,79 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:98:20 + --> tests/ui/collapsible_match.rs:106:20 | LL | Ok(val) => match val { | ____________________^ LL | | +LL | | LL | | Some(n) => foo(n), LL | | None => return, LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:98:12 + --> tests/ui/collapsible_match.rs:106:12 | LL | Ok(val) => match val { | ^^^ replace this binding -LL | +... LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:108:22 + --> tests/ui/collapsible_match.rs:117:22 | LL | Some(val) => match val { | ______________________^ LL | | +LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:108:14 + --> tests/ui/collapsible_match.rs:117:14 | LL | Some(val) => match val { | ^^^ replace this binding -LL | +... LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:252:22 + --> tests/ui/collapsible_match.rs:262:22 | LL | Some(val) => match val { | ______________________^ +LL | | LL | | E::A(val) | E::B(val) => foo(val), LL | | _ => return, LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:252:14 + --> tests/ui/collapsible_match.rs:262:14 | LL | Some(val) => match val { | ^^^ replace this binding +LL | LL | E::A(val) | E::B(val) => foo(val), | ^^^^^^^^^^^^^^^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:283:9 + --> tests/ui/collapsible_match.rs:294:9 | LL | / if let Some(u) = a { LL | | +LL | | LL | | println!("{u:?}") LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:282:27 + --> tests/ui/collapsible_match.rs:293:27 | LL | if let Issue9647::A { a, .. } = x { | ^ replace this binding @@ -226,16 +239,17 @@ LL | if let Some(u) = a { | ^^^^^^^ with this pattern, prefixed by `a`: error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:292:9 + --> tests/ui/collapsible_match.rs:304:9 | LL | / if let Some(u) = a { LL | | +LL | | LL | | println!("{u}") LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:291:35 + --> tests/ui/collapsible_match.rs:303:35 | LL | if let Issue9647::A { a: Some(a), .. } = x { | ^ replace this binding diff --git a/tests/ui/collapsible_match2.rs b/tests/ui/collapsible_match2.rs index 56801f99e454..1831fc3f0e35 100644 --- a/tests/ui/collapsible_match2.rs +++ b/tests/ui/collapsible_match2.rs @@ -11,7 +11,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> { match res_opt { Ok(val) if make() => match val { - //~^ ERROR: this `match` can be collapsed into the outer `match` + //~^ collapsible_match + Some(n) => foo(n), _ => return, }, @@ -19,7 +20,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> } match res_opt { Ok(val) => match val { - //~^ ERROR: this `match` can be collapsed into the outer `match` + //~^ collapsible_match + Some(n) => foo(n), _ => return, }, @@ -34,6 +36,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> ($outer:expr => $pat:pat, $e:expr => $inner_pat:pat, $then:expr) => { match $outer { $pat => match $e { + //~^ collapsible_match $inner_pat => $then, _ => return, }, @@ -51,7 +54,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // deref reference value match Some(&[1]) { Some(s) => match *s { - //~^ ERROR: this `match` can be collapsed into the outer `match` + //~^ collapsible_match + [n] => foo(n), _ => (), }, @@ -61,7 +65,8 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // ref pattern and deref match Some(&[1]) { Some(ref s) => match s { - //~^ ERROR: this `match` can be collapsed into the outer `match` + //~^ collapsible_match + [n] => foo(n), _ => (), }, diff --git a/tests/ui/collapsible_match2.stderr b/tests/ui/collapsible_match2.stderr index 13caa78fbeb5..322c583fda77 100644 --- a/tests/ui/collapsible_match2.stderr +++ b/tests/ui/collapsible_match2.stderr @@ -4,6 +4,7 @@ error: this `match` can be collapsed into the outer `match` LL | Ok(val) if make() => match val { | __________________________________^ LL | | +LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, @@ -14,37 +15,39 @@ help: the outer pattern can be modified to include the inner pattern | LL | Ok(val) if make() => match val { | ^^^ replace this binding -LL | +... LL | Some(n) => foo(n), | ^^^^^^^ with this pattern = note: `-D clippy::collapsible-match` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]` error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match2.rs:21:24 + --> tests/ui/collapsible_match2.rs:22:24 | LL | Ok(val) => match val { | ________________________^ LL | | +LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, | |_____________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match2.rs:21:16 + --> tests/ui/collapsible_match2.rs:22:16 | LL | Ok(val) => match val { | ^^^ replace this binding -LL | +... LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match2.rs:36:29 + --> tests/ui/collapsible_match2.rs:38:29 | LL | $pat => match $e { | _____________________________^ +LL | | LL | | $inner_pat => $then, LL | | _ => return, LL | | }, @@ -54,7 +57,7 @@ LL | mac!(res_opt => Ok(val), val => Some(n), foo(n)); | ------------------------------------------------ in this macro invocation | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match2.rs:48:28 + --> tests/ui/collapsible_match2.rs:51:28 | LL | mac!(res_opt => Ok(val), val => Some(n), foo(n)); | ^^^ ^^^^^^^ with this pattern @@ -63,30 +66,11 @@ LL | mac!(res_opt => Ok(val), val => Some(n), foo(n)); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match2.rs:53:20 + --> tests/ui/collapsible_match2.rs:56:20 | LL | Some(s) => match *s { | ____________________^ LL | | -LL | | [n] => foo(n), -LL | | _ => (), -LL | | }, - | |_________^ - | -help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match2.rs:53:14 - | -LL | Some(s) => match *s { - | ^ replace this binding -LL | -LL | [n] => foo(n), - | ^^^ with this pattern - -error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match2.rs:63:24 - | -LL | Some(ref s) => match s { - | ________________________^ LL | | LL | | [n] => foo(n), LL | | _ => (), @@ -94,11 +78,32 @@ LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match2.rs:63:14 + --> tests/ui/collapsible_match2.rs:56:14 + | +LL | Some(s) => match *s { + | ^ replace this binding +... +LL | [n] => foo(n), + | ^^^ with this pattern + +error: this `match` can be collapsed into the outer `match` + --> tests/ui/collapsible_match2.rs:67:24 + | +LL | Some(ref s) => match s { + | ________________________^ +LL | | +LL | | +LL | | [n] => foo(n), +LL | | _ => (), +LL | | }, + | |_________^ + | +help: the outer pattern can be modified to include the inner pattern + --> tests/ui/collapsible_match2.rs:67:14 | LL | Some(ref s) => match s { | ^^^^^ replace this binding -LL | +... LL | [n] => foo(n), | ^^^ with this pattern diff --git a/tests/ui/collapsible_str_replace.fixed b/tests/ui/collapsible_str_replace.fixed index 03b393d5a674..e9a7384b761b 100644 --- a/tests/ui/collapsible_str_replace.fixed +++ b/tests/ui/collapsible_str_replace.fixed @@ -16,32 +16,44 @@ fn main() { // LINT CASES let _ = "hesuo worpd".replace(['s', 'u'], "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace(['s', 'u'], l); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace(['s', 'u', 'p'], "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd" .replace(['s', 'u', 'p', 'd'], "l"); let _ = "hesuo world".replace([s, 'u'], "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace([s, 'u', 'p'], "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace([s, u, 'p'], "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace([s, u, p], "l"); + //~^ collapsible_str_replace let _ = "hesuo worlp".replace(['s', 'u'], "l").replace('p', "d"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace('s', "x").replace(['u', 'p'], "l"); + //~^ collapsible_str_replace // Note: Future iterations could lint `replace(|c| matches!(c, "su" | 'd' | 'p'), "l")` let _ = "hesudo worpd".replace("su", "l").replace(['d', 'p'], "l"); + //~^ collapsible_str_replace let _ = "hesudo worpd".replace([d, 'p'], "l").replace("su", "l"); + //~^ collapsible_str_replace let _ = "hesuo world".replace([get_filter(), 's'], "l"); + //~^ collapsible_str_replace // NO LINT CASES let _ = "hesuo world".replace('s', "l").replace('u', "p"); @@ -79,4 +91,5 @@ fn msrv_1_57() { #[clippy::msrv = "1.58"] fn msrv_1_58() { let _ = "".replace(['a', 'b'], "1.58"); + //~^ collapsible_str_replace } diff --git a/tests/ui/collapsible_str_replace.rs b/tests/ui/collapsible_str_replace.rs index 364e5493b872..4dc12c1b1c6e 100644 --- a/tests/ui/collapsible_str_replace.rs +++ b/tests/ui/collapsible_str_replace.rs @@ -16,35 +16,48 @@ fn main() { // LINT CASES let _ = "hesuo worpd".replace('s', "l").replace('u', "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace('s', l).replace('u', l); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace('s', "l").replace('u', "l").replace('p', "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd" .replace('s', "l") + //~^ collapsible_str_replace .replace('u', "l") .replace('p', "l") .replace('d', "l"); let _ = "hesuo world".replace(s, "l").replace('u', "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace(s, "l").replace('u', "l").replace('p', "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace('p', "l"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace(p, "l"); + //~^ collapsible_str_replace let _ = "hesuo worlp".replace('s', "l").replace('u', "l").replace('p', "d"); + //~^ collapsible_str_replace let _ = "hesuo worpd".replace('s', "x").replace('u', "l").replace('p', "l"); + //~^ collapsible_str_replace // Note: Future iterations could lint `replace(|c| matches!(c, "su" | 'd' | 'p'), "l")` let _ = "hesudo worpd".replace("su", "l").replace('d', "l").replace('p', "l"); + //~^ collapsible_str_replace let _ = "hesudo worpd".replace(d, "l").replace('p', "l").replace("su", "l"); + //~^ collapsible_str_replace let _ = "hesuo world".replace(get_filter(), "l").replace('s', "l"); + //~^ collapsible_str_replace // NO LINT CASES let _ = "hesuo world".replace('s', "l").replace('u', "p"); @@ -82,4 +95,5 @@ fn msrv_1_57() { #[clippy::msrv = "1.58"] fn msrv_1_58() { let _ = "".replace('a', "1.58").replace('b', "1.58"); + //~^ collapsible_str_replace } diff --git a/tests/ui/collapsible_str_replace.stderr b/tests/ui/collapsible_str_replace.stderr index da681dffd875..a634b857dd46 100644 --- a/tests/ui/collapsible_str_replace.stderr +++ b/tests/ui/collapsible_str_replace.stderr @@ -8,83 +8,84 @@ LL | let _ = "hesuo worpd".replace('s', "l").replace('u', "l"); = help: to override `-D warnings` add `#[allow(clippy::collapsible_str_replace)]` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:20:27 + --> tests/ui/collapsible_str_replace.rs:21:27 | LL | let _ = "hesuo worpd".replace('s', l).replace('u', l); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], l)` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:22:27 + --> tests/ui/collapsible_str_replace.rs:24:27 | LL | let _ = "hesuo worpd".replace('s', "l").replace('u', "l").replace('p', "l"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u', 'p'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:25:10 + --> tests/ui/collapsible_str_replace.rs:28:10 | LL | .replace('s', "l") | __________^ +LL | | LL | | .replace('u', "l") LL | | .replace('p', "l") LL | | .replace('d', "l"); | |__________________________^ help: replace with: `replace(['s', 'u', 'p', 'd'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:30:27 + --> tests/ui/collapsible_str_replace.rs:34:27 | LL | let _ = "hesuo world".replace(s, "l").replace('u', "l"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:32:27 + --> tests/ui/collapsible_str_replace.rs:37:27 | LL | let _ = "hesuo worpd".replace(s, "l").replace('u', "l").replace('p', "l"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u', 'p'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:34:27 + --> tests/ui/collapsible_str_replace.rs:40:27 | LL | let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace('p', "l"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, 'p'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:36:27 + --> tests/ui/collapsible_str_replace.rs:43:27 | LL | let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace(p, "l"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, p], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:38:27 + --> tests/ui/collapsible_str_replace.rs:46:27 | LL | let _ = "hesuo worlp".replace('s', "l").replace('u', "l").replace('p', "d"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:40:45 + --> tests/ui/collapsible_str_replace.rs:49:45 | LL | let _ = "hesuo worpd".replace('s', "x").replace('u', "l").replace('p', "l"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['u', 'p'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:43:47 + --> tests/ui/collapsible_str_replace.rs:53:47 | LL | let _ = "hesudo worpd".replace("su", "l").replace('d', "l").replace('p', "l"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['d', 'p'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:45:28 + --> tests/ui/collapsible_str_replace.rs:56:28 | LL | let _ = "hesudo worpd".replace(d, "l").replace('p', "l").replace("su", "l"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([d, 'p'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:47:27 + --> tests/ui/collapsible_str_replace.rs:59:27 | LL | let _ = "hesuo world".replace(get_filter(), "l").replace('s', "l"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([get_filter(), 's'], "l")` error: used consecutive `str::replace` call - --> tests/ui/collapsible_str_replace.rs:84:16 + --> tests/ui/collapsible_str_replace.rs:97:16 | LL | let _ = "".replace('a', "1.58").replace('b', "1.58"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['a', 'b'], "1.58")` diff --git a/tests/ui/collection_is_never_read.rs b/tests/ui/collection_is_never_read.rs index eeb10da3402a..406b5f8f9f69 100644 --- a/tests/ui/collection_is_never_read.rs +++ b/tests/ui/collection_is_never_read.rs @@ -19,8 +19,9 @@ fn no_access_at_all() { fn write_without_read() { // The main use case for `collection_is_never_read`. let mut x = HashMap::new(); - //~^ ERROR: collection is never read - //~| NOTE: `-D clippy::collection-is-never-read` implied by `-D warnings` + //~^ collection_is_never_read + + x.insert(1, 2); } @@ -60,7 +61,8 @@ fn read_in_closure() { fn write_in_closure() { let mut x = vec![1, 2, 3]; - //~^ ERROR: collection is never read + //~^ collection_is_never_read + let _ = || { x.push(4); }; @@ -76,13 +78,15 @@ fn shadowing_1() { let x = HashMap::::new(); // Ok let _ = x.len(); let mut x = HashMap::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.insert(1, 2); } fn shadowing_2() { let mut x = HashMap::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.insert(1, 2); let x = HashMap::::new(); // Ok let _ = x.len(); @@ -91,21 +95,24 @@ fn shadowing_2() { #[allow(clippy::let_unit_value)] fn fake_read_1() { let mut x = vec![1, 2, 3]; - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.reverse(); let _: () = x.clear(); } fn fake_read_2() { let mut x = vec![1, 2, 3]; - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.reverse(); println!("{:?}", x.push(5)); } fn assignment() { let mut x = vec![1, 2, 3]; - //~^ ERROR: collection is never read + //~^ collection_is_never_read + let y = vec![4, 5, 6]; // Ok x = y; } @@ -113,7 +120,8 @@ fn assignment() { #[allow(clippy::self_assignment)] fn self_assignment() { let mut x = vec![1, 2, 3]; - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x = x; } @@ -131,7 +139,8 @@ fn method_argument_but_not_target() { fn insert_is_not_a_read() { let mut x = HashSet::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.insert(5); } @@ -146,7 +155,8 @@ fn not_read_if_return_value_not_used() { // `is_empty` does not modify the set, so it's a query. But since the return value is not used, the // lint does not consider it a read here. let x = vec![1, 2, 3]; - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.is_empty(); } @@ -182,44 +192,54 @@ fn function_argument() { fn supported_types() { let mut x = std::collections::BTreeMap::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.insert(true, 1); let mut x = std::collections::BTreeSet::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.insert(1); let mut x = std::collections::BinaryHeap::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.push(1); let mut x = std::collections::HashMap::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.insert(1, 2); let mut x = std::collections::HashSet::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.insert(1); let mut x = std::collections::LinkedList::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.push_front(1); let mut x = Some(true); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.insert(false); let mut x = String::from("hello"); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.push('!'); let mut x = Vec::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.clear(); x.push(1); let mut x = std::collections::VecDeque::new(); - //~^ ERROR: collection is never read + //~^ collection_is_never_read + x.push_front(1); } diff --git a/tests/ui/collection_is_never_read.stderr b/tests/ui/collection_is_never_read.stderr index f91ce07483c3..674552629f7d 100644 --- a/tests/ui/collection_is_never_read.stderr +++ b/tests/ui/collection_is_never_read.stderr @@ -8,115 +8,115 @@ LL | let mut x = HashMap::new(); = help: to override `-D warnings` add `#[allow(clippy::collection_is_never_read)]` error: collection is never read - --> tests/ui/collection_is_never_read.rs:62:5 + --> tests/ui/collection_is_never_read.rs:63:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:78:5 + --> tests/ui/collection_is_never_read.rs:80:5 | LL | let mut x = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:84:5 + --> tests/ui/collection_is_never_read.rs:87:5 | LL | let mut x = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:93:5 + --> tests/ui/collection_is_never_read.rs:97:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:100:5 + --> tests/ui/collection_is_never_read.rs:105:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:107:5 + --> tests/ui/collection_is_never_read.rs:113:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:115:5 + --> tests/ui/collection_is_never_read.rs:122:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:133:5 + --> tests/ui/collection_is_never_read.rs:141:5 | LL | let mut x = HashSet::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:148:5 + --> tests/ui/collection_is_never_read.rs:157:5 | LL | let x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:184:5 + --> tests/ui/collection_is_never_read.rs:194:5 | LL | let mut x = std::collections::BTreeMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:188:5 + --> tests/ui/collection_is_never_read.rs:199:5 | LL | let mut x = std::collections::BTreeSet::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:192:5 + --> tests/ui/collection_is_never_read.rs:204:5 | LL | let mut x = std::collections::BinaryHeap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:196:5 + --> tests/ui/collection_is_never_read.rs:209:5 | LL | let mut x = std::collections::HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:200:5 + --> tests/ui/collection_is_never_read.rs:214:5 | LL | let mut x = std::collections::HashSet::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:204:5 + --> tests/ui/collection_is_never_read.rs:219:5 | LL | let mut x = std::collections::LinkedList::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:208:5 + --> tests/ui/collection_is_never_read.rs:224:5 | LL | let mut x = Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:212:5 + --> tests/ui/collection_is_never_read.rs:229:5 | LL | let mut x = String::from("hello"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:216:5 + --> tests/ui/collection_is_never_read.rs:234:5 | LL | let mut x = Vec::new(); | ^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:221:5 + --> tests/ui/collection_is_never_read.rs:240:5 | LL | let mut x = std::collections::VecDeque::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/comparison_chain.rs b/tests/ui/comparison_chain.rs index cab460d100dd..418c88b7d5a3 100644 --- a/tests/ui/comparison_chain.rs +++ b/tests/ui/comparison_chain.rs @@ -13,7 +13,8 @@ fn f(x: u8, y: u8, z: u8) { } if x > y { - //~^ ERROR: `if` chain can be rewritten with `match` + //~^ comparison_chain + a() } else if x < y { b() @@ -27,7 +28,8 @@ fn f(x: u8, y: u8, z: u8) { } if x > y { - //~^ ERROR: `if` chain can be rewritten with `match` + //~^ comparison_chain + a() } else if x < y { b() @@ -36,7 +38,8 @@ fn f(x: u8, y: u8, z: u8) { } if x > y { - //~^ ERROR: `if` chain can be rewritten with `match` + //~^ comparison_chain + a() } else if y > x { b() @@ -45,7 +48,8 @@ fn f(x: u8, y: u8, z: u8) { } if x > 1 { - //~^ ERROR: `if` chain can be rewritten with `match` + //~^ comparison_chain + a() } else if x < 1 { b() @@ -120,14 +124,16 @@ fn g(x: f64, y: f64, z: f64) { fn h(x: T, y: T, z: T) { if x > y { - //~^ ERROR: `if` chain can be rewritten with `match` + //~^ comparison_chain + a() } else if x < y { b() } if x > y { - //~^ ERROR: `if` chain can be rewritten with `match` + //~^ comparison_chain + a() } else if x < y { b() @@ -136,7 +142,8 @@ fn h(x: T, y: T, z: T) { } if x > y { - //~^ ERROR: `if` chain can be rewritten with `match` + //~^ comparison_chain + a() } else if y > x { b() @@ -242,7 +249,8 @@ const fn sign_i8(n: i8) -> Sign { fn needs_parens() -> &'static str { let (x, y) = (1, 2); if x + 1 > y * 2 { - //~^ ERROR: `if` chain can be rewritten with `match` + //~^ comparison_chain + "aa" } else if x + 1 < y * 2 { "bb" diff --git a/tests/ui/comparison_chain.stderr b/tests/ui/comparison_chain.stderr index 814004e3d4b1..0256573d0d90 100644 --- a/tests/ui/comparison_chain.stderr +++ b/tests/ui/comparison_chain.stderr @@ -3,6 +3,7 @@ error: `if` chain can be rewritten with `match` | LL | / if x > y { LL | | +LL | | LL | | a() LL | | } else if x < y { LL | | b() @@ -13,46 +14,47 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::comparison_chain)]` error: `if` chain can be rewritten with `match` - --> tests/ui/comparison_chain.rs:29:5 + --> tests/ui/comparison_chain.rs:30:5 | LL | / if x > y { LL | | +LL | | LL | | a() -LL | | } else if x < y { ... | LL | | c() LL | | } | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}` error: `if` chain can be rewritten with `match` - --> tests/ui/comparison_chain.rs:38:5 + --> tests/ui/comparison_chain.rs:40:5 | LL | / if x > y { LL | | +LL | | LL | | a() -LL | | } else if y > x { ... | LL | | c() LL | | } | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}` error: `if` chain can be rewritten with `match` - --> tests/ui/comparison_chain.rs:47:5 + --> tests/ui/comparison_chain.rs:50:5 | LL | / if x > 1 { LL | | +LL | | LL | | a() -LL | | } else if x < 1 { ... | LL | | c() LL | | } | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&1) {...}` error: `if` chain can be rewritten with `match` - --> tests/ui/comparison_chain.rs:122:5 + --> tests/ui/comparison_chain.rs:126:5 | LL | / if x > y { LL | | +LL | | LL | | a() LL | | } else if x < y { LL | | b() @@ -60,36 +62,36 @@ LL | | } | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}` error: `if` chain can be rewritten with `match` - --> tests/ui/comparison_chain.rs:129:5 + --> tests/ui/comparison_chain.rs:134:5 | LL | / if x > y { LL | | +LL | | LL | | a() -LL | | } else if x < y { ... | LL | | c() LL | | } | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}` error: `if` chain can be rewritten with `match` - --> tests/ui/comparison_chain.rs:138:5 + --> tests/ui/comparison_chain.rs:144:5 | LL | / if x > y { LL | | +LL | | LL | | a() -LL | | } else if y > x { ... | LL | | c() LL | | } | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}` error: `if` chain can be rewritten with `match` - --> tests/ui/comparison_chain.rs:244:5 + --> tests/ui/comparison_chain.rs:251:5 | LL | / if x + 1 > y * 2 { LL | | +LL | | LL | | "aa" -LL | | } else if x + 1 < y * 2 { ... | LL | | "cc" LL | | } diff --git a/tests/ui/comparison_to_empty.fixed b/tests/ui/comparison_to_empty.fixed index a2a3dd9086d4..205abe31cd86 100644 --- a/tests/ui/comparison_to_empty.fixed +++ b/tests/ui/comparison_to_empty.fixed @@ -6,17 +6,26 @@ fn main() { // Disallow comparisons to empty let s = String::new(); let _ = s.is_empty(); + //~^ comparison_to_empty let _ = !s.is_empty(); + //~^ comparison_to_empty let v = vec![0]; let _ = v.is_empty(); + //~^ comparison_to_empty let _ = !v.is_empty(); + //~^ comparison_to_empty if (*v).is_empty() {} + //~^ comparison_to_empty let s = [0].as_slice(); if s.is_empty() {} + //~^ comparison_to_empty if s.is_empty() {} + //~^ comparison_to_empty if s.is_empty() + //~^ comparison_to_empty && s.is_empty() + //~^ comparison_to_empty {} // Allow comparisons to non-empty @@ -37,8 +46,12 @@ fn main() { // Also lint the `PartialEq` methods let s = String::new(); let _ = s.is_empty(); + //~^ comparison_to_empty let _ = !s.is_empty(); + //~^ comparison_to_empty let v = vec![0]; let _ = v.is_empty(); + //~^ comparison_to_empty let _ = !v.is_empty(); + //~^ comparison_to_empty } diff --git a/tests/ui/comparison_to_empty.rs b/tests/ui/comparison_to_empty.rs index 7c5689a4bbec..4da6327050a8 100644 --- a/tests/ui/comparison_to_empty.rs +++ b/tests/ui/comparison_to_empty.rs @@ -6,17 +6,26 @@ fn main() { // Disallow comparisons to empty let s = String::new(); let _ = s == ""; + //~^ comparison_to_empty let _ = s != ""; + //~^ comparison_to_empty let v = vec![0]; let _ = v == []; + //~^ comparison_to_empty let _ = v != []; + //~^ comparison_to_empty if let [] = &*v {} + //~^ comparison_to_empty let s = [0].as_slice(); if let [] = s {} + //~^ comparison_to_empty if let [] = &*s {} + //~^ comparison_to_empty if let [] = &*s + //~^ comparison_to_empty && s == [] + //~^ comparison_to_empty {} // Allow comparisons to non-empty @@ -37,8 +46,12 @@ fn main() { // Also lint the `PartialEq` methods let s = String::new(); let _ = s.eq(""); + //~^ comparison_to_empty let _ = s.ne(""); + //~^ comparison_to_empty let v = vec![0]; let _ = v.eq(&[]); + //~^ comparison_to_empty let _ = v.ne(&[]); + //~^ comparison_to_empty } diff --git a/tests/ui/comparison_to_empty.stderr b/tests/ui/comparison_to_empty.stderr index 2ee0efc7dbb1..00a50430a3ee 100644 --- a/tests/ui/comparison_to_empty.stderr +++ b/tests/ui/comparison_to_empty.stderr @@ -8,73 +8,73 @@ LL | let _ = s == ""; = help: to override `-D warnings` add `#[allow(clippy::comparison_to_empty)]` error: comparison to empty slice - --> tests/ui/comparison_to_empty.rs:9:13 + --> tests/ui/comparison_to_empty.rs:10:13 | LL | let _ = s != ""; | ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!s.is_empty()` error: comparison to empty slice - --> tests/ui/comparison_to_empty.rs:12:13 + --> tests/ui/comparison_to_empty.rs:14:13 | LL | let _ = v == []; | ^^^^^^^ help: using `is_empty` is clearer and more explicit: `v.is_empty()` error: comparison to empty slice - --> tests/ui/comparison_to_empty.rs:13:13 + --> tests/ui/comparison_to_empty.rs:16:13 | LL | let _ = v != []; | ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!v.is_empty()` error: comparison to empty slice using `if let` - --> tests/ui/comparison_to_empty.rs:14:8 + --> tests/ui/comparison_to_empty.rs:18:8 | LL | if let [] = &*v {} | ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(*v).is_empty()` error: comparison to empty slice using `if let` - --> tests/ui/comparison_to_empty.rs:16:8 + --> tests/ui/comparison_to_empty.rs:21:8 | LL | if let [] = s {} | ^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` error: comparison to empty slice using `if let` - --> tests/ui/comparison_to_empty.rs:17:8 + --> tests/ui/comparison_to_empty.rs:23:8 | LL | if let [] = &*s {} | ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` error: comparison to empty slice using `if let` - --> tests/ui/comparison_to_empty.rs:18:8 + --> tests/ui/comparison_to_empty.rs:25:8 | LL | if let [] = &*s | ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` error: comparison to empty slice - --> tests/ui/comparison_to_empty.rs:19:12 + --> tests/ui/comparison_to_empty.rs:27:12 | LL | && s == [] | ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` error: comparison to empty slice - --> tests/ui/comparison_to_empty.rs:39:13 + --> tests/ui/comparison_to_empty.rs:48:13 | LL | let _ = s.eq(""); | ^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` error: comparison to empty slice - --> tests/ui/comparison_to_empty.rs:40:13 + --> tests/ui/comparison_to_empty.rs:50:13 | LL | let _ = s.ne(""); | ^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!s.is_empty()` error: comparison to empty slice - --> tests/ui/comparison_to_empty.rs:42:13 + --> tests/ui/comparison_to_empty.rs:53:13 | LL | let _ = v.eq(&[]); | ^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `v.is_empty()` error: comparison to empty slice - --> tests/ui/comparison_to_empty.rs:43:13 + --> tests/ui/comparison_to_empty.rs:55:13 | LL | let _ = v.ne(&[]); | ^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!v.is_empty()` diff --git a/tests/ui/const_comparisons.rs b/tests/ui/const_comparisons.rs index 0898b4ebd465..0df4b8eb356e 100644 --- a/tests/ui/const_comparisons.rs +++ b/tests/ui/const_comparisons.rs @@ -43,42 +43,53 @@ fn main() { // Correct status_code >= 400 && status_code < 500; status_code <= 400 && status_code > 500; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `400` < `500`, the expression evaluates to false for any value of `st + //~^ impossible_comparisons + + status_code > 500 && status_code < 400; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `500` > `400`, the expression evaluates to false for any value of `st + //~^ impossible_comparisons + + status_code < 500 && status_code > 500; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: `status_code` cannot simultaneously be greater than and less than `500` + //~^ impossible_comparisons + + // More complex expressions status_code < { 400 } && status_code > { 500 }; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any valu + //~^ impossible_comparisons + + status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluate + //~^ impossible_comparisons + + status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to f + //~^ impossible_comparisons + + status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: `status_code` cannot simultaneously be greater than and less than `STATUS_S + //~^ impossible_comparisons + + // Comparing two different types, via the `impl PartialOrd for Status` status < { 400 } && status > { 500 }; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any valu + //~^ impossible_comparisons + + status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluate + //~^ impossible_comparisons + + status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to f + //~^ impossible_comparisons + + status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: `status` cannot simultaneously be greater than and less than `STATUS_SERVER + //~^ impossible_comparisons + + // Yoda conditions // Correct @@ -87,12 +98,14 @@ fn main() { 500 <= status_code && status_code <= 600; // Incorrect 500 >= status_code && 600 < status_code; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `500` < `600`, the expression evaluates to false for any value of `st + //~^ impossible_comparisons + + // Incorrect 500 >= status_code && status_code > 600; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `500` < `600`, the expression evaluates to false for any value of `st + //~^ impossible_comparisons + + // Yoda conditions, comparing two different types // Correct @@ -101,50 +114,62 @@ fn main() { 500 <= status && status <= 600; // Incorrect 500 >= status && 600 < status; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `500` < `600`, the expression evaluates to false for any value of `st + //~^ impossible_comparisons + + // Incorrect 500 >= status && status > 600; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `500` < `600`, the expression evaluates to false for any value of `st + //~^ impossible_comparisons + + // Expressions where one of the sides has no effect status_code < 200 && status_code <= 299; - //~^ ERROR: right-hand side of `&&` operator has no effect + //~^ redundant_comparisons + status_code > 200 && status_code >= 299; - //~^ ERROR: left-hand side of `&&` operator has no effect + //~^ redundant_comparisons + // Useless left status_code >= 500 && status_code > 500; - //~^ ERROR: left-hand side of `&&` operator has no effect + //~^ redundant_comparisons + // Useless right status_code > 500 && status_code >= 500; - //~^ ERROR: right-hand side of `&&` operator has no effect + //~^ redundant_comparisons + // Useless left status_code <= 500 && status_code < 500; - //~^ ERROR: left-hand side of `&&` operator has no effect + //~^ redundant_comparisons + // Useless right status_code < 500 && status_code <= 500; - //~^ ERROR: right-hand side of `&&` operator has no effect + //~^ redundant_comparisons + // Other types let name = "Steve"; name < "Jennifer" && name > "Shannon"; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `"Jennifer"` < `"Shannon"`, the expression evaluates to false for any + //~^ impossible_comparisons + + let numbers = [1, 2]; numbers < [3, 4] && numbers > [5, 6]; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `[3, 4]` < `[5, 6]`, the expression evaluates to false for any value + //~^ impossible_comparisons + + let letter = 'a'; letter < 'b' && letter > 'c'; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `'b'` < `'c'`, the expression evaluates to false for any value of `le + //~^ impossible_comparisons + + let area = 42.0; area < std::f32::consts::E && area > std::f32::consts::PI; - //~^ ERROR: boolean expression will never evaluate to 'true' - //~| NOTE: since `std::f32::consts::E` < `std::f32::consts::PI`, the expression evalua + //~^ impossible_comparisons + + } diff --git a/tests/ui/const_comparisons.stderr b/tests/ui/const_comparisons.stderr index 1b8fd9733fae..2f3f5c9523e3 100644 --- a/tests/ui/const_comparisons.stderr +++ b/tests/ui/const_comparisons.stderr @@ -9,7 +9,7 @@ LL | status_code <= 400 && status_code > 500; = help: to override `-D warnings` add `#[allow(clippy::impossible_comparisons)]` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:48:5 + --> tests/ui/const_comparisons.rs:49:5 | LL | status_code > 500 && status_code < 400; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | status_code > 500 && status_code < 400; = note: since `500` > `400`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:51:5 + --> tests/ui/const_comparisons.rs:53:5 | LL | status_code < 500 && status_code > 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | status_code < 500 && status_code > 500; = note: `status_code` cannot simultaneously be greater than and less than `500` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:56:5 + --> tests/ui/const_comparisons.rs:59:5 | LL | status_code < { 400 } && status_code > { 500 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | status_code < { 400 } && status_code > { 500 }; = note: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:59:5 + --> tests/ui/const_comparisons.rs:63:5 | LL | status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR; = note: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:62:5 + --> tests/ui/const_comparisons.rs:67:5 | LL | status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR; = note: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:65:5 + --> tests/ui/const_comparisons.rs:71:5 | LL | status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR; = note: `status_code` cannot simultaneously be greater than and less than `STATUS_SERVER_ERROR` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:70:5 + --> tests/ui/const_comparisons.rs:77:5 | LL | status < { 400 } && status > { 500 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | status < { 400 } && status > { 500 }; = note: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any value of `status` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:73:5 + --> tests/ui/const_comparisons.rs:81:5 | LL | status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR; = note: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:76:5 + --> tests/ui/const_comparisons.rs:85:5 | LL | status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR; = note: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:79:5 + --> tests/ui/const_comparisons.rs:89:5 | LL | status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR; = note: `status` cannot simultaneously be greater than and less than `STATUS_SERVER_ERROR` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:89:5 + --> tests/ui/const_comparisons.rs:100:5 | LL | 500 >= status_code && 600 < status_code; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | 500 >= status_code && 600 < status_code; = note: since `500` < `600`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:93:5 + --> tests/ui/const_comparisons.rs:105:5 | LL | 500 >= status_code && status_code > 600; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | 500 >= status_code && status_code > 600; = note: since `500` < `600`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:103:5 + --> tests/ui/const_comparisons.rs:116:5 | LL | 500 >= status && 600 < status; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | 500 >= status && 600 < status; = note: since `500` < `600`, the expression evaluates to false for any value of `status` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:107:5 + --> tests/ui/const_comparisons.rs:121:5 | LL | 500 >= status && status > 600; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,13 +121,13 @@ LL | 500 >= status && status > 600; = note: since `500` < `600`, the expression evaluates to false for any value of `status` error: right-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:112:5 + --> tests/ui/const_comparisons.rs:127:5 | LL | status_code < 200 && status_code <= 299; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code < 200` evaluates to true, status_code <= 299` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:112:23 + --> tests/ui/const_comparisons.rs:127:23 | LL | status_code < 200 && status_code <= 299; | ^^^^^^^^^^^^^^^^^^^^^ @@ -135,67 +135,67 @@ LL | status_code < 200 && status_code <= 299; = help: to override `-D warnings` add `#[allow(clippy::redundant_comparisons)]` error: left-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:114:5 + --> tests/ui/const_comparisons.rs:130:5 | LL | status_code > 200 && status_code >= 299; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code >= 299` evaluates to true, status_code > 200` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:114:5 + --> tests/ui/const_comparisons.rs:130:5 | LL | status_code > 200 && status_code >= 299; | ^^^^^^^^^^^^^^^^^^^^^ error: left-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:118:5 + --> tests/ui/const_comparisons.rs:135:5 | LL | status_code >= 500 && status_code > 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code > 500` evaluates to true, status_code >= 500` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:118:5 + --> tests/ui/const_comparisons.rs:135:5 | LL | status_code >= 500 && status_code > 500; | ^^^^^^^^^^^^^^^^^^^^^^ error: right-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:121:5 + --> tests/ui/const_comparisons.rs:139:5 | LL | status_code > 500 && status_code >= 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code > 500` evaluates to true, status_code >= 500` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:121:23 + --> tests/ui/const_comparisons.rs:139:23 | LL | status_code > 500 && status_code >= 500; | ^^^^^^^^^^^^^^^^^^^^^ error: left-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:124:5 + --> tests/ui/const_comparisons.rs:143:5 | LL | status_code <= 500 && status_code < 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code < 500` evaluates to true, status_code <= 500` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:124:5 + --> tests/ui/const_comparisons.rs:143:5 | LL | status_code <= 500 && status_code < 500; | ^^^^^^^^^^^^^^^^^^^^^^ error: right-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:127:5 + --> tests/ui/const_comparisons.rs:147:5 | LL | status_code < 500 && status_code <= 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code < 500` evaluates to true, status_code <= 500` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:127:23 + --> tests/ui/const_comparisons.rs:147:23 | LL | status_code < 500 && status_code <= 500; | ^^^^^^^^^^^^^^^^^^^^^ error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:132:5 + --> tests/ui/const_comparisons.rs:153:5 | LL | name < "Jennifer" && name > "Shannon"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -203,7 +203,7 @@ LL | name < "Jennifer" && name > "Shannon"; = note: since `"Jennifer"` < `"Shannon"`, the expression evaluates to false for any value of `name` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:137:5 + --> tests/ui/const_comparisons.rs:159:5 | LL | numbers < [3, 4] && numbers > [5, 6]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +211,7 @@ LL | numbers < [3, 4] && numbers > [5, 6]; = note: since `[3, 4]` < `[5, 6]`, the expression evaluates to false for any value of `numbers` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:142:5 + --> tests/ui/const_comparisons.rs:165:5 | LL | letter < 'b' && letter > 'c'; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ LL | letter < 'b' && letter > 'c'; = note: since `'b'` < `'c'`, the expression evaluates to false for any value of `letter` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:147:5 + --> tests/ui/const_comparisons.rs:171:5 | LL | area < std::f32::consts::E && area > std::f32::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const_is_empty.rs b/tests/ui/const_is_empty.rs index b5e27b61548a..29891ae4c0e5 100644 --- a/tests/ui/const_is_empty.rs +++ b/tests/ui/const_is_empty.rs @@ -3,19 +3,23 @@ fn test_literal() { if "".is_empty() { - //~^ERROR: this expression always evaluates to true + //~^ const_is_empty + } if "foobar".is_empty() { - //~^ERROR: this expression always evaluates to false + //~^ const_is_empty + } } fn test_byte_literal() { if b"".is_empty() { - //~^ERROR: this expression always evaluates to true + //~^ const_is_empty + } if b"foobar".is_empty() { - //~^ERROR: this expression always evaluates to false + //~^ const_is_empty + } } @@ -32,10 +36,12 @@ fn test_propagated() { let empty2 = empty; let non_empty2 = non_empty; if empty2.is_empty() { - //~^ERROR: this expression always evaluates to true + //~^ const_is_empty + } if non_empty2.is_empty() { - //~^ERROR: this expression always evaluates to false + //~^ const_is_empty + } } @@ -57,48 +63,67 @@ const NON_EMPTY_REF_ARRAY: &[u32; 3] = &[1, 2, 3]; fn test_from_const() { let _ = EMPTY_STR.is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + let _ = NON_EMPTY_STR.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + let _ = EMPTY_BSTR.is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + let _ = NON_EMPTY_BSTR.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + let _ = EMPTY_ARRAY.is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + let _ = EMPTY_ARRAY_REPEAT.is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + let _ = EMPTY_U8_SLICE.is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + let _ = NON_EMPTY_U8_SLICE.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + let _ = NON_EMPTY_ARRAY.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + let _ = NON_EMPTY_ARRAY_REPEAT.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + let _ = EMPTY_REF_ARRAY.is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + let _ = NON_EMPTY_REF_ARRAY.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + let _ = EMPTY_SLICE.is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + let _ = NON_EMPTY_SLICE.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + let _ = NON_EMPTY_SLICE_REPEAT.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + } fn main() { let value = "foobar"; let _ = value.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + let x = value; let _ = x.is_empty(); - //~^ ERROR: this expression always evaluates to false + //~^ const_is_empty + let _ = "".is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + let _ = b"".is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + } fn str_from_arg(var: &str) { @@ -152,7 +177,8 @@ fn not_cfg_conditioned() { let val = ""; #[cfg(not(target_os = "inexistent"))] let _ = val.is_empty(); - //~^ ERROR: this expression always evaluates to true + //~^ const_is_empty + } const fn const_rand() -> &'static str { @@ -183,5 +209,6 @@ fn issue_13106() { const { EMPTY_STR.is_empty(); + //~^ const_is_empty } } diff --git a/tests/ui/const_is_empty.stderr b/tests/ui/const_is_empty.stderr index 0afba940d8b4..9557ad18dfc8 100644 --- a/tests/ui/const_is_empty.stderr +++ b/tests/ui/const_is_empty.stderr @@ -8,157 +8,157 @@ LL | if "".is_empty() { = help: to override `-D warnings` add `#[allow(clippy::const_is_empty)]` error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:8:8 + --> tests/ui/const_is_empty.rs:9:8 | LL | if "foobar".is_empty() { | ^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:14:8 + --> tests/ui/const_is_empty.rs:16:8 | LL | if b"".is_empty() { | ^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:17:8 + --> tests/ui/const_is_empty.rs:20:8 | LL | if b"foobar".is_empty() { | ^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:34:8 + --> tests/ui/const_is_empty.rs:38:8 | LL | if empty2.is_empty() { | ^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:37:8 + --> tests/ui/const_is_empty.rs:42:8 | LL | if non_empty2.is_empty() { | ^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:59:13 + --> tests/ui/const_is_empty.rs:65:13 | LL | let _ = EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:61:13 + --> tests/ui/const_is_empty.rs:68:13 | LL | let _ = NON_EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:63:13 + --> tests/ui/const_is_empty.rs:71:13 | LL | let _ = EMPTY_BSTR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:65:13 + --> tests/ui/const_is_empty.rs:74:13 | LL | let _ = NON_EMPTY_BSTR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:67:13 + --> tests/ui/const_is_empty.rs:77:13 | LL | let _ = EMPTY_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:69:13 + --> tests/ui/const_is_empty.rs:80:13 | LL | let _ = EMPTY_ARRAY_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:71:13 + --> tests/ui/const_is_empty.rs:83:13 | LL | let _ = EMPTY_U8_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:73:13 + --> tests/ui/const_is_empty.rs:86:13 | LL | let _ = NON_EMPTY_U8_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:75:13 + --> tests/ui/const_is_empty.rs:89:13 | LL | let _ = NON_EMPTY_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:77:13 + --> tests/ui/const_is_empty.rs:92:13 | LL | let _ = NON_EMPTY_ARRAY_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:79:13 + --> tests/ui/const_is_empty.rs:95:13 | LL | let _ = EMPTY_REF_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:81:13 + --> tests/ui/const_is_empty.rs:98:13 | LL | let _ = NON_EMPTY_REF_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:83:13 + --> tests/ui/const_is_empty.rs:101:13 | LL | let _ = EMPTY_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:85:13 + --> tests/ui/const_is_empty.rs:104:13 | LL | let _ = NON_EMPTY_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:87:13 + --> tests/ui/const_is_empty.rs:107:13 | LL | let _ = NON_EMPTY_SLICE_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:93:13 + --> tests/ui/const_is_empty.rs:114:13 | LL | let _ = value.is_empty(); | ^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:96:13 + --> tests/ui/const_is_empty.rs:118:13 | LL | let _ = x.is_empty(); | ^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:98:13 + --> tests/ui/const_is_empty.rs:121:13 | LL | let _ = "".is_empty(); | ^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:100:13 + --> tests/ui/const_is_empty.rs:124:13 | LL | let _ = b"".is_empty(); | ^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:154:13 + --> tests/ui/const_is_empty.rs:179:13 | LL | let _ = val.is_empty(); | ^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:185:9 + --> tests/ui/const_is_empty.rs:211:9 | LL | EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/copy_iterator.rs b/tests/ui/copy_iterator.rs index ea3a4face93f..f048f7541bc6 100644 --- a/tests/ui/copy_iterator.rs +++ b/tests/ui/copy_iterator.rs @@ -5,8 +5,9 @@ struct Countdown(u8); impl Iterator for Countdown { - //~^ ERROR: you are implementing `Iterator` on a `Copy` type - //~| NOTE: consider implementing `IntoIterator` instead +//~^ copy_iterator + + type Item = u8; fn next(&mut self) -> Option { diff --git a/tests/ui/copy_iterator.stderr b/tests/ui/copy_iterator.stderr index 2f6378a85fee..86fd326c36c5 100644 --- a/tests/ui/copy_iterator.stderr +++ b/tests/ui/copy_iterator.stderr @@ -2,9 +2,6 @@ error: you are implementing `Iterator` on a `Copy` type --> tests/ui/copy_iterator.rs:7:1 | LL | / impl Iterator for Countdown { -LL | | -LL | | -LL | | type Item = u8; ... | LL | | } | |_^ diff --git a/tests/ui/crashes/associated-constant-ice.rs b/tests/ui/crashes/associated-constant-ice.rs index fec16671eeb3..c5767cd656e9 100644 --- a/tests/ui/crashes/associated-constant-ice.rs +++ b/tests/ui/crashes/associated-constant-ice.rs @@ -1,3 +1,4 @@ +//@ check-pass // Test for https://github.com/rust-lang/rust-clippy/issues/1698 pub trait Trait { diff --git a/tests/ui/crashes/cc_seme.rs b/tests/ui/crashes/cc_seme.rs index 98897d6d7aaf..1d8e635ffe44 100644 --- a/tests/ui/crashes/cc_seme.rs +++ b/tests/ui/crashes/cc_seme.rs @@ -1,3 +1,4 @@ +//@ check-pass // Test for https://github.com/rust-lang/rust-clippy/issues/478 enum Baz { diff --git a/tests/ui/crashes/enum-glob-import-crate.rs b/tests/ui/crashes/enum-glob-import-crate.rs index dca32aa3b561..bbcd599f6d0b 100644 --- a/tests/ui/crashes/enum-glob-import-crate.rs +++ b/tests/ui/crashes/enum-glob-import-crate.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![deny(clippy::all)] #![allow(unused_imports)] diff --git a/tests/ui/crashes/ice-10148.rs b/tests/ui/crashes/ice-10148.rs index d89d94edbcdb..8baaccd811d7 100644 --- a/tests/ui/crashes/ice-10148.rs +++ b/tests/ui/crashes/ice-10148.rs @@ -6,4 +6,5 @@ use proc_macros::with_span; fn main() { println!(with_span!(""something "")); + //~^ println_empty_string } diff --git a/tests/ui/crashes/ice-10508a.rs b/tests/ui/crashes/ice-10508a.rs index f45057217b43..43da01344555 100644 --- a/tests/ui/crashes/ice-10508a.rs +++ b/tests/ui/crashes/ice-10508a.rs @@ -1,3 +1,4 @@ +//@ check-pass // Used to overflow in `is_normalizable` use std::marker::PhantomData; diff --git a/tests/ui/crashes/ice-10508b.rs b/tests/ui/crashes/ice-10508b.rs index 41d4f0234b94..7588419381cf 100644 --- a/tests/ui/crashes/ice-10508b.rs +++ b/tests/ui/crashes/ice-10508b.rs @@ -1,3 +1,5 @@ +//@ check-pass + use std::marker::PhantomData; struct Digit { diff --git a/tests/ui/crashes/ice-10508c.rs b/tests/ui/crashes/ice-10508c.rs index fb84d85fd675..d207fdb2c87a 100644 --- a/tests/ui/crashes/ice-10508c.rs +++ b/tests/ui/crashes/ice-10508c.rs @@ -1,3 +1,5 @@ +//@ check-pass + #[derive(Debug)] struct S { t: T, diff --git a/tests/ui/crashes/ice-10972-tait.rs b/tests/ui/crashes/ice-10972-tait.rs index f3ab9cebb7c2..11ddbfc3a04b 100644 --- a/tests/ui/crashes/ice-10972-tait.rs +++ b/tests/ui/crashes/ice-10972-tait.rs @@ -1,3 +1,4 @@ +//@ check-pass // ICE: #10972 // asked to assemble constituent types of unexpected type: Binder(Foo, []) #![feature(type_alias_impl_trait)] diff --git a/tests/ui/crashes/ice-11065.rs b/tests/ui/crashes/ice-11065.rs index a17d7e38e0c3..434f11a2c577 100644 --- a/tests/ui/crashes/ice-11065.rs +++ b/tests/ui/crashes/ice-11065.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::useless_conversion)] use std::option::IntoIter as OptionIter; diff --git a/tests/ui/crashes/ice-11230.fixed b/tests/ui/crashes/ice-11230.fixed index 1d4c3dd9dcc4..181e1ebbe5a3 100644 --- a/tests/ui/crashes/ice-11230.fixed +++ b/tests/ui/crashes/ice-11230.fixed @@ -6,6 +6,7 @@ fn main() { const A: &[for<'a> fn(&'a ())] = &[]; for v in A {} + //~^ explicit_iter_loop } // needless_collect @@ -13,4 +14,5 @@ trait Helper<'a>: Iterator {} fn x(w: &mut dyn for<'a> Helper<'a>) { w.next().is_none(); + //~^ needless_collect } diff --git a/tests/ui/crashes/ice-11230.rs b/tests/ui/crashes/ice-11230.rs index a16fb271497c..fb05dc781bc0 100644 --- a/tests/ui/crashes/ice-11230.rs +++ b/tests/ui/crashes/ice-11230.rs @@ -6,6 +6,7 @@ fn main() { const A: &[for<'a> fn(&'a ())] = &[]; for v in A.iter() {} + //~^ explicit_iter_loop } // needless_collect @@ -13,4 +14,5 @@ trait Helper<'a>: Iterator {} fn x(w: &mut dyn for<'a> Helper<'a>) { w.collect::>().is_empty(); + //~^ needless_collect } diff --git a/tests/ui/crashes/ice-11230.stderr b/tests/ui/crashes/ice-11230.stderr index 7167d90e456e..b4a3f67081ae 100644 --- a/tests/ui/crashes/ice-11230.stderr +++ b/tests/ui/crashes/ice-11230.stderr @@ -8,7 +8,7 @@ LL | for v in A.iter() {} = help: to override `-D warnings` add `#[allow(clippy::explicit_iter_loop)]` error: avoid using `collect()` when not needed - --> tests/ui/crashes/ice-11230.rs:15:7 + --> tests/ui/crashes/ice-11230.rs:16:7 | LL | w.collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` diff --git a/tests/ui/crashes/ice-11337.rs b/tests/ui/crashes/ice-11337.rs index 0bed4035f6bf..317b7a7083a6 100644 --- a/tests/ui/crashes/ice-11337.rs +++ b/tests/ui/crashes/ice-11337.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(trait_alias)] trait Confusing = Fn(i32) where F: Fn(u32); diff --git a/tests/ui/crashes/ice-11422.fixed b/tests/ui/crashes/ice-11422.fixed index d996b1db08a6..be07a9d8c1f9 100644 --- a/tests/ui/crashes/ice-11422.fixed +++ b/tests/ui/crashes/ice-11422.fixed @@ -4,6 +4,7 @@ use std::fmt::Debug; use std::ops::*; fn r#gen() -> impl PartialOrd + Debug {} +//~^ implied_bounds_in_impls struct Bar {} trait Foo {} diff --git a/tests/ui/crashes/ice-11422.rs b/tests/ui/crashes/ice-11422.rs index eb89b7c38f43..43de882caa11 100644 --- a/tests/ui/crashes/ice-11422.rs +++ b/tests/ui/crashes/ice-11422.rs @@ -4,6 +4,7 @@ use std::fmt::Debug; use std::ops::*; fn r#gen() -> impl PartialOrd + PartialEq + Debug {} +//~^ implied_bounds_in_impls struct Bar {} trait Foo {} diff --git a/tests/ui/crashes/ice-11755.rs b/tests/ui/crashes/ice-11755.rs index 367cb6998578..d6aa1e5183d2 100644 --- a/tests/ui/crashes/ice-11755.rs +++ b/tests/ui/crashes/ice-11755.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::unused_enumerate_index)] fn main() { diff --git a/tests/ui/crashes/ice-11803.rs b/tests/ui/crashes/ice-11803.rs index 1bb8bf0c746b..aced75b3ad12 100644 --- a/tests/ui/crashes/ice-11803.rs +++ b/tests/ui/crashes/ice-11803.rs @@ -3,6 +3,8 @@ #![warn(clippy::impl_trait_in_params)] pub fn g>>() { +//~^ impl_trait_in_params +//~| impl_trait_in_params extern "C" fn implementation_detail() {} } diff --git a/tests/ui/crashes/ice-11939.rs b/tests/ui/crashes/ice-11939.rs index 5e7193b68264..ce7a0de1ac3a 100644 --- a/tests/ui/crashes/ice-11939.rs +++ b/tests/ui/crashes/ice-11939.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::unit_arg, clippy::no_effect)] const fn v(_: ()) {} diff --git a/tests/ui/crashes/ice-12253.rs b/tests/ui/crashes/ice-12253.rs index 41f50035144a..58ad7c3bfbf5 100644 --- a/tests/ui/crashes/ice-12253.rs +++ b/tests/ui/crashes/ice-12253.rs @@ -1,3 +1,5 @@ +//@ check-pass + #[allow(overflowing_literals, unconditional_panic, clippy::no_effect)] fn main() { let arr: [i32; 5] = [0; 5]; diff --git a/tests/ui/crashes/ice-12491.fixed b/tests/ui/crashes/ice-12491.fixed index 4ea480b0663c..ab9c61463e92 100644 --- a/tests/ui/crashes/ice-12491.fixed +++ b/tests/ui/crashes/ice-12491.fixed @@ -3,5 +3,6 @@ fn main() { if (true) { // anything一些中文 + //~^^ needless_return } } diff --git a/tests/ui/crashes/ice-12491.rs b/tests/ui/crashes/ice-12491.rs index 60add6afa2c4..b774bd3788a7 100644 --- a/tests/ui/crashes/ice-12491.rs +++ b/tests/ui/crashes/ice-12491.rs @@ -4,5 +4,6 @@ fn main() { if (true) { // anything一些中文 return; + //~^^ needless_return } } diff --git a/tests/ui/crashes/ice-12585.rs b/tests/ui/crashes/ice-12585.rs index 7928115c0a94..f35e95c6bc34 100644 --- a/tests/ui/crashes/ice-12585.rs +++ b/tests/ui/crashes/ice-12585.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::unit_arg)] struct One { diff --git a/tests/ui/crashes/ice-12616.fixed b/tests/ui/crashes/ice-12616.fixed index a5a5b3d1e78e..b7840cabc6b4 100644 --- a/tests/ui/crashes/ice-12616.fixed +++ b/tests/ui/crashes/ice-12616.fixed @@ -4,4 +4,5 @@ fn main() { let s = std::ptr::null::<()>; s().cast::<()>(); + //~^ ptr_as_ptr } diff --git a/tests/ui/crashes/ice-12616.rs b/tests/ui/crashes/ice-12616.rs index 6ee9a5ec08fe..bb37b2e6a679 100644 --- a/tests/ui/crashes/ice-12616.rs +++ b/tests/ui/crashes/ice-12616.rs @@ -4,4 +4,5 @@ fn main() { let s = std::ptr::null::<()>; s() as *const (); + //~^ ptr_as_ptr } diff --git a/tests/ui/crashes/ice-13862.rs b/tests/ui/crashes/ice-13862.rs index a5f010054b2f..774774e6245b 100644 --- a/tests/ui/crashes/ice-13862.rs +++ b/tests/ui/crashes/ice-13862.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![crate_type = "lib"] #![no_std] diff --git a/tests/ui/crashes/ice-1588.rs b/tests/ui/crashes/ice-1588.rs index 9ec093721c17..3ccd33052cd6 100644 --- a/tests/ui/crashes/ice-1588.rs +++ b/tests/ui/crashes/ice-1588.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::all)] // Test for https://github.com/rust-lang/rust-clippy/issues/1588 diff --git a/tests/ui/crashes/ice-1782.rs b/tests/ui/crashes/ice-1782.rs index 73de5721cbc1..fefdc405cce2 100644 --- a/tests/ui/crashes/ice-1782.rs +++ b/tests/ui/crashes/ice-1782.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(dead_code, unused_variables)] #![allow(clippy::unnecessary_cast, clippy::missing_transmute_annotations)] diff --git a/tests/ui/crashes/ice-1969.rs b/tests/ui/crashes/ice-1969.rs index eb901c767294..34ff725d7117 100644 --- a/tests/ui/crashes/ice-1969.rs +++ b/tests/ui/crashes/ice-1969.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::all)] // Test for https://github.com/rust-lang/rust-clippy/issues/1969 diff --git a/tests/ui/crashes/ice-2499.rs b/tests/ui/crashes/ice-2499.rs index 732f331ad145..685c28ff4d6a 100644 --- a/tests/ui/crashes/ice-2499.rs +++ b/tests/ui/crashes/ice-2499.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(dead_code, clippy::char_lit_as_u8, clippy::needless_bool)] // Should not trigger an ICE in `SpanlessHash` / `consts::constant` diff --git a/tests/ui/crashes/ice-2594.rs b/tests/ui/crashes/ice-2594.rs index dddf860bd178..d4d9e74cc193 100644 --- a/tests/ui/crashes/ice-2594.rs +++ b/tests/ui/crashes/ice-2594.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(dead_code, unused_variables)] /// Should not trigger an ICE in `SpanlessHash` / `consts::constant` diff --git a/tests/ui/crashes/ice-2727.rs b/tests/ui/crashes/ice-2727.rs index 59fb9b04b86d..92287459424f 100644 --- a/tests/ui/crashes/ice-2727.rs +++ b/tests/ui/crashes/ice-2727.rs @@ -1,3 +1,4 @@ +//@ check-pass // Test for https://github.com/rust-lang/rust-clippy/issues/2727 pub fn f(new: fn()) { diff --git a/tests/ui/crashes/ice-2760.rs b/tests/ui/crashes/ice-2760.rs index 5f7d91abf995..188d90fcae22 100644 --- a/tests/ui/crashes/ice-2760.rs +++ b/tests/ui/crashes/ice-2760.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow( unused_variables, clippy::disallowed_names, diff --git a/tests/ui/crashes/ice-2774.fixed b/tests/ui/crashes/ice-2774.fixed index 96cf0d8540cd..d096584fa75c 100644 --- a/tests/ui/crashes/ice-2774.fixed +++ b/tests/ui/crashes/ice-2774.fixed @@ -13,8 +13,9 @@ pub struct Foo; #[allow(clippy::implicit_hasher)] // This should not cause a "cannot relate bound region" ICE. pub fn add_barfoos_to_foos(bars: &HashSet<&Bar>) { - //~^ ERROR: the following explicit lifetimes could be elided: 'a - //~| NOTE: `-D clippy::needless-lifetimes` implied by `-D warnings` +//~^ needless_lifetimes + + let mut foos = HashSet::new(); foos.extend(bars.iter().map(|b| &b.foo)); } diff --git a/tests/ui/crashes/ice-2774.rs b/tests/ui/crashes/ice-2774.rs index 464d7891c9f4..83fb7be626df 100644 --- a/tests/ui/crashes/ice-2774.rs +++ b/tests/ui/crashes/ice-2774.rs @@ -13,8 +13,9 @@ pub struct Foo; #[allow(clippy::implicit_hasher)] // This should not cause a "cannot relate bound region" ICE. pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) { - //~^ ERROR: the following explicit lifetimes could be elided: 'a - //~| NOTE: `-D clippy::needless-lifetimes` implied by `-D warnings` +//~^ needless_lifetimes + + let mut foos = HashSet::new(); foos.extend(bars.iter().map(|b| &b.foo)); } diff --git a/tests/ui/crashes/ice-2862.rs b/tests/ui/crashes/ice-2862.rs index 2573b571f55c..e27bdba04e80 100644 --- a/tests/ui/crashes/ice-2862.rs +++ b/tests/ui/crashes/ice-2862.rs @@ -1,3 +1,4 @@ +//@ check-pass // Test for https://github.com/rust-lang/rust-clippy/issues/2862 pub trait FooMap { diff --git a/tests/ui/crashes/ice-2865.rs b/tests/ui/crashes/ice-2865.rs index 28363707acca..681d10a75014 100644 --- a/tests/ui/crashes/ice-2865.rs +++ b/tests/ui/crashes/ice-2865.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(dead_code, clippy::extra_unused_lifetimes)] // Test for https://github.com/rust-lang/rust-clippy/issues/2865 diff --git a/tests/ui/crashes/ice-3151.rs b/tests/ui/crashes/ice-3151.rs index f88a26cb4859..f0c57d2f19f4 100644 --- a/tests/ui/crashes/ice-3151.rs +++ b/tests/ui/crashes/ice-3151.rs @@ -1,3 +1,4 @@ +//@ check-pass // Test for https://github.com/rust-lang/rust-clippy/issues/3151 #[derive(Clone)] diff --git a/tests/ui/crashes/ice-3462.rs b/tests/ui/crashes/ice-3462.rs index ccd617e305da..4ce484917ae2 100644 --- a/tests/ui/crashes/ice-3462.rs +++ b/tests/ui/crashes/ice-3462.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::all)] #![allow(clippy::disallowed_names, clippy::equatable_if_let, clippy::needless_if)] #![allow(unused)] diff --git a/tests/ui/crashes/ice-360.rs b/tests/ui/crashes/ice-360.rs index 0d10932b0987..43becad3183f 100644 --- a/tests/ui/crashes/ice-360.rs +++ b/tests/ui/crashes/ice-360.rs @@ -3,14 +3,17 @@ fn main() {} fn no_panic(slice: &[T]) { let mut iter = slice.iter(); loop { - //~^ ERROR: this loop never actually loops - //~| ERROR: this loop could be written as a `while let` loop - //~| NOTE: `-D clippy::while-let-loop` implied by `-D warnings` + //~^ never_loop + //~| while_let_loop + + + let _ = match iter.next() { Some(ele) => ele, None => break, }; loop {} - //~^ ERROR: empty `loop {}` wastes CPU cycles + //~^ empty_loop + } } diff --git a/tests/ui/crashes/ice-360.stderr b/tests/ui/crashes/ice-360.stderr index 9961eb21485d..e4bd436abc54 100644 --- a/tests/ui/crashes/ice-360.stderr +++ b/tests/ui/crashes/ice-360.stderr @@ -20,7 +20,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::while_let_loop)]` error: empty `loop {}` wastes CPU cycles - --> tests/ui/crashes/ice-360.rs:13:9 + --> tests/ui/crashes/ice-360.rs:15:9 | LL | loop {} | ^^^^^^^ diff --git a/tests/ui/crashes/ice-3717.fixed b/tests/ui/crashes/ice-3717.fixed index 3f54b326979c..0d7c38f95217 100644 --- a/tests/ui/crashes/ice-3717.fixed +++ b/tests/ui/crashes/ice-3717.fixed @@ -5,7 +5,8 @@ use std::collections::HashSet; fn main() {} pub fn ice_3717(_: &HashSet) { - //~^ ERROR: parameter of type `HashSet` should be generalized over different hashers +//~^ implicit_hasher + let _ = [0u8; 0]; let _: HashSet = HashSet::default(); } diff --git a/tests/ui/crashes/ice-3717.rs b/tests/ui/crashes/ice-3717.rs index 2890a9277c71..7c286abf32b0 100644 --- a/tests/ui/crashes/ice-3717.rs +++ b/tests/ui/crashes/ice-3717.rs @@ -5,7 +5,8 @@ use std::collections::HashSet; fn main() {} pub fn ice_3717(_: &HashSet) { - //~^ ERROR: parameter of type `HashSet` should be generalized over different hashers +//~^ implicit_hasher + let _ = [0u8; 0]; let _: HashSet = HashSet::new(); } diff --git a/tests/ui/crashes/ice-3717.stderr b/tests/ui/crashes/ice-3717.stderr index aac72c669654..2e53b610922e 100644 --- a/tests/ui/crashes/ice-3717.stderr +++ b/tests/ui/crashes/ice-3717.stderr @@ -13,6 +13,7 @@ help: add a type parameter for `BuildHasher` | LL ~ pub fn ice_3717(_: &HashSet) { LL | +LL | LL | let _ = [0u8; 0]; LL ~ let _: HashSet = HashSet::default(); | diff --git a/tests/ui/crashes/ice-3741.rs b/tests/ui/crashes/ice-3741.rs index 3106a2e72169..d8c02b1ba452 100644 --- a/tests/ui/crashes/ice-3741.rs +++ b/tests/ui/crashes/ice-3741.rs @@ -1,3 +1,4 @@ +//@ check-pass //@aux-build:proc_macro_crash.rs #![warn(clippy::suspicious_else_formatting)] diff --git a/tests/ui/crashes/ice-3747.rs b/tests/ui/crashes/ice-3747.rs index 44b1d7ed1b2e..62c7835ac55c 100644 --- a/tests/ui/crashes/ice-3747.rs +++ b/tests/ui/crashes/ice-3747.rs @@ -1,3 +1,4 @@ +//@ check-pass // Test for https://github.com/rust-lang/rust-clippy/issues/3747 macro_rules! a { diff --git a/tests/ui/crashes/ice-3969.rs b/tests/ui/crashes/ice-3969.rs index ac09ce08753a..1db7f0ad8b5b 100644 --- a/tests/ui/crashes/ice-3969.rs +++ b/tests/ui/crashes/ice-3969.rs @@ -18,13 +18,12 @@ struct Dst { struct TwoStrs(str, str) where str: Sized; -//~^ ERROR: trait bound str: std::marker::Sized does not depend on any type or lifetime -//~| NOTE: `-D trivial-bounds` implied by `-D warnings` +//~^ ERROR: trait bound fn unsized_local() where for<'a> Dst: Sized, - //~^ ERROR: trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend +//~^ ERROR: trait bound { let x: Dst = *(Box::new(Dst { x: 1 }) as Box>); } @@ -32,7 +31,7 @@ where fn return_str() -> str where str: Sized, - //~^ ERROR: trait bound str: std::marker::Sized does not depend on any type or lifetim +//~^ ERROR: trait bound { *"Sized".to_string().into_boxed_str() } @@ -40,7 +39,7 @@ where fn use_op(s: String) -> String where String: ::std::ops::Neg, - //~^ ERROR: trait bound std::string::String: std::ops::Neg does not depend on any type +//~^ ERROR: trait bound { -s } @@ -48,7 +47,7 @@ where fn use_for() where i32: Iterator, - //~^ ERROR: trait bound i32: std::iter::Iterator does not depend on any type or lifeti +//~^ ERROR: trait bound { for _ in 2i32 {} } diff --git a/tests/ui/crashes/ice-3969.stderr b/tests/ui/crashes/ice-3969.stderr index 285efee36bd8..b820ecf7e332 100644 --- a/tests/ui/crashes/ice-3969.stderr +++ b/tests/ui/crashes/ice-3969.stderr @@ -8,25 +8,25 @@ LL | str: Sized; = help: to override `-D warnings` add `#[allow(trivial_bounds)]` error: trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters - --> tests/ui/crashes/ice-3969.rs:26:30 + --> tests/ui/crashes/ice-3969.rs:25:30 | LL | for<'a> Dst: Sized, | ^^^^^ error: trait bound str: std::marker::Sized does not depend on any type or lifetime parameters - --> tests/ui/crashes/ice-3969.rs:34:10 + --> tests/ui/crashes/ice-3969.rs:33:10 | LL | str: Sized, | ^^^^^ error: trait bound std::string::String: std::ops::Neg does not depend on any type or lifetime parameters - --> tests/ui/crashes/ice-3969.rs:42:13 + --> tests/ui/crashes/ice-3969.rs:41:13 | LL | String: ::std::ops::Neg, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait bound i32: std::iter::Iterator does not depend on any type or lifetime parameters - --> tests/ui/crashes/ice-3969.rs:50:10 + --> tests/ui/crashes/ice-3969.rs:49:10 | LL | i32: Iterator, | ^^^^^^^^ diff --git a/tests/ui/crashes/ice-4121.rs b/tests/ui/crashes/ice-4121.rs index e1a142fdcb67..a1192b229ecd 100644 --- a/tests/ui/crashes/ice-4121.rs +++ b/tests/ui/crashes/ice-4121.rs @@ -1,3 +1,5 @@ +//@ check-pass + use std::mem; pub struct Foo(A, B); diff --git a/tests/ui/crashes/ice-4545.rs b/tests/ui/crashes/ice-4545.rs index d9c9c2096d97..1d7cb53ee7be 100644 --- a/tests/ui/crashes/ice-4545.rs +++ b/tests/ui/crashes/ice-4545.rs @@ -1,3 +1,5 @@ +//@ check-pass + fn repro() { trait Foo { type Bar; diff --git a/tests/ui/crashes/ice-4579.rs b/tests/ui/crashes/ice-4579.rs index 2e7e279f847d..14c8113e315b 100644 --- a/tests/ui/crashes/ice-4579.rs +++ b/tests/ui/crashes/ice-4579.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::single_match)] use std::ptr; diff --git a/tests/ui/crashes/ice-4671.rs b/tests/ui/crashes/ice-4671.rs index 64e8e7769412..3309d51302e2 100644 --- a/tests/ui/crashes/ice-4671.rs +++ b/tests/ui/crashes/ice-4671.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::use_self)] #[macro_use] diff --git a/tests/ui/crashes/ice-4727.rs b/tests/ui/crashes/ice-4727.rs index 2a4bc83f58a5..f90c6ca9a679 100644 --- a/tests/ui/crashes/ice-4727.rs +++ b/tests/ui/crashes/ice-4727.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::use_self)] #[path = "auxiliary/ice-4727-aux.rs"] diff --git a/tests/ui/crashes/ice-4760.rs b/tests/ui/crashes/ice-4760.rs index e1265169762f..07387db7b294 100644 --- a/tests/ui/crashes/ice-4760.rs +++ b/tests/ui/crashes/ice-4760.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(non_local_definitions)] const COUNT: usize = 2; diff --git a/tests/ui/crashes/ice-4775.rs b/tests/ui/crashes/ice-4775.rs index f693aafd1cbb..dd6c6b8de25a 100644 --- a/tests/ui/crashes/ice-4775.rs +++ b/tests/ui/crashes/ice-4775.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::uninlined_format_args)] pub struct ArrayWrapper([usize; N]); diff --git a/tests/ui/crashes/ice-4968.rs b/tests/ui/crashes/ice-4968.rs index 50473868005e..542cb63516da 100644 --- a/tests/ui/crashes/ice-4968.rs +++ b/tests/ui/crashes/ice-4968.rs @@ -1,3 +1,4 @@ +//@ check-pass // Test for https://github.com/rust-lang/rust-clippy/issues/4968 #![warn(clippy::unsound_collection_transmute)] diff --git a/tests/ui/crashes/ice-5207.rs b/tests/ui/crashes/ice-5207.rs index 0df8b88fea2f..6e438bcc2843 100644 --- a/tests/ui/crashes/ice-5207.rs +++ b/tests/ui/crashes/ice-5207.rs @@ -1,3 +1,4 @@ +//@ check-pass // Regression test for https://github.com/rust-lang/rust-clippy/issues/5207 pub async fn bar<'a, T: 'a>(_: T) {} diff --git a/tests/ui/crashes/ice-5223.rs b/tests/ui/crashes/ice-5223.rs index e3b3b27a6fc3..c055e551b298 100644 --- a/tests/ui/crashes/ice-5223.rs +++ b/tests/ui/crashes/ice-5223.rs @@ -1,3 +1,4 @@ +//@ check-pass // Regression test for #5233 #![warn(clippy::indexing_slicing, clippy::iter_cloned_collect)] diff --git a/tests/ui/crashes/ice-5238.rs b/tests/ui/crashes/ice-5238.rs index ee2ae4f1a042..1d7dd8c76507 100644 --- a/tests/ui/crashes/ice-5238.rs +++ b/tests/ui/crashes/ice-5238.rs @@ -1,3 +1,4 @@ +//@ check-pass // Regression test for #5238 / https://github.com/rust-lang/rust/pull/69562 #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] diff --git a/tests/ui/crashes/ice-5389.rs b/tests/ui/crashes/ice-5389.rs index de262199004b..b54562095a21 100644 --- a/tests/ui/crashes/ice-5389.rs +++ b/tests/ui/crashes/ice-5389.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::explicit_counter_loop)] fn main() { diff --git a/tests/ui/crashes/ice-5579.rs b/tests/ui/crashes/ice-5579.rs index 8ab36bbf93cb..e3e408a52539 100644 --- a/tests/ui/crashes/ice-5579.rs +++ b/tests/ui/crashes/ice-5579.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::unnecessary_literal_unwrap)] trait IsErr { diff --git a/tests/ui/crashes/ice-5835.fixed b/tests/ui/crashes/ice-5835.fixed deleted file mode 100644 index c0532d685786..000000000000 --- a/tests/ui/crashes/ice-5835.fixed +++ /dev/null @@ -1,11 +0,0 @@ -#[rustfmt::skip] -pub struct Foo { - /// 位 - //~^ ERROR: using tabs in doc comments is not recommended - //~| NOTE: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` - /// ^ Do not remove this tab character. - /// It was required to trigger the ICE. - pub bar: u8, -} - -fn main() {} diff --git a/tests/ui/crashes/ice-5835.rs b/tests/ui/crashes/ice-5835.rs index 122bddd6ae67..149ba4786181 100644 --- a/tests/ui/crashes/ice-5835.rs +++ b/tests/ui/crashes/ice-5835.rs @@ -1,8 +1,10 @@ #[rustfmt::skip] pub struct Foo { /// 位 - //~^ ERROR: using tabs in doc comments is not recommended - //~| NOTE: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` + //~^ tabs_in_doc_comments + //~| empty_line_after_doc_comments + + /// ^ Do not remove this tab character. /// It was required to trigger the ICE. pub bar: u8, diff --git a/tests/ui/crashes/ice-5835.stderr b/tests/ui/crashes/ice-5835.stderr index 45e5e9a4b83d..b342b43d0416 100644 --- a/tests/ui/crashes/ice-5835.stderr +++ b/tests/ui/crashes/ice-5835.stderr @@ -7,5 +7,21 @@ LL | /// 位 = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]` -error: aborting due to 1 previous error +error: empty lines after doc comment + --> tests/ui/crashes/ice-5835.rs:3:5 + | +LL | / /// 位 +... | +LL | | + | |_^ + | + = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]` + = help: if the empty lines are unintentional remove them +help: if the doc comment should not document `bar` comment it out + | +LL | // /// 位 + | ++ + +error: aborting due to 2 previous errors diff --git a/tests/ui/crashes/ice-5872.fixed b/tests/ui/crashes/ice-5872.fixed index c8e870c62fbf..a3235c3c7b7c 100644 --- a/tests/ui/crashes/ice-5872.fixed +++ b/tests/ui/crashes/ice-5872.fixed @@ -2,6 +2,7 @@ fn main() { let _ = vec![1, 2, 3].into_iter().next().is_none(); - //~^ ERROR: avoid using `collect()` when not needed - //~| NOTE: `-D clippy::needless-collect` implied by `-D warnings` + //~^ needless_collect + + } diff --git a/tests/ui/crashes/ice-5872.rs b/tests/ui/crashes/ice-5872.rs index c6ed31365892..7d3ad01f56e7 100644 --- a/tests/ui/crashes/ice-5872.rs +++ b/tests/ui/crashes/ice-5872.rs @@ -2,6 +2,7 @@ fn main() { let _ = vec![1, 2, 3].into_iter().collect::>().is_empty(); - //~^ ERROR: avoid using `collect()` when not needed - //~| NOTE: `-D clippy::needless-collect` implied by `-D warnings` + //~^ needless_collect + + } diff --git a/tests/ui/crashes/ice-5944.rs b/tests/ui/crashes/ice-5944.rs index ce46bc1acc1b..2a93c5436511 100644 --- a/tests/ui/crashes/ice-5944.rs +++ b/tests/ui/crashes/ice-5944.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::repeat_once)] #![allow(clippy::let_unit_value)] diff --git a/tests/ui/crashes/ice-6139.rs b/tests/ui/crashes/ice-6139.rs index f3966e47f5e8..866e13a86592 100644 --- a/tests/ui/crashes/ice-6139.rs +++ b/tests/ui/crashes/ice-6139.rs @@ -1,3 +1,5 @@ +//@ check-pass + trait T<'a> {} fn foo(_: Vec>>) {} diff --git a/tests/ui/crashes/ice-6153.rs b/tests/ui/crashes/ice-6153.rs index 9f73f39f10d7..84873c2ecf4c 100644 --- a/tests/ui/crashes/ice-6153.rs +++ b/tests/ui/crashes/ice-6153.rs @@ -1,3 +1,5 @@ +//@ check-pass + pub struct S<'a, 'e>(&'a str, &'e str); pub type T<'a, 'e> = std::collections::HashMap, ()>; diff --git a/tests/ui/crashes/ice-6179.rs b/tests/ui/crashes/ice-6179.rs index 91160eef03df..640b51517f74 100644 --- a/tests/ui/crashes/ice-6179.rs +++ b/tests/ui/crashes/ice-6179.rs @@ -1,3 +1,4 @@ +//@ check-pass //! This is a minimal reproducer for the ICE in https://github.com/rust-lang/rust-clippy/pull/6179. //! The ICE is mainly caused by using `lower_ty`. See the discussion in the PR for details. diff --git a/tests/ui/crashes/ice-6250.rs b/tests/ui/crashes/ice-6250.rs index 32849f2ca6f0..37db2ce68757 100644 --- a/tests/ui/crashes/ice-6250.rs +++ b/tests/ui/crashes/ice-6250.rs @@ -10,6 +10,8 @@ pub fn list_data(cache: &Cache, key: usize) { if /* let */ Some(reference) = cache.data.get(key) { + //~^ ERROR: mismatched types + //~| ERROR: mismatched types unimplemented!() } } diff --git a/tests/ui/crashes/ice-6251.rs b/tests/ui/crashes/ice-6251.rs index 73e919b6dd2e..8191a53b3e59 100644 --- a/tests/ui/crashes/ice-6251.rs +++ b/tests/ui/crashes/ice-6251.rs @@ -2,5 +2,8 @@ // assertion failed: `(left == right)` ; different DefIds //@no-rustfix fn bug() -> impl Iterator { +//~^ ERROR: the size for values +//~| ERROR: the size for values +//~| ERROR: mismatched types std::iter::empty() } diff --git a/tests/ui/crashes/ice-6252.rs b/tests/ui/crashes/ice-6252.rs index 67fbb0ff699c..829cb447211c 100644 --- a/tests/ui/crashes/ice-6252.rs +++ b/tests/ui/crashes/ice-6252.rs @@ -7,8 +7,11 @@ trait TypeVal { struct Five; struct Multiply { _n: PhantomData, + //~^ ERROR: cannot find type } impl TypeVal for Multiply where N: TypeVal {} +//~^ ERROR: cannot find type +//~| ERROR: not all trait items fn main() { [1; >::VAL]; diff --git a/tests/ui/crashes/ice-6252.stderr b/tests/ui/crashes/ice-6252.stderr index cd2031af1c6d..201a897b2319 100644 --- a/tests/ui/crashes/ice-6252.stderr +++ b/tests/ui/crashes/ice-6252.stderr @@ -10,7 +10,7 @@ LL + use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope - --> tests/ui/crashes/ice-6252.rs:11:63 + --> tests/ui/crashes/ice-6252.rs:12:63 | LL | impl TypeVal for Multiply where N: TypeVal {} | ^^^ not found in this scope @@ -21,7 +21,7 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | +++++ error[E0046]: not all trait items implemented, missing: `VAL` - --> tests/ui/crashes/ice-6252.rs:11:1 + --> tests/ui/crashes/ice-6252.rs:12:1 | LL | const VAL: T; | ------------ `VAL` from trait diff --git a/tests/ui/crashes/ice-6254.rs b/tests/ui/crashes/ice-6254.rs index aaca32ab2d93..45144fd9e5ec 100644 --- a/tests/ui/crashes/ice-6254.rs +++ b/tests/ui/crashes/ice-6254.rs @@ -1,3 +1,4 @@ +//@ check-pass // originally from ./tests/ui/pattern/usefulness/consts-opaque.rs // panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', // compiler/rustc_mir_build/src/thir/pattern/_match.rs:2030:5 diff --git a/tests/ui/crashes/ice-6332.rs b/tests/ui/crashes/ice-6332.rs index 9dc92aa500b2..25660a3ce853 100644 --- a/tests/ui/crashes/ice-6332.rs +++ b/tests/ui/crashes/ice-6332.rs @@ -1,3 +1,5 @@ +//@ check-pass + fn cmark_check() { let mut link_err = false; macro_rules! cmark_error { diff --git a/tests/ui/crashes/ice-6539.rs b/tests/ui/crashes/ice-6539.rs index ac6c3e4aba04..cff0882cbee3 100644 --- a/tests/ui/crashes/ice-6539.rs +++ b/tests/ui/crashes/ice-6539.rs @@ -1,3 +1,4 @@ +//@ check-pass // The test for the ICE 6539: https://github.com/rust-lang/rust-clippy/issues/6539. // The cause is that `zero_sized_map_values` used `layout_of` with types from type aliases, // which is essentially the same as the ICE 4968. diff --git a/tests/ui/crashes/ice-6792.rs b/tests/ui/crashes/ice-6792.rs index 9cbafc716b50..372ce5ac06f3 100644 --- a/tests/ui/crashes/ice-6792.rs +++ b/tests/ui/crashes/ice-6792.rs @@ -1,3 +1,4 @@ +//@ check-pass //! This is a reproducer for the ICE 6792: https://github.com/rust-lang/rust-clippy/issues/6792. //! The ICE is caused by using `TyCtxt::type_of(assoc_type_id)`. diff --git a/tests/ui/crashes/ice-6793.rs b/tests/ui/crashes/ice-6793.rs index 12a4a0d25ef5..d83a2ee251db 100644 --- a/tests/ui/crashes/ice-6793.rs +++ b/tests/ui/crashes/ice-6793.rs @@ -1,3 +1,4 @@ +//@ check-pass //! This is a reproducer for the ICE 6793: https://github.com/rust-lang/rust-clippy/issues/6793. //! The ICE is caused by using `TyCtxt::type_of(assoc_type_id)`, which is the same as the ICE 6792. diff --git a/tests/ui/crashes/ice-6840.rs b/tests/ui/crashes/ice-6840.rs index d789f60c5d5a..94481f248998 100644 --- a/tests/ui/crashes/ice-6840.rs +++ b/tests/ui/crashes/ice-6840.rs @@ -1,3 +1,4 @@ +//@ check-pass //! This is a reproducer for the ICE 6840: https://github.com/rust-lang/rust-clippy/issues/6840. //! The ICE is caused by `TyCtxt::layout_of` and `is_normalizable` not being strict enough #![allow(dead_code)] diff --git a/tests/ui/crashes/ice-700.rs b/tests/ui/crashes/ice-700.rs index 5e004b94330e..aa3bf493c201 100644 --- a/tests/ui/crashes/ice-700.rs +++ b/tests/ui/crashes/ice-700.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![deny(clippy::all)] // Test for https://github.com/rust-lang/rust-clippy/issues/700 diff --git a/tests/ui/crashes/ice-7012.rs b/tests/ui/crashes/ice-7012.rs index 60bdbc4f124e..d76995adadf1 100644 --- a/tests/ui/crashes/ice-7012.rs +++ b/tests/ui/crashes/ice-7012.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::all)] enum _MyOption { diff --git a/tests/ui/crashes/ice-7126.rs b/tests/ui/crashes/ice-7126.rs index b2dc2248b556..f0c23c7e852d 100644 --- a/tests/ui/crashes/ice-7126.rs +++ b/tests/ui/crashes/ice-7126.rs @@ -1,3 +1,4 @@ +//@ check-pass // This test requires a feature gated const fn and will stop working in the future. #![feature(const_btree_len)] diff --git a/tests/ui/crashes/ice-7169.fixed b/tests/ui/crashes/ice-7169.fixed index cf4077e4d898..d69b472a3617 100644 --- a/tests/ui/crashes/ice-7169.fixed +++ b/tests/ui/crashes/ice-7169.fixed @@ -8,6 +8,7 @@ struct A { fn main() { if Ok::<_, ()>(A::::default()).is_ok() {} - //~^ ERROR: redundant pattern matching, consider using `is_ok()` - //~| NOTE: `-D clippy::redundant-pattern-matching` implied by `-D warnings` + //~^ redundant_pattern_matching + + } diff --git a/tests/ui/crashes/ice-7169.rs b/tests/ui/crashes/ice-7169.rs index b09e6f384632..918f2b0f0b3c 100644 --- a/tests/ui/crashes/ice-7169.rs +++ b/tests/ui/crashes/ice-7169.rs @@ -8,6 +8,7 @@ struct A { fn main() { if let Ok(_) = Ok::<_, ()>(A::::default()) {} - //~^ ERROR: redundant pattern matching, consider using `is_ok()` - //~| NOTE: `-D clippy::redundant-pattern-matching` implied by `-D warnings` + //~^ redundant_pattern_matching + + } diff --git a/tests/ui/crashes/ice-7231.rs b/tests/ui/crashes/ice-7231.rs index 4ad0d351372f..873cdbb0516c 100644 --- a/tests/ui/crashes/ice-7231.rs +++ b/tests/ui/crashes/ice-7231.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::never_loop)] async fn f() { diff --git a/tests/ui/crashes/ice-7272.rs b/tests/ui/crashes/ice-7272.rs index e949038c8d0b..e1910096418b 100644 --- a/tests/ui/crashes/ice-7272.rs +++ b/tests/ui/crashes/ice-7272.rs @@ -1,3 +1,4 @@ +//@ check-pass //@aux-build:ice-7272-aux.rs #![allow(clippy::no_effect)] diff --git a/tests/ui/crashes/ice-7340.rs b/tests/ui/crashes/ice-7340.rs index 7d2351d606f1..6c71c232fddb 100644 --- a/tests/ui/crashes/ice-7340.rs +++ b/tests/ui/crashes/ice-7340.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::no_effect)] fn main() { diff --git a/tests/ui/crashes/ice-7410.rs b/tests/ui/crashes/ice-7410.rs index addbca54e80a..71f00fb9aede 100644 --- a/tests/ui/crashes/ice-7410.rs +++ b/tests/ui/crashes/ice-7410.rs @@ -1,3 +1,4 @@ +//@ check-pass //@compile-flags: -Clink-arg=-nostartfiles //@ignore-target: apple windows diff --git a/tests/ui/crashes/ice-7423.rs b/tests/ui/crashes/ice-7423.rs index 31340b012dd0..a03981842fcc 100644 --- a/tests/ui/crashes/ice-7423.rs +++ b/tests/ui/crashes/ice-7423.rs @@ -1,3 +1,5 @@ +//@ check-pass + pub trait Trait { fn f(); } diff --git a/tests/ui/crashes/ice-7868.rs b/tests/ui/crashes/ice-7868.rs index c6932164e3bf..727dd41aa322 100644 --- a/tests/ui/crashes/ice-7868.rs +++ b/tests/ui/crashes/ice-7868.rs @@ -1,3 +1,4 @@ +//@error-in-other-file: #![warn(clippy::undocumented_unsafe_blocks)] #![allow(clippy::no_effect)] diff --git a/tests/ui/crashes/ice-7869.rs b/tests/ui/crashes/ice-7869.rs index 774e22f6b4c5..68648462b57a 100644 --- a/tests/ui/crashes/ice-7869.rs +++ b/tests/ui/crashes/ice-7869.rs @@ -1,5 +1,6 @@ enum Tila { - //~^ ERROR: all variants have the same prefix: `Työ` +//~^ enum_variant_names + TyöAlkoi, TyöKeskeytyi, TyöValmis, diff --git a/tests/ui/crashes/ice-7869.stderr b/tests/ui/crashes/ice-7869.stderr index 2377b4fd5b6b..7d70e3834e9d 100644 --- a/tests/ui/crashes/ice-7869.stderr +++ b/tests/ui/crashes/ice-7869.stderr @@ -3,6 +3,7 @@ error: all variants have the same prefix: `Työ` | LL | / enum Tila { LL | | +LL | | LL | | TyöAlkoi, LL | | TyöKeskeytyi, LL | | TyöValmis, diff --git a/tests/ui/crashes/ice-7934.rs b/tests/ui/crashes/ice-7934.rs index a4691c4131b3..c7a8d68d63b6 100644 --- a/tests/ui/crashes/ice-7934.rs +++ b/tests/ui/crashes/ice-7934.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::undocumented_unsafe_blocks)] #![allow(clippy::no_effect)] diff --git a/tests/ui/crashes/ice-8250.fixed b/tests/ui/crashes/ice-8250.fixed index 984b61258c78..2474c47944ef 100644 --- a/tests/ui/crashes/ice-8250.fixed +++ b/tests/ui/crashes/ice-8250.fixed @@ -1,7 +1,8 @@ fn _f(s: &str) -> Option<()> { let _ = s[1..].split('.').next()?; - //~^ ERROR: unnecessary use of `splitn` - //~| NOTE: `-D clippy::needless-splitn` implied by `-D warnings` + //~^ needless_splitn + + Some(()) } diff --git a/tests/ui/crashes/ice-8250.rs b/tests/ui/crashes/ice-8250.rs index c1b2e48ba3c0..8f938246f37a 100644 --- a/tests/ui/crashes/ice-8250.rs +++ b/tests/ui/crashes/ice-8250.rs @@ -1,7 +1,8 @@ fn _f(s: &str) -> Option<()> { let _ = s[1..].splitn(2, '.').next()?; - //~^ ERROR: unnecessary use of `splitn` - //~| NOTE: `-D clippy::needless-splitn` implied by `-D warnings` + //~^ needless_splitn + + Some(()) } diff --git a/tests/ui/crashes/ice-8386.rs b/tests/ui/crashes/ice-8386.rs index 3e38b1408d8c..1c7a809174b6 100644 --- a/tests/ui/crashes/ice-8386.rs +++ b/tests/ui/crashes/ice-8386.rs @@ -1,3 +1,5 @@ +//@ check-pass + fn f(x: u32, mut arg: &String) {} fn main() {} diff --git a/tests/ui/crashes/ice-8681.rs b/tests/ui/crashes/ice-8681.rs index 607b9caa3249..b7d6c4556bbd 100644 --- a/tests/ui/crashes/ice-8681.rs +++ b/tests/ui/crashes/ice-8681.rs @@ -1,3 +1,4 @@ +//@ check-pass //@aux-build: ice-8681-aux.rs #![warn(clippy::undocumented_unsafe_blocks)] diff --git a/tests/ui/crashes/ice-8821.rs b/tests/ui/crashes/ice-8821.rs index fb87b79aeed8..c9fea3d1ccb8 100644 --- a/tests/ui/crashes/ice-8821.rs +++ b/tests/ui/crashes/ice-8821.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::let_unit_value)] fn f() {} diff --git a/tests/ui/crashes/ice-8850.fixed b/tests/ui/crashes/ice-8850.fixed index 4569b9e8793e..0e1d8d5a2aae 100644 --- a/tests/ui/crashes/ice-8850.fixed +++ b/tests/ui/crashes/ice-8850.fixed @@ -2,15 +2,14 @@ fn fn_pointer_static() -> usize { static FN: fn() -> usize = || 1; FN() + 1 - //~^ ERROR: returning the result of a `let` binding from a block - //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings` + //~^ let_and_return } fn fn_pointer_const() -> usize { const FN: fn() -> usize = || 1; FN() + 1 - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return } fn deref_to_dyn_fn() -> usize { @@ -25,7 +24,7 @@ fn deref_to_dyn_fn() -> usize { static FN: Derefs = Derefs; FN() + 1 - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return } fn main() {} diff --git a/tests/ui/crashes/ice-8850.rs b/tests/ui/crashes/ice-8850.rs index 499756ecefe9..0109911bca68 100644 --- a/tests/ui/crashes/ice-8850.rs +++ b/tests/ui/crashes/ice-8850.rs @@ -2,15 +2,14 @@ fn fn_pointer_static() -> usize { static FN: fn() -> usize = || 1; let res = FN() + 1; res - //~^ ERROR: returning the result of a `let` binding from a block - //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings` + //~^ let_and_return } fn fn_pointer_const() -> usize { const FN: fn() -> usize = || 1; let res = FN() + 1; res - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return } fn deref_to_dyn_fn() -> usize { @@ -25,7 +24,7 @@ fn deref_to_dyn_fn() -> usize { static FN: Derefs = Derefs; let res = FN() + 1; res - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return } fn main() {} diff --git a/tests/ui/crashes/ice-8850.stderr b/tests/ui/crashes/ice-8850.stderr index 5a8f24ee8c0b..1a44f103beb3 100644 --- a/tests/ui/crashes/ice-8850.stderr +++ b/tests/ui/crashes/ice-8850.stderr @@ -15,7 +15,7 @@ LL ~ FN() + 1 | error: returning the result of a `let` binding from a block - --> tests/ui/crashes/ice-8850.rs:12:5 + --> tests/ui/crashes/ice-8850.rs:11:5 | LL | let res = FN() + 1; | ------------------- unnecessary `let` binding @@ -29,7 +29,7 @@ LL ~ FN() + 1 | error: returning the result of a `let` binding from a block - --> tests/ui/crashes/ice-8850.rs:27:5 + --> tests/ui/crashes/ice-8850.rs:26:5 | LL | let res = FN() + 1; | ------------------- unnecessary `let` binding diff --git a/tests/ui/crashes/ice-9041.rs b/tests/ui/crashes/ice-9041.rs index 727d88f7fbd2..69e74e6e394b 100644 --- a/tests/ui/crashes/ice-9041.rs +++ b/tests/ui/crashes/ice-9041.rs @@ -3,8 +3,9 @@ pub struct Thing; pub fn has_thing(things: &[Thing]) -> bool { let is_thing_ready = |_peer: &Thing| -> bool { todo!() }; things.iter().find(|p| is_thing_ready(p)).is_some() - //~^ ERROR: called `is_some()` after searching an `Iterator` with `find` - //~| NOTE: `-D clippy::search-is-some` implied by `-D warnings` + //~^ search_is_some + + } fn main() {} diff --git a/tests/ui/crashes/ice-9238.rs b/tests/ui/crashes/ice-9238.rs index ee6abd519f16..cbce84305ba8 100644 --- a/tests/ui/crashes/ice-9238.rs +++ b/tests/ui/crashes/ice-9238.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(incomplete_features)] #![feature(generic_const_exprs)] #![warn(clippy::branches_sharing_code)] diff --git a/tests/ui/crashes/ice-9242.rs b/tests/ui/crashes/ice-9242.rs index 0099e6e2f34b..ac5bbad98c14 100644 --- a/tests/ui/crashes/ice-9242.rs +++ b/tests/ui/crashes/ice-9242.rs @@ -1,3 +1,5 @@ +//@ check-pass + enum E { X(), Y, diff --git a/tests/ui/crashes/ice-9405.rs b/tests/ui/crashes/ice-9405.rs index e2d274aeb044..74a56f4d2ef8 100644 --- a/tests/ui/crashes/ice-9405.rs +++ b/tests/ui/crashes/ice-9405.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::useless_format)] #![allow(clippy::print_literal)] diff --git a/tests/ui/crashes/ice-9405.stderr b/tests/ui/crashes/ice-9405.stderr index e8a73b9e782e..96e0f2ea736a 100644 --- a/tests/ui/crashes/ice-9405.stderr +++ b/tests/ui/crashes/ice-9405.stderr @@ -1,5 +1,5 @@ warning: multiple lines skipped by escaped newline - --> tests/ui/crashes/ice-9405.rs:6:10 + --> tests/ui/crashes/ice-9405.rs:8:10 | LL | "\ | __________^ diff --git a/tests/ui/crashes/ice-9414.rs b/tests/ui/crashes/ice-9414.rs index 02cf5d5c240f..2341c99b2390 100644 --- a/tests/ui/crashes/ice-9414.rs +++ b/tests/ui/crashes/ice-9414.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::result_large_err)] trait T {} diff --git a/tests/ui/crashes/ice-9445.rs b/tests/ui/crashes/ice-9445.rs index c67b22f6f8c4..232b8e4a7959 100644 --- a/tests/ui/crashes/ice-9445.rs +++ b/tests/ui/crashes/ice-9445.rs @@ -1,3 +1,4 @@ const UNINIT: core::mem::MaybeUninit> = core::mem::MaybeUninit::uninit(); +//~^ declare_interior_mutable_const fn main() {} diff --git a/tests/ui/crashes/ice-9459.rs b/tests/ui/crashes/ice-9459.rs index 55615124fcf0..43d3264b264d 100644 --- a/tests/ui/crashes/ice-9459.rs +++ b/tests/ui/crashes/ice-9459.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(unsized_fn_params)] pub fn f0(_f: dyn FnOnce()) {} diff --git a/tests/ui/crashes/ice-9463.rs b/tests/ui/crashes/ice-9463.rs index fa83d25b3942..93808e0f8923 100644 --- a/tests/ui/crashes/ice-9463.rs +++ b/tests/ui/crashes/ice-9463.rs @@ -4,6 +4,5 @@ fn main() { //~^ ERROR: this arithmetic operation will overflow let _y = 1u32 >> 10000000000000u32; //~^ ERROR: this arithmetic operation will overflow - //~| ERROR: literal out of range for `u32` - //~| NOTE: the literal `10000000000000u32` does not fit into the type `u32` whose rang + //~| ERROR: literal out of range } diff --git a/tests/ui/crashes/ice-9625.rs b/tests/ui/crashes/ice-9625.rs index a765882b5d81..52117883aa7d 100644 --- a/tests/ui/crashes/ice-9625.rs +++ b/tests/ui/crashes/ice-9625.rs @@ -1,3 +1,5 @@ +//@ check-pass + fn main() { let x = &1; let _ = &1 < x && x < &10; diff --git a/tests/ui/crashes/ice-9746.rs b/tests/ui/crashes/ice-9746.rs index fbd373c70bf2..39fa8ff7a915 100644 --- a/tests/ui/crashes/ice-9746.rs +++ b/tests/ui/crashes/ice-9746.rs @@ -1,3 +1,4 @@ +//@ check-pass //! trait Trait {} diff --git a/tests/ui/crashes/ice-rust-107877.rs b/tests/ui/crashes/ice-rust-107877.rs index 7f5bae60d55d..55fe418bed12 100644 --- a/tests/ui/crashes/ice-rust-107877.rs +++ b/tests/ui/crashes/ice-rust-107877.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(dead_code)] struct Foo; diff --git a/tests/ui/crashes/ice_exact_size.rs b/tests/ui/crashes/ice_exact_size.rs index c0671eaff145..cb4685e78e22 100644 --- a/tests/ui/crashes/ice_exact_size.rs +++ b/tests/ui/crashes/ice_exact_size.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![deny(clippy::all)] // Test for https://github.com/rust-lang/rust-clippy/issues/1336 diff --git a/tests/ui/crashes/if_same_then_else.rs b/tests/ui/crashes/if_same_then_else.rs index a900fe5e6bc6..58ee751948b5 100644 --- a/tests/ui/crashes/if_same_then_else.rs +++ b/tests/ui/crashes/if_same_then_else.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::comparison_chain)] #![deny(clippy::if_same_then_else)] diff --git a/tests/ui/crashes/implements-trait.rs b/tests/ui/crashes/implements-trait.rs index 4502b0147a83..0e68c40be999 100644 --- a/tests/ui/crashes/implements-trait.rs +++ b/tests/ui/crashes/implements-trait.rs @@ -1,3 +1,5 @@ +//@ check-pass + #[allow(clippy::needless_borrowed_reference)] fn main() { let mut v = Vec::::new(); diff --git a/tests/ui/crashes/inherent_impl.rs b/tests/ui/crashes/inherent_impl.rs index 800a5a383f62..87f1347ecfca 100644 --- a/tests/ui/crashes/inherent_impl.rs +++ b/tests/ui/crashes/inherent_impl.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![deny(clippy::multiple_inherent_impl)] // Test for https://github.com/rust-lang/rust-clippy/issues/4578 diff --git a/tests/ui/crashes/issue-825.rs b/tests/ui/crashes/issue-825.rs index e8b455a0ec67..9bbb86e4c65a 100644 --- a/tests/ui/crashes/issue-825.rs +++ b/tests/ui/crashes/issue-825.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(warnings)] // Test for https://github.com/rust-lang/rust-clippy/issues/825 diff --git a/tests/ui/crashes/issues_loop_mut_cond.rs b/tests/ui/crashes/issues_loop_mut_cond.rs index bb238c81ebc0..635580c6a6e7 100644 --- a/tests/ui/crashes/issues_loop_mut_cond.rs +++ b/tests/ui/crashes/issues_loop_mut_cond.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(dead_code)] /// Issue: https://github.com/rust-lang/rust-clippy/issues/2596 diff --git a/tests/ui/crashes/match_same_arms_const.rs b/tests/ui/crashes/match_same_arms_const.rs index 626179c00155..a70623f0c51f 100644 --- a/tests/ui/crashes/match_same_arms_const.rs +++ b/tests/ui/crashes/match_same_arms_const.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![deny(clippy::match_same_arms)] // Test for https://github.com/rust-lang/rust-clippy/issues/2427 diff --git a/tests/ui/crashes/needless_borrow_fp.rs b/tests/ui/crashes/needless_borrow_fp.rs index 4f61c76828db..68e39531682a 100644 --- a/tests/ui/crashes/needless_borrow_fp.rs +++ b/tests/ui/crashes/needless_borrow_fp.rs @@ -1,3 +1,5 @@ +//@ check-pass + #[deny(clippy::all)] #[derive(Debug)] pub enum Error { diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.fixed b/tests/ui/crashes/needless_lifetimes_impl_trait.fixed index 837069cae6d1..cc5ed052d264 100644 --- a/tests/ui/crashes/needless_lifetimes_impl_trait.fixed +++ b/tests/ui/crashes/needless_lifetimes_impl_trait.fixed @@ -10,10 +10,12 @@ struct Baz<'a> { } impl Foo for Baz<'_> {} +//~^ needless_lifetimes impl Bar { fn baz(&self) -> impl Foo + '_ { - //~^ ERROR: the following explicit lifetimes could be elided: 'a + //~^ needless_lifetimes + Baz { bar: self } } } diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.rs b/tests/ui/crashes/needless_lifetimes_impl_trait.rs index 06947e3a3513..258fb3118ef0 100644 --- a/tests/ui/crashes/needless_lifetimes_impl_trait.rs +++ b/tests/ui/crashes/needless_lifetimes_impl_trait.rs @@ -10,10 +10,12 @@ struct Baz<'a> { } impl<'a> Foo for Baz<'a> {} +//~^ needless_lifetimes impl Bar { fn baz<'a>(&'a self) -> impl Foo + 'a { - //~^ ERROR: the following explicit lifetimes could be elided: 'a + //~^ needless_lifetimes + Baz { bar: self } } } diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.stderr b/tests/ui/crashes/needless_lifetimes_impl_trait.stderr index bed6aab25c4d..97fb6d29cfbe 100644 --- a/tests/ui/crashes/needless_lifetimes_impl_trait.stderr +++ b/tests/ui/crashes/needless_lifetimes_impl_trait.stderr @@ -16,7 +16,7 @@ LL + impl Foo for Baz<'_> {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:15:12 + --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:16:12 | LL | fn baz<'a>(&'a self) -> impl Foo + 'a { | ^^ ^^ ^^ diff --git a/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed b/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed index 774dea391939..128ff4a1c036 100644 --- a/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed +++ b/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed @@ -5,6 +5,7 @@ struct Foo<'a>(&'a [(); 100]); fn test(x: &Foo<'_>) {} -//~^ ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value + fn main() {} diff --git a/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs b/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs index f3d8871929a2..b82cc831c6e0 100644 --- a/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs +++ b/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs @@ -5,6 +5,7 @@ struct Foo<'a>(&'a [(); 100]); fn test(x: Foo<'_>) {} -//~^ ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value + fn main() {} diff --git a/tests/ui/crashes/regressions.rs b/tests/ui/crashes/regressions.rs index b34997d4ee0b..8fda12fab06a 100644 --- a/tests/ui/crashes/regressions.rs +++ b/tests/ui/crashes/regressions.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(clippy::disallowed_names, clippy::uninlined_format_args)] pub fn foo(bar: *const u8) { diff --git a/tests/ui/crashes/returns.rs b/tests/ui/crashes/returns.rs index 91cdb5306c89..ccab9522753e 100644 --- a/tests/ui/crashes/returns.rs +++ b/tests/ui/crashes/returns.rs @@ -1,3 +1,4 @@ +//@ check-pass // Test for https://github.com/rust-lang/rust-clippy/issues/1346 #[deny(warnings)] diff --git a/tests/ui/crashes/shadow.rs b/tests/ui/crashes/shadow.rs index 843e8ef64dcd..237988a01681 100644 --- a/tests/ui/crashes/shadow.rs +++ b/tests/ui/crashes/shadow.rs @@ -1,3 +1,5 @@ +//@ check-pass + fn main() { let x: [i32; { let u = 2; diff --git a/tests/ui/crashes/single-match-else.rs b/tests/ui/crashes/single-match-else.rs index 1ba7ac082132..2ef5dd891c56 100644 --- a/tests/ui/crashes/single-match-else.rs +++ b/tests/ui/crashes/single-match-else.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::single_match_else)] //! Test for https://github.com/rust-lang/rust-clippy/issues/1588 diff --git a/tests/ui/crashes/third-party/conf_allowlisted.rs b/tests/ui/crashes/third-party/conf_allowlisted.rs index f328e4d9d04c..20c76a4d46d9 100644 --- a/tests/ui/crashes/third-party/conf_allowlisted.rs +++ b/tests/ui/crashes/third-party/conf_allowlisted.rs @@ -1 +1,3 @@ +//@ check-pass + fn main() {} diff --git a/tests/ui/crashes/trivial_bounds.rs b/tests/ui/crashes/trivial_bounds.rs index 60105a8213fe..23982fca7e7c 100644 --- a/tests/ui/crashes/trivial_bounds.rs +++ b/tests/ui/crashes/trivial_bounds.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(trivial_bounds)] #![allow(unused, trivial_bounds)] diff --git a/tests/ui/crashes/unreachable-array-or-slice.rs b/tests/ui/crashes/unreachable-array-or-slice.rs index e920e58d6ec6..bc2e9aa92ce1 100644 --- a/tests/ui/crashes/unreachable-array-or-slice.rs +++ b/tests/ui/crashes/unreachable-array-or-slice.rs @@ -2,6 +2,7 @@ struct Foo(isize, isize, isize, isize); pub fn main() { let Self::anything_here_kills_it(a, b, ..) = Foo(5, 5, 5, 5); + //~^ ERROR: failed to resolve match [5, 5, 5, 5] { [..] => {}, } diff --git a/tests/ui/crashes/used_underscore_binding_macro.rs b/tests/ui/crashes/used_underscore_binding_macro.rs index 901eb4e50398..0fff0afdf1fe 100644 --- a/tests/ui/crashes/used_underscore_binding_macro.rs +++ b/tests/ui/crashes/used_underscore_binding_macro.rs @@ -1,3 +1,5 @@ +//@ check-pass + use serde::Deserialize; /// Tests that we do not lint for unused underscores in a `MacroAttribute` diff --git a/tests/ui/crate_in_macro_def.fixed b/tests/ui/crate_in_macro_def.fixed index bd91389c8219..d7d8e2a64419 100644 --- a/tests/ui/crate_in_macro_def.fixed +++ b/tests/ui/crate_in_macro_def.fixed @@ -16,6 +16,7 @@ mod unhygienic { macro_rules! print_message_unhygienic { () => { println!("{}", $crate::unhygienic::MESSAGE); + //~^ crate_in_macro_def }; } diff --git a/tests/ui/crate_in_macro_def.rs b/tests/ui/crate_in_macro_def.rs index f6fa338eedbf..9ed9dacee48b 100644 --- a/tests/ui/crate_in_macro_def.rs +++ b/tests/ui/crate_in_macro_def.rs @@ -16,6 +16,7 @@ mod unhygienic { macro_rules! print_message_unhygienic { () => { println!("{}", crate::unhygienic::MESSAGE); + //~^ crate_in_macro_def }; } diff --git a/tests/ui/crate_level_checks/entrypoint_recursion.rs b/tests/ui/crate_level_checks/entrypoint_recursion.rs index 5d853d97bc35..3ded902e36b1 100644 --- a/tests/ui/crate_level_checks/entrypoint_recursion.rs +++ b/tests/ui/crate_level_checks/entrypoint_recursion.rs @@ -1,3 +1,4 @@ +//@check-pass //@ignore-target: apple #![feature(rustc_attrs)] diff --git a/tests/ui/crate_level_checks/no_std_swap.rs b/tests/ui/crate_level_checks/no_std_swap.rs index 536e71b4a25a..e332e10ea4ba 100644 --- a/tests/ui/crate_level_checks/no_std_swap.rs +++ b/tests/ui/crate_level_checks/no_std_swap.rs @@ -9,7 +9,8 @@ pub fn main() { let mut b = 1337; a = b; - //~^ ERROR: this looks like you are trying to swap `a` and `b` - //~| NOTE: or maybe you should use `core::mem::replace`? + //~^ almost_swapped + + b = a; } diff --git a/tests/ui/crate_level_checks/std_main_recursion.rs b/tests/ui/crate_level_checks/std_main_recursion.rs index c2c3e0958ec7..b582d560668a 100644 --- a/tests/ui/crate_level_checks/std_main_recursion.rs +++ b/tests/ui/crate_level_checks/std_main_recursion.rs @@ -3,5 +3,6 @@ fn main() { println!("Hello, World!"); main(); - //~^ ERROR: recursing into entrypoint `main` + //~^ main_recursion + } diff --git a/tests/ui/create_dir.fixed b/tests/ui/create_dir.fixed index 8fbf7dd19b83..4a5b1b77be6b 100644 --- a/tests/ui/create_dir.fixed +++ b/tests/ui/create_dir.fixed @@ -8,7 +8,9 @@ fn create_dir() {} fn main() { // Should be warned create_dir_all("foo"); + //~^ create_dir create_dir_all("bar").unwrap(); + //~^ create_dir // Shouldn't be warned create_dir(); diff --git a/tests/ui/create_dir.rs b/tests/ui/create_dir.rs index af2c326ec436..bf185ba3a7c3 100644 --- a/tests/ui/create_dir.rs +++ b/tests/ui/create_dir.rs @@ -8,7 +8,9 @@ fn create_dir() {} fn main() { // Should be warned std::fs::create_dir("foo"); + //~^ create_dir std::fs::create_dir("bar").unwrap(); + //~^ create_dir // Shouldn't be warned create_dir(); diff --git a/tests/ui/create_dir.stderr b/tests/ui/create_dir.stderr index ab51705bb55a..2aba2944aa60 100644 --- a/tests/ui/create_dir.stderr +++ b/tests/ui/create_dir.stderr @@ -12,7 +12,7 @@ LL | create_dir_all("foo"); | ~~~~~~~~~~~~~~~~~~~~~ error: calling `std::fs::create_dir` where there may be a better way - --> tests/ui/create_dir.rs:11:5 + --> tests/ui/create_dir.rs:12:5 | LL | std::fs::create_dir("bar").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/dbg_macro/dbg_macro.fixed b/tests/ui/dbg_macro/dbg_macro.fixed index bda9221a5e1e..de715db8faab 100644 --- a/tests/ui/dbg_macro/dbg_macro.fixed +++ b/tests/ui/dbg_macro/dbg_macro.fixed @@ -3,28 +3,35 @@ fn foo(n: u32) -> u32 { if let Some(n) = n.checked_sub(4) { n } else { n } - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } fn bar(_: ()) {} fn factorial(n: u32) -> u32 { if n <= 1 { - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + 1 - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } else { n * factorial(n - 1) - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } } fn main() { 42; - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + foo(3) + factorial(4); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + (1, 2, 3, 4, 5); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } fn issue9914() { @@ -41,21 +48,27 @@ fn issue9914() { macro_rules! expand_to_dbg { () => { - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + }; } - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + #[allow(clippy::let_unit_value)] let _ = (); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + bar(()); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + foo!(()); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + foo2!(foo!(())); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + expand_to_dbg!(); } @@ -77,35 +90,41 @@ mod issue7274 { struct MyThing; define_thing!(MyThing, { 2; - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + }); } #[test] pub fn issue8481() { 1; - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } #[cfg(test)] fn foo2() { 1; - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } #[cfg(test)] mod mod1 { fn func() { 1; - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } } mod issue12131 { fn dbg_in_print(s: &str) { println!("dbg: {:?}", s); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + print!("{}", s); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } } diff --git a/tests/ui/dbg_macro/dbg_macro.rs b/tests/ui/dbg_macro/dbg_macro.rs index 8244254026be..90a72d131667 100644 --- a/tests/ui/dbg_macro/dbg_macro.rs +++ b/tests/ui/dbg_macro/dbg_macro.rs @@ -3,28 +3,35 @@ fn foo(n: u32) -> u32 { if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } fn bar(_: ()) {} fn factorial(n: u32) -> u32 { if dbg!(n <= 1) { - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + dbg!(1) - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } else { dbg!(n * factorial(n - 1)) - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } } fn main() { dbg!(42); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + foo(3) + dbg!(factorial(4)); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + dbg!(1, 2, 3, 4, 5); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } fn issue9914() { @@ -41,21 +48,27 @@ fn issue9914() { macro_rules! expand_to_dbg { () => { dbg!(); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + }; } dbg!(); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + #[allow(clippy::let_unit_value)] let _ = dbg!(); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + bar(dbg!()); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + foo!(dbg!()); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + foo2!(foo!(dbg!())); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + expand_to_dbg!(); } @@ -77,35 +90,41 @@ mod issue7274 { struct MyThing; define_thing!(MyThing, { dbg!(2); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + }); } #[test] pub fn issue8481() { dbg!(1); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } #[cfg(test)] fn foo2() { dbg!(1); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } #[cfg(test)] mod mod1 { fn func() { dbg!(1); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } } mod issue12131 { fn dbg_in_print(s: &str) { println!("dbg: {:?}", dbg!(s)); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + print!("{}", dbg!(s)); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + } } diff --git a/tests/ui/dbg_macro/dbg_macro.stderr b/tests/ui/dbg_macro/dbg_macro.stderr index b3d74b9ff617..ee0cfc12b347 100644 --- a/tests/ui/dbg_macro/dbg_macro.stderr +++ b/tests/ui/dbg_macro/dbg_macro.stderr @@ -12,7 +12,7 @@ LL | if let Some(n) = n.checked_sub(4) { n } else { n } | ~~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:11:8 + --> tests/ui/dbg_macro/dbg_macro.rs:12:8 | LL | if dbg!(n <= 1) { | ^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | if n <= 1 { | ~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:13:9 + --> tests/ui/dbg_macro/dbg_macro.rs:15:9 | LL | dbg!(1) | ^^^^^^^ @@ -34,7 +34,7 @@ LL | 1 | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:16:9 + --> tests/ui/dbg_macro/dbg_macro.rs:19:9 | LL | dbg!(n * factorial(n - 1)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | n * factorial(n - 1) | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:22:5 + --> tests/ui/dbg_macro/dbg_macro.rs:26:5 | LL | dbg!(42); | ^^^^^^^^ @@ -56,7 +56,7 @@ LL | 42; | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:24:14 + --> tests/ui/dbg_macro/dbg_macro.rs:29:14 | LL | foo(3) + dbg!(factorial(4)); | ^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | foo(3) + factorial(4); | ~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:26:5 + --> tests/ui/dbg_macro/dbg_macro.rs:32:5 | LL | dbg!(1, 2, 3, 4, 5); | ^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | (1, 2, 3, 4, 5); | ~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:48:5 + --> tests/ui/dbg_macro/dbg_macro.rs:56:5 | LL | dbg!(); | ^^^^^^ @@ -89,7 +89,7 @@ LL - dbg!(); | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:51:13 + --> tests/ui/dbg_macro/dbg_macro.rs:60:13 | LL | let _ = dbg!(); | ^^^^^^ @@ -100,7 +100,7 @@ LL | let _ = (); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:53:9 + --> tests/ui/dbg_macro/dbg_macro.rs:63:9 | LL | bar(dbg!()); | ^^^^^^ @@ -111,7 +111,7 @@ LL | bar(()); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:55:10 + --> tests/ui/dbg_macro/dbg_macro.rs:66:10 | LL | foo!(dbg!()); | ^^^^^^ @@ -122,7 +122,7 @@ LL | foo!(()); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:57:16 + --> tests/ui/dbg_macro/dbg_macro.rs:69:16 | LL | foo2!(foo!(dbg!())); | ^^^^^^ @@ -133,7 +133,7 @@ LL | foo2!(foo!(())); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:43:13 + --> tests/ui/dbg_macro/dbg_macro.rs:50:13 | LL | dbg!(); | ^^^^^^ @@ -148,7 +148,7 @@ LL - dbg!(); | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:79:9 + --> tests/ui/dbg_macro/dbg_macro.rs:92:9 | LL | dbg!(2); | ^^^^^^^ @@ -159,7 +159,7 @@ LL | 2; | ~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:86:5 + --> tests/ui/dbg_macro/dbg_macro.rs:100:5 | LL | dbg!(1); | ^^^^^^^ @@ -170,7 +170,7 @@ LL | 1; | ~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:92:5 + --> tests/ui/dbg_macro/dbg_macro.rs:107:5 | LL | dbg!(1); | ^^^^^^^ @@ -181,7 +181,7 @@ LL | 1; | ~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:99:9 + --> tests/ui/dbg_macro/dbg_macro.rs:115:9 | LL | dbg!(1); | ^^^^^^^ @@ -192,7 +192,7 @@ LL | 1; | ~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:106:31 + --> tests/ui/dbg_macro/dbg_macro.rs:123:31 | LL | println!("dbg: {:?}", dbg!(s)); | ^^^^^^^ @@ -203,7 +203,7 @@ LL | println!("dbg: {:?}", s); | ~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:108:22 + --> tests/ui/dbg_macro/dbg_macro.rs:126:22 | LL | print!("{}", dbg!(s)); | ^^^^^^^ diff --git a/tests/ui/dbg_macro/dbg_macro_unfixable.rs b/tests/ui/dbg_macro/dbg_macro_unfixable.rs index 0e83766ccaec..bd16306b89db 100644 --- a/tests/ui/dbg_macro/dbg_macro_unfixable.rs +++ b/tests/ui/dbg_macro/dbg_macro_unfixable.rs @@ -1,4 +1,5 @@ //@no-rustfix +//@error-in-other-file: #![warn(clippy::dbg_macro)] #[path = "auxiliary/submodule.rs"] @@ -6,7 +7,12 @@ mod submodule; fn main() { dbg!(dbg!(dbg!(42))); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + //~| dbg_macro + //~| dbg_macro + dbg!(1, 2, dbg!(3, 4)); - //~^ ERROR: the `dbg!` macro is intended as a debugging tool + //~^ dbg_macro + //~| dbg_macro + } diff --git a/tests/ui/dbg_macro/dbg_macro_unfixable.stderr b/tests/ui/dbg_macro/dbg_macro_unfixable.stderr index b8e91906b931..df053a7a5f21 100644 --- a/tests/ui/dbg_macro/dbg_macro_unfixable.stderr +++ b/tests/ui/dbg_macro/dbg_macro_unfixable.stderr @@ -12,7 +12,7 @@ LL - dbg!(); | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:8:5 + --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:9:5 | LL | dbg!(dbg!(dbg!(42))); | ^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | dbg!(dbg!(42)); | ~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:8:10 + --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:9:10 | LL | dbg!(dbg!(dbg!(42))); | ^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | dbg!(dbg!(42)); | ~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:8:15 + --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:9:15 | LL | dbg!(dbg!(dbg!(42))); | ^^^^^^^^ @@ -45,7 +45,7 @@ LL | dbg!(dbg!(42)); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:10:5 + --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:14:5 | LL | dbg!(1, 2, dbg!(3, 4)); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | (1, 2, dbg!(3, 4)); | ~~~~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:10:16 + --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:14:16 | LL | dbg!(1, 2, dbg!(3, 4)); | ^^^^^^^^^^ diff --git a/tests/ui/debug_assert_with_mut_call.rs b/tests/ui/debug_assert_with_mut_call.rs index 8d04be777c7b..74d59b7593fa 100644 --- a/tests/ui/debug_assert_with_mut_call.rs +++ b/tests/ui/debug_assert_with_mut_call.rs @@ -40,20 +40,26 @@ fn func_non_mutable() { fn func_mutable() { debug_assert!(bool_mut(&mut 3)); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` - //~| NOTE: `-D clippy::debug-assert-with-mut-call` implied by `-D warnings` + //~^ debug_assert_with_mut_call + + debug_assert!(!bool_mut(&mut 3)); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + debug_assert_eq!(0, u32_mut(&mut 3)); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!` + //~^ debug_assert_with_mut_call + debug_assert_eq!(u32_mut(&mut 3), 0); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!` + //~^ debug_assert_with_mut_call + debug_assert_ne!(1, u32_mut(&mut 3)); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!` + //~^ debug_assert_with_mut_call + debug_assert_ne!(u32_mut(&mut 3), 1); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!` + //~^ debug_assert_with_mut_call + } fn method_non_mutable() { @@ -69,33 +75,46 @@ fn method_non_mutable() { fn method_mutable() { debug_assert!(S.bool_self_mut()); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + debug_assert!(!S.bool_self_mut()); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + debug_assert!(S.bool_self_ref_arg_mut(&mut 3)); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + debug_assert!(S.bool_self_mut_arg_ref(&3)); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + debug_assert!(S.bool_self_mut_arg_mut(&mut 3)); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + debug_assert_eq!(S.u32_self_mut(), 0); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!` + //~^ debug_assert_with_mut_call + debug_assert_eq!(S.u32_self_mut_arg_ref(&3), 0); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!` + //~^ debug_assert_with_mut_call + debug_assert_eq!(S.u32_self_ref_arg_mut(&mut 3), 0); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!` + //~^ debug_assert_with_mut_call + debug_assert_eq!(S.u32_self_mut_arg_mut(&mut 3), 0); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!` + //~^ debug_assert_with_mut_call + debug_assert_ne!(S.u32_self_mut(), 1); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!` + //~^ debug_assert_with_mut_call + debug_assert_ne!(S.u32_self_mut_arg_ref(&3), 1); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!` + //~^ debug_assert_with_mut_call + debug_assert_ne!(S.u32_self_ref_arg_mut(&mut 3), 1); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!` + //~^ debug_assert_with_mut_call + debug_assert_ne!(S.u32_self_mut_arg_mut(&mut 3), 1); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!` + //~^ debug_assert_with_mut_call + } fn misc() { @@ -104,35 +123,43 @@ fn misc() { debug_assert_eq!(v.get(0), Some(&1)); debug_assert_ne!(v[0], 2); debug_assert_eq!(v.pop(), Some(1)); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!` + //~^ debug_assert_with_mut_call + debug_assert_ne!(Some(3), v.pop()); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!` + //~^ debug_assert_with_mut_call + let a = &mut 3; debug_assert!(bool_mut(a)); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + // nested debug_assert!(!(bool_ref(&u32_mut(&mut 3)))); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + // chained debug_assert_eq!(v.pop().unwrap(), 3); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!` + //~^ debug_assert_with_mut_call + // format args debug_assert!(bool_ref(&3), "w/o format"); debug_assert!(bool_mut(&mut 3), "w/o format"); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + debug_assert!(bool_ref(&3), "{} format", "w/"); debug_assert!(bool_mut(&mut 3), "{} format", "w/"); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!` + //~^ debug_assert_with_mut_call + // sub block let mut x = 42_u32; debug_assert!({ bool_mut(&mut x); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert! + //~^ debug_assert_with_mut_call + x > 10 }); @@ -140,7 +167,8 @@ fn misc() { debug_assert!((|| { let mut x = 42; bool_mut(&mut x); - //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert! + //~^ debug_assert_with_mut_call + x > 10 })()); } diff --git a/tests/ui/debug_assert_with_mut_call.stderr b/tests/ui/debug_assert_with_mut_call.stderr index 83e1105a07df..216ab27264c1 100644 --- a/tests/ui/debug_assert_with_mut_call.stderr +++ b/tests/ui/debug_assert_with_mut_call.stderr @@ -8,163 +8,163 @@ LL | debug_assert!(bool_mut(&mut 3)); = help: to override `-D warnings` add `#[allow(clippy::debug_assert_with_mut_call)]` error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:45:20 + --> tests/ui/debug_assert_with_mut_call.rs:46:20 | LL | debug_assert!(!bool_mut(&mut 3)); | ^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_eq!` - --> tests/ui/debug_assert_with_mut_call.rs:48:25 + --> tests/ui/debug_assert_with_mut_call.rs:50:25 | LL | debug_assert_eq!(0, u32_mut(&mut 3)); | ^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_eq!` - --> tests/ui/debug_assert_with_mut_call.rs:50:22 + --> tests/ui/debug_assert_with_mut_call.rs:53:22 | LL | debug_assert_eq!(u32_mut(&mut 3), 0); | ^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_ne!` - --> tests/ui/debug_assert_with_mut_call.rs:53:25 + --> tests/ui/debug_assert_with_mut_call.rs:57:25 | LL | debug_assert_ne!(1, u32_mut(&mut 3)); | ^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_ne!` - --> tests/ui/debug_assert_with_mut_call.rs:55:22 + --> tests/ui/debug_assert_with_mut_call.rs:60:22 | LL | debug_assert_ne!(u32_mut(&mut 3), 1); | ^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:71:19 + --> tests/ui/debug_assert_with_mut_call.rs:77:19 | LL | debug_assert!(S.bool_self_mut()); | ^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:73:20 + --> tests/ui/debug_assert_with_mut_call.rs:80:20 | LL | debug_assert!(!S.bool_self_mut()); | ^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:75:19 + --> tests/ui/debug_assert_with_mut_call.rs:83:19 | LL | debug_assert!(S.bool_self_ref_arg_mut(&mut 3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:77:19 + --> tests/ui/debug_assert_with_mut_call.rs:86:19 | LL | debug_assert!(S.bool_self_mut_arg_ref(&3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:79:19 + --> tests/ui/debug_assert_with_mut_call.rs:89:19 | LL | debug_assert!(S.bool_self_mut_arg_mut(&mut 3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_eq!` - --> tests/ui/debug_assert_with_mut_call.rs:82:22 + --> tests/ui/debug_assert_with_mut_call.rs:93:22 | LL | debug_assert_eq!(S.u32_self_mut(), 0); | ^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_eq!` - --> tests/ui/debug_assert_with_mut_call.rs:84:22 + --> tests/ui/debug_assert_with_mut_call.rs:96:22 | LL | debug_assert_eq!(S.u32_self_mut_arg_ref(&3), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_eq!` - --> tests/ui/debug_assert_with_mut_call.rs:86:22 + --> tests/ui/debug_assert_with_mut_call.rs:99:22 | LL | debug_assert_eq!(S.u32_self_ref_arg_mut(&mut 3), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_eq!` - --> tests/ui/debug_assert_with_mut_call.rs:88:22 + --> tests/ui/debug_assert_with_mut_call.rs:102:22 | LL | debug_assert_eq!(S.u32_self_mut_arg_mut(&mut 3), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_ne!` - --> tests/ui/debug_assert_with_mut_call.rs:91:22 + --> tests/ui/debug_assert_with_mut_call.rs:106:22 | LL | debug_assert_ne!(S.u32_self_mut(), 1); | ^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_ne!` - --> tests/ui/debug_assert_with_mut_call.rs:93:22 + --> tests/ui/debug_assert_with_mut_call.rs:109:22 | LL | debug_assert_ne!(S.u32_self_mut_arg_ref(&3), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_ne!` - --> tests/ui/debug_assert_with_mut_call.rs:95:22 + --> tests/ui/debug_assert_with_mut_call.rs:112:22 | LL | debug_assert_ne!(S.u32_self_ref_arg_mut(&mut 3), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_ne!` - --> tests/ui/debug_assert_with_mut_call.rs:97:22 + --> tests/ui/debug_assert_with_mut_call.rs:115:22 | LL | debug_assert_ne!(S.u32_self_mut_arg_mut(&mut 3), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_eq!` - --> tests/ui/debug_assert_with_mut_call.rs:106:22 + --> tests/ui/debug_assert_with_mut_call.rs:125:22 | LL | debug_assert_eq!(v.pop(), Some(1)); | ^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_ne!` - --> tests/ui/debug_assert_with_mut_call.rs:108:31 + --> tests/ui/debug_assert_with_mut_call.rs:128:31 | LL | debug_assert_ne!(Some(3), v.pop()); | ^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:112:19 + --> tests/ui/debug_assert_with_mut_call.rs:133:19 | LL | debug_assert!(bool_mut(a)); | ^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:116:31 + --> tests/ui/debug_assert_with_mut_call.rs:138:31 | LL | debug_assert!(!(bool_ref(&u32_mut(&mut 3)))); | ^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert_eq!` - --> tests/ui/debug_assert_with_mut_call.rs:120:22 + --> tests/ui/debug_assert_with_mut_call.rs:143:22 | LL | debug_assert_eq!(v.pop().unwrap(), 3); | ^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:125:19 + --> tests/ui/debug_assert_with_mut_call.rs:149:19 | LL | debug_assert!(bool_mut(&mut 3), "w/o format"); | ^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:128:19 + --> tests/ui/debug_assert_with_mut_call.rs:153:19 | LL | debug_assert!(bool_mut(&mut 3), "{} format", "w/"); | ^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:134:9 + --> tests/ui/debug_assert_with_mut_call.rs:160:9 | LL | bool_mut(&mut x); | ^^^^^^^^^^^^^^^^ error: do not call a function with mutable arguments inside of `debug_assert!` - --> tests/ui/debug_assert_with_mut_call.rs:142:9 + --> tests/ui/debug_assert_with_mut_call.rs:169:9 | LL | bool_mut(&mut x); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/decimal_literal_representation.fixed b/tests/ui/decimal_literal_representation.fixed index e34f48b65dd1..e0477578488c 100644 --- a/tests/ui/decimal_literal_representation.fixed +++ b/tests/ui/decimal_literal_representation.fixed @@ -14,12 +14,19 @@ fn main() { ); let bad = ( // Hex: 0x8005, // 0x8005 + //~^ decimal_literal_representation 0xFF00, // 0xFF00 + //~^ decimal_literal_representation 0x7F0F_F00F, // 0x7F0F_F00F + //~^ decimal_literal_representation 0x7FFF_FFFF, // 0x7FFF_FFFF + //~^ decimal_literal_representation #[allow(overflowing_literals)] 0xF0F0_F0F0, // 0xF0F0_F0F0 + //~^ decimal_literal_representation 0x8005_usize, // 0x8005_usize + //~^ decimal_literal_representation 0x7F0F_F00F_isize, // 0x7F0F_F00F_isize + //~^ decimal_literal_representation ); } diff --git a/tests/ui/decimal_literal_representation.rs b/tests/ui/decimal_literal_representation.rs index bcc4d0df9c0e..85dc4fac0928 100644 --- a/tests/ui/decimal_literal_representation.rs +++ b/tests/ui/decimal_literal_representation.rs @@ -14,12 +14,19 @@ fn main() { ); let bad = ( // Hex: 32_773, // 0x8005 + //~^ decimal_literal_representation 65_280, // 0xFF00 + //~^ decimal_literal_representation 2_131_750_927, // 0x7F0F_F00F + //~^ decimal_literal_representation 2_147_483_647, // 0x7FFF_FFFF + //~^ decimal_literal_representation #[allow(overflowing_literals)] 4_042_322_160, // 0xF0F0_F0F0 + //~^ decimal_literal_representation 32_773usize, // 0x8005_usize + //~^ decimal_literal_representation 2_131_750_927isize, // 0x7F0F_F00F_isize + //~^ decimal_literal_representation ); } diff --git a/tests/ui/decimal_literal_representation.stderr b/tests/ui/decimal_literal_representation.stderr index 824e7ec85ee0..0196350ce402 100644 --- a/tests/ui/decimal_literal_representation.stderr +++ b/tests/ui/decimal_literal_representation.stderr @@ -8,37 +8,37 @@ LL | 32_773, // 0x8005 = help: to override `-D warnings` add `#[allow(clippy::decimal_literal_representation)]` error: integer literal has a better hexadecimal representation - --> tests/ui/decimal_literal_representation.rs:17:9 + --> tests/ui/decimal_literal_representation.rs:18:9 | LL | 65_280, // 0xFF00 | ^^^^^^ help: consider: `0xFF00` error: integer literal has a better hexadecimal representation - --> tests/ui/decimal_literal_representation.rs:18:9 + --> tests/ui/decimal_literal_representation.rs:20:9 | LL | 2_131_750_927, // 0x7F0F_F00F | ^^^^^^^^^^^^^ help: consider: `0x7F0F_F00F` error: integer literal has a better hexadecimal representation - --> tests/ui/decimal_literal_representation.rs:19:9 + --> tests/ui/decimal_literal_representation.rs:22:9 | LL | 2_147_483_647, // 0x7FFF_FFFF | ^^^^^^^^^^^^^ help: consider: `0x7FFF_FFFF` error: integer literal has a better hexadecimal representation - --> tests/ui/decimal_literal_representation.rs:21:9 + --> tests/ui/decimal_literal_representation.rs:25:9 | LL | 4_042_322_160, // 0xF0F0_F0F0 | ^^^^^^^^^^^^^ help: consider: `0xF0F0_F0F0` error: integer literal has a better hexadecimal representation - --> tests/ui/decimal_literal_representation.rs:22:9 + --> tests/ui/decimal_literal_representation.rs:27:9 | LL | 32_773usize, // 0x8005_usize | ^^^^^^^^^^^ help: consider: `0x8005_usize` error: integer literal has a better hexadecimal representation - --> tests/ui/decimal_literal_representation.rs:23:9 + --> tests/ui/decimal_literal_representation.rs:29:9 | LL | 2_131_750_927isize, // 0x7F0F_F00F_isize | ^^^^^^^^^^^^^^^^^^ help: consider: `0x7F0F_F00F_isize` diff --git a/tests/ui/declare_interior_mutable_const/enums.rs b/tests/ui/declare_interior_mutable_const/enums.rs index a88bf7b21b8b..0f454786156e 100644 --- a/tests/ui/declare_interior_mutable_const/enums.rs +++ b/tests/ui/declare_interior_mutable_const/enums.rs @@ -9,7 +9,8 @@ enum OptionalCell { } // a constant with enums should be linted only when the used variant is unfrozen (#3962). -const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); //~ ERROR: interior mutable +const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); +//~^ declare_interior_mutable_const const FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen; const fn unfrozen_variant() -> OptionalCell { @@ -20,7 +21,8 @@ const fn frozen_variant() -> OptionalCell { OptionalCell::Frozen } -const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); //~ ERROR: interior mutable +const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); +//~^ declare_interior_mutable_const const FROZEN_VARIANT_FROM_FN: OptionalCell = frozen_variant(); enum NestedInnermost { @@ -43,7 +45,8 @@ struct NestedOutermost { // a constant with enums should be linted according to its value, no matter how structs involve. const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost { - //~^ ERROR: interior mutable +//~^ declare_interior_mutable_const + outer: NestedOuter::NestedInner(NestedInner { inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)), }), @@ -57,11 +60,14 @@ const NESTED_FROZEN_VARIANT: NestedOutermost = NestedOutermost { trait AssocConsts { // When there's no default value, lint it only according to its type. // Further details are on the corresponding code (`NonCopyConst::check_trait_item`). - const TO_BE_UNFROZEN_VARIANT: OptionalCell; //~ ERROR: interior mutable - const TO_BE_FROZEN_VARIANT: OptionalCell; //~ ERROR: interior mutable +const TO_BE_UNFROZEN_VARIANT: OptionalCell; +//~^ declare_interior_mutable_const +const TO_BE_FROZEN_VARIANT: OptionalCell; +//~^ declare_interior_mutable_const // Lint default values accordingly. - const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); //~ ERROR: interior mutable +const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); +//~^ declare_interior_mutable_const const DEFAULTED_ON_FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen; } @@ -87,7 +93,8 @@ trait AssocTypes { impl AssocTypes for u64 { type ToBeUnfrozen = AtomicUsize; - const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); //~ ERROR: interior mutable +const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); +//~^ declare_interior_mutable_const const TO_BE_FROZEN_VARIANT: Option = None; } @@ -99,25 +106,30 @@ enum BothOfCellAndGeneric { } impl BothOfCellAndGeneric { - const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR: interior mutable +const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); +//~^ declare_interior_mutable_const // This is a false positive. The argument about this is on `is_value_unfrozen_raw` - const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR: interior mutable +const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); +//~^ declare_interior_mutable_const const FROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Frozen(5); // This is what is likely to be a false negative when one tries to fix // the `GENERIC_VARIANT` false positive. - const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); //~ ERROR: interior mutable +const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); +//~^ declare_interior_mutable_const } // associated types here is basically the same as the one above. trait BothOfCellAndGenericWithAssocType { type AssocType; - const UNFROZEN_VARIANT: BothOfCellAndGeneric = //~ ERROR: interior mutable +const UNFROZEN_VARIANT: BothOfCellAndGeneric = +//~^ declare_interior_mutable_const BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); - const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR: interior mutable +const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); +//~^ declare_interior_mutable_const const FROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Frozen(5); } diff --git a/tests/ui/declare_interior_mutable_const/enums.stderr b/tests/ui/declare_interior_mutable_const/enums.stderr index 22329172c3af..a6f14ec71feb 100644 --- a/tests/ui/declare_interior_mutable_const/enums.stderr +++ b/tests/ui/declare_interior_mutable_const/enums.stderr @@ -9,7 +9,7 @@ LL | const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(tru = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:23:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:24:1 | LL | const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,10 +17,11 @@ LL | const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); = help: consider making this `Sync` so that it can go in a static item or using a `thread_local` error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:45:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:47:1 | LL | / const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost { LL | | +LL | | LL | | outer: NestedOuter::NestedInner(NestedInner { LL | | inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)), LL | | }), @@ -30,59 +31,60 @@ LL | | }; = help: consider making this a static item error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:60:5 + --> tests/ui/declare_interior_mutable_const/enums.rs:63:1 | -LL | const TO_BE_UNFROZEN_VARIANT: OptionalCell; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_UNFROZEN_VARIANT: OptionalCell; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:61:5 + --> tests/ui/declare_interior_mutable_const/enums.rs:65:1 | -LL | const TO_BE_FROZEN_VARIANT: OptionalCell; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_FROZEN_VARIANT: OptionalCell; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:64:5 + --> tests/ui/declare_interior_mutable_const/enums.rs:69:1 | -LL | const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:90:5 + --> tests/ui/declare_interior_mutable_const/enums.rs:96:1 | -LL | const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:102:5 + --> tests/ui/declare_interior_mutable_const/enums.rs:109:1 | -LL | const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:105:5 + --> tests/ui/declare_interior_mutable_const/enums.rs:113:1 | -LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:111:5 + --> tests/ui/declare_interior_mutable_const/enums.rs:120:1 | -LL | const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:118:5 + --> tests/ui/declare_interior_mutable_const/enums.rs:128:1 | -LL | / const UNFROZEN_VARIANT: BothOfCellAndGeneric = +LL | / const UNFROZEN_VARIANT: BothOfCellAndGeneric = +LL | | LL | | BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); | |____________________________________________________________________^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:120:5 + --> tests/ui/declare_interior_mutable_const/enums.rs:131:1 | -LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 12 previous errors diff --git a/tests/ui/declare_interior_mutable_const/others.rs b/tests/ui/declare_interior_mutable_const/others.rs index 0dccf18c4930..9820626ae454 100644 --- a/tests/ui/declare_interior_mutable_const/others.rs +++ b/tests/ui/declare_interior_mutable_const/others.rs @@ -7,15 +7,19 @@ use std::ptr; use std::sync::Once; use std::sync::atomic::AtomicUsize; -const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR: interior mutable -const CELL: Cell = Cell::new(6); //~ ERROR: interior mutable +const ATOMIC: AtomicUsize = AtomicUsize::new(5); +//~^ declare_interior_mutable_const +const CELL: Cell = Cell::new(6); +//~^ declare_interior_mutable_const const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec, u8) = ([ATOMIC], Vec::new(), 7); -//~^ ERROR: interior mutable +//~^ declare_interior_mutable_const + macro_rules! declare_const { ($name:ident: $ty:ty = $e:expr) => { const $name: $ty = $e; - //~^ ERROR: interior mutable + //~^ declare_interior_mutable_const + }; } declare_const!(_ONCE: Once = Once::new()); @@ -43,6 +47,7 @@ mod issue_8493 { macro_rules! issue_8493 { () => { const _BAZ: Cell = Cell::new(0); + //~^ declare_interior_mutable_const static _FOOBAR: () = { thread_local! { static _VAR: Cell = const { Cell::new(0) }; diff --git a/tests/ui/declare_interior_mutable_const/others.stderr b/tests/ui/declare_interior_mutable_const/others.stderr index 4a7251471424..3c388e3bcf37 100644 --- a/tests/ui/declare_interior_mutable_const/others.stderr +++ b/tests/ui/declare_interior_mutable_const/others.stderr @@ -9,7 +9,7 @@ LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:11:1 + --> tests/ui/declare_interior_mutable_const/others.rs:12:1 | LL | const CELL: Cell = Cell::new(6); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | const CELL: Cell = Cell::new(6); = help: consider making this `Sync` so that it can go in a static item or using a `thread_local` error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:12:1 + --> tests/ui/declare_interior_mutable_const/others.rs:14:1 | LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec, u8) = ([ATOMIC], Vec::new(), 7); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec, u8) = ([ATOMIC], V = help: consider making this a static item error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:17:9 + --> tests/ui/declare_interior_mutable_const/others.rs:20:9 | LL | const $name: $ty = $e; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | declare_const!(_ONCE: Once = Once::new()); = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:45:13 + --> tests/ui/declare_interior_mutable_const/others.rs:49:13 | LL | const _BAZ: Cell = Cell::new(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/declare_interior_mutable_const/traits.rs b/tests/ui/declare_interior_mutable_const/traits.rs index 490073f97fb1..83d6c1307ea2 100644 --- a/tests/ui/declare_interior_mutable_const/traits.rs +++ b/tests/ui/declare_interior_mutable_const/traits.rs @@ -7,13 +7,15 @@ use std::sync::atomic::AtomicUsize; macro_rules! declare_const { ($name:ident: $ty:ty = $e:expr) => { const $name: $ty = $e; - //~^ ERROR: interior mutable + //~^ declare_interior_mutable_const + }; } // a constant whose type is a concrete type should be linted at the definition site. trait ConcreteTypes { - const ATOMIC: AtomicUsize; //~ ERROR: interior mutable +const ATOMIC: AtomicUsize; +//~^ declare_interior_mutable_const const INTEGER: u64; const STRING: String; declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); @@ -41,7 +43,8 @@ trait GenericTypes { impl GenericTypes for u64 { const TO_REMAIN_GENERIC: T = T::DEFAULT; - const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR: interior mutable +const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); +//~^ declare_interior_mutable_const } // a helper type used below @@ -66,8 +69,10 @@ impl AssocTypes for Vec { type ToBeGenericParam = T; const TO_BE_FROZEN: Self::ToBeFrozen = 12; - const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR: interior mutable - const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); //~ ERROR: interior mutable +const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); +//~^ declare_interior_mutable_const +const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); +//~^ declare_interior_mutable_const const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper = Wrapper(T::DEFAULT); } @@ -86,7 +91,8 @@ where T: AssocTypesHelper, { const NOT_BOUNDED: T::NotToBeBounded; - const BOUNDED: T::ToBeBounded; //~ ERROR: interior mutable +const BOUNDED: T::ToBeBounded; +//~^ declare_interior_mutable_const } impl AssocTypesFromGenericParam for u64 @@ -114,19 +120,24 @@ impl SelfType for u64 { impl SelfType for AtomicUsize { // this (interior mutable `Self` const) exists in `parking_lot`. // `const_trait_impl` will replace it in the future, hopefully. - const SELF: Self = AtomicUsize::new(17); //~ ERROR: interior mutable - const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); //~ ERROR: interior mutable +const SELF: Self = AtomicUsize::new(17); +//~^ declare_interior_mutable_const +const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); +//~^ declare_interior_mutable_const } // Even though a constant contains a generic type, if it also have an interior mutable type, // it should be linted at the definition site. trait BothOfCellAndGeneric { - const DIRECT: Cell; //~ ERROR: interior mutable - const INDIRECT: Cell<*const T>; //~ ERROR: interior mutable +const DIRECT: Cell; +//~^ declare_interior_mutable_const +const INDIRECT: Cell<*const T>; +//~^ declare_interior_mutable_const } impl BothOfCellAndGeneric for u64 { - const DIRECT: Cell = Cell::new(T::DEFAULT); //~ ERROR: interior mutable +const DIRECT: Cell = Cell::new(T::DEFAULT); +//~^ declare_interior_mutable_const const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null()); } @@ -138,13 +149,15 @@ impl Local where T: ConstDefault + AssocTypesHelper, { - const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR: interior mutable +const ATOMIC: AtomicUsize = AtomicUsize::new(18); +//~^ declare_interior_mutable_const const COW: Cow<'static, str> = Cow::Borrowed("tuvwxy"); const GENERIC_TYPE: T = T::DEFAULT; const ASSOC_TYPE: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED; - const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR: interior mutable +const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); +//~^ declare_interior_mutable_const } fn main() {} diff --git a/tests/ui/declare_interior_mutable_const/traits.stderr b/tests/ui/declare_interior_mutable_const/traits.stderr index 4a793d985e5e..1be6b9d2ec60 100644 --- a/tests/ui/declare_interior_mutable_const/traits.stderr +++ b/tests/ui/declare_interior_mutable_const/traits.stderr @@ -1,8 +1,8 @@ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:16:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:17:1 | -LL | const ATOMIC: AtomicUsize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const ATOMIC: AtomicUsize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` @@ -19,70 +19,70 @@ LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:44:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:46:1 | -LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:69:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:72:1 | -LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:70:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:74:1 | -LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:89:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:94:1 | -LL | const BOUNDED: T::ToBeBounded; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const BOUNDED: T::ToBeBounded; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:117:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:123:1 | -LL | const SELF: Self = AtomicUsize::new(17); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const SELF: Self = AtomicUsize::new(17); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:118:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:125:1 | -LL | const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:124:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:132:1 | -LL | const DIRECT: Cell; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | const DIRECT: Cell; + | ^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:125:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:134:1 | -LL | const INDIRECT: Cell<*const T>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const INDIRECT: Cell<*const T>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:129:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:139:1 | -LL | const DIRECT: Cell = Cell::new(T::DEFAULT); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const DIRECT: Cell = Cell::new(T::DEFAULT); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:141:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:152:1 | -LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:147:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:159:1 | -LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 13 previous errors diff --git a/tests/ui/default_constructed_unit_structs.fixed b/tests/ui/default_constructed_unit_structs.fixed index 3047c221d457..fa4d55177823 100644 --- a/tests/ui/default_constructed_unit_structs.fixed +++ b/tests/ui/default_constructed_unit_structs.fixed @@ -9,6 +9,7 @@ impl UnitStruct { fn new() -> Self { //should lint Self + //~^ default_constructed_unit_structs } } @@ -51,6 +52,7 @@ impl NormalStruct { // should lint Self { inner: PhantomData, + //~^ default_constructed_unit_structs } } @@ -124,9 +126,13 @@ mod issue_10755 { fn main() { // should lint let _ = PhantomData::; + //~^ default_constructed_unit_structs let _: PhantomData = PhantomData; + //~^ default_constructed_unit_structs let _: PhantomData = std::marker::PhantomData; + //~^ default_constructed_unit_structs let _ = UnitStruct; + //~^ default_constructed_unit_structs // should not lint let _ = TupleStruct::default(); diff --git a/tests/ui/default_constructed_unit_structs.rs b/tests/ui/default_constructed_unit_structs.rs index 66afedb23801..291cd89da0b7 100644 --- a/tests/ui/default_constructed_unit_structs.rs +++ b/tests/ui/default_constructed_unit_structs.rs @@ -9,6 +9,7 @@ impl UnitStruct { fn new() -> Self { //should lint Self::default() + //~^ default_constructed_unit_structs } } @@ -51,6 +52,7 @@ impl NormalStruct { // should lint Self { inner: PhantomData::default(), + //~^ default_constructed_unit_structs } } @@ -124,9 +126,13 @@ mod issue_10755 { fn main() { // should lint let _ = PhantomData::::default(); + //~^ default_constructed_unit_structs let _: PhantomData = PhantomData::default(); + //~^ default_constructed_unit_structs let _: PhantomData = std::marker::PhantomData::default(); + //~^ default_constructed_unit_structs let _ = UnitStruct::default(); + //~^ default_constructed_unit_structs // should not lint let _ = TupleStruct::default(); diff --git a/tests/ui/default_constructed_unit_structs.stderr b/tests/ui/default_constructed_unit_structs.stderr index c0fa73515c03..6d4e1bdc2cc8 100644 --- a/tests/ui/default_constructed_unit_structs.stderr +++ b/tests/ui/default_constructed_unit_structs.stderr @@ -8,31 +8,31 @@ LL | Self::default() = help: to override `-D warnings` add `#[allow(clippy::default_constructed_unit_structs)]` error: use of `default` to create a unit struct - --> tests/ui/default_constructed_unit_structs.rs:53:31 + --> tests/ui/default_constructed_unit_structs.rs:54:31 | LL | inner: PhantomData::default(), | ^^^^^^^^^^^ help: remove this call to `default` error: use of `default` to create a unit struct - --> tests/ui/default_constructed_unit_structs.rs:126:33 + --> tests/ui/default_constructed_unit_structs.rs:128:33 | LL | let _ = PhantomData::::default(); | ^^^^^^^^^^^ help: remove this call to `default` error: use of `default` to create a unit struct - --> tests/ui/default_constructed_unit_structs.rs:127:42 + --> tests/ui/default_constructed_unit_structs.rs:130:42 | LL | let _: PhantomData = PhantomData::default(); | ^^^^^^^^^^^ help: remove this call to `default` error: use of `default` to create a unit struct - --> tests/ui/default_constructed_unit_structs.rs:128:55 + --> tests/ui/default_constructed_unit_structs.rs:132:55 | LL | let _: PhantomData = std::marker::PhantomData::default(); | ^^^^^^^^^^^ help: remove this call to `default` error: use of `default` to create a unit struct - --> tests/ui/default_constructed_unit_structs.rs:129:23 + --> tests/ui/default_constructed_unit_structs.rs:134:23 | LL | let _ = UnitStruct::default(); | ^^^^^^^^^^^ help: remove this call to `default` diff --git a/tests/ui/default_instead_of_iter_empty.fixed b/tests/ui/default_instead_of_iter_empty.fixed index 3298a222bda6..548de9379927 100644 --- a/tests/ui/default_instead_of_iter_empty.fixed +++ b/tests/ui/default_instead_of_iter_empty.fixed @@ -10,8 +10,11 @@ struct Iter { fn main() { // Do lint. let _ = std::iter::empty::(); + //~^ default_instead_of_iter_empty let _ = std::iter::empty::>(); + //~^ default_instead_of_iter_empty let _foo: std::iter::Empty = std::iter::empty(); + //~^ default_instead_of_iter_empty // Do not lint. let _ = Vec::::default(); diff --git a/tests/ui/default_instead_of_iter_empty.rs b/tests/ui/default_instead_of_iter_empty.rs index 75b088a99590..824cc20566de 100644 --- a/tests/ui/default_instead_of_iter_empty.rs +++ b/tests/ui/default_instead_of_iter_empty.rs @@ -10,8 +10,11 @@ struct Iter { fn main() { // Do lint. let _ = std::iter::Empty::::default(); + //~^ default_instead_of_iter_empty let _ = std::iter::Empty::>::default(); + //~^ default_instead_of_iter_empty let _foo: std::iter::Empty = std::iter::Empty::default(); + //~^ default_instead_of_iter_empty // Do not lint. let _ = Vec::::default(); diff --git a/tests/ui/default_instead_of_iter_empty.stderr b/tests/ui/default_instead_of_iter_empty.stderr index 4bd4d060a3f7..dc0b757adc2e 100644 --- a/tests/ui/default_instead_of_iter_empty.stderr +++ b/tests/ui/default_instead_of_iter_empty.stderr @@ -8,13 +8,13 @@ LL | let _ = std::iter::Empty::::default(); = help: to override `-D warnings` add `#[allow(clippy::default_instead_of_iter_empty)]` error: `std::iter::empty()` is the more idiomatic way - --> tests/ui/default_instead_of_iter_empty.rs:13:13 + --> tests/ui/default_instead_of_iter_empty.rs:14:13 | LL | let _ = std::iter::Empty::>::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::empty::>()` error: `std::iter::empty()` is the more idiomatic way - --> tests/ui/default_instead_of_iter_empty.rs:14:41 + --> tests/ui/default_instead_of_iter_empty.rs:16:41 | LL | let _foo: std::iter::Empty = std::iter::Empty::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()` diff --git a/tests/ui/default_instead_of_iter_empty_no_std.fixed b/tests/ui/default_instead_of_iter_empty_no_std.fixed index 7300bd9bd2ab..76d75ea7e591 100644 --- a/tests/ui/default_instead_of_iter_empty_no_std.fixed +++ b/tests/ui/default_instead_of_iter_empty_no_std.fixed @@ -21,7 +21,9 @@ struct Iter { fn main() { // Do lint. let _ = core::iter::empty::(); + //~^ default_instead_of_iter_empty let _foo: core::iter::Empty = core::iter::empty(); + //~^ default_instead_of_iter_empty // Do not lint. let _ = Iter::default(); diff --git a/tests/ui/default_instead_of_iter_empty_no_std.rs b/tests/ui/default_instead_of_iter_empty_no_std.rs index 0bc5c7169d12..639b73ba38de 100644 --- a/tests/ui/default_instead_of_iter_empty_no_std.rs +++ b/tests/ui/default_instead_of_iter_empty_no_std.rs @@ -21,7 +21,9 @@ struct Iter { fn main() { // Do lint. let _ = core::iter::Empty::::default(); + //~^ default_instead_of_iter_empty let _foo: core::iter::Empty = core::iter::Empty::default(); + //~^ default_instead_of_iter_empty // Do not lint. let _ = Iter::default(); diff --git a/tests/ui/default_instead_of_iter_empty_no_std.stderr b/tests/ui/default_instead_of_iter_empty_no_std.stderr index eb80da13e850..69812eba5423 100644 --- a/tests/ui/default_instead_of_iter_empty_no_std.stderr +++ b/tests/ui/default_instead_of_iter_empty_no_std.stderr @@ -8,7 +8,7 @@ LL | let _ = core::iter::Empty::::default(); = help: to override `-D warnings` add `#[allow(clippy::default_instead_of_iter_empty)]` error: `core::iter::empty()` is the more idiomatic way - --> tests/ui/default_instead_of_iter_empty_no_std.rs:24:42 + --> tests/ui/default_instead_of_iter_empty_no_std.rs:25:42 | LL | let _foo: core::iter::Empty = core::iter::Empty::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::iter::empty()` diff --git a/tests/ui/default_numeric_fallback_f64.fixed b/tests/ui/default_numeric_fallback_f64.fixed index 00f0d7644340..a4d66f951f75 100644 --- a/tests/ui/default_numeric_fallback_f64.fixed +++ b/tests/ui/default_numeric_fallback_f64.fixed @@ -19,10 +19,20 @@ mod basic_expr { fn test() { // Should lint unsuffixed literals typed `f64`. let x = 0.12_f64; + //~^ default_numeric_fallback let x = [1.0_f64, 2.0_f64, 3.0_f64]; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback let x = if true { (1.0_f64, 2.0_f64) } else { (3.0_f64, 4.0_f64) }; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback let x = match 1.0_f64 { + //~^ default_numeric_fallback _ => 1.0_f64, + //~^ default_numeric_fallback }; // Should NOT lint suffixed literals. @@ -42,6 +52,7 @@ mod nested_local { let x: _ = { // Should lint this because this literal is not bound to any types. let y = 1.0_f64; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1. @@ -50,12 +61,14 @@ mod nested_local { let x: _ = if true { // Should lint this because this literal is not bound to any types. let y = 1.0_f64; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1. } else { // Should lint this because this literal is not bound to any types. let y = 1.0_f64; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 2. @@ -64,6 +77,7 @@ mod nested_local { const X: f32 = { // Should lint this because this literal is not bound to any types. let y = 1.0_f64; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1. @@ -80,10 +94,12 @@ mod function_def { // Should lint this because return type is inferred to `f64` and NOT bound to a concrete // type. let f = || -> _ { 1.0_f64 }; + //~^ default_numeric_fallback // Even though the output type is specified, // this unsuffixed literal is linted to reduce heuristics and keep codebase simple. let f = || -> f64 { 1.0_f64 }; + //~^ default_numeric_fallback } } @@ -98,9 +114,11 @@ mod function_calls { // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type. generic_arg(1.0_f64); + //~^ default_numeric_fallback // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type. let x: _ = generic_arg(1.0_f64); + //~^ default_numeric_fallback } } @@ -119,9 +137,11 @@ mod struct_ctor { // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type. GenericStruct { x: 1.0_f64 }; + //~^ default_numeric_fallback // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type. let _ = GenericStruct { x: 1.0_f64 }; + //~^ default_numeric_fallback } } @@ -140,6 +160,7 @@ mod enum_ctor { // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type. GenericEnum::X(1.0_f64); + //~^ default_numeric_fallback } } @@ -160,6 +181,7 @@ mod method_calls { // Should lint this because the argument type is bound to a concrete type. s.generic_arg(1.0_f64); + //~^ default_numeric_fallback } } @@ -170,6 +192,7 @@ mod in_macro { #[inline_macros] fn internal() { inline!(let x = 22.0_f64;); + //~^ default_numeric_fallback } // Should NOT lint in external macro. diff --git a/tests/ui/default_numeric_fallback_f64.rs b/tests/ui/default_numeric_fallback_f64.rs index 942cedac2753..d1446c35557f 100644 --- a/tests/ui/default_numeric_fallback_f64.rs +++ b/tests/ui/default_numeric_fallback_f64.rs @@ -19,10 +19,20 @@ mod basic_expr { fn test() { // Should lint unsuffixed literals typed `f64`. let x = 0.12; + //~^ default_numeric_fallback let x = [1., 2., 3.]; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback let x = if true { (1., 2.) } else { (3., 4.) }; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback let x = match 1. { + //~^ default_numeric_fallback _ => 1., + //~^ default_numeric_fallback }; // Should NOT lint suffixed literals. @@ -42,6 +52,7 @@ mod nested_local { let x: _ = { // Should lint this because this literal is not bound to any types. let y = 1.; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1. @@ -50,12 +61,14 @@ mod nested_local { let x: _ = if true { // Should lint this because this literal is not bound to any types. let y = 1.; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1. } else { // Should lint this because this literal is not bound to any types. let y = 1.; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 2. @@ -64,6 +77,7 @@ mod nested_local { const X: f32 = { // Should lint this because this literal is not bound to any types. let y = 1.; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1. @@ -80,10 +94,12 @@ mod function_def { // Should lint this because return type is inferred to `f64` and NOT bound to a concrete // type. let f = || -> _ { 1. }; + //~^ default_numeric_fallback // Even though the output type is specified, // this unsuffixed literal is linted to reduce heuristics and keep codebase simple. let f = || -> f64 { 1. }; + //~^ default_numeric_fallback } } @@ -98,9 +114,11 @@ mod function_calls { // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type. generic_arg(1.); + //~^ default_numeric_fallback // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type. let x: _ = generic_arg(1.); + //~^ default_numeric_fallback } } @@ -119,9 +137,11 @@ mod struct_ctor { // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type. GenericStruct { x: 1. }; + //~^ default_numeric_fallback // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type. let _ = GenericStruct { x: 1. }; + //~^ default_numeric_fallback } } @@ -140,6 +160,7 @@ mod enum_ctor { // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type. GenericEnum::X(1.); + //~^ default_numeric_fallback } } @@ -160,6 +181,7 @@ mod method_calls { // Should lint this because the argument type is bound to a concrete type. s.generic_arg(1.); + //~^ default_numeric_fallback } } @@ -170,6 +192,7 @@ mod in_macro { #[inline_macros] fn internal() { inline!(let x = 22.;); + //~^ default_numeric_fallback } // Should NOT lint in external macro. diff --git a/tests/ui/default_numeric_fallback_f64.stderr b/tests/ui/default_numeric_fallback_f64.stderr index d7e4dbd63771..f9451211e1ac 100644 --- a/tests/ui/default_numeric_fallback_f64.stderr +++ b/tests/ui/default_numeric_fallback_f64.stderr @@ -8,133 +8,133 @@ LL | let x = 0.12; = help: to override `-D warnings` add `#[allow(clippy::default_numeric_fallback)]` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:22:18 + --> tests/ui/default_numeric_fallback_f64.rs:23:18 | LL | let x = [1., 2., 3.]; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:22:22 + --> tests/ui/default_numeric_fallback_f64.rs:23:22 | LL | let x = [1., 2., 3.]; | ^^ help: consider adding suffix: `2.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:22:26 + --> tests/ui/default_numeric_fallback_f64.rs:23:26 | LL | let x = [1., 2., 3.]; | ^^ help: consider adding suffix: `3.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:23:28 + --> tests/ui/default_numeric_fallback_f64.rs:27:28 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:23:32 + --> tests/ui/default_numeric_fallback_f64.rs:27:32 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `2.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:23:46 + --> tests/ui/default_numeric_fallback_f64.rs:27:46 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `3.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:23:50 + --> tests/ui/default_numeric_fallback_f64.rs:27:50 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `4.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:24:23 + --> tests/ui/default_numeric_fallback_f64.rs:32:23 | LL | let x = match 1. { | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:25:18 + --> tests/ui/default_numeric_fallback_f64.rs:34:18 | LL | _ => 1., | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:44:21 + --> tests/ui/default_numeric_fallback_f64.rs:54:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:52:21 + --> tests/ui/default_numeric_fallback_f64.rs:63:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:58:21 + --> tests/ui/default_numeric_fallback_f64.rs:70:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:66:21 + --> tests/ui/default_numeric_fallback_f64.rs:79:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:82:27 + --> tests/ui/default_numeric_fallback_f64.rs:96:27 | LL | let f = || -> _ { 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:86:29 + --> tests/ui/default_numeric_fallback_f64.rs:101:29 | LL | let f = || -> f64 { 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:100:21 + --> tests/ui/default_numeric_fallback_f64.rs:116:21 | LL | generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:103:32 + --> tests/ui/default_numeric_fallback_f64.rs:120:32 | LL | let x: _ = generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:121:28 + --> tests/ui/default_numeric_fallback_f64.rs:139:28 | LL | GenericStruct { x: 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:124:36 + --> tests/ui/default_numeric_fallback_f64.rs:143:36 | LL | let _ = GenericStruct { x: 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:142:24 + --> tests/ui/default_numeric_fallback_f64.rs:162:24 | LL | GenericEnum::X(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:162:23 + --> tests/ui/default_numeric_fallback_f64.rs:183:23 | LL | s.generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_f64.rs:172:25 + --> tests/ui/default_numeric_fallback_f64.rs:194:25 | LL | inline!(let x = 22.;); | ^^^ help: consider adding suffix: `22.0_f64` diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed index f28ae04fd0a4..e95c49dd6b66 100644 --- a/tests/ui/default_numeric_fallback_i32.fixed +++ b/tests/ui/default_numeric_fallback_i32.fixed @@ -18,11 +18,23 @@ mod basic_expr { fn test() { // Should lint unsuffixed literals typed `i32`. let x = 22_i32; + //~^ default_numeric_fallback let x = [1_i32, 2_i32, 3_i32]; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback let x = if true { (1_i32, 2_i32) } else { (3_i32, 4_i32) }; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback let x = match 1_i32 { + //~^ default_numeric_fallback 1_i32 => 1_i32, + //~^ default_numeric_fallback + //~| default_numeric_fallback _ => 2_i32, + //~^ default_numeric_fallback }; // Should NOT lint suffixed literals. @@ -42,6 +54,7 @@ mod nested_local { let x: _ = { // Should lint this because this literal is not bound to any types. let y = 1_i32; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1 @@ -50,12 +63,14 @@ mod nested_local { let x: _ = if true { // Should lint this because this literal is not bound to any types. let y = 1_i32; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1 } else { // Should lint this because this literal is not bound to any types. let y = 1_i32; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 2 @@ -64,6 +79,7 @@ mod nested_local { const CONST_X: i32 = { // Should lint this because this literal is not bound to any types. let y = 1_i32; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1 @@ -80,10 +96,12 @@ mod function_def { // Should lint this because return type is inferred to `i32` and NOT bound to a concrete // type. let f = || -> _ { 1_i32 }; + //~^ default_numeric_fallback // Even though the output type is specified, // this unsuffixed literal is linted to reduce heuristics and keep codebase simple. let f = || -> i32 { 1_i32 }; + //~^ default_numeric_fallback } } @@ -98,9 +116,11 @@ mod function_calls { // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type. generic_arg(1_i32); + //~^ default_numeric_fallback // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type. let x: _ = generic_arg(1_i32); + //~^ default_numeric_fallback } } @@ -119,9 +139,11 @@ mod struct_ctor { // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type. GenericStruct { x: 1_i32 }; + //~^ default_numeric_fallback // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type. let _ = GenericStruct { x: 1_i32 }; + //~^ default_numeric_fallback } } @@ -140,6 +162,7 @@ mod enum_ctor { // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type. GenericEnum::X(1_i32); + //~^ default_numeric_fallback } } @@ -160,6 +183,7 @@ mod method_calls { // Should lint this because the argument type is bound to a concrete type. s.generic_arg(1_i32); + //~^ default_numeric_fallback } } @@ -170,6 +194,7 @@ mod in_macro { #[inline_macros] fn internal() { inline!(let x = 22_i32;); + //~^ default_numeric_fallback } // Should NOT lint in external macro. @@ -212,6 +237,9 @@ mod type_already_inferred { // Should NOT lint in `vec!` call if the type was already stated let data_i32: Vec = vec![1, 2, 3]; let data_i32 = vec![1_i32, 2_i32, 3_i32]; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback } } diff --git a/tests/ui/default_numeric_fallback_i32.rs b/tests/ui/default_numeric_fallback_i32.rs index 78a5006444ee..377c8934c5be 100644 --- a/tests/ui/default_numeric_fallback_i32.rs +++ b/tests/ui/default_numeric_fallback_i32.rs @@ -18,11 +18,23 @@ mod basic_expr { fn test() { // Should lint unsuffixed literals typed `i32`. let x = 22; + //~^ default_numeric_fallback let x = [1, 2, 3]; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback let x = if true { (1, 2) } else { (3, 4) }; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback let x = match 1 { + //~^ default_numeric_fallback 1 => 1, + //~^ default_numeric_fallback + //~| default_numeric_fallback _ => 2, + //~^ default_numeric_fallback }; // Should NOT lint suffixed literals. @@ -42,6 +54,7 @@ mod nested_local { let x: _ = { // Should lint this because this literal is not bound to any types. let y = 1; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1 @@ -50,12 +63,14 @@ mod nested_local { let x: _ = if true { // Should lint this because this literal is not bound to any types. let y = 1; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1 } else { // Should lint this because this literal is not bound to any types. let y = 1; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 2 @@ -64,6 +79,7 @@ mod nested_local { const CONST_X: i32 = { // Should lint this because this literal is not bound to any types. let y = 1; + //~^ default_numeric_fallback // Should NOT lint this because this literal is bound to `_` of outer `Local`. 1 @@ -80,10 +96,12 @@ mod function_def { // Should lint this because return type is inferred to `i32` and NOT bound to a concrete // type. let f = || -> _ { 1 }; + //~^ default_numeric_fallback // Even though the output type is specified, // this unsuffixed literal is linted to reduce heuristics and keep codebase simple. let f = || -> i32 { 1 }; + //~^ default_numeric_fallback } } @@ -98,9 +116,11 @@ mod function_calls { // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type. generic_arg(1); + //~^ default_numeric_fallback // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type. let x: _ = generic_arg(1); + //~^ default_numeric_fallback } } @@ -119,9 +139,11 @@ mod struct_ctor { // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type. GenericStruct { x: 1 }; + //~^ default_numeric_fallback // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type. let _ = GenericStruct { x: 1 }; + //~^ default_numeric_fallback } } @@ -140,6 +162,7 @@ mod enum_ctor { // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type. GenericEnum::X(1); + //~^ default_numeric_fallback } } @@ -160,6 +183,7 @@ mod method_calls { // Should lint this because the argument type is bound to a concrete type. s.generic_arg(1); + //~^ default_numeric_fallback } } @@ -170,6 +194,7 @@ mod in_macro { #[inline_macros] fn internal() { inline!(let x = 22;); + //~^ default_numeric_fallback } // Should NOT lint in external macro. @@ -212,6 +237,9 @@ mod type_already_inferred { // Should NOT lint in `vec!` call if the type was already stated let data_i32: Vec = vec![1, 2, 3]; let data_i32 = vec![1, 2, 3]; + //~^ default_numeric_fallback + //~| default_numeric_fallback + //~| default_numeric_fallback } } diff --git a/tests/ui/default_numeric_fallback_i32.stderr b/tests/ui/default_numeric_fallback_i32.stderr index 67ab923ecf5f..02afbddcb3be 100644 --- a/tests/ui/default_numeric_fallback_i32.stderr +++ b/tests/ui/default_numeric_fallback_i32.stderr @@ -8,145 +8,145 @@ LL | let x = 22; = help: to override `-D warnings` add `#[allow(clippy::default_numeric_fallback)]` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:21:18 + --> tests/ui/default_numeric_fallback_i32.rs:22:18 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:21:21 + --> tests/ui/default_numeric_fallback_i32.rs:22:21 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:21:24 + --> tests/ui/default_numeric_fallback_i32.rs:22:24 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:22:28 + --> tests/ui/default_numeric_fallback_i32.rs:26:28 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:22:31 + --> tests/ui/default_numeric_fallback_i32.rs:26:31 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:22:44 + --> tests/ui/default_numeric_fallback_i32.rs:26:44 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:22:47 + --> tests/ui/default_numeric_fallback_i32.rs:26:47 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `4_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:23:23 + --> tests/ui/default_numeric_fallback_i32.rs:31:23 | LL | let x = match 1 { | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:24:13 + --> tests/ui/default_numeric_fallback_i32.rs:33:13 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:24:18 + --> tests/ui/default_numeric_fallback_i32.rs:33:18 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:25:18 + --> tests/ui/default_numeric_fallback_i32.rs:36:18 | LL | _ => 2, | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:44:21 + --> tests/ui/default_numeric_fallback_i32.rs:56:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:52:21 + --> tests/ui/default_numeric_fallback_i32.rs:65:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:58:21 + --> tests/ui/default_numeric_fallback_i32.rs:72:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:66:21 + --> tests/ui/default_numeric_fallback_i32.rs:81:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:82:27 + --> tests/ui/default_numeric_fallback_i32.rs:98:27 | LL | let f = || -> _ { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:86:29 + --> tests/ui/default_numeric_fallback_i32.rs:103:29 | LL | let f = || -> i32 { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:100:21 + --> tests/ui/default_numeric_fallback_i32.rs:118:21 | LL | generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:103:32 + --> tests/ui/default_numeric_fallback_i32.rs:122:32 | LL | let x: _ = generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:121:28 + --> tests/ui/default_numeric_fallback_i32.rs:141:28 | LL | GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:124:36 + --> tests/ui/default_numeric_fallback_i32.rs:145:36 | LL | let _ = GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:142:24 + --> tests/ui/default_numeric_fallback_i32.rs:164:24 | LL | GenericEnum::X(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:162:23 + --> tests/ui/default_numeric_fallback_i32.rs:185:23 | LL | s.generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:172:25 + --> tests/ui/default_numeric_fallback_i32.rs:196:25 | LL | inline!(let x = 22;); | ^^ help: consider adding suffix: `22_i32` @@ -154,19 +154,19 @@ LL | inline!(let x = 22;); = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info) error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:214:29 + --> tests/ui/default_numeric_fallback_i32.rs:239:29 | LL | let data_i32 = vec![1, 2, 3]; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:214:32 + --> tests/ui/default_numeric_fallback_i32.rs:239:32 | LL | let data_i32 = vec![1, 2, 3]; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:214:35 + --> tests/ui/default_numeric_fallback_i32.rs:239:35 | LL | let data_i32 = vec![1, 2, 3]; | ^ help: consider adding suffix: `3_i32` diff --git a/tests/ui/default_trait_access.fixed b/tests/ui/default_trait_access.fixed index 6f1e72c5a6c0..d3fe09a052ef 100644 --- a/tests/ui/default_trait_access.fixed +++ b/tests/ui/default_trait_access.fixed @@ -11,16 +11,20 @@ use std::{default, string}; fn main() { let s1: String = String::default(); + //~^ default_trait_access let s2 = String::default(); let s3: String = String::default(); + //~^ default_trait_access let s4: String = String::default(); + //~^ default_trait_access let s5 = string::String::default(); let s6: String = String::default(); + //~^ default_trait_access let s7 = std::string::String::default(); @@ -31,18 +35,22 @@ fn main() { let s10 = DerivedDefault::default(); let s11: GenericDerivedDefault = GenericDerivedDefault::default(); + //~^ default_trait_access let s12 = GenericDerivedDefault::::default(); let s13 = TupleDerivedDefault::default(); let s14: TupleDerivedDefault = TupleDerivedDefault::default(); + //~^ default_trait_access let s15: ArrayDerivedDefault = ArrayDerivedDefault::default(); + //~^ default_trait_access let s16 = ArrayDerivedDefault::default(); let s17: TupleStructDerivedDefault = TupleStructDerivedDefault::default(); + //~^ default_trait_access let s18 = TupleStructDerivedDefault::default(); diff --git a/tests/ui/default_trait_access.rs b/tests/ui/default_trait_access.rs index 5528ca8b7936..cdffb2a2ee8c 100644 --- a/tests/ui/default_trait_access.rs +++ b/tests/ui/default_trait_access.rs @@ -11,16 +11,20 @@ use std::{default, string}; fn main() { let s1: String = Default::default(); + //~^ default_trait_access let s2 = String::default(); let s3: String = D2::default(); + //~^ default_trait_access let s4: String = std::default::Default::default(); + //~^ default_trait_access let s5 = string::String::default(); let s6: String = default::Default::default(); + //~^ default_trait_access let s7 = std::string::String::default(); @@ -31,18 +35,22 @@ fn main() { let s10 = DerivedDefault::default(); let s11: GenericDerivedDefault = Default::default(); + //~^ default_trait_access let s12 = GenericDerivedDefault::::default(); let s13 = TupleDerivedDefault::default(); let s14: TupleDerivedDefault = Default::default(); + //~^ default_trait_access let s15: ArrayDerivedDefault = Default::default(); + //~^ default_trait_access let s16 = ArrayDerivedDefault::default(); let s17: TupleStructDerivedDefault = Default::default(); + //~^ default_trait_access let s18 = TupleStructDerivedDefault::default(); diff --git a/tests/ui/default_trait_access.stderr b/tests/ui/default_trait_access.stderr index 276f03d79df1..aa7eb4f89558 100644 --- a/tests/ui/default_trait_access.stderr +++ b/tests/ui/default_trait_access.stderr @@ -11,43 +11,43 @@ LL | #![deny(clippy::default_trait_access)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: calling `String::default()` is more clear than this expression - --> tests/ui/default_trait_access.rs:17:22 + --> tests/ui/default_trait_access.rs:18:22 | LL | let s3: String = D2::default(); | ^^^^^^^^^^^^^ help: try: `String::default()` error: calling `String::default()` is more clear than this expression - --> tests/ui/default_trait_access.rs:19:22 + --> tests/ui/default_trait_access.rs:21:22 | LL | let s4: String = std::default::Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `String::default()` error: calling `String::default()` is more clear than this expression - --> tests/ui/default_trait_access.rs:23:22 + --> tests/ui/default_trait_access.rs:26:22 | LL | let s6: String = default::Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `String::default()` error: calling `GenericDerivedDefault::default()` is more clear than this expression - --> tests/ui/default_trait_access.rs:33:46 + --> tests/ui/default_trait_access.rs:37:46 | LL | let s11: GenericDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault::default()` error: calling `TupleDerivedDefault::default()` is more clear than this expression - --> tests/ui/default_trait_access.rs:39:36 + --> tests/ui/default_trait_access.rs:44:36 | LL | let s14: TupleDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `TupleDerivedDefault::default()` error: calling `ArrayDerivedDefault::default()` is more clear than this expression - --> tests/ui/default_trait_access.rs:41:36 + --> tests/ui/default_trait_access.rs:47:36 | LL | let s15: ArrayDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `ArrayDerivedDefault::default()` error: calling `TupleStructDerivedDefault::default()` is more clear than this expression - --> tests/ui/default_trait_access.rs:45:42 + --> tests/ui/default_trait_access.rs:52:42 | LL | let s17: TupleStructDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `TupleStructDerivedDefault::default()` diff --git a/tests/ui/default_union_representation.rs b/tests/ui/default_union_representation.rs index ba63cde2fa9d..90d1a20e6d8d 100644 --- a/tests/ui/default_union_representation.rs +++ b/tests/ui/default_union_representation.rs @@ -3,7 +3,8 @@ #![allow(clippy::repr_packed_without_abi)] union NoAttribute { - //~^ ERROR: this union has the default representation +//~^ default_union_representation + a: i32, b: u32, } @@ -16,7 +17,8 @@ union ReprC { #[repr(packed)] union ReprPacked { - //~^ ERROR: this union has the default representation +//~^ default_union_representation + a: i32, b: u32, } @@ -35,7 +37,8 @@ union ReprCAlign { #[repr(align(32))] union ReprAlign { - //~^ ERROR: this union has the default representation +//~^ default_union_representation + a: i32, b: u32, } @@ -56,7 +59,8 @@ union ZSTsAndField2 { f3: (), } union ZSTAndTwoFields { - //~^ ERROR: this union has the default representation +//~^ default_union_representation + f0: u32, f1: u64, f2: (), diff --git a/tests/ui/default_union_representation.stderr b/tests/ui/default_union_representation.stderr index d558a3e8de1b..07c106d4092d 100644 --- a/tests/ui/default_union_representation.stderr +++ b/tests/ui/default_union_representation.stderr @@ -3,6 +3,7 @@ error: this union has the default representation | LL | / union NoAttribute { LL | | +LL | | LL | | a: i32, LL | | b: u32, LL | | } @@ -13,10 +14,11 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::default_union_representation)]` error: this union has the default representation - --> tests/ui/default_union_representation.rs:18:1 + --> tests/ui/default_union_representation.rs:19:1 | LL | / union ReprPacked { LL | | +LL | | LL | | a: i32, LL | | b: u32, LL | | } @@ -25,10 +27,11 @@ LL | | } = help: consider annotating `ReprPacked` with `#[repr(C)]` to explicitly specify memory layout error: this union has the default representation - --> tests/ui/default_union_representation.rs:37:1 + --> tests/ui/default_union_representation.rs:39:1 | LL | / union ReprAlign { LL | | +LL | | LL | | a: i32, LL | | b: u32, LL | | } @@ -37,10 +40,11 @@ LL | | } = help: consider annotating `ReprAlign` with `#[repr(C)]` to explicitly specify memory layout error: this union has the default representation - --> tests/ui/default_union_representation.rs:58:1 + --> tests/ui/default_union_representation.rs:61:1 | LL | / union ZSTAndTwoFields { LL | | +LL | | LL | | f0: u32, LL | | f1: u64, LL | | f2: (), diff --git a/tests/ui/deref_addrof.fixed b/tests/ui/deref_addrof.fixed index f412c57d6505..35dbd790e890 100644 --- a/tests/ui/deref_addrof.fixed +++ b/tests/ui/deref_addrof.fixed @@ -21,30 +21,39 @@ fn main() { let aref = &a; let b = a; + //~^ deref_addrof let b = get_number(); + //~^ deref_addrof let b = *get_reference(&a); let bytes: Vec = vec![1, 2, 3, 4]; let b = bytes[1..2][0]; + //~^ deref_addrof //This produces a suggestion of 'let b = (a);' which //will trigger the 'unused_parens' lint let b = (a); + //~^ deref_addrof let b = a; + //~^ deref_addrof #[rustfmt::skip] let b = a; + //~^ deref_addrof let b = &a; + //~^ deref_addrof let b = *aref; + //~^ deref_addrof let _ = unsafe { *core::ptr::addr_of!(a) }; let _repeat = [0; 64]; + //~^ deref_addrof // do NOT lint for array as semantic differences with/out `*&`. let _arr = *&[0, 1, 2, 3, 4]; } @@ -55,9 +64,11 @@ pub struct S; impl S { pub fn f(&self) -> &Self { inline!($(@expr self)) + //~^ deref_addrof } #[allow(unused_mut)] // mut will be unused, once the macro is fixed pub fn f_mut(mut self) -> Self { inline!($(@expr self)) + //~^ deref_addrof } } diff --git a/tests/ui/deref_addrof.rs b/tests/ui/deref_addrof.rs index 67836b0de52d..96d1b92ef7be 100644 --- a/tests/ui/deref_addrof.rs +++ b/tests/ui/deref_addrof.rs @@ -21,30 +21,39 @@ fn main() { let aref = &a; let b = *&a; + //~^ deref_addrof let b = *&get_number(); + //~^ deref_addrof let b = *get_reference(&a); let bytes: Vec = vec![1, 2, 3, 4]; let b = *&bytes[1..2][0]; + //~^ deref_addrof //This produces a suggestion of 'let b = (a);' which //will trigger the 'unused_parens' lint let b = *&(a); + //~^ deref_addrof let b = *(&a); + //~^ deref_addrof #[rustfmt::skip] let b = *((&a)); + //~^ deref_addrof let b = *&&a; + //~^ deref_addrof let b = **&aref; + //~^ deref_addrof let _ = unsafe { *core::ptr::addr_of!(a) }; let _repeat = *&[0; 64]; + //~^ deref_addrof // do NOT lint for array as semantic differences with/out `*&`. let _arr = *&[0, 1, 2, 3, 4]; } @@ -55,9 +64,11 @@ pub struct S; impl S { pub fn f(&self) -> &Self { inline!(*& $(@expr self)) + //~^ deref_addrof } #[allow(unused_mut)] // mut will be unused, once the macro is fixed pub fn f_mut(mut self) -> Self { inline!(*&mut $(@expr self)) + //~^ deref_addrof } } diff --git a/tests/ui/deref_addrof.stderr b/tests/ui/deref_addrof.stderr index 20069f746c81..81414b625b2f 100644 --- a/tests/ui/deref_addrof.stderr +++ b/tests/ui/deref_addrof.stderr @@ -8,55 +8,55 @@ LL | let b = *&a; = help: to override `-D warnings` add `#[allow(clippy::deref_addrof)]` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:25:13 + --> tests/ui/deref_addrof.rs:26:13 | LL | let b = *&get_number(); | ^^^^^^^^^^^^^^ help: try: `get_number()` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:30:13 + --> tests/ui/deref_addrof.rs:32:13 | LL | let b = *&bytes[1..2][0]; | ^^^^^^^^^^^^^^^^ help: try: `bytes[1..2][0]` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:34:13 + --> tests/ui/deref_addrof.rs:37:13 | LL | let b = *&(a); | ^^^^^ help: try: `(a)` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:36:13 + --> tests/ui/deref_addrof.rs:40:13 | LL | let b = *(&a); | ^^^^^ help: try: `a` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:39:13 + --> tests/ui/deref_addrof.rs:44:13 | LL | let b = *((&a)); | ^^^^^^^ help: try: `a` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:41:13 + --> tests/ui/deref_addrof.rs:47:13 | LL | let b = *&&a; | ^^^^ help: try: `&a` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:43:14 + --> tests/ui/deref_addrof.rs:50:14 | LL | let b = **&aref; | ^^^^^^ help: try: `aref` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:47:19 + --> tests/ui/deref_addrof.rs:55:19 | LL | let _repeat = *&[0; 64]; | ^^^^^^^^^ help: try: `[0; 64]` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:57:17 + --> tests/ui/deref_addrof.rs:66:17 | LL | inline!(*& $(@expr self)) | ^^^^^^^^^^^^^^^^ help: try: `$(@expr self)` @@ -64,7 +64,7 @@ LL | inline!(*& $(@expr self)) = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:61:17 + --> tests/ui/deref_addrof.rs:71:17 | LL | inline!(*&mut $(@expr self)) | ^^^^^^^^^^^^^^^^^^^ help: try: `$(@expr self)` diff --git a/tests/ui/deref_addrof_double_trigger.rs b/tests/ui/deref_addrof_double_trigger.rs index 6f997875777e..928907f516a4 100644 --- a/tests/ui/deref_addrof_double_trigger.rs +++ b/tests/ui/deref_addrof_double_trigger.rs @@ -8,13 +8,15 @@ fn main() { //This produces a suggestion of 'let b = *&a;' which //will trigger the 'clippy::deref_addrof' lint again let b = **&&a; - //~^ ERROR: immediately dereferencing a reference - //~| NOTE: `-D clippy::deref-addrof` implied by `-D warnings` + //~^ deref_addrof + + { let mut x = 10; let y = *&mut x; - //~^ ERROR: immediately dereferencing a reference + //~^ deref_addrof + } { @@ -22,6 +24,7 @@ fn main() { //will trigger the 'clippy::deref_addrof' lint again let mut x = 10; let y = **&mut &mut x; - //~^ ERROR: immediately dereferencing a reference + //~^ deref_addrof + } } diff --git a/tests/ui/deref_addrof_double_trigger.stderr b/tests/ui/deref_addrof_double_trigger.stderr index 8905b1424674..8e69f986b056 100644 --- a/tests/ui/deref_addrof_double_trigger.stderr +++ b/tests/ui/deref_addrof_double_trigger.stderr @@ -8,13 +8,13 @@ LL | let b = **&&a; = help: to override `-D warnings` add `#[allow(clippy::deref_addrof)]` error: immediately dereferencing a reference - --> tests/ui/deref_addrof_double_trigger.rs:16:17 + --> tests/ui/deref_addrof_double_trigger.rs:17:17 | LL | let y = *&mut x; | ^^^^^^^ help: try: `x` error: immediately dereferencing a reference - --> tests/ui/deref_addrof_double_trigger.rs:24:18 + --> tests/ui/deref_addrof_double_trigger.rs:26:18 | LL | let y = **&mut &mut x; | ^^^^^^^^^^^^ help: try: `&mut x` diff --git a/tests/ui/deref_addrof_macro.rs b/tests/ui/deref_addrof_macro.rs index c7e60f365060..452ccd173a16 100644 --- a/tests/ui/deref_addrof_macro.rs +++ b/tests/ui/deref_addrof_macro.rs @@ -1,3 +1,4 @@ +//@ check-pass //@aux-build:proc_macros.rs #![warn(clippy::deref_addrof)] diff --git a/tests/ui/deref_by_slicing.fixed b/tests/ui/deref_by_slicing.fixed index 87b33b1f881d..78a8f292bc9a 100644 --- a/tests/ui/deref_by_slicing.fixed +++ b/tests/ui/deref_by_slicing.fixed @@ -6,27 +6,37 @@ use std::io::Read; fn main() { let mut vec = vec![0]; let _ = &*vec; + //~^ deref_by_slicing let _ = &mut *vec; + //~^ deref_by_slicing let ref_vec = &mut vec; let _ = &**ref_vec; + //~^ deref_by_slicing let mut_slice = &mut **ref_vec; + //~^ deref_by_slicing let _ = &mut *mut_slice; // Err, re-borrows slice + //~^ deref_by_slicing let s = String::new(); let _ = &*s; + //~^ deref_by_slicing static S: &[u8] = &[0, 1, 2]; let _ = &mut &*S; // Err, re-borrows slice + //~^ deref_by_slicing let slice: &[u32] = &[0u32, 1u32]; let slice_ref = &slice; let _ = *slice_ref; // Err, derefs slice + //~^ deref_by_slicing let bytes: &[u8] = &[]; let _ = (&*bytes).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice + //~^ deref_by_slicing // issue 12751 let a = &mut [1, 2, 3][..]; let _ = &*a; + //~^ deref_by_slicing } diff --git a/tests/ui/deref_by_slicing.rs b/tests/ui/deref_by_slicing.rs index 8d8882a1781e..205cad63ddac 100644 --- a/tests/ui/deref_by_slicing.rs +++ b/tests/ui/deref_by_slicing.rs @@ -6,27 +6,37 @@ use std::io::Read; fn main() { let mut vec = vec![0]; let _ = &vec[..]; + //~^ deref_by_slicing let _ = &mut vec[..]; + //~^ deref_by_slicing let ref_vec = &mut vec; let _ = &ref_vec[..]; + //~^ deref_by_slicing let mut_slice = &mut ref_vec[..]; + //~^ deref_by_slicing let _ = &mut mut_slice[..]; // Err, re-borrows slice + //~^ deref_by_slicing let s = String::new(); let _ = &s[..]; + //~^ deref_by_slicing static S: &[u8] = &[0, 1, 2]; let _ = &mut &S[..]; // Err, re-borrows slice + //~^ deref_by_slicing let slice: &[u32] = &[0u32, 1u32]; let slice_ref = &slice; let _ = &slice_ref[..]; // Err, derefs slice + //~^ deref_by_slicing let bytes: &[u8] = &[]; let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice + //~^ deref_by_slicing // issue 12751 let a = &mut [1, 2, 3][..]; let _ = &a[..]; + //~^ deref_by_slicing } diff --git a/tests/ui/deref_by_slicing.stderr b/tests/ui/deref_by_slicing.stderr index ceb9ab6db73d..a1fda3b3ec50 100644 --- a/tests/ui/deref_by_slicing.stderr +++ b/tests/ui/deref_by_slicing.stderr @@ -8,55 +8,55 @@ LL | let _ = &vec[..]; = help: to override `-D warnings` add `#[allow(clippy::deref_by_slicing)]` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:9:13 + --> tests/ui/deref_by_slicing.rs:10:13 | LL | let _ = &mut vec[..]; | ^^^^^^^^^^^^ help: dereference the original value instead: `&mut *vec` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:12:13 + --> tests/ui/deref_by_slicing.rs:14:13 | LL | let _ = &ref_vec[..]; | ^^^^^^^^^^^^ help: dereference the original value instead: `&**ref_vec` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:13:21 + --> tests/ui/deref_by_slicing.rs:16:21 | LL | let mut_slice = &mut ref_vec[..]; | ^^^^^^^^^^^^^^^^ help: dereference the original value instead: `&mut **ref_vec` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:14:13 + --> tests/ui/deref_by_slicing.rs:18:13 | LL | let _ = &mut mut_slice[..]; // Err, re-borrows slice | ^^^^^^^^^^^^^^^^^^ help: reborrow the original value instead: `&mut *mut_slice` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:17:13 + --> tests/ui/deref_by_slicing.rs:22:13 | LL | let _ = &s[..]; | ^^^^^^ help: dereference the original value instead: `&*s` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:20:18 + --> tests/ui/deref_by_slicing.rs:26:18 | LL | let _ = &mut &S[..]; // Err, re-borrows slice | ^^^^^^ help: reborrow the original value instead: `&*S` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:24:13 + --> tests/ui/deref_by_slicing.rs:31:13 | LL | let _ = &slice_ref[..]; // Err, derefs slice | ^^^^^^^^^^^^^^ help: dereference the original value instead: `*slice_ref` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:27:13 + --> tests/ui/deref_by_slicing.rs:35:13 | LL | let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice | ^^^^^^^^^^^^ help: reborrow the original value instead: `(&*bytes)` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:31:13 + --> tests/ui/deref_by_slicing.rs:40:13 | LL | let _ = &a[..]; | ^^^^^^ help: reborrow the original value instead: `&*a` diff --git a/tests/ui/derivable_impls.rs b/tests/ui/derivable_impls.rs index eb9a007bf10f..1df2d88824b0 100644 --- a/tests/ui/derivable_impls.rs +++ b/tests/ui/derivable_impls.rs @@ -18,6 +18,7 @@ struct FooDefault<'a> { } impl std::default::Default for FooDefault<'_> { +//~^ derivable_impls fn default() -> Self { Self { a: false, @@ -39,6 +40,7 @@ impl std::default::Default for FooDefault<'_> { struct TupleDefault(bool, i32, u64); impl std::default::Default for TupleDefault { +//~^ derivable_impls fn default() -> Self { Self(false, 0, 0u64) } @@ -91,6 +93,7 @@ impl Default for FooNDVec { struct StrDefault<'a>(&'a str); impl Default for StrDefault<'_> { +//~^ derivable_impls fn default() -> Self { Self("") } @@ -117,6 +120,7 @@ mac!(0); struct Y(u32); impl Default for Y { +//~^ derivable_impls fn default() -> Self { Self(mac!()) } @@ -156,6 +160,7 @@ struct WithoutSelfCurly { } impl Default for WithoutSelfCurly { +//~^ derivable_impls fn default() -> Self { WithoutSelfCurly { a: false } } @@ -164,6 +169,7 @@ impl Default for WithoutSelfCurly { struct WithoutSelfParan(bool); impl Default for WithoutSelfParan { +//~^ derivable_impls fn default() -> Self { WithoutSelfParan(false) } @@ -186,6 +192,7 @@ pub struct DirectDefaultDefaultCall { } impl Default for DirectDefaultDefaultCall { +//~^ derivable_impls fn default() -> Self { // When calling `Default::default()` in all fields, we know it is the same as deriving. Self { v: Default::default() } @@ -197,6 +204,7 @@ pub struct EquivalentToDefaultDefaultCallVec { } impl Default for EquivalentToDefaultDefaultCallVec { +//~^ derivable_impls fn default() -> Self { // The body of `::default()` is `Vec::new()`, so they are equivalent. Self { v: Vec::new() } @@ -224,6 +232,7 @@ pub struct EquivalentToDefaultDefaultCallLocal { } impl Default for EquivalentToDefaultDefaultCallLocal { +//~^ derivable_impls fn default() -> Self { // The body of `::default()` is `S::new()`, so they are equivalent. Self { v: S::new() } @@ -263,6 +272,7 @@ pub struct RepeatDefault1 { } impl Default for RepeatDefault1 { +//~^ derivable_impls fn default() -> Self { RepeatDefault1 { a: [0; 32] } } @@ -297,6 +307,7 @@ pub enum SimpleEnum { } impl Default for SimpleEnum { +//~^ derivable_impls fn default() -> Self { SimpleEnum::Bar } diff --git a/tests/ui/derivable_impls.stderr b/tests/ui/derivable_impls.stderr index a14c0b28c4ea..0f73ad55a85e 100644 --- a/tests/ui/derivable_impls.stderr +++ b/tests/ui/derivable_impls.stderr @@ -2,9 +2,9 @@ error: this `impl` can be derived --> tests/ui/derivable_impls.rs:20:1 | LL | / impl std::default::Default for FooDefault<'_> { +LL | | LL | | fn default() -> Self { LL | | Self { -LL | | a: false, ... | LL | | } | |_^ @@ -18,9 +18,10 @@ LL ~ struct FooDefault<'a> { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:41:1 + --> tests/ui/derivable_impls.rs:42:1 | LL | / impl std::default::Default for TupleDefault { +LL | | LL | | fn default() -> Self { LL | | Self(false, 0, 0u64) LL | | } @@ -34,9 +35,10 @@ LL ~ struct TupleDefault(bool, i32, u64); | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:93:1 + --> tests/ui/derivable_impls.rs:95:1 | LL | / impl Default for StrDefault<'_> { +LL | | LL | | fn default() -> Self { LL | | Self("") LL | | } @@ -50,9 +52,10 @@ LL ~ struct StrDefault<'a>(&'a str); | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:119:1 + --> tests/ui/derivable_impls.rs:122:1 | LL | / impl Default for Y { +LL | | LL | | fn default() -> Self { LL | | Self(mac!()) LL | | } @@ -66,9 +69,10 @@ LL ~ struct Y(u32); | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:158:1 + --> tests/ui/derivable_impls.rs:162:1 | LL | / impl Default for WithoutSelfCurly { +LL | | LL | | fn default() -> Self { LL | | WithoutSelfCurly { a: false } LL | | } @@ -82,9 +86,10 @@ LL ~ struct WithoutSelfCurly { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:166:1 + --> tests/ui/derivable_impls.rs:171:1 | LL | / impl Default for WithoutSelfParan { +LL | | LL | | fn default() -> Self { LL | | WithoutSelfParan(false) LL | | } @@ -98,13 +103,12 @@ LL ~ struct WithoutSelfParan(bool); | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:188:1 + --> tests/ui/derivable_impls.rs:194:1 | LL | / impl Default for DirectDefaultDefaultCall { +LL | | LL | | fn default() -> Self { -LL | | // When calling `Default::default()` in all fields, we know it is the same as deriving. -LL | | Self { v: Default::default() } -LL | | } +... | LL | | } | |_^ | @@ -115,13 +119,12 @@ LL ~ pub struct DirectDefaultDefaultCall { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:199:1 + --> tests/ui/derivable_impls.rs:206:1 | LL | / impl Default for EquivalentToDefaultDefaultCallVec { +LL | | LL | | fn default() -> Self { -LL | | // The body of `::default()` is `Vec::new()`, so they are equivalent. -LL | | Self { v: Vec::new() } -LL | | } +... | LL | | } | |_^ | @@ -132,13 +135,12 @@ LL ~ pub struct EquivalentToDefaultDefaultCallVec { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:226:1 + --> tests/ui/derivable_impls.rs:234:1 | LL | / impl Default for EquivalentToDefaultDefaultCallLocal { +LL | | LL | | fn default() -> Self { -LL | | // The body of `::default()` is `S::new()`, so they are equivalent. -LL | | Self { v: S::new() } -LL | | } +... | LL | | } | |_^ | @@ -149,9 +151,10 @@ LL ~ pub struct EquivalentToDefaultDefaultCallLocal { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:265:1 + --> tests/ui/derivable_impls.rs:274:1 | LL | / impl Default for RepeatDefault1 { +LL | | LL | | fn default() -> Self { LL | | RepeatDefault1 { a: [0; 32] } LL | | } @@ -165,9 +168,10 @@ LL ~ pub struct RepeatDefault1 { | error: this `impl` can be derived - --> tests/ui/derivable_impls.rs:299:1 + --> tests/ui/derivable_impls.rs:309:1 | LL | / impl Default for SimpleEnum { +LL | | LL | | fn default() -> Self { LL | | SimpleEnum::Bar LL | | } diff --git a/tests/ui/derive.rs b/tests/ui/derive.rs index dabc06bd7d16..2e8b5959d498 100644 --- a/tests/ui/derive.rs +++ b/tests/ui/derive.rs @@ -11,7 +11,8 @@ struct Qux; impl Clone for Qux { - //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type +//~^ expl_impl_clone_on_copy + fn clone(&self) -> Self { Qux } @@ -36,7 +37,8 @@ struct Lt<'a> { } impl<'a> Clone for Lt<'a> { - //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type +//~^ expl_impl_clone_on_copy + fn clone(&self) -> Self { unimplemented!() } @@ -48,7 +50,8 @@ struct BigArray { } impl Clone for BigArray { - //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type +//~^ expl_impl_clone_on_copy + fn clone(&self) -> Self { unimplemented!() } @@ -60,7 +63,8 @@ struct FnPtr { } impl Clone for FnPtr { - //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type +//~^ expl_impl_clone_on_copy + fn clone(&self) -> Self { unimplemented!() } @@ -81,7 +85,8 @@ impl Clone for Generic { #[derive(Copy)] struct Generic2(T); impl Clone for Generic2 { - //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type +//~^ expl_impl_clone_on_copy + fn clone(&self) -> Self { Self(self.0.clone()) } diff --git a/tests/ui/derive.stderr b/tests/ui/derive.stderr index 0eb4b3c1adaa..bda8800e80a9 100644 --- a/tests/ui/derive.stderr +++ b/tests/ui/derive.stderr @@ -3,9 +3,9 @@ error: you are implementing `Clone` explicitly on a `Copy` type | LL | / impl Clone for Qux { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | Qux -LL | | } +... | LL | | } | |_^ | @@ -14,99 +14,99 @@ note: consider deriving `Clone` or removing `Copy` | LL | / impl Clone for Qux { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | Qux -LL | | } +... | LL | | } | |_^ = note: `-D clippy::expl-impl-clone-on-copy` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]` error: you are implementing `Clone` explicitly on a `Copy` type - --> tests/ui/derive.rs:38:1 + --> tests/ui/derive.rs:39:1 | LL | / impl<'a> Clone for Lt<'a> { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | unimplemented!() -LL | | } +... | LL | | } | |_^ | note: consider deriving `Clone` or removing `Copy` - --> tests/ui/derive.rs:38:1 + --> tests/ui/derive.rs:39:1 | LL | / impl<'a> Clone for Lt<'a> { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | unimplemented!() -LL | | } +... | LL | | } | |_^ error: you are implementing `Clone` explicitly on a `Copy` type - --> tests/ui/derive.rs:50:1 + --> tests/ui/derive.rs:52:1 | LL | / impl Clone for BigArray { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | unimplemented!() -LL | | } +... | LL | | } | |_^ | note: consider deriving `Clone` or removing `Copy` - --> tests/ui/derive.rs:50:1 + --> tests/ui/derive.rs:52:1 | LL | / impl Clone for BigArray { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | unimplemented!() -LL | | } +... | LL | | } | |_^ error: you are implementing `Clone` explicitly on a `Copy` type - --> tests/ui/derive.rs:62:1 + --> tests/ui/derive.rs:65:1 | LL | / impl Clone for FnPtr { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | unimplemented!() -LL | | } +... | LL | | } | |_^ | note: consider deriving `Clone` or removing `Copy` - --> tests/ui/derive.rs:62:1 + --> tests/ui/derive.rs:65:1 | LL | / impl Clone for FnPtr { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | unimplemented!() -LL | | } +... | LL | | } | |_^ error: you are implementing `Clone` explicitly on a `Copy` type - --> tests/ui/derive.rs:83:1 + --> tests/ui/derive.rs:87:1 | LL | / impl Clone for Generic2 { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | Self(self.0.clone()) -LL | | } +... | LL | | } | |_^ | note: consider deriving `Clone` or removing `Copy` - --> tests/ui/derive.rs:83:1 + --> tests/ui/derive.rs:87:1 | LL | / impl Clone for Generic2 { LL | | +LL | | LL | | fn clone(&self) -> Self { -LL | | Self(self.0.clone()) -LL | | } +... | LL | | } | |_^ diff --git a/tests/ui/derive_ord_xor_partial_ord.rs b/tests/ui/derive_ord_xor_partial_ord.rs index 1c7e6d1c2023..0a2a1ee7bc9f 100644 --- a/tests/ui/derive_ord_xor_partial_ord.rs +++ b/tests/ui/derive_ord_xor_partial_ord.rs @@ -20,7 +20,8 @@ impl PartialOrd for DeriveBoth { } #[derive(Ord, PartialEq, Eq)] -//~^ ERROR: you are deriving `Ord` but have implemented `PartialOrd` explicitly +//~^ derive_ord_xor_partial_ord + struct DeriveOrd; impl PartialOrd for DeriveOrd { @@ -30,7 +31,8 @@ impl PartialOrd for DeriveOrd { } #[derive(Ord, PartialEq, Eq)] -//~^ ERROR: you are deriving `Ord` but have implemented `PartialOrd` explicitly +//~^ derive_ord_xor_partial_ord + struct DeriveOrdWithExplicitTypeVariable; impl PartialOrd for DeriveOrdWithExplicitTypeVariable { @@ -43,7 +45,8 @@ impl PartialOrd for DeriveOrdWithExplicitType struct DerivePartialOrd; impl std::cmp::Ord for DerivePartialOrd { - //~^ ERROR: you are implementing `Ord` explicitly but have derived `PartialOrd` +//~^ derive_ord_xor_partial_ord + fn cmp(&self, other: &Self) -> Ordering { Ordering::Less } @@ -64,7 +67,8 @@ mod use_ord { struct DerivePartialOrdInUseOrd; impl Ord for DerivePartialOrdInUseOrd { - //~^ ERROR: you are implementing `Ord` explicitly but have derived `PartialOrd` + //~^ derive_ord_xor_partial_ord + fn cmp(&self, other: &Self) -> Ordering { Ordering::Less } diff --git a/tests/ui/derive_ord_xor_partial_ord.stderr b/tests/ui/derive_ord_xor_partial_ord.stderr index dcf32419baa2..6bbe54eeaa6a 100644 --- a/tests/ui/derive_ord_xor_partial_ord.stderr +++ b/tests/ui/derive_ord_xor_partial_ord.stderr @@ -5,7 +5,7 @@ LL | #[derive(Ord, PartialEq, Eq)] | ^^^ | note: `PartialOrd` implemented here - --> tests/ui/derive_ord_xor_partial_ord.rs:26:1 + --> tests/ui/derive_ord_xor_partial_ord.rs:27:1 | LL | impl PartialOrd for DeriveOrd { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -14,49 +14,49 @@ LL | impl PartialOrd for DeriveOrd { = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `Ord` but have implemented `PartialOrd` explicitly - --> tests/ui/derive_ord_xor_partial_ord.rs:32:10 + --> tests/ui/derive_ord_xor_partial_ord.rs:33:10 | LL | #[derive(Ord, PartialEq, Eq)] | ^^^ | note: `PartialOrd` implemented here - --> tests/ui/derive_ord_xor_partial_ord.rs:36:1 + --> tests/ui/derive_ord_xor_partial_ord.rs:38:1 | LL | impl PartialOrd for DeriveOrdWithExplicitTypeVariable { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are implementing `Ord` explicitly but have derived `PartialOrd` - --> tests/ui/derive_ord_xor_partial_ord.rs:45:1 + --> tests/ui/derive_ord_xor_partial_ord.rs:47:1 | LL | / impl std::cmp::Ord for DerivePartialOrd { LL | | +LL | | LL | | fn cmp(&self, other: &Self) -> Ordering { -LL | | Ordering::Less -LL | | } +... | LL | | } | |_^ | note: `PartialOrd` implemented here - --> tests/ui/derive_ord_xor_partial_ord.rs:42:10 + --> tests/ui/derive_ord_xor_partial_ord.rs:44:10 | LL | #[derive(PartialOrd, PartialEq, Eq)] | ^^^^^^^^^^ = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are implementing `Ord` explicitly but have derived `PartialOrd` - --> tests/ui/derive_ord_xor_partial_ord.rs:66:5 + --> tests/ui/derive_ord_xor_partial_ord.rs:69:5 | LL | / impl Ord for DerivePartialOrdInUseOrd { LL | | +LL | | LL | | fn cmp(&self, other: &Self) -> Ordering { -LL | | Ordering::Less -LL | | } +... | LL | | } | |_____^ | note: `PartialOrd` implemented here - --> tests/ui/derive_ord_xor_partial_ord.rs:63:14 + --> tests/ui/derive_ord_xor_partial_ord.rs:66:14 | LL | #[derive(PartialOrd, PartialEq, Eq)] | ^^^^^^^^^^ diff --git a/tests/ui/derive_partial_eq_without_eq.fixed b/tests/ui/derive_partial_eq_without_eq.fixed index e4a33193a1ab..00f51d6acb94 100644 --- a/tests/ui/derive_partial_eq_without_eq.fixed +++ b/tests/ui/derive_partial_eq_without_eq.fixed @@ -9,6 +9,7 @@ pub struct NotPartialEq { // Eq can be derived but is missing #[derive(Debug, PartialEq, Eq)] +//~^ derive_partial_eq_without_eq pub struct MissingEq { foo: u32, bar: String, @@ -67,33 +68,39 @@ impl PartialEq for ManualPartialEqImpl { // Generic fields should be properly checked for Eq-ness #[derive(PartialEq, Eq)] +//~^ derive_partial_eq_without_eq pub struct GenericNotEq { foo: T, bar: U, } #[derive(PartialEq, Eq)] +//~^ derive_partial_eq_without_eq pub struct GenericEq { foo: T, bar: U, } #[derive(PartialEq, Eq)] +//~^ derive_partial_eq_without_eq pub struct TupleStruct(u32); #[derive(PartialEq, Eq)] +//~^ derive_partial_eq_without_eq pub struct GenericTupleStruct(T); #[derive(PartialEq)] pub struct TupleStructNotEq(f32); #[derive(PartialEq, Eq)] +//~^ derive_partial_eq_without_eq pub enum Enum { Foo(u32), Bar { a: String, b: () }, } #[derive(PartialEq, Eq)] +//~^ derive_partial_eq_without_eq pub enum GenericEnum { Foo(T), Bar { a: U, b: V }, @@ -107,9 +114,11 @@ pub enum EnumNotEq { // Ensure that rustfix works properly when `PartialEq` has other derives on either side #[derive(Debug, PartialEq, Eq, Clone)] +//~^ derive_partial_eq_without_eq pub struct RustFixWithOtherDerives; #[derive(PartialEq, Eq)] +//~^ derive_partial_eq_without_eq pub struct Generic(T); #[derive(PartialEq, Eq)] @@ -117,9 +126,11 @@ pub struct GenericPhantom(core::marker::PhantomData); mod _hidden { #[derive(PartialEq, Eq)] + //~^ derive_partial_eq_without_eq pub struct Reexported; #[derive(PartialEq, Eq)] + //~^ derive_partial_eq_without_eq pub struct InPubFn; #[derive(PartialEq)] @@ -180,7 +191,8 @@ mod struct_gen { } #[derive(PartialEq, Eq)] - //~^ ERROR: you are deriving `PartialEq` and can implement `Eq` + //~^ derive_partial_eq_without_eq + pub struct Foo(::Element); #[derive(PartialEq, Eq)] @@ -188,7 +200,8 @@ mod struct_gen { // issue 9319 #[derive(PartialEq, Eq)] - //~^ ERROR: you are deriving `PartialEq` and can implement `Eq` + //~^ derive_partial_eq_without_eq + pub struct Oof(T); #[derive(PartialEq, Eq)] diff --git a/tests/ui/derive_partial_eq_without_eq.rs b/tests/ui/derive_partial_eq_without_eq.rs index a418b38e3499..073330468d31 100644 --- a/tests/ui/derive_partial_eq_without_eq.rs +++ b/tests/ui/derive_partial_eq_without_eq.rs @@ -9,6 +9,7 @@ pub struct NotPartialEq { // Eq can be derived but is missing #[derive(Debug, PartialEq)] +//~^ derive_partial_eq_without_eq pub struct MissingEq { foo: u32, bar: String, @@ -67,33 +68,39 @@ impl PartialEq for ManualPartialEqImpl { // Generic fields should be properly checked for Eq-ness #[derive(PartialEq)] +//~^ derive_partial_eq_without_eq pub struct GenericNotEq { foo: T, bar: U, } #[derive(PartialEq)] +//~^ derive_partial_eq_without_eq pub struct GenericEq { foo: T, bar: U, } #[derive(PartialEq)] +//~^ derive_partial_eq_without_eq pub struct TupleStruct(u32); #[derive(PartialEq)] +//~^ derive_partial_eq_without_eq pub struct GenericTupleStruct(T); #[derive(PartialEq)] pub struct TupleStructNotEq(f32); #[derive(PartialEq)] +//~^ derive_partial_eq_without_eq pub enum Enum { Foo(u32), Bar { a: String, b: () }, } #[derive(PartialEq)] +//~^ derive_partial_eq_without_eq pub enum GenericEnum { Foo(T), Bar { a: U, b: V }, @@ -107,9 +114,11 @@ pub enum EnumNotEq { // Ensure that rustfix works properly when `PartialEq` has other derives on either side #[derive(Debug, PartialEq, Clone)] +//~^ derive_partial_eq_without_eq pub struct RustFixWithOtherDerives; #[derive(PartialEq)] +//~^ derive_partial_eq_without_eq pub struct Generic(T); #[derive(PartialEq, Eq)] @@ -117,9 +126,11 @@ pub struct GenericPhantom(core::marker::PhantomData); mod _hidden { #[derive(PartialEq)] + //~^ derive_partial_eq_without_eq pub struct Reexported; #[derive(PartialEq)] + //~^ derive_partial_eq_without_eq pub struct InPubFn; #[derive(PartialEq)] @@ -180,7 +191,8 @@ mod struct_gen { } #[derive(PartialEq)] - //~^ ERROR: you are deriving `PartialEq` and can implement `Eq` + //~^ derive_partial_eq_without_eq + pub struct Foo(::Element); #[derive(PartialEq, Eq)] @@ -188,7 +200,8 @@ mod struct_gen { // issue 9319 #[derive(PartialEq)] - //~^ ERROR: you are deriving `PartialEq` and can implement `Eq` + //~^ derive_partial_eq_without_eq + pub struct Oof(T); #[derive(PartialEq, Eq)] diff --git a/tests/ui/derive_partial_eq_without_eq.stderr b/tests/ui/derive_partial_eq_without_eq.stderr index 7436114fadb2..fd9bac28a711 100644 --- a/tests/ui/derive_partial_eq_without_eq.stderr +++ b/tests/ui/derive_partial_eq_without_eq.stderr @@ -8,19 +8,13 @@ LL | #[derive(Debug, PartialEq)] = help: to override `-D warnings` add `#[allow(clippy::derive_partial_eq_without_eq)]` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:69:10 + --> tests/ui/derive_partial_eq_without_eq.rs:70:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:75:10 - | -LL | #[derive(PartialEq)] - | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` - -error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:81:10 + --> tests/ui/derive_partial_eq_without_eq.rs:77:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` @@ -32,49 +26,55 @@ LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:90:10 + --> tests/ui/derive_partial_eq_without_eq.rs:88:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:96:10 + --> tests/ui/derive_partial_eq_without_eq.rs:95:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:109:17 + --> tests/ui/derive_partial_eq_without_eq.rs:102:10 + | +LL | #[derive(PartialEq)] + | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` + +error: you are deriving `PartialEq` and can implement `Eq` + --> tests/ui/derive_partial_eq_without_eq.rs:116:17 | LL | #[derive(Debug, PartialEq, Clone)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:112:10 + --> tests/ui/derive_partial_eq_without_eq.rs:120:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:119:14 + --> tests/ui/derive_partial_eq_without_eq.rs:128:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:122:14 + --> tests/ui/derive_partial_eq_without_eq.rs:132:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:182:14 + --> tests/ui/derive_partial_eq_without_eq.rs:193:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:190:14 + --> tests/ui/derive_partial_eq_without_eq.rs:202:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` diff --git a/tests/ui/derived_hash_with_manual_eq.rs b/tests/ui/derived_hash_with_manual_eq.rs index 8423699d99ed..88b574add3f2 100644 --- a/tests/ui/derived_hash_with_manual_eq.rs +++ b/tests/ui/derived_hash_with_manual_eq.rs @@ -10,7 +10,8 @@ impl PartialEq for Foo { } #[derive(Hash)] -//~^ ERROR: you are deriving `Hash` but have implemented `PartialEq` explicitly +//~^ derived_hash_with_manual_eq + struct Bar; impl PartialEq for Bar { @@ -20,7 +21,8 @@ impl PartialEq for Bar { } #[derive(Hash)] -//~^ ERROR: you are deriving `Hash` but have implemented `PartialEq` explicitly +//~^ derived_hash_with_manual_eq + struct Baz; impl PartialEq for Baz { diff --git a/tests/ui/derived_hash_with_manual_eq.stderr b/tests/ui/derived_hash_with_manual_eq.stderr index af4d247f95ba..19a24e752810 100644 --- a/tests/ui/derived_hash_with_manual_eq.stderr +++ b/tests/ui/derived_hash_with_manual_eq.stderr @@ -5,7 +5,7 @@ LL | #[derive(Hash)] | ^^^^ | note: `PartialEq` implemented here - --> tests/ui/derived_hash_with_manual_eq.rs:16:1 + --> tests/ui/derived_hash_with_manual_eq.rs:17:1 | LL | impl PartialEq for Bar { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -13,13 +13,13 @@ LL | impl PartialEq for Bar { = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `Hash` but have implemented `PartialEq` explicitly - --> tests/ui/derived_hash_with_manual_eq.rs:22:10 + --> tests/ui/derived_hash_with_manual_eq.rs:23:10 | LL | #[derive(Hash)] | ^^^^ | note: `PartialEq` implemented here - --> tests/ui/derived_hash_with_manual_eq.rs:26:1 + --> tests/ui/derived_hash_with_manual_eq.rs:28:1 | LL | impl PartialEq for Baz { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/disallowed_names.rs b/tests/ui/disallowed_names.rs index 96531bf8d88c..d6e26dfcf202 100644 --- a/tests/ui/disallowed_names.rs +++ b/tests/ui/disallowed_names.rs @@ -10,16 +10,20 @@ #![warn(clippy::disallowed_names)] fn test(foo: ()) {} -//~^ ERROR: use of a disallowed/placeholder name `foo` -//~| NOTE: `-D clippy::disallowed-names` implied by `-D warnings` +//~^ disallowed_names + + fn main() { let foo = 42; - //~^ ERROR: use of a disallowed/placeholder name `foo` + //~^ disallowed_names + let baz = 42; - //~^ ERROR: use of a disallowed/placeholder name `baz` + //~^ disallowed_names + let quux = 42; - //~^ ERROR: use of a disallowed/placeholder name `quux` + //~^ disallowed_names + // Unlike these others, `bar` is actually considered an acceptable name. // Among many other legitimate uses, bar commonly refers to a period of time in music. // See https://github.com/rust-lang/rust-clippy/issues/5225. @@ -31,33 +35,43 @@ fn main() { match (42, Some(1337), Some(0)) { (foo, Some(baz), quux @ Some(_)) => (), - //~^ ERROR: use of a disallowed/placeholder name `foo` - //~| ERROR: use of a disallowed/placeholder name `baz` - //~| ERROR: use of a disallowed/placeholder name `quux` + //~^ disallowed_names + //~| disallowed_names + //~| disallowed_names + + + _ => (), } } fn issue_1647(mut foo: u8) { - //~^ ERROR: use of a disallowed/placeholder name `foo` +//~^ disallowed_names + let mut baz = 0; - //~^ ERROR: use of a disallowed/placeholder name `baz` + //~^ disallowed_names + if let Some(mut quux) = Some(42) {} - //~^ ERROR: use of a disallowed/placeholder name `quux` + //~^ disallowed_names + } fn issue_1647_ref() { let ref baz = 0; - //~^ ERROR: use of a disallowed/placeholder name `baz` + //~^ disallowed_names + if let Some(ref quux) = Some(42) {} - //~^ ERROR: use of a disallowed/placeholder name `quux` + //~^ disallowed_names + } fn issue_1647_ref_mut() { let ref mut baz = 0; - //~^ ERROR: use of a disallowed/placeholder name `baz` + //~^ disallowed_names + if let Some(ref mut quux) = Some(42) {} - //~^ ERROR: use of a disallowed/placeholder name `quux` + //~^ disallowed_names + } #[cfg(test)] diff --git a/tests/ui/disallowed_names.stderr b/tests/ui/disallowed_names.stderr index d131cad8e11e..e412d27e7fca 100644 --- a/tests/ui/disallowed_names.stderr +++ b/tests/ui/disallowed_names.stderr @@ -8,79 +8,79 @@ LL | fn test(foo: ()) {} = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]` error: use of a disallowed/placeholder name `foo` - --> tests/ui/disallowed_names.rs:17:9 + --> tests/ui/disallowed_names.rs:18:9 | LL | let foo = 42; | ^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:19:9 + --> tests/ui/disallowed_names.rs:21:9 | LL | let baz = 42; | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:21:9 + --> tests/ui/disallowed_names.rs:24:9 | LL | let quux = 42; | ^^^^ error: use of a disallowed/placeholder name `foo` - --> tests/ui/disallowed_names.rs:33:10 + --> tests/ui/disallowed_names.rs:37:10 | LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:33:20 + --> tests/ui/disallowed_names.rs:37:20 | LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:33:26 + --> tests/ui/disallowed_names.rs:37:26 | LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^^ error: use of a disallowed/placeholder name `foo` - --> tests/ui/disallowed_names.rs:41:19 + --> tests/ui/disallowed_names.rs:48:19 | LL | fn issue_1647(mut foo: u8) { | ^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:43:13 + --> tests/ui/disallowed_names.rs:51:13 | LL | let mut baz = 0; | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:45:21 + --> tests/ui/disallowed_names.rs:54:21 | LL | if let Some(mut quux) = Some(42) {} | ^^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:50:13 + --> tests/ui/disallowed_names.rs:60:13 | LL | let ref baz = 0; | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:52:21 + --> tests/ui/disallowed_names.rs:63:21 | LL | if let Some(ref quux) = Some(42) {} | ^^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:57:17 + --> tests/ui/disallowed_names.rs:69:17 | LL | let ref mut baz = 0; | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:59:25 + --> tests/ui/disallowed_names.rs:72:25 | LL | if let Some(ref mut quux) = Some(42) {} | ^^^^ diff --git a/tests/ui/disallowed_script_idents.rs b/tests/ui/disallowed_script_idents.rs index 6b68fae318c0..00308d0063a8 100644 --- a/tests/ui/disallowed_script_idents.rs +++ b/tests/ui/disallowed_script_idents.rs @@ -9,8 +9,10 @@ fn main() { // Cyrillic is not allowed by default. let счётчик = 10; - //~^ ERROR: identifier `счётчик` has a Unicode script that is not allowed by configura + //~^ disallowed_script_idents + // Same for japanese. let カウンタ = 10; - //~^ ERROR: identifier `カウンタ` has a Unicode script that is not allowed by configuratio + //~^ disallowed_script_idents + } diff --git a/tests/ui/disallowed_script_idents.stderr b/tests/ui/disallowed_script_idents.stderr index c11655ab6021..edbcea5e5dd6 100644 --- a/tests/ui/disallowed_script_idents.stderr +++ b/tests/ui/disallowed_script_idents.stderr @@ -11,7 +11,7 @@ LL | #![deny(clippy::disallowed_script_idents)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: identifier `カウンタ` has a Unicode script that is not allowed by configuration: Katakana - --> tests/ui/disallowed_script_idents.rs:14:9 + --> tests/ui/disallowed_script_idents.rs:15:9 | LL | let カウンタ = 10; | ^^^^^^^^ diff --git a/tests/ui/diverging_sub_expression.rs b/tests/ui/diverging_sub_expression.rs index 1abba60fd34a..e3b40a0cae11 100644 --- a/tests/ui/diverging_sub_expression.rs +++ b/tests/ui/diverging_sub_expression.rs @@ -18,10 +18,12 @@ impl A { fn main() { let b = true; b || diverge(); - //~^ ERROR: sub-expression diverges - //~| NOTE: `-D clippy::diverging-sub-expression` implied by `-D warnings` + //~^ diverging_sub_expression + + b || A.foo(); - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + } #[allow(dead_code, unused_variables)] @@ -32,28 +34,36 @@ fn foobar() { 4 => return, 5 => continue, 6 => true || return, - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + 7 => true || continue, - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + 8 => break, 9 => diverge(), 3 => true || diverge(), - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + 10 => match 42 { 99 => return, _ => true || panic!("boo"), - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + }, // lint blocks as well 15 => true || { return; }, - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + 16 => false || { return; }, - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + // ... and when it's a single expression 17 => true || { return }, - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + 18 => false || { return }, - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + // ... but not when there's both an expression and a statement 19 => true || { _ = 1; return }, 20 => false || { _ = 1; return }, @@ -63,7 +73,8 @@ fn foobar() { 23 => true || { return; true }, 24 => true || { return; true }, _ => true || break, - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + }; } } diff --git a/tests/ui/diverging_sub_expression.stderr b/tests/ui/diverging_sub_expression.stderr index f90c95696a9c..617c7a0be8ab 100644 --- a/tests/ui/diverging_sub_expression.stderr +++ b/tests/ui/diverging_sub_expression.stderr @@ -8,31 +8,31 @@ LL | b || diverge(); = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]` error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:23:10 + --> tests/ui/diverging_sub_expression.rs:24:10 | LL | b || A.foo(); | ^^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:34:26 + --> tests/ui/diverging_sub_expression.rs:36:26 | LL | 6 => true || return, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:36:26 + --> tests/ui/diverging_sub_expression.rs:39:26 | LL | 7 => true || continue, | ^^^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:40:26 + --> tests/ui/diverging_sub_expression.rs:44:26 | LL | 3 => true || diverge(), | ^^^^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:44:30 + --> tests/ui/diverging_sub_expression.rs:49:30 | LL | _ => true || panic!("boo"), | ^^^^^^^^^^^^^ @@ -40,31 +40,31 @@ LL | _ => true || panic!("boo"), = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:48:29 + --> tests/ui/diverging_sub_expression.rs:54:29 | LL | 15 => true || { return; }, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:50:30 + --> tests/ui/diverging_sub_expression.rs:57:30 | LL | 16 => false || { return; }, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:53:29 + --> tests/ui/diverging_sub_expression.rs:61:29 | LL | 17 => true || { return }, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:55:30 + --> tests/ui/diverging_sub_expression.rs:64:30 | LL | 18 => false || { return }, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:65:26 + --> tests/ui/diverging_sub_expression.rs:75:26 | LL | _ => true || break, | ^^^^^ diff --git a/tests/ui/doc/doc-fixable.fixed b/tests/ui/doc/doc-fixable.fixed index 83574a5cd98d..5f2b697f88b0 100644 --- a/tests/ui/doc/doc-fixable.fixed +++ b/tests/ui/doc/doc-fixable.fixed @@ -7,13 +7,22 @@ #![rustfmt::skip] /// The `foo_bar` function does _nothing_. See also `foo::bar`. (note the dot there) +//~^ doc_markdown +//~| doc_markdown /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun` +//~^ doc_markdown /// which should be reported only once despite being __doubly bad__. /// Here be `::a::global:path`, and _`::another::global::path`_. :: is not a path though. +//~^ doc_markdown +//~| doc_markdown /// Import an item from `::awesome::global::blob::` (Intended postfix) +//~^ doc_markdown /// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted) +//~^ doc_markdown /// That's not code ~`NotInCodeBlock`~. +//~^ doc_markdown /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn foo_bar() { } @@ -28,6 +37,7 @@ fn foo_bar() { /// _foo bar_ /// ~~~ /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn multiline_codeblock() { } @@ -35,6 +45,7 @@ fn multiline_codeblock() { /// multiline /// emphasis_. /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn test_emphasis() { } @@ -49,6 +60,7 @@ fn test_emphasis() { /// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb /// NaN /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn test_units() { } @@ -77,6 +89,7 @@ fn test_units() { /// MinGW /// CamelCase (see also #2395) /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn test_allowed() { } @@ -94,6 +107,7 @@ fn test_allowed() { /// expression of the type `_ m c` (where `` /// is one of {`&`, '|'} and `` is one of {`!=`, `>=`, `>` , /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn main() { foo_bar(); multiline_codeblock(); @@ -102,12 +116,16 @@ fn main() { } /// ## `CamelCaseThing` +//~^ doc_markdown /// Talks about `CamelCaseThing`. Titles should be ignored; see issue #897. /// /// # `CamelCaseThing` +//~^ doc_markdown /// /// Not a title #897 `CamelCaseThing` +//~^ doc_markdown /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn issue897() { } @@ -115,6 +133,7 @@ fn issue897() { /// I am confused by brackets? (foo `x_y`) /// I am confused by brackets? (`x_y` foo) /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn issue900() { } @@ -128,6 +147,7 @@ fn issue900() { /// [iterator]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html /// [helper_types]: ../helper_types/index.html /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn issue883() { } @@ -146,6 +166,9 @@ That's in a code block: `PackedNode` And `BarQuz` too. `be_sure_we_got_to_the_end_of_it` */ +//~^^^ doc_markdown +//~^^^ doc_markdown +//~^^^^^^^^^^ doc_markdown fn issue1073() { } @@ -157,6 +180,9 @@ That's in a code block: PackedNode And `BarQuz` too. `be_sure_we_got_to_the_end_of_it` */ +//~^^ doc_markdown +//~^^^^ doc_markdown +//~^^^^^^^^^^ doc_markdown fn issue1073_alt() { } @@ -167,6 +193,7 @@ fn issue1073_alt() { /// StillDont /// ```` /// `be_sure_we_got_to_the_end_of_it` +//~^ doc_markdown fn four_quotes() { } @@ -186,6 +213,7 @@ fn issue_1469() {} fn issue_1920() {} /// An iterator over `mycrate::Collection`'s values. +//~^ doc_markdown /// It should not lint a `'static` lifetime in ticks. fn issue_2210() {} @@ -210,6 +238,7 @@ fn intra_doc_link() {} fn issue_2581() {} /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint` +//~^ doc_markdown fn lint_after_escaped_chars() {} // issue #7033 - generic_const_exprs ICE @@ -233,17 +262,22 @@ where [(); N.checked_next_power_of_two().unwrap()]: { fn issue_11568() {} /// There is no try (`do()` or `do_not()`). +//~^ doc_markdown +//~| doc_markdown fn parenthesized_word() {} /// `ABes` +//~^ doc_markdown /// OSes /// UXes fn plural_acronym_test() {} extern "C" { /// `foo()` + //~^ doc_markdown fn in_extern(); } /// +//~^ doc_markdown fn check_autofix_for_base_urls() {} diff --git a/tests/ui/doc/doc-fixable.rs b/tests/ui/doc/doc-fixable.rs index 20fe89cdc536..ed3925694c67 100644 --- a/tests/ui/doc/doc-fixable.rs +++ b/tests/ui/doc/doc-fixable.rs @@ -7,13 +7,22 @@ #![rustfmt::skip] /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there) +//~^ doc_markdown +//~| doc_markdown /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun +//~^ doc_markdown /// which should be reported only once despite being __doubly bad__. /// Here be ::a::global:path, and _::another::global::path_. :: is not a path though. +//~^ doc_markdown +//~| doc_markdown /// Import an item from ::awesome::global::blob:: (Intended postfix) +//~^ doc_markdown /// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted) +//~^ doc_markdown /// That's not code ~NotInCodeBlock~. +//~^ doc_markdown /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn foo_bar() { } @@ -28,6 +37,7 @@ fn foo_bar() { /// _foo bar_ /// ~~~ /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn multiline_codeblock() { } @@ -35,6 +45,7 @@ fn multiline_codeblock() { /// multiline /// emphasis_. /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn test_emphasis() { } @@ -49,6 +60,7 @@ fn test_emphasis() { /// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb /// NaN /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn test_units() { } @@ -77,6 +89,7 @@ fn test_units() { /// MinGW /// CamelCase (see also #2395) /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn test_allowed() { } @@ -94,6 +107,7 @@ fn test_allowed() { /// expression of the type `_ m c` (where `` /// is one of {`&`, '|'} and `` is one of {`!=`, `>=`, `>` , /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn main() { foo_bar(); multiline_codeblock(); @@ -102,12 +116,16 @@ fn main() { } /// ## CamelCaseThing +//~^ doc_markdown /// Talks about `CamelCaseThing`. Titles should be ignored; see issue #897. /// /// # CamelCaseThing +//~^ doc_markdown /// /// Not a title #897 CamelCaseThing +//~^ doc_markdown /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn issue897() { } @@ -115,6 +133,7 @@ fn issue897() { /// I am confused by brackets? (foo `x_y`) /// I am confused by brackets? (`x_y` foo) /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn issue900() { } @@ -128,6 +147,7 @@ fn issue900() { /// [iterator]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html /// [helper_types]: ../helper_types/index.html /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn issue883() { } @@ -146,6 +166,9 @@ That's in a code block: `PackedNode` And BarQuz too. be_sure_we_got_to_the_end_of_it */ +//~^^^ doc_markdown +//~^^^ doc_markdown +//~^^^^^^^^^^ doc_markdown fn issue1073() { } @@ -157,6 +180,9 @@ That's in a code block: PackedNode And BarQuz too. be_sure_we_got_to_the_end_of_it */ +//~^^ doc_markdown +//~^^^^ doc_markdown +//~^^^^^^^^^^ doc_markdown fn issue1073_alt() { } @@ -167,6 +193,7 @@ fn issue1073_alt() { /// StillDont /// ```` /// be_sure_we_got_to_the_end_of_it +//~^ doc_markdown fn four_quotes() { } @@ -186,6 +213,7 @@ fn issue_1469() {} fn issue_1920() {} /// An iterator over mycrate::Collection's values. +//~^ doc_markdown /// It should not lint a `'static` lifetime in ticks. fn issue_2210() {} @@ -210,6 +238,7 @@ fn intra_doc_link() {} fn issue_2581() {} /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint +//~^ doc_markdown fn lint_after_escaped_chars() {} // issue #7033 - generic_const_exprs ICE @@ -233,17 +262,22 @@ where [(); N.checked_next_power_of_two().unwrap()]: { fn issue_11568() {} /// There is no try (do() or do_not()). +//~^ doc_markdown +//~| doc_markdown fn parenthesized_word() {} /// ABes +//~^ doc_markdown /// OSes /// UXes fn plural_acronym_test() {} extern "C" { /// foo() + //~^ doc_markdown fn in_extern(); } /// https://github.com/rust-lang/rust-clippy/pull/12836 +//~^ doc_markdown fn check_autofix_for_base_urls() {} diff --git a/tests/ui/doc/doc-fixable.stderr b/tests/ui/doc/doc-fixable.stderr index 27a04e4b5583..f630f72ca854 100644 --- a/tests/ui/doc/doc-fixable.stderr +++ b/tests/ui/doc/doc-fixable.stderr @@ -23,7 +23,7 @@ LL | /// The foo_bar function does _nothing_. See also `foo::bar`. (note the dot | ~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:10:83 + --> tests/ui/doc/doc-fixable.rs:12:83 | LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun | ^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. B | ~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:12:13 + --> tests/ui/doc/doc-fixable.rs:15:13 | LL | /// Here be ::a::global:path, and _::another::global::path_. :: is not a path though. | ^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | /// Here be `::a::global:path`, and _::another::global::path_. :: is not a | ~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:12:36 + --> tests/ui/doc/doc-fixable.rs:15:36 | LL | /// Here be ::a::global:path, and _::another::global::path_. :: is not a path though. | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | /// Here be ::a::global:path, and _`::another::global::path`_. :: is not a | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:13:25 + --> tests/ui/doc/doc-fixable.rs:18:25 | LL | /// Import an item from ::awesome::global::blob:: (Intended postfix) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | /// Import an item from `::awesome::global::blob::` (Intended postfix) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:14:31 + --> tests/ui/doc/doc-fixable.rs:20:31 | LL | /// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted) | ^^^^^ @@ -78,7 +78,7 @@ LL | /// These are the options for `::Cat`: (Intended trailing single colon, sho | ~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:15:22 + --> tests/ui/doc/doc-fixable.rs:22:22 | LL | /// That's not code ~NotInCodeBlock~. | ^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | /// That's not code ~`NotInCodeBlock`~. | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:16:5 + --> tests/ui/doc/doc-fixable.rs:24:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:30:5 + --> tests/ui/doc/doc-fixable.rs:39:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:37:5 + --> tests/ui/doc/doc-fixable.rs:47:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:51:5 + --> tests/ui/doc/doc-fixable.rs:62:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:79:5 + --> tests/ui/doc/doc-fixable.rs:91:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:96:5 + --> tests/ui/doc/doc-fixable.rs:109:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:104:8 + --> tests/ui/doc/doc-fixable.rs:118:8 | LL | /// ## CamelCaseThing | ^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | /// ## `CamelCaseThing` | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:107:7 + --> tests/ui/doc/doc-fixable.rs:122:7 | LL | /// # CamelCaseThing | ^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | /// # `CamelCaseThing` | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:109:22 + --> tests/ui/doc/doc-fixable.rs:125:22 | LL | /// Not a title #897 CamelCaseThing | ^^^^^^^^^^^^^^ @@ -188,7 +188,7 @@ LL | /// Not a title #897 `CamelCaseThing` | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:110:5 + --> tests/ui/doc/doc-fixable.rs:127:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:117:5 + --> tests/ui/doc/doc-fixable.rs:135:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,7 +210,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:130:5 + --> tests/ui/doc/doc-fixable.rs:149:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +221,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:141:43 + --> tests/ui/doc/doc-fixable.rs:161:43 | LL | /** E.g., serialization of an empty list: FooBar | ^^^^^^ @@ -232,7 +232,7 @@ LL | /** E.g., serialization of an empty list: `FooBar` | ~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:146:5 + --> tests/ui/doc/doc-fixable.rs:166:5 | LL | And BarQuz too. | ^^^^^^ @@ -243,7 +243,7 @@ LL | And `BarQuz` too. | ~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:147:1 + --> tests/ui/doc/doc-fixable.rs:167:1 | LL | be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -254,7 +254,7 @@ LL | `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:152:43 + --> tests/ui/doc/doc-fixable.rs:175:43 | LL | /** E.g., serialization of an empty list: FooBar | ^^^^^^ @@ -265,7 +265,7 @@ LL | /** E.g., serialization of an empty list: `FooBar` | ~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:157:5 + --> tests/ui/doc/doc-fixable.rs:180:5 | LL | And BarQuz too. | ^^^^^^ @@ -276,7 +276,7 @@ LL | And `BarQuz` too. | ~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:158:1 + --> tests/ui/doc/doc-fixable.rs:181:1 | LL | be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -287,7 +287,7 @@ LL | `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:169:5 + --> tests/ui/doc/doc-fixable.rs:195:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -298,7 +298,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:188:22 + --> tests/ui/doc/doc-fixable.rs:215:22 | LL | /// An iterator over mycrate::Collection's values. | ^^^^^^^^^^^^^^^^^^^ @@ -309,7 +309,7 @@ LL | /// An iterator over `mycrate::Collection`'s values. | ~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:212:34 + --> tests/ui/doc/doc-fixable.rs:240:34 | LL | /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint | ^^^^^^^^^^^^^^^ @@ -320,7 +320,7 @@ LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint` | ~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:235:22 + --> tests/ui/doc/doc-fixable.rs:264:22 | LL | /// There is no try (do() or do_not()). | ^^^^ @@ -331,7 +331,7 @@ LL | /// There is no try (`do()` or do_not()). | ~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:235:30 + --> tests/ui/doc/doc-fixable.rs:264:30 | LL | /// There is no try (do() or do_not()). | ^^^^^^^^ @@ -342,7 +342,7 @@ LL | /// There is no try (do() or `do_not()`). | ~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:238:5 + --> tests/ui/doc/doc-fixable.rs:269:5 | LL | /// ABes | ^^^^ @@ -353,7 +353,7 @@ LL | /// `ABes` | ~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:244:9 + --> tests/ui/doc/doc-fixable.rs:276:9 | LL | /// foo() | ^^^^^ @@ -364,7 +364,7 @@ LL | /// `foo()` | ~~~~~~~ error: you should put bare URLs between `<`/`>` or make a proper Markdown link - --> tests/ui/doc/doc-fixable.rs:248:5 + --> tests/ui/doc/doc-fixable.rs:281:5 | LL | /// https://github.com/rust-lang/rust-clippy/pull/12836 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `` diff --git a/tests/ui/doc/doc_include_without_cfg.fixed b/tests/ui/doc/doc_include_without_cfg.fixed index d4ae810d7385..a05954adf5a5 100644 --- a/tests/ui/doc/doc_include_without_cfg.fixed +++ b/tests/ui/doc/doc_include_without_cfg.fixed @@ -1,7 +1,8 @@ #![warn(clippy::doc_include_without_cfg)] // Should not lint. #![doc(html_playground_url = "https://playground.example.com/")] -#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))] //~ doc_include_without_cfg +#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))] +//~^ doc_include_without_cfg // Should not lint. #![cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))] #![cfg_attr(doc, doc = include_str!("../approx_const.rs"))] @@ -28,7 +29,8 @@ tst! { /// This is a test with no included file } -#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))] //~ doc_include_without_cfg +#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))] +//~^ doc_include_without_cfg // Should not lint. #[doc = man_link!("bla", "blob")] #[cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))] diff --git a/tests/ui/doc/doc_include_without_cfg.rs b/tests/ui/doc/doc_include_without_cfg.rs index c82f6bf20356..26aa7a3a706a 100644 --- a/tests/ui/doc/doc_include_without_cfg.rs +++ b/tests/ui/doc/doc_include_without_cfg.rs @@ -1,7 +1,8 @@ #![warn(clippy::doc_include_without_cfg)] // Should not lint. #![doc(html_playground_url = "https://playground.example.com/")] -#![doc = include_str!("../approx_const.rs")] //~ doc_include_without_cfg +#![doc = include_str!("../approx_const.rs")] +//~^ doc_include_without_cfg // Should not lint. #![cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))] #![cfg_attr(doc, doc = include_str!("../approx_const.rs"))] @@ -28,7 +29,8 @@ tst! { /// This is a test with no included file } -#[doc = include_str!("../approx_const.rs")] //~ doc_include_without_cfg +#[doc = include_str!("../approx_const.rs")] +//~^ doc_include_without_cfg // Should not lint. #[doc = man_link!("bla", "blob")] #[cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))] diff --git a/tests/ui/doc/doc_include_without_cfg.stderr b/tests/ui/doc/doc_include_without_cfg.stderr index 17ea53c7c318..24991df581e8 100644 --- a/tests/ui/doc/doc_include_without_cfg.stderr +++ b/tests/ui/doc/doc_include_without_cfg.stderr @@ -8,7 +8,7 @@ LL | #![doc = include_str!("../approx_const.rs")] = help: to override `-D warnings` add `#[allow(clippy::doc_include_without_cfg)]` error: included a file in documentation unconditionally - --> tests/ui/doc/doc_include_without_cfg.rs:31:1 + --> tests/ui/doc/doc_include_without_cfg.rs:32:1 | LL | #[doc = include_str!("../approx_const.rs")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `cfg_attr(doc, doc = "...")`: `#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))]` diff --git a/tests/ui/doc/footnote_issue_13183.rs b/tests/ui/doc/footnote_issue_13183.rs index a18b4c3ac539..dbb01bd5155b 100644 --- a/tests/ui/doc/footnote_issue_13183.rs +++ b/tests/ui/doc/footnote_issue_13183.rs @@ -1,3 +1,4 @@ +//@ check-pass // This is a regression test for . // It should not warn on missing backticks on footnote references. diff --git a/tests/ui/doc/issue_12795.fixed b/tests/ui/doc/issue_12795.fixed index ade23bf975c2..ff252c07ae8c 100644 --- a/tests/ui/doc/issue_12795.fixed +++ b/tests/ui/doc/issue_12795.fixed @@ -1,9 +1,13 @@ #![warn(clippy::doc_markdown)] //! A comment with `a_b(x)` and `a_c` in it and (`a_b((c))` ) too and (maybe `a_b((c))`) -//~^ ERROR: item in documentation is missing backticks -//~| ERROR: item in documentation is missing backticks -//~| ERROR: item in documentation is missing backticks -//~| ERROR: item in documentation is missing backticks +//~^ doc_markdown +//~| doc_markdown +//~| doc_markdown +//~| doc_markdown + + + + pub fn main() {} diff --git a/tests/ui/doc/issue_12795.rs b/tests/ui/doc/issue_12795.rs index 6d94a07e3036..b7e89cf4ea0e 100644 --- a/tests/ui/doc/issue_12795.rs +++ b/tests/ui/doc/issue_12795.rs @@ -1,9 +1,13 @@ #![warn(clippy::doc_markdown)] //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c))) -//~^ ERROR: item in documentation is missing backticks -//~| ERROR: item in documentation is missing backticks -//~| ERROR: item in documentation is missing backticks -//~| ERROR: item in documentation is missing backticks +//~^ doc_markdown +//~| doc_markdown +//~| doc_markdown +//~| doc_markdown + + + + pub fn main() {} diff --git a/tests/ui/doc/issue_1832.rs b/tests/ui/doc/issue_1832.rs index 10586f16d466..9678badd11c8 100644 --- a/tests/ui/doc/issue_1832.rs +++ b/tests/ui/doc/issue_1832.rs @@ -1,3 +1,4 @@ +//@ check-pass /// Ok: /// /// Not ok: http://www.unicode.org diff --git a/tests/ui/doc/issue_902.rs b/tests/ui/doc/issue_902.rs index 4b0c835dd3f0..1be6db01dcb2 100644 --- a/tests/ui/doc/issue_902.rs +++ b/tests/ui/doc/issue_902.rs @@ -1,3 +1,4 @@ +//@ check-pass /// See [NIST SP 800-56A, revision 2]. /// /// [NIST SP 800-56A, revision 2]: diff --git a/tests/ui/doc/issue_9473.fixed b/tests/ui/doc/issue_9473.fixed index 276ce7620ca7..2d910c43b263 100644 --- a/tests/ui/doc/issue_9473.fixed +++ b/tests/ui/doc/issue_9473.fixed @@ -6,4 +6,5 @@ pub struct Foo(u32); // Should warn. /// Blah blah blah [FooBar]<[FooBar]>[`FooBar`]. +//~^ doc_markdown pub struct FooBar(u32); diff --git a/tests/ui/doc/issue_9473.rs b/tests/ui/doc/issue_9473.rs index 52527f7106d1..e5798685382a 100644 --- a/tests/ui/doc/issue_9473.rs +++ b/tests/ui/doc/issue_9473.rs @@ -6,4 +6,5 @@ pub struct Foo(u32); // Should warn. /// Blah blah blah [FooBar]<[FooBar]>[FooBar]. +//~^ doc_markdown pub struct FooBar(u32); diff --git a/tests/ui/doc/needless_doctest_main.rs b/tests/ui/doc/needless_doctest_main.rs index f1a2c0575ee5..633a435ca5ed 100644 --- a/tests/ui/doc/needless_doctest_main.rs +++ b/tests/ui/doc/needless_doctest_main.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::needless_doctest_main)] //! issue 10491: //! ```rust,no_test diff --git a/tests/ui/doc/unbalanced_ticks.rs b/tests/ui/doc/unbalanced_ticks.rs index 04446787b6c2..8adbb1f7f714 100644 --- a/tests/ui/doc/unbalanced_ticks.rs +++ b/tests/ui/doc/unbalanced_ticks.rs @@ -5,20 +5,22 @@ #![warn(clippy::doc_markdown)] /// This is a doc comment with `unbalanced_tick marks and several words that -//~^ ERROR: backticks are unbalanced +//~^ empty_line_after_doc_comments + /// should be `encompassed_by` tick marks because they `contain_underscores`. /// Because of the initial `unbalanced_tick` pair, the error message is /// very `confusing_and_misleading`. fn main() {} /// This paragraph has `unbalanced_tick marks and should stop_linting. -//~^ ERROR: backticks are unbalanced +//~^ empty_line_after_doc_comments + /// /// This paragraph is fine and should_be linted normally. -//~^ ERROR: item in documentation is missing backticks + /// /// Double unbalanced backtick from ``here to here` should lint. -//~^ ERROR: backticks are unbalanced + /// /// Double balanced back ticks ``start end`` is fine. fn multiple_paragraphs() {} @@ -32,15 +34,16 @@ fn in_code_block() {} /// # `Fine` /// /// ## not_fine -//~^ ERROR: item in documentation is missing backticks +//~^ empty_line_after_doc_comments + /// /// ### `unbalanced -//~^ ERROR: backticks are unbalanced + /// /// - This `item has unbalanced tick marks -//~^ ERROR: backticks are unbalanced + /// - This item needs backticks_here -//~^ ERROR: item in documentation is missing backticks + fn other_markdown() {} #[rustfmt::skip] @@ -51,7 +54,8 @@ fn other_markdown() {} fn issue_7421() {} /// ` -//~^ ERROR: backticks are unbalanced +//~^ empty_line_after_doc_comments + fn escape_0() {} /// Escaped \` backticks don't count. @@ -61,7 +65,8 @@ fn escape_1() {} fn escape_2() {} /// Escaped \` ` backticks don't count, but unescaped backticks do. -//~^ ERROR: backticks are unbalanced +//~^ empty_line_after_doc_comments + fn escape_3() {} /// Backslashes ` \` within code blocks don't count. diff --git a/tests/ui/doc/unbalanced_ticks.stderr b/tests/ui/doc/unbalanced_ticks.stderr index 50324010e97f..563d86376481 100644 --- a/tests/ui/doc/unbalanced_ticks.stderr +++ b/tests/ui/doc/unbalanced_ticks.stderr @@ -1,98 +1,112 @@ -error: backticks are unbalanced - --> tests/ui/doc/unbalanced_ticks.rs:7:5 +error: empty line after doc comment + --> tests/ui/doc/unbalanced_ticks.rs:7:1 | -LL | /// This is a doc comment with `unbalanced_tick marks and several words that - | _____^ +LL | / /// This is a doc comment with `unbalanced_tick marks and several words that LL | | -LL | | /// should be `encompassed_by` tick marks because they `contain_underscores`. -LL | | /// Because of the initial `unbalanced_tick` pair, the error message is -LL | | /// very `confusing_and_misleading`. - | |____________________________________^ +LL | | + | |_^ +... +LL | fn main() {} + | --------- the comment documents this function | - = help: a backtick may be missing a pair - = note: `-D clippy::doc-markdown` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` + = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]` + = help: if the empty line is unintentional remove it +help: if the doc comment should not document `main` comment it out + | +LL | // /// This is a doc comment with `unbalanced_tick marks and several words that + | ++ -error: backticks are unbalanced - --> tests/ui/doc/unbalanced_ticks.rs:14:5 +error: empty lines after doc comment + --> tests/ui/doc/unbalanced_ticks.rs:15:1 | -LL | /// This paragraph has `unbalanced_tick marks and should stop_linting. - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / /// This paragraph has `unbalanced_tick marks and should stop_linting. +LL | | +LL | | +LL | | /// +... | +LL | | /// Double unbalanced backtick from ``here to here` should lint. +LL | | + | |_^ +... +LL | fn multiple_paragraphs() {} + | ------------------------ the comment documents this function + | + = help: if the empty lines are unintentional remove them +help: if the doc comment should not document `multiple_paragraphs` comment it out + | +LL ~ // /// This paragraph has `unbalanced_tick marks and should stop_linting. +LL | +LL | +LL ~ // /// +LL ~ // /// This paragraph is fine and should_be linted normally. +LL | +LL ~ // /// +LL ~ // /// Double unbalanced backtick from ``here to here` should lint. | - = help: a backtick may be missing a pair -error: item in documentation is missing backticks - --> tests/ui/doc/unbalanced_ticks.rs:17:32 +error: empty lines after doc comment + --> tests/ui/doc/unbalanced_ticks.rs:36:1 | -LL | /// This paragraph is fine and should_be linted normally. - | ^^^^^^^^^ +LL | / /// ## not_fine +LL | | +LL | | +LL | | /// +... | +LL | | /// - This item needs backticks_here +LL | | + | |_^ +LL | fn other_markdown() {} + | ------------------- the comment documents this function | -help: try + = help: if the empty lines are unintentional remove them +help: if the doc comment should not document `other_markdown` comment it out + | +LL ~ // /// # `Fine` +LL ~ // /// +LL ~ // /// ## not_fine +LL | +LL | +LL ~ // /// +LL ~ // /// ### `unbalanced +LL | +LL ~ // /// +LL ~ // /// - This `item has unbalanced tick marks +LL | +LL ~ // /// - This item needs backticks_here | -LL | /// This paragraph is fine and `should_be` linted normally. - | ~~~~~~~~~~~ -error: backticks are unbalanced - --> tests/ui/doc/unbalanced_ticks.rs:20:5 +error: empty line after doc comment + --> tests/ui/doc/unbalanced_ticks.rs:56:1 | -LL | /// Double unbalanced backtick from ``here to here` should lint. - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / /// ` +LL | | +LL | | + | |_^ +LL | fn escape_0() {} + | ------------- the comment documents this function | - = help: a backtick may be missing a pair + = help: if the empty line is unintentional remove it +help: if the doc comment should not document `escape_0` comment it out + | +LL | // /// ` + | ++ -error: item in documentation is missing backticks - --> tests/ui/doc/unbalanced_ticks.rs:34:8 +error: empty line after doc comment + --> tests/ui/doc/unbalanced_ticks.rs:67:1 | -LL | /// ## not_fine - | ^^^^^^^^ +LL | / /// Escaped \` ` backticks don't count, but unescaped backticks do. +LL | | +LL | | + | |_^ +LL | fn escape_3() {} + | ------------- the comment documents this function | -help: try + = help: if the empty line is unintentional remove it +help: if the doc comment should not document `escape_3` comment it out | -LL | /// ## `not_fine` - | ~~~~~~~~~~ +LL | // /// Escaped \` ` backticks don't count, but unescaped backticks do. + | ++ -error: backticks are unbalanced - --> tests/ui/doc/unbalanced_ticks.rs:37:5 - | -LL | /// ### `unbalanced - | ^^^^^^^^^^^^^^^ - | - = help: a backtick may be missing a pair - -error: backticks are unbalanced - --> tests/ui/doc/unbalanced_ticks.rs:40:5 - | -LL | /// - This `item has unbalanced tick marks - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: a backtick may be missing a pair - -error: item in documentation is missing backticks - --> tests/ui/doc/unbalanced_ticks.rs:42:23 - | -LL | /// - This item needs backticks_here - | ^^^^^^^^^^^^^^ - | -help: try - | -LL | /// - This item needs `backticks_here` - | ~~~~~~~~~~~~~~~~ - -error: backticks are unbalanced - --> tests/ui/doc/unbalanced_ticks.rs:53:5 - | -LL | /// ` - | ^ - | - = help: a backtick may be missing a pair - -error: backticks are unbalanced - --> tests/ui/doc/unbalanced_ticks.rs:63:5 - | -LL | /// Escaped \` ` backticks don't count, but unescaped backticks do. - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: a backtick may be missing a pair - -error: aborting due to 10 previous errors +error: aborting due to 5 previous errors diff --git a/tests/ui/doc_errors.rs b/tests/ui/doc_errors.rs index 9b3783aaf09d..65783b22a58c 100644 --- a/tests/ui/doc_errors.rs +++ b/tests/ui/doc_errors.rs @@ -5,25 +5,29 @@ use std::io; pub fn pub_fn_missing_errors_header() -> Result<(), ()> { - //~^ ERROR: docs for function returning `Result` missing `# Errors` section - //~| NOTE: `-D clippy::missing-errors-doc` implied by `-D warnings` +//~^ missing_errors_doc + + unimplemented!(); } pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> { - //~^ ERROR: docs for function returning `Result` missing `# Errors` section +//~^ missing_errors_doc + unimplemented!(); } /// This is not sufficiently documented. pub fn pub_fn_returning_io_result() -> io::Result<()> { - //~^ ERROR: docs for function returning `Result` missing `# Errors` section +//~^ missing_errors_doc + unimplemented!(); } /// This is not sufficiently documented. pub async fn async_pub_fn_returning_io_result() -> io::Result<()> { - //~^ ERROR: docs for function returning `Result` missing `# Errors` section +//~^ missing_errors_doc + unimplemented!(); } @@ -54,13 +58,15 @@ pub struct Struct1; impl Struct1 { /// This is not sufficiently documented. pub fn pub_method_missing_errors_header() -> Result<(), ()> { - //~^ ERROR: docs for function returning `Result` missing `# Errors` section + //~^ missing_errors_doc + unimplemented!(); } /// This is not sufficiently documented. pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> { - //~^ ERROR: docs for function returning `Result` missing `# Errors` section + //~^ missing_errors_doc + unimplemented!(); } @@ -111,7 +117,8 @@ impl Struct1 { pub trait Trait1 { /// This is not sufficiently documented. fn trait_method_missing_errors_header() -> Result<(), ()>; - //~^ ERROR: docs for function returning `Result` missing `# Errors` section + //~^ missing_errors_doc + /// # Errors /// A description of the errors goes here. diff --git a/tests/ui/doc_errors.stderr b/tests/ui/doc_errors.stderr index c5b9479adace..e719c186e600 100644 --- a/tests/ui/doc_errors.stderr +++ b/tests/ui/doc_errors.stderr @@ -8,37 +8,37 @@ LL | pub fn pub_fn_missing_errors_header() -> Result<(), ()> { = help: to override `-D warnings` add `#[allow(clippy::missing_errors_doc)]` error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:13:1 + --> tests/ui/doc_errors.rs:14:1 | LL | pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:19:1 + --> tests/ui/doc_errors.rs:21:1 | LL | pub fn pub_fn_returning_io_result() -> io::Result<()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:25:1 + --> tests/ui/doc_errors.rs:28:1 | LL | pub async fn async_pub_fn_returning_io_result() -> io::Result<()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:56:5 + --> tests/ui/doc_errors.rs:60:5 | LL | pub fn pub_method_missing_errors_header() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:62:5 + --> tests/ui/doc_errors.rs:67:5 | LL | pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:113:5 + --> tests/ui/doc_errors.rs:119:5 | LL | fn trait_method_missing_errors_header() -> Result<(), ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/doc_link_with_quotes.rs b/tests/ui/doc_link_with_quotes.rs index 48e1b1819c6f..e2614e6b4318 100644 --- a/tests/ui/doc_link_with_quotes.rs +++ b/tests/ui/doc_link_with_quotes.rs @@ -1,18 +1,18 @@ #![warn(clippy::doc_link_with_quotes)] +#![allow(clippy::empty_line_after_doc_comments)] fn main() { foo() } /// Calls ['bar'] uselessly -//~^ ERROR: possible intra-doc link using quotes instead of backticks -//~| NOTE: `-D clippy::doc-link-with-quotes` implied by `-D warnings` +//~^ doc_link_with_quotes pub fn foo() { bar() } /// Calls ["bar"] uselessly -//~^ ERROR: possible intra-doc link using quotes instead of backticks +//~^ doc_link_with_quotes pub fn foo2() { bar() } diff --git a/tests/ui/doc_link_with_quotes.stderr b/tests/ui/doc_link_with_quotes.stderr index e4be59c65719..1c1d8e0ffd52 100644 --- a/tests/ui/doc_link_with_quotes.stderr +++ b/tests/ui/doc_link_with_quotes.stderr @@ -1,5 +1,5 @@ error: possible intra-doc link using quotes instead of backticks - --> tests/ui/doc_link_with_quotes.rs:7:12 + --> tests/ui/doc_link_with_quotes.rs:8:12 | LL | /// Calls ['bar'] uselessly | ^^^^^ diff --git a/tests/ui/doc_unsafe.rs b/tests/ui/doc_unsafe.rs index f7f41c915e3f..ccdc59bfb5a2 100644 --- a/tests/ui/doc_unsafe.rs +++ b/tests/ui/doc_unsafe.rs @@ -7,6 +7,7 @@ use proc_macros::external; /// This is not sufficiently documented pub unsafe fn destroy_the_planet() { +//~^ missing_safety_doc unimplemented!(); } @@ -30,6 +31,7 @@ mod private_mod { } pub unsafe fn republished() { + //~^ missing_safety_doc unimplemented!(); } } @@ -38,12 +40,14 @@ pub use private_mod::republished; pub trait SafeTraitUnsafeMethods { unsafe fn woefully_underdocumented(self); + //~^ missing_safety_doc /// # Safety unsafe fn at_least_somewhat_documented(self); } pub unsafe trait UnsafeTrait { +//~^ missing_safety_doc fn method(); } @@ -74,6 +78,7 @@ unsafe impl DocumentedUnsafeTrait for Struct { impl Struct { pub unsafe fn more_undocumented_unsafe() -> Self { + //~^ missing_safety_doc unimplemented!(); } @@ -90,6 +95,7 @@ impl Struct { macro_rules! very_unsafe { () => { pub unsafe fn whee() { + //~^ missing_safety_doc unimplemented!() } diff --git a/tests/ui/doc_unsafe.stderr b/tests/ui/doc_unsafe.stderr index 929afbceb879..6e128133d498 100644 --- a/tests/ui/doc_unsafe.stderr +++ b/tests/ui/doc_unsafe.stderr @@ -8,31 +8,31 @@ LL | pub unsafe fn destroy_the_planet() { = help: to override `-D warnings` add `#[allow(clippy::missing_safety_doc)]` error: unsafe function's docs are missing a `# Safety` section - --> tests/ui/doc_unsafe.rs:32:5 + --> tests/ui/doc_unsafe.rs:33:5 | LL | pub unsafe fn republished() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe function's docs are missing a `# Safety` section - --> tests/ui/doc_unsafe.rs:40:5 + --> tests/ui/doc_unsafe.rs:42:5 | LL | unsafe fn woefully_underdocumented(self); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for unsafe trait missing `# Safety` section - --> tests/ui/doc_unsafe.rs:46:1 + --> tests/ui/doc_unsafe.rs:49:1 | LL | pub unsafe trait UnsafeTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe function's docs are missing a `# Safety` section - --> tests/ui/doc_unsafe.rs:76:5 + --> tests/ui/doc_unsafe.rs:80:5 | LL | pub unsafe fn more_undocumented_unsafe() -> Self { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe function's docs are missing a `# Safety` section - --> tests/ui/doc_unsafe.rs:92:9 + --> tests/ui/doc_unsafe.rs:97:9 | LL | pub unsafe fn whee() { | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/double_comparison.fixed b/tests/ui/double_comparison.fixed index 788f3224b418..e9d707cdb53d 100644 --- a/tests/ui/double_comparison.fixed +++ b/tests/ui/double_comparison.fixed @@ -4,27 +4,35 @@ fn main() { let x = 1; let y = 2; if x <= y { + //~^ double_comparisons // do something } if x <= y { + //~^ double_comparisons // do something } if x >= y { + //~^ double_comparisons // do something } if x >= y { + //~^ double_comparisons // do something } if x != y { + //~^ double_comparisons // do something } if x != y { + //~^ double_comparisons // do something } if x == y { + //~^ double_comparisons // do something } if x == y { + //~^ double_comparisons // do something } } diff --git a/tests/ui/double_comparison.rs b/tests/ui/double_comparison.rs index 245a83d5709d..4b9a141747db 100644 --- a/tests/ui/double_comparison.rs +++ b/tests/ui/double_comparison.rs @@ -4,27 +4,35 @@ fn main() { let x = 1; let y = 2; if x == y || x < y { + //~^ double_comparisons // do something } if x < y || x == y { + //~^ double_comparisons // do something } if x == y || x > y { + //~^ double_comparisons // do something } if x > y || x == y { + //~^ double_comparisons // do something } if x < y || x > y { + //~^ double_comparisons // do something } if x > y || x < y { + //~^ double_comparisons // do something } if x <= y && x >= y { + //~^ double_comparisons // do something } if x >= y && x <= y { + //~^ double_comparisons // do something } } diff --git a/tests/ui/double_comparison.stderr b/tests/ui/double_comparison.stderr index 01ba7a8ee108..984614c203eb 100644 --- a/tests/ui/double_comparison.stderr +++ b/tests/ui/double_comparison.stderr @@ -8,43 +8,43 @@ LL | if x == y || x < y { = help: to override `-D warnings` add `#[allow(clippy::double_comparisons)]` error: this binary expression can be simplified - --> tests/ui/double_comparison.rs:9:8 + --> tests/ui/double_comparison.rs:10:8 | LL | if x < y || x == y { | ^^^^^^^^^^^^^^^ help: try: `x <= y` error: this binary expression can be simplified - --> tests/ui/double_comparison.rs:12:8 + --> tests/ui/double_comparison.rs:14:8 | LL | if x == y || x > y { | ^^^^^^^^^^^^^^^ help: try: `x >= y` error: this binary expression can be simplified - --> tests/ui/double_comparison.rs:15:8 + --> tests/ui/double_comparison.rs:18:8 | LL | if x > y || x == y { | ^^^^^^^^^^^^^^^ help: try: `x >= y` error: this binary expression can be simplified - --> tests/ui/double_comparison.rs:18:8 + --> tests/ui/double_comparison.rs:22:8 | LL | if x < y || x > y { | ^^^^^^^^^^^^^^ help: try: `x != y` error: this binary expression can be simplified - --> tests/ui/double_comparison.rs:21:8 + --> tests/ui/double_comparison.rs:26:8 | LL | if x > y || x < y { | ^^^^^^^^^^^^^^ help: try: `x != y` error: this binary expression can be simplified - --> tests/ui/double_comparison.rs:24:8 + --> tests/ui/double_comparison.rs:30:8 | LL | if x <= y && x >= y { | ^^^^^^^^^^^^^^^^ help: try: `x == y` error: this binary expression can be simplified - --> tests/ui/double_comparison.rs:27:8 + --> tests/ui/double_comparison.rs:34:8 | LL | if x >= y && x <= y { | ^^^^^^^^^^^^^^^^ help: try: `x == y` diff --git a/tests/ui/double_ended_iterator_last.fixed b/tests/ui/double_ended_iterator_last.fixed index 06c48e337537..08f3d4907153 100644 --- a/tests/ui/double_ended_iterator_last.fixed +++ b/tests/ui/double_ended_iterator_last.fixed @@ -3,6 +3,7 @@ // Typical case pub fn last_arg(s: &str) -> Option<&str> { s.split(' ').next_back() + //~^ double_ended_iterator_last } fn main() { @@ -20,6 +21,7 @@ fn main() { } } let _ = DeIterator.next_back(); + //~^ double_ended_iterator_last // Should not apply to other methods of Iterator let _ = DeIterator.count(); diff --git a/tests/ui/double_ended_iterator_last.rs b/tests/ui/double_ended_iterator_last.rs index 9c13b496d117..2c2f311805ef 100644 --- a/tests/ui/double_ended_iterator_last.rs +++ b/tests/ui/double_ended_iterator_last.rs @@ -3,6 +3,7 @@ // Typical case pub fn last_arg(s: &str) -> Option<&str> { s.split(' ').last() + //~^ double_ended_iterator_last } fn main() { @@ -20,6 +21,7 @@ fn main() { } } let _ = DeIterator.last(); + //~^ double_ended_iterator_last // Should not apply to other methods of Iterator let _ = DeIterator.count(); diff --git a/tests/ui/double_ended_iterator_last.stderr b/tests/ui/double_ended_iterator_last.stderr index b795c18a736e..ea1962176a61 100644 --- a/tests/ui/double_ended_iterator_last.stderr +++ b/tests/ui/double_ended_iterator_last.stderr @@ -8,7 +8,7 @@ LL | s.split(' ').last() = help: to override `-D warnings` add `#[allow(clippy::double_ended_iterator_last)]` error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator - --> tests/ui/double_ended_iterator_last.rs:22:24 + --> tests/ui/double_ended_iterator_last.rs:23:24 | LL | let _ = DeIterator.last(); | ^^^^^^ help: try: `next_back()` diff --git a/tests/ui/double_must_use.rs b/tests/ui/double_must_use.rs index 4460aeb075bf..1f69afad25d4 100644 --- a/tests/ui/double_must_use.rs +++ b/tests/ui/double_must_use.rs @@ -3,19 +3,22 @@ #[must_use] pub fn must_use_result() -> Result<(), ()> { - //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already +//~^ double_must_use + unimplemented!(); } #[must_use] pub fn must_use_tuple() -> (Result<(), ()>, u8) { - //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already +//~^ double_must_use + unimplemented!(); } #[must_use] pub fn must_use_array() -> [Result<(), ()>; 1] { - //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already +//~^ double_must_use + unimplemented!(); } @@ -32,7 +35,8 @@ async fn async_must_use() -> usize { #[must_use] async fn async_must_use_result() -> Result<(), ()> { - //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already +//~^ double_must_use + Ok(()) } diff --git a/tests/ui/double_must_use.stderr b/tests/ui/double_must_use.stderr index b26d1e48a8b8..555dd8902cac 100644 --- a/tests/ui/double_must_use.stderr +++ b/tests/ui/double_must_use.stderr @@ -9,7 +9,7 @@ LL | pub fn must_use_result() -> Result<(), ()> { = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]` error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]` - --> tests/ui/double_must_use.rs:11:1 + --> tests/ui/double_must_use.rs:12:1 | LL | pub fn must_use_tuple() -> (Result<(), ()>, u8) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | pub fn must_use_tuple() -> (Result<(), ()>, u8) { = help: either add some descriptive message or remove the attribute error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]` - --> tests/ui/double_must_use.rs:17:1 + --> tests/ui/double_must_use.rs:19:1 | LL | pub fn must_use_array() -> [Result<(), ()>; 1] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | pub fn must_use_array() -> [Result<(), ()>; 1] { = help: either add some descriptive message or remove the attribute error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]` - --> tests/ui/double_must_use.rs:34:1 + --> tests/ui/double_must_use.rs:37:1 | LL | async fn async_must_use_result() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/double_parens.rs b/tests/ui/double_parens.rs index ab1459eed48b..7c976015b4e7 100644 --- a/tests/ui/double_parens.rs +++ b/tests/ui/double_parens.rs @@ -13,28 +13,33 @@ impl DummyStruct { fn simple_double_parens() -> i32 { ((0)) - //~^ ERROR: consider removing unnecessary double parentheses - //~| NOTE: `-D clippy::double-parens` implied by `-D warnings` + //~^ double_parens + + } fn fn_double_parens() { dummy_fn((0)); - //~^ ERROR: consider removing unnecessary double parentheses + //~^ double_parens + } fn method_double_parens(x: DummyStruct) { x.dummy_method((0)); - //~^ ERROR: consider removing unnecessary double parentheses + //~^ double_parens + } fn tuple_double_parens() -> (i32, i32) { ((1, 2)) - //~^ ERROR: consider removing unnecessary double parentheses + //~^ double_parens + } fn unit_double_parens() { (()) - //~^ ERROR: consider removing unnecessary double parentheses + //~^ double_parens + } fn fn_tuple_ok() { @@ -57,7 +62,8 @@ fn method_unit_ok(x: DummyStruct) { fn inside_macro() { assert_eq!((1, 2), (1, 2), "Error"); assert_eq!(((1, 2)), (1, 2), "Error"); - //~^ ERROR: consider removing unnecessary double parentheses + //~^ double_parens + } fn main() {} diff --git a/tests/ui/double_parens.stderr b/tests/ui/double_parens.stderr index aba301e9f072..e119f54949b1 100644 --- a/tests/ui/double_parens.stderr +++ b/tests/ui/double_parens.stderr @@ -8,31 +8,31 @@ LL | ((0)) = help: to override `-D warnings` add `#[allow(clippy::double_parens)]` error: consider removing unnecessary double parentheses - --> tests/ui/double_parens.rs:21:14 + --> tests/ui/double_parens.rs:22:14 | LL | dummy_fn((0)); | ^^^ error: consider removing unnecessary double parentheses - --> tests/ui/double_parens.rs:26:20 + --> tests/ui/double_parens.rs:28:20 | LL | x.dummy_method((0)); | ^^^ error: consider removing unnecessary double parentheses - --> tests/ui/double_parens.rs:31:5 + --> tests/ui/double_parens.rs:34:5 | LL | ((1, 2)) | ^^^^^^^^ error: consider removing unnecessary double parentheses - --> tests/ui/double_parens.rs:36:5 + --> tests/ui/double_parens.rs:40:5 | LL | (()) | ^^^^ error: consider removing unnecessary double parentheses - --> tests/ui/double_parens.rs:59:16 + --> tests/ui/double_parens.rs:64:16 | LL | assert_eq!(((1, 2)), (1, 2), "Error"); | ^^^^^^^^ diff --git a/tests/ui/drain_collect.fixed b/tests/ui/drain_collect.fixed index 6f597243fe6f..7ae971d975b1 100644 --- a/tests/ui/drain_collect.fixed +++ b/tests/ui/drain_collect.fixed @@ -5,6 +5,7 @@ use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; fn binaryheap(b: &mut BinaryHeap) -> BinaryHeap { std::mem::take(b) + //~^ drain_collect } fn binaryheap_dont_lint(b: &mut BinaryHeap) -> HashSet { @@ -13,6 +14,7 @@ fn binaryheap_dont_lint(b: &mut BinaryHeap) -> HashSet { fn hashmap(b: &mut HashMap) -> HashMap { std::mem::take(b) + //~^ drain_collect } fn hashmap_dont_lint(b: &mut HashMap) -> Vec<(i32, i32)> { @@ -21,6 +23,7 @@ fn hashmap_dont_lint(b: &mut HashMap) -> Vec<(i32, i32)> { fn hashset(b: &mut HashSet) -> HashSet { std::mem::take(b) + //~^ drain_collect } fn hashset_dont_lint(b: &mut HashSet) -> Vec { @@ -29,6 +32,7 @@ fn hashset_dont_lint(b: &mut HashSet) -> Vec { fn vecdeque(b: &mut VecDeque) -> VecDeque { std::mem::take(b) + //~^ drain_collect } fn vecdeque_dont_lint(b: &mut VecDeque) -> HashSet { @@ -37,23 +41,28 @@ fn vecdeque_dont_lint(b: &mut VecDeque) -> HashSet { fn vec(b: &mut Vec) -> Vec { std::mem::take(b) + //~^ drain_collect } fn vec2(b: &mut Vec) -> Vec { std::mem::take(b) + //~^ drain_collect } fn vec3(b: &mut Vec) -> Vec { std::mem::take(b) + //~^ drain_collect } fn vec4(b: &mut Vec) -> Vec { std::mem::take(b) + //~^ drain_collect } fn vec_no_reborrow() -> Vec { let mut b = vec![1, 2, 3]; std::mem::take(&mut b) + //~^ drain_collect } fn vec_dont_lint(b: &mut Vec) -> HashSet { @@ -62,6 +71,7 @@ fn vec_dont_lint(b: &mut Vec) -> HashSet { fn string(b: &mut String) -> String { std::mem::take(b) + //~^ drain_collect } fn string_dont_lint(b: &mut String) -> HashSet { diff --git a/tests/ui/drain_collect.rs b/tests/ui/drain_collect.rs index 353aac4da9a4..e99d84fa8b66 100644 --- a/tests/ui/drain_collect.rs +++ b/tests/ui/drain_collect.rs @@ -5,6 +5,7 @@ use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; fn binaryheap(b: &mut BinaryHeap) -> BinaryHeap { b.drain().collect() + //~^ drain_collect } fn binaryheap_dont_lint(b: &mut BinaryHeap) -> HashSet { @@ -13,6 +14,7 @@ fn binaryheap_dont_lint(b: &mut BinaryHeap) -> HashSet { fn hashmap(b: &mut HashMap) -> HashMap { b.drain().collect() + //~^ drain_collect } fn hashmap_dont_lint(b: &mut HashMap) -> Vec<(i32, i32)> { @@ -21,6 +23,7 @@ fn hashmap_dont_lint(b: &mut HashMap) -> Vec<(i32, i32)> { fn hashset(b: &mut HashSet) -> HashSet { b.drain().collect() + //~^ drain_collect } fn hashset_dont_lint(b: &mut HashSet) -> Vec { @@ -29,6 +32,7 @@ fn hashset_dont_lint(b: &mut HashSet) -> Vec { fn vecdeque(b: &mut VecDeque) -> VecDeque { b.drain(..).collect() + //~^ drain_collect } fn vecdeque_dont_lint(b: &mut VecDeque) -> HashSet { @@ -37,23 +41,28 @@ fn vecdeque_dont_lint(b: &mut VecDeque) -> HashSet { fn vec(b: &mut Vec) -> Vec { b.drain(..).collect() + //~^ drain_collect } fn vec2(b: &mut Vec) -> Vec { b.drain(0..).collect() + //~^ drain_collect } fn vec3(b: &mut Vec) -> Vec { b.drain(..b.len()).collect() + //~^ drain_collect } fn vec4(b: &mut Vec) -> Vec { b.drain(0..b.len()).collect() + //~^ drain_collect } fn vec_no_reborrow() -> Vec { let mut b = vec![1, 2, 3]; b.drain(..).collect() + //~^ drain_collect } fn vec_dont_lint(b: &mut Vec) -> HashSet { @@ -62,6 +71,7 @@ fn vec_dont_lint(b: &mut Vec) -> HashSet { fn string(b: &mut String) -> String { b.drain(..).collect() + //~^ drain_collect } fn string_dont_lint(b: &mut String) -> HashSet { diff --git a/tests/ui/drain_collect.stderr b/tests/ui/drain_collect.stderr index 1dfd0f1e3463..cfb1e01b65cf 100644 --- a/tests/ui/drain_collect.stderr +++ b/tests/ui/drain_collect.stderr @@ -11,25 +11,19 @@ LL | #![deny(clippy::drain_collect)] | ^^^^^^^^^^^^^^^^^^^^^ error: you seem to be trying to move all elements into a new `HashMap` - --> tests/ui/drain_collect.rs:15:5 + --> tests/ui/drain_collect.rs:16:5 | LL | b.drain().collect() | ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` error: you seem to be trying to move all elements into a new `HashSet` - --> tests/ui/drain_collect.rs:23:5 + --> tests/ui/drain_collect.rs:25:5 | LL | b.drain().collect() | ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` error: you seem to be trying to move all elements into a new `Vec` - --> tests/ui/drain_collect.rs:31:5 - | -LL | b.drain(..).collect() - | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` - -error: you seem to be trying to move all elements into a new `Vec` - --> tests/ui/drain_collect.rs:39:5 + --> tests/ui/drain_collect.rs:34:5 | LL | b.drain(..).collect() | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` @@ -37,29 +31,35 @@ LL | b.drain(..).collect() error: you seem to be trying to move all elements into a new `Vec` --> tests/ui/drain_collect.rs:43:5 | +LL | b.drain(..).collect() + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> tests/ui/drain_collect.rs:48:5 + | LL | b.drain(0..).collect() | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` error: you seem to be trying to move all elements into a new `Vec` - --> tests/ui/drain_collect.rs:47:5 + --> tests/ui/drain_collect.rs:53:5 | LL | b.drain(..b.len()).collect() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` error: you seem to be trying to move all elements into a new `Vec` - --> tests/ui/drain_collect.rs:51:5 + --> tests/ui/drain_collect.rs:58:5 | LL | b.drain(0..b.len()).collect() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` error: you seem to be trying to move all elements into a new `Vec` - --> tests/ui/drain_collect.rs:56:5 + --> tests/ui/drain_collect.rs:64:5 | LL | b.drain(..).collect() | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(&mut b)` error: you seem to be trying to move all elements into a new `String` - --> tests/ui/drain_collect.rs:64:5 + --> tests/ui/drain_collect.rs:73:5 | LL | b.drain(..).collect() | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` diff --git a/tests/ui/drain_collect_nostd.fixed b/tests/ui/drain_collect_nostd.fixed index a4ab2956f2a6..4741922d1dc4 100644 --- a/tests/ui/drain_collect_nostd.fixed +++ b/tests/ui/drain_collect_nostd.fixed @@ -5,4 +5,5 @@ use alloc::vec::Vec; fn remove_all(v: &mut Vec) -> Vec { core::mem::take(v) + //~^ drain_collect } diff --git a/tests/ui/drain_collect_nostd.rs b/tests/ui/drain_collect_nostd.rs index a8be1ce6bbd3..69dcb1c41658 100644 --- a/tests/ui/drain_collect_nostd.rs +++ b/tests/ui/drain_collect_nostd.rs @@ -5,4 +5,5 @@ use alloc::vec::Vec; fn remove_all(v: &mut Vec) -> Vec { v.drain(..).collect() + //~^ drain_collect } diff --git a/tests/ui/drop_non_drop.rs b/tests/ui/drop_non_drop.rs index 6dbcb7777d49..0345e8670ab8 100644 --- a/tests/ui/drop_non_drop.rs +++ b/tests/ui/drop_non_drop.rs @@ -20,7 +20,8 @@ fn main() { struct Foo; // Lint drop(Foo); - //~^ ERROR: call to `std::mem::drop` with a value that does not implement `Drop`. Drop + //~^ drop_non_drop + // Don't lint drop(make_result(Foo)); // Don't lint @@ -36,7 +37,8 @@ fn main() { struct Baz(T); // Lint drop(Baz(Foo)); - //~^ ERROR: call to `std::mem::drop` with a value that does not implement `Drop`. Drop + //~^ drop_non_drop + // Don't lint drop(Baz(Bar)); } diff --git a/tests/ui/drop_non_drop.stderr b/tests/ui/drop_non_drop.stderr index fac89bf1f26a..b431c62c92c5 100644 --- a/tests/ui/drop_non_drop.stderr +++ b/tests/ui/drop_non_drop.stderr @@ -13,13 +13,13 @@ LL | drop(Foo); = help: to override `-D warnings` add `#[allow(clippy::drop_non_drop)]` error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes - --> tests/ui/drop_non_drop.rs:38:5 + --> tests/ui/drop_non_drop.rs:39:5 | LL | drop(Baz(Foo)); | ^^^^^^^^^^^^^^ | note: argument has type `main::Baz` - --> tests/ui/drop_non_drop.rs:38:10 + --> tests/ui/drop_non_drop.rs:39:10 | LL | drop(Baz(Foo)); | ^^^^^^^^ diff --git a/tests/ui/duplicate_underscore_argument.rs b/tests/ui/duplicate_underscore_argument.rs index a725538436cb..cb4930363e8f 100644 --- a/tests/ui/duplicate_underscore_argument.rs +++ b/tests/ui/duplicate_underscore_argument.rs @@ -1,8 +1,9 @@ #![warn(clippy::duplicate_underscore_argument)] fn join_the_dark_side(darth: i32, _darth: i32) {} -//~^ ERROR: `darth` already exists, having another argument having almost the same name ma -//~| NOTE: `-D clippy::duplicate-underscore-argument` implied by `-D warnings` +//~^ duplicate_underscore_argument + + fn join_the_light_side(knight: i32, _master: i32) {} // the Force is strong with this one fn main() { diff --git a/tests/ui/duration_subsec.fixed b/tests/ui/duration_subsec.fixed index 114c516ed1a1..a8c2f78ca383 100644 --- a/tests/ui/duration_subsec.fixed +++ b/tests/ui/duration_subsec.fixed @@ -7,21 +7,26 @@ fn main() { let dur = Duration::new(5, 0); let bad_millis_1 = dur.subsec_millis(); + //~^ duration_subsec let bad_millis_2 = dur.subsec_millis(); + //~^ duration_subsec let good_millis = dur.subsec_millis(); assert_eq!(bad_millis_1, good_millis); assert_eq!(bad_millis_2, good_millis); let bad_micros = dur.subsec_micros(); + //~^ duration_subsec let good_micros = dur.subsec_micros(); assert_eq!(bad_micros, good_micros); // Handle refs let _ = (&dur).subsec_micros(); + //~^ duration_subsec // Handle constants const NANOS_IN_MICRO: u32 = 1_000; let _ = dur.subsec_micros(); + //~^ duration_subsec // Other literals aren't linted let _ = dur.subsec_nanos() / 699; diff --git a/tests/ui/duration_subsec.rs b/tests/ui/duration_subsec.rs index 8469fe086b10..582f4717de27 100644 --- a/tests/ui/duration_subsec.rs +++ b/tests/ui/duration_subsec.rs @@ -7,21 +7,26 @@ fn main() { let dur = Duration::new(5, 0); let bad_millis_1 = dur.subsec_micros() / 1_000; + //~^ duration_subsec let bad_millis_2 = dur.subsec_nanos() / 1_000_000; + //~^ duration_subsec let good_millis = dur.subsec_millis(); assert_eq!(bad_millis_1, good_millis); assert_eq!(bad_millis_2, good_millis); let bad_micros = dur.subsec_nanos() / 1_000; + //~^ duration_subsec let good_micros = dur.subsec_micros(); assert_eq!(bad_micros, good_micros); // Handle refs let _ = (&dur).subsec_nanos() / 1_000; + //~^ duration_subsec // Handle constants const NANOS_IN_MICRO: u32 = 1_000; let _ = dur.subsec_nanos() / NANOS_IN_MICRO; + //~^ duration_subsec // Other literals aren't linted let _ = dur.subsec_nanos() / 699; diff --git a/tests/ui/duration_subsec.stderr b/tests/ui/duration_subsec.stderr index 55e44f149cf1..1a41742e1fa6 100644 --- a/tests/ui/duration_subsec.stderr +++ b/tests/ui/duration_subsec.stderr @@ -8,25 +8,25 @@ LL | let bad_millis_1 = dur.subsec_micros() / 1_000; = help: to override `-D warnings` add `#[allow(clippy::duration_subsec)]` error: calling `subsec_millis()` is more concise than this calculation - --> tests/ui/duration_subsec.rs:10:24 + --> tests/ui/duration_subsec.rs:11:24 | LL | let bad_millis_2 = dur.subsec_nanos() / 1_000_000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_millis()` error: calling `subsec_micros()` is more concise than this calculation - --> tests/ui/duration_subsec.rs:15:22 + --> tests/ui/duration_subsec.rs:17:22 | LL | let bad_micros = dur.subsec_nanos() / 1_000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_micros()` error: calling `subsec_micros()` is more concise than this calculation - --> tests/ui/duration_subsec.rs:20:13 + --> tests/ui/duration_subsec.rs:23:13 | LL | let _ = (&dur).subsec_nanos() / 1_000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&dur).subsec_micros()` error: calling `subsec_micros()` is more concise than this calculation - --> tests/ui/duration_subsec.rs:24:13 + --> tests/ui/duration_subsec.rs:28:13 | LL | let _ = dur.subsec_nanos() / NANOS_IN_MICRO; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_micros()` diff --git a/tests/ui/eager_transmute.fixed b/tests/ui/eager_transmute.fixed index ba4342462dca..14cbb6113e62 100644 --- a/tests/ui/eager_transmute.fixed +++ b/tests/ui/eager_transmute.fixed @@ -19,20 +19,27 @@ struct Data { fn int_to_opcode(op: u8) -> Option { (op < 4).then(|| unsafe { std::mem::transmute(op) }) + //~^ eager_transmute } fn f(op: u8, op2: Data, unrelated: u8) { true.then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); (unrelated < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); + //~^ eager_transmute (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); + //~^ eager_transmute (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); + //~^ eager_transmute let _: Option = (op > 0 && op < 10).then(|| unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (op > 0 && op < 10 && unrelated == 0).then(|| unsafe { std::mem::transmute(op) }); + //~^ eager_transmute // lint even when the transmutable goes through field/array accesses let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| unsafe { std::mem::transmute(op2.foo[0]) }); + //~^ eager_transmute // don't lint: wrong index used in the transmute let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[1]) }); @@ -45,11 +52,17 @@ fn f(op: u8, op2: Data, unrelated: u8) { // range contains checks let _: Option = (1..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = ((1..=3).contains(&op) || op == 4).then(|| unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (1..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (1..).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (..3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) }); + //~^ eager_transmute // unrelated binding in contains let _: Option = (1..=3) @@ -59,6 +72,7 @@ fn f(op: u8, op2: Data, unrelated: u8) { unsafe fn f2(op: u8) { (op < 4).then(|| std::mem::transmute::<_, Opcode>(op)); + //~^ eager_transmute } #[rustc_layout_scalar_valid_range_end(254)] @@ -88,18 +102,21 @@ impls!(NonMaxU8, NonZeroNonMaxU8); fn niche_tests(v1: u8, v2: NonZero, v3: NonZeroNonMaxU8) { // u8 -> NonZero, do lint let _: Option> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) }); + //~^ eager_transmute // NonZero -> u8, don't lint, target type has no niche and therefore a higher validity range let _: Option = (v2 > NonZero::new(1u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); // NonZero -> NonMaxU8, do lint, different niche let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); + //~^ eager_transmute // NonZeroNonMaxU8 -> NonMaxU8, don't lint, target type has more validity let _: Option = (v3 < 255).then_some(unsafe { std::mem::transmute(v2) }); // NonZero -> NonZeroNonMaxU8, do lint, target type has less validity let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) }); + //~^ eager_transmute } fn main() {} diff --git a/tests/ui/eager_transmute.rs b/tests/ui/eager_transmute.rs index 9750e87ce574..48d7d50cdaef 100644 --- a/tests/ui/eager_transmute.rs +++ b/tests/ui/eager_transmute.rs @@ -19,20 +19,27 @@ struct Data { fn int_to_opcode(op: u8) -> Option { (op < 4).then_some(unsafe { std::mem::transmute(op) }) + //~^ eager_transmute } fn f(op: u8, op2: Data, unrelated: u8) { true.then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); (unrelated < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); + //~^ eager_transmute (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); + //~^ eager_transmute (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); + //~^ eager_transmute let _: Option = (op > 0 && op < 10).then_some(unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (op > 0 && op < 10 && unrelated == 0).then_some(unsafe { std::mem::transmute(op) }); + //~^ eager_transmute // lint even when the transmutable goes through field/array accesses let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[0]) }); + //~^ eager_transmute // don't lint: wrong index used in the transmute let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[1]) }); @@ -45,11 +52,17 @@ fn f(op: u8, op2: Data, unrelated: u8) { // range contains checks let _: Option = (1..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = ((1..=3).contains(&op) || op == 4).then_some(unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (1..3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (1..).contains(&op).then_some(unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (..3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); + //~^ eager_transmute let _: Option = (..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); + //~^ eager_transmute // unrelated binding in contains let _: Option = (1..=3) @@ -59,6 +72,7 @@ fn f(op: u8, op2: Data, unrelated: u8) { unsafe fn f2(op: u8) { (op < 4).then_some(std::mem::transmute::<_, Opcode>(op)); + //~^ eager_transmute } #[rustc_layout_scalar_valid_range_end(254)] @@ -88,18 +102,21 @@ impls!(NonMaxU8, NonZeroNonMaxU8); fn niche_tests(v1: u8, v2: NonZero, v3: NonZeroNonMaxU8) { // u8 -> NonZero, do lint let _: Option> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) }); + //~^ eager_transmute // NonZero -> u8, don't lint, target type has no niche and therefore a higher validity range let _: Option = (v2 > NonZero::new(1u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); // NonZero -> NonMaxU8, do lint, different niche let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); + //~^ eager_transmute // NonZeroNonMaxU8 -> NonMaxU8, don't lint, target type has more validity let _: Option = (v3 < 255).then_some(unsafe { std::mem::transmute(v2) }); // NonZero -> NonZeroNonMaxU8, do lint, target type has less validity let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); + //~^ eager_transmute } fn main() {} diff --git a/tests/ui/eager_transmute.stderr b/tests/ui/eager_transmute.stderr index 5cf7bd49a929..e31c12eb5222 100644 --- a/tests/ui/eager_transmute.stderr +++ b/tests/ui/eager_transmute.stderr @@ -12,7 +12,7 @@ LL | (op < 4).then(|| unsafe { std::mem::transmute(op) }) | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:27:33 + --> tests/ui/eager_transmute.rs:28:33 | LL | (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:28:33 + --> tests/ui/eager_transmute.rs:30:33 | LL | (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:29:34 + --> tests/ui/eager_transmute.rs:32:34 | LL | (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) }); | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:31:68 + --> tests/ui/eager_transmute.rs:35:68 | LL | let _: Option = (op > 0 && op < 10).then_some(unsafe { std::mem::transmute(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _: Option = (op > 0 && op < 10).then(|| unsafe { std::mem:: | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:32:86 + --> tests/ui/eager_transmute.rs:37:86 | LL | let _: Option = (op > 0 && op < 10 && unrelated == 0).then_some(unsafe { std::mem::transmute(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let _: Option = (op > 0 && op < 10 && unrelated == 0).then(|| u | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:35:84 + --> tests/ui/eager_transmute.rs:41:84 | LL | let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[0]) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _: Option = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| uns | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:47:70 + --> tests/ui/eager_transmute.rs:54:70 | LL | let _: Option = (1..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _: Option = (1..=3).contains(&op).then(|| unsafe { std::mem | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:48:83 + --> tests/ui/eager_transmute.rs:56:83 | LL | let _: Option = ((1..=3).contains(&op) || op == 4).then_some(unsafe { std::mem::transmute(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let _: Option = ((1..=3).contains(&op) || op == 4).then(|| unsa | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:49:69 + --> tests/ui/eager_transmute.rs:58:69 | LL | let _: Option = (1..3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _: Option = (1..3).contains(&op).then(|| unsafe { std::mem: | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:50:68 + --> tests/ui/eager_transmute.rs:60:68 | LL | let _: Option = (1..).contains(&op).then_some(unsafe { std::mem::transmute(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let _: Option = (1..).contains(&op).then(|| unsafe { std::mem:: | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:51:68 + --> tests/ui/eager_transmute.rs:62:68 | LL | let _: Option = (..3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let _: Option = (..3).contains(&op).then(|| unsafe { std::mem:: | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:52:69 + --> tests/ui/eager_transmute.rs:64:69 | LL | let _: Option = (..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | let _: Option = (..=3).contains(&op).then(|| unsafe { std::mem: | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:61:24 + --> tests/ui/eager_transmute.rs:74:24 | LL | (op < 4).then_some(std::mem::transmute::<_, Opcode>(op)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | (op < 4).then(|| std::mem::transmute::<_, Opcode>(op)); | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:90:62 + --> tests/ui/eager_transmute.rs:104:62 | LL | let _: Option> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | let _: Option> = (v1 > 0).then(|| unsafe { std::mem::transm | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:96:86 + --> tests/ui/eager_transmute.rs:111:86 | LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then(|| u | ~~~~ ++ error: this transmute is always evaluated eagerly, even if the condition is false - --> tests/ui/eager_transmute.rs:102:93 + --> tests/ui/eager_transmute.rs:118:93 | LL | let _: Option = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) }); | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/else_if_without_else.rs b/tests/ui/else_if_without_else.rs index b04c22fa2aed..8c0df6ee8786 100644 --- a/tests/ui/else_if_without_else.rs +++ b/tests/ui/else_if_without_else.rs @@ -49,7 +49,8 @@ fn main() { if bla1() { println!("if"); } else if bla2() { - //~^ ERROR: `if` expression with an `else if`, but without a final `else` + //~^ else_if_without_else + println!("else if"); } @@ -58,7 +59,8 @@ fn main() { } else if bla2() { println!("else if 1"); } else if bla3() { - //~^ ERROR: `if` expression with an `else if`, but without a final `else` + //~^ else_if_without_else + println!("else if 2"); } @@ -85,7 +87,8 @@ fn main() { } else if bla4() { println!("else if 3"); } else if bla5() { - //~^ ERROR: `if` expression with an `else if`, but without a final `else` + //~^ else_if_without_else + println!("else if 4"); } @@ -115,7 +118,8 @@ fn main() { } else if bla4() { println!("else if 3"); } else if bla5() { - //~^ ERROR: `if` expression with an `else if`, but without a final `else` + //~^ else_if_without_else + println!("else if 4"); } } diff --git a/tests/ui/else_if_without_else.stderr b/tests/ui/else_if_without_else.stderr index bc7174852293..ac7802345b97 100644 --- a/tests/ui/else_if_without_else.stderr +++ b/tests/ui/else_if_without_else.stderr @@ -4,6 +4,7 @@ error: `if` expression with an `else if`, but without a final `else` LL | } else if bla2() { | ____________^ LL | | +LL | | LL | | println!("else if"); LL | | } | |_____^ @@ -13,11 +14,12 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::else_if_without_else)]` error: `if` expression with an `else if`, but without a final `else` - --> tests/ui/else_if_without_else.rs:60:12 + --> tests/ui/else_if_without_else.rs:61:12 | LL | } else if bla3() { | ____________^ LL | | +LL | | LL | | println!("else if 2"); LL | | } | |_____^ @@ -25,11 +27,12 @@ LL | | } = help: add an `else` block here error: `if` expression with an `else if`, but without a final `else` - --> tests/ui/else_if_without_else.rs:87:12 + --> tests/ui/else_if_without_else.rs:89:12 | LL | } else if bla5() { | ____________^ LL | | +LL | | LL | | println!("else if 4"); LL | | } | |_____^ @@ -37,11 +40,12 @@ LL | | } = help: add an `else` block here error: `if` expression with an `else if`, but without a final `else` - --> tests/ui/else_if_without_else.rs:117:16 + --> tests/ui/else_if_without_else.rs:120:16 | LL | } else if bla5() { | ________________^ LL | | +LL | | LL | | println!("else if 4"); LL | | } | |_________^ diff --git a/tests/ui/empty_docs.rs b/tests/ui/empty_docs.rs index 00e64eebc5fb..d7768e07901a 100644 --- a/tests/ui/empty_docs.rs +++ b/tests/ui/empty_docs.rs @@ -7,6 +7,7 @@ mod outer { //! + //~^ empty_docs /// this is a struct struct Bananas { @@ -15,8 +16,10 @@ mod outer { } /// + //~^ empty_docs enum Warn { /// + //~^ empty_docs A, B, } @@ -28,16 +31,19 @@ mod outer { } #[doc = ""] + //~^ empty_docs fn warn_about_this() {} #[doc = ""] #[doc = ""] + //~^^ empty_docs fn this_doesn_warn() {} #[doc = "a fine function"] fn this_is_fine() {} /// + //~^ empty_docs mod inner { /// fn dont_warn_inner_outer() { @@ -51,6 +57,7 @@ mod outer { fn warn() { /*! */ + //~^ empty_docs } fn dont_warn() { @@ -59,6 +66,7 @@ mod outer { trait NoDoc { /// + //~^ empty_docs fn some() {} } } @@ -67,6 +75,7 @@ mod outer { /// lint y x: i32, /// + //~^ empty_docs y: i32, } } diff --git a/tests/ui/empty_docs.stderr b/tests/ui/empty_docs.stderr index 5fd7272d7c16..2eba6806852b 100644 --- a/tests/ui/empty_docs.stderr +++ b/tests/ui/empty_docs.stderr @@ -9,7 +9,7 @@ LL | //! = help: to override `-D warnings` add `#[allow(clippy::empty_docs)]` error: empty doc comment - --> tests/ui/empty_docs.rs:17:5 + --> tests/ui/empty_docs.rs:18:5 | LL | /// | ^^^ @@ -17,7 +17,7 @@ LL | /// = help: consider removing or filling it error: empty doc comment - --> tests/ui/empty_docs.rs:19:9 + --> tests/ui/empty_docs.rs:21:9 | LL | /// | ^^^ @@ -25,7 +25,7 @@ LL | /// = help: consider removing or filling it error: empty doc comment - --> tests/ui/empty_docs.rs:30:13 + --> tests/ui/empty_docs.rs:33:13 | LL | #[doc = ""] | ^^ @@ -33,7 +33,7 @@ LL | #[doc = ""] = help: consider removing or filling it error: empty doc comment - --> tests/ui/empty_docs.rs:33:13 + --> tests/ui/empty_docs.rs:37:13 | LL | #[doc = ""] | _____________^ @@ -43,7 +43,7 @@ LL | | #[doc = ""] = help: consider removing or filling it error: empty doc comment - --> tests/ui/empty_docs.rs:40:5 + --> tests/ui/empty_docs.rs:45:5 | LL | /// | ^^^ @@ -51,7 +51,7 @@ LL | /// = help: consider removing or filling it error: empty doc comment - --> tests/ui/empty_docs.rs:53:13 + --> tests/ui/empty_docs.rs:59:13 | LL | /*! */ | ^^^^^^ @@ -59,7 +59,7 @@ LL | /*! */ = help: consider removing or filling it error: empty doc comment - --> tests/ui/empty_docs.rs:61:13 + --> tests/ui/empty_docs.rs:68:13 | LL | /// | ^^^ @@ -67,7 +67,7 @@ LL | /// = help: consider removing or filling it error: empty doc comment - --> tests/ui/empty_docs.rs:69:9 + --> tests/ui/empty_docs.rs:77:9 | LL | /// | ^^^ diff --git a/tests/ui/empty_drop.rs b/tests/ui/empty_drop.rs index 74822ea50ec7..c2dc7a0193a3 100644 --- a/tests/ui/empty_drop.rs +++ b/tests/ui/empty_drop.rs @@ -5,6 +5,7 @@ struct Foo; impl Drop for Foo { +//~^ empty_drop fn drop(&mut self) {} } @@ -21,6 +22,7 @@ impl Drop for Bar { struct Baz; impl Drop for Baz { +//~^ empty_drop fn drop(&mut self) { {} } diff --git a/tests/ui/empty_drop.stderr b/tests/ui/empty_drop.stderr index d4d020fec30c..3073bf553969 100644 --- a/tests/ui/empty_drop.stderr +++ b/tests/ui/empty_drop.stderr @@ -2,6 +2,7 @@ error: empty drop implementation --> tests/ui/empty_drop.rs:7:1 | LL | / impl Drop for Foo { +LL | | LL | | fn drop(&mut self) {} LL | | } | |_^ @@ -11,9 +12,10 @@ LL | | } = help: try removing this impl error: empty drop implementation - --> tests/ui/empty_drop.rs:23:1 + --> tests/ui/empty_drop.rs:24:1 | LL | / impl Drop for Baz { +LL | | LL | | fn drop(&mut self) { LL | | {} LL | | } diff --git a/tests/ui/empty_enum.rs b/tests/ui/empty_enum.rs index 77357c15d957..cc22a76734fe 100644 --- a/tests/ui/empty_enum.rs +++ b/tests/ui/empty_enum.rs @@ -3,6 +3,7 @@ // Enable never type to test empty enum lint #![feature(never_type)] enum Empty {} -//~^ ERROR: enum with no variants +//~^ empty_enum + fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.fixed b/tests/ui/empty_enum_variants_with_brackets.fixed index 1a5e78dd47fe..8316d3b8fd34 100644 --- a/tests/ui/empty_enum_variants_with_brackets.fixed +++ b/tests/ui/empty_enum_variants_with_brackets.fixed @@ -4,15 +4,19 @@ pub enum PublicTestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error NonEmptyParentheses(i32, i32), // No error - EmptyBraces, //~ ERROR: enum variant has empty brackets - EmptyParentheses, //~ ERROR: enum variant has empty brackets +EmptyBraces, +//~^ empty_enum_variants_with_brackets +EmptyParentheses, +//~^ empty_enum_variants_with_brackets } enum TestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error NonEmptyParentheses(i32, i32), // No error - EmptyBraces, //~ ERROR: enum variant has empty brackets - EmptyParentheses, //~ ERROR: enum variant has empty brackets +EmptyBraces, +//~^ empty_enum_variants_with_brackets +EmptyParentheses, +//~^ empty_enum_variants_with_brackets AnotherEnum, // No error } diff --git a/tests/ui/empty_enum_variants_with_brackets.rs b/tests/ui/empty_enum_variants_with_brackets.rs index ca20b969a240..6cce2533b979 100644 --- a/tests/ui/empty_enum_variants_with_brackets.rs +++ b/tests/ui/empty_enum_variants_with_brackets.rs @@ -4,15 +4,19 @@ pub enum PublicTestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error NonEmptyParentheses(i32, i32), // No error - EmptyBraces {}, //~ ERROR: enum variant has empty brackets - EmptyParentheses(), //~ ERROR: enum variant has empty brackets +EmptyBraces {}, +//~^ empty_enum_variants_with_brackets +EmptyParentheses(), +//~^ empty_enum_variants_with_brackets } enum TestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error NonEmptyParentheses(i32, i32), // No error - EmptyBraces {}, //~ ERROR: enum variant has empty brackets - EmptyParentheses(), //~ ERROR: enum variant has empty brackets +EmptyBraces {}, +//~^ empty_enum_variants_with_brackets +EmptyParentheses(), +//~^ empty_enum_variants_with_brackets AnotherEnum, // No error } diff --git a/tests/ui/empty_enum_variants_with_brackets.stderr b/tests/ui/empty_enum_variants_with_brackets.stderr index 2b187b8f755b..f49e526584c8 100644 --- a/tests/ui/empty_enum_variants_with_brackets.stderr +++ b/tests/ui/empty_enum_variants_with_brackets.stderr @@ -1,34 +1,34 @@ error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:7:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:7:12 | -LL | EmptyBraces {}, - | ^^^ +LL | EmptyBraces {}, + | ^^^ | = note: `-D clippy::empty-enum-variants-with-brackets` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::empty_enum_variants_with_brackets)]` = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:8:21 + --> tests/ui/empty_enum_variants_with_brackets.rs:9:17 | -LL | EmptyParentheses(), - | ^^ +LL | EmptyParentheses(), + | ^^ | = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:14:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:16:12 | -LL | EmptyBraces {}, - | ^^^ +LL | EmptyBraces {}, + | ^^^ | = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:15:21 + --> tests/ui/empty_enum_variants_with_brackets.rs:18:17 | -LL | EmptyParentheses(), - | ^^ +LL | EmptyParentheses(), + | ^^ | = help: remove the brackets diff --git a/tests/ui/empty_enum_without_never_type.rs b/tests/ui/empty_enum_without_never_type.rs index 386677352e29..3661a1537208 100644 --- a/tests/ui/empty_enum_without_never_type.rs +++ b/tests/ui/empty_enum_without_never_type.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(dead_code)] #![warn(clippy::empty_enum)] diff --git a/tests/ui/empty_line_after/doc_comments.1.fixed b/tests/ui/empty_line_after/doc_comments.1.fixed index fd6a94b6a80c..cf2cc497799f 100644 --- a/tests/ui/empty_line_after/doc_comments.1.fixed +++ b/tests/ui/empty_line_after/doc_comments.1.fixed @@ -1,16 +1,18 @@ #![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)] -//~vvv empty_line_after_doc_comments + /// Meant to be an /// inner doc comment /// for the crate +//~^ empty_line_after_doc_comments fn first_in_crate() {} mod m { - //~vvv empty_line_after_doc_comments + /// Meant to be an /// inner doc comment /// for the module + //~^ empty_line_after_doc_comments fn first_in_module() {} } @@ -21,14 +23,16 @@ mod some_mod { fn some_noop() {} } - //~v empty_line_after_doc_comments + /// # Indented + //~^ empty_line_after_doc_comments /// Blank line fn indented() {} } -//~v empty_line_after_doc_comments + /// This should produce a warning +//~^ empty_line_after_doc_comments fn with_doc_and_newline() {} // This should *NOT* produce a warning @@ -36,8 +40,9 @@ fn with_doc_and_newline() {} /// some comment fn with_no_newline_and_comment() {} -//~v empty_line_after_doc_comments + /// This doc comment should produce a warning +//~^ empty_line_after_doc_comments /** This is also a doc comment and is part of the warning */ #[allow(non_camel_case_types)] @@ -46,14 +51,16 @@ fn with_no_newline_and_comment() {} fn three_attributes() {} mod misattributed { - //~v empty_line_after_doc_comments + /// docs for `old_code` + //~^ empty_line_after_doc_comments // fn old_code() {} fn new_code() {} - //~vv empty_line_after_doc_comments + /// Docs /// for OldA + //~^ empty_line_after_doc_comments // struct OldA; /// Docs /// for OldB @@ -65,14 +72,16 @@ mod misattributed { } mod block_comments { - //~v empty_line_after_doc_comments + /** + //~^ empty_line_after_doc_comments * Meant to be inner doc comment */ fn first_in_module() {} - //~v empty_line_after_doc_comments + /** + //~^ empty_line_after_doc_comments * Docs for `old_code` */ /* fn old_code() {} */ @@ -81,8 +90,9 @@ mod block_comments { */ fn new_code() {} - //~v empty_line_after_doc_comments + /// Docs for `old_code2` + //~^ empty_line_after_doc_comments /* fn old_code2() {} */ /// Docs for `new_code2` fn new_code2() {} diff --git a/tests/ui/empty_line_after/doc_comments.2.fixed b/tests/ui/empty_line_after/doc_comments.2.fixed index 7a57dcd92332..ee02e2f87d2d 100644 --- a/tests/ui/empty_line_after/doc_comments.2.fixed +++ b/tests/ui/empty_line_after/doc_comments.2.fixed @@ -1,17 +1,19 @@ #![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)] -//~vvv empty_line_after_doc_comments -//! Meant to be an -//! inner doc comment -//! for the crate + +// /// Meant to be an +// /// inner doc comment +// /// for the crate +//~^ empty_line_after_doc_comments fn first_in_crate() {} mod m { - //~vvv empty_line_after_doc_comments - //! Meant to be an - //! inner doc comment - //! for the module + + // /// Meant to be an + // /// inner doc comment + // /// for the module + //~^ empty_line_after_doc_comments fn first_in_module() {} } @@ -23,15 +25,18 @@ mod some_mod { fn some_noop() {} } - //~v empty_line_after_doc_comments - /// # Indented - /// + + // /// # Indented + //~^ empty_line_after_doc_comments + /// Blank line fn indented() {} } -//~v empty_line_after_doc_comments -/// This should produce a warning + +// /// This should produce a warning +//~^ empty_line_after_doc_comments + fn with_doc_and_newline() {} // This should *NOT* produce a warning @@ -39,25 +44,30 @@ fn with_doc_and_newline() {} /// some comment fn with_no_newline_and_comment() {} -//~v empty_line_after_doc_comments -/// This doc comment should produce a warning -/** This is also a doc comment and is part of the warning + +// /// This doc comment should produce a warning +//~^ empty_line_after_doc_comments + +/* This is also a doc comment and is part of the warning */ + #[allow(non_camel_case_types)] #[allow(missing_docs)] #[allow(dead_code)] fn three_attributes() {} mod misattributed { - //~v empty_line_after_doc_comments + // /// docs for `old_code` + //~^ empty_line_after_doc_comments // fn old_code() {} fn new_code() {} - //~vv empty_line_after_doc_comments + // /// Docs // /// for OldA + //~^ empty_line_after_doc_comments // struct OldA; // /// Docs @@ -71,15 +81,17 @@ mod misattributed { } mod block_comments { - //~v empty_line_after_doc_comments + /*! + //~^ empty_line_after_doc_comments * Meant to be inner doc comment */ fn first_in_module() {} - //~v empty_line_after_doc_comments + /* + //~^ empty_line_after_doc_comments * Docs for `old_code` */ /* fn old_code() {} */ @@ -89,8 +101,9 @@ mod block_comments { */ fn new_code() {} - //~v empty_line_after_doc_comments + // /// Docs for `old_code2` + //~^ empty_line_after_doc_comments /* fn old_code2() {} */ /// Docs for `new_code2` diff --git a/tests/ui/empty_line_after/doc_comments.rs b/tests/ui/empty_line_after/doc_comments.rs index 1da761a5c3d5..789f14f39777 100644 --- a/tests/ui/empty_line_after/doc_comments.rs +++ b/tests/ui/empty_line_after/doc_comments.rs @@ -1,17 +1,19 @@ #![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)] -//~vvv empty_line_after_doc_comments + /// Meant to be an /// inner doc comment /// for the crate +//~^ empty_line_after_doc_comments fn first_in_crate() {} mod m { - //~vvv empty_line_after_doc_comments + /// Meant to be an /// inner doc comment /// for the module + //~^ empty_line_after_doc_comments fn first_in_module() {} } @@ -23,15 +25,17 @@ mod some_mod { fn some_noop() {} } - //~v empty_line_after_doc_comments + /// # Indented + //~^ empty_line_after_doc_comments /// Blank line fn indented() {} } -//~v empty_line_after_doc_comments + /// This should produce a warning +//~^ empty_line_after_doc_comments fn with_doc_and_newline() {} @@ -40,8 +44,9 @@ fn with_doc_and_newline() {} /// some comment fn with_no_newline_and_comment() {} -//~v empty_line_after_doc_comments + /// This doc comment should produce a warning +//~^ empty_line_after_doc_comments /** This is also a doc comment and is part of the warning */ @@ -52,15 +57,17 @@ fn with_no_newline_and_comment() {} fn three_attributes() {} mod misattributed { - //~v empty_line_after_doc_comments + /// docs for `old_code` + //~^ empty_line_after_doc_comments // fn old_code() {} fn new_code() {} - //~vv empty_line_after_doc_comments + /// Docs /// for OldA + //~^ empty_line_after_doc_comments // struct OldA; /// Docs @@ -74,15 +81,17 @@ mod misattributed { } mod block_comments { - //~v empty_line_after_doc_comments + /** + //~^ empty_line_after_doc_comments * Meant to be inner doc comment */ fn first_in_module() {} - //~v empty_line_after_doc_comments + /** + //~^ empty_line_after_doc_comments * Docs for `old_code` */ /* fn old_code() {} */ @@ -92,8 +101,9 @@ mod block_comments { */ fn new_code() {} - //~v empty_line_after_doc_comments + /// Docs for `old_code2` + //~^ empty_line_after_doc_comments /* fn old_code2() {} */ /// Docs for `new_code2` diff --git a/tests/ui/empty_line_after/doc_comments.stderr b/tests/ui/empty_line_after/doc_comments.stderr index c5d5f3d37594..91745dac3a79 100644 --- a/tests/ui/empty_line_after/doc_comments.stderr +++ b/tests/ui/empty_line_after/doc_comments.stderr @@ -2,6 +2,7 @@ error: empty line after doc comment --> tests/ui/empty_line_after/doc_comments.rs:6:1 | LL | / /// for the crate +LL | | LL | | | |_^ LL | fn first_in_crate() {} @@ -10,34 +11,36 @@ LL | fn first_in_crate() {} = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]` = help: if the empty line is unintentional remove it -help: if the comment should document the crate use an inner doc comment +help: if the doc comment should not document `first_in_crate` comment it out | -LL ~ //! Meant to be an -LL ~ //! inner doc comment -LL ~ //! for the crate +LL ~ // /// Meant to be an +LL ~ // /// inner doc comment +LL ~ // /// for the crate | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:14:5 + --> tests/ui/empty_line_after/doc_comments.rs:15:5 | LL | / /// for the module +LL | | LL | | | |_^ LL | fn first_in_module() {} | -------------------- the comment documents this function | = help: if the empty line is unintentional remove it -help: if the comment should document the parent module use an inner doc comment +help: if the doc comment should not document `first_in_module` comment it out | -LL ~ //! Meant to be an -LL ~ //! inner doc comment -LL ~ //! for the module +LL ~ // /// Meant to be an +LL ~ // /// inner doc comment +LL ~ // /// for the module | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:27:5 + --> tests/ui/empty_line_after/doc_comments.rs:29:5 | LL | / /// # Indented +LL | | LL | | | |_^ LL | /// Blank line @@ -45,27 +48,33 @@ LL | fn indented() {} | ------------- the comment documents this function | = help: if the empty line is unintentional remove it -help: if the documentation should include the empty line include it in the comment - | -LL | /// +help: if the doc comment should not document `indented` comment it out | +LL | // /// # Indented + | ++ error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:34:1 + --> tests/ui/empty_line_after/doc_comments.rs:37:1 | LL | / /// This should produce a warning +LL | | LL | | | |_^ LL | fn with_doc_and_newline() {} | ------------------------- the comment documents this function | = help: if the empty line is unintentional remove it +help: if the doc comment should not document `with_doc_and_newline` comment it out + | +LL | // /// This should produce a warning + | ++ error: empty lines after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:44:1 + --> tests/ui/empty_line_after/doc_comments.rs:48:1 | LL | / /// This doc comment should produce a warning LL | | +LL | | LL | | /** This is also a doc comment and is part of the warning LL | | */ LL | | @@ -75,12 +84,19 @@ LL | fn three_attributes() {} | --------------------- the comment documents this function | = help: if the empty lines are unintentional remove them +help: if the doc comment should not document `three_attributes` comment it out + | +LL ~ // /// This doc comment should produce a warning +LL | +LL | +LL ~ /* This is also a doc comment and is part of the warning + | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:56:5 + --> tests/ui/empty_line_after/doc_comments.rs:61:5 | LL | / /// docs for `old_code` -LL | | // fn old_code() {} +... | LL | | | |_^ LL | fn new_code() {} @@ -93,12 +109,9 @@ LL | // /// docs for `old_code` | ++ error: empty lines after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:63:5 + --> tests/ui/empty_line_after/doc_comments.rs:69:5 | LL | / /// for OldA -LL | | // struct OldA; -LL | | -LL | | /// Docs ... | LL | | | |_^ @@ -111,6 +124,7 @@ help: if the doc comment should not document `Multiple` comment it out | LL ~ // /// Docs LL ~ // /// for OldA +LL | LL | // struct OldA; LL | LL ~ // /// Docs @@ -118,9 +132,10 @@ LL ~ // /// for OldB | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:78:5 + --> tests/ui/empty_line_after/doc_comments.rs:85:5 | LL | / /** +LL | | LL | | * Meant to be inner doc comment LL | | */ LL | | @@ -135,9 +150,10 @@ LL | /*! | ~ error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:85:5 + --> tests/ui/empty_line_after/doc_comments.rs:93:5 | LL | / /** +LL | | LL | | * Docs for `old_code` LL | | */ LL | | /* fn old_code() {} */ @@ -155,9 +171,10 @@ LL + /* | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:96:5 + --> tests/ui/empty_line_after/doc_comments.rs:105:5 | LL | / /// Docs for `old_code2` +LL | | LL | | /* fn old_code2() {} */ LL | | | |_^ diff --git a/tests/ui/empty_loop.rs b/tests/ui/empty_loop.rs index be347563135c..e2d4ff84b56a 100644 --- a/tests/ui/empty_loop.rs +++ b/tests/ui/empty_loop.rs @@ -7,14 +7,17 @@ use proc_macros::{external, inline_macros}; fn should_trigger() { loop {} + //~^ empty_loop #[allow(clippy::never_loop)] loop { loop {} + //~^ empty_loop } #[allow(clippy::never_loop)] 'outer: loop { 'inner: loop {} + //~^ empty_loop } } diff --git a/tests/ui/empty_loop.stderr b/tests/ui/empty_loop.stderr index 3ac93f4ece0c..bc723ceefbb3 100644 --- a/tests/ui/empty_loop.stderr +++ b/tests/ui/empty_loop.stderr @@ -9,7 +9,7 @@ LL | loop {} = help: to override `-D warnings` add `#[allow(clippy::empty_loop)]` error: empty `loop {}` wastes CPU cycles - --> tests/ui/empty_loop.rs:12:9 + --> tests/ui/empty_loop.rs:13:9 | LL | loop {} | ^^^^^^^ @@ -17,7 +17,7 @@ LL | loop {} = help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body error: empty `loop {}` wastes CPU cycles - --> tests/ui/empty_loop.rs:17:9 + --> tests/ui/empty_loop.rs:19:9 | LL | 'inner: loop {} | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/empty_loop_no_std.rs b/tests/ui/empty_loop_no_std.rs index 9bfcbfba9697..c3b2bafe2f87 100644 --- a/tests/ui/empty_loop_no_std.rs +++ b/tests/ui/empty_loop_no_std.rs @@ -8,5 +8,6 @@ pub fn main(argc: isize, argv: *const *const u8) -> isize { // This should trigger the lint loop {} - //~^ ERROR: empty `loop {}` wastes CPU cycles + //~^ empty_loop + } diff --git a/tests/ui/empty_structs_with_brackets.fixed b/tests/ui/empty_structs_with_brackets.fixed index 80572645f5d1..b1600862a8f6 100644 --- a/tests/ui/empty_structs_with_brackets.fixed +++ b/tests/ui/empty_structs_with_brackets.fixed @@ -2,7 +2,9 @@ #![allow(dead_code)] pub struct MyEmptyStruct; // should trigger lint +//~^ empty_structs_with_brackets struct MyEmptyTupleStruct; // should trigger lint +//~^ empty_structs_with_brackets // should not trigger lint struct MyCfgStruct { diff --git a/tests/ui/empty_structs_with_brackets.rs b/tests/ui/empty_structs_with_brackets.rs index 8fb3e247a419..1f69c4be9ec7 100644 --- a/tests/ui/empty_structs_with_brackets.rs +++ b/tests/ui/empty_structs_with_brackets.rs @@ -2,7 +2,9 @@ #![allow(dead_code)] pub struct MyEmptyStruct {} // should trigger lint +//~^ empty_structs_with_brackets struct MyEmptyTupleStruct(); // should trigger lint +//~^ empty_structs_with_brackets // should not trigger lint struct MyCfgStruct { diff --git a/tests/ui/empty_structs_with_brackets.stderr b/tests/ui/empty_structs_with_brackets.stderr index e57249aec023..86ef43aa9600 100644 --- a/tests/ui/empty_structs_with_brackets.stderr +++ b/tests/ui/empty_structs_with_brackets.stderr @@ -9,7 +9,7 @@ LL | pub struct MyEmptyStruct {} // should trigger lint = help: remove the brackets error: found empty brackets on struct declaration - --> tests/ui/empty_structs_with_brackets.rs:5:26 + --> tests/ui/empty_structs_with_brackets.rs:6:26 | LL | struct MyEmptyTupleStruct(); // should trigger lint | ^^^ diff --git a/tests/ui/endian_bytes.rs b/tests/ui/endian_bytes.rs index 580fc2fc24d7..879467c7f6e2 100644 --- a/tests/ui/endian_bytes.rs +++ b/tests/ui/endian_bytes.rs @@ -7,62 +7,118 @@ macro_rules! fn_body { () => { 2u8.to_ne_bytes(); + //~^ host_endian_bytes 2i8.to_ne_bytes(); + //~^ host_endian_bytes 2u16.to_ne_bytes(); + //~^ host_endian_bytes 2i16.to_ne_bytes(); + //~^ host_endian_bytes 2u32.to_ne_bytes(); + //~^ host_endian_bytes 2i32.to_ne_bytes(); + //~^ host_endian_bytes 2u64.to_ne_bytes(); + //~^ host_endian_bytes 2i64.to_ne_bytes(); + //~^ host_endian_bytes 2u128.to_ne_bytes(); + //~^ host_endian_bytes 2i128.to_ne_bytes(); + //~^ host_endian_bytes 2.0f32.to_ne_bytes(); + //~^ host_endian_bytes 2.0f64.to_ne_bytes(); + //~^ host_endian_bytes 2usize.to_ne_bytes(); + //~^ host_endian_bytes 2isize.to_ne_bytes(); + //~^ host_endian_bytes u8::from_ne_bytes(todo!()); + //~^ host_endian_bytes i8::from_ne_bytes(todo!()); + //~^ host_endian_bytes u16::from_ne_bytes(todo!()); + //~^ host_endian_bytes i16::from_ne_bytes(todo!()); + //~^ host_endian_bytes u32::from_ne_bytes(todo!()); + //~^ host_endian_bytes i32::from_ne_bytes(todo!()); + //~^ host_endian_bytes u64::from_ne_bytes(todo!()); + //~^ host_endian_bytes i64::from_ne_bytes(todo!()); + //~^ host_endian_bytes u128::from_ne_bytes(todo!()); + //~^ host_endian_bytes i128::from_ne_bytes(todo!()); + //~^ host_endian_bytes usize::from_ne_bytes(todo!()); + //~^ host_endian_bytes isize::from_ne_bytes(todo!()); + //~^ host_endian_bytes f32::from_ne_bytes(todo!()); + //~^ host_endian_bytes f64::from_ne_bytes(todo!()); + //~^ host_endian_bytes 2u8.to_le_bytes(); + //~^ little_endian_bytes 2i8.to_le_bytes(); + //~^ little_endian_bytes 2u16.to_le_bytes(); + //~^ little_endian_bytes 2i16.to_le_bytes(); + //~^ little_endian_bytes 2u32.to_le_bytes(); + //~^ little_endian_bytes 2i32.to_le_bytes(); + //~^ little_endian_bytes 2u64.to_le_bytes(); + //~^ little_endian_bytes 2i64.to_le_bytes(); + //~^ little_endian_bytes 2u128.to_le_bytes(); + //~^ little_endian_bytes 2i128.to_le_bytes(); + //~^ little_endian_bytes 2.0f32.to_le_bytes(); + //~^ little_endian_bytes 2.0f64.to_le_bytes(); + //~^ little_endian_bytes 2usize.to_le_bytes(); + //~^ little_endian_bytes 2isize.to_le_bytes(); + //~^ little_endian_bytes u8::from_le_bytes(todo!()); + //~^ little_endian_bytes i8::from_le_bytes(todo!()); + //~^ little_endian_bytes u16::from_le_bytes(todo!()); + //~^ little_endian_bytes i16::from_le_bytes(todo!()); + //~^ little_endian_bytes u32::from_le_bytes(todo!()); + //~^ little_endian_bytes i32::from_le_bytes(todo!()); + //~^ little_endian_bytes u64::from_le_bytes(todo!()); + //~^ little_endian_bytes i64::from_le_bytes(todo!()); + //~^ little_endian_bytes u128::from_le_bytes(todo!()); + //~^ little_endian_bytes i128::from_le_bytes(todo!()); + //~^ little_endian_bytes usize::from_le_bytes(todo!()); + //~^ little_endian_bytes isize::from_le_bytes(todo!()); + //~^ little_endian_bytes f32::from_le_bytes(todo!()); + //~^ little_endian_bytes f64::from_le_bytes(todo!()); + //~^ little_endian_bytes }; } @@ -70,13 +126,43 @@ macro_rules! fn_body { macro_rules! fn_body_smol { () => { 2u8.to_ne_bytes(); + //~^ host_endian_bytes + //~| host_endian_bytes + //~| host_endian_bytes + //~| host_endian_bytes + //~| host_endian_bytes u8::from_ne_bytes(todo!()); + //~^ host_endian_bytes + //~| host_endian_bytes + //~| host_endian_bytes + //~| host_endian_bytes + //~| host_endian_bytes 2u8.to_le_bytes(); + //~^ little_endian_bytes + //~| little_endian_bytes + //~| little_endian_bytes + //~| little_endian_bytes + //~| little_endian_bytes u8::from_le_bytes(todo!()); + //~^ little_endian_bytes + //~| little_endian_bytes + //~| little_endian_bytes + //~| little_endian_bytes + //~| little_endian_bytes 2u8.to_be_bytes(); + //~^ big_endian_bytes + //~| big_endian_bytes + //~| big_endian_bytes + //~| big_endian_bytes + //~| big_endian_bytes u8::from_be_bytes(todo!()); + //~^ big_endian_bytes + //~| big_endian_bytes + //~| big_endian_bytes + //~| big_endian_bytes + //~| big_endian_bytes }; } diff --git a/tests/ui/endian_bytes.stderr b/tests/ui/endian_bytes.stderr index fd19ec45872b..edc2a3309f24 100644 --- a/tests/ui/endian_bytes.stderr +++ b/tests/ui/endian_bytes.stderr @@ -13,7 +13,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:10:9 + --> tests/ui/endian_bytes.rs:11:9 | LL | 2i8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u16::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:11:9 + --> tests/ui/endian_bytes.rs:13:9 | LL | 2u16.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i16::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:12:9 + --> tests/ui/endian_bytes.rs:15:9 | LL | 2i16.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u32::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:13:9 + --> tests/ui/endian_bytes.rs:17:9 | LL | 2u32.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i32::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:14:9 + --> tests/ui/endian_bytes.rs:19:9 | LL | 2i32.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u64::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:15:9 + --> tests/ui/endian_bytes.rs:21:9 | LL | 2u64.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i64::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:16:9 + --> tests/ui/endian_bytes.rs:23:9 | LL | 2i64.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u128::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:17:9 + --> tests/ui/endian_bytes.rs:25:9 | LL | 2u128.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i128::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:18:9 + --> tests/ui/endian_bytes.rs:27:9 | LL | 2i128.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `f32::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:19:9 + --> tests/ui/endian_bytes.rs:29:9 | LL | 2.0f32.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `f64::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:20:9 + --> tests/ui/endian_bytes.rs:31:9 | LL | 2.0f64.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `usize::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:21:9 + --> tests/ui/endian_bytes.rs:33:9 | LL | 2usize.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `isize::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:22:9 + --> tests/ui/endian_bytes.rs:35:9 | LL | 2isize.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:23:9 + --> tests/ui/endian_bytes.rs:37:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:24:9 + --> tests/ui/endian_bytes.rs:39:9 | LL | i8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u16::from_ne_bytes` - --> tests/ui/endian_bytes.rs:25:9 + --> tests/ui/endian_bytes.rs:41:9 | LL | u16::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -205,7 +205,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i16::from_ne_bytes` - --> tests/ui/endian_bytes.rs:26:9 + --> tests/ui/endian_bytes.rs:43:9 | LL | i16::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u32::from_ne_bytes` - --> tests/ui/endian_bytes.rs:27:9 + --> tests/ui/endian_bytes.rs:45:9 | LL | u32::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -229,7 +229,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i32::from_ne_bytes` - --> tests/ui/endian_bytes.rs:28:9 + --> tests/ui/endian_bytes.rs:47:9 | LL | i32::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +241,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u64::from_ne_bytes` - --> tests/ui/endian_bytes.rs:29:9 + --> tests/ui/endian_bytes.rs:49:9 | LL | u64::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i64::from_ne_bytes` - --> tests/ui/endian_bytes.rs:30:9 + --> tests/ui/endian_bytes.rs:51:9 | LL | i64::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -265,7 +265,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u128::from_ne_bytes` - --> tests/ui/endian_bytes.rs:31:9 + --> tests/ui/endian_bytes.rs:53:9 | LL | u128::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -277,7 +277,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i128::from_ne_bytes` - --> tests/ui/endian_bytes.rs:32:9 + --> tests/ui/endian_bytes.rs:55:9 | LL | i128::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -289,7 +289,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `usize::from_ne_bytes` - --> tests/ui/endian_bytes.rs:33:9 + --> tests/ui/endian_bytes.rs:57:9 | LL | usize::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -301,7 +301,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `isize::from_ne_bytes` - --> tests/ui/endian_bytes.rs:34:9 + --> tests/ui/endian_bytes.rs:59:9 | LL | isize::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -313,7 +313,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `f32::from_ne_bytes` - --> tests/ui/endian_bytes.rs:35:9 + --> tests/ui/endian_bytes.rs:61:9 | LL | f32::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -325,7 +325,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `f64::from_ne_bytes` - --> tests/ui/endian_bytes.rs:36:9 + --> tests/ui/endian_bytes.rs:63:9 | LL | f64::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -337,7 +337,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:38:9 + --> tests/ui/endian_bytes.rs:66:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -351,7 +351,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:39:9 + --> tests/ui/endian_bytes.rs:68:9 | LL | 2i8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -363,7 +363,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u16::to_le_bytes` method - --> tests/ui/endian_bytes.rs:40:9 + --> tests/ui/endian_bytes.rs:70:9 | LL | 2u16.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -375,7 +375,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i16::to_le_bytes` method - --> tests/ui/endian_bytes.rs:41:9 + --> tests/ui/endian_bytes.rs:72:9 | LL | 2i16.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -387,7 +387,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u32::to_le_bytes` method - --> tests/ui/endian_bytes.rs:42:9 + --> tests/ui/endian_bytes.rs:74:9 | LL | 2u32.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -399,7 +399,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i32::to_le_bytes` method - --> tests/ui/endian_bytes.rs:43:9 + --> tests/ui/endian_bytes.rs:76:9 | LL | 2i32.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -411,7 +411,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u64::to_le_bytes` method - --> tests/ui/endian_bytes.rs:44:9 + --> tests/ui/endian_bytes.rs:78:9 | LL | 2u64.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -423,7 +423,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i64::to_le_bytes` method - --> tests/ui/endian_bytes.rs:45:9 + --> tests/ui/endian_bytes.rs:80:9 | LL | 2i64.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -435,7 +435,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u128::to_le_bytes` method - --> tests/ui/endian_bytes.rs:46:9 + --> tests/ui/endian_bytes.rs:82:9 | LL | 2u128.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^ @@ -447,7 +447,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i128::to_le_bytes` method - --> tests/ui/endian_bytes.rs:47:9 + --> tests/ui/endian_bytes.rs:84:9 | LL | 2i128.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^ @@ -459,7 +459,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `f32::to_le_bytes` method - --> tests/ui/endian_bytes.rs:48:9 + --> tests/ui/endian_bytes.rs:86:9 | LL | 2.0f32.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -471,7 +471,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `f64::to_le_bytes` method - --> tests/ui/endian_bytes.rs:49:9 + --> tests/ui/endian_bytes.rs:88:9 | LL | 2.0f64.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -483,7 +483,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `usize::to_le_bytes` method - --> tests/ui/endian_bytes.rs:50:9 + --> tests/ui/endian_bytes.rs:90:9 | LL | 2usize.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -495,7 +495,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `isize::to_le_bytes` method - --> tests/ui/endian_bytes.rs:51:9 + --> tests/ui/endian_bytes.rs:92:9 | LL | 2isize.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -507,7 +507,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:52:9 + --> tests/ui/endian_bytes.rs:94:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -519,7 +519,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i8::from_le_bytes` - --> tests/ui/endian_bytes.rs:53:9 + --> tests/ui/endian_bytes.rs:96:9 | LL | i8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -531,7 +531,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u16::from_le_bytes` - --> tests/ui/endian_bytes.rs:54:9 + --> tests/ui/endian_bytes.rs:98:9 | LL | u16::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -543,7 +543,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i16::from_le_bytes` - --> tests/ui/endian_bytes.rs:55:9 + --> tests/ui/endian_bytes.rs:100:9 | LL | i16::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -555,7 +555,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u32::from_le_bytes` - --> tests/ui/endian_bytes.rs:56:9 + --> tests/ui/endian_bytes.rs:102:9 | LL | u32::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -567,7 +567,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i32::from_le_bytes` - --> tests/ui/endian_bytes.rs:57:9 + --> tests/ui/endian_bytes.rs:104:9 | LL | i32::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -579,7 +579,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u64::from_le_bytes` - --> tests/ui/endian_bytes.rs:58:9 + --> tests/ui/endian_bytes.rs:106:9 | LL | u64::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -591,7 +591,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i64::from_le_bytes` - --> tests/ui/endian_bytes.rs:59:9 + --> tests/ui/endian_bytes.rs:108:9 | LL | i64::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -603,7 +603,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u128::from_le_bytes` - --> tests/ui/endian_bytes.rs:60:9 + --> tests/ui/endian_bytes.rs:110:9 | LL | u128::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -615,7 +615,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i128::from_le_bytes` - --> tests/ui/endian_bytes.rs:61:9 + --> tests/ui/endian_bytes.rs:112:9 | LL | i128::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -627,7 +627,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `usize::from_le_bytes` - --> tests/ui/endian_bytes.rs:62:9 + --> tests/ui/endian_bytes.rs:114:9 | LL | usize::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -639,7 +639,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `isize::from_le_bytes` - --> tests/ui/endian_bytes.rs:63:9 + --> tests/ui/endian_bytes.rs:116:9 | LL | isize::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -651,7 +651,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `f32::from_le_bytes` - --> tests/ui/endian_bytes.rs:64:9 + --> tests/ui/endian_bytes.rs:118:9 | LL | f32::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -663,7 +663,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `f64::from_le_bytes` - --> tests/ui/endian_bytes.rs:65:9 + --> tests/ui/endian_bytes.rs:120:9 | LL | f64::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -675,7 +675,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:72:9 + --> tests/ui/endian_bytes.rs:128:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -687,7 +687,7 @@ LL | fn host_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:134:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -699,7 +699,7 @@ LL | fn host_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:78:9 + --> tests/ui/endian_bytes.rs:154:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -713,7 +713,7 @@ LL | fn host_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:79:9 + --> tests/ui/endian_bytes.rs:160:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -725,7 +725,7 @@ LL | fn host_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:72:9 + --> tests/ui/endian_bytes.rs:128:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -737,7 +737,7 @@ LL | fn host_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:134:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -749,7 +749,7 @@ LL | fn host_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:75:9 + --> tests/ui/endian_bytes.rs:141:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -761,7 +761,7 @@ LL | fn host_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:147:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -773,7 +773,7 @@ LL | fn host_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:72:9 + --> tests/ui/endian_bytes.rs:128:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -784,7 +784,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:134:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -795,7 +795,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:75:9 + --> tests/ui/endian_bytes.rs:141:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -806,7 +806,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:147:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -817,7 +817,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:78:9 + --> tests/ui/endian_bytes.rs:154:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -828,7 +828,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:79:9 + --> tests/ui/endian_bytes.rs:160:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -839,7 +839,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:75:9 + --> tests/ui/endian_bytes.rs:141:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -851,7 +851,7 @@ LL | fn little_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:147:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -863,7 +863,7 @@ LL | fn little_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:78:9 + --> tests/ui/endian_bytes.rs:154:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -875,7 +875,7 @@ LL | fn little_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:79:9 + --> tests/ui/endian_bytes.rs:160:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -887,7 +887,7 @@ LL | fn little_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:72:9 + --> tests/ui/endian_bytes.rs:128:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -899,7 +899,7 @@ LL | fn little_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:134:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -911,7 +911,7 @@ LL | fn little_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:75:9 + --> tests/ui/endian_bytes.rs:141:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -923,7 +923,7 @@ LL | fn little_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:147:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -935,7 +935,7 @@ LL | fn little_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:75:9 + --> tests/ui/endian_bytes.rs:141:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -947,7 +947,7 @@ LL | fn big_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:147:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -959,7 +959,7 @@ LL | fn big_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:78:9 + --> tests/ui/endian_bytes.rs:154:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -971,7 +971,7 @@ LL | fn big_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:79:9 + --> tests/ui/endian_bytes.rs:160:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -983,7 +983,7 @@ LL | fn big_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:72:9 + --> tests/ui/endian_bytes.rs:128:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -995,7 +995,7 @@ LL | fn big_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:134:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1007,7 +1007,7 @@ LL | fn big_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:78:9 + --> tests/ui/endian_bytes.rs:154:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -1019,7 +1019,7 @@ LL | fn big_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:79:9 + --> tests/ui/endian_bytes.rs:160:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/entry.fixed b/tests/ui/entry.fixed index abdfae2a3e13..87dc7a8de920 100644 --- a/tests/ui/entry.fixed +++ b/tests/ui/entry.fixed @@ -25,6 +25,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // semicolon on insert, use or_insert_with(..) m.entry(k).or_insert_with(|| { + //~^ map_entry if true { v } else { @@ -34,6 +35,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // semicolon on if, use or_insert_with(..) m.entry(k).or_insert_with(|| { + //~^ map_entry if true { v } else { @@ -43,6 +45,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // early return, use if let if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { + //~^ map_entry if true { e.insert(v); } else { @@ -53,12 +56,14 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // use or_insert_with(..) m.entry(k).or_insert_with(|| { + //~^ map_entry foo(); v }); // semicolon on insert and match, use or_insert_with(..) m.entry(k).or_insert_with(|| { + //~^ map_entry match 0 { 1 if true => { v @@ -71,6 +76,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // one branch doesn't insert, use if let if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { + //~^ map_entry match 0 { 0 => foo(), _ => { @@ -81,6 +87,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // use or_insert_with m.entry(k).or_insert_with(|| { + //~^ map_entry foo(); match 0 { 0 if false => { @@ -145,6 +152,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // or_insert_with. Partial move of a local declared in the closure is ok. m.entry(k).or_insert_with(|| { + //~^ map_entry let x = (String::new(), String::new()); let _ = x.0; v @@ -178,6 +186,7 @@ pub fn issue_11935() { fn issue12489(map: &mut HashMap) -> Option<()> { if let std::collections::hash_map::Entry::Vacant(e) = map.entry(1) { + //~^ map_entry let Some(1) = Some(2) else { return None; }; diff --git a/tests/ui/entry.rs b/tests/ui/entry.rs index 7774f99a2a22..c795d3b97590 100644 --- a/tests/ui/entry.rs +++ b/tests/ui/entry.rs @@ -22,11 +22,13 @@ fn foo() {} fn hash_map(m: &mut HashMap, m2: &mut HashMap, k: K, k2: K, v: V, v2: V) { // or_insert(v) if !m.contains_key(&k) { + //~^ map_entry m.insert(k, v); } // semicolon on insert, use or_insert_with(..) if !m.contains_key(&k) { + //~^ map_entry if true { m.insert(k, v); } else { @@ -36,6 +38,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // semicolon on if, use or_insert_with(..) if !m.contains_key(&k) { + //~^ map_entry if true { m.insert(k, v) } else { @@ -45,6 +48,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // early return, use if let if !m.contains_key(&k) { + //~^ map_entry if true { m.insert(k, v); } else { @@ -55,12 +59,14 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // use or_insert_with(..) if !m.contains_key(&k) { + //~^ map_entry foo(); m.insert(k, v); } // semicolon on insert and match, use or_insert_with(..) if !m.contains_key(&k) { + //~^ map_entry match 0 { 1 if true => { m.insert(k, v); @@ -73,6 +79,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // one branch doesn't insert, use if let if !m.contains_key(&k) { + //~^ map_entry match 0 { 0 => foo(), _ => { @@ -83,6 +90,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // use or_insert_with if !m.contains_key(&k) { + //~^ map_entry foo(); match 0 { 0 if false => { @@ -117,6 +125,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // macro_expansion test, use or_insert(..) if !m.contains_key(&m!(k)) { + //~^ map_entry m.insert(m!(k), m!(v)); } @@ -149,6 +158,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // or_insert_with. Partial move of a local declared in the closure is ok. if !m.contains_key(&k) { + //~^ map_entry let x = (String::new(), String::new()); let _ = x.0; m.insert(k, v); @@ -182,6 +192,7 @@ pub fn issue_11935() { fn issue12489(map: &mut HashMap) -> Option<()> { if !map.contains_key(&1) { + //~^ map_entry let Some(1) = Some(2) else { return None; }; diff --git a/tests/ui/entry.stderr b/tests/ui/entry.stderr index 4b6bd3b4a258..009b78d29073 100644 --- a/tests/ui/entry.stderr +++ b/tests/ui/entry.stderr @@ -2,6 +2,7 @@ error: usage of `contains_key` followed by `insert` on a `HashMap` --> tests/ui/entry.rs:24:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | m.insert(k, v); LL | | } | |_____^ help: try: `m.entry(k).or_insert(v);` @@ -10,12 +11,12 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::map_entry)]` error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:29:5 + --> tests/ui/entry.rs:30:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | if true { LL | | m.insert(k, v); -LL | | } else { ... | LL | | } | |_____^ @@ -23,6 +24,7 @@ LL | | } help: try | LL ~ m.entry(k).or_insert_with(|| { +LL + LL + if true { LL + v LL + } else { @@ -32,13 +34,13 @@ LL + }); | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:38:5 + --> tests/ui/entry.rs:40:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | if true { LL | | m.insert(k, v) -LL | | } else { -LL | | m.insert(k, v2) +... | LL | | }; LL | | } | |_____^ @@ -46,6 +48,7 @@ LL | | } help: try | LL ~ m.entry(k).or_insert_with(|| { +LL + LL + if true { LL + v LL + } else { @@ -55,12 +58,12 @@ LL + }); | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:47:5 + --> tests/ui/entry.rs:50:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | if true { LL | | m.insert(k, v); -LL | | } else { ... | LL | | } | |_____^ @@ -68,6 +71,7 @@ LL | | } help: try | LL ~ if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { +LL + LL + if true { LL + e.insert(v); LL + } else { @@ -78,9 +82,10 @@ LL + } | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:57:5 + --> tests/ui/entry.rs:61:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | foo(); LL | | m.insert(k, v); LL | | } @@ -89,18 +94,19 @@ LL | | } help: try | LL ~ m.entry(k).or_insert_with(|| { +LL + LL + foo(); LL + v LL + }); | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:63:5 + --> tests/ui/entry.rs:68:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | match 0 { LL | | 1 if true => { -LL | | m.insert(k, v); ... | LL | | }; LL | | } @@ -109,6 +115,7 @@ LL | | } help: try | LL ~ m.entry(k).or_insert_with(|| { +LL + LL + match 0 { LL + 1 if true => { LL + v @@ -121,12 +128,12 @@ LL + }); | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:75:5 + --> tests/ui/entry.rs:81:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | match 0 { LL | | 0 => foo(), -LL | | _ => { ... | LL | | }; LL | | } @@ -135,6 +142,7 @@ LL | | } help: try | LL ~ if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { +LL + LL + match 0 { LL + 0 => foo(), LL + _ => { @@ -145,12 +153,12 @@ LL + } | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:85:5 + --> tests/ui/entry.rs:92:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | foo(); LL | | match 0 { -LL | | 0 if false => { ... | LL | | } | |_____^ @@ -158,6 +166,7 @@ LL | | } help: try | LL ~ m.entry(k).or_insert_with(|| { +LL + LL + foo(); LL + match 0 { LL + 0 if false => { @@ -185,17 +194,19 @@ LL + }); | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:119:5 + --> tests/ui/entry.rs:127:5 | LL | / if !m.contains_key(&m!(k)) { +LL | | LL | | m.insert(m!(k), m!(v)); LL | | } | |_____^ help: try: `m.entry(m!(k)).or_insert_with(|| m!(v));` error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:151:5 + --> tests/ui/entry.rs:160:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | let x = (String::new(), String::new()); LL | | let _ = x.0; LL | | m.insert(k, v); @@ -205,6 +216,7 @@ LL | | } help: try | LL ~ m.entry(k).or_insert_with(|| { +LL + LL + let x = (String::new(), String::new()); LL + let _ = x.0; LL + v @@ -212,9 +224,10 @@ LL + }); | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry.rs:184:5 + --> tests/ui/entry.rs:194:5 | LL | / if !map.contains_key(&1) { +LL | | LL | | let Some(1) = Some(2) else { LL | | return None; LL | | }; @@ -225,6 +238,7 @@ LL | | } help: try | LL ~ if let std::collections::hash_map::Entry::Vacant(e) = map.entry(1) { +LL + LL + let Some(1) = Some(2) else { LL + return None; LL + }; diff --git a/tests/ui/entry_btree.fixed b/tests/ui/entry_btree.fixed index 228212c79eaf..518f503475fc 100644 --- a/tests/ui/entry_btree.fixed +++ b/tests/ui/entry_btree.fixed @@ -8,6 +8,7 @@ fn foo() {} fn btree_map(m: &mut BTreeMap, k: K, v: V) { // insert then do something, use if let if let std::collections::btree_map::Entry::Vacant(e) = m.entry(k) { + //~^ map_entry e.insert(v); foo(); } diff --git a/tests/ui/entry_btree.rs b/tests/ui/entry_btree.rs index 44703c567113..4e4b3a502e03 100644 --- a/tests/ui/entry_btree.rs +++ b/tests/ui/entry_btree.rs @@ -8,6 +8,7 @@ fn foo() {} fn btree_map(m: &mut BTreeMap, k: K, v: V) { // insert then do something, use if let if !m.contains_key(&k) { + //~^ map_entry m.insert(k, v); foo(); } diff --git a/tests/ui/entry_btree.stderr b/tests/ui/entry_btree.stderr index 290e6b788054..671340b89532 100644 --- a/tests/ui/entry_btree.stderr +++ b/tests/ui/entry_btree.stderr @@ -2,6 +2,7 @@ error: usage of `contains_key` followed by `insert` on a `BTreeMap` --> tests/ui/entry_btree.rs:10:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | m.insert(k, v); LL | | foo(); LL | | } @@ -12,6 +13,7 @@ LL | | } help: try | LL ~ if let std::collections::btree_map::Entry::Vacant(e) = m.entry(k) { +LL + LL + e.insert(v); LL + foo(); LL + } diff --git a/tests/ui/entry_with_else.fixed b/tests/ui/entry_with_else.fixed index 34804b9ee5d7..995611803908 100644 --- a/tests/ui/entry_with_else.fixed +++ b/tests/ui/entry_with_else.fixed @@ -13,6 +13,7 @@ fn foo() {} fn insert_if_absent0(m: &mut HashMap, k: K, v: V, v2: V) { match m.entry(k) { std::collections::hash_map::Entry::Vacant(e) => { + //~^ map_entry e.insert(v); } std::collections::hash_map::Entry::Occupied(mut e) => { @@ -22,6 +23,7 @@ fn insert_if_absent0(m: &mut HashMap, k: K, match m.entry(k) { std::collections::hash_map::Entry::Occupied(mut e) => { + //~^ map_entry e.insert(v); } std::collections::hash_map::Entry::Vacant(e) => { @@ -30,6 +32,7 @@ fn insert_if_absent0(m: &mut HashMap, k: K, } if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { + //~^ map_entry e.insert(v); } else { foo(); @@ -38,11 +41,13 @@ fn insert_if_absent0(m: &mut HashMap, k: K, if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) { e.insert(v); } else { + //~^ map_entry foo(); } match m.entry(k) { std::collections::hash_map::Entry::Vacant(e) => { + //~^ map_entry e.insert(v); } std::collections::hash_map::Entry::Occupied(mut e) => { @@ -52,6 +57,7 @@ fn insert_if_absent0(m: &mut HashMap, k: K, match m.entry(k) { std::collections::hash_map::Entry::Occupied(mut e) => { + //~^ map_entry if true { Some(e.insert(v)) } else { Some(e.insert(v2)) } } std::collections::hash_map::Entry::Vacant(e) => { @@ -61,6 +67,7 @@ fn insert_if_absent0(m: &mut HashMap, k: K, }; if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) { + //~^ map_entry foo(); Some(e.insert(v)) } else { diff --git a/tests/ui/entry_with_else.rs b/tests/ui/entry_with_else.rs index 0515748fd733..dcfafedc11f8 100644 --- a/tests/ui/entry_with_else.rs +++ b/tests/ui/entry_with_else.rs @@ -12,42 +12,49 @@ fn foo() {} fn insert_if_absent0(m: &mut HashMap, k: K, v: V, v2: V) { if !m.contains_key(&k) { + //~^ map_entry m.insert(k, v); } else { m.insert(k, v2); } if m.contains_key(&k) { + //~^ map_entry m.insert(k, v); } else { m.insert(k, v2); } if !m.contains_key(&k) { + //~^ map_entry m.insert(k, v); } else { foo(); } if !m.contains_key(&k) { + //~^ map_entry foo(); } else { m.insert(k, v); } if !m.contains_key(&k) { + //~^ map_entry m.insert(k, v); } else { m.insert(k, v2); } if m.contains_key(&k) { + //~^ map_entry if true { m.insert(k, v) } else { m.insert(k, v2) } } else { m.insert(k, v) }; if m.contains_key(&k) { + //~^ map_entry foo(); m.insert(k, v) } else { diff --git a/tests/ui/entry_with_else.stderr b/tests/ui/entry_with_else.stderr index 26b21b076b6c..d483ac95ad5b 100644 --- a/tests/ui/entry_with_else.stderr +++ b/tests/ui/entry_with_else.stderr @@ -2,6 +2,7 @@ error: usage of `contains_key` followed by `insert` on a `HashMap` --> tests/ui/entry_with_else.rs:14:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | m.insert(k, v); LL | | } else { LL | | m.insert(k, v2); @@ -14,6 +15,7 @@ help: try | LL ~ match m.entry(k) { LL + std::collections::hash_map::Entry::Vacant(e) => { +LL + LL + e.insert(v); LL + } LL + std::collections::hash_map::Entry::Occupied(mut e) => { @@ -23,9 +25,10 @@ LL + } | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry_with_else.rs:20:5 + --> tests/ui/entry_with_else.rs:21:5 | LL | / if m.contains_key(&k) { +LL | | LL | | m.insert(k, v); LL | | } else { LL | | m.insert(k, v2); @@ -36,6 +39,7 @@ help: try | LL ~ match m.entry(k) { LL + std::collections::hash_map::Entry::Occupied(mut e) => { +LL + LL + e.insert(v); LL + } LL + std::collections::hash_map::Entry::Vacant(e) => { @@ -45,9 +49,10 @@ LL + } | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry_with_else.rs:26:5 + --> tests/ui/entry_with_else.rs:28:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | m.insert(k, v); LL | | } else { LL | | foo(); @@ -57,6 +62,7 @@ LL | | } help: try | LL ~ if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { +LL + LL + e.insert(v); LL + } else { LL + foo(); @@ -64,9 +70,10 @@ LL + } | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry_with_else.rs:32:5 + --> tests/ui/entry_with_else.rs:35:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | foo(); LL | | } else { LL | | m.insert(k, v); @@ -78,14 +85,16 @@ help: try LL ~ if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) { LL + e.insert(v); LL + } else { +LL + LL + foo(); LL + } | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry_with_else.rs:38:5 + --> tests/ui/entry_with_else.rs:42:5 | LL | / if !m.contains_key(&k) { +LL | | LL | | m.insert(k, v); LL | | } else { LL | | m.insert(k, v2); @@ -96,6 +105,7 @@ help: try | LL ~ match m.entry(k) { LL + std::collections::hash_map::Entry::Vacant(e) => { +LL + LL + e.insert(v); LL + } LL + std::collections::hash_map::Entry::Occupied(mut e) => { @@ -105,9 +115,10 @@ LL + } | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry_with_else.rs:44:5 + --> tests/ui/entry_with_else.rs:49:5 | LL | / if m.contains_key(&k) { +LL | | LL | | if true { m.insert(k, v) } else { m.insert(k, v2) } LL | | } else { LL | | m.insert(k, v) @@ -118,6 +129,7 @@ help: try | LL ~ match m.entry(k) { LL + std::collections::hash_map::Entry::Occupied(mut e) => { +LL + LL + if true { Some(e.insert(v)) } else { Some(e.insert(v2)) } LL + } LL + std::collections::hash_map::Entry::Vacant(e) => { @@ -128,9 +140,10 @@ LL ~ }; | error: usage of `contains_key` followed by `insert` on a `HashMap` - --> tests/ui/entry_with_else.rs:50:5 + --> tests/ui/entry_with_else.rs:56:5 | LL | / if m.contains_key(&k) { +LL | | LL | | foo(); LL | | m.insert(k, v) LL | | } else { @@ -141,6 +154,7 @@ LL | | }; help: try | LL ~ if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) { +LL + LL + foo(); LL + Some(e.insert(v)) LL + } else { diff --git a/tests/ui/enum_clike_unportable_variant.rs b/tests/ui/enum_clike_unportable_variant.rs index 37849179d6a0..f54cca9c611c 100644 --- a/tests/ui/enum_clike_unportable_variant.rs +++ b/tests/ui/enum_clike_unportable_variant.rs @@ -6,8 +6,9 @@ #[repr(usize)] enum NonPortable { X = 0x1_0000_0000, - //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets - //~| NOTE: `-D clippy::enum-clike-unportable-variant` implied by `-D warnings` + //~^ enum_clike_unportable_variant + + Y = 0, Z = 0x7FFF_FFFF, A = 0xFFFF_FFFF, @@ -15,11 +16,13 @@ enum NonPortable { enum NonPortableNoHint { X = 0x1_0000_0000, - //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets + //~^ enum_clike_unportable_variant + Y = 0, Z = 0x7FFF_FFFF, A = 0xFFFF_FFFF, - //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets + //~^ enum_clike_unportable_variant + } #[repr(isize)] @@ -27,27 +30,33 @@ enum NonPortableSigned { X = -1, Y = 0x7FFF_FFFF, Z = 0xFFFF_FFFF, - //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets + //~^ enum_clike_unportable_variant + A = 0x1_0000_0000, - //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets + //~^ enum_clike_unportable_variant + B = i32::MIN as isize, C = (i32::MIN as isize) - 1, - //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets + //~^ enum_clike_unportable_variant + } enum NonPortableSignedNoHint { X = -1, Y = 0x7FFF_FFFF, Z = 0xFFFF_FFFF, - //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets + //~^ enum_clike_unportable_variant + A = 0x1_0000_0000, - //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets + //~^ enum_clike_unportable_variant + } #[repr(usize)] enum NonPortable2 { X = ::Number, - //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets + //~^ enum_clike_unportable_variant + Y = 0, } diff --git a/tests/ui/enum_clike_unportable_variant.stderr b/tests/ui/enum_clike_unportable_variant.stderr index 741de179a497..ade2106ad96c 100644 --- a/tests/ui/enum_clike_unportable_variant.stderr +++ b/tests/ui/enum_clike_unportable_variant.stderr @@ -8,49 +8,49 @@ LL | X = 0x1_0000_0000, = help: to override `-D warnings` add `#[allow(clippy::enum_clike_unportable_variant)]` error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:17:5 + --> tests/ui/enum_clike_unportable_variant.rs:18:5 | LL | X = 0x1_0000_0000, | ^^^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:21:5 + --> tests/ui/enum_clike_unportable_variant.rs:23:5 | LL | A = 0xFFFF_FFFF, | ^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:29:5 + --> tests/ui/enum_clike_unportable_variant.rs:32:5 | LL | Z = 0xFFFF_FFFF, | ^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:31:5 + --> tests/ui/enum_clike_unportable_variant.rs:35:5 | LL | A = 0x1_0000_0000, | ^^^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:34:5 + --> tests/ui/enum_clike_unportable_variant.rs:39:5 | LL | C = (i32::MIN as isize) - 1, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:41:5 + --> tests/ui/enum_clike_unportable_variant.rs:47:5 | LL | Z = 0xFFFF_FFFF, | ^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:43:5 + --> tests/ui/enum_clike_unportable_variant.rs:50:5 | LL | A = 0x1_0000_0000, | ^^^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:49:5 + --> tests/ui/enum_clike_unportable_variant.rs:57:5 | LL | X = ::Number, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/enum_glob_use.fixed b/tests/ui/enum_glob_use.fixed index 3c0db9beb1a6..881493f3d5ff 100644 --- a/tests/ui/enum_glob_use.fixed +++ b/tests/ui/enum_glob_use.fixed @@ -3,16 +3,19 @@ #![warn(unused_imports)] use std::cmp::Ordering::Less; +//~^ enum_glob_use enum Enum { Foo, } use self::Enum::Foo; +//~^ enum_glob_use mod in_fn_test { fn blarg() { use crate::Enum::Foo; + //~^ enum_glob_use let _ = Foo; } diff --git a/tests/ui/enum_glob_use.rs b/tests/ui/enum_glob_use.rs index 2538477f7978..a510462ecb2f 100644 --- a/tests/ui/enum_glob_use.rs +++ b/tests/ui/enum_glob_use.rs @@ -3,16 +3,19 @@ #![warn(unused_imports)] use std::cmp::Ordering::*; +//~^ enum_glob_use enum Enum { Foo, } use self::Enum::*; +//~^ enum_glob_use mod in_fn_test { fn blarg() { use crate::Enum::*; + //~^ enum_glob_use let _ = Foo; } diff --git a/tests/ui/enum_glob_use.stderr b/tests/ui/enum_glob_use.stderr index 6825383b769d..a2cef8008e21 100644 --- a/tests/ui/enum_glob_use.stderr +++ b/tests/ui/enum_glob_use.stderr @@ -8,13 +8,13 @@ LL | use std::cmp::Ordering::*; = help: to override `-D warnings` add `#[allow(clippy::enum_glob_use)]` error: usage of wildcard import for enum variants - --> tests/ui/enum_glob_use.rs:11:5 + --> tests/ui/enum_glob_use.rs:12:5 | LL | use self::Enum::*; | ^^^^^^^^^^^^^ help: try: `self::Enum::Foo` error: usage of wildcard import for enum variants - --> tests/ui/enum_glob_use.rs:15:13 + --> tests/ui/enum_glob_use.rs:17:13 | LL | use crate::Enum::*; | ^^^^^^^^^^^^^^ help: try: `crate::Enum::Foo` diff --git a/tests/ui/enum_variants.rs b/tests/ui/enum_variants.rs index ddf2dfdaea9b..f3c81b2111ce 100644 --- a/tests/ui/enum_variants.rs +++ b/tests/ui/enum_variants.rs @@ -12,10 +12,9 @@ enum FakeCallType2 { } enum Foo { - //~^ ERROR: all variants have the same prefix: `c` +//~^ enum_variant_names cFoo, - //~^ ERROR: variant name ends with the enum's name - //~| NOTE: `-D clippy::enum-variant-names` implied by `-D warnings` + //~^ enum_variant_names cBar, cBaz, } @@ -26,13 +25,13 @@ enum Fooo { } enum Food { - //~^ ERROR: all variants have the same prefix: `Food` +//~^ enum_variant_names FoodGood, - //~^ ERROR: variant name starts with the enum's name + //~^ enum_variant_names FoodMiddle, - //~^ ERROR: variant name starts with the enum's name + //~^ enum_variant_names FoodBad, - //~^ ERROR: variant name starts with the enum's name + //~^ enum_variant_names } enum Stuff { @@ -40,7 +39,8 @@ enum Stuff { } enum BadCallType { - //~^ ERROR: all variants have the same prefix: `CallType` +//~^ enum_variant_names + CallTypeCall, CallTypeCreate, CallTypeDestroy, @@ -53,7 +53,7 @@ enum TwoCallType { } enum Consts { - //~^ ERROR: all variants have the same prefix: `Constant` +//~^ enum_variant_names ConstantInt, ConstantCake, ConstantLie, @@ -66,7 +66,7 @@ enum Two { } enum Something { - //~^ ERROR: all variants have the same prefix: `C` +//~^ enum_variant_names CCall, CCreate, CCryogenize, @@ -89,7 +89,7 @@ enum Sealll { } enum Seallll { - //~^ ERROR: all variants have the same prefix: `WithOut` +//~^ enum_variant_names WithOutCake, WithOutTea, WithOut, @@ -145,14 +145,14 @@ pub enum NetworkLayer { // should lint suggesting `IData`, not only `Data` (see #4639) enum IDataRequest { - //~^ ERROR: all variants have the same postfix: `IData` +//~^ enum_variant_names PutIData(String), GetIData(String), DeleteUnpubIData(String), } enum HIDataRequest { - //~^ ERROR: all variants have the same postfix: `HIData` +//~^ enum_variant_names PutHIData(String), GetHIData(String), DeleteUnpubHIData(String), @@ -173,7 +173,7 @@ enum Phase { mod issue9018 { enum DoLint { - //~^ ERROR: all variants have the same prefix: `_Type` + //~^ enum_variant_names _TypeCreate, _TypeRead, _TypeUpdate, @@ -181,7 +181,7 @@ mod issue9018 { } enum DoLintToo { - //~^ ERROR: all variants have the same postfix: `Type` + //~^ enum_variant_names _CreateType, _UpdateType, _DeleteType, @@ -210,12 +210,12 @@ mod issue11494 { Valid, Invalid, DataDependent, - //~^ ERROR: variant name starts with the enum's name + //~^ enum_variant_names } enum Datas { DatasDependent, - //~^ ERROR: variant name starts with the enum's name + //~^ enum_variant_names Valid, Invalid, } diff --git a/tests/ui/enum_variants.stderr b/tests/ui/enum_variants.stderr index ecca6c833ac5..2f0b0e6149d2 100644 --- a/tests/ui/enum_variants.stderr +++ b/tests/ui/enum_variants.stderr @@ -21,25 +21,25 @@ LL | | } = help: remove the prefixes and use full paths to the variants instead of glob imports error: variant name starts with the enum's name - --> tests/ui/enum_variants.rs:30:5 + --> tests/ui/enum_variants.rs:29:5 | LL | FoodGood, | ^^^^^^^^ error: variant name starts with the enum's name - --> tests/ui/enum_variants.rs:32:5 + --> tests/ui/enum_variants.rs:31:5 | LL | FoodMiddle, | ^^^^^^^^^^ error: variant name starts with the enum's name - --> tests/ui/enum_variants.rs:34:5 + --> tests/ui/enum_variants.rs:33:5 | LL | FoodBad, | ^^^^^^^ error: all variants have the same prefix: `Food` - --> tests/ui/enum_variants.rs:28:1 + --> tests/ui/enum_variants.rs:27:1 | LL | / enum Food { LL | | @@ -51,10 +51,11 @@ LL | | } = help: remove the prefixes and use full paths to the variants instead of glob imports error: all variants have the same prefix: `CallType` - --> tests/ui/enum_variants.rs:42:1 + --> tests/ui/enum_variants.rs:41:1 | LL | / enum BadCallType { LL | | +LL | | LL | | CallTypeCall, LL | | CallTypeCreate, LL | | CallTypeDestroy, diff --git a/tests/ui/eprint_with_newline.fixed b/tests/ui/eprint_with_newline.fixed index 7383d784c841..cb6cff419e9d 100644 --- a/tests/ui/eprint_with_newline.fixed +++ b/tests/ui/eprint_with_newline.fixed @@ -3,16 +3,21 @@ fn main() { eprintln!("Hello"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline - //~| NOTE: `-D clippy::print-with-newline` implied by `-D warnings` + //~^ print_with_newline + + eprintln!("Hello {}", "world"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprintln!("Hello {} {}", "world", "#2"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprintln!("{}", 1265); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprintln!(); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + // these are all fine eprint!(""); @@ -35,7 +40,8 @@ fn main() { // #3514 eprint!("\\n"); eprintln!("\\"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprint!("\\\\n"); // Raw strings @@ -44,11 +50,13 @@ fn main() { // Literal newlines should also fail eprintln!( - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + ); eprintln!( - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + ); @@ -56,7 +64,8 @@ fn main() { eprint!("\r\n"); eprint!("foo\r\n"); eprintln!("\\r"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprint!("foo\rbar\n"); // Ignore expanded format strings diff --git a/tests/ui/eprint_with_newline.rs b/tests/ui/eprint_with_newline.rs index 5b114056411d..cfe503cec1f1 100644 --- a/tests/ui/eprint_with_newline.rs +++ b/tests/ui/eprint_with_newline.rs @@ -3,16 +3,21 @@ fn main() { eprint!("Hello\n"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline - //~| NOTE: `-D clippy::print-with-newline` implied by `-D warnings` + //~^ print_with_newline + + eprint!("Hello {}\n", "world"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprint!("Hello {} {}\n", "world", "#2"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprint!("{}\n", 1265); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprint!("\n"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + // these are all fine eprint!(""); @@ -35,7 +40,8 @@ fn main() { // #3514 eprint!("\\n"); eprint!("\\\n"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprint!("\\\\n"); // Raw strings @@ -44,12 +50,14 @@ fn main() { // Literal newlines should also fail eprint!( - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + " " ); eprint!( - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + r" " ); @@ -58,7 +66,8 @@ fn main() { eprint!("\r\n"); eprint!("foo\r\n"); eprint!("\\r\n"); - //~^ ERROR: using `eprint!()` with a format string that ends in a single newline + //~^ print_with_newline + eprint!("foo\rbar\n"); // Ignore expanded format strings diff --git a/tests/ui/eprint_with_newline.stderr b/tests/ui/eprint_with_newline.stderr index de450090a66e..87dcb9126b6d 100644 --- a/tests/ui/eprint_with_newline.stderr +++ b/tests/ui/eprint_with_newline.stderr @@ -13,7 +13,7 @@ LL + eprintln!("Hello"); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:8:5 + --> tests/ui/eprint_with_newline.rs:9:5 | LL | eprint!("Hello {}\n", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + eprintln!("Hello {}", "world"); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:10:5 + --> tests/ui/eprint_with_newline.rs:12:5 | LL | eprint!("Hello {} {}\n", "world", "#2"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + eprintln!("Hello {} {}", "world", "#2"); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:12:5 + --> tests/ui/eprint_with_newline.rs:15:5 | LL | eprint!("{}\n", 1265); | ^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + eprintln!("{}", 1265); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:14:5 + --> tests/ui/eprint_with_newline.rs:18:5 | LL | eprint!("\n"); | ^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + eprintln!(); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:37:5 + --> tests/ui/eprint_with_newline.rs:42:5 | LL | eprint!("\\\n"); | ^^^^^^^^^^^^^^^ @@ -73,10 +73,11 @@ LL + eprintln!("\\"); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:46:5 + --> tests/ui/eprint_with_newline.rs:52:5 | LL | / eprint!( LL | | +LL | | LL | | " LL | | " LL | | ); @@ -86,14 +87,16 @@ help: use `eprintln!` instead | LL ~ eprintln!( LL | +LL | LL ~ | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:51:5 + --> tests/ui/eprint_with_newline.rs:58:5 | LL | / eprint!( LL | | +LL | | LL | | r" LL | | " LL | | ); @@ -103,11 +106,12 @@ help: use `eprintln!` instead | LL ~ eprintln!( LL | +LL | LL ~ | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:60:5 + --> tests/ui/eprint_with_newline.rs:68:5 | LL | eprint!("\\r\n"); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/eq_op.rs b/tests/ui/eq_op.rs index 7c2c13187518..757a7e011903 100644 --- a/tests/ui/eq_op.rs +++ b/tests/ui/eq_op.rs @@ -5,80 +5,107 @@ fn main() { // simple values and comparisons let _ = 1 == 1; - //~^ ERROR: equal expressions as operands to `==` - //~| NOTE: `-D clippy::eq-op` implied by `-D warnings` + //~^ eq_op + + let _ = "no" == "no"; - //~^ ERROR: equal expressions as operands to `==` + //~^ eq_op + // even though I agree that no means no ;-) let _ = false != false; - //~^ ERROR: equal expressions as operands to `!=` + //~^ eq_op + let _ = 1.5 < 1.5; - //~^ ERROR: equal expressions as operands to `<` + //~^ eq_op + let _ = 1u64 >= 1u64; - //~^ ERROR: equal expressions as operands to `>=` + //~^ eq_op + let x = f32::NAN; let _ = x != x; - //~^ ERROR: equal expressions as operands to `!=` - //~| NOTE: if you intended to check if the operand is NaN, use `.is_nan()` instead + //~^ eq_op + + // casts, methods, parentheses let _ = (1u32 as u64) & (1u32 as u64); - //~^ ERROR: equal expressions as operands to `&` + //~^ eq_op + #[rustfmt::skip] { let _ = 1 ^ ((((((1)))))); - //~^ ERROR: equal expressions as operands to `^` + //~^ eq_op + }; // unary and binary operators let _ = (-(2) < -(2)); - //~^ ERROR: equal expressions as operands to `<` + //~^ eq_op + let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); - //~^ ERROR: equal expressions as operands to `==` - //~| ERROR: equal expressions as operands to `&` - //~| ERROR: equal expressions as operands to `&` + //~^ eq_op + //~| eq_op + //~| eq_op + + + let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4; - //~^ ERROR: equal expressions as operands to `==` + //~^ eq_op + // various other things let _ = ([1] != [1]); - //~^ ERROR: equal expressions as operands to `!=` + //~^ eq_op + let _ = ((1, 2) != (1, 2)); - //~^ ERROR: equal expressions as operands to `!=` + //~^ eq_op + let _ = vec![1, 2, 3] == vec![1, 2, 3]; //no error yet, as we don't match macros // const folding let _ = 1 + 1 == 2; - //~^ ERROR: equal expressions as operands to `==` + //~^ eq_op + let _ = 1 - 1 == 0; - //~^ ERROR: equal expressions as operands to `==` - //~| ERROR: equal expressions as operands to `-` + //~^ eq_op + //~| eq_op + + let _ = 1 - 1; - //~^ ERROR: equal expressions as operands to `-` + //~^ eq_op + let _ = 1 / 1; - //~^ ERROR: equal expressions as operands to `/` + //~^ eq_op + let _ = true && true; - //~^ ERROR: equal expressions as operands to `&&` + //~^ eq_op + let _ = true || true; - //~^ ERROR: equal expressions as operands to `||` + //~^ eq_op + let a: u32 = 0; let b: u32 = 0; let _ = a == b && b == a; - //~^ ERROR: equal expressions as operands to `&&` + //~^ eq_op + let _ = a != b && b != a; - //~^ ERROR: equal expressions as operands to `&&` + //~^ eq_op + let _ = a < b && b > a; - //~^ ERROR: equal expressions as operands to `&&` + //~^ eq_op + let _ = a <= b && b >= a; - //~^ ERROR: equal expressions as operands to `&&` + //~^ eq_op + let mut a = vec![1]; let _ = a == a; - //~^ ERROR: equal expressions as operands to `==` + //~^ eq_op + let _ = 2 * a.len() == 2 * a.len(); // ok, functions let _ = a.pop() == a.pop(); // ok, functions @@ -89,7 +116,8 @@ fn main() { const B: u32 = 10; const C: u32 = A / B; // ok, different named constants const D: u32 = A / A; - //~^ ERROR: equal expressions as operands to `/` + //~^ eq_op + } macro_rules! check_if_named_foo { @@ -121,7 +149,8 @@ struct Nested { fn check_nested(n1: &Nested, n2: &Nested) -> bool { // `n2.inner.0.0` mistyped as `n1.inner.0.0` (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0 - //~^ ERROR: equal expressions as operands to `==` + //~^ eq_op + } #[test] diff --git a/tests/ui/eq_op.stderr b/tests/ui/eq_op.stderr index bd3c115d8b8b..bd9362f3e0dd 100644 --- a/tests/ui/eq_op.stderr +++ b/tests/ui/eq_op.stderr @@ -8,31 +8,31 @@ LL | let _ = 1 == 1; = help: to override `-D warnings` add `#[allow(clippy::eq_op)]` error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:10:13 + --> tests/ui/eq_op.rs:11:13 | LL | let _ = "no" == "no"; | ^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/eq_op.rs:13:13 + --> tests/ui/eq_op.rs:15:13 | LL | let _ = false != false; | ^^^^^^^^^^^^^^ error: equal expressions as operands to `<` - --> tests/ui/eq_op.rs:15:13 + --> tests/ui/eq_op.rs:18:13 | LL | let _ = 1.5 < 1.5; | ^^^^^^^^^ error: equal expressions as operands to `>=` - --> tests/ui/eq_op.rs:17:13 + --> tests/ui/eq_op.rs:21:13 | LL | let _ = 1u64 >= 1u64; | ^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/eq_op.rs:20:13 + --> tests/ui/eq_op.rs:25:13 | LL | let _ = x != x; | ^^^^^^ @@ -40,139 +40,139 @@ LL | let _ = x != x; = note: if you intended to check if the operand is NaN, use `.is_nan()` instead error: equal expressions as operands to `&` - --> tests/ui/eq_op.rs:25:13 + --> tests/ui/eq_op.rs:31:13 | LL | let _ = (1u32 as u64) & (1u32 as u64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `^` - --> tests/ui/eq_op.rs:29:17 + --> tests/ui/eq_op.rs:36:17 | LL | let _ = 1 ^ ((((((1)))))); | ^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `<` - --> tests/ui/eq_op.rs:34:13 + --> tests/ui/eq_op.rs:42:13 | LL | let _ = (-(2) < -(2)); | ^^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:36:13 + --> tests/ui/eq_op.rs:45:13 | LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `&` - --> tests/ui/eq_op.rs:36:14 + --> tests/ui/eq_op.rs:45:14 | LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); | ^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `&` - --> tests/ui/eq_op.rs:36:35 + --> tests/ui/eq_op.rs:45:35 | LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); | ^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:40:13 + --> tests/ui/eq_op.rs:52:13 | LL | let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/eq_op.rs:44:13 + --> tests/ui/eq_op.rs:57:13 | LL | let _ = ([1] != [1]); | ^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/eq_op.rs:46:13 + --> tests/ui/eq_op.rs:60:13 | LL | let _ = ((1, 2) != (1, 2)); | ^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:51:13 + --> tests/ui/eq_op.rs:66:13 | LL | let _ = 1 + 1 == 2; | ^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:53:13 + --> tests/ui/eq_op.rs:69:13 | LL | let _ = 1 - 1 == 0; | ^^^^^^^^^^ error: equal expressions as operands to `-` - --> tests/ui/eq_op.rs:53:13 + --> tests/ui/eq_op.rs:69:13 | LL | let _ = 1 - 1 == 0; | ^^^^^ error: equal expressions as operands to `-` - --> tests/ui/eq_op.rs:57:13 + --> tests/ui/eq_op.rs:75:13 | LL | let _ = 1 - 1; | ^^^^^ error: equal expressions as operands to `/` - --> tests/ui/eq_op.rs:59:13 + --> tests/ui/eq_op.rs:78:13 | LL | let _ = 1 / 1; | ^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:61:13 + --> tests/ui/eq_op.rs:81:13 | LL | let _ = true && true; | ^^^^^^^^^^^^ error: equal expressions as operands to `||` - --> tests/ui/eq_op.rs:64:13 + --> tests/ui/eq_op.rs:85:13 | LL | let _ = true || true; | ^^^^^^^^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:70:13 + --> tests/ui/eq_op.rs:92:13 | LL | let _ = a == b && b == a; | ^^^^^^^^^^^^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:72:13 + --> tests/ui/eq_op.rs:95:13 | LL | let _ = a != b && b != a; | ^^^^^^^^^^^^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:74:13 + --> tests/ui/eq_op.rs:98:13 | LL | let _ = a < b && b > a; | ^^^^^^^^^^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:76:13 + --> tests/ui/eq_op.rs:101:13 | LL | let _ = a <= b && b >= a; | ^^^^^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:80:13 + --> tests/ui/eq_op.rs:106:13 | LL | let _ = a == a; | ^^^^^^ error: equal expressions as operands to `/` - --> tests/ui/eq_op.rs:91:20 + --> tests/ui/eq_op.rs:118:20 | LL | const D: u32 = A / A; | ^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:123:5 + --> tests/ui/eq_op.rs:151:5 | LL | (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/eq_op_macros.rs b/tests/ui/eq_op_macros.rs index a511af4a31c8..82242d0eb196 100644 --- a/tests/ui/eq_op_macros.rs +++ b/tests/ui/eq_op_macros.rs @@ -6,9 +6,13 @@ macro_rules! assert_in_macro_def { () => { let a = 42; assert_eq!(a, a); + //~^ eq_op assert_ne!(a, a); + //~^ eq_op debug_assert_eq!(a, a); + //~^ eq_op debug_assert_ne!(a, a); + //~^ eq_op }; } @@ -21,9 +25,11 @@ fn main() { // lint identical args in `assert_eq!` assert_eq!(a, a); - //~^ ERROR: identical args used in this `assert_eq!` macro call + //~^ eq_op + assert_eq!(a + 1, a + 1); - //~^ ERROR: identical args used in this `assert_eq!` macro call + //~^ eq_op + // ok assert_eq!(a, b); assert_eq!(a, a + 1); @@ -31,9 +37,11 @@ fn main() { // lint identical args in `assert_ne!` assert_ne!(a, a); - //~^ ERROR: identical args used in this `assert_ne!` macro call + //~^ eq_op + assert_ne!(a + 1, a + 1); - //~^ ERROR: identical args used in this `assert_ne!` macro call + //~^ eq_op + // ok assert_ne!(a, b); assert_ne!(a, a + 1); @@ -41,9 +49,11 @@ fn main() { // lint identical args in `debug_assert_eq!` debug_assert_eq!(a, a); - //~^ ERROR: identical args used in this `debug_assert_eq!` macro call + //~^ eq_op + debug_assert_eq!(a + 1, a + 1); - //~^ ERROR: identical args used in this `debug_assert_eq!` macro call + //~^ eq_op + // ok debug_assert_eq!(a, b); debug_assert_eq!(a, a + 1); @@ -51,9 +61,11 @@ fn main() { // lint identical args in `debug_assert_ne!` debug_assert_ne!(a, a); - //~^ ERROR: identical args used in this `debug_assert_ne!` macro call + //~^ eq_op + debug_assert_ne!(a + 1, a + 1); - //~^ ERROR: identical args used in this `debug_assert_ne!` macro call + //~^ eq_op + // ok debug_assert_ne!(a, b); debug_assert_ne!(a, a + 1); diff --git a/tests/ui/eq_op_macros.stderr b/tests/ui/eq_op_macros.stderr index b114db0ca98e..72315e87bfef 100644 --- a/tests/ui/eq_op_macros.stderr +++ b/tests/ui/eq_op_macros.stderr @@ -12,7 +12,7 @@ LL | assert_in_macro_def!(); = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info) error: identical args used in this `assert_ne!` macro call - --> tests/ui/eq_op_macros.rs:9:20 + --> tests/ui/eq_op_macros.rs:10:20 | LL | assert_ne!(a, a); | ^^^^ @@ -23,7 +23,7 @@ LL | assert_in_macro_def!(); = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info) error: identical args used in this `debug_assert_eq!` macro call - --> tests/ui/eq_op_macros.rs:10:26 + --> tests/ui/eq_op_macros.rs:12:26 | LL | debug_assert_eq!(a, a); | ^^^^ @@ -34,7 +34,7 @@ LL | assert_in_macro_def!(); = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info) error: identical args used in this `debug_assert_ne!` macro call - --> tests/ui/eq_op_macros.rs:11:26 + --> tests/ui/eq_op_macros.rs:14:26 | LL | debug_assert_ne!(a, a); | ^^^^ @@ -45,49 +45,49 @@ LL | assert_in_macro_def!(); = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info) error: identical args used in this `assert_eq!` macro call - --> tests/ui/eq_op_macros.rs:23:16 + --> tests/ui/eq_op_macros.rs:27:16 | LL | assert_eq!(a, a); | ^^^^ error: identical args used in this `assert_eq!` macro call - --> tests/ui/eq_op_macros.rs:25:16 + --> tests/ui/eq_op_macros.rs:30:16 | LL | assert_eq!(a + 1, a + 1); | ^^^^^^^^^^^^ error: identical args used in this `assert_ne!` macro call - --> tests/ui/eq_op_macros.rs:33:16 + --> tests/ui/eq_op_macros.rs:39:16 | LL | assert_ne!(a, a); | ^^^^ error: identical args used in this `assert_ne!` macro call - --> tests/ui/eq_op_macros.rs:35:16 + --> tests/ui/eq_op_macros.rs:42:16 | LL | assert_ne!(a + 1, a + 1); | ^^^^^^^^^^^^ error: identical args used in this `debug_assert_eq!` macro call - --> tests/ui/eq_op_macros.rs:43:22 + --> tests/ui/eq_op_macros.rs:51:22 | LL | debug_assert_eq!(a, a); | ^^^^ error: identical args used in this `debug_assert_eq!` macro call - --> tests/ui/eq_op_macros.rs:45:22 + --> tests/ui/eq_op_macros.rs:54:22 | LL | debug_assert_eq!(a + 1, a + 1); | ^^^^^^^^^^^^ error: identical args used in this `debug_assert_ne!` macro call - --> tests/ui/eq_op_macros.rs:53:22 + --> tests/ui/eq_op_macros.rs:63:22 | LL | debug_assert_ne!(a, a); | ^^^^ error: identical args used in this `debug_assert_ne!` macro call - --> tests/ui/eq_op_macros.rs:55:22 + --> tests/ui/eq_op_macros.rs:66:22 | LL | debug_assert_ne!(a + 1, a + 1); | ^^^^^^^^^^^^ diff --git a/tests/ui/equatable_if_let.fixed b/tests/ui/equatable_if_let.fixed index 2b523e1e185c..2f39c34cb394 100644 --- a/tests/ui/equatable_if_let.fixed +++ b/tests/ui/equatable_if_let.fixed @@ -62,13 +62,21 @@ fn main() { // true if a == 2 {} + //~^ equatable_if_let if a.cmp(&b) == Ordering::Greater {} + //~^ equatable_if_let if c == Some(2) {} + //~^ equatable_if_let if d == (Struct { a: 2, b: false }) {} + //~^ equatable_if_let if e == Enum::TupleVariant(32, 64) {} + //~^ equatable_if_let if e == (Enum::RecordVariant { a: 64, b: 32 }) {} + //~^ equatable_if_let if e == Enum::UnitVariant {} + //~^ equatable_if_let if (e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false }) {} + //~^ equatable_if_let // false @@ -78,12 +86,18 @@ fn main() { if let Struct { a, b: false } = d {} if let Struct { a: 2, b: x } = d {} if matches!(f, NotPartialEq::A) {} + //~^ equatable_if_let if g == NotStructuralEq::A {} + //~^ equatable_if_let if matches!(Some(f), Some(NotPartialEq::A)) {} + //~^ equatable_if_let if Some(g) == Some(NotStructuralEq::A) {} + //~^ equatable_if_let if matches!(h, NoPartialEqStruct { a: 2, b: false }) {} + //~^ equatable_if_let if "abc" == inline!("abc") { + //~^ equatable_if_let println!("OK"); } diff --git a/tests/ui/equatable_if_let.rs b/tests/ui/equatable_if_let.rs index f7e3bb2964da..f7289a9ee56f 100644 --- a/tests/ui/equatable_if_let.rs +++ b/tests/ui/equatable_if_let.rs @@ -62,13 +62,21 @@ fn main() { // true if let 2 = a {} + //~^ equatable_if_let if let Ordering::Greater = a.cmp(&b) {} + //~^ equatable_if_let if let Some(2) = c {} + //~^ equatable_if_let if let Struct { a: 2, b: false } = d {} + //~^ equatable_if_let if let Enum::TupleVariant(32, 64) = e {} + //~^ equatable_if_let if let Enum::RecordVariant { a: 64, b: 32 } = e {} + //~^ equatable_if_let if let Enum::UnitVariant = e {} + //~^ equatable_if_let if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {} + //~^ equatable_if_let // false @@ -78,12 +86,18 @@ fn main() { if let Struct { a, b: false } = d {} if let Struct { a: 2, b: x } = d {} if let NotPartialEq::A = f {} + //~^ equatable_if_let if let NotStructuralEq::A = g {} + //~^ equatable_if_let if let Some(NotPartialEq::A) = Some(f) {} + //~^ equatable_if_let if let Some(NotStructuralEq::A) = Some(g) {} + //~^ equatable_if_let if let NoPartialEqStruct { a: 2, b: false } = h {} + //~^ equatable_if_let if let inline!("abc") = "abc" { + //~^ equatable_if_let println!("OK"); } diff --git a/tests/ui/equatable_if_let.stderr b/tests/ui/equatable_if_let.stderr index 9e93a33cd7e2..81e0e15a5c74 100644 --- a/tests/ui/equatable_if_let.stderr +++ b/tests/ui/equatable_if_let.stderr @@ -8,79 +8,79 @@ LL | if let 2 = a {} = help: to override `-D warnings` add `#[allow(clippy::equatable_if_let)]` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:65:8 + --> tests/ui/equatable_if_let.rs:66:8 | LL | if let Ordering::Greater = a.cmp(&b) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:66:8 + --> tests/ui/equatable_if_let.rs:68:8 | LL | if let Some(2) = c {} | ^^^^^^^^^^^^^^^ help: try: `c == Some(2)` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:67:8 + --> tests/ui/equatable_if_let.rs:70:8 | LL | if let Struct { a: 2, b: false } = d {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:68:8 + --> tests/ui/equatable_if_let.rs:72:8 | LL | if let Enum::TupleVariant(32, 64) = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:69:8 + --> tests/ui/equatable_if_let.rs:74:8 | LL | if let Enum::RecordVariant { a: 64, b: 32 } = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:70:8 + --> tests/ui/equatable_if_let.rs:76:8 | LL | if let Enum::UnitVariant = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:71:8 + --> tests/ui/equatable_if_let.rs:78:8 | LL | if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })` error: this pattern matching can be expressed using `matches!` - --> tests/ui/equatable_if_let.rs:80:8 + --> tests/ui/equatable_if_let.rs:88:8 | LL | if let NotPartialEq::A = f {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:81:8 + --> tests/ui/equatable_if_let.rs:90:8 | LL | if let NotStructuralEq::A = g {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A` error: this pattern matching can be expressed using `matches!` - --> tests/ui/equatable_if_let.rs:82:8 + --> tests/ui/equatable_if_let.rs:92:8 | LL | if let Some(NotPartialEq::A) = Some(f) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:83:8 + --> tests/ui/equatable_if_let.rs:94:8 | LL | if let Some(NotStructuralEq::A) = Some(g) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)` error: this pattern matching can be expressed using `matches!` - --> tests/ui/equatable_if_let.rs:84:8 + --> tests/ui/equatable_if_let.rs:96:8 | LL | if let NoPartialEqStruct { a: 2, b: false } = h {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:86:8 + --> tests/ui/equatable_if_let.rs:99:8 | LL | if let inline!("abc") = "abc" { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"abc" == inline!("abc")` diff --git a/tests/ui/erasing_op.rs b/tests/ui/erasing_op.rs index 00c74f23fed0..9387a20cb5a0 100644 --- a/tests/ui/erasing_op.rs +++ b/tests/ui/erasing_op.rs @@ -33,17 +33,22 @@ impl core::ops::Mul for Vec1 { #[warn(clippy::erasing_op)] fn test(x: u8) { x * 0; - //~^ ERROR: this operation will always return zero. This is likely not the intended ou - //~| NOTE: `-D clippy::erasing-op` implied by `-D warnings` + //~^ erasing_op + + 0 & x; - //~^ ERROR: this operation will always return zero. This is likely not the intended ou + //~^ erasing_op + 0 / x; - //~^ ERROR: this operation will always return zero. This is likely not the intended ou + //~^ erasing_op + 0 * Meter; // no error: Output type is different from the non-zero argument 0 * Vec1 { x: 5 }; - //~^ ERROR: this operation will always return zero. This is likely not the intended ou + //~^ erasing_op + Vec1 { x: 5 } * 0; - //~^ ERROR: this operation will always return zero. This is likely not the intended ou + //~^ erasing_op + } fn main() { diff --git a/tests/ui/erasing_op.stderr b/tests/ui/erasing_op.stderr index 6ed8bffeb24d..7029fac6c130 100644 --- a/tests/ui/erasing_op.stderr +++ b/tests/ui/erasing_op.stderr @@ -8,25 +8,25 @@ LL | x * 0; = help: to override `-D warnings` add `#[allow(clippy::erasing_op)]` error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/erasing_op.rs:38:5 + --> tests/ui/erasing_op.rs:39:5 | LL | 0 & x; | ^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/erasing_op.rs:40:5 + --> tests/ui/erasing_op.rs:42:5 | LL | 0 / x; | ^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/erasing_op.rs:43:5 + --> tests/ui/erasing_op.rs:46:5 | LL | 0 * Vec1 { x: 5 }; | ^^^^^^^^^^^^^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/erasing_op.rs:45:5 + --> tests/ui/erasing_op.rs:49:5 | LL | Vec1 { x: 5 } * 0; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/err_expect.fixed b/tests/ui/err_expect.fixed index abbc6dbebedb..9e1a3a0c739c 100644 --- a/tests/ui/err_expect.fixed +++ b/tests/ui/err_expect.fixed @@ -8,6 +8,7 @@ struct MyTypeDebug; fn main() { let test_debug: Result = Ok(MyTypeDebug); test_debug.expect_err("Testing debug type"); + //~^ err_expect let test_non_debug: Result = Ok(MyTypeNonDebug); test_non_debug.err().expect("Testing non debug type"); @@ -23,4 +24,5 @@ fn msrv_1_16() { fn msrv_1_17() { let x: Result = Ok(17); x.expect_err("17"); + //~^ err_expect } diff --git a/tests/ui/err_expect.rs b/tests/ui/err_expect.rs index 0c7ad185dfbe..8e9063a2e1d4 100644 --- a/tests/ui/err_expect.rs +++ b/tests/ui/err_expect.rs @@ -8,6 +8,7 @@ struct MyTypeDebug; fn main() { let test_debug: Result = Ok(MyTypeDebug); test_debug.err().expect("Testing debug type"); + //~^ err_expect let test_non_debug: Result = Ok(MyTypeNonDebug); test_non_debug.err().expect("Testing non debug type"); @@ -23,4 +24,5 @@ fn msrv_1_16() { fn msrv_1_17() { let x: Result = Ok(17); x.err().expect("17"); + //~^ err_expect } diff --git a/tests/ui/err_expect.stderr b/tests/ui/err_expect.stderr index 68f39cc45c5b..5b591e1604db 100644 --- a/tests/ui/err_expect.stderr +++ b/tests/ui/err_expect.stderr @@ -8,7 +8,7 @@ LL | test_debug.err().expect("Testing debug type"); = help: to override `-D warnings` add `#[allow(clippy::err_expect)]` error: called `.err().expect()` on a `Result` value - --> tests/ui/err_expect.rs:25:7 + --> tests/ui/err_expect.rs:26:7 | LL | x.err().expect("17"); | ^^^^^^^^^^^^ help: try: `expect_err` diff --git a/tests/ui/error_impl_error.rs b/tests/ui/error_impl_error.rs index 05003f7d047c..3606e1bcefbb 100644 --- a/tests/ui/error_impl_error.rs +++ b/tests/ui/error_impl_error.rs @@ -5,7 +5,8 @@ pub mod a { #[derive(Debug)] pub struct Error; - //~^ ERROR: exported type named `Error` that implements `Error` + //~^ error_impl_error + impl std::fmt::Display for Error { fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -19,7 +20,8 @@ pub mod a { mod b { #[derive(Debug)] pub(super) enum Error {} - //~^ ERROR: exported type named `Error` that implements `Error` + //~^ error_impl_error + impl std::fmt::Display for Error { fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -32,7 +34,8 @@ mod b { pub mod c { pub union Error { - //~^ ERROR: exported type named `Error` that implements `Error` + //~^ error_impl_error + a: u32, b: u32, } @@ -54,7 +57,8 @@ pub mod c { pub mod d { pub type Error = std::fmt::Error; - //~^ ERROR: exported type alias named `Error` that implements `Error` + //~^ error_impl_error + } mod e { diff --git a/tests/ui/error_impl_error.stderr b/tests/ui/error_impl_error.stderr index 087d43d1d083..4fa1ffeb4c92 100644 --- a/tests/ui/error_impl_error.stderr +++ b/tests/ui/error_impl_error.stderr @@ -5,7 +5,7 @@ LL | pub struct Error; | ^^^^^ | note: `Error` was implemented here - --> tests/ui/error_impl_error.rs:16:5 + --> tests/ui/error_impl_error.rs:17:5 | LL | impl std::error::Error for Error {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,31 +13,31 @@ LL | impl std::error::Error for Error {} = help: to override `-D warnings` add `#[allow(clippy::error_impl_error)]` error: exported type named `Error` that implements `Error` - --> tests/ui/error_impl_error.rs:21:21 + --> tests/ui/error_impl_error.rs:22:21 | LL | pub(super) enum Error {} | ^^^^^ | note: `Error` was implemented here - --> tests/ui/error_impl_error.rs:30:5 + --> tests/ui/error_impl_error.rs:32:5 | LL | impl std::error::Error for Error {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: exported type named `Error` that implements `Error` - --> tests/ui/error_impl_error.rs:34:15 + --> tests/ui/error_impl_error.rs:36:15 | LL | pub union Error { | ^^^^^ | note: `Error` was implemented here - --> tests/ui/error_impl_error.rs:52:5 + --> tests/ui/error_impl_error.rs:55:5 | LL | impl std::error::Error for Error {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: exported type alias named `Error` that implements `Error` - --> tests/ui/error_impl_error.rs:56:14 + --> tests/ui/error_impl_error.rs:59:14 | LL | pub type Error = std::fmt::Error; | ^^^^^ diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed index abccc30ef87d..2be5c7d2b4b0 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -29,12 +29,16 @@ macro_rules! closure_mac { fn main() { let a = Some(1u8).map(foo); + //~^ redundant_closure let c = Some(1u8).map(|a| {1+2; foo}(a)); true.then(|| mac!()); // don't lint function in macro expansion Some(1).map(closure_mac!()); // don't lint closure in macro expansion let _: Option> = true.then(std::vec::Vec::new); // special case vec! + //~^ redundant_closure let d = Some(1u8).map(|a| foo(foo2(a))); //is adjusted? + //~^ redundant_closure all(&[1, 2, 3], &&2, below); //is adjusted + //~^ redundant_closure unsafe { Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn } @@ -42,6 +46,7 @@ fn main() { // See #815 let e = Some(1u8).map(|a| divergent(a)); let e = Some(1u8).map(generic); + //~^ redundant_closure let e = Some(1u8).map(generic); // See #515 let a: Option)>> = @@ -94,16 +99,22 @@ impl<'a> std::ops::Deref for TestStruct<'a> { fn test_redundant_closures_containing_method_calls() { let i = 10; let e = Some(TestStruct { some_ref: &i }).map(TestStruct::foo); + //~^ redundant_closure_for_method_calls let e = Some(TestStruct { some_ref: &i }).map(TestTrait::trait_foo); + //~^ redundant_closure_for_method_calls let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo_ref()); let e = Some(&mut vec![1, 2, 3]).map(std::vec::Vec::clear); + //~^ redundant_closure_for_method_calls unsafe { let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo_unsafe()); } let e = Some("str").map(std::string::ToString::to_string); + //~^ redundant_closure_for_method_calls let e = Some('a').map(char::to_uppercase); + //~^ redundant_closure_for_method_calls let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.len_utf8()).collect(); let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(char::to_ascii_uppercase).collect(); + //~^ redundant_closure_for_method_calls let e = Some(PathBuf::new()).as_ref().and_then(|s| s.to_str()); let c = Some(TestStruct { some_ref: &i }) .as_ref() @@ -120,6 +131,7 @@ fn test_redundant_closures_containing_method_calls() { fn issue14096() { let x = Some("42"); let _ = x.map(str::parse::); + //~^ redundant_closure_for_method_calls } } @@ -172,6 +184,7 @@ fn generic(_: T) -> u8 { fn passes_fn_mut(mut x: Box) { requires_fn_once(x); + //~^ redundant_closure } fn requires_fn_once(_: T) {} @@ -179,11 +192,13 @@ fn test_redundant_closure_with_function_pointer() { type FnPtrType = fn(u8); let foo_ptr: FnPtrType = foo; let a = Some(1u8).map(foo_ptr); + //~^ redundant_closure } fn test_redundant_closure_with_another_closure() { let closure = |a| println!("{}", a); let a = Some(1u8).map(closure); + //~^ redundant_closure } fn make_lazy(f: impl Fn() -> fn(u8) -> u8) -> impl Fn(u8) -> u8 { @@ -216,8 +231,11 @@ fn mutable_closure_used_again(x: Vec, y: Vec, z: Vec) { let mut res = Vec::new(); let mut add_to_res = |n| res.push(n); x.into_iter().for_each(&mut add_to_res); + //~^ redundant_closure y.into_iter().for_each(&mut add_to_res); + //~^ redundant_closure z.into_iter().for_each(add_to_res); + //~^ redundant_closure } fn mutable_closure_in_loop() { @@ -225,10 +243,12 @@ fn mutable_closure_in_loop() { let mut closure = |n| value += n; for _ in 0..5 { Some(1).map(&mut closure); + //~^ redundant_closure let mut value = 0; let mut in_loop = |n| value += n; Some(1).map(in_loop); + //~^ redundant_closure } } @@ -322,13 +342,16 @@ fn not_general_enough() { pub fn mutable_impl_fn_mut(mut f: impl FnMut(), mut f_used_once: impl FnMut()) -> impl FnMut() { fn takes_fn_mut(_: impl FnMut()) {} takes_fn_mut(&mut f); + //~^ redundant_closure fn takes_fn_once(_: impl FnOnce()) {} takes_fn_once(&mut f); + //~^ redundant_closure f(); move || takes_fn_mut(&mut f_used_once) + //~^ redundant_closure } impl dyn TestTrait + '_ { @@ -341,16 +364,20 @@ impl dyn TestTrait + '_ { fn angle_brackets_and_args() { let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]); array_opt.map(<[u8; 3]>::as_slice); + //~^ redundant_closure_for_method_calls let slice_opt: Option<&[u8]> = Some(b"slice"); slice_opt.map(<[u8]>::len); + //~^ redundant_closure_for_method_calls let ptr_opt: Option<*const usize> = Some(&487); ptr_opt.map(<*const usize>::is_null); + //~^ redundant_closure_for_method_calls let test_struct = TestStruct { some_ref: &487 }; let dyn_opt: Option<&dyn TestTrait> = Some(&test_struct); dyn_opt.map(::method_on_dyn); + //~^ redundant_closure_for_method_calls } // https://github.com/rust-lang/rust-clippy/issues/12199 @@ -411,6 +438,7 @@ fn _mixed_late_bound_and_early_bound_regions() { *y } let _ = f(&0, f2); + //~^ redundant_closure } fn _closure_with_types() { @@ -439,10 +467,12 @@ mod issue_10854 { pub fn calls_test(test: Option) -> Option { test.map(Test::method) + //~^ redundant_closure_for_method_calls } pub fn calls_outer(test: Option) -> Option { test.map(super::Outer::method) + //~^ redundant_closure_for_method_calls } } @@ -456,6 +486,7 @@ mod issue_10854 { pub fn calls_into_mod(test: Option) -> Option { test.map(test_mod::Test::method) + //~^ redundant_closure_for_method_calls } mod a { @@ -463,6 +494,7 @@ mod issue_10854 { pub mod c { pub fn extreme_nesting(test: Option) -> Option { test.map(crate::issue_10854::d::Test::method) + //~^ redundant_closure_for_method_calls } } } @@ -482,10 +514,12 @@ mod issue_10854 { mod issue_12853 { fn f_by_value(f: F) { let x = Box::new(|| None.map(&f)); + //~^ redundant_closure x(); } fn f_by_ref(f: &F) { let x = Box::new(|| None.map(f)); + //~^ redundant_closure x(); } } @@ -503,5 +537,6 @@ mod issue_13073 { let _field = bind.as_deref().or_else(|| get_default()).unwrap(); // should lint let _field = bind.or_else(get_default).unwrap(); + //~^ redundant_closure } } diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index 9bcee4eba340..7c9a92306b95 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -29,12 +29,16 @@ macro_rules! closure_mac { fn main() { let a = Some(1u8).map(|a| foo(a)); + //~^ redundant_closure let c = Some(1u8).map(|a| {1+2; foo}(a)); true.then(|| mac!()); // don't lint function in macro expansion Some(1).map(closure_mac!()); // don't lint closure in macro expansion let _: Option> = true.then(|| vec![]); // special case vec! + //~^ redundant_closure let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? + //~^ redundant_closure all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted + //~^ redundant_closure unsafe { Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn } @@ -42,6 +46,7 @@ fn main() { // See #815 let e = Some(1u8).map(|a| divergent(a)); let e = Some(1u8).map(|a| generic(a)); + //~^ redundant_closure let e = Some(1u8).map(generic); // See #515 let a: Option)>> = @@ -94,16 +99,22 @@ impl<'a> std::ops::Deref for TestStruct<'a> { fn test_redundant_closures_containing_method_calls() { let i = 10; let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); + //~^ redundant_closure_for_method_calls let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo()); + //~^ redundant_closure_for_method_calls let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo_ref()); let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear()); + //~^ redundant_closure_for_method_calls unsafe { let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo_unsafe()); } let e = Some("str").map(|s| s.to_string()); + //~^ redundant_closure_for_method_calls let e = Some('a').map(|s| s.to_uppercase()); + //~^ redundant_closure_for_method_calls let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.len_utf8()).collect(); let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect(); + //~^ redundant_closure_for_method_calls let e = Some(PathBuf::new()).as_ref().and_then(|s| s.to_str()); let c = Some(TestStruct { some_ref: &i }) .as_ref() @@ -120,6 +131,7 @@ fn test_redundant_closures_containing_method_calls() { fn issue14096() { let x = Some("42"); let _ = x.map(|x| x.parse::()); + //~^ redundant_closure_for_method_calls } } @@ -172,6 +184,7 @@ fn generic(_: T) -> u8 { fn passes_fn_mut(mut x: Box) { requires_fn_once(|| x()); + //~^ redundant_closure } fn requires_fn_once(_: T) {} @@ -179,11 +192,13 @@ fn test_redundant_closure_with_function_pointer() { type FnPtrType = fn(u8); let foo_ptr: FnPtrType = foo; let a = Some(1u8).map(|a| foo_ptr(a)); + //~^ redundant_closure } fn test_redundant_closure_with_another_closure() { let closure = |a| println!("{}", a); let a = Some(1u8).map(|a| closure(a)); + //~^ redundant_closure } fn make_lazy(f: impl Fn() -> fn(u8) -> u8) -> impl Fn(u8) -> u8 { @@ -216,8 +231,11 @@ fn mutable_closure_used_again(x: Vec, y: Vec, z: Vec) { let mut res = Vec::new(); let mut add_to_res = |n| res.push(n); x.into_iter().for_each(|x| add_to_res(x)); + //~^ redundant_closure y.into_iter().for_each(|x| add_to_res(x)); + //~^ redundant_closure z.into_iter().for_each(|x| add_to_res(x)); + //~^ redundant_closure } fn mutable_closure_in_loop() { @@ -225,10 +243,12 @@ fn mutable_closure_in_loop() { let mut closure = |n| value += n; for _ in 0..5 { Some(1).map(|n| closure(n)); + //~^ redundant_closure let mut value = 0; let mut in_loop = |n| value += n; Some(1).map(|n| in_loop(n)); + //~^ redundant_closure } } @@ -322,13 +342,16 @@ fn not_general_enough() { pub fn mutable_impl_fn_mut(mut f: impl FnMut(), mut f_used_once: impl FnMut()) -> impl FnMut() { fn takes_fn_mut(_: impl FnMut()) {} takes_fn_mut(|| f()); + //~^ redundant_closure fn takes_fn_once(_: impl FnOnce()) {} takes_fn_once(|| f()); + //~^ redundant_closure f(); move || takes_fn_mut(|| f_used_once()) + //~^ redundant_closure } impl dyn TestTrait + '_ { @@ -341,16 +364,20 @@ impl dyn TestTrait + '_ { fn angle_brackets_and_args() { let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]); array_opt.map(|a| a.as_slice()); + //~^ redundant_closure_for_method_calls let slice_opt: Option<&[u8]> = Some(b"slice"); slice_opt.map(|s| s.len()); + //~^ redundant_closure_for_method_calls let ptr_opt: Option<*const usize> = Some(&487); ptr_opt.map(|p| p.is_null()); + //~^ redundant_closure_for_method_calls let test_struct = TestStruct { some_ref: &487 }; let dyn_opt: Option<&dyn TestTrait> = Some(&test_struct); dyn_opt.map(|d| d.method_on_dyn()); + //~^ redundant_closure_for_method_calls } // https://github.com/rust-lang/rust-clippy/issues/12199 @@ -411,6 +438,7 @@ fn _mixed_late_bound_and_early_bound_regions() { *y } let _ = f(&0, |x, y| f2(x, y)); + //~^ redundant_closure } fn _closure_with_types() { @@ -439,10 +467,12 @@ mod issue_10854 { pub fn calls_test(test: Option) -> Option { test.map(|t| t.method()) + //~^ redundant_closure_for_method_calls } pub fn calls_outer(test: Option) -> Option { test.map(|t| t.method()) + //~^ redundant_closure_for_method_calls } } @@ -456,6 +486,7 @@ mod issue_10854 { pub fn calls_into_mod(test: Option) -> Option { test.map(|t| t.method()) + //~^ redundant_closure_for_method_calls } mod a { @@ -463,6 +494,7 @@ mod issue_10854 { pub mod c { pub fn extreme_nesting(test: Option) -> Option { test.map(|t| t.method()) + //~^ redundant_closure_for_method_calls } } } @@ -482,10 +514,12 @@ mod issue_10854 { mod issue_12853 { fn f_by_value(f: F) { let x = Box::new(|| None.map(|x| f(x))); + //~^ redundant_closure x(); } fn f_by_ref(f: &F) { let x = Box::new(|| None.map(|x| f(x))); + //~^ redundant_closure x(); } } @@ -503,5 +537,6 @@ mod issue_13073 { let _field = bind.as_deref().or_else(|| get_default()).unwrap(); // should lint let _field = bind.or_else(|| get_default()).unwrap(); + //~^ redundant_closure } } diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index ac58e87bc5ec..434a034a4f8e 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -8,31 +8,31 @@ LL | let a = Some(1u8).map(|a| foo(a)); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]` error: redundant closure - --> tests/ui/eta.rs:35:40 + --> tests/ui/eta.rs:36:40 | LL | let _: Option> = true.then(|| vec![]); // special case vec! | ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new` error: redundant closure - --> tests/ui/eta.rs:36:35 + --> tests/ui/eta.rs:38:35 | LL | let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? | ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2` error: redundant closure - --> tests/ui/eta.rs:37:26 + --> tests/ui/eta.rs:40:26 | LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted | ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below` error: redundant closure - --> tests/ui/eta.rs:44:27 + --> tests/ui/eta.rs:48:27 | LL | let e = Some(1u8).map(|a| generic(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic` error: redundant closure - --> tests/ui/eta.rs:96:51 + --> tests/ui/eta.rs:101:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); | ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo` @@ -41,175 +41,175 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_for_method_calls)]` error: redundant closure - --> tests/ui/eta.rs:97:51 + --> tests/ui/eta.rs:103:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo()); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo` error: redundant closure - --> tests/ui/eta.rs:99:42 + --> tests/ui/eta.rs:106:42 | LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear()); | ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear` error: redundant closure - --> tests/ui/eta.rs:103:29 + --> tests/ui/eta.rs:111:29 | LL | let e = Some("str").map(|s| s.to_string()); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string` error: redundant closure - --> tests/ui/eta.rs:104:27 + --> tests/ui/eta.rs:113:27 | LL | let e = Some('a').map(|s| s.to_uppercase()); | ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase` error: redundant closure - --> tests/ui/eta.rs:106:65 + --> tests/ui/eta.rs:116:65 | LL | let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase` error: redundant closure - --> tests/ui/eta.rs:122:23 + --> tests/ui/eta.rs:133:23 | LL | let _ = x.map(|x| x.parse::()); | ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `str::parse::` error: redundant closure - --> tests/ui/eta.rs:174:22 + --> tests/ui/eta.rs:186:22 | LL | requires_fn_once(|| x()); | ^^^^^^ help: replace the closure with the function itself: `x` error: redundant closure - --> tests/ui/eta.rs:181:27 + --> tests/ui/eta.rs:194:27 | LL | let a = Some(1u8).map(|a| foo_ptr(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr` error: redundant closure - --> tests/ui/eta.rs:186:27 + --> tests/ui/eta.rs:200:27 | LL | let a = Some(1u8).map(|a| closure(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure` error: redundant closure - --> tests/ui/eta.rs:218:28 + --> tests/ui/eta.rs:233:28 | LL | x.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> tests/ui/eta.rs:219:28 + --> tests/ui/eta.rs:235:28 | LL | y.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> tests/ui/eta.rs:220:28 + --> tests/ui/eta.rs:237:28 | LL | z.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res` error: redundant closure - --> tests/ui/eta.rs:227:21 + --> tests/ui/eta.rs:245:21 | LL | Some(1).map(|n| closure(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure` error: redundant closure - --> tests/ui/eta.rs:231:21 + --> tests/ui/eta.rs:250:21 | LL | Some(1).map(|n| in_loop(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop` error: redundant closure - --> tests/ui/eta.rs:324:18 + --> tests/ui/eta.rs:344:18 | LL | takes_fn_mut(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> tests/ui/eta.rs:327:19 + --> tests/ui/eta.rs:348:19 | LL | takes_fn_once(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> tests/ui/eta.rs:331:26 + --> tests/ui/eta.rs:353:26 | LL | move || takes_fn_mut(|| f_used_once()) | ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once` error: redundant closure - --> tests/ui/eta.rs:343:19 + --> tests/ui/eta.rs:366:19 | LL | array_opt.map(|a| a.as_slice()); | ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice` error: redundant closure - --> tests/ui/eta.rs:346:19 + --> tests/ui/eta.rs:370:19 | LL | slice_opt.map(|s| s.len()); | ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len` error: redundant closure - --> tests/ui/eta.rs:349:17 + --> tests/ui/eta.rs:374:17 | LL | ptr_opt.map(|p| p.is_null()); | ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null` error: redundant closure - --> tests/ui/eta.rs:353:17 + --> tests/ui/eta.rs:379:17 | LL | dyn_opt.map(|d| d.method_on_dyn()); | ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `::method_on_dyn` error: redundant closure - --> tests/ui/eta.rs:413:19 + --> tests/ui/eta.rs:440:19 | LL | let _ = f(&0, |x, y| f2(x, y)); | ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2` error: redundant closure - --> tests/ui/eta.rs:441:22 + --> tests/ui/eta.rs:469:22 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Test::method` error: redundant closure - --> tests/ui/eta.rs:445:22 + --> tests/ui/eta.rs:474:22 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `super::Outer::method` error: redundant closure - --> tests/ui/eta.rs:458:18 + --> tests/ui/eta.rs:488:18 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `test_mod::Test::method` error: redundant closure - --> tests/ui/eta.rs:465:30 + --> tests/ui/eta.rs:496:30 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method` error: redundant closure - --> tests/ui/eta.rs:484:38 + --> tests/ui/eta.rs:516:38 | LL | let x = Box::new(|| None.map(|x| f(x))); | ^^^^^^^^ help: replace the closure with the function itself: `&f` error: redundant closure - --> tests/ui/eta.rs:488:38 + --> tests/ui/eta.rs:521:38 | LL | let x = Box::new(|| None.map(|x| f(x))); | ^^^^^^^^ help: replace the closure with the function itself: `f` error: redundant closure - --> tests/ui/eta.rs:505:35 + --> tests/ui/eta.rs:539:35 | LL | let _field = bind.or_else(|| get_default()).unwrap(); | ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default` diff --git a/tests/ui/eta_nostd.fixed b/tests/ui/eta_nostd.fixed index 23059c52b67f..134af34a826a 100644 --- a/tests/ui/eta_nostd.fixed +++ b/tests/ui/eta_nostd.fixed @@ -7,4 +7,5 @@ use alloc::vec::Vec; fn issue_13895() { let _: Option> = true.then(alloc::vec::Vec::new); + //~^ redundant_closure } diff --git a/tests/ui/eta_nostd.rs b/tests/ui/eta_nostd.rs index ae44ac348c64..8d0541bedb2e 100644 --- a/tests/ui/eta_nostd.rs +++ b/tests/ui/eta_nostd.rs @@ -7,4 +7,5 @@ use alloc::vec::Vec; fn issue_13895() { let _: Option> = true.then(|| vec![]); + //~^ redundant_closure } diff --git a/tests/ui/excessive_precision.fixed b/tests/ui/excessive_precision.fixed index 372f64f7d99e..99d09774d16d 100644 --- a/tests/ui/excessive_precision.fixed +++ b/tests/ui/excessive_precision.fixed @@ -18,16 +18,22 @@ fn main() { const GOOD64_DOT: f32 = 10_000_000_000_000_000.0; const BAD32_1: f32 = 0.123_456_79_f32; + //~^ excessive_precision const BAD32_2: f32 = 0.123_456_79; + //~^ excessive_precision const BAD32_3: f32 = 0.1; + //~^ excessive_precision const BAD32_EDGE: f32 = 1.000_001; + //~^ excessive_precision const BAD64_1: f64 = 0.123_456_789_012_345_67f64; const BAD64_2: f64 = 0.123_456_789_012_345_67; const BAD64_3: f64 = 0.1; + //~^ excessive_precision // Literal as param println!("{:?}", 8.888_888_888_888_89); + //~^ excessive_precision // // TODO add inferred type tests for f32 // Locals @@ -39,8 +45,11 @@ fn main() { let good64_inf = 0.123_456_789_012; let bad32: f32 = 1.123_456_8; + //~^ excessive_precision let bad32_suf: f32 = 1.123_456_8_f32; + //~^ excessive_precision let bad32_inf = 1.123_456_8_f32; + //~^ excessive_precision let bad64: f64 = 0.123_456_789_012_345_67; let bad64_suf: f64 = 0.123_456_789_012_345_67f64; @@ -51,14 +60,18 @@ fn main() { let good_vec64: Vec = vec![0.123_456_789]; let bad_vec32: Vec = vec![0.123_456_79]; + //~^ excessive_precision let bad_vec64: Vec = vec![0.123_456_789_123_456_78]; + //~^ excessive_precision // Exponential float notation let good_e32: f32 = 1e-10; let bad_e32: f32 = 1.123_456_8e-10; + //~^ excessive_precision let good_bige32: f32 = 1E-10; let bad_bige32: f32 = 1.123_456_8E-10; + //~^ excessive_precision // Inferred type let good_inferred: f32 = 1f32 * 1_000_000_000.; @@ -68,9 +81,11 @@ fn main() { // issue #7744 let _ = 2.225_073_858_507_201e-308_f64; + //~^ excessive_precision // issue #7745 let _ = 0_f64; + //~^ excessive_precision // issue #9910 const INF1: f32 = 1.0e+33f32; @@ -81,5 +96,6 @@ fn main() { // issue #12954 const _: f64 = 3.0; + //~^ excessive_precision const _: f64 = 3.0000000000000000; } diff --git a/tests/ui/excessive_precision.rs b/tests/ui/excessive_precision.rs index 1e40efbf2452..a542fb2e7e3c 100644 --- a/tests/ui/excessive_precision.rs +++ b/tests/ui/excessive_precision.rs @@ -18,16 +18,22 @@ fn main() { const GOOD64_DOT: f32 = 10_000_000_000_000_000.0; const BAD32_1: f32 = 0.123_456_789_f32; + //~^ excessive_precision const BAD32_2: f32 = 0.123_456_789; + //~^ excessive_precision const BAD32_3: f32 = 0.100_000_000_000_1; + //~^ excessive_precision const BAD32_EDGE: f32 = 1.000_000_9; + //~^ excessive_precision const BAD64_1: f64 = 0.123_456_789_012_345_67f64; const BAD64_2: f64 = 0.123_456_789_012_345_67; const BAD64_3: f64 = 0.100_000_000_000_000_000_1; + //~^ excessive_precision // Literal as param println!("{:?}", 8.888_888_888_888_888_888_888); + //~^ excessive_precision // // TODO add inferred type tests for f32 // Locals @@ -39,8 +45,11 @@ fn main() { let good64_inf = 0.123_456_789_012; let bad32: f32 = 1.123_456_789; + //~^ excessive_precision let bad32_suf: f32 = 1.123_456_789_f32; + //~^ excessive_precision let bad32_inf = 1.123_456_789_f32; + //~^ excessive_precision let bad64: f64 = 0.123_456_789_012_345_67; let bad64_suf: f64 = 0.123_456_789_012_345_67f64; @@ -51,14 +60,18 @@ fn main() { let good_vec64: Vec = vec![0.123_456_789]; let bad_vec32: Vec = vec![0.123_456_789]; + //~^ excessive_precision let bad_vec64: Vec = vec![0.123_456_789_123_456_789]; + //~^ excessive_precision // Exponential float notation let good_e32: f32 = 1e-10; let bad_e32: f32 = 1.123_456_788_888e-10; + //~^ excessive_precision let good_bige32: f32 = 1E-10; let bad_bige32: f32 = 1.123_456_788_888E-10; + //~^ excessive_precision // Inferred type let good_inferred: f32 = 1f32 * 1_000_000_000.; @@ -68,9 +81,11 @@ fn main() { // issue #7744 let _ = 2.225_073_858_507_201_1e-308_f64; + //~^ excessive_precision // issue #7745 let _ = 1.000_000_000_000_001e-324_f64; + //~^ excessive_precision // issue #9910 const INF1: f32 = 1.0e+33f32; @@ -81,5 +96,6 @@ fn main() { // issue #12954 const _: f64 = 3.0000000000000000e+00; + //~^ excessive_precision const _: f64 = 3.0000000000000000; } diff --git a/tests/ui/excessive_precision.stderr b/tests/ui/excessive_precision.stderr index 81e4fb6765d0..09fe3de4993a 100644 --- a/tests/ui/excessive_precision.stderr +++ b/tests/ui/excessive_precision.stderr @@ -12,7 +12,7 @@ LL | const BAD32_1: f32 = 0.123_456_79_f32; | ~~~~~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:21:26 + --> tests/ui/excessive_precision.rs:22:26 | LL | const BAD32_2: f32 = 0.123_456_789; | ^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | const BAD32_2: f32 = 0.123_456_79; | ~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:22:26 + --> tests/ui/excessive_precision.rs:24:26 | LL | const BAD32_3: f32 = 0.100_000_000_000_1; | ^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | const BAD32_3: f32 = 0.1; | ~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:23:29 + --> tests/ui/excessive_precision.rs:26:29 | LL | const BAD32_EDGE: f32 = 1.000_000_9; | ^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | const BAD32_EDGE: f32 = 1.000_001; | ~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:27:26 + --> tests/ui/excessive_precision.rs:31:26 | LL | const BAD64_3: f64 = 0.100_000_000_000_000_000_1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | const BAD64_3: f64 = 0.1; | ~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:30:22 + --> tests/ui/excessive_precision.rs:35:22 | LL | println!("{:?}", 8.888_888_888_888_888_888_888); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | println!("{:?}", 8.888_888_888_888_89); | ~~~~~~~~~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:41:22 + --> tests/ui/excessive_precision.rs:47:22 | LL | let bad32: f32 = 1.123_456_789; | ^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let bad32: f32 = 1.123_456_8; | ~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:42:26 + --> tests/ui/excessive_precision.rs:49:26 | LL | let bad32_suf: f32 = 1.123_456_789_f32; | ^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let bad32_suf: f32 = 1.123_456_8_f32; | ~~~~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:43:21 + --> tests/ui/excessive_precision.rs:51:21 | LL | let bad32_inf = 1.123_456_789_f32; | ^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let bad32_inf = 1.123_456_8_f32; | ~~~~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:53:36 + --> tests/ui/excessive_precision.rs:62:36 | LL | let bad_vec32: Vec = vec![0.123_456_789]; | ^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let bad_vec32: Vec = vec![0.123_456_79]; | ~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:54:36 + --> tests/ui/excessive_precision.rs:64:36 | LL | let bad_vec64: Vec = vec![0.123_456_789_123_456_789]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let bad_vec64: Vec = vec![0.123_456_789_123_456_78]; | ~~~~~~~~~~~~~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:58:24 + --> tests/ui/excessive_precision.rs:69:24 | LL | let bad_e32: f32 = 1.123_456_788_888e-10; | ^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let bad_e32: f32 = 1.123_456_8e-10; | ~~~~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:61:27 + --> tests/ui/excessive_precision.rs:73:27 | LL | let bad_bige32: f32 = 1.123_456_788_888E-10; | ^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | let bad_bige32: f32 = 1.123_456_8E-10; | ~~~~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:70:13 + --> tests/ui/excessive_precision.rs:83:13 | LL | let _ = 2.225_073_858_507_201_1e-308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | let _ = 2.225_073_858_507_201e-308_f64; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:73:13 + --> tests/ui/excessive_precision.rs:87:13 | LL | let _ = 1.000_000_000_000_001e-324_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | let _ = 0_f64; | ~~~~~ error: float has excessive precision - --> tests/ui/excessive_precision.rs:83:20 + --> tests/ui/excessive_precision.rs:98:20 | LL | const _: f64 = 3.0000000000000000e+00; | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/exhaustive_items.fixed b/tests/ui/exhaustive_items.fixed index 1bf33a5f2f13..a3c584c2a269 100644 --- a/tests/ui/exhaustive_items.fixed +++ b/tests/ui/exhaustive_items.fixed @@ -8,6 +8,7 @@ fn main() { pub mod enums { #[non_exhaustive] pub enum Exhaustive { + //~^ exhaustive_enums Foo, Bar, Baz, @@ -18,6 +19,7 @@ pub mod enums { #[repr(C)] #[non_exhaustive] pub enum ExhaustiveWithAttrs { + //~^ exhaustive_enums Foo, Bar, Baz, @@ -54,6 +56,7 @@ pub mod enums { pub mod structs { #[non_exhaustive] pub struct Exhaustive { + //~^ exhaustive_structs pub foo: u8, pub bar: String, } diff --git a/tests/ui/exhaustive_items.rs b/tests/ui/exhaustive_items.rs index 1328791e186d..b1f0c789b709 100644 --- a/tests/ui/exhaustive_items.rs +++ b/tests/ui/exhaustive_items.rs @@ -7,6 +7,7 @@ fn main() { pub mod enums { pub enum Exhaustive { + //~^ exhaustive_enums Foo, Bar, Baz, @@ -16,6 +17,7 @@ pub mod enums { /// Some docs #[repr(C)] pub enum ExhaustiveWithAttrs { + //~^ exhaustive_enums Foo, Bar, Baz, @@ -51,6 +53,7 @@ pub mod enums { pub mod structs { pub struct Exhaustive { + //~^ exhaustive_structs pub foo: u8, pub bar: String, } diff --git a/tests/ui/exhaustive_items.stderr b/tests/ui/exhaustive_items.stderr index 536fbe8d790f..c92c8a9efaae 100644 --- a/tests/ui/exhaustive_items.stderr +++ b/tests/ui/exhaustive_items.stderr @@ -2,6 +2,7 @@ error: exported enums should not be exhaustive --> tests/ui/exhaustive_items.rs:9:5 | LL | / pub enum Exhaustive { +LL | | LL | | Foo, LL | | Bar, LL | | Baz, @@ -21,9 +22,10 @@ LL ~ pub enum Exhaustive { | error: exported enums should not be exhaustive - --> tests/ui/exhaustive_items.rs:18:5 + --> tests/ui/exhaustive_items.rs:19:5 | LL | / pub enum ExhaustiveWithAttrs { +LL | | LL | | Foo, LL | | Bar, LL | | Baz, @@ -38,9 +40,10 @@ LL ~ pub enum ExhaustiveWithAttrs { | error: exported structs should not be exhaustive - --> tests/ui/exhaustive_items.rs:53:5 + --> tests/ui/exhaustive_items.rs:55:5 | LL | / pub struct Exhaustive { +LL | | LL | | pub foo: u8, LL | | pub bar: String, LL | | } diff --git a/tests/ui/exit1.rs b/tests/ui/exit1.rs index 36b3c42fd995..127c72aac99f 100644 --- a/tests/ui/exit1.rs +++ b/tests/ui/exit1.rs @@ -3,8 +3,9 @@ fn not_main() { if true { std::process::exit(4); - //~^ ERROR: usage of `process::exit` - //~| NOTE: `-D clippy::exit` implied by `-D warnings` + //~^ exit + + } } diff --git a/tests/ui/exit2.rs b/tests/ui/exit2.rs index 9bbb7b073a4b..2e2c4828afe6 100644 --- a/tests/ui/exit2.rs +++ b/tests/ui/exit2.rs @@ -2,8 +2,9 @@ fn also_not_main() { std::process::exit(3); - //~^ ERROR: usage of `process::exit` - //~| NOTE: `-D clippy::exit` implied by `-D warnings` + //~^ exit + + } fn main() { diff --git a/tests/ui/exit3.rs b/tests/ui/exit3.rs index cab908aafd33..a8af1b225788 100644 --- a/tests/ui/exit3.rs +++ b/tests/ui/exit3.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::exit)] fn main() { diff --git a/tests/ui/expect.rs b/tests/ui/expect.rs index f15b3d37e154..575c29e6f31c 100644 --- a/tests/ui/expect.rs +++ b/tests/ui/expect.rs @@ -4,15 +4,18 @@ fn expect_option() { let opt = Some(0); let _ = opt.expect(""); - //~^ ERROR: used `expect()` on an `Option` value + //~^ expect_used + } fn expect_result() { let res: Result = Ok(0); let _ = res.expect(""); - //~^ ERROR: used `expect()` on a `Result` value + //~^ expect_used + let _ = res.expect_err(""); - //~^ ERROR: used `expect_err()` on a `Result` value + //~^ expect_used + } fn main() { diff --git a/tests/ui/expect.stderr b/tests/ui/expect.stderr index c0ba3390aac5..b44429a3b71d 100644 --- a/tests/ui/expect.stderr +++ b/tests/ui/expect.stderr @@ -9,7 +9,7 @@ LL | let _ = opt.expect(""); = help: to override `-D warnings` add `#[allow(clippy::expect_used)]` error: used `expect()` on a `Result` value - --> tests/ui/expect.rs:12:13 + --> tests/ui/expect.rs:13:13 | LL | let _ = res.expect(""); | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = res.expect(""); = note: if this value is an `Err`, it will panic error: used `expect_err()` on a `Result` value - --> tests/ui/expect.rs:14:13 + --> tests/ui/expect.rs:16:13 | LL | let _ = res.expect_err(""); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/expect_fun_call.fixed b/tests/ui/expect_fun_call.fixed index 8f800c71941a..73eaebf773c8 100644 --- a/tests/ui/expect_fun_call.fixed +++ b/tests/ui/expect_fun_call.fixed @@ -33,12 +33,15 @@ fn main() { let error_code = 123_i32; let with_none_and_format: Option = None; with_none_and_format.unwrap_or_else(|| panic!("Error {}: fake error", error_code)); + //~^ expect_fun_call let with_none_and_as_str: Option = None; with_none_and_as_str.unwrap_or_else(|| panic!("Error {}: fake error", error_code)); + //~^ expect_fun_call let with_none_and_format_with_macro: Option = None; with_none_and_format_with_macro.unwrap_or_else(|| panic!("Error {}: fake error", one!())); + //~^ expect_fun_call let with_ok: Result<(), ()> = Ok(()); with_ok.expect("error"); @@ -49,9 +52,11 @@ fn main() { let error_code = 123_i32; let with_err_and_format: Result<(), ()> = Err(()); with_err_and_format.unwrap_or_else(|_| panic!("Error {}: fake error", error_code)); + //~^ expect_fun_call let with_err_and_as_str: Result<(), ()> = Err(()); with_err_and_as_str.unwrap_or_else(|_| panic!("Error {}: fake error", error_code)); + //~^ expect_fun_call let with_dummy_type = Foo::new(); with_dummy_type.expect("another test string"); @@ -64,6 +69,7 @@ fn main() { //Issue #2937 Some("foo").unwrap_or_else(|| panic!("{} {}", 1, 2)); + //~^ expect_fun_call //Issue #2979 - this should not lint { @@ -85,26 +91,35 @@ fn main() { } Some("foo").unwrap_or_else(|| { panic!("{}", get_string()) }); + //~^ expect_fun_call Some("foo").unwrap_or_else(|| { panic!("{}", get_string()) }); + //~^ expect_fun_call Some("foo").unwrap_or_else(|| { panic!("{}", get_string()) }); + //~^ expect_fun_call Some("foo").unwrap_or_else(|| { panic!("{}", get_static_str()) }); + //~^ expect_fun_call Some("foo").unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) }); + //~^ expect_fun_call } //Issue #3839 Some(true).unwrap_or_else(|| panic!("key {}, {}", 1, 2)); + //~^ expect_fun_call //Issue #4912 - the receiver is a &Option { let opt = Some(1); let opt_ref = &opt; opt_ref.unwrap_or_else(|| panic!("{:?}", opt_ref)); + //~^ expect_fun_call } let format_capture: Option = None; format_capture.unwrap_or_else(|| panic!("{error_code}")); + //~^ expect_fun_call let format_capture_and_value: Option = None; format_capture_and_value.unwrap_or_else(|| panic!("{error_code}, {}", 1)); + //~^ expect_fun_call } diff --git a/tests/ui/expect_fun_call.rs b/tests/ui/expect_fun_call.rs index b5cfafb2993e..ecebc9ebfb6f 100644 --- a/tests/ui/expect_fun_call.rs +++ b/tests/ui/expect_fun_call.rs @@ -33,12 +33,15 @@ fn main() { let error_code = 123_i32; let with_none_and_format: Option = None; with_none_and_format.expect(&format!("Error {}: fake error", error_code)); + //~^ expect_fun_call let with_none_and_as_str: Option = None; with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); + //~^ expect_fun_call let with_none_and_format_with_macro: Option = None; with_none_and_format_with_macro.expect(format!("Error {}: fake error", one!()).as_str()); + //~^ expect_fun_call let with_ok: Result<(), ()> = Ok(()); with_ok.expect("error"); @@ -49,9 +52,11 @@ fn main() { let error_code = 123_i32; let with_err_and_format: Result<(), ()> = Err(()); with_err_and_format.expect(&format!("Error {}: fake error", error_code)); + //~^ expect_fun_call let with_err_and_as_str: Result<(), ()> = Err(()); with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); + //~^ expect_fun_call let with_dummy_type = Foo::new(); with_dummy_type.expect("another test string"); @@ -64,6 +69,7 @@ fn main() { //Issue #2937 Some("foo").expect(format!("{} {}", 1, 2).as_ref()); + //~^ expect_fun_call //Issue #2979 - this should not lint { @@ -85,26 +91,35 @@ fn main() { } Some("foo").expect(&get_string()); + //~^ expect_fun_call Some("foo").expect(get_string().as_ref()); + //~^ expect_fun_call Some("foo").expect(get_string().as_str()); + //~^ expect_fun_call Some("foo").expect(get_static_str()); + //~^ expect_fun_call Some("foo").expect(get_non_static_str(&0)); + //~^ expect_fun_call } //Issue #3839 Some(true).expect(&format!("key {}, {}", 1, 2)); + //~^ expect_fun_call //Issue #4912 - the receiver is a &Option { let opt = Some(1); let opt_ref = &opt; opt_ref.expect(&format!("{:?}", opt_ref)); + //~^ expect_fun_call } let format_capture: Option = None; format_capture.expect(&format!("{error_code}")); + //~^ expect_fun_call let format_capture_and_value: Option = None; format_capture_and_value.expect(&format!("{error_code}, {}", 1)); + //~^ expect_fun_call } diff --git a/tests/ui/expect_fun_call.stderr b/tests/ui/expect_fun_call.stderr index 050c039f834d..36713196cb92 100644 --- a/tests/ui/expect_fun_call.stderr +++ b/tests/ui/expect_fun_call.stderr @@ -8,85 +8,85 @@ LL | with_none_and_format.expect(&format!("Error {}: fake error", error_code = help: to override `-D warnings` add `#[allow(clippy::expect_fun_call)]` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:38:26 + --> tests/ui/expect_fun_call.rs:39:26 | LL | with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:41:37 + --> tests/ui/expect_fun_call.rs:43:37 | LL | with_none_and_format_with_macro.expect(format!("Error {}: fake error", one!()).as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", one!()))` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:51:25 + --> tests/ui/expect_fun_call.rs:54:25 | LL | with_err_and_format.expect(&format!("Error {}: fake error", error_code)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:54:25 + --> tests/ui/expect_fun_call.rs:58:25 | LL | with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:66:17 + --> tests/ui/expect_fun_call.rs:71:17 | LL | Some("foo").expect(format!("{} {}", 1, 2).as_ref()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{} {}", 1, 2))` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:87:21 + --> tests/ui/expect_fun_call.rs:93:21 | LL | Some("foo").expect(&get_string()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:88:21 + --> tests/ui/expect_fun_call.rs:95:21 | LL | Some("foo").expect(get_string().as_ref()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:89:21 + --> tests/ui/expect_fun_call.rs:97:21 | LL | Some("foo").expect(get_string().as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:91:21 + --> tests/ui/expect_fun_call.rs:100:21 | LL | Some("foo").expect(get_static_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_static_str()) })` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:92:21 + --> tests/ui/expect_fun_call.rs:102:21 | LL | Some("foo").expect(get_non_static_str(&0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) })` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:96:16 + --> tests/ui/expect_fun_call.rs:107:16 | LL | Some(true).expect(&format!("key {}, {}", 1, 2)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:102:17 + --> tests/ui/expect_fun_call.rs:114:17 | LL | opt_ref.expect(&format!("{:?}", opt_ref)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{:?}", opt_ref))` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:106:20 + --> tests/ui/expect_fun_call.rs:119:20 | LL | format_capture.expect(&format!("{error_code}")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}"))` error: function call inside of `expect` - --> tests/ui/expect_fun_call.rs:109:30 + --> tests/ui/expect_fun_call.rs:123:30 | LL | format_capture_and_value.expect(&format!("{error_code}, {}", 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}, {}", 1))` diff --git a/tests/ui/explicit_auto_deref.fixed b/tests/ui/explicit_auto_deref.fixed index 9d476259b87e..c7edf33012e0 100644 --- a/tests/ui/explicit_auto_deref.fixed +++ b/tests/ui/explicit_auto_deref.fixed @@ -67,43 +67,54 @@ fn main() { let s = String::new(); let _: &str = &s; + //~^ explicit_auto_deref let _: &str = &{ String::new() }; + //~^ explicit_auto_deref let _: &str = &mut { String::new() }; + //~^ explicit_auto_deref let _ = &*s; // Don't lint. Inferred type would change. let _: &_ = &*s; // Don't lint. Inferred type would change. f_str(&s); + //~^ explicit_auto_deref f_t(&*s); // Don't lint. Inferred type would change. f_ref_t(&*s); // Don't lint. Inferred type would change. f_str_t(&s, &*s); // Don't lint second param. + //~^ explicit_auto_deref let b = Box::new(Box::new(Box::new(5))); let _: &Box = &b; + //~^ explicit_auto_deref let _: &Box<_> = &**b; // Don't lint. Inferred type would change. f_box_t(&**b); // Don't lint. Inferred type would change. let c = |_x: &str| (); c(&s); + //~^ explicit_auto_deref let c = |_x| (); c(&*s); // Don't lint. Inferred type would change. fn _f(x: &String) -> &str { x + //~^ explicit_auto_deref } fn _f1(x: &String) -> &str { { x } + //~^ explicit_auto_deref } fn _f2(x: &String) -> &str { { x } + //~^ explicit_auto_deref } fn _f3(x: &Box>>) -> &Box { x + //~^ explicit_auto_deref } fn _f4( @@ -121,25 +132,38 @@ fn main() { f11: &dyn CallableT, ) { f1(&x); + //~^ explicit_auto_deref f2(&x); + //~^ explicit_auto_deref f3(&x); + //~^ explicit_auto_deref f4.callable_str()(&x); + //~^ explicit_auto_deref f5(&x); + //~^ explicit_auto_deref f6(&x); + //~^ explicit_auto_deref f7.callable_str()(&x); + //~^ explicit_auto_deref f8.callable_t()(&x); + //~^ explicit_auto_deref f9(&x); + //~^ explicit_auto_deref f10(&x); + //~^ explicit_auto_deref f11.callable_t()(&x); + //~^ explicit_auto_deref } struct S1<'a>(&'a str); let _ = S1(&s); + //~^ explicit_auto_deref struct S2<'a> { s: &'a str, } let _ = S2 { s: &s }; + //~^ explicit_auto_deref struct S3<'a, T: ?Sized>(&'a T); let _ = S3(&*s); // Don't lint. Inferred type would change. @@ -156,11 +180,15 @@ fn main() { impl<'a> E1<'a> { fn m1(s: &'a String) { let _ = Self::S1(s); + //~^ explicit_auto_deref let _ = Self::S2 { s: s }; + //~^ explicit_auto_deref } } let _ = E1::S1(&s); + //~^ explicit_auto_deref let _ = E1::S2 { s: &s }; + //~^ explicit_auto_deref enum E2<'a, T: ?Sized> { S1(&'a T), @@ -179,7 +207,9 @@ fn main() { let b = Box::new(Box::new(S5 { foo: 5 })); let _ = b.foo; let _ = b.foo; + //~^ explicit_auto_deref let _ = b.foo; + //~^ explicit_auto_deref struct S6 { foo: S5, @@ -195,8 +225,10 @@ fn main() { let ref_str = &"foo"; let _ = f_str(ref_str); + //~^ explicit_auto_deref let ref_ref_str = &ref_str; let _ = f_str(ref_ref_str); + //~^ explicit_auto_deref fn _f5(x: &u32) -> u32 { if true { @@ -207,7 +239,9 @@ fn main() { } f_str(&ref_str); // `needless_borrow` will suggest removing both references + //~^ explicit_auto_deref f_str(&ref_str); // `needless_borrow` will suggest removing only one reference + //~^ explicit_auto_deref let x = &&40; unsafe { @@ -217,6 +251,7 @@ fn main() { let s = &"str"; let _ = || return *s; let _ = || -> &'static str { return s }; + //~^ explicit_auto_deref struct X; struct Y(X); @@ -236,6 +271,7 @@ fn main() { fn deref_to_u>(x: &T) -> &U { x + //~^ explicit_auto_deref } let _ = |x: &'static Box>| -> &'static dyn Iterator { &**x }; @@ -259,11 +295,14 @@ fn main() { let c1 = |_: &Vec<&u32>| {}; let x = &&vec![&1u32]; c1(x); + //~^ explicit_auto_deref let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> { if b { return x; + //~^ explicit_auto_deref } x + //~^ explicit_auto_deref }; trait WithAssoc { @@ -298,6 +337,7 @@ fn main() { // Issue #11366 let _: &mut u32 = match &mut Some(&mut 0u32) { Some(x) => x, + //~^ explicit_auto_deref None => panic!(), }; @@ -331,18 +371,23 @@ fn main() { }; let _ = &mut (*x.u).x; let _ = &mut { x.u }.x; + //~^ explicit_auto_deref let _ = &mut ({ *x.u }).x; let mut x = U { u: Wrap(core::mem::ManuallyDrop::new(S8 { x: "" })), }; let _ = &mut (*x.u).x; + //~^ explicit_auto_deref let _ = &mut { x.u }.x; + //~^ explicit_auto_deref let _ = &mut ({ **x.u }).x; let mut x = U { u: Wrap(S8 { x: "" }) }; let _ = &mut x.u.x; + //~^ explicit_auto_deref let _ = &mut { x.u }.x; + //~^ explicit_auto_deref let _ = &mut ({ *x.u }).x; } } @@ -366,6 +411,7 @@ mod issue_12969 { let wrapped_bar = Wrapper(""); foo(&wrapped_bar); + //~^ explicit_auto_deref } } diff --git a/tests/ui/explicit_auto_deref.rs b/tests/ui/explicit_auto_deref.rs index 23307c837f0e..4d2b2fc3fc39 100644 --- a/tests/ui/explicit_auto_deref.rs +++ b/tests/ui/explicit_auto_deref.rs @@ -67,43 +67,54 @@ fn main() { let s = String::new(); let _: &str = &*s; + //~^ explicit_auto_deref let _: &str = &*{ String::new() }; + //~^ explicit_auto_deref let _: &str = &mut *{ String::new() }; + //~^ explicit_auto_deref let _ = &*s; // Don't lint. Inferred type would change. let _: &_ = &*s; // Don't lint. Inferred type would change. f_str(&*s); + //~^ explicit_auto_deref f_t(&*s); // Don't lint. Inferred type would change. f_ref_t(&*s); // Don't lint. Inferred type would change. f_str_t(&*s, &*s); // Don't lint second param. + //~^ explicit_auto_deref let b = Box::new(Box::new(Box::new(5))); let _: &Box = &**b; + //~^ explicit_auto_deref let _: &Box<_> = &**b; // Don't lint. Inferred type would change. f_box_t(&**b); // Don't lint. Inferred type would change. let c = |_x: &str| (); c(&*s); + //~^ explicit_auto_deref let c = |_x| (); c(&*s); // Don't lint. Inferred type would change. fn _f(x: &String) -> &str { &**x + //~^ explicit_auto_deref } fn _f1(x: &String) -> &str { { &**x } + //~^ explicit_auto_deref } fn _f2(x: &String) -> &str { &**{ x } + //~^ explicit_auto_deref } fn _f3(x: &Box>>) -> &Box { &***x + //~^ explicit_auto_deref } fn _f4( @@ -121,25 +132,38 @@ fn main() { f11: &dyn CallableT, ) { f1(&*x); + //~^ explicit_auto_deref f2(&*x); + //~^ explicit_auto_deref f3(&*x); + //~^ explicit_auto_deref f4.callable_str()(&*x); + //~^ explicit_auto_deref f5(&*x); + //~^ explicit_auto_deref f6(&*x); + //~^ explicit_auto_deref f7.callable_str()(&*x); + //~^ explicit_auto_deref f8.callable_t()(&*x); + //~^ explicit_auto_deref f9(&*x); + //~^ explicit_auto_deref f10(&*x); + //~^ explicit_auto_deref f11.callable_t()(&*x); + //~^ explicit_auto_deref } struct S1<'a>(&'a str); let _ = S1(&*s); + //~^ explicit_auto_deref struct S2<'a> { s: &'a str, } let _ = S2 { s: &*s }; + //~^ explicit_auto_deref struct S3<'a, T: ?Sized>(&'a T); let _ = S3(&*s); // Don't lint. Inferred type would change. @@ -156,11 +180,15 @@ fn main() { impl<'a> E1<'a> { fn m1(s: &'a String) { let _ = Self::S1(&**s); + //~^ explicit_auto_deref let _ = Self::S2 { s: &**s }; + //~^ explicit_auto_deref } } let _ = E1::S1(&*s); + //~^ explicit_auto_deref let _ = E1::S2 { s: &*s }; + //~^ explicit_auto_deref enum E2<'a, T: ?Sized> { S1(&'a T), @@ -179,7 +207,9 @@ fn main() { let b = Box::new(Box::new(S5 { foo: 5 })); let _ = b.foo; let _ = (*b).foo; + //~^ explicit_auto_deref let _ = (**b).foo; + //~^ explicit_auto_deref struct S6 { foo: S5, @@ -195,8 +225,10 @@ fn main() { let ref_str = &"foo"; let _ = f_str(*ref_str); + //~^ explicit_auto_deref let ref_ref_str = &ref_str; let _ = f_str(**ref_ref_str); + //~^ explicit_auto_deref fn _f5(x: &u32) -> u32 { if true { @@ -207,7 +239,9 @@ fn main() { } f_str(&&*ref_str); // `needless_borrow` will suggest removing both references + //~^ explicit_auto_deref f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference + //~^ explicit_auto_deref let x = &&40; unsafe { @@ -217,6 +251,7 @@ fn main() { let s = &"str"; let _ = || return *s; let _ = || -> &'static str { return *s }; + //~^ explicit_auto_deref struct X; struct Y(X); @@ -236,6 +271,7 @@ fn main() { fn deref_to_u>(x: &T) -> &U { &**x + //~^ explicit_auto_deref } let _ = |x: &'static Box>| -> &'static dyn Iterator { &**x }; @@ -259,11 +295,14 @@ fn main() { let c1 = |_: &Vec<&u32>| {}; let x = &&vec![&1u32]; c1(*x); + //~^ explicit_auto_deref let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> { if b { return *x; + //~^ explicit_auto_deref } *x + //~^ explicit_auto_deref }; trait WithAssoc { @@ -298,6 +337,7 @@ fn main() { // Issue #11366 let _: &mut u32 = match &mut Some(&mut 0u32) { Some(x) => &mut *x, + //~^ explicit_auto_deref None => panic!(), }; @@ -331,18 +371,23 @@ fn main() { }; let _ = &mut (*x.u).x; let _ = &mut (*{ x.u }).x; + //~^ explicit_auto_deref let _ = &mut ({ *x.u }).x; let mut x = U { u: Wrap(core::mem::ManuallyDrop::new(S8 { x: "" })), }; let _ = &mut (**x.u).x; + //~^ explicit_auto_deref let _ = &mut (**{ x.u }).x; + //~^ explicit_auto_deref let _ = &mut ({ **x.u }).x; let mut x = U { u: Wrap(S8 { x: "" }) }; let _ = &mut (*x.u).x; + //~^ explicit_auto_deref let _ = &mut (*{ x.u }).x; + //~^ explicit_auto_deref let _ = &mut ({ *x.u }).x; } } @@ -366,6 +411,7 @@ mod issue_12969 { let wrapped_bar = Wrapper(""); foo(&*wrapped_bar); + //~^ explicit_auto_deref } } diff --git a/tests/ui/explicit_auto_deref.stderr b/tests/ui/explicit_auto_deref.stderr index 0b05a554eb11..e1cfb214864f 100644 --- a/tests/ui/explicit_auto_deref.stderr +++ b/tests/ui/explicit_auto_deref.stderr @@ -8,271 +8,271 @@ LL | let _: &str = &*s; = help: to override `-D warnings` add `#[allow(clippy::explicit_auto_deref)]` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:70:19 + --> tests/ui/explicit_auto_deref.rs:71:19 | LL | let _: &str = &*{ String::new() }; | ^^^^^^^^^^^^^^^^^^^ help: try: `&{ String::new() }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:71:19 + --> tests/ui/explicit_auto_deref.rs:73:19 | LL | let _: &str = &mut *{ String::new() }; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut { String::new() }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:75:11 + --> tests/ui/explicit_auto_deref.rs:78:11 | LL | f_str(&*s); | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:79:13 + --> tests/ui/explicit_auto_deref.rs:83:13 | LL | f_str_t(&*s, &*s); // Don't lint second param. | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:82:24 + --> tests/ui/explicit_auto_deref.rs:87:24 | LL | let _: &Box = &**b; | ^^^^ help: try: `&b` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:88:7 + --> tests/ui/explicit_auto_deref.rs:94:7 | LL | c(&*s); | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:94:9 + --> tests/ui/explicit_auto_deref.rs:101:9 | LL | &**x | ^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:98:11 + --> tests/ui/explicit_auto_deref.rs:106:11 | LL | { &**x } | ^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:102:9 + --> tests/ui/explicit_auto_deref.rs:111:9 | LL | &**{ x } | ^^^^^^^^ help: try: `{ x }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:106:9 + --> tests/ui/explicit_auto_deref.rs:116:9 | LL | &***x | ^^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:123:12 + --> tests/ui/explicit_auto_deref.rs:134:12 | LL | f1(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:124:12 + --> tests/ui/explicit_auto_deref.rs:136:12 | LL | f2(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:125:12 + --> tests/ui/explicit_auto_deref.rs:138:12 | LL | f3(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:126:27 + --> tests/ui/explicit_auto_deref.rs:140:27 | LL | f4.callable_str()(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:127:12 + --> tests/ui/explicit_auto_deref.rs:142:12 | LL | f5(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:128:12 + --> tests/ui/explicit_auto_deref.rs:144:12 | LL | f6(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:129:27 + --> tests/ui/explicit_auto_deref.rs:146:27 | LL | f7.callable_str()(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:130:25 + --> tests/ui/explicit_auto_deref.rs:148:25 | LL | f8.callable_t()(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:131:12 + --> tests/ui/explicit_auto_deref.rs:150:12 | LL | f9(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:132:13 + --> tests/ui/explicit_auto_deref.rs:152:13 | LL | f10(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:133:26 + --> tests/ui/explicit_auto_deref.rs:154:26 | LL | f11.callable_t()(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:137:16 + --> tests/ui/explicit_auto_deref.rs:159:16 | LL | let _ = S1(&*s); | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:142:21 + --> tests/ui/explicit_auto_deref.rs:165:21 | LL | let _ = S2 { s: &*s }; | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:158:30 + --> tests/ui/explicit_auto_deref.rs:182:30 | LL | let _ = Self::S1(&**s); | ^^^^ help: try: `s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:159:35 + --> tests/ui/explicit_auto_deref.rs:184:35 | LL | let _ = Self::S2 { s: &**s }; | ^^^^ help: try: `s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:162:20 + --> tests/ui/explicit_auto_deref.rs:188:20 | LL | let _ = E1::S1(&*s); | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:163:25 + --> tests/ui/explicit_auto_deref.rs:190:25 | LL | let _ = E1::S2 { s: &*s }; | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:181:13 + --> tests/ui/explicit_auto_deref.rs:209:13 | LL | let _ = (*b).foo; | ^^^^ help: try: `b` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:182:13 + --> tests/ui/explicit_auto_deref.rs:211:13 | LL | let _ = (**b).foo; | ^^^^^ help: try: `b` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:197:19 + --> tests/ui/explicit_auto_deref.rs:227:19 | LL | let _ = f_str(*ref_str); | ^^^^^^^^ help: try: `ref_str` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:199:19 + --> tests/ui/explicit_auto_deref.rs:230:19 | LL | let _ = f_str(**ref_ref_str); | ^^^^^^^^^^^^^ help: try: `ref_ref_str` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:209:12 + --> tests/ui/explicit_auto_deref.rs:241:12 | LL | f_str(&&*ref_str); // `needless_borrow` will suggest removing both references | ^^^^^^^^^ help: try: `ref_str` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:210:12 + --> tests/ui/explicit_auto_deref.rs:243:12 | LL | f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference | ^^^^^^^^^^ help: try: `ref_str` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:219:41 + --> tests/ui/explicit_auto_deref.rs:253:41 | LL | let _ = || -> &'static str { return *s }; | ^^ help: try: `s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:238:9 + --> tests/ui/explicit_auto_deref.rs:273:9 | LL | &**x | ^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:261:8 + --> tests/ui/explicit_auto_deref.rs:297:8 | LL | c1(*x); | ^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:264:20 + --> tests/ui/explicit_auto_deref.rs:301:20 | LL | return *x; | ^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:266:9 + --> tests/ui/explicit_auto_deref.rs:304:9 | LL | *x | ^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:300:20 + --> tests/ui/explicit_auto_deref.rs:339:20 | LL | Some(x) => &mut *x, | ^^^^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:333:22 + --> tests/ui/explicit_auto_deref.rs:373:22 | LL | let _ = &mut (*{ x.u }).x; | ^^^^^^^^^^ help: try: `{ x.u }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:339:22 + --> tests/ui/explicit_auto_deref.rs:380:22 | LL | let _ = &mut (**x.u).x; | ^^^^^^^ help: try: `(*x.u)` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:340:22 + --> tests/ui/explicit_auto_deref.rs:382:22 | LL | let _ = &mut (**{ x.u }).x; | ^^^^^^^^^^^ help: try: `{ x.u }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:344:22 + --> tests/ui/explicit_auto_deref.rs:387:22 | LL | let _ = &mut (*x.u).x; | ^^^^^^ help: try: `x.u` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:345:22 + --> tests/ui/explicit_auto_deref.rs:389:22 | LL | let _ = &mut (*{ x.u }).x; | ^^^^^^^^^^ help: try: `{ x.u }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:368:13 + --> tests/ui/explicit_auto_deref.rs:413:13 | LL | foo(&*wrapped_bar); | ^^^^^^^^^^^^^ help: try: `&wrapped_bar` diff --git a/tests/ui/explicit_counter_loop.rs b/tests/ui/explicit_counter_loop.rs index 28b477b69215..585e261c2f43 100644 --- a/tests/ui/explicit_counter_loop.rs +++ b/tests/ui/explicit_counter_loop.rs @@ -5,27 +5,31 @@ fn main() { let mut vec = vec![1, 2, 3, 4]; let mut _index = 0; for _v in &vec { - //~^ ERROR: the variable `_index` is used as a loop counter - //~| NOTE: `-D clippy::explicit-counter-loop` implied by `-D warnings` + //~^ explicit_counter_loop + + _index += 1 } let mut _index = 1; _index = 0; for _v in &vec { - //~^ ERROR: the variable `_index` is used as a loop counter + //~^ explicit_counter_loop + _index += 1 } let mut _index = 0; for _v in &mut vec { - //~^ ERROR: the variable `_index` is used as a loop counter + //~^ explicit_counter_loop + _index += 1; } let mut _index = 0; for _v in vec { - //~^ ERROR: the variable `_index` is used as a loop counter + //~^ explicit_counter_loop + _index += 1; } @@ -113,7 +117,8 @@ mod issue_1219 { let text = "banana"; let mut count = 0; for ch in text.chars() { - //~^ ERROR: the variable `count` is used as a loop counter + //~^ explicit_counter_loop + println!("{}", count); count += 1; if ch == 'a' { @@ -125,7 +130,8 @@ mod issue_1219 { let text = "banana"; let mut count = 0; for ch in text.chars() { - //~^ ERROR: the variable `count` is used as a loop counter + //~^ explicit_counter_loop + println!("{}", count); count += 1; for i in 0..2 { @@ -184,7 +190,8 @@ mod issue_1670 { pub fn test() { let mut count = 0; for _i in 3..10 { - //~^ ERROR: the variable `count` is used as a loop counter + //~^ explicit_counter_loop + count += 1; } } @@ -225,7 +232,8 @@ mod issue_7920 { // should suggest `enumerate` for _item in slice { - //~^ ERROR: the variable `idx_usize` is used as a loop counter + //~^ explicit_counter_loop + if idx_usize == index_usize { break; } @@ -238,8 +246,9 @@ mod issue_7920 { // should suggest `zip` for _item in slice { - //~^ ERROR: the variable `idx_u32` is used as a loop counter - //~| NOTE: `idx_u32` is of type `u32`, making it ineligible for `Iterator::enumera + //~^ explicit_counter_loop + + if idx_u32 == index_u32 { break; } @@ -284,6 +293,7 @@ mod issue_13123 { let mut vec = vec![1, 2, 3, 4]; let mut _index = 0; 'label: for v in vec { + //~^ explicit_counter_loop _index += 1; if v == 1 { break 'label; diff --git a/tests/ui/explicit_counter_loop.stderr b/tests/ui/explicit_counter_loop.stderr index 1b2d1f8570a3..c565bd4cf356 100644 --- a/tests/ui/explicit_counter_loop.stderr +++ b/tests/ui/explicit_counter_loop.stderr @@ -8,49 +8,49 @@ LL | for _v in &vec { = help: to override `-D warnings` add `#[allow(clippy::explicit_counter_loop)]` error: the variable `_index` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:15:5 + --> tests/ui/explicit_counter_loop.rs:16:5 | LL | for _v in &vec { | ^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter().enumerate()` error: the variable `_index` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:21:5 + --> tests/ui/explicit_counter_loop.rs:23:5 | LL | for _v in &mut vec { | ^^^^^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter_mut().enumerate()` error: the variable `_index` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:27:5 + --> tests/ui/explicit_counter_loop.rs:30:5 | LL | for _v in vec { | ^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.into_iter().enumerate()` error: the variable `count` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:115:9 + --> tests/ui/explicit_counter_loop.rs:119:9 | LL | for ch in text.chars() { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()` error: the variable `count` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:127:9 + --> tests/ui/explicit_counter_loop.rs:132:9 | LL | for ch in text.chars() { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()` error: the variable `count` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:186:9 + --> tests/ui/explicit_counter_loop.rs:192:9 | LL | for _i in 3..10 { | ^^^^^^^^^^^^^^^ help: consider using: `for (count, _i) in (3..10).enumerate()` error: the variable `idx_usize` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:227:9 + --> tests/ui/explicit_counter_loop.rs:234:9 | LL | for _item in slice { | ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_usize, _item) in slice.iter().enumerate()` error: the variable `idx_u32` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:240:9 + --> tests/ui/explicit_counter_loop.rs:248:9 | LL | for _item in slice { | ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_u32, _item) in (0_u32..).zip(slice.iter())` @@ -58,7 +58,7 @@ LL | for _item in slice { = note: `idx_u32` is of type `u32`, making it ineligible for `Iterator::enumerate` error: the variable `_index` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:286:9 + --> tests/ui/explicit_counter_loop.rs:295:9 | LL | 'label: for v in vec { | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `'label: for (_index, v) in vec.into_iter().enumerate()` diff --git a/tests/ui/explicit_deref_methods.fixed b/tests/ui/explicit_deref_methods.fixed index 7b2dd2fe6eb8..ae63f7cbfd8c 100644 --- a/tests/ui/explicit_deref_methods.fixed +++ b/tests/ui/explicit_deref_methods.fixed @@ -52,29 +52,40 @@ fn main() { // these should require linting let b: &str = &*a; + //~^ explicit_deref_methods let b: &mut str = &mut **a; + //~^ explicit_deref_methods // both derefs should get linted here let b: String = format!("{}, {}", &*a, &*a); + //~^ explicit_deref_methods + //~| explicit_deref_methods println!("{}", &*a); + //~^ explicit_deref_methods #[allow(clippy::match_single_binding)] match &*a { + //~^ explicit_deref_methods _ => (), } let b: String = concat(&*a); + //~^ explicit_deref_methods let b = just_return(a); + //~^ explicit_deref_methods let b: String = concat(just_return(a)); + //~^ explicit_deref_methods let b: &str = &**a; + //~^ explicit_deref_methods let opt_a = Some(a.clone()); let b = &*opt_a.unwrap(); + //~^ explicit_deref_methods // make sure `Aaa::deref` instead of `aaa.deref()` is not linted, as well as fully qualified // syntax @@ -112,6 +123,7 @@ fn main() { let b: &str = expr_deref!(a); let b: &str = expr_deref!(&*a); + //~^ explicit_deref_methods // The struct does not implement Deref trait #[derive(Copy, Clone)] diff --git a/tests/ui/explicit_deref_methods.rs b/tests/ui/explicit_deref_methods.rs index eb52cfb0d857..a1378bda85fa 100644 --- a/tests/ui/explicit_deref_methods.rs +++ b/tests/ui/explicit_deref_methods.rs @@ -52,29 +52,40 @@ fn main() { // these should require linting let b: &str = a.deref(); + //~^ explicit_deref_methods let b: &mut str = a.deref_mut(); + //~^ explicit_deref_methods // both derefs should get linted here let b: String = format!("{}, {}", a.deref(), a.deref()); + //~^ explicit_deref_methods + //~| explicit_deref_methods println!("{}", a.deref()); + //~^ explicit_deref_methods #[allow(clippy::match_single_binding)] match a.deref() { + //~^ explicit_deref_methods _ => (), } let b: String = concat(a.deref()); + //~^ explicit_deref_methods let b = just_return(a).deref(); + //~^ explicit_deref_methods let b: String = concat(just_return(a).deref()); + //~^ explicit_deref_methods let b: &str = a.deref().deref(); + //~^ explicit_deref_methods let opt_a = Some(a.clone()); let b = opt_a.unwrap().deref(); + //~^ explicit_deref_methods // make sure `Aaa::deref` instead of `aaa.deref()` is not linted, as well as fully qualified // syntax @@ -112,6 +123,7 @@ fn main() { let b: &str = expr_deref!(a); let b: &str = expr_deref!(a.deref()); + //~^ explicit_deref_methods // The struct does not implement Deref trait #[derive(Copy, Clone)] diff --git a/tests/ui/explicit_deref_methods.stderr b/tests/ui/explicit_deref_methods.stderr index aab862baf599..2ca376cba00b 100644 --- a/tests/ui/explicit_deref_methods.stderr +++ b/tests/ui/explicit_deref_methods.stderr @@ -8,67 +8,67 @@ LL | let b: &str = a.deref(); = help: to override `-D warnings` add `#[allow(clippy::explicit_deref_methods)]` error: explicit `deref_mut` method call - --> tests/ui/explicit_deref_methods.rs:56:23 + --> tests/ui/explicit_deref_methods.rs:57:23 | LL | let b: &mut str = a.deref_mut(); | ^^^^^^^^^^^^^ help: try: `&mut **a` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:59:39 + --> tests/ui/explicit_deref_methods.rs:61:39 | LL | let b: String = format!("{}, {}", a.deref(), a.deref()); | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:59:50 + --> tests/ui/explicit_deref_methods.rs:61:50 | LL | let b: String = format!("{}, {}", a.deref(), a.deref()); | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:61:20 + --> tests/ui/explicit_deref_methods.rs:65:20 | LL | println!("{}", a.deref()); | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:64:11 + --> tests/ui/explicit_deref_methods.rs:69:11 | LL | match a.deref() { | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:68:28 + --> tests/ui/explicit_deref_methods.rs:74:28 | LL | let b: String = concat(a.deref()); | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:70:13 + --> tests/ui/explicit_deref_methods.rs:77:13 | LL | let b = just_return(a).deref(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:72:28 + --> tests/ui/explicit_deref_methods.rs:80:28 | LL | let b: String = concat(just_return(a).deref()); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:74:19 + --> tests/ui/explicit_deref_methods.rs:83:19 | LL | let b: &str = a.deref().deref(); | ^^^^^^^^^^^^^^^^^ help: try: `&**a` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:77:13 + --> tests/ui/explicit_deref_methods.rs:87:13 | LL | let b = opt_a.unwrap().deref(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*opt_a.unwrap()` error: explicit `deref` method call - --> tests/ui/explicit_deref_methods.rs:114:31 + --> tests/ui/explicit_deref_methods.rs:125:31 | LL | let b: &str = expr_deref!(a.deref()); | ^^^^^^^^^ help: try: `&*a` diff --git a/tests/ui/explicit_into_iter_loop.fixed b/tests/ui/explicit_into_iter_loop.fixed index 6d67488a7130..2b68906ae39f 100644 --- a/tests/ui/explicit_into_iter_loop.fixed +++ b/tests/ui/explicit_into_iter_loop.fixed @@ -8,6 +8,7 @@ fn main() { for<'a> &'a T: IntoIterator, { for _ in iterator {} + //~^ explicit_into_iter_loop } struct T; @@ -21,9 +22,11 @@ fn main() { let mut t = T; for _ in &t {} + //~^ explicit_into_iter_loop let r = &t; for _ in r {} + //~^ explicit_into_iter_loop // No suggestion for this. // We'd have to suggest `for _ in *rr {}` which is less clear. @@ -32,6 +35,7 @@ fn main() { let mr = &mut t; for _ in &*mr {} + //~^ explicit_into_iter_loop struct U; impl IntoIterator for &mut U { @@ -44,9 +48,11 @@ fn main() { let mut u = U; for _ in &mut u {} + //~^ explicit_into_iter_loop let mr = &mut u; for _ in &mut *mr {} + //~^ explicit_into_iter_loop // Issue #6900 struct S; diff --git a/tests/ui/explicit_into_iter_loop.rs b/tests/ui/explicit_into_iter_loop.rs index 14630c07c5cc..ca335b62d906 100644 --- a/tests/ui/explicit_into_iter_loop.rs +++ b/tests/ui/explicit_into_iter_loop.rs @@ -8,6 +8,7 @@ fn main() { for<'a> &'a T: IntoIterator, { for _ in iterator.into_iter() {} + //~^ explicit_into_iter_loop } struct T; @@ -21,9 +22,11 @@ fn main() { let mut t = T; for _ in t.into_iter() {} + //~^ explicit_into_iter_loop let r = &t; for _ in r.into_iter() {} + //~^ explicit_into_iter_loop // No suggestion for this. // We'd have to suggest `for _ in *rr {}` which is less clear. @@ -32,6 +35,7 @@ fn main() { let mr = &mut t; for _ in mr.into_iter() {} + //~^ explicit_into_iter_loop struct U; impl IntoIterator for &mut U { @@ -44,9 +48,11 @@ fn main() { let mut u = U; for _ in u.into_iter() {} + //~^ explicit_into_iter_loop let mr = &mut u; for _ in mr.into_iter() {} + //~^ explicit_into_iter_loop // Issue #6900 struct S; diff --git a/tests/ui/explicit_into_iter_loop.stderr b/tests/ui/explicit_into_iter_loop.stderr index f0e2048e036f..1c3156755d4e 100644 --- a/tests/ui/explicit_into_iter_loop.stderr +++ b/tests/ui/explicit_into_iter_loop.stderr @@ -8,31 +8,31 @@ LL | for _ in iterator.into_iter() {} = help: to override `-D warnings` add `#[allow(clippy::explicit_into_iter_loop)]` error: it is more concise to loop over containers instead of using explicit iteration methods - --> tests/ui/explicit_into_iter_loop.rs:23:14 + --> tests/ui/explicit_into_iter_loop.rs:24:14 | LL | for _ in t.into_iter() {} | ^^^^^^^^^^^^^ help: to write this more concisely, try: `&t` error: it is more concise to loop over containers instead of using explicit iteration methods - --> tests/ui/explicit_into_iter_loop.rs:26:14 + --> tests/ui/explicit_into_iter_loop.rs:28:14 | LL | for _ in r.into_iter() {} | ^^^^^^^^^^^^^ help: to write this more concisely, try: `r` error: it is more concise to loop over containers instead of using explicit iteration methods - --> tests/ui/explicit_into_iter_loop.rs:34:14 + --> tests/ui/explicit_into_iter_loop.rs:37:14 | LL | for _ in mr.into_iter() {} | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&*mr` error: it is more concise to loop over containers instead of using explicit iteration methods - --> tests/ui/explicit_into_iter_loop.rs:46:14 + --> tests/ui/explicit_into_iter_loop.rs:50:14 | LL | for _ in u.into_iter() {} | ^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut u` error: it is more concise to loop over containers instead of using explicit iteration methods - --> tests/ui/explicit_into_iter_loop.rs:49:14 + --> tests/ui/explicit_into_iter_loop.rs:54:14 | LL | for _ in mr.into_iter() {} | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *mr` diff --git a/tests/ui/explicit_iter_loop.fixed b/tests/ui/explicit_iter_loop.fixed index 1148f0f6c6a6..cd0898dfc367 100644 --- a/tests/ui/explicit_iter_loop.fixed +++ b/tests/ui/explicit_iter_loop.fixed @@ -16,10 +16,13 @@ fn main() { let mut vec = vec![1, 2, 3, 4]; for _ in &vec {} + //~^ explicit_iter_loop for _ in &mut vec {} + //~^ explicit_iter_loop let rvec = &vec; for _ in rvec {} + //~^ explicit_iter_loop let rmvec = &mut vec; for _ in rmvec.iter() {} @@ -29,36 +32,48 @@ fn main() { for _ in &mut vec {} // these are fine for _ in &[1, 2, 3] {} + //~^ explicit_iter_loop for _ in (&mut [1, 2, 3]).iter() {} for _ in &[0; 32] {} + //~^ explicit_iter_loop for _ in &[0; 33] {} + //~^ explicit_iter_loop let ll: LinkedList<()> = LinkedList::new(); for _ in &ll {} + //~^ explicit_iter_loop let rll = ≪ for _ in rll {} + //~^ explicit_iter_loop let vd: VecDeque<()> = VecDeque::new(); for _ in &vd {} + //~^ explicit_iter_loop let rvd = &vd; for _ in rvd {} + //~^ explicit_iter_loop let bh: BinaryHeap<()> = BinaryHeap::new(); for _ in &bh {} + //~^ explicit_iter_loop let hm: HashMap<(), ()> = HashMap::new(); for _ in &hm {} + //~^ explicit_iter_loop let bt: BTreeMap<(), ()> = BTreeMap::new(); for _ in &bt {} + //~^ explicit_iter_loop let hs: HashSet<()> = HashSet::new(); for _ in &hs {} + //~^ explicit_iter_loop let bs: BTreeSet<()> = BTreeSet::new(); for _ in &bs {} + //~^ explicit_iter_loop struct NoIntoIter(); impl NoIntoIter { @@ -148,10 +163,13 @@ fn main() { } let mut x = CustomType; for _ in &x {} + //~^ explicit_iter_loop for _ in &mut x {} + //~^ explicit_iter_loop let r = &x; for _ in r {} + //~^ explicit_iter_loop } #[clippy::msrv = "1.79"] diff --git a/tests/ui/explicit_iter_loop.rs b/tests/ui/explicit_iter_loop.rs index 4dda2f13e5b8..02405280ce42 100644 --- a/tests/ui/explicit_iter_loop.rs +++ b/tests/ui/explicit_iter_loop.rs @@ -16,10 +16,13 @@ fn main() { let mut vec = vec![1, 2, 3, 4]; for _ in vec.iter() {} + //~^ explicit_iter_loop for _ in vec.iter_mut() {} + //~^ explicit_iter_loop let rvec = &vec; for _ in rvec.iter() {} + //~^ explicit_iter_loop let rmvec = &mut vec; for _ in rmvec.iter() {} @@ -29,36 +32,48 @@ fn main() { for _ in &mut vec {} // these are fine for _ in [1, 2, 3].iter() {} + //~^ explicit_iter_loop for _ in (&mut [1, 2, 3]).iter() {} for _ in [0; 32].iter() {} + //~^ explicit_iter_loop for _ in [0; 33].iter() {} + //~^ explicit_iter_loop let ll: LinkedList<()> = LinkedList::new(); for _ in ll.iter() {} + //~^ explicit_iter_loop let rll = ≪ for _ in rll.iter() {} + //~^ explicit_iter_loop let vd: VecDeque<()> = VecDeque::new(); for _ in vd.iter() {} + //~^ explicit_iter_loop let rvd = &vd; for _ in rvd.iter() {} + //~^ explicit_iter_loop let bh: BinaryHeap<()> = BinaryHeap::new(); for _ in bh.iter() {} + //~^ explicit_iter_loop let hm: HashMap<(), ()> = HashMap::new(); for _ in hm.iter() {} + //~^ explicit_iter_loop let bt: BTreeMap<(), ()> = BTreeMap::new(); for _ in bt.iter() {} + //~^ explicit_iter_loop let hs: HashSet<()> = HashSet::new(); for _ in hs.iter() {} + //~^ explicit_iter_loop let bs: BTreeSet<()> = BTreeSet::new(); for _ in bs.iter() {} + //~^ explicit_iter_loop struct NoIntoIter(); impl NoIntoIter { @@ -148,10 +163,13 @@ fn main() { } let mut x = CustomType; for _ in x.iter() {} + //~^ explicit_iter_loop for _ in x.iter_mut() {} + //~^ explicit_iter_loop let r = &x; for _ in r.iter() {} + //~^ explicit_iter_loop } #[clippy::msrv = "1.79"] diff --git a/tests/ui/explicit_iter_loop.stderr b/tests/ui/explicit_iter_loop.stderr index c646e61aa045..3816bb4db98b 100644 --- a/tests/ui/explicit_iter_loop.stderr +++ b/tests/ui/explicit_iter_loop.stderr @@ -11,103 +11,103 @@ LL | #![deny(clippy::explicit_iter_loop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:19:14 + --> tests/ui/explicit_iter_loop.rs:20:14 | LL | for _ in vec.iter_mut() {} | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut vec` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:22:14 + --> tests/ui/explicit_iter_loop.rs:24:14 | LL | for _ in rvec.iter() {} | ^^^^^^^^^^^ help: to write this more concisely, try: `rvec` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:31:14 + --> tests/ui/explicit_iter_loop.rs:34:14 | LL | for _ in [1, 2, 3].iter() {} | ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:35:14 + --> tests/ui/explicit_iter_loop.rs:39:14 | LL | for _ in [0; 32].iter() {} | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 32]` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:36:14 + --> tests/ui/explicit_iter_loop.rs:41:14 | LL | for _ in [0; 33].iter() {} | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 33]` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:39:14 + --> tests/ui/explicit_iter_loop.rs:45:14 | LL | for _ in ll.iter() {} | ^^^^^^^^^ help: to write this more concisely, try: `&ll` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:41:14 + --> tests/ui/explicit_iter_loop.rs:48:14 | LL | for _ in rll.iter() {} | ^^^^^^^^^^ help: to write this more concisely, try: `rll` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:44:14 + --> tests/ui/explicit_iter_loop.rs:52:14 | LL | for _ in vd.iter() {} | ^^^^^^^^^ help: to write this more concisely, try: `&vd` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:46:14 + --> tests/ui/explicit_iter_loop.rs:55:14 | LL | for _ in rvd.iter() {} | ^^^^^^^^^^ help: to write this more concisely, try: `rvd` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:49:14 + --> tests/ui/explicit_iter_loop.rs:59:14 | LL | for _ in bh.iter() {} | ^^^^^^^^^ help: to write this more concisely, try: `&bh` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:52:14 + --> tests/ui/explicit_iter_loop.rs:63:14 | LL | for _ in hm.iter() {} | ^^^^^^^^^ help: to write this more concisely, try: `&hm` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:55:14 + --> tests/ui/explicit_iter_loop.rs:67:14 | LL | for _ in bt.iter() {} | ^^^^^^^^^ help: to write this more concisely, try: `&bt` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:58:14 + --> tests/ui/explicit_iter_loop.rs:71:14 | LL | for _ in hs.iter() {} | ^^^^^^^^^ help: to write this more concisely, try: `&hs` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:61:14 + --> tests/ui/explicit_iter_loop.rs:75:14 | LL | for _ in bs.iter() {} | ^^^^^^^^^ help: to write this more concisely, try: `&bs` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:150:14 + --> tests/ui/explicit_iter_loop.rs:165:14 | LL | for _ in x.iter() {} | ^^^^^^^^ help: to write this more concisely, try: `&x` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:151:14 + --> tests/ui/explicit_iter_loop.rs:167:14 | LL | for _ in x.iter_mut() {} | ^^^^^^^^^^^^ help: to write this more concisely, try: `&mut x` error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> tests/ui/explicit_iter_loop.rs:154:14 + --> tests/ui/explicit_iter_loop.rs:171:14 | LL | for _ in r.iter() {} | ^^^^^^^^ help: to write this more concisely, try: `r` diff --git a/tests/ui/explicit_write.fixed b/tests/ui/explicit_write.fixed index 77a910dc1963..024999fc609e 100644 --- a/tests/ui/explicit_write.fixed +++ b/tests/ui/explicit_write.fixed @@ -21,23 +21,36 @@ fn main() { { use std::io::Write; print!("test"); + //~^ explicit_write eprint!("test"); + //~^ explicit_write println!("test"); + //~^ explicit_write eprintln!("test"); + //~^ explicit_write print!("test"); + //~^ explicit_write eprint!("test"); + //~^ explicit_write // including newlines println!("test\ntest"); + //~^ explicit_write eprintln!("test\ntest"); + //~^ explicit_write let value = 1; eprintln!("with {}", value); + //~^ explicit_write eprintln!("with {} {}", 2, value); + //~^ explicit_write eprintln!("with {value}"); + //~^ explicit_write eprintln!("macro arg {}", one!()); + //~^ explicit_write let width = 2; eprintln!("{:w$}", value, w = width); + //~^ explicit_write } // these should not warn, different destination { diff --git a/tests/ui/explicit_write.rs b/tests/ui/explicit_write.rs index c77956264f6d..c83c760d48c8 100644 --- a/tests/ui/explicit_write.rs +++ b/tests/ui/explicit_write.rs @@ -21,23 +21,36 @@ fn main() { { use std::io::Write; write!(std::io::stdout(), "test").unwrap(); + //~^ explicit_write write!(std::io::stderr(), "test").unwrap(); + //~^ explicit_write writeln!(std::io::stdout(), "test").unwrap(); + //~^ explicit_write writeln!(std::io::stderr(), "test").unwrap(); + //~^ explicit_write std::io::stdout().write_fmt(format_args!("test")).unwrap(); + //~^ explicit_write std::io::stderr().write_fmt(format_args!("test")).unwrap(); + //~^ explicit_write // including newlines writeln!(std::io::stdout(), "test\ntest").unwrap(); + //~^ explicit_write writeln!(std::io::stderr(), "test\ntest").unwrap(); + //~^ explicit_write let value = 1; writeln!(std::io::stderr(), "with {}", value).unwrap(); + //~^ explicit_write writeln!(std::io::stderr(), "with {} {}", 2, value).unwrap(); + //~^ explicit_write writeln!(std::io::stderr(), "with {value}").unwrap(); + //~^ explicit_write writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap(); + //~^ explicit_write let width = 2; writeln!(std::io::stderr(), "{:w$}", value, w = width).unwrap(); + //~^ explicit_write } // these should not warn, different destination { diff --git a/tests/ui/explicit_write.stderr b/tests/ui/explicit_write.stderr index 0d22f02c36f2..670a0411b310 100644 --- a/tests/ui/explicit_write.stderr +++ b/tests/ui/explicit_write.stderr @@ -8,73 +8,73 @@ LL | write!(std::io::stdout(), "test").unwrap(); = help: to override `-D warnings` add `#[allow(clippy::explicit_write)]` error: use of `write!(stderr(), ...).unwrap()` - --> tests/ui/explicit_write.rs:24:9 + --> tests/ui/explicit_write.rs:25:9 | LL | write!(std::io::stderr(), "test").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprint!("test")` error: use of `writeln!(stdout(), ...).unwrap()` - --> tests/ui/explicit_write.rs:25:9 + --> tests/ui/explicit_write.rs:27:9 | LL | writeln!(std::io::stdout(), "test").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `println!("test")` error: use of `writeln!(stderr(), ...).unwrap()` - --> tests/ui/explicit_write.rs:26:9 + --> tests/ui/explicit_write.rs:29:9 | LL | writeln!(std::io::stderr(), "test").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("test")` error: use of `stdout().write_fmt(...).unwrap()` - --> tests/ui/explicit_write.rs:27:9 + --> tests/ui/explicit_write.rs:31:9 | LL | std::io::stdout().write_fmt(format_args!("test")).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `print!("test")` error: use of `stderr().write_fmt(...).unwrap()` - --> tests/ui/explicit_write.rs:28:9 + --> tests/ui/explicit_write.rs:33:9 | LL | std::io::stderr().write_fmt(format_args!("test")).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprint!("test")` error: use of `writeln!(stdout(), ...).unwrap()` - --> tests/ui/explicit_write.rs:31:9 + --> tests/ui/explicit_write.rs:37:9 | LL | writeln!(std::io::stdout(), "test\ntest").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `println!("test\ntest")` error: use of `writeln!(stderr(), ...).unwrap()` - --> tests/ui/explicit_write.rs:32:9 + --> tests/ui/explicit_write.rs:39:9 | LL | writeln!(std::io::stderr(), "test\ntest").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("test\ntest")` error: use of `writeln!(stderr(), ...).unwrap()` - --> tests/ui/explicit_write.rs:35:9 + --> tests/ui/explicit_write.rs:43:9 | LL | writeln!(std::io::stderr(), "with {}", value).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("with {}", value)` error: use of `writeln!(stderr(), ...).unwrap()` - --> tests/ui/explicit_write.rs:36:9 + --> tests/ui/explicit_write.rs:45:9 | LL | writeln!(std::io::stderr(), "with {} {}", 2, value).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("with {} {}", 2, value)` error: use of `writeln!(stderr(), ...).unwrap()` - --> tests/ui/explicit_write.rs:37:9 + --> tests/ui/explicit_write.rs:47:9 | LL | writeln!(std::io::stderr(), "with {value}").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("with {value}")` error: use of `writeln!(stderr(), ...).unwrap()` - --> tests/ui/explicit_write.rs:38:9 + --> tests/ui/explicit_write.rs:49:9 | LL | writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("macro arg {}", one!())` error: use of `writeln!(stderr(), ...).unwrap()` - --> tests/ui/explicit_write.rs:40:9 + --> tests/ui/explicit_write.rs:52:9 | LL | writeln!(std::io::stderr(), "{:w$}", value, w = width).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("{:w$}", value, w = width)` diff --git a/tests/ui/extend_with_drain.fixed b/tests/ui/extend_with_drain.fixed index 856c1a42dafc..7b314381e9a3 100644 --- a/tests/ui/extend_with_drain.fixed +++ b/tests/ui/extend_with_drain.fixed @@ -6,15 +6,18 @@ fn main() { let mut vec1 = vec![0u8; 1024]; let mut vec2: std::vec::Vec = Vec::new(); vec2.append(&mut vec1); + //~^ extend_with_drain let mut vec3 = vec![0u8; 1024]; let mut vec4: std::vec::Vec = Vec::new(); vec4.append(&mut vec3); + //~^ extend_with_drain let mut vec11: std::vec::Vec = Vec::new(); vec11.append(&mut return_vector()); + //~^ extend_with_drain //won't get linted it doesn't move the entire content of a vec into another let mut test1 = vec![0u8, 10]; @@ -46,6 +49,7 @@ fn main() { let ref_x = &mut x; let mut y = Vec::new(); y.append(ref_x); + //~^ extend_with_drain } fn return_vector() -> Vec { diff --git a/tests/ui/extend_with_drain.rs b/tests/ui/extend_with_drain.rs index 7d538097639f..77214c053979 100644 --- a/tests/ui/extend_with_drain.rs +++ b/tests/ui/extend_with_drain.rs @@ -6,15 +6,18 @@ fn main() { let mut vec1 = vec![0u8; 1024]; let mut vec2: std::vec::Vec = Vec::new(); vec2.extend(vec1.drain(..)); + //~^ extend_with_drain let mut vec3 = vec![0u8; 1024]; let mut vec4: std::vec::Vec = Vec::new(); vec4.extend(vec3.drain(..)); + //~^ extend_with_drain let mut vec11: std::vec::Vec = Vec::new(); vec11.extend(return_vector().drain(..)); + //~^ extend_with_drain //won't get linted it doesn't move the entire content of a vec into another let mut test1 = vec![0u8, 10]; @@ -46,6 +49,7 @@ fn main() { let ref_x = &mut x; let mut y = Vec::new(); y.extend(ref_x.drain(..)); + //~^ extend_with_drain } fn return_vector() -> Vec { diff --git a/tests/ui/extend_with_drain.stderr b/tests/ui/extend_with_drain.stderr index 444cc82bbae7..2ee7aa7294e0 100644 --- a/tests/ui/extend_with_drain.stderr +++ b/tests/ui/extend_with_drain.stderr @@ -8,19 +8,19 @@ LL | vec2.extend(vec1.drain(..)); = help: to override `-D warnings` add `#[allow(clippy::extend_with_drain)]` error: use of `extend` instead of `append` for adding the full range of a second vector - --> tests/ui/extend_with_drain.rs:13:5 + --> tests/ui/extend_with_drain.rs:14:5 | LL | vec4.extend(vec3.drain(..)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec4.append(&mut vec3)` error: use of `extend` instead of `append` for adding the full range of a second vector - --> tests/ui/extend_with_drain.rs:17:5 + --> tests/ui/extend_with_drain.rs:19:5 | LL | vec11.extend(return_vector().drain(..)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec11.append(&mut return_vector())` error: use of `extend` instead of `append` for adding the full range of a second vector - --> tests/ui/extend_with_drain.rs:48:5 + --> tests/ui/extend_with_drain.rs:51:5 | LL | y.extend(ref_x.drain(..)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `y.append(ref_x)` diff --git a/tests/ui/extra_unused_lifetimes.rs b/tests/ui/extra_unused_lifetimes.rs index aa964af3fc2d..fb853bb58305 100644 --- a/tests/ui/extra_unused_lifetimes.rs +++ b/tests/ui/extra_unused_lifetimes.rs @@ -17,6 +17,7 @@ fn empty() {} fn used_lt<'a>(x: &'a u8) {} fn unused_lt<'a>(x: u8) {} +//~^ extra_unused_lifetimes fn unused_lt_transitive<'a, 'b: 'a>(x: &'b u8) { // 'a is useless here since it's not directly bound @@ -44,6 +45,7 @@ struct Bar; impl Bar { fn x<'a>(&self) {} + //~^ extra_unused_lifetimes } // test for #489 (used lifetimes in bounds) @@ -70,6 +72,7 @@ impl X { mod issue4291 { trait BadTrait { fn unused_lt<'a>(x: u8) {} + //~^ extra_unused_lifetimes } impl BadTrait for () { @@ -81,13 +84,16 @@ mod issue6437 { pub struct Scalar; impl<'a> std::ops::AddAssign<&Scalar> for &mut Scalar { + //~^ extra_unused_lifetimes fn add_assign(&mut self, _rhs: &Scalar) { unimplemented!(); } } impl<'b> Scalar { + //~^ extra_unused_lifetimes pub fn something<'c>() -> Self { + //~^ extra_unused_lifetimes Self } } @@ -117,6 +123,7 @@ mod second_case { // Should lint. The response to the above comment incorrectly called this a false positive. The // lifetime `'a` can be removed, as demonstrated below. impl<'a, T: Source + ?Sized + 'a> Source for Box { + //~^ extra_unused_lifetimes fn hey() {} } diff --git a/tests/ui/extra_unused_lifetimes.stderr b/tests/ui/extra_unused_lifetimes.stderr index 85fbb7568ff4..0cecbbe80f76 100644 --- a/tests/ui/extra_unused_lifetimes.stderr +++ b/tests/ui/extra_unused_lifetimes.stderr @@ -8,37 +8,37 @@ LL | fn unused_lt<'a>(x: u8) {} = help: to override `-D warnings` add `#[allow(clippy::extra_unused_lifetimes)]` error: this lifetime isn't used in the function definition - --> tests/ui/extra_unused_lifetimes.rs:46:10 + --> tests/ui/extra_unused_lifetimes.rs:47:10 | LL | fn x<'a>(&self) {} | ^^ error: this lifetime isn't used in the function definition - --> tests/ui/extra_unused_lifetimes.rs:72:22 + --> tests/ui/extra_unused_lifetimes.rs:74:22 | LL | fn unused_lt<'a>(x: u8) {} | ^^ error: this lifetime isn't used in the impl - --> tests/ui/extra_unused_lifetimes.rs:83:10 + --> tests/ui/extra_unused_lifetimes.rs:86:10 | LL | impl<'a> std::ops::AddAssign<&Scalar> for &mut Scalar { | ^^ error: this lifetime isn't used in the impl - --> tests/ui/extra_unused_lifetimes.rs:89:10 + --> tests/ui/extra_unused_lifetimes.rs:93:10 | LL | impl<'b> Scalar { | ^^ error: this lifetime isn't used in the function definition - --> tests/ui/extra_unused_lifetimes.rs:90:26 + --> tests/ui/extra_unused_lifetimes.rs:95:26 | LL | pub fn something<'c>() -> Self { | ^^ error: this lifetime isn't used in the impl - --> tests/ui/extra_unused_lifetimes.rs:119:10 + --> tests/ui/extra_unused_lifetimes.rs:125:10 | LL | impl<'a, T: Source + ?Sized + 'a> Source for Box { | ^^ diff --git a/tests/ui/extra_unused_type_parameters.fixed b/tests/ui/extra_unused_type_parameters.fixed index c9bebabdf17a..1ab74d398314 100644 --- a/tests/ui/extra_unused_type_parameters.fixed +++ b/tests/ui/extra_unused_type_parameters.fixed @@ -7,14 +7,17 @@ extern crate proc_macros; use proc_macros::with_span; fn unused_ty(x: u8) { +//~^ extra_unused_type_parameters unimplemented!() } fn unused_multi(x: u8) { +//~^ extra_unused_type_parameters unimplemented!() } fn unused_with_lt<'a>(x: &'a u8) { +//~^ extra_unused_type_parameters unimplemented!() } @@ -27,10 +30,12 @@ fn used_ret(x: u8) -> T { } fn unused_bounded(x: U) { +//~^ extra_unused_type_parameters unimplemented!(); } fn some_unused(b: B, c: C) { +//~^ extra_unused_type_parameters unimplemented!(); } @@ -56,6 +61,7 @@ struct S; impl S { fn unused_ty_impl(&self) { + //~^ extra_unused_type_parameters unimplemented!() } } @@ -78,6 +84,7 @@ where } fn unused_opaque(dummy: impl Default) { +//~^ extra_unused_type_parameters unimplemented!() } @@ -91,6 +98,7 @@ mod unexported_trait_bounds { } fn unused_with_priv_trait_bound() { + //~^ extra_unused_type_parameters unimplemented!(); } } diff --git a/tests/ui/extra_unused_type_parameters.rs b/tests/ui/extra_unused_type_parameters.rs index 1bc0047adf01..0837efef27bb 100644 --- a/tests/ui/extra_unused_type_parameters.rs +++ b/tests/ui/extra_unused_type_parameters.rs @@ -7,14 +7,17 @@ extern crate proc_macros; use proc_macros::with_span; fn unused_ty(x: u8) { +//~^ extra_unused_type_parameters unimplemented!() } fn unused_multi(x: u8) { +//~^ extra_unused_type_parameters unimplemented!() } fn unused_with_lt<'a, T>(x: &'a u8) { +//~^ extra_unused_type_parameters unimplemented!() } @@ -27,10 +30,12 @@ fn used_ret(x: u8) -> T { } fn unused_bounded(x: U) { +//~^ extra_unused_type_parameters unimplemented!(); } fn some_unused, E>(b: B, c: C) { +//~^ extra_unused_type_parameters unimplemented!(); } @@ -56,6 +61,7 @@ struct S; impl S { fn unused_ty_impl(&self) { + //~^ extra_unused_type_parameters unimplemented!() } } @@ -78,6 +84,7 @@ where } fn unused_opaque(dummy: impl Default) { +//~^ extra_unused_type_parameters unimplemented!() } @@ -91,6 +98,7 @@ mod unexported_trait_bounds { } fn unused_with_priv_trait_bound() { + //~^ extra_unused_type_parameters unimplemented!(); } } diff --git a/tests/ui/extra_unused_type_parameters.stderr b/tests/ui/extra_unused_type_parameters.stderr index 928c0038c2c3..5086826ae5c0 100644 --- a/tests/ui/extra_unused_type_parameters.stderr +++ b/tests/ui/extra_unused_type_parameters.stderr @@ -8,19 +8,19 @@ LL | fn unused_ty(x: u8) { = help: to override `-D warnings` add `#[allow(clippy::extra_unused_type_parameters)]` error: type parameters go unused in function definition: T, U - --> tests/ui/extra_unused_type_parameters.rs:13:16 + --> tests/ui/extra_unused_type_parameters.rs:14:16 | LL | fn unused_multi(x: u8) { | ^^^^^^ help: consider removing the parameters error: type parameter `T` goes unused in function definition - --> tests/ui/extra_unused_type_parameters.rs:17:21 + --> tests/ui/extra_unused_type_parameters.rs:19:21 | LL | fn unused_with_lt<'a, T>(x: &'a u8) { | ^^^ help: consider removing the parameter error: type parameters go unused in function definition: T, V - --> tests/ui/extra_unused_type_parameters.rs:29:19 + --> tests/ui/extra_unused_type_parameters.rs:32:19 | LL | fn unused_bounded(x: U) { | ^^^^^^^^^^^^ ^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL + fn unused_bounded(x: U) { | error: type parameters go unused in function definition: A, D, E - --> tests/ui/extra_unused_type_parameters.rs:33:16 + --> tests/ui/extra_unused_type_parameters.rs:37:16 | LL | fn some_unused, E>(b: B, c: C) { | ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,19 +44,19 @@ LL + fn some_unused(b: B, c: C) { | error: type parameter `T` goes unused in function definition - --> tests/ui/extra_unused_type_parameters.rs:58:22 + --> tests/ui/extra_unused_type_parameters.rs:63:22 | LL | fn unused_ty_impl(&self) { | ^^^ help: consider removing the parameter error: type parameters go unused in function definition: A, B - --> tests/ui/extra_unused_type_parameters.rs:80:17 + --> tests/ui/extra_unused_type_parameters.rs:86:17 | LL | fn unused_opaque(dummy: impl Default) { | ^^^^^^ help: consider removing the parameters error: type parameter `U` goes unused in function definition - --> tests/ui/extra_unused_type_parameters.rs:93:56 + --> tests/ui/extra_unused_type_parameters.rs:100:56 | LL | fn unused_with_priv_trait_bound() { | ^^^ help: consider removing the parameter diff --git a/tests/ui/extra_unused_type_parameters_unfixable.rs b/tests/ui/extra_unused_type_parameters_unfixable.rs index 65b53eb2e4b3..e69c924af00d 100644 --- a/tests/ui/extra_unused_type_parameters_unfixable.rs +++ b/tests/ui/extra_unused_type_parameters_unfixable.rs @@ -1,7 +1,8 @@ #![warn(clippy::extra_unused_type_parameters)] fn unused_where_clause(x: U) -//~^ ERROR: type parameter `T` goes unused in function definition +//~^ extra_unused_type_parameters + where T: Default, { @@ -9,7 +10,8 @@ where } fn unused_multi_where_clause(x: U) -//~^ ERROR: type parameters go unused in function definition: T, V +//~^ extra_unused_type_parameters + where T: Default, { @@ -17,7 +19,8 @@ where } fn unused_all_where_clause() -//~^ ERROR: type parameters go unused in function definition: T, U, V +//~^ extra_unused_type_parameters + where T: Default, { diff --git a/tests/ui/extra_unused_type_parameters_unfixable.stderr b/tests/ui/extra_unused_type_parameters_unfixable.stderr index 0765c4160936..8accb7e5924e 100644 --- a/tests/ui/extra_unused_type_parameters_unfixable.stderr +++ b/tests/ui/extra_unused_type_parameters_unfixable.stderr @@ -9,7 +9,7 @@ LL | fn unused_where_clause(x: U) = help: to override `-D warnings` add `#[allow(clippy::extra_unused_type_parameters)]` error: type parameters go unused in function definition: T, V - --> tests/ui/extra_unused_type_parameters_unfixable.rs:11:30 + --> tests/ui/extra_unused_type_parameters_unfixable.rs:12:30 | LL | fn unused_multi_where_clause(x: U) | ^ ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn unused_multi_where_clause(x: U) = help: consider removing the parameters error: type parameters go unused in function definition: T, U, V - --> tests/ui/extra_unused_type_parameters_unfixable.rs:19:28 + --> tests/ui/extra_unused_type_parameters_unfixable.rs:21:28 | LL | fn unused_all_where_clause() | ^ ^^^^^^^^^^ ^^^^^^^^^^ diff --git a/tests/ui/fallible_impl_from.rs b/tests/ui/fallible_impl_from.rs index a81e51fcac75..56bd8a482684 100644 --- a/tests/ui/fallible_impl_from.rs +++ b/tests/ui/fallible_impl_from.rs @@ -4,7 +4,8 @@ // docs example struct Foo(i32); impl From for Foo { - //~^ ERROR: consider implementing `TryFrom` instead +//~^ fallible_impl_from + fn from(s: String) -> Self { Foo(s.parse().unwrap()) } @@ -26,7 +27,8 @@ impl From for Valid { struct Invalid; impl From for Invalid { - //~^ ERROR: consider implementing `TryFrom` instead +//~^ fallible_impl_from + fn from(i: usize) -> Invalid { if i != 42 { panic!(); @@ -36,7 +38,8 @@ impl From for Invalid { } impl From> for Invalid { - //~^ ERROR: consider implementing `TryFrom` instead +//~^ fallible_impl_from + fn from(s: Option) -> Invalid { let s = s.unwrap(); if !s.is_empty() { @@ -55,7 +58,8 @@ impl ProjStrTrait for Box { type ProjString = String; } impl<'a> From<&'a mut as ProjStrTrait>::ProjString> for Invalid { - //~^ ERROR: consider implementing `TryFrom` instead +//~^ fallible_impl_from + fn from(s: &'a mut as ProjStrTrait>::ProjString) -> Invalid { if s.parse::().ok().unwrap() != 42 { panic!("{:?}", s); diff --git a/tests/ui/fallible_impl_from.stderr b/tests/ui/fallible_impl_from.stderr index cc3739031b76..d773fc3a6d7c 100644 --- a/tests/ui/fallible_impl_from.stderr +++ b/tests/ui/fallible_impl_from.stderr @@ -3,15 +3,15 @@ error: consider implementing `TryFrom` instead | LL | / impl From for Foo { LL | | +LL | | LL | | fn from(s: String) -> Self { -LL | | Foo(s.parse().unwrap()) -LL | | } +... | LL | | } | |_^ | = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail note: potential failure(s) - --> tests/ui/fallible_impl_from.rs:9:13 + --> tests/ui/fallible_impl_from.rs:10:13 | LL | Foo(s.parse().unwrap()) | ^^^^^^^^^^^^^^^^^^ @@ -22,38 +22,38 @@ LL | #![deny(clippy::fallible_impl_from)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: consider implementing `TryFrom` instead - --> tests/ui/fallible_impl_from.rs:28:1 + --> tests/ui/fallible_impl_from.rs:29:1 | LL | / impl From for Invalid { LL | | +LL | | LL | | fn from(i: usize) -> Invalid { -LL | | if i != 42 { ... | LL | | } | |_^ | = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail note: potential failure(s) - --> tests/ui/fallible_impl_from.rs:32:13 + --> tests/ui/fallible_impl_from.rs:34:13 | LL | panic!(); | ^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: consider implementing `TryFrom` instead - --> tests/ui/fallible_impl_from.rs:38:1 + --> tests/ui/fallible_impl_from.rs:40:1 | LL | / impl From> for Invalid { LL | | +LL | | LL | | fn from(s: Option) -> Invalid { -LL | | let s = s.unwrap(); ... | LL | | } | |_^ | = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail note: potential failure(s) - --> tests/ui/fallible_impl_from.rs:41:17 + --> tests/ui/fallible_impl_from.rs:44:17 | LL | let s = s.unwrap(); | ^^^^^^^^^^ @@ -67,19 +67,19 @@ LL | panic!("{:?}", s); = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: consider implementing `TryFrom` instead - --> tests/ui/fallible_impl_from.rs:57:1 + --> tests/ui/fallible_impl_from.rs:60:1 | LL | / impl<'a> From<&'a mut as ProjStrTrait>::ProjString> for Invalid { LL | | +LL | | LL | | fn from(s: &'a mut as ProjStrTrait>::ProjString) -> Invalid { -LL | | if s.parse::().ok().unwrap() != 42 { ... | LL | | } | |_^ | = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail note: potential failure(s) - --> tests/ui/fallible_impl_from.rs:60:12 + --> tests/ui/fallible_impl_from.rs:64:12 | LL | if s.parse::().ok().unwrap() != 42 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/field_reassign_with_default.rs b/tests/ui/field_reassign_with_default.rs index 2a432751952d..f3179b78ecb7 100644 --- a/tests/ui/field_reassign_with_default.rs +++ b/tests/ui/field_reassign_with_default.rs @@ -55,6 +55,7 @@ fn main() { // wrong, produces first error in stderr let mut a: A = Default::default(); a.i = 42; + //~^ field_reassign_with_default // right let mut a: A = Default::default(); @@ -95,17 +96,20 @@ fn main() { // wrong, produces second error in stderr let mut a: A = Default::default(); a.j = 43; + //~^ field_reassign_with_default a.i = 42; // wrong, produces third error in stderr let mut a: A = Default::default(); a.i = 42; + //~^ field_reassign_with_default a.j = 43; a.j = 44; // wrong, produces fourth error in stderr let mut a = A::default(); a.i = 42; + //~^ field_reassign_with_default // wrong, but does not produce an error in stderr, because we can't produce a correct kind of // suggestion with current implementation @@ -116,10 +120,12 @@ fn main() { // wrong, produces the fifth error in stderr let mut a: A = Default::default(); a.i = Default::default(); + //~^ field_reassign_with_default // wrong, produces the sixth error in stderr let mut a: A = Default::default(); a.i = Default::default(); + //~^ field_reassign_with_default a.j = 45; // right, because an assignment refers to another field @@ -142,6 +148,7 @@ fn main() { // don't expand macros in the suggestion (#6522) let mut a: C = C::default(); a.i = vec![1]; + //~^ field_reassign_with_default // Don't lint in external macros external! { @@ -160,9 +167,11 @@ fn main() { // be sure suggestion is correct with generics let mut a: Wrapper = Default::default(); a.i = true; + //~^ field_reassign_with_default let mut a: WrapperMulti = Default::default(); a.i = 42; + //~^ field_reassign_with_default // Don't lint in macros inline!( @@ -234,6 +243,7 @@ mod issue6312 { fn new(name: &str) -> Self { let mut f = ImplDropAllCopy::default(); f.name = name.len(); + //~^ field_reassign_with_default f } fn close(&self) {} @@ -250,6 +260,7 @@ mod issue6312 { fn new(name: &str) -> Self { let mut f = NoDropAllCopy::default(); f.name = name.len(); + //~^ field_reassign_with_default f } } diff --git a/tests/ui/field_reassign_with_default.stderr b/tests/ui/field_reassign_with_default.stderr index ae909475c6f2..19382e671510 100644 --- a/tests/ui/field_reassign_with_default.stderr +++ b/tests/ui/field_reassign_with_default.stderr @@ -13,121 +13,121 @@ LL | let mut a: A = Default::default(); = help: to override `-D warnings` add `#[allow(clippy::field_reassign_with_default)]` error: field assignment outside of initializer for an instance created with Default::default() - --> tests/ui/field_reassign_with_default.rs:97:5 + --> tests/ui/field_reassign_with_default.rs:98:5 | LL | a.j = 43; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments - --> tests/ui/field_reassign_with_default.rs:96:5 + --> tests/ui/field_reassign_with_default.rs:97:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> tests/ui/field_reassign_with_default.rs:102:5 + --> tests/ui/field_reassign_with_default.rs:104:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments - --> tests/ui/field_reassign_with_default.rs:101:5 + --> tests/ui/field_reassign_with_default.rs:103:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> tests/ui/field_reassign_with_default.rs:108:5 + --> tests/ui/field_reassign_with_default.rs:111:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments - --> tests/ui/field_reassign_with_default.rs:107:5 + --> tests/ui/field_reassign_with_default.rs:110:5 | LL | let mut a = A::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: field assignment outside of initializer for an instance created with Default::default() - --> tests/ui/field_reassign_with_default.rs:118:5 - | -LL | a.i = Default::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments - --> tests/ui/field_reassign_with_default.rs:117:5 - | -LL | let mut a: A = Default::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: field assignment outside of initializer for an instance created with Default::default() --> tests/ui/field_reassign_with_default.rs:122:5 | LL | a.i = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments +note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments --> tests/ui/field_reassign_with_default.rs:121:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> tests/ui/field_reassign_with_default.rs:144:5 + --> tests/ui/field_reassign_with_default.rs:127:5 + | +LL | a.i = Default::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments + --> tests/ui/field_reassign_with_default.rs:126:5 + | +LL | let mut a: A = Default::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: field assignment outside of initializer for an instance created with Default::default() + --> tests/ui/field_reassign_with_default.rs:150:5 | LL | a.i = vec![1]; | ^^^^^^^^^^^^^^ | note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments - --> tests/ui/field_reassign_with_default.rs:143:5 + --> tests/ui/field_reassign_with_default.rs:149:5 | LL | let mut a: C = C::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> tests/ui/field_reassign_with_default.rs:162:5 + --> tests/ui/field_reassign_with_default.rs:169:5 | LL | a.i = true; | ^^^^^^^^^^^ | note: consider initializing the variable with `Wrapper:: { i: true }` and removing relevant reassignments - --> tests/ui/field_reassign_with_default.rs:161:5 + --> tests/ui/field_reassign_with_default.rs:168:5 | LL | let mut a: Wrapper = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> tests/ui/field_reassign_with_default.rs:165:5 + --> tests/ui/field_reassign_with_default.rs:173:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `WrapperMulti:: { i: 42, ..Default::default() }` and removing relevant reassignments - --> tests/ui/field_reassign_with_default.rs:164:5 + --> tests/ui/field_reassign_with_default.rs:172:5 | LL | let mut a: WrapperMulti = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> tests/ui/field_reassign_with_default.rs:236:13 + --> tests/ui/field_reassign_with_default.rs:245:13 | LL | f.name = name.len(); | ^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `issue6312::ImplDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments - --> tests/ui/field_reassign_with_default.rs:235:13 + --> tests/ui/field_reassign_with_default.rs:244:13 | LL | let mut f = ImplDropAllCopy::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> tests/ui/field_reassign_with_default.rs:252:13 + --> tests/ui/field_reassign_with_default.rs:262:13 | LL | f.name = name.len(); | ^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `issue6312::NoDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments - --> tests/ui/field_reassign_with_default.rs:251:13 + --> tests/ui/field_reassign_with_default.rs:261:13 | LL | let mut f = NoDropAllCopy::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/field_scoped_visibility_modifiers.rs b/tests/ui/field_scoped_visibility_modifiers.rs index 5789dbf9b1d7..159cabad1b43 100644 --- a/tests/ui/field_scoped_visibility_modifiers.rs +++ b/tests/ui/field_scoped_visibility_modifiers.rs @@ -7,8 +7,11 @@ pub mod pub_module { private_field: bool, pub pub_field: bool, pub(crate) pub_crate_field: bool, + //~^ field_scoped_visibility_modifiers pub(in crate::pub_module) pub_in_path_field: bool, + //~^ field_scoped_visibility_modifiers pub(super) pub_super_field: bool, + //~^ field_scoped_visibility_modifiers #[allow(clippy::needless_pub_self)] pub(self) pub_self_field: bool, } diff --git a/tests/ui/field_scoped_visibility_modifiers.stderr b/tests/ui/field_scoped_visibility_modifiers.stderr index beea6c92107c..c0c202fd87af 100644 --- a/tests/ui/field_scoped_visibility_modifiers.stderr +++ b/tests/ui/field_scoped_visibility_modifiers.stderr @@ -9,7 +9,7 @@ LL | pub(crate) pub_crate_field: bool, = help: to override `-D warnings` add `#[allow(clippy::field_scoped_visibility_modifiers)]` error: scoped visibility modifier on a field - --> tests/ui/field_scoped_visibility_modifiers.rs:10:9 + --> tests/ui/field_scoped_visibility_modifiers.rs:11:9 | LL | pub(in crate::pub_module) pub_in_path_field: bool, | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | pub(in crate::pub_module) pub_in_path_field: bool, = help: consider making the field private and adding a scoped visibility method for it error: scoped visibility modifier on a field - --> tests/ui/field_scoped_visibility_modifiers.rs:11:9 + --> tests/ui/field_scoped_visibility_modifiers.rs:13:9 | LL | pub(super) pub_super_field: bool, | ^^^^^^^^^^ diff --git a/tests/ui/filetype_is_file.rs b/tests/ui/filetype_is_file.rs index 9e8a4c04324b..0e9c160e4a90 100644 --- a/tests/ui/filetype_is_file.rs +++ b/tests/ui/filetype_is_file.rs @@ -7,19 +7,22 @@ fn main() -> std::io::Result<()> { // !filetype.is_dir() if fs::metadata("foo.txt")?.file_type().is_file() { - //~^ ERROR: `FileType::is_file()` only covers regular files + //~^ filetype_is_file + // read file } // positive of filetype.is_dir() if !fs::metadata("foo.txt")?.file_type().is_file() { - //~^ ERROR: `!FileType::is_file()` only denies regular files + //~^ filetype_is_file + // handle dir } // false positive of filetype.is_dir() if !fs::metadata("foo.txt")?.file_type().is_file().bitor(true) { - //~^ ERROR: `FileType::is_file()` only covers regular files + //~^ filetype_is_file + // ... } diff --git a/tests/ui/filetype_is_file.stderr b/tests/ui/filetype_is_file.stderr index 0c66910c1b61..b930ac929748 100644 --- a/tests/ui/filetype_is_file.stderr +++ b/tests/ui/filetype_is_file.stderr @@ -9,7 +9,7 @@ LL | if fs::metadata("foo.txt")?.file_type().is_file() { = help: to override `-D warnings` add `#[allow(clippy::filetype_is_file)]` error: `!FileType::is_file()` only denies regular files - --> tests/ui/filetype_is_file.rs:15:8 + --> tests/ui/filetype_is_file.rs:16:8 | LL | if !fs::metadata("foo.txt")?.file_type().is_file() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | if !fs::metadata("foo.txt")?.file_type().is_file() { = help: use `FileType::is_dir()` instead error: `FileType::is_file()` only covers regular files - --> tests/ui/filetype_is_file.rs:21:9 + --> tests/ui/filetype_is_file.rs:23:9 | LL | if !fs::metadata("foo.txt")?.file_type().is_file().bitor(true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/filter_map_bool_then.fixed b/tests/ui/filter_map_bool_then.fixed index 6a1b81fdbcbe..6d9564dc828b 100644 --- a/tests/ui/filter_map_bool_then.fixed +++ b/tests/ui/filter_map_bool_then.fixed @@ -17,24 +17,30 @@ struct NonCopy; fn main() { let v = vec![1, 2, 3, 4, 5, 6]; v.clone().iter().filter(|&i| (i % 2 == 0)).map(|i| i + 1); + //~^ filter_map_bool_then v.clone().into_iter().filter(|&i| (i % 2 == 0)).map(|i| i + 1); + //~^ filter_map_bool_then v.clone() .into_iter() .filter(|&i| (i % 2 == 0)).map(|i| i + 1); + //~^ filter_map_bool_then v.clone() .into_iter() .filter(|&i| i != 1000) .filter(|&i| (i % 2 == 0)).map(|i| i + 1); + //~^ filter_map_bool_then v.iter() .copied() .filter(|&i| i != 1000) .filter(|&i| (i.clone() % 2 == 0)).map(|i| i + 1); + //~^ filter_map_bool_then // Despite this is non-copy, `is_copy` still returns true (at least now) because it's `&NonCopy`, // and any `&` is `Copy`. So since we can dereference it in `filter` (since it's then `&&NonCopy`), // we can lint this and still get the same input type. // See: let v = vec![NonCopy, NonCopy]; v.clone().iter().filter(|&i| (i == &NonCopy)).map(|i| i); + //~^ filter_map_bool_then // Do not lint let v = vec![NonCopy, NonCopy]; v.clone().into_iter().filter_map(|i| (i == NonCopy).then(|| i)); @@ -59,14 +65,17 @@ fn issue11309<'a>(iter: impl Iterator) -> Vec<&'a str fn issue11503() { let bools: &[bool] = &[true, false, false, true]; let _: Vec = bools.iter().enumerate().filter(|&(i, b)| *b).map(|(i, b)| i).collect(); + //~^ filter_map_bool_then // Need to insert multiple derefs if there is more than one layer of references let bools: &[&&bool] = &[&&true, &&false, &&false, &&true]; let _: Vec = bools.iter().enumerate().filter(|&(i, b)| ***b).map(|(i, b)| i).collect(); + //~^ filter_map_bool_then // Should also suggest derefs when going through a mutable reference let bools: &[&mut bool] = &[&mut true]; let _: Vec = bools.iter().enumerate().filter(|&(i, b)| **b).map(|(i, b)| i).collect(); + //~^ filter_map_bool_then // Should also suggest derefs when going through a custom deref struct DerefToBool; @@ -78,4 +87,5 @@ fn issue11503() { } let bools: &[&&DerefToBool] = &[&&DerefToBool]; let _: Vec = bools.iter().enumerate().filter(|&(i, b)| ****b).map(|(i, b)| i).collect(); + //~^ filter_map_bool_then } diff --git a/tests/ui/filter_map_bool_then.rs b/tests/ui/filter_map_bool_then.rs index a41e88f8805d..dffd798da254 100644 --- a/tests/ui/filter_map_bool_then.rs +++ b/tests/ui/filter_map_bool_then.rs @@ -17,24 +17,30 @@ struct NonCopy; fn main() { let v = vec![1, 2, 3, 4, 5, 6]; v.clone().iter().filter_map(|i| (i % 2 == 0).then(|| i + 1)); + //~^ filter_map_bool_then v.clone().into_iter().filter_map(|i| (i % 2 == 0).then(|| i + 1)); + //~^ filter_map_bool_then v.clone() .into_iter() .filter_map(|i| -> Option<_> { (i % 2 == 0).then(|| i + 1) }); + //~^ filter_map_bool_then v.clone() .into_iter() .filter(|&i| i != 1000) .filter_map(|i| (i % 2 == 0).then(|| i + 1)); + //~^ filter_map_bool_then v.iter() .copied() .filter(|&i| i != 1000) .filter_map(|i| (i.clone() % 2 == 0).then(|| i + 1)); + //~^ filter_map_bool_then // Despite this is non-copy, `is_copy` still returns true (at least now) because it's `&NonCopy`, // and any `&` is `Copy`. So since we can dereference it in `filter` (since it's then `&&NonCopy`), // we can lint this and still get the same input type. // See: let v = vec![NonCopy, NonCopy]; v.clone().iter().filter_map(|i| (i == &NonCopy).then(|| i)); + //~^ filter_map_bool_then // Do not lint let v = vec![NonCopy, NonCopy]; v.clone().into_iter().filter_map(|i| (i == NonCopy).then(|| i)); @@ -59,14 +65,17 @@ fn issue11309<'a>(iter: impl Iterator) -> Vec<&'a str fn issue11503() { let bools: &[bool] = &[true, false, false, true]; let _: Vec = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect(); + //~^ filter_map_bool_then // Need to insert multiple derefs if there is more than one layer of references let bools: &[&&bool] = &[&&true, &&false, &&false, &&true]; let _: Vec = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect(); + //~^ filter_map_bool_then // Should also suggest derefs when going through a mutable reference let bools: &[&mut bool] = &[&mut true]; let _: Vec = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect(); + //~^ filter_map_bool_then // Should also suggest derefs when going through a custom deref struct DerefToBool; @@ -78,4 +87,5 @@ fn issue11503() { } let bools: &[&&DerefToBool] = &[&&DerefToBool]; let _: Vec = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect(); + //~^ filter_map_bool_then } diff --git a/tests/ui/filter_map_bool_then.stderr b/tests/ui/filter_map_bool_then.stderr index 088b9ba12867..aeb1baeb35e6 100644 --- a/tests/ui/filter_map_bool_then.stderr +++ b/tests/ui/filter_map_bool_then.stderr @@ -8,55 +8,55 @@ LL | v.clone().iter().filter_map(|i| (i % 2 == 0).then(|| i + 1)); = help: to override `-D warnings` add `#[allow(clippy::filter_map_bool_then)]` error: usage of `bool::then` in `filter_map` - --> tests/ui/filter_map_bool_then.rs:20:27 + --> tests/ui/filter_map_bool_then.rs:21:27 | LL | v.clone().into_iter().filter_map(|i| (i % 2 == 0).then(|| i + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)` error: usage of `bool::then` in `filter_map` - --> tests/ui/filter_map_bool_then.rs:23:10 + --> tests/ui/filter_map_bool_then.rs:25:10 | LL | .filter_map(|i| -> Option<_> { (i % 2 == 0).then(|| i + 1) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)` error: usage of `bool::then` in `filter_map` - --> tests/ui/filter_map_bool_then.rs:27:10 + --> tests/ui/filter_map_bool_then.rs:30:10 | LL | .filter_map(|i| (i % 2 == 0).then(|| i + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)` error: usage of `bool::then` in `filter_map` - --> tests/ui/filter_map_bool_then.rs:31:10 + --> tests/ui/filter_map_bool_then.rs:35:10 | LL | .filter_map(|i| (i.clone() % 2 == 0).then(|| i + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i.clone() % 2 == 0)).map(|i| i + 1)` error: usage of `bool::then` in `filter_map` - --> tests/ui/filter_map_bool_then.rs:37:22 + --> tests/ui/filter_map_bool_then.rs:42:22 | LL | v.clone().iter().filter_map(|i| (i == &NonCopy).then(|| i)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i == &NonCopy)).map(|i| i)` error: usage of `bool::then` in `filter_map` - --> tests/ui/filter_map_bool_then.rs:61:50 + --> tests/ui/filter_map_bool_then.rs:67:50 | LL | let _: Vec = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| *b).map(|(i, b)| i)` error: usage of `bool::then` in `filter_map` - --> tests/ui/filter_map_bool_then.rs:65:50 + --> tests/ui/filter_map_bool_then.rs:72:50 | LL | let _: Vec = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ***b).map(|(i, b)| i)` error: usage of `bool::then` in `filter_map` - --> tests/ui/filter_map_bool_then.rs:69:50 + --> tests/ui/filter_map_bool_then.rs:77:50 | LL | let _: Vec = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| **b).map(|(i, b)| i)` error: usage of `bool::then` in `filter_map` - --> tests/ui/filter_map_bool_then.rs:80:50 + --> tests/ui/filter_map_bool_then.rs:89:50 | LL | let _: Vec = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ****b).map(|(i, b)| i)` diff --git a/tests/ui/filter_map_identity.fixed b/tests/ui/filter_map_identity.fixed index fdd020fcd773..40c3f58da976 100644 --- a/tests/ui/filter_map_identity.fixed +++ b/tests/ui/filter_map_identity.fixed @@ -26,59 +26,81 @@ fn main() { { // into_iter copy_vec_non_inferred().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec_non_inferred().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec_non_inferred().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec_non_inferred().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec_non_inferred().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + non_copy_vec().into_iter().flatten(); - //~^ ERROR: use of - non_copy_vec().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity non_copy_vec().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + + non_copy_vec().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + non_copy_vec().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + non_copy_vec().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + + non_copy_vec().into_iter().flatten(); + //~^ filter_map_identity + copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + // we are forced to pass the type in the call. copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + #[rustfmt::skip] copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + #[rustfmt::skip] copy_vec::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + // note, the compiler requires that we pass the type to `opaque`. This is mostly for reference, // it behaves the same as copy_vec. opaque::().into_iter().flatten(); - //~^ ERROR: use of + //~^ filter_map_identity + } } diff --git a/tests/ui/filter_map_identity.rs b/tests/ui/filter_map_identity.rs index a626de9f5bbd..f11f80437e85 100644 --- a/tests/ui/filter_map_identity.rs +++ b/tests/ui/filter_map_identity.rs @@ -26,59 +26,81 @@ fn main() { { // into_iter copy_vec_non_inferred().into_iter().filter_map(|x| x); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec_non_inferred().into_iter().filter_map(std::convert::identity); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec_non_inferred().into_iter().filter_map(identity); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec_non_inferred().into_iter().filter_map(|x| return x); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec_non_inferred().into_iter().filter_map(|x| return x); - //~^ ERROR: use of + //~^ filter_map_identity + non_copy_vec().into_iter().filter_map(|x| x); - //~^ ERROR: use of + //~^ filter_map_identity + non_copy_vec().into_iter().filter_map(|x| x); - //~^ ERROR: use of + //~^ filter_map_identity + non_copy_vec().into_iter().filter_map(std::convert::identity); - //~^ ERROR: use of + //~^ filter_map_identity + non_copy_vec().into_iter().filter_map(identity); - //~^ ERROR: use of + //~^ filter_map_identity + non_copy_vec().into_iter().filter_map(|x| return x); - //~^ ERROR: use of + //~^ filter_map_identity + non_copy_vec().into_iter().filter_map(|x| return x); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().filter_map(|x: Option<_>| x); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().filter_map(|x: Option<_>| x); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().filter_map(|x: Option<_>| return x); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().filter_map(|x: Option<_>| return x); - //~^ ERROR: use of + //~^ filter_map_identity + // we are forced to pass the type in the call. copy_vec::().into_iter().filter_map(|x: Option| x); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().filter_map(|x: Option| x); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().filter_map(|x: Option| return x); - //~^ ERROR: use of + //~^ filter_map_identity + copy_vec::().into_iter().filter_map(|x: Option| return x); - //~^ ERROR: use of + //~^ filter_map_identity + #[rustfmt::skip] copy_vec::().into_iter().filter_map(|x: Option| -> Option {{ x }}); - //~^ ERROR: use of + //~^ filter_map_identity + #[rustfmt::skip] copy_vec::().into_iter().filter_map(|x: Option| -> Option {{ return x }}); - //~^ ERROR: use of + //~^ filter_map_identity + // note, the compiler requires that we pass the type to `opaque`. This is mostly for reference, // it behaves the same as copy_vec. opaque::().into_iter().filter_map(|x| x); - //~^ ERROR: use of + //~^ filter_map_identity + } } diff --git a/tests/ui/filter_map_identity.stderr b/tests/ui/filter_map_identity.stderr index 55068db4e9d0..4223343251f1 100644 --- a/tests/ui/filter_map_identity.stderr +++ b/tests/ui/filter_map_identity.stderr @@ -8,127 +8,127 @@ LL | copy_vec_non_inferred().into_iter().filter_map(|x| x); = help: to override `-D warnings` add `#[allow(clippy::filter_map_identity)]` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:30:45 + --> tests/ui/filter_map_identity.rs:31:45 | LL | copy_vec_non_inferred().into_iter().filter_map(std::convert::identity); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:32:45 + --> tests/ui/filter_map_identity.rs:34:45 | LL | copy_vec_non_inferred().into_iter().filter_map(identity); | ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:34:45 + --> tests/ui/filter_map_identity.rs:37:45 | LL | copy_vec_non_inferred().into_iter().filter_map(|x| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:36:45 + --> tests/ui/filter_map_identity.rs:40:45 | LL | copy_vec_non_inferred().into_iter().filter_map(|x| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` -error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:39:36 - | -LL | non_copy_vec().into_iter().filter_map(|x| x); - | ^^^^^^^^^^^^^^^^^ help: try: `flatten()` - -error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:41:36 - | -LL | non_copy_vec().into_iter().filter_map(|x| x); - | ^^^^^^^^^^^^^^^^^ help: try: `flatten()` - error: use of `filter_map` with an identity function --> tests/ui/filter_map_identity.rs:44:36 | +LL | non_copy_vec().into_iter().filter_map(|x| x); + | ^^^^^^^^^^^^^^^^^ help: try: `flatten()` + +error: use of `filter_map` with an identity function + --> tests/ui/filter_map_identity.rs:47:36 + | +LL | non_copy_vec().into_iter().filter_map(|x| x); + | ^^^^^^^^^^^^^^^^^ help: try: `flatten()` + +error: use of `filter_map` with an identity function + --> tests/ui/filter_map_identity.rs:51:36 + | LL | non_copy_vec().into_iter().filter_map(std::convert::identity); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:46:36 + --> tests/ui/filter_map_identity.rs:54:36 | LL | non_copy_vec().into_iter().filter_map(identity); | ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:48:36 + --> tests/ui/filter_map_identity.rs:57:36 | LL | non_copy_vec().into_iter().filter_map(|x| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:50:36 + --> tests/ui/filter_map_identity.rs:60:36 | LL | non_copy_vec().into_iter().filter_map(|x| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:53:39 + --> tests/ui/filter_map_identity.rs:64:39 | LL | copy_vec::().into_iter().filter_map(|x: Option<_>| x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` -error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:55:39 - | -LL | copy_vec::().into_iter().filter_map(|x: Option<_>| x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` - -error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:57:39 - | -LL | copy_vec::().into_iter().filter_map(|x: Option<_>| return x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` - -error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:59:39 - | -LL | copy_vec::().into_iter().filter_map(|x: Option<_>| return x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` - -error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:63:39 - | -LL | copy_vec::().into_iter().filter_map(|x: Option| x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` - -error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:65:39 - | -LL | copy_vec::().into_iter().filter_map(|x: Option| x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` - error: use of `filter_map` with an identity function --> tests/ui/filter_map_identity.rs:67:39 | -LL | copy_vec::().into_iter().filter_map(|x: Option| return x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` +LL | copy_vec::().into_iter().filter_map(|x: Option<_>| x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:69:39 + --> tests/ui/filter_map_identity.rs:70:39 + | +LL | copy_vec::().into_iter().filter_map(|x: Option<_>| return x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` + +error: use of `filter_map` with an identity function + --> tests/ui/filter_map_identity.rs:73:39 + | +LL | copy_vec::().into_iter().filter_map(|x: Option<_>| return x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` + +error: use of `filter_map` with an identity function + --> tests/ui/filter_map_identity.rs:78:39 + | +LL | copy_vec::().into_iter().filter_map(|x: Option| x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` + +error: use of `filter_map` with an identity function + --> tests/ui/filter_map_identity.rs:81:39 + | +LL | copy_vec::().into_iter().filter_map(|x: Option| x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` + +error: use of `filter_map` with an identity function + --> tests/ui/filter_map_identity.rs:84:39 | LL | copy_vec::().into_iter().filter_map(|x: Option| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:72:43 + --> tests/ui/filter_map_identity.rs:87:39 + | +LL | copy_vec::().into_iter().filter_map(|x: Option| return x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` + +error: use of `filter_map` with an identity function + --> tests/ui/filter_map_identity.rs:91:43 | LL | copy_vec::().into_iter().filter_map(|x: Option| -> Option {{ x }}); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:75:43 + --> tests/ui/filter_map_identity.rs:95:43 | LL | copy_vec::().into_iter().filter_map(|x: Option| -> Option {{ return x }}); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:80:37 + --> tests/ui/filter_map_identity.rs:101:37 | LL | opaque::().into_iter().filter_map(|x| x); | ^^^^^^^^^^^^^^^^^ help: try: `flatten()` diff --git a/tests/ui/filter_map_next.rs b/tests/ui/filter_map_next.rs index 9077b8fca23e..2a2237ed16cf 100644 --- a/tests/ui/filter_map_next.rs +++ b/tests/ui/filter_map_next.rs @@ -5,8 +5,9 @@ fn main() { #[rustfmt::skip] let _: Option = vec![1, 2, 3, 4, 5, 6] - //~^ ERROR: called `filter_map(..).next()` on an `Iterator`. This is more succinctly e - //~| NOTE: `-D clippy::filter-map-next` implied by `-D warnings` + //~^ filter_map_next + + .into_iter() .filter_map(|x| { if x == 2 { diff --git a/tests/ui/filter_map_next.stderr b/tests/ui/filter_map_next.stderr index cd3ffe3aa7f0..974bb946d46a 100644 --- a/tests/ui/filter_map_next.stderr +++ b/tests/ui/filter_map_next.stderr @@ -3,9 +3,6 @@ error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly | LL | let _: Option = vec![1, 2, 3, 4, 5, 6] | __________________________^ -LL | | -LL | | -LL | | .into_iter() ... | LL | | }) LL | | .next(); diff --git a/tests/ui/filter_map_next_fixable.fixed b/tests/ui/filter_map_next_fixable.fixed index 193ac3aea433..285863ef340d 100644 --- a/tests/ui/filter_map_next_fixable.fixed +++ b/tests/ui/filter_map_next_fixable.fixed @@ -5,6 +5,7 @@ fn main() { let a = ["1", "lol", "3", "NaN", "5"]; let element: Option = a.iter().find_map(|s| s.parse().ok()); + //~^ filter_map_next assert_eq!(element, Some(1)); } @@ -18,4 +19,5 @@ fn msrv_1_29() { fn msrv_1_30() { let a = ["1", "lol", "3", "NaN", "5"]; let _: Option = a.iter().find_map(|s| s.parse().ok()); + //~^ filter_map_next } diff --git a/tests/ui/filter_map_next_fixable.rs b/tests/ui/filter_map_next_fixable.rs index dab8d289817e..af911689b7c7 100644 --- a/tests/ui/filter_map_next_fixable.rs +++ b/tests/ui/filter_map_next_fixable.rs @@ -5,6 +5,7 @@ fn main() { let a = ["1", "lol", "3", "NaN", "5"]; let element: Option = a.iter().filter_map(|s| s.parse().ok()).next(); + //~^ filter_map_next assert_eq!(element, Some(1)); } @@ -18,4 +19,5 @@ fn msrv_1_29() { fn msrv_1_30() { let a = ["1", "lol", "3", "NaN", "5"]; let _: Option = a.iter().filter_map(|s| s.parse().ok()).next(); + //~^ filter_map_next } diff --git a/tests/ui/filter_map_next_fixable.stderr b/tests/ui/filter_map_next_fixable.stderr index 2c6148f3f4b6..707dec8687b1 100644 --- a/tests/ui/filter_map_next_fixable.stderr +++ b/tests/ui/filter_map_next_fixable.stderr @@ -8,7 +8,7 @@ LL | let element: Option = a.iter().filter_map(|s| s.parse().ok()).next = help: to override `-D warnings` add `#[allow(clippy::filter_map_next)]` error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead - --> tests/ui/filter_map_next_fixable.rs:20:26 + --> tests/ui/filter_map_next_fixable.rs:21:26 | LL | let _: Option = a.iter().filter_map(|s| s.parse().ok()).next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.iter().find_map(|s| s.parse().ok())` diff --git a/tests/ui/find_map.rs b/tests/ui/find_map.rs index bbd395d50ef2..aba1f2cbe581 100644 --- a/tests/ui/find_map.rs +++ b/tests/ui/find_map.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::all, clippy::pedantic)] #![allow(clippy::useless_vec)] diff --git a/tests/ui/flat_map_identity.fixed b/tests/ui/flat_map_identity.fixed index c142cf719808..f62062326126 100644 --- a/tests/ui/flat_map_identity.fixed +++ b/tests/ui/flat_map_identity.fixed @@ -6,10 +6,13 @@ use std::convert; fn main() { let iterator = [[0, 1], [2, 3], [4, 5]].iter(); let _ = iterator.flatten(); + //~^ flat_map_identity let iterator = [[0, 1], [2, 3], [4, 5]].iter(); let _ = iterator.flatten(); + //~^ flat_map_identity let iterator = [[0, 1], [2, 3], [4, 5]].iter(); let _ = iterator.flatten(); + //~^ flat_map_identity } diff --git a/tests/ui/flat_map_identity.rs b/tests/ui/flat_map_identity.rs index 8505ba9005d3..c59e749474ee 100644 --- a/tests/ui/flat_map_identity.rs +++ b/tests/ui/flat_map_identity.rs @@ -6,10 +6,13 @@ use std::convert; fn main() { let iterator = [[0, 1], [2, 3], [4, 5]].iter(); let _ = iterator.flat_map(|x| x); + //~^ flat_map_identity let iterator = [[0, 1], [2, 3], [4, 5]].iter(); let _ = iterator.flat_map(convert::identity); + //~^ flat_map_identity let iterator = [[0, 1], [2, 3], [4, 5]].iter(); let _ = iterator.flat_map(|x| return x); + //~^ flat_map_identity } diff --git a/tests/ui/flat_map_identity.stderr b/tests/ui/flat_map_identity.stderr index 496fd972a498..75137f5d9e57 100644 --- a/tests/ui/flat_map_identity.stderr +++ b/tests/ui/flat_map_identity.stderr @@ -8,13 +8,13 @@ LL | let _ = iterator.flat_map(|x| x); = help: to override `-D warnings` add `#[allow(clippy::flat_map_identity)]` error: use of `flat_map` with an identity function - --> tests/ui/flat_map_identity.rs:11:22 + --> tests/ui/flat_map_identity.rs:12:22 | LL | let _ = iterator.flat_map(convert::identity); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `flat_map` with an identity function - --> tests/ui/flat_map_identity.rs:14:22 + --> tests/ui/flat_map_identity.rs:16:22 | LL | let _ = iterator.flat_map(|x| return x); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` diff --git a/tests/ui/flat_map_option.fixed b/tests/ui/flat_map_option.fixed index e08d9a14533b..e65e77ab79dc 100644 --- a/tests/ui/flat_map_option.fixed +++ b/tests/ui/flat_map_option.fixed @@ -5,7 +5,9 @@ fn main() { // yay let c = |x| Some(x); let _ = [1].iter().filter_map(c); + //~^ flat_map_option let _ = [1].iter().filter_map(Some); + //~^ flat_map_option // nay let _ = [1].iter().flat_map(|_| &Some(1)); diff --git a/tests/ui/flat_map_option.rs b/tests/ui/flat_map_option.rs index 4d0f32ac0fda..6784100a4fc9 100644 --- a/tests/ui/flat_map_option.rs +++ b/tests/ui/flat_map_option.rs @@ -5,7 +5,9 @@ fn main() { // yay let c = |x| Some(x); let _ = [1].iter().flat_map(c); + //~^ flat_map_option let _ = [1].iter().flat_map(Some); + //~^ flat_map_option // nay let _ = [1].iter().flat_map(|_| &Some(1)); diff --git a/tests/ui/flat_map_option.stderr b/tests/ui/flat_map_option.stderr index 6e151965fad5..7f5f2c14ec8e 100644 --- a/tests/ui/flat_map_option.stderr +++ b/tests/ui/flat_map_option.stderr @@ -8,7 +8,7 @@ LL | let _ = [1].iter().flat_map(c); = help: to override `-D warnings` add `#[allow(clippy::flat_map_option)]` error: used `flat_map` where `filter_map` could be used instead - --> tests/ui/flat_map_option.rs:8:24 + --> tests/ui/flat_map_option.rs:9:24 | LL | let _ = [1].iter().flat_map(Some); | ^^^^^^^^ help: try: `filter_map` diff --git a/tests/ui/float_arithmetic.rs b/tests/ui/float_arithmetic.rs index 1647273c436d..3b87d2ec066d 100644 --- a/tests/ui/float_arithmetic.rs +++ b/tests/ui/float_arithmetic.rs @@ -13,58 +13,75 @@ fn main() { let mut f = 1.0f32; f * 2.0; - //~^ ERROR: floating-point arithmetic detected - //~| NOTE: `-D clippy::float-arithmetic` implied by `-D warnings` + //~^ float_arithmetic + + 1.0 + f; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + f * 2.0; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + f / 2.0; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + f - 2.0 * 4.2; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + -f; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + f += 1.0; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + f -= 1.0; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + f *= 2.0; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + f /= 2.0; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + } // also warn about floating point arith with references involved pub fn float_arith_ref() { 3.1_f32 + &1.2_f32; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + &3.4_f32 + 1.5_f32; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + &3.5_f32 + &1.3_f32; - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + } pub fn float_foo(f: &f32) -> f32 { let a = 5.1; a + f - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + } pub fn float_bar(f1: &f32, f2: &f32) -> f32 { f1 + f2 - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + } pub fn float_baz(f1: f32, f2: &f32) -> f32 { f1 + f2 - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + } pub fn float_qux(f1: f32, f2: f32) -> f32 { (&f1 + &f2) - //~^ ERROR: floating-point arithmetic detected + //~^ float_arithmetic + } diff --git a/tests/ui/float_arithmetic.stderr b/tests/ui/float_arithmetic.stderr index 66455f061455..c01fdf8b46ec 100644 --- a/tests/ui/float_arithmetic.stderr +++ b/tests/ui/float_arithmetic.stderr @@ -8,97 +8,97 @@ LL | f * 2.0; = help: to override `-D warnings` add `#[allow(clippy::float_arithmetic)]` error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:19:5 + --> tests/ui/float_arithmetic.rs:20:5 | LL | 1.0 + f; | ^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:21:5 + --> tests/ui/float_arithmetic.rs:23:5 | LL | f * 2.0; | ^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:23:5 + --> tests/ui/float_arithmetic.rs:26:5 | LL | f / 2.0; | ^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:25:5 + --> tests/ui/float_arithmetic.rs:29:5 | LL | f - 2.0 * 4.2; | ^^^^^^^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:27:5 + --> tests/ui/float_arithmetic.rs:32:5 | LL | -f; | ^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:30:5 + --> tests/ui/float_arithmetic.rs:36:5 | LL | f += 1.0; | ^^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:32:5 + --> tests/ui/float_arithmetic.rs:39:5 | LL | f -= 1.0; | ^^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:34:5 + --> tests/ui/float_arithmetic.rs:42:5 | LL | f *= 2.0; | ^^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:36:5 + --> tests/ui/float_arithmetic.rs:45:5 | LL | f /= 2.0; | ^^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:43:5 + --> tests/ui/float_arithmetic.rs:53:5 | LL | 3.1_f32 + &1.2_f32; | ^^^^^^^^^^^^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:45:5 + --> tests/ui/float_arithmetic.rs:56:5 | LL | &3.4_f32 + 1.5_f32; | ^^^^^^^^^^^^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:47:5 + --> tests/ui/float_arithmetic.rs:59:5 | LL | &3.5_f32 + &1.3_f32; | ^^^^^^^^^^^^^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:53:5 + --> tests/ui/float_arithmetic.rs:66:5 | LL | a + f | ^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:58:5 + --> tests/ui/float_arithmetic.rs:72:5 | LL | f1 + f2 | ^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:63:5 + --> tests/ui/float_arithmetic.rs:78:5 | LL | f1 + f2 | ^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:68:5 + --> tests/ui/float_arithmetic.rs:84:5 | LL | (&f1 + &f2) | ^^^^^^^^^^^ diff --git a/tests/ui/float_cmp.rs b/tests/ui/float_cmp.rs index a1dfd1954fce..84cf67ed4f10 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -70,17 +70,20 @@ fn main() { ONE != 0.0; // no error, comparison with zero is ok twice(ONE) != ONE; ONE as f64 != 2.0; - //~^ ERROR: strict comparison of `f32` or `f64` + //~^ float_cmp + ONE as f64 != 0.0; // no error, comparison with zero is ok let x: f64 = 1.0; x == 1.0; - //~^ ERROR: strict comparison of `f32` or `f64` + //~^ float_cmp + x != 0f64; // no error, comparison with zero is ok twice(x) != twice(ONE as f64); - //~^ ERROR: strict comparison of `f32` or `f64` + //~^ float_cmp + x < 0.0; // no errors, lower or greater comparisons need no fuzzyness x > 0.0; @@ -101,15 +104,18 @@ fn main() { ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; // ok, because lhs is zero regardless of i NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; - //~^ ERROR: strict comparison of `f32` or `f64` + //~^ float_cmp + let a1: [f32; 1] = [0.0]; let a2: [f32; 1] = [1.1]; a1 == a2; - //~^ ERROR: strict comparison of `f32` or `f64` arrays + //~^ float_cmp + a1[0] == a2[0]; - //~^ ERROR: strict comparison of `f32` or `f64` + //~^ float_cmp + // no errors - comparing signums is ok let x32 = 3.21f32; diff --git a/tests/ui/float_cmp.stderr b/tests/ui/float_cmp.stderr index d10da8a99a9d..1b57e15bbb97 100644 --- a/tests/ui/float_cmp.stderr +++ b/tests/ui/float_cmp.stderr @@ -8,31 +8,31 @@ LL | ONE as f64 != 2.0; = help: to override `-D warnings` add `#[allow(clippy::float_cmp)]` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:78:5 + --> tests/ui/float_cmp.rs:79:5 | LL | x == 1.0; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:82:5 + --> tests/ui/float_cmp.rs:84:5 | LL | twice(x) != twice(ONE as f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:103:5 + --> tests/ui/float_cmp.rs:106:5 | LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:109:5 + --> tests/ui/float_cmp.rs:113:5 | LL | a1 == a2; | ^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:111:5 + --> tests/ui/float_cmp.rs:116:5 | LL | a1[0] == a2[0]; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin` diff --git a/tests/ui/float_cmp_const.rs b/tests/ui/float_cmp_const.rs index ba760a18f28a..86b3e5d46a06 100644 --- a/tests/ui/float_cmp_const.rs +++ b/tests/ui/float_cmp_const.rs @@ -13,22 +13,29 @@ fn eq_one(x: f32) -> bool { fn main() { // has errors 1f32 == ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant + //~^ float_cmp_const + TWO == ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant + //~^ float_cmp_const + TWO != ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant + //~^ float_cmp_const + ONE + ONE == TWO; - //~^ ERROR: strict comparison of `f32` or `f64` constant + //~^ float_cmp_const + let x = 1; x as f32 == ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant + //~^ float_cmp_const + let v = 0.9; v == ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant + //~^ float_cmp_const + v != ONE; - //~^ ERROR: strict comparison of `f32` or `f64` constant + //~^ float_cmp_const + // no errors, lower than or greater than comparisons v < ONE; @@ -61,5 +68,6 @@ fn main() { // has errors NON_ZERO_ARRAY == NON_ZERO_ARRAY2; - //~^ ERROR: strict comparison of `f32` or `f64` constant arrays + //~^ float_cmp_const + } diff --git a/tests/ui/float_cmp_const.stderr b/tests/ui/float_cmp_const.stderr index e0cd6faf4b3a..c2c7b229870a 100644 --- a/tests/ui/float_cmp_const.stderr +++ b/tests/ui/float_cmp_const.stderr @@ -8,43 +8,43 @@ LL | 1f32 == ONE; = help: to override `-D warnings` add `#[allow(clippy::float_cmp_const)]` error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:17:5 + --> tests/ui/float_cmp_const.rs:18:5 | LL | TWO == ONE; | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() < error_margin` error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:19:5 + --> tests/ui/float_cmp_const.rs:21:5 | LL | TWO != ONE; | ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() > error_margin` error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:21:5 + --> tests/ui/float_cmp_const.rs:24:5 | LL | ONE + ONE == TWO; | ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE + ONE - TWO).abs() < error_margin` error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:24:5 + --> tests/ui/float_cmp_const.rs:28:5 | LL | x as f32 == ONE; | ^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x as f32 - ONE).abs() < error_margin` error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:28:5 + --> tests/ui/float_cmp_const.rs:33:5 | LL | v == ONE; | ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() < error_margin` error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:30:5 + --> tests/ui/float_cmp_const.rs:36:5 | LL | v != ONE; | ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() > error_margin` error: strict comparison of `f32` or `f64` constant arrays - --> tests/ui/float_cmp_const.rs:63:5 + --> tests/ui/float_cmp_const.rs:70:5 | LL | NON_ZERO_ARRAY == NON_ZERO_ARRAY2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/float_equality_without_abs.rs b/tests/ui/float_equality_without_abs.rs index 500b3035390f..db0a4f492607 100644 --- a/tests/ui/float_equality_without_abs.rs +++ b/tests/ui/float_equality_without_abs.rs @@ -5,8 +5,9 @@ pub fn is_roughly_equal(a: f32, b: f32) -> bool { (a - b) < f32::EPSILON - //~^ ERROR: float equality check without `.abs()` - //~| NOTE: `-D clippy::float-equality-without-abs` implied by `-D warnings` + //~^ float_equality_without_abs + + } pub fn main() { @@ -16,26 +17,36 @@ pub fn main() { let b = 0.0500001; let _ = (a - b) < f32::EPSILON; - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + let _ = a - b < f32::EPSILON; - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + let _ = a - b.abs() < f32::EPSILON; - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + let _ = (a as f64 - b as f64) < f64::EPSILON; - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + let _ = 1.0 - 2.0 < f32::EPSILON; - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + let _ = f32::EPSILON > (a - b); - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + let _ = f32::EPSILON > a - b; - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + let _ = f32::EPSILON > a - b.abs(); - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + let _ = f64::EPSILON > (a as f64 - b as f64); - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + let _ = f32::EPSILON > 1.0 - 2.0; - //~^ ERROR: float equality check without `.abs()` + //~^ float_equality_without_abs + // those are correct let _ = (a - b).abs() < f32::EPSILON; diff --git a/tests/ui/float_equality_without_abs.stderr b/tests/ui/float_equality_without_abs.stderr index cdaaf0cdbcf7..5696ec54d765 100644 --- a/tests/ui/float_equality_without_abs.stderr +++ b/tests/ui/float_equality_without_abs.stderr @@ -10,7 +10,7 @@ LL | (a - b) < f32::EPSILON = help: to override `-D warnings` add `#[allow(clippy::float_equality_without_abs)]` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:18:13 + --> tests/ui/float_equality_without_abs.rs:19:13 | LL | let _ = (a - b) < f32::EPSILON; | -------^^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | let _ = (a - b) < f32::EPSILON; | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:20:13 + --> tests/ui/float_equality_without_abs.rs:22:13 | LL | let _ = a - b < f32::EPSILON; | -----^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let _ = a - b < f32::EPSILON; | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:22:13 + --> tests/ui/float_equality_without_abs.rs:25:13 | LL | let _ = a - b.abs() < f32::EPSILON; | -----------^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = a - b.abs() < f32::EPSILON; | help: add `.abs()`: `(a - b.abs()).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:24:13 + --> tests/ui/float_equality_without_abs.rs:28:13 | LL | let _ = (a as f64 - b as f64) < f64::EPSILON; | ---------------------^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | let _ = (a as f64 - b as f64) < f64::EPSILON; | help: add `.abs()`: `(a as f64 - b as f64).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:26:13 + --> tests/ui/float_equality_without_abs.rs:31:13 | LL | let _ = 1.0 - 2.0 < f32::EPSILON; | ---------^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | let _ = 1.0 - 2.0 < f32::EPSILON; | help: add `.abs()`: `(1.0 - 2.0).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:29:13 + --> tests/ui/float_equality_without_abs.rs:35:13 | LL | let _ = f32::EPSILON > (a - b); | ^^^^^^^^^^^^^^^------- @@ -58,7 +58,7 @@ LL | let _ = f32::EPSILON > (a - b); | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:31:13 + --> tests/ui/float_equality_without_abs.rs:38:13 | LL | let _ = f32::EPSILON > a - b; | ^^^^^^^^^^^^^^^----- @@ -66,7 +66,7 @@ LL | let _ = f32::EPSILON > a - b; | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:33:13 + --> tests/ui/float_equality_without_abs.rs:41:13 | LL | let _ = f32::EPSILON > a - b.abs(); | ^^^^^^^^^^^^^^^----------- @@ -74,7 +74,7 @@ LL | let _ = f32::EPSILON > a - b.abs(); | help: add `.abs()`: `(a - b.abs()).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:35:13 + --> tests/ui/float_equality_without_abs.rs:44:13 | LL | let _ = f64::EPSILON > (a as f64 - b as f64); | ^^^^^^^^^^^^^^^--------------------- @@ -82,7 +82,7 @@ LL | let _ = f64::EPSILON > (a as f64 - b as f64); | help: add `.abs()`: `(a as f64 - b as f64).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:37:13 + --> tests/ui/float_equality_without_abs.rs:47:13 | LL | let _ = f32::EPSILON > 1.0 - 2.0; | ^^^^^^^^^^^^^^^--------- diff --git a/tests/ui/floating_point_abs.fixed b/tests/ui/floating_point_abs.fixed index 33183c769724..e8d64a3d7c29 100644 --- a/tests/ui/floating_point_abs.fixed +++ b/tests/ui/floating_point_abs.fixed @@ -12,35 +12,43 @@ struct A { fn fake_abs1(num: f64) -> f64 { num.abs() + //~^ suboptimal_flops } fn fake_abs2(num: f64) -> f64 { num.abs() + //~^ suboptimal_flops } fn fake_abs3(a: A) -> f64 { a.a.abs() + //~^ suboptimal_flops } fn fake_abs4(num: f64) -> f64 { num.abs() + //~^ suboptimal_flops } fn fake_abs5(a: A) -> f64 { a.a.abs() + //~^ suboptimal_flops } fn fake_nabs1(num: f64) -> f64 { -num.abs() + //~^ suboptimal_flops } fn fake_nabs2(num: f64) -> f64 { -num.abs() + //~^ suboptimal_flops } fn fake_nabs3(a: A) -> A { A { a: -a.a.abs(), + //~^ suboptimal_flops b: a.b, } } diff --git a/tests/ui/floating_point_abs.rs b/tests/ui/floating_point_abs.rs index a08d5bbcef5c..a27279b0662f 100644 --- a/tests/ui/floating_point_abs.rs +++ b/tests/ui/floating_point_abs.rs @@ -12,35 +12,43 @@ struct A { fn fake_abs1(num: f64) -> f64 { if num >= 0.0 { num } else { -num } + //~^ suboptimal_flops } fn fake_abs2(num: f64) -> f64 { if 0.0 < num { num } else { -num } + //~^ suboptimal_flops } fn fake_abs3(a: A) -> f64 { if a.a > 0.0 { a.a } else { -a.a } + //~^ suboptimal_flops } fn fake_abs4(num: f64) -> f64 { if 0.0 >= num { -num } else { num } + //~^ suboptimal_flops } fn fake_abs5(a: A) -> f64 { if a.a < 0.0 { -a.a } else { a.a } + //~^ suboptimal_flops } fn fake_nabs1(num: f64) -> f64 { if num < 0.0 { num } else { -num } + //~^ suboptimal_flops } fn fake_nabs2(num: f64) -> f64 { if 0.0 >= num { num } else { -num } + //~^ suboptimal_flops } fn fake_nabs3(a: A) -> A { A { a: if a.a >= 0.0 { -a.a } else { a.a }, + //~^ suboptimal_flops b: a.b, } } diff --git a/tests/ui/floating_point_abs.stderr b/tests/ui/floating_point_abs.stderr index 0c1f68f3b7fd..f031ac25114d 100644 --- a/tests/ui/floating_point_abs.stderr +++ b/tests/ui/floating_point_abs.stderr @@ -8,43 +8,43 @@ LL | if num >= 0.0 { num } else { -num } = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]` error: manual implementation of `abs` method - --> tests/ui/floating_point_abs.rs:18:5 + --> tests/ui/floating_point_abs.rs:19:5 | LL | if 0.0 < num { num } else { -num } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()` error: manual implementation of `abs` method - --> tests/ui/floating_point_abs.rs:22:5 + --> tests/ui/floating_point_abs.rs:24:5 | LL | if a.a > 0.0 { a.a } else { -a.a } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()` error: manual implementation of `abs` method - --> tests/ui/floating_point_abs.rs:26:5 + --> tests/ui/floating_point_abs.rs:29:5 | LL | if 0.0 >= num { -num } else { num } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()` error: manual implementation of `abs` method - --> tests/ui/floating_point_abs.rs:30:5 + --> tests/ui/floating_point_abs.rs:34:5 | LL | if a.a < 0.0 { -a.a } else { a.a } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()` error: manual implementation of negation of `abs` method - --> tests/ui/floating_point_abs.rs:34:5 + --> tests/ui/floating_point_abs.rs:39:5 | LL | if num < 0.0 { num } else { -num } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()` error: manual implementation of negation of `abs` method - --> tests/ui/floating_point_abs.rs:38:5 + --> tests/ui/floating_point_abs.rs:44:5 | LL | if 0.0 >= num { num } else { -num } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()` error: manual implementation of negation of `abs` method - --> tests/ui/floating_point_abs.rs:43:12 + --> tests/ui/floating_point_abs.rs:50:12 | LL | a: if a.a >= 0.0 { -a.a } else { a.a }, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-a.a.abs()` diff --git a/tests/ui/floating_point_arithmetic_nostd.rs b/tests/ui/floating_point_arithmetic_nostd.rs index 81e4e0380dad..c4456bf870cd 100644 --- a/tests/ui/floating_point_arithmetic_nostd.rs +++ b/tests/ui/floating_point_arithmetic_nostd.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![crate_type = "lib"] #![warn(clippy::imprecise_flops)] #![warn(clippy::suboptimal_flops)] diff --git a/tests/ui/floating_point_exp.fixed b/tests/ui/floating_point_exp.fixed index fbd91cbc9d70..72a6f4fcfbd3 100644 --- a/tests/ui/floating_point_exp.fixed +++ b/tests/ui/floating_point_exp.fixed @@ -6,15 +6,20 @@ fn main() { let x = 2f32; let _ = x.exp_m1(); + //~^ imprecise_flops let _ = x.exp_m1() + 2.0; + //~^ imprecise_flops let _ = (x as f32).exp_m1() + 2.0; + //~^ imprecise_flops // Cases where the lint shouldn't be applied let _ = x.exp() - 2.0; let _ = x.exp() - 1.0 * 2.0; let x = 2f64; let _ = x.exp_m1(); + //~^ imprecise_flops let _ = x.exp_m1() + 2.0; + //~^ imprecise_flops // Cases where the lint shouldn't be applied let _ = x.exp() - 2.0; let _ = x.exp() - 1.0 * 2.0; diff --git a/tests/ui/floating_point_exp.rs b/tests/ui/floating_point_exp.rs index 340bacaf56b5..ce584c038a49 100644 --- a/tests/ui/floating_point_exp.rs +++ b/tests/ui/floating_point_exp.rs @@ -6,15 +6,20 @@ fn main() { let x = 2f32; let _ = x.exp() - 1.0; + //~^ imprecise_flops let _ = x.exp() - 1.0 + 2.0; + //~^ imprecise_flops let _ = (x as f32).exp() - 1.0 + 2.0; + //~^ imprecise_flops // Cases where the lint shouldn't be applied let _ = x.exp() - 2.0; let _ = x.exp() - 1.0 * 2.0; let x = 2f64; let _ = x.exp() - 1.0; + //~^ imprecise_flops let _ = x.exp() - 1.0 + 2.0; + //~^ imprecise_flops // Cases where the lint shouldn't be applied let _ = x.exp() - 2.0; let _ = x.exp() - 1.0 * 2.0; diff --git a/tests/ui/floating_point_exp.stderr b/tests/ui/floating_point_exp.stderr index 6ce67254abc9..7736a8e7ac36 100644 --- a/tests/ui/floating_point_exp.stderr +++ b/tests/ui/floating_point_exp.stderr @@ -8,25 +8,25 @@ LL | let _ = x.exp() - 1.0; = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]` error: (e.pow(x) - 1) can be computed more accurately - --> tests/ui/floating_point_exp.rs:9:13 + --> tests/ui/floating_point_exp.rs:10:13 | LL | let _ = x.exp() - 1.0 + 2.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` error: (e.pow(x) - 1) can be computed more accurately - --> tests/ui/floating_point_exp.rs:10:13 + --> tests/ui/floating_point_exp.rs:12:13 | LL | let _ = (x as f32).exp() - 1.0 + 2.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).exp_m1()` error: (e.pow(x) - 1) can be computed more accurately - --> tests/ui/floating_point_exp.rs:16:13 + --> tests/ui/floating_point_exp.rs:19:13 | LL | let _ = x.exp() - 1.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` error: (e.pow(x) - 1) can be computed more accurately - --> tests/ui/floating_point_exp.rs:17:13 + --> tests/ui/floating_point_exp.rs:21:13 | LL | let _ = x.exp() - 1.0 + 2.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` diff --git a/tests/ui/floating_point_hypot.fixed b/tests/ui/floating_point_hypot.fixed index 75a224440b0d..1fa684e78e0b 100644 --- a/tests/ui/floating_point_hypot.fixed +++ b/tests/ui/floating_point_hypot.fixed @@ -4,8 +4,11 @@ fn main() { let x = 3f32; let y = 4f32; let _ = x.hypot(y); + //~^ imprecise_flops let _ = (x + 1f32).hypot(y); + //~^ imprecise_flops let _ = x.hypot(y); + //~^ imprecise_flops // Cases where the lint shouldn't be applied // TODO: linting this adds some complexity, but could be done let _ = x.mul_add(x, y * y).sqrt(); diff --git a/tests/ui/floating_point_hypot.rs b/tests/ui/floating_point_hypot.rs index ed4dbf6382e7..9b4e74d28d0f 100644 --- a/tests/ui/floating_point_hypot.rs +++ b/tests/ui/floating_point_hypot.rs @@ -4,8 +4,11 @@ fn main() { let x = 3f32; let y = 4f32; let _ = (x * x + y * y).sqrt(); + //~^ imprecise_flops let _ = ((x + 1f32) * (x + 1f32) + y * y).sqrt(); + //~^ imprecise_flops let _ = (x.powi(2) + y.powi(2)).sqrt(); + //~^ imprecise_flops // Cases where the lint shouldn't be applied // TODO: linting this adds some complexity, but could be done let _ = x.mul_add(x, y * y).sqrt(); diff --git a/tests/ui/floating_point_hypot.stderr b/tests/ui/floating_point_hypot.stderr index 8942e86910da..3526df2cf265 100644 --- a/tests/ui/floating_point_hypot.stderr +++ b/tests/ui/floating_point_hypot.stderr @@ -8,13 +8,13 @@ LL | let _ = (x * x + y * y).sqrt(); = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]` error: hypotenuse can be computed more accurately - --> tests/ui/floating_point_hypot.rs:7:13 + --> tests/ui/floating_point_hypot.rs:8:13 | LL | let _ = ((x + 1f32) * (x + 1f32) + y * y).sqrt(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 1f32).hypot(y)` error: hypotenuse can be computed more accurately - --> tests/ui/floating_point_hypot.rs:8:13 + --> tests/ui/floating_point_hypot.rs:10:13 | LL | let _ = (x.powi(2) + y.powi(2)).sqrt(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)` diff --git a/tests/ui/floating_point_log.fixed b/tests/ui/floating_point_log.fixed index 75e9c40a5218..275c9b4a3ab9 100644 --- a/tests/ui/floating_point_log.fixed +++ b/tests/ui/floating_point_log.fixed @@ -9,31 +9,51 @@ const E: f32 = std::f32::consts::E; fn check_log_base() { let x = 1f32; let _ = x.log2(); + //~^ suboptimal_flops let _ = x.log10(); + //~^ suboptimal_flops let _ = x.ln(); + //~^ suboptimal_flops let _ = x.log2(); + //~^ suboptimal_flops let _ = x.ln(); + //~^ suboptimal_flops let _ = (x as f32).log2(); + //~^ suboptimal_flops let x = 1f64; let _ = x.log2(); + //~^ suboptimal_flops let _ = x.log10(); + //~^ suboptimal_flops let _ = x.ln(); + //~^ suboptimal_flops } fn check_ln1p() { let x = 1f32; let _ = 2.0f32.ln_1p(); + //~^ imprecise_flops let _ = 2.0f32.ln_1p(); + //~^ imprecise_flops let _ = x.ln_1p(); + //~^ imprecise_flops let _ = (x / 2.0).ln_1p(); + //~^ imprecise_flops let _ = x.powi(3).ln_1p(); + //~^ imprecise_flops let _ = (x.powi(3) / 2.0).ln_1p(); + //~^ imprecise_flops let _ = (std::f32::consts::E - 1.0).ln_1p(); + //~^ imprecise_flops let _ = x.ln_1p(); + //~^ imprecise_flops let _ = x.powi(3).ln_1p(); + //~^ imprecise_flops let _ = (x + 2.0).ln_1p(); + //~^ imprecise_flops let _ = (x / 2.0).ln_1p(); + //~^ imprecise_flops // Cases where the lint shouldn't be applied let _ = (1.0 + x + 2.0).ln(); let _ = (x + 1.0 + 2.0).ln(); @@ -42,14 +62,23 @@ fn check_ln1p() { let x = 1f64; let _ = 2.0f64.ln_1p(); + //~^ imprecise_flops let _ = 2.0f64.ln_1p(); + //~^ imprecise_flops let _ = x.ln_1p(); + //~^ imprecise_flops let _ = (x / 2.0).ln_1p(); + //~^ imprecise_flops let _ = x.powi(3).ln_1p(); + //~^ imprecise_flops let _ = x.ln_1p(); + //~^ imprecise_flops let _ = x.powi(3).ln_1p(); + //~^ imprecise_flops let _ = (x + 2.0).ln_1p(); + //~^ imprecise_flops let _ = (x / 2.0).ln_1p(); + //~^ imprecise_flops // Cases where the lint shouldn't be applied let _ = (1.0 + x + 2.0).ln(); let _ = (x + 1.0 + 2.0).ln(); diff --git a/tests/ui/floating_point_log.rs b/tests/ui/floating_point_log.rs index d68369a38618..a372ccbb9fb0 100644 --- a/tests/ui/floating_point_log.rs +++ b/tests/ui/floating_point_log.rs @@ -9,31 +9,51 @@ const E: f32 = std::f32::consts::E; fn check_log_base() { let x = 1f32; let _ = x.log(2f32); + //~^ suboptimal_flops let _ = x.log(10f32); + //~^ suboptimal_flops let _ = x.log(std::f32::consts::E); + //~^ suboptimal_flops let _ = x.log(TWO); + //~^ suboptimal_flops let _ = x.log(E); + //~^ suboptimal_flops let _ = (x as f32).log(2f32); + //~^ suboptimal_flops let x = 1f64; let _ = x.log(2f64); + //~^ suboptimal_flops let _ = x.log(10f64); + //~^ suboptimal_flops let _ = x.log(std::f64::consts::E); + //~^ suboptimal_flops } fn check_ln1p() { let x = 1f32; let _ = (1f32 + 2.).ln(); + //~^ imprecise_flops let _ = (1f32 + 2.0).ln(); + //~^ imprecise_flops let _ = (1.0 + x).ln(); + //~^ imprecise_flops let _ = (1.0 + x / 2.0).ln(); + //~^ imprecise_flops let _ = (1.0 + x.powi(3)).ln(); + //~^ imprecise_flops let _ = (1.0 + x.powi(3) / 2.0).ln(); + //~^ imprecise_flops let _ = (1.0 + (std::f32::consts::E - 1.0)).ln(); + //~^ imprecise_flops let _ = (x + 1.0).ln(); + //~^ imprecise_flops let _ = (x.powi(3) + 1.0).ln(); + //~^ imprecise_flops let _ = (x + 2.0 + 1.0).ln(); + //~^ imprecise_flops let _ = (x / 2.0 + 1.0).ln(); + //~^ imprecise_flops // Cases where the lint shouldn't be applied let _ = (1.0 + x + 2.0).ln(); let _ = (x + 1.0 + 2.0).ln(); @@ -42,14 +62,23 @@ fn check_ln1p() { let x = 1f64; let _ = (1f64 + 2.).ln(); + //~^ imprecise_flops let _ = (1f64 + 2.0).ln(); + //~^ imprecise_flops let _ = (1.0 + x).ln(); + //~^ imprecise_flops let _ = (1.0 + x / 2.0).ln(); + //~^ imprecise_flops let _ = (1.0 + x.powi(3)).ln(); + //~^ imprecise_flops let _ = (x + 1.0).ln(); + //~^ imprecise_flops let _ = (x.powi(3) + 1.0).ln(); + //~^ imprecise_flops let _ = (x + 2.0 + 1.0).ln(); + //~^ imprecise_flops let _ = (x / 2.0 + 1.0).ln(); + //~^ imprecise_flops // Cases where the lint shouldn't be applied let _ = (1.0 + x + 2.0).ln(); let _ = (x + 1.0 + 2.0).ln(); diff --git a/tests/ui/floating_point_log.stderr b/tests/ui/floating_point_log.stderr index 19c28de8e39a..e93b3af851cb 100644 --- a/tests/ui/floating_point_log.stderr +++ b/tests/ui/floating_point_log.stderr @@ -8,55 +8,55 @@ LL | let _ = x.log(2f32); = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:12:13 + --> tests/ui/floating_point_log.rs:13:13 | LL | let _ = x.log(10f32); | ^^^^^^^^^^^^ help: consider using: `x.log10()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:13:13 + --> tests/ui/floating_point_log.rs:15:13 | LL | let _ = x.log(std::f32::consts::E); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:14:13 + --> tests/ui/floating_point_log.rs:17:13 | LL | let _ = x.log(TWO); | ^^^^^^^^^^ help: consider using: `x.log2()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:15:13 + --> tests/ui/floating_point_log.rs:19:13 | LL | let _ = x.log(E); | ^^^^^^^^ help: consider using: `x.ln()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:16:13 + --> tests/ui/floating_point_log.rs:21:13 | LL | let _ = (x as f32).log(2f32); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log2()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:19:13 + --> tests/ui/floating_point_log.rs:25:13 | LL | let _ = x.log(2f64); | ^^^^^^^^^^^ help: consider using: `x.log2()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:20:13 + --> tests/ui/floating_point_log.rs:27:13 | LL | let _ = x.log(10f64); | ^^^^^^^^^^^^ help: consider using: `x.log10()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:21:13 + --> tests/ui/floating_point_log.rs:29:13 | LL | let _ = x.log(std::f64::consts::E); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:26:13 + --> tests/ui/floating_point_log.rs:35:13 | LL | let _ = (1f32 + 2.).ln(); | ^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()` @@ -65,95 +65,41 @@ LL | let _ = (1f32 + 2.).ln(); = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:27:13 + --> tests/ui/floating_point_log.rs:37:13 | LL | let _ = (1f32 + 2.0).ln(); | ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:28:13 + --> tests/ui/floating_point_log.rs:39:13 | LL | let _ = (1.0 + x).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:29:13 + --> tests/ui/floating_point_log.rs:41:13 | LL | let _ = (1.0 + x / 2.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:30:13 + --> tests/ui/floating_point_log.rs:43:13 | LL | let _ = (1.0 + x.powi(3)).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:31:13 + --> tests/ui/floating_point_log.rs:45:13 | LL | let _ = (1.0 + x.powi(3) / 2.0).ln(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x.powi(3) / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:32:13 + --> tests/ui/floating_point_log.rs:47:13 | LL | let _ = (1.0 + (std::f32::consts::E - 1.0)).ln(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(std::f32::consts::E - 1.0).ln_1p()` -error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:33:13 - | -LL | let _ = (x + 1.0).ln(); - | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` - -error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:34:13 - | -LL | let _ = (x.powi(3) + 1.0).ln(); - | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` - -error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:35:13 - | -LL | let _ = (x + 2.0 + 1.0).ln(); - | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()` - -error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:36:13 - | -LL | let _ = (x / 2.0 + 1.0).ln(); - | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` - -error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:44:13 - | -LL | let _ = (1f64 + 2.).ln(); - | ^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` - -error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:45:13 - | -LL | let _ = (1f64 + 2.0).ln(); - | ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` - -error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:46:13 - | -LL | let _ = (1.0 + x).ln(); - | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` - -error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:47:13 - | -LL | let _ = (1.0 + x / 2.0).ln(); - | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` - -error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:48:13 - | -LL | let _ = (1.0 + x.powi(3)).ln(); - | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` - error: ln(1 + x) can be computed more accurately --> tests/ui/floating_point_log.rs:49:13 | @@ -161,19 +107,73 @@ LL | let _ = (x + 1.0).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:50:13 + --> tests/ui/floating_point_log.rs:51:13 | LL | let _ = (x.powi(3) + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:51:13 + --> tests/ui/floating_point_log.rs:53:13 | LL | let _ = (x + 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:52:13 + --> tests/ui/floating_point_log.rs:55:13 + | +LL | let _ = (x / 2.0 + 1.0).ln(); + | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` + +error: ln(1 + x) can be computed more accurately + --> tests/ui/floating_point_log.rs:64:13 + | +LL | let _ = (1f64 + 2.).ln(); + | ^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` + +error: ln(1 + x) can be computed more accurately + --> tests/ui/floating_point_log.rs:66:13 + | +LL | let _ = (1f64 + 2.0).ln(); + | ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` + +error: ln(1 + x) can be computed more accurately + --> tests/ui/floating_point_log.rs:68:13 + | +LL | let _ = (1.0 + x).ln(); + | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` + +error: ln(1 + x) can be computed more accurately + --> tests/ui/floating_point_log.rs:70:13 + | +LL | let _ = (1.0 + x / 2.0).ln(); + | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` + +error: ln(1 + x) can be computed more accurately + --> tests/ui/floating_point_log.rs:72:13 + | +LL | let _ = (1.0 + x.powi(3)).ln(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` + +error: ln(1 + x) can be computed more accurately + --> tests/ui/floating_point_log.rs:74:13 + | +LL | let _ = (x + 1.0).ln(); + | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` + +error: ln(1 + x) can be computed more accurately + --> tests/ui/floating_point_log.rs:76:13 + | +LL | let _ = (x.powi(3) + 1.0).ln(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` + +error: ln(1 + x) can be computed more accurately + --> tests/ui/floating_point_log.rs:78:13 + | +LL | let _ = (x + 2.0 + 1.0).ln(); + | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()` + +error: ln(1 + x) can be computed more accurately + --> tests/ui/floating_point_log.rs:80:13 | LL | let _ = (x / 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` diff --git a/tests/ui/floating_point_logbase.fixed b/tests/ui/floating_point_logbase.fixed index 451673d109c6..d03882c774c0 100644 --- a/tests/ui/floating_point_logbase.fixed +++ b/tests/ui/floating_point_logbase.fixed @@ -5,10 +5,15 @@ fn main() { let x = 3f32; let y = 5f32; let _ = x.log(y); + //~^ suboptimal_flops let _ = (x as f32).log(y); + //~^ suboptimal_flops let _ = x.log(y); + //~^ suboptimal_flops let _ = x.log(y); + //~^ suboptimal_flops let _ = x.log(y); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = x.ln() / y.powf(3.2); let _ = x.powf(3.2) / y.powf(3.2); diff --git a/tests/ui/floating_point_logbase.rs b/tests/ui/floating_point_logbase.rs index c309114599d9..c29f4deb3738 100644 --- a/tests/ui/floating_point_logbase.rs +++ b/tests/ui/floating_point_logbase.rs @@ -5,10 +5,15 @@ fn main() { let x = 3f32; let y = 5f32; let _ = x.ln() / y.ln(); + //~^ suboptimal_flops let _ = (x as f32).ln() / y.ln(); + //~^ suboptimal_flops let _ = x.log2() / y.log2(); + //~^ suboptimal_flops let _ = x.log10() / y.log10(); + //~^ suboptimal_flops let _ = x.log(5f32) / y.log(5f32); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = x.ln() / y.powf(3.2); let _ = x.powf(3.2) / y.powf(3.2); diff --git a/tests/ui/floating_point_logbase.stderr b/tests/ui/floating_point_logbase.stderr index 8dfc57b133c6..1f30e5cbc177 100644 --- a/tests/ui/floating_point_logbase.stderr +++ b/tests/ui/floating_point_logbase.stderr @@ -8,25 +8,25 @@ LL | let _ = x.ln() / y.ln(); = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]` error: log base can be expressed more clearly - --> tests/ui/floating_point_logbase.rs:8:13 + --> tests/ui/floating_point_logbase.rs:9:13 | LL | let _ = (x as f32).ln() / y.ln(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log(y)` error: log base can be expressed more clearly - --> tests/ui/floating_point_logbase.rs:9:13 + --> tests/ui/floating_point_logbase.rs:11:13 | LL | let _ = x.log2() / y.log2(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` error: log base can be expressed more clearly - --> tests/ui/floating_point_logbase.rs:10:13 + --> tests/ui/floating_point_logbase.rs:13:13 | LL | let _ = x.log10() / y.log10(); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` error: log base can be expressed more clearly - --> tests/ui/floating_point_logbase.rs:11:13 + --> tests/ui/floating_point_logbase.rs:15:13 | LL | let _ = x.log(5f32) / y.log(5f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` diff --git a/tests/ui/floating_point_mul_add.fixed b/tests/ui/floating_point_mul_add.fixed index 164aac2601a5..83aeddb2a1f4 100644 --- a/tests/ui/floating_point_mul_add.fixed +++ b/tests/ui/floating_point_mul_add.fixed @@ -17,23 +17,36 @@ fn main() { let d: f64 = 0.0001; let _ = a.mul_add(b, c); + //~^ suboptimal_flops let _ = a.mul_add(b, -c); + //~^ suboptimal_flops let _ = a.mul_add(b, c); + //~^ suboptimal_flops let _ = a.mul_add(-b, c); + //~^ suboptimal_flops let _ = 2.0f64.mul_add(4.0, a); + //~^ suboptimal_flops let _ = 2.0f64.mul_add(4., a); + //~^ suboptimal_flops let _ = a.mul_add(b, c); + //~^ suboptimal_flops let _ = a.mul_add(b, c); + //~^ suboptimal_flops let _ = (a * b).mul_add(c, d); + //~^ suboptimal_flops let _ = a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c)) + c; + //~^ suboptimal_flops let _ = 1234.567_f64.mul_add(45.67834_f64, 0.0004_f64); + //~^ suboptimal_flops let _ = a.mul_add(a, b).sqrt(); + //~^ suboptimal_flops let u = 1usize; let _ = b.mul_add(-(u as f64), a); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = (a * a + b * b).sqrt(); diff --git a/tests/ui/floating_point_mul_add.rs b/tests/ui/floating_point_mul_add.rs index ae024b7f224b..039ee8d053fc 100644 --- a/tests/ui/floating_point_mul_add.rs +++ b/tests/ui/floating_point_mul_add.rs @@ -17,23 +17,36 @@ fn main() { let d: f64 = 0.0001; let _ = a * b + c; + //~^ suboptimal_flops let _ = a * b - c; + //~^ suboptimal_flops let _ = c + a * b; + //~^ suboptimal_flops let _ = c - a * b; + //~^ suboptimal_flops let _ = a + 2.0 * 4.0; + //~^ suboptimal_flops let _ = a + 2. * 4.; + //~^ suboptimal_flops let _ = (a * b) + c; + //~^ suboptimal_flops let _ = c + (a * b); + //~^ suboptimal_flops let _ = a * b * c + d; + //~^ suboptimal_flops let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c; + //~^ suboptimal_flops let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64; + //~^ suboptimal_flops let _ = (a * a + b).sqrt(); + //~^ suboptimal_flops let u = 1usize; let _ = a - (b * u as f64); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = (a * a + b * b).sqrt(); diff --git a/tests/ui/floating_point_mul_add.stderr b/tests/ui/floating_point_mul_add.stderr index 9c75909f7158..6482127bcc00 100644 --- a/tests/ui/floating_point_mul_add.stderr +++ b/tests/ui/floating_point_mul_add.stderr @@ -8,73 +8,73 @@ LL | let _ = a * b + c; = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:20:13 + --> tests/ui/floating_point_mul_add.rs:21:13 | LL | let _ = a * b - c; | ^^^^^^^^^ help: consider using: `a.mul_add(b, -c)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:21:13 + --> tests/ui/floating_point_mul_add.rs:23:13 | LL | let _ = c + a * b; | ^^^^^^^^^ help: consider using: `a.mul_add(b, c)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:22:13 + --> tests/ui/floating_point_mul_add.rs:25:13 | LL | let _ = c - a * b; | ^^^^^^^^^ help: consider using: `a.mul_add(-b, c)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:23:13 + --> tests/ui/floating_point_mul_add.rs:27:13 | LL | let _ = a + 2.0 * 4.0; | ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, a)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:24:13 + --> tests/ui/floating_point_mul_add.rs:29:13 | LL | let _ = a + 2. * 4.; | ^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4., a)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:26:13 + --> tests/ui/floating_point_mul_add.rs:32:13 | LL | let _ = (a * b) + c; | ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:27:13 + --> tests/ui/floating_point_mul_add.rs:34:13 | LL | let _ = c + (a * b); | ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:28:13 + --> tests/ui/floating_point_mul_add.rs:36:13 | LL | let _ = a * b * c + d; | ^^^^^^^^^^^^^ help: consider using: `(a * b).mul_add(c, d)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:30:13 + --> tests/ui/floating_point_mul_add.rs:39:13 | LL | let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c))` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:31:13 + --> tests/ui/floating_point_mul_add.rs:41:13 | LL | let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:33:13 + --> tests/ui/floating_point_mul_add.rs:44:13 | LL | let _ = (a * a + b).sqrt(); | ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_mul_add.rs:36:13 + --> tests/ui/floating_point_mul_add.rs:48:13 | LL | let _ = a - (b * u as f64); | ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)` diff --git a/tests/ui/floating_point_powf.fixed b/tests/ui/floating_point_powf.fixed index 25f09a637951..293df9bfe9b9 100644 --- a/tests/ui/floating_point_powf.fixed +++ b/tests/ui/floating_point_powf.fixed @@ -6,24 +6,43 @@ fn main() { let x = 3f32; let _ = x.exp2(); + //~^ suboptimal_flops let _ = 3.1f32.exp2(); + //~^ suboptimal_flops let _ = (-3.1f32).exp2(); + //~^ suboptimal_flops let _ = x.exp(); + //~^ suboptimal_flops let _ = 3.1f32.exp(); + //~^ suboptimal_flops let _ = (-3.1f32).exp(); + //~^ suboptimal_flops let _ = x.sqrt(); + //~^ suboptimal_flops let _ = x.cbrt(); + //~^ imprecise_flops let _ = (x as f32).cbrt(); + //~^ imprecise_flops let _ = x.powi(3); + //~^ suboptimal_flops let _ = x.powi(-2); + //~^ suboptimal_flops let _ = x.powi(16_777_215); + //~^ suboptimal_flops let _ = x.powi(-16_777_215); + //~^ suboptimal_flops let _ = (x as f32).powi(-16_777_215); + //~^ suboptimal_flops let _ = (x as f32).powi(3); + //~^ suboptimal_flops let _ = (1.5_f32 + 1.0).cbrt(); + //~^ imprecise_flops let _ = 1.5_f64.cbrt(); + //~^ imprecise_flops let _ = 1.5_f64.sqrt(); + //~^ suboptimal_flops let _ = 1.5_f64.powi(3); + //~^ suboptimal_flops macro_rules! m { ($e:expr) => { @@ -32,6 +51,7 @@ fn main() { } let _ = (1f32 + m!(2.0)).exp2(); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = x.powf(2.1); @@ -41,17 +61,29 @@ fn main() { let x = 3f64; let _ = x.exp2(); + //~^ suboptimal_flops let _ = 3.1f64.exp2(); + //~^ suboptimal_flops let _ = (-3.1f64).exp2(); + //~^ suboptimal_flops let _ = x.exp(); + //~^ suboptimal_flops let _ = 3.1f64.exp(); + //~^ suboptimal_flops let _ = (-3.1f64).exp(); + //~^ suboptimal_flops let _ = x.sqrt(); + //~^ suboptimal_flops let _ = x.cbrt(); + //~^ imprecise_flops let _ = x.powi(3); + //~^ suboptimal_flops let _ = x.powi(-2); + //~^ suboptimal_flops let _ = x.powi(-2_147_483_648); + //~^ suboptimal_flops let _ = x.powi(2_147_483_647); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = x.powf(2.1); let _ = x.powf(-2.1); diff --git a/tests/ui/floating_point_powf.rs b/tests/ui/floating_point_powf.rs index 9e9878de4bad..5b1940a369a5 100644 --- a/tests/ui/floating_point_powf.rs +++ b/tests/ui/floating_point_powf.rs @@ -6,24 +6,43 @@ fn main() { let x = 3f32; let _ = 2f32.powf(x); + //~^ suboptimal_flops let _ = 2f32.powf(3.1); + //~^ suboptimal_flops let _ = 2f32.powf(-3.1); + //~^ suboptimal_flops let _ = std::f32::consts::E.powf(x); + //~^ suboptimal_flops let _ = std::f32::consts::E.powf(3.1); + //~^ suboptimal_flops let _ = std::f32::consts::E.powf(-3.1); + //~^ suboptimal_flops let _ = x.powf(1.0 / 2.0); + //~^ suboptimal_flops let _ = x.powf(1.0 / 3.0); + //~^ imprecise_flops let _ = (x as f32).powf(1.0 / 3.0); + //~^ imprecise_flops let _ = x.powf(3.0); + //~^ suboptimal_flops let _ = x.powf(-2.0); + //~^ suboptimal_flops let _ = x.powf(16_777_215.0); + //~^ suboptimal_flops let _ = x.powf(-16_777_215.0); + //~^ suboptimal_flops let _ = (x as f32).powf(-16_777_215.0); + //~^ suboptimal_flops let _ = (x as f32).powf(3.0); + //~^ suboptimal_flops let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0); + //~^ imprecise_flops let _ = 1.5_f64.powf(1.0 / 3.0); + //~^ imprecise_flops let _ = 1.5_f64.powf(1.0 / 2.0); + //~^ suboptimal_flops let _ = 1.5_f64.powf(3.0); + //~^ suboptimal_flops macro_rules! m { ($e:expr) => { @@ -32,6 +51,7 @@ fn main() { } let _ = 2f32.powf(1f32 + m!(2.0)); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = x.powf(2.1); @@ -41,17 +61,29 @@ fn main() { let x = 3f64; let _ = 2f64.powf(x); + //~^ suboptimal_flops let _ = 2f64.powf(3.1); + //~^ suboptimal_flops let _ = 2f64.powf(-3.1); + //~^ suboptimal_flops let _ = std::f64::consts::E.powf(x); + //~^ suboptimal_flops let _ = std::f64::consts::E.powf(3.1); + //~^ suboptimal_flops let _ = std::f64::consts::E.powf(-3.1); + //~^ suboptimal_flops let _ = x.powf(1.0 / 2.0); + //~^ suboptimal_flops let _ = x.powf(1.0 / 3.0); + //~^ imprecise_flops let _ = x.powf(3.0); + //~^ suboptimal_flops let _ = x.powf(-2.0); + //~^ suboptimal_flops let _ = x.powf(-2_147_483_648.0); + //~^ suboptimal_flops let _ = x.powf(2_147_483_647.0); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = x.powf(2.1); let _ = x.powf(-2.1); diff --git a/tests/ui/floating_point_powf.stderr b/tests/ui/floating_point_powf.stderr index c944f14fa34d..dec30a94cc78 100644 --- a/tests/ui/floating_point_powf.stderr +++ b/tests/ui/floating_point_powf.stderr @@ -8,43 +8,43 @@ LL | let _ = 2f32.powf(x); = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:9:13 + --> tests/ui/floating_point_powf.rs:10:13 | LL | let _ = 2f32.powf(3.1); | ^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:10:13 + --> tests/ui/floating_point_powf.rs:12:13 | LL | let _ = 2f32.powf(-3.1); | ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:11:13 + --> tests/ui/floating_point_powf.rs:14:13 | LL | let _ = std::f32::consts::E.powf(x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:12:13 + --> tests/ui/floating_point_powf.rs:16:13 | LL | let _ = std::f32::consts::E.powf(3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:13:13 + --> tests/ui/floating_point_powf.rs:18:13 | LL | let _ = std::f32::consts::E.powf(-3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp()` error: square-root of a number can be computed more efficiently and accurately - --> tests/ui/floating_point_powf.rs:14:13 + --> tests/ui/floating_point_powf.rs:20:13 | LL | let _ = x.powf(1.0 / 2.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:15:13 + --> tests/ui/floating_point_powf.rs:22:13 | LL | let _ = x.powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()` @@ -53,145 +53,145 @@ LL | let _ = x.powf(1.0 / 3.0); = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:16:13 + --> tests/ui/floating_point_powf.rs:24:13 | LL | let _ = (x as f32).powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).cbrt()` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:17:13 + --> tests/ui/floating_point_powf.rs:26:13 | LL | let _ = x.powf(3.0); | ^^^^^^^^^^^ help: consider using: `x.powi(3)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:18:13 + --> tests/ui/floating_point_powf.rs:28:13 | LL | let _ = x.powf(-2.0); | ^^^^^^^^^^^^ help: consider using: `x.powi(-2)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:19:13 + --> tests/ui/floating_point_powf.rs:30:13 | LL | let _ = x.powf(16_777_215.0); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(16_777_215)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:20:13 + --> tests/ui/floating_point_powf.rs:32:13 | LL | let _ = x.powf(-16_777_215.0); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-16_777_215)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:21:13 + --> tests/ui/floating_point_powf.rs:34:13 | LL | let _ = (x as f32).powf(-16_777_215.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(-16_777_215)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:22:13 + --> tests/ui/floating_point_powf.rs:36:13 | LL | let _ = (x as f32).powf(3.0); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(3)` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:23:13 + --> tests/ui/floating_point_powf.rs:38:13 | LL | let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1.5_f32 + 1.0).cbrt()` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:24:13 + --> tests/ui/floating_point_powf.rs:40:13 | LL | let _ = 1.5_f64.powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.cbrt()` error: square-root of a number can be computed more efficiently and accurately - --> tests/ui/floating_point_powf.rs:25:13 + --> tests/ui/floating_point_powf.rs:42:13 | LL | let _ = 1.5_f64.powf(1.0 / 2.0); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.sqrt()` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:26:13 + --> tests/ui/floating_point_powf.rs:44:13 | LL | let _ = 1.5_f64.powf(3.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.powi(3)` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:34:13 + --> tests/ui/floating_point_powf.rs:53:13 | LL | let _ = 2f32.powf(1f32 + m!(2.0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1f32 + m!(2.0)).exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:43:13 + --> tests/ui/floating_point_powf.rs:63:13 | LL | let _ = 2f64.powf(x); | ^^^^^^^^^^^^ help: consider using: `x.exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:44:13 + --> tests/ui/floating_point_powf.rs:65:13 | LL | let _ = 2f64.powf(3.1); | ^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:45:13 + --> tests/ui/floating_point_powf.rs:67:13 | LL | let _ = 2f64.powf(-3.1); | ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:46:13 + --> tests/ui/floating_point_powf.rs:69:13 | LL | let _ = std::f64::consts::E.powf(x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:47:13 + --> tests/ui/floating_point_powf.rs:71:13 | LL | let _ = std::f64::consts::E.powf(3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:48:13 + --> tests/ui/floating_point_powf.rs:73:13 | LL | let _ = std::f64::consts::E.powf(-3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp()` error: square-root of a number can be computed more efficiently and accurately - --> tests/ui/floating_point_powf.rs:49:13 + --> tests/ui/floating_point_powf.rs:75:13 | LL | let _ = x.powf(1.0 / 2.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:50:13 + --> tests/ui/floating_point_powf.rs:77:13 | LL | let _ = x.powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:51:13 + --> tests/ui/floating_point_powf.rs:79:13 | LL | let _ = x.powf(3.0); | ^^^^^^^^^^^ help: consider using: `x.powi(3)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:52:13 + --> tests/ui/floating_point_powf.rs:81:13 | LL | let _ = x.powf(-2.0); | ^^^^^^^^^^^^ help: consider using: `x.powi(-2)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:53:13 + --> tests/ui/floating_point_powf.rs:83:13 | LL | let _ = x.powf(-2_147_483_648.0); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-2_147_483_648)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:54:13 + --> tests/ui/floating_point_powf.rs:85:13 | LL | let _ = x.powf(2_147_483_647.0); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2_147_483_647)` diff --git a/tests/ui/floating_point_powi.fixed b/tests/ui/floating_point_powi.fixed index cb033c899f31..5f0618ab1c72 100644 --- a/tests/ui/floating_point_powi.fixed +++ b/tests/ui/floating_point_powi.fixed @@ -7,20 +7,34 @@ fn main() { let y = 4f32; let _ = x.mul_add(x, y); + //~^ suboptimal_flops let _ = x.mul_add(x, -y); + //~^ suboptimal_flops let _ = y.mul_add(y, x); + //~^ suboptimal_flops let _ = y.mul_add(-y, x); + //~^ suboptimal_flops let _ = (y as f32).mul_add(y as f32, x); + //~^ suboptimal_flops let _ = x.mul_add(x, y).sqrt(); + //~^ suboptimal_flops let _ = y.mul_add(y, x).sqrt(); + //~^ suboptimal_flops let _ = (x - 1.0).mul_add(x - 1.0, -y); + //~^ suboptimal_flops let _ = (x - 1.0).mul_add(x - 1.0, -y) + 3.0; + //~^ suboptimal_flops let _ = (x - 1.0).mul_add(x - 1.0, -(y + 3.0)); + //~^ suboptimal_flops let _ = (y + 1.0).mul_add(-(y + 1.0), x); + //~^ suboptimal_flops let _ = (3.0 * y).mul_add(-(3.0 * y), x); + //~^ suboptimal_flops let _ = (y + 1.0 + x).mul_add(-(y + 1.0 + x), x); + //~^ suboptimal_flops let _ = (y + 1.0 + 2.0).mul_add(-(y + 1.0 + 2.0), x); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = x.powi(2); diff --git a/tests/ui/floating_point_powi.rs b/tests/ui/floating_point_powi.rs index f02e0e8ddb36..bb97a8eddf33 100644 --- a/tests/ui/floating_point_powi.rs +++ b/tests/ui/floating_point_powi.rs @@ -7,20 +7,34 @@ fn main() { let y = 4f32; let _ = x.powi(2) + y; + //~^ suboptimal_flops let _ = x.powi(2) - y; + //~^ suboptimal_flops let _ = x + y.powi(2); + //~^ suboptimal_flops let _ = x - y.powi(2); + //~^ suboptimal_flops let _ = x + (y as f32).powi(2); + //~^ suboptimal_flops let _ = (x.powi(2) + y).sqrt(); + //~^ suboptimal_flops let _ = (x + y.powi(2)).sqrt(); + //~^ suboptimal_flops let _ = (x - 1.0).powi(2) - y; + //~^ suboptimal_flops let _ = (x - 1.0).powi(2) - y + 3.0; + //~^ suboptimal_flops let _ = (x - 1.0).powi(2) - (y + 3.0); + //~^ suboptimal_flops let _ = x - (y + 1.0).powi(2); + //~^ suboptimal_flops let _ = x - (3.0 * y).powi(2); + //~^ suboptimal_flops let _ = x - (y + 1.0 + x).powi(2); + //~^ suboptimal_flops let _ = x - (y + 1.0 + 2.0).powi(2); + //~^ suboptimal_flops // Cases where the lint shouldn't be applied let _ = x.powi(2); diff --git a/tests/ui/floating_point_powi.stderr b/tests/ui/floating_point_powi.stderr index dfed20cb8c5a..211589382911 100644 --- a/tests/ui/floating_point_powi.stderr +++ b/tests/ui/floating_point_powi.stderr @@ -8,79 +8,79 @@ LL | let _ = x.powi(2) + y; = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:10:13 + --> tests/ui/floating_point_powi.rs:11:13 | LL | let _ = x.powi(2) - y; | ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, -y)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:11:13 + --> tests/ui/floating_point_powi.rs:13:13 | LL | let _ = x + y.powi(2); | ^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:12:13 + --> tests/ui/floating_point_powi.rs:15:13 | LL | let _ = x - y.powi(2); | ^^^^^^^^^^^^^ help: consider using: `y.mul_add(-y, x)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:13:13 + --> tests/ui/floating_point_powi.rs:17:13 | LL | let _ = x + (y as f32).powi(2); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y as f32).mul_add(y as f32, x)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:14:13 + --> tests/ui/floating_point_powi.rs:19:13 | LL | let _ = (x.powi(2) + y).sqrt(); | ^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:15:13 + --> tests/ui/floating_point_powi.rs:21:13 | LL | let _ = (x + y.powi(2)).sqrt(); | ^^^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:17:13 + --> tests/ui/floating_point_powi.rs:24:13 | LL | let _ = (x - 1.0).powi(2) - y; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x - 1.0).mul_add(x - 1.0, -y)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:18:13 + --> tests/ui/floating_point_powi.rs:26:13 | LL | let _ = (x - 1.0).powi(2) - y + 3.0; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x - 1.0).mul_add(x - 1.0, -y)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:19:13 + --> tests/ui/floating_point_powi.rs:28:13 | LL | let _ = (x - 1.0).powi(2) - (y + 3.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x - 1.0).mul_add(x - 1.0, -(y + 3.0))` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:20:13 + --> tests/ui/floating_point_powi.rs:30:13 | LL | let _ = x - (y + 1.0).powi(2); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y + 1.0).mul_add(-(y + 1.0), x)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:21:13 + --> tests/ui/floating_point_powi.rs:32:13 | LL | let _ = x - (3.0 * y).powi(2); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(3.0 * y).mul_add(-(3.0 * y), x)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:22:13 + --> tests/ui/floating_point_powi.rs:34:13 | LL | let _ = x - (y + 1.0 + x).powi(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y + 1.0 + x).mul_add(-(y + 1.0 + x), x)` error: multiply and add expressions can be calculated more efficiently and accurately - --> tests/ui/floating_point_powi.rs:23:13 + --> tests/ui/floating_point_powi.rs:36:13 | LL | let _ = x - (y + 1.0 + 2.0).powi(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y + 1.0 + 2.0).mul_add(-(y + 1.0 + 2.0), x)` diff --git a/tests/ui/floating_point_rad.fixed b/tests/ui/floating_point_rad.fixed index 2f93d233cb40..61f3ccc8bd02 100644 --- a/tests/ui/floating_point_rad.fixed +++ b/tests/ui/floating_point_rad.fixed @@ -8,17 +8,25 @@ pub const fn const_context() { pub fn issue9391(degrees: i64) { let _ = (degrees as f64).to_radians(); + //~^ suboptimal_flops let _ = (degrees as f64).to_degrees(); + //~^ suboptimal_flops } fn main() { let x = 3f32; let _ = x.to_degrees(); + //~^ suboptimal_flops let _ = 90.0_f64.to_degrees(); + //~^ suboptimal_flops let _ = 90.5_f64.to_degrees(); + //~^ suboptimal_flops let _ = x.to_radians(); + //~^ suboptimal_flops let _ = 90.0_f64.to_radians(); + //~^ suboptimal_flops let _ = 90.5_f64.to_radians(); + //~^ suboptimal_flops // let _ = 90.5 * 80. * std::f32::consts::PI / 180f32; // Cases where the lint shouldn't be applied let _ = x * 90f32 / std::f32::consts::PI; diff --git a/tests/ui/floating_point_rad.rs b/tests/ui/floating_point_rad.rs index 9690effc4e10..f57359e15fe1 100644 --- a/tests/ui/floating_point_rad.rs +++ b/tests/ui/floating_point_rad.rs @@ -8,17 +8,25 @@ pub const fn const_context() { pub fn issue9391(degrees: i64) { let _ = degrees as f64 * std::f64::consts::PI / 180.0; + //~^ suboptimal_flops let _ = degrees as f64 * 180.0 / std::f64::consts::PI; + //~^ suboptimal_flops } fn main() { let x = 3f32; let _ = x * 180f32 / std::f32::consts::PI; + //~^ suboptimal_flops let _ = 90. * 180f64 / std::f64::consts::PI; + //~^ suboptimal_flops let _ = 90.5 * 180f64 / std::f64::consts::PI; + //~^ suboptimal_flops let _ = x * std::f32::consts::PI / 180f32; + //~^ suboptimal_flops let _ = 90. * std::f32::consts::PI / 180f32; + //~^ suboptimal_flops let _ = 90.5 * std::f32::consts::PI / 180f32; + //~^ suboptimal_flops // let _ = 90.5 * 80. * std::f32::consts::PI / 180f32; // Cases where the lint shouldn't be applied let _ = x * 90f32 / std::f32::consts::PI; diff --git a/tests/ui/floating_point_rad.stderr b/tests/ui/floating_point_rad.stderr index b834f5374e0b..b888edd59bfd 100644 --- a/tests/ui/floating_point_rad.stderr +++ b/tests/ui/floating_point_rad.stderr @@ -8,43 +8,43 @@ LL | let _ = degrees as f64 * std::f64::consts::PI / 180.0; = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]` error: conversion to degrees can be done more accurately - --> tests/ui/floating_point_rad.rs:11:13 + --> tests/ui/floating_point_rad.rs:12:13 | LL | let _ = degrees as f64 * 180.0 / std::f64::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_degrees()` error: conversion to degrees can be done more accurately - --> tests/ui/floating_point_rad.rs:16:13 + --> tests/ui/floating_point_rad.rs:18:13 | LL | let _ = x * 180f32 / std::f32::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()` error: conversion to degrees can be done more accurately - --> tests/ui/floating_point_rad.rs:17:13 + --> tests/ui/floating_point_rad.rs:20:13 | LL | let _ = 90. * 180f64 / std::f64::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_degrees()` error: conversion to degrees can be done more accurately - --> tests/ui/floating_point_rad.rs:18:13 + --> tests/ui/floating_point_rad.rs:22:13 | LL | let _ = 90.5 * 180f64 / std::f64::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_degrees()` error: conversion to radians can be done more accurately - --> tests/ui/floating_point_rad.rs:19:13 + --> tests/ui/floating_point_rad.rs:24:13 | LL | let _ = x * std::f32::consts::PI / 180f32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()` error: conversion to radians can be done more accurately - --> tests/ui/floating_point_rad.rs:20:13 + --> tests/ui/floating_point_rad.rs:26:13 | LL | let _ = 90. * std::f32::consts::PI / 180f32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_radians()` error: conversion to radians can be done more accurately - --> tests/ui/floating_point_rad.rs:21:13 + --> tests/ui/floating_point_rad.rs:28:13 | LL | let _ = 90.5 * std::f32::consts::PI / 180f32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_radians()` diff --git a/tests/ui/fn_to_numeric_cast.64bit.stderr b/tests/ui/fn_to_numeric_cast.64bit.stderr index 58f55f19a745..1c2a0dab10b5 100644 --- a/tests/ui/fn_to_numeric_cast.64bit.stderr +++ b/tests/ui/fn_to_numeric_cast.64bit.stderr @@ -8,19 +8,19 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]` error: casting function pointer `foo` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:11:13 + --> tests/ui/fn_to_numeric_cast.rs:12:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:12:13 + --> tests/ui/fn_to_numeric_cast.rs:14:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:13:13 + --> tests/ui/fn_to_numeric_cast.rs:16:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ help: try: `foo as usize` @@ -29,115 +29,115 @@ LL | let _ = foo as i64; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]` error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:14:13 + --> tests/ui/fn_to_numeric_cast.rs:18:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:15:13 + --> tests/ui/fn_to_numeric_cast.rs:20:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:17:13 + --> tests/ui/fn_to_numeric_cast.rs:23:13 | LL | let _ = foo as u8; | ^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:18:13 + --> tests/ui/fn_to_numeric_cast.rs:25:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:19:13 + --> tests/ui/fn_to_numeric_cast.rs:27:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:20:13 + --> tests/ui/fn_to_numeric_cast.rs:29:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:21:13 + --> tests/ui/fn_to_numeric_cast.rs:31:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `abc` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:34:13 + --> tests/ui/fn_to_numeric_cast.rs:45:13 | LL | let _ = abc as i8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:35:13 + --> tests/ui/fn_to_numeric_cast.rs:47:13 | LL | let _ = abc as i16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:36:13 + --> tests/ui/fn_to_numeric_cast.rs:49:13 | LL | let _ = abc as i32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:37:13 + --> tests/ui/fn_to_numeric_cast.rs:51:13 | LL | let _ = abc as i64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:38:13 + --> tests/ui/fn_to_numeric_cast.rs:53:13 | LL | let _ = abc as i128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:39:13 + --> tests/ui/fn_to_numeric_cast.rs:55:13 | LL | let _ = abc as isize; | ^^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:41:13 + --> tests/ui/fn_to_numeric_cast.rs:58:13 | LL | let _ = abc as u8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:42:13 + --> tests/ui/fn_to_numeric_cast.rs:60:13 | LL | let _ = abc as u16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:43:13 + --> tests/ui/fn_to_numeric_cast.rs:62:13 | LL | let _ = abc as u32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:44:13 + --> tests/ui/fn_to_numeric_cast.rs:64:13 | LL | let _ = abc as u64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:45:13 + --> tests/ui/fn_to_numeric_cast.rs:66:13 | LL | let _ = abc as u128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `f` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:52:5 + --> tests/ui/fn_to_numeric_cast.rs:74:5 | LL | f as i32 | ^^^^^^^^ help: try: `f as usize` diff --git a/tests/ui/fn_to_numeric_cast.rs b/tests/ui/fn_to_numeric_cast.rs index 9501eb5da4b2..70be37c0f959 100644 --- a/tests/ui/fn_to_numeric_cast.rs +++ b/tests/ui/fn_to_numeric_cast.rs @@ -8,17 +8,28 @@ fn foo() -> String { fn test_function_to_numeric_cast() { let _ = foo as i8; + //~^ fn_to_numeric_cast_with_truncation let _ = foo as i16; + //~^ fn_to_numeric_cast_with_truncation let _ = foo as i32; + //~^ fn_to_numeric_cast_with_truncation let _ = foo as i64; + //~^ fn_to_numeric_cast let _ = foo as i128; + //~^ fn_to_numeric_cast let _ = foo as isize; + //~^ fn_to_numeric_cast let _ = foo as u8; + //~^ fn_to_numeric_cast_with_truncation let _ = foo as u16; + //~^ fn_to_numeric_cast_with_truncation let _ = foo as u32; + //~^ fn_to_numeric_cast_with_truncation let _ = foo as u64; + //~^ fn_to_numeric_cast let _ = foo as u128; + //~^ fn_to_numeric_cast // Casting to usize is OK and should not warn let _ = foo as usize; @@ -32,17 +43,28 @@ fn test_function_var_to_numeric_cast() { let abc: fn() -> String = foo; let _ = abc as i8; + //~^ fn_to_numeric_cast_with_truncation let _ = abc as i16; + //~^ fn_to_numeric_cast_with_truncation let _ = abc as i32; + //~^ fn_to_numeric_cast_with_truncation let _ = abc as i64; + //~^ fn_to_numeric_cast let _ = abc as i128; + //~^ fn_to_numeric_cast let _ = abc as isize; + //~^ fn_to_numeric_cast let _ = abc as u8; + //~^ fn_to_numeric_cast_with_truncation let _ = abc as u16; + //~^ fn_to_numeric_cast_with_truncation let _ = abc as u32; + //~^ fn_to_numeric_cast_with_truncation let _ = abc as u64; + //~^ fn_to_numeric_cast let _ = abc as u128; + //~^ fn_to_numeric_cast // Casting to usize is OK and should not warn let _ = abc as usize; @@ -50,6 +72,7 @@ fn test_function_var_to_numeric_cast() { fn fn_with_fn_args(f: fn(i32) -> i32) -> i32 { f as i32 + //~^ fn_to_numeric_cast_with_truncation } fn main() {} diff --git a/tests/ui/fn_to_numeric_cast_any.rs b/tests/ui/fn_to_numeric_cast_any.rs index 95abc0ac68dd..3359e24c2b6a 100644 --- a/tests/ui/fn_to_numeric_cast_any.rs +++ b/tests/ui/fn_to_numeric_cast_any.rs @@ -21,58 +21,75 @@ impl Trait for Struct {} fn fn_pointer_to_integer() { let _ = foo as i8; - //~^ ERROR: casting function pointer `foo` to `i8` - //~| NOTE: `-D clippy::fn-to-numeric-cast-any` implied by `-D warnings` + //~^ fn_to_numeric_cast_any + + let _ = foo as i16; - //~^ ERROR: casting function pointer `foo` to `i16` + //~^ fn_to_numeric_cast_any + let _ = foo as i32; - //~^ ERROR: casting function pointer `foo` to `i32` + //~^ fn_to_numeric_cast_any + let _ = foo as i64; - //~^ ERROR: casting function pointer `foo` to `i64` + //~^ fn_to_numeric_cast_any + let _ = foo as i128; - //~^ ERROR: casting function pointer `foo` to `i128` + //~^ fn_to_numeric_cast_any + let _ = foo as isize; - //~^ ERROR: casting function pointer `foo` to `isize` + //~^ fn_to_numeric_cast_any + let _ = foo as u8; - //~^ ERROR: casting function pointer `foo` to `u8` + //~^ fn_to_numeric_cast_any + let _ = foo as u16; - //~^ ERROR: casting function pointer `foo` to `u16` + //~^ fn_to_numeric_cast_any + let _ = foo as u32; - //~^ ERROR: casting function pointer `foo` to `u32` + //~^ fn_to_numeric_cast_any + let _ = foo as u64; - //~^ ERROR: casting function pointer `foo` to `u64` + //~^ fn_to_numeric_cast_any + let _ = foo as u128; - //~^ ERROR: casting function pointer `foo` to `u128` + //~^ fn_to_numeric_cast_any + let _ = foo as usize; - //~^ ERROR: casting function pointer `foo` to `usize` + //~^ fn_to_numeric_cast_any + } fn static_method_to_integer() { let _ = Struct::static_method as usize; - //~^ ERROR: casting function pointer `Struct::static_method` to `usize` + //~^ fn_to_numeric_cast_any + } fn fn_with_fn_arg(f: fn(i32) -> u32) -> usize { f as usize - //~^ ERROR: casting function pointer `f` to `usize` + //~^ fn_to_numeric_cast_any + } fn fn_with_generic_static_trait_method() -> usize { T::static_method as usize - //~^ ERROR: casting function pointer `T::static_method` to `usize` + //~^ fn_to_numeric_cast_any + } fn closure_to_fn_to_integer() { let clos = |x| x * 2_u32; let _ = (clos as fn(u32) -> u32) as usize; - //~^ ERROR: casting function pointer `(clos as fn(u32) -> u32)` to `usize` + //~^ fn_to_numeric_cast_any + } fn fn_to_raw_ptr() { let _ = foo as *const (); - //~^ ERROR: casting function pointer `foo` to `*const ()` + //~^ fn_to_numeric_cast_any + } fn cast_fn_to_self() { diff --git a/tests/ui/fn_to_numeric_cast_any.stderr b/tests/ui/fn_to_numeric_cast_any.stderr index a05b7138bc99..c6a7b2403395 100644 --- a/tests/ui/fn_to_numeric_cast_any.stderr +++ b/tests/ui/fn_to_numeric_cast_any.stderr @@ -12,7 +12,7 @@ LL | let _ = foo() as i8; | ~~~~~~~~~~~ error: casting function pointer `foo` to `i16` - --> tests/ui/fn_to_numeric_cast_any.rs:26:13 + --> tests/ui/fn_to_numeric_cast_any.rs:27:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = foo() as i16; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `i32` - --> tests/ui/fn_to_numeric_cast_any.rs:28:13 + --> tests/ui/fn_to_numeric_cast_any.rs:30:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = foo() as i32; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast_any.rs:30:13 + --> tests/ui/fn_to_numeric_cast_any.rs:33:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _ = foo() as i64; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast_any.rs:32:13 + --> tests/ui/fn_to_numeric_cast_any.rs:36:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _ = foo() as i128; | ~~~~~~~~~~~~~ error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast_any.rs:34:13 + --> tests/ui/fn_to_numeric_cast_any.rs:39:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let _ = foo() as isize; | ~~~~~~~~~~~~~~ error: casting function pointer `foo` to `u8` - --> tests/ui/fn_to_numeric_cast_any.rs:37:13 + --> tests/ui/fn_to_numeric_cast_any.rs:43:13 | LL | let _ = foo as u8; | ^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _ = foo() as u8; | ~~~~~~~~~~~ error: casting function pointer `foo` to `u16` - --> tests/ui/fn_to_numeric_cast_any.rs:39:13 + --> tests/ui/fn_to_numeric_cast_any.rs:46:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = foo() as u16; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `u32` - --> tests/ui/fn_to_numeric_cast_any.rs:41:13 + --> tests/ui/fn_to_numeric_cast_any.rs:49:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let _ = foo() as u32; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast_any.rs:43:13 + --> tests/ui/fn_to_numeric_cast_any.rs:52:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _ = foo() as u64; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast_any.rs:45:13 + --> tests/ui/fn_to_numeric_cast_any.rs:55:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let _ = foo() as u128; | ~~~~~~~~~~~~~ error: casting function pointer `foo` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:47:13 + --> tests/ui/fn_to_numeric_cast_any.rs:58:13 | LL | let _ = foo as usize; | ^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let _ = foo() as usize; | ~~~~~~~~~~~~~~ error: casting function pointer `Struct::static_method` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:52:13 + --> tests/ui/fn_to_numeric_cast_any.rs:64:13 | LL | let _ = Struct::static_method as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | let _ = Struct::static_method() as usize; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting function pointer `f` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:57:5 + --> tests/ui/fn_to_numeric_cast_any.rs:70:5 | LL | f as usize | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | f() as usize | error: casting function pointer `T::static_method` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:62:5 + --> tests/ui/fn_to_numeric_cast_any.rs:76:5 | LL | T::static_method as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | T::static_method() as usize | error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:69:13 + --> tests/ui/fn_to_numeric_cast_any.rs:84:13 | LL | let _ = (clos as fn(u32) -> u32) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | let _ = (clos as fn(u32) -> u32)() as usize; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting function pointer `foo` to `*const ()` - --> tests/ui/fn_to_numeric_cast_any.rs:74:13 + --> tests/ui/fn_to_numeric_cast_any.rs:90:13 | LL | let _ = foo as *const (); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/for_kv_map.fixed b/tests/ui/for_kv_map.fixed index 1733b29128fe..402098e9394b 100644 --- a/tests/ui/for_kv_map.fixed +++ b/tests/ui/for_kv_map.fixed @@ -7,14 +7,16 @@ use std::rc::Rc; fn main() { let m: HashMap = HashMap::new(); for v in m.values() { - //~^ ERROR: you seem to want to iterate on a map's values - //~| NOTE: `-D clippy::for-kv-map` implied by `-D warnings` + //~^ for_kv_map + + let _v = v; } let m: Rc> = Rc::new(HashMap::new()); for v in (*m).values() { - //~^ ERROR: you seem to want to iterate on a map's values + //~^ for_kv_map + let _v = v; // Here the `*` is not actually necessary, but the test tests that we don't // suggest @@ -23,27 +25,31 @@ fn main() { let mut m: HashMap = HashMap::new(); for v in m.values_mut() { - //~^ ERROR: you seem to want to iterate on a map's values + //~^ for_kv_map + let _v = v; } let m: &mut HashMap = &mut HashMap::new(); for v in (*m).values_mut() { - //~^ ERROR: you seem to want to iterate on a map's values + //~^ for_kv_map + let _v = v; } let m: HashMap = HashMap::new(); let rm = &m; for k in rm.keys() { - //~^ ERROR: you seem to want to iterate on a map's keys + //~^ for_kv_map + let _k = k; } let m: HashMap = HashMap::new(); let rm = &m; 'label: for k in rm.keys() { - //~^ ERROR: you seem to want to iterate on a map's keys + //~^ for_kv_map + let _k = k; if *k == 0u64 { break 'label; diff --git a/tests/ui/for_kv_map.rs b/tests/ui/for_kv_map.rs index de465a7c8e6e..407590747a4b 100644 --- a/tests/ui/for_kv_map.rs +++ b/tests/ui/for_kv_map.rs @@ -7,14 +7,16 @@ use std::rc::Rc; fn main() { let m: HashMap = HashMap::new(); for (_, v) in &m { - //~^ ERROR: you seem to want to iterate on a map's values - //~| NOTE: `-D clippy::for-kv-map` implied by `-D warnings` + //~^ for_kv_map + + let _v = v; } let m: Rc> = Rc::new(HashMap::new()); for (_, v) in &*m { - //~^ ERROR: you seem to want to iterate on a map's values + //~^ for_kv_map + let _v = v; // Here the `*` is not actually necessary, but the test tests that we don't // suggest @@ -23,27 +25,31 @@ fn main() { let mut m: HashMap = HashMap::new(); for (_, v) in &mut m { - //~^ ERROR: you seem to want to iterate on a map's values + //~^ for_kv_map + let _v = v; } let m: &mut HashMap = &mut HashMap::new(); for (_, v) in &mut *m { - //~^ ERROR: you seem to want to iterate on a map's values + //~^ for_kv_map + let _v = v; } let m: HashMap = HashMap::new(); let rm = &m; for (k, _value) in rm { - //~^ ERROR: you seem to want to iterate on a map's keys + //~^ for_kv_map + let _k = k; } let m: HashMap = HashMap::new(); let rm = &m; 'label: for (k, _value) in rm { - //~^ ERROR: you seem to want to iterate on a map's keys + //~^ for_kv_map + let _k = k; if *k == 0u64 { break 'label; diff --git a/tests/ui/for_kv_map.stderr b/tests/ui/for_kv_map.stderr index adcc3ab8fdb9..5c28da81a961 100644 --- a/tests/ui/for_kv_map.stderr +++ b/tests/ui/for_kv_map.stderr @@ -12,7 +12,7 @@ LL | for v in m.values() { | ~ ~~~~~~~~~~ error: you seem to want to iterate on a map's values - --> tests/ui/for_kv_map.rs:16:19 + --> tests/ui/for_kv_map.rs:17:19 | LL | for (_, v) in &*m { | ^^^ @@ -23,7 +23,7 @@ LL | for v in (*m).values() { | ~ ~~~~~~~~~~~~~ error: you seem to want to iterate on a map's values - --> tests/ui/for_kv_map.rs:25:19 + --> tests/ui/for_kv_map.rs:27:19 | LL | for (_, v) in &mut m { | ^^^^^^ @@ -34,7 +34,7 @@ LL | for v in m.values_mut() { | ~ ~~~~~~~~~~~~~~ error: you seem to want to iterate on a map's values - --> tests/ui/for_kv_map.rs:31:19 + --> tests/ui/for_kv_map.rs:34:19 | LL | for (_, v) in &mut *m { | ^^^^^^^ @@ -45,7 +45,7 @@ LL | for v in (*m).values_mut() { | ~ ~~~~~~~~~~~~~~~~~ error: you seem to want to iterate on a map's keys - --> tests/ui/for_kv_map.rs:38:24 + --> tests/ui/for_kv_map.rs:42:24 | LL | for (k, _value) in rm { | ^^ @@ -56,7 +56,7 @@ LL | for k in rm.keys() { | ~ ~~~~~~~~~ error: you seem to want to iterate on a map's keys - --> tests/ui/for_kv_map.rs:45:32 + --> tests/ui/for_kv_map.rs:50:32 | LL | 'label: for (k, _value) in rm { | ^^ diff --git a/tests/ui/forget_non_drop.rs b/tests/ui/forget_non_drop.rs index 2459f51a38da..a69fa0f20359 100644 --- a/tests/ui/forget_non_drop.rs +++ b/tests/ui/forget_non_drop.rs @@ -11,7 +11,8 @@ fn main() { struct Foo; // Lint forget(Foo); - //~^ ERROR: call to `std::mem::forget` with a value that does not implement `Drop`. Fo + //~^ forget_non_drop + struct Bar; impl Drop for Bar { @@ -23,7 +24,8 @@ fn main() { struct Baz(T); // Lint forget(Baz(Foo)); - //~^ ERROR: call to `std::mem::forget` with a value that does not implement `Drop`. Fo + //~^ forget_non_drop + // Don't lint forget(Baz(Bar)); } diff --git a/tests/ui/forget_non_drop.stderr b/tests/ui/forget_non_drop.stderr index e121984154c7..0bff152a7132 100644 --- a/tests/ui/forget_non_drop.stderr +++ b/tests/ui/forget_non_drop.stderr @@ -13,13 +13,13 @@ LL | forget(Foo); = help: to override `-D warnings` add `#[allow(clippy::forget_non_drop)]` error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it - --> tests/ui/forget_non_drop.rs:25:5 + --> tests/ui/forget_non_drop.rs:26:5 | LL | forget(Baz(Foo)); | ^^^^^^^^^^^^^^^^ | note: argument has type `main::Baz` - --> tests/ui/forget_non_drop.rs:25:12 + --> tests/ui/forget_non_drop.rs:26:12 | LL | forget(Baz(Foo)); | ^^^^^^^^ diff --git a/tests/ui/format.fixed b/tests/ui/format.fixed index 3dc8eb79ba28..16437c62094a 100644 --- a/tests/ui/format.fixed +++ b/tests/ui/format.fixed @@ -18,14 +18,19 @@ macro_rules! foo { fn main() { "foo".to_string(); + //~^ useless_format "{}".to_string(); + //~^ useless_format "{} abc {}".to_string(); + //~^ useless_format r##"foo {} " bar"##.to_string(); let _ = String::new(); + //~^ useless_format "foo".to_string(); + //~^ useless_format format!("{:?}", "foo"); // Don't warn about `Debug`. format!("{:8}", "foo"); format!("{:width$}", "foo", width = 8); @@ -34,6 +39,7 @@ fn main() { let arg = String::new(); arg.to_string(); + //~^ useless_format format!("{:?}", arg); // Don't warn about debug. format!("{:8}", arg); format!("{:width$}", arg, width = 8); @@ -64,28 +70,36 @@ fn main() { format!("{:.prec$}", "foo", prec = 10); 42.to_string(); + //~^ useless_format let x = std::path::PathBuf::from("/bar/foo/qux"); x.display().to_string(); + //~^ useless_format // False positive let a = "foo".to_string(); let _ = Some(a + "bar"); + //~^ useless_format // Wrap it with braces let v: Vec = vec!["foo".to_string(), "bar".to_string()]; let _s: String = (&*v.join("\n")).to_string(); + //~^ useless_format format!("prepend {:+}", "s"); // Issue #8290 let x = "foo"; let _ = x.to_string(); + //~^ useless_format let _ = format!("{x:?}"); // Don't lint on debug let _ = x.to_string(); + //~^ useless_format // Issue #9234 let abc = "abc"; let _ = abc.to_string(); + //~^ useless_format let xx = "xx"; let _ = xx.to_string(); + //~^ useless_format } diff --git a/tests/ui/format.rs b/tests/ui/format.rs index eaf33c2a6c92..b40eb9d1eb9e 100644 --- a/tests/ui/format.rs +++ b/tests/ui/format.rs @@ -18,16 +18,22 @@ macro_rules! foo { fn main() { format!("foo"); + //~^ useless_format format!("{{}}"); + //~^ useless_format format!("{{}} abc {{}}"); + //~^ useless_format format!( + //~^ useless_format r##"foo {{}} " bar"## ); let _ = format!(""); + //~^ useless_format format!("{}", "foo"); + //~^ useless_format format!("{:?}", "foo"); // Don't warn about `Debug`. format!("{:8}", "foo"); format!("{:width$}", "foo", width = 8); @@ -36,6 +42,7 @@ fn main() { let arg = String::new(); format!("{}", arg); + //~^ useless_format format!("{:?}", arg); // Don't warn about debug. format!("{:8}", arg); format!("{:width$}", arg, width = 8); @@ -66,28 +73,36 @@ fn main() { format!("{:.prec$}", "foo", prec = 10); format!("{}", 42.to_string()); + //~^ useless_format let x = std::path::PathBuf::from("/bar/foo/qux"); format!("{}", x.display().to_string()); + //~^ useless_format // False positive let a = "foo".to_string(); let _ = Some(format!("{}", a + "bar")); + //~^ useless_format // Wrap it with braces let v: Vec = vec!["foo".to_string(), "bar".to_string()]; let _s: String = format!("{}", &*v.join("\n")); + //~^ useless_format format!("prepend {:+}", "s"); // Issue #8290 let x = "foo"; let _ = format!("{x}"); + //~^ useless_format let _ = format!("{x:?}"); // Don't lint on debug let _ = format!("{y}", y = x); + //~^ useless_format // Issue #9234 let abc = "abc"; let _ = format!("{abc}"); + //~^ useless_format let xx = "xx"; let _ = format!("{xx}"); + //~^ useless_format } diff --git a/tests/ui/format.stderr b/tests/ui/format.stderr index 1368c8cd77e0..da990d32cb80 100644 --- a/tests/ui/format.stderr +++ b/tests/ui/format.stderr @@ -8,21 +8,22 @@ LL | format!("foo"); = help: to override `-D warnings` add `#[allow(clippy::useless_format)]` error: useless use of `format!` - --> tests/ui/format.rs:21:5 + --> tests/ui/format.rs:22:5 | LL | format!("{{}}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()` error: useless use of `format!` - --> tests/ui/format.rs:22:5 + --> tests/ui/format.rs:24:5 | LL | format!("{{}} abc {{}}"); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()` error: useless use of `format!` - --> tests/ui/format.rs:23:5 + --> tests/ui/format.rs:26:5 | LL | / format!( +LL | | LL | | r##"foo {{}} LL | | " bar"## LL | | ); @@ -35,67 +36,67 @@ LL ~ " bar"##.to_string(); | error: useless use of `format!` - --> tests/ui/format.rs:28:13 + --> tests/ui/format.rs:32:13 | LL | let _ = format!(""); | ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()` error: useless use of `format!` - --> tests/ui/format.rs:30:5 + --> tests/ui/format.rs:35:5 | LL | format!("{}", "foo"); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` error: useless use of `format!` - --> tests/ui/format.rs:38:5 + --> tests/ui/format.rs:44:5 | LL | format!("{}", arg); | ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()` error: useless use of `format!` - --> tests/ui/format.rs:68:5 + --> tests/ui/format.rs:75:5 | LL | format!("{}", 42.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()` error: useless use of `format!` - --> tests/ui/format.rs:70:5 + --> tests/ui/format.rs:78:5 | LL | format!("{}", x.display().to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()` error: useless use of `format!` - --> tests/ui/format.rs:74:18 + --> tests/ui/format.rs:83:18 | LL | let _ = Some(format!("{}", a + "bar")); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"` error: useless use of `format!` - --> tests/ui/format.rs:78:22 + --> tests/ui/format.rs:88:22 | LL | let _s: String = format!("{}", &*v.join("\n")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("\n")).to_string()` error: useless use of `format!` - --> tests/ui/format.rs:84:13 + --> tests/ui/format.rs:95:13 | LL | let _ = format!("{x}"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> tests/ui/format.rs:86:13 + --> tests/ui/format.rs:98:13 | LL | let _ = format!("{y}", y = x); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> tests/ui/format.rs:90:13 + --> tests/ui/format.rs:103:13 | LL | let _ = format!("{abc}"); | ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()` error: useless use of `format!` - --> tests/ui/format.rs:92:13 + --> tests/ui/format.rs:106:13 | LL | let _ = format!("{xx}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()` diff --git a/tests/ui/format_args.fixed b/tests/ui/format_args.fixed index 20d1e3d90504..075450451b24 100644 --- a/tests/ui/format_args.fixed +++ b/tests/ui/format_args.fixed @@ -75,36 +75,58 @@ fn main() { let x_ref = &x; let _ = format!("error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args let _ = write!( stdout(), "error: something failed at {}", Location::caller() + //~^ to_string_in_format_args ); let _ = writeln!( stdout(), "error: something failed at {}", Location::caller() + //~^ to_string_in_format_args ); print!("error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args println!("error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args eprint!("error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args eprintln!("error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args let _ = format_args!("error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args assert!(true, "error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args assert_eq!(0, 0, "error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args assert_ne!(0, 0, "error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args panic!("error: something failed at {}", Location::caller()); + //~^ to_string_in_format_args println!("{}", *X(1)); + //~^ to_string_in_format_args println!("{}", ***Y(&X(1))); + //~^ to_string_in_format_args println!("{}", Z(1)); + //~^ to_string_in_format_args println!("{}", **x); + //~^ to_string_in_format_args println!("{}", ***x_ref); + //~^ to_string_in_format_args // https://github.com/rust-lang/rust-clippy/issues/7903 println!("{foo}{bar}", foo = "foo", bar = "bar"); + //~^ to_string_in_format_args println!("{foo}{bar}", foo = "foo", bar = "bar"); + //~^ to_string_in_format_args println!("{foo}{bar}", bar = "bar", foo = "foo"); + //~^ to_string_in_format_args println!("{foo}{bar}", bar = "bar", foo = "foo"); + //~^ to_string_in_format_args println!("{}", my_other_macro!()); + //~^ to_string_in_format_args // negative tests println!("error: something failed at {}", Somewhere.to_string()); @@ -117,7 +139,9 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/7903 println!("{foo}{foo:?}", foo = "foo".to_string()); print!("{}", (Location::caller())); + //~^ to_string_in_format_args print!("{}", ((Location::caller()))); + //~^ to_string_in_format_args } fn issue8643(vendor_id: usize, product_id: usize, name: &str) { @@ -146,6 +170,7 @@ mod issue_8855 { let b = A {}; let x = format!("{} {}", a, b); + //~^ to_string_in_format_args dbg!(x); let x = format!("{:>6} {:>6}", a, b.to_string()); @@ -160,6 +185,7 @@ mod issue_9256 { fn print_substring(original: &str) { assert!(original.len() > 10); println!("{}", &original[..10]); + //~^ to_string_in_format_args } fn main() { diff --git a/tests/ui/format_args.rs b/tests/ui/format_args.rs index 18ab223db78a..4d7a018732c7 100644 --- a/tests/ui/format_args.rs +++ b/tests/ui/format_args.rs @@ -75,36 +75,58 @@ fn main() { let x_ref = &x; let _ = format!("error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args let _ = write!( stdout(), "error: something failed at {}", Location::caller().to_string() + //~^ to_string_in_format_args ); let _ = writeln!( stdout(), "error: something failed at {}", Location::caller().to_string() + //~^ to_string_in_format_args ); print!("error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args println!("error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args eprint!("error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args eprintln!("error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args let _ = format_args!("error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args assert!(true, "error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args assert_eq!(0, 0, "error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args assert_ne!(0, 0, "error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args panic!("error: something failed at {}", Location::caller().to_string()); + //~^ to_string_in_format_args println!("{}", X(1).to_string()); + //~^ to_string_in_format_args println!("{}", Y(&X(1)).to_string()); + //~^ to_string_in_format_args println!("{}", Z(1).to_string()); + //~^ to_string_in_format_args println!("{}", x.to_string()); + //~^ to_string_in_format_args println!("{}", x_ref.to_string()); + //~^ to_string_in_format_args // https://github.com/rust-lang/rust-clippy/issues/7903 println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar"); + //~^ to_string_in_format_args println!("{foo}{bar}", foo = "foo", bar = "bar".to_string()); + //~^ to_string_in_format_args println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo"); + //~^ to_string_in_format_args println!("{foo}{bar}", bar = "bar", foo = "foo".to_string()); + //~^ to_string_in_format_args println!("{}", my_other_macro!().to_string()); + //~^ to_string_in_format_args // negative tests println!("error: something failed at {}", Somewhere.to_string()); @@ -117,7 +139,9 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/7903 println!("{foo}{foo:?}", foo = "foo".to_string()); print!("{}", (Location::caller().to_string())); + //~^ to_string_in_format_args print!("{}", ((Location::caller()).to_string())); + //~^ to_string_in_format_args } fn issue8643(vendor_id: usize, product_id: usize, name: &str) { @@ -146,6 +170,7 @@ mod issue_8855 { let b = A {}; let x = format!("{} {}", a, b.to_string()); + //~^ to_string_in_format_args dbg!(x); let x = format!("{:>6} {:>6}", a, b.to_string()); @@ -160,6 +185,7 @@ mod issue_9256 { fn print_substring(original: &str) { assert!(original.len() > 10); println!("{}", original[..10].to_string()); + //~^ to_string_in_format_args } fn main() { diff --git a/tests/ui/format_args.stderr b/tests/ui/format_args.stderr index 91a45e270081..68c3c9c322d9 100644 --- a/tests/ui/format_args.stderr +++ b/tests/ui/format_args.stderr @@ -8,151 +8,151 @@ LL | let _ = format!("error: something failed at {}", Location::caller().to_ = help: to override `-D warnings` add `#[allow(clippy::to_string_in_format_args)]` error: `to_string` applied to a type that implements `Display` in `write!` args - --> tests/ui/format_args.rs:81:27 + --> tests/ui/format_args.rs:82:27 | LL | Location::caller().to_string() | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `writeln!` args - --> tests/ui/format_args.rs:86:27 + --> tests/ui/format_args.rs:88:27 | LL | Location::caller().to_string() | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `print!` args - --> tests/ui/format_args.rs:88:63 + --> tests/ui/format_args.rs:91:63 | LL | print!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:89:65 + --> tests/ui/format_args.rs:93:65 | LL | println!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `eprint!` args - --> tests/ui/format_args.rs:90:64 + --> tests/ui/format_args.rs:95:64 | LL | eprint!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `eprintln!` args - --> tests/ui/format_args.rs:91:66 + --> tests/ui/format_args.rs:97:66 | LL | eprintln!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `format_args!` args - --> tests/ui/format_args.rs:92:77 + --> tests/ui/format_args.rs:99:77 | LL | let _ = format_args!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `assert!` args - --> tests/ui/format_args.rs:93:70 + --> tests/ui/format_args.rs:101:70 | LL | assert!(true, "error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `assert_eq!` args - --> tests/ui/format_args.rs:94:73 + --> tests/ui/format_args.rs:103:73 | LL | assert_eq!(0, 0, "error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `assert_ne!` args - --> tests/ui/format_args.rs:95:73 + --> tests/ui/format_args.rs:105:73 | LL | assert_ne!(0, 0, "error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `panic!` args - --> tests/ui/format_args.rs:96:63 + --> tests/ui/format_args.rs:107:63 | LL | panic!("error: something failed at {}", Location::caller().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:97:20 + --> tests/ui/format_args.rs:109:20 | LL | println!("{}", X(1).to_string()); | ^^^^^^^^^^^^^^^^ help: use this: `*X(1)` error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:98:20 + --> tests/ui/format_args.rs:111:20 | LL | println!("{}", Y(&X(1)).to_string()); | ^^^^^^^^^^^^^^^^^^^^ help: use this: `***Y(&X(1))` error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:99:24 + --> tests/ui/format_args.rs:113:24 | LL | println!("{}", Z(1).to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:100:20 + --> tests/ui/format_args.rs:115:20 | LL | println!("{}", x.to_string()); | ^^^^^^^^^^^^^ help: use this: `**x` error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:101:20 + --> tests/ui/format_args.rs:117:20 | LL | println!("{}", x_ref.to_string()); | ^^^^^^^^^^^^^^^^^ help: use this: `***x_ref` error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:103:39 + --> tests/ui/format_args.rs:120:39 | LL | println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar"); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:104:52 + --> tests/ui/format_args.rs:122:52 | LL | println!("{foo}{bar}", foo = "foo", bar = "bar".to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:105:39 + --> tests/ui/format_args.rs:124:39 | LL | println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo"); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:106:52 + --> tests/ui/format_args.rs:126:52 | LL | println!("{foo}{bar}", bar = "bar", foo = "foo".to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:107:37 + --> tests/ui/format_args.rs:128:37 | LL | println!("{}", my_other_macro!().to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `print!` args - --> tests/ui/format_args.rs:119:37 + --> tests/ui/format_args.rs:141:37 | LL | print!("{}", (Location::caller().to_string())); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `print!` args - --> tests/ui/format_args.rs:120:39 + --> tests/ui/format_args.rs:143:39 | LL | print!("{}", ((Location::caller()).to_string())); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `format!` args - --> tests/ui/format_args.rs:148:38 + --> tests/ui/format_args.rs:172:38 | LL | let x = format!("{} {}", a, b.to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:162:24 + --> tests/ui/format_args.rs:187:24 | LL | println!("{}", original[..10].to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]` diff --git a/tests/ui/format_args_unfixable.rs b/tests/ui/format_args_unfixable.rs index 7590de3751a8..adbdaca7313b 100644 --- a/tests/ui/format_args_unfixable.rs +++ b/tests/ui/format_args_unfixable.rs @@ -24,49 +24,67 @@ fn main() { let x = 'x'; println!("error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `println!` args + //~^ format_in_format_args + println!("{}: {}", error, format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `println!` args + //~^ format_in_format_args + println!("{:?}: {}", error, format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `println!` args + //~^ format_in_format_args + println!("{{}}: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `println!` args + //~^ format_in_format_args + println!(r#"error: "{}""#, format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `println!` args + //~^ format_in_format_args + println!("error: {}", format!(r#"something failed at "{}""#, Location::caller())); - //~^ ERROR: `format!` in `println!` args + //~^ format_in_format_args + println!("error: {}", format!("something failed at {} {0}", Location::caller())); - //~^ ERROR: `format!` in `println!` args + //~^ format_in_format_args + let _ = format!("error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `format!` args + //~^ format_in_format_args + let _ = write!( - //~^ ERROR: `format!` in `write!` args + //~^ format_in_format_args + stdout(), "error: {}", format!("something failed at {}", Location::caller()) ); let _ = writeln!( - //~^ ERROR: `format!` in `writeln!` args + //~^ format_in_format_args + stdout(), "error: {}", format!("something failed at {}", Location::caller()) ); print!("error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `print!` args + //~^ format_in_format_args + eprint!("error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `eprint!` args + //~^ format_in_format_args + eprintln!("error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `eprintln!` args + //~^ format_in_format_args + let _ = format_args!("error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `format_args!` args + //~^ format_in_format_args + assert!(true, "error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `assert!` args + //~^ format_in_format_args + assert_eq!(0, 0, "error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `assert_eq!` args + //~^ format_in_format_args + assert_ne!(0, 0, "error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `assert_ne!` args + //~^ format_in_format_args + panic!("error: {}", format!("something failed at {}", Location::caller())); - //~^ ERROR: `format!` in `panic!` args + //~^ format_in_format_args + // negative tests println!("error: {}", format_args!("something failed at {}", Location::caller())); @@ -134,17 +152,24 @@ fn user_format() { let x = 'x'; usr_println!(true, "error: {}", format!("boom at {}", Location::caller())); - //~^ ERROR: `format!` in `usr_println!` args + //~^ format_in_format_args + usr_println!(true, "{}: {}", error, format!("boom at {}", Location::caller())); - //~^ ERROR: `format!` in `usr_println!` args + //~^ format_in_format_args + usr_println!(true, "{:?}: {}", error, format!("boom at {}", Location::caller())); - //~^ ERROR: `format!` in `usr_println!` args + //~^ format_in_format_args + usr_println!(true, "{{}}: {}", format!("boom at {}", Location::caller())); - //~^ ERROR: `format!` in `usr_println!` args + //~^ format_in_format_args + usr_println!(true, r#"error: "{}""#, format!("boom at {}", Location::caller())); - //~^ ERROR: `format!` in `usr_println!` args + //~^ format_in_format_args + usr_println!(true, "error: {}", format!(r#"boom at "{}""#, Location::caller())); - //~^ ERROR: `format!` in `usr_println!` args + //~^ format_in_format_args + usr_println!(true, "error: {}", format!("boom at {} {0}", Location::caller())); - //~^ ERROR: `format!` in `usr_println!` args + //~^ format_in_format_args + } diff --git a/tests/ui/format_args_unfixable.stderr b/tests/ui/format_args_unfixable.stderr index 1b4b683fd6c6..82af72229066 100644 --- a/tests/ui/format_args_unfixable.stderr +++ b/tests/ui/format_args_unfixable.stderr @@ -10,7 +10,7 @@ LL | println!("error: {}", format!("something failed at {}", Location::calle = help: to override `-D warnings` add `#[allow(clippy::format_in_format_args)]` error: `format!` in `println!` args - --> tests/ui/format_args_unfixable.rs:28:5 + --> tests/ui/format_args_unfixable.rs:29:5 | LL | println!("{}: {}", error, format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | println!("{}: {}", error, format!("something failed at {}", Location::c = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> tests/ui/format_args_unfixable.rs:30:5 + --> tests/ui/format_args_unfixable.rs:32:5 | LL | println!("{:?}: {}", error, format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | println!("{:?}: {}", error, format!("something failed at {}", Location: = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> tests/ui/format_args_unfixable.rs:32:5 + --> tests/ui/format_args_unfixable.rs:35:5 | LL | println!("{{}}: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | println!("{{}}: {}", format!("something failed at {}", Location::caller = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> tests/ui/format_args_unfixable.rs:34:5 + --> tests/ui/format_args_unfixable.rs:38:5 | LL | println!(r#"error: "{}""#, format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | println!(r#"error: "{}""#, format!("something failed at {}", Location:: = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> tests/ui/format_args_unfixable.rs:36:5 + --> tests/ui/format_args_unfixable.rs:41:5 | LL | println!("error: {}", format!(r#"something failed at "{}""#, Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | println!("error: {}", format!(r#"something failed at "{}""#, Location:: = help: or consider changing `format!` to `format_args!` error: `format!` in `println!` args - --> tests/ui/format_args_unfixable.rs:38:5 + --> tests/ui/format_args_unfixable.rs:44:5 | LL | println!("error: {}", format!("something failed at {} {0}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | println!("error: {}", format!("something failed at {} {0}", Location::c = help: or consider changing `format!` to `format_args!` error: `format!` in `format!` args - --> tests/ui/format_args_unfixable.rs:40:13 + --> tests/ui/format_args_unfixable.rs:47:13 | LL | let _ = format!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,11 +73,12 @@ LL | let _ = format!("error: {}", format!("something failed at {}", Location = help: or consider changing `format!` to `format_args!` error: `format!` in `write!` args - --> tests/ui/format_args_unfixable.rs:42:13 + --> tests/ui/format_args_unfixable.rs:50:13 | LL | let _ = write!( | _____________^ LL | | +LL | | LL | | stdout(), LL | | "error: {}", LL | | format!("something failed at {}", Location::caller()) @@ -88,11 +89,12 @@ LL | | ); = help: or consider changing `format!` to `format_args!` error: `format!` in `writeln!` args - --> tests/ui/format_args_unfixable.rs:48:13 + --> tests/ui/format_args_unfixable.rs:57:13 | LL | let _ = writeln!( | _____________^ LL | | +LL | | LL | | stdout(), LL | | "error: {}", LL | | format!("something failed at {}", Location::caller()) @@ -103,7 +105,7 @@ LL | | ); = help: or consider changing `format!` to `format_args!` error: `format!` in `print!` args - --> tests/ui/format_args_unfixable.rs:54:5 + --> tests/ui/format_args_unfixable.rs:64:5 | LL | print!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +114,7 @@ LL | print!("error: {}", format!("something failed at {}", Location::caller( = help: or consider changing `format!` to `format_args!` error: `format!` in `eprint!` args - --> tests/ui/format_args_unfixable.rs:56:5 + --> tests/ui/format_args_unfixable.rs:67:5 | LL | eprint!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +123,7 @@ LL | eprint!("error: {}", format!("something failed at {}", Location::caller = help: or consider changing `format!` to `format_args!` error: `format!` in `eprintln!` args - --> tests/ui/format_args_unfixable.rs:58:5 + --> tests/ui/format_args_unfixable.rs:70:5 | LL | eprintln!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -130,7 +132,7 @@ LL | eprintln!("error: {}", format!("something failed at {}", Location::call = help: or consider changing `format!` to `format_args!` error: `format!` in `format_args!` args - --> tests/ui/format_args_unfixable.rs:60:13 + --> tests/ui/format_args_unfixable.rs:73:13 | LL | let _ = format_args!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,7 +141,7 @@ LL | let _ = format_args!("error: {}", format!("something failed at {}", Loc = help: or consider changing `format!` to `format_args!` error: `format!` in `assert!` args - --> tests/ui/format_args_unfixable.rs:62:5 + --> tests/ui/format_args_unfixable.rs:76:5 | LL | assert!(true, "error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +150,7 @@ LL | assert!(true, "error: {}", format!("something failed at {}", Location:: = help: or consider changing `format!` to `format_args!` error: `format!` in `assert_eq!` args - --> tests/ui/format_args_unfixable.rs:64:5 + --> tests/ui/format_args_unfixable.rs:79:5 | LL | assert_eq!(0, 0, "error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +159,7 @@ LL | assert_eq!(0, 0, "error: {}", format!("something failed at {}", Locatio = help: or consider changing `format!` to `format_args!` error: `format!` in `assert_ne!` args - --> tests/ui/format_args_unfixable.rs:66:5 + --> tests/ui/format_args_unfixable.rs:82:5 | LL | assert_ne!(0, 0, "error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +168,7 @@ LL | assert_ne!(0, 0, "error: {}", format!("something failed at {}", Locatio = help: or consider changing `format!` to `format_args!` error: `format!` in `panic!` args - --> tests/ui/format_args_unfixable.rs:68:5 + --> tests/ui/format_args_unfixable.rs:85:5 | LL | panic!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -175,7 +177,7 @@ LL | panic!("error: {}", format!("something failed at {}", Location::caller( = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:136:5 + --> tests/ui/format_args_unfixable.rs:154:5 | LL | usr_println!(true, "error: {}", format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -184,7 +186,7 @@ LL | usr_println!(true, "error: {}", format!("boom at {}", Location::caller( = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:138:5 + --> tests/ui/format_args_unfixable.rs:157:5 | LL | usr_println!(true, "{}: {}", error, format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +195,7 @@ LL | usr_println!(true, "{}: {}", error, format!("boom at {}", Location::cal = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:140:5 + --> tests/ui/format_args_unfixable.rs:160:5 | LL | usr_println!(true, "{:?}: {}", error, format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -202,7 +204,7 @@ LL | usr_println!(true, "{:?}: {}", error, format!("boom at {}", Location::c = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:142:5 + --> tests/ui/format_args_unfixable.rs:163:5 | LL | usr_println!(true, "{{}}: {}", format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +213,7 @@ LL | usr_println!(true, "{{}}: {}", format!("boom at {}", Location::caller() = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:144:5 + --> tests/ui/format_args_unfixable.rs:166:5 | LL | usr_println!(true, r#"error: "{}""#, format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +222,7 @@ LL | usr_println!(true, r#"error: "{}""#, format!("boom at {}", Location::ca = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:146:5 + --> tests/ui/format_args_unfixable.rs:169:5 | LL | usr_println!(true, "error: {}", format!(r#"boom at "{}""#, Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -229,7 +231,7 @@ LL | usr_println!(true, "error: {}", format!(r#"boom at "{}""#, Location::ca = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:148:5 + --> tests/ui/format_args_unfixable.rs:172:5 | LL | usr_println!(true, "error: {}", format!("boom at {} {0}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/format_collect.rs b/tests/ui/format_collect.rs index 26ebdc6c0cb6..85dbd5692fef 100644 --- a/tests/ui/format_collect.rs +++ b/tests/ui/format_collect.rs @@ -3,13 +3,15 @@ fn hex_encode(bytes: &[u8]) -> String { bytes.iter().map(|b| format!("{b:02X}")).collect() - //~^ ERROR: use of `format!` to build up a string from an iterator + //~^ format_collect + } #[rustfmt::skip] fn hex_encode_deep(bytes: &[u8]) -> String { bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect() - //~^ ERROR: use of `format!` to build up a string from an iterator + //~^ format_collect + } macro_rules! fmt { @@ -24,7 +26,8 @@ fn from_macro(bytes: &[u8]) -> String { fn with_block() -> String { (1..10) - //~^ ERROR: use of `format!` to build up a string from an iterator + //~^ format_collect + .map(|s| { let y = 1; format!("{s} {y}") diff --git a/tests/ui/format_collect.stderr b/tests/ui/format_collect.stderr index 863b457a7905..a87951efa543 100644 --- a/tests/ui/format_collect.stderr +++ b/tests/ui/format_collect.stderr @@ -19,42 +19,42 @@ LL | bytes.iter().map(|b| format!("{b:02X}")).collect() = help: to override `-D warnings` add `#[allow(clippy::format_collect)]` error: use of `format!` to build up a string from an iterator - --> tests/ui/format_collect.rs:11:5 + --> tests/ui/format_collect.rs:12:5 | LL | bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: call `fold` instead - --> tests/ui/format_collect.rs:11:18 + --> tests/ui/format_collect.rs:12:18 | LL | bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect() | ^^^ help: ... and use the `write!` macro here - --> tests/ui/format_collect.rs:11:32 + --> tests/ui/format_collect.rs:12:32 | LL | bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect() | ^^^^^^^^^^^^^^^^^^ = note: this can be written more efficiently by appending to a `String` directly error: use of `format!` to build up a string from an iterator - --> tests/ui/format_collect.rs:26:5 + --> tests/ui/format_collect.rs:28:5 | LL | / (1..10) LL | | +LL | | LL | | .map(|s| { -LL | | let y = 1; -LL | | format!("{s} {y}") +... | LL | | }) LL | | .collect() | |__________________^ | help: call `fold` instead - --> tests/ui/format_collect.rs:28:10 + --> tests/ui/format_collect.rs:31:10 | LL | .map(|s| { | ^^^ help: ... and use the `write!` macro here - --> tests/ui/format_collect.rs:30:13 + --> tests/ui/format_collect.rs:33:13 | LL | format!("{s} {y}") | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/format_push_string.rs b/tests/ui/format_push_string.rs index 735ae3393289..c047118b5f50 100644 --- a/tests/ui/format_push_string.rs +++ b/tests/ui/format_push_string.rs @@ -3,9 +3,11 @@ fn main() { let mut string = String::new(); string += &format!("{:?}", 1234); - //~^ ERROR: `format!(..)` appended to existing `String` + //~^ format_push_string + string.push_str(&format!("{:?}", 5678)); - //~^ ERROR: `format!(..)` appended to existing `String` + //~^ format_push_string + } mod issue9493 { @@ -13,7 +15,8 @@ mod issue9493 { let mut hex = String::with_capacity(vector.len() * 2); for byte in vector { hex += &(if upper { - //~^ ERROR: `format!(..)` appended to existing `String` + //~^ format_push_string + format!("{byte:02X}") } else { format!("{byte:02x}") @@ -26,14 +29,16 @@ mod issue9493 { let mut s = String::new(); // if let s += &(if let Some(_a) = Some(1234) { - //~^ ERROR: `format!(..)` appended to existing `String` + //~^ format_push_string + format!("{}", 1234) } else { format!("{}", 1234) }); // match s += &(match Some(1234) { - //~^ ERROR: `format!(..)` appended to existing `String` + //~^ format_push_string + Some(_) => format!("{}", 1234), None => format!("{}", 1234), }); diff --git a/tests/ui/format_push_string.stderr b/tests/ui/format_push_string.stderr index a9520600f52a..a496371938e9 100644 --- a/tests/ui/format_push_string.stderr +++ b/tests/ui/format_push_string.stderr @@ -9,7 +9,7 @@ LL | string += &format!("{:?}", 1234); = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]` error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:7:5 + --> tests/ui/format_push_string.rs:8:5 | LL | string.push_str(&format!("{:?}", 5678)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,10 +17,11 @@ LL | string.push_str(&format!("{:?}", 5678)); = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:15:13 + --> tests/ui/format_push_string.rs:17:13 | LL | / hex += &(if upper { LL | | +LL | | LL | | format!("{byte:02X}") LL | | } else { LL | | format!("{byte:02x}") @@ -30,10 +31,11 @@ LL | | }); = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:28:9 + --> tests/ui/format_push_string.rs:31:9 | LL | / s += &(if let Some(_a) = Some(1234) { LL | | +LL | | LL | | format!("{}", 1234) LL | | } else { LL | | format!("{}", 1234) @@ -43,10 +45,11 @@ LL | | }); = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:35:9 + --> tests/ui/format_push_string.rs:39:9 | LL | / s += &(match Some(1234) { LL | | +LL | | LL | | Some(_) => format!("{}", 1234), LL | | None => format!("{}", 1234), LL | | }); diff --git a/tests/ui/formatting.rs b/tests/ui/formatting.rs index 312fa2aa40ad..4e84dcf7d5b7 100644 --- a/tests/ui/formatting.rs +++ b/tests/ui/formatting.rs @@ -14,16 +14,19 @@ fn main() { // weird op_eq formatting: let mut a = 42; a =- 35; - //~^ ERROR: this looks like you are trying to use `.. -= ..`, but you really are doing - //~| NOTE: to remove this lint, use either `-=` or `= -` + //~^ suspicious_assignment_formatting + + a =* &191; - //~^ ERROR: this looks like you are trying to use `.. *= ..`, but you really are doing - //~| NOTE: to remove this lint, use either `*=` or `= *` + //~^ suspicious_assignment_formatting + + let mut b = true; b =! false; - //~^ ERROR: this looks like you are trying to use `.. != ..`, but you really are doing - //~| NOTE: to remove this lint, use either `!=` or `= !` + //~^ suspicious_assignment_formatting + + // those are ok: a = -35; @@ -33,14 +36,16 @@ fn main() { // possible missing comma in an array let _ = &[ -1, -2, -3 // <= no comma here - //~^ ERROR: possibly missing a comma here - //~| NOTE: to remove this lint, add a comma or write the expr in a single line + //~^ possible_missing_comma + + -4, -5, -6 ]; let _ = &[ -1, -2, -3 // <= no comma here - //~^ ERROR: possibly missing a comma here - //~| NOTE: to remove this lint, add a comma or write the expr in a single line + //~^ possible_missing_comma + + *4, -5, -6 ]; @@ -78,8 +83,9 @@ fn main() { // lint if it doesn't let _ = &[ -1 - //~^ ERROR: possibly missing a comma here - //~| NOTE: to remove this lint, add a comma or write the expr in a single line + //~^ possible_missing_comma + + -4, ]; } diff --git a/tests/ui/formatting.stderr b/tests/ui/formatting.stderr index e823e6512b8d..972bd3a6a2e6 100644 --- a/tests/ui/formatting.stderr +++ b/tests/ui/formatting.stderr @@ -9,7 +9,7 @@ LL | a =- 35; = help: to override `-D warnings` add `#[allow(clippy::suspicious_assignment_formatting)]` error: this looks like you are trying to use `.. *= ..`, but you really are doing `.. = (* ..)` - --> tests/ui/formatting.rs:19:6 + --> tests/ui/formatting.rs:20:6 | LL | a =* &191; | ^^^^ @@ -17,7 +17,7 @@ LL | a =* &191; = note: to remove this lint, use either `*=` or `= *` error: this looks like you are trying to use `.. != ..`, but you really are doing `.. = (! ..)` - --> tests/ui/formatting.rs:24:6 + --> tests/ui/formatting.rs:26:6 | LL | b =! false; | ^^^^ @@ -25,7 +25,7 @@ LL | b =! false; = note: to remove this lint, use either `!=` or `= !` error: possibly missing a comma here - --> tests/ui/formatting.rs:35:19 + --> tests/ui/formatting.rs:38:19 | LL | -1, -2, -3 // <= no comma here | ^ @@ -35,7 +35,7 @@ LL | -1, -2, -3 // <= no comma here = help: to override `-D warnings` add `#[allow(clippy::possible_missing_comma)]` error: possibly missing a comma here - --> tests/ui/formatting.rs:41:19 + --> tests/ui/formatting.rs:45:19 | LL | -1, -2, -3 // <= no comma here | ^ @@ -43,7 +43,7 @@ LL | -1, -2, -3 // <= no comma here = note: to remove this lint, add a comma or write the expr in a single line error: possibly missing a comma here - --> tests/ui/formatting.rs:80:11 + --> tests/ui/formatting.rs:85:11 | LL | -1 | ^ diff --git a/tests/ui/four_forward_slashes.fixed b/tests/ui/four_forward_slashes.fixed index 6d31c543d727..6f387b67ccbf 100644 --- a/tests/ui/four_forward_slashes.fixed +++ b/tests/ui/four_forward_slashes.fixed @@ -1,4 +1,3 @@ - //@aux-build:proc_macros.rs #![feature(custom_inner_attributes)] #![allow(unused)] @@ -10,14 +9,17 @@ extern crate proc_macros; /// whoops +//~^ four_forward_slashes fn a() {} /// whoops +//~^ four_forward_slashes #[allow(dead_code)] fn b() {} /// whoops /// two borked comments! +//~^^ four_forward_slashes #[track_caller] fn c() {} @@ -25,10 +27,12 @@ fn d() {} #[test] /// between attributes +//~^ four_forward_slashes #[allow(dead_code)] fn g() {} /// not very start of contents + //~^ four_forward_slashes fn h() {} fn i() { diff --git a/tests/ui/four_forward_slashes.rs b/tests/ui/four_forward_slashes.rs index 458b8de53e15..fae07e7d6094 100644 --- a/tests/ui/four_forward_slashes.rs +++ b/tests/ui/four_forward_slashes.rs @@ -1,4 +1,3 @@ - //@aux-build:proc_macros.rs #![feature(custom_inner_attributes)] #![allow(unused)] @@ -10,14 +9,17 @@ extern crate proc_macros; //// whoops +//~^ four_forward_slashes fn a() {} //// whoops +//~^ four_forward_slashes #[allow(dead_code)] fn b() {} //// whoops //// two borked comments! +//~^^ four_forward_slashes #[track_caller] fn c() {} @@ -25,10 +27,12 @@ fn d() {} #[test] //// between attributes +//~^ four_forward_slashes #[allow(dead_code)] fn g() {} //// not very start of contents + //~^ four_forward_slashes fn h() {} fn i() { diff --git a/tests/ui/four_forward_slashes.stderr b/tests/ui/four_forward_slashes.stderr index 3606a2227a00..4ac5d13c4fa8 100644 --- a/tests/ui/four_forward_slashes.stderr +++ b/tests/ui/four_forward_slashes.stderr @@ -1,7 +1,8 @@ error: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't - --> tests/ui/four_forward_slashes.rs:12:1 + --> tests/ui/four_forward_slashes.rs:11:1 | LL | / //// whoops +LL | | LL | | fn a() {} | |_^ | @@ -16,6 +17,7 @@ error: this item has comments with 4 forward slashes (`////`). These look like d --> tests/ui/four_forward_slashes.rs:15:1 | LL | / //// whoops +LL | | LL | | #[allow(dead_code)] LL | | fn b() {} | |_^ @@ -26,10 +28,11 @@ LL + /// whoops | error: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't - --> tests/ui/four_forward_slashes.rs:19:1 + --> tests/ui/four_forward_slashes.rs:20:1 | LL | / //// whoops LL | | //// two borked comments! +LL | | LL | | #[track_caller] LL | | fn c() {} | |_^ @@ -41,9 +44,10 @@ LL ~ /// two borked comments! | error: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't - --> tests/ui/four_forward_slashes.rs:27:1 + --> tests/ui/four_forward_slashes.rs:29:1 | LL | / //// between attributes +LL | | LL | | #[allow(dead_code)] LL | | fn g() {} | |_^ @@ -54,9 +58,10 @@ LL + /// between attributes | error: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't - --> tests/ui/four_forward_slashes.rs:31:1 + --> tests/ui/four_forward_slashes.rs:34:1 | LL | / //// not very start of contents +LL | | LL | | fn h() {} | |_^ | diff --git a/tests/ui/four_forward_slashes_first_line.fixed b/tests/ui/four_forward_slashes_first_line.fixed index 5ef40015d88b..34604a6461b9 100644 --- a/tests/ui/four_forward_slashes_first_line.fixed +++ b/tests/ui/four_forward_slashes_first_line.fixed @@ -1,4 +1,5 @@ /// borked doc comment on the first line. doesn't combust! +//~^ four_forward_slashes fn a() {} // This test's entire purpose is to make sure we don't panic if the comment with four slashes diff --git a/tests/ui/four_forward_slashes_first_line.rs b/tests/ui/four_forward_slashes_first_line.rs index 9c835e745f65..150e9ba2711c 100644 --- a/tests/ui/four_forward_slashes_first_line.rs +++ b/tests/ui/four_forward_slashes_first_line.rs @@ -1,4 +1,5 @@ //// borked doc comment on the first line. doesn't combust! +//~^ four_forward_slashes fn a() {} // This test's entire purpose is to make sure we don't panic if the comment with four slashes diff --git a/tests/ui/four_forward_slashes_first_line.stderr b/tests/ui/four_forward_slashes_first_line.stderr index 81732346412a..3cb95797319f 100644 --- a/tests/ui/four_forward_slashes_first_line.stderr +++ b/tests/ui/four_forward_slashes_first_line.stderr @@ -2,6 +2,7 @@ error: this item has comments with 4 forward slashes (`////`). These look like d --> tests/ui/four_forward_slashes_first_line.rs:1:1 | LL | / //// borked doc comment on the first line. doesn't combust! +LL | | LL | | fn a() {} | |_^ | diff --git a/tests/ui/from_iter_instead_of_collect.fixed b/tests/ui/from_iter_instead_of_collect.fixed index 67da45a348f9..8618004efb89 100644 --- a/tests/ui/from_iter_instead_of_collect.fixed +++ b/tests/ui/from_iter_instead_of_collect.fixed @@ -15,46 +15,61 @@ impl FromIterator for Foo { impl<'a> FromIterator<&'a bool> for Foo { fn from_iter>(iter: T) -> Self { iter.into_iter().copied().collect::() + //~^ from_iter_instead_of_collect } } fn main() { let iter_expr = std::iter::repeat(5).take(5); let _ = iter_expr.collect::>(); + //~^ from_iter_instead_of_collect let _ = vec![5, 5, 5, 5].iter().enumerate().collect::>(); + //~^ from_iter_instead_of_collect Vec::from_iter(vec![42u32]); let a = vec![0, 1, 2]; assert_eq!(a, (0..3).collect::>()); + //~^ from_iter_instead_of_collect assert_eq!(a, (0..3).collect::>()); + //~^ from_iter_instead_of_collect let mut b = (0..3).collect::>(); + //~^ from_iter_instead_of_collect b.push_back(4); let mut b = (0..3).collect::>(); + //~^ from_iter_instead_of_collect b.push_back(4); { use std::collections; let mut b = (0..3).collect::>(); + //~^ from_iter_instead_of_collect b.push_back(4); } let values = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]; let bm = values.iter().cloned().collect::>(); + //~^ from_iter_instead_of_collect let mut bar = bm.range(0..2).collect::>(); + //~^ from_iter_instead_of_collect bar.insert(&4, &'e'); let mut bts = (0..3).collect::>(); + //~^ from_iter_instead_of_collect bts.insert(2); { use std::collections; let _ = (0..3).collect::>(); + //~^ from_iter_instead_of_collect let _ = (0..3).collect::>(); + //~^ from_iter_instead_of_collect } for _i in [1, 2, 3].iter().collect::>() {} + //~^ from_iter_instead_of_collect for _i in [1, 2, 3].iter().collect::>() {} + //~^ from_iter_instead_of_collect } diff --git a/tests/ui/from_iter_instead_of_collect.rs b/tests/ui/from_iter_instead_of_collect.rs index 423a7454bed7..c46397e8ff56 100644 --- a/tests/ui/from_iter_instead_of_collect.rs +++ b/tests/ui/from_iter_instead_of_collect.rs @@ -15,46 +15,61 @@ impl FromIterator for Foo { impl<'a> FromIterator<&'a bool> for Foo { fn from_iter>(iter: T) -> Self { >::from_iter(iter.into_iter().copied()) + //~^ from_iter_instead_of_collect } } fn main() { let iter_expr = std::iter::repeat(5).take(5); let _ = Vec::from_iter(iter_expr); + //~^ from_iter_instead_of_collect let _ = HashMap::::from_iter(vec![5, 5, 5, 5].iter().enumerate()); + //~^ from_iter_instead_of_collect Vec::from_iter(vec![42u32]); let a = vec![0, 1, 2]; assert_eq!(a, Vec::from_iter(0..3)); + //~^ from_iter_instead_of_collect assert_eq!(a, Vec::::from_iter(0..3)); + //~^ from_iter_instead_of_collect let mut b = VecDeque::from_iter(0..3); + //~^ from_iter_instead_of_collect b.push_back(4); let mut b = VecDeque::::from_iter(0..3); + //~^ from_iter_instead_of_collect b.push_back(4); { use std::collections; let mut b = collections::VecDeque::::from_iter(0..3); + //~^ from_iter_instead_of_collect b.push_back(4); } let values = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]; let bm = BTreeMap::from_iter(values.iter().cloned()); + //~^ from_iter_instead_of_collect let mut bar = BTreeMap::from_iter(bm.range(0..2)); + //~^ from_iter_instead_of_collect bar.insert(&4, &'e'); let mut bts = BTreeSet::from_iter(0..3); + //~^ from_iter_instead_of_collect bts.insert(2); { use std::collections; let _ = collections::BTreeSet::from_iter(0..3); + //~^ from_iter_instead_of_collect let _ = collections::BTreeSet::::from_iter(0..3); + //~^ from_iter_instead_of_collect } for _i in Vec::from_iter([1, 2, 3].iter()) {} + //~^ from_iter_instead_of_collect for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {} + //~^ from_iter_instead_of_collect } diff --git a/tests/ui/from_iter_instead_of_collect.stderr b/tests/ui/from_iter_instead_of_collect.stderr index 0824a526b793..b46d97af152f 100644 --- a/tests/ui/from_iter_instead_of_collect.stderr +++ b/tests/ui/from_iter_instead_of_collect.stderr @@ -8,85 +8,85 @@ LL | >::from_iter(iter.into_iter().copied()) = help: to override `-D warnings` add `#[allow(clippy::from_iter_instead_of_collect)]` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:23:13 + --> tests/ui/from_iter_instead_of_collect.rs:24:13 | LL | let _ = Vec::from_iter(iter_expr); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter_expr.collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:25:13 + --> tests/ui/from_iter_instead_of_collect.rs:27:13 | LL | let _ = HashMap::::from_iter(vec![5, 5, 5, 5].iter().enumerate()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `vec![5, 5, 5, 5].iter().enumerate().collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:30:19 + --> tests/ui/from_iter_instead_of_collect.rs:33:19 | LL | assert_eq!(a, Vec::from_iter(0..3)); | ^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:31:19 + --> tests/ui/from_iter_instead_of_collect.rs:35:19 | LL | assert_eq!(a, Vec::::from_iter(0..3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:33:17 + --> tests/ui/from_iter_instead_of_collect.rs:38:17 | LL | let mut b = VecDeque::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:36:17 + --> tests/ui/from_iter_instead_of_collect.rs:42:17 | LL | let mut b = VecDeque::::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:41:21 + --> tests/ui/from_iter_instead_of_collect.rs:48:21 | LL | let mut b = collections::VecDeque::::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:46:14 + --> tests/ui/from_iter_instead_of_collect.rs:54:14 | LL | let bm = BTreeMap::from_iter(values.iter().cloned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `values.iter().cloned().collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:47:19 + --> tests/ui/from_iter_instead_of_collect.rs:56:19 | LL | let mut bar = BTreeMap::from_iter(bm.range(0..2)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `bm.range(0..2).collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:50:19 + --> tests/ui/from_iter_instead_of_collect.rs:60:19 | LL | let mut bts = BTreeSet::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:54:17 + --> tests/ui/from_iter_instead_of_collect.rs:65:17 | LL | let _ = collections::BTreeSet::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:55:17 + --> tests/ui/from_iter_instead_of_collect.rs:67:17 | LL | let _ = collections::BTreeSet::::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:58:15 + --> tests/ui/from_iter_instead_of_collect.rs:71:15 | LL | for _i in Vec::from_iter([1, 2, 3].iter()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::>()` error: usage of `FromIterator::from_iter` - --> tests/ui/from_iter_instead_of_collect.rs:59:15 + --> tests/ui/from_iter_instead_of_collect.rs:73:15 | LL | for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::>()` diff --git a/tests/ui/from_over_into.fixed b/tests/ui/from_over_into.fixed index a33c1ea5738b..85befb87fe5b 100644 --- a/tests/ui/from_over_into.fixed +++ b/tests/ui/from_over_into.fixed @@ -7,6 +7,7 @@ struct StringWrapper(String); impl From for StringWrapper { +//~^ from_over_into fn from(val: String) -> Self { StringWrapper(val) } @@ -15,6 +16,7 @@ impl From for StringWrapper { struct SelfType(String); impl From for SelfType { +//~^ from_over_into fn from(val: String) -> Self { SelfType(String::new()) } @@ -30,6 +32,7 @@ impl X { struct SelfKeywords; impl From for SelfKeywords { +//~^ from_over_into fn from(val: X) -> Self { let _ = X; let _ = X::FOO; @@ -42,6 +45,7 @@ impl From for SelfKeywords { struct ExplicitPaths(bool); impl core::convert::From for bool { +//~^ from_over_into fn from(mut val: crate::ExplicitPaths) -> Self { let in_closure = || val.0; @@ -62,6 +66,7 @@ impl From for A { struct PathInExpansion; impl From for String { +//~^ from_over_into fn from(val: PathInExpansion) -> Self { // non self/Self paths in expansions are fine panic!() @@ -84,6 +89,7 @@ fn msrv_1_41() { struct FromOverInto(Vec); impl From> for FromOverInto { + //~^ from_over_into fn from(val: Vec) -> Self { FromOverInto(val) } @@ -94,6 +100,7 @@ fn issue_12138() { struct Hello; impl From for () { + //~^ from_over_into fn from(val: Hello) {} } } diff --git a/tests/ui/from_over_into.rs b/tests/ui/from_over_into.rs index 6cd811ae401e..d4bdad56473a 100644 --- a/tests/ui/from_over_into.rs +++ b/tests/ui/from_over_into.rs @@ -7,6 +7,7 @@ struct StringWrapper(String); impl Into for String { +//~^ from_over_into fn into(self) -> StringWrapper { StringWrapper(self) } @@ -15,6 +16,7 @@ impl Into for String { struct SelfType(String); impl Into for String { +//~^ from_over_into fn into(self) -> SelfType { SelfType(Self::new()) } @@ -30,6 +32,7 @@ impl X { struct SelfKeywords; impl Into for X { +//~^ from_over_into fn into(self) -> SelfKeywords { let _ = Self; let _ = Self::FOO; @@ -42,6 +45,7 @@ impl Into for X { struct ExplicitPaths(bool); impl core::convert::Into for crate::ExplicitPaths { +//~^ from_over_into fn into(mut self) -> bool { let in_closure = || self.0; @@ -62,6 +66,7 @@ impl From for A { struct PathInExpansion; impl Into for PathInExpansion { +//~^ from_over_into fn into(self) -> String { // non self/Self paths in expansions are fine panic!() @@ -84,6 +89,7 @@ fn msrv_1_41() { struct FromOverInto(Vec); impl Into> for Vec { + //~^ from_over_into fn into(self) -> FromOverInto { FromOverInto(self) } @@ -94,6 +100,7 @@ fn issue_12138() { struct Hello; impl Into<()> for Hello { + //~^ from_over_into fn into(self) {} } } diff --git a/tests/ui/from_over_into.stderr b/tests/ui/from_over_into.stderr index f913ae0bb506..a564bccbaf71 100644 --- a/tests/ui/from_over_into.stderr +++ b/tests/ui/from_over_into.stderr @@ -9,12 +9,13 @@ LL | impl Into for String { help: replace the `Into` implementation with `From` | LL ~ impl From for StringWrapper { +LL | LL ~ fn from(val: String) -> Self { LL ~ StringWrapper(val) | error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> tests/ui/from_over_into.rs:17:1 + --> tests/ui/from_over_into.rs:18:1 | LL | impl Into for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,12 +23,13 @@ LL | impl Into for String { help: replace the `Into` implementation with `From` | LL ~ impl From for SelfType { +LL | LL ~ fn from(val: String) -> Self { LL ~ SelfType(String::new()) | error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> tests/ui/from_over_into.rs:32:1 + --> tests/ui/from_over_into.rs:34:1 | LL | impl Into for X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,6 +37,7 @@ LL | impl Into for X { help: replace the `Into` implementation with `From` | LL ~ impl From for SelfKeywords { +LL | LL ~ fn from(val: X) -> Self { LL ~ let _ = X; LL ~ let _ = X::FOO; @@ -42,7 +45,7 @@ LL ~ let _: X = val; | error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> tests/ui/from_over_into.rs:44:1 + --> tests/ui/from_over_into.rs:47:1 | LL | impl core::convert::Into for crate::ExplicitPaths { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,6 +55,7 @@ LL | impl core::convert::Into for crate::ExplicitPaths { help: replace the `Into` implementation with `From` | LL ~ impl core::convert::From for bool { +LL | LL ~ fn from(mut val: crate::ExplicitPaths) -> Self { LL ~ let in_closure = || val.0; LL | @@ -60,7 +64,7 @@ LL ~ val.0 | error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> tests/ui/from_over_into.rs:64:1 + --> tests/ui/from_over_into.rs:68:1 | LL | impl Into for PathInExpansion { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,11 +74,12 @@ LL | impl Into for PathInExpansion { help: replace the `Into` implementation with `From` | LL ~ impl From for String { +LL | LL ~ fn from(val: PathInExpansion) -> Self { | error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> tests/ui/from_over_into.rs:86:5 + --> tests/ui/from_over_into.rs:91:5 | LL | impl Into> for Vec { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -82,12 +87,13 @@ LL | impl Into> for Vec { help: replace the `Into` implementation with `From>` | LL ~ impl From> for FromOverInto { +LL | LL ~ fn from(val: Vec) -> Self { LL ~ FromOverInto(val) | error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> tests/ui/from_over_into.rs:96:5 + --> tests/ui/from_over_into.rs:102:5 | LL | impl Into<()> for Hello { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,6 +103,7 @@ LL | impl Into<()> for Hello { help: replace the `Into` implementation with `From` | LL ~ impl From for () { +LL | LL ~ fn from(val: Hello) {} | diff --git a/tests/ui/from_over_into_unfixable.rs b/tests/ui/from_over_into_unfixable.rs index 0c1f39f93fd3..23aab9b52e1b 100644 --- a/tests/ui/from_over_into_unfixable.rs +++ b/tests/ui/from_over_into_unfixable.rs @@ -9,7 +9,8 @@ macro_rules! in_macro { } impl Into for String { - //~^ ERROR: an implementation of `From` is preferred since it gives you `Into<_>` for free +//~^ from_over_into + fn into(self) -> InMacro { InMacro(in_macro!()) } @@ -18,7 +19,8 @@ impl Into for String { struct WeirdUpperSelf; impl Into for &'static [u8] { - //~^ ERROR: an implementation of `From` is preferred since it gives you `Into<_>` for free +//~^ from_over_into + fn into(self) -> WeirdUpperSelf { let _ = Self::default(); WeirdUpperSelf @@ -28,7 +30,8 @@ impl Into for &'static [u8] { struct ContainsVal; impl Into for ContainsVal { - //~^ ERROR: an implementation of `From` is preferred since it gives you `Into<_>` for free +//~^ from_over_into + fn into(self) -> u8 { let val = 1; val + 1 @@ -40,7 +43,8 @@ pub struct Lval(T); pub struct Rval(T); impl Into> for Lval { - //~^ ERROR: an implementation of `From` is preferred since it gives you `Into<_>` for free +//~^ from_over_into + fn into(self) -> Rval { Rval(self) } diff --git a/tests/ui/from_over_into_unfixable.stderr b/tests/ui/from_over_into_unfixable.stderr index 1776b86e40dd..0e9264a153bb 100644 --- a/tests/ui/from_over_into_unfixable.stderr +++ b/tests/ui/from_over_into_unfixable.stderr @@ -9,7 +9,7 @@ LL | impl Into for String { = help: to override `-D warnings` add `#[allow(clippy::from_over_into)]` error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> tests/ui/from_over_into_unfixable.rs:20:1 + --> tests/ui/from_over_into_unfixable.rs:21:1 | LL | impl Into for &'static [u8] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | impl Into for &'static [u8] { = help: replace the `Into` implementation with `From<&'static [u8]>` error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> tests/ui/from_over_into_unfixable.rs:30:1 + --> tests/ui/from_over_into_unfixable.rs:32:1 | LL | impl Into for ContainsVal { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | impl Into for ContainsVal { = help: replace the `Into` implementation with `From` error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> tests/ui/from_over_into_unfixable.rs:42:1 + --> tests/ui/from_over_into_unfixable.rs:45:1 | LL | impl Into> for Lval { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/from_raw_with_void_ptr.rs b/tests/ui/from_raw_with_void_ptr.rs index 81472070eb4c..840508ad340d 100644 --- a/tests/ui/from_raw_with_void_ptr.rs +++ b/tests/ui/from_raw_with_void_ptr.rs @@ -9,7 +9,8 @@ fn main() { // must lint let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void; let _ = unsafe { Box::from_raw(ptr) }; - //~^ ERROR: creating a `Box` from a void raw pointer + //~^ from_raw_with_void_ptr + // shouldn't be linted let _ = unsafe { Box::from_raw(ptr as *mut usize) }; @@ -21,20 +22,24 @@ fn main() { // must lint let ptr = Rc::into_raw(Rc::new(42usize)) as *mut c_void; let _ = unsafe { Rc::from_raw(ptr) }; - //~^ ERROR: creating a `Rc` from a void raw pointer + //~^ from_raw_with_void_ptr + // must lint let ptr = Arc::into_raw(Arc::new(42usize)) as *mut c_void; let _ = unsafe { Arc::from_raw(ptr) }; - //~^ ERROR: creating a `Arc` from a void raw pointer + //~^ from_raw_with_void_ptr + // must lint let ptr = std::rc::Weak::into_raw(Rc::downgrade(&Rc::new(42usize))) as *mut c_void; let _ = unsafe { std::rc::Weak::from_raw(ptr) }; - //~^ ERROR: creating a `Weak` from a void raw pointer + //~^ from_raw_with_void_ptr + // must lint let ptr = std::sync::Weak::into_raw(Arc::downgrade(&Arc::new(42usize))) as *mut c_void; let _ = unsafe { std::sync::Weak::from_raw(ptr) }; - //~^ ERROR: creating a `Weak` from a void raw pointer + //~^ from_raw_with_void_ptr + } diff --git a/tests/ui/from_raw_with_void_ptr.stderr b/tests/ui/from_raw_with_void_ptr.stderr index e5bcb783d18b..ab55cfd48a5b 100644 --- a/tests/ui/from_raw_with_void_ptr.stderr +++ b/tests/ui/from_raw_with_void_ptr.stderr @@ -13,49 +13,49 @@ LL | let _ = unsafe { Box::from_raw(ptr) }; = help: to override `-D warnings` add `#[allow(clippy::from_raw_with_void_ptr)]` error: creating a `Rc` from a void raw pointer - --> tests/ui/from_raw_with_void_ptr.rs:23:22 + --> tests/ui/from_raw_with_void_ptr.rs:24:22 | LL | let _ = unsafe { Rc::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> tests/ui/from_raw_with_void_ptr.rs:23:35 + --> tests/ui/from_raw_with_void_ptr.rs:24:35 | LL | let _ = unsafe { Rc::from_raw(ptr) }; | ^^^ error: creating a `Arc` from a void raw pointer - --> tests/ui/from_raw_with_void_ptr.rs:28:22 + --> tests/ui/from_raw_with_void_ptr.rs:30:22 | LL | let _ = unsafe { Arc::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> tests/ui/from_raw_with_void_ptr.rs:28:36 + --> tests/ui/from_raw_with_void_ptr.rs:30:36 | LL | let _ = unsafe { Arc::from_raw(ptr) }; | ^^^ error: creating a `Weak` from a void raw pointer - --> tests/ui/from_raw_with_void_ptr.rs:33:22 + --> tests/ui/from_raw_with_void_ptr.rs:36:22 | LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> tests/ui/from_raw_with_void_ptr.rs:33:46 + --> tests/ui/from_raw_with_void_ptr.rs:36:46 | LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) }; | ^^^ error: creating a `Weak` from a void raw pointer - --> tests/ui/from_raw_with_void_ptr.rs:38:22 + --> tests/ui/from_raw_with_void_ptr.rs:42:22 | LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> tests/ui/from_raw_with_void_ptr.rs:38:48 + --> tests/ui/from_raw_with_void_ptr.rs:42:48 | LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) }; | ^^^ diff --git a/tests/ui/from_str_radix_10.fixed b/tests/ui/from_str_radix_10.fixed index 6c582190b442..e9f4de518bbc 100644 --- a/tests/ui/from_str_radix_10.fixed +++ b/tests/ui/from_str_radix_10.fixed @@ -26,26 +26,34 @@ impl std::ops::Add for Test { fn main() -> Result<(), Box> { // all of these should trigger the lint "30".parse::()?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` - //~| NOTE: `-D clippy::from-str-radix-10` implied by `-D warnings` + //~^ from_str_radix_10 + + "24".parse::()?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + "100".parse::()?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + "7".parse::()?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + ("10".to_owned() + "5").parse::()?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + (Test + Test).parse::()?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + let string = "300"; string.parse::()?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + let stringier = "400".to_string(); stringier.parse::()?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + // none of these should trigger the lint u16::from_str_radix("20", 3)?; diff --git a/tests/ui/from_str_radix_10.rs b/tests/ui/from_str_radix_10.rs index 0df6a0a202ae..9ebead7f75ba 100644 --- a/tests/ui/from_str_radix_10.rs +++ b/tests/ui/from_str_radix_10.rs @@ -26,26 +26,34 @@ impl std::ops::Add for Test { fn main() -> Result<(), Box> { // all of these should trigger the lint u32::from_str_radix("30", 10)?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` - //~| NOTE: `-D clippy::from-str-radix-10` implied by `-D warnings` + //~^ from_str_radix_10 + + i64::from_str_radix("24", 10)?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + isize::from_str_radix("100", 10)?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + u8::from_str_radix("7", 10)?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + u16::from_str_radix(&("10".to_owned() + "5"), 10)?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + i128::from_str_radix(Test + Test, 10)?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + let string = "300"; i32::from_str_radix(string, 10)?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + let stringier = "400".to_string(); i32::from_str_radix(&stringier, 10)?; - //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse` + //~^ from_str_radix_10 + // none of these should trigger the lint u16::from_str_radix("20", 3)?; diff --git a/tests/ui/from_str_radix_10.stderr b/tests/ui/from_str_radix_10.stderr index 4aa84eca2612..7f0a12a03f3c 100644 --- a/tests/ui/from_str_radix_10.stderr +++ b/tests/ui/from_str_radix_10.stderr @@ -8,43 +8,43 @@ LL | u32::from_str_radix("30", 10)?; = help: to override `-D warnings` add `#[allow(clippy::from_str_radix_10)]` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:31:5 + --> tests/ui/from_str_radix_10.rs:32:5 | LL | i64::from_str_radix("24", 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"24".parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:33:5 + --> tests/ui/from_str_radix_10.rs:35:5 | LL | isize::from_str_radix("100", 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"100".parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:35:5 + --> tests/ui/from_str_radix_10.rs:38:5 | LL | u8::from_str_radix("7", 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"7".parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:37:5 + --> tests/ui/from_str_radix_10.rs:41:5 | LL | u16::from_str_radix(&("10".to_owned() + "5"), 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `("10".to_owned() + "5").parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:39:5 + --> tests/ui/from_str_radix_10.rs:44:5 | LL | i128::from_str_radix(Test + Test, 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(Test + Test).parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:43:5 + --> tests/ui/from_str_radix_10.rs:49:5 | LL | i32::from_str_radix(string, 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:47:5 + --> tests/ui/from_str_radix_10.rs:54:5 | LL | i32::from_str_radix(&stringier, 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `stringier.parse::()` diff --git a/tests/ui/functions.rs b/tests/ui/functions.rs index 0aef60959593..9114dd96ce4d 100644 --- a/tests/ui/functions.rs +++ b/tests/ui/functions.rs @@ -6,12 +6,14 @@ fn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {} fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} -//~^ ERROR: this function has too many arguments (8/7) -//~| NOTE: `-D clippy::too-many-arguments` implied by `-D warnings` +//~^ too_many_arguments + + #[rustfmt::skip] fn bad_multiline( -//~^ ERROR: this function has too many arguments (8/7) +//~^ too_many_arguments + one: u32, two: u32, three: &str, @@ -46,7 +48,8 @@ extern "C" fn extern_fn( pub trait Foo { fn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool); fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()); - //~^ ERROR: this function has too many arguments (8/7) + //~^ too_many_arguments + fn ptr(p: *const u8); } @@ -56,7 +59,8 @@ pub struct Bar; impl Bar { fn good_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {} fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} - //~^ ERROR: this function has too many arguments (8/7) + //~^ too_many_arguments + } // ok, we don’t want to warn implementations @@ -66,12 +70,15 @@ impl Foo for Bar { fn ptr(p: *const u8) { println!("{}", unsafe { *p }); - //~^ ERROR: this public function might dereference a raw pointer but is not marked - //~| NOTE: `-D clippy::not-unsafe-ptr-arg-deref` implied by `-D warnings` + //~^ not_unsafe_ptr_arg_deref + + println!("{:?}", unsafe { p.as_ref() }); - //~^ ERROR: this public function might dereference a raw pointer but is not marked + //~^ not_unsafe_ptr_arg_deref + unsafe { std::ptr::read(p) }; - //~^ ERROR: this public function might dereference a raw pointer but is not marked + //~^ not_unsafe_ptr_arg_deref + } } @@ -83,22 +90,28 @@ fn private(p: *const u8) { pub fn public(p: *const u8) { println!("{}", unsafe { *p }); - //~^ ERROR: this public function might dereference a raw pointer but is not marked `un + //~^ not_unsafe_ptr_arg_deref + println!("{:?}", unsafe { p.as_ref() }); - //~^ ERROR: this public function might dereference a raw pointer but is not marked `un + //~^ not_unsafe_ptr_arg_deref + unsafe { std::ptr::read(p) }; - //~^ ERROR: this public function might dereference a raw pointer but is not marked `un + //~^ not_unsafe_ptr_arg_deref + } type Alias = *const u8; pub fn type_alias(p: Alias) { println!("{}", unsafe { *p }); - //~^ ERROR: this public function might dereference a raw pointer but is not marked `un + //~^ not_unsafe_ptr_arg_deref + println!("{:?}", unsafe { p.as_ref() }); - //~^ ERROR: this public function might dereference a raw pointer but is not marked `un + //~^ not_unsafe_ptr_arg_deref + unsafe { std::ptr::read(p) }; - //~^ ERROR: this public function might dereference a raw pointer but is not marked `un + //~^ not_unsafe_ptr_arg_deref + } impl Bar { @@ -108,11 +121,14 @@ impl Bar { pub fn public(self, p: *const u8) { println!("{}", unsafe { *p }); - //~^ ERROR: this public function might dereference a raw pointer but is not marked + //~^ not_unsafe_ptr_arg_deref + println!("{:?}", unsafe { p.as_ref() }); - //~^ ERROR: this public function might dereference a raw pointer but is not marked + //~^ not_unsafe_ptr_arg_deref + unsafe { std::ptr::read(p) }; - //~^ ERROR: this public function might dereference a raw pointer but is not marked + //~^ not_unsafe_ptr_arg_deref + } pub fn public_ok(self, p: *const u8) { diff --git a/tests/ui/functions.stderr b/tests/ui/functions.stderr index 8fdceb8d8cd0..4e3cf2edb085 100644 --- a/tests/ui/functions.stderr +++ b/tests/ui/functions.stderr @@ -8,31 +8,31 @@ LL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]` error: this function has too many arguments (8/7) - --> tests/ui/functions.rs:13:1 + --> tests/ui/functions.rs:14:1 | LL | / fn bad_multiline( LL | | +LL | | LL | | one: u32, -LL | | two: u32, ... | LL | | eight: () LL | | ) { | |_^ error: this function has too many arguments (8/7) - --> tests/ui/functions.rs:48:5 + --> tests/ui/functions.rs:50:5 | LL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this function has too many arguments (8/7) - --> tests/ui/functions.rs:58:5 + --> tests/ui/functions.rs:61:5 | LL | fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:68:34 + --> tests/ui/functions.rs:72:34 | LL | println!("{}", unsafe { *p }); | ^ @@ -41,67 +41,67 @@ LL | println!("{}", unsafe { *p }); = help: to override `-D warnings` add `#[allow(clippy::not_unsafe_ptr_arg_deref)]` error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:71:35 + --> tests/ui/functions.rs:76:35 | LL | println!("{:?}", unsafe { p.as_ref() }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:73:33 + --> tests/ui/functions.rs:79:33 | LL | unsafe { std::ptr::read(p) }; | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:85:30 + --> tests/ui/functions.rs:92:30 | LL | println!("{}", unsafe { *p }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:87:31 + --> tests/ui/functions.rs:95:31 | LL | println!("{:?}", unsafe { p.as_ref() }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:89:29 + --> tests/ui/functions.rs:98:29 | LL | unsafe { std::ptr::read(p) }; | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:96:30 + --> tests/ui/functions.rs:106:30 | LL | println!("{}", unsafe { *p }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:98:31 + --> tests/ui/functions.rs:109:31 | LL | println!("{:?}", unsafe { p.as_ref() }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:100:29 + --> tests/ui/functions.rs:112:29 | LL | unsafe { std::ptr::read(p) }; | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:110:34 + --> tests/ui/functions.rs:123:34 | LL | println!("{}", unsafe { *p }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:112:35 + --> tests/ui/functions.rs:126:35 | LL | println!("{:?}", unsafe { p.as_ref() }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:114:33 + --> tests/ui/functions.rs:129:33 | LL | unsafe { std::ptr::read(p) }; | ^ diff --git a/tests/ui/functions_maxlines.rs b/tests/ui/functions_maxlines.rs index a3496f56d4a6..3c32e88c6880 100644 --- a/tests/ui/functions_maxlines.rs +++ b/tests/ui/functions_maxlines.rs @@ -56,8 +56,9 @@ fn good_lines() { } fn bad_lines() { - //~^ ERROR: this function has too many lines (102/100) - //~| NOTE: `-D clippy::too-many-lines` implied by `-D warnings` +//~^ too_many_lines + + println!("Dont get confused by braces: {{}}"); println!("This is bad."); println!("This is bad."); diff --git a/tests/ui/functions_maxlines.stderr b/tests/ui/functions_maxlines.stderr index f42a2b2a22a2..82d5fc8d5859 100644 --- a/tests/ui/functions_maxlines.stderr +++ b/tests/ui/functions_maxlines.stderr @@ -2,9 +2,6 @@ error: this function has too many lines (102/100) --> tests/ui/functions_maxlines.rs:58:1 | LL | / fn bad_lines() { -LL | | -LL | | -LL | | println!("Dont get confused by braces: {{}}"); ... | LL | | println!("This is bad."); LL | | } diff --git a/tests/ui/future_not_send.rs b/tests/ui/future_not_send.rs index 626ee6de9e4f..1df0b1334827 100644 --- a/tests/ui/future_not_send.rs +++ b/tests/ui/future_not_send.rs @@ -6,12 +6,14 @@ use std::rc::Rc; use std::sync::Arc; async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { - //~^ ERROR: future cannot be sent between threads safely +//~^ future_not_send + async { true }.await } pub async fn public_future(rc: Rc<[u8]>) { - //~^ ERROR: future cannot be sent between threads safely +//~^ future_not_send + async { true }.await; } @@ -20,12 +22,14 @@ pub async fn public_send(arc: Arc<[u8]>) -> bool { } async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { - //~^ ERROR: future cannot be sent between threads safely +//~^ future_not_send + true } pub async fn public_future2(rc: Rc<[u8]>) {} -//~^ ERROR: future cannot be sent between threads safely +//~^ future_not_send + pub async fn public_send2(arc: Arc<[u8]>) -> bool { false @@ -37,13 +41,15 @@ struct Dummy { impl Dummy { async fn private_future(&self) -> usize { - //~^ ERROR: future cannot be sent between threads safely + //~^ future_not_send + async { true }.await; self.rc.len() } pub async fn public_future(&self) { - //~^ ERROR: future cannot be sent between threads safely + //~^ future_not_send + self.private_future().await; } @@ -54,7 +60,8 @@ impl Dummy { } async fn generic_future(t: T) -> T -//~^ ERROR: future cannot be sent between threads safely +//~^ future_not_send + where T: Send, { @@ -76,7 +83,8 @@ async fn maybe_send_generic_future2 Fut, Fut: Future>(f: F) { } async fn generic_future_always_unsend(_: Rc) { - //~^ ERROR: future cannot be sent between threads safely +//~^ future_not_send + async { true }.await; } diff --git a/tests/ui/future_not_send.stderr b/tests/ui/future_not_send.stderr index 3807c7470136..4dcff55942a6 100644 --- a/tests/ui/future_not_send.stderr +++ b/tests/ui/future_not_send.stderr @@ -5,11 +5,11 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:10:20 + --> tests/ui/future_not_send.rs:11:20 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { | -- has type `std::rc::Rc<[u8]>` which is not `Send` -LL | +... LL | async { true }.await | ^^^^^ await occurs here, with `rc` maybe used later = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` @@ -23,93 +23,94 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:13:1 + --> tests/ui/future_not_send.rs:14:1 | LL | pub async fn public_future(rc: Rc<[u8]>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:15:20 + --> tests/ui/future_not_send.rs:17:20 | LL | pub async fn public_future(rc: Rc<[u8]>) { | -- has type `std::rc::Rc<[u8]>` which is not `Send` -LL | +... LL | async { true }.await; | ^^^^^ await occurs here, with `rc` maybe used later = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:22:1 + --> tests/ui/future_not_send.rs:24:1 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future2` is not `Send` | note: captured value is not `Send` - --> tests/ui/future_not_send.rs:22:26 + --> tests/ui/future_not_send.rs:24:26 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^ has type `std::rc::Rc<[u8]>` which is not `Send` = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` - --> tests/ui/future_not_send.rs:22:40 + --> tests/ui/future_not_send.rs:24:40 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^^^ has type `&std::cell::Cell` which is not `Send`, because `std::cell::Cell` is not `Sync` = note: `std::cell::Cell` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:27:1 + --> tests/ui/future_not_send.rs:30:1 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future2` is not `Send` | note: captured value is not `Send` - --> tests/ui/future_not_send.rs:27:29 + --> tests/ui/future_not_send.rs:30:29 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} | ^^ has type `std::rc::Rc<[u8]>` which is not `Send` = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:39:5 + --> tests/ui/future_not_send.rs:43:5 | LL | async fn private_future(&self) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:41:24 + --> tests/ui/future_not_send.rs:46:24 | LL | async fn private_future(&self) -> usize { | ----- has type `&Dummy` which is not `Send` -LL | +... LL | async { true }.await; | ^^^^^ await occurs here, with `&self` maybe used later = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:45:5 + --> tests/ui/future_not_send.rs:50:5 | LL | pub async fn public_future(&self) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` | note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` - --> tests/ui/future_not_send.rs:45:32 + --> tests/ui/future_not_send.rs:50:32 | LL | pub async fn public_future(&self) { | ^^^^^ has type `&Dummy` which is not `Send`, because `Dummy` is not `Sync` = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:56:1 + --> tests/ui/future_not_send.rs:62:1 | LL | / async fn generic_future(t: T) -> T LL | | +LL | | LL | | where LL | | T: Send, | |____________^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:62:20 + --> tests/ui/future_not_send.rs:69:20 | LL | let rt = &t; | -- has type `&T` which is not `Send` @@ -118,17 +119,17 @@ LL | async { true }.await; = note: `T` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:78:1 + --> tests/ui/future_not_send.rs:85:1 | LL | async fn generic_future_always_unsend(_: Rc) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `generic_future_always_unsend` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:80:20 + --> tests/ui/future_not_send.rs:88:20 | LL | async fn generic_future_always_unsend(_: Rc) { | - has type `std::rc::Rc` which is not `Send` -LL | +... LL | async { true }.await; | ^^^^^ await occurs here, with `_` maybe used later = note: `std::rc::Rc` doesn't implement `std::marker::Send` diff --git a/tests/ui/get_first.fixed b/tests/ui/get_first.fixed index 710ebab1ef2d..090fe48096ae 100644 --- a/tests/ui/get_first.fixed +++ b/tests/ui/get_first.fixed @@ -15,25 +15,29 @@ impl Bar { fn main() { let x = vec![2, 3, 5]; let _ = x.first(); - //~^ ERROR: accessing first element with `x.get(0)` + //~^ get_first + let _ = x.get(1); let _ = x[0]; let y = [2, 3, 5]; let _ = y.first(); - //~^ ERROR: accessing first element with `y.get(0)` + //~^ get_first + let _ = y.get(1); let _ = y[0]; let z = &[2, 3, 5]; let _ = z.first(); - //~^ ERROR: accessing first element with `z.get(0)` + //~^ get_first + let _ = z.get(1); let _ = z[0]; let vecdeque: VecDeque<_> = x.iter().cloned().collect(); let _ = vecdeque.front(); - //~^ ERROR: accessing first element with `vecdeque.get(0)` + //~^ get_first + let _ = vecdeque.get(1); let hashmap: HashMap = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]); @@ -46,5 +50,6 @@ fn main() { let non_primitives = [vec![1, 2], vec![3, 4]]; let _ = non_primitives.first(); - //~^ ERROR: accessing first element with `non_primitives.get(0)` + //~^ get_first + } diff --git a/tests/ui/get_first.rs b/tests/ui/get_first.rs index ad2ba6ce2c3b..c85d5aa89ca2 100644 --- a/tests/ui/get_first.rs +++ b/tests/ui/get_first.rs @@ -15,25 +15,29 @@ impl Bar { fn main() { let x = vec![2, 3, 5]; let _ = x.get(0); - //~^ ERROR: accessing first element with `x.get(0)` + //~^ get_first + let _ = x.get(1); let _ = x[0]; let y = [2, 3, 5]; let _ = y.get(0); - //~^ ERROR: accessing first element with `y.get(0)` + //~^ get_first + let _ = y.get(1); let _ = y[0]; let z = &[2, 3, 5]; let _ = z.get(0); - //~^ ERROR: accessing first element with `z.get(0)` + //~^ get_first + let _ = z.get(1); let _ = z[0]; let vecdeque: VecDeque<_> = x.iter().cloned().collect(); let _ = vecdeque.get(0); - //~^ ERROR: accessing first element with `vecdeque.get(0)` + //~^ get_first + let _ = vecdeque.get(1); let hashmap: HashMap = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]); @@ -46,5 +50,6 @@ fn main() { let non_primitives = [vec![1, 2], vec![3, 4]]; let _ = non_primitives.get(0); - //~^ ERROR: accessing first element with `non_primitives.get(0)` + //~^ get_first + } diff --git a/tests/ui/get_first.stderr b/tests/ui/get_first.stderr index 155d341b5a77..4e19ebbc7589 100644 --- a/tests/ui/get_first.stderr +++ b/tests/ui/get_first.stderr @@ -8,25 +8,25 @@ LL | let _ = x.get(0); = help: to override `-D warnings` add `#[allow(clippy::get_first)]` error: accessing first element with `y.get(0)` - --> tests/ui/get_first.rs:23:13 + --> tests/ui/get_first.rs:24:13 | LL | let _ = y.get(0); | ^^^^^^^^ help: try: `y.first()` error: accessing first element with `z.get(0)` - --> tests/ui/get_first.rs:29:13 + --> tests/ui/get_first.rs:31:13 | LL | let _ = z.get(0); | ^^^^^^^^ help: try: `z.first()` error: accessing first element with `vecdeque.get(0)` - --> tests/ui/get_first.rs:35:13 + --> tests/ui/get_first.rs:38:13 | LL | let _ = vecdeque.get(0); | ^^^^^^^^^^^^^^^ help: try: `vecdeque.front()` error: accessing first element with `non_primitives.get(0)` - --> tests/ui/get_first.rs:48:13 + --> tests/ui/get_first.rs:52:13 | LL | let _ = non_primitives.get(0); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `non_primitives.first()` diff --git a/tests/ui/get_last_with_len.fixed b/tests/ui/get_last_with_len.fixed index 377906cb2448..15b6e1666af2 100644 --- a/tests/ui/get_last_with_len.fixed +++ b/tests/ui/get_last_with_len.fixed @@ -6,6 +6,7 @@ use std::collections::VecDeque; fn dont_use_last() { let x = vec![2, 3, 5]; let _ = x.last(); + //~^ get_last_with_len } fn indexing_two_from_end() { @@ -30,18 +31,23 @@ struct S { fn in_field(s: &S) { let _ = s.field.last(); + //~^ get_last_with_len } fn main() { let slice = &[1, 2, 3]; let _ = slice.last(); + //~^ get_last_with_len let array = [4, 5, 6]; let _ = array.last(); + //~^ get_last_with_len let deq = VecDeque::from([7, 8, 9]); let _ = deq.back(); + //~^ get_last_with_len let nested = [[1]]; let _ = nested[0].last(); + //~^ get_last_with_len } diff --git a/tests/ui/get_last_with_len.rs b/tests/ui/get_last_with_len.rs index 2735932043a3..5b132e001e7b 100644 --- a/tests/ui/get_last_with_len.rs +++ b/tests/ui/get_last_with_len.rs @@ -6,6 +6,7 @@ use std::collections::VecDeque; fn dont_use_last() { let x = vec![2, 3, 5]; let _ = x.get(x.len() - 1); + //~^ get_last_with_len } fn indexing_two_from_end() { @@ -30,18 +31,23 @@ struct S { fn in_field(s: &S) { let _ = s.field.get(s.field.len() - 1); + //~^ get_last_with_len } fn main() { let slice = &[1, 2, 3]; let _ = slice.get(slice.len() - 1); + //~^ get_last_with_len let array = [4, 5, 6]; let _ = array.get(array.len() - 1); + //~^ get_last_with_len let deq = VecDeque::from([7, 8, 9]); let _ = deq.get(deq.len() - 1); + //~^ get_last_with_len let nested = [[1]]; let _ = nested[0].get(nested[0].len() - 1); + //~^ get_last_with_len } diff --git a/tests/ui/get_last_with_len.stderr b/tests/ui/get_last_with_len.stderr index ba08f5db7cfa..83a03a438e44 100644 --- a/tests/ui/get_last_with_len.stderr +++ b/tests/ui/get_last_with_len.stderr @@ -8,31 +8,31 @@ LL | let _ = x.get(x.len() - 1); = help: to override `-D warnings` add `#[allow(clippy::get_last_with_len)]` error: accessing last element with `s.field.get(s.field.len() - 1)` - --> tests/ui/get_last_with_len.rs:32:13 + --> tests/ui/get_last_with_len.rs:33:13 | LL | let _ = s.field.get(s.field.len() - 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.field.last()` error: accessing last element with `slice.get(slice.len() - 1)` - --> tests/ui/get_last_with_len.rs:37:13 + --> tests/ui/get_last_with_len.rs:39:13 | LL | let _ = slice.get(slice.len() - 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `slice.last()` error: accessing last element with `array.get(array.len() - 1)` - --> tests/ui/get_last_with_len.rs:40:13 + --> tests/ui/get_last_with_len.rs:43:13 | LL | let _ = array.get(array.len() - 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `array.last()` error: accessing last element with `deq.get(deq.len() - 1)` - --> tests/ui/get_last_with_len.rs:43:13 + --> tests/ui/get_last_with_len.rs:47:13 | LL | let _ = deq.get(deq.len() - 1); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `deq.back()` error: accessing last element with `nested[0].get(nested[0].len() - 1)` - --> tests/ui/get_last_with_len.rs:46:13 + --> tests/ui/get_last_with_len.rs:51:13 | LL | let _ = nested[0].get(nested[0].len() - 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `nested[0].last()` diff --git a/tests/ui/get_unwrap.fixed b/tests/ui/get_unwrap.fixed index 2dd3c30a4e29..3115c1462f5a 100644 --- a/tests/ui/get_unwrap.fixed +++ b/tests/ui/get_unwrap.fixed @@ -35,23 +35,45 @@ fn main() { { // Test `get().unwrap()` let _ = &boxed_slice[1]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_slice[0]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_vec[0]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_vecdeque[0]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_hashmap[&1]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_btreemap[&1]; + //~^ get_unwrap + //~| unwrap_used #[allow(clippy::unwrap_used)] let _ = false_positive.get(0).unwrap(); // Test with deref let _: u8 = boxed_slice[1]; + //~^ get_unwrap + //~| unwrap_used } { // Test `get_mut().unwrap()` boxed_slice[0] = 1; + //~^ get_unwrap + //~| unwrap_used some_slice[0] = 1; + //~^ get_unwrap + //~| unwrap_used some_vec[0] = 1; + //~^ get_unwrap + //~| unwrap_used some_vecdeque[0] = 1; + //~^ get_unwrap + //~| unwrap_used // Check false positives #[allow(clippy::unwrap_used)] { @@ -64,7 +86,11 @@ fn main() { { // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()` let _ = some_vec[0..1].to_vec(); + //~^ get_unwrap + //~| unwrap_used let _ = some_vec[0..1].to_vec(); + //~^ get_unwrap + //~| unwrap_used } } mod issue9909 { @@ -76,12 +102,15 @@ mod issue9909 { // include a borrow in the suggestion, even if the argument is not just a numeric literal let _x: &i32 = &f[1 + 2]; + //~^ get_unwrap // don't include a borrow here let _x = f[1 + 2].to_string(); + //~^ get_unwrap // don't include a borrow here let _x = f[1 + 2].abs(); + //~^ get_unwrap } // original code: @@ -99,6 +128,7 @@ mod issue9909 { let (x, rest) = mat.split_at_mut(linidx(i, k) + 1); let a = x.last_mut().unwrap(); let b = &mut rest[linidx(j, k) - linidx(i, k) - 1]; + //~^ get_unwrap ::std::mem::swap(a, b); } } diff --git a/tests/ui/get_unwrap.rs b/tests/ui/get_unwrap.rs index 94226564cacb..963238a88983 100644 --- a/tests/ui/get_unwrap.rs +++ b/tests/ui/get_unwrap.rs @@ -35,23 +35,45 @@ fn main() { { // Test `get().unwrap()` let _ = boxed_slice.get(1).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_slice.get(0).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_vec.get(0).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_vecdeque.get(0).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_hashmap.get(&1).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_btreemap.get(&1).unwrap(); + //~^ get_unwrap + //~| unwrap_used #[allow(clippy::unwrap_used)] let _ = false_positive.get(0).unwrap(); // Test with deref let _: u8 = *boxed_slice.get(1).unwrap(); + //~^ get_unwrap + //~| unwrap_used } { // Test `get_mut().unwrap()` *boxed_slice.get_mut(0).unwrap() = 1; + //~^ get_unwrap + //~| unwrap_used *some_slice.get_mut(0).unwrap() = 1; + //~^ get_unwrap + //~| unwrap_used *some_vec.get_mut(0).unwrap() = 1; + //~^ get_unwrap + //~| unwrap_used *some_vecdeque.get_mut(0).unwrap() = 1; + //~^ get_unwrap + //~| unwrap_used // Check false positives #[allow(clippy::unwrap_used)] { @@ -64,7 +86,11 @@ fn main() { { // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()` let _ = some_vec.get(0..1).unwrap().to_vec(); + //~^ get_unwrap + //~| unwrap_used let _ = some_vec.get_mut(0..1).unwrap().to_vec(); + //~^ get_unwrap + //~| unwrap_used } } mod issue9909 { @@ -76,12 +102,15 @@ mod issue9909 { // include a borrow in the suggestion, even if the argument is not just a numeric literal let _x: &i32 = f.get(1 + 2).unwrap(); + //~^ get_unwrap // don't include a borrow here let _x = f.get(1 + 2).unwrap().to_string(); + //~^ get_unwrap // don't include a borrow here let _x = f.get(1 + 2).unwrap().abs(); + //~^ get_unwrap } // original code: @@ -99,6 +128,7 @@ mod issue9909 { let (x, rest) = mat.split_at_mut(linidx(i, k) + 1); let a = x.last_mut().unwrap(); let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); + //~^ get_unwrap ::std::mem::swap(a, b); } } diff --git a/tests/ui/get_unwrap.stderr b/tests/ui/get_unwrap.stderr index 8eacb249c60c..f663362dbb3e 100644 --- a/tests/ui/get_unwrap.stderr +++ b/tests/ui/get_unwrap.stderr @@ -26,7 +26,7 @@ LL | let _ = boxed_slice.get(1).unwrap(); = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]` error: called `.get().unwrap()` on a slice - --> tests/ui/get_unwrap.rs:38:17 + --> tests/ui/get_unwrap.rs:40:17 | LL | let _ = some_slice.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | let _ = &some_slice[0]; | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:38:17 + --> tests/ui/get_unwrap.rs:40:17 | LL | let _ = some_slice.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | let _ = some_slice.get(0).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec - --> tests/ui/get_unwrap.rs:39:17 + --> tests/ui/get_unwrap.rs:43:17 | LL | let _ = some_vec.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = &some_vec[0]; | ~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:39:17 + --> tests/ui/get_unwrap.rs:43:17 | LL | let _ = some_vec.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | let _ = some_vec.get(0).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a VecDeque - --> tests/ui/get_unwrap.rs:40:17 + --> tests/ui/get_unwrap.rs:46:17 | LL | let _ = some_vecdeque.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | let _ = &some_vecdeque[0]; | ~~~~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:40:17 + --> tests/ui/get_unwrap.rs:46:17 | LL | let _ = some_vecdeque.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -86,7 +86,7 @@ LL | let _ = some_vecdeque.get(0).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a HashMap - --> tests/ui/get_unwrap.rs:41:17 + --> tests/ui/get_unwrap.rs:49:17 | LL | let _ = some_hashmap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _ = &some_hashmap[&1]; | ~~~~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:41:17 + --> tests/ui/get_unwrap.rs:49:17 | LL | let _ = some_hashmap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -106,7 +106,7 @@ LL | let _ = some_hashmap.get(&1).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a BTreeMap - --> tests/ui/get_unwrap.rs:42:17 + --> tests/ui/get_unwrap.rs:52:17 | LL | let _ = some_btreemap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -117,7 +117,7 @@ LL | let _ = &some_btreemap[&1]; | ~~~~~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:42:17 + --> tests/ui/get_unwrap.rs:52:17 | LL | let _ = some_btreemap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -126,7 +126,7 @@ LL | let _ = some_btreemap.get(&1).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice - --> tests/ui/get_unwrap.rs:46:21 + --> tests/ui/get_unwrap.rs:58:21 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ LL | let _: u8 = boxed_slice[1]; | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:46:22 + --> tests/ui/get_unwrap.rs:58:22 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -146,7 +146,7 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice - --> tests/ui/get_unwrap.rs:51:9 + --> tests/ui/get_unwrap.rs:65:9 | LL | *boxed_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | boxed_slice[0] = 1; | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:51:10 + --> tests/ui/get_unwrap.rs:65:10 | LL | *boxed_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1; = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice - --> tests/ui/get_unwrap.rs:52:9 + --> tests/ui/get_unwrap.rs:68:9 | LL | *some_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | some_slice[0] = 1; | ~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:52:10 + --> tests/ui/get_unwrap.rs:68:10 | LL | *some_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -186,7 +186,7 @@ LL | *some_slice.get_mut(0).unwrap() = 1; = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec - --> tests/ui/get_unwrap.rs:53:9 + --> tests/ui/get_unwrap.rs:71:9 | LL | *some_vec.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -197,7 +197,7 @@ LL | some_vec[0] = 1; | ~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:53:10 + --> tests/ui/get_unwrap.rs:71:10 | LL | *some_vec.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +206,7 @@ LL | *some_vec.get_mut(0).unwrap() = 1; = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a VecDeque - --> tests/ui/get_unwrap.rs:54:9 + --> tests/ui/get_unwrap.rs:74:9 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | some_vecdeque[0] = 1; | ~~~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:54:10 + --> tests/ui/get_unwrap.rs:74:10 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -226,7 +226,7 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1; = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec - --> tests/ui/get_unwrap.rs:66:17 + --> tests/ui/get_unwrap.rs:88:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -237,7 +237,7 @@ LL | let _ = some_vec[0..1].to_vec(); | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:66:17 + --> tests/ui/get_unwrap.rs:88:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -246,7 +246,7 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec(); = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec - --> tests/ui/get_unwrap.rs:67:17 + --> tests/ui/get_unwrap.rs:91:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -257,7 +257,7 @@ LL | let _ = some_vec[0..1].to_vec(); | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui/get_unwrap.rs:67:17 + --> tests/ui/get_unwrap.rs:91:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -266,7 +266,7 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice - --> tests/ui/get_unwrap.rs:78:24 + --> tests/ui/get_unwrap.rs:104:24 | LL | let _x: &i32 = f.get(1 + 2).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -277,7 +277,7 @@ LL | let _x: &i32 = &f[1 + 2]; | ~~~~~~~~~ error: called `.get().unwrap()` on a slice - --> tests/ui/get_unwrap.rs:81:18 + --> tests/ui/get_unwrap.rs:108:18 | LL | let _x = f.get(1 + 2).unwrap().to_string(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -288,7 +288,7 @@ LL | let _x = f[1 + 2].to_string(); | ~~~~~~~~ error: called `.get().unwrap()` on a slice - --> tests/ui/get_unwrap.rs:84:18 + --> tests/ui/get_unwrap.rs:112:18 | LL | let _x = f.get(1 + 2).unwrap().abs(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -299,7 +299,7 @@ LL | let _x = f[1 + 2].abs(); | ~~~~~~~~ error: called `.get_mut().unwrap()` on a slice - --> tests/ui/get_unwrap.rs:101:33 + --> tests/ui/get_unwrap.rs:130:33 | LL | let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/identity_op.fixed b/tests/ui/identity_op.fixed index 2e8e2366de6f..b3836bda2b6f 100644 --- a/tests/ui/identity_op.fixed +++ b/tests/ui/identity_op.fixed @@ -42,45 +42,58 @@ fn main() { let x = 0; x; - //~^ ERROR: this operation has no effect + //~^ identity_op + x; - //~^ ERROR: this operation has no effect + //~^ identity_op + x + 1; x; - //~^ ERROR: this operation has no effect + //~^ identity_op + 1 + x; x - ZERO; //no error, as we skip lookups (for now) x; - //~^ ERROR: this operation has no effect + //~^ identity_op + ((ZERO)) | x; //no error, as we skip lookups (for now) x; - //~^ ERROR: this operation has no effect + //~^ identity_op + x; - //~^ ERROR: this operation has no effect + //~^ identity_op + x / ONE; //no error, as we skip lookups (for now) x / 2; //no false positive x & NEG_ONE; //no error, as we skip lookups (for now) x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let u: u8 = 0; u; - //~^ ERROR: this operation has no effect + //~^ identity_op + 1 << 0; // no error, this case is allowed, see issue 3430 42; - //~^ ERROR: this operation has no effect + //~^ identity_op + 1; - //~^ ERROR: this operation has no effect + //~^ identity_op + 42; - //~^ ERROR: this operation has no effect + //~^ identity_op + x; - //~^ ERROR: this operation has no effect + //~^ identity_op + x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let mut a = A(String::new()); let b = a << 0; // no error: non-integer @@ -88,15 +101,20 @@ fn main() { 1 * Meter; // no error: non-integer 2; - //~^ ERROR: this operation has no effect + //~^ identity_op + -2; - //~^ ERROR: this operation has no effect + //~^ identity_op + 2 + x; - //~^ ERROR: this operation has no effect + //~^ identity_op + -2 + x; - //~^ ERROR: this operation has no effect + //~^ identity_op + x + 1; - //~^ ERROR: this operation has no effect + //~^ identity_op + (x + 1) % 3; // no error 4 % 3; // no error 4 % -3; // no error @@ -105,63 +123,85 @@ fn main() { let a = 0; let b = true; (if b { 1 } else { 2 }); - //~^ ERROR: this operation has no effect + //~^ identity_op + (if b { 1 } else { 2 }) + if b { 3 } else { 4 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + (match a { 0 => 10, _ => 20 }); - //~^ ERROR: this operation has no effect + //~^ identity_op + (match a { 0 => 10, _ => 20 }) + match a { 0 => 30, _ => 40 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + (if b { 1 } else { 2 }) + match a { 0 => 30, _ => 40 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + (match a { 0 => 10, _ => 20 }) + if b { 3 } else { 4 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + ((if b { 1 } else { 2 })); - //~^ ERROR: this operation has no effect + //~^ identity_op + ({ a }) + 3; - //~^ ERROR: this operation has no effect + //~^ identity_op + ({ a } * 2); - //~^ ERROR: this operation has no effect + //~^ identity_op + (loop { let mut c = 0; if c == 10 { break c; } c += 1; }) + { a * 2 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + fn f(_: i32) { todo!(); } f(a + { 8 * 5 }); - //~^ ERROR: this operation has no effect + //~^ identity_op + f(if b { 1 } else { 2 } + 3); - //~^ ERROR: this operation has no effect + //~^ identity_op + const _: i32 = { 2 * 4 } + 3; - //~^ ERROR: this operation has no effect + //~^ identity_op + const _: i32 = { 1 + 2 * 3 } + 3; - //~^ ERROR: this operation has no effect + //~^ identity_op + a as usize; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _ = a as usize; - //~^ ERROR: this operation has no effect + //~^ identity_op + ({ a } as usize); - //~^ ERROR: this operation has no effect + //~^ identity_op + 2 * { a }; - //~^ ERROR: this operation has no effect + //~^ identity_op + (({ a } + 4)); - //~^ ERROR: this operation has no effect + //~^ identity_op + 1; - //~^ ERROR: this operation has no effect + //~^ identity_op + // Issue #9904 let x = 0i32; let _: i32 = x; - //~^ ERROR: this operation has no effect + //~^ identity_op + } pub fn decide(a: bool, b: bool) -> u32 { (if a { 1 } else { 2 }) + if b { 3 } else { 5 } + //~^ identity_op } /// The following tests are from / for issue #12050 @@ -173,43 +213,55 @@ fn issue_12050() { { let x = &0i32; let _: i32 = *x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = *x; - //~^ ERROR: this operation has no effect + //~^ identity_op + } { let x = &&0i32; let _: i32 = **x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let x = &&0i32; let _: i32 = **x; - //~^ ERROR: this operation has no effect + //~^ identity_op + } { // this is just silly let x = &&&0i32; let _: i32 = ***x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = ***x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let x = 0i32; let _: i32 = *&x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = **&&x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = *&*&x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = **&&*&x; - //~^ ERROR: this operation has no effect + //~^ identity_op + } { // this is getting ridiculous, but we should still see the same // error message so let's just keep going let x = &0i32; let _: i32 = ***&&*&x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = ***&&*&x; - //~^ ERROR: this operation has no effect + //~^ identity_op + } } @@ -218,41 +270,52 @@ fn issue_13470() { let y = 1i32; // Removes the + 0i32 while keeping the parentheses around x + y so the cast operation works let _: u64 = (x + y) as u64; - //~^ ERROR: this operation has no effect + //~^ identity_op + // both of the next two lines should look the same after rustfix let _: u64 = 1u64 & (x + y) as u64; - //~^ ERROR: this operation has no effect + //~^ identity_op + // Same as above, but with extra redundant parenthesis let _: u64 = 1u64 & ((x + y)) as u64; - //~^ ERROR: this operation has no effect + //~^ identity_op + // Should maintain parenthesis even if the surrounding expr has the same precedence let _: u64 = 5u64 + ((x + y)) as u64; - //~^ ERROR: this operation has no effect + //~^ identity_op + // If we don't maintain the parens here, the behavior changes let _ = -(x + y); - //~^ ERROR: this operation has no effect + //~^ identity_op + // Similarly, we need to maintain parens here let _ = -(x / y); - //~^ ERROR: this operation has no effect + //~^ identity_op + // Maintain parenthesis if the parent expr is of higher precedence let _ = 2i32 * (x + y); - //~^ ERROR: this operation has no effect + //~^ identity_op + // Maintain parenthesis if the parent expr is the same precedence // as not all operations are associative let _ = 2i32 - (x - y); - //~^ ERROR: this operation has no effect + //~^ identity_op + // But make sure that inner parens still exist let z = 1i32; let _ = 2 + (x + (y * z)); - //~^ ERROR: this operation has no effect + //~^ identity_op + // Maintain parenthesis if the parent expr is of lower precedence // This is for clarity, and clippy will not warn on these being unnecessary let _ = 2i32 + (x * y); - //~^ ERROR: this operation has no effect + //~^ identity_op + let x = 1i16; let y = 1i16; let _: u64 = 1u64 + ((x as i32 + y as i32) as u64); - //~^ ERROR: this operation has no effect + //~^ identity_op + } diff --git a/tests/ui/identity_op.rs b/tests/ui/identity_op.rs index 3e20fa6f2b89..9d545a95bdd3 100644 --- a/tests/ui/identity_op.rs +++ b/tests/ui/identity_op.rs @@ -42,45 +42,58 @@ fn main() { let x = 0; x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + x + (1 - 1); - //~^ ERROR: this operation has no effect + //~^ identity_op + x + 1; 0 + x; - //~^ ERROR: this operation has no effect + //~^ identity_op + 1 + x; x - ZERO; //no error, as we skip lookups (for now) x | (0); - //~^ ERROR: this operation has no effect + //~^ identity_op + ((ZERO)) | x; //no error, as we skip lookups (for now) x * 1; - //~^ ERROR: this operation has no effect + //~^ identity_op + 1 * x; - //~^ ERROR: this operation has no effect + //~^ identity_op + x / ONE; //no error, as we skip lookups (for now) x / 2; //no false positive x & NEG_ONE; //no error, as we skip lookups (for now) -1 & x; - //~^ ERROR: this operation has no effect + //~^ identity_op + let u: u8 = 0; u & 255; - //~^ ERROR: this operation has no effect + //~^ identity_op + 1 << 0; // no error, this case is allowed, see issue 3430 42 << 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + 1 >> 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + 42 >> 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + &x >> 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + x >> &0; - //~^ ERROR: this operation has no effect + //~^ identity_op + let mut a = A(String::new()); let b = a << 0; // no error: non-integer @@ -88,15 +101,20 @@ fn main() { 1 * Meter; // no error: non-integer 2 % 3; - //~^ ERROR: this operation has no effect + //~^ identity_op + -2 % 3; - //~^ ERROR: this operation has no effect + //~^ identity_op + 2 % -3 + x; - //~^ ERROR: this operation has no effect + //~^ identity_op + -2 % -3 + x; - //~^ ERROR: this operation has no effect + //~^ identity_op + x + 1 % 3; - //~^ ERROR: this operation has no effect + //~^ identity_op + (x + 1) % 3; // no error 4 % 3; // no error 4 % -3; // no error @@ -105,63 +123,85 @@ fn main() { let a = 0; let b = true; 0 + if b { 1 } else { 2 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + if b { 1 } else { 2 } + if b { 3 } else { 4 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + match a { 0 => 10, _ => 20 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + match a { 0 => 10, _ => 20 } + match a { 0 => 30, _ => 40 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + if b { 1 } else { 2 } + match a { 0 => 30, _ => 40 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + match a { 0 => 10, _ => 20 } + if b { 3 } else { 4 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + (if b { 1 } else { 2 }) + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + { a } + 3; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + { a } * 2; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + loop { let mut c = 0; if c == 10 { break c; } c += 1; } + { a * 2 }; - //~^ ERROR: this operation has no effect + //~^ identity_op + fn f(_: i32) { todo!(); } f(1 * a + { 8 * 5 }); - //~^ ERROR: this operation has no effect + //~^ identity_op + f(0 + if b { 1 } else { 2 } + 3); - //~^ ERROR: this operation has no effect + //~^ identity_op + const _: i32 = { 2 * 4 } + 0 + 3; - //~^ ERROR: this operation has no effect + //~^ identity_op + const _: i32 = 0 + { 1 + 2 * 3 } + 3; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + a as usize; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _ = 0 + a as usize; - //~^ ERROR: this operation has no effect + //~^ identity_op + 0 + { a } as usize; - //~^ ERROR: this operation has no effect + //~^ identity_op + 2 * (0 + { a }); - //~^ ERROR: this operation has no effect + //~^ identity_op + 1 * ({ a } + 4); - //~^ ERROR: this operation has no effect + //~^ identity_op + 1 * 1; - //~^ ERROR: this operation has no effect + //~^ identity_op + // Issue #9904 let x = 0i32; let _: i32 = &x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + } pub fn decide(a: bool, b: bool) -> u32 { 0 + if a { 1 } else { 2 } + if b { 3 } else { 5 } + //~^ identity_op } /// The following tests are from / for issue #12050 @@ -173,43 +213,55 @@ fn issue_12050() { { let x = &0i32; let _: i32 = *x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + } { let x = &&0i32; let _: i32 = **x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + let x = &&0i32; let _: i32 = *x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + } { // this is just silly let x = &&&0i32; let _: i32 = ***x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = **x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + let x = 0i32; let _: i32 = *&x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = **&&x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = *&*&x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = **&&*&x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + } { // this is getting ridiculous, but we should still see the same // error message so let's just keep going let x = &0i32; let _: i32 = **&&*&x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + let _: i32 = **&&*&x + 0; - //~^ ERROR: this operation has no effect + //~^ identity_op + } } @@ -218,41 +270,52 @@ fn issue_13470() { let y = 1i32; // Removes the + 0i32 while keeping the parentheses around x + y so the cast operation works let _: u64 = (x + y + 0i32) as u64; - //~^ ERROR: this operation has no effect + //~^ identity_op + // both of the next two lines should look the same after rustfix let _: u64 = 1u64 & (x + y + 0i32) as u64; - //~^ ERROR: this operation has no effect + //~^ identity_op + // Same as above, but with extra redundant parenthesis let _: u64 = 1u64 & ((x + y) + 0i32) as u64; - //~^ ERROR: this operation has no effect + //~^ identity_op + // Should maintain parenthesis even if the surrounding expr has the same precedence let _: u64 = 5u64 + ((x + y) + 0i32) as u64; - //~^ ERROR: this operation has no effect + //~^ identity_op + // If we don't maintain the parens here, the behavior changes let _ = -(x + y + 0i32); - //~^ ERROR: this operation has no effect + //~^ identity_op + // Similarly, we need to maintain parens here let _ = -(x / y / 1i32); - //~^ ERROR: this operation has no effect + //~^ identity_op + // Maintain parenthesis if the parent expr is of higher precedence let _ = 2i32 * (x + y + 0i32); - //~^ ERROR: this operation has no effect + //~^ identity_op + // Maintain parenthesis if the parent expr is the same precedence // as not all operations are associative let _ = 2i32 - (x - y - 0i32); - //~^ ERROR: this operation has no effect + //~^ identity_op + // But make sure that inner parens still exist let z = 1i32; let _ = 2 + (x + (y * z) + 0); - //~^ ERROR: this operation has no effect + //~^ identity_op + // Maintain parenthesis if the parent expr is of lower precedence // This is for clarity, and clippy will not warn on these being unnecessary let _ = 2i32 + (x * y * 1i32); - //~^ ERROR: this operation has no effect + //~^ identity_op + let x = 1i16; let y = 1i16; let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64); - //~^ ERROR: this operation has no effect + //~^ identity_op + } diff --git a/tests/ui/identity_op.stderr b/tests/ui/identity_op.stderr index 99a58ef2c1b5..8952f2fb7b8b 100644 --- a/tests/ui/identity_op.stderr +++ b/tests/ui/identity_op.stderr @@ -8,373 +8,373 @@ LL | x + 0; = help: to override `-D warnings` add `#[allow(clippy::identity_op)]` error: this operation has no effect - --> tests/ui/identity_op.rs:46:5 + --> tests/ui/identity_op.rs:47:5 | LL | x + (1 - 1); | ^^^^^^^^^^^ help: consider reducing it to: `x` error: this operation has no effect - --> tests/ui/identity_op.rs:49:5 + --> tests/ui/identity_op.rs:51:5 | LL | 0 + x; | ^^^^^ help: consider reducing it to: `x` error: this operation has no effect - --> tests/ui/identity_op.rs:53:5 + --> tests/ui/identity_op.rs:56:5 | LL | x | (0); | ^^^^^^^ help: consider reducing it to: `x` error: this operation has no effect - --> tests/ui/identity_op.rs:57:5 + --> tests/ui/identity_op.rs:61:5 | LL | x * 1; | ^^^^^ help: consider reducing it to: `x` error: this operation has no effect - --> tests/ui/identity_op.rs:59:5 + --> tests/ui/identity_op.rs:64:5 | LL | 1 * x; | ^^^^^ help: consider reducing it to: `x` error: this operation has no effect - --> tests/ui/identity_op.rs:66:5 + --> tests/ui/identity_op.rs:72:5 | LL | -1 & x; | ^^^^^^ help: consider reducing it to: `x` error: this operation has no effect - --> tests/ui/identity_op.rs:70:5 + --> tests/ui/identity_op.rs:77:5 | LL | u & 255; | ^^^^^^^ help: consider reducing it to: `u` error: this operation has no effect - --> tests/ui/identity_op.rs:74:5 + --> tests/ui/identity_op.rs:82:5 | LL | 42 << 0; | ^^^^^^^ help: consider reducing it to: `42` error: this operation has no effect - --> tests/ui/identity_op.rs:76:5 + --> tests/ui/identity_op.rs:85:5 | LL | 1 >> 0; | ^^^^^^ help: consider reducing it to: `1` error: this operation has no effect - --> tests/ui/identity_op.rs:78:5 + --> tests/ui/identity_op.rs:88:5 | LL | 42 >> 0; | ^^^^^^^ help: consider reducing it to: `42` error: this operation has no effect - --> tests/ui/identity_op.rs:80:5 + --> tests/ui/identity_op.rs:91:5 | LL | &x >> 0; | ^^^^^^^ help: consider reducing it to: `x` error: this operation has no effect - --> tests/ui/identity_op.rs:82:5 + --> tests/ui/identity_op.rs:94:5 | LL | x >> &0; | ^^^^^^^ help: consider reducing it to: `x` error: this operation has no effect - --> tests/ui/identity_op.rs:90:5 + --> tests/ui/identity_op.rs:103:5 | LL | 2 % 3; | ^^^^^ help: consider reducing it to: `2` error: this operation has no effect - --> tests/ui/identity_op.rs:92:5 + --> tests/ui/identity_op.rs:106:5 | LL | -2 % 3; | ^^^^^^ help: consider reducing it to: `-2` error: this operation has no effect - --> tests/ui/identity_op.rs:94:5 + --> tests/ui/identity_op.rs:109:5 | LL | 2 % -3 + x; | ^^^^^^ help: consider reducing it to: `2` error: this operation has no effect - --> tests/ui/identity_op.rs:96:5 + --> tests/ui/identity_op.rs:112:5 | LL | -2 % -3 + x; | ^^^^^^^ help: consider reducing it to: `-2` error: this operation has no effect - --> tests/ui/identity_op.rs:98:9 + --> tests/ui/identity_op.rs:115:9 | LL | x + 1 % 3; | ^^^^^ help: consider reducing it to: `1` error: this operation has no effect - --> tests/ui/identity_op.rs:107:5 + --> tests/ui/identity_op.rs:125:5 | LL | 0 + if b { 1 } else { 2 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })` error: this operation has no effect - --> tests/ui/identity_op.rs:109:5 + --> tests/ui/identity_op.rs:128:5 | LL | 0 + if b { 1 } else { 2 } + if b { 3 } else { 4 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })` error: this operation has no effect - --> tests/ui/identity_op.rs:111:5 + --> tests/ui/identity_op.rs:131:5 | LL | 0 + match a { 0 => 10, _ => 20 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(match a { 0 => 10, _ => 20 })` error: this operation has no effect - --> tests/ui/identity_op.rs:113:5 + --> tests/ui/identity_op.rs:134:5 | LL | 0 + match a { 0 => 10, _ => 20 } + match a { 0 => 30, _ => 40 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(match a { 0 => 10, _ => 20 })` error: this operation has no effect - --> tests/ui/identity_op.rs:115:5 + --> tests/ui/identity_op.rs:137:5 | LL | 0 + if b { 1 } else { 2 } + match a { 0 => 30, _ => 40 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })` error: this operation has no effect - --> tests/ui/identity_op.rs:117:5 + --> tests/ui/identity_op.rs:140:5 | LL | 0 + match a { 0 => 10, _ => 20 } + if b { 3 } else { 4 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(match a { 0 => 10, _ => 20 })` error: this operation has no effect - --> tests/ui/identity_op.rs:119:5 + --> tests/ui/identity_op.rs:143:5 | LL | (if b { 1 } else { 2 }) + 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `((if b { 1 } else { 2 }))` error: this operation has no effect - --> tests/ui/identity_op.rs:122:5 + --> tests/ui/identity_op.rs:147:5 | LL | 0 + { a } + 3; | ^^^^^^^^^ help: consider reducing it to: `({ a })` error: this operation has no effect - --> tests/ui/identity_op.rs:124:5 + --> tests/ui/identity_op.rs:150:5 | LL | 0 + { a } * 2; | ^^^^^^^^^^^^^ help: consider reducing it to: `({ a } * 2)` error: this operation has no effect - --> tests/ui/identity_op.rs:126:5 + --> tests/ui/identity_op.rs:153:5 | LL | 0 + loop { let mut c = 0; if c == 10 { break c; } c += 1; } + { a * 2 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(loop { let mut c = 0; if c == 10 { break c; } c += 1; })` error: this operation has no effect - --> tests/ui/identity_op.rs:133:7 + --> tests/ui/identity_op.rs:161:7 | LL | f(1 * a + { 8 * 5 }); | ^^^^^ help: consider reducing it to: `a` error: this operation has no effect - --> tests/ui/identity_op.rs:135:7 + --> tests/ui/identity_op.rs:164:7 | LL | f(0 + if b { 1 } else { 2 } + 3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `if b { 1 } else { 2 }` error: this operation has no effect - --> tests/ui/identity_op.rs:138:20 + --> tests/ui/identity_op.rs:168:20 | LL | const _: i32 = { 2 * 4 } + 0 + 3; | ^^^^^^^^^^^^^ help: consider reducing it to: `{ 2 * 4 }` error: this operation has no effect - --> tests/ui/identity_op.rs:140:20 + --> tests/ui/identity_op.rs:171:20 | LL | const _: i32 = 0 + { 1 + 2 * 3 } + 3; | ^^^^^^^^^^^^^^^^^ help: consider reducing it to: `{ 1 + 2 * 3 }` error: this operation has no effect - --> tests/ui/identity_op.rs:143:5 + --> tests/ui/identity_op.rs:175:5 | LL | 0 + a as usize; | ^^^^^^^^^^^^^^ help: consider reducing it to: `a as usize` error: this operation has no effect - --> tests/ui/identity_op.rs:145:13 + --> tests/ui/identity_op.rs:178:13 | LL | let _ = 0 + a as usize; | ^^^^^^^^^^^^^^ help: consider reducing it to: `a as usize` error: this operation has no effect - --> tests/ui/identity_op.rs:147:5 + --> tests/ui/identity_op.rs:181:5 | LL | 0 + { a } as usize; | ^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `({ a } as usize)` error: this operation has no effect - --> tests/ui/identity_op.rs:150:9 + --> tests/ui/identity_op.rs:185:9 | LL | 2 * (0 + { a }); | ^^^^^^^^^^^ help: consider reducing it to: `{ a }` error: this operation has no effect - --> tests/ui/identity_op.rs:152:5 + --> tests/ui/identity_op.rs:188:5 | LL | 1 * ({ a } + 4); | ^^^^^^^^^^^^^^^ help: consider reducing it to: `(({ a } + 4))` error: this operation has no effect - --> tests/ui/identity_op.rs:154:5 + --> tests/ui/identity_op.rs:191:5 | LL | 1 * 1; | ^^^^^ help: consider reducing it to: `1` error: this operation has no effect - --> tests/ui/identity_op.rs:159:18 + --> tests/ui/identity_op.rs:197:18 | LL | let _: i32 = &x + 0; | ^^^^^^ help: consider reducing it to: `x` error: this operation has no effect - --> tests/ui/identity_op.rs:164:5 + --> tests/ui/identity_op.rs:203:5 | LL | 0 + if a { 1 } else { 2 } + if b { 3 } else { 5 } | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if a { 1 } else { 2 })` error: this operation has no effect - --> tests/ui/identity_op.rs:175:22 + --> tests/ui/identity_op.rs:215:22 | LL | let _: i32 = *x + 0; | ^^^^^^ help: consider reducing it to: `*x` error: this operation has no effect - --> tests/ui/identity_op.rs:177:22 + --> tests/ui/identity_op.rs:218:22 | LL | let _: i32 = x + 0; | ^^^^^ help: consider reducing it to: `*x` error: this operation has no effect - --> tests/ui/identity_op.rs:182:22 + --> tests/ui/identity_op.rs:224:22 | LL | let _: i32 = **x + 0; | ^^^^^^^ help: consider reducing it to: `**x` error: this operation has no effect - --> tests/ui/identity_op.rs:185:22 + --> tests/ui/identity_op.rs:228:22 | LL | let _: i32 = *x + 0; | ^^^^^^ help: consider reducing it to: `**x` error: this operation has no effect - --> tests/ui/identity_op.rs:191:22 + --> tests/ui/identity_op.rs:235:22 | LL | let _: i32 = ***x + 0; | ^^^^^^^^ help: consider reducing it to: `***x` error: this operation has no effect - --> tests/ui/identity_op.rs:193:22 + --> tests/ui/identity_op.rs:238:22 | LL | let _: i32 = **x + 0; | ^^^^^^^ help: consider reducing it to: `***x` error: this operation has no effect - --> tests/ui/identity_op.rs:196:22 + --> tests/ui/identity_op.rs:242:22 | LL | let _: i32 = *&x + 0; | ^^^^^^^ help: consider reducing it to: `*&x` error: this operation has no effect - --> tests/ui/identity_op.rs:198:22 + --> tests/ui/identity_op.rs:245:22 | LL | let _: i32 = **&&x + 0; | ^^^^^^^^^ help: consider reducing it to: `**&&x` error: this operation has no effect - --> tests/ui/identity_op.rs:200:22 + --> tests/ui/identity_op.rs:248:22 | LL | let _: i32 = *&*&x + 0; | ^^^^^^^^^ help: consider reducing it to: `*&*&x` error: this operation has no effect - --> tests/ui/identity_op.rs:202:22 + --> tests/ui/identity_op.rs:251:22 | LL | let _: i32 = **&&*&x + 0; | ^^^^^^^^^^^ help: consider reducing it to: `**&&*&x` error: this operation has no effect - --> tests/ui/identity_op.rs:209:22 + --> tests/ui/identity_op.rs:259:22 | LL | let _: i32 = **&&*&x + 0; | ^^^^^^^^^^^ help: consider reducing it to: `***&&*&x` error: this operation has no effect - --> tests/ui/identity_op.rs:211:22 + --> tests/ui/identity_op.rs:262:22 | LL | let _: i32 = **&&*&x + 0; | ^^^^^^^^^^^ help: consider reducing it to: `***&&*&x` error: this operation has no effect - --> tests/ui/identity_op.rs:220:18 + --> tests/ui/identity_op.rs:272:18 | LL | let _: u64 = (x + y + 0i32) as u64; | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)` error: this operation has no effect - --> tests/ui/identity_op.rs:223:25 + --> tests/ui/identity_op.rs:276:25 | LL | let _: u64 = 1u64 & (x + y + 0i32) as u64; | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)` error: this operation has no effect - --> tests/ui/identity_op.rs:226:25 + --> tests/ui/identity_op.rs:280:25 | LL | let _: u64 = 1u64 & ((x + y) + 0i32) as u64; | ^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x + y))` error: this operation has no effect - --> tests/ui/identity_op.rs:229:25 + --> tests/ui/identity_op.rs:284:25 | LL | let _: u64 = 5u64 + ((x + y) + 0i32) as u64; | ^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x + y))` error: this operation has no effect - --> tests/ui/identity_op.rs:233:14 + --> tests/ui/identity_op.rs:289:14 | LL | let _ = -(x + y + 0i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)` error: this operation has no effect - --> tests/ui/identity_op.rs:236:14 + --> tests/ui/identity_op.rs:293:14 | LL | let _ = -(x / y / 1i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x / y)` error: this operation has no effect - --> tests/ui/identity_op.rs:239:20 + --> tests/ui/identity_op.rs:297:20 | LL | let _ = 2i32 * (x + y + 0i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)` error: this operation has no effect - --> tests/ui/identity_op.rs:243:20 + --> tests/ui/identity_op.rs:302:20 | LL | let _ = 2i32 - (x - y - 0i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x - y)` error: this operation has no effect - --> tests/ui/identity_op.rs:247:17 + --> tests/ui/identity_op.rs:307:17 | LL | let _ = 2 + (x + (y * z) + 0); | ^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(x + (y * z))` error: this operation has no effect - --> tests/ui/identity_op.rs:251:20 + --> tests/ui/identity_op.rs:312:20 | LL | let _ = 2i32 + (x * y * 1i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x * y)` error: this operation has no effect - --> tests/ui/identity_op.rs:256:25 + --> tests/ui/identity_op.rs:318:25 | LL | let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x as i32 + y as i32) as u64)` diff --git a/tests/ui/if_let_mutex.rs b/tests/ui/if_let_mutex.rs index 80eee2939890..ddf178b63048 100644 --- a/tests/ui/if_let_mutex.rs +++ b/tests/ui/if_let_mutex.rs @@ -62,6 +62,10 @@ fn multiple_mutexes(m1: &Mutex<()>, m2: &Mutex<()>) { } else { m1.lock(); } + //~^ if_let_mutex + //~^ if_let_mutex + //~^ if_let_mutex + //~^ if_let_mutex } fn main() {} diff --git a/tests/ui/if_not_else.fixed b/tests/ui/if_not_else.fixed index 11d1e13179c4..1b58bdda5217 100644 --- a/tests/ui/if_not_else.fixed +++ b/tests/ui/if_not_else.fixed @@ -12,13 +12,15 @@ fn main() { if bla() { println!("Bunny"); } else { - //~^ ERROR: unnecessary boolean `not` operation + //~^ if_not_else + println!("Bugs"); } if 4 == 5 { println!("Bunny"); } else { - //~^ ERROR: unnecessary `!=` operation + //~^ if_not_else + println!("Bugs"); } if !foo() { @@ -32,6 +34,7 @@ fn main() { if (foo() && bla()) { println!("both true"); } else { + //~^ if_not_else #[cfg(not(debug_assertions))] println!("not debug"); #[cfg(debug_assertions)] @@ -50,6 +53,7 @@ fn with_comments() { if foo() { println!("foo"); /* foo */ } else { + //~^ if_not_else /* foo is false */ println!("foo is false"); } @@ -57,6 +61,7 @@ fn with_comments() { if bla() { println!("bla"); // bla } else { + //~^ if_not_else // bla is false println!("bla"); } @@ -67,6 +72,7 @@ fn with_annotations() { if foo() { println!("foo"); /* foo */ } else { + //~^ if_not_else /* foo is false */ println!("foo is false"); } diff --git a/tests/ui/if_not_else.rs b/tests/ui/if_not_else.rs index fcc67e163e8a..0d035e283774 100644 --- a/tests/ui/if_not_else.rs +++ b/tests/ui/if_not_else.rs @@ -10,13 +10,15 @@ fn bla() -> bool { fn main() { if !bla() { - //~^ ERROR: unnecessary boolean `not` operation + //~^ if_not_else + println!("Bugs"); } else { println!("Bunny"); } if 4 != 5 { - //~^ ERROR: unnecessary `!=` operation + //~^ if_not_else + println!("Bugs"); } else { println!("Bunny"); @@ -30,6 +32,7 @@ fn main() { } if !(foo() && bla()) { + //~^ if_not_else #[cfg(not(debug_assertions))] println!("not debug"); #[cfg(debug_assertions)] @@ -48,6 +51,7 @@ fn main() { fn with_comments() { if !foo() { + //~^ if_not_else /* foo is false */ println!("foo is false"); } else { @@ -55,6 +59,7 @@ fn with_comments() { } if !bla() { + //~^ if_not_else // bla is false println!("bla"); } else { @@ -65,6 +70,7 @@ fn with_comments() { fn with_annotations() { #[cfg(debug_assertions)] if !foo() { + //~^ if_not_else /* foo is false */ println!("foo is false"); } else { diff --git a/tests/ui/if_not_else.stderr b/tests/ui/if_not_else.stderr index b01cb5af11f7..f44dd0aabc86 100644 --- a/tests/ui/if_not_else.stderr +++ b/tests/ui/if_not_else.stderr @@ -3,6 +3,7 @@ error: unnecessary boolean `not` operation | LL | / if !bla() { LL | | +LL | | LL | | println!("Bugs"); LL | | } else { LL | | println!("Bunny"); @@ -17,15 +18,17 @@ LL ~ if bla() { LL + println!("Bunny"); LL + } else { LL + +LL + LL + println!("Bugs"); LL + } | error: unnecessary `!=` operation - --> tests/ui/if_not_else.rs:18:5 + --> tests/ui/if_not_else.rs:19:5 | LL | / if 4 != 5 { LL | | +LL | | LL | | println!("Bugs"); LL | | } else { LL | | println!("Bunny"); @@ -38,17 +41,18 @@ LL ~ if 4 == 5 { LL + println!("Bunny"); LL + } else { LL + +LL + LL + println!("Bugs"); LL + } | error: unnecessary boolean `not` operation - --> tests/ui/if_not_else.rs:32:5 + --> tests/ui/if_not_else.rs:34:5 | LL | / if !(foo() && bla()) { +LL | | LL | | #[cfg(not(debug_assertions))] LL | | println!("not debug"); -LL | | #[cfg(debug_assertions)] ... | LL | | println!("both true"); LL | | } @@ -59,6 +63,7 @@ help: try LL ~ if (foo() && bla()) { LL + println!("both true"); LL + } else { +LL + LL + #[cfg(not(debug_assertions))] LL + println!("not debug"); LL + #[cfg(debug_assertions)] @@ -74,9 +79,10 @@ LL + } | error: unnecessary boolean `not` operation - --> tests/ui/if_not_else.rs:50:5 + --> tests/ui/if_not_else.rs:53:5 | LL | / if !foo() { +LL | | LL | | /* foo is false */ LL | | println!("foo is false"); LL | | } else { @@ -89,15 +95,17 @@ help: try LL ~ if foo() { LL + println!("foo"); /* foo */ LL + } else { +LL + LL + /* foo is false */ LL + println!("foo is false"); LL + } | error: unnecessary boolean `not` operation - --> tests/ui/if_not_else.rs:57:5 + --> tests/ui/if_not_else.rs:61:5 | LL | / if !bla() { +LL | | LL | | // bla is false LL | | println!("bla"); LL | | } else { @@ -110,15 +118,17 @@ help: try LL ~ if bla() { LL + println!("bla"); // bla LL + } else { +LL + LL + // bla is false LL + println!("bla"); LL + } | error: unnecessary boolean `not` operation - --> tests/ui/if_not_else.rs:67:5 + --> tests/ui/if_not_else.rs:72:5 | LL | / if !foo() { +LL | | LL | | /* foo is false */ LL | | println!("foo is false"); LL | | } else { @@ -131,6 +141,7 @@ help: try LL ~ if foo() { LL + println!("foo"); /* foo */ LL + } else { +LL + LL + /* foo is false */ LL + println!("foo is false"); LL + } diff --git a/tests/ui/if_not_else_bittest.rs b/tests/ui/if_not_else_bittest.rs index 586ce6ce1bcc..205823c5a8ab 100644 --- a/tests/ui/if_not_else_bittest.rs +++ b/tests/ui/if_not_else_bittest.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![deny(clippy::if_not_else)] fn show_permissions(flags: u32) { diff --git a/tests/ui/if_same_then_else.rs b/tests/ui/if_same_then_else.rs index d53e1383d845..5eaf4015b77b 100644 --- a/tests/ui/if_same_then_else.rs +++ b/tests/ui/if_same_then_else.rs @@ -37,7 +37,8 @@ fn if_same_then_else() { 0..=10; foo(); } - //~^^^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks + //~^^^^^^^^^^^^^^^^^ if_same_then_else + if true { Foo { bar: 42 }; @@ -65,10 +66,12 @@ fn if_same_then_else() { } let _ = if true { 0.0 } else { 0.0 }; - //~^ ERROR: this `if` has identical blocks + //~^ if_same_then_else + let _ = if true { -0.0 } else { -0.0 }; - //~^ ERROR: this `if` has identical blocks + //~^ if_same_then_else + let _ = if true { 0.0 } else { -0.0 }; @@ -80,7 +83,8 @@ fn if_same_then_else() { } let _ = if true { 42 } else { 42 }; - //~^ ERROR: this `if` has identical blocks + //~^ if_same_then_else + if true { let bar = if true { 42 } else { 43 }; @@ -97,7 +101,8 @@ fn if_same_then_else() { } bar + 1; } - //~^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks + //~^^^^^^^^^^^^^^^ if_same_then_else + if true { let _ = match 42 { @@ -240,6 +245,7 @@ mod issue_11213 { } else { 0_u8.is_power_of_two() } + //~^^^^^ if_same_then_else } } diff --git a/tests/ui/if_same_then_else.stderr b/tests/ui/if_same_then_else.stderr index b76da3fb1cb5..e715dbfa2258 100644 --- a/tests/ui/if_same_then_else.stderr +++ b/tests/ui/if_same_then_else.stderr @@ -27,43 +27,43 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]` error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:67:21 + --> tests/ui/if_same_then_else.rs:68:21 | LL | let _ = if true { 0.0 } else { 0.0 }; | ^^^^^^^ | note: same as this - --> tests/ui/if_same_then_else.rs:67:34 + --> tests/ui/if_same_then_else.rs:68:34 | LL | let _ = if true { 0.0 } else { 0.0 }; | ^^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:70:21 + --> tests/ui/if_same_then_else.rs:72:21 | LL | let _ = if true { -0.0 } else { -0.0 }; | ^^^^^^^^ | note: same as this - --> tests/ui/if_same_then_else.rs:70:35 + --> tests/ui/if_same_then_else.rs:72:35 | LL | let _ = if true { -0.0 } else { -0.0 }; | ^^^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:82:21 + --> tests/ui/if_same_then_else.rs:85:21 | LL | let _ = if true { 42 } else { 42 }; | ^^^^^^ | note: same as this - --> tests/ui/if_same_then_else.rs:82:33 + --> tests/ui/if_same_then_else.rs:85:33 | LL | let _ = if true { 42 } else { 42 }; | ^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:85:13 + --> tests/ui/if_same_then_else.rs:89:13 | LL | if true { | _____________^ @@ -76,7 +76,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else.rs:92:12 + --> tests/ui/if_same_then_else.rs:96:12 | LL | } else { | ____________^ @@ -89,7 +89,7 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:238:14 + --> tests/ui/if_same_then_else.rs:243:14 | LL | if x { | ______________^ @@ -98,7 +98,7 @@ LL | | } else { | |_________^ | note: same as this - --> tests/ui/if_same_then_else.rs:240:16 + --> tests/ui/if_same_then_else.rs:245:16 | LL | } else { | ________________^ diff --git a/tests/ui/if_same_then_else2.rs b/tests/ui/if_same_then_else2.rs index e23c77b08274..2ccd85224cd3 100644 --- a/tests/ui/if_same_then_else2.rs +++ b/tests/ui/if_same_then_else2.rs @@ -31,21 +31,24 @@ fn if_same_then_else2() -> Result<&'static str, ()> { } } } - //~^^^^^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks + //~^^^^^^^^^^^^^^^^^^^ if_same_then_else + if true { if let Some(a) = Some(42) {} } else { if let Some(a) = Some(42) {} } - //~^^^^^ ERROR: this `if` has identical blocks + //~^^^^^ if_same_then_else + if true { if let (1, .., 3) = (1, 2, 3) {} } else { if let (1, .., 3) = (1, 2, 3) {} } - //~^^^^^ ERROR: this `if` has identical blocks + //~^^^^^ if_same_then_else + if true { if let (1, .., 3) = (1, 2, 3) {} @@ -91,14 +94,16 @@ fn if_same_then_else2() -> Result<&'static str, ()> { // Same NaNs let _ = if true { f32::NAN } else { f32::NAN }; - //~^ ERROR: this `if` has identical blocks + //~^ if_same_then_else + if true { Ok("foo")?; } else { Ok("foo")?; } - //~^^^^^ ERROR: this `if` has identical blocks + //~^^^^^ if_same_then_else + if true { let foo = ""; @@ -124,7 +129,8 @@ fn if_same_then_else2() -> Result<&'static str, ()> { let foo = ""; return Ok(&foo[0..]); } - //~^^^^^^^ ERROR: this `if` has identical blocks + //~^^^^^^^ if_same_then_else + // False positive `if_same_then_else`: `let (x, y)` vs. `let (y, x)`; see issue #3559. if true { diff --git a/tests/ui/if_same_then_else2.stderr b/tests/ui/if_same_then_else2.stderr index 369d6f667372..3465482f9872 100644 --- a/tests/ui/if_same_then_else2.stderr +++ b/tests/ui/if_same_then_else2.stderr @@ -25,7 +25,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]` error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:36:13 + --> tests/ui/if_same_then_else2.rs:37:13 | LL | if true { | _____________^ @@ -34,7 +34,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else2.rs:38:12 + --> tests/ui/if_same_then_else2.rs:39:12 | LL | } else { | ____________^ @@ -43,7 +43,7 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:43:13 + --> tests/ui/if_same_then_else2.rs:45:13 | LL | if true { | _____________^ @@ -52,7 +52,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else2.rs:45:12 + --> tests/ui/if_same_then_else2.rs:47:12 | LL | } else { | ____________^ @@ -61,19 +61,19 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:93:21 + --> tests/ui/if_same_then_else2.rs:96:21 | LL | let _ = if true { f32::NAN } else { f32::NAN }; | ^^^^^^^^^^^^ | note: same as this - --> tests/ui/if_same_then_else2.rs:93:39 + --> tests/ui/if_same_then_else2.rs:96:39 | LL | let _ = if true { f32::NAN } else { f32::NAN }; | ^^^^^^^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:96:13 + --> tests/ui/if_same_then_else2.rs:100:13 | LL | if true { | _____________^ @@ -82,7 +82,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else2.rs:98:12 + --> tests/ui/if_same_then_else2.rs:102:12 | LL | } else { | ____________^ @@ -91,7 +91,7 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:120:20 + --> tests/ui/if_same_then_else2.rs:125:20 | LL | } else if true { | ____________________^ @@ -101,7 +101,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else2.rs:123:12 + --> tests/ui/if_same_then_else2.rs:128:12 | LL | } else { | ____________^ diff --git a/tests/ui/if_then_some_else_none.fixed b/tests/ui/if_then_some_else_none.fixed index 1f47dddcbc40..1f9ea9bf9bc0 100644 --- a/tests/ui/if_then_some_else_none.fixed +++ b/tests/ui/if_then_some_else_none.fixed @@ -11,12 +11,14 @@ fn main() { // Should issue an error. Binary expression `o < 32` should be parenthesized. let x = Some(5); let _ = x.and_then(|o| (o < 32).then_some(o)); - //~^ ERROR: this could be simplified with `bool::then_some` + //~^ if_then_some_else_none + // Should issue an error. Unary expression `!x` should be parenthesized. let x = true; let _ = (!x).then_some(0); - //~^ ERROR: this could be simplified with `bool::then_some` + //~^ if_then_some_else_none + // Should not issue an error since the `else` block has a statement besides `None`. let _ = if foo() { @@ -115,6 +117,7 @@ fn issue11394(b: bool, v: Result<(), ()>) -> Result<(), ()> { fn issue13407(s: &str) -> Option { (s == "1").then(|| true) + //~^ if_then_some_else_none } const fn issue12103(x: u32) -> Option { diff --git a/tests/ui/if_then_some_else_none.rs b/tests/ui/if_then_some_else_none.rs index 499f008fb876..238d524a5522 100644 --- a/tests/ui/if_then_some_else_none.rs +++ b/tests/ui/if_then_some_else_none.rs @@ -4,7 +4,8 @@ fn main() { // Should issue an error. let _ = if foo() { - //~^ ERROR: this could be simplified with `bool::then` + //~^ if_then_some_else_none + println!("true!"); Some("foo") } else { @@ -13,7 +14,8 @@ fn main() { // Should issue an error when macros are used. let _ = if matches!(true, true) { - //~^ ERROR: this could be simplified with `bool::then` + //~^ if_then_some_else_none + println!("true!"); Some(matches!(true, false)) } else { @@ -23,12 +25,14 @@ fn main() { // Should issue an error. Binary expression `o < 32` should be parenthesized. let x = Some(5); let _ = x.and_then(|o| if o < 32 { Some(o) } else { None }); - //~^ ERROR: this could be simplified with `bool::then_some` + //~^ if_then_some_else_none + // Should issue an error. Unary expression `!x` should be parenthesized. let x = true; let _ = if !x { Some(0) } else { None }; - //~^ ERROR: this could be simplified with `bool::then_some` + //~^ if_then_some_else_none + // Should not issue an error since the `else` block has a statement besides `None`. let _ = if foo() { @@ -84,7 +88,8 @@ fn _msrv_1_49() { #[clippy::msrv = "1.50"] fn _msrv_1_50() { let _ = if foo() { - //~^ ERROR: this could be simplified with `bool::then` + //~^ if_then_some_else_none + println!("true!"); Some(150) } else { @@ -133,6 +138,7 @@ fn issue11394(b: bool, v: Result<(), ()>) -> Result<(), ()> { fn issue13407(s: &str) -> Option { if s == "1" { Some(true) } else { None } + //~^ if_then_some_else_none } const fn issue12103(x: u32) -> Option { diff --git a/tests/ui/if_then_some_else_none.stderr b/tests/ui/if_then_some_else_none.stderr index e7bc66b3ee88..a996dec236d6 100644 --- a/tests/ui/if_then_some_else_none.stderr +++ b/tests/ui/if_then_some_else_none.stderr @@ -4,9 +4,9 @@ error: this could be simplified with `bool::then` LL | let _ = if foo() { | _____________^ LL | | +LL | | LL | | println!("true!"); -LL | | Some("foo") -LL | | } else { +... | LL | | None LL | | }; | |_____^ help: try: `foo().then(|| { println!("true!"); "foo" })` @@ -15,45 +15,45 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::if_then_some_else_none)]` error: this could be simplified with `bool::then` - --> tests/ui/if_then_some_else_none.rs:15:13 + --> tests/ui/if_then_some_else_none.rs:16:13 | LL | let _ = if matches!(true, true) { | _____________^ LL | | +LL | | LL | | println!("true!"); -LL | | Some(matches!(true, false)) -LL | | } else { +... | LL | | None LL | | }; | |_____^ help: try: `matches!(true, true).then(|| { println!("true!"); matches!(true, false) })` error: this could be simplified with `bool::then_some` - --> tests/ui/if_then_some_else_none.rs:25:28 + --> tests/ui/if_then_some_else_none.rs:27:28 | LL | let _ = x.and_then(|o| if o < 32 { Some(o) } else { None }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(o < 32).then_some(o)` error: this could be simplified with `bool::then_some` - --> tests/ui/if_then_some_else_none.rs:30:13 + --> tests/ui/if_then_some_else_none.rs:33:13 | LL | let _ = if !x { Some(0) } else { None }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(!x).then_some(0)` error: this could be simplified with `bool::then` - --> tests/ui/if_then_some_else_none.rs:86:13 + --> tests/ui/if_then_some_else_none.rs:90:13 | LL | let _ = if foo() { | _____________^ LL | | +LL | | LL | | println!("true!"); -LL | | Some(150) -LL | | } else { +... | LL | | None LL | | }; | |_____^ help: try: `foo().then(|| { println!("true!"); 150 })` error: this could be simplified with `bool::then` - --> tests/ui/if_then_some_else_none.rs:135:5 + --> tests/ui/if_then_some_else_none.rs:140:5 | LL | if s == "1" { Some(true) } else { None } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(s == "1").then(|| true)` diff --git a/tests/ui/ifs_same_cond.rs b/tests/ui/ifs_same_cond.rs index ad77346b75f2..202b164d03ba 100644 --- a/tests/ui/ifs_same_cond.rs +++ b/tests/ui/ifs_same_cond.rs @@ -12,18 +12,21 @@ fn ifs_same_cond() { if b { } else if b { - //~^ ERROR: this `if` has the same condition as a previous `if` + //~^ ifs_same_cond + } if a == 1 { } else if a == 1 { - //~^ ERROR: this `if` has the same condition as a previous `if` + //~^ ifs_same_cond + } if 2 * a == 1 { } else if 2 * a == 2 { } else if 2 * a == 1 { - //~^ ERROR: this `if` has the same condition as a previous `if` + //~^ ifs_same_cond + } else if a == 1 { } @@ -56,7 +59,8 @@ fn issue10272() { let a = String::from("ha"); if a.contains("ah") { } else if a.contains("ah") { - //~^ ERROR: this `if` has the same condition as a previous `if` + //~^ ifs_same_cond + // Trigger this lint } else if a.contains("ha") { } else if a == "wow" { diff --git a/tests/ui/ifs_same_cond.stderr b/tests/ui/ifs_same_cond.stderr index 81fbb921e846..a45e01d26227 100644 --- a/tests/ui/ifs_same_cond.stderr +++ b/tests/ui/ifs_same_cond.stderr @@ -13,37 +13,37 @@ LL | if b { = help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]` error: this `if` has the same condition as a previous `if` - --> tests/ui/ifs_same_cond.rs:19:15 + --> tests/ui/ifs_same_cond.rs:20:15 | LL | } else if a == 1 { | ^^^^^^ | note: same as this - --> tests/ui/ifs_same_cond.rs:18:8 + --> tests/ui/ifs_same_cond.rs:19:8 | LL | if a == 1 { | ^^^^^^ error: this `if` has the same condition as a previous `if` - --> tests/ui/ifs_same_cond.rs:25:15 + --> tests/ui/ifs_same_cond.rs:27:15 | LL | } else if 2 * a == 1 { | ^^^^^^^^^^ | note: same as this - --> tests/ui/ifs_same_cond.rs:23:8 + --> tests/ui/ifs_same_cond.rs:25:8 | LL | if 2 * a == 1 { | ^^^^^^^^^^ error: this `if` has the same condition as a previous `if` - --> tests/ui/ifs_same_cond.rs:58:15 + --> tests/ui/ifs_same_cond.rs:61:15 | LL | } else if a.contains("ah") { | ^^^^^^^^^^^^^^^^ | note: same as this - --> tests/ui/ifs_same_cond.rs:57:8 + --> tests/ui/ifs_same_cond.rs:60:8 | LL | if a.contains("ah") { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl.rs b/tests/ui/impl.rs index 7f452cb46e06..423c8d501741 100644 --- a/tests/ui/impl.rs +++ b/tests/ui/impl.rs @@ -8,7 +8,8 @@ impl MyStruct { } impl MyStruct { - //~^ ERROR: multiple implementations of this structure +//~^ multiple_inherent_impl + fn second() {} } @@ -23,7 +24,8 @@ mod submod { } impl super::MyStruct { - //~^ ERROR: multiple implementations of this structure + //~^ multiple_inherent_impl + fn third() {} } } @@ -44,7 +46,8 @@ impl WithArgs { fn f2() {} } impl WithArgs { - //~^ ERROR: multiple implementations of this structure +//~^ multiple_inherent_impl + fn f3() {} } @@ -66,6 +69,7 @@ impl OneAllowedImpl {} #[allow(clippy::multiple_inherent_impl)] impl OneAllowedImpl {} impl OneAllowedImpl {} // Lint, only one of the three blocks is allowed. -//~^ ERROR: multiple implementations of this structure +//~^ multiple_inherent_impl + fn main() {} diff --git a/tests/ui/impl.stderr b/tests/ui/impl.stderr index bb906957a0d3..355927b78253 100644 --- a/tests/ui/impl.stderr +++ b/tests/ui/impl.stderr @@ -3,6 +3,7 @@ error: multiple implementations of this structure | LL | / impl MyStruct { LL | | +LL | | LL | | fn second() {} LL | | } | |_^ @@ -18,10 +19,11 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::multiple_inherent_impl)]` error: multiple implementations of this structure - --> tests/ui/impl.rs:25:5 + --> tests/ui/impl.rs:26:5 | LL | / impl super::MyStruct { LL | | +LL | | LL | | fn third() {} LL | | } | |_____^ @@ -35,16 +37,17 @@ LL | | } | |_^ error: multiple implementations of this structure - --> tests/ui/impl.rs:46:1 + --> tests/ui/impl.rs:48:1 | LL | / impl WithArgs { LL | | +LL | | LL | | fn f3() {} LL | | } | |_^ | note: first implementation here - --> tests/ui/impl.rs:43:1 + --> tests/ui/impl.rs:45:1 | LL | / impl WithArgs { LL | | fn f2() {} @@ -52,13 +55,13 @@ LL | | } | |_^ error: multiple implementations of this structure - --> tests/ui/impl.rs:68:1 + --> tests/ui/impl.rs:71:1 | LL | impl OneAllowedImpl {} // Lint, only one of the three blocks is allowed. | ^^^^^^^^^^^^^^^^^^^^^^ | note: first implementation here - --> tests/ui/impl.rs:65:1 + --> tests/ui/impl.rs:68:1 | LL | impl OneAllowedImpl {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl_trait_in_params.rs b/tests/ui/impl_trait_in_params.rs index a6251a370d1d..6d502a685bf7 100644 --- a/tests/ui/impl_trait_in_params.rs +++ b/tests/ui/impl_trait_in_params.rs @@ -7,9 +7,11 @@ pub trait AnotherTrait {} // Should warn pub fn a(_: impl Trait) {} -//~^ ERROR: `impl Trait` used as a function parameter +//~^ impl_trait_in_params + pub fn c(_: C, _: impl Trait) {} -//~^ ERROR: `impl Trait` used as a function parameter +//~^ impl_trait_in_params + // Shouldn't warn @@ -33,10 +35,12 @@ trait Private { struct S; impl S { - pub fn h(_: impl Trait) {} //~ ERROR: `impl Trait` used as a function parameter +pub fn h(_: impl Trait) {} +//~^ impl_trait_in_params fn i(_: impl Trait) {} pub fn j(_: J) {} - pub fn k>(_: K, _: impl AnotherTrait) {} //~ ERROR: `impl Trait` used as a function parameter +pub fn k>(_: K, _: impl AnotherTrait) {} +//~^ impl_trait_in_params } // Trying with traits diff --git a/tests/ui/impl_trait_in_params.stderr b/tests/ui/impl_trait_in_params.stderr index 0ec0a34ea8db..ad735d034317 100644 --- a/tests/ui/impl_trait_in_params.stderr +++ b/tests/ui/impl_trait_in_params.stderr @@ -12,7 +12,7 @@ LL | pub fn a<{ /* Generic name */ }: Trait>(_: impl Trait) {} | +++++++++++++++++++++++++++++++ error: `impl Trait` used as a function parameter - --> tests/ui/impl_trait_in_params.rs:11:29 + --> tests/ui/impl_trait_in_params.rs:12:29 | LL | pub fn c(_: C, _: impl Trait) {} | ^^^^^^^^^^ @@ -23,26 +23,26 @@ LL | pub fn c(_: C, _: impl Trait) {} | +++++++++++++++++++++++++++++++ error: `impl Trait` used as a function parameter - --> tests/ui/impl_trait_in_params.rs:36:17 + --> tests/ui/impl_trait_in_params.rs:38:13 | -LL | pub fn h(_: impl Trait) {} - | ^^^^^^^^^^ +LL | pub fn h(_: impl Trait) {} + | ^^^^^^^^^^ | help: add a type parameter | -LL | pub fn h<{ /* Generic name */ }: Trait>(_: impl Trait) {} - | +++++++++++++++++++++++++++++++ +LL | pub fn h<{ /* Generic name */ }: Trait>(_: impl Trait) {} + | +++++++++++++++++++++++++++++++ error: `impl Trait` used as a function parameter - --> tests/ui/impl_trait_in_params.rs:39:45 + --> tests/ui/impl_trait_in_params.rs:42:41 | -LL | pub fn k>(_: K, _: impl AnotherTrait) {} - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | pub fn k>(_: K, _: impl AnotherTrait) {} + | ^^^^^^^^^^^^^^^^^^^^^^ | help: add a type parameter | -LL | pub fn k, { /* Generic name */ }: AnotherTrait>(_: K, _: impl AnotherTrait) {} - | +++++++++++++++++++++++++++++++++++++++++++ +LL | pub fn k, { /* Generic name */ }: AnotherTrait>(_: K, _: impl AnotherTrait) {} + | +++++++++++++++++++++++++++++++++++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/implicit_clone.fixed b/tests/ui/implicit_clone.fixed index 98556b4dd303..d60d1cb0ec04 100644 --- a/tests/ui/implicit_clone.fixed +++ b/tests/ui/implicit_clone.fixed @@ -63,12 +63,15 @@ fn main() { let vec = vec![5]; let _ = return_owned_from_slice(&vec); let _ = vec.clone(); + //~^ implicit_clone let _ = vec.clone(); + //~^ implicit_clone let vec_ref = &vec; let _ = return_owned_from_slice(vec_ref); let _ = vec_ref.to_owned(); let _ = vec_ref.clone(); + //~^ implicit_clone // we expect no lint for this let _ = weird::to_vec(&vec); @@ -81,10 +84,12 @@ fn main() { let str = "hello world".to_string(); let _ = str.clone(); + //~^ implicit_clone // testing w/ an arbitrary type let kitten = Kitten {}; let _ = kitten.clone(); + //~^ implicit_clone let _ = own_same_from_ref(&kitten); // this shouldn't lint let _ = kitten.to_vec(); @@ -95,11 +100,15 @@ fn main() { let pathbuf = PathBuf::new(); let _ = pathbuf.clone(); + //~^ implicit_clone let _ = pathbuf.clone(); + //~^ implicit_clone let os_string = OsString::from("foo"); let _ = os_string.clone(); + //~^ implicit_clone let _ = os_string.clone(); + //~^ implicit_clone // we expect no lints for this let os_str = OsStr::new("foo"); @@ -111,9 +120,11 @@ fn main() { let pathbuf_ref = &pathbuf_ref; let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&PathBuf` let _ = (*pathbuf_ref).clone(); + //~^ implicit_clone let pathbuf_ref = &pathbuf_ref; let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&&PathBuf` let _ = (**pathbuf_ref).clone(); + //~^ implicit_clone struct NoClone; impl ToOwned for NoClone { diff --git a/tests/ui/implicit_clone.rs b/tests/ui/implicit_clone.rs index a064bd23a338..b96828f28c82 100644 --- a/tests/ui/implicit_clone.rs +++ b/tests/ui/implicit_clone.rs @@ -63,12 +63,15 @@ fn main() { let vec = vec![5]; let _ = return_owned_from_slice(&vec); let _ = vec.to_owned(); + //~^ implicit_clone let _ = vec.to_vec(); + //~^ implicit_clone let vec_ref = &vec; let _ = return_owned_from_slice(vec_ref); let _ = vec_ref.to_owned(); let _ = vec_ref.to_vec(); + //~^ implicit_clone // we expect no lint for this let _ = weird::to_vec(&vec); @@ -81,10 +84,12 @@ fn main() { let str = "hello world".to_string(); let _ = str.to_owned(); + //~^ implicit_clone // testing w/ an arbitrary type let kitten = Kitten {}; let _ = kitten.to_owned(); + //~^ implicit_clone let _ = own_same_from_ref(&kitten); // this shouldn't lint let _ = kitten.to_vec(); @@ -95,11 +100,15 @@ fn main() { let pathbuf = PathBuf::new(); let _ = pathbuf.to_owned(); + //~^ implicit_clone let _ = pathbuf.to_path_buf(); + //~^ implicit_clone let os_string = OsString::from("foo"); let _ = os_string.to_owned(); + //~^ implicit_clone let _ = os_string.to_os_string(); + //~^ implicit_clone // we expect no lints for this let os_str = OsStr::new("foo"); @@ -111,9 +120,11 @@ fn main() { let pathbuf_ref = &pathbuf_ref; let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&PathBuf` let _ = pathbuf_ref.to_path_buf(); + //~^ implicit_clone let pathbuf_ref = &pathbuf_ref; let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&&PathBuf` let _ = pathbuf_ref.to_path_buf(); + //~^ implicit_clone struct NoClone; impl ToOwned for NoClone { diff --git a/tests/ui/implicit_clone.stderr b/tests/ui/implicit_clone.stderr index 31c212eba2c8..1eb6ff1fe429 100644 --- a/tests/ui/implicit_clone.stderr +++ b/tests/ui/implicit_clone.stderr @@ -8,61 +8,61 @@ LL | let _ = vec.to_owned(); = help: to override `-D warnings` add `#[allow(clippy::implicit_clone)]` error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type - --> tests/ui/implicit_clone.rs:66:13 + --> tests/ui/implicit_clone.rs:67:13 | LL | let _ = vec.to_vec(); | ^^^^^^^^^^^^ help: consider using: `vec.clone()` error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type - --> tests/ui/implicit_clone.rs:71:13 + --> tests/ui/implicit_clone.rs:73:13 | LL | let _ = vec_ref.to_vec(); | ^^^^^^^^^^^^^^^^ help: consider using: `vec_ref.clone()` error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type - --> tests/ui/implicit_clone.rs:83:13 + --> tests/ui/implicit_clone.rs:86:13 | LL | let _ = str.to_owned(); | ^^^^^^^^^^^^^^ help: consider using: `str.clone()` error: implicitly cloning a `Kitten` by calling `to_owned` on its dereferenced type - --> tests/ui/implicit_clone.rs:87:13 + --> tests/ui/implicit_clone.rs:91:13 | LL | let _ = kitten.to_owned(); | ^^^^^^^^^^^^^^^^^ help: consider using: `kitten.clone()` error: implicitly cloning a `PathBuf` by calling `to_owned` on its dereferenced type - --> tests/ui/implicit_clone.rs:97:13 + --> tests/ui/implicit_clone.rs:102:13 | LL | let _ = pathbuf.to_owned(); | ^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()` error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type - --> tests/ui/implicit_clone.rs:98:13 + --> tests/ui/implicit_clone.rs:104:13 | LL | let _ = pathbuf.to_path_buf(); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()` error: implicitly cloning a `OsString` by calling `to_owned` on its dereferenced type - --> tests/ui/implicit_clone.rs:101:13 + --> tests/ui/implicit_clone.rs:108:13 | LL | let _ = os_string.to_owned(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()` error: implicitly cloning a `OsString` by calling `to_os_string` on its dereferenced type - --> tests/ui/implicit_clone.rs:102:13 + --> tests/ui/implicit_clone.rs:110:13 | LL | let _ = os_string.to_os_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()` error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type - --> tests/ui/implicit_clone.rs:113:13 + --> tests/ui/implicit_clone.rs:122:13 | LL | let _ = pathbuf_ref.to_path_buf(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(*pathbuf_ref).clone()` error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type - --> tests/ui/implicit_clone.rs:116:13 + --> tests/ui/implicit_clone.rs:126:13 | LL | let _ = pathbuf_ref.to_path_buf(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(**pathbuf_ref).clone()` diff --git a/tests/ui/implicit_hasher.fixed b/tests/ui/implicit_hasher.fixed index 971746ae95d7..fd6c4ffc9122 100644 --- a/tests/ui/implicit_hasher.fixed +++ b/tests/ui/implicit_hasher.fixed @@ -13,6 +13,7 @@ pub trait Foo: Sized { } impl Foo for HashMap { +//~^ implicit_hasher fn make() -> (Self, Self) { // OK, don't suggest to modify these let _: HashMap = HashMap::new(); @@ -22,11 +23,13 @@ impl Foo for HashMap } } impl Foo for (HashMap,) { +//~^ implicit_hasher fn make() -> (Self, Self) { ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Default::default()),)) } } impl Foo for HashMap { +//~^ implicit_hasher fn make() -> (Self, Self) { (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default())) } @@ -44,11 +47,13 @@ impl Foo for HashMap { } impl Foo for HashSet { +//~^ implicit_hasher fn make() -> (Self, Self) { (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default())) } } impl Foo for HashSet { +//~^ implicit_hasher fn make() -> (Self, Self) { (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default())) } @@ -66,14 +71,17 @@ impl Foo for HashSet { } pub fn map(map: &mut HashMap) {} +//~^ implicit_hasher pub fn set(set: &mut HashSet) {} +//~^ implicit_hasher #[inline_macros] pub mod gen_ { use super::*; inline! { impl Foo for HashMap { + //~^ implicit_hasher fn make() -> (Self, Self) { (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default())) } @@ -98,5 +106,6 @@ external! { // #7712 pub async fn election_vote(_data: HashMap) {} +//~^ implicit_hasher fn main() {} diff --git a/tests/ui/implicit_hasher.rs b/tests/ui/implicit_hasher.rs index b34aa1f81374..29a1afd2efc8 100644 --- a/tests/ui/implicit_hasher.rs +++ b/tests/ui/implicit_hasher.rs @@ -13,6 +13,7 @@ pub trait Foo: Sized { } impl Foo for HashMap { +//~^ implicit_hasher fn make() -> (Self, Self) { // OK, don't suggest to modify these let _: HashMap = HashMap::new(); @@ -22,11 +23,13 @@ impl Foo for HashMap { } } impl Foo for (HashMap,) { +//~^ implicit_hasher fn make() -> (Self, Self) { ((HashMap::new(),), (HashMap::with_capacity(10),)) } } impl Foo for HashMap { +//~^ implicit_hasher fn make() -> (Self, Self) { (HashMap::new(), HashMap::with_capacity(10)) } @@ -44,11 +47,13 @@ impl Foo for HashMap { } impl Foo for HashSet { +//~^ implicit_hasher fn make() -> (Self, Self) { (HashSet::new(), HashSet::with_capacity(10)) } } impl Foo for HashSet { +//~^ implicit_hasher fn make() -> (Self, Self) { (HashSet::new(), HashSet::with_capacity(10)) } @@ -66,14 +71,17 @@ impl Foo for HashSet { } pub fn map(map: &mut HashMap) {} +//~^ implicit_hasher pub fn set(set: &mut HashSet) {} +//~^ implicit_hasher #[inline_macros] pub mod gen_ { use super::*; inline! { impl Foo for HashMap { + //~^ implicit_hasher fn make() -> (Self, Self) { (HashMap::new(), HashMap::with_capacity(10)) } @@ -98,5 +106,6 @@ external! { // #7712 pub async fn election_vote(_data: HashMap) {} +//~^ implicit_hasher fn main() {} diff --git a/tests/ui/implicit_hasher.stderr b/tests/ui/implicit_hasher.stderr index 442f4789aacf..a4b2b5066daf 100644 --- a/tests/ui/implicit_hasher.stderr +++ b/tests/ui/implicit_hasher.stderr @@ -12,14 +12,14 @@ LL | #![deny(clippy::implicit_hasher)] help: add a type parameter for `BuildHasher` | LL ~ impl Foo for HashMap { -LL | fn make() -> (Self, Self) { +LL | ... LL | LL ~ (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default())) | error: impl for `HashMap` should be generalized over different hashers - --> tests/ui/implicit_hasher.rs:24:36 + --> tests/ui/implicit_hasher.rs:25:36 | LL | impl Foo for (HashMap,) { | ^^^^^^^^^^^^^ @@ -27,12 +27,13 @@ LL | impl Foo for (HashMap,) { help: add a type parameter for `BuildHasher` | LL ~ impl Foo for (HashMap,) { +LL | LL | fn make() -> (Self, Self) { LL ~ ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Default::default()),)) | error: impl for `HashMap` should be generalized over different hashers - --> tests/ui/implicit_hasher.rs:29:19 + --> tests/ui/implicit_hasher.rs:31:19 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,12 +41,13 @@ LL | impl Foo for HashMap { help: add a type parameter for `BuildHasher` | LL ~ impl Foo for HashMap { +LL | LL | fn make() -> (Self, Self) { LL ~ (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default())) | error: impl for `HashSet` should be generalized over different hashers - --> tests/ui/implicit_hasher.rs:46:32 + --> tests/ui/implicit_hasher.rs:49:32 | LL | impl Foo for HashSet { | ^^^^^^^^^^ @@ -53,12 +55,13 @@ LL | impl Foo for HashSet { help: add a type parameter for `BuildHasher` | LL ~ impl Foo for HashSet { +LL | LL | fn make() -> (Self, Self) { LL ~ (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default())) | error: impl for `HashSet` should be generalized over different hashers - --> tests/ui/implicit_hasher.rs:51:19 + --> tests/ui/implicit_hasher.rs:55:19 | LL | impl Foo for HashSet { | ^^^^^^^^^^^^^^^ @@ -66,12 +69,13 @@ LL | impl Foo for HashSet { help: add a type parameter for `BuildHasher` | LL ~ impl Foo for HashSet { +LL | LL | fn make() -> (Self, Self) { LL ~ (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default())) | error: parameter of type `HashMap` should be generalized over different hashers - --> tests/ui/implicit_hasher.rs:68:22 + --> tests/ui/implicit_hasher.rs:73:22 | LL | pub fn map(map: &mut HashMap) {} | ^^^^^^^^^^^^^^^^^ @@ -82,7 +86,7 @@ LL | pub fn map(map: &mut HashMap) {} | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ error: parameter of type `HashSet` should be generalized over different hashers - --> tests/ui/implicit_hasher.rs:70:22 + --> tests/ui/implicit_hasher.rs:76:22 | LL | pub fn set(set: &mut HashSet) {} | ^^^^^^^^^^^^ @@ -93,7 +97,7 @@ LL | pub fn set(set: &mut HashSet) {} | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ error: impl for `HashMap` should be generalized over different hashers - --> tests/ui/implicit_hasher.rs:76:43 + --> tests/ui/implicit_hasher.rs:83:43 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^ @@ -102,12 +106,13 @@ LL | impl Foo for HashMap { help: add a type parameter for `BuildHasher` | LL ~ impl Foo for HashMap { +LL | LL | fn make() -> (Self, Self) { LL ~ (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default())) | error: parameter of type `HashMap` should be generalized over different hashers - --> tests/ui/implicit_hasher.rs:100:35 + --> tests/ui/implicit_hasher.rs:108:35 | LL | pub async fn election_vote(_data: HashMap) {} | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/implicit_return.fixed b/tests/ui/implicit_return.fixed index 56fe29b4e677..1cb639b60a9a 100644 --- a/tests/ui/implicit_return.fixed +++ b/tests/ui/implicit_return.fixed @@ -13,17 +13,22 @@ fn test_end_of_fn() -> bool { } return true + //~^ implicit_return } fn test_if_block() -> bool { if true { return true } else { return false } + //~^ implicit_return + //~| implicit_return } #[rustfmt::skip] fn test_match(x: bool) -> bool { match x { true => return false, + //~^ implicit_return false => { return true }, + //~^ implicit_return } } @@ -37,6 +42,7 @@ fn test_match_with_unreachable(x: bool) -> bool { fn test_loop() -> bool { loop { return true; + //~^ implicit_return } } @@ -44,6 +50,7 @@ fn test_loop_with_block() -> bool { loop { { return true; + //~^ implicit_return } } } @@ -52,6 +59,7 @@ fn test_loop_with_nests() -> bool { loop { if true { return true; + //~^ implicit_return } else { let _ = true; } @@ -70,7 +78,9 @@ fn test_loop_with_if_let() -> bool { fn test_closure() { #[rustfmt::skip] let _ = || { return true }; + //~^ implicit_return let _ = || return true; + //~^ implicit_return } fn test_panic() -> bool { @@ -79,6 +89,7 @@ fn test_panic() -> bool { fn test_return_macro() -> String { return format!("test {}", "test") + //~^ implicit_return } fn macro_branch_test() -> bool { @@ -88,17 +99,20 @@ fn macro_branch_test() -> bool { }; } return m!(true, false) + //~^ implicit_return } fn loop_test() -> bool { 'outer: loop { if true { return true; + //~^ implicit_return } let _ = loop { if false { return false; + //~^ implicit_return } if true { break true; @@ -117,6 +131,7 @@ fn loop_macro_test() -> bool { m!(true); } } +//~^^^^ implicit_return fn divergent_test() -> bool { fn diverge() -> ! { @@ -128,6 +143,7 @@ fn divergent_test() -> bool { // issue #6940 async fn foo() -> bool { return true + //~^ implicit_return } fn main() {} diff --git a/tests/ui/implicit_return.rs b/tests/ui/implicit_return.rs index f066ce20cfd1..99d75e4987e4 100644 --- a/tests/ui/implicit_return.rs +++ b/tests/ui/implicit_return.rs @@ -13,17 +13,22 @@ fn test_end_of_fn() -> bool { } true + //~^ implicit_return } fn test_if_block() -> bool { if true { true } else { false } + //~^ implicit_return + //~| implicit_return } #[rustfmt::skip] fn test_match(x: bool) -> bool { match x { true => false, + //~^ implicit_return false => { true }, + //~^ implicit_return } } @@ -37,6 +42,7 @@ fn test_match_with_unreachable(x: bool) -> bool { fn test_loop() -> bool { loop { break true; + //~^ implicit_return } } @@ -44,6 +50,7 @@ fn test_loop_with_block() -> bool { loop { { break true; + //~^ implicit_return } } } @@ -52,6 +59,7 @@ fn test_loop_with_nests() -> bool { loop { if true { break true; + //~^ implicit_return } else { let _ = true; } @@ -70,7 +78,9 @@ fn test_loop_with_if_let() -> bool { fn test_closure() { #[rustfmt::skip] let _ = || { true }; + //~^ implicit_return let _ = || true; + //~^ implicit_return } fn test_panic() -> bool { @@ -79,6 +89,7 @@ fn test_panic() -> bool { fn test_return_macro() -> String { format!("test {}", "test") + //~^ implicit_return } fn macro_branch_test() -> bool { @@ -88,17 +99,20 @@ fn macro_branch_test() -> bool { }; } m!(true, false) + //~^ implicit_return } fn loop_test() -> bool { 'outer: loop { if true { break true; + //~^ implicit_return } let _ = loop { if false { break 'outer false; + //~^ implicit_return } if true { break true; @@ -117,6 +131,7 @@ fn loop_macro_test() -> bool { m!(true); } } +//~^^^^ implicit_return fn divergent_test() -> bool { fn diverge() -> ! { @@ -128,6 +143,7 @@ fn divergent_test() -> bool { // issue #6940 async fn foo() -> bool { true + //~^ implicit_return } fn main() {} diff --git a/tests/ui/implicit_return.stderr b/tests/ui/implicit_return.stderr index 3b06f26f5a05..940324c25491 100644 --- a/tests/ui/implicit_return.stderr +++ b/tests/ui/implicit_return.stderr @@ -12,7 +12,7 @@ LL | return true | error: missing `return` statement - --> tests/ui/implicit_return.rs:19:15 + --> tests/ui/implicit_return.rs:20:15 | LL | if true { true } else { false } | ^^^^ @@ -23,7 +23,7 @@ LL | if true { return true } else { false } | ~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:19:29 + --> tests/ui/implicit_return.rs:20:29 | LL | if true { true } else { false } | ^^^^^ @@ -34,7 +34,7 @@ LL | if true { true } else { return false } | ~~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:25:17 + --> tests/ui/implicit_return.rs:28:17 | LL | true => false, | ^^^^^ @@ -45,7 +45,7 @@ LL | true => return false, | ~~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:26:20 + --> tests/ui/implicit_return.rs:30:20 | LL | false => { true }, | ^^^^ @@ -56,7 +56,7 @@ LL | false => { return true }, | ~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:39:9 + --> tests/ui/implicit_return.rs:44:9 | LL | break true; | ^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | return true; | ~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:46:13 + --> tests/ui/implicit_return.rs:52:13 | LL | break true; | ^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | return true; | ~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:54:13 + --> tests/ui/implicit_return.rs:61:13 | LL | break true; | ^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | return true; | ~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:72:18 + --> tests/ui/implicit_return.rs:80:18 | LL | let _ = || { true }; | ^^^^ @@ -100,7 +100,7 @@ LL | let _ = || { return true }; | ~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:73:16 + --> tests/ui/implicit_return.rs:82:16 | LL | let _ = || true; | ^^^^ @@ -111,7 +111,7 @@ LL | let _ = || return true; | ~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:81:5 + --> tests/ui/implicit_return.rs:91:5 | LL | format!("test {}", "test") | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | return format!("test {}", "test") | error: missing `return` statement - --> tests/ui/implicit_return.rs:90:5 + --> tests/ui/implicit_return.rs:101:5 | LL | m!(true, false) | ^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | return m!(true, false) | error: missing `return` statement - --> tests/ui/implicit_return.rs:96:13 + --> tests/ui/implicit_return.rs:108:13 | LL | break true; | ^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | return true; | ~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:101:17 + --> tests/ui/implicit_return.rs:114:17 | LL | break 'outer false; | ^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | return false; | ~~~~~~~~~~~~ error: missing `return` statement - --> tests/ui/implicit_return.rs:116:5 + --> tests/ui/implicit_return.rs:130:5 | LL | / loop { LL | | m!(true); @@ -170,7 +170,7 @@ LL + } | error: missing `return` statement - --> tests/ui/implicit_return.rs:130:5 + --> tests/ui/implicit_return.rs:145:5 | LL | true | ^^^^ diff --git a/tests/ui/implicit_saturating_add.rs b/tests/ui/implicit_saturating_add.rs index 94513f34c262..2396db8daa0c 100644 --- a/tests/ui/implicit_saturating_add.rs +++ b/tests/ui/implicit_saturating_add.rs @@ -19,10 +19,12 @@ fn main() { } if u_8 != u8::MAX { + //~^ implicit_saturating_add u_8 += 1; } if u_8 < u8::MAX { + //~^ implicit_saturating_add u_8 += 1; } @@ -31,86 +33,107 @@ fn main() { } if u_16 != u16::MAX { + //~^ implicit_saturating_add u_16 += 1; } if u_16 < u16::MAX { + //~^ implicit_saturating_add u_16 += 1; } if u16::MAX > u_16 { + //~^ implicit_saturating_add u_16 += 1; } if u_32 != u32::MAX { + //~^ implicit_saturating_add u_32 += 1; } if u_32 < u32::MAX { + //~^ implicit_saturating_add u_32 += 1; } if u32::MAX > u_32 { + //~^ implicit_saturating_add u_32 += 1; } if u_64 != u64::MAX { + //~^ implicit_saturating_add u_64 += 1; } if u_64 < u64::MAX { + //~^ implicit_saturating_add u_64 += 1; } if u64::MAX > u_64 { + //~^ implicit_saturating_add u_64 += 1; } if i_8 != i8::MAX { + //~^ implicit_saturating_add i_8 += 1; } if i_8 < i8::MAX { + //~^ implicit_saturating_add i_8 += 1; } if i8::MAX > i_8 { + //~^ implicit_saturating_add i_8 += 1; } if i_16 != i16::MAX { + //~^ implicit_saturating_add i_16 += 1; } if i_16 < i16::MAX { + //~^ implicit_saturating_add i_16 += 1; } if i16::MAX > i_16 { + //~^ implicit_saturating_add i_16 += 1; } if i_32 != i32::MAX { + //~^ implicit_saturating_add i_32 += 1; } if i_32 < i32::MAX { + //~^ implicit_saturating_add i_32 += 1; } if i32::MAX > i_32 { + //~^ implicit_saturating_add i_32 += 1; } if i_64 != i64::MAX { + //~^ implicit_saturating_add i_64 += 1; } if i_64 < i64::MAX { + //~^ implicit_saturating_add i_64 += 1; } if i64::MAX > i_64 { + //~^ implicit_saturating_add i_64 += 1; } @@ -147,6 +170,7 @@ fn main() { if u_32 < 42 { println!("brace yourself!"); } else if u_32 < u32::MAX { + //~^ implicit_saturating_add u_32 += 1; } } diff --git a/tests/ui/implicit_saturating_add.stderr b/tests/ui/implicit_saturating_add.stderr index 4fb9282bc91d..8ae7dc4b884b 100644 --- a/tests/ui/implicit_saturating_add.stderr +++ b/tests/ui/implicit_saturating_add.stderr @@ -2,6 +2,7 @@ error: manual saturating add detected --> tests/ui/implicit_saturating_add.rs:21:5 | LL | / if u_8 != u8::MAX { +LL | | LL | | u_8 += 1; LL | | } | |_____^ help: use instead: `u_8 = u_8.saturating_add(1);` @@ -10,33 +11,28 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_add)]` error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:25:5 + --> tests/ui/implicit_saturating_add.rs:26:5 | LL | / if u_8 < u8::MAX { +LL | | LL | | u_8 += 1; LL | | } | |_____^ help: use instead: `u_8 = u_8.saturating_add(1);` error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:33:5 + --> tests/ui/implicit_saturating_add.rs:35:5 | LL | / if u_16 != u16::MAX { +LL | | LL | | u_16 += 1; LL | | } | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);` error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:37:5 + --> tests/ui/implicit_saturating_add.rs:40:5 | LL | / if u_16 < u16::MAX { -LL | | u_16 += 1; -LL | | } - | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);` - -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:41:5 - | -LL | / if u16::MAX > u_16 { +LL | | LL | | u_16 += 1; LL | | } | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);` @@ -44,152 +40,180 @@ LL | | } error: manual saturating add detected --> tests/ui/implicit_saturating_add.rs:45:5 | +LL | / if u16::MAX > u_16 { +LL | | +LL | | u_16 += 1; +LL | | } + | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:50:5 + | LL | / if u_32 != u32::MAX { +LL | | LL | | u_32 += 1; LL | | } | |_____^ help: use instead: `u_32 = u_32.saturating_add(1);` error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:49:5 + --> tests/ui/implicit_saturating_add.rs:55:5 | LL | / if u_32 < u32::MAX { +LL | | LL | | u_32 += 1; LL | | } | |_____^ help: use instead: `u_32 = u_32.saturating_add(1);` error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:53:5 + --> tests/ui/implicit_saturating_add.rs:60:5 | LL | / if u32::MAX > u_32 { +LL | | LL | | u_32 += 1; LL | | } | |_____^ help: use instead: `u_32 = u_32.saturating_add(1);` -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:57:5 - | -LL | / if u_64 != u64::MAX { -LL | | u_64 += 1; -LL | | } - | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);` - -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:61:5 - | -LL | / if u_64 < u64::MAX { -LL | | u_64 += 1; -LL | | } - | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);` - error: manual saturating add detected --> tests/ui/implicit_saturating_add.rs:65:5 | -LL | / if u64::MAX > u_64 { +LL | / if u_64 != u64::MAX { +LL | | LL | | u_64 += 1; LL | | } | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);` error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:69:5 + --> tests/ui/implicit_saturating_add.rs:70:5 + | +LL | / if u_64 < u64::MAX { +LL | | +LL | | u_64 += 1; +LL | | } + | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:75:5 + | +LL | / if u64::MAX > u_64 { +LL | | +LL | | u_64 += 1; +LL | | } + | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:80:5 | LL | / if i_8 != i8::MAX { +LL | | LL | | i_8 += 1; LL | | } | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);` -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:73:5 - | -LL | / if i_8 < i8::MAX { -LL | | i_8 += 1; -LL | | } - | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);` - -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:77:5 - | -LL | / if i8::MAX > i_8 { -LL | | i_8 += 1; -LL | | } - | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);` - -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:81:5 - | -LL | / if i_16 != i16::MAX { -LL | | i_16 += 1; -LL | | } - | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);` - error: manual saturating add detected --> tests/ui/implicit_saturating_add.rs:85:5 | +LL | / if i_8 < i8::MAX { +LL | | +LL | | i_8 += 1; +LL | | } + | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:90:5 + | +LL | / if i8::MAX > i_8 { +LL | | +LL | | i_8 += 1; +LL | | } + | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:95:5 + | +LL | / if i_16 != i16::MAX { +LL | | +LL | | i_16 += 1; +LL | | } + | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:100:5 + | LL | / if i_16 < i16::MAX { +LL | | LL | | i_16 += 1; LL | | } | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);` -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:89:5 - | -LL | / if i16::MAX > i_16 { -LL | | i_16 += 1; -LL | | } - | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);` - -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:93:5 - | -LL | / if i_32 != i32::MAX { -LL | | i_32 += 1; -LL | | } - | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);` - -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:97:5 - | -LL | / if i_32 < i32::MAX { -LL | | i_32 += 1; -LL | | } - | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);` - -error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:101:5 - | -LL | / if i32::MAX > i_32 { -LL | | i_32 += 1; -LL | | } - | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);` - error: manual saturating add detected --> tests/ui/implicit_saturating_add.rs:105:5 | +LL | / if i16::MAX > i_16 { +LL | | +LL | | i_16 += 1; +LL | | } + | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:110:5 + | +LL | / if i_32 != i32::MAX { +LL | | +LL | | i_32 += 1; +LL | | } + | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:115:5 + | +LL | / if i_32 < i32::MAX { +LL | | +LL | | i_32 += 1; +LL | | } + | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:120:5 + | +LL | / if i32::MAX > i_32 { +LL | | +LL | | i_32 += 1; +LL | | } + | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);` + +error: manual saturating add detected + --> tests/ui/implicit_saturating_add.rs:125:5 + | LL | / if i_64 != i64::MAX { +LL | | LL | | i_64 += 1; LL | | } | |_____^ help: use instead: `i_64 = i_64.saturating_add(1);` error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:109:5 + --> tests/ui/implicit_saturating_add.rs:130:5 | LL | / if i_64 < i64::MAX { +LL | | LL | | i_64 += 1; LL | | } | |_____^ help: use instead: `i_64 = i_64.saturating_add(1);` error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:113:5 + --> tests/ui/implicit_saturating_add.rs:135:5 | LL | / if i64::MAX > i_64 { +LL | | LL | | i_64 += 1; LL | | } | |_____^ help: use instead: `i_64 = i_64.saturating_add(1);` error: manual saturating add detected - --> tests/ui/implicit_saturating_add.rs:149:12 + --> tests/ui/implicit_saturating_add.rs:172:12 | LL | } else if u_32 < u32::MAX { | ____________^ +LL | | LL | | u_32 += 1; LL | | } | |_____^ help: use instead: `{u_32 = u_32.saturating_add(1); }` diff --git a/tests/ui/implicit_saturating_sub.rs b/tests/ui/implicit_saturating_sub.rs index e371e37fb2f6..5b7221b7060f 100644 --- a/tests/ui/implicit_saturating_sub.rs +++ b/tests/ui/implicit_saturating_sub.rs @@ -25,6 +25,7 @@ fn main() { // Lint if u_8 > 0 { + //~^ implicit_saturating_sub u_8 = u_8 - 1; } @@ -32,6 +33,7 @@ fn main() { 10 => { // Lint if u_8 > 0 { + //~^ implicit_saturating_sub u_8 -= 1; } }, @@ -46,6 +48,7 @@ fn main() { // Lint if u_16 > 0 { + //~^ implicit_saturating_sub u_16 -= 1; } @@ -56,6 +59,7 @@ fn main() { // Lint if u_32 != 0 { + //~^ implicit_saturating_sub u_32 -= 1; } @@ -77,16 +81,19 @@ fn main() { // Lint if u_64 > 0 { + //~^ implicit_saturating_sub u_64 -= 1; } // Lint if 0 < u_64 { + //~^ implicit_saturating_sub u_64 -= 1; } // Lint if 0 != u_64 { + //~^ implicit_saturating_sub u_64 -= 1; } @@ -108,6 +115,7 @@ fn main() { // Lint if u_usize > 0 { + //~^ implicit_saturating_sub u_usize -= 1; } @@ -120,21 +128,25 @@ fn main() { // Lint if i_8 > i8::MIN { + //~^ implicit_saturating_sub i_8 -= 1; } // Lint if i_8 > i8::MIN { + //~^ implicit_saturating_sub i_8 -= 1; } // Lint if i_8 != i8::MIN { + //~^ implicit_saturating_sub i_8 -= 1; } // Lint if i_8 != i8::MIN { + //~^ implicit_saturating_sub i_8 -= 1; } @@ -145,21 +157,25 @@ fn main() { // Lint if i_16 > i16::MIN { + //~^ implicit_saturating_sub i_16 -= 1; } // Lint if i_16 > i16::MIN { + //~^ implicit_saturating_sub i_16 -= 1; } // Lint if i_16 != i16::MIN { + //~^ implicit_saturating_sub i_16 -= 1; } // Lint if i_16 != i16::MIN { + //~^ implicit_saturating_sub i_16 -= 1; } @@ -170,21 +186,25 @@ fn main() { // Lint if i_32 > i32::MIN { + //~^ implicit_saturating_sub i_32 -= 1; } // Lint if i_32 > i32::MIN { + //~^ implicit_saturating_sub i_32 -= 1; } // Lint if i_32 != i32::MIN { + //~^ implicit_saturating_sub i_32 -= 1; } // Lint if i_32 != i32::MIN { + //~^ implicit_saturating_sub i_32 -= 1; } @@ -195,16 +215,19 @@ fn main() { // Lint if i64::MIN < i_64 { + //~^ implicit_saturating_sub i_64 -= 1; } // Lint if i64::MIN != i_64 { + //~^ implicit_saturating_sub i_64 -= 1; } // Lint if i64::MIN < i_64 { + //~^ implicit_saturating_sub i_64 -= 1; } @@ -273,6 +296,7 @@ fn regression_13524(a: usize, b: usize, c: bool) -> usize { if c { 123 } else if a >= b { + //~^ implicit_saturating_sub 0 } else { b - a diff --git a/tests/ui/implicit_saturating_sub.stderr b/tests/ui/implicit_saturating_sub.stderr index 613198512280..f9c94d3ad841 100644 --- a/tests/ui/implicit_saturating_sub.stderr +++ b/tests/ui/implicit_saturating_sub.stderr @@ -2,6 +2,7 @@ error: implicitly performing saturating subtraction --> tests/ui/implicit_saturating_sub.rs:27:5 | LL | / if u_8 > 0 { +LL | | LL | | u_8 = u_8 - 1; LL | | } | |_____^ help: try: `u_8 = u_8.saturating_sub(1);` @@ -10,41 +11,37 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_sub)]` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:34:13 + --> tests/ui/implicit_saturating_sub.rs:35:13 | LL | / if u_8 > 0 { +LL | | LL | | u_8 -= 1; LL | | } | |_____________^ help: try: `u_8 = u_8.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:48:5 + --> tests/ui/implicit_saturating_sub.rs:50:5 | LL | / if u_16 > 0 { +LL | | LL | | u_16 -= 1; LL | | } | |_____^ help: try: `u_16 = u_16.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:58:5 + --> tests/ui/implicit_saturating_sub.rs:61:5 | LL | / if u_32 != 0 { +LL | | LL | | u_32 -= 1; LL | | } | |_____^ help: try: `u_32 = u_32.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:79:5 + --> tests/ui/implicit_saturating_sub.rs:83:5 | LL | / if u_64 > 0 { -LL | | u_64 -= 1; -LL | | } - | |_____^ help: try: `u_64 = u_64.saturating_sub(1);` - -error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:84:5 - | -LL | / if 0 < u_64 { +LL | | LL | | u_64 -= 1; LL | | } | |_____^ help: try: `u_64 = u_64.saturating_sub(1);` @@ -52,144 +49,171 @@ LL | | } error: implicitly performing saturating subtraction --> tests/ui/implicit_saturating_sub.rs:89:5 | -LL | / if 0 != u_64 { +LL | / if 0 < u_64 { +LL | | LL | | u_64 -= 1; LL | | } | |_____^ help: try: `u_64 = u_64.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:110:5 + --> tests/ui/implicit_saturating_sub.rs:95:5 + | +LL | / if 0 != u_64 { +LL | | +LL | | u_64 -= 1; +LL | | } + | |_____^ help: try: `u_64 = u_64.saturating_sub(1);` + +error: implicitly performing saturating subtraction + --> tests/ui/implicit_saturating_sub.rs:117:5 | LL | / if u_usize > 0 { +LL | | LL | | u_usize -= 1; LL | | } | |_____^ help: try: `u_usize = u_usize.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:122:5 + --> tests/ui/implicit_saturating_sub.rs:130:5 | LL | / if i_8 > i8::MIN { +LL | | LL | | i_8 -= 1; LL | | } | |_____^ help: try: `i_8 = i_8.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:127:5 + --> tests/ui/implicit_saturating_sub.rs:136:5 | LL | / if i_8 > i8::MIN { +LL | | LL | | i_8 -= 1; LL | | } | |_____^ help: try: `i_8 = i_8.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:132:5 + --> tests/ui/implicit_saturating_sub.rs:142:5 | LL | / if i_8 != i8::MIN { +LL | | LL | | i_8 -= 1; LL | | } | |_____^ help: try: `i_8 = i_8.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:137:5 + --> tests/ui/implicit_saturating_sub.rs:148:5 | LL | / if i_8 != i8::MIN { +LL | | LL | | i_8 -= 1; LL | | } | |_____^ help: try: `i_8 = i_8.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:147:5 + --> tests/ui/implicit_saturating_sub.rs:159:5 | LL | / if i_16 > i16::MIN { +LL | | LL | | i_16 -= 1; LL | | } | |_____^ help: try: `i_16 = i_16.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:152:5 + --> tests/ui/implicit_saturating_sub.rs:165:5 | LL | / if i_16 > i16::MIN { +LL | | LL | | i_16 -= 1; LL | | } | |_____^ help: try: `i_16 = i_16.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:157:5 + --> tests/ui/implicit_saturating_sub.rs:171:5 | LL | / if i_16 != i16::MIN { +LL | | LL | | i_16 -= 1; LL | | } | |_____^ help: try: `i_16 = i_16.saturating_sub(1);` -error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:162:5 - | -LL | / if i_16 != i16::MIN { -LL | | i_16 -= 1; -LL | | } - | |_____^ help: try: `i_16 = i_16.saturating_sub(1);` - -error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:172:5 - | -LL | / if i_32 > i32::MIN { -LL | | i_32 -= 1; -LL | | } - | |_____^ help: try: `i_32 = i_32.saturating_sub(1);` - error: implicitly performing saturating subtraction --> tests/ui/implicit_saturating_sub.rs:177:5 | +LL | / if i_16 != i16::MIN { +LL | | +LL | | i_16 -= 1; +LL | | } + | |_____^ help: try: `i_16 = i_16.saturating_sub(1);` + +error: implicitly performing saturating subtraction + --> tests/ui/implicit_saturating_sub.rs:188:5 + | LL | / if i_32 > i32::MIN { +LL | | LL | | i_32 -= 1; LL | | } | |_____^ help: try: `i_32 = i_32.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:182:5 + --> tests/ui/implicit_saturating_sub.rs:194:5 + | +LL | / if i_32 > i32::MIN { +LL | | +LL | | i_32 -= 1; +LL | | } + | |_____^ help: try: `i_32 = i_32.saturating_sub(1);` + +error: implicitly performing saturating subtraction + --> tests/ui/implicit_saturating_sub.rs:200:5 | LL | / if i_32 != i32::MIN { +LL | | LL | | i_32 -= 1; LL | | } | |_____^ help: try: `i_32 = i_32.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:187:5 + --> tests/ui/implicit_saturating_sub.rs:206:5 | LL | / if i_32 != i32::MIN { +LL | | LL | | i_32 -= 1; LL | | } | |_____^ help: try: `i_32 = i_32.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:197:5 + --> tests/ui/implicit_saturating_sub.rs:217:5 | LL | / if i64::MIN < i_64 { +LL | | LL | | i_64 -= 1; LL | | } | |_____^ help: try: `i_64 = i_64.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:202:5 + --> tests/ui/implicit_saturating_sub.rs:223:5 | LL | / if i64::MIN != i_64 { +LL | | LL | | i_64 -= 1; LL | | } | |_____^ help: try: `i_64 = i_64.saturating_sub(1);` error: implicitly performing saturating subtraction - --> tests/ui/implicit_saturating_sub.rs:207:5 + --> tests/ui/implicit_saturating_sub.rs:229:5 | LL | / if i64::MIN < i_64 { +LL | | LL | | i_64 -= 1; LL | | } | |_____^ help: try: `i_64 = i_64.saturating_sub(1);` error: manual arithmetic check found - --> tests/ui/implicit_saturating_sub.rs:275:12 + --> tests/ui/implicit_saturating_sub.rs:298:12 | LL | } else if a >= b { | ____________^ +LL | | LL | | 0 LL | | } else { LL | | b - a diff --git a/tests/ui/implied_bounds_in_impls.fixed b/tests/ui/implied_bounds_in_impls.fixed index 6fd4cbd80fe4..fe44d7c64b6e 100644 --- a/tests/ui/implied_bounds_in_impls.fixed +++ b/tests/ui/implied_bounds_in_impls.fixed @@ -11,6 +11,7 @@ fn normal_deref(x: T) -> impl Deref { // Deref implied by DerefMut fn deref_derefmut(x: T) -> impl DerefMut { +//~^ implied_bounds_in_impls Box::new(x) } @@ -28,14 +29,19 @@ impl GenericSubtrait<(), i32, V> for () {} impl GenericSubtrait<(), i64, V> for () {} fn generics_implied() -> impl GenericSubtrait +//~^ implied_bounds_in_impls where (): GenericSubtrait, { } fn generics_implied_multi() -> impl GenericSubtrait<(), i32, V> {} +//~^ implied_bounds_in_impls +//~| implied_bounds_in_impls fn generics_implied_multi2() -> impl GenericSubtrait<(), T, V> +//~^ implied_bounds_in_impls +//~| implied_bounds_in_impls where (): GenericSubtrait<(), T, V> + GenericTrait, { @@ -46,21 +52,25 @@ fn generics_different() -> impl GenericTrait + GenericSubtrait<(), i64, ()> // i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait, lint fn generics_same() -> impl GenericSubtrait<(), i32, ()> {} +//~^ implied_bounds_in_impls trait SomeTrait { // Check that it works in trait declarations. fn f() -> impl DerefMut; + //~^ implied_bounds_in_impls } struct SomeStruct; impl SomeStruct { // Check that it works in inherent impl blocks. fn f() -> impl DerefMut { + //~^ implied_bounds_in_impls Box::new(123) } } impl SomeTrait for SomeStruct { // Check that it works in trait impls. fn f() -> impl DerefMut { + //~^ implied_bounds_in_impls Box::new(42) } } @@ -72,7 +82,9 @@ mod issue11422 { // `PartialOrd` has a default generic parameter and does not need to be explicitly specified. // This needs special handling. fn default_generic_param1() -> impl PartialOrd + Debug {} + //~^ implied_bounds_in_impls fn default_generic_param2() -> impl PartialOrd + Debug {} + //~^ implied_bounds_in_impls // Referring to `Self` in the supertrait clause needs special handling. trait Trait1 {} @@ -86,11 +98,13 @@ mod issue11422 { mod issue11435 { // Associated type needs to be included on DoubleEndedIterator in the suggestion fn my_iter() -> impl DoubleEndedIterator { + //~^ implied_bounds_in_impls 0..5 } // Removing the `Clone` bound should include the `+` behind it in its remove suggestion fn f() -> impl Copy { + //~^ implied_bounds_in_impls 1 } @@ -105,6 +119,7 @@ mod issue11435 { // When the other trait has generics, it shouldn't add another pair of `<>` fn f2() -> impl Trait2 {} + //~^ implied_bounds_in_impls trait Trait3 { type X; @@ -120,6 +135,7 @@ mod issue11435 { // Associated type `X` is specified, but `Y` is not, so only that associated type should be moved // over fn f3() -> impl Trait4 {} + //~^ implied_bounds_in_impls } fn issue11880() { @@ -147,14 +163,19 @@ fn issue11880() { // X::T is never constrained in the first place, so it can be omitted // and left unconstrained fn f3() -> impl Y {} + //~^ implied_bounds_in_impls fn f4() -> impl Y {} + //~^ implied_bounds_in_impls fn f5() -> impl Y {} + //~^ implied_bounds_in_impls } fn apit(_: impl DerefMut) {} +//~^ implied_bounds_in_impls trait Rpitit { fn f() -> impl DerefMut; + //~^ implied_bounds_in_impls } trait Atpit { @@ -163,12 +184,14 @@ trait Atpit { } impl Atpit for () { type Assoc = impl DerefMut; + //~^ implied_bounds_in_impls fn define() -> Self::Assoc { &mut [] as &mut [()] } } type Tait = impl DerefMut; +//~^ implied_bounds_in_impls fn define() -> Tait { &mut [] as &mut [()] } diff --git a/tests/ui/implied_bounds_in_impls.rs b/tests/ui/implied_bounds_in_impls.rs index 52076c9f998e..0e100262d2d9 100644 --- a/tests/ui/implied_bounds_in_impls.rs +++ b/tests/ui/implied_bounds_in_impls.rs @@ -11,6 +11,7 @@ fn normal_deref(x: T) -> impl Deref { // Deref implied by DerefMut fn deref_derefmut(x: T) -> impl Deref + DerefMut { +//~^ implied_bounds_in_impls Box::new(x) } @@ -28,14 +29,19 @@ impl GenericSubtrait<(), i32, V> for () {} impl GenericSubtrait<(), i64, V> for () {} fn generics_implied() -> impl GenericTrait + GenericSubtrait +//~^ implied_bounds_in_impls where (): GenericSubtrait, { } fn generics_implied_multi() -> impl GenericTrait + GenericTrait2 + GenericSubtrait<(), i32, V> {} +//~^ implied_bounds_in_impls +//~| implied_bounds_in_impls fn generics_implied_multi2() -> impl GenericTrait + GenericTrait2 + GenericSubtrait<(), T, V> +//~^ implied_bounds_in_impls +//~| implied_bounds_in_impls where (): GenericSubtrait<(), T, V> + GenericTrait, { @@ -46,21 +52,25 @@ fn generics_different() -> impl GenericTrait + GenericSubtrait<(), i64, ()> // i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait, lint fn generics_same() -> impl GenericTrait + GenericSubtrait<(), i32, ()> {} +//~^ implied_bounds_in_impls trait SomeTrait { // Check that it works in trait declarations. fn f() -> impl Deref + DerefMut; + //~^ implied_bounds_in_impls } struct SomeStruct; impl SomeStruct { // Check that it works in inherent impl blocks. fn f() -> impl Deref + DerefMut { + //~^ implied_bounds_in_impls Box::new(123) } } impl SomeTrait for SomeStruct { // Check that it works in trait impls. fn f() -> impl Deref + DerefMut { + //~^ implied_bounds_in_impls Box::new(42) } } @@ -72,7 +82,9 @@ mod issue11422 { // `PartialOrd` has a default generic parameter and does not need to be explicitly specified. // This needs special handling. fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {} + //~^ implied_bounds_in_impls fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {} + //~^ implied_bounds_in_impls // Referring to `Self` in the supertrait clause needs special handling. trait Trait1 {} @@ -86,11 +98,13 @@ mod issue11422 { mod issue11435 { // Associated type needs to be included on DoubleEndedIterator in the suggestion fn my_iter() -> impl Iterator + DoubleEndedIterator { + //~^ implied_bounds_in_impls 0..5 } // Removing the `Clone` bound should include the `+` behind it in its remove suggestion fn f() -> impl Copy + Clone { + //~^ implied_bounds_in_impls 1 } @@ -105,6 +119,7 @@ mod issue11435 { // When the other trait has generics, it shouldn't add another pair of `<>` fn f2() -> impl Trait1 + Trait2 {} + //~^ implied_bounds_in_impls trait Trait3 { type X; @@ -120,6 +135,7 @@ mod issue11435 { // Associated type `X` is specified, but `Y` is not, so only that associated type should be moved // over fn f3() -> impl Trait3 + Trait4 {} + //~^ implied_bounds_in_impls } fn issue11880() { @@ -147,14 +163,19 @@ fn issue11880() { // X::T is never constrained in the first place, so it can be omitted // and left unconstrained fn f3() -> impl X + Y {} + //~^ implied_bounds_in_impls fn f4() -> impl X + Y {} + //~^ implied_bounds_in_impls fn f5() -> impl X + Y {} + //~^ implied_bounds_in_impls } fn apit(_: impl Deref + DerefMut) {} +//~^ implied_bounds_in_impls trait Rpitit { fn f() -> impl Deref + DerefMut; + //~^ implied_bounds_in_impls } trait Atpit { @@ -163,12 +184,14 @@ trait Atpit { } impl Atpit for () { type Assoc = impl Deref + DerefMut; + //~^ implied_bounds_in_impls fn define() -> Self::Assoc { &mut [] as &mut [()] } } type Tait = impl Deref + DerefMut; +//~^ implied_bounds_in_impls fn define() -> Tait { &mut [] as &mut [()] } diff --git a/tests/ui/implied_bounds_in_impls.stderr b/tests/ui/implied_bounds_in_impls.stderr index 805532a56802..e2888d86f315 100644 --- a/tests/ui/implied_bounds_in_impls.stderr +++ b/tests/ui/implied_bounds_in_impls.stderr @@ -13,7 +13,7 @@ LL + fn deref_derefmut(x: T) -> impl DerefMut { | error: this bound is already specified as the supertrait of `GenericSubtrait` - --> tests/ui/implied_bounds_in_impls.rs:30:37 + --> tests/ui/implied_bounds_in_impls.rs:31:37 | LL | fn generics_implied() -> impl GenericTrait + GenericSubtrait | ^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + fn generics_implied() -> impl GenericSubtrait | error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>` - --> tests/ui/implied_bounds_in_impls.rs:36:40 + --> tests/ui/implied_bounds_in_impls.rs:38:40 | LL | fn generics_implied_multi() -> impl GenericTrait + GenericTrait2 + GenericSubtrait<(), i32, V> {} | ^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + fn generics_implied_multi() -> impl GenericTrait2 + GenericSubtrait<( | error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>` - --> tests/ui/implied_bounds_in_impls.rs:36:60 + --> tests/ui/implied_bounds_in_impls.rs:38:60 | LL | fn generics_implied_multi() -> impl GenericTrait + GenericTrait2 + GenericSubtrait<(), i32, V> {} | ^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + fn generics_implied_multi() -> impl GenericTrait + GenericSubtrait< | error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>` - --> tests/ui/implied_bounds_in_impls.rs:38:44 + --> tests/ui/implied_bounds_in_impls.rs:42:44 | LL | fn generics_implied_multi2() -> impl GenericTrait + GenericTrait2 + GenericSubtrait<(), T, V> | ^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + fn generics_implied_multi2() -> impl GenericTrait2 + GenericSubtra | error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>` - --> tests/ui/implied_bounds_in_impls.rs:38:62 + --> tests/ui/implied_bounds_in_impls.rs:42:62 | LL | fn generics_implied_multi2() -> impl GenericTrait + GenericTrait2 + GenericSubtrait<(), T, V> | ^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + fn generics_implied_multi2() -> impl GenericTrait + GenericSubtrai | error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, ()>` - --> tests/ui/implied_bounds_in_impls.rs:48:28 + --> tests/ui/implied_bounds_in_impls.rs:54:28 | LL | fn generics_same() -> impl GenericTrait + GenericSubtrait<(), i32, ()> {} | ^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + fn generics_same() -> impl GenericSubtrait<(), i32, ()> {} | error: this bound is already specified as the supertrait of `DerefMut` - --> tests/ui/implied_bounds_in_impls.rs:52:20 + --> tests/ui/implied_bounds_in_impls.rs:59:20 | LL | fn f() -> impl Deref + DerefMut; | ^^^^^ @@ -97,7 +97,7 @@ LL + fn f() -> impl DerefMut; | error: this bound is already specified as the supertrait of `DerefMut` - --> tests/ui/implied_bounds_in_impls.rs:57:20 + --> tests/ui/implied_bounds_in_impls.rs:65:20 | LL | fn f() -> impl Deref + DerefMut { | ^^^^^ @@ -109,7 +109,7 @@ LL + fn f() -> impl DerefMut { | error: this bound is already specified as the supertrait of `DerefMut` - --> tests/ui/implied_bounds_in_impls.rs:63:20 + --> tests/ui/implied_bounds_in_impls.rs:72:20 | LL | fn f() -> impl Deref + DerefMut { | ^^^^^ @@ -121,7 +121,7 @@ LL + fn f() -> impl DerefMut { | error: this bound is already specified as the supertrait of `PartialOrd` - --> tests/ui/implied_bounds_in_impls.rs:74:41 + --> tests/ui/implied_bounds_in_impls.rs:84:41 | LL | fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {} | ^^^^^^^^^ @@ -133,7 +133,7 @@ LL + fn default_generic_param1() -> impl PartialOrd + Debug {} | error: this bound is already specified as the supertrait of `PartialOrd` - --> tests/ui/implied_bounds_in_impls.rs:75:54 + --> tests/ui/implied_bounds_in_impls.rs:86:54 | LL | fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {} | ^^^^^^^^^ @@ -145,7 +145,7 @@ LL + fn default_generic_param2() -> impl PartialOrd + Debug {} | error: this bound is already specified as the supertrait of `DoubleEndedIterator` - --> tests/ui/implied_bounds_in_impls.rs:88:26 + --> tests/ui/implied_bounds_in_impls.rs:100:26 | LL | fn my_iter() -> impl Iterator + DoubleEndedIterator { | ^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL + fn my_iter() -> impl DoubleEndedIterator { | error: this bound is already specified as the supertrait of `Copy` - --> tests/ui/implied_bounds_in_impls.rs:93:27 + --> tests/ui/implied_bounds_in_impls.rs:106:27 | LL | fn f() -> impl Copy + Clone { | ^^^^^ @@ -169,7 +169,7 @@ LL + fn f() -> impl Copy { | error: this bound is already specified as the supertrait of `Trait2` - --> tests/ui/implied_bounds_in_impls.rs:107:21 + --> tests/ui/implied_bounds_in_impls.rs:121:21 | LL | fn f2() -> impl Trait1 + Trait2 {} | ^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + fn f2() -> impl Trait2 {} | error: this bound is already specified as the supertrait of `Trait4` - --> tests/ui/implied_bounds_in_impls.rs:122:21 + --> tests/ui/implied_bounds_in_impls.rs:137:21 | LL | fn f3() -> impl Trait3 + Trait4 {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL + fn f3() -> impl Trait4 {} | error: this bound is already specified as the supertrait of `Y` - --> tests/ui/implied_bounds_in_impls.rs:149:21 + --> tests/ui/implied_bounds_in_impls.rs:165:21 | LL | fn f3() -> impl X + Y {} | ^ @@ -205,7 +205,7 @@ LL + fn f3() -> impl Y {} | error: this bound is already specified as the supertrait of `Y` - --> tests/ui/implied_bounds_in_impls.rs:150:21 + --> tests/ui/implied_bounds_in_impls.rs:167:21 | LL | fn f4() -> impl X + Y {} | ^ @@ -217,7 +217,7 @@ LL + fn f4() -> impl Y {} | error: this bound is already specified as the supertrait of `Y` - --> tests/ui/implied_bounds_in_impls.rs:151:21 + --> tests/ui/implied_bounds_in_impls.rs:169:21 | LL | fn f5() -> impl X + Y {} | ^^^^^^^^^^^^^ @@ -229,7 +229,7 @@ LL + fn f5() -> impl Y {} | error: this bound is already specified as the supertrait of `DerefMut` - --> tests/ui/implied_bounds_in_impls.rs:154:17 + --> tests/ui/implied_bounds_in_impls.rs:173:17 | LL | fn apit(_: impl Deref + DerefMut) {} | ^^^^^ @@ -241,7 +241,7 @@ LL + fn apit(_: impl DerefMut) {} | error: this bound is already specified as the supertrait of `DerefMut` - --> tests/ui/implied_bounds_in_impls.rs:157:20 + --> tests/ui/implied_bounds_in_impls.rs:177:20 | LL | fn f() -> impl Deref + DerefMut; | ^^^^^ @@ -253,7 +253,7 @@ LL + fn f() -> impl DerefMut; | error: this bound is already specified as the supertrait of `DerefMut` - --> tests/ui/implied_bounds_in_impls.rs:165:23 + --> tests/ui/implied_bounds_in_impls.rs:186:23 | LL | type Assoc = impl Deref + DerefMut; | ^^^^^ @@ -265,7 +265,7 @@ LL + type Assoc = impl DerefMut; | error: this bound is already specified as the supertrait of `DerefMut` - --> tests/ui/implied_bounds_in_impls.rs:171:18 + --> tests/ui/implied_bounds_in_impls.rs:193:18 | LL | type Tait = impl Deref + DerefMut; | ^^^^^ diff --git a/tests/ui/incompatible_msrv.rs b/tests/ui/incompatible_msrv.rs index c23df223d508..523c754437aa 100644 --- a/tests/ui/incompatible_msrv.rs +++ b/tests/ui/incompatible_msrv.rs @@ -11,14 +11,17 @@ use std::time::Duration; fn foo() { let mut map: HashMap<&str, u32> = HashMap::new(); assert_eq!(map.entry("poneyland").key(), &"poneyland"); - //~^ ERROR: is `1.3.0` but this item is stable since `1.10.0` + //~^ incompatible_msrv + if let Entry::Vacant(v) = map.entry("poneyland") { v.into_key(); - //~^ ERROR: is `1.3.0` but this item is stable since `1.12.0` + //~^ incompatible_msrv + } // Should warn for `sleep` but not for `Duration` (which was added in `1.3.0`). sleep(Duration::new(1, 0)); - //~^ ERROR: is `1.3.0` but this item is stable since `1.4.0` + //~^ incompatible_msrv + } #[test] diff --git a/tests/ui/incompatible_msrv.stderr b/tests/ui/incompatible_msrv.stderr index 34f01c3e14a1..f14e9810b203 100644 --- a/tests/ui/incompatible_msrv.stderr +++ b/tests/ui/incompatible_msrv.stderr @@ -8,13 +8,13 @@ LL | assert_eq!(map.entry("poneyland").key(), &"poneyland"); = help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]` error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.12.0` - --> tests/ui/incompatible_msrv.rs:16:11 + --> tests/ui/incompatible_msrv.rs:17:11 | LL | v.into_key(); | ^^^^^^^^^^ error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0` - --> tests/ui/incompatible_msrv.rs:20:5 + --> tests/ui/incompatible_msrv.rs:22:5 | LL | sleep(Duration::new(1, 0)); | ^^^^^ diff --git a/tests/ui/inconsistent_digit_grouping.fixed b/tests/ui/inconsistent_digit_grouping.fixed index 3f1dfbbae97b..23d2d7cc0aa4 100644 --- a/tests/ui/inconsistent_digit_grouping.fixed +++ b/tests/ui/inconsistent_digit_grouping.fixed @@ -23,15 +23,25 @@ fn main() { 1.123_456_7_f32, ); let bad = (123_456, 12_345_678, 1_234_567, 1_234.567_8_f32, 1.234_567_8_f32); + //~^ inconsistent_digit_grouping + //~| inconsistent_digit_grouping + //~| inconsistent_digit_grouping + //~| inconsistent_digit_grouping + //~| inconsistent_digit_grouping // Test padding let _ = 0x0010_0000; + //~^ unreadable_literal let _ = 0x0100_0000; + //~^ unreadable_literal let _ = 0x1000_0000; + //~^ unreadable_literal let _ = 0x0001_0000_0000_u64; + //~^ unreadable_literal // Test suggestion when fraction has no digits let _: f32 = 123_456.; + //~^ inconsistent_digit_grouping // Test UUID formatted literal let _: u128 = 0x12345678_1234_1234_1234_123456789012; diff --git a/tests/ui/inconsistent_digit_grouping.rs b/tests/ui/inconsistent_digit_grouping.rs index ac47ae175948..a172c5450ef8 100644 --- a/tests/ui/inconsistent_digit_grouping.rs +++ b/tests/ui/inconsistent_digit_grouping.rs @@ -23,15 +23,25 @@ fn main() { 1.123_456_7_f32, ); let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32); + //~^ inconsistent_digit_grouping + //~| inconsistent_digit_grouping + //~| inconsistent_digit_grouping + //~| inconsistent_digit_grouping + //~| inconsistent_digit_grouping // Test padding let _ = 0x100000; + //~^ unreadable_literal let _ = 0x1000000; + //~^ unreadable_literal let _ = 0x10000000; + //~^ unreadable_literal let _ = 0x100000000_u64; + //~^ unreadable_literal // Test suggestion when fraction has no digits let _: f32 = 1_23_456.; + //~^ inconsistent_digit_grouping // Test UUID formatted literal let _: u128 = 0x12345678_1234_1234_1234_123456789012; diff --git a/tests/ui/inconsistent_digit_grouping.stderr b/tests/ui/inconsistent_digit_grouping.stderr index 173b824935c8..be54de5e7c16 100644 --- a/tests/ui/inconsistent_digit_grouping.stderr +++ b/tests/ui/inconsistent_digit_grouping.stderr @@ -32,7 +32,7 @@ LL | let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f | ^^^^^^^^^^^^^^ help: consider: `1.234_567_8_f32` error: long literal lacking separators - --> tests/ui/inconsistent_digit_grouping.rs:28:13 + --> tests/ui/inconsistent_digit_grouping.rs:33:13 | LL | let _ = 0x100000; | ^^^^^^^^ help: consider: `0x0010_0000` @@ -44,25 +44,25 @@ LL | #[deny(clippy::unreadable_literal)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: long literal lacking separators - --> tests/ui/inconsistent_digit_grouping.rs:29:13 + --> tests/ui/inconsistent_digit_grouping.rs:35:13 | LL | let _ = 0x1000000; | ^^^^^^^^^ help: consider: `0x0100_0000` error: long literal lacking separators - --> tests/ui/inconsistent_digit_grouping.rs:30:13 + --> tests/ui/inconsistent_digit_grouping.rs:37:13 | LL | let _ = 0x10000000; | ^^^^^^^^^^ help: consider: `0x1000_0000` error: long literal lacking separators - --> tests/ui/inconsistent_digit_grouping.rs:31:13 + --> tests/ui/inconsistent_digit_grouping.rs:39:13 | LL | let _ = 0x100000000_u64; | ^^^^^^^^^^^^^^^ help: consider: `0x0001_0000_0000_u64` error: digits grouped inconsistently by underscores - --> tests/ui/inconsistent_digit_grouping.rs:34:18 + --> tests/ui/inconsistent_digit_grouping.rs:43:18 | LL | let _: f32 = 1_23_456.; | ^^^^^^^^^ help: consider: `123_456.` diff --git a/tests/ui/inconsistent_struct_constructor.fixed b/tests/ui/inconsistent_struct_constructor.fixed index 67bd3e4d2797..1b3f27a45d6a 100644 --- a/tests/ui/inconsistent_struct_constructor.fixed +++ b/tests/ui/inconsistent_struct_constructor.fixed @@ -34,6 +34,7 @@ mod without_base { // Should lint. Foo { x, y, z }; + //~^ inconsistent_struct_constructor // Should NOT lint. // issue #7069. @@ -65,6 +66,7 @@ mod with_base { z, ..Default::default() }; + //~^^^^ inconsistent_struct_constructor // Should NOT lint because the order is consistent with the definition. Foo { diff --git a/tests/ui/inconsistent_struct_constructor.rs b/tests/ui/inconsistent_struct_constructor.rs index d49f236b9b07..ec29bdaf93f0 100644 --- a/tests/ui/inconsistent_struct_constructor.rs +++ b/tests/ui/inconsistent_struct_constructor.rs @@ -34,6 +34,7 @@ mod without_base { // Should lint. Foo { y, x, z }; + //~^ inconsistent_struct_constructor // Should NOT lint. // issue #7069. @@ -65,6 +66,7 @@ mod with_base { x, ..Default::default() }; + //~^^^^ inconsistent_struct_constructor // Should NOT lint because the order is consistent with the definition. Foo { diff --git a/tests/ui/inconsistent_struct_constructor.stderr b/tests/ui/inconsistent_struct_constructor.stderr index c145eb2a239e..2f48a011d26f 100644 --- a/tests/ui/inconsistent_struct_constructor.stderr +++ b/tests/ui/inconsistent_struct_constructor.stderr @@ -8,7 +8,7 @@ LL | Foo { y, x, z }; = help: to override `-D warnings` add `#[allow(clippy::inconsistent_struct_constructor)]` error: struct constructor field order is inconsistent with struct definition field order - --> tests/ui/inconsistent_struct_constructor.rs:64:13 + --> tests/ui/inconsistent_struct_constructor.rs:65:13 | LL | / z, LL | | x, diff --git a/tests/ui/index_refutable_slice/if_let_slice_binding.fixed b/tests/ui/index_refutable_slice/if_let_slice_binding.fixed index ea8e56e18b08..f5f66d6eca61 100644 --- a/tests/ui/index_refutable_slice/if_let_slice_binding.fixed +++ b/tests/ui/index_refutable_slice/if_let_slice_binding.fixed @@ -12,21 +12,24 @@ fn lintable_examples() { // Try with reference let slice: Option<&[u32]> = Some(&[1, 2, 3]); if let Some([slice_0, ..]) = slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{}", slice_0); } // Try with copy let slice: Option<[u32; 3]> = Some([1, 2, 3]); if let Some([slice_0, ..]) = slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{}", slice_0); } // Try with long slice and small indices let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]); if let Some([slice_0, _, slice_2, ..]) = slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{}", slice_2); println!("{}", slice_0); } @@ -34,7 +37,8 @@ fn lintable_examples() { // Multiple bindings let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]); if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{}", slice_0); } @@ -42,8 +46,10 @@ fn lintable_examples() { let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]); let b_wrapped: Option<[u32; 2]> = Some([4, 6]); if let (SomeEnum::Three([_, _, a_2, ..]), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) { - //~^ ERROR: this binding can be a slice pattern to avoid indexing - //~| ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + //~| index_refutable_slice + + println!("{} -> {}", a_2, b_1); } @@ -51,7 +57,8 @@ fn lintable_examples() { // borrowed and `String` doesn't implement copy let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); if let Some([_, ref slice_1, ..]) = slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{:?}", slice_1); } println!("{:?}", slice); @@ -60,7 +67,8 @@ fn lintable_examples() { // a reference let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); if let Some([slice_0, ..]) = &slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{:?}", slice_0); } println!("{:?}", slice); @@ -130,7 +138,8 @@ fn check_slice_in_struct() { // Test 1: Field access if let Some([slice_0, ..]) = wrap.inner { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + if wrap.is_awesome { println!("This is awesome! {}", slice_0); } @@ -138,7 +147,8 @@ fn check_slice_in_struct() { // Test 2: function access if let Some([slice_0, ..]) = wrap.inner { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + if wrap.is_super_awesome() { println!("This is super awesome! {}", slice_0); } diff --git a/tests/ui/index_refutable_slice/if_let_slice_binding.rs b/tests/ui/index_refutable_slice/if_let_slice_binding.rs index 1c1d1c4cbe46..408fd85cfe6a 100644 --- a/tests/ui/index_refutable_slice/if_let_slice_binding.rs +++ b/tests/ui/index_refutable_slice/if_let_slice_binding.rs @@ -12,21 +12,24 @@ fn lintable_examples() { // Try with reference let slice: Option<&[u32]> = Some(&[1, 2, 3]); if let Some(slice) = slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{}", slice[0]); } // Try with copy let slice: Option<[u32; 3]> = Some([1, 2, 3]); if let Some(slice) = slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{}", slice[0]); } // Try with long slice and small indices let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]); if let Some(slice) = slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{}", slice[2]); println!("{}", slice[0]); } @@ -34,7 +37,8 @@ fn lintable_examples() { // Multiple bindings let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]); if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{}", slice[0]); } @@ -42,8 +46,10 @@ fn lintable_examples() { let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]); let b_wrapped: Option<[u32; 2]> = Some([4, 6]); if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) { - //~^ ERROR: this binding can be a slice pattern to avoid indexing - //~| ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + //~| index_refutable_slice + + println!("{} -> {}", a[2], b[1]); } @@ -51,7 +57,8 @@ fn lintable_examples() { // borrowed and `String` doesn't implement copy let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); if let Some(ref slice) = slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{:?}", slice[1]); } println!("{:?}", slice); @@ -60,7 +67,8 @@ fn lintable_examples() { // a reference let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); if let Some(slice) = &slice { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + println!("{:?}", slice[0]); } println!("{:?}", slice); @@ -130,7 +138,8 @@ fn check_slice_in_struct() { // Test 1: Field access if let Some(slice) = wrap.inner { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + if wrap.is_awesome { println!("This is awesome! {}", slice[0]); } @@ -138,7 +147,8 @@ fn check_slice_in_struct() { // Test 2: function access if let Some(slice) = wrap.inner { - //~^ ERROR: this binding can be a slice pattern to avoid indexing + //~^ index_refutable_slice + if wrap.is_super_awesome() { println!("This is super awesome! {}", slice[0]); } diff --git a/tests/ui/index_refutable_slice/if_let_slice_binding.stderr b/tests/ui/index_refutable_slice/if_let_slice_binding.stderr index 14ee2e54cab1..6abbc3d7dfad 100644 --- a/tests/ui/index_refutable_slice/if_let_slice_binding.stderr +++ b/tests/ui/index_refutable_slice/if_let_slice_binding.stderr @@ -13,11 +13,12 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let Some([slice_0, ..]) = slice { LL | +LL | LL ~ println!("{}", slice_0); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:21:17 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:22:17 | LL | if let Some(slice) = slice { | ^^^^^ @@ -26,11 +27,12 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let Some([slice_0, ..]) = slice { LL | +LL | LL ~ println!("{}", slice_0); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:28:17 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:30:17 | LL | if let Some(slice) = slice { | ^^^^^ @@ -39,12 +41,13 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let Some([slice_0, _, slice_2, ..]) = slice { LL | +LL | LL ~ println!("{}", slice_2); LL ~ println!("{}", slice_0); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:36:26 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:39:26 | LL | if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped { | ^^^^^ @@ -53,11 +56,12 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped { LL | +LL | LL ~ println!("{}", slice_0); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:44:29 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:48:29 | LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) { | ^ @@ -66,12 +70,13 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let (SomeEnum::Three([_, _, a_2, ..]), Some(b)) = (a_wrapped, b_wrapped) { LL | +... LL | LL ~ println!("{} -> {}", a_2, b[1]); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:44:38 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:48:38 | LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) { | ^ @@ -80,12 +85,13 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let (SomeEnum::Three(a), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) { LL | +... LL | LL ~ println!("{} -> {}", a[2], b_1); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:53:21 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:59:21 | LL | if let Some(ref slice) = slice { | ^^^^^ @@ -94,11 +100,12 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let Some([_, ref slice_1, ..]) = slice { LL | +LL | LL ~ println!("{:?}", slice_1); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:62:17 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:69:17 | LL | if let Some(slice) = &slice { | ^^^^^ @@ -107,21 +114,8 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let Some([slice_0, ..]) = &slice { LL | -LL ~ println!("{:?}", slice_0); - | - -error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:132:17 - | -LL | if let Some(slice) = wrap.inner { - | ^^^^^ - | -help: replace the binding and indexed access with a slice pattern - | -LL ~ if let Some([slice_0, ..]) = wrap.inner { LL | -LL | if wrap.is_awesome { -LL ~ println!("This is awesome! {}", slice_0); +LL ~ println!("{:?}", slice_0); | error: this binding can be a slice pattern to avoid indexing @@ -134,6 +128,22 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let Some([slice_0, ..]) = wrap.inner { LL | +LL | +LL | if wrap.is_awesome { +LL ~ println!("This is awesome! {}", slice_0); + | + +error: this binding can be a slice pattern to avoid indexing + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:149:17 + | +LL | if let Some(slice) = wrap.inner { + | ^^^^^ + | +help: replace the binding and indexed access with a slice pattern + | +LL ~ if let Some([slice_0, ..]) = wrap.inner { +LL | +LL | LL | if wrap.is_super_awesome() { LL ~ println!("This is super awesome! {}", slice_0); | diff --git a/tests/ui/indexing_slicing_index.rs b/tests/ui/indexing_slicing_index.rs index 2af5fcc82a9b..cfa1c2f7c75f 100644 --- a/tests/ui/indexing_slicing_index.rs +++ b/tests/ui/indexing_slicing_index.rs @@ -49,8 +49,10 @@ fn main() { //~^ ERROR: indexing may panic // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays. x[4]; + //~^ out_of_bounds_indexing // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays. x[1 << 3]; + //~^ out_of_bounds_indexing // Ok, should not produce stderr. x[0]; @@ -66,12 +68,14 @@ fn main() { // This should be linted, since `suppress-restriction-lint-in-const` default is false. const { &ARR[idx4()] }; //~^ ERROR: indexing may panic + //~| ERROR: evaluation of `main let y = &x; // Ok, referencing shouldn't affect this lint. See the issue 6021 y[0]; // Ok, rustc will handle references too. y[4]; + //~^ out_of_bounds_indexing let v = vec![0; 5]; v[0]; @@ -87,6 +91,7 @@ fn main() { const M: usize = 3; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays. x[N]; + //~^ out_of_bounds_indexing // Ok, should not produce stderr. x[M]; v[N]; @@ -96,4 +101,5 @@ fn main() { let slice = &x; let _ = x[4]; + //~^ out_of_bounds_indexing } diff --git a/tests/ui/indexing_slicing_index.stderr b/tests/ui/indexing_slicing_index.stderr index 71677584d25b..50ee9b9edc75 100644 --- a/tests/ui/indexing_slicing_index.stderr +++ b/tests/ui/indexing_slicing_index.stderr @@ -10,13 +10,13 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]` error[E0080]: evaluation of `main::{constant#3}` failed - --> tests/ui/indexing_slicing_index.rs:67:14 + --> tests/ui/indexing_slicing_index.rs:69:14 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 note: erroneous constant encountered - --> tests/ui/indexing_slicing_index.rs:67:5 + --> tests/ui/indexing_slicing_index.rs:69:5 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | x[4]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:53:5 + --> tests/ui/indexing_slicing_index.rs:54:5 | LL | x[1 << 3]; | ^^^^^^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:64:14 + --> tests/ui/indexing_slicing_index.rs:66:14 | LL | const { &ARR[idx()] }; | ^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | const { &ARR[idx()] }; = note: the suggestion might not be applicable in constant blocks error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:67:14 + --> tests/ui/indexing_slicing_index.rs:69:14 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^ @@ -63,13 +63,13 @@ LL | const { &ARR[idx4()] }; = note: the suggestion might not be applicable in constant blocks error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:74:5 + --> tests/ui/indexing_slicing_index.rs:77:5 | LL | y[4]; | ^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:77:5 + --> tests/ui/indexing_slicing_index.rs:81:5 | LL | v[0]; | ^^^^ @@ -77,7 +77,7 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:79:5 + --> tests/ui/indexing_slicing_index.rs:83:5 | LL | v[10]; | ^^^^^ @@ -85,7 +85,7 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:81:5 + --> tests/ui/indexing_slicing_index.rs:85:5 | LL | v[1 << 3]; | ^^^^^^^^^ @@ -93,13 +93,13 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:89:5 + --> tests/ui/indexing_slicing_index.rs:93:5 | LL | x[N]; | ^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:92:5 + --> tests/ui/indexing_slicing_index.rs:97:5 | LL | v[N]; | ^^^^ @@ -107,7 +107,7 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:94:5 + --> tests/ui/indexing_slicing_index.rs:99:5 | LL | v[M]; | ^^^^ @@ -115,7 +115,7 @@ LL | v[M]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:98:13 + --> tests/ui/indexing_slicing_index.rs:103:13 | LL | let _ = x[4]; | ^^^^ diff --git a/tests/ui/indexing_slicing_slice.rs b/tests/ui/indexing_slicing_slice.rs index f37bcc4aa0ca..cad77f56d03a 100644 --- a/tests/ui/indexing_slicing_slice.rs +++ b/tests/ui/indexing_slicing_slice.rs @@ -113,22 +113,21 @@ fn main() { let index_from: usize = 2; let index_to: usize = 3; &x[index..]; - //~^ ERROR: slicing may panic + //~^ indexing_slicing &x[..index]; - //~^ ERROR: slicing may panic + //~^ indexing_slicing &x[index_from..index_to]; - //~^ ERROR: slicing may panic + //~^ indexing_slicing &x[index_from..][..index_to]; - //~^ ERROR: slicing may panic - //~| ERROR: slicing may panic + //~^ indexing_slicing + //~| indexing_slicing &x[5..][..10]; - //~^ ERROR: slicing may panic - //~| ERROR: range is out of bounds - //~| NOTE: `-D clippy::out-of-bounds-indexing` implied by `-D warnings` + //~^ indexing_slicing + //~| out_of_bounds_indexing &x[0..][..3]; - //~^ ERROR: slicing may panic + //~^ indexing_slicing &x[1..][..5]; - //~^ ERROR: slicing may panic + //~^ indexing_slicing &x[0..].get(..3); // Ok, should not produce stderr. &x[0..3]; // Ok, should not produce stderr. @@ -136,22 +135,22 @@ fn main() { let y = &x; &y[1..2]; &y[0..=4]; - //~^ ERROR: range is out of bounds + //~^ out_of_bounds_indexing &y[..=4]; - //~^ ERROR: range is out of bounds + //~^ out_of_bounds_indexing &y[..]; // Ok, should not produce stderr. let v = vec![0; 5]; &v[10..100]; - //~^ ERROR: slicing may panic + //~^ indexing_slicing &x[10..][..100]; - //~^ ERROR: slicing may panic - //~| ERROR: range is out of bounds + //~^ indexing_slicing + //~| out_of_bounds_indexing &v[10..]; - //~^ ERROR: slicing may panic + //~^ indexing_slicing &v[..100]; - //~^ ERROR: slicing may panic + //~^ indexing_slicing &v[..]; // Ok, should not produce stderr. @@ -169,12 +168,15 @@ fn main() { // Lint on this, because `get` does exist with same signature map_with_get[true]; + //~^ indexing_slicing let s = S::(1); s[0]; + //~^ indexing_slicing let y = Y::(1); y[0]; + //~^ indexing_slicing let z = Z::(1); z[0]; diff --git a/tests/ui/indexing_slicing_slice.stderr b/tests/ui/indexing_slicing_slice.stderr index 1e72506746ec..e3ef89823e3d 100644 --- a/tests/ui/indexing_slicing_slice.stderr +++ b/tests/ui/indexing_slicing_slice.stderr @@ -58,7 +58,7 @@ LL | &x[5..][..10]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:128:6 + --> tests/ui/indexing_slicing_slice.rs:127:6 | LL | &x[0..][..3]; | ^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | &x[0..][..3]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:130:6 + --> tests/ui/indexing_slicing_slice.rs:129:6 | LL | &x[1..][..5]; | ^^^^^^^^^^^ @@ -74,19 +74,19 @@ LL | &x[1..][..5]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: range is out of bounds - --> tests/ui/indexing_slicing_slice.rs:138:12 + --> tests/ui/indexing_slicing_slice.rs:137:12 | LL | &y[0..=4]; | ^ error: range is out of bounds - --> tests/ui/indexing_slicing_slice.rs:140:11 + --> tests/ui/indexing_slicing_slice.rs:139:11 | LL | &y[..=4]; | ^ error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:146:6 + --> tests/ui/indexing_slicing_slice.rs:145:6 | LL | &v[10..100]; | ^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | &v[10..100]; = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:148:6 + --> tests/ui/indexing_slicing_slice.rs:147:6 | LL | &x[10..][..100]; | ^^^^^^^^^^^^^^ @@ -102,13 +102,13 @@ LL | &x[10..][..100]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: range is out of bounds - --> tests/ui/indexing_slicing_slice.rs:148:8 + --> tests/ui/indexing_slicing_slice.rs:147:8 | LL | &x[10..][..100]; | ^^ error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:151:6 + --> tests/ui/indexing_slicing_slice.rs:150:6 | LL | &v[10..]; | ^^^^^^^ @@ -116,7 +116,7 @@ LL | &v[10..]; = help: consider using `.get(n..)` or .get_mut(n..)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:153:6 + --> tests/ui/indexing_slicing_slice.rs:152:6 | LL | &v[..100]; | ^^^^^^^^ @@ -124,7 +124,7 @@ LL | &v[..100]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_slice.rs:171:5 + --> tests/ui/indexing_slicing_slice.rs:170:5 | LL | map_with_get[true]; | ^^^^^^^^^^^^^^^^^^ @@ -140,7 +140,7 @@ LL | s[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_slice.rs:177:5 + --> tests/ui/indexing_slicing_slice.rs:178:5 | LL | y[0]; | ^^^^ diff --git a/tests/ui/ineffective_open_options.fixed b/tests/ui/ineffective_open_options.fixed index 88489dc46bbb..c229278e78b2 100644 --- a/tests/ui/ineffective_open_options.fixed +++ b/tests/ui/ineffective_open_options.fixed @@ -5,7 +5,7 @@ use std::fs::OpenOptions; fn main() { let file = OpenOptions::new() .create(true) - //~ ERROR: unnecessary use of `.write(true)` +//~^ ineffective_open_options .append(true) .open("dump.json") .unwrap(); @@ -13,7 +13,7 @@ fn main() { let file = OpenOptions::new() .create(true) .append(true) - //~ ERROR: unnecessary use of `.write(true)` +//~^ ineffective_open_options .open("dump.json") .unwrap(); diff --git a/tests/ui/ineffective_open_options.rs b/tests/ui/ineffective_open_options.rs index db8bca3e2acd..ed1fe79a2782 100644 --- a/tests/ui/ineffective_open_options.rs +++ b/tests/ui/ineffective_open_options.rs @@ -5,7 +5,8 @@ use std::fs::OpenOptions; fn main() { let file = OpenOptions::new() .create(true) - .write(true) //~ ERROR: unnecessary use of `.write(true)` +.write(true) +//~^ ineffective_open_options .append(true) .open("dump.json") .unwrap(); @@ -13,7 +14,8 @@ fn main() { let file = OpenOptions::new() .create(true) .append(true) - .write(true) //~ ERROR: unnecessary use of `.write(true)` +.write(true) +//~^ ineffective_open_options .open("dump.json") .unwrap(); diff --git a/tests/ui/ineffective_open_options.stderr b/tests/ui/ineffective_open_options.stderr index 0d6933bb449e..afc97ecd755c 100644 --- a/tests/ui/ineffective_open_options.stderr +++ b/tests/ui/ineffective_open_options.stderr @@ -1,17 +1,17 @@ error: unnecessary use of `.write(true)` because there is `.append(true)` - --> tests/ui/ineffective_open_options.rs:8:9 + --> tests/ui/ineffective_open_options.rs:8:1 | -LL | .write(true) - | ^^^^^^^^^^^^ help: remove `.write(true)` +LL | .write(true) + | ^^^^^^^^^^^^ help: remove `.write(true)` | = note: `-D clippy::ineffective-open-options` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::ineffective_open_options)]` error: unnecessary use of `.write(true)` because there is `.append(true)` - --> tests/ui/ineffective_open_options.rs:16:9 + --> tests/ui/ineffective_open_options.rs:17:1 | -LL | .write(true) - | ^^^^^^^^^^^^ help: remove `.write(true)` +LL | .write(true) + | ^^^^^^^^^^^^ help: remove `.write(true)` error: aborting due to 2 previous errors diff --git a/tests/ui/inefficient_to_string.fixed b/tests/ui/inefficient_to_string.fixed index 1e19323113c5..a0d34e58a925 100644 --- a/tests/ui/inefficient_to_string.fixed +++ b/tests/ui/inefficient_to_string.fixed @@ -8,7 +8,9 @@ fn main() { let rrrstr: &&&str = &rrstr; let _: String = rstr.to_string(); let _: String = (*rrstr).to_string(); + //~^ inefficient_to_string let _: String = (**rrrstr).to_string(); + //~^ inefficient_to_string let string: String = String::from("hello"); let rstring: &String = &string; @@ -17,7 +19,9 @@ fn main() { let _: String = string.to_string(); let _: String = rstring.to_string(); let _: String = (*rrstring).to_string(); + //~^ inefficient_to_string let _: String = (**rrrstring).to_string(); + //~^ inefficient_to_string let cow: Cow<'_, str> = Cow::Borrowed("hello"); let rcow: &Cow<'_, str> = &cow; @@ -26,5 +30,7 @@ fn main() { let _: String = cow.to_string(); let _: String = rcow.to_string(); let _: String = (*rrcow).to_string(); + //~^ inefficient_to_string let _: String = (**rrrcow).to_string(); + //~^ inefficient_to_string } diff --git a/tests/ui/inefficient_to_string.rs b/tests/ui/inefficient_to_string.rs index f027bae6fe34..cbe90d4a125b 100644 --- a/tests/ui/inefficient_to_string.rs +++ b/tests/ui/inefficient_to_string.rs @@ -8,7 +8,9 @@ fn main() { let rrrstr: &&&str = &rrstr; let _: String = rstr.to_string(); let _: String = rrstr.to_string(); + //~^ inefficient_to_string let _: String = rrrstr.to_string(); + //~^ inefficient_to_string let string: String = String::from("hello"); let rstring: &String = &string; @@ -17,7 +19,9 @@ fn main() { let _: String = string.to_string(); let _: String = rstring.to_string(); let _: String = rrstring.to_string(); + //~^ inefficient_to_string let _: String = rrrstring.to_string(); + //~^ inefficient_to_string let cow: Cow<'_, str> = Cow::Borrowed("hello"); let rcow: &Cow<'_, str> = &cow; @@ -26,5 +30,7 @@ fn main() { let _: String = cow.to_string(); let _: String = rcow.to_string(); let _: String = rrcow.to_string(); + //~^ inefficient_to_string let _: String = rrrcow.to_string(); + //~^ inefficient_to_string } diff --git a/tests/ui/inefficient_to_string.stderr b/tests/ui/inefficient_to_string.stderr index e71e667cf0cf..8593c0addc5f 100644 --- a/tests/ui/inefficient_to_string.stderr +++ b/tests/ui/inefficient_to_string.stderr @@ -12,7 +12,7 @@ LL | #![deny(clippy::inefficient_to_string)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: calling `to_string` on `&&&str` - --> tests/ui/inefficient_to_string.rs:11:21 + --> tests/ui/inefficient_to_string.rs:12:21 | LL | let _: String = rrrstr.to_string(); | ^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(**rrrstr).to_string()` @@ -20,7 +20,7 @@ LL | let _: String = rrrstr.to_string(); = help: `&&str` implements `ToString` through a slower blanket impl, but `str` has a fast specialization of `ToString` error: calling `to_string` on `&&std::string::String` - --> tests/ui/inefficient_to_string.rs:19:21 + --> tests/ui/inefficient_to_string.rs:21:21 | LL | let _: String = rrstring.to_string(); | ^^^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrstring).to_string()` @@ -28,7 +28,7 @@ LL | let _: String = rrstring.to_string(); = help: `&std::string::String` implements `ToString` through a slower blanket impl, but `std::string::String` has a fast specialization of `ToString` error: calling `to_string` on `&&&std::string::String` - --> tests/ui/inefficient_to_string.rs:20:21 + --> tests/ui/inefficient_to_string.rs:23:21 | LL | let _: String = rrrstring.to_string(); | ^^^^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(**rrrstring).to_string()` @@ -36,7 +36,7 @@ LL | let _: String = rrrstring.to_string(); = help: `&&std::string::String` implements `ToString` through a slower blanket impl, but `std::string::String` has a fast specialization of `ToString` error: calling `to_string` on `&&std::borrow::Cow<'_, str>` - --> tests/ui/inefficient_to_string.rs:28:21 + --> tests/ui/inefficient_to_string.rs:32:21 | LL | let _: String = rrcow.to_string(); | ^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrcow).to_string()` @@ -44,7 +44,7 @@ LL | let _: String = rrcow.to_string(); = help: `&std::borrow::Cow<'_, str>` implements `ToString` through a slower blanket impl, but `std::borrow::Cow<'_, str>` has a fast specialization of `ToString` error: calling `to_string` on `&&&std::borrow::Cow<'_, str>` - --> tests/ui/inefficient_to_string.rs:29:21 + --> tests/ui/inefficient_to_string.rs:34:21 | LL | let _: String = rrrcow.to_string(); | ^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(**rrrcow).to_string()` diff --git a/tests/ui/infallible_destructuring_match.rs b/tests/ui/infallible_destructuring_match.rs index 7cc7cb9d6878..3db3aca18f23 100644 --- a/tests/ui/infallible_destructuring_match.rs +++ b/tests/ui/infallible_destructuring_match.rs @@ -26,6 +26,7 @@ fn infallible_destructuring_match_enum() { // This should lint! let data = match wrapper { + //~^ infallible_destructuring_match SingleVariantEnum::Variant(i) => i, }; @@ -58,6 +59,7 @@ fn infallible_destructuring_match_struct() { // This should lint! let data = match wrapper { + //~^ infallible_destructuring_match TupleStruct(i) => i, }; @@ -82,6 +84,7 @@ fn infallible_destructuring_match_struct_with_noncopy() { // This should lint! (keeping `ref` in the suggestion) let data = match wrapper { + //~^ infallible_destructuring_match TupleStructWithNonCopy(ref n) => n, }; @@ -101,6 +104,7 @@ fn never_enum() { // This should lint! let data = match wrapper { + //~^ infallible_destructuring_match Ok(i) => i, }; diff --git a/tests/ui/infallible_destructuring_match.stderr b/tests/ui/infallible_destructuring_match.stderr index b709fd8630e9..1e784bc598bf 100644 --- a/tests/ui/infallible_destructuring_match.stderr +++ b/tests/ui/infallible_destructuring_match.stderr @@ -2,6 +2,7 @@ error: you seem to be trying to use `match` to destructure a single infallible p --> tests/ui/infallible_destructuring_match.rs:28:5 | LL | / let data = match wrapper { +LL | | LL | | SingleVariantEnum::Variant(i) => i, LL | | }; | |______^ help: try: `let SingleVariantEnum::Variant(data) = wrapper;` @@ -10,25 +11,28 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::infallible_destructuring_match)]` error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let` - --> tests/ui/infallible_destructuring_match.rs:60:5 + --> tests/ui/infallible_destructuring_match.rs:61:5 | LL | / let data = match wrapper { +LL | | LL | | TupleStruct(i) => i, LL | | }; | |______^ help: try: `let TupleStruct(data) = wrapper;` error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let` - --> tests/ui/infallible_destructuring_match.rs:84:5 + --> tests/ui/infallible_destructuring_match.rs:86:5 | LL | / let data = match wrapper { +LL | | LL | | TupleStructWithNonCopy(ref n) => n, LL | | }; | |______^ help: try: `let TupleStructWithNonCopy(ref data) = wrapper;` error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let` - --> tests/ui/infallible_destructuring_match.rs:103:5 + --> tests/ui/infallible_destructuring_match.rs:106:5 | LL | / let data = match wrapper { +LL | | LL | | Ok(i) => i, LL | | }; | |______^ help: try: `let Ok(data) = wrapper;` diff --git a/tests/ui/infinite_iter.rs b/tests/ui/infinite_iter.rs index 178e300ff5bf..2f8cc954e70c 100644 --- a/tests/ui/infinite_iter.rs +++ b/tests/ui/infinite_iter.rs @@ -9,13 +9,16 @@ fn square_is_lower_64(x: &u32) -> bool { #[deny(clippy::infinite_iter)] fn infinite_iters() { repeat(0_u8).collect::>(); - //~^ ERROR: infinite iteration detected + //~^ infinite_iter + // infinite iter (0..8_u32).take_while(square_is_lower_64).cycle().count(); - //~^ ERROR: infinite iteration detected + //~^ infinite_iter + // infinite iter (0..8_u64).chain(0..).max(); - //~^ ERROR: infinite iteration detected + //~^ infinite_iter + // infinite iter (0_usize..) .chain([0usize, 1, 2].iter().cloned()) @@ -23,7 +26,8 @@ fn infinite_iters() { .min(); // infinite iter (0..8_u32) - //~^ ERROR: infinite iteration detected + //~^ infinite_iter + .rev() .cycle() .map(|x| x + 1_u32) @@ -32,10 +36,12 @@ fn infinite_iters() { (0..3_u32).flat_map(|x| x..).sum::(); // infinite iter (0_usize..).flat_map(|x| 0..x).product::(); - //~^ ERROR: infinite iteration detected + //~^ infinite_iter + // infinite iter (0_u64..).filter(|x| x % 2 == 0).last(); - //~^ ERROR: infinite iteration detected + //~^ infinite_iter + // not an infinite, because ranges are double-ended (0..42_u64).by_ref().last(); // iterator is not exhausted @@ -46,13 +52,16 @@ fn infinite_iters() { fn potential_infinite_iters() { // maybe infinite iter (0..).zip((0..).take_while(square_is_lower_64)).count(); - //~^ ERROR: possible infinite iteration detected + //~^ maybe_infinite_iter + // maybe infinite iter repeat(42).take_while(|x| *x == 42).chain(0..42).max(); - //~^ ERROR: possible infinite iteration detected + //~^ maybe_infinite_iter + // maybe infinite iter (1..) - //~^ ERROR: possible infinite iteration detected + //~^ maybe_infinite_iter + .scan(0, |state, x| { *state += x; Some(*state) @@ -60,16 +69,20 @@ fn potential_infinite_iters() { .min(); // maybe infinite iter (0..).find(|x| *x == 24); - //~^ ERROR: possible infinite iteration detected + //~^ maybe_infinite_iter + // maybe infinite iter (0..).position(|x| x == 24); - //~^ ERROR: possible infinite iteration detected + //~^ maybe_infinite_iter + // maybe infinite iter (0..).any(|x| x == 24); - //~^ ERROR: possible infinite iteration detected + //~^ maybe_infinite_iter + // maybe infinite iter (0..).all(|x| x == 24); - //~^ ERROR: possible infinite iteration detected + //~^ maybe_infinite_iter + // not infinite (0..).zip(0..42).take_while(|&(x, _)| x != 42).count(); @@ -95,8 +108,9 @@ mod finite_collect { fn check_collect() { // Infinite iter let _: HashSet = (0..).collect(); - //~^ ERROR: infinite iteration detected - //~| NOTE: `#[deny(clippy::infinite_iter)]` on by default + //~^ infinite_iter + + // Some data structures don't collect infinitely, such as `ArrayVec` let _: C = (0..).collect(); diff --git a/tests/ui/infinite_iter.stderr b/tests/ui/infinite_iter.stderr index e33d83b75edb..ef3836a5ab59 100644 --- a/tests/ui/infinite_iter.stderr +++ b/tests/ui/infinite_iter.stderr @@ -11,22 +11,23 @@ LL | #[deny(clippy::infinite_iter)] | ^^^^^^^^^^^^^^^^^^^^^ error: infinite iteration detected - --> tests/ui/infinite_iter.rs:14:5 + --> tests/ui/infinite_iter.rs:15:5 | LL | (0..8_u32).take_while(square_is_lower_64).cycle().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: infinite iteration detected - --> tests/ui/infinite_iter.rs:17:5 + --> tests/ui/infinite_iter.rs:19:5 | LL | (0..8_u64).chain(0..).max(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: infinite iteration detected - --> tests/ui/infinite_iter.rs:25:5 + --> tests/ui/infinite_iter.rs:28:5 | LL | / (0..8_u32) LL | | +LL | | LL | | .rev() LL | | .cycle() LL | | .map(|x| x + 1_u32) @@ -34,73 +35,73 @@ LL | | .for_each(|x| println!("{}", x)); | |________________________________________^ error: infinite iteration detected - --> tests/ui/infinite_iter.rs:34:5 + --> tests/ui/infinite_iter.rs:38:5 | LL | (0_usize..).flat_map(|x| 0..x).product::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: infinite iteration detected - --> tests/ui/infinite_iter.rs:37:5 + --> tests/ui/infinite_iter.rs:42:5 | LL | (0_u64..).filter(|x| x % 2 == 0).last(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:48:5 + --> tests/ui/infinite_iter.rs:54:5 | LL | (0..).zip((0..).take_while(square_is_lower_64)).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> tests/ui/infinite_iter.rs:45:8 + --> tests/ui/infinite_iter.rs:51:8 | LL | #[deny(clippy::maybe_infinite_iter)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:51:5 + --> tests/ui/infinite_iter.rs:58:5 | LL | repeat(42).take_while(|x| *x == 42).chain(0..42).max(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:54:5 + --> tests/ui/infinite_iter.rs:62:5 | LL | / (1..) LL | | +LL | | LL | | .scan(0, |state, x| { -LL | | *state += x; -LL | | Some(*state) +... | LL | | }) LL | | .min(); | |______________^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:62:5 + --> tests/ui/infinite_iter.rs:71:5 | LL | (0..).find(|x| *x == 24); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:65:5 + --> tests/ui/infinite_iter.rs:75:5 | LL | (0..).position(|x| x == 24); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:68:5 + --> tests/ui/infinite_iter.rs:79:5 | LL | (0..).any(|x| x == 24); | ^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:71:5 + --> tests/ui/infinite_iter.rs:83:5 | LL | (0..).all(|x| x == 24); | ^^^^^^^^^^^^^^^^^^^^^^ error: infinite iteration detected - --> tests/ui/infinite_iter.rs:97:31 + --> tests/ui/infinite_iter.rs:110:31 | LL | let _: HashSet = (0..).collect(); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/infinite_loop.rs b/tests/ui/infinite_loop.rs index 765c67011474..02d40e84eed9 100644 --- a/tests/ui/infinite_loop.rs +++ b/tests/ui/infinite_loop.rs @@ -20,15 +20,17 @@ fn immutable_condition() { // Should warn when all vars mentioned are immutable let y = 0; while y < 10 { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + println!("KO - y is immutable"); } let x = 0; while y < 10 && x < 3 { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + let mut k = 1; k += 2; println!("KO - x and y immutable"); @@ -36,8 +38,9 @@ fn immutable_condition() { let cond = false; while !cond { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + println!("KO - cond immutable"); } @@ -82,21 +85,24 @@ fn unused_var() { let (mut i, mut j) = (0, 0); while i < 3 { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + j = 3; println!("KO - i not mentioned"); } while i < 3 && j > 0 { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + println!("KO - i and j not mentioned"); } while i < 3 { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + let mut i = 5; fn_mutref(&mut i); println!("KO - shadowed"); @@ -112,15 +118,17 @@ fn used_immutable() { let mut i = 0; while i < 3 { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + fn_constref(&i); println!("KO - const reference"); } while i < 3 { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + fn_val(i); println!("KO - passed by value"); } @@ -187,8 +195,9 @@ impl Counter { fn print_n(&self, n: usize) { while self.count < n { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + println!("KO - {} is not mutated", self.count); } } @@ -197,8 +206,9 @@ impl Counter { fn while_loop_with_break_and_return() { let y = 0; while y < 10 { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + if y == 0 { break; } @@ -206,8 +216,9 @@ fn while_loop_with_break_and_return() { } while y < 10 { - //~^ ERROR: variables in the condition are not mutated in the loop body - //~| NOTE: this may lead to an infinite or to a never running loop + //~^ while_immutable_condition + + if y == 0 { return; } diff --git a/tests/ui/infinite_loop.stderr b/tests/ui/infinite_loop.stderr index 7ba1374d64f4..f2876fd6ddb8 100644 --- a/tests/ui/infinite_loop.stderr +++ b/tests/ui/infinite_loop.stderr @@ -8,7 +8,7 @@ LL | while y < 10 { = note: `#[deny(clippy::while_immutable_condition)]` on by default error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:29:11 + --> tests/ui/infinite_loop.rs:30:11 | LL | while y < 10 && x < 3 { | ^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | while y < 10 && x < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:38:11 + --> tests/ui/infinite_loop.rs:40:11 | LL | while !cond { | ^^^^^ @@ -24,7 +24,7 @@ LL | while !cond { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:84:11 + --> tests/ui/infinite_loop.rs:87:11 | LL | while i < 3 { | ^^^^^ @@ -32,7 +32,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:91:11 + --> tests/ui/infinite_loop.rs:95:11 | LL | while i < 3 && j > 0 { | ^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | while i < 3 && j > 0 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:97:11 + --> tests/ui/infinite_loop.rs:102:11 | LL | while i < 3 { | ^^^^^ @@ -48,7 +48,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:114:11 + --> tests/ui/infinite_loop.rs:120:11 | LL | while i < 3 { | ^^^^^ @@ -56,7 +56,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:121:11 + --> tests/ui/infinite_loop.rs:128:11 | LL | while i < 3 { | ^^^^^ @@ -64,23 +64,13 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:189:15 + --> tests/ui/infinite_loop.rs:197:15 | LL | while self.count < n { | ^^^^^^^^^^^^^^ | = note: this may lead to an infinite or to a never running loop -error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:199:11 - | -LL | while y < 10 { - | ^^^^^^ - | - = note: this may lead to an infinite or to a never running loop - = note: this loop contains `return`s or `break`s - = help: rewrite it as `if cond { loop { } }` - error: variables in the condition are not mutated in the loop body --> tests/ui/infinite_loop.rs:208:11 | @@ -91,5 +81,15 @@ LL | while y < 10 { = note: this loop contains `return`s or `break`s = help: rewrite it as `if cond { loop { } }` +error: variables in the condition are not mutated in the loop body + --> tests/ui/infinite_loop.rs:218:11 + | +LL | while y < 10 { + | ^^^^^^ + | + = note: this may lead to an infinite or to a never running loop + = note: this loop contains `return`s or `break`s + = help: rewrite it as `if cond { loop { } }` + error: aborting due to 11 previous errors diff --git a/tests/ui/infinite_loops.rs b/tests/ui/infinite_loops.rs index d7be6f9ce7e9..b5c1a5688eca 100644 --- a/tests/ui/infinite_loops.rs +++ b/tests/ui/infinite_loops.rs @@ -11,18 +11,18 @@ fn do_something() {} fn no_break() { loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop do_something(); } } fn all_inf() { loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop do_something(); } } @@ -36,7 +36,7 @@ fn no_break_return_some_ty() -> Option { return None; } loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop do_something(); } } @@ -49,6 +49,7 @@ fn no_break_never_ret() -> ! { fn no_break_never_ret_noise() { loop { + //~^ infinite_loop fn inner_fn() -> ! { std::process::exit(0); } @@ -92,7 +93,7 @@ fn has_indirect_break_2(stop_num: i32) { fn break_inner_but_not_outer_1(cond: bool) { loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop loop { if cond { break; @@ -103,7 +104,7 @@ fn break_inner_but_not_outer_1(cond: bool) { fn break_inner_but_not_outer_2(cond: bool) { loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop 'inner: loop { loop { if cond { @@ -117,7 +118,7 @@ fn break_inner_but_not_outer_2(cond: bool) { fn break_outer_but_not_inner() { loop { loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop do_something(); } break; @@ -140,7 +141,7 @@ fn break_wrong_loop(cond: bool) { // 'inner has statement to break 'outer loop, but it was broken out of early by a labeled child loop 'outer: loop { loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop 'inner: loop { loop { loop { @@ -180,7 +181,7 @@ enum Foo { fn match_like() { let opt: Option = Some(1); loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop match opt { Some(v) => { println!("{v}"); @@ -221,12 +222,12 @@ fn match_like() { } loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop let _x = matches!(result, Ok(v) if v != 0).then_some(0); } loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop // This `return` does not return the function, so it doesn't count let _x = matches!(result, Ok(v) if v != 0).then(|| { if true { @@ -331,7 +332,7 @@ fn exit_directly(cond: bool) { trait MyTrait { fn problematic_trait_method() { loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop do_something(); } } @@ -341,7 +342,7 @@ trait MyTrait { impl MyTrait for String { fn could_be_problematic() { loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop do_something(); } } @@ -350,7 +351,7 @@ impl MyTrait for String { fn inf_loop_in_closure() { let _loop_forever = || { loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop do_something(); } }; @@ -364,6 +365,7 @@ fn inf_loop_in_closure() { fn inf_loop_in_res() -> Result<(), i32> { Ok(loop { + //~^ infinite_loop do_something() }) } @@ -406,15 +408,16 @@ fn continue_outer() { // This should lint as we continue the loop itself 'infinite: loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop loop { continue 'infinite; } } // This should lint as we continue an inner loop loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop 'inner: loop { + //~^ infinite_loop loop { continue 'inner; } @@ -423,7 +426,7 @@ fn continue_outer() { // This should lint as we continue the loop itself loop { - //~^ ERROR: infinite loop detected + //~^ infinite_loop continue; } } diff --git a/tests/ui/infinite_loops.stderr b/tests/ui/infinite_loops.stderr index 3b5705d5f21d..4d02636ef4ae 100644 --- a/tests/ui/infinite_loops.stderr +++ b/tests/ui/infinite_loops.stderr @@ -74,9 +74,11 @@ error: infinite loop detected --> tests/ui/infinite_loops.rs:51:5 | LL | / loop { +LL | | LL | | fn inner_fn() -> ! { LL | | std::process::exit(0); -... | +LL | | } +LL | | do_something(); LL | | } | |_____^ | @@ -86,7 +88,7 @@ LL | fn no_break_never_ret_noise() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:94:5 + --> tests/ui/infinite_loops.rs:95:5 | LL | / loop { LL | | @@ -102,7 +104,7 @@ LL | fn break_inner_but_not_outer_1(cond: bool) -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:105:5 + --> tests/ui/infinite_loops.rs:106:5 | LL | / loop { LL | | @@ -118,7 +120,7 @@ LL | fn break_inner_but_not_outer_2(cond: bool) -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:119:9 + --> tests/ui/infinite_loops.rs:120:9 | LL | / loop { LL | | @@ -132,7 +134,7 @@ LL | fn break_outer_but_not_inner() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:142:9 + --> tests/ui/infinite_loops.rs:143:9 | LL | / loop { LL | | @@ -148,7 +150,7 @@ LL | fn break_wrong_loop(cond: bool) -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:182:5 + --> tests/ui/infinite_loops.rs:183:5 | LL | / loop { LL | | @@ -164,7 +166,7 @@ LL | fn match_like() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:223:5 + --> tests/ui/infinite_loops.rs:224:5 | LL | / loop { LL | | @@ -178,7 +180,7 @@ LL | fn match_like() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:228:5 + --> tests/ui/infinite_loops.rs:229:5 | LL | / loop { LL | | @@ -195,7 +197,7 @@ LL | fn match_like() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:333:9 + --> tests/ui/infinite_loops.rs:334:9 | LL | / loop { LL | | @@ -209,7 +211,7 @@ LL | fn problematic_trait_method() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:343:9 + --> tests/ui/infinite_loops.rs:344:9 | LL | / loop { LL | | @@ -223,7 +225,7 @@ LL | fn could_be_problematic() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:352:9 + --> tests/ui/infinite_loops.rs:353:9 | LL | / loop { LL | | @@ -237,10 +239,11 @@ LL | let _loop_forever = || -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:366:8 + --> tests/ui/infinite_loops.rs:367:8 | LL | Ok(loop { | ________^ +LL | | LL | | do_something() LL | | }) | |_____^ @@ -248,7 +251,7 @@ LL | | }) = help: if this is not intended, try adding a `break` or `return` condition in the loop error: infinite loop detected - --> tests/ui/infinite_loops.rs:408:5 + --> tests/ui/infinite_loops.rs:410:5 | LL | / 'infinite: loop { LL | | @@ -264,12 +267,11 @@ LL | fn continue_outer() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:415:5 + --> tests/ui/infinite_loops.rs:417:5 | LL | / loop { LL | | LL | | 'inner: loop { -LL | | loop { ... | LL | | } | |_____^ @@ -280,9 +282,10 @@ LL | fn continue_outer() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:417:9 + --> tests/ui/infinite_loops.rs:419:9 | LL | / 'inner: loop { +LL | | LL | | loop { LL | | continue 'inner; LL | | } @@ -295,7 +298,7 @@ LL | fn continue_outer() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:425:5 + --> tests/ui/infinite_loops.rs:428:5 | LL | / loop { LL | | diff --git a/tests/ui/inherent_to_string.rs b/tests/ui/inherent_to_string.rs index 7b938cdd758c..a1a810dad1e4 100644 --- a/tests/ui/inherent_to_string.rs +++ b/tests/ui/inherent_to_string.rs @@ -20,7 +20,8 @@ struct J; impl A { // Should be detected; emit warning fn to_string(&self) -> String { - //~^ ERROR: implementation of inherent method `to_string(&self) -> String` for type `A + //~^ inherent_to_string + "A.to_string()".to_string() } @@ -45,7 +46,8 @@ impl B { impl C { // Should be detected and emit error as C also implements Display fn to_string(&self) -> String { - //~^ ERROR: type `C` implements inherent method `to_string(&self) -> String` which sha + //~^ inherent_to_string_shadow_display + "C.to_string()".to_string() } } diff --git a/tests/ui/inherent_to_string.stderr b/tests/ui/inherent_to_string.stderr index eb22525a2491..f1d415a45755 100644 --- a/tests/ui/inherent_to_string.stderr +++ b/tests/ui/inherent_to_string.stderr @@ -3,6 +3,7 @@ error: implementation of inherent method `to_string(&self) -> String` for type ` | LL | / fn to_string(&self) -> String { LL | | +LL | | LL | | "A.to_string()".to_string() LL | | } | |_____^ @@ -12,10 +13,11 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::inherent_to_string)]` error: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display` - --> tests/ui/inherent_to_string.rs:47:5 + --> tests/ui/inherent_to_string.rs:48:5 | LL | / fn to_string(&self) -> String { LL | | +LL | | LL | | "C.to_string()".to_string() LL | | } | |_____^ diff --git a/tests/ui/init_numbered_fields.fixed b/tests/ui/init_numbered_fields.fixed index dca4e8da4d2f..b4c5fa83ce95 100644 --- a/tests/ui/init_numbered_fields.fixed +++ b/tests/ui/init_numbered_fields.fixed @@ -39,6 +39,7 @@ fn main() { struct TupleStructVec(Vec); let _ = TupleStructVec(vec![0, 1, 2, 3]); + //~^ init_numbered_fields { struct S(i32, i32); diff --git a/tests/ui/init_numbered_fields.rs b/tests/ui/init_numbered_fields.rs index 8cb34705b4f6..dc33921e3df9 100644 --- a/tests/ui/init_numbered_fields.rs +++ b/tests/ui/init_numbered_fields.rs @@ -15,6 +15,7 @@ fn main() { // This should lint let _ = TupleStruct { + //~^ init_numbered_fields 0: 1u32, 1: 42, 2: 23u8, @@ -22,6 +23,7 @@ fn main() { // This should also lint and order the fields correctly let _ = TupleStruct { + //~^ init_numbered_fields 0: 1u32, 2: 2u8, 1: 3u32, @@ -47,6 +49,7 @@ fn main() { struct TupleStructVec(Vec); let _ = TupleStructVec { 0: vec![0, 1, 2, 3] }; + //~^ init_numbered_fields { struct S(i32, i32); diff --git a/tests/ui/init_numbered_fields.stderr b/tests/ui/init_numbered_fields.stderr index f176e0c2ff30..89828b7e2fce 100644 --- a/tests/ui/init_numbered_fields.stderr +++ b/tests/ui/init_numbered_fields.stderr @@ -3,6 +3,7 @@ error: used a field initializer for a tuple struct | LL | let _ = TupleStruct { | _____________^ +LL | | LL | | 0: 1u32, LL | | 1: 42, LL | | 2: 23u8, @@ -13,10 +14,11 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::init_numbered_fields)]` error: used a field initializer for a tuple struct - --> tests/ui/init_numbered_fields.rs:24:13 + --> tests/ui/init_numbered_fields.rs:25:13 | LL | let _ = TupleStruct { | _____________^ +LL | | LL | | 0: 1u32, LL | | 2: 2u8, LL | | 1: 3u32, @@ -24,7 +26,7 @@ LL | | }; | |_____^ help: use tuple initialization: `TupleStruct(1u32, 3u32, 2u8)` error: used a field initializer for a tuple struct - --> tests/ui/init_numbered_fields.rs:49:13 + --> tests/ui/init_numbered_fields.rs:51:13 | LL | let _ = TupleStructVec { 0: vec![0, 1, 2, 3] }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use tuple initialization: `TupleStructVec(vec![0, 1, 2, 3])` diff --git a/tests/ui/inline_fn_without_body.fixed b/tests/ui/inline_fn_without_body.fixed index acd808ed49bb..3567209b41f7 100644 --- a/tests/ui/inline_fn_without_body.fixed +++ b/tests/ui/inline_fn_without_body.fixed @@ -2,10 +2,13 @@ #![allow(clippy::inline_always)] trait Foo { + //~^ inline_fn_without_body fn default_inline(); + //~^ inline_fn_without_body fn always_inline(); + //~^ inline_fn_without_body fn never_inline(); #[inline] diff --git a/tests/ui/inline_fn_without_body.rs b/tests/ui/inline_fn_without_body.rs index af81feaa374a..9ca90e637f15 100644 --- a/tests/ui/inline_fn_without_body.rs +++ b/tests/ui/inline_fn_without_body.rs @@ -3,12 +3,15 @@ trait Foo { #[inline] + //~^ inline_fn_without_body fn default_inline(); #[inline(always)] + //~^ inline_fn_without_body fn always_inline(); #[inline(never)] + //~^ inline_fn_without_body fn never_inline(); #[inline] diff --git a/tests/ui/inline_fn_without_body.stderr b/tests/ui/inline_fn_without_body.stderr index 89db710fabe7..61bc5505ea30 100644 --- a/tests/ui/inline_fn_without_body.stderr +++ b/tests/ui/inline_fn_without_body.stderr @@ -3,26 +3,26 @@ error: use of `#[inline]` on trait method `default_inline` which has no body | LL | #[inline] | _____-^^^^^^^^ -LL | | fn default_inline(); +LL | | | |____- help: remove | = note: `-D clippy::inline-fn-without-body` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::inline_fn_without_body)]` error: use of `#[inline]` on trait method `always_inline` which has no body - --> tests/ui/inline_fn_without_body.rs:8:5 + --> tests/ui/inline_fn_without_body.rs:9:5 | LL | #[inline(always)] | _____-^^^^^^^^^^^^^^^^ -LL | | fn always_inline(); +LL | | | |____- help: remove error: use of `#[inline]` on trait method `never_inline` which has no body - --> tests/ui/inline_fn_without_body.rs:11:5 + --> tests/ui/inline_fn_without_body.rs:13:5 | LL | #[inline(never)] | _____-^^^^^^^^^^^^^^^ -LL | | fn never_inline(); +LL | | | |____- help: remove error: aborting due to 3 previous errors diff --git a/tests/ui/inspect_for_each.rs b/tests/ui/inspect_for_each.rs index 974690eaa8e4..d3eb7fcbba4d 100644 --- a/tests/ui/inspect_for_each.rs +++ b/tests/ui/inspect_for_each.rs @@ -5,7 +5,8 @@ fn main() { let mut b: Vec = Vec::new(); a.into_iter().inspect(|x| assert!(*x > 0)).for_each(|x| { - //~^ ERROR: called `inspect(..).for_each(..)` on an `Iterator` + //~^ inspect_for_each + let y = do_some(x); let z = do_more(y); b.push(z); diff --git a/tests/ui/inspect_for_each.stderr b/tests/ui/inspect_for_each.stderr index 3c2dee15ebd5..6a715c9c4efc 100644 --- a/tests/ui/inspect_for_each.stderr +++ b/tests/ui/inspect_for_each.stderr @@ -4,6 +4,7 @@ error: called `inspect(..).for_each(..)` on an `Iterator` LL | a.into_iter().inspect(|x| assert!(*x > 0)).for_each(|x| { | ___________________^ LL | | +LL | | LL | | let y = do_some(x); LL | | let z = do_more(y); LL | | b.push(z); diff --git a/tests/ui/int_plus_one.fixed b/tests/ui/int_plus_one.fixed index 77d9cd3f773a..a1aba6bf7f64 100644 --- a/tests/ui/int_plus_one.fixed +++ b/tests/ui/int_plus_one.fixed @@ -5,10 +5,14 @@ fn main() { let y = 0i32; let _ = x > y; + //~^ int_plus_one let _ = y < x; + //~^ int_plus_one let _ = x > y; + //~^ int_plus_one let _ = y < x; + //~^ int_plus_one let _ = x > y; // should be ok let _ = y < x; // should be ok diff --git a/tests/ui/int_plus_one.rs b/tests/ui/int_plus_one.rs index 57c87819dbfe..f804fc9047de 100644 --- a/tests/ui/int_plus_one.rs +++ b/tests/ui/int_plus_one.rs @@ -5,10 +5,14 @@ fn main() { let y = 0i32; let _ = x >= y + 1; + //~^ int_plus_one let _ = y + 1 <= x; + //~^ int_plus_one let _ = x - 1 >= y; + //~^ int_plus_one let _ = y <= x - 1; + //~^ int_plus_one let _ = x > y; // should be ok let _ = y < x; // should be ok diff --git a/tests/ui/int_plus_one.stderr b/tests/ui/int_plus_one.stderr index cedac14f350d..052706028141 100644 --- a/tests/ui/int_plus_one.stderr +++ b/tests/ui/int_plus_one.stderr @@ -8,19 +8,19 @@ LL | let _ = x >= y + 1; = help: to override `-D warnings` add `#[allow(clippy::int_plus_one)]` error: unnecessary `>= y + 1` or `x - 1 >=` - --> tests/ui/int_plus_one.rs:8:13 + --> tests/ui/int_plus_one.rs:9:13 | LL | let _ = y + 1 <= x; | ^^^^^^^^^^ help: change it to: `y < x` error: unnecessary `>= y + 1` or `x - 1 >=` - --> tests/ui/int_plus_one.rs:10:13 + --> tests/ui/int_plus_one.rs:12:13 | LL | let _ = x - 1 >= y; | ^^^^^^^^^^ help: change it to: `x > y` error: unnecessary `>= y + 1` or `x - 1 >=` - --> tests/ui/int_plus_one.rs:11:13 + --> tests/ui/int_plus_one.rs:14:13 | LL | let _ = y <= x - 1; | ^^^^^^^^^^ help: change it to: `y < x` diff --git a/tests/ui/integer_division.rs b/tests/ui/integer_division.rs index 137548fecf4a..632fedc9e8fe 100644 --- a/tests/ui/integer_division.rs +++ b/tests/ui/integer_division.rs @@ -3,10 +3,13 @@ fn main() { let two = 2; let n = 1 / 2; - //~^ ERROR: integer division + //~^ integer_division + let o = 1 / two; - //~^ ERROR: integer division + //~^ integer_division + let p = two / 4; - //~^ ERROR: integer division + //~^ integer_division + let x = 1. / 2.0; } diff --git a/tests/ui/integer_division.stderr b/tests/ui/integer_division.stderr index 5f0d905a48b6..0fe2021a1a9c 100644 --- a/tests/ui/integer_division.stderr +++ b/tests/ui/integer_division.stderr @@ -9,7 +9,7 @@ LL | let n = 1 / 2; = help: to override `-D warnings` add `#[allow(clippy::integer_division)]` error: integer division - --> tests/ui/integer_division.rs:7:13 + --> tests/ui/integer_division.rs:8:13 | LL | let o = 1 / two; | ^^^^^^^ @@ -17,7 +17,7 @@ LL | let o = 1 / two; = help: division of integers may cause loss of precision. consider using floats error: integer division - --> tests/ui/integer_division.rs:9:13 + --> tests/ui/integer_division.rs:11:13 | LL | let p = two / 4; | ^^^^^^^ diff --git a/tests/ui/integer_division_remainder_used.rs b/tests/ui/integer_division_remainder_used.rs index 5d1b02095d18..4d3a7c5eaa15 100644 --- a/tests/ui/integer_division_remainder_used.rs +++ b/tests/ui/integer_division_remainder_used.rs @@ -8,6 +8,7 @@ impl std::ops::Div for CustomOps { fn div(self, rhs: Self) -> Self::Output { Self(self.0 / rhs.0) + //~^ integer_division_remainder_used } } impl std::ops::Rem for CustomOps { @@ -15,6 +16,7 @@ impl std::ops::Rem for CustomOps { fn rem(self, rhs: Self) -> Self::Output { Self(self.0 % rhs.0) + //~^ integer_division_remainder_used } } @@ -23,12 +25,19 @@ fn main() { let a = 10; let b = 5; let c = a / b; + //~^ integer_division_remainder_used let d = a % b; + //~^ integer_division_remainder_used let e = &a / b; + //~^ integer_division_remainder_used let f = a % &b; + //~^ integer_division_remainder_used let g = &a / &b; + //~^ integer_division_remainder_used let h = &10 % b; + //~^ integer_division_remainder_used let i = a / &4; + //~^ integer_division_remainder_used // should not trigger on custom Div and Rem let w = CustomOps(3); diff --git a/tests/ui/integer_division_remainder_used.stderr b/tests/ui/integer_division_remainder_used.stderr index 8adfda28893d..ea9f0e716c7d 100644 --- a/tests/ui/integer_division_remainder_used.stderr +++ b/tests/ui/integer_division_remainder_used.stderr @@ -8,49 +8,49 @@ LL | Self(self.0 / rhs.0) = help: to override `-D warnings` add `#[allow(clippy::integer_division_remainder_used)]` error: use of % has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:17:14 + --> tests/ui/integer_division_remainder_used.rs:18:14 | LL | Self(self.0 % rhs.0) | ^^^^^^^^^^^^^^ error: use of / has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:25:13 + --> tests/ui/integer_division_remainder_used.rs:27:13 | LL | let c = a / b; | ^^^^^ error: use of % has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:26:13 + --> tests/ui/integer_division_remainder_used.rs:29:13 | LL | let d = a % b; | ^^^^^ error: use of / has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:27:13 + --> tests/ui/integer_division_remainder_used.rs:31:13 | LL | let e = &a / b; | ^^^^^^ error: use of % has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:28:13 + --> tests/ui/integer_division_remainder_used.rs:33:13 | LL | let f = a % &b; | ^^^^^^ error: use of / has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:29:13 + --> tests/ui/integer_division_remainder_used.rs:35:13 | LL | let g = &a / &b; | ^^^^^^^ error: use of % has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:30:13 + --> tests/ui/integer_division_remainder_used.rs:37:13 | LL | let h = &10 % b; | ^^^^^^^ error: use of / has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:31:13 + --> tests/ui/integer_division_remainder_used.rs:39:13 | LL | let i = a / &4; | ^^^^^^ diff --git a/tests/ui/into_iter_on_ref.fixed b/tests/ui/into_iter_on_ref.fixed index 72b39c982bf7..6d62a6547427 100644 --- a/tests/ui/into_iter_on_ref.fixed +++ b/tests/ui/into_iter_on_ref.fixed @@ -10,34 +10,60 @@ fn main() { for _ in &vec![X, X] {} let _ = vec![1, 2, 3].into_iter(); - let _ = (&vec![1, 2, 3]).iter(); //~ ERROR: equivalent to `.iter() - let _ = std::rc::Rc::from(&[X][..]).iter(); //~ ERROR: equivalent to `.iter() - let _ = std::sync::Arc::from(&[X][..]).iter(); //~ ERROR: equivalent to `.iter() +let _ = (&vec![1, 2, 3]).iter(); +//~^ into_iter_on_ref +let _ = std::rc::Rc::from(&[X][..]).iter(); +//~^ into_iter_on_ref +let _ = std::sync::Arc::from(&[X][..]).iter(); +//~^ into_iter_on_ref - let _ = (&&&&&&&[1, 2, 3]).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&&&&mut &&&[1, 2, 3]).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut &mut &mut [1, 2, 3]).iter_mut(); //~ ERROR: equivalent to `.iter_mut() +let _ = (&&&&&&&[1, 2, 3]).iter(); +//~^ into_iter_on_ref +let _ = (&&&&mut &&&[1, 2, 3]).iter(); +//~^ into_iter_on_ref +let _ = (&mut &mut &mut [1, 2, 3]).iter_mut(); +//~^ into_iter_on_ref - let _ = (&Some(4)).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut Some(5)).iter_mut(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&Ok::<_, i32>(6)).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut Err::(7)).iter_mut(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&Vec::::new()).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut Vec::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&BTreeMap::::new()).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut BTreeMap::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&VecDeque::::new()).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut VecDeque::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&LinkedList::::new()).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut LinkedList::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&HashMap::::new()).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut HashMap::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() +let _ = (&Some(4)).iter(); +//~^ into_iter_on_ref +let _ = (&mut Some(5)).iter_mut(); +//~^ into_iter_on_ref +let _ = (&Ok::<_, i32>(6)).iter(); +//~^ into_iter_on_ref +let _ = (&mut Err::(7)).iter_mut(); +//~^ into_iter_on_ref +let _ = (&Vec::::new()).iter(); +//~^ into_iter_on_ref +let _ = (&mut Vec::::new()).iter_mut(); +//~^ into_iter_on_ref +let _ = (&BTreeMap::::new()).iter(); +//~^ into_iter_on_ref +let _ = (&mut BTreeMap::::new()).iter_mut(); +//~^ into_iter_on_ref +let _ = (&VecDeque::::new()).iter(); +//~^ into_iter_on_ref +let _ = (&mut VecDeque::::new()).iter_mut(); +//~^ into_iter_on_ref +let _ = (&LinkedList::::new()).iter(); +//~^ into_iter_on_ref +let _ = (&mut LinkedList::::new()).iter_mut(); +//~^ into_iter_on_ref +let _ = (&HashMap::::new()).iter(); +//~^ into_iter_on_ref +let _ = (&mut HashMap::::new()).iter_mut(); +//~^ into_iter_on_ref - let _ = (&BTreeSet::::new()).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&BinaryHeap::::new()).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&HashSet::::new()).iter(); //~ ERROR: equivalent to `.iter() - let _ = std::path::Path::new("12/34").iter(); //~ ERROR: equivalent to `.iter() - let _ = std::path::PathBuf::from("12/34").iter(); //~ ERROR: equivalent to `.iter() +let _ = (&BTreeSet::::new()).iter(); +//~^ into_iter_on_ref +let _ = (&BinaryHeap::::new()).iter(); +//~^ into_iter_on_ref +let _ = (&HashSet::::new()).iter(); +//~^ into_iter_on_ref +let _ = std::path::Path::new("12/34").iter(); +//~^ into_iter_on_ref +let _ = std::path::PathBuf::from("12/34").iter(); +//~^ into_iter_on_ref - let _ = (&[1, 2, 3]).iter().next(); //~ ERROR: equivalent to `.iter() +let _ = (&[1, 2, 3]).iter().next(); +//~^ into_iter_on_ref } diff --git a/tests/ui/into_iter_on_ref.rs b/tests/ui/into_iter_on_ref.rs index 5ba224720d34..3e678761d751 100644 --- a/tests/ui/into_iter_on_ref.rs +++ b/tests/ui/into_iter_on_ref.rs @@ -10,34 +10,60 @@ fn main() { for _ in &vec![X, X] {} let _ = vec![1, 2, 3].into_iter(); - let _ = (&vec![1, 2, 3]).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = std::rc::Rc::from(&[X][..]).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = std::sync::Arc::from(&[X][..]).into_iter(); //~ ERROR: equivalent to `.iter() +let _ = (&vec![1, 2, 3]).into_iter(); +//~^ into_iter_on_ref +let _ = std::rc::Rc::from(&[X][..]).into_iter(); +//~^ into_iter_on_ref +let _ = std::sync::Arc::from(&[X][..]).into_iter(); +//~^ into_iter_on_ref - let _ = (&&&&&&&[1, 2, 3]).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); //~ ERROR: equivalent to `.iter_mut() +let _ = (&&&&&&&[1, 2, 3]).into_iter(); +//~^ into_iter_on_ref +let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); +//~^ into_iter_on_ref +let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); +//~^ into_iter_on_ref - let _ = (&Some(4)).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut Some(5)).into_iter(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&Ok::<_, i32>(6)).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut Err::(7)).into_iter(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&Vec::::new()).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut Vec::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&BTreeMap::::new()).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut BTreeMap::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&VecDeque::::new()).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut VecDeque::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&LinkedList::::new()).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut LinkedList::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&HashMap::::new()).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&mut HashMap::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() +let _ = (&Some(4)).into_iter(); +//~^ into_iter_on_ref +let _ = (&mut Some(5)).into_iter(); +//~^ into_iter_on_ref +let _ = (&Ok::<_, i32>(6)).into_iter(); +//~^ into_iter_on_ref +let _ = (&mut Err::(7)).into_iter(); +//~^ into_iter_on_ref +let _ = (&Vec::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&mut Vec::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&BTreeMap::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&mut BTreeMap::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&VecDeque::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&mut VecDeque::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&LinkedList::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&mut LinkedList::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&HashMap::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&mut HashMap::::new()).into_iter(); +//~^ into_iter_on_ref - let _ = (&BTreeSet::::new()).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&BinaryHeap::::new()).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&HashSet::::new()).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = std::path::Path::new("12/34").into_iter(); //~ ERROR: equivalent to `.iter() - let _ = std::path::PathBuf::from("12/34").into_iter(); //~ ERROR: equivalent to `.iter() +let _ = (&BTreeSet::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&BinaryHeap::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = (&HashSet::::new()).into_iter(); +//~^ into_iter_on_ref +let _ = std::path::Path::new("12/34").into_iter(); +//~^ into_iter_on_ref +let _ = std::path::PathBuf::from("12/34").into_iter(); +//~^ into_iter_on_ref - let _ = (&[1, 2, 3]).into_iter().next(); //~ ERROR: equivalent to `.iter() +let _ = (&[1, 2, 3]).into_iter().next(); +//~^ into_iter_on_ref } diff --git a/tests/ui/into_iter_on_ref.stderr b/tests/ui/into_iter_on_ref.stderr index 64d814074da4..2c472fca9da5 100644 --- a/tests/ui/into_iter_on_ref.stderr +++ b/tests/ui/into_iter_on_ref.stderr @@ -1,161 +1,161 @@ error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec` - --> tests/ui/into_iter_on_ref.rs:13:30 + --> tests/ui/into_iter_on_ref.rs:13:26 | -LL | let _ = (&vec![1, 2, 3]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&vec![1, 2, 3]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` | = note: `-D clippy::into-iter-on-ref` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::into_iter_on_ref)]` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice` - --> tests/ui/into_iter_on_ref.rs:14:41 + --> tests/ui/into_iter_on_ref.rs:15:37 | -LL | let _ = std::rc::Rc::from(&[X][..]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = std::rc::Rc::from(&[X][..]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice` - --> tests/ui/into_iter_on_ref.rs:15:44 + --> tests/ui/into_iter_on_ref.rs:17:40 | -LL | let _ = std::sync::Arc::from(&[X][..]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = std::sync::Arc::from(&[X][..]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` - --> tests/ui/into_iter_on_ref.rs:17:32 + --> tests/ui/into_iter_on_ref.rs:20:28 | -LL | let _ = (&&&&&&&[1, 2, 3]).into_iter(); +LL | let _ = (&&&&&&&[1, 2, 3]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` + --> tests/ui/into_iter_on_ref.rs:22:32 + | +LL | let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); | ^^^^^^^^^ help: call directly: `iter` -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` - --> tests/ui/into_iter_on_ref.rs:18:36 - | -LL | let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `array` - --> tests/ui/into_iter_on_ref.rs:19:40 + --> tests/ui/into_iter_on_ref.rs:24:36 | -LL | let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Option` - --> tests/ui/into_iter_on_ref.rs:21:24 + --> tests/ui/into_iter_on_ref.rs:27:20 | -LL | let _ = (&Some(4)).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&Some(4)).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Option` - --> tests/ui/into_iter_on_ref.rs:22:28 + --> tests/ui/into_iter_on_ref.rs:29:24 | -LL | let _ = (&mut Some(5)).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&mut Some(5)).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Result` - --> tests/ui/into_iter_on_ref.rs:23:32 + --> tests/ui/into_iter_on_ref.rs:31:28 | -LL | let _ = (&Ok::<_, i32>(6)).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&Ok::<_, i32>(6)).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Result` - --> tests/ui/into_iter_on_ref.rs:24:37 + --> tests/ui/into_iter_on_ref.rs:33:33 | -LL | let _ = (&mut Err::(7)).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&mut Err::(7)).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec` - --> tests/ui/into_iter_on_ref.rs:25:34 + --> tests/ui/into_iter_on_ref.rs:35:30 | -LL | let _ = (&Vec::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&Vec::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Vec` - --> tests/ui/into_iter_on_ref.rs:26:38 + --> tests/ui/into_iter_on_ref.rs:37:34 | -LL | let _ = (&mut Vec::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&mut Vec::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeMap` - --> tests/ui/into_iter_on_ref.rs:27:44 + --> tests/ui/into_iter_on_ref.rs:39:40 | -LL | let _ = (&BTreeMap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&BTreeMap::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `BTreeMap` - --> tests/ui/into_iter_on_ref.rs:28:48 + --> tests/ui/into_iter_on_ref.rs:41:44 | -LL | let _ = (&mut BTreeMap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&mut BTreeMap::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `VecDeque` - --> tests/ui/into_iter_on_ref.rs:29:39 + --> tests/ui/into_iter_on_ref.rs:43:35 | -LL | let _ = (&VecDeque::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&VecDeque::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `VecDeque` - --> tests/ui/into_iter_on_ref.rs:30:43 + --> tests/ui/into_iter_on_ref.rs:45:39 | -LL | let _ = (&mut VecDeque::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&mut VecDeque::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `LinkedList` - --> tests/ui/into_iter_on_ref.rs:31:41 + --> tests/ui/into_iter_on_ref.rs:47:37 | -LL | let _ = (&LinkedList::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&LinkedList::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `LinkedList` - --> tests/ui/into_iter_on_ref.rs:32:45 + --> tests/ui/into_iter_on_ref.rs:49:41 | -LL | let _ = (&mut LinkedList::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&mut LinkedList::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashMap` - --> tests/ui/into_iter_on_ref.rs:33:43 + --> tests/ui/into_iter_on_ref.rs:51:39 | -LL | let _ = (&HashMap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - -error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `HashMap` - --> tests/ui/into_iter_on_ref.rs:34:47 - | -LL | let _ = (&mut HashMap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` - -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeSet` - --> tests/ui/into_iter_on_ref.rs:36:39 - | -LL | let _ = (&BTreeSet::::new()).into_iter(); +LL | let _ = (&HashMap::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BinaryHeap` - --> tests/ui/into_iter_on_ref.rs:37:41 +error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `HashMap` + --> tests/ui/into_iter_on_ref.rs:53:43 | -LL | let _ = (&BinaryHeap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&mut HashMap::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeSet` + --> tests/ui/into_iter_on_ref.rs:56:35 + | +LL | let _ = (&BTreeSet::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BinaryHeap` + --> tests/ui/into_iter_on_ref.rs:58:37 + | +LL | let _ = (&BinaryHeap::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashSet` - --> tests/ui/into_iter_on_ref.rs:38:38 + --> tests/ui/into_iter_on_ref.rs:60:34 | -LL | let _ = (&HashSet::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&HashSet::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Path` - --> tests/ui/into_iter_on_ref.rs:39:43 + --> tests/ui/into_iter_on_ref.rs:62:39 | -LL | let _ = std::path::Path::new("12/34").into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = std::path::Path::new("12/34").into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `PathBuf` - --> tests/ui/into_iter_on_ref.rs:40:47 + --> tests/ui/into_iter_on_ref.rs:64:43 | -LL | let _ = std::path::PathBuf::from("12/34").into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = std::path::PathBuf::from("12/34").into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` - --> tests/ui/into_iter_on_ref.rs:42:26 + --> tests/ui/into_iter_on_ref.rs:67:22 | -LL | let _ = (&[1, 2, 3]).into_iter().next(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&[1, 2, 3]).into_iter().next(); + | ^^^^^^^^^ help: call directly: `iter` error: aborting due to 26 previous errors diff --git a/tests/ui/into_iter_without_iter.rs b/tests/ui/into_iter_without_iter.rs index 109259d6975c..368313af6f91 100644 --- a/tests/ui/into_iter_without_iter.rs +++ b/tests/ui/into_iter_without_iter.rs @@ -7,7 +7,7 @@ use std::iter::IntoIterator; pub struct S1; impl<'a> IntoIterator for &'a S1 { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method +//~^ into_iter_without_iter type IntoIter = std::slice::Iter<'a, u8>; type Item = &'a u8; fn into_iter(self) -> Self::IntoIter { @@ -15,7 +15,7 @@ impl<'a> IntoIterator for &'a S1 { } } impl<'a> IntoIterator for &'a mut S1 { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method +//~^ into_iter_without_iter type IntoIter = std::slice::IterMut<'a, u8>; type Item = &'a mut u8; fn into_iter(self) -> Self::IntoIter { @@ -25,7 +25,7 @@ impl<'a> IntoIterator for &'a mut S1 { pub struct S2(T); impl<'a, T> IntoIterator for &'a S2 { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method +//~^ into_iter_without_iter type IntoIter = std::slice::Iter<'a, T>; type Item = &'a T; fn into_iter(self) -> Self::IntoIter { @@ -33,7 +33,7 @@ impl<'a, T> IntoIterator for &'a S2 { } } impl<'a, T> IntoIterator for &'a mut S2 { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method +//~^ into_iter_without_iter type IntoIter = std::slice::IterMut<'a, T>; type Item = &'a mut T; fn into_iter(self) -> Self::IntoIter { @@ -84,7 +84,7 @@ impl<'a, T> IntoIterator for &S4<'a, T> { } impl<'a, T> IntoIterator for &mut S4<'a, T> { - //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method +//~^ into_iter_without_iter type IntoIter = std::slice::IterMut<'a, T>; type Item = &'a mut T; fn into_iter(self) -> Self::IntoIter { @@ -118,6 +118,7 @@ pub struct Issue12037; macro_rules! generate_impl { () => { impl<'a> IntoIterator for &'a Issue12037 { + //~^ into_iter_without_iter type IntoIter = std::slice::Iter<'a, u8>; type Item = &'a u8; fn into_iter(self) -> Self::IntoIter { diff --git a/tests/ui/into_iter_without_iter.stderr b/tests/ui/into_iter_without_iter.stderr index cde1b60c2abc..a033ff645f49 100644 --- a/tests/ui/into_iter_without_iter.stderr +++ b/tests/ui/into_iter_without_iter.stderr @@ -109,9 +109,9 @@ error: `IntoIterator` implemented for a reference type without an `iter` method --> tests/ui/into_iter_without_iter.rs:120:9 | LL | / impl<'a> IntoIterator for &'a Issue12037 { +LL | | LL | | type IntoIter = std::slice::Iter<'a, u8>; LL | | type Item = &'a u8; -LL | | fn into_iter(self) -> Self::IntoIter { ... | LL | | } | |_________^ diff --git a/tests/ui/invalid_null_ptr_usage.fixed b/tests/ui/invalid_null_ptr_usage.fixed index ba225102c984..ce78e89ee829 100644 --- a/tests/ui/invalid_null_ptr_usage.fixed +++ b/tests/ui/invalid_null_ptr_usage.fixed @@ -1,44 +1,66 @@ fn main() { unsafe { let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage std::ptr::copy::(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage std::ptr::copy::(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage std::ptr::copy_nonoverlapping::(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage std::ptr::copy_nonoverlapping::(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage struct A; // zero sized struct assert_eq!(std::mem::size_of::(), 0); let _a: A = std::ptr::read(std::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read(std::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read_unaligned(std::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read_unaligned(std::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read_volatile(std::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read_volatile(std::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::replace(std::ptr::NonNull::dangling().as_ptr(), A); + //~^ invalid_null_ptr_usage let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0); std::ptr::swap::(std::ptr::NonNull::dangling().as_ptr(), &mut A); + //~^ invalid_null_ptr_usage std::ptr::swap::(&mut A, std::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage std::ptr::swap_nonoverlapping::(std::ptr::NonNull::dangling().as_ptr(), &mut A, 0); + //~^ invalid_null_ptr_usage std::ptr::swap_nonoverlapping::(&mut A, std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage std::ptr::write(std::ptr::NonNull::dangling().as_ptr(), A); + //~^ invalid_null_ptr_usage std::ptr::write_unaligned(std::ptr::NonNull::dangling().as_ptr(), A); + //~^ invalid_null_ptr_usage std::ptr::write_volatile(std::ptr::NonNull::dangling().as_ptr(), A); + //~^ invalid_null_ptr_usage std::ptr::write_bytes::(std::ptr::NonNull::dangling().as_ptr(), 42, 0); + //~^ invalid_null_ptr_usage } } diff --git a/tests/ui/invalid_null_ptr_usage.rs b/tests/ui/invalid_null_ptr_usage.rs index 480b6642a3e3..361865fbd960 100644 --- a/tests/ui/invalid_null_ptr_usage.rs +++ b/tests/ui/invalid_null_ptr_usage.rs @@ -1,44 +1,66 @@ fn main() { unsafe { let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null(), 0); + //~^ invalid_null_ptr_usage let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage std::ptr::copy::(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage std::ptr::copy::(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage std::ptr::copy_nonoverlapping::(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage std::ptr::copy_nonoverlapping::(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage struct A; // zero sized struct assert_eq!(std::mem::size_of::(), 0); let _a: A = std::ptr::read(std::ptr::null()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read(std::ptr::null_mut()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read_unaligned(std::ptr::null()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read_unaligned(std::ptr::null_mut()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read_volatile(std::ptr::null()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::read_volatile(std::ptr::null_mut()); + //~^ invalid_null_ptr_usage let _a: A = std::ptr::replace(std::ptr::null_mut(), A); + //~^ invalid_null_ptr_usage let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0); std::ptr::swap::(std::ptr::null_mut(), &mut A); + //~^ invalid_null_ptr_usage std::ptr::swap::(&mut A, std::ptr::null_mut()); + //~^ invalid_null_ptr_usage std::ptr::swap_nonoverlapping::(std::ptr::null_mut(), &mut A, 0); + //~^ invalid_null_ptr_usage std::ptr::swap_nonoverlapping::(&mut A, std::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage std::ptr::write(std::ptr::null_mut(), A); + //~^ invalid_null_ptr_usage std::ptr::write_unaligned(std::ptr::null_mut(), A); + //~^ invalid_null_ptr_usage std::ptr::write_volatile(std::ptr::null_mut(), A); + //~^ invalid_null_ptr_usage std::ptr::write_bytes::(std::ptr::null_mut(), 42, 0); + //~^ invalid_null_ptr_usage } } diff --git a/tests/ui/invalid_null_ptr_usage.stderr b/tests/ui/invalid_null_ptr_usage.stderr index 613a2cc36885..3f9d15b90401 100644 --- a/tests/ui/invalid_null_ptr_usage.stderr +++ b/tests/ui/invalid_null_ptr_usage.stderr @@ -7,127 +7,127 @@ LL | let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null(), = note: `#[deny(clippy::invalid_null_ptr_usage)]` on by default error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:4:59 + --> tests/ui/invalid_null_ptr_usage.rs:5:59 | LL | let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:6:63 + --> tests/ui/invalid_null_ptr_usage.rs:8:63 | LL | let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:8:33 + --> tests/ui/invalid_null_ptr_usage.rs:11:33 | LL | std::ptr::copy::(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0); | ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:9:73 + --> tests/ui/invalid_null_ptr_usage.rs:13:73 | LL | std::ptr::copy::(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:11:48 + --> tests/ui/invalid_null_ptr_usage.rs:16:48 | LL | std::ptr::copy_nonoverlapping::(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0); | ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:12:88 + --> tests/ui/invalid_null_ptr_usage.rs:18:88 | LL | std::ptr::copy_nonoverlapping::(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:17:36 + --> tests/ui/invalid_null_ptr_usage.rs:24:36 | LL | let _a: A = std::ptr::read(std::ptr::null()); | ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:18:36 + --> tests/ui/invalid_null_ptr_usage.rs:26:36 | LL | let _a: A = std::ptr::read(std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:20:46 + --> tests/ui/invalid_null_ptr_usage.rs:29:46 | LL | let _a: A = std::ptr::read_unaligned(std::ptr::null()); | ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:21:46 + --> tests/ui/invalid_null_ptr_usage.rs:31:46 | LL | let _a: A = std::ptr::read_unaligned(std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:23:45 + --> tests/ui/invalid_null_ptr_usage.rs:34:45 | LL | let _a: A = std::ptr::read_volatile(std::ptr::null()); | ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:24:45 + --> tests/ui/invalid_null_ptr_usage.rs:36:45 | LL | let _a: A = std::ptr::read_volatile(std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:26:39 + --> tests/ui/invalid_null_ptr_usage.rs:39:39 | LL | let _a: A = std::ptr::replace(std::ptr::null_mut(), A); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:30:29 + --> tests/ui/invalid_null_ptr_usage.rs:44:29 | LL | std::ptr::swap::(std::ptr::null_mut(), &mut A); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:31:37 + --> tests/ui/invalid_null_ptr_usage.rs:46:37 | LL | std::ptr::swap::(&mut A, std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:33:44 + --> tests/ui/invalid_null_ptr_usage.rs:49:44 | LL | std::ptr::swap_nonoverlapping::(std::ptr::null_mut(), &mut A, 0); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:34:52 + --> tests/ui/invalid_null_ptr_usage.rs:51:52 | LL | std::ptr::swap_nonoverlapping::(&mut A, std::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:36:25 + --> tests/ui/invalid_null_ptr_usage.rs:54:25 | LL | std::ptr::write(std::ptr::null_mut(), A); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:38:35 + --> tests/ui/invalid_null_ptr_usage.rs:57:35 | LL | std::ptr::write_unaligned(std::ptr::null_mut(), A); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:40:34 + --> tests/ui/invalid_null_ptr_usage.rs:60:34 | LL | std::ptr::write_volatile(std::ptr::null_mut(), A); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage.rs:42:40 + --> tests/ui/invalid_null_ptr_usage.rs:63:40 | LL | std::ptr::write_bytes::(std::ptr::null_mut(), 42, 0); | ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()` diff --git a/tests/ui/invalid_null_ptr_usage_no_std.fixed b/tests/ui/invalid_null_ptr_usage_no_std.fixed index 2bbfe7274242..df7ab166187d 100644 --- a/tests/ui/invalid_null_ptr_usage_no_std.fixed +++ b/tests/ui/invalid_null_ptr_usage_no_std.fixed @@ -14,44 +14,66 @@ fn panic(info: &PanicInfo) -> ! { fn main() { unsafe { let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage let _slice: &[usize] = core::slice::from_raw_parts_mut(core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage core::ptr::copy::(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage core::ptr::copy::(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage core::ptr::copy_nonoverlapping::(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage core::ptr::copy_nonoverlapping::(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage struct A; // zero sized struct assert_eq!(core::mem::size_of::(), 0); let _a: A = core::ptr::read(core::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read(core::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read_unaligned(core::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read_unaligned(core::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read_volatile(core::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read_volatile(core::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::replace(core::ptr::NonNull::dangling().as_ptr(), A); + //~^ invalid_null_ptr_usage let _slice: *const [usize] = core::ptr::slice_from_raw_parts(core::ptr::null_mut(), 0); // shouldn't lint let _slice: *const [usize] = core::ptr::slice_from_raw_parts_mut(core::ptr::null_mut(), 0); core::ptr::swap::(core::ptr::NonNull::dangling().as_ptr(), &mut A); + //~^ invalid_null_ptr_usage core::ptr::swap::(&mut A, core::ptr::NonNull::dangling().as_ptr()); + //~^ invalid_null_ptr_usage core::ptr::swap_nonoverlapping::(core::ptr::NonNull::dangling().as_ptr(), &mut A, 0); + //~^ invalid_null_ptr_usage core::ptr::swap_nonoverlapping::(&mut A, core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage core::ptr::write(core::ptr::NonNull::dangling().as_ptr(), A); + //~^ invalid_null_ptr_usage core::ptr::write_unaligned(core::ptr::NonNull::dangling().as_ptr(), A); + //~^ invalid_null_ptr_usage core::ptr::write_volatile(core::ptr::NonNull::dangling().as_ptr(), A); + //~^ invalid_null_ptr_usage core::ptr::write_bytes::(core::ptr::NonNull::dangling().as_ptr(), 42, 0); + //~^ invalid_null_ptr_usage } } diff --git a/tests/ui/invalid_null_ptr_usage_no_std.rs b/tests/ui/invalid_null_ptr_usage_no_std.rs index cbce44f7c0d9..38ddfff05535 100644 --- a/tests/ui/invalid_null_ptr_usage_no_std.rs +++ b/tests/ui/invalid_null_ptr_usage_no_std.rs @@ -14,44 +14,66 @@ fn panic(info: &PanicInfo) -> ! { fn main() { unsafe { let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null(), 0); + //~^ invalid_null_ptr_usage let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage let _slice: &[usize] = core::slice::from_raw_parts_mut(core::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage core::ptr::copy::(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage core::ptr::copy::(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage core::ptr::copy_nonoverlapping::(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0); + //~^ invalid_null_ptr_usage core::ptr::copy_nonoverlapping::(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage struct A; // zero sized struct assert_eq!(core::mem::size_of::(), 0); let _a: A = core::ptr::read(core::ptr::null()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read(core::ptr::null_mut()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read_unaligned(core::ptr::null()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read_unaligned(core::ptr::null_mut()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read_volatile(core::ptr::null()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::read_volatile(core::ptr::null_mut()); + //~^ invalid_null_ptr_usage let _a: A = core::ptr::replace(core::ptr::null_mut(), A); + //~^ invalid_null_ptr_usage let _slice: *const [usize] = core::ptr::slice_from_raw_parts(core::ptr::null_mut(), 0); // shouldn't lint let _slice: *const [usize] = core::ptr::slice_from_raw_parts_mut(core::ptr::null_mut(), 0); core::ptr::swap::(core::ptr::null_mut(), &mut A); + //~^ invalid_null_ptr_usage core::ptr::swap::(&mut A, core::ptr::null_mut()); + //~^ invalid_null_ptr_usage core::ptr::swap_nonoverlapping::(core::ptr::null_mut(), &mut A, 0); + //~^ invalid_null_ptr_usage core::ptr::swap_nonoverlapping::(&mut A, core::ptr::null_mut(), 0); + //~^ invalid_null_ptr_usage core::ptr::write(core::ptr::null_mut(), A); + //~^ invalid_null_ptr_usage core::ptr::write_unaligned(core::ptr::null_mut(), A); + //~^ invalid_null_ptr_usage core::ptr::write_volatile(core::ptr::null_mut(), A); + //~^ invalid_null_ptr_usage core::ptr::write_bytes::(core::ptr::null_mut(), 42, 0); + //~^ invalid_null_ptr_usage } } diff --git a/tests/ui/invalid_null_ptr_usage_no_std.stderr b/tests/ui/invalid_null_ptr_usage_no_std.stderr index df0d40e9e072..b5dd21ce6248 100644 --- a/tests/ui/invalid_null_ptr_usage_no_std.stderr +++ b/tests/ui/invalid_null_ptr_usage_no_std.stderr @@ -7,127 +7,127 @@ LL | let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null( = note: `#[deny(clippy::invalid_null_ptr_usage)]` on by default error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:17:60 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:18:60 | LL | let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:19:64 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:21:64 | LL | let _slice: &[usize] = core::slice::from_raw_parts_mut(core::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:21:34 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:24:34 | LL | core::ptr::copy::(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0); | ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:22:75 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:26:75 | LL | core::ptr::copy::(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:24:49 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:29:49 | LL | core::ptr::copy_nonoverlapping::(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0); | ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:25:90 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:31:90 | LL | core::ptr::copy_nonoverlapping::(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:30:37 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:37:37 | LL | let _a: A = core::ptr::read(core::ptr::null()); | ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:31:37 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:39:37 | LL | let _a: A = core::ptr::read(core::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:33:47 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:42:47 | LL | let _a: A = core::ptr::read_unaligned(core::ptr::null()); | ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:34:47 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:44:47 | LL | let _a: A = core::ptr::read_unaligned(core::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:36:46 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:47:46 | LL | let _a: A = core::ptr::read_volatile(core::ptr::null()); | ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:37:46 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:49:46 | LL | let _a: A = core::ptr::read_volatile(core::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:39:40 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:52:40 | LL | let _a: A = core::ptr::replace(core::ptr::null_mut(), A); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:43:30 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:57:30 | LL | core::ptr::swap::(core::ptr::null_mut(), &mut A); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:44:38 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:59:38 | LL | core::ptr::swap::(&mut A, core::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:46:45 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:62:45 | LL | core::ptr::swap_nonoverlapping::(core::ptr::null_mut(), &mut A, 0); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:47:53 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:64:53 | LL | core::ptr::swap_nonoverlapping::(&mut A, core::ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:49:26 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:67:26 | LL | core::ptr::write(core::ptr::null_mut(), A); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:51:36 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:70:36 | LL | core::ptr::write_unaligned(core::ptr::null_mut(), A); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:53:35 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:73:35 | LL | core::ptr::write_volatile(core::ptr::null_mut(), A); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` error: pointer must be non-null - --> tests/ui/invalid_null_ptr_usage_no_std.rs:55:41 + --> tests/ui/invalid_null_ptr_usage_no_std.rs:76:41 | LL | core::ptr::write_bytes::(core::ptr::null_mut(), 42, 0); | ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()` diff --git a/tests/ui/invalid_upcast_comparisons.rs b/tests/ui/invalid_upcast_comparisons.rs index a9db15f20973..bb2166862efc 100644 --- a/tests/ui/invalid_upcast_comparisons.rs +++ b/tests/ui/invalid_upcast_comparisons.rs @@ -19,61 +19,85 @@ fn main() { // always false, since no u8 can be > 300 (u8 as u32) > 300; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is - //~| NOTE: `-D clippy::invalid-upcast-comparisons` implied by `-D warnings` + //~^ invalid_upcast_comparisons + + (u8 as i32) > 300; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + (u8 as u32) == 300; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + (u8 as i32) == 300; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 300 < (u8 as u32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 300 < (u8 as i32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 300 == (u8 as u32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 300 == (u8 as i32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + // inverted of the above (u8 as u32) <= 300; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + (u8 as i32) <= 300; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + (u8 as u32) != 300; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + (u8 as i32) != 300; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 300 >= (u8 as u32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 300 >= (u8 as i32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 300 != (u8 as u32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 300 != (u8 as i32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + // always false, since u8 -> i32 doesn't wrap (u8 as i32) < 0; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + -5 != (u8 as i32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + // inverted of the above (u8 as i32) >= 0; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + -5 == (u8 as i32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + // always false, since no u8 can be 1337 1337 == (u8 as i32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 1337 == (u8 as u32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + // inverted of the above 1337 != (u8 as i32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + 1337 != (u8 as u32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + // Those are Ok: (u8 as u32) > 20; @@ -88,9 +112,11 @@ fn main() { (u8 as i8) == -1; (u8 as i8) != -1; (u8 as i32) > -1; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + (u8 as i32) < -1; - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + (u32 as i32) < -5; (u32 as i32) < 10; @@ -107,7 +133,8 @@ fn main() { -5 > (u32 as i32); -5 >= (u8 as i32); - //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is + //~^ invalid_upcast_comparisons + -5 == (u32 as i32); } diff --git a/tests/ui/invalid_upcast_comparisons.stderr b/tests/ui/invalid_upcast_comparisons.stderr index b1fbe2951577..911022c005c9 100644 --- a/tests/ui/invalid_upcast_comparisons.stderr +++ b/tests/ui/invalid_upcast_comparisons.stderr @@ -8,157 +8,157 @@ LL | (u8 as u32) > 300; = help: to override `-D warnings` add `#[allow(clippy::invalid_upcast_comparisons)]` error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:24:5 + --> tests/ui/invalid_upcast_comparisons.rs:25:5 | LL | (u8 as i32) > 300; | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:26:5 + --> tests/ui/invalid_upcast_comparisons.rs:28:5 | LL | (u8 as u32) == 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:28:5 + --> tests/ui/invalid_upcast_comparisons.rs:31:5 | LL | (u8 as i32) == 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:30:5 + --> tests/ui/invalid_upcast_comparisons.rs:34:5 | LL | 300 < (u8 as u32); | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:32:5 + --> tests/ui/invalid_upcast_comparisons.rs:37:5 | LL | 300 < (u8 as i32); | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:34:5 + --> tests/ui/invalid_upcast_comparisons.rs:40:5 | LL | 300 == (u8 as u32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:36:5 + --> tests/ui/invalid_upcast_comparisons.rs:43:5 | LL | 300 == (u8 as i32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:39:5 + --> tests/ui/invalid_upcast_comparisons.rs:47:5 | LL | (u8 as u32) <= 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:41:5 + --> tests/ui/invalid_upcast_comparisons.rs:50:5 | LL | (u8 as i32) <= 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:43:5 + --> tests/ui/invalid_upcast_comparisons.rs:53:5 | LL | (u8 as u32) != 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:45:5 + --> tests/ui/invalid_upcast_comparisons.rs:56:5 | LL | (u8 as i32) != 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:47:5 + --> tests/ui/invalid_upcast_comparisons.rs:59:5 | LL | 300 >= (u8 as u32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:49:5 + --> tests/ui/invalid_upcast_comparisons.rs:62:5 | LL | 300 >= (u8 as i32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:51:5 + --> tests/ui/invalid_upcast_comparisons.rs:65:5 | LL | 300 != (u8 as u32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:53:5 + --> tests/ui/invalid_upcast_comparisons.rs:68:5 | LL | 300 != (u8 as i32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:57:5 + --> tests/ui/invalid_upcast_comparisons.rs:73:5 | LL | (u8 as i32) < 0; | ^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:59:5 + --> tests/ui/invalid_upcast_comparisons.rs:76:5 | LL | -5 != (u8 as i32); | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:62:5 + --> tests/ui/invalid_upcast_comparisons.rs:80:5 | LL | (u8 as i32) >= 0; | ^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:64:5 + --> tests/ui/invalid_upcast_comparisons.rs:83:5 | LL | -5 == (u8 as i32); | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:68:5 + --> tests/ui/invalid_upcast_comparisons.rs:88:5 | LL | 1337 == (u8 as i32); | ^^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:70:5 + --> tests/ui/invalid_upcast_comparisons.rs:91:5 | LL | 1337 == (u8 as u32); | ^^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:73:5 + --> tests/ui/invalid_upcast_comparisons.rs:95:5 | LL | 1337 != (u8 as i32); | ^^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:75:5 + --> tests/ui/invalid_upcast_comparisons.rs:98:5 | LL | 1337 != (u8 as u32); | ^^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:90:5 + --> tests/ui/invalid_upcast_comparisons.rs:114:5 | LL | (u8 as i32) > -1; | ^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:92:5 + --> tests/ui/invalid_upcast_comparisons.rs:117:5 | LL | (u8 as i32) < -1; | ^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:109:5 + --> tests/ui/invalid_upcast_comparisons.rs:135:5 | LL | -5 >= (u8 as i32); | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/is_digit_ascii_radix.fixed b/tests/ui/is_digit_ascii_radix.fixed index 62953ff74cfc..b0509ed2a751 100644 --- a/tests/ui/is_digit_ascii_radix.fixed +++ b/tests/ui/is_digit_ascii_radix.fixed @@ -7,8 +7,11 @@ fn main() { // Should trigger the lint. let _ = c.is_ascii_digit(); + //~^ is_digit_ascii_radix let _ = c.is_ascii_hexdigit(); + //~^ is_digit_ascii_radix let _ = c.is_ascii_hexdigit(); + //~^ is_digit_ascii_radix // Should not trigger the lint. let _ = c.is_digit(11); diff --git a/tests/ui/is_digit_ascii_radix.rs b/tests/ui/is_digit_ascii_radix.rs index 229f530f611d..68d4b56063b5 100644 --- a/tests/ui/is_digit_ascii_radix.rs +++ b/tests/ui/is_digit_ascii_radix.rs @@ -7,8 +7,11 @@ fn main() { // Should trigger the lint. let _ = c.is_digit(10); + //~^ is_digit_ascii_radix let _ = c.is_digit(16); + //~^ is_digit_ascii_radix let _ = c.is_digit(0x10); + //~^ is_digit_ascii_radix // Should not trigger the lint. let _ = c.is_digit(11); diff --git a/tests/ui/is_digit_ascii_radix.stderr b/tests/ui/is_digit_ascii_radix.stderr index f26183ddab84..b6e53eb5829f 100644 --- a/tests/ui/is_digit_ascii_radix.stderr +++ b/tests/ui/is_digit_ascii_radix.stderr @@ -8,13 +8,13 @@ LL | let _ = c.is_digit(10); = help: to override `-D warnings` add `#[allow(clippy::is_digit_ascii_radix)]` error: use of `char::is_digit` with literal radix of 16 - --> tests/ui/is_digit_ascii_radix.rs:10:13 + --> tests/ui/is_digit_ascii_radix.rs:11:13 | LL | let _ = c.is_digit(16); | ^^^^^^^^^^^^^^ help: try: `c.is_ascii_hexdigit()` error: use of `char::is_digit` with literal radix of 16 - --> tests/ui/is_digit_ascii_radix.rs:11:13 + --> tests/ui/is_digit_ascii_radix.rs:13:13 | LL | let _ = c.is_digit(0x10); | ^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_hexdigit()` diff --git a/tests/ui/issue-111399.rs b/tests/ui/issue-111399.rs index b65e6c7261a5..2a6436b4b4eb 100644 --- a/tests/ui/issue-111399.rs +++ b/tests/ui/issue-111399.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(inherent_associated_types)] #![allow(incomplete_features)] diff --git a/tests/ui/issue-7447.rs b/tests/ui/issue-7447.rs index 7e7ef209d485..25ace345ad14 100644 --- a/tests/ui/issue-7447.rs +++ b/tests/ui/issue-7447.rs @@ -24,8 +24,10 @@ pub struct ByteView<'a> { fn main() { byte_view(panic!()); - //~^ ERROR: sub-expression diverges - //~| NOTE: `-D clippy::diverging-sub-expression` implied by `-D warnings` + //~^ diverging_sub_expression + + group_entries(panic!()); - //~^ ERROR: sub-expression diverges + //~^ diverging_sub_expression + } diff --git a/tests/ui/issue-7447.stderr b/tests/ui/issue-7447.stderr index 5e28c1423840..1ba53631b52d 100644 --- a/tests/ui/issue-7447.stderr +++ b/tests/ui/issue-7447.stderr @@ -9,7 +9,7 @@ LL | byte_view(panic!()); = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: sub-expression diverges - --> tests/ui/issue-7447.rs:29:19 + --> tests/ui/issue-7447.rs:30:19 | LL | group_entries(panic!()); | ^^^^^^^^ diff --git a/tests/ui/issue_2356.fixed b/tests/ui/issue_2356.fixed index 892aa4e34216..c96d3c1a24f9 100644 --- a/tests/ui/issue_2356.fixed +++ b/tests/ui/issue_2356.fixed @@ -15,6 +15,7 @@ impl Foo { fn foo2>(mut it: I) { for e in it { + //~^ while_let_on_iterator println!("{:?}", e); } } diff --git a/tests/ui/issue_2356.rs b/tests/ui/issue_2356.rs index da0eead15b39..a4040cb37ced 100644 --- a/tests/ui/issue_2356.rs +++ b/tests/ui/issue_2356.rs @@ -15,6 +15,7 @@ impl Foo { fn foo2>(mut it: I) { while let Some(e) = it.next() { + //~^ while_let_on_iterator println!("{:?}", e); } } diff --git a/tests/ui/issue_4266.rs b/tests/ui/issue_4266.rs index 23453207b4e5..aabf72a93ce2 100644 --- a/tests/ui/issue_4266.rs +++ b/tests/ui/issue_4266.rs @@ -2,13 +2,15 @@ #![allow(clippy::uninlined_format_args)] async fn sink1<'a>(_: &'a str) {} // lint -//~^ ERROR: the following explicit lifetimes could be elided: 'a -//~| NOTE: `-D clippy::needless-lifetimes` implied by `-D warnings` +//~^ needless_lifetimes + + async fn sink1_elided(_: &str) {} // ok // lint async fn one_to_one<'a>(s: &'a str) -> &'a str { - //~^ ERROR: the following explicit lifetimes could be elided: 'a +//~^ needless_lifetimes + s } @@ -29,7 +31,8 @@ struct Foo; impl Foo { // ok pub async fn new(&mut self) -> Self { - //~^ ERROR: methods called `new` usually take no `self` + //~^ wrong_self_convention + Foo {} } } diff --git a/tests/ui/issue_4266.stderr b/tests/ui/issue_4266.stderr index 63c568a153b2..ce0588521810 100644 --- a/tests/ui/issue_4266.stderr +++ b/tests/ui/issue_4266.stderr @@ -8,13 +8,13 @@ LL | async fn sink1<'a>(_: &'a str) {} // lint = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]` error: the following explicit lifetimes could be elided: 'a - --> tests/ui/issue_4266.rs:10:21 + --> tests/ui/issue_4266.rs:11:21 | LL | async fn one_to_one<'a>(s: &'a str) -> &'a str { | ^^ ^^ ^^ error: methods called `new` usually take no `self` - --> tests/ui/issue_4266.rs:31:22 + --> tests/ui/issue_4266.rs:33:22 | LL | pub async fn new(&mut self) -> Self { | ^^^^^^^^^ diff --git a/tests/ui/items_after_statement.rs b/tests/ui/items_after_statement.rs index 943e7c116760..db3583464e9a 100644 --- a/tests/ui/items_after_statement.rs +++ b/tests/ui/items_after_statement.rs @@ -11,8 +11,9 @@ fn ok() { fn last() { foo(); fn foo() { - //~^ ERROR: adding items after statements is confusing, since items exist from the sta - //~| NOTE: `-D clippy::items-after-statements` implied by `-D warnings` + //~^ items_after_statements + + println!("foo"); } } @@ -20,7 +21,8 @@ fn last() { fn main() { foo(); fn foo() { - //~^ ERROR: adding items after statements is confusing, since items exist from the sta + //~^ items_after_statements + println!("foo"); } foo(); @@ -34,6 +36,7 @@ fn mac() { () => {{ a = 6; fn say_something() { + //~^ items_after_statements println!("something"); } }}; diff --git a/tests/ui/items_after_statement.stderr b/tests/ui/items_after_statement.stderr index 0f1989d4c9fc..d6186f1305a0 100644 --- a/tests/ui/items_after_statement.stderr +++ b/tests/ui/items_after_statement.stderr @@ -2,9 +2,7 @@ error: adding items after statements is confusing, since items exist from the st --> tests/ui/items_after_statement.rs:13:5 | LL | / fn foo() { -LL | | -LL | | -LL | | println!("foo"); +... | LL | | } | |_____^ | @@ -12,18 +10,20 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::items_after_statements)]` error: adding items after statements is confusing, since items exist from the start of the scope - --> tests/ui/items_after_statement.rs:22:5 + --> tests/ui/items_after_statement.rs:23:5 | LL | / fn foo() { LL | | +LL | | LL | | println!("foo"); LL | | } | |_____^ error: adding items after statements is confusing, since items exist from the start of the scope - --> tests/ui/items_after_statement.rs:36:13 + --> tests/ui/items_after_statement.rs:38:13 | LL | / fn say_something() { +LL | | LL | | println!("something"); LL | | } | |_____________^ diff --git a/tests/ui/items_after_test_module/after_proc_macros.rs b/tests/ui/items_after_test_module/after_proc_macros.rs index d9c0aef88c8c..54a04988cda0 100644 --- a/tests/ui/items_after_test_module/after_proc_macros.rs +++ b/tests/ui/items_after_test_module/after_proc_macros.rs @@ -1,3 +1,4 @@ +//@ check-pass //@aux-build:../auxiliary/proc_macros.rs extern crate proc_macros; diff --git a/tests/ui/items_after_test_module/imported_module.rs b/tests/ui/items_after_test_module/imported_module.rs index 6a757aef48e7..d756be5b433e 100644 --- a/tests/ui/items_after_test_module/imported_module.rs +++ b/tests/ui/items_after_test_module/imported_module.rs @@ -1,3 +1,4 @@ +//@ check-pass //@compile-flags: --test #![allow(unused)] #![warn(clippy::items_after_test_module)] diff --git a/tests/ui/items_after_test_module/in_submodule.rs b/tests/ui/items_after_test_module/in_submodule.rs index 7132e71764eb..6ca100c07f96 100644 --- a/tests/ui/items_after_test_module/in_submodule.rs +++ b/tests/ui/items_after_test_module/in_submodule.rs @@ -1,3 +1,4 @@ +//@error-in-other-file: #[path = "auxiliary/submodule.rs"] mod submodule; diff --git a/tests/ui/items_after_test_module/multiple_modules.rs b/tests/ui/items_after_test_module/multiple_modules.rs index 8ab9e8200f18..8618710654a5 100644 --- a/tests/ui/items_after_test_module/multiple_modules.rs +++ b/tests/ui/items_after_test_module/multiple_modules.rs @@ -1,3 +1,5 @@ +//@ check-pass + #[cfg(test)] mod tests { #[test] diff --git a/tests/ui/items_after_test_module/root_module.fixed b/tests/ui/items_after_test_module/root_module.fixed index d444100a76b9..25eff3d38f76 100644 --- a/tests/ui/items_after_test_module/root_module.fixed +++ b/tests/ui/items_after_test_module/root_module.fixed @@ -17,6 +17,7 @@ macro_rules! should_lint { #[allow(clippy::allow_attributes)] #[cfg(test)] mod tests { +//~^ items_after_test_module #[test] fn hi() {} } diff --git a/tests/ui/items_after_test_module/root_module.rs b/tests/ui/items_after_test_module/root_module.rs index 57da01639cca..94afffd92de5 100644 --- a/tests/ui/items_after_test_module/root_module.rs +++ b/tests/ui/items_after_test_module/root_module.rs @@ -10,6 +10,7 @@ fn should_not_lint() {} #[allow(clippy::allow_attributes)] #[cfg(test)] mod tests { +//~^ items_after_test_module #[test] fn hi() {} } diff --git a/tests/ui/iter_cloned_collect.fixed b/tests/ui/iter_cloned_collect.fixed index 1d623642a713..e9fb44e89598 100644 --- a/tests/ui/iter_cloned_collect.fixed +++ b/tests/ui/iter_cloned_collect.fixed @@ -6,11 +6,13 @@ use std::collections::{HashSet, VecDeque}; fn main() { let v = [1, 2, 3, 4, 5]; let v2: Vec = v.to_vec(); + //~^ iter_cloned_collect let v3: HashSet = v.iter().cloned().collect(); let v4: VecDeque = v.iter().cloned().collect(); // Handle macro expansion in suggestion let _: Vec = vec![1, 2, 3].to_vec(); + //~^ iter_cloned_collect // Issue #3704 unsafe { @@ -21,7 +23,9 @@ fn main() { // Issue #6808 let arr: [u8; 64] = [0; 64]; let _: Vec<_> = arr.to_vec(); + //~^ iter_cloned_collect // Issue #6703 let _: Vec = v.to_vec(); + //~^ iter_cloned_collect } diff --git a/tests/ui/iter_cloned_collect.rs b/tests/ui/iter_cloned_collect.rs index 091bd9eaf081..c9b8abcc9a0d 100644 --- a/tests/ui/iter_cloned_collect.rs +++ b/tests/ui/iter_cloned_collect.rs @@ -6,16 +6,19 @@ use std::collections::{HashSet, VecDeque}; fn main() { let v = [1, 2, 3, 4, 5]; let v2: Vec = v.iter().cloned().collect(); + //~^ iter_cloned_collect let v3: HashSet = v.iter().cloned().collect(); let v4: VecDeque = v.iter().cloned().collect(); // Handle macro expansion in suggestion let _: Vec = vec![1, 2, 3].iter().cloned().collect(); + //~^ iter_cloned_collect // Issue #3704 unsafe { let _: Vec = std::ffi::CStr::from_ptr(std::ptr::null()) .to_bytes() + //~^ iter_cloned_collect .iter() .cloned() .collect(); @@ -24,7 +27,9 @@ fn main() { // Issue #6808 let arr: [u8; 64] = [0; 64]; let _: Vec<_> = arr.iter().cloned().collect(); + //~^ iter_cloned_collect // Issue #6703 let _: Vec = v.iter().copied().collect(); + //~^ iter_cloned_collect } diff --git a/tests/ui/iter_cloned_collect.stderr b/tests/ui/iter_cloned_collect.stderr index e8d82ec2c1b3..119698cb4634 100644 --- a/tests/ui/iter_cloned_collect.stderr +++ b/tests/ui/iter_cloned_collect.stderr @@ -8,29 +8,30 @@ LL | let v2: Vec = v.iter().cloned().collect(); = help: to override `-D warnings` add `#[allow(clippy::iter_cloned_collect)]` error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable - --> tests/ui/iter_cloned_collect.rs:13:38 + --> tests/ui/iter_cloned_collect.rs:14:38 | LL | let _: Vec = vec![1, 2, 3].iter().cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()` error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable - --> tests/ui/iter_cloned_collect.rs:18:24 + --> tests/ui/iter_cloned_collect.rs:20:24 | LL | .to_bytes() | ________________________^ +LL | | LL | | .iter() LL | | .cloned() LL | | .collect(); | |______________________^ help: try: `.to_vec()` error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable - --> tests/ui/iter_cloned_collect.rs:26:24 + --> tests/ui/iter_cloned_collect.rs:29:24 | LL | let _: Vec<_> = arr.iter().cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()` error: called `iter().copied().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable - --> tests/ui/iter_cloned_collect.rs:29:26 + --> tests/ui/iter_cloned_collect.rs:33:26 | LL | let _: Vec = v.iter().copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()` diff --git a/tests/ui/iter_count.fixed b/tests/ui/iter_count.fixed index 75c007bb0c99..2e187e5bfa75 100644 --- a/tests/ui/iter_count.fixed +++ b/tests/ui/iter_count.fixed @@ -52,32 +52,57 @@ fn main() { binary_heap.push(1); &vec[..].len(); + //~^ iter_count vec.len(); + //~^ iter_count boxed_slice.len(); + //~^ iter_count vec_deque.len(); + //~^ iter_count hash_set.len(); + //~^ iter_count hash_map.len(); + //~^ iter_count b_tree_map.len(); + //~^ iter_count b_tree_set.len(); + //~^ iter_count linked_list.len(); + //~^ iter_count binary_heap.len(); + //~^ iter_count vec.len(); + //~^ iter_count &vec[..].len(); + //~^ iter_count vec_deque.len(); + //~^ iter_count hash_map.len(); + //~^ iter_count b_tree_map.len(); + //~^ iter_count linked_list.len(); + //~^ iter_count &vec[..].len(); + //~^ iter_count vec.len(); + //~^ iter_count vec_deque.len(); + //~^ iter_count hash_set.len(); + //~^ iter_count hash_map.len(); + //~^ iter_count b_tree_map.len(); + //~^ iter_count b_tree_set.len(); + //~^ iter_count linked_list.len(); + //~^ iter_count binary_heap.len(); + //~^ iter_count // Make sure we don't lint for non-relevant types. let false_positive = HasIter; diff --git a/tests/ui/iter_count.rs b/tests/ui/iter_count.rs index cd8207b2c5dc..e941892136ec 100644 --- a/tests/ui/iter_count.rs +++ b/tests/ui/iter_count.rs @@ -52,32 +52,57 @@ fn main() { binary_heap.push(1); &vec[..].iter().count(); + //~^ iter_count vec.iter().count(); + //~^ iter_count boxed_slice.iter().count(); + //~^ iter_count vec_deque.iter().count(); + //~^ iter_count hash_set.iter().count(); + //~^ iter_count hash_map.iter().count(); + //~^ iter_count b_tree_map.iter().count(); + //~^ iter_count b_tree_set.iter().count(); + //~^ iter_count linked_list.iter().count(); + //~^ iter_count binary_heap.iter().count(); + //~^ iter_count vec.iter_mut().count(); + //~^ iter_count &vec[..].iter_mut().count(); + //~^ iter_count vec_deque.iter_mut().count(); + //~^ iter_count hash_map.iter_mut().count(); + //~^ iter_count b_tree_map.iter_mut().count(); + //~^ iter_count linked_list.iter_mut().count(); + //~^ iter_count &vec[..].into_iter().count(); + //~^ iter_count vec.into_iter().count(); + //~^ iter_count vec_deque.into_iter().count(); + //~^ iter_count hash_set.into_iter().count(); + //~^ iter_count hash_map.into_iter().count(); + //~^ iter_count b_tree_map.into_iter().count(); + //~^ iter_count b_tree_set.into_iter().count(); + //~^ iter_count linked_list.into_iter().count(); + //~^ iter_count binary_heap.into_iter().count(); + //~^ iter_count // Make sure we don't lint for non-relevant types. let false_positive = HasIter; diff --git a/tests/ui/iter_count.stderr b/tests/ui/iter_count.stderr index b703310731f3..a5ccefd9048d 100644 --- a/tests/ui/iter_count.stderr +++ b/tests/ui/iter_count.stderr @@ -8,145 +8,145 @@ LL | &vec[..].iter().count(); = help: to override `-D warnings` add `#[allow(clippy::iter_count)]` error: called `.iter().count()` on a `Vec` - --> tests/ui/iter_count.rs:55:5 + --> tests/ui/iter_count.rs:56:5 | LL | vec.iter().count(); | ^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.iter().count()` on a `slice` - --> tests/ui/iter_count.rs:56:5 + --> tests/ui/iter_count.rs:58:5 | LL | boxed_slice.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()` error: called `.iter().count()` on a `VecDeque` - --> tests/ui/iter_count.rs:57:5 + --> tests/ui/iter_count.rs:60:5 | LL | vec_deque.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` error: called `.iter().count()` on a `HashSet` - --> tests/ui/iter_count.rs:58:5 + --> tests/ui/iter_count.rs:62:5 | LL | hash_set.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()` error: called `.iter().count()` on a `HashMap` - --> tests/ui/iter_count.rs:59:5 + --> tests/ui/iter_count.rs:64:5 | LL | hash_map.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()` error: called `.iter().count()` on a `BTreeMap` - --> tests/ui/iter_count.rs:60:5 + --> tests/ui/iter_count.rs:66:5 | LL | b_tree_map.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()` error: called `.iter().count()` on a `BTreeSet` - --> tests/ui/iter_count.rs:61:5 + --> tests/ui/iter_count.rs:68:5 | LL | b_tree_set.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()` error: called `.iter().count()` on a `LinkedList` - --> tests/ui/iter_count.rs:62:5 + --> tests/ui/iter_count.rs:70:5 | LL | linked_list.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()` error: called `.iter().count()` on a `BinaryHeap` - --> tests/ui/iter_count.rs:63:5 + --> tests/ui/iter_count.rs:72:5 | LL | binary_heap.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()` error: called `.iter_mut().count()` on a `Vec` - --> tests/ui/iter_count.rs:65:5 + --> tests/ui/iter_count.rs:75:5 | LL | vec.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.iter_mut().count()` on a `slice` - --> tests/ui/iter_count.rs:66:6 + --> tests/ui/iter_count.rs:77:6 | LL | &vec[..].iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` error: called `.iter_mut().count()` on a `VecDeque` - --> tests/ui/iter_count.rs:67:5 + --> tests/ui/iter_count.rs:79:5 | LL | vec_deque.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` error: called `.iter_mut().count()` on a `HashMap` - --> tests/ui/iter_count.rs:68:5 + --> tests/ui/iter_count.rs:81:5 | LL | hash_map.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()` error: called `.iter_mut().count()` on a `BTreeMap` - --> tests/ui/iter_count.rs:69:5 + --> tests/ui/iter_count.rs:83:5 | LL | b_tree_map.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()` error: called `.iter_mut().count()` on a `LinkedList` - --> tests/ui/iter_count.rs:70:5 + --> tests/ui/iter_count.rs:85:5 | LL | linked_list.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()` error: called `.into_iter().count()` on a `slice` - --> tests/ui/iter_count.rs:72:6 + --> tests/ui/iter_count.rs:88:6 | LL | &vec[..].into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` error: called `.into_iter().count()` on a `Vec` - --> tests/ui/iter_count.rs:73:5 + --> tests/ui/iter_count.rs:90:5 | LL | vec.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.into_iter().count()` on a `VecDeque` - --> tests/ui/iter_count.rs:74:5 + --> tests/ui/iter_count.rs:92:5 | LL | vec_deque.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` error: called `.into_iter().count()` on a `HashSet` - --> tests/ui/iter_count.rs:75:5 + --> tests/ui/iter_count.rs:94:5 | LL | hash_set.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()` error: called `.into_iter().count()` on a `HashMap` - --> tests/ui/iter_count.rs:76:5 + --> tests/ui/iter_count.rs:96:5 | LL | hash_map.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()` error: called `.into_iter().count()` on a `BTreeMap` - --> tests/ui/iter_count.rs:77:5 + --> tests/ui/iter_count.rs:98:5 | LL | b_tree_map.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()` error: called `.into_iter().count()` on a `BTreeSet` - --> tests/ui/iter_count.rs:78:5 + --> tests/ui/iter_count.rs:100:5 | LL | b_tree_set.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()` error: called `.into_iter().count()` on a `LinkedList` - --> tests/ui/iter_count.rs:79:5 + --> tests/ui/iter_count.rs:102:5 | LL | linked_list.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()` error: called `.into_iter().count()` on a `BinaryHeap` - --> tests/ui/iter_count.rs:80:5 + --> tests/ui/iter_count.rs:104:5 | LL | binary_heap.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()` diff --git a/tests/ui/iter_filter_is_ok.fixed b/tests/ui/iter_filter_is_ok.fixed index 80db8b29c18e..d3aeeff7d7b4 100644 --- a/tests/ui/iter_filter_is_ok.fixed +++ b/tests/ui/iter_filter_is_ok.fixed @@ -9,51 +9,63 @@ fn main() { { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + } { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + } { let _ = vec![Ok(1), Err(2), Ok(3)] .into_iter() .flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + let _ = vec![Ok(1), Err(2), Ok(3)] .into_iter() .flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + #[rustfmt::skip] let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + } { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + } } diff --git a/tests/ui/iter_filter_is_ok.rs b/tests/ui/iter_filter_is_ok.rs index 89b083b84f32..7ed974876693 100644 --- a/tests/ui/iter_filter_is_ok.rs +++ b/tests/ui/iter_filter_is_ok.rs @@ -9,51 +9,63 @@ fn main() { { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(Result::is_ok); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| a.is_ok()); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| { o.is_ok() }); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + } { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok()); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok()); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().filter(|&o| { o.is_ok() }); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + } { let _ = vec![Ok(1), Err(2), Ok(3)] .into_iter() .filter(std::result::Result::is_ok); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + let _ = vec![Ok(1), Err(2), Ok(3)] .into_iter() .filter(|a| std::result::Result::is_ok(a)); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + #[rustfmt::skip] let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| { std::result::Result::is_ok(a) }); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + } { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok()); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok()); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().filter(|ref o| { o.is_ok() }); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_ok + } } diff --git a/tests/ui/iter_filter_is_ok.stderr b/tests/ui/iter_filter_is_ok.stderr index 0aff60224e0e..56c60c093a4b 100644 --- a/tests/ui/iter_filter_is_ok.stderr +++ b/tests/ui/iter_filter_is_ok.stderr @@ -8,23 +8,17 @@ LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(Result::is_ok = help: to override `-D warnings` add `#[allow(clippy::iter_filter_is_ok)]` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:13:56 + --> tests/ui/iter_filter_is_ok.rs:14:56 | LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| a.is_ok()); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:16:49 + --> tests/ui/iter_filter_is_ok.rs:18:49 | LL | let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| { o.is_ok() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` -error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:21:56 - | -LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok()); - | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` - error: `filter` for `is_ok` on iterator over `Result`s --> tests/ui/iter_filter_is_ok.rs:24:56 | @@ -32,43 +26,49 @@ LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok( | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:28:49 + --> tests/ui/iter_filter_is_ok.rs:28:56 + | +LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok()); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` + +error: `filter` for `is_ok` on iterator over `Result`s + --> tests/ui/iter_filter_is_ok.rs:33:49 | LL | let _ = vec![Ok(1), Err(2)].into_iter().filter(|&o| { o.is_ok() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:35:14 + --> tests/ui/iter_filter_is_ok.rs:41:14 | LL | .filter(std::result::Result::is_ok); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:40:14 + --> tests/ui/iter_filter_is_ok.rs:47:14 | LL | .filter(|a| std::result::Result::is_ok(a)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:43:56 + --> tests/ui/iter_filter_is_ok.rs:51:56 | LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| { std::result::Result::is_ok(a) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:48:56 + --> tests/ui/iter_filter_is_ok.rs:57:56 | LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:51:56 + --> tests/ui/iter_filter_is_ok.rs:61:56 | LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:55:49 + --> tests/ui/iter_filter_is_ok.rs:66:49 | LL | let _ = vec![Ok(1), Err(2)].into_iter().filter(|ref o| { o.is_ok() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` diff --git a/tests/ui/iter_filter_is_some.fixed b/tests/ui/iter_filter_is_some.fixed index 8a818c0c6728..f76e7a619079 100644 --- a/tests/ui/iter_filter_is_some.fixed +++ b/tests/ui/iter_filter_is_some.fixed @@ -13,45 +13,55 @@ use std::collections::HashMap; fn main() { { let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + } { let _ = vec![Some(1), None, Some(3)] .into_iter() .flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + let _ = vec![Some(1), None, Some(3)] .into_iter() .flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + } { let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + } { let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + } } diff --git a/tests/ui/iter_filter_is_some.rs b/tests/ui/iter_filter_is_some.rs index 9eda93a25921..536af0021420 100644 --- a/tests/ui/iter_filter_is_some.rs +++ b/tests/ui/iter_filter_is_some.rs @@ -13,45 +13,55 @@ use std::collections::HashMap; fn main() { { let _ = vec![Some(1), None, Some(3)].into_iter().filter(Option::is_some); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| a.is_some()); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| { o.is_some() }); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + } { let _ = vec![Some(1), None, Some(3)] .into_iter() .filter(std::option::Option::is_some); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + let _ = vec![Some(1), None, Some(3)] .into_iter() .filter(|a| std::option::Option::is_some(a)); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| { std::option::Option::is_some(a) }); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + } { let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&a| a.is_some()); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&o| { o.is_some() }); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + } { let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref a| a.is_some()); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref o| { o.is_some() }); - //~^ HELP: consider using `flatten` instead + //~^ iter_filter_is_some + } } diff --git a/tests/ui/iter_filter_is_some.stderr b/tests/ui/iter_filter_is_some.stderr index 54aff892b1f0..d1653fe1b7a3 100644 --- a/tests/ui/iter_filter_is_some.stderr +++ b/tests/ui/iter_filter_is_some.stderr @@ -8,55 +8,55 @@ LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(Option::is_ = help: to override `-D warnings` add `#[allow(clippy::iter_filter_is_some)]` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:17:58 + --> tests/ui/iter_filter_is_some.rs:18:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| a.is_some()); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:20:58 + --> tests/ui/iter_filter_is_some.rs:22:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| { o.is_some() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:27:14 + --> tests/ui/iter_filter_is_some.rs:30:14 | LL | .filter(std::option::Option::is_some); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:32:14 + --> tests/ui/iter_filter_is_some.rs:36:14 | LL | .filter(|a| std::option::Option::is_some(a)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:35:58 + --> tests/ui/iter_filter_is_some.rs:40:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| { std::option::Option::is_some(a) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:40:58 + --> tests/ui/iter_filter_is_some.rs:46:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&a| a.is_some()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:44:58 + --> tests/ui/iter_filter_is_some.rs:51:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&o| { o.is_some() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:49:58 + --> tests/ui/iter_filter_is_some.rs:57:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref a| a.is_some()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:53:58 + --> tests/ui/iter_filter_is_some.rs:62:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref o| { o.is_some() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` diff --git a/tests/ui/iter_kv_map.fixed b/tests/ui/iter_kv_map.fixed index 2cbf972fca5f..b9d86d8dd803 100644 --- a/tests/ui/iter_kv_map.fixed +++ b/tests/ui/iter_kv_map.fixed @@ -12,17 +12,26 @@ fn main() { let map: HashMap = HashMap::new(); let _ = map.keys().collect::>(); + //~^ iter_kv_map let _ = map.values().collect::>(); + //~^ iter_kv_map let _ = map.values().map(|v| v + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_keys().collect::>(); + //~^ iter_kv_map let _ = map.clone().into_keys().map(|key| key + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_values().collect::>(); + //~^ iter_kv_map let _ = map.clone().into_values().map(|val| val + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().values().collect::>(); + //~^ iter_kv_map let _ = map.keys().filter(|x| *x % 2 == 0).count(); + //~^ iter_kv_map // Don't lint let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count(); @@ -33,13 +42,17 @@ fn main() { // Lint let _ = map.keys().map(|key| key * 9).count(); + //~^ iter_kv_map let _ = map.values().map(|value| value * 17).count(); + //~^ iter_kv_map // Preserve the ref in the fix. let _ = map.clone().into_values().map(|ref val| ref_acceptor(val)).count(); + //~^ iter_kv_map // Preserve the mut in the fix. let _ = map + //~^ iter_kv_map .clone().into_values().map(|mut val| { val += 2; val @@ -48,21 +61,31 @@ fn main() { // Don't let a mut interfere. let _ = map.clone().into_values().count(); + //~^ iter_kv_map let map: BTreeMap = BTreeMap::new(); let _ = map.keys().collect::>(); + //~^ iter_kv_map let _ = map.values().collect::>(); + //~^ iter_kv_map let _ = map.values().map(|v| v + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_keys().collect::>(); + //~^ iter_kv_map let _ = map.clone().into_keys().map(|key| key + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_values().collect::>(); + //~^ iter_kv_map let _ = map.clone().into_values().map(|val| val + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().values().collect::>(); + //~^ iter_kv_map let _ = map.keys().filter(|x| *x % 2 == 0).count(); + //~^ iter_kv_map // Don't lint let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count(); @@ -73,13 +96,17 @@ fn main() { // Lint let _ = map.keys().map(|key| key * 9).count(); + //~^ iter_kv_map let _ = map.values().map(|value| value * 17).count(); + //~^ iter_kv_map // Preserve the ref in the fix. let _ = map.clone().into_values().map(|ref val| ref_acceptor(val)).count(); + //~^ iter_kv_map // Preserve the mut in the fix. let _ = map + //~^ iter_kv_map .clone().into_values().map(|mut val| { val += 2; val @@ -88,6 +115,7 @@ fn main() { // Don't let a mut interfere. let _ = map.clone().into_values().count(); + //~^ iter_kv_map } #[clippy::msrv = "1.53"] @@ -103,11 +131,14 @@ fn msrv_1_53() { // Lint let _ = map.keys().collect::>(); - //~^ ERROR: iterating on a map's keys + //~^ iter_kv_map + let _ = map.values().collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + let _ = map.values().map(|v| v + 2).collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + } #[clippy::msrv = "1.54"] @@ -116,19 +147,26 @@ fn msrv_1_54() { let map: HashMap = HashMap::new(); let _ = map.clone().into_keys().collect::>(); - //~^ ERROR: iterating on a map's keys + //~^ iter_kv_map + let _ = map.clone().into_keys().map(|key| key + 2).collect::>(); - //~^ ERROR: iterating on a map's keys + //~^ iter_kv_map + let _ = map.clone().into_values().collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + let _ = map.clone().into_values().map(|val| val + 2).collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + let _ = map.keys().collect::>(); - //~^ ERROR: iterating on a map's keys + //~^ iter_kv_map + let _ = map.values().collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + let _ = map.values().map(|v| v + 2).collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + } diff --git a/tests/ui/iter_kv_map.rs b/tests/ui/iter_kv_map.rs index 6a9a4267a765..b14786180b1f 100644 --- a/tests/ui/iter_kv_map.rs +++ b/tests/ui/iter_kv_map.rs @@ -12,17 +12,26 @@ fn main() { let map: HashMap = HashMap::new(); let _ = map.iter().map(|(key, _)| key).collect::>(); + //~^ iter_kv_map let _ = map.iter().map(|(_, value)| value).collect::>(); + //~^ iter_kv_map let _ = map.iter().map(|(_, v)| v + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().iter().map(|(_, val)| val).collect::>(); + //~^ iter_kv_map let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count(); + //~^ iter_kv_map // Don't lint let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count(); @@ -33,13 +42,17 @@ fn main() { // Lint let _ = map.iter().map(|(key, _value)| key * 9).count(); + //~^ iter_kv_map let _ = map.iter().map(|(_key, value)| value * 17).count(); + //~^ iter_kv_map // Preserve the ref in the fix. let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count(); + //~^ iter_kv_map // Preserve the mut in the fix. let _ = map + //~^ iter_kv_map .clone() .into_iter() .map(|(_, mut val)| { @@ -50,21 +63,31 @@ fn main() { // Don't let a mut interfere. let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); + //~^ iter_kv_map let map: BTreeMap = BTreeMap::new(); let _ = map.iter().map(|(key, _)| key).collect::>(); + //~^ iter_kv_map let _ = map.iter().map(|(_, value)| value).collect::>(); + //~^ iter_kv_map let _ = map.iter().map(|(_, v)| v + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); + //~^ iter_kv_map let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); + //~^ iter_kv_map let _ = map.clone().iter().map(|(_, val)| val).collect::>(); + //~^ iter_kv_map let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count(); + //~^ iter_kv_map // Don't lint let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count(); @@ -75,13 +98,17 @@ fn main() { // Lint let _ = map.iter().map(|(key, _value)| key * 9).count(); + //~^ iter_kv_map let _ = map.iter().map(|(_key, value)| value * 17).count(); + //~^ iter_kv_map // Preserve the ref in the fix. let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count(); + //~^ iter_kv_map // Preserve the mut in the fix. let _ = map + //~^ iter_kv_map .clone() .into_iter() .map(|(_, mut val)| { @@ -92,6 +119,7 @@ fn main() { // Don't let a mut interfere. let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); + //~^ iter_kv_map } #[clippy::msrv = "1.53"] @@ -107,11 +135,14 @@ fn msrv_1_53() { // Lint let _ = map.iter().map(|(key, _)| key).collect::>(); - //~^ ERROR: iterating on a map's keys + //~^ iter_kv_map + let _ = map.iter().map(|(_, value)| value).collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + let _ = map.iter().map(|(_, v)| v + 2).collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + } #[clippy::msrv = "1.54"] @@ -120,19 +151,26 @@ fn msrv_1_54() { let map: HashMap = HashMap::new(); let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); - //~^ ERROR: iterating on a map's keys + //~^ iter_kv_map + let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); - //~^ ERROR: iterating on a map's keys + //~^ iter_kv_map + let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + let _ = map.iter().map(|(key, _)| key).collect::>(); - //~^ ERROR: iterating on a map's keys + //~^ iter_kv_map + let _ = map.iter().map(|(_, value)| value).collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + let _ = map.iter().map(|(_, v)| v + 2).collect::>(); - //~^ ERROR: iterating on a map's values + //~^ iter_kv_map + } diff --git a/tests/ui/iter_kv_map.stderr b/tests/ui/iter_kv_map.stderr index ad23dba55cb6..d99fea1124a7 100644 --- a/tests/ui/iter_kv_map.stderr +++ b/tests/ui/iter_kv_map.stderr @@ -8,80 +8,80 @@ LL | let _ = map.iter().map(|(key, _)| key).collect::>(); = help: to override `-D warnings` add `#[allow(clippy::iter_kv_map)]` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:15:13 + --> tests/ui/iter_kv_map.rs:16:13 | LL | let _ = map.iter().map(|(_, value)| value).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:16:13 + --> tests/ui/iter_kv_map.rs:18:13 | LL | let _ = map.iter().map(|(_, v)| v + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:18:13 + --> tests/ui/iter_kv_map.rs:21:13 | LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:19:13 + --> tests/ui/iter_kv_map.rs:23:13 | LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:21:13 + --> tests/ui/iter_kv_map.rs:26:13 | LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:22:13 + --> tests/ui/iter_kv_map.rs:28:13 | LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:24:13 + --> tests/ui/iter_kv_map.rs:31:13 | LL | let _ = map.clone().iter().map(|(_, val)| val).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:25:13 + --> tests/ui/iter_kv_map.rs:33:13 | LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:35:13 + --> tests/ui/iter_kv_map.rs:44:13 | LL | let _ = map.iter().map(|(key, _value)| key * 9).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:36:13 + --> tests/ui/iter_kv_map.rs:46:13 | LL | let _ = map.iter().map(|(_key, value)| value * 17).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:39:13 + --> tests/ui/iter_kv_map.rs:50:13 | LL | let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:42:13 + --> tests/ui/iter_kv_map.rs:54:13 | LL | let _ = map | _____________^ +LL | | LL | | .clone() LL | | .into_iter() -LL | | .map(|(_, mut val)| { -LL | | val += 2; +... | LL | | val LL | | }) | |__________^ @@ -89,6 +89,7 @@ LL | | }) help: try | LL ~ let _ = map +LL + LL + .clone().into_values().map(|mut val| { LL + val += 2; LL + val @@ -96,92 +97,92 @@ LL + }) | error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:52:13 + --> tests/ui/iter_kv_map.rs:65:13 | LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:56:13 + --> tests/ui/iter_kv_map.rs:70:13 | LL | let _ = map.iter().map(|(key, _)| key).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:57:13 + --> tests/ui/iter_kv_map.rs:72:13 | LL | let _ = map.iter().map(|(_, value)| value).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:58:13 + --> tests/ui/iter_kv_map.rs:74:13 | LL | let _ = map.iter().map(|(_, v)| v + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` -error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:60:13 - | -LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()` - -error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:61:13 - | -LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)` - -error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:63:13 - | -LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` - -error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:64:13 - | -LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)` - -error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:66:13 - | -LL | let _ = map.clone().iter().map(|(_, val)| val).collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()` - -error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:67:13 - | -LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` - error: iterating on a map's keys --> tests/ui/iter_kv_map.rs:77:13 | +LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()` + +error: iterating on a map's keys + --> tests/ui/iter_kv_map.rs:79:13 + | +LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)` + +error: iterating on a map's values + --> tests/ui/iter_kv_map.rs:82:13 + | +LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` + +error: iterating on a map's values + --> tests/ui/iter_kv_map.rs:84:13 + | +LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)` + +error: iterating on a map's values + --> tests/ui/iter_kv_map.rs:87:13 + | +LL | let _ = map.clone().iter().map(|(_, val)| val).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()` + +error: iterating on a map's keys + --> tests/ui/iter_kv_map.rs:89:13 + | +LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` + +error: iterating on a map's keys + --> tests/ui/iter_kv_map.rs:100:13 + | LL | let _ = map.iter().map(|(key, _value)| key * 9).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:78:13 + --> tests/ui/iter_kv_map.rs:102:13 | LL | let _ = map.iter().map(|(_key, value)| value * 17).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:81:13 + --> tests/ui/iter_kv_map.rs:106:13 | LL | let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:84:13 + --> tests/ui/iter_kv_map.rs:110:13 | LL | let _ = map | _____________^ +LL | | LL | | .clone() LL | | .into_iter() -LL | | .map(|(_, mut val)| { -LL | | val += 2; +... | LL | | val LL | | }) | |__________^ @@ -189,6 +190,7 @@ LL | | }) help: try | LL ~ let _ = map +LL + LL + .clone().into_values().map(|mut val| { LL + val += 2; LL + val @@ -196,67 +198,67 @@ LL + }) | error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:94:13 + --> tests/ui/iter_kv_map.rs:121:13 | LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:109:13 + --> tests/ui/iter_kv_map.rs:137:13 | LL | let _ = map.iter().map(|(key, _)| key).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:111:13 + --> tests/ui/iter_kv_map.rs:140:13 | LL | let _ = map.iter().map(|(_, value)| value).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:113:13 + --> tests/ui/iter_kv_map.rs:143:13 | LL | let _ = map.iter().map(|(_, v)| v + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:122:13 + --> tests/ui/iter_kv_map.rs:153:13 | LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:124:13 + --> tests/ui/iter_kv_map.rs:156:13 | LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:127:13 + --> tests/ui/iter_kv_map.rs:160:13 | LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:129:13 + --> tests/ui/iter_kv_map.rs:163:13 | LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:132:13 + --> tests/ui/iter_kv_map.rs:167:13 | LL | let _ = map.iter().map(|(key, _)| key).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:134:13 + --> tests/ui/iter_kv_map.rs:170:13 | LL | let _ = map.iter().map(|(_, value)| value).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:136:13 + --> tests/ui/iter_kv_map.rs:173:13 | LL | let _ = map.iter().map(|(_, v)| v + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` diff --git a/tests/ui/iter_next_loop.rs b/tests/ui/iter_next_loop.rs index d425f4da0e81..32711c7ef623 100644 --- a/tests/ui/iter_next_loop.rs +++ b/tests/ui/iter_next_loop.rs @@ -4,6 +4,7 @@ fn main() { let x = [1, 2, 3, 4]; for _ in x.iter().next() {} + //~^ iter_next_loop struct Unrelated(&'static [u8]); impl Unrelated { diff --git a/tests/ui/iter_next_slice.fixed b/tests/ui/iter_next_slice.fixed index 83be12c4e254..2e7b4e632840 100644 --- a/tests/ui/iter_next_slice.fixed +++ b/tests/ui/iter_next_slice.fixed @@ -7,15 +7,19 @@ fn main() { let v = vec![1, 2, 3]; let _ = s.first(); + //~^ iter_next_slice // Should be replaced by s.first() let _ = s.get(2); + //~^ iter_next_slice // Should be replaced by s.get(2) let _ = v.get(5); + //~^ iter_next_slice // Should be replaced by v.get(5) let _ = v.first(); + //~^ iter_next_slice // Should be replaced by v.first() let o = Some(5); diff --git a/tests/ui/iter_next_slice.rs b/tests/ui/iter_next_slice.rs index 1b257514d23e..b2e047f5d817 100644 --- a/tests/ui/iter_next_slice.rs +++ b/tests/ui/iter_next_slice.rs @@ -7,15 +7,19 @@ fn main() { let v = vec![1, 2, 3]; let _ = s.iter().next(); + //~^ iter_next_slice // Should be replaced by s.first() let _ = s[2..].iter().next(); + //~^ iter_next_slice // Should be replaced by s.get(2) let _ = v[5..].iter().next(); + //~^ iter_next_slice // Should be replaced by v.get(5) let _ = v.iter().next(); + //~^ iter_next_slice // Should be replaced by v.first() let o = Some(5); diff --git a/tests/ui/iter_next_slice.stderr b/tests/ui/iter_next_slice.stderr index 55cce2b9103d..0a22ab7f6a15 100644 --- a/tests/ui/iter_next_slice.stderr +++ b/tests/ui/iter_next_slice.stderr @@ -8,19 +8,19 @@ LL | let _ = s.iter().next(); = help: to override `-D warnings` add `#[allow(clippy::iter_next_slice)]` error: using `.iter().next()` on a Slice without end index - --> tests/ui/iter_next_slice.rs:12:13 + --> tests/ui/iter_next_slice.rs:13:13 | LL | let _ = s[2..].iter().next(); | ^^^^^^^^^^^^^^^^^^^^ help: try calling: `s.get(2)` error: using `.iter().next()` on a Slice without end index - --> tests/ui/iter_next_slice.rs:15:13 + --> tests/ui/iter_next_slice.rs:17:13 | LL | let _ = v[5..].iter().next(); | ^^^^^^^^^^^^^^^^^^^^ help: try calling: `v.get(5)` error: using `.iter().next()` on an array - --> tests/ui/iter_next_slice.rs:18:13 + --> tests/ui/iter_next_slice.rs:21:13 | LL | let _ = v.iter().next(); | ^^^^^^^^^^^^^^^ help: try calling: `v.first()` diff --git a/tests/ui/iter_not_returning_iterator.rs b/tests/ui/iter_not_returning_iterator.rs index e694bc7ac62f..4c0c667be80f 100644 --- a/tests/ui/iter_not_returning_iterator.rs +++ b/tests/ui/iter_not_returning_iterator.rs @@ -28,13 +28,15 @@ struct Counter2 { impl Data2 { fn iter(&self) -> Counter2 { - //~^ ERROR: this method is named `iter` but its return type does not implement `Iterat - //~| NOTE: `-D clippy::iter-not-returning-iterator` implied by `-D warnings` + //~^ iter_not_returning_iterator + + todo!() } fn iter_mut(&self) -> Counter2 { - //~^ ERROR: this method is named `iter_mut` but its return type does not implement `It + //~^ iter_not_returning_iterator + todo!() } } @@ -51,7 +53,8 @@ impl Iterator for Counter { trait Iter { type I; fn iter(&self) -> Self::I; - //~^ ERROR: this method is named `iter` but its return type does not implement `Iterat + //~^ iter_not_returning_iterator + } impl Iter for () { diff --git a/tests/ui/iter_not_returning_iterator.stderr b/tests/ui/iter_not_returning_iterator.stderr index c3ee8bae772d..8c0ebd847110 100644 --- a/tests/ui/iter_not_returning_iterator.stderr +++ b/tests/ui/iter_not_returning_iterator.stderr @@ -8,13 +8,13 @@ LL | fn iter(&self) -> Counter2 { = help: to override `-D warnings` add `#[allow(clippy::iter_not_returning_iterator)]` error: this method is named `iter_mut` but its return type does not implement `Iterator` - --> tests/ui/iter_not_returning_iterator.rs:36:5 + --> tests/ui/iter_not_returning_iterator.rs:37:5 | LL | fn iter_mut(&self) -> Counter2 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this method is named `iter` but its return type does not implement `Iterator` - --> tests/ui/iter_not_returning_iterator.rs:53:5 + --> tests/ui/iter_not_returning_iterator.rs:55:5 | LL | fn iter(&self) -> Self::I; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/iter_nth.fixed b/tests/ui/iter_nth.fixed index aff3731a8837..5650903a5dcb 100644 --- a/tests/ui/iter_nth.fixed +++ b/tests/ui/iter_nth.fixed @@ -32,24 +32,32 @@ fn iter_nth() { { // Make sure we lint `.iter()` for relevant types. let bad_vec = some_vec.get(3); + //~^ iter_nth let bad_slice = &some_vec[..].get(3); + //~^ iter_nth let bad_boxed_slice = boxed_slice.get(3); + //~^ iter_nth let bad_vec_deque = some_vec_deque.get(3); + //~^ iter_nth } { // Make sure we lint `.iter_mut()` for relevant types. let bad_vec = some_vec.get_mut(3); + //~^ iter_nth } { let bad_slice = &some_vec[..].get_mut(3); + //~^ iter_nth } { let bad_vec_deque = some_vec_deque.get_mut(3); + //~^ iter_nth } let vec_ref = &Vec::::new(); vec_ref.get(3); + //~^ iter_nth // Make sure we don't lint for non-relevant types. let false_positive = HasIter; diff --git a/tests/ui/iter_nth.rs b/tests/ui/iter_nth.rs index 89d68044ddda..cfd0629420e1 100644 --- a/tests/ui/iter_nth.rs +++ b/tests/ui/iter_nth.rs @@ -32,24 +32,32 @@ fn iter_nth() { { // Make sure we lint `.iter()` for relevant types. let bad_vec = some_vec.iter().nth(3); + //~^ iter_nth let bad_slice = &some_vec[..].iter().nth(3); + //~^ iter_nth let bad_boxed_slice = boxed_slice.iter().nth(3); + //~^ iter_nth let bad_vec_deque = some_vec_deque.iter().nth(3); + //~^ iter_nth } { // Make sure we lint `.iter_mut()` for relevant types. let bad_vec = some_vec.iter_mut().nth(3); + //~^ iter_nth } { let bad_slice = &some_vec[..].iter_mut().nth(3); + //~^ iter_nth } { let bad_vec_deque = some_vec_deque.iter_mut().nth(3); + //~^ iter_nth } let vec_ref = &Vec::::new(); vec_ref.iter().nth(3); + //~^ iter_nth // Make sure we don't lint for non-relevant types. let false_positive = HasIter; diff --git a/tests/ui/iter_nth.stderr b/tests/ui/iter_nth.stderr index 178463f53475..ae6e66f8cbf4 100644 --- a/tests/ui/iter_nth.stderr +++ b/tests/ui/iter_nth.stderr @@ -12,7 +12,7 @@ LL | let bad_vec = some_vec.get(3); | ~~~ error: called `.iter().nth()` on a slice - --> tests/ui/iter_nth.rs:35:26 + --> tests/ui/iter_nth.rs:36:26 | LL | let bad_slice = &some_vec[..].iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let bad_slice = &some_vec[..].get(3); | ~~~ error: called `.iter().nth()` on a slice - --> tests/ui/iter_nth.rs:36:31 + --> tests/ui/iter_nth.rs:38:31 | LL | let bad_boxed_slice = boxed_slice.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let bad_boxed_slice = boxed_slice.get(3); | ~~~ error: called `.iter().nth()` on a `VecDeque` - --> tests/ui/iter_nth.rs:37:29 + --> tests/ui/iter_nth.rs:40:29 | LL | let bad_vec_deque = some_vec_deque.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let bad_vec_deque = some_vec_deque.get(3); | ~~~ error: called `.iter_mut().nth()` on a `Vec` - --> tests/ui/iter_nth.rs:42:23 + --> tests/ui/iter_nth.rs:46:23 | LL | let bad_vec = some_vec.iter_mut().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let bad_vec = some_vec.get_mut(3); | ~~~~~~~ error: called `.iter_mut().nth()` on a slice - --> tests/ui/iter_nth.rs:45:26 + --> tests/ui/iter_nth.rs:50:26 | LL | let bad_slice = &some_vec[..].iter_mut().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let bad_slice = &some_vec[..].get_mut(3); | ~~~~~~~ error: called `.iter_mut().nth()` on a `VecDeque` - --> tests/ui/iter_nth.rs:48:29 + --> tests/ui/iter_nth.rs:54:29 | LL | let bad_vec_deque = some_vec_deque.iter_mut().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let bad_vec_deque = some_vec_deque.get_mut(3); | ~~~~~~~ error: called `.iter().nth()` on a `Vec` - --> tests/ui/iter_nth.rs:52:5 + --> tests/ui/iter_nth.rs:59:5 | LL | vec_ref.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/iter_nth_zero.fixed b/tests/ui/iter_nth_zero.fixed index a3cdb2e59bff..07153db90c19 100644 --- a/tests/ui/iter_nth_zero.fixed +++ b/tests/ui/iter_nth_zero.fixed @@ -16,16 +16,19 @@ fn main() { let mut s = HashSet::new(); s.insert(1); let _x = s.iter().next(); + //~^ iter_nth_zero let mut s2 = HashSet::new(); s2.insert(2); let mut iter = s2.iter(); let _y = iter.next(); + //~^ iter_nth_zero let mut s3 = HashSet::new(); s3.insert(3); let mut iter2 = s3.iter(); let _unwrapped = iter2.next().unwrap(); + //~^ iter_nth_zero } struct Issue9820; diff --git a/tests/ui/iter_nth_zero.rs b/tests/ui/iter_nth_zero.rs index 64229b5128a3..45d008cd7040 100644 --- a/tests/ui/iter_nth_zero.rs +++ b/tests/ui/iter_nth_zero.rs @@ -16,16 +16,19 @@ fn main() { let mut s = HashSet::new(); s.insert(1); let _x = s.iter().nth(0); + //~^ iter_nth_zero let mut s2 = HashSet::new(); s2.insert(2); let mut iter = s2.iter(); let _y = iter.nth(0); + //~^ iter_nth_zero let mut s3 = HashSet::new(); s3.insert(3); let mut iter2 = s3.iter(); let _unwrapped = iter2.nth(0).unwrap(); + //~^ iter_nth_zero } struct Issue9820; diff --git a/tests/ui/iter_nth_zero.stderr b/tests/ui/iter_nth_zero.stderr index b5e5cf45c26b..edd44838b7ec 100644 --- a/tests/ui/iter_nth_zero.stderr +++ b/tests/ui/iter_nth_zero.stderr @@ -8,13 +8,13 @@ LL | let _x = s.iter().nth(0); = help: to override `-D warnings` add `#[allow(clippy::iter_nth_zero)]` error: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent - --> tests/ui/iter_nth_zero.rs:23:14 + --> tests/ui/iter_nth_zero.rs:24:14 | LL | let _y = iter.nth(0); | ^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `iter.next()` error: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent - --> tests/ui/iter_nth_zero.rs:28:22 + --> tests/ui/iter_nth_zero.rs:30:22 | LL | let _unwrapped = iter2.nth(0).unwrap(); | ^^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `iter2.next()` diff --git a/tests/ui/iter_on_empty_collections.fixed b/tests/ui/iter_on_empty_collections.fixed index 0f28b48d9ab8..e1e4e331843b 100644 --- a/tests/ui/iter_on_empty_collections.fixed +++ b/tests/ui/iter_on_empty_collections.fixed @@ -3,11 +3,17 @@ fn array() { assert_eq!(std::iter::empty().next(), Option::::None); + //~^ iter_on_empty_collections assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None); + //~^ iter_on_empty_collections assert_eq!(std::iter::empty().next(), Option::<&i32>::None); + //~^ iter_on_empty_collections assert_eq!(std::iter::empty().next(), Option::::None); + //~^ iter_on_empty_collections assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None); + //~^ iter_on_empty_collections assert_eq!(std::iter::empty().next(), Option::<&i32>::None); + //~^ iter_on_empty_collections // Don't trigger on non-iter methods let _: Option = None.clone(); @@ -26,6 +32,7 @@ fn array() { // Don't trigger when the empty collection iter is relied upon for its concrete type // But do trigger if it is just an iterator, despite being an argument to a method for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain(std::iter::empty()) { + //~^ iter_on_empty_collections println!("{i}"); } diff --git a/tests/ui/iter_on_empty_collections.rs b/tests/ui/iter_on_empty_collections.rs index 702da514df7d..3a4ad7fb372a 100644 --- a/tests/ui/iter_on_empty_collections.rs +++ b/tests/ui/iter_on_empty_collections.rs @@ -3,11 +3,17 @@ fn array() { assert_eq!([].into_iter().next(), Option::::None); + //~^ iter_on_empty_collections assert_eq!([].iter_mut().next(), Option::<&mut i32>::None); + //~^ iter_on_empty_collections assert_eq!([].iter().next(), Option::<&i32>::None); + //~^ iter_on_empty_collections assert_eq!(None.into_iter().next(), Option::::None); + //~^ iter_on_empty_collections assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); + //~^ iter_on_empty_collections assert_eq!(None.iter().next(), Option::<&i32>::None); + //~^ iter_on_empty_collections // Don't trigger on non-iter methods let _: Option = None.clone(); @@ -26,6 +32,7 @@ fn array() { // Don't trigger when the empty collection iter is relied upon for its concrete type // But do trigger if it is just an iterator, despite being an argument to a method for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain([].iter()) { + //~^ iter_on_empty_collections println!("{i}"); } diff --git a/tests/ui/iter_on_empty_collections.stderr b/tests/ui/iter_on_empty_collections.stderr index da9caa6925bd..2803999cc735 100644 --- a/tests/ui/iter_on_empty_collections.stderr +++ b/tests/ui/iter_on_empty_collections.stderr @@ -8,37 +8,37 @@ LL | assert_eq!([].into_iter().next(), Option::::None); = help: to override `-D warnings` add `#[allow(clippy::iter_on_empty_collections)]` error: `iter_mut` call on an empty collection - --> tests/ui/iter_on_empty_collections.rs:6:16 + --> tests/ui/iter_on_empty_collections.rs:7:16 | LL | assert_eq!([].iter_mut().next(), Option::<&mut i32>::None); | ^^^^^^^^^^^^^ help: try: `std::iter::empty()` error: `iter` call on an empty collection - --> tests/ui/iter_on_empty_collections.rs:7:16 + --> tests/ui/iter_on_empty_collections.rs:9:16 | LL | assert_eq!([].iter().next(), Option::<&i32>::None); | ^^^^^^^^^ help: try: `std::iter::empty()` error: `into_iter` call on an empty collection - --> tests/ui/iter_on_empty_collections.rs:8:16 + --> tests/ui/iter_on_empty_collections.rs:11:16 | LL | assert_eq!(None.into_iter().next(), Option::::None); | ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()` error: `iter_mut` call on an empty collection - --> tests/ui/iter_on_empty_collections.rs:9:16 + --> tests/ui/iter_on_empty_collections.rs:13:16 | LL | assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); | ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()` error: `iter` call on an empty collection - --> tests/ui/iter_on_empty_collections.rs:10:16 + --> tests/ui/iter_on_empty_collections.rs:15:16 | LL | assert_eq!(None.iter().next(), Option::<&i32>::None); | ^^^^^^^^^^^ help: try: `std::iter::empty()` error: `iter` call on an empty collection - --> tests/ui/iter_on_empty_collections.rs:28:66 + --> tests/ui/iter_on_empty_collections.rs:34:66 | LL | for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain([].iter()) { | ^^^^^^^^^ help: try: `std::iter::empty()` diff --git a/tests/ui/iter_on_single_items.fixed b/tests/ui/iter_on_single_items.fixed index 117ec8429c37..b43fad6449c1 100644 --- a/tests/ui/iter_on_single_items.fixed +++ b/tests/ui/iter_on_single_items.fixed @@ -3,11 +3,17 @@ fn array() { assert_eq!(std::iter::once(123).next(), Some(123)); + //~^ iter_on_single_items assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123)); + //~^ iter_on_single_items assert_eq!(std::iter::once(&123).next(), Some(&123)); + //~^ iter_on_single_items assert_eq!(std::iter::once(123).next(), Some(123)); + //~^ iter_on_single_items assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123)); + //~^ iter_on_single_items assert_eq!(std::iter::once(&123).next(), Some(&123)); + //~^ iter_on_single_items // Don't trigger on non-iter methods let _: Option = Some("test".to_string()).clone(); diff --git a/tests/ui/iter_on_single_items.rs b/tests/ui/iter_on_single_items.rs index d059370d996c..625c96d3ef1f 100644 --- a/tests/ui/iter_on_single_items.rs +++ b/tests/ui/iter_on_single_items.rs @@ -3,11 +3,17 @@ fn array() { assert_eq!([123].into_iter().next(), Some(123)); + //~^ iter_on_single_items assert_eq!([123].iter_mut().next(), Some(&mut 123)); + //~^ iter_on_single_items assert_eq!([123].iter().next(), Some(&123)); + //~^ iter_on_single_items assert_eq!(Some(123).into_iter().next(), Some(123)); + //~^ iter_on_single_items assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); + //~^ iter_on_single_items assert_eq!(Some(123).iter().next(), Some(&123)); + //~^ iter_on_single_items // Don't trigger on non-iter methods let _: Option = Some("test".to_string()).clone(); diff --git a/tests/ui/iter_on_single_items.stderr b/tests/ui/iter_on_single_items.stderr index 0252c859581b..536e9eb36d88 100644 --- a/tests/ui/iter_on_single_items.stderr +++ b/tests/ui/iter_on_single_items.stderr @@ -8,31 +8,31 @@ LL | assert_eq!([123].into_iter().next(), Some(123)); = help: to override `-D warnings` add `#[allow(clippy::iter_on_single_items)]` error: `iter_mut` call on a collection with only one item - --> tests/ui/iter_on_single_items.rs:6:16 + --> tests/ui/iter_on_single_items.rs:7:16 | LL | assert_eq!([123].iter_mut().next(), Some(&mut 123)); | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)` error: `iter` call on a collection with only one item - --> tests/ui/iter_on_single_items.rs:7:16 + --> tests/ui/iter_on_single_items.rs:9:16 | LL | assert_eq!([123].iter().next(), Some(&123)); | ^^^^^^^^^^^^ help: try: `std::iter::once(&123)` error: `into_iter` call on a collection with only one item - --> tests/ui/iter_on_single_items.rs:8:16 + --> tests/ui/iter_on_single_items.rs:11:16 | LL | assert_eq!(Some(123).into_iter().next(), Some(123)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)` error: `iter_mut` call on a collection with only one item - --> tests/ui/iter_on_single_items.rs:9:16 + --> tests/ui/iter_on_single_items.rs:13:16 | LL | assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); | ^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)` error: `iter` call on a collection with only one item - --> tests/ui/iter_on_single_items.rs:10:16 + --> tests/ui/iter_on_single_items.rs:15:16 | LL | assert_eq!(Some(123).iter().next(), Some(&123)); | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&123)` diff --git a/tests/ui/iter_out_of_bounds.rs b/tests/ui/iter_out_of_bounds.rs index 3cfe6e82fc1e..243dce9939c1 100644 --- a/tests/ui/iter_out_of_bounds.rs +++ b/tests/ui/iter_out_of_bounds.rs @@ -10,57 +10,71 @@ fn opaque_empty_iter() -> impl Iterator { fn main() { #[allow(clippy::never_loop)] for _ in [1, 2, 3].iter().skip(4) { - //~^ ERROR: this `.skip()` call skips more items than the iterator will produce + //~^ iter_out_of_bounds + unreachable!(); } for (i, _) in [1, 2, 3].iter().take(4).enumerate() { - //~^ ERROR: this `.take()` call takes more items than the iterator will produce + //~^ iter_out_of_bounds + assert!(i <= 2); } #[allow(clippy::needless_borrow)] for _ in (&&&&&&[1, 2, 3]).iter().take(4) {} - //~^ ERROR: this `.take()` call takes more items than the iterator will produce + //~^ iter_out_of_bounds + for _ in [1, 2, 3].iter().skip(4) {} - //~^ ERROR: this `.skip()` call skips more items than the iterator will produce + //~^ iter_out_of_bounds + for _ in [1; 3].iter().skip(4) {} - //~^ ERROR: this `.skip()` call skips more items than the iterator will produce + //~^ iter_out_of_bounds + // Should not lint for _ in opaque_empty_iter().skip(1) {} for _ in vec![1, 2, 3].iter().skip(4) {} - //~^ ERROR: this `.skip()` call skips more items than the iterator will produce + //~^ iter_out_of_bounds + for _ in vec![1; 3].iter().skip(4) {} - //~^ ERROR: this `.skip()` call skips more items than the iterator will produce + //~^ iter_out_of_bounds + let x = [1, 2, 3]; for _ in x.iter().skip(4) {} - //~^ ERROR: this `.skip()` call skips more items than the iterator will produce + //~^ iter_out_of_bounds + let n = 4; for _ in x.iter().skip(n) {} - //~^ ERROR: this `.skip()` call skips more items than the iterator will produce + //~^ iter_out_of_bounds + let empty = std::iter::empty::; for _ in empty().skip(1) {} - //~^ ERROR: this `.skip()` call skips more items than the iterator will produce + //~^ iter_out_of_bounds + for _ in empty().take(1) {} - //~^ ERROR: this `.take()` call takes more items than the iterator will produce + //~^ iter_out_of_bounds + for _ in std::iter::once(1).skip(2) {} - //~^ ERROR: this `.skip()` call skips more items than the iterator will produce + //~^ iter_out_of_bounds + for _ in std::iter::once(1).take(2) {} - //~^ ERROR: this `.take()` call takes more items than the iterator will produce + //~^ iter_out_of_bounds + for x in [].iter().take(1) { - //~^ ERROR: this `.take()` call takes more items than the iterator will produce + //~^ iter_out_of_bounds + let _: &i32 = x; } diff --git a/tests/ui/iter_out_of_bounds.stderr b/tests/ui/iter_out_of_bounds.stderr index 96df04251fc9..42984e00e1d4 100644 --- a/tests/ui/iter_out_of_bounds.stderr +++ b/tests/ui/iter_out_of_bounds.stderr @@ -12,7 +12,7 @@ LL | #![deny(clippy::iter_out_of_bounds)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `.take()` call takes more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:16:19 + --> tests/ui/iter_out_of_bounds.rs:17:19 | LL | for (i, _) in [1, 2, 3].iter().take(4).enumerate() { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | for (i, _) in [1, 2, 3].iter().take(4).enumerate() { = note: this operation is useless and the returned iterator will simply yield the same items error: this `.take()` call takes more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:22:14 + --> tests/ui/iter_out_of_bounds.rs:24:14 | LL | for _ in (&&&&&&[1, 2, 3]).iter().take(4) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | for _ in (&&&&&&[1, 2, 3]).iter().take(4) {} = note: this operation is useless and the returned iterator will simply yield the same items error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:25:14 + --> tests/ui/iter_out_of_bounds.rs:28:14 | LL | for _ in [1, 2, 3].iter().skip(4) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | for _ in [1, 2, 3].iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:28:14 + --> tests/ui/iter_out_of_bounds.rs:32:14 | LL | for _ in [1; 3].iter().skip(4) {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | for _ in [1; 3].iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:34:14 + --> tests/ui/iter_out_of_bounds.rs:39:14 | LL | for _ in vec![1, 2, 3].iter().skip(4) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | for _ in vec![1, 2, 3].iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:37:14 + --> tests/ui/iter_out_of_bounds.rs:43:14 | LL | for _ in vec![1; 3].iter().skip(4) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | for _ in vec![1; 3].iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:41:14 + --> tests/ui/iter_out_of_bounds.rs:48:14 | LL | for _ in x.iter().skip(4) {} | ^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | for _ in x.iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:45:14 + --> tests/ui/iter_out_of_bounds.rs:53:14 | LL | for _ in x.iter().skip(n) {} | ^^^^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | for _ in x.iter().skip(n) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:50:14 + --> tests/ui/iter_out_of_bounds.rs:59:14 | LL | for _ in empty().skip(1) {} | ^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | for _ in empty().skip(1) {} = note: this operation is useless and will create an empty iterator error: this `.take()` call takes more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:53:14 + --> tests/ui/iter_out_of_bounds.rs:63:14 | LL | for _ in empty().take(1) {} | ^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL | for _ in empty().take(1) {} = note: this operation is useless and the returned iterator will simply yield the same items error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:56:14 + --> tests/ui/iter_out_of_bounds.rs:67:14 | LL | for _ in std::iter::once(1).skip(2) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | for _ in std::iter::once(1).skip(2) {} = note: this operation is useless and will create an empty iterator error: this `.take()` call takes more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:59:14 + --> tests/ui/iter_out_of_bounds.rs:71:14 | LL | for _ in std::iter::once(1).take(2) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | for _ in std::iter::once(1).take(2) {} = note: this operation is useless and the returned iterator will simply yield the same items error: this `.take()` call takes more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:62:14 + --> tests/ui/iter_out_of_bounds.rs:75:14 | LL | for x in [].iter().take(1) { | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/iter_over_hash_type.rs b/tests/ui/iter_over_hash_type.rs index 65bae1df4218..0dd9544cfe01 100644 --- a/tests/ui/iter_over_hash_type.rs +++ b/tests/ui/iter_over_hash_type.rs @@ -16,46 +16,59 @@ fn main() { // test hashset for x in &hash_set { + //~^ iter_over_hash_type let _ = x; } for x in hash_set.iter() { + //~^ iter_over_hash_type let _ = x; } for x in hash_set.clone() { + //~^ iter_over_hash_type let _ = x; } for x in hash_set.drain() { + //~^ iter_over_hash_type let _ = x; } // test hashmap for (x, y) in &hash_map { + //~^ iter_over_hash_type let _ = (x, y); } for x in hash_map.keys() { + //~^ iter_over_hash_type let _ = x; } for x in hash_map.values() { + //~^ iter_over_hash_type let _ = x; } for x in hash_map.values_mut() { + //~^ iter_over_hash_type *x += 1; } for x in hash_map.iter() { + //~^ iter_over_hash_type let _ = x; } for x in hash_map.clone() { + //~^ iter_over_hash_type let _ = x; } for x in hash_map.drain() { + //~^ iter_over_hash_type let _ = x; } // test type-aliased hashers for x in fx_hash_set { + //~^ iter_over_hash_type let _ = x; } for x in fx_hash_map { + //~^ iter_over_hash_type let _ = x; } diff --git a/tests/ui/iter_over_hash_type.stderr b/tests/ui/iter_over_hash_type.stderr index 6afe69ee20e1..1bc6f4588d44 100644 --- a/tests/ui/iter_over_hash_type.stderr +++ b/tests/ui/iter_over_hash_type.stderr @@ -2,6 +2,7 @@ error: iteration over unordered hash-based type --> tests/ui/iter_over_hash_type.rs:18:5 | LL | / for x in &hash_set { +LL | | LL | | let _ = x; LL | | } | |_____^ @@ -10,97 +11,109 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]` error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:21:5 + --> tests/ui/iter_over_hash_type.rs:22:5 | LL | / for x in hash_set.iter() { +LL | | LL | | let _ = x; LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:24:5 + --> tests/ui/iter_over_hash_type.rs:26:5 | LL | / for x in hash_set.clone() { +LL | | LL | | let _ = x; LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:27:5 + --> tests/ui/iter_over_hash_type.rs:30:5 | LL | / for x in hash_set.drain() { +LL | | LL | | let _ = x; LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:32:5 + --> tests/ui/iter_over_hash_type.rs:36:5 | LL | / for (x, y) in &hash_map { +LL | | LL | | let _ = (x, y); LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:35:5 + --> tests/ui/iter_over_hash_type.rs:40:5 | LL | / for x in hash_map.keys() { +LL | | LL | | let _ = x; LL | | } | |_____^ -error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:38:5 - | -LL | / for x in hash_map.values() { -LL | | let _ = x; -LL | | } - | |_____^ - -error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:41:5 - | -LL | / for x in hash_map.values_mut() { -LL | | *x += 1; -LL | | } - | |_____^ - error: iteration over unordered hash-based type --> tests/ui/iter_over_hash_type.rs:44:5 | -LL | / for x in hash_map.iter() { +LL | / for x in hash_map.values() { +LL | | LL | | let _ = x; LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:47:5 + --> tests/ui/iter_over_hash_type.rs:48:5 + | +LL | / for x in hash_map.values_mut() { +LL | | +LL | | *x += 1; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> tests/ui/iter_over_hash_type.rs:52:5 + | +LL | / for x in hash_map.iter() { +LL | | +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> tests/ui/iter_over_hash_type.rs:56:5 | LL | / for x in hash_map.clone() { +LL | | LL | | let _ = x; LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:50:5 + --> tests/ui/iter_over_hash_type.rs:60:5 | LL | / for x in hash_map.drain() { +LL | | LL | | let _ = x; LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:55:5 + --> tests/ui/iter_over_hash_type.rs:66:5 | LL | / for x in fx_hash_set { +LL | | LL | | let _ = x; LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:58:5 + --> tests/ui/iter_over_hash_type.rs:70:5 | LL | / for x in fx_hash_map { +LL | | LL | | let _ = x; LL | | } | |_____^ diff --git a/tests/ui/iter_overeager_cloned.fixed b/tests/ui/iter_overeager_cloned.fixed index d7d3d299349e..bc6cf76a58d8 100644 --- a/tests/ui/iter_overeager_cloned.fixed +++ b/tests/ui/iter_overeager_cloned.fixed @@ -10,36 +10,49 @@ fn main() { let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()]; let _: Option = vec.iter().last().cloned(); + //~^ iter_overeager_cloned let _: Option = vec.iter().chain(vec.iter()).next().cloned(); + //~^ iter_overeager_cloned let _: usize = vec.iter().filter(|x| x == &"2").count(); + //~^ redundant_clone let _: Vec<_> = vec.iter().take(2).cloned().collect(); + //~^ iter_overeager_cloned let _: Vec<_> = vec.iter().skip(2).cloned().collect(); + //~^ iter_overeager_cloned let _ = vec.iter().filter(|x| x == &"2").nth(2).cloned(); + //~^ iter_overeager_cloned let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))] + //~^ iter_overeager_cloned .iter() .flatten().cloned(); let _ = vec.iter().filter(|&x| x.starts_with('2')).cloned(); + //~^ iter_overeager_cloned let _ = vec.iter().find(|&x| x == "2").cloned(); + //~^ iter_overeager_cloned { let f = |x: &String| x.starts_with('2'); let _ = vec.iter().filter(|&x| f(x)).cloned(); + //~^ iter_overeager_cloned let _ = vec.iter().find(|&x| f(x)).cloned(); + //~^ iter_overeager_cloned } { let vec: Vec<(String, String)> = vec![]; let f = move |x: &(String, String)| x.0.starts_with('2'); let _ = vec.iter().filter(|&x| f(x)).cloned(); + //~^ iter_overeager_cloned let _ = vec.iter().find(|&x| f(x)).cloned(); + //~^ iter_overeager_cloned } fn test_move<'a>( @@ -47,6 +60,7 @@ fn main() { target: String, ) -> impl Iterator + 'a { iter.filter(move |&(&a, b)| a == 1 && b == &target).cloned() + //~^ iter_overeager_cloned } { @@ -58,19 +72,24 @@ fn main() { fn bar<'a>(iter: impl Iterator> + 'a, target: String) -> impl Iterator> + 'a { iter.filter(move |&S { a, b }| **a == 1 && b == &target).cloned() + //~^ iter_overeager_cloned } } let _ = vec.iter().map(|x| x.len()); + //~^ redundant_clone // This would fail if changed. let _ = vec.iter().cloned().map(|x| x + "2"); let _ = vec.iter().for_each(|x| assert!(!x.is_empty())); + //~^ redundant_clone let _ = vec.iter().all(|x| x.len() == 1); + //~^ redundant_clone let _ = vec.iter().any(|x| x.len() == 1); + //~^ redundant_clone // Should probably stay as it is. let _ = [0, 1, 2, 3, 4].iter().cloned().take(10); diff --git a/tests/ui/iter_overeager_cloned.rs b/tests/ui/iter_overeager_cloned.rs index 45e1349febd0..094760893c3e 100644 --- a/tests/ui/iter_overeager_cloned.rs +++ b/tests/ui/iter_overeager_cloned.rs @@ -10,37 +10,50 @@ fn main() { let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()]; let _: Option = vec.iter().cloned().last(); + //~^ iter_overeager_cloned let _: Option = vec.iter().chain(vec.iter()).cloned().next(); + //~^ iter_overeager_cloned let _: usize = vec.iter().filter(|x| x == &"2").cloned().count(); + //~^ redundant_clone let _: Vec<_> = vec.iter().cloned().take(2).collect(); + //~^ iter_overeager_cloned let _: Vec<_> = vec.iter().cloned().skip(2).collect(); + //~^ iter_overeager_cloned let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2); + //~^ iter_overeager_cloned let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))] + //~^ iter_overeager_cloned .iter() .cloned() .flatten(); let _ = vec.iter().cloned().filter(|x| x.starts_with('2')); + //~^ iter_overeager_cloned let _ = vec.iter().cloned().find(|x| x == "2"); + //~^ iter_overeager_cloned { let f = |x: &String| x.starts_with('2'); let _ = vec.iter().cloned().filter(f); + //~^ iter_overeager_cloned let _ = vec.iter().cloned().find(f); + //~^ iter_overeager_cloned } { let vec: Vec<(String, String)> = vec![]; let f = move |x: &(String, String)| x.0.starts_with('2'); let _ = vec.iter().cloned().filter(f); + //~^ iter_overeager_cloned let _ = vec.iter().cloned().find(f); + //~^ iter_overeager_cloned } fn test_move<'a>( @@ -48,6 +61,7 @@ fn main() { target: String, ) -> impl Iterator + 'a { iter.cloned().filter(move |(&a, b)| a == 1 && b == &target) + //~^ iter_overeager_cloned } { @@ -59,19 +73,24 @@ fn main() { fn bar<'a>(iter: impl Iterator> + 'a, target: String) -> impl Iterator> + 'a { iter.cloned().filter(move |S { a, b }| **a == 1 && b == &target) + //~^ iter_overeager_cloned } } let _ = vec.iter().cloned().map(|x| x.len()); + //~^ redundant_clone // This would fail if changed. let _ = vec.iter().cloned().map(|x| x + "2"); let _ = vec.iter().cloned().for_each(|x| assert!(!x.is_empty())); + //~^ redundant_clone let _ = vec.iter().cloned().all(|x| x.len() == 1); + //~^ redundant_clone let _ = vec.iter().cloned().any(|x| x.len() == 1); + //~^ redundant_clone // Should probably stay as it is. let _ = [0, 1, 2, 3, 4].iter().cloned().take(10); diff --git a/tests/ui/iter_overeager_cloned.stderr b/tests/ui/iter_overeager_cloned.stderr index e6680266f107..f3239b59582e 100644 --- a/tests/ui/iter_overeager_cloned.stderr +++ b/tests/ui/iter_overeager_cloned.stderr @@ -10,7 +10,7 @@ LL | let _: Option = vec.iter().cloned().last(); = help: to override `-D warnings` add `#[allow(clippy::iter_overeager_cloned)]` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:14:29 + --> tests/ui/iter_overeager_cloned.rs:15:29 | LL | let _: Option = vec.iter().chain(vec.iter()).cloned().next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------- @@ -18,7 +18,7 @@ LL | let _: Option = vec.iter().chain(vec.iter()).cloned().next(); | help: try: `.next().cloned()` error: unneeded cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:16:20 + --> tests/ui/iter_overeager_cloned.rs:18:20 | LL | let _: usize = vec.iter().filter(|x| x == &"2").cloned().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------- @@ -29,7 +29,7 @@ LL | let _: usize = vec.iter().filter(|x| x == &"2").cloned().count(); = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:18:21 + --> tests/ui/iter_overeager_cloned.rs:21:21 | LL | let _: Vec<_> = vec.iter().cloned().take(2).collect(); | ^^^^^^^^^^----------------- @@ -37,7 +37,7 @@ LL | let _: Vec<_> = vec.iter().cloned().take(2).collect(); | help: try: `.take(2).cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:20:21 + --> tests/ui/iter_overeager_cloned.rs:24:21 | LL | let _: Vec<_> = vec.iter().cloned().skip(2).collect(); | ^^^^^^^^^^----------------- @@ -45,7 +45,7 @@ LL | let _: Vec<_> = vec.iter().cloned().skip(2).collect(); | help: try: `.skip(2).cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:22:13 + --> tests/ui/iter_overeager_cloned.rs:27:13 | LL | let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------- @@ -53,10 +53,11 @@ LL | let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2); | help: try: `.nth(2).cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:24:13 + --> tests/ui/iter_overeager_cloned.rs:30:13 | LL | let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))] | _____________^ +LL | | LL | | .iter() LL | | .cloned() LL | | .flatten(); @@ -69,7 +70,7 @@ LL ~ .flatten().cloned(); | error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:29:13 + --> tests/ui/iter_overeager_cloned.rs:36:13 | LL | let _ = vec.iter().cloned().filter(|x| x.starts_with('2')); | ^^^^^^^^^^---------------------------------------- @@ -77,7 +78,7 @@ LL | let _ = vec.iter().cloned().filter(|x| x.starts_with('2')); | help: try: `.filter(|&x| x.starts_with('2')).cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:31:13 + --> tests/ui/iter_overeager_cloned.rs:39:13 | LL | let _ = vec.iter().cloned().find(|x| x == "2"); | ^^^^^^^^^^---------------------------- @@ -85,7 +86,7 @@ LL | let _ = vec.iter().cloned().find(|x| x == "2"); | help: try: `.find(|&x| x == "2").cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:35:17 + --> tests/ui/iter_overeager_cloned.rs:44:17 | LL | let _ = vec.iter().cloned().filter(f); | ^^^^^^^^^^------------------- @@ -93,7 +94,7 @@ LL | let _ = vec.iter().cloned().filter(f); | help: try: `.filter(|&x| f(x)).cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:36:17 + --> tests/ui/iter_overeager_cloned.rs:46:17 | LL | let _ = vec.iter().cloned().find(f); | ^^^^^^^^^^----------------- @@ -101,7 +102,7 @@ LL | let _ = vec.iter().cloned().find(f); | help: try: `.find(|&x| f(x)).cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:42:17 + --> tests/ui/iter_overeager_cloned.rs:53:17 | LL | let _ = vec.iter().cloned().filter(f); | ^^^^^^^^^^------------------- @@ -109,7 +110,7 @@ LL | let _ = vec.iter().cloned().filter(f); | help: try: `.filter(|&x| f(x)).cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:43:17 + --> tests/ui/iter_overeager_cloned.rs:55:17 | LL | let _ = vec.iter().cloned().find(f); | ^^^^^^^^^^----------------- @@ -117,7 +118,7 @@ LL | let _ = vec.iter().cloned().find(f); | help: try: `.find(|&x| f(x)).cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:50:9 + --> tests/ui/iter_overeager_cloned.rs:63:9 | LL | iter.cloned().filter(move |(&a, b)| a == 1 && b == &target) | ^^^^------------------------------------------------------- @@ -125,7 +126,7 @@ LL | iter.cloned().filter(move |(&a, b)| a == 1 && b == &target) | help: try: `.filter(move |&(&a, b)| a == 1 && b == &target).cloned()` error: unnecessarily eager cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:61:13 + --> tests/ui/iter_overeager_cloned.rs:75:13 | LL | iter.cloned().filter(move |S { a, b }| **a == 1 && b == &target) | ^^^^------------------------------------------------------------ @@ -133,7 +134,7 @@ LL | iter.cloned().filter(move |S { a, b }| **a == 1 && b == &target | help: try: `.filter(move |&S { a, b }| **a == 1 && b == &target).cloned()` error: unneeded cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:65:13 + --> tests/ui/iter_overeager_cloned.rs:80:13 | LL | let _ = vec.iter().cloned().map(|x| x.len()); | ^^^^^^^^^^-------------------------- @@ -141,7 +142,7 @@ LL | let _ = vec.iter().cloned().map(|x| x.len()); | help: try: `.map(|x| x.len())` error: unneeded cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:70:13 + --> tests/ui/iter_overeager_cloned.rs:86:13 | LL | let _ = vec.iter().cloned().for_each(|x| assert!(!x.is_empty())); | ^^^^^^^^^^---------------------------------------------- @@ -149,7 +150,7 @@ LL | let _ = vec.iter().cloned().for_each(|x| assert!(!x.is_empty())); | help: try: `.for_each(|x| assert!(!x.is_empty()))` error: unneeded cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:72:13 + --> tests/ui/iter_overeager_cloned.rs:89:13 | LL | let _ = vec.iter().cloned().all(|x| x.len() == 1); | ^^^^^^^^^^------------------------------- @@ -157,7 +158,7 @@ LL | let _ = vec.iter().cloned().all(|x| x.len() == 1); | help: try: `.all(|x| x.len() == 1)` error: unneeded cloning of iterator items - --> tests/ui/iter_overeager_cloned.rs:74:13 + --> tests/ui/iter_overeager_cloned.rs:92:13 | LL | let _ = vec.iter().cloned().any(|x| x.len() == 1); | ^^^^^^^^^^------------------------------- diff --git a/tests/ui/iter_skip_next.fixed b/tests/ui/iter_skip_next.fixed index 3e41b3632490..1d6a07f2d828 100644 --- a/tests/ui/iter_skip_next.fixed +++ b/tests/ui/iter_skip_next.fixed @@ -15,9 +15,13 @@ use option_helpers::IteratorFalsePositives; fn main() { let some_vec = vec![0, 1, 2, 3]; let _ = some_vec.iter().nth(42); + //~^ iter_skip_next let _ = some_vec.iter().cycle().nth(42); + //~^ iter_skip_next let _ = (1..10).nth(10); + //~^ iter_skip_next let _ = &some_vec[..].iter().nth(3); + //~^ iter_skip_next let foo = IteratorFalsePositives { foo: 0 }; let _ = foo.skip(42).next(); let _ = foo.filter().skip(42).next(); @@ -26,13 +30,16 @@ fn main() { let test_string = "1|1 2"; let mut sp = test_string.split('|').map(|s| s.trim()); let _: Vec<&str> = sp.nth(1).unwrap().split(' ').collect(); + //~^ iter_skip_next if let Some(mut s) = Some(test_string.split('|').map(|s| s.trim())) { let _: Vec<&str> = s.nth(1).unwrap().split(' ').collect(); + //~^ iter_skip_next }; fn check(mut s: T) where T: Iterator, { let _: Vec<&str> = s.nth(1).unwrap().split(' ').collect(); + //~^ iter_skip_next } } diff --git a/tests/ui/iter_skip_next.rs b/tests/ui/iter_skip_next.rs index 6d96441ca96f..7570e17a0925 100644 --- a/tests/ui/iter_skip_next.rs +++ b/tests/ui/iter_skip_next.rs @@ -15,9 +15,13 @@ use option_helpers::IteratorFalsePositives; fn main() { let some_vec = vec![0, 1, 2, 3]; let _ = some_vec.iter().skip(42).next(); + //~^ iter_skip_next let _ = some_vec.iter().cycle().skip(42).next(); + //~^ iter_skip_next let _ = (1..10).skip(10).next(); + //~^ iter_skip_next let _ = &some_vec[..].iter().skip(3).next(); + //~^ iter_skip_next let foo = IteratorFalsePositives { foo: 0 }; let _ = foo.skip(42).next(); let _ = foo.filter().skip(42).next(); @@ -26,13 +30,16 @@ fn main() { let test_string = "1|1 2"; let mut sp = test_string.split('|').map(|s| s.trim()); let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect(); + //~^ iter_skip_next if let Some(mut s) = Some(test_string.split('|').map(|s| s.trim())) { let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); + //~^ iter_skip_next }; fn check(mut s: T) where T: Iterator, { let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); + //~^ iter_skip_next } } diff --git a/tests/ui/iter_skip_next.stderr b/tests/ui/iter_skip_next.stderr index 0fa04465ff15..9f6d708c2f41 100644 --- a/tests/ui/iter_skip_next.stderr +++ b/tests/ui/iter_skip_next.stderr @@ -8,37 +8,37 @@ LL | let _ = some_vec.iter().skip(42).next(); = help: to override `-D warnings` add `#[allow(clippy::iter_skip_next)]` error: called `skip(..).next()` on an iterator - --> tests/ui/iter_skip_next.rs:18:36 + --> tests/ui/iter_skip_next.rs:19:36 | LL | let _ = some_vec.iter().cycle().skip(42).next(); | ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(42)` error: called `skip(..).next()` on an iterator - --> tests/ui/iter_skip_next.rs:19:20 + --> tests/ui/iter_skip_next.rs:21:20 | LL | let _ = (1..10).skip(10).next(); | ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(10)` error: called `skip(..).next()` on an iterator - --> tests/ui/iter_skip_next.rs:20:33 + --> tests/ui/iter_skip_next.rs:23:33 | LL | let _ = &some_vec[..].iter().skip(3).next(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(3)` error: called `skip(..).next()` on an iterator - --> tests/ui/iter_skip_next.rs:28:26 + --> tests/ui/iter_skip_next.rs:32:26 | LL | let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` error: called `skip(..).next()` on an iterator - --> tests/ui/iter_skip_next.rs:30:29 + --> tests/ui/iter_skip_next.rs:35:29 | LL | let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` error: called `skip(..).next()` on an iterator - --> tests/ui/iter_skip_next.rs:36:29 + --> tests/ui/iter_skip_next.rs:42:29 | LL | let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` diff --git a/tests/ui/iter_skip_next_unfixable.rs b/tests/ui/iter_skip_next_unfixable.rs index 6c98bdc8c880..273ccd25ddcc 100644 --- a/tests/ui/iter_skip_next_unfixable.rs +++ b/tests/ui/iter_skip_next_unfixable.rs @@ -7,16 +7,19 @@ fn main() { let test_string = "1|1 2"; let sp = test_string.split('|').map(|s| s.trim()); let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect(); - //~^ ERROR: called `skip(..).next()` on an iterator + //~^ iter_skip_next + if let Some(s) = Some(test_string.split('|').map(|s| s.trim())) { let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); - //~^ ERROR: called `skip(..).next()` on an iterator + //~^ iter_skip_next + }; fn check(s: T) where T: Iterator, { let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); - //~^ ERROR: called `skip(..).next()` on an iterator + //~^ iter_skip_next + } } diff --git a/tests/ui/iter_skip_next_unfixable.stderr b/tests/ui/iter_skip_next_unfixable.stderr index 9bfffb07ca62..cfbf75d85304 100644 --- a/tests/ui/iter_skip_next_unfixable.stderr +++ b/tests/ui/iter_skip_next_unfixable.stderr @@ -13,25 +13,25 @@ LL | let sp = test_string.split('|').map(|s| s.trim()); = help: to override `-D warnings` add `#[allow(clippy::iter_skip_next)]` error: called `skip(..).next()` on an iterator - --> tests/ui/iter_skip_next_unfixable.rs:12:29 + --> tests/ui/iter_skip_next_unfixable.rs:13:29 | LL | let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` | help: for this change `s` has to be mutable - --> tests/ui/iter_skip_next_unfixable.rs:11:17 + --> tests/ui/iter_skip_next_unfixable.rs:12:17 | LL | if let Some(s) = Some(test_string.split('|').map(|s| s.trim())) { | ^ error: called `skip(..).next()` on an iterator - --> tests/ui/iter_skip_next_unfixable.rs:19:29 + --> tests/ui/iter_skip_next_unfixable.rs:21:29 | LL | let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` | help: for this change `s` has to be mutable - --> tests/ui/iter_skip_next_unfixable.rs:15:17 + --> tests/ui/iter_skip_next_unfixable.rs:17:17 | LL | fn check(s: T) | ^ diff --git a/tests/ui/iter_skip_zero.fixed b/tests/ui/iter_skip_zero.fixed index 447d07100e95..498af9bb4ff6 100644 --- a/tests/ui/iter_skip_zero.fixed +++ b/tests/ui/iter_skip_zero.fixed @@ -9,9 +9,14 @@ use std::iter::once; fn main() { let _ = [1, 2, 3].iter().skip(1); + //~^ iter_skip_zero let _ = vec![1, 2, 3].iter().skip(1); + //~^ iter_skip_zero let _ = once([1, 2, 3]).skip(1); + //~^ iter_skip_zero let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(1)).skip(1); + //~^ iter_skip_zero + //~| iter_skip_zero // Don't lint let _ = [1, 2, 3].iter().skip(1); let _ = vec![1, 2, 3].iter().skip(1); diff --git a/tests/ui/iter_skip_zero.rs b/tests/ui/iter_skip_zero.rs index ba63c3981808..f168e9109953 100644 --- a/tests/ui/iter_skip_zero.rs +++ b/tests/ui/iter_skip_zero.rs @@ -9,9 +9,14 @@ use std::iter::once; fn main() { let _ = [1, 2, 3].iter().skip(0); + //~^ iter_skip_zero let _ = vec![1, 2, 3].iter().skip(0); + //~^ iter_skip_zero let _ = once([1, 2, 3]).skip(0); + //~^ iter_skip_zero let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0); + //~^ iter_skip_zero + //~| iter_skip_zero // Don't lint let _ = [1, 2, 3].iter().skip(1); let _ = vec![1, 2, 3].iter().skip(1); diff --git a/tests/ui/iter_skip_zero.stderr b/tests/ui/iter_skip_zero.stderr index ef46db843377..235074374aa1 100644 --- a/tests/ui/iter_skip_zero.stderr +++ b/tests/ui/iter_skip_zero.stderr @@ -9,7 +9,7 @@ LL | let _ = [1, 2, 3].iter().skip(0); = help: to override `-D warnings` add `#[allow(clippy::iter_skip_zero)]` error: usage of `.skip(0)` - --> tests/ui/iter_skip_zero.rs:12:39 + --> tests/ui/iter_skip_zero.rs:13:39 | LL | let _ = vec![1, 2, 3].iter().skip(0); | ^ help: if you meant to skip the first element, use: `1` @@ -17,7 +17,7 @@ LL | let _ = vec![1, 2, 3].iter().skip(0); = note: this call to `skip` does nothing and is useless; remove it error: usage of `.skip(0)` - --> tests/ui/iter_skip_zero.rs:13:34 + --> tests/ui/iter_skip_zero.rs:15:34 | LL | let _ = once([1, 2, 3]).skip(0); | ^ help: if you meant to skip the first element, use: `1` @@ -25,7 +25,7 @@ LL | let _ = once([1, 2, 3]).skip(0); = note: this call to `skip` does nothing and is useless; remove it error: usage of `.skip(0)` - --> tests/ui/iter_skip_zero.rs:14:71 + --> tests/ui/iter_skip_zero.rs:17:71 | LL | let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0); | ^ help: if you meant to skip the first element, use: `1` @@ -33,7 +33,7 @@ LL | let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0); = note: this call to `skip` does nothing and is useless; remove it error: usage of `.skip(0)` - --> tests/ui/iter_skip_zero.rs:14:62 + --> tests/ui/iter_skip_zero.rs:17:62 | LL | let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0); | ^ help: if you meant to skip the first element, use: `1` diff --git a/tests/ui/iter_with_drain.fixed b/tests/ui/iter_with_drain.fixed index a03efceed4ca..b0661ffb981b 100644 --- a/tests/ui/iter_with_drain.fixed +++ b/tests/ui/iter_with_drain.fixed @@ -8,20 +8,26 @@ use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; fn full() { let mut a = vec!["aaa".to_string(), "bbb".to_string()]; let mut a: BinaryHeap<_> = a.into_iter().collect(); + //~^ iter_with_drain let mut a: HashSet<_> = a.drain().collect(); let mut a: VecDeque<_> = a.drain().collect(); let mut a: Vec<_> = a.into_iter().collect(); + //~^ iter_with_drain let mut a: HashMap<_, _> = a.into_iter().map(|x| (x.clone(), x)).collect(); + //~^ iter_with_drain let _: Vec<(String, String)> = a.drain().collect(); } fn closed() { let mut a = vec!["aaa".to_string(), "bbb".to_string()]; let mut a: BinaryHeap<_> = a.into_iter().collect(); + //~^ iter_with_drain let mut a: HashSet<_> = a.drain().collect(); let mut a: VecDeque<_> = a.drain().collect(); let mut a: Vec<_> = a.into_iter().collect(); + //~^ iter_with_drain let mut a: HashMap<_, _> = a.into_iter().map(|x| (x.clone(), x)).collect(); + //~^ iter_with_drain let _: Vec<(String, String)> = a.drain().collect(); } diff --git a/tests/ui/iter_with_drain.rs b/tests/ui/iter_with_drain.rs index a8cd47f83d04..746b0f9a5eda 100644 --- a/tests/ui/iter_with_drain.rs +++ b/tests/ui/iter_with_drain.rs @@ -8,20 +8,26 @@ use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; fn full() { let mut a = vec!["aaa".to_string(), "bbb".to_string()]; let mut a: BinaryHeap<_> = a.drain(..).collect(); + //~^ iter_with_drain let mut a: HashSet<_> = a.drain().collect(); let mut a: VecDeque<_> = a.drain().collect(); let mut a: Vec<_> = a.drain(..).collect(); + //~^ iter_with_drain let mut a: HashMap<_, _> = a.drain(..).map(|x| (x.clone(), x)).collect(); + //~^ iter_with_drain let _: Vec<(String, String)> = a.drain().collect(); } fn closed() { let mut a = vec!["aaa".to_string(), "bbb".to_string()]; let mut a: BinaryHeap<_> = a.drain(0..).collect(); + //~^ iter_with_drain let mut a: HashSet<_> = a.drain().collect(); let mut a: VecDeque<_> = a.drain().collect(); let mut a: Vec<_> = a.drain(..a.len()).collect(); + //~^ iter_with_drain let mut a: HashMap<_, _> = a.drain(0..a.len()).map(|x| (x.clone(), x)).collect(); + //~^ iter_with_drain let _: Vec<(String, String)> = a.drain().collect(); } diff --git a/tests/ui/iter_with_drain.stderr b/tests/ui/iter_with_drain.stderr index 265e18c263be..370658961b9b 100644 --- a/tests/ui/iter_with_drain.stderr +++ b/tests/ui/iter_with_drain.stderr @@ -8,31 +8,31 @@ LL | let mut a: BinaryHeap<_> = a.drain(..).collect(); = help: to override `-D warnings` add `#[allow(clippy::iter_with_drain)]` error: `drain(..)` used on a `VecDeque` - --> tests/ui/iter_with_drain.rs:13:27 + --> tests/ui/iter_with_drain.rs:14:27 | LL | let mut a: Vec<_> = a.drain(..).collect(); | ^^^^^^^^^ help: try: `into_iter()` error: `drain(..)` used on a `Vec` - --> tests/ui/iter_with_drain.rs:14:34 + --> tests/ui/iter_with_drain.rs:16:34 | LL | let mut a: HashMap<_, _> = a.drain(..).map(|x| (x.clone(), x)).collect(); | ^^^^^^^^^ help: try: `into_iter()` error: `drain(..)` used on a `Vec` - --> tests/ui/iter_with_drain.rs:20:34 + --> tests/ui/iter_with_drain.rs:23:34 | LL | let mut a: BinaryHeap<_> = a.drain(0..).collect(); | ^^^^^^^^^^ help: try: `into_iter()` error: `drain(..)` used on a `VecDeque` - --> tests/ui/iter_with_drain.rs:23:27 + --> tests/ui/iter_with_drain.rs:27:27 | LL | let mut a: Vec<_> = a.drain(..a.len()).collect(); | ^^^^^^^^^^^^^^^^ help: try: `into_iter()` error: `drain(..)` used on a `Vec` - --> tests/ui/iter_with_drain.rs:24:34 + --> tests/ui/iter_with_drain.rs:29:34 | LL | let mut a: HashMap<_, _> = a.drain(0..a.len()).map(|x| (x.clone(), x)).collect(); | ^^^^^^^^^^^^^^^^^ help: try: `into_iter()` diff --git a/tests/ui/iter_without_into_iter.rs b/tests/ui/iter_without_into_iter.rs index d5b28e45453b..80fb736b9bde 100644 --- a/tests/ui/iter_without_into_iter.rs +++ b/tests/ui/iter_without_into_iter.rs @@ -7,11 +7,11 @@ extern crate proc_macros; pub struct S1; impl S1 { pub fn iter(&self) -> std::slice::Iter<'_, u8> { - //~^ ERROR: `iter` method without an `IntoIterator` impl + //~^ iter_without_into_iter [].iter() } pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { - //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + //~^ iter_without_into_iter [].iter_mut() } } @@ -27,11 +27,11 @@ impl S2 { pub struct S3<'a>(&'a mut [u8]); impl<'a> S3<'a> { pub fn iter(&self) -> std::slice::Iter<'_, u8> { - //~^ ERROR: `iter` method without an `IntoIterator` impl + //~^ iter_without_into_iter self.0.iter() } pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { - //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + //~^ iter_without_into_iter self.0.iter_mut() } } @@ -68,6 +68,7 @@ impl S7 { pub struct S8(T); impl S8 { pub fn iter(&self) -> std::slice::Iter<'static, T> { + //~^ iter_without_into_iter todo!() } } @@ -76,11 +77,11 @@ impl S8 { pub struct S9(T); impl S9 { pub fn iter(&self) -> std::slice::Iter<'_, T> { - //~^ ERROR: `iter` method without an `IntoIterator` impl + //~^ iter_without_into_iter todo!() } pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { - //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + //~^ iter_without_into_iter todo!() } } @@ -129,6 +130,7 @@ macro_rules! generate_impl { () => { impl Issue12037 { fn iter(&self) -> std::slice::Iter<'_, u8> { + //~^ iter_without_into_iter todo!() } } diff --git a/tests/ui/iter_without_into_iter.stderr b/tests/ui/iter_without_into_iter.stderr index d748c85003bb..8f86bee09670 100644 --- a/tests/ui/iter_without_into_iter.stderr +++ b/tests/ui/iter_without_into_iter.stderr @@ -88,6 +88,7 @@ error: `iter` method without an `IntoIterator` impl for `&S8` --> tests/ui/iter_without_into_iter.rs:70:5 | LL | / pub fn iter(&self) -> std::slice::Iter<'static, T> { +LL | | LL | | todo!() LL | | } | |_____^ @@ -105,7 +106,7 @@ LL + } | error: `iter` method without an `IntoIterator` impl for `&S9` - --> tests/ui/iter_without_into_iter.rs:78:5 + --> tests/ui/iter_without_into_iter.rs:79:5 | LL | / pub fn iter(&self) -> std::slice::Iter<'_, T> { LL | | @@ -126,7 +127,7 @@ LL + } | error: `iter_mut` method without an `IntoIterator` impl for `&mut S9` - --> tests/ui/iter_without_into_iter.rs:82:5 + --> tests/ui/iter_without_into_iter.rs:83:5 | LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { LL | | @@ -147,9 +148,10 @@ LL + } | error: `iter` method without an `IntoIterator` impl for `&Issue12037` - --> tests/ui/iter_without_into_iter.rs:131:13 + --> tests/ui/iter_without_into_iter.rs:132:13 | LL | / fn iter(&self) -> std::slice::Iter<'_, u8> { +LL | | LL | | todo!() LL | | } | |_____________^ diff --git a/tests/ui/iterator_step_by_zero.rs b/tests/ui/iterator_step_by_zero.rs index 0b51842df2e3..c416095cb426 100644 --- a/tests/ui/iterator_step_by_zero.rs +++ b/tests/ui/iterator_step_by_zero.rs @@ -2,12 +2,15 @@ #[warn(clippy::iterator_step_by_zero)] fn main() { let _ = vec!["A", "B", "B"].iter().step_by(0); - //~^ ERROR: `Iterator::step_by(0)` will panic at runtime - //~| NOTE: `-D clippy::iterator-step-by-zero` implied by `-D warnings` + //~^ iterator_step_by_zero + + let _ = "XXX".chars().step_by(0); - //~^ ERROR: `Iterator::step_by(0)` will panic at runtime + //~^ iterator_step_by_zero + let _ = (0..1).step_by(0); - //~^ ERROR: `Iterator::step_by(0)` will panic at runtime + //~^ iterator_step_by_zero + // No error, not an iterator. let y = NotIterator; @@ -17,18 +20,22 @@ fn main() { let _ = (0..1).step_by(1); let _ = (1..).step_by(0); - //~^ ERROR: `Iterator::step_by(0)` will panic at runtime + //~^ iterator_step_by_zero + let _ = (1..=2).step_by(0); - //~^ ERROR: `Iterator::step_by(0)` will panic at runtime + //~^ iterator_step_by_zero + let x = 0..1; let _ = x.step_by(0); - //~^ ERROR: `Iterator::step_by(0)` will panic at runtime + //~^ iterator_step_by_zero + // check const eval let v1 = vec![1, 2, 3]; let _ = v1.iter().step_by(2 / 3); - //~^ ERROR: `Iterator::step_by(0)` will panic at runtime + //~^ iterator_step_by_zero + } struct NotIterator; diff --git a/tests/ui/iterator_step_by_zero.stderr b/tests/ui/iterator_step_by_zero.stderr index 4156642d6dbb..8cc79a978bca 100644 --- a/tests/ui/iterator_step_by_zero.stderr +++ b/tests/ui/iterator_step_by_zero.stderr @@ -8,37 +8,37 @@ LL | let _ = vec!["A", "B", "B"].iter().step_by(0); = help: to override `-D warnings` add `#[allow(clippy::iterator_step_by_zero)]` error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:7:13 + --> tests/ui/iterator_step_by_zero.rs:8:13 | LL | let _ = "XXX".chars().step_by(0); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:9:13 + --> tests/ui/iterator_step_by_zero.rs:11:13 | LL | let _ = (0..1).step_by(0); | ^^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:19:13 + --> tests/ui/iterator_step_by_zero.rs:22:13 | LL | let _ = (1..).step_by(0); | ^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:21:13 + --> tests/ui/iterator_step_by_zero.rs:25:13 | LL | let _ = (1..=2).step_by(0); | ^^^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:25:13 + --> tests/ui/iterator_step_by_zero.rs:30:13 | LL | let _ = x.step_by(0); | ^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:30:13 + --> tests/ui/iterator_step_by_zero.rs:36:13 | LL | let _ = v1.iter().step_by(2 / 3); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/join_absolute_paths.rs b/tests/ui/join_absolute_paths.rs index efa77a0492e6..ada160d963a6 100644 --- a/tests/ui/join_absolute_paths.rs +++ b/tests/ui/join_absolute_paths.rs @@ -8,19 +8,23 @@ use std::path::{Path, PathBuf}; fn main() { let path = Path::new("/bin"); path.join("/sh"); - //~^ ERROR: argument to `Path::join` starts with a path separator + //~^ join_absolute_paths + let path = Path::new("C:\\Users"); path.join("\\user"); - //~^ ERROR: argument to `Path::join` starts with a path separator + //~^ join_absolute_paths + let path = PathBuf::from("/bin"); path.join("/sh"); - //~^ ERROR: argument to `Path::join` starts with a path separator + //~^ join_absolute_paths + let path = PathBuf::from("/bin"); path.join(r#"/sh"#); - //~^ ERROR: argument to `Path::join` starts with a path separator + //~^ join_absolute_paths + let path: &[&str] = &["/bin"]; path.join("/sh"); diff --git a/tests/ui/join_absolute_paths.stderr b/tests/ui/join_absolute_paths.stderr index e7fd5508823a..94e8beb38446 100644 --- a/tests/ui/join_absolute_paths.stderr +++ b/tests/ui/join_absolute_paths.stderr @@ -17,7 +17,7 @@ LL | PathBuf::from("/sh"); | ~~~~~~~~~~~~~~~~~~~~ error: argument to `Path::join` starts with a path separator - --> tests/ui/join_absolute_paths.rs:14:15 + --> tests/ui/join_absolute_paths.rs:15:15 | LL | path.join("\\user"); | ^^^^^^^^ @@ -33,7 +33,7 @@ LL | PathBuf::from("\\user"); | ~~~~~~~~~~~~~~~~~~~~~~~ error: argument to `Path::join` starts with a path separator - --> tests/ui/join_absolute_paths.rs:18:15 + --> tests/ui/join_absolute_paths.rs:20:15 | LL | path.join("/sh"); | ^^^^^ @@ -49,7 +49,7 @@ LL | PathBuf::from("/sh"); | ~~~~~~~~~~~~~~~~~~~~ error: argument to `Path::join` starts with a path separator - --> tests/ui/join_absolute_paths.rs:22:15 + --> tests/ui/join_absolute_paths.rs:25:15 | LL | path.join(r#"/sh"#); | ^^^^^^^^ diff --git a/tests/ui/large_const_arrays.fixed b/tests/ui/large_const_arrays.fixed index e5b28cb6a9dd..7c3868fc8ffd 100644 --- a/tests/ui/large_const_arrays.fixed +++ b/tests/ui/large_const_arrays.fixed @@ -8,9 +8,13 @@ pub struct S { // Should lint pub(crate) static FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000]; +//~^ large_const_arrays pub static FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; +//~^ large_const_arrays static FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100]; +//~^ large_const_arrays static FOO: [u32; 1_000_000] = [0u32; 1_000_000]; +//~^ large_const_arrays // Good pub(crate) const G_FOO_PUB_CRATE: [u32; 250] = [0u32; 250]; @@ -21,11 +25,17 @@ const G_FOO: [u32; 250] = [0u32; 250]; fn main() { // Should lint pub static BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; + //~^ large_const_arrays static BAR: [u32; 1_000_000] = [0u32; 1_000_000]; + //~^ large_const_arrays pub static BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000]; + //~^ large_const_arrays static BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000]; + //~^ large_const_arrays pub static BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000]; + //~^ large_const_arrays static BAR_S: [Option<&str>; 200_000] = [Some("str"); 200_000]; + //~^ large_const_arrays // Good pub const G_BAR_PUB: [u32; 250] = [0u32; 250]; diff --git a/tests/ui/large_const_arrays.rs b/tests/ui/large_const_arrays.rs index b9593225da2f..3e811520f063 100644 --- a/tests/ui/large_const_arrays.rs +++ b/tests/ui/large_const_arrays.rs @@ -8,9 +8,13 @@ pub struct S { // Should lint pub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000]; +//~^ large_const_arrays pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; +//~^ large_const_arrays const FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100]; +//~^ large_const_arrays const FOO: [u32; 1_000_000] = [0u32; 1_000_000]; +//~^ large_const_arrays // Good pub(crate) const G_FOO_PUB_CRATE: [u32; 250] = [0u32; 250]; @@ -21,11 +25,17 @@ const G_FOO: [u32; 250] = [0u32; 250]; fn main() { // Should lint pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; + //~^ large_const_arrays const BAR: [u32; 1_000_000] = [0u32; 1_000_000]; + //~^ large_const_arrays pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000]; + //~^ large_const_arrays const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000]; + //~^ large_const_arrays pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000]; + //~^ large_const_arrays const BAR_S: [Option<&str>; 200_000] = [Some("str"); 200_000]; + //~^ large_const_arrays // Good pub const G_BAR_PUB: [u32; 250] = [0u32; 250]; diff --git a/tests/ui/large_const_arrays.stderr b/tests/ui/large_const_arrays.stderr index 271122053908..56cddeaf628d 100644 --- a/tests/ui/large_const_arrays.stderr +++ b/tests/ui/large_const_arrays.stderr @@ -10,7 +10,7 @@ LL | pub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000]; = help: to override `-D warnings` add `#[allow(clippy::large_const_arrays)]` error: large array defined as const - --> tests/ui/large_const_arrays.rs:11:1 + --> tests/ui/large_const_arrays.rs:12:1 | LL | pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | help: make this a static item: `static` error: large array defined as const - --> tests/ui/large_const_arrays.rs:12:1 + --> tests/ui/large_const_arrays.rs:14:1 | LL | const FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100]; | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | const FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100]; | help: make this a static item: `static` error: large array defined as const - --> tests/ui/large_const_arrays.rs:13:1 + --> tests/ui/large_const_arrays.rs:16:1 | LL | const FOO: [u32; 1_000_000] = [0u32; 1_000_000]; | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | const FOO: [u32; 1_000_000] = [0u32; 1_000_000]; | help: make this a static item: `static` error: large array defined as const - --> tests/ui/large_const_arrays.rs:23:5 + --> tests/ui/large_const_arrays.rs:27:5 | LL | pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000]; | help: make this a static item: `static` error: large array defined as const - --> tests/ui/large_const_arrays.rs:24:5 + --> tests/ui/large_const_arrays.rs:29:5 | LL | const BAR: [u32; 1_000_000] = [0u32; 1_000_000]; | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | const BAR: [u32; 1_000_000] = [0u32; 1_000_000]; | help: make this a static item: `static` error: large array defined as const - --> tests/ui/large_const_arrays.rs:25:5 + --> tests/ui/large_const_arrays.rs:31:5 | LL | pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -58,7 +58,7 @@ LL | pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | help: make this a static item: `static` error: large array defined as const - --> tests/ui/large_const_arrays.rs:26:5 + --> tests/ui/large_const_arrays.rs:33:5 | LL | const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000]; | help: make this a static item: `static` error: large array defined as const - --> tests/ui/large_const_arrays.rs:27:5 + --> tests/ui/large_const_arrays.rs:35:5 | LL | pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000]; | ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000]; | help: make this a static item: `static` error: large array defined as const - --> tests/ui/large_const_arrays.rs:28:5 + --> tests/ui/large_const_arrays.rs:37:5 | LL | const BAR_S: [Option<&str>; 200_000] = [Some("str"); 200_000]; | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/large_digit_groups.fixed b/tests/ui/large_digit_groups.fixed index cdb001e47e2b..0ad2ebf522b8 100644 --- a/tests/ui/large_digit_groups.fixed +++ b/tests/ui/large_digit_groups.fixed @@ -20,10 +20,15 @@ fn main() { let _bad = ( 0b1_10110_i64, 0xdead_beef_usize, + //~^ unusual_byte_groupings 123_456_f32, + //~^ large_digit_groups 123_456.12_f32, + //~^ large_digit_groups 123_456.123_45_f64, + //~^ large_digit_groups 123_456.123_456_f64, + //~^ large_digit_groups ); // Ignore literals in macros let _ = mac!(); diff --git a/tests/ui/large_digit_groups.rs b/tests/ui/large_digit_groups.rs index 3c30c8670284..1cf489fd69b2 100644 --- a/tests/ui/large_digit_groups.rs +++ b/tests/ui/large_digit_groups.rs @@ -20,10 +20,15 @@ fn main() { let _bad = ( 0b1_10110_i64, 0xd_e_adbee_f_usize, + //~^ unusual_byte_groupings 1_23456_f32, + //~^ large_digit_groups 1_23456.12_f32, + //~^ large_digit_groups 1_23456.12345_f64, + //~^ large_digit_groups 1_23456.12345_6_f64, + //~^ large_digit_groups ); // Ignore literals in macros let _ = mac!(); diff --git a/tests/ui/large_digit_groups.stderr b/tests/ui/large_digit_groups.stderr index da34a91bc3bc..281a6267c8d6 100644 --- a/tests/ui/large_digit_groups.stderr +++ b/tests/ui/large_digit_groups.stderr @@ -8,7 +8,7 @@ LL | 0xd_e_adbee_f_usize, = help: to override `-D warnings` add `#[allow(clippy::unusual_byte_groupings)]` error: digit groups should be smaller - --> tests/ui/large_digit_groups.rs:23:9 + --> tests/ui/large_digit_groups.rs:24:9 | LL | 1_23456_f32, | ^^^^^^^^^^^ help: consider: `123_456_f32` @@ -17,19 +17,19 @@ LL | 1_23456_f32, = help: to override `-D warnings` add `#[allow(clippy::large_digit_groups)]` error: digit groups should be smaller - --> tests/ui/large_digit_groups.rs:24:9 + --> tests/ui/large_digit_groups.rs:26:9 | LL | 1_23456.12_f32, | ^^^^^^^^^^^^^^ help: consider: `123_456.12_f32` error: digit groups should be smaller - --> tests/ui/large_digit_groups.rs:25:9 + --> tests/ui/large_digit_groups.rs:28:9 | LL | 1_23456.12345_f64, | ^^^^^^^^^^^^^^^^^ help: consider: `123_456.123_45_f64` error: digit groups should be smaller - --> tests/ui/large_digit_groups.rs:26:9 + --> tests/ui/large_digit_groups.rs:30:9 | LL | 1_23456.12345_6_f64, | ^^^^^^^^^^^^^^^^^^^ help: consider: `123_456.123_456_f64` diff --git a/tests/ui/large_enum_variant.64bit.stderr b/tests/ui/large_enum_variant.64bit.stderr index 31576a5863fc..8f70ad2b5b72 100644 --- a/tests/ui/large_enum_variant.64bit.stderr +++ b/tests/ui/large_enum_variant.64bit.stderr @@ -2,6 +2,7 @@ error: large size difference between variants --> tests/ui/large_enum_variant.rs:11:1 | LL | / enum LargeEnum { +LL | | LL | | A(i32), | | ------ the second-largest variant contains at least 4 bytes LL | | B([i32; 8000]), @@ -17,9 +18,10 @@ LL | B(Box<[i32; 8000]>), | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:35:1 + --> tests/ui/large_enum_variant.rs:36:1 | LL | / enum LargeEnum2 { +LL | | LL | | VariantOk(i32, u32), | | ------------------- the second-largest variant contains at least 8 bytes LL | | ContainingLargeEnum(LargeEnum), @@ -33,9 +35,10 @@ LL | ContainingLargeEnum(Box), | ~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:40:1 + --> tests/ui/large_enum_variant.rs:42:1 | LL | / enum LargeEnum3 { +LL | | LL | | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), | | --------------------------------------------------------- the largest variant contains at least 70004 bytes LL | | VoidVariant, @@ -50,9 +53,10 @@ LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:46:1 + --> tests/ui/large_enum_variant.rs:49:1 | LL | / enum LargeEnum4 { +LL | | LL | | VariantOk(i32, u32), | | ------------------- the second-largest variant contains at least 8 bytes LL | | StructLikeLarge { x: [i32; 8000], y: i32 }, @@ -66,9 +70,10 @@ LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:51:1 + --> tests/ui/large_enum_variant.rs:55:1 | LL | / enum LargeEnum5 { +LL | | LL | | VariantOk(i32, u32), | | ------------------- the second-largest variant contains at least 8 bytes LL | | StructLikeLarge2 { x: [i32; 8000] }, @@ -82,9 +87,10 @@ LL | StructLikeLarge2 { x: Box<[i32; 8000]> }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:67:1 + --> tests/ui/large_enum_variant.rs:72:1 | LL | / enum LargeEnum7 { +LL | | LL | | A, LL | | B([u8; 1255]), | | ------------- the largest variant contains at least 1255 bytes @@ -99,9 +105,10 @@ LL | B(Box<[u8; 1255]>), | ~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:73:1 + --> tests/ui/large_enum_variant.rs:79:1 | LL | / enum LargeEnum8 { +LL | | LL | | VariantOk(i32, u32), | | ------------------- the second-largest variant contains at least 8 bytes LL | | ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), @@ -115,9 +122,10 @@ LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]> | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:78:1 + --> tests/ui/large_enum_variant.rs:85:1 | LL | / enum LargeEnum9 { +LL | | LL | | A(Struct<()>), | | ------------- the second-largest variant contains at least 4 bytes LL | | B(Struct2), @@ -131,9 +139,10 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:83:1 + --> tests/ui/large_enum_variant.rs:91:1 | LL | / enum LargeEnumOk2 { +LL | | LL | | A(T), | | ---- the second-largest variant contains at least 0 bytes LL | | B(Struct2), @@ -147,9 +156,10 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:88:1 + --> tests/ui/large_enum_variant.rs:97:1 | LL | / enum LargeEnumOk3 { +LL | | LL | | A(Struct), | | ------------ the second-largest variant contains at least 4 bytes LL | | B(Struct2), @@ -163,9 +173,10 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:103:1 + --> tests/ui/large_enum_variant.rs:113:1 | LL | / enum CopyableLargeEnum { +LL | | LL | | A(bool), | | ------- the second-largest variant contains at least 1 bytes LL | | B([u64; 8000]), @@ -174,20 +185,21 @@ LL | | } | |_^ the entire enum is at least 64008 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:103:6 + --> tests/ui/large_enum_variant.rs:113:6 | LL | enum CopyableLargeEnum { | ^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:105:5 + --> tests/ui/large_enum_variant.rs:116:5 | LL | B([u64; 8000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:108:1 + --> tests/ui/large_enum_variant.rs:119:1 | LL | / enum ManuallyCopyLargeEnum { +LL | | LL | | A(bool), | | ------- the second-largest variant contains at least 1 bytes LL | | B([u64; 8000]), @@ -196,20 +208,21 @@ LL | | } | |_^ the entire enum is at least 64008 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:108:6 + --> tests/ui/large_enum_variant.rs:119:6 | LL | enum ManuallyCopyLargeEnum { | ^^^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:110:5 + --> tests/ui/large_enum_variant.rs:122:5 | LL | B([u64; 8000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:121:1 + --> tests/ui/large_enum_variant.rs:133:1 | LL | / enum SomeGenericPossiblyCopyEnum { +LL | | LL | | A(bool, std::marker::PhantomData), | | ------------------------------------ the second-largest variant contains at least 1 bytes LL | | B([u64; 4000]), @@ -218,20 +231,21 @@ LL | | } | |_^ the entire enum is at least 32008 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:121:6 + --> tests/ui/large_enum_variant.rs:133:6 | LL | enum SomeGenericPossiblyCopyEnum { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:123:5 + --> tests/ui/large_enum_variant.rs:136:5 | LL | B([u64; 4000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:134:1 + --> tests/ui/large_enum_variant.rs:147:1 | LL | / enum LargeEnumWithGenerics { +LL | | LL | | Small, | | ----- the second-largest variant carries no data at all LL | | Large((T, [u8; 512])), @@ -245,9 +259,10 @@ LL | Large(Box<(T, [u8; 512])>), | ~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:143:1 + --> tests/ui/large_enum_variant.rs:157:1 | LL | / enum WithGenerics { +LL | | LL | | Large([Foo; 64]), | | --------------------- the largest variant contains at least 512 bytes LL | | Small(u8), @@ -261,9 +276,10 @@ LL | Large(Box<[Foo; 64]>), | ~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:153:1 + --> tests/ui/large_enum_variant.rs:168:1 | LL | / enum LargeEnumOfConst { +LL | | LL | | Ok, | | -- the second-largest variant carries no data at all LL | | Error(PossiblyLargeEnumWithConst<256>), @@ -277,9 +293,10 @@ LL | Error(Box>), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:158:1 + --> tests/ui/large_enum_variant.rs:174:1 | LL | / enum WithRecursion { +LL | | LL | | Large([u64; 64]), | | ---------------- the largest variant contains at least 512 bytes LL | | Recursive(Box), @@ -293,9 +310,10 @@ LL | Large(Box<[u64; 64]>), | ~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:168:1 + --> tests/ui/large_enum_variant.rs:185:1 | LL | / enum LargeEnumWithGenericsAndRecursive { +LL | | LL | | Ok(), | | ---- the second-largest variant carries no data at all LL | | Error(WithRecursionAndGenerics), @@ -309,9 +327,10 @@ LL | Error(Box>), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:203:5 + --> tests/ui/large_enum_variant.rs:221:5 | LL | / enum NoWarnings { +LL | | LL | | BigBoi(PublishWithBytes), | | ------------------------ the largest variant contains at least 296 bytes LL | | _SmallBoi(u8), @@ -325,9 +344,10 @@ LL | BigBoi(Box), | ~~~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:208:5 + --> tests/ui/large_enum_variant.rs:227:5 | LL | / enum MakesClippyAngry { +LL | | LL | | BigBoi(PublishWithVec), | | ---------------------- the largest variant contains at least 224 bytes LL | | _SmallBoi(u8), diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs index 57722f63b225..0ed562f90bc0 100644 --- a/tests/ui/large_enum_variant.rs +++ b/tests/ui/large_enum_variant.rs @@ -9,6 +9,7 @@ extern crate proc_macros; use proc_macros::external; enum LargeEnum { +//~^ large_enum_variant A(i32), B([i32; 8000]), } @@ -33,22 +34,26 @@ enum LargeEnumGeneric { } enum LargeEnum2 { +//~^ large_enum_variant VariantOk(i32, u32), ContainingLargeEnum(LargeEnum), } enum LargeEnum3 { +//~^ large_enum_variant ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), VoidVariant, StructLikeLittle { x: i32, y: i32 }, } enum LargeEnum4 { +//~^ large_enum_variant VariantOk(i32, u32), StructLikeLarge { x: [i32; 8000], y: i32 }, } enum LargeEnum5 { +//~^ large_enum_variant VariantOk(i32, u32), StructLikeLarge2 { x: [i32; 8000] }, } @@ -65,27 +70,32 @@ enum LargeEnum6 { } enum LargeEnum7 { +//~^ large_enum_variant A, B([u8; 1255]), C([u8; 200]), } enum LargeEnum8 { +//~^ large_enum_variant VariantOk(i32, u32), ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), } enum LargeEnum9 { +//~^ large_enum_variant A(Struct<()>), B(Struct2), } enum LargeEnumOk2 { +//~^ large_enum_variant A(T), B(Struct2), } enum LargeEnumOk3 { +//~^ large_enum_variant A(Struct), B(Struct2), } @@ -101,11 +111,13 @@ struct Struct2 { #[derive(Copy, Clone)] enum CopyableLargeEnum { +//~^ large_enum_variant A(bool), B([u64; 8000]), } enum ManuallyCopyLargeEnum { +//~^ large_enum_variant A(bool), B([u64; 8000]), } @@ -119,6 +131,7 @@ impl Clone for ManuallyCopyLargeEnum { impl Copy for ManuallyCopyLargeEnum {} enum SomeGenericPossiblyCopyEnum { +//~^ large_enum_variant A(bool, std::marker::PhantomData), B([u64; 4000]), } @@ -132,6 +145,7 @@ impl Clone for SomeGenericPossiblyCopyEnum { impl Copy for SomeGenericPossiblyCopyEnum {} enum LargeEnumWithGenerics { +//~^ large_enum_variant Small, Large((T, [u8; 512])), } @@ -141,6 +155,7 @@ struct Foo { } enum WithGenerics { +//~^ large_enum_variant Large([Foo; 64]), Small(u8), } @@ -151,11 +166,13 @@ enum PossiblyLargeEnumWithConst { } enum LargeEnumOfConst { +//~^ large_enum_variant Ok, Error(PossiblyLargeEnumWithConst<256>), } enum WithRecursion { +//~^ large_enum_variant Large([u64; 64]), Recursive(Box), } @@ -166,6 +183,7 @@ enum WithRecursionAndGenerics { } enum LargeEnumWithGenericsAndRecursive { +//~^ large_enum_variant Ok(), Error(WithRecursionAndGenerics), } @@ -201,11 +219,13 @@ mod issue11915 { } enum NoWarnings { + //~^ large_enum_variant BigBoi(PublishWithBytes), _SmallBoi(u8), } enum MakesClippyAngry { + //~^ large_enum_variant BigBoi(PublishWithVec), _SmallBoi(u8), } diff --git a/tests/ui/large_futures.fixed b/tests/ui/large_futures.fixed index 1e87859f4526..dabb96e42918 100644 --- a/tests/ui/large_futures.fixed +++ b/tests/ui/large_futures.fixed @@ -8,21 +8,25 @@ async fn big_fut(_arg: [u8; 1024 * 16]) {} async fn wait() { let f = async { Box::pin(big_fut([0u8; 1024 * 16])).await; - //~^ ERROR: large future with a size of 16385 bytes - //~| NOTE: `-D clippy::large-futures` implied by `-D warnings` + //~^ large_futures + + }; Box::pin(f).await - //~^ ERROR: large future with a size of 16386 bytes + //~^ large_futures + } async fn calls_fut(fut: impl std::future::Future) { loop { Box::pin(wait()).await; - //~^ ERROR: large future with a size of 16387 bytes + //~^ large_futures + if true { return fut.await; } else { Box::pin(wait()).await; - //~^ ERROR: large future with a size of 16387 bytes + //~^ large_futures + } } } @@ -30,9 +34,11 @@ async fn calls_fut(fut: impl std::future::Future) { pub async fn test() { let fut = big_fut([0u8; 1024 * 16]); Box::pin(foo()).await; - //~^ ERROR: large future with a size of 65540 bytes + //~^ large_futures + Box::pin(calls_fut(fut)).await; - //~^ ERROR: large future with a size of 49159 bytes + //~^ large_futures + } pub fn foo() -> impl std::future::Future { @@ -45,7 +51,8 @@ pub fn foo() -> impl std::future::Future { pub async fn lines() { Box::pin(async { - //~^ ERROR: large future with a size of 65540 bytes + //~^ large_futures + let x = [0i32; 1024 * 16]; async {}.await; println!("{:?}", x); @@ -57,6 +64,7 @@ pub async fn macro_expn() { macro_rules! macro_ { () => { Box::pin(async { + //~^ large_futures let x = [0i32; 1024 * 16]; async {}.await; println!("macro: {:?}", x); diff --git a/tests/ui/large_futures.rs b/tests/ui/large_futures.rs index 3f4ea2ebf8bb..bafb0e2e3ba5 100644 --- a/tests/ui/large_futures.rs +++ b/tests/ui/large_futures.rs @@ -8,21 +8,25 @@ async fn big_fut(_arg: [u8; 1024 * 16]) {} async fn wait() { let f = async { big_fut([0u8; 1024 * 16]).await; - //~^ ERROR: large future with a size of 16385 bytes - //~| NOTE: `-D clippy::large-futures` implied by `-D warnings` + //~^ large_futures + + }; f.await - //~^ ERROR: large future with a size of 16386 bytes + //~^ large_futures + } async fn calls_fut(fut: impl std::future::Future) { loop { wait().await; - //~^ ERROR: large future with a size of 16387 bytes + //~^ large_futures + if true { return fut.await; } else { wait().await; - //~^ ERROR: large future with a size of 16387 bytes + //~^ large_futures + } } } @@ -30,9 +34,11 @@ async fn calls_fut(fut: impl std::future::Future) { pub async fn test() { let fut = big_fut([0u8; 1024 * 16]); foo().await; - //~^ ERROR: large future with a size of 65540 bytes + //~^ large_futures + calls_fut(fut).await; - //~^ ERROR: large future with a size of 49159 bytes + //~^ large_futures + } pub fn foo() -> impl std::future::Future { @@ -45,7 +51,8 @@ pub fn foo() -> impl std::future::Future { pub async fn lines() { async { - //~^ ERROR: large future with a size of 65540 bytes + //~^ large_futures + let x = [0i32; 1024 * 16]; async {}.await; println!("{:?}", x); @@ -57,6 +64,7 @@ pub async fn macro_expn() { macro_rules! macro_ { () => { async { + //~^ large_futures let x = [0i32; 1024 * 16]; async {}.await; println!("macro: {:?}", x); diff --git a/tests/ui/large_futures.stderr b/tests/ui/large_futures.stderr index 00082e579c59..cefc4769e846 100644 --- a/tests/ui/large_futures.stderr +++ b/tests/ui/large_futures.stderr @@ -8,40 +8,41 @@ LL | big_fut([0u8; 1024 * 16]).await; = help: to override `-D warnings` add `#[allow(clippy::large_futures)]` error: large future with a size of 16386 bytes - --> tests/ui/large_futures.rs:14:5 + --> tests/ui/large_futures.rs:15:5 | LL | f.await | ^ help: consider `Box::pin` on it: `Box::pin(f)` error: large future with a size of 16387 bytes - --> tests/ui/large_futures.rs:19:9 + --> tests/ui/large_futures.rs:21:9 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 16387 bytes - --> tests/ui/large_futures.rs:24:13 + --> tests/ui/large_futures.rs:27:13 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:32:5 + --> tests/ui/large_futures.rs:36:5 | LL | foo().await; | ^^^^^ help: consider `Box::pin` on it: `Box::pin(foo())` error: large future with a size of 49159 bytes - --> tests/ui/large_futures.rs:34:5 + --> tests/ui/large_futures.rs:39:5 | LL | calls_fut(fut).await; | ^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(calls_fut(fut))` error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:47:5 + --> tests/ui/large_futures.rs:53:5 | LL | / async { LL | | +LL | | LL | | let x = [0i32; 1024 * 16]; LL | | async {}.await; LL | | println!("{:?}", x); @@ -52,6 +53,7 @@ help: consider `Box::pin` on it | LL ~ Box::pin(async { LL + +LL + LL + let x = [0i32; 1024 * 16]; LL + async {}.await; LL + println!("{:?}", x); @@ -59,9 +61,10 @@ LL + }) | error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:59:13 + --> tests/ui/large_futures.rs:66:13 | LL | / async { +LL | | LL | | let x = [0i32; 1024 * 16]; LL | | async {}.await; LL | | println!("macro: {:?}", x); @@ -75,6 +78,7 @@ LL | macro_!().await help: consider `Box::pin` on it | LL ~ Box::pin(async { +LL + LL + let x = [0i32; 1024 * 16]; LL + async {}.await; LL + println!("macro: {:?}", x); diff --git a/tests/ui/large_stack_frames.rs b/tests/ui/large_stack_frames.rs index e6c030b8a9e8..81d89cc1c5ca 100644 --- a/tests/ui/large_stack_frames.rs +++ b/tests/ui/large_stack_frames.rs @@ -25,7 +25,8 @@ impl Default for ArrayDefault { } fn many_small_arrays() { - //~^ ERROR: this function may allocate +//~^ large_stack_frames + let x = [0u8; 500_000]; let x2 = [0u8; 500_000]; let x3 = [0u8; 500_000]; @@ -35,18 +36,21 @@ fn many_small_arrays() { } fn large_return_value() -> ArrayDefault<1_000_000> { - //~^ ERROR: this function may allocate 1000000 bytes on the stack +//~^ large_stack_frames + Default::default() } fn large_fn_arg(x: ArrayDefault<1_000_000>) { - //~^ ERROR: this function may allocate +//~^ large_stack_frames + black_box(&x); } fn has_large_closure() { let f = || black_box(&[0u8; 1_000_000]); - //~^ ERROR: this function may allocate + //~^ large_stack_frames + f(); } diff --git a/tests/ui/large_stack_frames.stderr b/tests/ui/large_stack_frames.stderr index f2e0a127f5f5..0ff49e9f5b37 100644 --- a/tests/ui/large_stack_frames.stderr +++ b/tests/ui/large_stack_frames.stderr @@ -13,7 +13,7 @@ LL | let x5 = [0u8; 500_000]; = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]` error: this function may allocate 1000000 bytes on the stack - --> tests/ui/large_stack_frames.rs:37:4 + --> tests/ui/large_stack_frames.rs:38:4 | LL | fn large_return_value() -> ArrayDefault<1_000_000> { | ^^^^^^^^^^^^^^^^^^ ----------------------- this is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>` @@ -21,7 +21,7 @@ LL | fn large_return_value() -> ArrayDefault<1_000_000> { = note: 1000000 bytes is larger than Clippy's configured `stack-size-threshold` of 512000 error: this function may allocate 100$PTR bytes on the stack - --> tests/ui/large_stack_frames.rs:42:4 + --> tests/ui/large_stack_frames.rs:44:4 | LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) { | ^^^^^^^^^^^^ - `x` is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>` @@ -29,7 +29,7 @@ LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) { = note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000 error: this function may allocate 100$PTR bytes on the stack - --> tests/ui/large_stack_frames.rs:48:13 + --> tests/ui/large_stack_frames.rs:51:13 | LL | let f = || black_box(&[0u8; 1_000_000]); | ^^^^^^^^^^^^^^----------------^ diff --git a/tests/ui/large_types_passed_by_value.rs b/tests/ui/large_types_passed_by_value.rs index 78994a2988a2..cd0c88b6834c 100644 --- a/tests/ui/large_types_passed_by_value.rs +++ b/tests/ui/large_types_passed_by_value.rs @@ -18,19 +18,25 @@ fn not_copy(a: Large) {} fn by_ref(a: &Large, b: &LargeAndCopy) {} fn mutable(mut a: LargeAndCopy) {} fn bad(a: LargeAndCopy) {} +//~^ large_types_passed_by_value pub fn bad_but_pub(a: LargeAndCopy) {} impl LargeAndCopy { fn self_is_ok(self) {} fn other_is_not_ok(self, other: LargeAndCopy) {} + //~^ large_types_passed_by_value fn unless_other_can_change(self, mut other: LargeAndCopy) {} pub fn or_were_in_public(self, other: LargeAndCopy) {} } trait LargeTypeDevourer { fn devoure_array(&self, array: [u8; 6666]); + //~^ large_types_passed_by_value fn devoure_tuple(&self, tup: (LargeAndCopy, LargeAndCopy)); + //~^ large_types_passed_by_value fn devoure_array_and_tuple_wow(&self, array: [u8; 6666], tup: (LargeAndCopy, LargeAndCopy)); + //~^ large_types_passed_by_value + //~| large_types_passed_by_value } pub trait PubLargeTypeDevourer { @@ -56,10 +62,12 @@ fn foo_always(x: LargeAndCopy) { } #[inline(never)] fn foo_never(x: LargeAndCopy) { +//~^ large_types_passed_by_value todo!(); } #[inline] fn foo(x: LargeAndCopy) { +//~^ large_types_passed_by_value todo!(); } diff --git a/tests/ui/large_types_passed_by_value.stderr b/tests/ui/large_types_passed_by_value.stderr index 5b42ab9e02ac..0ad68bc326e0 100644 --- a/tests/ui/large_types_passed_by_value.stderr +++ b/tests/ui/large_types_passed_by_value.stderr @@ -8,43 +8,43 @@ LL | fn bad(a: LargeAndCopy) {} = help: to override `-D warnings` add `#[allow(clippy::large_types_passed_by_value)]` error: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte) - --> tests/ui/large_types_passed_by_value.rs:25:37 + --> tests/ui/large_types_passed_by_value.rs:26:37 | LL | fn other_is_not_ok(self, other: LargeAndCopy) {} | ^^^^^^^^^^^^ help: consider passing by reference instead: `&LargeAndCopy` error: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte) - --> tests/ui/large_types_passed_by_value.rs:31:36 + --> tests/ui/large_types_passed_by_value.rs:33:36 | LL | fn devoure_array(&self, array: [u8; 6666]); | ^^^^^^^^^^ help: consider passing by reference instead: `&[u8; 6666]` error: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte) - --> tests/ui/large_types_passed_by_value.rs:32:34 + --> tests/ui/large_types_passed_by_value.rs:35:34 | LL | fn devoure_tuple(&self, tup: (LargeAndCopy, LargeAndCopy)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider passing by reference instead: `&(LargeAndCopy, LargeAndCopy)` error: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte) - --> tests/ui/large_types_passed_by_value.rs:33:50 + --> tests/ui/large_types_passed_by_value.rs:37:50 | LL | fn devoure_array_and_tuple_wow(&self, array: [u8; 6666], tup: (LargeAndCopy, LargeAndCopy)); | ^^^^^^^^^^ help: consider passing by reference instead: `&[u8; 6666]` error: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte) - --> tests/ui/large_types_passed_by_value.rs:33:67 + --> tests/ui/large_types_passed_by_value.rs:37:67 | LL | fn devoure_array_and_tuple_wow(&self, array: [u8; 6666], tup: (LargeAndCopy, LargeAndCopy)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider passing by reference instead: `&(LargeAndCopy, LargeAndCopy)` error: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte) - --> tests/ui/large_types_passed_by_value.rs:58:17 + --> tests/ui/large_types_passed_by_value.rs:64:17 | LL | fn foo_never(x: LargeAndCopy) { | ^^^^^^^^^^^^ help: consider passing by reference instead: `&LargeAndCopy` error: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte) - --> tests/ui/large_types_passed_by_value.rs:62:11 + --> tests/ui/large_types_passed_by_value.rs:69:11 | LL | fn foo(x: LargeAndCopy) { | ^^^^^^^^^^^^ help: consider passing by reference instead: `&LargeAndCopy` diff --git a/tests/ui/legacy_numeric_constants.fixed b/tests/ui/legacy_numeric_constants.fixed index 3a2294ef4c59..30bb549a9d65 100644 --- a/tests/ui/legacy_numeric_constants.fixed +++ b/tests/ui/legacy_numeric_constants.fixed @@ -1,4 +1,5 @@ //@aux-build:proc_macros.rs +//@require-annotations-for-level: WARN #![allow(clippy::no_effect, deprecated, unused)] #![allow(clippy::legacy_numeric_constants)] // For imports. diff --git a/tests/ui/legacy_numeric_constants.rs b/tests/ui/legacy_numeric_constants.rs index 6cb3e694ea14..d3878199055f 100644 --- a/tests/ui/legacy_numeric_constants.rs +++ b/tests/ui/legacy_numeric_constants.rs @@ -1,4 +1,5 @@ //@aux-build:proc_macros.rs +//@require-annotations-for-level: WARN #![allow(clippy::no_effect, deprecated, unused)] #![allow(clippy::legacy_numeric_constants)] // For imports. diff --git a/tests/ui/legacy_numeric_constants.stderr b/tests/ui/legacy_numeric_constants.stderr index 267b9ac8e4d1..af9b003ed540 100644 --- a/tests/ui/legacy_numeric_constants.stderr +++ b/tests/ui/legacy_numeric_constants.stderr @@ -1,5 +1,5 @@ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:31:5 + --> tests/ui/legacy_numeric_constants.rs:32:5 | LL | std::f32::EPSILON; | ^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | f32::EPSILON; | ~~~~~~~~~~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:34:5 + --> tests/ui/legacy_numeric_constants.rs:35:5 | LL | std::u8::MIN; | ^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | u8::MIN; | ~~~~~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:37:5 + --> tests/ui/legacy_numeric_constants.rs:38:5 | LL | std::usize::MIN; | ^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | usize::MIN; | ~~~~~~~~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:40:5 + --> tests/ui/legacy_numeric_constants.rs:41:5 | LL | std::u32::MAX; | ^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | u32::MAX; | ~~~~~~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:43:5 + --> tests/ui/legacy_numeric_constants.rs:44:5 | LL | core::u32::MAX; | ^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | u32::MAX; | ~~~~~~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:46:5 + --> tests/ui/legacy_numeric_constants.rs:47:5 | LL | MAX; | ^^^ @@ -67,7 +67,7 @@ LL | u32::MAX; | ~~~~~~~~ error: usage of a legacy numeric method - --> tests/ui/legacy_numeric_constants.rs:49:10 + --> tests/ui/legacy_numeric_constants.rs:50:10 | LL | i32::max_value(); | ^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | i32::MAX; | ~~~ error: usage of a legacy numeric method - --> tests/ui/legacy_numeric_constants.rs:52:9 + --> tests/ui/legacy_numeric_constants.rs:53:9 | LL | u8::max_value(); | ^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | u8::MAX; | ~~~ error: usage of a legacy numeric method - --> tests/ui/legacy_numeric_constants.rs:55:9 + --> tests/ui/legacy_numeric_constants.rs:56:9 | LL | u8::min_value(); | ^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | u8::MIN; | ~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:58:5 + --> tests/ui/legacy_numeric_constants.rs:59:5 | LL | ::std::u8::MIN; | ^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | u8::MIN; | ~~~~~~~ error: usage of a legacy numeric method - --> tests/ui/legacy_numeric_constants.rs:61:27 + --> tests/ui/legacy_numeric_constants.rs:62:27 | LL | ::std::primitive::u8::min_value(); | ^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | ::std::primitive::u8::MIN; | ~~~ error: usage of a legacy numeric method - --> tests/ui/legacy_numeric_constants.rs:64:26 + --> tests/ui/legacy_numeric_constants.rs:65:26 | LL | std::primitive::i32::max_value(); | ^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | std::primitive::i32::MAX; | ~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:67:5 + --> tests/ui/legacy_numeric_constants.rs:68:5 | LL | self::a::u128::MAX; | ^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | u128::MAX; | ~~~~~~~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:17:25 + --> tests/ui/legacy_numeric_constants.rs:18:25 | LL | let x = std::u64::MAX; | ^^^^^^^^^^^^^ @@ -159,7 +159,7 @@ LL | let x = u64::MAX; | ~~~~~~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:81:14 + --> tests/ui/legacy_numeric_constants.rs:82:14 | LL | [(0, "", std::i128::MAX)]; | ^^^^^^^^^^^^^^ @@ -170,7 +170,7 @@ LL | [(0, "", i128::MAX)]; | ~~~~~~~~~ error: usage of a legacy numeric constant - --> tests/ui/legacy_numeric_constants.rs:115:5 + --> tests/ui/legacy_numeric_constants.rs:116:5 | LL | std::u32::MAX; | ^^^^^^^^^^^^^ diff --git a/tests/ui/legacy_numeric_constants_unfixable.rs b/tests/ui/legacy_numeric_constants_unfixable.rs index 86738ede210c..9bf0f7f355ae 100644 --- a/tests/ui/legacy_numeric_constants_unfixable.rs +++ b/tests/ui/legacy_numeric_constants_unfixable.rs @@ -1,4 +1,5 @@ //@no-rustfix +//@require-annotations-for-level: WARN //@aux-build:proc_macros.rs #![allow(clippy::no_effect, deprecated, unused)] #![warn(clippy::legacy_numeric_constants)] diff --git a/tests/ui/legacy_numeric_constants_unfixable.stderr b/tests/ui/legacy_numeric_constants_unfixable.stderr index 2edcf7188362..96e6c9ef9759 100644 --- a/tests/ui/legacy_numeric_constants_unfixable.stderr +++ b/tests/ui/legacy_numeric_constants_unfixable.stderr @@ -1,5 +1,5 @@ error: importing legacy numeric constants - --> tests/ui/legacy_numeric_constants_unfixable.rs:9:5 + --> tests/ui/legacy_numeric_constants_unfixable.rs:10:5 | LL | use std::u128 as _; | ^^^^^^^^^ @@ -9,7 +9,7 @@ LL | use std::u128 as _; = help: to override `-D warnings` add `#[allow(clippy::legacy_numeric_constants)]` error: importing legacy numeric constants - --> tests/ui/legacy_numeric_constants_unfixable.rs:13:24 + --> tests/ui/legacy_numeric_constants_unfixable.rs:14:24 | LL | pub use std::{mem, u128}; | ^^^^ @@ -18,7 +18,7 @@ LL | pub use std::{mem, u128}; = note: then `u128::` will resolve to the respective associated constant error: importing a legacy numeric constant - --> tests/ui/legacy_numeric_constants_unfixable.rs:29:9 + --> tests/ui/legacy_numeric_constants_unfixable.rs:30:9 | LL | use std::u32::MAX; | ^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | use std::u32::MAX; = help: remove this import and use the associated constant `u32::MAX` from the primitive type instead error: importing a legacy numeric constant - --> tests/ui/legacy_numeric_constants_unfixable.rs:32:9 + --> tests/ui/legacy_numeric_constants_unfixable.rs:33:9 | LL | use std::u8::MIN; | ^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | use std::u8::MIN; = help: remove this import and use the associated constant `u8::MIN` from the primitive type instead error: importing legacy numeric constants - --> tests/ui/legacy_numeric_constants_unfixable.rs:36:9 + --> tests/ui/legacy_numeric_constants_unfixable.rs:37:9 | LL | use std::u32; | ^^^^^^^^ @@ -43,7 +43,7 @@ LL | use std::u32; = note: then `u32::` will resolve to the respective associated constant error: importing a legacy numeric constant - --> tests/ui/legacy_numeric_constants_unfixable.rs:40:9 + --> tests/ui/legacy_numeric_constants_unfixable.rs:41:9 | LL | use std::f32::MIN_POSITIVE; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | use std::f32::MIN_POSITIVE; = help: remove this import and use the associated constant `f32::MIN_POSITIVE` from the primitive type instead error: importing legacy numeric constants - --> tests/ui/legacy_numeric_constants_unfixable.rs:44:9 + --> tests/ui/legacy_numeric_constants_unfixable.rs:45:9 | LL | use std::i16::*; | ^^^^^^^^ @@ -59,7 +59,7 @@ LL | use std::i16::*; = help: remove this import and use associated constants `i16::` from the primitive type instead error: importing legacy numeric constants - --> tests/ui/legacy_numeric_constants_unfixable.rs:21:17 + --> tests/ui/legacy_numeric_constants_unfixable.rs:22:17 | LL | use std::u32; | ^^^^^^^^ @@ -72,7 +72,7 @@ LL | b!(); = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) error: importing a legacy numeric constant - --> tests/ui/legacy_numeric_constants_unfixable.rs:76:9 + --> tests/ui/legacy_numeric_constants_unfixable.rs:77:9 | LL | use std::u32::MAX; | ^^^^^^^^^^^^^ diff --git a/tests/ui/len_without_is_empty.rs b/tests/ui/len_without_is_empty.rs index d623601110e2..781c28d04bec 100644 --- a/tests/ui/len_without_is_empty.rs +++ b/tests/ui/len_without_is_empty.rs @@ -5,8 +5,9 @@ pub struct PubOne; impl PubOne { pub fn len(&self) -> isize { - //~^ ERROR: struct `PubOne` has a public `len` method, but no `is_empty` method - //~| NOTE: `-D clippy::len-without-is-empty` implied by `-D warnings` + //~^ len_without_is_empty + + 1 } } @@ -55,7 +56,8 @@ impl PubAllowedStruct { } pub trait PubTraitsToo { - //~^ ERROR: trait `PubTraitsToo` has a `len` method but no (possibly inherited) `is_empty` +//~^ len_without_is_empty + fn len(&self) -> isize; } @@ -69,7 +71,8 @@ pub struct HasIsEmpty; impl HasIsEmpty { pub fn len(&self) -> isize { - //~^ ERROR: struct `HasIsEmpty` has a public `len` method, but a private `is_empty` me + //~^ len_without_is_empty + 1 } @@ -82,7 +85,8 @@ pub struct HasWrongIsEmpty; impl HasWrongIsEmpty { pub fn len(&self) -> isize { - //~^ ERROR: struct `HasWrongIsEmpty` has a public `len` method, but the `is_empty` met + //~^ len_without_is_empty + 1 } @@ -95,7 +99,8 @@ pub struct MismatchedSelf; impl MismatchedSelf { pub fn len(self) -> isize { - //~^ ERROR: struct `MismatchedSelf` has a public `len` method, but the `is_empty` meth + //~^ len_without_is_empty + 1 } @@ -175,7 +180,8 @@ pub trait InheritingEmpty: Empty { pub trait Foo: Sized {} pub trait DependsOnFoo: Foo { - //~^ ERROR: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty` +//~^ len_without_is_empty + fn len(&mut self) -> usize; } @@ -221,7 +227,8 @@ impl OptionalLen2 { pub struct OptionalLen3; impl OptionalLen3 { pub fn len(&self) -> usize { - //~^ ERROR: struct `OptionalLen3` has a public `len` method, but the `is_empty` method + //~^ len_without_is_empty + 0 } @@ -234,8 +241,10 @@ impl OptionalLen3 { pub struct ResultLen; impl ResultLen { pub fn len(&self) -> Result { - //~^ ERROR: struct `ResultLen` has a public `len` method, but the `is_empty` method ha - //~| ERROR: this returns a `Result<_, ()>` + //~^ len_without_is_empty + //~| result_unit_err + + Ok(0) } @@ -248,12 +257,14 @@ impl ResultLen { pub struct ResultLen2; impl ResultLen2 { pub fn len(&self) -> Result { - //~^ ERROR: this returns a `Result<_, ()>` + //~^ result_unit_err + Ok(0) } pub fn is_empty(&self) -> Result { - //~^ ERROR: this returns a `Result<_, ()>` + //~^ result_unit_err + Ok(true) } } @@ -261,7 +272,8 @@ impl ResultLen2 { pub struct ResultLen3; impl ResultLen3 { pub fn len(&self) -> Result { - //~^ ERROR: this returns a `Result<_, ()>` + //~^ result_unit_err + Ok(0) } @@ -303,7 +315,8 @@ impl AsyncLenWithoutIsEmpty { } pub async fn len(&self) -> usize { - //~^ ERROR: struct `AsyncLenWithoutIsEmpty` has a public `len` method, but no `is_empt + //~^ len_without_is_empty + usize::from(!self.async_task().await) } } @@ -316,7 +329,8 @@ impl AsyncOptionLenWithoutIsEmpty { } pub async fn len(&self) -> Option { - //~^ ERROR: struct `AsyncOptionLenWithoutIsEmpty` has a public `len` method, but no `i + //~^ len_without_is_empty + None } } @@ -338,7 +352,8 @@ impl AsyncResultLenWithoutIsEmpty { } pub async fn len(&self) -> Result { - //~^ ERROR: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `i + //~^ len_without_is_empty + Err(()) } } @@ -454,7 +469,8 @@ pub struct Aliased2; pub type Alias2 = Aliased2; impl Alias2 { pub fn len(&self) -> usize { - //~^ ERROR: type `Alias2` has a public `len` method, but no `is_empty` method + //~^ len_without_is_empty + todo!() } } diff --git a/tests/ui/len_without_is_empty.stderr b/tests/ui/len_without_is_empty.stderr index 11d0d855fc0b..0fd445c720bd 100644 --- a/tests/ui/len_without_is_empty.stderr +++ b/tests/ui/len_without_is_empty.stderr @@ -8,89 +8,91 @@ LL | pub fn len(&self) -> isize { = help: to override `-D warnings` add `#[allow(clippy::len_without_is_empty)]` error: trait `PubTraitsToo` has a `len` method but no (possibly inherited) `is_empty` method - --> tests/ui/len_without_is_empty.rs:57:1 + --> tests/ui/len_without_is_empty.rs:58:1 | LL | / pub trait PubTraitsToo { LL | | +LL | | LL | | fn len(&self) -> isize; LL | | } | |_^ error: struct `HasIsEmpty` has a public `len` method, but a private `is_empty` method - --> tests/ui/len_without_is_empty.rs:71:5 + --> tests/ui/len_without_is_empty.rs:73:5 | LL | pub fn len(&self) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:76:5 + --> tests/ui/len_without_is_empty.rs:79:5 | LL | fn is_empty(&self) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: struct `HasWrongIsEmpty` has a public `len` method, but the `is_empty` method has an unexpected signature - --> tests/ui/len_without_is_empty.rs:84:5 + --> tests/ui/len_without_is_empty.rs:87:5 | LL | pub fn len(&self) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:89:5 + --> tests/ui/len_without_is_empty.rs:93:5 | LL | pub fn is_empty(&self, x: u32) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature: `(&self) -> bool` error: struct `MismatchedSelf` has a public `len` method, but the `is_empty` method has an unexpected signature - --> tests/ui/len_without_is_empty.rs:97:5 + --> tests/ui/len_without_is_empty.rs:101:5 | LL | pub fn len(self) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:102:5 + --> tests/ui/len_without_is_empty.rs:107:5 | LL | pub fn is_empty(&self) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature: `(self) -> bool` error: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty` method - --> tests/ui/len_without_is_empty.rs:177:1 + --> tests/ui/len_without_is_empty.rs:182:1 | LL | / pub trait DependsOnFoo: Foo { LL | | +LL | | LL | | fn len(&mut self) -> usize; LL | | } | |_^ error: struct `OptionalLen3` has a public `len` method, but the `is_empty` method has an unexpected signature - --> tests/ui/len_without_is_empty.rs:223:5 + --> tests/ui/len_without_is_empty.rs:229:5 | LL | pub fn len(&self) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:229:5 + --> tests/ui/len_without_is_empty.rs:236:5 | LL | pub fn is_empty(&self) -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature: `(&self) -> bool` error: struct `ResultLen` has a public `len` method, but the `is_empty` method has an unexpected signature - --> tests/ui/len_without_is_empty.rs:236:5 + --> tests/ui/len_without_is_empty.rs:243:5 | LL | pub fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:243:5 + --> tests/ui/len_without_is_empty.rs:252:5 | LL | pub fn is_empty(&self) -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature: `(&self) -> bool` or `(&self) -> Result error: this returns a `Result<_, ()>` - --> tests/ui/len_without_is_empty.rs:236:5 + --> tests/ui/len_without_is_empty.rs:243:5 | LL | pub fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +102,7 @@ LL | pub fn len(&self) -> Result { = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]` error: this returns a `Result<_, ()>` - --> tests/ui/len_without_is_empty.rs:250:5 + --> tests/ui/len_without_is_empty.rs:259:5 | LL | pub fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -108,7 +110,7 @@ LL | pub fn len(&self) -> Result { = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/len_without_is_empty.rs:255:5 + --> tests/ui/len_without_is_empty.rs:265:5 | LL | pub fn is_empty(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -116,7 +118,7 @@ LL | pub fn is_empty(&self) -> Result { = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/len_without_is_empty.rs:263:5 + --> tests/ui/len_without_is_empty.rs:274:5 | LL | pub fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -124,25 +126,25 @@ LL | pub fn len(&self) -> Result { = help: use a custom `Error` type instead error: struct `AsyncLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method - --> tests/ui/len_without_is_empty.rs:305:5 + --> tests/ui/len_without_is_empty.rs:317:5 | LL | pub async fn len(&self) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: struct `AsyncOptionLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method - --> tests/ui/len_without_is_empty.rs:318:5 + --> tests/ui/len_without_is_empty.rs:331:5 | LL | pub async fn len(&self) -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method - --> tests/ui/len_without_is_empty.rs:340:5 + --> tests/ui/len_without_is_empty.rs:354:5 | LL | pub async fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `Alias2` has a public `len` method, but no `is_empty` method - --> tests/ui/len_without_is_empty.rs:456:5 + --> tests/ui/len_without_is_empty.rs:471:5 | LL | pub fn len(&self) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/len_zero.fixed b/tests/ui/len_zero.fixed index c9c476ba4214..e24a569cfde8 100644 --- a/tests/ui/len_zero.fixed +++ b/tests/ui/len_zero.fixed @@ -86,10 +86,12 @@ impl Deref for DerefToString { fn main() { let x = [1, 2]; if x.is_empty() { + //~^ len_zero println!("This should not happen!"); } if "".is_empty() {} + //~^ len_zero let s = "Hello, world!"; let s1 = &s; @@ -99,16 +101,24 @@ fn main() { let s5 = &s4; let s6 = &s5; println!("{}", s1.is_empty()); + //~^ comparison_to_empty println!("{}", s2.is_empty()); + //~^ comparison_to_empty println!("{}", s3.is_empty()); + //~^ comparison_to_empty println!("{}", s4.is_empty()); + //~^ comparison_to_empty println!("{}", s5.is_empty()); + //~^ comparison_to_empty println!("{}", (s6).is_empty()); + //~^ comparison_to_empty let d2s = DerefToDerefToString {}; println!("{}", (**d2s).is_empty()); + //~^ comparison_to_empty println!("{}", std::borrow::Cow::Borrowed("").is_empty()); + //~^ comparison_to_empty let y = One; if y.len() == 0 { @@ -124,18 +134,23 @@ fn main() { let has_is_empty = HasIsEmpty; if has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if has_is_empty.len() > 1 { @@ -147,18 +162,23 @@ fn main() { println!("This can happen."); } if has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if has_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } if 1 < has_is_empty.len() { @@ -173,6 +193,7 @@ fn main() { let with_is_empty: &dyn WithIsEmpty = &Wither; if with_is_empty.is_empty() { + //~^ len_zero println!("Or this!"); } assert!(!with_is_empty.is_empty()); @@ -185,11 +206,14 @@ fn main() { // issue #10529 (!has_is_empty.is_empty()).then(|| println!("This can happen.")); + //~^ len_zero (has_is_empty.is_empty()).then(|| println!("Or this!")); + //~^ len_zero } fn test_slice(b: &[u8]) { if !b.is_empty() {} + //~^ len_zero } // issue #11992 @@ -224,9 +248,12 @@ fn binop_with_macros() { if has_is_empty.len() == compare_to!(1) {} if has_is_empty.is_empty() {} + //~^ len_zero if has_is_empty.is_empty() {} + //~^ len_zero (!has_is_empty.is_empty()).then(|| println!("This can happen.")); + //~^ len_zero } fn no_infinite_recursion() -> bool { diff --git a/tests/ui/len_zero.rs b/tests/ui/len_zero.rs index 610a5448d10e..b558dd9a215e 100644 --- a/tests/ui/len_zero.rs +++ b/tests/ui/len_zero.rs @@ -86,10 +86,12 @@ impl Deref for DerefToString { fn main() { let x = [1, 2]; if x.len() == 0 { + //~^ len_zero println!("This should not happen!"); } if "".len() == 0 {} + //~^ len_zero let s = "Hello, world!"; let s1 = &s; @@ -99,16 +101,24 @@ fn main() { let s5 = &s4; let s6 = &s5; println!("{}", *s1 == ""); + //~^ comparison_to_empty println!("{}", **s2 == ""); + //~^ comparison_to_empty println!("{}", ***s3 == ""); + //~^ comparison_to_empty println!("{}", ****s4 == ""); + //~^ comparison_to_empty println!("{}", *****s5 == ""); + //~^ comparison_to_empty println!("{}", ******(s6) == ""); + //~^ comparison_to_empty let d2s = DerefToDerefToString {}; println!("{}", &**d2s == ""); + //~^ comparison_to_empty println!("{}", std::borrow::Cow::Borrowed("") == ""); + //~^ comparison_to_empty let y = One; if y.len() == 0 { @@ -124,18 +134,23 @@ fn main() { let has_is_empty = HasIsEmpty; if has_is_empty.len() == 0 { + //~^ len_zero println!("Or this!"); } if has_is_empty.len() != 0 { + //~^ len_zero println!("Or this!"); } if has_is_empty.len() > 0 { + //~^ len_zero println!("Or this!"); } if has_is_empty.len() < 1 { + //~^ len_zero println!("Or this!"); } if has_is_empty.len() >= 1 { + //~^ len_zero println!("Or this!"); } if has_is_empty.len() > 1 { @@ -147,18 +162,23 @@ fn main() { println!("This can happen."); } if 0 == has_is_empty.len() { + //~^ len_zero println!("Or this!"); } if 0 != has_is_empty.len() { + //~^ len_zero println!("Or this!"); } if 0 < has_is_empty.len() { + //~^ len_zero println!("Or this!"); } if 1 <= has_is_empty.len() { + //~^ len_zero println!("Or this!"); } if 1 > has_is_empty.len() { + //~^ len_zero println!("Or this!"); } if 1 < has_is_empty.len() { @@ -173,6 +193,7 @@ fn main() { let with_is_empty: &dyn WithIsEmpty = &Wither; if with_is_empty.len() == 0 { + //~^ len_zero println!("Or this!"); } assert!(!with_is_empty.is_empty()); @@ -185,11 +206,14 @@ fn main() { // issue #10529 (has_is_empty.len() > 0).then(|| println!("This can happen.")); + //~^ len_zero (has_is_empty.len() == 0).then(|| println!("Or this!")); + //~^ len_zero } fn test_slice(b: &[u8]) { if b.len() != 0 {} + //~^ len_zero } // issue #11992 @@ -224,9 +248,12 @@ fn binop_with_macros() { if has_is_empty.len() == compare_to!(1) {} if has_is_empty.len() == compare_to!(0) {} + //~^ len_zero if has_is_empty.len() == zero!() {} + //~^ len_zero (compare_to!(0) < has_is_empty.len()).then(|| println!("This can happen.")); + //~^ len_zero } fn no_infinite_recursion() -> bool { diff --git a/tests/ui/len_zero.stderr b/tests/ui/len_zero.stderr index 8d6b57e4b6d4..25052f39ad33 100644 --- a/tests/ui/len_zero.stderr +++ b/tests/ui/len_zero.stderr @@ -8,13 +8,13 @@ LL | if x.len() == 0 { = help: to override `-D warnings` add `#[allow(clippy::len_zero)]` error: length comparison to zero - --> tests/ui/len_zero.rs:92:8 + --> tests/ui/len_zero.rs:93:8 | LL | if "".len() == 0 {} | ^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `"".is_empty()` error: comparison to empty slice - --> tests/ui/len_zero.rs:101:20 + --> tests/ui/len_zero.rs:103:20 | LL | println!("{}", *s1 == ""); | ^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s1.is_empty()` @@ -23,145 +23,145 @@ LL | println!("{}", *s1 == ""); = help: to override `-D warnings` add `#[allow(clippy::comparison_to_empty)]` error: comparison to empty slice - --> tests/ui/len_zero.rs:102:20 + --> tests/ui/len_zero.rs:105:20 | LL | println!("{}", **s2 == ""); | ^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s2.is_empty()` error: comparison to empty slice - --> tests/ui/len_zero.rs:103:20 + --> tests/ui/len_zero.rs:107:20 | LL | println!("{}", ***s3 == ""); | ^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s3.is_empty()` error: comparison to empty slice - --> tests/ui/len_zero.rs:104:20 + --> tests/ui/len_zero.rs:109:20 | LL | println!("{}", ****s4 == ""); | ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s4.is_empty()` error: comparison to empty slice - --> tests/ui/len_zero.rs:105:20 + --> tests/ui/len_zero.rs:111:20 | LL | println!("{}", *****s5 == ""); | ^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s5.is_empty()` error: comparison to empty slice - --> tests/ui/len_zero.rs:106:20 + --> tests/ui/len_zero.rs:113:20 | LL | println!("{}", ******(s6) == ""); | ^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(s6).is_empty()` error: comparison to empty slice - --> tests/ui/len_zero.rs:109:20 + --> tests/ui/len_zero.rs:117:20 | LL | println!("{}", &**d2s == ""); | ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(**d2s).is_empty()` error: comparison to empty slice - --> tests/ui/len_zero.rs:111:20 + --> tests/ui/len_zero.rs:120:20 | LL | println!("{}", std::borrow::Cow::Borrowed("") == ""); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `std::borrow::Cow::Borrowed("").is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:126:8 + --> tests/ui/len_zero.rs:136:8 | LL | if has_is_empty.len() == 0 { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:129:8 + --> tests/ui/len_zero.rs:140:8 | LL | if has_is_empty.len() != 0 { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:132:8 + --> tests/ui/len_zero.rs:144:8 | LL | if has_is_empty.len() > 0 { | ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to one - --> tests/ui/len_zero.rs:135:8 + --> tests/ui/len_zero.rs:148:8 | LL | if has_is_empty.len() < 1 { | ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to one - --> tests/ui/len_zero.rs:138:8 + --> tests/ui/len_zero.rs:152:8 | LL | if has_is_empty.len() >= 1 { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:149:8 + --> tests/ui/len_zero.rs:164:8 | LL | if 0 == has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:152:8 + --> tests/ui/len_zero.rs:168:8 | LL | if 0 != has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:155:8 + --> tests/ui/len_zero.rs:172:8 | LL | if 0 < has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to one - --> tests/ui/len_zero.rs:158:8 + --> tests/ui/len_zero.rs:176:8 | LL | if 1 <= has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to one - --> tests/ui/len_zero.rs:161:8 + --> tests/ui/len_zero.rs:180:8 | LL | if 1 > has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:175:8 + --> tests/ui/len_zero.rs:195:8 | LL | if with_is_empty.len() == 0 { | ^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `with_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:187:6 + --> tests/ui/len_zero.rs:208:6 | LL | (has_is_empty.len() > 0).then(|| println!("This can happen.")); | ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:188:6 + --> tests/ui/len_zero.rs:210:6 | LL | (has_is_empty.len() == 0).then(|| println!("Or this!")); | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:192:8 + --> tests/ui/len_zero.rs:215:8 | LL | if b.len() != 0 {} | ^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!b.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:226:8 + --> tests/ui/len_zero.rs:250:8 | LL | if has_is_empty.len() == compare_to!(0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:227:8 + --> tests/ui/len_zero.rs:252:8 | LL | if has_is_empty.len() == zero!() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to zero - --> tests/ui/len_zero.rs:229:6 + --> tests/ui/len_zero.rs:255:6 | LL | (compare_to!(0) < has_is_empty.len()).then(|| println!("This can happen.")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` diff --git a/tests/ui/len_zero_ranges.fixed b/tests/ui/len_zero_ranges.fixed index 1fdeb2c7a37b..d5b514d98113 100644 --- a/tests/ui/len_zero_ranges.fixed +++ b/tests/ui/len_zero_ranges.fixed @@ -5,10 +5,12 @@ mod issue_3807 { fn suggestion_is_fine_range() { let _ = (0..42).is_empty(); + //~^ len_zero } fn suggestion_is_fine_range_inclusive() { let _ = (0_u8..=42).is_empty(); + //~^ len_zero } } diff --git a/tests/ui/len_zero_ranges.rs b/tests/ui/len_zero_ranges.rs index a5c9a969aaa6..98c97ca02457 100644 --- a/tests/ui/len_zero_ranges.rs +++ b/tests/ui/len_zero_ranges.rs @@ -5,10 +5,12 @@ mod issue_3807 { fn suggestion_is_fine_range() { let _ = (0..42).len() == 0; + //~^ len_zero } fn suggestion_is_fine_range_inclusive() { let _ = (0_u8..=42).len() == 0; + //~^ len_zero } } diff --git a/tests/ui/len_zero_ranges.stderr b/tests/ui/len_zero_ranges.stderr index 0b2991e15ea3..10845bcade47 100644 --- a/tests/ui/len_zero_ranges.stderr +++ b/tests/ui/len_zero_ranges.stderr @@ -8,7 +8,7 @@ LL | let _ = (0..42).len() == 0; = help: to override `-D warnings` add `#[allow(clippy::len_zero)]` error: length comparison to zero - --> tests/ui/len_zero_ranges.rs:11:17 + --> tests/ui/len_zero_ranges.rs:12:17 | LL | let _ = (0_u8..=42).len() == 0; | ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(0_u8..=42).is_empty()` diff --git a/tests/ui/let_and_return.edition2021.fixed b/tests/ui/let_and_return.edition2021.fixed index c160d5df30fd..83e4a0298a7d 100644 --- a/tests/ui/let_and_return.edition2021.fixed +++ b/tests/ui/let_and_return.edition2021.fixed @@ -11,15 +11,17 @@ fn test() -> i32 { let _y = 0; // no warning 5 - //~^ ERROR: returning the result of a `let` binding from a block - //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings` + //~^ let_and_return + + } fn test_inner() -> i32 { if true { 5 - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } else { 0 } @@ -82,7 +84,8 @@ fn issue_3792() -> String { // https://github.com/rust-lang/rust/pull/93965 stdin.lock().lines().next().unwrap().unwrap() - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7); @@ -105,7 +108,7 @@ mod no_lint_if_stmt_borrows { let value = value.upgrade().unwrap(); let ret = value.borrow().baz(); ret - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } fn borrows_in_closure(value: Weak>) -> u32 { @@ -116,7 +119,7 @@ mod no_lint_if_stmt_borrows { let value = value.upgrade().unwrap(); let ret = f(|| value.borrow().baz())(); ret - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } mod free_function { @@ -148,14 +151,14 @@ mod no_lint_if_stmt_borrows { let x = Inner {}; let value = some_foo(&x).value(); value - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } fn test2() -> i32 { let x = Inner {}; let value = Foo::new(&x).value(); value - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } } } @@ -177,7 +180,8 @@ mod issue_5729 { fn foo_cloned(&self) -> Arc { (Arc::clone(&self.foo)) as _ - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } } } @@ -196,7 +200,8 @@ mod issue_11335 { E::A(x) => x, E::B(x) => x, }) as _ - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } } } @@ -222,19 +227,22 @@ fn issue12801() { fn left_is_if() -> String { (if true { "a".to_string() } else { "b".to_string() } + "c") - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } fn no_par_needed() -> String { "c".to_string() + if true { "a" } else { "b" } - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } fn conjunctive_blocks() -> String { ({ "a".to_string() } + "b" + { "c" } + "d") - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } #[allow(clippy::overly_complex_bool_expr)] @@ -242,12 +250,14 @@ fn issue12801() { let _ = || { (if true { 2 } else { 3 } << 4) - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + }; let _ = || { ({ true } || { false } && { 2 <= 3 }) - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + }; } } @@ -259,7 +269,7 @@ fn issue14164() -> Result { None => Ok(Ok(0)), }?; r - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } fn main() {} diff --git a/tests/ui/let_and_return.edition2021.stderr b/tests/ui/let_and_return.edition2021.stderr index 105fa7a722d7..4302053c7815 100644 --- a/tests/ui/let_and_return.edition2021.stderr +++ b/tests/ui/let_and_return.edition2021.stderr @@ -15,7 +15,7 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:21:9 + --> tests/ui/let_and_return.rs:22:9 | LL | let x = 5; | ---------- unnecessary `let` binding @@ -29,7 +29,7 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:84:5 + --> tests/ui/let_and_return.rs:86:5 | LL | let line = stdin.lock().lines().next().unwrap().unwrap(); | --------------------------------------------------------- unnecessary `let` binding @@ -43,7 +43,7 @@ LL ~ stdin.lock().lines().next().unwrap().unwrap() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:179:13 + --> tests/ui/let_and_return.rs:182:13 | LL | let clone = Arc::clone(&self.foo); | ---------------------------------- unnecessary `let` binding @@ -57,7 +57,7 @@ LL ~ (Arc::clone(&self.foo)) as _ | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:198:13 + --> tests/ui/let_and_return.rs:202:13 | LL | / let result = match self { LL | | E::A(x) => x, @@ -79,7 +79,7 @@ LL + }) as _ | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:224:9 + --> tests/ui/let_and_return.rs:229:9 | LL | let s = if true { "a".to_string() } else { "b".to_string() } + "c"; | ------------------------------------------------------------------- unnecessary `let` binding @@ -93,7 +93,7 @@ LL ~ (if true { "a".to_string() } else { "b".to_string() } + "c") | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:230:9 + --> tests/ui/let_and_return.rs:236:9 | LL | let s = "c".to_string() + if true { "a" } else { "b" }; | ------------------------------------------------------- unnecessary `let` binding @@ -107,7 +107,7 @@ LL ~ "c".to_string() + if true { "a" } else { "b" } | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:236:9 + --> tests/ui/let_and_return.rs:243:9 | LL | let s = { "a".to_string() } + "b" + { "c" } + "d"; | -------------------------------------------------- unnecessary `let` binding @@ -121,7 +121,7 @@ LL ~ ({ "a".to_string() } + "b" + { "c" } + "d") | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:244:13 + --> tests/ui/let_and_return.rs:252:13 | LL | let s = if true { 2 } else { 3 } << 4; | -------------------------------------- unnecessary `let` binding @@ -135,7 +135,7 @@ LL ~ (if true { 2 } else { 3 } << 4) | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:249:13 + --> tests/ui/let_and_return.rs:258:13 | LL | let s = { true } || { false } && { 2 <= 3 }; | -------------------------------------------- unnecessary `let` binding diff --git a/tests/ui/let_and_return.edition2024.fixed b/tests/ui/let_and_return.edition2024.fixed index f958f70e1dcf..4846d6ada3ca 100644 --- a/tests/ui/let_and_return.edition2024.fixed +++ b/tests/ui/let_and_return.edition2024.fixed @@ -11,15 +11,17 @@ fn test() -> i32 { let _y = 0; // no warning 5 - //~^ ERROR: returning the result of a `let` binding from a block - //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings` + //~^ let_and_return + + } fn test_inner() -> i32 { if true { 5 - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } else { 0 } @@ -82,7 +84,8 @@ fn issue_3792() -> String { // https://github.com/rust-lang/rust/pull/93965 stdin.lock().lines().next().unwrap().unwrap() - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7); @@ -105,7 +108,7 @@ mod no_lint_if_stmt_borrows { let value = value.upgrade().unwrap(); value.borrow().baz() - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } fn borrows_in_closure(value: Weak>) -> u32 { @@ -116,7 +119,7 @@ mod no_lint_if_stmt_borrows { let value = value.upgrade().unwrap(); f(|| value.borrow().baz())() - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } mod free_function { @@ -148,14 +151,14 @@ mod no_lint_if_stmt_borrows { let x = Inner {}; some_foo(&x).value() - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } fn test2() -> i32 { let x = Inner {}; Foo::new(&x).value() - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } } } @@ -177,7 +180,8 @@ mod issue_5729 { fn foo_cloned(&self) -> Arc { (Arc::clone(&self.foo)) as _ - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } } } @@ -196,7 +200,8 @@ mod issue_11335 { E::A(x) => x, E::B(x) => x, }) as _ - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } } } @@ -222,19 +227,22 @@ fn issue12801() { fn left_is_if() -> String { (if true { "a".to_string() } else { "b".to_string() } + "c") - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } fn no_par_needed() -> String { "c".to_string() + if true { "a" } else { "b" } - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } fn conjunctive_blocks() -> String { ({ "a".to_string() } + "b" + { "c" } + "d") - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } #[allow(clippy::overly_complex_bool_expr)] @@ -242,12 +250,14 @@ fn issue12801() { let _ = || { (if true { 2 } else { 3 } << 4) - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + }; let _ = || { ({ true } || { false } && { 2 <= 3 }) - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + }; } } @@ -259,7 +269,7 @@ fn issue14164() -> Result { Some(v) => Ok(Ok(v[0])), None => Ok(Ok(0)), }? - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } fn main() {} diff --git a/tests/ui/let_and_return.edition2024.stderr b/tests/ui/let_and_return.edition2024.stderr index ec87e32b582d..4b7f1a019f27 100644 --- a/tests/ui/let_and_return.edition2024.stderr +++ b/tests/ui/let_and_return.edition2024.stderr @@ -15,7 +15,7 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:21:9 + --> tests/ui/let_and_return.rs:22:9 | LL | let x = 5; | ---------- unnecessary `let` binding @@ -29,7 +29,7 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:84:5 + --> tests/ui/let_and_return.rs:86:5 | LL | let line = stdin.lock().lines().next().unwrap().unwrap(); | --------------------------------------------------------- unnecessary `let` binding @@ -43,7 +43,7 @@ LL ~ stdin.lock().lines().next().unwrap().unwrap() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:107:9 + --> tests/ui/let_and_return.rs:110:9 | LL | let ret = value.borrow().baz(); | ------------------------------- unnecessary `let` binding @@ -57,7 +57,7 @@ LL ~ value.borrow().baz() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:118:9 + --> tests/ui/let_and_return.rs:121:9 | LL | let ret = f(|| value.borrow().baz())(); | --------------------------------------- unnecessary `let` binding @@ -71,7 +71,7 @@ LL ~ f(|| value.borrow().baz())() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:150:13 + --> tests/ui/let_and_return.rs:153:13 | LL | let value = some_foo(&x).value(); | --------------------------------- unnecessary `let` binding @@ -85,7 +85,7 @@ LL ~ some_foo(&x).value() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:157:13 + --> tests/ui/let_and_return.rs:160:13 | LL | let value = Foo::new(&x).value(); | --------------------------------- unnecessary `let` binding @@ -99,7 +99,7 @@ LL ~ Foo::new(&x).value() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:179:13 + --> tests/ui/let_and_return.rs:182:13 | LL | let clone = Arc::clone(&self.foo); | ---------------------------------- unnecessary `let` binding @@ -113,7 +113,7 @@ LL ~ (Arc::clone(&self.foo)) as _ | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:198:13 + --> tests/ui/let_and_return.rs:202:13 | LL | / let result = match self { LL | | E::A(x) => x, @@ -135,7 +135,7 @@ LL + }) as _ | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:224:9 + --> tests/ui/let_and_return.rs:229:9 | LL | let s = if true { "a".to_string() } else { "b".to_string() } + "c"; | ------------------------------------------------------------------- unnecessary `let` binding @@ -149,7 +149,7 @@ LL ~ (if true { "a".to_string() } else { "b".to_string() } + "c") | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:230:9 + --> tests/ui/let_and_return.rs:236:9 | LL | let s = "c".to_string() + if true { "a" } else { "b" }; | ------------------------------------------------------- unnecessary `let` binding @@ -163,7 +163,7 @@ LL ~ "c".to_string() + if true { "a" } else { "b" } | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:236:9 + --> tests/ui/let_and_return.rs:243:9 | LL | let s = { "a".to_string() } + "b" + { "c" } + "d"; | -------------------------------------------------- unnecessary `let` binding @@ -177,7 +177,7 @@ LL ~ ({ "a".to_string() } + "b" + { "c" } + "d") | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:244:13 + --> tests/ui/let_and_return.rs:252:13 | LL | let s = if true { 2 } else { 3 } << 4; | -------------------------------------- unnecessary `let` binding @@ -191,7 +191,7 @@ LL ~ (if true { 2 } else { 3 } << 4) | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:249:13 + --> tests/ui/let_and_return.rs:258:13 | LL | let s = { true } || { false } && { 2 <= 3 }; | -------------------------------------------- unnecessary `let` binding @@ -205,7 +205,7 @@ LL ~ ({ true } || { false } && { 2 <= 3 }) | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:261:5 + --> tests/ui/let_and_return.rs:271:5 | LL | / let r = match &*v.borrow() { LL | | Some(v) => Ok(Ok(v[0])), diff --git a/tests/ui/let_and_return.rs b/tests/ui/let_and_return.rs index 0b7a1e26890f..ab5338837a53 100644 --- a/tests/ui/let_and_return.rs +++ b/tests/ui/let_and_return.rs @@ -11,15 +11,17 @@ fn test() -> i32 { let _y = 0; // no warning let x = 5; x - //~^ ERROR: returning the result of a `let` binding from a block - //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings` + //~^ let_and_return + + } fn test_inner() -> i32 { if true { let x = 5; x - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } else { 0 } @@ -82,7 +84,8 @@ fn issue_3792() -> String { // https://github.com/rust-lang/rust/pull/93965 let line = stdin.lock().lines().next().unwrap().unwrap(); line - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7); @@ -105,7 +108,7 @@ mod no_lint_if_stmt_borrows { let value = value.upgrade().unwrap(); let ret = value.borrow().baz(); ret - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } fn borrows_in_closure(value: Weak>) -> u32 { @@ -116,7 +119,7 @@ mod no_lint_if_stmt_borrows { let value = value.upgrade().unwrap(); let ret = f(|| value.borrow().baz())(); ret - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } mod free_function { @@ -148,14 +151,14 @@ mod no_lint_if_stmt_borrows { let x = Inner {}; let value = some_foo(&x).value(); value - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } fn test2() -> i32 { let x = Inner {}; let value = Foo::new(&x).value(); value - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } } } @@ -177,7 +180,8 @@ mod issue_5729 { fn foo_cloned(&self) -> Arc { let clone = Arc::clone(&self.foo); clone - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } } } @@ -196,7 +200,8 @@ mod issue_11335 { }; result - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } } } @@ -222,19 +227,22 @@ fn issue12801() { fn left_is_if() -> String { let s = if true { "a".to_string() } else { "b".to_string() } + "c"; s - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } fn no_par_needed() -> String { let s = "c".to_string() + if true { "a" } else { "b" }; s - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } fn conjunctive_blocks() -> String { let s = { "a".to_string() } + "b" + { "c" } + "d"; s - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + } #[allow(clippy::overly_complex_bool_expr)] @@ -242,12 +250,14 @@ fn issue12801() { let _ = || { let s = if true { 2 } else { 3 } << 4; s - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + }; let _ = || { let s = { true } || { false } && { 2 <= 3 }; s - //~^ ERROR: returning the result of a `let` binding from a block + //~^ let_and_return + }; } } @@ -259,7 +269,7 @@ fn issue14164() -> Result { None => Ok(Ok(0)), }?; r - //~[edition2024]^ ERROR: returning the result of a `let` binding from a block + //~[edition2024]^ let_and_return } fn main() {} diff --git a/tests/ui/let_if_seq.rs b/tests/ui/let_if_seq.rs index a29d35880b8d..cc482155eda7 100644 --- a/tests/ui/let_if_seq.rs +++ b/tests/ui/let_if_seq.rs @@ -75,15 +75,17 @@ fn main() { issue985_alt(); let mut foo = 0; - //~^ ERROR: `if _ { .. } else { .. }` is an expression - //~| NOTE: you might not need `mut` at all + //~^ useless_let_if_seq + + if f() { foo = 42; } let mut bar = 0; - //~^ ERROR: `if _ { .. } else { .. }` is an expression - //~| NOTE: you might not need `mut` at all + //~^ useless_let_if_seq + + if f() { f(); bar = 42; @@ -92,7 +94,8 @@ fn main() { } let quz; - //~^ ERROR: `if _ { .. } else { .. }` is an expression + //~^ useless_let_if_seq + if f() { quz = 42; } else { @@ -122,8 +125,9 @@ fn main() { // baz needs to be mut let mut baz = 0; - //~^ ERROR: `if _ { .. } else { .. }` is an expression - //~| NOTE: you might not need `mut` at all + //~^ useless_let_if_seq + + if f() { baz = 42; } diff --git a/tests/ui/let_if_seq.stderr b/tests/ui/let_if_seq.stderr index 41930108fb1a..b63a31b99129 100644 --- a/tests/ui/let_if_seq.stderr +++ b/tests/ui/let_if_seq.stderr @@ -2,9 +2,7 @@ error: `if _ { .. } else { .. }` is an expression --> tests/ui/let_if_seq.rs:77:5 | LL | / let mut foo = 0; -LL | | -LL | | -LL | | if f() { +... | LL | | foo = 42; LL | | } | |_____^ help: it is more idiomatic to write: `let foo = if f() { 42 } else { 0 };` @@ -14,12 +12,9 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::useless_let_if_seq)]` error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:84:5 + --> tests/ui/let_if_seq.rs:85:5 | LL | / let mut bar = 0; -LL | | -LL | | -LL | | if f() { ... | LL | | f(); LL | | } @@ -28,24 +23,22 @@ LL | | } = note: you might not need `mut` at all error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:94:5 + --> tests/ui/let_if_seq.rs:96:5 | LL | / let quz; LL | | +LL | | LL | | if f() { -LL | | quz = 42; -LL | | } else { +... | LL | | quz = 0; LL | | } | |_____^ help: it is more idiomatic to write: `let quz = if f() { 42 } else { 0 };` error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:124:5 + --> tests/ui/let_if_seq.rs:127:5 | LL | / let mut baz = 0; -LL | | -LL | | -LL | | if f() { +... | LL | | baz = 42; LL | | } | |_____^ help: it is more idiomatic to write: `let baz = if f() { 42 } else { 0 };` diff --git a/tests/ui/let_underscore_future.rs b/tests/ui/let_underscore_future.rs index c2185e9785d8..2d57e83fd54d 100644 --- a/tests/ui/let_underscore_future.rs +++ b/tests/ui/let_underscore_future.rs @@ -12,12 +12,15 @@ fn do_something_to_future(future: &mut impl Future) {} fn main() { let _ = some_async_fn(); - //~^ ERROR: non-binding `let` on a future + //~^ let_underscore_future + let _ = custom(); - //~^ ERROR: non-binding `let` on a future + //~^ let_underscore_future + let mut future = some_async_fn(); do_something_to_future(&mut future); let _ = future; - //~^ ERROR: non-binding `let` on a future + //~^ let_underscore_future + } diff --git a/tests/ui/let_underscore_future.stderr b/tests/ui/let_underscore_future.stderr index 66aeb5035394..e59e1f68911a 100644 --- a/tests/ui/let_underscore_future.stderr +++ b/tests/ui/let_underscore_future.stderr @@ -9,7 +9,7 @@ LL | let _ = some_async_fn(); = help: to override `-D warnings` add `#[allow(clippy::let_underscore_future)]` error: non-binding `let` on a future - --> tests/ui/let_underscore_future.rs:16:5 + --> tests/ui/let_underscore_future.rs:17:5 | LL | let _ = custom(); | ^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = custom(); = help: consider awaiting the future or dropping explicitly with `std::mem::drop` error: non-binding `let` on a future - --> tests/ui/let_underscore_future.rs:21:5 + --> tests/ui/let_underscore_future.rs:23:5 | LL | let _ = future; | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/let_underscore_must_use.rs b/tests/ui/let_underscore_must_use.rs index 3290d087724e..730e586eea79 100644 --- a/tests/ui/let_underscore_must_use.rs +++ b/tests/ui/let_underscore_must_use.rs @@ -65,42 +65,54 @@ impl Trait for S { fn main() { let _ = f(); - //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function + //~^ let_underscore_must_use + let _ = g(); - //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type + //~^ let_underscore_must_use + let _ = h(); let _ = l(0_u32); - //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function + //~^ let_underscore_must_use + let s = S {}; let _ = s.f(); - //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function + //~^ let_underscore_must_use + let _ = s.g(); - //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type + //~^ let_underscore_must_use + let _ = s.k(); let _ = S::h(); - //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function + //~^ let_underscore_must_use + let _ = S::p(); - //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type + //~^ let_underscore_must_use + let _ = S::a(); - //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function + //~^ let_underscore_must_use + let _ = if true { Ok(()) } else { Err(()) }; - //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type + //~^ let_underscore_must_use + let a = Result::<(), ()>::Ok(()); let _ = a.is_ok(); - //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function + //~^ let_underscore_must_use + let _ = a.map(|_| ()); - //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type + //~^ let_underscore_must_use + let _ = a; - //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type + //~^ let_underscore_must_use + #[allow(clippy::let_underscore_must_use)] let _ = a; diff --git a/tests/ui/let_underscore_must_use.stderr b/tests/ui/let_underscore_must_use.stderr index e8785b92b815..fda2a2b2adaa 100644 --- a/tests/ui/let_underscore_must_use.stderr +++ b/tests/ui/let_underscore_must_use.stderr @@ -9,7 +9,7 @@ LL | let _ = f(); = help: to override `-D warnings` add `#[allow(clippy::let_underscore_must_use)]` error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:69:5 + --> tests/ui/let_underscore_must_use.rs:70:5 | LL | let _ = g(); | ^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = g(); = help: consider explicitly using expression value error: non-binding `let` on a result of a `#[must_use]` function - --> tests/ui/let_underscore_must_use.rs:72:5 + --> tests/ui/let_underscore_must_use.rs:74:5 | LL | let _ = l(0_u32); | ^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = l(0_u32); = help: consider explicitly using function result error: non-binding `let` on a result of a `#[must_use]` function - --> tests/ui/let_underscore_must_use.rs:77:5 + --> tests/ui/let_underscore_must_use.rs:80:5 | LL | let _ = s.f(); | ^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = s.f(); = help: consider explicitly using function result error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:79:5 + --> tests/ui/let_underscore_must_use.rs:83:5 | LL | let _ = s.g(); | ^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = s.g(); = help: consider explicitly using expression value error: non-binding `let` on a result of a `#[must_use]` function - --> tests/ui/let_underscore_must_use.rs:83:5 + --> tests/ui/let_underscore_must_use.rs:88:5 | LL | let _ = S::h(); | ^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = S::h(); = help: consider explicitly using function result error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:85:5 + --> tests/ui/let_underscore_must_use.rs:91:5 | LL | let _ = S::p(); | ^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = S::p(); = help: consider explicitly using expression value error: non-binding `let` on a result of a `#[must_use]` function - --> tests/ui/let_underscore_must_use.rs:88:5 + --> tests/ui/let_underscore_must_use.rs:95:5 | LL | let _ = S::a(); | ^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | let _ = S::a(); = help: consider explicitly using function result error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:91:5 + --> tests/ui/let_underscore_must_use.rs:99:5 | LL | let _ = if true { Ok(()) } else { Err(()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let _ = if true { Ok(()) } else { Err(()) }; = help: consider explicitly using expression value error: non-binding `let` on a result of a `#[must_use]` function - --> tests/ui/let_underscore_must_use.rs:96:5 + --> tests/ui/let_underscore_must_use.rs:105:5 | LL | let _ = a.is_ok(); | ^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | let _ = a.is_ok(); = help: consider explicitly using function result error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:99:5 + --> tests/ui/let_underscore_must_use.rs:109:5 | LL | let _ = a.map(|_| ()); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = a.map(|_| ()); = help: consider explicitly using expression value error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:102:5 + --> tests/ui/let_underscore_must_use.rs:113:5 | LL | let _ = a; | ^^^^^^^^^^ diff --git a/tests/ui/let_underscore_untyped.rs b/tests/ui/let_underscore_untyped.rs index 6275b6f970a1..26ba8682dc2d 100644 --- a/tests/ui/let_underscore_untyped.rs +++ b/tests/ui/let_underscore_untyped.rs @@ -49,11 +49,16 @@ with_span!( fn main() { let _ = a(); + //~^ let_underscore_untyped let _ = b(1); + //~^ let_underscore_untyped let _ = c(); let _ = d(&1); + //~^ let_underscore_untyped let _ = e(); + //~^ let_underscore_untyped let _ = f(); + //~^ let_underscore_untyped let _ = g(); let closure = || {}; diff --git a/tests/ui/let_underscore_untyped.stderr b/tests/ui/let_underscore_untyped.stderr index 1dd51e1e59b1..86cdd5c662cc 100644 --- a/tests/ui/let_underscore_untyped.stderr +++ b/tests/ui/let_underscore_untyped.stderr @@ -13,49 +13,49 @@ LL | let _ = a(); = help: to override `-D warnings` add `#[allow(clippy::let_underscore_untyped)]` error: non-binding `let` without a type annotation - --> tests/ui/let_underscore_untyped.rs:52:5 + --> tests/ui/let_underscore_untyped.rs:53:5 | LL | let _ = b(1); | ^^^^^^^^^^^^^ | help: consider adding a type annotation - --> tests/ui/let_underscore_untyped.rs:52:10 + --> tests/ui/let_underscore_untyped.rs:53:10 | LL | let _ = b(1); | ^ error: non-binding `let` without a type annotation - --> tests/ui/let_underscore_untyped.rs:54:5 + --> tests/ui/let_underscore_untyped.rs:56:5 | LL | let _ = d(&1); | ^^^^^^^^^^^^^^ | help: consider adding a type annotation - --> tests/ui/let_underscore_untyped.rs:54:10 + --> tests/ui/let_underscore_untyped.rs:56:10 | LL | let _ = d(&1); | ^ error: non-binding `let` without a type annotation - --> tests/ui/let_underscore_untyped.rs:55:5 + --> tests/ui/let_underscore_untyped.rs:58:5 | LL | let _ = e(); | ^^^^^^^^^^^^ | help: consider adding a type annotation - --> tests/ui/let_underscore_untyped.rs:55:10 + --> tests/ui/let_underscore_untyped.rs:58:10 | LL | let _ = e(); | ^ error: non-binding `let` without a type annotation - --> tests/ui/let_underscore_untyped.rs:56:5 + --> tests/ui/let_underscore_untyped.rs:60:5 | LL | let _ = f(); | ^^^^^^^^^^^^ | help: consider adding a type annotation - --> tests/ui/let_underscore_untyped.rs:56:10 + --> tests/ui/let_underscore_untyped.rs:60:10 | LL | let _ = f(); | ^ diff --git a/tests/ui/let_unit.fixed b/tests/ui/let_unit.fixed index 3456e274f6a4..23145bd132f5 100644 --- a/tests/ui/let_unit.fixed +++ b/tests/ui/let_unit.fixed @@ -9,6 +9,7 @@ macro_rules! let_and_return { fn main() { println!("x"); + //~^ let_unit_value let _y = 1; // this is fine let _z = ((), 1); // this as well if true { @@ -57,6 +58,7 @@ fn multiline_sugg() { let v: Vec = vec![2]; v + //~^ let_unit_value .into_iter() .map(|i| i * 2) .filter(|i| i % 2 == 0) @@ -106,6 +108,7 @@ fn _returns_generic() { let x: () = if true { f() } else { f2(0) }; match Some(0) { + //~^ let_unit_value None => f2(1), Some(0) => f(), Some(1) => f2(3), @@ -187,6 +190,7 @@ pub fn issue12594() { fn actual_test() { // create first a unit value'd value returns_unit(); + //~^ let_unit_value returns_result(()).unwrap(); returns_result(()).unwrap(); // make sure we replace only the first variable diff --git a/tests/ui/let_unit.rs b/tests/ui/let_unit.rs index e2dafbcb7714..59800b553a8c 100644 --- a/tests/ui/let_unit.rs +++ b/tests/ui/let_unit.rs @@ -9,6 +9,7 @@ macro_rules! let_and_return { fn main() { let _x = println!("x"); + //~^ let_unit_value let _y = 1; // this is fine let _z = ((), 1); // this as well if true { @@ -57,6 +58,7 @@ fn multiline_sugg() { let v: Vec = vec![2]; let _ = v + //~^ let_unit_value .into_iter() .map(|i| i * 2) .filter(|i| i % 2 == 0) @@ -106,6 +108,7 @@ fn _returns_generic() { let x: () = if true { f() } else { f2(0) }; let x = match Some(0) { + //~^ let_unit_value None => f2(1), Some(0) => f(), Some(1) => f2(3), @@ -187,6 +190,7 @@ pub fn issue12594() { fn actual_test() { // create first a unit value'd value let res = returns_unit(); + //~^ let_unit_value returns_result(res).unwrap(); returns_result(res).unwrap(); // make sure we replace only the first variable diff --git a/tests/ui/let_unit.stderr b/tests/ui/let_unit.stderr index a2f368f22e5b..d7d01d304cad 100644 --- a/tests/ui/let_unit.stderr +++ b/tests/ui/let_unit.stderr @@ -8,13 +8,13 @@ LL | let _x = println!("x"); = help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]` error: this let-binding has unit value - --> tests/ui/let_unit.rs:59:5 + --> tests/ui/let_unit.rs:60:5 | LL | / let _ = v +LL | | LL | | .into_iter() LL | | .map(|i| i * 2) -LL | | .filter(|i| i % 2 == 0) -LL | | .map(|_| ()) +... | LL | | .next() LL | | .unwrap(); | |__________________^ @@ -22,6 +22,7 @@ LL | | .unwrap(); help: omit the `let` binding | LL ~ v +LL + LL + .into_iter() LL + .map(|i| i * 2) LL + .filter(|i| i % 2 == 0) @@ -31,9 +32,10 @@ LL + .unwrap(); | error: this let-binding has unit value - --> tests/ui/let_unit.rs:108:5 + --> tests/ui/let_unit.rs:110:5 | LL | / let x = match Some(0) { +LL | | LL | | None => f2(1), LL | | Some(0) => f(), LL | | Some(1) => f2(3), @@ -44,6 +46,7 @@ LL | | }; help: omit the `let` binding | LL ~ match Some(0) { +LL + LL + None => f2(1), LL + Some(0) => f(), LL + Some(1) => f2(3), @@ -52,7 +55,7 @@ LL + }; | error: this let-binding has unit value - --> tests/ui/let_unit.rs:189:9 + --> tests/ui/let_unit.rs:192:9 | LL | let res = returns_unit(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,6 +63,7 @@ LL | let res = returns_unit(); help: omit the `let` binding and replace variable usages with `()` | LL ~ returns_unit(); +LL | LL ~ returns_result(()).unwrap(); LL ~ returns_result(()).unwrap(); | diff --git a/tests/ui/let_with_type_underscore.rs b/tests/ui/let_with_type_underscore.rs index ae1a480bcfc5..a7c2f598b56d 100644 --- a/tests/ui/let_with_type_underscore.rs +++ b/tests/ui/let_with_type_underscore.rs @@ -13,9 +13,13 @@ fn func() -> &'static str { fn main() { // Will lint let x: _ = 1; + //~^ let_with_type_underscore let _: _ = 2; + //~^ let_with_type_underscore let x: _ = func(); + //~^ let_with_type_underscore let x: _; + //~^ let_with_type_underscore x = (); let x = 1; // Will not lint, Rust infers this to an integer before Clippy @@ -23,6 +27,7 @@ fn main() { let x: Vec<_> = Vec::::new(); let x: [_; 1] = [1]; let x : _ = 1; + //~^ let_with_type_underscore // Do not lint from procedural macros proc_macros::with_span! { diff --git a/tests/ui/let_with_type_underscore.stderr b/tests/ui/let_with_type_underscore.stderr index 29ec25a5b2ac..2284d1fe2e48 100644 --- a/tests/ui/let_with_type_underscore.stderr +++ b/tests/ui/let_with_type_underscore.stderr @@ -13,49 +13,49 @@ LL | let x: _ = 1; = help: to override `-D warnings` add `#[allow(clippy::let_with_type_underscore)]` error: variable declared with type underscore - --> tests/ui/let_with_type_underscore.rs:16:5 + --> tests/ui/let_with_type_underscore.rs:17:5 | LL | let _: _ = 2; | ^^^^^^^^^^^^^ | help: remove the explicit type `_` declaration - --> tests/ui/let_with_type_underscore.rs:16:10 + --> tests/ui/let_with_type_underscore.rs:17:10 | LL | let _: _ = 2; | ^^^ error: variable declared with type underscore - --> tests/ui/let_with_type_underscore.rs:17:5 + --> tests/ui/let_with_type_underscore.rs:19:5 | LL | let x: _ = func(); | ^^^^^^^^^^^^^^^^^^ | help: remove the explicit type `_` declaration - --> tests/ui/let_with_type_underscore.rs:17:10 + --> tests/ui/let_with_type_underscore.rs:19:10 | LL | let x: _ = func(); | ^^^ error: variable declared with type underscore - --> tests/ui/let_with_type_underscore.rs:18:5 + --> tests/ui/let_with_type_underscore.rs:21:5 | LL | let x: _; | ^^^^^^^^^ | help: remove the explicit type `_` declaration - --> tests/ui/let_with_type_underscore.rs:18:10 + --> tests/ui/let_with_type_underscore.rs:21:10 | LL | let x: _; | ^^^ error: variable declared with type underscore - --> tests/ui/let_with_type_underscore.rs:25:5 + --> tests/ui/let_with_type_underscore.rs:29:5 | LL | let x : _ = 1; | ^^^^^^^^^^^^^^ | help: remove the explicit type `_` declaration - --> tests/ui/let_with_type_underscore.rs:25:10 + --> tests/ui/let_with_type_underscore.rs:29:10 | LL | let x : _ = 1; | ^^^^ diff --git a/tests/ui/lines_filter_map_ok.fixed b/tests/ui/lines_filter_map_ok.fixed index ae388ec39a15..977e31c744a2 100644 --- a/tests/ui/lines_filter_map_ok.fixed +++ b/tests/ui/lines_filter_map_ok.fixed @@ -7,20 +7,26 @@ fn main() -> io::Result<()> { let f = std::fs::File::open("/")?; // Lint BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ()); + //~^ lines_filter_map_ok // Lint let f = std::fs::File::open("/")?; BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ()); + //~^ lines_filter_map_ok // Lint let f = std::fs::File::open("/")?; BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ()); + //~^ lines_filter_map_ok let s = "foo\nbar\nbaz\n"; // Lint io::stdin().lines().map_while(Result::ok).for_each(|_| ()); + //~^ lines_filter_map_ok // Lint io::stdin().lines().map_while(Result::ok).for_each(|_| ()); + //~^ lines_filter_map_ok // Lint io::stdin().lines().map_while(Result::ok).for_each(|_| ()); + //~^ lines_filter_map_ok // Do not lint (not a `Lines` iterator) io::stdin() .lines() diff --git a/tests/ui/lines_filter_map_ok.rs b/tests/ui/lines_filter_map_ok.rs index 4f486534e9b0..2196075bc445 100644 --- a/tests/ui/lines_filter_map_ok.rs +++ b/tests/ui/lines_filter_map_ok.rs @@ -7,20 +7,26 @@ fn main() -> io::Result<()> { let f = std::fs::File::open("/")?; // Lint BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ()); + //~^ lines_filter_map_ok // Lint let f = std::fs::File::open("/")?; BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ()); + //~^ lines_filter_map_ok // Lint let f = std::fs::File::open("/")?; BufReader::new(f).lines().flatten().for_each(|_| ()); + //~^ lines_filter_map_ok let s = "foo\nbar\nbaz\n"; // Lint io::stdin().lines().filter_map(Result::ok).for_each(|_| ()); + //~^ lines_filter_map_ok // Lint io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ()); + //~^ lines_filter_map_ok // Lint io::stdin().lines().flatten().for_each(|_| ()); + //~^ lines_filter_map_ok // Do not lint (not a `Lines` iterator) io::stdin() .lines() diff --git a/tests/ui/lines_filter_map_ok.stderr b/tests/ui/lines_filter_map_ok.stderr index 558c0532be95..f9038eec9fb2 100644 --- a/tests/ui/lines_filter_map_ok.stderr +++ b/tests/ui/lines_filter_map_ok.stderr @@ -13,61 +13,61 @@ LL | BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ()); = help: to override `-D warnings` add `#[allow(clippy::lines_filter_map_ok)]` error: `flat_map()` will run forever if the iterator repeatedly produces an `Err` - --> tests/ui/lines_filter_map_ok.rs:12:31 + --> tests/ui/lines_filter_map_ok.rs:13:31 | LL | BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)` | note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error - --> tests/ui/lines_filter_map_ok.rs:12:5 + --> tests/ui/lines_filter_map_ok.rs:13:5 | LL | BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `flatten()` will run forever if the iterator repeatedly produces an `Err` - --> tests/ui/lines_filter_map_ok.rs:15:31 + --> tests/ui/lines_filter_map_ok.rs:17:31 | LL | BufReader::new(f).lines().flatten().for_each(|_| ()); | ^^^^^^^^^ help: replace with: `map_while(Result::ok)` | note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error - --> tests/ui/lines_filter_map_ok.rs:15:5 + --> tests/ui/lines_filter_map_ok.rs:17:5 | LL | BufReader::new(f).lines().flatten().for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `filter_map()` will run forever if the iterator repeatedly produces an `Err` - --> tests/ui/lines_filter_map_ok.rs:19:25 + --> tests/ui/lines_filter_map_ok.rs:22:25 | LL | io::stdin().lines().filter_map(Result::ok).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)` | note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error - --> tests/ui/lines_filter_map_ok.rs:19:5 + --> tests/ui/lines_filter_map_ok.rs:22:5 | LL | io::stdin().lines().filter_map(Result::ok).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^ error: `filter_map()` will run forever if the iterator repeatedly produces an `Err` - --> tests/ui/lines_filter_map_ok.rs:21:25 + --> tests/ui/lines_filter_map_ok.rs:25:25 | LL | io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)` | note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error - --> tests/ui/lines_filter_map_ok.rs:21:5 + --> tests/ui/lines_filter_map_ok.rs:25:5 | LL | io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^ error: `flatten()` will run forever if the iterator repeatedly produces an `Err` - --> tests/ui/lines_filter_map_ok.rs:23:25 + --> tests/ui/lines_filter_map_ok.rs:28:25 | LL | io::stdin().lines().flatten().for_each(|_| ()); | ^^^^^^^^^ help: replace with: `map_while(Result::ok)` | note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error - --> tests/ui/lines_filter_map_ok.rs:23:5 + --> tests/ui/lines_filter_map_ok.rs:28:5 | LL | io::stdin().lines().flatten().for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/linkedlist.rs b/tests/ui/linkedlist.rs index e1e6cff98097..eddbe730c174 100644 --- a/tests/ui/linkedlist.rs +++ b/tests/ui/linkedlist.rs @@ -6,17 +6,22 @@ extern crate alloc; use alloc::collections::linked_list::LinkedList; const C: LinkedList = LinkedList::new(); -//~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data structu +//~^ linkedlist + static S: LinkedList = LinkedList::new(); -//~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data structu +//~^ linkedlist + trait Foo { type Baz = LinkedList; - //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str + //~^ linkedlist + fn foo(_: LinkedList); - //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str + //~^ linkedlist + const BAR: Option>; - //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str + //~^ linkedlist + } // Ok, we don’t want to warn for implementations; see issue #605. @@ -27,20 +32,24 @@ impl Foo for LinkedList { pub struct Bar { priv_linked_list_field: LinkedList, - //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str + //~^ linkedlist + pub pub_linked_list_field: LinkedList, } impl Bar { fn foo(_: LinkedList) {} - //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str + //~^ linkedlist + } // All of these test should be trigger the lint because they are not // part of the public api fn test(my_favorite_linked_list: LinkedList) {} -//~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data structu +//~^ linkedlist + fn test_ret() -> Option> { - //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data structu +//~^ linkedlist + None } fn test_local_not_linted() { diff --git a/tests/ui/linkedlist.stderr b/tests/ui/linkedlist.stderr index d19176c7b0d2..22382d49e3a4 100644 --- a/tests/ui/linkedlist.stderr +++ b/tests/ui/linkedlist.stderr @@ -9,7 +9,7 @@ LL | const C: LinkedList = LinkedList::new(); = help: to override `-D warnings` add `#[allow(clippy::linkedlist)]` error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:10:11 + --> tests/ui/linkedlist.rs:11:11 | LL | static S: LinkedList = LinkedList::new(); | ^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | static S: LinkedList = LinkedList::new(); = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:14:16 + --> tests/ui/linkedlist.rs:16:16 | LL | type Baz = LinkedList; | ^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | type Baz = LinkedList; = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:16:15 + --> tests/ui/linkedlist.rs:19:15 | LL | fn foo(_: LinkedList); | ^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | fn foo(_: LinkedList); = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:18:23 + --> tests/ui/linkedlist.rs:22:23 | LL | const BAR: Option>; | ^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | const BAR: Option>; = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:29:29 + --> tests/ui/linkedlist.rs:34:29 | LL | priv_linked_list_field: LinkedList, | ^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | priv_linked_list_field: LinkedList, = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:34:15 + --> tests/ui/linkedlist.rs:40:15 | LL | fn foo(_: LinkedList) {} | ^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn foo(_: LinkedList) {} = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:40:34 + --> tests/ui/linkedlist.rs:47:34 | LL | fn test(my_favorite_linked_list: LinkedList) {} | ^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | fn test(my_favorite_linked_list: LinkedList) {} = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:42:25 + --> tests/ui/linkedlist.rs:50:25 | LL | fn test_ret() -> Option> { | ^^^^^^^^^^^^^^ diff --git a/tests/ui/literal_string_with_formatting_arg.rs b/tests/ui/literal_string_with_formatting_arg.rs index b9a6654d4276..b6f865b1ef28 100644 --- a/tests/ui/literal_string_with_formatting_arg.rs +++ b/tests/ui/literal_string_with_formatting_arg.rs @@ -40,7 +40,8 @@ fn main() { x.expect(r##" {y:?} {y:?} "##); //~ literal_string_with_formatting_args assert!("{y}".is_ascii()); //~ literal_string_with_formatting_args // Ensure that it doesn't try to go in the middle of a unicode character. - x.expect("———{:?}"); //~ literal_string_with_formatting_args + x.expect("———{:?}"); + //~^ literal_string_with_formatting_args // Should not lint! format!("{y:?}"); @@ -51,6 +52,7 @@ fn main() { x.expect("{{y:?}"); x.expect(" {0}"); // If it only contains an integer, we ignore it. x.expect(r##" {x:?} "##); // `x` doesn't exist so we shoud not lint + //~^ literal_string_with_formatting_args x.expect("{y:...}"); let _ = "fn main {\n\ }"; diff --git a/tests/ui/literal_string_with_formatting_arg.stderr b/tests/ui/literal_string_with_formatting_arg.stderr index 021983056bf6..55425d01c587 100644 --- a/tests/ui/literal_string_with_formatting_arg.stderr +++ b/tests/ui/literal_string_with_formatting_arg.stderr @@ -74,7 +74,7 @@ LL | x.expect("———{:?}"); | ^^^^ error: this looks like a formatting argument but it is not part of a formatting macro - --> tests/ui/literal_string_with_formatting_arg.rs:53:19 + --> tests/ui/literal_string_with_formatting_arg.rs:54:19 | LL | x.expect(r##" {x:?} "##); // `x` doesn't exist so we shoud not lint | ^^^^^ diff --git a/tests/ui/literals.rs b/tests/ui/literals.rs index c275b04d886b..300a2d7802dd 100644 --- a/tests/ui/literals.rs +++ b/tests/ui/literals.rs @@ -11,32 +11,44 @@ fn main() { let ok1 = 0xABCD; let ok3 = 0xab_cd; let ok4 = 0xab_cd_i32; - //~^ ERROR: integer type suffix should not be separated by an underscore - //~| NOTE: `-D clippy::separated-literal-suffix` implied by `-D warnings` + //~^ separated_literal_suffix + + let ok5 = 0xAB_CD_u32; - //~^ ERROR: integer type suffix should not be separated by an underscore + //~^ separated_literal_suffix + let ok5 = 0xAB_CD_isize; - //~^ ERROR: integer type suffix should not be separated by an underscore + //~^ separated_literal_suffix + let fail1 = 0xabCD; - //~^ ERROR: inconsistent casing in hexadecimal literal - //~| NOTE: `-D clippy::mixed-case-hex-literals` implied by `-D warnings` + //~^ mixed_case_hex_literals + + let fail2 = 0xabCD_u32; - //~^ ERROR: integer type suffix should not be separated by an underscore - //~| ERROR: inconsistent casing in hexadecimal literal + //~^ separated_literal_suffix + //~| mixed_case_hex_literals + + let fail2 = 0xabCD_isize; - //~^ ERROR: integer type suffix should not be separated by an underscore - //~| ERROR: inconsistent casing in hexadecimal literal + //~^ separated_literal_suffix + //~| mixed_case_hex_literals + + let fail_multi_zero = 000_123usize; - //~^ ERROR: integer type suffix should be separated by an underscore - //~| NOTE: `-D clippy::unseparated-literal-suffix` implied by `-D warnings` - //~| ERROR: this is a decimal constant - //~| NOTE: `-D clippy::zero-prefixed-literal` implied by `-D warnings` + //~^ unseparated_literal_suffix + //~| zero_prefixed_literal + + + + let ok9 = 0; let ok10 = 0_i64; - //~^ ERROR: integer type suffix should not be separated by an underscore + //~^ separated_literal_suffix + let fail8 = 0123; - //~^ ERROR: this is a decimal constant + //~^ zero_prefixed_literal + let ok11 = 0o123; let ok12 = 0b10_1010; @@ -46,20 +58,25 @@ fn main() { let ok15 = 0xab_cabc_abca_bcab_cabc; let ok16 = 0xFE_BAFE_ABAB_ABCD; let ok17 = 0x123_4567_8901_usize; - //~^ ERROR: integer type suffix should not be separated by an underscore + //~^ separated_literal_suffix + let ok18 = 0xF; let fail19 = 12_3456_21; - //~^ ERROR: digits grouped inconsistently by underscores - //~| NOTE: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings` + //~^ inconsistent_digit_grouping + + let fail22 = 3__4___23; - //~^ ERROR: digits grouped inconsistently by underscores + //~^ inconsistent_digit_grouping + let fail23 = 3__16___23; - //~^ ERROR: digits grouped inconsistently by underscores + //~^ inconsistent_digit_grouping + let fail24 = 0xAB_ABC_AB; - //~^ ERROR: digits of hex, binary or octal literal not in groups of equal size - //~| NOTE: `-D clippy::unusual-byte-groupings` implied by `-D warnings` + //~^ unusual_byte_groupings + + let fail25 = 0b01_100_101; let ok26 = 0x6_A0_BF; let ok27 = 0b1_0010_0101; @@ -68,9 +85,12 @@ fn main() { fn issue9651() { // lint but octal form is not possible here let _ = 08; - //~^ ERROR: this is a decimal constant + //~^ zero_prefixed_literal + let _ = 09; - //~^ ERROR: this is a decimal constant + //~^ zero_prefixed_literal + let _ = 089; - //~^ ERROR: this is a decimal constant + //~^ zero_prefixed_literal + } diff --git a/tests/ui/literals.stderr b/tests/ui/literals.stderr index 564e0bc4f747..1e19af071f82 100644 --- a/tests/ui/literals.stderr +++ b/tests/ui/literals.stderr @@ -8,19 +8,19 @@ LL | let ok4 = 0xab_cd_i32; = help: to override `-D warnings` add `#[allow(clippy::separated_literal_suffix)]` error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:16:15 + --> tests/ui/literals.rs:17:15 | LL | let ok5 = 0xAB_CD_u32; | ^^^^^^^^^^^ help: remove the underscore: `0xAB_CDu32` error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:18:15 + --> tests/ui/literals.rs:20:15 | LL | let ok5 = 0xAB_CD_isize; | ^^^^^^^^^^^^^ help: remove the underscore: `0xAB_CDisize` error: inconsistent casing in hexadecimal literal - --> tests/ui/literals.rs:20:17 + --> tests/ui/literals.rs:23:17 | LL | let fail1 = 0xabCD; | ^^^^^^ @@ -29,31 +29,31 @@ LL | let fail1 = 0xabCD; = help: to override `-D warnings` add `#[allow(clippy::mixed_case_hex_literals)]` error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:23:17 + --> tests/ui/literals.rs:27:17 | LL | let fail2 = 0xabCD_u32; | ^^^^^^^^^^ help: remove the underscore: `0xabCDu32` error: inconsistent casing in hexadecimal literal - --> tests/ui/literals.rs:23:17 + --> tests/ui/literals.rs:27:17 | LL | let fail2 = 0xabCD_u32; | ^^^^^^^^^^ error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:26:17 + --> tests/ui/literals.rs:32:17 | LL | let fail2 = 0xabCD_isize; | ^^^^^^^^^^^^ help: remove the underscore: `0xabCDisize` error: inconsistent casing in hexadecimal literal - --> tests/ui/literals.rs:26:17 + --> tests/ui/literals.rs:32:17 | LL | let fail2 = 0xabCD_isize; | ^^^^^^^^^^^^ error: integer type suffix should be separated by an underscore - --> tests/ui/literals.rs:29:27 + --> tests/ui/literals.rs:37:27 | LL | let fail_multi_zero = 000_123usize; | ^^^^^^^^^^^^ help: add an underscore: `000_123_usize` @@ -62,7 +62,7 @@ LL | let fail_multi_zero = 000_123usize; = help: to override `-D warnings` add `#[allow(clippy::unseparated_literal_suffix)]` error: this is a decimal constant - --> tests/ui/literals.rs:29:27 + --> tests/ui/literals.rs:37:27 | LL | let fail_multi_zero = 000_123usize; | ^^^^^^^^^^^^ @@ -79,13 +79,13 @@ LL | let fail_multi_zero = 0o123usize; | ~~~~~~~~~~ error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:36:16 + --> tests/ui/literals.rs:46:16 | LL | let ok10 = 0_i64; | ^^^^^ help: remove the underscore: `0i64` error: this is a decimal constant - --> tests/ui/literals.rs:38:17 + --> tests/ui/literals.rs:49:17 | LL | let fail8 = 0123; | ^^^^ @@ -100,13 +100,13 @@ LL | let fail8 = 0o123; | ~~~~~ error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:48:16 + --> tests/ui/literals.rs:60:16 | LL | let ok17 = 0x123_4567_8901_usize; | ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901usize` error: digits grouped inconsistently by underscores - --> tests/ui/literals.rs:52:18 + --> tests/ui/literals.rs:65:18 | LL | let fail19 = 12_3456_21; | ^^^^^^^^^^ help: consider: `12_345_621` @@ -115,19 +115,19 @@ LL | let fail19 = 12_3456_21; = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]` error: digits grouped inconsistently by underscores - --> tests/ui/literals.rs:55:18 + --> tests/ui/literals.rs:69:18 | LL | let fail22 = 3__4___23; | ^^^^^^^^^ help: consider: `3_423` error: digits grouped inconsistently by underscores - --> tests/ui/literals.rs:57:18 + --> tests/ui/literals.rs:72:18 | LL | let fail23 = 3__16___23; | ^^^^^^^^^^ help: consider: `31_623` error: digits of hex, binary or octal literal not in groups of equal size - --> tests/ui/literals.rs:60:18 + --> tests/ui/literals.rs:76:18 | LL | let fail24 = 0xAB_ABC_AB; | ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB` @@ -136,7 +136,7 @@ LL | let fail24 = 0xAB_ABC_AB; = help: to override `-D warnings` add `#[allow(clippy::unusual_byte_groupings)]` error: this is a decimal constant - --> tests/ui/literals.rs:70:13 + --> tests/ui/literals.rs:87:13 | LL | let _ = 08; | ^^ @@ -147,7 +147,7 @@ LL | let _ = 8; | ~ error: this is a decimal constant - --> tests/ui/literals.rs:72:13 + --> tests/ui/literals.rs:90:13 | LL | let _ = 09; | ^^ @@ -158,7 +158,7 @@ LL | let _ = 9; | ~ error: this is a decimal constant - --> tests/ui/literals.rs:74:13 + --> tests/ui/literals.rs:93:13 | LL | let _ = 089; | ^^^ diff --git a/tests/ui/lossy_float_literal.fixed b/tests/ui/lossy_float_literal.fixed index cc8c0b4a0d17..925a1465cc30 100644 --- a/tests/ui/lossy_float_literal.fixed +++ b/tests/ui/lossy_float_literal.fixed @@ -12,17 +12,28 @@ fn main() { let _: f16 = -4_097.0; let _: f32 = 16_777_216.0; + //~^ lossy_float_literal let _: f32 = 16_777_220.0; + //~^ lossy_float_literal let _: f32 = 16_777_220.0; + //~^ lossy_float_literal let _: f32 = 16_777_220.0; + //~^ lossy_float_literal let _ = 16_777_220_f32; + //~^ lossy_float_literal let _: f32 = -16_777_220.0; + //~^ lossy_float_literal let _: f64 = 9_007_199_254_740_992.0; + //~^ lossy_float_literal let _: f64 = 9_007_199_254_740_992.0; + //~^ lossy_float_literal let _: f64 = 9_007_199_254_740_992.0; + //~^ lossy_float_literal let _ = 9_007_199_254_740_992_f64; + //~^ lossy_float_literal let _: f64 = -9_007_199_254_740_992.0; + //~^ lossy_float_literal let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.0; let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.; diff --git a/tests/ui/lossy_float_literal.rs b/tests/ui/lossy_float_literal.rs index c84eef396d58..7341388d4816 100644 --- a/tests/ui/lossy_float_literal.rs +++ b/tests/ui/lossy_float_literal.rs @@ -12,17 +12,28 @@ fn main() { let _: f16 = -4_097.0; let _: f32 = 16_777_217.0; + //~^ lossy_float_literal let _: f32 = 16_777_219.0; + //~^ lossy_float_literal let _: f32 = 16_777_219.; + //~^ lossy_float_literal let _: f32 = 16_777_219.000; + //~^ lossy_float_literal let _ = 16_777_219f32; + //~^ lossy_float_literal let _: f32 = -16_777_219.0; + //~^ lossy_float_literal let _: f64 = 9_007_199_254_740_993.0; + //~^ lossy_float_literal let _: f64 = 9_007_199_254_740_993.; + //~^ lossy_float_literal let _: f64 = 9_007_199_254_740_993.00; + //~^ lossy_float_literal let _ = 9_007_199_254_740_993f64; + //~^ lossy_float_literal let _: f64 = -9_007_199_254_740_993.0; + //~^ lossy_float_literal let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.0; let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.; diff --git a/tests/ui/lossy_float_literal.stderr b/tests/ui/lossy_float_literal.stderr index 3026854e317a..a83f9a7aa241 100644 --- a/tests/ui/lossy_float_literal.stderr +++ b/tests/ui/lossy_float_literal.stderr @@ -12,7 +12,7 @@ LL | let _: f32 = 16_777_216.0; | ~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:15:18 + --> tests/ui/lossy_float_literal.rs:16:18 | LL | let _: f32 = 16_777_219.0; | ^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _: f32 = 16_777_220.0; | ~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:16:18 + --> tests/ui/lossy_float_literal.rs:18:18 | LL | let _: f32 = 16_777_219.; | ^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _: f32 = 16_777_220.0; | ~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:17:18 + --> tests/ui/lossy_float_literal.rs:20:18 | LL | let _: f32 = 16_777_219.000; | ^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _: f32 = 16_777_220.0; | ~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:18:13 + --> tests/ui/lossy_float_literal.rs:22:13 | LL | let _ = 16_777_219f32; | ^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _ = 16_777_220_f32; | ~~~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:19:19 + --> tests/ui/lossy_float_literal.rs:24:19 | LL | let _: f32 = -16_777_219.0; | ^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let _: f32 = -16_777_220.0; | ~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:21:18 + --> tests/ui/lossy_float_literal.rs:27:18 | LL | let _: f64 = 9_007_199_254_740_993.0; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _: f64 = 9_007_199_254_740_992.0; | ~~~~~~~~~~~~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:22:18 + --> tests/ui/lossy_float_literal.rs:29:18 | LL | let _: f64 = 9_007_199_254_740_993.; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _: f64 = 9_007_199_254_740_992.0; | ~~~~~~~~~~~~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:23:18 + --> tests/ui/lossy_float_literal.rs:31:18 | LL | let _: f64 = 9_007_199_254_740_993.00; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let _: f64 = 9_007_199_254_740_992.0; | ~~~~~~~~~~~~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:24:13 + --> tests/ui/lossy_float_literal.rs:33:13 | LL | let _ = 9_007_199_254_740_993f64; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _ = 9_007_199_254_740_992_f64; | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:25:19 + --> tests/ui/lossy_float_literal.rs:35:19 | LL | let _: f64 = -9_007_199_254_740_993.0; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/macro_use_imports.fixed b/tests/ui/macro_use_imports.fixed index 28844fab7479..d12222fce3eb 100644 --- a/tests/ui/macro_use_imports.fixed +++ b/tests/ui/macro_use_imports.fixed @@ -16,12 +16,16 @@ extern crate proc_macro_derive as mini_mac; mod a { use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro}; + //~^ macro_use_imports use mac; use mini_mac::ClippyMiniMacroTest; + //~^ macro_use_imports use mini_mac; use mac::{inner::mut_mut, inner::try_err}; + //~^ macro_use_imports use mac::inner; use mac::inner::nested::string_add; + //~^ macro_use_imports use mac::inner::nested; #[derive(ClippyMiniMacroTest)] diff --git a/tests/ui/macro_use_imports.rs b/tests/ui/macro_use_imports.rs index 5381f2959898..3baa9f8b5e59 100644 --- a/tests/ui/macro_use_imports.rs +++ b/tests/ui/macro_use_imports.rs @@ -16,12 +16,16 @@ extern crate proc_macro_derive as mini_mac; mod a { #[macro_use] + //~^ macro_use_imports use mac; #[macro_use] + //~^ macro_use_imports use mini_mac; #[macro_use] + //~^ macro_use_imports use mac::inner; #[macro_use] + //~^ macro_use_imports use mac::inner::nested; #[derive(ClippyMiniMacroTest)] diff --git a/tests/ui/macro_use_imports.stderr b/tests/ui/macro_use_imports.stderr index ea0670d36667..cdef5bc79e0c 100644 --- a/tests/ui/macro_use_imports.stderr +++ b/tests/ui/macro_use_imports.stderr @@ -8,19 +8,19 @@ LL | #[macro_use] = help: to override `-D warnings` add `#[allow(clippy::macro_use_imports)]` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> tests/ui/macro_use_imports.rs:22:5 + --> tests/ui/macro_use_imports.rs:24:5 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> tests/ui/macro_use_imports.rs:24:5 + --> tests/ui/macro_use_imports.rs:27:5 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> tests/ui/macro_use_imports.rs:20:5 + --> tests/ui/macro_use_imports.rs:21:5 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;` diff --git a/tests/ui/macro_use_imports_expect.rs b/tests/ui/macro_use_imports_expect.rs index 60cce1d24a28..115b30d3877f 100644 --- a/tests/ui/macro_use_imports_expect.rs +++ b/tests/ui/macro_use_imports_expect.rs @@ -1,3 +1,4 @@ +//@ check-pass //@aux-build:macro_rules.rs //@aux-build:macro_use_helper.rs //@aux-build:proc_macro_derive.rs diff --git a/tests/ui/manual_arithmetic_check-2.rs b/tests/ui/manual_arithmetic_check-2.rs index e97e3bdfef76..51515e7d9dcf 100644 --- a/tests/ui/manual_arithmetic_check-2.rs +++ b/tests/ui/manual_arithmetic_check-2.rs @@ -7,18 +7,24 @@ fn main() { let b = 13u32; let result = if a > b { b - a } else { 0 }; - //~^ ERROR: inverted arithmetic check before subtraction + //~^ inverted_saturating_sub + let result = if b < a { b - a } else { 0 }; - //~^ ERROR: inverted arithmetic check before subtraction + //~^ inverted_saturating_sub + let result = if a > b { 0 } else { a - b }; - //~^ ERROR: inverted arithmetic check before subtraction + //~^ inverted_saturating_sub + let result = if a >= b { 0 } else { a - b }; - //~^ ERROR: inverted arithmetic check before subtraction + //~^ inverted_saturating_sub + let result = if b < a { 0 } else { a - b }; - //~^ ERROR: inverted arithmetic check before subtraction + //~^ inverted_saturating_sub + let result = if b <= a { 0 } else { a - b }; - //~^ ERROR: inverted arithmetic check before subtraction + //~^ inverted_saturating_sub + let af = 12f32; let bf = 13f32; diff --git a/tests/ui/manual_arithmetic_check-2.stderr b/tests/ui/manual_arithmetic_check-2.stderr index 4121aa7464f0..3d51a8be670c 100644 --- a/tests/ui/manual_arithmetic_check-2.stderr +++ b/tests/ui/manual_arithmetic_check-2.stderr @@ -12,61 +12,61 @@ LL | let result = if a > b { b - a } else { 0 }; = note: `#[deny(clippy::inverted_saturating_sub)]` on by default error: inverted arithmetic check before subtraction - --> tests/ui/manual_arithmetic_check-2.rs:11:23 + --> tests/ui/manual_arithmetic_check-2.rs:12:23 | LL | let result = if b < a { b - a } else { 0 }; | ^ ----- help: try replacing it with: `a - b` | note: this subtraction underflows when `b < a` - --> tests/ui/manual_arithmetic_check-2.rs:11:29 + --> tests/ui/manual_arithmetic_check-2.rs:12:29 | LL | let result = if b < a { b - a } else { 0 }; | ^^^^^ error: inverted arithmetic check before subtraction - --> tests/ui/manual_arithmetic_check-2.rs:14:23 + --> tests/ui/manual_arithmetic_check-2.rs:16:23 | LL | let result = if a > b { 0 } else { a - b }; | ^ ----- help: try replacing it with: `b - a` | note: this subtraction underflows when `a < b` - --> tests/ui/manual_arithmetic_check-2.rs:14:40 + --> tests/ui/manual_arithmetic_check-2.rs:16:40 | LL | let result = if a > b { 0 } else { a - b }; | ^^^^^ error: inverted arithmetic check before subtraction - --> tests/ui/manual_arithmetic_check-2.rs:16:23 + --> tests/ui/manual_arithmetic_check-2.rs:19:23 | LL | let result = if a >= b { 0 } else { a - b }; | ^^ ----- help: try replacing it with: `b - a` | note: this subtraction underflows when `a < b` - --> tests/ui/manual_arithmetic_check-2.rs:16:41 + --> tests/ui/manual_arithmetic_check-2.rs:19:41 | LL | let result = if a >= b { 0 } else { a - b }; | ^^^^^ error: inverted arithmetic check before subtraction - --> tests/ui/manual_arithmetic_check-2.rs:18:23 + --> tests/ui/manual_arithmetic_check-2.rs:22:23 | LL | let result = if b < a { 0 } else { a - b }; | ^ ----- help: try replacing it with: `b - a` | note: this subtraction underflows when `a < b` - --> tests/ui/manual_arithmetic_check-2.rs:18:40 + --> tests/ui/manual_arithmetic_check-2.rs:22:40 | LL | let result = if b < a { 0 } else { a - b }; | ^^^^^ error: inverted arithmetic check before subtraction - --> tests/ui/manual_arithmetic_check-2.rs:20:23 + --> tests/ui/manual_arithmetic_check-2.rs:25:23 | LL | let result = if b <= a { 0 } else { a - b }; | ^^ ----- help: try replacing it with: `b - a` | note: this subtraction underflows when `a < b` - --> tests/ui/manual_arithmetic_check-2.rs:20:41 + --> tests/ui/manual_arithmetic_check-2.rs:25:41 | LL | let result = if b <= a { 0 } else { a - b }; | ^^^^^ diff --git a/tests/ui/manual_arithmetic_check.fixed b/tests/ui/manual_arithmetic_check.fixed index 29ecbb9ad2ad..5bda101c7b7c 100644 --- a/tests/ui/manual_arithmetic_check.fixed +++ b/tests/ui/manual_arithmetic_check.fixed @@ -7,14 +7,18 @@ fn main() { let c = 8u32; let result = a.saturating_sub(b); - //~^ ERROR: manual arithmetic check found - let result = a.saturating_sub(b); - //~^ ERROR: manual arithmetic check found + //~^ implicit_saturating_sub let result = a.saturating_sub(b); - //~^ ERROR: manual arithmetic check found + //~^ implicit_saturating_sub + + let result = a.saturating_sub(b); - //~^ ERROR: manual arithmetic check found + //~^ implicit_saturating_sub + + let result = a.saturating_sub(b); + //~^ implicit_saturating_sub + // Should not warn! let result = if a > b { a - b } else { a - c }; diff --git a/tests/ui/manual_arithmetic_check.rs b/tests/ui/manual_arithmetic_check.rs index 69554c6b61ca..ba296c736f01 100644 --- a/tests/ui/manual_arithmetic_check.rs +++ b/tests/ui/manual_arithmetic_check.rs @@ -7,14 +7,18 @@ fn main() { let c = 8u32; let result = if a > b { a - b } else { 0 }; - //~^ ERROR: manual arithmetic check found + //~^ implicit_saturating_sub + let result = if b < a { a - b } else { 0 }; - //~^ ERROR: manual arithmetic check found + //~^ implicit_saturating_sub + let result = if a < b { 0 } else { a - b }; - //~^ ERROR: manual arithmetic check found + //~^ implicit_saturating_sub + let result = if b > a { 0 } else { a - b }; - //~^ ERROR: manual arithmetic check found + //~^ implicit_saturating_sub + // Should not warn! let result = if a > b { a - b } else { a - c }; diff --git a/tests/ui/manual_arithmetic_check.stderr b/tests/ui/manual_arithmetic_check.stderr index b0cf73cd9151..fe5663f586f4 100644 --- a/tests/ui/manual_arithmetic_check.stderr +++ b/tests/ui/manual_arithmetic_check.stderr @@ -8,19 +8,19 @@ LL | let result = if a > b { a - b } else { 0 }; = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_sub)]` error: manual arithmetic check found - --> tests/ui/manual_arithmetic_check.rs:11:18 + --> tests/ui/manual_arithmetic_check.rs:12:18 | LL | let result = if b < a { a - b } else { 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)` error: manual arithmetic check found - --> tests/ui/manual_arithmetic_check.rs:14:18 + --> tests/ui/manual_arithmetic_check.rs:16:18 | LL | let result = if a < b { 0 } else { a - b }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)` error: manual arithmetic check found - --> tests/ui/manual_arithmetic_check.rs:16:18 + --> tests/ui/manual_arithmetic_check.rs:19:18 | LL | let result = if b > a { 0 } else { a - b }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)` diff --git a/tests/ui/manual_assert.edition2018.stderr b/tests/ui/manual_assert.edition2018.stderr index 004463720e26..f9fa8cf04d96 100644 --- a/tests/ui/manual_assert.edition2018.stderr +++ b/tests/ui/manual_assert.edition2018.stderr @@ -2,76 +2,123 @@ error: only a `panic!` in `if`-then statement --> tests/ui/manual_assert.rs:32:5 | LL | / if !a.is_empty() { +LL | | LL | | panic!("qaqaq{:?}", a); LL | | } - | |_____^ help: try instead: `assert!(a.is_empty(), "qaqaq{:?}", a);` + | |_____^ | = note: `-D clippy::manual-assert` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::manual_assert)]` +help: try instead + | +LL | assert!(a.is_empty(), "qaqaq{:?}", a); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:35:5 + --> tests/ui/manual_assert.rs:36:5 | LL | / if !a.is_empty() { +LL | | LL | | panic!("qwqwq"); LL | | } - | |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");` + | |_____^ + | +help: try instead + | +LL | assert!(a.is_empty(), "qwqwq"); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:52:5 + --> tests/ui/manual_assert.rs:54:5 | LL | / if b.is_empty() { +LL | | LL | | panic!("panic1"); LL | | } - | |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");` - -error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:55:5 + | |_____^ + | +help: try instead + | +LL | assert!(!b.is_empty(), "panic1"); | -LL | / if b.is_empty() && a.is_empty() { -LL | | panic!("panic2"); -LL | | } - | |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");` error: only a `panic!` in `if`-then statement --> tests/ui/manual_assert.rs:58:5 | +LL | / if b.is_empty() && a.is_empty() { +LL | | +LL | | panic!("panic2"); +LL | | } + | |_____^ + | +help: try instead + | +LL | assert!(!(b.is_empty() && a.is_empty()), "panic2"); + | + +error: only a `panic!` in `if`-then statement + --> tests/ui/manual_assert.rs:62:5 + | LL | / if a.is_empty() && !b.is_empty() { +LL | | LL | | panic!("panic3"); LL | | } - | |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");` + | |_____^ + | +help: try instead + | +LL | assert!(!(a.is_empty() && !b.is_empty()), "panic3"); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:61:5 + --> tests/ui/manual_assert.rs:66:5 | LL | / if b.is_empty() || a.is_empty() { +LL | | LL | | panic!("panic4"); LL | | } - | |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");` + | |_____^ + | +help: try instead + | +LL | assert!(!(b.is_empty() || a.is_empty()), "panic4"); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:64:5 + --> tests/ui/manual_assert.rs:70:5 | LL | / if a.is_empty() || !b.is_empty() { +LL | | LL | | panic!("panic5"); LL | | } - | |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");` + | |_____^ + | +help: try instead + | +LL | assert!(!(a.is_empty() || !b.is_empty()), "panic5"); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:67:5 + --> tests/ui/manual_assert.rs:74:5 | LL | / if a.is_empty() { +LL | | LL | | panic!("with expansion {}", one!()) LL | | } - | |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());` + | |_____^ + | +help: try instead + | +LL | assert!(!a.is_empty(), "with expansion {}", one!()); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:79:5 + --> tests/ui/manual_assert.rs:87:5 | LL | / if a > 2 { +LL | | LL | | // comment LL | | /* this is a -LL | | multiline ... | LL | | panic!("panic with comment") // comment after `panic!` LL | | } @@ -83,13 +130,19 @@ LL | assert!(!(a > 2), "panic with comment"); | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:93:25 + --> tests/ui/manual_assert.rs:102:25 | LL | const BAR: () = if N == 0 { | _________________________^ +LL | | LL | | panic!() LL | | }; - | |_________^ help: try instead: `assert!(!(N == 0), )` + | |_________^ + | +help: try instead + | +LL | const BAR: () = assert!(!(N == 0), ); + | ~~~~~~~~~~~~~~~~~~~~ error: aborting due to 10 previous errors diff --git a/tests/ui/manual_assert.edition2021.stderr b/tests/ui/manual_assert.edition2021.stderr index 004463720e26..f9fa8cf04d96 100644 --- a/tests/ui/manual_assert.edition2021.stderr +++ b/tests/ui/manual_assert.edition2021.stderr @@ -2,76 +2,123 @@ error: only a `panic!` in `if`-then statement --> tests/ui/manual_assert.rs:32:5 | LL | / if !a.is_empty() { +LL | | LL | | panic!("qaqaq{:?}", a); LL | | } - | |_____^ help: try instead: `assert!(a.is_empty(), "qaqaq{:?}", a);` + | |_____^ | = note: `-D clippy::manual-assert` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::manual_assert)]` +help: try instead + | +LL | assert!(a.is_empty(), "qaqaq{:?}", a); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:35:5 + --> tests/ui/manual_assert.rs:36:5 | LL | / if !a.is_empty() { +LL | | LL | | panic!("qwqwq"); LL | | } - | |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");` + | |_____^ + | +help: try instead + | +LL | assert!(a.is_empty(), "qwqwq"); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:52:5 + --> tests/ui/manual_assert.rs:54:5 | LL | / if b.is_empty() { +LL | | LL | | panic!("panic1"); LL | | } - | |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");` - -error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:55:5 + | |_____^ + | +help: try instead + | +LL | assert!(!b.is_empty(), "panic1"); | -LL | / if b.is_empty() && a.is_empty() { -LL | | panic!("panic2"); -LL | | } - | |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");` error: only a `panic!` in `if`-then statement --> tests/ui/manual_assert.rs:58:5 | +LL | / if b.is_empty() && a.is_empty() { +LL | | +LL | | panic!("panic2"); +LL | | } + | |_____^ + | +help: try instead + | +LL | assert!(!(b.is_empty() && a.is_empty()), "panic2"); + | + +error: only a `panic!` in `if`-then statement + --> tests/ui/manual_assert.rs:62:5 + | LL | / if a.is_empty() && !b.is_empty() { +LL | | LL | | panic!("panic3"); LL | | } - | |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");` + | |_____^ + | +help: try instead + | +LL | assert!(!(a.is_empty() && !b.is_empty()), "panic3"); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:61:5 + --> tests/ui/manual_assert.rs:66:5 | LL | / if b.is_empty() || a.is_empty() { +LL | | LL | | panic!("panic4"); LL | | } - | |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");` + | |_____^ + | +help: try instead + | +LL | assert!(!(b.is_empty() || a.is_empty()), "panic4"); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:64:5 + --> tests/ui/manual_assert.rs:70:5 | LL | / if a.is_empty() || !b.is_empty() { +LL | | LL | | panic!("panic5"); LL | | } - | |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");` + | |_____^ + | +help: try instead + | +LL | assert!(!(a.is_empty() || !b.is_empty()), "panic5"); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:67:5 + --> tests/ui/manual_assert.rs:74:5 | LL | / if a.is_empty() { +LL | | LL | | panic!("with expansion {}", one!()) LL | | } - | |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());` + | |_____^ + | +help: try instead + | +LL | assert!(!a.is_empty(), "with expansion {}", one!()); + | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:79:5 + --> tests/ui/manual_assert.rs:87:5 | LL | / if a > 2 { +LL | | LL | | // comment LL | | /* this is a -LL | | multiline ... | LL | | panic!("panic with comment") // comment after `panic!` LL | | } @@ -83,13 +130,19 @@ LL | assert!(!(a > 2), "panic with comment"); | error: only a `panic!` in `if`-then statement - --> tests/ui/manual_assert.rs:93:25 + --> tests/ui/manual_assert.rs:102:25 | LL | const BAR: () = if N == 0 { | _________________________^ +LL | | LL | | panic!() LL | | }; - | |_________^ help: try instead: `assert!(!(N == 0), )` + | |_________^ + | +help: try instead + | +LL | const BAR: () = assert!(!(N == 0), ); + | ~~~~~~~~~~~~~~~~~~~~ error: aborting due to 10 previous errors diff --git a/tests/ui/manual_assert.rs b/tests/ui/manual_assert.rs index 6337920a3eea..2c9b17bb8b1b 100644 --- a/tests/ui/manual_assert.rs +++ b/tests/ui/manual_assert.rs @@ -30,9 +30,11 @@ fn main() { panic!("qaqaq{:?}", a); } if !a.is_empty() { + //~^ manual_assert panic!("qaqaq{:?}", a); } if !a.is_empty() { + //~^ manual_assert panic!("qwqwq"); } if a.len() == 3 { @@ -50,21 +52,27 @@ fn main() { } let b = vec![1, 2, 3]; if b.is_empty() { + //~^ manual_assert panic!("panic1"); } if b.is_empty() && a.is_empty() { + //~^ manual_assert panic!("panic2"); } if a.is_empty() && !b.is_empty() { + //~^ manual_assert panic!("panic3"); } if b.is_empty() || a.is_empty() { + //~^ manual_assert panic!("panic4"); } if a.is_empty() || !b.is_empty() { + //~^ manual_assert panic!("panic5"); } if a.is_empty() { + //~^ manual_assert panic!("with expansion {}", one!()) } if a.is_empty() { @@ -77,6 +85,7 @@ fn main() { fn issue7730(a: u8) { // Suggestion should preserve comment if a > 2 { + //~^ manual_assert // comment /* this is a multiline @@ -91,6 +100,7 @@ fn issue12505() { impl Foo { const BAR: () = if N == 0 { + //~^ manual_assert panic!() }; } diff --git a/tests/ui/manual_async_fn.rs b/tests/ui/manual_async_fn.rs index 87973222c0bb..a699e40868d7 100644 --- a/tests/ui/manual_async_fn.rs +++ b/tests/ui/manual_async_fn.rs @@ -4,34 +4,41 @@ use std::future::Future; fn fut() -> impl Future { +//~^ manual_async_fn async { 42 } } #[rustfmt::skip] fn fut2() ->impl Future { +//~^ manual_async_fn async { 42 } } #[rustfmt::skip] fn fut3()-> impl Future { +//~^ manual_async_fn async { 42 } } fn empty_fut() -> impl Future { +//~^ manual_async_fn async {} } #[rustfmt::skip] fn empty_fut2() ->impl Future { +//~^ manual_async_fn async {} } #[rustfmt::skip] fn empty_fut3()-> impl Future { +//~^ manual_async_fn async {} } fn core_fut() -> impl core::future::Future { +//~^ manual_async_fn async move { 42 } } @@ -54,6 +61,7 @@ async fn already_async() -> impl Future { struct S; impl S { fn inh_fut() -> impl Future { + //~^ manual_async_fn async { // NOTE: this code is here just to check that the indentation is correct in the suggested fix let a = 42; @@ -89,6 +97,7 @@ impl S { // Tests related to lifetime capture fn elided(_: &i32) -> impl Future + '_ { +//~^ manual_async_fn async { 42 } } @@ -99,6 +108,7 @@ fn elided_not_bound(_: &i32) -> impl Future { #[allow(clippy::needless_lifetimes)] fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { +//~^ manual_async_fn async { 42 } } @@ -128,14 +138,17 @@ mod issue_5765 { } pub fn issue_10450() -> impl Future { +//~^ manual_async_fn async { 42 } } pub(crate) fn issue_10450_2() -> impl Future { +//~^ manual_async_fn async { 42 } } pub(self) fn issue_10450_3() -> impl Future { +//~^ manual_async_fn async { 42 } } diff --git a/tests/ui/manual_async_fn.stderr b/tests/ui/manual_async_fn.stderr index 68a97243436d..5d063e550f28 100644 --- a/tests/ui/manual_async_fn.stderr +++ b/tests/ui/manual_async_fn.stderr @@ -12,7 +12,7 @@ LL | async fn fut() -> i32 { 42 } | ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:11:1 + --> tests/ui/manual_async_fn.rs:12:1 | LL | fn fut2() ->impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | async fn fut2() -> i32 { 42 } | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:16:1 + --> tests/ui/manual_async_fn.rs:18:1 | LL | fn fut3()-> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | async fn fut3() -> i32 { 42 } | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:20:1 + --> tests/ui/manual_async_fn.rs:23:1 | LL | fn empty_fut() -> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | async fn empty_fut() {} | ~~~~~~~~~~~~~~~~~~~~ ~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:25:1 + --> tests/ui/manual_async_fn.rs:29:1 | LL | fn empty_fut2() ->impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | async fn empty_fut2() {} | ~~~~~~~~~~~~~~~~~~~~~ ~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:30:1 + --> tests/ui/manual_async_fn.rs:35:1 | LL | fn empty_fut3()-> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | async fn empty_fut3() {} | ~~~~~~~~~~~~~~~~~~~~~ ~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:34:1 + --> tests/ui/manual_async_fn.rs:40:1 | LL | fn core_fut() -> impl core::future::Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | async fn core_fut() -> i32 { 42 } | ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:56:5 + --> tests/ui/manual_async_fn.rs:63:5 | LL | fn inh_fut() -> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -101,7 +101,7 @@ LL + } | error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:91:1 + --> tests/ui/manual_async_fn.rs:99:1 | LL | fn elided(_: &i32) -> impl Future + '_ { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +112,7 @@ LL | async fn elided(_: &i32) -> i32 { 42 } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:101:1 + --> tests/ui/manual_async_fn.rs:110:1 | LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ LL | async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:130:1 + --> tests/ui/manual_async_fn.rs:140:1 | LL | pub fn issue_10450() -> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -134,7 +134,7 @@ LL | pub async fn issue_10450() -> i32 { 42 } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:134:1 + --> tests/ui/manual_async_fn.rs:145:1 | LL | pub(crate) fn issue_10450_2() -> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | pub(crate) async fn issue_10450_2() -> i32 { 42 } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ error: this function can be simplified using the `async fn` syntax - --> tests/ui/manual_async_fn.rs:138:1 + --> tests/ui/manual_async_fn.rs:150:1 | LL | pub(self) fn issue_10450_3() -> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/manual_bits.fixed b/tests/ui/manual_bits.fixed index 8e5cb7d38b9b..db2ad2ace625 100644 --- a/tests/ui/manual_bits.fixed +++ b/tests/ui/manual_bits.fixed @@ -12,32 +12,56 @@ use std::mem::{size_of, size_of_val}; fn main() { i8::BITS as usize; + //~^ manual_bits i16::BITS as usize; + //~^ manual_bits i32::BITS as usize; + //~^ manual_bits i64::BITS as usize; + //~^ manual_bits i128::BITS as usize; + //~^ manual_bits isize::BITS as usize; + //~^ manual_bits u8::BITS as usize; + //~^ manual_bits u16::BITS as usize; + //~^ manual_bits u32::BITS as usize; + //~^ manual_bits u64::BITS as usize; + //~^ manual_bits u128::BITS as usize; + //~^ manual_bits usize::BITS as usize; + //~^ manual_bits i8::BITS as usize; + //~^ manual_bits i16::BITS as usize; + //~^ manual_bits i32::BITS as usize; + //~^ manual_bits i64::BITS as usize; + //~^ manual_bits i128::BITS as usize; + //~^ manual_bits isize::BITS as usize; + //~^ manual_bits u8::BITS as usize; + //~^ manual_bits u16::BITS as usize; + //~^ manual_bits u32::BITS as usize; + //~^ manual_bits u64::BITS as usize; + //~^ manual_bits u128::BITS as usize; + //~^ manual_bits usize::BITS as usize; + //~^ manual_bits size_of::() * 4; 4 * size_of::(); @@ -48,13 +72,18 @@ fn main() { type Word = u32; Word::BITS as usize; + //~^ manual_bits type Bool = bool; size_of::() * 8; let _: u32 = u128::BITS as u32; + //~^ manual_bits let _: u32 = u128::BITS.try_into().unwrap(); + //~^ manual_bits let _ = (u128::BITS as usize).pow(5); + //~^ manual_bits let _ = &(u128::BITS as usize); + //~^ manual_bits } fn should_not_lint() { diff --git a/tests/ui/manual_bits.rs b/tests/ui/manual_bits.rs index 5e492ed15d21..6d1f0de1c19d 100644 --- a/tests/ui/manual_bits.rs +++ b/tests/ui/manual_bits.rs @@ -12,32 +12,56 @@ use std::mem::{size_of, size_of_val}; fn main() { size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits size_of::() * 8; + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits 8 * size_of::(); + //~^ manual_bits size_of::() * 4; 4 * size_of::(); @@ -48,13 +72,18 @@ fn main() { type Word = u32; size_of::() * 8; + //~^ manual_bits type Bool = bool; size_of::() * 8; let _: u32 = (size_of::() * 8) as u32; + //~^ manual_bits let _: u32 = (size_of::() * 8).try_into().unwrap(); + //~^ manual_bits let _ = (size_of::() * 8).pow(5); + //~^ manual_bits let _ = &(size_of::() * 8); + //~^ manual_bits } fn should_not_lint() { diff --git a/tests/ui/manual_bits.stderr b/tests/ui/manual_bits.stderr index 4383aa49df9b..a50975ed474e 100644 --- a/tests/ui/manual_bits.stderr +++ b/tests/ui/manual_bits.stderr @@ -8,169 +8,169 @@ LL | size_of::() * 8; = help: to override `-D warnings` add `#[allow(clippy::manual_bits)]` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:15:5 + --> tests/ui/manual_bits.rs:16:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:16:5 + --> tests/ui/manual_bits.rs:18:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:17:5 + --> tests/ui/manual_bits.rs:20:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:18:5 + --> tests/ui/manual_bits.rs:22:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:19:5 + --> tests/ui/manual_bits.rs:24:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:21:5 + --> tests/ui/manual_bits.rs:27:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:22:5 + --> tests/ui/manual_bits.rs:29:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:23:5 + --> tests/ui/manual_bits.rs:31:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:24:5 + --> tests/ui/manual_bits.rs:33:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:25:5 + --> tests/ui/manual_bits.rs:35:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:26:5 + --> tests/ui/manual_bits.rs:37:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:28:5 + --> tests/ui/manual_bits.rs:40:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:29:5 + --> tests/ui/manual_bits.rs:42:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:30:5 + --> tests/ui/manual_bits.rs:44:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:31:5 + --> tests/ui/manual_bits.rs:46:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:32:5 + --> tests/ui/manual_bits.rs:48:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:33:5 + --> tests/ui/manual_bits.rs:50:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:35:5 + --> tests/ui/manual_bits.rs:53:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:36:5 + --> tests/ui/manual_bits.rs:55:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:37:5 + --> tests/ui/manual_bits.rs:57:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:38:5 + --> tests/ui/manual_bits.rs:59:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:39:5 + --> tests/ui/manual_bits.rs:61:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:40:5 + --> tests/ui/manual_bits.rs:63:5 | LL | 8 * size_of::(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:50:5 + --> tests/ui/manual_bits.rs:74:5 | LL | size_of::() * 8; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS as usize` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:54:18 + --> tests/ui/manual_bits.rs:79:18 | LL | let _: u32 = (size_of::() * 8) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:55:18 + --> tests/ui/manual_bits.rs:81:18 | LL | let _: u32 = (size_of::() * 8).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:56:13 + --> tests/ui/manual_bits.rs:83:13 | LL | let _ = (size_of::() * 8).pow(5); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)` error: usage of `mem::size_of::()` to obtain the size of `T` in bits - --> tests/ui/manual_bits.rs:57:14 + --> tests/ui/manual_bits.rs:85:14 | LL | let _ = &(size_of::() * 8); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)` diff --git a/tests/ui/manual_c_str_literals.edition2021.fixed b/tests/ui/manual_c_str_literals.edition2021.fixed index 391c63bb4b89..3ffaef0386ce 100644 --- a/tests/ui/manual_c_str_literals.edition2021.fixed +++ b/tests/ui/manual_c_str_literals.edition2021.fixed @@ -1,6 +1,7 @@ //@revisions: edition2018 edition2021 //@[edition2018] edition:2018 //@[edition2021] edition:2021 +//@[edition2018] check-pass #![warn(clippy::manual_c_str_literals)] #![allow(clippy::no_effect)] @@ -32,29 +33,42 @@ fn pre_stabilization() { #[clippy::msrv = "1.77.0"] fn post_stabilization() { c"foo"; + //~[edition2021]^ manual_c_str_literals } fn main() { c"foo"; + //~[edition2021]^ manual_c_str_literals c"foo"; + //~[edition2021]^ manual_c_str_literals c"foo"; + //~[edition2021]^ manual_c_str_literals c"foo\\0sdsd"; + //~[edition2021]^ manual_c_str_literals CStr::from_bytes_with_nul(br"foo\\0sdsd\0").unwrap(); CStr::from_bytes_with_nul(br"foo\x00").unwrap(); CStr::from_bytes_with_nul(br##"foo#a\0"##).unwrap(); unsafe { c"foo" }; + //~[edition2021]^ manual_c_str_literals unsafe { c"foo" }; + //~[edition2021]^ manual_c_str_literals let _: *const _ = c"foo".as_ptr(); + //~[edition2021]^ manual_c_str_literals let _: *const _ = c"foo".as_ptr(); + //~[edition2021]^ manual_c_str_literals let _: *const _ = "foo".as_ptr(); // not a C-string let _: *const _ = "".as_ptr(); let _: *const _ = c"foo".as_ptr().cast::(); + //~[edition2021]^ manual_c_str_literals let _ = "电脑".as_ptr(); let _ = "电脑\\".as_ptr(); let _ = c"电脑\\".as_ptr(); + //~[edition2021]^ manual_c_str_literals let _ = c"电脑".as_ptr(); + //~[edition2021]^ manual_c_str_literals let _ = c"电脑".as_ptr(); + //~[edition2021]^ manual_c_str_literals // Macro cases, don't lint: cstr!("foo"); diff --git a/tests/ui/manual_c_str_literals.edition2021.stderr b/tests/ui/manual_c_str_literals.edition2021.stderr index beab29ccdda0..2119bbc5b425 100644 --- a/tests/ui/manual_c_str_literals.edition2021.stderr +++ b/tests/ui/manual_c_str_literals.edition2021.stderr @@ -1,5 +1,5 @@ error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:34:5 + --> tests/ui/manual_c_str_literals.rs:35:5 | LL | CStr::from_bytes_with_nul(b"foo\0"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` @@ -8,73 +8,73 @@ LL | CStr::from_bytes_with_nul(b"foo\0"); = help: to override `-D warnings` add `#[allow(clippy::manual_c_str_literals)]` error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:38:5 + --> tests/ui/manual_c_str_literals.rs:40:5 | LL | CStr::from_bytes_with_nul(b"foo\0"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:39:5 + --> tests/ui/manual_c_str_literals.rs:42:5 | LL | CStr::from_bytes_with_nul(b"foo\x00"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:40:5 + --> tests/ui/manual_c_str_literals.rs:44:5 | LL | CStr::from_bytes_with_nul(b"foo\0").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:41:5 + --> tests/ui/manual_c_str_literals.rs:46:5 | LL | CStr::from_bytes_with_nul(b"foo\\0sdsd\0").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo\\0sdsd"` error: calling `CStr::from_ptr` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:46:14 + --> tests/ui/manual_c_str_literals.rs:52:14 | LL | unsafe { CStr::from_ptr(b"foo\0".as_ptr().cast()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` error: calling `CStr::from_ptr` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:47:14 + --> tests/ui/manual_c_str_literals.rs:54:14 | LL | unsafe { CStr::from_ptr(b"foo\0".as_ptr() as *const _) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:48:23 + --> tests/ui/manual_c_str_literals.rs:56:23 | LL | let _: *const _ = b"foo\0".as_ptr(); | ^^^^^^^^ help: use a `c""` literal: `c"foo"` error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:49:23 + --> tests/ui/manual_c_str_literals.rs:58:23 | LL | let _: *const _ = "foo\0".as_ptr(); | ^^^^^^^ help: use a `c""` literal: `c"foo"` error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:52:23 + --> tests/ui/manual_c_str_literals.rs:62:23 | LL | let _: *const _ = b"foo\0".as_ptr().cast::(); | ^^^^^^^^ help: use a `c""` literal: `c"foo"` error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:55:13 + --> tests/ui/manual_c_str_literals.rs:66:13 | LL | let _ = "电脑\\\0".as_ptr(); | ^^^^^^^^^^ help: use a `c""` literal: `c"电脑\\"` error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:56:13 + --> tests/ui/manual_c_str_literals.rs:68:13 | LL | let _ = "电脑\0".as_ptr(); | ^^^^^^^^ help: use a `c""` literal: `c"电脑"` error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:57:13 + --> tests/ui/manual_c_str_literals.rs:70:13 | LL | let _ = "电脑\x00".as_ptr(); | ^^^^^^^^^^ help: use a `c""` literal: `c"电脑"` diff --git a/tests/ui/manual_c_str_literals.rs b/tests/ui/manual_c_str_literals.rs index 39b622580774..ec3b8e587724 100644 --- a/tests/ui/manual_c_str_literals.rs +++ b/tests/ui/manual_c_str_literals.rs @@ -1,6 +1,7 @@ //@revisions: edition2018 edition2021 //@[edition2018] edition:2018 //@[edition2021] edition:2021 +//@[edition2018] check-pass #![warn(clippy::manual_c_str_literals)] #![allow(clippy::no_effect)] @@ -32,29 +33,42 @@ fn pre_stabilization() { #[clippy::msrv = "1.77.0"] fn post_stabilization() { CStr::from_bytes_with_nul(b"foo\0"); + //~[edition2021]^ manual_c_str_literals } fn main() { CStr::from_bytes_with_nul(b"foo\0"); + //~[edition2021]^ manual_c_str_literals CStr::from_bytes_with_nul(b"foo\x00"); + //~[edition2021]^ manual_c_str_literals CStr::from_bytes_with_nul(b"foo\0").unwrap(); + //~[edition2021]^ manual_c_str_literals CStr::from_bytes_with_nul(b"foo\\0sdsd\0").unwrap(); + //~[edition2021]^ manual_c_str_literals CStr::from_bytes_with_nul(br"foo\\0sdsd\0").unwrap(); CStr::from_bytes_with_nul(br"foo\x00").unwrap(); CStr::from_bytes_with_nul(br##"foo#a\0"##).unwrap(); unsafe { CStr::from_ptr(b"foo\0".as_ptr().cast()) }; + //~[edition2021]^ manual_c_str_literals unsafe { CStr::from_ptr(b"foo\0".as_ptr() as *const _) }; + //~[edition2021]^ manual_c_str_literals let _: *const _ = b"foo\0".as_ptr(); + //~[edition2021]^ manual_c_str_literals let _: *const _ = "foo\0".as_ptr(); + //~[edition2021]^ manual_c_str_literals let _: *const _ = "foo".as_ptr(); // not a C-string let _: *const _ = "".as_ptr(); let _: *const _ = b"foo\0".as_ptr().cast::(); + //~[edition2021]^ manual_c_str_literals let _ = "电脑".as_ptr(); let _ = "电脑\\".as_ptr(); let _ = "电脑\\\0".as_ptr(); + //~[edition2021]^ manual_c_str_literals let _ = "电脑\0".as_ptr(); + //~[edition2021]^ manual_c_str_literals let _ = "电脑\x00".as_ptr(); + //~[edition2021]^ manual_c_str_literals // Macro cases, don't lint: cstr!("foo"); diff --git a/tests/ui/manual_clamp.fixed b/tests/ui/manual_clamp.fixed index 8d57cbbf51bf..1e2b1d009907 100644 --- a/tests/ui/manual_clamp.fixed +++ b/tests/ui/manual_clamp.fixed @@ -150,12 +150,14 @@ fn const_main() { let x3 = input.clamp(CONST_MIN, CONST_MAX); let x4 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x5 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x6 = input.clamp(CONST_MIN, CONST_MAX); @@ -187,54 +189,70 @@ fn const_main() { let input: i32 = cmp_min_max(1); // These can only be detected if exactly one of the arguments to the inner function is const. let x16 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x17 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x18 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x19 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x20 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x21 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x22 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x23 = input.clamp(CONST_MIN, CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let input: f64 = cmp_min_max(1) as f64; let x24 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x25 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x26 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x27 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x28 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x29 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x30 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x31 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + } let mut x32 = input; x32 = x32.clamp(CONST_MIN, CONST_MAX); diff --git a/tests/ui/manual_clamp.rs b/tests/ui/manual_clamp.rs index 4d2a0c47bbd7..bf40e09969a4 100644 --- a/tests/ui/manual_clamp.rs +++ b/tests/ui/manual_clamp.rs @@ -142,8 +142,9 @@ fn const_main() { let input = 0; // Min and max are const, so this should trigger the lint. let x0 = if CONST_MAX < input { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + CONST_MAX } else if CONST_MIN > input { CONST_MIN @@ -152,8 +153,9 @@ fn const_main() { }; let x1 = if input > CONST_MAX { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + CONST_MAX } else if input < CONST_MIN { CONST_MIN @@ -162,8 +164,9 @@ fn const_main() { }; let x2 = if input < CONST_MIN { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + CONST_MIN } else if input > CONST_MAX { CONST_MAX @@ -172,8 +175,9 @@ fn const_main() { }; let x3 = if CONST_MIN > input { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + CONST_MIN } else if CONST_MAX < input { CONST_MAX @@ -182,32 +186,37 @@ fn const_main() { }; let x4 = input.max(CONST_MIN).min(CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x5 = input.min(CONST_MAX).max(CONST_MIN); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x6 = match input { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x if x > CONST_MAX => CONST_MAX, x if x < CONST_MIN => CONST_MIN, x => x, }; let x7 = match input { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x if x < CONST_MIN => CONST_MIN, x if x > CONST_MAX => CONST_MAX, x => x, }; let x8 = match input { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x if CONST_MAX < x => CONST_MAX, x if CONST_MIN > x => CONST_MIN, x => x, @@ -215,8 +224,9 @@ fn const_main() { let mut x9 = input; if x9 < CONST_MIN { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x9 = CONST_MIN; } if x9 > CONST_MAX { @@ -224,8 +234,9 @@ fn const_main() { } let x10 = match input { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x if CONST_MIN > x => CONST_MIN, x if CONST_MAX < x => CONST_MAX, x => x, @@ -234,8 +245,9 @@ fn const_main() { let mut x11 = input; let _ = 1; if x11 > CONST_MAX { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x11 = CONST_MAX; } if x11 < CONST_MIN { @@ -244,8 +256,9 @@ fn const_main() { let mut x12 = input; if CONST_MIN > x12 { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x12 = CONST_MIN; } if CONST_MAX < x12 { @@ -254,8 +267,9 @@ fn const_main() { let mut x13 = input; if CONST_MAX < x13 { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x13 = CONST_MAX; } if CONST_MIN > x13 { @@ -263,8 +277,9 @@ fn const_main() { } let x14 = if input > CONST_MAX { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + CONST_MAX } else if input < CONST_MIN { CONST_MIN @@ -274,8 +289,9 @@ fn const_main() { { let input = 0.0f64; let x15 = if input > CONST_F64_MAX { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + CONST_F64_MAX } else if input < CONST_F64_MIN { CONST_F64_MIN @@ -287,59 +303,76 @@ fn const_main() { let input: i32 = cmp_min_max(1); // These can only be detected if exactly one of the arguments to the inner function is const. let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + let input: f64 = cmp_min_max(1) as f64; let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan() + //~^ manual_clamp + + } let mut x32 = input; if x32 < CONST_MIN { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x32 = CONST_MIN; } else if x32 > CONST_MAX { x32 = CONST_MAX; @@ -368,8 +401,9 @@ fn const_main() { // It's important this be the last set of statements let mut x35 = input; if CONST_MAX < x35 { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + x35 = CONST_MAX; } if CONST_MIN > x35 { @@ -530,8 +564,9 @@ fn msrv_1_49() { fn msrv_1_50() { let input = 0; let _ = if input > CONST_MAX { - //~^ ERROR: clamp-like pattern without using clamp function - //~| NOTE: clamp will panic if max < min + //~^ manual_clamp + + CONST_MAX } else if input < CONST_MIN { CONST_MIN diff --git a/tests/ui/manual_clamp.stderr b/tests/ui/manual_clamp.stderr index 459d46796d87..ca7da23efec2 100644 --- a/tests/ui/manual_clamp.stderr +++ b/tests/ui/manual_clamp.stderr @@ -1,10 +1,7 @@ error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:217:5 + --> tests/ui/manual_clamp.rs:226:5 | LL | / if x9 < CONST_MIN { -LL | | -LL | | -LL | | x9 = CONST_MIN; ... | LL | | x9 = CONST_MAX; LL | | } @@ -15,12 +12,9 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_clamp)]` error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:236:5 + --> tests/ui/manual_clamp.rs:247:5 | LL | / if x11 > CONST_MAX { -LL | | -LL | | -LL | | x11 = CONST_MAX; ... | LL | | x11 = CONST_MIN; LL | | } @@ -29,12 +23,9 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:246:5 + --> tests/ui/manual_clamp.rs:258:5 | LL | / if CONST_MIN > x12 { -LL | | -LL | | -LL | | x12 = CONST_MIN; ... | LL | | x12 = CONST_MAX; LL | | } @@ -43,12 +34,9 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:256:5 + --> tests/ui/manual_clamp.rs:269:5 | LL | / if CONST_MAX < x13 { -LL | | -LL | | -LL | | x13 = CONST_MAX; ... | LL | | x13 = CONST_MIN; LL | | } @@ -57,12 +45,9 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:370:5 + --> tests/ui/manual_clamp.rs:403:5 | LL | / if CONST_MAX < x35 { -LL | | -LL | | -LL | | x35 = CONST_MAX; ... | LL | | x35 = CONST_MIN; LL | | } @@ -75,9 +60,6 @@ error: clamp-like pattern without using clamp function | LL | let x0 = if CONST_MAX < input { | ______________^ -LL | | -LL | | -LL | | CONST_MAX ... | LL | | input LL | | }; @@ -86,13 +68,10 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:154:14 + --> tests/ui/manual_clamp.rs:155:14 | LL | let x1 = if input > CONST_MAX { | ______________^ -LL | | -LL | | -LL | | CONST_MAX ... | LL | | input LL | | }; @@ -101,13 +80,10 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:164:14 + --> tests/ui/manual_clamp.rs:166:14 | LL | let x2 = if input < CONST_MIN { | ______________^ -LL | | -LL | | -LL | | CONST_MIN ... | LL | | input LL | | }; @@ -116,13 +92,10 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:174:14 + --> tests/ui/manual_clamp.rs:177:14 | LL | let x3 = if CONST_MIN > input { | ______________^ -LL | | -LL | | -LL | | CONST_MIN ... | LL | | input LL | | }; @@ -131,7 +104,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:184:14 + --> tests/ui/manual_clamp.rs:188:14 | LL | let x4 = input.max(CONST_MIN).min(CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -139,7 +112,7 @@ LL | let x4 = input.max(CONST_MIN).min(CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:188:14 + --> tests/ui/manual_clamp.rs:193:14 | LL | let x5 = input.min(CONST_MAX).max(CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -147,14 +120,11 @@ LL | let x5 = input.min(CONST_MAX).max(CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:192:14 + --> tests/ui/manual_clamp.rs:198:14 | LL | let x6 = match input { | ______________^ -LL | | -LL | | -LL | | x if x > CONST_MAX => CONST_MAX, -LL | | x if x < CONST_MIN => CONST_MIN, +... | LL | | x => x, LL | | }; | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -162,14 +132,11 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:200:14 + --> tests/ui/manual_clamp.rs:207:14 | LL | let x7 = match input { | ______________^ -LL | | -LL | | -LL | | x if x < CONST_MIN => CONST_MIN, -LL | | x if x > CONST_MAX => CONST_MAX, +... | LL | | x => x, LL | | }; | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -177,14 +144,11 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:208:14 + --> tests/ui/manual_clamp.rs:216:14 | LL | let x8 = match input { | ______________^ -LL | | -LL | | -LL | | x if CONST_MAX < x => CONST_MAX, -LL | | x if CONST_MIN > x => CONST_MIN, +... | LL | | x => x, LL | | }; | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -192,14 +156,11 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:226:15 + --> tests/ui/manual_clamp.rs:236:15 | LL | let x10 = match input { | _______________^ -LL | | -LL | | -LL | | x if CONST_MIN > x => CONST_MIN, -LL | | x if CONST_MAX < x => CONST_MAX, +... | LL | | x => x, LL | | }; | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -207,13 +168,10 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:265:15 + --> tests/ui/manual_clamp.rs:279:15 | LL | let x14 = if input > CONST_MAX { | _______________^ -LL | | -LL | | -LL | | CONST_MAX ... | LL | | input LL | | }; @@ -222,13 +180,10 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:276:19 + --> tests/ui/manual_clamp.rs:291:19 | LL | let x15 = if input > CONST_F64_MAX { | ___________________^ -LL | | -LL | | -LL | | CONST_F64_MAX ... | LL | | input LL | | }; @@ -238,7 +193,7 @@ LL | | }; = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:289:19 + --> tests/ui/manual_clamp.rs:305:19 | LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -246,7 +201,7 @@ LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:292:19 + --> tests/ui/manual_clamp.rs:309:19 | LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -254,7 +209,7 @@ LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:295:19 + --> tests/ui/manual_clamp.rs:313:19 | LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -262,7 +217,7 @@ LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:298:19 + --> tests/ui/manual_clamp.rs:317:19 | LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -270,7 +225,7 @@ LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:301:19 + --> tests/ui/manual_clamp.rs:321:19 | LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -278,7 +233,7 @@ LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:304:19 + --> tests/ui/manual_clamp.rs:325:19 | LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -286,7 +241,7 @@ LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:307:19 + --> tests/ui/manual_clamp.rs:329:19 | LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -294,7 +249,7 @@ LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:310:19 + --> tests/ui/manual_clamp.rs:333:19 | LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -302,7 +257,7 @@ LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:314:19 + --> tests/ui/manual_clamp.rs:338:19 | LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -311,7 +266,7 @@ LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:317:19 + --> tests/ui/manual_clamp.rs:342:19 | LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -320,7 +275,7 @@ LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:320:19 + --> tests/ui/manual_clamp.rs:346:19 | LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -329,7 +284,7 @@ LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:323:19 + --> tests/ui/manual_clamp.rs:350:19 | LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -338,7 +293,7 @@ LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:326:19 + --> tests/ui/manual_clamp.rs:354:19 | LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -347,7 +302,7 @@ LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:329:19 + --> tests/ui/manual_clamp.rs:358:19 | LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -356,7 +311,7 @@ LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:332:19 + --> tests/ui/manual_clamp.rs:362:19 | LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -365,7 +320,7 @@ LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:335:19 + --> tests/ui/manual_clamp.rs:366:19 | LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -374,13 +329,10 @@ LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:340:5 + --> tests/ui/manual_clamp.rs:372:5 | LL | / if x32 < CONST_MIN { -LL | | -LL | | -LL | | x32 = CONST_MIN; -LL | | } else if x32 > CONST_MAX { +... | LL | | x32 = CONST_MAX; LL | | } | |_____^ help: replace with clamp: `x32 = x32.clamp(CONST_MIN, CONST_MAX);` @@ -388,13 +340,10 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:532:13 + --> tests/ui/manual_clamp.rs:566:13 | LL | let _ = if input > CONST_MAX { | _____________^ -LL | | -LL | | -LL | | CONST_MAX ... | LL | | input LL | | }; diff --git a/tests/ui/manual_div_ceil.fixed b/tests/ui/manual_div_ceil.fixed index f6eb5a9784ac..6657c695abea 100644 --- a/tests/ui/manual_div_ceil.fixed +++ b/tests/ui/manual_div_ceil.fixed @@ -6,12 +6,17 @@ fn main() { let z = 11_u32; // Lint - let _ = x.div_ceil(y); //~ ERROR: manually reimplementing `div_ceil` - let _ = x.div_ceil(y); //~ ERROR: manually reimplementing `div_ceil` - let _ = x.div_ceil(y); //~ ERROR: manually reimplementing `div_ceil` +let _ = x.div_ceil(y); +//~^ manual_div_ceil +let _ = x.div_ceil(y); +//~^ manual_div_ceil +let _ = x.div_ceil(y); +//~^ manual_div_ceil - let _ = 7_u32.div_ceil(4); //~ ERROR: manually reimplementing `div_ceil` - let _ = (7_i32 as u32).div_ceil(4); //~ ERROR: manually reimplementing `div_ceil` +let _ = 7_u32.div_ceil(4); +//~^ manual_div_ceil +let _ = (7_i32 as u32).div_ceil(4); +//~^ manual_div_ceil // No lint let _ = (x + (y - 2)) / y; @@ -32,29 +37,40 @@ fn main() { fn issue_13843() { let x = 3usize; let _ = 2048_usize.div_ceil(x); + //~^ manual_div_ceil let x = 5usize; let _ = 2048usize.div_ceil(x); + //~^ manual_div_ceil let x = 5usize; let _ = 2048_usize.div_ceil(x); + //~^ manual_div_ceil let x = 2048usize; let _ = x.div_ceil(4); + //~^ manual_div_ceil let _: u32 = 2048_u32.div_ceil(6); + //~^ manual_div_ceil let _: usize = 2048_usize.div_ceil(6); + //~^ manual_div_ceil let _: u32 = 0x2048_u32.div_ceil(0x6); + //~^ manual_div_ceil let _ = 2048_u32.div_ceil(6u32); + //~^ manual_div_ceil let _ = 1_000_000_u32.div_ceil(6u32); + //~^ manual_div_ceil } fn issue_13950() { let x = 33u32; let _ = x.div_ceil(8); + //~^ manual_div_ceil let _ = x.div_ceil(8); + //~^ manual_div_ceil let y = -33i32; let _ = (y + -8) / -7; diff --git a/tests/ui/manual_div_ceil.rs b/tests/ui/manual_div_ceil.rs index 2f063afe787d..2c8506e84cb5 100644 --- a/tests/ui/manual_div_ceil.rs +++ b/tests/ui/manual_div_ceil.rs @@ -6,12 +6,17 @@ fn main() { let z = 11_u32; // Lint - let _ = (x + (y - 1)) / y; //~ ERROR: manually reimplementing `div_ceil` - let _ = ((y - 1) + x) / y; //~ ERROR: manually reimplementing `div_ceil` - let _ = (x + y - 1) / y; //~ ERROR: manually reimplementing `div_ceil` +let _ = (x + (y - 1)) / y; +//~^ manual_div_ceil +let _ = ((y - 1) + x) / y; +//~^ manual_div_ceil +let _ = (x + y - 1) / y; +//~^ manual_div_ceil - let _ = (7_u32 + (4 - 1)) / 4; //~ ERROR: manually reimplementing `div_ceil` - let _ = (7_i32 as u32 + (4 - 1)) / 4; //~ ERROR: manually reimplementing `div_ceil` +let _ = (7_u32 + (4 - 1)) / 4; +//~^ manual_div_ceil +let _ = (7_i32 as u32 + (4 - 1)) / 4; +//~^ manual_div_ceil // No lint let _ = (x + (y - 2)) / y; @@ -32,29 +37,40 @@ fn main() { fn issue_13843() { let x = 3usize; let _ = (2048 + x - 1) / x; + //~^ manual_div_ceil let x = 5usize; let _ = (2048usize + x - 1) / x; + //~^ manual_div_ceil let x = 5usize; let _ = (2048_usize + x - 1) / x; + //~^ manual_div_ceil let x = 2048usize; let _ = (x + 4 - 1) / 4; + //~^ manual_div_ceil let _: u32 = (2048 + 6 - 1) / 6; + //~^ manual_div_ceil let _: usize = (2048 + 6 - 1) / 6; + //~^ manual_div_ceil let _: u32 = (0x2048 + 0x6 - 1) / 0x6; + //~^ manual_div_ceil let _ = (2048 + 6u32 - 1) / 6u32; + //~^ manual_div_ceil let _ = (1_000_000 + 6u32 - 1) / 6u32; + //~^ manual_div_ceil } fn issue_13950() { let x = 33u32; let _ = (x + 7) / 8; + //~^ manual_div_ceil let _ = (7 + x) / 8; + //~^ manual_div_ceil let y = -33i32; let _ = (y + -8) / -7; diff --git a/tests/ui/manual_div_ceil.stderr b/tests/ui/manual_div_ceil.stderr index 0bac5d8ef1c1..d6793dcfb5f3 100644 --- a/tests/ui/manual_div_ceil.stderr +++ b/tests/ui/manual_div_ceil.stderr @@ -1,98 +1,98 @@ error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:9:13 + --> tests/ui/manual_div_ceil.rs:9:9 | -LL | let _ = (x + (y - 1)) / y; - | ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` +LL | let _ = (x + (y - 1)) / y; + | ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` | = note: `-D clippy::manual-div-ceil` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::manual_div_ceil)]` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:10:13 + --> tests/ui/manual_div_ceil.rs:11:9 | -LL | let _ = ((y - 1) + x) / y; - | ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` +LL | let _ = ((y - 1) + x) / y; + | ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:11:13 + --> tests/ui/manual_div_ceil.rs:13:9 | -LL | let _ = (x + y - 1) / y; - | ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` +LL | let _ = (x + y - 1) / y; + | ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:13:13 + --> tests/ui/manual_div_ceil.rs:16:9 | -LL | let _ = (7_u32 + (4 - 1)) / 4; - | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `7_u32.div_ceil(4)` +LL | let _ = (7_u32 + (4 - 1)) / 4; + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `7_u32.div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:14:13 + --> tests/ui/manual_div_ceil.rs:18:9 | -LL | let _ = (7_i32 as u32 + (4 - 1)) / 4; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)` +LL | let _ = (7_i32 as u32 + (4 - 1)) / 4; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:34:13 + --> tests/ui/manual_div_ceil.rs:39:13 | LL | let _ = (2048 + x - 1) / x; | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:37:13 + --> tests/ui/manual_div_ceil.rs:43:13 | LL | let _ = (2048usize + x - 1) / x; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048usize.div_ceil(x)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:40:13 + --> tests/ui/manual_div_ceil.rs:47:13 | LL | let _ = (2048_usize + x - 1) / x; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:43:13 + --> tests/ui/manual_div_ceil.rs:51:13 | LL | let _ = (x + 4 - 1) / 4; | ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:45:18 + --> tests/ui/manual_div_ceil.rs:54:18 | LL | let _: u32 = (2048 + 6 - 1) / 6; | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:46:20 + --> tests/ui/manual_div_ceil.rs:56:20 | LL | let _: usize = (2048 + 6 - 1) / 6; | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(6)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:47:18 + --> tests/ui/manual_div_ceil.rs:58:18 | LL | let _: u32 = (0x2048 + 0x6 - 1) / 0x6; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `0x2048_u32.div_ceil(0x6)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:49:13 + --> tests/ui/manual_div_ceil.rs:61:13 | LL | let _ = (2048 + 6u32 - 1) / 6u32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6u32)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:51:13 + --> tests/ui/manual_div_ceil.rs:64:13 | LL | let _ = (1_000_000 + 6u32 - 1) / 6u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:56:13 + --> tests/ui/manual_div_ceil.rs:70:13 | LL | let _ = (x + 7) / 8; | ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:57:13 + --> tests/ui/manual_div_ceil.rs:72:13 | LL | let _ = (7 + x) / 8; | ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` diff --git a/tests/ui/manual_div_ceil_with_feature.fixed b/tests/ui/manual_div_ceil_with_feature.fixed index 01c58151bc94..f55999c5ad08 100644 --- a/tests/ui/manual_div_ceil_with_feature.fixed +++ b/tests/ui/manual_div_ceil_with_feature.fixed @@ -9,13 +9,20 @@ fn main() { // Lint. let _ = x.div_ceil(y); + //~^ manual_div_ceil let _ = x.div_ceil(y); + //~^ manual_div_ceil let _ = x.div_ceil(y); + //~^ manual_div_ceil let _ = 7_i32.div_ceil(4); + //~^ manual_div_ceil let _ = (7_i32 as u32).div_ceil(4); + //~^ manual_div_ceil let _ = (7_u32 as i32).div_ceil(4); + //~^ manual_div_ceil let _ = z_u.div_ceil(4); + //~^ manual_div_ceil // No lint. let _ = (x + (y - 2)) / y; @@ -27,37 +34,53 @@ fn main() { fn issue_13843() { let x = 3usize; let _ = 2048_usize.div_ceil(x); + //~^ manual_div_ceil let x = 5usize; let _ = 2048usize.div_ceil(x); + //~^ manual_div_ceil let x = 5usize; let _ = 2048_usize.div_ceil(x); + //~^ manual_div_ceil let x = 2048usize; let _ = x.div_ceil(4); + //~^ manual_div_ceil let _ = 2048_i32.div_ceil(4); + //~^ manual_div_ceil let _: u32 = 2048_u32.div_ceil(6); + //~^ manual_div_ceil let _: usize = 2048_usize.div_ceil(6); + //~^ manual_div_ceil let _: u32 = 0x2048_u32.div_ceil(0x6); + //~^ manual_div_ceil let _ = 2048_u32.div_ceil(6u32); + //~^ manual_div_ceil let x = -2; let _ = (-2048_i32).div_ceil(x); + //~^ manual_div_ceil let _ = 1_000_000_u32.div_ceil(6u32); + //~^ manual_div_ceil } fn issue_13950() { let x = 33u32; let _ = x.div_ceil(8); + //~^ manual_div_ceil let _ = x.div_ceil(8); + //~^ manual_div_ceil let y = -33i32; let _ = y.div_ceil(-7); + //~^ manual_div_ceil let _ = y.div_ceil(-7); + //~^ manual_div_ceil let _ = y.div_ceil(-7); + //~^ manual_div_ceil } diff --git a/tests/ui/manual_div_ceil_with_feature.rs b/tests/ui/manual_div_ceil_with_feature.rs index 048ff401581f..8a895f634cb4 100644 --- a/tests/ui/manual_div_ceil_with_feature.rs +++ b/tests/ui/manual_div_ceil_with_feature.rs @@ -9,13 +9,20 @@ fn main() { // Lint. let _ = (x + (y - 1)) / y; + //~^ manual_div_ceil let _ = ((y - 1) + x) / y; + //~^ manual_div_ceil let _ = (x + y - 1) / y; + //~^ manual_div_ceil let _ = (7_i32 + (4 - 1)) / 4; + //~^ manual_div_ceil let _ = (7_i32 as u32 + (4 - 1)) / 4; + //~^ manual_div_ceil let _ = (7_u32 as i32 + (4 - 1)) / 4; + //~^ manual_div_ceil let _ = (z_u + (4 - 1)) / 4; + //~^ manual_div_ceil // No lint. let _ = (x + (y - 2)) / y; @@ -27,37 +34,53 @@ fn main() { fn issue_13843() { let x = 3usize; let _ = (2048 + x - 1) / x; + //~^ manual_div_ceil let x = 5usize; let _ = (2048usize + x - 1) / x; + //~^ manual_div_ceil let x = 5usize; let _ = (2048_usize + x - 1) / x; + //~^ manual_div_ceil let x = 2048usize; let _ = (x + 4 - 1) / 4; + //~^ manual_div_ceil let _ = (2048 + 4 - 1) / 4; + //~^ manual_div_ceil let _: u32 = (2048 + 6 - 1) / 6; + //~^ manual_div_ceil let _: usize = (2048 + 6 - 1) / 6; + //~^ manual_div_ceil let _: u32 = (0x2048 + 0x6 - 1) / 0x6; + //~^ manual_div_ceil let _ = (2048 + 6u32 - 1) / 6u32; + //~^ manual_div_ceil let x = -2; let _ = (-2048 + x - 1) / x; + //~^ manual_div_ceil let _ = (1_000_000 + 6u32 - 1) / 6u32; + //~^ manual_div_ceil } fn issue_13950() { let x = 33u32; let _ = (x + 7) / 8; + //~^ manual_div_ceil let _ = (7 + x) / 8; + //~^ manual_div_ceil let y = -33i32; let _ = (y + -8) / -7; + //~^ manual_div_ceil let _ = (-8 + y) / -7; + //~^ manual_div_ceil let _ = (y - 8) / -7; + //~^ manual_div_ceil } diff --git a/tests/ui/manual_div_ceil_with_feature.stderr b/tests/ui/manual_div_ceil_with_feature.stderr index 807cfd82724e..e1160d962996 100644 --- a/tests/ui/manual_div_ceil_with_feature.stderr +++ b/tests/ui/manual_div_ceil_with_feature.stderr @@ -8,133 +8,133 @@ LL | let _ = (x + (y - 1)) / y; = help: to override `-D warnings` add `#[allow(clippy::manual_div_ceil)]` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:12:13 + --> tests/ui/manual_div_ceil_with_feature.rs:13:13 | LL | let _ = ((y - 1) + x) / y; | ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:13:13 + --> tests/ui/manual_div_ceil_with_feature.rs:15:13 | LL | let _ = (x + y - 1) / y; | ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:15:13 + --> tests/ui/manual_div_ceil_with_feature.rs:18:13 | LL | let _ = (7_i32 + (4 - 1)) / 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `7_i32.div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:16:13 + --> tests/ui/manual_div_ceil_with_feature.rs:20:13 | LL | let _ = (7_i32 as u32 + (4 - 1)) / 4; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:17:13 + --> tests/ui/manual_div_ceil_with_feature.rs:22:13 | LL | let _ = (7_u32 as i32 + (4 - 1)) / 4; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_u32 as i32).div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:18:13 + --> tests/ui/manual_div_ceil_with_feature.rs:24:13 | LL | let _ = (z_u + (4 - 1)) / 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `z_u.div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:29:13 + --> tests/ui/manual_div_ceil_with_feature.rs:36:13 | LL | let _ = (2048 + x - 1) / x; | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:32:13 + --> tests/ui/manual_div_ceil_with_feature.rs:40:13 | LL | let _ = (2048usize + x - 1) / x; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048usize.div_ceil(x)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:35:13 + --> tests/ui/manual_div_ceil_with_feature.rs:44:13 | LL | let _ = (2048_usize + x - 1) / x; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:38:13 + --> tests/ui/manual_div_ceil_with_feature.rs:48:13 | LL | let _ = (x + 4 - 1) / 4; | ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:40:13 + --> tests/ui/manual_div_ceil_with_feature.rs:51:13 | LL | let _ = (2048 + 4 - 1) / 4; | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_i32.div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:42:18 + --> tests/ui/manual_div_ceil_with_feature.rs:54:18 | LL | let _: u32 = (2048 + 6 - 1) / 6; | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:43:20 + --> tests/ui/manual_div_ceil_with_feature.rs:56:20 | LL | let _: usize = (2048 + 6 - 1) / 6; | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(6)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:44:18 + --> tests/ui/manual_div_ceil_with_feature.rs:58:18 | LL | let _: u32 = (0x2048 + 0x6 - 1) / 0x6; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `0x2048_u32.div_ceil(0x6)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:46:13 + --> tests/ui/manual_div_ceil_with_feature.rs:61:13 | LL | let _ = (2048 + 6u32 - 1) / 6u32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6u32)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:49:13 + --> tests/ui/manual_div_ceil_with_feature.rs:65:13 | LL | let _ = (-2048 + x - 1) / x; | ^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(-2048_i32).div_ceil(x)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:51:13 + --> tests/ui/manual_div_ceil_with_feature.rs:68:13 | LL | let _ = (1_000_000 + 6u32 - 1) / 6u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:56:13 + --> tests/ui/manual_div_ceil_with_feature.rs:74:13 | LL | let _ = (x + 7) / 8; | ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:57:13 + --> tests/ui/manual_div_ceil_with_feature.rs:76:13 | LL | let _ = (7 + x) / 8; | ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:60:13 + --> tests/ui/manual_div_ceil_with_feature.rs:80:13 | LL | let _ = (y + -8) / -7; | ^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:61:13 + --> tests/ui/manual_div_ceil_with_feature.rs:82:13 | LL | let _ = (-8 + y) / -7; | ^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil_with_feature.rs:62:13 + --> tests/ui/manual_div_ceil_with_feature.rs:84:13 | LL | let _ = (y - 8) / -7; | ^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)` diff --git a/tests/ui/manual_filter.rs b/tests/ui/manual_filter.rs index 0ac6cbefc4ec..a83a316f95ad 100644 --- a/tests/ui/manual_filter.rs +++ b/tests/ui/manual_filter.rs @@ -3,6 +3,7 @@ fn main() { match Some(0) { + //~^ manual_filter None => None, Some(x) => { if x > 0 { @@ -14,6 +15,7 @@ fn main() { }; match Some(1) { + //~^ manual_filter Some(x) => { if x > 0 { None @@ -25,6 +27,7 @@ fn main() { }; match Some(2) { + //~^ manual_filter Some(x) => { if x > 0 { None @@ -36,6 +39,7 @@ fn main() { }; match Some(3) { + //~^ manual_filter Some(x) => { if x > 0 { Some(x) @@ -48,6 +52,7 @@ fn main() { let y = Some(4); match y { + //~^ manual_filter // Some(4) None => None, Some(x) => { @@ -60,6 +65,7 @@ fn main() { }; match Some(5) { + //~^ manual_filter Some(x) => { if x > 0 { Some(x) @@ -71,6 +77,7 @@ fn main() { }; match Some(6) { + //~^ manual_filter Some(ref x) => { if x > &0 { Some(x) @@ -83,6 +90,7 @@ fn main() { let external_cond = true; match Some(String::new()) { + //~^ manual_filter Some(x) => { if external_cond { Some(x) @@ -94,12 +102,14 @@ fn main() { }; if let Some(x) = Some(7) { + //~^ manual_filter if external_cond { Some(x) } else { None } } else { None }; match &Some(8) { + //~^ manual_filter &Some(x) => { if x != 0 { Some(x) @@ -111,6 +121,7 @@ fn main() { }; match Some(9) { + //~^ manual_filter Some(x) => { if x > 10 && x < 100 { Some(x) @@ -137,6 +148,7 @@ fn main() { #[allow(clippy::blocks_in_conditions)] match Some(11) { + //~^ manual_filter // Lint, statement is preserved by `.filter` Some(x) => { if { @@ -181,6 +193,7 @@ fn main() { true } let _ = match Some(14) { + //~^ manual_filter Some(x) => { if unsafe { f(x) } { Some(x) @@ -191,6 +204,7 @@ fn main() { None => None, }; let _ = match Some(15) { + //~^ manual_filter Some(x) => unsafe { if f(x) { Some(x) } else { None } }, None => None, }; @@ -199,6 +213,7 @@ fn main() { if let Some(_) = Some(16) { Some(16) } else if let Some(x) = Some(16) { + //~^ manual_filter // Lint starting from here if x % 2 == 0 { Some(x) } else { None } } else { diff --git a/tests/ui/manual_filter.stderr b/tests/ui/manual_filter.stderr index 3add706d7f73..63463997f435 100644 --- a/tests/ui/manual_filter.stderr +++ b/tests/ui/manual_filter.stderr @@ -2,9 +2,9 @@ error: manual implementation of `Option::filter` --> tests/ui/manual_filter.rs:5:5 | LL | / match Some(0) { +LL | | LL | | None => None, LL | | Some(x) => { -LL | | if x > 0 { ... | LL | | }, LL | | }; @@ -14,93 +14,94 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_filter)]` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:16:5 + --> tests/ui/manual_filter.rs:17:5 | LL | / match Some(1) { +LL | | LL | | Some(x) => { LL | | if x > 0 { -LL | | None ... | LL | | None => None, LL | | }; | |_____^ help: try: `Some(1).filter(|&x| x <= 0)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:27:5 + --> tests/ui/manual_filter.rs:29:5 | LL | / match Some(2) { +LL | | LL | | Some(x) => { LL | | if x > 0 { -LL | | None ... | LL | | _ => None, LL | | }; | |_____^ help: try: `Some(2).filter(|&x| x <= 0)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:38:5 + --> tests/ui/manual_filter.rs:41:5 | LL | / match Some(3) { +LL | | LL | | Some(x) => { LL | | if x > 0 { -LL | | Some(x) ... | LL | | None => None, LL | | }; | |_____^ help: try: `Some(3).filter(|&x| x > 0)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:50:5 + --> tests/ui/manual_filter.rs:54:5 | LL | / match y { +LL | | LL | | // Some(4) LL | | None => None, -LL | | Some(x) => { ... | LL | | }, LL | | }; | |_____^ help: try: `y.filter(|&x| x <= 0)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:62:5 + --> tests/ui/manual_filter.rs:67:5 | LL | / match Some(5) { +LL | | LL | | Some(x) => { LL | | if x > 0 { -LL | | Some(x) ... | LL | | _ => None, LL | | }; | |_____^ help: try: `Some(5).filter(|&x| x > 0)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:73:5 + --> tests/ui/manual_filter.rs:79:5 | LL | / match Some(6) { +LL | | LL | | Some(ref x) => { LL | | if x > &0 { -LL | | Some(x) ... | LL | | _ => None, LL | | }; | |_____^ help: try: `Some(6).as_ref().filter(|&x| x > &0)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:85:5 + --> tests/ui/manual_filter.rs:92:5 | LL | / match Some(String::new()) { +LL | | LL | | Some(x) => { LL | | if external_cond { -LL | | Some(x) ... | LL | | _ => None, LL | | }; | |_____^ help: try: `Some(String::new()).filter(|x| external_cond)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:96:5 + --> tests/ui/manual_filter.rs:104:5 | LL | / if let Some(x) = Some(7) { +LL | | LL | | if external_cond { Some(x) } else { None } LL | | } else { LL | | None @@ -108,36 +109,36 @@ LL | | }; | |_____^ help: try: `Some(7).filter(|&x| external_cond)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:102:5 + --> tests/ui/manual_filter.rs:111:5 | LL | / match &Some(8) { +LL | | LL | | &Some(x) => { LL | | if x != 0 { -LL | | Some(x) ... | LL | | _ => None, LL | | }; | |_____^ help: try: `Some(8).filter(|&x| x != 0)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:113:5 + --> tests/ui/manual_filter.rs:123:5 | LL | / match Some(9) { +LL | | LL | | Some(x) => { LL | | if x > 10 && x < 100 { -LL | | Some(x) ... | LL | | None => None, LL | | }; | |_____^ help: try: `Some(9).filter(|&x| x > 10 && x < 100)` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:139:5 + --> tests/ui/manual_filter.rs:150:5 | LL | / match Some(11) { +LL | | LL | | // Lint, statement is preserved by `.filter` LL | | Some(x) => { -LL | | if { ... | LL | | None => None, LL | | }; @@ -152,33 +153,35 @@ LL ~ }); | error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:183:13 + --> tests/ui/manual_filter.rs:195:13 | LL | let _ = match Some(14) { | _____________^ +LL | | LL | | Some(x) => { LL | | if unsafe { f(x) } { -LL | | Some(x) ... | LL | | None => None, LL | | }; | |_____^ help: try: `Some(14).filter(|&x| unsafe { f(x) })` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:193:13 + --> tests/ui/manual_filter.rs:206:13 | LL | let _ = match Some(15) { | _____________^ +LL | | LL | | Some(x) => unsafe { if f(x) { Some(x) } else { None } }, LL | | None => None, LL | | }; | |_____^ help: try: `Some(15).filter(|&x| unsafe { f(x) })` error: manual implementation of `Option::filter` - --> tests/ui/manual_filter.rs:201:12 + --> tests/ui/manual_filter.rs:215:12 | LL | } else if let Some(x) = Some(16) { | ____________^ +LL | | LL | | // Lint starting from here LL | | if x % 2 == 0 { Some(x) } else { None } LL | | } else { diff --git a/tests/ui/manual_filter_map.fixed b/tests/ui/manual_filter_map.fixed index a44c46c145c6..caf82289031f 100644 --- a/tests/ui/manual_filter_map.fixed +++ b/tests/ui/manual_filter_map.fixed @@ -7,12 +7,15 @@ fn main() { // is_some(), unwrap() let _ = (0..).filter_map(|a| to_opt(a)); + //~^ manual_filter_map // ref pattern, expect() let _ = (0..).filter_map(|a| to_opt(a)); + //~^ manual_filter_map // is_ok(), unwrap_or() let _ = (0..).filter_map(|a| to_res(a).ok()); + //~^ manual_filter_map let _ = (1..5) .filter_map(|y| *to_ref(to_opt(y))); @@ -28,17 +31,28 @@ fn main() { #[rustfmt::skip] fn simple_equal() { iter::>().find_map(|x| x.cloned()); + //~^ manual_find_map iter::<&Option<&u8>>().find_map(|x| x.cloned()); + //~^ manual_find_map iter::<&Option>().find_map(|x| x.as_deref()); + //~^ manual_find_map iter::>().find_map(|y| to_ref(y).cloned()); + //~^ manual_find_map iter::>().find_map(|x| x.ok()); + //~^ manual_find_map iter::<&Result>().find_map(|x| x.ok()); + //~^ manual_find_map iter::<&&Result>().find_map(|x| x.ok()); + //~^ manual_find_map iter::>().find_map(|x| x.cloned().ok()); + //~^ manual_find_map iter::<&Result<&u8, ()>>().find_map(|x| x.cloned().ok()); + //~^ manual_find_map iter::<&Result>().find_map(|x| x.as_deref().ok()); + //~^ manual_find_map iter::>().find_map(|y| to_ref(y).cloned().ok()); + //~^ manual_find_map } fn no_lint() { diff --git a/tests/ui/manual_filter_map.rs b/tests/ui/manual_filter_map.rs index e72d0c4305b3..75e15d3b5a5a 100644 --- a/tests/ui/manual_filter_map.rs +++ b/tests/ui/manual_filter_map.rs @@ -7,42 +7,60 @@ fn main() { // is_some(), unwrap() let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap()); + //~^ manual_filter_map // ref pattern, expect() let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); + //~^ manual_filter_map // is_ok(), unwrap_or() let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); + //~^ manual_filter_map let _ = (1..5) .filter(|&x| to_ref(to_opt(x)).is_some()) + //~^ manual_filter_map .map(|y| to_ref(to_opt(y)).unwrap()); let _ = (1..5) .filter(|x| to_ref(to_opt(*x)).is_some()) + //~^ manual_filter_map .map(|y| to_ref(to_opt(y)).unwrap()); let _ = (1..5) .filter(|&x| to_ref(to_res(x)).is_ok()) + //~^ manual_filter_map .map(|y| to_ref(to_res(y)).unwrap()); let _ = (1..5) .filter(|x| to_ref(to_res(*x)).is_ok()) + //~^ manual_filter_map .map(|y| to_ref(to_res(y)).unwrap()); } #[rustfmt::skip] fn simple_equal() { iter::>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); + //~^ manual_find_map iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); + //~^ manual_find_map iter::<&Option>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap()); + //~^ manual_find_map iter::>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); + //~^ manual_find_map iter::>().find(|x| x.is_ok()).map(|x| x.unwrap()); + //~^ manual_find_map iter::<&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); + //~^ manual_find_map iter::<&&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); + //~^ manual_find_map iter::>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); + //~^ manual_find_map iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); + //~^ manual_find_map iter::<&Result>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap()); + //~^ manual_find_map iter::>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); + //~^ manual_find_map } fn no_lint() { @@ -91,46 +109,55 @@ fn issue_8920() { let _ = vec .iter() .filter(|f| f.option_field.is_some()) + //~^ manual_filter_map .map(|f| f.option_field.clone().unwrap()); let _ = vec .iter() .filter(|f| f.ref_field.is_some()) + //~^ manual_filter_map .map(|f| f.ref_field.cloned().unwrap()); let _ = vec .iter() .filter(|f| f.ref_field.is_some()) + //~^ manual_filter_map .map(|f| f.ref_field.copied().unwrap()); let _ = vec .iter() .filter(|f| f.result_field.is_ok()) + //~^ manual_filter_map .map(|f| f.result_field.clone().unwrap()); let _ = vec .iter() .filter(|f| f.result_field.is_ok()) + //~^ manual_filter_map .map(|f| f.result_field.as_ref().unwrap()); let _ = vec .iter() .filter(|f| f.result_field.is_ok()) + //~^ manual_filter_map .map(|f| f.result_field.as_deref().unwrap()); let _ = vec .iter_mut() .filter(|f| f.result_field.is_ok()) + //~^ manual_filter_map .map(|f| f.result_field.as_mut().unwrap()); let _ = vec .iter_mut() .filter(|f| f.result_field.is_ok()) + //~^ manual_filter_map .map(|f| f.result_field.as_deref_mut().unwrap()); let _ = vec .iter() .filter(|f| f.result_field.is_ok()) + //~^ manual_filter_map .map(|f| f.result_field.to_owned().unwrap()); } @@ -144,6 +171,7 @@ fn issue8010() { let iter = [Enum::A(123), Enum::B].into_iter(); let _x = iter.clone().filter(|x| matches!(x, Enum::A(_))).map(|x| match x { + //~^ manual_filter_map Enum::A(s) => s, _ => unreachable!(), }); @@ -154,6 +182,7 @@ fn issue8010() { let _x = iter .clone() .filter(|x| matches!(x, Enum::A(_))) + //~^ manual_filter_map .map(|x| if let Enum::A(s) = x { s } else { unreachable!() }); #[allow(clippy::unused_unit)] let _x = iter diff --git a/tests/ui/manual_filter_map.stderr b/tests/ui/manual_filter_map.stderr index 2e5056727831..07c894bf0e66 100644 --- a/tests/ui/manual_filter_map.stderr +++ b/tests/ui/manual_filter_map.stderr @@ -13,87 +13,91 @@ LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap = help: to override `-D warnings` add `#[allow(clippy::manual_filter_map)]` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:12:19 + --> tests/ui/manual_filter_map.rs:13:19 | LL | let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_filter_map.rs:12:31 + --> tests/ui/manual_filter_map.rs:13:31 | LL | let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:15:19 + --> tests/ui/manual_filter_map.rs:17:19 | LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_res(a).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_filter_map.rs:15:31 + --> tests/ui/manual_filter_map.rs:17:31 | LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:18:10 + --> tests/ui/manual_filter_map.rs:21:10 | LL | .filter(|&x| to_ref(to_opt(x)).is_some()) | __________^ +LL | | LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_filter_map.rs:18:22 + --> tests/ui/manual_filter_map.rs:21:22 | LL | .filter(|&x| to_ref(to_opt(x)).is_some()) | ^^^^^^^^^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:21:10 + --> tests/ui/manual_filter_map.rs:25:10 | LL | .filter(|x| to_ref(to_opt(*x)).is_some()) | __________^ +LL | | LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_filter_map.rs:21:21 + --> tests/ui/manual_filter_map.rs:25:21 | LL | .filter(|x| to_ref(to_opt(*x)).is_some()) | ^^^^^^^^^^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:25:10 + --> tests/ui/manual_filter_map.rs:30:10 | LL | .filter(|&x| to_ref(to_res(x)).is_ok()) | __________^ +LL | | LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_filter_map.rs:25:22 + --> tests/ui/manual_filter_map.rs:30:22 | LL | .filter(|&x| to_ref(to_res(x)).is_ok()) | ^^^^^^^^^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:28:10 + --> tests/ui/manual_filter_map.rs:34:10 | LL | .filter(|x| to_ref(to_res(*x)).is_ok()) | __________^ +LL | | LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_filter_map.rs:28:21 + --> tests/ui/manual_filter_map.rs:34:21 | LL | .filter(|x| to_ref(to_res(*x)).is_ok()) | ^^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:34:27 + --> tests/ui/manual_filter_map.rs:41:27 | LL | iter::>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` @@ -102,164 +106,175 @@ LL | iter::>().find(|x| x.is_some()).map(|x| x.cloned().unwrap() = help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:35:28 + --> tests/ui/manual_filter_map.rs:43:28 | LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:36:31 + --> tests/ui/manual_filter_map.rs:45:31 | LL | iter::<&Option>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:37:31 + --> tests/ui/manual_filter_map.rs:47:31 | LL | iter::>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_filter_map.rs:37:41 + --> tests/ui/manual_filter_map.rs:47:41 | LL | iter::>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:39:30 + --> tests/ui/manual_filter_map.rs:50:30 | LL | iter::>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:40:31 + --> tests/ui/manual_filter_map.rs:52:31 | LL | iter::<&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:41:32 + --> tests/ui/manual_filter_map.rs:54:32 | LL | iter::<&&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:42:31 + --> tests/ui/manual_filter_map.rs:56:31 | LL | iter::>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:43:32 + --> tests/ui/manual_filter_map.rs:58:32 | LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:44:35 + --> tests/ui/manual_filter_map.rs:60:35 | LL | iter::<&Result>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_filter_map.rs:45:35 + --> tests/ui/manual_filter_map.rs:62:35 | LL | iter::>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_filter_map.rs:45:45 + --> tests/ui/manual_filter_map.rs:62:45 | LL | iter::>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:93:10 + --> tests/ui/manual_filter_map.rs:111:10 | LL | .filter(|f| f.option_field.is_some()) | __________^ +LL | | LL | | .map(|f| f.option_field.clone().unwrap()); | |_________________________________________________^ help: try: `filter_map(|f| f.option_field.clone())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:98:10 + --> tests/ui/manual_filter_map.rs:117:10 | LL | .filter(|f| f.ref_field.is_some()) | __________^ +LL | | LL | | .map(|f| f.ref_field.cloned().unwrap()); | |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.cloned())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:103:10 + --> tests/ui/manual_filter_map.rs:123:10 | LL | .filter(|f| f.ref_field.is_some()) | __________^ +LL | | LL | | .map(|f| f.ref_field.copied().unwrap()); | |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.copied())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:108:10 + --> tests/ui/manual_filter_map.rs:129:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.clone().unwrap()); | |_________________________________________________^ help: try: `filter_map(|f| f.result_field.clone().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:113:10 + --> tests/ui/manual_filter_map.rs:135:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.as_ref().unwrap()); | |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_ref().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:118:10 + --> tests/ui/manual_filter_map.rs:141:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.as_deref().unwrap()); | |____________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:123:10 + --> tests/ui/manual_filter_map.rs:147:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.as_mut().unwrap()); | |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_mut().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:128:10 + --> tests/ui/manual_filter_map.rs:153:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.as_deref_mut().unwrap()); | |________________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref_mut().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:133:10 + --> tests/ui/manual_filter_map.rs:159:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.to_owned().unwrap()); | |____________________________________________________^ help: try: `filter_map(|f| f.result_field.to_owned().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:146:27 + --> tests/ui/manual_filter_map.rs:173:27 | LL | let _x = iter.clone().filter(|x| matches!(x, Enum::A(_))).map(|x| match x { | ___________________________^ +LL | | LL | | Enum::A(s) => s, LL | | _ => unreachable!(), LL | | }); | |______^ help: try: `filter_map(|x| match x { Enum::A(s) => Some(s), _ => None })` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> tests/ui/manual_filter_map.rs:156:10 + --> tests/ui/manual_filter_map.rs:184:10 | LL | .filter(|x| matches!(x, Enum::A(_))) | __________^ +LL | | LL | | .map(|x| if let Enum::A(s) = x { s } else { unreachable!() }); | |_____________________________________________________________________^ help: try: `filter_map(|x| match x { Enum::A(s) => Some(s), _ => None })` diff --git a/tests/ui/manual_find.rs b/tests/ui/manual_find.rs index 0a105b0359e5..d3c24d0b8849 100644 --- a/tests/ui/manual_find.rs +++ b/tests/ui/manual_find.rs @@ -3,8 +3,9 @@ //@no-rustfix fn vec_string(strings: Vec) -> Option { for s in strings { - //~^ ERROR: manual implementation of `Iterator::find` - //~| NOTE: you may need to dereference some variables + //~^ manual_find + + if s == String::new() { return Some(s); } @@ -14,8 +15,9 @@ fn vec_string(strings: Vec) -> Option { fn tuple(arr: Vec<(String, i32)>) -> Option { for (s, _) in arr { - //~^ ERROR: manual implementation of `Iterator::find` - //~| NOTE: you may need to dereference some variables + //~^ manual_find + + if s == String::new() { return Some(s); } diff --git a/tests/ui/manual_find.stderr b/tests/ui/manual_find.stderr index a4e7878a247c..2dbe0b16b75a 100644 --- a/tests/ui/manual_find.stderr +++ b/tests/ui/manual_find.stderr @@ -2,9 +2,6 @@ error: manual implementation of `Iterator::find` --> tests/ui/manual_find.rs:5:5 | LL | / for s in strings { -LL | | -LL | | -LL | | if s == String::new() { ... | LL | | None | |________^ help: replace with an iterator: `strings.into_iter().find(|s| s == String::new())` @@ -14,12 +11,9 @@ LL | | None = help: to override `-D warnings` add `#[allow(clippy::manual_find)]` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find.rs:16:5 + --> tests/ui/manual_find.rs:17:5 | LL | / for (s, _) in arr { -LL | | -LL | | -LL | | if s == String::new() { ... | LL | | None | |________^ help: replace with an iterator: `arr.into_iter().map(|(s, _)| s).find(|s| s == String::new())` diff --git a/tests/ui/manual_find_fixable.rs b/tests/ui/manual_find_fixable.rs index 56c3f2629c7a..3966d8df89b9 100644 --- a/tests/ui/manual_find_fixable.rs +++ b/tests/ui/manual_find_fixable.rs @@ -8,6 +8,7 @@ const ARRAY: &[u32; 5] = &[2, 7, 1, 9, 3]; fn lookup(n: u32) -> Option { for &v in ARRAY { + //~^ manual_find if v == n { return Some(v); } @@ -17,6 +18,7 @@ fn lookup(n: u32) -> Option { fn with_pat(arr: Vec<(u32, u32)>) -> Option { for (a, _) in arr { + //~^ manual_find if a % 2 == 0 { return Some(a); } @@ -30,6 +32,7 @@ struct Data { } fn with_struct(arr: Vec) -> Option { for el in arr { + //~^ manual_find if el.name.len() == 10 { return Some(el); } @@ -40,6 +43,7 @@ fn with_struct(arr: Vec) -> Option { struct Tuple(usize, usize); fn with_tuple_struct(arr: Vec) -> Option { for Tuple(a, _) in arr { + //~^ manual_find if a >= 3 { return Some(a); } @@ -55,6 +59,7 @@ impl A { } fn with_method_call(arr: Vec) -> Option { for el in arr { + //~^ manual_find if el.should_keep() { return Some(el); } @@ -65,6 +70,7 @@ fn with_method_call(arr: Vec) -> Option { fn with_closure(arr: Vec) -> Option { let f = |el: u32| -> u32 { el + 10 }; for el in arr { + //~^ manual_find if f(el) == 20 { return Some(el); } @@ -75,6 +81,7 @@ fn with_closure(arr: Vec) -> Option { fn with_closure2(arr: HashMap) -> Option { let f = |el: i32| -> bool { el == 10 }; for &el in arr.values() { + //~^ manual_find if f(el) { return Some(el); } @@ -84,6 +91,7 @@ fn with_closure2(arr: HashMap) -> Option { fn with_bool(arr: Vec) -> Option { for el in arr { + //~^ manual_find if el.is_true { return Some(el); } @@ -114,6 +122,7 @@ fn with_else(arr: Vec) -> Option { fn tuple_with_ref(v: [(u8, &u8); 3]) -> Option { for (_, &x) in v { + //~^ manual_find if x > 10 { return Some(x); } @@ -123,6 +132,7 @@ fn tuple_with_ref(v: [(u8, &u8); 3]) -> Option { fn ref_to_tuple_with_ref(v: &[(u8, &u8)]) -> Option { for &(_, &x) in v { + //~^ manual_find if x > 10 { return Some(x); } @@ -132,6 +142,7 @@ fn ref_to_tuple_with_ref(v: &[(u8, &u8)]) -> Option { fn explicit_ret(arr: Vec) -> Option { for x in arr { + //~^ manual_find if x >= 5 { return Some(x); } @@ -187,6 +198,7 @@ fn as_closure() { #[rustfmt::skip] let f = |arr: Vec| -> Option { for x in arr { + //~^ manual_find if x < 1 { return Some(x); } diff --git a/tests/ui/manual_find_fixable.stderr b/tests/ui/manual_find_fixable.stderr index 5ed8be1b3eed..afa453c5a876 100644 --- a/tests/ui/manual_find_fixable.stderr +++ b/tests/ui/manual_find_fixable.stderr @@ -2,6 +2,7 @@ error: manual implementation of `Iterator::find` --> tests/ui/manual_find_fixable.rs:10:5 | LL | / for &v in ARRAY { +LL | | LL | | if v == n { LL | | return Some(v); ... | @@ -12,9 +13,10 @@ LL | | None = help: to override `-D warnings` add `#[allow(clippy::manual_find)]` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:19:5 + --> tests/ui/manual_find_fixable.rs:20:5 | LL | / for (a, _) in arr { +LL | | LL | | if a % 2 == 0 { LL | | return Some(a); ... | @@ -22,9 +24,10 @@ LL | | None | |________^ help: replace with an iterator: `arr.into_iter().map(|(a, _)| a).find(|&a| a % 2 == 0)` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:32:5 + --> tests/ui/manual_find_fixable.rs:34:5 | LL | / for el in arr { +LL | | LL | | if el.name.len() == 10 { LL | | return Some(el); ... | @@ -34,9 +37,10 @@ LL | | None = note: you may need to dereference some variables error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:42:5 + --> tests/ui/manual_find_fixable.rs:45:5 | LL | / for Tuple(a, _) in arr { +LL | | LL | | if a >= 3 { LL | | return Some(a); ... | @@ -44,9 +48,10 @@ LL | | None | |________^ help: replace with an iterator: `arr.into_iter().map(|Tuple(a, _)| a).find(|&a| a >= 3)` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:57:5 + --> tests/ui/manual_find_fixable.rs:61:5 | LL | / for el in arr { +LL | | LL | | if el.should_keep() { LL | | return Some(el); ... | @@ -56,9 +61,10 @@ LL | | None = note: you may need to dereference some variables error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:67:5 + --> tests/ui/manual_find_fixable.rs:72:5 | LL | / for el in arr { +LL | | LL | | if f(el) == 20 { LL | | return Some(el); ... | @@ -66,9 +72,10 @@ LL | | None | |________^ help: replace with an iterator: `arr.into_iter().find(|&el| f(el) == 20)` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:77:5 + --> tests/ui/manual_find_fixable.rs:83:5 | LL | / for &el in arr.values() { +LL | | LL | | if f(el) { LL | | return Some(el); ... | @@ -76,9 +83,10 @@ LL | | None | |________^ help: replace with an iterator: `arr.values().find(|&&el| f(el)).copied()` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:86:5 + --> tests/ui/manual_find_fixable.rs:93:5 | LL | / for el in arr { +LL | | LL | | if el.is_true { LL | | return Some(el); ... | @@ -88,9 +96,10 @@ LL | | None = note: you may need to dereference some variables error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:116:5 + --> tests/ui/manual_find_fixable.rs:124:5 | LL | / for (_, &x) in v { +LL | | LL | | if x > 10 { LL | | return Some(x); ... | @@ -98,9 +107,10 @@ LL | | None | |________^ help: replace with an iterator: `v.into_iter().map(|(_, &x)| x).find(|&x| x > 10)` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:125:5 + --> tests/ui/manual_find_fixable.rs:134:5 | LL | / for &(_, &x) in v { +LL | | LL | | if x > 10 { LL | | return Some(x); ... | @@ -108,9 +118,10 @@ LL | | None | |________^ help: replace with an iterator: `v.iter().map(|&(_, &x)| x).find(|&x| x > 10)` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:134:5 + --> tests/ui/manual_find_fixable.rs:144:5 | LL | / for x in arr { +LL | | LL | | if x >= 5 { LL | | return Some(x); ... | @@ -118,9 +129,10 @@ LL | | return None; | |________________^ help: replace with an iterator: `arr.into_iter().find(|&x| x >= 5)` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find_fixable.rs:189:9 + --> tests/ui/manual_find_fixable.rs:200:9 | LL | / for x in arr { +LL | | LL | | if x < 1 { LL | | return Some(x); ... | diff --git a/tests/ui/manual_find_map.fixed b/tests/ui/manual_find_map.fixed index 2d9a356b9bcd..1a452d50261f 100644 --- a/tests/ui/manual_find_map.fixed +++ b/tests/ui/manual_find_map.fixed @@ -7,12 +7,15 @@ fn main() { // is_some(), unwrap() let _ = (0..).find_map(|a| to_opt(a)); + //~^ manual_find_map // ref pattern, expect() let _ = (0..).find_map(|a| to_opt(a)); + //~^ manual_find_map // is_ok(), unwrap_or() let _ = (0..).find_map(|a| to_res(a).ok()); + //~^ manual_find_map let _ = (1..5) .find_map(|y| *to_ref(to_opt(y))); @@ -28,20 +31,34 @@ fn main() { #[rustfmt::skip] fn simple_equal() { iter::>().find_map(|x| x); + //~^ manual_find_map iter::<&Option>().find_map(|x| *x); + //~^ manual_find_map iter::<&&Option>().find_map(|x| **x); + //~^ manual_find_map iter::>().find_map(|x| x.cloned()); + //~^ manual_find_map iter::<&Option<&u8>>().find_map(|x| x.cloned()); + //~^ manual_find_map iter::<&Option>().find_map(|x| x.as_deref()); + //~^ manual_find_map iter::>().find_map(|y| to_ref(y).cloned()); + //~^ manual_find_map iter::>().find_map(|x| x.ok()); + //~^ manual_find_map iter::<&Result>().find_map(|x| x.ok()); + //~^ manual_find_map iter::<&&Result>().find_map(|x| x.ok()); + //~^ manual_find_map iter::>().find_map(|x| x.cloned().ok()); + //~^ manual_find_map iter::<&Result<&u8, ()>>().find_map(|x| x.cloned().ok()); + //~^ manual_find_map iter::<&Result>().find_map(|x| x.as_deref().ok()); + //~^ manual_find_map iter::>().find_map(|y| to_ref(y).cloned().ok()); + //~^ manual_find_map } fn no_lint() { diff --git a/tests/ui/manual_find_map.rs b/tests/ui/manual_find_map.rs index 7c5cc136695a..9415a2d2b572 100644 --- a/tests/ui/manual_find_map.rs +++ b/tests/ui/manual_find_map.rs @@ -7,45 +7,66 @@ fn main() { // is_some(), unwrap() let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap()); + //~^ manual_find_map // ref pattern, expect() let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); + //~^ manual_find_map // is_ok(), unwrap_or() let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); + //~^ manual_find_map let _ = (1..5) .find(|&x| to_ref(to_opt(x)).is_some()) + //~^ manual_find_map .map(|y| to_ref(to_opt(y)).unwrap()); let _ = (1..5) .find(|x| to_ref(to_opt(*x)).is_some()) + //~^ manual_find_map .map(|y| to_ref(to_opt(y)).unwrap()); let _ = (1..5) .find(|&x| to_ref(to_res(x)).is_ok()) + //~^ manual_find_map .map(|y| to_ref(to_res(y)).unwrap()); let _ = (1..5) .find(|x| to_ref(to_res(*x)).is_ok()) + //~^ manual_find_map .map(|y| to_ref(to_res(y)).unwrap()); } #[rustfmt::skip] fn simple_equal() { iter::>().find(|x| x.is_some()).map(|x| x.unwrap()); + //~^ manual_find_map iter::<&Option>().find(|x| x.is_some()).map(|x| x.unwrap()); + //~^ manual_find_map iter::<&&Option>().find(|x| x.is_some()).map(|x| x.unwrap()); + //~^ manual_find_map iter::>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); + //~^ manual_find_map iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); + //~^ manual_find_map iter::<&Option>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap()); + //~^ manual_find_map iter::>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); + //~^ manual_find_map iter::>().find(|x| x.is_ok()).map(|x| x.unwrap()); + //~^ manual_find_map iter::<&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); + //~^ manual_find_map iter::<&&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); + //~^ manual_find_map iter::>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); + //~^ manual_find_map iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); + //~^ manual_find_map iter::<&Result>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap()); + //~^ manual_find_map iter::>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); + //~^ manual_find_map } fn no_lint() { @@ -94,45 +115,54 @@ fn issue_8920() { let _ = vec .iter() .find(|f| f.option_field.is_some()) + //~^ manual_find_map .map(|f| f.option_field.clone().unwrap()); let _ = vec .iter() .find(|f| f.ref_field.is_some()) + //~^ manual_find_map .map(|f| f.ref_field.cloned().unwrap()); let _ = vec .iter() .find(|f| f.ref_field.is_some()) + //~^ manual_find_map .map(|f| f.ref_field.copied().unwrap()); let _ = vec .iter() .find(|f| f.result_field.is_ok()) + //~^ manual_find_map .map(|f| f.result_field.clone().unwrap()); let _ = vec .iter() .find(|f| f.result_field.is_ok()) + //~^ manual_find_map .map(|f| f.result_field.as_ref().unwrap()); let _ = vec .iter() .find(|f| f.result_field.is_ok()) + //~^ manual_find_map .map(|f| f.result_field.as_deref().unwrap()); let _ = vec .iter_mut() .find(|f| f.result_field.is_ok()) + //~^ manual_find_map .map(|f| f.result_field.as_mut().unwrap()); let _ = vec .iter_mut() .find(|f| f.result_field.is_ok()) + //~^ manual_find_map .map(|f| f.result_field.as_deref_mut().unwrap()); let _ = vec .iter() .find(|f| f.result_field.is_ok()) + //~^ manual_find_map .map(|f| f.result_field.to_owned().unwrap()); } diff --git a/tests/ui/manual_find_map.stderr b/tests/ui/manual_find_map.stderr index 2722d59f52a9..8fa6c090e6d2 100644 --- a/tests/ui/manual_find_map.stderr +++ b/tests/ui/manual_find_map.stderr @@ -13,250 +13,263 @@ LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap() = help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:12:19 + --> tests/ui/manual_find_map.rs:13:19 | LL | let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_find_map.rs:12:29 + --> tests/ui/manual_find_map.rs:13:29 | LL | let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:15:19 + --> tests/ui/manual_find_map.rs:17:19 | LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_res(a).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_find_map.rs:15:29 + --> tests/ui/manual_find_map.rs:17:29 | LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:18:10 + --> tests/ui/manual_find_map.rs:21:10 | LL | .find(|&x| to_ref(to_opt(x)).is_some()) | __________^ +LL | | LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_find_map.rs:18:20 + --> tests/ui/manual_find_map.rs:21:20 | LL | .find(|&x| to_ref(to_opt(x)).is_some()) | ^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:21:10 + --> tests/ui/manual_find_map.rs:25:10 | LL | .find(|x| to_ref(to_opt(*x)).is_some()) | __________^ +LL | | LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_find_map.rs:21:19 + --> tests/ui/manual_find_map.rs:25:19 | LL | .find(|x| to_ref(to_opt(*x)).is_some()) | ^^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:25:10 + --> tests/ui/manual_find_map.rs:30:10 | LL | .find(|&x| to_ref(to_res(x)).is_ok()) | __________^ +LL | | LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_find_map.rs:25:20 + --> tests/ui/manual_find_map.rs:30:20 | LL | .find(|&x| to_ref(to_res(x)).is_ok()) | ^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:28:10 + --> tests/ui/manual_find_map.rs:34:10 | LL | .find(|x| to_ref(to_res(*x)).is_ok()) | __________^ +LL | | LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_find_map.rs:28:19 + --> tests/ui/manual_find_map.rs:34:19 | LL | .find(|x| to_ref(to_res(*x)).is_ok()) | ^^^^^^^^^^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:34:26 + --> tests/ui/manual_find_map.rs:41:26 | LL | iter::>().find(|x| x.is_some()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x)` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:35:27 + --> tests/ui/manual_find_map.rs:43:27 | LL | iter::<&Option>().find(|x| x.is_some()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| *x)` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:36:28 + --> tests/ui/manual_find_map.rs:45:28 | LL | iter::<&&Option>().find(|x| x.is_some()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| **x)` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:37:27 + --> tests/ui/manual_find_map.rs:47:27 | LL | iter::>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:38:28 + --> tests/ui/manual_find_map.rs:49:28 | LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:39:31 + --> tests/ui/manual_find_map.rs:51:31 | LL | iter::<&Option>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:40:31 + --> tests/ui/manual_find_map.rs:53:31 | LL | iter::>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_find_map.rs:40:41 + --> tests/ui/manual_find_map.rs:53:41 | LL | iter::>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:42:30 + --> tests/ui/manual_find_map.rs:56:30 | LL | iter::>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:43:31 + --> tests/ui/manual_find_map.rs:58:31 | LL | iter::<&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:44:32 + --> tests/ui/manual_find_map.rs:60:32 | LL | iter::<&&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:45:31 + --> tests/ui/manual_find_map.rs:62:31 | LL | iter::>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:46:32 + --> tests/ui/manual_find_map.rs:64:32 | LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:47:35 + --> tests/ui/manual_find_map.rs:66:35 | LL | iter::<&Result>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:48:35 + --> tests/ui/manual_find_map.rs:68:35 | LL | iter::>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())` | note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once - --> tests/ui/manual_find_map.rs:48:45 + --> tests/ui/manual_find_map.rs:68:45 | LL | iter::>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:96:10 + --> tests/ui/manual_find_map.rs:117:10 | LL | .find(|f| f.option_field.is_some()) | __________^ +LL | | LL | | .map(|f| f.option_field.clone().unwrap()); | |_________________________________________________^ help: try: `find_map(|f| f.option_field.clone())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:101:10 + --> tests/ui/manual_find_map.rs:123:10 | LL | .find(|f| f.ref_field.is_some()) | __________^ +LL | | LL | | .map(|f| f.ref_field.cloned().unwrap()); | |_______________________________________________^ help: try: `find_map(|f| f.ref_field.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:106:10 + --> tests/ui/manual_find_map.rs:129:10 | LL | .find(|f| f.ref_field.is_some()) | __________^ +LL | | LL | | .map(|f| f.ref_field.copied().unwrap()); | |_______________________________________________^ help: try: `find_map(|f| f.ref_field.copied())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:111:10 + --> tests/ui/manual_find_map.rs:135:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.clone().unwrap()); | |_________________________________________________^ help: try: `find_map(|f| f.result_field.clone().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:116:10 + --> tests/ui/manual_find_map.rs:141:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.as_ref().unwrap()); | |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_ref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:121:10 + --> tests/ui/manual_find_map.rs:147:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.as_deref().unwrap()); | |____________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:126:10 + --> tests/ui/manual_find_map.rs:153:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.as_mut().unwrap()); | |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_mut().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:131:10 + --> tests/ui/manual_find_map.rs:159:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.as_deref_mut().unwrap()); | |________________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref_mut().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> tests/ui/manual_find_map.rs:136:10 + --> tests/ui/manual_find_map.rs:165:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ +LL | | LL | | .map(|f| f.result_field.to_owned().unwrap()); | |____________________________________________________^ help: try: `find_map(|f| f.result_field.to_owned().ok())` diff --git a/tests/ui/manual_flatten.rs b/tests/ui/manual_flatten.rs index d57333ace040..e22025c6f1a8 100644 --- a/tests/ui/manual_flatten.rs +++ b/tests/ui/manual_flatten.rs @@ -5,7 +5,8 @@ fn main() { // Test for loop over implicitly adjusted `Iterator` with `if let` expression let x = vec![Some(1), Some(2), Some(3)]; for n in x { - //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element + //~^ manual_flatten + if let Some(y) = n { println!("{}", y); } @@ -14,7 +15,8 @@ fn main() { // Test for loop over implicitly adjusted `Iterator` with `if let` statement let y: Vec> = vec![]; for n in y.clone() { - //~^ ERROR: unnecessary `if let` since only the `Ok` variant of the iterator element i + //~^ manual_flatten + if let Ok(n) = n { println!("{}", n); }; @@ -22,7 +24,8 @@ fn main() { // Test for loop over by reference for n in &y { - //~^ ERROR: unnecessary `if let` since only the `Ok` variant of the iterator element i + //~^ manual_flatten + if let Ok(n) = n { println!("{}", n); } @@ -31,7 +34,8 @@ fn main() { // Test for loop over an implicit reference let z = &y; for n in z { - //~^ ERROR: unnecessary `if let` since only the `Ok` variant of the iterator element i + //~^ manual_flatten + if let Ok(n) = n { println!("{}", n); } @@ -41,7 +45,8 @@ fn main() { let z = vec![Some(1), Some(2), Some(3)]; let z = z.iter(); for n in z { - //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element + //~^ manual_flatten + if let Some(m) = n { println!("{}", m); } @@ -75,7 +80,8 @@ fn main() { let vec_of_ref = vec![&Some(1)]; for n in &vec_of_ref { - //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element + //~^ manual_flatten + if let Some(n) = n { println!("{:?}", n); } @@ -83,7 +89,8 @@ fn main() { let vec_of_ref = &vec_of_ref; for n in vec_of_ref { - //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element + //~^ manual_flatten + if let Some(n) = n { println!("{:?}", n); } @@ -91,7 +98,8 @@ fn main() { let slice_of_ref = &[&Some(1)]; for n in slice_of_ref { - //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element + //~^ manual_flatten + if let Some(n) = n { println!("{:?}", n); } @@ -122,7 +130,8 @@ fn main() { fn run_unformatted_tests() { // Skip rustfmt here on purpose so the suggestion does not fit in one line for n in vec![ - //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element + //~^ manual_flatten + Some(1), Some(2), Some(3) diff --git a/tests/ui/manual_flatten.stderr b/tests/ui/manual_flatten.stderr index cf1b0a1c8bbf..564c0eba8260 100644 --- a/tests/ui/manual_flatten.stderr +++ b/tests/ui/manual_flatten.stderr @@ -6,14 +6,14 @@ LL | for n in x { | _____| | | LL | | +LL | | LL | | if let Some(y) = n { -LL | | println!("{}", y); -LL | | } +... | LL | | } | |_____^ | help: ...and remove the `if let` statement in the for loop - --> tests/ui/manual_flatten.rs:9:9 + --> tests/ui/manual_flatten.rs:10:9 | LL | / if let Some(y) = n { LL | | println!("{}", y); @@ -23,13 +23,14 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_flatten)]` error: unnecessary `if let` since only the `Ok` variant of the iterator element is used - --> tests/ui/manual_flatten.rs:16:5 + --> tests/ui/manual_flatten.rs:17:5 | LL | for n in y.clone() { | ^ --------- help: try: `y.clone().into_iter().flatten()` | _____| | | LL | | +LL | | LL | | if let Ok(n) = n { LL | | println!("{}", n); LL | | }; @@ -37,7 +38,7 @@ LL | | } | |_____^ | help: ...and remove the `if let` statement in the for loop - --> tests/ui/manual_flatten.rs:18:9 + --> tests/ui/manual_flatten.rs:20:9 | LL | / if let Ok(n) = n { LL | | println!("{}", n); @@ -45,21 +46,21 @@ LL | | }; | |_________^ error: unnecessary `if let` since only the `Ok` variant of the iterator element is used - --> tests/ui/manual_flatten.rs:24:5 + --> tests/ui/manual_flatten.rs:26:5 | LL | for n in &y { | ^ -- help: try: `y.iter().flatten()` | _____| | | LL | | +LL | | LL | | if let Ok(n) = n { -LL | | println!("{}", n); -LL | | } +... | LL | | } | |_____^ | help: ...and remove the `if let` statement in the for loop - --> tests/ui/manual_flatten.rs:26:9 + --> tests/ui/manual_flatten.rs:29:9 | LL | / if let Ok(n) = n { LL | | println!("{}", n); @@ -67,21 +68,21 @@ LL | | } | |_________^ error: unnecessary `if let` since only the `Ok` variant of the iterator element is used - --> tests/ui/manual_flatten.rs:33:5 + --> tests/ui/manual_flatten.rs:36:5 | LL | for n in z { | ^ - help: try: `z.iter().flatten()` | _____| | | LL | | +LL | | LL | | if let Ok(n) = n { -LL | | println!("{}", n); -LL | | } +... | LL | | } | |_____^ | help: ...and remove the `if let` statement in the for loop - --> tests/ui/manual_flatten.rs:35:9 + --> tests/ui/manual_flatten.rs:39:9 | LL | / if let Ok(n) = n { LL | | println!("{}", n); @@ -89,21 +90,21 @@ LL | | } | |_________^ error: unnecessary `if let` since only the `Some` variant of the iterator element is used - --> tests/ui/manual_flatten.rs:43:5 + --> tests/ui/manual_flatten.rs:47:5 | LL | for n in z { | ^ - help: try: `z.flatten()` | _____| | | LL | | +LL | | LL | | if let Some(m) = n { -LL | | println!("{}", m); -LL | | } +... | LL | | } | |_____^ | help: ...and remove the `if let` statement in the for loop - --> tests/ui/manual_flatten.rs:45:9 + --> tests/ui/manual_flatten.rs:50:9 | LL | / if let Some(m) = n { LL | | println!("{}", m); @@ -111,21 +112,21 @@ LL | | } | |_________^ error: unnecessary `if let` since only the `Some` variant of the iterator element is used - --> tests/ui/manual_flatten.rs:77:5 + --> tests/ui/manual_flatten.rs:82:5 | LL | for n in &vec_of_ref { | ^ ----------- help: try: `vec_of_ref.iter().copied().flatten()` | _____| | | LL | | +LL | | LL | | if let Some(n) = n { -LL | | println!("{:?}", n); -LL | | } +... | LL | | } | |_____^ | help: ...and remove the `if let` statement in the for loop - --> tests/ui/manual_flatten.rs:79:9 + --> tests/ui/manual_flatten.rs:85:9 | LL | / if let Some(n) = n { LL | | println!("{:?}", n); @@ -133,21 +134,21 @@ LL | | } | |_________^ error: unnecessary `if let` since only the `Some` variant of the iterator element is used - --> tests/ui/manual_flatten.rs:85:5 + --> tests/ui/manual_flatten.rs:91:5 | LL | for n in vec_of_ref { | ^ ---------- help: try: `vec_of_ref.iter().copied().flatten()` | _____| | | LL | | +LL | | LL | | if let Some(n) = n { -LL | | println!("{:?}", n); -LL | | } +... | LL | | } | |_____^ | help: ...and remove the `if let` statement in the for loop - --> tests/ui/manual_flatten.rs:87:9 + --> tests/ui/manual_flatten.rs:94:9 | LL | / if let Some(n) = n { LL | | println!("{:?}", n); @@ -155,21 +156,21 @@ LL | | } | |_________^ error: unnecessary `if let` since only the `Some` variant of the iterator element is used - --> tests/ui/manual_flatten.rs:93:5 + --> tests/ui/manual_flatten.rs:100:5 | LL | for n in slice_of_ref { | ^ ------------ help: try: `slice_of_ref.iter().copied().flatten()` | _____| | | LL | | +LL | | LL | | if let Some(n) = n { -LL | | println!("{:?}", n); -LL | | } +... | LL | | } | |_____^ | help: ...and remove the `if let` statement in the for loop - --> tests/ui/manual_flatten.rs:95:9 + --> tests/ui/manual_flatten.rs:103:9 | LL | / if let Some(n) = n { LL | | println!("{:?}", n); @@ -177,18 +178,18 @@ LL | | } | |_________^ error: unnecessary `if let` since only the `Some` variant of the iterator element is used - --> tests/ui/manual_flatten.rs:124:5 + --> tests/ui/manual_flatten.rs:132:5 | LL | / for n in vec![ LL | | +LL | | LL | | Some(1), -LL | | Some(2), ... | LL | | } | |_____^ | help: remove the `if let` statement in the for loop and then... - --> tests/ui/manual_flatten.rs:130:9 + --> tests/ui/manual_flatten.rs:139:9 | LL | / if let Some(n) = n { LL | | println!("{:?}", n); @@ -198,6 +199,7 @@ help: try | LL ~ for n in vec![ LL + +LL + LL + Some(1), LL + Some(2), LL + Some(3) diff --git a/tests/ui/manual_float_methods.rs b/tests/ui/manual_float_methods.rs index 66545d180ef9..62cdc1c141d0 100644 --- a/tests/ui/manual_float_methods.rs +++ b/tests/ui/manual_float_methods.rs @@ -22,12 +22,18 @@ fn fn_test_not_inf() -> f64 { fn main() { let x = 1.0f32; if x == f32::INFINITY || x == f32::NEG_INFINITY {} + //~^ manual_is_infinite if x != f32::INFINITY && x != f32::NEG_INFINITY {} + //~^ manual_is_finite if x == INFINITE || x == NEG_INFINITE {} + //~^ manual_is_infinite if x != INFINITE && x != NEG_INFINITE {} + //~^ manual_is_finite let x = 1.0f64; if x == f64::INFINITY || x == f64::NEG_INFINITY {} + //~^ manual_is_infinite if x != f64::INFINITY && x != f64::NEG_INFINITY {} + //~^ manual_is_finite // Don't lint if x.is_infinite() {} if x.is_finite() {} @@ -42,6 +48,7 @@ fn main() { const { let x = 1.0f64; if x == f64::INFINITY || x == f64::NEG_INFINITY {} + //~^ manual_is_infinite } const X: f64 = 1.0f64; if const { X == f64::INFINITY || X == f64::NEG_INFINITY } {} diff --git a/tests/ui/manual_float_methods.stderr b/tests/ui/manual_float_methods.stderr index 676a4485ab4d..d2ed50642178 100644 --- a/tests/ui/manual_float_methods.stderr +++ b/tests/ui/manual_float_methods.stderr @@ -8,7 +8,7 @@ LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {} = help: to override `-D warnings` add `#[allow(clippy::manual_is_infinite)]` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:25:8 + --> tests/ui/manual_float_methods.rs:26:8 | LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,13 +29,13 @@ LL | if !x.is_infinite() {} | ~~~~~~~~~~~~~~~~ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:26:8 + --> tests/ui/manual_float_methods.rs:28:8 | LL | if x == INFINITE || x == NEG_INFINITE {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:27:8 + --> tests/ui/manual_float_methods.rs:30:8 | LL | if x != INFINITE && x != NEG_INFINITE {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | if !x.is_infinite() {} | ~~~~~~~~~~~~~~~~ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:29:8 + --> tests/ui/manual_float_methods.rs:33:8 | LL | if x == f64::INFINITY || x == f64::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:30:8 + --> tests/ui/manual_float_methods.rs:35:8 | LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,7 +79,7 @@ LL | if !x.is_infinite() {} | ~~~~~~~~~~~~~~~~ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:44:12 + --> tests/ui/manual_float_methods.rs:50:12 | LL | if x == f64::INFINITY || x == f64::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` diff --git a/tests/ui/manual_hash_one.fixed b/tests/ui/manual_hash_one.fixed index edfd9c4a47bb..e45e4bbc3ce7 100644 --- a/tests/ui/manual_hash_one.fixed +++ b/tests/ui/manual_hash_one.fixed @@ -7,18 +7,21 @@ fn returned(b: impl BuildHasher) -> u64 { b.hash_one(&true) + //~^ manual_hash_one } fn unsized_receiver(b: impl BuildHasher, s: &str) { let _ = b.hash_one(&s[4..10]); + //~^ manual_hash_one } fn owned_value(b: impl BuildHasher, v: Vec) -> Vec { let _ = b.hash_one(&v); + //~^ manual_hash_one v } @@ -86,4 +89,5 @@ fn msrv_1_71(b: impl BuildHasher, v: impl Hash) { let _ = b.hash_one(&v); + //~^ manual_hash_one } diff --git a/tests/ui/manual_hash_one.rs b/tests/ui/manual_hash_one.rs index ee61522853f0..c93e26c8f6bf 100644 --- a/tests/ui/manual_hash_one.rs +++ b/tests/ui/manual_hash_one.rs @@ -7,18 +7,21 @@ fn returned(b: impl BuildHasher) -> u64 { let mut hasher = b.build_hasher(); true.hash(&mut hasher); hasher.finish() + //~^ manual_hash_one } fn unsized_receiver(b: impl BuildHasher, s: &str) { let mut hasher = b.build_hasher(); s[4..10].hash(&mut hasher); let _ = hasher.finish(); + //~^ manual_hash_one } fn owned_value(b: impl BuildHasher, v: Vec) -> Vec { let mut hasher = b.build_hasher(); v.hash(&mut hasher); let _ = hasher.finish(); + //~^ manual_hash_one v } @@ -86,4 +89,5 @@ fn msrv_1_71(b: impl BuildHasher, v: impl Hash) { let mut hasher = b.build_hasher(); v.hash(&mut hasher); let _ = hasher.finish(); + //~^ manual_hash_one } diff --git a/tests/ui/manual_hash_one.stderr b/tests/ui/manual_hash_one.stderr index bcff36d9bafc..b0691e2d396c 100644 --- a/tests/ui/manual_hash_one.stderr +++ b/tests/ui/manual_hash_one.stderr @@ -14,7 +14,7 @@ LL ~ b.hash_one(&true) | error: manual implementation of `BuildHasher::hash_one` - --> tests/ui/manual_hash_one.rs:15:13 + --> tests/ui/manual_hash_one.rs:16:13 | LL | let _ = hasher.finish(); | ^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL ~ let _ = b.hash_one(&s[4..10]); | error: manual implementation of `BuildHasher::hash_one` - --> tests/ui/manual_hash_one.rs:21:13 + --> tests/ui/manual_hash_one.rs:23:13 | LL | let _ = hasher.finish(); | ^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL ~ let _ = b.hash_one(&v); | error: manual implementation of `BuildHasher::hash_one` - --> tests/ui/manual_hash_one.rs:88:13 + --> tests/ui/manual_hash_one.rs:91:13 | LL | let _ = hasher.finish(); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/manual_ignore_case_cmp.fixed b/tests/ui/manual_ignore_case_cmp.fixed index 53a124f59c8d..a75b0702a5ff 100644 --- a/tests/ui/manual_ignore_case_cmp.fixed +++ b/tests/ui/manual_ignore_case_cmp.fixed @@ -7,24 +7,34 @@ fn main() {} fn variants(a: &str, b: &str) { if a.eq_ignore_ascii_case(b) { + //~^ manual_ignore_case_cmp return; } if a.eq_ignore_ascii_case(b) { + //~^ manual_ignore_case_cmp return; } let r = a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp let r = r || a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp r && a.eq_ignore_ascii_case(&b.to_uppercase()); + //~^ manual_ignore_case_cmp // != if !a.eq_ignore_ascii_case(b) { + //~^ manual_ignore_case_cmp return; } if !a.eq_ignore_ascii_case(b) { + //~^ manual_ignore_case_cmp return; } let r = !a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp let r = r || !a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp r && !a.eq_ignore_ascii_case(&b.to_uppercase()); + //~^ manual_ignore_case_cmp } fn unsupported(a: char, b: char) { @@ -36,72 +46,111 @@ fn unsupported(a: char, b: char) { fn char(a: char, b: char) { a.eq_ignore_ascii_case(&b); + //~^ manual_ignore_case_cmp a.to_ascii_lowercase() == *&b.to_ascii_lowercase(); *&a.to_ascii_lowercase() == b.to_ascii_lowercase(); a.eq_ignore_ascii_case(&'a'); + //~^ manual_ignore_case_cmp 'a'.eq_ignore_ascii_case(&b); + //~^ manual_ignore_case_cmp } fn u8(a: u8, b: u8) { a.eq_ignore_ascii_case(&b); + //~^ manual_ignore_case_cmp a.eq_ignore_ascii_case(&b'a'); + //~^ manual_ignore_case_cmp b'a'.eq_ignore_ascii_case(&b); + //~^ manual_ignore_case_cmp } fn ref_str(a: &str, b: &str) { a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp a.to_uppercase().eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp a.eq_ignore_ascii_case("a"); + //~^ manual_ignore_case_cmp "a".eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp } fn ref_ref_str(a: &&str, b: &&str) { a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp a.to_uppercase().eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp a.eq_ignore_ascii_case("a"); + //~^ manual_ignore_case_cmp "a".eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp } fn string(a: String, b: String) { a.eq_ignore_ascii_case(&b); + //~^ manual_ignore_case_cmp a.eq_ignore_ascii_case("a"); + //~^ manual_ignore_case_cmp "a".eq_ignore_ascii_case(&b); + //~^ manual_ignore_case_cmp &a.to_ascii_lowercase() == &b.to_ascii_lowercase(); &&a.to_ascii_lowercase() == &&b.to_ascii_lowercase(); a.eq_ignore_ascii_case("a"); + //~^ manual_ignore_case_cmp "a".eq_ignore_ascii_case(&b); + //~^ manual_ignore_case_cmp } fn ref_string(a: String, b: &String) { a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp a.eq_ignore_ascii_case("a"); + //~^ manual_ignore_case_cmp "a".eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp b.eq_ignore_ascii_case(&a); + //~^ manual_ignore_case_cmp b.eq_ignore_ascii_case("a"); + //~^ manual_ignore_case_cmp "a".eq_ignore_ascii_case(&a); + //~^ manual_ignore_case_cmp } fn string_ref_str(a: String, b: &str) { a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp a.eq_ignore_ascii_case("a"); + //~^ manual_ignore_case_cmp "a".eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp b.eq_ignore_ascii_case(&a); + //~^ manual_ignore_case_cmp b.eq_ignore_ascii_case("a"); + //~^ manual_ignore_case_cmp "a".eq_ignore_ascii_case(&a); + //~^ manual_ignore_case_cmp } fn ref_u8slice(a: &[u8], b: &[u8]) { a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp } fn u8vec(a: Vec, b: Vec) { a.eq_ignore_ascii_case(&b); + //~^ manual_ignore_case_cmp } fn ref_u8vec(a: Vec, b: &Vec) { a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp b.eq_ignore_ascii_case(&a); + //~^ manual_ignore_case_cmp } fn ref_osstr(a: &OsStr, b: &OsStr) { a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp } fn osstring(a: OsString, b: OsString) { a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp } fn ref_osstring(a: OsString, b: &OsString) { a.eq_ignore_ascii_case(b); + //~^ manual_ignore_case_cmp b.eq_ignore_ascii_case(a); + //~^ manual_ignore_case_cmp } diff --git a/tests/ui/manual_ignore_case_cmp.rs b/tests/ui/manual_ignore_case_cmp.rs index 2a4d84b30ace..822f171a4506 100644 --- a/tests/ui/manual_ignore_case_cmp.rs +++ b/tests/ui/manual_ignore_case_cmp.rs @@ -7,24 +7,34 @@ fn main() {} fn variants(a: &str, b: &str) { if a.to_ascii_lowercase() == b.to_ascii_lowercase() { + //~^ manual_ignore_case_cmp return; } if a.to_ascii_uppercase() == b.to_ascii_uppercase() { + //~^ manual_ignore_case_cmp return; } let r = a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase(); + //~^ manual_ignore_case_cmp r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase(); + //~^ manual_ignore_case_cmp // != if a.to_ascii_lowercase() != b.to_ascii_lowercase() { + //~^ manual_ignore_case_cmp return; } if a.to_ascii_uppercase() != b.to_ascii_uppercase() { + //~^ manual_ignore_case_cmp return; } let r = a.to_ascii_lowercase() != b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase(); + //~^ manual_ignore_case_cmp r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn unsupported(a: char, b: char) { @@ -36,72 +46,111 @@ fn unsupported(a: char, b: char) { fn char(a: char, b: char) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp a.to_ascii_lowercase() == *&b.to_ascii_lowercase(); *&a.to_ascii_lowercase() == b.to_ascii_lowercase(); a.to_ascii_lowercase() == 'a'; + //~^ manual_ignore_case_cmp 'a' == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn u8(a: u8, b: u8) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp a.to_ascii_lowercase() == b'a'; + //~^ manual_ignore_case_cmp b'a' == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn ref_str(a: &str, b: &str) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp a.to_ascii_lowercase() == "a"; + //~^ manual_ignore_case_cmp "a" == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn ref_ref_str(a: &&str, b: &&str) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp a.to_ascii_lowercase() == "a"; + //~^ manual_ignore_case_cmp "a" == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn string(a: String, b: String) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp a.to_ascii_lowercase() == "a"; + //~^ manual_ignore_case_cmp "a" == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp &a.to_ascii_lowercase() == &b.to_ascii_lowercase(); &&a.to_ascii_lowercase() == &&b.to_ascii_lowercase(); a.to_ascii_lowercase() == "a"; + //~^ manual_ignore_case_cmp "a" == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn ref_string(a: String, b: &String) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp a.to_ascii_lowercase() == "a"; + //~^ manual_ignore_case_cmp "a" == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp b.to_ascii_lowercase() == a.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp b.to_ascii_lowercase() == "a"; + //~^ manual_ignore_case_cmp "a" == a.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn string_ref_str(a: String, b: &str) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp a.to_ascii_lowercase() == "a"; + //~^ manual_ignore_case_cmp "a" == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp b.to_ascii_lowercase() == a.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp b.to_ascii_lowercase() == "a"; + //~^ manual_ignore_case_cmp "a" == a.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn ref_u8slice(a: &[u8], b: &[u8]) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn u8vec(a: Vec, b: Vec) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn ref_u8vec(a: Vec, b: &Vec) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp b.to_ascii_lowercase() == a.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn ref_osstr(a: &OsStr, b: &OsStr) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn osstring(a: OsString, b: OsString) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } fn ref_osstring(a: OsString, b: &OsString) { a.to_ascii_lowercase() == b.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp b.to_ascii_lowercase() == a.to_ascii_lowercase(); + //~^ manual_ignore_case_cmp } diff --git a/tests/ui/manual_ignore_case_cmp.stderr b/tests/ui/manual_ignore_case_cmp.stderr index 11e8b8aebb54..14cd8cfc1731 100644 --- a/tests/ui/manual_ignore_case_cmp.stderr +++ b/tests/ui/manual_ignore_case_cmp.stderr @@ -15,7 +15,7 @@ LL | if a.eq_ignore_ascii_case(b) { | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:12:8 + --> tests/ui/manual_ignore_case_cmp.rs:13:8 | LL | if a.to_ascii_uppercase() == b.to_ascii_uppercase() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | if a.eq_ignore_ascii_case(b) { | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:15:13 + --> tests/ui/manual_ignore_case_cmp.rs:17:13 | LL | let r = a.to_ascii_lowercase() == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | let r = a.eq_ignore_ascii_case(b); | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:16:18 + --> tests/ui/manual_ignore_case_cmp.rs:19:18 | LL | let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | let r = r || a.eq_ignore_ascii_case(b); | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:17:10 + --> tests/ui/manual_ignore_case_cmp.rs:21:10 | LL | r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | r && a.eq_ignore_ascii_case(&b.to_uppercase()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:19:8 + --> tests/ui/manual_ignore_case_cmp.rs:24:8 | LL | if a.to_ascii_lowercase() != b.to_ascii_lowercase() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | if !a.eq_ignore_ascii_case(b) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:22:8 + --> tests/ui/manual_ignore_case_cmp.rs:28:8 | LL | if a.to_ascii_uppercase() != b.to_ascii_uppercase() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | if !a.eq_ignore_ascii_case(b) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:25:13 + --> tests/ui/manual_ignore_case_cmp.rs:32:13 | LL | let r = a.to_ascii_lowercase() != b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL | let r = !a.eq_ignore_ascii_case(b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:26:18 + --> tests/ui/manual_ignore_case_cmp.rs:34:18 | LL | let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL | let r = r || !a.eq_ignore_ascii_case(b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:27:10 + --> tests/ui/manual_ignore_case_cmp.rs:36:10 | LL | r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | r && !a.eq_ignore_ascii_case(&b.to_uppercase()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:38:5 + --> tests/ui/manual_ignore_case_cmp.rs:48:5 | LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -125,7 +125,7 @@ LL | a.eq_ignore_ascii_case(&b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:41:5 + --> tests/ui/manual_ignore_case_cmp.rs:52:5 | LL | a.to_ascii_lowercase() == 'a'; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | a.eq_ignore_ascii_case(&'a'); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:42:5 + --> tests/ui/manual_ignore_case_cmp.rs:54:5 | LL | 'a' == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -147,7 +147,7 @@ LL | 'a'.eq_ignore_ascii_case(&b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:45:5 + --> tests/ui/manual_ignore_case_cmp.rs:58:5 | LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -158,7 +158,7 @@ LL | a.eq_ignore_ascii_case(&b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:46:5 + --> tests/ui/manual_ignore_case_cmp.rs:60:5 | LL | a.to_ascii_lowercase() == b'a'; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | a.eq_ignore_ascii_case(&b'a'); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:47:5 + --> tests/ui/manual_ignore_case_cmp.rs:62:5 | LL | b'a' == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -180,7 +180,7 @@ LL | b'a'.eq_ignore_ascii_case(&b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:50:5 + --> tests/ui/manual_ignore_case_cmp.rs:66:5 | LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -190,151 +190,19 @@ help: consider using `.eq_ignore_ascii_case()` instead LL | a.eq_ignore_ascii_case(b); | ~~~~~~~~~~~~~~~~~~~~~~~~~ -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:51:5 - | -LL | a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.to_uppercase().eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:52:5 - | -LL | a.to_ascii_lowercase() == "a"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:53:5 - | -LL | "a" == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:56:5 - | -LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:57:5 - | -LL | a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.to_uppercase().eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:58:5 - | -LL | a.to_ascii_lowercase() == "a"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:59:5 - | -LL | "a" == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | "a".eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:62:5 - | -LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:63:5 - | -LL | a.to_ascii_lowercase() == "a"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:64:5 - | -LL | "a" == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | "a".eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:67:5 - | -LL | a.to_ascii_lowercase() == "a"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:68:5 | -LL | "a" == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider using `.eq_ignore_ascii_case()` instead | -LL | "a".eq_ignore_ascii_case(&b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | a.to_uppercase().eq_ignore_ascii_case(b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:71:5 - | -LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:72:5 + --> tests/ui/manual_ignore_case_cmp.rs:70:5 | LL | a.to_ascii_lowercase() == "a"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -345,7 +213,7 @@ LL | a.eq_ignore_ascii_case("a"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:73:5 + --> tests/ui/manual_ignore_case_cmp.rs:72:5 | LL | "a" == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -355,42 +223,9 @@ help: consider using `.eq_ignore_ascii_case()` instead LL | "a".eq_ignore_ascii_case(b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:75:5 - | -LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | b.eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ - error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:76:5 | -LL | b.to_ascii_lowercase() == "a"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | b.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:77:5 - | -LL | "a" == a.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | "a".eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:80:5 - | LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -400,7 +235,18 @@ LL | a.eq_ignore_ascii_case(b); | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:81:5 + --> tests/ui/manual_ignore_case_cmp.rs:78:5 + | +LL | a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.to_uppercase().eq_ignore_ascii_case(b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:80:5 | LL | a.to_ascii_lowercase() == "a"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -421,53 +267,9 @@ help: consider using `.eq_ignore_ascii_case()` instead LL | "a".eq_ignore_ascii_case(b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:84:5 - | -LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | b.eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:85:5 - | -LL | b.to_ascii_lowercase() == "a"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | b.eq_ignore_ascii_case("a"); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:86:5 | -LL | "a" == a.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | "a".eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:89:5 - | -LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using `.eq_ignore_ascii_case()` instead - | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:92:5 - | LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -477,29 +279,51 @@ LL | a.eq_ignore_ascii_case(&b); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:95:5 + --> tests/ui/manual_ignore_case_cmp.rs:88:5 | -LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | a.to_ascii_lowercase() == "a"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | a.eq_ignore_ascii_case("a"); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:90:5 + | +LL | "a" == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | "a".eq_ignore_ascii_case(&b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:94:5 + | +LL | a.to_ascii_lowercase() == "a"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.eq_ignore_ascii_case("a"); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:96:5 | -LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | "a" == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider using `.eq_ignore_ascii_case()` instead | -LL | b.eq_ignore_ascii_case(&a); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | "a".eq_ignore_ascii_case(&b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:99:5 + --> tests/ui/manual_ignore_case_cmp.rs:100:5 | LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -512,16 +336,60 @@ LL | a.eq_ignore_ascii_case(b); error: manual case-insensitive ASCII comparison --> tests/ui/manual_ignore_case_cmp.rs:102:5 | -LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); +LL | a.to_ascii_lowercase() == "a"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.eq_ignore_ascii_case("a"); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:104:5 + | +LL | "a" == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | "a".eq_ignore_ascii_case(b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:107:5 + | +LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider using `.eq_ignore_ascii_case()` instead | -LL | a.eq_ignore_ascii_case(b); - | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | b.eq_ignore_ascii_case(&a); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:105:5 + --> tests/ui/manual_ignore_case_cmp.rs:109:5 + | +LL | b.to_ascii_lowercase() == "a"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | b.eq_ignore_ascii_case("a"); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:111:5 + | +LL | "a" == a.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | "a".eq_ignore_ascii_case(&a); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:115:5 | LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -532,7 +400,139 @@ LL | a.eq_ignore_ascii_case(b); | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: manual case-insensitive ASCII comparison - --> tests/ui/manual_ignore_case_cmp.rs:106:5 + --> tests/ui/manual_ignore_case_cmp.rs:117:5 + | +LL | a.to_ascii_lowercase() == "a"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.eq_ignore_ascii_case("a"); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:119:5 + | +LL | "a" == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | "a".eq_ignore_ascii_case(b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:122:5 + | +LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | b.eq_ignore_ascii_case(&a); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:124:5 + | +LL | b.to_ascii_lowercase() == "a"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | b.eq_ignore_ascii_case("a"); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:126:5 + | +LL | "a" == a.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | "a".eq_ignore_ascii_case(&a); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:130:5 + | +LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.eq_ignore_ascii_case(b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:134:5 + | +LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.eq_ignore_ascii_case(&b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:138:5 + | +LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.eq_ignore_ascii_case(b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:140:5 + | +LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | b.eq_ignore_ascii_case(&a); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:144:5 + | +LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.eq_ignore_ascii_case(b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:148:5 + | +LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.eq_ignore_ascii_case(b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:152:5 + | +LL | a.to_ascii_lowercase() == b.to_ascii_lowercase(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL | a.eq_ignore_ascii_case(b); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:154:5 | LL | b.to_ascii_lowercase() == a.to_ascii_lowercase(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/manual_inspect.fixed b/tests/ui/manual_inspect.fixed index 0e1b8fe3edb5..8512da0bdf62 100644 --- a/tests/ui/manual_inspect.fixed +++ b/tests/ui/manual_inspect.fixed @@ -3,24 +3,29 @@ fn main() { let _ = Some(0).inspect(|&x| { + //~^ manual_inspect println!("{}", x); }); let _ = Some(0).inspect(|&x| { + //~^ manual_inspect println!("{x}"); }); let _ = Some(0).inspect(|&x| { + //~^ manual_inspect println!("{}", x * 5 + 1); }); let _ = Some(0).inspect(|&x| { + //~^ manual_inspect if x == 0 { panic!(); } }); let _ = Some(0).inspect(|&x| { + //~^ manual_inspect if &x == &0 { let _y = x; panic!(); @@ -71,6 +76,7 @@ fn main() { } let _ = Some((String::new(), 0u32)).inspect(|x| { + //~^ manual_inspect if x.1 == 0 { let _x = x.1; panic!(); @@ -96,6 +102,7 @@ fn main() { }); let _ = Some(String::new()).inspect(|x| { + //~^ manual_inspect if x.is_empty() { let _ = || { let _x = x; @@ -106,6 +113,7 @@ fn main() { }); let _ = Some(0).inspect(|&x| { + //~^ manual_inspect if x == 0 { let _ = || { let _x = x; @@ -120,6 +128,7 @@ fn main() { struct Cell2(core::cell::Cell); let _ = Some(Cell2(Cell::new(0u32))).inspect(|x| { + //~^ manual_inspect x.0.set(1); }); @@ -135,16 +144,20 @@ fn main() { } let _: Result<_, ()> = Ok(0).inspect(|&x| { + //~^ manual_inspect println!("{}", x); }); let _: Result<(), _> = Err(0).inspect_err(|&x| { + //~^ manual_inspect println!("{}", x); }); let _ = [0] + //~^ suspicious_map .into_iter() .inspect(|&x| { + //~^ manual_inspect println!("{}", x); }) .count(); diff --git a/tests/ui/manual_inspect.rs b/tests/ui/manual_inspect.rs index 94cdfe391400..7f07394d4b22 100644 --- a/tests/ui/manual_inspect.rs +++ b/tests/ui/manual_inspect.rs @@ -3,21 +3,25 @@ fn main() { let _ = Some(0).map(|x| { + //~^ manual_inspect println!("{}", x); x }); let _ = Some(0).map(|x| { + //~^ manual_inspect println!("{x}"); x }); let _ = Some(0).map(|x| { + //~^ manual_inspect println!("{}", x * 5 + 1); x }); let _ = Some(0).map(|x| { + //~^ manual_inspect if x == 0 { panic!(); } @@ -25,6 +29,7 @@ fn main() { }); let _ = Some(0).map(|x| { + //~^ manual_inspect if &x == &0 { let _y = x; panic!(); @@ -76,6 +81,7 @@ fn main() { } let _ = Some((String::new(), 0u32)).map(|x| { + //~^ manual_inspect if x.1 == 0 { let _x = x.1; panic!(); @@ -102,6 +108,7 @@ fn main() { }); let _ = Some(String::new()).map(|x| { + //~^ manual_inspect if x.is_empty() { let _ = || { let _x = &x; @@ -113,6 +120,7 @@ fn main() { }); let _ = Some(0).map(|x| { + //~^ manual_inspect if x == 0 { let _ = || { let _x = x; @@ -128,6 +136,7 @@ fn main() { struct Cell2(core::cell::Cell); let _ = Some(Cell2(Cell::new(0u32))).map(|x| { + //~^ manual_inspect x.0.set(1); x }); @@ -144,18 +153,22 @@ fn main() { } let _: Result<_, ()> = Ok(0).map(|x| { + //~^ manual_inspect println!("{}", x); x }); let _: Result<(), _> = Err(0).map_err(|x| { + //~^ manual_inspect println!("{}", x); x }); let _ = [0] + //~^ suspicious_map .into_iter() .map(|x| { + //~^ manual_inspect println!("{}", x); x }) diff --git a/tests/ui/manual_inspect.stderr b/tests/ui/manual_inspect.stderr index 0559b3bd6611..510325d2baaa 100644 --- a/tests/ui/manual_inspect.stderr +++ b/tests/ui/manual_inspect.stderr @@ -9,11 +9,12 @@ LL | let _ = Some(0).map(|x| { help: try | LL ~ let _ = Some(0).inspect(|&x| { +LL | LL ~ println!("{}", x); | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:10:21 + --> tests/ui/manual_inspect.rs:11:21 | LL | let _ = Some(0).map(|x| { | ^^^ @@ -21,11 +22,12 @@ LL | let _ = Some(0).map(|x| { help: try | LL ~ let _ = Some(0).inspect(|&x| { +LL | LL ~ println!("{x}"); | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:15:21 + --> tests/ui/manual_inspect.rs:17:21 | LL | let _ = Some(0).map(|x| { | ^^^ @@ -33,11 +35,12 @@ LL | let _ = Some(0).map(|x| { help: try | LL ~ let _ = Some(0).inspect(|&x| { +LL | LL ~ println!("{}", x * 5 + 1); | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:20:21 + --> tests/ui/manual_inspect.rs:23:21 | LL | let _ = Some(0).map(|x| { | ^^^ @@ -45,13 +48,14 @@ LL | let _ = Some(0).map(|x| { help: try | LL ~ let _ = Some(0).inspect(|&x| { +LL | LL | if x == 0 { LL | panic!(); LL ~ } | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:27:21 + --> tests/ui/manual_inspect.rs:31:21 | LL | let _ = Some(0).map(|x| { | ^^^ @@ -59,14 +63,14 @@ LL | let _ = Some(0).map(|x| { help: try | LL ~ let _ = Some(0).inspect(|&x| { -LL | if &x == &0 { -LL | let _y = x; +LL | +... LL | panic!(); LL ~ } | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:78:41 + --> tests/ui/manual_inspect.rs:83:41 | LL | let _ = Some((String::new(), 0u32)).map(|x| { | ^^^ @@ -74,14 +78,14 @@ LL | let _ = Some((String::new(), 0u32)).map(|x| { help: try | LL ~ let _ = Some((String::new(), 0u32)).inspect(|x| { -LL | if x.1 == 0 { -LL | let _x = x.1; +LL | +... LL | panic!(); LL ~ } | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:104:33 + --> tests/ui/manual_inspect.rs:110:33 | LL | let _ = Some(String::new()).map(|x| { | ^^^ @@ -89,6 +93,7 @@ LL | let _ = Some(String::new()).map(|x| { help: try | LL ~ let _ = Some(String::new()).inspect(|x| { +LL | LL | if x.is_empty() { LL | let _ = || { LL ~ let _x = x; @@ -99,7 +104,7 @@ LL ~ println!("test"); | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:115:21 + --> tests/ui/manual_inspect.rs:122:21 | LL | let _ = Some(0).map(|x| { | ^^^ @@ -107,14 +112,14 @@ LL | let _ = Some(0).map(|x| { help: try | LL ~ let _ = Some(0).inspect(|&x| { -LL | if x == 0 { +LL | ... LL | panic!(); LL ~ } | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:130:46 + --> tests/ui/manual_inspect.rs:138:46 | LL | let _ = Some(Cell2(Cell::new(0u32))).map(|x| { | ^^^ @@ -122,11 +127,12 @@ LL | let _ = Some(Cell2(Cell::new(0u32))).map(|x| { help: try | LL ~ let _ = Some(Cell2(Cell::new(0u32))).inspect(|x| { +LL | LL ~ x.0.set(1); | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:146:34 + --> tests/ui/manual_inspect.rs:155:34 | LL | let _: Result<_, ()> = Ok(0).map(|x| { | ^^^ @@ -134,11 +140,12 @@ LL | let _: Result<_, ()> = Ok(0).map(|x| { help: try | LL ~ let _: Result<_, ()> = Ok(0).inspect(|&x| { +LL | LL ~ println!("{}", x); | error: using `map_err` over `inspect_err` - --> tests/ui/manual_inspect.rs:151:35 + --> tests/ui/manual_inspect.rs:161:35 | LL | let _: Result<(), _> = Err(0).map_err(|x| { | ^^^^^^^ @@ -146,18 +153,19 @@ LL | let _: Result<(), _> = Err(0).map_err(|x| { help: try | LL ~ let _: Result<(), _> = Err(0).inspect_err(|&x| { +LL | LL ~ println!("{}", x); | error: this call to `map()` won't have an effect on the call to `count()` - --> tests/ui/manual_inspect.rs:156:13 + --> tests/ui/manual_inspect.rs:167:13 | LL | let _ = [0] | _____________^ +LL | | LL | | .into_iter() LL | | .map(|x| { -LL | | println!("{}", x); -LL | | x +... | LL | | }) LL | | .count(); | |________________^ @@ -167,7 +175,7 @@ LL | | .count(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]` error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:158:10 + --> tests/ui/manual_inspect.rs:170:10 | LL | .map(|x| { | ^^^ @@ -175,6 +183,7 @@ LL | .map(|x| { help: try | LL ~ .inspect(|&x| { +LL | LL ~ println!("{}", x); | diff --git a/tests/ui/manual_instant_elapsed.fixed b/tests/ui/manual_instant_elapsed.fixed index 1811337652dd..4ef22002226e 100644 --- a/tests/ui/manual_instant_elapsed.fixed +++ b/tests/ui/manual_instant_elapsed.fixed @@ -15,6 +15,7 @@ fn main() { } let duration = prev_instant.elapsed(); + //~^ manual_instant_elapsed // don't catch let duration = prev_instant.elapsed(); @@ -24,4 +25,5 @@ fn main() { let ref_to_instant = &Instant::now(); (*ref_to_instant).elapsed(); // to ensure parens are added correctly + //~^ manual_instant_elapsed } diff --git a/tests/ui/manual_instant_elapsed.rs b/tests/ui/manual_instant_elapsed.rs index fedca38b158a..4586b33cf880 100644 --- a/tests/ui/manual_instant_elapsed.rs +++ b/tests/ui/manual_instant_elapsed.rs @@ -15,6 +15,7 @@ fn main() { } let duration = Instant::now() - prev_instant; + //~^ manual_instant_elapsed // don't catch let duration = prev_instant.elapsed(); @@ -24,4 +25,5 @@ fn main() { let ref_to_instant = &Instant::now(); Instant::now() - *ref_to_instant; // to ensure parens are added correctly + //~^ manual_instant_elapsed } diff --git a/tests/ui/manual_instant_elapsed.stderr b/tests/ui/manual_instant_elapsed.stderr index e8ffeb5f8ca3..e84f3126f707 100644 --- a/tests/ui/manual_instant_elapsed.stderr +++ b/tests/ui/manual_instant_elapsed.stderr @@ -8,7 +8,7 @@ LL | let duration = Instant::now() - prev_instant; = help: to override `-D warnings` add `#[allow(clippy::manual_instant_elapsed)]` error: manual implementation of `Instant::elapsed` - --> tests/ui/manual_instant_elapsed.rs:26:5 + --> tests/ui/manual_instant_elapsed.rs:27:5 | LL | Instant::now() - *ref_to_instant; // to ensure parens are added correctly | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*ref_to_instant).elapsed()` diff --git a/tests/ui/manual_is_ascii_check.fixed b/tests/ui/manual_is_ascii_check.fixed index 179149f697db..7b0d19068346 100644 --- a/tests/ui/manual_is_ascii_check.fixed +++ b/tests/ui/manual_is_ascii_check.fixed @@ -3,29 +3,45 @@ fn main() { assert!('x'.is_ascii_lowercase()); + //~^ manual_is_ascii_check assert!('X'.is_ascii_uppercase()); + //~^ manual_is_ascii_check assert!(b'x'.is_ascii_lowercase()); + //~^ manual_is_ascii_check assert!(b'X'.is_ascii_uppercase()); + //~^ manual_is_ascii_check let num = '2'; assert!(num.is_ascii_digit()); + //~^ manual_is_ascii_check assert!(b'1'.is_ascii_digit()); + //~^ manual_is_ascii_check assert!('x'.is_ascii_alphabetic()); + //~^ manual_is_ascii_check assert!(matches!('x', 'A'..='Z' | 'a'..='z' | '_')); b'0'.is_ascii_digit(); + //~^ manual_is_ascii_check b'a'.is_ascii_lowercase(); + //~^ manual_is_ascii_check b'A'.is_ascii_uppercase(); + //~^ manual_is_ascii_check '0'.is_ascii_digit(); + //~^ manual_is_ascii_check 'a'.is_ascii_lowercase(); + //~^ manual_is_ascii_check 'A'.is_ascii_uppercase(); + //~^ manual_is_ascii_check let cool_letter = &'g'; cool_letter.is_ascii_digit(); + //~^ manual_is_ascii_check cool_letter.is_ascii_lowercase(); + //~^ manual_is_ascii_check cool_letter.is_ascii_uppercase(); + //~^ manual_is_ascii_check } #[clippy::msrv = "1.23"] @@ -39,9 +55,13 @@ fn msrv_1_23() { #[clippy::msrv = "1.24"] fn msrv_1_24() { assert!(b'1'.is_ascii_digit()); + //~^ manual_is_ascii_check assert!('X'.is_ascii_uppercase()); + //~^ manual_is_ascii_check assert!('x'.is_ascii_alphabetic()); + //~^ manual_is_ascii_check assert!('x'.is_ascii_hexdigit()); + //~^ manual_is_ascii_check } #[clippy::msrv = "1.46"] @@ -53,14 +73,18 @@ fn msrv_1_46() { #[clippy::msrv = "1.47"] fn msrv_1_47() { const FOO: bool = 'x'.is_ascii_digit(); + //~^ manual_is_ascii_check const BAR: bool = 'x'.is_ascii_hexdigit(); + //~^ manual_is_ascii_check } #[allow(clippy::deref_addrof, clippy::needless_borrow)] fn with_refs() { let cool_letter = &&'g'; cool_letter.is_ascii_digit(); + //~^ manual_is_ascii_check cool_letter.is_ascii_lowercase(); + //~^ manual_is_ascii_check } fn generics() { @@ -79,11 +103,16 @@ fn generics() { { } take_while(|c: char| c.is_ascii_uppercase()); + //~^ manual_is_ascii_check take_while(|c: u8| c.is_ascii_uppercase()); + //~^ manual_is_ascii_check take_while(|c: char| c.is_ascii_uppercase()); + //~^ manual_is_ascii_check } fn adds_type_reference() { let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect(); + //~^ manual_is_ascii_check let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect(); + //~^ manual_is_ascii_check } diff --git a/tests/ui/manual_is_ascii_check.rs b/tests/ui/manual_is_ascii_check.rs index 74f35ce94e84..e4f7fe9f5838 100644 --- a/tests/ui/manual_is_ascii_check.rs +++ b/tests/ui/manual_is_ascii_check.rs @@ -3,29 +3,45 @@ fn main() { assert!(matches!('x', 'a'..='z')); + //~^ manual_is_ascii_check assert!(matches!('X', 'A'..='Z')); + //~^ manual_is_ascii_check assert!(matches!(b'x', b'a'..=b'z')); + //~^ manual_is_ascii_check assert!(matches!(b'X', b'A'..=b'Z')); + //~^ manual_is_ascii_check let num = '2'; assert!(matches!(num, '0'..='9')); + //~^ manual_is_ascii_check assert!(matches!(b'1', b'0'..=b'9')); + //~^ manual_is_ascii_check assert!(matches!('x', 'A'..='Z' | 'a'..='z')); + //~^ manual_is_ascii_check assert!(matches!('x', 'A'..='Z' | 'a'..='z' | '_')); (b'0'..=b'9').contains(&b'0'); + //~^ manual_is_ascii_check (b'a'..=b'z').contains(&b'a'); + //~^ manual_is_ascii_check (b'A'..=b'Z').contains(&b'A'); + //~^ manual_is_ascii_check ('0'..='9').contains(&'0'); + //~^ manual_is_ascii_check ('a'..='z').contains(&'a'); + //~^ manual_is_ascii_check ('A'..='Z').contains(&'A'); + //~^ manual_is_ascii_check let cool_letter = &'g'; ('0'..='9').contains(cool_letter); + //~^ manual_is_ascii_check ('a'..='z').contains(cool_letter); + //~^ manual_is_ascii_check ('A'..='Z').contains(cool_letter); + //~^ manual_is_ascii_check } #[clippy::msrv = "1.23"] @@ -39,9 +55,13 @@ fn msrv_1_23() { #[clippy::msrv = "1.24"] fn msrv_1_24() { assert!(matches!(b'1', b'0'..=b'9')); + //~^ manual_is_ascii_check assert!(matches!('X', 'A'..='Z')); + //~^ manual_is_ascii_check assert!(matches!('x', 'A'..='Z' | 'a'..='z')); + //~^ manual_is_ascii_check assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F')); + //~^ manual_is_ascii_check } #[clippy::msrv = "1.46"] @@ -53,14 +73,18 @@ fn msrv_1_46() { #[clippy::msrv = "1.47"] fn msrv_1_47() { const FOO: bool = matches!('x', '0'..='9'); + //~^ manual_is_ascii_check const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'); + //~^ manual_is_ascii_check } #[allow(clippy::deref_addrof, clippy::needless_borrow)] fn with_refs() { let cool_letter = &&'g'; ('0'..='9').contains(&&cool_letter); + //~^ manual_is_ascii_check ('a'..='z').contains(*cool_letter); + //~^ manual_is_ascii_check } fn generics() { @@ -79,11 +103,16 @@ fn generics() { { } take_while(|c| ('A'..='Z').contains(&c)); + //~^ manual_is_ascii_check take_while(|c| (b'A'..=b'Z').contains(&c)); + //~^ manual_is_ascii_check take_while(|c: char| ('A'..='Z').contains(&c)); + //~^ manual_is_ascii_check } fn adds_type_reference() { let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect(); + //~^ manual_is_ascii_check let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect(); + //~^ manual_is_ascii_check } diff --git a/tests/ui/manual_is_ascii_check.stderr b/tests/ui/manual_is_ascii_check.stderr index 92d93208006a..cbb7aa2205b6 100644 --- a/tests/ui/manual_is_ascii_check.stderr +++ b/tests/ui/manual_is_ascii_check.stderr @@ -8,145 +8,145 @@ LL | assert!(matches!('x', 'a'..='z')); = help: to override `-D warnings` add `#[allow(clippy::manual_is_ascii_check)]` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:6:13 + --> tests/ui/manual_is_ascii_check.rs:7:13 | LL | assert!(matches!('X', 'A'..='Z')); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'X'.is_ascii_uppercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:7:13 + --> tests/ui/manual_is_ascii_check.rs:9:13 | LL | assert!(matches!(b'x', b'a'..=b'z')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'x'.is_ascii_lowercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:8:13 + --> tests/ui/manual_is_ascii_check.rs:11:13 | LL | assert!(matches!(b'X', b'A'..=b'Z')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'X'.is_ascii_uppercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:11:13 + --> tests/ui/manual_is_ascii_check.rs:15:13 | LL | assert!(matches!(num, '0'..='9')); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.is_ascii_digit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:12:13 + --> tests/ui/manual_is_ascii_check.rs:17:13 | LL | assert!(matches!(b'1', b'0'..=b'9')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'1'.is_ascii_digit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:13:13 + --> tests/ui/manual_is_ascii_check.rs:19:13 | LL | assert!(matches!('x', 'A'..='Z' | 'a'..='z')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_alphabetic()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:17:5 + --> tests/ui/manual_is_ascii_check.rs:24:5 | LL | (b'0'..=b'9').contains(&b'0'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'0'.is_ascii_digit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:18:5 + --> tests/ui/manual_is_ascii_check.rs:26:5 | LL | (b'a'..=b'z').contains(&b'a'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'a'.is_ascii_lowercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:19:5 + --> tests/ui/manual_is_ascii_check.rs:28:5 | LL | (b'A'..=b'Z').contains(&b'A'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'A'.is_ascii_uppercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:21:5 + --> tests/ui/manual_is_ascii_check.rs:31:5 | LL | ('0'..='9').contains(&'0'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'0'.is_ascii_digit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:22:5 + --> tests/ui/manual_is_ascii_check.rs:33:5 | LL | ('a'..='z').contains(&'a'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'a'.is_ascii_lowercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:23:5 + --> tests/ui/manual_is_ascii_check.rs:35:5 | LL | ('A'..='Z').contains(&'A'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'A'.is_ascii_uppercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:26:5 + --> tests/ui/manual_is_ascii_check.rs:39:5 | LL | ('0'..='9').contains(cool_letter); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_digit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:27:5 + --> tests/ui/manual_is_ascii_check.rs:41:5 | LL | ('a'..='z').contains(cool_letter); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_lowercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:28:5 + --> tests/ui/manual_is_ascii_check.rs:43:5 | LL | ('A'..='Z').contains(cool_letter); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_uppercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:41:13 + --> tests/ui/manual_is_ascii_check.rs:57:13 | LL | assert!(matches!(b'1', b'0'..=b'9')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'1'.is_ascii_digit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:42:13 + --> tests/ui/manual_is_ascii_check.rs:59:13 | LL | assert!(matches!('X', 'A'..='Z')); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'X'.is_ascii_uppercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:43:13 + --> tests/ui/manual_is_ascii_check.rs:61:13 | LL | assert!(matches!('x', 'A'..='Z' | 'a'..='z')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_alphabetic()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:44:13 + --> tests/ui/manual_is_ascii_check.rs:63:13 | LL | assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_hexdigit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:55:23 + --> tests/ui/manual_is_ascii_check.rs:75:23 | LL | const FOO: bool = matches!('x', '0'..='9'); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_digit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:56:23 + --> tests/ui/manual_is_ascii_check.rs:77:23 | LL | const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_hexdigit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:62:5 + --> tests/ui/manual_is_ascii_check.rs:84:5 | LL | ('0'..='9').contains(&&cool_letter); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_digit()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:63:5 + --> tests/ui/manual_is_ascii_check.rs:86:5 | LL | ('a'..='z').contains(*cool_letter); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_lowercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:81:20 + --> tests/ui/manual_is_ascii_check.rs:105:20 | LL | take_while(|c| ('A'..='Z').contains(&c)); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | take_while(|c: char| c.is_ascii_uppercase()); | ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:82:20 + --> tests/ui/manual_is_ascii_check.rs:107:20 | LL | take_while(|c| (b'A'..=b'Z').contains(&c)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -168,13 +168,13 @@ LL | take_while(|c: u8| c.is_ascii_uppercase()); | ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:83:26 + --> tests/ui/manual_is_ascii_check.rs:109:26 | LL | take_while(|c: char| ('A'..='Z').contains(&c)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_uppercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:87:63 + --> tests/ui/manual_is_ascii_check.rs:114:63 | LL | let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ LL | let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ | ~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:88:71 + --> tests/ui/manual_is_ascii_check.rs:116:71 | LL | let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/manual_is_power_of_two.fixed b/tests/ui/manual_is_power_of_two.fixed index dda5fe0ec3e7..6f29d76bd210 100644 --- a/tests/ui/manual_is_power_of_two.fixed +++ b/tests/ui/manual_is_power_of_two.fixed @@ -4,13 +4,19 @@ fn main() { let a = 16_u64; let _ = a.is_power_of_two(); + //~^ manual_is_power_of_two let _ = a.is_power_of_two(); + //~^ manual_is_power_of_two // Test different orders of expression let _ = a.is_power_of_two(); + //~^ manual_is_power_of_two let _ = a.is_power_of_two(); + //~^ manual_is_power_of_two let _ = a.is_power_of_two(); + //~^ manual_is_power_of_two let _ = a.is_power_of_two(); + //~^ manual_is_power_of_two let b = 4_i64; diff --git a/tests/ui/manual_is_power_of_two.rs b/tests/ui/manual_is_power_of_two.rs index a1d3a95c4102..0c44d7a660b4 100644 --- a/tests/ui/manual_is_power_of_two.rs +++ b/tests/ui/manual_is_power_of_two.rs @@ -4,13 +4,19 @@ fn main() { let a = 16_u64; let _ = a.count_ones() == 1; + //~^ manual_is_power_of_two let _ = a & (a - 1) == 0; + //~^ manual_is_power_of_two // Test different orders of expression let _ = 1 == a.count_ones(); + //~^ manual_is_power_of_two let _ = (a - 1) & a == 0; + //~^ manual_is_power_of_two let _ = 0 == a & (a - 1); + //~^ manual_is_power_of_two let _ = 0 == (a - 1) & a; + //~^ manual_is_power_of_two let b = 4_i64; diff --git a/tests/ui/manual_is_power_of_two.stderr b/tests/ui/manual_is_power_of_two.stderr index 3cfc6297abf2..ad12ee10565f 100644 --- a/tests/ui/manual_is_power_of_two.stderr +++ b/tests/ui/manual_is_power_of_two.stderr @@ -8,31 +8,31 @@ LL | let _ = a.count_ones() == 1; = help: to override `-D warnings` add `#[allow(clippy::manual_is_power_of_two)]` error: manually reimplementing `is_power_of_two` - --> tests/ui/manual_is_power_of_two.rs:7:13 + --> tests/ui/manual_is_power_of_two.rs:8:13 | LL | let _ = a & (a - 1) == 0; | ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()` error: manually reimplementing `is_power_of_two` - --> tests/ui/manual_is_power_of_two.rs:10:13 + --> tests/ui/manual_is_power_of_two.rs:12:13 | LL | let _ = 1 == a.count_ones(); | ^^^^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()` error: manually reimplementing `is_power_of_two` - --> tests/ui/manual_is_power_of_two.rs:11:13 + --> tests/ui/manual_is_power_of_two.rs:14:13 | LL | let _ = (a - 1) & a == 0; | ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()` error: manually reimplementing `is_power_of_two` - --> tests/ui/manual_is_power_of_two.rs:12:13 + --> tests/ui/manual_is_power_of_two.rs:16:13 | LL | let _ = 0 == a & (a - 1); | ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()` error: manually reimplementing `is_power_of_two` - --> tests/ui/manual_is_power_of_two.rs:13:13 + --> tests/ui/manual_is_power_of_two.rs:18:13 | LL | let _ = 0 == (a - 1) & a; | ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()` diff --git a/tests/ui/manual_is_variant_and.fixed b/tests/ui/manual_is_variant_and.fixed index 8c34b51103c1..c9c184561dd6 100644 --- a/tests/ui/manual_is_variant_and.fixed +++ b/tests/ui/manual_is_variant_and.fixed @@ -13,9 +13,11 @@ fn option_methods() { let _ = opt.is_some_and(|x| x > 1); // Multi-line cases. let _ = opt.is_some_and(|x| { + //~^ manual_is_variant_and x > 1 }); let _ = opt.is_some_and(|x| x > 1); + //~^ manual_is_variant_and let _ = opt .is_some_and(|x| x > 1); @@ -24,6 +26,7 @@ fn option_methods() { let opt2 = Some('a'); let _ = opt2.is_some_and(char::is_alphanumeric); // should lint + //~^ manual_is_variant_and let _ = opt_map!(opt2, |x| x == 'a').unwrap_or_default(); // should not lint } @@ -33,6 +36,7 @@ fn result_methods() { // multi line cases let _ = res.is_ok_and(|x| { + //~^ manual_is_variant_and x > 1 }); let _ = res.is_ok_and(|x| x > 1); @@ -42,6 +46,7 @@ fn result_methods() { let res2: Result = Ok('a'); let _ = res2.is_ok_and(char::is_alphanumeric); // should lint + //~^ manual_is_variant_and let _ = opt_map!(res2, |x| x == 'a').unwrap_or_default(); // should not lint } diff --git a/tests/ui/manual_is_variant_and.rs b/tests/ui/manual_is_variant_and.rs index 25b2489d9421..52c7b56804ce 100644 --- a/tests/ui/manual_is_variant_and.rs +++ b/tests/ui/manual_is_variant_and.rs @@ -11,16 +11,20 @@ fn option_methods() { // Check for `option.map(_).unwrap_or_default()` use. // Single line case. let _ = opt.map(|x| x > 1) + //~^ manual_is_variant_and // Should lint even though this call is on a separate line. .unwrap_or_default(); // Multi-line cases. let _ = opt.map(|x| { + //~^ manual_is_variant_and x > 1 } ).unwrap_or_default(); let _ = opt.map(|x| x > 1).unwrap_or_default(); + //~^ manual_is_variant_and let _ = opt .map(|x| x > 1) + //~^ manual_is_variant_and .unwrap_or_default(); // won't fix because the return type of the closure is not `bool` @@ -28,6 +32,7 @@ fn option_methods() { let opt2 = Some('a'); let _ = opt2.map(char::is_alphanumeric).unwrap_or_default(); // should lint + //~^ manual_is_variant_and let _ = opt_map!(opt2, |x| x == 'a').unwrap_or_default(); // should not lint } @@ -37,10 +42,12 @@ fn result_methods() { // multi line cases let _ = res.map(|x| { + //~^ manual_is_variant_and x > 1 } ).unwrap_or_default(); let _ = res.map(|x| x > 1) + //~^ manual_is_variant_and .unwrap_or_default(); // won't fix because the return type of the closure is not `bool` @@ -48,6 +55,7 @@ fn result_methods() { let res2: Result = Ok('a'); let _ = res2.map(char::is_alphanumeric).unwrap_or_default(); // should lint + //~^ manual_is_variant_and let _ = opt_map!(res2, |x| x == 'a').unwrap_or_default(); // should not lint } diff --git a/tests/ui/manual_is_variant_and.stderr b/tests/ui/manual_is_variant_and.stderr index d3ff7cf8b316..a4fa500580d0 100644 --- a/tests/ui/manual_is_variant_and.stderr +++ b/tests/ui/manual_is_variant_and.stderr @@ -3,7 +3,7 @@ error: called `map().unwrap_or_default()` on an `Option` value | LL | let _ = opt.map(|x| x > 1) | _________________^ -LL | | // Should lint even though this call is on a separate line. +... | LL | | .unwrap_or_default(); | |____________________________^ help: use: `is_some_and(|x| x > 1)` | @@ -11,10 +11,11 @@ LL | | .unwrap_or_default(); = help: to override `-D warnings` add `#[allow(clippy::manual_is_variant_and)]` error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:17:17 + --> tests/ui/manual_is_variant_and.rs:18:17 | LL | let _ = opt.map(|x| { | _________________^ +LL | | LL | | x > 1 LL | | } LL | | ).unwrap_or_default(); @@ -23,35 +24,38 @@ LL | | ).unwrap_or_default(); help: use | LL ~ let _ = opt.is_some_and(|x| { +LL + LL + x > 1 LL ~ }); | error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:21:17 + --> tests/ui/manual_is_variant_and.rs:23:17 | LL | let _ = opt.map(|x| x > 1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x > 1)` error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:23:10 + --> tests/ui/manual_is_variant_and.rs:26:10 | LL | .map(|x| x > 1) | __________^ +LL | | LL | | .unwrap_or_default(); | |____________________________^ help: use: `is_some_and(|x| x > 1)` error: called `map().unwrap_or_default()` on an `Option` value - --> tests/ui/manual_is_variant_and.rs:30:18 + --> tests/ui/manual_is_variant_and.rs:34:18 | LL | let _ = opt2.map(char::is_alphanumeric).unwrap_or_default(); // should lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(char::is_alphanumeric)` error: called `map().unwrap_or_default()` on a `Result` value - --> tests/ui/manual_is_variant_and.rs:39:17 + --> tests/ui/manual_is_variant_and.rs:44:17 | LL | let _ = res.map(|x| { | _________________^ +LL | | LL | | x > 1 LL | | } LL | | ).unwrap_or_default(); @@ -60,20 +64,22 @@ LL | | ).unwrap_or_default(); help: use | LL ~ let _ = res.is_ok_and(|x| { +LL + LL + x > 1 LL ~ }); | error: called `map().unwrap_or_default()` on a `Result` value - --> tests/ui/manual_is_variant_and.rs:43:17 + --> tests/ui/manual_is_variant_and.rs:49:17 | LL | let _ = res.map(|x| x > 1) | _________________^ +LL | | LL | | .unwrap_or_default(); | |____________________________^ help: use: `is_ok_and(|x| x > 1)` error: called `map().unwrap_or_default()` on a `Result` value - --> tests/ui/manual_is_variant_and.rs:50:18 + --> tests/ui/manual_is_variant_and.rs:57:18 | LL | let _ = res2.map(char::is_alphanumeric).unwrap_or_default(); // should lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_ok_and(char::is_alphanumeric)` diff --git a/tests/ui/manual_let_else.rs b/tests/ui/manual_let_else.rs index 2b36c3f3c2fb..e5ef55c0b8a8 100644 --- a/tests/ui/manual_let_else.rs +++ b/tests/ui/manual_let_else.rs @@ -27,17 +27,20 @@ fn main() {} fn fire() { let v = if let Some(v_some) = g() { v_some } else { return }; - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { return; }; let v = if let Some(v) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + // Blocks around the identity should have no impact { { v } } } else { @@ -49,18 +52,22 @@ fn fire() { // continue and break diverge loop { let v = if let Some(v_some) = g() { v_some } else { continue }; - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + let v = if let Some(v_some) = g() { v_some } else { break }; - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + } // panic also diverges let v = if let Some(v_some) = g() { v_some } else { panic!() }; - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + // abort also diverges let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { std::process::abort() @@ -68,7 +75,8 @@ fn fire() { // If whose two branches diverge also diverges let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { if true { return } else { panic!() } @@ -76,7 +84,8 @@ fn fire() { // Diverging after an if still makes the block diverge: let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { if true {} @@ -85,7 +94,8 @@ fn fire() { // The final expression will need to be turned into a statement. let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { panic!(); @@ -94,7 +104,8 @@ fn fire() { // Even if the result is buried multiple expressions deep. let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { panic!(); @@ -110,7 +121,8 @@ fn fire() { // Or if a break gives the value. let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { loop { @@ -121,7 +133,8 @@ fn fire() { // Even if the break is in a weird position. let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { 'a: loop { @@ -137,7 +150,8 @@ fn fire() { // A match diverges if all branches diverge: let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { match 0 { @@ -148,7 +162,8 @@ fn fire() { // An if's expression can cause divergence: let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { if panic!() {}; @@ -156,7 +171,8 @@ fn fire() { // An expression of a match can cause divergence: let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { match panic!() { @@ -166,7 +182,8 @@ fn fire() { // Top level else if let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else if true { return; @@ -176,7 +193,8 @@ fn fire() { // All match arms diverge let v = if let Some(v_some) = g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { match (g(), g()) { @@ -194,7 +212,8 @@ fn fire() { // Tuples supported for the declared variables let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + v_some } else { return; @@ -202,7 +221,8 @@ fn fire() { // Tuples supported with multiple bindings let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + (w_some, v_some) } else { return; @@ -212,6 +232,7 @@ fn fire() { macro_rules! create_binding_if_some { ($n:ident, $e:expr) => { let $n = if let Some(v) = $e { v } else { return }; + //~^ manual_let_else }; } create_binding_if_some!(w, g()); @@ -221,31 +242,37 @@ fn fire() { } let v = if let Variant::A(a, 0) = e() { a } else { return }; - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + // `mut v` is inserted into the pattern let mut v = if let Variant::B(b) = e() { b } else { return }; - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + // Nesting works let nested = Ok(Some(e())); let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + b } else { return; }; // dot dot works let v = if let Variant::A(.., a) = e() { a } else { return }; - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + // () is preserved: a bit of an edge case but make sure it stays around let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + // Tuple structs work let w = if let Some(S { v: x }) = Some(S { v: 0 }) { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + x } else { return; @@ -253,7 +280,8 @@ fn fire() { // Field init shorthand is suggested let v = if let Some(S { v: x }) = Some(S { v: 0 }) { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + x } else { return; @@ -261,7 +289,8 @@ fn fire() { // Multi-field structs also work let (x, S { v }, w) = if let Some(U { v, w, x }) = None::>> { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + (x, v, w) } else { return; @@ -378,7 +407,8 @@ fn not_fire() { let ff = Some(1); let _ = match ff { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + Some(value) => value, _ => macro_call!(), }; @@ -455,5 +485,6 @@ fn issue12337() { // we still emit a lint for manual_let_else let _: Option<()> = try { let v = if let Some(v_some) = g() { v_some } else { return }; + //~^ manual_let_else }; } diff --git a/tests/ui/manual_let_else.stderr b/tests/ui/manual_let_else.stderr index dcd5d4561113..8982a1c567bf 100644 --- a/tests/ui/manual_let_else.stderr +++ b/tests/ui/manual_let_else.stderr @@ -8,10 +8,11 @@ LL | let v = if let Some(v_some) = g() { v_some } else { return }; = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:32:5 + --> tests/ui/manual_let_else.rs:33:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some LL | | } else { LL | | return; @@ -26,12 +27,9 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:39:5 + --> tests/ui/manual_let_else.rs:41:5 | LL | / let v = if let Some(v) = g() { -LL | | -LL | | // Blocks around the identity should have no impact -LL | | { { v } } ... | LL | | return; LL | | }; @@ -47,28 +45,29 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:51:9 + --> tests/ui/manual_let_else.rs:54:9 | LL | let v = if let Some(v_some) = g() { v_some } else { continue }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:53:9 + --> tests/ui/manual_let_else.rs:57:9 | LL | let v = if let Some(v_some) = g() { v_some } else { break }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:58:5 + --> tests/ui/manual_let_else.rs:63:5 | LL | let v = if let Some(v_some) = g() { v_some } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:62:5 + --> tests/ui/manual_let_else.rs:68:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some LL | | } else { LL | | std::process::abort() @@ -83,10 +82,11 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:70:5 + --> tests/ui/manual_let_else.rs:77:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some LL | | } else { LL | | if true { return } else { panic!() } @@ -101,13 +101,13 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:78:5 + --> tests/ui/manual_let_else.rs:86:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some -LL | | } else { -LL | | if true {} +... | LL | | panic!(); LL | | }; | |______^ @@ -121,13 +121,13 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:87:5 + --> tests/ui/manual_let_else.rs:96:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some -LL | | } else { -LL | | panic!(); +... | LL | | () LL | | }; | |______^ @@ -141,12 +141,12 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:96:5 + --> tests/ui/manual_let_else.rs:106:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some -LL | | } else { ... | LL | | }; | |______^ @@ -167,12 +167,12 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:112:5 + --> tests/ui/manual_let_else.rs:123:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some -LL | | } else { ... | LL | | }; | |______^ @@ -188,12 +188,12 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:123:5 + --> tests/ui/manual_let_else.rs:135:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some -LL | | } else { ... | LL | | }; | |______^ @@ -214,12 +214,12 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:139:5 + --> tests/ui/manual_let_else.rs:152:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some -LL | | } else { ... | LL | | }; LL | | }; @@ -236,10 +236,11 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:150:5 + --> tests/ui/manual_let_else.rs:164:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some LL | | } else { LL | | if panic!() {}; @@ -254,12 +255,12 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:158:5 + --> tests/ui/manual_let_else.rs:173:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some -LL | | } else { ... | LL | | }; LL | | }; @@ -275,12 +276,12 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:168:5 + --> tests/ui/manual_let_else.rs:184:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some -LL | | } else if true { ... | LL | | panic!("diverge"); LL | | }; @@ -296,12 +297,12 @@ LL + } }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:178:5 + --> tests/ui/manual_let_else.rs:195:5 | LL | / let v = if let Some(v_some) = g() { LL | | +LL | | LL | | v_some -LL | | } else { ... | LL | | }; | |______^ @@ -324,10 +325,11 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:196:5 + --> tests/ui/manual_let_else.rs:214:5 | LL | / let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) { LL | | +LL | | LL | | v_some LL | | } else { LL | | return; @@ -342,10 +344,11 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:204:5 + --> tests/ui/manual_let_else.rs:223:5 | LL | / let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) { LL | | +LL | | LL | | (w_some, v_some) LL | | } else { LL | | return; @@ -360,7 +363,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:214:13 + --> tests/ui/manual_let_else.rs:234:13 | LL | let $n = if let Some(v) = $e { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };` @@ -371,22 +374,23 @@ LL | create_binding_if_some!(w, g()); = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info) error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:223:5 + --> tests/ui/manual_let_else.rs:244:5 | LL | let v = if let Variant::A(a, 0) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:227:5 + --> tests/ui/manual_let_else.rs:249:5 | LL | let mut v = if let Variant::B(b) = e() { b } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:232:5 + --> tests/ui/manual_let_else.rs:255:5 | LL | / let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { LL | | +LL | | LL | | b LL | | } else { LL | | return; @@ -401,22 +405,23 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:239:5 + --> tests/ui/manual_let_else.rs:263:5 | LL | let v = if let Variant::A(.., a) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:243:5 + --> tests/ui/manual_let_else.rs:268:5 | LL | let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:247:5 + --> tests/ui/manual_let_else.rs:273:5 | LL | / let w = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | +LL | | LL | | x LL | | } else { LL | | return; @@ -431,10 +436,11 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:255:5 + --> tests/ui/manual_let_else.rs:282:5 | LL | / let v = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | +LL | | LL | | x LL | | } else { LL | | return; @@ -449,10 +455,11 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:263:5 + --> tests/ui/manual_let_else.rs:291:5 | LL | / let (x, S { v }, w) = if let Some(U { v, w, x }) = None::>> { LL | | +LL | | LL | | (x, v, w) LL | | } else { LL | | return; @@ -467,17 +474,18 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:380:5 + --> tests/ui/manual_let_else.rs:409:5 | LL | / let _ = match ff { LL | | +LL | | LL | | Some(value) => value, LL | | _ => macro_call!(), LL | | }; | |______^ help: consider writing: `let Some(_) = ff else { macro_call!() };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:457:9 + --> tests/ui/manual_let_else.rs:487:9 | LL | let v = if let Some(v_some) = g() { v_some } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };` diff --git a/tests/ui/manual_let_else_match.rs b/tests/ui/manual_let_else_match.rs index c37b5613ff7d..cdb407030111 100644 --- a/tests/ui/manual_let_else_match.rs +++ b/tests/ui/manual_let_else_match.rs @@ -34,14 +34,16 @@ fn main() {} fn fire() { let v = match g() { - //~^ ERROR: this could be rewritten as `let...else` - //~| NOTE: `-D clippy::manual-let-else` implied by `-D warnings` + //~^ manual_let_else + + Some(v_some) => v_some, None => return, }; let v = match g() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + Some(v_some) => v_some, _ => return, }; @@ -49,13 +51,15 @@ fn fire() { loop { // More complex pattern for the identity arm and diverging arm let v = match h() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + (Some(v), None) | (None, Some(v)) => v, (Some(_), Some(_)) | (None, None) => continue, }; // Custom enums are supported as long as the "else" arm is a simple _ let v = match build_enum() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + Variant::Bar(v) | Variant::Baz(v) => v, _ => continue, }; @@ -64,14 +68,16 @@ fn fire() { // There is a _ in the diverging arm // TODO also support unused bindings aka _v let v = match f() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + Ok(v) => v, Err(_) => return, }; // Err(()) is an allowed pattern let v = match f().map_err(|_| ()) { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + Ok(v) => v, Err(()) => return, }; @@ -79,20 +85,23 @@ fn fire() { let f = Variant::Bar(1); let _value = match f { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + Variant::Bar(v) | Variant::Baz(v) => v, _ => return, }; let _value = match Some(build_enum()) { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + Some(Variant::Bar(v) | Variant::Baz(v)) => v, _ => return, }; let data = [1_u8, 2, 3, 4, 0, 0, 0, 0]; let data = match data.as_slice() { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data, _ => return, }; @@ -173,7 +182,8 @@ fn not_fire() { fn issue11579() { let msg = match Some("hi") { - //~^ ERROR: this could be rewritten as `let...else` + //~^ manual_let_else + Some(m) => m, _ => unreachable!("can't happen"), }; diff --git a/tests/ui/manual_let_else_match.stderr b/tests/ui/manual_let_else_match.stderr index 3c0065f64033..6a65186d6b53 100644 --- a/tests/ui/manual_let_else_match.stderr +++ b/tests/ui/manual_let_else_match.stderr @@ -2,9 +2,7 @@ error: this could be rewritten as `let...else` --> tests/ui/manual_let_else_match.rs:36:5 | LL | / let v = match g() { -LL | | -LL | | -LL | | Some(v_some) => v_some, +... | LL | | None => return, LL | | }; | |______^ help: consider writing: `let Some(v) = g() else { return };` @@ -13,90 +11,99 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:43:5 + --> tests/ui/manual_let_else_match.rs:44:5 | LL | / let v = match g() { LL | | +LL | | LL | | Some(v_some) => v_some, LL | | _ => return, LL | | }; | |______^ help: consider writing: `let Some(v) = g() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:51:9 + --> tests/ui/manual_let_else_match.rs:53:9 | LL | / let v = match h() { LL | | +LL | | LL | | (Some(v), None) | (None, Some(v)) => v, LL | | (Some(_), Some(_)) | (None, None) => continue, LL | | }; | |__________^ help: consider writing: `let ((Some(v), None) | (None, Some(v))) = h() else { continue };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:57:9 + --> tests/ui/manual_let_else_match.rs:60:9 | LL | / let v = match build_enum() { LL | | +LL | | LL | | Variant::Bar(v) | Variant::Baz(v) => v, LL | | _ => continue, LL | | }; | |__________^ help: consider writing: `let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:66:5 + --> tests/ui/manual_let_else_match.rs:70:5 | LL | / let v = match f() { LL | | +LL | | LL | | Ok(v) => v, LL | | Err(_) => return, LL | | }; | |______^ help: consider writing: `let Ok(v) = f() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:73:5 + --> tests/ui/manual_let_else_match.rs:78:5 | LL | / let v = match f().map_err(|_| ()) { LL | | +LL | | LL | | Ok(v) => v, LL | | Err(()) => return, LL | | }; | |______^ help: consider writing: `let Ok(v) = f().map_err(|_| ()) else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:81:5 + --> tests/ui/manual_let_else_match.rs:87:5 | LL | / let _value = match f { LL | | +LL | | LL | | Variant::Bar(v) | Variant::Baz(v) => v, LL | | _ => return, LL | | }; | |______^ help: consider writing: `let (Variant::Bar(_value) | Variant::Baz(_value)) = f else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:87:5 + --> tests/ui/manual_let_else_match.rs:94:5 | LL | / let _value = match Some(build_enum()) { LL | | +LL | | LL | | Some(Variant::Bar(v) | Variant::Baz(v)) => v, LL | | _ => return, LL | | }; | |______^ help: consider writing: `let Some(Variant::Bar(_value) | Variant::Baz(_value)) = Some(build_enum()) else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:94:5 + --> tests/ui/manual_let_else_match.rs:102:5 | LL | / let data = match data.as_slice() { LL | | +LL | | LL | | [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data, LL | | _ => return, LL | | }; | |______^ help: consider writing: `let ([data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0]) = data.as_slice() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:175:5 + --> tests/ui/manual_let_else_match.rs:184:5 | LL | / let msg = match Some("hi") { LL | | +LL | | LL | | Some(m) => m, LL | | _ => unreachable!("can't happen"), LL | | }; diff --git a/tests/ui/manual_let_else_question_mark.fixed b/tests/ui/manual_let_else_question_mark.fixed index 6b29ce759857..aca32a49c13b 100644 --- a/tests/ui/manual_let_else_question_mark.fixed +++ b/tests/ui/manual_let_else_question_mark.fixed @@ -27,15 +27,18 @@ fn main() {} fn foo() -> Option<()> { // Fire here, normal case let v = g()?; + //~^ question_mark // Don't fire here, the pattern is refutable let Variant::A(v, w) = e() else { return None }; // Fire here, the pattern is irrefutable let (v, w) = g()?; + //~^ question_mark // Don't fire manual_let_else in this instance: question mark can be used instead. let v = g()?; + //~^ question_mark // Do fire manual_let_else in this instance: question mark cannot be used here due to the return // body. @@ -56,6 +59,7 @@ fn foo() -> Option<()> { #[allow(clippy::question_mark)] { let Some(v) = g() else { return None }; + //~^ manual_let_else } Some(()) @@ -64,6 +68,7 @@ fn foo() -> Option<()> { // lint not just `return None`, but also `return None;` (note the semicolon) fn issue11993(y: Option) -> Option { let x = y?; + //~^^^ question_mark // don't lint: more than one statement in the else body let Some(x) = y else { diff --git a/tests/ui/manual_let_else_question_mark.rs b/tests/ui/manual_let_else_question_mark.rs index e92c4c1375e5..a07801ce0681 100644 --- a/tests/ui/manual_let_else_question_mark.rs +++ b/tests/ui/manual_let_else_question_mark.rs @@ -27,19 +27,23 @@ fn main() {} fn foo() -> Option<()> { // Fire here, normal case let Some(v) = g() else { return None }; + //~^ question_mark // Don't fire here, the pattern is refutable let Variant::A(v, w) = e() else { return None }; // Fire here, the pattern is irrefutable let Some((v, w)) = g() else { return None }; + //~^ question_mark // Don't fire manual_let_else in this instance: question mark can be used instead. let v = if let Some(v_some) = g() { v_some } else { return None }; + //~^ question_mark // Do fire manual_let_else in this instance: question mark cannot be used here due to the return // body. let v = if let Some(v_some) = g() { + //~^ manual_let_else v_some } else { return Some(()); @@ -51,6 +55,7 @@ fn foo() -> Option<()> { #[allow(clippy::question_mark)] { let v = match g() { + //~^ manual_let_else Some(v_some) => v_some, _ => return None, }; @@ -61,6 +66,7 @@ fn foo() -> Option<()> { #[allow(clippy::question_mark)] { let v = if let Some(v_some) = g() { v_some } else { return None }; + //~^ manual_let_else } Some(()) @@ -71,6 +77,7 @@ fn issue11993(y: Option) -> Option { let Some(x) = y else { return None; }; + //~^^^ question_mark // don't lint: more than one statement in the else body let Some(x) = y else { diff --git a/tests/ui/manual_let_else_question_mark.stderr b/tests/ui/manual_let_else_question_mark.stderr index 434872ca2677..4fdd64d98491 100644 --- a/tests/ui/manual_let_else_question_mark.stderr +++ b/tests/ui/manual_let_else_question_mark.stderr @@ -8,21 +8,22 @@ LL | let Some(v) = g() else { return None }; = help: to override `-D warnings` add `#[allow(clippy::question_mark)]` error: this `let...else` may be rewritten with the `?` operator - --> tests/ui/manual_let_else_question_mark.rs:35:5 + --> tests/ui/manual_let_else_question_mark.rs:36:5 | LL | let Some((v, w)) = g() else { return None }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `let (v, w) = g()?;` error: this block may be rewritten with the `?` operator - --> tests/ui/manual_let_else_question_mark.rs:38:13 + --> tests/ui/manual_let_else_question_mark.rs:40:13 | LL | let v = if let Some(v_some) = g() { v_some } else { return None }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `g()?` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_question_mark.rs:42:5 + --> tests/ui/manual_let_else_question_mark.rs:45:5 | LL | / let v = if let Some(v_some) = g() { +LL | | LL | | v_some LL | | } else { LL | | return Some(()); @@ -39,22 +40,23 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_question_mark.rs:53:9 + --> tests/ui/manual_let_else_question_mark.rs:57:9 | LL | / let v = match g() { +LL | | LL | | Some(v_some) => v_some, LL | | _ => return None, LL | | }; | |__________^ help: consider writing: `let Some(v) = g() else { return None };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_question_mark.rs:63:9 + --> tests/ui/manual_let_else_question_mark.rs:68:9 | LL | let v = if let Some(v_some) = g() { v_some } else { return None }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return None };` error: this `let...else` may be rewritten with the `?` operator - --> tests/ui/manual_let_else_question_mark.rs:71:5 + --> tests/ui/manual_let_else_question_mark.rs:77:5 | LL | / let Some(x) = y else { LL | | return None; diff --git a/tests/ui/manual_main_separator_str.fixed b/tests/ui/manual_main_separator_str.fixed index 6441d6edef8c..6e5478ad009e 100644 --- a/tests/ui/manual_main_separator_str.fixed +++ b/tests/ui/manual_main_separator_str.fixed @@ -19,12 +19,16 @@ struct V { fn main() { // Should lint let _: &str = std::path::MAIN_SEPARATOR_STR; + //~^ manual_main_separator_str let _ = len(std::path::MAIN_SEPARATOR_STR); + //~^ manual_main_separator_str let _: Vec = std::path::MAIN_SEPARATOR_STR.encode_utf16().collect(); + //~^ manual_main_separator_str // Should lint for field `f` only let _ = U { f: std::path::MAIN_SEPARATOR_STR, + //~^ manual_main_separator_str g: &MAIN_SEPARATOR.to_string(), }; diff --git a/tests/ui/manual_main_separator_str.rs b/tests/ui/manual_main_separator_str.rs index 339dfd8bb473..170af2da143f 100644 --- a/tests/ui/manual_main_separator_str.rs +++ b/tests/ui/manual_main_separator_str.rs @@ -19,12 +19,16 @@ struct V { fn main() { // Should lint let _: &str = &MAIN_SEPARATOR.to_string(); + //~^ manual_main_separator_str let _ = len(&MAIN_SEPARATOR.to_string()); + //~^ manual_main_separator_str let _: Vec = MAIN_SEPARATOR.to_string().encode_utf16().collect(); + //~^ manual_main_separator_str // Should lint for field `f` only let _ = U { f: &MAIN_SEPARATOR.to_string(), + //~^ manual_main_separator_str g: &MAIN_SEPARATOR.to_string(), }; diff --git a/tests/ui/manual_main_separator_str.stderr b/tests/ui/manual_main_separator_str.stderr index 78395eb7d664..1c58b8261d4f 100644 --- a/tests/ui/manual_main_separator_str.stderr +++ b/tests/ui/manual_main_separator_str.stderr @@ -8,19 +8,19 @@ LL | let _: &str = &MAIN_SEPARATOR.to_string(); = help: to override `-D warnings` add `#[allow(clippy::manual_main_separator_str)]` error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` - --> tests/ui/manual_main_separator_str.rs:22:17 + --> tests/ui/manual_main_separator_str.rs:23:17 | LL | let _ = len(&MAIN_SEPARATOR.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` - --> tests/ui/manual_main_separator_str.rs:23:23 + --> tests/ui/manual_main_separator_str.rs:25:23 | LL | let _: Vec = MAIN_SEPARATOR.to_string().encode_utf16().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` - --> tests/ui/manual_main_separator_str.rs:27:12 + --> tests/ui/manual_main_separator_str.rs:30:12 | LL | f: &MAIN_SEPARATOR.to_string(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs index 2f21628977cf..9d7cf754f4b8 100644 --- a/tests/ui/manual_map_option.rs +++ b/tests/ui/manual_map_option.rs @@ -12,21 +12,25 @@ fn main() { match Some(0) { + //~^ manual_map Some(_) => Some(2), None:: => None, }; match Some(0) { + //~^ manual_map Some(x) => Some(x + 1), _ => None, }; match Some("") { + //~^ manual_map Some(x) => Some(x.is_empty()), None => None, }; if let Some(x) = Some(0) { + //~^ manual_map Some(!x) } else { None @@ -34,11 +38,13 @@ fn main() { #[rustfmt::skip] match Some(0) { + //~^ manual_map Some(x) => { Some(std::convert::identity(x)) } None => { None } }; match Some(&String::new()) { + //~^ manual_map Some(x) => Some(str::len(x)), None => None, }; @@ -49,26 +55,31 @@ fn main() { }; match &Some([0, 1]) { + //~^ manual_map Some(x) => Some(x[0]), &None => None, }; match &Some(0) { + //~^ manual_map &Some(x) => Some(x * 2), None => None, }; match Some(String::new()) { + //~^ manual_map Some(ref x) => Some(x.is_empty()), _ => None, }; match &&Some(String::new()) { + //~^ manual_map Some(x) => Some(x.len()), _ => None, }; match &&Some(0) { + //~^ manual_map &&Some(x) => Some(x + x), &&_ => None, }; @@ -82,32 +93,38 @@ fn main() { #[allow(clippy::option_map_unit_fn)] { match &mut Some(String::new()) { + //~^ manual_map Some(x) => Some(x.push_str("")), None => None, }; } match &mut Some(String::new()) { + //~^ manual_map Some(ref x) => Some(x.len()), None => None, }; match &mut &Some(String::new()) { + //~^ manual_map Some(x) => Some(x.is_empty()), &mut _ => None, }; match Some((0, 1, 2)) { + //~^ manual_map Some((x, y, z)) => Some(x + y + z), None => None, }; match Some([1, 2, 3]) { + //~^ manual_map Some([first, ..]) => Some(first), None => None, }; match &Some((String::new(), "test")) { + //~^ manual_map Some((x, y)) => Some((y, x)), None => None, }; @@ -177,6 +194,7 @@ fn main() { }; match option_env!("") { + //~^ manual_map Some(x) => Some(String::from(x)), None => None, }; @@ -197,6 +215,7 @@ fn main() { if let Some(_) = Some(0) { Some(0) } else if let Some(x) = Some(0) { + //~^ manual_map Some(x + 1) } else { None @@ -205,6 +224,7 @@ fn main() { if true { Some(0) } else if let Some(x) = Some(0) { + //~^ manual_map Some(x + 1) } else { None diff --git a/tests/ui/manual_map_option.stderr b/tests/ui/manual_map_option.stderr index c496752e2f6d..8f9bce4c265c 100644 --- a/tests/ui/manual_map_option.stderr +++ b/tests/ui/manual_map_option.stderr @@ -2,6 +2,7 @@ error: manual implementation of `Option::map` --> tests/ui/manual_map_option.rs:14:5 | LL | / match Some(0) { +LL | | LL | | Some(_) => Some(2), LL | | None:: => None, LL | | }; @@ -11,27 +12,30 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_map)]` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:19:5 + --> tests/ui/manual_map_option.rs:20:5 | LL | / match Some(0) { +LL | | LL | | Some(x) => Some(x + 1), LL | | _ => None, LL | | }; | |_____^ help: try: `Some(0).map(|x| x + 1)` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:24:5 + --> tests/ui/manual_map_option.rs:26:5 | LL | / match Some("") { +LL | | LL | | Some(x) => Some(x.is_empty()), LL | | None => None, LL | | }; | |_____^ help: try: `Some("").map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:29:5 + --> tests/ui/manual_map_option.rs:32:5 | LL | / if let Some(x) = Some(0) { +LL | | LL | | Some(!x) LL | | } else { LL | | None @@ -39,136 +43,151 @@ LL | | }; | |_____^ help: try: `Some(0).map(|x| !x)` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:36:5 + --> tests/ui/manual_map_option.rs:40:5 | LL | / match Some(0) { +LL | | LL | | Some(x) => { Some(std::convert::identity(x)) } LL | | None => { None } LL | | }; | |_____^ help: try: `Some(0).map(std::convert::identity)` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:41:5 + --> tests/ui/manual_map_option.rs:46:5 | LL | / match Some(&String::new()) { +LL | | LL | | Some(x) => Some(str::len(x)), LL | | None => None, LL | | }; | |_____^ help: try: `Some(&String::new()).map(|x| str::len(x))` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:51:5 + --> tests/ui/manual_map_option.rs:57:5 | LL | / match &Some([0, 1]) { +LL | | LL | | Some(x) => Some(x[0]), LL | | &None => None, LL | | }; | |_____^ help: try: `Some([0, 1]).as_ref().map(|x| x[0])` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:56:5 + --> tests/ui/manual_map_option.rs:63:5 | LL | / match &Some(0) { +LL | | LL | | &Some(x) => Some(x * 2), LL | | None => None, LL | | }; | |_____^ help: try: `Some(0).map(|x| x * 2)` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:61:5 + --> tests/ui/manual_map_option.rs:69:5 | LL | / match Some(String::new()) { +LL | | LL | | Some(ref x) => Some(x.is_empty()), LL | | _ => None, LL | | }; | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:66:5 + --> tests/ui/manual_map_option.rs:75:5 | LL | / match &&Some(String::new()) { +LL | | LL | | Some(x) => Some(x.len()), LL | | _ => None, LL | | }; | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:71:5 + --> tests/ui/manual_map_option.rs:81:5 | LL | / match &&Some(0) { +LL | | LL | | &&Some(x) => Some(x + x), LL | | &&_ => None, LL | | }; | |_____^ help: try: `Some(0).map(|x| x + x)` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:84:9 + --> tests/ui/manual_map_option.rs:95:9 | LL | / match &mut Some(String::new()) { +LL | | LL | | Some(x) => Some(x.push_str("")), LL | | None => None, LL | | }; | |_________^ help: try: `Some(String::new()).as_mut().map(|x| x.push_str(""))` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:90:5 + --> tests/ui/manual_map_option.rs:102:5 | LL | / match &mut Some(String::new()) { +LL | | LL | | Some(ref x) => Some(x.len()), LL | | None => None, LL | | }; | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:95:5 + --> tests/ui/manual_map_option.rs:108:5 | LL | / match &mut &Some(String::new()) { +LL | | LL | | Some(x) => Some(x.is_empty()), LL | | &mut _ => None, LL | | }; | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:100:5 + --> tests/ui/manual_map_option.rs:114:5 | LL | / match Some((0, 1, 2)) { +LL | | LL | | Some((x, y, z)) => Some(x + y + z), LL | | None => None, LL | | }; | |_____^ help: try: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:105:5 + --> tests/ui/manual_map_option.rs:120:5 | LL | / match Some([1, 2, 3]) { +LL | | LL | | Some([first, ..]) => Some(first), LL | | None => None, LL | | }; | |_____^ help: try: `Some([1, 2, 3]).map(|[first, ..]| first)` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:110:5 + --> tests/ui/manual_map_option.rs:126:5 | LL | / match &Some((String::new(), "test")) { +LL | | LL | | Some((x, y)) => Some((y, x)), LL | | None => None, LL | | }; | |_____^ help: try: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:179:5 + --> tests/ui/manual_map_option.rs:196:5 | LL | / match option_env!("") { +LL | | LL | | Some(x) => Some(String::from(x)), LL | | None => None, LL | | }; | |_____^ help: try: `option_env!("").map(String::from)` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:199:12 + --> tests/ui/manual_map_option.rs:217:12 | LL | } else if let Some(x) = Some(0) { | ____________^ +LL | | LL | | Some(x + 1) LL | | } else { LL | | None @@ -176,10 +195,11 @@ LL | | }; | |_____^ help: try: `{ Some(0).map(|x| x + 1) }` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option.rs:207:12 + --> tests/ui/manual_map_option.rs:226:12 | LL | } else if let Some(x) = Some(0) { | ____________^ +LL | | LL | | Some(x + 1) LL | | } else { LL | | None diff --git a/tests/ui/manual_map_option_2.fixed b/tests/ui/manual_map_option_2.fixed index 49b9e77b441f..d698cc74ea65 100644 --- a/tests/ui/manual_map_option_2.fixed +++ b/tests/ui/manual_map_option_2.fixed @@ -90,7 +90,6 @@ mod with_type_coercion { None => None, }; - //~v ERROR: manual implementation of `Option::map` let _ = Some(0).map(|_| match f() { Ok(res) => Ok(Box::new(res)), _ => Err(()), @@ -110,7 +109,6 @@ mod with_type_coercion { None => None, }); - //~v ERROR: manual implementation of `Option::map` let _: Option> = Some(0).map(|_| g(x)); } diff --git a/tests/ui/manual_map_option_2.rs b/tests/ui/manual_map_option_2.rs index 962455daf7ba..9f45349d5c89 100644 --- a/tests/ui/manual_map_option_2.rs +++ b/tests/ui/manual_map_option_2.rs @@ -4,6 +4,7 @@ fn main() { // Lint. `y` is declared within the arm, so it isn't captured by the map closure let _ = match Some(0) { + //~^ manual_map Some(x) => Some({ let y = (String::new(), String::new()); (x, y.0) @@ -46,6 +47,7 @@ fn main() { let s = Some(String::new()); // Lint. `s` is captured by reference, so no lifetime issues. let _ = match &s { + //~^ manual_map Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), None => None, }; @@ -61,15 +63,18 @@ fn main() { } unsafe { let _ = match Some(0) { + //~^ manual_map Some(x) => Some(f(x)), None => None, }; } let _ = match Some(0) { + //~^ manual_map Some(x) => unsafe { Some(f(x)) }, None => None, }; let _ = match Some(0) { + //~^ manual_map Some(x) => Some(unsafe { f(x) }), None => None, }; @@ -105,8 +110,8 @@ mod with_type_coercion { None => None, }; - //~v ERROR: manual implementation of `Option::map` let _ = match Some(0) { + //~^ manual_map Some(_) => Some(match f() { Ok(res) => Ok(Box::new(res)), _ => Err(()), @@ -128,8 +133,8 @@ mod with_type_coercion { None => None, }); - //~v ERROR: manual implementation of `Option::map` let _: Option> = match Some(0) { + //~^ manual_map Some(_) => Some(g(x)), None => None, }; diff --git a/tests/ui/manual_map_option_2.stderr b/tests/ui/manual_map_option_2.stderr index db048221db6a..c9e040ce1d0e 100644 --- a/tests/ui/manual_map_option_2.stderr +++ b/tests/ui/manual_map_option_2.stderr @@ -3,10 +3,10 @@ error: manual implementation of `Option::map` | LL | let _ = match Some(0) { | _____________^ +LL | | LL | | Some(x) => Some({ LL | | let y = (String::new(), String::new()); -LL | | (x, y.0) -LL | | }), +... | LL | | None => None, LL | | }; | |_____^ @@ -22,54 +22,58 @@ LL ~ }); | error: manual implementation of `Option::map` - --> tests/ui/manual_map_option_2.rs:48:13 + --> tests/ui/manual_map_option_2.rs:49:13 | LL | let _ = match &s { | _____________^ +LL | | LL | | Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), LL | | None => None, LL | | }; | |_____^ help: try: `s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } })` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option_2.rs:63:17 + --> tests/ui/manual_map_option_2.rs:65:17 | LL | let _ = match Some(0) { | _________________^ +LL | | LL | | Some(x) => Some(f(x)), LL | | None => None, LL | | }; | |_________^ help: try: `Some(0).map(|x| f(x))` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option_2.rs:68:13 + --> tests/ui/manual_map_option_2.rs:71:13 | LL | let _ = match Some(0) { | _____________^ +LL | | LL | | Some(x) => unsafe { Some(f(x)) }, LL | | None => None, LL | | }; | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option_2.rs:72:13 + --> tests/ui/manual_map_option_2.rs:76:13 | LL | let _ = match Some(0) { | _____________^ +LL | | LL | | Some(x) => Some(unsafe { f(x) }), LL | | None => None, LL | | }; | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })` error: manual implementation of `Option::map` - --> tests/ui/manual_map_option_2.rs:109:17 + --> tests/ui/manual_map_option_2.rs:113:17 | LL | let _ = match Some(0) { | _________________^ +LL | | LL | | Some(_) => Some(match f() { LL | | Ok(res) => Ok(Box::new(res)), -LL | | _ => Err(()), -LL | | }), +... | LL | | None => None, LL | | }; | |_________^ @@ -83,10 +87,11 @@ LL ~ }); | error: manual implementation of `Option::map` - --> tests/ui/manual_map_option_2.rs:132:37 + --> tests/ui/manual_map_option_2.rs:136:37 | LL | let _: Option> = match Some(0) { | _____________________________________^ +LL | | LL | | Some(_) => Some(g(x)), LL | | None => None, LL | | }; diff --git a/tests/ui/manual_memcpy/with_loop_counters.rs b/tests/ui/manual_memcpy/with_loop_counters.rs index 786d7e6e2445..eee6c8235daa 100644 --- a/tests/ui/manual_memcpy/with_loop_counters.rs +++ b/tests/ui/manual_memcpy/with_loop_counters.rs @@ -3,57 +3,65 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let mut count = 0; for i in 3..src.len() { - //~^ ERROR: it looks like you're manually copying between slices - //~| NOTE: `-D clippy::manual-memcpy` implied by `-D warnings` + //~^ manual_memcpy + + dst[i] = src[count]; count += 1; } let mut count = 0; for i in 3..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[count] = src[i]; count += 1; } let mut count = 3; for i in 0..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[count] = src[i]; count += 1; } let mut count = 3; for i in 0..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[count]; count += 1; } let mut count = 0; for i in 3..(3 + src.len()) { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[count]; count += 1; } let mut count = 3; for i in 5..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[count - 2]; count += 1; } let mut count = 2; for i in 0..dst.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[count]; count += 1; } let mut count = 5; for i in 3..10 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[count]; count += 1; } @@ -61,7 +69,8 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) let mut count = 3; let mut count2 = 30; for i in 0..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[count] = src[i]; dst2[count2] = src[i]; count += 1; @@ -72,7 +81,8 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) // arithmetic ones let mut count = 0 << 1; for i in 0..1 << 1 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[count] = src[i + 2]; count += 1; } @@ -80,7 +90,8 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) // make sure incrementing expressions without semicolons at the end of loops are handled correctly. let mut count = 0; for i in 3..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[count]; count += 1 } diff --git a/tests/ui/manual_memcpy/with_loop_counters.stderr b/tests/ui/manual_memcpy/with_loop_counters.stderr index 41a991e9688f..fe42842b969b 100644 --- a/tests/ui/manual_memcpy/with_loop_counters.stderr +++ b/tests/ui/manual_memcpy/with_loop_counters.stderr @@ -2,9 +2,7 @@ error: it looks like you're manually copying between slices --> tests/ui/manual_memcpy/with_loop_counters.rs:5:5 | LL | / for i in 3..src.len() { -LL | | -LL | | -LL | | dst[i] = src[count]; +... | LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst[3..src.len()].copy_from_slice(&src[..(src.len() - 3)]);` @@ -13,83 +11,90 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:13:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:14:5 | LL | / for i in 3..src.len() { LL | | +LL | | LL | | dst[count] = src[i]; LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst[..(src.len() - 3)].copy_from_slice(&src[3..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:20:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:22:5 | LL | / for i in 0..src.len() { LL | | +LL | | LL | | dst[count] = src[i]; LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst[3..(src.len() + 3)].copy_from_slice(&src[..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:27:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:30:5 | LL | / for i in 0..src.len() { LL | | +LL | | LL | | dst[i] = src[count]; LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[3..(src.len() + 3)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:34:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:38:5 | LL | / for i in 3..(3 + src.len()) { LL | | +LL | | LL | | dst[i] = src[count]; LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst[3..(3 + src.len())].copy_from_slice(&src[..(3 + src.len() - 3)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:41:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:46:5 | LL | / for i in 5..src.len() { LL | | +LL | | LL | | dst[i] = src[count - 2]; LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst[5..src.len()].copy_from_slice(&src[(3 - 2)..((src.len() - 2) + 3 - 5)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:48:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:54:5 | LL | / for i in 0..dst.len() { LL | | +LL | | LL | | dst[i] = src[count]; LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[2..(dst.len() + 2)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:55:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:62:5 | LL | / for i in 3..10 { LL | | +LL | | LL | | dst[i] = src[count]; LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst[3..10].copy_from_slice(&src[5..(10 + 5 - 3)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:63:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:71:5 | LL | / for i in 0..src.len() { LL | | +LL | | LL | | dst[count] = src[i]; -LL | | dst2[count2] = src[i]; -LL | | count += 1; +... | LL | | count2 += 1; LL | | } | |_____^ @@ -101,20 +106,22 @@ LL + dst2[30..(src.len() + 30)].copy_from_slice(&src[..]); | error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:74:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:83:5 | LL | / for i in 0..1 << 1 { LL | | +LL | | LL | | dst[count] = src[i + 2]; LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst[(0 << 1)..((1 << 1) + (0 << 1))].copy_from_slice(&src[2..((1 << 1) + 2)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:82:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:92:5 | LL | / for i in 3..src.len() { LL | | +LL | | LL | | dst[i] = src[count]; LL | | count += 1 LL | | } diff --git a/tests/ui/manual_memcpy/without_loop_counters.rs b/tests/ui/manual_memcpy/without_loop_counters.rs index 2f8640cd3f50..65254df0aab4 100644 --- a/tests/ui/manual_memcpy/without_loop_counters.rs +++ b/tests/ui/manual_memcpy/without_loop_counters.rs @@ -12,32 +12,37 @@ const LOOP_OFFSET: usize = 5000; pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { // plain manual memcpy for i in 0..src.len() { - //~^ ERROR: it looks like you're manually copying between slices - //~| NOTE: `-D clippy::manual-memcpy` implied by `-D warnings` + //~^ manual_memcpy + + dst[i] = src[i]; } // dst offset memcpy for i in 0..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i + 10] = src[i]; } // src offset memcpy for i in 0..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i + 10]; } // src offset memcpy for i in 11..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i - 10]; } // overwrite entire dst for i in 0..dst.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i]; } @@ -51,7 +56,8 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { // multiple copies - suggest two memcpy statements for i in 10..256 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i - 5]; dst2[i + 500] = src[i] } @@ -64,7 +70,8 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let some_var = 5; // Offset in variable for i in 10..LOOP_OFFSET { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i + LOOP_OFFSET] = src[i - some_var]; } @@ -78,7 +85,8 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { // make sure vectors are supported for i in 0..src_vec.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst_vec[i] = src_vec[i]; } @@ -108,24 +116,28 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let from = 1; for i in from..from + src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i - from]; } for i in from..from + 3 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i - from]; } #[allow(clippy::identity_op)] for i in 0..5 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i - 0] = src[i]; } #[allow(clippy::reversed_empty_ranges)] for i in 0..0 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i]; } @@ -149,19 +161,22 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let src = [0, 1, 2, 3, 4]; let mut dst = [0; 4]; for i in 0..4 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i]; } let mut dst = [0; 6]; for i in 0..5 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i]; } let mut dst = [0; 5]; for i in 0..5 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i]; } @@ -208,13 +223,15 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let src = [[0; 5]; 5]; let mut dst = [0; 5]; for i in 0..5 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[0][i]; } let src = [[[0; 5]; 5]; 5]; for i in 0..5 { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[0][1][i]; } } @@ -222,7 +239,8 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { #[warn(clippy::needless_range_loop, clippy::manual_memcpy)] pub fn manual_clone(src: &[String], dst: &mut [String]) { for i in 0..src.len() { - //~^ ERROR: it looks like you're manually copying between slices + //~^ manual_memcpy + dst[i] = src[i].clone(); } } diff --git a/tests/ui/manual_memcpy/without_loop_counters.stderr b/tests/ui/manual_memcpy/without_loop_counters.stderr index c881e3fac769..2599bc02c3ca 100644 --- a/tests/ui/manual_memcpy/without_loop_counters.stderr +++ b/tests/ui/manual_memcpy/without_loop_counters.stderr @@ -2,9 +2,7 @@ error: it looks like you're manually copying between slices --> tests/ui/manual_memcpy/without_loop_counters.rs:14:5 | LL | / for i in 0..src.len() { -LL | | -LL | | -LL | | dst[i] = src[i]; +... | LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[..]);` | @@ -12,46 +10,51 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:21:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:22:5 | LL | / for i in 0..src.len() { LL | | +LL | | LL | | dst[i + 10] = src[i]; LL | | } | |_____^ help: try replacing the loop by: `dst[10..(src.len() + 10)].copy_from_slice(&src[..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:27:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:29:5 | LL | / for i in 0..src.len() { LL | | +LL | | LL | | dst[i] = src[i + 10]; LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:33:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:36:5 | LL | / for i in 11..src.len() { LL | | +LL | | LL | | dst[i] = src[i - 10]; LL | | } | |_____^ help: try replacing the loop by: `dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:39:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:43:5 | LL | / for i in 0..dst.len() { LL | | +LL | | LL | | dst[i] = src[i]; LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..dst.len()]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:53:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:58:5 | LL | / for i in 10..256 { LL | | +LL | | LL | | dst[i] = src[i - 5]; LL | | dst2[i + 500] = src[i] LL | | } @@ -64,109 +67,121 @@ LL + dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]); | error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:66:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:72:5 | LL | / for i in 10..LOOP_OFFSET { LL | | +LL | | LL | | dst[i + LOOP_OFFSET] = src[i - some_var]; LL | | } | |_____^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:80:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:87:5 | LL | / for i in 0..src_vec.len() { LL | | +LL | | LL | | dst_vec[i] = src_vec[i]; LL | | } | |_____^ help: try replacing the loop by: `dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:110:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:118:5 | LL | / for i in from..from + src.len() { LL | | +LL | | LL | | dst[i] = src[i - from]; LL | | } | |_____^ help: try replacing the loop by: `dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:115:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:124:5 | LL | / for i in from..from + 3 { LL | | +LL | | LL | | dst[i] = src[i - from]; LL | | } | |_____^ help: try replacing the loop by: `dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:121:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:131:5 | LL | / for i in 0..5 { LL | | +LL | | LL | | dst[i - 0] = src[i]; LL | | } | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:127:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:138:5 | LL | / for i in 0..0 { LL | | +LL | | LL | | dst[i] = src[i]; LL | | } | |_____^ help: try replacing the loop by: `dst[..0].copy_from_slice(&src[..0]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:151:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:163:5 | LL | / for i in 0..4 { LL | | +LL | | LL | | dst[i] = src[i]; LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..4]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:157:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:170:5 | LL | / for i in 0..5 { LL | | +LL | | LL | | dst[i] = src[i]; LL | | } | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:163:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:177:5 | LL | / for i in 0..5 { LL | | +LL | | LL | | dst[i] = src[i]; LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:210:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:225:5 | LL | / for i in 0..5 { LL | | +LL | | LL | | dst[i] = src[0][i]; LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:216:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:232:5 | LL | / for i in 0..5 { LL | | +LL | | LL | | dst[i] = src[0][1][i]; LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0][1]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:224:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:241:5 | LL | / for i in 0..src.len() { LL | | +LL | | LL | | dst[i] = src[i].clone(); LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..]);` diff --git a/tests/ui/manual_next_back.fixed b/tests/ui/manual_next_back.fixed index 75828f355d90..153fbc6fd071 100644 --- a/tests/ui/manual_next_back.fixed +++ b/tests/ui/manual_next_back.fixed @@ -30,5 +30,7 @@ fn main() { // should lint let _ = (0..10).next_back().unwrap(); + //~^ manual_next_back let _ = "something".bytes().next_back(); + //~^ manual_next_back } diff --git a/tests/ui/manual_next_back.rs b/tests/ui/manual_next_back.rs index b980e90e1144..ca71d6a24773 100644 --- a/tests/ui/manual_next_back.rs +++ b/tests/ui/manual_next_back.rs @@ -30,5 +30,7 @@ fn main() { // should lint let _ = (0..10).rev().next().unwrap(); + //~^ manual_next_back let _ = "something".bytes().rev().next(); + //~^ manual_next_back } diff --git a/tests/ui/manual_next_back.stderr b/tests/ui/manual_next_back.stderr index c7e1ceca437c..4ac7b0d21244 100644 --- a/tests/ui/manual_next_back.stderr +++ b/tests/ui/manual_next_back.stderr @@ -8,7 +8,7 @@ LL | let _ = (0..10).rev().next().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::manual_next_back)]` error: manual backwards iteration - --> tests/ui/manual_next_back.rs:33:32 + --> tests/ui/manual_next_back.rs:34:32 | LL | let _ = "something".bytes().rev().next(); | ^^^^^^^^^^^^^ help: use: `.next_back()` diff --git a/tests/ui/manual_non_exhaustive_enum.rs b/tests/ui/manual_non_exhaustive_enum.rs index ffe2bb924673..aaa5b549e734 100644 --- a/tests/ui/manual_non_exhaustive_enum.rs +++ b/tests/ui/manual_non_exhaustive_enum.rs @@ -2,7 +2,7 @@ #![allow(unused)] //@no-rustfix pub enum E { - //~^ manual_non_exhaustive +//~^ manual_non_exhaustive A, B, #[doc(hidden)] @@ -27,6 +27,7 @@ pub enum NoDocHidden { // name of variant with doc hidden does not start with underscore pub enum NoUnderscore { +//~^ manual_non_exhaustive A, B, #[doc(hidden)] diff --git a/tests/ui/manual_non_exhaustive_enum.stderr b/tests/ui/manual_non_exhaustive_enum.stderr index 0a9ac157f850..0f91f24b4a34 100644 --- a/tests/ui/manual_non_exhaustive_enum.stderr +++ b/tests/ui/manual_non_exhaustive_enum.stderr @@ -27,6 +27,7 @@ error: this seems like a manual implementation of the non-exhaustive pattern --> tests/ui/manual_non_exhaustive_enum.rs:29:1 | LL | / pub enum NoUnderscore { +LL | | LL | | A, LL | | B, LL | | #[doc(hidden)] @@ -35,7 +36,7 @@ LL | | } | |_^ | help: remove this variant - --> tests/ui/manual_non_exhaustive_enum.rs:33:5 + --> tests/ui/manual_non_exhaustive_enum.rs:34:5 | LL | C, | ^ diff --git a/tests/ui/manual_ok_err.rs b/tests/ui/manual_ok_err.rs index 03ad773f47cf..976311604a38 100644 --- a/tests/ui/manual_ok_err.rs +++ b/tests/ui/manual_ok_err.rs @@ -6,38 +6,44 @@ fn funcall() -> Result { fn main() { let _ = match funcall() { - //~^ manual_ok_err + //~^ manual_ok_err + Ok(v) => Some(v), Err(_) => None, }; let _ = match funcall() { - //~^ manual_ok_err + //~^ manual_ok_err + Ok(v) => Some(v), _v => None, }; let _ = match funcall() { - //~^ manual_ok_err + //~^ manual_ok_err + Err(v) => Some(v), Ok(_) => None, }; let _ = match funcall() { - //~^ manual_ok_err + //~^ manual_ok_err + Err(v) => Some(v), _v => None, }; let _ = if let Ok(v) = funcall() { - //~^ manual_ok_err + //~^ manual_ok_err + Some(v) } else { None }; let _ = if let Err(v) = funcall() { - //~^ manual_ok_err + //~^ manual_ok_err + Some(v) } else { None @@ -45,7 +51,8 @@ fn main() { #[allow(clippy::redundant_pattern)] let _ = match funcall() { - //~^ manual_ok_err + //~^ manual_ok_err + Ok(v) => Some(v), _v @ _ => None, }; @@ -62,7 +69,8 @@ fn main() { // Suggestion should be properly parenthesized let _ = match -S { - //~^ manual_ok_err + //~^ manual_ok_err + Ok(v) => Some(v), _ => None, }; diff --git a/tests/ui/manual_ok_err.stderr b/tests/ui/manual_ok_err.stderr index d0d5e2c81e96..ea430dd3eb45 100644 --- a/tests/ui/manual_ok_err.stderr +++ b/tests/ui/manual_ok_err.stderr @@ -4,6 +4,7 @@ error: manual implementation of `ok` LL | let _ = match funcall() { | _____________^ LL | | +LL | | LL | | Ok(v) => Some(v), LL | | Err(_) => None, LL | | }; @@ -13,44 +14,48 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_ok_err)]` error: manual implementation of `ok` - --> tests/ui/manual_ok_err.rs:14:13 + --> tests/ui/manual_ok_err.rs:15:13 | LL | let _ = match funcall() { | _____________^ LL | | +LL | | LL | | Ok(v) => Some(v), LL | | _v => None, LL | | }; | |_____^ help: replace with: `funcall().ok()` error: manual implementation of `err` - --> tests/ui/manual_ok_err.rs:20:13 + --> tests/ui/manual_ok_err.rs:22:13 | LL | let _ = match funcall() { | _____________^ LL | | +LL | | LL | | Err(v) => Some(v), LL | | Ok(_) => None, LL | | }; | |_____^ help: replace with: `funcall().err()` error: manual implementation of `err` - --> tests/ui/manual_ok_err.rs:26:13 + --> tests/ui/manual_ok_err.rs:29:13 | LL | let _ = match funcall() { | _____________^ LL | | +LL | | LL | | Err(v) => Some(v), LL | | _v => None, LL | | }; | |_____^ help: replace with: `funcall().err()` error: manual implementation of `ok` - --> tests/ui/manual_ok_err.rs:32:13 + --> tests/ui/manual_ok_err.rs:36:13 | LL | let _ = if let Ok(v) = funcall() { | _____________^ LL | | +LL | | LL | | Some(v) LL | | } else { LL | | None @@ -58,11 +63,12 @@ LL | | }; | |_____^ help: replace with: `funcall().ok()` error: manual implementation of `err` - --> tests/ui/manual_ok_err.rs:39:13 + --> tests/ui/manual_ok_err.rs:44:13 | LL | let _ = if let Err(v) = funcall() { | _____________^ LL | | +LL | | LL | | Some(v) LL | | } else { LL | | None @@ -70,22 +76,24 @@ LL | | }; | |_____^ help: replace with: `funcall().err()` error: manual implementation of `ok` - --> tests/ui/manual_ok_err.rs:47:13 + --> tests/ui/manual_ok_err.rs:53:13 | LL | let _ = match funcall() { | _____________^ LL | | +LL | | LL | | Ok(v) => Some(v), LL | | _v @ _ => None, LL | | }; | |_____^ help: replace with: `funcall().ok()` error: manual implementation of `ok` - --> tests/ui/manual_ok_err.rs:64:13 + --> tests/ui/manual_ok_err.rs:71:13 | LL | let _ = match -S { | _____________^ LL | | +LL | | LL | | Ok(v) => Some(v), LL | | _ => None, LL | | }; diff --git a/tests/ui/manual_ok_or.fixed b/tests/ui/manual_ok_or.fixed index cc53cb416a22..f326822149cd 100644 --- a/tests/ui/manual_ok_or.fixed +++ b/tests/ui/manual_ok_or.fixed @@ -9,12 +9,15 @@ fn main() { // basic case let foo: Option = None; foo.ok_or("error"); + //~^ manual_ok_or // eta expansion case foo.ok_or("error"); + //~^ manual_ok_or // turbo fish syntax None::.ok_or("error"); + //~^ manual_ok_or // multiline case #[rustfmt::skip] diff --git a/tests/ui/manual_ok_or.rs b/tests/ui/manual_ok_or.rs index 39c61a1e490f..7d065eda0ea1 100644 --- a/tests/ui/manual_ok_or.rs +++ b/tests/ui/manual_ok_or.rs @@ -9,16 +9,20 @@ fn main() { // basic case let foo: Option = None; foo.map_or(Err("error"), |v| Ok(v)); + //~^ manual_ok_or // eta expansion case foo.map_or(Err("error"), Ok); + //~^ manual_ok_or // turbo fish syntax None::.map_or(Err("error"), |v| Ok(v)); + //~^ manual_ok_or // multiline case #[rustfmt::skip] foo.map_or(Err::( + //~^ manual_ok_or &format!( "{}{}{}{}{}{}{}", "Alice", "Bob", "Sarah", "Marc", "Sandra", "Eric", "Jenifer") diff --git a/tests/ui/manual_ok_or.stderr b/tests/ui/manual_ok_or.stderr index 4722f53580f1..e8176f4c31fa 100644 --- a/tests/ui/manual_ok_or.stderr +++ b/tests/ui/manual_ok_or.stderr @@ -8,25 +8,25 @@ LL | foo.map_or(Err("error"), |v| Ok(v)); = help: to override `-D warnings` add `#[allow(clippy::manual_ok_or)]` error: this pattern reimplements `Option::ok_or` - --> tests/ui/manual_ok_or.rs:14:5 + --> tests/ui/manual_ok_or.rs:15:5 | LL | foo.map_or(Err("error"), Ok); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or("error")` error: this pattern reimplements `Option::ok_or` - --> tests/ui/manual_ok_or.rs:17:5 + --> tests/ui/manual_ok_or.rs:19:5 | LL | None::.map_or(Err("error"), |v| Ok(v)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `None::.ok_or("error")` error: this pattern reimplements `Option::ok_or` - --> tests/ui/manual_ok_or.rs:21:5 + --> tests/ui/manual_ok_or.rs:24:5 | LL | / foo.map_or(Err::( +LL | | LL | | &format!( LL | | "{}{}{}{}{}{}{}", -LL | | "Alice", "Bob", "Sarah", "Marc", "Sandra", "Eric", "Jenifer") -LL | | ), +... | LL | | |v| Ok(v), LL | | ); | |_____^ diff --git a/tests/ui/manual_option_as_slice.fixed b/tests/ui/manual_option_as_slice.fixed index 48337d7654de..17a412017a43 100644 --- a/tests/ui/manual_option_as_slice.fixed +++ b/tests/ui/manual_option_as_slice.fixed @@ -9,19 +9,24 @@ fn check(x: Option) { _ = x.as_slice(); //~^ manual_option_as_slice - _ = x.as_slice(); - //~^ manual_option_as_slice _ = x.as_slice(); //~^ manual_option_as_slice + _ = x.as_slice(); //~^ manual_option_as_slice + + _ = x.as_slice(); + //~^ manual_option_as_slice + + { use std::slice::from_ref; _ = x.as_slice(); //~^ manual_option_as_slice + } // possible false positives diff --git a/tests/ui/manual_option_as_slice.rs b/tests/ui/manual_option_as_slice.rs index 561a8b534014..71166399cbea 100644 --- a/tests/ui/manual_option_as_slice.rs +++ b/tests/ui/manual_option_as_slice.rs @@ -3,13 +3,15 @@ fn check(x: Option) { _ = match x.as_ref() { - //~^ manual_option_as_slice + //~^ manual_option_as_slice + Some(f) => std::slice::from_ref(f), None => &[], }; _ = if let Some(f) = x.as_ref() { - //~^ manual_option_as_slice + //~^ manual_option_as_slice + std::slice::from_ref(f) } else { &[] @@ -18,19 +20,24 @@ fn check(x: Option) { _ = x.as_ref().map_or(&[][..], std::slice::from_ref); //~^ manual_option_as_slice + _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref); //~^ manual_option_as_slice + _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default(); //~^ manual_option_as_slice + _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref); //~^ manual_option_as_slice + { use std::slice::from_ref; _ = x.as_ref().map_or_else(<&[_]>::default, from_ref); //~^ manual_option_as_slice + } // possible false positives diff --git a/tests/ui/manual_option_as_slice.stderr b/tests/ui/manual_option_as_slice.stderr index 569269d3e2b7..3a07c6a02dae 100644 --- a/tests/ui/manual_option_as_slice.stderr +++ b/tests/ui/manual_option_as_slice.stderr @@ -4,6 +4,7 @@ error: use `Option::as_slice` LL | _ = match x.as_ref() { | _________^ LL | | +LL | | LL | | Some(f) => std::slice::from_ref(f), LL | | None => &[], LL | | }; @@ -13,11 +14,12 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_option_as_slice)]` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:11:9 + --> tests/ui/manual_option_as_slice.rs:12:9 | LL | _ = if let Some(f) = x.as_ref() { | _________^ LL | | +LL | | LL | | std::slice::from_ref(f) LL | | } else { LL | | &[] @@ -25,31 +27,31 @@ LL | | }; | |_____^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:18:9 + --> tests/ui/manual_option_as_slice.rs:20:9 | LL | _ = x.as_ref().map_or(&[][..], std::slice::from_ref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:21:9 + --> tests/ui/manual_option_as_slice.rs:24:9 | LL | _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:24:9 + --> tests/ui/manual_option_as_slice.rs:28:9 | LL | _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:27:9 + --> tests/ui/manual_option_as_slice.rs:32:9 | LL | _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:32:13 + --> tests/ui/manual_option_as_slice.rs:38:13 | LL | _ = x.as_ref().map_or_else(<&[_]>::default, from_ref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` diff --git a/tests/ui/manual_pattern_char_comparison.fixed b/tests/ui/manual_pattern_char_comparison.fixed index 03e621d95ba1..b03e83e6b99d 100644 --- a/tests/ui/manual_pattern_char_comparison.fixed +++ b/tests/ui/manual_pattern_char_comparison.fixed @@ -9,16 +9,25 @@ impl NotStr { fn main() { let sentence = "Hello, world!"; sentence.trim_end_matches(['.', ',', '!', '?']); + //~^ manual_pattern_char_comparison sentence.split(['\n', 'X']); + //~^ manual_pattern_char_comparison sentence.split(['\n', 'X']); + //~^ manual_pattern_char_comparison sentence.splitn(3, 'X'); + //~^ manual_pattern_char_comparison sentence.splitn(3, |c: char| c.is_whitespace() || c == 'X'); let char_compare = 'X'; sentence.splitn(3, char_compare); + //~^ manual_pattern_char_comparison sentence.split(['\n', 'X', 'Y']); + //~^ manual_pattern_char_comparison sentence.splitn(3, 'X'); + //~^ manual_pattern_char_comparison sentence.splitn(3, ['X', 'W']); + //~^ manual_pattern_char_comparison sentence.find('🎈'); + //~^ manual_pattern_char_comparison let not_str = NotStr; not_str.find(|c: char| c == 'X'); @@ -58,4 +67,5 @@ fn msrv_1_57() { fn msrv_1_58() { let sentence = "Hello, world!"; sentence.trim_end_matches(['.', ',', '!', '?']); + //~^ manual_pattern_char_comparison } diff --git a/tests/ui/manual_pattern_char_comparison.rs b/tests/ui/manual_pattern_char_comparison.rs index 43e883cd325a..451480df4225 100644 --- a/tests/ui/manual_pattern_char_comparison.rs +++ b/tests/ui/manual_pattern_char_comparison.rs @@ -9,16 +9,25 @@ impl NotStr { fn main() { let sentence = "Hello, world!"; sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?'); + //~^ manual_pattern_char_comparison sentence.split(|c: char| c == '\n' || c == 'X'); + //~^ manual_pattern_char_comparison sentence.split(|c| c == '\n' || c == 'X'); + //~^ manual_pattern_char_comparison sentence.splitn(3, |c: char| c == 'X'); + //~^ manual_pattern_char_comparison sentence.splitn(3, |c: char| c.is_whitespace() || c == 'X'); let char_compare = 'X'; sentence.splitn(3, |c: char| c == char_compare); + //~^ manual_pattern_char_comparison sentence.split(|c: char| matches!(c, '\n' | 'X' | 'Y')); + //~^ manual_pattern_char_comparison sentence.splitn(3, |c: char| matches!(c, 'X')); + //~^ manual_pattern_char_comparison sentence.splitn(3, |c: char| matches!(c, 'X' | 'W')); + //~^ manual_pattern_char_comparison sentence.find(|c| c == '🎈'); + //~^ manual_pattern_char_comparison let not_str = NotStr; not_str.find(|c: char| c == 'X'); @@ -58,4 +67,5 @@ fn msrv_1_57() { fn msrv_1_58() { let sentence = "Hello, world!"; sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?'); + //~^ manual_pattern_char_comparison } diff --git a/tests/ui/manual_pattern_char_comparison.stderr b/tests/ui/manual_pattern_char_comparison.stderr index f185d7c8f676..d4fc3faa066f 100644 --- a/tests/ui/manual_pattern_char_comparison.stderr +++ b/tests/ui/manual_pattern_char_comparison.stderr @@ -8,55 +8,55 @@ LL | sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || = help: to override `-D warnings` add `#[allow(clippy::manual_pattern_char_comparison)]` error: this manual char comparison can be written more succinctly - --> tests/ui/manual_pattern_char_comparison.rs:12:20 + --> tests/ui/manual_pattern_char_comparison.rs:13:20 | LL | sentence.split(|c: char| c == '\n' || c == 'X'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\n', 'X']` error: this manual char comparison can be written more succinctly - --> tests/ui/manual_pattern_char_comparison.rs:13:20 + --> tests/ui/manual_pattern_char_comparison.rs:15:20 | LL | sentence.split(|c| c == '\n' || c == 'X'); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\n', 'X']` error: this manual char comparison can be written more succinctly - --> tests/ui/manual_pattern_char_comparison.rs:14:24 + --> tests/ui/manual_pattern_char_comparison.rs:17:24 | LL | sentence.splitn(3, |c: char| c == 'X'); | ^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `'X'` error: this manual char comparison can be written more succinctly - --> tests/ui/manual_pattern_char_comparison.rs:17:24 + --> tests/ui/manual_pattern_char_comparison.rs:21:24 | LL | sentence.splitn(3, |c: char| c == char_compare); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `char_compare` error: this manual char comparison can be written more succinctly - --> tests/ui/manual_pattern_char_comparison.rs:18:20 + --> tests/ui/manual_pattern_char_comparison.rs:23:20 | LL | sentence.split(|c: char| matches!(c, '\n' | 'X' | 'Y')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\n', 'X', 'Y']` error: this manual char comparison can be written more succinctly - --> tests/ui/manual_pattern_char_comparison.rs:19:24 + --> tests/ui/manual_pattern_char_comparison.rs:25:24 | LL | sentence.splitn(3, |c: char| matches!(c, 'X')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `'X'` error: this manual char comparison can be written more succinctly - --> tests/ui/manual_pattern_char_comparison.rs:20:24 + --> tests/ui/manual_pattern_char_comparison.rs:27:24 | LL | sentence.splitn(3, |c: char| matches!(c, 'X' | 'W')); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['X', 'W']` error: this manual char comparison can be written more succinctly - --> tests/ui/manual_pattern_char_comparison.rs:21:19 + --> tests/ui/manual_pattern_char_comparison.rs:29:19 | LL | sentence.find(|c| c == '🎈'); | ^^^^^^^^^^^^^ help: consider using a `char`: `'🎈'` error: this manual char comparison can be written more succinctly - --> tests/ui/manual_pattern_char_comparison.rs:60:31 + --> tests/ui/manual_pattern_char_comparison.rs:69:31 | LL | sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['.', ',', '!', '?']` diff --git a/tests/ui/manual_range_patterns.fixed b/tests/ui/manual_range_patterns.fixed index 60467bf9e884..c05e1fb27b03 100644 --- a/tests/ui/manual_range_patterns.fixed +++ b/tests/ui/manual_range_patterns.fixed @@ -6,7 +6,9 @@ fn main() { let f = 6; let _ = matches!(f, 1..=10); + //~^ manual_range_patterns let _ = matches!(f, 1..=10); + //~^ manual_range_patterns let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 8 | 10); // 7 is missing let _ = matches!(f, | 4); let _ = matches!(f, 4 | 5); @@ -14,34 +16,51 @@ fn main() { let _ = matches!(f, 0 | 2147483647); let _ = matches!(f, -2147483647 | 2147483647); let _ = matches!(f, 1..=4); + //~^ manual_range_patterns let _ = matches!(f, 1..4); + //~^ manual_range_patterns let _ = matches!(f, 1..=48324729); + //~^ manual_range_patterns let _ = matches!(f, 0..=48324730); + //~^ manual_range_patterns let _ = matches!(f, 0..=3); + //~^ manual_range_patterns #[allow(clippy::match_like_matches_macro)] let _ = match f { 1..=10 => true, + //~^ manual_range_patterns _ => false, }; let _ = matches!(f, -5..=3); + //~^ manual_range_patterns let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1); // 2 is missing let _ = matches!(f, -1_000_001..=1_000_001); + //~^ manual_range_patterns let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002); matches!(f, 0x00..=0x03); + //~^ manual_range_patterns matches!(f, 0x00..=0x07); + //~^ manual_range_patterns matches!(f, -0x09..=0x00); + //~^ manual_range_patterns matches!(f, 0..=5); + //~^ manual_range_patterns matches!(f, 0..5); + //~^ manual_range_patterns matches!(f, 0..10); + //~^ manual_range_patterns matches!(f, 0..=10); + //~^ manual_range_patterns matches!(f, 0..=10); + //~^ manual_range_patterns macro_rules! mac { ($e:expr) => { matches!($e, 1..=10) + //~^ manual_range_patterns }; } mac!(f); diff --git a/tests/ui/manual_range_patterns.rs b/tests/ui/manual_range_patterns.rs index 9cd803334499..e5c403dc5f2e 100644 --- a/tests/ui/manual_range_patterns.rs +++ b/tests/ui/manual_range_patterns.rs @@ -6,7 +6,9 @@ fn main() { let f = 6; let _ = matches!(f, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10); + //~^ manual_range_patterns let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 7 | 8 | 10); + //~^ manual_range_patterns let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 8 | 10); // 7 is missing let _ = matches!(f, | 4); let _ = matches!(f, 4 | 5); @@ -14,34 +16,51 @@ fn main() { let _ = matches!(f, 0 | 2147483647); let _ = matches!(f, -2147483647 | 2147483647); let _ = matches!(f, 1 | (2..=4)); + //~^ manual_range_patterns let _ = matches!(f, 1 | (2..4)); + //~^ manual_range_patterns let _ = matches!(f, (1..=10) | (2..=13) | (14..=48324728) | 48324729); + //~^ manual_range_patterns let _ = matches!(f, 0 | (1..=10) | 48324730 | (2..=13) | (14..=48324728) | 48324729); + //~^ manual_range_patterns let _ = matches!(f, 0..=1 | 0..=2 | 0..=3); + //~^ manual_range_patterns #[allow(clippy::match_like_matches_macro)] let _ = match f { 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true, + //~^ manual_range_patterns _ => false, }; let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2); + //~^ manual_range_patterns let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1); // 2 is missing let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001); + //~^ manual_range_patterns let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002); matches!(f, 0x00 | 0x01 | 0x02 | 0x03); + //~^ manual_range_patterns matches!(f, 0x00..=0x05 | 0x06 | 0x07); + //~^ manual_range_patterns matches!(f, -0x09 | -0x08 | -0x07..=0x00); + //~^ manual_range_patterns matches!(f, 0..5 | 5); + //~^ manual_range_patterns matches!(f, 0 | 1..5); + //~^ manual_range_patterns matches!(f, 0..=5 | 6..10); + //~^ manual_range_patterns matches!(f, 0..5 | 5..=10); + //~^ manual_range_patterns matches!(f, 5..=10 | 0..5); + //~^ manual_range_patterns macro_rules! mac { ($e:expr) => { matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10) + //~^ manual_range_patterns }; } mac!(f); diff --git a/tests/ui/manual_range_patterns.stderr b/tests/ui/manual_range_patterns.stderr index 7c19fdd475f1..e494e7234d68 100644 --- a/tests/ui/manual_range_patterns.stderr +++ b/tests/ui/manual_range_patterns.stderr @@ -8,109 +8,109 @@ LL | let _ = matches!(f, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10); = help: to override `-D warnings` add `#[allow(clippy::manual_range_patterns)]` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:9:25 + --> tests/ui/manual_range_patterns.rs:10:25 | LL | let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 7 | 8 | 10); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:16:25 + --> tests/ui/manual_range_patterns.rs:18:25 | LL | let _ = matches!(f, 1 | (2..=4)); | ^^^^^^^^^^^ help: try: `1..=4` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:17:25 + --> tests/ui/manual_range_patterns.rs:20:25 | LL | let _ = matches!(f, 1 | (2..4)); | ^^^^^^^^^^ help: try: `1..4` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:18:25 + --> tests/ui/manual_range_patterns.rs:22:25 | LL | let _ = matches!(f, (1..=10) | (2..=13) | (14..=48324728) | 48324729); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=48324729` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:19:25 + --> tests/ui/manual_range_patterns.rs:24:25 | LL | let _ = matches!(f, 0 | (1..=10) | 48324730 | (2..=13) | (14..=48324728) | 48324729); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=48324730` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:20:25 + --> tests/ui/manual_range_patterns.rs:26:25 | LL | let _ = matches!(f, 0..=1 | 0..=2 | 0..=3); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=3` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:23:9 + --> tests/ui/manual_range_patterns.rs:30:9 | LL | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:26:25 + --> tests/ui/manual_range_patterns.rs:34:25 | LL | let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-5..=3` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:28:25 + --> tests/ui/manual_range_patterns.rs:37:25 | LL | let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-1_000_001..=1_000_001` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:31:17 + --> tests/ui/manual_range_patterns.rs:41:17 | LL | matches!(f, 0x00 | 0x01 | 0x02 | 0x03); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0x00..=0x03` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:32:17 + --> tests/ui/manual_range_patterns.rs:43:17 | LL | matches!(f, 0x00..=0x05 | 0x06 | 0x07); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0x00..=0x07` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:33:17 + --> tests/ui/manual_range_patterns.rs:45:17 | LL | matches!(f, -0x09 | -0x08 | -0x07..=0x00); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-0x09..=0x00` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:35:17 + --> tests/ui/manual_range_patterns.rs:48:17 | LL | matches!(f, 0..5 | 5); | ^^^^^^^^ help: try: `0..=5` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:36:17 + --> tests/ui/manual_range_patterns.rs:50:17 | LL | matches!(f, 0 | 1..5); | ^^^^^^^^ help: try: `0..5` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:38:17 + --> tests/ui/manual_range_patterns.rs:53:17 | LL | matches!(f, 0..=5 | 6..10); | ^^^^^^^^^^^^^ help: try: `0..10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:39:17 + --> tests/ui/manual_range_patterns.rs:55:17 | LL | matches!(f, 0..5 | 5..=10); | ^^^^^^^^^^^^^ help: try: `0..=10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:40:17 + --> tests/ui/manual_range_patterns.rs:57:17 | LL | matches!(f, 5..=10 | 0..5); | ^^^^^^^^^^^^^ help: try: `0..=10` error: this OR pattern can be rewritten using a range - --> tests/ui/manual_range_patterns.rs:44:26 + --> tests/ui/manual_range_patterns.rs:62:26 | LL | matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` diff --git a/tests/ui/manual_rem_euclid.fixed b/tests/ui/manual_rem_euclid.fixed index 2d50865586d1..e64654bb6866 100644 --- a/tests/ui/manual_rem_euclid.fixed +++ b/tests/ui/manual_rem_euclid.fixed @@ -11,10 +11,15 @@ fn main() { let value: i32 = 5; let _: i32 = value.rem_euclid(4); + //~^ manual_rem_euclid let _: i32 = value.rem_euclid(4); + //~^ manual_rem_euclid let _: i32 = value.rem_euclid(4); + //~^ manual_rem_euclid let _: i32 = value.rem_euclid(4); + //~^ manual_rem_euclid let _: i32 = 1 + value.rem_euclid(4); + //~^ manual_rem_euclid let _: i32 = (3 + value % 4) % 4; let _: i32 = (-4 + value % -4) % -4; @@ -35,6 +40,7 @@ fn main() { inline!( let value: i32 = 5; let _: i32 = value.rem_euclid(4); + //~^ manual_rem_euclid ); // Do not lint in external macros @@ -47,11 +53,13 @@ fn main() { // Should lint for params too pub fn rem_euclid_4(num: i32) -> i32 { num.rem_euclid(4) + //~^ manual_rem_euclid } // Constant version came later, should still lint pub const fn const_rem_euclid_4(num: i32) -> i32 { num.rem_euclid(4) + //~^ manual_rem_euclid } #[clippy::msrv = "1.37"] @@ -64,6 +72,7 @@ pub fn msrv_1_37() { pub fn msrv_1_38() { let x: i32 = 10; let _: i32 = x.rem_euclid(4); + //~^ manual_rem_euclid } // For const fns: @@ -77,4 +86,5 @@ pub const fn msrv_1_51() { pub const fn msrv_1_52() { let x: i32 = 10; let _: i32 = x.rem_euclid(4); + //~^ manual_rem_euclid } diff --git a/tests/ui/manual_rem_euclid.rs b/tests/ui/manual_rem_euclid.rs index e405a2db4765..4561a7ee9ea4 100644 --- a/tests/ui/manual_rem_euclid.rs +++ b/tests/ui/manual_rem_euclid.rs @@ -11,10 +11,15 @@ fn main() { let value: i32 = 5; let _: i32 = ((value % 4) + 4) % 4; + //~^ manual_rem_euclid let _: i32 = (4 + (value % 4)) % 4; + //~^ manual_rem_euclid let _: i32 = (value % 4 + 4) % 4; + //~^ manual_rem_euclid let _: i32 = (4 + value % 4) % 4; + //~^ manual_rem_euclid let _: i32 = 1 + (4 + value % 4) % 4; + //~^ manual_rem_euclid let _: i32 = (3 + value % 4) % 4; let _: i32 = (-4 + value % -4) % -4; @@ -35,6 +40,7 @@ fn main() { inline!( let value: i32 = 5; let _: i32 = ((value % 4) + 4) % 4; + //~^ manual_rem_euclid ); // Do not lint in external macros @@ -47,11 +53,13 @@ fn main() { // Should lint for params too pub fn rem_euclid_4(num: i32) -> i32 { ((num % 4) + 4) % 4 + //~^ manual_rem_euclid } // Constant version came later, should still lint pub const fn const_rem_euclid_4(num: i32) -> i32 { ((num % 4) + 4) % 4 + //~^ manual_rem_euclid } #[clippy::msrv = "1.37"] @@ -64,6 +72,7 @@ pub fn msrv_1_37() { pub fn msrv_1_38() { let x: i32 = 10; let _: i32 = ((x % 4) + 4) % 4; + //~^ manual_rem_euclid } // For const fns: @@ -77,4 +86,5 @@ pub const fn msrv_1_51() { pub const fn msrv_1_52() { let x: i32 = 10; let _: i32 = ((x % 4) + 4) % 4; + //~^ manual_rem_euclid } diff --git a/tests/ui/manual_rem_euclid.stderr b/tests/ui/manual_rem_euclid.stderr index a19fdadb1c9b..386815b23b68 100644 --- a/tests/ui/manual_rem_euclid.stderr +++ b/tests/ui/manual_rem_euclid.stderr @@ -8,31 +8,31 @@ LL | let _: i32 = ((value % 4) + 4) % 4; = help: to override `-D warnings` add `#[allow(clippy::manual_rem_euclid)]` error: manual `rem_euclid` implementation - --> tests/ui/manual_rem_euclid.rs:14:18 + --> tests/ui/manual_rem_euclid.rs:15:18 | LL | let _: i32 = (4 + (value % 4)) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> tests/ui/manual_rem_euclid.rs:15:18 + --> tests/ui/manual_rem_euclid.rs:17:18 | LL | let _: i32 = (value % 4 + 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> tests/ui/manual_rem_euclid.rs:16:18 + --> tests/ui/manual_rem_euclid.rs:19:18 | LL | let _: i32 = (4 + value % 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> tests/ui/manual_rem_euclid.rs:17:22 + --> tests/ui/manual_rem_euclid.rs:21:22 | LL | let _: i32 = 1 + (4 + value % 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> tests/ui/manual_rem_euclid.rs:37:22 + --> tests/ui/manual_rem_euclid.rs:42:22 | LL | let _: i32 = ((value % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` @@ -40,25 +40,25 @@ LL | let _: i32 = ((value % 4) + 4) % 4; = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: manual `rem_euclid` implementation - --> tests/ui/manual_rem_euclid.rs:49:5 + --> tests/ui/manual_rem_euclid.rs:55:5 | LL | ((num % 4) + 4) % 4 | ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)` error: manual `rem_euclid` implementation - --> tests/ui/manual_rem_euclid.rs:54:5 + --> tests/ui/manual_rem_euclid.rs:61:5 | LL | ((num % 4) + 4) % 4 | ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)` error: manual `rem_euclid` implementation - --> tests/ui/manual_rem_euclid.rs:66:18 + --> tests/ui/manual_rem_euclid.rs:74:18 | LL | let _: i32 = ((x % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)` error: manual `rem_euclid` implementation - --> tests/ui/manual_rem_euclid.rs:79:18 + --> tests/ui/manual_rem_euclid.rs:88:18 | LL | let _: i32 = ((x % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)` diff --git a/tests/ui/manual_repeat_n.fixed b/tests/ui/manual_repeat_n.fixed index 4235b02a89e3..44ad3c02d3b8 100644 --- a/tests/ui/manual_repeat_n.fixed +++ b/tests/ui/manual_repeat_n.fixed @@ -4,14 +4,19 @@ use std::iter::repeat; fn main() { let _ = std::iter::repeat_n(10, 3); + //~^ manual_repeat_n let _ = std::iter::repeat_n(String::from("foo"), 4); + //~^ manual_repeat_n for value in std::iter::repeat_n(5, 3) {} + //~^ manual_repeat_n let _: Vec<_> = std::iter::repeat_n(String::from("bar"), 10).collect(); + //~^ manual_repeat_n let _ = std::iter::repeat_n(vec![1, 2], 2); + //~^ manual_repeat_n } mod foo_lib { diff --git a/tests/ui/manual_repeat_n.rs b/tests/ui/manual_repeat_n.rs index dbf9ac6a14af..ef6d6827d573 100644 --- a/tests/ui/manual_repeat_n.rs +++ b/tests/ui/manual_repeat_n.rs @@ -4,14 +4,19 @@ use std::iter::repeat; fn main() { let _ = repeat(10).take(3); + //~^ manual_repeat_n let _ = repeat(String::from("foo")).take(4); + //~^ manual_repeat_n for value in std::iter::repeat(5).take(3) {} + //~^ manual_repeat_n let _: Vec<_> = std::iter::repeat(String::from("bar")).take(10).collect(); + //~^ manual_repeat_n let _ = repeat(vec![1, 2]).take(2); + //~^ manual_repeat_n } mod foo_lib { diff --git a/tests/ui/manual_repeat_n.stderr b/tests/ui/manual_repeat_n.stderr index 87395b3f8bf1..de968b3ff791 100644 --- a/tests/ui/manual_repeat_n.stderr +++ b/tests/ui/manual_repeat_n.stderr @@ -8,25 +8,25 @@ LL | let _ = repeat(10).take(3); = help: to override `-D warnings` add `#[allow(clippy::manual_repeat_n)]` error: this `repeat().take()` can be written more concisely - --> tests/ui/manual_repeat_n.rs:8:13 + --> tests/ui/manual_repeat_n.rs:9:13 | LL | let _ = repeat(String::from("foo")).take(4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(String::from("foo"), 4)` error: this `repeat().take()` can be written more concisely - --> tests/ui/manual_repeat_n.rs:10:18 + --> tests/ui/manual_repeat_n.rs:12:18 | LL | for value in std::iter::repeat(5).take(3) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(5, 3)` error: this `repeat().take()` can be written more concisely - --> tests/ui/manual_repeat_n.rs:12:21 + --> tests/ui/manual_repeat_n.rs:15:21 | LL | let _: Vec<_> = std::iter::repeat(String::from("bar")).take(10).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(String::from("bar"), 10)` error: this `repeat().take()` can be written more concisely - --> tests/ui/manual_repeat_n.rs:14:13 + --> tests/ui/manual_repeat_n.rs:18:13 | LL | let _ = repeat(vec![1, 2]).take(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(vec![1, 2], 2)` diff --git a/tests/ui/manual_retain.fixed b/tests/ui/manual_retain.fixed index 5540029bf6b1..ca8491131c06 100644 --- a/tests/ui/manual_retain.fixed +++ b/tests/ui/manual_retain.fixed @@ -23,13 +23,18 @@ fn binary_heap_retain() { let mut binary_heap = BinaryHeap::from([1, 2, 3]); // Do lint. binary_heap.retain(|x| x % 2 == 0); + //~^ manual_retain binary_heap.retain(|x| x % 2 == 0); + //~^ manual_retain binary_heap.retain(|x| x % 2 == 0); + //~^ manual_retain // Do lint, because we use pattern matching let mut tuples = BinaryHeap::from([(0, 1), (1, 2), (2, 3)]); tuples.retain(|(ref x, ref y)| *x == 0); + //~^ manual_retain tuples.retain(|(x, y)| *x == 0); + //~^ manual_retain // Do not lint, because type conversion is performed binary_heap = binary_heap @@ -60,7 +65,9 @@ fn btree_map_retain() { let mut btree_map: BTreeMap = (0..8).map(|x| (x, x * 10)).collect(); // Do lint. btree_map.retain(|k, _| k % 2 == 0); + //~^ manual_retain btree_map.retain(|_, &mut v| v % 2 == 0); + //~^ manual_retain btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0)); // Do not lint, because the parameters are not matched in tuple pattern @@ -84,13 +91,18 @@ fn btree_set_retain() { // Do lint. btree_set.retain(|x| x % 2 == 0); + //~^ manual_retain btree_set.retain(|x| x % 2 == 0); + //~^ manual_retain btree_set.retain(|x| x % 2 == 0); + //~^ manual_retain // Do lint, because we use pattern matching let mut tuples = BTreeSet::from([(0, 1), (1, 2), (2, 3)]); tuples.retain(|(ref x, ref y)| *x == 0); + //~^ manual_retain tuples.retain(|(x, y)| *x == 0); + //~^ manual_retain // Do not lint, because type conversion is performed btree_set = btree_set @@ -121,7 +133,9 @@ fn hash_map_retain() { let mut hash_map: HashMap = (0..8).map(|x| (x, x * 10)).collect(); // Do lint. hash_map.retain(|k, _| k % 2 == 0); + //~^ manual_retain hash_map.retain(|_, &mut v| v % 2 == 0); + //~^ manual_retain hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0)); // Do not lint, because the parameters are not matched in tuple pattern @@ -144,13 +158,18 @@ fn hash_set_retain() { let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]); // Do lint. hash_set.retain(|x| x % 2 == 0); + //~^ manual_retain hash_set.retain(|x| x % 2 == 0); + //~^ manual_retain hash_set.retain(|x| x % 2 == 0); + //~^ manual_retain // Do lint, because we use pattern matching let mut tuples = HashSet::from([(0, 1), (1, 2), (2, 3)]); tuples.retain(|(ref x, ref y)| *x == 0); + //~^ manual_retain tuples.retain(|(x, y)| *x == 0); + //~^ manual_retain // Do not lint, because type conversion is performed hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::>(); @@ -180,6 +199,7 @@ fn string_retain() { let mut s = String::from("foobar"); // Do lint. s.retain(|c| c != 'o'); + //~^ manual_retain // Do not lint, because this expression is not assign. let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect(); @@ -192,13 +212,18 @@ fn vec_retain() { let mut vec = vec![0, 1, 2]; // Do lint. vec.retain(|x| x % 2 == 0); + //~^ manual_retain vec.retain(|x| x % 2 == 0); + //~^ manual_retain vec.retain(|x| x % 2 == 0); + //~^ manual_retain // Do lint, because we use pattern matching let mut tuples = vec![(0, 1), (1, 2), (2, 3)]; tuples.retain(|(ref x, ref y)| *x == 0); + //~^ manual_retain tuples.retain(|(x, y)| *x == 0); + //~^ manual_retain // Do not lint, because type conversion is performed vec = vec.into_iter().filter(|x| x % 2 == 0).collect::>(); @@ -221,8 +246,11 @@ fn vec_deque_retain() { // Do lint. vec_deque.retain(|x| x % 2 == 0); + //~^ manual_retain vec_deque.retain(|x| x % 2 == 0); + //~^ manual_retain vec_deque.retain(|x| x % 2 == 0); + //~^ manual_retain // Do not lint, because type conversion is performed vec_deque = vec_deque @@ -280,10 +308,12 @@ fn issue_10393() { // Do lint let mut vec = vec![(0, 1), (1, 2), (2, 3)]; vec.retain(|(x, y)| *x == 0); + //~^ manual_retain // Do lint let mut tuples = vec![(true, -2), (false, 3)]; tuples.retain(|(_, n)| *n > 0); + //~^ manual_retain } fn issue_11457() { @@ -301,11 +331,17 @@ fn issue_12081() { // Do lint vec.retain(|&x| x == 0); + //~^ manual_retain vec.retain(|&x| x == 0); + //~^ manual_retain vec.retain(|&x| x == 0); + //~^ manual_retain // Do lint vec.retain(|x| *x == 0); + //~^ manual_retain vec.retain(|x| *x == 0); + //~^ manual_retain vec.retain(|x| *x == 0); + //~^ manual_retain } diff --git a/tests/ui/manual_retain.rs b/tests/ui/manual_retain.rs index cee641d9d65f..61e2d73b544f 100644 --- a/tests/ui/manual_retain.rs +++ b/tests/ui/manual_retain.rs @@ -23,13 +23,18 @@ fn binary_heap_retain() { let mut binary_heap = BinaryHeap::from([1, 2, 3]); // Do lint. binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect(); + //~^ manual_retain binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect(); + //~^ manual_retain binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect(); + //~^ manual_retain // Do lint, because we use pattern matching let mut tuples = BinaryHeap::from([(0, 1), (1, 2), (2, 3)]); tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect(); + //~^ manual_retain tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect(); + //~^ manual_retain // Do not lint, because type conversion is performed binary_heap = binary_heap @@ -60,8 +65,11 @@ fn btree_map_retain() { let mut btree_map: BTreeMap = (0..8).map(|x| (x, x * 10)).collect(); // Do lint. btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect(); + //~^ manual_retain btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect(); + //~^ manual_retain btree_map = btree_map + //~^ manual_retain .into_iter() .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0)) .collect(); @@ -87,13 +95,18 @@ fn btree_set_retain() { // Do lint. btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect(); + //~^ manual_retain btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect(); + //~^ manual_retain btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect(); + //~^ manual_retain // Do lint, because we use pattern matching let mut tuples = BTreeSet::from([(0, 1), (1, 2), (2, 3)]); tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect(); + //~^ manual_retain tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect(); + //~^ manual_retain // Do not lint, because type conversion is performed btree_set = btree_set @@ -124,8 +137,11 @@ fn hash_map_retain() { let mut hash_map: HashMap = (0..8).map(|x| (x, x * 10)).collect(); // Do lint. hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect(); + //~^ manual_retain hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect(); + //~^ manual_retain hash_map = hash_map + //~^ manual_retain .into_iter() .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0)) .collect(); @@ -150,13 +166,18 @@ fn hash_set_retain() { let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]); // Do lint. hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect(); + //~^ manual_retain hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect(); + //~^ manual_retain hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect(); + //~^ manual_retain // Do lint, because we use pattern matching let mut tuples = HashSet::from([(0, 1), (1, 2), (2, 3)]); tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect(); + //~^ manual_retain tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect(); + //~^ manual_retain // Do not lint, because type conversion is performed hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::>(); @@ -186,6 +207,7 @@ fn string_retain() { let mut s = String::from("foobar"); // Do lint. s = s.chars().filter(|&c| c != 'o').to_owned().collect(); + //~^ manual_retain // Do not lint, because this expression is not assign. let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect(); @@ -198,13 +220,18 @@ fn vec_retain() { let mut vec = vec![0, 1, 2]; // Do lint. vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect(); + //~^ manual_retain vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect(); + //~^ manual_retain vec = vec.into_iter().filter(|x| x % 2 == 0).collect(); + //~^ manual_retain // Do lint, because we use pattern matching let mut tuples = vec![(0, 1), (1, 2), (2, 3)]; tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect(); + //~^ manual_retain tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect(); + //~^ manual_retain // Do not lint, because type conversion is performed vec = vec.into_iter().filter(|x| x % 2 == 0).collect::>(); @@ -227,8 +254,11 @@ fn vec_deque_retain() { // Do lint. vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect(); + //~^ manual_retain vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect(); + //~^ manual_retain vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect(); + //~^ manual_retain // Do not lint, because type conversion is performed vec_deque = vec_deque @@ -286,10 +316,12 @@ fn issue_10393() { // Do lint let mut vec = vec![(0, 1), (1, 2), (2, 3)]; vec = vec.into_iter().filter(|(x, y)| *x == 0).collect(); + //~^ manual_retain // Do lint let mut tuples = vec![(true, -2), (false, 3)]; tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect(); + //~^ manual_retain } fn issue_11457() { @@ -307,11 +339,17 @@ fn issue_12081() { // Do lint vec = vec.iter().filter(|&&x| x == 0).copied().collect(); + //~^ manual_retain vec = vec.iter().filter(|&&x| x == 0).cloned().collect(); + //~^ manual_retain vec = vec.into_iter().filter(|&x| x == 0).collect(); + //~^ manual_retain // Do lint vec = vec.iter().filter(|&x| *x == 0).copied().collect(); + //~^ manual_retain vec = vec.iter().filter(|&x| *x == 0).cloned().collect(); + //~^ manual_retain vec = vec.into_iter().filter(|x| *x == 0).collect(); + //~^ manual_retain } diff --git a/tests/ui/manual_retain.stderr b/tests/ui/manual_retain.stderr index c25c804df758..2f81647dd8b7 100644 --- a/tests/ui/manual_retain.stderr +++ b/tests/ui/manual_retain.stderr @@ -8,229 +8,231 @@ LL | binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect(); = help: to override `-D warnings` add `#[allow(clippy::manual_retain)]` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:26:5 + --> tests/ui/manual_retain.rs:27:5 | LL | binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:27:5 + --> tests/ui/manual_retain.rs:29:5 | LL | binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:31:5 + --> tests/ui/manual_retain.rs:34:5 | LL | tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:32:5 + --> tests/ui/manual_retain.rs:36:5 | LL | tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:62:5 + --> tests/ui/manual_retain.rs:67:5 | LL | btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:63:5 + --> tests/ui/manual_retain.rs:69:5 | LL | btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|_, &mut v| v % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:64:5 + --> tests/ui/manual_retain.rs:71:5 | LL | / btree_map = btree_map +LL | | LL | | .into_iter() LL | | .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0)) LL | | .collect(); | |__________________^ help: consider calling `.retain()` instead: `btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:89:5 + --> tests/ui/manual_retain.rs:97:5 | LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:90:5 + --> tests/ui/manual_retain.rs:99:5 | LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:91:5 + --> tests/ui/manual_retain.rs:101:5 | LL | btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:95:5 + --> tests/ui/manual_retain.rs:106:5 | LL | tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:96:5 + --> tests/ui/manual_retain.rs:108:5 | LL | tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:126:5 + --> tests/ui/manual_retain.rs:139:5 | LL | hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|k, _| k % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:127:5 + --> tests/ui/manual_retain.rs:141:5 | LL | hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|_, &mut v| v % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:128:5 + --> tests/ui/manual_retain.rs:143:5 | LL | / hash_map = hash_map +LL | | LL | | .into_iter() LL | | .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0)) LL | | .collect(); | |__________________^ help: consider calling `.retain()` instead: `hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:152:5 + --> tests/ui/manual_retain.rs:168:5 | LL | hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:153:5 + --> tests/ui/manual_retain.rs:170:5 | LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:154:5 + --> tests/ui/manual_retain.rs:172:5 | LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:158:5 + --> tests/ui/manual_retain.rs:177:5 | LL | tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:159:5 + --> tests/ui/manual_retain.rs:179:5 | LL | tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:188:5 + --> tests/ui/manual_retain.rs:209:5 | LL | s = s.chars().filter(|&c| c != 'o').to_owned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `s.retain(|c| c != 'o')` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:200:5 + --> tests/ui/manual_retain.rs:222:5 | LL | vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:201:5 + --> tests/ui/manual_retain.rs:224:5 | LL | vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:202:5 + --> tests/ui/manual_retain.rs:226:5 | LL | vec = vec.into_iter().filter(|x| x % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:206:5 + --> tests/ui/manual_retain.rs:231:5 | LL | tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:207:5 + --> tests/ui/manual_retain.rs:233:5 | LL | tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:229:5 + --> tests/ui/manual_retain.rs:256:5 | LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:230:5 + --> tests/ui/manual_retain.rs:258:5 | LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:231:5 + --> tests/ui/manual_retain.rs:260:5 | LL | vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:288:5 + --> tests/ui/manual_retain.rs:318:5 | LL | vec = vec.into_iter().filter(|(x, y)| *x == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|(x, y)| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:292:5 + --> tests/ui/manual_retain.rs:323:5 | LL | tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(_, n)| *n > 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:309:5 + --> tests/ui/manual_retain.rs:341:5 | LL | vec = vec.iter().filter(|&&x| x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:310:5 + --> tests/ui/manual_retain.rs:343:5 | LL | vec = vec.iter().filter(|&&x| x == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:311:5 + --> tests/ui/manual_retain.rs:345:5 | LL | vec = vec.into_iter().filter(|&x| x == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:314:5 + --> tests/ui/manual_retain.rs:349:5 | LL | vec = vec.iter().filter(|&x| *x == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:315:5 + --> tests/ui/manual_retain.rs:351:5 | LL | vec = vec.iter().filter(|&x| *x == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)` error: this expression can be written more simply using `.retain()` - --> tests/ui/manual_retain.rs:316:5 + --> tests/ui/manual_retain.rs:353:5 | LL | vec = vec.into_iter().filter(|x| *x == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)` diff --git a/tests/ui/manual_rotate.fixed b/tests/ui/manual_rotate.fixed index 5d33838a3187..49db8661369e 100644 --- a/tests/ui/manual_rotate.fixed +++ b/tests/ui/manual_rotate.fixed @@ -6,18 +6,29 @@ fn main() { let a_u32 = 1u32; // True positives let y_u8 = x_u8.rotate_right(3); + //~^ manual_rotate let y_u16 = x_u16.rotate_right(7); + //~^ manual_rotate let y_u32 = x_u32.rotate_right(8); + //~^ manual_rotate let y_u64 = x_u64.rotate_right(9); + //~^ manual_rotate let y_i8 = x_i8.rotate_right(3); + //~^ manual_rotate let y_i16 = x_i16.rotate_right(7); + //~^ manual_rotate let y_i32 = x_i32.rotate_right(8); + //~^ manual_rotate let y_i64 = x_i64.rotate_right(9); + //~^ manual_rotate // Plus also works instead of | let y_u32_plus = x_u32.rotate_right(8); + //~^ manual_rotate // Complex expression let y_u32_complex = (x_u32 | 3256).rotate_right(8); + //~^ manual_rotate let y_u64_as = (x_u32 as u64).rotate_right(8); + //~^ manual_rotate // False positives - can't be replaced with a rotation let y_u8_false = (x_u8 >> 6) | (x_u8 << 3); diff --git a/tests/ui/manual_rotate.rs b/tests/ui/manual_rotate.rs index 5377491fb1a3..6445e60aa25d 100644 --- a/tests/ui/manual_rotate.rs +++ b/tests/ui/manual_rotate.rs @@ -6,18 +6,29 @@ fn main() { let a_u32 = 1u32; // True positives let y_u8 = (x_u8 >> 3) | (x_u8 << 5); + //~^ manual_rotate let y_u16 = (x_u16 >> 7) | (x_u16 << 9); + //~^ manual_rotate let y_u32 = (x_u32 >> 8) | (x_u32 << 24); + //~^ manual_rotate let y_u64 = (x_u64 >> 9) | (x_u64 << 55); + //~^ manual_rotate let y_i8 = (x_i8 >> 3) | (x_i8 << 5); + //~^ manual_rotate let y_i16 = (x_i16 >> 7) | (x_i16 << 9); + //~^ manual_rotate let y_i32 = (x_i32 >> 8) | (x_i32 << 24); + //~^ manual_rotate let y_i64 = (x_i64 >> 9) | (x_i64 << 55); + //~^ manual_rotate // Plus also works instead of | let y_u32_plus = (x_u32 >> 8) + (x_u32 << 24); + //~^ manual_rotate // Complex expression let y_u32_complex = ((x_u32 | 3256) >> 8) | ((x_u32 | 3256) << 24); + //~^ manual_rotate let y_u64_as = (x_u32 as u64 >> 8) | ((x_u32 as u64) << 56); + //~^ manual_rotate // False positives - can't be replaced with a rotation let y_u8_false = (x_u8 >> 6) | (x_u8 << 3); diff --git a/tests/ui/manual_rotate.stderr b/tests/ui/manual_rotate.stderr index 52da0861f700..a28721fbb94c 100644 --- a/tests/ui/manual_rotate.stderr +++ b/tests/ui/manual_rotate.stderr @@ -8,61 +8,61 @@ LL | let y_u8 = (x_u8 >> 3) | (x_u8 << 5); = help: to override `-D warnings` add `#[allow(clippy::manual_rotate)]` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:9:17 + --> tests/ui/manual_rotate.rs:10:17 | LL | let y_u16 = (x_u16 >> 7) | (x_u16 << 9); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_u16.rotate_right(7)` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:10:17 + --> tests/ui/manual_rotate.rs:12:17 | LL | let y_u32 = (x_u32 >> 8) | (x_u32 << 24); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_u32.rotate_right(8)` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:11:17 + --> tests/ui/manual_rotate.rs:14:17 | LL | let y_u64 = (x_u64 >> 9) | (x_u64 << 55); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_u64.rotate_right(9)` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:12:16 + --> tests/ui/manual_rotate.rs:16:16 | LL | let y_i8 = (x_i8 >> 3) | (x_i8 << 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_i8.rotate_right(3)` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:13:17 + --> tests/ui/manual_rotate.rs:18:17 | LL | let y_i16 = (x_i16 >> 7) | (x_i16 << 9); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_i16.rotate_right(7)` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:14:17 + --> tests/ui/manual_rotate.rs:20:17 | LL | let y_i32 = (x_i32 >> 8) | (x_i32 << 24); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_i32.rotate_right(8)` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:15:17 + --> tests/ui/manual_rotate.rs:22:17 | LL | let y_i64 = (x_i64 >> 9) | (x_i64 << 55); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_i64.rotate_right(9)` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:17:22 + --> tests/ui/manual_rotate.rs:25:22 | LL | let y_u32_plus = (x_u32 >> 8) + (x_u32 << 24); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_u32.rotate_right(8)` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:19:25 + --> tests/ui/manual_rotate.rs:28:25 | LL | let y_u32_complex = ((x_u32 | 3256) >> 8) | ((x_u32 | 3256) << 24); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `(x_u32 | 3256).rotate_right(8)` error: there is no need to manually implement bit rotation - --> tests/ui/manual_rotate.rs:20:20 + --> tests/ui/manual_rotate.rs:30:20 | LL | let y_u64_as = (x_u32 as u64 >> 8) | ((x_u32 as u64) << 56); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `(x_u32 as u64).rotate_right(8)` diff --git a/tests/ui/manual_saturating_arithmetic.fixed b/tests/ui/manual_saturating_arithmetic.fixed index 528a65790c4c..3f73d6e5a1a6 100644 --- a/tests/ui/manual_saturating_arithmetic.fixed +++ b/tests/ui/manual_saturating_arithmetic.fixed @@ -4,38 +4,57 @@ use std::{i32, i128, u32, u128}; fn main() { let _ = 1u32.saturating_add(1); + //~^ manual_saturating_arithmetic let _ = 1u32.saturating_add(1); + //~^ manual_saturating_arithmetic let _ = 1u8.saturating_add(1); + //~^ manual_saturating_arithmetic let _ = 1u128.saturating_add(1); let _ = 1u32.checked_add(1).unwrap_or(1234); // ok let _ = 1u8.checked_add(1).unwrap_or(0); // ok let _ = 1u32.saturating_mul(1); + //~^ manual_saturating_arithmetic let _ = 1u32.saturating_sub(1); + //~^ manual_saturating_arithmetic let _ = 1u32.saturating_sub(1); + //~^ manual_saturating_arithmetic let _ = 1u8.saturating_sub(1); + //~^ manual_saturating_arithmetic let _ = 1u32.checked_sub(1).unwrap_or(1234); // ok let _ = 1u8.checked_sub(1).unwrap_or(255); // ok let _ = 1i32.saturating_add(1); + //~^ manual_saturating_arithmetic let _ = 1i32.saturating_add(1); + //~^ manual_saturating_arithmetic let _ = 1i8.saturating_add(1); + //~^ manual_saturating_arithmetic let _ = 1i128.saturating_add(1); let _ = 1i32.saturating_add(-1); + //~^ manual_saturating_arithmetic let _ = 1i32.saturating_add(-1); + //~^ manual_saturating_arithmetic let _ = 1i8.saturating_add(-1); + //~^ manual_saturating_arithmetic let _ = 1i128.saturating_add(-1); let _ = 1i32.checked_add(1).unwrap_or(1234); // ok let _ = 1i8.checked_add(1).unwrap_or(-128); // ok let _ = 1i8.checked_add(-1).unwrap_or(127); // ok let _ = 1i32.saturating_sub(1); + //~^ manual_saturating_arithmetic let _ = 1i32.saturating_sub(1); + //~^ manual_saturating_arithmetic let _ = 1i8.saturating_sub(1); + //~^ manual_saturating_arithmetic let _ = 1i128.saturating_sub(1); let _ = 1i32.saturating_sub(-1); + //~^ manual_saturating_arithmetic let _ = 1i32.saturating_sub(-1); + //~^ manual_saturating_arithmetic let _ = 1i8.saturating_sub(-1); + //~^ manual_saturating_arithmetic let _ = 1i128.saturating_sub(-1); let _ = 1i32.checked_sub(1).unwrap_or(1234); // ok let _ = 1i8.checked_sub(1).unwrap_or(127); // ok diff --git a/tests/ui/manual_saturating_arithmetic.rs b/tests/ui/manual_saturating_arithmetic.rs index 55f3720dfcc0..c0d7f26916ee 100644 --- a/tests/ui/manual_saturating_arithmetic.rs +++ b/tests/ui/manual_saturating_arithmetic.rs @@ -4,31 +4,47 @@ use std::{i32, i128, u32, u128}; fn main() { let _ = 1u32.checked_add(1).unwrap_or(u32::max_value()); + //~^ manual_saturating_arithmetic let _ = 1u32.checked_add(1).unwrap_or(u32::MAX); + //~^ manual_saturating_arithmetic let _ = 1u8.checked_add(1).unwrap_or(255); + //~^ manual_saturating_arithmetic let _ = 1u128 + //~^ manual_saturating_arithmetic .checked_add(1) .unwrap_or(340_282_366_920_938_463_463_374_607_431_768_211_455); let _ = 1u32.checked_add(1).unwrap_or(1234); // ok let _ = 1u8.checked_add(1).unwrap_or(0); // ok let _ = 1u32.checked_mul(1).unwrap_or(u32::MAX); + //~^ manual_saturating_arithmetic let _ = 1u32.checked_sub(1).unwrap_or(u32::min_value()); + //~^ manual_saturating_arithmetic let _ = 1u32.checked_sub(1).unwrap_or(u32::MIN); + //~^ manual_saturating_arithmetic let _ = 1u8.checked_sub(1).unwrap_or(0); + //~^ manual_saturating_arithmetic let _ = 1u32.checked_sub(1).unwrap_or(1234); // ok let _ = 1u8.checked_sub(1).unwrap_or(255); // ok let _ = 1i32.checked_add(1).unwrap_or(i32::max_value()); + //~^ manual_saturating_arithmetic let _ = 1i32.checked_add(1).unwrap_or(i32::MAX); + //~^ manual_saturating_arithmetic let _ = 1i8.checked_add(1).unwrap_or(127); + //~^ manual_saturating_arithmetic let _ = 1i128 + //~^ manual_saturating_arithmetic .checked_add(1) .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727); let _ = 1i32.checked_add(-1).unwrap_or(i32::min_value()); + //~^ manual_saturating_arithmetic let _ = 1i32.checked_add(-1).unwrap_or(i32::MIN); + //~^ manual_saturating_arithmetic let _ = 1i8.checked_add(-1).unwrap_or(-128); + //~^ manual_saturating_arithmetic let _ = 1i128 + //~^ manual_saturating_arithmetic .checked_add(-1) .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728); let _ = 1i32.checked_add(1).unwrap_or(1234); // ok @@ -36,15 +52,23 @@ fn main() { let _ = 1i8.checked_add(-1).unwrap_or(127); // ok let _ = 1i32.checked_sub(1).unwrap_or(i32::min_value()); + //~^ manual_saturating_arithmetic let _ = 1i32.checked_sub(1).unwrap_or(i32::MIN); + //~^ manual_saturating_arithmetic let _ = 1i8.checked_sub(1).unwrap_or(-128); + //~^ manual_saturating_arithmetic let _ = 1i128 + //~^ manual_saturating_arithmetic .checked_sub(1) .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728); let _ = 1i32.checked_sub(-1).unwrap_or(i32::max_value()); + //~^ manual_saturating_arithmetic let _ = 1i32.checked_sub(-1).unwrap_or(i32::MAX); + //~^ manual_saturating_arithmetic let _ = 1i8.checked_sub(-1).unwrap_or(127); + //~^ manual_saturating_arithmetic let _ = 1i128 + //~^ manual_saturating_arithmetic .checked_sub(-1) .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727); let _ = 1i32.checked_sub(1).unwrap_or(1234); // ok diff --git a/tests/ui/manual_saturating_arithmetic.stderr b/tests/ui/manual_saturating_arithmetic.stderr index b6a8df0f84e1..9d133d8a073b 100644 --- a/tests/ui/manual_saturating_arithmetic.stderr +++ b/tests/ui/manual_saturating_arithmetic.stderr @@ -8,154 +8,159 @@ LL | let _ = 1u32.checked_add(1).unwrap_or(u32::max_value()); = help: to override `-D warnings` add `#[allow(clippy::manual_saturating_arithmetic)]` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:7:13 + --> tests/ui/manual_saturating_arithmetic.rs:8:13 | LL | let _ = 1u32.checked_add(1).unwrap_or(u32::MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u32.saturating_add(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:8:13 + --> tests/ui/manual_saturating_arithmetic.rs:10:13 | LL | let _ = 1u8.checked_add(1).unwrap_or(255); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u8.saturating_add(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:9:13 + --> tests/ui/manual_saturating_arithmetic.rs:12:13 | LL | let _ = 1u128 | _____________^ +LL | | LL | | .checked_add(1) LL | | .unwrap_or(340_282_366_920_938_463_463_374_607_431_768_211_455); | |_______________________________________________________________________^ help: consider using `saturating_add`: `1u128.saturating_add(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:14:13 + --> tests/ui/manual_saturating_arithmetic.rs:18:13 | LL | let _ = 1u32.checked_mul(1).unwrap_or(u32::MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_mul`: `1u32.saturating_mul(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:16:13 + --> tests/ui/manual_saturating_arithmetic.rs:21:13 | LL | let _ = 1u32.checked_sub(1).unwrap_or(u32::min_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:17:13 + --> tests/ui/manual_saturating_arithmetic.rs:23:13 | LL | let _ = 1u32.checked_sub(1).unwrap_or(u32::MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:18:13 + --> tests/ui/manual_saturating_arithmetic.rs:25:13 | LL | let _ = 1u8.checked_sub(1).unwrap_or(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u8.saturating_sub(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:22:13 + --> tests/ui/manual_saturating_arithmetic.rs:30:13 | LL | let _ = 1i32.checked_add(1).unwrap_or(i32::max_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:23:13 + --> tests/ui/manual_saturating_arithmetic.rs:32:13 | LL | let _ = 1i32.checked_add(1).unwrap_or(i32::MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:24:13 + --> tests/ui/manual_saturating_arithmetic.rs:34:13 | LL | let _ = 1i8.checked_add(1).unwrap_or(127); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:25:13 + --> tests/ui/manual_saturating_arithmetic.rs:36:13 | LL | let _ = 1i128 | _____________^ +LL | | LL | | .checked_add(1) LL | | .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727); | |_______________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:28:13 + --> tests/ui/manual_saturating_arithmetic.rs:40:13 | LL | let _ = 1i32.checked_add(-1).unwrap_or(i32::min_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:29:13 + --> tests/ui/manual_saturating_arithmetic.rs:42:13 | LL | let _ = 1i32.checked_add(-1).unwrap_or(i32::MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:30:13 + --> tests/ui/manual_saturating_arithmetic.rs:44:13 | LL | let _ = 1i8.checked_add(-1).unwrap_or(-128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(-1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:31:13 + --> tests/ui/manual_saturating_arithmetic.rs:46:13 | LL | let _ = 1i128 | _____________^ +LL | | LL | | .checked_add(-1) LL | | .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728); | |________________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(-1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:38:13 + --> tests/ui/manual_saturating_arithmetic.rs:54:13 | LL | let _ = 1i32.checked_sub(1).unwrap_or(i32::min_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:39:13 + --> tests/ui/manual_saturating_arithmetic.rs:56:13 | LL | let _ = 1i32.checked_sub(1).unwrap_or(i32::MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:40:13 + --> tests/ui/manual_saturating_arithmetic.rs:58:13 | LL | let _ = 1i8.checked_sub(1).unwrap_or(-128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:41:13 + --> tests/ui/manual_saturating_arithmetic.rs:60:13 | LL | let _ = 1i128 | _____________^ +LL | | LL | | .checked_sub(1) LL | | .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728); | |________________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:44:13 + --> tests/ui/manual_saturating_arithmetic.rs:64:13 | LL | let _ = 1i32.checked_sub(-1).unwrap_or(i32::max_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:45:13 + --> tests/ui/manual_saturating_arithmetic.rs:66:13 | LL | let _ = 1i32.checked_sub(-1).unwrap_or(i32::MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:46:13 + --> tests/ui/manual_saturating_arithmetic.rs:68:13 | LL | let _ = 1i8.checked_sub(-1).unwrap_or(127); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(-1)` error: manual saturating arithmetic - --> tests/ui/manual_saturating_arithmetic.rs:47:13 + --> tests/ui/manual_saturating_arithmetic.rs:70:13 | LL | let _ = 1i128 | _____________^ +LL | | LL | | .checked_sub(-1) LL | | .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727); | |_______________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(-1)` diff --git a/tests/ui/manual_slice_fill.rs b/tests/ui/manual_slice_fill.rs index 75a391f4243c..cd62a476d174 100644 --- a/tests/ui/manual_slice_fill.rs +++ b/tests/ui/manual_slice_fill.rs @@ -23,21 +23,25 @@ fn should_lint() { let mut some_slice = [1, 2, 3, 4, 5]; for i in 0..some_slice.len() { + //~^ manual_slice_fill some_slice[i] = 0; } let x = 5; for i in 0..some_slice.len() { + //~^ manual_slice_fill some_slice[i] = x; } for i in &mut some_slice { + //~^ manual_slice_fill *i = 0; } // This should trigger `manual_slice_fill`, but the applicability is `MaybeIncorrect` since comments // within the loop might be purely informational. for i in 0..some_slice.len() { + //~^ manual_slice_fill some_slice[i] = 0; // foo } diff --git a/tests/ui/manual_slice_fill.stderr b/tests/ui/manual_slice_fill.stderr index 3aa980f69191..38e43d5b4e06 100644 --- a/tests/ui/manual_slice_fill.stderr +++ b/tests/ui/manual_slice_fill.stderr @@ -2,6 +2,7 @@ error: manually filling a slice --> tests/ui/manual_slice_fill.rs:25:5 | LL | / for i in 0..some_slice.len() { +LL | | LL | | some_slice[i] = 0; LL | | } | |_____^ help: try: `some_slice.fill(0);` @@ -10,25 +11,28 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_slice_fill)]` error: manually filling a slice - --> tests/ui/manual_slice_fill.rs:30:5 + --> tests/ui/manual_slice_fill.rs:31:5 | LL | / for i in 0..some_slice.len() { +LL | | LL | | some_slice[i] = x; LL | | } | |_____^ help: try: `some_slice.fill(x);` error: manually filling a slice - --> tests/ui/manual_slice_fill.rs:34:5 + --> tests/ui/manual_slice_fill.rs:36:5 | LL | / for i in &mut some_slice { +LL | | LL | | *i = 0; LL | | } | |_____^ help: try: `some_slice.fill(0);` error: manually filling a slice - --> tests/ui/manual_slice_fill.rs:40:5 + --> tests/ui/manual_slice_fill.rs:43:5 | LL | / for i in 0..some_slice.len() { +LL | | LL | | some_slice[i] = 0; LL | | // foo LL | | } diff --git a/tests/ui/manual_slice_size_calculation.fixed b/tests/ui/manual_slice_size_calculation.fixed index 0603b30e3465..91ada0b75d5c 100644 --- a/tests/ui/manual_slice_size_calculation.fixed +++ b/tests/ui/manual_slice_size_calculation.fixed @@ -15,18 +15,27 @@ fn main() { // True positives: let _ = std::mem::size_of_val(s_i32); // WARNING + //~^ manual_slice_size_calculation let _ = std::mem::size_of_val(s_i32); // WARNING + //~^ manual_slice_size_calculation let _ = std::mem::size_of_val(s_i32) * 5; // WARNING + //~^ manual_slice_size_calculation let _ = std::mem::size_of_val(*s_i32_ref); // WARNING + //~^ manual_slice_size_calculation let _ = std::mem::size_of_val(**s_i32_ref_ref); // WARNING + //~^ manual_slice_size_calculation let len = s_i32.len(); let size = size_of::(); let _ = std::mem::size_of_val(s_i32); // WARNING + //~^ manual_slice_size_calculation let _ = std::mem::size_of_val(s_i32); // WARNING + //~^ manual_slice_size_calculation let _ = std::mem::size_of_val(s_i32); // WARNING + //~^ manual_slice_size_calculation let _ = std::mem::size_of_val(external!(&[1u64][..])); + //~^ manual_slice_size_calculation // True negatives: let _ = size_of::() + s_i32.len(); // Ok, not a multiplication diff --git a/tests/ui/manual_slice_size_calculation.rs b/tests/ui/manual_slice_size_calculation.rs index 14093e653c09..0ef3793619c4 100644 --- a/tests/ui/manual_slice_size_calculation.rs +++ b/tests/ui/manual_slice_size_calculation.rs @@ -15,18 +15,27 @@ fn main() { // True positives: let _ = s_i32.len() * size_of::(); // WARNING + //~^ manual_slice_size_calculation let _ = size_of::() * s_i32.len(); // WARNING + //~^ manual_slice_size_calculation let _ = size_of::() * s_i32.len() * 5; // WARNING + //~^ manual_slice_size_calculation let _ = size_of::() * s_i32_ref.len(); // WARNING + //~^ manual_slice_size_calculation let _ = size_of::() * s_i32_ref_ref.len(); // WARNING + //~^ manual_slice_size_calculation let len = s_i32.len(); let size = size_of::(); let _ = len * size_of::(); // WARNING + //~^ manual_slice_size_calculation let _ = s_i32.len() * size; // WARNING + //~^ manual_slice_size_calculation let _ = len * size; // WARNING + //~^ manual_slice_size_calculation let _ = external!(&[1u64][..]).len() * size_of::(); + //~^ manual_slice_size_calculation // True negatives: let _ = size_of::() + s_i32.len(); // Ok, not a multiplication diff --git a/tests/ui/manual_slice_size_calculation.stderr b/tests/ui/manual_slice_size_calculation.stderr index 0397f3a4969a..d752e8356aa8 100644 --- a/tests/ui/manual_slice_size_calculation.stderr +++ b/tests/ui/manual_slice_size_calculation.stderr @@ -8,49 +8,49 @@ LL | let _ = s_i32.len() * size_of::(); // WARNING = help: to override `-D warnings` add `#[allow(clippy::manual_slice_size_calculation)]` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:18:13 + --> tests/ui/manual_slice_size_calculation.rs:19:13 | LL | let _ = size_of::() * s_i32.len(); // WARNING | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:19:13 + --> tests/ui/manual_slice_size_calculation.rs:21:13 | LL | let _ = size_of::() * s_i32.len() * 5; // WARNING | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:20:13 + --> tests/ui/manual_slice_size_calculation.rs:23:13 | LL | let _ = size_of::() * s_i32_ref.len(); // WARNING | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(*s_i32_ref)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:21:13 + --> tests/ui/manual_slice_size_calculation.rs:25:13 | LL | let _ = size_of::() * s_i32_ref_ref.len(); // WARNING | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(**s_i32_ref_ref)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:25:13 + --> tests/ui/manual_slice_size_calculation.rs:30:13 | LL | let _ = len * size_of::(); // WARNING | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:26:13 + --> tests/ui/manual_slice_size_calculation.rs:32:13 | LL | let _ = s_i32.len() * size; // WARNING | ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:27:13 + --> tests/ui/manual_slice_size_calculation.rs:34:13 | LL | let _ = len * size; // WARNING | ^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:29:13 + --> tests/ui/manual_slice_size_calculation.rs:37:13 | LL | let _ = external!(&[1u64][..]).len() * size_of::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` diff --git a/tests/ui/manual_split_once.fixed b/tests/ui/manual_split_once.fixed index aaac6a048e1d..76dfb99b787d 100644 --- a/tests/ui/manual_split_once.fixed +++ b/tests/ui/manual_split_once.fixed @@ -9,23 +9,33 @@ use itertools::Itertools; fn main() { let _ = "key=value".splitn(2, '=').nth(2); let _ = "key=value".split_once('=').unwrap().1; + //~^ manual_split_once let _ = "key=value".split_once('=').unwrap().1; + //~^ manual_split_once let (_, _) = "key=value".split_once('=').unwrap(); + //~^ manual_split_once let s = String::from("key=value"); let _ = s.split_once('=').unwrap().1; + //~^ manual_split_once let s = Box::::from("key=value"); let _ = s.split_once('=').unwrap().1; + //~^ manual_split_once let s = &"key=value"; let _ = s.split_once('=').unwrap().1; + //~^ manual_split_once fn _f(s: &str) -> Option<&str> { let _ = s.split_once('=')?.1; + //~^ manual_split_once let _ = s.split_once('=')?.1; + //~^ manual_split_once let _ = s.rsplit_once('=')?.0; + //~^ manual_split_once let _ = s.rsplit_once('=')?.0; + //~^ manual_split_once None } @@ -34,24 +44,31 @@ fn main() { // `rsplitn` gives the results in the reverse order of `rsplit_once` let _ = "key=value".rsplit_once('=').unwrap().0; + //~^ manual_split_once let (_, _) = "key=value".rsplit_once('=').map(|(x, y)| (y, x)).unwrap(); + //~^ manual_split_once let _ = s.rsplit_once('=').map(|x| x.0); + //~^ manual_split_once } fn indirect() -> Option<()> { let (l, r) = "a.b.c".split_once('.').unwrap(); + //~^ manual_split_once let (l, r) = "a.b.c".split_once('.')?; + //~^ manual_split_once let (l, r) = "a.b.c".rsplit_once('.').unwrap(); + //~^ manual_split_once let (l, r) = "a.b.c".rsplit_once('.')?; + //~^ manual_split_once @@ -137,8 +154,10 @@ fn _msrv_1_51() { #[clippy::msrv = "1.52"] fn _msrv_1_52() { let _ = "key=value".split_once('=').unwrap().1; + //~^ manual_split_once let (a, b) = "a.b.c".split_once('.').unwrap(); + //~^ manual_split_once } diff --git a/tests/ui/manual_split_once.rs b/tests/ui/manual_split_once.rs index 113e1737c97d..73602fae3d82 100644 --- a/tests/ui/manual_split_once.rs +++ b/tests/ui/manual_split_once.rs @@ -9,23 +9,33 @@ use itertools::Itertools; fn main() { let _ = "key=value".splitn(2, '=').nth(2); let _ = "key=value".splitn(2, '=').nth(1).unwrap(); + //~^ manual_split_once let _ = "key=value".splitn(2, '=').skip(1).next().unwrap(); + //~^ manual_split_once let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap(); + //~^ manual_split_once let s = String::from("key=value"); let _ = s.splitn(2, '=').nth(1).unwrap(); + //~^ manual_split_once let s = Box::::from("key=value"); let _ = s.splitn(2, '=').nth(1).unwrap(); + //~^ manual_split_once let s = &"key=value"; let _ = s.splitn(2, '=').skip(1).next().unwrap(); + //~^ manual_split_once fn _f(s: &str) -> Option<&str> { let _ = s.splitn(2, '=').nth(1)?; + //~^ manual_split_once let _ = s.splitn(2, '=').skip(1).next()?; + //~^ manual_split_once let _ = s.rsplitn(2, '=').nth(1)?; + //~^ manual_split_once let _ = s.rsplitn(2, '=').skip(1).next()?; + //~^ manual_split_once None } @@ -34,24 +44,31 @@ fn main() { // `rsplitn` gives the results in the reverse order of `rsplit_once` let _ = "key=value".rsplitn(2, '=').nth(1).unwrap(); + //~^ manual_split_once let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap(); + //~^ manual_split_once let _ = s.rsplitn(2, '=').nth(1); + //~^ manual_split_once } fn indirect() -> Option<()> { let mut iter = "a.b.c".splitn(2, '.'); + //~^ manual_split_once let l = iter.next().unwrap(); let r = iter.next().unwrap(); let mut iter = "a.b.c".splitn(2, '.'); + //~^ manual_split_once let l = iter.next()?; let r = iter.next()?; let mut iter = "a.b.c".rsplitn(2, '.'); + //~^ manual_split_once let r = iter.next().unwrap(); let l = iter.next().unwrap(); let mut iter = "a.b.c".rsplitn(2, '.'); + //~^ manual_split_once let r = iter.next()?; let l = iter.next()?; @@ -137,8 +154,10 @@ fn _msrv_1_51() { #[clippy::msrv = "1.52"] fn _msrv_1_52() { let _ = "key=value".splitn(2, '=').nth(1).unwrap(); + //~^ manual_split_once let mut iter = "a.b.c".splitn(2, '.'); + //~^ manual_split_once let a = iter.next().unwrap(); let b = iter.next().unwrap(); } diff --git a/tests/ui/manual_split_once.stderr b/tests/ui/manual_split_once.stderr index 366d860f25ef..2a44f6e7438c 100644 --- a/tests/ui/manual_split_once.stderr +++ b/tests/ui/manual_split_once.stderr @@ -8,23 +8,17 @@ LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap(); = help: to override `-D warnings` add `#[allow(clippy::manual_split_once)]` error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:12:13 + --> tests/ui/manual_split_once.rs:13:13 | LL | let _ = "key=value".splitn(2, '=').skip(1).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1` error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:13:18 + --> tests/ui/manual_split_once.rs:15:18 | LL | let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=')` -error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:16:13 - | -LL | let _ = s.splitn(2, '=').nth(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1` - error: manual implementation of `split_once` --> tests/ui/manual_split_once.rs:19:13 | @@ -32,58 +26,65 @@ LL | let _ = s.splitn(2, '=').nth(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1` error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:22:13 + --> tests/ui/manual_split_once.rs:23:13 + | +LL | let _ = s.splitn(2, '=').nth(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1` + +error: manual implementation of `split_once` + --> tests/ui/manual_split_once.rs:27:13 | LL | let _ = s.splitn(2, '=').skip(1).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1` error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:25:17 + --> tests/ui/manual_split_once.rs:31:17 | LL | let _ = s.splitn(2, '=').nth(1)?; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1` error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:26:17 + --> tests/ui/manual_split_once.rs:33:17 | LL | let _ = s.splitn(2, '=').skip(1).next()?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1` error: manual implementation of `rsplit_once` - --> tests/ui/manual_split_once.rs:27:17 + --> tests/ui/manual_split_once.rs:35:17 | LL | let _ = s.rsplitn(2, '=').nth(1)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0` error: manual implementation of `rsplit_once` - --> tests/ui/manual_split_once.rs:28:17 + --> tests/ui/manual_split_once.rs:37:17 | LL | let _ = s.rsplitn(2, '=').skip(1).next()?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0` error: manual implementation of `rsplit_once` - --> tests/ui/manual_split_once.rs:36:13 + --> tests/ui/manual_split_once.rs:46:13 | LL | let _ = "key=value".rsplitn(2, '=').nth(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').unwrap().0` error: manual implementation of `rsplit_once` - --> tests/ui/manual_split_once.rs:37:18 + --> tests/ui/manual_split_once.rs:48:18 | LL | let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))` error: manual implementation of `rsplit_once` - --> tests/ui/manual_split_once.rs:38:13 + --> tests/ui/manual_split_once.rs:50:13 | LL | let _ = s.rsplitn(2, '=').nth(1); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=').map(|x| x.0)` error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:42:5 + --> tests/ui/manual_split_once.rs:55:5 | LL | let mut iter = "a.b.c".splitn(2, '.'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | let l = iter.next().unwrap(); | ----------------------------- first usage here LL | let r = iter.next().unwrap(); @@ -92,15 +93,17 @@ LL | let r = iter.next().unwrap(); help: replace with `split_once` | LL ~ let (l, r) = "a.b.c".split_once('.').unwrap(); +LL | LL ~ LL ~ | error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:46:5 + --> tests/ui/manual_split_once.rs:60:5 | LL | let mut iter = "a.b.c".splitn(2, '.'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | let l = iter.next()?; | --------------------- first usage here LL | let r = iter.next()?; @@ -109,15 +112,17 @@ LL | let r = iter.next()?; help: replace with `split_once` | LL ~ let (l, r) = "a.b.c".split_once('.')?; +LL | LL ~ LL ~ | error: manual implementation of `rsplit_once` - --> tests/ui/manual_split_once.rs:50:5 + --> tests/ui/manual_split_once.rs:65:5 | LL | let mut iter = "a.b.c".rsplitn(2, '.'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | let r = iter.next().unwrap(); | ----------------------------- first usage here LL | let l = iter.next().unwrap(); @@ -126,15 +131,17 @@ LL | let l = iter.next().unwrap(); help: replace with `rsplit_once` | LL ~ let (l, r) = "a.b.c".rsplit_once('.').unwrap(); +LL | LL ~ LL ~ | error: manual implementation of `rsplit_once` - --> tests/ui/manual_split_once.rs:54:5 + --> tests/ui/manual_split_once.rs:70:5 | LL | let mut iter = "a.b.c".rsplitn(2, '.'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | let r = iter.next()?; | --------------------- first usage here LL | let l = iter.next()?; @@ -143,21 +150,23 @@ LL | let l = iter.next()?; help: replace with `rsplit_once` | LL ~ let (l, r) = "a.b.c".rsplit_once('.')?; +LL | LL ~ LL ~ | error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:139:13 + --> tests/ui/manual_split_once.rs:156:13 | LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1` error: manual implementation of `split_once` - --> tests/ui/manual_split_once.rs:141:5 + --> tests/ui/manual_split_once.rs:159:5 | LL | let mut iter = "a.b.c".splitn(2, '.'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | let a = iter.next().unwrap(); | ----------------------------- first usage here LL | let b = iter.next().unwrap(); @@ -166,6 +175,7 @@ LL | let b = iter.next().unwrap(); help: replace with `split_once` | LL ~ let (a, b) = "a.b.c".split_once('.').unwrap(); +LL | LL ~ LL ~ | diff --git a/tests/ui/manual_str_repeat.fixed b/tests/ui/manual_str_repeat.fixed index da6f36f53b0d..bbe4260f6bc8 100644 --- a/tests/ui/manual_str_repeat.fixed +++ b/tests/ui/manual_str_repeat.fixed @@ -6,13 +6,18 @@ use std::iter::repeat; fn main() { let _: String = "test".repeat(10); + //~^ manual_str_repeat let _: String = "x".repeat(10); + //~^ manual_str_repeat let _: String = "'".repeat(10); + //~^ manual_str_repeat let _: String = "\"".repeat(10); + //~^ manual_str_repeat let x = "test"; let count = 10; let _ = x.repeat(count + 2); + //~^ manual_str_repeat macro_rules! m { ($e:expr) => {{ $e }}; @@ -22,6 +27,7 @@ fn main() { let x = &x; let _: String = (*x).repeat(count); + //~^ manual_str_repeat macro_rules! repeat_m { ($e:expr) => {{ repeat($e) }}; @@ -31,6 +37,7 @@ fn main() { let x: Box = Box::from("test"); let _: String = x.repeat(count); + //~^ manual_str_repeat #[derive(Clone)] struct S; @@ -43,9 +50,11 @@ fn main() { let _: String = repeat(Box::new(S)).take(count).collect(); let _: String = Cow::Borrowed("test").repeat(count); + //~^ manual_str_repeat let x = "x".to_owned(); let _: String = x.repeat(count); + //~^ manual_str_repeat let x = 'x'; // Don't lint, not char literal @@ -61,4 +70,5 @@ fn _msrv_1_15() { #[clippy::msrv = "1.16"] fn _msrv_1_16() { let _: String = "test".repeat(10); + //~^ manual_str_repeat } diff --git a/tests/ui/manual_str_repeat.rs b/tests/ui/manual_str_repeat.rs index 686ed4fee7d1..38d2eb4fcad8 100644 --- a/tests/ui/manual_str_repeat.rs +++ b/tests/ui/manual_str_repeat.rs @@ -6,13 +6,18 @@ use std::iter::repeat; fn main() { let _: String = std::iter::repeat("test").take(10).collect(); + //~^ manual_str_repeat let _: String = std::iter::repeat('x').take(10).collect(); + //~^ manual_str_repeat let _: String = std::iter::repeat('\'').take(10).collect(); + //~^ manual_str_repeat let _: String = std::iter::repeat('"').take(10).collect(); + //~^ manual_str_repeat let x = "test"; let count = 10; let _ = repeat(x).take(count + 2).collect::(); + //~^ manual_str_repeat macro_rules! m { ($e:expr) => {{ $e }}; @@ -22,6 +27,7 @@ fn main() { let x = &x; let _: String = repeat(*x).take(count).collect(); + //~^ manual_str_repeat macro_rules! repeat_m { ($e:expr) => {{ repeat($e) }}; @@ -31,6 +37,7 @@ fn main() { let x: Box = Box::from("test"); let _: String = repeat(x).take(count).collect(); + //~^ manual_str_repeat #[derive(Clone)] struct S; @@ -43,9 +50,11 @@ fn main() { let _: String = repeat(Box::new(S)).take(count).collect(); let _: String = repeat(Cow::Borrowed("test")).take(count).collect(); + //~^ manual_str_repeat let x = "x".to_owned(); let _: String = repeat(x).take(count).collect(); + //~^ manual_str_repeat let x = 'x'; // Don't lint, not char literal @@ -61,4 +70,5 @@ fn _msrv_1_15() { #[clippy::msrv = "1.16"] fn _msrv_1_16() { let _: String = std::iter::repeat("test").take(10).collect(); + //~^ manual_str_repeat } diff --git a/tests/ui/manual_str_repeat.stderr b/tests/ui/manual_str_repeat.stderr index d4f8786fb5f1..7998c3f6d97c 100644 --- a/tests/ui/manual_str_repeat.stderr +++ b/tests/ui/manual_str_repeat.stderr @@ -8,55 +8,55 @@ LL | let _: String = std::iter::repeat("test").take(10).collect(); = help: to override `-D warnings` add `#[allow(clippy::manual_str_repeat)]` error: manual implementation of `str::repeat` using iterators - --> tests/ui/manual_str_repeat.rs:9:21 + --> tests/ui/manual_str_repeat.rs:10:21 | LL | let _: String = std::iter::repeat('x').take(10).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"x".repeat(10)` error: manual implementation of `str::repeat` using iterators - --> tests/ui/manual_str_repeat.rs:10:21 + --> tests/ui/manual_str_repeat.rs:12:21 | LL | let _: String = std::iter::repeat('\'').take(10).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"'".repeat(10)` error: manual implementation of `str::repeat` using iterators - --> tests/ui/manual_str_repeat.rs:11:21 + --> tests/ui/manual_str_repeat.rs:14:21 | LL | let _: String = std::iter::repeat('"').take(10).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"\"".repeat(10)` error: manual implementation of `str::repeat` using iterators - --> tests/ui/manual_str_repeat.rs:15:13 + --> tests/ui/manual_str_repeat.rs:19:13 | LL | let _ = repeat(x).take(count + 2).collect::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count + 2)` error: manual implementation of `str::repeat` using iterators - --> tests/ui/manual_str_repeat.rs:24:21 + --> tests/ui/manual_str_repeat.rs:29:21 | LL | let _: String = repeat(*x).take(count).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*x).repeat(count)` error: manual implementation of `str::repeat` using iterators - --> tests/ui/manual_str_repeat.rs:33:21 + --> tests/ui/manual_str_repeat.rs:39:21 | LL | let _: String = repeat(x).take(count).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)` error: manual implementation of `str::repeat` using iterators - --> tests/ui/manual_str_repeat.rs:45:21 + --> tests/ui/manual_str_repeat.rs:52:21 | LL | let _: String = repeat(Cow::Borrowed("test")).take(count).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Cow::Borrowed("test").repeat(count)` error: manual implementation of `str::repeat` using iterators - --> tests/ui/manual_str_repeat.rs:48:21 + --> tests/ui/manual_str_repeat.rs:56:21 | LL | let _: String = repeat(x).take(count).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)` error: manual implementation of `str::repeat` using iterators - --> tests/ui/manual_str_repeat.rs:63:21 + --> tests/ui/manual_str_repeat.rs:72:21 | LL | let _: String = std::iter::repeat("test").take(10).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"test".repeat(10)` diff --git a/tests/ui/manual_string_new.fixed b/tests/ui/manual_string_new.fixed index 2d4c5a029153..02eeb603891a 100644 --- a/tests/ui/manual_string_new.fixed +++ b/tests/ui/manual_string_new.fixed @@ -12,12 +12,15 @@ macro_rules! create_strings_from_macro { fn main() { // Method calls let _ = String::new(); + //~^ manual_string_new let _ = "no warning".to_string(); let _ = String::new(); + //~^ manual_string_new let _ = "no warning".to_owned(); let _: String = String::new(); + //~^ manual_string_new let _: String = "no warning".into(); let _: SomeOtherStruct = "no warning".into(); @@ -25,26 +28,32 @@ fn main() { // Calls let _ = String::new(); + //~^ manual_string_new let _ = String::new(); + //~^ manual_string_new let _ = String::from("no warning"); let _ = SomeOtherStruct::from("no warning"); let _ = SomeOtherStruct::from(""); // Again: no warning. let _ = String::new(); + //~^ manual_string_new let _ = String::try_from("no warning").unwrap(); let _ = String::try_from("no warning").expect("this should not warn"); let _ = SomeOtherStruct::try_from("no warning").unwrap(); let _ = SomeOtherStruct::try_from("").unwrap(); // Again: no warning. let _: String = String::new(); + //~^ manual_string_new let _: String = From::from("no warning"); let _: SomeOtherStruct = From::from("no warning"); let _: SomeOtherStruct = From::from(""); // Again: no warning. let _: String = String::new(); + //~^ manual_string_new let _: String = TryFrom::try_from("no warning").unwrap(); let _: String = TryFrom::try_from("no warning").expect("this should not warn"); let _: String = String::new(); + //~^ manual_string_new let _: SomeOtherStruct = TryFrom::try_from("no_warning").unwrap(); let _: SomeOtherStruct = TryFrom::try_from("").unwrap(); // Again: no warning. diff --git a/tests/ui/manual_string_new.rs b/tests/ui/manual_string_new.rs index 20f0be6aaf97..fb4f58abad26 100644 --- a/tests/ui/manual_string_new.rs +++ b/tests/ui/manual_string_new.rs @@ -12,12 +12,15 @@ macro_rules! create_strings_from_macro { fn main() { // Method calls let _ = "".to_string(); + //~^ manual_string_new let _ = "no warning".to_string(); let _ = "".to_owned(); + //~^ manual_string_new let _ = "no warning".to_owned(); let _: String = "".into(); + //~^ manual_string_new let _: String = "no warning".into(); let _: SomeOtherStruct = "no warning".into(); @@ -25,26 +28,32 @@ fn main() { // Calls let _ = String::from(""); + //~^ manual_string_new let _ = ::from(""); + //~^ manual_string_new let _ = String::from("no warning"); let _ = SomeOtherStruct::from("no warning"); let _ = SomeOtherStruct::from(""); // Again: no warning. let _ = String::try_from("").unwrap(); + //~^ manual_string_new let _ = String::try_from("no warning").unwrap(); let _ = String::try_from("no warning").expect("this should not warn"); let _ = SomeOtherStruct::try_from("no warning").unwrap(); let _ = SomeOtherStruct::try_from("").unwrap(); // Again: no warning. let _: String = From::from(""); + //~^ manual_string_new let _: String = From::from("no warning"); let _: SomeOtherStruct = From::from("no warning"); let _: SomeOtherStruct = From::from(""); // Again: no warning. let _: String = TryFrom::try_from("").unwrap(); + //~^ manual_string_new let _: String = TryFrom::try_from("no warning").unwrap(); let _: String = TryFrom::try_from("no warning").expect("this should not warn"); let _: String = TryFrom::try_from("").expect("this should warn"); + //~^ manual_string_new let _: SomeOtherStruct = TryFrom::try_from("no_warning").unwrap(); let _: SomeOtherStruct = TryFrom::try_from("").unwrap(); // Again: no warning. diff --git a/tests/ui/manual_string_new.stderr b/tests/ui/manual_string_new.stderr index 6b434f405d31..2d98501f62d4 100644 --- a/tests/ui/manual_string_new.stderr +++ b/tests/ui/manual_string_new.stderr @@ -8,49 +8,49 @@ LL | let _ = "".to_string(); = help: to override `-D warnings` add `#[allow(clippy::manual_string_new)]` error: empty String is being created manually - --> tests/ui/manual_string_new.rs:17:13 + --> tests/ui/manual_string_new.rs:18:13 | LL | let _ = "".to_owned(); | ^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> tests/ui/manual_string_new.rs:20:21 + --> tests/ui/manual_string_new.rs:22:21 | LL | let _: String = "".into(); | ^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> tests/ui/manual_string_new.rs:27:13 + --> tests/ui/manual_string_new.rs:30:13 | LL | let _ = String::from(""); | ^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> tests/ui/manual_string_new.rs:28:13 + --> tests/ui/manual_string_new.rs:32:13 | LL | let _ = ::from(""); | ^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> tests/ui/manual_string_new.rs:33:13 + --> tests/ui/manual_string_new.rs:38:13 | LL | let _ = String::try_from("").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> tests/ui/manual_string_new.rs:39:21 + --> tests/ui/manual_string_new.rs:45:21 | LL | let _: String = From::from(""); | ^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> tests/ui/manual_string_new.rs:44:21 + --> tests/ui/manual_string_new.rs:51:21 | LL | let _: String = TryFrom::try_from("").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` error: empty String is being created manually - --> tests/ui/manual_string_new.rs:47:21 + --> tests/ui/manual_string_new.rs:55:21 | LL | let _: String = TryFrom::try_from("").expect("this should warn"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()` diff --git a/tests/ui/manual_strip.rs b/tests/ui/manual_strip.rs index 8bd0300e6bcc..d3dbf301d9c0 100644 --- a/tests/ui/manual_strip.rs +++ b/tests/ui/manual_strip.rs @@ -5,7 +5,8 @@ fn main() { if s.starts_with("ab") { str::to_string(&s["ab".len()..]); - //~^ ERROR: stripping a prefix manually + //~^ manual_strip + s["ab".len()..].to_string(); str::to_string(&s[2..]); @@ -14,7 +15,8 @@ fn main() { if s.ends_with("bc") { str::to_string(&s[..s.len() - "bc".len()]); - //~^ ERROR: stripping a suffix manually + //~^ manual_strip + s[..s.len() - "bc".len()].to_string(); str::to_string(&s[..s.len() - 2]); @@ -24,7 +26,8 @@ fn main() { // Character patterns if s.starts_with('a') { str::to_string(&s[1..]); - //~^ ERROR: stripping a prefix manually + //~^ manual_strip + s[1..].to_string(); } @@ -32,14 +35,16 @@ fn main() { let prefix = "ab"; if s.starts_with(prefix) { str::to_string(&s[prefix.len()..]); - //~^ ERROR: stripping a prefix manually + //~^ manual_strip + } // Constant prefix const PREFIX: &str = "ab"; if s.starts_with(PREFIX) { str::to_string(&s[PREFIX.len()..]); - //~^ ERROR: stripping a prefix manually + //~^ manual_strip + str::to_string(&s[2..]); } @@ -47,14 +52,16 @@ fn main() { const TARGET: &str = "abc"; if TARGET.starts_with(prefix) { str::to_string(&TARGET[prefix.len()..]); - //~^ ERROR: stripping a prefix manually + //~^ manual_strip + } // String target - not mutated. let s1: String = "abc".into(); if s1.starts_with("ab") { s1[2..].to_uppercase(); - //~^ ERROR: stripping a prefix manually + //~^ manual_strip + } // String target - mutated. (Don't lint.) @@ -85,6 +92,7 @@ fn msrv_1_45() { let s = "abc"; if s.starts_with('a') { s[1..].to_string(); - //~^ ERROR: stripping a prefix manually + //~^ manual_strip + } } diff --git a/tests/ui/manual_strip.stderr b/tests/ui/manual_strip.stderr index a70c988a0549..78967e521baa 100644 --- a/tests/ui/manual_strip.stderr +++ b/tests/ui/manual_strip.stderr @@ -16,6 +16,7 @@ help: try using the `strip_prefix` method LL ~ if let Some() = s.strip_prefix("ab") { LL ~ str::to_string(); LL | +LL | LL ~ .to_string(); LL | LL ~ str::to_string(); @@ -23,13 +24,13 @@ LL ~ .to_string(); | error: stripping a suffix manually - --> tests/ui/manual_strip.rs:16:24 + --> tests/ui/manual_strip.rs:17:24 | LL | str::to_string(&s[..s.len() - "bc".len()]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the suffix was tested here - --> tests/ui/manual_strip.rs:15:5 + --> tests/ui/manual_strip.rs:16:5 | LL | if s.ends_with("bc") { | ^^^^^^^^^^^^^^^^^^^^^ @@ -38,6 +39,7 @@ help: try using the `strip_suffix` method LL ~ if let Some() = s.strip_suffix("bc") { LL ~ str::to_string(); LL | +LL | LL ~ .to_string(); LL | LL ~ str::to_string(); @@ -45,13 +47,13 @@ LL ~ .to_string(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:26:24 + --> tests/ui/manual_strip.rs:28:24 | LL | str::to_string(&s[1..]); | ^^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:25:5 + --> tests/ui/manual_strip.rs:27:5 | LL | if s.starts_with('a') { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -60,17 +62,18 @@ help: try using the `strip_prefix` method LL ~ if let Some() = s.strip_prefix('a') { LL ~ str::to_string(); LL | +LL | LL ~ .to_string(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:34:24 + --> tests/ui/manual_strip.rs:37:24 | LL | str::to_string(&s[prefix.len()..]); | ^^^^^^^^^^^^^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:33:5 + --> tests/ui/manual_strip.rs:36:5 | LL | if s.starts_with(prefix) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,13 +84,13 @@ LL ~ str::to_string(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:41:24 + --> tests/ui/manual_strip.rs:45:24 | LL | str::to_string(&s[PREFIX.len()..]); | ^^^^^^^^^^^^^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:40:5 + --> tests/ui/manual_strip.rs:44:5 | LL | if s.starts_with(PREFIX) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,17 +99,18 @@ help: try using the `strip_prefix` method LL ~ if let Some() = s.strip_prefix(PREFIX) { LL ~ str::to_string(); LL | +LL | LL ~ str::to_string(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:49:24 + --> tests/ui/manual_strip.rs:54:24 | LL | str::to_string(&TARGET[prefix.len()..]); | ^^^^^^^^^^^^^^^^^^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:48:5 + --> tests/ui/manual_strip.rs:53:5 | LL | if TARGET.starts_with(prefix) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -117,13 +121,13 @@ LL ~ str::to_string(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:56:9 + --> tests/ui/manual_strip.rs:62:9 | LL | s1[2..].to_uppercase(); | ^^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:55:5 + --> tests/ui/manual_strip.rs:61:5 | LL | if s1.starts_with("ab") { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -134,13 +138,13 @@ LL ~ .to_uppercase(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:87:9 + --> tests/ui/manual_strip.rs:94:9 | LL | s[1..].to_string(); | ^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:86:5 + --> tests/ui/manual_strip.rs:93:5 | LL | if s.starts_with('a') { | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/manual_swap_auto_fix.rs b/tests/ui/manual_swap_auto_fix.rs index 702a9e67d3d5..c9880e651cd7 100644 --- a/tests/ui/manual_swap_auto_fix.rs +++ b/tests/ui/manual_swap_auto_fix.rs @@ -4,7 +4,8 @@ fn swap1() { let mut v = [3, 2, 1, 0]; let index = v[0]; - //~^ ERROR: this looks like you are swapping elements of `v` manually + //~^ manual_swap + v[0] = v[index]; v[index] = index; } @@ -12,6 +13,7 @@ fn swap1() { fn swap2() { let mut v = [3, 2, 1, 0]; let tmp = v[0]; + //~^ manual_swap v[0] = v[1]; v[1] = tmp; // check not found in this scope. @@ -23,6 +25,7 @@ fn swap3() { let i1 = 0; let i2 = 1; let temp = v[i1]; + //~^ manual_swap v[i1] = v[i2]; v[i2] = temp; } @@ -32,6 +35,7 @@ fn swap4() { let i1 = 0; let i2 = 1; let temp = v[i1]; + //~^ manual_swap v[i1] = v[i2 + 1]; v[i2 + 1] = temp; } @@ -41,6 +45,7 @@ fn swap5() { let i1 = 0; let i2 = 1; let temp = v[i1]; + //~^ manual_swap v[i1] = v[i2 + 1]; v[i2 + 1] = temp; } @@ -48,7 +53,8 @@ fn swap5() { fn swap6() { let mut v = [0, 1, 2, 3]; let index = v[0]; - //~^ ERROR: this looks like you are swapping elements of `v` manually + //~^ manual_swap + v[0] = v[index + 1]; v[index + 1] = index; } @@ -58,6 +64,7 @@ fn swap7() { let i1 = 0; let i2 = 6; let tmp = v[i1 * 3]; + //~^ manual_swap v[i1 * 3] = v[i2 / 2]; v[i2 / 2] = tmp; } @@ -67,6 +74,7 @@ fn swap8() { let i1 = 1; let i2 = 1; let tmp = v[i1 + i2]; + //~^ manual_swap v[i1 + i2] = v[i2]; v[i2] = tmp; } diff --git a/tests/ui/manual_swap_auto_fix.stderr b/tests/ui/manual_swap_auto_fix.stderr index eecfcd3977be..7ab898fcc726 100644 --- a/tests/ui/manual_swap_auto_fix.stderr +++ b/tests/ui/manual_swap_auto_fix.stderr @@ -3,6 +3,7 @@ error: this looks like you are swapping elements of `v` manually | LL | / let index = v[0]; LL | | +LL | | LL | | v[0] = v[index]; LL | | v[index] = index; | |_____________________^ @@ -16,9 +17,10 @@ LL + v.swap(0, index); | error: this looks like you are swapping elements of `v` manually - --> tests/ui/manual_swap_auto_fix.rs:14:5 + --> tests/ui/manual_swap_auto_fix.rs:15:5 | LL | / let tmp = v[0]; +LL | | LL | | v[0] = v[1]; LL | | v[1] = tmp; | |_______________^ @@ -30,34 +32,38 @@ LL + v.swap(0, 1); | error: this looks like you are swapping elements of `v` manually - --> tests/ui/manual_swap_auto_fix.rs:25:5 + --> tests/ui/manual_swap_auto_fix.rs:27:5 | LL | / let temp = v[i1]; +LL | | LL | | v[i1] = v[i2]; LL | | v[i2] = temp; | |_________________^ help: try: `v.swap(i1, i2);` error: this looks like you are swapping elements of `v` manually - --> tests/ui/manual_swap_auto_fix.rs:34:5 + --> tests/ui/manual_swap_auto_fix.rs:37:5 | LL | / let temp = v[i1]; +LL | | LL | | v[i1] = v[i2 + 1]; LL | | v[i2 + 1] = temp; | |_____________________^ help: try: `v.swap(i1, i2 + 1);` error: this looks like you are swapping elements of `v` manually - --> tests/ui/manual_swap_auto_fix.rs:43:5 + --> tests/ui/manual_swap_auto_fix.rs:47:5 | LL | / let temp = v[i1]; +LL | | LL | | v[i1] = v[i2 + 1]; LL | | v[i2 + 1] = temp; | |_____________________^ help: try: `v.swap(i1, i2 + 1);` error: this looks like you are swapping elements of `v` manually - --> tests/ui/manual_swap_auto_fix.rs:50:5 + --> tests/ui/manual_swap_auto_fix.rs:55:5 | LL | / let index = v[0]; LL | | +LL | | LL | | v[0] = v[index + 1]; LL | | v[index + 1] = index; | |_________________________^ @@ -69,17 +75,19 @@ LL + v.swap(0, index + 1); | error: this looks like you are swapping elements of `v` manually - --> tests/ui/manual_swap_auto_fix.rs:60:5 + --> tests/ui/manual_swap_auto_fix.rs:66:5 | LL | / let tmp = v[i1 * 3]; +LL | | LL | | v[i1 * 3] = v[i2 / 2]; LL | | v[i2 / 2] = tmp; | |____________________^ help: try: `v.swap(i1 * 3, i2 / 2);` error: this looks like you are swapping elements of `v` manually - --> tests/ui/manual_swap_auto_fix.rs:69:5 + --> tests/ui/manual_swap_auto_fix.rs:76:5 | LL | / let tmp = v[i1 + i2]; +LL | | LL | | v[i1 + i2] = v[i2]; LL | | v[i2] = tmp; | |________________^ help: try: `v.swap(i1 + i2, i2);` diff --git a/tests/ui/manual_try_fold.rs b/tests/ui/manual_try_fold.rs index 7299d7cf9862..749fc7c7b683 100644 --- a/tests/ui/manual_try_fold.rs +++ b/tests/ui/manual_try_fold.rs @@ -57,13 +57,16 @@ fn main() { [1, 2, 3] .iter() .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) + //~^ manual_try_fold .unwrap(); [1, 2, 3] .iter() .fold(NotOption(0i32, 0i32), |sum, i| NotOption(0i32, 0i32)); + //~^ manual_try_fold [1, 2, 3] .iter() .fold(NotOptionButWorse(0i32), |sum, i| NotOptionButWorse(0i32)); + //~^ manual_try_fold // Do not lint [1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)).unwrap(); [1, 2, 3].iter().fold(0i32, |sum, i| sum + i); @@ -94,6 +97,7 @@ fn msrv_juust_right() { [1, 2, 3] .iter() .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) + //~^ manual_try_fold .unwrap(); } diff --git a/tests/ui/manual_try_fold.stderr b/tests/ui/manual_try_fold.stderr index bc075e87d71f..f2740187878f 100644 --- a/tests/ui/manual_try_fold.stderr +++ b/tests/ui/manual_try_fold.stderr @@ -8,19 +8,19 @@ LL | .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) = help: to override `-D warnings` add `#[allow(clippy::manual_try_fold)]` error: usage of `Iterator::fold` on a type that implements `Try` - --> tests/ui/manual_try_fold.rs:63:10 + --> tests/ui/manual_try_fold.rs:64:10 | LL | .fold(NotOption(0i32, 0i32), |sum, i| NotOption(0i32, 0i32)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(..., |sum, i| ...)` error: usage of `Iterator::fold` on a type that implements `Try` - --> tests/ui/manual_try_fold.rs:66:10 + --> tests/ui/manual_try_fold.rs:68:10 | LL | .fold(NotOptionButWorse(0i32), |sum, i| NotOptionButWorse(0i32)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)` error: usage of `Iterator::fold` on a type that implements `Try` - --> tests/ui/manual_try_fold.rs:96:10 + --> tests/ui/manual_try_fold.rs:99:10 | LL | .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)` diff --git a/tests/ui/manual_unwrap_or.rs b/tests/ui/manual_unwrap_or.rs index cdbe51a41212..80a677d726ef 100644 --- a/tests/ui/manual_unwrap_or.rs +++ b/tests/ui/manual_unwrap_or.rs @@ -9,18 +9,21 @@ fn option_unwrap_or() { // int case match Some(1) { + //~^ manual_unwrap_or Some(i) => i, None => 42, }; // int case reversed match Some(1) { + //~^ manual_unwrap_or None => 42, Some(i) => i, }; // richer none expr match Some(1) { + //~^ manual_unwrap_or Some(i) => i, None => 1 + 42, }; @@ -28,6 +31,7 @@ fn option_unwrap_or() { // multiline case #[rustfmt::skip] match Some(1) { + //~^ manual_unwrap_or Some(i) => i, None => { 42 + 42 @@ -38,6 +42,7 @@ fn option_unwrap_or() { // string case match Some("Bob") { + //~^ manual_unwrap_or Some(i) => i, None => "Alice", }; @@ -85,6 +90,7 @@ fn option_unwrap_or() { }; if let Some(x) = Some(1) { + //~^ manual_unwrap_or x } else { 42 @@ -118,6 +124,7 @@ fn option_unwrap_or() { fn result_unwrap_or() { // int case match Ok::(1) { + //~^ manual_unwrap_or Ok(i) => i, Err(_) => 42, }; @@ -125,12 +132,14 @@ fn result_unwrap_or() { // int case, scrutinee is a binding let a = Ok::(1); match a { + //~^ manual_unwrap_or Ok(i) => i, Err(_) => 42, }; // int case, suggestion must surround Result expr with parentheses match Ok(1) as Result { + //~^ manual_unwrap_or Ok(i) => i, Err(_) => 42, }; @@ -144,18 +153,21 @@ fn result_unwrap_or() { } let s = S {}; match s.method() { + //~^ manual_unwrap_or Some(i) => i, None => 42, }; // int case reversed match Ok::(1) { + //~^ manual_unwrap_or Err(_) => 42, Ok(i) => i, }; // richer none expr match Ok::(1) { + //~^ manual_unwrap_or Ok(i) => i, Err(_) => 1 + 42, }; @@ -163,6 +175,7 @@ fn result_unwrap_or() { // multiline case #[rustfmt::skip] match Ok::(1) { + //~^ manual_unwrap_or Ok(i) => i, Err(_) => { 42 + 42 @@ -173,6 +186,7 @@ fn result_unwrap_or() { // string case match Ok::<&str, &str>("Bob") { + //~^ manual_unwrap_or Ok(i) => i, Err(_) => "Alice", }; @@ -209,6 +223,7 @@ fn result_unwrap_or() { }; if let Ok(x) = Ok::(1) { + //~^ manual_unwrap_or x } else { 42 @@ -263,6 +278,7 @@ mod issue6965 { fn test() { let _ = match some_macro!() { + //~^ manual_unwrap_or Some(val) => val, None => 0, }; diff --git a/tests/ui/manual_unwrap_or.stderr b/tests/ui/manual_unwrap_or.stderr index a5a64ecb9a3e..a5deb55786e9 100644 --- a/tests/ui/manual_unwrap_or.stderr +++ b/tests/ui/manual_unwrap_or.stderr @@ -2,6 +2,7 @@ error: this pattern reimplements `Option::unwrap_or` --> tests/ui/manual_unwrap_or.rs:11:5 | LL | / match Some(1) { +LL | | LL | | Some(i) => i, LL | | None => 42, LL | | }; @@ -11,30 +12,32 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or)]` error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:17:5 + --> tests/ui/manual_unwrap_or.rs:18:5 | LL | / match Some(1) { +LL | | LL | | None => 42, LL | | Some(i) => i, LL | | }; | |_____^ help: replace with: `Some(1).unwrap_or(42)` error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:23:5 + --> tests/ui/manual_unwrap_or.rs:25:5 | LL | / match Some(1) { +LL | | LL | | Some(i) => i, LL | | None => 1 + 42, LL | | }; | |_____^ help: replace with: `Some(1).unwrap_or(1 + 42)` error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:30:5 + --> tests/ui/manual_unwrap_or.rs:33:5 | LL | / match Some(1) { +LL | | LL | | Some(i) => i, LL | | None => { -LL | | 42 + 42 ... | LL | | }; | |_____^ @@ -49,18 +52,20 @@ LL ~ }); | error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:40:5 + --> tests/ui/manual_unwrap_or.rs:44:5 | LL | / match Some("Bob") { +LL | | LL | | Some(i) => i, LL | | None => "Alice", LL | | }; | |_____^ help: replace with: `Some("Bob").unwrap_or("Alice")` error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:87:5 + --> tests/ui/manual_unwrap_or.rs:92:5 | LL | / if let Some(x) = Some(1) { +LL | | LL | | x LL | | } else { LL | | 42 @@ -68,66 +73,72 @@ LL | | }; | |_____^ help: replace with: `Some(1).unwrap_or(42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:120:5 + --> tests/ui/manual_unwrap_or.rs:126:5 | LL | / match Ok::(1) { +LL | | LL | | Ok(i) => i, LL | | Err(_) => 42, LL | | }; | |_____^ help: replace with: `Ok::(1).unwrap_or(42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:127:5 + --> tests/ui/manual_unwrap_or.rs:134:5 | LL | / match a { +LL | | LL | | Ok(i) => i, LL | | Err(_) => 42, LL | | }; | |_____^ help: replace with: `a.unwrap_or(42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:133:5 + --> tests/ui/manual_unwrap_or.rs:141:5 | LL | / match Ok(1) as Result { +LL | | LL | | Ok(i) => i, LL | | Err(_) => 42, LL | | }; | |_____^ help: replace with: `(Ok(1) as Result).unwrap_or(42)` error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:146:5 + --> tests/ui/manual_unwrap_or.rs:155:5 | LL | / match s.method() { +LL | | LL | | Some(i) => i, LL | | None => 42, LL | | }; | |_____^ help: replace with: `s.method().unwrap_or(42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:152:5 + --> tests/ui/manual_unwrap_or.rs:162:5 | LL | / match Ok::(1) { +LL | | LL | | Err(_) => 42, LL | | Ok(i) => i, LL | | }; | |_____^ help: replace with: `Ok::(1).unwrap_or(42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:158:5 + --> tests/ui/manual_unwrap_or.rs:169:5 | LL | / match Ok::(1) { +LL | | LL | | Ok(i) => i, LL | | Err(_) => 1 + 42, LL | | }; | |_____^ help: replace with: `Ok::(1).unwrap_or(1 + 42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:165:5 + --> tests/ui/manual_unwrap_or.rs:177:5 | LL | / match Ok::(1) { +LL | | LL | | Ok(i) => i, LL | | Err(_) => { -LL | | 42 + 42 ... | LL | | }; | |_____^ @@ -142,18 +153,20 @@ LL ~ }); | error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:175:5 + --> tests/ui/manual_unwrap_or.rs:188:5 | LL | / match Ok::<&str, &str>("Bob") { +LL | | LL | | Ok(i) => i, LL | | Err(_) => "Alice", LL | | }; | |_____^ help: replace with: `Ok::<&str, &str>("Bob").unwrap_or("Alice")` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:211:5 + --> tests/ui/manual_unwrap_or.rs:225:5 | LL | / if let Ok(x) = Ok::(1) { +LL | | LL | | x LL | | } else { LL | | 42 @@ -161,10 +174,11 @@ LL | | }; | |_____^ help: replace with: `Ok::(1).unwrap_or(42)` error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:265:17 + --> tests/ui/manual_unwrap_or.rs:280:17 | LL | let _ = match some_macro!() { | _________________^ +LL | | LL | | Some(val) => val, LL | | None => 0, LL | | }; diff --git a/tests/ui/manual_unwrap_or_default.rs b/tests/ui/manual_unwrap_or_default.rs index 649f65c89fb0..1ef07cf84bde 100644 --- a/tests/ui/manual_unwrap_or_default.rs +++ b/tests/ui/manual_unwrap_or_default.rs @@ -4,35 +4,40 @@ fn main() { let x: Option> = None; match x { - //~^ ERROR: match can be simplified with `.unwrap_or_default()` + //~^ manual_unwrap_or_default + Some(v) => v, None => Vec::default(), }; let x: Option> = None; match x { - //~^ ERROR: match can be simplified with `.unwrap_or_default()` + //~^ manual_unwrap_or_default + Some(v) => v, _ => Vec::default(), }; let x: Option = None; match x { - //~^ ERROR: match can be simplified with `.unwrap_or_default()` + //~^ manual_unwrap_or_default + Some(v) => v, None => String::new(), }; let x: Option> = None; match x { - //~^ ERROR: match can be simplified with `.unwrap_or_default()` + //~^ manual_unwrap_or_default + None => Vec::default(), Some(v) => v, }; let x: Option> = None; if let Some(v) = x { - //~^ ERROR: if let can be simplified with `.unwrap_or_default()` + //~^ manual_unwrap_or_default + v } else { Vec::default() @@ -50,14 +55,16 @@ fn main() { let x: Result = Ok(String::new()); match x { - //~^ ERROR: match can be simplified with `.unwrap_or_default()` + //~^ manual_unwrap_or_default + Ok(v) => v, Err(_) => String::new(), }; let x: Result = Ok(String::new()); if let Ok(v) = x { - //~^ ERROR: if let can be simplified with `.unwrap_or_default()` + //~^ manual_unwrap_or_default + v } else { String::new() @@ -69,6 +76,7 @@ unsafe fn no_deref_ptr(a: Option, b: *const Option) -> i32 { match a { // `*b` being correct depends on `a == Some(_)` Some(_) => match *b { + //~^ manual_unwrap_or_default Some(v) => v, _ => 0, }, diff --git a/tests/ui/manual_unwrap_or_default.stderr b/tests/ui/manual_unwrap_or_default.stderr index 9e3b1be5cb9b..ff388ba85d51 100644 --- a/tests/ui/manual_unwrap_or_default.stderr +++ b/tests/ui/manual_unwrap_or_default.stderr @@ -3,6 +3,7 @@ error: match can be simplified with `.unwrap_or_default()` | LL | / match x { LL | | +LL | | LL | | Some(v) => v, LL | | None => Vec::default(), LL | | }; @@ -12,40 +13,44 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or_default)]` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:13:5 + --> tests/ui/manual_unwrap_or_default.rs:14:5 | LL | / match x { LL | | +LL | | LL | | Some(v) => v, LL | | _ => Vec::default(), LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:20:5 + --> tests/ui/manual_unwrap_or_default.rs:22:5 | LL | / match x { LL | | +LL | | LL | | Some(v) => v, LL | | None => String::new(), LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:27:5 + --> tests/ui/manual_unwrap_or_default.rs:30:5 | LL | / match x { LL | | +LL | | LL | | None => Vec::default(), LL | | Some(v) => v, LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: if let can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:34:5 + --> tests/ui/manual_unwrap_or_default.rs:38:5 | LL | / if let Some(v) = x { LL | | +LL | | LL | | v LL | | } else { LL | | Vec::default() @@ -53,20 +58,22 @@ LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:52:5 + --> tests/ui/manual_unwrap_or_default.rs:57:5 | LL | / match x { LL | | +LL | | LL | | Ok(v) => v, LL | | Err(_) => String::new(), LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: if let can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:59:5 + --> tests/ui/manual_unwrap_or_default.rs:65:5 | LL | / if let Ok(v) = x { LL | | +LL | | LL | | v LL | | } else { LL | | String::new() @@ -74,10 +81,11 @@ LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:71:20 + --> tests/ui/manual_unwrap_or_default.rs:78:20 | LL | Some(_) => match *b { | ____________________^ +LL | | LL | | Some(v) => v, LL | | _ => 0, LL | | }, diff --git a/tests/ui/manual_unwrap_or_default_unfixable.rs b/tests/ui/manual_unwrap_or_default_unfixable.rs index acc54b52816c..fb61d639f9c0 100644 --- a/tests/ui/manual_unwrap_or_default_unfixable.rs +++ b/tests/ui/manual_unwrap_or_default_unfixable.rs @@ -3,13 +3,17 @@ fn issue_12670() { // no auto: type not found #[allow(clippy::match_result_ok)] let _ = if let Some(x) = "1".parse().ok() { + //~^ manual_unwrap_or_default x } else { i32::default() }; let _ = if let Some(x) = None { x } else { i32::default() }; + //~^ manual_unwrap_or_default // auto fix with unwrap_or_default let a: Option = None; let _ = if let Some(x) = a { x } else { i32::default() }; + //~^ manual_unwrap_or_default let _ = if let Some(x) = Some(99) { x } else { i32::default() }; + //~^ manual_unwrap_or_default } diff --git a/tests/ui/manual_unwrap_or_default_unfixable.stderr b/tests/ui/manual_unwrap_or_default_unfixable.stderr index 3849d33cf254..94a7c2f5d2c3 100644 --- a/tests/ui/manual_unwrap_or_default_unfixable.stderr +++ b/tests/ui/manual_unwrap_or_default_unfixable.stderr @@ -3,6 +3,7 @@ error: if let can be simplified with `.unwrap_or_default()` | LL | let _ = if let Some(x) = "1".parse().ok() { | _____________^ +LL | | LL | | x LL | | } else { LL | | i32::default() @@ -13,19 +14,19 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or_default)]` error: if let can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default_unfixable.rs:10:13 + --> tests/ui/manual_unwrap_or_default_unfixable.rs:11:13 | LL | let _ = if let Some(x) = None { x } else { i32::default() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `None::.unwrap_or_default()` error: if let can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default_unfixable.rs:13:13 + --> tests/ui/manual_unwrap_or_default_unfixable.rs:15:13 | LL | let _ = if let Some(x) = a { x } else { i32::default() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.unwrap_or_default()` error: if let can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default_unfixable.rs:14:13 + --> tests/ui/manual_unwrap_or_default_unfixable.rs:17:13 | LL | let _ = if let Some(x) = Some(99) { x } else { i32::default() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(99).unwrap_or_default()` diff --git a/tests/ui/manual_while_let_some.fixed b/tests/ui/manual_while_let_some.fixed index c70d258dfe6e..c0f6522d5fb8 100644 --- a/tests/ui/manual_while_let_some.fixed +++ b/tests/ui/manual_while_let_some.fixed @@ -19,6 +19,7 @@ fn main() { let mut numbers = vec![1, 2, 3, 4, 5]; while let Some(number) = numbers.pop() { + //~^ manual_while_let_some } let mut val = VecInStruct { @@ -27,14 +28,17 @@ fn main() { }; while let Some(number) = val.numbers.pop() { + //~^ manual_while_let_some } while let Some(element) = numbers.pop() { accept_i32(element); + //~^ manual_while_let_some } while let Some(element) = numbers.pop() { accept_i32(element); + //~^ manual_while_let_some } // This should not warn. It "conditionally" pops elements. @@ -78,14 +82,17 @@ fn main() { let mut numbers = vec![(0, 0), (1, 1), (2, 2)]; while let Some((a, b)) = numbers.pop() { + //~^ manual_while_let_some } while let Some(element) = numbers.pop() { accept_i32_tuple(element); + //~^ manual_while_let_some } let mut results = vec![Foo { a: 1, b: 2 }, Foo { a: 3, b: 4 }]; while let Some(Foo { a, b }) = results.pop() { + //~^ manual_while_let_some } } diff --git a/tests/ui/manual_while_let_some.rs b/tests/ui/manual_while_let_some.rs index 415bb5798667..f69eb66af1d7 100644 --- a/tests/ui/manual_while_let_some.rs +++ b/tests/ui/manual_while_let_some.rs @@ -19,6 +19,7 @@ fn main() { let mut numbers = vec![1, 2, 3, 4, 5]; while !numbers.is_empty() { let number = numbers.pop().unwrap(); + //~^ manual_while_let_some } let mut val = VecInStruct { @@ -27,14 +28,17 @@ fn main() { }; while !val.numbers.is_empty() { let number = val.numbers.pop().unwrap(); + //~^ manual_while_let_some } while !numbers.is_empty() { accept_i32(numbers.pop().unwrap()); + //~^ manual_while_let_some } while !numbers.is_empty() { accept_i32(numbers.pop().expect("")); + //~^ manual_while_let_some } // This should not warn. It "conditionally" pops elements. @@ -78,14 +82,17 @@ fn main() { let mut numbers = vec![(0, 0), (1, 1), (2, 2)]; while !numbers.is_empty() { let (a, b) = numbers.pop().unwrap(); + //~^ manual_while_let_some } while !numbers.is_empty() { accept_i32_tuple(numbers.pop().unwrap()); + //~^ manual_while_let_some } let mut results = vec![Foo { a: 1, b: 2 }, Foo { a: 3, b: 4 }]; while !results.is_empty() { let Foo { a, b } = results.pop().unwrap(); + //~^ manual_while_let_some } } diff --git a/tests/ui/manual_while_let_some.stderr b/tests/ui/manual_while_let_some.stderr index 8d444b80aaff..5f2fecb7a0b9 100644 --- a/tests/ui/manual_while_let_some.stderr +++ b/tests/ui/manual_while_let_some.stderr @@ -13,7 +13,7 @@ LL ~ | error: you seem to be trying to pop elements from a `Vec` in a loop - --> tests/ui/manual_while_let_some.rs:29:9 + --> tests/ui/manual_while_let_some.rs:30:9 | LL | let number = val.numbers.pop().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL ~ | error: you seem to be trying to pop elements from a `Vec` in a loop - --> tests/ui/manual_while_let_some.rs:33:20 + --> tests/ui/manual_while_let_some.rs:35:20 | LL | accept_i32(numbers.pop().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL ~ accept_i32(element); | error: you seem to be trying to pop elements from a `Vec` in a loop - --> tests/ui/manual_while_let_some.rs:37:20 + --> tests/ui/manual_while_let_some.rs:40:20 | LL | accept_i32(numbers.pop().expect("")); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL ~ accept_i32(element); | error: you seem to be trying to pop elements from a `Vec` in a loop - --> tests/ui/manual_while_let_some.rs:80:9 + --> tests/ui/manual_while_let_some.rs:84:9 | LL | let (a, b) = numbers.pop().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL ~ | error: you seem to be trying to pop elements from a `Vec` in a loop - --> tests/ui/manual_while_let_some.rs:84:26 + --> tests/ui/manual_while_let_some.rs:89:26 | LL | accept_i32_tuple(numbers.pop().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL ~ accept_i32_tuple(element); | error: you seem to be trying to pop elements from a `Vec` in a loop - --> tests/ui/manual_while_let_some.rs:89:9 + --> tests/ui/manual_while_let_some.rs:95:9 | LL | let Foo { a, b } = results.pop().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/many_single_char_names.rs b/tests/ui/many_single_char_names.rs index 68578340d90e..6e662e246061 100644 --- a/tests/ui/many_single_char_names.rs +++ b/tests/ui/many_single_char_names.rs @@ -3,10 +3,13 @@ fn bla() { let a: i32; - //~^ ERROR: 5 bindings with single-character names in scope - //~| NOTE: `-D clippy::many-single-char-names` implied by `-D warnings` - //~| ERROR: 6 bindings with single-character names in scope - //~| ERROR: 5 bindings with single-character names in scope + //~^ many_single_char_names + //~| many_single_char_names + //~| many_single_char_names + + + + let (b, c, d): (i32, i64, i16); { { @@ -32,11 +35,13 @@ fn bla() { } fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {} -//~^ ERROR: 8 bindings with single-character names in scope +//~^ many_single_char_names + fn bindings2() { let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!(); - //~^ ERROR: 8 bindings with single-character names in scope + //~^ many_single_char_names + } fn shadowing() { diff --git a/tests/ui/many_single_char_names.stderr b/tests/ui/many_single_char_names.stderr index 131836ef7c88..ad45f9a34fd4 100644 --- a/tests/ui/many_single_char_names.stderr +++ b/tests/ui/many_single_char_names.stderr @@ -40,13 +40,13 @@ LL | e => panic!(), | ^ error: 8 bindings with single-character names in scope - --> tests/ui/many_single_char_names.rs:34:13 + --> tests/ui/many_single_char_names.rs:37:13 | LL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {} | ^ ^ ^ ^ ^ ^ ^ ^ error: 8 bindings with single-character names in scope - --> tests/ui/many_single_char_names.rs:38:10 + --> tests/ui/many_single_char_names.rs:42:10 | LL | let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!(); | ^ ^ ^ ^ ^ ^ ^ ^ diff --git a/tests/ui/map_all_any_identity.fixed b/tests/ui/map_all_any_identity.fixed index c92462ab9c27..436b94bde0fc 100644 --- a/tests/ui/map_all_any_identity.fixed +++ b/tests/ui/map_all_any_identity.fixed @@ -3,9 +3,11 @@ fn main() { let _ = ["foo"].into_iter().any(|s| s == "foo"); //~^ map_all_any_identity + let _ = ["foo"].into_iter().all(|s| s == "foo"); //~^ map_all_any_identity + // // Do not lint // diff --git a/tests/ui/map_all_any_identity.rs b/tests/ui/map_all_any_identity.rs index 0e4a564ca046..68fe7b77f5c6 100644 --- a/tests/ui/map_all_any_identity.rs +++ b/tests/ui/map_all_any_identity.rs @@ -3,9 +3,11 @@ fn main() { let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a); //~^ map_all_any_identity + let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity); //~^ map_all_any_identity + // // Do not lint // diff --git a/tests/ui/map_all_any_identity.stderr b/tests/ui/map_all_any_identity.stderr index 98fdcc2a9393..869d81a73d65 100644 --- a/tests/ui/map_all_any_identity.stderr +++ b/tests/ui/map_all_any_identity.stderr @@ -12,7 +12,7 @@ LL | let _ = ["foo"].into_iter().any(|s| s == "foo"); | ~~~~~~~~~~~~~~~~~~~ error: usage of `.map(...).all(identity)` - --> tests/ui/map_all_any_identity.rs:6:33 + --> tests/ui/map_all_any_identity.rs:7:33 | LL | let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/map_clone.fixed b/tests/ui/map_clone.fixed index f9f8dc1a5123..5e2c31bb31df 100644 --- a/tests/ui/map_clone.fixed +++ b/tests/ui/map_clone.fixed @@ -12,11 +12,16 @@ fn main() { let _: Vec = vec![5_i8; 6].iter().copied().collect(); + //~^ map_clone let _: Vec = vec![String::new()].iter().cloned().collect(); + //~^ map_clone let _: Vec = vec![42, 43].iter().copied().collect(); + //~^ map_clone let _: Option = Some(Box::new(16)).map(|b| *b); let _: Option = Some(&16).copied(); + //~^ map_clone let _: Option = Some(&1).copied(); + //~^ map_clone // Don't lint these let v = vec![5_i8; 6]; @@ -28,6 +33,7 @@ fn main() { // Issue #498 let _ = std::env::args(); + //~^ map_clone // Issue #4824 item types that aren't references { @@ -67,22 +73,27 @@ fn main() { let x = Some(String::new()); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.cloned(); - //~^ ERROR: you are explicitly cloning with `.map()` + //~^ map_clone + let y = x.cloned(); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `cloned` method + //~^ map_clone + + let y = x.cloned(); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `cloned` method + //~^ map_clone + + let x: Option = Some(0); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.copied(); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `copied` method + //~^ map_clone + + let y = x.copied(); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `copied` method + //~^ map_clone + + // Should not suggest `copied` or `cloned` here since `T` is not a reference. let x: Option = Some(0); @@ -93,20 +104,24 @@ fn main() { let x: Result = Ok(String::new()); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.cloned(); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `cloned` method + //~^ map_clone + + let y = x.cloned(); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `cloned` method + //~^ map_clone + + let x: Result = Ok(0); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.copied(); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `copied` method + //~^ map_clone + + let y = x.copied(); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `copied` method + //~^ map_clone + + // Should not suggest `copied` or `cloned` here since `T` is not a reference. let x: Result = Ok(0); diff --git a/tests/ui/map_clone.rs b/tests/ui/map_clone.rs index a5c19ce06319..f15889d64c52 100644 --- a/tests/ui/map_clone.rs +++ b/tests/ui/map_clone.rs @@ -12,11 +12,16 @@ fn main() { let _: Vec = vec![5_i8; 6].iter().map(|x| *x).collect(); + //~^ map_clone let _: Vec = vec![String::new()].iter().map(|x| x.clone()).collect(); + //~^ map_clone let _: Vec = vec![42, 43].iter().map(|&x| x).collect(); + //~^ map_clone let _: Option = Some(Box::new(16)).map(|b| *b); let _: Option = Some(&16).map(|b| *b); + //~^ map_clone let _: Option = Some(&1).map(|x| x.clone()); + //~^ map_clone // Don't lint these let v = vec![5_i8; 6]; @@ -28,6 +33,7 @@ fn main() { // Issue #498 let _ = std::env::args().map(|v| v.clone()); + //~^ map_clone // Issue #4824 item types that aren't references { @@ -67,22 +73,27 @@ fn main() { let x = Some(String::new()); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.map(|x| String::clone(x)); - //~^ ERROR: you are explicitly cloning with `.map()` + //~^ map_clone + let y = x.map(Clone::clone); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `cloned` method + //~^ map_clone + + let y = x.map(String::clone); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `cloned` method + //~^ map_clone + + let x: Option = Some(0); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.map(|x| u32::clone(x)); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `copied` method + //~^ map_clone + + let y = x.map(|x| Clone::clone(x)); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `copied` method + //~^ map_clone + + // Should not suggest `copied` or `cloned` here since `T` is not a reference. let x: Option = Some(0); @@ -93,20 +104,24 @@ fn main() { let x: Result = Ok(String::new()); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.map(|x| String::clone(x)); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `cloned` method + //~^ map_clone + + let y = x.map(|x| Clone::clone(x)); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `cloned` method + //~^ map_clone + + let x: Result = Ok(0); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.map(|x| u32::clone(x)); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `copied` method + //~^ map_clone + + let y = x.map(|x| Clone::clone(x)); - //~^ ERROR: you are explicitly cloning with `.map()` - //~| HELP: consider calling the dedicated `copied` method + //~^ map_clone + + // Should not suggest `copied` or `cloned` here since `T` is not a reference. let x: Result = Ok(0); diff --git a/tests/ui/map_clone.stderr b/tests/ui/map_clone.stderr index d9e025de4abe..5c88ec579328 100644 --- a/tests/ui/map_clone.stderr +++ b/tests/ui/map_clone.stderr @@ -8,85 +8,85 @@ LL | let _: Vec = vec![5_i8; 6].iter().map(|x| *x).collect(); = help: to override `-D warnings` add `#[allow(clippy::map_clone)]` error: you are using an explicit closure for cloning elements - --> tests/ui/map_clone.rs:15:26 + --> tests/ui/map_clone.rs:16:26 | LL | let _: Vec = vec![String::new()].iter().map(|x| x.clone()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `vec![String::new()].iter().cloned()` error: you are using an explicit closure for copying elements - --> tests/ui/map_clone.rs:16:23 + --> tests/ui/map_clone.rs:18:23 | LL | let _: Vec = vec![42, 43].iter().map(|&x| x).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `vec![42, 43].iter().copied()` error: you are using an explicit closure for copying elements - --> tests/ui/map_clone.rs:18:26 + --> tests/ui/map_clone.rs:21:26 | LL | let _: Option = Some(&16).map(|b| *b); | ^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&16).copied()` error: you are using an explicit closure for copying elements - --> tests/ui/map_clone.rs:19:25 + --> tests/ui/map_clone.rs:23:25 | LL | let _: Option = Some(&1).map(|x| x.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&1).copied()` error: you are needlessly cloning iterator elements - --> tests/ui/map_clone.rs:30:29 + --> tests/ui/map_clone.rs:35:29 | LL | let _ = std::env::args().map(|v| v.clone()); | ^^^^^^^^^^^^^^^^^^^ help: remove the `map` call error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:69:13 + --> tests/ui/map_clone.rs:75:13 | LL | let y = x.map(|x| String::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:71:13 + --> tests/ui/map_clone.rs:78:13 | LL | let y = x.map(Clone::clone); | ^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:74:13 + --> tests/ui/map_clone.rs:82:13 | LL | let y = x.map(String::clone); | ^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:80:13 + --> tests/ui/map_clone.rs:89:13 | LL | let y = x.map(|x| u32::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:83:13 + --> tests/ui/map_clone.rs:93:13 | LL | let y = x.map(|x| Clone::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:95:13 + --> tests/ui/map_clone.rs:106:13 | LL | let y = x.map(|x| String::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:98:13 + --> tests/ui/map_clone.rs:110:13 | LL | let y = x.map(|x| Clone::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:104:13 + --> tests/ui/map_clone.rs:117:13 | LL | let y = x.map(|x| u32::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:107:13 + --> tests/ui/map_clone.rs:121:13 | LL | let y = x.map(|x| Clone::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()` diff --git a/tests/ui/map_collect_result_unit.fixed b/tests/ui/map_collect_result_unit.fixed index 374af105f889..26957e59f14a 100644 --- a/tests/ui/map_collect_result_unit.fixed +++ b/tests/ui/map_collect_result_unit.fixed @@ -3,7 +3,9 @@ fn main() { { let _ = (0..3).try_for_each(|t| Err(t + 1)); + //~^ map_collect_result_unit let _: Result<(), _> = (0..3).try_for_each(|t| Err(t + 1)); + //~^ map_collect_result_unit let _ = (0..3).try_for_each(|t| Err(t + 1)); } diff --git a/tests/ui/map_collect_result_unit.rs b/tests/ui/map_collect_result_unit.rs index 5c6fb23e2372..cdd73bfe6544 100644 --- a/tests/ui/map_collect_result_unit.rs +++ b/tests/ui/map_collect_result_unit.rs @@ -3,7 +3,9 @@ fn main() { { let _ = (0..3).map(|t| Err(t + 1)).collect::>(); + //~^ map_collect_result_unit let _: Result<(), _> = (0..3).map(|t| Err(t + 1)).collect(); + //~^ map_collect_result_unit let _ = (0..3).try_for_each(|t| Err(t + 1)); } diff --git a/tests/ui/map_collect_result_unit.stderr b/tests/ui/map_collect_result_unit.stderr index 8d147340e16a..93293be855bb 100644 --- a/tests/ui/map_collect_result_unit.stderr +++ b/tests/ui/map_collect_result_unit.stderr @@ -8,7 +8,7 @@ LL | let _ = (0..3).map(|t| Err(t + 1)).collect::>(); = help: to override `-D warnings` add `#[allow(clippy::map_collect_result_unit)]` error: `.map().collect()` can be replaced with `.try_for_each()` - --> tests/ui/map_collect_result_unit.rs:6:32 + --> tests/ui/map_collect_result_unit.rs:7:32 | LL | let _: Result<(), _> = (0..3).map(|t| Err(t + 1)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(0..3).try_for_each(|t| Err(t + 1))` diff --git a/tests/ui/map_err.rs b/tests/ui/map_err.rs index 07c51784407a..43f6ea0b3ae0 100644 --- a/tests/ui/map_err.rs +++ b/tests/ui/map_err.rs @@ -20,7 +20,8 @@ fn main() -> Result<(), Errors> { let x = u32::try_from(-123_i32); println!("{:?}", x.map_err(|_| Errors::Ignored)); - //~^ ERROR: `map_err(|_|...` wildcard pattern discards the original error + //~^ map_err_ignore + // Should not warn you because you explicitly ignore the parameter // using a named wildcard value diff --git a/tests/ui/map_flatten.rs b/tests/ui/map_flatten.rs index eafc8b6e81ca..e16a11f83ed5 100644 --- a/tests/ui/map_flatten.rs +++ b/tests/ui/map_flatten.rs @@ -6,8 +6,9 @@ fn long_span() { let _: Option = Some(1) .map(|x| { - //~^ ERROR: called `map(..).flatten()` on `Option` - //~| NOTE: `-D clippy::map-flatten` implied by `-D warnings` + //~^ map_flatten + + if x <= 5 { Some(x) } else { @@ -18,7 +19,8 @@ fn long_span() { let _: Result = Ok(1) .map(|x| { - //~^ ERROR: called `map(..).flatten()` on `Result` + //~^ map_flatten + if x == 1 { Ok(x) } else { @@ -31,7 +33,8 @@ fn long_span() { fn do_something() { } let _: Result = result .map(|res| { - //~^ ERROR: called `map(..).flatten()` on `Result` + //~^ map_flatten + if res > 0 { do_something(); Ok(res) @@ -44,7 +47,8 @@ fn long_span() { let _: Vec<_> = vec![5_i8; 6] .into_iter() .map(|some_value| { - //~^ ERROR: called `map(..).flatten()` on `Iterator` + //~^ map_flatten + if some_value > 3 { Some(some_value) } else { @@ -62,7 +66,8 @@ fn no_suggestion_if_comments_present() { .iter() // a lovely comment explaining the code in very detail .map(|x| x.iter()) - //~^ ERROR: called `map(..).flatten()` on `Iterator` + //~^ map_flatten + // the answer to life, the universe and everything could be here .flatten(); } diff --git a/tests/ui/map_flatten.stderr b/tests/ui/map_flatten.stderr index 34bd174d7dde..704267fea3cf 100644 --- a/tests/ui/map_flatten.stderr +++ b/tests/ui/map_flatten.stderr @@ -3,9 +3,6 @@ error: called `map(..).flatten()` on `Option` | LL | .map(|x| { | __________^ -LL | | -LL | | -LL | | if x <= 5 { ... | LL | | }) LL | | .flatten(); @@ -17,7 +14,8 @@ help: try replacing `map` with `and_then` and remove the `.flatten()` | LL ~ .and_then(|x| { LL + -LL + +LL + +LL + LL + if x <= 5 { LL + Some(x) LL + } else { @@ -27,13 +25,13 @@ LL ~ }); | error: called `map(..).flatten()` on `Result` - --> tests/ui/map_flatten.rs:20:10 + --> tests/ui/map_flatten.rs:21:10 | LL | .map(|x| { | __________^ LL | | +LL | | LL | | if x == 1 { -LL | | Ok(x) ... | LL | | }) LL | | .flatten(); @@ -43,6 +41,7 @@ help: try replacing `map` with `and_then` and remove the `.flatten()` | LL ~ .and_then(|x| { LL + +LL + LL + if x == 1 { LL + Ok(x) LL + } else { @@ -52,13 +51,13 @@ LL ~ }); | error: called `map(..).flatten()` on `Result` - --> tests/ui/map_flatten.rs:33:10 + --> tests/ui/map_flatten.rs:35:10 | LL | .map(|res| { | __________^ LL | | +LL | | LL | | if res > 0 { -LL | | do_something(); ... | LL | | }) LL | | .flatten(); @@ -68,6 +67,7 @@ help: try replacing `map` with `and_then` and remove the `.flatten()` | LL ~ .and_then(|res| { LL + +LL + LL + if res > 0 { LL + do_something(); LL + Ok(res) @@ -78,13 +78,13 @@ LL ~ }); | error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten.rs:46:10 + --> tests/ui/map_flatten.rs:49:10 | LL | .map(|some_value| { | __________^ LL | | +LL | | LL | | if some_value > 3 { -LL | | Some(some_value) ... | LL | | }) LL | | .flatten() @@ -94,6 +94,7 @@ help: try replacing `map` with `filter_map` and remove the `.flatten()` | LL ~ .filter_map(|some_value| { LL + +LL + LL + if some_value > 3 { LL + Some(some_value) LL + } else { @@ -103,7 +104,7 @@ LL + }) | error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten.rs:64:10 + --> tests/ui/map_flatten.rs:68:10 | LL | .map(|x| x.iter()) | __________^ diff --git a/tests/ui/map_flatten_fixable.fixed b/tests/ui/map_flatten_fixable.fixed index 1932f412d2ca..a5dc17cc06ca 100644 --- a/tests/ui/map_flatten_fixable.fixed +++ b/tests/ui/map_flatten_fixable.fixed @@ -14,18 +14,25 @@ fn main() { let option_id_ref: fn(i8) -> Option = option_id; let option_id_closure = |x| Some(x); let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(option_id).collect(); + //~^ map_flatten let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(option_id_ref).collect(); + //~^ map_flatten let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(option_id_closure).collect(); + //~^ map_flatten let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(|x| x.checked_add(1)).collect(); + //~^ map_flatten // mapping to Iterator on Iterator let _: Vec<_> = vec![5_i8; 6].into_iter().flat_map(|x| 0..x).collect(); + //~^ map_flatten // mapping to Option on Option let _: Option<_> = (Some(Some(1))).and_then(|x| x); + //~^ map_flatten // mapping to Result on Result let _: Result<_, &str> = (Ok(Ok(1))).and_then(|x| x); + //~^ map_flatten issue8734(); issue8878(); @@ -35,6 +42,7 @@ fn issue8734() { let _ = [0u8, 1, 2, 3] .into_iter() .flat_map(|n| match n { + //~^ map_flatten 1 => [n .saturating_add(1) .saturating_add(1) @@ -54,6 +62,7 @@ fn issue8878() { std::collections::HashMap::::new() .get(&0) .and_then(|_| { + //~^ map_flatten // we need some newlines // so that the span is big enough // for a split output of the diagnostic diff --git a/tests/ui/map_flatten_fixable.rs b/tests/ui/map_flatten_fixable.rs index 093fd9b6cae2..57b8e7943f41 100644 --- a/tests/ui/map_flatten_fixable.rs +++ b/tests/ui/map_flatten_fixable.rs @@ -14,18 +14,25 @@ fn main() { let option_id_ref: fn(i8) -> Option = option_id; let option_id_closure = |x| Some(x); let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().collect(); + //~^ map_flatten let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_ref).flatten().collect(); + //~^ map_flatten let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_closure).flatten().collect(); + //~^ map_flatten let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| x.checked_add(1)).flatten().collect(); + //~^ map_flatten // mapping to Iterator on Iterator let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect(); + //~^ map_flatten // mapping to Option on Option let _: Option<_> = (Some(Some(1))).map(|x| x).flatten(); + //~^ map_flatten // mapping to Result on Result let _: Result<_, &str> = (Ok(Ok(1))).map(|x| x).flatten(); + //~^ map_flatten issue8734(); issue8878(); @@ -35,6 +42,7 @@ fn issue8734() { let _ = [0u8, 1, 2, 3] .into_iter() .map(|n| match n { + //~^ map_flatten 1 => [n .saturating_add(1) .saturating_add(1) @@ -55,6 +63,7 @@ fn issue8878() { std::collections::HashMap::::new() .get(&0) .map(|_| { + //~^ map_flatten // we need some newlines // so that the span is big enough // for a split output of the diagnostic diff --git a/tests/ui/map_flatten_fixable.stderr b/tests/ui/map_flatten_fixable.stderr index 095bee52d6d7..05d4d9a6ad85 100644 --- a/tests/ui/map_flatten_fixable.stderr +++ b/tests/ui/map_flatten_fixable.stderr @@ -8,49 +8,49 @@ LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().coll = help: to override `-D warnings` add `#[allow(clippy::map_flatten)]` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:17:47 + --> tests/ui/map_flatten_fixable.rs:18:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_ref).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_ref)` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:18:47 + --> tests/ui/map_flatten_fixable.rs:20:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_closure).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_closure)` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:19:47 + --> tests/ui/map_flatten_fixable.rs:22:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| x.checked_add(1)).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(|x| x.checked_add(1))` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:22:47 + --> tests/ui/map_flatten_fixable.rs:26:47 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `flat_map` and remove the `.flatten()`: `flat_map(|x| 0..x)` error: called `map(..).flatten()` on `Option` - --> tests/ui/map_flatten_fixable.rs:25:40 + --> tests/ui/map_flatten_fixable.rs:30:40 | LL | let _: Option<_> = (Some(Some(1))).map(|x| x).flatten(); | ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)` error: called `map(..).flatten()` on `Result` - --> tests/ui/map_flatten_fixable.rs:28:42 + --> tests/ui/map_flatten_fixable.rs:34:42 | LL | let _: Result<_, &str> = (Ok(Ok(1))).map(|x| x).flatten(); | ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)` error: called `map(..).flatten()` on `Iterator` - --> tests/ui/map_flatten_fixable.rs:37:10 + --> tests/ui/map_flatten_fixable.rs:44:10 | LL | .map(|n| match n { | __________^ +LL | | LL | | 1 => [n LL | | .saturating_add(1) -LL | | .saturating_add(1) ... | LL | | }) LL | | .flatten(); @@ -59,6 +59,7 @@ LL | | .flatten(); help: try replacing `map` with `flat_map` and remove the `.flatten()` | LL ~ .flat_map(|n| match n { +LL + LL + 1 => [n LL + .saturating_add(1) LL + .saturating_add(1) @@ -73,7 +74,7 @@ LL ~ }); | error: called `map(..).flatten()` on `Option` - --> tests/ui/map_flatten_fixable.rs:57:10 + --> tests/ui/map_flatten_fixable.rs:65:10 | LL | .map(|_| { | __________^ @@ -85,6 +86,7 @@ LL | | .flatten(); help: try replacing `map` with `and_then` and remove the `.flatten()` | LL ~ .and_then(|_| { +LL + LL + // we need some newlines LL + // so that the span is big enough LL + // for a split output of the diagnostic diff --git a/tests/ui/map_identity.fixed b/tests/ui/map_identity.fixed index 3257ddc6f72b..83b2dac5fc51 100644 --- a/tests/ui/map_identity.fixed +++ b/tests/ui/map_identity.fixed @@ -5,8 +5,12 @@ fn main() { let x: [u16; 3] = [1, 2, 3]; // should lint let _: Vec<_> = x.iter().map(not_identity).collect(); + //~^ map_identity let _: Vec<_> = x.iter().collect(); + //~^ map_identity + //~| map_identity let _: Option = Some(3); + //~^ map_identity let _: Result = Ok(-3); // should not lint let _: Vec<_> = x.iter().map(|x| 2 * x).collect(); @@ -16,6 +20,7 @@ fn main() { return x + 3; }); let _: Result = Ok(1); + //~^ map_identity let _: Result = Ok(1).map_err(|a: u32| a * 42); // : u32 guides type inference let _ = Ok(1).map_err(|a: u32| a); @@ -26,11 +31,14 @@ fn issue7189() { // should lint let x = [(1, 2), (3, 4)].iter().copied(); let _ = x.clone(); + //~^ map_identity let _ = x.clone(); let _ = x.clone(); + //~^ map_identity let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))].iter().copied(); let _ = y.clone(); + //~^ map_identity // should not lint let _ = x.clone().map(|(x, y)| (x, y, y)); @@ -60,6 +68,7 @@ fn issue11764() { // no match ergonomics for `(i32, i32)` let _ = x.iter().copied(); + //~^ map_identity } fn issue13904() { @@ -71,8 +80,10 @@ fn issue13904() { #[allow(unused_mut)] let mut it = [1, 2, 3].into_iter(); let _ = it.next(); + //~^ map_identity // lint let it = [1, 2, 3].into_iter(); let _ = { it }.next(); + //~^ map_identity } diff --git a/tests/ui/map_identity.rs b/tests/ui/map_identity.rs index be3bb9a4f106..7c891dda79ce 100644 --- a/tests/ui/map_identity.rs +++ b/tests/ui/map_identity.rs @@ -5,9 +5,14 @@ fn main() { let x: [u16; 3] = [1, 2, 3]; // should lint let _: Vec<_> = x.iter().map(not_identity).map(|x| return x).collect(); + //~^ map_identity let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect(); + //~^ map_identity + //~| map_identity let _: Option = Some(3).map(|x| x); + //~^ map_identity let _: Result = Ok(-3).map(|x| { + //~^ map_identity return x; }); // should not lint @@ -18,6 +23,7 @@ fn main() { return x + 3; }); let _: Result = Ok(1).map_err(|a| a); + //~^ map_identity let _: Result = Ok(1).map_err(|a: u32| a * 42); // : u32 guides type inference let _ = Ok(1).map_err(|a: u32| a); @@ -28,13 +34,17 @@ fn issue7189() { // should lint let x = [(1, 2), (3, 4)].iter().copied(); let _ = x.clone().map(|(x, y)| (x, y)); + //~^ map_identity let _ = x.clone().map(|(x, y)| { + //~^ map_identity return (x, y); }); let _ = x.clone().map(|(x, y)| return (x, y)); + //~^ map_identity let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))].iter().copied(); let _ = y.clone().map(|(x, y, (z, (w,)))| (x, y, (z, (w,)))); + //~^ map_identity // should not lint let _ = x.clone().map(|(x, y)| (x, y, y)); @@ -64,6 +74,7 @@ fn issue11764() { // no match ergonomics for `(i32, i32)` let _ = x.iter().copied().map(|(x, y)| (x, y)); + //~^ map_identity } fn issue13904() { @@ -75,8 +86,10 @@ fn issue13904() { #[allow(unused_mut)] let mut it = [1, 2, 3].into_iter(); let _ = it.map(|x| x).next(); + //~^ map_identity // lint let it = [1, 2, 3].into_iter(); let _ = { it }.map(|x| x).next(); + //~^ map_identity } diff --git a/tests/ui/map_identity.stderr b/tests/ui/map_identity.stderr index aa3fc4ae0b5c..9836f3b4cc5f 100644 --- a/tests/ui/map_identity.stderr +++ b/tests/ui/map_identity.stderr @@ -8,79 +8,81 @@ LL | let _: Vec<_> = x.iter().map(not_identity).map(|x| return x).collect(); = help: to override `-D warnings` add `#[allow(clippy::map_identity)]` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:8:57 + --> tests/ui/map_identity.rs:9:57 | LL | let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect(); | ^^^^^^^^^^^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:8:29 + --> tests/ui/map_identity.rs:9:29 | LL | let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:9:32 + --> tests/ui/map_identity.rs:12:32 | LL | let _: Option = Some(3).map(|x| x); | ^^^^^^^^^^^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:10:36 + --> tests/ui/map_identity.rs:14:36 | LL | let _: Result = Ok(-3).map(|x| { | ____________________________________^ +LL | | LL | | return x; LL | | }); | |______^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:20:36 + --> tests/ui/map_identity.rs:25:36 | LL | let _: Result = Ok(1).map_err(|a| a); | ^^^^^^^^^^^^^^^ help: remove the call to `map_err` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:30:22 + --> tests/ui/map_identity.rs:36:22 | LL | let _ = x.clone().map(|(x, y)| (x, y)); | ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:31:22 + --> tests/ui/map_identity.rs:38:22 | LL | let _ = x.clone().map(|(x, y)| { | ______________________^ +LL | | LL | | return (x, y); LL | | }); | |______^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:34:22 + --> tests/ui/map_identity.rs:42:22 | LL | let _ = x.clone().map(|(x, y)| return (x, y)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:37:22 + --> tests/ui/map_identity.rs:46:22 | LL | let _ = y.clone().map(|(x, y, (z, (w,)))| (x, y, (z, (w,)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:66:30 + --> tests/ui/map_identity.rs:76:30 | LL | let _ = x.iter().copied().map(|(x, y)| (x, y)); | ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:77:15 + --> tests/ui/map_identity.rs:88:15 | LL | let _ = it.map(|x| x).next(); | ^^^^^^^^^^^ help: remove the call to `map` error: unnecessary map of the identity function - --> tests/ui/map_identity.rs:81:19 + --> tests/ui/map_identity.rs:93:19 | LL | let _ = { it }.map(|x| x).next(); | ^^^^^^^^^^^ help: remove the call to `map` diff --git a/tests/ui/map_unit_fn.rs b/tests/ui/map_unit_fn.rs index e7f07b50f3ab..3a810196a44d 100644 --- a/tests/ui/map_unit_fn.rs +++ b/tests/ui/map_unit_fn.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![allow(unused)] struct Mappable; diff --git a/tests/ui/map_unwrap_or.rs b/tests/ui/map_unwrap_or.rs index dfaa8f24f987..fba81cb493cd 100644 --- a/tests/ui/map_unwrap_or.rs +++ b/tests/ui/map_unwrap_or.rs @@ -15,25 +15,31 @@ fn option_methods() { // Check for `option.map(_).unwrap_or(_)` use. // Single line case. let _ = opt.map(|x| x + 1) + //~^ map_unwrap_or // Should lint even though this call is on a separate line. .unwrap_or(0); // Multi-line cases. let _ = opt.map(|x| { + //~^ map_unwrap_or x + 1 } ).unwrap_or(0); let _ = opt.map(|x| x + 1) + //~^ map_unwrap_or .unwrap_or({ 0 }); // Single line `map(f).unwrap_or(None)` case. let _ = opt.map(|x| Some(x + 1)).unwrap_or(None); + //~^ map_unwrap_or // Multi-line `map(f).unwrap_or(None)` cases. let _ = opt.map(|x| { + //~^ map_unwrap_or Some(x + 1) } ).unwrap_or(None); let _ = opt + //~^ map_unwrap_or .map(|x| Some(x + 1)) .unwrap_or(None); // macro case @@ -45,20 +51,24 @@ fn option_methods() { // ...but DO lint if the `unwrap_or` argument is not used in the `map` let id: String = "identifier".to_string(); let _ = Some("prefix").map(|p| format!("{}.", p)).unwrap_or(id); + //~^ map_unwrap_or // Check for `option.map(_).unwrap_or_else(_)` use. // Multi-line cases. let _ = opt.map(|x| { + //~^ map_unwrap_or x + 1 } ).unwrap_or_else(|| 0); let _ = opt.map(|x| x + 1) + //~^ map_unwrap_or .unwrap_or_else(|| 0 ); // Check for `map(f).unwrap_or(false)` use. let _ = opt.map(|x| x > 5).unwrap_or(false); + //~^ map_unwrap_or } @@ -69,10 +79,12 @@ fn result_methods() { // Check for `result.map(_).unwrap_or_else(_)` use. // multi line cases let _ = res.map(|x| { + //~^ map_unwrap_or x + 1 } ).unwrap_or_else(|_e| 0); let _ = res.map(|x| x + 1) + //~^ map_unwrap_or .unwrap_or_else(|_e| { 0 }); @@ -97,6 +109,7 @@ fn msrv_1_41() { let res: Result = Ok(1); let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0); + //~^ map_unwrap_or } #[clippy::msrv = "1.69"] @@ -104,6 +117,7 @@ fn msrv_1_69() { let opt: Option = Some(1); let _ = opt.map(|x| x > 5).unwrap_or(false); + //~^ map_unwrap_or } #[clippy::msrv = "1.70"] @@ -111,6 +125,7 @@ fn msrv_1_70() { let opt: Option = Some(1); let _ = opt.map(|x| x > 5).unwrap_or(false); + //~^ map_unwrap_or } mod issue_10579 { diff --git a/tests/ui/map_unwrap_or.stderr b/tests/ui/map_unwrap_or.stderr index d6ddd09c188c..0b6c9b7fcf19 100644 --- a/tests/ui/map_unwrap_or.stderr +++ b/tests/ui/map_unwrap_or.stderr @@ -3,7 +3,7 @@ error: called `map().unwrap_or()` on an `Option` value | LL | let _ = opt.map(|x| x + 1) | _____________^ -LL | | // Should lint even though this call is on a separate line. +... | LL | | .unwrap_or(0); | |_____________________^ | @@ -16,10 +16,11 @@ LL + let _ = opt.map_or(0, |x| x + 1); | error: called `map().unwrap_or()` on an `Option` value - --> tests/ui/map_unwrap_or.rs:21:13 + --> tests/ui/map_unwrap_or.rs:22:13 | LL | let _ = opt.map(|x| { | _____________^ +LL | | LL | | x + 1 LL | | } LL | | ).unwrap_or(0); @@ -28,16 +29,18 @@ LL | | ).unwrap_or(0); help: use `map_or(, )` instead | LL ~ let _ = opt.map_or(0, |x| { +LL | LL | x + 1 LL | } LL ~ ); | error: called `map().unwrap_or()` on an `Option` value - --> tests/ui/map_unwrap_or.rs:25:13 + --> tests/ui/map_unwrap_or.rs:27:13 | LL | let _ = opt.map(|x| x + 1) | _____________^ +LL | | LL | | .unwrap_or({ LL | | 0 LL | | }); @@ -51,7 +54,7 @@ LL ~ }, |x| x + 1); | error: called `map().unwrap_or(None)` on an `Option` value - --> tests/ui/map_unwrap_or.rs:30:13 + --> tests/ui/map_unwrap_or.rs:33:13 | LL | let _ = opt.map(|x| Some(x + 1)).unwrap_or(None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -63,10 +66,11 @@ LL + let _ = opt.and_then(|x| Some(x + 1)); | error: called `map().unwrap_or(None)` on an `Option` value - --> tests/ui/map_unwrap_or.rs:32:13 + --> tests/ui/map_unwrap_or.rs:36:13 | LL | let _ = opt.map(|x| { | _____________^ +LL | | LL | | Some(x + 1) LL | | } LL | | ).unwrap_or(None); @@ -75,16 +79,18 @@ LL | | ).unwrap_or(None); help: use `and_then()` instead | LL ~ let _ = opt.and_then(|x| { +LL | LL | Some(x + 1) LL | } LL ~ ); | error: called `map().unwrap_or(None)` on an `Option` value - --> tests/ui/map_unwrap_or.rs:36:13 + --> tests/ui/map_unwrap_or.rs:41:13 | LL | let _ = opt | _____________^ +LL | | LL | | .map(|x| Some(x + 1)) LL | | .unwrap_or(None); | |________________________^ @@ -96,7 +102,7 @@ LL + .and_then(|x| Some(x + 1)); | error: called `map().unwrap_or()` on an `Option` value - --> tests/ui/map_unwrap_or.rs:47:13 + --> tests/ui/map_unwrap_or.rs:53:13 | LL | let _ = Some("prefix").map(|p| format!("{}.", p)).unwrap_or(id); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -108,27 +114,29 @@ LL + let _ = Some("prefix").map_or(id, |p| format!("{}.", p)); | error: called `map().unwrap_or_else()` on an `Option` value - --> tests/ui/map_unwrap_or.rs:51:13 + --> tests/ui/map_unwrap_or.rs:58:13 | LL | let _ = opt.map(|x| { | _____________^ +LL | | LL | | x + 1 LL | | } LL | | ).unwrap_or_else(|| 0); | |__________________________^ error: called `map().unwrap_or_else()` on an `Option` value - --> tests/ui/map_unwrap_or.rs:55:13 + --> tests/ui/map_unwrap_or.rs:63:13 | LL | let _ = opt.map(|x| x + 1) | _____________^ +LL | | LL | | .unwrap_or_else(|| LL | | 0 LL | | ); | |_________^ error: called `map().unwrap_or(false)` on an `Option` value - --> tests/ui/map_unwrap_or.rs:61:13 + --> tests/ui/map_unwrap_or.rs:70:13 | LL | let _ = opt.map(|x| x > 5).unwrap_or(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -140,33 +148,35 @@ LL + let _ = opt.is_some_and(|x| x > 5); | error: called `map().unwrap_or_else()` on a `Result` value - --> tests/ui/map_unwrap_or.rs:71:13 + --> tests/ui/map_unwrap_or.rs:81:13 | LL | let _ = res.map(|x| { | _____________^ +LL | | LL | | x + 1 LL | | } LL | | ).unwrap_or_else(|_e| 0); | |____________________________^ error: called `map().unwrap_or_else()` on a `Result` value - --> tests/ui/map_unwrap_or.rs:75:13 + --> tests/ui/map_unwrap_or.rs:86:13 | LL | let _ = res.map(|x| x + 1) | _____________^ +LL | | LL | | .unwrap_or_else(|_e| { LL | | 0 LL | | }); | |__________^ error: called `map().unwrap_or_else()` on a `Result` value - --> tests/ui/map_unwrap_or.rs:99:13 + --> tests/ui/map_unwrap_or.rs:111:13 | LL | let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)` error: called `map().unwrap_or()` on an `Option` value - --> tests/ui/map_unwrap_or.rs:106:13 + --> tests/ui/map_unwrap_or.rs:119:13 | LL | let _ = opt.map(|x| x > 5).unwrap_or(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -178,7 +188,7 @@ LL + let _ = opt.map_or(false, |x| x > 5); | error: called `map().unwrap_or(false)` on an `Option` value - --> tests/ui/map_unwrap_or.rs:113:13 + --> tests/ui/map_unwrap_or.rs:127:13 | LL | let _ = opt.map(|x| x > 5).unwrap_or(false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/map_unwrap_or_fixable.rs b/tests/ui/map_unwrap_or_fixable.rs index d3d0ae0154c1..1078c7a3cf34 100644 --- a/tests/ui/map_unwrap_or_fixable.rs +++ b/tests/ui/map_unwrap_or_fixable.rs @@ -14,6 +14,7 @@ fn option_methods() { // Check for `option.map(_).unwrap_or_else(_)` use. // single line case let _ = opt.map(|x| x + 1) + //~^ map_unwrap_or // Should lint even though this call is on a separate line. .unwrap_or_else(|| 0); @@ -44,6 +45,7 @@ fn result_methods() { // Check for `result.map(_).unwrap_or_else(_)` use. // single line case let _ = res.map(|x| x + 1) + //~^ map_unwrap_or // should lint even though this call is on a separate line .unwrap_or_else(|_e| 0); diff --git a/tests/ui/map_unwrap_or_fixable.stderr b/tests/ui/map_unwrap_or_fixable.stderr index 89a7c979f6e9..99e660f8dbd1 100644 --- a/tests/ui/map_unwrap_or_fixable.stderr +++ b/tests/ui/map_unwrap_or_fixable.stderr @@ -3,7 +3,7 @@ error: called `map().unwrap_or_else()` on an `Option` value | LL | let _ = opt.map(|x| x + 1) | _____________^ -LL | | // Should lint even though this call is on a separate line. +... | LL | | .unwrap_or_else(|| 0); | |_____________________________^ help: try: `opt.map_or_else(|| 0, |x| x + 1)` | @@ -11,11 +11,11 @@ LL | | .unwrap_or_else(|| 0); = help: to override `-D warnings` add `#[allow(clippy::map_unwrap_or)]` error: called `map().unwrap_or_else()` on a `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:46:13 + --> tests/ui/map_unwrap_or_fixable.rs:47:13 | LL | let _ = res.map(|x| x + 1) | _____________^ -LL | | // should lint even though this call is on a separate line +... | LL | | .unwrap_or_else(|_e| 0); | |_______________________________^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)` diff --git a/tests/ui/map_with_unused_argument_over_ranges.fixed b/tests/ui/map_with_unused_argument_over_ranges.fixed index 18716e93d1e9..08bc1c7a6283 100644 --- a/tests/ui/map_with_unused_argument_over_ranges.fixed +++ b/tests/ui/map_with_unused_argument_over_ranges.fixed @@ -23,27 +23,43 @@ macro_rules! r#gen { fn main() { // These should be raised std::iter::repeat_with(|| do_something()).take(10); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| do_something()).take(10); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| do_something()).take(11); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| do_something()).take(7); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| do_something()).take(8); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_n(3, 10); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| { + //~^ map_with_unused_argument_over_ranges let x = 3; x + 2 }).take(10); std::iter::repeat_with(|| do_something()).take(10).collect::>(); + //~^ map_with_unused_argument_over_ranges let upper = 4; std::iter::repeat_with(|| do_something()).take(upper); + //~^ map_with_unused_argument_over_ranges let upper_fn = || 4; std::iter::repeat_with(|| do_something()).take(upper_fn()); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| do_something()).take(upper_fn() + 1); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| do_something()).take(upper_fn() - 2); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| do_something()).take(upper_fn() - 1); + //~^ map_with_unused_argument_over_ranges (-3..9).map(|_| do_something()); std::iter::repeat_with(|| do_something()).take(0); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| do_something()).take(1); + //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| do_something()).take((1 << 4) - 0); + //~^ map_with_unused_argument_over_ranges // These should not be raised r#gen!(); let lower = 2; @@ -65,9 +81,11 @@ fn msrv_1_27() { #[clippy::msrv = "1.28"] fn msrv_1_28() { std::iter::repeat_with(|| do_something()).take(10); + //~^ map_with_unused_argument_over_ranges } #[clippy::msrv = "1.81"] fn msrv_1_82() { std::iter::repeat(3).take(10); + //~^ map_with_unused_argument_over_ranges } diff --git a/tests/ui/map_with_unused_argument_over_ranges.rs b/tests/ui/map_with_unused_argument_over_ranges.rs index 596afd51e61f..151ebdf97e5d 100644 --- a/tests/ui/map_with_unused_argument_over_ranges.rs +++ b/tests/ui/map_with_unused_argument_over_ranges.rs @@ -23,27 +23,43 @@ macro_rules! r#gen { fn main() { // These should be raised (0..10).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (0..10).map(|_foo| do_something()); + //~^ map_with_unused_argument_over_ranges (0..=10).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (3..10).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (3..=10).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (0..10).map(|_| 3); + //~^ map_with_unused_argument_over_ranges (0..10).map(|_| { + //~^ map_with_unused_argument_over_ranges let x = 3; x + 2 }); (0..10).map(|_| do_something()).collect::>(); + //~^ map_with_unused_argument_over_ranges let upper = 4; (0..upper).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges let upper_fn = || 4; (0..upper_fn()).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (0..=upper_fn()).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (2..upper_fn()).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (2..=upper_fn()).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (-3..9).map(|_| do_something()); (9..3).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (9..=9).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges (1..=1 << 4).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges // These should not be raised r#gen!(); let lower = 2; @@ -65,9 +81,11 @@ fn msrv_1_27() { #[clippy::msrv = "1.28"] fn msrv_1_28() { (0..10).map(|_| do_something()); + //~^ map_with_unused_argument_over_ranges } #[clippy::msrv = "1.81"] fn msrv_1_82() { (0..10).map(|_| 3); + //~^ map_with_unused_argument_over_ranges } diff --git a/tests/ui/map_with_unused_argument_over_ranges.stderr b/tests/ui/map_with_unused_argument_over_ranges.stderr index 0b56c6d95219..ed905b6591c7 100644 --- a/tests/ui/map_with_unused_argument_over_ranges.stderr +++ b/tests/ui/map_with_unused_argument_over_ranges.stderr @@ -13,7 +13,7 @@ LL + std::iter::repeat_with(|| do_something()).take(10); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:26:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:27:5 | LL | (0..10).map(|_foo| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + std::iter::repeat_with(|| do_something()).take(10); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:27:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:29:5 | LL | (0..=10).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + std::iter::repeat_with(|| do_something()).take(11); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:28:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:31:5 | LL | (3..10).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + std::iter::repeat_with(|| do_something()).take(7); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:29:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:33:5 | LL | (3..=10).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + std::iter::repeat_with(|| do_something()).take(8); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:30:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:35:5 | LL | (0..10).map(|_| 3); | ^^^^^^^^^^^^^^^^^^ @@ -72,9 +72,10 @@ LL | std::iter::repeat_n(3, 10); | ~~~~~~~~~~~~~~~~~~~ ~~~~~ error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:31:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:37:5 | LL | / (0..10).map(|_| { +LL | | LL | | let x = 3; LL | | x + 2 LL | | }); @@ -83,13 +84,14 @@ LL | | }); help: remove the explicit range and use `repeat_with` and `take` | LL ~ std::iter::repeat_with(|| { +LL | LL | let x = 3; LL | x + 2 LL ~ }).take(10); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:35:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:42:5 | LL | (0..10).map(|_| do_something()).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -101,7 +103,7 @@ LL + std::iter::repeat_with(|| do_something()).take(10).collect::>(); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:37:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:45:5 | LL | (0..upper).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +115,7 @@ LL + std::iter::repeat_with(|| do_something()).take(upper); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:39:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:48:5 | LL | (0..upper_fn()).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -125,7 +127,7 @@ LL + std::iter::repeat_with(|| do_something()).take(upper_fn()); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:40:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:50:5 | LL | (0..=upper_fn()).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,7 +139,7 @@ LL + std::iter::repeat_with(|| do_something()).take(upper_fn() + 1); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:41:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:52:5 | LL | (2..upper_fn()).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +151,7 @@ LL + std::iter::repeat_with(|| do_something()).take(upper_fn() - 2); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:42:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:54:5 | LL | (2..=upper_fn()).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -161,7 +163,7 @@ LL + std::iter::repeat_with(|| do_something()).take(upper_fn() - 1); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:44:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:57:5 | LL | (9..3).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -173,7 +175,7 @@ LL + std::iter::repeat_with(|| do_something()).take(0); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:45:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:59:5 | LL | (9..=9).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +187,7 @@ LL + std::iter::repeat_with(|| do_something()).take(1); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:46:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:61:5 | LL | (1..=1 << 4).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -197,7 +199,7 @@ LL + std::iter::repeat_with(|| do_something()).take((1 << 4) - 0); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:67:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:83:5 | LL | (0..10).map(|_| do_something()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +211,7 @@ LL + std::iter::repeat_with(|| do_something()).take(10); | error: map of a closure that does not depend on its parameter over a range - --> tests/ui/map_with_unused_argument_over_ranges.rs:72:5 + --> tests/ui/map_with_unused_argument_over_ranges.rs:89:5 | LL | (0..10).map(|_| 3); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/map_with_unused_argument_over_ranges_nostd.fixed b/tests/ui/map_with_unused_argument_over_ranges_nostd.fixed index 65e59774905c..15a2780da440 100644 --- a/tests/ui/map_with_unused_argument_over_ranges_nostd.fixed +++ b/tests/ui/map_with_unused_argument_over_ranges_nostd.fixed @@ -5,4 +5,5 @@ use alloc::vec::Vec; fn nostd(v: &mut [i32]) { let _: Vec<_> = core::iter::repeat_n(3 + 1, 10).collect(); + //~^ map_with_unused_argument_over_ranges } diff --git a/tests/ui/map_with_unused_argument_over_ranges_nostd.rs b/tests/ui/map_with_unused_argument_over_ranges_nostd.rs index dda7a69b33f9..58de71facebb 100644 --- a/tests/ui/map_with_unused_argument_over_ranges_nostd.rs +++ b/tests/ui/map_with_unused_argument_over_ranges_nostd.rs @@ -5,4 +5,5 @@ use alloc::vec::Vec; fn nostd(v: &mut [i32]) { let _: Vec<_> = (0..10).map(|_| 3 + 1).collect(); + //~^ map_with_unused_argument_over_ranges } diff --git a/tests/ui/match_as_ref.rs b/tests/ui/match_as_ref.rs index 655e16623697..7eaabcdc3d0e 100644 --- a/tests/ui/match_as_ref.rs +++ b/tests/ui/match_as_ref.rs @@ -4,12 +4,14 @@ fn match_as_ref() { let owned: Option<()> = None; let borrowed: Option<&()> = match owned { + //~^ match_as_ref None => None, Some(ref v) => Some(v), }; let mut mut_owned: Option<()> = None; let borrow_mut: Option<&mut ()> = match mut_owned { + //~^ match_as_ref None => None, Some(ref mut v) => Some(v), }; @@ -28,6 +30,7 @@ mod issue4437 { impl Error for E { fn source(&self) -> Option<&(dyn Error + 'static)> { match self.source { + //~^ match_as_ref Some(ref s) => Some(s), None => None, } diff --git a/tests/ui/match_as_ref.stderr b/tests/ui/match_as_ref.stderr index 97b121424d93..7b40cb80dc6e 100644 --- a/tests/ui/match_as_ref.stderr +++ b/tests/ui/match_as_ref.stderr @@ -3,6 +3,7 @@ error: use `as_ref()` instead | LL | let borrowed: Option<&()> = match owned { | _________________________________^ +LL | | LL | | None => None, LL | | Some(ref v) => Some(v), LL | | }; @@ -12,19 +13,21 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::match_as_ref)]` error: use `as_mut()` instead - --> tests/ui/match_as_ref.rs:12:39 + --> tests/ui/match_as_ref.rs:13:39 | LL | let borrow_mut: Option<&mut ()> = match mut_owned { | _______________________________________^ +LL | | LL | | None => None, LL | | Some(ref mut v) => Some(v), LL | | }; | |_____^ help: try: `mut_owned.as_mut()` error: use `as_ref()` instead - --> tests/ui/match_as_ref.rs:30:13 + --> tests/ui/match_as_ref.rs:32:13 | LL | / match self.source { +LL | | LL | | Some(ref s) => Some(s), LL | | None => None, LL | | } diff --git a/tests/ui/match_bool.rs b/tests/ui/match_bool.rs index e77f0304feda..7d4afd3f2890 100644 --- a/tests/ui/match_bool.rs +++ b/tests/ui/match_bool.rs @@ -5,20 +5,23 @@ fn match_bool() { let test: bool = true; match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + true => 0, false => 42, }; let option = 1; match option == 1 { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + true => 1, false => 0, }; match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + true => (), false => { println!("Noooo!"); @@ -26,7 +29,8 @@ fn match_bool() { }; match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + false => { println!("Noooo!"); }, @@ -34,7 +38,8 @@ fn match_bool() { }; match test && test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + false => { println!("Noooo!"); }, @@ -42,7 +47,8 @@ fn match_bool() { }; match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + false => { println!("Noooo!"); }, @@ -67,37 +73,43 @@ fn match_bool() { }; let _ = match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + true if option == 5 => 10, _ => 1, }; let _ = match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + false if option == 5 => 10, _ => 1, }; match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + true if option == 5 => println!("Hello"), _ => (), }; match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + true if option == 5 => (), _ => println!("Hello"), }; match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + false if option == 5 => println!("Hello"), _ => (), }; match test { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + false if option == 5 => (), _ => println!("Hello"), }; @@ -105,7 +117,8 @@ fn match_bool() { fn issue14099() { match true { - //~^ ERROR: `match` on a boolean expression + //~^ match_bool + true => 'a: { break 'a; }, diff --git a/tests/ui/match_bool.stderr b/tests/ui/match_bool.stderr index c05742e56339..c25aad27cef2 100644 --- a/tests/ui/match_bool.stderr +++ b/tests/ui/match_bool.stderr @@ -3,6 +3,7 @@ error: `match` on a boolean expression | LL | / match test { LL | | +LL | | LL | | true => 0, LL | | false => 42, LL | | }; @@ -15,23 +16,24 @@ LL | #![deny(clippy::match_bool)] | ^^^^^^^^^^^^^^^^^^ error: `match` on a boolean expression - --> tests/ui/match_bool.rs:14:5 + --> tests/ui/match_bool.rs:15:5 | LL | / match option == 1 { LL | | +LL | | LL | | true => 1, LL | | false => 0, LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if option == 1 { 1 } else { 0 }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:20:5 + --> tests/ui/match_bool.rs:22:5 | LL | / match test { LL | | +LL | | LL | | true => (), -LL | | false => { -LL | | println!("Noooo!"); +... | LL | | }, LL | | }; | |_____^ @@ -44,13 +46,13 @@ LL ~ }; | error: `match` on a boolean expression - --> tests/ui/match_bool.rs:28:5 + --> tests/ui/match_bool.rs:31:5 | LL | / match test { LL | | +LL | | LL | | false => { -LL | | println!("Noooo!"); -LL | | }, +... | LL | | _ => (), LL | | }; | |_____^ @@ -63,13 +65,13 @@ LL ~ }; | error: `match` on a boolean expression - --> tests/ui/match_bool.rs:36:5 + --> tests/ui/match_bool.rs:40:5 | LL | / match test && test { LL | | +LL | | LL | | false => { -LL | | println!("Noooo!"); -LL | | }, +... | LL | | _ => (), LL | | }; | |_____^ @@ -82,12 +84,12 @@ LL ~ }; | error: `match` on a boolean expression - --> tests/ui/match_bool.rs:44:5 + --> tests/ui/match_bool.rs:49:5 | LL | / match test { LL | | +LL | | LL | | false => { -LL | | println!("Noooo!"); ... | LL | | }, LL | | }; @@ -103,75 +105,81 @@ LL ~ }; | error: `match` on a boolean expression - --> tests/ui/match_bool.rs:69:13 + --> tests/ui/match_bool.rs:75:13 | LL | let _ = match test { | _____________^ LL | | +LL | | LL | | true if option == 5 => 10, LL | | _ => 1, LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if test && option == 5 { 10 } else { 1 }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:75:13 + --> tests/ui/match_bool.rs:82:13 | LL | let _ = match test { | _____________^ LL | | +LL | | LL | | false if option == 5 => 10, LL | | _ => 1, LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if !test && option == 5 { 10 } else { 1 }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:81:5 + --> tests/ui/match_bool.rs:89:5 | LL | / match test { LL | | +LL | | LL | | true if option == 5 => println!("Hello"), LL | | _ => (), LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if test && option == 5 { println!("Hello") }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:87:5 + --> tests/ui/match_bool.rs:96:5 | LL | / match test { LL | | +LL | | LL | | true if option == 5 => (), LL | | _ => println!("Hello"), LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if !(test && option == 5) { println!("Hello") }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:93:5 + --> tests/ui/match_bool.rs:103:5 | LL | / match test { LL | | +LL | | LL | | false if option == 5 => println!("Hello"), LL | | _ => (), LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if !test && option == 5 { println!("Hello") }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:99:5 + --> tests/ui/match_bool.rs:110:5 | LL | / match test { LL | | +LL | | LL | | false if option == 5 => (), LL | | _ => println!("Hello"), LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if !(!test && option == 5) { println!("Hello") }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:107:5 + --> tests/ui/match_bool.rs:119:5 | LL | / match true { LL | | +LL | | LL | | true => 'a: { -LL | | break 'a; -LL | | }, +... | LL | | _ => (), LL | | } | |_____^ diff --git a/tests/ui/match_expr_like_matches_macro.fixed b/tests/ui/match_expr_like_matches_macro.fixed index 05edc024ba9f..8530ab16bfd7 100644 --- a/tests/ui/match_expr_like_matches_macro.fixed +++ b/tests/ui/match_expr_like_matches_macro.fixed @@ -12,18 +12,23 @@ fn main() { // Lint let _y = matches!(x, Some(0)); + //~^^^^ match_like_matches_macro // Lint let _w = x.is_some(); + //~^^^^ redundant_pattern_matching // Turn into is_none let _z = x.is_none(); + //~^^^^ redundant_pattern_matching // Lint let _zz = !matches!(x, Some(r) if r == 0); + //~^^^^ match_like_matches_macro // Lint let _zzz = matches!(x, Some(5)); + //~^ match_like_matches_macro // No lint let _a = match x { @@ -48,16 +53,19 @@ fn main() { { // lint let _ans = matches!(x, E::A(_) | E::B(_)); + //~^^^^^ match_like_matches_macro } { // lint // skip rustfmt to prevent removing block for first pattern #[rustfmt::skip] let _ans = matches!(x, E::A(_) | E::B(_)); + //~^^^^^^^ match_like_matches_macro } { // lint let _ans = !matches!(x, E::B(_) | E::C); + //~^^^^^ match_like_matches_macro } { // no lint @@ -114,12 +122,14 @@ fn main() { // should print "z" in suggestion (#6503) let z = &Some(3); let _z = matches!(z, Some(3)); + //~^^^^ match_like_matches_macro } { // this could also print "z" in suggestion..? let z = Some(3); let _z = matches!(&z, Some(3)); + //~^^^^ match_like_matches_macro } { @@ -134,6 +144,7 @@ fn main() { let z = AnEnum::X; // we can't remove the reference here! let _ = matches!(&z, AnEnum::X); + //~^^^^ match_like_matches_macro foo(z); } } @@ -145,6 +156,7 @@ fn main() { let val = Some(S(42)); // we need the reference here because later val is consumed by fun() let _res = matches!(&val, &Some(ref _a)); + //~^^^^ match_like_matches_macro fun(val); } @@ -154,6 +166,7 @@ fn main() { fn fun(_val: Option) {} let val = Some(S(42)); let _res = matches!(&val, &Some(ref _a)); + //~^^^^ match_like_matches_macro fun(val); } @@ -209,4 +222,5 @@ fn msrv_1_41() { #[clippy::msrv = "1.42"] fn msrv_1_42() { let _y = matches!(Some(5), Some(0)); + //~^^^^ match_like_matches_macro } diff --git a/tests/ui/match_expr_like_matches_macro.rs b/tests/ui/match_expr_like_matches_macro.rs index d6a0313cde43..81017936889e 100644 --- a/tests/ui/match_expr_like_matches_macro.rs +++ b/tests/ui/match_expr_like_matches_macro.rs @@ -15,27 +15,32 @@ fn main() { Some(0) => true, _ => false, }; + //~^^^^ match_like_matches_macro // Lint let _w = match x { Some(_) => true, _ => false, }; + //~^^^^ redundant_pattern_matching // Turn into is_none let _z = match x { Some(_) => false, None => true, }; + //~^^^^ redundant_pattern_matching // Lint let _zz = match x { Some(r) if r == 0 => false, _ => true, }; + //~^^^^ match_like_matches_macro // Lint let _zzz = if let Some(5) = x { true } else { false }; + //~^ match_like_matches_macro // No lint let _a = match x { @@ -64,6 +69,7 @@ fn main() { E::B(_) => true, _ => false, }; + //~^^^^^ match_like_matches_macro } { // lint @@ -76,6 +82,7 @@ fn main() { E::B(_) => true, _ => false, }; + //~^^^^^^^ match_like_matches_macro } { // lint @@ -84,6 +91,7 @@ fn main() { E::C => false, _ => true, }; + //~^^^^^ match_like_matches_macro } { // no lint @@ -143,6 +151,7 @@ fn main() { Some(3) => true, _ => false, }; + //~^^^^ match_like_matches_macro } { @@ -152,6 +161,7 @@ fn main() { Some(3) => true, _ => false, }; + //~^^^^ match_like_matches_macro } { @@ -169,6 +179,7 @@ fn main() { AnEnum::X => true, _ => false, }; + //~^^^^ match_like_matches_macro foo(z); } } @@ -183,6 +194,7 @@ fn main() { &Some(ref _a) => true, _ => false, }; + //~^^^^ match_like_matches_macro fun(val); } @@ -195,6 +207,7 @@ fn main() { &Some(ref _a) => true, _ => false, }; + //~^^^^ match_like_matches_macro fun(val); } @@ -253,4 +266,5 @@ fn msrv_1_42() { Some(0) => true, _ => false, }; + //~^^^^ match_like_matches_macro } diff --git a/tests/ui/match_expr_like_matches_macro.stderr b/tests/ui/match_expr_like_matches_macro.stderr index ffe5772ece90..8fceb05bc6e8 100644 --- a/tests/ui/match_expr_like_matches_macro.stderr +++ b/tests/ui/match_expr_like_matches_macro.stderr @@ -12,7 +12,7 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::match_like_matches_macro)]` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/match_expr_like_matches_macro.rs:20:14 + --> tests/ui/match_expr_like_matches_macro.rs:21:14 | LL | let _w = match x { | ______________^ @@ -25,7 +25,7 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/match_expr_like_matches_macro.rs:26:14 + --> tests/ui/match_expr_like_matches_macro.rs:28:14 | LL | let _z = match x { | ______________^ @@ -35,7 +35,7 @@ LL | | }; | |_____^ help: try: `x.is_none()` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:32:15 + --> tests/ui/match_expr_like_matches_macro.rs:35:15 | LL | let _zz = match x { | _______________^ @@ -45,13 +45,13 @@ LL | | }; | |_____^ help: try: `!matches!(x, Some(r) if r == 0)` error: if let .. else expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:38:16 + --> tests/ui/match_expr_like_matches_macro.rs:42:16 | LL | let _zzz = if let Some(5) = x { true } else { false }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(x, Some(5))` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:62:20 + --> tests/ui/match_expr_like_matches_macro.rs:67:20 | LL | let _ans = match x { | ____________________^ @@ -62,7 +62,7 @@ LL | | }; | |_________^ help: try: `matches!(x, E::A(_) | E::B(_))` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:72:20 + --> tests/ui/match_expr_like_matches_macro.rs:78:20 | LL | let _ans = match x { | ____________________^ @@ -74,7 +74,7 @@ LL | | }; | |_________^ help: try: `matches!(x, E::A(_) | E::B(_))` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:82:20 + --> tests/ui/match_expr_like_matches_macro.rs:89:20 | LL | let _ans = match x { | ____________________^ @@ -85,7 +85,7 @@ LL | | }; | |_________^ help: try: `!matches!(x, E::B(_) | E::C)` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:142:18 + --> tests/ui/match_expr_like_matches_macro.rs:150:18 | LL | let _z = match &z { | __________________^ @@ -95,7 +95,7 @@ LL | | }; | |_________^ help: try: `matches!(z, Some(3))` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:151:18 + --> tests/ui/match_expr_like_matches_macro.rs:160:18 | LL | let _z = match &z { | __________________^ @@ -105,7 +105,7 @@ LL | | }; | |_________^ help: try: `matches!(&z, Some(3))` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:168:21 + --> tests/ui/match_expr_like_matches_macro.rs:178:21 | LL | let _ = match &z { | _____________________^ @@ -115,7 +115,7 @@ LL | | }; | |_____________^ help: try: `matches!(&z, AnEnum::X)` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:182:20 + --> tests/ui/match_expr_like_matches_macro.rs:193:20 | LL | let _res = match &val { | ____________________^ @@ -125,7 +125,7 @@ LL | | }; | |_________^ help: try: `matches!(&val, &Some(ref _a))` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:194:20 + --> tests/ui/match_expr_like_matches_macro.rs:206:20 | LL | let _res = match &val { | ____________________^ @@ -135,7 +135,7 @@ LL | | }; | |_________^ help: try: `matches!(&val, &Some(ref _a))` error: match expression looks like `matches!` macro - --> tests/ui/match_expr_like_matches_macro.rs:252:14 + --> tests/ui/match_expr_like_matches_macro.rs:265:14 | LL | let _y = match Some(5) { | ______________^ diff --git a/tests/ui/match_on_vec_items.rs b/tests/ui/match_on_vec_items.rs index f7b8500faa4a..1b7ce69f3ae7 100644 --- a/tests/ui/match_on_vec_items.rs +++ b/tests/ui/match_on_vec_items.rs @@ -8,8 +8,9 @@ fn match_with_wildcard() { // Lint, may panic match arr[idx] { - //~^ ERROR: indexing into a vector may panic - //~| NOTE: `-D clippy::match-on-vec-items` implied by `-D warnings` + //~^ match_on_vec_items + + 0 => println!("0"), 1 => println!("1"), _ => {}, @@ -17,7 +18,8 @@ fn match_with_wildcard() { // Lint, may panic match arr[range] { - //~^ ERROR: indexing into a vector may panic + //~^ match_on_vec_items + [0, 1] => println!("0 1"), [1, 2] => println!("1 2"), _ => {}, @@ -31,7 +33,8 @@ fn match_without_wildcard() { // Lint, may panic match arr[idx] { - //~^ ERROR: indexing into a vector may panic + //~^ match_on_vec_items + 0 => println!("0"), 1 => println!("1"), num => {}, @@ -39,7 +42,8 @@ fn match_without_wildcard() { // Lint, may panic match arr[range] { - //~^ ERROR: indexing into a vector may panic + //~^ match_on_vec_items + [0, 1] => println!("0 1"), [1, 2] => println!("1 2"), [ref sub @ ..] => {}, @@ -53,7 +57,8 @@ fn match_wildcard_and_action() { // Lint, may panic match arr[idx] { - //~^ ERROR: indexing into a vector may panic + //~^ match_on_vec_items + 0 => println!("0"), 1 => println!("1"), _ => println!("Hello, World!"), @@ -61,7 +66,8 @@ fn match_wildcard_and_action() { // Lint, may panic match arr[range] { - //~^ ERROR: indexing into a vector may panic + //~^ match_on_vec_items + [0, 1] => println!("0 1"), [1, 2] => println!("1 2"), _ => println!("Hello, World!"), @@ -75,7 +81,8 @@ fn match_vec_ref() { // Lint, may panic match arr[idx] { - //~^ ERROR: indexing into a vector may panic + //~^ match_on_vec_items + 0 => println!("0"), 1 => println!("1"), _ => {}, @@ -83,7 +90,8 @@ fn match_vec_ref() { // Lint, may panic match arr[range] { - //~^ ERROR: indexing into a vector may panic + //~^ match_on_vec_items + [0, 1] => println!("0 1"), [1, 2] => println!("1 2"), _ => {}, diff --git a/tests/ui/match_on_vec_items.stderr b/tests/ui/match_on_vec_items.stderr index e31db3784137..b00b2cb662a0 100644 --- a/tests/ui/match_on_vec_items.stderr +++ b/tests/ui/match_on_vec_items.stderr @@ -8,43 +8,43 @@ LL | match arr[idx] { = help: to override `-D warnings` add `#[allow(clippy::match_on_vec_items)]` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:19:11 + --> tests/ui/match_on_vec_items.rs:20:11 | LL | match arr[range] { | ^^^^^^^^^^ help: try: `arr.get(range)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:33:11 + --> tests/ui/match_on_vec_items.rs:35:11 | LL | match arr[idx] { | ^^^^^^^^ help: try: `arr.get(idx)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:41:11 + --> tests/ui/match_on_vec_items.rs:44:11 | LL | match arr[range] { | ^^^^^^^^^^ help: try: `arr.get(range)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:55:11 + --> tests/ui/match_on_vec_items.rs:59:11 | LL | match arr[idx] { | ^^^^^^^^ help: try: `arr.get(idx)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:63:11 + --> tests/ui/match_on_vec_items.rs:68:11 | LL | match arr[range] { | ^^^^^^^^^^ help: try: `arr.get(range)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:77:11 + --> tests/ui/match_on_vec_items.rs:83:11 | LL | match arr[idx] { | ^^^^^^^^ help: try: `arr.get(idx)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:85:11 + --> tests/ui/match_on_vec_items.rs:92:11 | LL | match arr[range] { | ^^^^^^^^^^ help: try: `arr.get(range)` diff --git a/tests/ui/match_overlapping_arm.rs b/tests/ui/match_overlapping_arm.rs index a056fdeaa5d0..3885731264f7 100644 --- a/tests/ui/match_overlapping_arm.rs +++ b/tests/ui/match_overlapping_arm.rs @@ -7,14 +7,16 @@ fn overlapping() { match 42 { 0..=10 => println!("0..=10"), - //~^ ERROR: some ranges overlap + //~^ match_overlapping_arm + 0..=11 => println!("0..=11"), _ => (), } match 42 { 0..=5 => println!("0..=5"), - //~^ ERROR: some ranges overlap + //~^ match_overlapping_arm + 6..=7 => println!("6..=7"), FOO..=11 => println!("FOO..=11"), _ => (), @@ -52,7 +54,8 @@ fn overlapping() { match 42 { 0..11 => println!("0..11"), - //~^ ERROR: some ranges overlap + //~^ match_overlapping_arm + 0..=11 => println!("0..=11"), _ => (), } @@ -78,13 +81,15 @@ fn overlapping() { match 42 { 5..14 => println!("5..14"), 0..=10 => println!("0..=10"), - //~^ ERROR: some ranges overlap + //~^ match_overlapping_arm + _ => (), } match 42 { 0..7 => println!("0..7"), - //~^ ERROR: some ranges overlap + //~^ match_overlapping_arm + 0..=10 => println!("0..=10"), _ => (), } @@ -97,7 +102,8 @@ fn overlapping() { match 42 { ..=23 => println!("..=23"), - //~^ ERROR: some ranges overlap + //~^ match_overlapping_arm + ..26 => println!("..26"), _ => (), } @@ -107,7 +113,8 @@ fn overlapping() { 5..=10 => (), 0..=20 => (), 21..=30 => (), - //~^ ERROR: some ranges overlap + //~^ match_overlapping_arm + 21..=40 => (), _ => (), } @@ -122,7 +129,8 @@ fn overlapping() { // Only warn about the first if there are multiple overlaps match 42u128 { 0..=0x0000_0000_0000_00ff => (), - //~^ ERROR: some ranges overlap + //~^ match_overlapping_arm + 0..=0x0000_0000_0000_ffff => (), 0..=0x0000_0000_ffff_ffff => (), 0..=0xffff_ffff_ffff_ffff => (), diff --git a/tests/ui/match_overlapping_arm.stderr b/tests/ui/match_overlapping_arm.stderr index a60a09a07990..cc928b4066a9 100644 --- a/tests/ui/match_overlapping_arm.stderr +++ b/tests/ui/match_overlapping_arm.stderr @@ -5,7 +5,7 @@ LL | 0..=10 => println!("0..=10"), | ^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:11:9 + --> tests/ui/match_overlapping_arm.rs:12:9 | LL | 0..=11 => println!("0..=11"), | ^^^^^^ @@ -13,85 +13,85 @@ LL | 0..=11 => println!("0..=11"), = help: to override `-D warnings` add `#[allow(clippy::match_overlapping_arm)]` error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:16:9 + --> tests/ui/match_overlapping_arm.rs:17:9 | LL | 0..=5 => println!("0..=5"), | ^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:19:9 + --> tests/ui/match_overlapping_arm.rs:21:9 | LL | FOO..=11 => println!("FOO..=11"), | ^^^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:54:9 + --> tests/ui/match_overlapping_arm.rs:56:9 | LL | 0..11 => println!("0..11"), | ^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:56:9 + --> tests/ui/match_overlapping_arm.rs:59:9 | LL | 0..=11 => println!("0..=11"), | ^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:80:9 + --> tests/ui/match_overlapping_arm.rs:83:9 | LL | 0..=10 => println!("0..=10"), | ^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:79:9 + --> tests/ui/match_overlapping_arm.rs:82:9 | LL | 5..14 => println!("5..14"), | ^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:86:9 + --> tests/ui/match_overlapping_arm.rs:90:9 | LL | 0..7 => println!("0..7"), | ^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:88:9 + --> tests/ui/match_overlapping_arm.rs:93:9 | LL | 0..=10 => println!("0..=10"), | ^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:99:9 + --> tests/ui/match_overlapping_arm.rs:104:9 | LL | ..=23 => println!("..=23"), | ^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:101:9 + --> tests/ui/match_overlapping_arm.rs:107:9 | LL | ..26 => println!("..26"), | ^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:109:9 + --> tests/ui/match_overlapping_arm.rs:115:9 | LL | 21..=30 => (), | ^^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:111:9 + --> tests/ui/match_overlapping_arm.rs:118:9 | LL | 21..=40 => (), | ^^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:124:9 + --> tests/ui/match_overlapping_arm.rs:131:9 | LL | 0..=0x0000_0000_0000_00ff => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:126:9 + --> tests/ui/match_overlapping_arm.rs:134:9 | LL | 0..=0x0000_0000_0000_ffff => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/match_ref_pats.fixed b/tests/ui/match_ref_pats.fixed index f8d47b0fdc7d..8ada28985198 100644 --- a/tests/ui/match_ref_pats.fixed +++ b/tests/ui/match_ref_pats.fixed @@ -6,6 +6,7 @@ fn ref_pats() { { let v = &Some(0); match *v { + //~^ match_ref_pats Some(v) => println!("{:?}", v), None => println!("none"), } @@ -23,6 +24,7 @@ fn ref_pats() { // Special case: using `&` both in expr and pats. let w = Some(0); match w { + //~^ match_ref_pats Some(v) => println!("{:?}", v), None => println!("none"), } @@ -35,11 +37,13 @@ fn ref_pats() { let a = &Some(0); if a.is_none() { + //~^ redundant_pattern_matching println!("none"); } let b = Some(0); if b.is_none() { + //~^ redundant_pattern_matching println!("none"); } } @@ -100,6 +104,7 @@ mod issue_7740 { fn issue_7740() { // Issue #7740 match *foobar_variant!(0) { + //~^ match_ref_pats FooBar::Foo => println!("Foo"), FooBar::Bar => println!("Bar"), FooBar::FooBar => println!("FooBar"), diff --git a/tests/ui/match_ref_pats.rs b/tests/ui/match_ref_pats.rs index bcd7bf7ab51b..cac6240bde31 100644 --- a/tests/ui/match_ref_pats.rs +++ b/tests/ui/match_ref_pats.rs @@ -6,6 +6,7 @@ fn ref_pats() { { let v = &Some(0); match v { + //~^ match_ref_pats &Some(v) => println!("{:?}", v), &None => println!("none"), } @@ -23,6 +24,7 @@ fn ref_pats() { // Special case: using `&` both in expr and pats. let w = Some(0); match &w { + //~^ match_ref_pats &Some(v) => println!("{:?}", v), &None => println!("none"), } @@ -35,11 +37,13 @@ fn ref_pats() { let a = &Some(0); if let &None = a { + //~^ redundant_pattern_matching println!("none"); } let b = Some(0); if let &None = &b { + //~^ redundant_pattern_matching println!("none"); } } @@ -100,6 +104,7 @@ mod issue_7740 { fn issue_7740() { // Issue #7740 match foobar_variant!(0) { + //~^ match_ref_pats &FooBar::Foo => println!("Foo"), &FooBar::Bar => println!("Bar"), &FooBar::FooBar => println!("FooBar"), diff --git a/tests/ui/match_ref_pats.stderr b/tests/ui/match_ref_pats.stderr index fc01ab0a919a..f81b290b32cb 100644 --- a/tests/ui/match_ref_pats.stderr +++ b/tests/ui/match_ref_pats.stderr @@ -2,6 +2,7 @@ error: you don't need to add `&` to all patterns --> tests/ui/match_ref_pats.rs:8:9 | LL | / match v { +LL | | LL | | &Some(v) => println!("{:?}", v), LL | | &None => println!("none"), LL | | } @@ -12,14 +13,16 @@ LL | | } help: instead of prefixing all patterns with `&`, you can dereference the expression | LL ~ match *v { +LL | LL ~ Some(v) => println!("{:?}", v), LL ~ None => println!("none"), | error: you don't need to add `&` to both the expression and the patterns - --> tests/ui/match_ref_pats.rs:25:5 + --> tests/ui/match_ref_pats.rs:26:5 | LL | / match &w { +LL | | LL | | &Some(v) => println!("{:?}", v), LL | | &None => println!("none"), LL | | } @@ -28,12 +31,13 @@ LL | | } help: try | LL ~ match w { +LL | LL ~ Some(v) => println!("{:?}", v), LL ~ None => println!("none"), | error: redundant pattern matching, consider using `is_none()` - --> tests/ui/match_ref_pats.rs:37:12 + --> tests/ui/match_ref_pats.rs:39:12 | LL | if let &None = a { | -------^^^^^---- help: try: `if a.is_none()` @@ -42,15 +46,16 @@ LL | if let &None = a { = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/match_ref_pats.rs:42:12 + --> tests/ui/match_ref_pats.rs:45:12 | LL | if let &None = &b { | -------^^^^^----- help: try: `if b.is_none()` error: you don't need to add `&` to all patterns - --> tests/ui/match_ref_pats.rs:102:9 + --> tests/ui/match_ref_pats.rs:106:9 | LL | / match foobar_variant!(0) { +LL | | LL | | &FooBar::Foo => println!("Foo"), LL | | &FooBar::Bar => println!("Bar"), LL | | &FooBar::FooBar => println!("FooBar"), @@ -61,6 +66,7 @@ LL | | } help: instead of prefixing all patterns with `&`, you can dereference the expression | LL ~ match *foobar_variant!(0) { +LL | LL ~ FooBar::Foo => println!("Foo"), LL ~ FooBar::Bar => println!("Bar"), LL ~ FooBar::FooBar => println!("FooBar"), diff --git a/tests/ui/match_result_ok.fixed b/tests/ui/match_result_ok.fixed index 117e0bc68ccc..2032394f0e92 100644 --- a/tests/ui/match_result_ok.fixed +++ b/tests/ui/match_result_ok.fixed @@ -11,6 +11,7 @@ fn str_to_int(x: &str) -> i32 { if let Ok(y) = x.parse() { y } else { 0 } + //~^ match_result_ok } fn str_to_int_ok(x: &str) -> i32 { @@ -21,6 +22,7 @@ fn str_to_int_ok(x: &str) -> i32 { fn strange_some_no_else(x: &str) -> i32 { { if let Ok(y) = x . parse() { + //~^ match_result_ok return y; }; 0 @@ -47,6 +49,7 @@ impl Wat { fn base_1(x: i32) { let mut wat = Wat { counter: x }; while let Ok(a) = wat.next() { + //~^ match_result_ok println!("{}", a); } } diff --git a/tests/ui/match_result_ok.rs b/tests/ui/match_result_ok.rs index f8a5269024da..c15e32d112d4 100644 --- a/tests/ui/match_result_ok.rs +++ b/tests/ui/match_result_ok.rs @@ -11,6 +11,7 @@ fn str_to_int(x: &str) -> i32 { if let Some(y) = x.parse().ok() { y } else { 0 } + //~^ match_result_ok } fn str_to_int_ok(x: &str) -> i32 { @@ -21,6 +22,7 @@ fn str_to_int_ok(x: &str) -> i32 { fn strange_some_no_else(x: &str) -> i32 { { if let Some(y) = x . parse() . ok () { + //~^ match_result_ok return y; }; 0 @@ -47,6 +49,7 @@ impl Wat { fn base_1(x: i32) { let mut wat = Wat { counter: x }; while let Some(a) = wat.next().ok() { + //~^ match_result_ok println!("{}", a); } } diff --git a/tests/ui/match_result_ok.stderr b/tests/ui/match_result_ok.stderr index b5b91cbe5534..ccdf53230757 100644 --- a/tests/ui/match_result_ok.stderr +++ b/tests/ui/match_result_ok.stderr @@ -12,7 +12,7 @@ LL | if let Ok(y) = x.parse() { y } else { 0 } | ~~~~~~~~~~~~~~~~~~~~~~~~ error: matching on `Some` with `ok()` is redundant - --> tests/ui/match_result_ok.rs:23:9 + --> tests/ui/match_result_ok.rs:24:9 | LL | if let Some(y) = x . parse() . ok () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | if let Ok(y) = x . parse() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: matching on `Some` with `ok()` is redundant - --> tests/ui/match_result_ok.rs:49:5 + --> tests/ui/match_result_ok.rs:51:5 | LL | while let Some(a) = wat.next().ok() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/match_same_arms.rs b/tests/ui/match_same_arms.rs index 2f4652dcf32b..073c66930357 100644 --- a/tests/ui/match_same_arms.rs +++ b/tests/ui/match_same_arms.rs @@ -9,30 +9,37 @@ pub enum Abc { fn match_same_arms() { let _ = match Abc::A { - Abc::A => 0, //~ ERROR: this match arm has an identical body to the `_` wildcard arm +Abc::A => 0, +//~^ match_same_arms Abc::B => 1, _ => 0, }; match (1, 2, 3) { - (1, .., 3) => 42, //~ ERROR: this match arm has an identical body to another arm +(1, .., 3) => 42, +//~^ match_same_arms (.., 3) => 42, _ => 0, }; let _ = match 42 { 42 => 1, - 51 => 1, //~ ERROR: this match arm has an identical body to another arm - 41 => 2, //~ ERROR: this match arm has an identical body to another arm +51 => 1, +//~^ match_same_arms +41 => 2, +//~^ match_same_arms 52 => 2, _ => 0, }; let _ = match 42 { 1 => 2, - 2 => 2, //~ ERROR: this match arm has an identical body to another arm - //~^ ERROR: this match arm has an identical body to another arm - 3 => 2, //~ ERROR: this match arm has an identical body to another arm +2 => 2, +//~^ match_same_arms +//~| match_same_arms + +3 => 2, +//~^ match_same_arms 4 => 3, _ => 0, }; @@ -50,7 +57,8 @@ mod issue4244 { match self { CommandInfo::BuiltIn { name, .. } => name.to_string(), CommandInfo::External { name, .. } => name.to_string(), - //~^ ERROR: this match arm has an identical body to another arm + //~^ match_same_arms + } } } diff --git a/tests/ui/match_same_arms.stderr b/tests/ui/match_same_arms.stderr index 4a4772da143a..a269c4f39267 100644 --- a/tests/ui/match_same_arms.stderr +++ b/tests/ui/match_same_arms.stderr @@ -1,12 +1,13 @@ error: this match arm has an identical body to the `_` wildcard arm - --> tests/ui/match_same_arms.rs:12:9 + --> tests/ui/match_same_arms.rs:12:1 | -LL | Abc::A => 0, - | ^^^^^^^^^^^^^ help: try removing the arm +LL | / Abc::A => 0, +LL | | + | |_^ help: try removing the arm | = help: or try changing either arm body note: `_` wildcard arm here - --> tests/ui/match_same_arms.rs:14:9 + --> tests/ui/match_same_arms.rs:15:9 | LL | _ => 0, | ^^^^^^ @@ -14,89 +15,91 @@ LL | _ => 0, = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]` error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:18:9 + --> tests/ui/match_same_arms.rs:19:1 | -LL | (1, .., 3) => 42, - | ^^^^^^^^^^^^^^^^ +LL | (1, .., 3) => 42, + | ^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ (1, .., 3) | (.., 3) => 42, +LL ~ (1, .., 3) | (.., 3) => 42, +LL | LL ~ _ => 0, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:25:9 + --> tests/ui/match_same_arms.rs:27:1 | -LL | 51 => 1, - | ^^^^^^^ +LL | 51 => 1, + | ^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - 42 => 1, -LL - 51 => 1, +LL - 51 => 1, LL + 51 | 42 => 1, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:26:9 + --> tests/ui/match_same_arms.rs:29:1 | -LL | 41 => 2, - | ^^^^^^^ +LL | 41 => 2, + | ^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ 41 | 52 => 2, +LL ~ 41 | 52 => 2, +LL | LL ~ _ => 0, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:33:9 + --> tests/ui/match_same_arms.rs:37:1 | -LL | 2 => 2, - | ^^^^^^ +LL | 2 => 2, + | ^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - 1 => 2, -LL - 2 => 2, +LL - 2 => 2, LL + 2 | 1 => 2, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:35:9 + --> tests/ui/match_same_arms.rs:41:1 | -LL | 3 => 2, - | ^^^^^^ +LL | 3 => 2, + | ^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL ~ 2 => 2, LL | -LL ~ 3 | 1 => 2, +LL | +LL | +LL ~ 3 | 1 => 2, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:33:9 + --> tests/ui/match_same_arms.rs:37:1 | -LL | 2 => 2, - | ^^^^^^ +LL | 2 => 2, + | ^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ 2 | 3 => 2, -LL | -LL ~ +LL ~ 2 | 3 => 2, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:52:17 + --> tests/ui/match_same_arms.rs:59:17 | LL | CommandInfo::External { name, .. } => name.to_string(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/match_same_arms2.fixed b/tests/ui/match_same_arms2.fixed index b7d377f1ebff..855c3287532c 100644 --- a/tests/ui/match_same_arms2.fixed +++ b/tests/ui/match_same_arms2.fixed @@ -14,6 +14,7 @@ fn foo() -> bool { fn match_same_arms() { let _ = match 42 { + //~^^^^^^^^^ match_same_arms _ => { foo(); let mut a = 42 + [23].len() as i32; @@ -24,15 +25,17 @@ fn match_same_arms() { a }, }; - //~^^^^^^^^^^^^^^^^^^^ ERROR: this match arm has an identical body to the `_` wildcard arm + let _ = match 42 { - 51 | 42 => foo(), //~ ERROR: this match arm has an identical body to another arm + 51 | 42 => foo(), +//~^ match_same_arms _ => true, }; let _ = match Some(42) { - None | Some(_) => 24, //~ ERROR: this match arm has an identical body to another arm + None | Some(_) => 24, +//~^ match_same_arms }; let _ = match Some(42) { @@ -53,7 +56,8 @@ fn match_same_arms() { }; match (Some(42), Some(42)) { - (None, Some(a)) | (Some(a), None) => bar(a), //~ ERROR: this match arm has an identical body to another arm + (None, Some(a)) | (Some(a), None) => bar(a), +//~^ match_same_arms _ => (), } @@ -66,12 +70,14 @@ fn match_same_arms() { }; let _ = match (Some(42), Some(42)) { - (None, Some(a)) | (Some(a), None) if a == 42 => a, //~ ERROR: this match arm has an identical body to another arm + (None, Some(a)) | (Some(a), None) if a == 42 => a, +//~^ match_same_arms _ => 0, }; match (Some(42), Some(42)) { - (Some(a), ..) | (.., Some(a)) => bar(a), //~ ERROR: this match arm has an identical body to another arm +(Some(a), ..) | (.., Some(a)) => bar(a), +//~^ match_same_arms _ => (), } @@ -104,7 +110,8 @@ fn match_same_arms() { } match (x, Some(1i32)) { - (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), //~ ERROR: this match arm has an identical body to another arm +(Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), +//~^ match_same_arms _ => println!("err"), } @@ -118,7 +125,8 @@ fn match_same_arms() { // False negative #2251. match x { Ok(_tmp) => println!("ok"), - Ok(_) | Ok(3) => println!("ok"), //~ ERROR: this match arm has an identical body to another arm + Ok(_) | Ok(3) => println!("ok"), +//~^ match_same_arms Err(_) => { unreachable!(); }, @@ -145,11 +153,12 @@ fn match_same_arms() { 1 | 0 => { empty!(0); }, + //~^^^ match_same_arms x => { empty!(x); }, } - //~^^^^^^^ ERROR: this match arm has an identical body to another arm + match_expr_like_matches_macro_priority(); } @@ -193,7 +202,8 @@ fn main() { // Suggest moving `Foo::Z(_)` up. let _ = match Foo::X(0) { - Foo::X(0) | Foo::Z(_) => 1, //~ ERROR: this match arm has an identical body to another arm +Foo::X(0) | Foo::Z(_) => 1, +//~^ match_same_arms Foo::X(_) | Foo::Y(_) => 2, _ => 0, }; @@ -201,7 +211,8 @@ fn main() { // Suggest moving `Foo::X(0)` down. let _ = match Foo::X(0) { Foo::Y(_) | Foo::Z(0) => 2, - Foo::Z(_) | Foo::X(0) => 1, //~ ERROR: this match arm has an identical body to another arm +Foo::Z(_) | Foo::X(0) => 1, +//~^ match_same_arms _ => 0, }; @@ -223,7 +234,8 @@ fn main() { let _ = match None { Some(Bar { y: 10, z: 0, .. }) => 2, None => 50, - Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, //~ ERROR: this match arm has an identical body to another arm +Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, +//~^ match_same_arms _ => 200, }; @@ -237,6 +249,7 @@ fn main() { let _ = match 0 { 1 | 0 => cfg!(not_enable), + //~^ match_same_arms _ => false, }; } @@ -252,7 +265,8 @@ mod with_lifetime { fn get(&self) -> &'a str { match *self { MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s, - //~^ ERROR: this match arm has an identical body to another arm + //~^ match_same_arms + } } } diff --git a/tests/ui/match_same_arms2.rs b/tests/ui/match_same_arms2.rs index dfd15d10c3d3..73a4fd432551 100644 --- a/tests/ui/match_same_arms2.rs +++ b/tests/ui/match_same_arms2.rs @@ -23,6 +23,7 @@ fn match_same_arms() { a = -31 - a; a }, + //~^^^^^^^^^ match_same_arms _ => { foo(); let mut a = 42 + [23].len() as i32; @@ -33,17 +34,19 @@ fn match_same_arms() { a }, }; - //~^^^^^^^^^^^^^^^^^^^ ERROR: this match arm has an identical body to the `_` wildcard arm + let _ = match 42 { 42 => foo(), - 51 => foo(), //~ ERROR: this match arm has an identical body to another arm +51 => foo(), +//~^ match_same_arms _ => true, }; let _ = match Some(42) { Some(_) => 24, - None => 24, //~ ERROR: this match arm has an identical body to another arm +None => 24, +//~^ match_same_arms }; let _ = match Some(42) { @@ -65,7 +68,8 @@ fn match_same_arms() { match (Some(42), Some(42)) { (Some(a), None) => bar(a), - (None, Some(a)) => bar(a), //~ ERROR: this match arm has an identical body to another arm +(None, Some(a)) => bar(a), +//~^ match_same_arms _ => (), } @@ -79,12 +83,14 @@ fn match_same_arms() { let _ = match (Some(42), Some(42)) { (Some(a), None) if a == 42 => a, - (None, Some(a)) if a == 42 => a, //~ ERROR: this match arm has an identical body to another arm +(None, Some(a)) if a == 42 => a, +//~^ match_same_arms _ => 0, }; match (Some(42), Some(42)) { - (Some(a), ..) => bar(a), //~ ERROR: this match arm has an identical body to another arm +(Some(a), ..) => bar(a), +//~^ match_same_arms (.., Some(a)) => bar(a), _ => (), } @@ -118,7 +124,8 @@ fn match_same_arms() { } match (x, Some(1i32)) { - (Ok(x), Some(_)) => println!("ok {}", x), //~ ERROR: this match arm has an identical body to another arm +(Ok(x), Some(_)) => println!("ok {}", x), +//~^ match_same_arms (Ok(_), Some(x)) => println!("ok {}", x), _ => println!("err"), } @@ -134,7 +141,8 @@ fn match_same_arms() { match x { Ok(_tmp) => println!("ok"), Ok(3) => println!("ok"), - Ok(_) => println!("ok"), //~ ERROR: this match arm has an identical body to another arm +Ok(_) => println!("ok"), +//~^ match_same_arms Err(_) => { unreachable!(); }, @@ -164,11 +172,12 @@ fn match_same_arms() { 1 => { empty!(0); }, + //~^^^ match_same_arms x => { empty!(x); }, } - //~^^^^^^^ ERROR: this match arm has an identical body to another arm + match_expr_like_matches_macro_priority(); } @@ -212,7 +221,8 @@ fn main() { // Suggest moving `Foo::Z(_)` up. let _ = match Foo::X(0) { - Foo::X(0) => 1, //~ ERROR: this match arm has an identical body to another arm +Foo::X(0) => 1, +//~^ match_same_arms Foo::X(_) | Foo::Y(_) => 2, Foo::Z(_) => 1, _ => 0, @@ -222,7 +232,8 @@ fn main() { let _ = match Foo::X(0) { Foo::X(0) => 1, Foo::Y(_) | Foo::Z(0) => 2, - Foo::Z(_) => 1, //~ ERROR: this match arm has an identical body to another arm +Foo::Z(_) => 1, +//~^ match_same_arms _ => 0, }; @@ -245,7 +256,8 @@ fn main() { Some(Bar { x: 0, y: 5, .. }) => 1, Some(Bar { y: 10, z: 0, .. }) => 2, None => 50, - Some(Bar { y: 0, x: 5, .. }) => 1, //~ ERROR: this match arm has an identical body to another arm +Some(Bar { y: 0, x: 5, .. }) => 1, +//~^ match_same_arms _ => 200, }; @@ -260,6 +272,7 @@ fn main() { let _ = match 0 { 0 => cfg!(not_enable), 1 => cfg!(not_enable), + //~^ match_same_arms _ => false, }; } @@ -276,7 +289,8 @@ mod with_lifetime { match *self { MaybeStaticStr::Static(s) => s, MaybeStaticStr::Borrowed(s) => s, - //~^ ERROR: this match arm has an identical body to another arm + //~^ match_same_arms + } } } diff --git a/tests/ui/match_same_arms2.stderr b/tests/ui/match_same_arms2.stderr index 525a25e9287b..c67ac5475aae 100644 --- a/tests/ui/match_same_arms2.stderr +++ b/tests/ui/match_same_arms2.stderr @@ -7,12 +7,12 @@ LL | | let mut a = 42 + [23].len() as i32; LL | | if true { ... | LL | | }, -LL | | _ => { +LL | | | |________^ help: try removing the arm | = help: or try changing either arm body note: `_` wildcard arm here - --> tests/ui/match_same_arms2.rs:26:9 + --> tests/ui/match_same_arms2.rs:27:9 | LL | / _ => { LL | | foo(); @@ -26,103 +26,105 @@ LL | | }, = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]` error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:40:9 + --> tests/ui/match_same_arms2.rs:41:1 | -LL | 51 => foo(), - | ^^^^^^^^^^^ +LL | 51 => foo(), + | ^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - 42 => foo(), -LL - 51 => foo(), +LL - 51 => foo(), LL + 51 | 42 => foo(), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:46:9 + --> tests/ui/match_same_arms2.rs:48:1 | -LL | None => 24, - | ^^^^^^^^^^ +LL | None => 24, + | ^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - Some(_) => 24, -LL - None => 24, +LL - None => 24, LL + None | Some(_) => 24, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:68:9 + --> tests/ui/match_same_arms2.rs:71:1 | -LL | (None, Some(a)) => bar(a), - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (None, Some(a)) => bar(a), + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - (Some(a), None) => bar(a), -LL - (None, Some(a)) => bar(a), +LL - (None, Some(a)) => bar(a), LL + (None, Some(a)) | (Some(a), None) => bar(a), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:82:9 + --> tests/ui/match_same_arms2.rs:86:1 | -LL | (None, Some(a)) if a == 42 => a, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (None, Some(a)) if a == 42 => a, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - (Some(a), None) if a == 42 => a, -LL - (None, Some(a)) if a == 42 => a, +LL - (None, Some(a)) if a == 42 => a, LL + (None, Some(a)) | (Some(a), None) if a == 42 => a, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:87:9 + --> tests/ui/match_same_arms2.rs:92:1 | -LL | (Some(a), ..) => bar(a), - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | (Some(a), ..) => bar(a), + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ (Some(a), ..) | (.., Some(a)) => bar(a), +LL ~ (Some(a), ..) | (.., Some(a)) => bar(a), +LL | LL ~ _ => (), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:121:9 + --> tests/ui/match_same_arms2.rs:127:1 | -LL | (Ok(x), Some(_)) => println!("ok {}", x), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (Ok(x), Some(_)) => println!("ok {}", x), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), +LL ~ (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), +LL | LL ~ _ => println!("err"), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:137:9 + --> tests/ui/match_same_arms2.rs:144:1 | -LL | Ok(_) => println!("ok"), - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | Ok(_) => println!("ok"), + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - Ok(3) => println!("ok"), -LL - Ok(_) => println!("ok"), +LL - Ok(_) => println!("ok"), LL + Ok(_) | Ok(3) => println!("ok"), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:164:9 + --> tests/ui/match_same_arms2.rs:172:9 | LL | / 1 => { LL | | empty!(0); @@ -140,48 +142,49 @@ LL + 1 | 0 => { | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:215:9 + --> tests/ui/match_same_arms2.rs:224:1 | -LL | Foo::X(0) => 1, - | ^^^^^^^^^^^^^^ +LL | Foo::X(0) => 1, + | ^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ Foo::X(0) | Foo::Z(_) => 1, +LL ~ Foo::X(0) | Foo::Z(_) => 1, +LL | LL | Foo::X(_) | Foo::Y(_) => 2, LL ~ _ => 0, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:225:9 + --> tests/ui/match_same_arms2.rs:235:1 | -LL | Foo::Z(_) => 1, - | ^^^^^^^^^^^^^^ +LL | Foo::Z(_) => 1, + | ^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL ~ Foo::Y(_) | Foo::Z(0) => 2, -LL ~ Foo::Z(_) | Foo::X(0) => 1, +LL ~ Foo::Z(_) | Foo::X(0) => 1, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:248:9 + --> tests/ui/match_same_arms2.rs:259:1 | -LL | Some(Bar { y: 0, x: 5, .. }) => 1, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Some(Bar { y: 0, x: 5, .. }) => 1, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL ~ Some(Bar { y: 10, z: 0, .. }) => 2, LL | None => 50, -LL ~ Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, +LL ~ Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:262:9 + --> tests/ui/match_same_arms2.rs:274:9 | LL | 1 => cfg!(not_enable), | ^^^^^^^^^^^^^^^^^^^^^ @@ -195,7 +198,7 @@ LL + 1 | 0 => cfg!(not_enable), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:278:17 + --> tests/ui/match_same_arms2.rs:291:17 | LL | MaybeStaticStr::Borrowed(s) => s, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/match_same_arms_non_exhaustive.fixed b/tests/ui/match_same_arms_non_exhaustive.fixed index 804c0a869a9f..71041cff8d0a 100644 --- a/tests/ui/match_same_arms_non_exhaustive.fixed +++ b/tests/ui/match_same_arms_non_exhaustive.fixed @@ -41,7 +41,8 @@ pub fn g(x: Ordering) { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - //~^ ERROR: this match arm has an identical body to the `_` wildcard arm + //~^ match_same_arms + _ => repeat(), } } @@ -54,7 +55,8 @@ mod g { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - //~^ ERROR: this match arm has an identical body to the `_` wildcard arm + //~^ match_same_arms + _ => repeat(), } } diff --git a/tests/ui/match_same_arms_non_exhaustive.rs b/tests/ui/match_same_arms_non_exhaustive.rs index e50663932a1a..45dc5d78883b 100644 --- a/tests/ui/match_same_arms_non_exhaustive.rs +++ b/tests/ui/match_same_arms_non_exhaustive.rs @@ -42,7 +42,8 @@ pub fn g(x: Ordering) { Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), Ordering::AcqRel | Ordering::SeqCst => repeat(), - //~^ ERROR: this match arm has an identical body to the `_` wildcard arm + //~^ match_same_arms + _ => repeat(), } } @@ -56,7 +57,8 @@ mod g { Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), Ordering::AcqRel | Ordering::SeqCst => repeat(), - //~^ ERROR: this match arm has an identical body to the `_` wildcard arm + //~^ match_same_arms + _ => repeat(), } } diff --git a/tests/ui/match_same_arms_non_exhaustive.stderr b/tests/ui/match_same_arms_non_exhaustive.stderr index aa7f8c95dce8..1033203c7237 100644 --- a/tests/ui/match_same_arms_non_exhaustive.stderr +++ b/tests/ui/match_same_arms_non_exhaustive.stderr @@ -7,7 +7,7 @@ LL | | | = help: or try changing either arm body note: `_` wildcard arm here - --> tests/ui/match_same_arms_non_exhaustive.rs:46:9 + --> tests/ui/match_same_arms_non_exhaustive.rs:47:9 | LL | _ => repeat(), | ^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | _ => repeat(), = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]` error: this match arm has an identical body to the `_` wildcard arm - --> tests/ui/match_same_arms_non_exhaustive.rs:58:13 + --> tests/ui/match_same_arms_non_exhaustive.rs:59:13 | LL | / Ordering::AcqRel | Ordering::SeqCst => repeat(), LL | | @@ -23,7 +23,7 @@ LL | | | = help: or try changing either arm body note: `_` wildcard arm here - --> tests/ui/match_same_arms_non_exhaustive.rs:60:13 + --> tests/ui/match_same_arms_non_exhaustive.rs:62:13 | LL | _ => repeat(), | ^^^^^^^^^^^^^ diff --git a/tests/ui/match_single_binding.rs b/tests/ui/match_single_binding.rs index ff2f842ac39e..27fd7d601abf 100644 --- a/tests/ui/match_single_binding.rs +++ b/tests/ui/match_single_binding.rs @@ -31,12 +31,14 @@ fn main() { let c = 3; // Lint match (a, b, c) { + //~^ match_single_binding (x, y, z) => { println!("{} {} {}", x, y, z); }, } // Lint match (a, b, c) { + //~^ match_single_binding (x, y, z) => println!("{} {} {}", x, y, z), } // Ok @@ -54,10 +56,12 @@ fn main() { } // Lint match a { + //~^ match_single_binding _ => println!("whatever"), } // Lint match a { + //~^ match_single_binding _ => { let x = 29; println!("x has a value of {}", x); @@ -65,6 +69,7 @@ fn main() { } // Lint match a { + //~^ match_single_binding _ => { let e = 5 * a; if e >= 5 { @@ -75,24 +80,29 @@ fn main() { // Lint let p = Point { x: 0, y: 7 }; match p { + //~^ match_single_binding Point { x, y } => println!("Coords: ({}, {})", x, y), } // Lint match p { + //~^ match_single_binding Point { x: x1, y: y1 } => println!("Coords: ({}, {})", x1, y1), } // Lint let x = 5; match x { + //~^ match_single_binding ref r => println!("Got a reference to {}", r), } // Lint let mut x = 5; match x { + //~^ match_single_binding ref mut mr => println!("Got a mutable reference to {}", mr), } // Lint let product = match coords() { + //~^ match_single_binding Point { x, y } => x * y, }; // Lint @@ -101,6 +111,7 @@ fn main() { let _ = v .iter() .map(|i| match i.unwrap() { + //~^ match_single_binding unwrapped => unwrapped, }) .collect::>(); @@ -127,6 +138,7 @@ fn main() { // Lint let x = 1; match x { + //~^ match_single_binding // => _ => println!("Not an array index start"), } @@ -136,6 +148,7 @@ fn issue_8723() { let (mut val, idx) = ("a b", 1); val = match val.split_at(idx) { + //~^ match_single_binding (pre, suf) => { println!("{}", pre); suf @@ -149,12 +162,14 @@ fn side_effects() {} fn issue_9575() { let _ = || match side_effects() { + //~^ match_single_binding _ => println!("Needs curlies"), }; } fn issue_9725(r: Option) { match r { + //~^ match_single_binding x => match x { Some(_) => { println!("Some"); @@ -168,37 +183,46 @@ fn issue_9725(r: Option) { fn issue_10447() -> usize { match 1 { + //~^ match_single_binding _ => (), } let a = match 1 { + //~^ match_single_binding _ => (), }; match 1 { + //~^ match_single_binding _ => side_effects(), } let b = match 1 { + //~^ match_single_binding _ => side_effects(), }; match 1 { + //~^ match_single_binding _ => println!("1"), } let c = match 1 { + //~^ match_single_binding _ => println!("1"), }; let in_expr = [ match 1 { + //~^ match_single_binding _ => (), }, match 1 { + //~^ match_single_binding _ => side_effects(), }, match 1 { + //~^ match_single_binding _ => println!("1"), }, ]; diff --git a/tests/ui/match_single_binding.stderr b/tests/ui/match_single_binding.stderr index 19ab85180ad2..7e1ec32dac2f 100644 --- a/tests/ui/match_single_binding.stderr +++ b/tests/ui/match_single_binding.stderr @@ -2,6 +2,7 @@ error: this match could be written as a `let` statement --> tests/ui/match_single_binding.rs:33:5 | LL | / match (a, b, c) { +LL | | LL | | (x, y, z) => { LL | | println!("{} {} {}", x, y, z); LL | | }, @@ -19,9 +20,10 @@ LL + } | error: this match could be written as a `let` statement - --> tests/ui/match_single_binding.rs:39:5 + --> tests/ui/match_single_binding.rs:40:5 | LL | / match (a, b, c) { +LL | | LL | | (x, y, z) => println!("{} {} {}", x, y, z), LL | | } | |_____^ @@ -33,17 +35,19 @@ LL + println!("{} {} {}", x, y, z); | error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:56:5 + --> tests/ui/match_single_binding.rs:58:5 | LL | / match a { +LL | | LL | | _ => println!("whatever"), LL | | } | |_____^ help: consider using the match body instead: `println!("whatever");` error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:60:5 + --> tests/ui/match_single_binding.rs:63:5 | LL | / match a { +LL | | LL | | _ => { LL | | let x = 29; LL | | println!("x has a value of {}", x); @@ -60,12 +64,12 @@ LL + } | error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:67:5 + --> tests/ui/match_single_binding.rs:71:5 | LL | / match a { +LL | | LL | | _ => { LL | | let e = 5 * a; -LL | | if e >= 5 { ... | LL | | }, LL | | } @@ -82,9 +86,10 @@ LL + } | error: this match could be written as a `let` statement - --> tests/ui/match_single_binding.rs:77:5 + --> tests/ui/match_single_binding.rs:82:5 | LL | / match p { +LL | | LL | | Point { x, y } => println!("Coords: ({}, {})", x, y), LL | | } | |_____^ @@ -96,9 +101,10 @@ LL + println!("Coords: ({}, {})", x, y); | error: this match could be written as a `let` statement - --> tests/ui/match_single_binding.rs:81:5 + --> tests/ui/match_single_binding.rs:87:5 | LL | / match p { +LL | | LL | | Point { x: x1, y: y1 } => println!("Coords: ({}, {})", x1, y1), LL | | } | |_____^ @@ -110,9 +116,10 @@ LL + println!("Coords: ({}, {})", x1, y1); | error: this match could be written as a `let` statement - --> tests/ui/match_single_binding.rs:86:5 + --> tests/ui/match_single_binding.rs:93:5 | LL | / match x { +LL | | LL | | ref r => println!("Got a reference to {}", r), LL | | } | |_____^ @@ -124,9 +131,10 @@ LL + println!("Got a reference to {}", r); | error: this match could be written as a `let` statement - --> tests/ui/match_single_binding.rs:91:5 + --> tests/ui/match_single_binding.rs:99:5 | LL | / match x { +LL | | LL | | ref mut mr => println!("Got a mutable reference to {}", mr), LL | | } | |_____^ @@ -138,9 +146,10 @@ LL + println!("Got a mutable reference to {}", mr); | error: this match could be written as a `let` statement - --> tests/ui/match_single_binding.rs:95:5 + --> tests/ui/match_single_binding.rs:104:5 | LL | / let product = match coords() { +LL | | LL | | Point { x, y } => x * y, LL | | }; | |______^ @@ -152,10 +161,11 @@ LL + let product = x * y; | error: this match could be written as a `let` statement - --> tests/ui/match_single_binding.rs:103:18 + --> tests/ui/match_single_binding.rs:113:18 | LL | .map(|i| match i.unwrap() { | __________________^ +LL | | LL | | unwrapped => unwrapped, LL | | }) | |_________^ @@ -169,18 +179,20 @@ LL ~ }) | error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:129:5 + --> tests/ui/match_single_binding.rs:140:5 | LL | / match x { +LL | | LL | | // => LL | | _ => println!("Not an array index start"), LL | | } | |_____^ help: consider using the match body instead: `println!("Not an array index start")` error: this assignment could be simplified - --> tests/ui/match_single_binding.rs:138:5 + --> tests/ui/match_single_binding.rs:150:5 | LL | / val = match val.split_at(idx) { +LL | | LL | | (pre, suf) => { LL | | println!("{}", pre); LL | | suf @@ -198,10 +210,11 @@ LL ~ }; | error: this match could be replaced by its scrutinee and body - --> tests/ui/match_single_binding.rs:151:16 + --> tests/ui/match_single_binding.rs:164:16 | LL | let _ = || match side_effects() { | ________________^ +LL | | LL | | _ => println!("Needs curlies"), LL | | }; | |_____^ @@ -215,12 +228,12 @@ LL ~ }; | error: this match could be written as a `let` statement - --> tests/ui/match_single_binding.rs:157:5 + --> tests/ui/match_single_binding.rs:171:5 | LL | / match r { +LL | | LL | | x => match x { LL | | Some(_) => { -LL | | println!("Some"); ... | LL | | }, LL | | }; @@ -240,76 +253,85 @@ LL ~ }; | error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:170:5 + --> tests/ui/match_single_binding.rs:185:5 | LL | / match 1 { +LL | | LL | | _ => (), LL | | } | |_____^ help: consider using the match body instead: `();` error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:174:13 + --> tests/ui/match_single_binding.rs:190:13 | LL | let a = match 1 { | _____________^ +LL | | LL | | _ => (), LL | | }; | |_____^ help: consider using the match body instead: `()` error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:178:5 + --> tests/ui/match_single_binding.rs:195:5 | LL | / match 1 { +LL | | LL | | _ => side_effects(), LL | | } | |_____^ help: consider using the match body instead: `side_effects();` error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:182:13 + --> tests/ui/match_single_binding.rs:200:13 | LL | let b = match 1 { | _____________^ +LL | | LL | | _ => side_effects(), LL | | }; | |_____^ help: consider using the match body instead: `side_effects()` error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:186:5 + --> tests/ui/match_single_binding.rs:205:5 | LL | / match 1 { +LL | | LL | | _ => println!("1"), LL | | } | |_____^ help: consider using the match body instead: `println!("1");` error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:190:13 + --> tests/ui/match_single_binding.rs:210:13 | LL | let c = match 1 { | _____________^ +LL | | LL | | _ => println!("1"), LL | | }; | |_____^ help: consider using the match body instead: `println!("1")` error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:195:9 + --> tests/ui/match_single_binding.rs:216:9 | LL | / match 1 { +LL | | LL | | _ => (), LL | | }, | |_________^ help: consider using the match body instead: `()` error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:198:9 + --> tests/ui/match_single_binding.rs:220:9 | LL | / match 1 { +LL | | LL | | _ => side_effects(), LL | | }, | |_________^ help: consider using the match body instead: `side_effects()` error: this match could be replaced by its body itself - --> tests/ui/match_single_binding.rs:201:9 + --> tests/ui/match_single_binding.rs:224:9 | LL | / match 1 { +LL | | LL | | _ => println!("1"), LL | | }, | |_________^ help: consider using the match body instead: `println!("1")` diff --git a/tests/ui/match_single_binding2.fixed b/tests/ui/match_single_binding2.fixed index 5673aa78c76a..1d34f179ea4a 100644 --- a/tests/ui/match_single_binding2.fixed +++ b/tests/ui/match_single_binding2.fixed @@ -45,6 +45,7 @@ fn main() { // issue #7094 let x = 1; match x { + //~^ match_single_binding 0 => 1, _ => 2, }; diff --git a/tests/ui/match_single_binding2.rs b/tests/ui/match_single_binding2.rs index 575e7f5816b8..8c18d7c133c1 100644 --- a/tests/ui/match_single_binding2.rs +++ b/tests/ui/match_single_binding2.rs @@ -15,6 +15,7 @@ fn main() { fn size_hint(iter: &AppendIter) -> (usize, Option) { match &iter.inner { Some((iter, _item)) => match iter.size_hint() { + //~^ match_single_binding (min, max) => (min.saturating_add(1), max.and_then(|max| max.checked_add(1))), }, None => (0, Some(0)), @@ -28,6 +29,7 @@ fn main() { #[rustfmt::skip] Some((first, _second)) => { match get_tup() { + //~^ match_single_binding (a, b) => println!("a {:?} and b {:?}", a, b), } }, @@ -39,6 +41,7 @@ fn main() { // Lint (scrutinee has side effects) // issue #7094 match side_effects() { + //~^ match_single_binding _ => println!("Side effects"), } @@ -46,6 +49,7 @@ fn main() { // issue #7094 let x = 1; match match x { + //~^ match_single_binding 0 => 1, _ => 2, } { diff --git a/tests/ui/match_single_binding2.stderr b/tests/ui/match_single_binding2.stderr index 38659596af1f..a24cbe3eed76 100644 --- a/tests/ui/match_single_binding2.stderr +++ b/tests/ui/match_single_binding2.stderr @@ -3,6 +3,7 @@ error: this match could be written as a `let` statement | LL | Some((iter, _item)) => match iter.size_hint() { | ____________________________________^ +LL | | LL | | (min, max) => (min.saturating_add(1), max.and_then(|max| max.checked_add(1))), LL | | }, | |_____________^ @@ -18,9 +19,10 @@ LL ~ }, | error: this match could be written as a `let` statement - --> tests/ui/match_single_binding2.rs:30:13 + --> tests/ui/match_single_binding2.rs:31:13 | LL | / match get_tup() { +LL | | LL | | (a, b) => println!("a {:?} and b {:?}", a, b), LL | | } | |_____________^ @@ -32,9 +34,10 @@ LL + println!("a {:?} and b {:?}", a, b) | error: this match could be replaced by its scrutinee and body - --> tests/ui/match_single_binding2.rs:41:5 + --> tests/ui/match_single_binding2.rs:43:5 | LL | / match side_effects() { +LL | | LL | | _ => println!("Side effects"), LL | | } | |_____^ @@ -46,9 +49,10 @@ LL + println!("Side effects"); | error: this match could be replaced by its scrutinee and body - --> tests/ui/match_single_binding2.rs:48:5 + --> tests/ui/match_single_binding2.rs:51:5 | LL | / match match x { +LL | | LL | | 0 => 1, LL | | _ => 2, LL | | } { @@ -59,6 +63,7 @@ LL | | } help: consider using the scrutinee and body instead | LL ~ match x { +LL + LL + 0 => 1, LL + _ => 2, LL + }; diff --git a/tests/ui/match_str_case_mismatch.fixed b/tests/ui/match_str_case_mismatch.fixed index a608ab0c0cb0..5f41f29f8a46 100644 --- a/tests/ui/match_str_case_mismatch.fixed +++ b/tests/ui/match_str_case_mismatch.fixed @@ -110,6 +110,7 @@ fn as_str_match_mismatch() { match var.to_ascii_lowercase().as_str() { "foo" => {}, "bar" => {}, + //~^ match_str_case_mismatch _ => {}, } } @@ -120,6 +121,7 @@ fn non_alphabetic_mismatch() { match var.to_ascii_lowercase().as_str() { "1234567890" => {}, "~!@#$%^&*()-_=+foo" => {}, + //~^ match_str_case_mismatch "\n\r\t\x7F" => {}, _ => {}, } @@ -132,6 +134,7 @@ fn unicode_cased_mismatch() { "水" => {}, "νερό" => {}, "воды" => {}, + //~^ match_str_case_mismatch "물" => {}, _ => {}, } @@ -143,6 +146,7 @@ fn titlecase_mismatch() { match var.to_lowercase().as_str() { "foolj" => {}, "bardz" => {}, + //~^ match_str_case_mismatch _ => {}, } } @@ -153,6 +157,7 @@ fn no_case_equivalent_mismatch() { match var.to_uppercase().as_str() { "FOOɕ" => {}, "BARʁ" => {}, + //~^ match_str_case_mismatch _ => {}, } } @@ -163,6 +168,7 @@ fn addrof_unary_match_mismatch() { match &*var.to_ascii_lowercase() { "foo" => {}, "bar" => {}, + //~^ match_str_case_mismatch _ => {}, } } @@ -178,6 +184,7 @@ fn alternating_chain_mismatch() { { "FOO" => {}, "BAR" => {}, + //~^ match_str_case_mismatch _ => {}, } } diff --git a/tests/ui/match_str_case_mismatch.rs b/tests/ui/match_str_case_mismatch.rs index 1e4269d1db5d..fa5d5a8ebc31 100644 --- a/tests/ui/match_str_case_mismatch.rs +++ b/tests/ui/match_str_case_mismatch.rs @@ -110,6 +110,7 @@ fn as_str_match_mismatch() { match var.to_ascii_lowercase().as_str() { "foo" => {}, "Bar" => {}, + //~^ match_str_case_mismatch _ => {}, } } @@ -120,6 +121,7 @@ fn non_alphabetic_mismatch() { match var.to_ascii_lowercase().as_str() { "1234567890" => {}, "~!@#$%^&*()-_=+Foo" => {}, + //~^ match_str_case_mismatch "\n\r\t\x7F" => {}, _ => {}, } @@ -132,6 +134,7 @@ fn unicode_cased_mismatch() { "水" => {}, "νερό" => {}, "Воды" => {}, + //~^ match_str_case_mismatch "물" => {}, _ => {}, } @@ -143,6 +146,7 @@ fn titlecase_mismatch() { match var.to_lowercase().as_str() { "foolj" => {}, "barDz" => {}, + //~^ match_str_case_mismatch _ => {}, } } @@ -153,6 +157,7 @@ fn no_case_equivalent_mismatch() { match var.to_uppercase().as_str() { "FOOɕ" => {}, "bARʁ" => {}, + //~^ match_str_case_mismatch _ => {}, } } @@ -163,6 +168,7 @@ fn addrof_unary_match_mismatch() { match &*var.to_ascii_lowercase() { "foo" => {}, "Bar" => {}, + //~^ match_str_case_mismatch _ => {}, } } @@ -178,6 +184,7 @@ fn alternating_chain_mismatch() { { "FOO" => {}, "bAR" => {}, + //~^ match_str_case_mismatch _ => {}, } } diff --git a/tests/ui/match_str_case_mismatch.stderr b/tests/ui/match_str_case_mismatch.stderr index 67e9ccaf6d2f..ea461eb510ff 100644 --- a/tests/ui/match_str_case_mismatch.stderr +++ b/tests/ui/match_str_case_mismatch.stderr @@ -12,7 +12,7 @@ LL | "bar" => {}, | ~~~~~ error: this `match` arm has a differing case than its expression - --> tests/ui/match_str_case_mismatch.rs:122:9 + --> tests/ui/match_str_case_mismatch.rs:123:9 | LL | "~!@#$%^&*()-_=+Foo" => {}, | ^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | "~!@#$%^&*()-_=+foo" => {}, | ~~~~~~~~~~~~~~~~~~~~ error: this `match` arm has a differing case than its expression - --> tests/ui/match_str_case_mismatch.rs:134:9 + --> tests/ui/match_str_case_mismatch.rs:136:9 | LL | "Воды" => {}, | ^^^^^^ @@ -34,7 +34,7 @@ LL | "воды" => {}, | ~~~~~~ error: this `match` arm has a differing case than its expression - --> tests/ui/match_str_case_mismatch.rs:145:9 + --> tests/ui/match_str_case_mismatch.rs:148:9 | LL | "barDz" => {}, | ^^^^^^ @@ -45,7 +45,7 @@ LL | "bardz" => {}, | ~~~~~~ error: this `match` arm has a differing case than its expression - --> tests/ui/match_str_case_mismatch.rs:155:9 + --> tests/ui/match_str_case_mismatch.rs:159:9 | LL | "bARʁ" => {}, | ^^^^^^ @@ -56,7 +56,7 @@ LL | "BARʁ" => {}, | ~~~~~~ error: this `match` arm has a differing case than its expression - --> tests/ui/match_str_case_mismatch.rs:165:9 + --> tests/ui/match_str_case_mismatch.rs:170:9 | LL | "Bar" => {}, | ^^^^^ @@ -67,7 +67,7 @@ LL | "bar" => {}, | ~~~~~ error: this `match` arm has a differing case than its expression - --> tests/ui/match_str_case_mismatch.rs:180:9 + --> tests/ui/match_str_case_mismatch.rs:186:9 | LL | "bAR" => {}, | ^^^^^ diff --git a/tests/ui/match_wild_err_arm.rs b/tests/ui/match_wild_err_arm.rs index 8e670ce5bda2..f7f7c398d647 100644 --- a/tests/ui/match_wild_err_arm.rs +++ b/tests/ui/match_wild_err_arm.rs @@ -21,24 +21,27 @@ fn match_wild_err_arm() { Ok(3) => println!("ok"), Ok(_) => println!("ok"), Err(_) => panic!("err"), - //~^ ERROR: `Err(_)` matches all errors - //~| NOTE: match each error separately or use the error output, or use `.expect(ms + //~^ match_wild_err_arm + + } match x { Ok(3) => println!("ok"), Ok(_) => println!("ok"), Err(_) => panic!(), - //~^ ERROR: `Err(_)` matches all errors - //~| NOTE: match each error separately or use the error output, or use `.expect(ms + //~^ match_wild_err_arm + + } match x { Ok(3) => println!("ok"), Ok(_) => println!("ok"), Err(_) => { - //~^ ERROR: `Err(_)` matches all errors - //~| NOTE: match each error separately or use the error output, or use `.expect(ms + //~^ match_wild_err_arm + + panic!(); }, } @@ -47,8 +50,9 @@ fn match_wild_err_arm() { Ok(3) => println!("ok"), Ok(_) => println!("ok"), Err(_e) => panic!(), - //~^ ERROR: `Err(_e)` matches all errors - //~| NOTE: match each error separately or use the error output, or use `.expect(ms + //~^ match_wild_err_arm + + } // Allowed when used in `panic!`. diff --git a/tests/ui/match_wild_err_arm.stderr b/tests/ui/match_wild_err_arm.stderr index f98065d9a591..ec0ca602f5f9 100644 --- a/tests/ui/match_wild_err_arm.stderr +++ b/tests/ui/match_wild_err_arm.stderr @@ -9,7 +9,7 @@ LL | Err(_) => panic!("err"), = help: to override `-D warnings` add `#[allow(clippy::match_wild_err_arm)]` error: `Err(_)` matches all errors - --> tests/ui/match_wild_err_arm.rs:31:9 + --> tests/ui/match_wild_err_arm.rs:32:9 | LL | Err(_) => panic!(), | ^^^^^^ @@ -17,7 +17,7 @@ LL | Err(_) => panic!(), = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_)` matches all errors - --> tests/ui/match_wild_err_arm.rs:39:9 + --> tests/ui/match_wild_err_arm.rs:41:9 | LL | Err(_) => { | ^^^^^^ @@ -25,7 +25,7 @@ LL | Err(_) => { = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_e)` matches all errors - --> tests/ui/match_wild_err_arm.rs:49:9 + --> tests/ui/match_wild_err_arm.rs:52:9 | LL | Err(_e) => panic!(), | ^^^^^^^ diff --git a/tests/ui/match_wildcard_for_single_variants.fixed b/tests/ui/match_wildcard_for_single_variants.fixed index e5ea2fdde82f..c34f49df6549 100644 --- a/tests/ui/match_wildcard_for_single_variants.fixed +++ b/tests/ui/match_wildcard_for_single_variants.fixed @@ -20,6 +20,7 @@ impl Color { Self::Green => (), Self::Blue => (), Self::Rgb(..) => (), + //~^ match_wildcard_for_single_variants }; } } @@ -30,6 +31,7 @@ fn main() { Foo::A => {}, Foo::B => {}, Foo::C => {}, + //~^ match_wildcard_for_single_variants } let color = Color::Red; @@ -40,6 +42,7 @@ fn main() { Color::Green => {}, Color::Rgb(_r, _g, _b) => {}, Color::Blue => {}, + //~^ match_wildcard_for_single_variants } // check exhaustive wild @@ -48,12 +51,14 @@ fn main() { Color::Green => {}, Color::Rgb(..) => {}, Color::Blue => {}, + //~^ match_wildcard_for_single_variants } match color { Color::Red => {}, Color::Green => {}, Color::Rgb(_, _, _) => {}, Color::Blue => {}, + //~^ match_wildcard_for_single_variants } // shouldn't lint as there is one missing variant @@ -71,6 +76,7 @@ fn main() { Color::Green => (), &Color::Rgb(..) => (), Color::Blue => (), + //~^ match_wildcard_for_single_variants } use self::Color as C; @@ -80,6 +86,7 @@ fn main() { C::Green => (), C::Rgb(..) => (), C::Blue => (), + //~^ match_wildcard_for_single_variants } match color { @@ -87,6 +94,7 @@ fn main() { Color::Green => (), Color::Rgb(..) => (), Color::Blue => (), + //~^ match_wildcard_for_single_variants } match Some(0) { @@ -122,6 +130,7 @@ fn main() { Enum::B => (), Enum::C => (), Enum::__Private => (), + //~^ match_wildcard_for_single_variants } match Enum::A { Enum::A => (), @@ -149,6 +158,7 @@ mod issue9993 { _ if false => 0, Foo::A(_) => 1, Foo::B => 2, + //~^ match_wildcard_for_single_variants }; } } diff --git a/tests/ui/match_wildcard_for_single_variants.rs b/tests/ui/match_wildcard_for_single_variants.rs index dbd7fbe160f0..ecdb7d2fa3af 100644 --- a/tests/ui/match_wildcard_for_single_variants.rs +++ b/tests/ui/match_wildcard_for_single_variants.rs @@ -20,6 +20,7 @@ impl Color { Self::Green => (), Self::Blue => (), _ => (), + //~^ match_wildcard_for_single_variants }; } } @@ -30,6 +31,7 @@ fn main() { Foo::A => {}, Foo::B => {}, _ => {}, + //~^ match_wildcard_for_single_variants } let color = Color::Red; @@ -40,6 +42,7 @@ fn main() { Color::Green => {}, Color::Rgb(_r, _g, _b) => {}, _ => {}, + //~^ match_wildcard_for_single_variants } // check exhaustive wild @@ -48,12 +51,14 @@ fn main() { Color::Green => {}, Color::Rgb(..) => {}, _ => {}, + //~^ match_wildcard_for_single_variants } match color { Color::Red => {}, Color::Green => {}, Color::Rgb(_, _, _) => {}, _ => {}, + //~^ match_wildcard_for_single_variants } // shouldn't lint as there is one missing variant @@ -71,6 +76,7 @@ fn main() { Color::Green => (), &Color::Rgb(..) => (), &_ => (), + //~^ match_wildcard_for_single_variants } use self::Color as C; @@ -80,6 +86,7 @@ fn main() { C::Green => (), C::Rgb(..) => (), _ => (), + //~^ match_wildcard_for_single_variants } match color { @@ -87,6 +94,7 @@ fn main() { Color::Green => (), Color::Rgb(..) => (), _ => (), + //~^ match_wildcard_for_single_variants } match Some(0) { @@ -122,6 +130,7 @@ fn main() { Enum::B => (), Enum::C => (), _ => (), + //~^ match_wildcard_for_single_variants } match Enum::A { Enum::A => (), @@ -149,6 +158,7 @@ mod issue9993 { _ if false => 0, Foo::A(_) => 1, _ => 2, + //~^ match_wildcard_for_single_variants }; } } diff --git a/tests/ui/match_wildcard_for_single_variants.stderr b/tests/ui/match_wildcard_for_single_variants.stderr index 5cc50c823b2c..3c0cc53b1bf2 100644 --- a/tests/ui/match_wildcard_for_single_variants.stderr +++ b/tests/ui/match_wildcard_for_single_variants.stderr @@ -8,55 +8,55 @@ LL | _ => (), = help: to override `-D warnings` add `#[allow(clippy::match_wildcard_for_single_variants)]` error: wildcard matches only a single variant and will also match any future added variants - --> tests/ui/match_wildcard_for_single_variants.rs:32:9 + --> tests/ui/match_wildcard_for_single_variants.rs:33:9 | LL | _ => {}, | ^ help: try: `Foo::C` error: wildcard matches only a single variant and will also match any future added variants - --> tests/ui/match_wildcard_for_single_variants.rs:42:9 + --> tests/ui/match_wildcard_for_single_variants.rs:44:9 | LL | _ => {}, | ^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants - --> tests/ui/match_wildcard_for_single_variants.rs:50:9 + --> tests/ui/match_wildcard_for_single_variants.rs:53:9 | LL | _ => {}, | ^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants - --> tests/ui/match_wildcard_for_single_variants.rs:56:9 + --> tests/ui/match_wildcard_for_single_variants.rs:60:9 | LL | _ => {}, | ^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants - --> tests/ui/match_wildcard_for_single_variants.rs:73:9 + --> tests/ui/match_wildcard_for_single_variants.rs:78:9 | LL | &_ => (), | ^^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants - --> tests/ui/match_wildcard_for_single_variants.rs:82:9 + --> tests/ui/match_wildcard_for_single_variants.rs:88:9 | LL | _ => (), | ^ help: try: `C::Blue` error: wildcard matches only a single variant and will also match any future added variants - --> tests/ui/match_wildcard_for_single_variants.rs:89:9 + --> tests/ui/match_wildcard_for_single_variants.rs:96:9 | LL | _ => (), | ^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants - --> tests/ui/match_wildcard_for_single_variants.rs:124:13 + --> tests/ui/match_wildcard_for_single_variants.rs:132:13 | LL | _ => (), | ^ help: try: `Enum::__Private` error: wildcard matches only a single variant and will also match any future added variants - --> tests/ui/match_wildcard_for_single_variants.rs:151:13 + --> tests/ui/match_wildcard_for_single_variants.rs:160:13 | LL | _ => 2, | ^ help: try: `Foo::B` diff --git a/tests/ui/mem_forget.rs b/tests/ui/mem_forget.rs index 1f508b3bca28..ad9bd079b98d 100644 --- a/tests/ui/mem_forget.rs +++ b/tests/ui/mem_forget.rs @@ -12,23 +12,27 @@ fn main() { let six: Arc = Arc::new(6); memstuff::forget(six); - //~^ ERROR: usage of `mem::forget` on `Drop` type - //~| NOTE: argument has type `std::sync::Arc` + //~^ mem_forget + + let seven: Rc = Rc::new(7); std::mem::forget(seven); - //~^ ERROR: usage of `mem::forget` on `Drop` type - //~| NOTE: argument has type `std::rc::Rc` + //~^ mem_forget + + let eight: Vec = vec![8]; forgetSomething(eight); - //~^ ERROR: usage of `mem::forget` on `Drop` type - //~| NOTE: argument has type `std::vec::Vec` + //~^ mem_forget + + let string = String::new(); std::mem::forget(string); - //~^ ERROR: usage of `mem::forget` on type with `Drop` fields - //~| NOTE: argument has type `std::string::String` + //~^ mem_forget + + std::mem::forget(7); } diff --git a/tests/ui/mem_forget.stderr b/tests/ui/mem_forget.stderr index 3b0e839e0871..4dd1efc1a240 100644 --- a/tests/ui/mem_forget.stderr +++ b/tests/ui/mem_forget.stderr @@ -9,7 +9,7 @@ LL | memstuff::forget(six); = help: to override `-D warnings` add `#[allow(clippy::mem_forget)]` error: usage of `mem::forget` on `Drop` type - --> tests/ui/mem_forget.rs:19:5 + --> tests/ui/mem_forget.rs:20:5 | LL | std::mem::forget(seven); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | std::mem::forget(seven); = note: argument has type `std::rc::Rc` error: usage of `mem::forget` on `Drop` type - --> tests/ui/mem_forget.rs:24:5 + --> tests/ui/mem_forget.rs:26:5 | LL | forgetSomething(eight); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | forgetSomething(eight); = note: argument has type `std::vec::Vec` error: usage of `mem::forget` on type with `Drop` fields - --> tests/ui/mem_forget.rs:29:5 + --> tests/ui/mem_forget.rs:32:5 | LL | std::mem::forget(string); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/mem_replace.fixed b/tests/ui/mem_replace.fixed index 02b0d9c7045f..870ef23113a2 100644 --- a/tests/ui/mem_replace.fixed +++ b/tests/ui/mem_replace.fixed @@ -11,55 +11,76 @@ use std::mem; fn replace_option_with_none() { let mut an_option = Some(1); let _ = an_option.take(); + //~^ mem_replace_option_with_none let an_option = &mut Some(1); let _ = an_option.take(); + //~^ mem_replace_option_with_none } fn replace_with_default() { let mut s = String::from("foo"); let _ = std::mem::take(&mut s); + //~^ mem_replace_with_default let _ = std::mem::take(&mut s); + //~^ mem_replace_with_default let s = &mut String::from("foo"); let _ = std::mem::take(s); + //~^ mem_replace_with_default let _ = std::mem::take(s); + //~^ mem_replace_with_default let _ = std::mem::take(s); + //~^ mem_replace_with_default let mut v = vec![123]; let _ = std::mem::take(&mut v); + //~^ mem_replace_with_default let _ = std::mem::take(&mut v); + //~^ mem_replace_with_default let _ = std::mem::take(&mut v); + //~^ mem_replace_with_default let _ = std::mem::take(&mut v); + //~^ mem_replace_with_default let mut hash_map: HashMap = HashMap::new(); let _ = std::mem::take(&mut hash_map); + //~^ mem_replace_with_default let mut btree_map: BTreeMap = BTreeMap::new(); let _ = std::mem::take(&mut btree_map); + //~^ mem_replace_with_default let mut vd: VecDeque = VecDeque::new(); let _ = std::mem::take(&mut vd); + //~^ mem_replace_with_default let mut hash_set: HashSet<&str> = HashSet::new(); let _ = std::mem::take(&mut hash_set); + //~^ mem_replace_with_default let mut btree_set: BTreeSet<&str> = BTreeSet::new(); let _ = std::mem::take(&mut btree_set); + //~^ mem_replace_with_default let mut list: LinkedList = LinkedList::new(); let _ = std::mem::take(&mut list); + //~^ mem_replace_with_default let mut binary_heap: BinaryHeap = BinaryHeap::new(); let _ = std::mem::take(&mut binary_heap); + //~^ mem_replace_with_default let mut tuple = (vec![1, 2], BinaryHeap::::new()); let _ = std::mem::take(&mut tuple); + //~^ mem_replace_with_default let mut refstr = "hello"; let _ = std::mem::take(&mut refstr); + //~^ mem_replace_with_default let mut slice: &[i32] = &[1, 2, 3]; let _ = std::mem::take(&mut slice); + //~^ mem_replace_with_default } // lint is disabled for primitives because in this case `take` @@ -96,6 +117,7 @@ fn msrv_1_39() { fn msrv_1_40() { let mut s = String::from("foo"); let _ = std::mem::take(&mut s); + //~^ mem_replace_with_default } fn issue9824() { @@ -126,10 +148,14 @@ fn issue9824() { // replace option with none let _ = f.0.take(); + //~^ mem_replace_option_with_none let _ = (*f).take(); + //~^ mem_replace_option_with_none let _ = b.opt.take(); + //~^ mem_replace_option_with_none // replace with default let _ = std::mem::take(&mut b.val); + //~^ mem_replace_with_default } #[clippy::msrv = "1.31"] diff --git a/tests/ui/mem_replace.rs b/tests/ui/mem_replace.rs index 1bb72b5de239..b4ed5eafea95 100644 --- a/tests/ui/mem_replace.rs +++ b/tests/ui/mem_replace.rs @@ -11,55 +11,76 @@ use std::mem; fn replace_option_with_none() { let mut an_option = Some(1); let _ = mem::replace(&mut an_option, None); + //~^ mem_replace_option_with_none let an_option = &mut Some(1); let _ = mem::replace(an_option, None); + //~^ mem_replace_option_with_none } fn replace_with_default() { let mut s = String::from("foo"); let _ = std::mem::replace(&mut s, String::default()); + //~^ mem_replace_with_default let _ = std::mem::replace(&mut s, String::new()); + //~^ mem_replace_with_default let s = &mut String::from("foo"); let _ = std::mem::replace(s, String::default()); + //~^ mem_replace_with_default let _ = std::mem::replace(s, String::new()); + //~^ mem_replace_with_default let _ = std::mem::replace(s, Default::default()); + //~^ mem_replace_with_default let mut v = vec![123]; let _ = std::mem::replace(&mut v, Vec::default()); + //~^ mem_replace_with_default let _ = std::mem::replace(&mut v, Default::default()); + //~^ mem_replace_with_default let _ = std::mem::replace(&mut v, Vec::new()); + //~^ mem_replace_with_default let _ = std::mem::replace(&mut v, vec![]); + //~^ mem_replace_with_default let mut hash_map: HashMap = HashMap::new(); let _ = std::mem::replace(&mut hash_map, HashMap::new()); + //~^ mem_replace_with_default let mut btree_map: BTreeMap = BTreeMap::new(); let _ = std::mem::replace(&mut btree_map, BTreeMap::new()); + //~^ mem_replace_with_default let mut vd: VecDeque = VecDeque::new(); let _ = std::mem::replace(&mut vd, VecDeque::new()); + //~^ mem_replace_with_default let mut hash_set: HashSet<&str> = HashSet::new(); let _ = std::mem::replace(&mut hash_set, HashSet::new()); + //~^ mem_replace_with_default let mut btree_set: BTreeSet<&str> = BTreeSet::new(); let _ = std::mem::replace(&mut btree_set, BTreeSet::new()); + //~^ mem_replace_with_default let mut list: LinkedList = LinkedList::new(); let _ = std::mem::replace(&mut list, LinkedList::new()); + //~^ mem_replace_with_default let mut binary_heap: BinaryHeap = BinaryHeap::new(); let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new()); + //~^ mem_replace_with_default let mut tuple = (vec![1, 2], BinaryHeap::::new()); let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new())); + //~^ mem_replace_with_default let mut refstr = "hello"; let _ = std::mem::replace(&mut refstr, ""); + //~^ mem_replace_with_default let mut slice: &[i32] = &[1, 2, 3]; let _ = std::mem::replace(&mut slice, &[]); + //~^ mem_replace_with_default } // lint is disabled for primitives because in this case `take` @@ -96,6 +117,7 @@ fn msrv_1_39() { fn msrv_1_40() { let mut s = String::from("foo"); let _ = std::mem::replace(&mut s, String::default()); + //~^ mem_replace_with_default } fn issue9824() { @@ -126,10 +148,14 @@ fn issue9824() { // replace option with none let _ = std::mem::replace(&mut f.0, None); + //~^ mem_replace_option_with_none let _ = std::mem::replace(&mut *f, None); + //~^ mem_replace_option_with_none let _ = std::mem::replace(&mut b.opt, None); + //~^ mem_replace_option_with_none // replace with default let _ = std::mem::replace(&mut b.val, String::default()); + //~^ mem_replace_with_default } #[clippy::msrv = "1.31"] diff --git a/tests/ui/mem_replace.stderr b/tests/ui/mem_replace.stderr index 42ab546a5d77..98417df8c84b 100644 --- a/tests/ui/mem_replace.stderr +++ b/tests/ui/mem_replace.stderr @@ -8,13 +8,13 @@ LL | let _ = mem::replace(&mut an_option, None); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]` error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:15:13 + --> tests/ui/mem_replace.rs:16:13 | LL | let _ = mem::replace(an_option, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:20:13 + --> tests/ui/mem_replace.rs:22:13 | LL | let _ = std::mem::replace(&mut s, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)` @@ -23,139 +23,139 @@ LL | let _ = std::mem::replace(&mut s, String::default()); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:21:13 + --> tests/ui/mem_replace.rs:24:13 | LL | let _ = std::mem::replace(&mut s, String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:24:13 + --> tests/ui/mem_replace.rs:28:13 | LL | let _ = std::mem::replace(s, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:25:13 + --> tests/ui/mem_replace.rs:30:13 | LL | let _ = std::mem::replace(s, String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:26:13 + --> tests/ui/mem_replace.rs:32:13 | LL | let _ = std::mem::replace(s, Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:29:13 + --> tests/ui/mem_replace.rs:36:13 | LL | let _ = std::mem::replace(&mut v, Vec::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:30:13 + --> tests/ui/mem_replace.rs:38:13 | LL | let _ = std::mem::replace(&mut v, Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:31:13 + --> tests/ui/mem_replace.rs:40:13 | LL | let _ = std::mem::replace(&mut v, Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:32:13 + --> tests/ui/mem_replace.rs:42:13 | LL | let _ = std::mem::replace(&mut v, vec![]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:35:13 + --> tests/ui/mem_replace.rs:46:13 | LL | let _ = std::mem::replace(&mut hash_map, HashMap::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_map)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:38:13 + --> tests/ui/mem_replace.rs:50:13 | LL | let _ = std::mem::replace(&mut btree_map, BTreeMap::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_map)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:41:13 + --> tests/ui/mem_replace.rs:54:13 | LL | let _ = std::mem::replace(&mut vd, VecDeque::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut vd)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:44:13 + --> tests/ui/mem_replace.rs:58:13 | LL | let _ = std::mem::replace(&mut hash_set, HashSet::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_set)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:47:13 + --> tests/ui/mem_replace.rs:62:13 | LL | let _ = std::mem::replace(&mut btree_set, BTreeSet::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_set)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:50:13 + --> tests/ui/mem_replace.rs:66:13 | LL | let _ = std::mem::replace(&mut list, LinkedList::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut list)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:53:13 + --> tests/ui/mem_replace.rs:70:13 | LL | let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut binary_heap)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:56:13 + --> tests/ui/mem_replace.rs:74:13 | LL | let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut tuple)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:59:13 + --> tests/ui/mem_replace.rs:78:13 | LL | let _ = std::mem::replace(&mut refstr, ""); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut refstr)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:62:13 + --> tests/ui/mem_replace.rs:82:13 | LL | let _ = std::mem::replace(&mut slice, &[]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut slice)` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:98:13 + --> tests/ui/mem_replace.rs:119:13 | LL | let _ = std::mem::replace(&mut s, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)` error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:128:13 + --> tests/ui/mem_replace.rs:150:13 | LL | let _ = std::mem::replace(&mut f.0, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()` error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:129:13 + --> tests/ui/mem_replace.rs:152:13 | LL | let _ = std::mem::replace(&mut *f, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()` error: replacing an `Option` with `None` - --> tests/ui/mem_replace.rs:130:13 + --> tests/ui/mem_replace.rs:154:13 | LL | let _ = std::mem::replace(&mut b.opt, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> tests/ui/mem_replace.rs:132:13 + --> tests/ui/mem_replace.rs:157:13 | LL | let _ = std::mem::replace(&mut b.val, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)` diff --git a/tests/ui/mem_replace_macro.rs b/tests/ui/mem_replace_macro.rs index c14ea2942f3e..9458dade3a9c 100644 --- a/tests/ui/mem_replace_macro.rs +++ b/tests/ui/mem_replace_macro.rs @@ -8,5 +8,6 @@ use proc_macros::{external, inline_macros}; fn main() { let s = &mut String::from("foo"); let _ = inline!(std::mem::replace($s, Default::default())); + //~^ mem_replace_with_default let _ = external!(std::mem::replace($s, Default::default())); } diff --git a/tests/ui/mem_replace_no_std.fixed b/tests/ui/mem_replace_no_std.fixed index 60f523c8ef1e..669450e59d8b 100644 --- a/tests/ui/mem_replace_no_std.fixed +++ b/tests/ui/mem_replace_no_std.fixed @@ -21,16 +21,20 @@ fn panic(info: &PanicInfo) -> ! { fn replace_option_with_none() { let mut an_option = Some(1); let _ = an_option.take(); + //~^ mem_replace_option_with_none let an_option = &mut Some(1); let _ = an_option.take(); + //~^ mem_replace_option_with_none } fn replace_with_default() { let mut refstr = "hello"; let _ = core::mem::take(&mut refstr); + //~^ mem_replace_with_default let mut slice: &[i32] = &[1, 2, 3]; let _ = core::mem::take(&mut slice); + //~^ mem_replace_with_default } // lint is disabled for primitives because in this case `take` @@ -74,8 +78,11 @@ fn issue9824() { // replace option with none let _ = f.0.take(); + //~^ mem_replace_option_with_none let _ = (*f).take(); + //~^ mem_replace_option_with_none let _ = b.opt.take(); + //~^ mem_replace_option_with_none // replace with default let _ = mem::replace(&mut b.val, u8::default()); } diff --git a/tests/ui/mem_replace_no_std.rs b/tests/ui/mem_replace_no_std.rs index d1cb9a5817ba..2cdf1df5196a 100644 --- a/tests/ui/mem_replace_no_std.rs +++ b/tests/ui/mem_replace_no_std.rs @@ -21,16 +21,20 @@ fn panic(info: &PanicInfo) -> ! { fn replace_option_with_none() { let mut an_option = Some(1); let _ = mem::replace(&mut an_option, None); + //~^ mem_replace_option_with_none let an_option = &mut Some(1); let _ = mem::replace(an_option, None); + //~^ mem_replace_option_with_none } fn replace_with_default() { let mut refstr = "hello"; let _ = mem::replace(&mut refstr, ""); + //~^ mem_replace_with_default let mut slice: &[i32] = &[1, 2, 3]; let _ = mem::replace(&mut slice, &[]); + //~^ mem_replace_with_default } // lint is disabled for primitives because in this case `take` @@ -74,8 +78,11 @@ fn issue9824() { // replace option with none let _ = mem::replace(&mut f.0, None); + //~^ mem_replace_option_with_none let _ = mem::replace(&mut *f, None); + //~^ mem_replace_option_with_none let _ = mem::replace(&mut b.opt, None); + //~^ mem_replace_option_with_none // replace with default let _ = mem::replace(&mut b.val, u8::default()); } diff --git a/tests/ui/mem_replace_no_std.stderr b/tests/ui/mem_replace_no_std.stderr index 6ba6d2162a74..926a8288fd31 100644 --- a/tests/ui/mem_replace_no_std.stderr +++ b/tests/ui/mem_replace_no_std.stderr @@ -8,13 +8,13 @@ LL | let _ = mem::replace(&mut an_option, None); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]` error: replacing an `Option` with `None` - --> tests/ui/mem_replace_no_std.rs:25:13 + --> tests/ui/mem_replace_no_std.rs:26:13 | LL | let _ = mem::replace(an_option, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()` error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take` - --> tests/ui/mem_replace_no_std.rs:30:13 + --> tests/ui/mem_replace_no_std.rs:32:13 | LL | let _ = mem::replace(&mut refstr, ""); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut refstr)` @@ -23,25 +23,25 @@ LL | let _ = mem::replace(&mut refstr, ""); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]` error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take` - --> tests/ui/mem_replace_no_std.rs:33:13 + --> tests/ui/mem_replace_no_std.rs:36:13 | LL | let _ = mem::replace(&mut slice, &[]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut slice)` error: replacing an `Option` with `None` - --> tests/ui/mem_replace_no_std.rs:76:13 + --> tests/ui/mem_replace_no_std.rs:80:13 | LL | let _ = mem::replace(&mut f.0, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()` error: replacing an `Option` with `None` - --> tests/ui/mem_replace_no_std.rs:77:13 + --> tests/ui/mem_replace_no_std.rs:82:13 | LL | let _ = mem::replace(&mut *f, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()` error: replacing an `Option` with `None` - --> tests/ui/mem_replace_no_std.rs:78:13 + --> tests/ui/mem_replace_no_std.rs:84:13 | LL | let _ = mem::replace(&mut b.opt, None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()` diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs index cb1f695c651c..a7e37b2e8d23 100644 --- a/tests/ui/methods.rs +++ b/tests/ui/methods.rs @@ -101,6 +101,7 @@ struct BadNew; impl BadNew { fn new() -> i32 { + //~^ new_ret_no_self 0 } } @@ -122,6 +123,7 @@ fn filter_next() { // Multi-line case. let _ = v.iter().filter(|&x| { + //~^ filter_next *x < 0 } ).next(); diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr index 2e2bd3d874f5..30e8d0794f71 100644 --- a/tests/ui/methods.stderr +++ b/tests/ui/methods.stderr @@ -2,6 +2,7 @@ error: methods called `new` usually return `Self` --> tests/ui/methods.rs:103:5 | LL | / fn new() -> i32 { +LL | | LL | | 0 LL | | } | |_____^ @@ -10,10 +11,11 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::new_ret_no_self)]` error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead - --> tests/ui/methods.rs:124:13 + --> tests/ui/methods.rs:125:13 | LL | let _ = v.iter().filter(|&x| { | _____________^ +LL | | LL | | *x < 0 LL | | } LL | | ).next(); diff --git a/tests/ui/methods_fixable.fixed b/tests/ui/methods_fixable.fixed index bb06b5a480ff..49730d811558 100644 --- a/tests/ui/methods_fixable.fixed +++ b/tests/ui/methods_fixable.fixed @@ -7,4 +7,5 @@ fn main() { // Single-line case. let _ = v.iter().find(|&x| *x < 0); + //~^ filter_next } diff --git a/tests/ui/methods_fixable.rs b/tests/ui/methods_fixable.rs index 11de924593ed..a499b63b6f5b 100644 --- a/tests/ui/methods_fixable.rs +++ b/tests/ui/methods_fixable.rs @@ -7,4 +7,5 @@ fn main() { // Single-line case. let _ = v.iter().filter(|&x| *x < 0).next(); + //~^ filter_next } diff --git a/tests/ui/methods_unfixable.rs b/tests/ui/methods_unfixable.rs index ee59983a7573..a9881080d6f4 100644 --- a/tests/ui/methods_unfixable.rs +++ b/tests/ui/methods_unfixable.rs @@ -7,5 +7,6 @@ fn main() { pub fn issue10029() { let iter = (0..10); let _ = iter.filter(|_| true).next(); - //~^ ERROR: called `filter(..).next()` on an `Iterator`. This is more succinctly expre + //~^ filter_next + } diff --git a/tests/ui/min_ident_chars.rs b/tests/ui/min_ident_chars.rs index 1d89f26b6ee4..5eae52d5c25c 100644 --- a/tests/ui/min_ident_chars.rs +++ b/tests/ui/min_ident_chars.rs @@ -7,24 +7,35 @@ extern crate proc_macros; use proc_macros::{external, with_span}; struct A { +//~^ min_ident_chars a: u32, + //~^ min_ident_chars i: u32, A: u32, + //~^ min_ident_chars I: u32, + //~^ min_ident_chars } struct B(u32); +//~^ min_ident_chars struct O { +//~^ min_ident_chars o: u32, + //~^ min_ident_chars } struct i; enum C { +//~^ min_ident_chars D, + //~^ min_ident_chars E, + //~^ min_ident_chars F, + //~^ min_ident_chars j, } @@ -39,8 +50,11 @@ struct AA(T, E); trait Trait { const A: u32 = 0; + //~^ min_ident_chars type A; + //~^ min_ident_chars fn a() {} + //~^ min_ident_chars } fn main() { @@ -55,22 +69,37 @@ fn main() { let z = 1; // Implicitly disallowed idents let h = 1; + //~^ min_ident_chars let e = 2; + //~^ min_ident_chars let l = 3; + //~^ min_ident_chars let l = 4; + //~^ min_ident_chars let o = 6; + //~^ min_ident_chars // 2 len does not lint let hi = 0; // Lint let (h, o, w) = (1, 2, 3); + //~^ min_ident_chars + //~| min_ident_chars for (a, (r, e)) in (0..1000).enumerate().enumerate() {} + //~^ min_ident_chars + //~| min_ident_chars + //~| min_ident_chars let you = Vec4 { x: 1, y: 2, z: 3, w: 4 }; while let (d, o, _i, n, g) = (true, true, false, false, true) {} + //~^ min_ident_chars + //~| min_ident_chars + //~| min_ident_chars let today = true; // Ideally this wouldn't lint, but this would (likely) require global analysis, outta scope // of this lint regardless let o = 1; + //~^ min_ident_chars let o = O { o }; + //~^ min_ident_chars for j in 0..1000 {} for _ in 0..10 {} @@ -85,7 +114,10 @@ fn main() { } fn b() {} +//~^ min_ident_chars fn wrong_pythagoras(a: f32, b: f32) -> f32 { +//~^ min_ident_chars +//~| min_ident_chars a * a + a * b } diff --git a/tests/ui/min_ident_chars.stderr b/tests/ui/min_ident_chars.stderr index 3dd5c9561fd0..bd6c45cf648e 100644 --- a/tests/ui/min_ident_chars.stderr +++ b/tests/ui/min_ident_chars.stderr @@ -8,187 +8,187 @@ LL | struct A { = help: to override `-D warnings` add `#[allow(clippy::min_ident_chars)]` error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:10:5 + --> tests/ui/min_ident_chars.rs:11:5 | LL | a: u32, | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:12:5 + --> tests/ui/min_ident_chars.rs:14:5 | LL | A: u32, | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:13:5 + --> tests/ui/min_ident_chars.rs:16:5 | LL | I: u32, | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:16:8 + --> tests/ui/min_ident_chars.rs:20:8 | LL | struct B(u32); | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:18:8 + --> tests/ui/min_ident_chars.rs:23:8 | LL | struct O { | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:19:5 + --> tests/ui/min_ident_chars.rs:25:5 | LL | o: u32, | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:24:6 + --> tests/ui/min_ident_chars.rs:31:6 | LL | enum C { | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:25:5 + --> tests/ui/min_ident_chars.rs:33:5 | LL | D, | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:26:5 + --> tests/ui/min_ident_chars.rs:35:5 | LL | E, | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:27:5 + --> tests/ui/min_ident_chars.rs:37:5 | LL | F, | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:41:11 + --> tests/ui/min_ident_chars.rs:52:11 | LL | const A: u32 = 0; | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:42:10 + --> tests/ui/min_ident_chars.rs:54:10 | LL | type A; | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:43:8 + --> tests/ui/min_ident_chars.rs:56:8 | LL | fn a() {} | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:57:9 + --> tests/ui/min_ident_chars.rs:71:9 | LL | let h = 1; | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:58:9 + --> tests/ui/min_ident_chars.rs:73:9 | LL | let e = 2; | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:59:9 + --> tests/ui/min_ident_chars.rs:75:9 | LL | let l = 3; | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:60:9 + --> tests/ui/min_ident_chars.rs:77:9 | LL | let l = 4; | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:61:9 + --> tests/ui/min_ident_chars.rs:79:9 | LL | let o = 6; | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:65:10 + --> tests/ui/min_ident_chars.rs:84:10 | LL | let (h, o, w) = (1, 2, 3); | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:65:13 + --> tests/ui/min_ident_chars.rs:84:13 | LL | let (h, o, w) = (1, 2, 3); | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:66:10 + --> tests/ui/min_ident_chars.rs:87:10 | LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:66:14 + --> tests/ui/min_ident_chars.rs:87:14 | LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:66:17 + --> tests/ui/min_ident_chars.rs:87:17 | LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:68:16 + --> tests/ui/min_ident_chars.rs:92:16 | LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:68:19 + --> tests/ui/min_ident_chars.rs:92:19 | LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:68:29 + --> tests/ui/min_ident_chars.rs:92:29 | LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:72:9 + --> tests/ui/min_ident_chars.rs:99:9 | LL | let o = 1; | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:73:9 + --> tests/ui/min_ident_chars.rs:101:9 | LL | let o = O { o }; | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:87:4 + --> tests/ui/min_ident_chars.rs:116:4 | LL | fn b() {} | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:88:21 + --> tests/ui/min_ident_chars.rs:118:21 | LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 { | ^ error: this ident consists of a single char - --> tests/ui/min_ident_chars.rs:88:29 + --> tests/ui/min_ident_chars.rs:118:29 | LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 { | ^ diff --git a/tests/ui/min_max.rs b/tests/ui/min_max.rs index cf64f85f9bb5..1b1a6a0eb10b 100644 --- a/tests/ui/min_max.rs +++ b/tests/ui/min_max.rs @@ -20,17 +20,22 @@ impl NotOrd { fn main() { let x = 2usize; min(1, max(3, x)); - //~^ ERROR: this `min`/`max` combination leads to constant result - //~| NOTE: `-D clippy::min-max` implied by `-D warnings` + //~^ min_max + + min(max(3, x), 1); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + max(min(x, 1), 3); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + max(3, min(x, 1)); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + my_max(3, my_min(x, 1)); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + min(3, max(1, x)); // ok, could be 1, 2 or 3 depending on x @@ -41,32 +46,40 @@ fn main() { let s = "Hello"; min("Apple", max("Zoo", s)); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + max(min(s, "Apple"), "Zoo"); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + max("Apple", min(s, "Zoo")); // ok let f = 3f32; x.min(1).max(3); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + x.max(3).min(1); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + f.max(3f32).min(1f32); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + x.max(1).min(3); // ok x.min(3).max(1); // ok f.min(3f32).max(1f32); // ok max(x.min(1), 3); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + min(x.max(1), 3); // ok s.max("Zoo").min("Apple"); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + s.min("Apple").max("Zoo"); - //~^ ERROR: this `min`/`max` combination leads to constant result + //~^ min_max + s.min("Zoo").max("Apple"); // ok diff --git a/tests/ui/min_max.stderr b/tests/ui/min_max.stderr index bb1a82e320d9..91b3d722b3c6 100644 --- a/tests/ui/min_max.stderr +++ b/tests/ui/min_max.stderr @@ -8,73 +8,73 @@ LL | min(1, max(3, x)); = help: to override `-D warnings` add `#[allow(clippy::min_max)]` error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:25:5 + --> tests/ui/min_max.rs:26:5 | LL | min(max(3, x), 1); | ^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:27:5 + --> tests/ui/min_max.rs:29:5 | LL | max(min(x, 1), 3); | ^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:29:5 + --> tests/ui/min_max.rs:32:5 | LL | max(3, min(x, 1)); | ^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:32:5 + --> tests/ui/min_max.rs:36:5 | LL | my_max(3, my_min(x, 1)); | ^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:43:5 + --> tests/ui/min_max.rs:48:5 | LL | min("Apple", max("Zoo", s)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:45:5 + --> tests/ui/min_max.rs:51:5 | LL | max(min(s, "Apple"), "Zoo"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:51:5 + --> tests/ui/min_max.rs:58:5 | LL | x.min(1).max(3); | ^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:53:5 + --> tests/ui/min_max.rs:61:5 | LL | x.max(3).min(1); | ^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:55:5 + --> tests/ui/min_max.rs:64:5 | LL | f.max(3f32).min(1f32); | ^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:62:5 + --> tests/ui/min_max.rs:72:5 | LL | max(x.min(1), 3); | ^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:66:5 + --> tests/ui/min_max.rs:77:5 | LL | s.max("Zoo").min("Apple"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:68:5 + --> tests/ui/min_max.rs:80:5 | LL | s.min("Apple").max("Zoo"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/min_rust_version_attr.rs b/tests/ui/min_rust_version_attr.rs index 5fe3306d6fc8..4793eb9726d6 100644 --- a/tests/ui/min_rust_version_attr.rs +++ b/tests/ui/min_rust_version_attr.rs @@ -11,13 +11,15 @@ fn just_under_msrv() { #[clippy::msrv = "1.43.0"] fn meets_msrv() { let log2_10 = 3.321928094887362; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found + //~^ approx_constant + } #[clippy::msrv = "1.44.0"] fn just_above_msrv() { let log2_10 = 3.321928094887362; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found + //~^ approx_constant + } #[clippy::msrv = "1.42"] @@ -28,7 +30,8 @@ fn no_patch_under() { #[clippy::msrv = "1.43"] fn no_patch_meets() { let log2_10 = 3.321928094887362; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found + //~^ approx_constant + } fn inner_attr_under() { @@ -39,7 +42,8 @@ fn inner_attr_under() { fn inner_attr_meets() { #![clippy::msrv = "1.43"] let log2_10 = 3.321928094887362; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found + //~^ approx_constant + } // https://github.com/rust-lang/rust-clippy/issues/6920 @@ -50,7 +54,8 @@ fn scoping() { // Should warn let log2_10 = 3.321928094887362; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found + //~^ approx_constant + mod a { #![clippy::msrv = "1.42.0"] @@ -58,7 +63,8 @@ fn scoping() { fn should_warn() { #![clippy::msrv = "1.43.0"] let log2_10 = 3.321928094887362; - //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found + //~^ approx_constant + } fn should_not_warn() { diff --git a/tests/ui/min_rust_version_attr.stderr b/tests/ui/min_rust_version_attr.stderr index 809b1cfe73bf..6d4a8d9bd86e 100644 --- a/tests/ui/min_rust_version_attr.stderr +++ b/tests/ui/min_rust_version_attr.stderr @@ -8,7 +8,7 @@ LL | let log2_10 = 3.321928094887362; = note: `#[deny(clippy::approx_constant)]` on by default error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:19:19 + --> tests/ui/min_rust_version_attr.rs:20:19 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let log2_10 = 3.321928094887362; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:30:19 + --> tests/ui/min_rust_version_attr.rs:32:19 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | let log2_10 = 3.321928094887362; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:41:19 + --> tests/ui/min_rust_version_attr.rs:44:19 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | let log2_10 = 3.321928094887362; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:52:19 + --> tests/ui/min_rust_version_attr.rs:56:19 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | let log2_10 = 3.321928094887362; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:60:27 + --> tests/ui/min_rust_version_attr.rs:65:27 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/mismatching_type_param_order.rs b/tests/ui/mismatching_type_param_order.rs index a4560f9e9a99..7e6044d0f5ff 100644 --- a/tests/ui/mismatching_type_param_order.rs +++ b/tests/ui/mismatching_type_param_order.rs @@ -9,12 +9,15 @@ fn main() { // lint on both params impl Foo {} - //~^ ERROR: `Foo` has a similarly named generic type parameter `B` in its declaration, - //~| ERROR: `Foo` has a similarly named generic type parameter `A` in its declaration, + //~^ mismatching_type_param_order + //~| mismatching_type_param_order + + // lint on the 2nd param impl Foo {} - //~^ ERROR: `Foo` has a similarly named generic type parameter `A` in its declaration, + //~^ mismatching_type_param_order + // should not lint impl Foo {} @@ -26,8 +29,10 @@ fn main() { // should not lint on lifetimes impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {} - //~^ ERROR: `FooLifetime` has a similarly named generic type parameter `B` in its decl - //~| ERROR: `FooLifetime` has a similarly named generic type parameter `A` in its decl + //~^ mismatching_type_param_order + //~| mismatching_type_param_order + + struct Bar { x: i32, @@ -44,9 +49,12 @@ fn main() { } impl FooEnum {} - //~^ ERROR: `FooEnum` has a similarly named generic type parameter `C` in its declarat - //~| ERROR: `FooEnum` has a similarly named generic type parameter `A` in its declarat - //~| ERROR: `FooEnum` has a similarly named generic type parameter `B` in its declarat + //~^ mismatching_type_param_order + //~| mismatching_type_param_order + //~| mismatching_type_param_order + + + // also works for unions union FooUnion @@ -58,8 +66,10 @@ fn main() { } impl FooUnion where A: Copy {} - //~^ ERROR: `FooUnion` has a similarly named generic type parameter `B` in its declara - //~| ERROR: `FooUnion` has a similarly named generic type parameter `A` in its declara + //~^ mismatching_type_param_order + //~| mismatching_type_param_order + + impl FooUnion where diff --git a/tests/ui/mismatching_type_param_order.stderr b/tests/ui/mismatching_type_param_order.stderr index 214d9d734d1b..817ab8c99796 100644 --- a/tests/ui/mismatching_type_param_order.stderr +++ b/tests/ui/mismatching_type_param_order.stderr @@ -17,7 +17,7 @@ LL | impl Foo {} = help: try `B`, or a name that does not conflict with `Foo`'s generic params error: `Foo` has a similarly named generic type parameter `A` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:16:23 + --> tests/ui/mismatching_type_param_order.rs:18:23 | LL | impl Foo {} | ^ @@ -25,7 +25,7 @@ LL | impl Foo {} = help: try `B`, or a name that does not conflict with `Foo`'s generic params error: `FooLifetime` has a similarly named generic type parameter `B` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:28:44 + --> tests/ui/mismatching_type_param_order.rs:31:44 | LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {} | ^ @@ -33,7 +33,7 @@ LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {} = help: try `A`, or a name that does not conflict with `FooLifetime`'s generic params error: `FooLifetime` has a similarly named generic type parameter `A` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:28:47 + --> tests/ui/mismatching_type_param_order.rs:31:47 | LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {} | ^ @@ -41,7 +41,7 @@ LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {} = help: try `B`, or a name that does not conflict with `FooLifetime`'s generic params error: `FooEnum` has a similarly named generic type parameter `C` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:46:27 + --> tests/ui/mismatching_type_param_order.rs:51:27 | LL | impl FooEnum {} | ^ @@ -49,7 +49,7 @@ LL | impl FooEnum {} = help: try `A`, or a name that does not conflict with `FooEnum`'s generic params error: `FooEnum` has a similarly named generic type parameter `A` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:46:30 + --> tests/ui/mismatching_type_param_order.rs:51:30 | LL | impl FooEnum {} | ^ @@ -57,7 +57,7 @@ LL | impl FooEnum {} = help: try `B`, or a name that does not conflict with `FooEnum`'s generic params error: `FooEnum` has a similarly named generic type parameter `B` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:46:33 + --> tests/ui/mismatching_type_param_order.rs:51:33 | LL | impl FooEnum {} | ^ @@ -65,7 +65,7 @@ LL | impl FooEnum {} = help: try `C`, or a name that does not conflict with `FooEnum`'s generic params error: `FooUnion` has a similarly named generic type parameter `B` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:60:31 + --> tests/ui/mismatching_type_param_order.rs:68:31 | LL | impl FooUnion where A: Copy {} | ^ @@ -73,7 +73,7 @@ LL | impl FooUnion where A: Copy {} = help: try `A`, or a name that does not conflict with `FooUnion`'s generic params error: `FooUnion` has a similarly named generic type parameter `A` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:60:34 + --> tests/ui/mismatching_type_param_order.rs:68:34 | LL | impl FooUnion where A: Copy {} | ^ diff --git a/tests/ui/misnamed_getters.fixed b/tests/ui/misnamed_getters.fixed index 70af604b2144..81af604e2e63 100644 --- a/tests/ui/misnamed_getters.fixed +++ b/tests/ui/misnamed_getters.fixed @@ -10,32 +10,38 @@ struct A { impl A { fn a(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field - //~| NOTE: `-D clippy::misnamed-getters` implied by `-D warnings` + //~^ misnamed_getters + + &self.a } fn a_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.a } fn b(self) -> u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + self.b } fn b_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.b } fn c(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.c } fn c_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.c } } @@ -47,21 +53,25 @@ union B { impl B { unsafe fn a(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.a } unsafe fn a_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.a } unsafe fn b(self) -> u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + self.b } unsafe fn b_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.b } @@ -74,21 +84,25 @@ impl B { } unsafe fn a_unchecked(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.a } unsafe fn a_unchecked_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.a } unsafe fn b_unchecked(self) -> u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + self.b } unsafe fn b_unchecked_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.b } @@ -121,20 +135,24 @@ impl core::ops::DerefMut for D { impl D { fn a(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.a } fn a_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.a } fn d(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.d } fn d_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.d } } diff --git a/tests/ui/misnamed_getters.rs b/tests/ui/misnamed_getters.rs index 23c3e7bc5cf7..cb83ae02ccf1 100644 --- a/tests/ui/misnamed_getters.rs +++ b/tests/ui/misnamed_getters.rs @@ -10,32 +10,38 @@ struct A { impl A { fn a(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field - //~| NOTE: `-D clippy::misnamed-getters` implied by `-D warnings` + //~^ misnamed_getters + + &self.b } fn a_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.b } fn b(self) -> u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + self.a } fn b_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.a } fn c(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.b } fn c_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.a } } @@ -47,21 +53,25 @@ union B { impl B { unsafe fn a(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.b } unsafe fn a_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.b } unsafe fn b(self) -> u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + self.a } unsafe fn b_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.a } @@ -74,21 +84,25 @@ impl B { } unsafe fn a_unchecked(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.b } unsafe fn a_unchecked_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.b } unsafe fn b_unchecked(self) -> u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + self.a } unsafe fn b_unchecked_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.a } @@ -121,20 +135,24 @@ impl core::ops::DerefMut for D { impl D { fn a(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.b } fn a_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.b } fn d(&self) -> &u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &self.b } fn d_mut(&mut self) -> &mut u8 { - //~^ ERROR: getter function appears to return the wrong field + //~^ misnamed_getters + &mut self.b } } diff --git a/tests/ui/misnamed_getters.stderr b/tests/ui/misnamed_getters.stderr index 056fa2be9215..e3ea40b7a94e 100644 --- a/tests/ui/misnamed_getters.stderr +++ b/tests/ui/misnamed_getters.stderr @@ -2,8 +2,7 @@ error: getter function appears to return the wrong field --> tests/ui/misnamed_getters.rs:12:5 | LL | / fn a(&self) -> &u8 { -LL | | -LL | | +... | LL | | &self.b | | ------- help: consider using: `&self.a` LL | | } @@ -13,170 +12,187 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::misnamed_getters)]` error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:17:5 + --> tests/ui/misnamed_getters.rs:18:5 | LL | / fn a_mut(&mut self) -> &mut u8 { LL | | +LL | | LL | | &mut self.b | | ----------- help: consider using: `&mut self.a` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:22:5 + --> tests/ui/misnamed_getters.rs:24:5 | LL | / fn b(self) -> u8 { LL | | +LL | | LL | | self.a | | ------ help: consider using: `self.b` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:27:5 + --> tests/ui/misnamed_getters.rs:30:5 | LL | / fn b_mut(&mut self) -> &mut u8 { LL | | +LL | | LL | | &mut self.a | | ----------- help: consider using: `&mut self.b` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:32:5 + --> tests/ui/misnamed_getters.rs:36:5 | LL | / fn c(&self) -> &u8 { LL | | +LL | | LL | | &self.b | | ------- help: consider using: `&self.c` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:37:5 + --> tests/ui/misnamed_getters.rs:42:5 | LL | / fn c_mut(&mut self) -> &mut u8 { LL | | +LL | | LL | | &mut self.a | | ----------- help: consider using: `&mut self.c` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:49:5 + --> tests/ui/misnamed_getters.rs:55:5 | LL | / unsafe fn a(&self) -> &u8 { LL | | +LL | | LL | | &self.b | | ------- help: consider using: `&self.a` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:53:5 + --> tests/ui/misnamed_getters.rs:60:5 | LL | / unsafe fn a_mut(&mut self) -> &mut u8 { LL | | +LL | | LL | | &mut self.b | | ----------- help: consider using: `&mut self.a` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:58:5 + --> tests/ui/misnamed_getters.rs:66:5 | LL | / unsafe fn b(self) -> u8 { LL | | +LL | | LL | | self.a | | ------ help: consider using: `self.b` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:63:5 + --> tests/ui/misnamed_getters.rs:72:5 | LL | / unsafe fn b_mut(&mut self) -> &mut u8 { LL | | +LL | | LL | | &mut self.a | | ----------- help: consider using: `&mut self.b` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:76:5 + --> tests/ui/misnamed_getters.rs:86:5 | LL | / unsafe fn a_unchecked(&self) -> &u8 { LL | | +LL | | LL | | &self.b | | ------- help: consider using: `&self.a` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:80:5 + --> tests/ui/misnamed_getters.rs:91:5 | LL | / unsafe fn a_unchecked_mut(&mut self) -> &mut u8 { LL | | +LL | | LL | | &mut self.b | | ----------- help: consider using: `&mut self.a` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:85:5 + --> tests/ui/misnamed_getters.rs:97:5 | LL | / unsafe fn b_unchecked(self) -> u8 { LL | | +LL | | LL | | self.a | | ------ help: consider using: `self.b` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:90:5 + --> tests/ui/misnamed_getters.rs:103:5 | LL | / unsafe fn b_unchecked_mut(&mut self) -> &mut u8 { LL | | +LL | | LL | | &mut self.a | | ----------- help: consider using: `&mut self.b` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:123:5 + --> tests/ui/misnamed_getters.rs:137:5 | LL | / fn a(&self) -> &u8 { LL | | +LL | | LL | | &self.b | | ------- help: consider using: `&self.a` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:127:5 + --> tests/ui/misnamed_getters.rs:142:5 | LL | / fn a_mut(&mut self) -> &mut u8 { LL | | +LL | | LL | | &mut self.b | | ----------- help: consider using: `&mut self.a` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:132:5 + --> tests/ui/misnamed_getters.rs:148:5 | LL | / fn d(&self) -> &u8 { LL | | +LL | | LL | | &self.b | | ------- help: consider using: `&self.d` LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:136:5 + --> tests/ui/misnamed_getters.rs:153:5 | LL | / fn d_mut(&mut self) -> &mut u8 { LL | | +LL | | LL | | &mut self.b | | ----------- help: consider using: `&mut self.d` LL | | } diff --git a/tests/ui/missing_asserts_for_indexing.fixed b/tests/ui/missing_asserts_for_indexing.fixed index ac44a6f3fdb2..ce23c45b5214 100644 --- a/tests/ui/missing_asserts_for_indexing.fixed +++ b/tests/ui/missing_asserts_for_indexing.fixed @@ -28,25 +28,29 @@ fn sum_with_assert_ge_other_way(v: &[u8]) -> u8 { fn sum_with_assert_lt(v: &[u8]) -> u8 { assert!(v.len() > 4); v[0] + v[1] + v[2] + v[3] + v[4] - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } fn sum_with_assert_le(v: &[u8]) -> u8 { assert!(v.len() > 4); v[0] + v[1] + v[2] + v[3] + v[4] - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } fn sum_with_incorrect_assert_len(v: &[u8]) -> u8 { assert!(v.len() > 4); v[0] + v[1] + v[2] + v[3] + v[4] - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } fn sum_with_incorrect_assert_len2(v: &[u8]) -> u8 { assert!(v.len() > 4); v[0] + v[1] + v[2] + v[3] + v[4] - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } // ok, don't lint for single array access @@ -64,7 +68,8 @@ fn subslice_ok(v: &[u8]) { fn subslice_bad(v: &[u8]) { assert!(v.len() > 3); let _ = v[0]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v[1..4]; } @@ -78,7 +83,8 @@ fn subslice_inclusive_ok(v: &[u8]) { fn subslice_inclusive_bad(v: &[u8]) { assert!(v.len() > 4); let _ = v[0]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v[1..=4]; } @@ -93,15 +99,18 @@ fn index_different_slices_wrong_len(v1: &[u8], v2: &[u8]) { assert!(v1.len() > 12); assert!(v2.len() > 15); let _ = v1[0] + v1[12]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v2[5] + v2[15]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } fn index_different_slices_one_wrong_len(v1: &[u8], v2: &[u8]) { assert!(v1.len() > 12); assert!(v2.len() > 15); let _ = v1[0] + v1[12]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v2[5] + v2[15]; } @@ -125,11 +134,13 @@ fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) { assert!(4 == v4.len()); let _ = v1[0] + v1[1] + v1[2]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v2[0] + v2[1] + v2[2]; let _ = v3[0] + v3[1] + v3[2]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v4[0] + v4[1] + v4[2]; } diff --git a/tests/ui/missing_asserts_for_indexing.rs b/tests/ui/missing_asserts_for_indexing.rs index f05d5fea57dc..2d129c6b7e2c 100644 --- a/tests/ui/missing_asserts_for_indexing.rs +++ b/tests/ui/missing_asserts_for_indexing.rs @@ -28,25 +28,29 @@ fn sum_with_assert_ge_other_way(v: &[u8]) -> u8 { fn sum_with_assert_lt(v: &[u8]) -> u8 { assert!(v.len() < 5); v[0] + v[1] + v[2] + v[3] + v[4] - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } fn sum_with_assert_le(v: &[u8]) -> u8 { assert!(v.len() <= 5); v[0] + v[1] + v[2] + v[3] + v[4] - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } fn sum_with_incorrect_assert_len(v: &[u8]) -> u8 { assert!(v.len() > 3); v[0] + v[1] + v[2] + v[3] + v[4] - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } fn sum_with_incorrect_assert_len2(v: &[u8]) -> u8 { assert!(v.len() >= 4); v[0] + v[1] + v[2] + v[3] + v[4] - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } // ok, don't lint for single array access @@ -64,7 +68,8 @@ fn subslice_ok(v: &[u8]) { fn subslice_bad(v: &[u8]) { assert!(v.len() >= 3); let _ = v[0]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v[1..4]; } @@ -78,7 +83,8 @@ fn subslice_inclusive_ok(v: &[u8]) { fn subslice_inclusive_bad(v: &[u8]) { assert!(v.len() >= 4); let _ = v[0]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v[1..=4]; } @@ -93,15 +99,18 @@ fn index_different_slices_wrong_len(v1: &[u8], v2: &[u8]) { assert!(v1.len() >= 12); assert!(v2.len() >= 15); let _ = v1[0] + v1[12]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v2[5] + v2[15]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + } fn index_different_slices_one_wrong_len(v1: &[u8], v2: &[u8]) { assert!(v1.len() >= 12); assert!(v2.len() > 15); let _ = v1[0] + v1[12]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v2[5] + v2[15]; } @@ -125,11 +134,13 @@ fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) { assert!(4 == v4.len()); let _ = v1[0] + v1[1] + v1[2]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v2[0] + v2[1] + v2[2]; let _ = v3[0] + v3[1] + v3[2]; - //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + //~^ missing_asserts_for_indexing + let _ = v4[0] + v4[1] + v4[2]; } diff --git a/tests/ui/missing_asserts_for_indexing.stderr b/tests/ui/missing_asserts_for_indexing.stderr index 2e63cd4a0e50..a1559d21150b 100644 --- a/tests/ui/missing_asserts_for_indexing.stderr +++ b/tests/ui/missing_asserts_for_indexing.stderr @@ -36,7 +36,7 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]` error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:36:5 + --> tests/ui/missing_asserts_for_indexing.rs:37:5 | LL | assert!(v.len() <= 5); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` @@ -44,34 +44,34 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:5 + --> tests/ui/missing_asserts_for_indexing.rs:37:5 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:12 + --> tests/ui/missing_asserts_for_indexing.rs:37:12 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:19 + --> tests/ui/missing_asserts_for_indexing.rs:37:19 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:26 + --> tests/ui/missing_asserts_for_indexing.rs:37:26 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:33 + --> tests/ui/missing_asserts_for_indexing.rs:37:33 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:42:5 + --> tests/ui/missing_asserts_for_indexing.rs:44:5 | LL | assert!(v.len() > 3); | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` @@ -79,34 +79,34 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:5 + --> tests/ui/missing_asserts_for_indexing.rs:44:5 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:12 + --> tests/ui/missing_asserts_for_indexing.rs:44:12 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:19 + --> tests/ui/missing_asserts_for_indexing.rs:44:19 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:26 + --> tests/ui/missing_asserts_for_indexing.rs:44:26 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:33 + --> tests/ui/missing_asserts_for_indexing.rs:44:33 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:48:5 + --> tests/ui/missing_asserts_for_indexing.rs:51:5 | LL | assert!(v.len() >= 4); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` @@ -114,80 +114,80 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:5 + --> tests/ui/missing_asserts_for_indexing.rs:51:5 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:12 + --> tests/ui/missing_asserts_for_indexing.rs:51:12 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:19 + --> tests/ui/missing_asserts_for_indexing.rs:51:19 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:26 + --> tests/ui/missing_asserts_for_indexing.rs:51:26 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:33 + --> tests/ui/missing_asserts_for_indexing.rs:51:33 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:66:13 + --> tests/ui/missing_asserts_for_indexing.rs:70:13 | LL | assert!(v.len() >= 3); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 3)` LL | let _ = v[0]; | _____________^ -LL | | +... | LL | | let _ = v[1..4]; | |___________________^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:66:13 + --> tests/ui/missing_asserts_for_indexing.rs:70:13 | LL | let _ = v[0]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:68:13 + --> tests/ui/missing_asserts_for_indexing.rs:73:13 | LL | let _ = v[1..4]; | ^^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:80:13 + --> tests/ui/missing_asserts_for_indexing.rs:85:13 | LL | assert!(v.len() >= 4); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | let _ = v[0]; | _____________^ -LL | | +... | LL | | let _ = v[1..=4]; | |____________________^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:80:13 + --> tests/ui/missing_asserts_for_indexing.rs:85:13 | LL | let _ = v[0]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:82:13 + --> tests/ui/missing_asserts_for_indexing.rs:88:13 | LL | let _ = v[1..=4]; | ^^^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:95:13 + --> tests/ui/missing_asserts_for_indexing.rs:101:13 | LL | assert!(v1.len() >= 12); | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` @@ -196,19 +196,19 @@ LL | let _ = v1[0] + v1[12]; | ^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:95:13 + --> tests/ui/missing_asserts_for_indexing.rs:101:13 | LL | let _ = v1[0] + v1[12]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:95:21 + --> tests/ui/missing_asserts_for_indexing.rs:101:21 | LL | let _ = v1[0] + v1[12]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:97:13 + --> tests/ui/missing_asserts_for_indexing.rs:104:13 | LL | assert!(v2.len() >= 15); | ----------------------- help: provide the highest index that is indexed with: `assert!(v2.len() > 15)` @@ -217,19 +217,19 @@ LL | let _ = v2[5] + v2[15]; | ^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:97:13 + --> tests/ui/missing_asserts_for_indexing.rs:104:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:97:21 + --> tests/ui/missing_asserts_for_indexing.rs:104:21 | LL | let _ = v2[5] + v2[15]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:103:13 + --> tests/ui/missing_asserts_for_indexing.rs:111:13 | LL | assert!(v1.len() >= 12); | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` @@ -238,19 +238,19 @@ LL | let _ = v1[0] + v1[12]; | ^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:103:13 + --> tests/ui/missing_asserts_for_indexing.rs:111:13 | LL | let _ = v1[0] + v1[12]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:103:21 + --> tests/ui/missing_asserts_for_indexing.rs:111:21 | LL | let _ = v1[0] + v1[12]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:127:13 + --> tests/ui/missing_asserts_for_indexing.rs:136:13 | LL | assert!(v1.len() == 2); | ---------------------- help: provide the highest index that is indexed with: `assert!(v1.len() == 3)` @@ -259,24 +259,24 @@ LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:127:13 + --> tests/ui/missing_asserts_for_indexing.rs:136:13 | LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:127:21 + --> tests/ui/missing_asserts_for_indexing.rs:136:21 | LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:127:29 + --> tests/ui/missing_asserts_for_indexing.rs:136:29 | LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:131:13 + --> tests/ui/missing_asserts_for_indexing.rs:141:13 | LL | assert!(2 == v3.len()); | ---------------------- help: provide the highest index that is indexed with: `assert!(v3.len() == 3)` @@ -285,17 +285,17 @@ LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:131:13 + --> tests/ui/missing_asserts_for_indexing.rs:141:13 | LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:131:21 + --> tests/ui/missing_asserts_for_indexing.rs:141:21 | LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:131:29 + --> tests/ui/missing_asserts_for_indexing.rs:141:29 | LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ diff --git a/tests/ui/missing_asserts_for_indexing_unfixable.rs b/tests/ui/missing_asserts_for_indexing_unfixable.rs index de53079a4760..c2083a90a19a 100644 --- a/tests/ui/missing_asserts_for_indexing_unfixable.rs +++ b/tests/ui/missing_asserts_for_indexing_unfixable.rs @@ -3,18 +3,21 @@ fn sum(v: &[u8]) -> u8 { v[0] + v[1] + v[2] + v[3] + v[4] - //~^ ERROR: indexing into a slice multiple times without an `assert` + //~^ missing_asserts_for_indexing + } fn subslice(v: &[u8]) { let _ = v[0]; - //~^ ERROR: indexing into a slice multiple times without an `assert` + //~^ missing_asserts_for_indexing + let _ = v[1..4]; } fn variables(v: &[u8]) -> u8 { let a = v[0]; - //~^ ERROR: indexing into a slice multiple times without an `assert` + //~^ missing_asserts_for_indexing + let b = v[1]; let c = v[2]; a + b + c @@ -22,13 +25,16 @@ fn variables(v: &[u8]) -> u8 { fn index_different_slices(v1: &[u8], v2: &[u8]) { let _ = v1[0] + v1[12]; + //~^ missing_asserts_for_indexing let _ = v2[5] + v2[15]; + //~^ missing_asserts_for_indexing } fn index_different_slices2(v1: &[u8], v2: &[u8]) { assert!(v1.len() > 12); let _ = v1[0] + v1[12]; let _ = v2[5] + v2[15]; + //~^ missing_asserts_for_indexing } struct Foo<'a> { @@ -38,7 +44,8 @@ struct Foo<'a> { fn index_struct_field(f: &Foo<'_>) { let _ = f.v[0] + f.v[1]; - //~^ ERROR: indexing into a slice multiple times without an `assert` + //~^ missing_asserts_for_indexing + } fn index_struct_different_fields(f: &Foo<'_>) { @@ -52,7 +59,8 @@ fn shadowing() { let x: &[i32] = &[1]; let _ = x[0] + x[1]; - //~^ ERROR: indexing into a slice multiple times without an `assert` + //~^ missing_asserts_for_indexing + } pub fn issue11856(values: &[i32]) -> usize { diff --git a/tests/ui/missing_asserts_for_indexing_unfixable.stderr b/tests/ui/missing_asserts_for_indexing_unfixable.stderr index b575e09966ce..f6557fb2e50f 100644 --- a/tests/ui/missing_asserts_for_indexing_unfixable.stderr +++ b/tests/ui/missing_asserts_for_indexing_unfixable.stderr @@ -35,145 +35,146 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]` error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:10:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:11:13 | LL | let _ = v[0]; | _____________^ -LL | | +... | LL | | let _ = v[1..4]; | |___________________^ | = help: consider asserting the length before indexing: `assert!(v.len() > 3);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:10:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:11:13 | LL | let _ = v[0]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:12:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:14:13 | LL | let _ = v[1..4]; | ^^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:16:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:18:13 | LL | let a = v[0]; | _____________^ LL | | +LL | | LL | | let b = v[1]; LL | | let c = v[2]; | |________________^ | = help: consider asserting the length before indexing: `assert!(v.len() > 2);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:16:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:18:13 | LL | let a = v[0]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:18:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:21:13 | LL | let b = v[1]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:19:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:22:13 | LL | let c = v[2]; | ^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:24:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:27:13 | LL | let _ = v1[0] + v1[12]; | ^^^^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(v1.len() > 12);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:24:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:27:13 | LL | let _ = v1[0] + v1[12]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:24:21 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:27:21 | LL | let _ = v1[0] + v1[12]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:25:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:29:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(v2.len() > 15);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:25:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:29:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:25:21 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:29:21 | LL | let _ = v2[5] + v2[15]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:31:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:36:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(v2.len() > 15);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:31:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:36:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:31:21 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:36:21 | LL | let _ = v2[5] + v2[15]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:40:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:46:13 | LL | let _ = f.v[0] + f.v[1]; | ^^^^^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(f.v.len() > 1);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:40:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:46:13 | LL | let _ = f.v[0] + f.v[1]; | ^^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:40:22 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:46:22 | LL | let _ = f.v[0] + f.v[1]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:54:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:61:13 | LL | let _ = x[0] + x[1]; | ^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(x.len() > 1);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:54:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:61:13 | LL | let _ = x[0] + x[1]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:54:20 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:61:20 | LL | let _ = x[0] + x[1]; | ^^^^ diff --git a/tests/ui/missing_const_for_fn/cant_be_const.rs b/tests/ui/missing_const_for_fn/cant_be_const.rs index cdfdcd5007a8..aef5eb5b890a 100644 --- a/tests/ui/missing_const_for_fn/cant_be_const.rs +++ b/tests/ui/missing_const_for_fn/cant_be_const.rs @@ -1,3 +1,4 @@ +//@ check-pass //! False-positive tests to ensure we don't suggest `const` for things where it would cause a //! compilation error. //! The .stderr output of this test should be empty. Otherwise it's a bug somewhere. diff --git a/tests/ui/missing_const_for_fn/could_be_const.fixed b/tests/ui/missing_const_for_fn/could_be_const.fixed index 689060468c57..592302c34ae6 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.fixed +++ b/tests/ui/missing_const_for_fn/could_be_const.fixed @@ -11,45 +11,44 @@ struct Game { impl Game { // Could be const pub const fn new() -> Self { - //~^ ERROR: this could be a `const fn` - //~| NOTE: `-D clippy::missing-const-for-fn` implied by `-D warnings` + //~^ missing_const_for_fn Self { guess: 42 } } const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn b } } // Could be const const fn one() -> i32 { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn 1 } // Could also be const const fn two() -> i32 { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn let abc = 2; abc } // Could be const (since Rust 1.39) const fn string() -> String { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn String::new() } // Could be const const unsafe fn four() -> i32 { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn 4 } // Could also be const const fn generic(t: T) -> T { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn t } @@ -58,7 +57,7 @@ fn sub(x: u32) -> usize { } const fn generic_arr(t: [T; 1]) -> T { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn t[0] } @@ -72,7 +71,7 @@ mod with_drop { impl B { // This can be const, because `a` is passed by reference pub const fn b(self, a: &A) -> B { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn B } } @@ -82,7 +81,7 @@ mod with_drop { mod const_fn_stabilized_before_msrv { // This could be const because `u8::is_ascii_digit` is a stable const function in 1.47. const fn const_fn_stabilized_before_msrv(byte: u8) { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn byte.is_ascii_digit(); } } @@ -94,7 +93,7 @@ fn msrv_1_45() -> i32 { #[clippy::msrv = "1.46"] const fn msrv_1_46() -> i32 { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn 46 } @@ -114,7 +113,7 @@ impl const Drop for D { // Lint this, since it can be dropped in const contexts // FIXME(const_trait_impl) const fn d(this: D) {} -//~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn mod msrv { struct Foo(*const u8, &'static u8); @@ -122,12 +121,12 @@ mod msrv { impl Foo { #[clippy::msrv = "1.58"] const fn deref_ptr_can_be_const(self) -> usize { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn unsafe { *self.0 as usize } } const fn deref_copied_val(self) -> usize { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn *self.1 as usize } } @@ -138,7 +137,7 @@ mod msrv { #[clippy::msrv = "1.56"] const fn union_access_can_be_const() { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn let bar = Bar { val: 1 }; let _ = unsafe { bar.val }; } @@ -146,12 +145,12 @@ mod msrv { #[clippy::msrv = "1.62"] mod with_extern { const extern "C" fn c() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn #[rustfmt::skip] #[allow(missing_abi)] const extern fn implicit_c() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn // any item functions in extern block won't trigger this lint extern "C" { @@ -168,11 +167,13 @@ mod issue12677 { impl Wrapper { #[must_use] pub const fn new(strings: Vec) -> Self { + //~^ missing_const_for_fn Self { strings } } #[must_use] pub const fn empty() -> Self { + //~^ missing_const_for_fn Self { strings: Vec::new() } } } @@ -184,6 +185,7 @@ mod issue12677 { impl Other { pub const fn new(text: String) -> Self { + //~^ missing_const_for_fn let vec = Vec::new(); Self { text, vec } } @@ -203,18 +205,19 @@ mod with_ty_alias { // is. Because the associate ty could have no default, therefore would cause ICE, as demonstrated // in this test. const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {} + //~^ missing_const_for_fn } mod extern_fn { const extern "C-unwind" fn c_unwind() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn const extern "system" fn system() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn const extern "system-unwind" fn system_unwind() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn } const fn mut_add(x: &mut i32) { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn *x += 1; } diff --git a/tests/ui/missing_const_for_fn/could_be_const.rs b/tests/ui/missing_const_for_fn/could_be_const.rs index 492c47d7e49b..f689f9bb7f92 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/tests/ui/missing_const_for_fn/could_be_const.rs @@ -11,45 +11,44 @@ struct Game { impl Game { // Could be const pub fn new() -> Self { - //~^ ERROR: this could be a `const fn` - //~| NOTE: `-D clippy::missing-const-for-fn` implied by `-D warnings` + //~^ missing_const_for_fn Self { guess: 42 } } fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn b } } // Could be const fn one() -> i32 { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn 1 } // Could also be const fn two() -> i32 { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn let abc = 2; abc } // Could be const (since Rust 1.39) fn string() -> String { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn String::new() } // Could be const unsafe fn four() -> i32 { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn 4 } // Could also be const fn generic(t: T) -> T { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn t } @@ -58,7 +57,7 @@ fn sub(x: u32) -> usize { } fn generic_arr(t: [T; 1]) -> T { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn t[0] } @@ -72,7 +71,7 @@ mod with_drop { impl B { // This can be const, because `a` is passed by reference pub fn b(self, a: &A) -> B { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn B } } @@ -82,7 +81,7 @@ mod with_drop { mod const_fn_stabilized_before_msrv { // This could be const because `u8::is_ascii_digit` is a stable const function in 1.47. fn const_fn_stabilized_before_msrv(byte: u8) { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn byte.is_ascii_digit(); } } @@ -94,7 +93,7 @@ fn msrv_1_45() -> i32 { #[clippy::msrv = "1.46"] fn msrv_1_46() -> i32 { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn 46 } @@ -114,7 +113,7 @@ impl const Drop for D { // Lint this, since it can be dropped in const contexts // FIXME(const_trait_impl) fn d(this: D) {} -//~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn mod msrv { struct Foo(*const u8, &'static u8); @@ -122,12 +121,12 @@ mod msrv { impl Foo { #[clippy::msrv = "1.58"] fn deref_ptr_can_be_const(self) -> usize { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn unsafe { *self.0 as usize } } fn deref_copied_val(self) -> usize { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn *self.1 as usize } } @@ -138,7 +137,7 @@ mod msrv { #[clippy::msrv = "1.56"] fn union_access_can_be_const() { - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn let bar = Bar { val: 1 }; let _ = unsafe { bar.val }; } @@ -146,12 +145,12 @@ mod msrv { #[clippy::msrv = "1.62"] mod with_extern { extern "C" fn c() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn #[rustfmt::skip] #[allow(missing_abi)] extern fn implicit_c() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn // any item functions in extern block won't trigger this lint extern "C" { @@ -168,11 +167,13 @@ mod issue12677 { impl Wrapper { #[must_use] pub fn new(strings: Vec) -> Self { + //~^ missing_const_for_fn Self { strings } } #[must_use] pub fn empty() -> Self { + //~^ missing_const_for_fn Self { strings: Vec::new() } } } @@ -184,6 +185,7 @@ mod issue12677 { impl Other { pub fn new(text: String) -> Self { + //~^ missing_const_for_fn let vec = Vec::new(); Self { text, vec } } @@ -203,18 +205,19 @@ mod with_ty_alias { // is. Because the associate ty could have no default, therefore would cause ICE, as demonstrated // in this test. fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {} + //~^ missing_const_for_fn } mod extern_fn { extern "C-unwind" fn c_unwind() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn extern "system" fn system() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn extern "system-unwind" fn system_unwind() {} - //~^ ERROR: this could be a `const fn` + //~^ missing_const_for_fn } fn mut_add(x: &mut i32) { - //~^ ERROR: this could be a `const fn` +//~^ missing_const_for_fn *x += 1; } diff --git a/tests/ui/missing_const_for_fn/could_be_const.stderr b/tests/ui/missing_const_for_fn/could_be_const.stderr index a06703e2ebf2..5df5a54ff521 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -3,7 +3,6 @@ error: this could be a `const fn` | LL | / pub fn new() -> Self { LL | | -LL | | LL | | Self { guess: 42 } LL | | } | |_____^ @@ -16,7 +15,7 @@ LL | pub const fn new() -> Self { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:19:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:18:5 | LL | / fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] { LL | | @@ -30,7 +29,7 @@ LL | const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:26:1 + --> tests/ui/missing_const_for_fn/could_be_const.rs:25:1 | LL | / fn one() -> i32 { LL | | @@ -44,7 +43,7 @@ LL | const fn one() -> i32 { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:32:1 + --> tests/ui/missing_const_for_fn/could_be_const.rs:31:1 | LL | / fn two() -> i32 { LL | | @@ -59,7 +58,7 @@ LL | const fn two() -> i32 { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:39:1 + --> tests/ui/missing_const_for_fn/could_be_const.rs:38:1 | LL | / fn string() -> String { LL | | @@ -73,7 +72,7 @@ LL | const fn string() -> String { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:45:1 + --> tests/ui/missing_const_for_fn/could_be_const.rs:44:1 | LL | / unsafe fn four() -> i32 { LL | | @@ -87,7 +86,7 @@ LL | const unsafe fn four() -> i32 { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:51:1 + --> tests/ui/missing_const_for_fn/could_be_const.rs:50:1 | LL | / fn generic(t: T) -> T { LL | | @@ -101,7 +100,7 @@ LL | const fn generic(t: T) -> T { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:60:1 + --> tests/ui/missing_const_for_fn/could_be_const.rs:59:1 | LL | / fn generic_arr(t: [T; 1]) -> T { LL | | @@ -115,7 +114,7 @@ LL | const fn generic_arr(t: [T; 1]) -> T { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:74:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:73:9 | LL | / pub fn b(self, a: &A) -> B { LL | | @@ -129,7 +128,7 @@ LL | pub const fn b(self, a: &A) -> B { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:84:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:83:5 | LL | / fn const_fn_stabilized_before_msrv(byte: u8) { LL | | @@ -143,7 +142,7 @@ LL | const fn const_fn_stabilized_before_msrv(byte: u8) { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:96:1 + --> tests/ui/missing_const_for_fn/could_be_const.rs:95:1 | LL | / fn msrv_1_46() -> i32 { LL | | @@ -157,7 +156,7 @@ LL | const fn msrv_1_46() -> i32 { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:116:1 + --> tests/ui/missing_const_for_fn/could_be_const.rs:115:1 | LL | fn d(this: D) {} | ^^^^^^^^^^^^^^^^ @@ -168,7 +167,7 @@ LL | const fn d(this: D) {} | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:124:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:123:9 | LL | / fn deref_ptr_can_be_const(self) -> usize { LL | | @@ -182,7 +181,7 @@ LL | const fn deref_ptr_can_be_const(self) -> usize { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:129:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:128:9 | LL | / fn deref_copied_val(self) -> usize { LL | | @@ -196,7 +195,7 @@ LL | const fn deref_copied_val(self) -> usize { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:140:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:139:5 | LL | / fn union_access_can_be_const() { LL | | @@ -211,7 +210,7 @@ LL | const fn union_access_can_be_const() { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:148:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:147:9 | LL | extern "C" fn c() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -222,7 +221,7 @@ LL | const extern "C" fn c() {} | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:153:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:152:9 | LL | extern fn implicit_c() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,9 +232,10 @@ LL | const extern fn implicit_c() {} | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:170:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:169:9 | LL | / pub fn new(strings: Vec) -> Self { +LL | | LL | | Self { strings } LL | | } | |_________^ @@ -249,6 +249,7 @@ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:175:9 | LL | / pub fn empty() -> Self { +LL | | LL | | Self { strings: Vec::new() } LL | | } | |_________^ @@ -259,9 +260,10 @@ LL | pub const fn empty() -> Self { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:186:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:187:9 | LL | / pub fn new(text: String) -> Self { +LL | | LL | | let vec = Vec::new(); LL | | Self { text, vec } LL | | } @@ -273,7 +275,7 @@ LL | pub const fn new(text: String) -> Self { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:205:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:207:5 | LL | fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -284,7 +286,7 @@ LL | const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {} | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:209:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:212:5 | LL | extern "C-unwind" fn c_unwind() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -295,7 +297,7 @@ LL | const extern "C-unwind" fn c_unwind() {} | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:211:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:214:5 | LL | extern "system" fn system() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -306,7 +308,7 @@ LL | const extern "system" fn system() {} | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:213:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:216:5 | LL | extern "system-unwind" fn system_unwind() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -317,7 +319,7 @@ LL | const extern "system-unwind" fn system_unwind() {} | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:217:1 + --> tests/ui/missing_const_for_fn/could_be_const.rs:220:1 | LL | / fn mut_add(x: &mut i32) { LL | | diff --git a/tests/ui/missing_const_for_thread_local.fixed b/tests/ui/missing_const_for_thread_local.fixed index 90b31b9b5d21..281d7a6c9da3 100644 --- a/tests/ui/missing_const_for_thread_local.fixed +++ b/tests/ui/missing_const_for_thread_local.fixed @@ -6,8 +6,9 @@ fn main() { // lint and suggest const thread_local! { static BUF_1: RefCell = const { RefCell::new(String::new()) }; + //~^ missing_const_for_thread_local } - //~^^ ERROR: initializer for `thread_local` value can be made `const` + // don't lint thread_local! { @@ -16,23 +17,28 @@ fn main() { thread_local! { static SIMPLE:i32 = const { 1 }; + //~^ missing_const_for_thread_local } - //~^^ ERROR: initializer for `thread_local` value can be made `const` + // lint and suggest const for all non const items thread_local! { static BUF_3_CAN_BE_MADE_CONST: RefCell = const { RefCell::new(String::new()) }; + //~^ missing_const_for_thread_local static CONST_MIXED_WITH:i32 = const { 1 }; static BUF_4_CAN_BE_MADE_CONST: RefCell = const { RefCell::new(String::new()) }; + //~^ missing_const_for_thread_local } - //~^^^^ ERROR: initializer for `thread_local` value can be made `const` - //~^^^ ERROR: initializer for `thread_local` value can be made `const` + + thread_local! { static PEEL_ME: i32 = const { 1 }; - //~^ ERROR: initializer for `thread_local` value can be made `const` + //~^ missing_const_for_thread_local + static PEEL_ME_MANY: i32 = const { { let x = 1; x * x } }; - //~^ ERROR: initializer for `thread_local` value can be made `const` + //~^ missing_const_for_thread_local + } } diff --git a/tests/ui/missing_const_for_thread_local.rs b/tests/ui/missing_const_for_thread_local.rs index f97e4848fd7a..07239e5fa617 100644 --- a/tests/ui/missing_const_for_thread_local.rs +++ b/tests/ui/missing_const_for_thread_local.rs @@ -6,8 +6,9 @@ fn main() { // lint and suggest const thread_local! { static BUF_1: RefCell = RefCell::new(String::new()); + //~^ missing_const_for_thread_local } - //~^^ ERROR: initializer for `thread_local` value can be made `const` + // don't lint thread_local! { @@ -16,23 +17,28 @@ fn main() { thread_local! { static SIMPLE:i32 = 1; + //~^ missing_const_for_thread_local } - //~^^ ERROR: initializer for `thread_local` value can be made `const` + // lint and suggest const for all non const items thread_local! { static BUF_3_CAN_BE_MADE_CONST: RefCell = RefCell::new(String::new()); + //~^ missing_const_for_thread_local static CONST_MIXED_WITH:i32 = const { 1 }; static BUF_4_CAN_BE_MADE_CONST: RefCell = RefCell::new(String::new()); + //~^ missing_const_for_thread_local } - //~^^^^ ERROR: initializer for `thread_local` value can be made `const` - //~^^^ ERROR: initializer for `thread_local` value can be made `const` + + thread_local! { static PEEL_ME: i32 = { 1 }; - //~^ ERROR: initializer for `thread_local` value can be made `const` + //~^ missing_const_for_thread_local + static PEEL_ME_MANY: i32 = { let x = 1; x * x }; - //~^ ERROR: initializer for `thread_local` value can be made `const` + //~^ missing_const_for_thread_local + } } diff --git a/tests/ui/missing_const_for_thread_local.stderr b/tests/ui/missing_const_for_thread_local.stderr index c143a37454f5..76104a3761eb 100644 --- a/tests/ui/missing_const_for_thread_local.stderr +++ b/tests/ui/missing_const_for_thread_local.stderr @@ -8,31 +8,31 @@ LL | static BUF_1: RefCell = RefCell::new(String::new()); = help: to override `-D warnings` add `#[allow(clippy::missing_const_for_thread_local)]` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:18:29 + --> tests/ui/missing_const_for_thread_local.rs:19:29 | LL | static SIMPLE:i32 = 1; | ^ help: replace with: `const { 1 }` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:24:59 + --> tests/ui/missing_const_for_thread_local.rs:26:59 | LL | static BUF_3_CAN_BE_MADE_CONST: RefCell = RefCell::new(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(String::new()) }` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:26:59 + --> tests/ui/missing_const_for_thread_local.rs:29:59 | LL | static BUF_4_CAN_BE_MADE_CONST: RefCell = RefCell::new(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(String::new()) }` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:32:31 + --> tests/ui/missing_const_for_thread_local.rs:36:31 | LL | static PEEL_ME: i32 = { 1 }; | ^^^^^ help: replace with: `const { 1 }` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:34:36 + --> tests/ui/missing_const_for_thread_local.rs:39:36 | LL | static PEEL_ME_MANY: i32 = { let x = 1; x * x }; | ^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { { let x = 1; x * x } }` diff --git a/tests/ui/missing_doc.rs b/tests/ui/missing_doc.rs index 31bc4309582e..301c46e0f1b9 100644 --- a/tests/ui/missing_doc.rs +++ b/tests/ui/missing_doc.rs @@ -17,15 +17,18 @@ use proc_macros::with_span; use std::arch::global_asm; type Typedef = String; +//~^ missing_docs_in_private_items pub type PubTypedef = String; mod module_no_dox {} +//~^ missing_docs_in_private_items pub mod pub_module_no_dox {} /// dox pub fn foo() {} pub fn foo2() {} fn foo3() {} +//~^ missing_docs_in_private_items #[allow(clippy::missing_docs_in_private_items)] pub fn foo4() {} @@ -40,8 +43,13 @@ mod a { } enum Baz { +//~^ missing_docs_in_private_items BazA { a: isize, b: isize }, + //~^ missing_docs_in_private_items + //~| missing_docs_in_private_items + //~| missing_docs_in_private_items BarB, + //~^ missing_docs_in_private_items } pub enum PubBaz { @@ -66,6 +74,7 @@ pub enum PubBaz3 { pub fn baz() {} const FOO: u32 = 0; +//~^ missing_docs_in_private_items /// dox pub const FOO1: u32 = 0; #[allow(clippy::missing_docs_in_private_items)] @@ -75,6 +84,7 @@ pub const FOO3: u32 = 0; pub const FOO4: u32 = 0; static BAR: u32 = 0; +//~^ missing_docs_in_private_items /// dox pub static BAR1: u32 = 0; #[allow(clippy::missing_docs_in_private_items)] @@ -84,17 +94,20 @@ pub static BAR3: u32 = 0; pub static BAR4: u32 = 0; mod internal_impl { +//~^ missing_docs_in_private_items /// dox pub fn documented() {} pub fn undocumented1() {} pub fn undocumented2() {} fn undocumented3() {} + //~^ missing_docs_in_private_items /// dox pub mod globbed { /// dox pub fn also_documented() {} pub fn also_undocumented1() {} fn also_undocumented2() {} + //~^ missing_docs_in_private_items } } /// dox @@ -120,6 +133,7 @@ with_span!(span pub const FOO2_PM: u32 = 0;); const _: () = (); fn issue13298() { +//~^ missing_docs_in_private_items // Rustdoc doesn't generate documentation for items within other items like fns or consts const MSG: &str = "Hello, world!"; } diff --git a/tests/ui/missing_doc.stderr b/tests/ui/missing_doc.stderr index 6554eed16106..63e440b82d14 100644 --- a/tests/ui/missing_doc.stderr +++ b/tests/ui/missing_doc.stderr @@ -8,89 +8,91 @@ LL | type Typedef = String; = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` error: missing documentation for a module - --> tests/ui/missing_doc.rs:22:1 + --> tests/ui/missing_doc.rs:23:1 | LL | mod module_no_dox {} | ^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> tests/ui/missing_doc.rs:28:1 + --> tests/ui/missing_doc.rs:30:1 | LL | fn foo3() {} | ^^^^^^^^^^^^ error: missing documentation for an enum - --> tests/ui/missing_doc.rs:42:1 + --> tests/ui/missing_doc.rs:45:1 | LL | / enum Baz { +LL | | LL | | BazA { a: isize, b: isize }, -LL | | BarB, +... | LL | | } | |_^ error: missing documentation for a variant - --> tests/ui/missing_doc.rs:43:5 + --> tests/ui/missing_doc.rs:47:5 | LL | BazA { a: isize, b: isize }, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a struct field - --> tests/ui/missing_doc.rs:43:12 + --> tests/ui/missing_doc.rs:47:12 | LL | BazA { a: isize, b: isize }, | ^^^^^^^^ error: missing documentation for a struct field - --> tests/ui/missing_doc.rs:43:22 + --> tests/ui/missing_doc.rs:47:22 | LL | BazA { a: isize, b: isize }, | ^^^^^^^^ error: missing documentation for a variant - --> tests/ui/missing_doc.rs:44:5 + --> tests/ui/missing_doc.rs:51:5 | LL | BarB, | ^^^^ error: missing documentation for a constant - --> tests/ui/missing_doc.rs:68:1 + --> tests/ui/missing_doc.rs:76:1 | LL | const FOO: u32 = 0; | ^^^^^^^^^^^^^^^^^^^ error: missing documentation for a static - --> tests/ui/missing_doc.rs:77:1 + --> tests/ui/missing_doc.rs:86:1 | LL | static BAR: u32 = 0; | ^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a module - --> tests/ui/missing_doc.rs:86:1 + --> tests/ui/missing_doc.rs:96:1 | LL | / mod internal_impl { +LL | | LL | | /// dox LL | | pub fn documented() {} -LL | | pub fn undocumented1() {} ... | LL | | } | |_^ error: missing documentation for a function - --> tests/ui/missing_doc.rs:91:5 + --> tests/ui/missing_doc.rs:102:5 | LL | fn undocumented3() {} | ^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> tests/ui/missing_doc.rs:97:9 + --> tests/ui/missing_doc.rs:109:9 | LL | fn also_undocumented2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> tests/ui/missing_doc.rs:122:1 + --> tests/ui/missing_doc.rs:135:1 | LL | / fn issue13298() { +LL | | LL | | // Rustdoc doesn't generate documentation for items within other items like fns or consts LL | | const MSG: &str = "Hello, world!"; LL | | } diff --git a/tests/ui/missing_doc_crate.rs b/tests/ui/missing_doc_crate.rs index fdb23af279df..e6e783a2bb40 100644 --- a/tests/ui/missing_doc_crate.rs +++ b/tests/ui/missing_doc_crate.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::missing_docs_in_private_items)] #![allow(clippy::doc_include_without_cfg)] #![doc = include_str!("../../README.md")] diff --git a/tests/ui/missing_doc_crate_missing.rs b/tests/ui/missing_doc_crate_missing.rs index 73584ac8c67d..70e96f4dd547 100644 --- a/tests/ui/missing_doc_crate_missing.rs +++ b/tests/ui/missing_doc_crate_missing.rs @@ -1,5 +1,6 @@ #![warn(clippy::missing_docs_in_private_items)] -//~^ ERROR: missing documentation for the crate -//~| NOTE: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` +//~^ missing_docs_in_private_items + + fn main() {} diff --git a/tests/ui/missing_doc_impl.rs b/tests/ui/missing_doc_impl.rs index 520ddbe16b82..e2d268c4e3bd 100644 --- a/tests/ui/missing_doc_impl.rs +++ b/tests/ui/missing_doc_impl.rs @@ -11,13 +11,17 @@ extern crate proc_macros; use proc_macros::with_span; struct Foo { +//~^ missing_docs_in_private_items a: isize, + //~^ missing_docs_in_private_items b: isize, + //~^ missing_docs_in_private_items } pub struct PubFoo { pub a: isize, b: isize, + //~^ missing_docs_in_private_items } #[allow(clippy::missing_docs_in_private_items)] @@ -65,9 +69,11 @@ pub trait E: Sized { impl Foo { pub fn new() -> Self { + //~^ missing_docs_in_private_items Foo { a: 0, b: 0 } } fn bar() {} + //~^ missing_docs_in_private_items } impl PubFoo { @@ -76,6 +82,7 @@ impl PubFoo { pub fn foo1() {} #[must_use = "yep"] fn foo2() -> u32 { + //~^ missing_docs_in_private_items 1 } #[allow(clippy::missing_docs_in_private_items)] diff --git a/tests/ui/missing_doc_impl.stderr b/tests/ui/missing_doc_impl.stderr index e2052c346df8..999ff06f593e 100644 --- a/tests/ui/missing_doc_impl.stderr +++ b/tests/ui/missing_doc_impl.stderr @@ -2,8 +2,9 @@ error: missing documentation for a struct --> tests/ui/missing_doc_impl.rs:13:1 | LL | / struct Foo { +LL | | LL | | a: isize, -LL | | b: isize, +... | LL | | } | |_^ | @@ -11,41 +12,43 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` error: missing documentation for a struct field - --> tests/ui/missing_doc_impl.rs:14:5 + --> tests/ui/missing_doc_impl.rs:15:5 | LL | a: isize, | ^^^^^^^^ error: missing documentation for a struct field - --> tests/ui/missing_doc_impl.rs:15:5 + --> tests/ui/missing_doc_impl.rs:17:5 | LL | b: isize, | ^^^^^^^^ error: missing documentation for a struct field - --> tests/ui/missing_doc_impl.rs:20:5 + --> tests/ui/missing_doc_impl.rs:23:5 | LL | b: isize, | ^^^^^^^^ error: missing documentation for an associated function - --> tests/ui/missing_doc_impl.rs:67:5 + --> tests/ui/missing_doc_impl.rs:71:5 | LL | / pub fn new() -> Self { +LL | | LL | | Foo { a: 0, b: 0 } LL | | } | |_____^ error: missing documentation for an associated function - --> tests/ui/missing_doc_impl.rs:70:5 + --> tests/ui/missing_doc_impl.rs:75:5 | LL | fn bar() {} | ^^^^^^^^^^^ error: missing documentation for an associated function - --> tests/ui/missing_doc_impl.rs:78:5 + --> tests/ui/missing_doc_impl.rs:84:5 | LL | / fn foo2() -> u32 { +LL | | LL | | 1 LL | | } | |_____^ diff --git a/tests/ui/missing_fields_in_debug.rs b/tests/ui/missing_fields_in_debug.rs index 68867ec819d1..bf69eae05169 100644 --- a/tests/ui/missing_fields_in_debug.rs +++ b/tests/ui/missing_fields_in_debug.rs @@ -12,7 +12,8 @@ struct NamedStruct1Ignored { } impl fmt::Debug for NamedStruct1Ignored { - //~^ ERROR: manual `Debug` impl does not include all fields +//~^ missing_fields_in_debug + // unused field: hidden fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter @@ -31,7 +32,8 @@ struct NamedStructMultipleIgnored { } impl fmt::Debug for NamedStructMultipleIgnored { - //~^ ERROR: manual `Debug` impl does not include all fields +//~^ missing_fields_in_debug + // unused fields: hidden, hidden2, hidden4 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter @@ -93,7 +95,8 @@ struct MultiExprDebugImpl { // ok impl fmt::Debug for MultiExprDebugImpl { - //~^ ERROR: manual `Debug` impl does not include all fields +//~^ missing_fields_in_debug + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { let mut f = formatter.debug_struct("MultiExprDebugImpl"); f.field("a", &self.a); diff --git a/tests/ui/missing_fields_in_debug.stderr b/tests/ui/missing_fields_in_debug.stderr index 5e51194c4b37..75b551e1f5c7 100644 --- a/tests/ui/missing_fields_in_debug.stderr +++ b/tests/ui/missing_fields_in_debug.stderr @@ -2,9 +2,6 @@ error: manual `Debug` impl does not include all fields --> tests/ui/missing_fields_in_debug.rs:14:1 | LL | / impl fmt::Debug for NamedStruct1Ignored { -LL | | -LL | | // unused field: hidden -LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { ... | LL | | } | |_^ @@ -20,28 +17,25 @@ LL | hidden: u32, = help: to override `-D warnings` add `#[allow(clippy::missing_fields_in_debug)]` error: manual `Debug` impl does not include all fields - --> tests/ui/missing_fields_in_debug.rs:33:1 + --> tests/ui/missing_fields_in_debug.rs:34:1 | LL | / impl fmt::Debug for NamedStructMultipleIgnored { -LL | | -LL | | // unused fields: hidden, hidden2, hidden4 -LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { ... | LL | | } | |_^ | note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:27:5 + --> tests/ui/missing_fields_in_debug.rs:28:5 | LL | hidden: u32, | ^^^^^^^^^^^ note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:28:5 + --> tests/ui/missing_fields_in_debug.rs:29:5 | LL | hidden2: String, | ^^^^^^^^^^^^^^^ note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:30:5 + --> tests/ui/missing_fields_in_debug.rs:31:5 | LL | hidden4: ((((u8), u16), u32), u64), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,18 +43,18 @@ LL | hidden4: ((((u8), u16), u32), u64), = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields error: manual `Debug` impl does not include all fields - --> tests/ui/missing_fields_in_debug.rs:95:1 + --> tests/ui/missing_fields_in_debug.rs:97:1 | LL | / impl fmt::Debug for MultiExprDebugImpl { LL | | +LL | | LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { -LL | | let mut f = formatter.debug_struct("MultiExprDebugImpl"); ... | LL | | } | |_^ | note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:91:5 + --> tests/ui/missing_fields_in_debug.rs:93:5 | LL | b: String, | ^^^^^^^^^ diff --git a/tests/ui/missing_inline.rs b/tests/ui/missing_inline.rs index dca85b94d5ee..ec21de4ca41c 100644 --- a/tests/ui/missing_inline.rs +++ b/tests/ui/missing_inline.rs @@ -18,8 +18,9 @@ pub mod pub_module {} // ok fn foo() {} // missing #[inline] pub fn pub_foo() {} -//~^ ERROR: missing `#[inline]` for a function -//~| NOTE: `-D clippy::missing-inline-in-public-items` implied by `-D warnings` +//~^ missing_inline_in_public_items + + #[inline] pub fn pub_foo_inline() {} // ok #[inline(always)] @@ -37,7 +38,8 @@ pub trait PubBar { fn PubBar_a(); // ok // missing #[inline] fn PubBar_b() {} - //~^ ERROR: missing `#[inline]` for a default trait method + //~^ missing_inline_in_public_items + #[inline] fn PubBar_c() {} // ok } @@ -53,13 +55,16 @@ impl PubBar for Foo { impl PubBar for PubFoo { // missing #[inline] fn PubBar_a() {} - //~^ ERROR: missing `#[inline]` for a method + //~^ missing_inline_in_public_items + // missing #[inline] fn PubBar_b() {} - //~^ ERROR: missing `#[inline]` for a method + //~^ missing_inline_in_public_items + // missing #[inline] fn PubBar_c() {} - //~^ ERROR: missing `#[inline]` for a method + //~^ missing_inline_in_public_items + } // do not need inline because Foo is not exported @@ -71,7 +76,8 @@ impl Foo { impl PubFoo { // missing #[inline] pub fn PubFooImpl() {} - //~^ ERROR: missing `#[inline]` for a method + //~^ missing_inline_in_public_items + } // do not lint this since users cannot control the external code diff --git a/tests/ui/missing_inline.stderr b/tests/ui/missing_inline.stderr index c2bb37141a02..2ce335a696ce 100644 --- a/tests/ui/missing_inline.stderr +++ b/tests/ui/missing_inline.stderr @@ -8,31 +8,31 @@ LL | pub fn pub_foo() {} = help: to override `-D warnings` add `#[allow(clippy::missing_inline_in_public_items)]` error: missing `#[inline]` for a default trait method - --> tests/ui/missing_inline.rs:39:5 + --> tests/ui/missing_inline.rs:40:5 | LL | fn PubBar_b() {} | ^^^^^^^^^^^^^^^^ error: missing `#[inline]` for a method - --> tests/ui/missing_inline.rs:55:5 + --> tests/ui/missing_inline.rs:57:5 | LL | fn PubBar_a() {} | ^^^^^^^^^^^^^^^^ error: missing `#[inline]` for a method - --> tests/ui/missing_inline.rs:58:5 + --> tests/ui/missing_inline.rs:61:5 | LL | fn PubBar_b() {} | ^^^^^^^^^^^^^^^^ error: missing `#[inline]` for a method - --> tests/ui/missing_inline.rs:61:5 + --> tests/ui/missing_inline.rs:65:5 | LL | fn PubBar_c() {} | ^^^^^^^^^^^^^^^^ error: missing `#[inline]` for a method - --> tests/ui/missing_inline.rs:73:5 + --> tests/ui/missing_inline.rs:78:5 | LL | pub fn PubFooImpl() {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/missing_inline_executable.rs b/tests/ui/missing_inline_executable.rs index 6e0400ac935b..444a7f1c964f 100644 --- a/tests/ui/missing_inline_executable.rs +++ b/tests/ui/missing_inline_executable.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::missing_inline_in_public_items)] pub fn foo() {} diff --git a/tests/ui/missing_inline_proc_macro.rs b/tests/ui/missing_inline_proc_macro.rs index e47a198c6aea..ce368304f725 100644 --- a/tests/ui/missing_inline_proc_macro.rs +++ b/tests/ui/missing_inline_proc_macro.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::missing_inline_in_public_items)] extern crate proc_macro; diff --git a/tests/ui/missing_panics_doc.rs b/tests/ui/missing_panics_doc.rs index b0fa8e988598..f8aeffb3d041 100644 --- a/tests/ui/missing_panics_doc.rs +++ b/tests/ui/missing_panics_doc.rs @@ -11,17 +11,20 @@ fn main() {} /// This needs to be documented pub fn unwrap() { +//~^ missing_panics_doc let result = Err("Hi"); result.unwrap() } /// This needs to be documented pub fn panic() { +//~^ missing_panics_doc panic!("This function panics") } /// This needs to be documented pub fn inner_body(opt: Option) { +//~^ missing_panics_doc opt.map(|x| { if x == 10 { panic!() @@ -31,17 +34,20 @@ pub fn inner_body(opt: Option) { /// This needs to be documented pub fn unreachable_and_panic() { +//~^ missing_panics_doc if true { unreachable!() } else { panic!() } } /// This needs to be documented pub fn assert_eq() { +//~^ missing_panics_doc let x = 0; assert_eq!(x, 0); } /// This needs to be documented pub fn assert_ne() { +//~^ missing_panics_doc let x = 0; assert_ne!(x, 0); } @@ -149,30 +155,36 @@ pub fn debug_assertions() { // `pub` is required, because the lint does not consider unreachable items pub mod issue10240 { pub fn option_unwrap(v: &[T]) -> &T { + //~^ missing_panics_doc let o: Option<&T> = v.last(); o.unwrap() } pub fn option_expect(v: &[T]) -> &T { + //~^ missing_panics_doc let o: Option<&T> = v.last(); o.expect("passed an empty thing") } pub fn result_unwrap(v: &[T]) -> &T { + //~^ missing_panics_doc let res: Result<&T, &str> = v.last().ok_or("oh noes"); res.unwrap() } pub fn result_expect(v: &[T]) -> &T { + //~^ missing_panics_doc let res: Result<&T, &str> = v.last().ok_or("oh noes"); res.expect("passed an empty thing") } pub fn last_unwrap(v: &[u32]) -> u32 { + //~^ missing_panics_doc *v.last().unwrap() } pub fn last_expect(v: &[u32]) -> u32 { + //~^ missing_panics_doc *v.last().expect("passed an empty thing") } } diff --git a/tests/ui/missing_panics_doc.stderr b/tests/ui/missing_panics_doc.stderr index c6a939d86f7c..a83e2fa367dd 100644 --- a/tests/ui/missing_panics_doc.stderr +++ b/tests/ui/missing_panics_doc.stderr @@ -5,7 +5,7 @@ LL | pub fn unwrap() { | ^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:15:5 + --> tests/ui/missing_panics_doc.rs:16:5 | LL | result.unwrap() | ^^^^^^^^^^^^^^^ @@ -13,133 +13,133 @@ LL | result.unwrap() = help: to override `-D warnings` add `#[allow(clippy::missing_panics_doc)]` error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:19:1 + --> tests/ui/missing_panics_doc.rs:20:1 | LL | pub fn panic() { | ^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:20:5 + --> tests/ui/missing_panics_doc.rs:22:5 | LL | panic!("This function panics") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:24:1 + --> tests/ui/missing_panics_doc.rs:26:1 | LL | pub fn inner_body(opt: Option) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:27:13 + --> tests/ui/missing_panics_doc.rs:30:13 | LL | panic!() | ^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:33:1 + --> tests/ui/missing_panics_doc.rs:36:1 | LL | pub fn unreachable_and_panic() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:34:39 + --> tests/ui/missing_panics_doc.rs:38:39 | LL | if true { unreachable!() } else { panic!() } | ^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:38:1 + --> tests/ui/missing_panics_doc.rs:42:1 | LL | pub fn assert_eq() { | ^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:40:5 + --> tests/ui/missing_panics_doc.rs:45:5 | LL | assert_eq!(x, 0); | ^^^^^^^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:44:1 + --> tests/ui/missing_panics_doc.rs:49:1 | LL | pub fn assert_ne() { | ^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:46:5 + --> tests/ui/missing_panics_doc.rs:52:5 | LL | assert_ne!(x, 0); | ^^^^^^^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:151:5 + --> tests/ui/missing_panics_doc.rs:157:5 | LL | pub fn option_unwrap(v: &[T]) -> &T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:153:9 + --> tests/ui/missing_panics_doc.rs:160:9 | LL | o.unwrap() | ^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:156:5 + --> tests/ui/missing_panics_doc.rs:163:5 | LL | pub fn option_expect(v: &[T]) -> &T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:158:9 + --> tests/ui/missing_panics_doc.rs:166:9 | LL | o.expect("passed an empty thing") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:161:5 + --> tests/ui/missing_panics_doc.rs:169:5 | LL | pub fn result_unwrap(v: &[T]) -> &T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:163:9 + --> tests/ui/missing_panics_doc.rs:172:9 | LL | res.unwrap() | ^^^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:166:5 + --> tests/ui/missing_panics_doc.rs:175:5 | LL | pub fn result_expect(v: &[T]) -> &T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:168:9 + --> tests/ui/missing_panics_doc.rs:178:9 | LL | res.expect("passed an empty thing") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:171:5 + --> tests/ui/missing_panics_doc.rs:181:5 | LL | pub fn last_unwrap(v: &[u32]) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:172:10 + --> tests/ui/missing_panics_doc.rs:183:10 | LL | *v.last().unwrap() | ^^^^^^^^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> tests/ui/missing_panics_doc.rs:175:5 + --> tests/ui/missing_panics_doc.rs:186:5 | LL | pub fn last_expect(v: &[u32]) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> tests/ui/missing_panics_doc.rs:176:10 + --> tests/ui/missing_panics_doc.rs:188:10 | LL | *v.last().expect("passed an empty thing") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/missing_spin_loop.fixed b/tests/ui/missing_spin_loop.fixed index b6520d478be8..03fbf8ccc8a3 100644 --- a/tests/ui/missing_spin_loop.fixed +++ b/tests/ui/missing_spin_loop.fixed @@ -8,16 +8,22 @@ fn main() { let b = AtomicBool::new(true); // Those should lint while b.load(Ordering::Acquire) { std::hint::spin_loop() } + //~^ missing_spin_loop while !b.load(Ordering::SeqCst) { std::hint::spin_loop() } + //~^ missing_spin_loop while b.load(Ordering::Acquire) == false { std::hint::spin_loop() } + //~^ missing_spin_loop while { true == b.load(Ordering::Acquire) } { std::hint::spin_loop() } + //~^ missing_spin_loop while b.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed) != Ok(true) { std::hint::spin_loop() } + //~^ missing_spin_loop while Ok(false) != b.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) { std::hint::spin_loop() } + //~^ missing_spin_loop // This is OK, as the body is not empty while b.load(Ordering::Acquire) { diff --git a/tests/ui/missing_spin_loop.rs b/tests/ui/missing_spin_loop.rs index 7b115c66ade6..bf18590b9408 100644 --- a/tests/ui/missing_spin_loop.rs +++ b/tests/ui/missing_spin_loop.rs @@ -8,16 +8,22 @@ fn main() { let b = AtomicBool::new(true); // Those should lint while b.load(Ordering::Acquire) {} + //~^ missing_spin_loop while !b.load(Ordering::SeqCst) {} + //~^ missing_spin_loop while b.load(Ordering::Acquire) == false {} + //~^ missing_spin_loop while { true == b.load(Ordering::Acquire) } {} + //~^ missing_spin_loop while b.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed) != Ok(true) {} + //~^ missing_spin_loop while Ok(false) != b.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) {} + //~^ missing_spin_loop // This is OK, as the body is not empty while b.load(Ordering::Acquire) { diff --git a/tests/ui/missing_spin_loop.stderr b/tests/ui/missing_spin_loop.stderr index 12f4b53a3d18..98c32d042346 100644 --- a/tests/ui/missing_spin_loop.stderr +++ b/tests/ui/missing_spin_loop.stderr @@ -8,31 +8,31 @@ LL | while b.load(Ordering::Acquire) {} = help: to override `-D warnings` add `#[allow(clippy::missing_spin_loop)]` error: busy-waiting loop should at least have a spin loop hint - --> tests/ui/missing_spin_loop.rs:12:37 + --> tests/ui/missing_spin_loop.rs:13:37 | LL | while !b.load(Ordering::SeqCst) {} | ^^ help: try: `{ std::hint::spin_loop() }` error: busy-waiting loop should at least have a spin loop hint - --> tests/ui/missing_spin_loop.rs:14:46 + --> tests/ui/missing_spin_loop.rs:16:46 | LL | while b.load(Ordering::Acquire) == false {} | ^^ help: try: `{ std::hint::spin_loop() }` error: busy-waiting loop should at least have a spin loop hint - --> tests/ui/missing_spin_loop.rs:16:49 + --> tests/ui/missing_spin_loop.rs:19:49 | LL | while { true == b.load(Ordering::Acquire) } {} | ^^ help: try: `{ std::hint::spin_loop() }` error: busy-waiting loop should at least have a spin loop hint - --> tests/ui/missing_spin_loop.rs:18:93 + --> tests/ui/missing_spin_loop.rs:22:93 | LL | while b.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed) != Ok(true) {} | ^^ help: try: `{ std::hint::spin_loop() }` error: busy-waiting loop should at least have a spin loop hint - --> tests/ui/missing_spin_loop.rs:20:94 + --> tests/ui/missing_spin_loop.rs:25:94 | LL | while Ok(false) != b.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) {} | ^^ help: try: `{ std::hint::spin_loop() }` diff --git a/tests/ui/missing_spin_loop_no_std.fixed b/tests/ui/missing_spin_loop_no_std.fixed index 771ab1ab21a8..a525d414670e 100644 --- a/tests/ui/missing_spin_loop_no_std.fixed +++ b/tests/ui/missing_spin_loop_no_std.fixed @@ -9,5 +9,6 @@ pub fn main(_argc: isize, _argv: *const *const u8) -> isize { let b = AtomicBool::new(true); // This should lint with `core::hint::spin_loop()` while b.load(Ordering::Acquire) { core::hint::spin_loop() } + //~^ missing_spin_loop 0 } diff --git a/tests/ui/missing_spin_loop_no_std.rs b/tests/ui/missing_spin_loop_no_std.rs index bf890fc4066b..3b421f32c34f 100644 --- a/tests/ui/missing_spin_loop_no_std.rs +++ b/tests/ui/missing_spin_loop_no_std.rs @@ -9,5 +9,6 @@ pub fn main(_argc: isize, _argv: *const *const u8) -> isize { let b = AtomicBool::new(true); // This should lint with `core::hint::spin_loop()` while b.load(Ordering::Acquire) {} + //~^ missing_spin_loop 0 } diff --git a/tests/ui/missing_trait_methods.rs b/tests/ui/missing_trait_methods.rs index 55b904bde59a..bcca5e1ae5bd 100644 --- a/tests/ui/missing_trait_methods.rs +++ b/tests/ui/missing_trait_methods.rs @@ -20,10 +20,12 @@ trait B { struct Partial; impl A for Partial {} -//~^ ERROR: missing trait method provided by default: `provided` +//~^ missing_trait_methods + impl B for Partial { - //~^ ERROR: missing trait method provided by default: `b` +//~^ missing_trait_methods + fn required() {} fn a(_: usize) -> usize { @@ -56,5 +58,8 @@ trait MissingMultiple { } impl MissingMultiple for Partial {} +//~^ missing_trait_methods +//~| missing_trait_methods +//~| missing_trait_methods fn main() {} diff --git a/tests/ui/missing_trait_methods.stderr b/tests/ui/missing_trait_methods.stderr index 9c4968b022d7..4af7b9ae1ea9 100644 --- a/tests/ui/missing_trait_methods.stderr +++ b/tests/ui/missing_trait_methods.stderr @@ -13,7 +13,7 @@ LL | fn provided() {} = help: to override `-D warnings` add `#[allow(clippy::missing_trait_methods)]` error: missing trait method provided by default: `b` - --> tests/ui/missing_trait_methods.rs:25:1 + --> tests/ui/missing_trait_methods.rs:26:1 | LL | impl B for Partial { | ^^^^^^^^^^^^^^^^^^ @@ -25,31 +25,7 @@ LL | fn b<'a, T: AsRef<[u8]>>(a: &'a T) -> &'a [u8] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing trait method provided by default: `one` - --> tests/ui/missing_trait_methods.rs:58:1 - | -LL | impl MissingMultiple for Partial {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: implement the method - --> tests/ui/missing_trait_methods.rs:53:5 - | -LL | fn one() {} - | ^^^^^^^^ - -error: missing trait method provided by default: `two` - --> tests/ui/missing_trait_methods.rs:58:1 - | -LL | impl MissingMultiple for Partial {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: implement the method - --> tests/ui/missing_trait_methods.rs:54:5 - | -LL | fn two() {} - | ^^^^^^^^ - -error: missing trait method provided by default: `three` - --> tests/ui/missing_trait_methods.rs:58:1 + --> tests/ui/missing_trait_methods.rs:60:1 | LL | impl MissingMultiple for Partial {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,6 +33,30 @@ LL | impl MissingMultiple for Partial {} help: implement the method --> tests/ui/missing_trait_methods.rs:55:5 | +LL | fn one() {} + | ^^^^^^^^ + +error: missing trait method provided by default: `two` + --> tests/ui/missing_trait_methods.rs:60:1 + | +LL | impl MissingMultiple for Partial {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: implement the method + --> tests/ui/missing_trait_methods.rs:56:5 + | +LL | fn two() {} + | ^^^^^^^^ + +error: missing trait method provided by default: `three` + --> tests/ui/missing_trait_methods.rs:60:1 + | +LL | impl MissingMultiple for Partial {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: implement the method + --> tests/ui/missing_trait_methods.rs:57:5 + | LL | fn three() {} | ^^^^^^^^^^ diff --git a/tests/ui/mistyped_literal_suffix.fixed b/tests/ui/mistyped_literal_suffix.fixed index b84b3dc349ec..50ef32e47c03 100644 --- a/tests/ui/mistyped_literal_suffix.fixed +++ b/tests/ui/mistyped_literal_suffix.fixed @@ -14,35 +14,51 @@ use proc_macros::with_span; fn main() { let fail14 = 2_i32; + //~^ mistyped_literal_suffixes let fail15 = 4_i64; + //~^ mistyped_literal_suffixes let fail16 = 7_i8; // + //~^ mistyped_literal_suffixes let fail17 = 23_i16; // + //~^ mistyped_literal_suffixes let ok18 = 23_128; let fail20 = 2_i8; // + //~^ mistyped_literal_suffixes let fail21 = 4_i16; // + //~^ mistyped_literal_suffixes let ok24 = 12.34_64; let fail25 = 1E2_f32; + //~^ mistyped_literal_suffixes let fail26 = 43E7_f64; + //~^ mistyped_literal_suffixes let fail27 = 243E17_f32; + //~^ mistyped_literal_suffixes let fail28 = 241_251_235E723_f64; + //~^ mistyped_literal_suffixes let ok29 = 42279.911_32; // testing that the suggestion actually fits in its type let fail30 = 127_i8; // should be i8 + //~^ mistyped_literal_suffixes let fail31 = 240_u8; // should be u8 + //~^ mistyped_literal_suffixes let ok32 = 360_8; // doesn't fit in either, should be ignored let fail33 = 0x1234_i16; + //~^ mistyped_literal_suffixes let fail34 = 0xABCD_u16; + //~^ mistyped_literal_suffixes let ok35 = 0x12345_16; let fail36 = 0xFFFF_FFFF_FFFF_FFFF_u64; // u64 + //~^ mistyped_literal_suffixes // issue #6129 let ok37 = 123_32.123; let ok38 = 124_64.0; let _ = 1.123_45E1_f32; + //~^ mistyped_literal_suffixes let _ = with_span!(1 2_u32); } diff --git a/tests/ui/mistyped_literal_suffix.rs b/tests/ui/mistyped_literal_suffix.rs index a47a736067a8..92f827608b10 100644 --- a/tests/ui/mistyped_literal_suffix.rs +++ b/tests/ui/mistyped_literal_suffix.rs @@ -14,35 +14,51 @@ use proc_macros::with_span; fn main() { let fail14 = 2_32; + //~^ mistyped_literal_suffixes let fail15 = 4_64; + //~^ mistyped_literal_suffixes let fail16 = 7_8; // + //~^ mistyped_literal_suffixes let fail17 = 23_16; // + //~^ mistyped_literal_suffixes let ok18 = 23_128; let fail20 = 2__8; // + //~^ mistyped_literal_suffixes let fail21 = 4___16; // + //~^ mistyped_literal_suffixes let ok24 = 12.34_64; let fail25 = 1E2_32; + //~^ mistyped_literal_suffixes let fail26 = 43E7_64; + //~^ mistyped_literal_suffixes let fail27 = 243E17_32; + //~^ mistyped_literal_suffixes let fail28 = 241251235E723_64; + //~^ mistyped_literal_suffixes let ok29 = 42279.911_32; // testing that the suggestion actually fits in its type let fail30 = 127_8; // should be i8 + //~^ mistyped_literal_suffixes let fail31 = 240_8; // should be u8 + //~^ mistyped_literal_suffixes let ok32 = 360_8; // doesn't fit in either, should be ignored let fail33 = 0x1234_16; + //~^ mistyped_literal_suffixes let fail34 = 0xABCD_16; + //~^ mistyped_literal_suffixes let ok35 = 0x12345_16; let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64 + //~^ mistyped_literal_suffixes // issue #6129 let ok37 = 123_32.123; let ok38 = 124_64.0; let _ = 1.12345E1_32; + //~^ mistyped_literal_suffixes let _ = with_span!(1 2_u32); } diff --git a/tests/ui/mistyped_literal_suffix.stderr b/tests/ui/mistyped_literal_suffix.stderr index 56bfb06d8e66..2fb3012b84f6 100644 --- a/tests/ui/mistyped_literal_suffix.stderr +++ b/tests/ui/mistyped_literal_suffix.stderr @@ -7,91 +7,91 @@ LL | let fail14 = 2_32; = note: `#[deny(clippy::mistyped_literal_suffixes)]` on by default error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:17:18 + --> tests/ui/mistyped_literal_suffix.rs:18:18 | LL | let fail15 = 4_64; | ^^^^ help: did you mean to write: `4_i64` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:18:18 + --> tests/ui/mistyped_literal_suffix.rs:20:18 | LL | let fail16 = 7_8; // | ^^^ help: did you mean to write: `7_i8` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:19:18 + --> tests/ui/mistyped_literal_suffix.rs:22:18 | LL | let fail17 = 23_16; // | ^^^^^ help: did you mean to write: `23_i16` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:22:18 + --> tests/ui/mistyped_literal_suffix.rs:26:18 | LL | let fail20 = 2__8; // | ^^^^ help: did you mean to write: `2_i8` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:23:18 + --> tests/ui/mistyped_literal_suffix.rs:28:18 | LL | let fail21 = 4___16; // | ^^^^^^ help: did you mean to write: `4_i16` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:26:18 + --> tests/ui/mistyped_literal_suffix.rs:32:18 | LL | let fail25 = 1E2_32; | ^^^^^^ help: did you mean to write: `1E2_f32` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:27:18 + --> tests/ui/mistyped_literal_suffix.rs:34:18 | LL | let fail26 = 43E7_64; | ^^^^^^^ help: did you mean to write: `43E7_f64` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:28:18 + --> tests/ui/mistyped_literal_suffix.rs:36:18 | LL | let fail27 = 243E17_32; | ^^^^^^^^^ help: did you mean to write: `243E17_f32` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:29:18 + --> tests/ui/mistyped_literal_suffix.rs:38:18 | LL | let fail28 = 241251235E723_64; | ^^^^^^^^^^^^^^^^ help: did you mean to write: `241_251_235E723_f64` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:33:18 + --> tests/ui/mistyped_literal_suffix.rs:43:18 | LL | let fail30 = 127_8; // should be i8 | ^^^^^ help: did you mean to write: `127_i8` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:34:18 + --> tests/ui/mistyped_literal_suffix.rs:45:18 | LL | let fail31 = 240_8; // should be u8 | ^^^^^ help: did you mean to write: `240_u8` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:36:18 + --> tests/ui/mistyped_literal_suffix.rs:48:18 | LL | let fail33 = 0x1234_16; | ^^^^^^^^^ help: did you mean to write: `0x1234_i16` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:37:18 + --> tests/ui/mistyped_literal_suffix.rs:50:18 | LL | let fail34 = 0xABCD_16; | ^^^^^^^^^ help: did you mean to write: `0xABCD_u16` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:39:18 + --> tests/ui/mistyped_literal_suffix.rs:53:18 | LL | let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64 | ^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `0xFFFF_FFFF_FFFF_FFFF_u64` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:45:13 + --> tests/ui/mistyped_literal_suffix.rs:60:13 | LL | let _ = 1.12345E1_32; | ^^^^^^^^^^^^ help: did you mean to write: `1.123_45E1_f32` diff --git a/tests/ui/mixed_attributes_style/auxiliary/submodule.rs b/tests/ui/mixed_attributes_style/auxiliary/submodule.rs index df44b07a6941..61615c5d3a64 100644 --- a/tests/ui/mixed_attributes_style/auxiliary/submodule.rs +++ b/tests/ui/mixed_attributes_style/auxiliary/submodule.rs @@ -3,7 +3,8 @@ #![allow(dead_code)] #[allow(unused)] -//~^ ERROR: item has both inner and outer attributes +//~^ mixed_attributes_style + mod foo { #![allow(dead_code)] } diff --git a/tests/ui/mixed_attributes_style/global_allow.rs b/tests/ui/mixed_attributes_style/global_allow.rs index 153262e65570..c68a5462afea 100644 --- a/tests/ui/mixed_attributes_style/global_allow.rs +++ b/tests/ui/mixed_attributes_style/global_allow.rs @@ -1,3 +1,5 @@ +//@error-in-other-file: +//@no-rustfix // issue 12436 #![allow(clippy::mixed_attributes_style)] diff --git a/tests/ui/mixed_attributes_style/mod_declaration.rs b/tests/ui/mixed_attributes_style/mod_declaration.rs index b0f1f0bda9e6..f2aad9a21e99 100644 --- a/tests/ui/mixed_attributes_style/mod_declaration.rs +++ b/tests/ui/mixed_attributes_style/mod_declaration.rs @@ -1,3 +1,6 @@ +//@error-in-other-file: empty line after outer attribute +//@error-in-other-file: item has both inner and outer attributes +//@no-rustfix #[path = "auxiliary/submodule.rs"] // don't lint. /// This doc comment should not lint, it could be used to add context to the original module doc mod submodule; diff --git a/tests/ui/mixed_attributes_style/mod_declaration.stderr b/tests/ui/mixed_attributes_style/mod_declaration.stderr index 968c537c7e44..13ec97fbc1af 100644 --- a/tests/ui/mixed_attributes_style/mod_declaration.stderr +++ b/tests/ui/mixed_attributes_style/mod_declaration.stderr @@ -3,6 +3,7 @@ error: item has both inner and outer attributes | LL | / #[allow(unused)] LL | | +LL | | LL | | mod foo { LL | | #![allow(dead_code)] | |________________________^ @@ -10,5 +11,23 @@ LL | | #![allow(dead_code)] = note: `-D clippy::mixed-attributes-style` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::mixed_attributes_style)]` -error: aborting due to 1 previous error +error: empty line after outer attribute + --> tests/ui/mixed_attributes_style/auxiliary/submodule.rs:5:1 + | +LL | / #[allow(unused)] +LL | | +LL | | + | |_^ +LL | mod foo { + | ------- the attribute applies to this module + | + = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]` + = help: if the empty line is unintentional remove it +help: if the attribute should apply to the parent module use an inner attribute + | +LL | #![allow(unused)] + | + + +error: aborting due to 2 previous errors diff --git a/tests/ui/mixed_read_write_in_expression.rs b/tests/ui/mixed_read_write_in_expression.rs index 241536abdfbd..cff7996243bb 100644 --- a/tests/ui/mixed_read_write_in_expression.rs +++ b/tests/ui/mixed_read_write_in_expression.rs @@ -12,11 +12,13 @@ fn main() { x = 1; 1 } + x; - //~^ ERROR: unsequenced read of `x` + //~^ mixed_read_write_in_expression + // Example from iss#277 x += { - //~^ ERROR: unsequenced read of `x` + //~^ mixed_read_write_in_expression + x = 20; 2 }; @@ -30,7 +32,8 @@ fn main() { let base = Foo { a: 4, b: 5 }; let foo = Foo { a: x, - //~^ ERROR: unsequenced read of `x` + //~^ mixed_read_write_in_expression + ..{ x = 6; base @@ -40,7 +43,8 @@ fn main() { let closure = || { let mut x = 0; x += { - //~^ ERROR: unsequenced read of `x` + //~^ mixed_read_write_in_expression + x = 20; 2 }; diff --git a/tests/ui/mixed_read_write_in_expression.stderr b/tests/ui/mixed_read_write_in_expression.stderr index 796d4ccd26b7..ebb3e691e6b7 100644 --- a/tests/ui/mixed_read_write_in_expression.stderr +++ b/tests/ui/mixed_read_write_in_expression.stderr @@ -13,37 +13,37 @@ LL | x = 1; = help: to override `-D warnings` add `#[allow(clippy::mixed_read_write_in_expression)]` error: unsequenced read of `x` - --> tests/ui/mixed_read_write_in_expression.rs:18:5 + --> tests/ui/mixed_read_write_in_expression.rs:19:5 | LL | x += { | ^ | note: whether read occurs before this write depends on evaluation order - --> tests/ui/mixed_read_write_in_expression.rs:20:9 + --> tests/ui/mixed_read_write_in_expression.rs:22:9 | LL | x = 20; | ^^^^^^ error: unsequenced read of `x` - --> tests/ui/mixed_read_write_in_expression.rs:32:12 + --> tests/ui/mixed_read_write_in_expression.rs:34:12 | LL | a: x, | ^ | note: whether read occurs before this write depends on evaluation order - --> tests/ui/mixed_read_write_in_expression.rs:35:13 + --> tests/ui/mixed_read_write_in_expression.rs:38:13 | LL | x = 6; | ^^^^^ error: unsequenced read of `x` - --> tests/ui/mixed_read_write_in_expression.rs:42:9 + --> tests/ui/mixed_read_write_in_expression.rs:45:9 | LL | x += { | ^ | note: whether read occurs before this write depends on evaluation order - --> tests/ui/mixed_read_write_in_expression.rs:44:13 + --> tests/ui/mixed_read_write_in_expression.rs:48:13 | LL | x = 20; | ^^^^^^ diff --git a/tests/ui/module_inception.rs b/tests/ui/module_inception.rs index ad46e0c29aee..f04f0c5eeeba 100644 --- a/tests/ui/module_inception.rs +++ b/tests/ui/module_inception.rs @@ -3,14 +3,16 @@ pub mod foo2 { pub mod bar2 { pub mod bar2 { - //~^ ERROR: module has the same name as its containing module - //~| NOTE: `-D clippy::module-inception` implied by `-D warnings` + //~^ module_inception + + pub mod foo2 {} } pub mod foo2 {} } pub mod foo2 { - //~^ ERROR: module has the same name as its containing module + //~^ module_inception + pub mod bar2 {} } } @@ -18,13 +20,15 @@ pub mod foo2 { mod foo { mod bar { mod bar { - //~^ ERROR: module has the same name as its containing module + //~^ module_inception + mod foo {} } mod foo {} } mod foo { - //~^ ERROR: module has the same name as its containing module + //~^ module_inception + mod bar {} } } diff --git a/tests/ui/module_inception.stderr b/tests/ui/module_inception.stderr index 455f5372747a..3aaf304ac0e5 100644 --- a/tests/ui/module_inception.stderr +++ b/tests/ui/module_inception.stderr @@ -2,9 +2,7 @@ error: module has the same name as its containing module --> tests/ui/module_inception.rs:5:9 | LL | / pub mod bar2 { -LL | | -LL | | -LL | | pub mod foo2 {} +... | LL | | } | |_________^ | @@ -12,28 +10,31 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::module_inception)]` error: module has the same name as its containing module - --> tests/ui/module_inception.rs:12:5 + --> tests/ui/module_inception.rs:13:5 | LL | / pub mod foo2 { LL | | +LL | | LL | | pub mod bar2 {} LL | | } | |_____^ error: module has the same name as its containing module - --> tests/ui/module_inception.rs:20:9 + --> tests/ui/module_inception.rs:22:9 | LL | / mod bar { LL | | +LL | | LL | | mod foo {} LL | | } | |_________^ error: module has the same name as its containing module - --> tests/ui/module_inception.rs:26:5 + --> tests/ui/module_inception.rs:29:5 | LL | / mod foo { LL | | +LL | | LL | | mod bar {} LL | | } | |_____^ diff --git a/tests/ui/module_name_repetitions.rs b/tests/ui/module_name_repetitions.rs index 71d8ac7a1f0e..b45120a8d10c 100644 --- a/tests/ui/module_name_repetitions.rs +++ b/tests/ui/module_name_repetitions.rs @@ -6,16 +6,21 @@ pub mod foo { pub fn foo() {} pub fn foo_bar() {} - //~^ ERROR: item name starts with its containing module's name - //~| NOTE: `-D clippy::module-name-repetitions` implied by `-D warnings` + //~^ module_name_repetitions + + pub fn bar_foo() {} - //~^ ERROR: item name ends with its containing module's name + //~^ module_name_repetitions + pub struct FooCake; - //~^ ERROR: item name starts with its containing module's name + //~^ module_name_repetitions + pub enum CakeFoo {} - //~^ ERROR: item name ends with its containing module's name + //~^ module_name_repetitions + pub struct Foo7Bar; - //~^ ERROR: item name starts with its containing module's name + //~^ module_name_repetitions + // Should not warn pub struct Foobar; @@ -28,7 +33,8 @@ pub mod foo { pub use error::Error; // ... but should still warn when the item is reexported to create a *public* path with repetition. pub use error::FooError; - //~^ ERROR: item name starts with its containing module's name + //~^ module_name_repetitions + // FIXME: This should also warn because it creates the public path `foo::FooIter`. mod iter { diff --git a/tests/ui/module_name_repetitions.stderr b/tests/ui/module_name_repetitions.stderr index 8fd8b3948753..664a816ae5d1 100644 --- a/tests/ui/module_name_repetitions.stderr +++ b/tests/ui/module_name_repetitions.stderr @@ -8,31 +8,31 @@ LL | pub fn foo_bar() {} = help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]` error: item name ends with its containing module's name - --> tests/ui/module_name_repetitions.rs:11:12 + --> tests/ui/module_name_repetitions.rs:12:12 | LL | pub fn bar_foo() {} | ^^^^^^^ error: item name starts with its containing module's name - --> tests/ui/module_name_repetitions.rs:13:16 + --> tests/ui/module_name_repetitions.rs:15:16 | LL | pub struct FooCake; | ^^^^^^^ error: item name ends with its containing module's name - --> tests/ui/module_name_repetitions.rs:15:14 + --> tests/ui/module_name_repetitions.rs:18:14 | LL | pub enum CakeFoo {} | ^^^^^^^ error: item name starts with its containing module's name - --> tests/ui/module_name_repetitions.rs:17:16 + --> tests/ui/module_name_repetitions.rs:21:16 | LL | pub struct Foo7Bar; | ^^^^^^^ error: item name starts with its containing module's name - --> tests/ui/module_name_repetitions.rs:30:20 + --> tests/ui/module_name_repetitions.rs:35:20 | LL | pub use error::FooError; | ^^^^^^^^ diff --git a/tests/ui/modulo_arithmetic_float.rs b/tests/ui/modulo_arithmetic_float.rs index a5b63bed531b..1b622151bcc2 100644 --- a/tests/ui/modulo_arithmetic_float.rs +++ b/tests/ui/modulo_arithmetic_float.rs @@ -6,67 +6,83 @@ fn main() { // Lint when both sides are const and of the opposite sign -1.6 % 2.1; - //~^ ERROR: you are using modulo operator on constants with different signs: `-1.600 % - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + 1.6 % -2.1; - //~^ ERROR: you are using modulo operator on constants with different signs: `1.600 % - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + (1.1 - 2.3) % (1.1 + 2.3); - //~^ ERROR: you are using modulo operator on constants with different signs: `-1.200 % - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + (1.1 + 2.3) % (1.1 - 2.3); - //~^ ERROR: you are using modulo operator on constants with different signs: `3.400 % - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + // Lint on floating point numbers let a_f16: f16 = -1.6; let mut b_f16: f16 = 2.1; a_f16 % b_f16; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_f16 % a_f16; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_f16 %= a_f16; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + // Lint on floating point numbers let a_f32: f32 = -1.6; let mut b_f32: f32 = 2.1; a_f32 % b_f32; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_f32 % a_f32; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_f32 %= a_f32; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + let a_f64: f64 = -1.6; let mut b_f64: f64 = 2.1; a_f64 % b_f64; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_f64 % a_f64; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_f64 %= a_f64; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + let a_f128: f128 = -1.6; let mut b_f128: f128 = 2.1; a_f128 % b_f128; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_f128 % a_f128; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_f128 %= a_f128; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + // No lint when both sides are const and of the same sign 1.6 % 2.1; diff --git a/tests/ui/modulo_arithmetic_float.stderr b/tests/ui/modulo_arithmetic_float.stderr index 2b4937552bda..9eb9a328664b 100644 --- a/tests/ui/modulo_arithmetic_float.stderr +++ b/tests/ui/modulo_arithmetic_float.stderr @@ -9,7 +9,7 @@ LL | -1.6 % 2.1; = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]` error: you are using modulo operator on constants with different signs: `1.600 % -2.100` - --> tests/ui/modulo_arithmetic_float.rs:11:5 + --> tests/ui/modulo_arithmetic_float.rs:12:5 | LL | 1.6 % -2.1; | ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | 1.6 % -2.1; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on constants with different signs: `-1.200 % 3.400` - --> tests/ui/modulo_arithmetic_float.rs:14:5 + --> tests/ui/modulo_arithmetic_float.rs:16:5 | LL | (1.1 - 2.3) % (1.1 + 2.3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | (1.1 - 2.3) % (1.1 + 2.3); = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on constants with different signs: `3.400 % -1.200` - --> tests/ui/modulo_arithmetic_float.rs:17:5 + --> tests/ui/modulo_arithmetic_float.rs:20:5 | LL | (1.1 + 2.3) % (1.1 - 2.3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | (1.1 + 2.3) % (1.1 - 2.3); = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:24:5 + --> tests/ui/modulo_arithmetic_float.rs:28:5 | LL | a_f16 % b_f16; | ^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | a_f16 % b_f16; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:27:5 + --> tests/ui/modulo_arithmetic_float.rs:32:5 | LL | b_f16 % a_f16; | ^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | b_f16 % a_f16; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:30:5 + --> tests/ui/modulo_arithmetic_float.rs:36:5 | LL | b_f16 %= a_f16; | ^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | b_f16 %= a_f16; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:37:5 + --> tests/ui/modulo_arithmetic_float.rs:44:5 | LL | a_f32 % b_f32; | ^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | a_f32 % b_f32; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:40:5 + --> tests/ui/modulo_arithmetic_float.rs:48:5 | LL | b_f32 % a_f32; | ^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | b_f32 % a_f32; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:43:5 + --> tests/ui/modulo_arithmetic_float.rs:52:5 | LL | b_f32 %= a_f32; | ^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | b_f32 %= a_f32; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:49:5 + --> tests/ui/modulo_arithmetic_float.rs:59:5 | LL | a_f64 % b_f64; | ^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | a_f64 % b_f64; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:52:5 + --> tests/ui/modulo_arithmetic_float.rs:63:5 | LL | b_f64 % a_f64; | ^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | b_f64 % a_f64; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:55:5 + --> tests/ui/modulo_arithmetic_float.rs:67:5 | LL | b_f64 %= a_f64; | ^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | b_f64 %= a_f64; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:61:5 + --> tests/ui/modulo_arithmetic_float.rs:74:5 | LL | a_f128 % b_f128; | ^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | a_f128 % b_f128; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:64:5 + --> tests/ui/modulo_arithmetic_float.rs:78:5 | LL | b_f128 % a_f128; | ^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | b_f128 % a_f128; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:67:5 + --> tests/ui/modulo_arithmetic_float.rs:82:5 | LL | b_f128 %= a_f128; | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/modulo_arithmetic_integral.rs b/tests/ui/modulo_arithmetic_integral.rs index c427b8580e17..e3a6df7c88f3 100644 --- a/tests/ui/modulo_arithmetic_integral.rs +++ b/tests/ui/modulo_arithmetic_integral.rs @@ -6,77 +6,94 @@ fn main() { let a = -1; let mut b = 2; a % b; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b % a; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b %= a; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + let a_i8: i8 = 1; let mut b_i8: i8 = 2; a_i8 % b_i8; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_i8 %= a_i8; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + let a_i16: i16 = 1; let mut b_i16: i16 = 2; a_i16 % b_i16; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_i16 %= a_i16; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + let a_i32: i32 = 1; let mut b_i32: i32 = 2; a_i32 % b_i32; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_i32 %= a_i32; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + let a_i64: i64 = 1; let mut b_i64: i64 = 2; a_i64 % b_i64; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_i64 %= a_i64; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + let a_i128: i128 = 1; let mut b_i128: i128 = 2; a_i128 % b_i128; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_i128 %= a_i128; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + let a_isize: isize = 1; let mut b_isize: isize = 2; a_isize % b_isize; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b_isize %= a_isize; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + let a = 1; let mut b = 2; a % b; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + b %= a; - //~^ ERROR: you are using modulo operator on types that might have different signs - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + // No lint on unsigned integral value let a_u8: u8 = 17; diff --git a/tests/ui/modulo_arithmetic_integral.stderr b/tests/ui/modulo_arithmetic_integral.stderr index f1cfe791a03b..32cf45240c1b 100644 --- a/tests/ui/modulo_arithmetic_integral.stderr +++ b/tests/ui/modulo_arithmetic_integral.stderr @@ -10,7 +10,7 @@ LL | a % b; = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]` error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:11:5 + --> tests/ui/modulo_arithmetic_integral.rs:12:5 | LL | b % a; | ^^^^^ @@ -19,7 +19,7 @@ LL | b % a; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:14:5 + --> tests/ui/modulo_arithmetic_integral.rs:16:5 | LL | b %= a; | ^^^^^^ @@ -28,7 +28,7 @@ LL | b %= a; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:20:5 + --> tests/ui/modulo_arithmetic_integral.rs:23:5 | LL | a_i8 % b_i8; | ^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | a_i8 % b_i8; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:23:5 + --> tests/ui/modulo_arithmetic_integral.rs:27:5 | LL | b_i8 %= a_i8; | ^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | b_i8 %= a_i8; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:29:5 + --> tests/ui/modulo_arithmetic_integral.rs:34:5 | LL | a_i16 % b_i16; | ^^^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | a_i16 % b_i16; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:32:5 + --> tests/ui/modulo_arithmetic_integral.rs:38:5 | LL | b_i16 %= a_i16; | ^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | b_i16 %= a_i16; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:38:5 + --> tests/ui/modulo_arithmetic_integral.rs:45:5 | LL | a_i32 % b_i32; | ^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | a_i32 % b_i32; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:41:5 + --> tests/ui/modulo_arithmetic_integral.rs:49:5 | LL | b_i32 %= a_i32; | ^^^^^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | b_i32 %= a_i32; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:47:5 + --> tests/ui/modulo_arithmetic_integral.rs:56:5 | LL | a_i64 % b_i64; | ^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | a_i64 % b_i64; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:50:5 + --> tests/ui/modulo_arithmetic_integral.rs:60:5 | LL | b_i64 %= a_i64; | ^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | b_i64 %= a_i64; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:56:5 + --> tests/ui/modulo_arithmetic_integral.rs:67:5 | LL | a_i128 % b_i128; | ^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | a_i128 % b_i128; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:59:5 + --> tests/ui/modulo_arithmetic_integral.rs:71:5 | LL | b_i128 %= a_i128; | ^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | b_i128 %= a_i128; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:65:5 + --> tests/ui/modulo_arithmetic_integral.rs:78:5 | LL | a_isize % b_isize; | ^^^^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | a_isize % b_isize; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:68:5 + --> tests/ui/modulo_arithmetic_integral.rs:82:5 | LL | b_isize %= a_isize; | ^^^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | b_isize %= a_isize; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:74:5 + --> tests/ui/modulo_arithmetic_integral.rs:89:5 | LL | a % b; | ^^^^^ @@ -145,7 +145,7 @@ LL | a % b; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:77:5 + --> tests/ui/modulo_arithmetic_integral.rs:93:5 | LL | b %= a; | ^^^^^^ diff --git a/tests/ui/modulo_arithmetic_integral_const.rs b/tests/ui/modulo_arithmetic_integral_const.rs index dbc679a69825..ddcf4b219073 100644 --- a/tests/ui/modulo_arithmetic_integral_const.rs +++ b/tests/ui/modulo_arithmetic_integral_const.rs @@ -9,57 +9,74 @@ fn main() { // Lint when both sides are const and of the opposite sign -1 % 2; - //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + 1 % -2; - //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + (1 - 2) % (1 + 2); - //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 3` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + (1 + 2) % (1 - 2); - //~^ ERROR: you are using modulo operator on constants with different signs: `3 % -1` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + 35 * (7 - 4 * 2) % (-500 * -600); - //~^ ERROR: you are using modulo operator on constants with different signs: `-35 % 30 - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + -1i8 % 2i8; - //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + 1i8 % -2i8; - //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + -1i16 % 2i16; - //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + 1i16 % -2i16; - //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + -1i32 % 2i32; - //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + 1i32 % -2i32; - //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + -1i64 % 2i64; - //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + 1i64 % -2i64; - //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + -1i128 % 2i128; - //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + 1i128 % -2i128; - //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + -1isize % 2isize; - //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + 1isize % -2isize; - //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2` - //~| NOTE: double check for expected result especially when interoperating with differ + //~^ modulo_arithmetic + + // No lint when both sides are const and of the same sign 1 % 2; diff --git a/tests/ui/modulo_arithmetic_integral_const.stderr b/tests/ui/modulo_arithmetic_integral_const.stderr index 722d9b83660e..49a5a2c6433a 100644 --- a/tests/ui/modulo_arithmetic_integral_const.stderr +++ b/tests/ui/modulo_arithmetic_integral_const.stderr @@ -10,7 +10,7 @@ LL | -1 % 2; = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]` error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:14:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:15:5 | LL | 1 % -2; | ^^^^^^ @@ -19,7 +19,7 @@ LL | 1 % -2; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 3` - --> tests/ui/modulo_arithmetic_integral_const.rs:17:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:19:5 | LL | (1 - 2) % (1 + 2); | ^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | (1 - 2) % (1 + 2); = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `3 % -1` - --> tests/ui/modulo_arithmetic_integral_const.rs:20:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:23:5 | LL | (1 + 2) % (1 - 2); | ^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | (1 + 2) % (1 - 2); = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-35 % 300000` - --> tests/ui/modulo_arithmetic_integral_const.rs:23:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:27:5 | LL | 35 * (7 - 4 * 2) % (-500 * -600); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | 35 * (7 - 4 * 2) % (-500 * -600); = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:27:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:32:5 | LL | -1i8 % 2i8; | ^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | -1i8 % 2i8; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:30:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:36:5 | LL | 1i8 % -2i8; | ^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | 1i8 % -2i8; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:33:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:40:5 | LL | -1i16 % 2i16; | ^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | -1i16 % 2i16; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:36:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:44:5 | LL | 1i16 % -2i16; | ^^^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | 1i16 % -2i16; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:39:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:48:5 | LL | -1i32 % 2i32; | ^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | -1i32 % 2i32; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:42:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:52:5 | LL | 1i32 % -2i32; | ^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | 1i32 % -2i32; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:45:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:56:5 | LL | -1i64 % 2i64; | ^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | -1i64 % 2i64; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:48:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:60:5 | LL | 1i64 % -2i64; | ^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | 1i64 % -2i64; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:51:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:64:5 | LL | -1i128 % 2i128; | ^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | -1i128 % 2i128; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:54:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:68:5 | LL | 1i128 % -2i128; | ^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | 1i128 % -2i128; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:57:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:72:5 | LL | -1isize % 2isize; | ^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | -1isize % 2isize; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:60:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:76:5 | LL | 1isize % -2isize; | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/modulo_one.rs b/tests/ui/modulo_one.rs index c332a15f1577..6ad038e60744 100644 --- a/tests/ui/modulo_one.rs +++ b/tests/ui/modulo_one.rs @@ -1,4 +1,5 @@ #![warn(clippy::modulo_one)] +#![allow(unconditional_panic)] #![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::identity_op)] static STATIC_ONE: usize = 2 - 1; @@ -6,33 +7,35 @@ static STATIC_NEG_ONE: i64 = 1 - 2; fn main() { 10 % 1; - //~^ ERROR: any number modulo 1 will be 0 - //~| NOTE: `-D clippy::modulo-one` implied by `-D warnings` + //~^ modulo_one + + 10 % -1; - //~^ ERROR: any number modulo -1 will panic/overflow or result in 0 + //~^ modulo_one + 10 % 2; // also caught by rustc i32::MIN % (-1); - //~^ ERROR: this operation will panic at runtime - //~| NOTE: `#[deny(unconditional_panic)]` on by default - //~| ERROR: any number modulo -1 will panic/overflow or result in 0 + //~^ modulo_one const ONE: u32 = 1 * 1; const NEG_ONE: i64 = 1 - 2; const INT_MIN: i64 = i64::MIN; 2 % ONE; - //~^ ERROR: any number modulo 1 will be 0 + //~^ modulo_one + // NOT caught by lint 5 % STATIC_ONE; 2 % NEG_ONE; - //~^ ERROR: any number modulo -1 will panic/overflow or result in 0 + //~^ modulo_one + // NOT caught by lint 5 % STATIC_NEG_ONE; // also caught by rustc INT_MIN % NEG_ONE; - //~^ ERROR: this operation will panic at runtime - //~| ERROR: any number modulo -1 will panic/overflow or result in 0 + //~^ modulo_one + // Not caught by lint, we don't look into static items, even if entirely immutable. INT_MIN % STATIC_NEG_ONE; } diff --git a/tests/ui/modulo_one.stderr b/tests/ui/modulo_one.stderr index aedcf24eae71..1eb886123d85 100644 --- a/tests/ui/modulo_one.stderr +++ b/tests/ui/modulo_one.stderr @@ -1,19 +1,5 @@ -error: this operation will panic at runtime - --> tests/ui/modulo_one.rs:15:5 - | -LL | i32::MIN % (-1); - | ^^^^^^^^^^^^^^^ attempt to compute `i32::MIN % -1_i32`, which would overflow - | - = note: `#[deny(unconditional_panic)]` on by default - -error: this operation will panic at runtime - --> tests/ui/modulo_one.rs:33:5 - | -LL | INT_MIN % NEG_ONE; - | ^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow - error: any number modulo 1 will be 0 - --> tests/ui/modulo_one.rs:8:5 + --> tests/ui/modulo_one.rs:9:5 | LL | 10 % 1; | ^^^^^^ @@ -22,34 +8,34 @@ LL | 10 % 1; = help: to override `-D warnings` add `#[allow(clippy::modulo_one)]` error: any number modulo -1 will panic/overflow or result in 0 - --> tests/ui/modulo_one.rs:11:5 + --> tests/ui/modulo_one.rs:13:5 | LL | 10 % -1; | ^^^^^^^ error: any number modulo -1 will panic/overflow or result in 0 - --> tests/ui/modulo_one.rs:15:5 + --> tests/ui/modulo_one.rs:18:5 | LL | i32::MIN % (-1); | ^^^^^^^^^^^^^^^ error: any number modulo 1 will be 0 - --> tests/ui/modulo_one.rs:24:5 + --> tests/ui/modulo_one.rs:25:5 | LL | 2 % ONE; | ^^^^^^^ error: any number modulo -1 will panic/overflow or result in 0 - --> tests/ui/modulo_one.rs:28:5 + --> tests/ui/modulo_one.rs:30:5 | LL | 2 % NEG_ONE; | ^^^^^^^^^^^ error: any number modulo -1 will panic/overflow or result in 0 - --> tests/ui/modulo_one.rs:33:5 + --> tests/ui/modulo_one.rs:36:5 | LL | INT_MIN % NEG_ONE; | ^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors diff --git a/tests/ui/multi_assignments.rs b/tests/ui/multi_assignments.rs index cdbf13b68889..651cdc5773de 100644 --- a/tests/ui/multi_assignments.rs +++ b/tests/ui/multi_assignments.rs @@ -2,15 +2,21 @@ fn main() { let (mut a, mut b, mut c, mut d) = ((), (), (), ()); a = b = c; - //~^ ERROR: assignments don't nest intuitively - //~| NOTE: `-D clippy::multi-assignments` implied by `-D warnings` + //~^ multi_assignments + + a = b = c = d; - //~^ ERROR: assignments don't nest intuitively - //~| ERROR: assignments don't nest intuitively + //~^ multi_assignments + //~| multi_assignments + + a = b = { c }; - //~^ ERROR: assignments don't nest intuitively + //~^ multi_assignments + a = { b = c }; - //~^ ERROR: assignments don't nest intuitively + //~^ multi_assignments + a = (b = c); - //~^ ERROR: assignments don't nest intuitively + //~^ multi_assignments + } diff --git a/tests/ui/multi_assignments.stderr b/tests/ui/multi_assignments.stderr index 53c22fcdb4c0..3c5bbcdea5f3 100644 --- a/tests/ui/multi_assignments.stderr +++ b/tests/ui/multi_assignments.stderr @@ -8,31 +8,31 @@ LL | a = b = c; = help: to override `-D warnings` add `#[allow(clippy::multi_assignments)]` error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:7:5 + --> tests/ui/multi_assignments.rs:8:5 | LL | a = b = c = d; | ^^^^^^^^^^^^^ error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:7:9 + --> tests/ui/multi_assignments.rs:8:9 | LL | a = b = c = d; | ^^^^^^^^^ error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:10:5 + --> tests/ui/multi_assignments.rs:13:5 | LL | a = b = { c }; | ^^^^^^^^^^^^^ error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:12:5 + --> tests/ui/multi_assignments.rs:16:5 | LL | a = { b = c }; | ^^^^^^^^^^^^^ error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:14:5 + --> tests/ui/multi_assignments.rs:19:5 | LL | a = (b = c); | ^^^^^^^^^^^ diff --git a/tests/ui/multiple_bound_locations.rs b/tests/ui/multiple_bound_locations.rs index de9d994782ec..45524c90b7f2 100644 --- a/tests/ui/multiple_bound_locations.rs +++ b/tests/ui/multiple_bound_locations.rs @@ -1,21 +1,24 @@ #![warn(clippy::multiple_bound_locations)] fn ty(a: F) -//~^ ERROR: bound is defined in more than one place +//~^ multiple_bound_locations + where F: Sized, { } fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str) -//~^ ERROR: bound is defined in more than one place +//~^ multiple_bound_locations + where 'b: 'c, { } fn ty_pred() -//~^ ERROR: bound is defined in more than one place +//~^ multiple_bound_locations + where for<'a> F: Send + 'a, { @@ -25,21 +28,24 @@ struct B; impl B { fn ty(a: F) - //~^ ERROR: bound is defined in more than one place + //~^ multiple_bound_locations + where F: Sized, { } fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str) - //~^ ERROR: bound is defined in more than one place + //~^ multiple_bound_locations + where 'b: 'c, { } fn ty_pred() - //~^ ERROR: bound is defined in more than one place + //~^ multiple_bound_locations + where for<'a> F: Send + 'a, { diff --git a/tests/ui/multiple_bound_locations.stderr b/tests/ui/multiple_bound_locations.stderr index 22dd2e0a5524..bccc57fe7054 100644 --- a/tests/ui/multiple_bound_locations.stderr +++ b/tests/ui/multiple_bound_locations.stderr @@ -11,7 +11,7 @@ LL | F: Sized, = help: to override `-D warnings` add `#[allow(clippy::multiple_bound_locations)]` error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:10:17 + --> tests/ui/multiple_bound_locations.rs:11:17 | LL | fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str) | ^^ @@ -20,7 +20,7 @@ LL | 'b: 'c, | ^^ error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:17:12 + --> tests/ui/multiple_bound_locations.rs:19:12 | LL | fn ty_pred() | ^ @@ -29,7 +29,7 @@ LL | for<'a> F: Send + 'a, | ^ error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:27:11 + --> tests/ui/multiple_bound_locations.rs:30:11 | LL | fn ty(a: F) | ^ @@ -38,7 +38,7 @@ LL | F: Sized, | ^ error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:34:21 + --> tests/ui/multiple_bound_locations.rs:38:21 | LL | fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str) | ^^ @@ -47,7 +47,7 @@ LL | 'b: 'c, | ^^ error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:41:16 + --> tests/ui/multiple_bound_locations.rs:46:16 | LL | fn ty_pred() | ^ diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index 87d3517cd5f2..cc5d455f78cf 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -36,6 +36,7 @@ static mut STATIC: i32 = 0; fn test1() { unsafe { + //~^ multiple_unsafe_ops_per_block STATIC += 1; not_very_safe(); } @@ -45,6 +46,7 @@ fn test2() { let u = U { i: 0 }; unsafe { + //~^ multiple_unsafe_ops_per_block drop(u.u); *raw_ptr(); } @@ -52,6 +54,7 @@ fn test2() { fn test3() { unsafe { + //~^ multiple_unsafe_ops_per_block asm!("nop"); sample.not_very_safe(); STATIC = 0; @@ -61,6 +64,7 @@ fn test3() { fn test_all() { let u = U { i: 0 }; unsafe { + //~^ multiple_unsafe_ops_per_block drop(u.u); drop(STATIC); sample.not_very_safe(); @@ -105,6 +109,7 @@ fn correct3() { unsafe fn read_char_bad(ptr: *const u8) -> char { unsafe { char::from_u32_unchecked(*ptr.cast::()) } + //~^ multiple_unsafe_ops_per_block } // no lint @@ -123,6 +128,7 @@ fn issue10259() { fn _fn_ptr(x: unsafe fn()) { unsafe { + //~^ multiple_unsafe_ops_per_block x(); x(); } @@ -134,6 +140,7 @@ fn _assoc_const() { } fn _f() { unsafe { + //~^ multiple_unsafe_ops_per_block T::X(); T::X(); } @@ -144,6 +151,7 @@ fn _field_fn_ptr(x: unsafe fn()) { struct X(unsafe fn()); let x = X(x); unsafe { + //~^ multiple_unsafe_ops_per_block x.0(); x.0(); } diff --git a/tests/ui/multiple_unsafe_ops_per_block.stderr b/tests/ui/multiple_unsafe_ops_per_block.stderr index a9417a9ef91c..3130cecc2525 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.stderr +++ b/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -2,18 +2,19 @@ error: this `unsafe` block contains 2 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:38:5 | LL | / unsafe { +LL | | LL | | STATIC += 1; LL | | not_very_safe(); LL | | } | |_____^ | note: modification of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:39:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:40:9 | LL | STATIC += 1; | ^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:40:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:41:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ @@ -21,29 +22,31 @@ LL | not_very_safe(); = help: to override `-D warnings` add `#[allow(clippy::multiple_unsafe_ops_per_block)]` error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:47:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:48:5 | LL | / unsafe { +LL | | LL | | drop(u.u); LL | | *raw_ptr(); LL | | } | |_____^ | note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:48:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:50:14 | LL | drop(u.u); | ^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:49:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:51:9 | LL | *raw_ptr(); | ^^^^^^^^^^ error: this `unsafe` block contains 3 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:54:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:56:5 | LL | / unsafe { +LL | | LL | | asm!("nop"); LL | | sample.not_very_safe(); LL | | STATIC = 0; @@ -51,137 +54,140 @@ LL | | } | |_____^ | note: inline assembly used here - --> tests/ui/multiple_unsafe_ops_per_block.rs:55:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:58:9 | LL | asm!("nop"); | ^^^^^^^^^^^ note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:56:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:59:9 | LL | sample.not_very_safe(); | ^^^^^^^^^^^^^^^^^^^^^^ note: modification of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:57:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:60:9 | LL | STATIC = 0; | ^^^^^^^^^^ error: this `unsafe` block contains 6 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:63:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:66:5 | LL | / unsafe { +LL | | LL | | drop(u.u); LL | | drop(STATIC); -LL | | sample.not_very_safe(); ... | LL | | asm!("nop"); LL | | } | |_____^ | note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:64:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:68:14 | LL | drop(u.u); | ^^^ note: access of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:65:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:69:14 | LL | drop(STATIC); | ^^^^^^ note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:66:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:70:9 | LL | sample.not_very_safe(); | ^^^^^^^^^^^^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:67:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:71:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:68:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:72:9 | LL | *raw_ptr(); | ^^^^^^^^^^ note: inline assembly used here - --> tests/ui/multiple_unsafe_ops_per_block.rs:69:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:73:9 | LL | asm!("nop"); | ^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:107:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:111:5 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:107:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:111:14 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:107:39 + --> tests/ui/multiple_unsafe_ops_per_block.rs:111:39 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:125:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:130:5 | LL | / unsafe { +LL | | LL | | x(); LL | | x(); LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:126:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:132:9 | LL | x(); | ^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:127:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:133:9 | LL | x(); | ^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:136:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:142:9 | LL | / unsafe { +LL | | LL | | T::X(); LL | | T::X(); LL | | } | |_________^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:137:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:144:13 | LL | T::X(); | ^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:138:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:145:13 | LL | T::X(); | ^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:146:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:153:5 | LL | / unsafe { +LL | | LL | | x.0(); LL | | x.0(); LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:147:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:155:9 | LL | x.0(); | ^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:148:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:156:9 | LL | x.0(); | ^^^^^ diff --git a/tests/ui/must_use_candidates.fixed b/tests/ui/must_use_candidates.fixed index 2459af606884..7c70c7f6399f 100644 --- a/tests/ui/must_use_candidates.fixed +++ b/tests/ui/must_use_candidates.fixed @@ -14,11 +14,13 @@ pub struct MyAtomic(AtomicBool); pub struct MyPure; #[must_use] pub fn pure(i: u8) -> u8 { +//~^ must_use_candidate i } impl MyPure { #[must_use] pub fn inherent_pure(&self) -> u8 { + //~^ must_use_candidate 0 } } @@ -50,6 +52,7 @@ pub fn with_callback bool>(f: &F) -> bool { } #[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool { +//~^ must_use_candidate true } @@ -62,6 +65,7 @@ pub fn atomics(b: &AtomicBool) -> bool { } #[must_use] pub fn rcd(_x: Rc) -> bool { +//~^ must_use_candidate true } @@ -70,6 +74,7 @@ pub fn rcmut(_x: Rc<&mut u32>) -> bool { } #[must_use] pub fn arcd(_x: Arc) -> bool { +//~^ must_use_candidate false } diff --git a/tests/ui/must_use_candidates.rs b/tests/ui/must_use_candidates.rs index 5f9b2449552a..a422e952dbcd 100644 --- a/tests/ui/must_use_candidates.rs +++ b/tests/ui/must_use_candidates.rs @@ -14,11 +14,13 @@ pub struct MyAtomic(AtomicBool); pub struct MyPure; pub fn pure(i: u8) -> u8 { +//~^ must_use_candidate i } impl MyPure { pub fn inherent_pure(&self) -> u8 { + //~^ must_use_candidate 0 } } @@ -50,6 +52,7 @@ pub fn with_callback bool>(f: &F) -> bool { } pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool { +//~^ must_use_candidate true } @@ -62,6 +65,7 @@ pub fn atomics(b: &AtomicBool) -> bool { } pub fn rcd(_x: Rc) -> bool { +//~^ must_use_candidate true } @@ -70,6 +74,7 @@ pub fn rcmut(_x: Rc<&mut u32>) -> bool { } pub fn arcd(_x: Arc) -> bool { +//~^ must_use_candidate false } diff --git a/tests/ui/must_use_candidates.stderr b/tests/ui/must_use_candidates.stderr index 2117e37866e2..590253d95f9e 100644 --- a/tests/ui/must_use_candidates.stderr +++ b/tests/ui/must_use_candidates.stderr @@ -8,25 +8,25 @@ LL | pub fn pure(i: u8) -> u8 { = help: to override `-D warnings` add `#[allow(clippy::must_use_candidate)]` error: this method could have a `#[must_use]` attribute - --> tests/ui/must_use_candidates.rs:21:5 + --> tests/ui/must_use_candidates.rs:22:5 | LL | pub fn inherent_pure(&self) -> u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn inherent_pure(&self) -> u8` error: this function could have a `#[must_use]` attribute - --> tests/ui/must_use_candidates.rs:52:1 + --> tests/ui/must_use_candidates.rs:54:1 | LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool` error: this function could have a `#[must_use]` attribute - --> tests/ui/must_use_candidates.rs:64:1 + --> tests/ui/must_use_candidates.rs:67:1 | LL | pub fn rcd(_x: Rc) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn rcd(_x: Rc) -> bool` error: this function could have a `#[must_use]` attribute - --> tests/ui/must_use_candidates.rs:72:1 + --> tests/ui/must_use_candidates.rs:76:1 | LL | pub fn arcd(_x: Arc) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn arcd(_x: Arc) -> bool` diff --git a/tests/ui/must_use_unit.fixed b/tests/ui/must_use_unit.fixed index b92d9379c904..5a8603ceb562 100644 --- a/tests/ui/must_use_unit.fixed +++ b/tests/ui/must_use_unit.fixed @@ -7,10 +7,13 @@ extern crate proc_macros; use proc_macros::external; pub fn must_use_default() {} +//~^ must_use_unit pub fn must_use_unit() -> () {} +//~^ must_use_unit pub fn must_use_with_note() {} +//~^ must_use_unit fn main() { must_use_default(); @@ -26,6 +29,8 @@ fn main() { #[cfg_attr(all(), deprecated)] fn issue_12320() {} +//~^ must_use_unit #[cfg_attr(all(), deprecated, doc = "foo")] fn issue_12320_2() {} +//~^ must_use_unit diff --git a/tests/ui/must_use_unit.rs b/tests/ui/must_use_unit.rs index c77e72827504..ab2764841cb4 100644 --- a/tests/ui/must_use_unit.rs +++ b/tests/ui/must_use_unit.rs @@ -8,12 +8,15 @@ use proc_macros::external; #[must_use] pub fn must_use_default() {} +//~^ must_use_unit #[must_use] pub fn must_use_unit() -> () {} +//~^ must_use_unit #[must_use = "With note"] pub fn must_use_with_note() {} +//~^ must_use_unit fn main() { must_use_default(); @@ -29,6 +32,8 @@ fn main() { #[cfg_attr(all(), must_use, deprecated)] fn issue_12320() {} +//~^ must_use_unit #[cfg_attr(all(), deprecated, doc = "foo", must_use)] fn issue_12320_2() {} +//~^ must_use_unit diff --git a/tests/ui/must_use_unit.stderr b/tests/ui/must_use_unit.stderr index b435568deeab..3df9738a9693 100644 --- a/tests/ui/must_use_unit.stderr +++ b/tests/ui/must_use_unit.stderr @@ -10,7 +10,7 @@ LL | pub fn must_use_default() {} = help: to override `-D warnings` add `#[allow(clippy::must_use_unit)]` error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit.rs:13:1 + --> tests/ui/must_use_unit.rs:14:1 | LL | #[must_use] | ----------- help: remove the attribute @@ -18,7 +18,7 @@ LL | pub fn must_use_unit() -> () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit.rs:16:1 + --> tests/ui/must_use_unit.rs:18:1 | LL | #[must_use = "With note"] | ------------------------- help: remove the attribute @@ -26,7 +26,7 @@ LL | pub fn must_use_with_note() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit.rs:31:1 + --> tests/ui/must_use_unit.rs:34:1 | LL | #[cfg_attr(all(), must_use, deprecated)] | -------------------- help: change these attributes to: `deprecated` @@ -34,7 +34,7 @@ LL | fn issue_12320() {} | ^^^^^^^^^^^^^^^^ error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit.rs:34:1 + --> tests/ui/must_use_unit.rs:38:1 | LL | #[cfg_attr(all(), deprecated, doc = "foo", must_use)] | --------------------------------- help: change these attributes to: `deprecated, doc = "foo"` diff --git a/tests/ui/mut_from_ref.rs b/tests/ui/mut_from_ref.rs index 0ab6d77de1e1..d2d82135d641 100644 --- a/tests/ui/mut_from_ref.rs +++ b/tests/ui/mut_from_ref.rs @@ -5,14 +5,16 @@ struct Foo; impl Foo { fn this_wont_hurt_a_bit(&self) -> &mut Foo { - //~^ ERROR: mutable borrow from immutable input(s) + //~^ mut_from_ref + unsafe { unimplemented!() } } } trait Ouch { fn ouch(x: &Foo) -> &mut Foo; - //~^ ERROR: mutable borrow from immutable input(s) + //~^ mut_from_ref + } impl Ouch for Foo { @@ -22,17 +24,20 @@ impl Ouch for Foo { } fn fail(x: &u32) -> &mut u16 { - //~^ ERROR: mutable borrow from immutable input(s) +//~^ mut_from_ref + unsafe { unimplemented!() } } fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 { - //~^ ERROR: mutable borrow from immutable input(s) +//~^ mut_from_ref + unsafe { unimplemented!() } } fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 { - //~^ ERROR: mutable borrow from immutable input(s) +//~^ mut_from_ref + unsafe { unimplemented!() } } @@ -47,7 +52,8 @@ fn also_works<'a>(x: &'a u32, y: &'a mut u32) -> &'a mut u32 { } unsafe fn also_broken(x: &u32) -> &mut u32 { - //~^ ERROR: mutable borrow from immutable input(s) +//~^ mut_from_ref + unimplemented!() } diff --git a/tests/ui/mut_from_ref.stderr b/tests/ui/mut_from_ref.stderr index 34fe91b5b3ac..593e7acdaed8 100644 --- a/tests/ui/mut_from_ref.stderr +++ b/tests/ui/mut_from_ref.stderr @@ -13,61 +13,61 @@ LL | fn this_wont_hurt_a_bit(&self) -> &mut Foo { = help: to override `-D warnings` add `#[allow(clippy::mut_from_ref)]` error: mutable borrow from immutable input(s) - --> tests/ui/mut_from_ref.rs:14:25 + --> tests/ui/mut_from_ref.rs:15:25 | LL | fn ouch(x: &Foo) -> &mut Foo; | ^^^^^^^^ | note: immutable borrow here - --> tests/ui/mut_from_ref.rs:14:16 + --> tests/ui/mut_from_ref.rs:15:16 | LL | fn ouch(x: &Foo) -> &mut Foo; | ^^^^ error: mutable borrow from immutable input(s) - --> tests/ui/mut_from_ref.rs:24:21 + --> tests/ui/mut_from_ref.rs:26:21 | LL | fn fail(x: &u32) -> &mut u16 { | ^^^^^^^^ | note: immutable borrow here - --> tests/ui/mut_from_ref.rs:24:12 + --> tests/ui/mut_from_ref.rs:26:12 | LL | fn fail(x: &u32) -> &mut u16 { | ^^^^ error: mutable borrow from immutable input(s) - --> tests/ui/mut_from_ref.rs:29:50 + --> tests/ui/mut_from_ref.rs:32:50 | LL | fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 { | ^^^^^^^^^^^ | note: immutable borrow here - --> tests/ui/mut_from_ref.rs:29:25 + --> tests/ui/mut_from_ref.rs:32:25 | LL | fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 { | ^^^^^^^ error: mutable borrow from immutable input(s) - --> tests/ui/mut_from_ref.rs:34:67 + --> tests/ui/mut_from_ref.rs:38:67 | LL | fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 { | ^^^^^^^^^^^ | note: immutable borrow here - --> tests/ui/mut_from_ref.rs:34:27 + --> tests/ui/mut_from_ref.rs:38:27 | LL | fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 { | ^^^^^^^ ^^^^^^^ error: mutable borrow from immutable input(s) - --> tests/ui/mut_from_ref.rs:49:35 + --> tests/ui/mut_from_ref.rs:54:35 | LL | unsafe fn also_broken(x: &u32) -> &mut u32 { | ^^^^^^^^ | note: immutable borrow here - --> tests/ui/mut_from_ref.rs:49:26 + --> tests/ui/mut_from_ref.rs:54:26 | LL | unsafe fn also_broken(x: &u32) -> &mut u32 { | ^^^^ diff --git a/tests/ui/mut_key.rs b/tests/ui/mut_key.rs index 43ff705c4775..55b7fe2bcca0 100644 --- a/tests/ui/mut_key.rs +++ b/tests/ui/mut_key.rs @@ -29,11 +29,14 @@ impl Hash for Key { } fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> HashSet { - //~^ ERROR: mutable key type - //~| NOTE: `-D clippy::mutable-key-type` implied by `-D warnings` - //~| ERROR: mutable key type +//~^ mutable_key_type +//~| mutable_key_type + + + let _other: HashMap = HashMap::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + m.keys().cloned().collect() } @@ -61,7 +64,8 @@ fn generics_are_ok_too(_m: &mut HashSet) { fn tuples(_m: &mut HashMap<((), U), ()>) {} fn tuples_bad(_m: &mut HashMap<(Key, U), bool>) {} -//~^ ERROR: mutable key type +//~^ mutable_key_type + fn main() { let _ = should_not_take_this_arg(&mut HashMap::new(), 1); @@ -74,29 +78,40 @@ fn main() { raw_mut_ptr_is_ok(&mut HashMap::new()); let _map = HashMap::, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + let _map = HashMap::<&mut Cell, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + // Collection types from `std` who's impl of `Hash` or `Ord` delegate their type parameters let _map = HashMap::>, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + let _map = HashMap::, ()>, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + let _map = HashMap::>, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + let _map = HashMap::>, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + let _map = HashMap::>, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + let _map = HashMap::>>, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + // Smart pointers from `std` who's impl of `Hash` or `Ord` delegate their type parameters let _map = HashMap::>, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + let _map = HashMap::>, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + let _map = HashMap::>, usize>::new(); - //~^ ERROR: mutable key type + //~^ mutable_key_type + // Not interior mutability let _map = HashMap::<&mut usize, usize>::new(); diff --git a/tests/ui/mut_key.stderr b/tests/ui/mut_key.stderr index 8698ed4fd678..1887604b080a 100644 --- a/tests/ui/mut_key.stderr +++ b/tests/ui/mut_key.stderr @@ -21,7 +21,7 @@ LL | fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> Hash = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:35:5 + --> tests/ui/mut_key.rs:37:5 | LL | let _other: HashMap = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | let _other: HashMap = HashMap::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:63:22 + --> tests/ui/mut_key.rs:66:22 | LL | fn tuples_bad(_m: &mut HashMap<(Key, U), bool>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | fn tuples_bad(_m: &mut HashMap<(Key, U), bool>) {} = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:76:5 + --> tests/ui/mut_key.rs:80:5 | LL | let _map = HashMap::, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | let _map = HashMap::, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:78:5 + --> tests/ui/mut_key.rs:83:5 | LL | let _map = HashMap::<&mut Cell, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | let _map = HashMap::<&mut Cell, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:81:5 + --> tests/ui/mut_key.rs:87:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:83:5 + --> tests/ui/mut_key.rs:90:5 | LL | let _map = HashMap::, ()>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | let _map = HashMap::, ()>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:85:5 + --> tests/ui/mut_key.rs:93:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:87:5 + --> tests/ui/mut_key.rs:96:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -101,7 +101,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:89:5 + --> tests/ui/mut_key.rs:99:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:91:5 + --> tests/ui/mut_key.rs:102:5 | LL | let _map = HashMap::>>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let _map = HashMap::>>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:94:5 + --> tests/ui/mut_key.rs:106:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:96:5 + --> tests/ui/mut_key.rs:109:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:98:5 + --> tests/ui/mut_key.rs:112:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/mut_mut.rs b/tests/ui/mut_mut.rs index 4c45bc980265..47f52621794b 100644 --- a/tests/ui/mut_mut.rs +++ b/tests/ui/mut_mut.rs @@ -13,6 +13,7 @@ extern crate proc_macros; use proc_macros::{external, inline_macros}; fn fun(x: &mut &mut u32) -> bool { +//~^ mut_mut **x > 0 } @@ -30,21 +31,29 @@ macro_rules! mut_ptr { #[inline_macros] fn main() { let mut x = &mut &mut 1u32; + //~^ mut_mut { let mut y = &mut x; + //~^ mut_mut } if fun(x) { let y: &mut &mut u32 = &mut &mut 2; + //~^ mut_mut + //~| mut_mut **y + **x; } if fun(x) { let y: &mut &mut &mut u32 = &mut &mut &mut 2; + //~^ mut_mut + //~| mut_mut + //~| mut_mut ***y + **x; } let mut z = inline!(&mut $(&mut 3u32)); + //~^ mut_mut } fn issue939() { diff --git a/tests/ui/mut_mut.stderr b/tests/ui/mut_mut.stderr index 42853fdc008c..74b0c9ba145a 100644 --- a/tests/ui/mut_mut.stderr +++ b/tests/ui/mut_mut.stderr @@ -8,13 +8,13 @@ LL | fn fun(x: &mut &mut u32) -> bool { = help: to override `-D warnings` add `#[allow(clippy::mut_mut)]` error: generally you want to avoid `&mut &mut _` if possible - --> tests/ui/mut_mut.rs:32:17 + --> tests/ui/mut_mut.rs:33:17 | LL | let mut x = &mut &mut 1u32; | ^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> tests/ui/mut_mut.rs:47:25 + --> tests/ui/mut_mut.rs:55:25 | LL | let mut z = inline!(&mut $(&mut 3u32)); | ^ @@ -22,37 +22,37 @@ LL | let mut z = inline!(&mut $(&mut 3u32)); = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this expression mutably borrows a mutable reference. Consider reborrowing - --> tests/ui/mut_mut.rs:34:21 + --> tests/ui/mut_mut.rs:36:21 | LL | let mut y = &mut x; | ^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> tests/ui/mut_mut.rs:38:32 + --> tests/ui/mut_mut.rs:41:32 | LL | let y: &mut &mut u32 = &mut &mut 2; | ^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> tests/ui/mut_mut.rs:38:16 + --> tests/ui/mut_mut.rs:41:16 | LL | let y: &mut &mut u32 = &mut &mut 2; | ^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> tests/ui/mut_mut.rs:43:37 + --> tests/ui/mut_mut.rs:48:37 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> tests/ui/mut_mut.rs:43:16 + --> tests/ui/mut_mut.rs:48:16 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> tests/ui/mut_mut.rs:43:21 + --> tests/ui/mut_mut.rs:48:21 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^ diff --git a/tests/ui/mut_mutex_lock.fixed b/tests/ui/mut_mutex_lock.fixed index 29c5a27cb624..5790ee8c1b02 100644 --- a/tests/ui/mut_mutex_lock.fixed +++ b/tests/ui/mut_mutex_lock.fixed @@ -8,11 +8,13 @@ fn mut_mutex_lock() { let value_mutex = Arc::get_mut(&mut value_rc).unwrap(); let mut value = value_mutex.get_mut().unwrap(); + //~^ mut_mutex_lock *value += 1; let mut value_mutex = Mutex::new(42_u8); let mut_ref_mut_ref_mutex = &mut &mut value_mutex; let mut value = mut_ref_mut_ref_mutex.get_mut().unwrap(); + //~^ mut_mutex_lock *value += 1; } diff --git a/tests/ui/mut_mutex_lock.rs b/tests/ui/mut_mutex_lock.rs index fcdb3ff97dbc..7286afac823b 100644 --- a/tests/ui/mut_mutex_lock.rs +++ b/tests/ui/mut_mutex_lock.rs @@ -8,11 +8,13 @@ fn mut_mutex_lock() { let value_mutex = Arc::get_mut(&mut value_rc).unwrap(); let mut value = value_mutex.lock().unwrap(); + //~^ mut_mutex_lock *value += 1; let mut value_mutex = Mutex::new(42_u8); let mut_ref_mut_ref_mutex = &mut &mut value_mutex; let mut value = mut_ref_mut_ref_mutex.lock().unwrap(); + //~^ mut_mutex_lock *value += 1; } diff --git a/tests/ui/mut_mutex_lock.stderr b/tests/ui/mut_mutex_lock.stderr index 92601c4c6121..67543c73c6ee 100644 --- a/tests/ui/mut_mutex_lock.stderr +++ b/tests/ui/mut_mutex_lock.stderr @@ -8,7 +8,7 @@ LL | let mut value = value_mutex.lock().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::mut_mutex_lock)]` error: calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference - --> tests/ui/mut_mutex_lock.rs:15:43 + --> tests/ui/mut_mutex_lock.rs:16:43 | LL | let mut value = mut_ref_mut_ref_mutex.lock().unwrap(); | ^^^^ help: change this to: `get_mut` diff --git a/tests/ui/mut_range_bound.rs b/tests/ui/mut_range_bound.rs index 7aebbf4981ee..326afb42ccb2 100644 --- a/tests/ui/mut_range_bound.rs +++ b/tests/ui/mut_range_bound.rs @@ -6,8 +6,9 @@ fn mut_range_bound_upper() { let mut m = 4; for i in 0..m { m = 5; - //~^ ERROR: attempt to mutate range bound within loop - //~| NOTE: the range of the loop is unchanged + //~^ mut_range_bound + + } } @@ -15,8 +16,9 @@ fn mut_range_bound_lower() { let mut m = 4; for i in m..10 { m *= 2; - //~^ ERROR: attempt to mutate range bound within loop - //~| NOTE: the range of the loop is unchanged + //~^ mut_range_bound + + } } @@ -25,11 +27,13 @@ fn mut_range_bound_both() { let mut n = 6; for i in m..n { m = 5; - //~^ ERROR: attempt to mutate range bound within loop - //~| NOTE: the range of the loop is unchanged + //~^ mut_range_bound + + n = 7; - //~^ ERROR: attempt to mutate range bound within loop - //~| NOTE: the range of the loop is unchanged + //~^ mut_range_bound + + } } @@ -44,8 +48,9 @@ fn mut_borrow_range_bound() { let mut m = 4; for i in 0..m { let n = &mut m; - //~^ ERROR: attempt to mutate range bound within loop - //~| NOTE: the range of the loop is unchanged + //~^ mut_range_bound + + *n += 1; } } @@ -79,8 +84,9 @@ fn mut_range_bound_no_immediate_break() { for i in 0..m { // warning because it is not immediately followed by break m = 2; - //~^ ERROR: attempt to mutate range bound within loop - //~| NOTE: the range of the loop is unchanged + //~^ mut_range_bound + + if m == 4 { break; } @@ -91,8 +97,9 @@ fn mut_range_bound_no_immediate_break() { if n == 4 { // FIXME: warning because it is not immediately followed by break n = 1; - //~^ ERROR: attempt to mutate range bound within loop - //~| NOTE: the range of the loop is unchanged + //~^ mut_range_bound + + let _ = 2; break; } diff --git a/tests/ui/mut_range_bound.stderr b/tests/ui/mut_range_bound.stderr index 6f93b0ebe6fc..3dbc70f87f0f 100644 --- a/tests/ui/mut_range_bound.stderr +++ b/tests/ui/mut_range_bound.stderr @@ -9,7 +9,7 @@ LL | m = 5; = help: to override `-D warnings` add `#[allow(clippy::mut_range_bound)]` error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:17:9 + --> tests/ui/mut_range_bound.rs:18:9 | LL | m *= 2; | ^ @@ -17,7 +17,7 @@ LL | m *= 2; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:27:9 + --> tests/ui/mut_range_bound.rs:29:9 | LL | m = 5; | ^ @@ -25,7 +25,7 @@ LL | m = 5; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:30:9 + --> tests/ui/mut_range_bound.rs:33:9 | LL | n = 7; | ^ @@ -33,7 +33,7 @@ LL | n = 7; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:46:22 + --> tests/ui/mut_range_bound.rs:50:22 | LL | let n = &mut m; | ^ @@ -41,7 +41,7 @@ LL | let n = &mut m; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:81:9 + --> tests/ui/mut_range_bound.rs:86:9 | LL | m = 2; | ^ @@ -49,7 +49,7 @@ LL | m = 2; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:93:13 + --> tests/ui/mut_range_bound.rs:99:13 | LL | n = 1; | ^ diff --git a/tests/ui/mut_reference.rs b/tests/ui/mut_reference.rs index 1d7faaa5e75e..4ae57940cf2d 100644 --- a/tests/ui/mut_reference.rs +++ b/tests/ui/mut_reference.rs @@ -28,16 +28,19 @@ impl MyStruct { fn main() { // Functions takes_an_immutable_reference(&mut 42); - //~^ ERROR: the function `takes_an_immutable_reference` doesn't need a mutable referen - //~| NOTE: `-D clippy::unnecessary-mut-passed` implied by `-D warnings` + //~^ unnecessary_mut_passed + + let as_ptr: fn(&i32) = takes_an_immutable_reference; as_ptr(&mut 42); - //~^ ERROR: the function `as_ptr` doesn't need a mutable reference + //~^ unnecessary_mut_passed + // Methods let my_struct = MyStruct; my_struct.takes_an_immutable_reference(&mut 42); - //~^ ERROR: the method `takes_an_immutable_reference` doesn't need a mutable reference + //~^ unnecessary_mut_passed + // No error diff --git a/tests/ui/mut_reference.stderr b/tests/ui/mut_reference.stderr index 474221329c25..fb489360a1a3 100644 --- a/tests/ui/mut_reference.stderr +++ b/tests/ui/mut_reference.stderr @@ -8,13 +8,13 @@ LL | takes_an_immutable_reference(&mut 42); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_mut_passed)]` error: the function `as_ptr` doesn't need a mutable reference - --> tests/ui/mut_reference.rs:34:12 + --> tests/ui/mut_reference.rs:35:12 | LL | as_ptr(&mut 42); | ^^^^^^^ error: the method `takes_an_immutable_reference` doesn't need a mutable reference - --> tests/ui/mut_reference.rs:39:44 + --> tests/ui/mut_reference.rs:41:44 | LL | my_struct.takes_an_immutable_reference(&mut 42); | ^^^^^^^ diff --git a/tests/ui/mutex_atomic.rs b/tests/ui/mutex_atomic.rs index 3a51538b7424..993ea880d66b 100644 --- a/tests/ui/mutex_atomic.rs +++ b/tests/ui/mutex_atomic.rs @@ -6,32 +6,43 @@ fn main() { use std::sync::Mutex; Mutex::new(true); - //~^ ERROR: consider using an `AtomicBool` instead of a `Mutex` here; if you just want - //~| NOTE: `-D clippy::mutex-atomic` implied by `-D warnings` + //~^ mutex_atomic + + Mutex::new(5usize); - //~^ ERROR: consider using an `AtomicUsize` instead of a `Mutex` here; if you just wan + //~^ mutex_atomic + Mutex::new(9isize); - //~^ ERROR: consider using an `AtomicIsize` instead of a `Mutex` here; if you just wan + //~^ mutex_atomic + let mut x = 4u32; Mutex::new(&x as *const u32); - //~^ ERROR: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want + //~^ mutex_atomic + Mutex::new(&mut x as *mut u32); - //~^ ERROR: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want + //~^ mutex_atomic + Mutex::new(0u32); - //~^ ERROR: consider using an `AtomicU32` instead of a `Mutex` here; if you just wan - //~| NOTE: `-D clippy::mutex-integer` implied by `-D warnings` + //~^ mutex_integer + + Mutex::new(0i32); - //~^ ERROR: consider using an `AtomicI32` instead of a `Mutex` here; if you just wan + //~^ mutex_integer + Mutex::new(0f32); // there are no float atomics, so this should not lint Mutex::new(0u8); - //~^ ERROR: consider using an `AtomicU8` instead of a `Mutex` here; if you just wan + //~^ mutex_integer + Mutex::new(0i16); - //~^ ERROR: consider using an `AtomicI16` instead of a `Mutex` here; if you just wan + //~^ mutex_integer + let _x: Mutex = Mutex::new(0); - //~^ ERROR: consider using an `AtomicI8` instead of a `Mutex` here; if you just wan + //~^ mutex_integer + const X: i64 = 0; Mutex::new(X); - //~^ ERROR: consider using an `AtomicI64` instead of a `Mutex` here; if you just wan + //~^ mutex_integer + // there are no 128 atomics, so these two should not lint { diff --git a/tests/ui/mutex_atomic.stderr b/tests/ui/mutex_atomic.stderr index 683a7b939db3..83be2ef995ce 100644 --- a/tests/ui/mutex_atomic.stderr +++ b/tests/ui/mutex_atomic.stderr @@ -8,31 +8,31 @@ LL | Mutex::new(true); = help: to override `-D warnings` add `#[allow(clippy::mutex_atomic)]` error: consider using an `AtomicUsize` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:11:5 + --> tests/ui/mutex_atomic.rs:12:5 | LL | Mutex::new(5usize); | ^^^^^^^^^^^^^^^^^^ error: consider using an `AtomicIsize` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:13:5 + --> tests/ui/mutex_atomic.rs:15:5 | LL | Mutex::new(9isize); | ^^^^^^^^^^^^^^^^^^ error: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:16:5 + --> tests/ui/mutex_atomic.rs:19:5 | LL | Mutex::new(&x as *const u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:18:5 + --> tests/ui/mutex_atomic.rs:22:5 | LL | Mutex::new(&mut x as *mut u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: consider using an `AtomicU32` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:20:5 + --> tests/ui/mutex_atomic.rs:25:5 | LL | Mutex::new(0u32); | ^^^^^^^^^^^^^^^^ @@ -41,31 +41,31 @@ LL | Mutex::new(0u32); = help: to override `-D warnings` add `#[allow(clippy::mutex_integer)]` error: consider using an `AtomicI32` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:23:5 + --> tests/ui/mutex_atomic.rs:29:5 | LL | Mutex::new(0i32); | ^^^^^^^^^^^^^^^^ error: consider using an `AtomicU8` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:26:5 + --> tests/ui/mutex_atomic.rs:33:5 | LL | Mutex::new(0u8); | ^^^^^^^^^^^^^^^ error: consider using an `AtomicI16` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:28:5 + --> tests/ui/mutex_atomic.rs:36:5 | LL | Mutex::new(0i16); | ^^^^^^^^^^^^^^^^ error: consider using an `AtomicI8` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:30:25 + --> tests/ui/mutex_atomic.rs:39:25 | LL | let _x: Mutex = Mutex::new(0); | ^^^^^^^^^^^^^ error: consider using an `AtomicI64` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:33:5 + --> tests/ui/mutex_atomic.rs:43:5 | LL | Mutex::new(X); | ^^^^^^^^^^^^^ diff --git a/tests/ui/needless_arbitrary_self_type.fixed b/tests/ui/needless_arbitrary_self_type.fixed index 530eb77d83d2..22dd127f01f3 100644 --- a/tests/ui/needless_arbitrary_self_type.fixed +++ b/tests/ui/needless_arbitrary_self_type.fixed @@ -8,6 +8,7 @@ pub enum ValType { impl ValType { pub fn bad(self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -16,6 +17,7 @@ impl ValType { } pub fn mut_bad(mut self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -24,6 +26,7 @@ impl ValType { } pub fn ref_bad(&self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -32,6 +35,7 @@ impl ValType { } pub fn ref_bad_with_lifetime<'a>(&'a self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -40,6 +44,7 @@ impl ValType { } pub fn mut_ref_bad(&mut self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -48,6 +53,7 @@ impl ValType { } pub fn mut_ref_bad_with_lifetime<'a>(&'a mut self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -66,7 +72,9 @@ impl ValType { trait Foo<'r#struct> { fn f1(&'r#struct self) {} + //~^ needless_arbitrary_self_type fn f2(&'r#struct mut self) {} + //~^ needless_arbitrary_self_type } fn main() {} diff --git a/tests/ui/needless_arbitrary_self_type.rs b/tests/ui/needless_arbitrary_self_type.rs index 5a1ff96a11cc..5b1702bfdf96 100644 --- a/tests/ui/needless_arbitrary_self_type.rs +++ b/tests/ui/needless_arbitrary_self_type.rs @@ -8,6 +8,7 @@ pub enum ValType { impl ValType { pub fn bad(self: Self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -16,6 +17,7 @@ impl ValType { } pub fn mut_bad(mut self: Self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -24,6 +26,7 @@ impl ValType { } pub fn ref_bad(self: &Self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -32,6 +35,7 @@ impl ValType { } pub fn ref_bad_with_lifetime<'a>(self: &'a Self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -40,6 +44,7 @@ impl ValType { } pub fn mut_ref_bad(self: &mut Self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -48,6 +53,7 @@ impl ValType { } pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) { + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -66,7 +72,9 @@ impl ValType { trait Foo<'r#struct> { fn f1(self: &'r#struct Self) {} + //~^ needless_arbitrary_self_type fn f2(self: &'r#struct mut Self) {} + //~^ needless_arbitrary_self_type } fn main() {} diff --git a/tests/ui/needless_arbitrary_self_type.stderr b/tests/ui/needless_arbitrary_self_type.stderr index 7ebbbaa122f5..b5c0aae8310f 100644 --- a/tests/ui/needless_arbitrary_self_type.stderr +++ b/tests/ui/needless_arbitrary_self_type.stderr @@ -8,43 +8,43 @@ LL | pub fn bad(self: Self) { = help: to override `-D warnings` add `#[allow(clippy::needless_arbitrary_self_type)]` error: the type of the `self` parameter does not need to be arbitrary - --> tests/ui/needless_arbitrary_self_type.rs:18:20 + --> tests/ui/needless_arbitrary_self_type.rs:19:20 | LL | pub fn mut_bad(mut self: Self) { | ^^^^^^^^^^^^^^ help: consider to change this parameter to: `mut self` error: the type of the `self` parameter does not need to be arbitrary - --> tests/ui/needless_arbitrary_self_type.rs:26:20 + --> tests/ui/needless_arbitrary_self_type.rs:28:20 | LL | pub fn ref_bad(self: &Self) { | ^^^^^^^^^^^ help: consider to change this parameter to: `&self` error: the type of the `self` parameter does not need to be arbitrary - --> tests/ui/needless_arbitrary_self_type.rs:34:38 + --> tests/ui/needless_arbitrary_self_type.rs:37:38 | LL | pub fn ref_bad_with_lifetime<'a>(self: &'a Self) { | ^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'a self` error: the type of the `self` parameter does not need to be arbitrary - --> tests/ui/needless_arbitrary_self_type.rs:42:24 + --> tests/ui/needless_arbitrary_self_type.rs:46:24 | LL | pub fn mut_ref_bad(self: &mut Self) { | ^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&mut self` error: the type of the `self` parameter does not need to be arbitrary - --> tests/ui/needless_arbitrary_self_type.rs:50:42 + --> tests/ui/needless_arbitrary_self_type.rs:55:42 | LL | pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) { | ^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'a mut self` error: the type of the `self` parameter does not need to be arbitrary - --> tests/ui/needless_arbitrary_self_type.rs:68:11 + --> tests/ui/needless_arbitrary_self_type.rs:74:11 | LL | fn f1(self: &'r#struct Self) {} | ^^^^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'r#struct self` error: the type of the `self` parameter does not need to be arbitrary - --> tests/ui/needless_arbitrary_self_type.rs:69:11 + --> tests/ui/needless_arbitrary_self_type.rs:76:11 | LL | fn f2(self: &'r#struct mut Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'r#struct mut self` diff --git a/tests/ui/needless_arbitrary_self_type_unfixable.fixed b/tests/ui/needless_arbitrary_self_type_unfixable.fixed index 62a6e5932435..f4ee0a8bd072 100644 --- a/tests/ui/needless_arbitrary_self_type_unfixable.fixed +++ b/tests/ui/needless_arbitrary_self_type_unfixable.fixed @@ -40,6 +40,7 @@ mod issue_6089 { impl T2 for S2 { #[allow(clippy::needless_lifetimes)] fn call_with_mut_self(&mut self) {} + //~^ needless_arbitrary_self_type } } diff --git a/tests/ui/needless_arbitrary_self_type_unfixable.rs b/tests/ui/needless_arbitrary_self_type_unfixable.rs index 00871f9f450c..3f29025c1362 100644 --- a/tests/ui/needless_arbitrary_self_type_unfixable.rs +++ b/tests/ui/needless_arbitrary_self_type_unfixable.rs @@ -40,6 +40,7 @@ mod issue_6089 { impl T2 for S2 { #[allow(clippy::needless_lifetimes)] fn call_with_mut_self(self: &mut Self) {} + //~^ needless_arbitrary_self_type } } diff --git a/tests/ui/needless_as_bytes.fixed b/tests/ui/needless_as_bytes.fixed index 74b4ba5be798..2f9e82218889 100644 --- a/tests/ui/needless_as_bytes.fixed +++ b/tests/ui/needless_as_bytes.fixed @@ -15,26 +15,34 @@ impl S { fn main() { if "some string".is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes + println!("len = {}", "some string".len()); //~^ needless_as_bytes + } if "some string".is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes + println!("len = {}", "some string".len()); //~^ needless_as_bytes + } let s = String::from("yet another string"); if s.is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes + println!("len = {}", s.len()); //~^ needless_as_bytes + } if s.is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes + println!("len = {}", s.len()); //~^ needless_as_bytes + } // Do not lint diff --git a/tests/ui/needless_as_bytes.rs b/tests/ui/needless_as_bytes.rs index ffcce60bbbef..2f0fc352d192 100644 --- a/tests/ui/needless_as_bytes.rs +++ b/tests/ui/needless_as_bytes.rs @@ -15,26 +15,34 @@ impl S { fn main() { if "some string".as_bytes().is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes + println!("len = {}", "some string".as_bytes().len()); //~^ needless_as_bytes + } if "some string".bytes().is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes + println!("len = {}", "some string".bytes().len()); //~^ needless_as_bytes + } let s = String::from("yet another string"); if s.as_bytes().is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes + println!("len = {}", s.as_bytes().len()); //~^ needless_as_bytes + } if s.bytes().is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes + println!("len = {}", s.bytes().len()); //~^ needless_as_bytes + } // Do not lint diff --git a/tests/ui/needless_as_bytes.stderr b/tests/ui/needless_as_bytes.stderr index 138c6630ae7d..72746c05b8e2 100644 --- a/tests/ui/needless_as_bytes.stderr +++ b/tests/ui/needless_as_bytes.stderr @@ -8,43 +8,43 @@ LL | if "some string".as_bytes().is_empty() { = help: to override `-D warnings` add `#[allow(clippy::needless_as_bytes)]` error: needless call to `as_bytes` - --> tests/ui/needless_as_bytes.rs:19:30 + --> tests/ui/needless_as_bytes.rs:20:30 | LL | println!("len = {}", "some string".as_bytes().len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()` error: needless call to `bytes` - --> tests/ui/needless_as_bytes.rs:22:8 + --> tests/ui/needless_as_bytes.rs:24:8 | LL | if "some string".bytes().is_empty() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `"some string".is_empty()` error: needless call to `bytes` - --> tests/ui/needless_as_bytes.rs:24:30 + --> tests/ui/needless_as_bytes.rs:27:30 | LL | println!("len = {}", "some string".bytes().len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()` error: needless call to `as_bytes` - --> tests/ui/needless_as_bytes.rs:29:8 + --> tests/ui/needless_as_bytes.rs:33:8 | LL | if s.as_bytes().is_empty() { | ^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()` error: needless call to `as_bytes` - --> tests/ui/needless_as_bytes.rs:31:30 + --> tests/ui/needless_as_bytes.rs:36:30 | LL | println!("len = {}", s.as_bytes().len()); | ^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()` error: needless call to `bytes` - --> tests/ui/needless_as_bytes.rs:34:8 + --> tests/ui/needless_as_bytes.rs:40:8 | LL | if s.bytes().is_empty() { | ^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()` error: needless call to `bytes` - --> tests/ui/needless_as_bytes.rs:36:30 + --> tests/ui/needless_as_bytes.rs:43:30 | LL | println!("len = {}", s.bytes().len()); | ^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()` diff --git a/tests/ui/needless_bitwise_bool.fixed b/tests/ui/needless_bitwise_bool.fixed index a8176618c1f2..7fc36e0f94b4 100644 --- a/tests/ui/needless_bitwise_bool.fixed +++ b/tests/ui/needless_bitwise_bool.fixed @@ -21,6 +21,7 @@ fn main() { println!("true") } if y && !x { + //~^ needless_bitwise_bool println!("true") } diff --git a/tests/ui/needless_bitwise_bool.rs b/tests/ui/needless_bitwise_bool.rs index f190eb2b76e7..dcbc08334a77 100644 --- a/tests/ui/needless_bitwise_bool.rs +++ b/tests/ui/needless_bitwise_bool.rs @@ -21,6 +21,7 @@ fn main() { println!("true") } if y & !x { + //~^ needless_bitwise_bool println!("true") } diff --git a/tests/ui/needless_bool/fixable.fixed b/tests/ui/needless_bool/fixable.fixed index ec63c4fd6a26..0664abf0944d 100644 --- a/tests/ui/needless_bool/fixable.fixed +++ b/tests/ui/needless_bool/fixable.fixed @@ -39,17 +39,26 @@ fn main() { let x = true; let y = false; x; + //~^^^^^ needless_bool !x; + //~^^^^^ needless_bool !(x && y); + //~^^^^^ needless_bool let a = 0; let b = 1; a != b; + //~^^^^^ needless_bool a == b; + //~^^^^^ needless_bool a >= b; + //~^^^^^ needless_bool a > b; + //~^^^^^ needless_bool a <= b; + //~^^^^^ needless_bool a < b; + //~^^^^^ needless_bool if x { x } else { @@ -74,26 +83,32 @@ fn main() { fn bool_ret3(x: bool) -> bool { return x; + //~^^^^^ needless_bool } fn bool_ret4(x: bool) -> bool { return !x; + //~^^^^^ needless_bool } fn bool_ret5(x: bool, y: bool) -> bool { return x && y; + //~^^^^^ needless_bool } fn bool_ret6(x: bool, y: bool) -> bool { return !(x && y); + //~^^^^^ needless_bool } fn needless_bool(x: bool) { if x {}; + //~^ bool_comparison } fn needless_bool2(x: bool) { if !x {}; + //~^ bool_comparison } fn needless_bool3(x: bool) { @@ -104,7 +119,9 @@ fn needless_bool3(x: bool) { } if x {}; + //~^ bool_comparison if !x {}; + //~^ bool_comparison } fn needless_bool_in_the_suggestion_wraps_the_predicate_of_if_else_statement_in_brackets() { @@ -114,6 +131,7 @@ fn needless_bool_in_the_suggestion_wraps_the_predicate_of_if_else_statement_in_b let x = if b { true } else { !returns_bool() }; + //~^^^^^ needless_bool } unsafe fn no(v: u8) -> u8 { @@ -123,10 +141,13 @@ unsafe fn no(v: u8) -> u8 { #[allow(clippy::unnecessary_operation)] fn needless_bool_condition() -> bool { (unsafe { no(4) } & 1 != 0); + //~^^^^^ needless_bool let _brackets_unneeded = unsafe { no(4) } & 1 != 0; + //~^ needless_bool fn foo() -> bool { // parentheses are needed here (unsafe { no(4) } & 1 != 0) + //~^ needless_bool } foo() @@ -138,8 +159,11 @@ fn issue12846() { // parentheses are needed here let _x = (a && b).then(|| todo!()); + //~^ needless_bool let _x = (a && b) as u8; + //~^ needless_bool // parentheses are not needed here let _x = a.then(|| todo!()); + //~^ needless_bool } diff --git a/tests/ui/needless_bool/fixable.rs b/tests/ui/needless_bool/fixable.rs index 8694aa715908..7507a6af408b 100644 --- a/tests/ui/needless_bool/fixable.rs +++ b/tests/ui/needless_bool/fixable.rs @@ -43,16 +43,19 @@ fn main() { } else { false }; + //~^^^^^ needless_bool if x { false } else { true }; + //~^^^^^ needless_bool if x && y { false } else { true }; + //~^^^^^ needless_bool let a = 0; let b = 1; @@ -61,31 +64,37 @@ fn main() { } else { true }; + //~^^^^^ needless_bool if a != b { false } else { true }; + //~^^^^^ needless_bool if a < b { false } else { true }; + //~^^^^^ needless_bool if a <= b { false } else { true }; + //~^^^^^ needless_bool if a > b { false } else { true }; + //~^^^^^ needless_bool if a >= b { false } else { true }; + //~^^^^^ needless_bool if x { x } else { @@ -114,6 +123,7 @@ fn bool_ret3(x: bool) -> bool { } else { return false; }; + //~^^^^^ needless_bool } fn bool_ret4(x: bool) -> bool { @@ -122,6 +132,7 @@ fn bool_ret4(x: bool) -> bool { } else { return true; }; + //~^^^^^ needless_bool } fn bool_ret5(x: bool, y: bool) -> bool { @@ -130,6 +141,7 @@ fn bool_ret5(x: bool, y: bool) -> bool { } else { return false; }; + //~^^^^^ needless_bool } fn bool_ret6(x: bool, y: bool) -> bool { @@ -138,14 +150,17 @@ fn bool_ret6(x: bool, y: bool) -> bool { } else { return true; }; + //~^^^^^ needless_bool } fn needless_bool(x: bool) { if x == true {}; + //~^ bool_comparison } fn needless_bool2(x: bool) { if x == false {}; + //~^ bool_comparison } fn needless_bool3(x: bool) { @@ -156,7 +171,9 @@ fn needless_bool3(x: bool) { } if x == true {}; + //~^ bool_comparison if x == false {}; + //~^ bool_comparison } fn needless_bool_in_the_suggestion_wraps_the_predicate_of_if_else_statement_in_brackets() { @@ -170,6 +187,7 @@ fn needless_bool_in_the_suggestion_wraps_the_predicate_of_if_else_statement_in_b } else { true }; + //~^^^^^ needless_bool } unsafe fn no(v: u8) -> u8 { @@ -183,10 +201,13 @@ fn needless_bool_condition() -> bool { } else { false }; + //~^^^^^ needless_bool let _brackets_unneeded = if unsafe { no(4) } & 1 != 0 { true } else { false }; + //~^ needless_bool fn foo() -> bool { // parentheses are needed here if unsafe { no(4) } & 1 != 0 { true } else { false } + //~^ needless_bool } foo() @@ -198,8 +219,11 @@ fn issue12846() { // parentheses are needed here let _x = if a && b { true } else { false }.then(|| todo!()); + //~^ needless_bool let _x = if a && b { true } else { false } as u8; + //~^ needless_bool // parentheses are not needed here let _x = if a { true } else { false }.then(|| todo!()); + //~^ needless_bool } diff --git a/tests/ui/needless_bool/fixable.stderr b/tests/ui/needless_bool/fixable.stderr index 99b5b9983448..3f117ee5a502 100644 --- a/tests/ui/needless_bool/fixable.stderr +++ b/tests/ui/needless_bool/fixable.stderr @@ -12,7 +12,7 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:46:5 + --> tests/ui/needless_bool/fixable.rs:47:5 | LL | / if x { LL | | false @@ -22,7 +22,7 @@ LL | | }; | |_____^ help: you can reduce it to: `!x` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:51:5 + --> tests/ui/needless_bool/fixable.rs:53:5 | LL | / if x && y { LL | | false @@ -32,7 +32,7 @@ LL | | }; | |_____^ help: you can reduce it to: `!(x && y)` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:59:5 + --> tests/ui/needless_bool/fixable.rs:62:5 | LL | / if a == b { LL | | false @@ -42,7 +42,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a != b` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:64:5 + --> tests/ui/needless_bool/fixable.rs:68:5 | LL | / if a != b { LL | | false @@ -52,7 +52,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a == b` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:69:5 + --> tests/ui/needless_bool/fixable.rs:74:5 | LL | / if a < b { LL | | false @@ -62,7 +62,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a >= b` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:74:5 + --> tests/ui/needless_bool/fixable.rs:80:5 | LL | / if a <= b { LL | | false @@ -72,7 +72,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a > b` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:79:5 + --> tests/ui/needless_bool/fixable.rs:86:5 | LL | / if a > b { LL | | false @@ -82,7 +82,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a <= b` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:84:5 + --> tests/ui/needless_bool/fixable.rs:92:5 | LL | / if a >= b { LL | | false @@ -92,7 +92,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a < b` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:112:5 + --> tests/ui/needless_bool/fixable.rs:121:5 | LL | / if x { LL | | return true; @@ -102,7 +102,7 @@ LL | | }; | |_____^ help: you can reduce it to: `return x` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:120:5 + --> tests/ui/needless_bool/fixable.rs:130:5 | LL | / if x { LL | | return false; @@ -112,7 +112,7 @@ LL | | }; | |_____^ help: you can reduce it to: `return !x` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:128:5 + --> tests/ui/needless_bool/fixable.rs:139:5 | LL | / if x && y { LL | | return true; @@ -122,7 +122,7 @@ LL | | }; | |_____^ help: you can reduce it to: `return x && y` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:136:5 + --> tests/ui/needless_bool/fixable.rs:148:5 | LL | / if x && y { LL | | return false; @@ -132,7 +132,7 @@ LL | | }; | |_____^ help: you can reduce it to: `return !(x && y)` error: equality checks against true are unnecessary - --> tests/ui/needless_bool/fixable.rs:144:8 + --> tests/ui/needless_bool/fixable.rs:157:8 | LL | if x == true {}; | ^^^^^^^^^ help: try simplifying it as shown: `x` @@ -141,25 +141,25 @@ LL | if x == true {}; = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]` error: equality checks against false can be replaced by a negation - --> tests/ui/needless_bool/fixable.rs:148:8 + --> tests/ui/needless_bool/fixable.rs:162:8 | LL | if x == false {}; | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: equality checks against true are unnecessary - --> tests/ui/needless_bool/fixable.rs:158:8 + --> tests/ui/needless_bool/fixable.rs:173:8 | LL | if x == true {}; | ^^^^^^^^^ help: try simplifying it as shown: `x` error: equality checks against false can be replaced by a negation - --> tests/ui/needless_bool/fixable.rs:159:8 + --> tests/ui/needless_bool/fixable.rs:175:8 | LL | if x == false {}; | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:168:12 + --> tests/ui/needless_bool/fixable.rs:185:12 | LL | } else if returns_bool() { | ____________^ @@ -170,7 +170,7 @@ LL | | }; | |_____^ help: you can reduce it to: `{ !returns_bool() }` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:181:5 + --> tests/ui/needless_bool/fixable.rs:199:5 | LL | / if unsafe { no(4) } & 1 != 0 { LL | | true @@ -180,31 +180,31 @@ LL | | }; | |_____^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:186:30 + --> tests/ui/needless_bool/fixable.rs:205:30 | LL | let _brackets_unneeded = if unsafe { no(4) } & 1 != 0 { true } else { false }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `unsafe { no(4) } & 1 != 0` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:189:9 + --> tests/ui/needless_bool/fixable.rs:209:9 | LL | if unsafe { no(4) } & 1 != 0 { true } else { false } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:200:14 + --> tests/ui/needless_bool/fixable.rs:221:14 | LL | let _x = if a && b { true } else { false }.then(|| todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:201:14 + --> tests/ui/needless_bool/fixable.rs:223:14 | LL | let _x = if a && b { true } else { false } as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)` error: this if-then-else expression returns a bool literal - --> tests/ui/needless_bool/fixable.rs:204:14 + --> tests/ui/needless_bool/fixable.rs:227:14 | LL | let _x = if a { true } else { false }.then(|| todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `a` diff --git a/tests/ui/needless_bool/simple.rs b/tests/ui/needless_bool/simple.rs index 588bb88f4461..40ffeae6c56f 100644 --- a/tests/ui/needless_bool/simple.rs +++ b/tests/ui/needless_bool/simple.rs @@ -16,11 +16,13 @@ fn main() { } else { true }; + //~^^^^^ needless_bool if x { false } else { false }; + //~^^^^^ needless_bool if x { x } else { @@ -36,6 +38,7 @@ fn bool_ret(x: bool) -> bool { } else { return true; }; + //~^^^^^ needless_bool } fn bool_ret2(x: bool) -> bool { @@ -44,4 +47,5 @@ fn bool_ret2(x: bool) -> bool { } else { return false; }; + //~^^^^^ needless_bool } diff --git a/tests/ui/needless_bool/simple.stderr b/tests/ui/needless_bool/simple.stderr deleted file mode 100644 index bf30a56f43e7..000000000000 --- a/tests/ui/needless_bool/simple.stderr +++ /dev/null @@ -1,45 +0,0 @@ -error: this if-then-else expression will always return true - --> tests/ui/needless_bool/simple.rs:14:5 - | -LL | / if x { -LL | | true -LL | | } else { -LL | | true -LL | | }; - | |_____^ - | - = note: `-D clippy::needless-bool` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]` - -error: this if-then-else expression will always return false - --> tests/ui/needless_bool/simple.rs:19:5 - | -LL | / if x { -LL | | false -LL | | } else { -LL | | false -LL | | }; - | |_____^ - -error: this if-then-else expression will always return true - --> tests/ui/needless_bool/simple.rs:34:5 - | -LL | / if x { -LL | | return true; -LL | | } else { -LL | | return true; -LL | | }; - | |_____^ - -error: this if-then-else expression will always return false - --> tests/ui/needless_bool/simple.rs:42:5 - | -LL | / if x { -LL | | return false; -LL | | } else { -LL | | return false; -LL | | }; - | |_____^ - -error: aborting due to 4 previous errors - diff --git a/tests/ui/needless_bool_assign.fixed b/tests/ui/needless_bool_assign.fixed index 7b10fe78c681..e0c717ecda21 100644 --- a/tests/ui/needless_bool_assign.fixed +++ b/tests/ui/needless_bool_assign.fixed @@ -11,7 +11,9 @@ fn main() { }; let mut a = Data { field: false }; a.field = random() && random(); + //~^^^^^ needless_bool_assign a.field = !(random() && random()); + //~^^^^^ needless_bool_assign // Do not lint… if random() { a.field = false; @@ -22,6 +24,8 @@ fn main() { // This one also triggers lint `clippy::if_same_then_else` // which does not suggest a rewrite. random(); a.field = true; + //~^^^^^ if_same_then_else + //~| needless_bool_assign let mut b = false; if random() { a.field = false; diff --git a/tests/ui/needless_bool_assign.rs b/tests/ui/needless_bool_assign.rs index 85c0a5777fee..3e4fecefa785 100644 --- a/tests/ui/needless_bool_assign.rs +++ b/tests/ui/needless_bool_assign.rs @@ -15,11 +15,13 @@ fn main() { } else { a.field = false } + //~^^^^^ needless_bool_assign if random() && random() { a.field = false; } else { a.field = true } + //~^^^^^ needless_bool_assign // Do not lint… if random() { a.field = false; @@ -34,6 +36,8 @@ fn main() { } else { a.field = true; } + //~^^^^^ if_same_then_else + //~| needless_bool_assign let mut b = false; if random() { a.field = false; diff --git a/tests/ui/needless_bool_assign.stderr b/tests/ui/needless_bool_assign.stderr deleted file mode 100644 index 2d80dded39c3..000000000000 --- a/tests/ui/needless_bool_assign.stderr +++ /dev/null @@ -1,55 +0,0 @@ -error: this if-then-else expression assigns a bool literal - --> tests/ui/needless_bool_assign.rs:13:5 - | -LL | / if random() && random() { -LL | | a.field = true; -LL | | } else { -LL | | a.field = false -LL | | } - | |_____^ help: you can reduce it to: `a.field = random() && random();` - | - = note: `-D clippy::needless-bool-assign` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::needless_bool_assign)]` - -error: this if-then-else expression assigns a bool literal - --> tests/ui/needless_bool_assign.rs:18:5 - | -LL | / if random() && random() { -LL | | a.field = false; -LL | | } else { -LL | | a.field = true -LL | | } - | |_____^ help: you can reduce it to: `a.field = !(random() && random());` - -error: this if-then-else expression assigns a bool literal - --> tests/ui/needless_bool_assign.rs:32:5 - | -LL | / if random() { -LL | | a.field = true; -LL | | } else { -LL | | a.field = true; -LL | | } - | |_____^ help: you can reduce it to: `random(); a.field = true;` - -error: this `if` has identical blocks - --> tests/ui/needless_bool_assign.rs:32:17 - | -LL | if random() { - | _________________^ -LL | | a.field = true; -LL | | } else { - | |_____^ - | -note: same as this - --> tests/ui/needless_bool_assign.rs:34:12 - | -LL | } else { - | ____________^ -LL | | a.field = true; -LL | | } - | |_____^ - = note: `-D clippy::if-same-then-else` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]` - -error: aborting due to 4 previous errors - diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed index 2763830e09c9..7bd42d17f3a4 100644 --- a/tests/ui/needless_borrow.fixed +++ b/tests/ui/needless_borrow.fixed @@ -14,10 +14,12 @@ fn main() { let ref_a = &a; let _ = x(&a); // no warning let _ = x(&a); // warn + //~^ needless_borrow let mut b = 5; mut_ref(&mut b); // no warning mut_ref(&mut b); // warn + //~^ needless_borrow let s = &String::from("hi"); let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not @@ -30,14 +32,17 @@ fn main() { 45 => { println!("foo"); &a + //~^ needless_borrow }, 46 => &a, + //~^ needless_borrow 47 => { println!("foo"); loop { println!("{}", a); if a == 25 { break ref_a; + //~^ needless_borrow } } }, @@ -45,12 +50,17 @@ fn main() { }; let _ = x(&a); + //~^ needless_borrow let _ = x(&a); + //~^ needless_borrow let _ = x(&mut b); + //~^ needless_borrow let _ = x(ref_a); + //~^ needless_borrow { let b = &mut b; x(b); + //~^ needless_borrow } // Issue #8191 @@ -58,9 +68,13 @@ fn main() { let mut x = &mut x; mut_ref(x); + //~^ needless_borrow mut_ref(x); + //~^ needless_borrow let y: &mut i32 = x; + //~^ needless_borrow let y: &mut i32 = x; + //~^ needless_borrow let y = match 0 { // Don't lint. Removing the borrow would move 'x' @@ -70,12 +84,14 @@ fn main() { let y: &mut i32 = match 0 { // Lint here. The type given above triggers auto-borrow. 0 => x, + //~^ needless_borrow _ => &mut *x, }; fn ref_mut_i32(_: &mut i32) {} ref_mut_i32(match 0 { // Lint here. The type given above triggers auto-borrow. 0 => x, + //~^ needless_borrow _ => &mut *x, }); // use 'x' after to make sure it's still usable in the fixed code. @@ -88,8 +104,10 @@ fn main() { let x = (1, 2); let _ = x.0; + //~^ needless_borrow let x = &x as *const (i32, i32); let _ = unsafe { (*x).0 }; + //~^ needless_borrow // Issue #8367 trait Foo { @@ -100,6 +118,7 @@ fn main() { } (&()).foo(); // Don't lint. `()` doesn't implement `Foo` (&()).foo(); + //~^ needless_borrow impl Foo for i32 { fn foo(self) {} @@ -109,6 +128,7 @@ fn main() { } (&5).foo(); // Don't lint. `5` will call `::foo` (&5).foo(); + //~^ needless_borrow trait FooRef { fn foo_ref(&self); @@ -135,6 +155,7 @@ fn main() { // issue #11786 let x: (&str,) = ("",); + //~^ needless_borrow } #[allow(clippy::needless_borrowed_reference)] @@ -177,6 +198,7 @@ mod issue9160 { { fn calls_field(&self) -> T { (self.f)() + //~^ needless_borrow } } @@ -186,6 +208,7 @@ mod issue9160 { { fn calls_mut_field(&mut self) -> T { (self.f)() + //~^ needless_borrow } } } @@ -223,6 +246,7 @@ fn issue9383() { }; let _ = &mut (&mut x.u).x; let _ = &mut { x.u }.x; + //~^ needless_borrow let _ = &mut ({ &mut x.u }).x; let mut x = U { @@ -230,11 +254,14 @@ fn issue9383() { }; let _ = &mut (&mut x.u).x; let _ = &mut { x.u }.x; + //~^ needless_borrow let _ = &mut ({ &mut x.u }).x; let mut x = U { u: Wrap(Foo { x: 0 }) }; let _ = &mut x.u.x; + //~^ needless_borrow let _ = &mut { x.u }.x; + //~^ needless_borrow let _ = &mut ({ &mut x.u }).x; } } @@ -256,6 +283,7 @@ fn issue_12268() { let option = Some((&1,)); let x = (&1,); option.unwrap_or((x.0,)); - //~^ ERROR: this expression creates a reference which is immediately dereferenced by the + //~^ needless_borrow + // compiler } diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs index b46f82b18c64..a5b337140b5b 100644 --- a/tests/ui/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -14,10 +14,12 @@ fn main() { let ref_a = &a; let _ = x(&a); // no warning let _ = x(&&a); // warn + //~^ needless_borrow let mut b = 5; mut_ref(&mut b); // no warning mut_ref(&mut &mut b); // warn + //~^ needless_borrow let s = &String::from("hi"); let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not @@ -30,14 +32,17 @@ fn main() { 45 => { println!("foo"); &&a + //~^ needless_borrow }, 46 => &&a, + //~^ needless_borrow 47 => { println!("foo"); loop { println!("{}", a); if a == 25 { break &ref_a; + //~^ needless_borrow } } }, @@ -45,12 +50,17 @@ fn main() { }; let _ = x(&&&a); + //~^ needless_borrow let _ = x(&mut &&a); + //~^ needless_borrow let _ = x(&&&mut b); + //~^ needless_borrow let _ = x(&&ref_a); + //~^ needless_borrow { let b = &mut b; x(&b); + //~^ needless_borrow } // Issue #8191 @@ -58,9 +68,13 @@ fn main() { let mut x = &mut x; mut_ref(&mut x); + //~^ needless_borrow mut_ref(&mut &mut x); + //~^ needless_borrow let y: &mut i32 = &mut x; + //~^ needless_borrow let y: &mut i32 = &mut &mut x; + //~^ needless_borrow let y = match 0 { // Don't lint. Removing the borrow would move 'x' @@ -70,12 +84,14 @@ fn main() { let y: &mut i32 = match 0 { // Lint here. The type given above triggers auto-borrow. 0 => &mut x, + //~^ needless_borrow _ => &mut *x, }; fn ref_mut_i32(_: &mut i32) {} ref_mut_i32(match 0 { // Lint here. The type given above triggers auto-borrow. 0 => &mut x, + //~^ needless_borrow _ => &mut *x, }); // use 'x' after to make sure it's still usable in the fixed code. @@ -88,8 +104,10 @@ fn main() { let x = (1, 2); let _ = (&x).0; + //~^ needless_borrow let x = &x as *const (i32, i32); let _ = unsafe { (&*x).0 }; + //~^ needless_borrow // Issue #8367 trait Foo { @@ -100,6 +118,7 @@ fn main() { } (&()).foo(); // Don't lint. `()` doesn't implement `Foo` (&&()).foo(); + //~^ needless_borrow impl Foo for i32 { fn foo(self) {} @@ -109,6 +128,7 @@ fn main() { } (&5).foo(); // Don't lint. `5` will call `::foo` (&&5).foo(); + //~^ needless_borrow trait FooRef { fn foo_ref(&self); @@ -135,6 +155,7 @@ fn main() { // issue #11786 let x: (&str,) = (&"",); + //~^ needless_borrow } #[allow(clippy::needless_borrowed_reference)] @@ -177,6 +198,7 @@ mod issue9160 { { fn calls_field(&self) -> T { (&self.f)() + //~^ needless_borrow } } @@ -186,6 +208,7 @@ mod issue9160 { { fn calls_mut_field(&mut self) -> T { (&mut self.f)() + //~^ needless_borrow } } } @@ -223,6 +246,7 @@ fn issue9383() { }; let _ = &mut (&mut x.u).x; let _ = &mut (&mut { x.u }).x; + //~^ needless_borrow let _ = &mut ({ &mut x.u }).x; let mut x = U { @@ -230,11 +254,14 @@ fn issue9383() { }; let _ = &mut (&mut x.u).x; let _ = &mut (&mut { x.u }).x; + //~^ needless_borrow let _ = &mut ({ &mut x.u }).x; let mut x = U { u: Wrap(Foo { x: 0 }) }; let _ = &mut (&mut x.u).x; + //~^ needless_borrow let _ = &mut (&mut { x.u }).x; + //~^ needless_borrow let _ = &mut ({ &mut x.u }).x; } } @@ -256,6 +283,7 @@ fn issue_12268() { let option = Some((&1,)); let x = (&1,); option.unwrap_or((&x.0,)); - //~^ ERROR: this expression creates a reference which is immediately dereferenced by the + //~^ needless_borrow + // compiler } diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr index 4b2b17e7e570..b574948962de 100644 --- a/tests/ui/needless_borrow.stderr +++ b/tests/ui/needless_borrow.stderr @@ -8,163 +8,163 @@ LL | let _ = x(&&a); // warn = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:20:13 + --> tests/ui/needless_borrow.rs:21:13 | LL | mut_ref(&mut &mut b); // warn | ^^^^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:32:13 + --> tests/ui/needless_borrow.rs:34:13 | LL | &&a | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:34:15 + --> tests/ui/needless_borrow.rs:37:15 | LL | 46 => &&a, | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:40:27 + --> tests/ui/needless_borrow.rs:44:27 | LL | break &ref_a; | ^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:47:15 + --> tests/ui/needless_borrow.rs:52:15 | LL | let _ = x(&&&a); | ^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:48:15 + --> tests/ui/needless_borrow.rs:54:15 | LL | let _ = x(&mut &&a); | ^^^^^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:49:15 + --> tests/ui/needless_borrow.rs:56:15 | LL | let _ = x(&&&mut b); | ^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:50:15 + --> tests/ui/needless_borrow.rs:58:15 | LL | let _ = x(&&ref_a); | ^^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:53:11 + --> tests/ui/needless_borrow.rs:62:11 | LL | x(&b); | ^^ help: change this to: `b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:60:13 + --> tests/ui/needless_borrow.rs:70:13 | LL | mut_ref(&mut x); | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:61:13 + --> tests/ui/needless_borrow.rs:72:13 | LL | mut_ref(&mut &mut x); | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:62:23 + --> tests/ui/needless_borrow.rs:74:23 | LL | let y: &mut i32 = &mut x; | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:63:23 + --> tests/ui/needless_borrow.rs:76:23 | LL | let y: &mut i32 = &mut &mut x; | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:72:14 + --> tests/ui/needless_borrow.rs:86:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:78:14 + --> tests/ui/needless_borrow.rs:93:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:90:13 + --> tests/ui/needless_borrow.rs:106:13 | LL | let _ = (&x).0; | ^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:92:22 + --> tests/ui/needless_borrow.rs:109:22 | LL | let _ = unsafe { (&*x).0 }; | ^^^^^ help: change this to: `(*x)` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:102:5 + --> tests/ui/needless_borrow.rs:120:5 | LL | (&&()).foo(); | ^^^^^^ help: change this to: `(&())` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:111:5 + --> tests/ui/needless_borrow.rs:130:5 | LL | (&&5).foo(); | ^^^^^ help: change this to: `(&5)` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:137:23 + --> tests/ui/needless_borrow.rs:157:23 | LL | let x: (&str,) = (&"",); | ^^^ help: change this to: `""` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:179:13 + --> tests/ui/needless_borrow.rs:200:13 | LL | (&self.f)() | ^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:188:13 + --> tests/ui/needless_borrow.rs:210:13 | LL | (&mut self.f)() | ^^^^^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:225:22 + --> tests/ui/needless_borrow.rs:248:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:232:22 + --> tests/ui/needless_borrow.rs:256:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:236:22 + --> tests/ui/needless_borrow.rs:261:22 | LL | let _ = &mut (&mut x.u).x; | ^^^^^^^^^^ help: change this to: `x.u` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:237:22 + --> tests/ui/needless_borrow.rs:263:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:258:23 + --> tests/ui/needless_borrow.rs:285:23 | LL | option.unwrap_or((&x.0,)); | ^^^^ help: change this to: `x.0` diff --git a/tests/ui/needless_borrow_pat.fixed b/tests/ui/needless_borrow_pat.fixed index 8f8887f08a27..d067f1c6016b 100644 --- a/tests/ui/needless_borrow_pat.fixed +++ b/tests/ui/needless_borrow_pat.fixed @@ -57,22 +57,25 @@ fn main() { // Err, reference to a &String let _: &String = match Some(&x) { Some(x) => x, - //~^ ERROR: this pattern creates a reference to a reference - //~| NOTE: `-D clippy::needless-borrow` implied by `-D warnings` + //~^ needless_borrow + + None => return, }; // Err, reference to a &String. let _: &String = match Some(&x) { Some(x) => x, - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + None => return, }; // Err, reference to a &String let _: &String = match Some(&x) { Some(x) => { - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + f1(x); f1(x); x @@ -83,19 +86,22 @@ fn main() { // Err, reference to a &String match Some(&x) { Some(x) => m1!(x), - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + None => return, }; // Err, reference to a &String let _ = |&x: &&String| { - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + let _: &String = x; }; // Err, reference to a &String let (y,) = (&x,); - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + let _: &String = y; let y = &&x; @@ -106,7 +112,8 @@ fn main() { // Err, reference to a &u32. Don't suggest adding a reference to the field access. let _: u32 = match Some(&x) { Some(x) => x.0, - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + None => return, }; @@ -117,14 +124,16 @@ fn main() { // Err, reference to &u32. let _: &u32 = match E::A(&0) { E::A(x) | E::B(x) => x, - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + }; // Err, reference to &String. if_chain! { if true; if let Some(x) = Some(&String::new()); - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + then { f1(x); } @@ -133,7 +142,8 @@ fn main() { // Err, reference to a &String fn f2<'a>(&x: &&'a String) -> &'a String { - //~^ ERROR: this pattern creates a reference to a reference +//~^ needless_borrow + let _: &String = x; x } @@ -141,7 +151,8 @@ fn f2<'a>(&x: &&'a String) -> &'a String { trait T1 { // Err, reference to a &String fn f(&x: &&String) { - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + let _: &String = x; } } @@ -150,7 +161,8 @@ struct S; impl T1 for S { // Err, reference to a &String fn f(&x: &&String) { - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + let _: &String = x; } } diff --git a/tests/ui/needless_borrow_pat.rs b/tests/ui/needless_borrow_pat.rs index 56dbd923f256..7c39183d7916 100644 --- a/tests/ui/needless_borrow_pat.rs +++ b/tests/ui/needless_borrow_pat.rs @@ -57,22 +57,25 @@ fn main() { // Err, reference to a &String let _: &String = match Some(&x) { Some(ref x) => x, - //~^ ERROR: this pattern creates a reference to a reference - //~| NOTE: `-D clippy::needless-borrow` implied by `-D warnings` + //~^ needless_borrow + + None => return, }; // Err, reference to a &String. let _: &String = match Some(&x) { Some(ref x) => *x, - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + None => return, }; // Err, reference to a &String let _: &String = match Some(&x) { Some(ref x) => { - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + f1(x); f1(*x); x @@ -83,19 +86,22 @@ fn main() { // Err, reference to a &String match Some(&x) { Some(ref x) => m1!(x), - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + None => return, }; // Err, reference to a &String let _ = |&ref x: &&String| { - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + let _: &String = x; }; // Err, reference to a &String let (ref y,) = (&x,); - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + let _: &String = *y; let y = &&x; @@ -106,7 +112,8 @@ fn main() { // Err, reference to a &u32. Don't suggest adding a reference to the field access. let _: u32 = match Some(&x) { Some(ref x) => x.0, - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + None => return, }; @@ -117,14 +124,16 @@ fn main() { // Err, reference to &u32. let _: &u32 = match E::A(&0) { E::A(ref x) | E::B(ref x) => *x, - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + }; // Err, reference to &String. if_chain! { if true; if let Some(ref x) = Some(&String::new()); - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + then { f1(x); } @@ -133,7 +142,8 @@ fn main() { // Err, reference to a &String fn f2<'a>(&ref x: &&'a String) -> &'a String { - //~^ ERROR: this pattern creates a reference to a reference +//~^ needless_borrow + let _: &String = x; *x } @@ -141,7 +151,8 @@ fn f2<'a>(&ref x: &&'a String) -> &'a String { trait T1 { // Err, reference to a &String fn f(&ref x: &&String) { - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + let _: &String = x; } } @@ -150,7 +161,8 @@ struct S; impl T1 for S { // Err, reference to a &String fn f(&ref x: &&String) { - //~^ ERROR: this pattern creates a reference to a reference + //~^ needless_borrow + let _: &String = *x; } } diff --git a/tests/ui/needless_borrow_pat.stderr b/tests/ui/needless_borrow_pat.stderr index 2ad694490396..7e1b3694e30f 100644 --- a/tests/ui/needless_borrow_pat.stderr +++ b/tests/ui/needless_borrow_pat.stderr @@ -8,7 +8,7 @@ LL | Some(ref x) => x, = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:67:14 + --> tests/ui/needless_borrow_pat.rs:68:14 | LL | Some(ref x) => *x, | ^^^^^ @@ -19,7 +19,7 @@ LL | Some(x) => x, | ~ ~ error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:74:14 + --> tests/ui/needless_borrow_pat.rs:76:14 | LL | Some(ref x) => { | ^^^^^ @@ -28,24 +28,25 @@ help: try | LL ~ Some(x) => { LL | +LL | LL | f1(x); LL ~ f1(x); | error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:85:14 + --> tests/ui/needless_borrow_pat.rs:88:14 | LL | Some(ref x) => m1!(x), | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:91:15 + --> tests/ui/needless_borrow_pat.rs:95:15 | LL | let _ = |&ref x: &&String| { | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:97:10 + --> tests/ui/needless_borrow_pat.rs:102:10 | LL | let (ref y,) = (&x,); | ^^^^^ @@ -54,17 +55,18 @@ help: try | LL ~ let (y,) = (&x,); LL | +LL | LL ~ let _: &String = y; | error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:108:14 + --> tests/ui/needless_borrow_pat.rs:114:14 | LL | Some(ref x) => x.0, | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:119:14 + --> tests/ui/needless_borrow_pat.rs:126:14 | LL | E::A(ref x) | E::B(ref x) => *x, | ^^^^^ ^^^^^ @@ -75,13 +77,13 @@ LL | E::A(x) | E::B(x) => x, | ~ ~ ~ error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:126:21 + --> tests/ui/needless_borrow_pat.rs:134:21 | LL | if let Some(ref x) = Some(&String::new()); | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:135:12 + --> tests/ui/needless_borrow_pat.rs:144:12 | LL | fn f2<'a>(&ref x: &&'a String) -> &'a String { | ^^^^^ @@ -90,18 +92,19 @@ help: try | LL ~ fn f2<'a>(&x: &&'a String) -> &'a String { LL | +LL | LL | let _: &String = x; LL ~ x | error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:143:11 + --> tests/ui/needless_borrow_pat.rs:153:11 | LL | fn f(&ref x: &&String) { | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:152:11 + --> tests/ui/needless_borrow_pat.rs:163:11 | LL | fn f(&ref x: &&String) { | ^^^^^ @@ -110,6 +113,7 @@ help: try | LL ~ fn f(&x: &&String) { LL | +LL | LL ~ let _: &String = x; | diff --git a/tests/ui/needless_borrowed_ref.fixed b/tests/ui/needless_borrowed_ref.fixed index 5d2fd0950ee4..1cad115e96d1 100644 --- a/tests/ui/needless_borrowed_ref.fixed +++ b/tests/ui/needless_borrowed_ref.fixed @@ -28,32 +28,48 @@ fn should_lint( ) { let mut v = Vec::::new(); let _ = v.iter_mut().filter(|a| a.is_empty()); + //~^ needless_borrowed_reference let var = 3; let thingy = Some(&var); if let Some(v) = thingy {} + //~^ needless_borrowed_reference if let &[a, ref b] = slice_of_refs {} + //~^ needless_borrowed_reference let [a, ..] = &array; + //~^ needless_borrowed_reference let [a, b, ..] = &array; + //~^ needless_borrowed_reference if let [a, b] = slice {} + //~^ needless_borrowed_reference if let [a, b] = &vec[..] {} + //~^ needless_borrowed_reference if let [a, b, ..] = slice {} + //~^ needless_borrowed_reference if let [a, .., b] = slice {} + //~^ needless_borrowed_reference if let [.., a, b] = slice {} + //~^ needless_borrowed_reference if let [a, _] = slice {} + //~^ needless_borrowed_reference if let (a, b, c) = &tuple {} + //~^ needless_borrowed_reference if let (a, _, c) = &tuple {} + //~^ needless_borrowed_reference if let (a, ..) = &tuple {} + //~^ needless_borrowed_reference if let TupleStruct(a, ..) = &tuple_struct {} + //~^ needless_borrowed_reference if let Struct { + //~^ needless_borrowed_reference a, b: b, c: renamed, @@ -61,6 +77,7 @@ fn should_lint( {} if let Struct { a, b: _, .. } = &s {} + //~^ needless_borrowed_reference } fn should_not_lint( diff --git a/tests/ui/needless_borrowed_ref.rs b/tests/ui/needless_borrowed_ref.rs index 556fd3a35427..ae6377fd4421 100644 --- a/tests/ui/needless_borrowed_ref.rs +++ b/tests/ui/needless_borrowed_ref.rs @@ -28,32 +28,48 @@ fn should_lint( ) { let mut v = Vec::::new(); let _ = v.iter_mut().filter(|&ref a| a.is_empty()); + //~^ needless_borrowed_reference let var = 3; let thingy = Some(&var); if let Some(&ref v) = thingy {} + //~^ needless_borrowed_reference if let &[&ref a, ref b] = slice_of_refs {} + //~^ needless_borrowed_reference let &[ref a, ..] = &array; + //~^ needless_borrowed_reference let &[ref a, ref b, ..] = &array; + //~^ needless_borrowed_reference if let &[ref a, ref b] = slice {} + //~^ needless_borrowed_reference if let &[ref a, ref b] = &vec[..] {} + //~^ needless_borrowed_reference if let &[ref a, ref b, ..] = slice {} + //~^ needless_borrowed_reference if let &[ref a, .., ref b] = slice {} + //~^ needless_borrowed_reference if let &[.., ref a, ref b] = slice {} + //~^ needless_borrowed_reference if let &[ref a, _] = slice {} + //~^ needless_borrowed_reference if let &(ref a, ref b, ref c) = &tuple {} + //~^ needless_borrowed_reference if let &(ref a, _, ref c) = &tuple {} + //~^ needless_borrowed_reference if let &(ref a, ..) = &tuple {} + //~^ needless_borrowed_reference if let &TupleStruct(ref a, ..) = &tuple_struct {} + //~^ needless_borrowed_reference if let &Struct { + //~^ needless_borrowed_reference ref a, b: ref b, c: ref renamed, @@ -61,6 +77,7 @@ fn should_lint( {} if let &Struct { ref a, b: _, .. } = &s {} + //~^ needless_borrowed_reference } fn should_not_lint( diff --git a/tests/ui/needless_borrowed_ref.stderr b/tests/ui/needless_borrowed_ref.stderr index b8181e2805c9..bfa3cafdedeb 100644 --- a/tests/ui/needless_borrowed_ref.stderr +++ b/tests/ui/needless_borrowed_ref.stderr @@ -13,7 +13,7 @@ LL + let _ = v.iter_mut().filter(|a| a.is_empty()); | error: this pattern takes a reference on something that is being dereferenced - --> tests/ui/needless_borrowed_ref.rs:34:17 + --> tests/ui/needless_borrowed_ref.rs:35:17 | LL | if let Some(&ref v) = thingy {} | ^^^^^^ @@ -25,7 +25,7 @@ LL + if let Some(v) = thingy {} | error: this pattern takes a reference on something that is being dereferenced - --> tests/ui/needless_borrowed_ref.rs:36:14 + --> tests/ui/needless_borrowed_ref.rs:38:14 | LL | if let &[&ref a, ref b] = slice_of_refs {} | ^^^^^^ @@ -37,7 +37,7 @@ LL + if let &[a, ref b] = slice_of_refs {} | error: dereferencing a slice pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:38:9 + --> tests/ui/needless_borrowed_ref.rs:41:9 | LL | let &[ref a, ..] = &array; | ^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + let [a, ..] = &array; | error: dereferencing a slice pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:39:9 + --> tests/ui/needless_borrowed_ref.rs:43:9 | LL | let &[ref a, ref b, ..] = &array; | ^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + let [a, b, ..] = &array; | error: dereferencing a slice pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:41:12 + --> tests/ui/needless_borrowed_ref.rs:46:12 | LL | if let &[ref a, ref b] = slice {} | ^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + if let [a, b] = slice {} | error: dereferencing a slice pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:42:12 + --> tests/ui/needless_borrowed_ref.rs:48:12 | LL | if let &[ref a, ref b] = &vec[..] {} | ^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + if let [a, b] = &vec[..] {} | error: dereferencing a slice pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:44:12 + --> tests/ui/needless_borrowed_ref.rs:51:12 | LL | if let &[ref a, ref b, ..] = slice {} | ^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL + if let [a, b, ..] = slice {} | error: dereferencing a slice pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:45:12 + --> tests/ui/needless_borrowed_ref.rs:53:12 | LL | if let &[ref a, .., ref b] = slice {} | ^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL + if let [a, .., b] = slice {} | error: dereferencing a slice pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:46:12 + --> tests/ui/needless_borrowed_ref.rs:55:12 | LL | if let &[.., ref a, ref b] = slice {} | ^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL + if let [.., a, b] = slice {} | error: dereferencing a slice pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:48:12 + --> tests/ui/needless_borrowed_ref.rs:58:12 | LL | if let &[ref a, _] = slice {} | ^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL + if let [a, _] = slice {} | error: dereferencing a tuple pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:50:12 + --> tests/ui/needless_borrowed_ref.rs:61:12 | LL | if let &(ref a, ref b, ref c) = &tuple {} | ^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL + if let (a, b, c) = &tuple {} | error: dereferencing a tuple pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:51:12 + --> tests/ui/needless_borrowed_ref.rs:63:12 | LL | if let &(ref a, _, ref c) = &tuple {} | ^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL + if let (a, _, c) = &tuple {} | error: dereferencing a tuple pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:52:12 + --> tests/ui/needless_borrowed_ref.rs:65:12 | LL | if let &(ref a, ..) = &tuple {} | ^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL + if let (a, ..) = &tuple {} | error: dereferencing a tuple pattern where every element takes a reference - --> tests/ui/needless_borrowed_ref.rs:54:12 + --> tests/ui/needless_borrowed_ref.rs:68:12 | LL | if let &TupleStruct(ref a, ..) = &tuple_struct {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,10 +181,11 @@ LL + if let TupleStruct(a, ..) = &tuple_struct {} | error: dereferencing a struct pattern where every field's pattern takes a reference - --> tests/ui/needless_borrowed_ref.rs:56:12 + --> tests/ui/needless_borrowed_ref.rs:71:12 | LL | if let &Struct { | ____________^ +LL | | LL | | ref a, LL | | b: ref b, LL | | c: ref renamed, @@ -194,13 +195,14 @@ LL | | } = &s help: try removing the `&` and `ref` parts | LL ~ if let Struct { +LL | LL ~ a, LL ~ b: b, LL ~ c: renamed, | error: dereferencing a struct pattern where every field's pattern takes a reference - --> tests/ui/needless_borrowed_ref.rs:63:12 + --> tests/ui/needless_borrowed_ref.rs:79:12 | LL | if let &Struct { ref a, b: _, .. } = &s {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/needless_borrows_for_generic_args.fixed b/tests/ui/needless_borrows_for_generic_args.fixed index c1dc8b5e8d09..374caeacfd28 100644 --- a/tests/ui/needless_borrows_for_generic_args.fixed +++ b/tests/ui/needless_borrows_for_generic_args.fixed @@ -14,11 +14,14 @@ use std::process::Command; fn main() { let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap(); + //~^ needless_borrows_for_generic_args let _ = Path::new(".").join("."); + //~^ needless_borrows_for_generic_args let _ = Any::type_id(&""); // Don't lint. `Any` is only bound let _ = Box::new(&""); // Don't lint. Type parameter appears in return type let _ = Some("").unwrap_or(&""); let _ = std::fs::write("x", "".to_string()); + //~^ needless_borrows_for_generic_args { #[derive(Clone, Copy)] @@ -34,6 +37,7 @@ fn main() { fn deref_target_is_x>(_: T) {} deref_target_is_x(X); + //~^ needless_borrows_for_generic_args } { fn multiple_constraints(_: T) @@ -47,6 +51,7 @@ fn main() { } multiple_constraints([[""]]); + //~^ needless_borrows_for_generic_args } { #[derive(Clone, Copy)] @@ -67,6 +72,7 @@ fn main() { } multiple_constraints_normalizes_to_same(X, X); + //~^ needless_borrows_for_generic_args } { fn only_sized(_: T) {} @@ -125,6 +131,7 @@ fn main() { #[allow(unused_mut)] fn warn(mut x: &mut Iter) { takes_iter(x) + //~^ needless_borrows_for_generic_args } } #[clippy::msrv = "1.52.0"] @@ -134,6 +141,7 @@ fn main() { #[clippy::msrv = "1.53.0"] { let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap(); + //~^ needless_borrows_for_generic_args }; { let env = "env".to_owned(); @@ -245,6 +253,7 @@ fn main() { // 8 foo::<&[u8; 100]>(&a); foo(a); + //~^ needless_borrows_for_generic_args } { struct S; @@ -329,9 +338,11 @@ fn main() { let x = String::new(); f(&x); // Don't lint, not a copy, makes it unavailable later f(String::new()); // Lint, makes no difference + //~^ needless_borrows_for_generic_args let y = "".to_owned(); f(&y); // Don't lint f("".to_owned()); // Lint + //~^ needless_borrows_for_generic_args } { fn takes_writer(_: T) {} diff --git a/tests/ui/needless_borrows_for_generic_args.rs b/tests/ui/needless_borrows_for_generic_args.rs index c7f66824d581..06e2a4505211 100644 --- a/tests/ui/needless_borrows_for_generic_args.rs +++ b/tests/ui/needless_borrows_for_generic_args.rs @@ -14,11 +14,14 @@ use std::process::Command; fn main() { let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap(); + //~^ needless_borrows_for_generic_args let _ = Path::new(".").join(&&"."); + //~^ needless_borrows_for_generic_args let _ = Any::type_id(&""); // Don't lint. `Any` is only bound let _ = Box::new(&""); // Don't lint. Type parameter appears in return type let _ = Some("").unwrap_or(&""); let _ = std::fs::write("x", &"".to_string()); + //~^ needless_borrows_for_generic_args { #[derive(Clone, Copy)] @@ -34,6 +37,7 @@ fn main() { fn deref_target_is_x>(_: T) {} deref_target_is_x(&X); + //~^ needless_borrows_for_generic_args } { fn multiple_constraints(_: T) @@ -47,6 +51,7 @@ fn main() { } multiple_constraints(&[[""]]); + //~^ needless_borrows_for_generic_args } { #[derive(Clone, Copy)] @@ -67,6 +72,7 @@ fn main() { } multiple_constraints_normalizes_to_same(&X, X); + //~^ needless_borrows_for_generic_args } { fn only_sized(_: T) {} @@ -125,6 +131,7 @@ fn main() { #[allow(unused_mut)] fn warn(mut x: &mut Iter) { takes_iter(&mut x) + //~^ needless_borrows_for_generic_args } } #[clippy::msrv = "1.52.0"] @@ -134,6 +141,7 @@ fn main() { #[clippy::msrv = "1.53.0"] { let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap(); + //~^ needless_borrows_for_generic_args }; { let env = "env".to_owned(); @@ -245,6 +253,7 @@ fn main() { // 8 foo::<&[u8; 100]>(&a); foo(&a); + //~^ needless_borrows_for_generic_args } { struct S; @@ -329,9 +338,11 @@ fn main() { let x = String::new(); f(&x); // Don't lint, not a copy, makes it unavailable later f(&String::new()); // Lint, makes no difference + //~^ needless_borrows_for_generic_args let y = "".to_owned(); f(&y); // Don't lint f(&"".to_owned()); // Lint + //~^ needless_borrows_for_generic_args } { fn takes_writer(_: T) {} diff --git a/tests/ui/needless_borrows_for_generic_args.stderr b/tests/ui/needless_borrows_for_generic_args.stderr index fba0755d14b5..6b5a0b4b1b67 100644 --- a/tests/ui/needless_borrows_for_generic_args.stderr +++ b/tests/ui/needless_borrows_for_generic_args.stderr @@ -8,61 +8,61 @@ LL | let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::needless_borrows_for_generic_args)]` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:17:33 + --> tests/ui/needless_borrows_for_generic_args.rs:18:33 | LL | let _ = Path::new(".").join(&&"."); | ^^^^^ help: change this to: `"."` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:21:33 + --> tests/ui/needless_borrows_for_generic_args.rs:23:33 | LL | let _ = std::fs::write("x", &"".to_string()); | ^^^^^^^^^^^^^^^ help: change this to: `"".to_string()` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:36:27 + --> tests/ui/needless_borrows_for_generic_args.rs:39:27 | LL | deref_target_is_x(&X); | ^^ help: change this to: `X` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:49:30 + --> tests/ui/needless_borrows_for_generic_args.rs:53:30 | LL | multiple_constraints(&[[""]]); | ^^^^^^^ help: change this to: `[[""]]` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:69:49 + --> tests/ui/needless_borrows_for_generic_args.rs:74:49 | LL | multiple_constraints_normalizes_to_same(&X, X); | ^^ help: change this to: `X` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:127:24 + --> tests/ui/needless_borrows_for_generic_args.rs:133:24 | LL | takes_iter(&mut x) | ^^^^^^ help: change this to: `x` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:136:41 + --> tests/ui/needless_borrows_for_generic_args.rs:143:41 | LL | let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap(); | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:247:13 + --> tests/ui/needless_borrows_for_generic_args.rs:255:13 | LL | foo(&a); | ^^ help: change this to: `a` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:331:11 + --> tests/ui/needless_borrows_for_generic_args.rs:340:11 | LL | f(&String::new()); // Lint, makes no difference | ^^^^^^^^^^^^^^ help: change this to: `String::new()` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:334:11 + --> tests/ui/needless_borrows_for_generic_args.rs:344:11 | LL | f(&"".to_owned()); // Lint | ^^^^^^^^^^^^^^ help: change this to: `"".to_owned()` diff --git a/tests/ui/needless_character_iteration.fixed b/tests/ui/needless_character_iteration.fixed index f0bf84a41d7e..584b578fa8be 100644 --- a/tests/ui/needless_character_iteration.fixed +++ b/tests/ui/needless_character_iteration.fixed @@ -16,25 +16,32 @@ fn magic(_: char) {} fn main() { "foo".is_ascii(); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + !"foo".is_ascii(); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + "foo".is_ascii(); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + !"foo".is_ascii(); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + let s = String::new(); s.is_ascii(); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + !"foo".to_string().is_ascii(); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + "foo".is_ascii(); !"foo".is_ascii(); S::default().field().is_ascii(); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + // Should not lint! "foo".chars().all(|c| { diff --git a/tests/ui/needless_character_iteration.rs b/tests/ui/needless_character_iteration.rs index 2805d2438b4a..1ef5c3a79a3e 100644 --- a/tests/ui/needless_character_iteration.rs +++ b/tests/ui/needless_character_iteration.rs @@ -16,33 +16,42 @@ fn magic(_: char) {} fn main() { "foo".chars().all(|c| c.is_ascii()); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + "foo".chars().any(|c| !c.is_ascii()); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + "foo".chars().all(|c| char::is_ascii(&c)); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + "foo".chars().any(|c| !char::is_ascii(&c)); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + let s = String::new(); s.chars().all(|c| c.is_ascii()); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + "foo".to_string().chars().any(|c| !c.is_ascii()); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + "foo".chars().all(|c| { - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + let x = c; x.is_ascii() }); "foo".chars().any(|c| { - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + let x = c; !x.is_ascii() }); S::default().field().chars().all(|x| x.is_ascii()); - //~^ ERROR: checking if a string is ascii using iterators + //~^ needless_character_iteration + // Should not lint! "foo".chars().all(|c| { diff --git a/tests/ui/needless_character_iteration.stderr b/tests/ui/needless_character_iteration.stderr index 7966033555f5..29e5a674e0c5 100644 --- a/tests/ui/needless_character_iteration.stderr +++ b/tests/ui/needless_character_iteration.stderr @@ -8,57 +8,59 @@ LL | "foo".chars().all(|c| c.is_ascii()); = help: to override `-D warnings` add `#[allow(clippy::needless_character_iteration)]` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:20:5 + --> tests/ui/needless_character_iteration.rs:21:5 | LL | "foo".chars().any(|c| !c.is_ascii()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:22:5 + --> tests/ui/needless_character_iteration.rs:24:5 | LL | "foo".chars().all(|c| char::is_ascii(&c)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"foo".is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:24:5 + --> tests/ui/needless_character_iteration.rs:27:5 | LL | "foo".chars().any(|c| !char::is_ascii(&c)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:28:5 + --> tests/ui/needless_character_iteration.rs:32:5 | LL | s.chars().all(|c| c.is_ascii()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:30:5 + --> tests/ui/needless_character_iteration.rs:35:5 | LL | "foo".to_string().chars().any(|c| !c.is_ascii()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".to_string().is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:33:5 + --> tests/ui/needless_character_iteration.rs:39:5 | LL | / "foo".chars().all(|c| { LL | | +LL | | LL | | let x = c; LL | | x.is_ascii() LL | | }); | |______^ help: try: `"foo".is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:38:5 + --> tests/ui/needless_character_iteration.rs:45:5 | LL | / "foo".chars().any(|c| { LL | | +LL | | LL | | let x = c; LL | | !x.is_ascii() LL | | }); | |______^ help: try: `!"foo".is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:44:5 + --> tests/ui/needless_character_iteration.rs:52:5 | LL | S::default().field().chars().all(|x| x.is_ascii()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `S::default().field().is_ascii()` diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index bd83581bdd97..c2267b84de42 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -7,16 +7,21 @@ use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedL fn main() { let sample = [1; 5]; let len = sample.iter().count(); + //~^ needless_collect if sample.iter().next().is_none() { + //~^ needless_collect // Empty } sample.iter().cloned().any(|x| x == 1); + //~^ needless_collect // #7164 HashMap's and BTreeMap's `len` usage should not be linted sample.iter().map(|x| (x, x)).collect::>().len(); sample.iter().map(|x| (x, x)).collect::>().len(); sample.iter().map(|x| (x, x)).next().is_none(); + //~^ needless_collect sample.iter().map(|x| (x, x)).next().is_none(); + //~^ needless_collect // Notice the `HashSet`--this should not be linted sample.iter().collect::>().len(); @@ -24,19 +29,27 @@ fn main() { sample.iter().collect::>().len(); sample.iter().count(); + //~^ needless_collect sample.iter().next().is_none(); + //~^ needless_collect sample.iter().cloned().any(|x| x == 1); + //~^ needless_collect sample.iter().any(|x| x == &1); + //~^ needless_collect // `BinaryHeap` doesn't have `contains` method sample.iter().count(); + //~^ needless_collect sample.iter().next().is_none(); + //~^ needless_collect // Don't lint string from str let _ = ["", ""].into_iter().collect::().is_empty(); let _ = sample.iter().next().is_none(); + //~^ needless_collect let _ = sample.iter().any(|x| x == &0); + //~^ needless_collect struct VecWrapper(Vec); impl core::ops::Deref for VecWrapper { @@ -59,14 +72,20 @@ fn main() { } let _ = sample.iter().next().is_none(); + //~^ needless_collect let _ = sample.iter().any(|x| x == &0); + //~^ needless_collect #[allow(clippy::double_parens)] { Vec::::new().extend((0..10)); + //~^ needless_collect foo((0..10)); + //~^ needless_collect bar((0..10).collect::>(), (0..10)); + //~^ needless_collect baz((0..10), (), ('a'..='z')) + //~^ needless_collect } let values = [1, 2, 3, 4]; diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index 6a81a767bbb6..854bc3fff19d 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -7,16 +7,21 @@ use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedL fn main() { let sample = [1; 5]; let len = sample.iter().collect::>().len(); + //~^ needless_collect if sample.iter().collect::>().is_empty() { + //~^ needless_collect // Empty } sample.iter().cloned().collect::>().contains(&1); + //~^ needless_collect // #7164 HashMap's and BTreeMap's `len` usage should not be linted sample.iter().map(|x| (x, x)).collect::>().len(); sample.iter().map(|x| (x, x)).collect::>().len(); sample.iter().map(|x| (x, x)).collect::>().is_empty(); + //~^ needless_collect sample.iter().map(|x| (x, x)).collect::>().is_empty(); + //~^ needless_collect // Notice the `HashSet`--this should not be linted sample.iter().collect::>().len(); @@ -24,19 +29,27 @@ fn main() { sample.iter().collect::>().len(); sample.iter().collect::>().len(); + //~^ needless_collect sample.iter().collect::>().is_empty(); + //~^ needless_collect sample.iter().cloned().collect::>().contains(&1); + //~^ needless_collect sample.iter().collect::>().contains(&&1); + //~^ needless_collect // `BinaryHeap` doesn't have `contains` method sample.iter().collect::>().len(); + //~^ needless_collect sample.iter().collect::>().is_empty(); + //~^ needless_collect // Don't lint string from str let _ = ["", ""].into_iter().collect::().is_empty(); let _ = sample.iter().collect::>().is_empty(); + //~^ needless_collect let _ = sample.iter().collect::>().contains(&&0); + //~^ needless_collect struct VecWrapper(Vec); impl core::ops::Deref for VecWrapper { @@ -59,14 +72,20 @@ fn main() { } let _ = sample.iter().collect::>().is_empty(); + //~^ needless_collect let _ = sample.iter().collect::>().contains(&&0); + //~^ needless_collect #[allow(clippy::double_parens)] { Vec::::new().extend((0..10).collect::>()); + //~^ needless_collect foo((0..10).collect::>()); + //~^ needless_collect bar((0..10).collect::>(), (0..10).collect::>()); + //~^ needless_collect baz((0..10), (), ('a'..='z').collect::>()) + //~^ needless_collect } let values = [1, 2, 3, 4]; diff --git a/tests/ui/needless_collect.stderr b/tests/ui/needless_collect.stderr index ea317896d368..cba54f0af6bf 100644 --- a/tests/ui/needless_collect.stderr +++ b/tests/ui/needless_collect.stderr @@ -8,109 +8,109 @@ LL | let len = sample.iter().collect::>().len(); = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:10:22 + --> tests/ui/needless_collect.rs:11:22 | LL | if sample.iter().collect::>().is_empty() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:13:28 + --> tests/ui/needless_collect.rs:15:28 | LL | sample.iter().cloned().collect::>().contains(&1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:18:35 + --> tests/ui/needless_collect.rs:21:35 | LL | sample.iter().map(|x| (x, x)).collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:19:35 + --> tests/ui/needless_collect.rs:23:35 | LL | sample.iter().map(|x| (x, x)).collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:26:19 + --> tests/ui/needless_collect.rs:31:19 | LL | sample.iter().collect::>().len(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:27:19 + --> tests/ui/needless_collect.rs:33:19 | LL | sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:28:28 + --> tests/ui/needless_collect.rs:35:28 | LL | sample.iter().cloned().collect::>().contains(&1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:29:19 + --> tests/ui/needless_collect.rs:37:19 | LL | sample.iter().collect::>().contains(&&1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &1)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:32:19 + --> tests/ui/needless_collect.rs:41:19 | LL | sample.iter().collect::>().len(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:33:19 + --> tests/ui/needless_collect.rs:43:19 | LL | sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:38:27 + --> tests/ui/needless_collect.rs:49:27 | LL | let _ = sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:39:27 + --> tests/ui/needless_collect.rs:51:27 | LL | let _ = sample.iter().collect::>().contains(&&0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:61:27 + --> tests/ui/needless_collect.rs:74:27 | LL | let _ = sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:62:27 + --> tests/ui/needless_collect.rs:76:27 | LL | let _ = sample.iter().collect::>().contains(&&0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:66:40 + --> tests/ui/needless_collect.rs:81:40 | LL | Vec::::new().extend((0..10).collect::>()); | ^^^^^^^^^^^^^^^^^^^^ help: remove this call error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:67:20 + --> tests/ui/needless_collect.rs:83:20 | LL | foo((0..10).collect::>()); | ^^^^^^^^^^^^^^^^^^^^ help: remove this call error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:68:49 + --> tests/ui/needless_collect.rs:85:49 | LL | bar((0..10).collect::>(), (0..10).collect::>()); | ^^^^^^^^^^^^^^^^^^^^ help: remove this call error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:69:37 + --> tests/ui/needless_collect.rs:87:37 | LL | baz((0..10), (), ('a'..='z').collect::>()) | ^^^^^^^^^^^^^^^^^^^^ help: remove this call diff --git a/tests/ui/needless_collect_indirect.rs b/tests/ui/needless_collect_indirect.rs index 9d66c5f255fe..57d0f2b99480 100644 --- a/tests/ui/needless_collect_indirect.rs +++ b/tests/ui/needless_collect_indirect.rs @@ -7,17 +7,20 @@ use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; fn main() { let sample = [1; 5]; let indirect_iter = sample.iter().collect::>(); - //~^ ERROR: avoid using `collect()` when not needed - //~| NOTE: `-D clippy::needless-collect` implied by `-D warnings` + //~^ needless_collect + indirect_iter.into_iter().map(|x| (x, x + 1)).collect::>(); let indirect_len = sample.iter().collect::>(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + indirect_len.len(); let indirect_empty = sample.iter().collect::>(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + indirect_empty.is_empty(); let indirect_contains = sample.iter().collect::>(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + indirect_contains.contains(&&5); let indirect_negative = sample.iter().collect::>(); indirect_negative.len(); @@ -30,7 +33,8 @@ fn main() { let a = "a".to_string(); let sample = vec![a.clone(), "b".to_string(), "c".to_string()]; let non_copy_contains = sample.into_iter().collect::>(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + non_copy_contains.contains(&a); // Fix #5991 @@ -60,25 +64,29 @@ mod issue7110 { fn lint_vec(string: &str) -> usize { let buffer: Vec<&str> = string.split('/').collect(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + buffer.len() } fn lint_vec_deque() -> usize { let sample = [1; 5]; let indirect_len: VecDeque<_> = sample.iter().collect(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + indirect_len.len() } fn lint_linked_list() -> usize { let sample = [1; 5]; let indirect_len: LinkedList<_> = sample.iter().collect(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + indirect_len.len() } fn lint_binary_heap() -> usize { let sample = [1; 5]; let indirect_len: BinaryHeap<_> = sample.iter().collect(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + indirect_len.len() } fn dont_lint(string: &str) -> usize { @@ -139,7 +147,8 @@ mod issue_8553 { for i in 0..2 { let y: Vec = vec.iter().map(|k| k * k).collect(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + let z: Vec = vec.iter().map(|k| k * k).collect(); // Do lint y.contains(&i); @@ -165,7 +174,8 @@ mod issue_8553 { while n > 2 { let y: Vec = vec.iter().map(|k| k * k).collect(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + let z: Vec = vec.iter().map(|k| k * k).collect(); // Do lint y.contains(&n); @@ -195,7 +205,8 @@ mod issue_8553 { loop { if n < 2 { let y: Vec = vec.iter().map(|k| k * k).collect(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + let z: Vec = vec.iter().map(|k| k * k).collect(); // Do lint y.contains(&n); @@ -232,7 +243,8 @@ mod issue_8553 { while let Some(value) = optional { let y: Vec = vec.iter().map(|k| k * k).collect(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + let z: Vec = vec.iter().map(|k| k * k).collect(); if n < 2 { // Do lint @@ -258,7 +270,8 @@ mod issue_8553 { let vec = vec![1, 2]; let v: Vec = vec.iter().map(|i| i * i).collect(); let w = v.iter().collect::>(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + // Do lint for _ in 0..w.len() { todo!(); @@ -281,7 +294,8 @@ mod issue_8553 { let mut vec = vec![1, 2]; let mut v: Vec = vec.iter().map(|i| i * i).collect(); let mut w = v.iter().collect::>(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + // Do lint while 1 == w.len() { todo!(); @@ -304,7 +318,8 @@ mod issue_8553 { let mut vec = vec![1, 2]; let mut v: Vec = vec.iter().map(|i| i * i).collect(); let mut w = v.iter().collect::>(); - //~^ ERROR: avoid using `collect()` when not needed + //~^ needless_collect + // Do lint while let Some(i) = Some(w.len()) { todo!(); diff --git a/tests/ui/needless_collect_indirect.stderr b/tests/ui/needless_collect_indirect.stderr index f25c02937545..c7bf1b14df80 100644 --- a/tests/ui/needless_collect_indirect.stderr +++ b/tests/ui/needless_collect_indirect.stderr @@ -22,7 +22,7 @@ error: avoid using `collect()` when not needed | LL | let indirect_len = sample.iter().collect::>(); | ^^^^^^^ -LL | +... LL | indirect_len.len(); | ------------------ the iterator could be used here instead | @@ -30,15 +30,16 @@ help: take the original Iterator's count instead of collecting it and finding th | LL ~ LL | +LL | LL ~ sample.iter().count(); | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:16:40 + --> tests/ui/needless_collect_indirect.rs:17:40 | LL | let indirect_empty = sample.iter().collect::>(); | ^^^^^^^ -LL | +... LL | indirect_empty.is_empty(); | ------------------------- the iterator could be used here instead | @@ -46,15 +47,16 @@ help: check if the original Iterator has anything instead of collecting it and s | LL ~ LL | +LL | LL ~ sample.iter().next().is_none(); | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:19:43 + --> tests/ui/needless_collect_indirect.rs:21:43 | LL | let indirect_contains = sample.iter().collect::>(); | ^^^^^^^ -LL | +... LL | indirect_contains.contains(&&5); | ------------------------------- the iterator could be used here instead | @@ -62,15 +64,16 @@ help: check if the original Iterator contains an element instead of collecting t | LL ~ LL | +LL | LL ~ sample.iter().any(|x| x == &5); | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:32:48 + --> tests/ui/needless_collect_indirect.rs:35:48 | LL | let non_copy_contains = sample.into_iter().collect::>(); | ^^^^^^^ -LL | +... LL | non_copy_contains.contains(&a); | ------------------------------ the iterator could be used here instead | @@ -78,15 +81,16 @@ help: check if the original Iterator contains an element instead of collecting t | LL ~ LL | +LL | LL ~ sample.into_iter().any(|x| x == a); | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:62:51 + --> tests/ui/needless_collect_indirect.rs:66:51 | LL | let buffer: Vec<&str> = string.split('/').collect(); | ^^^^^^^ -LL | +... LL | buffer.len() | ------------ the iterator could be used here instead | @@ -94,15 +98,16 @@ help: take the original Iterator's count instead of collecting it and finding th | LL ~ LL | +LL | LL ~ string.split('/').count() | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:68:55 + --> tests/ui/needless_collect_indirect.rs:73:55 | LL | let indirect_len: VecDeque<_> = sample.iter().collect(); | ^^^^^^^ -LL | +... LL | indirect_len.len() | ------------------ the iterator could be used here instead | @@ -110,21 +115,6 @@ help: take the original Iterator's count instead of collecting it and finding th | LL ~ LL | -LL ~ sample.iter().count() - | - -error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:74:57 - | -LL | let indirect_len: LinkedList<_> = sample.iter().collect(); - | ^^^^^^^ -LL | -LL | indirect_len.len() - | ------------------ the iterator could be used here instead - | -help: take the original Iterator's count instead of collecting it and finding the length - | -LL ~ LL | LL ~ sample.iter().count() | @@ -132,9 +122,9 @@ LL ~ sample.iter().count() error: avoid using `collect()` when not needed --> tests/ui/needless_collect_indirect.rs:80:57 | -LL | let indirect_len: BinaryHeap<_> = sample.iter().collect(); +LL | let indirect_len: LinkedList<_> = sample.iter().collect(); | ^^^^^^^ -LL | +... LL | indirect_len.len() | ------------------ the iterator could be used here instead | @@ -142,11 +132,29 @@ help: take the original Iterator's count instead of collecting it and finding th | LL ~ LL | +LL | LL ~ sample.iter().count() | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:141:59 + --> tests/ui/needless_collect_indirect.rs:87:57 + | +LL | let indirect_len: BinaryHeap<_> = sample.iter().collect(); + | ^^^^^^^ +... +LL | indirect_len.len() + | ------------------ the iterator could be used here instead + | +help: take the original Iterator's count instead of collecting it and finding the length + | +LL ~ +LL | +LL | +LL ~ sample.iter().count() + | + +error: avoid using `collect()` when not needed + --> tests/ui/needless_collect_indirect.rs:149:59 | LL | let y: Vec = vec.iter().map(|k| k * k).collect(); | ^^^^^^^ @@ -158,13 +166,13 @@ help: check if the original Iterator contains an element instead of collecting t | LL ~ LL | -LL | let z: Vec = vec.iter().map(|k| k * k).collect(); +... LL | // Do lint LL ~ vec.iter().map(|k| k * k).any(|x| x == i); | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:167:59 + --> tests/ui/needless_collect_indirect.rs:176:59 | LL | let y: Vec = vec.iter().map(|k| k * k).collect(); | ^^^^^^^ @@ -176,13 +184,13 @@ help: check if the original Iterator contains an element instead of collecting t | LL ~ LL | -LL | let z: Vec = vec.iter().map(|k| k * k).collect(); +... LL | // Do lint LL ~ vec.iter().map(|k| k * k).any(|x| x == n); | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:197:63 + --> tests/ui/needless_collect_indirect.rs:207:63 | LL | let y: Vec = vec.iter().map(|k| k * k).collect(); | ^^^^^^^ @@ -194,13 +202,13 @@ help: check if the original Iterator contains an element instead of collecting t | LL ~ LL | -LL | let z: Vec = vec.iter().map(|k| k * k).collect(); +... LL | // Do lint LL ~ vec.iter().map(|k| k * k).any(|x| x == n); | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:234:59 + --> tests/ui/needless_collect_indirect.rs:245:59 | LL | let y: Vec = vec.iter().map(|k| k * k).collect(); | ^^^^^^^ @@ -218,7 +226,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n); | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:260:26 + --> tests/ui/needless_collect_indirect.rs:272:26 | LL | let w = v.iter().collect::>(); | ^^^^^^^ @@ -230,12 +238,13 @@ help: take the original Iterator's count instead of collecting it and finding th | LL ~ LL | +LL | LL | // Do lint LL ~ for _ in 0..v.iter().count() { | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:283:30 + --> tests/ui/needless_collect_indirect.rs:296:30 | LL | let mut w = v.iter().collect::>(); | ^^^^^^^ @@ -247,12 +256,13 @@ help: take the original Iterator's count instead of collecting it and finding th | LL ~ LL | +LL | LL | // Do lint LL ~ while 1 == v.iter().count() { | error: avoid using `collect()` when not needed - --> tests/ui/needless_collect_indirect.rs:306:30 + --> tests/ui/needless_collect_indirect.rs:320:30 | LL | let mut w = v.iter().collect::>(); | ^^^^^^^ @@ -264,6 +274,7 @@ help: take the original Iterator's count instead of collecting it and finding th | LL ~ LL | +LL | LL | // Do lint LL ~ while let Some(i) = Some(v.iter().count()) { | diff --git a/tests/ui/needless_continue.rs b/tests/ui/needless_continue.rs index 334a2b32775f..0adef7e72ee4 100644 --- a/tests/ui/needless_continue.rs +++ b/tests/ui/needless_continue.rs @@ -28,7 +28,8 @@ fn main() { let i = 0; println!("bar {} ", i); } else { - //~^ ERROR: this `else` block is redundant + //~^ needless_continue + continue; } @@ -44,7 +45,8 @@ fn main() { } if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 { - //~^ ERROR: there is no need for an explicit `else` block for this `if` expression + //~^ needless_continue + continue; } else { println!("Blabber"); @@ -58,7 +60,8 @@ fn main() { fn simple_loop() { loop { continue; - //~^ ERROR: this `continue` expression is redundant + //~^ needless_continue + } } @@ -66,7 +69,8 @@ fn simple_loop2() { loop { println!("bleh"); continue; - //~^ ERROR: this `continue` expression is redundant + //~^ needless_continue + } } @@ -74,7 +78,8 @@ fn simple_loop2() { fn simple_loop3() { loop { continue - //~^ ERROR: this `continue` expression is redundant + //~^ needless_continue + } } @@ -83,7 +88,8 @@ fn simple_loop4() { loop { println!("bleh"); continue - //~^ ERROR: this `continue` expression is redundant + //~^ needless_continue + } } @@ -91,7 +97,8 @@ fn simple_loop5() { loop { println!("bleh"); { continue } - //~^ ERROR: this `continue` expression is redundant + //~^ needless_continue + } } @@ -142,14 +149,16 @@ mod issue_2329 { if condition() { println!("bar-3"); } else { - //~^ ERROR: this `else` block is redundant + //~^ needless_continue + continue 'inner; } println!("bar-4"); update_condition(); if condition() { - //~^ ERROR: there is no need for an explicit `else` block for this `if` ex + //~^ needless_continue + continue; } else { println!("bar-5"); @@ -172,7 +181,8 @@ fn issue_13641() { while std::hint::black_box(true) { 'b: loop { continue 'b; - //~^ ERROR: this `continue` expression is redundant + //~^ needless_continue + } } } @@ -188,9 +198,11 @@ mod issue_4077 { } else if !some_expr() { println!("bar-8"); continue 'inner; + //~^ needless_continue } else { println!("bar-9"); continue 'inner; + //~^ needless_continue } } } @@ -201,6 +213,7 @@ mod issue_4077 { Err(_) => { println!("bar-10"); continue; + //~^ needless_continue }, } } @@ -208,6 +221,7 @@ mod issue_4077 { loop { if true { } else { + //~^ needless_continue // redundant `else` continue; // redundant `continue` } @@ -215,6 +229,7 @@ mod issue_4077 { loop { if some_expr() { + //~^ needless_continue continue; } else { do_something(); diff --git a/tests/ui/needless_continue.stderr b/tests/ui/needless_continue.stderr index ec39d6234195..947e61cac12e 100644 --- a/tests/ui/needless_continue.stderr +++ b/tests/ui/needless_continue.stderr @@ -4,6 +4,7 @@ error: this `else` block is redundant LL | } else { | ________________^ LL | | +LL | | LL | | continue; LL | | } | |_________^ @@ -27,6 +28,7 @@ LL | | } } if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 { + continue; } else { println!("Blabber"); @@ -38,13 +40,13 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::needless_continue)]` error: there is no need for an explicit `else` block for this `if` expression - --> tests/ui/needless_continue.rs:46:9 + --> tests/ui/needless_continue.rs:47:9 | LL | / if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 { LL | | +LL | | LL | | continue; -LL | | } else { -LL | | println!("Blabber"); +... | LL | | println!("Jabber"); LL | | } | |_________^ @@ -52,6 +54,7 @@ LL | | } = help: consider dropping the `else` clause if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 { + continue; } { @@ -60,7 +63,7 @@ LL | | } } error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:60:9 + --> tests/ui/needless_continue.rs:62:9 | LL | continue; | ^^^^^^^^ @@ -68,7 +71,7 @@ LL | continue; = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:68:9 + --> tests/ui/needless_continue.rs:71:9 | LL | continue; | ^^^^^^^^ @@ -76,7 +79,7 @@ LL | continue; = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:76:9 + --> tests/ui/needless_continue.rs:80:9 | LL | continue | ^^^^^^^^ @@ -84,7 +87,7 @@ LL | continue = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:85:9 + --> tests/ui/needless_continue.rs:90:9 | LL | continue | ^^^^^^^^ @@ -92,7 +95,7 @@ LL | continue = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:93:11 + --> tests/ui/needless_continue.rs:99:11 | LL | { continue } | ^^^^^^^^ @@ -100,11 +103,12 @@ LL | { continue } = help: consider dropping the `continue` expression error: this `else` block is redundant - --> tests/ui/needless_continue.rs:144:24 + --> tests/ui/needless_continue.rs:151:24 | LL | } else { | ________________________^ LL | | +LL | | LL | | continue 'inner; LL | | } | |_________________^ @@ -117,6 +121,7 @@ LL | | } update_condition(); if condition() { + continue; } else { println!("bar-5"); @@ -125,10 +130,11 @@ LL | | } } error: there is no need for an explicit `else` block for this `if` expression - --> tests/ui/needless_continue.rs:151:17 + --> tests/ui/needless_continue.rs:159:17 | LL | / if condition() { LL | | +LL | | LL | | continue; LL | | } else { LL | | println!("bar-5"); @@ -138,6 +144,7 @@ LL | | } = help: consider dropping the `else` clause if condition() { + continue; } { @@ -145,7 +152,7 @@ LL | | } } error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:174:13 + --> tests/ui/needless_continue.rs:183:13 | LL | continue 'b; | ^^^^^^^^^^^ @@ -153,7 +160,7 @@ LL | continue 'b; = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:190:21 + --> tests/ui/needless_continue.rs:200:21 | LL | continue 'inner; | ^^^^^^^^^^^^^^^ @@ -161,7 +168,7 @@ LL | continue 'inner; = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:193:21 + --> tests/ui/needless_continue.rs:204:21 | LL | continue 'inner; | ^^^^^^^^^^^^^^^ @@ -169,7 +176,7 @@ LL | continue 'inner; = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:203:21 + --> tests/ui/needless_continue.rs:215:21 | LL | continue; | ^^^^^^^^ @@ -177,10 +184,11 @@ LL | continue; = help: consider dropping the `continue` expression error: this `else` block is redundant - --> tests/ui/needless_continue.rs:210:20 + --> tests/ui/needless_continue.rs:223:20 | LL | } else { | ____________________^ +LL | | LL | | // redundant `else` LL | | continue; // redundant `continue` LL | | } @@ -193,9 +201,10 @@ LL | | } } error: there is no need for an explicit `else` block for this `if` expression - --> tests/ui/needless_continue.rs:217:13 + --> tests/ui/needless_continue.rs:231:13 | LL | / if some_expr() { +LL | | LL | | continue; LL | | } else { LL | | do_something(); @@ -204,6 +213,7 @@ LL | | } | = help: consider dropping the `else` clause if some_expr() { + continue; } { diff --git a/tests/ui/needless_doc_main.rs b/tests/ui/needless_doc_main.rs index 18adfff8beba..8894ab0285d4 100644 --- a/tests/ui/needless_doc_main.rs +++ b/tests/ui/needless_doc_main.rs @@ -6,7 +6,6 @@ /// ``` /// fn main() { //~^ ERROR: needless `fn main` in doctest -//~| NOTE: `-D clippy::needless-doctest-main` implied by `-D warnings` /// unimplemented!(); /// } /// ``` diff --git a/tests/ui/needless_doc_main.stderr b/tests/ui/needless_doc_main.stderr index 7e362cf377ce..9ba2ad306dac 100644 --- a/tests/ui/needless_doc_main.stderr +++ b/tests/ui/needless_doc_main.stderr @@ -4,7 +4,6 @@ error: needless `fn main` in doctest LL | /// fn main() { | _____^ LL | | -LL | | LL | | /// unimplemented!(); LL | | /// } | |_____^ @@ -13,7 +12,7 @@ LL | | /// } = help: to override `-D warnings` add `#[allow(clippy::needless_doctest_main)]` error: needless `fn main` in doctest - --> tests/ui/needless_doc_main.rs:16:5 + --> tests/ui/needless_doc_main.rs:15:5 | LL | /// fn main() -> () { | _____^ @@ -23,7 +22,7 @@ LL | | /// } | |_____^ error: needless `fn main` in doctest - --> tests/ui/needless_doc_main.rs:24:5 + --> tests/ui/needless_doc_main.rs:23:5 | LL | /// fn main() { | _____^ @@ -33,7 +32,7 @@ LL | | /// } | |_____^ error: needless `fn main` in doctest - --> tests/ui/needless_doc_main.rs:32:5 + --> tests/ui/needless_doc_main.rs:31:5 | LL | /// // the fn is not always the first line | _____^ diff --git a/tests/ui/needless_else.fixed b/tests/ui/needless_else.fixed index 240b79bae13c..0455910c3ee8 100644 --- a/tests/ui/needless_else.fixed +++ b/tests/ui/needless_else.fixed @@ -21,6 +21,7 @@ fn main() { if b { println!("Foobar"); } + //~^^ needless_else if b { println!("Foobar"); diff --git a/tests/ui/needless_else.rs b/tests/ui/needless_else.rs index ad84da170535..236ac631a49e 100644 --- a/tests/ui/needless_else.rs +++ b/tests/ui/needless_else.rs @@ -22,6 +22,7 @@ fn main() { println!("Foobar"); } else { } + //~^^ needless_else if b { println!("Foobar"); diff --git a/tests/ui/needless_else.stderr b/tests/ui/needless_else.stderr deleted file mode 100644 index 77ead31b31cc..000000000000 --- a/tests/ui/needless_else.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: this `else` branch is empty - --> tests/ui/needless_else.rs:23:7 - | -LL | } else { - | _______^ -LL | | } - | |_____^ help: you can remove it - | - = note: `-D clippy::needless-else` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::needless_else)]` - -error: aborting due to 1 previous error - diff --git a/tests/ui/needless_for_each_fixable.fixed b/tests/ui/needless_for_each_fixable.fixed index 2362314290e6..873bad552af1 100644 --- a/tests/ui/needless_for_each_fixable.fixed +++ b/tests/ui/needless_for_each_fixable.fixed @@ -13,27 +13,34 @@ fn should_lint() { let v: Vec = Vec::new(); let mut acc = 0; for elem in v.iter() { + //~^ needless_for_each acc += elem; } for elem in v.into_iter() { + //~^ needless_for_each acc += elem; } for elem in [1, 2, 3].iter() { + //~^ needless_for_each acc += elem; } let mut hash_map: HashMap = HashMap::new(); for (k, v) in hash_map.iter() { + //~^ needless_for_each acc += k + v; } for (k, v) in hash_map.iter_mut() { + //~^ needless_for_each acc += *k + *v; } for k in hash_map.keys() { + //~^ needless_for_each acc += k; } for v in hash_map.values() { + //~^ needless_for_each acc += v; } @@ -41,6 +48,7 @@ fn should_lint() { Vec::new() } for elem in my_vec().iter() { + //~^ needless_for_each acc += elem; } } diff --git a/tests/ui/needless_for_each_fixable.rs b/tests/ui/needless_for_each_fixable.rs index 5b1186daa229..5e650dfc06c1 100644 --- a/tests/ui/needless_for_each_fixable.rs +++ b/tests/ui/needless_for_each_fixable.rs @@ -13,27 +13,34 @@ fn should_lint() { let v: Vec = Vec::new(); let mut acc = 0; v.iter().for_each(|elem| { + //~^ needless_for_each acc += elem; }); v.into_iter().for_each(|elem| { + //~^ needless_for_each acc += elem; }); [1, 2, 3].iter().for_each(|elem| { + //~^ needless_for_each acc += elem; }); let mut hash_map: HashMap = HashMap::new(); hash_map.iter().for_each(|(k, v)| { + //~^ needless_for_each acc += k + v; }); hash_map.iter_mut().for_each(|(k, v)| { + //~^ needless_for_each acc += *k + *v; }); hash_map.keys().for_each(|k| { + //~^ needless_for_each acc += k; }); hash_map.values().for_each(|v| { + //~^ needless_for_each acc += v; }); @@ -41,6 +48,7 @@ fn should_lint() { Vec::new() } my_vec().iter().for_each(|elem| { + //~^ needless_for_each acc += elem; }); } diff --git a/tests/ui/needless_for_each_fixable.stderr b/tests/ui/needless_for_each_fixable.stderr index 21342d052561..013a3fa3e36d 100644 --- a/tests/ui/needless_for_each_fixable.stderr +++ b/tests/ui/needless_for_each_fixable.stderr @@ -2,6 +2,7 @@ error: needless use of `for_each` --> tests/ui/needless_for_each_fixable.rs:15:5 | LL | / v.iter().for_each(|elem| { +LL | | LL | | acc += elem; LL | | }); | |_______^ @@ -11,14 +12,16 @@ LL | | }); help: try | LL ~ for elem in v.iter() { +LL + LL + acc += elem; LL + } | error: needless use of `for_each` - --> tests/ui/needless_for_each_fixable.rs:18:5 + --> tests/ui/needless_for_each_fixable.rs:19:5 | LL | / v.into_iter().for_each(|elem| { +LL | | LL | | acc += elem; LL | | }); | |_______^ @@ -26,14 +29,16 @@ LL | | }); help: try | LL ~ for elem in v.into_iter() { +LL + LL + acc += elem; LL + } | error: needless use of `for_each` - --> tests/ui/needless_for_each_fixable.rs:22:5 + --> tests/ui/needless_for_each_fixable.rs:24:5 | LL | / [1, 2, 3].iter().for_each(|elem| { +LL | | LL | | acc += elem; LL | | }); | |_______^ @@ -41,14 +46,16 @@ LL | | }); help: try | LL ~ for elem in [1, 2, 3].iter() { +LL + LL + acc += elem; LL + } | error: needless use of `for_each` - --> tests/ui/needless_for_each_fixable.rs:27:5 + --> tests/ui/needless_for_each_fixable.rs:30:5 | LL | / hash_map.iter().for_each(|(k, v)| { +LL | | LL | | acc += k + v; LL | | }); | |_______^ @@ -56,14 +63,16 @@ LL | | }); help: try | LL ~ for (k, v) in hash_map.iter() { +LL + LL + acc += k + v; LL + } | error: needless use of `for_each` - --> tests/ui/needless_for_each_fixable.rs:30:5 + --> tests/ui/needless_for_each_fixable.rs:34:5 | LL | / hash_map.iter_mut().for_each(|(k, v)| { +LL | | LL | | acc += *k + *v; LL | | }); | |_______^ @@ -71,14 +80,16 @@ LL | | }); help: try | LL ~ for (k, v) in hash_map.iter_mut() { +LL + LL + acc += *k + *v; LL + } | error: needless use of `for_each` - --> tests/ui/needless_for_each_fixable.rs:33:5 + --> tests/ui/needless_for_each_fixable.rs:38:5 | LL | / hash_map.keys().for_each(|k| { +LL | | LL | | acc += k; LL | | }); | |_______^ @@ -86,14 +97,16 @@ LL | | }); help: try | LL ~ for k in hash_map.keys() { +LL + LL + acc += k; LL + } | error: needless use of `for_each` - --> tests/ui/needless_for_each_fixable.rs:36:5 + --> tests/ui/needless_for_each_fixable.rs:42:5 | LL | / hash_map.values().for_each(|v| { +LL | | LL | | acc += v; LL | | }); | |_______^ @@ -101,14 +114,16 @@ LL | | }); help: try | LL ~ for v in hash_map.values() { +LL + LL + acc += v; LL + } | error: needless use of `for_each` - --> tests/ui/needless_for_each_fixable.rs:43:5 + --> tests/ui/needless_for_each_fixable.rs:50:5 | LL | / my_vec().iter().for_each(|elem| { +LL | | LL | | acc += elem; LL | | }); | |_______^ @@ -116,6 +131,7 @@ LL | | }); help: try | LL ~ for elem in my_vec().iter() { +LL + LL + acc += elem; LL + } | diff --git a/tests/ui/needless_for_each_unfixable.rs b/tests/ui/needless_for_each_unfixable.rs index 2220cf9e11ee..56faa471ed8c 100644 --- a/tests/ui/needless_for_each_unfixable.rs +++ b/tests/ui/needless_for_each_unfixable.rs @@ -6,8 +6,9 @@ fn main() { let v: Vec = Vec::new(); // This is unfixable because the closure includes `return`. v.iter().for_each(|v| { - //~^ ERROR: needless use of `for_each` - //~| NOTE: `-D clippy::needless-for-each` implied by `-D warnings` + //~^ needless_for_each + + if *v == 10 { return; } else { diff --git a/tests/ui/needless_for_each_unfixable.stderr b/tests/ui/needless_for_each_unfixable.stderr index 682140a1dfda..37470a8a622e 100644 --- a/tests/ui/needless_for_each_unfixable.stderr +++ b/tests/ui/needless_for_each_unfixable.stderr @@ -2,9 +2,6 @@ error: needless use of `for_each` --> tests/ui/needless_for_each_unfixable.rs:8:5 | LL | / v.iter().for_each(|v| { -LL | | -LL | | -LL | | if *v == 10 { ... | LL | | }); | |_______^ @@ -15,7 +12,8 @@ help: try | LL ~ for v in v.iter() { LL + -LL + +LL + +LL + LL + if *v == 10 { LL + return; LL + } else { diff --git a/tests/ui/needless_if.fixed b/tests/ui/needless_if.fixed index 79e33a7218b7..1e2842a27aa6 100644 --- a/tests/ui/needless_if.fixed +++ b/tests/ui/needless_if.fixed @@ -25,13 +25,16 @@ fn maybe_side_effect() -> bool { fn main() { // Lint + //~^ needless_if // Do not remove the condition maybe_side_effect(); + //~^ needless_if // Do not lint if (true) { } else { } ({ + //~^ needless_if return; }); // Do not lint if `else if` is present @@ -48,6 +51,7 @@ fn main() { {} // Can lint nested `if let`s ({ + //~^ needless_if if let true = true && true { @@ -91,12 +95,15 @@ fn main() { // Must be placed into an expression context to not be interpreted as a block ({ maybe_side_effect() }); + //~^ needless_if // Would be a block followed by `&&true` - a double reference to `true` ({ maybe_side_effect() } && true); + //~^ needless_if // Don't leave trailing attributes #[allow(unused)] true; + //~^ needless_if let () = if maybe_side_effect() {}; } diff --git a/tests/ui/needless_if.rs b/tests/ui/needless_if.rs index 2c135fb22bf8..a753c66da5a5 100644 --- a/tests/ui/needless_if.rs +++ b/tests/ui/needless_if.rs @@ -25,13 +25,16 @@ fn maybe_side_effect() -> bool { fn main() { // Lint if (true) {} + //~^ needless_if // Do not remove the condition if maybe_side_effect() {} + //~^ needless_if // Do not lint if (true) { } else { } if { + //~^ needless_if return; } {} // Do not lint if `else if` is present @@ -48,6 +51,7 @@ fn main() { {} // Can lint nested `if let`s if { + //~^ needless_if if let true = true && true { @@ -92,12 +96,15 @@ fn main() { // Must be placed into an expression context to not be interpreted as a block if { maybe_side_effect() } {} + //~^ needless_if // Would be a block followed by `&&true` - a double reference to `true` if { maybe_side_effect() } && true {} + //~^ needless_if // Don't leave trailing attributes #[allow(unused)] if true {} + //~^ needless_if let () = if maybe_side_effect() {}; } diff --git a/tests/ui/needless_if.stderr b/tests/ui/needless_if.stderr index cbfeb979d2f2..eeb8d044526d 100644 --- a/tests/ui/needless_if.stderr +++ b/tests/ui/needless_if.stderr @@ -8,15 +8,16 @@ LL | if (true) {} = help: to override `-D warnings` add `#[allow(clippy::needless_if)]` error: this `if` branch is empty - --> tests/ui/needless_if.rs:29:5 + --> tests/ui/needless_if.rs:30:5 | LL | if maybe_side_effect() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `maybe_side_effect();` error: this `if` branch is empty - --> tests/ui/needless_if.rs:34:5 + --> tests/ui/needless_if.rs:36:5 | LL | / if { +LL | | LL | | return; LL | | } {} | |________^ @@ -24,14 +25,16 @@ LL | | } {} help: you can remove it | LL ~ ({ +LL + LL + return; LL + }); | error: this `if` branch is empty - --> tests/ui/needless_if.rs:50:5 + --> tests/ui/needless_if.rs:53:5 | LL | / if { +LL | | LL | | if let true = true LL | | && true ... | @@ -42,6 +45,7 @@ LL | | {} help: you can remove it | LL ~ ({ +LL + LL + if let true = true LL + && true LL + { @@ -53,19 +57,19 @@ LL + } && true); | error: this `if` branch is empty - --> tests/ui/needless_if.rs:94:5 + --> tests/ui/needless_if.rs:98:5 | LL | if { maybe_side_effect() } {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() });` error: this `if` branch is empty - --> tests/ui/needless_if.rs:96:5 + --> tests/ui/needless_if.rs:101:5 | LL | if { maybe_side_effect() } && true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() } && true);` error: this `if` branch is empty - --> tests/ui/needless_if.rs:100:5 + --> tests/ui/needless_if.rs:106:5 | LL | if true {} | ^^^^^^^^^^ help: you can remove it: `true;` diff --git a/tests/ui/needless_late_init.fixed b/tests/ui/needless_late_init.fixed index b4bd53ce7bf7..eb67e6cc8282 100644 --- a/tests/ui/needless_late_init.fixed +++ b/tests/ui/needless_late_init.fixed @@ -25,22 +25,28 @@ impl std::ops::Drop for SignificantDrop { fn simple() { + //~^ needless_late_init let a = "zero"; + //~^ needless_late_init + //~^ needless_late_init let b = 1; let c = 2; + //~^ needless_late_init let d: usize = 1; + //~^ needless_late_init let e = format!("{}", d); } fn main() { + //~^ needless_late_init let n = 1; let a = match n { 1 => "one", @@ -50,6 +56,7 @@ fn main() { }; + //~^ needless_late_init let b = if n == 3 { "four" } else { @@ -57,6 +64,7 @@ fn main() { }; + //~^ needless_late_init let d = if true { let temp = 5; temp @@ -65,6 +73,7 @@ fn main() { }; + //~^ needless_late_init let e = if true { format!("{} {}", a, b) } else { @@ -72,12 +81,14 @@ fn main() { }; + //~^ needless_late_init let f = match 1 { 1 => "three", _ => return, }; // has semi + //~^ needless_late_init let g: usize = if true { 5 } else { @@ -86,14 +97,17 @@ fn main() { // Drop order only matters if both are significant + //~^ needless_late_init let y = SignificantDrop; let x = 1; + //~^ needless_late_init let y = 1; let x = SignificantDrop; + //~^ needless_late_init // types that should be considered insignificant let y = 1; let y = "2"; @@ -113,6 +127,7 @@ async fn in_async() -> &'static str { } + //~^ needless_late_init let n = 1; let a = match n { 1 => f().await, @@ -130,6 +145,7 @@ const fn in_const() -> &'static str { } + //~^ needless_late_init let n = 1; let a = match n { 1 => f(), diff --git a/tests/ui/needless_late_init.rs b/tests/ui/needless_late_init.rs index e25483625a68..7de2202dc323 100644 --- a/tests/ui/needless_late_init.rs +++ b/tests/ui/needless_late_init.rs @@ -25,22 +25,28 @@ impl std::ops::Drop for SignificantDrop { fn simple() { let a; + //~^ needless_late_init a = "zero"; let b; + //~^ needless_late_init let c; + //~^ needless_late_init b = 1; c = 2; let d: usize; + //~^ needless_late_init d = 1; let e; + //~^ needless_late_init e = format!("{}", d); } fn main() { let a; + //~^ needless_late_init let n = 1; match n { 1 => a = "one", @@ -50,6 +56,7 @@ fn main() { } let b; + //~^ needless_late_init if n == 3 { b = "four"; } else { @@ -57,6 +64,7 @@ fn main() { } let d; + //~^ needless_late_init if true { let temp = 5; d = temp; @@ -65,6 +73,7 @@ fn main() { } let e; + //~^ needless_late_init if true { e = format!("{} {}", a, b); } else { @@ -72,12 +81,14 @@ fn main() { } let f; + //~^ needless_late_init match 1 { 1 => f = "three", _ => return, }; // has semi let g: usize; + //~^ needless_late_init if true { g = 5; } else { @@ -86,14 +97,17 @@ fn main() { // Drop order only matters if both are significant let x; + //~^ needless_late_init let y = SignificantDrop; x = 1; let x; + //~^ needless_late_init let y = 1; x = SignificantDrop; let x; + //~^ needless_late_init // types that should be considered insignificant let y = 1; let y = "2"; @@ -113,6 +127,7 @@ async fn in_async() -> &'static str { } let a; + //~^ needless_late_init let n = 1; match n { 1 => a = f().await, @@ -130,6 +145,7 @@ const fn in_const() -> &'static str { } let a; + //~^ needless_late_init let n = 1; match n { 1 => a = f(), diff --git a/tests/ui/needless_late_init.stderr b/tests/ui/needless_late_init.stderr index de048091cfbe..02fd2811da58 100644 --- a/tests/ui/needless_late_init.stderr +++ b/tests/ui/needless_late_init.stderr @@ -3,6 +3,7 @@ error: unneeded late initialization | LL | let a; | ^^^^^^ created here +LL | LL | a = "zero"; | ^^^^^^^^^^ initialised here | @@ -11,71 +12,79 @@ LL | a = "zero"; help: move the declaration `a` here | LL ~ +LL | LL ~ let a = "zero"; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:30:5 + --> tests/ui/needless_late_init.rs:31:5 | LL | let b; | ^^^^^^ created here -LL | let c; +... LL | b = 1; | ^^^^^ initialised here | help: move the declaration `b` here | LL ~ +LL | LL | let c; +LL | LL ~ let b = 1; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:31:5 + --> tests/ui/needless_late_init.rs:33:5 | LL | let c; | ^^^^^^ created here -LL | b = 1; +... LL | c = 2; | ^^^^^ initialised here | help: move the declaration `c` here | LL ~ +LL | LL | b = 1; LL ~ let c = 2; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:35:5 + --> tests/ui/needless_late_init.rs:38:5 | LL | let d: usize; | ^^^^^^^^^^^^^ created here +LL | LL | d = 1; | ^^^^^ initialised here | help: move the declaration `d` here | LL ~ +LL | LL ~ let d: usize = 1; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:38:5 + --> tests/ui/needless_late_init.rs:42:5 | LL | let e; | ^^^^^^ created here +LL | LL | e = format!("{}", d); | ^^^^^^^^^^^^^^^^^^^^ initialised here | help: move the declaration `e` here | LL ~ +LL | LL ~ let e = format!("{}", d); | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:43:5 + --> tests/ui/needless_late_init.rs:48:5 | LL | let a; | ^^^^^^ @@ -83,6 +92,7 @@ LL | let a; help: move the declaration `a` here and remove the assignments from the `match` arms | LL ~ +LL | LL | let n = 1; LL ~ let a = match n { LL ~ 1 => "one", @@ -93,7 +103,7 @@ LL ~ }; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:52:5 + --> tests/ui/needless_late_init.rs:58:5 | LL | let b; | ^^^^^^ @@ -101,6 +111,7 @@ LL | let b; help: move the declaration `b` here and remove the assignments from the branches | LL ~ +LL | LL ~ let b = if n == 3 { LL ~ "four" LL | } else { @@ -109,7 +120,7 @@ LL ~ }; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:59:5 + --> tests/ui/needless_late_init.rs:66:5 | LL | let d; | ^^^^^^ @@ -117,6 +128,7 @@ LL | let d; help: move the declaration `d` here and remove the assignments from the branches | LL ~ +LL | LL ~ let d = if true { LL | let temp = 5; LL ~ temp @@ -126,7 +138,7 @@ LL ~ }; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:67:5 + --> tests/ui/needless_late_init.rs:75:5 | LL | let e; | ^^^^^^ @@ -134,6 +146,7 @@ LL | let e; help: move the declaration `e` here and remove the assignments from the branches | LL ~ +LL | LL ~ let e = if true { LL ~ format!("{} {}", a, b) LL | } else { @@ -142,7 +155,7 @@ LL ~ }; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:74:5 + --> tests/ui/needless_late_init.rs:83:5 | LL | let f; | ^^^^^^ @@ -150,12 +163,13 @@ LL | let f; help: move the declaration `f` here and remove the assignments from the `match` arms | LL ~ +LL | LL ~ let f = match 1 { LL ~ 1 => "three", | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:80:5 + --> tests/ui/needless_late_init.rs:90:5 | LL | let g: usize; | ^^^^^^^^^^^^^ @@ -163,6 +177,7 @@ LL | let g: usize; help: move the declaration `g` here and remove the assignments from the branches | LL ~ +LL | LL ~ let g: usize = if true { LL ~ 5 LL | } else { @@ -171,39 +186,24 @@ LL ~ }; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:88:5 + --> tests/ui/needless_late_init.rs:99:5 | LL | let x; | ^^^^^^ created here -LL | let y = SignificantDrop; +... LL | x = 1; | ^^^^^ initialised here | help: move the declaration `x` here | LL ~ +LL | LL | let y = SignificantDrop; LL ~ let x = 1; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:92:5 - | -LL | let x; - | ^^^^^^ created here -LL | let y = 1; -LL | x = SignificantDrop; - | ^^^^^^^^^^^^^^^^^^^ initialised here - | -help: move the declaration `x` here - | -LL ~ -LL | let y = 1; -LL ~ let x = SignificantDrop; - | - -error: unneeded late initialization - --> tests/ui/needless_late_init.rs:96:5 + --> tests/ui/needless_late_init.rs:104:5 | LL | let x; | ^^^^^^ created here @@ -214,14 +214,31 @@ LL | x = SignificantDrop; help: move the declaration `x` here | LL ~ -LL | // types that should be considered insignificant +LL | +LL | let y = 1; +LL ~ let x = SignificantDrop; + | + +error: unneeded late initialization + --> tests/ui/needless_late_init.rs:109:5 + | +LL | let x; + | ^^^^^^ created here +... +LL | x = SignificantDrop; + | ^^^^^^^^^^^^^^^^^^^ initialised here + | +help: move the declaration `x` here + | +LL ~ +LL | ... LL | let y = Box::new(4); LL ~ let x = SignificantDrop; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:115:5 + --> tests/ui/needless_late_init.rs:129:5 | LL | let a; | ^^^^^^ @@ -229,6 +246,7 @@ LL | let a; help: move the declaration `a` here and remove the assignments from the `match` arms | LL ~ +LL | LL | let n = 1; LL ~ let a = match n { LL ~ 1 => f().await, @@ -239,7 +257,7 @@ LL ~ }; | error: unneeded late initialization - --> tests/ui/needless_late_init.rs:132:5 + --> tests/ui/needless_late_init.rs:147:5 | LL | let a; | ^^^^^^ @@ -247,6 +265,7 @@ LL | let a; help: move the declaration `a` here and remove the assignments from the `match` arms | LL ~ +LL | LL | let n = 1; LL ~ let a = match n { LL ~ 1 => f(), diff --git a/tests/ui/needless_lifetimes.fixed b/tests/ui/needless_lifetimes.fixed index 86cf9a9cdb63..3cfbce84cd9b 100644 --- a/tests/ui/needless_lifetimes.fixed +++ b/tests/ui/needless_lifetimes.fixed @@ -9,15 +9,18 @@ clippy::redundant_allocation, clippy::unnecessary_wraps, dyn_drop, - clippy::get_first + clippy::get_first, + elided_named_lifetimes )] extern crate proc_macros; use proc_macros::inline_macros; fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {} +//~^ needless_lifetimes fn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {} +//~^ needless_lifetimes // No error; same lifetime on two params. fn same_lifetime_on_input<'a>(_x: &'a u8, _y: &'a u8) {} @@ -28,6 +31,7 @@ fn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) {} fn mut_and_static_input(_x: &mut u8, _y: &'static str) {} fn in_and_out(x: &u8, _y: u8) -> &u8 { +//~^ needless_lifetimes x } @@ -40,6 +44,7 @@ fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 { // fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 // ^^^ fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 { +//~^ needless_lifetimes x } @@ -47,6 +52,7 @@ fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 { // fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 // ^^^ fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 { +//~^ needless_lifetimes y } @@ -64,6 +70,7 @@ fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 { // fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> // ^^^ fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> { +//~^ needless_lifetimes Ok(x) } @@ -71,6 +78,7 @@ fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> { // fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> // ^^^ fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> { +//~^ needless_lifetimes Ok(y) } @@ -80,11 +88,13 @@ fn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 { } fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> { +//~^ needless_lifetimes Ok(x) } // Where-clause, but without lifetimes. fn where_clause_without_lt(x: &u8, _y: u8) -> Result<&u8, ()> +//~^ needless_lifetimes where T: Copy, { @@ -97,6 +107,7 @@ type Ref<'r> = &'r u8; fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {} fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {} +//~^ needless_lifetimes // No error; bounded lifetime. fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {} @@ -121,6 +132,7 @@ where } fn fn_bound_2(_m: Lt<'_, I>, _f: F) -> Lt<'_, I> +//~^ needless_lifetimes where for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>, { @@ -151,6 +163,7 @@ struct X { impl X { fn self_and_out(&self) -> &u8 { + //~^ needless_lifetimes &self.x } @@ -158,6 +171,7 @@ impl X { // fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 // ^^^ fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 { + //~^ needless_lifetimes &self.x } @@ -165,10 +179,12 @@ impl X { // fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 // ^^^^^ fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 { + //~^ needless_lifetimes x } fn distinct_self_and_in(&self, _x: &u8) {} + //~^ needless_lifetimes // No error; same lifetimes on two params. fn self_and_same_in<'s>(&'s self, _x: &'s u8) {} @@ -188,6 +204,7 @@ fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 { } fn struct_with_lt(_foo: Foo<'_>) -> &str { +//~^ needless_lifetimes unimplemented!() } @@ -206,6 +223,7 @@ fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str { // fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str // ^^ fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { +//~^ needless_lifetimes unimplemented!() } @@ -214,6 +232,7 @@ fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { // fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str // ^^^^ fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str { +//~^ needless_lifetimes unimplemented!() } @@ -229,12 +248,14 @@ fn trait_obj_elided<'a>(_arg: &'a dyn WithLifetime) -> &'a str { // Should warn because there is no lifetime on `Drop`, so this would be // unambiguous if we elided the lifetime. fn trait_obj_elided2(_arg: &dyn Drop) -> &str { +//~^ needless_lifetimes unimplemented!() } type FooAlias<'a> = Foo<'a>; fn alias_with_lt(_foo: FooAlias<'_>) -> &str { +//~^ needless_lifetimes unimplemented!() } @@ -253,6 +274,7 @@ fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str { // fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str // ^^ fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { +//~^ needless_lifetimes unimplemented!() } @@ -261,10 +283,12 @@ fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { // fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str // ^^^^^^^^^ fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str { +//~^ needless_lifetimes unimplemented!() } fn named_input_elided_output(_arg: &str) -> &str { +//~^ needless_lifetimes unimplemented!() } @@ -273,6 +297,7 @@ fn elided_input_named_output<'a>(_arg: &str) -> &'a str { } fn trait_bound_ok>(_: &u8, _: T) { +//~^ needless_lifetimes unimplemented!() } fn trait_bound<'a, T: WithLifetime<'a>>(_: &'a u8, _: T) { @@ -309,6 +334,7 @@ struct Cow<'a> { x: &'a str, } fn out_return_type_lts(e: &str) -> Cow<'_> { +//~^ needless_lifetimes unimplemented!() } @@ -316,10 +342,12 @@ fn out_return_type_lts(e: &str) -> Cow<'_> { mod issue4291 { trait BadTrait { fn needless_lt(x: &u8) {} + //~^ needless_lifetimes } impl BadTrait for () { fn needless_lt(_x: &u8) {} + //~^ needless_lifetimes } } @@ -331,8 +359,10 @@ mod issue2944 { } impl Foo for Baz<'_> {} + //~^ needless_lifetimes impl Bar { fn baz(&self) -> impl Foo + '_ { + //~^ needless_lifetimes Baz { bar: self } } } @@ -365,6 +395,7 @@ mod nested_elision_sites { f(i) } fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(&i32) -> &i32) -> &i32 { + //~^ needless_lifetimes f(i) } @@ -374,6 +405,7 @@ mod nested_elision_sites { } // lint fn generics_elidable &i32>(i: &i32, f: T) -> &i32 { + //~^ needless_lifetimes f(i) } @@ -386,6 +418,7 @@ mod nested_elision_sites { } // lint fn where_clause_elidable(i: &i32, f: T) -> &i32 + //~^ needless_lifetimes where T: Fn(&i32) -> &i32, { @@ -401,6 +434,7 @@ mod nested_elision_sites { } // lint fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 { + //~^ needless_lifetimes f(i) } @@ -414,9 +448,11 @@ mod nested_elision_sites { // lint fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 { + //~^ needless_lifetimes |f| 42 } fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) { + //~^ needless_lifetimes |f| () } } @@ -439,17 +475,21 @@ mod issue7296 { struct Foo; impl Foo { fn implicit(&self) -> &() { + //~^ needless_lifetimes &() } fn implicit_mut(&mut self) -> &() { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit(self: &Arc) -> &() { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit_mut(self: &mut Rc) -> &() { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.80"] @@ -462,20 +502,25 @@ mod issue7296 { } fn lifetime_elsewhere(self: Box, here: &()) -> &() { + //~^ needless_lifetimes &() } } trait Bar { fn implicit(&self) -> &(); + //~^ needless_lifetimes fn implicit_provided(&self) -> &() { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit(self: &Arc) -> &(); + //~^ needless_lifetimes #[clippy::msrv = "1.81"] fn explicit_provided(self: &Arc) -> &() { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.80"] @@ -486,7 +531,9 @@ mod issue7296 { } fn lifetime_elsewhere(self: Box, here: &()) -> &(); + //~^ needless_lifetimes fn lifetime_elsewhere_provided(self: Box, here: &()) -> &() { + //~^ needless_lifetimes &() } } @@ -496,8 +543,10 @@ mod pr_9743_false_negative_fix { #![allow(unused)] fn foo(x: &u8, y: &'_ u8) {} + //~^ needless_lifetimes fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {} + //~^ needless_lifetimes } mod pr_9743_output_lifetime_checks { @@ -505,11 +554,13 @@ mod pr_9743_output_lifetime_checks { // lint: only one input fn one_input(x: &u8) -> &u8 { + //~^ needless_lifetimes unimplemented!() } // lint: multiple inputs, output would not be elided fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) -> &'b u8 { + //~^ needless_lifetimes unimplemented!() } @@ -526,6 +577,7 @@ mod in_macro { // lint local macro expands to function with needless lifetimes inline! { fn one_input(x: &u8) -> &u8 { + //~^ needless_lifetimes unimplemented!() } } @@ -621,6 +673,7 @@ mod issue13923 { } impl<'t> ContentString<'t> { + //~^ needless_lifetimes // `'py` can be elided because of `&self` fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { match self { @@ -631,6 +684,7 @@ mod issue13923 { } impl<'t> ContentString<'t> { + //~^ needless_lifetimes // `'py` can be elided because of `&'_ self` fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { match self { @@ -651,6 +705,7 @@ mod issue13923 { } impl<'t> ContentString<'t> { + //~^ needless_lifetimes // `'py` can be elided because of `&Self` fn map_content5( self: std::pin::Pin<&Self>, @@ -672,6 +727,7 @@ mod issue13923 { // `'c` cannot be elided because we have several input lifetimes fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 { x.b + //~^ needless_borrow } } diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs index 1ee0f4c6092a..612e7546d962 100644 --- a/tests/ui/needless_lifetimes.rs +++ b/tests/ui/needless_lifetimes.rs @@ -9,15 +9,18 @@ clippy::redundant_allocation, clippy::unnecessary_wraps, dyn_drop, - clippy::get_first + clippy::get_first, + elided_named_lifetimes )] extern crate proc_macros; use proc_macros::inline_macros; fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {} +//~^ needless_lifetimes fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {} +//~^ needless_lifetimes // No error; same lifetime on two params. fn same_lifetime_on_input<'a>(_x: &'a u8, _y: &'a u8) {} @@ -28,6 +31,7 @@ fn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) {} fn mut_and_static_input(_x: &mut u8, _y: &'static str) {} fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 { +//~^ needless_lifetimes x } @@ -40,6 +44,7 @@ fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 { // fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 // ^^^ fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 { +//~^ needless_lifetimes x } @@ -47,6 +52,7 @@ fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 { // fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 // ^^^ fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 { +//~^ needless_lifetimes y } @@ -64,6 +70,7 @@ fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 { // fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> // ^^^ fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> { +//~^ needless_lifetimes Ok(x) } @@ -71,6 +78,7 @@ fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> { // fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> // ^^^ fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> { +//~^ needless_lifetimes Ok(y) } @@ -80,11 +88,13 @@ fn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 { } fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> { +//~^ needless_lifetimes Ok(x) } // Where-clause, but without lifetimes. fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> +//~^ needless_lifetimes where T: Copy, { @@ -97,6 +107,7 @@ type Ref<'r> = &'r u8; fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {} fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} +//~^ needless_lifetimes // No error; bounded lifetime. fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {} @@ -121,6 +132,7 @@ where } fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> +//~^ needless_lifetimes where for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>, { @@ -151,6 +163,7 @@ struct X { impl X { fn self_and_out<'s>(&'s self) -> &'s u8 { + //~^ needless_lifetimes &self.x } @@ -158,6 +171,7 @@ impl X { // fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 // ^^^ fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 { + //~^ needless_lifetimes &self.x } @@ -165,10 +179,12 @@ impl X { // fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 // ^^^^^ fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 { + //~^ needless_lifetimes x } fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {} + //~^ needless_lifetimes // No error; same lifetimes on two params. fn self_and_same_in<'s>(&'s self, _x: &'s u8) {} @@ -188,6 +204,7 @@ fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 { } fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { +//~^ needless_lifetimes unimplemented!() } @@ -206,6 +223,7 @@ fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str { // fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str // ^^ fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { +//~^ needless_lifetimes unimplemented!() } @@ -214,6 +232,7 @@ fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { // fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str // ^^^^ fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str { +//~^ needless_lifetimes unimplemented!() } @@ -229,12 +248,14 @@ fn trait_obj_elided<'a>(_arg: &'a dyn WithLifetime) -> &'a str { // Should warn because there is no lifetime on `Drop`, so this would be // unambiguous if we elided the lifetime. fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str { +//~^ needless_lifetimes unimplemented!() } type FooAlias<'a> = Foo<'a>; fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { +//~^ needless_lifetimes unimplemented!() } @@ -253,6 +274,7 @@ fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str { // fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str // ^^ fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { +//~^ needless_lifetimes unimplemented!() } @@ -261,10 +283,12 @@ fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { // fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str // ^^^^^^^^^ fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str { +//~^ needless_lifetimes unimplemented!() } fn named_input_elided_output<'a>(_arg: &'a str) -> &str { +//~^ needless_lifetimes unimplemented!() } @@ -273,6 +297,7 @@ fn elided_input_named_output<'a>(_arg: &str) -> &'a str { } fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { +//~^ needless_lifetimes unimplemented!() } fn trait_bound<'a, T: WithLifetime<'a>>(_: &'a u8, _: T) { @@ -309,6 +334,7 @@ struct Cow<'a> { x: &'a str, } fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { +//~^ needless_lifetimes unimplemented!() } @@ -316,10 +342,12 @@ fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { mod issue4291 { trait BadTrait { fn needless_lt<'a>(x: &'a u8) {} + //~^ needless_lifetimes } impl BadTrait for () { fn needless_lt<'a>(_x: &'a u8) {} + //~^ needless_lifetimes } } @@ -331,8 +359,10 @@ mod issue2944 { } impl<'a> Foo for Baz<'a> {} + //~^ needless_lifetimes impl Bar { fn baz<'a>(&'a self) -> impl Foo + 'a { + //~^ needless_lifetimes Baz { bar: self } } } @@ -365,6 +395,7 @@ mod nested_elision_sites { f(i) } fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 { + //~^ needless_lifetimes f(i) } @@ -374,6 +405,7 @@ mod nested_elision_sites { } // lint fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 { + //~^ needless_lifetimes f(i) } @@ -386,6 +418,7 @@ mod nested_elision_sites { } // lint fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32 + //~^ needless_lifetimes where T: Fn(&i32) -> &i32, { @@ -401,6 +434,7 @@ mod nested_elision_sites { } // lint fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 { + //~^ needless_lifetimes f(i) } @@ -414,9 +448,11 @@ mod nested_elision_sites { // lint fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 { + //~^ needless_lifetimes |f| 42 } fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) { + //~^ needless_lifetimes |f| () } } @@ -439,17 +475,21 @@ mod issue7296 { struct Foo; impl Foo { fn implicit<'a>(&'a self) -> &'a () { + //~^ needless_lifetimes &() } fn implicit_mut<'a>(&'a mut self) -> &'a () { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit<'a>(self: &'a Arc) -> &'a () { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit_mut<'a>(self: &'a mut Rc) -> &'a () { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.80"] @@ -462,20 +502,25 @@ mod issue7296 { } fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a () { + //~^ needless_lifetimes &() } } trait Bar { fn implicit<'a>(&'a self) -> &'a (); + //~^ needless_lifetimes fn implicit_provided<'a>(&'a self) -> &'a () { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit<'a>(self: &'a Arc) -> &'a (); + //~^ needless_lifetimes #[clippy::msrv = "1.81"] fn explicit_provided<'a>(self: &'a Arc) -> &'a () { + //~^ needless_lifetimes &() } #[clippy::msrv = "1.80"] @@ -486,7 +531,9 @@ mod issue7296 { } fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a (); + //~^ needless_lifetimes fn lifetime_elsewhere_provided<'a>(self: Box, here: &'a ()) -> &'a () { + //~^ needless_lifetimes &() } } @@ -496,8 +543,10 @@ mod pr_9743_false_negative_fix { #![allow(unused)] fn foo<'a>(x: &'a u8, y: &'_ u8) {} + //~^ needless_lifetimes fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {} + //~^ needless_lifetimes } mod pr_9743_output_lifetime_checks { @@ -505,11 +554,13 @@ mod pr_9743_output_lifetime_checks { // lint: only one input fn one_input<'a>(x: &'a u8) -> &'a u8 { + //~^ needless_lifetimes unimplemented!() } // lint: multiple inputs, output would not be elided fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 { + //~^ needless_lifetimes unimplemented!() } @@ -526,6 +577,7 @@ mod in_macro { // lint local macro expands to function with needless lifetimes inline! { fn one_input<'a>(x: &'a u8) -> &'a u8 { + //~^ needless_lifetimes unimplemented!() } } @@ -621,6 +673,7 @@ mod issue13923 { } impl<'t, 'py> ContentString<'t> { + //~^ needless_lifetimes // `'py` can be elided because of `&self` fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { match self { @@ -631,6 +684,7 @@ mod issue13923 { } impl<'t, 'py> ContentString<'t> { + //~^ needless_lifetimes // `'py` can be elided because of `&'_ self` fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { match self { @@ -651,6 +705,7 @@ mod issue13923 { } impl<'t, 'py> ContentString<'t> { + //~^ needless_lifetimes // `'py` can be elided because of `&Self` fn map_content5( self: std::pin::Pin<&Self>, @@ -672,6 +727,7 @@ mod issue13923 { // `'c` cannot be elided because we have several input lifetimes fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 { &x.b + //~^ needless_borrow } } diff --git a/tests/ui/needless_lifetimes.stderr b/tests/ui/needless_lifetimes.stderr index 465d529bf16c..b1d1c88a2968 100644 --- a/tests/ui/needless_lifetimes.stderr +++ b/tests/ui/needless_lifetimes.stderr @@ -1,16 +1,5 @@ -error: elided lifetime has a name - --> tests/ui/needless_lifetimes.rs:267:52 - | -LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str { - | -- ^ this elided lifetime gets resolved as `'a` - | | - | lifetime `'a` declared here - | - = note: `-D elided-named-lifetimes` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(elided_named_lifetimes)]` - error: the following explicit lifetimes could be elided: 'a, 'b - --> tests/ui/needless_lifetimes.rs:18:23 + --> tests/ui/needless_lifetimes.rs:19:23 | LL | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {} | ^^ ^^ ^^ ^^ @@ -24,7 +13,7 @@ LL + fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {} | error: the following explicit lifetimes could be elided: 'a, 'b - --> tests/ui/needless_lifetimes.rs:20:24 + --> tests/ui/needless_lifetimes.rs:22:24 | LL | fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {} | ^^ ^^ ^^ ^^ @@ -36,7 +25,7 @@ LL + fn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:30:15 + --> tests/ui/needless_lifetimes.rs:33:15 | LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 { | ^^ ^^ ^^ @@ -48,7 +37,7 @@ LL + fn in_and_out(x: &u8, _y: u8) -> &u8 { | error: the following explicit lifetimes could be elided: 'b - --> tests/ui/needless_lifetimes.rs:42:31 + --> tests/ui/needless_lifetimes.rs:46:31 | LL | fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 { | ^^ ^^ @@ -60,7 +49,7 @@ LL + fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:49:27 + --> tests/ui/needless_lifetimes.rs:54:27 | LL | fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 { | ^^ ^^ @@ -72,7 +61,7 @@ LL + fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 { | error: the following explicit lifetimes could be elided: 'b - --> tests/ui/needless_lifetimes.rs:66:26 + --> tests/ui/needless_lifetimes.rs:72:26 | LL | fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> { | ^^ ^^ @@ -84,7 +73,7 @@ LL + fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:73:22 + --> tests/ui/needless_lifetimes.rs:80:22 | LL | fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> { | ^^ ^^ @@ -96,7 +85,7 @@ LL + fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:82:21 + --> tests/ui/needless_lifetimes.rs:90:21 | LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> { | ^^ ^^ ^^ @@ -108,7 +97,7 @@ LL + fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:87:28 + --> tests/ui/needless_lifetimes.rs:96:28 | LL | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> | ^^ ^^ ^^ @@ -120,7 +109,7 @@ LL + fn where_clause_without_lt(x: &u8, _y: u8) -> Result<&u8, ()> | error: the following explicit lifetimes could be elided: 'a, 'b - --> tests/ui/needless_lifetimes.rs:99:21 + --> tests/ui/needless_lifetimes.rs:109:21 | LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} | ^^ ^^ ^^ ^^ @@ -132,7 +121,7 @@ LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:123:15 + --> tests/ui/needless_lifetimes.rs:134:15 | LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> | ^^ ^^ ^^ @@ -144,7 +133,7 @@ LL + fn fn_bound_2(_m: Lt<'_, I>, _f: F) -> Lt<'_, I> | error: the following explicit lifetimes could be elided: 's - --> tests/ui/needless_lifetimes.rs:153:21 + --> tests/ui/needless_lifetimes.rs:165:21 | LL | fn self_and_out<'s>(&'s self) -> &'s u8 { | ^^ ^^ ^^ @@ -156,7 +145,7 @@ LL + fn self_and_out(&self) -> &u8 { | error: the following explicit lifetimes could be elided: 't - --> tests/ui/needless_lifetimes.rs:160:30 + --> tests/ui/needless_lifetimes.rs:173:30 | LL | fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 { | ^^ ^^ @@ -168,7 +157,7 @@ LL + fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 { | error: the following explicit lifetimes could be elided: 's - --> tests/ui/needless_lifetimes.rs:167:26 + --> tests/ui/needless_lifetimes.rs:181:26 | LL | fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 { | ^^ ^^ @@ -180,7 +169,7 @@ LL + fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 { | error: the following explicit lifetimes could be elided: 's, 't - --> tests/ui/needless_lifetimes.rs:171:29 + --> tests/ui/needless_lifetimes.rs:186:29 | LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {} | ^^ ^^ ^^ ^^ @@ -192,7 +181,7 @@ LL + fn distinct_self_and_in(&self, _x: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:190:19 + --> tests/ui/needless_lifetimes.rs:206:19 | LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { | ^^ ^^ ^^ @@ -204,7 +193,7 @@ LL + fn struct_with_lt(_foo: Foo<'_>) -> &str { | error: the following explicit lifetimes could be elided: 'b - --> tests/ui/needless_lifetimes.rs:208:25 + --> tests/ui/needless_lifetimes.rs:225:25 | LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { | ^^ ^^ @@ -216,7 +205,7 @@ LL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:216:21 + --> tests/ui/needless_lifetimes.rs:234:21 | LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str { | ^^ ^^ @@ -228,7 +217,7 @@ LL + fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:231:22 + --> tests/ui/needless_lifetimes.rs:250:22 | LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str { | ^^ ^^ ^^ @@ -240,7 +229,7 @@ LL + fn trait_obj_elided2(_arg: &dyn Drop) -> &str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:237:18 + --> tests/ui/needless_lifetimes.rs:257:18 | LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { | ^^ ^^ ^^ @@ -252,7 +241,7 @@ LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str { | error: the following explicit lifetimes could be elided: 'b - --> tests/ui/needless_lifetimes.rs:255:24 + --> tests/ui/needless_lifetimes.rs:276:24 | LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { | ^^ ^^ @@ -264,7 +253,7 @@ LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:263:20 + --> tests/ui/needless_lifetimes.rs:285:20 | LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str { | ^^ ^^ @@ -276,7 +265,7 @@ LL + fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:267:30 + --> tests/ui/needless_lifetimes.rs:290:30 | LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str { | ^^ ^^ ^ @@ -288,7 +277,7 @@ LL + fn named_input_elided_output(_arg: &str) -> &str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:275:19 + --> tests/ui/needless_lifetimes.rs:299:19 | LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { | ^^ ^^ @@ -300,7 +289,7 @@ LL + fn trait_bound_ok>(_: &u8, _: T) { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:311:24 + --> tests/ui/needless_lifetimes.rs:336:24 | LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { | ^^ ^^ ^^ @@ -312,7 +301,7 @@ LL + fn out_return_type_lts(e: &str) -> Cow<'_> { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:318:24 + --> tests/ui/needless_lifetimes.rs:344:24 | LL | fn needless_lt<'a>(x: &'a u8) {} | ^^ ^^ @@ -324,7 +313,7 @@ LL + fn needless_lt(x: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:322:24 + --> tests/ui/needless_lifetimes.rs:349:24 | LL | fn needless_lt<'a>(_x: &'a u8) {} | ^^ ^^ @@ -336,7 +325,7 @@ LL + fn needless_lt(_x: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:333:10 + --> tests/ui/needless_lifetimes.rs:361:10 | LL | impl<'a> Foo for Baz<'a> {} | ^^ ^^ @@ -348,7 +337,7 @@ LL + impl Foo for Baz<'_> {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:335:16 + --> tests/ui/needless_lifetimes.rs:364:16 | LL | fn baz<'a>(&'a self) -> impl Foo + 'a { | ^^ ^^ ^^ @@ -360,7 +349,7 @@ LL + fn baz(&self) -> impl Foo + '_ { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:367:55 + --> tests/ui/needless_lifetimes.rs:397:55 | LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 { | ^^ ^^ ^^ @@ -372,7 +361,7 @@ LL + fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(& | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:376:26 + --> tests/ui/needless_lifetimes.rs:407:26 | LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 { | ^^ ^^ ^^ @@ -384,7 +373,7 @@ LL + fn generics_elidable &i32>(i: &i32, f: T) -> &i32 { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:388:30 + --> tests/ui/needless_lifetimes.rs:420:30 | LL | fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32 | ^^ ^^ ^^ @@ -396,7 +385,7 @@ LL + fn where_clause_elidable(i: &i32, f: T) -> &i32 | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:403:28 + --> tests/ui/needless_lifetimes.rs:436:28 | LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 { | ^^ ^^ ^^ @@ -408,7 +397,7 @@ LL + fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:416:28 + --> tests/ui/needless_lifetimes.rs:450:28 | LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 { | ^^ ^^ @@ -420,7 +409,7 @@ LL + fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:419:28 + --> tests/ui/needless_lifetimes.rs:454:28 | LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) { | ^^ ^^ @@ -432,7 +421,7 @@ LL + fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:441:21 + --> tests/ui/needless_lifetimes.rs:477:21 | LL | fn implicit<'a>(&'a self) -> &'a () { | ^^ ^^ ^^ @@ -444,7 +433,7 @@ LL + fn implicit(&self) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:444:25 + --> tests/ui/needless_lifetimes.rs:481:25 | LL | fn implicit_mut<'a>(&'a mut self) -> &'a () { | ^^ ^^ ^^ @@ -456,7 +445,7 @@ LL + fn implicit_mut(&mut self) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:448:21 + --> tests/ui/needless_lifetimes.rs:486:21 | LL | fn explicit<'a>(self: &'a Arc) -> &'a () { | ^^ ^^ ^^ @@ -468,7 +457,7 @@ LL + fn explicit(self: &Arc) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:452:25 + --> tests/ui/needless_lifetimes.rs:491:25 | LL | fn explicit_mut<'a>(self: &'a mut Rc) -> &'a () { | ^^ ^^ ^^ @@ -480,7 +469,7 @@ LL + fn explicit_mut(self: &mut Rc) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:464:31 + --> tests/ui/needless_lifetimes.rs:504:31 | LL | fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a () { | ^^ ^^ ^^ @@ -492,7 +481,7 @@ LL + fn lifetime_elsewhere(self: Box, here: &()) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:470:21 + --> tests/ui/needless_lifetimes.rs:511:21 | LL | fn implicit<'a>(&'a self) -> &'a (); | ^^ ^^ ^^ @@ -504,7 +493,7 @@ LL + fn implicit(&self) -> &(); | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:471:30 + --> tests/ui/needless_lifetimes.rs:513:30 | LL | fn implicit_provided<'a>(&'a self) -> &'a () { | ^^ ^^ ^^ @@ -516,7 +505,7 @@ LL + fn implicit_provided(&self) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:476:21 + --> tests/ui/needless_lifetimes.rs:519:21 | LL | fn explicit<'a>(self: &'a Arc) -> &'a (); | ^^ ^^ ^^ @@ -528,7 +517,7 @@ LL + fn explicit(self: &Arc) -> &(); | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:478:30 + --> tests/ui/needless_lifetimes.rs:522:30 | LL | fn explicit_provided<'a>(self: &'a Arc) -> &'a () { | ^^ ^^ ^^ @@ -540,7 +529,7 @@ LL + fn explicit_provided(self: &Arc) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:488:31 + --> tests/ui/needless_lifetimes.rs:533:31 | LL | fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a (); | ^^ ^^ ^^ @@ -552,7 +541,7 @@ LL + fn lifetime_elsewhere(self: Box, here: &()) -> &(); | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:489:40 + --> tests/ui/needless_lifetimes.rs:535:40 | LL | fn lifetime_elsewhere_provided<'a>(self: Box, here: &'a ()) -> &'a () { | ^^ ^^ ^^ @@ -564,7 +553,7 @@ LL + fn lifetime_elsewhere_provided(self: Box, here: &()) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:498:12 + --> tests/ui/needless_lifetimes.rs:545:12 | LL | fn foo<'a>(x: &'a u8, y: &'_ u8) {} | ^^ ^^ @@ -576,7 +565,7 @@ LL + fn foo(x: &u8, y: &'_ u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:500:12 + --> tests/ui/needless_lifetimes.rs:548:12 | LL | fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {} | ^^ ^^ @@ -588,7 +577,7 @@ LL + fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:507:18 + --> tests/ui/needless_lifetimes.rs:556:18 | LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { | ^^ ^^ ^^ @@ -600,7 +589,7 @@ LL + fn one_input(x: &u8) -> &u8 { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:512:42 + --> tests/ui/needless_lifetimes.rs:562:42 | LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 { | ^^ ^^ @@ -612,7 +601,7 @@ LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:528:22 + --> tests/ui/needless_lifetimes.rs:579:22 | LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { | ^^ ^^ ^^ @@ -625,39 +614,41 @@ LL + fn one_input(x: &u8) -> &u8 { | error: the following explicit lifetimes could be elided: 'py - --> tests/ui/needless_lifetimes.rs:623:14 + --> tests/ui/needless_lifetimes.rs:675:14 | LL | impl<'t, 'py> ContentString<'t> { | ^^^ -LL | // `'py` can be elided because of `&self` +... LL | fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { | ^^^ | help: elide the lifetimes | LL ~ impl<'t> ContentString<'t> { +LL | LL | // `'py` can be elided because of `&self` LL ~ fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { | error: the following explicit lifetimes could be elided: 'py - --> tests/ui/needless_lifetimes.rs:633:14 + --> tests/ui/needless_lifetimes.rs:686:14 | LL | impl<'t, 'py> ContentString<'t> { | ^^^ -LL | // `'py` can be elided because of `&'_ self` +... LL | fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { | ^^^ | help: elide the lifetimes | LL ~ impl<'t> ContentString<'t> { +LL | LL | // `'py` can be elided because of `&'_ self` LL ~ fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { | error: the following explicit lifetimes could be elided: 'py - --> tests/ui/needless_lifetimes.rs:653:14 + --> tests/ui/needless_lifetimes.rs:707:14 | LL | impl<'t, 'py> ContentString<'t> { | ^^^ @@ -668,14 +659,14 @@ LL | ) -> Content<'t, 'py> { help: elide the lifetimes | LL ~ impl<'t> ContentString<'t> { -LL | // `'py` can be elided because of `&Self` +LL | ... LL | o: &'t str, LL ~ ) -> Content<'t, '_> { | error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_lifetimes.rs:674:9 + --> tests/ui/needless_lifetimes.rs:729:9 | LL | &x.b | ^^^^ help: change this to: `x.b` @@ -683,5 +674,5 @@ LL | &x.b = note: `-D clippy::needless-borrow` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]` -error: aborting due to 56 previous errors +error: aborting due to 55 previous errors diff --git a/tests/ui/needless_match.fixed b/tests/ui/needless_match.fixed index 06c6169d0da0..b2c2bbfaa361 100644 --- a/tests/ui/needless_match.fixed +++ b/tests/ui/needless_match.fixed @@ -61,6 +61,7 @@ fn result_match() { fn if_let_option() { let _ = Some(1); + //~^ needless_match fn do_something() {} @@ -96,7 +97,9 @@ fn if_let_option_result() -> Result<(), ()> { fn if_let_result() { let x: Result = Ok(1); let _: Result = x; + //~^ needless_match let _: Result = x; + //~^ needless_match // Input type mismatch, don't trigger #[allow(clippy::question_mark)] let _: Result = if let Err(e) = Ok(1) { Err(e) } else { x }; diff --git a/tests/ui/needless_match.rs b/tests/ui/needless_match.rs index 6b71de68e1be..848490d9b35e 100644 --- a/tests/ui/needless_match.rs +++ b/tests/ui/needless_match.rs @@ -13,6 +13,7 @@ enum Simple { fn useless_match() { let i = 10; let _: i32 = match i { + //~^ needless_match 0 => 0, 1 => 1, 2 => 2, @@ -20,6 +21,7 @@ fn useless_match() { }; let s = "test"; let _: &str = match s { + //~^ needless_match "a" => "a", "b" => "b", s => s, @@ -29,6 +31,7 @@ fn useless_match() { fn custom_type_match() { let se = Simple::A; let _: Simple = match se { + //~^ needless_match Simple::A => Simple::A, Simple::B => Simple::B, Simple::C => Simple::C, @@ -51,6 +54,7 @@ fn custom_type_match() { fn option_match(x: Option) { let _: Option = match x { + //~^ needless_match Some(a) => Some(a), None => None, }; @@ -67,10 +71,12 @@ fn func_ret_err(err: T) -> Result { fn result_match() { let _: Result = match Ok(1) { + //~^ needless_match Ok(a) => Ok(a), Err(err) => Err(err), }; let _: Result = match func_ret_err(0_i32) { + //~^ needless_match Err(err) => Err(err), Ok(a) => Ok(a), }; @@ -84,6 +90,7 @@ fn result_match() { fn if_let_option() { let _ = if let Some(a) = Some(1) { Some(a) } else { None }; + //~^ needless_match fn do_something() {} @@ -119,7 +126,9 @@ fn if_let_option_result() -> Result<(), ()> { fn if_let_result() { let x: Result = Ok(1); let _: Result = if let Err(e) = x { Err(e) } else { x }; + //~^ needless_match let _: Result = if let Ok(val) = x { Ok(val) } else { x }; + //~^ needless_match // Input type mismatch, don't trigger #[allow(clippy::question_mark)] let _: Result = if let Err(e) = Ok(1) { Err(e) } else { x }; @@ -127,6 +136,7 @@ fn if_let_result() { fn if_let_custom_enum(x: Simple) { let _: Simple = if let Simple::A = x { + //~^ needless_match Simple::A } else if let Simple::B = x { Simple::B @@ -166,6 +176,7 @@ mod issue8542 { let bb = false; let _: Complex = match ce { + //~^ needless_match Complex::A(a) => Complex::A(a), Complex::B(a, b) => Complex::B(a, b), Complex::C(a, b, c) => Complex::C(a, b, c), @@ -250,12 +261,14 @@ mod issue9084 { // should lint let _ = match e { + //~^ needless_match _ if some_bool => e, _ => e, }; // should lint let _ = match e { + //~^ needless_match Some(i) => Some(i), _ if some_bool => e, _ => e, @@ -337,6 +350,7 @@ pub fn issue13574() -> Option<()> { // Same const, should lint let _ = { if let Some(num) = A { + //~^ needless_match Some(num) } else if let Some(num) = A { Some(num) diff --git a/tests/ui/needless_match.stderr b/tests/ui/needless_match.stderr index 1410585cb2e3..719b0ef88469 100644 --- a/tests/ui/needless_match.stderr +++ b/tests/ui/needless_match.stderr @@ -3,6 +3,7 @@ error: this match expression is unnecessary | LL | let _: i32 = match i { | __________________^ +LL | | LL | | 0 => 0, LL | | 1 => 1, LL | | 2 => 2, @@ -14,10 +15,11 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::needless_match)]` error: this match expression is unnecessary - --> tests/ui/needless_match.rs:22:19 + --> tests/ui/needless_match.rs:23:19 | LL | let _: &str = match s { | ___________________^ +LL | | LL | | "a" => "a", LL | | "b" => "b", LL | | s => s, @@ -25,10 +27,11 @@ LL | | }; | |_____^ help: replace it with: `s` error: this match expression is unnecessary - --> tests/ui/needless_match.rs:31:21 + --> tests/ui/needless_match.rs:33:21 | LL | let _: Simple = match se { | _____________________^ +LL | | LL | | Simple::A => Simple::A, LL | | Simple::B => Simple::B, LL | | Simple::C => Simple::C, @@ -37,94 +40,99 @@ LL | | }; | |_____^ help: replace it with: `se` error: this match expression is unnecessary - --> tests/ui/needless_match.rs:53:26 + --> tests/ui/needless_match.rs:56:26 | LL | let _: Option = match x { | __________________________^ +LL | | LL | | Some(a) => Some(a), LL | | None => None, LL | | }; | |_____^ help: replace it with: `x` error: this match expression is unnecessary - --> tests/ui/needless_match.rs:69:31 + --> tests/ui/needless_match.rs:73:31 | LL | let _: Result = match Ok(1) { | _______________________________^ +LL | | LL | | Ok(a) => Ok(a), LL | | Err(err) => Err(err), LL | | }; | |_____^ help: replace it with: `Ok(1)` error: this match expression is unnecessary - --> tests/ui/needless_match.rs:73:31 + --> tests/ui/needless_match.rs:78:31 | LL | let _: Result = match func_ret_err(0_i32) { | _______________________________^ +LL | | LL | | Err(err) => Err(err), LL | | Ok(a) => Ok(a), LL | | }; | |_____^ help: replace it with: `func_ret_err(0_i32)` error: this if-let expression is unnecessary - --> tests/ui/needless_match.rs:86:13 + --> tests/ui/needless_match.rs:92:13 | LL | let _ = if let Some(a) = Some(1) { Some(a) } else { None }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)` error: this if-let expression is unnecessary - --> tests/ui/needless_match.rs:121:31 + --> tests/ui/needless_match.rs:128:31 | LL | let _: Result = if let Err(e) = x { Err(e) } else { x }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x` error: this if-let expression is unnecessary - --> tests/ui/needless_match.rs:122:31 + --> tests/ui/needless_match.rs:130:31 | LL | let _: Result = if let Ok(val) = x { Ok(val) } else { x }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x` error: this if-let expression is unnecessary - --> tests/ui/needless_match.rs:129:21 + --> tests/ui/needless_match.rs:138:21 | LL | let _: Simple = if let Simple::A = x { | _____________________^ +LL | | LL | | Simple::A LL | | } else if let Simple::B = x { -LL | | Simple::B ... | LL | | x LL | | }; | |_____^ help: replace it with: `x` error: this match expression is unnecessary - --> tests/ui/needless_match.rs:168:26 + --> tests/ui/needless_match.rs:178:26 | LL | let _: Complex = match ce { | __________________________^ +LL | | LL | | Complex::A(a) => Complex::A(a), LL | | Complex::B(a, b) => Complex::B(a, b), -LL | | Complex::C(a, b, c) => Complex::C(a, b, c), -LL | | Complex::D(E::VariantA(ea, eb), b) => Complex::D(E::VariantA(ea, eb), b), +... | LL | | Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(ea, eb), b), LL | | }; | |_________^ help: replace it with: `ce` error: this match expression is unnecessary - --> tests/ui/needless_match.rs:252:17 + --> tests/ui/needless_match.rs:263:17 | LL | let _ = match e { | _________________^ +LL | | LL | | _ if some_bool => e, LL | | _ => e, LL | | }; | |_________^ help: replace it with: `e` error: this match expression is unnecessary - --> tests/ui/needless_match.rs:258:17 + --> tests/ui/needless_match.rs:270:17 | LL | let _ = match e { | _________________^ +LL | | LL | | Some(i) => Some(i), LL | | _ if some_bool => e, LL | | _ => e, @@ -132,12 +140,12 @@ LL | | }; | |_________^ help: replace it with: `e` error: this if-let expression is unnecessary - --> tests/ui/needless_match.rs:339:9 + --> tests/ui/needless_match.rs:352:9 | LL | / if let Some(num) = A { +LL | | LL | | Some(num) LL | | } else if let Some(num) = A { -LL | | Some(num) ... | LL | | None LL | | } diff --git a/tests/ui/needless_maybe_sized.fixed b/tests/ui/needless_maybe_sized.fixed index 4d24a7cee619..68252ba54fd4 100644 --- a/tests/ui/needless_maybe_sized.fixed +++ b/tests/ui/needless_maybe_sized.fixed @@ -7,27 +7,34 @@ extern crate proc_macros; use proc_macros::external; fn directly(t: &T) {} +//~^ needless_maybe_sized trait A: Sized {} trait B: A {} fn depth_1(t: &T) {} +//~^ needless_maybe_sized fn depth_2(t: &T) {} +//~^ needless_maybe_sized // We only need to show one fn multiple_paths(t: &T) {} +//~^ needless_maybe_sized fn in_where(t: &T) where T: Sized, + //~^ needless_maybe_sized { } fn mixed_1(t: &T) + //~^ needless_maybe_sized { } fn mixed_2(t: &T) +//~^ needless_maybe_sized where T: Sized, { @@ -36,38 +43,50 @@ where fn mixed_3(t: &T) where T: Sized, + //~^ needless_maybe_sized { } struct Struct(T); +//~^ needless_maybe_sized impl Struct { +//~^ needless_maybe_sized fn method(&self) {} + //~^ needless_maybe_sized } enum Enum { +//~^ needless_maybe_sized Variant(&'static T), } union Union<'a, T: Sized> { +//~^ needless_maybe_sized a: &'a T, } trait Trait { +//~^ needless_maybe_sized fn trait_method() {} + //~^ needless_maybe_sized type GAT; + //~^ needless_maybe_sized type Assoc: Sized + ?Sized; // False negative } trait SecondInTrait: Send + Sized {} fn second_in_trait() {} +//~^ needless_maybe_sized fn impl_trait(_: &(impl Sized)) {} +//~^ needless_maybe_sized trait GenericTrait: Sized {} fn in_generic_trait, U>() {} +//~^ needless_maybe_sized mod larger_graph { // C1 C2 Sized @@ -83,6 +102,7 @@ mod larger_graph { trait A1: B1 + B2 {} fn larger_graph() {} + //~^ needless_maybe_sized } // Should not lint diff --git a/tests/ui/needless_maybe_sized.rs b/tests/ui/needless_maybe_sized.rs index ef66f9a4f2ae..0cafc0d9ff6e 100644 --- a/tests/ui/needless_maybe_sized.rs +++ b/tests/ui/needless_maybe_sized.rs @@ -7,29 +7,36 @@ extern crate proc_macros; use proc_macros::external; fn directly(t: &T) {} +//~^ needless_maybe_sized trait A: Sized {} trait B: A {} fn depth_1(t: &T) {} +//~^ needless_maybe_sized fn depth_2(t: &T) {} +//~^ needless_maybe_sized // We only need to show one fn multiple_paths(t: &T) {} +//~^ needless_maybe_sized fn in_where(t: &T) where T: Sized + ?Sized, + //~^ needless_maybe_sized { } fn mixed_1(t: &T) where T: ?Sized, + //~^ needless_maybe_sized { } fn mixed_2(t: &T) +//~^ needless_maybe_sized where T: Sized, { @@ -39,38 +46,50 @@ fn mixed_3(t: &T) where T: Sized, T: ?Sized, + //~^ needless_maybe_sized { } struct Struct(T); +//~^ needless_maybe_sized impl Struct { +//~^ needless_maybe_sized fn method(&self) {} + //~^ needless_maybe_sized } enum Enum { +//~^ needless_maybe_sized Variant(&'static T), } union Union<'a, T: Sized + ?Sized> { +//~^ needless_maybe_sized a: &'a T, } trait Trait { +//~^ needless_maybe_sized fn trait_method() {} + //~^ needless_maybe_sized type GAT; + //~^ needless_maybe_sized type Assoc: Sized + ?Sized; // False negative } trait SecondInTrait: Send + Sized {} fn second_in_trait() {} +//~^ needless_maybe_sized fn impl_trait(_: &(impl Sized + ?Sized)) {} +//~^ needless_maybe_sized trait GenericTrait: Sized {} fn in_generic_trait + ?Sized, U>() {} +//~^ needless_maybe_sized mod larger_graph { // C1 C2 Sized @@ -86,6 +105,7 @@ mod larger_graph { trait A1: B1 + B2 {} fn larger_graph() {} + //~^ needless_maybe_sized } // Should not lint diff --git a/tests/ui/needless_maybe_sized.stderr b/tests/ui/needless_maybe_sized.stderr index 3b1d2b49b062..30dcaa48e429 100644 --- a/tests/ui/needless_maybe_sized.stderr +++ b/tests/ui/needless_maybe_sized.stderr @@ -18,13 +18,13 @@ LL + fn directly(t: &T) {} | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:14:19 + --> tests/ui/needless_maybe_sized.rs:15:19 | LL | fn depth_1(t: &T) {} | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:14:15 + --> tests/ui/needless_maybe_sized.rs:15:15 | LL | fn depth_1(t: &T) {} | ^ @@ -36,13 +36,13 @@ LL + fn depth_1(t: &T) {} | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:15:19 + --> tests/ui/needless_maybe_sized.rs:17:19 | LL | fn depth_2(t: &T) {} | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:15:15 + --> tests/ui/needless_maybe_sized.rs:17:15 | LL | fn depth_2(t: &T) {} | ^ @@ -55,13 +55,13 @@ LL + fn depth_2(t: &T) {} | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:18:30 + --> tests/ui/needless_maybe_sized.rs:21:30 | LL | fn multiple_paths(t: &T) {} | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:18:22 + --> tests/ui/needless_maybe_sized.rs:21:22 | LL | fn multiple_paths(t: &T) {} | ^ @@ -73,13 +73,13 @@ LL + fn multiple_paths(t: &T) {} | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:22:16 + --> tests/ui/needless_maybe_sized.rs:26:16 | LL | T: Sized + ?Sized, | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:22:8 + --> tests/ui/needless_maybe_sized.rs:26:8 | LL | T: Sized + ?Sized, | ^^^^^ @@ -90,13 +90,13 @@ LL + T: Sized, | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:28:8 + --> tests/ui/needless_maybe_sized.rs:33:8 | LL | T: ?Sized, | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:26:15 + --> tests/ui/needless_maybe_sized.rs:31:15 | LL | fn mixed_1(t: &T) | ^^^^^ @@ -107,13 +107,13 @@ LL - T: ?Sized, | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:32:15 + --> tests/ui/needless_maybe_sized.rs:38:15 | LL | fn mixed_2(t: &T) | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:34:8 + --> tests/ui/needless_maybe_sized.rs:41:8 | LL | T: Sized, | ^^^^^ @@ -124,13 +124,13 @@ LL + fn mixed_2(t: &T) | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:41:8 + --> tests/ui/needless_maybe_sized.rs:48:8 | LL | T: ?Sized, | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:40:8 + --> tests/ui/needless_maybe_sized.rs:47:8 | LL | T: Sized, | ^^^^^ @@ -142,13 +142,13 @@ LL + T: Sized, | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:45:26 + --> tests/ui/needless_maybe_sized.rs:53:26 | LL | struct Struct(T); | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:45:18 + --> tests/ui/needless_maybe_sized.rs:53:18 | LL | struct Struct(T); | ^^^^^ @@ -159,13 +159,13 @@ LL + struct Struct(T); | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:47:17 + --> tests/ui/needless_maybe_sized.rs:56:17 | LL | impl Struct { | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:47:9 + --> tests/ui/needless_maybe_sized.rs:56:9 | LL | impl Struct { | ^^^^^ @@ -176,13 +176,13 @@ LL + impl Struct { | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:48:26 + --> tests/ui/needless_maybe_sized.rs:58:26 | LL | fn method(&self) {} | ^^^^^^ | note: `U` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:48:18 + --> tests/ui/needless_maybe_sized.rs:58:18 | LL | fn method(&self) {} | ^^^^^ @@ -193,13 +193,13 @@ LL + fn method(&self) {} | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:51:22 + --> tests/ui/needless_maybe_sized.rs:62:22 | LL | enum Enum { | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:51:14 + --> tests/ui/needless_maybe_sized.rs:62:14 | LL | enum Enum { | ^^^^^ @@ -210,13 +210,13 @@ LL + enum Enum { | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:55:28 + --> tests/ui/needless_maybe_sized.rs:67:28 | LL | union Union<'a, T: Sized + ?Sized> { | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:55:20 + --> tests/ui/needless_maybe_sized.rs:67:20 | LL | union Union<'a, T: Sized + ?Sized> { | ^^^^^ @@ -227,13 +227,13 @@ LL + union Union<'a, T: Sized> { | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:59:24 + --> tests/ui/needless_maybe_sized.rs:72:24 | LL | trait Trait { | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:59:16 + --> tests/ui/needless_maybe_sized.rs:72:16 | LL | trait Trait { | ^^^^^ @@ -244,13 +244,13 @@ LL + trait Trait { | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:60:32 + --> tests/ui/needless_maybe_sized.rs:74:32 | LL | fn trait_method() {} | ^^^^^^ | note: `U` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:60:24 + --> tests/ui/needless_maybe_sized.rs:74:24 | LL | fn trait_method() {} | ^^^^^ @@ -261,13 +261,13 @@ LL + fn trait_method() {} | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:62:25 + --> tests/ui/needless_maybe_sized.rs:77:25 | LL | type GAT; | ^^^^^^ | note: `U` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:62:17 + --> tests/ui/needless_maybe_sized.rs:77:17 | LL | type GAT; | ^^^^^ @@ -278,13 +278,13 @@ LL + type GAT; | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:68:23 + --> tests/ui/needless_maybe_sized.rs:84:23 | LL | fn second_in_trait() {} | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:68:32 + --> tests/ui/needless_maybe_sized.rs:84:32 | LL | fn second_in_trait() {} | ^^^^^^^^^^^^^ @@ -296,13 +296,13 @@ LL + fn second_in_trait() {} | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:70:33 + --> tests/ui/needless_maybe_sized.rs:87:33 | LL | fn impl_trait(_: &(impl Sized + ?Sized)) {} | ^^^^^^ | note: `impl Sized + ?Sized` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:70:25 + --> tests/ui/needless_maybe_sized.rs:87:25 | LL | fn impl_trait(_: &(impl Sized + ?Sized)) {} | ^^^^^ @@ -313,13 +313,13 @@ LL + fn impl_trait(_: &(impl Sized)) {} | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:73:42 + --> tests/ui/needless_maybe_sized.rs:91:42 | LL | fn in_generic_trait + ?Sized, U>() {} | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:73:24 + --> tests/ui/needless_maybe_sized.rs:91:24 | LL | fn in_generic_trait + ?Sized, U>() {} | ^^^^^^^^^^^^^^^ @@ -331,13 +331,13 @@ LL + fn in_generic_trait, U>() {} | error: `?Sized` bound is ignored because of a `Sized` requirement - --> tests/ui/needless_maybe_sized.rs:88:29 + --> tests/ui/needless_maybe_sized.rs:107:29 | LL | fn larger_graph() {} | ^^^^^^ | note: `T` cannot be unsized because of the bound - --> tests/ui/needless_maybe_sized.rs:88:24 + --> tests/ui/needless_maybe_sized.rs:107:24 | LL | fn larger_graph() {} | ^^ diff --git a/tests/ui/needless_option_as_deref.fixed b/tests/ui/needless_option_as_deref.fixed index 84eaf12fc139..5bb0244ee091 100644 --- a/tests/ui/needless_option_as_deref.fixed +++ b/tests/ui/needless_option_as_deref.fixed @@ -5,11 +5,14 @@ fn main() { // should lint let _: Option<&usize> = Some(&1); + //~^ needless_option_as_deref let _: Option<&mut usize> = Some(&mut 1); + //~^ needless_option_as_deref let mut y = 0; let mut x = Some(&mut y); let _ = x; + //~^ needless_option_as_deref // should not lint let _ = Some(Box::new(1)).as_deref(); diff --git a/tests/ui/needless_option_as_deref.rs b/tests/ui/needless_option_as_deref.rs index fff1e45d846f..9cd8afe0bc72 100644 --- a/tests/ui/needless_option_as_deref.rs +++ b/tests/ui/needless_option_as_deref.rs @@ -5,11 +5,14 @@ fn main() { // should lint let _: Option<&usize> = Some(&1).as_deref(); + //~^ needless_option_as_deref let _: Option<&mut usize> = Some(&mut 1).as_deref_mut(); + //~^ needless_option_as_deref let mut y = 0; let mut x = Some(&mut y); let _ = x.as_deref_mut(); + //~^ needless_option_as_deref // should not lint let _ = Some(Box::new(1)).as_deref(); diff --git a/tests/ui/needless_option_as_deref.stderr b/tests/ui/needless_option_as_deref.stderr index a05d0aa9276a..bd19dc75eed6 100644 --- a/tests/ui/needless_option_as_deref.stderr +++ b/tests/ui/needless_option_as_deref.stderr @@ -8,13 +8,13 @@ LL | let _: Option<&usize> = Some(&1).as_deref(); = help: to override `-D warnings` add `#[allow(clippy::needless_option_as_deref)]` error: derefed type is same as origin - --> tests/ui/needless_option_as_deref.rs:8:33 + --> tests/ui/needless_option_as_deref.rs:9:33 | LL | let _: Option<&mut usize> = Some(&mut 1).as_deref_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&mut 1)` error: derefed type is same as origin - --> tests/ui/needless_option_as_deref.rs:12:13 + --> tests/ui/needless_option_as_deref.rs:14:13 | LL | let _ = x.as_deref_mut(); | ^^^^^^^^^^^^^^^^ help: try: `x` diff --git a/tests/ui/needless_option_take.fixed b/tests/ui/needless_option_take.fixed index 6514b67ef7a7..ae2bfab0e06d 100644 --- a/tests/ui/needless_option_take.fixed +++ b/tests/ui/needless_option_take.fixed @@ -21,7 +21,8 @@ fn main() { let x = Some(3); x.as_ref(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + println!("Testing non erroneous option_take_on_temporary"); let mut x = Some(3); @@ -29,30 +30,38 @@ fn main() { let mut x = Some(3); let y = x.as_mut(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let y = x.replace(289); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let y = Some(3).as_mut(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let y = Option::as_mut(&mut x); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let x = return_option(); let x = return_option(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let x = MyStruct::get_option(); let x = MyStruct::get_option(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let mut my_vec = vec![1, 2, 3]; my_vec.push(4); let y = my_vec.first(); let y = my_vec.first(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let y = my_vec.first(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + } diff --git a/tests/ui/needless_option_take.rs b/tests/ui/needless_option_take.rs index c6807718a758..723930f59a11 100644 --- a/tests/ui/needless_option_take.rs +++ b/tests/ui/needless_option_take.rs @@ -21,7 +21,8 @@ fn main() { let x = Some(3); x.as_ref().take(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + println!("Testing non erroneous option_take_on_temporary"); let mut x = Some(3); @@ -29,30 +30,38 @@ fn main() { let mut x = Some(3); let y = x.as_mut().take(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let y = x.replace(289).take(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let y = Some(3).as_mut().take(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let y = Option::as_mut(&mut x).take(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let x = return_option(); let x = return_option().take(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let x = MyStruct::get_option(); let x = MyStruct::get_option().take(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let mut my_vec = vec![1, 2, 3]; my_vec.push(4); let y = my_vec.first(); let y = my_vec.first().take(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + let y = my_vec.first().take(); - //~^ ERROR: called `Option::take()` on a temporary value + //~^ needless_option_take + } diff --git a/tests/ui/needless_option_take.stderr b/tests/ui/needless_option_take.stderr index 3fc339ed79e2..271e1a0c7915 100644 --- a/tests/ui/needless_option_take.stderr +++ b/tests/ui/needless_option_take.stderr @@ -11,7 +11,7 @@ LL | x.as_ref().take(); = help: to override `-D warnings` add `#[allow(clippy::needless_option_take)]` error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:31:13 + --> tests/ui/needless_option_take.rs:32:13 | LL | let y = x.as_mut().take(); | ^^^^^^^^^^------- @@ -21,7 +21,7 @@ LL | let y = x.as_mut().take(); = note: `as_mut` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:33:13 + --> tests/ui/needless_option_take.rs:35:13 | LL | let y = x.replace(289).take(); | ^^^^^^^^^^^^^^------- @@ -31,7 +31,7 @@ LL | let y = x.replace(289).take(); = note: `replace` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:36:13 + --> tests/ui/needless_option_take.rs:39:13 | LL | let y = Some(3).as_mut().take(); | ^^^^^^^^^^^^^^^^------- @@ -41,7 +41,7 @@ LL | let y = Some(3).as_mut().take(); = note: `as_mut` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:39:13 + --> tests/ui/needless_option_take.rs:43:13 | LL | let y = Option::as_mut(&mut x).take(); | ^^^^^^^^^^^^^^^^^^^^^^------- @@ -51,7 +51,7 @@ LL | let y = Option::as_mut(&mut x).take(); = note: `as_mut` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:43:13 + --> tests/ui/needless_option_take.rs:48:13 | LL | let x = return_option().take(); | ^^^^^^^^^^^^^^^------- @@ -61,7 +61,7 @@ LL | let x = return_option().take(); = note: `return_option` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:47:13 + --> tests/ui/needless_option_take.rs:53:13 | LL | let x = MyStruct::get_option().take(); | ^^^^^^^^^^^^^^^^^^^^^^------- @@ -71,7 +71,7 @@ LL | let x = MyStruct::get_option().take(); = note: `get_option` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:53:13 + --> tests/ui/needless_option_take.rs:60:13 | LL | let y = my_vec.first().take(); | ^^^^^^^^^^^^^^------- @@ -81,7 +81,7 @@ LL | let y = my_vec.first().take(); = note: `first` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:56:13 + --> tests/ui/needless_option_take.rs:64:13 | LL | let y = my_vec.first().take(); | ^^^^^^^^^^^^^^------- diff --git a/tests/ui/needless_parens_on_range_literals.fixed b/tests/ui/needless_parens_on_range_literals.fixed index b4d9e3297c49..7abcbc0c6e32 100644 --- a/tests/ui/needless_parens_on_range_literals.fixed +++ b/tests/ui/needless_parens_on_range_literals.fixed @@ -5,9 +5,15 @@ fn main() { let _ = 'a'..='z'; + //~^ needless_parens_on_range_literals + //~| needless_parens_on_range_literals let _ = 'a'..'z'; + //~^ needless_parens_on_range_literals let _ = (1.)..2.; let _ = (1.)..2.; + //~^ needless_parens_on_range_literals let _ = 'a'..; + //~^ needless_parens_on_range_literals let _ = ..'z'; + //~^ needless_parens_on_range_literals } diff --git a/tests/ui/needless_parens_on_range_literals.rs b/tests/ui/needless_parens_on_range_literals.rs index 2f0e54f80d85..2a6f9305883b 100644 --- a/tests/ui/needless_parens_on_range_literals.rs +++ b/tests/ui/needless_parens_on_range_literals.rs @@ -5,9 +5,15 @@ fn main() { let _ = ('a')..=('z'); + //~^ needless_parens_on_range_literals + //~| needless_parens_on_range_literals let _ = 'a'..('z'); + //~^ needless_parens_on_range_literals let _ = (1.)..2.; let _ = (1.)..(2.); + //~^ needless_parens_on_range_literals let _ = ('a')..; + //~^ needless_parens_on_range_literals let _ = ..('z'); + //~^ needless_parens_on_range_literals } diff --git a/tests/ui/needless_parens_on_range_literals.stderr b/tests/ui/needless_parens_on_range_literals.stderr index d293ecce69fb..082b2cd8cade 100644 --- a/tests/ui/needless_parens_on_range_literals.stderr +++ b/tests/ui/needless_parens_on_range_literals.stderr @@ -14,25 +14,25 @@ LL | let _ = ('a')..=('z'); | ^^^^^ help: try: `'z'` error: needless parenthesis on range literals can be removed - --> tests/ui/needless_parens_on_range_literals.rs:8:18 + --> tests/ui/needless_parens_on_range_literals.rs:10:18 | LL | let _ = 'a'..('z'); | ^^^^^ help: try: `'z'` error: needless parenthesis on range literals can be removed - --> tests/ui/needless_parens_on_range_literals.rs:10:19 + --> tests/ui/needless_parens_on_range_literals.rs:13:19 | LL | let _ = (1.)..(2.); | ^^^^ help: try: `2.` error: needless parenthesis on range literals can be removed - --> tests/ui/needless_parens_on_range_literals.rs:11:13 + --> tests/ui/needless_parens_on_range_literals.rs:15:13 | LL | let _ = ('a')..; | ^^^^^ help: try: `'a'` error: needless parenthesis on range literals can be removed - --> tests/ui/needless_parens_on_range_literals.rs:12:15 + --> tests/ui/needless_parens_on_range_literals.rs:17:15 | LL | let _ = ..('z'); | ^^^^^ help: try: `'z'` diff --git a/tests/ui/needless_pass_by_ref_mut.rs b/tests/ui/needless_pass_by_ref_mut.rs index 162ec82aeded..415a13163805 100644 --- a/tests/ui/needless_pass_by_ref_mut.rs +++ b/tests/ui/needless_pass_by_ref_mut.rs @@ -9,7 +9,8 @@ use std::ptr::NonNull; fn foo(s: &mut Vec, b: &u32, x: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + *x += *b + s.len() as u32; } @@ -34,7 +35,8 @@ fn foo5(s: &mut Vec) { } fn foo6(s: &mut Vec) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + non_mut_ref(s); } @@ -44,10 +46,12 @@ struct Bar; impl Bar { fn bar(&mut self) {} - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut + fn mushroom(&self, vec: &mut Vec) -> usize { - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut + vec.len() } } @@ -124,35 +128,44 @@ async fn f7(x: &mut i32, y: i32, z: &mut i32, a: i32) { } async fn a1(x: &mut i32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + println!("{:?}", x); } async fn a2(x: &mut i32, y: String) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + println!("{:?}", x); } async fn a3(x: &mut i32, y: String, z: String) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + println!("{:?}", x); } async fn a4(x: &mut i32, y: i32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + println!("{:?}", x); } async fn a5(x: i32, y: &mut i32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + println!("{:?}", x); } async fn a6(x: i32, y: &mut i32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + println!("{:?}", x); } async fn a7(x: i32, y: i32, z: &mut i32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + println!("{:?}", z); } async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut +//~| needless_pass_by_ref_mut + println!("{:?}", z); } @@ -186,14 +199,16 @@ fn lint_attr(s: &mut u32) {} #[cfg(not(feature = "a"))] fn cfg_warn(s: &mut u32) {} -//~^ ERROR: this argument is a mutable reference, but not used mutably -//~| NOTE: this is cfg-gated and may require further changes +//~^ needless_pass_by_ref_mut + + #[cfg(not(feature = "a"))] mod foo { fn cfg_warn(s: &mut u32) {} - //~^ ERROR: this argument is a mutable reference, but not used mutably - //~| NOTE: this is cfg-gated and may require further changes + //~^ needless_pass_by_ref_mut + + } // Should not warn. @@ -206,7 +221,8 @@ async fn inner_async(x: &mut i32, y: &mut u32) { } async fn inner_async2(x: &mut i32, y: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + async { *x += 1; } @@ -214,7 +230,8 @@ async fn inner_async2(x: &mut i32, y: &mut u32) { } async fn inner_async3(x: &mut i32, y: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + async { *y += 1; } @@ -233,6 +250,7 @@ async fn async_vec2(b: &mut Vec) { fn non_mut(n: &str) {} //Should warn async fn call_in_closure1(n: &mut str) { +//~^ needless_pass_by_ref_mut (|| non_mut(n))() } fn str_mut(str: &mut String) -> bool { @@ -252,7 +270,8 @@ async fn closure(n: &mut usize) -> impl '_ + FnMut() { // Should warn. fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + || *n + 1 } @@ -263,7 +282,8 @@ async fn closure3(n: &mut usize) { // Should warn. async fn closure4(n: &mut usize) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + (|| { let _x = *n + 1; })(); @@ -317,17 +337,21 @@ struct MutSelf { impl MutSelf { fn bar(&mut self) {} - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut + async fn foo(&mut self, u: &mut i32, v: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably - //~| ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut + //~| needless_pass_by_ref_mut + + async { *u += 1; } .await; } async fn foo2(&mut self, u: &mut i32, v: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut + async { self.a += 1; *u += 1; @@ -343,16 +367,26 @@ impl MutSelfTrait for MutSelf { // `is_from_proc_macro` stress tests fn _empty_tup(x: &mut (())) {} +//~^ needless_pass_by_ref_mut fn _single_tup(x: &mut ((i32,))) {} +//~^ needless_pass_by_ref_mut fn _multi_tup(x: &mut ((i32, u32))) {} +//~^ needless_pass_by_ref_mut fn _fn(x: &mut (fn())) {} +//~^ needless_pass_by_ref_mut #[rustfmt::skip] fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} +//~^ needless_pass_by_ref_mut fn _extern_c_fn(x: &mut extern "C" fn()) {} +//~^ needless_pass_by_ref_mut fn _unsafe_fn(x: &mut unsafe fn()) {} +//~^ needless_pass_by_ref_mut fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} +//~^ needless_pass_by_ref_mut fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} +//~^ needless_pass_by_ref_mut fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} +//~^ needless_pass_by_ref_mut fn main() { let mut u = 0; diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr index f462fa9099ed..0492acf7cc08 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -8,79 +8,79 @@ LL | fn foo(s: &mut Vec, b: &u32, x: &mut u32) { = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:36:12 + --> tests/ui/needless_pass_by_ref_mut.rs:37:12 | LL | fn foo6(s: &mut Vec) { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:46:12 + --> tests/ui/needless_pass_by_ref_mut.rs:48:12 | LL | fn bar(&mut self) {} | ^^^^^^^^^ help: consider changing to: `&self` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:49:29 + --> tests/ui/needless_pass_by_ref_mut.rs:52:29 | LL | fn mushroom(&self, vec: &mut Vec) -> usize { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:126:16 + --> tests/ui/needless_pass_by_ref_mut.rs:130:16 | LL | async fn a1(x: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:130:16 + --> tests/ui/needless_pass_by_ref_mut.rs:135:16 | LL | async fn a2(x: &mut i32, y: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:134:16 + --> tests/ui/needless_pass_by_ref_mut.rs:140:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:138:16 + --> tests/ui/needless_pass_by_ref_mut.rs:145:16 | LL | async fn a4(x: &mut i32, y: i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:142:24 + --> tests/ui/needless_pass_by_ref_mut.rs:150:24 | LL | async fn a5(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:146:24 + --> tests/ui/needless_pass_by_ref_mut.rs:155:24 | LL | async fn a6(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:150:32 + --> tests/ui/needless_pass_by_ref_mut.rs:160:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:154:24 + --> tests/ui/needless_pass_by_ref_mut.rs:165:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:154:45 + --> tests/ui/needless_pass_by_ref_mut.rs:165:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:188:16 + --> tests/ui/needless_pass_by_ref_mut.rs:201:16 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -88,7 +88,7 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:194:20 + --> tests/ui/needless_pass_by_ref_mut.rs:208:20 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -96,115 +96,115 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:208:39 + --> tests/ui/needless_pass_by_ref_mut.rs:223:39 | LL | async fn inner_async2(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:216:26 + --> tests/ui/needless_pass_by_ref_mut.rs:232:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:235:30 + --> tests/ui/needless_pass_by_ref_mut.rs:252:30 | LL | async fn call_in_closure1(n: &mut str) { | ^^^^^^^^ help: consider changing to: `&str` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:254:16 + --> tests/ui/needless_pass_by_ref_mut.rs:272:16 | LL | fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { | ^^^^^^^^^^ help: consider changing to: `&usize` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:265:22 + --> tests/ui/needless_pass_by_ref_mut.rs:284:22 | LL | async fn closure4(n: &mut usize) { | ^^^^^^^^^^ help: consider changing to: `&usize` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:319:12 + --> tests/ui/needless_pass_by_ref_mut.rs:339:12 | LL | fn bar(&mut self) {} | ^^^^^^^^^ help: consider changing to: `&self` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:321:18 + --> tests/ui/needless_pass_by_ref_mut.rs:342:18 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { | ^^^^^^^^^ help: consider changing to: `&self` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:321:45 + --> tests/ui/needless_pass_by_ref_mut.rs:342:45 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:329:46 + --> tests/ui/needless_pass_by_ref_mut.rs:352:46 | LL | async fn foo2(&mut self, u: &mut i32, v: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:345:18 + --> tests/ui/needless_pass_by_ref_mut.rs:369:18 | LL | fn _empty_tup(x: &mut (())) {} | ^^^^^^^^^ help: consider changing to: `&()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:346:19 + --> tests/ui/needless_pass_by_ref_mut.rs:371:19 | LL | fn _single_tup(x: &mut ((i32,))) {} | ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:347:18 + --> tests/ui/needless_pass_by_ref_mut.rs:373:18 | LL | fn _multi_tup(x: &mut ((i32, u32))) {} | ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:348:11 + --> tests/ui/needless_pass_by_ref_mut.rs:375:11 | LL | fn _fn(x: &mut (fn())) {} | ^^^^^^^^^^^ help: consider changing to: `&fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:350:23 + --> tests/ui/needless_pass_by_ref_mut.rs:378:23 | LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:351:20 + --> tests/ui/needless_pass_by_ref_mut.rs:380:20 | LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:352:18 + --> tests/ui/needless_pass_by_ref_mut.rs:382:18 | LL | fn _unsafe_fn(x: &mut unsafe fn()) {} | ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:353:25 + --> tests/ui/needless_pass_by_ref_mut.rs:384:25 | LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:354:20 + --> tests/ui/needless_pass_by_ref_mut.rs:386:20 | LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:355:20 + --> tests/ui/needless_pass_by_ref_mut.rs:388:20 | LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)` diff --git a/tests/ui/needless_pass_by_ref_mut2.fixed b/tests/ui/needless_pass_by_ref_mut2.fixed index f26b39ea6a16..fc40f8c8ca30 100644 --- a/tests/ui/needless_pass_by_ref_mut2.fixed +++ b/tests/ui/needless_pass_by_ref_mut2.fixed @@ -6,7 +6,8 @@ #![warn(clippy::needless_pass_by_ref_mut)] async fn inner_async3(x: &i32, y: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + async { *y += 1; } @@ -14,7 +15,8 @@ async fn inner_async3(x: &i32, y: &mut u32) { } async fn inner_async4(u: &mut i32, v: &u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + async { *u += 1; } diff --git a/tests/ui/needless_pass_by_ref_mut2.rs b/tests/ui/needless_pass_by_ref_mut2.rs index 4220215b1fe9..f921a7684236 100644 --- a/tests/ui/needless_pass_by_ref_mut2.rs +++ b/tests/ui/needless_pass_by_ref_mut2.rs @@ -6,7 +6,8 @@ #![warn(clippy::needless_pass_by_ref_mut)] async fn inner_async3(x: &mut i32, y: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + async { *y += 1; } @@ -14,7 +15,8 @@ async fn inner_async3(x: &mut i32, y: &mut u32) { } async fn inner_async4(u: &mut i32, v: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably +//~^ needless_pass_by_ref_mut + async { *u += 1; } diff --git a/tests/ui/needless_pass_by_ref_mut2.stderr b/tests/ui/needless_pass_by_ref_mut2.stderr index 1c0136cf5d59..9876a6b50718 100644 --- a/tests/ui/needless_pass_by_ref_mut2.stderr +++ b/tests/ui/needless_pass_by_ref_mut2.stderr @@ -8,7 +8,7 @@ LL | async fn inner_async3(x: &mut i32, y: &mut u32) { = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut2.rs:16:39 + --> tests/ui/needless_pass_by_ref_mut2.rs:17:39 | LL | async fn inner_async4(u: &mut i32, v: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` diff --git a/tests/ui/needless_pass_by_value.rs b/tests/ui/needless_pass_by_value.rs index a8d9db95dcc7..faa68c8140cb 100644 --- a/tests/ui/needless_pass_by_value.rs +++ b/tests/ui/needless_pass_by_value.rs @@ -17,8 +17,9 @@ use std::mem::MaybeUninit; // `v` should be warned // `w`, `x` and `y` are allowed (moved or mutated) fn foo(v: Vec, w: Vec, mut x: Vec, y: Vec) -> Vec { - //~^ ERROR: this argument is passed by value, but not consumed in the function body - //~| NOTE: `-D clippy::needless-pass-by-value` implied by `-D warnings` +//~^ needless_pass_by_value + + assert_eq!(v.len(), 42); consume(w); @@ -33,15 +34,18 @@ fn consume(_: T) {} struct Wrapper(String); fn bar(x: String, y: Wrapper) { - //~^ ERROR: this argument is passed by value, but not consumed in the function body - //~| ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value +//~| needless_pass_by_value + + assert_eq!(x.len(), 42); assert_eq!(y.0.len(), 42); } // V implements `Borrow`, but should be warned correctly fn test_borrow_trait, U: AsRef, V>(t: T, u: U, v: V) { - //~^ ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value + println!("{}", t.borrow()); println!("{}", u.as_ref()); consume(&v); @@ -54,7 +58,8 @@ fn test_fn i32>(f: F) { // x should be warned, but y is ok fn test_match(x: Option>, y: Option>) { - //~^ ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value + match x { Some(Some(_)) => 1, // not moved _ => 0, @@ -68,8 +73,10 @@ fn test_match(x: Option>, y: Option>) { // x and y should be warned, but z is ok fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) { - //~^ ERROR: this argument is passed by value, but not consumed in the function body - //~| ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value +//~| needless_pass_by_value + + let Wrapper(s) = z; // moved let Wrapper(ref t) = y; // not moved let Wrapper(_) = y; // still not moved @@ -86,13 +93,18 @@ impl<'a, T> Serialize for &'a T where T: Serialize {} impl Serialize for i32 {} fn test_blanket_ref(vals: T, serializable: S) {} -//~^ ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value + fn issue_2114(s: String, t: String, u: Vec, v: Vec) { - //~^ ERROR: this argument is passed by value, but not consumed in the function body - //~| ERROR: this argument is passed by value, but not consumed in the function body - //~| ERROR: this argument is passed by value, but not consumed in the function body - //~| ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value +//~| needless_pass_by_value +//~| needless_pass_by_value +//~| needless_pass_by_value + + + + s.capacity(); let _ = t.clone(); u.capacity(); @@ -106,9 +118,11 @@ impl S { self, // taking `self` by value is always allowed s: String, - //~^ ERROR: this argument is passed by value, but not consumed in the function bod + //~^ needless_pass_by_value + t: String, - //~^ ERROR: this argument is passed by value, but not consumed in the function bod + //~^ needless_pass_by_value + ) -> usize { s.len() + t.capacity() } @@ -118,8 +132,10 @@ impl S { } fn baz(&self, uu: U, ss: Self) {} - //~^ ERROR: this argument is passed by value, but not consumed in the function body - //~| ERROR: this argument is passed by value, but not consumed in the function body + //~^ needless_pass_by_value + //~| needless_pass_by_value + + } trait FalsePositive { @@ -142,16 +158,20 @@ fn range>(range: T) { struct CopyWrapper(u32); fn bar_copy(x: u32, y: CopyWrapper) { - //~^ ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value + assert_eq!(x, 42); assert_eq!(y.0, 42); } // x and y should be warned, but z is ok fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { - //~^ ERROR: this argument is passed by value, but not consumed in the function body - //~| ERROR: this argument is passed by value, but not consumed in the function body - //~| ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value +//~| needless_pass_by_value +//~| needless_pass_by_value + + + let CopyWrapper(s) = z; // moved let CopyWrapper(ref t) = y; // not moved let CopyWrapper(_) = y; // still not moved @@ -164,13 +184,15 @@ fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { trait Bar<'a, A> {} impl<'b, T> Bar<'b, T> for T {} fn some_fun<'b, S: Bar<'b, ()>>(items: S) {} -//~^ ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value + // Also this should not cause an ICE. See #2831 trait Club<'a, A> {} impl Club<'static, T> for T {} fn more_fun(items: impl Club<'static, i32>) {} -//~^ ERROR: this argument is passed by value, but not consumed in the function body +//~^ needless_pass_by_value + fn is_sync(_: T) where diff --git a/tests/ui/needless_pass_by_value.stderr b/tests/ui/needless_pass_by_value.stderr index 2587d3f8c52f..414ce347403a 100644 --- a/tests/ui/needless_pass_by_value.stderr +++ b/tests/ui/needless_pass_by_value.stderr @@ -8,55 +8,55 @@ LL | fn foo(v: Vec, w: Vec, mut x: Vec, y: Vec) -> Vec tests/ui/needless_pass_by_value.rs:35:11 + --> tests/ui/needless_pass_by_value.rs:36:11 | LL | fn bar(x: String, y: Wrapper) { | ^^^^^^ help: consider changing the type to: `&str` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:35:22 + --> tests/ui/needless_pass_by_value.rs:36:22 | LL | fn bar(x: String, y: Wrapper) { | ^^^^^^^ help: consider taking a reference instead: `&Wrapper` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:43:71 + --> tests/ui/needless_pass_by_value.rs:46:71 | LL | fn test_borrow_trait, U: AsRef, V>(t: T, u: U, v: V) { | ^ help: consider taking a reference instead: `&V` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:56:18 + --> tests/ui/needless_pass_by_value.rs:60:18 | LL | fn test_match(x: Option>, y: Option>) { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&Option>` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:70:24 + --> tests/ui/needless_pass_by_value.rs:75:24 | LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) { | ^^^^^^^ help: consider taking a reference instead: `&Wrapper` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:70:36 + --> tests/ui/needless_pass_by_value.rs:75:36 | LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) { | ^^^^^^^ help: consider taking a reference instead: `&Wrapper` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:88:49 + --> tests/ui/needless_pass_by_value.rs:95:49 | LL | fn test_blanket_ref(vals: T, serializable: S) {} | ^ help: consider taking a reference instead: `&T` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:91:18 + --> tests/ui/needless_pass_by_value.rs:99:18 | LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | ^^^^^^ help: consider taking a reference instead: `&String` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:91:29 + --> tests/ui/needless_pass_by_value.rs:99:29 | LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | ^^^^^^ @@ -71,13 +71,13 @@ LL | let _ = t.to_string(); | ~~~~~~~~~~~~~ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:91:40 + --> tests/ui/needless_pass_by_value.rs:99:40 | LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | ^^^^^^^^ help: consider taking a reference instead: `&Vec` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:91:53 + --> tests/ui/needless_pass_by_value.rs:99:53 | LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | ^^^^^^^^ @@ -92,85 +92,85 @@ LL | let _ = v.to_owned(); | ~~~~~~~~~~~~ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:108:12 + --> tests/ui/needless_pass_by_value.rs:120:12 | LL | s: String, | ^^^^^^ help: consider changing the type to: `&str` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:110:12 + --> tests/ui/needless_pass_by_value.rs:123:12 | LL | t: String, | ^^^^^^ help: consider taking a reference instead: `&String` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:120:23 + --> tests/ui/needless_pass_by_value.rs:134:23 | LL | fn baz(&self, uu: U, ss: Self) {} | ^ help: consider taking a reference instead: `&U` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:120:30 + --> tests/ui/needless_pass_by_value.rs:134:30 | LL | fn baz(&self, uu: U, ss: Self) {} | ^^^^ help: consider taking a reference instead: `&Self` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:144:24 + --> tests/ui/needless_pass_by_value.rs:160:24 | LL | fn bar_copy(x: u32, y: CopyWrapper) { | ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper` | help: or consider marking this type as `Copy` - --> tests/ui/needless_pass_by_value.rs:142:1 + --> tests/ui/needless_pass_by_value.rs:158:1 | LL | struct CopyWrapper(u32); | ^^^^^^^^^^^^^^^^^^ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:151:29 + --> tests/ui/needless_pass_by_value.rs:168:29 | LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { | ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper` | help: or consider marking this type as `Copy` - --> tests/ui/needless_pass_by_value.rs:142:1 + --> tests/ui/needless_pass_by_value.rs:158:1 | LL | struct CopyWrapper(u32); | ^^^^^^^^^^^^^^^^^^ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:151:45 + --> tests/ui/needless_pass_by_value.rs:168:45 | LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { | ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper` | help: or consider marking this type as `Copy` - --> tests/ui/needless_pass_by_value.rs:142:1 + --> tests/ui/needless_pass_by_value.rs:158:1 | LL | struct CopyWrapper(u32); | ^^^^^^^^^^^^^^^^^^ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:151:61 + --> tests/ui/needless_pass_by_value.rs:168:61 | LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { | ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper` | help: or consider marking this type as `Copy` - --> tests/ui/needless_pass_by_value.rs:142:1 + --> tests/ui/needless_pass_by_value.rs:158:1 | LL | struct CopyWrapper(u32); | ^^^^^^^^^^^^^^^^^^ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:166:40 + --> tests/ui/needless_pass_by_value.rs:186:40 | LL | fn some_fun<'b, S: Bar<'b, ()>>(items: S) {} | ^ help: consider taking a reference instead: `&S` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:172:20 + --> tests/ui/needless_pass_by_value.rs:193:20 | LL | fn more_fun(items: impl Club<'static, i32>) {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&impl Club<'static, i32>` diff --git a/tests/ui/needless_pass_by_value_proc_macro.rs b/tests/ui/needless_pass_by_value_proc_macro.rs index c603163c145f..67516a962e75 100644 --- a/tests/ui/needless_pass_by_value_proc_macro.rs +++ b/tests/ui/needless_pass_by_value_proc_macro.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::needless_pass_by_value)] extern crate proc_macro; diff --git a/tests/ui/needless_pub_self.fixed b/tests/ui/needless_pub_self.fixed index d9f7b92d0901..7b4601ba8a37 100644 --- a/tests/ui/needless_pub_self.fixed +++ b/tests/ui/needless_pub_self.fixed @@ -11,13 +11,16 @@ extern crate proc_macros; fn a() {} +//~^ needless_pub_self fn b() {} +//~^ needless_pub_self pub fn c() {} mod a { pub(in super) fn d() {} pub(super) fn e() {} fn f() {} + //~^ needless_pub_self } external! { diff --git a/tests/ui/needless_pub_self.rs b/tests/ui/needless_pub_self.rs index 9f0ec76477e6..f64a56c37989 100644 --- a/tests/ui/needless_pub_self.rs +++ b/tests/ui/needless_pub_self.rs @@ -11,13 +11,16 @@ extern crate proc_macros; pub(self) fn a() {} +//~^ needless_pub_self pub(in self) fn b() {} +//~^ needless_pub_self pub fn c() {} mod a { pub(in super) fn d() {} pub(super) fn e() {} pub(self) fn f() {} + //~^ needless_pub_self } external! { diff --git a/tests/ui/needless_pub_self.stderr b/tests/ui/needless_pub_self.stderr index 1fdd84165659..c362d11804ec 100644 --- a/tests/ui/needless_pub_self.stderr +++ b/tests/ui/needless_pub_self.stderr @@ -9,7 +9,7 @@ LL | pub(self) fn a() {} = help: remove it error: unnecessary `pub(in self)` - --> tests/ui/needless_pub_self.rs:14:1 + --> tests/ui/needless_pub_self.rs:15:1 | LL | pub(in self) fn b() {} | ^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | pub(in self) fn b() {} = help: remove it error: unnecessary `pub(self)` - --> tests/ui/needless_pub_self.rs:20:5 + --> tests/ui/needless_pub_self.rs:22:5 | LL | pub(self) fn f() {} | ^^^^^^^^^ diff --git a/tests/ui/needless_question_mark.fixed b/tests/ui/needless_question_mark.fixed index 92f01c217c1c..375c38771eb6 100644 --- a/tests/ui/needless_question_mark.fixed +++ b/tests/ui/needless_question_mark.fixed @@ -18,6 +18,7 @@ struct TR { fn simple_option_bad1(to: TO) -> Option { // return as a statement return to.magic; + //~^ needless_question_mark } // formatting will add a semi-colon, which would make @@ -26,16 +27,19 @@ fn simple_option_bad1(to: TO) -> Option { fn simple_option_bad2(to: TO) -> Option { // return as an expression return to.magic + //~^ needless_question_mark } fn simple_option_bad3(to: TO) -> Option { // block value "return" to.magic + //~^ needless_question_mark } fn simple_option_bad4(to: Option) -> Option { // single line closure to.and_then(|t| t.magic) + //~^ needless_question_mark } // formatting this will remove the block brackets, making @@ -45,11 +49,13 @@ fn simple_option_bad5(to: Option) -> Option { // closure with body to.and_then(|t| { t.magic + //~^ needless_question_mark }) } fn simple_result_bad1(tr: TR) -> Result { return tr.magic; + //~^ needless_question_mark } // formatting will add a semi-colon, which would make @@ -57,14 +63,17 @@ fn simple_result_bad1(tr: TR) -> Result { #[rustfmt::skip] fn simple_result_bad2(tr: TR) -> Result { return tr.magic + //~^ needless_question_mark } fn simple_result_bad3(tr: TR) -> Result { tr.magic + //~^ needless_question_mark } fn simple_result_bad4(tr: Result) -> Result { tr.and_then(|t| t.magic) + //~^ needless_question_mark } // formatting this will remove the block brackets, making @@ -73,6 +82,7 @@ fn simple_result_bad4(tr: Result) -> Result { fn simple_result_bad5(tr: Result) -> Result { tr.and_then(|t| { t.magic + //~^ needless_question_mark }) } @@ -80,6 +90,7 @@ fn also_bad(tr: Result) -> Result { if tr.is_ok() { let t = tr.unwrap(); return t.magic; + //~^ needless_question_mark } Err(false) } @@ -115,6 +126,7 @@ pub fn test1() { macro_rules! some_and_qmark_in_macro { ($expr:expr) => { || -> Option<_> { Some($expr) }() + //~^ needless_question_mark }; } @@ -126,6 +138,7 @@ pub fn test2() { async fn async_option_bad(to: TO) -> Option { let _ = Some(3); to.magic + //~^ needless_question_mark } async fn async_deref_ref(s: Option<&String>) -> Option<&str> { @@ -134,8 +147,10 @@ async fn async_deref_ref(s: Option<&String>) -> Option<&str> { async fn async_result_bad(s: TR) -> Result { s.magic + //~^ needless_question_mark } async fn async_wrapped(a: Option) -> Option { { a } + //~^ needless_question_mark } diff --git a/tests/ui/needless_question_mark.rs b/tests/ui/needless_question_mark.rs index 21c858c291ff..5f6bd0c0f166 100644 --- a/tests/ui/needless_question_mark.rs +++ b/tests/ui/needless_question_mark.rs @@ -18,6 +18,7 @@ struct TR { fn simple_option_bad1(to: TO) -> Option { // return as a statement return Some(to.magic?); + //~^ needless_question_mark } // formatting will add a semi-colon, which would make @@ -26,16 +27,19 @@ fn simple_option_bad1(to: TO) -> Option { fn simple_option_bad2(to: TO) -> Option { // return as an expression return Some(to.magic?) + //~^ needless_question_mark } fn simple_option_bad3(to: TO) -> Option { // block value "return" Some(to.magic?) + //~^ needless_question_mark } fn simple_option_bad4(to: Option) -> Option { // single line closure to.and_then(|t| Some(t.magic?)) + //~^ needless_question_mark } // formatting this will remove the block brackets, making @@ -45,11 +49,13 @@ fn simple_option_bad5(to: Option) -> Option { // closure with body to.and_then(|t| { Some(t.magic?) + //~^ needless_question_mark }) } fn simple_result_bad1(tr: TR) -> Result { return Ok(tr.magic?); + //~^ needless_question_mark } // formatting will add a semi-colon, which would make @@ -57,14 +63,17 @@ fn simple_result_bad1(tr: TR) -> Result { #[rustfmt::skip] fn simple_result_bad2(tr: TR) -> Result { return Ok(tr.magic?) + //~^ needless_question_mark } fn simple_result_bad3(tr: TR) -> Result { Ok(tr.magic?) + //~^ needless_question_mark } fn simple_result_bad4(tr: Result) -> Result { tr.and_then(|t| Ok(t.magic?)) + //~^ needless_question_mark } // formatting this will remove the block brackets, making @@ -73,6 +82,7 @@ fn simple_result_bad4(tr: Result) -> Result { fn simple_result_bad5(tr: Result) -> Result { tr.and_then(|t| { Ok(t.magic?) + //~^ needless_question_mark }) } @@ -80,6 +90,7 @@ fn also_bad(tr: Result) -> Result { if tr.is_ok() { let t = tr.unwrap(); return Ok(t.magic?); + //~^ needless_question_mark } Err(false) } @@ -115,6 +126,7 @@ pub fn test1() { macro_rules! some_and_qmark_in_macro { ($expr:expr) => { || -> Option<_> { Some(Some($expr)?) }() + //~^ needless_question_mark }; } @@ -126,6 +138,7 @@ pub fn test2() { async fn async_option_bad(to: TO) -> Option { let _ = Some(3); Some(to.magic?) + //~^ needless_question_mark } async fn async_deref_ref(s: Option<&String>) -> Option<&str> { @@ -134,8 +147,10 @@ async fn async_deref_ref(s: Option<&String>) -> Option<&str> { async fn async_result_bad(s: TR) -> Result { Ok(s.magic?) + //~^ needless_question_mark } async fn async_wrapped(a: Option) -> Option { { Some(a?) } + //~^ needless_question_mark } diff --git a/tests/ui/needless_question_mark.stderr b/tests/ui/needless_question_mark.stderr index 0a1cb5979708..55da4f28976c 100644 --- a/tests/ui/needless_question_mark.stderr +++ b/tests/ui/needless_question_mark.stderr @@ -8,67 +8,67 @@ LL | return Some(to.magic?); = help: to override `-D warnings` add `#[allow(clippy::needless_question_mark)]` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:28:12 + --> tests/ui/needless_question_mark.rs:29:12 | LL | return Some(to.magic?) | ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:33:5 + --> tests/ui/needless_question_mark.rs:35:5 | LL | Some(to.magic?) | ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:38:21 + --> tests/ui/needless_question_mark.rs:41:21 | LL | to.and_then(|t| Some(t.magic?)) | ^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `t.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:47:9 + --> tests/ui/needless_question_mark.rs:51:9 | LL | Some(t.magic?) | ^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `t.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:52:12 + --> tests/ui/needless_question_mark.rs:57:12 | LL | return Ok(tr.magic?); | ^^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `tr.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:59:12 + --> tests/ui/needless_question_mark.rs:65:12 | LL | return Ok(tr.magic?) | ^^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `tr.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:63:5 + --> tests/ui/needless_question_mark.rs:70:5 | LL | Ok(tr.magic?) | ^^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `tr.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:67:21 + --> tests/ui/needless_question_mark.rs:75:21 | LL | tr.and_then(|t| Ok(t.magic?)) | ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `t.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:75:9 + --> tests/ui/needless_question_mark.rs:84:9 | LL | Ok(t.magic?) | ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `t.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:82:16 + --> tests/ui/needless_question_mark.rs:92:16 | LL | return Ok(t.magic?); | ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `t.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:117:27 + --> tests/ui/needless_question_mark.rs:128:27 | LL | || -> Option<_> { Some(Some($expr)?) }() | ^^^^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `Some($expr)` @@ -79,19 +79,19 @@ LL | let _x = some_and_qmark_in_macro!(x?); = note: this error originates in the macro `some_and_qmark_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:128:5 + --> tests/ui/needless_question_mark.rs:140:5 | LL | Some(to.magic?) | ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:136:5 + --> tests/ui/needless_question_mark.rs:149:5 | LL | Ok(s.magic?) | ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `s.magic` error: question mark operator is useless here - --> tests/ui/needless_question_mark.rs:140:7 + --> tests/ui/needless_question_mark.rs:154:7 | LL | { Some(a?) } | ^^^^^^^^ help: try removing question mark and `Some()`: `a` diff --git a/tests/ui/needless_range_loop.rs b/tests/ui/needless_range_loop.rs index 75f1896eded1..ff9699e35691 100644 --- a/tests/ui/needless_range_loop.rs +++ b/tests/ui/needless_range_loop.rs @@ -14,8 +14,9 @@ fn main() { let mut vec = vec![1, 2, 3, 4]; let vec2 = vec![1, 2, 3, 4]; for i in 0..vec.len() { - //~^ ERROR: the loop variable `i` is only used to index `vec` - //~| NOTE: `-D clippy::needless-range-loop` implied by `-D warnings` + //~^ needless_range_loop + + println!("{}", vec[i]); } @@ -25,23 +26,27 @@ fn main() { } for i in 0..vec.len() { - //~^ ERROR: the loop variable `i` is only used to index `vec` + //~^ needless_range_loop + let _ = vec[i]; } // ICE #746 for j in 0..4 { - //~^ ERROR: the loop variable `j` is only used to index `STATIC` + //~^ needless_range_loop + println!("{:?}", STATIC[j]); } for j in 0..4 { - //~^ ERROR: the loop variable `j` is only used to index `CONST` + //~^ needless_range_loop + println!("{:?}", CONST[j]); } for i in 0..vec.len() { - //~^ ERROR: the loop variable `i` is used to index `vec` + //~^ needless_range_loop + println!("{} {}", vec[i], i); } for i in 0..vec.len() { @@ -50,48 +55,57 @@ fn main() { } for i in 0..vec.len() { - //~^ ERROR: the loop variable `i` is only used to index `vec2` + //~^ needless_range_loop + println!("{}", vec2[i]); } for i in 5..vec.len() { - //~^ ERROR: the loop variable `i` is only used to index `vec` + //~^ needless_range_loop + println!("{}", vec[i]); } for i in 0..MAX_LEN { - //~^ ERROR: the loop variable `i` is only used to index `vec` + //~^ needless_range_loop + println!("{}", vec[i]); } for i in 0..=MAX_LEN { - //~^ ERROR: the loop variable `i` is only used to index `vec` + //~^ needless_range_loop + println!("{}", vec[i]); } for i in 5..10 { - //~^ ERROR: the loop variable `i` is only used to index `vec` + //~^ needless_range_loop + println!("{}", vec[i]); } for i in 5..=10 { - //~^ ERROR: the loop variable `i` is only used to index `vec` + //~^ needless_range_loop + println!("{}", vec[i]); } for i in 5..vec.len() { - //~^ ERROR: the loop variable `i` is used to index `vec` + //~^ needless_range_loop + println!("{} {}", vec[i], i); } for i in 5..10 { - //~^ ERROR: the loop variable `i` is used to index `vec` + //~^ needless_range_loop + println!("{} {}", vec[i], i); } // #2542 for i in 0..vec.len() { - //~^ ERROR: the loop variable `i` is used to index `vec` + //~^ needless_range_loop + vec[i] = Some(1).unwrap_or_else(|| panic!("error on {}", i)); } diff --git a/tests/ui/needless_range_loop.stderr b/tests/ui/needless_range_loop.stderr index 503d796e5e8d..a15830d721b6 100644 --- a/tests/ui/needless_range_loop.stderr +++ b/tests/ui/needless_range_loop.stderr @@ -12,7 +12,7 @@ LL | for in &vec { | ~~~~~~ ~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:27:14 + --> tests/ui/needless_range_loop.rs:28:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | for in &vec { | ~~~~~~ ~~~~ error: the loop variable `j` is only used to index `STATIC` - --> tests/ui/needless_range_loop.rs:33:14 + --> tests/ui/needless_range_loop.rs:35:14 | LL | for j in 0..4 { | ^^^^ @@ -34,7 +34,7 @@ LL | for in &STATIC { | ~~~~~~ ~~~~~~~ error: the loop variable `j` is only used to index `CONST` - --> tests/ui/needless_range_loop.rs:38:14 + --> tests/ui/needless_range_loop.rs:41:14 | LL | for j in 0..4 { | ^^^^ @@ -45,7 +45,7 @@ LL | for in &CONST { | ~~~~~~ ~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:43:14 + --> tests/ui/needless_range_loop.rs:47:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | for (i, ) in vec.iter().enumerate() { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec2` - --> tests/ui/needless_range_loop.rs:52:14 + --> tests/ui/needless_range_loop.rs:57:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | for in vec2.iter().take(vec.len()) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:57:14 + --> tests/ui/needless_range_loop.rs:63:14 | LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | for in vec.iter().skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:62:14 + --> tests/ui/needless_range_loop.rs:69:14 | LL | for i in 0..MAX_LEN { | ^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | for in vec.iter().take(MAX_LEN) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:67:14 + --> tests/ui/needless_range_loop.rs:75:14 | LL | for i in 0..=MAX_LEN { | ^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | for in vec.iter().take(MAX_LEN + 1) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:72:14 + --> tests/ui/needless_range_loop.rs:81:14 | LL | for i in 5..10 { | ^^^^^ @@ -111,7 +111,7 @@ LL | for in vec.iter().take(10).skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:77:14 + --> tests/ui/needless_range_loop.rs:87:14 | LL | for i in 5..=10 { | ^^^^^^ @@ -122,7 +122,7 @@ LL | for in vec.iter().take(10 + 1).skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:82:14 + --> tests/ui/needless_range_loop.rs:93:14 | LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | for (i, ) in vec.iter().enumerate().skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:87:14 + --> tests/ui/needless_range_loop.rs:99:14 | LL | for i in 5..10 { | ^^^^^ @@ -144,7 +144,7 @@ LL | for (i, ) in vec.iter().enumerate().take(10).skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:93:14 + --> tests/ui/needless_range_loop.rs:106:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ diff --git a/tests/ui/needless_range_loop2.rs b/tests/ui/needless_range_loop2.rs index 787ff18f338d..8a591a4bddae 100644 --- a/tests/ui/needless_range_loop2.rs +++ b/tests/ui/needless_range_loop2.rs @@ -9,8 +9,9 @@ fn main() { let ns = vec![2, 3, 5, 7]; for i in 3..10 { - //~^ ERROR: the loop variable `i` is only used to index `ns` - //~| NOTE: `-D clippy::needless-range-loop` implied by `-D warnings` + //~^ needless_range_loop + + println!("{}", ns[i]); } @@ -32,14 +33,16 @@ fn main() { let mut ms = vec![1, 2, 3, 4, 5, 6]; for i in 0..ms.len() { - //~^ ERROR: the loop variable `i` is only used to index `ms` + //~^ needless_range_loop + ms[i] *= 2; } assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]); let mut ms = vec![1, 2, 3, 4, 5, 6]; for i in 0..ms.len() { - //~^ ERROR: the loop variable `i` is only used to index `ms` + //~^ needless_range_loop + let x = &mut ms[i]; *x *= 2; } @@ -64,7 +67,8 @@ fn main() { let mut vec = vec![0; 9]; for i in x..x + 4 { - //~^ ERROR: the loop variable `i` is only used to index `vec` + //~^ needless_range_loop + vec[i] += 1; } @@ -72,24 +76,28 @@ fn main() { let mut vec = vec![0; 10]; for i in x..=x + 4 { - //~^ ERROR: the loop variable `i` is only used to index `vec` + //~^ needless_range_loop + vec[i] += 1; } let arr = [1, 2, 3]; for i in 0..3 { - //~^ ERROR: the loop variable `i` is only used to index `arr` + //~^ needless_range_loop + println!("{}", arr[i]); } for i in 0..2 { - //~^ ERROR: the loop variable `i` is only used to index `arr` + //~^ needless_range_loop + println!("{}", arr[i]); } for i in 1..3 { - //~^ ERROR: the loop variable `i` is only used to index `arr` + //~^ needless_range_loop + println!("{}", arr[i]); } diff --git a/tests/ui/needless_range_loop2.stderr b/tests/ui/needless_range_loop2.stderr index 353f30b1b26d..34357c3db02f 100644 --- a/tests/ui/needless_range_loop2.stderr +++ b/tests/ui/needless_range_loop2.stderr @@ -12,7 +12,7 @@ LL | for in ns.iter().take(10).skip(3) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `ms` - --> tests/ui/needless_range_loop2.rs:34:14 + --> tests/ui/needless_range_loop2.rs:35:14 | LL | for i in 0..ms.len() { | ^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | for in &mut ms { | ~~~~~~ ~~~~~~~ error: the loop variable `i` is only used to index `ms` - --> tests/ui/needless_range_loop2.rs:41:14 + --> tests/ui/needless_range_loop2.rs:43:14 | LL | for i in 0..ms.len() { | ^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | for in &mut ms { | ~~~~~~ ~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop2.rs:66:14 + --> tests/ui/needless_range_loop2.rs:69:14 | LL | for i in x..x + 4 { | ^^^^^^^^ @@ -45,7 +45,7 @@ LL | for in vec.iter_mut().skip(x).take(4) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop2.rs:74:14 + --> tests/ui/needless_range_loop2.rs:78:14 | LL | for i in x..=x + 4 { | ^^^^^^^^^ @@ -56,7 +56,7 @@ LL | for in vec.iter_mut().skip(x).take(4 + 1) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `arr` - --> tests/ui/needless_range_loop2.rs:81:14 + --> tests/ui/needless_range_loop2.rs:86:14 | LL | for i in 0..3 { | ^^^^ @@ -67,7 +67,7 @@ LL | for in &arr { | ~~~~~~ ~~~~ error: the loop variable `i` is only used to index `arr` - --> tests/ui/needless_range_loop2.rs:86:14 + --> tests/ui/needless_range_loop2.rs:92:14 | LL | for i in 0..2 { | ^^^^ @@ -78,7 +78,7 @@ LL | for in arr.iter().take(2) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `arr` - --> tests/ui/needless_range_loop2.rs:91:14 + --> tests/ui/needless_range_loop2.rs:98:14 | LL | for i in 1..3 { | ^^^^ diff --git a/tests/ui/needless_raw_string.fixed b/tests/ui/needless_raw_string.fixed index ab061467488a..88f9096db03c 100644 --- a/tests/ui/needless_raw_string.fixed +++ b/tests/ui/needless_raw_string.fixed @@ -3,31 +3,41 @@ fn main() { "aaa"; + //~^ needless_raw_strings r#""aaa""#; r#"\s"#; b"aaa"; + //~^ needless_raw_strings br#""aaa""#; br#"\s"#; c"aaa"; + //~^ needless_raw_strings cr#""aaa""#; cr#"\s"#; " + //~^ needless_raw_strings a multiline string "; "no hashes"; + //~^ needless_raw_strings b"no hashes"; + //~^ needless_raw_strings c"no hashes"; + //~^ needless_raw_strings } fn issue_13503() { println!("SELECT * FROM posts"); + //~^ needless_raw_strings println!("SELECT * FROM posts"); + //~^ needless_raw_strings println!(r##"SELECT * FROM "posts""##); // Test arguments as well println!("{}", "foobar".len()); + //~^ needless_raw_strings } diff --git a/tests/ui/needless_raw_string.rs b/tests/ui/needless_raw_string.rs index 5be8bdeb4ad0..6913b8b75546 100644 --- a/tests/ui/needless_raw_string.rs +++ b/tests/ui/needless_raw_string.rs @@ -3,31 +3,41 @@ fn main() { r#"aaa"#; + //~^ needless_raw_strings r#""aaa""#; r#"\s"#; br#"aaa"#; + //~^ needless_raw_strings br#""aaa""#; br#"\s"#; cr#"aaa"#; + //~^ needless_raw_strings cr#""aaa""#; cr#"\s"#; r#" + //~^ needless_raw_strings a multiline string "#; r"no hashes"; + //~^ needless_raw_strings br"no hashes"; + //~^ needless_raw_strings cr"no hashes"; + //~^ needless_raw_strings } fn issue_13503() { println!(r"SELECT * FROM posts"); + //~^ needless_raw_strings println!(r#"SELECT * FROM posts"#); + //~^ needless_raw_strings println!(r##"SELECT * FROM "posts""##); // Test arguments as well println!("{}", r"foobar".len()); + //~^ needless_raw_strings } diff --git a/tests/ui/needless_raw_string.stderr b/tests/ui/needless_raw_string.stderr index 5169f0855738..99c60b10b21b 100644 --- a/tests/ui/needless_raw_string.stderr +++ b/tests/ui/needless_raw_string.stderr @@ -13,7 +13,7 @@ LL + "aaa"; | error: unnecessary raw string literal - --> tests/ui/needless_raw_string.rs:8:5 + --> tests/ui/needless_raw_string.rs:9:5 | LL | br#"aaa"#; | ^^^^^^^^^ @@ -25,7 +25,7 @@ LL + b"aaa"; | error: unnecessary raw string literal - --> tests/ui/needless_raw_string.rs:11:5 + --> tests/ui/needless_raw_string.rs:13:5 | LL | cr#"aaa"#; | ^^^^^^^^^ @@ -37,9 +37,10 @@ LL + c"aaa"; | error: unnecessary raw string literal - --> tests/ui/needless_raw_string.rs:15:5 + --> tests/ui/needless_raw_string.rs:18:5 | LL | / r#" +LL | | LL | | a LL | | multiline LL | | string @@ -49,14 +50,14 @@ LL | | "#; help: use a plain string literal instead | LL ~ " -LL | a -LL | multiline +LL | +... LL | string LL ~ "; | error: unnecessary raw string literal - --> tests/ui/needless_raw_string.rs:21:5 + --> tests/ui/needless_raw_string.rs:25:5 | LL | r"no hashes"; | ^^^^^^^^^^^^ @@ -68,7 +69,7 @@ LL + "no hashes"; | error: unnecessary raw string literal - --> tests/ui/needless_raw_string.rs:22:5 + --> tests/ui/needless_raw_string.rs:27:5 | LL | br"no hashes"; | ^^^^^^^^^^^^^ @@ -80,7 +81,7 @@ LL + b"no hashes"; | error: unnecessary raw string literal - --> tests/ui/needless_raw_string.rs:23:5 + --> tests/ui/needless_raw_string.rs:29:5 | LL | cr"no hashes"; | ^^^^^^^^^^^^^ @@ -92,7 +93,7 @@ LL + c"no hashes"; | error: unnecessary raw string literal - --> tests/ui/needless_raw_string.rs:27:14 + --> tests/ui/needless_raw_string.rs:34:14 | LL | println!(r"SELECT * FROM posts"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +105,7 @@ LL + println!("SELECT * FROM posts"); | error: unnecessary raw string literal - --> tests/ui/needless_raw_string.rs:28:14 + --> tests/ui/needless_raw_string.rs:36:14 | LL | println!(r#"SELECT * FROM posts"#); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -116,7 +117,7 @@ LL + println!("SELECT * FROM posts"); | error: unnecessary raw string literal - --> tests/ui/needless_raw_string.rs:32:20 + --> tests/ui/needless_raw_string.rs:41:20 | LL | println!("{}", r"foobar".len()); | ^^^^^^^^^ diff --git a/tests/ui/needless_raw_string_hashes.fixed b/tests/ui/needless_raw_string_hashes.fixed index 4c1137091071..bc7da202df4a 100644 --- a/tests/ui/needless_raw_string_hashes.fixed +++ b/tests/ui/needless_raw_string_hashes.fixed @@ -3,33 +3,51 @@ fn main() { r"\aaa"; + //~^ needless_raw_string_hashes r#"Hello "world"!"#; + //~^ needless_raw_string_hashes r####" "### "## "# "####; + //~^ needless_raw_string_hashes r###" "aa" "# "## "###; + //~^ needless_raw_string_hashes br"\aaa"; + //~^ needless_raw_string_hashes br#"Hello "world"!"#; + //~^ needless_raw_string_hashes br####" "### "## "# "####; + //~^ needless_raw_string_hashes br###" "aa" "# "## "###; + //~^ needless_raw_string_hashes cr"\aaa"; + //~^ needless_raw_string_hashes cr#"Hello "world"!"#; + //~^ needless_raw_string_hashes cr####" "### "## "# "####; + //~^ needless_raw_string_hashes cr###" "aa" "# "## "###; + //~^ needless_raw_string_hashes r" + //~^ needless_raw_string_hashes \a multiline string "; r"rust"; + //~^ needless_raw_string_hashes r"hello world"; + //~^ needless_raw_string_hashes } fn issue_13503() { println!(r"SELECT * FROM posts"); println!(r"SELECT * FROM posts"); + //~^ needless_raw_string_hashes println!(r#"SELECT * FROM "posts""#); + //~^ needless_raw_string_hashes println!(r#"SELECT * FROM "posts""#); + //~^ needless_raw_string_hashes // Test arguments as well println!("{}", r"foobar".len()); diff --git a/tests/ui/needless_raw_string_hashes.rs b/tests/ui/needless_raw_string_hashes.rs index 7b6b4e784eea..3f2f92a4097c 100644 --- a/tests/ui/needless_raw_string_hashes.rs +++ b/tests/ui/needless_raw_string_hashes.rs @@ -3,33 +3,51 @@ fn main() { r#"\aaa"#; + //~^ needless_raw_string_hashes r##"Hello "world"!"##; + //~^ needless_raw_string_hashes r######" "### "## "# "######; + //~^ needless_raw_string_hashes r######" "aa" "# "## "######; + //~^ needless_raw_string_hashes br#"\aaa"#; + //~^ needless_raw_string_hashes br##"Hello "world"!"##; + //~^ needless_raw_string_hashes br######" "### "## "# "######; + //~^ needless_raw_string_hashes br######" "aa" "# "## "######; + //~^ needless_raw_string_hashes cr#"\aaa"#; + //~^ needless_raw_string_hashes cr##"Hello "world"!"##; + //~^ needless_raw_string_hashes cr######" "### "## "# "######; + //~^ needless_raw_string_hashes cr######" "aa" "# "## "######; + //~^ needless_raw_string_hashes r#" + //~^ needless_raw_string_hashes \a multiline string "#; r###"rust"###; + //~^ needless_raw_string_hashes r#"hello world"#; + //~^ needless_raw_string_hashes } fn issue_13503() { println!(r"SELECT * FROM posts"); println!(r#"SELECT * FROM posts"#); + //~^ needless_raw_string_hashes println!(r##"SELECT * FROM "posts""##); + //~^ needless_raw_string_hashes println!(r##"SELECT * FROM "posts""##); + //~^ needless_raw_string_hashes // Test arguments as well println!("{}", r"foobar".len()); diff --git a/tests/ui/needless_raw_string_hashes.stderr b/tests/ui/needless_raw_string_hashes.stderr index a213ba3e7438..853ee7092528 100644 --- a/tests/ui/needless_raw_string_hashes.stderr +++ b/tests/ui/needless_raw_string_hashes.stderr @@ -13,7 +13,7 @@ LL + r"\aaa"; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:6:5 + --> tests/ui/needless_raw_string_hashes.rs:7:5 | LL | r##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + r#"Hello "world"!"#; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:7:5 + --> tests/ui/needless_raw_string_hashes.rs:9:5 | LL | r######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + r####" "### "## "# "####; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:8:5 + --> tests/ui/needless_raw_string_hashes.rs:11:5 | LL | r######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + r###" "aa" "# "## "###; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:9:5 + --> tests/ui/needless_raw_string_hashes.rs:13:5 | LL | br#"\aaa"#; | ^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + br"\aaa"; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:10:5 + --> tests/ui/needless_raw_string_hashes.rs:15:5 | LL | br##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + br#"Hello "world"!"#; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:11:5 + --> tests/ui/needless_raw_string_hashes.rs:17:5 | LL | br######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + br####" "### "## "# "####; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:12:5 + --> tests/ui/needless_raw_string_hashes.rs:19:5 | LL | br######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL + br###" "aa" "# "## "###; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:13:5 + --> tests/ui/needless_raw_string_hashes.rs:21:5 | LL | cr#"\aaa"#; | ^^^^^^^^^^ @@ -109,7 +109,7 @@ LL + cr"\aaa"; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:14:5 + --> tests/ui/needless_raw_string_hashes.rs:23:5 | LL | cr##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL + cr#"Hello "world"!"#; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:15:5 + --> tests/ui/needless_raw_string_hashes.rs:25:5 | LL | cr######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL + cr####" "### "## "# "####; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:16:5 + --> tests/ui/needless_raw_string_hashes.rs:27:5 | LL | cr######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,9 +145,10 @@ LL + cr###" "aa" "# "## "###; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:18:5 + --> tests/ui/needless_raw_string_hashes.rs:30:5 | LL | / r#" +LL | | LL | | \a LL | | multiline LL | | string @@ -157,14 +158,14 @@ LL | | "#; help: remove all the hashes around the string literal | LL ~ r" -LL | \a -LL | multiline +LL | +... LL | string LL ~ "; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:24:5 + --> tests/ui/needless_raw_string_hashes.rs:37:5 | LL | r###"rust"###; | ^^^^^^^^^^^^^ @@ -176,7 +177,7 @@ LL + r"rust"; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:25:5 + --> tests/ui/needless_raw_string_hashes.rs:39:5 | LL | r#"hello world"#; | ^^^^^^^^^^^^^^^^ @@ -188,7 +189,7 @@ LL + r"hello world"; | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:30:14 + --> tests/ui/needless_raw_string_hashes.rs:45:14 | LL | println!(r#"SELECT * FROM posts"#); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -200,7 +201,7 @@ LL + println!(r"SELECT * FROM posts"); | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:31:14 + --> tests/ui/needless_raw_string_hashes.rs:47:14 | LL | println!(r##"SELECT * FROM "posts""##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -212,7 +213,7 @@ LL + println!(r#"SELECT * FROM "posts""#); | error: unnecessary hashes around raw string literal - --> tests/ui/needless_raw_string_hashes.rs:32:14 + --> tests/ui/needless_raw_string_hashes.rs:49:14 | LL | println!(r##"SELECT * FROM "posts""##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/needless_return.fixed b/tests/ui/needless_return.fixed index aa2a274525bc..efc073ebe874 100644 --- a/tests/ui/needless_return.fixed +++ b/tests/ui/needless_return.fixed @@ -27,35 +27,43 @@ fn test_end_of_fn() -> bool { return true; } true + //~^ needless_return } fn test_no_semicolon() -> bool { true + //~^ needless_return } #[rustfmt::skip] fn test_multiple_semicolon() -> bool { true + //~^ needless_return } #[rustfmt::skip] fn test_multiple_semicolon_with_spaces() -> bool { true + //~^ needless_return } fn test_if_block() -> bool { if true { true + //~^ needless_return } else { false + //~^ needless_return } } fn test_match(x: bool) -> bool { match x { true => false, + //~^ needless_return false => { true + //~^ needless_return }, } } @@ -63,20 +71,26 @@ fn test_match(x: bool) -> bool { fn test_closure() { let _ = || { true + //~^ needless_return }; let _ = || true; + //~^ needless_return } fn test_macro_call() -> i32 { the_answer!() + //~^ needless_return } fn test_void_fun() { + //~^^ needless_return } fn test_void_if_fun(b: bool) { if b { + //~^^ needless_return } else { + //~^^ needless_return } } @@ -84,6 +98,7 @@ fn test_void_match(x: u32) { match x { 0 => (), _ => (), + //~^ needless_return } } @@ -92,8 +107,10 @@ fn test_nested_match(x: u32) { 0 => (), 1 => { let _ = 42; + //~^^ needless_return }, _ => (), + //~^ needless_return } } @@ -107,8 +124,10 @@ fn borrows_but_not_last(value: bool) -> String { let x = RefCell::::default(); let _a = x.borrow().clone(); String::from("test") + //~^ needless_return } else { String::new() + //~^ needless_return } } @@ -131,18 +150,22 @@ mod issue6501 { #[allow(clippy::unnecessary_lazy_evaluations)] fn foo(bar: Result<(), ()>) { bar.unwrap_or_else(|_| {}) + //~^ needless_return } fn test_closure() { let _ = || { + //~^^ needless_return }; let _ = || {}; + //~^ needless_return } struct Foo; #[allow(clippy::unnecessary_lazy_evaluations)] fn bar(res: Result) -> Foo { res.unwrap_or_else(|_| Foo) + //~^ needless_return } } @@ -152,25 +175,31 @@ async fn async_test_end_of_fn() -> bool { return true; } true + //~^ needless_return } async fn async_test_no_semicolon() -> bool { true + //~^ needless_return } async fn async_test_if_block() -> bool { if true { true + //~^ needless_return } else { false + //~^ needless_return } } async fn async_test_match(x: bool) -> bool { match x { true => false, + //~^ needless_return false => { true + //~^ needless_return }, } } @@ -178,20 +207,26 @@ async fn async_test_match(x: bool) -> bool { async fn async_test_closure() { let _ = || { true + //~^ needless_return }; let _ = || true; + //~^ needless_return } async fn async_test_macro_call() -> i32 { the_answer!() + //~^ needless_return } async fn async_test_void_fun() { + //~^^ needless_return } async fn async_test_void_if_fun(b: bool) { if b { + //~^^ needless_return } else { + //~^^ needless_return } } @@ -199,6 +234,7 @@ async fn async_test_void_match(x: u32) { match x { 0 => (), _ => (), + //~^ needless_return } } @@ -212,8 +248,10 @@ async fn async_borrows_but_not_last(value: bool) -> String { let x = RefCell::::default(); let _a = x.borrow().clone(); String::from("test") + //~^ needless_return } else { String::new() + //~^ needless_return } } @@ -230,6 +268,7 @@ fn needless_return_macro() -> String { let _ = "foo"; let _ = "bar"; format!("Hello {}", "world!") + //~^ needless_return } fn issue_9361(n: i32) -> i32 { @@ -271,8 +310,10 @@ fn issue8336(x: i32) -> bool { if x > 0 { println!("something"); true + //~^ needless_return } else { false + //~^ needless_return } } @@ -280,9 +321,11 @@ fn issue8156(x: u8) -> u64 { match x { 80 => { 10 + //~^ needless_return }, _ => { 100 + //~^ needless_return }, } } @@ -291,6 +334,7 @@ fn issue8156(x: u8) -> u64 { fn issue9192() -> i32 { { 0 + //~^ needless_return } } @@ -298,8 +342,10 @@ fn issue9503(x: usize) -> isize { unsafe { if x > 12 { *(x as *const isize) + //~^ needless_return } else { !*(x as *const isize) + //~^ needless_return } } } @@ -307,11 +353,13 @@ fn issue9503(x: usize) -> isize { mod issue9416 { pub fn with_newline() { let _ = 42; + //~^^ needless_return } #[rustfmt::skip] pub fn oneline() { let _ = 42; + //~^ needless_return } } @@ -324,18 +372,22 @@ fn issue9947() -> Result<(), String> { fn issue10051() -> Result { if true { Ok(format!("ok!")) + //~^ needless_return } else { Err(format!("err!")) + //~^ needless_return } } mod issue10049 { fn single() -> u32 { if true { 1 } else { 2 } + //~^ needless_return } fn multiple(b1: bool, b2: bool, b3: bool) -> u32 { (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }) + //~^ needless_return } } @@ -357,10 +409,12 @@ fn allow_works() -> i32 { fn conjunctive_blocks() -> String { ({ "a".to_string() } + "b" + { "c" }) + //~^ needless_return } fn issue12907() -> String { "".split("").next().unwrap().to_string() + //~^ needless_return } fn issue13458() { diff --git a/tests/ui/needless_return.rs b/tests/ui/needless_return.rs index bf67cfd3698a..283d86f25fe5 100644 --- a/tests/ui/needless_return.rs +++ b/tests/ui/needless_return.rs @@ -27,35 +27,43 @@ fn test_end_of_fn() -> bool { return true; } return true; + //~^ needless_return } fn test_no_semicolon() -> bool { return true; + //~^ needless_return } #[rustfmt::skip] fn test_multiple_semicolon() -> bool { return true;;; + //~^ needless_return } #[rustfmt::skip] fn test_multiple_semicolon_with_spaces() -> bool { return true;; ; ; + //~^ needless_return } fn test_if_block() -> bool { if true { return true; + //~^ needless_return } else { return false; + //~^ needless_return } } fn test_match(x: bool) -> bool { match x { true => return false, + //~^ needless_return false => { return true; + //~^ needless_return }, } } @@ -63,23 +71,29 @@ fn test_match(x: bool) -> bool { fn test_closure() { let _ = || { return true; + //~^ needless_return }; let _ = || return true; + //~^ needless_return } fn test_macro_call() -> i32 { return the_answer!(); + //~^ needless_return } fn test_void_fun() { return; + //~^^ needless_return } fn test_void_if_fun(b: bool) { if b { return; + //~^^ needless_return } else { return; + //~^^ needless_return } } @@ -87,6 +101,7 @@ fn test_void_match(x: u32) { match x { 0 => (), _ => return, + //~^ needless_return } } @@ -96,8 +111,10 @@ fn test_nested_match(x: u32) { 1 => { let _ = 42; return; + //~^^ needless_return }, _ => return, + //~^ needless_return } } @@ -111,8 +128,10 @@ fn borrows_but_not_last(value: bool) -> String { let x = RefCell::::default(); let _a = x.borrow().clone(); return String::from("test"); + //~^ needless_return } else { return String::new(); + //~^ needless_return } } @@ -135,19 +154,23 @@ mod issue6501 { #[allow(clippy::unnecessary_lazy_evaluations)] fn foo(bar: Result<(), ()>) { bar.unwrap_or_else(|_| return) + //~^ needless_return } fn test_closure() { let _ = || { return; + //~^^ needless_return }; let _ = || return; + //~^ needless_return } struct Foo; #[allow(clippy::unnecessary_lazy_evaluations)] fn bar(res: Result) -> Foo { res.unwrap_or_else(|_| return Foo) + //~^ needless_return } } @@ -157,25 +180,31 @@ async fn async_test_end_of_fn() -> bool { return true; } return true; + //~^ needless_return } async fn async_test_no_semicolon() -> bool { return true; + //~^ needless_return } async fn async_test_if_block() -> bool { if true { return true; + //~^ needless_return } else { return false; + //~^ needless_return } } async fn async_test_match(x: bool) -> bool { match x { true => return false, + //~^ needless_return false => { return true; + //~^ needless_return }, } } @@ -183,23 +212,29 @@ async fn async_test_match(x: bool) -> bool { async fn async_test_closure() { let _ = || { return true; + //~^ needless_return }; let _ = || return true; + //~^ needless_return } async fn async_test_macro_call() -> i32 { return the_answer!(); + //~^ needless_return } async fn async_test_void_fun() { return; + //~^^ needless_return } async fn async_test_void_if_fun(b: bool) { if b { return; + //~^^ needless_return } else { return; + //~^^ needless_return } } @@ -207,6 +242,7 @@ async fn async_test_void_match(x: u32) { match x { 0 => (), _ => return, + //~^ needless_return } } @@ -220,8 +256,10 @@ async fn async_borrows_but_not_last(value: bool) -> String { let x = RefCell::::default(); let _a = x.borrow().clone(); return String::from("test"); + //~^ needless_return } else { return String::new(); + //~^ needless_return } } @@ -238,6 +276,7 @@ fn needless_return_macro() -> String { let _ = "foo"; let _ = "bar"; return format!("Hello {}", "world!"); + //~^ needless_return } fn issue_9361(n: i32) -> i32 { @@ -279,8 +318,10 @@ fn issue8336(x: i32) -> bool { if x > 0 { println!("something"); return true; + //~^ needless_return } else { return false; + //~^ needless_return }; } @@ -288,9 +329,11 @@ fn issue8156(x: u8) -> u64 { match x { 80 => { return 10; + //~^ needless_return }, _ => { return 100; + //~^ needless_return }, }; } @@ -299,6 +342,7 @@ fn issue8156(x: u8) -> u64 { fn issue9192() -> i32 { { return 0; + //~^ needless_return }; } @@ -306,8 +350,10 @@ fn issue9503(x: usize) -> isize { unsafe { if x > 12 { return *(x as *const isize); + //~^ needless_return } else { return !*(x as *const isize); + //~^ needless_return }; }; } @@ -315,13 +361,14 @@ fn issue9503(x: usize) -> isize { mod issue9416 { pub fn with_newline() { let _ = 42; - return; + //~^^ needless_return } #[rustfmt::skip] pub fn oneline() { let _ = 42; return; + //~^ needless_return } } @@ -334,18 +381,22 @@ fn issue9947() -> Result<(), String> { fn issue10051() -> Result { if true { return Ok(format!("ok!")); + //~^ needless_return } else { return Err(format!("err!")); + //~^ needless_return } } mod issue10049 { fn single() -> u32 { return if true { 1 } else { 2 }; + //~^ needless_return } fn multiple(b1: bool, b2: bool, b3: bool) -> u32 { return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }; + //~^ needless_return } } @@ -367,10 +418,12 @@ fn allow_works() -> i32 { fn conjunctive_blocks() -> String { return { "a".to_string() } + "b" + { "c" }; + //~^ needless_return } fn issue12907() -> String { return "".split("").next().unwrap().to_string(); + //~^ needless_return } fn issue13458() { diff --git a/tests/ui/needless_return.stderr b/tests/ui/needless_return.stderr index d3c2a6badc0f..3865a7fea6bf 100644 --- a/tests/ui/needless_return.stderr +++ b/tests/ui/needless_return.stderr @@ -13,7 +13,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:33:5 + --> tests/ui/needless_return.rs:34:5 | LL | return true; | ^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:38:5 + --> tests/ui/needless_return.rs:40:5 | LL | return true;;; | ^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:43:5 + --> tests/ui/needless_return.rs:46:5 | LL | return true;; ; ; | ^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:48:9 + --> tests/ui/needless_return.rs:52:9 | LL | return true; | ^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:50:9 + --> tests/ui/needless_return.rs:55:9 | LL | return false; | ^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + false | error: unneeded `return` statement - --> tests/ui/needless_return.rs:56:17 + --> tests/ui/needless_return.rs:62:17 | LL | true => return false, | ^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | true => false, | ~~~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:58:13 + --> tests/ui/needless_return.rs:65:13 | LL | return true; | ^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:65:9 + --> tests/ui/needless_return.rs:73:9 | LL | return true; | ^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:67:16 + --> tests/ui/needless_return.rs:76:16 | LL | let _ = || return true; | ^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | let _ = || true; | ~~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:71:5 + --> tests/ui/needless_return.rs:81:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL + the_answer!() | error: unneeded `return` statement - --> tests/ui/needless_return.rs:74:21 + --> tests/ui/needless_return.rs:85:21 | LL | fn test_void_fun() { | _____________________^ @@ -146,7 +146,7 @@ LL + fn test_void_fun() { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:79:11 + --> tests/ui/needless_return.rs:91:11 | LL | if b { | ___________^ @@ -161,7 +161,7 @@ LL + if b { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:81:13 + --> tests/ui/needless_return.rs:94:13 | LL | } else { | _____________^ @@ -176,7 +176,7 @@ LL + } else { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:89:14 + --> tests/ui/needless_return.rs:103:14 | LL | _ => return, | ^^^^^^ @@ -187,7 +187,7 @@ LL | _ => (), | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:97:24 + --> tests/ui/needless_return.rs:112:24 | LL | let _ = 42; | ________________________^ @@ -202,7 +202,7 @@ LL + let _ = 42; | error: unneeded `return` statement - --> tests/ui/needless_return.rs:100:14 + --> tests/ui/needless_return.rs:116:14 | LL | _ => return, | ^^^^^^ @@ -213,7 +213,7 @@ LL | _ => (), | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:113:9 + --> tests/ui/needless_return.rs:130:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -225,7 +225,7 @@ LL + String::from("test") | error: unneeded `return` statement - --> tests/ui/needless_return.rs:115:9 + --> tests/ui/needless_return.rs:133:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^ @@ -237,7 +237,7 @@ LL + String::new() | error: unneeded `return` statement - --> tests/ui/needless_return.rs:137:32 + --> tests/ui/needless_return.rs:156:32 | LL | bar.unwrap_or_else(|_| return) | ^^^^^^ @@ -248,7 +248,7 @@ LL | bar.unwrap_or_else(|_| {}) | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:141:21 + --> tests/ui/needless_return.rs:161:21 | LL | let _ = || { | _____________________^ @@ -263,7 +263,7 @@ LL + let _ = || { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:144:20 + --> tests/ui/needless_return.rs:165:20 | LL | let _ = || return; | ^^^^^^ @@ -274,7 +274,7 @@ LL | let _ = || {}; | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:150:32 + --> tests/ui/needless_return.rs:172:32 | LL | res.unwrap_or_else(|_| return Foo) | ^^^^^^^^^^ @@ -285,7 +285,7 @@ LL | res.unwrap_or_else(|_| Foo) | ~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:159:5 + --> tests/ui/needless_return.rs:182:5 | LL | return true; | ^^^^^^^^^^^ @@ -297,7 +297,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:163:5 + --> tests/ui/needless_return.rs:187:5 | LL | return true; | ^^^^^^^^^^^ @@ -309,7 +309,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:168:9 + --> tests/ui/needless_return.rs:193:9 | LL | return true; | ^^^^^^^^^^^ @@ -321,7 +321,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:170:9 + --> tests/ui/needless_return.rs:196:9 | LL | return false; | ^^^^^^^^^^^^ @@ -333,7 +333,7 @@ LL + false | error: unneeded `return` statement - --> tests/ui/needless_return.rs:176:17 + --> tests/ui/needless_return.rs:203:17 | LL | true => return false, | ^^^^^^^^^^^^ @@ -344,7 +344,7 @@ LL | true => false, | ~~~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:178:13 + --> tests/ui/needless_return.rs:206:13 | LL | return true; | ^^^^^^^^^^^ @@ -356,7 +356,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:185:9 + --> tests/ui/needless_return.rs:214:9 | LL | return true; | ^^^^^^^^^^^ @@ -368,7 +368,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:187:16 + --> tests/ui/needless_return.rs:217:16 | LL | let _ = || return true; | ^^^^^^^^^^^ @@ -379,7 +379,7 @@ LL | let _ = || true; | ~~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:191:5 + --> tests/ui/needless_return.rs:222:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^ @@ -391,7 +391,7 @@ LL + the_answer!() | error: unneeded `return` statement - --> tests/ui/needless_return.rs:194:33 + --> tests/ui/needless_return.rs:226:33 | LL | async fn async_test_void_fun() { | _________________________________^ @@ -406,7 +406,7 @@ LL + async fn async_test_void_fun() { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:199:11 + --> tests/ui/needless_return.rs:232:11 | LL | if b { | ___________^ @@ -421,7 +421,7 @@ LL + if b { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:201:13 + --> tests/ui/needless_return.rs:235:13 | LL | } else { | _____________^ @@ -436,7 +436,7 @@ LL + } else { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:209:14 + --> tests/ui/needless_return.rs:244:14 | LL | _ => return, | ^^^^^^ @@ -447,7 +447,7 @@ LL | _ => (), | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:222:9 + --> tests/ui/needless_return.rs:258:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -459,7 +459,7 @@ LL + String::from("test") | error: unneeded `return` statement - --> tests/ui/needless_return.rs:224:9 + --> tests/ui/needless_return.rs:261:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^ @@ -471,7 +471,7 @@ LL + String::new() | error: unneeded `return` statement - --> tests/ui/needless_return.rs:240:5 + --> tests/ui/needless_return.rs:278:5 | LL | return format!("Hello {}", "world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -483,7 +483,7 @@ LL + format!("Hello {}", "world!") | error: unneeded `return` statement - --> tests/ui/needless_return.rs:281:9 + --> tests/ui/needless_return.rs:320:9 | LL | return true; | ^^^^^^^^^^^ @@ -491,13 +491,14 @@ LL | return true; help: remove `return` | LL ~ true -LL | } else { -LL | return false; +LL | +... +LL | LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:283:9 + --> tests/ui/needless_return.rs:323:9 | LL | return false; | ^^^^^^^^^^^^ @@ -505,11 +506,12 @@ LL | return false; help: remove `return` | LL ~ false +LL | LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:290:13 + --> tests/ui/needless_return.rs:331:13 | LL | return 10; | ^^^^^^^^^ @@ -517,14 +519,14 @@ LL | return 10; help: remove `return` | LL ~ 10 -LL | }, +LL | ... LL | }, LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:293:13 + --> tests/ui/needless_return.rs:335:13 | LL | return 100; | ^^^^^^^^^^ @@ -532,12 +534,13 @@ LL | return 100; help: remove `return` | LL ~ 100 +LL | LL | }, LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:301:9 + --> tests/ui/needless_return.rs:344:9 | LL | return 0; | ^^^^^^^^ @@ -545,11 +548,12 @@ LL | return 0; help: remove `return` | LL ~ 0 +LL | LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:308:13 + --> tests/ui/needless_return.rs:352:13 | LL | return *(x as *const isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -557,14 +561,15 @@ LL | return *(x as *const isize); help: remove `return` | LL ~ *(x as *const isize) -LL | } else { -LL | return !*(x as *const isize); +LL | +... +LL | LL ~ } LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:310:13 + --> tests/ui/needless_return.rs:355:13 | LL | return !*(x as *const isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -572,29 +577,28 @@ LL | return !*(x as *const isize); help: remove `return` | LL ~ !*(x as *const isize) +LL | LL ~ } LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:317:20 + --> tests/ui/needless_return.rs:363:20 | LL | let _ = 42; | ____________________^ -LL | | LL | | return; | |______________^ | help: remove `return` | LL - let _ = 42; -LL - LL - return; LL + let _ = 42; | error: unneeded `return` statement - --> tests/ui/needless_return.rs:324:20 + --> tests/ui/needless_return.rs:370:20 | LL | let _ = 42; return; | ^^^^^^^ @@ -606,7 +610,7 @@ LL + let _ = 42; | error: unneeded `return` statement - --> tests/ui/needless_return.rs:336:9 + --> tests/ui/needless_return.rs:383:9 | LL | return Ok(format!("ok!")); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -618,7 +622,7 @@ LL + Ok(format!("ok!")) | error: unneeded `return` statement - --> tests/ui/needless_return.rs:338:9 + --> tests/ui/needless_return.rs:386:9 | LL | return Err(format!("err!")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -630,7 +634,7 @@ LL + Err(format!("err!")) | error: unneeded `return` statement - --> tests/ui/needless_return.rs:344:9 + --> tests/ui/needless_return.rs:393:9 | LL | return if true { 1 } else { 2 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -642,7 +646,7 @@ LL + if true { 1 } else { 2 } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:348:9 + --> tests/ui/needless_return.rs:398:9 | LL | return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -654,7 +658,7 @@ LL + (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else | error: unneeded `return` statement - --> tests/ui/needless_return.rs:369:5 + --> tests/ui/needless_return.rs:420:5 | LL | return { "a".to_string() } + "b" + { "c" }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -666,7 +670,7 @@ LL + ({ "a".to_string() } + "b" + { "c" }) | error: unneeded `return` statement - --> tests/ui/needless_return.rs:373:5 + --> tests/ui/needless_return.rs:425:5 | LL | return "".split("").next().unwrap().to_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/needless_return_with_question_mark.fixed b/tests/ui/needless_return_with_question_mark.fixed index 9b7da8526631..2c6faf37717d 100644 --- a/tests/ui/needless_return_with_question_mark.fixed +++ b/tests/ui/needless_return_with_question_mark.fixed @@ -27,6 +27,7 @@ fn c() -> Option<()> { fn main() -> Result<(), ()> { Err(())?; + //~^ needless_return_with_question_mark return Ok::<(), ()>(()); Err(())?; Ok::<(), ()>(()); diff --git a/tests/ui/needless_return_with_question_mark.rs b/tests/ui/needless_return_with_question_mark.rs index 68e76d2b6402..b4411fa19561 100644 --- a/tests/ui/needless_return_with_question_mark.rs +++ b/tests/ui/needless_return_with_question_mark.rs @@ -27,6 +27,7 @@ fn c() -> Option<()> { fn main() -> Result<(), ()> { return Err(())?; + //~^ needless_return_with_question_mark return Ok::<(), ()>(()); Err(())?; Ok::<(), ()>(()); diff --git a/tests/ui/needless_return_with_question_mark.stderr b/tests/ui/needless_return_with_question_mark.stderr index 76dd5f953bc6..2af0f46a1ad0 100644 --- a/tests/ui/needless_return_with_question_mark.stderr +++ b/tests/ui/needless_return_with_question_mark.stderr @@ -8,7 +8,7 @@ LL | return Err(())?; = help: to override `-D warnings` add `#[allow(clippy::needless_return_with_question_mark)]` error: unneeded `return` statement with `?` operator - --> tests/ui/needless_return_with_question_mark.rs:69:9 + --> tests/ui/needless_return_with_question_mark.rs:70:9 | LL | return Err(())?; | ^^^^^^^ help: remove it diff --git a/tests/ui/needless_splitn.fixed b/tests/ui/needless_splitn.fixed index efc47533e233..bf5c1717ae53 100644 --- a/tests/ui/needless_splitn.fixed +++ b/tests/ui/needless_splitn.fixed @@ -11,29 +11,41 @@ use itertools::Itertools; fn main() { let str = "key=value=end"; let _ = str.split('=').next(); + //~^ needless_splitn let _ = str.split('=').nth(0); + //~^ needless_splitn let _ = str.splitn(2, '=').nth(1); let (_, _) = str.splitn(2, '=').next_tuple().unwrap(); let (_, _) = str.split('=').next_tuple().unwrap(); + //~^ needless_splitn let _: Vec<&str> = str.splitn(3, '=').collect(); let _ = str.rsplit('=').next(); + //~^ needless_splitn let _ = str.rsplit('=').nth(0); + //~^ needless_splitn let _ = str.rsplitn(2, '=').nth(1); let (_, _) = str.rsplitn(2, '=').next_tuple().unwrap(); let (_, _) = str.rsplit('=').next_tuple().unwrap(); + //~^ needless_splitn let _ = str.split('=').next(); + //~^ needless_splitn let _ = str.split('=').nth(3); + //~^ needless_splitn let _ = str.splitn(5, '=').nth(4); let _ = str.splitn(5, '=').nth(5); } fn _question_mark(s: &str) -> Option<()> { let _ = s.split('=').next()?; + //~^ needless_splitn let _ = s.split('=').nth(0)?; + //~^ needless_splitn let _ = s.rsplit('=').next()?; + //~^ needless_splitn let _ = s.rsplit('=').nth(0)?; + //~^ needless_splitn Some(()) } @@ -42,4 +54,5 @@ fn _question_mark(s: &str) -> Option<()> { fn _test_msrv() { // `manual_split_once` MSRV shouldn't apply to `needless_splitn` let _ = "key=value".split('=').nth(0).unwrap(); + //~^ needless_splitn } diff --git a/tests/ui/needless_splitn.rs b/tests/ui/needless_splitn.rs index a4a3736eea2f..fdfdcb9d5ca8 100644 --- a/tests/ui/needless_splitn.rs +++ b/tests/ui/needless_splitn.rs @@ -11,29 +11,41 @@ use itertools::Itertools; fn main() { let str = "key=value=end"; let _ = str.splitn(2, '=').next(); + //~^ needless_splitn let _ = str.splitn(2, '=').nth(0); + //~^ needless_splitn let _ = str.splitn(2, '=').nth(1); let (_, _) = str.splitn(2, '=').next_tuple().unwrap(); let (_, _) = str.splitn(3, '=').next_tuple().unwrap(); + //~^ needless_splitn let _: Vec<&str> = str.splitn(3, '=').collect(); let _ = str.rsplitn(2, '=').next(); + //~^ needless_splitn let _ = str.rsplitn(2, '=').nth(0); + //~^ needless_splitn let _ = str.rsplitn(2, '=').nth(1); let (_, _) = str.rsplitn(2, '=').next_tuple().unwrap(); let (_, _) = str.rsplitn(3, '=').next_tuple().unwrap(); + //~^ needless_splitn let _ = str.splitn(5, '=').next(); + //~^ needless_splitn let _ = str.splitn(5, '=').nth(3); + //~^ needless_splitn let _ = str.splitn(5, '=').nth(4); let _ = str.splitn(5, '=').nth(5); } fn _question_mark(s: &str) -> Option<()> { let _ = s.splitn(2, '=').next()?; + //~^ needless_splitn let _ = s.splitn(2, '=').nth(0)?; + //~^ needless_splitn let _ = s.rsplitn(2, '=').next()?; + //~^ needless_splitn let _ = s.rsplitn(2, '=').nth(0)?; + //~^ needless_splitn Some(()) } @@ -42,4 +54,5 @@ fn _question_mark(s: &str) -> Option<()> { fn _test_msrv() { // `manual_split_once` MSRV shouldn't apply to `needless_splitn` let _ = "key=value".splitn(2, '=').nth(0).unwrap(); + //~^ needless_splitn } diff --git a/tests/ui/needless_splitn.stderr b/tests/ui/needless_splitn.stderr index ffd82c3fcb13..49387793a122 100644 --- a/tests/ui/needless_splitn.stderr +++ b/tests/ui/needless_splitn.stderr @@ -8,73 +8,73 @@ LL | let _ = str.splitn(2, '=').next(); = help: to override `-D warnings` add `#[allow(clippy::needless_splitn)]` error: unnecessary use of `splitn` - --> tests/ui/needless_splitn.rs:14:13 + --> tests/ui/needless_splitn.rs:15:13 | LL | let _ = str.splitn(2, '=').nth(0); | ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')` error: unnecessary use of `splitn` - --> tests/ui/needless_splitn.rs:17:18 + --> tests/ui/needless_splitn.rs:19:18 | LL | let (_, _) = str.splitn(3, '=').next_tuple().unwrap(); | ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')` error: unnecessary use of `rsplitn` - --> tests/ui/needless_splitn.rs:20:13 + --> tests/ui/needless_splitn.rs:23:13 | LL | let _ = str.rsplitn(2, '=').next(); | ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')` error: unnecessary use of `rsplitn` - --> tests/ui/needless_splitn.rs:21:13 + --> tests/ui/needless_splitn.rs:25:13 | LL | let _ = str.rsplitn(2, '=').nth(0); | ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')` error: unnecessary use of `rsplitn` - --> tests/ui/needless_splitn.rs:24:18 + --> tests/ui/needless_splitn.rs:29:18 | LL | let (_, _) = str.rsplitn(3, '=').next_tuple().unwrap(); | ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')` error: unnecessary use of `splitn` - --> tests/ui/needless_splitn.rs:26:13 + --> tests/ui/needless_splitn.rs:32:13 | LL | let _ = str.splitn(5, '=').next(); | ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')` error: unnecessary use of `splitn` - --> tests/ui/needless_splitn.rs:27:13 + --> tests/ui/needless_splitn.rs:34:13 | LL | let _ = str.splitn(5, '=').nth(3); | ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')` error: unnecessary use of `splitn` - --> tests/ui/needless_splitn.rs:33:13 + --> tests/ui/needless_splitn.rs:41:13 | LL | let _ = s.splitn(2, '=').next()?; | ^^^^^^^^^^^^^^^^ help: try: `s.split('=')` error: unnecessary use of `splitn` - --> tests/ui/needless_splitn.rs:34:13 + --> tests/ui/needless_splitn.rs:43:13 | LL | let _ = s.splitn(2, '=').nth(0)?; | ^^^^^^^^^^^^^^^^ help: try: `s.split('=')` error: unnecessary use of `rsplitn` - --> tests/ui/needless_splitn.rs:35:13 + --> tests/ui/needless_splitn.rs:45:13 | LL | let _ = s.rsplitn(2, '=').next()?; | ^^^^^^^^^^^^^^^^^ help: try: `s.rsplit('=')` error: unnecessary use of `rsplitn` - --> tests/ui/needless_splitn.rs:36:13 + --> tests/ui/needless_splitn.rs:47:13 | LL | let _ = s.rsplitn(2, '=').nth(0)?; | ^^^^^^^^^^^^^^^^^ help: try: `s.rsplit('=')` error: unnecessary use of `splitn` - --> tests/ui/needless_splitn.rs:44:13 + --> tests/ui/needless_splitn.rs:56:13 | LL | let _ = "key=value".splitn(2, '=').nth(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split('=')` diff --git a/tests/ui/needless_update.rs b/tests/ui/needless_update.rs index 7c59abf07aba..6e91c957e811 100644 --- a/tests/ui/needless_update.rs +++ b/tests/ui/needless_update.rs @@ -17,8 +17,9 @@ fn main() { S { ..base }; // no error S { a: 1, ..base }; // no error S { a: 1, b: 1, ..base }; - //~^ ERROR: struct update has no effect, all the fields in the struct have already bee - //~| NOTE: `-D clippy::needless-update` implied by `-D warnings` + //~^ needless_update + + let base = T { x: 0, y: 0 }; T { ..base }; // no error diff --git a/tests/ui/neg_cmp_op_on_partial_ord.rs b/tests/ui/neg_cmp_op_on_partial_ord.rs index c79fd2665260..7d24429b5867 100644 --- a/tests/ui/neg_cmp_op_on_partial_ord.rs +++ b/tests/ui/neg_cmp_op_on_partial_ord.rs @@ -14,20 +14,24 @@ fn main() { // Not Less but potentially Greater, Equal or Uncomparable. let _not_less = !(a_value < another_value); - //~^ ERROR: the use of negated comparison operators on partially ordered types produce - //~| NOTE: `-D clippy::neg-cmp-op-on-partial-ord` implied by `-D warnings` + //~^ neg_cmp_op_on_partial_ord + + // Not Less or Equal but potentially Greater or Uncomparable. let _not_less_or_equal = !(a_value <= another_value); - //~^ ERROR: the use of negated comparison operators on partially ordered types produce + //~^ neg_cmp_op_on_partial_ord + // Not Greater but potentially Less, Equal or Uncomparable. let _not_greater = !(a_value > another_value); - //~^ ERROR: the use of negated comparison operators on partially ordered types produce + //~^ neg_cmp_op_on_partial_ord + // Not Greater or Equal but potentially Less or Uncomparable. let _not_greater_or_equal = !(a_value >= another_value); - //~^ ERROR: the use of negated comparison operators on partially ordered types produce + //~^ neg_cmp_op_on_partial_ord + // --- Good --- diff --git a/tests/ui/neg_cmp_op_on_partial_ord.stderr b/tests/ui/neg_cmp_op_on_partial_ord.stderr index d4f7f14f59a3..f6347b7d56cd 100644 --- a/tests/ui/neg_cmp_op_on_partial_ord.stderr +++ b/tests/ui/neg_cmp_op_on_partial_ord.stderr @@ -8,19 +8,19 @@ LL | let _not_less = !(a_value < another_value); = help: to override `-D warnings` add `#[allow(clippy::neg_cmp_op_on_partial_ord)]` error: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable - --> tests/ui/neg_cmp_op_on_partial_ord.rs:21:30 + --> tests/ui/neg_cmp_op_on_partial_ord.rs:22:30 | LL | let _not_less_or_equal = !(a_value <= another_value); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable - --> tests/ui/neg_cmp_op_on_partial_ord.rs:25:24 + --> tests/ui/neg_cmp_op_on_partial_ord.rs:27:24 | LL | let _not_greater = !(a_value > another_value); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable - --> tests/ui/neg_cmp_op_on_partial_ord.rs:29:33 + --> tests/ui/neg_cmp_op_on_partial_ord.rs:32:33 | LL | let _not_greater_or_equal = !(a_value >= another_value); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/neg_multiply.fixed b/tests/ui/neg_multiply.fixed index 52edea73afbb..995470493bfb 100644 --- a/tests/ui/neg_multiply.fixed +++ b/tests/ui/neg_multiply.fixed @@ -26,19 +26,27 @@ fn main() { let x = 0; -x; + //~^ neg_multiply -x; + //~^ neg_multiply 100 + -x; + //~^ neg_multiply -(100 + x); + //~^ neg_multiply -17; + //~^ neg_multiply 0xcafe | -0xff00; + //~^ neg_multiply -(3_usize as i32); + //~^ neg_multiply -(3_usize as i32); + //~^ neg_multiply -1 * -1; // should be ok diff --git a/tests/ui/neg_multiply.rs b/tests/ui/neg_multiply.rs index 23092a35e606..95b94e29517f 100644 --- a/tests/ui/neg_multiply.rs +++ b/tests/ui/neg_multiply.rs @@ -26,19 +26,27 @@ fn main() { let x = 0; x * -1; + //~^ neg_multiply -1 * x; + //~^ neg_multiply 100 + x * -1; + //~^ neg_multiply (100 + x) * -1; + //~^ neg_multiply -1 * 17; + //~^ neg_multiply 0xcafe | 0xff00 * -1; + //~^ neg_multiply 3_usize as i32 * -1; + //~^ neg_multiply (3_usize as i32) * -1; + //~^ neg_multiply -1 * -1; // should be ok diff --git a/tests/ui/neg_multiply.stderr b/tests/ui/neg_multiply.stderr index 13226c7c37b3..9efa5d3ba1f1 100644 --- a/tests/ui/neg_multiply.stderr +++ b/tests/ui/neg_multiply.stderr @@ -8,43 +8,43 @@ LL | x * -1; = help: to override `-D warnings` add `#[allow(clippy::neg_multiply)]` error: this multiplication by -1 can be written more succinctly - --> tests/ui/neg_multiply.rs:30:5 + --> tests/ui/neg_multiply.rs:31:5 | LL | -1 * x; | ^^^^^^ help: consider using: `-x` error: this multiplication by -1 can be written more succinctly - --> tests/ui/neg_multiply.rs:32:11 + --> tests/ui/neg_multiply.rs:34:11 | LL | 100 + x * -1; | ^^^^^^ help: consider using: `-x` error: this multiplication by -1 can be written more succinctly - --> tests/ui/neg_multiply.rs:34:5 + --> tests/ui/neg_multiply.rs:37:5 | LL | (100 + x) * -1; | ^^^^^^^^^^^^^^ help: consider using: `-(100 + x)` error: this multiplication by -1 can be written more succinctly - --> tests/ui/neg_multiply.rs:36:5 + --> tests/ui/neg_multiply.rs:40:5 | LL | -1 * 17; | ^^^^^^^ help: consider using: `-17` error: this multiplication by -1 can be written more succinctly - --> tests/ui/neg_multiply.rs:38:14 + --> tests/ui/neg_multiply.rs:43:14 | LL | 0xcafe | 0xff00 * -1; | ^^^^^^^^^^^ help: consider using: `-0xff00` error: this multiplication by -1 can be written more succinctly - --> tests/ui/neg_multiply.rs:40:5 + --> tests/ui/neg_multiply.rs:46:5 | LL | 3_usize as i32 * -1; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3_usize as i32)` error: this multiplication by -1 can be written more succinctly - --> tests/ui/neg_multiply.rs:41:5 + --> tests/ui/neg_multiply.rs:48:5 | LL | (3_usize as i32) * -1; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3_usize as i32)` diff --git a/tests/ui/never_loop.rs b/tests/ui/never_loop.rs index 93c69209c698..c366e7d86310 100644 --- a/tests/ui/never_loop.rs +++ b/tests/ui/never_loop.rs @@ -10,8 +10,9 @@ fn test1() { let mut x = 0; loop { - //~^ ERROR: this loop never actually loops - //~| NOTE: `#[deny(clippy::never_loop)]` on by default + //~^ never_loop + + // clippy::never_loop x += 1; if x == 1 { @@ -34,7 +35,8 @@ fn test2() { fn test3() { let mut x = 0; loop { - //~^ ERROR: this loop never actually loops + //~^ never_loop + // never loops x += 1; break; @@ -55,10 +57,12 @@ fn test4() { fn test5() { let i = 0; loop { - //~^ ERROR: this loop never actually loops + //~^ never_loop + // never loops while i == 0 { - //~^ ERROR: this loop never actually loops + //~^ never_loop + // never loops break; } @@ -71,7 +75,8 @@ fn test6() { 'outer: loop { x += 1; loop { - //~^ ERROR: this loop never actually loops + //~^ never_loop + // never loops if x == 5 { break; @@ -108,7 +113,8 @@ fn test8() { fn test9() { let x = Some(1); while let Some(y) = x { - //~^ ERROR: this loop never actually loops + //~^ never_loop + // never loops return; } @@ -116,7 +122,8 @@ fn test9() { fn test10() { for x in 0..10 { - //~^ ERROR: this loop never actually loops + //~^ never_loop + // never loops match x { 1 => break, @@ -165,7 +172,8 @@ pub fn test13() { pub fn test14() { let mut a = true; 'outer: while a { - //~^ ERROR: this loop never actually loops + //~^ never_loop + // never loops while a { if a { @@ -181,7 +189,8 @@ pub fn test14() { pub fn test15() { 'label: loop { while false { - //~^ ERROR: this loop never actually loops + //~^ never_loop + break 'label; } } @@ -233,7 +242,8 @@ pub fn test18() { }; // never loops let _ = loop { - //~^ ERROR: this loop never actually loops + //~^ never_loop + let Some(x) = x else { return; }; @@ -255,12 +265,14 @@ pub fn test19() { pub fn test20() { 'a: loop { - //~^ ERROR: this loop never actually loops + //~^ never_loop + 'b: { break 'b 'c: { break 'a; - //~^ ERROR: sub-expression diverges - //~| NOTE: `-D clippy::diverging-sub-expression` implied by `-D warnings` + //~^ diverging_sub_expression + + }; } } @@ -292,7 +304,8 @@ pub fn test23() { for _ in 0..10 { 'block: { for _ in 0..20 { - //~^ ERROR: this loop never actually loops + //~^ never_loop + break 'block; } } @@ -376,7 +389,8 @@ pub fn test31(b: bool) { 'a: loop { 'b: { 'c: loop { - //~^ ERROR: this loop never actually loops + //~^ never_loop + if b { break 'c } else { break 'b } } continue 'a; @@ -387,11 +401,13 @@ pub fn test31(b: bool) { pub fn test32() { loop { - //~^ ERROR: this loop never actually loops + //~^ never_loop + panic!("oh no"); } loop { - //~^ ERROR: this loop never actually loops + //~^ never_loop + unimplemented!("not yet"); } loop { diff --git a/tests/ui/never_loop.stderr b/tests/ui/never_loop.stderr index dab3488af106..6d492f8eb9da 100644 --- a/tests/ui/never_loop.stderr +++ b/tests/ui/never_loop.stderr @@ -10,67 +10,52 @@ LL | | } = note: `#[deny(clippy::never_loop)]` on by default error: this loop never actually loops - --> tests/ui/never_loop.rs:36:5 + --> tests/ui/never_loop.rs:37:5 | LL | / loop { -LL | | -LL | | // never loops -LL | | x += 1; +... | LL | | break; LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:57:5 + --> tests/ui/never_loop.rs:59:5 | LL | / loop { -LL | | -LL | | // never loops -LL | | while i == 0 { ... | LL | | return; LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:60:9 + --> tests/ui/never_loop.rs:63:9 | LL | / while i == 0 { -LL | | -LL | | // never loops -LL | | break; +... | LL | | } | |_________^ error: this loop never actually loops - --> tests/ui/never_loop.rs:73:9 + --> tests/ui/never_loop.rs:77:9 | LL | / loop { -LL | | -LL | | // never loops -LL | | if x == 5 { ... | LL | | continue 'outer; LL | | } | |_________^ error: this loop never actually loops - --> tests/ui/never_loop.rs:110:5 + --> tests/ui/never_loop.rs:115:5 | LL | / while let Some(y) = x { -LL | | -LL | | // never loops -LL | | return; +... | LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:118:5 + --> tests/ui/never_loop.rs:124:5 | LL | / for x in 0..10 { -LL | | -LL | | // never loops -LL | | match x { ... | LL | | } | |_____^ @@ -81,52 +66,50 @@ LL | if let Some(x) = (0..10).next() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: this loop never actually loops - --> tests/ui/never_loop.rs:167:5 + --> tests/ui/never_loop.rs:174:5 | LL | / 'outer: while a { -LL | | -LL | | // never loops -LL | | while a { ... | LL | | break 'outer; LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:183:9 + --> tests/ui/never_loop.rs:191:9 | LL | / while false { LL | | +LL | | LL | | break 'label; LL | | } | |_________^ error: this loop never actually loops - --> tests/ui/never_loop.rs:235:13 + --> tests/ui/never_loop.rs:244:13 | LL | let _ = loop { | _____________^ LL | | +LL | | LL | | let Some(x) = x else { -LL | | return; ... | LL | | break x; LL | | }; | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:257:5 + --> tests/ui/never_loop.rs:267:5 | LL | / 'a: loop { LL | | +LL | | LL | | 'b: { -LL | | break 'b 'c: { ... | LL | | } | |_____^ error: sub-expression diverges - --> tests/ui/never_loop.rs:261:17 + --> tests/ui/never_loop.rs:272:17 | LL | break 'a; | ^^^^^^^^ @@ -135,10 +118,11 @@ LL | break 'a; = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]` error: this loop never actually loops - --> tests/ui/never_loop.rs:294:13 + --> tests/ui/never_loop.rs:306:13 | LL | / for _ in 0..20 { LL | | +LL | | LL | | break 'block; LL | | } | |_____________^ @@ -149,28 +133,31 @@ LL | if let Some(_) = (0..20).next() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: this loop never actually loops - --> tests/ui/never_loop.rs:378:13 + --> tests/ui/never_loop.rs:391:13 | LL | / 'c: loop { LL | | +LL | | LL | | if b { break 'c } else { break 'b } LL | | } | |_____________^ error: this loop never actually loops - --> tests/ui/never_loop.rs:389:5 + --> tests/ui/never_loop.rs:403:5 | LL | / loop { LL | | +LL | | LL | | panic!("oh no"); LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:393:5 + --> tests/ui/never_loop.rs:408:5 | LL | / loop { LL | | +LL | | LL | | unimplemented!("not yet"); LL | | } | |_____^ diff --git a/tests/ui/new_ret_no_self.rs b/tests/ui/new_ret_no_self.rs index 175b14d815a2..fc7dea97e48a 100644 --- a/tests/ui/new_ret_no_self.rs +++ b/tests/ui/new_ret_no_self.rs @@ -48,8 +48,9 @@ impl R for S3 { impl S3 { // should trigger the lint pub fn new(_: String) -> impl R { - //~^ ERROR: methods called `new` usually return `Self` - //~| NOTE: `-D clippy::new-ret-no-self` implied by `-D warnings` + //~^ new_ret_no_self + + S3 } } @@ -82,7 +83,8 @@ struct U; impl U { // should trigger lint pub fn new() -> u32 { - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + unimplemented!(); } } @@ -92,7 +94,8 @@ struct V; impl V { // should trigger lint pub fn new(_: String) -> u32 { - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + unimplemented!(); } } @@ -129,7 +132,8 @@ struct TupleReturnerBad; impl TupleReturnerBad { // should trigger lint pub fn new() -> (u32, u32) { - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + unimplemented!(); } } @@ -157,7 +161,8 @@ struct MutPointerReturnerBad; impl MutPointerReturnerBad { // should trigger lint pub fn new() -> *mut V { - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + unimplemented!(); } } @@ -176,7 +181,8 @@ struct GenericReturnerBad; impl GenericReturnerBad { // should trigger lint pub fn new() -> Option { - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + unimplemented!(); } } @@ -230,7 +236,8 @@ mod issue5435 { pub trait TraitRet { // should trigger lint as we are in trait definition fn new() -> String; - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + } pub struct StructRet; impl TraitRet for StructRet { @@ -243,7 +250,8 @@ mod issue5435 { pub trait TraitRet2 { // should trigger lint fn new(_: String) -> String; - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + } trait TupleReturnerOk { @@ -279,7 +287,8 @@ mod issue5435 { trait TupleReturnerBad { // should trigger lint fn new() -> (u32, u32) { - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + unimplemented!(); } } @@ -307,7 +316,8 @@ mod issue5435 { trait MutPointerReturnerBad { // should trigger lint fn new() -> *mut V { - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + unimplemented!(); } } @@ -378,7 +388,8 @@ mod issue7344 { impl RetImplTraitNoSelf { // should trigger lint fn new(t: T) -> impl Into { - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + 1 } } @@ -398,7 +409,8 @@ mod issue7344 { impl RetImplTraitNoSelf2 { // should trigger lint fn new(t: T) -> impl Trait2<(), i32> { - //~^ ERROR: methods called `new` usually return `Self` + //~^ new_ret_no_self + } } diff --git a/tests/ui/new_ret_no_self.stderr b/tests/ui/new_ret_no_self.stderr index 3597ad65838f..e31282c3fb7e 100644 --- a/tests/ui/new_ret_no_self.stderr +++ b/tests/ui/new_ret_no_self.stderr @@ -2,9 +2,7 @@ error: methods called `new` usually return `Self` --> tests/ui/new_ret_no_self.rs:50:5 | LL | / pub fn new(_: String) -> impl R { -LL | | -LL | | -LL | | S3 +... | LL | | } | |_____^ | @@ -12,94 +10,102 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::new_ret_no_self)]` error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:84:5 + --> tests/ui/new_ret_no_self.rs:85:5 | LL | / pub fn new() -> u32 { LL | | +LL | | LL | | unimplemented!(); LL | | } | |_____^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:94:5 + --> tests/ui/new_ret_no_self.rs:96:5 | LL | / pub fn new(_: String) -> u32 { LL | | +LL | | LL | | unimplemented!(); LL | | } | |_____^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:131:5 + --> tests/ui/new_ret_no_self.rs:134:5 | LL | / pub fn new() -> (u32, u32) { LL | | +LL | | LL | | unimplemented!(); LL | | } | |_____^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:159:5 + --> tests/ui/new_ret_no_self.rs:163:5 | LL | / pub fn new() -> *mut V { LL | | -LL | | unimplemented!(); -LL | | } - | |_____^ - -error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:178:5 - | -LL | / pub fn new() -> Option { LL | | LL | | unimplemented!(); LL | | } | |_____^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:232:9 + --> tests/ui/new_ret_no_self.rs:183:5 + | +LL | / pub fn new() -> Option { +LL | | +LL | | +LL | | unimplemented!(); +LL | | } + | |_____^ + +error: methods called `new` usually return `Self` + --> tests/ui/new_ret_no_self.rs:238:9 | LL | fn new() -> String; | ^^^^^^^^^^^^^^^^^^^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:245:9 + --> tests/ui/new_ret_no_self.rs:252:9 | LL | fn new(_: String) -> String; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:281:9 + --> tests/ui/new_ret_no_self.rs:289:9 | LL | / fn new() -> (u32, u32) { LL | | -LL | | unimplemented!(); -LL | | } - | |_________^ - -error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:309:9 - | -LL | / fn new() -> *mut V { LL | | LL | | unimplemented!(); LL | | } | |_________^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:380:9 + --> tests/ui/new_ret_no_self.rs:318:9 + | +LL | / fn new() -> *mut V { +LL | | +LL | | +LL | | unimplemented!(); +LL | | } + | |_________^ + +error: methods called `new` usually return `Self` + --> tests/ui/new_ret_no_self.rs:390:9 | LL | / fn new(t: T) -> impl Into { LL | | +LL | | LL | | 1 LL | | } | |_________^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:400:9 + --> tests/ui/new_ret_no_self.rs:411:9 | LL | / fn new(t: T) -> impl Trait2<(), i32> { -LL | | +... | LL | | } | |_________^ diff --git a/tests/ui/new_ret_no_self_overflow.rs b/tests/ui/new_ret_no_self_overflow.rs index 7bc6fec10ba6..db7ce9c4054e 100644 --- a/tests/ui/new_ret_no_self_overflow.rs +++ b/tests/ui/new_ret_no_self_overflow.rs @@ -18,6 +18,7 @@ mod issue10041 { impl Bomb2 { pub fn new() -> X { + //~^ ERROR: overflow evaluating the requirement 0i32 } } diff --git a/tests/ui/new_without_default.fixed b/tests/ui/new_without_default.fixed index 5a6a92394a7f..8fd703200835 100644 --- a/tests/ui/new_without_default.fixed +++ b/tests/ui/new_without_default.fixed @@ -17,8 +17,9 @@ impl Default for Foo { impl Foo { pub fn new() -> Foo { - //~^ ERROR: you should consider adding a `Default` implementation for `Foo` - //~| NOTE: `-D clippy::new-without-default` implied by `-D warnings` + //~^ new_without_default + + Foo } } @@ -33,7 +34,8 @@ impl Default for Bar { impl Bar { pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `Bar` + //~^ new_without_default + Bar } } @@ -104,7 +106,8 @@ impl<'c> Default for LtKo<'c> { impl<'c> LtKo<'c> { pub fn new() -> LtKo<'c> { - //~^ ERROR: you should consider adding a `Default` implementation for `LtKo<'c>` + //~^ new_without_default + unimplemented!() } } @@ -143,6 +146,7 @@ impl Default for Const { impl Const { pub const fn new() -> Const { + //~^ new_without_default Const } // While Default is not const, it can still call const functions, so we should lint this } @@ -209,7 +213,8 @@ impl Default for NewNotEqualToDerive { impl NewNotEqualToDerive { // This `new` implementation is not equal to a derived `Default`, so do not suggest deriving. pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `NewNotEqualToDe + //~^ new_without_default + NewNotEqualToDerive { foo: 1 } } } @@ -224,7 +229,8 @@ impl Default for FooGenerics { impl FooGenerics { pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `FooGenerics` + //~^ new_without_default + Self(Default::default()) } } @@ -238,7 +244,8 @@ impl Default for BarGenerics { impl BarGenerics { pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `BarGenerics` + //~^ new_without_default + Self(Default::default()) } } @@ -256,7 +263,8 @@ pub mod issue7220 { impl Foo { pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `Foo` + //~^ new_without_default + todo!() } } @@ -311,6 +319,7 @@ where K: std::hash::Hash + Eq + PartialEq, { pub fn new() -> Self { + //~^ new_without_default Self { _kv: None } } } diff --git a/tests/ui/new_without_default.rs b/tests/ui/new_without_default.rs index 12ea729253ac..856f515e4aba 100644 --- a/tests/ui/new_without_default.rs +++ b/tests/ui/new_without_default.rs @@ -11,8 +11,9 @@ pub struct Foo; impl Foo { pub fn new() -> Foo { - //~^ ERROR: you should consider adding a `Default` implementation for `Foo` - //~| NOTE: `-D clippy::new-without-default` implied by `-D warnings` + //~^ new_without_default + + Foo } } @@ -21,7 +22,8 @@ pub struct Bar; impl Bar { pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `Bar` + //~^ new_without_default + Bar } } @@ -86,7 +88,8 @@ pub struct LtKo<'a> { impl<'c> LtKo<'c> { pub fn new() -> LtKo<'c> { - //~^ ERROR: you should consider adding a `Default` implementation for `LtKo<'c>` + //~^ new_without_default + unimplemented!() } } @@ -119,6 +122,7 @@ pub struct Const; impl Const { pub const fn new() -> Const { + //~^ new_without_default Const } // While Default is not const, it can still call const functions, so we should lint this } @@ -179,7 +183,8 @@ pub struct NewNotEqualToDerive { impl NewNotEqualToDerive { // This `new` implementation is not equal to a derived `Default`, so do not suggest deriving. pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `NewNotEqualToDe + //~^ new_without_default + NewNotEqualToDerive { foo: 1 } } } @@ -188,7 +193,8 @@ impl NewNotEqualToDerive { pub struct FooGenerics(std::marker::PhantomData); impl FooGenerics { pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `FooGenerics` + //~^ new_without_default + Self(Default::default()) } } @@ -196,7 +202,8 @@ impl FooGenerics { pub struct BarGenerics(std::marker::PhantomData); impl BarGenerics { pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `BarGenerics` + //~^ new_without_default + Self(Default::default()) } } @@ -208,7 +215,8 @@ pub mod issue7220 { impl Foo { pub fn new() -> Self { - //~^ ERROR: you should consider adding a `Default` implementation for `Foo` + //~^ new_without_default + todo!() } } @@ -254,6 +262,7 @@ where K: std::hash::Hash + Eq + PartialEq, { pub fn new() -> Self { + //~^ new_without_default Self { _kv: None } } } diff --git a/tests/ui/new_without_default.stderr b/tests/ui/new_without_default.stderr index 57bf4bd847cc..1a122d341a08 100644 --- a/tests/ui/new_without_default.stderr +++ b/tests/ui/new_without_default.stderr @@ -2,9 +2,7 @@ error: you should consider adding a `Default` implementation for `Foo` --> tests/ui/new_without_default.rs:13:5 | LL | / pub fn new() -> Foo { -LL | | -LL | | -LL | | Foo +... | LL | | } | |_____^ | @@ -20,10 +18,11 @@ LL + } | error: you should consider adding a `Default` implementation for `Bar` - --> tests/ui/new_without_default.rs:23:5 + --> tests/ui/new_without_default.rs:24:5 | LL | / pub fn new() -> Self { LL | | +LL | | LL | | Bar LL | | } | |_____^ @@ -38,10 +37,11 @@ LL + } | error: you should consider adding a `Default` implementation for `LtKo<'c>` - --> tests/ui/new_without_default.rs:88:5 + --> tests/ui/new_without_default.rs:90:5 | LL | / pub fn new() -> LtKo<'c> { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -56,9 +56,10 @@ LL + } | error: you should consider adding a `Default` implementation for `Const` - --> tests/ui/new_without_default.rs:121:5 + --> tests/ui/new_without_default.rs:124:5 | LL | / pub const fn new() -> Const { +LL | | LL | | Const LL | | } // While Default is not const, it can still call const functions, so we should lint this | |_____^ @@ -73,10 +74,11 @@ LL + } | error: you should consider adding a `Default` implementation for `NewNotEqualToDerive` - --> tests/ui/new_without_default.rs:181:5 + --> tests/ui/new_without_default.rs:185:5 | LL | / pub fn new() -> Self { LL | | +LL | | LL | | NewNotEqualToDerive { foo: 1 } LL | | } | |_____^ @@ -91,10 +93,11 @@ LL + } | error: you should consider adding a `Default` implementation for `FooGenerics` - --> tests/ui/new_without_default.rs:190:5 + --> tests/ui/new_without_default.rs:195:5 | LL | / pub fn new() -> Self { LL | | +LL | | LL | | Self(Default::default()) LL | | } | |_____^ @@ -109,10 +112,11 @@ LL + } | error: you should consider adding a `Default` implementation for `BarGenerics` - --> tests/ui/new_without_default.rs:198:5 + --> tests/ui/new_without_default.rs:204:5 | LL | / pub fn new() -> Self { LL | | +LL | | LL | | Self(Default::default()) LL | | } | |_____^ @@ -127,10 +131,11 @@ LL + } | error: you should consider adding a `Default` implementation for `Foo` - --> tests/ui/new_without_default.rs:210:9 + --> tests/ui/new_without_default.rs:217:9 | LL | / pub fn new() -> Self { LL | | +LL | | LL | | todo!() LL | | } | |_________^ @@ -147,9 +152,10 @@ LL ~ impl Foo { | error: you should consider adding a `Default` implementation for `MyStruct` - --> tests/ui/new_without_default.rs:256:5 + --> tests/ui/new_without_default.rs:264:5 | LL | / pub fn new() -> Self { +LL | | LL | | Self { _kv: None } LL | | } | |_____^ diff --git a/tests/ui/no_effect.rs b/tests/ui/no_effect.rs index 0ea911c34348..cd992aed15e2 100644 --- a/tests/ui/no_effect.rs +++ b/tests/ui/no_effect.rs @@ -113,62 +113,89 @@ fn main() { let s = get_struct(); 0; - //~^ ERROR: statement with no effect + //~^ no_effect + Tuple(0); - //~^ ERROR: statement with no effect + //~^ no_effect + Struct { field: 0 }; - //~^ ERROR: statement with no effect + //~^ no_effect + Struct { ..s }; - //~^ ERROR: statement with no effect + //~^ no_effect + Union { a: 0 }; - //~^ ERROR: statement with no effect + //~^ no_effect + Enum::Tuple(0); - //~^ ERROR: statement with no effect + //~^ no_effect + Enum::Struct { field: 0 }; - //~^ ERROR: statement with no effect + //~^ no_effect + 5 + 6; - //~^ ERROR: statement with no effect + //~^ no_effect + *&42; - //~^ ERROR: statement with no effect + //~^ no_effect + &6; - //~^ ERROR: statement with no effect + //~^ no_effect + (5, 6, 7); - //~^ ERROR: statement with no effect + //~^ no_effect + ..; - //~^ ERROR: statement with no effect + //~^ no_effect + 5..; - //~^ ERROR: statement with no effect + //~^ no_effect + ..5; - //~^ ERROR: statement with no effect + //~^ no_effect + 5..6; - //~^ ERROR: statement with no effect + //~^ no_effect + 5..=6; - //~^ ERROR: statement with no effect + //~^ no_effect + [42, 55]; - //~^ ERROR: statement with no effect + //~^ no_effect + [42, 55][1]; - //~^ ERROR: statement with no effect + //~^ no_effect + (42, 55).1; - //~^ ERROR: statement with no effect + //~^ no_effect + [42; 55]; - //~^ ERROR: statement with no effect + //~^ no_effect + [42; 55][13]; - //~^ ERROR: statement with no effect + //~^ no_effect + let mut x = 0; || x += 5; - //~^ ERROR: statement with no effect + //~^ no_effect + let s: String = "foo".into(); FooString { s: s }; - //~^ ERROR: statement with no effect + //~^ no_effect + let _unused = 1; - //~^ ERROR: binding to `_` prefixed variable with no side-effect - //~| NOTE: `-D clippy::no-effect-underscore-binding` implied by `-D warnings` + //~^ no_effect_underscore_binding + + let _penguin = || println!("Some helpful closure"); - //~^ ERROR: binding to `_` prefixed variable with no side-effect + //~^ no_effect_underscore_binding + let _duck = Struct { field: 0 }; - //~^ ERROR: binding to `_` prefixed variable with no side-effect + //~^ no_effect_underscore_binding + let _cat = [2, 4, 6, 8][2]; - //~^ ERROR: binding to `_` prefixed variable with no side-effect + //~^ no_effect_underscore_binding + let _issue_12166 = 42; let underscore_variable_above_can_be_used_dont_lint = _issue_12166; diff --git a/tests/ui/no_effect.stderr b/tests/ui/no_effect.stderr index 48ec997d938c..617a43aaf60d 100644 --- a/tests/ui/no_effect.stderr +++ b/tests/ui/no_effect.stderr @@ -8,139 +8,139 @@ LL | 0; = help: to override `-D warnings` add `#[allow(clippy::no_effect)]` error: statement with no effect - --> tests/ui/no_effect.rs:117:5 + --> tests/ui/no_effect.rs:118:5 | LL | Tuple(0); | ^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:119:5 + --> tests/ui/no_effect.rs:121:5 | LL | Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:121:5 + --> tests/ui/no_effect.rs:124:5 | LL | Struct { ..s }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:123:5 + --> tests/ui/no_effect.rs:127:5 | LL | Union { a: 0 }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:125:5 + --> tests/ui/no_effect.rs:130:5 | LL | Enum::Tuple(0); | ^^^^^^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:127:5 + --> tests/ui/no_effect.rs:133:5 | LL | Enum::Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:129:5 + --> tests/ui/no_effect.rs:136:5 | LL | 5 + 6; | ^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:131:5 + --> tests/ui/no_effect.rs:139:5 | LL | *&42; | ^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:133:5 + --> tests/ui/no_effect.rs:142:5 | LL | &6; | ^^^ error: statement with no effect - --> tests/ui/no_effect.rs:135:5 + --> tests/ui/no_effect.rs:145:5 | LL | (5, 6, 7); | ^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:137:5 + --> tests/ui/no_effect.rs:148:5 | LL | ..; | ^^^ error: statement with no effect - --> tests/ui/no_effect.rs:139:5 + --> tests/ui/no_effect.rs:151:5 | LL | 5..; | ^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:141:5 + --> tests/ui/no_effect.rs:154:5 | LL | ..5; | ^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:143:5 + --> tests/ui/no_effect.rs:157:5 | LL | 5..6; | ^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:145:5 + --> tests/ui/no_effect.rs:160:5 | LL | 5..=6; | ^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:147:5 + --> tests/ui/no_effect.rs:163:5 | LL | [42, 55]; | ^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:149:5 + --> tests/ui/no_effect.rs:166:5 | LL | [42, 55][1]; | ^^^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:151:5 + --> tests/ui/no_effect.rs:169:5 | LL | (42, 55).1; | ^^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:153:5 + --> tests/ui/no_effect.rs:172:5 | LL | [42; 55]; | ^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:155:5 + --> tests/ui/no_effect.rs:175:5 | LL | [42; 55][13]; | ^^^^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:158:5 + --> tests/ui/no_effect.rs:179:5 | LL | || x += 5; | ^^^^^^^^^^ error: statement with no effect - --> tests/ui/no_effect.rs:161:5 + --> tests/ui/no_effect.rs:183:5 | LL | FooString { s: s }; | ^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect.rs:163:9 + --> tests/ui/no_effect.rs:186:9 | LL | let _unused = 1; | ^^^^^^^ @@ -149,19 +149,19 @@ LL | let _unused = 1; = help: to override `-D warnings` add `#[allow(clippy::no_effect_underscore_binding)]` error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect.rs:166:9 + --> tests/ui/no_effect.rs:190:9 | LL | let _penguin = || println!("Some helpful closure"); | ^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect.rs:168:9 + --> tests/ui/no_effect.rs:193:9 | LL | let _duck = Struct { field: 0 }; | ^^^^^ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect.rs:170:9 + --> tests/ui/no_effect.rs:196:9 | LL | let _cat = [2, 4, 6, 8][2]; | ^^^^ diff --git a/tests/ui/no_effect_async_fn.rs b/tests/ui/no_effect_async_fn.rs index ef0f3d1df1ac..6fb3ccab8a08 100644 --- a/tests/ui/no_effect_async_fn.rs +++ b/tests/ui/no_effect_async_fn.rs @@ -11,14 +11,16 @@ impl AsyncTrait for Bar { // Shouldn't lint `binding to `_` prefixed variable with no side-effect` async fn bar(_i: u64) { let _a = 0; - //~^ ERROR: binding to `_` prefixed variable with no side-effect + //~^ no_effect_underscore_binding + // Shouldn't lint `binding to `_` prefixed variable with no side-effect` let _b = num(); let _ = async { let _c = 0; - //~^ ERROR: binding to `_` prefixed variable with no side-effect + //~^ no_effect_underscore_binding + // Shouldn't lint `binding to `_` prefixed variable with no side-effect` let _d = num(); @@ -30,14 +32,16 @@ impl AsyncTrait for Bar { // Shouldn't lint `binding to `_` prefixed variable with no side-effect` async fn foo(_i: u64) { let _a = 0; - //~^ ERROR: binding to `_` prefixed variable with no side-effect + //~^ no_effect_underscore_binding + // Shouldn't lint `binding to `_` prefixed variable with no side-effect` let _b = num(); let _ = async { let _c = 0; - //~^ ERROR: binding to `_` prefixed variable with no side-effect + //~^ no_effect_underscore_binding + // Shouldn't lint `binding to `_` prefixed variable with no side-effect` let _d = num(); diff --git a/tests/ui/no_effect_async_fn.stderr b/tests/ui/no_effect_async_fn.stderr index 2325eb9aae59..96ad7b9d6075 100644 --- a/tests/ui/no_effect_async_fn.stderr +++ b/tests/ui/no_effect_async_fn.stderr @@ -1,5 +1,5 @@ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect_async_fn.rs:20:17 + --> tests/ui/no_effect_async_fn.rs:21:17 | LL | let _c = 0; | ^^ @@ -14,13 +14,13 @@ LL | let _a = 0; | ^^ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect_async_fn.rs:39:13 + --> tests/ui/no_effect_async_fn.rs:42:13 | LL | let _c = 0; | ^^ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect_async_fn.rs:32:9 + --> tests/ui/no_effect_async_fn.rs:34:9 | LL | let _a = 0; | ^^ diff --git a/tests/ui/no_effect_replace.rs b/tests/ui/no_effect_replace.rs index e4fd5caae2a5..dc8e66f69ff5 100644 --- a/tests/ui/no_effect_replace.rs +++ b/tests/ui/no_effect_replace.rs @@ -2,30 +2,38 @@ fn main() { let _ = "12345".replace('1', "1"); - //~^ ERROR: replacing text with itself - //~| NOTE: `-D clippy::no-effect-replace` implied by `-D warnings` + //~^ no_effect_replace + + let _ = "12345".replace("12", "12"); - //~^ ERROR: replacing text with itself + //~^ no_effect_replace + let _ = String::new().replace("12", "12"); - //~^ ERROR: replacing text with itself + //~^ no_effect_replace + let _ = "12345".replacen('1', "1", 1); - //~^ ERROR: replacing text with itself + //~^ no_effect_replace + let _ = "12345".replacen("12", "12", 1); - //~^ ERROR: replacing text with itself + //~^ no_effect_replace + let _ = String::new().replacen("12", "12", 1); - //~^ ERROR: replacing text with itself + //~^ no_effect_replace + let _ = "12345".replace("12", "22"); let _ = "12345".replacen("12", "22", 1); let mut x = X::default(); let _ = "hello".replace(&x.f(), &x.f()); - //~^ ERROR: replacing text with itself + //~^ no_effect_replace + let _ = "hello".replace(&x.f(), &x.ff()); let _ = "hello".replace(&y(), &y()); - //~^ ERROR: replacing text with itself + //~^ no_effect_replace + let _ = "hello".replace(&y(), &z()); let _ = Replaceme.replace("a", "a"); diff --git a/tests/ui/no_effect_replace.stderr b/tests/ui/no_effect_replace.stderr index ded86c5c5b8d..3861d042e6f5 100644 --- a/tests/ui/no_effect_replace.stderr +++ b/tests/ui/no_effect_replace.stderr @@ -8,43 +8,43 @@ LL | let _ = "12345".replace('1', "1"); = help: to override `-D warnings` add `#[allow(clippy::no_effect_replace)]` error: replacing text with itself - --> tests/ui/no_effect_replace.rs:7:13 + --> tests/ui/no_effect_replace.rs:8:13 | LL | let _ = "12345".replace("12", "12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:9:13 + --> tests/ui/no_effect_replace.rs:11:13 | LL | let _ = String::new().replace("12", "12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:12:13 + --> tests/ui/no_effect_replace.rs:15:13 | LL | let _ = "12345".replacen('1', "1", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:14:13 + --> tests/ui/no_effect_replace.rs:18:13 | LL | let _ = "12345".replacen("12", "12", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:16:13 + --> tests/ui/no_effect_replace.rs:21:13 | LL | let _ = String::new().replacen("12", "12", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:23:13 + --> tests/ui/no_effect_replace.rs:29:13 | LL | let _ = "hello".replace(&x.f(), &x.f()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:27:13 + --> tests/ui/no_effect_replace.rs:34:13 | LL | let _ = "hello".replace(&y(), &y()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/no_effect_return.rs b/tests/ui/no_effect_return.rs index e46c0d73518b..8bfd8367f104 100644 --- a/tests/ui/no_effect_return.rs +++ b/tests/ui/no_effect_return.rs @@ -7,8 +7,9 @@ use std::ops::ControlFlow; fn a() -> u32 { { 0u32; - //~^ ERROR: statement with no effect - //~| NOTE: `-D clippy::no-effect` implied by `-D warnings` + //~^ no_effect + + } 0 } @@ -16,7 +17,8 @@ fn a() -> u32 { async fn b() -> u32 { { 0u32; - //~^ ERROR: statement with no effect + //~^ no_effect + } 0 } @@ -25,7 +27,8 @@ type C = i32; async fn c() -> C { { 0i32 as C; - //~^ ERROR: statement with no effect + //~^ no_effect + } 0 } @@ -34,7 +37,8 @@ fn d() -> u128 { { // not last stmt 0u128; - //~^ ERROR: statement with no effect + //~^ no_effect + println!("lol"); } 0 @@ -44,7 +48,8 @@ fn e() -> u32 { { // mismatched types 0u16; - //~^ ERROR: statement with no effect + //~^ no_effect + } 0 } @@ -52,7 +57,8 @@ fn e() -> u32 { fn f() -> [u16; 1] { { [1u16]; - //~^ ERROR: statement with no effect + //~^ no_effect + } [1] } @@ -60,7 +66,8 @@ fn f() -> [u16; 1] { fn g() -> ControlFlow<()> { { ControlFlow::Break::<()>(()); - //~^ ERROR: statement with no effect + //~^ no_effect + } ControlFlow::Continue(()) } @@ -78,7 +85,8 @@ fn i() -> () { { // does not suggest on function with explicit unit return type (); - //~^ ERROR: statement with no effect + //~^ no_effect + } () } @@ -87,7 +95,8 @@ fn j() { { // does not suggest on function without explicit return type (); - //~^ ERROR: statement with no effect + //~^ no_effect + } () } diff --git a/tests/ui/no_effect_return.stderr b/tests/ui/no_effect_return.stderr index 3cfe375d034a..f6ff2ded33e0 100644 --- a/tests/ui/no_effect_return.stderr +++ b/tests/ui/no_effect_return.stderr @@ -10,7 +10,7 @@ LL | 0u32; = help: to override `-D warnings` add `#[allow(clippy::no_effect)]` error: statement with no effect - --> tests/ui/no_effect_return.rs:18:9 + --> tests/ui/no_effect_return.rs:19:9 | LL | 0u32; | -^^^^ @@ -18,7 +18,7 @@ LL | 0u32; | help: did you mean to return it?: `return` error: statement with no effect - --> tests/ui/no_effect_return.rs:27:9 + --> tests/ui/no_effect_return.rs:29:9 | LL | 0i32 as C; | -^^^^^^^^^ @@ -26,19 +26,19 @@ LL | 0i32 as C; | help: did you mean to return it?: `return` error: statement with no effect - --> tests/ui/no_effect_return.rs:36:9 + --> tests/ui/no_effect_return.rs:39:9 | LL | 0u128; | ^^^^^^ error: statement with no effect - --> tests/ui/no_effect_return.rs:46:9 + --> tests/ui/no_effect_return.rs:50:9 | LL | 0u16; | ^^^^^ error: statement with no effect - --> tests/ui/no_effect_return.rs:54:9 + --> tests/ui/no_effect_return.rs:59:9 | LL | [1u16]; | -^^^^^^ @@ -46,7 +46,7 @@ LL | [1u16]; | help: did you mean to return it?: `return` error: statement with no effect - --> tests/ui/no_effect_return.rs:62:9 + --> tests/ui/no_effect_return.rs:68:9 | LL | ControlFlow::Break::<()>(()); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | ControlFlow::Break::<()>(()); | help: did you mean to return it?: `return` error: statement with no effect - --> tests/ui/no_effect_return.rs:80:9 + --> tests/ui/no_effect_return.rs:87:9 | LL | (); | ^^^ error: statement with no effect - --> tests/ui/no_effect_return.rs:89:9 + --> tests/ui/no_effect_return.rs:97:9 | LL | (); | ^^^ diff --git a/tests/ui/no_mangle_with_rust_abi.rs b/tests/ui/no_mangle_with_rust_abi.rs index 8be149d18637..99b731d4a597 100644 --- a/tests/ui/no_mangle_with_rust_abi.rs +++ b/tests/ui/no_mangle_with_rust_abi.rs @@ -4,28 +4,27 @@ #[unsafe(no_mangle)] fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} -//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI -//~| NOTE: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings` +//~^ no_mangle_with_rust_abi #[unsafe(no_mangle)] pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} -//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI +//~^ no_mangle_with_rust_abi /// # Safety /// This function shouldn't be called unless the horsemen are ready #[unsafe(no_mangle)] pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} -//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI +//~^ no_mangle_with_rust_abi /// # Safety /// This function shouldn't be called unless the horsemen are ready #[unsafe(no_mangle)] unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} -//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI +//~^ no_mangle_with_rust_abi #[unsafe(no_mangle)] fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( - //~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI +//~^ no_mangle_with_rust_abi arg_one: u32, arg_two: usize, ) -> u32 { @@ -51,6 +50,7 @@ extern "C" { mod r#fn { #[unsafe(no_mangle)] pub(in super::r#fn) fn with_some_fn_around() {} + //~^ no_mangle_with_rust_abi } fn main() { diff --git a/tests/ui/no_mangle_with_rust_abi.stderr b/tests/ui/no_mangle_with_rust_abi.stderr index a00ebe5e1ac7..871f38e94b63 100644 --- a/tests/ui/no_mangle_with_rust_abi.stderr +++ b/tests/ui/no_mangle_with_rust_abi.stderr @@ -16,7 +16,7 @@ LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} | +++++++++++++ error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI - --> tests/ui/no_mangle_with_rust_abi.rs:11:1 + --> tests/ui/no_mangle_with_rust_abi.rs:10:1 | LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} | +++++++++++++ error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI - --> tests/ui/no_mangle_with_rust_abi.rs:17:1 + --> tests/ui/no_mangle_with_rust_abi.rs:16:1 | LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) | +++++++++++++ error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI - --> tests/ui/no_mangle_with_rust_abi.rs:23:1 + --> tests/ui/no_mangle_with_rust_abi.rs:22:1 | LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} | +++++++++++++ error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI - --> tests/ui/no_mangle_with_rust_abi.rs:27:1 + --> tests/ui/no_mangle_with_rust_abi.rs:26:1 | LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( LL | | @@ -80,7 +80,7 @@ LL | extern "Rust" fn rust_abi_multiline_function_really_long_name_to_overflow_a | +++++++++++++ error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI - --> tests/ui/no_mangle_with_rust_abi.rs:53:5 + --> tests/ui/no_mangle_with_rust_abi.rs:52:5 | LL | pub(in super::r#fn) fn with_some_fn_around() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/no_mangle_with_rust_abi_2021.rs b/tests/ui/no_mangle_with_rust_abi_2021.rs index c7c973353480..eba653889064 100644 --- a/tests/ui/no_mangle_with_rust_abi_2021.rs +++ b/tests/ui/no_mangle_with_rust_abi_2021.rs @@ -8,28 +8,27 @@ #[no_mangle] fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} -//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI -//~| NOTE: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings` +//~^ no_mangle_with_rust_abi #[no_mangle] pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} -//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI +//~^ no_mangle_with_rust_abi /// # Safety /// This function shouldn't be called unless the horsemen are ready #[no_mangle] pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} -//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI +//~^ no_mangle_with_rust_abi /// # Safety /// This function shouldn't be called unless the horsemen are ready #[no_mangle] unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} -//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI +//~^ no_mangle_with_rust_abi #[no_mangle] fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( - //~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI +//~^ no_mangle_with_rust_abi arg_one: u32, arg_two: usize, ) -> u32 { diff --git a/tests/ui/no_mangle_with_rust_abi_2021.stderr b/tests/ui/no_mangle_with_rust_abi_2021.stderr index 15075be72d0b..abae8fafbeee 100644 --- a/tests/ui/no_mangle_with_rust_abi_2021.stderr +++ b/tests/ui/no_mangle_with_rust_abi_2021.stderr @@ -16,7 +16,7 @@ LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} | +++++++++++++ error: `#[no_mangle]` set on a function with the default (`Rust`) ABI - --> tests/ui/no_mangle_with_rust_abi_2021.rs:15:1 + --> tests/ui/no_mangle_with_rust_abi_2021.rs:14:1 | LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} | +++++++++++++ error: `#[no_mangle]` set on a function with the default (`Rust`) ABI - --> tests/ui/no_mangle_with_rust_abi_2021.rs:21:1 + --> tests/ui/no_mangle_with_rust_abi_2021.rs:20:1 | LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) | +++++++++++++ error: `#[no_mangle]` set on a function with the default (`Rust`) ABI - --> tests/ui/no_mangle_with_rust_abi_2021.rs:27:1 + --> tests/ui/no_mangle_with_rust_abi_2021.rs:26:1 | LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} | +++++++++++++ error: `#[no_mangle]` set on a function with the default (`Rust`) ABI - --> tests/ui/no_mangle_with_rust_abi_2021.rs:31:1 + --> tests/ui/no_mangle_with_rust_abi_2021.rs:30:1 | LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( LL | | diff --git a/tests/ui/non_canonical_clone_impl.rs b/tests/ui/non_canonical_clone_impl.rs index a36c7ed44c24..d735122e1845 100644 --- a/tests/ui/non_canonical_clone_impl.rs +++ b/tests/ui/non_canonical_clone_impl.rs @@ -12,10 +12,12 @@ struct A(u32); impl Clone for A { fn clone(&self) -> Self { + //~^ non_canonical_clone_impl Self(self.0) } fn clone_from(&mut self, source: &Self) { + //~^ non_canonical_clone_impl source.clone(); *self = source.clone(); } @@ -83,10 +85,12 @@ struct F(u32); impl Clone for F { fn clone(&self) -> Self { + //~^ non_canonical_clone_impl Self(self.0) } fn clone_from(&mut self, source: &Self) { + //~^ non_canonical_clone_impl source.clone(); *self = source.clone(); } diff --git a/tests/ui/non_canonical_clone_impl.stderr b/tests/ui/non_canonical_clone_impl.stderr index f7cad58150f7..550098452717 100644 --- a/tests/ui/non_canonical_clone_impl.stderr +++ b/tests/ui/non_canonical_clone_impl.stderr @@ -3,6 +3,7 @@ error: non-canonical implementation of `clone` on a `Copy` type | LL | fn clone(&self) -> Self { | _____________________________^ +LL | | LL | | Self(self.0) LL | | } | |_____^ help: change this to: `{ *self }` @@ -11,27 +12,30 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::non_canonical_clone_impl)]` error: unnecessary implementation of `clone_from` on a `Copy` type - --> tests/ui/non_canonical_clone_impl.rs:18:5 + --> tests/ui/non_canonical_clone_impl.rs:19:5 | LL | / fn clone_from(&mut self, source: &Self) { +LL | | LL | | source.clone(); LL | | *self = source.clone(); LL | | } | |_____^ help: remove it error: non-canonical implementation of `clone` on a `Copy` type - --> tests/ui/non_canonical_clone_impl.rs:85:29 + --> tests/ui/non_canonical_clone_impl.rs:87:29 | LL | fn clone(&self) -> Self { | _____________________________^ +LL | | LL | | Self(self.0) LL | | } | |_____^ help: change this to: `{ *self }` error: unnecessary implementation of `clone_from` on a `Copy` type - --> tests/ui/non_canonical_clone_impl.rs:89:5 + --> tests/ui/non_canonical_clone_impl.rs:92:5 | LL | / fn clone_from(&mut self, source: &Self) { +LL | | LL | | source.clone(); LL | | *self = source.clone(); LL | | } diff --git a/tests/ui/non_canonical_partial_ord_impl.fixed b/tests/ui/non_canonical_partial_ord_impl.fixed index d444a753697f..7d1211522f18 100644 --- a/tests/ui/non_canonical_partial_ord_impl.fixed +++ b/tests/ui/non_canonical_partial_ord_impl.fixed @@ -14,6 +14,7 @@ impl Ord for A { } impl PartialOrd for A { +//~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } @@ -46,6 +47,7 @@ impl Ord for C { } impl PartialOrd for C { +//~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } diff --git a/tests/ui/non_canonical_partial_ord_impl.rs b/tests/ui/non_canonical_partial_ord_impl.rs index dc6c4354604d..4f3310557992 100644 --- a/tests/ui/non_canonical_partial_ord_impl.rs +++ b/tests/ui/non_canonical_partial_ord_impl.rs @@ -14,6 +14,7 @@ impl Ord for A { } impl PartialOrd for A { +//~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { todo!(); } @@ -48,6 +49,7 @@ impl Ord for C { } impl PartialOrd for C { +//~^ non_canonical_partial_ord_impl fn partial_cmp(&self, _: &Self) -> Option { todo!(); } diff --git a/tests/ui/non_canonical_partial_ord_impl.stderr b/tests/ui/non_canonical_partial_ord_impl.stderr index a15379c5b1a5..12e6bdc7addc 100644 --- a/tests/ui/non_canonical_partial_ord_impl.stderr +++ b/tests/ui/non_canonical_partial_ord_impl.stderr @@ -2,6 +2,7 @@ error: non-canonical implementation of `partial_cmp` on an `Ord` type --> tests/ui/non_canonical_partial_ord_impl.rs:16:1 | LL | / impl PartialOrd for A { +LL | | LL | | fn partial_cmp(&self, other: &Self) -> Option { | | _____________________________________________________________- LL | || todo!(); @@ -14,9 +15,10 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::non_canonical_partial_ord_impl)]` error: non-canonical implementation of `partial_cmp` on an `Ord` type - --> tests/ui/non_canonical_partial_ord_impl.rs:50:1 + --> tests/ui/non_canonical_partial_ord_impl.rs:51:1 | LL | / impl PartialOrd for C { +LL | | LL | | fn partial_cmp(&self, _: &Self) -> Option { LL | | todo!(); LL | | } diff --git a/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs b/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs index 2f8d5cf30c77..cbd1ae57be4a 100644 --- a/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs +++ b/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs @@ -21,6 +21,7 @@ impl cmp::Ord for A { } impl PartialOrd for A { +//~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { // NOTE: This suggestion is wrong, as `Ord` is not in scope. But this should be fine as it isn't // automatically applied @@ -44,6 +45,7 @@ impl cmp::Ord for B { } impl PartialOrd for B { +//~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { // This calls `B.cmp`, not `Ord::cmp`! Some(self.cmp(other)) diff --git a/tests/ui/non_canonical_partial_ord_impl_fully_qual.stderr b/tests/ui/non_canonical_partial_ord_impl_fully_qual.stderr index 8dd7face6ef4..392b81dc8d74 100644 --- a/tests/ui/non_canonical_partial_ord_impl_fully_qual.stderr +++ b/tests/ui/non_canonical_partial_ord_impl_fully_qual.stderr @@ -2,6 +2,7 @@ error: non-canonical implementation of `partial_cmp` on an `Ord` type --> tests/ui/non_canonical_partial_ord_impl_fully_qual.rs:23:1 | LL | / impl PartialOrd for A { +LL | | LL | | fn partial_cmp(&self, other: &Self) -> Option { | | _____________________________________________________________- LL | || // NOTE: This suggestion is wrong, as `Ord` is not in scope. But this should be fine as it isn't @@ -16,9 +17,10 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::non_canonical_partial_ord_impl)]` error: non-canonical implementation of `partial_cmp` on an `Ord` type - --> tests/ui/non_canonical_partial_ord_impl_fully_qual.rs:46:1 + --> tests/ui/non_canonical_partial_ord_impl_fully_qual.rs:47:1 | LL | / impl PartialOrd for B { +LL | | LL | | fn partial_cmp(&self, other: &Self) -> Option { | | _____________________________________________________________- LL | || // This calls `B.cmp`, not `Ord::cmp`! diff --git a/tests/ui/non_expressive_names.rs b/tests/ui/non_expressive_names.rs index 987a4775ef07..69e90c3d670b 100644 --- a/tests/ui/non_expressive_names.rs +++ b/tests/ui/non_expressive_names.rs @@ -25,9 +25,12 @@ impl MaybeInst { } fn underscores_and_numbers() { - let _1 = 1; //~ERROR: consider choosing a more descriptive name - let ____1 = 1; //~ERROR: consider choosing a more descriptive name - let __1___2 = 12; //~ERROR: consider choosing a more descriptive name +let _1 = 1; +//~^ just_underscores_and_digits +let ____1 = 1; +//~^ just_underscores_and_digits +let __1___2 = 12; +//~^ just_underscores_and_digits let _1_ok = 1; } @@ -48,9 +51,12 @@ struct Bar; impl Bar { fn bar() { - let _1 = 1; //~ERROR: consider choosing a more descriptive name - let ____1 = 1; //~ERROR: consider choosing a more descriptive name - let __1___2 = 12; //~ERROR: consider choosing a more descriptive name +let _1 = 1; +//~^ just_underscores_and_digits +let ____1 = 1; +//~^ just_underscores_and_digits +let __1___2 = 12; +//~^ just_underscores_and_digits let _1_ok = 1; } } diff --git a/tests/ui/non_expressive_names.stderr b/tests/ui/non_expressive_names.stderr index d9c745f466b7..7aa67e1ca415 100644 --- a/tests/ui/non_expressive_names.stderr +++ b/tests/ui/non_expressive_names.stderr @@ -1,41 +1,41 @@ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:28:9 + --> tests/ui/non_expressive_names.rs:28:5 | -LL | let _1 = 1; - | ^^ +LL | let _1 = 1; + | ^^ | = note: `-D clippy::just-underscores-and-digits` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::just_underscores_and_digits)]` error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:29:9 + --> tests/ui/non_expressive_names.rs:30:5 | -LL | let ____1 = 1; - | ^^^^^ +LL | let ____1 = 1; + | ^^^^^ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:30:9 + --> tests/ui/non_expressive_names.rs:32:5 | -LL | let __1___2 = 12; - | ^^^^^^^ +LL | let __1___2 = 12; + | ^^^^^^^ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:51:13 + --> tests/ui/non_expressive_names.rs:54:5 | -LL | let _1 = 1; - | ^^ +LL | let _1 = 1; + | ^^ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:52:13 + --> tests/ui/non_expressive_names.rs:56:5 | -LL | let ____1 = 1; - | ^^^^^ +LL | let ____1 = 1; + | ^^^^^ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:53:13 + --> tests/ui/non_expressive_names.rs:58:5 | -LL | let __1___2 = 12; - | ^^^^^^^ +LL | let __1___2 = 12; + | ^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/non_minimal_cfg.fixed b/tests/ui/non_minimal_cfg.fixed index 2fcecab452b8..a2b69d0662ee 100644 --- a/tests/ui/non_minimal_cfg.fixed +++ b/tests/ui/non_minimal_cfg.fixed @@ -1,12 +1,16 @@ #![allow(unused)] #[cfg(windows)] +//~^ non_minimal_cfg fn hermit() {} #[cfg(windows)] +//~^ non_minimal_cfg fn wasi() {} #[cfg(all(unix, not(windows)))] +//~^ non_minimal_cfg +//~| non_minimal_cfg fn the_end() {} #[cfg(any())] diff --git a/tests/ui/non_minimal_cfg.rs b/tests/ui/non_minimal_cfg.rs index e3ce11b73336..7178cd189c08 100644 --- a/tests/ui/non_minimal_cfg.rs +++ b/tests/ui/non_minimal_cfg.rs @@ -1,12 +1,16 @@ #![allow(unused)] #[cfg(all(windows))] +//~^ non_minimal_cfg fn hermit() {} #[cfg(any(windows))] +//~^ non_minimal_cfg fn wasi() {} #[cfg(all(any(unix), all(not(windows))))] +//~^ non_minimal_cfg +//~| non_minimal_cfg fn the_end() {} #[cfg(any())] diff --git a/tests/ui/non_minimal_cfg.stderr b/tests/ui/non_minimal_cfg.stderr index 707ff51d430c..3bf306dd89c2 100644 --- a/tests/ui/non_minimal_cfg.stderr +++ b/tests/ui/non_minimal_cfg.stderr @@ -8,19 +8,19 @@ LL | #[cfg(all(windows))] = help: to override `-D warnings` add `#[allow(clippy::non_minimal_cfg)]` error: unneeded sub `cfg` when there is only one condition - --> tests/ui/non_minimal_cfg.rs:6:7 + --> tests/ui/non_minimal_cfg.rs:7:7 | LL | #[cfg(any(windows))] | ^^^^^^^^^^^^ help: try: `windows` error: unneeded sub `cfg` when there is only one condition - --> tests/ui/non_minimal_cfg.rs:9:11 + --> tests/ui/non_minimal_cfg.rs:11:11 | LL | #[cfg(all(any(unix), all(not(windows))))] | ^^^^^^^^^ help: try: `unix` error: unneeded sub `cfg` when there is only one condition - --> tests/ui/non_minimal_cfg.rs:9:22 + --> tests/ui/non_minimal_cfg.rs:11:22 | LL | #[cfg(all(any(unix), all(not(windows))))] | ^^^^^^^^^^^^^^^^^ help: try: `not(windows)` diff --git a/tests/ui/non_minimal_cfg2.rs b/tests/ui/non_minimal_cfg2.rs index f9e3ba4dacda..d073feedb1da 100644 --- a/tests/ui/non_minimal_cfg2.rs +++ b/tests/ui/non_minimal_cfg2.rs @@ -1,3 +1,4 @@ +//@require-annotations-for-level: WARN #![allow(unused)] #[cfg(all())] diff --git a/tests/ui/non_minimal_cfg2.stderr b/tests/ui/non_minimal_cfg2.stderr index 6d86e931edce..169d2989aa13 100644 --- a/tests/ui/non_minimal_cfg2.stderr +++ b/tests/ui/non_minimal_cfg2.stderr @@ -1,5 +1,5 @@ error: unneeded sub `cfg` when there is no condition - --> tests/ui/non_minimal_cfg2.rs:3:7 + --> tests/ui/non_minimal_cfg2.rs:4:7 | LL | #[cfg(all())] | ^^^^^ diff --git a/tests/ui/non_octal_unix_permissions.fixed b/tests/ui/non_octal_unix_permissions.fixed index f68d5e30d27e..83f8991c94f8 100644 --- a/tests/ui/non_octal_unix_permissions.fixed +++ b/tests/ui/non_octal_unix_permissions.fixed @@ -10,11 +10,13 @@ fn main() { // OpenOptionsExt::mode let mut options = OpenOptions::new(); options.mode(0o440); + //~^ non_octal_unix_permissions options.mode(0o400); options.mode(permissions); // PermissionsExt::from_mode let _permissions = Permissions::from_mode(0o647); + //~^ non_octal_unix_permissions let _permissions = Permissions::from_mode(0o000); let _permissions = Permissions::from_mode(permissions); @@ -24,6 +26,7 @@ fn main() { let mut permissions = metadata.permissions(); permissions.set_mode(0o644); + //~^ non_octal_unix_permissions permissions.set_mode(0o704); // no error permissions.set_mode(0b111_000_100); @@ -31,6 +34,7 @@ fn main() { // DirBuilderExt::mode let mut builder = DirBuilder::new(); builder.mode(0o755); + //~^ non_octal_unix_permissions builder.mode(0o406); // no error permissions.set_mode(0b111000100); diff --git a/tests/ui/non_octal_unix_permissions.rs b/tests/ui/non_octal_unix_permissions.rs index 647c3769d2c3..ba1ee10a2787 100644 --- a/tests/ui/non_octal_unix_permissions.rs +++ b/tests/ui/non_octal_unix_permissions.rs @@ -10,11 +10,13 @@ fn main() { // OpenOptionsExt::mode let mut options = OpenOptions::new(); options.mode(440); + //~^ non_octal_unix_permissions options.mode(0o400); options.mode(permissions); // PermissionsExt::from_mode let _permissions = Permissions::from_mode(647); + //~^ non_octal_unix_permissions let _permissions = Permissions::from_mode(0o000); let _permissions = Permissions::from_mode(permissions); @@ -24,6 +26,7 @@ fn main() { let mut permissions = metadata.permissions(); permissions.set_mode(644); + //~^ non_octal_unix_permissions permissions.set_mode(0o704); // no error permissions.set_mode(0b111_000_100); @@ -31,6 +34,7 @@ fn main() { // DirBuilderExt::mode let mut builder = DirBuilder::new(); builder.mode(755); + //~^ non_octal_unix_permissions builder.mode(0o406); // no error permissions.set_mode(0b111000100); diff --git a/tests/ui/non_octal_unix_permissions.stderr b/tests/ui/non_octal_unix_permissions.stderr index 890b308a1dc5..9027617c813a 100644 --- a/tests/ui/non_octal_unix_permissions.stderr +++ b/tests/ui/non_octal_unix_permissions.stderr @@ -8,19 +8,19 @@ LL | options.mode(440); = help: to override `-D warnings` add `#[allow(clippy::non_octal_unix_permissions)]` error: using a non-octal value to set unix file permissions - --> tests/ui/non_octal_unix_permissions.rs:17:47 + --> tests/ui/non_octal_unix_permissions.rs:18:47 | LL | let _permissions = Permissions::from_mode(647); | ^^^ help: consider using an octal literal instead: `0o647` error: using a non-octal value to set unix file permissions - --> tests/ui/non_octal_unix_permissions.rs:26:26 + --> tests/ui/non_octal_unix_permissions.rs:28:26 | LL | permissions.set_mode(644); | ^^^ help: consider using an octal literal instead: `0o644` error: using a non-octal value to set unix file permissions - --> tests/ui/non_octal_unix_permissions.rs:33:18 + --> tests/ui/non_octal_unix_permissions.rs:36:18 | LL | builder.mode(755); | ^^^ help: consider using an octal literal instead: `0o755` diff --git a/tests/ui/non_std_lazy_static/non_std_lazy_static_no_std.rs b/tests/ui/non_std_lazy_static/non_std_lazy_static_no_std.rs index 6208612c6983..1170696b2030 100644 --- a/tests/ui/non_std_lazy_static/non_std_lazy_static_no_std.rs +++ b/tests/ui/non_std_lazy_static/non_std_lazy_static_no_std.rs @@ -1,3 +1,4 @@ +//@ check-pass //@aux-build:once_cell.rs //@aux-build:lazy_static.rs diff --git a/tests/ui/non_std_lazy_static/non_std_lazy_static_other_once_cell.rs b/tests/ui/non_std_lazy_static/non_std_lazy_static_other_once_cell.rs index 8701a4b7729a..f6d4f7250915 100644 --- a/tests/ui/non_std_lazy_static/non_std_lazy_static_other_once_cell.rs +++ b/tests/ui/non_std_lazy_static/non_std_lazy_static_other_once_cell.rs @@ -1,3 +1,4 @@ +//@ check-pass //@aux-build:once_cell.rs #![warn(clippy::non_std_lazy_statics)] diff --git a/tests/ui/non_zero_suggestions.fixed b/tests/ui/non_zero_suggestions.fixed index e67c992fdde0..1459832be75e 100644 --- a/tests/ui/non_zero_suggestions.fixed +++ b/tests/ui/non_zero_suggestions.fixed @@ -7,19 +7,23 @@ fn main() { let x: u64 = 100; let y = NonZeroU32::new(10).unwrap(); let r1 = x / NonZeroU64::from(y); - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + let r2 = x % NonZeroU64::from(y); - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + // U16 -> U32 let a: u32 = 50; let b = NonZeroU16::new(5).unwrap(); let r3 = a / NonZeroU32::from(b); - //~^ ERROR: consider using `NonZeroU32::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + let x = NonZeroU64::from(NonZeroU32::new(5).unwrap()); - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + /// Negative test cases (lint should not trigger) // Left hand side expressions should not be triggered @@ -50,7 +54,8 @@ fn main() { // Additional function to test the lint in a different context fn divide_numbers(x: u64, y: NonZeroU32) -> u64 { x / NonZeroU64::from(y) - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + } struct Calculator { @@ -60,6 +65,7 @@ struct Calculator { impl Calculator { fn divide(&self, divisor: NonZeroU32) -> u64 { self.value / NonZeroU64::from(divisor) - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + } } diff --git a/tests/ui/non_zero_suggestions.rs b/tests/ui/non_zero_suggestions.rs index de82371a8f29..72a38131a132 100644 --- a/tests/ui/non_zero_suggestions.rs +++ b/tests/ui/non_zero_suggestions.rs @@ -7,19 +7,23 @@ fn main() { let x: u64 = 100; let y = NonZeroU32::new(10).unwrap(); let r1 = x / u64::from(y.get()); - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + let r2 = x % u64::from(y.get()); - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + // U16 -> U32 let a: u32 = 50; let b = NonZeroU16::new(5).unwrap(); let r3 = a / u32::from(b.get()); - //~^ ERROR: consider using `NonZeroU32::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + let x = u64::from(NonZeroU32::new(5).unwrap().get()); - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + /// Negative test cases (lint should not trigger) // Left hand side expressions should not be triggered @@ -50,7 +54,8 @@ fn main() { // Additional function to test the lint in a different context fn divide_numbers(x: u64, y: NonZeroU32) -> u64 { x / u64::from(y.get()) - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + } struct Calculator { @@ -60,6 +65,7 @@ struct Calculator { impl Calculator { fn divide(&self, divisor: NonZeroU32) -> u64 { self.value / u64::from(divisor.get()) - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + } } diff --git a/tests/ui/non_zero_suggestions.stderr b/tests/ui/non_zero_suggestions.stderr index 7a57f7983be7..f7ed71dcf56c 100644 --- a/tests/ui/non_zero_suggestions.stderr +++ b/tests/ui/non_zero_suggestions.stderr @@ -8,31 +8,31 @@ LL | let r1 = x / u64::from(y.get()); = help: to override `-D warnings` add `#[allow(clippy::non_zero_suggestions)]` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:12:18 + --> tests/ui/non_zero_suggestions.rs:13:18 | LL | let r2 = x % u64::from(y.get()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)` error: consider using `NonZeroU32::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:18:18 + --> tests/ui/non_zero_suggestions.rs:20:18 | LL | let r3 = a / u32::from(b.get()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU32::from(b)` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:21:13 + --> tests/ui/non_zero_suggestions.rs:24:13 | LL | let x = u64::from(NonZeroU32::new(5).unwrap().get()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(NonZeroU32::new(5).unwrap())` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:52:9 + --> tests/ui/non_zero_suggestions.rs:56:9 | LL | x / u64::from(y.get()) | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:62:22 + --> tests/ui/non_zero_suggestions.rs:67:22 | LL | self.value / u64::from(divisor.get()) | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(divisor)` diff --git a/tests/ui/non_zero_suggestions_unfixable.rs b/tests/ui/non_zero_suggestions_unfixable.rs index 193c710e589f..4adbdf7bcc74 100644 --- a/tests/ui/non_zero_suggestions_unfixable.rs +++ b/tests/ui/non_zero_suggestions_unfixable.rs @@ -4,11 +4,13 @@ use std::num::{NonZeroI8, NonZeroI16, NonZeroU8, NonZeroU16, NonZeroU32, NonZero fn main() { let x: u64 = u64::from(NonZeroU32::new(5).unwrap().get()); - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + let n = NonZeroU32::new(20).unwrap(); let y = u64::from(n.get()); - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + some_fn_that_only_takes_u64(y); let m = NonZeroU32::try_from(1).unwrap(); @@ -17,7 +19,8 @@ fn main() { fn return_non_zero(x: u64, y: NonZeroU32) -> u64 { u64::from(y.get()) - //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion + //~^ non_zero_suggestions + } fn some_fn_that_only_takes_u64(_: u64) {} diff --git a/tests/ui/non_zero_suggestions_unfixable.stderr b/tests/ui/non_zero_suggestions_unfixable.stderr index 787179f2a2d6..dff70dada26d 100644 --- a/tests/ui/non_zero_suggestions_unfixable.stderr +++ b/tests/ui/non_zero_suggestions_unfixable.stderr @@ -8,13 +8,13 @@ LL | let x: u64 = u64::from(NonZeroU32::new(5).unwrap().get()); = help: to override `-D warnings` add `#[allow(clippy::non_zero_suggestions)]` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions_unfixable.rs:10:13 + --> tests/ui/non_zero_suggestions_unfixable.rs:11:13 | LL | let y = u64::from(n.get()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(n)` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions_unfixable.rs:19:5 + --> tests/ui/non_zero_suggestions_unfixable.rs:21:5 | LL | u64::from(y.get()) | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)` diff --git a/tests/ui/nonminimal_bool.rs b/tests/ui/nonminimal_bool.rs index 9d0a475064ed..1d41b2b9a84c 100644 --- a/tests/ui/nonminimal_bool.rs +++ b/tests/ui/nonminimal_bool.rs @@ -15,23 +15,30 @@ fn main() { let d: bool = unimplemented!(); let e: bool = unimplemented!(); let _ = !true; - //~^ ERROR: this boolean expression can be simplified - //~| NOTE: `-D clippy::nonminimal-bool` implied by `-D warnings` + //~^ nonminimal_bool + + let _ = !false; - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + let _ = !!a; - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + let _ = false || a; - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + // don't lint on cfgs let _ = cfg!(you_shall_not_not_pass) && a; let _ = a || !b || !c || !d || !e; let _ = !(!a && b); - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + let _ = !(!a || b); - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + let _ = !a && !(b && c); - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + } fn equality_stuff() { @@ -40,15 +47,20 @@ fn equality_stuff() { let c: i32 = unimplemented!(); let d: i32 = unimplemented!(); let _ = a == b && c == 5 && a == b; - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + let _ = a == b || c == 5 || a == b; - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + let _ = a == b && c == 5 && b == a; - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + let _ = a != b || !(a != b || c == d); - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + let _ = a != b && !(a != b && c == d); - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + } fn issue3847(a: u32, b: u32) -> bool { @@ -79,7 +91,8 @@ fn check_expect() { fn issue9428() { if matches!(true, true) && true { - //~^ ERROR: this boolean expression can be simplified + //~^ nonminimal_bool + println!("foo"); } } @@ -158,19 +171,35 @@ fn issue11932() { fn issue_5794() { let a = 0; - if !(12 == a) {} //~ ERROR: this boolean expression can be simplified - if !(a == 12) {} //~ ERROR: this boolean expression can be simplified - if !(12 != a) {} //~ ERROR: this boolean expression can be simplified - if !(a != 12) {} //~ ERROR: this boolean expression can be simplified +if !(12 == a) {} +//~^ nonminimal_bool +if !(a == 12) {} +//~^ nonminimal_bool +if !(12 != a) {} +//~^ nonminimal_bool +if !(a != 12) {} +//~^ nonminimal_bool let b = true; let c = false; - if !b == true {} //~ ERROR: this boolean expression can be simplified - if !b != true {} //~ ERROR: this boolean expression can be simplified - if true == !b {} //~ ERROR: this boolean expression can be simplified - if true != !b {} //~ ERROR: this boolean expression can be simplified - if !b == !c {} //~ ERROR: this boolean expression can be simplified - if !b != !c {} //~ ERROR: this boolean expression can be simplified +if !b == true {} +//~^ nonminimal_bool +//~| bool_comparison +//~| bool_comparison +if !b != true {} +//~^ nonminimal_bool +//~| bool_comparison +if true == !b {} +//~^ nonminimal_bool +//~| bool_comparison +//~| bool_comparison +if true != !b {} +//~^ nonminimal_bool +//~| bool_comparison +if !b == !c {} +//~^ nonminimal_bool +if !b != !c {} +//~^ nonminimal_bool } fn issue_12371(x: usize) -> bool { @@ -186,6 +215,7 @@ fn many_ops(a: bool, b: bool, c: bool, d: bool, e: bool, f: bool) -> bool { fn issue14184(a: f32, b: bool) { if !(a < 2.0 && !b) { + //~^ nonminimal_bool println!("Hi"); } } diff --git a/tests/ui/nonminimal_bool.stderr b/tests/ui/nonminimal_bool.stderr index 129dadf315e4..ca2c7ab8232a 100644 --- a/tests/ui/nonminimal_bool.stderr +++ b/tests/ui/nonminimal_bool.stderr @@ -8,43 +8,43 @@ LL | let _ = !true; = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:20:13 + --> tests/ui/nonminimal_bool.rs:21:13 | LL | let _ = !false; | ^^^^^^ help: try: `true` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:22:13 + --> tests/ui/nonminimal_bool.rs:24:13 | LL | let _ = !!a; | ^^^ help: try: `a` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:24:13 + --> tests/ui/nonminimal_bool.rs:27:13 | LL | let _ = false || a; | ^^^^^^^^^^ help: try: `a` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:29:13 + --> tests/ui/nonminimal_bool.rs:33:13 | LL | let _ = !(!a && b); | ^^^^^^^^^^ help: try: `a || !b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:31:13 + --> tests/ui/nonminimal_bool.rs:36:13 | LL | let _ = !(!a || b); | ^^^^^^^^^^ help: try: `a && !b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:33:13 + --> tests/ui/nonminimal_bool.rs:39:13 | LL | let _ = !a && !(b && c); | ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:42:13 + --> tests/ui/nonminimal_bool.rs:49:13 | LL | let _ = a == b && c == 5 && a == b; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = a == b && c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:44:13 + --> tests/ui/nonminimal_bool.rs:52:13 | LL | let _ = a == b || c == 5 || a == b; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | let _ = a == b || c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:46:13 + --> tests/ui/nonminimal_bool.rs:55:13 | LL | let _ = a == b && c == 5 && b == a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | let _ = a == b && c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:48:13 + --> tests/ui/nonminimal_bool.rs:58:13 | LL | let _ = a != b || !(a != b || c == d); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL | let _ = a != b || c != d; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:50:13 + --> tests/ui/nonminimal_bool.rs:61:13 | LL | let _ = a != b && !(a != b && c == d); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,112 +109,112 @@ LL | let _ = a != b && c != d; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:81:8 + --> tests/ui/nonminimal_bool.rs:93:8 | LL | if matches!(true, true) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(true, true)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:161:8 + --> tests/ui/nonminimal_bool.rs:174:4 | -LL | if !(12 == a) {} - | ^^^^^^^^^^ help: try: `(12 != a)` +LL | if !(12 == a) {} + | ^^^^^^^^^^ help: try: `(12 != a)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:162:8 + --> tests/ui/nonminimal_bool.rs:176:4 | -LL | if !(a == 12) {} - | ^^^^^^^^^^ help: try: `(a != 12)` +LL | if !(a == 12) {} + | ^^^^^^^^^^ help: try: `(a != 12)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:163:8 + --> tests/ui/nonminimal_bool.rs:178:4 | -LL | if !(12 != a) {} - | ^^^^^^^^^^ help: try: `(12 == a)` +LL | if !(12 != a) {} + | ^^^^^^^^^^ help: try: `(12 == a)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:164:8 + --> tests/ui/nonminimal_bool.rs:180:4 | -LL | if !(a != 12) {} - | ^^^^^^^^^^ help: try: `(a == 12)` +LL | if !(a != 12) {} + | ^^^^^^^^^^ help: try: `(a == 12)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:168:8 + --> tests/ui/nonminimal_bool.rs:185:4 | -LL | if !b == true {} - | ^^^^^^^^^^ help: try: `b != true` +LL | if !b == true {} + | ^^^^^^^^^^ help: try: `b != true` error: this comparison might be written more concisely - --> tests/ui/nonminimal_bool.rs:168:8 + --> tests/ui/nonminimal_bool.rs:185:4 | -LL | if !b == true {} - | ^^^^^^^^^^ help: try simplifying it as shown: `b != true` +LL | if !b == true {} + | ^^^^^^^^^^ help: try simplifying it as shown: `b != true` | = note: `-D clippy::bool-comparison` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]` error: equality checks against true are unnecessary - --> tests/ui/nonminimal_bool.rs:168:8 + --> tests/ui/nonminimal_bool.rs:185:4 | -LL | if !b == true {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!b` +LL | if !b == true {} + | ^^^^^^^^^^ help: try simplifying it as shown: `!b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:169:8 + --> tests/ui/nonminimal_bool.rs:189:4 | -LL | if !b != true {} - | ^^^^^^^^^^ help: try: `b == true` +LL | if !b != true {} + | ^^^^^^^^^^ help: try: `b == true` error: inequality checks against true can be replaced by a negation - --> tests/ui/nonminimal_bool.rs:169:8 + --> tests/ui/nonminimal_bool.rs:189:4 | -LL | if !b != true {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` +LL | if !b != true {} + | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:170:8 + --> tests/ui/nonminimal_bool.rs:192:4 | -LL | if true == !b {} - | ^^^^^^^^^^ help: try: `true != b` +LL | if true == !b {} + | ^^^^^^^^^^ help: try: `true != b` error: this comparison might be written more concisely - --> tests/ui/nonminimal_bool.rs:170:8 + --> tests/ui/nonminimal_bool.rs:192:4 | -LL | if true == !b {} - | ^^^^^^^^^^ help: try simplifying it as shown: `true != b` +LL | if true == !b {} + | ^^^^^^^^^^ help: try simplifying it as shown: `true != b` error: equality checks against true are unnecessary - --> tests/ui/nonminimal_bool.rs:170:8 + --> tests/ui/nonminimal_bool.rs:192:4 | -LL | if true == !b {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!b` +LL | if true == !b {} + | ^^^^^^^^^^ help: try simplifying it as shown: `!b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:171:8 + --> tests/ui/nonminimal_bool.rs:196:4 | -LL | if true != !b {} - | ^^^^^^^^^^ help: try: `true == b` +LL | if true != !b {} + | ^^^^^^^^^^ help: try: `true == b` error: inequality checks against true can be replaced by a negation - --> tests/ui/nonminimal_bool.rs:171:8 + --> tests/ui/nonminimal_bool.rs:196:4 | -LL | if true != !b {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` +LL | if true != !b {} + | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:172:8 + --> tests/ui/nonminimal_bool.rs:199:4 | -LL | if !b == !c {} - | ^^^^^^^^ help: try: `b == c` +LL | if !b == !c {} + | ^^^^^^^^ help: try: `b == c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:173:8 + --> tests/ui/nonminimal_bool.rs:201:4 | -LL | if !b != !c {} - | ^^^^^^^^ help: try: `b != c` +LL | if !b != !c {} + | ^^^^^^^^ help: try: `b != c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:188:8 + --> tests/ui/nonminimal_bool.rs:217:8 | LL | if !(a < 2.0 && !b) { | ^^^^^^^^^^^^^^^^ help: try: `!(a < 2.0) || b` diff --git a/tests/ui/nonminimal_bool_methods.fixed b/tests/ui/nonminimal_bool_methods.fixed index 65ccaaca8918..4b11dc2b5dda 100644 --- a/tests/ui/nonminimal_bool_methods.fixed +++ b/tests/ui/nonminimal_bool_methods.fixed @@ -6,18 +6,27 @@ fn methods_with_negation() { let b: Result = unimplemented!(); let _ = a.is_some(); let _ = a.is_none(); + //~^ nonminimal_bool let _ = a.is_none(); let _ = a.is_some(); + //~^ nonminimal_bool let _ = b.is_err(); let _ = b.is_ok(); + //~^ nonminimal_bool let _ = b.is_ok(); let _ = b.is_err(); + //~^ nonminimal_bool let c = false; let _ = a.is_none() || c; + //~^ nonminimal_bool let _ = a.is_none() && c; + //~^ nonminimal_bool let _ = !(!c ^ c) || a.is_none(); + //~^ nonminimal_bool let _ = (!c ^ c) || a.is_none(); + //~^ nonminimal_bool let _ = !c ^ c || a.is_none(); + //~^ nonminimal_bool } // Simplified versions of https://github.com/rust-lang/rust-clippy/issues/2638 @@ -90,11 +99,15 @@ fn dont_warn_for_custom_methods_with_negation() { fn warn_for_built_in_methods_with_negation() { let res: Result = Ok(1); if res.is_err() {} + //~^ nonminimal_bool if res.is_ok() {} + //~^ nonminimal_bool let res = Some(1); if res.is_none() {} + //~^ nonminimal_bool if res.is_some() {} + //~^ nonminimal_bool } #[allow(clippy::neg_cmp_op_on_partial_ord)] @@ -110,24 +123,34 @@ fn dont_warn_for_negated_partial_ord_comparison() { fn issue_12625() { let a = 0; let b = 0; - if ((a as u64) < b) {} //~ ERROR: this boolean expression can be simplified - if ((a as u64) < b) {} //~ ERROR: this boolean expression can be simplified - if (a as u64 > b) {} //~ ERROR: this boolean expression can be simplified +if ((a as u64) < b) {} +//~^ nonminimal_bool +if ((a as u64) < b) {} +//~^ nonminimal_bool +if (a as u64 > b) {} +//~^ nonminimal_bool } fn issue_12761() { let a = 0; let b = 0; let c = 0; - if (a < b) as i32 == c {} //~ ERROR: this boolean expression can be simplified - if (a < b) | (a > c) {} //~ ERROR: this boolean expression can be simplified +if (a < b) as i32 == c {} +//~^ nonminimal_bool +if (a < b) | (a > c) {} +//~^ nonminimal_bool +//~| nonminimal_bool let opt: Option = Some(1); let res: Result = Ok(1); - if res.is_err() as i32 == c {} //~ ERROR: this boolean expression can be simplified - if res.is_err() | opt.is_some() {} //~ ERROR: this boolean expression can be simplified +if res.is_err() as i32 == c {} +//~^ nonminimal_bool +if res.is_err() | opt.is_some() {} +//~^ nonminimal_bool +//~| nonminimal_bool fn a(a: bool) -> bool { - (4 <= 3).b() //~ ERROR: this boolean expression can be simplified +(4 <= 3).b() +//~^ nonminimal_bool } trait B { @@ -152,12 +175,18 @@ fn issue_13436() { _ = opt.is_some_and(|x| x == 1000); _ = opt.is_some_and(|x| x != 1000); _ = opt.is_some_and(not_zero); - _ = opt.is_none_or(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_none_or(|x| x > 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_none_or(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_none_or(|x| x < 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_none_or(|x| x != 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_none_or(|x| x == 1000); //~ ERROR: this boolean expression can be simplified +_ = opt.is_none_or(|x| x >= 1000); +//~^ nonminimal_bool +_ = opt.is_none_or(|x| x > 1000); +//~^ nonminimal_bool +_ = opt.is_none_or(|x| x <= 1000); +//~^ nonminimal_bool +_ = opt.is_none_or(|x| x < 1000); +//~^ nonminimal_bool +_ = opt.is_none_or(|x| x != 1000); +//~^ nonminimal_bool +_ = opt.is_none_or(|x| x == 1000); +//~^ nonminimal_bool _ = !opt.is_some_and(not_zero); _ = opt.is_none_or(|x| x < 1000); _ = opt.is_none_or(|x| x <= 1000); @@ -166,33 +195,45 @@ fn issue_13436() { _ = opt.is_none_or(|x| x == 1000); _ = opt.is_none_or(|x| x != 1000); _ = opt.is_none_or(not_zero); - _ = opt.is_some_and(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_some_and(|x| x > 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_some_and(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_some_and(|x| x < 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_some_and(|x| x != 1000); //~ ERROR: this boolean expression can be simplified - _ = opt.is_some_and(|x| x == 1000); //~ ERROR: this boolean expression can be simplified +_ = opt.is_some_and(|x| x >= 1000); +//~^ nonminimal_bool +_ = opt.is_some_and(|x| x > 1000); +//~^ nonminimal_bool +_ = opt.is_some_and(|x| x <= 1000); +//~^ nonminimal_bool +_ = opt.is_some_and(|x| x < 1000); +//~^ nonminimal_bool +_ = opt.is_some_and(|x| x != 1000); +//~^ nonminimal_bool +_ = opt.is_some_and(|x| x == 1000); +//~^ nonminimal_bool _ = !opt.is_none_or(not_zero); let opt = Some(true); _ = opt.is_some_and(|x| x); _ = opt.is_some_and(|x| !x); _ = !opt.is_some_and(|x| x); - _ = opt.is_none_or(|x| x); //~ ERROR: this boolean expression can be simplified +_ = opt.is_none_or(|x| x); +//~^ nonminimal_bool _ = opt.is_none_or(|x| x); _ = opt.is_none_or(|x| !x); _ = !opt.is_none_or(|x| x); - _ = opt.is_some_and(|x| x); //~ ERROR: this boolean expression can be simplified +_ = opt.is_some_and(|x| x); +//~^ nonminimal_bool let opt: Option> = Some(Ok(123)); _ = opt.is_some_and(|x| x.is_ok()); _ = opt.is_some_and(|x| x.is_err()); _ = opt.is_none_or(|x| x.is_ok()); _ = opt.is_none_or(|x| x.is_err()); - _ = opt.is_none_or(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified - _ = opt.is_none_or(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified - _ = opt.is_some_and(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified - _ = opt.is_some_and(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified +_ = opt.is_none_or(|x| x.is_err()); +//~^ nonminimal_bool +_ = opt.is_none_or(|x| x.is_ok()); +//~^ nonminimal_bool +_ = opt.is_some_and(|x| x.is_err()); +//~^ nonminimal_bool +_ = opt.is_some_and(|x| x.is_ok()); +//~^ nonminimal_bool #[clippy::msrv = "1.81"] fn before_stabilization() { diff --git a/tests/ui/nonminimal_bool_methods.rs b/tests/ui/nonminimal_bool_methods.rs index 06db3a1d4a5c..3e574de2d156 100644 --- a/tests/ui/nonminimal_bool_methods.rs +++ b/tests/ui/nonminimal_bool_methods.rs @@ -6,18 +6,27 @@ fn methods_with_negation() { let b: Result = unimplemented!(); let _ = a.is_some(); let _ = !a.is_some(); + //~^ nonminimal_bool let _ = a.is_none(); let _ = !a.is_none(); + //~^ nonminimal_bool let _ = b.is_err(); let _ = !b.is_err(); + //~^ nonminimal_bool let _ = b.is_ok(); let _ = !b.is_ok(); + //~^ nonminimal_bool let c = false; let _ = !(a.is_some() && !c); + //~^ nonminimal_bool let _ = !(a.is_some() || !c); + //~^ nonminimal_bool let _ = !(!c ^ c) || !a.is_some(); + //~^ nonminimal_bool let _ = (!c ^ c) || !a.is_some(); + //~^ nonminimal_bool let _ = !c ^ c || !a.is_some(); + //~^ nonminimal_bool } // Simplified versions of https://github.com/rust-lang/rust-clippy/issues/2638 @@ -90,11 +99,15 @@ fn dont_warn_for_custom_methods_with_negation() { fn warn_for_built_in_methods_with_negation() { let res: Result = Ok(1); if !res.is_ok() {} + //~^ nonminimal_bool if !res.is_err() {} + //~^ nonminimal_bool let res = Some(1); if !res.is_some() {} + //~^ nonminimal_bool if !res.is_none() {} + //~^ nonminimal_bool } #[allow(clippy::neg_cmp_op_on_partial_ord)] @@ -110,24 +123,34 @@ fn dont_warn_for_negated_partial_ord_comparison() { fn issue_12625() { let a = 0; let b = 0; - if !(a as u64 >= b) {} //~ ERROR: this boolean expression can be simplified - if !((a as u64) >= b) {} //~ ERROR: this boolean expression can be simplified - if !(a as u64 <= b) {} //~ ERROR: this boolean expression can be simplified +if !(a as u64 >= b) {} +//~^ nonminimal_bool +if !((a as u64) >= b) {} +//~^ nonminimal_bool +if !(a as u64 <= b) {} +//~^ nonminimal_bool } fn issue_12761() { let a = 0; let b = 0; let c = 0; - if !(a >= b) as i32 == c {} //~ ERROR: this boolean expression can be simplified - if !(a >= b) | !(a <= c) {} //~ ERROR: this boolean expression can be simplified +if !(a >= b) as i32 == c {} +//~^ nonminimal_bool +if !(a >= b) | !(a <= c) {} +//~^ nonminimal_bool +//~| nonminimal_bool let opt: Option = Some(1); let res: Result = Ok(1); - if !res.is_ok() as i32 == c {} //~ ERROR: this boolean expression can be simplified - if !res.is_ok() | !opt.is_none() {} //~ ERROR: this boolean expression can be simplified +if !res.is_ok() as i32 == c {} +//~^ nonminimal_bool +if !res.is_ok() | !opt.is_none() {} +//~^ nonminimal_bool +//~| nonminimal_bool fn a(a: bool) -> bool { - (!(4 > 3)).b() //~ ERROR: this boolean expression can be simplified +(!(4 > 3)).b() +//~^ nonminimal_bool } trait B { @@ -152,12 +175,18 @@ fn issue_13436() { _ = opt.is_some_and(|x| x == 1000); _ = opt.is_some_and(|x| x != 1000); _ = opt.is_some_and(not_zero); - _ = !opt.is_some_and(|x| x < 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_some_and(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_some_and(|x| x > 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_some_and(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_some_and(|x| x == 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_some_and(|x| x != 1000); //~ ERROR: this boolean expression can be simplified +_ = !opt.is_some_and(|x| x < 1000); +//~^ nonminimal_bool +_ = !opt.is_some_and(|x| x <= 1000); +//~^ nonminimal_bool +_ = !opt.is_some_and(|x| x > 1000); +//~^ nonminimal_bool +_ = !opt.is_some_and(|x| x >= 1000); +//~^ nonminimal_bool +_ = !opt.is_some_and(|x| x == 1000); +//~^ nonminimal_bool +_ = !opt.is_some_and(|x| x != 1000); +//~^ nonminimal_bool _ = !opt.is_some_and(not_zero); _ = opt.is_none_or(|x| x < 1000); _ = opt.is_none_or(|x| x <= 1000); @@ -166,33 +195,45 @@ fn issue_13436() { _ = opt.is_none_or(|x| x == 1000); _ = opt.is_none_or(|x| x != 1000); _ = opt.is_none_or(not_zero); - _ = !opt.is_none_or(|x| x < 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_none_or(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_none_or(|x| x > 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_none_or(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_none_or(|x| x == 1000); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_none_or(|x| x != 1000); //~ ERROR: this boolean expression can be simplified +_ = !opt.is_none_or(|x| x < 1000); +//~^ nonminimal_bool +_ = !opt.is_none_or(|x| x <= 1000); +//~^ nonminimal_bool +_ = !opt.is_none_or(|x| x > 1000); +//~^ nonminimal_bool +_ = !opt.is_none_or(|x| x >= 1000); +//~^ nonminimal_bool +_ = !opt.is_none_or(|x| x == 1000); +//~^ nonminimal_bool +_ = !opt.is_none_or(|x| x != 1000); +//~^ nonminimal_bool _ = !opt.is_none_or(not_zero); let opt = Some(true); _ = opt.is_some_and(|x| x); _ = opt.is_some_and(|x| !x); _ = !opt.is_some_and(|x| x); - _ = !opt.is_some_and(|x| !x); //~ ERROR: this boolean expression can be simplified +_ = !opt.is_some_and(|x| !x); +//~^ nonminimal_bool _ = opt.is_none_or(|x| x); _ = opt.is_none_or(|x| !x); _ = !opt.is_none_or(|x| x); - _ = !opt.is_none_or(|x| !x); //~ ERROR: this boolean expression can be simplified +_ = !opt.is_none_or(|x| !x); +//~^ nonminimal_bool let opt: Option> = Some(Ok(123)); _ = opt.is_some_and(|x| x.is_ok()); _ = opt.is_some_and(|x| x.is_err()); _ = opt.is_none_or(|x| x.is_ok()); _ = opt.is_none_or(|x| x.is_err()); - _ = !opt.is_some_and(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_some_and(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_none_or(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified - _ = !opt.is_none_or(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified +_ = !opt.is_some_and(|x| x.is_ok()); +//~^ nonminimal_bool +_ = !opt.is_some_and(|x| x.is_err()); +//~^ nonminimal_bool +_ = !opt.is_none_or(|x| x.is_ok()); +//~^ nonminimal_bool +_ = !opt.is_none_or(|x| x.is_err()); +//~^ nonminimal_bool #[clippy::msrv = "1.81"] fn before_stabilization() { diff --git a/tests/ui/nonminimal_bool_methods.stderr b/tests/ui/nonminimal_bool_methods.stderr index 66c50f9ff1e1..3f03b8613596 100644 --- a/tests/ui/nonminimal_bool_methods.stderr +++ b/tests/ui/nonminimal_bool_methods.stderr @@ -8,244 +8,244 @@ LL | let _ = !a.is_some(); = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:10:13 + --> tests/ui/nonminimal_bool_methods.rs:11:13 | LL | let _ = !a.is_none(); | ^^^^^^^^^^^^ help: try: `a.is_some()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:12:13 + --> tests/ui/nonminimal_bool_methods.rs:14:13 | LL | let _ = !b.is_err(); | ^^^^^^^^^^^ help: try: `b.is_ok()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:14:13 + --> tests/ui/nonminimal_bool_methods.rs:17:13 | LL | let _ = !b.is_ok(); | ^^^^^^^^^^ help: try: `b.is_err()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:16:13 + --> tests/ui/nonminimal_bool_methods.rs:20:13 | LL | let _ = !(a.is_some() && !c); | ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() || c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:17:13 + --> tests/ui/nonminimal_bool_methods.rs:22:13 | LL | let _ = !(a.is_some() || !c); | ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() && c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:18:26 + --> tests/ui/nonminimal_bool_methods.rs:24:26 | LL | let _ = !(!c ^ c) || !a.is_some(); | ^^^^^^^^^^^^ help: try: `a.is_none()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:19:25 + --> tests/ui/nonminimal_bool_methods.rs:26:25 | LL | let _ = (!c ^ c) || !a.is_some(); | ^^^^^^^^^^^^ help: try: `a.is_none()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:20:23 + --> tests/ui/nonminimal_bool_methods.rs:28:23 | LL | let _ = !c ^ c || !a.is_some(); | ^^^^^^^^^^^^ help: try: `a.is_none()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:92:8 + --> tests/ui/nonminimal_bool_methods.rs:101:8 | LL | if !res.is_ok() {} | ^^^^^^^^^^^^ help: try: `res.is_err()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:93:8 + --> tests/ui/nonminimal_bool_methods.rs:103:8 | LL | if !res.is_err() {} | ^^^^^^^^^^^^^ help: try: `res.is_ok()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:96:8 + --> tests/ui/nonminimal_bool_methods.rs:107:8 | LL | if !res.is_some() {} | ^^^^^^^^^^^^^^ help: try: `res.is_none()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:97:8 + --> tests/ui/nonminimal_bool_methods.rs:109:8 | LL | if !res.is_none() {} | ^^^^^^^^^^^^^^ help: try: `res.is_some()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:113:8 + --> tests/ui/nonminimal_bool_methods.rs:126:4 | -LL | if !(a as u64 >= b) {} - | ^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)` +LL | if !(a as u64 >= b) {} + | ^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:114:8 + --> tests/ui/nonminimal_bool_methods.rs:128:4 | -LL | if !((a as u64) >= b) {} - | ^^^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)` +LL | if !((a as u64) >= b) {} + | ^^^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:115:8 + --> tests/ui/nonminimal_bool_methods.rs:130:4 | -LL | if !(a as u64 <= b) {} - | ^^^^^^^^^^^^^^^^ help: try: `(a as u64 > b)` +LL | if !(a as u64 <= b) {} + | ^^^^^^^^^^^^^^^^ help: try: `(a as u64 > b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:122:8 + --> tests/ui/nonminimal_bool_methods.rs:138:4 | -LL | if !(a >= b) as i32 == c {} - | ^^^^^^^^^ help: try: `(a < b)` +LL | if !(a >= b) as i32 == c {} + | ^^^^^^^^^ help: try: `(a < b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:123:8 + --> tests/ui/nonminimal_bool_methods.rs:140:4 | -LL | if !(a >= b) | !(a <= c) {} - | ^^^^^^^^^ help: try: `(a < b)` +LL | if !(a >= b) | !(a <= c) {} + | ^^^^^^^^^ help: try: `(a < b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:123:20 + --> tests/ui/nonminimal_bool_methods.rs:140:16 | -LL | if !(a >= b) | !(a <= c) {} - | ^^^^^^^^^ help: try: `(a > c)` +LL | if !(a >= b) | !(a <= c) {} + | ^^^^^^^^^ help: try: `(a > c)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:126:8 + --> tests/ui/nonminimal_bool_methods.rs:145:4 | -LL | if !res.is_ok() as i32 == c {} - | ^^^^^^^^^^^^ help: try: `res.is_err()` +LL | if !res.is_ok() as i32 == c {} + | ^^^^^^^^^^^^ help: try: `res.is_err()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:127:8 + --> tests/ui/nonminimal_bool_methods.rs:147:4 | -LL | if !res.is_ok() | !opt.is_none() {} - | ^^^^^^^^^^^^ help: try: `res.is_err()` +LL | if !res.is_ok() | !opt.is_none() {} + | ^^^^^^^^^^^^ help: try: `res.is_err()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:127:23 + --> tests/ui/nonminimal_bool_methods.rs:147:19 | -LL | if !res.is_ok() | !opt.is_none() {} - | ^^^^^^^^^^^^^^ help: try: `opt.is_some()` +LL | if !res.is_ok() | !opt.is_none() {} + | ^^^^^^^^^^^^^^ help: try: `opt.is_some()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:130:9 + --> tests/ui/nonminimal_bool_methods.rs:152:1 | -LL | (!(4 > 3)).b() - | ^^^^^^^^^^ help: try: `(4 <= 3)` +LL | (!(4 > 3)).b() + | ^^^^^^^^^^ help: try: `(4 <= 3)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:155:9 + --> tests/ui/nonminimal_bool_methods.rs:178:5 | -LL | _ = !opt.is_some_and(|x| x < 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x >= 1000)` +LL | _ = !opt.is_some_and(|x| x < 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x >= 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:156:9 + --> tests/ui/nonminimal_bool_methods.rs:180:5 | -LL | _ = !opt.is_some_and(|x| x <= 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x > 1000)` +LL | _ = !opt.is_some_and(|x| x <= 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x > 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:157:9 + --> tests/ui/nonminimal_bool_methods.rs:182:5 | -LL | _ = !opt.is_some_and(|x| x > 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x <= 1000)` +LL | _ = !opt.is_some_and(|x| x > 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x <= 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:158:9 + --> tests/ui/nonminimal_bool_methods.rs:184:5 | -LL | _ = !opt.is_some_and(|x| x >= 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x < 1000)` +LL | _ = !opt.is_some_and(|x| x >= 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x < 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:159:9 + --> tests/ui/nonminimal_bool_methods.rs:186:5 | -LL | _ = !opt.is_some_and(|x| x == 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x != 1000)` +LL | _ = !opt.is_some_and(|x| x == 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x != 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:160:9 + --> tests/ui/nonminimal_bool_methods.rs:188:5 | -LL | _ = !opt.is_some_and(|x| x != 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x == 1000)` +LL | _ = !opt.is_some_and(|x| x != 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x == 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:169:9 + --> tests/ui/nonminimal_bool_methods.rs:198:5 | -LL | _ = !opt.is_none_or(|x| x < 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x >= 1000)` +LL | _ = !opt.is_none_or(|x| x < 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x >= 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:170:9 + --> tests/ui/nonminimal_bool_methods.rs:200:5 | -LL | _ = !opt.is_none_or(|x| x <= 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x > 1000)` +LL | _ = !opt.is_none_or(|x| x <= 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x > 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:171:9 + --> tests/ui/nonminimal_bool_methods.rs:202:5 | -LL | _ = !opt.is_none_or(|x| x > 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x <= 1000)` +LL | _ = !opt.is_none_or(|x| x > 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x <= 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:172:9 + --> tests/ui/nonminimal_bool_methods.rs:204:5 | -LL | _ = !opt.is_none_or(|x| x >= 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x < 1000)` +LL | _ = !opt.is_none_or(|x| x >= 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x < 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:173:9 + --> tests/ui/nonminimal_bool_methods.rs:206:5 | -LL | _ = !opt.is_none_or(|x| x == 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x != 1000)` +LL | _ = !opt.is_none_or(|x| x == 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x != 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:174:9 + --> tests/ui/nonminimal_bool_methods.rs:208:5 | -LL | _ = !opt.is_none_or(|x| x != 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x == 1000)` +LL | _ = !opt.is_none_or(|x| x != 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x == 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:181:9 + --> tests/ui/nonminimal_bool_methods.rs:216:5 | -LL | _ = !opt.is_some_and(|x| !x); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x)` +LL | _ = !opt.is_some_and(|x| !x); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:185:9 + --> tests/ui/nonminimal_bool_methods.rs:221:5 | -LL | _ = !opt.is_none_or(|x| !x); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x)` +LL | _ = !opt.is_none_or(|x| !x); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:192:9 + --> tests/ui/nonminimal_bool_methods.rs:229:5 | -LL | _ = !opt.is_some_and(|x| x.is_ok()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_err())` +LL | _ = !opt.is_some_and(|x| x.is_ok()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_err())` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:193:9 + --> tests/ui/nonminimal_bool_methods.rs:231:5 | -LL | _ = !opt.is_some_and(|x| x.is_err()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_ok())` +LL | _ = !opt.is_some_and(|x| x.is_err()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_ok())` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:194:9 + --> tests/ui/nonminimal_bool_methods.rs:233:5 | -LL | _ = !opt.is_none_or(|x| x.is_ok()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_err())` +LL | _ = !opt.is_none_or(|x| x.is_ok()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_err())` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:195:9 + --> tests/ui/nonminimal_bool_methods.rs:235:5 | -LL | _ = !opt.is_none_or(|x| x.is_err()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_ok())` +LL | _ = !opt.is_none_or(|x| x.is_err()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_ok())` error: aborting due to 41 previous errors diff --git a/tests/ui/nonminimal_bool_methods_unfixable.rs b/tests/ui/nonminimal_bool_methods_unfixable.rs index 60b8da30a2f1..aba156ac8ea9 100644 --- a/tests/ui/nonminimal_bool_methods_unfixable.rs +++ b/tests/ui/nonminimal_bool_methods_unfixable.rs @@ -3,7 +3,9 @@ fn issue_13436() { let opt_opt = Some(Some(500)); - _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); //~ ERROR: this boolean expression can be simplified +_ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); +//~^ nonminimal_bool +//~| nonminimal_bool } fn main() {} diff --git a/tests/ui/nonminimal_bool_methods_unfixable.stderr b/tests/ui/nonminimal_bool_methods_unfixable.stderr index 5a90155844cd..c228bafad325 100644 --- a/tests/ui/nonminimal_bool_methods_unfixable.stderr +++ b/tests/ui/nonminimal_bool_methods_unfixable.stderr @@ -1,17 +1,17 @@ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:9 + --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:5 | -LL | _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt_opt.is_none_or(|x| x.is_some_and(|y| y != 1000))` +LL | _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt_opt.is_none_or(|x| x.is_some_and(|y| y != 1000))` | = note: `-D clippy::nonminimal-bool` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:34 + --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:30 | -LL | _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_none_or(|y| y == 1000)` +LL | _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_none_or(|y| y == 1000)` error: aborting due to 2 previous errors diff --git a/tests/ui/obfuscated_if_else.fixed b/tests/ui/obfuscated_if_else.fixed index 2cdbee90d52d..61a8fdddcd7d 100644 --- a/tests/ui/obfuscated_if_else.fixed +++ b/tests/ui/obfuscated_if_else.fixed @@ -3,48 +3,62 @@ fn main() { if true { "a" } else { "b" }; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + if true { "a" } else { "b" }; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + let a = 1; if a == 1 { "a" } else { "b" }; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + if a == 1 { "a" } else { "b" }; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + let partial = (a == 1).then_some("a"); partial.unwrap_or("b"); // not lint let mut a = 0; if true { a += 1 } else { () }; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + if true { () } else { a += 2 }; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + } fn issue11141() { // Parentheses are required around the left side of a binary expression let _ = (if true { 40 } else { 17 }) | 2; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + // Parentheses are required only for the leftmost expression let _ = (if true { 30 } else { 17 }) | if true { 2 } else { 3 } | if true { 10 } else { 1 }; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + //~| obfuscated_if_else + //~| obfuscated_if_else + // Parentheses are not required around the right side of a binary expression let _ = 2 | if true { 40 } else { 17 }; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + // Parentheses are not required for a cast let _ = if true { 42 } else { 17 } as u8; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + // Parentheses are not required for a deref let _ = *if true { &42 } else { &17 }; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + // Parentheses are not required for a deref followed by a cast let _ = *if true { &42 } else { &17 } as u8; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + } diff --git a/tests/ui/obfuscated_if_else.rs b/tests/ui/obfuscated_if_else.rs index 20c67e729926..0eaafe8b66ad 100644 --- a/tests/ui/obfuscated_if_else.rs +++ b/tests/ui/obfuscated_if_else.rs @@ -3,48 +3,62 @@ fn main() { true.then_some("a").unwrap_or("b"); - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + true.then(|| "a").unwrap_or("b"); - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + let a = 1; (a == 1).then_some("a").unwrap_or("b"); - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + (a == 1).then(|| "a").unwrap_or("b"); - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + let partial = (a == 1).then_some("a"); partial.unwrap_or("b"); // not lint let mut a = 0; true.then_some(a += 1).unwrap_or(()); - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + true.then_some(()).unwrap_or(a += 2); - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + } fn issue11141() { // Parentheses are required around the left side of a binary expression let _ = true.then_some(40).unwrap_or(17) | 2; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + // Parentheses are required only for the leftmost expression let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + //~| obfuscated_if_else + //~| obfuscated_if_else + // Parentheses are not required around the right side of a binary expression let _ = 2 | true.then_some(40).unwrap_or(17); - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + // Parentheses are not required for a cast let _ = true.then_some(42).unwrap_or(17) as u8; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + // Parentheses are not required for a deref let _ = *true.then_some(&42).unwrap_or(&17); - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + // Parentheses are not required for a deref followed by a cast let _ = *true.then_some(&42).unwrap_or(&17) as u8; - //~^ ERROR: this method chain can be written more clearly with `if .. else ..` + //~^ obfuscated_if_else + } diff --git a/tests/ui/obfuscated_if_else.stderr b/tests/ui/obfuscated_if_else.stderr index 9b1aebb58940..2d635871950f 100644 --- a/tests/ui/obfuscated_if_else.stderr +++ b/tests/ui/obfuscated_if_else.stderr @@ -8,79 +8,79 @@ LL | true.then_some("a").unwrap_or("b"); = help: to override `-D warnings` add `#[allow(clippy::obfuscated_if_else)]` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:7:5 + --> tests/ui/obfuscated_if_else.rs:8:5 | LL | true.then(|| "a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:11:5 + --> tests/ui/obfuscated_if_else.rs:13:5 | LL | (a == 1).then_some("a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:13:5 + --> tests/ui/obfuscated_if_else.rs:16:5 | LL | (a == 1).then(|| "a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:20:5 + --> tests/ui/obfuscated_if_else.rs:24:5 | LL | true.then_some(a += 1).unwrap_or(()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { a += 1 } else { () }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:22:5 + --> tests/ui/obfuscated_if_else.rs:27:5 | LL | true.then_some(()).unwrap_or(a += 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { a += 2 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:28:13 + --> tests/ui/obfuscated_if_else.rs:34:13 | LL | let _ = true.then_some(40).unwrap_or(17) | 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 40 } else { 17 })` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:32:13 + --> tests/ui/obfuscated_if_else.rs:39:13 | LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 30 } else { 17 })` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:32:48 + --> tests/ui/obfuscated_if_else.rs:39:48 | LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 2 } else { 3 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:32:81 + --> tests/ui/obfuscated_if_else.rs:39:81 | LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 10 } else { 1 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:36:17 + --> tests/ui/obfuscated_if_else.rs:46:17 | LL | let _ = 2 | true.then_some(40).unwrap_or(17); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 40 } else { 17 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:40:13 + --> tests/ui/obfuscated_if_else.rs:51:13 | LL | let _ = true.then_some(42).unwrap_or(17) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 42 } else { 17 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:44:14 + --> tests/ui/obfuscated_if_else.rs:56:14 | LL | let _ = *true.then_some(&42).unwrap_or(&17); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:48:14 + --> tests/ui/obfuscated_if_else.rs:61:14 | LL | let _ = *true.then_some(&42).unwrap_or(&17) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` diff --git a/tests/ui/octal_escapes.rs b/tests/ui/octal_escapes.rs index f2664e2fa67f..08e0316d1124 100644 --- a/tests/ui/octal_escapes.rs +++ b/tests/ui/octal_escapes.rs @@ -2,20 +2,31 @@ #![warn(clippy::octal_escapes)] fn main() { - let _bad1 = "\033[0m"; //~ octal_escapes - let _bad2 = b"\033[0m"; //~ octal_escapes - let _bad3 = "\\\033[0m"; //~ octal_escapes +let _bad1 = "\033[0m"; +//~^ octal_escapes +let _bad2 = b"\033[0m"; +//~^ octal_escapes +let _bad3 = "\\\033[0m"; +//~^ octal_escapes // maximum 3 digits (\012 is the escape) - let _bad4 = "\01234567"; //~ octal_escapes - let _bad5 = "\0\03"; //~ octal_escapes +let _bad4 = "\01234567"; +//~^ octal_escapes +let _bad5 = "\0\03"; +//~^ octal_escapes let _bad6 = "Text-\055\077-MoreText"; //~^ octal_escapes //~| octal_escapes + + let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; //~^ octal_escapes //~| octal_escapes - let _bad8 = "锈\01锈"; //~ octal_escapes - let _bad9 = "锈\011锈"; //~ octal_escapes + + +let _bad8 = "锈\01锈"; +//~^ octal_escapes +let _bad9 = "锈\011锈"; +//~^ octal_escapes let _good1 = "\\033[0m"; let _good2 = "\0\\0"; diff --git a/tests/ui/octal_escapes.stderr b/tests/ui/octal_escapes.stderr index 9343ba64a30b..2f838a84dd48 100644 --- a/tests/ui/octal_escapes.stderr +++ b/tests/ui/octal_escapes.stderr @@ -1,83 +1,83 @@ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:5:18 + --> tests/ui/octal_escapes.rs:5:14 | -LL | let _bad1 = "\033[0m"; - | ^^^^ +LL | let _bad1 = "\033[0m"; + | ^^^^ | = help: octal escapes are not supported, `\0` is always null = note: `-D clippy::octal-escapes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::octal_escapes)]` help: if an octal escape is intended, use a hex escape instead | -LL | let _bad1 = "\x1b[0m"; - | ~~~~ +LL | let _bad1 = "\x1b[0m"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad1 = "\x0033[0m"; - | ~~~~~~ +LL | let _bad1 = "\x0033[0m"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:6:19 + --> tests/ui/octal_escapes.rs:7:15 | -LL | let _bad2 = b"\033[0m"; - | ^^^^ +LL | let _bad2 = b"\033[0m"; + | ^^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad2 = b"\x1b[0m"; - | ~~~~ +LL | let _bad2 = b"\x1b[0m"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad2 = b"\x0033[0m"; - | ~~~~~~ +LL | let _bad2 = b"\x0033[0m"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:7:20 + --> tests/ui/octal_escapes.rs:9:16 | -LL | let _bad3 = "\\\033[0m"; - | ^^^^ +LL | let _bad3 = "\\\033[0m"; + | ^^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad3 = "\\\x1b[0m"; - | ~~~~ +LL | let _bad3 = "\\\x1b[0m"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad3 = "\\\x0033[0m"; - | ~~~~~~ +LL | let _bad3 = "\\\x0033[0m"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:9:18 + --> tests/ui/octal_escapes.rs:12:14 | -LL | let _bad4 = "\01234567"; - | ^^^^ +LL | let _bad4 = "\01234567"; + | ^^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad4 = "\x0a34567"; - | ~~~~ +LL | let _bad4 = "\x0a34567"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad4 = "\x001234567"; - | ~~~~~~ +LL | let _bad4 = "\x001234567"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:10:20 + --> tests/ui/octal_escapes.rs:14:16 | -LL | let _bad5 = "\0\03"; - | ^^^ +LL | let _bad5 = "\0\03"; + | ^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad5 = "\0\x03"; - | ~~~~ +LL | let _bad5 = "\0\x03"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad5 = "\0\x0003"; - | ~~~~~~ +LL | let _bad5 = "\0\x0003"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:11:23 + --> tests/ui/octal_escapes.rs:16:23 | LL | let _bad6 = "Text-\055\077-MoreText"; | ^^^^ @@ -92,7 +92,7 @@ LL | let _bad6 = "Text-\x0055\077-MoreText"; | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:11:27 + --> tests/ui/octal_escapes.rs:16:27 | LL | let _bad6 = "Text-\055\077-MoreText"; | ^^^^ @@ -107,7 +107,7 @@ LL | let _bad6 = "Text-\055\x0077-MoreText"; | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:14:31 + --> tests/ui/octal_escapes.rs:21:31 | LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | ^^^ @@ -122,7 +122,7 @@ LL | let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:14:34 + --> tests/ui/octal_escapes.rs:21:34 | LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | ^^^ @@ -137,34 +137,34 @@ LL | let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:17:19 + --> tests/ui/octal_escapes.rs:26:15 | -LL | let _bad8 = "锈\01锈"; - | ^^^ +LL | let _bad8 = "锈\01锈"; + | ^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad8 = "锈\x01锈"; - | ~~~~ +LL | let _bad8 = "锈\x01锈"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad8 = "锈\x0001锈"; - | ~~~~~~ +LL | let _bad8 = "锈\x0001锈"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:18:19 + --> tests/ui/octal_escapes.rs:28:15 | -LL | let _bad9 = "锈\011锈"; - | ^^^^ +LL | let _bad9 = "锈\011锈"; + | ^^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad9 = "锈\x09锈"; - | ~~~~ +LL | let _bad9 = "锈\x09锈"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad9 = "锈\x0011锈"; - | ~~~~~~ +LL | let _bad9 = "锈\x0011锈"; + | ~~~~~~ error: aborting due to 11 previous errors diff --git a/tests/ui/ok_expect.rs b/tests/ui/ok_expect.rs index c2ad21e22ff8..33702878ddb7 100644 --- a/tests/ui/ok_expect.rs +++ b/tests/ui/ok_expect.rs @@ -14,21 +14,26 @@ fn main() { let _ = res.unwrap(); res.ok().expect("disaster!"); - //~^ ERROR: called `ok().expect()` on a `Result` value + //~^ ok_expect + // the following should not warn, since `expect` isn't implemented unless // the error type implements `Debug` let res2: Result = Ok(0); res2.ok().expect("oh noes!"); let res3: Result> = Ok(0); res3.ok().expect("whoof"); - //~^ ERROR: called `ok().expect()` on a `Result` value + //~^ ok_expect + let res4: Result = Ok(0); res4.ok().expect("argh"); - //~^ ERROR: called `ok().expect()` on a `Result` value + //~^ ok_expect + let res5: io::Result = Ok(0); res5.ok().expect("oops"); - //~^ ERROR: called `ok().expect()` on a `Result` value + //~^ ok_expect + let res6: Result = Ok(0); res6.ok().expect("meh"); - //~^ ERROR: called `ok().expect()` on a `Result` value + //~^ ok_expect + } diff --git a/tests/ui/ok_expect.stderr b/tests/ui/ok_expect.stderr index 2fd4f007d06d..a9e3533d8ca1 100644 --- a/tests/ui/ok_expect.stderr +++ b/tests/ui/ok_expect.stderr @@ -9,7 +9,7 @@ LL | res.ok().expect("disaster!"); = help: to override `-D warnings` add `#[allow(clippy::ok_expect)]` error: called `ok().expect()` on a `Result` value - --> tests/ui/ok_expect.rs:23:5 + --> tests/ui/ok_expect.rs:24:5 | LL | res3.ok().expect("whoof"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | res3.ok().expect("whoof"); = help: you can call `expect()` directly on the `Result` error: called `ok().expect()` on a `Result` value - --> tests/ui/ok_expect.rs:26:5 + --> tests/ui/ok_expect.rs:28:5 | LL | res4.ok().expect("argh"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | res4.ok().expect("argh"); = help: you can call `expect()` directly on the `Result` error: called `ok().expect()` on a `Result` value - --> tests/ui/ok_expect.rs:29:5 + --> tests/ui/ok_expect.rs:32:5 | LL | res5.ok().expect("oops"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | res5.ok().expect("oops"); = help: you can call `expect()` directly on the `Result` error: called `ok().expect()` on a `Result` value - --> tests/ui/ok_expect.rs:32:5 + --> tests/ui/ok_expect.rs:36:5 | LL | res6.ok().expect("meh"); | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/only_used_in_recursion.rs b/tests/ui/only_used_in_recursion.rs index 169fb790f8c5..cf872920a6e2 100644 --- a/tests/ui/only_used_in_recursion.rs +++ b/tests/ui/only_used_in_recursion.rs @@ -9,18 +9,22 @@ fn _simple2(x: u32) -> u32 { } fn _one_unused(flag: u32, a: usize) -> usize { - //~^ ERROR: parameter is only used in recursion +//~^ only_used_in_recursion + if flag == 0 { 0 } else { _one_unused(flag - 1, a) } } fn _two_unused(flag: u32, a: u32, b: i32) -> usize { - //~^ ERROR: parameter is only used in recursion - //~| ERROR: parameter is only used in recursion +//~^ only_used_in_recursion +//~| only_used_in_recursion + + if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) } } fn _with_calc(flag: u32, a: i64) -> usize { - //~^ ERROR: parameter is only used in recursion +//~^ only_used_in_recursion + if flag == 0 { 0 } else { @@ -34,8 +38,10 @@ fn _used_with_flag(flag: u32, a: u32) -> usize { } fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { - //~^ ERROR: parameter is only used in recursion - //~| ERROR: parameter is only used in recursion +//~^ only_used_in_recursion +//~| only_used_in_recursion + + if flag == 0 { 0 } else { @@ -44,8 +50,10 @@ fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { } fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { - //~^ ERROR: parameter is only used in recursion - //~| ERROR: parameter is only used in recursion +//~^ only_used_in_recursion +//~| only_used_in_recursion + + if flag == 0 { 0 } else { @@ -54,7 +62,8 @@ fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { } fn _not_primitive(flag: u32, b: String) -> usize { - //~^ ERROR: parameter is only used in recursion +//~^ only_used_in_recursion + if flag == 0 { 0 } else { _not_primitive(flag - 1, b) } } @@ -62,13 +71,16 @@ struct A; impl A { fn _method(flag: usize, a: usize) -> usize { - //~^ ERROR: parameter is only used in recursion + //~^ only_used_in_recursion + if flag == 0 { 0 } else { Self::_method(flag - 1, a) } } fn _method_self(&self, flag: usize, a: usize) -> usize { - //~^ ERROR: parameter is only used in recursion - //~| ERROR: parameter is only used in recursion + //~^ only_used_in_recursion + //~| only_used_in_recursion + + if flag == 0 { 0 } else { self._method_self(flag - 1, a) } } } @@ -80,12 +92,14 @@ trait B { impl B for A { fn method(flag: u32, a: usize) -> usize { - //~^ ERROR: parameter is only used in recursion + //~^ only_used_in_recursion + if flag == 0 { 0 } else { Self::method(flag - 1, a) } } fn method_self(&self, flag: u32, a: usize) -> usize { - //~^ ERROR: parameter is only used in recursion + //~^ only_used_in_recursion + if flag == 0 { 0 } else { self.method_self(flag - 1, a) } } } @@ -112,12 +126,14 @@ impl B for u32 { trait C { fn method(flag: u32, a: usize) -> usize { - //~^ ERROR: parameter is only used in recursion + //~^ only_used_in_recursion + if flag == 0 { 0 } else { Self::method(flag - 1, a) } } fn method_self(&self, flag: u32, a: usize) -> usize { - //~^ ERROR: parameter is only used in recursion + //~^ only_used_in_recursion + if flag == 0 { 0 } else { self.method_self(flag - 1, a) } } } diff --git a/tests/ui/only_used_in_recursion.stderr b/tests/ui/only_used_in_recursion.stderr index a3aee2697f38..1f1aa75be662 100644 --- a/tests/ui/only_used_in_recursion.stderr +++ b/tests/ui/only_used_in_recursion.stderr @@ -5,7 +5,7 @@ LL | fn _one_unused(flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:13:53 + --> tests/ui/only_used_in_recursion.rs:14:53 | LL | if flag == 0 { 0 } else { _one_unused(flag - 1, a) } | ^ @@ -13,181 +13,181 @@ LL | if flag == 0 { 0 } else { _one_unused(flag - 1, a) } = help: to override `-D warnings` add `#[allow(clippy::only_used_in_recursion)]` error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:16:27 + --> tests/ui/only_used_in_recursion.rs:17:27 | LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:19:53 + --> tests/ui/only_used_in_recursion.rs:22:53 | LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:16:35 + --> tests/ui/only_used_in_recursion.rs:17:35 | LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:19:56 + --> tests/ui/only_used_in_recursion.rs:22:56 | LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:22:26 + --> tests/ui/only_used_in_recursion.rs:25:26 | LL | fn _with_calc(flag: u32, a: i64) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:27:32 + --> tests/ui/only_used_in_recursion.rs:31:32 | LL | _with_calc(flag - 1, (-a + 10) * 5) | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:36:33 + --> tests/ui/only_used_in_recursion.rs:40:33 | LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:42:38 + --> tests/ui/only_used_in_recursion.rs:48:38 | LL | _used_with_unused(flag - 1, -a, a + b) | ^ ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:36:41 + --> tests/ui/only_used_in_recursion.rs:40:41 | LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:42:45 + --> tests/ui/only_used_in_recursion.rs:48:45 | LL | _used_with_unused(flag - 1, -a, a + b) | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:46:35 + --> tests/ui/only_used_in_recursion.rs:52:35 | LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:52:39 + --> tests/ui/only_used_in_recursion.rs:60:39 | LL | _codependent_unused(flag - 1, a * b, a + b) | ^ ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:46:43 + --> tests/ui/only_used_in_recursion.rs:52:43 | LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:52:43 + --> tests/ui/only_used_in_recursion.rs:60:43 | LL | _codependent_unused(flag - 1, a * b, a + b) | ^ ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:56:30 + --> tests/ui/only_used_in_recursion.rs:64:30 | LL | fn _not_primitive(flag: u32, b: String) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:58:56 + --> tests/ui/only_used_in_recursion.rs:67:56 | LL | if flag == 0 { 0 } else { _not_primitive(flag - 1, b) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:64:29 + --> tests/ui/only_used_in_recursion.rs:73:29 | LL | fn _method(flag: usize, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:66:59 + --> tests/ui/only_used_in_recursion.rs:76:59 | LL | if flag == 0 { 0 } else { Self::_method(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:69:22 + --> tests/ui/only_used_in_recursion.rs:79:22 | LL | fn _method_self(&self, flag: usize, a: usize) -> usize { | ^^^^ | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:72:35 + --> tests/ui/only_used_in_recursion.rs:84:35 | LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) } | ^^^^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:69:41 + --> tests/ui/only_used_in_recursion.rs:79:41 | LL | fn _method_self(&self, flag: usize, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:72:63 + --> tests/ui/only_used_in_recursion.rs:84:63 | LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:82:26 + --> tests/ui/only_used_in_recursion.rs:94:26 | LL | fn method(flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:84:58 + --> tests/ui/only_used_in_recursion.rs:97:58 | LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:87:38 + --> tests/ui/only_used_in_recursion.rs:100:38 | LL | fn method_self(&self, flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:89:62 + --> tests/ui/only_used_in_recursion.rs:103:62 | LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:114:26 + --> tests/ui/only_used_in_recursion.rs:128:26 | LL | fn method(flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:116:58 + --> tests/ui/only_used_in_recursion.rs:131:58 | LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:119:38 + --> tests/ui/only_used_in_recursion.rs:134:38 | LL | fn method_self(&self, flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:121:62 + --> tests/ui/only_used_in_recursion.rs:137:62 | LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) } | ^ diff --git a/tests/ui/only_used_in_recursion2.rs b/tests/ui/only_used_in_recursion2.rs index 1353ff8816ad..e4639c8b8a45 100644 --- a/tests/ui/only_used_in_recursion2.rs +++ b/tests/ui/only_used_in_recursion2.rs @@ -1,9 +1,11 @@ #![warn(clippy::only_used_in_recursion)] //@no-rustfix fn _with_inner(flag: u32, a: u32, b: u32) -> usize { - //~^ ERROR: parameter is only used in recursion +//~^ only_used_in_recursion + fn inner(flag: u32, a: u32) -> u32 { - //~^ ERROR: parameter is only used in recursion + //~^ only_used_in_recursion + if flag == 0 { 0 } else { inner(flag, a) } } @@ -12,7 +14,8 @@ fn _with_inner(flag: u32, a: u32, b: u32) -> usize { } fn _with_closure(a: Option, b: u32, f: impl Fn(u32, u32) -> Option) -> u32 { - //~^ ERROR: parameter is only used in recursion +//~^ only_used_in_recursion + if let Some(x) = a.and_then(|x| f(x, x)) { _with_closure(Some(x), b, f) } else { @@ -63,7 +66,8 @@ impl E<()> for () { } fn overwritten_param(flag: u32, mut a: usize) -> usize { - //~^ ERROR: parameter is only used in recursion +//~^ only_used_in_recursion + if flag == 0 { return 0; } else if flag > 5 { @@ -75,7 +79,8 @@ fn overwritten_param(flag: u32, mut a: usize) -> usize { } fn field_direct(flag: u32, mut a: (usize,)) -> usize { - //~^ ERROR: parameter is only used in recursion +//~^ only_used_in_recursion + if flag == 0 { 0 } else { diff --git a/tests/ui/only_used_in_recursion2.stderr b/tests/ui/only_used_in_recursion2.stderr index e39460c7e8f3..a7cd8713cf7a 100644 --- a/tests/ui/only_used_in_recursion2.stderr +++ b/tests/ui/only_used_in_recursion2.stderr @@ -5,7 +5,7 @@ LL | fn _with_inner(flag: u32, a: u32, b: u32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion2.rs:11:52 + --> tests/ui/only_used_in_recursion2.rs:13:52 | LL | if flag == 0 { 0 } else { _with_inner(flag, a, b + x) } | ^ @@ -13,49 +13,49 @@ LL | if flag == 0 { 0 } else { _with_inner(flag, a, b + x) } = help: to override `-D warnings` add `#[allow(clippy::only_used_in_recursion)]` error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion2.rs:5:25 + --> tests/ui/only_used_in_recursion2.rs:6:25 | LL | fn inner(flag: u32, a: u32) -> u32 { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion2.rs:7:47 + --> tests/ui/only_used_in_recursion2.rs:9:47 | LL | if flag == 0 { 0 } else { inner(flag, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion2.rs:14:34 + --> tests/ui/only_used_in_recursion2.rs:16:34 | LL | fn _with_closure(a: Option, b: u32, f: impl Fn(u32, u32) -> Option) -> u32 { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion2.rs:17:32 + --> tests/ui/only_used_in_recursion2.rs:20:32 | LL | _with_closure(Some(x), b, f) | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion2.rs:65:37 + --> tests/ui/only_used_in_recursion2.rs:68:37 | LL | fn overwritten_param(flag: u32, mut a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion2.rs:74:29 + --> tests/ui/only_used_in_recursion2.rs:78:29 | LL | overwritten_param(flag, a) | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion2.rs:77:32 + --> tests/ui/only_used_in_recursion2.rs:81:32 | LL | fn field_direct(flag: u32, mut a: (usize,)) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion2.rs:83:32 + --> tests/ui/only_used_in_recursion2.rs:88:32 | LL | field_direct(flag - 1, a) | ^ diff --git a/tests/ui/op_ref.fixed b/tests/ui/op_ref.fixed index 183dcf4f0863..a67f883fe2e2 100644 --- a/tests/ui/op_ref.fixed +++ b/tests/ui/op_ref.fixed @@ -9,8 +9,9 @@ fn main() { let unwanted = &tracked_fds - &new_fds; let foo = 5 - 6; - //~^ ERROR: needlessly taken reference of both operands - //~| NOTE: `-D clippy::op-ref` implied by `-D warnings` + //~^ op_ref + + let bar = String::new(); let bar = "foo" == &bar; @@ -56,7 +57,8 @@ fn main() { let x = Y(1); let y = Y(2); let z = x & y; - //~^ ERROR: taken reference of right operand + //~^ op_ref + } #[derive(Clone, Copy)] @@ -90,9 +92,11 @@ impl Mul for A { let two = 2; let three = 3; let _ = one * self; - //~^ ERROR: taken reference of right operand + //~^ op_ref + let _ = two + three; - //~^ ERROR: taken reference of right operand + //~^ op_ref + // Removing the reference would lead to unconditional recursion self * &rhs } diff --git a/tests/ui/op_ref.rs b/tests/ui/op_ref.rs index 6ed4f23d2bd7..798484c9fe9e 100644 --- a/tests/ui/op_ref.rs +++ b/tests/ui/op_ref.rs @@ -9,8 +9,9 @@ fn main() { let unwanted = &tracked_fds - &new_fds; let foo = &5 - &6; - //~^ ERROR: needlessly taken reference of both operands - //~| NOTE: `-D clippy::op-ref` implied by `-D warnings` + //~^ op_ref + + let bar = String::new(); let bar = "foo" == &bar; @@ -56,7 +57,8 @@ fn main() { let x = Y(1); let y = Y(2); let z = x & &y; - //~^ ERROR: taken reference of right operand + //~^ op_ref + } #[derive(Clone, Copy)] @@ -90,9 +92,11 @@ impl Mul for A { let two = 2; let three = 3; let _ = one * &self; - //~^ ERROR: taken reference of right operand + //~^ op_ref + let _ = two + &three; - //~^ ERROR: taken reference of right operand + //~^ op_ref + // Removing the reference would lead to unconditional recursion self * &rhs } diff --git a/tests/ui/op_ref.stderr b/tests/ui/op_ref.stderr index c5b68730a8f2..86d0be4272c6 100644 --- a/tests/ui/op_ref.stderr +++ b/tests/ui/op_ref.stderr @@ -12,7 +12,7 @@ LL | let foo = 5 - 6; | ~ ~ error: taken reference of right operand - --> tests/ui/op_ref.rs:58:13 + --> tests/ui/op_ref.rs:59:13 | LL | let z = x & &y; | ^^^^-- @@ -20,7 +20,7 @@ LL | let z = x & &y; | help: use the right value directly: `y` error: taken reference of right operand - --> tests/ui/op_ref.rs:92:17 + --> tests/ui/op_ref.rs:94:17 | LL | let _ = one * &self; | ^^^^^^----- @@ -28,7 +28,7 @@ LL | let _ = one * &self; | help: use the right value directly: `self` error: taken reference of right operand - --> tests/ui/op_ref.rs:94:17 + --> tests/ui/op_ref.rs:97:17 | LL | let _ = two + &three; | ^^^^^^------ diff --git a/tests/ui/open_options.rs b/tests/ui/open_options.rs index 4acb3780df43..acc2a5f86164 100644 --- a/tests/ui/open_options.rs +++ b/tests/ui/open_options.rs @@ -15,28 +15,36 @@ impl OpenOptionsExt for OpenOptions { fn main() { OpenOptions::new().read(true).truncate(true).open("foo.txt"); - //~^ ERROR: file opened with `truncate` and `read` - //~| NOTE: `-D clippy::nonsensical-open-options` implied by `-D warnings` + //~^ nonsensical_open_options + + OpenOptions::new().append(true).truncate(true).open("foo.txt"); - //~^ ERROR: file opened with `append` and `truncate` + //~^ nonsensical_open_options + OpenOptions::new().read(true).read(false).open("foo.txt"); - //~^ ERROR: the method `read` is called more than once + //~^ nonsensical_open_options + OpenOptions::new() .create(true) .truncate(true) // Ensure we don't trigger suspicious open options by having create without truncate .create(false) - //~^ ERROR: the method `create` is called more than once + //~^ nonsensical_open_options + .open("foo.txt"); OpenOptions::new().write(true).write(false).open("foo.txt"); - //~^ ERROR: the method `write` is called more than once + //~^ nonsensical_open_options + OpenOptions::new().append(true).append(false).open("foo.txt"); - //~^ ERROR: the method `append` is called more than once + //~^ nonsensical_open_options + OpenOptions::new().truncate(true).truncate(false).open("foo.txt"); - //~^ ERROR: the method `truncate` is called more than once + //~^ nonsensical_open_options + std::fs::File::options().read(true).read(false).open("foo.txt"); - //~^ ERROR: the method `read` is called more than once + //~^ nonsensical_open_options + let mut options = std::fs::OpenOptions::new(); options.read(true); diff --git a/tests/ui/open_options.stderr b/tests/ui/open_options.stderr index 19755bce46c8..27d8d01f3b5f 100644 --- a/tests/ui/open_options.stderr +++ b/tests/ui/open_options.stderr @@ -8,43 +8,43 @@ LL | OpenOptions::new().read(true).truncate(true).open("foo.txt"); = help: to override `-D warnings` add `#[allow(clippy::nonsensical_open_options)]` error: file opened with `append` and `truncate` - --> tests/ui/open_options.rs:20:5 + --> tests/ui/open_options.rs:21:5 | LL | OpenOptions::new().append(true).truncate(true).open("foo.txt"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the method `read` is called more than once - --> tests/ui/open_options.rs:23:35 + --> tests/ui/open_options.rs:25:35 | LL | OpenOptions::new().read(true).read(false).open("foo.txt"); | ^^^^^^^^^^^ error: the method `create` is called more than once - --> tests/ui/open_options.rs:28:10 + --> tests/ui/open_options.rs:31:10 | LL | .create(false) | ^^^^^^^^^^^^^ error: the method `write` is called more than once - --> tests/ui/open_options.rs:31:36 + --> tests/ui/open_options.rs:35:36 | LL | OpenOptions::new().write(true).write(false).open("foo.txt"); | ^^^^^^^^^^^^ error: the method `append` is called more than once - --> tests/ui/open_options.rs:33:37 + --> tests/ui/open_options.rs:38:37 | LL | OpenOptions::new().append(true).append(false).open("foo.txt"); | ^^^^^^^^^^^^^ error: the method `truncate` is called more than once - --> tests/ui/open_options.rs:35:39 + --> tests/ui/open_options.rs:41:39 | LL | OpenOptions::new().truncate(true).truncate(false).open("foo.txt"); | ^^^^^^^^^^^^^^^ error: the method `read` is called more than once - --> tests/ui/open_options.rs:38:41 + --> tests/ui/open_options.rs:45:41 | LL | std::fs::File::options().read(true).read(false).open("foo.txt"); | ^^^^^^^^^^^ diff --git a/tests/ui/open_options_fixable.fixed b/tests/ui/open_options_fixable.fixed index 90a129a9bdff..7ba5a8782bef 100644 --- a/tests/ui/open_options_fixable.fixed +++ b/tests/ui/open_options_fixable.fixed @@ -3,5 +3,6 @@ use std::fs::OpenOptions; #[warn(clippy::suspicious_open_options)] fn main() { OpenOptions::new().create(true).truncate(true).open("foo.txt"); - //~^ ERROR: file opened with `create`, but `truncate` behavior not defined + //~^ suspicious_open_options + } diff --git a/tests/ui/open_options_fixable.rs b/tests/ui/open_options_fixable.rs index 3a9e522ba150..230d6d782074 100644 --- a/tests/ui/open_options_fixable.rs +++ b/tests/ui/open_options_fixable.rs @@ -3,5 +3,6 @@ use std::fs::OpenOptions; #[warn(clippy::suspicious_open_options)] fn main() { OpenOptions::new().create(true).open("foo.txt"); - //~^ ERROR: file opened with `create`, but `truncate` behavior not defined + //~^ suspicious_open_options + } diff --git a/tests/ui/option_as_ref_cloned.fixed b/tests/ui/option_as_ref_cloned.fixed index 394dad219f77..cf21d1c0176e 100644 --- a/tests/ui/option_as_ref_cloned.fixed +++ b/tests/ui/option_as_ref_cloned.fixed @@ -5,10 +5,13 @@ fn main() { let mut x = Some(String::new()); let _: Option = x.clone(); + //~^ option_as_ref_cloned let _: Option = x.clone(); + //~^ option_as_ref_cloned let y = x.as_ref(); let _: Option<&String> = y.clone(); + //~^ option_as_ref_cloned macro_rules! cloned_recv { () => { diff --git a/tests/ui/option_as_ref_cloned.rs b/tests/ui/option_as_ref_cloned.rs index 7243957927b2..354638c4c380 100644 --- a/tests/ui/option_as_ref_cloned.rs +++ b/tests/ui/option_as_ref_cloned.rs @@ -5,10 +5,13 @@ fn main() { let mut x = Some(String::new()); let _: Option = x.as_ref().cloned(); + //~^ option_as_ref_cloned let _: Option = x.as_mut().cloned(); + //~^ option_as_ref_cloned let y = x.as_ref(); let _: Option<&String> = y.as_ref().cloned(); + //~^ option_as_ref_cloned macro_rules! cloned_recv { () => { diff --git a/tests/ui/option_as_ref_cloned.stderr b/tests/ui/option_as_ref_cloned.stderr index 5892f2bdec56..d0f5747420bc 100644 --- a/tests/ui/option_as_ref_cloned.stderr +++ b/tests/ui/option_as_ref_cloned.stderr @@ -12,7 +12,7 @@ LL | let _: Option = x.clone(); | ~~~~~ error: cloning an `Option<_>` using `.as_mut().cloned()` - --> tests/ui/option_as_ref_cloned.rs:8:31 + --> tests/ui/option_as_ref_cloned.rs:9:31 | LL | let _: Option = x.as_mut().cloned(); | ^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _: Option = x.clone(); | ~~~~~ error: cloning an `Option<_>` using `.as_ref().cloned()` - --> tests/ui/option_as_ref_cloned.rs:11:32 + --> tests/ui/option_as_ref_cloned.rs:13:32 | LL | let _: Option<&String> = y.as_ref().cloned(); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/option_as_ref_deref.fixed b/tests/ui/option_as_ref_deref.fixed index c5a959ba566d..9be89b5d484f 100644 --- a/tests/ui/option_as_ref_deref.fixed +++ b/tests/ui/option_as_ref_deref.fixed @@ -9,25 +9,38 @@ fn main() { let mut opt = Some(String::from("123")); let _ = opt.clone().as_deref().map(str::len); + //~^ option_as_ref_deref #[rustfmt::skip] let _ = opt.clone().as_deref() .map(str::len); let _ = opt.as_deref_mut(); + //~^ option_as_ref_deref let _ = opt.as_deref(); + //~^ option_as_ref_deref let _ = opt.as_deref(); + //~^ option_as_ref_deref let _ = opt.as_deref_mut(); + //~^ option_as_ref_deref let _ = opt.as_deref_mut(); + //~^ option_as_ref_deref let _ = Some(CString::new(vec![]).unwrap()).as_deref(); + //~^ option_as_ref_deref let _ = Some(OsString::new()).as_deref(); + //~^ option_as_ref_deref let _ = Some(PathBuf::new()).as_deref(); + //~^ option_as_ref_deref let _ = Some(Vec::<()>::new()).as_deref(); + //~^ option_as_ref_deref let _ = Some(Vec::<()>::new()).as_deref_mut(); + //~^ option_as_ref_deref let _ = opt.as_deref(); + //~^ option_as_ref_deref let _ = opt.clone().as_deref_mut().map(|x| x.len()); + //~^ option_as_ref_deref let vc = vec![String::new()]; let _ = Some(1_usize).as_ref().map(|x| vc[*x].as_str()); // should not be linted @@ -35,10 +48,13 @@ fn main() { let _: Option<&str> = Some(&String::new()).as_ref().map(|x| x.as_str()); // should not be linted let _ = opt.as_deref(); + //~^ option_as_ref_deref let _ = opt.as_deref_mut(); + //~^ option_as_ref_deref // Issue #5927 let _ = opt.as_deref(); + //~^ option_as_ref_deref } #[clippy::msrv = "1.39"] @@ -51,4 +67,5 @@ fn msrv_1_39() { fn msrv_1_40() { let opt = Some(String::from("123")); let _ = opt.as_deref(); + //~^ option_as_ref_deref } diff --git a/tests/ui/option_as_ref_deref.rs b/tests/ui/option_as_ref_deref.rs index 1aeedf211fe2..d6b29e5e61b1 100644 --- a/tests/ui/option_as_ref_deref.rs +++ b/tests/ui/option_as_ref_deref.rs @@ -9,28 +9,42 @@ fn main() { let mut opt = Some(String::from("123")); let _ = opt.clone().as_ref().map(Deref::deref).map(str::len); + //~^ option_as_ref_deref #[rustfmt::skip] let _ = opt.clone() + //~^ option_as_ref_deref .as_ref().map( Deref::deref ) .map(str::len); let _ = opt.as_mut().map(DerefMut::deref_mut); + //~^ option_as_ref_deref let _ = opt.as_ref().map(String::as_str); + //~^ option_as_ref_deref let _ = opt.as_ref().map(|x| x.as_str()); + //~^ option_as_ref_deref let _ = opt.as_mut().map(String::as_mut_str); + //~^ option_as_ref_deref let _ = opt.as_mut().map(|x| x.as_mut_str()); + //~^ option_as_ref_deref let _ = Some(CString::new(vec![]).unwrap()).as_ref().map(CString::as_c_str); + //~^ option_as_ref_deref let _ = Some(OsString::new()).as_ref().map(OsString::as_os_str); + //~^ option_as_ref_deref let _ = Some(PathBuf::new()).as_ref().map(PathBuf::as_path); + //~^ option_as_ref_deref let _ = Some(Vec::<()>::new()).as_ref().map(Vec::as_slice); + //~^ option_as_ref_deref let _ = Some(Vec::<()>::new()).as_mut().map(Vec::as_mut_slice); + //~^ option_as_ref_deref let _ = opt.as_ref().map(|x| x.deref()); + //~^ option_as_ref_deref let _ = opt.clone().as_mut().map(|x| x.deref_mut()).map(|x| x.len()); + //~^ option_as_ref_deref let vc = vec![String::new()]; let _ = Some(1_usize).as_ref().map(|x| vc[*x].as_str()); // should not be linted @@ -38,10 +52,13 @@ fn main() { let _: Option<&str> = Some(&String::new()).as_ref().map(|x| x.as_str()); // should not be linted let _ = opt.as_ref().map(|x| &**x); + //~^ option_as_ref_deref let _ = opt.as_mut().map(|x| &mut **x); + //~^ option_as_ref_deref // Issue #5927 let _ = opt.as_ref().map(std::ops::Deref::deref); + //~^ option_as_ref_deref } #[clippy::msrv = "1.39"] @@ -54,4 +71,5 @@ fn msrv_1_39() { fn msrv_1_40() { let opt = Some(String::from("123")); let _ = opt.as_ref().map(String::as_str); + //~^ option_as_ref_deref } diff --git a/tests/ui/option_as_ref_deref.stderr b/tests/ui/option_as_ref_deref.stderr index 8b7f47a1b9af..ca924aec66dd 100644 --- a/tests/ui/option_as_ref_deref.stderr +++ b/tests/ui/option_as_ref_deref.stderr @@ -8,107 +8,108 @@ LL | let _ = opt.clone().as_ref().map(Deref::deref).map(str::len); = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_deref)]` error: called `.as_ref().map(Deref::deref)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:14:13 + --> tests/ui/option_as_ref_deref.rs:15:13 | LL | let _ = opt.clone() | _____________^ +LL | | LL | | .as_ref().map( LL | | Deref::deref LL | | ) | |_________^ help: consider using as_deref: `opt.clone().as_deref()` error: called `.as_mut().map(DerefMut::deref_mut)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:20:13 + --> tests/ui/option_as_ref_deref.rs:22:13 | LL | let _ = opt.as_mut().map(DerefMut::deref_mut); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()` error: called `.as_ref().map(String::as_str)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:22:13 + --> tests/ui/option_as_ref_deref.rs:25:13 | LL | let _ = opt.as_ref().map(String::as_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()` error: called `.as_ref().map(|x| x.as_str())` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:23:13 + --> tests/ui/option_as_ref_deref.rs:27:13 | LL | let _ = opt.as_ref().map(|x| x.as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()` error: called `.as_mut().map(String::as_mut_str)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:24:13 + --> tests/ui/option_as_ref_deref.rs:29:13 | LL | let _ = opt.as_mut().map(String::as_mut_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()` error: called `.as_mut().map(|x| x.as_mut_str())` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:25:13 + --> tests/ui/option_as_ref_deref.rs:31:13 | LL | let _ = opt.as_mut().map(|x| x.as_mut_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()` error: called `.as_ref().map(CString::as_c_str)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:26:13 + --> tests/ui/option_as_ref_deref.rs:33:13 | LL | let _ = Some(CString::new(vec![]).unwrap()).as_ref().map(CString::as_c_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(CString::new(vec![]).unwrap()).as_deref()` error: called `.as_ref().map(OsString::as_os_str)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:27:13 + --> tests/ui/option_as_ref_deref.rs:35:13 | LL | let _ = Some(OsString::new()).as_ref().map(OsString::as_os_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(OsString::new()).as_deref()` error: called `.as_ref().map(PathBuf::as_path)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:28:13 + --> tests/ui/option_as_ref_deref.rs:37:13 | LL | let _ = Some(PathBuf::new()).as_ref().map(PathBuf::as_path); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(PathBuf::new()).as_deref()` error: called `.as_ref().map(Vec::as_slice)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:29:13 + --> tests/ui/option_as_ref_deref.rs:39:13 | LL | let _ = Some(Vec::<()>::new()).as_ref().map(Vec::as_slice); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(Vec::<()>::new()).as_deref()` error: called `.as_mut().map(Vec::as_mut_slice)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:30:13 + --> tests/ui/option_as_ref_deref.rs:41:13 | LL | let _ = Some(Vec::<()>::new()).as_mut().map(Vec::as_mut_slice); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `Some(Vec::<()>::new()).as_deref_mut()` error: called `.as_ref().map(|x| x.deref())` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:32:13 + --> tests/ui/option_as_ref_deref.rs:44:13 | LL | let _ = opt.as_ref().map(|x| x.deref()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()` error: called `.as_mut().map(|x| x.deref_mut())` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:33:13 + --> tests/ui/option_as_ref_deref.rs:46:13 | LL | let _ = opt.clone().as_mut().map(|x| x.deref_mut()).map(|x| x.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.clone().as_deref_mut()` error: called `.as_ref().map(|x| &**x)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:40:13 + --> tests/ui/option_as_ref_deref.rs:54:13 | LL | let _ = opt.as_ref().map(|x| &**x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()` error: called `.as_mut().map(|x| &mut **x)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:41:13 + --> tests/ui/option_as_ref_deref.rs:56:13 | LL | let _ = opt.as_mut().map(|x| &mut **x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()` error: called `.as_ref().map(std::ops::Deref::deref)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:44:13 + --> tests/ui/option_as_ref_deref.rs:60:13 | LL | let _ = opt.as_ref().map(std::ops::Deref::deref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()` error: called `.as_ref().map(String::as_str)` on an `Option` value - --> tests/ui/option_as_ref_deref.rs:56:13 + --> tests/ui/option_as_ref_deref.rs:73:13 | LL | let _ = opt.as_ref().map(String::as_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()` diff --git a/tests/ui/option_env_unwrap.rs b/tests/ui/option_env_unwrap.rs index f8d382340f2f..f5e57284df49 100644 --- a/tests/ui/option_env_unwrap.rs +++ b/tests/ui/option_env_unwrap.rs @@ -8,10 +8,17 @@ use proc_macros::{external, inline_macros}; #[inline_macros] fn main() { let _ = option_env!("PATH").unwrap(); + //~^ option_env_unwrap let _ = option_env!("PATH").expect("environment variable PATH isn't set"); + //~^ option_env_unwrap let _ = option_env!("__Y__do_not_use").unwrap(); // This test only works if you don't have a __Y__do_not_use env variable in your environment. + //~^ option_env_unwrap let _ = inline!(option_env!($"PATH").unwrap()); + //~^ option_env_unwrap let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set")); + //~^ option_env_unwrap let _ = external!(option_env!($"PATH").unwrap()); + //~^ option_env_unwrap let _ = external!(option_env!($"PATH").expect($"environment variable PATH isn't set")); + //~^ option_env_unwrap } diff --git a/tests/ui/option_env_unwrap.stderr b/tests/ui/option_env_unwrap.stderr index 169523269fbb..cee0fe6bf9ae 100644 --- a/tests/ui/option_env_unwrap.stderr +++ b/tests/ui/option_env_unwrap.stderr @@ -9,7 +9,7 @@ LL | let _ = option_env!("PATH").unwrap(); = help: to override `-D warnings` add `#[allow(clippy::option_env_unwrap)]` error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:11:13 + --> tests/ui/option_env_unwrap.rs:12:13 | LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set = help: consider using the `env!` macro instead error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:12:13 + --> tests/ui/option_env_unwrap.rs:14:13 | LL | let _ = option_env!("__Y__do_not_use").unwrap(); // This test only works if you don't have a __Y__do_not_use env variable in your env... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = option_env!("__Y__do_not_use").unwrap(); // This test only work = help: consider using the `env!` macro instead error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:13:21 + --> tests/ui/option_env_unwrap.rs:16:21 | LL | let _ = inline!(option_env!($"PATH").unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = inline!(option_env!($"PATH").unwrap()); = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:14:21 + --> tests/ui/option_env_unwrap.rs:18:21 | LL | let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL | let _ = inline!(option_env!($"PATH").expect($"environment variable PATH = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:15:13 + --> tests/ui/option_env_unwrap.rs:20:13 | LL | let _ = external!(option_env!($"PATH").unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | let _ = external!(option_env!($"PATH").unwrap()); = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:16:13 + --> tests/ui/option_env_unwrap.rs:22:13 | LL | let _ = external!(option_env!($"PATH").expect($"environment variable PATH isn't set")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/option_filter_map.fixed b/tests/ui/option_filter_map.fixed index b1c3cfa48a44..d8d3ba7edd28 100644 --- a/tests/ui/option_filter_map.fixed +++ b/tests/ui/option_filter_map.fixed @@ -3,18 +3,24 @@ fn main() { let _ = Some(Some(1)).flatten(); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = Some(Some(1)).flatten(); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = Some(1).map(odds_out).flatten(); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = Some(1).map(odds_out).flatten(); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = vec![Some(1)].into_iter().flatten(); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = vec![Some(1)].into_iter().flatten(); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = vec![1] .into_iter() .map(odds_out) diff --git a/tests/ui/option_filter_map.rs b/tests/ui/option_filter_map.rs index 2550b9cd2b36..68abaff01b44 100644 --- a/tests/ui/option_filter_map.rs +++ b/tests/ui/option_filter_map.rs @@ -3,29 +3,37 @@ fn main() { let _ = Some(Some(1)).filter(Option::is_some).map(Option::unwrap); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = Some(Some(1)).filter(|o| o.is_some()).map(|o| o.unwrap()); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = Some(1).map(odds_out).filter(Option::is_some).map(Option::unwrap); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = Some(1).map(odds_out).filter(|o| o.is_some()).map(|o| o.unwrap()); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = vec![Some(1)].into_iter().filter(Option::is_some).map(Option::unwrap); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = vec![Some(1)].into_iter().filter(|o| o.is_some()).map(|o| o.unwrap()); - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + let _ = vec![1] .into_iter() .map(odds_out) .filter(Option::is_some) - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + .map(Option::unwrap); let _ = vec![1] .into_iter() .map(odds_out) .filter(|o| o.is_some()) - //~^ ERROR: `filter` for `Some` followed by `unwrap` + //~^ option_filter_map + .map(|o| o.unwrap()); } diff --git a/tests/ui/option_filter_map.stderr b/tests/ui/option_filter_map.stderr index 401ac2b2296d..24a3a2d7605c 100644 --- a/tests/ui/option_filter_map.stderr +++ b/tests/ui/option_filter_map.stderr @@ -8,50 +8,50 @@ LL | let _ = Some(Some(1)).filter(Option::is_some).map(Option::unwrap); = help: to override `-D warnings` add `#[allow(clippy::option_filter_map)]` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:7:27 + --> tests/ui/option_filter_map.rs:8:27 | LL | let _ = Some(Some(1)).filter(|o| o.is_some()).map(|o| o.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:9:35 + --> tests/ui/option_filter_map.rs:11:35 | LL | let _ = Some(1).map(odds_out).filter(Option::is_some).map(Option::unwrap); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:11:35 + --> tests/ui/option_filter_map.rs:14:35 | LL | let _ = Some(1).map(odds_out).filter(|o| o.is_some()).map(|o| o.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:14:39 + --> tests/ui/option_filter_map.rs:18:39 | LL | let _ = vec![Some(1)].into_iter().filter(Option::is_some).map(Option::unwrap); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:16:39 + --> tests/ui/option_filter_map.rs:21:39 | LL | let _ = vec![Some(1)].into_iter().filter(|o| o.is_some()).map(|o| o.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:21:10 + --> tests/ui/option_filter_map.rs:27:10 | LL | .filter(Option::is_some) | __________^ -LL | | +... | LL | | .map(Option::unwrap); | |____________________________^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:27:10 + --> tests/ui/option_filter_map.rs:34:10 | LL | .filter(|o| o.is_some()) | __________^ -LL | | +... | LL | | .map(|o| o.unwrap()); | |____________________________^ help: consider using `flatten` instead: `flatten()` diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index 0ac89bf0d8ea..eb1aabe63e75 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -24,17 +24,23 @@ fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { fn unop_bad(string: &Option<&str>, mut num: Option) { let _ = string.map_or(0, |s| s.len()); + //~^ option_if_let_else let _ = num.as_ref().map_or(&0, |s| s); + //~^ option_if_let_else let _ = num.as_mut().map_or(&0, |s| { + //~^ option_if_let_else *s += 1; s }); let _ = num.as_ref().map_or(&0, |s| s); + //~^ option_if_let_else let _ = num.map_or(0, |mut s| { + //~^ option_if_let_else s += 1; s }); let _ = num.as_mut().map_or(&0, |s| { + //~^ option_if_let_else *s += 1; s }); @@ -42,6 +48,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { fn longer_body(arg: Option) -> u32 { arg.map_or(13, |x| { + //~^ option_if_let_else let y = x * x; y * y }) @@ -98,6 +105,7 @@ fn test_result_impure_else(variable: Result) -> bool { println!("Err"); false }, |binding| { + //~^ option_if_let_else println!("Ok {binding}"); true }) @@ -119,6 +127,7 @@ fn complex_subpat() -> DummyEnum { fn main() { let optional = Some(5); let _ = optional.map_or(5, |x| x + 2); + //~^ option_if_let_else let _ = bad1(None); let _ = else_if_option(None); unop_bad(&None, None); @@ -153,10 +162,12 @@ fn main() { let s = String::new(); // Lint, both branches immutably borrow `s`. let _ = Some(0).map_or(s.len(), |x| s.len() + x); + //~^ option_if_let_else let s = String::new(); // Lint, `Some` branch consumes `s`, but else branch doesn't use `s`. let _ = Some(0).map_or(1, |x| { + //~^ option_if_let_else let s = s; s.len() + x }); @@ -200,6 +211,7 @@ fn main() { let _ = res.map_or(1, |a| a + 1); let _ = res.map_or(1, |a| a + 1); let _ = res.map_or(5, |a| a + 1); + //~^ option_if_let_else } #[allow(dead_code)] @@ -243,6 +255,7 @@ fn issue11429() { let mut _hashmap = opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone()); let mut _hm = opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone()); + //~^ option_if_let_else } fn issue11893() { diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index b4f1b2cd1f7f..f2e2de02a93d 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -10,6 +10,7 @@ fn bad1(string: Option<&str>) -> (bool, &str) { if let Some(x) = string { + //~^ option_if_let_else (true, x) } else { (false, "hello") @@ -28,21 +29,27 @@ fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { fn unop_bad(string: &Option<&str>, mut num: Option) { let _ = if let Some(s) = *string { s.len() } else { 0 }; + //~^ option_if_let_else let _ = if let Some(s) = &num { s } else { &0 }; + //~^ option_if_let_else let _ = if let Some(s) = &mut num { + //~^ option_if_let_else *s += 1; s } else { &0 }; let _ = if let Some(ref s) = num { s } else { &0 }; + //~^ option_if_let_else let _ = if let Some(mut s) = num { + //~^ option_if_let_else s += 1; s } else { 0 }; let _ = if let Some(ref mut s) = num { + //~^ option_if_let_else *s += 1; s } else { @@ -52,6 +59,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { fn longer_body(arg: Option) -> u32 { if let Some(x) = arg { + //~^ option_if_let_else let y = x * x; y * y } else { @@ -65,6 +73,7 @@ fn impure_else(arg: Option) { 1 }; let _ = if let Some(x) = arg { + //~^ option_if_let_else x } else { // map_or_else must be suggested @@ -74,6 +83,7 @@ fn impure_else(arg: Option) { fn test_map_or_else(arg: Option) { let _ = if let Some(x) = arg { + //~^ option_if_let_else x * x * x * x } else { let mut y = 1; @@ -107,6 +117,7 @@ fn pattern_to_vec(pattern: &str) -> Vec { .split('/') .flat_map(|s| { if let Some(idx) = s.find('.') { + //~^ option_if_let_else vec![s[..idx].to_string(), s[idx..].to_string()] } else { vec![s.to_string()] @@ -118,6 +129,7 @@ fn pattern_to_vec(pattern: &str) -> Vec { // #10335 fn test_result_impure_else(variable: Result) -> bool { if let Ok(binding) = variable { + //~^ option_if_let_else println!("Ok {binding}"); true } else { @@ -142,6 +154,7 @@ fn complex_subpat() -> DummyEnum { fn main() { let optional = Some(5); let _ = if let Some(x) = optional { x + 2 } else { 5 }; + //~^ option_if_let_else let _ = bad1(None); let _ = else_if_option(None); unop_bad(&None, None); @@ -152,6 +165,7 @@ fn main() { let _ = impure_else(None); let _ = if let Some(x) = Some(0) { + //~^ option_if_let_else loop { if x == 0 { break x; @@ -180,10 +194,12 @@ fn main() { let s = String::new(); // Lint, both branches immutably borrow `s`. let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() }; + //~^ option_if_let_else let s = String::new(); // Lint, `Some` branch consumes `s`, but else branch doesn't use `s`. let _ = if let Some(x) = Some(0) { + //~^ option_if_let_else let s = s; s.len() + x } else { @@ -223,24 +239,29 @@ fn main() { // issue #8492 let _ = match s { + //~^ option_if_let_else Some(string) => string.len(), None => 1, }; let _ = match Some(10) { + //~^ option_if_let_else Some(a) => a + 1, None => 5, }; let res: Result = Ok(5); let _ = match res { + //~^ option_if_let_else Ok(a) => a + 1, _ => 1, }; let _ = match res { + //~^ option_if_let_else Err(_) => 1, Ok(a) => a + 1, }; let _ = if let Ok(a) = res { a + 1 } else { 5 }; + //~^ option_if_let_else } #[allow(dead_code)] @@ -258,6 +279,7 @@ mod issue10729 { pub fn reproduce(initial: &Option) { // 👇 needs `.as_ref()` because initial is an `&Option<_>` let _ = match initial { + //~^ option_if_let_else Some(value) => do_something(value), None => 42, }; @@ -265,6 +287,7 @@ mod issue10729 { pub fn reproduce2(initial: &mut Option) { let _ = match initial { + //~^ option_if_let_else Some(value) => do_something2(value), None => 42, }; @@ -288,12 +311,14 @@ fn issue11429() { let opt: Option> = None; let mut _hashmap = if let Some(hm) = &opt { + //~^ option_if_let_else hm.clone() } else { HashMap::new() }; let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; + //~^ option_if_let_else } fn issue11893() { diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index 32ff22763234..f872ac991840 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -2,6 +2,7 @@ error: use Option::map_or instead of an if let/else --> tests/ui/option_if_let_else.rs:12:5 | LL | / if let Some(x) = string { +LL | | LL | | (true, x) LL | | } else { LL | | (false, "hello") @@ -12,22 +13,23 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:30:13 + --> tests/ui/option_if_let_else.rs:31:13 | LL | let _ = if let Some(s) = *string { s.len() } else { 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:31:13 + --> tests/ui/option_if_let_else.rs:33:13 | LL | let _ = if let Some(s) = &num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:32:13 + --> tests/ui/option_if_let_else.rs:35:13 | LL | let _ = if let Some(s) = &mut num { | _____________^ +LL | | LL | | *s += 1; LL | | s LL | | } else { @@ -38,22 +40,24 @@ LL | | }; help: try | LL ~ let _ = num.as_mut().map_or(&0, |s| { +LL + LL + *s += 1; LL + s LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:38:13 + --> tests/ui/option_if_let_else.rs:42:13 | LL | let _ = if let Some(ref s) = num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:39:13 + --> tests/ui/option_if_let_else.rs:44:13 | LL | let _ = if let Some(mut s) = num { | _____________^ +LL | | LL | | s += 1; LL | | s LL | | } else { @@ -64,16 +68,18 @@ LL | | }; help: try | LL ~ let _ = num.map_or(0, |mut s| { +LL + LL + s += 1; LL + s LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:45:13 + --> tests/ui/option_if_let_else.rs:51:13 | LL | let _ = if let Some(ref mut s) = num { | _____________^ +LL | | LL | | *s += 1; LL | | s LL | | } else { @@ -84,15 +90,17 @@ LL | | }; help: try | LL ~ let _ = num.as_mut().map_or(&0, |s| { +LL + LL + *s += 1; LL + s LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:54:5 + --> tests/ui/option_if_let_else.rs:61:5 | LL | / if let Some(x) = arg { +LL | | LL | | let y = x * x; LL | | y * y LL | | } else { @@ -103,30 +111,33 @@ LL | | } help: try | LL ~ arg.map_or(13, |x| { +LL + LL + let y = x * x; LL + y * y LL + }) | error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:67:13 + --> tests/ui/option_if_let_else.rs:75:13 | LL | let _ = if let Some(x) = arg { | _____________^ +LL | | LL | | x LL | | } else { -... | +LL | | // map_or_else must be suggested +LL | | side_effect() LL | | }; | |_____^ help: try: `arg.map_or_else(side_effect, |x| x)` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:76:13 + --> tests/ui/option_if_let_else.rs:85:13 | LL | let _ = if let Some(x) = arg { | _____________^ +LL | | LL | | x * x * x * x LL | | } else { -LL | | let mut y = 1; ... | LL | | y LL | | }; @@ -143,9 +154,10 @@ LL ~ }, |x| x * x * x * x); | error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:109:13 + --> tests/ui/option_if_let_else.rs:119:13 | LL | / if let Some(idx) = s.find('.') { +LL | | LL | | vec![s[..idx].to_string(), s[idx..].to_string()] LL | | } else { LL | | vec![s.to_string()] @@ -153,13 +165,13 @@ LL | | } | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:120:5 + --> tests/ui/option_if_let_else.rs:131:5 | LL | / if let Ok(binding) = variable { +LL | | LL | | println!("Ok {binding}"); LL | | true -LL | | } else { -LL | | println!("Err"); +... | LL | | false LL | | } | |_____^ @@ -170,25 +182,26 @@ LL ~ variable.map_or_else(|_| { LL + println!("Err"); LL + false LL + }, |binding| { +LL + LL + println!("Ok {binding}"); LL + true LL + }) | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:144:13 + --> tests/ui/option_if_let_else.rs:156:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:154:13 + --> tests/ui/option_if_let_else.rs:167:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ +LL | | LL | | loop { LL | | if x == 0 { -LL | | break x; ... | LL | | 0 LL | | }; @@ -204,16 +217,17 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:182:13 + --> tests/ui/option_if_let_else.rs:196:13 | LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:186:13 + --> tests/ui/option_if_let_else.rs:201:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ +LL | | LL | | let s = s; LL | | s.len() + x LL | | } else { @@ -224,82 +238,90 @@ LL | | }; help: try | LL ~ let _ = Some(0).map_or(1, |x| { +LL + LL + let s = s; LL + s.len() + x LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:225:13 + --> tests/ui/option_if_let_else.rs:241:13 | LL | let _ = match s { | _____________^ +LL | | LL | | Some(string) => string.len(), LL | | None => 1, LL | | }; | |_____^ help: try: `s.map_or(1, |string| string.len())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:229:13 + --> tests/ui/option_if_let_else.rs:246:13 | LL | let _ = match Some(10) { | _____________^ +LL | | LL | | Some(a) => a + 1, LL | | None => 5, LL | | }; | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:235:13 + --> tests/ui/option_if_let_else.rs:253:13 | LL | let _ = match res { | _____________^ +LL | | LL | | Ok(a) => a + 1, LL | | _ => 1, LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:239:13 + --> tests/ui/option_if_let_else.rs:258:13 | LL | let _ = match res { | _____________^ +LL | | LL | | Err(_) => 1, LL | | Ok(a) => a + 1, LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:243:13 + --> tests/ui/option_if_let_else.rs:263:13 | LL | let _ = if let Ok(a) = res { a + 1 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:260:17 + --> tests/ui/option_if_let_else.rs:281:17 | LL | let _ = match initial { | _________________^ +LL | | LL | | Some(value) => do_something(value), LL | | None => 42, LL | | }; | |_________^ help: try: `initial.as_ref().map_or(42, |value| do_something(value))` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:267:17 + --> tests/ui/option_if_let_else.rs:289:17 | LL | let _ = match initial { | _________________^ +LL | | LL | | Some(value) => do_something2(value), LL | | None => 42, LL | | }; | |_________^ help: try: `initial.as_mut().map_or(42, |value| do_something2(value))` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:290:24 + --> tests/ui/option_if_let_else.rs:313:24 | LL | let mut _hashmap = if let Some(hm) = &opt { | ________________________^ +LL | | LL | | hm.clone() LL | | } else { LL | | HashMap::new() @@ -307,7 +329,7 @@ LL | | }; | |_____^ help: try: `opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone())` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:296:19 + --> tests/ui/option_if_let_else.rs:320:19 | LL | let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())` diff --git a/tests/ui/option_map_or_none.fixed b/tests/ui/option_map_or_none.fixed index 5f0ef34d231c..c4d9f25bd28c 100644 --- a/tests/ui/option_map_or_none.fixed +++ b/tests/ui/option_map_or_none.fixed @@ -8,12 +8,15 @@ fn main() { // Check `OPTION_MAP_OR_NONE`. // Single line case. let _: Option = opt.map(|x| x + 1); + //~^ option_map_or_none // Multi-line case. #[rustfmt::skip] let _: Option = opt.map(|x| x + 1); // function returning `Option` let _: Option = opt.and_then(bar); + //~^ option_map_or_none let _: Option = opt.and_then(|x| { + //~^ option_map_or_none let offset = 0; let height = x; Some(offset + height) @@ -21,4 +24,5 @@ fn main() { // Check `RESULT_MAP_OR_INTO_OPTION`. let _: Option = r.ok(); + //~^ result_map_or_into_option } diff --git a/tests/ui/option_map_or_none.rs b/tests/ui/option_map_or_none.rs index 56b1f61212d0..c3143f50cb6c 100644 --- a/tests/ui/option_map_or_none.rs +++ b/tests/ui/option_map_or_none.rs @@ -8,14 +8,18 @@ fn main() { // Check `OPTION_MAP_OR_NONE`. // Single line case. let _: Option = opt.map_or(None, |x| Some(x + 1)); + //~^ option_map_or_none // Multi-line case. #[rustfmt::skip] let _: Option = opt.map_or(None, |x| { + //~^ option_map_or_none Some(x + 1) }); // function returning `Option` let _: Option = opt.map_or(None, bar); + //~^ option_map_or_none let _: Option = opt.map_or(None, |x| { + //~^ option_map_or_none let offset = 0; let height = x; Some(offset + height) @@ -23,4 +27,5 @@ fn main() { // Check `RESULT_MAP_OR_INTO_OPTION`. let _: Option = r.map_or(None, Some); + //~^ result_map_or_into_option } diff --git a/tests/ui/option_map_or_none.stderr b/tests/ui/option_map_or_none.stderr index cba29861296f..f9290fb99bc1 100644 --- a/tests/ui/option_map_or_none.stderr +++ b/tests/ui/option_map_or_none.stderr @@ -8,25 +8,27 @@ LL | let _: Option = opt.map_or(None, |x| Some(x + 1)); = help: to override `-D warnings` add `#[allow(clippy::option_map_or_none)]` error: called `map_or(None, ..)` on an `Option` value - --> tests/ui/option_map_or_none.rs:13:26 + --> tests/ui/option_map_or_none.rs:14:26 | LL | let _: Option = opt.map_or(None, |x| { | __________________________^ +LL | | LL | | Some(x + 1) LL | | }); | |_________________________^ help: consider using `map`: `opt.map(|x| x + 1)` error: called `map_or(None, ..)` on an `Option` value - --> tests/ui/option_map_or_none.rs:17:26 + --> tests/ui/option_map_or_none.rs:19:26 | LL | let _: Option = opt.map_or(None, bar); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `and_then`: `opt.and_then(bar)` error: called `map_or(None, ..)` on an `Option` value - --> tests/ui/option_map_or_none.rs:18:26 + --> tests/ui/option_map_or_none.rs:21:26 | LL | let _: Option = opt.map_or(None, |x| { | __________________________^ +LL | | LL | | let offset = 0; LL | | let height = x; LL | | Some(offset + height) @@ -36,6 +38,7 @@ LL | | }); help: consider using `and_then` | LL ~ let _: Option = opt.and_then(|x| { +LL + LL + let offset = 0; LL + let height = x; LL + Some(offset + height) @@ -43,7 +46,7 @@ LL ~ }); | error: called `map_or(None, Some)` on a `Result` value - --> tests/ui/option_map_or_none.rs:25:26 + --> tests/ui/option_map_or_none.rs:29:26 | LL | let _: Option = r.map_or(None, Some); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `r.ok()` diff --git a/tests/ui/option_map_unit_fn_fixable.fixed b/tests/ui/option_map_unit_fn_fixable.fixed index 5dcc6464ff5f..55c1b8f110ce 100644 --- a/tests/ui/option_map_unit_fn_fixable.fixed +++ b/tests/ui/option_map_unit_fn_fixable.fixed @@ -35,52 +35,71 @@ fn option_map_unit_fn() { let _ : Option<()> = x.field.map(do_nothing); if let Some(x_field) = x.field { do_nothing(x_field) } + //~^ option_map_unit_fn if let Some(x_field) = x.field { do_nothing(x_field) } + //~^ option_map_unit_fn if let Some(x_field) = x.field { diverge(x_field) } + //~^ option_map_unit_fn let captured = 10; if let Some(value) = x.field { do_nothing(value + captured) }; let _ : Option<()> = x.field.map(|value| do_nothing(value + captured)); if let Some(value) = x.field { x.do_option_nothing(value + captured) } + //~^ option_map_unit_fn if let Some(value) = x.field { x.do_option_plus_one(value + captured); } + //~^ option_map_unit_fn if let Some(value) = x.field { do_nothing(value + captured) } + //~^ option_map_unit_fn if let Some(value) = x.field { do_nothing(value + captured) } + //~^ option_map_unit_fn if let Some(value) = x.field { do_nothing(value + captured); } + //~^ option_map_unit_fn if let Some(value) = x.field { do_nothing(value + captured); } + //~^ option_map_unit_fn if let Some(value) = x.field { diverge(value + captured) } + //~^ option_map_unit_fn if let Some(value) = x.field { diverge(value + captured) } + //~^ option_map_unit_fn if let Some(value) = x.field { diverge(value + captured); } + //~^ option_map_unit_fn if let Some(value) = x.field { diverge(value + captured); } + //~^ option_map_unit_fn x.field.map(|value| plus_one(value + captured)); x.field.map(|value| { plus_one(value + captured) }); if let Some(value) = x.field { let y = plus_one(value + captured); } + //~^ option_map_unit_fn if let Some(value) = x.field { plus_one(value + captured); } + //~^ option_map_unit_fn if let Some(value) = x.field { plus_one(value + captured); } + //~^ option_map_unit_fn if let Some(ref value) = x.field { do_nothing(value + captured) } + //~^ option_map_unit_fn if let Some(a) = option() { do_nothing(a) } + //~^ option_map_unit_fn if let Some(value) = option() { println!("{:?}", value) } + //~^ option_map_unit_fn } fn main() {} diff --git a/tests/ui/option_map_unit_fn_fixable.rs b/tests/ui/option_map_unit_fn_fixable.rs index 5489545fe3d9..5ed47e4c60b5 100644 --- a/tests/ui/option_map_unit_fn_fixable.rs +++ b/tests/ui/option_map_unit_fn_fixable.rs @@ -35,52 +35,71 @@ fn option_map_unit_fn() { let _ : Option<()> = x.field.map(do_nothing); x.field.map(do_nothing); + //~^ option_map_unit_fn x.field.map(do_nothing); + //~^ option_map_unit_fn x.field.map(diverge); + //~^ option_map_unit_fn let captured = 10; if let Some(value) = x.field { do_nothing(value + captured) }; let _ : Option<()> = x.field.map(|value| do_nothing(value + captured)); x.field.map(|value| x.do_option_nothing(value + captured)); + //~^ option_map_unit_fn x.field.map(|value| { x.do_option_plus_one(value + captured); }); + //~^ option_map_unit_fn x.field.map(|value| do_nothing(value + captured)); + //~^ option_map_unit_fn x.field.map(|value| { do_nothing(value + captured) }); + //~^ option_map_unit_fn x.field.map(|value| { do_nothing(value + captured); }); + //~^ option_map_unit_fn x.field.map(|value| { { do_nothing(value + captured); } }); + //~^ option_map_unit_fn x.field.map(|value| diverge(value + captured)); + //~^ option_map_unit_fn x.field.map(|value| { diverge(value + captured) }); + //~^ option_map_unit_fn x.field.map(|value| { diverge(value + captured); }); + //~^ option_map_unit_fn x.field.map(|value| { { diverge(value + captured); } }); + //~^ option_map_unit_fn x.field.map(|value| plus_one(value + captured)); x.field.map(|value| { plus_one(value + captured) }); x.field.map(|value| { let y = plus_one(value + captured); }); + //~^ option_map_unit_fn x.field.map(|value| { plus_one(value + captured); }); + //~^ option_map_unit_fn x.field.map(|value| { { plus_one(value + captured); } }); + //~^ option_map_unit_fn x.field.map(|ref value| { do_nothing(value + captured) }); + //~^ option_map_unit_fn option().map(do_nothing); + //~^ option_map_unit_fn option().map(|value| println!("{:?}", value)); + //~^ option_map_unit_fn } fn main() {} diff --git a/tests/ui/option_map_unit_fn_fixable.stderr b/tests/ui/option_map_unit_fn_fixable.stderr index 5fd3dfd071c2..3f7abae34eea 100644 --- a/tests/ui/option_map_unit_fn_fixable.stderr +++ b/tests/ui/option_map_unit_fn_fixable.stderr @@ -10,7 +10,7 @@ LL | x.field.map(do_nothing); = help: to override `-D warnings` add `#[allow(clippy::option_map_unit_fn)]` error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:39:5 + --> tests/ui/option_map_unit_fn_fixable.rs:40:5 | LL | x.field.map(do_nothing); | ^^^^^^^^^^^^^^^^^^^^^^^- @@ -18,7 +18,7 @@ LL | x.field.map(do_nothing); | help: try: `if let Some(x_field) = x.field { do_nothing(x_field) }` error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:41:5 + --> tests/ui/option_map_unit_fn_fixable.rs:43:5 | LL | x.field.map(diverge); | ^^^^^^^^^^^^^^^^^^^^- @@ -26,7 +26,7 @@ LL | x.field.map(diverge); | help: try: `if let Some(x_field) = x.field { diverge(x_field) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:47:5 + --> tests/ui/option_map_unit_fn_fixable.rs:50:5 | LL | x.field.map(|value| x.do_option_nothing(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -34,7 +34,7 @@ LL | x.field.map(|value| x.do_option_nothing(value + captured)); | help: try: `if let Some(value) = x.field { x.do_option_nothing(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:49:5 + --> tests/ui/option_map_unit_fn_fixable.rs:53:5 | LL | x.field.map(|value| { x.do_option_plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -42,7 +42,7 @@ LL | x.field.map(|value| { x.do_option_plus_one(value + captured); }); | help: try: `if let Some(value) = x.field { x.do_option_plus_one(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:52:5 + --> tests/ui/option_map_unit_fn_fixable.rs:57:5 | LL | x.field.map(|value| do_nothing(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -50,7 +50,7 @@ LL | x.field.map(|value| do_nothing(value + captured)); | help: try: `if let Some(value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:54:5 + --> tests/ui/option_map_unit_fn_fixable.rs:60:5 | LL | x.field.map(|value| { do_nothing(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -58,7 +58,7 @@ LL | x.field.map(|value| { do_nothing(value + captured) }); | help: try: `if let Some(value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:56:5 + --> tests/ui/option_map_unit_fn_fixable.rs:63:5 | LL | x.field.map(|value| { do_nothing(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -66,7 +66,7 @@ LL | x.field.map(|value| { do_nothing(value + captured); }); | help: try: `if let Some(value) = x.field { do_nothing(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:58:5 + --> tests/ui/option_map_unit_fn_fixable.rs:66:5 | LL | x.field.map(|value| { { do_nothing(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -74,7 +74,7 @@ LL | x.field.map(|value| { { do_nothing(value + captured); } }); | help: try: `if let Some(value) = x.field { do_nothing(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:61:5 + --> tests/ui/option_map_unit_fn_fixable.rs:70:5 | LL | x.field.map(|value| diverge(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -82,7 +82,7 @@ LL | x.field.map(|value| diverge(value + captured)); | help: try: `if let Some(value) = x.field { diverge(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:63:5 + --> tests/ui/option_map_unit_fn_fixable.rs:73:5 | LL | x.field.map(|value| { diverge(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -90,7 +90,7 @@ LL | x.field.map(|value| { diverge(value + captured) }); | help: try: `if let Some(value) = x.field { diverge(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:65:5 + --> tests/ui/option_map_unit_fn_fixable.rs:76:5 | LL | x.field.map(|value| { diverge(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -98,7 +98,7 @@ LL | x.field.map(|value| { diverge(value + captured); }); | help: try: `if let Some(value) = x.field { diverge(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:67:5 + --> tests/ui/option_map_unit_fn_fixable.rs:79:5 | LL | x.field.map(|value| { { diverge(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -106,7 +106,7 @@ LL | x.field.map(|value| { { diverge(value + captured); } }); | help: try: `if let Some(value) = x.field { diverge(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:72:5 + --> tests/ui/option_map_unit_fn_fixable.rs:85:5 | LL | x.field.map(|value| { let y = plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -114,7 +114,7 @@ LL | x.field.map(|value| { let y = plus_one(value + captured); }); | help: try: `if let Some(value) = x.field { let y = plus_one(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:74:5 + --> tests/ui/option_map_unit_fn_fixable.rs:88:5 | LL | x.field.map(|value| { plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -122,7 +122,7 @@ LL | x.field.map(|value| { plus_one(value + captured); }); | help: try: `if let Some(value) = x.field { plus_one(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:76:5 + --> tests/ui/option_map_unit_fn_fixable.rs:91:5 | LL | x.field.map(|value| { { plus_one(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -130,7 +130,7 @@ LL | x.field.map(|value| { { plus_one(value + captured); } }); | help: try: `if let Some(value) = x.field { plus_one(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:79:5 + --> tests/ui/option_map_unit_fn_fixable.rs:95:5 | LL | x.field.map(|ref value| { do_nothing(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -138,7 +138,7 @@ LL | x.field.map(|ref value| { do_nothing(value + captured) }); | help: try: `if let Some(ref value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:81:5 + --> tests/ui/option_map_unit_fn_fixable.rs:98:5 | LL | option().map(do_nothing); | ^^^^^^^^^^^^^^^^^^^^^^^^- @@ -146,7 +146,7 @@ LL | option().map(do_nothing); | help: try: `if let Some(a) = option() { do_nothing(a) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` - --> tests/ui/option_map_unit_fn_fixable.rs:83:5 + --> tests/ui/option_map_unit_fn_fixable.rs:101:5 | LL | option().map(|value| println!("{:?}", value)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- diff --git a/tests/ui/option_map_unit_fn_unfixable.rs b/tests/ui/option_map_unit_fn_unfixable.rs index 20e6c15b18d5..dd2f80fefbee 100644 --- a/tests/ui/option_map_unit_fn_unfixable.rs +++ b/tests/ui/option_map_unit_fn_unfixable.rs @@ -15,8 +15,10 @@ fn plus_one(value: usize) -> usize { fn option_map_unit_fn() { x.field.map(|value| { do_nothing(value); do_nothing(value) }); + //~^ ERROR: cannot find value x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) }); + //~^ ERROR: cannot find value // Suggestion for the let block should be `{ ... }` as it's too difficult to build a // proper suggestion for these cases @@ -24,7 +26,9 @@ fn option_map_unit_fn() { do_nothing(value); do_nothing(value) }); + //~^^^^ ERROR: cannot find value x.field.map(|value| { do_nothing(value); do_nothing(value); }); + //~^ ERROR: cannot find value // The following should suggest `if let Some(_X) ...` as it's difficult to generate a proper let variable name for them Some(42).map(diverge); diff --git a/tests/ui/option_map_unit_fn_unfixable.stderr b/tests/ui/option_map_unit_fn_unfixable.stderr index 66271036113c..852785014329 100644 --- a/tests/ui/option_map_unit_fn_unfixable.stderr +++ b/tests/ui/option_map_unit_fn_unfixable.stderr @@ -5,19 +5,19 @@ LL | x.field.map(|value| { do_nothing(value); do_nothing(value) }); | ^ not found in this scope error[E0425]: cannot find value `x` in this scope - --> tests/ui/option_map_unit_fn_unfixable.rs:19:5 + --> tests/ui/option_map_unit_fn_unfixable.rs:20:5 | LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) }); | ^ not found in this scope error[E0425]: cannot find value `x` in this scope - --> tests/ui/option_map_unit_fn_unfixable.rs:23:5 + --> tests/ui/option_map_unit_fn_unfixable.rs:25:5 | LL | x.field.map(|value| { | ^ not found in this scope error[E0425]: cannot find value `x` in this scope - --> tests/ui/option_map_unit_fn_unfixable.rs:27:5 + --> tests/ui/option_map_unit_fn_unfixable.rs:30:5 | LL | x.field.map(|value| { do_nothing(value); do_nothing(value); }); | ^ not found in this scope diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed index 625d654dd396..73ba4394e983 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -50,61 +50,80 @@ fn or_fun_call() { let with_constructor = Some(vec![1]); with_constructor.unwrap_or_else(make); + //~^ or_fun_call let with_new = Some(vec![1]); with_new.unwrap_or_default(); + //~^ unwrap_or_default let with_const_args = Some(vec![1]); with_const_args.unwrap_or_else(|| Vec::with_capacity(12)); + //~^ or_fun_call let with_err: Result<_, ()> = Ok(vec![1]); with_err.unwrap_or_else(|_| make()); + //~^ or_fun_call let with_err_args: Result<_, ()> = Ok(vec![1]); with_err_args.unwrap_or_else(|_| Vec::with_capacity(12)); + //~^ or_fun_call let with_default_trait = Some(1); with_default_trait.unwrap_or_default(); + //~^ unwrap_or_default let with_default_type = Some(1); with_default_type.unwrap_or_default(); + //~^ unwrap_or_default let self_default = None::; self_default.unwrap_or_else(::default); + //~^ or_fun_call let real_default = None::; real_default.unwrap_or_default(); + //~^ unwrap_or_default let with_vec = Some(vec![1]); with_vec.unwrap_or_default(); + //~^ unwrap_or_default let without_default = Some(Foo); without_default.unwrap_or_else(Foo::new); + //~^ or_fun_call let mut map = HashMap::::new(); map.entry(42).or_default(); + //~^ unwrap_or_default let mut map_vec = HashMap::>::new(); map_vec.entry(42).or_default(); + //~^ unwrap_or_default let mut btree = BTreeMap::::new(); btree.entry(42).or_default(); + //~^ unwrap_or_default let mut btree_vec = BTreeMap::>::new(); btree_vec.entry(42).or_default(); + //~^ unwrap_or_default let stringy = Some(String::new()); let _ = stringy.unwrap_or_default(); + //~^ unwrap_or_default let opt = Some(1); let hello = "Hello"; let _ = opt.ok_or_else(|| format!("{} world.", hello)); + //~^ or_fun_call // index let map = HashMap::::new(); let _ = Some(1).unwrap_or_else(|| map[&1]); + //~^ or_fun_call let map = BTreeMap::::new(); let _ = Some(1).unwrap_or_else(|| map[&1]); + //~^ or_fun_call // don't lint index vec let vec = vec![1]; let _ = Some(1).unwrap_or(vec[1]); @@ -129,6 +148,7 @@ fn test_or_with_ctors() { let _ = opt.or(Some(two)); let _ = Some("a".to_string()).or_else(|| Some("b".to_string())); + //~^ or_fun_call let b = "b".to_string(); let _ = Some(Bar("a".to_string(), Duration::from_secs(1))) @@ -168,14 +188,17 @@ mod issue6675 { let s = "test".to_owned(); let s = &s as *const _; None.unwrap_or_else(|| ptr_to_ref(s)); + //~^ or_fun_call } fn bar() { let s = "test".to_owned(); let s = &s as *const _; None.unwrap_or_else(|| unsafe { ptr_to_ref(s) }); + //~^ or_fun_call #[rustfmt::skip] None.unwrap_or_else(|| unsafe { ptr_to_ref(s) }); + //~^ or_fun_call } } @@ -251,7 +274,9 @@ mod issue8993 { fn test_map_or() { let _ = Some(4).map_or_else(g, |v| v); + //~^ or_fun_call let _ = Some(4).map_or_else(g, f); + //~^ or_fun_call let _ = Some(4).map_or(0, f); } } @@ -283,24 +308,31 @@ mod lazy { let with_new = Some(vec![1]); with_new.unwrap_or_default(); + //~^ unwrap_or_default let with_default_trait = Some(1); with_default_trait.unwrap_or_default(); + //~^ unwrap_or_default let with_default_type = Some(1); with_default_type.unwrap_or_default(); + //~^ unwrap_or_default let real_default = None::; real_default.unwrap_or_default(); + //~^ unwrap_or_default let mut map = HashMap::::new(); map.entry(42).or_default(); + //~^ unwrap_or_default let mut btree = BTreeMap::::new(); btree.entry(42).or_default(); + //~^ unwrap_or_default let stringy = Some(String::new()); let _ = stringy.unwrap_or_default(); + //~^ unwrap_or_default // negative tests let self_default = None::; @@ -341,28 +373,34 @@ fn fn_call_in_nested_expr() { } let opt: Option = Some(1); - //~v ERROR: function call inside of `unwrap_or` + let _ = opt.unwrap_or_else(f); // suggest `.unwrap_or_else(f)` + //~^ or_fun_call // - //~v ERROR: function call inside of `unwrap_or` + let _ = opt.unwrap_or_else(|| f() + 1); // suggest `.unwrap_or_else(|| f() + 1)` + //~^ or_fun_call // - //~v ERROR: function call inside of `unwrap_or` + let _ = opt.unwrap_or_else(|| { + //~^ or_fun_call let x = f(); x + 1 }); - //~v ERROR: function call inside of `map_or` + let _ = opt.map_or_else(|| f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)` + //~^ or_fun_call // - //~v ERROR: use of `unwrap_or` to construct default value + let _ = opt.unwrap_or_default(); + //~^ unwrap_or_default let opt_foo = Some(Foo { val: String::from("123"), }); - //~v ERROR: function call inside of `unwrap_or` + let _ = opt_foo.unwrap_or_else(|| Foo { val: String::default() }); + //~^ or_fun_call } fn main() {} diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index 5b7d8faec7bf..ed3469178196 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -50,61 +50,80 @@ fn or_fun_call() { let with_constructor = Some(vec![1]); with_constructor.unwrap_or(make()); + //~^ or_fun_call let with_new = Some(vec![1]); with_new.unwrap_or(Vec::new()); + //~^ unwrap_or_default let with_const_args = Some(vec![1]); with_const_args.unwrap_or(Vec::with_capacity(12)); + //~^ or_fun_call let with_err: Result<_, ()> = Ok(vec![1]); with_err.unwrap_or(make()); + //~^ or_fun_call let with_err_args: Result<_, ()> = Ok(vec![1]); with_err_args.unwrap_or(Vec::with_capacity(12)); + //~^ or_fun_call let with_default_trait = Some(1); with_default_trait.unwrap_or(Default::default()); + //~^ unwrap_or_default let with_default_type = Some(1); with_default_type.unwrap_or(u64::default()); + //~^ unwrap_or_default let self_default = None::; self_default.unwrap_or(::default()); + //~^ or_fun_call let real_default = None::; real_default.unwrap_or(::default()); + //~^ unwrap_or_default let with_vec = Some(vec![1]); with_vec.unwrap_or(vec![]); + //~^ unwrap_or_default let without_default = Some(Foo); without_default.unwrap_or(Foo::new()); + //~^ or_fun_call let mut map = HashMap::::new(); map.entry(42).or_insert(String::new()); + //~^ unwrap_or_default let mut map_vec = HashMap::>::new(); map_vec.entry(42).or_insert(vec![]); + //~^ unwrap_or_default let mut btree = BTreeMap::::new(); btree.entry(42).or_insert(String::new()); + //~^ unwrap_or_default let mut btree_vec = BTreeMap::>::new(); btree_vec.entry(42).or_insert(vec![]); + //~^ unwrap_or_default let stringy = Some(String::new()); let _ = stringy.unwrap_or(String::new()); + //~^ unwrap_or_default let opt = Some(1); let hello = "Hello"; let _ = opt.ok_or(format!("{} world.", hello)); + //~^ or_fun_call // index let map = HashMap::::new(); let _ = Some(1).unwrap_or(map[&1]); + //~^ or_fun_call let map = BTreeMap::::new(); let _ = Some(1).unwrap_or(map[&1]); + //~^ or_fun_call // don't lint index vec let vec = vec![1]; let _ = Some(1).unwrap_or(vec[1]); @@ -129,6 +148,7 @@ fn test_or_with_ctors() { let _ = opt.or(Some(two)); let _ = Some("a".to_string()).or(Some("b".to_string())); + //~^ or_fun_call let b = "b".to_string(); let _ = Some(Bar("a".to_string(), Duration::from_secs(1))) @@ -168,14 +188,17 @@ mod issue6675 { let s = "test".to_owned(); let s = &s as *const _; None.unwrap_or(ptr_to_ref(s)); + //~^ or_fun_call } fn bar() { let s = "test".to_owned(); let s = &s as *const _; None.unwrap_or(unsafe { ptr_to_ref(s) }); + //~^ or_fun_call #[rustfmt::skip] None.unwrap_or( unsafe { ptr_to_ref(s) } ); + //~^ or_fun_call } } @@ -251,7 +274,9 @@ mod issue8993 { fn test_map_or() { let _ = Some(4).map_or(g(), |v| v); + //~^ or_fun_call let _ = Some(4).map_or(g(), f); + //~^ or_fun_call let _ = Some(4).map_or(0, f); } } @@ -283,24 +308,31 @@ mod lazy { let with_new = Some(vec![1]); with_new.unwrap_or_else(Vec::new); + //~^ unwrap_or_default let with_default_trait = Some(1); with_default_trait.unwrap_or_else(Default::default); + //~^ unwrap_or_default let with_default_type = Some(1); with_default_type.unwrap_or_else(u64::default); + //~^ unwrap_or_default let real_default = None::; real_default.unwrap_or_else(::default); + //~^ unwrap_or_default let mut map = HashMap::::new(); map.entry(42).or_insert_with(String::new); + //~^ unwrap_or_default let mut btree = BTreeMap::::new(); btree.entry(42).or_insert_with(String::new); + //~^ unwrap_or_default let stringy = Some(String::new()); let _ = stringy.unwrap_or_else(String::new); + //~^ unwrap_or_default // negative tests let self_default = None::; @@ -341,28 +373,34 @@ fn fn_call_in_nested_expr() { } let opt: Option = Some(1); - //~v ERROR: function call inside of `unwrap_or` + let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)` + //~^ or_fun_call // - //~v ERROR: function call inside of `unwrap_or` + let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)` + //~^ or_fun_call // - //~v ERROR: function call inside of `unwrap_or` + let _ = opt.unwrap_or({ + //~^ or_fun_call let x = f(); x + 1 }); - //~v ERROR: function call inside of `map_or` + let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)` + //~^ or_fun_call // - //~v ERROR: use of `unwrap_or` to construct default value + let _ = opt.unwrap_or({ i32::default() }); + //~^ unwrap_or_default let opt_foo = Some(Foo { val: String::from("123"), }); - //~v ERROR: function call inside of `unwrap_or` + let _ = opt_foo.unwrap_or(Foo { val: String::default() }); + //~^ or_fun_call } fn main() {} diff --git a/tests/ui/or_fun_call.stderr b/tests/ui/or_fun_call.stderr index 9f90a830a211..a1eaf08e4458 100644 --- a/tests/ui/or_fun_call.stderr +++ b/tests/ui/or_fun_call.stderr @@ -8,7 +8,7 @@ LL | with_constructor.unwrap_or(make()); = help: to override `-D warnings` add `#[allow(clippy::or_fun_call)]` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:55:14 + --> tests/ui/or_fun_call.rs:56:14 | LL | with_new.unwrap_or(Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` @@ -17,202 +17,203 @@ LL | with_new.unwrap_or(Vec::new()); = help: to override `-D warnings` add `#[allow(clippy::unwrap_or_default)]` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:58:21 + --> tests/ui/or_fun_call.rs:60:21 | LL | with_const_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Vec::with_capacity(12))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:61:14 + --> tests/ui/or_fun_call.rs:64:14 | LL | with_err.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| make())` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:64:19 + --> tests/ui/or_fun_call.rs:68:19 | LL | with_err_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Vec::with_capacity(12))` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:67:24 + --> tests/ui/or_fun_call.rs:72:24 | LL | with_default_trait.unwrap_or(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:70:23 + --> tests/ui/or_fun_call.rs:76:23 | LL | with_default_type.unwrap_or(u64::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:73:18 + --> tests/ui/or_fun_call.rs:80:18 | LL | self_default.unwrap_or(::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(::default)` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:76:18 + --> tests/ui/or_fun_call.rs:84:18 | LL | real_default.unwrap_or(::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:79:14 + --> tests/ui/or_fun_call.rs:88:14 | LL | with_vec.unwrap_or(vec![]); | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:82:21 + --> tests/ui/or_fun_call.rs:92:21 | LL | without_default.unwrap_or(Foo::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(Foo::new)` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:85:19 + --> tests/ui/or_fun_call.rs:96:19 | LL | map.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:88:23 + --> tests/ui/or_fun_call.rs:100:23 | LL | map_vec.entry(42).or_insert(vec![]); | ^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:91:21 + --> tests/ui/or_fun_call.rs:104:21 | LL | btree.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:94:25 + --> tests/ui/or_fun_call.rs:108:25 | LL | btree_vec.entry(42).or_insert(vec![]); | ^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:97:21 + --> tests/ui/or_fun_call.rs:112:21 | LL | let _ = stringy.unwrap_or(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `ok_or` - --> tests/ui/or_fun_call.rs:101:17 + --> tests/ui/or_fun_call.rs:117:17 | LL | let _ = opt.ok_or(format!("{} world.", hello)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ok_or_else(|| format!("{} world.", hello))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:105:21 + --> tests/ui/or_fun_call.rs:122:21 | LL | let _ = Some(1).unwrap_or(map[&1]); | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:107:21 + --> tests/ui/or_fun_call.rs:125:21 | LL | let _ = Some(1).unwrap_or(map[&1]); | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])` error: function call inside of `or` - --> tests/ui/or_fun_call.rs:131:35 + --> tests/ui/or_fun_call.rs:150:35 | LL | let _ = Some("a".to_string()).or(Some("b".to_string())); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_else(|| Some("b".to_string()))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:170:14 + --> tests/ui/or_fun_call.rs:190:14 | LL | None.unwrap_or(ptr_to_ref(s)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| ptr_to_ref(s))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:176:14 + --> tests/ui/or_fun_call.rs:197:14 | LL | None.unwrap_or(unsafe { ptr_to_ref(s) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:178:14 + --> tests/ui/or_fun_call.rs:200:14 | LL | None.unwrap_or( unsafe { ptr_to_ref(s) } ); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:253:25 + --> tests/ui/or_fun_call.rs:276:25 | LL | let _ = Some(4).map_or(g(), |v| v); | ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(g, |v| v)` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:254:25 + --> tests/ui/or_fun_call.rs:278:25 | LL | let _ = Some(4).map_or(g(), f); | ^^^^^^^^^^^^^^ help: try: `map_or_else(g, f)` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:285:18 + --> tests/ui/or_fun_call.rs:310:18 | LL | with_new.unwrap_or_else(Vec::new); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:288:28 + --> tests/ui/or_fun_call.rs:314:28 | LL | with_default_trait.unwrap_or_else(Default::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:291:27 + --> tests/ui/or_fun_call.rs:318:27 | LL | with_default_type.unwrap_or_else(u64::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:294:22 + --> tests/ui/or_fun_call.rs:322:22 | LL | real_default.unwrap_or_else(::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `or_insert_with` to construct default value - --> tests/ui/or_fun_call.rs:297:23 + --> tests/ui/or_fun_call.rs:326:23 | LL | map.entry(42).or_insert_with(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert_with` to construct default value - --> tests/ui/or_fun_call.rs:300:25 + --> tests/ui/or_fun_call.rs:330:25 | LL | btree.entry(42).or_insert_with(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:303:25 + --> tests/ui/or_fun_call.rs:334:25 | LL | let _ = stringy.unwrap_or_else(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:345:17 + --> tests/ui/or_fun_call.rs:377:17 | LL | let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(f)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:348:17 + --> tests/ui/or_fun_call.rs:381:17 | LL | let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| f() + 1)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:351:17 + --> tests/ui/or_fun_call.rs:385:17 | LL | let _ = opt.unwrap_or({ | _________________^ +LL | | LL | | let x = f(); LL | | x + 1 LL | | }); @@ -221,25 +222,26 @@ LL | | }); help: try | LL ~ let _ = opt.unwrap_or_else(|| { +LL + LL + let x = f(); LL + x + 1 LL ~ }); | error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:356:17 + --> tests/ui/or_fun_call.rs:391:17 | LL | let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)` | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| f() + 1, |v| v)` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:359:17 + --> tests/ui/or_fun_call.rs:395:17 | LL | let _ = opt.unwrap_or({ i32::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:365:21 + --> tests/ui/or_fun_call.rs:402:21 | LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })` diff --git a/tests/ui/or_then_unwrap.fixed b/tests/ui/or_then_unwrap.fixed index c94478614352..19db0e47279c 100644 --- a/tests/ui/or_then_unwrap.fixed +++ b/tests/ui/or_then_unwrap.fixed @@ -20,13 +20,16 @@ impl SomeOtherStruct { fn main() { let option: Option<&str> = None; let _ = option.unwrap_or("fallback"); // should trigger lint + //~^ or_then_unwrap let result: Result<&str, &str> = Err("Error"); let _ = result.unwrap_or("fallback"); // should trigger lint + //~^ or_then_unwrap // as part of a method chain let option: Option<&str> = None; let _ = option.map(|v| v).unwrap_or("fallback").to_string().chars(); // should trigger lint + //~^ or_then_unwrap // Not Option/Result let instance = SomeStruct {}; diff --git a/tests/ui/or_then_unwrap.rs b/tests/ui/or_then_unwrap.rs index 10e43e1d1896..7af03b523f73 100644 --- a/tests/ui/or_then_unwrap.rs +++ b/tests/ui/or_then_unwrap.rs @@ -20,13 +20,16 @@ impl SomeOtherStruct { fn main() { let option: Option<&str> = None; let _ = option.or(Some("fallback")).unwrap(); // should trigger lint + //~^ or_then_unwrap let result: Result<&str, &str> = Err("Error"); let _ = result.or::<&str>(Ok("fallback")).unwrap(); // should trigger lint + //~^ or_then_unwrap // as part of a method chain let option: Option<&str> = None; let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint + //~^ or_then_unwrap // Not Option/Result let instance = SomeStruct {}; diff --git a/tests/ui/or_then_unwrap.stderr b/tests/ui/or_then_unwrap.stderr index f454316068f2..d64cc58a790b 100644 --- a/tests/ui/or_then_unwrap.stderr +++ b/tests/ui/or_then_unwrap.stderr @@ -8,13 +8,13 @@ LL | let _ = option.or(Some("fallback")).unwrap(); // should trigger lint = help: to override `-D warnings` add `#[allow(clippy::or_then_unwrap)]` error: found `.or(Ok(…)).unwrap()` - --> tests/ui/or_then_unwrap.rs:25:20 + --> tests/ui/or_then_unwrap.rs:26:20 | LL | let _ = result.or::<&str>(Ok("fallback")).unwrap(); // should trigger lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")` error: found `.or(Some(…)).unwrap()` - --> tests/ui/or_then_unwrap.rs:29:31 + --> tests/ui/or_then_unwrap.rs:31:31 | LL | let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")` diff --git a/tests/ui/out_of_bounds_indexing/issue-3102.rs b/tests/ui/out_of_bounds_indexing/issue-3102.rs index 81674653bdd3..3ba35482780d 100644 --- a/tests/ui/out_of_bounds_indexing/issue-3102.rs +++ b/tests/ui/out_of_bounds_indexing/issue-3102.rs @@ -7,8 +7,10 @@ fn main() { // issue 3102 let num = 1; &x[num..10]; - //~^ ERROR: range is out of bounds - //~| NOTE: `-D clippy::out-of-bounds-indexing` implied by `-D warnings` + //~^ out_of_bounds_indexing + + &x[10..num]; - //~^ ERROR: range is out of bounds + //~^ out_of_bounds_indexing + } diff --git a/tests/ui/out_of_bounds_indexing/issue-3102.stderr b/tests/ui/out_of_bounds_indexing/issue-3102.stderr index 8bf0152601df..304adcfdc2d3 100644 --- a/tests/ui/out_of_bounds_indexing/issue-3102.stderr +++ b/tests/ui/out_of_bounds_indexing/issue-3102.stderr @@ -8,7 +8,7 @@ LL | &x[num..10]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/issue-3102.rs:12:8 + --> tests/ui/out_of_bounds_indexing/issue-3102.rs:13:8 | LL | &x[10..num]; | ^^ diff --git a/tests/ui/out_of_bounds_indexing/simple.rs b/tests/ui/out_of_bounds_indexing/simple.rs index c38ca5123816..86f29f9ee408 100644 --- a/tests/ui/out_of_bounds_indexing/simple.rs +++ b/tests/ui/out_of_bounds_indexing/simple.rs @@ -5,18 +5,24 @@ fn main() { let x = [1, 2, 3, 4]; &x[..=4]; - //~^ ERROR: range is out of bounds - //~| NOTE: `-D clippy::out-of-bounds-indexing` implied by `-D warnings` + //~^ out_of_bounds_indexing + + &x[1..5]; - //~^ ERROR: range is out of bounds + //~^ out_of_bounds_indexing + &x[5..]; - //~^ ERROR: range is out of bounds + //~^ out_of_bounds_indexing + &x[..5]; - //~^ ERROR: range is out of bounds + //~^ out_of_bounds_indexing + &x[5..].iter().map(|x| 2 * x).collect::>(); - //~^ ERROR: range is out of bounds + //~^ out_of_bounds_indexing + &x[0..=4]; - //~^ ERROR: range is out of bounds + //~^ out_of_bounds_indexing + &x[4..]; // Ok, should not produce stderr. &x[..4]; // Ok, should not produce stderr. diff --git a/tests/ui/out_of_bounds_indexing/simple.stderr b/tests/ui/out_of_bounds_indexing/simple.stderr index 87d1d574dcb8..47f36e51bffa 100644 --- a/tests/ui/out_of_bounds_indexing/simple.stderr +++ b/tests/ui/out_of_bounds_indexing/simple.stderr @@ -8,31 +8,31 @@ LL | &x[..=4]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:10:11 + --> tests/ui/out_of_bounds_indexing/simple.rs:11:11 | LL | &x[1..5]; | ^ error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:12:8 + --> tests/ui/out_of_bounds_indexing/simple.rs:14:8 | LL | &x[5..]; | ^ error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:14:10 + --> tests/ui/out_of_bounds_indexing/simple.rs:17:10 | LL | &x[..5]; | ^ error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:16:8 + --> tests/ui/out_of_bounds_indexing/simple.rs:20:8 | LL | &x[5..].iter().map(|x| 2 * x).collect::>(); | ^ error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:18:12 + --> tests/ui/out_of_bounds_indexing/simple.rs:23:12 | LL | &x[0..=4]; | ^ diff --git a/tests/ui/overly_complex_bool_expr.fixed b/tests/ui/overly_complex_bool_expr.fixed index b21e91aa3ad4..6818f96725e7 100644 --- a/tests/ui/overly_complex_bool_expr.fixed +++ b/tests/ui/overly_complex_bool_expr.fixed @@ -8,10 +8,12 @@ fn main() { let d: bool = unimplemented!(); let e: bool = unimplemented!(); let _ = a; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + let _ = !(a && b); let _ = false; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + // don't lint on cfgs let _ = cfg!(you_shall_not_not_pass) && a; let _ = a || !b || !c || !d || !e; @@ -22,11 +24,14 @@ fn equality_stuff() { let a: i32 = unimplemented!(); let b: i32 = unimplemented!(); let _ = false; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + let _ = false; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + let _ = false; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + let _ = a > b && a == b; } diff --git a/tests/ui/overly_complex_bool_expr.rs b/tests/ui/overly_complex_bool_expr.rs index 35ef0a1240a5..f1cd9562a855 100644 --- a/tests/ui/overly_complex_bool_expr.rs +++ b/tests/ui/overly_complex_bool_expr.rs @@ -8,10 +8,12 @@ fn main() { let d: bool = unimplemented!(); let e: bool = unimplemented!(); let _ = a && b || a; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + let _ = !(a && b); let _ = false && a; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + // don't lint on cfgs let _ = cfg!(you_shall_not_not_pass) && a; let _ = a || !b || !c || !d || !e; @@ -22,11 +24,14 @@ fn equality_stuff() { let a: i32 = unimplemented!(); let b: i32 = unimplemented!(); let _ = a == b && a != b; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + let _ = a < b && a >= b; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + let _ = a > b && a <= b; - //~^ ERROR: this boolean expression contains a logic bug + //~^ overly_complex_bool_expr + let _ = a > b && a == b; } diff --git a/tests/ui/overly_complex_bool_expr.stderr b/tests/ui/overly_complex_bool_expr.stderr index 5a754236fe4b..42a48a3b5be8 100644 --- a/tests/ui/overly_complex_bool_expr.stderr +++ b/tests/ui/overly_complex_bool_expr.stderr @@ -13,49 +13,49 @@ LL | let _ = a && b || a; = help: to override `-D warnings` add `#[allow(clippy::overly_complex_bool_expr)]` error: this boolean expression contains a logic bug - --> tests/ui/overly_complex_bool_expr.rs:13:13 + --> tests/ui/overly_complex_bool_expr.rs:14:13 | LL | let _ = false && a; | ^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> tests/ui/overly_complex_bool_expr.rs:13:22 + --> tests/ui/overly_complex_bool_expr.rs:14:22 | LL | let _ = false && a; | ^ error: this boolean expression contains a logic bug - --> tests/ui/overly_complex_bool_expr.rs:24:13 + --> tests/ui/overly_complex_bool_expr.rs:26:13 | LL | let _ = a == b && a != b; | ^^^^^^^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> tests/ui/overly_complex_bool_expr.rs:24:13 + --> tests/ui/overly_complex_bool_expr.rs:26:13 | LL | let _ = a == b && a != b; | ^^^^^^ error: this boolean expression contains a logic bug - --> tests/ui/overly_complex_bool_expr.rs:26:13 + --> tests/ui/overly_complex_bool_expr.rs:29:13 | LL | let _ = a < b && a >= b; | ^^^^^^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> tests/ui/overly_complex_bool_expr.rs:26:13 + --> tests/ui/overly_complex_bool_expr.rs:29:13 | LL | let _ = a < b && a >= b; | ^^^^^ error: this boolean expression contains a logic bug - --> tests/ui/overly_complex_bool_expr.rs:28:13 + --> tests/ui/overly_complex_bool_expr.rs:32:13 | LL | let _ = a > b && a <= b; | ^^^^^^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> tests/ui/overly_complex_bool_expr.rs:28:13 + --> tests/ui/overly_complex_bool_expr.rs:32:13 | LL | let _ = a > b && a <= b; | ^^^^^ diff --git a/tests/ui/panic_in_result_fn.rs b/tests/ui/panic_in_result_fn.rs index e2375aa996f7..dc0fc65fd777 100644 --- a/tests/ui/panic_in_result_fn.rs +++ b/tests/ui/panic_in_result_fn.rs @@ -4,7 +4,8 @@ struct A; impl A { fn result_with_panic() -> Result // should emit lint - //~^ ERROR: used `panic!()` or assertion in a function that returns `Result` + //~^ panic_in_result_fn + { panic!("error"); } @@ -51,12 +52,14 @@ impl A { } fn function_result_with_panic() -> Result // should emit lint -//~^ ERROR: used `panic!()` or assertion in a function that returns `Result` +//~^ panic_in_result_fn + { panic!("error"); } fn in_closure() -> Result { +//~^ panic_in_result_fn let c = || panic!(); c() } diff --git a/tests/ui/panic_in_result_fn.stderr b/tests/ui/panic_in_result_fn.stderr index 2d49b5ab1b8f..17fd03733abc 100644 --- a/tests/ui/panic_in_result_fn.stderr +++ b/tests/ui/panic_in_result_fn.stderr @@ -2,15 +2,13 @@ error: used `panic!()` or assertion in a function that returns `Result` --> tests/ui/panic_in_result_fn.rs:6:5 | LL | / fn result_with_panic() -> Result // should emit lint -LL | | -LL | | { -LL | | panic!("error"); +... | LL | | } | |_____^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn.rs:9:9 + --> tests/ui/panic_in_result_fn.rs:10:9 | LL | panic!("error"); | ^^^^^^^^^^^^^^^ @@ -18,26 +16,25 @@ LL | panic!("error"); = help: to override `-D warnings` add `#[allow(clippy::panic_in_result_fn)]` error: used `panic!()` or assertion in a function that returns `Result` - --> tests/ui/panic_in_result_fn.rs:53:1 + --> tests/ui/panic_in_result_fn.rs:54:1 | LL | / fn function_result_with_panic() -> Result // should emit lint -LL | | -LL | | { -LL | | panic!("error"); +... | LL | | } | |_^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn.rs:56:5 + --> tests/ui/panic_in_result_fn.rs:58:5 | LL | panic!("error"); | ^^^^^^^^^^^^^^^ error: used `panic!()` or assertion in a function that returns `Result` - --> tests/ui/panic_in_result_fn.rs:59:1 + --> tests/ui/panic_in_result_fn.rs:61:1 | LL | / fn in_closure() -> Result { +LL | | LL | | let c = || panic!(); LL | | c() LL | | } @@ -45,7 +42,7 @@ LL | | } | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn.rs:60:16 + --> tests/ui/panic_in_result_fn.rs:63:16 | LL | let c = || panic!(); | ^^^^^^^^ diff --git a/tests/ui/panic_in_result_fn_assertions.rs b/tests/ui/panic_in_result_fn_assertions.rs index 672c4c738339..894e63f8ff1e 100644 --- a/tests/ui/panic_in_result_fn_assertions.rs +++ b/tests/ui/panic_in_result_fn_assertions.rs @@ -5,21 +5,24 @@ struct A; impl A { fn result_with_assert_with_message(x: i32) -> Result // should emit lint - //~^ ERROR: used `panic!()` or assertion in a function that returns `Result` + //~^ panic_in_result_fn + { assert!(x == 5, "wrong argument"); Ok(true) } fn result_with_assert_eq(x: i32) -> Result // should emit lint - //~^ ERROR: used `panic!()` or assertion in a function that returns `Result` + //~^ panic_in_result_fn + { assert_eq!(x, 5); Ok(true) } fn result_with_assert_ne(x: i32) -> Result // should emit lint - //~^ ERROR: used `panic!()` or assertion in a function that returns `Result` + //~^ panic_in_result_fn + { assert_ne!(x, 1); Ok(true) diff --git a/tests/ui/panic_in_result_fn_assertions.stderr b/tests/ui/panic_in_result_fn_assertions.stderr index cdb7762510d9..46bc16fe8e16 100644 --- a/tests/ui/panic_in_result_fn_assertions.stderr +++ b/tests/ui/panic_in_result_fn_assertions.stderr @@ -2,16 +2,14 @@ error: used `panic!()` or assertion in a function that returns `Result` --> tests/ui/panic_in_result_fn_assertions.rs:7:5 | LL | / fn result_with_assert_with_message(x: i32) -> Result // should emit lint -LL | | -LL | | { -LL | | assert!(x == 5, "wrong argument"); +... | LL | | Ok(true) LL | | } | |_____^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn_assertions.rs:10:9 + --> tests/ui/panic_in_result_fn_assertions.rs:11:9 | LL | assert!(x == 5, "wrong argument"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,37 +17,33 @@ LL | assert!(x == 5, "wrong argument"); = help: to override `-D warnings` add `#[allow(clippy::panic_in_result_fn)]` error: used `panic!()` or assertion in a function that returns `Result` - --> tests/ui/panic_in_result_fn_assertions.rs:14:5 + --> tests/ui/panic_in_result_fn_assertions.rs:15:5 | LL | / fn result_with_assert_eq(x: i32) -> Result // should emit lint -LL | | -LL | | { -LL | | assert_eq!(x, 5); +... | LL | | Ok(true) LL | | } | |_____^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn_assertions.rs:17:9 + --> tests/ui/panic_in_result_fn_assertions.rs:19:9 | LL | assert_eq!(x, 5); | ^^^^^^^^^^^^^^^^ error: used `panic!()` or assertion in a function that returns `Result` - --> tests/ui/panic_in_result_fn_assertions.rs:21:5 + --> tests/ui/panic_in_result_fn_assertions.rs:23:5 | LL | / fn result_with_assert_ne(x: i32) -> Result // should emit lint -LL | | -LL | | { -LL | | assert_ne!(x, 1); +... | LL | | Ok(true) LL | | } | |_____^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn_assertions.rs:24:9 + --> tests/ui/panic_in_result_fn_assertions.rs:27:9 | LL | assert_ne!(x, 1); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/panic_in_result_fn_debug_assertions.rs b/tests/ui/panic_in_result_fn_debug_assertions.rs index df89d8c50246..c4549c6b8412 100644 --- a/tests/ui/panic_in_result_fn_debug_assertions.rs +++ b/tests/ui/panic_in_result_fn_debug_assertions.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::panic_in_result_fn)] #![allow(clippy::uninlined_format_args, clippy::unnecessary_wraps)] diff --git a/tests/ui/panicking_macros.rs b/tests/ui/panicking_macros.rs index 2bbf5792ec4c..a718dd925216 100644 --- a/tests/ui/panicking_macros.rs +++ b/tests/ui/panicking_macros.rs @@ -20,61 +20,77 @@ fn inline_const() { fn panic() { let a = 2; panic!(); - //~^ ERROR: `panic` should not be present in production code - //~| NOTE: `-D clippy::panic` implied by `-D warnings` + //~^ panic + + panic!("message"); - //~^ ERROR: `panic` should not be present in production code + //~^ panic + panic!("{} {}", "panic with", "multiple arguments"); - //~^ ERROR: `panic` should not be present in production code + //~^ panic + let b = a + 2; } fn todo() { let a = 2; todo!(); - //~^ ERROR: `todo` should not be present in production code - //~| NOTE: `-D clippy::todo` implied by `-D warnings` + //~^ todo + + todo!("message"); - //~^ ERROR: `todo` should not be present in production code + //~^ todo + todo!("{} {}", "panic with", "multiple arguments"); - //~^ ERROR: `todo` should not be present in production code + //~^ todo + let b = a + 2; } fn unimplemented() { let a = 2; unimplemented!(); - //~^ ERROR: `unimplemented` should not be present in production code - //~| NOTE: `-D clippy::unimplemented` implied by `-D warnings` + //~^ unimplemented + + unimplemented!("message"); - //~^ ERROR: `unimplemented` should not be present in production code + //~^ unimplemented + unimplemented!("{} {}", "panic with", "multiple arguments"); - //~^ ERROR: `unimplemented` should not be present in production code + //~^ unimplemented + let b = a + 2; } fn unreachable() { let a = 2; unreachable!(); - //~^ ERROR: usage of the `unreachable!` macro - //~| NOTE: `-D clippy::unreachable` implied by `-D warnings` + //~^ unreachable + + unreachable!("message"); - //~^ ERROR: usage of the `unreachable!` macro + //~^ unreachable + unreachable!("{} {}", "panic with", "multiple arguments"); - //~^ ERROR: usage of the `unreachable!` macro + //~^ unreachable + let b = a + 2; } fn core_versions() { use core::{panic, todo, unimplemented, unreachable}; panic!(); - //~^ ERROR: `panic` should not be present in production code + //~^ panic + todo!(); - //~^ ERROR: `todo` should not be present in production code + //~^ todo + unimplemented!(); - //~^ ERROR: `unimplemented` should not be present in production code + //~^ unimplemented + unreachable!(); - //~^ ERROR: usage of the `unreachable!` macro + //~^ unreachable + } fn assert() { diff --git a/tests/ui/panicking_macros.stderr b/tests/ui/panicking_macros.stderr index 7c0f0a7d3764..0c2b4508a803 100644 --- a/tests/ui/panicking_macros.stderr +++ b/tests/ui/panicking_macros.stderr @@ -8,19 +8,19 @@ LL | panic!(); = help: to override `-D warnings` add `#[allow(clippy::panic)]` error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:25:5 + --> tests/ui/panicking_macros.rs:26:5 | LL | panic!("message"); | ^^^^^^^^^^^^^^^^^ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:27:5 + --> tests/ui/panicking_macros.rs:29:5 | LL | panic!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:34:5 + --> tests/ui/panicking_macros.rs:37:5 | LL | todo!(); | ^^^^^^^ @@ -29,19 +29,19 @@ LL | todo!(); = help: to override `-D warnings` add `#[allow(clippy::todo)]` error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:37:5 + --> tests/ui/panicking_macros.rs:41:5 | LL | todo!("message"); | ^^^^^^^^^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:39:5 + --> tests/ui/panicking_macros.rs:44:5 | LL | todo!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:46:5 + --> tests/ui/panicking_macros.rs:52:5 | LL | unimplemented!(); | ^^^^^^^^^^^^^^^^ @@ -50,19 +50,19 @@ LL | unimplemented!(); = help: to override `-D warnings` add `#[allow(clippy::unimplemented)]` error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:49:5 + --> tests/ui/panicking_macros.rs:56:5 | LL | unimplemented!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:51:5 + --> tests/ui/panicking_macros.rs:59:5 | LL | unimplemented!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:58:5 + --> tests/ui/panicking_macros.rs:67:5 | LL | unreachable!(); | ^^^^^^^^^^^^^^ @@ -71,37 +71,37 @@ LL | unreachable!(); = help: to override `-D warnings` add `#[allow(clippy::unreachable)]` error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:61:5 + --> tests/ui/panicking_macros.rs:71:5 | LL | unreachable!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:63:5 + --> tests/ui/panicking_macros.rs:74:5 | LL | unreachable!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:70:5 + --> tests/ui/panicking_macros.rs:82:5 | LL | panic!(); | ^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:72:5 + --> tests/ui/panicking_macros.rs:85:5 | LL | todo!(); | ^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:74:5 + --> tests/ui/panicking_macros.rs:88:5 | LL | unimplemented!(); | ^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:76:5 + --> tests/ui/panicking_macros.rs:91:5 | LL | unreachable!(); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/panicking_overflow_checks.rs b/tests/ui/panicking_overflow_checks.rs index dc2ddeada1e9..57a829d50d2c 100644 --- a/tests/ui/panicking_overflow_checks.rs +++ b/tests/ui/panicking_overflow_checks.rs @@ -2,14 +2,20 @@ #![allow(clippy::needless_if)] fn test(a: u32, b: u32, c: u32) { - if a + b < a {} //~ panicking_overflow_checks - if a > a + b {} //~ panicking_overflow_checks - if a + b < b {} //~ panicking_overflow_checks - if b > a + b {} //~ panicking_overflow_checks +if a + b < a {} +//~^ panicking_overflow_checks +if a > a + b {} +//~^ panicking_overflow_checks +if a + b < b {} +//~^ panicking_overflow_checks +if b > a + b {} +//~^ panicking_overflow_checks if a - b > b {} if b < a - b {} - if a - b > a {} //~ panicking_overflow_checks - if a < a - b {} //~ panicking_overflow_checks +if a - b > a {} +//~^ panicking_overflow_checks +if a < a - b {} +//~^ panicking_overflow_checks if a + b < c {} if c > a + b {} if a - b < c {} diff --git a/tests/ui/panicking_overflow_checks.stderr b/tests/ui/panicking_overflow_checks.stderr index 1fae04578899..3bb209ccfa7e 100644 --- a/tests/ui/panicking_overflow_checks.stderr +++ b/tests/ui/panicking_overflow_checks.stderr @@ -1,41 +1,41 @@ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:5:8 + --> tests/ui/panicking_overflow_checks.rs:5:4 | -LL | if a + b < a {} - | ^^^^^^^^^ +LL | if a + b < a {} + | ^^^^^^^^^ | = note: `-D clippy::panicking-overflow-checks` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::panicking_overflow_checks)]` error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:6:8 + --> tests/ui/panicking_overflow_checks.rs:7:4 | -LL | if a > a + b {} - | ^^^^^^^^^ +LL | if a > a + b {} + | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:7:8 + --> tests/ui/panicking_overflow_checks.rs:9:4 | -LL | if a + b < b {} - | ^^^^^^^^^ +LL | if a + b < b {} + | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:8:8 + --> tests/ui/panicking_overflow_checks.rs:11:4 | -LL | if b > a + b {} - | ^^^^^^^^^ +LL | if b > a + b {} + | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:11:8 + --> tests/ui/panicking_overflow_checks.rs:15:4 | -LL | if a - b > a {} - | ^^^^^^^^^ +LL | if a - b > a {} + | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:12:8 + --> tests/ui/panicking_overflow_checks.rs:17:4 | -LL | if a < a - b {} - | ^^^^^^^^^ +LL | if a < a - b {} + | ^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/partial_pub_fields.rs b/tests/ui/partial_pub_fields.rs index 316b36c25eac..a0ee4f2b0496 100644 --- a/tests/ui/partial_pub_fields.rs +++ b/tests/ui/partial_pub_fields.rs @@ -8,23 +8,27 @@ fn main() { pub struct FileSet { files: HashMap, pub paths: HashMap, - //~^ ERROR: mixed usage of pub and non-pub fields + //~^ partial_pub_fields + } pub struct Color { pub r: u8, pub g: u8, b: u8, - //~^ ERROR: mixed usage of pub and non-pub fields + //~^ partial_pub_fields + } pub struct Point(i32, pub i32); - //~^ ERROR: mixed usage of pub and non-pub fields + //~^ partial_pub_fields + pub struct Visibility { r#pub: bool, pub pos: u32, - //~^ ERROR: mixed usage of pub and non-pub fields + //~^ partial_pub_fields + } // Don't lint on empty structs; diff --git a/tests/ui/partial_pub_fields.stderr b/tests/ui/partial_pub_fields.stderr index af3b2f758757..4232f3e82e45 100644 --- a/tests/ui/partial_pub_fields.stderr +++ b/tests/ui/partial_pub_fields.stderr @@ -9,7 +9,7 @@ LL | pub paths: HashMap, = help: to override `-D warnings` add `#[allow(clippy::partial_pub_fields)]` error: mixed usage of pub and non-pub fields - --> tests/ui/partial_pub_fields.rs:17:9 + --> tests/ui/partial_pub_fields.rs:18:9 | LL | b: u8, | ^ @@ -17,7 +17,7 @@ LL | b: u8, = help: consider using public field here error: mixed usage of pub and non-pub fields - --> tests/ui/partial_pub_fields.rs:21:27 + --> tests/ui/partial_pub_fields.rs:23:27 | LL | pub struct Point(i32, pub i32); | ^^^ @@ -25,7 +25,7 @@ LL | pub struct Point(i32, pub i32); = help: consider using private field here error: mixed usage of pub and non-pub fields - --> tests/ui/partial_pub_fields.rs:26:9 + --> tests/ui/partial_pub_fields.rs:29:9 | LL | pub pos: u32, | ^^^ diff --git a/tests/ui/partialeq_ne_impl.rs b/tests/ui/partialeq_ne_impl.rs index 555eeebe1c78..42c235b381ef 100644 --- a/tests/ui/partialeq_ne_impl.rs +++ b/tests/ui/partialeq_ne_impl.rs @@ -7,8 +7,9 @@ impl PartialEq for Foo { true } fn ne(&self, _: &Foo) -> bool { - //~^ ERROR: re-implementing `PartialEq::ne` is unnecessary - //~| NOTE: `-D clippy::partialeq-ne-impl` implied by `-D warnings` + //~^ partialeq_ne_impl + + false } } diff --git a/tests/ui/partialeq_ne_impl.stderr b/tests/ui/partialeq_ne_impl.stderr index dc01a375060b..ffc26afa075d 100644 --- a/tests/ui/partialeq_ne_impl.stderr +++ b/tests/ui/partialeq_ne_impl.stderr @@ -2,9 +2,7 @@ error: re-implementing `PartialEq::ne` is unnecessary --> tests/ui/partialeq_ne_impl.rs:9:5 | LL | / fn ne(&self, _: &Foo) -> bool { -LL | | -LL | | -LL | | false +... | LL | | } | |_____^ | diff --git a/tests/ui/partialeq_to_none.fixed b/tests/ui/partialeq_to_none.fixed index 87adbca39484..d650e28f2b68 100644 --- a/tests/ui/partialeq_to_none.fixed +++ b/tests/ui/partialeq_to_none.fixed @@ -12,6 +12,7 @@ impl PartialEq> for Foobar { #[allow(dead_code)] fn foo(f: Option) -> &'static str { if f.is_some() { "yay" } else { "nay" } + //~^ partialeq_to_none } fn foobar() -> Option<()> { @@ -42,19 +43,28 @@ fn main() { let x = Some(0); let _ = x.is_none(); + //~^ partialeq_to_none let _ = x.is_some(); + //~^ partialeq_to_none let _ = x.is_none(); + //~^ partialeq_to_none let _ = x.is_some(); + //~^ partialeq_to_none if foobar().is_none() {} + //~^ partialeq_to_none if bar().ok().is_some() {} + //~^ partialeq_to_none let _ = Some(1 + 2).is_some(); + //~^ partialeq_to_none let _ = { Some(0) }.is_none(); + //~^ partialeq_to_none let _ = { + //~^ partialeq_to_none /* This comment runs long */ @@ -65,10 +75,15 @@ fn main() { let _ = Foobar == None; let _ = optref().is_none(); + //~^ partialeq_to_none let _ = optref().is_some(); + //~^ partialeq_to_none let _ = optref().is_none(); + //~^ partialeq_to_none let _ = optref().is_some(); + //~^ partialeq_to_none let x = Box::new(Option::<()>::None); let _ = (*x).is_some(); + //~^ partialeq_to_none } diff --git a/tests/ui/partialeq_to_none.rs b/tests/ui/partialeq_to_none.rs index b623e6a66268..77804b0765f1 100644 --- a/tests/ui/partialeq_to_none.rs +++ b/tests/ui/partialeq_to_none.rs @@ -12,6 +12,7 @@ impl PartialEq> for Foobar { #[allow(dead_code)] fn foo(f: Option) -> &'static str { if f != None { "yay" } else { "nay" } + //~^ partialeq_to_none } fn foobar() -> Option<()> { @@ -42,19 +43,28 @@ fn main() { let x = Some(0); let _ = x == None; + //~^ partialeq_to_none let _ = x != None; + //~^ partialeq_to_none let _ = None == x; + //~^ partialeq_to_none let _ = None != x; + //~^ partialeq_to_none if foobar() == None {} + //~^ partialeq_to_none if bar().ok() != None {} + //~^ partialeq_to_none let _ = Some(1 + 2) != None; + //~^ partialeq_to_none let _ = { Some(0) } == None; + //~^ partialeq_to_none let _ = { + //~^ partialeq_to_none /* This comment runs long */ @@ -65,10 +75,15 @@ fn main() { let _ = Foobar == None; let _ = optref() == &&None; + //~^ partialeq_to_none let _ = &&None != optref(); + //~^ partialeq_to_none let _ = **optref() == None; + //~^ partialeq_to_none let _ = &None != *optref(); + //~^ partialeq_to_none let x = Box::new(Option::<()>::None); let _ = None != *x; + //~^ partialeq_to_none } diff --git a/tests/ui/partialeq_to_none.stderr b/tests/ui/partialeq_to_none.stderr index b588fbf32b60..b09bd7fa0f42 100644 --- a/tests/ui/partialeq_to_none.stderr +++ b/tests/ui/partialeq_to_none.stderr @@ -8,58 +8,59 @@ LL | if f != None { "yay" } else { "nay" } = help: to override `-D warnings` add `#[allow(clippy::partialeq_to_none)]` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:44:13 + --> tests/ui/partialeq_to_none.rs:45:13 | LL | let _ = x == None; | ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:45:13 + --> tests/ui/partialeq_to_none.rs:47:13 | LL | let _ = x != None; | ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:46:13 + --> tests/ui/partialeq_to_none.rs:49:13 | LL | let _ = None == x; | ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:47:13 + --> tests/ui/partialeq_to_none.rs:51:13 | LL | let _ = None != x; | ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:49:8 + --> tests/ui/partialeq_to_none.rs:54:8 | LL | if foobar() == None {} | ^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `foobar().is_none()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:51:8 + --> tests/ui/partialeq_to_none.rs:57:8 | LL | if bar().ok() != None {} | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `bar().ok().is_some()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:53:13 + --> tests/ui/partialeq_to_none.rs:60:13 | LL | let _ = Some(1 + 2) != None; | ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `Some(1 + 2).is_some()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:55:13 + --> tests/ui/partialeq_to_none.rs:63:13 | LL | let _ = { Some(0) } == None; | ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `{ Some(0) }.is_none()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:57:13 + --> tests/ui/partialeq_to_none.rs:66:13 | LL | let _ = { | _____________^ +LL | | LL | | /* LL | | This comment runs long LL | | */ @@ -70,6 +71,7 @@ LL | | } != None; help: use `Option::is_some()` instead | LL ~ let _ = { +LL + LL + /* LL + This comment runs long LL + */ @@ -78,31 +80,31 @@ LL ~ }.is_some(); | error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:67:13 + --> tests/ui/partialeq_to_none.rs:77:13 | LL | let _ = optref() == &&None; | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:68:13 + --> tests/ui/partialeq_to_none.rs:79:13 | LL | let _ = &&None != optref(); | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:69:13 + --> tests/ui/partialeq_to_none.rs:81:13 | LL | let _ = **optref() == None; | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:70:13 + --> tests/ui/partialeq_to_none.rs:83:13 | LL | let _ = &None != *optref(); | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()` error: binary comparison to literal `Option::None` - --> tests/ui/partialeq_to_none.rs:73:13 + --> tests/ui/partialeq_to_none.rs:87:13 | LL | let _ = None != *x; | ^^^^^^^^^^ help: use `Option::is_some()` instead: `(*x).is_some()` diff --git a/tests/ui/path_buf_push_overwrite.fixed b/tests/ui/path_buf_push_overwrite.fixed index 1a46d72378f8..5c818bad3d53 100644 --- a/tests/ui/path_buf_push_overwrite.fixed +++ b/tests/ui/path_buf_push_overwrite.fixed @@ -5,4 +5,5 @@ use std::path::PathBuf; fn main() { let mut x = PathBuf::from("/foo"); x.push("bar"); + //~^ path_buf_push_overwrite } diff --git a/tests/ui/path_buf_push_overwrite.rs b/tests/ui/path_buf_push_overwrite.rs index 3e3f84b17a4b..650ae3286a0c 100644 --- a/tests/ui/path_buf_push_overwrite.rs +++ b/tests/ui/path_buf_push_overwrite.rs @@ -5,4 +5,5 @@ use std::path::PathBuf; fn main() { let mut x = PathBuf::from("/foo"); x.push("/bar"); + //~^ path_buf_push_overwrite } diff --git a/tests/ui/path_ends_with_ext.fixed b/tests/ui/path_ends_with_ext.fixed index 49767e242cee..a20925f9ba67 100644 --- a/tests/ui/path_ends_with_ext.fixed +++ b/tests/ui/path_ends_with_ext.fixed @@ -9,7 +9,8 @@ macro_rules! arg { fn test(path: &Path) { path.extension().is_some_and(|ext| ext == "md"); - //~^ ERROR: this looks like a failed attempt at checking for the file extension + //~^ path_ends_with_ext + // some "extensions" are allowed by default path.ends_with(".git"); @@ -30,7 +31,8 @@ fn test(path: &Path) { #[clippy::msrv = "1.69"] fn under_msv(path: &Path) -> bool { path.extension().map_or(false, |ext| ext == "md") - //~^ ERROR: this looks like a failed attempt at checking for the file extension + //~^ path_ends_with_ext + } fn main() {} diff --git a/tests/ui/path_ends_with_ext.rs b/tests/ui/path_ends_with_ext.rs index 2dfd046218af..e20620e983d0 100644 --- a/tests/ui/path_ends_with_ext.rs +++ b/tests/ui/path_ends_with_ext.rs @@ -9,7 +9,8 @@ macro_rules! arg { fn test(path: &Path) { path.ends_with(".md"); - //~^ ERROR: this looks like a failed attempt at checking for the file extension + //~^ path_ends_with_ext + // some "extensions" are allowed by default path.ends_with(".git"); @@ -30,7 +31,8 @@ fn test(path: &Path) { #[clippy::msrv = "1.69"] fn under_msv(path: &Path) -> bool { path.ends_with(".md") - //~^ ERROR: this looks like a failed attempt at checking for the file extension + //~^ path_ends_with_ext + } fn main() {} diff --git a/tests/ui/path_ends_with_ext.stderr b/tests/ui/path_ends_with_ext.stderr index deab71ff7626..7016b8e5b8fb 100644 --- a/tests/ui/path_ends_with_ext.stderr +++ b/tests/ui/path_ends_with_ext.stderr @@ -8,7 +8,7 @@ LL | path.ends_with(".md"); = help: to override `-D warnings` add `#[allow(clippy::path_ends_with_ext)]` error: this looks like a failed attempt at checking for the file extension - --> tests/ui/path_ends_with_ext.rs:32:5 + --> tests/ui/path_ends_with_ext.rs:33:5 | LL | path.ends_with(".md") | ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().map_or(false, |ext| ext == "md")` diff --git a/tests/ui/pathbuf_init_then_push.fixed b/tests/ui/pathbuf_init_then_push.fixed index 2a90b8ce2814..43cc65f8dfbf 100644 --- a/tests/ui/pathbuf_init_then_push.fixed +++ b/tests/ui/pathbuf_init_then_push.fixed @@ -3,14 +3,14 @@ use std::path::PathBuf; fn main() { - let mut path_buf = PathBuf::from("foo"); +let mut path_buf = PathBuf::from("foo"); - path_buf = PathBuf::from("foo").join("bar"); +path_buf = PathBuf::from("foo").join("bar"); let bar = "bar"; - path_buf = PathBuf::from("foo").join(bar); +path_buf = PathBuf::from("foo").join(bar); - let mut path_buf = PathBuf::from("foo").join("bar").join("buz"); +let mut path_buf = PathBuf::from("foo").join("bar").join("buz"); let mut x = PathBuf::new(); println!("{}", x.display()); diff --git a/tests/ui/pathbuf_init_then_push.rs b/tests/ui/pathbuf_init_then_push.rs index 4a7ae00a7352..f3adb6d27abf 100644 --- a/tests/ui/pathbuf_init_then_push.rs +++ b/tests/ui/pathbuf_init_then_push.rs @@ -3,17 +3,21 @@ use std::path::PathBuf; fn main() { - let mut path_buf = PathBuf::new(); //~ ERROR: calls to `push` immediately after creation +let mut path_buf = PathBuf::new(); +//~^ pathbuf_init_then_push path_buf.push("foo"); - path_buf = PathBuf::from("foo"); //~ ERROR: calls to `push` immediately after creation +path_buf = PathBuf::from("foo"); +//~^ pathbuf_init_then_push path_buf.push("bar"); let bar = "bar"; - path_buf = PathBuf::from("foo"); //~ ERROR: calls to `push` immediately after creation +path_buf = PathBuf::from("foo"); +//~^ pathbuf_init_then_push path_buf.push(bar); - let mut path_buf = PathBuf::from("foo").join("bar"); //~ ERROR: calls to `push` immediately after creation +let mut path_buf = PathBuf::from("foo").join("bar"); +//~^ pathbuf_init_then_push path_buf.push("buz"); let mut x = PathBuf::new(); diff --git a/tests/ui/pathbuf_init_then_push.stderr b/tests/ui/pathbuf_init_then_push.stderr index e7aa291035d2..80e7b836fce3 100644 --- a/tests/ui/pathbuf_init_then_push.stderr +++ b/tests/ui/pathbuf_init_then_push.stderr @@ -1,7 +1,8 @@ error: calls to `push` immediately after creation - --> tests/ui/pathbuf_init_then_push.rs:6:5 + --> tests/ui/pathbuf_init_then_push.rs:6:1 | -LL | / let mut path_buf = PathBuf::new(); +LL | / let mut path_buf = PathBuf::new(); +LL | | LL | | path_buf.push("foo"); | |_________________________^ help: consider using the `.join()`: `let mut path_buf = PathBuf::from("foo");` | @@ -9,23 +10,26 @@ LL | | path_buf.push("foo"); = help: to override `-D warnings` add `#[allow(clippy::pathbuf_init_then_push)]` error: calls to `push` immediately after creation - --> tests/ui/pathbuf_init_then_push.rs:9:5 + --> tests/ui/pathbuf_init_then_push.rs:10:1 | -LL | / path_buf = PathBuf::from("foo"); +LL | / path_buf = PathBuf::from("foo"); +LL | | LL | | path_buf.push("bar"); | |_________________________^ help: consider using the `.join()`: `path_buf = PathBuf::from("foo").join("bar");` error: calls to `push` immediately after creation - --> tests/ui/pathbuf_init_then_push.rs:13:5 + --> tests/ui/pathbuf_init_then_push.rs:15:1 | -LL | / path_buf = PathBuf::from("foo"); +LL | / path_buf = PathBuf::from("foo"); +LL | | LL | | path_buf.push(bar); | |_______________________^ help: consider using the `.join()`: `path_buf = PathBuf::from("foo").join(bar);` error: calls to `push` immediately after creation - --> tests/ui/pathbuf_init_then_push.rs:16:5 + --> tests/ui/pathbuf_init_then_push.rs:19:1 | -LL | / let mut path_buf = PathBuf::from("foo").join("bar"); +LL | / let mut path_buf = PathBuf::from("foo").join("bar"); +LL | | LL | | path_buf.push("buz"); | |_________________________^ help: consider using the `.join()`: `let mut path_buf = PathBuf::from("foo").join("bar").join("buz");` diff --git a/tests/ui/pattern_type_mismatch/mutability.rs b/tests/ui/pattern_type_mismatch/mutability.rs index 61dee47cb192..c62b33681439 100644 --- a/tests/ui/pattern_type_mismatch/mutability.rs +++ b/tests/ui/pattern_type_mismatch/mutability.rs @@ -7,14 +7,16 @@ fn should_lint() { let value = &Some(23); match value { Some(_) => (), - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + _ => (), } let value = &mut Some(23); match value { Some(_) => (), - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + _ => (), } } diff --git a/tests/ui/pattern_type_mismatch/mutability.stderr b/tests/ui/pattern_type_mismatch/mutability.stderr index e795ded7386d..805fc99ea212 100644 --- a/tests/ui/pattern_type_mismatch/mutability.stderr +++ b/tests/ui/pattern_type_mismatch/mutability.stderr @@ -9,7 +9,7 @@ LL | Some(_) => (), = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]` error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/mutability.rs:16:9 + --> tests/ui/pattern_type_mismatch/mutability.rs:17:9 | LL | Some(_) => (), | ^^^^^^^ diff --git a/tests/ui/pattern_type_mismatch/pattern_alternatives.rs b/tests/ui/pattern_type_mismatch/pattern_alternatives.rs index 558d496ae2c0..9df08bfe7246 100644 --- a/tests/ui/pattern_type_mismatch/pattern_alternatives.rs +++ b/tests/ui/pattern_type_mismatch/pattern_alternatives.rs @@ -13,11 +13,14 @@ fn alternatives() { // not ok if let Value::B | Value::A(_) = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let &Value::B | &Value::A(Some(_)) = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let Value::B | Value::A(Some(_)) = *ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok if let &Value::B | &Value::A(_) = ref_value {} diff --git a/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr b/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr index e1aec2497cd1..763f688ea897 100644 --- a/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr +++ b/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr @@ -9,7 +9,7 @@ LL | if let Value::B | Value::A(_) = ref_value {} = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]` error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_alternatives.rs:17:34 + --> tests/ui/pattern_type_mismatch/pattern_alternatives.rs:18:34 | LL | if let &Value::B | &Value::A(Some(_)) = ref_value {} | ^^^^^^^ @@ -17,7 +17,7 @@ LL | if let &Value::B | &Value::A(Some(_)) = ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_alternatives.rs:19:32 + --> tests/ui/pattern_type_mismatch/pattern_alternatives.rs:21:32 | LL | if let Value::B | Value::A(Some(_)) = *ref_value {} | ^^^^^^^ diff --git a/tests/ui/pattern_type_mismatch/pattern_structs.rs b/tests/ui/pattern_type_mismatch/pattern_structs.rs index d9b22693f297..862953120b4c 100644 --- a/tests/ui/pattern_type_mismatch/pattern_structs.rs +++ b/tests/ui/pattern_type_mismatch/pattern_structs.rs @@ -11,11 +11,14 @@ fn struct_types() { // not ok let Struct { .. } = ref_value; - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let &Struct { ref_inner: Some(_) } = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let Struct { ref_inner: Some(_) } = *ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok let &Struct { .. } = ref_value; @@ -33,15 +36,20 @@ fn struct_enum_variants() { // not ok if let StructEnum::Var { .. } = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let StructEnum::Var { inner_ref: Some(_) } = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let StructEnum::Empty = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok if let &StructEnum::Var { .. } = ref_value {} diff --git a/tests/ui/pattern_type_mismatch/pattern_structs.stderr b/tests/ui/pattern_type_mismatch/pattern_structs.stderr index e5d6e9ed6f81..bdb11c73a457 100644 --- a/tests/ui/pattern_type_mismatch/pattern_structs.stderr +++ b/tests/ui/pattern_type_mismatch/pattern_structs.stderr @@ -9,7 +9,7 @@ LL | let Struct { .. } = ref_value; = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]` error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:15:33 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:16:33 | LL | if let &Struct { ref_inner: Some(_) } = ref_value {} | ^^^^^^^ @@ -17,7 +17,7 @@ LL | if let &Struct { ref_inner: Some(_) } = ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:17:32 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:19:32 | LL | if let Struct { ref_inner: Some(_) } = *ref_value {} | ^^^^^^^ @@ -25,7 +25,7 @@ LL | if let Struct { ref_inner: Some(_) } = *ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:35:12 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:38:12 | LL | if let StructEnum::Var { .. } = ref_value {} | ^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | if let StructEnum::Var { .. } = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:37:12 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:41:12 | LL | if let StructEnum::Var { inner_ref: Some(_) } = ref_value {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | if let StructEnum::Var { inner_ref: Some(_) } = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:39:42 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:44:42 | LL | if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {} | ^^^^^^^ @@ -49,7 +49,7 @@ LL | if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:41:41 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:47:41 | LL | if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {} | ^^^^^^^ @@ -57,7 +57,7 @@ LL | if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:43:12 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:50:12 | LL | if let StructEnum::Empty = ref_value {} | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/pattern_type_mismatch/pattern_tuples.rs b/tests/ui/pattern_type_mismatch/pattern_tuples.rs index f44e3543c96a..4847e1a30a20 100644 --- a/tests/ui/pattern_type_mismatch/pattern_tuples.rs +++ b/tests/ui/pattern_type_mismatch/pattern_tuples.rs @@ -9,11 +9,14 @@ fn tuple_types() { // not ok let TupleStruct(_) = ref_value; - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let &TupleStruct(Some(_)) = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let TupleStruct(Some(_)) = *ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok let &TupleStruct(_) = ref_value; @@ -31,13 +34,17 @@ fn tuple_enum_variants() { // not ok if let TupleEnum::Var(_) = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let &TupleEnum::Var(Some(_)) = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let TupleEnum::Var(Some(_)) = *ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let TupleEnum::Empty = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok if let &TupleEnum::Var(_) = ref_value {} @@ -53,11 +60,14 @@ fn plain_tuples() { // not ok let (_a, _b) = ref_value; - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let &(_a, Some(_)) = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + if let (_a, Some(_)) = *ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok let &(_a, _b) = ref_value; diff --git a/tests/ui/pattern_type_mismatch/pattern_tuples.stderr b/tests/ui/pattern_type_mismatch/pattern_tuples.stderr index 9ecf12a1d639..8a80a888f775 100644 --- a/tests/ui/pattern_type_mismatch/pattern_tuples.stderr +++ b/tests/ui/pattern_type_mismatch/pattern_tuples.stderr @@ -9,7 +9,7 @@ LL | let TupleStruct(_) = ref_value; = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]` error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:13:25 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:14:25 | LL | if let &TupleStruct(Some(_)) = ref_value {} | ^^^^^^^ @@ -17,7 +17,7 @@ LL | if let &TupleStruct(Some(_)) = ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:15:24 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:17:24 | LL | if let TupleStruct(Some(_)) = *ref_value {} | ^^^^^^^ @@ -25,7 +25,7 @@ LL | if let TupleStruct(Some(_)) = *ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:33:12 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:36:12 | LL | if let TupleEnum::Var(_) = ref_value {} | ^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | if let TupleEnum::Var(_) = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:35:28 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:39:28 | LL | if let &TupleEnum::Var(Some(_)) = ref_value {} | ^^^^^^^ @@ -41,7 +41,7 @@ LL | if let &TupleEnum::Var(Some(_)) = ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:37:27 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:42:27 | LL | if let TupleEnum::Var(Some(_)) = *ref_value {} | ^^^^^^^ @@ -49,7 +49,7 @@ LL | if let TupleEnum::Var(Some(_)) = *ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:39:12 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:45:12 | LL | if let TupleEnum::Empty = ref_value {} | ^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | if let TupleEnum::Empty = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:55:9 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:62:9 | LL | let (_a, _b) = ref_value; | ^^^^^^^^ @@ -65,7 +65,7 @@ LL | let (_a, _b) = ref_value; = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:57:18 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:65:18 | LL | if let &(_a, Some(_)) = ref_value {} | ^^^^^^^ @@ -73,7 +73,7 @@ LL | if let &(_a, Some(_)) = ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:59:17 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:68:17 | LL | if let (_a, Some(_)) = *ref_value {} | ^^^^^^^ diff --git a/tests/ui/pattern_type_mismatch/syntax.rs b/tests/ui/pattern_type_mismatch/syntax.rs index dbc7c3f31061..77e9ec772aa8 100644 --- a/tests/ui/pattern_type_mismatch/syntax.rs +++ b/tests/ui/pattern_type_mismatch/syntax.rs @@ -9,7 +9,8 @@ fn syntax_match() { // not ok match ref_value { Some(_) => (), - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + None => (), } @@ -29,7 +30,8 @@ fn syntax_if_let() { // not ok if let Some(_) = ref_value {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok if let &Some(_) = ref_value {} @@ -41,7 +43,8 @@ fn syntax_while_let() { // not ok while let Some(_) = ref_value { - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + break; } @@ -60,7 +63,8 @@ fn syntax_for() { // not ok for (_a, _b) in slice.iter() {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok for &(_a, _b) in slice.iter() {} @@ -71,7 +75,8 @@ fn syntax_let() { // not ok let (_n, _m) = ref_value; - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok let &(_n, _m) = ref_value; @@ -81,7 +86,8 @@ fn syntax_let() { fn syntax_fn() { // not ok fn foo((_a, _b): &(i32, i32)) {} - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok fn foo_ok_1(&(_a, _b): &(i32, i32)) {} @@ -96,7 +102,8 @@ fn syntax_closure() { // not ok foo(|(_a, _b)| ()); - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + // ok foo(|&(_a, _b)| ()); @@ -113,7 +120,8 @@ fn macro_with_expression() { // not ok matching_macro!(match value { Some(_) => (), - //~^ ERROR: type of pattern does not match the expression type + //~^ pattern_type_mismatch + _ => (), }); @@ -134,6 +142,7 @@ fn macro_expansion() { // not ok match $e { Some(_) => (), + //~^ pattern_type_mismatch _ => (), } diff --git a/tests/ui/pattern_type_mismatch/syntax.stderr b/tests/ui/pattern_type_mismatch/syntax.stderr index 9186a01b9c75..eec9ea70c69d 100644 --- a/tests/ui/pattern_type_mismatch/syntax.stderr +++ b/tests/ui/pattern_type_mismatch/syntax.stderr @@ -9,7 +9,7 @@ LL | Some(_) => (), = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]` error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:31:12 + --> tests/ui/pattern_type_mismatch/syntax.rs:32:12 | LL | if let Some(_) = ref_value {} | ^^^^^^^ @@ -17,7 +17,7 @@ LL | if let Some(_) = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:43:15 + --> tests/ui/pattern_type_mismatch/syntax.rs:45:15 | LL | while let Some(_) = ref_value { | ^^^^^^^ @@ -25,7 +25,7 @@ LL | while let Some(_) = ref_value { = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:62:9 + --> tests/ui/pattern_type_mismatch/syntax.rs:65:9 | LL | for (_a, _b) in slice.iter() {} | ^^^^^^^^ @@ -33,7 +33,7 @@ LL | for (_a, _b) in slice.iter() {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:73:9 + --> tests/ui/pattern_type_mismatch/syntax.rs:77:9 | LL | let (_n, _m) = ref_value; | ^^^^^^^^ @@ -41,7 +41,7 @@ LL | let (_n, _m) = ref_value; = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:83:12 + --> tests/ui/pattern_type_mismatch/syntax.rs:88:12 | LL | fn foo((_a, _b): &(i32, i32)) {} | ^^^^^^^^ @@ -49,7 +49,7 @@ LL | fn foo((_a, _b): &(i32, i32)) {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:98:10 + --> tests/ui/pattern_type_mismatch/syntax.rs:104:10 | LL | foo(|(_a, _b)| ()); | ^^^^^^^^ @@ -57,7 +57,7 @@ LL | foo(|(_a, _b)| ()); = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:115:9 + --> tests/ui/pattern_type_mismatch/syntax.rs:122:9 | LL | Some(_) => (), | ^^^^^^^ @@ -65,7 +65,7 @@ LL | Some(_) => (), = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:136:17 + --> tests/ui/pattern_type_mismatch/syntax.rs:144:17 | LL | Some(_) => (), | ^^^^^^^ diff --git a/tests/ui/patterns.fixed b/tests/ui/patterns.fixed index feaec33ac15a..a119096865a0 100644 --- a/tests/ui/patterns.fixed +++ b/tests/ui/patterns.fixed @@ -12,6 +12,7 @@ fn main() { match v { Some(x) => (), y => (), + //~^ redundant_pattern } match v { Some(x) => (), @@ -27,6 +28,7 @@ fn main() { // required "ref" left out in suggestion: #5271 match mutv { ref mut x => { + //~^ redundant_pattern x.push(4); println!("vec: {:?}", x); }, @@ -35,6 +37,7 @@ fn main() { match mutv { ref x => println!("vec: {:?}", x), + //~^ redundant_pattern ref y if y == &vec![0] => (), } external! { diff --git a/tests/ui/patterns.rs b/tests/ui/patterns.rs index 53812c7deec3..4ba6ac319af9 100644 --- a/tests/ui/patterns.rs +++ b/tests/ui/patterns.rs @@ -12,6 +12,7 @@ fn main() { match v { Some(x) => (), y @ _ => (), + //~^ redundant_pattern } match v { Some(x) => (), @@ -27,6 +28,7 @@ fn main() { // required "ref" left out in suggestion: #5271 match mutv { ref mut x @ _ => { + //~^ redundant_pattern x.push(4); println!("vec: {:?}", x); }, @@ -35,6 +37,7 @@ fn main() { match mutv { ref x @ _ => println!("vec: {:?}", x), + //~^ redundant_pattern ref y if y == &vec![0] => (), } external! { diff --git a/tests/ui/patterns.stderr b/tests/ui/patterns.stderr index fa4cf7f83562..b9950fe181cc 100644 --- a/tests/ui/patterns.stderr +++ b/tests/ui/patterns.stderr @@ -8,13 +8,13 @@ LL | y @ _ => (), = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern)]` error: the `x @ _` pattern can be written as just `x` - --> tests/ui/patterns.rs:29:9 + --> tests/ui/patterns.rs:30:9 | LL | ref mut x @ _ => { | ^^^^^^^^^^^^^ help: try: `ref mut x` error: the `x @ _` pattern can be written as just `x` - --> tests/ui/patterns.rs:37:9 + --> tests/ui/patterns.rs:39:9 | LL | ref x @ _ => println!("vec: {:?}", x), | ^^^^^^^^^ help: try: `ref x` diff --git a/tests/ui/permissions_set_readonly_false.rs b/tests/ui/permissions_set_readonly_false.rs index 5a84a64fd2d1..652ffd724d95 100644 --- a/tests/ui/permissions_set_readonly_false.rs +++ b/tests/ui/permissions_set_readonly_false.rs @@ -17,8 +17,9 @@ fn main() { let mut permissions = metadata.permissions(); // lint here permissions.set_readonly(false); - //~^ ERROR: call to `set_readonly` with argument `false` - //~| NOTE: on Unix platforms this results in the file being world writable + //~^ permissions_set_readonly_false + + // no lint permissions.set_readonly(true); diff --git a/tests/ui/pointers_in_nomem_asm_block.rs b/tests/ui/pointers_in_nomem_asm_block.rs index b5abcbb3474c..6d23bd78e919 100644 --- a/tests/ui/pointers_in_nomem_asm_block.rs +++ b/tests/ui/pointers_in_nomem_asm_block.rs @@ -9,7 +9,8 @@ unsafe fn nomem_bad(p: &i32) { asm!( "asdf {p1}, {p2}, {p3}", p1 = in(reg) p, - //~^ ERROR: passing pointers to nomem asm block + //~^ pointers_in_nomem_asm_block + p2 = in(reg) p as *const _ as usize, p3 = in(reg) p, options(nomem, nostack, preserves_flags) @@ -24,10 +25,12 @@ unsafe fn nomem_good(p: &i32) { unsafe fn nomem_bad2(p: &mut i32) { asm!("asdf {p}", p = in(reg) p, options(nomem, nostack, preserves_flags)); - //~^ ERROR: passing pointers to nomem asm block + //~^ pointers_in_nomem_asm_block + } unsafe fn nomem_fn(p: extern "C" fn()) { asm!("call {p}", p = in(reg) p, options(nomem)); - //~^ ERROR: passing pointers to nomem asm block + //~^ pointers_in_nomem_asm_block + } diff --git a/tests/ui/pointers_in_nomem_asm_block.stderr b/tests/ui/pointers_in_nomem_asm_block.stderr index cabeb37344f2..6de9c476312a 100644 --- a/tests/ui/pointers_in_nomem_asm_block.stderr +++ b/tests/ui/pointers_in_nomem_asm_block.stderr @@ -13,7 +13,7 @@ LL | p3 = in(reg) p, = help: to override `-D warnings` add `#[allow(clippy::pointers_in_nomem_asm_block)]` error: passing pointers to nomem asm block - --> tests/ui/pointers_in_nomem_asm_block.rs:26:22 + --> tests/ui/pointers_in_nomem_asm_block.rs:27:22 | LL | asm!("asdf {p}", p = in(reg) p, options(nomem, nostack, preserves_flags)); | ^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | asm!("asdf {p}", p = in(reg) p, options(nomem, nostack, preserves_flags = note: if this is intentional and no pointers are read or written to, consider allowing the lint error: passing pointers to nomem asm block - --> tests/ui/pointers_in_nomem_asm_block.rs:31:22 + --> tests/ui/pointers_in_nomem_asm_block.rs:33:22 | LL | asm!("call {p}", p = in(reg) p, options(nomem)); | ^^^^^^^^^^^^^ diff --git a/tests/ui/precedence.fixed b/tests/ui/precedence.fixed index 52144a18bac0..cbb78bff68bf 100644 --- a/tests/ui/precedence.fixed +++ b/tests/ui/precedence.fixed @@ -14,12 +14,19 @@ macro_rules! trip { fn main() { 1 << (2 + 3); + //~^ precedence (1 + 2) << 3; + //~^ precedence 4 >> (1 + 1); + //~^ precedence (1 + 3) >> 2; + //~^ precedence 1 ^ (1 - 1); + //~^ precedence 3 | (2 - 1); + //~^ precedence 3 & (5 - 2); + //~^ precedence 0x0F00 & 0x00F0 << 4; 0x0F00 & 0xF000 >> 4; 0x0F00 << 1 ^ 3; diff --git a/tests/ui/precedence.rs b/tests/ui/precedence.rs index 9ef5c43833f8..c73a4020e2e5 100644 --- a/tests/ui/precedence.rs +++ b/tests/ui/precedence.rs @@ -14,12 +14,19 @@ macro_rules! trip { fn main() { 1 << 2 + 3; + //~^ precedence 1 + 2 << 3; + //~^ precedence 4 >> 1 + 1; + //~^ precedence 1 + 3 >> 2; + //~^ precedence 1 ^ 1 - 1; + //~^ precedence 3 | 2 - 1; + //~^ precedence 3 & 5 - 2; + //~^ precedence 0x0F00 & 0x00F0 << 4; 0x0F00 & 0xF000 >> 4; 0x0F00 << 1 ^ 3; diff --git a/tests/ui/precedence.stderr b/tests/ui/precedence.stderr index 68ad5cb4829a..50cd8f4b8146 100644 --- a/tests/ui/precedence.stderr +++ b/tests/ui/precedence.stderr @@ -8,37 +8,37 @@ LL | 1 << 2 + 3; = help: to override `-D warnings` add `#[allow(clippy::precedence)]` error: operator precedence might not be obvious - --> tests/ui/precedence.rs:17:5 + --> tests/ui/precedence.rs:18:5 | LL | 1 + 2 << 3; | ^^^^^^^^^^ help: consider parenthesizing your expression: `(1 + 2) << 3` error: operator precedence might not be obvious - --> tests/ui/precedence.rs:18:5 + --> tests/ui/precedence.rs:20:5 | LL | 4 >> 1 + 1; | ^^^^^^^^^^ help: consider parenthesizing your expression: `4 >> (1 + 1)` error: operator precedence might not be obvious - --> tests/ui/precedence.rs:19:5 + --> tests/ui/precedence.rs:22:5 | LL | 1 + 3 >> 2; | ^^^^^^^^^^ help: consider parenthesizing your expression: `(1 + 3) >> 2` error: operator precedence might not be obvious - --> tests/ui/precedence.rs:20:5 + --> tests/ui/precedence.rs:24:5 | LL | 1 ^ 1 - 1; | ^^^^^^^^^ help: consider parenthesizing your expression: `1 ^ (1 - 1)` error: operator precedence might not be obvious - --> tests/ui/precedence.rs:21:5 + --> tests/ui/precedence.rs:26:5 | LL | 3 | 2 - 1; | ^^^^^^^^^ help: consider parenthesizing your expression: `3 | (2 - 1)` error: operator precedence might not be obvious - --> tests/ui/precedence.rs:22:5 + --> tests/ui/precedence.rs:28:5 | LL | 3 & 5 - 2; | ^^^^^^^^^ help: consider parenthesizing your expression: `3 & (5 - 2)` diff --git a/tests/ui/precedence_bits.fixed b/tests/ui/precedence_bits.fixed index 82fea0d14e43..e0ce4a992bb1 100644 --- a/tests/ui/precedence_bits.fixed +++ b/tests/ui/precedence_bits.fixed @@ -26,9 +26,13 @@ fn main() { 3 | 2 - 1; 3 & 5 - 2; 0x0F00 & (0x00F0 << 4); + //~^ precedence_bits 0x0F00 & (0xF000 >> 4); + //~^ precedence_bits (0x0F00 << 1) ^ 3; + //~^ precedence_bits (0x0F00 << 1) | 2; + //~^ precedence_bits let b = 3; trip!(b * 8); diff --git a/tests/ui/precedence_bits.rs b/tests/ui/precedence_bits.rs index 9b353308b6ee..20d17e26c355 100644 --- a/tests/ui/precedence_bits.rs +++ b/tests/ui/precedence_bits.rs @@ -26,9 +26,13 @@ fn main() { 3 | 2 - 1; 3 & 5 - 2; 0x0F00 & 0x00F0 << 4; + //~^ precedence_bits 0x0F00 & 0xF000 >> 4; + //~^ precedence_bits 0x0F00 << 1 ^ 3; + //~^ precedence_bits 0x0F00 << 1 | 2; + //~^ precedence_bits let b = 3; trip!(b * 8); diff --git a/tests/ui/precedence_bits.stderr b/tests/ui/precedence_bits.stderr index f468186b363c..9cbdca8956d6 100644 --- a/tests/ui/precedence_bits.stderr +++ b/tests/ui/precedence_bits.stderr @@ -8,19 +8,19 @@ LL | 0x0F00 & 0x00F0 << 4; = help: to override `-D warnings` add `#[allow(clippy::precedence_bits)]` error: operator precedence might not be obvious - --> tests/ui/precedence_bits.rs:29:5 + --> tests/ui/precedence_bits.rs:30:5 | LL | 0x0F00 & 0xF000 >> 4; | ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0xF000 >> 4)` error: operator precedence might not be obvious - --> tests/ui/precedence_bits.rs:30:5 + --> tests/ui/precedence_bits.rs:32:5 | LL | 0x0F00 << 1 ^ 3; | ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) ^ 3` error: operator precedence might not be obvious - --> tests/ui/precedence_bits.rs:31:5 + --> tests/ui/precedence_bits.rs:34:5 | LL | 0x0F00 << 1 | 2; | ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) | 2` diff --git a/tests/ui/print.rs b/tests/ui/print.rs index 9ac4b51e1afd..7f7b8eb15b5d 100644 --- a/tests/ui/print.rs +++ b/tests/ui/print.rs @@ -9,8 +9,9 @@ struct Foo; impl Display for Foo { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "{:?}", 43.1415) - //~^ ERROR: use of `Debug`-based formatting - //~| NOTE: `-D clippy::use-debug` implied by `-D warnings` + //~^ use_debug + + } } @@ -23,21 +24,28 @@ impl Debug for Foo { fn main() { println!("Hello"); - //~^ ERROR: use of `println!` - //~| NOTE: `-D clippy::print-stdout` implied by `-D warnings` + //~^ print_stdout + + print!("Hello"); - //~^ ERROR: use of `print!` + //~^ print_stdout + print!("Hello {}", "World"); - //~^ ERROR: use of `print!` + //~^ print_stdout + print!("Hello {:?}", "World"); - //~^ ERROR: use of `print!` - //~| ERROR: use of `Debug`-based formatting + //~^ print_stdout + //~| use_debug + + print!("Hello {:#?}", "#orld"); - //~^ ERROR: use of `print!` - //~| ERROR: use of `Debug`-based formatting + //~^ print_stdout + //~| use_debug + + assert_eq!(42, 1337); diff --git a/tests/ui/print.stderr b/tests/ui/print.stderr index a8374241c831..4e9d4135486c 100644 --- a/tests/ui/print.stderr +++ b/tests/ui/print.stderr @@ -8,7 +8,7 @@ LL | write!(f, "{:?}", 43.1415) = help: to override `-D warnings` add `#[allow(clippy::use_debug)]` error: use of `println!` - --> tests/ui/print.rs:25:5 + --> tests/ui/print.rs:26:5 | LL | println!("Hello"); | ^^^^^^^^^^^^^^^^^ @@ -17,37 +17,37 @@ LL | println!("Hello"); = help: to override `-D warnings` add `#[allow(clippy::print_stdout)]` error: use of `print!` - --> tests/ui/print.rs:28:5 + --> tests/ui/print.rs:30:5 | LL | print!("Hello"); | ^^^^^^^^^^^^^^^ error: use of `print!` - --> tests/ui/print.rs:31:5 + --> tests/ui/print.rs:34:5 | LL | print!("Hello {}", "World"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `print!` - --> tests/ui/print.rs:34:5 + --> tests/ui/print.rs:38:5 | LL | print!("Hello {:?}", "World"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `Debug`-based formatting - --> tests/ui/print.rs:34:19 + --> tests/ui/print.rs:38:19 | LL | print!("Hello {:?}", "World"); | ^^^^ error: use of `print!` - --> tests/ui/print.rs:38:5 + --> tests/ui/print.rs:44:5 | LL | print!("Hello {:#?}", "#orld"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `Debug`-based formatting - --> tests/ui/print.rs:38:19 + --> tests/ui/print.rs:44:19 | LL | print!("Hello {:#?}", "#orld"); | ^^^^^ diff --git a/tests/ui/print_in_format_impl.rs b/tests/ui/print_in_format_impl.rs index 261f50832199..fdf630355044 100644 --- a/tests/ui/print_in_format_impl.rs +++ b/tests/ui/print_in_format_impl.rs @@ -18,17 +18,22 @@ impl Debug for Foo { static WORKS_WITH_NESTED_ITEMS: bool = true; print!("{}", 1); - //~^ ERROR: use of `print!` in `Debug` impl - //~| NOTE: `-D clippy::print-in-format-impl` implied by `-D warnings` + //~^ print_in_format_impl + + println!("{}", 2); - //~^ ERROR: use of `println!` in `Debug` impl + //~^ print_in_format_impl + eprint!("{}", 3); - //~^ ERROR: use of `eprint!` in `Debug` impl + //~^ print_in_format_impl + eprintln!("{}", 4); - //~^ ERROR: use of `eprintln!` in `Debug` impl + //~^ print_in_format_impl + nested! { println!("nested"); - //~^ ERROR: use of `println!` in `Debug` impl + //~^ print_in_format_impl + }; write!(f, "{}", 5); @@ -42,7 +47,8 @@ impl Debug for Foo { impl Display for Foo { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { print!("Display"); - //~^ ERROR: use of `print!` in `Display` impl + //~^ print_in_format_impl + write!(f, "Display"); Ok(()) @@ -53,7 +59,8 @@ struct UnnamedFormatter; impl Debug for UnnamedFormatter { fn fmt(&self, _: &mut Formatter) -> Result<(), Error> { println!("UnnamedFormatter"); - //~^ ERROR: use of `println!` in `Debug` impl + //~^ print_in_format_impl + Ok(()) } } diff --git a/tests/ui/print_in_format_impl.stderr b/tests/ui/print_in_format_impl.stderr index 3fb6b3f9c911..1a9c62d39e03 100644 --- a/tests/ui/print_in_format_impl.stderr +++ b/tests/ui/print_in_format_impl.stderr @@ -8,37 +8,37 @@ LL | print!("{}", 1); = help: to override `-D warnings` add `#[allow(clippy::print_in_format_impl)]` error: use of `println!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:23:9 + --> tests/ui/print_in_format_impl.rs:24:9 | LL | println!("{}", 2); | ^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)` error: use of `eprint!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:25:9 + --> tests/ui/print_in_format_impl.rs:27:9 | LL | eprint!("{}", 3); | ^^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)` error: use of `eprintln!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:27:9 + --> tests/ui/print_in_format_impl.rs:30:9 | LL | eprintln!("{}", 4); | ^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)` error: use of `println!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:30:13 + --> tests/ui/print_in_format_impl.rs:34:13 | LL | println!("nested"); | ^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)` error: use of `print!` in `Display` impl - --> tests/ui/print_in_format_impl.rs:44:9 + --> tests/ui/print_in_format_impl.rs:49:9 | LL | print!("Display"); | ^^^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)` error: use of `println!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:55:9 + --> tests/ui/print_in_format_impl.rs:61:9 | LL | println!("UnnamedFormatter"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(..)` diff --git a/tests/ui/print_literal.fixed b/tests/ui/print_literal.fixed index 328e9a9b999f..bcf022badc6e 100644 --- a/tests/ui/print_literal.fixed +++ b/tests/ui/print_literal.fixed @@ -25,28 +25,36 @@ fn main() { // these should throw warnings print!("Hello world"); - //~^ ERROR: literal with an empty format string - //~| NOTE: `-D clippy::print-literal` implied by `-D warnings` + //~^ print_literal + + println!("Hello {} world", world); - //~^ ERROR: literal with an empty format string + //~^ print_literal + println!("Hello world"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + println!("a literal {:.4}", 5); - //~^ ERROR: literal with an empty format string + //~^ print_literal + // positional args don't change the fact // that we're using a literal -- this should // throw a warning println!("hello world"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + println!("world hello"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + // named args shouldn't change anything either println!("hello world"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + println!("world hello"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + // The string literal from `file!()` has a callsite span that isn't marked as coming from an // expansion @@ -54,23 +62,33 @@ fn main() { // Braces in unicode escapes should not be escaped println!("{{}} \x00 \u{ab123} \\\u{ab123} {{:?}}"); + //~^ print_literal println!("\\\u{1234}"); + //~^ print_literal // This does not lint because it would have to suggest unescaping the character println!(r"{}", "\u{ab123}"); // These are not unicode escapes println!("\\u{{ab123}} \\u{{{{"); + //~^ print_literal println!(r"\u{{ab123}} \u{{{{"); + //~^ print_literal println!("\\{{ab123}} \\u{{{{"); + //~^ print_literal println!("\\u{{ab123}}"); + //~^ print_literal println!("\\\\u{{1234}}"); + //~^ print_literal println!("mixed: {{hello}} {world}"); + //~^ print_literal } fn issue_13959() { println!("\""); + //~^ print_literal println!( " + //~^ print_literal foo \\ \\\\ diff --git a/tests/ui/print_literal.rs b/tests/ui/print_literal.rs index 3130d0b6998e..96c150ae4810 100644 --- a/tests/ui/print_literal.rs +++ b/tests/ui/print_literal.rs @@ -25,28 +25,36 @@ fn main() { // these should throw warnings print!("Hello {}", "world"); - //~^ ERROR: literal with an empty format string - //~| NOTE: `-D clippy::print-literal` implied by `-D warnings` + //~^ print_literal + + println!("Hello {} {}", world, "world"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + println!("Hello {}", "world"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + println!("{} {:.4}", "a literal", 5); - //~^ ERROR: literal with an empty format string + //~^ print_literal + // positional args don't change the fact // that we're using a literal -- this should // throw a warning println!("{0} {1}", "hello", "world"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + println!("{1} {0}", "hello", "world"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + // named args shouldn't change anything either println!("{foo} {bar}", foo = "hello", bar = "world"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + println!("{bar} {foo}", foo = "hello", bar = "world"); - //~^ ERROR: literal with an empty format string + //~^ print_literal + // The string literal from `file!()` has a callsite span that isn't marked as coming from an // expansion @@ -54,24 +62,34 @@ fn main() { // Braces in unicode escapes should not be escaped println!("{}", "{} \x00 \u{ab123} \\\u{ab123} {:?}"); + //~^ print_literal println!("{}", "\\\u{1234}"); + //~^ print_literal // This does not lint because it would have to suggest unescaping the character println!(r"{}", "\u{ab123}"); // These are not unicode escapes println!("{}", r"\u{ab123} \u{{"); + //~^ print_literal println!(r"{}", r"\u{ab123} \u{{"); + //~^ print_literal println!("{}", r"\{ab123} \u{{"); + //~^ print_literal println!("{}", "\\u{ab123}"); + //~^ print_literal println!("{}", "\\\\u{1234}"); + //~^ print_literal println!("mixed: {} {world}", "{hello}"); + //~^ print_literal } fn issue_13959() { println!("{}", r#"""#); + //~^ print_literal println!( "{}", r#" + //~^ print_literal foo \ \\ diff --git a/tests/ui/print_literal.stderr b/tests/ui/print_literal.stderr index d967b7c24070..c2bc7d495f27 100644 --- a/tests/ui/print_literal.stderr +++ b/tests/ui/print_literal.stderr @@ -13,7 +13,7 @@ LL + print!("Hello world"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:30:36 + --> tests/ui/print_literal.rs:31:36 | LL | println!("Hello {} {}", world, "world"); | ^^^^^^^ @@ -25,7 +25,7 @@ LL + println!("Hello {} world", world); | error: literal with an empty format string - --> tests/ui/print_literal.rs:32:26 + --> tests/ui/print_literal.rs:34:26 | LL | println!("Hello {}", "world"); | ^^^^^^^ @@ -37,7 +37,7 @@ LL + println!("Hello world"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:34:26 + --> tests/ui/print_literal.rs:37:26 | LL | println!("{} {:.4}", "a literal", 5); | ^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + println!("a literal {:.4}", 5); | error: literal with an empty format string - --> tests/ui/print_literal.rs:40:25 + --> tests/ui/print_literal.rs:44:25 | LL | println!("{0} {1}", "hello", "world"); | ^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + println!("hello world"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:42:25 + --> tests/ui/print_literal.rs:47:25 | LL | println!("{1} {0}", "hello", "world"); | ^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + println!("world hello"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:46:35 + --> tests/ui/print_literal.rs:52:35 | LL | println!("{foo} {bar}", foo = "hello", bar = "world"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + println!("hello world"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:48:35 + --> tests/ui/print_literal.rs:55:35 | LL | println!("{bar} {foo}", foo = "hello", bar = "world"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL + println!("world hello"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:56:20 + --> tests/ui/print_literal.rs:64:20 | LL | println!("{}", "{} \x00 \u{ab123} \\\u{ab123} {:?}"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL + println!("{{}} \x00 \u{ab123} \\\u{ab123} {{:?}}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:57:20 + --> tests/ui/print_literal.rs:66:20 | LL | println!("{}", "\\\u{1234}"); | ^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL + println!("\\\u{1234}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:61:20 + --> tests/ui/print_literal.rs:71:20 | LL | println!("{}", r"\u{ab123} \u{{"); | ^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL + println!("\\u{{ab123}} \\u{{{{"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:62:21 + --> tests/ui/print_literal.rs:73:21 | LL | println!(r"{}", r"\u{ab123} \u{{"); | ^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL + println!(r"\u{{ab123}} \u{{{{"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:63:20 + --> tests/ui/print_literal.rs:75:20 | LL | println!("{}", r"\{ab123} \u{{"); | ^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL + println!("\\{{ab123}} \\u{{{{"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:64:20 + --> tests/ui/print_literal.rs:77:20 | LL | println!("{}", "\\u{ab123}"); | ^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL + println!("\\u{{ab123}}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:65:20 + --> tests/ui/print_literal.rs:79:20 | LL | println!("{}", "\\\\u{1234}"); | ^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + println!("\\\\u{{1234}}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:67:35 + --> tests/ui/print_literal.rs:82:35 | LL | println!("mixed: {} {world}", "{hello}"); | ^^^^^^^^^ @@ -193,7 +193,7 @@ LL + println!("mixed: {{hello}} {world}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:71:20 + --> tests/ui/print_literal.rs:87:20 | LL | println!("{}", r#"""#); | ^^^^^^ @@ -205,12 +205,12 @@ LL + println!("\""); | error: literal with an empty format string - --> tests/ui/print_literal.rs:74:9 + --> tests/ui/print_literal.rs:91:9 | LL | / r#" +LL | | LL | | foo LL | | \ -LL | | \\ ... | LL | | bar LL | | "# @@ -219,6 +219,7 @@ LL | | "# help: try | LL ~ " +LL + LL + foo LL + \\ LL + \\\\ diff --git a/tests/ui/print_stderr.rs b/tests/ui/print_stderr.rs index 109f43ffe25d..2ad2c97b7cc1 100644 --- a/tests/ui/print_stderr.rs +++ b/tests/ui/print_stderr.rs @@ -2,10 +2,12 @@ fn main() { eprintln!("Hello"); - //~^ ERROR: use of `eprintln!` - //~| NOTE: `-D clippy::print-stderr` implied by `-D warnings` + //~^ print_stderr + + println!("This should not do anything"); eprint!("World"); - //~^ ERROR: use of `eprint!` + //~^ print_stderr + print!("Nor should this"); } diff --git a/tests/ui/print_stderr.stderr b/tests/ui/print_stderr.stderr index 17019b886905..7dfe72934c64 100644 --- a/tests/ui/print_stderr.stderr +++ b/tests/ui/print_stderr.stderr @@ -8,7 +8,7 @@ LL | eprintln!("Hello"); = help: to override `-D warnings` add `#[allow(clippy::print_stderr)]` error: use of `eprint!` - --> tests/ui/print_stderr.rs:8:5 + --> tests/ui/print_stderr.rs:9:5 | LL | eprint!("World"); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/print_stdout_build_script.rs b/tests/ui/print_stdout_build_script.rs index 91448cb0faf8..f01b8538ef49 100644 --- a/tests/ui/print_stdout_build_script.rs +++ b/tests/ui/print_stdout_build_script.rs @@ -1,4 +1,5 @@ //@compile-flags: --crate-name=build_script_build +//@ check-pass #![warn(clippy::print_stdout)] diff --git a/tests/ui/print_with_newline.fixed b/tests/ui/print_with_newline.fixed index 7ac6d2870c12..79bd8a2c8d36 100644 --- a/tests/ui/print_with_newline.fixed +++ b/tests/ui/print_with_newline.fixed @@ -5,16 +5,21 @@ fn main() { println!("Hello"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline - //~| NOTE: `-D clippy::print-with-newline` implied by `-D warnings` + //~^ print_with_newline + + println!("Hello {}", "world"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + println!("Hello {} {}", "world", "#2"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + println!("{}", 1265); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + println!(); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + // these are all fine print!(""); @@ -37,7 +42,8 @@ fn main() { // #3514 print!("\\n"); println!("\\"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + print!("\\\\n"); // Raw strings @@ -46,11 +52,13 @@ fn main() { // Literal newlines should also fail println!( - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + ); println!( - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + ); @@ -59,7 +67,8 @@ fn main() { print!("foo\r\n"); // should fail println!("\\r"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + print!("foo\rbar\n"); // Ignore expanded format strings diff --git a/tests/ui/print_with_newline.rs b/tests/ui/print_with_newline.rs index 602d1ea3ec0e..a9cbd214fc61 100644 --- a/tests/ui/print_with_newline.rs +++ b/tests/ui/print_with_newline.rs @@ -5,16 +5,21 @@ fn main() { print!("Hello\n"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline - //~| NOTE: `-D clippy::print-with-newline` implied by `-D warnings` + //~^ print_with_newline + + print!("Hello {}\n", "world"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + print!("Hello {} {}\n", "world", "#2"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + print!("{}\n", 1265); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + print!("\n"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + // these are all fine print!(""); @@ -37,7 +42,8 @@ fn main() { // #3514 print!("\\n"); print!("\\\n"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + print!("\\\\n"); // Raw strings @@ -46,12 +52,14 @@ fn main() { // Literal newlines should also fail print!( - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + " " ); print!( - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + r" " ); @@ -61,7 +69,8 @@ fn main() { print!("foo\r\n"); // should fail print!("\\r\n"); - //~^ ERROR: using `print!()` with a format string that ends in a single newline + //~^ print_with_newline + print!("foo\rbar\n"); // Ignore expanded format strings diff --git a/tests/ui/print_with_newline.stderr b/tests/ui/print_with_newline.stderr index 9b07299e61d3..45f858d68966 100644 --- a/tests/ui/print_with_newline.stderr +++ b/tests/ui/print_with_newline.stderr @@ -13,7 +13,7 @@ LL + println!("Hello"); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:10:5 + --> tests/ui/print_with_newline.rs:11:5 | LL | print!("Hello {}\n", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + println!("Hello {}", "world"); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:12:5 + --> tests/ui/print_with_newline.rs:14:5 | LL | print!("Hello {} {}\n", "world", "#2"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + println!("Hello {} {}", "world", "#2"); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:14:5 + --> tests/ui/print_with_newline.rs:17:5 | LL | print!("{}\n", 1265); | ^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + println!("{}", 1265); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:16:5 + --> tests/ui/print_with_newline.rs:20:5 | LL | print!("\n"); | ^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + println!(); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:39:5 + --> tests/ui/print_with_newline.rs:44:5 | LL | print!("\\\n"); | ^^^^^^^^^^^^^^ @@ -73,10 +73,11 @@ LL + println!("\\"); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:48:5 + --> tests/ui/print_with_newline.rs:54:5 | LL | / print!( LL | | +LL | | LL | | " LL | | " LL | | ); @@ -86,14 +87,16 @@ help: use `println!` instead | LL ~ println!( LL | +LL | LL ~ | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:53:5 + --> tests/ui/print_with_newline.rs:60:5 | LL | / print!( LL | | +LL | | LL | | r" LL | | " LL | | ); @@ -103,11 +106,12 @@ help: use `println!` instead | LL ~ println!( LL | +LL | LL ~ | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:63:5 + --> tests/ui/print_with_newline.rs:71:5 | LL | print!("\\r\n"); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/println_empty_string.fixed b/tests/ui/println_empty_string.fixed index 20811fc75323..05e262ec7786 100644 --- a/tests/ui/println_empty_string.fixed +++ b/tests/ui/println_empty_string.fixed @@ -3,15 +3,19 @@ fn main() { println!(); println!(); + //~^ println_empty_string match "a" { _ => println!(), + //~^ println_empty_string } eprintln!(); eprintln!(); + //~^ println_empty_string match "a" { _ => eprintln!(), + //~^ println_empty_string } } diff --git a/tests/ui/println_empty_string.rs b/tests/ui/println_empty_string.rs index 47f7277dce79..028ddb60dbce 100644 --- a/tests/ui/println_empty_string.rs +++ b/tests/ui/println_empty_string.rs @@ -3,15 +3,19 @@ fn main() { println!(); println!(""); + //~^ println_empty_string match "a" { _ => println!(""), + //~^ println_empty_string } eprintln!(); eprintln!(""); + //~^ println_empty_string match "a" { _ => eprintln!(""), + //~^ println_empty_string } } diff --git a/tests/ui/println_empty_string.stderr b/tests/ui/println_empty_string.stderr index 17de05fa25a4..8b997aef9069 100644 --- a/tests/ui/println_empty_string.stderr +++ b/tests/ui/println_empty_string.stderr @@ -10,7 +10,7 @@ LL | println!(""); = help: to override `-D warnings` add `#[allow(clippy::println_empty_string)]` error: empty string literal in `println!` - --> tests/ui/println_empty_string.rs:8:14 + --> tests/ui/println_empty_string.rs:9:14 | LL | _ => println!(""), | ^^^^^^^^^--^ @@ -18,7 +18,7 @@ LL | _ => println!(""), | help: remove the empty string error: empty string literal in `eprintln!` - --> tests/ui/println_empty_string.rs:12:5 + --> tests/ui/println_empty_string.rs:14:5 | LL | eprintln!(""); | ^^^^^^^^^^--^ @@ -26,7 +26,7 @@ LL | eprintln!(""); | help: remove the empty string error: empty string literal in `eprintln!` - --> tests/ui/println_empty_string.rs:15:14 + --> tests/ui/println_empty_string.rs:18:14 | LL | _ => eprintln!(""), | ^^^^^^^^^^--^ diff --git a/tests/ui/ptr_arg.rs b/tests/ui/ptr_arg.rs index e8b42d3b913b..e8332cb97e1b 100644 --- a/tests/ui/ptr_arg.rs +++ b/tests/ui/ptr_arg.rs @@ -11,39 +11,46 @@ use std::borrow::Cow; use std::path::{Path, PathBuf}; fn do_vec(x: &Vec) { - //~^ ERROR: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - //~| NOTE: `-D clippy::ptr-arg` implied by `-D warnings` +//~^ ptr_arg + + //Nothing here } fn do_vec_mut(x: &mut Vec) { - //~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w +//~^ ptr_arg + //Nothing here } fn do_vec_mut2(x: &mut Vec) { - //~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w +//~^ ptr_arg + x.len(); x.is_empty(); } fn do_str(x: &String) { - //~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice will d +//~^ ptr_arg + //Nothing here either } fn do_str_mut(x: &mut String) { - //~^ ERROR: writing `&mut String` instead of `&mut str` involves a new object where a slic +//~^ ptr_arg + //Nothing here either } fn do_path(x: &PathBuf) { - //~^ ERROR: writing `&PathBuf` instead of `&Path` involves a new object where a slice will +//~^ ptr_arg + //Nothing here either } fn do_path_mut(x: &mut PathBuf) { - //~^ ERROR: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a sl +//~^ ptr_arg + //Nothing here either } @@ -52,7 +59,8 @@ fn main() {} trait Foo { type Item; fn do_vec(x: &Vec); - //~^ ERROR: writing `&Vec` instead of `&[_]` involves a new object where a slice will + //~^ ptr_arg + fn do_item(x: &Self::Item); } @@ -66,7 +74,8 @@ impl Foo for Bar { } fn cloned(x: &Vec) -> Vec { - //~^ ERROR: writing `&Vec` instead of `&[_]` involves a new object where a slice will do +//~^ ptr_arg + let e = x.clone(); let f = e.clone(); // OK let g = x; @@ -76,7 +85,8 @@ fn cloned(x: &Vec) -> Vec { } fn str_cloned(x: &String) -> String { - //~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice will d +//~^ ptr_arg + let a = x.clone(); let b = x.clone(); let c = b.clone(); @@ -85,7 +95,8 @@ fn str_cloned(x: &String) -> String { } fn path_cloned(x: &PathBuf) -> PathBuf { - //~^ ERROR: writing `&PathBuf` instead of `&Path` involves a new object where a slice will +//~^ ptr_arg + let a = x.clone(); let b = x.clone(); let c = b.clone(); @@ -94,7 +105,8 @@ fn path_cloned(x: &PathBuf) -> PathBuf { } fn false_positive_capacity(x: &Vec, y: &String) { - //~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice will d +//~^ ptr_arg + let a = x.capacity(); let b = y.clone(); let c = y.as_str(); @@ -109,7 +121,8 @@ fn false_positive_capacity_too(x: &String) -> String { #[allow(dead_code)] fn test_cow_with_ref(c: &Cow<[i32]>) {} -//~^ ERROR: using a reference to `Cow` is not recommended +//~^ ptr_arg + fn test_cow(c: Cow<[i32]>) { let _c = c; @@ -139,7 +152,8 @@ mod issue_5644 { } fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec, _s: &String) {} - //~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice wi + //~^ ptr_arg + struct S; impl S { @@ -169,26 +183,30 @@ mod issue6509 { use std::path::PathBuf; fn foo_vec(vec: &Vec) { - //~^ ERROR: writing `&Vec` instead of `&[_]` involves a new object where a slice will + //~^ ptr_arg + let _ = vec.clone().pop(); let _ = vec.clone().clone(); } fn foo_path(path: &PathBuf) { - //~^ ERROR: writing `&PathBuf` instead of `&Path` involves a new object where a slice + //~^ ptr_arg + let _ = path.clone().pop(); let _ = path.clone().clone(); } fn foo_str(str: &PathBuf) { - //~^ ERROR: writing `&PathBuf` instead of `&Path` involves a new object where a slice + //~^ ptr_arg + let _ = str.clone().pop(); let _ = str.clone().clone(); } } fn mut_vec_slice_methods(v: &mut Vec) { - //~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w +//~^ ptr_arg + v.copy_within(1..5, 10); } @@ -251,9 +269,10 @@ fn dyn_trait_ok(a: &mut Vec, b: &mut String, c: &mut PathBuf) { } fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { - //~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w - //~| ERROR: writing `&mut String` instead of `&mut str` involves a new object where a slic - //~| ERROR: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a sl +//~^ ptr_arg +//~| ptr_arg +//~| ptr_arg + trait T {} impl T for Vec {} impl T for [U] {} @@ -277,22 +296,26 @@ mod issue_9218 { // This one has an anonymous lifetime so it's not okay fn cow_elided_lifetime<'a>(input: &'a Cow) -> &'a str { - //~^ ERROR: using a reference to `Cow` is not recommended + //~^ ptr_arg + todo!() } // These two's return types don't use 'a so it's not okay fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str { - //~^ ERROR: using a reference to `Cow` is not recommended + //~^ ptr_arg + todo!() } fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str { - //~^ ERROR: using a reference to `Cow` is not recommended + //~^ ptr_arg + todo!() } // Inferred to be `&'a str`, afaik. fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str { + //~^ ERROR: elided lifetime has a name todo!() } } @@ -325,8 +348,9 @@ mod issue_13308 { // Other cases that are still ok to lint and ideally shouldn't regress fn good(v1: &String, v2: &String) { - //~^ ERROR: writing `&String` instead of `&str` - //~^^ ERROR: writing `&String` instead of `&str` + //~^ ptr_arg + //~| ptr_arg + h1(v1); h2(String::new(), v2); } diff --git a/tests/ui/ptr_arg.stderr b/tests/ui/ptr_arg.stderr index 1a6b3aa1f8d4..94fa2184fd64 100644 --- a/tests/ui/ptr_arg.stderr +++ b/tests/ui/ptr_arg.stderr @@ -1,5 +1,5 @@ error: elided lifetime has a name - --> tests/ui/ptr_arg.rs:295:56 + --> tests/ui/ptr_arg.rs:317:56 | LL | fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str { | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` @@ -17,49 +17,49 @@ LL | fn do_vec(x: &Vec) { = help: to override `-D warnings` add `#[allow(clippy::ptr_arg)]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:19:18 + --> tests/ui/ptr_arg.rs:20:18 | LL | fn do_vec_mut(x: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:24:19 + --> tests/ui/ptr_arg.rs:26:19 | LL | fn do_vec_mut2(x: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:30:14 + --> tests/ui/ptr_arg.rs:33:14 | LL | fn do_str(x: &String) { | ^^^^^^^ help: change this to: `&str` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:35:18 + --> tests/ui/ptr_arg.rs:39:18 | LL | fn do_str_mut(x: &mut String) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:40:15 + --> tests/ui/ptr_arg.rs:45:15 | LL | fn do_path(x: &PathBuf) { | ^^^^^^^^ help: change this to: `&Path` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:45:19 + --> tests/ui/ptr_arg.rs:51:19 | LL | fn do_path_mut(x: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:54:18 + --> tests/ui/ptr_arg.rs:61:18 | LL | fn do_vec(x: &Vec); | ^^^^^^^^^ help: change this to: `&[i64]` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:68:14 + --> tests/ui/ptr_arg.rs:76:14 | LL | fn cloned(x: &Vec) -> Vec { | ^^^^^^^^ @@ -68,6 +68,7 @@ help: change this to | LL ~ fn cloned(x: &[u8]) -> Vec { LL | +LL | LL ~ let e = x.to_owned(); LL | let f = e.clone(); // OK LL | let g = x; @@ -77,7 +78,7 @@ LL ~ x.to_owned() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:78:18 + --> tests/ui/ptr_arg.rs:87:18 | LL | fn str_cloned(x: &String) -> String { | ^^^^^^^ @@ -86,6 +87,7 @@ help: change this to | LL ~ fn str_cloned(x: &str) -> String { LL | +LL | LL ~ let a = x.to_owned(); LL ~ let b = x.to_owned(); LL | let c = b.clone(); @@ -94,7 +96,7 @@ LL ~ x.to_owned() | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:87:19 + --> tests/ui/ptr_arg.rs:97:19 | LL | fn path_cloned(x: &PathBuf) -> PathBuf { | ^^^^^^^^ @@ -103,6 +105,7 @@ help: change this to | LL ~ fn path_cloned(x: &Path) -> PathBuf { LL | +LL | LL ~ let a = x.to_path_buf(); LL ~ let b = x.to_path_buf(); LL | let c = b.clone(); @@ -111,7 +114,7 @@ LL ~ x.to_path_buf() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:96:44 + --> tests/ui/ptr_arg.rs:107:44 | LL | fn false_positive_capacity(x: &Vec, y: &String) { | ^^^^^^^ @@ -120,25 +123,26 @@ help: change this to | LL ~ fn false_positive_capacity(x: &Vec, y: &str) { LL | +LL | LL | let a = x.capacity(); LL ~ let b = y.to_owned(); LL ~ let c = y; | error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:111:25 + --> tests/ui/ptr_arg.rs:123:25 | LL | fn test_cow_with_ref(c: &Cow<[i32]>) {} | ^^^^^^^^^^^ help: change this to: `&[i32]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:141:66 + --> tests/ui/ptr_arg.rs:154:66 | LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec, _s: &String) {} | ^^^^^^^ help: change this to: `&str` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:171:21 + --> tests/ui/ptr_arg.rs:185:21 | LL | fn foo_vec(vec: &Vec) { | ^^^^^^^^ @@ -147,12 +151,13 @@ help: change this to | LL ~ fn foo_vec(vec: &[u8]) { LL | +LL | LL ~ let _ = vec.to_owned().pop(); LL ~ let _ = vec.to_owned().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:177:23 + --> tests/ui/ptr_arg.rs:192:23 | LL | fn foo_path(path: &PathBuf) { | ^^^^^^^^ @@ -161,12 +166,13 @@ help: change this to | LL ~ fn foo_path(path: &Path) { LL | +LL | LL ~ let _ = path.to_path_buf().pop(); LL ~ let _ = path.to_path_buf().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:183:21 + --> tests/ui/ptr_arg.rs:199:21 | LL | fn foo_str(str: &PathBuf) { | ^^^^^^^^ @@ -175,60 +181,61 @@ help: change this to | LL ~ fn foo_str(str: &Path) { LL | +LL | LL ~ let _ = str.to_path_buf().pop(); LL ~ let _ = str.to_path_buf().clone(); | error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:190:29 + --> tests/ui/ptr_arg.rs:207:29 | LL | fn mut_vec_slice_methods(v: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:253:17 + --> tests/ui/ptr_arg.rs:271:17 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:253:35 + --> tests/ui/ptr_arg.rs:271:35 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:253:51 + --> tests/ui/ptr_arg.rs:271:51 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:279:39 + --> tests/ui/ptr_arg.rs:298:39 | LL | fn cow_elided_lifetime<'a>(input: &'a Cow) -> &'a str { | ^^^^^^^^^^^^ help: change this to: `&str` error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:285:36 + --> tests/ui/ptr_arg.rs:305:36 | LL | fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str { | ^^^^^^^^^^^^^^^^ help: change this to: `&str` error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:289:40 + --> tests/ui/ptr_arg.rs:310:40 | LL | fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str { | ^^^^^^^^^^^^^^^^ help: change this to: `&str` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:327:17 + --> tests/ui/ptr_arg.rs:350:17 | LL | fn good(v1: &String, v2: &String) { | ^^^^^^^ help: change this to: `&str` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:327:30 + --> tests/ui/ptr_arg.rs:350:30 | LL | fn good(v1: &String, v2: &String) { | ^^^^^^^ help: change this to: `&str` diff --git a/tests/ui/ptr_as_ptr.fixed b/tests/ui/ptr_as_ptr.fixed index fa15c323540f..2033f31c1eec 100644 --- a/tests/ui/ptr_as_ptr.fixed +++ b/tests/ui/ptr_as_ptr.fixed @@ -16,6 +16,7 @@ mod issue_11278_b { pub fn f(o: &mut super::issue_11278_a::T) -> super::issue_11278_a::T { // Retain `super` *unsafe { Box::from_raw(Box::into_raw(Box::new(o)).cast::>()) } + //~^ ptr_as_ptr } } @@ -25,12 +26,15 @@ fn main() { let mut_ptr: *mut u32 = &mut 42_u32; let _ = ptr.cast::(); + //~^ ptr_as_ptr let _ = mut_ptr.cast::(); + //~^ ptr_as_ptr // Make sure the lint can handle the difference in their operator precedences. unsafe { let ptr_ptr: *const *const u32 = &ptr; let _ = (*ptr_ptr).cast::(); + //~^ ptr_as_ptr } // Changes in mutability. Do not lint this. @@ -44,10 +48,13 @@ fn main() { // Ensure the lint doesn't produce unnecessary turbofish for inferred types. let _: *const i32 = ptr.cast(); + //~^ ptr_as_ptr let _: *mut i32 = mut_ptr.cast(); + //~^ ptr_as_ptr // Make sure the lint is triggered inside a macro let _ = inline!($ptr.cast::()); + //~^ ptr_as_ptr // Do not lint inside macros from external crates let _ = external!($ptr as *const i32); @@ -69,7 +76,9 @@ fn _msrv_1_38() { let mut_ptr: *mut u32 = &mut 42_u32; let _ = ptr.cast::(); + //~^ ptr_as_ptr let _ = mut_ptr.cast::(); + //~^ ptr_as_ptr } #[allow(clippy::unnecessary_cast)] @@ -77,37 +86,45 @@ mod null { fn use_path_mut() -> *mut u32 { use std::ptr; ptr::null_mut::() + //~^ ptr_as_ptr } fn full_path_mut() -> *mut u32 { std::ptr::null_mut::() + //~^ ptr_as_ptr } fn core_path_mut() -> *mut u32 { use core::ptr; ptr::null_mut::() + //~^ ptr_as_ptr } fn full_core_path_mut() -> *mut u32 { core::ptr::null_mut::() + //~^ ptr_as_ptr } fn use_path() -> *const u32 { use std::ptr; ptr::null::() + //~^ ptr_as_ptr } fn full_path() -> *const u32 { std::ptr::null::() + //~^ ptr_as_ptr } fn core_path() -> *const u32 { use core::ptr; ptr::null::() + //~^ ptr_as_ptr } fn full_core_path() -> *const u32 { core::ptr::null::() + //~^ ptr_as_ptr } } @@ -115,37 +132,45 @@ mod null_ptr_infer { fn use_path_mut() -> *mut u32 { use std::ptr; ptr::null_mut() + //~^ ptr_as_ptr } fn full_path_mut() -> *mut u32 { std::ptr::null_mut() + //~^ ptr_as_ptr } fn core_path_mut() -> *mut u32 { use core::ptr; ptr::null_mut() + //~^ ptr_as_ptr } fn full_core_path_mut() -> *mut u32 { core::ptr::null_mut() + //~^ ptr_as_ptr } fn use_path() -> *const u32 { use std::ptr; ptr::null() + //~^ ptr_as_ptr } fn full_path() -> *const u32 { std::ptr::null() + //~^ ptr_as_ptr } fn core_path() -> *const u32 { use core::ptr; ptr::null() + //~^ ptr_as_ptr } fn full_core_path() -> *const u32 { core::ptr::null() + //~^ ptr_as_ptr } } @@ -153,36 +178,44 @@ mod null_entire_infer { fn use_path_mut() -> *mut u32 { use std::ptr; ptr::null_mut() + //~^ ptr_as_ptr } fn full_path_mut() -> *mut u32 { std::ptr::null_mut() + //~^ ptr_as_ptr } fn core_path_mut() -> *mut u32 { use core::ptr; ptr::null_mut() + //~^ ptr_as_ptr } fn full_core_path_mut() -> *mut u32 { core::ptr::null_mut() + //~^ ptr_as_ptr } fn use_path() -> *const u32 { use std::ptr; ptr::null() + //~^ ptr_as_ptr } fn full_path() -> *const u32 { std::ptr::null() + //~^ ptr_as_ptr } fn core_path() -> *const u32 { use core::ptr; ptr::null() + //~^ ptr_as_ptr } fn full_core_path() -> *const u32 { core::ptr::null() + //~^ ptr_as_ptr } } diff --git a/tests/ui/ptr_as_ptr.rs b/tests/ui/ptr_as_ptr.rs index 7ab52e63da55..224d09b0eb6e 100644 --- a/tests/ui/ptr_as_ptr.rs +++ b/tests/ui/ptr_as_ptr.rs @@ -16,6 +16,7 @@ mod issue_11278_b { pub fn f(o: &mut super::issue_11278_a::T) -> super::issue_11278_a::T { // Retain `super` *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T) } + //~^ ptr_as_ptr } } @@ -25,12 +26,15 @@ fn main() { let mut_ptr: *mut u32 = &mut 42_u32; let _ = ptr as *const i32; + //~^ ptr_as_ptr let _ = mut_ptr as *mut i32; + //~^ ptr_as_ptr // Make sure the lint can handle the difference in their operator precedences. unsafe { let ptr_ptr: *const *const u32 = &ptr; let _ = *ptr_ptr as *const i32; + //~^ ptr_as_ptr } // Changes in mutability. Do not lint this. @@ -44,10 +48,13 @@ fn main() { // Ensure the lint doesn't produce unnecessary turbofish for inferred types. let _: *const i32 = ptr as *const _; + //~^ ptr_as_ptr let _: *mut i32 = mut_ptr as _; + //~^ ptr_as_ptr // Make sure the lint is triggered inside a macro let _ = inline!($ptr as *const i32); + //~^ ptr_as_ptr // Do not lint inside macros from external crates let _ = external!($ptr as *const i32); @@ -69,7 +76,9 @@ fn _msrv_1_38() { let mut_ptr: *mut u32 = &mut 42_u32; let _ = ptr as *const i32; + //~^ ptr_as_ptr let _ = mut_ptr as *mut i32; + //~^ ptr_as_ptr } #[allow(clippy::unnecessary_cast)] @@ -77,37 +86,45 @@ mod null { fn use_path_mut() -> *mut u32 { use std::ptr; ptr::null_mut() as *mut u32 + //~^ ptr_as_ptr } fn full_path_mut() -> *mut u32 { std::ptr::null_mut() as *mut u32 + //~^ ptr_as_ptr } fn core_path_mut() -> *mut u32 { use core::ptr; ptr::null_mut() as *mut u32 + //~^ ptr_as_ptr } fn full_core_path_mut() -> *mut u32 { core::ptr::null_mut() as *mut u32 + //~^ ptr_as_ptr } fn use_path() -> *const u32 { use std::ptr; ptr::null() as *const u32 + //~^ ptr_as_ptr } fn full_path() -> *const u32 { std::ptr::null() as *const u32 + //~^ ptr_as_ptr } fn core_path() -> *const u32 { use core::ptr; ptr::null() as *const u32 + //~^ ptr_as_ptr } fn full_core_path() -> *const u32 { core::ptr::null() as *const u32 + //~^ ptr_as_ptr } } @@ -115,37 +132,45 @@ mod null_ptr_infer { fn use_path_mut() -> *mut u32 { use std::ptr; ptr::null_mut() as *mut _ + //~^ ptr_as_ptr } fn full_path_mut() -> *mut u32 { std::ptr::null_mut() as *mut _ + //~^ ptr_as_ptr } fn core_path_mut() -> *mut u32 { use core::ptr; ptr::null_mut() as *mut _ + //~^ ptr_as_ptr } fn full_core_path_mut() -> *mut u32 { core::ptr::null_mut() as *mut _ + //~^ ptr_as_ptr } fn use_path() -> *const u32 { use std::ptr; ptr::null() as *const _ + //~^ ptr_as_ptr } fn full_path() -> *const u32 { std::ptr::null() as *const _ + //~^ ptr_as_ptr } fn core_path() -> *const u32 { use core::ptr; ptr::null() as *const _ + //~^ ptr_as_ptr } fn full_core_path() -> *const u32 { core::ptr::null() as *const _ + //~^ ptr_as_ptr } } @@ -153,36 +178,44 @@ mod null_entire_infer { fn use_path_mut() -> *mut u32 { use std::ptr; ptr::null_mut() as _ + //~^ ptr_as_ptr } fn full_path_mut() -> *mut u32 { std::ptr::null_mut() as _ + //~^ ptr_as_ptr } fn core_path_mut() -> *mut u32 { use core::ptr; ptr::null_mut() as _ + //~^ ptr_as_ptr } fn full_core_path_mut() -> *mut u32 { core::ptr::null_mut() as _ + //~^ ptr_as_ptr } fn use_path() -> *const u32 { use std::ptr; ptr::null() as _ + //~^ ptr_as_ptr } fn full_path() -> *const u32 { std::ptr::null() as _ + //~^ ptr_as_ptr } fn core_path() -> *const u32 { use core::ptr; ptr::null() as _ + //~^ ptr_as_ptr } fn full_core_path() -> *const u32 { core::ptr::null() as _ + //~^ ptr_as_ptr } } diff --git a/tests/ui/ptr_as_ptr.stderr b/tests/ui/ptr_as_ptr.stderr index 18462620b0a3..66dae8e0135e 100644 --- a/tests/ui/ptr_as_ptr.stderr +++ b/tests/ui/ptr_as_ptr.stderr @@ -8,37 +8,37 @@ LL | *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::i = help: to override `-D warnings` add `#[allow(clippy::ptr_as_ptr)]` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:27:13 + --> tests/ui/ptr_as_ptr.rs:28:13 | LL | let _ = ptr as *const i32; | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:28:13 + --> tests/ui/ptr_as_ptr.rs:30:13 | LL | let _ = mut_ptr as *mut i32; | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:33:17 + --> tests/ui/ptr_as_ptr.rs:36:17 | LL | let _ = *ptr_ptr as *const i32; | ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:46:25 + --> tests/ui/ptr_as_ptr.rs:50:25 | LL | let _: *const i32 = ptr as *const _; | ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:47:23 + --> tests/ui/ptr_as_ptr.rs:52:23 | LL | let _: *mut i32 = mut_ptr as _; | ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:50:21 + --> tests/ui/ptr_as_ptr.rs:56:21 | LL | let _ = inline!($ptr as *const i32); | ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::()` @@ -46,29 +46,17 @@ LL | let _ = inline!($ptr as *const i32); = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:71:13 + --> tests/ui/ptr_as_ptr.rs:78:13 | LL | let _ = ptr as *const i32; | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:72:13 + --> tests/ui/ptr_as_ptr.rs:80:13 | LL | let _ = mut_ptr as *mut i32; | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::()` -error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:79:9 - | -LL | ptr::null_mut() as *mut u32 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::()` - -error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:83:9 - | -LL | std::ptr::null_mut() as *mut u32 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut::()` - error: `as` casting between raw pointers without changing their constness --> tests/ui/ptr_as_ptr.rs:88:9 | @@ -76,127 +64,139 @@ LL | ptr::null_mut() as *mut u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:92:9 + --> tests/ui/ptr_as_ptr.rs:93:9 + | +LL | std::ptr::null_mut() as *mut u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut::()` + +error: `as` casting between raw pointers without changing their constness + --> tests/ui/ptr_as_ptr.rs:99:9 + | +LL | ptr::null_mut() as *mut u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::()` + +error: `as` casting between raw pointers without changing their constness + --> tests/ui/ptr_as_ptr.rs:104:9 | LL | core::ptr::null_mut() as *mut u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:97:9 + --> tests/ui/ptr_as_ptr.rs:110:9 | LL | ptr::null() as *const u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:101:9 + --> tests/ui/ptr_as_ptr.rs:115:9 | LL | std::ptr::null() as *const u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:106:9 + --> tests/ui/ptr_as_ptr.rs:121:9 | LL | ptr::null() as *const u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:110:9 + --> tests/ui/ptr_as_ptr.rs:126:9 | LL | core::ptr::null() as *const u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null::()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:117:9 + --> tests/ui/ptr_as_ptr.rs:134:9 | LL | ptr::null_mut() as *mut _ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:121:9 + --> tests/ui/ptr_as_ptr.rs:139:9 | LL | std::ptr::null_mut() as *mut _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:126:9 + --> tests/ui/ptr_as_ptr.rs:145:9 | LL | ptr::null_mut() as *mut _ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:130:9 + --> tests/ui/ptr_as_ptr.rs:150:9 | LL | core::ptr::null_mut() as *mut _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:135:9 + --> tests/ui/ptr_as_ptr.rs:156:9 | LL | ptr::null() as *const _ | ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:139:9 + --> tests/ui/ptr_as_ptr.rs:161:9 | LL | std::ptr::null() as *const _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:144:9 + --> tests/ui/ptr_as_ptr.rs:167:9 | LL | ptr::null() as *const _ | ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:148:9 + --> tests/ui/ptr_as_ptr.rs:172:9 | LL | core::ptr::null() as *const _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:155:9 + --> tests/ui/ptr_as_ptr.rs:180:9 | LL | ptr::null_mut() as _ | ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:159:9 + --> tests/ui/ptr_as_ptr.rs:185:9 | LL | std::ptr::null_mut() as _ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:164:9 + --> tests/ui/ptr_as_ptr.rs:191:9 | LL | ptr::null_mut() as _ | ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:168:9 + --> tests/ui/ptr_as_ptr.rs:196:9 | LL | core::ptr::null_mut() as _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:173:9 + --> tests/ui/ptr_as_ptr.rs:202:9 | LL | ptr::null() as _ | ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:177:9 + --> tests/ui/ptr_as_ptr.rs:207:9 | LL | std::ptr::null() as _ | ^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:182:9 + --> tests/ui/ptr_as_ptr.rs:213:9 | LL | ptr::null() as _ | ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` error: `as` casting between raw pointers without changing their constness - --> tests/ui/ptr_as_ptr.rs:186:9 + --> tests/ui/ptr_as_ptr.rs:218:9 | LL | core::ptr::null() as _ | ^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()` diff --git a/tests/ui/ptr_cast_constness.fixed b/tests/ui/ptr_cast_constness.fixed index 9a5272c7adc3..6dded72d3e19 100644 --- a/tests/ui/ptr_cast_constness.fixed +++ b/tests/ui/ptr_cast_constness.fixed @@ -13,7 +13,9 @@ use proc_macros::{external, inline_macros}; unsafe fn ptr_to_ref(p: *const T, om: *mut U) { let _: &mut T = std::mem::transmute(p.cast_mut()); + //~^ ptr_cast_constness let _ = &mut *p.cast_mut(); + //~^ ptr_cast_constness let _: &T = &*(om as *const T); } @@ -29,10 +31,13 @@ fn main() { unsafe { let ptr_ptr: *const *const u32 = &ptr; let _ = (*ptr_ptr).cast_mut(); + //~^ ptr_cast_constness } let _ = ptr.cast_mut(); + //~^ ptr_cast_constness let _ = mut_ptr.cast_const(); + //~^ ptr_cast_constness // Lint this, since pointer::cast_mut and pointer::cast_const have ?Sized let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4]; @@ -66,20 +71,28 @@ fn _msrv_1_65() { let mut_ptr: *mut u32 = &mut 42_u32; let _ = ptr.cast_mut(); + //~^ ptr_cast_constness let _ = mut_ptr.cast_const(); + //~^ ptr_cast_constness } #[inline_macros] fn null_pointers() { use std::ptr; let _ = std::ptr::null_mut::(); + //~^ ptr_cast_constness let _ = std::ptr::null::(); + //~^ ptr_cast_constness let _ = std::ptr::null_mut::(); + //~^ ptr_cast_constness let _ = std::ptr::null::(); + //~^ ptr_cast_constness // Make sure the lint is triggered inside a macro let _ = inline!(std::ptr::null_mut::()); + //~^ ptr_cast_constness let _ = inline!(std::ptr::null_mut::()); + //~^ ptr_cast_constness // Do not lint inside macros from external crates let _ = external!(ptr::null::() as *mut u32); diff --git a/tests/ui/ptr_cast_constness.rs b/tests/ui/ptr_cast_constness.rs index 43ab5f5ba7cc..e9629f5290ec 100644 --- a/tests/ui/ptr_cast_constness.rs +++ b/tests/ui/ptr_cast_constness.rs @@ -13,7 +13,9 @@ use proc_macros::{external, inline_macros}; unsafe fn ptr_to_ref(p: *const T, om: *mut U) { let _: &mut T = std::mem::transmute(p as *mut T); + //~^ ptr_cast_constness let _ = &mut *(p as *mut T); + //~^ ptr_cast_constness let _: &T = &*(om as *const T); } @@ -29,10 +31,13 @@ fn main() { unsafe { let ptr_ptr: *const *const u32 = &ptr; let _ = *ptr_ptr as *mut u32; + //~^ ptr_cast_constness } let _ = ptr as *mut u32; + //~^ ptr_cast_constness let _ = mut_ptr as *const u32; + //~^ ptr_cast_constness // Lint this, since pointer::cast_mut and pointer::cast_const have ?Sized let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4]; @@ -66,20 +71,28 @@ fn _msrv_1_65() { let mut_ptr: *mut u32 = &mut 42_u32; let _ = ptr as *mut u32; + //~^ ptr_cast_constness let _ = mut_ptr as *const u32; + //~^ ptr_cast_constness } #[inline_macros] fn null_pointers() { use std::ptr; let _ = ptr::null::() as *mut String; + //~^ ptr_cast_constness let _ = ptr::null_mut::() as *const u32; + //~^ ptr_cast_constness let _ = ptr::null::().cast_mut(); + //~^ ptr_cast_constness let _ = ptr::null_mut::().cast_const(); + //~^ ptr_cast_constness // Make sure the lint is triggered inside a macro let _ = inline!(ptr::null::() as *mut u32); + //~^ ptr_cast_constness let _ = inline!(ptr::null::().cast_mut()); + //~^ ptr_cast_constness // Do not lint inside macros from external crates let _ = external!(ptr::null::() as *mut u32); diff --git a/tests/ui/ptr_cast_constness.stderr b/tests/ui/ptr_cast_constness.stderr index a693793a4ae9..1eeeef747013 100644 --- a/tests/ui/ptr_cast_constness.stderr +++ b/tests/ui/ptr_cast_constness.stderr @@ -8,67 +8,67 @@ LL | let _: &mut T = std::mem::transmute(p as *mut T); = help: to override `-D warnings` add `#[allow(clippy::ptr_cast_constness)]` error: `as` casting between raw pointers while changing only its constness - --> tests/ui/ptr_cast_constness.rs:16:19 + --> tests/ui/ptr_cast_constness.rs:17:19 | LL | let _ = &mut *(p as *mut T); | ^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()` error: `as` casting between raw pointers while changing only its constness - --> tests/ui/ptr_cast_constness.rs:31:17 + --> tests/ui/ptr_cast_constness.rs:33:17 | LL | let _ = *ptr_ptr as *mut u32; | ^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(*ptr_ptr).cast_mut()` error: `as` casting between raw pointers while changing only its constness - --> tests/ui/ptr_cast_constness.rs:34:13 + --> tests/ui/ptr_cast_constness.rs:37:13 | LL | let _ = ptr as *mut u32; | ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()` error: `as` casting between raw pointers while changing only its constness - --> tests/ui/ptr_cast_constness.rs:35:13 + --> tests/ui/ptr_cast_constness.rs:39:13 | LL | let _ = mut_ptr as *const u32; | ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()` error: `as` casting between raw pointers while changing only its constness - --> tests/ui/ptr_cast_constness.rs:68:13 + --> tests/ui/ptr_cast_constness.rs:73:13 | LL | let _ = ptr as *mut u32; | ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()` error: `as` casting between raw pointers while changing only its constness - --> tests/ui/ptr_cast_constness.rs:69:13 + --> tests/ui/ptr_cast_constness.rs:75:13 | LL | let _ = mut_ptr as *const u32; | ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()` error: `as` casting to make a const null pointer into a mutable null pointer - --> tests/ui/ptr_cast_constness.rs:75:13 + --> tests/ui/ptr_cast_constness.rs:82:13 | LL | let _ = ptr::null::() as *mut String; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::()` error: `as` casting to make a mutable null pointer into a const null pointer - --> tests/ui/ptr_cast_constness.rs:76:13 + --> tests/ui/ptr_cast_constness.rs:84:13 | LL | let _ = ptr::null_mut::() as *const u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null()` directly instead: `std::ptr::null::()` error: changing constness of a null pointer - --> tests/ui/ptr_cast_constness.rs:77:13 + --> tests/ui/ptr_cast_constness.rs:86:13 | LL | let _ = ptr::null::().cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::()` error: changing constness of a null pointer - --> tests/ui/ptr_cast_constness.rs:78:13 + --> tests/ui/ptr_cast_constness.rs:88:13 | LL | let _ = ptr::null_mut::().cast_const(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null()` directly instead: `std::ptr::null::()` error: `as` casting to make a const null pointer into a mutable null pointer - --> tests/ui/ptr_cast_constness.rs:81:21 + --> tests/ui/ptr_cast_constness.rs:92:21 | LL | let _ = inline!(ptr::null::() as *mut u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::()` @@ -76,7 +76,7 @@ LL | let _ = inline!(ptr::null::() as *mut u32); = note: this error originates in the macro `__inline_mac_fn_null_pointers` (in Nightly builds, run with -Z macro-backtrace for more info) error: changing constness of a null pointer - --> tests/ui/ptr_cast_constness.rs:82:21 + --> tests/ui/ptr_cast_constness.rs:94:21 | LL | let _ = inline!(ptr::null::().cast_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::()` diff --git a/tests/ui/ptr_eq.fixed b/tests/ui/ptr_eq.fixed index 3ae6df18c0a0..1ccd2c2237de 100644 --- a/tests/ui/ptr_eq.fixed +++ b/tests/ui/ptr_eq.fixed @@ -17,7 +17,9 @@ fn main() { let b = &[1, 2, 3]; let _ = std::ptr::eq(a, b); + //~^ ptr_eq let _ = std::ptr::eq(a, b); + //~^ ptr_eq let _ = a.as_ptr() == b as *const _; let _ = a.as_ptr() == b.as_ptr(); diff --git a/tests/ui/ptr_eq.rs b/tests/ui/ptr_eq.rs index 440d5d94a831..0bc58a57fa53 100644 --- a/tests/ui/ptr_eq.rs +++ b/tests/ui/ptr_eq.rs @@ -17,7 +17,9 @@ fn main() { let b = &[1, 2, 3]; let _ = a as *const _ as usize == b as *const _ as usize; + //~^ ptr_eq let _ = a as *const _ == b as *const _; + //~^ ptr_eq let _ = a.as_ptr() == b as *const _; let _ = a.as_ptr() == b.as_ptr(); diff --git a/tests/ui/ptr_eq.stderr b/tests/ui/ptr_eq.stderr index bf8c2b5c08fb..8e8b34f26ff7 100644 --- a/tests/ui/ptr_eq.stderr +++ b/tests/ui/ptr_eq.stderr @@ -8,7 +8,7 @@ LL | let _ = a as *const _ as usize == b as *const _ as usize; = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:20:13 + --> tests/ui/ptr_eq.rs:21:13 | LL | let _ = a as *const _ == b as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)` diff --git a/tests/ui/ptr_eq_no_std.fixed b/tests/ui/ptr_eq_no_std.fixed index 97c8c394c03d..b3e82fae38f3 100644 --- a/tests/ui/ptr_eq_no_std.fixed +++ b/tests/ui/ptr_eq_no_std.fixed @@ -29,7 +29,9 @@ fn main() { let b = &[1, 2, 3]; let _ = core::ptr::eq(a, b); + //~^ ptr_eq let _ = core::ptr::eq(a, b); + //~^ ptr_eq let _ = a.as_ptr() == b as *const _; let _ = a.as_ptr() == b.as_ptr(); diff --git a/tests/ui/ptr_eq_no_std.rs b/tests/ui/ptr_eq_no_std.rs index a7ba9b4d8174..ba78f5ee5f84 100644 --- a/tests/ui/ptr_eq_no_std.rs +++ b/tests/ui/ptr_eq_no_std.rs @@ -29,7 +29,9 @@ fn main() { let b = &[1, 2, 3]; let _ = a as *const _ as usize == b as *const _ as usize; + //~^ ptr_eq let _ = a as *const _ == b as *const _; + //~^ ptr_eq let _ = a.as_ptr() == b as *const _; let _ = a.as_ptr() == b.as_ptr(); diff --git a/tests/ui/ptr_eq_no_std.stderr b/tests/ui/ptr_eq_no_std.stderr index 0463b75b720b..8c7b1ff76661 100644 --- a/tests/ui/ptr_eq_no_std.stderr +++ b/tests/ui/ptr_eq_no_std.stderr @@ -8,7 +8,7 @@ LL | let _ = a as *const _ as usize == b as *const _ as usize; = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]` error: use `core::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq_no_std.rs:32:13 + --> tests/ui/ptr_eq_no_std.rs:33:13 | LL | let _ = a as *const _ == b as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)` diff --git a/tests/ui/ptr_offset_with_cast.fixed b/tests/ui/ptr_offset_with_cast.fixed index 929512be63d4..4fe9dcf46c35 100644 --- a/tests/ui/ptr_offset_with_cast.fixed +++ b/tests/ui/ptr_offset_with_cast.fixed @@ -10,10 +10,12 @@ fn main() { unsafe { let _ = ptr.add(offset_usize); + //~^ ptr_offset_with_cast let _ = ptr.offset(offset_isize as isize); let _ = ptr.offset(offset_u8 as isize); let _ = ptr.wrapping_add(offset_usize); + //~^ ptr_offset_with_cast let _ = ptr.wrapping_offset(offset_isize as isize); let _ = ptr.wrapping_offset(offset_u8 as isize); } diff --git a/tests/ui/ptr_offset_with_cast.rs b/tests/ui/ptr_offset_with_cast.rs index 146bc27765ad..a1fb892733d3 100644 --- a/tests/ui/ptr_offset_with_cast.rs +++ b/tests/ui/ptr_offset_with_cast.rs @@ -10,10 +10,12 @@ fn main() { unsafe { let _ = ptr.offset(offset_usize as isize); + //~^ ptr_offset_with_cast let _ = ptr.offset(offset_isize as isize); let _ = ptr.offset(offset_u8 as isize); let _ = ptr.wrapping_offset(offset_usize as isize); + //~^ ptr_offset_with_cast let _ = ptr.wrapping_offset(offset_isize as isize); let _ = ptr.wrapping_offset(offset_u8 as isize); } diff --git a/tests/ui/ptr_offset_with_cast.stderr b/tests/ui/ptr_offset_with_cast.stderr index 87ff10adc946..dcd5e027d182 100644 --- a/tests/ui/ptr_offset_with_cast.stderr +++ b/tests/ui/ptr_offset_with_cast.stderr @@ -8,7 +8,7 @@ LL | let _ = ptr.offset(offset_usize as isize); = help: to override `-D warnings` add `#[allow(clippy::ptr_offset_with_cast)]` error: use of `wrapping_offset` with a `usize` casted to an `isize` - --> tests/ui/ptr_offset_with_cast.rs:16:17 + --> tests/ui/ptr_offset_with_cast.rs:17:17 | LL | let _ = ptr.wrapping_offset(offset_usize as isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr.wrapping_add(offset_usize)` diff --git a/tests/ui/pub_use.rs b/tests/ui/pub_use.rs index aef947e406a6..4c2c3dfb30cb 100644 --- a/tests/ui/pub_use.rs +++ b/tests/ui/pub_use.rs @@ -8,7 +8,8 @@ pub mod outer { } // should be linted pub use inner::Test; - //~^ ERROR: using `pub use` + //~^ pub_use + } // should not be linted diff --git a/tests/ui/pub_with_shorthand.fixed b/tests/ui/pub_with_shorthand.fixed index 028209de0666..4036de8bbc0a 100644 --- a/tests/ui/pub_with_shorthand.fixed +++ b/tests/ui/pub_with_shorthand.fixed @@ -11,14 +11,18 @@ extern crate proc_macros; pub(in self) fn a() {} +//~^ pub_with_shorthand pub(in self) fn b() {} pub fn c() {} mod a { pub(in super) fn d() {} pub(in super) fn e() {} + //~^ pub_with_shorthand pub(in self) fn f() {} + //~^ pub_with_shorthand pub(in crate) fn k() {} + //~^ pub_with_shorthand pub(in crate) fn m() {} mod b { pub(in crate::a) fn l() {} diff --git a/tests/ui/pub_with_shorthand.rs b/tests/ui/pub_with_shorthand.rs index 8578e3e0c434..fac4ba990447 100644 --- a/tests/ui/pub_with_shorthand.rs +++ b/tests/ui/pub_with_shorthand.rs @@ -11,14 +11,18 @@ extern crate proc_macros; pub(self) fn a() {} +//~^ pub_with_shorthand pub(in self) fn b() {} pub fn c() {} mod a { pub(in super) fn d() {} pub(super) fn e() {} + //~^ pub_with_shorthand pub(self) fn f() {} + //~^ pub_with_shorthand pub(crate) fn k() {} + //~^ pub_with_shorthand pub(in crate) fn m() {} mod b { pub(in crate::a) fn l() {} diff --git a/tests/ui/pub_with_shorthand.stderr b/tests/ui/pub_with_shorthand.stderr index 8978244c4c04..00a3fc28ecb6 100644 --- a/tests/ui/pub_with_shorthand.stderr +++ b/tests/ui/pub_with_shorthand.stderr @@ -8,19 +8,19 @@ LL | pub(self) fn a() {} = help: to override `-D warnings` add `#[allow(clippy::pub_with_shorthand)]` error: usage of `pub` without `in` - --> tests/ui/pub_with_shorthand.rs:19:5 + --> tests/ui/pub_with_shorthand.rs:20:5 | LL | pub(super) fn e() {} | ^^^^^^^^^^ help: add it: `pub(in super)` error: usage of `pub` without `in` - --> tests/ui/pub_with_shorthand.rs:20:5 + --> tests/ui/pub_with_shorthand.rs:22:5 | LL | pub(self) fn f() {} | ^^^^^^^^^ help: add it: `pub(in self)` error: usage of `pub` without `in` - --> tests/ui/pub_with_shorthand.rs:21:5 + --> tests/ui/pub_with_shorthand.rs:24:5 | LL | pub(crate) fn k() {} | ^^^^^^^^^^ help: add it: `pub(in crate)` diff --git a/tests/ui/pub_without_shorthand.fixed b/tests/ui/pub_without_shorthand.fixed index 715e86c17645..fbe3326400cb 100644 --- a/tests/ui/pub_without_shorthand.fixed +++ b/tests/ui/pub_without_shorthand.fixed @@ -12,14 +12,17 @@ extern crate proc_macros; pub(self) fn a() {} pub(self) fn b() {} +//~^ pub_without_shorthand pub fn c() {} mod a { pub(super) fn d() {} + //~^ pub_without_shorthand pub(super) fn e() {} pub(self) fn f() {} pub(crate) fn k() {} pub(crate) fn m() {} + //~^ pub_without_shorthand mod b { pub(in crate::a) fn l() {} } diff --git a/tests/ui/pub_without_shorthand.rs b/tests/ui/pub_without_shorthand.rs index ed2fd6f0f617..fb756096c9d9 100644 --- a/tests/ui/pub_without_shorthand.rs +++ b/tests/ui/pub_without_shorthand.rs @@ -12,14 +12,17 @@ extern crate proc_macros; pub(self) fn a() {} pub(in self) fn b() {} +//~^ pub_without_shorthand pub fn c() {} mod a { pub(in super) fn d() {} + //~^ pub_without_shorthand pub(super) fn e() {} pub(self) fn f() {} pub(crate) fn k() {} pub(in crate) fn m() {} + //~^ pub_without_shorthand mod b { pub(in crate::a) fn l() {} } diff --git a/tests/ui/pub_without_shorthand.stderr b/tests/ui/pub_without_shorthand.stderr index e37c731732ba..c823af6432de 100644 --- a/tests/ui/pub_without_shorthand.stderr +++ b/tests/ui/pub_without_shorthand.stderr @@ -8,13 +8,13 @@ LL | pub(in self) fn b() {} = help: to override `-D warnings` add `#[allow(clippy::pub_without_shorthand)]` error: usage of `pub` with `in` - --> tests/ui/pub_without_shorthand.rs:18:5 + --> tests/ui/pub_without_shorthand.rs:19:5 | LL | pub(in super) fn d() {} | ^^^^^^^^^^^^^ help: remove it: `pub(super)` error: usage of `pub` with `in` - --> tests/ui/pub_without_shorthand.rs:22:5 + --> tests/ui/pub_without_shorthand.rs:24:5 | LL | pub(in crate) fn m() {} | ^^^^^^^^^^^^^ help: remove it: `pub(crate)` diff --git a/tests/ui/question_mark.fixed b/tests/ui/question_mark.fixed index b6e148e9f772..8dfef3202be9 100644 --- a/tests/ui/question_mark.fixed +++ b/tests/ui/question_mark.fixed @@ -141,6 +141,7 @@ fn func_returning_result() -> Result { fn result_func(x: Result) -> Result { let _ = x?; + //~^ question_mark x?; @@ -371,5 +372,6 @@ fn issue12412(foo: &Foo, bar: &Bar) -> Option<()> { }; // lint let v = bar.foo.owned.clone()?; + //~^^^ question_mark Some(()) } diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs index 48dc9eb0a626..609a4d3251e7 100644 --- a/tests/ui/question_mark.rs +++ b/tests/ui/question_mark.rs @@ -5,6 +5,7 @@ fn some_func(a: Option) -> Option { if a.is_none() { + //~^ question_mark return None; } @@ -50,20 +51,24 @@ impl CopyStruct { #[rustfmt::skip] pub fn func(&self) -> Option { if (self.opt).is_none() { + //~^ question_mark return None; } if self.opt.is_none() { + //~^ question_mark return None } let _ = if self.opt.is_none() { + //~^ question_mark return None; } else { self.opt }; let _ = if let Some(x) = self.opt { + //~^ question_mark x } else { return None; @@ -81,6 +86,7 @@ pub struct MoveStruct { impl MoveStruct { pub fn ref_func(&self) -> Option> { if self.opt.is_none() { + //~^ question_mark return None; } @@ -89,6 +95,7 @@ impl MoveStruct { pub fn mov_func_reuse(self) -> Option> { if self.opt.is_none() { + //~^ question_mark return None; } @@ -97,6 +104,7 @@ impl MoveStruct { pub fn mov_func_no_use(self) -> Option> { if self.opt.is_none() { + //~^ question_mark return None; } Some(Vec::new()) @@ -104,6 +112,7 @@ impl MoveStruct { pub fn if_let_ref_func(self) -> Option> { let v: &Vec<_> = if let Some(ref v) = self.opt { + //~^ question_mark v } else { return None; @@ -114,6 +123,7 @@ impl MoveStruct { pub fn if_let_mov_func(self) -> Option> { let v = if let Some(v) = self.opt { + //~^ question_mark v } else { return None; @@ -135,10 +145,12 @@ fn func() -> Option { } if f().is_none() { + //~^ question_mark return None; } let _val = match f() { + //~^ question_mark Some(val) => val, None => return None, }; @@ -149,11 +161,13 @@ fn func() -> Option { }; match f() { + //~^ question_mark Some(val) => val, None => return None, }; match opt_none!() { + //~^ question_mark Some(x) => x, None => return None, }; @@ -180,17 +194,21 @@ fn func_returning_result() -> Result { fn result_func(x: Result) -> Result { let _ = if let Ok(x) = x { x } else { return x }; + //~^ question_mark if x.is_err() { + //~^ question_mark return x; } let _val = match func_returning_result() { + //~^ question_mark Ok(val) => val, Err(err) => return Err(err), }; match func_returning_result() { + //~^ question_mark Ok(val) => val, Err(err) => return Err(err), }; @@ -282,6 +300,7 @@ fn do_something() {} fn err_immediate_return() -> Result { if let Err(err) = func_returning_result() { + //~^ question_mark return Err(err); } Ok(1) @@ -289,6 +308,7 @@ fn err_immediate_return() -> Result { fn err_immediate_return_and_do_something() -> Result { if let Err(err) = func_returning_result() { + //~^ question_mark return Err(err); } do_something(); @@ -366,6 +386,7 @@ fn issue6828_nested_body() -> Option { try { fn f2(a: Option) -> Option { if a.is_none() { + //~^ question_mark return None; // do lint here, the outer `try` is not relevant here // https://github.com/rust-lang/rust-clippy/pull/11001#issuecomment-1610636867 @@ -428,5 +449,6 @@ fn issue12412(foo: &Foo, bar: &Bar) -> Option<()> { let Some(v) = bar.foo.owned.clone() else { return None; }; + //~^^^ question_mark Some(()) } diff --git a/tests/ui/question_mark.stderr b/tests/ui/question_mark.stderr index 06a8bd0de349..c4db0fbc3022 100644 --- a/tests/ui/question_mark.stderr +++ b/tests/ui/question_mark.stderr @@ -2,6 +2,7 @@ error: this block may be rewritten with the `?` operator --> tests/ui/question_mark.rs:7:5 | LL | / if a.is_none() { +LL | | LL | | return None; LL | | } | |_____^ help: replace it with: `a?;` @@ -10,26 +11,29 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::question_mark)]` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:52:9 + --> tests/ui/question_mark.rs:53:9 | LL | / if (self.opt).is_none() { +LL | | LL | | return None; LL | | } | |_________^ help: replace it with: `(self.opt)?;` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:56:9 + --> tests/ui/question_mark.rs:58:9 | LL | / if self.opt.is_none() { +LL | | LL | | return None LL | | } | |_________^ help: replace it with: `self.opt?;` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:60:17 + --> tests/ui/question_mark.rs:63:17 | LL | let _ = if self.opt.is_none() { | _________________^ +LL | | LL | | return None; LL | | } else { LL | | self.opt @@ -37,10 +41,11 @@ LL | | }; | |_________^ help: replace it with: `Some(self.opt?)` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:66:17 + --> tests/ui/question_mark.rs:70:17 | LL | let _ = if let Some(x) = self.opt { | _________________^ +LL | | LL | | x LL | | } else { LL | | return None; @@ -48,34 +53,38 @@ LL | | }; | |_________^ help: replace it with: `self.opt?` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:83:9 + --> tests/ui/question_mark.rs:88:9 | LL | / if self.opt.is_none() { +LL | | LL | | return None; LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:91:9 + --> tests/ui/question_mark.rs:97:9 | LL | / if self.opt.is_none() { +LL | | LL | | return None; LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:99:9 + --> tests/ui/question_mark.rs:106:9 | LL | / if self.opt.is_none() { +LL | | LL | | return None; LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:106:26 + --> tests/ui/question_mark.rs:114:26 | LL | let v: &Vec<_> = if let Some(ref v) = self.opt { | __________________________^ +LL | | LL | | v LL | | } else { LL | | return None; @@ -83,10 +92,11 @@ LL | | }; | |_________^ help: replace it with: `self.opt.as_ref()?` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:116:17 + --> tests/ui/question_mark.rs:125:17 | LL | let v = if let Some(v) = self.opt { | _________________^ +LL | | LL | | v LL | | } else { LL | | return None; @@ -94,101 +104,111 @@ LL | | }; | |_________^ help: replace it with: `self.opt?` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:137:5 + --> tests/ui/question_mark.rs:147:5 | LL | / if f().is_none() { +LL | | LL | | return None; LL | | } | |_____^ help: replace it with: `f()?;` error: this `match` expression can be replaced with `?` - --> tests/ui/question_mark.rs:141:16 + --> tests/ui/question_mark.rs:152:16 | LL | let _val = match f() { | ________________^ +LL | | LL | | Some(val) => val, LL | | None => return None, LL | | }; | |_____^ help: try instead: `f()?` error: this `match` expression can be replaced with `?` - --> tests/ui/question_mark.rs:151:5 + --> tests/ui/question_mark.rs:163:5 | LL | / match f() { +LL | | LL | | Some(val) => val, LL | | None => return None, LL | | }; | |_____^ help: try instead: `f()?` error: this `match` expression can be replaced with `?` - --> tests/ui/question_mark.rs:156:5 + --> tests/ui/question_mark.rs:169:5 | LL | / match opt_none!() { +LL | | LL | | Some(x) => x, LL | | None => return None, LL | | }; | |_____^ help: try instead: `opt_none!()?` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:182:13 + --> tests/ui/question_mark.rs:196:13 | LL | let _ = if let Ok(x) = x { x } else { return x }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x?` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:184:5 + --> tests/ui/question_mark.rs:199:5 | LL | / if x.is_err() { +LL | | LL | | return x; LL | | } | |_____^ help: replace it with: `x?;` error: this `match` expression can be replaced with `?` - --> tests/ui/question_mark.rs:188:16 + --> tests/ui/question_mark.rs:204:16 | LL | let _val = match func_returning_result() { | ________________^ +LL | | LL | | Ok(val) => val, LL | | Err(err) => return Err(err), LL | | }; | |_____^ help: try instead: `func_returning_result()?` error: this `match` expression can be replaced with `?` - --> tests/ui/question_mark.rs:193:5 + --> tests/ui/question_mark.rs:210:5 | LL | / match func_returning_result() { +LL | | LL | | Ok(val) => val, LL | | Err(err) => return Err(err), LL | | }; | |_____^ help: try instead: `func_returning_result()?` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:284:5 + --> tests/ui/question_mark.rs:302:5 | LL | / if let Err(err) = func_returning_result() { +LL | | LL | | return Err(err); LL | | } | |_____^ help: replace it with: `func_returning_result()?;` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:291:5 + --> tests/ui/question_mark.rs:310:5 | LL | / if let Err(err) = func_returning_result() { +LL | | LL | | return Err(err); LL | | } | |_____^ help: replace it with: `func_returning_result()?;` error: this block may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:368:13 + --> tests/ui/question_mark.rs:388:13 | LL | / if a.is_none() { +LL | | LL | | return None; ... | LL | | } | |_____________^ help: replace it with: `a?;` error: this `let...else` may be rewritten with the `?` operator - --> tests/ui/question_mark.rs:428:5 + --> tests/ui/question_mark.rs:449:5 | LL | / let Some(v) = bar.foo.owned.clone() else { LL | | return None; diff --git a/tests/ui/question_mark_used.rs b/tests/ui/question_mark_used.rs index 715d7fab8eed..9e204d1e9f3c 100644 --- a/tests/ui/question_mark_used.rs +++ b/tests/ui/question_mark_used.rs @@ -9,7 +9,8 @@ fn other_function() -> Option { fn my_function() -> Option { other_function()?; - //~^ ERROR: question mark operator was used + //~^ question_mark_used + None } diff --git a/tests/ui/range.fixed b/tests/ui/range.fixed index 82aa1b5f94fd..0e951d88091b 100644 --- a/tests/ui/range.fixed +++ b/tests/ui/range.fixed @@ -4,7 +4,8 @@ fn main() { let v1 = vec![1, 2, 3]; let v2 = vec![4, 5]; let _x = v1.iter().enumerate(); - //~^ ERROR: using `.zip()` with a range and `.len()` + //~^ range_zip_with_len + let _y = v1.iter().zip(0..v2.len()); // No error } diff --git a/tests/ui/range.rs b/tests/ui/range.rs index a7d5cf38dfb5..534380164743 100644 --- a/tests/ui/range.rs +++ b/tests/ui/range.rs @@ -4,7 +4,8 @@ fn main() { let v1 = vec![1, 2, 3]; let v2 = vec![4, 5]; let _x = v1.iter().zip(0..v1.len()); - //~^ ERROR: using `.zip()` with a range and `.len()` + //~^ range_zip_with_len + let _y = v1.iter().zip(0..v2.len()); // No error } diff --git a/tests/ui/range_contains.fixed b/tests/ui/range_contains.fixed index ed248df374d1..19d6165e9820 100644 --- a/tests/ui/range_contains.fixed +++ b/tests/ui/range_contains.fixed @@ -11,23 +11,35 @@ fn main() { // order shouldn't matter (8..12).contains(&x); + //~^ manual_range_contains (21..42).contains(&x); + //~^ manual_range_contains (1..100).contains(&x); + //~^ manual_range_contains // also with inclusive ranges (9..=99).contains(&x); + //~^ manual_range_contains (1..=33).contains(&x); + //~^ manual_range_contains (1..=999).contains(&x); + //~^ manual_range_contains // and the outside !(8..12).contains(&x); + //~^ manual_range_contains !(21..42).contains(&x); + //~^ manual_range_contains !(1..100).contains(&x); + //~^ manual_range_contains // also with the outside of inclusive ranges !(9..=99).contains(&x); + //~^ manual_range_contains !(1..=33).contains(&x); + //~^ manual_range_contains !(1..=999).contains(&x); + //~^ manual_range_contains // not a range.contains x > 8 && x < 12; // lower bound not inclusive @@ -43,18 +55,26 @@ fn main() { // Fix #6315 let y = 3.; (0. ..1.).contains(&y); + //~^ manual_range_contains !(0. ..=1.).contains(&y); + //~^ manual_range_contains // handle negatives #8721 (-10..=10).contains(&x); + //~^ manual_range_contains x >= 10 && x <= -10; (-3. ..=3.).contains(&y); + //~^ manual_range_contains y >= 3. && y <= -3.; // Fix #8745 let z = 42; (0..=10).contains(&x) && (0..=10).contains(&z); + //~^ manual_range_contains + //~| manual_range_contains !(0..10).contains(&x) || !(0..10).contains(&z); + //~^ manual_range_contains + //~| manual_range_contains // Make sure operators in parens don't give a breaking suggestion ((x % 2 == 0) || (x < 0)) || (x >= 10); } @@ -74,4 +94,5 @@ fn msrv_1_34() { fn msrv_1_35() { let x = 5; (8..35).contains(&x); + //~^ manual_range_contains } diff --git a/tests/ui/range_contains.rs b/tests/ui/range_contains.rs index c3188ec6d92b..80bf40806697 100644 --- a/tests/ui/range_contains.rs +++ b/tests/ui/range_contains.rs @@ -11,23 +11,35 @@ fn main() { // order shouldn't matter x >= 8 && x < 12; + //~^ manual_range_contains x < 42 && x >= 21; + //~^ manual_range_contains 100 > x && 1 <= x; + //~^ manual_range_contains // also with inclusive ranges x >= 9 && x <= 99; + //~^ manual_range_contains x <= 33 && x >= 1; + //~^ manual_range_contains 999 >= x && 1 <= x; + //~^ manual_range_contains // and the outside x < 8 || x >= 12; + //~^ manual_range_contains x >= 42 || x < 21; + //~^ manual_range_contains 100 <= x || 1 > x; + //~^ manual_range_contains // also with the outside of inclusive ranges x < 9 || x > 99; + //~^ manual_range_contains x > 33 || x < 1; + //~^ manual_range_contains 999 < x || 1 > x; + //~^ manual_range_contains // not a range.contains x > 8 && x < 12; // lower bound not inclusive @@ -43,18 +55,26 @@ fn main() { // Fix #6315 let y = 3.; y >= 0. && y < 1.; + //~^ manual_range_contains y < 0. || y > 1.; + //~^ manual_range_contains // handle negatives #8721 x >= -10 && x <= 10; + //~^ manual_range_contains x >= 10 && x <= -10; y >= -3. && y <= 3.; + //~^ manual_range_contains y >= 3. && y <= -3.; // Fix #8745 let z = 42; (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10); + //~^ manual_range_contains + //~| manual_range_contains (x < 0) || (x >= 10) || (z < 0) || (z >= 10); + //~^ manual_range_contains + //~| manual_range_contains // Make sure operators in parens don't give a breaking suggestion ((x % 2 == 0) || (x < 0)) || (x >= 10); } @@ -74,4 +94,5 @@ fn msrv_1_34() { fn msrv_1_35() { let x = 5; x >= 8 && x < 35; + //~^ manual_range_contains } diff --git a/tests/ui/range_contains.stderr b/tests/ui/range_contains.stderr index 58ed1292ac7c..67bd5aad093d 100644 --- a/tests/ui/range_contains.stderr +++ b/tests/ui/range_contains.stderr @@ -8,121 +8,121 @@ LL | x >= 8 && x < 12; = help: to override `-D warnings` add `#[allow(clippy::manual_range_contains)]` error: manual `Range::contains` implementation - --> tests/ui/range_contains.rs:14:5 + --> tests/ui/range_contains.rs:15:5 | LL | x < 42 && x >= 21; | ^^^^^^^^^^^^^^^^^ help: use: `(21..42).contains(&x)` error: manual `Range::contains` implementation - --> tests/ui/range_contains.rs:15:5 + --> tests/ui/range_contains.rs:17:5 | LL | 100 > x && 1 <= x; | ^^^^^^^^^^^^^^^^^ help: use: `(1..100).contains(&x)` error: manual `RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:18:5 + --> tests/ui/range_contains.rs:21:5 | LL | x >= 9 && x <= 99; | ^^^^^^^^^^^^^^^^^ help: use: `(9..=99).contains(&x)` error: manual `RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:19:5 + --> tests/ui/range_contains.rs:23:5 | LL | x <= 33 && x >= 1; | ^^^^^^^^^^^^^^^^^ help: use: `(1..=33).contains(&x)` error: manual `RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:20:5 + --> tests/ui/range_contains.rs:25:5 | LL | 999 >= x && 1 <= x; | ^^^^^^^^^^^^^^^^^^ help: use: `(1..=999).contains(&x)` error: manual `!Range::contains` implementation - --> tests/ui/range_contains.rs:23:5 + --> tests/ui/range_contains.rs:29:5 | LL | x < 8 || x >= 12; | ^^^^^^^^^^^^^^^^ help: use: `!(8..12).contains(&x)` error: manual `!Range::contains` implementation - --> tests/ui/range_contains.rs:24:5 + --> tests/ui/range_contains.rs:31:5 | LL | x >= 42 || x < 21; | ^^^^^^^^^^^^^^^^^ help: use: `!(21..42).contains(&x)` error: manual `!Range::contains` implementation - --> tests/ui/range_contains.rs:25:5 + --> tests/ui/range_contains.rs:33:5 | LL | 100 <= x || 1 > x; | ^^^^^^^^^^^^^^^^^ help: use: `!(1..100).contains(&x)` error: manual `!RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:28:5 + --> tests/ui/range_contains.rs:37:5 | LL | x < 9 || x > 99; | ^^^^^^^^^^^^^^^ help: use: `!(9..=99).contains(&x)` error: manual `!RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:29:5 + --> tests/ui/range_contains.rs:39:5 | LL | x > 33 || x < 1; | ^^^^^^^^^^^^^^^ help: use: `!(1..=33).contains(&x)` error: manual `!RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:30:5 + --> tests/ui/range_contains.rs:41:5 | LL | 999 < x || 1 > x; | ^^^^^^^^^^^^^^^^ help: use: `!(1..=999).contains(&x)` error: manual `Range::contains` implementation - --> tests/ui/range_contains.rs:45:5 + --> tests/ui/range_contains.rs:57:5 | LL | y >= 0. && y < 1.; | ^^^^^^^^^^^^^^^^^ help: use: `(0. ..1.).contains(&y)` error: manual `!RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:46:5 + --> tests/ui/range_contains.rs:59:5 | LL | y < 0. || y > 1.; | ^^^^^^^^^^^^^^^^ help: use: `!(0. ..=1.).contains(&y)` error: manual `RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:49:5 + --> tests/ui/range_contains.rs:63:5 | LL | x >= -10 && x <= 10; | ^^^^^^^^^^^^^^^^^^^ help: use: `(-10..=10).contains(&x)` error: manual `RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:51:5 + --> tests/ui/range_contains.rs:66:5 | LL | y >= -3. && y <= 3.; | ^^^^^^^^^^^^^^^^^^^ help: use: `(-3. ..=3.).contains(&y)` error: manual `RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:56:30 + --> tests/ui/range_contains.rs:72:30 | LL | (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10); | ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&z)` error: manual `RangeInclusive::contains` implementation - --> tests/ui/range_contains.rs:56:5 + --> tests/ui/range_contains.rs:72:5 | LL | (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10); | ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&x)` error: manual `!Range::contains` implementation - --> tests/ui/range_contains.rs:57:29 + --> tests/ui/range_contains.rs:75:29 | LL | (x < 0) || (x >= 10) || (z < 0) || (z >= 10); | ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&z)` error: manual `!Range::contains` implementation - --> tests/ui/range_contains.rs:57:5 + --> tests/ui/range_contains.rs:75:5 | LL | (x < 0) || (x >= 10) || (z < 0) || (z >= 10); | ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&x)` error: manual `Range::contains` implementation - --> tests/ui/range_contains.rs:76:5 + --> tests/ui/range_contains.rs:96:5 | LL | x >= 8 && x < 35; | ^^^^^^^^^^^^^^^^ help: use: `(8..35).contains(&x)` diff --git a/tests/ui/range_plus_minus_one.fixed b/tests/ui/range_plus_minus_one.fixed index e701dde86933..ee716ef3a6a0 100644 --- a/tests/ui/range_plus_minus_one.fixed +++ b/tests/ui/range_plus_minus_one.fixed @@ -27,29 +27,38 @@ fn main() { for _ in 0..=2 {} for _ in 0..=3 {} + //~^ range_plus_one for _ in 0..=3 + 1 {} for _ in 0..=5 {} + //~^ range_plus_one for _ in 0..=1 + 5 {} for _ in 1..=1 {} + //~^ range_plus_one for _ in 1..=1 + 1 {} for _ in 0..13 + 13 {} for _ in 0..=13 - 7 {} for _ in 0..=f() {} + //~^ range_plus_one for _ in 0..=(1 + f()) {} let _ = ..11 - 1; let _ = ..11; + //~^ range_minus_one let _ = ..11; + //~^ range_minus_one let _ = (1..=11); + //~^ range_plus_one let _ = ((f() + 1)..=f()); + //~^ range_plus_one const ONE: usize = 1; // integer consts are linted, too for _ in 1..=ONE {} + //~^ range_plus_one let mut vec: Vec<()> = std::vec::Vec::new(); vec.drain(..); diff --git a/tests/ui/range_plus_minus_one.rs b/tests/ui/range_plus_minus_one.rs index 7057fa8e3f0d..f2d5ae2c1506 100644 --- a/tests/ui/range_plus_minus_one.rs +++ b/tests/ui/range_plus_minus_one.rs @@ -27,29 +27,38 @@ fn main() { for _ in 0..=2 {} for _ in 0..3 + 1 {} + //~^ range_plus_one for _ in 0..=3 + 1 {} for _ in 0..1 + 5 {} + //~^ range_plus_one for _ in 0..=1 + 5 {} for _ in 1..1 + 1 {} + //~^ range_plus_one for _ in 1..=1 + 1 {} for _ in 0..13 + 13 {} for _ in 0..=13 - 7 {} for _ in 0..(1 + f()) {} + //~^ range_plus_one for _ in 0..=(1 + f()) {} let _ = ..11 - 1; let _ = ..=11 - 1; + //~^ range_minus_one let _ = ..=(11 - 1); + //~^ range_minus_one let _ = (1..11 + 1); + //~^ range_plus_one let _ = (f() + 1)..(f() + 1); + //~^ range_plus_one const ONE: usize = 1; // integer consts are linted, too for _ in 1..ONE + ONE {} + //~^ range_plus_one let mut vec: Vec<()> = std::vec::Vec::new(); vec.drain(..); diff --git a/tests/ui/range_plus_minus_one.stderr b/tests/ui/range_plus_minus_one.stderr index 0b1883bc5ff2..9b23a8b8c0b4 100644 --- a/tests/ui/range_plus_minus_one.stderr +++ b/tests/ui/range_plus_minus_one.stderr @@ -8,25 +8,25 @@ LL | for _ in 0..3 + 1 {} = help: to override `-D warnings` add `#[allow(clippy::range_plus_one)]` error: an inclusive range would be more readable - --> tests/ui/range_plus_minus_one.rs:32:14 + --> tests/ui/range_plus_minus_one.rs:33:14 | LL | for _ in 0..1 + 5 {} | ^^^^^^^^ help: use: `0..=5` error: an inclusive range would be more readable - --> tests/ui/range_plus_minus_one.rs:35:14 + --> tests/ui/range_plus_minus_one.rs:37:14 | LL | for _ in 1..1 + 1 {} | ^^^^^^^^ help: use: `1..=1` error: an inclusive range would be more readable - --> tests/ui/range_plus_minus_one.rs:41:14 + --> tests/ui/range_plus_minus_one.rs:44:14 | LL | for _ in 0..(1 + f()) {} | ^^^^^^^^^^^^ help: use: `0..=f()` error: an exclusive range would be more readable - --> tests/ui/range_plus_minus_one.rs:45:13 + --> tests/ui/range_plus_minus_one.rs:49:13 | LL | let _ = ..=11 - 1; | ^^^^^^^^^ help: use: `..11` @@ -35,25 +35,25 @@ LL | let _ = ..=11 - 1; = help: to override `-D warnings` add `#[allow(clippy::range_minus_one)]` error: an exclusive range would be more readable - --> tests/ui/range_plus_minus_one.rs:46:13 + --> tests/ui/range_plus_minus_one.rs:51:13 | LL | let _ = ..=(11 - 1); | ^^^^^^^^^^^ help: use: `..11` error: an inclusive range would be more readable - --> tests/ui/range_plus_minus_one.rs:47:13 + --> tests/ui/range_plus_minus_one.rs:53:13 | LL | let _ = (1..11 + 1); | ^^^^^^^^^^^ help: use: `(1..=11)` error: an inclusive range would be more readable - --> tests/ui/range_plus_minus_one.rs:48:13 + --> tests/ui/range_plus_minus_one.rs:55:13 | LL | let _ = (f() + 1)..(f() + 1); | ^^^^^^^^^^^^^^^^^^^^ help: use: `((f() + 1)..=f())` error: an inclusive range would be more readable - --> tests/ui/range_plus_minus_one.rs:52:14 + --> tests/ui/range_plus_minus_one.rs:60:14 | LL | for _ in 1..ONE + ONE {} | ^^^^^^^^^^^^ help: use: `1..=ONE` diff --git a/tests/ui/rc_buffer.fixed b/tests/ui/rc_buffer.fixed index 35ac95a76a91..c71a4072b962 100644 --- a/tests/ui/rc_buffer.fixed +++ b/tests/ui/rc_buffer.fixed @@ -9,18 +9,26 @@ use std::rc::Rc; struct S { // triggers lint bad1: Rc, + //~^ rc_buffer bad2: Rc, + //~^ rc_buffer bad3: Rc<[u8]>, + //~^ rc_buffer bad4: Rc, + //~^ rc_buffer // does not trigger lint good1: Rc>, } // triggers lint fn func_bad1(_: Rc) {} +//~^ rc_buffer fn func_bad2(_: Rc) {} +//~^ rc_buffer fn func_bad3(_: Rc<[u8]>) {} +//~^ rc_buffer fn func_bad4(_: Rc) {} +//~^ rc_buffer // does not trigger lint fn func_good1(_: Rc>) {} diff --git a/tests/ui/rc_buffer.rs b/tests/ui/rc_buffer.rs index e78fb5a6d9d8..686c2644da17 100644 --- a/tests/ui/rc_buffer.rs +++ b/tests/ui/rc_buffer.rs @@ -9,18 +9,26 @@ use std::rc::Rc; struct S { // triggers lint bad1: Rc, + //~^ rc_buffer bad2: Rc, + //~^ rc_buffer bad3: Rc>, + //~^ rc_buffer bad4: Rc, + //~^ rc_buffer // does not trigger lint good1: Rc>, } // triggers lint fn func_bad1(_: Rc) {} +//~^ rc_buffer fn func_bad2(_: Rc) {} +//~^ rc_buffer fn func_bad3(_: Rc>) {} +//~^ rc_buffer fn func_bad4(_: Rc) {} +//~^ rc_buffer // does not trigger lint fn func_good1(_: Rc>) {} diff --git a/tests/ui/rc_buffer.stderr b/tests/ui/rc_buffer.stderr index 922f09288bf3..7500523ab4ac 100644 --- a/tests/ui/rc_buffer.stderr +++ b/tests/ui/rc_buffer.stderr @@ -8,43 +8,43 @@ LL | bad1: Rc, = help: to override `-D warnings` add `#[allow(clippy::rc_buffer)]` error: usage of `Rc` when T is a buffer type - --> tests/ui/rc_buffer.rs:12:11 + --> tests/ui/rc_buffer.rs:13:11 | LL | bad2: Rc, | ^^^^^^^^^^^ help: try: `Rc` error: usage of `Rc` when T is a buffer type - --> tests/ui/rc_buffer.rs:13:11 + --> tests/ui/rc_buffer.rs:15:11 | LL | bad3: Rc>, | ^^^^^^^^^^^ help: try: `Rc<[u8]>` error: usage of `Rc` when T is a buffer type - --> tests/ui/rc_buffer.rs:14:11 + --> tests/ui/rc_buffer.rs:17:11 | LL | bad4: Rc, | ^^^^^^^^^^^^ help: try: `Rc` error: usage of `Rc` when T is a buffer type - --> tests/ui/rc_buffer.rs:20:17 + --> tests/ui/rc_buffer.rs:24:17 | LL | fn func_bad1(_: Rc) {} | ^^^^^^^^^^ help: try: `Rc` error: usage of `Rc` when T is a buffer type - --> tests/ui/rc_buffer.rs:21:17 + --> tests/ui/rc_buffer.rs:26:17 | LL | fn func_bad2(_: Rc) {} | ^^^^^^^^^^^ help: try: `Rc` error: usage of `Rc` when T is a buffer type - --> tests/ui/rc_buffer.rs:22:17 + --> tests/ui/rc_buffer.rs:28:17 | LL | fn func_bad3(_: Rc>) {} | ^^^^^^^^^^^ help: try: `Rc<[u8]>` error: usage of `Rc` when T is a buffer type - --> tests/ui/rc_buffer.rs:23:17 + --> tests/ui/rc_buffer.rs:30:17 | LL | fn func_bad4(_: Rc) {} | ^^^^^^^^^^^^ help: try: `Rc` diff --git a/tests/ui/rc_buffer_arc.fixed b/tests/ui/rc_buffer_arc.fixed index 0d01c7c476f7..27059e3f2e1f 100644 --- a/tests/ui/rc_buffer_arc.fixed +++ b/tests/ui/rc_buffer_arc.fixed @@ -8,18 +8,26 @@ use std::sync::{Arc, Mutex}; struct S { // triggers lint bad1: Arc, + //~^ rc_buffer bad2: Arc, + //~^ rc_buffer bad3: Arc<[u8]>, + //~^ rc_buffer bad4: Arc, + //~^ rc_buffer // does not trigger lint good1: Arc>, } // triggers lint fn func_bad1(_: Arc) {} +//~^ rc_buffer fn func_bad2(_: Arc) {} +//~^ rc_buffer fn func_bad3(_: Arc<[u8]>) {} +//~^ rc_buffer fn func_bad4(_: Arc) {} +//~^ rc_buffer // does not trigger lint fn func_good1(_: Arc>) {} diff --git a/tests/ui/rc_buffer_arc.rs b/tests/ui/rc_buffer_arc.rs index 61ab16dc1829..5261eae2f26a 100644 --- a/tests/ui/rc_buffer_arc.rs +++ b/tests/ui/rc_buffer_arc.rs @@ -8,18 +8,26 @@ use std::sync::{Arc, Mutex}; struct S { // triggers lint bad1: Arc, + //~^ rc_buffer bad2: Arc, + //~^ rc_buffer bad3: Arc>, + //~^ rc_buffer bad4: Arc, + //~^ rc_buffer // does not trigger lint good1: Arc>, } // triggers lint fn func_bad1(_: Arc) {} +//~^ rc_buffer fn func_bad2(_: Arc) {} +//~^ rc_buffer fn func_bad3(_: Arc>) {} +//~^ rc_buffer fn func_bad4(_: Arc) {} +//~^ rc_buffer // does not trigger lint fn func_good1(_: Arc>) {} diff --git a/tests/ui/rc_buffer_arc.stderr b/tests/ui/rc_buffer_arc.stderr index 5ef5da2f67f8..786715463232 100644 --- a/tests/ui/rc_buffer_arc.stderr +++ b/tests/ui/rc_buffer_arc.stderr @@ -8,43 +8,43 @@ LL | bad1: Arc, = help: to override `-D warnings` add `#[allow(clippy::rc_buffer)]` error: usage of `Arc` when T is a buffer type - --> tests/ui/rc_buffer_arc.rs:11:11 + --> tests/ui/rc_buffer_arc.rs:12:11 | LL | bad2: Arc, | ^^^^^^^^^^^^ help: try: `Arc` error: usage of `Arc` when T is a buffer type - --> tests/ui/rc_buffer_arc.rs:12:11 + --> tests/ui/rc_buffer_arc.rs:14:11 | LL | bad3: Arc>, | ^^^^^^^^^^^^ help: try: `Arc<[u8]>` error: usage of `Arc` when T is a buffer type - --> tests/ui/rc_buffer_arc.rs:13:11 + --> tests/ui/rc_buffer_arc.rs:16:11 | LL | bad4: Arc, | ^^^^^^^^^^^^^ help: try: `Arc` error: usage of `Arc` when T is a buffer type - --> tests/ui/rc_buffer_arc.rs:19:17 + --> tests/ui/rc_buffer_arc.rs:23:17 | LL | fn func_bad1(_: Arc) {} | ^^^^^^^^^^^ help: try: `Arc` error: usage of `Arc` when T is a buffer type - --> tests/ui/rc_buffer_arc.rs:20:17 + --> tests/ui/rc_buffer_arc.rs:25:17 | LL | fn func_bad2(_: Arc) {} | ^^^^^^^^^^^^ help: try: `Arc` error: usage of `Arc` when T is a buffer type - --> tests/ui/rc_buffer_arc.rs:21:17 + --> tests/ui/rc_buffer_arc.rs:27:17 | LL | fn func_bad3(_: Arc>) {} | ^^^^^^^^^^^^ help: try: `Arc<[u8]>` error: usage of `Arc` when T is a buffer type - --> tests/ui/rc_buffer_arc.rs:22:17 + --> tests/ui/rc_buffer_arc.rs:29:17 | LL | fn func_bad4(_: Arc) {} | ^^^^^^^^^^^^^ help: try: `Arc` diff --git a/tests/ui/rc_buffer_redefined_string.rs b/tests/ui/rc_buffer_redefined_string.rs index 5d31a848cf72..49a8ba3e2efb 100644 --- a/tests/ui/rc_buffer_redefined_string.rs +++ b/tests/ui/rc_buffer_redefined_string.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::rc_buffer)] use std::rc::Rc; diff --git a/tests/ui/rc_clone_in_vec_init/arc.rs b/tests/ui/rc_clone_in_vec_init/arc.rs index 1c9e9aa7ef47..3b3e5dc643e1 100644 --- a/tests/ui/rc_clone_in_vec_init/arc.rs +++ b/tests/ui/rc_clone_in_vec_init/arc.rs @@ -7,8 +7,9 @@ fn main() {} fn should_warn_simple_case() { let v = vec![Arc::new("x".to_string()); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Arc` instance + //~^ rc_clone_in_vec_init + + } fn should_warn_simple_case_with_big_indentation() { @@ -17,16 +18,18 @@ fn should_warn_simple_case_with_big_indentation() { dbg!(k); if true { let v = vec![Arc::new("x".to_string()); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Arc` instance + //~^ rc_clone_in_vec_init + + } } } fn should_warn_complex_case() { let v = vec![ - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Arc` instance + //~^ rc_clone_in_vec_init + + std::sync::Arc::new(Mutex::new({ let x = 1; dbg!(x); @@ -36,8 +39,9 @@ fn should_warn_complex_case() { ]; let v1 = vec![ - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Arc` instance + //~^ rc_clone_in_vec_init + + Arc::new(Mutex::new({ let x = 1; dbg!(x); diff --git a/tests/ui/rc_clone_in_vec_init/arc.stderr b/tests/ui/rc_clone_in_vec_init/arc.stderr index 1078a97542f2..5d70bfc85363 100644 --- a/tests/ui/rc_clone_in_vec_init/arc.stderr +++ b/tests/ui/rc_clone_in_vec_init/arc.stderr @@ -24,7 +24,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/arc.rs:19:21 + --> tests/ui/rc_clone_in_vec_init/arc.rs:20:21 | LL | let v = vec![Arc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,13 +47,10 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/arc.rs:27:13 + --> tests/ui/rc_clone_in_vec_init/arc.rs:29:13 | LL | let v = vec![ | _____________^ -LL | | -LL | | -LL | | std::sync::Arc::new(Mutex::new({ ... | LL | | 2 LL | | ]; @@ -77,13 +74,10 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/arc.rs:38:14 + --> tests/ui/rc_clone_in_vec_init/arc.rs:41:14 | LL | let v1 = vec![ | ______________^ -LL | | -LL | | -LL | | Arc::new(Mutex::new({ ... | LL | | 2 LL | | ]; diff --git a/tests/ui/rc_clone_in_vec_init/rc.rs b/tests/ui/rc_clone_in_vec_init/rc.rs index 01cc433cbdae..e93408798585 100644 --- a/tests/ui/rc_clone_in_vec_init/rc.rs +++ b/tests/ui/rc_clone_in_vec_init/rc.rs @@ -8,8 +8,9 @@ fn main() {} fn should_warn_simple_case() { let v = vec![Rc::new("x".to_string()); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Rc` instance + //~^ rc_clone_in_vec_init + + } fn should_warn_simple_case_with_big_indentation() { @@ -18,16 +19,18 @@ fn should_warn_simple_case_with_big_indentation() { dbg!(k); if true { let v = vec![Rc::new("x".to_string()); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Rc` instance + //~^ rc_clone_in_vec_init + + } } } fn should_warn_complex_case() { let v = vec![ - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Rc` instance + //~^ rc_clone_in_vec_init + + std::rc::Rc::new(Mutex::new({ let x = 1; dbg!(x); @@ -37,8 +40,9 @@ fn should_warn_complex_case() { ]; let v1 = vec![ - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Rc` instance + //~^ rc_clone_in_vec_init + + Rc::new(Mutex::new({ let x = 1; dbg!(x); diff --git a/tests/ui/rc_clone_in_vec_init/rc.stderr b/tests/ui/rc_clone_in_vec_init/rc.stderr index 702266d62d2c..57ea31f9ff89 100644 --- a/tests/ui/rc_clone_in_vec_init/rc.stderr +++ b/tests/ui/rc_clone_in_vec_init/rc.stderr @@ -24,7 +24,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/rc.rs:20:21 + --> tests/ui/rc_clone_in_vec_init/rc.rs:21:21 | LL | let v = vec![Rc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,13 +47,10 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/rc.rs:28:13 + --> tests/ui/rc_clone_in_vec_init/rc.rs:30:13 | LL | let v = vec![ | _____________^ -LL | | -LL | | -LL | | std::rc::Rc::new(Mutex::new({ ... | LL | | 2 LL | | ]; @@ -77,13 +74,10 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/rc.rs:39:14 + --> tests/ui/rc_clone_in_vec_init/rc.rs:42:14 | LL | let v1 = vec![ | ______________^ -LL | | -LL | | -LL | | Rc::new(Mutex::new({ ... | LL | | 2 LL | | ]; diff --git a/tests/ui/rc_clone_in_vec_init/weak.rs b/tests/ui/rc_clone_in_vec_init/weak.rs index fd2895d40458..af1ec1601dcf 100644 --- a/tests/ui/rc_clone_in_vec_init/weak.rs +++ b/tests/ui/rc_clone_in_vec_init/weak.rs @@ -8,18 +8,22 @@ fn main() {} fn should_warn_simple_case() { let v = vec![SyncWeak::::new(); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Weak` instance + //~^ rc_clone_in_vec_init + + let v2 = vec![UnSyncWeak::::new(); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Weak` instance + //~^ rc_clone_in_vec_init + + let v = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Weak` instance + //~^ rc_clone_in_vec_init + + let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Weak` instance + //~^ rc_clone_in_vec_init + + } fn should_warn_simple_case_with_big_indentation() { @@ -28,19 +32,22 @@ fn should_warn_simple_case_with_big_indentation() { dbg!(k); if true { let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Weak` instance + //~^ rc_clone_in_vec_init + + let v2 = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Weak` instance + //~^ rc_clone_in_vec_init + + } } } fn should_warn_complex_case() { let v = vec![ - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Weak` instance + //~^ rc_clone_in_vec_init + + Arc::downgrade(&Arc::new(Mutex::new({ let x = 1; dbg!(x); @@ -50,8 +57,9 @@ fn should_warn_complex_case() { ]; let v1 = vec![ - //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]` - //~| NOTE: each element will point to the same `Weak` instance + //~^ rc_clone_in_vec_init + + Rc::downgrade(&Rc::new(Mutex::new({ let x = 1; dbg!(x); diff --git a/tests/ui/rc_clone_in_vec_init/weak.stderr b/tests/ui/rc_clone_in_vec_init/weak.stderr index 68ca2a7eb848..26974dd7446c 100644 --- a/tests/ui/rc_clone_in_vec_init/weak.stderr +++ b/tests/ui/rc_clone_in_vec_init/weak.stderr @@ -24,7 +24,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:13:14 + --> tests/ui/rc_clone_in_vec_init/weak.rs:14:14 | LL | let v2 = vec![UnSyncWeak::::new(); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:17:13 + --> tests/ui/rc_clone_in_vec_init/weak.rs:19:13 | LL | let v = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:20:13 + --> tests/ui/rc_clone_in_vec_init/weak.rs:23:13 | LL | let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,7 +93,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:30:21 + --> tests/ui/rc_clone_in_vec_init/weak.rs:34:21 | LL | let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -116,7 +116,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:33:22 + --> tests/ui/rc_clone_in_vec_init/weak.rs:38:22 | LL | let v2 = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,13 +139,10 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:41:13 + --> tests/ui/rc_clone_in_vec_init/weak.rs:47:13 | LL | let v = vec![ | _____________^ -LL | | -LL | | -LL | | Arc::downgrade(&Arc::new(Mutex::new({ ... | LL | | 2 LL | | ]; @@ -169,13 +166,10 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:52:14 + --> tests/ui/rc_clone_in_vec_init/weak.rs:59:14 | LL | let v1 = vec![ | ______________^ -LL | | -LL | | -LL | | Rc::downgrade(&Rc::new(Mutex::new({ ... | LL | | 2 LL | | ]; diff --git a/tests/ui/rc_mutex.rs b/tests/ui/rc_mutex.rs index 40adb3ddce95..cccbc751f417 100644 --- a/tests/ui/rc_mutex.rs +++ b/tests/ui/rc_mutex.rs @@ -6,7 +6,7 @@ use std::sync::Mutex; pub struct MyStructWithPrivItem { foo: Rc>, - //~^ ERROR: usage of `Rc>` + //~^ rc_mutex } pub struct MyStructWithPubItem { @@ -25,11 +25,14 @@ pub enum MyEnum { // All of these test should be trigger the lint because they are not // part of the public api fn test1(foo: Rc>) {} -//~^ ERROR: usage of `Rc>` +//~^ rc_mutex + fn test2(foo: Rc>) {} -//~^ ERROR: usage of `Rc>` +//~^ rc_mutex + fn test3(foo: Rc>>) {} -//~^ ERROR: usage of `Rc>` +//~^ rc_mutex + // All of these test should be allowed because they are part of the // public api and `avoid_breaking_exported_api` is `false` by default. diff --git a/tests/ui/rc_mutex.stderr b/tests/ui/rc_mutex.stderr index 9aa18336df00..5b589cfa309a 100644 --- a/tests/ui/rc_mutex.stderr +++ b/tests/ui/rc_mutex.stderr @@ -17,7 +17,7 @@ LL | fn test1(foo: Rc>) {} = help: consider using `Rc>` or `Arc>` instead error: usage of `Rc>` - --> tests/ui/rc_mutex.rs:29:15 + --> tests/ui/rc_mutex.rs:30:15 | LL | fn test2(foo: Rc>) {} | ^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | fn test2(foo: Rc>) {} = help: consider using `Rc>` or `Arc>` instead error: usage of `Rc>` - --> tests/ui/rc_mutex.rs:31:15 + --> tests/ui/rc_mutex.rs:33:15 | LL | fn test3(foo: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/read_line_without_trim.fixed b/tests/ui/read_line_without_trim.fixed index 523ad5552747..9263a398ad85 100644 --- a/tests/ui/read_line_without_trim.fixed +++ b/tests/ui/read_line_without_trim.fixed @@ -10,22 +10,27 @@ fn main() { let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x: i32 = input.trim_end().parse().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x = input.trim_end().parse::().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x = input.trim_end().parse::().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x = input.trim_end().parse::().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x = input.trim_end().parse::().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); @@ -36,12 +41,14 @@ fn main() { let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); if input.trim_end() == "foo" { + //~^ read_line_without_trim println!("This will never ever execute!"); } let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); if input.trim_end().ends_with("foo") { + //~^ read_line_without_trim println!("Neither will this"); } } diff --git a/tests/ui/read_line_without_trim.rs b/tests/ui/read_line_without_trim.rs index e31ff0cde61d..ba5196bb51ba 100644 --- a/tests/ui/read_line_without_trim.rs +++ b/tests/ui/read_line_without_trim.rs @@ -10,22 +10,27 @@ fn main() { let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x: i32 = input.parse().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x = input.parse::().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x = input.parse::().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x = input.parse::().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); let _x = input.parse::().unwrap(); + //~^ read_line_without_trim let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); @@ -36,12 +41,14 @@ fn main() { let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); if input == "foo" { + //~^ read_line_without_trim println!("This will never ever execute!"); } let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); if input.ends_with("foo") { + //~^ read_line_without_trim println!("Neither will this"); } } diff --git a/tests/ui/read_line_without_trim.stderr b/tests/ui/read_line_without_trim.stderr index b54229f762a3..5e5618111432 100644 --- a/tests/ui/read_line_without_trim.stderr +++ b/tests/ui/read_line_without_trim.stderr @@ -15,7 +15,7 @@ LL | std::io::stdin().read_line(&mut input).unwrap(); = help: to override `-D warnings` add `#[allow(clippy::read_line_without_trim)]` error: calling `.parse()` on a string without trimming the trailing newline character - --> tests/ui/read_line_without_trim.rs:16:20 + --> tests/ui/read_line_without_trim.rs:17:20 | LL | let _x = input.parse::().unwrap(); | ----- ^^^^^^^^^^^^^^ @@ -23,13 +23,13 @@ LL | let _x = input.parse::().unwrap(); | help: try: `input.trim_end()` | note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the checking to always fail - --> tests/ui/read_line_without_trim.rs:15:5 + --> tests/ui/read_line_without_trim.rs:16:5 | LL | std::io::stdin().read_line(&mut input).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: calling `.parse()` on a string without trimming the trailing newline character - --> tests/ui/read_line_without_trim.rs:20:20 + --> tests/ui/read_line_without_trim.rs:22:20 | LL | let _x = input.parse::().unwrap(); | ----- ^^^^^^^^^^^^^^ @@ -37,13 +37,13 @@ LL | let _x = input.parse::().unwrap(); | help: try: `input.trim_end()` | note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the checking to always fail - --> tests/ui/read_line_without_trim.rs:19:5 + --> tests/ui/read_line_without_trim.rs:21:5 | LL | std::io::stdin().read_line(&mut input).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: calling `.parse()` on a string without trimming the trailing newline character - --> tests/ui/read_line_without_trim.rs:24:20 + --> tests/ui/read_line_without_trim.rs:27:20 | LL | let _x = input.parse::().unwrap(); | ----- ^^^^^^^^^^^^^^ @@ -51,13 +51,13 @@ LL | let _x = input.parse::().unwrap(); | help: try: `input.trim_end()` | note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the checking to always fail - --> tests/ui/read_line_without_trim.rs:23:5 + --> tests/ui/read_line_without_trim.rs:26:5 | LL | std::io::stdin().read_line(&mut input).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: calling `.parse()` on a string without trimming the trailing newline character - --> tests/ui/read_line_without_trim.rs:28:20 + --> tests/ui/read_line_without_trim.rs:32:20 | LL | let _x = input.parse::().unwrap(); | ----- ^^^^^^^^^^^^^^^ @@ -65,13 +65,13 @@ LL | let _x = input.parse::().unwrap(); | help: try: `input.trim_end()` | note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the checking to always fail - --> tests/ui/read_line_without_trim.rs:27:5 + --> tests/ui/read_line_without_trim.rs:31:5 | LL | std::io::stdin().read_line(&mut input).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: comparing a string literal without trimming the trailing newline character - --> tests/ui/read_line_without_trim.rs:38:8 + --> tests/ui/read_line_without_trim.rs:43:8 | LL | if input == "foo" { | -----^^^^^^^^^ @@ -79,13 +79,13 @@ LL | if input == "foo" { | help: try: `input.trim_end()` | note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the comparison to always fail - --> tests/ui/read_line_without_trim.rs:37:5 + --> tests/ui/read_line_without_trim.rs:42:5 | LL | std::io::stdin().read_line(&mut input).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: checking the end of a string without trimming the trailing newline character - --> tests/ui/read_line_without_trim.rs:44:8 + --> tests/ui/read_line_without_trim.rs:50:8 | LL | if input.ends_with("foo") { | -----^^^^^^^^^^^^^^^^^ @@ -93,7 +93,7 @@ LL | if input.ends_with("foo") { | help: try: `input.trim_end()` | note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the parsing to always fail - --> tests/ui/read_line_without_trim.rs:43:5 + --> tests/ui/read_line_without_trim.rs:49:5 | LL | std::io::stdin().read_line(&mut input).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/read_zero_byte_vec.rs b/tests/ui/read_zero_byte_vec.rs index 68acf4334699..938d61b68607 100644 --- a/tests/ui/read_zero_byte_vec.rs +++ b/tests/ui/read_zero_byte_vec.rs @@ -8,6 +8,7 @@ use std::fs::File; use std::io; use std::io::prelude::*; //@no-rustfix +//@require-annotations-for-level: WARN extern crate futures; use futures::io::{AsyncRead, AsyncReadExt}; use tokio::io::{AsyncRead as TokioAsyncRead, AsyncReadExt as _, AsyncWrite as TokioAsyncWrite, AsyncWriteExt as _}; diff --git a/tests/ui/read_zero_byte_vec.stderr b/tests/ui/read_zero_byte_vec.stderr index e2356f1cb56b..8f255bc87ab8 100644 --- a/tests/ui/read_zero_byte_vec.stderr +++ b/tests/ui/read_zero_byte_vec.stderr @@ -1,5 +1,5 @@ error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:21:5 + --> tests/ui/read_zero_byte_vec.rs:22:5 | LL | f.read_exact(&mut data).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data.resize(20, 0); f.read_exact(&mut data)` @@ -8,61 +8,61 @@ LL | f.read_exact(&mut data).unwrap(); = help: to override `-D warnings` add `#[allow(clippy::read_zero_byte_vec)]` error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:27:5 + --> tests/ui/read_zero_byte_vec.rs:28:5 | LL | f.read_exact(&mut data2)?; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data2.resize(cap, 0); f.read_exact(&mut data2)` error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:32:5 + --> tests/ui/read_zero_byte_vec.rs:33:5 | LL | f.read_exact(&mut data3)?; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:37:13 + --> tests/ui/read_zero_byte_vec.rs:38:13 | LL | let _ = f.read(&mut data4)?; | ^^^^^^^^^^^^^^^^^^ error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:43:9 + --> tests/ui/read_zero_byte_vec.rs:44:9 | LL | f.read(&mut data5) | ^^^^^^^^^^^^^^^^^^ error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:50:9 + --> tests/ui/read_zero_byte_vec.rs:51:9 | LL | f.read(&mut data6) | ^^^^^^^^^^^^^^^^^^ error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:84:9 + --> tests/ui/read_zero_byte_vec.rs:85:9 | LL | f.read(&mut v)?; | ^^^^^^^^^^^^^^ error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:94:5 + --> tests/ui/read_zero_byte_vec.rs:95:5 | LL | r.read(&mut data).await.unwrap(); | ^^^^^^^^^^^^^^^^^ error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:99:5 + --> tests/ui/read_zero_byte_vec.rs:100:5 | LL | r.read_exact(&mut data2).await.unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:106:5 + --> tests/ui/read_zero_byte_vec.rs:107:5 | LL | r.read(&mut data).await.unwrap(); | ^^^^^^^^^^^^^^^^^ error: reading zero byte data to `Vec` - --> tests/ui/read_zero_byte_vec.rs:111:5 + --> tests/ui/read_zero_byte_vec.rs:112:5 | LL | r.read_exact(&mut data2).await.unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/readonly_write_lock.fixed b/tests/ui/readonly_write_lock.fixed index 4db13482ac78..21822444f35f 100644 --- a/tests/ui/readonly_write_lock.fixed +++ b/tests/ui/readonly_write_lock.fixed @@ -14,14 +14,16 @@ fn main() { { let writer = lock.read().unwrap(); - //~^ ERROR: this write lock is used only for reading - //~| NOTE: `-D clippy::readonly-write-lock` implied by `-D warnings` + //~^ readonly_write_lock + + dbg!(&writer); } { let writer = lock.read().unwrap(); - //~^ ERROR: this write lock is used only for reading + //~^ readonly_write_lock + accept_i32(*writer); } diff --git a/tests/ui/readonly_write_lock.rs b/tests/ui/readonly_write_lock.rs index 66ba1b2d6969..b3fd1a611cc8 100644 --- a/tests/ui/readonly_write_lock.rs +++ b/tests/ui/readonly_write_lock.rs @@ -14,14 +14,16 @@ fn main() { { let writer = lock.write().unwrap(); - //~^ ERROR: this write lock is used only for reading - //~| NOTE: `-D clippy::readonly-write-lock` implied by `-D warnings` + //~^ readonly_write_lock + + dbg!(&writer); } { let writer = lock.write().unwrap(); - //~^ ERROR: this write lock is used only for reading + //~^ readonly_write_lock + accept_i32(*writer); } diff --git a/tests/ui/readonly_write_lock.stderr b/tests/ui/readonly_write_lock.stderr index 6b1ef3c4720f..a3f88e92bfae 100644 --- a/tests/ui/readonly_write_lock.stderr +++ b/tests/ui/readonly_write_lock.stderr @@ -8,7 +8,7 @@ LL | let writer = lock.write().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::readonly_write_lock)]` error: this write lock is used only for reading - --> tests/ui/readonly_write_lock.rs:23:22 + --> tests/ui/readonly_write_lock.rs:24:22 | LL | let writer = lock.write().unwrap(); | ^^^^^^^^^^^^ help: consider using a read lock instead: `lock.read()` diff --git a/tests/ui/recursive_format_impl.rs b/tests/ui/recursive_format_impl.rs index b3eafc6dad7a..d9b3a15eb9b1 100644 --- a/tests/ui/recursive_format_impl.rs +++ b/tests/ui/recursive_format_impl.rs @@ -29,8 +29,9 @@ impl B for A { impl fmt::Display for A { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.to_string()) - //~^ ERROR: using `self.to_string` in `fmt::Display` implementation will cause inf - //~| NOTE: `-D clippy::recursive-format-impl` implied by `-D warnings` + //~^ recursive_format_impl + + } } @@ -75,7 +76,8 @@ struct G; impl std::fmt::Display for G { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self) - //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs + //~^ recursive_format_impl + } } @@ -85,14 +87,16 @@ struct H; impl std::fmt::Display for H { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", &self) - //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs + //~^ recursive_format_impl + } } impl std::fmt::Debug for H { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", &self) - //~^ ERROR: using `self` as `Debug` in `impl Debug` will cause infinite recursion + //~^ recursive_format_impl + } } @@ -102,7 +106,8 @@ struct H2; impl std::fmt::Display for H2 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", &&&self) - //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs + //~^ recursive_format_impl + } } @@ -177,14 +182,16 @@ impl std::ops::Deref for J { impl std::fmt::Display for J { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", &*self) - //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs + //~^ recursive_format_impl + } } impl std::fmt::Debug for J { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{:?}", &*self) - //~^ ERROR: using `self` as `Debug` in `impl Debug` will cause infinite recursion + //~^ recursive_format_impl + } } @@ -201,7 +208,8 @@ impl std::ops::Deref for J2 { impl std::fmt::Display for J2 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", *self) - //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs + //~^ recursive_format_impl + } } @@ -218,7 +226,8 @@ impl std::ops::Deref for J3 { impl std::fmt::Display for J3 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", **&&*self) - //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs + //~^ recursive_format_impl + } } @@ -235,7 +244,8 @@ impl std::ops::Deref for J4 { impl std::fmt::Display for J4 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", &&**&&*self) - //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs + //~^ recursive_format_impl + } } diff --git a/tests/ui/recursive_format_impl.stderr b/tests/ui/recursive_format_impl.stderr index f80aff01eb53..515f18d5b477 100644 --- a/tests/ui/recursive_format_impl.stderr +++ b/tests/ui/recursive_format_impl.stderr @@ -8,7 +8,7 @@ LL | write!(f, "{}", self.to_string()) = help: to override `-D warnings` add `#[allow(clippy::recursive_format_impl)]` error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:77:9 + --> tests/ui/recursive_format_impl.rs:78:9 | LL | write!(f, "{}", self) | ^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | write!(f, "{}", self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:87:9 + --> tests/ui/recursive_format_impl.rs:89:9 | LL | write!(f, "{}", &self) | ^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | write!(f, "{}", &self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Debug` in `impl Debug` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:94:9 + --> tests/ui/recursive_format_impl.rs:97:9 | LL | write!(f, "{:?}", &self) | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | write!(f, "{:?}", &self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:104:9 + --> tests/ui/recursive_format_impl.rs:108:9 | LL | write!(f, "{}", &&&self) | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | write!(f, "{}", &&&self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:179:9 + --> tests/ui/recursive_format_impl.rs:184:9 | LL | write!(f, "{}", &*self) | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | write!(f, "{}", &*self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Debug` in `impl Debug` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:186:9 + --> tests/ui/recursive_format_impl.rs:192:9 | LL | write!(f, "{:?}", &*self) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | write!(f, "{:?}", &*self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:203:9 + --> tests/ui/recursive_format_impl.rs:210:9 | LL | write!(f, "{}", *self) | ^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | write!(f, "{}", *self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:220:9 + --> tests/ui/recursive_format_impl.rs:228:9 | LL | write!(f, "{}", **&&*self) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | write!(f, "{}", **&&*self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:237:9 + --> tests/ui/recursive_format_impl.rs:246:9 | LL | write!(f, "{}", &&**&&*self) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_allocation.rs b/tests/ui/redundant_allocation.rs index e70f8e71fae8..e3bf6c58b153 100644 --- a/tests/ui/redundant_allocation.rs +++ b/tests/ui/redundant_allocation.rs @@ -14,24 +14,29 @@ mod outer_box { use std::sync::Arc; pub fn box_test6(foo: Box>) {} - //~^ ERROR: usage of `Box>` - //~| NOTE: `Rc` is already on the heap, `Box>` makes an extra allocation + //~^ redundant_allocation + + pub fn box_test7(foo: Box>) {} - //~^ ERROR: usage of `Box>` - //~| NOTE: `Arc` is already on the heap, `Box>` makes an extra allocation + //~^ redundant_allocation + + pub fn box_test8() -> Box>> { - //~^ ERROR: usage of `Box>>` - //~| NOTE: `Rc>` is already on the heap, `Box>>` makes an e + //~^ redundant_allocation + + unimplemented!(); } pub fn box_test9(foo: Box>) -> Box>> { - //~^ ERROR: usage of `Box>` - //~| NOTE: `Arc` is already on the heap, `Box>` makes an extra allocation - //~| ERROR: usage of `Box>>` - //~| NOTE: `Arc>` is already on the heap, `Box>>` makes an extra a + //~^ redundant_allocation + //~| redundant_allocation + + + + unimplemented!(); } } @@ -43,24 +48,29 @@ mod outer_rc { use std::sync::Arc; pub fn rc_test5(a: Rc>) {} - //~^ ERROR: usage of `Rc>` - //~| NOTE: `Box` is already on the heap, `Rc>` makes an extra allocati + //~^ redundant_allocation + + pub fn rc_test7(a: Rc>) {} - //~^ ERROR: usage of `Rc>` - //~| NOTE: `Arc` is already on the heap, `Rc>` makes an extra allocati + //~^ redundant_allocation + + pub fn rc_test8() -> Rc>> { - //~^ ERROR: usage of `Rc>>` - //~| NOTE: `Box>` is already on the heap, `Rc>>` makes an + //~^ redundant_allocation + + unimplemented!(); } pub fn rc_test9(foo: Rc>) -> Rc>> { - //~^ ERROR: usage of `Rc>` - //~| NOTE: `Arc` is already on the heap, `Rc>` makes an extra allocation - //~| ERROR: usage of `Rc>>` - //~| NOTE: `Arc>` is already on the heap, `Rc>>` makes an extra al + //~^ redundant_allocation + //~| redundant_allocation + + + + unimplemented!(); } } @@ -72,24 +82,29 @@ mod outer_arc { use std::sync::Arc; pub fn arc_test5(a: Arc>) {} - //~^ ERROR: usage of `Arc>` - //~| NOTE: `Box` is already on the heap, `Arc>` makes an extra allocat + //~^ redundant_allocation + + pub fn arc_test6(a: Arc>) {} - //~^ ERROR: usage of `Arc>` - //~| NOTE: `Rc` is already on the heap, `Arc>` makes an extra allocatio + //~^ redundant_allocation + + pub fn arc_test8() -> Arc>> { - //~^ ERROR: usage of `Arc>>` - //~| NOTE: `Box>` is already on the heap, `Arc>>` makes an + //~^ redundant_allocation + + unimplemented!(); } pub fn arc_test9(foo: Arc>) -> Arc>> { - //~^ ERROR: usage of `Arc>` - //~| NOTE: `Rc` is already on the heap, `Arc>` makes an extra allocation - //~| ERROR: usage of `Arc>>` - //~| NOTE: `Rc>` is already on the heap, `Arc>>` makes an extra all + //~^ redundant_allocation + //~| redundant_allocation + + + + unimplemented!(); } } @@ -112,8 +127,9 @@ mod box_dyn { pub fn test_rc(_: Rc>) {} pub fn test_arc(_: Arc>) {} pub fn test_rc_box(_: Rc>>) {} - //~^ ERROR: usage of `Rc>>` - //~| NOTE: `Box>` is already on the heap, `Rc>>` makes an ex + //~^ redundant_allocation + + } // https://github.com/rust-lang/rust-clippy/issues/8604 @@ -146,17 +162,21 @@ mod box_fat_ptr { pub fn test_box_custom(_: Box>) {} pub fn test_rc_box_str(_: Rc>>) {} - //~^ ERROR: usage of `Rc>>` - //~| NOTE: `Box>` is already on the heap, `Rc>>` makes an extra + //~^ redundant_allocation + + pub fn test_rc_box_slice(_: Rc>>) {} - //~^ ERROR: usage of `Rc>>` - //~| NOTE: `Box>` is already on the heap, `Rc>>` makes a + //~^ redundant_allocation + + pub fn test_rc_box_path(_: Rc>>) {} - //~^ ERROR: usage of `Rc>>` - //~| NOTE: `Box>` is already on the heap, `Rc>>` makes an extr + //~^ redundant_allocation + + pub fn test_rc_box_custom(_: Rc>>) {} - //~^ ERROR: usage of `Rc>>` - //~| NOTE: `Box>` is already on the heap, `Rc>>` makes + //~^ redundant_allocation + + } // https://github.com/rust-lang/rust-clippy/issues/11417 diff --git a/tests/ui/redundant_allocation.stderr b/tests/ui/redundant_allocation.stderr index 8a043013e07a..407cdef1c20d 100644 --- a/tests/ui/redundant_allocation.stderr +++ b/tests/ui/redundant_allocation.stderr @@ -10,7 +10,7 @@ LL | pub fn box_test6(foo: Box>) {} = help: to override `-D warnings` add `#[allow(clippy::redundant_allocation)]` error: usage of `Box>` - --> tests/ui/redundant_allocation.rs:20:30 + --> tests/ui/redundant_allocation.rs:21:30 | LL | pub fn box_test7(foo: Box>) {} | ^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | pub fn box_test7(foo: Box>) {} = help: consider using just `Box` or `Arc` error: usage of `Box>>` - --> tests/ui/redundant_allocation.rs:24:27 + --> tests/ui/redundant_allocation.rs:26:27 | LL | pub fn box_test8() -> Box>> { | ^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | pub fn box_test8() -> Box>> { = help: consider using just `Box>` or `Rc>` error: usage of `Box>` - --> tests/ui/redundant_allocation.rs:30:30 + --> tests/ui/redundant_allocation.rs:33:30 | LL | pub fn box_test9(foo: Box>) -> Box>> { | ^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | pub fn box_test9(foo: Box>) -> Box>> { = help: consider using just `Box` or `Arc` error: usage of `Box>>` - --> tests/ui/redundant_allocation.rs:30:46 + --> tests/ui/redundant_allocation.rs:33:46 | LL | pub fn box_test9(foo: Box>) -> Box>> { | ^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | pub fn box_test9(foo: Box>) -> Box>> { = help: consider using just `Box>` or `Arc>` error: usage of `Rc>` - --> tests/ui/redundant_allocation.rs:45:24 + --> tests/ui/redundant_allocation.rs:50:24 | LL | pub fn rc_test5(a: Rc>) {} | ^^^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | pub fn rc_test5(a: Rc>) {} = help: consider using just `Rc` or `Box` error: usage of `Rc>` - --> tests/ui/redundant_allocation.rs:49:24 + --> tests/ui/redundant_allocation.rs:55:24 | LL | pub fn rc_test7(a: Rc>) {} | ^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | pub fn rc_test7(a: Rc>) {} = help: consider using just `Rc` or `Arc` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:53:26 + --> tests/ui/redundant_allocation.rs:60:26 | LL | pub fn rc_test8() -> Rc>> { | ^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | pub fn rc_test8() -> Rc>> { = help: consider using just `Rc>` or `Box>` error: usage of `Rc>` - --> tests/ui/redundant_allocation.rs:59:29 + --> tests/ui/redundant_allocation.rs:67:29 | LL | pub fn rc_test9(foo: Rc>) -> Rc>> { | ^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | pub fn rc_test9(foo: Rc>) -> Rc>> { = help: consider using just `Rc` or `Arc` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:59:44 + --> tests/ui/redundant_allocation.rs:67:44 | LL | pub fn rc_test9(foo: Rc>) -> Rc>> { | ^^^^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | pub fn rc_test9(foo: Rc>) -> Rc>> { = help: consider using just `Rc>` or `Arc>` error: usage of `Arc>` - --> tests/ui/redundant_allocation.rs:74:25 + --> tests/ui/redundant_allocation.rs:84:25 | LL | pub fn arc_test5(a: Arc>) {} | ^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | pub fn arc_test5(a: Arc>) {} = help: consider using just `Arc` or `Box` error: usage of `Arc>` - --> tests/ui/redundant_allocation.rs:78:25 + --> tests/ui/redundant_allocation.rs:89:25 | LL | pub fn arc_test6(a: Arc>) {} | ^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | pub fn arc_test6(a: Arc>) {} = help: consider using just `Arc` or `Rc` error: usage of `Arc>>` - --> tests/ui/redundant_allocation.rs:82:27 + --> tests/ui/redundant_allocation.rs:94:27 | LL | pub fn arc_test8() -> Arc>> { | ^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | pub fn arc_test8() -> Arc>> { = help: consider using just `Arc>` or `Box>` error: usage of `Arc>` - --> tests/ui/redundant_allocation.rs:88:30 + --> tests/ui/redundant_allocation.rs:101:30 | LL | pub fn arc_test9(foo: Arc>) -> Arc>> { | ^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | pub fn arc_test9(foo: Arc>) -> Arc>> { = help: consider using just `Arc` or `Rc` error: usage of `Arc>>` - --> tests/ui/redundant_allocation.rs:88:45 + --> tests/ui/redundant_allocation.rs:101:45 | LL | pub fn arc_test9(foo: Arc>) -> Arc>> { | ^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | pub fn arc_test9(foo: Arc>) -> Arc>> { = help: consider using just `Arc>` or `Rc>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:114:27 + --> tests/ui/redundant_allocation.rs:129:27 | LL | pub fn test_rc_box(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | pub fn test_rc_box(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:148:31 + --> tests/ui/redundant_allocation.rs:164:31 | LL | pub fn test_rc_box_str(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | pub fn test_rc_box_str(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:151:33 + --> tests/ui/redundant_allocation.rs:168:33 | LL | pub fn test_rc_box_slice(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ LL | pub fn test_rc_box_slice(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:154:32 + --> tests/ui/redundant_allocation.rs:172:32 | LL | pub fn test_rc_box_path(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | pub fn test_rc_box_path(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:157:34 + --> tests/ui/redundant_allocation.rs:176:34 | LL | pub fn test_rc_box_custom(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_allocation_fixable.fixed b/tests/ui/redundant_allocation_fixable.fixed index 61c989c67a1a..7773ba11f973 100644 --- a/tests/ui/redundant_allocation_fixable.fixed +++ b/tests/ui/redundant_allocation_fixable.fixed @@ -21,14 +21,18 @@ mod outer_box { use std::sync::Arc; pub fn box_test1(foo: &T) {} + //~^ redundant_allocation pub fn box_test2(foo: &MyStruct) {} + //~^ redundant_allocation pub fn box_test3(foo: &MyEnum) {} + //~^ redundant_allocation pub fn box_test4_neg(foo: Box>) {} pub fn box_test5(foo: Box) {} + //~^ redundant_allocation } mod outer_rc { @@ -38,14 +42,18 @@ mod outer_rc { use std::sync::Arc; pub fn rc_test1(foo: &T) {} + //~^ redundant_allocation pub fn rc_test2(foo: &MyStruct) {} + //~^ redundant_allocation pub fn rc_test3(foo: &MyEnum) {} + //~^ redundant_allocation pub fn rc_test4_neg(foo: Rc>) {} pub fn rc_test6(a: Rc) {} + //~^ redundant_allocation } mod outer_arc { @@ -55,14 +63,18 @@ mod outer_arc { use std::sync::Arc; pub fn arc_test1(foo: &T) {} + //~^ redundant_allocation pub fn arc_test2(foo: &MyStruct) {} + //~^ redundant_allocation pub fn arc_test3(foo: &MyEnum) {} + //~^ redundant_allocation pub fn arc_test4_neg(foo: Arc>) {} pub fn arc_test7(a: Arc) {} + //~^ redundant_allocation } fn main() {} diff --git a/tests/ui/redundant_allocation_fixable.rs b/tests/ui/redundant_allocation_fixable.rs index 3ad1e9a978df..fb86ed2b3cfd 100644 --- a/tests/ui/redundant_allocation_fixable.rs +++ b/tests/ui/redundant_allocation_fixable.rs @@ -21,14 +21,18 @@ mod outer_box { use std::sync::Arc; pub fn box_test1(foo: Box<&T>) {} + //~^ redundant_allocation pub fn box_test2(foo: Box<&MyStruct>) {} + //~^ redundant_allocation pub fn box_test3(foo: Box<&MyEnum>) {} + //~^ redundant_allocation pub fn box_test4_neg(foo: Box>) {} pub fn box_test5(foo: Box>) {} + //~^ redundant_allocation } mod outer_rc { @@ -38,14 +42,18 @@ mod outer_rc { use std::sync::Arc; pub fn rc_test1(foo: Rc<&T>) {} + //~^ redundant_allocation pub fn rc_test2(foo: Rc<&MyStruct>) {} + //~^ redundant_allocation pub fn rc_test3(foo: Rc<&MyEnum>) {} + //~^ redundant_allocation pub fn rc_test4_neg(foo: Rc>) {} pub fn rc_test6(a: Rc>) {} + //~^ redundant_allocation } mod outer_arc { @@ -55,14 +63,18 @@ mod outer_arc { use std::sync::Arc; pub fn arc_test1(foo: Arc<&T>) {} + //~^ redundant_allocation pub fn arc_test2(foo: Arc<&MyStruct>) {} + //~^ redundant_allocation pub fn arc_test3(foo: Arc<&MyEnum>) {} + //~^ redundant_allocation pub fn arc_test4_neg(foo: Arc>) {} pub fn arc_test7(a: Arc>) {} + //~^ redundant_allocation } fn main() {} diff --git a/tests/ui/redundant_allocation_fixable.stderr b/tests/ui/redundant_allocation_fixable.stderr index 34a1a21bdadc..ed8282cc82ce 100644 --- a/tests/ui/redundant_allocation_fixable.stderr +++ b/tests/ui/redundant_allocation_fixable.stderr @@ -9,7 +9,7 @@ LL | pub fn box_test1(foo: Box<&T>) {} = help: to override `-D warnings` add `#[allow(clippy::redundant_allocation)]` error: usage of `Box<&MyStruct>` - --> tests/ui/redundant_allocation_fixable.rs:25:27 + --> tests/ui/redundant_allocation_fixable.rs:26:27 | LL | pub fn box_test2(foo: Box<&MyStruct>) {} | ^^^^^^^^^^^^^^ help: try: `&MyStruct` @@ -17,7 +17,7 @@ LL | pub fn box_test2(foo: Box<&MyStruct>) {} = note: `&MyStruct` is already a pointer, `Box<&MyStruct>` allocates a pointer on the heap error: usage of `Box<&MyEnum>` - --> tests/ui/redundant_allocation_fixable.rs:27:27 + --> tests/ui/redundant_allocation_fixable.rs:29:27 | LL | pub fn box_test3(foo: Box<&MyEnum>) {} | ^^^^^^^^^^^^ help: try: `&MyEnum` @@ -25,7 +25,7 @@ LL | pub fn box_test3(foo: Box<&MyEnum>) {} = note: `&MyEnum` is already a pointer, `Box<&MyEnum>` allocates a pointer on the heap error: usage of `Box>` - --> tests/ui/redundant_allocation_fixable.rs:31:30 + --> tests/ui/redundant_allocation_fixable.rs:34:30 | LL | pub fn box_test5(foo: Box>) {} | ^^^^^^^^^^^ help: try: `Box` @@ -33,7 +33,7 @@ LL | pub fn box_test5(foo: Box>) {} = note: `Box` is already on the heap, `Box>` makes an extra allocation error: usage of `Rc<&T>` - --> tests/ui/redundant_allocation_fixable.rs:40:29 + --> tests/ui/redundant_allocation_fixable.rs:44:29 | LL | pub fn rc_test1(foo: Rc<&T>) {} | ^^^^^^ help: try: `&T` @@ -41,7 +41,7 @@ LL | pub fn rc_test1(foo: Rc<&T>) {} = note: `&T` is already a pointer, `Rc<&T>` allocates a pointer on the heap error: usage of `Rc<&MyStruct>` - --> tests/ui/redundant_allocation_fixable.rs:42:26 + --> tests/ui/redundant_allocation_fixable.rs:47:26 | LL | pub fn rc_test2(foo: Rc<&MyStruct>) {} | ^^^^^^^^^^^^^ help: try: `&MyStruct` @@ -49,7 +49,7 @@ LL | pub fn rc_test2(foo: Rc<&MyStruct>) {} = note: `&MyStruct` is already a pointer, `Rc<&MyStruct>` allocates a pointer on the heap error: usage of `Rc<&MyEnum>` - --> tests/ui/redundant_allocation_fixable.rs:44:26 + --> tests/ui/redundant_allocation_fixable.rs:50:26 | LL | pub fn rc_test3(foo: Rc<&MyEnum>) {} | ^^^^^^^^^^^ help: try: `&MyEnum` @@ -57,7 +57,7 @@ LL | pub fn rc_test3(foo: Rc<&MyEnum>) {} = note: `&MyEnum` is already a pointer, `Rc<&MyEnum>` allocates a pointer on the heap error: usage of `Rc>` - --> tests/ui/redundant_allocation_fixable.rs:48:24 + --> tests/ui/redundant_allocation_fixable.rs:55:24 | LL | pub fn rc_test6(a: Rc>) {} | ^^^^^^^^^^^^ help: try: `Rc` @@ -65,7 +65,7 @@ LL | pub fn rc_test6(a: Rc>) {} = note: `Rc` is already on the heap, `Rc>` makes an extra allocation error: usage of `Arc<&T>` - --> tests/ui/redundant_allocation_fixable.rs:57:30 + --> tests/ui/redundant_allocation_fixable.rs:65:30 | LL | pub fn arc_test1(foo: Arc<&T>) {} | ^^^^^^^ help: try: `&T` @@ -73,7 +73,7 @@ LL | pub fn arc_test1(foo: Arc<&T>) {} = note: `&T` is already a pointer, `Arc<&T>` allocates a pointer on the heap error: usage of `Arc<&MyStruct>` - --> tests/ui/redundant_allocation_fixable.rs:59:27 + --> tests/ui/redundant_allocation_fixable.rs:68:27 | LL | pub fn arc_test2(foo: Arc<&MyStruct>) {} | ^^^^^^^^^^^^^^ help: try: `&MyStruct` @@ -81,7 +81,7 @@ LL | pub fn arc_test2(foo: Arc<&MyStruct>) {} = note: `&MyStruct` is already a pointer, `Arc<&MyStruct>` allocates a pointer on the heap error: usage of `Arc<&MyEnum>` - --> tests/ui/redundant_allocation_fixable.rs:61:27 + --> tests/ui/redundant_allocation_fixable.rs:71:27 | LL | pub fn arc_test3(foo: Arc<&MyEnum>) {} | ^^^^^^^^^^^^ help: try: `&MyEnum` @@ -89,7 +89,7 @@ LL | pub fn arc_test3(foo: Arc<&MyEnum>) {} = note: `&MyEnum` is already a pointer, `Arc<&MyEnum>` allocates a pointer on the heap error: usage of `Arc>` - --> tests/ui/redundant_allocation_fixable.rs:65:25 + --> tests/ui/redundant_allocation_fixable.rs:76:25 | LL | pub fn arc_test7(a: Arc>) {} | ^^^^^^^^^^^^^^ help: try: `Arc` diff --git a/tests/ui/redundant_as_str.fixed b/tests/ui/redundant_as_str.fixed index 708a1cc91506..4c5f7893d42e 100644 --- a/tests/ui/redundant_as_str.fixed +++ b/tests/ui/redundant_as_str.fixed @@ -6,7 +6,9 @@ fn main() { // These methods are redundant and the `as_str` can be removed let _redundant = string.as_bytes(); + //~^ redundant_as_str let _redundant = string.is_empty(); + //~^ redundant_as_str // These methods don't use `as_str` when they are redundant let _no_as_str = string.as_bytes(); diff --git a/tests/ui/redundant_as_str.rs b/tests/ui/redundant_as_str.rs index 257af591ceff..e3baec754595 100644 --- a/tests/ui/redundant_as_str.rs +++ b/tests/ui/redundant_as_str.rs @@ -6,7 +6,9 @@ fn main() { // These methods are redundant and the `as_str` can be removed let _redundant = string.as_str().as_bytes(); + //~^ redundant_as_str let _redundant = string.as_str().is_empty(); + //~^ redundant_as_str // These methods don't use `as_str` when they are redundant let _no_as_str = string.as_bytes(); diff --git a/tests/ui/redundant_as_str.stderr b/tests/ui/redundant_as_str.stderr index f5379d701db8..fc99c008220e 100644 --- a/tests/ui/redundant_as_str.stderr +++ b/tests/ui/redundant_as_str.stderr @@ -8,7 +8,7 @@ LL | let _redundant = string.as_str().as_bytes(); = help: to override `-D warnings` add `#[allow(clippy::redundant_as_str)]` error: this `as_str` is redundant and can be removed as the method immediately following exists on `String` too - --> tests/ui/redundant_as_str.rs:9:29 + --> tests/ui/redundant_as_str.rs:10:29 | LL | let _redundant = string.as_str().is_empty(); | ^^^^^^^^^^^^^^^^^ help: try: `is_empty` diff --git a/tests/ui/redundant_async_block.fixed b/tests/ui/redundant_async_block.fixed index a1875c1c06e1..2f14f27e7056 100644 --- a/tests/ui/redundant_async_block.fixed +++ b/tests/ui/redundant_async_block.fixed @@ -11,6 +11,7 @@ async fn func2() -> String { let s = String::from("some string"); let f = async { (*s).to_owned() }; let x = f; + //~^ redundant_async_block x.await } @@ -18,13 +19,16 @@ fn main() { let fut1 = async { 17 }; // Lint let fut2 = fut1; + //~^ redundant_async_block let fut1 = async { 25 }; // Lint let fut2 = fut1; + //~^ redundant_async_block // Lint let fut = async { 42 }; + //~^ redundant_async_block // Do not lint: not a single expression let fut = async { @@ -41,6 +45,7 @@ fn capture_local() -> impl Future { let fut = async { 17 }; // Lint fut + //~^ redundant_async_block } fn capture_local_closure(s: &str) -> impl Future { @@ -54,11 +59,13 @@ fn capture_arg(s: &str) -> impl Future { let fut = async move { s }; // Lint fut + //~^ redundant_async_block } fn capture_future_arg(f: impl Future) -> impl Future { // Lint f + //~^ redundant_async_block } fn capture_func_result(f: FN) -> impl Future @@ -82,6 +89,7 @@ where { // Lint async { f().await + 1 } + //~^ redundant_async_block } #[derive(Debug, Clone)] @@ -145,6 +153,7 @@ fn all_from_macro() -> impl Future { () => { // Lint async { 42 } + //~^ redundant_async_block }; } mac!() @@ -165,6 +174,7 @@ fn safe_parts_from_macro() -> impl Future { ($e: expr) => { // Lint async { $e } + //~^ redundant_async_block }; } mac!(42) diff --git a/tests/ui/redundant_async_block.rs b/tests/ui/redundant_async_block.rs index bb43403a043e..f5fe26b19cc8 100644 --- a/tests/ui/redundant_async_block.rs +++ b/tests/ui/redundant_async_block.rs @@ -11,6 +11,7 @@ async fn func2() -> String { let s = String::from("some string"); let f = async { (*s).to_owned() }; let x = async { f.await }; + //~^ redundant_async_block x.await } @@ -18,13 +19,16 @@ fn main() { let fut1 = async { 17 }; // Lint let fut2 = async { fut1.await }; + //~^ redundant_async_block let fut1 = async { 25 }; // Lint let fut2 = async move { fut1.await }; + //~^ redundant_async_block // Lint let fut = async { async { 42 }.await }; + //~^ redundant_async_block // Do not lint: not a single expression let fut = async { @@ -41,6 +45,7 @@ fn capture_local() -> impl Future { let fut = async { 17 }; // Lint async move { fut.await } + //~^ redundant_async_block } fn capture_local_closure(s: &str) -> impl Future { @@ -54,11 +59,13 @@ fn capture_arg(s: &str) -> impl Future { let fut = async move { s }; // Lint async move { fut.await } + //~^ redundant_async_block } fn capture_future_arg(f: impl Future) -> impl Future { // Lint async { f.await } + //~^ redundant_async_block } fn capture_func_result(f: FN) -> impl Future @@ -82,6 +89,7 @@ where { // Lint async { async { f().await + 1 }.await } + //~^ redundant_async_block } #[derive(Debug, Clone)] @@ -145,6 +153,7 @@ fn all_from_macro() -> impl Future { () => { // Lint async { async { 42 }.await } + //~^ redundant_async_block }; } mac!() @@ -165,6 +174,7 @@ fn safe_parts_from_macro() -> impl Future { ($e: expr) => { // Lint async { async { $e }.await } + //~^ redundant_async_block }; } mac!(42) diff --git a/tests/ui/redundant_async_block.stderr b/tests/ui/redundant_async_block.stderr index c6a5e2f28ada..386f00a25c2f 100644 --- a/tests/ui/redundant_async_block.stderr +++ b/tests/ui/redundant_async_block.stderr @@ -8,31 +8,25 @@ LL | let x = async { f.await }; = help: to override `-D warnings` add `#[allow(clippy::redundant_async_block)]` error: this async expression only awaits a single future - --> tests/ui/redundant_async_block.rs:20:16 + --> tests/ui/redundant_async_block.rs:21:16 | LL | let fut2 = async { fut1.await }; | ^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1` error: this async expression only awaits a single future - --> tests/ui/redundant_async_block.rs:24:16 + --> tests/ui/redundant_async_block.rs:26:16 | LL | let fut2 = async move { fut1.await }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1` error: this async expression only awaits a single future - --> tests/ui/redundant_async_block.rs:27:15 + --> tests/ui/redundant_async_block.rs:30:15 | LL | let fut = async { async { 42 }.await }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }` error: this async expression only awaits a single future - --> tests/ui/redundant_async_block.rs:43:5 - | -LL | async move { fut.await } - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut` - -error: this async expression only awaits a single future - --> tests/ui/redundant_async_block.rs:56:5 + --> tests/ui/redundant_async_block.rs:47:5 | LL | async move { fut.await } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut` @@ -40,17 +34,23 @@ LL | async move { fut.await } error: this async expression only awaits a single future --> tests/ui/redundant_async_block.rs:61:5 | +LL | async move { fut.await } + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut` + +error: this async expression only awaits a single future + --> tests/ui/redundant_async_block.rs:67:5 + | LL | async { f.await } | ^^^^^^^^^^^^^^^^^ help: you can reduce it to: `f` error: this async expression only awaits a single future - --> tests/ui/redundant_async_block.rs:84:5 + --> tests/ui/redundant_async_block.rs:91:5 | LL | async { async { f().await + 1 }.await } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { f().await + 1 }` error: this async expression only awaits a single future - --> tests/ui/redundant_async_block.rs:147:13 + --> tests/ui/redundant_async_block.rs:155:13 | LL | async { async { 42 }.await } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }` @@ -61,7 +61,7 @@ LL | mac!() = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error: this async expression only awaits a single future - --> tests/ui/redundant_async_block.rs:167:13 + --> tests/ui/redundant_async_block.rs:176:13 | LL | async { async { $e }.await } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { $e }` diff --git a/tests/ui/redundant_at_rest_pattern.fixed b/tests/ui/redundant_at_rest_pattern.fixed index a7997637372e..908b9051b7ef 100644 --- a/tests/ui/redundant_at_rest_pattern.fixed +++ b/tests/ui/redundant_at_rest_pattern.fixed @@ -7,13 +7,19 @@ extern crate proc_macros; fn main() { if let a = [()] {} + //~^ redundant_at_rest_pattern if let ref a = [()] {} + //~^ redundant_at_rest_pattern if let mut a = [()] {} + //~^ redundant_at_rest_pattern if let ref mut a = [()] {} + //~^ redundant_at_rest_pattern let v = vec![()]; if let a = &*v {} + //~^ redundant_at_rest_pattern let s = &[()]; if let a = s {} + //~^ redundant_at_rest_pattern // Don't lint if let [..] = &*v {} if let [a] = &*v {} diff --git a/tests/ui/redundant_at_rest_pattern.rs b/tests/ui/redundant_at_rest_pattern.rs index f103d1f1a179..0f19459773a9 100644 --- a/tests/ui/redundant_at_rest_pattern.rs +++ b/tests/ui/redundant_at_rest_pattern.rs @@ -7,13 +7,19 @@ extern crate proc_macros; fn main() { if let [a @ ..] = [()] {} + //~^ redundant_at_rest_pattern if let [ref a @ ..] = [()] {} + //~^ redundant_at_rest_pattern if let [mut a @ ..] = [()] {} + //~^ redundant_at_rest_pattern if let [ref mut a @ ..] = [()] {} + //~^ redundant_at_rest_pattern let v = vec![()]; if let [a @ ..] = &*v {} + //~^ redundant_at_rest_pattern let s = &[()]; if let [a @ ..] = s {} + //~^ redundant_at_rest_pattern // Don't lint if let [..] = &*v {} if let [a] = &*v {} diff --git a/tests/ui/redundant_at_rest_pattern.stderr b/tests/ui/redundant_at_rest_pattern.stderr index 012ba550ca11..3a6f6cf6500a 100644 --- a/tests/ui/redundant_at_rest_pattern.stderr +++ b/tests/ui/redundant_at_rest_pattern.stderr @@ -8,31 +8,31 @@ LL | if let [a @ ..] = [()] {} = help: to override `-D warnings` add `#[allow(clippy::redundant_at_rest_pattern)]` error: using a rest pattern to bind an entire slice to a local - --> tests/ui/redundant_at_rest_pattern.rs:10:12 + --> tests/ui/redundant_at_rest_pattern.rs:11:12 | LL | if let [ref a @ ..] = [()] {} | ^^^^^^^^^^^^ help: this is better represented with just the binding: `ref a` error: using a rest pattern to bind an entire slice to a local - --> tests/ui/redundant_at_rest_pattern.rs:11:12 + --> tests/ui/redundant_at_rest_pattern.rs:13:12 | LL | if let [mut a @ ..] = [()] {} | ^^^^^^^^^^^^ help: this is better represented with just the binding: `mut a` error: using a rest pattern to bind an entire slice to a local - --> tests/ui/redundant_at_rest_pattern.rs:12:12 + --> tests/ui/redundant_at_rest_pattern.rs:15:12 | LL | if let [ref mut a @ ..] = [()] {} | ^^^^^^^^^^^^^^^^ help: this is better represented with just the binding: `ref mut a` error: using a rest pattern to bind an entire slice to a local - --> tests/ui/redundant_at_rest_pattern.rs:14:12 + --> tests/ui/redundant_at_rest_pattern.rs:18:12 | LL | if let [a @ ..] = &*v {} | ^^^^^^^^ help: this is better represented with just the binding: `a` error: using a rest pattern to bind an entire slice to a local - --> tests/ui/redundant_at_rest_pattern.rs:16:12 + --> tests/ui/redundant_at_rest_pattern.rs:21:12 | LL | if let [a @ ..] = s {} | ^^^^^^^^ help: this is better represented with just the binding: `a` diff --git a/tests/ui/redundant_clone.fixed b/tests/ui/redundant_clone.fixed index 1d04cca9b9ed..e0657246bd00 100644 --- a/tests/ui/redundant_clone.fixed +++ b/tests/ui/redundant_clone.fixed @@ -13,23 +13,31 @@ use std::path::Path; fn main() { let _s = ["lorem", "ipsum"].join(" "); + //~^ redundant_clone let s = String::from("foo"); let _s = s; + //~^ redundant_clone let s = String::from("foo"); let _s = s; + //~^ redundant_clone let s = String::from("foo"); let _s = s; + //~^ redundant_clone let _s = Path::new("/a/b/").join("c"); + //~^ redundant_clone let _s = Path::new("/a/b/").join("c"); + //~^ redundant_clone let _s = OsString::new(); + //~^ redundant_clone let _s = OsString::new(); + //~^ redundant_clone // Check that lint level works #[allow(clippy::redundant_clone)] @@ -41,6 +49,7 @@ fn main() { let tup = (String::from("foo"),); let _t = tup.0; + //~^ redundant_clone let tup_ref = &(String::from("foo"),); let _s = tup_ref.0.clone(); // this `.clone()` cannot be removed @@ -73,6 +82,7 @@ fn main() { struct Alpha; fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) { if b { (a.clone(), a) } else { (Alpha, a) } + //~^ redundant_clone } fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) { @@ -130,7 +140,9 @@ fn borrower_propagation() { } let _s = s; + //~^ redundant_clone let _t = t; + //~^ redundant_clone #[derive(Clone)] struct Foo { @@ -141,6 +153,7 @@ fn borrower_propagation() { let f = Foo { x: 123 }; let _x = Some(f.x); let _f = f; + //~^ redundant_clone } { @@ -153,6 +166,7 @@ fn borrower_propagation() { fn not_consumed() { let x = std::path::PathBuf::from("home"); let y = x.join("matthias"); + //~^ redundant_clone // join() creates a new owned PathBuf, does not take a &mut to x variable, thus the .clone() is // redundant. (It also does not consume the PathBuf) @@ -207,6 +221,7 @@ fn clone_then_move_cloned() { let x = Alpha; // ok, data is moved while the clone is in use. foo(&x, move || { + //~^ redundant_clone let _ = x; }); diff --git a/tests/ui/redundant_clone.rs b/tests/ui/redundant_clone.rs index 738744fec98f..53e60a44d7df 100644 --- a/tests/ui/redundant_clone.rs +++ b/tests/ui/redundant_clone.rs @@ -13,23 +13,31 @@ use std::path::Path; fn main() { let _s = ["lorem", "ipsum"].join(" ").to_string(); + //~^ redundant_clone let s = String::from("foo"); let _s = s.clone(); + //~^ redundant_clone let s = String::from("foo"); let _s = s.to_string(); + //~^ redundant_clone let s = String::from("foo"); let _s = s.to_owned(); + //~^ redundant_clone let _s = Path::new("/a/b/").join("c").to_owned(); + //~^ redundant_clone let _s = Path::new("/a/b/").join("c").to_path_buf(); + //~^ redundant_clone let _s = OsString::new().to_owned(); + //~^ redundant_clone let _s = OsString::new().to_os_string(); + //~^ redundant_clone // Check that lint level works #[allow(clippy::redundant_clone)] @@ -41,6 +49,7 @@ fn main() { let tup = (String::from("foo"),); let _t = tup.0.clone(); + //~^ redundant_clone let tup_ref = &(String::from("foo"),); let _s = tup_ref.0.clone(); // this `.clone()` cannot be removed @@ -73,6 +82,7 @@ fn main() { struct Alpha; fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) { if b { (a.clone(), a.clone()) } else { (Alpha, a) } + //~^ redundant_clone } fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) { @@ -130,7 +140,9 @@ fn borrower_propagation() { } let _s = s.clone(); + //~^ redundant_clone let _t = t.clone(); + //~^ redundant_clone #[derive(Clone)] struct Foo { @@ -141,6 +153,7 @@ fn borrower_propagation() { let f = Foo { x: 123 }; let _x = Some(f.x); let _f = f.clone(); + //~^ redundant_clone } { @@ -153,6 +166,7 @@ fn borrower_propagation() { fn not_consumed() { let x = std::path::PathBuf::from("home"); let y = x.clone().join("matthias"); + //~^ redundant_clone // join() creates a new owned PathBuf, does not take a &mut to x variable, thus the .clone() is // redundant. (It also does not consume the PathBuf) @@ -207,6 +221,7 @@ fn clone_then_move_cloned() { let x = Alpha; // ok, data is moved while the clone is in use. foo(&x.clone(), move || { + //~^ redundant_clone let _ = x; }); diff --git a/tests/ui/redundant_clone.stderr b/tests/ui/redundant_clone.stderr index 3c37288f5507..5be081f0f2f8 100644 --- a/tests/ui/redundant_clone.stderr +++ b/tests/ui/redundant_clone.stderr @@ -13,169 +13,169 @@ LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]` error: redundant clone - --> tests/ui/redundant_clone.rs:18:15 + --> tests/ui/redundant_clone.rs:19:15 | LL | let _s = s.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:18:14 + --> tests/ui/redundant_clone.rs:19:14 | LL | let _s = s.clone(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:21:15 + --> tests/ui/redundant_clone.rs:23:15 | LL | let _s = s.to_string(); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:21:14 + --> tests/ui/redundant_clone.rs:23:14 | LL | let _s = s.to_string(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:24:15 + --> tests/ui/redundant_clone.rs:27:15 | LL | let _s = s.to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:24:14 + --> tests/ui/redundant_clone.rs:27:14 | LL | let _s = s.to_owned(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:26:42 + --> tests/ui/redundant_clone.rs:30:42 | LL | let _s = Path::new("/a/b/").join("c").to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:26:14 + --> tests/ui/redundant_clone.rs:30:14 | LL | let _s = Path::new("/a/b/").join("c").to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:28:42 + --> tests/ui/redundant_clone.rs:33:42 | LL | let _s = Path::new("/a/b/").join("c").to_path_buf(); | ^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:28:14 + --> tests/ui/redundant_clone.rs:33:14 | LL | let _s = Path::new("/a/b/").join("c").to_path_buf(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:30:29 + --> tests/ui/redundant_clone.rs:36:29 | LL | let _s = OsString::new().to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:30:14 + --> tests/ui/redundant_clone.rs:36:14 | LL | let _s = OsString::new().to_owned(); | ^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:32:29 + --> tests/ui/redundant_clone.rs:39:29 | LL | let _s = OsString::new().to_os_string(); | ^^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:32:14 + --> tests/ui/redundant_clone.rs:39:14 | LL | let _s = OsString::new().to_os_string(); | ^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:43:19 + --> tests/ui/redundant_clone.rs:51:19 | LL | let _t = tup.0.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:43:14 + --> tests/ui/redundant_clone.rs:51:14 | LL | let _t = tup.0.clone(); | ^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:75:25 + --> tests/ui/redundant_clone.rs:84:25 | LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) } | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:75:24 + --> tests/ui/redundant_clone.rs:84:24 | LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) } | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:132:15 + --> tests/ui/redundant_clone.rs:142:15 | LL | let _s = s.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:132:14 + --> tests/ui/redundant_clone.rs:142:14 | LL | let _s = s.clone(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:133:15 + --> tests/ui/redundant_clone.rs:144:15 | LL | let _t = t.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:133:14 + --> tests/ui/redundant_clone.rs:144:14 | LL | let _t = t.clone(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:143:19 + --> tests/ui/redundant_clone.rs:155:19 | LL | let _f = f.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:143:18 + --> tests/ui/redundant_clone.rs:155:18 | LL | let _f = f.clone(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:155:14 + --> tests/ui/redundant_clone.rs:168:14 | LL | let y = x.clone().join("matthias"); | ^^^^^^^^ help: remove this | note: cloned value is neither consumed nor mutated - --> tests/ui/redundant_clone.rs:155:13 + --> tests/ui/redundant_clone.rs:168:13 | LL | let y = x.clone().join("matthias"); | ^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:209:11 + --> tests/ui/redundant_clone.rs:223:11 | LL | foo(&x.clone(), move || { | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:209:10 + --> tests/ui/redundant_clone.rs:223:10 | LL | foo(&x.clone(), move || { | ^ diff --git a/tests/ui/redundant_closure_call_early.rs b/tests/ui/redundant_closure_call_early.rs index 6f9c9fd52224..2f4feeed9ae6 100644 --- a/tests/ui/redundant_closure_call_early.rs +++ b/tests/ui/redundant_closure_call_early.rs @@ -7,12 +7,14 @@ fn main() { // lint here let mut k = (|m| m + 1)(i); - //~^ ERROR: try not to call a closure in the expression where it is declared - //~| NOTE: `-D clippy::redundant-closure-call` implied by `-D warnings` + //~^ redundant_closure_call + + // lint here k = (|a, b| a * b)(1, 5); - //~^ ERROR: try not to call a closure in the expression where it is declared + //~^ redundant_closure_call + // don't lint these #[allow(clippy::needless_return)] diff --git a/tests/ui/redundant_closure_call_early.stderr b/tests/ui/redundant_closure_call_early.stderr index 038144a5d613..4cfde9a64b57 100644 --- a/tests/ui/redundant_closure_call_early.stderr +++ b/tests/ui/redundant_closure_call_early.stderr @@ -8,7 +8,7 @@ LL | let mut k = (|m| m + 1)(i); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_early.rs:14:9 + --> tests/ui/redundant_closure_call_early.rs:15:9 | LL | k = (|a, b| a * b)(1, 5); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_closure_call_fixable.fixed b/tests/ui/redundant_closure_call_fixable.fixed index 9138a8bacfe1..528a2000693e 100644 --- a/tests/ui/redundant_closure_call_fixable.fixed +++ b/tests/ui/redundant_closure_call_fixable.fixed @@ -13,17 +13,21 @@ async fn something_else() -> u32 { fn main() { let a = 42; + //~^ redundant_closure_call let b = async { + //~^ redundant_closure_call let x = something().await; let y = something_else().await; x * y }; let c = { + //~^ redundant_closure_call let x = 21; let y = 2; x * y }; let d = async { something().await }; + //~^ redundant_closure_call macro_rules! m { () => { @@ -33,14 +37,17 @@ fn main() { macro_rules! m2 { () => { m!() + //~^ redundant_closure_call }; } m2!(); + //~^ redundant_closure_call issue9956(); } fn issue9956() { assert_eq!(43, 42); + //~^ redundant_closure_call // ... and some more interesting cases I've found while implementing the fix @@ -50,13 +57,16 @@ fn issue9956() { // immediately calling it inside of a macro dbg!(42); + //~^ redundant_closure_call // immediately calling only one closure, so we can't remove the other ones let a = (|| || 123); + //~^ redundant_closure_call dbg!(a()()); // nested async closures let a = async { 1 }; + //~^ redundant_closure_call let h = async { a.await }; // macro expansion tests @@ -66,8 +76,10 @@ fn issue9956() { }; } let a = 1; + //~^ redundant_closure_call assert_eq!(a, 1); let a = 123; + //~^ redundant_closure_call assert_eq!(a, 123); // chaining calls, but not closures @@ -81,11 +93,14 @@ fn issue9956() { } fn foo(_: i32, _: i32) {} bar()(42, 5); + //~^ redundant_closure_call foo(42, 5); + //~^ redundant_closure_call } async fn issue11357() { async {}.await; + //~^ redundant_closure_call } mod issue11707 { @@ -95,11 +110,13 @@ mod issue11707 { fn demo() { spawn_on(async move {}); + //~^ redundant_closure_call } } fn avoid_double_parens() { std::convert::identity(13_i32 + 36_i32).leading_zeros(); + //~^ redundant_closure_call } fn fp_11274() { diff --git a/tests/ui/redundant_closure_call_fixable.rs b/tests/ui/redundant_closure_call_fixable.rs index ede6fa27778b..c3cbd8d61ada 100644 --- a/tests/ui/redundant_closure_call_fixable.rs +++ b/tests/ui/redundant_closure_call_fixable.rs @@ -13,17 +13,21 @@ async fn something_else() -> u32 { fn main() { let a = (|| 42)(); + //~^ redundant_closure_call let b = (async || { + //~^ redundant_closure_call let x = something().await; let y = something_else().await; x * y })(); let c = (|| { + //~^ redundant_closure_call let x = 21; let y = 2; x * y })(); let d = (async || something().await)(); + //~^ redundant_closure_call macro_rules! m { () => { @@ -33,14 +37,17 @@ fn main() { macro_rules! m2 { () => { (|| m!())() + //~^ redundant_closure_call }; } m2!(); + //~^ redundant_closure_call issue9956(); } fn issue9956() { assert_eq!((|| || 43)()(), 42); + //~^ redundant_closure_call // ... and some more interesting cases I've found while implementing the fix @@ -50,13 +57,16 @@ fn issue9956() { // immediately calling it inside of a macro dbg!((|| 42)()); + //~^ redundant_closure_call // immediately calling only one closure, so we can't remove the other ones let a = (|| || || 123)(); + //~^ redundant_closure_call dbg!(a()()); // nested async closures let a = (|| || || || async || 1)()()()()(); + //~^ redundant_closure_call let h = async { a.await }; // macro expansion tests @@ -66,8 +76,10 @@ fn issue9956() { }; } let a = (|| echo!(|| echo!(|| 1)))()()(); + //~^ redundant_closure_call assert_eq!(a, 1); let a = (|| echo!((|| 123)))()(); + //~^ redundant_closure_call assert_eq!(a, 123); // chaining calls, but not closures @@ -81,11 +93,14 @@ fn issue9956() { } fn foo(_: i32, _: i32) {} bar()((|| || 42)()(), 5); + //~^ redundant_closure_call foo((|| || 42)()(), 5); + //~^ redundant_closure_call } async fn issue11357() { (|| async {})().await; + //~^ redundant_closure_call } mod issue11707 { @@ -95,11 +110,13 @@ mod issue11707 { fn demo() { spawn_on((|| async move {})()); + //~^ redundant_closure_call } } fn avoid_double_parens() { std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros(); + //~^ redundant_closure_call } fn fp_11274() { diff --git a/tests/ui/redundant_closure_call_fixable.stderr b/tests/ui/redundant_closure_call_fixable.stderr index 8e0d37df96b8..2c35aafbe310 100644 --- a/tests/ui/redundant_closure_call_fixable.stderr +++ b/tests/ui/redundant_closure_call_fixable.stderr @@ -8,10 +8,11 @@ LL | let a = (|| 42)(); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:16:13 + --> tests/ui/redundant_closure_call_fixable.rs:17:13 | LL | let b = (async || { | _____________^ +LL | | LL | | let x = something().await; LL | | let y = something_else().await; LL | | x * y @@ -21,6 +22,7 @@ LL | | })(); help: try doing something like | LL ~ let b = async { +LL + LL + let x = something().await; LL + let y = something_else().await; LL + x * y @@ -28,10 +30,11 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:21:13 + --> tests/ui/redundant_closure_call_fixable.rs:23:13 | LL | let c = (|| { | _____________^ +LL | | LL | | let x = 21; LL | | let y = 2; LL | | x * y @@ -41,6 +44,7 @@ LL | | })(); help: try doing something like | LL ~ let c = { +LL + LL + let x = 21; LL + let y = 2; LL + x * y @@ -48,13 +52,13 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:26:13 + --> tests/ui/redundant_closure_call_fixable.rs:29:13 | LL | let d = (async || something().await)(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:35:13 + --> tests/ui/redundant_closure_call_fixable.rs:39:13 | LL | (|| m!())() | ^^^^^^^^^^^ help: try doing something like: `m!()` @@ -65,7 +69,7 @@ LL | m2!(); = note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:30:13 + --> tests/ui/redundant_closure_call_fixable.rs:34:13 | LL | (|| 0)() | ^^^^^^^^ help: try doing something like: `0` @@ -76,67 +80,67 @@ LL | m2!(); = note: this error originates in the macro `m` which comes from the expansion of the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:43:16 + --> tests/ui/redundant_closure_call_fixable.rs:49:16 | LL | assert_eq!((|| || 43)()(), 42); | ^^^^^^^^^^^^^^ help: try doing something like: `43` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:52:10 + --> tests/ui/redundant_closure_call_fixable.rs:59:10 | LL | dbg!((|| 42)()); | ^^^^^^^^^ help: try doing something like: `42` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:55:13 + --> tests/ui/redundant_closure_call_fixable.rs:63:13 | LL | let a = (|| || || 123)(); | ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:59:13 + --> tests/ui/redundant_closure_call_fixable.rs:68:13 | LL | let a = (|| || || || async || 1)()()()()(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { 1 }` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:68:13 + --> tests/ui/redundant_closure_call_fixable.rs:78:13 | LL | let a = (|| echo!(|| echo!(|| 1)))()()(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `1` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:70:13 + --> tests/ui/redundant_closure_call_fixable.rs:81:13 | LL | let a = (|| echo!((|| 123)))()(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `123` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:83:11 + --> tests/ui/redundant_closure_call_fixable.rs:95:11 | LL | bar()((|| || 42)()(), 5); | ^^^^^^^^^^^^^^ help: try doing something like: `42` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:84:9 + --> tests/ui/redundant_closure_call_fixable.rs:97:9 | LL | foo((|| || 42)()(), 5); | ^^^^^^^^^^^^^^ help: try doing something like: `42` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:88:5 + --> tests/ui/redundant_closure_call_fixable.rs:102:5 | LL | (|| async {})().await; | ^^^^^^^^^^^^^^^ help: try doing something like: `async {}` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:97:18 + --> tests/ui/redundant_closure_call_fixable.rs:112:18 | LL | spawn_on((|| async move {})()); | ^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async move {}` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:102:28 + --> tests/ui/redundant_closure_call_fixable.rs:118:28 | LL | std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32` diff --git a/tests/ui/redundant_closure_call_late.rs b/tests/ui/redundant_closure_call_late.rs index dc369c3bc092..c697fedb871e 100644 --- a/tests/ui/redundant_closure_call_late.rs +++ b/tests/ui/redundant_closure_call_late.rs @@ -14,16 +14,19 @@ fn main() { // lint here let redun_closure = || 1; i = redun_closure(); - //~^ ERROR: closure called just once immediately after it was declared - //~| NOTE: `-D clippy::redundant-closure-call` implied by `-D warnings` + //~^ redundant_closure_call + + // shadowed closures are supported, lint here let shadowed_closure = || 1; i = shadowed_closure(); - //~^ ERROR: closure called just once immediately after it was declared + //~^ redundant_closure_call + let shadowed_closure = || 2; i = shadowed_closure(); - //~^ ERROR: closure called just once immediately after it was declared + //~^ redundant_closure_call + // don't lint here let shadowed_closure = || 2; diff --git a/tests/ui/redundant_closure_call_late.stderr b/tests/ui/redundant_closure_call_late.stderr index 023e766a5d2b..abe7ac7b6595 100644 --- a/tests/ui/redundant_closure_call_late.stderr +++ b/tests/ui/redundant_closure_call_late.stderr @@ -8,13 +8,13 @@ LL | i = redun_closure(); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]` error: closure called just once immediately after it was declared - --> tests/ui/redundant_closure_call_late.rs:22:5 + --> tests/ui/redundant_closure_call_late.rs:23:5 | LL | i = shadowed_closure(); | ^^^^^^^^^^^^^^^^^^^^^^ error: closure called just once immediately after it was declared - --> tests/ui/redundant_closure_call_late.rs:25:5 + --> tests/ui/redundant_closure_call_late.rs:27:5 | LL | i = shadowed_closure(); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_else.fixed b/tests/ui/redundant_else.fixed index 47aa79302d2c..4dc325330249 100644 --- a/tests/ui/redundant_else.fixed +++ b/tests/ui/redundant_else.fixed @@ -8,15 +8,17 @@ fn main() { println!("Love your neighbor;"); break; } - //~^ ERROR: redundant else block - println!("yet don't pull down your hedge."); + //~^ redundant_else + + println!("yet don't pull down your hedge."); // continue if foo() { println!("He that lies down with Dogs,"); continue; } - //~^ ERROR: redundant else block - println!("shall rise up with fleas."); + //~^ redundant_else + + println!("shall rise up with fleas."); // match block if foo() { match foo() { @@ -24,8 +26,9 @@ fn main() { _ => return, } } - //~^ ERROR: redundant else block - println!("You may delay, but time will not."); + //~^ redundant_else + + println!("You may delay, but time will not."); } // else if if foo() { @@ -33,15 +36,17 @@ fn main() { } else if foo() { return; } - //~^ ERROR: redundant else block - println!("A fat kitchen makes a lean will."); + //~^ redundant_else + + println!("A fat kitchen makes a lean will."); // let binding outside of block let _ = { if foo() { return; } - //~^ ERROR: redundant else block - 1 + //~^ redundant_else + + 1 }; // else if with let binding outside of block let _ = { @@ -50,8 +55,9 @@ fn main() { } else if foo() { return; } - //~^ ERROR: redundant else block - 2 + //~^ redundant_else + + 2 }; // inside if let let _ = if let Some(1) = foo() { @@ -59,8 +65,9 @@ fn main() { if foo() { return; } - //~^ ERROR: redundant else block - 1 + //~^ redundant_else + + 1 } else { 1 }; diff --git a/tests/ui/redundant_else.rs b/tests/ui/redundant_else.rs index 8bcf2ce5233d..842cb4bc9411 100644 --- a/tests/ui/redundant_else.rs +++ b/tests/ui/redundant_else.rs @@ -8,7 +8,8 @@ fn main() { println!("Love your neighbor;"); break; } else { - //~^ ERROR: redundant else block + //~^ redundant_else + println!("yet don't pull down your hedge."); } // continue @@ -16,7 +17,8 @@ fn main() { println!("He that lies down with Dogs,"); continue; } else { - //~^ ERROR: redundant else block + //~^ redundant_else + println!("shall rise up with fleas."); } // match block @@ -26,7 +28,8 @@ fn main() { _ => return, } } else { - //~^ ERROR: redundant else block + //~^ redundant_else + println!("You may delay, but time will not."); } } @@ -36,7 +39,8 @@ fn main() { } else if foo() { return; } else { - //~^ ERROR: redundant else block + //~^ redundant_else + println!("A fat kitchen makes a lean will."); } // let binding outside of block @@ -44,7 +48,8 @@ fn main() { if foo() { return; } else { - //~^ ERROR: redundant else block + //~^ redundant_else + 1 } }; @@ -55,7 +60,8 @@ fn main() { } else if foo() { return; } else { - //~^ ERROR: redundant else block + //~^ redundant_else + 2 } }; @@ -65,7 +71,8 @@ fn main() { if foo() { return; } else { - //~^ ERROR: redundant else block + //~^ redundant_else + 1 } } else { diff --git a/tests/ui/redundant_else.stderr b/tests/ui/redundant_else.stderr index ecc16f7cda5e..2cb0fd6f127f 100644 --- a/tests/ui/redundant_else.stderr +++ b/tests/ui/redundant_else.stderr @@ -4,6 +4,7 @@ error: redundant else block LL | } else { | __________^ LL | | +LL | | LL | | println!("yet don't pull down your hedge."); LL | | } | |_________^ @@ -14,15 +15,17 @@ help: remove the `else` block and move the contents out | LL ~ } LL + -LL + println!("yet don't pull down your hedge."); +LL + +LL + println!("yet don't pull down your hedge."); | error: redundant else block - --> tests/ui/redundant_else.rs:18:10 + --> tests/ui/redundant_else.rs:19:10 | LL | } else { | __________^ LL | | +LL | | LL | | println!("shall rise up with fleas."); LL | | } | |_________^ @@ -31,15 +34,17 @@ help: remove the `else` block and move the contents out | LL ~ } LL + -LL + println!("shall rise up with fleas."); +LL + +LL + println!("shall rise up with fleas."); | error: redundant else block - --> tests/ui/redundant_else.rs:28:10 + --> tests/ui/redundant_else.rs:30:10 | LL | } else { | __________^ LL | | +LL | | LL | | println!("You may delay, but time will not."); LL | | } | |_________^ @@ -48,15 +53,17 @@ help: remove the `else` block and move the contents out | LL ~ } LL + -LL + println!("You may delay, but time will not."); +LL + +LL + println!("You may delay, but time will not."); | error: redundant else block - --> tests/ui/redundant_else.rs:38:6 + --> tests/ui/redundant_else.rs:41:6 | LL | } else { | ______^ LL | | +LL | | LL | | println!("A fat kitchen makes a lean will."); LL | | } | |_____^ @@ -65,15 +72,17 @@ help: remove the `else` block and move the contents out | LL ~ } LL + -LL + println!("A fat kitchen makes a lean will."); +LL + +LL + println!("A fat kitchen makes a lean will."); | error: redundant else block - --> tests/ui/redundant_else.rs:46:10 + --> tests/ui/redundant_else.rs:50:10 | LL | } else { | __________^ LL | | +LL | | LL | | 1 LL | | } | |_________^ @@ -82,15 +91,17 @@ help: remove the `else` block and move the contents out | LL ~ } LL + -LL + 1 +LL + +LL + 1 | error: redundant else block - --> tests/ui/redundant_else.rs:57:10 + --> tests/ui/redundant_else.rs:62:10 | LL | } else { | __________^ LL | | +LL | | LL | | 2 LL | | } | |_________^ @@ -99,15 +110,17 @@ help: remove the `else` block and move the contents out | LL ~ } LL + -LL + 2 +LL + +LL + 2 | error: redundant else block - --> tests/ui/redundant_else.rs:67:10 + --> tests/ui/redundant_else.rs:73:10 | LL | } else { | __________^ LL | | +LL | | LL | | 1 LL | | } | |_________^ @@ -116,7 +129,8 @@ help: remove the `else` block and move the contents out | LL ~ } LL + -LL + 1 +LL + +LL + 1 | error: aborting due to 7 previous errors diff --git a/tests/ui/redundant_field_names.fixed b/tests/ui/redundant_field_names.fixed index 72fc4cb7333e..142828a2b2d8 100644 --- a/tests/ui/redundant_field_names.fixed +++ b/tests/ui/redundant_field_names.fixed @@ -31,7 +31,9 @@ fn main() { let me = Person { gender, + //~^ redundant_field_names age, + //~^ redundant_field_names name, //should be ok buzz: fizz, //should be ok @@ -53,10 +55,15 @@ fn main() { // hand-written Range family structs are linted let _ = RangeFrom { start }; + //~^ redundant_field_names let _ = RangeTo { end }; + //~^ redundant_field_names let _ = Range { start, end }; + //~^ redundant_field_names + //~| redundant_field_names let _ = RangeInclusive::new(start, end); let _ = RangeToInclusive { end }; + //~^ redundant_field_names external! { let v = 1; @@ -69,6 +76,7 @@ fn main() { macro_rules! internal { ($i:ident) => { let _ = S { v }; + //~^ redundant_field_names let _ = S { $i: v }; let _ = S { v: $i }; let _ = S { $i: $i }; @@ -97,4 +105,5 @@ fn msrv_1_16() { fn msrv_1_17() { let start = 0; let _ = RangeFrom { start }; + //~^ redundant_field_names } diff --git a/tests/ui/redundant_field_names.rs b/tests/ui/redundant_field_names.rs index 2617d7e72837..15fef11a0408 100644 --- a/tests/ui/redundant_field_names.rs +++ b/tests/ui/redundant_field_names.rs @@ -31,7 +31,9 @@ fn main() { let me = Person { gender: gender, + //~^ redundant_field_names age: age, + //~^ redundant_field_names name, //should be ok buzz: fizz, //should be ok @@ -53,10 +55,15 @@ fn main() { // hand-written Range family structs are linted let _ = RangeFrom { start: start }; + //~^ redundant_field_names let _ = RangeTo { end: end }; + //~^ redundant_field_names let _ = Range { start: start, end: end }; + //~^ redundant_field_names + //~| redundant_field_names let _ = RangeInclusive::new(start, end); let _ = RangeToInclusive { end: end }; + //~^ redundant_field_names external! { let v = 1; @@ -69,6 +76,7 @@ fn main() { macro_rules! internal { ($i:ident) => { let _ = S { v: v }; + //~^ redundant_field_names let _ = S { $i: v }; let _ = S { v: $i }; let _ = S { $i: $i }; @@ -97,4 +105,5 @@ fn msrv_1_16() { fn msrv_1_17() { let start = 0; let _ = RangeFrom { start: start }; + //~^ redundant_field_names } diff --git a/tests/ui/redundant_field_names.stderr b/tests/ui/redundant_field_names.stderr index 38c021fdba37..78b8a4f1118e 100644 --- a/tests/ui/redundant_field_names.stderr +++ b/tests/ui/redundant_field_names.stderr @@ -8,43 +8,43 @@ LL | gender: gender, = help: to override `-D warnings` add `#[allow(clippy::redundant_field_names)]` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:34:9 + --> tests/ui/redundant_field_names.rs:35:9 | LL | age: age, | ^^^^^^^^ help: replace it with: `age` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:55:25 + --> tests/ui/redundant_field_names.rs:57:25 | LL | let _ = RangeFrom { start: start }; | ^^^^^^^^^^^^ help: replace it with: `start` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:56:23 + --> tests/ui/redundant_field_names.rs:59:23 | LL | let _ = RangeTo { end: end }; | ^^^^^^^^ help: replace it with: `end` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:57:21 + --> tests/ui/redundant_field_names.rs:61:21 | LL | let _ = Range { start: start, end: end }; | ^^^^^^^^^^^^ help: replace it with: `start` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:57:35 + --> tests/ui/redundant_field_names.rs:61:35 | LL | let _ = Range { start: start, end: end }; | ^^^^^^^^ help: replace it with: `end` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:59:32 + --> tests/ui/redundant_field_names.rs:65:32 | LL | let _ = RangeToInclusive { end: end }; | ^^^^^^^^ help: replace it with: `end` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:71:25 + --> tests/ui/redundant_field_names.rs:78:25 | LL | let _ = S { v: v }; | ^^^^ help: replace it with: `v` @@ -55,7 +55,7 @@ LL | internal!(v); = note: this error originates in the macro `internal` (in Nightly builds, run with -Z macro-backtrace for more info) error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:99:25 + --> tests/ui/redundant_field_names.rs:107:25 | LL | let _ = RangeFrom { start: start }; | ^^^^^^^^^^^^ help: replace it with: `start` diff --git a/tests/ui/redundant_guards.fixed b/tests/ui/redundant_guards.fixed index ff7b233f004e..c7e6f44ad83e 100644 --- a/tests/ui/redundant_guards.fixed +++ b/tests/ui/redundant_guards.fixed @@ -20,12 +20,14 @@ struct FloatWrapper(f32); fn issue11304() { match 0.1 { 0.0 => todo!(), + //~^ redundant_guards // Pattern matching NAN is illegal x if x == f64::NAN => todo!(), _ => todo!(), } match FloatWrapper(0.1) { FloatWrapper(0.0) => todo!(), + //~^ redundant_guards _ => todo!(), } } @@ -41,19 +43,25 @@ fn main() { let c = C(1, 2); match c { C(x, 1) => .., + //~^ redundant_guards _ => todo!(), }; let x = Some(Some(1)); match x { Some(Some(1)) if true => .., + //~^ redundant_guards Some(Some(1)) => { + //~^ redundant_guards println!("a"); .. }, Some(Some(1)) => .., + //~^ redundant_guards Some(Some(2)) => .., + //~^ redundant_guards Some(Some(2)) => .., + //~^ redundant_guards // Don't lint, since x is used in the body Some(x) if let Some(1) = x => { x; @@ -79,6 +87,7 @@ fn main() { let b = B { e: Some(A(0)) }; match b { B { e: Some(A(2)) } => .., + //~^ redundant_guards _ => todo!(), }; // Do not lint, since we cannot represent this as a pattern (at least, without a conversion) @@ -116,6 +125,7 @@ fn i() { // Do not lint E::A(x) | E::B(x) | E::C(x) if x == "from an or pattern" => {}, E::A("not from an or pattern") => {}, + //~^ redundant_guards _ => {}, }; } @@ -123,6 +133,7 @@ fn i() { fn h(v: Option) { match v { Some(0) => .., + //~^ redundant_guards _ => .., }; } @@ -130,7 +141,9 @@ fn h(v: Option) { fn negative_literal(i: i32) { match i { -1 => {}, + //~^ redundant_guards 1 => {}, + //~^ redundant_guards _ => {}, } } @@ -193,9 +206,13 @@ mod issue11465 { let c = Some(1); match c { Some(1) => {}, + //~^ redundant_guards Some(1) => {}, + //~^ redundant_guards Some(2) => {}, + //~^ redundant_guards Some(3) => {}, + //~^ redundant_guards _ => {}, }; @@ -216,9 +233,13 @@ mod issue11465 { B { ref b, .. } if b == "bar" => {}, B { ref b, .. } if "bar" == b => {}, B { c: 1, .. } => {}, + //~^ redundant_guards B { c: 1, .. } => {}, + //~^ redundant_guards B { c: 1, .. } => {}, + //~^ redundant_guards B { c: 1, .. } => {}, + //~^ redundant_guards _ => {}, } } @@ -229,6 +250,7 @@ fn issue11807() { match Some(Some("")) { Some(Some("")) => {}, + //~^ redundant_guards _ => {}, } @@ -240,11 +262,13 @@ fn issue11807() { match Some(Some(&[] as &[i32])) { Some(Some([])) => {}, + //~^ redundant_guards _ => {}, } match Some(Some([] as [i32; 0])) { Some(Some([])) => {}, + //~^ redundant_guards _ => {}, } @@ -256,21 +280,25 @@ fn issue11807() { match Some(Some(&[] as &[i32])) { Some(Some([..])) => {}, + //~^ redundant_guards _ => {}, } match Some(Some(&[] as &[i32])) { Some(Some([1, ..])) => {}, + //~^ redundant_guards _ => {}, } match Some(Some(&[] as &[i32])) { Some(Some([1, 2, ..])) => {}, + //~^ redundant_guards _ => {}, } match Some(Some(&[] as &[i32])) { Some(Some([.., 1, 2])) => {}, + //~^ redundant_guards _ => {}, } diff --git a/tests/ui/redundant_guards.rs b/tests/ui/redundant_guards.rs index b4d4ef5b170d..d3c55c18884d 100644 --- a/tests/ui/redundant_guards.rs +++ b/tests/ui/redundant_guards.rs @@ -20,12 +20,14 @@ struct FloatWrapper(f32); fn issue11304() { match 0.1 { x if x == 0.0 => todo!(), + //~^ redundant_guards // Pattern matching NAN is illegal x if x == f64::NAN => todo!(), _ => todo!(), } match FloatWrapper(0.1) { x if x == FloatWrapper(0.0) => todo!(), + //~^ redundant_guards _ => todo!(), } } @@ -41,19 +43,25 @@ fn main() { let c = C(1, 2); match c { C(x, y) if let 1 = y => .., + //~^ redundant_guards _ => todo!(), }; let x = Some(Some(1)); match x { Some(x) if matches!(x, Some(1) if true) => .., + //~^ redundant_guards Some(x) if matches!(x, Some(1)) => { + //~^ redundant_guards println!("a"); .. }, Some(x) if let Some(1) = x => .., + //~^ redundant_guards Some(x) if x == Some(2) => .., + //~^ redundant_guards Some(x) if Some(2) == x => .., + //~^ redundant_guards // Don't lint, since x is used in the body Some(x) if let Some(1) = x => { x; @@ -79,6 +87,7 @@ fn main() { let b = B { e: Some(A(0)) }; match b { B { e } if matches!(e, Some(A(2))) => .., + //~^ redundant_guards _ => todo!(), }; // Do not lint, since we cannot represent this as a pattern (at least, without a conversion) @@ -116,6 +125,7 @@ fn i() { // Do not lint E::A(x) | E::B(x) | E::C(x) if x == "from an or pattern" => {}, E::A(y) if y == "not from an or pattern" => {}, + //~^ redundant_guards _ => {}, }; } @@ -123,6 +133,7 @@ fn i() { fn h(v: Option) { match v { x if matches!(x, Some(0)) => .., + //~^ redundant_guards _ => .., }; } @@ -130,7 +141,9 @@ fn h(v: Option) { fn negative_literal(i: i32) { match i { i if i == -1 => {}, + //~^ redundant_guards i if i == 1 => {}, + //~^ redundant_guards _ => {}, } } @@ -193,9 +206,13 @@ mod issue11465 { let c = Some(1); match c { Some(ref x) if x == &1 => {}, + //~^ redundant_guards Some(ref x) if &1 == x => {}, + //~^ redundant_guards Some(ref x) if let &2 = x => {}, + //~^ redundant_guards Some(ref x) if matches!(x, &3) => {}, + //~^ redundant_guards _ => {}, }; @@ -216,9 +233,13 @@ mod issue11465 { B { ref b, .. } if b == "bar" => {}, B { ref b, .. } if "bar" == b => {}, B { ref c, .. } if c == &1 => {}, + //~^ redundant_guards B { ref c, .. } if &1 == c => {}, + //~^ redundant_guards B { ref c, .. } if let &1 = c => {}, + //~^ redundant_guards B { ref c, .. } if matches!(c, &1) => {}, + //~^ redundant_guards _ => {}, } } @@ -229,6 +250,7 @@ fn issue11807() { match Some(Some("")) { Some(Some(x)) if x.is_empty() => {}, + //~^ redundant_guards _ => {}, } @@ -240,11 +262,13 @@ fn issue11807() { match Some(Some(&[] as &[i32])) { Some(Some(x)) if x.is_empty() => {}, + //~^ redundant_guards _ => {}, } match Some(Some([] as [i32; 0])) { Some(Some(x)) if x.is_empty() => {}, + //~^ redundant_guards _ => {}, } @@ -256,21 +280,25 @@ fn issue11807() { match Some(Some(&[] as &[i32])) { Some(Some(x)) if x.starts_with(&[]) => {}, + //~^ redundant_guards _ => {}, } match Some(Some(&[] as &[i32])) { Some(Some(x)) if x.starts_with(&[1]) => {}, + //~^ redundant_guards _ => {}, } match Some(Some(&[] as &[i32])) { Some(Some(x)) if x.starts_with(&[1, 2]) => {}, + //~^ redundant_guards _ => {}, } match Some(Some(&[] as &[i32])) { Some(Some(x)) if x.ends_with(&[1, 2]) => {}, + //~^ redundant_guards _ => {}, } diff --git a/tests/ui/redundant_guards.stderr b/tests/ui/redundant_guards.stderr index 7512546450b2..2a3d8901066d 100644 --- a/tests/ui/redundant_guards.stderr +++ b/tests/ui/redundant_guards.stderr @@ -13,7 +13,7 @@ LL + 0.0 => todo!(), | error: redundant guard - --> tests/ui/redundant_guards.rs:28:14 + --> tests/ui/redundant_guards.rs:29:14 | LL | x if x == FloatWrapper(0.0) => todo!(), | ^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + FloatWrapper(0.0) => todo!(), | error: redundant guard - --> tests/ui/redundant_guards.rs:43:20 + --> tests/ui/redundant_guards.rs:45:20 | LL | C(x, y) if let 1 = y => .., | ^^^^^^^^^ @@ -37,7 +37,7 @@ LL + C(x, 1) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:49:20 + --> tests/ui/redundant_guards.rs:52:20 | LL | Some(x) if matches!(x, Some(1) if true) => .., | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | Some(Some(1)) if true => .., | ~~~~~~~ ~~~~~~~ error: redundant guard - --> tests/ui/redundant_guards.rs:50:20 + --> tests/ui/redundant_guards.rs:54:20 | LL | Some(x) if matches!(x, Some(1)) => { | ^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL + Some(Some(1)) => { | error: redundant guard - --> tests/ui/redundant_guards.rs:54:20 + --> tests/ui/redundant_guards.rs:59:20 | LL | Some(x) if let Some(1) = x => .., | ^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL + Some(Some(1)) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:55:20 + --> tests/ui/redundant_guards.rs:61:20 | LL | Some(x) if x == Some(2) => .., | ^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL + Some(Some(2)) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:56:20 + --> tests/ui/redundant_guards.rs:63:20 | LL | Some(x) if Some(2) == x => .., | ^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL + Some(Some(2)) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:81:20 + --> tests/ui/redundant_guards.rs:89:20 | LL | B { e } if matches!(e, Some(A(2))) => .., | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL + B { e: Some(A(2)) } => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:118:20 + --> tests/ui/redundant_guards.rs:127:20 | LL | E::A(y) if y == "not from an or pattern" => {}, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL + E::A("not from an or pattern") => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:125:14 + --> tests/ui/redundant_guards.rs:135:14 | LL | x if matches!(x, Some(0)) => .., | ^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL + Some(0) => .., | error: redundant guard - --> tests/ui/redundant_guards.rs:132:14 + --> tests/ui/redundant_guards.rs:143:14 | LL | i if i == -1 => {}, | ^^^^^^^ @@ -144,7 +144,7 @@ LL + -1 => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:133:14 + --> tests/ui/redundant_guards.rs:145:14 | LL | i if i == 1 => {}, | ^^^^^^ @@ -156,7 +156,7 @@ LL + 1 => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:195:28 + --> tests/ui/redundant_guards.rs:208:28 | LL | Some(ref x) if x == &1 => {}, | ^^^^^^^ @@ -168,7 +168,7 @@ LL + Some(1) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:196:28 + --> tests/ui/redundant_guards.rs:210:28 | LL | Some(ref x) if &1 == x => {}, | ^^^^^^^ @@ -180,7 +180,7 @@ LL + Some(1) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:197:28 + --> tests/ui/redundant_guards.rs:212:28 | LL | Some(ref x) if let &2 = x => {}, | ^^^^^^^^^^ @@ -192,7 +192,7 @@ LL + Some(2) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:198:28 + --> tests/ui/redundant_guards.rs:214:28 | LL | Some(ref x) if matches!(x, &3) => {}, | ^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL + Some(3) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:218:32 + --> tests/ui/redundant_guards.rs:235:32 | LL | B { ref c, .. } if c == &1 => {}, | ^^^^^^^ @@ -216,7 +216,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:219:32 + --> tests/ui/redundant_guards.rs:237:32 | LL | B { ref c, .. } if &1 == c => {}, | ^^^^^^^ @@ -228,7 +228,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:220:32 + --> tests/ui/redundant_guards.rs:239:32 | LL | B { ref c, .. } if let &1 = c => {}, | ^^^^^^^^^^ @@ -240,7 +240,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:221:32 + --> tests/ui/redundant_guards.rs:241:32 | LL | B { ref c, .. } if matches!(c, &1) => {}, | ^^^^^^^^^^^^^^^ @@ -252,7 +252,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:231:26 + --> tests/ui/redundant_guards.rs:252:26 | LL | Some(Some(x)) if x.is_empty() => {}, | ^^^^^^^^^^^^ @@ -264,7 +264,7 @@ LL + Some(Some("")) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:242:26 + --> tests/ui/redundant_guards.rs:264:26 | LL | Some(Some(x)) if x.is_empty() => {}, | ^^^^^^^^^^^^ @@ -276,7 +276,7 @@ LL + Some(Some([])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:247:26 + --> tests/ui/redundant_guards.rs:270:26 | LL | Some(Some(x)) if x.is_empty() => {}, | ^^^^^^^^^^^^ @@ -288,7 +288,7 @@ LL + Some(Some([])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:258:26 + --> tests/ui/redundant_guards.rs:282:26 | LL | Some(Some(x)) if x.starts_with(&[]) => {}, | ^^^^^^^^^^^^^^^^^^ @@ -300,7 +300,7 @@ LL + Some(Some([..])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:263:26 + --> tests/ui/redundant_guards.rs:288:26 | LL | Some(Some(x)) if x.starts_with(&[1]) => {}, | ^^^^^^^^^^^^^^^^^^^ @@ -312,7 +312,7 @@ LL + Some(Some([1, ..])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:268:26 + --> tests/ui/redundant_guards.rs:294:26 | LL | Some(Some(x)) if x.starts_with(&[1, 2]) => {}, | ^^^^^^^^^^^^^^^^^^^^^^ @@ -324,7 +324,7 @@ LL + Some(Some([1, 2, ..])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:273:26 + --> tests/ui/redundant_guards.rs:300:26 | LL | Some(Some(x)) if x.ends_with(&[1, 2]) => {}, | ^^^^^^^^^^^^^^^^^^^^ @@ -336,7 +336,7 @@ LL + Some(Some([.., 1, 2])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:295:18 + --> tests/ui/redundant_guards.rs:323:18 | LL | y if y.is_empty() => {}, | ^^^^^^^^^^^^ @@ -348,7 +348,7 @@ LL + "" => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:314:22 + --> tests/ui/redundant_guards.rs:342:22 | LL | y if y.is_empty() => {}, | ^^^^^^^^^^^^ diff --git a/tests/ui/redundant_locals.rs b/tests/ui/redundant_locals.rs index 3e7695106a7f..b66532dd22ee 100644 --- a/tests/ui/redundant_locals.rs +++ b/tests/ui/redundant_locals.rs @@ -11,11 +11,13 @@ fn main() {} fn immutable() { let x = 1; let x = x; + //~^ redundant_locals } fn mutable() { let mut x = 1; let mut x = x; + //~^ redundant_locals } fn upgraded_mutability() { @@ -46,27 +48,35 @@ fn coercion(par: &mut i32) { fn parameter(x: i32) { let x = x; + //~^ redundant_locals } fn many() { let x = 1; let x = x; + //~^ redundant_locals let x = x; + //~^ redundant_locals let x = x; + //~^ redundant_locals let x = x; + //~^ redundant_locals } fn interleaved() { let a = 1; let b = 2; let a = a; + //~^ redundant_locals let b = b; + //~^ redundant_locals } fn block() { { let x = 1; let x = x; + //~^ redundant_locals } } @@ -74,9 +84,11 @@ fn closure() { || { let x = 1; let x = x; + //~^ redundant_locals }; |x: i32| { let x = x; + //~^ redundant_locals }; } @@ -96,6 +108,7 @@ fn inconsequential_drop_order() { { let x = x; + //~^ redundant_locals } } @@ -151,6 +164,7 @@ fn without_drop() { let a = WithoutDrop(1); let b = WithoutDrop(2); let a = a; + //~^ redundant_locals } fn drop_inner() { diff --git a/tests/ui/redundant_locals.stderr b/tests/ui/redundant_locals.stderr index 541b988eefe9..ae3631cdf15f 100644 --- a/tests/ui/redundant_locals.stderr +++ b/tests/ui/redundant_locals.stderr @@ -13,65 +13,29 @@ LL | let x = 1; = help: to override `-D warnings` add `#[allow(clippy::redundant_locals)]` error: redundant redefinition of a binding `x` - --> tests/ui/redundant_locals.rs:18:5 + --> tests/ui/redundant_locals.rs:19:5 | LL | let mut x = x; | ^^^^^^^^^^^^^^ | help: `x` is initially defined here - --> tests/ui/redundant_locals.rs:17:9 + --> tests/ui/redundant_locals.rs:18:9 | LL | let mut x = 1; | ^^^^^ error: redundant redefinition of a binding `x` - --> tests/ui/redundant_locals.rs:48:5 + --> tests/ui/redundant_locals.rs:50:5 | LL | let x = x; | ^^^^^^^^^^ | help: `x` is initially defined here - --> tests/ui/redundant_locals.rs:47:14 + --> tests/ui/redundant_locals.rs:49:14 | LL | fn parameter(x: i32) { | ^ -error: redundant redefinition of a binding `x` - --> tests/ui/redundant_locals.rs:53:5 - | -LL | let x = x; - | ^^^^^^^^^^ - | -help: `x` is initially defined here - --> tests/ui/redundant_locals.rs:52:9 - | -LL | let x = 1; - | ^ - -error: redundant redefinition of a binding `x` - --> tests/ui/redundant_locals.rs:54:5 - | -LL | let x = x; - | ^^^^^^^^^^ - | -help: `x` is initially defined here - --> tests/ui/redundant_locals.rs:53:9 - | -LL | let x = x; - | ^ - -error: redundant redefinition of a binding `x` - --> tests/ui/redundant_locals.rs:55:5 - | -LL | let x = x; - | ^^^^^^^^^^ - | -help: `x` is initially defined here - --> tests/ui/redundant_locals.rs:54:9 - | -LL | let x = x; - | ^ - error: redundant redefinition of a binding `x` --> tests/ui/redundant_locals.rs:56:5 | @@ -81,89 +45,125 @@ LL | let x = x; help: `x` is initially defined here --> tests/ui/redundant_locals.rs:55:9 | +LL | let x = 1; + | ^ + +error: redundant redefinition of a binding `x` + --> tests/ui/redundant_locals.rs:58:5 + | +LL | let x = x; + | ^^^^^^^^^^ + | +help: `x` is initially defined here + --> tests/ui/redundant_locals.rs:56:9 + | +LL | let x = x; + | ^ + +error: redundant redefinition of a binding `x` + --> tests/ui/redundant_locals.rs:60:5 + | +LL | let x = x; + | ^^^^^^^^^^ + | +help: `x` is initially defined here + --> tests/ui/redundant_locals.rs:58:9 + | +LL | let x = x; + | ^ + +error: redundant redefinition of a binding `x` + --> tests/ui/redundant_locals.rs:62:5 + | +LL | let x = x; + | ^^^^^^^^^^ + | +help: `x` is initially defined here + --> tests/ui/redundant_locals.rs:60:9 + | LL | let x = x; | ^ error: redundant redefinition of a binding `a` - --> tests/ui/redundant_locals.rs:62:5 + --> tests/ui/redundant_locals.rs:69:5 | LL | let a = a; | ^^^^^^^^^^ | help: `a` is initially defined here - --> tests/ui/redundant_locals.rs:60:9 + --> tests/ui/redundant_locals.rs:67:9 | LL | let a = 1; | ^ error: redundant redefinition of a binding `b` - --> tests/ui/redundant_locals.rs:63:5 + --> tests/ui/redundant_locals.rs:71:5 | LL | let b = b; | ^^^^^^^^^^ | help: `b` is initially defined here - --> tests/ui/redundant_locals.rs:61:9 + --> tests/ui/redundant_locals.rs:68:9 | LL | let b = 2; | ^ error: redundant redefinition of a binding `x` - --> tests/ui/redundant_locals.rs:69:9 + --> tests/ui/redundant_locals.rs:78:9 | LL | let x = x; | ^^^^^^^^^^ | help: `x` is initially defined here - --> tests/ui/redundant_locals.rs:68:13 + --> tests/ui/redundant_locals.rs:77:13 | LL | let x = 1; | ^ error: redundant redefinition of a binding `x` - --> tests/ui/redundant_locals.rs:76:9 + --> tests/ui/redundant_locals.rs:86:9 | LL | let x = x; | ^^^^^^^^^^ | help: `x` is initially defined here - --> tests/ui/redundant_locals.rs:75:13 + --> tests/ui/redundant_locals.rs:85:13 | LL | let x = 1; | ^ error: redundant redefinition of a binding `x` - --> tests/ui/redundant_locals.rs:79:9 + --> tests/ui/redundant_locals.rs:90:9 | LL | let x = x; | ^^^^^^^^^^ | help: `x` is initially defined here - --> tests/ui/redundant_locals.rs:78:6 + --> tests/ui/redundant_locals.rs:89:6 | LL | |x: i32| { | ^ error: redundant redefinition of a binding `x` - --> tests/ui/redundant_locals.rs:98:9 + --> tests/ui/redundant_locals.rs:110:9 | LL | let x = x; | ^^^^^^^^^^ | help: `x` is initially defined here - --> tests/ui/redundant_locals.rs:95:9 + --> tests/ui/redundant_locals.rs:107:9 | LL | let x = 1; | ^ error: redundant redefinition of a binding `a` - --> tests/ui/redundant_locals.rs:153:5 + --> tests/ui/redundant_locals.rs:166:5 | LL | let a = a; | ^^^^^^^^^^ | help: `a` is initially defined here - --> tests/ui/redundant_locals.rs:151:9 + --> tests/ui/redundant_locals.rs:164:9 | LL | let a = WithoutDrop(1); | ^ diff --git a/tests/ui/redundant_pattern_matching_drop_order.fixed b/tests/ui/redundant_pattern_matching_drop_order.fixed index 148eaa4b33a6..4de47a1ad3ee 100644 --- a/tests/ui/redundant_pattern_matching_drop_order.fixed +++ b/tests/ui/redundant_pattern_matching_drop_order.fixed @@ -13,49 +13,71 @@ fn main() { // Result if m.lock().is_ok() {} + //~^ redundant_pattern_matching if Err::<(), _>(m.lock().unwrap().0).is_err() {} + //~^ redundant_pattern_matching { if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok() {} + //~^ redundant_pattern_matching } if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok() { + //~^ redundant_pattern_matching } else { } if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok() {} + //~^ redundant_pattern_matching if Err::, _>(()).is_err() {} + //~^ redundant_pattern_matching if Ok::<_, ()>(String::new()).is_ok() {} + //~^ redundant_pattern_matching if Err::<(), _>((String::new(), ())).is_err() {} + //~^ redundant_pattern_matching // Option if Some(m.lock()).is_some() {} + //~^ redundant_pattern_matching if Some(m.lock().unwrap().0).is_some() {} + //~^ redundant_pattern_matching { if None::>.is_none() {} + //~^ redundant_pattern_matching } if None::>.is_none() { + //~^ redundant_pattern_matching } else { } if None::>.is_none() {} + //~^ redundant_pattern_matching if Some(String::new()).is_some() {} + //~^ redundant_pattern_matching if Some((String::new(), ())).is_some() {} + //~^ redundant_pattern_matching // Poll if Ready(m.lock()).is_ready() {} + //~^ redundant_pattern_matching if Ready(m.lock().unwrap().0).is_ready() {} + //~^ redundant_pattern_matching { if Pending::>.is_pending() {} + //~^ redundant_pattern_matching } if Pending::>.is_pending() { + //~^ redundant_pattern_matching } else { } if Pending::>.is_pending() {} + //~^ redundant_pattern_matching if Ready(String::new()).is_ready() {} + //~^ redundant_pattern_matching if Ready((String::new(), ())).is_ready() {} + //~^ redundant_pattern_matching } diff --git a/tests/ui/redundant_pattern_matching_drop_order.rs b/tests/ui/redundant_pattern_matching_drop_order.rs index 5bc06f3cc529..4e37837c1fe6 100644 --- a/tests/ui/redundant_pattern_matching_drop_order.rs +++ b/tests/ui/redundant_pattern_matching_drop_order.rs @@ -13,49 +13,71 @@ fn main() { // Result if let Ok(_) = m.lock() {} + //~^ redundant_pattern_matching if let Err(_) = Err::<(), _>(m.lock().unwrap().0) {} + //~^ redundant_pattern_matching { if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {} + //~^ redundant_pattern_matching } if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) { + //~^ redundant_pattern_matching } else { } if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {} + //~^ redundant_pattern_matching if let Err(_) = Err::, _>(()) {} + //~^ redundant_pattern_matching if let Ok(_) = Ok::<_, ()>(String::new()) {} + //~^ redundant_pattern_matching if let Err(_) = Err::<(), _>((String::new(), ())) {} + //~^ redundant_pattern_matching // Option if let Some(_) = Some(m.lock()) {} + //~^ redundant_pattern_matching if let Some(_) = Some(m.lock().unwrap().0) {} + //~^ redundant_pattern_matching { if let None = None::> {} + //~^ redundant_pattern_matching } if let None = None::> { + //~^ redundant_pattern_matching } else { } if let None = None::> {} + //~^ redundant_pattern_matching if let Some(_) = Some(String::new()) {} + //~^ redundant_pattern_matching if let Some(_) = Some((String::new(), ())) {} + //~^ redundant_pattern_matching // Poll if let Ready(_) = Ready(m.lock()) {} + //~^ redundant_pattern_matching if let Ready(_) = Ready(m.lock().unwrap().0) {} + //~^ redundant_pattern_matching { if let Pending = Pending::> {} + //~^ redundant_pattern_matching } if let Pending = Pending::> { + //~^ redundant_pattern_matching } else { } if let Pending = Pending::> {} + //~^ redundant_pattern_matching if let Ready(_) = Ready(String::new()) {} + //~^ redundant_pattern_matching if let Ready(_) = Ready((String::new(), ())) {} + //~^ redundant_pattern_matching } diff --git a/tests/ui/redundant_pattern_matching_drop_order.stderr b/tests/ui/redundant_pattern_matching_drop_order.stderr index 1a99cb9fc32b..74462f022f70 100644 --- a/tests/ui/redundant_pattern_matching_drop_order.stderr +++ b/tests/ui/redundant_pattern_matching_drop_order.stderr @@ -10,7 +10,7 @@ LL | if let Ok(_) = m.lock() {} = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:16:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:17:12 | LL | if let Err(_) = Err::<(), _>(m.lock().unwrap().0) {} | -------^^^^^^------------------------------------ help: try: `if Err::<(), _>(m.lock().unwrap().0).is_err()` @@ -19,7 +19,7 @@ LL | if let Err(_) = Err::<(), _>(m.lock().unwrap().0) {} = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:19:16 + --> tests/ui/redundant_pattern_matching_drop_order.rs:21:16 | LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {} | -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()` @@ -28,7 +28,7 @@ LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {} = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:21:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:24:12 | LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) { | -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()` @@ -37,31 +37,31 @@ LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) { = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:24:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:28:12 | LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {} | -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:25:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:30:12 | LL | if let Err(_) = Err::, _>(()) {} | -------^^^^^^------------------------------------------ help: try: `if Err::, _>(()).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:27:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:33:12 | LL | if let Ok(_) = Ok::<_, ()>(String::new()) {} | -------^^^^^----------------------------- help: try: `if Ok::<_, ()>(String::new()).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:28:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:35:12 | LL | if let Err(_) = Err::<(), _>((String::new(), ())) {} | -------^^^^^^------------------------------------ help: try: `if Err::<(), _>((String::new(), ())).is_err()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:31:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:39:12 | LL | if let Some(_) = Some(m.lock()) {} | -------^^^^^^^----------------- help: try: `if Some(m.lock()).is_some()` @@ -70,7 +70,7 @@ LL | if let Some(_) = Some(m.lock()) {} = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:32:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:41:12 | LL | if let Some(_) = Some(m.lock().unwrap().0) {} | -------^^^^^^^---------------------------- help: try: `if Some(m.lock().unwrap().0).is_some()` @@ -79,7 +79,7 @@ LL | if let Some(_) = Some(m.lock().unwrap().0) {} = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:35:16 + --> tests/ui/redundant_pattern_matching_drop_order.rs:45:16 | LL | if let None = None::> {} | -------^^^^------------------------------------ help: try: `if None::>.is_none()` @@ -88,7 +88,7 @@ LL | if let None = None::> {} = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:37:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:48:12 | LL | if let None = None::> { | -------^^^^------------------------------------ help: try: `if None::>.is_none()` @@ -97,25 +97,25 @@ LL | if let None = None::> { = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:41:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:53:12 | LL | if let None = None::> {} | -------^^^^------------------------------------ help: try: `if None::>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:43:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:56:12 | LL | if let Some(_) = Some(String::new()) {} | -------^^^^^^^---------------------- help: try: `if Some(String::new()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:44:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:58:12 | LL | if let Some(_) = Some((String::new(), ())) {} | -------^^^^^^^---------------------------- help: try: `if Some((String::new(), ())).is_some()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:47:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:62:12 | LL | if let Ready(_) = Ready(m.lock()) {} | -------^^^^^^^^------------------ help: try: `if Ready(m.lock()).is_ready()` @@ -124,7 +124,7 @@ LL | if let Ready(_) = Ready(m.lock()) {} = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:48:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:64:12 | LL | if let Ready(_) = Ready(m.lock().unwrap().0) {} | -------^^^^^^^^----------------------------- help: try: `if Ready(m.lock().unwrap().0).is_ready()` @@ -133,7 +133,7 @@ LL | if let Ready(_) = Ready(m.lock().unwrap().0) {} = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:51:16 + --> tests/ui/redundant_pattern_matching_drop_order.rs:68:16 | LL | if let Pending = Pending::> {} | -------^^^^^^^--------------------------------------- help: try: `if Pending::>.is_pending()` @@ -142,7 +142,7 @@ LL | if let Pending = Pending::> {} = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:53:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:71:12 | LL | if let Pending = Pending::> { | -------^^^^^^^--------------------------------------- help: try: `if Pending::>.is_pending()` @@ -151,19 +151,19 @@ LL | if let Pending = Pending::> { = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:57:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:76:12 | LL | if let Pending = Pending::> {} | -------^^^^^^^--------------------------------------- help: try: `if Pending::>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:59:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:79:12 | LL | if let Ready(_) = Ready(String::new()) {} | -------^^^^^^^^----------------------- help: try: `if Ready(String::new()).is_ready()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_drop_order.rs:60:12 + --> tests/ui/redundant_pattern_matching_drop_order.rs:81:12 | LL | if let Ready(_) = Ready((String::new(), ())) {} | -------^^^^^^^^----------------------------- help: try: `if Ready((String::new(), ())).is_ready()` diff --git a/tests/ui/redundant_pattern_matching_if_let_true.fixed b/tests/ui/redundant_pattern_matching_if_let_true.fixed index 6d9106789340..f40cd01d16cb 100644 --- a/tests/ui/redundant_pattern_matching_if_let_true.fixed +++ b/tests/ui/redundant_pattern_matching_if_let_true.fixed @@ -20,18 +20,25 @@ fn main() { let mut k = 5; if k > 1 {} + //~^ redundant_pattern_matching if !(k > 5) {} + //~^ redundant_pattern_matching if k > 1 {} + //~^ redundant_pattern_matching if let (true, true) = (k > 1, k > 2) {} while k > 1 { + //~^ redundant_pattern_matching k += 1; } while condition!() { + //~^ redundant_pattern_matching k += 1; } k > 5; + //~^ redundant_pattern_matching !(k > 5); + //~^ redundant_pattern_matching // Whole loop is from a macro expansion, don't lint: lettrue!(if); lettrue!(while); diff --git a/tests/ui/redundant_pattern_matching_if_let_true.rs b/tests/ui/redundant_pattern_matching_if_let_true.rs index a82e673982a3..143c279e41c1 100644 --- a/tests/ui/redundant_pattern_matching_if_let_true.rs +++ b/tests/ui/redundant_pattern_matching_if_let_true.rs @@ -20,18 +20,25 @@ fn main() { let mut k = 5; if let true = k > 1 {} + //~^ redundant_pattern_matching if let false = k > 5 {} + //~^ redundant_pattern_matching if let (true) = k > 1 {} + //~^ redundant_pattern_matching if let (true, true) = (k > 1, k > 2) {} while let true = k > 1 { + //~^ redundant_pattern_matching k += 1; } while let true = condition!() { + //~^ redundant_pattern_matching k += 1; } matches!(k > 5, true); + //~^ redundant_pattern_matching matches!(k > 5, false); + //~^ redundant_pattern_matching // Whole loop is from a macro expansion, don't lint: lettrue!(if); lettrue!(while); diff --git a/tests/ui/redundant_pattern_matching_if_let_true.stderr b/tests/ui/redundant_pattern_matching_if_let_true.stderr index 43d5cd07cec7..db8646270609 100644 --- a/tests/ui/redundant_pattern_matching_if_let_true.stderr +++ b/tests/ui/redundant_pattern_matching_if_let_true.stderr @@ -8,37 +8,37 @@ LL | if let true = k > 1 {} = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: using `if let` to pattern match a bool - --> tests/ui/redundant_pattern_matching_if_let_true.rs:23:8 + --> tests/ui/redundant_pattern_matching_if_let_true.rs:24:8 | LL | if let false = k > 5 {} | ^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `!(k > 5)` error: using `if let` to pattern match a bool - --> tests/ui/redundant_pattern_matching_if_let_true.rs:24:8 + --> tests/ui/redundant_pattern_matching_if_let_true.rs:26:8 | LL | if let (true) = k > 1 {} | ^^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `k > 1` error: using `if let` to pattern match a bool - --> tests/ui/redundant_pattern_matching_if_let_true.rs:26:11 + --> tests/ui/redundant_pattern_matching_if_let_true.rs:29:11 | LL | while let true = k > 1 { | ^^^^^^^^^^^^^^^^ help: consider using the condition directly: `k > 1` error: using `if let` to pattern match a bool - --> tests/ui/redundant_pattern_matching_if_let_true.rs:29:11 + --> tests/ui/redundant_pattern_matching_if_let_true.rs:33:11 | LL | while let true = condition!() { | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `condition!()` error: using `matches!` to pattern match a bool - --> tests/ui/redundant_pattern_matching_if_let_true.rs:33:5 + --> tests/ui/redundant_pattern_matching_if_let_true.rs:38:5 | LL | matches!(k > 5, true); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `k > 5` error: using `matches!` to pattern match a bool - --> tests/ui/redundant_pattern_matching_if_let_true.rs:34:5 + --> tests/ui/redundant_pattern_matching_if_let_true.rs:40:5 | LL | matches!(k > 5, false); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `!(k > 5)` diff --git a/tests/ui/redundant_pattern_matching_ipaddr.fixed b/tests/ui/redundant_pattern_matching_ipaddr.fixed index 429d33118a58..05ea8f75dc89 100644 --- a/tests/ui/redundant_pattern_matching_ipaddr.fixed +++ b/tests/ui/redundant_pattern_matching_ipaddr.fixed @@ -13,20 +13,27 @@ use std::net::{Ipv4Addr, Ipv6Addr}; fn main() { let ipaddr: IpAddr = V4(Ipv4Addr::LOCALHOST); if ipaddr.is_ipv4() {} + //~^ redundant_pattern_matching if V4(Ipv4Addr::LOCALHOST).is_ipv4() {} + //~^ redundant_pattern_matching if V6(Ipv6Addr::LOCALHOST).is_ipv6() {} + //~^ redundant_pattern_matching // Issue 6459 if V4(Ipv4Addr::LOCALHOST).is_ipv4() {} + //~^ redundant_pattern_matching // Issue 6459 if V6(Ipv6Addr::LOCALHOST).is_ipv6() {} + //~^ redundant_pattern_matching while V4(Ipv4Addr::LOCALHOST).is_ipv4() {} + //~^ redundant_pattern_matching while V6(Ipv6Addr::LOCALHOST).is_ipv6() {} + //~^ redundant_pattern_matching if V4(Ipv4Addr::LOCALHOST).is_ipv4() {} @@ -45,6 +52,7 @@ fn main() { V6(Ipv6Addr::LOCALHOST).is_ipv4(); let _ = if V4(Ipv4Addr::LOCALHOST).is_ipv4() { + //~^ redundant_pattern_matching true } else { false @@ -53,8 +61,10 @@ fn main() { ipaddr_const(); let _ = if gen_ipaddr().is_ipv4() { + //~^ redundant_pattern_matching 1 } else if gen_ipaddr().is_ipv6() { + //~^ redundant_pattern_matching 2 } else { 3 @@ -67,12 +77,16 @@ fn gen_ipaddr() -> IpAddr { const fn ipaddr_const() { if V4(Ipv4Addr::LOCALHOST).is_ipv4() {} + //~^ redundant_pattern_matching if V6(Ipv6Addr::LOCALHOST).is_ipv6() {} + //~^ redundant_pattern_matching while V4(Ipv4Addr::LOCALHOST).is_ipv4() {} + //~^ redundant_pattern_matching while V6(Ipv6Addr::LOCALHOST).is_ipv6() {} + //~^ redundant_pattern_matching V4(Ipv4Addr::LOCALHOST).is_ipv4(); diff --git a/tests/ui/redundant_pattern_matching_ipaddr.rs b/tests/ui/redundant_pattern_matching_ipaddr.rs index e7136b72c20c..4ff9b2204e8a 100644 --- a/tests/ui/redundant_pattern_matching_ipaddr.rs +++ b/tests/ui/redundant_pattern_matching_ipaddr.rs @@ -13,20 +13,27 @@ use std::net::{Ipv4Addr, Ipv6Addr}; fn main() { let ipaddr: IpAddr = V4(Ipv4Addr::LOCALHOST); if let V4(_) = &ipaddr {} + //~^ redundant_pattern_matching if let V4(_) = V4(Ipv4Addr::LOCALHOST) {} + //~^ redundant_pattern_matching if let V6(_) = V6(Ipv6Addr::LOCALHOST) {} + //~^ redundant_pattern_matching // Issue 6459 if matches!(V4(Ipv4Addr::LOCALHOST), V4(_)) {} + //~^ redundant_pattern_matching // Issue 6459 if matches!(V6(Ipv6Addr::LOCALHOST), V6(_)) {} + //~^ redundant_pattern_matching while let V4(_) = V4(Ipv4Addr::LOCALHOST) {} + //~^ redundant_pattern_matching while let V6(_) = V6(Ipv6Addr::LOCALHOST) {} + //~^ redundant_pattern_matching if V4(Ipv4Addr::LOCALHOST).is_ipv4() {} @@ -37,26 +44,31 @@ fn main() { } match V4(Ipv4Addr::LOCALHOST) { + //~^ redundant_pattern_matching V4(_) => true, V6(_) => false, }; match V4(Ipv4Addr::LOCALHOST) { + //~^ redundant_pattern_matching V4(_) => false, V6(_) => true, }; match V6(Ipv6Addr::LOCALHOST) { + //~^ redundant_pattern_matching V4(_) => false, V6(_) => true, }; match V6(Ipv6Addr::LOCALHOST) { + //~^ redundant_pattern_matching V4(_) => true, V6(_) => false, }; let _ = if let V4(_) = V4(Ipv4Addr::LOCALHOST) { + //~^ redundant_pattern_matching true } else { false @@ -65,8 +77,10 @@ fn main() { ipaddr_const(); let _ = if let V4(_) = gen_ipaddr() { + //~^ redundant_pattern_matching 1 } else if let V6(_) = gen_ipaddr() { + //~^ redundant_pattern_matching 2 } else { 3 @@ -79,19 +93,25 @@ fn gen_ipaddr() -> IpAddr { const fn ipaddr_const() { if let V4(_) = V4(Ipv4Addr::LOCALHOST) {} + //~^ redundant_pattern_matching if let V6(_) = V6(Ipv6Addr::LOCALHOST) {} + //~^ redundant_pattern_matching while let V4(_) = V4(Ipv4Addr::LOCALHOST) {} + //~^ redundant_pattern_matching while let V6(_) = V6(Ipv6Addr::LOCALHOST) {} + //~^ redundant_pattern_matching match V4(Ipv4Addr::LOCALHOST) { + //~^ redundant_pattern_matching V4(_) => true, V6(_) => false, }; match V6(Ipv6Addr::LOCALHOST) { + //~^ redundant_pattern_matching V4(_) => false, V6(_) => true, }; diff --git a/tests/ui/redundant_pattern_matching_ipaddr.stderr b/tests/ui/redundant_pattern_matching_ipaddr.stderr index a4930ad839f9..66d2cecdc0c9 100644 --- a/tests/ui/redundant_pattern_matching_ipaddr.stderr +++ b/tests/ui/redundant_pattern_matching_ipaddr.stderr @@ -8,132 +8,138 @@ LL | if let V4(_) = &ipaddr {} = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:17:12 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:18:12 | LL | if let V4(_) = V4(Ipv4Addr::LOCALHOST) {} | -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:19:12 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:21:12 | LL | if let V6(_) = V6(Ipv6Addr::LOCALHOST) {} | -------^^^^^-------------------------- help: try: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:22:8 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:25:8 | LL | if matches!(V4(Ipv4Addr::LOCALHOST), V4(_)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:25:8 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:29:8 | LL | if matches!(V6(Ipv6Addr::LOCALHOST), V6(_)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:27:15 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:32:15 | LL | while let V4(_) = V4(Ipv4Addr::LOCALHOST) {} | ----------^^^^^-------------------------- help: try: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:29:15 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:35:15 | LL | while let V6(_) = V6(Ipv6Addr::LOCALHOST) {} | ----------^^^^^-------------------------- help: try: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:39:5 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:46:5 | LL | / match V4(Ipv4Addr::LOCALHOST) { +LL | | LL | | V4(_) => true, LL | | V6(_) => false, LL | | }; | |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:44:5 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:52:5 | LL | / match V4(Ipv4Addr::LOCALHOST) { +LL | | LL | | V4(_) => false, LL | | V6(_) => true, LL | | }; | |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv6()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:49:5 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:58:5 | LL | / match V6(Ipv6Addr::LOCALHOST) { +LL | | LL | | V4(_) => false, LL | | V6(_) => true, LL | | }; | |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:54:5 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:64:5 | LL | / match V6(Ipv6Addr::LOCALHOST) { +LL | | LL | | V4(_) => true, LL | | V6(_) => false, LL | | }; | |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:59:20 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:70:20 | LL | let _ = if let V4(_) = V4(Ipv4Addr::LOCALHOST) { | -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:67:20 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:79:20 | LL | let _ = if let V4(_) = gen_ipaddr() { | -------^^^^^--------------- help: try: `if gen_ipaddr().is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:69:19 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:82:19 | LL | } else if let V6(_) = gen_ipaddr() { | -------^^^^^--------------- help: try: `if gen_ipaddr().is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:81:12 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:95:12 | LL | if let V4(_) = V4(Ipv4Addr::LOCALHOST) {} | -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:83:12 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:98:12 | LL | if let V6(_) = V6(Ipv6Addr::LOCALHOST) {} | -------^^^^^-------------------------- help: try: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:85:15 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:101:15 | LL | while let V4(_) = V4(Ipv4Addr::LOCALHOST) {} | ----------^^^^^-------------------------- help: try: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:87:15 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:104:15 | LL | while let V6(_) = V6(Ipv6Addr::LOCALHOST) {} | ----------^^^^^-------------------------- help: try: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:89:5 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:107:5 | LL | / match V4(Ipv4Addr::LOCALHOST) { +LL | | LL | | V4(_) => true, LL | | V6(_) => false, LL | | }; | |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> tests/ui/redundant_pattern_matching_ipaddr.rs:94:5 + --> tests/ui/redundant_pattern_matching_ipaddr.rs:113:5 | LL | / match V6(Ipv6Addr::LOCALHOST) { +LL | | LL | | V4(_) => false, LL | | V6(_) => true, LL | | }; diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed index c7e0cd2610f0..7d45bb63a395 100644 --- a/tests/ui/redundant_pattern_matching_option.fixed +++ b/tests/ui/redundant_pattern_matching_option.fixed @@ -12,10 +12,12 @@ fn issue_11174(boolean: bool, maybe_some: Option) -> bool { maybe_some.is_none() && (!boolean) + //~^ redundant_pattern_matching } fn issue_11174_edge_cases(boolean: bool, boolean2: bool, maybe_some: Option) { let _ = maybe_some.is_none() && (boolean || boolean2); // guard needs parentheses + //~^ redundant_pattern_matching let _ = match maybe_some { // can't use `matches!` here // because `expr` metavars in macros don't allow let exprs @@ -30,23 +32,30 @@ fn issue_11174_edge_cases(boolean: bool, boolean2: bool, maybe_some: Option.is_none() {} + //~^ redundant_pattern_matching if Some(42).is_some() {} + //~^ redundant_pattern_matching if Some(42).is_some() { + //~^ redundant_pattern_matching foo(); } else { bar(); } while Some(42).is_some() {} + //~^ redundant_pattern_matching while Some(42).is_none() {} + //~^ redundant_pattern_matching while None::<()>.is_none() {} + //~^ redundant_pattern_matching let mut v = vec![1, 2, 3]; while v.pop().is_some() { + //~^ redundant_pattern_matching foo(); } @@ -62,20 +71,24 @@ fn main() { let opt = Some(false); let _ = if opt.is_some() { true } else { false }; + //~^ redundant_pattern_matching issue6067(); issue10726(); issue10803(); let _ = if gen_opt().is_some() { + //~^ redundant_pattern_matching 1 } else if gen_opt().is_none() { + //~^ redundant_pattern_matching 2 } else { 3 }; if gen_opt().is_some() {} + //~^ redundant_pattern_matching } fn gen_opt() -> Option<()> { @@ -91,12 +104,16 @@ fn bar() {} // so the following should be linted. const fn issue6067() { if Some(42).is_some() {} + //~^ redundant_pattern_matching if None::<()>.is_none() {} + //~^ redundant_pattern_matching while Some(42).is_some() {} + //~^ redundant_pattern_matching while None::<()>.is_none() {} + //~^ redundant_pattern_matching Some(42).is_some(); @@ -106,7 +123,9 @@ const fn issue6067() { #[allow(clippy::deref_addrof, dead_code, clippy::needless_borrow)] fn issue7921() { if (&None::<()>).is_none() {} + //~^ redundant_pattern_matching if (&None::<()>).is_none() {} + //~^ redundant_pattern_matching } fn issue10726() { @@ -131,8 +150,10 @@ fn issue10803() { let x = Some(42); let _ = x.is_some(); + //~^ redundant_pattern_matching let _ = x.is_none(); + //~^ redundant_pattern_matching // Don't lint let _ = matches!(x, Some(16)); @@ -143,5 +164,6 @@ fn issue13902() { let p = &raw const x; unsafe { let _ = (*p).is_none(); + //~^ redundant_pattern_matching } } diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs index 6d9a9f7f9428..3d02bade4409 100644 --- a/tests/ui/redundant_pattern_matching_option.rs +++ b/tests/ui/redundant_pattern_matching_option.rs @@ -12,10 +12,12 @@ fn issue_11174(boolean: bool, maybe_some: Option) -> bool { matches!(maybe_some, None if !boolean) + //~^ redundant_pattern_matching } fn issue_11174_edge_cases(boolean: bool, boolean2: bool, maybe_some: Option) { let _ = matches!(maybe_some, None if boolean || boolean2); // guard needs parentheses + //~^ redundant_pattern_matching let _ = match maybe_some { // can't use `matches!` here // because `expr` metavars in macros don't allow let exprs @@ -30,23 +32,30 @@ fn issue_11174_edge_cases(boolean: bool, boolean2: bool, maybe_some: Option {} + //~^ redundant_pattern_matching if let Some(_) = Some(42) {} + //~^ redundant_pattern_matching if let Some(_) = Some(42) { + //~^ redundant_pattern_matching foo(); } else { bar(); } while let Some(_) = Some(42) {} + //~^ redundant_pattern_matching while let None = Some(42) {} + //~^ redundant_pattern_matching while let None = None::<()> {} + //~^ redundant_pattern_matching let mut v = vec![1, 2, 3]; while let Some(_) = v.pop() { + //~^ redundant_pattern_matching foo(); } @@ -55,36 +64,43 @@ fn main() { if Some(42).is_some() {} match Some(42) { + //~^ redundant_pattern_matching Some(_) => true, None => false, }; match None::<()> { + //~^ redundant_pattern_matching Some(_) => false, None => true, }; let _ = match None::<()> { + //~^ redundant_pattern_matching Some(_) => false, None => true, }; let opt = Some(false); let _ = if let Some(_) = opt { true } else { false }; + //~^ redundant_pattern_matching issue6067(); issue10726(); issue10803(); let _ = if let Some(_) = gen_opt() { + //~^ redundant_pattern_matching 1 } else if let None = gen_opt() { + //~^ redundant_pattern_matching 2 } else { 3 }; if let Some(..) = gen_opt() {} + //~^ redundant_pattern_matching } fn gen_opt() -> Option<()> { @@ -100,19 +116,25 @@ fn bar() {} // so the following should be linted. const fn issue6067() { if let Some(_) = Some(42) {} + //~^ redundant_pattern_matching if let None = None::<()> {} + //~^ redundant_pattern_matching while let Some(_) = Some(42) {} + //~^ redundant_pattern_matching while let None = None::<()> {} + //~^ redundant_pattern_matching match Some(42) { + //~^ redundant_pattern_matching Some(_) => true, None => false, }; match None::<()> { + //~^ redundant_pattern_matching Some(_) => false, None => true, }; @@ -121,28 +143,34 @@ const fn issue6067() { #[allow(clippy::deref_addrof, dead_code, clippy::needless_borrow)] fn issue7921() { if let None = *(&None::<()>) {} + //~^ redundant_pattern_matching if let None = *&None::<()> {} + //~^ redundant_pattern_matching } fn issue10726() { let x = Some(42); match x { + //~^ redundant_pattern_matching Some(_) => true, _ => false, }; match x { + //~^ redundant_pattern_matching None => true, _ => false, }; match x { + //~^ redundant_pattern_matching Some(_) => false, _ => true, }; match x { + //~^ redundant_pattern_matching None => false, _ => true, }; @@ -158,8 +186,10 @@ fn issue10803() { let x = Some(42); let _ = matches!(x, Some(_)); + //~^ redundant_pattern_matching let _ = matches!(x, None); + //~^ redundant_pattern_matching // Don't lint let _ = matches!(x, Some(16)); @@ -170,5 +200,6 @@ fn issue13902() { let p = &raw const x; unsafe { let _ = matches!(*p, None); + //~^ redundant_pattern_matching } } diff --git a/tests/ui/redundant_pattern_matching_option.stderr b/tests/ui/redundant_pattern_matching_option.stderr index 34d80f5ca782..0dfa05970ce3 100644 --- a/tests/ui/redundant_pattern_matching_option.stderr +++ b/tests/ui/redundant_pattern_matching_option.stderr @@ -8,209 +8,218 @@ LL | matches!(maybe_some, None if !boolean) = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:18:13 + --> tests/ui/redundant_pattern_matching_option.rs:19:13 | LL | let _ = matches!(maybe_some, None if boolean || boolean2); // guard needs parentheses | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (boolean || boolean2)` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:32:12 + --> tests/ui/redundant_pattern_matching_option.rs:34:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:34:12 + --> tests/ui/redundant_pattern_matching_option.rs:37:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:36:12 + --> tests/ui/redundant_pattern_matching_option.rs:40:12 | LL | if let Some(_) = Some(42) { | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:42:15 + --> tests/ui/redundant_pattern_matching_option.rs:47:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:44:15 + --> tests/ui/redundant_pattern_matching_option.rs:50:15 | LL | while let None = Some(42) {} | ----------^^^^----------- help: try: `while Some(42).is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:46:15 + --> tests/ui/redundant_pattern_matching_option.rs:53:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:49:15 + --> tests/ui/redundant_pattern_matching_option.rs:57:15 | LL | while let Some(_) = v.pop() { | ----------^^^^^^^---------- help: try: `while v.pop().is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:57:5 + --> tests/ui/redundant_pattern_matching_option.rs:66:5 | LL | / match Some(42) { +LL | | LL | | Some(_) => true, LL | | None => false, LL | | }; | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:62:5 + --> tests/ui/redundant_pattern_matching_option.rs:72:5 | LL | / match None::<()> { +LL | | LL | | Some(_) => false, LL | | None => true, LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:67:13 + --> tests/ui/redundant_pattern_matching_option.rs:78:13 | LL | let _ = match None::<()> { | _____________^ +LL | | LL | | Some(_) => false, LL | | None => true, LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:73:20 + --> tests/ui/redundant_pattern_matching_option.rs:85:20 | LL | let _ = if let Some(_) = opt { true } else { false }; | -------^^^^^^^------ help: try: `if opt.is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:79:20 + --> tests/ui/redundant_pattern_matching_option.rs:92:20 | LL | let _ = if let Some(_) = gen_opt() { | -------^^^^^^^------------ help: try: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:81:19 + --> tests/ui/redundant_pattern_matching_option.rs:95:19 | LL | } else if let None = gen_opt() { | -------^^^^------------ help: try: `if gen_opt().is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:87:12 + --> tests/ui/redundant_pattern_matching_option.rs:102:12 | LL | if let Some(..) = gen_opt() {} | -------^^^^^^^^------------ help: try: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:102:12 + --> tests/ui/redundant_pattern_matching_option.rs:118:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:104:12 + --> tests/ui/redundant_pattern_matching_option.rs:121:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:106:15 + --> tests/ui/redundant_pattern_matching_option.rs:124:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:108:15 + --> tests/ui/redundant_pattern_matching_option.rs:127:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:110:5 + --> tests/ui/redundant_pattern_matching_option.rs:130:5 | LL | / match Some(42) { +LL | | LL | | Some(_) => true, LL | | None => false, LL | | }; | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:115:5 + --> tests/ui/redundant_pattern_matching_option.rs:136:5 | LL | / match None::<()> { +LL | | LL | | Some(_) => false, LL | | None => true, LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:123:12 + --> tests/ui/redundant_pattern_matching_option.rs:145:12 | LL | if let None = *(&None::<()>) {} | -------^^^^----------------- help: try: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:124:12 + --> tests/ui/redundant_pattern_matching_option.rs:147:12 | LL | if let None = *&None::<()> {} | -------^^^^--------------- help: try: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:130:5 + --> tests/ui/redundant_pattern_matching_option.rs:154:5 | LL | / match x { +LL | | LL | | Some(_) => true, LL | | _ => false, LL | | }; | |_____^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:135:5 + --> tests/ui/redundant_pattern_matching_option.rs:160:5 | LL | / match x { +LL | | LL | | None => true, LL | | _ => false, LL | | }; | |_____^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:140:5 + --> tests/ui/redundant_pattern_matching_option.rs:166:5 | LL | / match x { +LL | | LL | | Some(_) => false, LL | | _ => true, LL | | }; | |_____^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:145:5 + --> tests/ui/redundant_pattern_matching_option.rs:172:5 | LL | / match x { +LL | | LL | | None => false, LL | | _ => true, LL | | }; | |_____^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:160:13 + --> tests/ui/redundant_pattern_matching_option.rs:188:13 | LL | let _ = matches!(x, Some(_)); | ^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:162:13 + --> tests/ui/redundant_pattern_matching_option.rs:191:13 | LL | let _ = matches!(x, None); | ^^^^^^^^^^^^^^^^^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:172:17 + --> tests/ui/redundant_pattern_matching_option.rs:202:17 | LL | let _ = matches!(*p, None); | ^^^^^^^^^^^^^^^^^^ help: try: `(*p).is_none()` diff --git a/tests/ui/redundant_pattern_matching_poll.fixed b/tests/ui/redundant_pattern_matching_poll.fixed index 08d83f87e4c3..f3ffb6b3c755 100644 --- a/tests/ui/redundant_pattern_matching_poll.fixed +++ b/tests/ui/redundant_pattern_matching_poll.fixed @@ -13,10 +13,13 @@ use std::task::Poll::{self, Pending, Ready}; fn main() { if Pending::<()>.is_pending() {} + //~^ redundant_pattern_matching if Ready(42).is_ready() {} + //~^ redundant_pattern_matching if Ready(42).is_ready() { + //~^ redundant_pattern_matching foo(); } else { bar(); @@ -24,15 +27,20 @@ fn main() { // Issue 6459 if Ready(42).is_ready() {} + //~^ redundant_pattern_matching // Issue 6459 if Pending::<()>.is_pending() {} + //~^ redundant_pattern_matching while Ready(42).is_ready() {} + //~^ redundant_pattern_matching while Ready(42).is_pending() {} + //~^ redundant_pattern_matching while Pending::<()>.is_pending() {} + //~^ redundant_pattern_matching if Pending::.is_pending() {} @@ -46,12 +54,15 @@ fn main() { let poll = Ready(false); let _ = if poll.is_ready() { true } else { false }; + //~^ redundant_pattern_matching poll_const(); let _ = if gen_poll().is_ready() { + //~^ redundant_pattern_matching 1 } else if gen_poll().is_pending() { + //~^ redundant_pattern_matching 2 } else { 3 @@ -68,12 +79,16 @@ fn bar() {} const fn poll_const() { if Ready(42).is_ready() {} + //~^ redundant_pattern_matching if Pending::<()>.is_pending() {} + //~^ redundant_pattern_matching while Ready(42).is_ready() {} + //~^ redundant_pattern_matching while Pending::<()>.is_pending() {} + //~^ redundant_pattern_matching Ready(42).is_ready(); diff --git a/tests/ui/redundant_pattern_matching_poll.rs b/tests/ui/redundant_pattern_matching_poll.rs index 7bc2b3be4d34..30e80b24521d 100644 --- a/tests/ui/redundant_pattern_matching_poll.rs +++ b/tests/ui/redundant_pattern_matching_poll.rs @@ -13,10 +13,13 @@ use std::task::Poll::{self, Pending, Ready}; fn main() { if let Pending = Pending::<()> {} + //~^ redundant_pattern_matching if let Ready(_) = Ready(42) {} + //~^ redundant_pattern_matching if let Ready(_) = Ready(42) { + //~^ redundant_pattern_matching foo(); } else { bar(); @@ -24,43 +27,54 @@ fn main() { // Issue 6459 if matches!(Ready(42), Ready(_)) {} + //~^ redundant_pattern_matching // Issue 6459 if matches!(Pending::<()>, Pending) {} + //~^ redundant_pattern_matching while let Ready(_) = Ready(42) {} + //~^ redundant_pattern_matching while let Pending = Ready(42) {} + //~^ redundant_pattern_matching while let Pending = Pending::<()> {} + //~^ redundant_pattern_matching if Pending::.is_pending() {} if Ready(42).is_ready() {} match Ready(42) { + //~^ redundant_pattern_matching Ready(_) => true, Pending => false, }; match Pending::<()> { + //~^ redundant_pattern_matching Ready(_) => false, Pending => true, }; let _ = match Pending::<()> { + //~^ redundant_pattern_matching Ready(_) => false, Pending => true, }; let poll = Ready(false); let _ = if let Ready(_) = poll { true } else { false }; + //~^ redundant_pattern_matching poll_const(); let _ = if let Ready(_) = gen_poll() { + //~^ redundant_pattern_matching 1 } else if let Pending = gen_poll() { + //~^ redundant_pattern_matching 2 } else { 3 @@ -77,19 +91,25 @@ fn bar() {} const fn poll_const() { if let Ready(_) = Ready(42) {} + //~^ redundant_pattern_matching if let Pending = Pending::<()> {} + //~^ redundant_pattern_matching while let Ready(_) = Ready(42) {} + //~^ redundant_pattern_matching while let Pending = Pending::<()> {} + //~^ redundant_pattern_matching match Ready(42) { + //~^ redundant_pattern_matching Ready(_) => true, Pending => false, }; match Pending::<()> { + //~^ redundant_pattern_matching Ready(_) => false, Pending => true, }; diff --git a/tests/ui/redundant_pattern_matching_poll.stderr b/tests/ui/redundant_pattern_matching_poll.stderr index 2b0f087fb993..5f659184f7b3 100644 --- a/tests/ui/redundant_pattern_matching_poll.stderr +++ b/tests/ui/redundant_pattern_matching_poll.stderr @@ -8,130 +8,135 @@ LL | if let Pending = Pending::<()> {} = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:17:12 + --> tests/ui/redundant_pattern_matching_poll.rs:18:12 | LL | if let Ready(_) = Ready(42) {} | -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:19:12 + --> tests/ui/redundant_pattern_matching_poll.rs:21:12 | LL | if let Ready(_) = Ready(42) { | -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:26:8 + --> tests/ui/redundant_pattern_matching_poll.rs:29:8 | LL | if matches!(Ready(42), Ready(_)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_poll.rs:29:8 + --> tests/ui/redundant_pattern_matching_poll.rs:33:8 | LL | if matches!(Pending::<()>, Pending) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:31:15 + --> tests/ui/redundant_pattern_matching_poll.rs:36:15 | LL | while let Ready(_) = Ready(42) {} | ----------^^^^^^^^------------ help: try: `while Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_poll.rs:33:15 + --> tests/ui/redundant_pattern_matching_poll.rs:39:15 | LL | while let Pending = Ready(42) {} | ----------^^^^^^^------------ help: try: `while Ready(42).is_pending()` error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_poll.rs:35:15 + --> tests/ui/redundant_pattern_matching_poll.rs:42:15 | LL | while let Pending = Pending::<()> {} | ----------^^^^^^^---------------- help: try: `while Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:41:5 + --> tests/ui/redundant_pattern_matching_poll.rs:49:5 | LL | / match Ready(42) { +LL | | LL | | Ready(_) => true, LL | | Pending => false, LL | | }; | |_____^ help: try: `Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_poll.rs:46:5 + --> tests/ui/redundant_pattern_matching_poll.rs:55:5 | LL | / match Pending::<()> { +LL | | LL | | Ready(_) => false, LL | | Pending => true, LL | | }; | |_____^ help: try: `Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_poll.rs:51:13 + --> tests/ui/redundant_pattern_matching_poll.rs:61:13 | LL | let _ = match Pending::<()> { | _____________^ +LL | | LL | | Ready(_) => false, LL | | Pending => true, LL | | }; | |_____^ help: try: `Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:57:20 + --> tests/ui/redundant_pattern_matching_poll.rs:68:20 | LL | let _ = if let Ready(_) = poll { true } else { false }; | -------^^^^^^^^------- help: try: `if poll.is_ready()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:61:20 + --> tests/ui/redundant_pattern_matching_poll.rs:73:20 | LL | let _ = if let Ready(_) = gen_poll() { | -------^^^^^^^^------------- help: try: `if gen_poll().is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_poll.rs:63:19 + --> tests/ui/redundant_pattern_matching_poll.rs:76:19 | LL | } else if let Pending = gen_poll() { | -------^^^^^^^------------- help: try: `if gen_poll().is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:79:12 + --> tests/ui/redundant_pattern_matching_poll.rs:93:12 | LL | if let Ready(_) = Ready(42) {} | -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_poll.rs:81:12 + --> tests/ui/redundant_pattern_matching_poll.rs:96:12 | LL | if let Pending = Pending::<()> {} | -------^^^^^^^---------------- help: try: `if Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:83:15 + --> tests/ui/redundant_pattern_matching_poll.rs:99:15 | LL | while let Ready(_) = Ready(42) {} | ----------^^^^^^^^------------ help: try: `while Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_poll.rs:85:15 + --> tests/ui/redundant_pattern_matching_poll.rs:102:15 | LL | while let Pending = Pending::<()> {} | ----------^^^^^^^---------------- help: try: `while Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> tests/ui/redundant_pattern_matching_poll.rs:87:5 + --> tests/ui/redundant_pattern_matching_poll.rs:105:5 | LL | / match Ready(42) { +LL | | LL | | Ready(_) => true, LL | | Pending => false, LL | | }; | |_____^ help: try: `Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> tests/ui/redundant_pattern_matching_poll.rs:92:5 + --> tests/ui/redundant_pattern_matching_poll.rs:111:5 | LL | / match Pending::<()> { +LL | | LL | | Ready(_) => false, LL | | Pending => true, LL | | }; diff --git a/tests/ui/redundant_pattern_matching_result.fixed b/tests/ui/redundant_pattern_matching_result.fixed index 9571aaee7424..3bb9dacf4618 100644 --- a/tests/ui/redundant_pattern_matching_result.fixed +++ b/tests/ui/redundant_pattern_matching_result.fixed @@ -13,14 +13,19 @@ fn main() { let result: Result = Err(5); if result.is_ok() {} + //~^ redundant_pattern_matching if Ok::(42).is_ok() {} + //~^ redundant_pattern_matching if Err::(42).is_err() {} + //~^ redundant_pattern_matching while Ok::(10).is_ok() {} + //~^ redundant_pattern_matching while Ok::(10).is_err() {} + //~^ redundant_pattern_matching if Ok::(42).is_ok() {} @@ -39,6 +44,7 @@ fn main() { Err::(42).is_ok(); let _ = if Ok::(4).is_ok() { true } else { false }; + //~^ redundant_pattern_matching issue5504(); issue6067(); @@ -47,8 +53,10 @@ fn main() { issue10803(); let _ = if gen_res().is_ok() { + //~^ redundant_pattern_matching 1 } else if gen_res().is_err() { + //~^ redundant_pattern_matching 2 } else { 3 @@ -72,14 +80,18 @@ fn issue5504() { fn try_result_opt() -> Result { while r#try!(result_opt()).is_some() {} + //~^ redundant_pattern_matching if r#try!(result_opt()).is_some() {} + //~^ redundant_pattern_matching Ok(42) } try_result_opt(); if m!().is_some() {} + //~^ redundant_pattern_matching while m!().is_some() {} + //~^ redundant_pattern_matching } fn issue6065() { @@ -98,12 +110,16 @@ fn issue6065() { // so the following should be linted. const fn issue6067() { if Ok::(42).is_ok() {} + //~^ redundant_pattern_matching if Err::(42).is_err() {} + //~^ redundant_pattern_matching while Ok::(10).is_ok() {} + //~^ redundant_pattern_matching while Ok::(10).is_err() {} + //~^ redundant_pattern_matching Ok::(42).is_ok(); @@ -139,8 +155,10 @@ fn issue10803() { let x: Result = Ok(42); let _ = x.is_ok(); + //~^ redundant_pattern_matching let _ = x.is_err(); + //~^ redundant_pattern_matching // Don't lint let _ = matches!(x, Ok(16)); diff --git a/tests/ui/redundant_pattern_matching_result.rs b/tests/ui/redundant_pattern_matching_result.rs index 4fc65aa70b54..f2632286ea3c 100644 --- a/tests/ui/redundant_pattern_matching_result.rs +++ b/tests/ui/redundant_pattern_matching_result.rs @@ -13,14 +13,19 @@ fn main() { let result: Result = Err(5); if let Ok(_) = &result {} + //~^ redundant_pattern_matching if let Ok(_) = Ok::(42) {} + //~^ redundant_pattern_matching if let Err(_) = Err::(42) {} + //~^ redundant_pattern_matching while let Ok(_) = Ok::(10) {} + //~^ redundant_pattern_matching while let Err(_) = Ok::(10) {} + //~^ redundant_pattern_matching if Ok::(42).is_ok() {} @@ -31,26 +36,31 @@ fn main() { } match Ok::(42) { + //~^ redundant_pattern_matching Ok(_) => true, Err(_) => false, }; match Ok::(42) { + //~^ redundant_pattern_matching Ok(_) => false, Err(_) => true, }; match Err::(42) { + //~^ redundant_pattern_matching Ok(_) => false, Err(_) => true, }; match Err::(42) { + //~^ redundant_pattern_matching Ok(_) => true, Err(_) => false, }; let _ = if let Ok(_) = Ok::(4) { true } else { false }; + //~^ redundant_pattern_matching issue5504(); issue6067(); @@ -59,8 +69,10 @@ fn main() { issue10803(); let _ = if let Ok(_) = gen_res() { + //~^ redundant_pattern_matching 1 } else if let Err(_) = gen_res() { + //~^ redundant_pattern_matching 2 } else { 3 @@ -84,14 +96,18 @@ fn issue5504() { fn try_result_opt() -> Result { while let Some(_) = r#try!(result_opt()) {} + //~^ redundant_pattern_matching if let Some(_) = r#try!(result_opt()) {} + //~^ redundant_pattern_matching Ok(42) } try_result_opt(); if let Some(_) = m!() {} + //~^ redundant_pattern_matching while let Some(_) = m!() {} + //~^ redundant_pattern_matching } fn issue6065() { @@ -110,19 +126,25 @@ fn issue6065() { // so the following should be linted. const fn issue6067() { if let Ok(_) = Ok::(42) {} + //~^ redundant_pattern_matching if let Err(_) = Err::(42) {} + //~^ redundant_pattern_matching while let Ok(_) = Ok::(10) {} + //~^ redundant_pattern_matching while let Err(_) = Ok::(10) {} + //~^ redundant_pattern_matching match Ok::(42) { + //~^ redundant_pattern_matching Ok(_) => true, Err(_) => false, }; match Err::(42) { + //~^ redundant_pattern_matching Ok(_) => false, Err(_) => true, }; @@ -133,21 +155,25 @@ fn issue10726() { let x: Result = Ok(42); match x { + //~^ redundant_pattern_matching Ok(_) => true, _ => false, }; match x { + //~^ redundant_pattern_matching Ok(_) => false, _ => true, }; match x { + //~^ redundant_pattern_matching Err(_) => true, _ => false, }; match x { + //~^ redundant_pattern_matching Err(_) => false, _ => true, }; @@ -169,8 +195,10 @@ fn issue10803() { let x: Result = Ok(42); let _ = matches!(x, Ok(_)); + //~^ redundant_pattern_matching let _ = matches!(x, Err(_)); + //~^ redundant_pattern_matching // Don't lint let _ = matches!(x, Ok(16)); diff --git a/tests/ui/redundant_pattern_matching_result.stderr b/tests/ui/redundant_pattern_matching_result.stderr index 991e6225ecb6..4f78b95356c2 100644 --- a/tests/ui/redundant_pattern_matching_result.stderr +++ b/tests/ui/redundant_pattern_matching_result.stderr @@ -8,193 +8,203 @@ LL | if let Ok(_) = &result {} = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:17:12 + --> tests/ui/redundant_pattern_matching_result.rs:18:12 | LL | if let Ok(_) = Ok::(42) {} | -------^^^^^--------------------- help: try: `if Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:19:12 + --> tests/ui/redundant_pattern_matching_result.rs:21:12 | LL | if let Err(_) = Err::(42) {} | -------^^^^^^---------------------- help: try: `if Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:21:15 + --> tests/ui/redundant_pattern_matching_result.rs:24:15 | LL | while let Ok(_) = Ok::(10) {} | ----------^^^^^--------------------- help: try: `while Ok::(10).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:23:15 + --> tests/ui/redundant_pattern_matching_result.rs:27:15 | LL | while let Err(_) = Ok::(10) {} | ----------^^^^^^--------------------- help: try: `while Ok::(10).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:33:5 + --> tests/ui/redundant_pattern_matching_result.rs:38:5 | LL | / match Ok::(42) { +LL | | LL | | Ok(_) => true, LL | | Err(_) => false, LL | | }; | |_____^ help: try: `Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:38:5 + --> tests/ui/redundant_pattern_matching_result.rs:44:5 | LL | / match Ok::(42) { +LL | | LL | | Ok(_) => false, LL | | Err(_) => true, LL | | }; | |_____^ help: try: `Ok::(42).is_err()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:43:5 + --> tests/ui/redundant_pattern_matching_result.rs:50:5 | LL | / match Err::(42) { +LL | | LL | | Ok(_) => false, LL | | Err(_) => true, LL | | }; | |_____^ help: try: `Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:48:5 + --> tests/ui/redundant_pattern_matching_result.rs:56:5 | LL | / match Err::(42) { +LL | | LL | | Ok(_) => true, LL | | Err(_) => false, LL | | }; | |_____^ help: try: `Err::(42).is_ok()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:53:20 + --> tests/ui/redundant_pattern_matching_result.rs:62:20 | LL | let _ = if let Ok(_) = Ok::(4) { true } else { false }; | -------^^^^^--------------------- help: try: `if Ok::(4).is_ok()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:61:20 + --> tests/ui/redundant_pattern_matching_result.rs:71:20 | LL | let _ = if let Ok(_) = gen_res() { | -------^^^^^------------ help: try: `if gen_res().is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:63:19 + --> tests/ui/redundant_pattern_matching_result.rs:74:19 | LL | } else if let Err(_) = gen_res() { | -------^^^^^^------------ help: try: `if gen_res().is_err()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_result.rs:86:19 + --> tests/ui/redundant_pattern_matching_result.rs:98:19 | LL | while let Some(_) = r#try!(result_opt()) {} | ----------^^^^^^^----------------------- help: try: `while r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_result.rs:87:16 + --> tests/ui/redundant_pattern_matching_result.rs:100:16 | LL | if let Some(_) = r#try!(result_opt()) {} | -------^^^^^^^----------------------- help: try: `if r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_result.rs:93:12 + --> tests/ui/redundant_pattern_matching_result.rs:107:12 | LL | if let Some(_) = m!() {} | -------^^^^^^^------- help: try: `if m!().is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_result.rs:94:15 + --> tests/ui/redundant_pattern_matching_result.rs:109:15 | LL | while let Some(_) = m!() {} | ----------^^^^^^^------- help: try: `while m!().is_some()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:112:12 + --> tests/ui/redundant_pattern_matching_result.rs:128:12 | LL | if let Ok(_) = Ok::(42) {} | -------^^^^^--------------------- help: try: `if Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:114:12 + --> tests/ui/redundant_pattern_matching_result.rs:131:12 | LL | if let Err(_) = Err::(42) {} | -------^^^^^^---------------------- help: try: `if Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:116:15 + --> tests/ui/redundant_pattern_matching_result.rs:134:15 | LL | while let Ok(_) = Ok::(10) {} | ----------^^^^^--------------------- help: try: `while Ok::(10).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:118:15 + --> tests/ui/redundant_pattern_matching_result.rs:137:15 | LL | while let Err(_) = Ok::(10) {} | ----------^^^^^^--------------------- help: try: `while Ok::(10).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:120:5 + --> tests/ui/redundant_pattern_matching_result.rs:140:5 | LL | / match Ok::(42) { +LL | | LL | | Ok(_) => true, LL | | Err(_) => false, LL | | }; | |_____^ help: try: `Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:125:5 + --> tests/ui/redundant_pattern_matching_result.rs:146:5 | LL | / match Err::(42) { +LL | | LL | | Ok(_) => false, LL | | Err(_) => true, LL | | }; | |_____^ help: try: `Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:135:5 + --> tests/ui/redundant_pattern_matching_result.rs:157:5 | LL | / match x { +LL | | LL | | Ok(_) => true, LL | | _ => false, LL | | }; | |_____^ help: try: `x.is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:140:5 + --> tests/ui/redundant_pattern_matching_result.rs:163:5 | LL | / match x { +LL | | LL | | Ok(_) => false, LL | | _ => true, LL | | }; | |_____^ help: try: `x.is_err()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:145:5 + --> tests/ui/redundant_pattern_matching_result.rs:169:5 | LL | / match x { +LL | | LL | | Err(_) => true, LL | | _ => false, LL | | }; | |_____^ help: try: `x.is_err()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:150:5 + --> tests/ui/redundant_pattern_matching_result.rs:175:5 | LL | / match x { +LL | | LL | | Err(_) => false, LL | | _ => true, LL | | }; | |_____^ help: try: `x.is_ok()` error: redundant pattern matching, consider using `is_ok()` - --> tests/ui/redundant_pattern_matching_result.rs:171:13 + --> tests/ui/redundant_pattern_matching_result.rs:197:13 | LL | let _ = matches!(x, Ok(_)); | ^^^^^^^^^^^^^^^^^^ help: try: `x.is_ok()` error: redundant pattern matching, consider using `is_err()` - --> tests/ui/redundant_pattern_matching_result.rs:173:13 + --> tests/ui/redundant_pattern_matching_result.rs:200:13 | LL | let _ = matches!(x, Err(_)); | ^^^^^^^^^^^^^^^^^^^ help: try: `x.is_err()` diff --git a/tests/ui/redundant_pub_crate.fixed b/tests/ui/redundant_pub_crate.fixed index 8882a4d50a5f..2072282bd2c3 100644 --- a/tests/ui/redundant_pub_crate.fixed +++ b/tests/ui/redundant_pub_crate.fixed @@ -5,24 +5,29 @@ mod m1 { fn f() {} pub fn g() {} // private due to m1 + //~^ redundant_pub_crate pub fn h() {} mod m1_1 { fn f() {} pub fn g() {} // private due to m1_1 and m1 + //~^ redundant_pub_crate pub fn h() {} } pub mod m1_2 { + //~^ redundant_pub_crate //:^ private due to m1 fn f() {} pub fn g() {} // private due to m1_2 and m1 + //~^ redundant_pub_crate pub fn h() {} } pub mod m1_3 { fn f() {} pub fn g() {} // private due to m1 + //~^ redundant_pub_crate pub fn h() {} } } @@ -30,24 +35,29 @@ mod m1 { pub(crate) mod m2 { fn f() {} pub fn g() {} // already crate visible due to m2 + //~^ redundant_pub_crate pub fn h() {} mod m2_1 { fn f() {} pub fn g() {} // private due to m2_1 + //~^ redundant_pub_crate pub fn h() {} } pub mod m2_2 { + //~^ redundant_pub_crate //:^ already crate visible due to m2 fn f() {} pub fn g() {} // already crate visible due to m2_2 and m2 + //~^ redundant_pub_crate pub fn h() {} } pub mod m2_3 { fn f() {} pub fn g() {} // already crate visible due to m2 + //~^ redundant_pub_crate pub fn h() {} } } @@ -60,6 +70,7 @@ pub mod m3 { mod m3_1 { fn f() {} pub fn g() {} // private due to m3_1 + //~^ redundant_pub_crate pub fn h() {} } @@ -67,6 +78,7 @@ pub mod m3 { //:^ ok fn f() {} pub fn g() {} // already crate visible due to m3_2 + //~^ redundant_pub_crate pub fn h() {} } @@ -80,18 +92,22 @@ pub mod m3 { mod m4 { fn f() {} pub fn g() {} // private: not re-exported by `pub use m4::*` + //~^ redundant_pub_crate pub fn h() {} mod m4_1 { fn f() {} pub fn g() {} // private due to m4_1 + //~^ redundant_pub_crate pub fn h() {} } pub mod m4_2 { + //~^ redundant_pub_crate //:^ private: not re-exported by `pub use m4::*` fn f() {} pub fn g() {} // private due to m4_2 + //~^ redundant_pub_crate pub fn h() {} } diff --git a/tests/ui/redundant_pub_crate.rs b/tests/ui/redundant_pub_crate.rs index 5c8cab9be161..d8eaa8cdbc69 100644 --- a/tests/ui/redundant_pub_crate.rs +++ b/tests/ui/redundant_pub_crate.rs @@ -5,24 +5,29 @@ mod m1 { fn f() {} pub(crate) fn g() {} // private due to m1 + //~^ redundant_pub_crate pub fn h() {} mod m1_1 { fn f() {} pub(crate) fn g() {} // private due to m1_1 and m1 + //~^ redundant_pub_crate pub fn h() {} } pub(crate) mod m1_2 { + //~^ redundant_pub_crate //:^ private due to m1 fn f() {} pub(crate) fn g() {} // private due to m1_2 and m1 + //~^ redundant_pub_crate pub fn h() {} } pub mod m1_3 { fn f() {} pub(crate) fn g() {} // private due to m1 + //~^ redundant_pub_crate pub fn h() {} } } @@ -30,24 +35,29 @@ mod m1 { pub(crate) mod m2 { fn f() {} pub(crate) fn g() {} // already crate visible due to m2 + //~^ redundant_pub_crate pub fn h() {} mod m2_1 { fn f() {} pub(crate) fn g() {} // private due to m2_1 + //~^ redundant_pub_crate pub fn h() {} } pub(crate) mod m2_2 { + //~^ redundant_pub_crate //:^ already crate visible due to m2 fn f() {} pub(crate) fn g() {} // already crate visible due to m2_2 and m2 + //~^ redundant_pub_crate pub fn h() {} } pub mod m2_3 { fn f() {} pub(crate) fn g() {} // already crate visible due to m2 + //~^ redundant_pub_crate pub fn h() {} } } @@ -60,6 +70,7 @@ pub mod m3 { mod m3_1 { fn f() {} pub(crate) fn g() {} // private due to m3_1 + //~^ redundant_pub_crate pub fn h() {} } @@ -67,6 +78,7 @@ pub mod m3 { //:^ ok fn f() {} pub(crate) fn g() {} // already crate visible due to m3_2 + //~^ redundant_pub_crate pub fn h() {} } @@ -80,18 +92,22 @@ pub mod m3 { mod m4 { fn f() {} pub(crate) fn g() {} // private: not re-exported by `pub use m4::*` + //~^ redundant_pub_crate pub fn h() {} mod m4_1 { fn f() {} pub(crate) fn g() {} // private due to m4_1 + //~^ redundant_pub_crate pub fn h() {} } pub(crate) mod m4_2 { + //~^ redundant_pub_crate //:^ private: not re-exported by `pub use m4::*` fn f() {} pub(crate) fn g() {} // private due to m4_2 + //~^ redundant_pub_crate pub fn h() {} } diff --git a/tests/ui/redundant_pub_crate.stderr b/tests/ui/redundant_pub_crate.stderr index 699e19b1abcf..90be83d948bd 100644 --- a/tests/ui/redundant_pub_crate.stderr +++ b/tests/ui/redundant_pub_crate.stderr @@ -10,7 +10,7 @@ LL | pub(crate) fn g() {} // private due to m1 = help: to override `-D warnings` add `#[allow(clippy::redundant_pub_crate)]` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:12:9 + --> tests/ui/redundant_pub_crate.rs:13:9 | LL | pub(crate) fn g() {} // private due to m1_1 and m1 | ----------^^^^^ @@ -18,7 +18,7 @@ LL | pub(crate) fn g() {} // private due to m1_1 and m1 | help: consider using: `pub` error: pub(crate) module inside private module - --> tests/ui/redundant_pub_crate.rs:16:5 + --> tests/ui/redundant_pub_crate.rs:18:5 | LL | pub(crate) mod m1_2 { | ----------^^^^^^^^^ @@ -26,7 +26,7 @@ LL | pub(crate) mod m1_2 { | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:19:9 + --> tests/ui/redundant_pub_crate.rs:22:9 | LL | pub(crate) fn g() {} // private due to m1_2 and m1 | ----------^^^^^ @@ -34,7 +34,7 @@ LL | pub(crate) fn g() {} // private due to m1_2 and m1 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:25:9 + --> tests/ui/redundant_pub_crate.rs:29:9 | LL | pub(crate) fn g() {} // private due to m1 | ----------^^^^^ @@ -42,7 +42,7 @@ LL | pub(crate) fn g() {} // private due to m1 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:32:5 + --> tests/ui/redundant_pub_crate.rs:37:5 | LL | pub(crate) fn g() {} // already crate visible due to m2 | ----------^^^^^ @@ -50,7 +50,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m2 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:37:9 + --> tests/ui/redundant_pub_crate.rs:43:9 | LL | pub(crate) fn g() {} // private due to m2_1 | ----------^^^^^ @@ -58,7 +58,7 @@ LL | pub(crate) fn g() {} // private due to m2_1 | help: consider using: `pub` error: pub(crate) module inside private module - --> tests/ui/redundant_pub_crate.rs:41:5 + --> tests/ui/redundant_pub_crate.rs:48:5 | LL | pub(crate) mod m2_2 { | ----------^^^^^^^^^ @@ -66,7 +66,7 @@ LL | pub(crate) mod m2_2 { | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:44:9 + --> tests/ui/redundant_pub_crate.rs:52:9 | LL | pub(crate) fn g() {} // already crate visible due to m2_2 and m2 | ----------^^^^^ @@ -74,7 +74,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m2_2 and m2 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:50:9 + --> tests/ui/redundant_pub_crate.rs:59:9 | LL | pub(crate) fn g() {} // already crate visible due to m2 | ----------^^^^^ @@ -82,7 +82,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m2 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:62:9 + --> tests/ui/redundant_pub_crate.rs:72:9 | LL | pub(crate) fn g() {} // private due to m3_1 | ----------^^^^^ @@ -90,7 +90,7 @@ LL | pub(crate) fn g() {} // private due to m3_1 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:69:9 + --> tests/ui/redundant_pub_crate.rs:80:9 | LL | pub(crate) fn g() {} // already crate visible due to m3_2 | ----------^^^^^ @@ -98,7 +98,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m3_2 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:82:5 + --> tests/ui/redundant_pub_crate.rs:94:5 | LL | pub(crate) fn g() {} // private: not re-exported by `pub use m4::*` | ----------^^^^^ @@ -106,7 +106,7 @@ LL | pub(crate) fn g() {} // private: not re-exported by `pub use m4::*` | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:87:9 + --> tests/ui/redundant_pub_crate.rs:100:9 | LL | pub(crate) fn g() {} // private due to m4_1 | ----------^^^^^ @@ -114,7 +114,7 @@ LL | pub(crate) fn g() {} // private due to m4_1 | help: consider using: `pub` error: pub(crate) module inside private module - --> tests/ui/redundant_pub_crate.rs:91:5 + --> tests/ui/redundant_pub_crate.rs:105:5 | LL | pub(crate) mod m4_2 { | ----------^^^^^^^^^ @@ -122,7 +122,7 @@ LL | pub(crate) mod m4_2 { | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:94:9 + --> tests/ui/redundant_pub_crate.rs:109:9 | LL | pub(crate) fn g() {} // private due to m4_2 | ----------^^^^^ diff --git a/tests/ui/redundant_slicing.fixed b/tests/ui/redundant_slicing.fixed index a4c035ba8407..d640de71e446 100644 --- a/tests/ui/redundant_slicing.fixed +++ b/tests/ui/redundant_slicing.fixed @@ -6,10 +6,12 @@ use std::io::Read; fn main() { let slice: &[u32] = &[0]; let _ = slice; // Redundant slice + //~^ redundant_slicing let v = vec![0]; let _ = &v[..]; // Ok, results in `&[_]` let _ = (&*v); // Outer borrow is redundant + //~^ redundant_slicing static S: &[u8] = &[0, 1, 2]; let _ = &mut &S[..]; // Ok, re-borrows slice @@ -27,6 +29,7 @@ fn main() { }; } let _ = slice; + //~^ redundant_slicing macro_rules! m2 { ($e:expr) => { diff --git a/tests/ui/redundant_slicing.rs b/tests/ui/redundant_slicing.rs index 67fe702acf54..34596cf84799 100644 --- a/tests/ui/redundant_slicing.rs +++ b/tests/ui/redundant_slicing.rs @@ -6,10 +6,12 @@ use std::io::Read; fn main() { let slice: &[u32] = &[0]; let _ = &slice[..]; // Redundant slice + //~^ redundant_slicing let v = vec![0]; let _ = &v[..]; // Ok, results in `&[_]` let _ = &(&*v)[..]; // Outer borrow is redundant + //~^ redundant_slicing static S: &[u8] = &[0, 1, 2]; let _ = &mut &S[..]; // Ok, re-borrows slice @@ -27,6 +29,7 @@ fn main() { }; } let _ = &m!(slice)[..]; + //~^ redundant_slicing macro_rules! m2 { ($e:expr) => { diff --git a/tests/ui/redundant_slicing.stderr b/tests/ui/redundant_slicing.stderr index 269a597b3226..47a61b41e978 100644 --- a/tests/ui/redundant_slicing.stderr +++ b/tests/ui/redundant_slicing.stderr @@ -8,13 +8,13 @@ LL | let _ = &slice[..]; // Redundant slice = help: to override `-D warnings` add `#[allow(clippy::redundant_slicing)]` error: redundant slicing of the whole range - --> tests/ui/redundant_slicing.rs:12:13 + --> tests/ui/redundant_slicing.rs:13:13 | LL | let _ = &(&*v)[..]; // Outer borrow is redundant | ^^^^^^^^^^ help: use the original value instead: `(&*v)` error: redundant slicing of the whole range - --> tests/ui/redundant_slicing.rs:29:13 + --> tests/ui/redundant_slicing.rs:31:13 | LL | let _ = &m!(slice)[..]; | ^^^^^^^^^^^^^^ help: use the original value instead: `slice` diff --git a/tests/ui/redundant_static_lifetimes.fixed b/tests/ui/redundant_static_lifetimes.fixed index 3d1c78bd12d9..86c6ca17eb20 100644 --- a/tests/ui/redundant_static_lifetimes.fixed +++ b/tests/ui/redundant_static_lifetimes.fixed @@ -6,40 +6,57 @@ struct Foo; const VAR_ONE: &str = "Test constant #1"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes const VAR_TWO: &str = "Test constant #2"; // This line should not raise a warning. const VAR_THREE: &[&str] = &["one", "two"]; // ERROR: Consider removing 'static +//~^ redundant_static_lifetimes const VAR_FOUR: (&str, (&str, &str), &str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static +//~^ redundant_static_lifetimes +//~| redundant_static_lifetimes const VAR_SIX: &u8 = &5; +//~^ redundant_static_lifetimes const VAR_HEIGHT: &Foo = &Foo {}; +//~^ redundant_static_lifetimes const VAR_SLICE: &[u8] = b"Test constant #1"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes const VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes const VAR_ARRAY: &[u8; 1] = b"T"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static STATIC_VAR_ONE: &str = "Test static #1"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static STATIC_VAR_TWO: &str = "Test static #2"; // This line should not raise a warning. static STATIC_VAR_THREE: &[&str] = &["one", "two"]; // ERROR: Consider removing 'static +//~^ redundant_static_lifetimes static STATIC_VAR_SIX: &u8 = &5; +//~^ redundant_static_lifetimes static STATIC_VAR_HEIGHT: &Foo = &Foo {}; +//~^ redundant_static_lifetimes static STATIC_VAR_SLICE: &[u8] = b"Test static #3"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static STATIC_VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static STATIC_VAR_ARRAY: &[u8; 1] = b"T"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static mut STATIC_MUT_SLICE: &mut [u32] = &mut [0]; +//~^ redundant_static_lifetimes fn main() { let false_positive: &'static str = "test"; @@ -69,4 +86,5 @@ fn msrv_1_16() { #[clippy::msrv = "1.17"] fn msrv_1_17() { static V: &u8 = &17; + //~^ redundant_static_lifetimes } diff --git a/tests/ui/redundant_static_lifetimes.rs b/tests/ui/redundant_static_lifetimes.rs index 5932f14b8d9a..6fefe6c232d2 100644 --- a/tests/ui/redundant_static_lifetimes.rs +++ b/tests/ui/redundant_static_lifetimes.rs @@ -6,40 +6,57 @@ struct Foo; const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes const VAR_TWO: &str = "Test constant #2"; // This line should not raise a warning. const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static +//~^ redundant_static_lifetimes const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static +//~^ redundant_static_lifetimes +//~| redundant_static_lifetimes const VAR_SIX: &'static u8 = &5; +//~^ redundant_static_lifetimes const VAR_HEIGHT: &'static Foo = &Foo {}; +//~^ redundant_static_lifetimes const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static STATIC_VAR_TWO: &str = "Test static #2"; // This line should not raise a warning. static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static +//~^ redundant_static_lifetimes static STATIC_VAR_SIX: &'static u8 = &5; +//~^ redundant_static_lifetimes static STATIC_VAR_HEIGHT: &'static Foo = &Foo {}; +//~^ redundant_static_lifetimes static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. +//~^ redundant_static_lifetimes static mut STATIC_MUT_SLICE: &'static mut [u32] = &mut [0]; +//~^ redundant_static_lifetimes fn main() { let false_positive: &'static str = "test"; @@ -69,4 +86,5 @@ fn msrv_1_16() { #[clippy::msrv = "1.17"] fn msrv_1_17() { static V: &'static u8 = &17; + //~^ redundant_static_lifetimes } diff --git a/tests/ui/redundant_static_lifetimes.stderr b/tests/ui/redundant_static_lifetimes.stderr index 48871eba2dc7..955882703955 100644 --- a/tests/ui/redundant_static_lifetimes.stderr +++ b/tests/ui/redundant_static_lifetimes.stderr @@ -8,103 +8,103 @@ LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removi = help: to override `-D warnings` add `#[allow(clippy::redundant_static_lifetimes)]` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:12:21 + --> tests/ui/redundant_static_lifetimes.rs:13:21 | LL | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:14:32 + --> tests/ui/redundant_static_lifetimes.rs:16:32 | LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:14:47 + --> tests/ui/redundant_static_lifetimes.rs:16:47 | LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:16:17 + --> tests/ui/redundant_static_lifetimes.rs:20:17 | LL | const VAR_SIX: &'static u8 = &5; | -^^^^^^^--- help: consider removing `'static`: `&u8` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:18:20 + --> tests/ui/redundant_static_lifetimes.rs:23:20 | LL | const VAR_HEIGHT: &'static Foo = &Foo {}; | -^^^^^^^---- help: consider removing `'static`: `&Foo` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:20:19 + --> tests/ui/redundant_static_lifetimes.rs:26:19 | LL | const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR: Consider removing 'static. | -^^^^^^^----- help: consider removing `'static`: `&[u8]` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:22:19 + --> tests/ui/redundant_static_lifetimes.rs:29:19 | LL | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. | -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:24:19 + --> tests/ui/redundant_static_lifetimes.rs:32:19 | LL | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. | -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:26:25 + --> tests/ui/redundant_static_lifetimes.rs:35:25 | LL | static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR: Consider removing 'static. | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:30:29 + --> tests/ui/redundant_static_lifetimes.rs:40:29 | LL | static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:32:25 + --> tests/ui/redundant_static_lifetimes.rs:43:25 | LL | static STATIC_VAR_SIX: &'static u8 = &5; | -^^^^^^^--- help: consider removing `'static`: `&u8` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:34:28 + --> tests/ui/redundant_static_lifetimes.rs:46:28 | LL | static STATIC_VAR_HEIGHT: &'static Foo = &Foo {}; | -^^^^^^^---- help: consider removing `'static`: `&Foo` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:36:27 + --> tests/ui/redundant_static_lifetimes.rs:49:27 | LL | static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR: Consider removing 'static. | -^^^^^^^----- help: consider removing `'static`: `&[u8]` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:38:27 + --> tests/ui/redundant_static_lifetimes.rs:52:27 | LL | static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. | -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:40:27 + --> tests/ui/redundant_static_lifetimes.rs:55:27 | LL | static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. | -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:42:31 + --> tests/ui/redundant_static_lifetimes.rs:58:31 | LL | static mut STATIC_MUT_SLICE: &'static mut [u32] = &mut [0]; | -^^^^^^^---------- help: consider removing `'static`: `&mut [u32]` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes.rs:71:16 + --> tests/ui/redundant_static_lifetimes.rs:88:16 | LL | static V: &'static u8 = &17; | -^^^^^^^--- help: consider removing `'static`: `&u8` diff --git a/tests/ui/redundant_static_lifetimes_multiple.rs b/tests/ui/redundant_static_lifetimes_multiple.rs index bfcab420b1f4..02f3829d8c03 100644 --- a/tests/ui/redundant_static_lifetimes_multiple.rs +++ b/tests/ui/redundant_static_lifetimes_multiple.rs @@ -2,24 +2,34 @@ // these are rustfixable, but run-rustfix tests cannot handle them const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static -//~^ ERROR: constants have by default a `'static` lifetime -//~| NOTE: `-D clippy::redundant-static-lifetimes` implied by `-D warnings` -//~| ERROR: constants have by default a `'static` lifetime +//~^ redundant_static_lifetimes +//~| redundant_static_lifetimes + + + const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; -//~^ ERROR: constants have by default a `'static` lifetime -//~| ERROR: constants have by default a `'static` lifetime +//~^ redundant_static_lifetimes +//~| redundant_static_lifetimes + + static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static -//~^ ERROR: statics have by default a `'static` lifetime -//~| ERROR: statics have by default a `'static` lifetime +//~^ redundant_static_lifetimes +//~| redundant_static_lifetimes + + static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static -//~^ ERROR: statics have by default a `'static` lifetime -//~| ERROR: statics have by default a `'static` lifetime +//~^ redundant_static_lifetimes +//~| redundant_static_lifetimes + + static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; -//~^ ERROR: statics have by default a `'static` lifetime -//~| ERROR: statics have by default a `'static` lifetime +//~^ redundant_static_lifetimes +//~| redundant_static_lifetimes + + fn main() {} diff --git a/tests/ui/redundant_static_lifetimes_multiple.stderr b/tests/ui/redundant_static_lifetimes_multiple.stderr index 330703d9eff1..486a23b06089 100644 --- a/tests/ui/redundant_static_lifetimes_multiple.stderr +++ b/tests/ui/redundant_static_lifetimes_multiple.stderr @@ -14,49 +14,49 @@ LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; | -^^^^^^^---- help: consider removing `'static`: `&str` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:9:29 + --> tests/ui/redundant_static_lifetimes_multiple.rs:11:29 | LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; | -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:9:39 + --> tests/ui/redundant_static_lifetimes_multiple.rs:11:39 | LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:13:40 + --> tests/ui/redundant_static_lifetimes_multiple.rs:17:40 | LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:13:55 + --> tests/ui/redundant_static_lifetimes_multiple.rs:17:55 | LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:17:26 + --> tests/ui/redundant_static_lifetimes_multiple.rs:23:26 | LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static | -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:17:38 + --> tests/ui/redundant_static_lifetimes_multiple.rs:23:38 | LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:21:37 + --> tests/ui/redundant_static_lifetimes_multiple.rs:29:37 | LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; | -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:21:47 + --> tests/ui/redundant_static_lifetimes_multiple.rs:29:47 | LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; | -^^^^^^^---- help: consider removing `'static`: `&str` diff --git a/tests/ui/redundant_type_annotations.rs b/tests/ui/redundant_type_annotations.rs index dc9b073ffba8..5023ec7ee576 100644 --- a/tests/ui/redundant_type_annotations.rs +++ b/tests/ui/redundant_type_annotations.rs @@ -79,12 +79,15 @@ impl Pie { // Everything here should be lint let v: u32 = self.return_an_int(); - //~^ ERROR: redundant type annotation - //~| NOTE: `-D clippy::redundant-type-annotations` implied by `-D warnings` + //~^ redundant_type_annotations + + let v: &u32 = self.return_a_ref(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let v: &Slice = self.return_a_ref_to_struct(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + } } @@ -157,50 +160,64 @@ fn test_functions() { // Everything here should be lint let _return: String = return_a_string(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _return: Pie = return_a_struct(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _return: Pizza = return_an_enum(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _return: u32 = return_an_int(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _return: String = String::new(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let new_pie: Pie = Pie::new(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _return: u32 = new_pie.return_an_int(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _return: u32 = Pie::associated_return_an_int(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _return: String = Pie::associated_return_a_string(); - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + } fn test_simple_types() { // Everything here should be lint let _var: u32 = u32::MAX; - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _var: u32 = 5_u32; - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _var: &str = "test"; - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _var: &[u8; 4] = b"test"; - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + let _var: bool = false; - //~^ ERROR: redundant type annotation + //~^ redundant_type_annotations + } fn issue12212() { diff --git a/tests/ui/redundant_type_annotations.stderr b/tests/ui/redundant_type_annotations.stderr index 4768f4d3c57c..de78ad5e4b48 100644 --- a/tests/ui/redundant_type_annotations.stderr +++ b/tests/ui/redundant_type_annotations.stderr @@ -8,97 +8,97 @@ LL | let v: u32 = self.return_an_int(); = help: to override `-D warnings` add `#[allow(clippy::redundant_type_annotations)]` error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:84:9 + --> tests/ui/redundant_type_annotations.rs:85:9 | LL | let v: &u32 = self.return_a_ref(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:86:9 + --> tests/ui/redundant_type_annotations.rs:88:9 | LL | let v: &Slice = self.return_a_ref_to_struct(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:159:5 + --> tests/ui/redundant_type_annotations.rs:162:5 | LL | let _return: String = return_a_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:162:5 + --> tests/ui/redundant_type_annotations.rs:166:5 | LL | let _return: Pie = return_a_struct(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:165:5 + --> tests/ui/redundant_type_annotations.rs:170:5 | LL | let _return: Pizza = return_an_enum(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:168:5 + --> tests/ui/redundant_type_annotations.rs:174:5 | LL | let _return: u32 = return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:171:5 + --> tests/ui/redundant_type_annotations.rs:178:5 | LL | let _return: String = String::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:174:5 + --> tests/ui/redundant_type_annotations.rs:182:5 | LL | let new_pie: Pie = Pie::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:177:5 + --> tests/ui/redundant_type_annotations.rs:186:5 | LL | let _return: u32 = new_pie.return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:180:5 + --> tests/ui/redundant_type_annotations.rs:190:5 | LL | let _return: u32 = Pie::associated_return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:183:5 + --> tests/ui/redundant_type_annotations.rs:194:5 | LL | let _return: String = Pie::associated_return_a_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:190:5 + --> tests/ui/redundant_type_annotations.rs:202:5 | LL | let _var: u32 = u32::MAX; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:193:5 + --> tests/ui/redundant_type_annotations.rs:206:5 | LL | let _var: u32 = 5_u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:196:5 + --> tests/ui/redundant_type_annotations.rs:210:5 | LL | let _var: &str = "test"; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:199:5 + --> tests/ui/redundant_type_annotations.rs:214:5 | LL | let _var: &[u8; 4] = b"test"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:202:5 + --> tests/ui/redundant_type_annotations.rs:218:5 | LL | let _var: bool = false; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/ref_as_ptr.fixed b/tests/ui/ref_as_ptr.fixed index 6048267092f1..ce144508581e 100644 --- a/tests/ui/ref_as_ptr.fixed +++ b/tests/ui/ref_as_ptr.fixed @@ -5,53 +5,86 @@ fn f(_: T) {} fn main() { f(std::ptr::from_ref(&1u8)); + //~^ ref_as_ptr f(std::ptr::from_ref::(&2u32)); + //~^ ref_as_ptr f(std::ptr::from_ref::(&3.0f64)); + //~^ ref_as_ptr f(std::ptr::from_ref(&4) as *const f32); + //~^ ref_as_ptr f(std::ptr::from_ref::(&5.0f32) as *const u32); + //~^ ref_as_ptr f(std::ptr::from_ref(&mut 6u8)); + //~^ ref_as_ptr f(std::ptr::from_ref::(&mut 7u32)); + //~^ ref_as_ptr f(std::ptr::from_ref::(&mut 8.0f64)); + //~^ ref_as_ptr f(std::ptr::from_ref(&mut 9) as *const f32); + //~^ ref_as_ptr f(std::ptr::from_ref::(&mut 10.0f32) as *const u32); + //~^ ref_as_ptr f(std::ptr::from_mut(&mut 11u8)); + //~^ ref_as_ptr f(std::ptr::from_mut::(&mut 12u32)); + //~^ ref_as_ptr f(std::ptr::from_mut::(&mut 13.0f64)); + //~^ ref_as_ptr f(std::ptr::from_mut(&mut 14) as *const f32); + //~^ ref_as_ptr f(std::ptr::from_mut::(&mut 15.0f32) as *const u32); + //~^ ref_as_ptr f(std::ptr::from_ref(&1u8)); + //~^ ref_as_ptr f(std::ptr::from_ref::(&2u32)); + //~^ ref_as_ptr f(std::ptr::from_ref::(&3.0f64)); + //~^ ref_as_ptr f(std::ptr::from_ref(&4) as *const f32); + //~^ ref_as_ptr f(std::ptr::from_ref::(&5.0f32) as *const u32); + //~^ ref_as_ptr let val = 1; f(std::ptr::from_ref(&val)); + //~^ ref_as_ptr f(std::ptr::from_ref::(&val)); + //~^ ref_as_ptr f(std::ptr::from_ref(&val) as *const f32); + //~^ ref_as_ptr f(std::ptr::from_ref::(&val) as *const f64); + //~^ ref_as_ptr let mut val: u8 = 2; f(std::ptr::from_mut::(&mut val)); + //~^ ref_as_ptr f(std::ptr::from_mut(&mut val)); + //~^ ref_as_ptr f(std::ptr::from_ref::(&mut val)); + //~^ ref_as_ptr f(std::ptr::from_ref(&mut val)); + //~^ ref_as_ptr f(std::ptr::from_ref::(&mut val) as *const f64); + //~^ ref_as_ptr f::<*const Option>(std::ptr::from_ref(&mut val) as *const _); + //~^ ref_as_ptr f(std::ptr::from_ref::<[usize; 7]>(&std::array::from_fn(|i| i * i))); + //~^ ref_as_ptr f(std::ptr::from_ref::<[usize; 8]>(&mut std::array::from_fn(|i| i * i))); + //~^ ref_as_ptr f(std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i))); + //~^ ref_as_ptr let _ = &String::new() as *const _; let _ = &mut String::new() as *mut _; @@ -74,17 +107,23 @@ fn _msrv_1_76() { let mut_val = &mut 42_i32; f(std::ptr::from_ref::(val)); + //~^ ref_as_ptr f(std::ptr::from_mut::(mut_val)); + //~^ ref_as_ptr } fn foo(val: &[u8]) { f(std::ptr::from_ref(val)); + //~^ ref_as_ptr f(std::ptr::from_ref::<[u8]>(val)); + //~^ ref_as_ptr } fn bar(val: &mut str) { f(std::ptr::from_mut(val)); + //~^ ref_as_ptr f(std::ptr::from_mut::(val)); + //~^ ref_as_ptr } struct X<'a>(&'a i32); @@ -92,10 +131,12 @@ struct X<'a>(&'a i32); impl<'a> X<'a> { fn foo(&self) -> *const i64 { std::ptr::from_ref(self.0) as *const _ + //~^ ref_as_ptr } fn bar(&mut self) -> *const i64 { std::ptr::from_ref(self.0) as *const _ + //~^ ref_as_ptr } } @@ -104,13 +145,16 @@ struct Y<'a>(&'a mut i32); impl<'a> Y<'a> { fn foo(&self) -> *const i64 { std::ptr::from_ref(self.0) as *const _ + //~^ ref_as_ptr } fn bar(&mut self) -> *const i64 { std::ptr::from_ref(self.0) as *const _ + //~^ ref_as_ptr } fn baz(&mut self) -> *const i64 { std::ptr::from_mut(self.0) as *mut _ + //~^ ref_as_ptr } } diff --git a/tests/ui/ref_as_ptr.rs b/tests/ui/ref_as_ptr.rs index 7f1d59b856e4..acdff2c2ba29 100644 --- a/tests/ui/ref_as_ptr.rs +++ b/tests/ui/ref_as_ptr.rs @@ -5,53 +5,86 @@ fn f(_: T) {} fn main() { f(&1u8 as *const _); + //~^ ref_as_ptr f(&2u32 as *const u32); + //~^ ref_as_ptr f(&3.0f64 as *const f64); + //~^ ref_as_ptr f(&4 as *const _ as *const f32); + //~^ ref_as_ptr f(&5.0f32 as *const f32 as *const u32); + //~^ ref_as_ptr f(&mut 6u8 as *const _); + //~^ ref_as_ptr f(&mut 7u32 as *const u32); + //~^ ref_as_ptr f(&mut 8.0f64 as *const f64); + //~^ ref_as_ptr f(&mut 9 as *const _ as *const f32); + //~^ ref_as_ptr f(&mut 10.0f32 as *const f32 as *const u32); + //~^ ref_as_ptr f(&mut 11u8 as *mut _); + //~^ ref_as_ptr f(&mut 12u32 as *mut u32); + //~^ ref_as_ptr f(&mut 13.0f64 as *mut f64); + //~^ ref_as_ptr f(&mut 14 as *mut _ as *const f32); + //~^ ref_as_ptr f(&mut 15.0f32 as *mut f32 as *const u32); + //~^ ref_as_ptr f(&1u8 as *const _); + //~^ ref_as_ptr f(&2u32 as *const u32); + //~^ ref_as_ptr f(&3.0f64 as *const f64); + //~^ ref_as_ptr f(&4 as *const _ as *const f32); + //~^ ref_as_ptr f(&5.0f32 as *const f32 as *const u32); + //~^ ref_as_ptr let val = 1; f(&val as *const _); + //~^ ref_as_ptr f(&val as *const i32); + //~^ ref_as_ptr f(&val as *const _ as *const f32); + //~^ ref_as_ptr f(&val as *const i32 as *const f64); + //~^ ref_as_ptr let mut val: u8 = 2; f(&mut val as *mut u8); + //~^ ref_as_ptr f(&mut val as *mut _); + //~^ ref_as_ptr f(&mut val as *const u8); + //~^ ref_as_ptr f(&mut val as *const _); + //~^ ref_as_ptr f(&mut val as *const u8 as *const f64); + //~^ ref_as_ptr f::<*const Option>(&mut val as *const _ as *const _); + //~^ ref_as_ptr f(&std::array::from_fn(|i| i * i) as *const [usize; 7]); + //~^ ref_as_ptr f(&mut std::array::from_fn(|i| i * i) as *const [usize; 8]); + //~^ ref_as_ptr f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]); + //~^ ref_as_ptr let _ = &String::new() as *const _; let _ = &mut String::new() as *mut _; @@ -74,17 +107,23 @@ fn _msrv_1_76() { let mut_val = &mut 42_i32; f(val as *const i32); + //~^ ref_as_ptr f(mut_val as *mut i32); + //~^ ref_as_ptr } fn foo(val: &[u8]) { f(val as *const _); + //~^ ref_as_ptr f(val as *const [u8]); + //~^ ref_as_ptr } fn bar(val: &mut str) { f(val as *mut _); + //~^ ref_as_ptr f(val as *mut str); + //~^ ref_as_ptr } struct X<'a>(&'a i32); @@ -92,10 +131,12 @@ struct X<'a>(&'a i32); impl<'a> X<'a> { fn foo(&self) -> *const i64 { self.0 as *const _ as *const _ + //~^ ref_as_ptr } fn bar(&mut self) -> *const i64 { self.0 as *const _ as *const _ + //~^ ref_as_ptr } } @@ -104,13 +145,16 @@ struct Y<'a>(&'a mut i32); impl<'a> Y<'a> { fn foo(&self) -> *const i64 { self.0 as *const _ as *const _ + //~^ ref_as_ptr } fn bar(&mut self) -> *const i64 { self.0 as *const _ as *const _ + //~^ ref_as_ptr } fn baz(&mut self) -> *const i64 { self.0 as *mut _ as *mut _ + //~^ ref_as_ptr } } diff --git a/tests/ui/ref_as_ptr.stderr b/tests/ui/ref_as_ptr.stderr index c5e9af38aea0..79db29e596bd 100644 --- a/tests/ui/ref_as_ptr.stderr +++ b/tests/ui/ref_as_ptr.stderr @@ -8,259 +8,259 @@ LL | f(&1u8 as *const _); = help: to override `-D warnings` add `#[allow(clippy::ref_as_ptr)]` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:8:7 + --> tests/ui/ref_as_ptr.rs:9:7 | LL | f(&2u32 as *const u32); | ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&2u32)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:9:7 + --> tests/ui/ref_as_ptr.rs:11:7 | LL | f(&3.0f64 as *const f64); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&3.0f64)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:11:7 + --> tests/ui/ref_as_ptr.rs:14:7 | LL | f(&4 as *const _ as *const f32); | ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&4)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:12:7 + --> tests/ui/ref_as_ptr.rs:16:7 | LL | f(&5.0f32 as *const f32 as *const u32); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&5.0f32)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:14:7 + --> tests/ui/ref_as_ptr.rs:19:7 | LL | f(&mut 6u8 as *const _); | ^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut 6u8)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:15:7 + --> tests/ui/ref_as_ptr.rs:21:7 | LL | f(&mut 7u32 as *const u32); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&mut 7u32)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:16:7 + --> tests/ui/ref_as_ptr.rs:23:7 | LL | f(&mut 8.0f64 as *const f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&mut 8.0f64)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:18:7 + --> tests/ui/ref_as_ptr.rs:26:7 | LL | f(&mut 9 as *const _ as *const f32); | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut 9)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:19:7 + --> tests/ui/ref_as_ptr.rs:28:7 | LL | f(&mut 10.0f32 as *const f32 as *const u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&mut 10.0f32)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:21:7 + --> tests/ui/ref_as_ptr.rs:31:7 | LL | f(&mut 11u8 as *mut _); | ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(&mut 11u8)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:22:7 + --> tests/ui/ref_as_ptr.rs:33:7 | LL | f(&mut 12u32 as *mut u32); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(&mut 12u32)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:23:7 + --> tests/ui/ref_as_ptr.rs:35:7 | LL | f(&mut 13.0f64 as *mut f64); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(&mut 13.0f64)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:25:7 + --> tests/ui/ref_as_ptr.rs:38:7 | LL | f(&mut 14 as *mut _ as *const f32); | ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(&mut 14)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:26:7 + --> tests/ui/ref_as_ptr.rs:40:7 | LL | f(&mut 15.0f32 as *mut f32 as *const u32); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(&mut 15.0f32)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:28:7 + --> tests/ui/ref_as_ptr.rs:43:7 | LL | f(&1u8 as *const _); | ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&1u8)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:29:7 + --> tests/ui/ref_as_ptr.rs:45:7 | LL | f(&2u32 as *const u32); | ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&2u32)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:30:7 + --> tests/ui/ref_as_ptr.rs:47:7 | LL | f(&3.0f64 as *const f64); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&3.0f64)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:32:7 + --> tests/ui/ref_as_ptr.rs:50:7 | LL | f(&4 as *const _ as *const f32); | ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&4)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:33:7 + --> tests/ui/ref_as_ptr.rs:52:7 | LL | f(&5.0f32 as *const f32 as *const u32); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&5.0f32)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:36:7 + --> tests/ui/ref_as_ptr.rs:56:7 | LL | f(&val as *const _); | ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:37:7 + --> tests/ui/ref_as_ptr.rs:58:7 | LL | f(&val as *const i32); | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:39:7 + --> tests/ui/ref_as_ptr.rs:61:7 | LL | f(&val as *const _ as *const f32); | ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:40:7 + --> tests/ui/ref_as_ptr.rs:63:7 | LL | f(&val as *const i32 as *const f64); | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:43:7 + --> tests/ui/ref_as_ptr.rs:67:7 | LL | f(&mut val as *mut u8); | ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(&mut val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:44:7 + --> tests/ui/ref_as_ptr.rs:69:7 | LL | f(&mut val as *mut _); | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(&mut val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:46:7 + --> tests/ui/ref_as_ptr.rs:72:7 | LL | f(&mut val as *const u8); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&mut val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:47:7 + --> tests/ui/ref_as_ptr.rs:74:7 | LL | f(&mut val as *const _); | ^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:49:7 + --> tests/ui/ref_as_ptr.rs:77:7 | LL | f(&mut val as *const u8 as *const f64); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(&mut val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:50:28 + --> tests/ui/ref_as_ptr.rs:79:28 | LL | f::<*const Option>(&mut val as *const _ as *const _); | ^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:52:7 + --> tests/ui/ref_as_ptr.rs:82:7 | LL | f(&std::array::from_fn(|i| i * i) as *const [usize; 7]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[usize; 7]>(&std::array::from_fn(|i| i * i))` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:53:7 + --> tests/ui/ref_as_ptr.rs:84:7 | LL | f(&mut std::array::from_fn(|i| i * i) as *const [usize; 8]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[usize; 8]>(&mut std::array::from_fn(|i| i * i))` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:54:7 + --> tests/ui/ref_as_ptr.rs:86:7 | LL | f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i))` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:76:7 + --> tests/ui/ref_as_ptr.rs:109:7 | LL | f(val as *const i32); | ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:77:7 + --> tests/ui/ref_as_ptr.rs:111:7 | LL | f(mut_val as *mut i32); | ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(mut_val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:81:7 + --> tests/ui/ref_as_ptr.rs:116:7 | LL | f(val as *const _); | ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:82:7 + --> tests/ui/ref_as_ptr.rs:118:7 | LL | f(val as *const [u8]); | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[u8]>(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:86:7 + --> tests/ui/ref_as_ptr.rs:123:7 | LL | f(val as *mut _); | ^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:87:7 + --> tests/ui/ref_as_ptr.rs:125:7 | LL | f(val as *mut str); | ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:94:9 + --> tests/ui/ref_as_ptr.rs:133:9 | LL | self.0 as *const _ as *const _ | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:98:9 + --> tests/ui/ref_as_ptr.rs:138:9 | LL | self.0 as *const _ as *const _ | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:106:9 + --> tests/ui/ref_as_ptr.rs:147:9 | LL | self.0 as *const _ as *const _ | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:110:9 + --> tests/ui/ref_as_ptr.rs:152:9 | LL | self.0 as *const _ as *const _ | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:114:9 + --> tests/ui/ref_as_ptr.rs:157:9 | LL | self.0 as *mut _ as *mut _ | ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(self.0)` diff --git a/tests/ui/ref_binding_to_reference.rs b/tests/ui/ref_binding_to_reference.rs index 001ed3119490..55df796c41dc 100644 --- a/tests/ui/ref_binding_to_reference.rs +++ b/tests/ui/ref_binding_to_reference.rs @@ -28,15 +28,17 @@ fn main() { // Err, reference to a &String let _: &&String = match Some(&x) { Some(ref x) => x, - //~^ ERROR: this pattern creates a reference to a reference - //~| NOTE: `-D clippy::ref-binding-to-reference` implied by `-D warnings` + //~^ ref_binding_to_reference + + None => return, }; // Err, reference to a &String let _: &&String = match Some(&x) { Some(ref x) => { - //~^ ERROR: this pattern creates a reference to a reference + //~^ ref_binding_to_reference + f1(x); f1(*x); x @@ -47,20 +49,23 @@ fn main() { // Err, reference to a &String match Some(&x) { Some(ref x) => m2!(x), - //~^ ERROR: this pattern creates a reference to a reference + //~^ ref_binding_to_reference + None => return, } // Err, reference to a &String let _ = |&ref x: &&String| { - //~^ ERROR: this pattern creates a reference to a reference + //~^ ref_binding_to_reference + let _: &&String = x; }; } // Err, reference to a &String fn f2<'a>(&ref x: &&'a String) -> &'a String { - //~^ ERROR: this pattern creates a reference to a reference +//~^ ref_binding_to_reference + let _: &&String = x; *x } @@ -68,7 +73,8 @@ fn f2<'a>(&ref x: &&'a String) -> &'a String { trait T1 { // Err, reference to a &String fn f(&ref x: &&String) { - //~^ ERROR: this pattern creates a reference to a reference + //~^ ref_binding_to_reference + let _: &&String = x; } } @@ -77,7 +83,8 @@ struct S; impl T1 for S { // Err, reference to a &String fn f(&ref x: &&String) { - //~^ ERROR: this pattern creates a reference to a reference + //~^ ref_binding_to_reference + let _: &&String = x; } } diff --git a/tests/ui/ref_binding_to_reference.stderr b/tests/ui/ref_binding_to_reference.stderr index 25ab98223827..66e769ec61b3 100644 --- a/tests/ui/ref_binding_to_reference.stderr +++ b/tests/ui/ref_binding_to_reference.stderr @@ -12,7 +12,7 @@ LL | Some(x) => &x, | ~ ~~ error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:38:14 + --> tests/ui/ref_binding_to_reference.rs:39:14 | LL | Some(ref x) => { | ^^^^^ @@ -21,13 +21,14 @@ help: try | LL ~ Some(x) => { LL | +LL | LL | f1(x); LL ~ f1(x); LL ~ &x | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:49:14 + --> tests/ui/ref_binding_to_reference.rs:51:14 | LL | Some(ref x) => m2!(x), | ^^^^^ @@ -38,7 +39,7 @@ LL | Some(x) => m2!(&x), | ~ ~~ error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:55:15 + --> tests/ui/ref_binding_to_reference.rs:58:15 | LL | let _ = |&ref x: &&String| { | ^^^^^ @@ -47,11 +48,12 @@ help: try | LL ~ let _ = |&x: &&String| { LL | +LL | LL ~ let _: &&String = &x; | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:62:12 + --> tests/ui/ref_binding_to_reference.rs:66:12 | LL | fn f2<'a>(&ref x: &&'a String) -> &'a String { | ^^^^^ @@ -60,12 +62,13 @@ help: try | LL ~ fn f2<'a>(&x: &&'a String) -> &'a String { LL | +LL | LL ~ let _: &&String = &x; LL ~ x | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:70:11 + --> tests/ui/ref_binding_to_reference.rs:75:11 | LL | fn f(&ref x: &&String) { | ^^^^^ @@ -74,11 +77,12 @@ help: try | LL ~ fn f(&x: &&String) { LL | +LL | LL ~ let _: &&String = &x; | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:79:11 + --> tests/ui/ref_binding_to_reference.rs:85:11 | LL | fn f(&ref x: &&String) { | ^^^^^ @@ -87,6 +91,7 @@ help: try | LL ~ fn f(&x: &&String) { LL | +LL | LL ~ let _: &&String = &x; | diff --git a/tests/ui/ref_option/ref_option.all.fixed b/tests/ui/ref_option/ref_option.all.fixed index 47781a97c983..d7b0e13e5bb9 100644 --- a/tests/ui/ref_option/ref_option.all.fixed +++ b/tests/ui/ref_option/ref_option.all.fixed @@ -6,42 +6,59 @@ #![warn(clippy::ref_option)] fn opt_u8(a: Option<&u8>) {} +//~^ ref_option fn opt_gen(a: Option<&T>) {} +//~^ ref_option fn opt_string(a: std::option::Option<&String>) {} +//~^ ref_option fn ret_string<'a>(p: &'a str) -> Option<&'a u8> { +//~^ ref_option panic!() } fn ret_string_static() -> Option<&'static u8> { +//~^ ref_option panic!() } fn mult_string(a: Option<&String>, b: Option<&Vec>) {} +//~^ ref_option fn ret_box<'a>() -> Option<&'a Box> { +//~^ ref_option panic!() } pub fn pub_opt_string(a: Option<&String>) {} +//~[all]^ ref_option pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec>) {} +//~[all]^ ref_option pub trait PubTrait { fn pub_trait_opt(&self, a: Option<&Vec>); + //~[all]^ ref_option fn pub_trait_ret(&self) -> Option<&Vec>; + //~[all]^ ref_option } trait PrivateTrait { fn trait_opt(&self, a: Option<&String>); + //~^ ref_option fn trait_ret(&self) -> Option<&String>; + //~^ ref_option } pub struct PubStruct; impl PubStruct { pub fn pub_opt_params(&self, a: Option<&()>) {} + //~[all]^ ref_option pub fn pub_opt_ret(&self) -> Option<&String> { + //~[all]^ ref_option panic!() } fn private_opt_params(&self, a: Option<&()>) {} + //~^ ref_option fn private_opt_ret(&self) -> Option<&String> { + //~^ ref_option panic!() } } diff --git a/tests/ui/ref_option/ref_option.all.stderr b/tests/ui/ref_option/ref_option.all.stderr index b4c69ac62962..7eb425548745 100644 --- a/tests/ui/ref_option/ref_option.all.stderr +++ b/tests/ui/ref_option/ref_option.all.stderr @@ -10,7 +10,7 @@ LL | fn opt_u8(a: &Option) {} = help: to override `-D warnings` add `#[allow(clippy::ref_option)]` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:9:1 + --> tests/ui/ref_option/ref_option.rs:10:1 | LL | fn opt_gen(a: &Option) {} | ^^^^^^^^^^^^^^^^^----------^^^^ @@ -18,7 +18,7 @@ LL | fn opt_gen(a: &Option) {} | help: change this to: `Option<&T>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:10:1 + --> tests/ui/ref_option/ref_option.rs:12:1 | LL | fn opt_string(a: &std::option::Option) {} | ^^^^^^^^^^^^^^^^^----------------------------^^^^ @@ -26,29 +26,31 @@ LL | fn opt_string(a: &std::option::Option) {} | help: change this to: `std::option::Option<&String>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:11:1 + --> tests/ui/ref_option/ref_option.rs:14:1 | LL | fn ret_string<'a>(p: &'a str) -> &'a Option { | ^ -------------- help: change this to: `Option<&'a u8>` | _| | | +LL | | LL | | panic!() LL | | } | |_^ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:14:1 + --> tests/ui/ref_option/ref_option.rs:18:1 | LL | fn ret_string_static() -> &'static Option { | ^ ------------------- help: change this to: `Option<&'static u8>` | _| | | +LL | | LL | | panic!() LL | | } | |_^ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:17:1 + --> tests/ui/ref_option/ref_option.rs:22:1 | LL | fn mult_string(a: &Option, b: &Option>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,18 +61,19 @@ LL | fn mult_string(a: Option<&String>, b: Option<&Vec>) {} | ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:18:1 + --> tests/ui/ref_option/ref_option.rs:24:1 | LL | fn ret_box<'a>() -> &'a Option> { | ^ ------------------- help: change this to: `Option<&'a Box>` | _| | | +LL | | LL | | panic!() LL | | } | |_^ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:22:1 + --> tests/ui/ref_option/ref_option.rs:29:1 | LL | pub fn pub_opt_string(a: &Option) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^ @@ -78,7 +81,7 @@ LL | pub fn pub_opt_string(a: &Option) {} | help: change this to: `Option<&String>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:23:1 + --> tests/ui/ref_option/ref_option.rs:31:1 | LL | pub fn pub_mult_string(a: &Option, b: &Option>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +92,7 @@ LL | pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec>) {} | ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:26:5 + --> tests/ui/ref_option/ref_option.rs:35:5 | LL | fn pub_trait_opt(&self, a: &Option>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^^ @@ -97,7 +100,7 @@ LL | fn pub_trait_opt(&self, a: &Option>); | help: change this to: `Option<&Vec>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:27:5 + --> tests/ui/ref_option/ref_option.rs:37:5 | LL | fn pub_trait_ret(&self) -> &Option>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^ @@ -105,7 +108,7 @@ LL | fn pub_trait_ret(&self) -> &Option>; | help: change this to: `Option<&Vec>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:31:5 + --> tests/ui/ref_option/ref_option.rs:42:5 | LL | fn trait_opt(&self, a: &Option); | ^^^^^^^^^^^^^^^^^^^^^^^---------------^^ @@ -113,7 +116,7 @@ LL | fn trait_opt(&self, a: &Option); | help: change this to: `Option<&String>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:32:5 + --> tests/ui/ref_option/ref_option.rs:44:5 | LL | fn trait_ret(&self) -> &Option; | ^^^^^^^^^^^^^^^^^^^^^^^---------------^ @@ -121,7 +124,7 @@ LL | fn trait_ret(&self) -> &Option; | help: change this to: `Option<&String>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:38:5 + --> tests/ui/ref_option/ref_option.rs:51:5 | LL | pub fn pub_opt_params(&self, a: &Option<()>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^ @@ -129,18 +132,19 @@ LL | pub fn pub_opt_params(&self, a: &Option<()>) {} | help: change this to: `Option<&()>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:39:5 + --> tests/ui/ref_option/ref_option.rs:53:5 | LL | pub fn pub_opt_ret(&self) -> &Option { | ^ --------------- help: change this to: `Option<&String>` | _____| | | +LL | | LL | | panic!() LL | | } | |_____^ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:43:5 + --> tests/ui/ref_option/ref_option.rs:58:5 | LL | fn private_opt_params(&self, a: &Option<()>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^ @@ -148,12 +152,13 @@ LL | fn private_opt_params(&self, a: &Option<()>) {} | help: change this to: `Option<&()>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:44:5 + --> tests/ui/ref_option/ref_option.rs:60:5 | LL | fn private_opt_ret(&self) -> &Option { | ^ --------------- help: change this to: `Option<&String>` | _____| | | +LL | | LL | | panic!() LL | | } | |_____^ diff --git a/tests/ui/ref_option/ref_option.private.fixed b/tests/ui/ref_option/ref_option.private.fixed index 8c42556e9b0d..4036c6a08dca 100644 --- a/tests/ui/ref_option/ref_option.private.fixed +++ b/tests/ui/ref_option/ref_option.private.fixed @@ -6,42 +6,59 @@ #![warn(clippy::ref_option)] fn opt_u8(a: Option<&u8>) {} +//~^ ref_option fn opt_gen(a: Option<&T>) {} +//~^ ref_option fn opt_string(a: std::option::Option<&String>) {} +//~^ ref_option fn ret_string<'a>(p: &'a str) -> Option<&'a u8> { +//~^ ref_option panic!() } fn ret_string_static() -> Option<&'static u8> { +//~^ ref_option panic!() } fn mult_string(a: Option<&String>, b: Option<&Vec>) {} +//~^ ref_option fn ret_box<'a>() -> Option<&'a Box> { +//~^ ref_option panic!() } pub fn pub_opt_string(a: &Option) {} +//~[all]^ ref_option pub fn pub_mult_string(a: &Option, b: &Option>) {} +//~[all]^ ref_option pub trait PubTrait { fn pub_trait_opt(&self, a: &Option>); + //~[all]^ ref_option fn pub_trait_ret(&self) -> &Option>; + //~[all]^ ref_option } trait PrivateTrait { fn trait_opt(&self, a: Option<&String>); + //~^ ref_option fn trait_ret(&self) -> Option<&String>; + //~^ ref_option } pub struct PubStruct; impl PubStruct { pub fn pub_opt_params(&self, a: &Option<()>) {} + //~[all]^ ref_option pub fn pub_opt_ret(&self) -> &Option { + //~[all]^ ref_option panic!() } fn private_opt_params(&self, a: Option<&()>) {} + //~^ ref_option fn private_opt_ret(&self) -> Option<&String> { + //~^ ref_option panic!() } } diff --git a/tests/ui/ref_option/ref_option.private.stderr b/tests/ui/ref_option/ref_option.private.stderr index 17c90536da34..f608092161bb 100644 --- a/tests/ui/ref_option/ref_option.private.stderr +++ b/tests/ui/ref_option/ref_option.private.stderr @@ -10,7 +10,7 @@ LL | fn opt_u8(a: &Option) {} = help: to override `-D warnings` add `#[allow(clippy::ref_option)]` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:9:1 + --> tests/ui/ref_option/ref_option.rs:10:1 | LL | fn opt_gen(a: &Option) {} | ^^^^^^^^^^^^^^^^^----------^^^^ @@ -18,7 +18,7 @@ LL | fn opt_gen(a: &Option) {} | help: change this to: `Option<&T>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:10:1 + --> tests/ui/ref_option/ref_option.rs:12:1 | LL | fn opt_string(a: &std::option::Option) {} | ^^^^^^^^^^^^^^^^^----------------------------^^^^ @@ -26,29 +26,31 @@ LL | fn opt_string(a: &std::option::Option) {} | help: change this to: `std::option::Option<&String>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:11:1 + --> tests/ui/ref_option/ref_option.rs:14:1 | LL | fn ret_string<'a>(p: &'a str) -> &'a Option { | ^ -------------- help: change this to: `Option<&'a u8>` | _| | | +LL | | LL | | panic!() LL | | } | |_^ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:14:1 + --> tests/ui/ref_option/ref_option.rs:18:1 | LL | fn ret_string_static() -> &'static Option { | ^ ------------------- help: change this to: `Option<&'static u8>` | _| | | +LL | | LL | | panic!() LL | | } | |_^ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:17:1 + --> tests/ui/ref_option/ref_option.rs:22:1 | LL | fn mult_string(a: &Option, b: &Option>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,18 +61,19 @@ LL | fn mult_string(a: Option<&String>, b: Option<&Vec>) {} | ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:18:1 + --> tests/ui/ref_option/ref_option.rs:24:1 | LL | fn ret_box<'a>() -> &'a Option> { | ^ ------------------- help: change this to: `Option<&'a Box>` | _| | | +LL | | LL | | panic!() LL | | } | |_^ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:31:5 + --> tests/ui/ref_option/ref_option.rs:42:5 | LL | fn trait_opt(&self, a: &Option); | ^^^^^^^^^^^^^^^^^^^^^^^---------------^^ @@ -78,7 +81,7 @@ LL | fn trait_opt(&self, a: &Option); | help: change this to: `Option<&String>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:32:5 + --> tests/ui/ref_option/ref_option.rs:44:5 | LL | fn trait_ret(&self) -> &Option; | ^^^^^^^^^^^^^^^^^^^^^^^---------------^ @@ -86,7 +89,7 @@ LL | fn trait_ret(&self) -> &Option; | help: change this to: `Option<&String>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:43:5 + --> tests/ui/ref_option/ref_option.rs:58:5 | LL | fn private_opt_params(&self, a: &Option<()>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^ @@ -94,12 +97,13 @@ LL | fn private_opt_params(&self, a: &Option<()>) {} | help: change this to: `Option<&()>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option.rs:44:5 + --> tests/ui/ref_option/ref_option.rs:60:5 | LL | fn private_opt_ret(&self) -> &Option { | ^ --------------- help: change this to: `Option<&String>` | _____| | | +LL | | LL | | panic!() LL | | } | |_____^ diff --git a/tests/ui/ref_option/ref_option.rs b/tests/ui/ref_option/ref_option.rs index 05251bcf12cd..86b5c6fe896b 100644 --- a/tests/ui/ref_option/ref_option.rs +++ b/tests/ui/ref_option/ref_option.rs @@ -6,42 +6,59 @@ #![warn(clippy::ref_option)] fn opt_u8(a: &Option) {} +//~^ ref_option fn opt_gen(a: &Option) {} +//~^ ref_option fn opt_string(a: &std::option::Option) {} +//~^ ref_option fn ret_string<'a>(p: &'a str) -> &'a Option { +//~^ ref_option panic!() } fn ret_string_static() -> &'static Option { +//~^ ref_option panic!() } fn mult_string(a: &Option, b: &Option>) {} +//~^ ref_option fn ret_box<'a>() -> &'a Option> { +//~^ ref_option panic!() } pub fn pub_opt_string(a: &Option) {} +//~[all]^ ref_option pub fn pub_mult_string(a: &Option, b: &Option>) {} +//~[all]^ ref_option pub trait PubTrait { fn pub_trait_opt(&self, a: &Option>); + //~[all]^ ref_option fn pub_trait_ret(&self) -> &Option>; + //~[all]^ ref_option } trait PrivateTrait { fn trait_opt(&self, a: &Option); + //~^ ref_option fn trait_ret(&self) -> &Option; + //~^ ref_option } pub struct PubStruct; impl PubStruct { pub fn pub_opt_params(&self, a: &Option<()>) {} + //~[all]^ ref_option pub fn pub_opt_ret(&self) -> &Option { + //~[all]^ ref_option panic!() } fn private_opt_params(&self, a: &Option<()>) {} + //~^ ref_option fn private_opt_ret(&self) -> &Option { + //~^ ref_option panic!() } } diff --git a/tests/ui/ref_option/ref_option_traits.all.stderr b/tests/ui/ref_option/ref_option_traits.all.stderr index a9967168c12e..030a9a28ec68 100644 --- a/tests/ui/ref_option/ref_option_traits.all.stderr +++ b/tests/ui/ref_option/ref_option_traits.all.stderr @@ -10,7 +10,7 @@ LL | fn pub_trait_opt(&self, a: &Option>); = help: to override `-D warnings` add `#[allow(clippy::ref_option)]` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option_traits.rs:11:5 + --> tests/ui/ref_option/ref_option_traits.rs:12:5 | LL | fn pub_trait_ret(&self) -> &Option>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^ @@ -18,7 +18,7 @@ LL | fn pub_trait_ret(&self) -> &Option>; | help: change this to: `Option<&Vec>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option_traits.rs:15:5 + --> tests/ui/ref_option/ref_option_traits.rs:17:5 | LL | fn trait_opt(&self, a: &Option); | ^^^^^^^^^^^^^^^^^^^^^^^---------------^^ @@ -26,7 +26,7 @@ LL | fn trait_opt(&self, a: &Option); | help: change this to: `Option<&String>` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option_traits.rs:16:5 + --> tests/ui/ref_option/ref_option_traits.rs:19:5 | LL | fn trait_ret(&self) -> &Option; | ^^^^^^^^^^^^^^^^^^^^^^^---------------^ diff --git a/tests/ui/ref_option/ref_option_traits.private.stderr b/tests/ui/ref_option/ref_option_traits.private.stderr index 36d0833af8a2..2837ee80fb2e 100644 --- a/tests/ui/ref_option/ref_option_traits.private.stderr +++ b/tests/ui/ref_option/ref_option_traits.private.stderr @@ -1,5 +1,5 @@ error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option_traits.rs:15:5 + --> tests/ui/ref_option/ref_option_traits.rs:17:5 | LL | fn trait_opt(&self, a: &Option); | ^^^^^^^^^^^^^^^^^^^^^^^---------------^^ @@ -10,7 +10,7 @@ LL | fn trait_opt(&self, a: &Option); = help: to override `-D warnings` add `#[allow(clippy::ref_option)]` error: it is more idiomatic to use `Option<&T>` instead of `&Option` - --> tests/ui/ref_option/ref_option_traits.rs:16:5 + --> tests/ui/ref_option/ref_option_traits.rs:19:5 | LL | fn trait_ret(&self) -> &Option; | ^^^^^^^^^^^^^^^^^^^^^^^---------------^ diff --git a/tests/ui/ref_option/ref_option_traits.rs b/tests/ui/ref_option/ref_option_traits.rs index 5d5f113c83db..811da2eb4d50 100644 --- a/tests/ui/ref_option/ref_option_traits.rs +++ b/tests/ui/ref_option/ref_option_traits.rs @@ -8,12 +8,16 @@ pub trait PubTrait { fn pub_trait_opt(&self, a: &Option>); + //~[all]^ ref_option fn pub_trait_ret(&self) -> &Option>; + //~[all]^ ref_option } trait PrivateTrait { fn trait_opt(&self, a: &Option); + //~^ ref_option fn trait_ret(&self) -> &Option; + //~^ ref_option } pub struct PubStruct; diff --git a/tests/ui/ref_option_ref.rs b/tests/ui/ref_option_ref.rs index 44001c45e99a..de936cb08108 100644 --- a/tests/ui/ref_option_ref.rs +++ b/tests/ui/ref_option_ref.rs @@ -8,37 +8,46 @@ static THRESHOLD: i32 = 10; static REF_THRESHOLD: &Option<&i32> = &Some(&THRESHOLD); -//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt -//~| NOTE: `-D clippy::ref-option-ref` implied by `-D warnings` +//~^ ref_option_ref + + const CONST_THRESHOLD: &i32 = &10; const REF_CONST: &Option<&i32> = &Some(CONST_THRESHOLD); -//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt +//~^ ref_option_ref + type RefOptRefU32<'a> = &'a Option<&'a u32>; -//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt +//~^ ref_option_ref + type RefOptRef<'a, T> = &'a Option<&'a T>; -//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt +//~^ ref_option_ref + fn foo(data: &Option<&u32>) {} -//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt +//~^ ref_option_ref + fn bar(data: &u32) -> &Option<&u32> { - //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt +//~^ ref_option_ref + &None } struct StructRef<'a> { data: &'a Option<&'a u32>, - //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to + //~^ ref_option_ref + } struct StructTupleRef<'a>(u32, &'a Option<&'a u32>); -//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt +//~^ ref_option_ref + enum EnumRef<'a> { Variant1(u32), Variant2(&'a Option<&'a u32>), - //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to + //~^ ref_option_ref + } trait RefOptTrait { @@ -48,14 +57,16 @@ trait RefOptTrait { impl RefOptTrait for u32 { type A = &'static Option<&'static Self>; - //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to + //~^ ref_option_ref + fn foo(&self, _: Self::A) {} } fn main() { let x: &Option<&u32> = &None; - //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to + //~^ ref_option_ref + } fn issue9682(arg: &Option<&mut String>) { diff --git a/tests/ui/ref_option_ref.stderr b/tests/ui/ref_option_ref.stderr index 1cb64e1182a5..fcafbc5ea18e 100644 --- a/tests/ui/ref_option_ref.stderr +++ b/tests/ui/ref_option_ref.stderr @@ -8,61 +8,61 @@ LL | static REF_THRESHOLD: &Option<&i32> = &Some(&THRESHOLD); = help: to override `-D warnings` add `#[allow(clippy::ref_option_ref)]` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:14:18 + --> tests/ui/ref_option_ref.rs:15:18 | LL | const REF_CONST: &Option<&i32> = &Some(CONST_THRESHOLD); | ^^^^^^^^^^^^^ help: try: `Option<&i32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:17:25 + --> tests/ui/ref_option_ref.rs:19:25 | LL | type RefOptRefU32<'a> = &'a Option<&'a u32>; | ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:19:25 + --> tests/ui/ref_option_ref.rs:22:25 | LL | type RefOptRef<'a, T> = &'a Option<&'a T>; | ^^^^^^^^^^^^^^^^^ help: try: `Option<&'a T>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:22:14 + --> tests/ui/ref_option_ref.rs:26:14 | LL | fn foo(data: &Option<&u32>) {} | ^^^^^^^^^^^^^ help: try: `Option<&u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:25:23 + --> tests/ui/ref_option_ref.rs:30:23 | LL | fn bar(data: &u32) -> &Option<&u32> { | ^^^^^^^^^^^^^ help: try: `Option<&u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:31:11 + --> tests/ui/ref_option_ref.rs:37:11 | LL | data: &'a Option<&'a u32>, | ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:35:32 + --> tests/ui/ref_option_ref.rs:42:32 | LL | struct StructTupleRef<'a>(u32, &'a Option<&'a u32>); | ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:40:14 + --> tests/ui/ref_option_ref.rs:48:14 | LL | Variant2(&'a Option<&'a u32>), | ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:50:14 + --> tests/ui/ref_option_ref.rs:59:14 | LL | type A = &'static Option<&'static Self>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'static Self>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:57:12 + --> tests/ui/ref_option_ref.rs:67:12 | LL | let x: &Option<&u32> = &None; | ^^^^^^^^^^^^^ help: try: `Option<&u32>` diff --git a/tests/ui/ref_patterns.rs b/tests/ui/ref_patterns.rs index acd42ec89b62..214778b78b5b 100644 --- a/tests/ui/ref_patterns.rs +++ b/tests/ui/ref_patterns.rs @@ -6,17 +6,20 @@ fn use_in_pattern() { match opt { None => {}, Some(ref opt) => {}, - //~^ ERROR: usage of ref pattern + //~^ ref_patterns + } } fn use_in_binding() { let x = 5; let ref y = x; - //~^ ERROR: usage of ref pattern + //~^ ref_patterns + } fn use_in_parameter(ref x: i32) {} -//~^ ERROR: usage of ref pattern +//~^ ref_patterns + fn main() {} diff --git a/tests/ui/ref_patterns.stderr b/tests/ui/ref_patterns.stderr index 9e2d036e3483..bf63189a15b0 100644 --- a/tests/ui/ref_patterns.stderr +++ b/tests/ui/ref_patterns.stderr @@ -9,7 +9,7 @@ LL | Some(ref opt) => {}, = help: to override `-D warnings` add `#[allow(clippy::ref_patterns)]` error: usage of ref pattern - --> tests/ui/ref_patterns.rs:15:9 + --> tests/ui/ref_patterns.rs:16:9 | LL | let ref y = x; | ^^^^^ @@ -17,7 +17,7 @@ LL | let ref y = x; = help: consider using `&` for clarity instead error: usage of ref pattern - --> tests/ui/ref_patterns.rs:19:21 + --> tests/ui/ref_patterns.rs:21:21 | LL | fn use_in_parameter(ref x: i32) {} | ^^^^^ diff --git a/tests/ui/regex.rs b/tests/ui/regex.rs index f607a2d50c6d..c63d549b7553 100644 --- a/tests/ui/regex.rs +++ b/tests/ui/regex.rs @@ -1,3 +1,4 @@ +//@require-annotations-for-level: WARN #![allow( unused, clippy::needless_raw_strings, @@ -27,11 +28,14 @@ fn syntax_error() { //~^ ERROR: regex syntax error: invalid character class range, the start must be <= th let some_regex = Regex::new(OPENING_PAREN); + //~^ invalid_regex let binary_pipe_in_wrong_position = BRegex::new("|"); //~^ ERROR: trivial regex let some_binary_regex = BRegex::new(OPENING_PAREN); + //~^ invalid_regex let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN); + //~^ invalid_regex let closing_paren = ")"; let not_linted = Regex::new(closing_paren); @@ -44,7 +48,9 @@ fn syntax_error() { ]); let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]); + //~^ invalid_regex let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]); + //~^ invalid_regex // These following three cases are considering valid since regex-1.8.0 let raw_string_error = Regex::new(r"[...\/...]"); @@ -52,6 +58,7 @@ fn syntax_error() { let _ = Regex::new(r"(?hi)").unwrap(); let escaped_string_span = Regex::new("\\b\\c"); + //~^ invalid_regex let aux_span = Regex::new("(?ixi)"); //~^ ERROR: regex syntax error: duplicate flag diff --git a/tests/ui/regex.stderr b/tests/ui/regex.stderr index 18dd538c68b4..aaec3bc14200 100644 --- a/tests/ui/regex.stderr +++ b/tests/ui/regex.stderr @@ -1,5 +1,5 @@ error: trivial regex - --> tests/ui/regex.rs:19:45 + --> tests/ui/regex.rs:20:45 | LL | let pipe_in_wrong_position = Regex::new("|"); | ^^^ @@ -9,7 +9,7 @@ LL | let pipe_in_wrong_position = Regex::new("|"); = help: to override `-D warnings` add `#[allow(clippy::trivial_regex)]` error: trivial regex - --> tests/ui/regex.rs:21:60 + --> tests/ui/regex.rs:22:60 | LL | let pipe_in_wrong_position_builder = RegexBuilder::new("|"); | ^^^ @@ -17,7 +17,7 @@ LL | let pipe_in_wrong_position_builder = RegexBuilder::new("|"); = help: the regex is unlikely to be useful as it is error: regex syntax error: invalid character class range, the start must be <= the end - --> tests/ui/regex.rs:23:42 + --> tests/ui/regex.rs:24:42 | LL | let wrong_char_ranice = Regex::new("[z-a]"); | ^^^ @@ -26,7 +26,7 @@ LL | let wrong_char_ranice = Regex::new("[z-a]"); = help: to override `-D warnings` add `#[allow(clippy::invalid_regex)]` error: regex syntax error: invalid character class range, the start must be <= the end - --> tests/ui/regex.rs:26:37 + --> tests/ui/regex.rs:27:37 | LL | let some_unicode = Regex::new("[é-è]"); | ^^^ @@ -35,13 +35,13 @@ error: regex parse error: ( ^ error: unclosed group - --> tests/ui/regex.rs:29:33 + --> tests/ui/regex.rs:30:33 | LL | let some_regex = Regex::new(OPENING_PAREN); | ^^^^^^^^^^^^^ error: trivial regex - --> tests/ui/regex.rs:31:53 + --> tests/ui/regex.rs:33:53 | LL | let binary_pipe_in_wrong_position = BRegex::new("|"); | ^^^ @@ -52,7 +52,7 @@ error: regex parse error: ( ^ error: unclosed group - --> tests/ui/regex.rs:33:41 + --> tests/ui/regex.rs:35:41 | LL | let some_binary_regex = BRegex::new(OPENING_PAREN); | ^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ error: regex parse error: ( ^ error: unclosed group - --> tests/ui/regex.rs:34:56 + --> tests/ui/regex.rs:37:56 | LL | let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN); | ^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ error: regex parse error: ( ^ error: unclosed group - --> tests/ui/regex.rs:46:37 + --> tests/ui/regex.rs:50:37 | LL | let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]); | ^^^^^^^^^^^^^ @@ -79,7 +79,7 @@ error: regex parse error: ( ^ error: unclosed group - --> tests/ui/regex.rs:47:39 + --> tests/ui/regex.rs:52:39 | LL | let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]); | ^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ error: regex parse error: \b\c ^^ error: unrecognized escape sequence - --> tests/ui/regex.rs:54:42 + --> tests/ui/regex.rs:60:42 | LL | let escaped_string_span = Regex::new("\\b\\c"); | ^^^^^^^^ @@ -96,19 +96,19 @@ LL | let escaped_string_span = Regex::new("\\b\\c"); = help: consider using a raw string literal: `r".."` error: regex syntax error: duplicate flag - --> tests/ui/regex.rs:56:34 + --> tests/ui/regex.rs:63:34 | LL | let aux_span = Regex::new("(?ixi)"); | ^ ^ error: regex syntax error: pattern can match invalid UTF-8 - --> tests/ui/regex.rs:62:53 + --> tests/ui/regex.rs:69:53 | LL | let invalid_utf8_should_lint = Regex::new("(?-u)."); | ^ error: trivial regex - --> tests/ui/regex.rs:67:33 + --> tests/ui/regex.rs:74:33 | LL | let trivial_eq = Regex::new("^foobar$"); | ^^^^^^^^^^ @@ -116,7 +116,7 @@ LL | let trivial_eq = Regex::new("^foobar$"); = help: consider using `==` on `str`s error: trivial regex - --> tests/ui/regex.rs:70:48 + --> tests/ui/regex.rs:77:48 | LL | let trivial_eq_builder = RegexBuilder::new("^foobar$"); | ^^^^^^^^^^ @@ -124,7 +124,7 @@ LL | let trivial_eq_builder = RegexBuilder::new("^foobar$"); = help: consider using `==` on `str`s error: trivial regex - --> tests/ui/regex.rs:73:42 + --> tests/ui/regex.rs:80:42 | LL | let trivial_starts_with = Regex::new("^foobar"); | ^^^^^^^^^ @@ -132,7 +132,7 @@ LL | let trivial_starts_with = Regex::new("^foobar"); = help: consider using `str::starts_with` error: trivial regex - --> tests/ui/regex.rs:76:40 + --> tests/ui/regex.rs:83:40 | LL | let trivial_ends_with = Regex::new("foobar$"); | ^^^^^^^^^ @@ -140,7 +140,7 @@ LL | let trivial_ends_with = Regex::new("foobar$"); = help: consider using `str::ends_with` error: trivial regex - --> tests/ui/regex.rs:79:39 + --> tests/ui/regex.rs:86:39 | LL | let trivial_contains = Regex::new("foobar"); | ^^^^^^^^ @@ -148,7 +148,7 @@ LL | let trivial_contains = Regex::new("foobar"); = help: consider using `str::contains` error: trivial regex - --> tests/ui/regex.rs:82:39 + --> tests/ui/regex.rs:89:39 | LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); | ^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); = help: consider using `str::contains` error: trivial regex - --> tests/ui/regex.rs:85:40 + --> tests/ui/regex.rs:92:40 | LL | let trivial_backslash = Regex::new("a\\.b"); | ^^^^^^^ @@ -164,7 +164,7 @@ LL | let trivial_backslash = Regex::new("a\\.b"); = help: consider using `str::contains` error: trivial regex - --> tests/ui/regex.rs:89:36 + --> tests/ui/regex.rs:96:36 | LL | let trivial_empty = Regex::new(""); | ^^ @@ -172,7 +172,7 @@ LL | let trivial_empty = Regex::new(""); = help: the regex is unlikely to be useful as it is error: trivial regex - --> tests/ui/regex.rs:92:36 + --> tests/ui/regex.rs:99:36 | LL | let trivial_empty = Regex::new("^"); | ^^^ @@ -180,7 +180,7 @@ LL | let trivial_empty = Regex::new("^"); = help: the regex is unlikely to be useful as it is error: trivial regex - --> tests/ui/regex.rs:95:36 + --> tests/ui/regex.rs:102:36 | LL | let trivial_empty = Regex::new("^$"); | ^^^^ @@ -188,7 +188,7 @@ LL | let trivial_empty = Regex::new("^$"); = help: consider using `str::is_empty` error: trivial regex - --> tests/ui/regex.rs:98:44 + --> tests/ui/regex.rs:105:44 | LL | let binary_trivial_empty = BRegex::new("^$"); | ^^^^ @@ -196,13 +196,13 @@ LL | let binary_trivial_empty = BRegex::new("^$"); = help: consider using `str::is_empty` error: compiling a regex in a loop - --> tests/ui/regex.rs:125:21 + --> tests/ui/regex.rs:132:21 | LL | let regex = Regex::new("a.b"); | ^^^^^^^^^^ | help: move the regex construction outside this loop - --> tests/ui/regex.rs:122:5 + --> tests/ui/regex.rs:129:5 | LL | loop { | ^^^^ @@ -210,37 +210,37 @@ LL | loop { = help: to override `-D warnings` add `#[allow(clippy::regex_creation_in_loops)]` error: compiling a regex in a loop - --> tests/ui/regex.rs:127:21 + --> tests/ui/regex.rs:134:21 | LL | let regex = BRegex::new("a.b"); | ^^^^^^^^^^^ | help: move the regex construction outside this loop - --> tests/ui/regex.rs:122:5 + --> tests/ui/regex.rs:129:5 | LL | loop { | ^^^^ error: compiling a regex in a loop - --> tests/ui/regex.rs:133:25 + --> tests/ui/regex.rs:140:25 | LL | let regex = Regex::new("a.b"); | ^^^^^^^^^^ | help: move the regex construction outside this loop - --> tests/ui/regex.rs:122:5 + --> tests/ui/regex.rs:129:5 | LL | loop { | ^^^^ error: compiling a regex in a loop - --> tests/ui/regex.rs:138:32 + --> tests/ui/regex.rs:145:32 | LL | let nested_regex = Regex::new("a.b"); | ^^^^^^^^^^ | help: move the regex construction outside this loop - --> tests/ui/regex.rs:137:9 + --> tests/ui/regex.rs:144:9 | LL | for _ in 0..10 { | ^^^^^^^^^^^^^^ diff --git a/tests/ui/renamed_builtin_attr.fixed b/tests/ui/renamed_builtin_attr.fixed index aebf8712dd92..1ad7d8702bc0 100644 --- a/tests/ui/renamed_builtin_attr.fixed +++ b/tests/ui/renamed_builtin_attr.fixed @@ -1,4 +1,5 @@ //@compile-flags: -Zdeduplicate-diagnostics=yes #[clippy::cognitive_complexity = "1"] +//~^ ERROR: usage of deprecated attribute fn main() {} diff --git a/tests/ui/renamed_builtin_attr.rs b/tests/ui/renamed_builtin_attr.rs index 6c18151195f5..0fb43b7f4901 100644 --- a/tests/ui/renamed_builtin_attr.rs +++ b/tests/ui/renamed_builtin_attr.rs @@ -1,4 +1,5 @@ //@compile-flags: -Zdeduplicate-diagnostics=yes #[clippy::cyclomatic_complexity = "1"] +//~^ ERROR: usage of deprecated attribute fn main() {} diff --git a/tests/ui/repeat_once.fixed b/tests/ui/repeat_once.fixed index 72e97350a0c8..e739e176f0ac 100644 --- a/tests/ui/repeat_once.fixed +++ b/tests/ui/repeat_once.fixed @@ -7,9 +7,15 @@ fn main() { let slice = [1; 5]; let a = [1; 5].to_vec(); + //~^ repeat_once let b = slice.to_vec(); + //~^ repeat_once let c = "hello".to_string(); + //~^ repeat_once let d = "hi".to_string(); + //~^ repeat_once let e = s.to_string(); + //~^ repeat_once let f = string.clone(); + //~^ repeat_once } diff --git a/tests/ui/repeat_once.rs b/tests/ui/repeat_once.rs index 7557c4d0bd41..89ab94bbaee8 100644 --- a/tests/ui/repeat_once.rs +++ b/tests/ui/repeat_once.rs @@ -7,9 +7,15 @@ fn main() { let slice = [1; 5]; let a = [1; 5].repeat(1); + //~^ repeat_once let b = slice.repeat(1); + //~^ repeat_once let c = "hello".repeat(N); + //~^ repeat_once let d = "hi".repeat(1); + //~^ repeat_once let e = s.repeat(1); + //~^ repeat_once let f = string.repeat(1); + //~^ repeat_once } diff --git a/tests/ui/repeat_once.stderr b/tests/ui/repeat_once.stderr index 6996dc5eee7d..3db7a3568f8e 100644 --- a/tests/ui/repeat_once.stderr +++ b/tests/ui/repeat_once.stderr @@ -8,31 +8,31 @@ LL | let a = [1; 5].repeat(1); = help: to override `-D warnings` add `#[allow(clippy::repeat_once)]` error: calling `repeat(1)` on slice - --> tests/ui/repeat_once.rs:10:13 + --> tests/ui/repeat_once.rs:11:13 | LL | let b = slice.repeat(1); | ^^^^^^^^^^^^^^^ help: consider using `.to_vec()` instead: `slice.to_vec()` error: calling `repeat(1)` on str - --> tests/ui/repeat_once.rs:11:13 + --> tests/ui/repeat_once.rs:13:13 | LL | let c = "hello".repeat(N); | ^^^^^^^^^^^^^^^^^ help: consider using `.to_string()` instead: `"hello".to_string()` error: calling `repeat(1)` on str - --> tests/ui/repeat_once.rs:12:13 + --> tests/ui/repeat_once.rs:15:13 | LL | let d = "hi".repeat(1); | ^^^^^^^^^^^^^^ help: consider using `.to_string()` instead: `"hi".to_string()` error: calling `repeat(1)` on str - --> tests/ui/repeat_once.rs:13:13 + --> tests/ui/repeat_once.rs:17:13 | LL | let e = s.repeat(1); | ^^^^^^^^^^^ help: consider using `.to_string()` instead: `s.to_string()` error: calling `repeat(1)` on a string literal - --> tests/ui/repeat_once.rs:14:13 + --> tests/ui/repeat_once.rs:19:13 | LL | let f = string.repeat(1); | ^^^^^^^^^^^^^^^^ help: consider using `.clone()` instead: `string.clone()` diff --git a/tests/ui/repeat_vec_with_capacity.fixed b/tests/ui/repeat_vec_with_capacity.fixed index f72b61b5f6cd..318839db221e 100644 --- a/tests/ui/repeat_vec_with_capacity.fixed +++ b/tests/ui/repeat_vec_with_capacity.fixed @@ -4,13 +4,15 @@ fn main() { { (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::>(); - //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + //~^ repeat_vec_with_capacity + } { let n = 123; (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::>(); - //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + //~^ repeat_vec_with_capacity + } { @@ -25,7 +27,8 @@ fn main() { { std::iter::repeat_with(|| Vec::<()>::with_capacity(42)); - //~^ ERROR: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity + //~^ repeat_vec_with_capacity + } { diff --git a/tests/ui/repeat_vec_with_capacity.rs b/tests/ui/repeat_vec_with_capacity.rs index c0cc81f78436..0ce4658c1089 100644 --- a/tests/ui/repeat_vec_with_capacity.rs +++ b/tests/ui/repeat_vec_with_capacity.rs @@ -4,13 +4,15 @@ fn main() { { vec![Vec::<()>::with_capacity(42); 123]; - //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + //~^ repeat_vec_with_capacity + } { let n = 123; vec![Vec::<()>::with_capacity(42); n]; - //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + //~^ repeat_vec_with_capacity + } { @@ -25,7 +27,8 @@ fn main() { { std::iter::repeat(Vec::<()>::with_capacity(42)); - //~^ ERROR: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity + //~^ repeat_vec_with_capacity + } { diff --git a/tests/ui/repeat_vec_with_capacity.stderr b/tests/ui/repeat_vec_with_capacity.stderr index 43027c9cb892..bdfd58137b0b 100644 --- a/tests/ui/repeat_vec_with_capacity.stderr +++ b/tests/ui/repeat_vec_with_capacity.stderr @@ -13,7 +13,7 @@ LL | (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::>(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity - --> tests/ui/repeat_vec_with_capacity.rs:12:9 + --> tests/ui/repeat_vec_with_capacity.rs:13:9 | LL | vec![Vec::<()>::with_capacity(42); n]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::>(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity - --> tests/ui/repeat_vec_with_capacity.rs:27:9 + --> tests/ui/repeat_vec_with_capacity.rs:29:9 | LL | std::iter::repeat(Vec::<()>::with_capacity(42)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repeat_vec_with_capacity_nostd.fixed b/tests/ui/repeat_vec_with_capacity_nostd.fixed index ef316f1def41..dcff18723b6c 100644 --- a/tests/ui/repeat_vec_with_capacity_nostd.fixed +++ b/tests/ui/repeat_vec_with_capacity_nostd.fixed @@ -7,4 +7,5 @@ use alloc::vec::Vec; fn nostd() { let _: Vec> = core::iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect(); + //~^ repeat_vec_with_capacity } diff --git a/tests/ui/repeat_vec_with_capacity_nostd.rs b/tests/ui/repeat_vec_with_capacity_nostd.rs index 83b418a56674..84cc78de35ec 100644 --- a/tests/ui/repeat_vec_with_capacity_nostd.rs +++ b/tests/ui/repeat_vec_with_capacity_nostd.rs @@ -7,4 +7,5 @@ use alloc::vec::Vec; fn nostd() { let _: Vec> = iter::repeat(Vec::with_capacity(42)).take(123).collect(); + //~^ repeat_vec_with_capacity } diff --git a/tests/ui/repl_uninit.rs b/tests/ui/repl_uninit.rs index 01bdf79e6422..f9887eedcf46 100644 --- a/tests/ui/repl_uninit.rs +++ b/tests/ui/repl_uninit.rs @@ -13,22 +13,25 @@ fn main() { // the following is UB if `might_panic` panics unsafe { let taken_v = mem::replace(&mut v, mem::uninitialized()); - //~^ ERROR: replacing with `mem::uninitialized()` - //~| NOTE: `-D clippy::mem-replace-with-uninit` implied by `-D warnings` + //~^ mem_replace_with_uninit + + let new_v = might_panic(taken_v); std::mem::forget(mem::replace(&mut v, new_v)); } unsafe { let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init()); - //~^ ERROR: replacing with `mem::MaybeUninit::uninit().assume_init()` + //~^ mem_replace_with_uninit + let new_v = might_panic(taken_v); std::mem::forget(mem::replace(&mut v, new_v)); } unsafe { let taken_v = mem::replace(&mut v, mem::zeroed()); - //~^ ERROR: replacing with `mem::zeroed()` + //~^ mem_replace_with_uninit + let new_v = might_panic(taken_v); std::mem::forget(mem::replace(&mut v, new_v)); } @@ -41,6 +44,7 @@ fn main() { // this is still not OK, because uninit let taken_u = unsafe { mem::replace(uref, mem::uninitialized()) }; - //~^ ERROR: replacing with `mem::uninitialized()` + //~^ mem_replace_with_uninit + *uref = taken_u + 1; } diff --git a/tests/ui/repl_uninit.stderr b/tests/ui/repl_uninit.stderr index 645c4a16a07e..6e314d0dd166 100644 --- a/tests/ui/repl_uninit.stderr +++ b/tests/ui/repl_uninit.stderr @@ -8,13 +8,13 @@ LL | let taken_v = mem::replace(&mut v, mem::uninitialized()); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_uninit)]` error: replacing with `mem::MaybeUninit::uninit().assume_init()` - --> tests/ui/repl_uninit.rs:23:23 + --> tests/ui/repl_uninit.rs:24:23 | LL | let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)` error: replacing with `mem::zeroed()` - --> tests/ui/repl_uninit.rs:30:23 + --> tests/ui/repl_uninit.rs:32:23 | LL | let taken_v = mem::replace(&mut v, mem::zeroed()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | let taken_v = mem::replace(&mut v, mem::zeroed()); = help: consider using a default value or the `take_mut` crate instead error: replacing with `mem::uninitialized()` - --> tests/ui/repl_uninit.rs:43:28 + --> tests/ui/repl_uninit.rs:46:28 | LL | let taken_u = unsafe { mem::replace(uref, mem::uninitialized()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(uref)` diff --git a/tests/ui/repr_packed_without_abi.rs b/tests/ui/repr_packed_without_abi.rs index 16b5ededee99..4f51d4b9aec6 100644 --- a/tests/ui/repr_packed_without_abi.rs +++ b/tests/ui/repr_packed_without_abi.rs @@ -2,12 +2,14 @@ #[repr(packed)] struct NetworkPacketHeader { +//~^ repr_packed_without_abi header_length: u8, header_version: u16, } #[repr(packed)] union Foo { +//~^ repr_packed_without_abi a: u8, b: u16, } diff --git a/tests/ui/repr_packed_without_abi.stderr b/tests/ui/repr_packed_without_abi.stderr index 4f7acd00db3d..d1078b3e8e48 100644 --- a/tests/ui/repr_packed_without_abi.stderr +++ b/tests/ui/repr_packed_without_abi.stderr @@ -4,6 +4,7 @@ error: item uses `packed` representation without ABI-qualification LL | #[repr(packed)] | ------ `packed` representation set here LL | / struct NetworkPacketHeader { +LL | | LL | | header_length: u8, LL | | header_version: u16, LL | | } @@ -18,11 +19,12 @@ LL | #![deny(clippy::repr_packed_without_abi)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: item uses `packed` representation without ABI-qualification - --> tests/ui/repr_packed_without_abi.rs:10:1 + --> tests/ui/repr_packed_without_abi.rs:11:1 | LL | #[repr(packed)] | ------ `packed` representation set here LL | / union Foo { +LL | | LL | | a: u8, LL | | b: u16, LL | | } diff --git a/tests/ui/reserve_after_initialization.rs b/tests/ui/reserve_after_initialization.rs index b57a8e162c53..7f79dac46536 100644 --- a/tests/ui/reserve_after_initialization.rs +++ b/tests/ui/reserve_after_initialization.rs @@ -8,6 +8,7 @@ use proc_macros::{external, with_span}; // Should lint fn standard() { let mut v1: Vec = vec![]; + //~^ reserve_after_initialization v1.reserve(10); } @@ -15,6 +16,7 @@ fn standard() { fn capacity_as_expr() { let capacity = 10; let mut v2: Vec = vec![]; + //~^ reserve_after_initialization v2.reserve(capacity); } @@ -33,6 +35,7 @@ fn called_with_capacity() { fn assign_expression() { let mut v5: Vec = Vec::new(); v5 = Vec::new(); + //~^ reserve_after_initialization v5.reserve(10); } diff --git a/tests/ui/reserve_after_initialization.stderr b/tests/ui/reserve_after_initialization.stderr index b6dbebb3f14c..e79b59a35d41 100644 --- a/tests/ui/reserve_after_initialization.stderr +++ b/tests/ui/reserve_after_initialization.stderr @@ -2,6 +2,7 @@ error: call to `reserve` immediately after creation --> tests/ui/reserve_after_initialization.rs:10:5 | LL | / let mut v1: Vec = vec![]; +LL | | LL | | v1.reserve(10); | |___________________^ help: consider using `Vec::with_capacity(/* Space hint */)`: `let mut v1: Vec = Vec::with_capacity(10);` | @@ -9,16 +10,18 @@ LL | | v1.reserve(10); = help: to override `-D warnings` add `#[allow(clippy::reserve_after_initialization)]` error: call to `reserve` immediately after creation - --> tests/ui/reserve_after_initialization.rs:17:5 + --> tests/ui/reserve_after_initialization.rs:18:5 | LL | / let mut v2: Vec = vec![]; +LL | | LL | | v2.reserve(capacity); | |_________________________^ help: consider using `Vec::with_capacity(/* Space hint */)`: `let mut v2: Vec = Vec::with_capacity(capacity);` error: call to `reserve` immediately after creation - --> tests/ui/reserve_after_initialization.rs:35:5 + --> tests/ui/reserve_after_initialization.rs:37:5 | LL | / v5 = Vec::new(); +LL | | LL | | v5.reserve(10); | |___________________^ help: consider using `Vec::with_capacity(/* Space hint */)`: `v5 = Vec::with_capacity(10);` diff --git a/tests/ui/rest_pat_in_fully_bound_structs.rs b/tests/ui/rest_pat_in_fully_bound_structs.rs index 51fe346d0926..fd6cf0d1ce1f 100644 --- a/tests/ui/rest_pat_in_fully_bound_structs.rs +++ b/tests/ui/rest_pat_in_fully_bound_structs.rs @@ -21,16 +21,19 @@ fn main() { match a_struct { A { a: 5, b: 42, c: "", .. } => {}, // Lint - //~^ ERROR: unnecessary use of `..` pattern in struct binding. All fields were alr + //~^ rest_pat_in_fully_bound_structs + A { a: 0, b: 0, c: "", .. } => {}, // Lint - //~^ ERROR: unnecessary use of `..` pattern in struct binding. All fields were alr + //~^ rest_pat_in_fully_bound_structs + _ => {}, } match a_struct { A { a: 5, b: 42, .. } => {}, A { a: 0, b: 0, c: "", .. } => {}, // Lint - //~^ ERROR: unnecessary use of `..` pattern in struct binding. All fields were alr + //~^ rest_pat_in_fully_bound_structs + _ => {}, } diff --git a/tests/ui/rest_pat_in_fully_bound_structs.stderr b/tests/ui/rest_pat_in_fully_bound_structs.stderr index d048933ddb7b..72cf778ca64c 100644 --- a/tests/ui/rest_pat_in_fully_bound_structs.stderr +++ b/tests/ui/rest_pat_in_fully_bound_structs.stderr @@ -9,7 +9,7 @@ LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint = help: to override `-D warnings` add `#[allow(clippy::rest_pat_in_fully_bound_structs)]` error: unnecessary use of `..` pattern in struct binding. All fields were already bound - --> tests/ui/rest_pat_in_fully_bound_structs.rs:25:9 + --> tests/ui/rest_pat_in_fully_bound_structs.rs:26:9 | LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint = help: consider removing `..` from this binding error: unnecessary use of `..` pattern in struct binding. All fields were already bound - --> tests/ui/rest_pat_in_fully_bound_structs.rs:32:9 + --> tests/ui/rest_pat_in_fully_bound_structs.rs:34:9 | LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/result_filter_map.rs b/tests/ui/result_filter_map.rs index bfe47ffcf380..f5e0a9da9ea5 100644 --- a/tests/ui/result_filter_map.rs +++ b/tests/ui/result_filter_map.rs @@ -11,25 +11,29 @@ fn main() { let _ = vec![Ok(1) as Result] .into_iter() .filter(Result::is_ok) - //~^ ERROR: `filter` for `Ok` followed by `unwrap` + //~^ result_filter_map + .map(Result::unwrap); let _ = vec![Ok(1) as Result] .into_iter() .filter(|o| o.is_ok()) - //~^ ERROR: `filter` for `Ok` followed by `unwrap` + //~^ result_filter_map + .map(|o| o.unwrap()); let _ = vec![1] .into_iter() .map(odds_out) .filter(Result::is_ok) - //~^ ERROR: `filter` for `Ok` followed by `unwrap` + //~^ result_filter_map + .map(Result::unwrap); let _ = vec![1] .into_iter() .map(odds_out) .filter(|o| o.is_ok()) - //~^ ERROR: `filter` for `Ok` followed by `unwrap` + //~^ result_filter_map + .map(|o| o.unwrap()); } diff --git a/tests/ui/result_filter_map.stderr b/tests/ui/result_filter_map.stderr index 12eb7083b5a8..f3ff5173c171 100644 --- a/tests/ui/result_filter_map.stderr +++ b/tests/ui/result_filter_map.stderr @@ -3,7 +3,7 @@ error: `filter` for `Ok` followed by `unwrap` | LL | .filter(Result::is_ok) | __________^ -LL | | +... | LL | | .map(Result::unwrap); | |____________________________^ help: consider using `flatten` instead: `flatten()` | @@ -11,29 +11,29 @@ LL | | .map(Result::unwrap); = help: to override `-D warnings` add `#[allow(clippy::result_filter_map)]` error: `filter` for `Ok` followed by `unwrap` - --> tests/ui/result_filter_map.rs:19:10 + --> tests/ui/result_filter_map.rs:20:10 | LL | .filter(|o| o.is_ok()) | __________^ -LL | | +... | LL | | .map(|o| o.unwrap()); | |____________________________^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Ok` followed by `unwrap` - --> tests/ui/result_filter_map.rs:26:10 + --> tests/ui/result_filter_map.rs:28:10 | LL | .filter(Result::is_ok) | __________^ -LL | | +... | LL | | .map(Result::unwrap); | |____________________________^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Ok` followed by `unwrap` - --> tests/ui/result_filter_map.rs:32:10 + --> tests/ui/result_filter_map.rs:35:10 | LL | .filter(|o| o.is_ok()) | __________^ -LL | | +... | LL | | .map(|o| o.unwrap()); | |____________________________^ help: consider using `flatten` instead: `flatten()` diff --git a/tests/ui/result_large_err.rs b/tests/ui/result_large_err.rs index 9c39f023da2d..bdcf40a99ab9 100644 --- a/tests/ui/result_large_err.rs +++ b/tests/ui/result_large_err.rs @@ -8,7 +8,8 @@ pub fn small_err() -> Result<(), u128> { } pub fn large_err() -> Result<(), [u8; 512]> { - //~^ ERROR: the `Err`-variant returned from this function is very large +//~^ result_large_err + Ok(()) } @@ -20,19 +21,22 @@ pub struct FullyDefinedLargeError { impl FullyDefinedLargeError { pub fn ret() -> Result<(), Self> { - //~^ ERROR: the `Err`-variant returned from this function is very large + //~^ result_large_err + Ok(()) } } pub fn struct_error() -> Result<(), FullyDefinedLargeError> { - //~^ ERROR: the `Err`-variant returned from this function is very large +//~^ result_large_err + Ok(()) } type Fdlr = std::result::Result; pub fn large_err_via_type_alias(x: T) -> Fdlr { - //~^ ERROR: the `Err`-variant returned from this function is very large +//~^ result_large_err + Ok(x) } @@ -41,7 +45,8 @@ pub fn param_small_error() -> Result<(), (R, u128)> { } pub fn param_large_error() -> Result<(), (u128, R, FullyDefinedLargeError)> { - //~^ ERROR: the `Err`-variant returned from this function is very large +//~^ result_large_err + Ok(()) } @@ -53,7 +58,8 @@ pub enum LargeErrorVariants { impl LargeErrorVariants<()> { pub fn large_enum_error() -> Result<(), Self> { - //~^ ERROR: the `Err`-variant returned from this function is very large + //~^ result_large_err + Ok(()) } } @@ -66,14 +72,16 @@ enum MultipleLargeVariants { impl MultipleLargeVariants { fn large_enum_error() -> Result<(), Self> { - //~^ ERROR: the `Err`-variant returned from this function is very large + //~^ result_large_err + Ok(()) } } trait TraitForcesLargeError { fn large_error() -> Result<(), [u8; 512]> { - //~^ ERROR: the `Err`-variant returned from this function is very large + //~^ result_large_err + Ok(()) } } @@ -93,7 +101,8 @@ pub union FullyDefinedUnionError { } pub fn large_union_err() -> Result<(), FullyDefinedUnionError> { - //~^ ERROR: the `Err`-variant returned from this function is very large +//~^ result_large_err + Ok(()) } @@ -103,7 +112,8 @@ pub union UnionError { } pub fn param_large_union() -> Result<(), UnionError> { - //~^ ERROR: the `Err`-variant returned from this function is very large +//~^ result_large_err + Ok(()) } @@ -113,12 +123,14 @@ pub struct ArrayError { } pub fn array_error_subst() -> Result<(), ArrayError> { - //~^ ERROR: the `Err`-variant returned from this function is very large +//~^ result_large_err + Ok(()) } pub fn array_error() -> Result<(), ArrayError<(i32, T), U>> { - //~^ ERROR: the `Err`-variant returned from this function is very large +//~^ result_large_err + Ok(()) } diff --git a/tests/ui/result_large_err.stderr b/tests/ui/result_large_err.stderr index 1dff3f9efe81..72fbc3f58961 100644 --- a/tests/ui/result_large_err.stderr +++ b/tests/ui/result_large_err.stderr @@ -9,7 +9,7 @@ LL | pub fn large_err() -> Result<(), [u8; 512]> { = help: to override `-D warnings` add `#[allow(clippy::result_large_err)]` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:22:21 + --> tests/ui/result_large_err.rs:23:21 | LL | pub fn ret() -> Result<(), Self> { | ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes @@ -17,7 +17,7 @@ LL | pub fn ret() -> Result<(), Self> { = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:28:26 + --> tests/ui/result_large_err.rs:30:26 | LL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes @@ -25,7 +25,7 @@ LL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> { = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:34:45 + --> tests/ui/result_large_err.rs:37:45 | LL | pub fn large_err_via_type_alias(x: T) -> Fdlr { | ^^^^^^^ the `Err`-variant is at least 240 bytes @@ -33,7 +33,7 @@ LL | pub fn large_err_via_type_alias(x: T) -> Fdlr { = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:43:34 + --> tests/ui/result_large_err.rs:47:34 | LL | pub fn param_large_error() -> Result<(), (u128, R, FullyDefinedLargeError)> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 256 bytes @@ -41,7 +41,7 @@ LL | pub fn param_large_error() -> Result<(), (u128, R, FullyDefinedLargeErro = help: try reducing the size of `(u128, R, FullyDefinedLargeError)`, for example by boxing large elements or replacing it with `Box<(u128, R, FullyDefinedLargeError)>` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:55:34 + --> tests/ui/result_large_err.rs:60:34 | LL | _Omg([u8; 512]), | --------------- the largest variant contains at least 512 bytes @@ -52,7 +52,7 @@ LL | pub fn large_enum_error() -> Result<(), Self> { = help: try reducing the size of `LargeErrorVariants<()>`, for example by boxing large elements or replacing it with `Box>` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:68:30 + --> tests/ui/result_large_err.rs:74:30 | LL | _Biggest([u8; 1024]), | -------------------- the largest variant contains at least 1024 bytes @@ -65,7 +65,7 @@ LL | fn large_enum_error() -> Result<(), Self> { = help: try reducing the size of `MultipleLargeVariants`, for example by boxing large elements or replacing it with `Box` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:75:25 + --> tests/ui/result_large_err.rs:82:25 | LL | fn large_error() -> Result<(), [u8; 512]> { | ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes @@ -73,7 +73,7 @@ LL | fn large_error() -> Result<(), [u8; 512]> { = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:95:29 + --> tests/ui/result_large_err.rs:103:29 | LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes @@ -81,7 +81,7 @@ LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> { = help: try reducing the size of `FullyDefinedUnionError`, for example by boxing large elements or replacing it with `Box` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:105:40 + --> tests/ui/result_large_err.rs:114:40 | LL | pub fn param_large_union() -> Result<(), UnionError> { | ^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes @@ -89,7 +89,7 @@ LL | pub fn param_large_union() -> Result<(), UnionError> { = help: try reducing the size of `UnionError`, for example by boxing large elements or replacing it with `Box>` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:115:34 + --> tests/ui/result_large_err.rs:125:34 | LL | pub fn array_error_subst() -> Result<(), ArrayError> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes @@ -97,7 +97,7 @@ LL | pub fn array_error_subst() -> Result<(), ArrayError> { = help: try reducing the size of `ArrayError`, for example by boxing large elements or replacing it with `Box>` error: the `Err`-variant returned from this function is very large - --> tests/ui/result_large_err.rs:120:31 + --> tests/ui/result_large_err.rs:131:31 | LL | pub fn array_error() -> Result<(), ArrayError<(i32, T), U>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes diff --git a/tests/ui/result_map_or_into_option.fixed b/tests/ui/result_map_or_into_option.fixed index cf42b24b2dda..47ba2b03bfc4 100644 --- a/tests/ui/result_map_or_into_option.fixed +++ b/tests/ui/result_map_or_into_option.fixed @@ -3,12 +3,15 @@ fn main() { let opt: Result = Ok(1); let _ = opt.ok(); - //~^ ERROR: called `map_or(None, Some)` on a `Result` value + //~^ result_map_or_into_option + let _ = opt.ok(); - //~^ ERROR: called `map_or_else(|_| None, Some)` on a `Result` value + //~^ result_map_or_into_option + #[rustfmt::skip] let _ = opt.ok(); - //~^ ERROR: called `map_or_else(|_| None, Some)` on a `Result` value + //~^ result_map_or_into_option + let rewrap = |s: u32| -> Option { Some(s) }; diff --git a/tests/ui/result_map_or_into_option.rs b/tests/ui/result_map_or_into_option.rs index cdb45d6b82a0..3c6b2f0e836f 100644 --- a/tests/ui/result_map_or_into_option.rs +++ b/tests/ui/result_map_or_into_option.rs @@ -3,12 +3,15 @@ fn main() { let opt: Result = Ok(1); let _ = opt.map_or(None, Some); - //~^ ERROR: called `map_or(None, Some)` on a `Result` value + //~^ result_map_or_into_option + let _ = opt.map_or_else(|_| None, Some); - //~^ ERROR: called `map_or_else(|_| None, Some)` on a `Result` value + //~^ result_map_or_into_option + #[rustfmt::skip] let _ = opt.map_or_else(|_| { None }, Some); - //~^ ERROR: called `map_or_else(|_| None, Some)` on a `Result` value + //~^ result_map_or_into_option + let rewrap = |s: u32| -> Option { Some(s) }; diff --git a/tests/ui/result_map_or_into_option.stderr b/tests/ui/result_map_or_into_option.stderr index 4cb510d77a06..f9058d35e6c6 100644 --- a/tests/ui/result_map_or_into_option.stderr +++ b/tests/ui/result_map_or_into_option.stderr @@ -8,13 +8,13 @@ LL | let _ = opt.map_or(None, Some); = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]` error: called `map_or_else(|_| None, Some)` on a `Result` value - --> tests/ui/result_map_or_into_option.rs:7:13 + --> tests/ui/result_map_or_into_option.rs:8:13 | LL | let _ = opt.map_or_else(|_| None, Some); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()` error: called `map_or_else(|_| None, Some)` on a `Result` value - --> tests/ui/result_map_or_into_option.rs:10:13 + --> tests/ui/result_map_or_into_option.rs:12:13 | LL | let _ = opt.map_or_else(|_| { None }, Some); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()` diff --git a/tests/ui/result_map_unit_fn_fixable.fixed b/tests/ui/result_map_unit_fn_fixable.fixed index 3890f916b606..6bee013c3f47 100644 --- a/tests/ui/result_map_unit_fn_fixable.fixed +++ b/tests/ui/result_map_unit_fn_fixable.fixed @@ -32,50 +32,68 @@ fn result_map_unit_fn() { let _: Result<(), usize> = x.field.map(do_nothing); if let Ok(x_field) = x.field { do_nothing(x_field) } + //~^ result_map_unit_fn if let Ok(x_field) = x.field { do_nothing(x_field) } + //~^ result_map_unit_fn if let Ok(x_field) = x.field { diverge(x_field) } + //~^ result_map_unit_fn let captured = 10; if let Ok(value) = x.field { do_nothing(value + captured) }; let _: Result<(), usize> = x.field.map(|value| do_nothing(value + captured)); if let Ok(value) = x.field { x.do_result_nothing(value + captured) } + //~^ result_map_unit_fn if let Ok(value) = x.field { x.do_result_plus_one(value + captured); } + //~^ result_map_unit_fn if let Ok(value) = x.field { do_nothing(value + captured) } + //~^ result_map_unit_fn if let Ok(value) = x.field { do_nothing(value + captured) } + //~^ result_map_unit_fn if let Ok(value) = x.field { do_nothing(value + captured); } + //~^ result_map_unit_fn if let Ok(value) = x.field { do_nothing(value + captured); } + //~^ result_map_unit_fn if let Ok(value) = x.field { diverge(value + captured) } + //~^ result_map_unit_fn if let Ok(value) = x.field { diverge(value + captured) } + //~^ result_map_unit_fn if let Ok(value) = x.field { diverge(value + captured); } + //~^ result_map_unit_fn if let Ok(value) = x.field { diverge(value + captured); } + //~^ result_map_unit_fn x.field.map(|value| plus_one(value + captured)); x.field.map(|value| { plus_one(value + captured) }); if let Ok(value) = x.field { let y = plus_one(value + captured); } + //~^ result_map_unit_fn if let Ok(value) = x.field { plus_one(value + captured); } + //~^ result_map_unit_fn if let Ok(value) = x.field { plus_one(value + captured); } + //~^ result_map_unit_fn if let Ok(ref value) = x.field { do_nothing(value + captured) } + //~^ result_map_unit_fn if let Ok(value) = x.field { println!("{:?}", value) } + //~^ result_map_unit_fn } fn main() {} diff --git a/tests/ui/result_map_unit_fn_fixable.rs b/tests/ui/result_map_unit_fn_fixable.rs index c3f5aca7bfbe..a206cfe6842f 100644 --- a/tests/ui/result_map_unit_fn_fixable.rs +++ b/tests/ui/result_map_unit_fn_fixable.rs @@ -32,50 +32,68 @@ fn result_map_unit_fn() { let _: Result<(), usize> = x.field.map(do_nothing); x.field.map(do_nothing); + //~^ result_map_unit_fn x.field.map(do_nothing); + //~^ result_map_unit_fn x.field.map(diverge); + //~^ result_map_unit_fn let captured = 10; if let Ok(value) = x.field { do_nothing(value + captured) }; let _: Result<(), usize> = x.field.map(|value| do_nothing(value + captured)); x.field.map(|value| x.do_result_nothing(value + captured)); + //~^ result_map_unit_fn x.field.map(|value| { x.do_result_plus_one(value + captured); }); + //~^ result_map_unit_fn x.field.map(|value| do_nothing(value + captured)); + //~^ result_map_unit_fn x.field.map(|value| { do_nothing(value + captured) }); + //~^ result_map_unit_fn x.field.map(|value| { do_nothing(value + captured); }); + //~^ result_map_unit_fn x.field.map(|value| { { do_nothing(value + captured); } }); + //~^ result_map_unit_fn x.field.map(|value| diverge(value + captured)); + //~^ result_map_unit_fn x.field.map(|value| { diverge(value + captured) }); + //~^ result_map_unit_fn x.field.map(|value| { diverge(value + captured); }); + //~^ result_map_unit_fn x.field.map(|value| { { diverge(value + captured); } }); + //~^ result_map_unit_fn x.field.map(|value| plus_one(value + captured)); x.field.map(|value| { plus_one(value + captured) }); x.field.map(|value| { let y = plus_one(value + captured); }); + //~^ result_map_unit_fn x.field.map(|value| { plus_one(value + captured); }); + //~^ result_map_unit_fn x.field.map(|value| { { plus_one(value + captured); } }); + //~^ result_map_unit_fn x.field.map(|ref value| { do_nothing(value + captured) }); + //~^ result_map_unit_fn x.field.map(|value| println!("{:?}", value)); + //~^ result_map_unit_fn } fn main() {} diff --git a/tests/ui/result_map_unit_fn_fixable.stderr b/tests/ui/result_map_unit_fn_fixable.stderr index 4f3bc2e95449..eca844e06cc0 100644 --- a/tests/ui/result_map_unit_fn_fixable.stderr +++ b/tests/ui/result_map_unit_fn_fixable.stderr @@ -10,7 +10,7 @@ LL | x.field.map(do_nothing); = help: to override `-D warnings` add `#[allow(clippy::result_map_unit_fn)]` error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:36:5 + --> tests/ui/result_map_unit_fn_fixable.rs:37:5 | LL | x.field.map(do_nothing); | ^^^^^^^^^^^^^^^^^^^^^^^- @@ -18,7 +18,7 @@ LL | x.field.map(do_nothing); | help: try: `if let Ok(x_field) = x.field { do_nothing(x_field) }` error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:38:5 + --> tests/ui/result_map_unit_fn_fixable.rs:40:5 | LL | x.field.map(diverge); | ^^^^^^^^^^^^^^^^^^^^- @@ -26,7 +26,7 @@ LL | x.field.map(diverge); | help: try: `if let Ok(x_field) = x.field { diverge(x_field) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:44:5 + --> tests/ui/result_map_unit_fn_fixable.rs:47:5 | LL | x.field.map(|value| x.do_result_nothing(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -34,7 +34,7 @@ LL | x.field.map(|value| x.do_result_nothing(value + captured)); | help: try: `if let Ok(value) = x.field { x.do_result_nothing(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:46:5 + --> tests/ui/result_map_unit_fn_fixable.rs:50:5 | LL | x.field.map(|value| { x.do_result_plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -42,7 +42,7 @@ LL | x.field.map(|value| { x.do_result_plus_one(value + captured); }); | help: try: `if let Ok(value) = x.field { x.do_result_plus_one(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:49:5 + --> tests/ui/result_map_unit_fn_fixable.rs:54:5 | LL | x.field.map(|value| do_nothing(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -50,7 +50,7 @@ LL | x.field.map(|value| do_nothing(value + captured)); | help: try: `if let Ok(value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:51:5 + --> tests/ui/result_map_unit_fn_fixable.rs:57:5 | LL | x.field.map(|value| { do_nothing(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -58,7 +58,7 @@ LL | x.field.map(|value| { do_nothing(value + captured) }); | help: try: `if let Ok(value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:53:5 + --> tests/ui/result_map_unit_fn_fixable.rs:60:5 | LL | x.field.map(|value| { do_nothing(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -66,7 +66,7 @@ LL | x.field.map(|value| { do_nothing(value + captured); }); | help: try: `if let Ok(value) = x.field { do_nothing(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:55:5 + --> tests/ui/result_map_unit_fn_fixable.rs:63:5 | LL | x.field.map(|value| { { do_nothing(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -74,7 +74,7 @@ LL | x.field.map(|value| { { do_nothing(value + captured); } }); | help: try: `if let Ok(value) = x.field { do_nothing(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:58:5 + --> tests/ui/result_map_unit_fn_fixable.rs:67:5 | LL | x.field.map(|value| diverge(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -82,7 +82,7 @@ LL | x.field.map(|value| diverge(value + captured)); | help: try: `if let Ok(value) = x.field { diverge(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:60:5 + --> tests/ui/result_map_unit_fn_fixable.rs:70:5 | LL | x.field.map(|value| { diverge(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -90,7 +90,7 @@ LL | x.field.map(|value| { diverge(value + captured) }); | help: try: `if let Ok(value) = x.field { diverge(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:62:5 + --> tests/ui/result_map_unit_fn_fixable.rs:73:5 | LL | x.field.map(|value| { diverge(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -98,7 +98,7 @@ LL | x.field.map(|value| { diverge(value + captured); }); | help: try: `if let Ok(value) = x.field { diverge(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:64:5 + --> tests/ui/result_map_unit_fn_fixable.rs:76:5 | LL | x.field.map(|value| { { diverge(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -106,7 +106,7 @@ LL | x.field.map(|value| { { diverge(value + captured); } }); | help: try: `if let Ok(value) = x.field { diverge(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:69:5 + --> tests/ui/result_map_unit_fn_fixable.rs:82:5 | LL | x.field.map(|value| { let y = plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -114,7 +114,7 @@ LL | x.field.map(|value| { let y = plus_one(value + captured); }); | help: try: `if let Ok(value) = x.field { let y = plus_one(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:71:5 + --> tests/ui/result_map_unit_fn_fixable.rs:85:5 | LL | x.field.map(|value| { plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -122,7 +122,7 @@ LL | x.field.map(|value| { plus_one(value + captured); }); | help: try: `if let Ok(value) = x.field { plus_one(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:73:5 + --> tests/ui/result_map_unit_fn_fixable.rs:88:5 | LL | x.field.map(|value| { { plus_one(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -130,7 +130,7 @@ LL | x.field.map(|value| { { plus_one(value + captured); } }); | help: try: `if let Ok(value) = x.field { plus_one(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:76:5 + --> tests/ui/result_map_unit_fn_fixable.rs:92:5 | LL | x.field.map(|ref value| { do_nothing(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -138,7 +138,7 @@ LL | x.field.map(|ref value| { do_nothing(value + captured) }); | help: try: `if let Ok(ref value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_fixable.rs:78:5 + --> tests/ui/result_map_unit_fn_fixable.rs:95:5 | LL | x.field.map(|value| println!("{:?}", value)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- diff --git a/tests/ui/result_map_unit_fn_unfixable.rs b/tests/ui/result_map_unit_fn_unfixable.rs index 62798b6d3d6f..fe3d8ece39f4 100644 --- a/tests/ui/result_map_unit_fn_unfixable.rs +++ b/tests/ui/result_map_unit_fn_unfixable.rs @@ -21,33 +21,39 @@ fn result_map_unit_fn() { let x = HasResult { field: Ok(10) }; x.field.map(|value| { do_nothing(value); do_nothing(value) }); - //~^ ERROR: called `map(f)` on an `Result` value where `f` is a closure that returns t - //~| NOTE: `-D clippy::result-map-unit-fn` implied by `-D warnings` + //~^ result_map_unit_fn + + x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) }); - //~^ ERROR: called `map(f)` on an `Result` value where `f` is a closure that returns t + //~^ result_map_unit_fn + // Suggestion for the let block should be `{ ... }` as it's too difficult to build a // proper suggestion for these cases x.field.map(|value| { - //~^ ERROR: called `map(f)` on an `Result` value where `f` is a closure that returns t + //~^ result_map_unit_fn + do_nothing(value); do_nothing(value) }); x.field.map(|value| { do_nothing(value); do_nothing(value); }); - //~^ ERROR: called `map(f)` on an `Result` value where `f` is a closure that returns t + //~^ result_map_unit_fn + // The following should suggest `if let Ok(_X) ...` as it's difficult to generate a proper let variable name for them let res: Result = Ok(42).map(diverge); "12".parse::().map(diverge); - //~^ ERROR: called `map(f)` on an `Result` value where `f` is a function that returns + //~^ result_map_unit_fn + let res: Result<(), usize> = Ok(plus_one(1)).map(do_nothing); // Should suggest `if let Ok(_y) ...` to not override the existing foo variable let y: Result = Ok(42); y.map(do_nothing); - //~^ ERROR: called `map(f)` on an `Result` value where `f` is a function that returns + //~^ result_map_unit_fn + } fn main() {} diff --git a/tests/ui/result_map_unit_fn_unfixable.stderr b/tests/ui/result_map_unit_fn_unfixable.stderr index d69c86c70e29..a6e38d808afa 100644 --- a/tests/ui/result_map_unit_fn_unfixable.stderr +++ b/tests/ui/result_map_unit_fn_unfixable.stderr @@ -10,7 +10,7 @@ LL | x.field.map(|value| { do_nothing(value); do_nothing(value) }); = help: to override `-D warnings` add `#[allow(clippy::result_map_unit_fn)]` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_unfixable.rs:27:5 + --> tests/ui/result_map_unit_fn_unfixable.rs:28:5 | LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -18,10 +18,11 @@ LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) | help: try: `if let Ok(value) = x.field { ... }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_unfixable.rs:32:5 + --> tests/ui/result_map_unit_fn_unfixable.rs:34:5 | LL | // x.field.map(|value| { LL | || +LL | || LL | || do_nothing(value); LL | || do_nothing(value) LL | || }); @@ -30,7 +31,7 @@ LL | || }); | error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> tests/ui/result_map_unit_fn_unfixable.rs:37:5 + --> tests/ui/result_map_unit_fn_unfixable.rs:40:5 | LL | x.field.map(|value| { do_nothing(value); do_nothing(value); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -38,7 +39,7 @@ LL | x.field.map(|value| { do_nothing(value); do_nothing(value); }); | help: try: `if let Ok(value) = x.field { ... }` error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()` - --> tests/ui/result_map_unit_fn_unfixable.rs:42:5 + --> tests/ui/result_map_unit_fn_unfixable.rs:46:5 | LL | "12".parse::().map(diverge); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -46,7 +47,7 @@ LL | "12".parse::().map(diverge); | help: try: `if let Ok(a) = "12".parse::() { diverge(a) }` error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()` - --> tests/ui/result_map_unit_fn_unfixable.rs:49:5 + --> tests/ui/result_map_unit_fn_unfixable.rs:54:5 | LL | y.map(do_nothing); | ^^^^^^^^^^^^^^^^^- diff --git a/tests/ui/result_unit_error.rs b/tests/ui/result_unit_error.rs index f3159f2e9515..a6cf36bff913 100644 --- a/tests/ui/result_unit_error.rs +++ b/tests/ui/result_unit_error.rs @@ -1,7 +1,8 @@ #![warn(clippy::result_unit_err)] pub fn returns_unit_error() -> Result { - //~^ ERROR: this returns a `Result<_, ()>` +//~^ result_unit_err + Err(()) } @@ -11,10 +12,12 @@ fn private_unit_errors() -> Result { pub trait HasUnitError { fn get_that_error(&self) -> Result; - //~^ ERROR: this returns a `Result<_, ()>` + //~^ result_unit_err + fn get_this_one_too(&self) -> Result { - //~^ ERROR: this returns a `Result<_, ()>` + //~^ result_unit_err + Err(()) } } @@ -33,7 +36,8 @@ pub struct UnitErrorHolder; impl UnitErrorHolder { pub fn unit_error(&self) -> Result { - //~^ ERROR: this returns a `Result<_, ()>` + //~^ result_unit_err + Ok(0) } } @@ -43,7 +47,8 @@ pub mod issue_6546 { type ResInv = Result; pub fn should_lint() -> ResInv<(), usize> { - //~^ ERROR: this returns a `Result<_, ()>` + //~^ result_unit_err + Ok(0) } diff --git a/tests/ui/result_unit_error.stderr b/tests/ui/result_unit_error.stderr index e869a3159775..a59271f8f72e 100644 --- a/tests/ui/result_unit_error.stderr +++ b/tests/ui/result_unit_error.stderr @@ -9,7 +9,7 @@ LL | pub fn returns_unit_error() -> Result { = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]` error: this returns a `Result<_, ()>` - --> tests/ui/result_unit_error.rs:13:5 + --> tests/ui/result_unit_error.rs:14:5 | LL | fn get_that_error(&self) -> Result; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn get_that_error(&self) -> Result; = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/result_unit_error.rs:16:5 + --> tests/ui/result_unit_error.rs:18:5 | LL | fn get_this_one_too(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | fn get_this_one_too(&self) -> Result { = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/result_unit_error.rs:35:5 + --> tests/ui/result_unit_error.rs:38:5 | LL | pub fn unit_error(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | pub fn unit_error(&self) -> Result { = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/result_unit_error.rs:45:5 + --> tests/ui/result_unit_error.rs:49:5 | LL | pub fn should_lint() -> ResInv<(), usize> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/result_unit_error_no_std.rs b/tests/ui/result_unit_error_no_std.rs index c9f4996c3689..cd2b17a52234 100644 --- a/tests/ui/result_unit_error_no_std.rs +++ b/tests/ui/result_unit_error_no_std.rs @@ -10,6 +10,7 @@ pub fn returns_unit_error_no_lint() -> Result { #[clippy::msrv = "1.81"] pub fn returns_unit_error_lint() -> Result { +//~^ result_unit_err Err(()) } diff --git a/tests/ui/return_and_then.fixed b/tests/ui/return_and_then.fixed index 9736a51ac868..732854d2b969 100644 --- a/tests/ui/return_and_then.fixed +++ b/tests/ui/return_and_then.fixed @@ -3,40 +3,47 @@ fn main() { fn test_opt_block(opt: Option) -> Option { let n = opt?; - let mut ret = n + 1; - ret += n; - if n > 1 { Some(ret) } else { None } + //~^ return_and_then + let mut ret = n + 1; + ret += n; + if n > 1 { Some(ret) } else { None } } fn test_opt_func(opt: Option) -> Option { let n = opt?; test_opt_block(Some(n)) + //~^ return_and_then } fn test_call_chain() -> Option { let n = gen_option(1)?; test_opt_block(Some(n)) + //~^ return_and_then } fn test_res_block(opt: Result) -> Result { let n = opt?; if n > 1 { Ok(n + 1) } else { Err(n) } + //~^ return_and_then } fn test_res_func(opt: Result) -> Result { let n = opt?; test_res_block(Ok(n)) + //~^ return_and_then } fn test_ref_only() -> Option { // ref: empty string let x = Some("")?; if x.len() > 2 { Some(3) } else { None } + //~^ return_and_then } fn test_tmp_only() -> Option { // unused temporary: vec![1, 2, 4] let x = Some(match (vec![1, 2, 3], vec![1, 2, 4]) { + //~^ return_and_then (a, _) if a.len() > 1 => a, (_, b) => b, })?; diff --git a/tests/ui/return_and_then.rs b/tests/ui/return_and_then.rs index 8bcbdfc3a632..cfefee373c78 100644 --- a/tests/ui/return_and_then.rs +++ b/tests/ui/return_and_then.rs @@ -3,6 +3,7 @@ fn main() { fn test_opt_block(opt: Option) -> Option { opt.and_then(|n| { + //~^ return_and_then let mut ret = n + 1; ret += n; if n > 1 { Some(ret) } else { None } @@ -11,28 +12,34 @@ fn main() { fn test_opt_func(opt: Option) -> Option { opt.and_then(|n| test_opt_block(Some(n))) + //~^ return_and_then } fn test_call_chain() -> Option { gen_option(1).and_then(|n| test_opt_block(Some(n))) + //~^ return_and_then } fn test_res_block(opt: Result) -> Result { opt.and_then(|n| if n > 1 { Ok(n + 1) } else { Err(n) }) + //~^ return_and_then } fn test_res_func(opt: Result) -> Result { opt.and_then(|n| test_res_block(Ok(n))) + //~^ return_and_then } fn test_ref_only() -> Option { // ref: empty string Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None }) + //~^ return_and_then } fn test_tmp_only() -> Option { // unused temporary: vec![1, 2, 4] Some(match (vec![1, 2, 3], vec![1, 2, 4]) { + //~^ return_and_then (a, _) if a.len() > 1 => a, (_, b) => b, }) diff --git a/tests/ui/return_and_then.stderr b/tests/ui/return_and_then.stderr index b2e8bf2ca45a..ef5f7417de78 100644 --- a/tests/ui/return_and_then.stderr +++ b/tests/ui/return_and_then.stderr @@ -2,6 +2,7 @@ error: use the question mark operator instead of an `and_then` call --> tests/ui/return_and_then.rs:5:9 | LL | / opt.and_then(|n| { +LL | | LL | | let mut ret = n + 1; LL | | ret += n; LL | | if n > 1 { Some(ret) } else { None } @@ -13,13 +14,14 @@ LL | | }) help: try | LL ~ let n = opt?; -LL + let mut ret = n + 1; -LL + ret += n; -LL + if n > 1 { Some(ret) } else { None } +LL + +LL + let mut ret = n + 1; +LL + ret += n; +LL + if n > 1 { Some(ret) } else { None } | error: use the question mark operator instead of an `and_then` call - --> tests/ui/return_and_then.rs:13:9 + --> tests/ui/return_and_then.rs:14:9 | LL | opt.and_then(|n| test_opt_block(Some(n))) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +33,7 @@ LL + test_opt_block(Some(n)) | error: use the question mark operator instead of an `and_then` call - --> tests/ui/return_and_then.rs:17:9 + --> tests/ui/return_and_then.rs:19:9 | LL | gen_option(1).and_then(|n| test_opt_block(Some(n))) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +45,7 @@ LL + test_opt_block(Some(n)) | error: use the question mark operator instead of an `and_then` call - --> tests/ui/return_and_then.rs:21:9 + --> tests/ui/return_and_then.rs:24:9 | LL | opt.and_then(|n| if n > 1 { Ok(n + 1) } else { Err(n) }) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -55,7 +57,7 @@ LL + if n > 1 { Ok(n + 1) } else { Err(n) } | error: use the question mark operator instead of an `and_then` call - --> tests/ui/return_and_then.rs:25:9 + --> tests/ui/return_and_then.rs:29:9 | LL | opt.and_then(|n| test_res_block(Ok(n))) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +69,7 @@ LL + test_res_block(Ok(n)) | error: use the question mark operator instead of an `and_then` call - --> tests/ui/return_and_then.rs:30:9 + --> tests/ui/return_and_then.rs:35:9 | LL | Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None }) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,9 +81,10 @@ LL + if x.len() > 2 { Some(3) } else { None } | error: use the question mark operator instead of an `and_then` call - --> tests/ui/return_and_then.rs:35:9 + --> tests/ui/return_and_then.rs:41:9 | LL | / Some(match (vec![1, 2, 3], vec![1, 2, 4]) { +LL | | LL | | (a, _) if a.len() > 1 => a, LL | | (_, b) => b, LL | | }) @@ -91,6 +94,7 @@ LL | | .and_then(|x| if x.len() > 2 { Some(3) } else { None }) help: try | LL ~ let x = Some(match (vec![1, 2, 3], vec![1, 2, 4]) { +LL + LL + (a, _) if a.len() > 1 => a, LL + (_, b) => b, LL + })?; diff --git a/tests/ui/return_self_not_must_use.rs b/tests/ui/return_self_not_must_use.rs index ec6f0feb8e65..2e9a29aea0d7 100644 --- a/tests/ui/return_self_not_must_use.rs +++ b/tests/ui/return_self_not_must_use.rs @@ -6,7 +6,8 @@ pub struct Bar; pub trait Whatever { fn what(&self) -> Self; - //~^ ERROR: missing `#[must_use]` attribute on a method returning `Self` + //~^ return_self_not_must_use + // There should be no warning here! (returns a reference) fn what2(&self) -> &Self; } @@ -17,11 +18,13 @@ impl Bar { Self } pub fn foo(&self) -> Self { - //~^ ERROR: missing `#[must_use]` attribute on a method returning `Self` + //~^ return_self_not_must_use + Self } pub fn bar(self) -> Self { - //~^ ERROR: missing `#[must_use]` attribute on a method returning `Self` + //~^ return_self_not_must_use + self } // There should be no warning here! (private method) diff --git a/tests/ui/return_self_not_must_use.stderr b/tests/ui/return_self_not_must_use.stderr index 01f826b94a80..3e6a28f32920 100644 --- a/tests/ui/return_self_not_must_use.stderr +++ b/tests/ui/return_self_not_must_use.stderr @@ -9,10 +9,11 @@ LL | fn what(&self) -> Self; = help: to override `-D warnings` add `#[allow(clippy::return_self_not_must_use)]` error: missing `#[must_use]` attribute on a method returning `Self` - --> tests/ui/return_self_not_must_use.rs:19:5 + --> tests/ui/return_self_not_must_use.rs:20:5 | LL | / pub fn foo(&self) -> Self { LL | | +LL | | LL | | Self LL | | } | |_____^ @@ -20,10 +21,11 @@ LL | | } = help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type error: missing `#[must_use]` attribute on a method returning `Self` - --> tests/ui/return_self_not_must_use.rs:23:5 + --> tests/ui/return_self_not_must_use.rs:25:5 | LL | / pub fn bar(self) -> Self { LL | | +LL | | LL | | self LL | | } | |_____^ diff --git a/tests/ui/reversed_empty_ranges_fixable.fixed b/tests/ui/reversed_empty_ranges_fixable.fixed index c8bf1b35085d..ba5059bbaa37 100644 --- a/tests/ui/reversed_empty_ranges_fixable.fixed +++ b/tests/ui/reversed_empty_ranges_fixable.fixed @@ -7,10 +7,14 @@ fn main() { // These should be linted: (21..=42).rev().for_each(|x| println!("{}", x)); + //~^ reversed_empty_ranges let _ = (21..ANSWER).rev().filter(|x| x % 2 == 0).take(10).collect::>(); + //~^ reversed_empty_ranges for _ in (-42..=-21).rev() {} + //~^ reversed_empty_ranges for _ in (21u32..42u32).rev() {} + //~^ reversed_empty_ranges // These should be ignored as they are not empty ranges: diff --git a/tests/ui/reversed_empty_ranges_fixable.rs b/tests/ui/reversed_empty_ranges_fixable.rs index 6733c096420b..4068bc393066 100644 --- a/tests/ui/reversed_empty_ranges_fixable.rs +++ b/tests/ui/reversed_empty_ranges_fixable.rs @@ -7,10 +7,14 @@ fn main() { // These should be linted: (42..=21).for_each(|x| println!("{}", x)); + //~^ reversed_empty_ranges let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::>(); + //~^ reversed_empty_ranges for _ in -21..=-42 {} + //~^ reversed_empty_ranges for _ in 42u32..21u32 {} + //~^ reversed_empty_ranges // These should be ignored as they are not empty ranges: diff --git a/tests/ui/reversed_empty_ranges_fixable.stderr b/tests/ui/reversed_empty_ranges_fixable.stderr index 3747eb9deebc..706413726a12 100644 --- a/tests/ui/reversed_empty_ranges_fixable.stderr +++ b/tests/ui/reversed_empty_ranges_fixable.stderr @@ -12,7 +12,7 @@ LL | (21..=42).rev().for_each(|x| println!("{}", x)); | ~~~~~~~~~~~~~~~ error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_fixable.rs:10:13 + --> tests/ui/reversed_empty_ranges_fixable.rs:11:13 | LL | let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::>(); | ^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = (21..ANSWER).rev().filter(|x| x % 2 == 0).take(10).collect:: tests/ui/reversed_empty_ranges_fixable.rs:12:14 + --> tests/ui/reversed_empty_ranges_fixable.rs:14:14 | LL | for _ in -21..=-42 {} | ^^^^^^^^^ @@ -34,7 +34,7 @@ LL | for _ in (-42..=-21).rev() {} | ~~~~~~~~~~~~~~~~~ error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_fixable.rs:13:14 + --> tests/ui/reversed_empty_ranges_fixable.rs:16:14 | LL | for _ in 42u32..21u32 {} | ^^^^^^^^^^^^ diff --git a/tests/ui/reversed_empty_ranges_loops_fixable.fixed b/tests/ui/reversed_empty_ranges_loops_fixable.fixed index df5f2c441f41..5d7f852e4e53 100644 --- a/tests/ui/reversed_empty_ranges_loops_fixable.fixed +++ b/tests/ui/reversed_empty_ranges_loops_fixable.fixed @@ -5,14 +5,17 @@ fn main() { const MAX_LEN: usize = 42; for i in (0..10).rev() { + //~^ reversed_empty_ranges println!("{}", i); } for i in (0..=10).rev() { + //~^ reversed_empty_ranges println!("{}", i); } for i in (0..MAX_LEN).rev() { + //~^ reversed_empty_ranges println!("{}", i); } @@ -32,15 +35,18 @@ fn main() { } for i in (0..10).rev().map(|x| x * 2) { + //~^ reversed_empty_ranges println!("{}", i); } // testing that the empty range lint folds constants for i in (5 + 4..10).rev() { + //~^ reversed_empty_ranges println!("{}", i); } for i in ((3 - 1)..(5 + 2)).rev() { + //~^ reversed_empty_ranges println!("{}", i); } diff --git a/tests/ui/reversed_empty_ranges_loops_fixable.rs b/tests/ui/reversed_empty_ranges_loops_fixable.rs index 92481be6cfc9..b65d4adb090a 100644 --- a/tests/ui/reversed_empty_ranges_loops_fixable.rs +++ b/tests/ui/reversed_empty_ranges_loops_fixable.rs @@ -5,14 +5,17 @@ fn main() { const MAX_LEN: usize = 42; for i in 10..0 { + //~^ reversed_empty_ranges println!("{}", i); } for i in 10..=0 { + //~^ reversed_empty_ranges println!("{}", i); } for i in MAX_LEN..0 { + //~^ reversed_empty_ranges println!("{}", i); } @@ -32,15 +35,18 @@ fn main() { } for i in (10..0).map(|x| x * 2) { + //~^ reversed_empty_ranges println!("{}", i); } // testing that the empty range lint folds constants for i in 10..5 + 4 { + //~^ reversed_empty_ranges println!("{}", i); } for i in (5 + 2)..(3 - 1) { + //~^ reversed_empty_ranges println!("{}", i); } diff --git a/tests/ui/reversed_empty_ranges_loops_fixable.stderr b/tests/ui/reversed_empty_ranges_loops_fixable.stderr index d5df34c42f4f..0c05f351b46f 100644 --- a/tests/ui/reversed_empty_ranges_loops_fixable.stderr +++ b/tests/ui/reversed_empty_ranges_loops_fixable.stderr @@ -12,7 +12,7 @@ LL | for i in (0..10).rev() { | ~~~~~~~~~~~~~ error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_loops_fixable.rs:11:14 + --> tests/ui/reversed_empty_ranges_loops_fixable.rs:12:14 | LL | for i in 10..=0 { | ^^^^^^ @@ -23,7 +23,7 @@ LL | for i in (0..=10).rev() { | ~~~~~~~~~~~~~~ error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_loops_fixable.rs:15:14 + --> tests/ui/reversed_empty_ranges_loops_fixable.rs:17:14 | LL | for i in MAX_LEN..0 { | ^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | for i in (0..MAX_LEN).rev() { | ~~~~~~~~~~~~~~~~~~ error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_loops_fixable.rs:34:14 + --> tests/ui/reversed_empty_ranges_loops_fixable.rs:37:14 | LL | for i in (10..0).map(|x| x * 2) { | ^^^^^^^ @@ -45,7 +45,7 @@ LL | for i in (0..10).rev().map(|x| x * 2) { | ~~~~~~~~~~~~~ error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_loops_fixable.rs:39:14 + --> tests/ui/reversed_empty_ranges_loops_fixable.rs:43:14 | LL | for i in 10..5 + 4 { | ^^^^^^^^^ @@ -56,7 +56,7 @@ LL | for i in (5 + 4..10).rev() { | ~~~~~~~~~~~~~~~~~ error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_loops_fixable.rs:43:14 + --> tests/ui/reversed_empty_ranges_loops_fixable.rs:48:14 | LL | for i in (5 + 2)..(3 - 1) { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/reversed_empty_ranges_loops_unfixable.rs b/tests/ui/reversed_empty_ranges_loops_unfixable.rs index cd1701dd4bf2..4fc7fb50a9ec 100644 --- a/tests/ui/reversed_empty_ranges_loops_unfixable.rs +++ b/tests/ui/reversed_empty_ranges_loops_unfixable.rs @@ -3,13 +3,15 @@ fn main() { for i in 5..5 { - //~^ ERROR: this range is empty so it will yield no values - //~| NOTE: `-D clippy::reversed-empty-ranges` implied by `-D warnings` + //~^ reversed_empty_ranges + + println!("{}", i); } for i in (5 + 2)..(8 - 1) { - //~^ ERROR: this range is empty so it will yield no values + //~^ reversed_empty_ranges + println!("{}", i); } } diff --git a/tests/ui/reversed_empty_ranges_loops_unfixable.stderr b/tests/ui/reversed_empty_ranges_loops_unfixable.stderr index b9e6fa04a34c..b5c17aad46bc 100644 --- a/tests/ui/reversed_empty_ranges_loops_unfixable.stderr +++ b/tests/ui/reversed_empty_ranges_loops_unfixable.stderr @@ -8,7 +8,7 @@ LL | for i in 5..5 { = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]` error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_loops_unfixable.rs:11:14 + --> tests/ui/reversed_empty_ranges_loops_unfixable.rs:12:14 | LL | for i in (5 + 2)..(8 - 1) { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/reversed_empty_ranges_unfixable.rs b/tests/ui/reversed_empty_ranges_unfixable.rs index 16c1121ae069..1ed35786a0da 100644 --- a/tests/ui/reversed_empty_ranges_unfixable.rs +++ b/tests/ui/reversed_empty_ranges_unfixable.rs @@ -6,13 +6,16 @@ const SOME_NUM: usize = 3; fn main() { let arr = [1, 2, 3, 4, 5]; let _ = &arr[3usize..=1usize]; - //~^ ERROR: this range is reversed and using it to index a slice will panic at run-tim - //~| NOTE: `-D clippy::reversed-empty-ranges` implied by `-D warnings` + //~^ reversed_empty_ranges + + let _ = &arr[SOME_NUM..1]; - //~^ ERROR: this range is reversed and using it to index a slice will panic at run-tim + //~^ reversed_empty_ranges + for _ in ANSWER..ANSWER {} - //~^ ERROR: this range is empty so it will yield no values + //~^ reversed_empty_ranges + // Should not be linted, see issue #5689 let _ = (42 + 10..42 + 10).map(|x| x / 2).find(|&x| x == 21); diff --git a/tests/ui/reversed_empty_ranges_unfixable.stderr b/tests/ui/reversed_empty_ranges_unfixable.stderr index bc2b9576c41d..770d916bad66 100644 --- a/tests/ui/reversed_empty_ranges_unfixable.stderr +++ b/tests/ui/reversed_empty_ranges_unfixable.stderr @@ -8,13 +8,13 @@ LL | let _ = &arr[3usize..=1usize]; = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]` error: this range is reversed and using it to index a slice will panic at run-time - --> tests/ui/reversed_empty_ranges_unfixable.rs:11:18 + --> tests/ui/reversed_empty_ranges_unfixable.rs:12:18 | LL | let _ = &arr[SOME_NUM..1]; | ^^^^^^^^^^^ error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_unfixable.rs:14:14 + --> tests/ui/reversed_empty_ranges_unfixable.rs:16:14 | LL | for _ in ANSWER..ANSWER {} | ^^^^^^^^^^^^^^ diff --git a/tests/ui/same_functions_in_if_condition.rs b/tests/ui/same_functions_in_if_condition.rs index a207e4221355..47954392178a 100644 --- a/tests/ui/same_functions_in_if_condition.rs +++ b/tests/ui/same_functions_in_if_condition.rs @@ -37,33 +37,39 @@ fn ifs_same_cond_fn() { if function() { } else if function() { - //~^ ERROR: `if` has the same function call as a previous `if` + //~^ same_functions_in_if_condition + } if fn_arg(a) { } else if fn_arg(a) { - //~^ ERROR: `if` has the same function call as a previous `if` + //~^ same_functions_in_if_condition + } if obj.method() { } else if obj.method() { - //~^ ERROR: `if` has the same function call as a previous `if` + //~^ same_functions_in_if_condition + } if obj.method_arg(a) { } else if obj.method_arg(a) { - //~^ ERROR: `if` has the same function call as a previous `if` + //~^ same_functions_in_if_condition + } let mut v = vec![1]; if v.pop().is_none() { } else if v.pop().is_none() { - //~^ ERROR: `if` has the same function call as a previous `if` + //~^ same_functions_in_if_condition + } if v.len() == 42 { } else if v.len() == 42 { - //~^ ERROR: `if` has the same function call as a previous `if` + //~^ same_functions_in_if_condition + } if v.len() == 1 { diff --git a/tests/ui/same_functions_in_if_condition.stderr b/tests/ui/same_functions_in_if_condition.stderr index 6cd4f96c13e3..0d40c8359557 100644 --- a/tests/ui/same_functions_in_if_condition.stderr +++ b/tests/ui/same_functions_in_if_condition.stderr @@ -16,61 +16,61 @@ LL | #![deny(clippy::same_functions_in_if_condition)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:44:15 + --> tests/ui/same_functions_in_if_condition.rs:45:15 | LL | } else if fn_arg(a) { | ^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:43:8 + --> tests/ui/same_functions_in_if_condition.rs:44:8 | LL | if fn_arg(a) { | ^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:49:15 + --> tests/ui/same_functions_in_if_condition.rs:51:15 | LL | } else if obj.method() { | ^^^^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:48:8 + --> tests/ui/same_functions_in_if_condition.rs:50:8 | LL | if obj.method() { | ^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:54:15 + --> tests/ui/same_functions_in_if_condition.rs:57:15 | LL | } else if obj.method_arg(a) { | ^^^^^^^^^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:53:8 + --> tests/ui/same_functions_in_if_condition.rs:56:8 | LL | if obj.method_arg(a) { | ^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:60:15 + --> tests/ui/same_functions_in_if_condition.rs:64:15 | LL | } else if v.pop().is_none() { | ^^^^^^^^^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:59:8 + --> tests/ui/same_functions_in_if_condition.rs:63:8 | LL | if v.pop().is_none() { | ^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:65:15 + --> tests/ui/same_functions_in_if_condition.rs:70:15 | LL | } else if v.len() == 42 { | ^^^^^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:64:8 + --> tests/ui/same_functions_in_if_condition.rs:69:8 | LL | if v.len() == 42 { | ^^^^^^^^^^^^^ diff --git a/tests/ui/same_item_push.rs b/tests/ui/same_item_push.rs index 87fd59ad3179..dbe9c729bc56 100644 --- a/tests/ui/same_item_push.rs +++ b/tests/ui/same_item_push.rs @@ -21,33 +21,38 @@ fn main() { let item = 2; for _ in 5..=20 { vec.push(item); - //~^ ERROR: it looks like the same item is being pushed into this `Vec` + //~^ same_item_push + } let mut vec: Vec = Vec::new(); for _ in 0..15 { let item = 2; vec.push(item); - //~^ ERROR: it looks like the same item is being pushed into this `Vec` + //~^ same_item_push + } let mut vec: Vec = Vec::new(); for _ in 0..15 { vec.push(13); - //~^ ERROR: it looks like the same item is being pushed into this `Vec` + //~^ same_item_push + } let mut vec = Vec::new(); for _ in 0..20 { vec.push(VALUE); - //~^ ERROR: it looks like the same item is being pushed into this `Vec` + //~^ same_item_push + } let mut vec = Vec::new(); let item = VALUE; for _ in 0..20 { vec.push(item); - //~^ ERROR: it looks like the same item is being pushed into this `Vec` + //~^ same_item_push + } #[clippy::msrv = "1.81"] @@ -56,7 +61,8 @@ fn main() { let item = VALUE; for _ in 0..20 { vec.push(item); - //~^ ERROR: it looks like the same item is being pushed into this `Vec` + //~^ same_item_push + } } diff --git a/tests/ui/same_item_push.stderr b/tests/ui/same_item_push.stderr index e3fa4f9cbcec..d2bf5069a846 100644 --- a/tests/ui/same_item_push.stderr +++ b/tests/ui/same_item_push.stderr @@ -10,7 +10,7 @@ LL | vec.push(item); = help: to override `-D warnings` add `#[allow(clippy::same_item_push)]` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:30:9 + --> tests/ui/same_item_push.rs:31:9 | LL | vec.push(item); | ^^^ @@ -19,7 +19,7 @@ LL | vec.push(item); = help: or `vec.extend(std::iter::repeat_n(item, SIZE))` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:36:9 + --> tests/ui/same_item_push.rs:38:9 | LL | vec.push(13); | ^^^ @@ -28,7 +28,7 @@ LL | vec.push(13); = help: or `vec.extend(std::iter::repeat_n(13, SIZE))` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:42:9 + --> tests/ui/same_item_push.rs:45:9 | LL | vec.push(VALUE); | ^^^ @@ -37,7 +37,7 @@ LL | vec.push(VALUE); = help: or `vec.extend(std::iter::repeat_n(VALUE, SIZE))` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:49:9 + --> tests/ui/same_item_push.rs:53:9 | LL | vec.push(item); | ^^^ @@ -46,7 +46,7 @@ LL | vec.push(item); = help: or `vec.extend(std::iter::repeat_n(item, SIZE))` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:58:13 + --> tests/ui/same_item_push.rs:63:13 | LL | vec.push(item); | ^^^ diff --git a/tests/ui/same_name_method.rs b/tests/ui/same_name_method.rs index ba876c2b5a3f..398f3a7d5f91 100644 --- a/tests/ui/same_name_method.rs +++ b/tests/ui/same_name_method.rs @@ -18,7 +18,8 @@ mod should_lint { impl S { fn foo() {} - //~^ ERROR: method's name is the same as an existing method in a trait + //~^ same_name_method + } impl T1 for S { @@ -33,7 +34,8 @@ mod should_lint { impl S { fn clone() {} - //~^ ERROR: method's name is the same as an existing method in a trait + //~^ same_name_method + } } @@ -44,7 +46,8 @@ mod should_lint { impl S { fn foo() {} - //~^ ERROR: method's name is the same as an existing method in a trait + //~^ same_name_method + } impl T1 for S { @@ -59,7 +62,8 @@ mod should_lint { impl S { fn foo() {} - //~^ ERROR: method's name is the same as an existing method in a trait + //~^ same_name_method + } impl T1 for S {} @@ -72,8 +76,10 @@ mod should_lint { impl S { fn foo() {} - //~^ ERROR: method's name is the same as an existing method in a trait - //~| ERROR: method's name is the same as an existing method in a trait + //~^ same_name_method + //~| same_name_method + + } impl T1 for S {} diff --git a/tests/ui/same_name_method.stderr b/tests/ui/same_name_method.stderr index fefdb5c9c23d..d3bf386ea545 100644 --- a/tests/ui/same_name_method.stderr +++ b/tests/ui/same_name_method.stderr @@ -5,7 +5,7 @@ LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:25:13 + --> tests/ui/same_name_method.rs:26:13 | LL | fn foo() {} | ^^^^^^^^^^^ @@ -13,62 +13,62 @@ LL | fn foo() {} = help: to override `-D warnings` add `#[allow(clippy::same_name_method)]` error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:35:13 + --> tests/ui/same_name_method.rs:36:13 | LL | fn clone() {} | ^^^^^^^^^^^^^ | note: existing `clone` defined here - --> tests/ui/same_name_method.rs:31:18 + --> tests/ui/same_name_method.rs:32:18 | LL | #[derive(Clone)] | ^^^^^ = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:46:13 + --> tests/ui/same_name_method.rs:48:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:51:13 + --> tests/ui/same_name_method.rs:54:13 | LL | fn foo() {} | ^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:61:13 + --> tests/ui/same_name_method.rs:64:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:65:9 + --> tests/ui/same_name_method.rs:69:9 | LL | impl T1 for S {} | ^^^^^^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:74:13 + --> tests/ui/same_name_method.rs:78:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:79:9 + --> tests/ui/same_name_method.rs:85:9 | LL | impl T1 for S {} | ^^^^^^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:74:13 + --> tests/ui/same_name_method.rs:78:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:81:9 + --> tests/ui/same_name_method.rs:87:9 | LL | impl T2 for S {} | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/search_is_some.rs b/tests/ui/search_is_some.rs index 9a9aaba56adc..4143b8bfba58 100644 --- a/tests/ui/search_is_some.rs +++ b/tests/ui/search_is_some.rs @@ -14,18 +14,21 @@ fn main() { // Check `find().is_some()`, multi-line case. let _ = v.iter().find(|&x| { + //~^ search_is_some *x < 0 } ).is_some(); // Check `position().is_some()`, multi-line case. let _ = v.iter().position(|&x| { + //~^ search_is_some x < 0 } ).is_some(); // Check `rposition().is_some()`, multi-line case. let _ = v.iter().rposition(|&x| { + //~^ search_is_some x < 0 } ).is_some(); @@ -41,6 +44,7 @@ fn main() { let some_closure = |x: &u32| *x == 0; let _ = (0..1).find(some_closure).is_some(); + //~^ search_is_some } #[rustfmt::skip] @@ -51,18 +55,21 @@ fn is_none() { // Check `find().is_none()`, multi-line case. let _ = v.iter().find(|&x| { + //~^ search_is_some *x < 0 } ).is_none(); // Check `position().is_none()`, multi-line case. let _ = v.iter().position(|&x| { + //~^ search_is_some x < 0 } ).is_none(); // Check `rposition().is_none()`, multi-line case. let _ = v.iter().rposition(|&x| { + //~^ search_is_some x < 0 } ).is_none(); @@ -78,4 +85,5 @@ fn is_none() { let some_closure = |x: &u32| *x == 0; let _ = (0..1).find(some_closure).is_none(); + //~^ search_is_some } diff --git a/tests/ui/search_is_some.stderr b/tests/ui/search_is_some.stderr index b5ef55341770..d9a43c8915e8 100644 --- a/tests/ui/search_is_some.stderr +++ b/tests/ui/search_is_some.stderr @@ -3,6 +3,7 @@ error: called `is_some()` after searching an `Iterator` with `find` | LL | let _ = v.iter().find(|&x| { | _____________^ +LL | | LL | | *x < 0 LL | | } LL | | ).is_some(); @@ -13,10 +14,11 @@ LL | | ).is_some(); = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]` error: called `is_some()` after searching an `Iterator` with `position` - --> tests/ui/search_is_some.rs:22:13 + --> tests/ui/search_is_some.rs:23:13 | LL | let _ = v.iter().position(|&x| { | _____________^ +LL | | LL | | x < 0 LL | | } LL | | ).is_some(); @@ -25,10 +27,11 @@ LL | | ).is_some(); = help: this is more succinctly expressed by calling `any()` error: called `is_some()` after searching an `Iterator` with `rposition` - --> tests/ui/search_is_some.rs:28:13 + --> tests/ui/search_is_some.rs:30:13 | LL | let _ = v.iter().rposition(|&x| { | _____________^ +LL | | LL | | x < 0 LL | | } LL | | ).is_some(); @@ -37,16 +40,17 @@ LL | | ).is_some(); = help: this is more succinctly expressed by calling `any()` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some.rs:43:20 + --> tests/ui/search_is_some.rs:46:20 | LL | let _ = (0..1).find(some_closure).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(some_closure)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some.rs:53:13 + --> tests/ui/search_is_some.rs:57:13 | LL | let _ = v.iter().find(|&x| { | _____________^ +LL | | LL | | *x < 0 LL | | } LL | | ).is_none(); @@ -55,10 +59,11 @@ LL | | ).is_none(); = help: this is more succinctly expressed by calling `any()` with negation error: called `is_none()` after searching an `Iterator` with `position` - --> tests/ui/search_is_some.rs:59:13 + --> tests/ui/search_is_some.rs:64:13 | LL | let _ = v.iter().position(|&x| { | _____________^ +LL | | LL | | x < 0 LL | | } LL | | ).is_none(); @@ -67,10 +72,11 @@ LL | | ).is_none(); = help: this is more succinctly expressed by calling `any()` with negation error: called `is_none()` after searching an `Iterator` with `rposition` - --> tests/ui/search_is_some.rs:65:13 + --> tests/ui/search_is_some.rs:71:13 | LL | let _ = v.iter().rposition(|&x| { | _____________^ +LL | | LL | | x < 0 LL | | } LL | | ).is_none(); @@ -79,7 +85,7 @@ LL | | ).is_none(); = help: this is more succinctly expressed by calling `any()` with negation error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some.rs:80:13 + --> tests/ui/search_is_some.rs:87:13 | LL | let _ = (0..1).find(some_closure).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(some_closure)` diff --git a/tests/ui/search_is_some_fixable_none.fixed b/tests/ui/search_is_some_fixable_none.fixed index 86a937b4dae1..e33f32d5bdb8 100644 --- a/tests/ui/search_is_some_fixable_none.fixed +++ b/tests/ui/search_is_some_fixable_none.fixed @@ -7,36 +7,55 @@ fn main() { // Check `find().is_none()`, single-line case. let _ = !v.iter().any(|x| *x < 0); + //~^ search_is_some let _ = !(0..1).any(|x| **y == x); // one dereference less + //~^ search_is_some let _ = !(0..1).any(|x| x == 0); + //~^ search_is_some let _ = !v.iter().any(|x| *x == 0); + //~^ search_is_some let _ = !(4..5).any(|x| x == 1 || x == 3 || x == 5); + //~^ search_is_some let _ = !(1..3).any(|x| [1, 2, 3].contains(&x)); + //~^ search_is_some let _ = !(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x)); + //~^ search_is_some let _ = !(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0); + //~^ search_is_some let _ = !(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1); // Check `position().is_none()`, single-line case. let _ = !v.iter().any(|&x| x < 0); + //~^ search_is_some // Check `rposition().is_none()`, single-line case. let _ = !v.iter().any(|&x| x < 0); + //~^ search_is_some let s1 = String::from("hello world"); let s2 = String::from("world"); // caller of `find()` is a `&`static str` let _ = !"hello world".contains("world"); + //~^ search_is_some let _ = !"hello world".contains(&s2); + //~^ search_is_some let _ = !"hello world".contains(&s2[2..]); + //~^ search_is_some // caller of `find()` is a `String` let _ = !s1.contains("world"); + //~^ search_is_some let _ = !s1.contains(&s2); + //~^ search_is_some let _ = !s1.contains(&s2[2..]); + //~^ search_is_some // caller of `find()` is slice of `String` let _ = !s1[2..].contains("world"); + //~^ search_is_some let _ = !s1[2..].contains(&s2); + //~^ search_is_some let _ = !s1[2..].contains(&s2[2..]); + //~^ search_is_some } #[allow(clippy::clone_on_copy, clippy::map_clone)] @@ -53,6 +72,7 @@ mod issue7392 { .hand .iter() .filter(|c| !filter_hand.iter().any(|cc| c == &cc)) + //~^ search_is_some .map(|c| c.clone()) .collect::>(); } @@ -69,6 +89,7 @@ mod issue7392 { .hand .iter() .filter(|(c, _)| !filter_hand.iter().any(|cc| c == cc)) + //~^ search_is_some .map(|c| c.clone()) .collect::>(); } @@ -80,21 +101,25 @@ mod issue7392 { } let vfoo = vec![Foo { foo: 1, bar: 2 }]; let _ = !vfoo.iter().any(|v| v.foo == 1 && v.bar == 2); + //~^ search_is_some let vfoo = vec![(42, Foo { foo: 1, bar: 2 })]; let _ = !vfoo + //~^ search_is_some .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2); } fn index_projection() { let vfoo = vec![[0, 1, 2, 3]]; let _ = !vfoo.iter().any(|a| a[0] == 42); + //~^ search_is_some } #[allow(clippy::match_like_matches_macro)] fn slice_projection() { let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]]; let _ = !vfoo.iter().any(|sub| sub[1..4].len() == 3); + //~^ search_is_some } fn please(x: &u32) -> bool { @@ -113,16 +138,22 @@ mod issue7392 { let x = 19; let ppx: &u32 = &x; let _ = ![ppx].iter().any(|ppp_x: &&u32| please(ppp_x)); + //~^ search_is_some let _ = ![String::from("Hey hey")].iter().any(|s| s.len() == 2); + //~^ search_is_some let v = vec![3, 2, 1, 0]; let _ = !v.iter().any(|x| deref_enough(*x)); + //~^ search_is_some let _ = !v.iter().any(|x: &u32| deref_enough(*x)); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = !v.iter().any(|x| arg_no_deref(&x)); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = !v.iter().any(|x: &u32| arg_no_deref(&x)); + //~^ search_is_some } fn field_index_projection() { @@ -143,6 +174,7 @@ mod issue7392 { }, }]; let _ = !vfoo + //~^ search_is_some .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2); } @@ -157,11 +189,13 @@ mod issue7392 { inner: vec![Foo { bar: 0 }], }]; let _ = !vfoo.iter().any(|v| v.inner[0].bar == 2); + //~^ search_is_some } fn double_deref_index_projection() { let vfoo = vec![&&[0, 1, 2, 3]]; let _ = !vfoo.iter().any(|x| (**x)[0] == 9); + //~^ search_is_some } fn method_call_by_ref() { @@ -175,11 +209,14 @@ mod issue7392 { } let vfoo = vec![Foo { bar: 1 }]; let _ = !vfoo.iter().any(|v| v.by_ref(&v.bar)); + //~^ search_is_some } fn ref_bindings() { let _ = ![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y); + //~^ search_is_some let _ = ![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y); + //~^ search_is_some } fn test_string_1(s: &str) -> bool { @@ -199,7 +236,9 @@ mod issue7392 { let lst = &[String::from("Hello"), String::from("world")]; let v: Vec<&[String]> = vec![lst]; let _ = !v.iter().any(|s| s[0].is_empty()); + //~^ search_is_some let _ = !v.iter().any(|s| test_string_1(&s[0])); + //~^ search_is_some // Field projections struct FieldProjection<'a> { @@ -209,8 +248,11 @@ mod issue7392 { let instance = FieldProjection { field: &field }; let v = vec![instance]; let _ = !v.iter().any(|fp| fp.field.is_power_of_two()); + //~^ search_is_some let _ = !v.iter().any(|fp| test_u32_1(fp.field)); + //~^ search_is_some let _ = !v.iter().any(|fp| test_u32_2(*fp.field)); + //~^ search_is_some } } @@ -227,39 +269,51 @@ mod issue_11910 { fn test_normal_for_iter() { let v = vec![3, 2, 1, 0, -1, -2, -3]; let _ = !v.iter().any(|x| *x == 42); + //~^ search_is_some Foo.bar(!v.iter().any(|x| *x == 42)); + //~^ search_is_some } fn test_then_for_iter() { let v = vec![3, 2, 1, 0, -1, -2, -3]; (!v.iter().any(|x| *x == 42)).then(computations); + //~^ search_is_some } fn test_then_some_for_iter() { let v = vec![3, 2, 1, 0, -1, -2, -3]; (!v.iter().any(|x| *x == 42)).then_some(0); + //~^ search_is_some } fn test_normal_for_str() { let s = "hello"; let _ = !s.contains("world"); + //~^ search_is_some Foo.bar(!s.contains("world")); + //~^ search_is_some let s = String::from("hello"); let _ = !s.contains("world"); + //~^ search_is_some Foo.bar(!s.contains("world")); + //~^ search_is_some } fn test_then_for_str() { let s = "hello"; let _ = (!s.contains("world")).then(computations); + //~^ search_is_some let s = String::from("hello"); let _ = (!s.contains("world")).then(computations); + //~^ search_is_some } fn test_then_some_for_str() { let s = "hello"; let _ = (!s.contains("world")).then_some(0); + //~^ search_is_some let s = String::from("hello"); let _ = (!s.contains("world")).then_some(0); + //~^ search_is_some } } diff --git a/tests/ui/search_is_some_fixable_none.rs b/tests/ui/search_is_some_fixable_none.rs index c0103a015097..86885c7d3be3 100644 --- a/tests/ui/search_is_some_fixable_none.rs +++ b/tests/ui/search_is_some_fixable_none.rs @@ -7,38 +7,58 @@ fn main() { // Check `find().is_none()`, single-line case. let _ = v.iter().find(|&x| *x < 0).is_none(); + //~^ search_is_some let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less + //~^ search_is_some let _ = (0..1).find(|x| *x == 0).is_none(); + //~^ search_is_some let _ = v.iter().find(|x| **x == 0).is_none(); + //~^ search_is_some let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_none(); + //~^ search_is_some let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_none(); + //~^ search_is_some let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_none(); + //~^ search_is_some let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none(); + //~^ search_is_some let _ = (1..3) + //~^ search_is_some .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1) .is_none(); // Check `position().is_none()`, single-line case. let _ = v.iter().position(|&x| x < 0).is_none(); + //~^ search_is_some // Check `rposition().is_none()`, single-line case. let _ = v.iter().rposition(|&x| x < 0).is_none(); + //~^ search_is_some let s1 = String::from("hello world"); let s2 = String::from("world"); // caller of `find()` is a `&`static str` let _ = "hello world".find("world").is_none(); + //~^ search_is_some let _ = "hello world".find(&s2).is_none(); + //~^ search_is_some let _ = "hello world".find(&s2[2..]).is_none(); + //~^ search_is_some // caller of `find()` is a `String` let _ = s1.find("world").is_none(); + //~^ search_is_some let _ = s1.find(&s2).is_none(); + //~^ search_is_some let _ = s1.find(&s2[2..]).is_none(); + //~^ search_is_some // caller of `find()` is slice of `String` let _ = s1[2..].find("world").is_none(); + //~^ search_is_some let _ = s1[2..].find(&s2).is_none(); + //~^ search_is_some let _ = s1[2..].find(&s2[2..]).is_none(); + //~^ search_is_some } #[allow(clippy::clone_on_copy, clippy::map_clone)] @@ -55,6 +75,7 @@ mod issue7392 { .hand .iter() .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none()) + //~^ search_is_some .map(|c| c.clone()) .collect::>(); } @@ -71,6 +92,7 @@ mod issue7392 { .hand .iter() .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none()) + //~^ search_is_some .map(|c| c.clone()) .collect::>(); } @@ -82,9 +104,11 @@ mod issue7392 { } let vfoo = vec![Foo { foo: 1, bar: 2 }]; let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_none(); + //~^ search_is_some let vfoo = vec![(42, Foo { foo: 1, bar: 2 })]; let _ = vfoo + //~^ search_is_some .iter() .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2) .is_none(); @@ -93,12 +117,14 @@ mod issue7392 { fn index_projection() { let vfoo = vec![[0, 1, 2, 3]]; let _ = vfoo.iter().find(|a| a[0] == 42).is_none(); + //~^ search_is_some } #[allow(clippy::match_like_matches_macro)] fn slice_projection() { let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]]; let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none(); + //~^ search_is_some } fn please(x: &u32) -> bool { @@ -117,16 +143,22 @@ mod issue7392 { let x = 19; let ppx: &u32 = &x; let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none(); + //~^ search_is_some let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_none(); + //~^ search_is_some let v = vec![3, 2, 1, 0]; let _ = v.iter().find(|x| deref_enough(**x)).is_none(); + //~^ search_is_some let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_none(); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().find(|x| arg_no_deref(x)).is_none(); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_none(); + //~^ search_is_some } fn field_index_projection() { @@ -147,6 +179,7 @@ mod issue7392 { }, }]; let _ = vfoo + //~^ search_is_some .iter() .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2) .is_none(); @@ -163,11 +196,13 @@ mod issue7392 { inner: vec![Foo { bar: 0 }], }]; let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_none(); + //~^ search_is_some } fn double_deref_index_projection() { let vfoo = vec![&&[0, 1, 2, 3]]; let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_none(); + //~^ search_is_some } fn method_call_by_ref() { @@ -181,11 +216,14 @@ mod issue7392 { } let vfoo = vec![Foo { bar: 1 }]; let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_none(); + //~^ search_is_some } fn ref_bindings() { let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_none(); + //~^ search_is_some let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_none(); + //~^ search_is_some } fn test_string_1(s: &str) -> bool { @@ -205,7 +243,9 @@ mod issue7392 { let lst = &[String::from("Hello"), String::from("world")]; let v: Vec<&[String]> = vec![lst]; let _ = v.iter().find(|s| s[0].is_empty()).is_none(); + //~^ search_is_some let _ = v.iter().find(|s| test_string_1(&s[0])).is_none(); + //~^ search_is_some // Field projections struct FieldProjection<'a> { @@ -215,8 +255,11 @@ mod issue7392 { let instance = FieldProjection { field: &field }; let v = vec![instance]; let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_none(); + //~^ search_is_some let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_none(); + //~^ search_is_some let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none(); + //~^ search_is_some } } @@ -233,39 +276,51 @@ mod issue_11910 { fn test_normal_for_iter() { let v = vec![3, 2, 1, 0, -1, -2, -3]; let _ = v.iter().find(|x| **x == 42).is_none(); + //~^ search_is_some Foo.bar(v.iter().find(|x| **x == 42).is_none()); + //~^ search_is_some } fn test_then_for_iter() { let v = vec![3, 2, 1, 0, -1, -2, -3]; v.iter().find(|x| **x == 42).is_none().then(computations); + //~^ search_is_some } fn test_then_some_for_iter() { let v = vec![3, 2, 1, 0, -1, -2, -3]; v.iter().find(|x| **x == 42).is_none().then_some(0); + //~^ search_is_some } fn test_normal_for_str() { let s = "hello"; let _ = s.find("world").is_none(); + //~^ search_is_some Foo.bar(s.find("world").is_none()); + //~^ search_is_some let s = String::from("hello"); let _ = s.find("world").is_none(); + //~^ search_is_some Foo.bar(s.find("world").is_none()); + //~^ search_is_some } fn test_then_for_str() { let s = "hello"; let _ = s.find("world").is_none().then(computations); + //~^ search_is_some let s = String::from("hello"); let _ = s.find("world").is_none().then(computations); + //~^ search_is_some } fn test_then_some_for_str() { let s = "hello"; let _ = s.find("world").is_none().then_some(0); + //~^ search_is_some let s = String::from("hello"); let _ = s.find("world").is_none().then_some(0); + //~^ search_is_some } } diff --git a/tests/ui/search_is_some_fixable_none.stderr b/tests/ui/search_is_some_fixable_none.stderr index 2c858b9fb10e..e134df9f63c9 100644 --- a/tests/ui/search_is_some_fixable_none.stderr +++ b/tests/ui/search_is_some_fixable_none.stderr @@ -8,145 +8,147 @@ LL | let _ = v.iter().find(|&x| *x < 0).is_none(); = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:10:13 + --> tests/ui/search_is_some_fixable_none.rs:11:13 | LL | let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| **y == x)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:11:13 + --> tests/ui/search_is_some_fixable_none.rs:13:13 | LL | let _ = (0..1).find(|x| *x == 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| x == 0)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:12:13 + --> tests/ui/search_is_some_fixable_none.rs:15:13 | LL | let _ = v.iter().find(|x| **x == 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 0)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:13:13 + --> tests/ui/search_is_some_fixable_none.rs:17:13 | LL | let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(4..5).any(|x| x == 1 || x == 3 || x == 5)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:14:13 + --> tests/ui/search_is_some_fixable_none.rs:19:13 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:15:13 + --> tests/ui/search_is_some_fixable_none.rs:21:13 | LL | let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:16:13 + --> tests/ui/search_is_some_fixable_none.rs:23:13 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:17:13 + --> tests/ui/search_is_some_fixable_none.rs:25:13 | LL | let _ = (1..3) | _____________^ +LL | | LL | | .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1) LL | | .is_none(); | |__________________^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)` error: called `is_none()` after searching an `Iterator` with `position` - --> tests/ui/search_is_some_fixable_none.rs:22:13 + --> tests/ui/search_is_some_fixable_none.rs:31:13 | LL | let _ = v.iter().position(|&x| x < 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)` error: called `is_none()` after searching an `Iterator` with `rposition` - --> tests/ui/search_is_some_fixable_none.rs:25:13 + --> tests/ui/search_is_some_fixable_none.rs:35:13 | LL | let _ = v.iter().rposition(|&x| x < 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:31:13 + --> tests/ui/search_is_some_fixable_none.rs:42:13 | LL | let _ = "hello world".find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:32:13 + --> tests/ui/search_is_some_fixable_none.rs:44:13 | LL | let _ = "hello world".find(&s2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains(&s2)` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:33:13 + --> tests/ui/search_is_some_fixable_none.rs:46:13 | LL | let _ = "hello world".find(&s2[2..]).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains(&s2[2..])` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:35:13 + --> tests/ui/search_is_some_fixable_none.rs:49:13 | LL | let _ = s1.find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:36:13 + --> tests/ui/search_is_some_fixable_none.rs:51:13 | LL | let _ = s1.find(&s2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2)` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:37:13 + --> tests/ui/search_is_some_fixable_none.rs:53:13 | LL | let _ = s1.find(&s2[2..]).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2[2..])` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:39:13 + --> tests/ui/search_is_some_fixable_none.rs:56:13 | LL | let _ = s1[2..].find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:40:13 + --> tests/ui/search_is_some_fixable_none.rs:58:13 | LL | let _ = s1[2..].find(&s2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2)` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:41:13 + --> tests/ui/search_is_some_fixable_none.rs:60:13 | LL | let _ = s1[2..].find(&s2[2..]).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2[2..])` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:57:25 + --> tests/ui/search_is_some_fixable_none.rs:77:25 | LL | .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == &cc)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:73:30 + --> tests/ui/search_is_some_fixable_none.rs:94:30 | LL | .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == cc)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:84:17 + --> tests/ui/search_is_some_fixable_none.rs:106:17 | LL | let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.foo == 1 && v.bar == 2)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:87:17 + --> tests/ui/search_is_some_fixable_none.rs:110:17 | LL | let _ = vfoo | _________________^ +LL | | LL | | .iter() LL | | .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2) LL | | .is_none(); @@ -155,62 +157,64 @@ LL | | .is_none(); help: consider using | LL ~ let _ = !vfoo +LL + LL ~ .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2); | error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:95:17 + --> tests/ui/search_is_some_fixable_none.rs:119:17 | LL | let _ = vfoo.iter().find(|a| a[0] == 42).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|a| a[0] == 42)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:101:17 + --> tests/ui/search_is_some_fixable_none.rs:126:17 | LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:119:17 + --> tests/ui/search_is_some_fixable_none.rs:145:17 | LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:120:17 + --> tests/ui/search_is_some_fixable_none.rs:147:17 | LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![String::from("Hey hey")].iter().any(|s| s.len() == 2)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:123:17 + --> tests/ui/search_is_some_fixable_none.rs:151:17 | LL | let _ = v.iter().find(|x| deref_enough(**x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| deref_enough(*x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:124:17 + --> tests/ui/search_is_some_fixable_none.rs:153:17 | LL | let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| deref_enough(*x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:127:17 + --> tests/ui/search_is_some_fixable_none.rs:157:17 | LL | let _ = v.iter().find(|x| arg_no_deref(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| arg_no_deref(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:129:17 + --> tests/ui/search_is_some_fixable_none.rs:160:17 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| arg_no_deref(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:149:17 + --> tests/ui/search_is_some_fixable_none.rs:181:17 | LL | let _ = vfoo | _________________^ +LL | | LL | | .iter() LL | | .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2) LL | | .is_none(); @@ -219,137 +223,138 @@ LL | | .is_none(); help: consider using | LL ~ let _ = !vfoo +LL + LL ~ .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2); | error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:165:17 + --> tests/ui/search_is_some_fixable_none.rs:198:17 | LL | let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.inner[0].bar == 2)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:170:17 + --> tests/ui/search_is_some_fixable_none.rs:204:17 | LL | let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|x| (**x)[0] == 9)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:183:17 + --> tests/ui/search_is_some_fixable_none.rs:218:17 | LL | let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.by_ref(&v.bar))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:187:17 + --> tests/ui/search_is_some_fixable_none.rs:223:17 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:188:17 + --> tests/ui/search_is_some_fixable_none.rs:225:17 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:207:17 + --> tests/ui/search_is_some_fixable_none.rs:245:17 | LL | let _ = v.iter().find(|s| s[0].is_empty()).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| s[0].is_empty())` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:208:17 + --> tests/ui/search_is_some_fixable_none.rs:247:17 | LL | let _ = v.iter().find(|s| test_string_1(&s[0])).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| test_string_1(&s[0]))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:217:17 + --> tests/ui/search_is_some_fixable_none.rs:257:17 | LL | let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| fp.field.is_power_of_two())` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:218:17 + --> tests/ui/search_is_some_fixable_none.rs:259:17 | LL | let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_1(fp.field))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:219:17 + --> tests/ui/search_is_some_fixable_none.rs:261:17 | LL | let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_2(*fp.field))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:235:17 + --> tests/ui/search_is_some_fixable_none.rs:278:17 | LL | let _ = v.iter().find(|x| **x == 42).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 42)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:236:17 + --> tests/ui/search_is_some_fixable_none.rs:280:17 | LL | Foo.bar(v.iter().find(|x| **x == 42).is_none()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 42)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:241:9 + --> tests/ui/search_is_some_fixable_none.rs:286:9 | LL | v.iter().find(|x| **x == 42).is_none().then(computations); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!v.iter().any(|x| *x == 42))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:246:9 + --> tests/ui/search_is_some_fixable_none.rs:292:9 | LL | v.iter().find(|x| **x == 42).is_none().then_some(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!v.iter().any(|x| *x == 42))` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:251:17 + --> tests/ui/search_is_some_fixable_none.rs:298:17 | LL | let _ = s.find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:252:17 + --> tests/ui/search_is_some_fixable_none.rs:300:17 | LL | Foo.bar(s.find("world").is_none()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:254:17 + --> tests/ui/search_is_some_fixable_none.rs:303:17 | LL | let _ = s.find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:255:17 + --> tests/ui/search_is_some_fixable_none.rs:305:17 | LL | Foo.bar(s.find("world").is_none()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:260:17 + --> tests/ui/search_is_some_fixable_none.rs:311:17 | LL | let _ = s.find("world").is_none().then(computations); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:262:17 + --> tests/ui/search_is_some_fixable_none.rs:314:17 | LL | let _ = s.find("world").is_none().then(computations); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:267:17 + --> tests/ui/search_is_some_fixable_none.rs:320:17 | LL | let _ = s.find("world").is_none().then_some(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:269:17 + --> tests/ui/search_is_some_fixable_none.rs:323:17 | LL | let _ = s.find("world").is_none().then_some(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` diff --git a/tests/ui/search_is_some_fixable_some.fixed b/tests/ui/search_is_some_fixable_some.fixed index ae3cbc3c4da2..69467796e0c9 100644 --- a/tests/ui/search_is_some_fixable_some.fixed +++ b/tests/ui/search_is_some_fixable_some.fixed @@ -7,36 +7,55 @@ fn main() { // Check `find().is_some()`, single-line case. let _ = v.iter().any(|x| *x < 0); + //~^ search_is_some let _ = (0..1).any(|x| **y == x); // one dereference less + //~^ search_is_some let _ = (0..1).any(|x| x == 0); + //~^ search_is_some let _ = v.iter().any(|x| *x == 0); + //~^ search_is_some let _ = (4..5).any(|x| x == 1 || x == 3 || x == 5); + //~^ search_is_some let _ = (1..3).any(|x| [1, 2, 3].contains(&x)); + //~^ search_is_some let _ = (1..3).any(|x| x == 0 || [1, 2, 3].contains(&x)); + //~^ search_is_some let _ = (1..3).any(|x| [1, 2, 3].contains(&x) || x == 0); + //~^ search_is_some let _ = (1..3) .any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1); // Check `position().is_some()`, single-line case. let _ = v.iter().any(|&x| x < 0); + //~^ search_is_some // Check `rposition().is_some()`, single-line case. let _ = v.iter().any(|&x| x < 0); + //~^ search_is_some let s1 = String::from("hello world"); let s2 = String::from("world"); // caller of `find()` is a `&`static str` let _ = "hello world".contains("world"); + //~^ search_is_some let _ = "hello world".contains(&s2); + //~^ search_is_some let _ = "hello world".contains(&s2[2..]); + //~^ search_is_some // caller of `find()` is a `String` let _ = s1.contains("world"); + //~^ search_is_some let _ = s1.contains(&s2); + //~^ search_is_some let _ = s1.contains(&s2[2..]); + //~^ search_is_some // caller of `find()` is slice of `String` let _ = s1[2..].contains("world"); + //~^ search_is_some let _ = s1[2..].contains(&s2); + //~^ search_is_some let _ = s1[2..].contains(&s2[2..]); + //~^ search_is_some } #[allow(clippy::clone_on_copy, clippy::map_clone)] @@ -53,6 +72,7 @@ mod issue7392 { .hand .iter() .filter(|c| filter_hand.iter().any(|cc| c == &cc)) + //~^ search_is_some .map(|c| c.clone()) .collect::>(); } @@ -69,6 +89,7 @@ mod issue7392 { .hand .iter() .filter(|(c, _)| filter_hand.iter().any(|cc| c == cc)) + //~^ search_is_some .map(|c| c.clone()) .collect::>(); } @@ -80,6 +101,7 @@ mod issue7392 { } let vfoo = vec![Foo { foo: 1, bar: 2 }]; let _ = vfoo.iter().any(|v| v.foo == 1 && v.bar == 2); + //~^ search_is_some let vfoo = vec![(42, Foo { foo: 1, bar: 2 })]; let _ = vfoo @@ -90,12 +112,14 @@ mod issue7392 { fn index_projection() { let vfoo = vec![[0, 1, 2, 3]]; let _ = vfoo.iter().any(|a| a[0] == 42); + //~^ search_is_some } #[allow(clippy::match_like_matches_macro)] fn slice_projection() { let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]]; let _ = vfoo.iter().any(|sub| sub[1..4].len() == 3); + //~^ search_is_some } fn please(x: &u32) -> bool { @@ -114,16 +138,22 @@ mod issue7392 { let x = 19; let ppx: &u32 = &x; let _ = [ppx].iter().any(|ppp_x: &&u32| please(ppp_x)); + //~^ search_is_some let _ = [String::from("Hey hey")].iter().any(|s| s.len() == 2); + //~^ search_is_some let v = vec![3, 2, 1, 0]; let _ = v.iter().any(|x| deref_enough(*x)); + //~^ search_is_some let _ = v.iter().any(|x: &u32| deref_enough(*x)); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().any(|x| arg_no_deref(&x)); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().any(|x: &u32| arg_no_deref(&x)); + //~^ search_is_some } fn field_index_projection() { @@ -159,11 +189,13 @@ mod issue7392 { inner: vec![Foo { bar: 0 }], }]; let _ = vfoo.iter().any(|v| v.inner[0].bar == 2); + //~^ search_is_some } fn double_deref_index_projection() { let vfoo = vec![&&[0, 1, 2, 3]]; let _ = vfoo.iter().any(|x| (**x)[0] == 9); + //~^ search_is_some } fn method_call_by_ref() { @@ -177,11 +209,14 @@ mod issue7392 { } let vfoo = vec![Foo { bar: 1 }]; let _ = vfoo.iter().any(|v| v.by_ref(&v.bar)); + //~^ search_is_some } fn ref_bindings() { let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y); + //~^ search_is_some let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y); + //~^ search_is_some } fn test_string_1(s: &str) -> bool { @@ -201,7 +236,9 @@ mod issue7392 { let lst = &[String::from("Hello"), String::from("world")]; let v: Vec<&[String]> = vec![lst]; let _ = v.iter().any(|s| s[0].is_empty()); + //~^ search_is_some let _ = v.iter().any(|s| test_string_1(&s[0])); + //~^ search_is_some // Field projections struct FieldProjection<'a> { @@ -211,8 +248,11 @@ mod issue7392 { let instance = FieldProjection { field: &field }; let v = vec![instance]; let _ = v.iter().any(|fp| fp.field.is_power_of_two()); + //~^ search_is_some let _ = v.iter().any(|fp| test_u32_1(fp.field)); + //~^ search_is_some let _ = v.iter().any(|fp| test_u32_2(*fp.field)); + //~^ search_is_some } } @@ -228,6 +268,7 @@ mod issue9120 { fn wrapper bool>(v: Vec, func: T) -> bool { #[allow(clippy::redundant_closure)] v.iter().any(|x: &u32| func(&x)) + //~^ search_is_some } fn do_tests() { @@ -237,11 +278,14 @@ mod issue9120 { #[allow(clippy::redundant_closure)] let _ = v.iter().any(|x: &u32| arg_no_deref_impl(&x)); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().any(|x: &u32| arg_no_deref_dyn(&x)); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().any(|x: &u32| (*arg_no_deref_dyn)(&x)); + //~^ search_is_some } } diff --git a/tests/ui/search_is_some_fixable_some.rs b/tests/ui/search_is_some_fixable_some.rs index 19a44803fd54..0ca80a563e28 100644 --- a/tests/ui/search_is_some_fixable_some.rs +++ b/tests/ui/search_is_some_fixable_some.rs @@ -7,37 +7,57 @@ fn main() { // Check `find().is_some()`, single-line case. let _ = v.iter().find(|&x| *x < 0).is_some(); + //~^ search_is_some let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less + //~^ search_is_some let _ = (0..1).find(|x| *x == 0).is_some(); + //~^ search_is_some let _ = v.iter().find(|x| **x == 0).is_some(); + //~^ search_is_some let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_some(); + //~^ search_is_some let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_some(); + //~^ search_is_some let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_some(); + //~^ search_is_some let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_some(); + //~^ search_is_some let _ = (1..3) .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1) + //~^ search_is_some .is_some(); // Check `position().is_some()`, single-line case. let _ = v.iter().position(|&x| x < 0).is_some(); + //~^ search_is_some // Check `rposition().is_some()`, single-line case. let _ = v.iter().rposition(|&x| x < 0).is_some(); + //~^ search_is_some let s1 = String::from("hello world"); let s2 = String::from("world"); // caller of `find()` is a `&`static str` let _ = "hello world".find("world").is_some(); + //~^ search_is_some let _ = "hello world".find(&s2).is_some(); + //~^ search_is_some let _ = "hello world".find(&s2[2..]).is_some(); + //~^ search_is_some // caller of `find()` is a `String` let _ = s1.find("world").is_some(); + //~^ search_is_some let _ = s1.find(&s2).is_some(); + //~^ search_is_some let _ = s1.find(&s2[2..]).is_some(); + //~^ search_is_some // caller of `find()` is slice of `String` let _ = s1[2..].find("world").is_some(); + //~^ search_is_some let _ = s1[2..].find(&s2).is_some(); + //~^ search_is_some let _ = s1[2..].find(&s2[2..]).is_some(); + //~^ search_is_some } #[allow(clippy::clone_on_copy, clippy::map_clone)] @@ -54,6 +74,7 @@ mod issue7392 { .hand .iter() .filter(|c| filter_hand.iter().find(|cc| c == cc).is_some()) + //~^ search_is_some .map(|c| c.clone()) .collect::>(); } @@ -70,6 +91,7 @@ mod issue7392 { .hand .iter() .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_some()) + //~^ search_is_some .map(|c| c.clone()) .collect::>(); } @@ -81,23 +103,27 @@ mod issue7392 { } let vfoo = vec![Foo { foo: 1, bar: 2 }]; let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_some(); + //~^ search_is_some let vfoo = vec![(42, Foo { foo: 1, bar: 2 })]; let _ = vfoo .iter() .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2) + //~^ search_is_some .is_some(); } fn index_projection() { let vfoo = vec![[0, 1, 2, 3]]; let _ = vfoo.iter().find(|a| a[0] == 42).is_some(); + //~^ search_is_some } #[allow(clippy::match_like_matches_macro)] fn slice_projection() { let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]]; let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some(); + //~^ search_is_some } fn please(x: &u32) -> bool { @@ -116,16 +142,22 @@ mod issue7392 { let x = 19; let ppx: &u32 = &x; let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some(); + //~^ search_is_some let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_some(); + //~^ search_is_some let v = vec![3, 2, 1, 0]; let _ = v.iter().find(|x| deref_enough(**x)).is_some(); + //~^ search_is_some let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_some(); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().find(|x| arg_no_deref(x)).is_some(); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_some(); + //~^ search_is_some } fn field_index_projection() { @@ -148,6 +180,7 @@ mod issue7392 { let _ = vfoo .iter() .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2) + //~^ search_is_some .is_some(); } @@ -162,11 +195,13 @@ mod issue7392 { inner: vec![Foo { bar: 0 }], }]; let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_some(); + //~^ search_is_some } fn double_deref_index_projection() { let vfoo = vec![&&[0, 1, 2, 3]]; let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_some(); + //~^ search_is_some } fn method_call_by_ref() { @@ -180,11 +215,14 @@ mod issue7392 { } let vfoo = vec![Foo { bar: 1 }]; let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_some(); + //~^ search_is_some } fn ref_bindings() { let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_some(); + //~^ search_is_some let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_some(); + //~^ search_is_some } fn test_string_1(s: &str) -> bool { @@ -204,7 +242,9 @@ mod issue7392 { let lst = &[String::from("Hello"), String::from("world")]; let v: Vec<&[String]> = vec![lst]; let _ = v.iter().find(|s| s[0].is_empty()).is_some(); + //~^ search_is_some let _ = v.iter().find(|s| test_string_1(&s[0])).is_some(); + //~^ search_is_some // Field projections struct FieldProjection<'a> { @@ -214,8 +254,11 @@ mod issue7392 { let instance = FieldProjection { field: &field }; let v = vec![instance]; let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_some(); + //~^ search_is_some let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_some(); + //~^ search_is_some let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_some(); + //~^ search_is_some } } @@ -231,6 +274,7 @@ mod issue9120 { fn wrapper bool>(v: Vec, func: T) -> bool { #[allow(clippy::redundant_closure)] v.iter().find(|x: &&u32| func(x)).is_some() + //~^ search_is_some } fn do_tests() { @@ -240,11 +284,14 @@ mod issue9120 { #[allow(clippy::redundant_closure)] let _ = v.iter().find(|x: &&u32| arg_no_deref_impl(x)).is_some(); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().find(|x: &&u32| arg_no_deref_dyn(x)).is_some(); + //~^ search_is_some #[allow(clippy::redundant_closure)] let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some(); + //~^ search_is_some } } diff --git a/tests/ui/search_is_some_fixable_some.stderr b/tests/ui/search_is_some_fixable_some.stderr index af1de7f82f80..3f18b0fdd3c3 100644 --- a/tests/ui/search_is_some_fixable_some.stderr +++ b/tests/ui/search_is_some_fixable_some.stderr @@ -8,283 +8,286 @@ LL | let _ = v.iter().find(|&x| *x < 0).is_some(); = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:10:20 + --> tests/ui/search_is_some_fixable_some.rs:11:20 | LL | let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| **y == x)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:11:20 + --> tests/ui/search_is_some_fixable_some.rs:13:20 | LL | let _ = (0..1).find(|x| *x == 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:12:22 + --> tests/ui/search_is_some_fixable_some.rs:15:22 | LL | let _ = v.iter().find(|x| **x == 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| *x == 0)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:13:20 + --> tests/ui/search_is_some_fixable_some.rs:17:20 | LL | let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 1 || x == 3 || x == 5)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:14:20 + --> tests/ui/search_is_some_fixable_some.rs:19:20 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:15:20 + --> tests/ui/search_is_some_fixable_some.rs:21:20 | LL | let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0 || [1, 2, 3].contains(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:16:20 + --> tests/ui/search_is_some_fixable_some.rs:23:20 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:18:10 + --> tests/ui/search_is_some_fixable_some.rs:26:10 | LL | .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1) | __________^ +LL | | LL | | .is_some(); | |__________________^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)` error: called `is_some()` after searching an `Iterator` with `position` - --> tests/ui/search_is_some_fixable_some.rs:22:22 + --> tests/ui/search_is_some_fixable_some.rs:31:22 | LL | let _ = v.iter().position(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)` error: called `is_some()` after searching an `Iterator` with `rposition` - --> tests/ui/search_is_some_fixable_some.rs:25:22 + --> tests/ui/search_is_some_fixable_some.rs:35:22 | LL | let _ = v.iter().rposition(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:30:27 + --> tests/ui/search_is_some_fixable_some.rs:41:27 | LL | let _ = "hello world".find("world").is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:31:27 + --> tests/ui/search_is_some_fixable_some.rs:43:27 | LL | let _ = "hello world".find(&s2).is_some(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:32:27 + --> tests/ui/search_is_some_fixable_some.rs:45:27 | LL | let _ = "hello world".find(&s2[2..]).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:34:16 + --> tests/ui/search_is_some_fixable_some.rs:48:16 | LL | let _ = s1.find("world").is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:35:16 + --> tests/ui/search_is_some_fixable_some.rs:50:16 | LL | let _ = s1.find(&s2).is_some(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:36:16 + --> tests/ui/search_is_some_fixable_some.rs:52:16 | LL | let _ = s1.find(&s2[2..]).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:38:21 + --> tests/ui/search_is_some_fixable_some.rs:55:21 | LL | let _ = s1[2..].find("world").is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:39:21 + --> tests/ui/search_is_some_fixable_some.rs:57:21 | LL | let _ = s1[2..].find(&s2).is_some(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:40:21 + --> tests/ui/search_is_some_fixable_some.rs:59:21 | LL | let _ = s1[2..].find(&s2[2..]).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:56:44 + --> tests/ui/search_is_some_fixable_some.rs:76:44 | LL | .filter(|c| filter_hand.iter().find(|cc| c == cc).is_some()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == &cc)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:72:49 + --> tests/ui/search_is_some_fixable_some.rs:93:49 | LL | .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_some()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == cc)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:83:29 + --> tests/ui/search_is_some_fixable_some.rs:105:29 | LL | let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.foo == 1 && v.bar == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:88:14 + --> tests/ui/search_is_some_fixable_some.rs:111:14 | LL | .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2) | ______________^ +LL | | LL | | .is_some(); | |______________________^ help: consider using: `any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:94:29 + --> tests/ui/search_is_some_fixable_some.rs:118:29 | LL | let _ = vfoo.iter().find(|a| a[0] == 42).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|a| a[0] == 42)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:100:29 + --> tests/ui/search_is_some_fixable_some.rs:125:29 | LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|sub| sub[1..4].len() == 3)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:118:30 + --> tests/ui/search_is_some_fixable_some.rs:144:30 | LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|ppp_x: &&u32| please(ppp_x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:119:50 + --> tests/ui/search_is_some_fixable_some.rs:146:50 | LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s.len() == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:122:26 + --> tests/ui/search_is_some_fixable_some.rs:150:26 | LL | let _ = v.iter().find(|x| deref_enough(**x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| deref_enough(*x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:123:26 + --> tests/ui/search_is_some_fixable_some.rs:152:26 | LL | let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| deref_enough(*x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:126:26 + --> tests/ui/search_is_some_fixable_some.rs:156:26 | LL | let _ = v.iter().find(|x| arg_no_deref(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| arg_no_deref(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:128:26 + --> tests/ui/search_is_some_fixable_some.rs:159:26 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:150:14 + --> tests/ui/search_is_some_fixable_some.rs:182:14 | LL | .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2) | ______________^ +LL | | LL | | .is_some(); | |______________________^ help: consider using: `any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:164:29 + --> tests/ui/search_is_some_fixable_some.rs:197:29 | LL | let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.inner[0].bar == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:169:29 + --> tests/ui/search_is_some_fixable_some.rs:203:29 | LL | let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| (**x)[0] == 9)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:182:29 + --> tests/ui/search_is_some_fixable_some.rs:217:29 | LL | let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.by_ref(&v.bar))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:186:55 + --> tests/ui/search_is_some_fixable_some.rs:222:55 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:187:55 + --> tests/ui/search_is_some_fixable_some.rs:224:55 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:206:26 + --> tests/ui/search_is_some_fixable_some.rs:244:26 | LL | let _ = v.iter().find(|s| s[0].is_empty()).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s[0].is_empty())` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:207:26 + --> tests/ui/search_is_some_fixable_some.rs:246:26 | LL | let _ = v.iter().find(|s| test_string_1(&s[0])).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| test_string_1(&s[0]))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:216:26 + --> tests/ui/search_is_some_fixable_some.rs:256:26 | LL | let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| fp.field.is_power_of_two())` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:217:26 + --> tests/ui/search_is_some_fixable_some.rs:258:26 | LL | let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_1(fp.field))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:218:26 + --> tests/ui/search_is_some_fixable_some.rs:260:26 | LL | let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_2(*fp.field))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:233:18 + --> tests/ui/search_is_some_fixable_some.rs:276:18 | LL | v.iter().find(|x: &&u32| func(x)).is_some() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| func(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:242:26 + --> tests/ui/search_is_some_fixable_some.rs:286:26 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref_impl(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_impl(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:245:26 + --> tests/ui/search_is_some_fixable_some.rs:290:26 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref_dyn(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_dyn(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:248:26 + --> tests/ui/search_is_some_fixable_some.rs:294:26 | LL | let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| (*arg_no_deref_dyn)(&x))` diff --git a/tests/ui/seek_from_current.fixed b/tests/ui/seek_from_current.fixed index 543f0c681393..08eb15fe4e78 100644 --- a/tests/ui/seek_from_current.fixed +++ b/tests/ui/seek_from_current.fixed @@ -17,6 +17,7 @@ fn _msrv_1_51() -> io::Result<()> { let mut f = File::create("foo.txt")?; f.write_all(b"Hi!")?; f.stream_position()?; + //~^ seek_from_current f.seek(SeekFrom::Current(1))?; Ok(()) } diff --git a/tests/ui/seek_from_current.rs b/tests/ui/seek_from_current.rs index 4ed877f8ec21..1974fd60dec7 100644 --- a/tests/ui/seek_from_current.rs +++ b/tests/ui/seek_from_current.rs @@ -17,6 +17,7 @@ fn _msrv_1_51() -> io::Result<()> { let mut f = File::create("foo.txt")?; f.write_all(b"Hi!")?; f.seek(SeekFrom::Current(0))?; + //~^ seek_from_current f.seek(SeekFrom::Current(1))?; Ok(()) } diff --git a/tests/ui/seek_to_start_instead_of_rewind.fixed b/tests/ui/seek_to_start_instead_of_rewind.fixed index 8859a68320f0..87747eafc443 100644 --- a/tests/ui/seek_to_start_instead_of_rewind.fixed +++ b/tests/ui/seek_to_start_instead_of_rewind.fixed @@ -50,11 +50,13 @@ fn seek_to_start_false_trait_bound(t: &mut T) { // This should trigger clippy warning fn seek_to_start(t: &mut T) { t.rewind(); + //~^ seek_to_start_instead_of_rewind } // This should trigger clippy warning fn owned_seek_to_start(mut t: T) { t.rewind(); + //~^ seek_to_start_instead_of_rewind } // This should NOT trigger clippy warning because @@ -134,6 +136,7 @@ fn msrv_1_55() { write!(f, "{hello}").unwrap(); f.rewind(); + //~^ seek_to_start_instead_of_rewind let mut buf = String::new(); f.read_to_string(&mut buf).unwrap(); diff --git a/tests/ui/seek_to_start_instead_of_rewind.rs b/tests/ui/seek_to_start_instead_of_rewind.rs index 7b72efb34ff8..e824a9b1ec31 100644 --- a/tests/ui/seek_to_start_instead_of_rewind.rs +++ b/tests/ui/seek_to_start_instead_of_rewind.rs @@ -50,11 +50,13 @@ fn seek_to_start_false_trait_bound(t: &mut T) { // This should trigger clippy warning fn seek_to_start(t: &mut T) { t.seek(SeekFrom::Start(0)); + //~^ seek_to_start_instead_of_rewind } // This should trigger clippy warning fn owned_seek_to_start(mut t: T) { t.seek(SeekFrom::Start(0)); + //~^ seek_to_start_instead_of_rewind } // This should NOT trigger clippy warning because @@ -134,6 +136,7 @@ fn msrv_1_55() { write!(f, "{hello}").unwrap(); f.seek(SeekFrom::Start(0)); + //~^ seek_to_start_instead_of_rewind let mut buf = String::new(); f.read_to_string(&mut buf).unwrap(); diff --git a/tests/ui/seek_to_start_instead_of_rewind.stderr b/tests/ui/seek_to_start_instead_of_rewind.stderr index 2c3c45820e10..6c6575cc02f5 100644 --- a/tests/ui/seek_to_start_instead_of_rewind.stderr +++ b/tests/ui/seek_to_start_instead_of_rewind.stderr @@ -8,13 +8,13 @@ LL | t.seek(SeekFrom::Start(0)); = help: to override `-D warnings` add `#[allow(clippy::seek_to_start_instead_of_rewind)]` error: used `seek` to go to the start of the stream - --> tests/ui/seek_to_start_instead_of_rewind.rs:57:7 + --> tests/ui/seek_to_start_instead_of_rewind.rs:58:7 | LL | t.seek(SeekFrom::Start(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()` error: used `seek` to go to the start of the stream - --> tests/ui/seek_to_start_instead_of_rewind.rs:136:7 + --> tests/ui/seek_to_start_instead_of_rewind.rs:138:7 | LL | f.seek(SeekFrom::Start(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()` diff --git a/tests/ui/self_assignment.rs b/tests/ui/self_assignment.rs index 213bca6c4515..a12a2829ba1a 100644 --- a/tests/ui/self_assignment.rs +++ b/tests/ui/self_assignment.rs @@ -11,30 +11,41 @@ pub struct S<'a> { pub fn positives(mut a: usize, b: &mut u32, mut s: S) { a = a; - //~^ ERROR: self-assignment of `a` to `a` - //~| NOTE: `-D clippy::self-assignment` implied by `-D warnings` + //~^ self_assignment + + *b = *b; - //~^ ERROR: self-assignment of `*b` to `*b` + //~^ self_assignment + s = s; - //~^ ERROR: self-assignment of `s` to `s` + //~^ self_assignment + s.a = s.a; - //~^ ERROR: self-assignment of `s.a` to `s.a` + //~^ self_assignment + s.b[9] = s.b[5 + 4]; - //~^ ERROR: self-assignment of `s.b[5 + 4]` to `s.b[9]` + //~^ self_assignment + s.c[0][1] = s.c[0][1]; - //~^ ERROR: self-assignment of `s.c[0][1]` to `s.c[0][1]` + //~^ self_assignment + s.b[a] = s.b[a]; - //~^ ERROR: self-assignment of `s.b[a]` to `s.b[a]` + //~^ self_assignment + *s.e = *s.e; - //~^ ERROR: self-assignment of `*s.e` to `*s.e` + //~^ self_assignment + s.b[a + 10] = s.b[10 + a]; - //~^ ERROR: self-assignment of `s.b[10 + a]` to `s.b[a + 10]` + //~^ self_assignment + let mut t = (0, 1); t.1 = t.1; - //~^ ERROR: self-assignment of `t.1` to `t.1` + //~^ self_assignment + t.0 = (t.0); - //~^ ERROR: self-assignment of `(t.0)` to `t.0` + //~^ self_assignment + } pub fn negatives_not_equal(mut a: usize, b: &mut usize, mut s: S) { diff --git a/tests/ui/self_assignment.stderr b/tests/ui/self_assignment.stderr index e92414163d4c..02c5b4195e9c 100644 --- a/tests/ui/self_assignment.stderr +++ b/tests/ui/self_assignment.stderr @@ -8,61 +8,61 @@ LL | a = a; = help: to override `-D warnings` add `#[allow(clippy::self_assignment)]` error: self-assignment of `*b` to `*b` - --> tests/ui/self_assignment.rs:16:5 + --> tests/ui/self_assignment.rs:17:5 | LL | *b = *b; | ^^^^^^^ error: self-assignment of `s` to `s` - --> tests/ui/self_assignment.rs:18:5 + --> tests/ui/self_assignment.rs:20:5 | LL | s = s; | ^^^^^ error: self-assignment of `s.a` to `s.a` - --> tests/ui/self_assignment.rs:20:5 + --> tests/ui/self_assignment.rs:23:5 | LL | s.a = s.a; | ^^^^^^^^^ error: self-assignment of `s.b[5 + 4]` to `s.b[9]` - --> tests/ui/self_assignment.rs:22:5 + --> tests/ui/self_assignment.rs:26:5 | LL | s.b[9] = s.b[5 + 4]; | ^^^^^^^^^^^^^^^^^^^ error: self-assignment of `s.c[0][1]` to `s.c[0][1]` - --> tests/ui/self_assignment.rs:24:5 + --> tests/ui/self_assignment.rs:29:5 | LL | s.c[0][1] = s.c[0][1]; | ^^^^^^^^^^^^^^^^^^^^^ error: self-assignment of `s.b[a]` to `s.b[a]` - --> tests/ui/self_assignment.rs:26:5 + --> tests/ui/self_assignment.rs:32:5 | LL | s.b[a] = s.b[a]; | ^^^^^^^^^^^^^^^ error: self-assignment of `*s.e` to `*s.e` - --> tests/ui/self_assignment.rs:28:5 + --> tests/ui/self_assignment.rs:35:5 | LL | *s.e = *s.e; | ^^^^^^^^^^^ error: self-assignment of `s.b[10 + a]` to `s.b[a + 10]` - --> tests/ui/self_assignment.rs:30:5 + --> tests/ui/self_assignment.rs:38:5 | LL | s.b[a + 10] = s.b[10 + a]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: self-assignment of `t.1` to `t.1` - --> tests/ui/self_assignment.rs:34:5 + --> tests/ui/self_assignment.rs:43:5 | LL | t.1 = t.1; | ^^^^^^^^^ error: self-assignment of `(t.0)` to `t.0` - --> tests/ui/self_assignment.rs:36:5 + --> tests/ui/self_assignment.rs:46:5 | LL | t.0 = (t.0); | ^^^^^^^^^^^ diff --git a/tests/ui/self_named_constructors.rs b/tests/ui/self_named_constructors.rs index dc326b399481..3dcd20b58c9d 100644 --- a/tests/ui/self_named_constructors.rs +++ b/tests/ui/self_named_constructors.rs @@ -5,8 +5,9 @@ struct ShouldNotSpawn; impl ShouldSpawn { pub fn should_spawn() -> ShouldSpawn { - //~^ ERROR: constructor `should_spawn` has the same name as the type - //~| NOTE: `-D clippy::self-named-constructors` implied by `-D warnings` + //~^ self_named_constructors + + ShouldSpawn } diff --git a/tests/ui/self_named_constructors.stderr b/tests/ui/self_named_constructors.stderr index 1d8b44f6bc2b..54d7fb939796 100644 --- a/tests/ui/self_named_constructors.stderr +++ b/tests/ui/self_named_constructors.stderr @@ -2,9 +2,7 @@ error: constructor `should_spawn` has the same name as the type --> tests/ui/self_named_constructors.rs:7:5 | LL | / pub fn should_spawn() -> ShouldSpawn { -LL | | -LL | | -LL | | ShouldSpawn +... | LL | | } | |_____^ | diff --git a/tests/ui/semicolon_if_nothing_returned.fixed b/tests/ui/semicolon_if_nothing_returned.fixed index 6c8c835d0e0e..3de14e9d2595 100644 --- a/tests/ui/semicolon_if_nothing_returned.fixed +++ b/tests/ui/semicolon_if_nothing_returned.fixed @@ -16,21 +16,25 @@ fn get_unit() {} // the functions below trigger the lint fn main() { println!("Hello"); + //~^ semicolon_if_nothing_returned } fn hello() { get_unit(); + //~^ semicolon_if_nothing_returned } fn basic101(x: i32) { let y: i32; y = x + 1; + //~^ semicolon_if_nothing_returned } #[rustfmt::skip] fn closure_error() { let _d = || { hello(); + //~^ semicolon_if_nothing_returned }; } @@ -42,6 +46,7 @@ fn unsafe_checks_error() { let mut s = MaybeUninit::::uninit(); let _d = || unsafe { ptr::drop_in_place(s.as_mut_ptr()); + //~^ semicolon_if_nothing_returned }; } diff --git a/tests/ui/semicolon_if_nothing_returned.rs b/tests/ui/semicolon_if_nothing_returned.rs index 2c2e4c024190..304f43fb457c 100644 --- a/tests/ui/semicolon_if_nothing_returned.rs +++ b/tests/ui/semicolon_if_nothing_returned.rs @@ -16,21 +16,25 @@ fn get_unit() {} // the functions below trigger the lint fn main() { println!("Hello") + //~^ semicolon_if_nothing_returned } fn hello() { get_unit() + //~^ semicolon_if_nothing_returned } fn basic101(x: i32) { let y: i32; y = x + 1 + //~^ semicolon_if_nothing_returned } #[rustfmt::skip] fn closure_error() { let _d = || { hello() + //~^ semicolon_if_nothing_returned }; } @@ -42,6 +46,7 @@ fn unsafe_checks_error() { let mut s = MaybeUninit::::uninit(); let _d = || unsafe { ptr::drop_in_place(s.as_mut_ptr()) + //~^ semicolon_if_nothing_returned }; } diff --git a/tests/ui/semicolon_if_nothing_returned.stderr b/tests/ui/semicolon_if_nothing_returned.stderr index 69e434b142cf..d7d117e05bdf 100644 --- a/tests/ui/semicolon_if_nothing_returned.stderr +++ b/tests/ui/semicolon_if_nothing_returned.stderr @@ -8,25 +8,25 @@ LL | println!("Hello") = help: to override `-D warnings` add `#[allow(clippy::semicolon_if_nothing_returned)]` error: consider adding a `;` to the last statement for consistent formatting - --> tests/ui/semicolon_if_nothing_returned.rs:22:5 + --> tests/ui/semicolon_if_nothing_returned.rs:23:5 | LL | get_unit() | ^^^^^^^^^^ help: add a `;` here: `get_unit();` error: consider adding a `;` to the last statement for consistent formatting - --> tests/ui/semicolon_if_nothing_returned.rs:27:5 + --> tests/ui/semicolon_if_nothing_returned.rs:29:5 | LL | y = x + 1 | ^^^^^^^^^ help: add a `;` here: `y = x + 1;` error: consider adding a `;` to the last statement for consistent formatting - --> tests/ui/semicolon_if_nothing_returned.rs:33:9 + --> tests/ui/semicolon_if_nothing_returned.rs:36:9 | LL | hello() | ^^^^^^^ help: add a `;` here: `hello();` error: consider adding a `;` to the last statement for consistent formatting - --> tests/ui/semicolon_if_nothing_returned.rs:44:9 + --> tests/ui/semicolon_if_nothing_returned.rs:48:9 | LL | ptr::drop_in_place(s.as_mut_ptr()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());` diff --git a/tests/ui/semicolon_inside_block.fixed b/tests/ui/semicolon_inside_block.fixed index 21681e71589e..7eb53e733ad5 100644 --- a/tests/ui/semicolon_inside_block.fixed +++ b/tests/ui/semicolon_inside_block.fixed @@ -36,7 +36,9 @@ fn main() { } { unit_fn_block(); } + //~^ semicolon_inside_block unsafe { unit_fn_block(); } + //~^ semicolon_inside_block { unit_fn_block(); } unsafe { unit_fn_block(); } @@ -45,6 +47,7 @@ fn main() { unsafe { unit_fn_block(); }; { + //~^ semicolon_inside_block unit_fn_block(); unit_fn_block(); } @@ -58,6 +61,7 @@ fn main() { }; { m!(()); } + //~^ semicolon_inside_block { m!(()); } { m!(()); }; m!(0); diff --git a/tests/ui/semicolon_inside_block.rs b/tests/ui/semicolon_inside_block.rs index 3a81661cd16f..9fa5b117194d 100644 --- a/tests/ui/semicolon_inside_block.rs +++ b/tests/ui/semicolon_inside_block.rs @@ -36,7 +36,9 @@ fn main() { } { unit_fn_block() }; + //~^ semicolon_inside_block unsafe { unit_fn_block() }; + //~^ semicolon_inside_block { unit_fn_block(); } unsafe { unit_fn_block(); } @@ -45,6 +47,7 @@ fn main() { unsafe { unit_fn_block(); }; { + //~^ semicolon_inside_block unit_fn_block(); unit_fn_block() }; @@ -58,6 +61,7 @@ fn main() { }; { m!(()) }; + //~^ semicolon_inside_block { m!(()); } { m!(()); }; m!(0); diff --git a/tests/ui/semicolon_inside_block.stderr b/tests/ui/semicolon_inside_block.stderr index d32fb681d3b9..23433f4e7ef9 100644 --- a/tests/ui/semicolon_inside_block.stderr +++ b/tests/ui/semicolon_inside_block.stderr @@ -13,7 +13,7 @@ LL + { unit_fn_block(); } | error: consider moving the `;` inside the block for consistent formatting - --> tests/ui/semicolon_inside_block.rs:39:5 + --> tests/ui/semicolon_inside_block.rs:40:5 | LL | unsafe { unit_fn_block() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,9 +25,10 @@ LL + unsafe { unit_fn_block(); } | error: consider moving the `;` inside the block for consistent formatting - --> tests/ui/semicolon_inside_block.rs:47:5 + --> tests/ui/semicolon_inside_block.rs:49:5 | LL | / { +LL | | LL | | unit_fn_block(); LL | | unit_fn_block() LL | | }; @@ -40,7 +41,7 @@ LL ~ } | error: consider moving the `;` inside the block for consistent formatting - --> tests/ui/semicolon_inside_block.rs:60:5 + --> tests/ui/semicolon_inside_block.rs:63:5 | LL | { m!(()) }; | ^^^^^^^^^^^ diff --git a/tests/ui/semicolon_outside_block.fixed b/tests/ui/semicolon_outside_block.fixed index ac7e86631cae..52fae9a3aff1 100644 --- a/tests/ui/semicolon_outside_block.fixed +++ b/tests/ui/semicolon_outside_block.fixed @@ -39,7 +39,9 @@ fn main() { unsafe { unit_fn_block() }; { unit_fn_block() }; + //~^ semicolon_outside_block unsafe { unit_fn_block() }; + //~^ semicolon_outside_block { unit_fn_block(); }; unsafe { unit_fn_block(); }; @@ -49,6 +51,7 @@ fn main() { unit_fn_block() }; { + //~^ semicolon_outside_block unit_fn_block(); unit_fn_block() }; @@ -59,6 +62,7 @@ fn main() { { m!(()) }; { m!(()) }; + //~^ semicolon_outside_block { m!(()); }; m!(0); m!(1); @@ -81,10 +85,12 @@ fn main() { { unit_fn_block(); }; unsafe { + //~^ semicolon_outside_block std::arch::asm!("") }; { + //~^ semicolon_outside_block line!() }; diff --git a/tests/ui/semicolon_outside_block.rs b/tests/ui/semicolon_outside_block.rs index 68f25339e322..5975e66fbb81 100644 --- a/tests/ui/semicolon_outside_block.rs +++ b/tests/ui/semicolon_outside_block.rs @@ -39,7 +39,9 @@ fn main() { unsafe { unit_fn_block() }; { unit_fn_block(); } + //~^ semicolon_outside_block unsafe { unit_fn_block(); } + //~^ semicolon_outside_block { unit_fn_block(); }; unsafe { unit_fn_block(); }; @@ -49,6 +51,7 @@ fn main() { unit_fn_block() }; { + //~^ semicolon_outside_block unit_fn_block(); unit_fn_block(); } @@ -59,6 +62,7 @@ fn main() { { m!(()) }; { m!(()); } + //~^ semicolon_outside_block { m!(()); }; m!(0); m!(1); @@ -81,10 +85,12 @@ fn main() { { unit_fn_block(); }; unsafe { + //~^ semicolon_outside_block std::arch::asm!(""); } { + //~^ semicolon_outside_block line!(); } diff --git a/tests/ui/semicolon_outside_block.stderr b/tests/ui/semicolon_outside_block.stderr index ff8c00048f63..18d6dc697f2e 100644 --- a/tests/ui/semicolon_outside_block.stderr +++ b/tests/ui/semicolon_outside_block.stderr @@ -13,7 +13,7 @@ LL + { unit_fn_block() }; | error: consider moving the `;` outside the block for consistent formatting - --> tests/ui/semicolon_outside_block.rs:42:5 + --> tests/ui/semicolon_outside_block.rs:43:5 | LL | unsafe { unit_fn_block(); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,9 +25,10 @@ LL + unsafe { unit_fn_block() }; | error: consider moving the `;` outside the block for consistent formatting - --> tests/ui/semicolon_outside_block.rs:51:5 + --> tests/ui/semicolon_outside_block.rs:53:5 | LL | / { +LL | | LL | | unit_fn_block(); LL | | unit_fn_block(); LL | | } @@ -40,7 +41,7 @@ LL ~ }; | error: consider moving the `;` outside the block for consistent formatting - --> tests/ui/semicolon_outside_block.rs:61:5 + --> tests/ui/semicolon_outside_block.rs:64:5 | LL | { m!(()); } | ^^^^^^^^^^^ @@ -52,9 +53,10 @@ LL + { m!(()) }; | error: consider moving the `;` outside the block for consistent formatting - --> tests/ui/semicolon_outside_block.rs:83:5 + --> tests/ui/semicolon_outside_block.rs:87:5 | LL | / unsafe { +LL | | LL | | std::arch::asm!(""); LL | | } | |_____^ @@ -66,9 +68,10 @@ LL ~ }; | error: consider moving the `;` outside the block for consistent formatting - --> tests/ui/semicolon_outside_block.rs:87:5 + --> tests/ui/semicolon_outside_block.rs:92:5 | LL | / { +LL | | LL | | line!(); LL | | } | |_____^ diff --git a/tests/ui/serde.rs b/tests/ui/serde.rs index af8b10f3e6ae..8ab1144e5700 100644 --- a/tests/ui/serde.rs +++ b/tests/ui/serde.rs @@ -37,8 +37,7 @@ impl<'de> serde::de::Visitor<'de> for B { } fn visit_string(self, _v: String) -> Result - //~^ ERROR: you should not implement `visit_string` without also implementing `visit_s - //~| NOTE: `-D clippy::serde-api-misuse` implied by `-D warnings` + //~^ serde_api_misuse where E: serde::de::Error, { diff --git a/tests/ui/serde.stderr b/tests/ui/serde.stderr index f71d41d58aae..eb6b7c6b0c36 100644 --- a/tests/ui/serde.stderr +++ b/tests/ui/serde.stderr @@ -3,9 +3,9 @@ error: you should not implement `visit_string` without also implementing `visit_ | LL | / fn visit_string(self, _v: String) -> Result LL | | -LL | | LL | | where -... | +LL | | E: serde::de::Error, +LL | | { LL | | unimplemented!() LL | | } | |_____^ diff --git a/tests/ui/set_contains_or_insert.rs b/tests/ui/set_contains_or_insert.rs index d3a3e1c878b3..0e54afe91a80 100644 --- a/tests/ui/set_contains_or_insert.rs +++ b/tests/ui/set_contains_or_insert.rs @@ -10,35 +10,42 @@ fn should_warn_hashset() { let value = 5; if !set.contains(&value) { + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if set.contains(&value) { + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if !set.contains(&value) { + //~^ set_contains_or_insert set.insert(value); } if !!set.contains(&value) { + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if (&set).contains(&value) { + //~^ set_contains_or_insert set.insert(value); } let borrow_value = &6; if !set.contains(borrow_value) { + //~^ set_contains_or_insert set.insert(*borrow_value); } let borrow_set = &mut set; if !borrow_set.contains(&value) { + //~^ set_contains_or_insert borrow_set.insert(value); } } @@ -77,35 +84,42 @@ fn should_warn_btreeset() { let value = 5; if !set.contains(&value) { + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if set.contains(&value) { + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if !set.contains(&value) { + //~^ set_contains_or_insert set.insert(value); } if !!set.contains(&value) { + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if (&set).contains(&value) { + //~^ set_contains_or_insert set.insert(value); } let borrow_value = &6; if !set.contains(borrow_value) { + //~^ set_contains_or_insert set.insert(*borrow_value); } let borrow_set = &mut set; if !borrow_set.contains(&value) { + //~^ set_contains_or_insert borrow_set.insert(value); } } diff --git a/tests/ui/set_contains_or_insert.stderr b/tests/ui/set_contains_or_insert.stderr index 14ad63005448..3152b1136458 100644 --- a/tests/ui/set_contains_or_insert.stderr +++ b/tests/ui/set_contains_or_insert.stderr @@ -3,6 +3,7 @@ error: usage of `HashSet::insert` after `HashSet::contains` | LL | if !set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ | @@ -10,106 +11,119 @@ LL | set.insert(value); = help: to override `-D warnings` add `#[allow(clippy::set_contains_or_insert)]` error: usage of `HashSet::insert` after `HashSet::contains` - --> tests/ui/set_contains_or_insert.rs:17:12 + --> tests/ui/set_contains_or_insert.rs:18:12 | LL | if set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ error: usage of `HashSet::insert` after `HashSet::contains` - --> tests/ui/set_contains_or_insert.rs:22:13 + --> tests/ui/set_contains_or_insert.rs:24:13 | LL | if !set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ error: usage of `HashSet::insert` after `HashSet::contains` - --> tests/ui/set_contains_or_insert.rs:26:14 + --> tests/ui/set_contains_or_insert.rs:29:14 | LL | if !!set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ error: usage of `HashSet::insert` after `HashSet::contains` - --> tests/ui/set_contains_or_insert.rs:31:15 + --> tests/ui/set_contains_or_insert.rs:35:15 | LL | if (&set).contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ error: usage of `HashSet::insert` after `HashSet::contains` - --> tests/ui/set_contains_or_insert.rs:36:13 + --> tests/ui/set_contains_or_insert.rs:41:13 | LL | if !set.contains(borrow_value) { | ^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | set.insert(*borrow_value); | ^^^^^^^^^^^^^^^^^^^^^ error: usage of `HashSet::insert` after `HashSet::contains` - --> tests/ui/set_contains_or_insert.rs:41:20 + --> tests/ui/set_contains_or_insert.rs:47:20 | LL | if !borrow_set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | borrow_set.insert(value); | ^^^^^^^^^^^^^ error: usage of `BTreeSet::insert` after `BTreeSet::contains` - --> tests/ui/set_contains_or_insert.rs:79:13 + --> tests/ui/set_contains_or_insert.rs:86:13 | LL | if !set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ error: usage of `BTreeSet::insert` after `BTreeSet::contains` - --> tests/ui/set_contains_or_insert.rs:84:12 + --> tests/ui/set_contains_or_insert.rs:92:12 | LL | if set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ error: usage of `BTreeSet::insert` after `BTreeSet::contains` - --> tests/ui/set_contains_or_insert.rs:89:13 + --> tests/ui/set_contains_or_insert.rs:98:13 | LL | if !set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ error: usage of `BTreeSet::insert` after `BTreeSet::contains` - --> tests/ui/set_contains_or_insert.rs:93:14 + --> tests/ui/set_contains_or_insert.rs:103:14 | LL | if !!set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ error: usage of `BTreeSet::insert` after `BTreeSet::contains` - --> tests/ui/set_contains_or_insert.rs:98:15 + --> tests/ui/set_contains_or_insert.rs:109:15 | LL | if (&set).contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | set.insert(value); | ^^^^^^^^^^^^^ error: usage of `BTreeSet::insert` after `BTreeSet::contains` - --> tests/ui/set_contains_or_insert.rs:103:13 + --> tests/ui/set_contains_or_insert.rs:115:13 | LL | if !set.contains(borrow_value) { | ^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | set.insert(*borrow_value); | ^^^^^^^^^^^^^^^^^^^^^ error: usage of `BTreeSet::insert` after `BTreeSet::contains` - --> tests/ui/set_contains_or_insert.rs:108:20 + --> tests/ui/set_contains_or_insert.rs:121:20 | LL | if !borrow_set.contains(&value) { | ^^^^^^^^^^^^^^^^ +LL | LL | borrow_set.insert(value); | ^^^^^^^^^^^^^ diff --git a/tests/ui/shadow.rs b/tests/ui/shadow.rs index 31944f5ef1b1..b44705dfc7d6 100644 --- a/tests/ui/shadow.rs +++ b/tests/ui/shadow.rs @@ -22,22 +22,34 @@ macro_rules! reuse { fn shadow_same() { let x = 1; let x = x; + //~^ shadow_same let mut x = &x; + //~^ shadow_same let x = &mut x; + //~^ shadow_same let x = *x; + //~^ shadow_same } fn shadow_reuse() -> Option<()> { let x = ([[0]], ()); let x = x.0; + //~^ shadow_reuse let x = x[0]; + //~^ shadow_reuse let [x] = x; + //~^ shadow_reuse let x = Some(x); + //~^ shadow_reuse let x = foo(x); + //~^ shadow_reuse let x = || x; + //~^ shadow_reuse let x = Some(1).map(|_| x)?; + //~^ shadow_reuse let y = 1; let y = match y { + //~^ shadow_reuse 1 => 2, _ => 3, }; @@ -53,27 +65,36 @@ fn shadow_reuse_macro() { fn shadow_unrelated() { let x = 1; let x = 2; + //~^ shadow_unrelated } fn syntax() { fn f(x: u32) { let x = 1; + //~^ shadow_unrelated } let x = 1; match Some(1) { Some(1) => {}, Some(x) => { + //~^ shadow_unrelated let x = 1; + //~^ shadow_unrelated }, _ => {}, } if let Some(x) = Some(1) {} + //~^ shadow_unrelated while let Some(x) = Some(1) {} + //~^ shadow_unrelated let _ = |[x]: [u32; 1]| { + //~^ shadow_unrelated let x = 1; + //~^ shadow_unrelated }; let y = Some(1); if let Some(y) = y {} + //~^ shadow_reuse } fn negative() { @@ -110,12 +131,14 @@ pub async fn foo1(_a: i32) {} pub async fn foo2(_a: i32, _b: i64) { let _b = _a; + //~^ shadow_unrelated } fn ice_8748() { let _ = [0; { let x = 1; if let Some(x) = Some(1) { x } else { 1 } + //~^ shadow_unrelated }]; } @@ -126,10 +149,12 @@ fn shadow_closure() { #[allow(clippy::shadow_reuse)] let y = x.map(|x| x + 1); let z = x.map(|x| x + 1); + //~^ shadow_reuse let a: Vec> = [100u8, 120, 140] .iter() .map(|i| i.checked_mul(2)) .map(|i| i.map(|i| i - 10)) + //~^ shadow_reuse .collect(); } @@ -139,6 +164,7 @@ struct Issue13795 { fn issue13795(value: Issue13795) { let Issue13795 { value, .. } = value; + //~^ shadow_same } fn main() {} diff --git a/tests/ui/shadow.stderr b/tests/ui/shadow.stderr index c8c524b3a2f5..649f843575a7 100644 --- a/tests/ui/shadow.stderr +++ b/tests/ui/shadow.stderr @@ -13,7 +13,7 @@ LL | let x = 1; = help: to override `-D warnings` add `#[allow(clippy::shadow_same)]` error: `mut x` is shadowed by itself in `&x` - --> tests/ui/shadow.rs:25:13 + --> tests/ui/shadow.rs:26:13 | LL | let mut x = &x; | ^ @@ -25,37 +25,37 @@ LL | let x = x; | ^ error: `x` is shadowed by itself in `&mut x` - --> tests/ui/shadow.rs:26:9 + --> tests/ui/shadow.rs:28:9 | LL | let x = &mut x; | ^ | note: previous binding is here - --> tests/ui/shadow.rs:25:9 + --> tests/ui/shadow.rs:26:9 | LL | let mut x = &x; | ^^^^^ error: `x` is shadowed by itself in `*x` - --> tests/ui/shadow.rs:27:9 + --> tests/ui/shadow.rs:30:9 | LL | let x = *x; | ^ | note: previous binding is here - --> tests/ui/shadow.rs:26:9 + --> tests/ui/shadow.rs:28:9 | LL | let x = &mut x; | ^ error: `x` is shadowed - --> tests/ui/shadow.rs:32:9 + --> tests/ui/shadow.rs:36:9 | LL | let x = x.0; | ^ | note: previous binding is here - --> tests/ui/shadow.rs:31:9 + --> tests/ui/shadow.rs:35:9 | LL | let x = ([[0]], ()); | ^ @@ -63,175 +63,103 @@ LL | let x = ([[0]], ()); = help: to override `-D warnings` add `#[allow(clippy::shadow_reuse)]` error: `x` is shadowed - --> tests/ui/shadow.rs:33:9 + --> tests/ui/shadow.rs:38:9 | LL | let x = x[0]; | ^ | note: previous binding is here - --> tests/ui/shadow.rs:32:9 + --> tests/ui/shadow.rs:36:9 | LL | let x = x.0; | ^ error: `x` is shadowed - --> tests/ui/shadow.rs:34:10 + --> tests/ui/shadow.rs:40:10 | LL | let [x] = x; | ^ | note: previous binding is here - --> tests/ui/shadow.rs:33:9 + --> tests/ui/shadow.rs:38:9 | LL | let x = x[0]; | ^ error: `x` is shadowed - --> tests/ui/shadow.rs:35:9 + --> tests/ui/shadow.rs:42:9 | LL | let x = Some(x); | ^ | note: previous binding is here - --> tests/ui/shadow.rs:34:10 + --> tests/ui/shadow.rs:40:10 | LL | let [x] = x; | ^ error: `x` is shadowed - --> tests/ui/shadow.rs:36:9 + --> tests/ui/shadow.rs:44:9 | LL | let x = foo(x); | ^ | note: previous binding is here - --> tests/ui/shadow.rs:35:9 + --> tests/ui/shadow.rs:42:9 | LL | let x = Some(x); | ^ error: `x` is shadowed - --> tests/ui/shadow.rs:37:9 + --> tests/ui/shadow.rs:46:9 | LL | let x = || x; | ^ | note: previous binding is here - --> tests/ui/shadow.rs:36:9 + --> tests/ui/shadow.rs:44:9 | LL | let x = foo(x); | ^ error: `x` is shadowed - --> tests/ui/shadow.rs:38:9 + --> tests/ui/shadow.rs:48:9 | LL | let x = Some(1).map(|_| x)?; | ^ | note: previous binding is here - --> tests/ui/shadow.rs:37:9 + --> tests/ui/shadow.rs:46:9 | LL | let x = || x; | ^ error: `y` is shadowed - --> tests/ui/shadow.rs:40:9 + --> tests/ui/shadow.rs:51:9 | LL | let y = match y { | ^ | note: previous binding is here - --> tests/ui/shadow.rs:39:9 + --> tests/ui/shadow.rs:50:9 | LL | let y = 1; | ^ error: `x` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:55:9 + --> tests/ui/shadow.rs:67:9 | LL | let x = 2; | ^ | note: previous binding is here - --> tests/ui/shadow.rs:54:9 + --> tests/ui/shadow.rs:66:9 | LL | let x = 1; | ^ = note: `-D clippy::shadow-unrelated` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::shadow_unrelated)]` -error: `x` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:60:13 - | -LL | let x = 1; - | ^ - | -note: previous binding is here - --> tests/ui/shadow.rs:59:10 - | -LL | fn f(x: u32) { - | ^ - -error: `x` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:65:14 - | -LL | Some(x) => { - | ^ - | -note: previous binding is here - --> tests/ui/shadow.rs:62:9 - | -LL | let x = 1; - | ^ - -error: `x` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:66:17 - | -LL | let x = 1; - | ^ - | -note: previous binding is here - --> tests/ui/shadow.rs:65:14 - | -LL | Some(x) => { - | ^ - -error: `x` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:70:17 - | -LL | if let Some(x) = Some(1) {} - | ^ - | -note: previous binding is here - --> tests/ui/shadow.rs:62:9 - | -LL | let x = 1; - | ^ - -error: `x` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:71:20 - | -LL | while let Some(x) = Some(1) {} - | ^ - | -note: previous binding is here - --> tests/ui/shadow.rs:62:9 - | -LL | let x = 1; - | ^ - -error: `x` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:72:15 - | -LL | let _ = |[x]: [u32; 1]| { - | ^ - | -note: previous binding is here - --> tests/ui/shadow.rs:62:9 - | -LL | let x = 1; - | ^ - error: `x` shadows a previous, unrelated binding --> tests/ui/shadow.rs:73:13 | @@ -239,79 +167,151 @@ LL | let x = 1; | ^ | note: previous binding is here - --> tests/ui/shadow.rs:72:15 + --> tests/ui/shadow.rs:72:10 + | +LL | fn f(x: u32) { + | ^ + +error: `x` shadows a previous, unrelated binding + --> tests/ui/shadow.rs:79:14 + | +LL | Some(x) => { + | ^ + | +note: previous binding is here + --> tests/ui/shadow.rs:76:9 + | +LL | let x = 1; + | ^ + +error: `x` shadows a previous, unrelated binding + --> tests/ui/shadow.rs:81:17 + | +LL | let x = 1; + | ^ + | +note: previous binding is here + --> tests/ui/shadow.rs:79:14 + | +LL | Some(x) => { + | ^ + +error: `x` shadows a previous, unrelated binding + --> tests/ui/shadow.rs:86:17 + | +LL | if let Some(x) = Some(1) {} + | ^ + | +note: previous binding is here + --> tests/ui/shadow.rs:76:9 + | +LL | let x = 1; + | ^ + +error: `x` shadows a previous, unrelated binding + --> tests/ui/shadow.rs:88:20 + | +LL | while let Some(x) = Some(1) {} + | ^ + | +note: previous binding is here + --> tests/ui/shadow.rs:76:9 + | +LL | let x = 1; + | ^ + +error: `x` shadows a previous, unrelated binding + --> tests/ui/shadow.rs:90:15 + | +LL | let _ = |[x]: [u32; 1]| { + | ^ + | +note: previous binding is here + --> tests/ui/shadow.rs:76:9 + | +LL | let x = 1; + | ^ + +error: `x` shadows a previous, unrelated binding + --> tests/ui/shadow.rs:92:13 + | +LL | let x = 1; + | ^ + | +note: previous binding is here + --> tests/ui/shadow.rs:90:15 | LL | let _ = |[x]: [u32; 1]| { | ^ error: `y` is shadowed - --> tests/ui/shadow.rs:76:17 + --> tests/ui/shadow.rs:96:17 | LL | if let Some(y) = y {} | ^ | note: previous binding is here - --> tests/ui/shadow.rs:75:9 + --> tests/ui/shadow.rs:95:9 | LL | let y = Some(1); | ^ error: `_b` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:112:9 + --> tests/ui/shadow.rs:133:9 | LL | let _b = _a; | ^^ | note: previous binding is here - --> tests/ui/shadow.rs:111:28 + --> tests/ui/shadow.rs:132:28 | LL | pub async fn foo2(_a: i32, _b: i64) { | ^^ error: `x` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:118:21 + --> tests/ui/shadow.rs:140:21 | LL | if let Some(x) = Some(1) { x } else { 1 } | ^ | note: previous binding is here - --> tests/ui/shadow.rs:117:13 + --> tests/ui/shadow.rs:139:13 | LL | let x = 1; | ^ error: `x` is shadowed - --> tests/ui/shadow.rs:128:20 + --> tests/ui/shadow.rs:151:20 | LL | let z = x.map(|x| x + 1); | ^ | note: previous binding is here - --> tests/ui/shadow.rs:125:9 + --> tests/ui/shadow.rs:148:9 | LL | let x = Some(1); | ^ error: `i` is shadowed - --> tests/ui/shadow.rs:132:25 + --> tests/ui/shadow.rs:156:25 | LL | .map(|i| i.map(|i| i - 10)) | ^ | note: previous binding is here - --> tests/ui/shadow.rs:132:15 + --> tests/ui/shadow.rs:156:15 | LL | .map(|i| i.map(|i| i - 10)) | ^ error: `value` is shadowed by itself in `value` - --> tests/ui/shadow.rs:141:22 + --> tests/ui/shadow.rs:166:22 | LL | let Issue13795 { value, .. } = value; | ^^^^^ | note: previous binding is here - --> tests/ui/shadow.rs:140:15 + --> tests/ui/shadow.rs:165:15 | LL | fn issue13795(value: Issue13795) { | ^^^^^ diff --git a/tests/ui/short_circuit_statement.fixed b/tests/ui/short_circuit_statement.fixed index a2bf07ac6052..672f692db51e 100644 --- a/tests/ui/short_circuit_statement.fixed +++ b/tests/ui/short_circuit_statement.fixed @@ -3,15 +3,20 @@ fn main() { if f() { g(); } - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + if !f() { g(); } - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + if 1 != 2 { g(); } - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + if f() || g() { H * 2; } - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + if !(f() || g()) { H * 2; } - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + macro_rules! mac { ($f:ident or $g:ident) => { @@ -26,9 +31,11 @@ fn main() { } if mac!() { mac!(); } - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + if !mac!() { mac!(); } - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + // Do not lint if the expression comes from a macro mac!(); diff --git a/tests/ui/short_circuit_statement.rs b/tests/ui/short_circuit_statement.rs index bdba546ad8f6..ca8913c8e637 100644 --- a/tests/ui/short_circuit_statement.rs +++ b/tests/ui/short_circuit_statement.rs @@ -3,15 +3,20 @@ fn main() { f() && g(); - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + f() || g(); - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + 1 == 2 || g(); - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + (f() || g()) && (H * 2); - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + (f() || g()) || (H * 2); - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + macro_rules! mac { ($f:ident or $g:ident) => { @@ -26,9 +31,11 @@ fn main() { } mac!() && mac!(); - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + mac!() || mac!(); - //~^ ERROR: boolean short circuit operator in statement + //~^ short_circuit_statement + // Do not lint if the expression comes from a macro mac!(); diff --git a/tests/ui/short_circuit_statement.stderr b/tests/ui/short_circuit_statement.stderr index ecf6676405b4..f69f411b4885 100644 --- a/tests/ui/short_circuit_statement.stderr +++ b/tests/ui/short_circuit_statement.stderr @@ -8,37 +8,37 @@ LL | f() && g(); = help: to override `-D warnings` add `#[allow(clippy::short_circuit_statement)]` error: boolean short circuit operator in statement may be clearer using an explicit test - --> tests/ui/short_circuit_statement.rs:7:5 + --> tests/ui/short_circuit_statement.rs:8:5 | LL | f() || g(); | ^^^^^^^^^^^ help: replace it with: `if !f() { g(); }` error: boolean short circuit operator in statement may be clearer using an explicit test - --> tests/ui/short_circuit_statement.rs:9:5 + --> tests/ui/short_circuit_statement.rs:11:5 | LL | 1 == 2 || g(); | ^^^^^^^^^^^^^^ help: replace it with: `if 1 != 2 { g(); }` error: boolean short circuit operator in statement may be clearer using an explicit test - --> tests/ui/short_circuit_statement.rs:11:5 + --> tests/ui/short_circuit_statement.rs:14:5 | LL | (f() || g()) && (H * 2); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `if f() || g() { H * 2; }` error: boolean short circuit operator in statement may be clearer using an explicit test - --> tests/ui/short_circuit_statement.rs:13:5 + --> tests/ui/short_circuit_statement.rs:17:5 | LL | (f() || g()) || (H * 2); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `if !(f() || g()) { H * 2; }` error: boolean short circuit operator in statement may be clearer using an explicit test - --> tests/ui/short_circuit_statement.rs:28:5 + --> tests/ui/short_circuit_statement.rs:33:5 | LL | mac!() && mac!(); | ^^^^^^^^^^^^^^^^^ help: replace it with: `if mac!() { mac!(); }` error: boolean short circuit operator in statement may be clearer using an explicit test - --> tests/ui/short_circuit_statement.rs:30:5 + --> tests/ui/short_circuit_statement.rs:36:5 | LL | mac!() || mac!(); | ^^^^^^^^^^^^^^^^^ help: replace it with: `if !mac!() { mac!(); }` diff --git a/tests/ui/should_impl_trait/corner_cases.rs b/tests/ui/should_impl_trait/corner_cases.rs index 50999c6f2198..4ec0f02d6645 100644 --- a/tests/ui/should_impl_trait/corner_cases.rs +++ b/tests/ui/should_impl_trait/corner_cases.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::all, clippy::pedantic)] #![allow( clippy::missing_errors_doc, diff --git a/tests/ui/should_impl_trait/method_list_1.rs b/tests/ui/should_impl_trait/method_list_1.rs index 85eed3f06f64..664d8aab7568 100644 --- a/tests/ui/should_impl_trait/method_list_1.rs +++ b/tests/ui/should_impl_trait/method_list_1.rs @@ -23,77 +23,92 @@ impl T { // trait method list part 1, should lint all // ***************************************** pub fn add(self, other: T) -> T { - //~^ ERROR: method `add` can be confused for the standard trait method `std::ops::Add: + //~^ should_implement_trait + unimplemented!() } pub fn as_mut(&mut self) -> &mut T { - //~^ ERROR: method `as_mut` can be confused for the standard trait method `std::conver + //~^ should_implement_trait + unimplemented!() } pub fn as_ref(&self) -> &T { - //~^ ERROR: method `as_ref` can be confused for the standard trait method `std::conver + //~^ should_implement_trait + unimplemented!() } pub fn bitand(self, rhs: T) -> T { - //~^ ERROR: method `bitand` can be confused for the standard trait method `std::ops::B + //~^ should_implement_trait + unimplemented!() } pub fn bitor(self, rhs: Self) -> Self { - //~^ ERROR: method `bitor` can be confused for the standard trait method `std::ops::Bi + //~^ should_implement_trait + unimplemented!() } pub fn bitxor(self, rhs: Self) -> Self { - //~^ ERROR: method `bitxor` can be confused for the standard trait method `std::ops::B + //~^ should_implement_trait + unimplemented!() } pub fn borrow(&self) -> &str { - //~^ ERROR: method `borrow` can be confused for the standard trait method `std::borrow + //~^ should_implement_trait + unimplemented!() } pub fn borrow_mut(&mut self) -> &mut str { - //~^ ERROR: method `borrow_mut` can be confused for the standard trait method `std::bo + //~^ should_implement_trait + unimplemented!() } pub fn clone(&self) -> Self { - //~^ ERROR: method `clone` can be confused for the standard trait method `std::clone:: + //~^ should_implement_trait + unimplemented!() } pub fn cmp(&self, other: &Self) -> Self { - //~^ ERROR: method `cmp` can be confused for the standard trait method `std::cmp::Ord: + //~^ should_implement_trait + unimplemented!() } pub fn default() -> Self { - //~^ ERROR: method `default` can be confused for the standard trait method `std::defau + //~^ should_implement_trait + unimplemented!() } pub fn deref(&self) -> &Self { - //~^ ERROR: method `deref` can be confused for the standard trait method `std::ops::De + //~^ should_implement_trait + unimplemented!() } pub fn deref_mut(&mut self) -> &mut Self { - //~^ ERROR: method `deref_mut` can be confused for the standard trait method `std::ops + //~^ should_implement_trait + unimplemented!() } pub fn div(self, rhs: Self) -> Self { - //~^ ERROR: method `div` can be confused for the standard trait method `std::ops::Div: + //~^ should_implement_trait + unimplemented!() } pub fn drop(&mut self) { - //~^ ERROR: method `drop` can be confused for the standard trait method `std::ops::Dro + //~^ should_implement_trait + unimplemented!() } // ********** diff --git a/tests/ui/should_impl_trait/method_list_1.stderr b/tests/ui/should_impl_trait/method_list_1.stderr index dfa55ace40f0..8738b61192a3 100644 --- a/tests/ui/should_impl_trait/method_list_1.stderr +++ b/tests/ui/should_impl_trait/method_list_1.stderr @@ -3,6 +3,7 @@ error: method `add` can be confused for the standard trait method `std::ops::Add | LL | / pub fn add(self, other: T) -> T { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -12,10 +13,11 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::should_implement_trait)]` error: method `as_mut` can be confused for the standard trait method `std::convert::AsMut::as_mut` - --> tests/ui/should_impl_trait/method_list_1.rs:30:5 + --> tests/ui/should_impl_trait/method_list_1.rs:31:5 | LL | / pub fn as_mut(&mut self) -> &mut T { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -23,10 +25,11 @@ LL | | } = help: consider implementing the trait `std::convert::AsMut` or choosing a less ambiguous method name error: method `as_ref` can be confused for the standard trait method `std::convert::AsRef::as_ref` - --> tests/ui/should_impl_trait/method_list_1.rs:35:5 + --> tests/ui/should_impl_trait/method_list_1.rs:37:5 | LL | / pub fn as_ref(&self) -> &T { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -34,10 +37,11 @@ LL | | } = help: consider implementing the trait `std::convert::AsRef` or choosing a less ambiguous method name error: method `bitand` can be confused for the standard trait method `std::ops::BitAnd::bitand` - --> tests/ui/should_impl_trait/method_list_1.rs:40:5 + --> tests/ui/should_impl_trait/method_list_1.rs:43:5 | LL | / pub fn bitand(self, rhs: T) -> T { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -45,10 +49,11 @@ LL | | } = help: consider implementing the trait `std::ops::BitAnd` or choosing a less ambiguous method name error: method `bitor` can be confused for the standard trait method `std::ops::BitOr::bitor` - --> tests/ui/should_impl_trait/method_list_1.rs:45:5 + --> tests/ui/should_impl_trait/method_list_1.rs:49:5 | LL | / pub fn bitor(self, rhs: Self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -56,10 +61,11 @@ LL | | } = help: consider implementing the trait `std::ops::BitOr` or choosing a less ambiguous method name error: method `bitxor` can be confused for the standard trait method `std::ops::BitXor::bitxor` - --> tests/ui/should_impl_trait/method_list_1.rs:50:5 + --> tests/ui/should_impl_trait/method_list_1.rs:55:5 | LL | / pub fn bitxor(self, rhs: Self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -67,10 +73,11 @@ LL | | } = help: consider implementing the trait `std::ops::BitXor` or choosing a less ambiguous method name error: method `borrow` can be confused for the standard trait method `std::borrow::Borrow::borrow` - --> tests/ui/should_impl_trait/method_list_1.rs:55:5 + --> tests/ui/should_impl_trait/method_list_1.rs:61:5 | LL | / pub fn borrow(&self) -> &str { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -78,10 +85,11 @@ LL | | } = help: consider implementing the trait `std::borrow::Borrow` or choosing a less ambiguous method name error: method `borrow_mut` can be confused for the standard trait method `std::borrow::BorrowMut::borrow_mut` - --> tests/ui/should_impl_trait/method_list_1.rs:60:5 + --> tests/ui/should_impl_trait/method_list_1.rs:67:5 | LL | / pub fn borrow_mut(&mut self) -> &mut str { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -89,10 +97,11 @@ LL | | } = help: consider implementing the trait `std::borrow::BorrowMut` or choosing a less ambiguous method name error: method `clone` can be confused for the standard trait method `std::clone::Clone::clone` - --> tests/ui/should_impl_trait/method_list_1.rs:65:5 + --> tests/ui/should_impl_trait/method_list_1.rs:73:5 | LL | / pub fn clone(&self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -100,10 +109,11 @@ LL | | } = help: consider implementing the trait `std::clone::Clone` or choosing a less ambiguous method name error: method `cmp` can be confused for the standard trait method `std::cmp::Ord::cmp` - --> tests/ui/should_impl_trait/method_list_1.rs:70:5 + --> tests/ui/should_impl_trait/method_list_1.rs:79:5 | LL | / pub fn cmp(&self, other: &Self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -111,10 +121,11 @@ LL | | } = help: consider implementing the trait `std::cmp::Ord` or choosing a less ambiguous method name error: method `default` can be confused for the standard trait method `std::default::Default::default` - --> tests/ui/should_impl_trait/method_list_1.rs:75:5 + --> tests/ui/should_impl_trait/method_list_1.rs:85:5 | LL | / pub fn default() -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -122,10 +133,11 @@ LL | | } = help: consider implementing the trait `std::default::Default` or choosing a less ambiguous method name error: method `deref` can be confused for the standard trait method `std::ops::Deref::deref` - --> tests/ui/should_impl_trait/method_list_1.rs:80:5 + --> tests/ui/should_impl_trait/method_list_1.rs:91:5 | LL | / pub fn deref(&self) -> &Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -133,10 +145,11 @@ LL | | } = help: consider implementing the trait `std::ops::Deref` or choosing a less ambiguous method name error: method `deref_mut` can be confused for the standard trait method `std::ops::DerefMut::deref_mut` - --> tests/ui/should_impl_trait/method_list_1.rs:85:5 + --> tests/ui/should_impl_trait/method_list_1.rs:97:5 | LL | / pub fn deref_mut(&mut self) -> &mut Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -144,10 +157,11 @@ LL | | } = help: consider implementing the trait `std::ops::DerefMut` or choosing a less ambiguous method name error: method `div` can be confused for the standard trait method `std::ops::Div::div` - --> tests/ui/should_impl_trait/method_list_1.rs:90:5 + --> tests/ui/should_impl_trait/method_list_1.rs:103:5 | LL | / pub fn div(self, rhs: Self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -155,10 +169,11 @@ LL | | } = help: consider implementing the trait `std::ops::Div` or choosing a less ambiguous method name error: method `drop` can be confused for the standard trait method `std::ops::Drop::drop` - --> tests/ui/should_impl_trait/method_list_1.rs:95:5 + --> tests/ui/should_impl_trait/method_list_1.rs:109:5 | LL | / pub fn drop(&mut self) { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ diff --git a/tests/ui/should_impl_trait/method_list_2.rs b/tests/ui/should_impl_trait/method_list_2.rs index 33211b32d74b..29b96c33ce9c 100644 --- a/tests/ui/should_impl_trait/method_list_2.rs +++ b/tests/ui/should_impl_trait/method_list_2.rs @@ -24,77 +24,92 @@ impl T { // ***************************************** pub fn eq(&self, other: &Self) -> bool { - //~^ ERROR: method `eq` can be confused for the standard trait method `std::cmp::Parti + //~^ should_implement_trait + unimplemented!() } pub fn from_iter(iter: T) -> Self { - //~^ ERROR: method `from_iter` can be confused for the standard trait method `std::ite + //~^ should_implement_trait + unimplemented!() } pub fn from_str(s: &str) -> Result { - //~^ ERROR: method `from_str` can be confused for the standard trait method `std::str: + //~^ should_implement_trait + unimplemented!() } pub fn hash(&self, state: &mut T) { - //~^ ERROR: method `hash` can be confused for the standard trait method `std::hash::Ha + //~^ should_implement_trait + unimplemented!() } pub fn index(&self, index: usize) -> &Self { - //~^ ERROR: method `index` can be confused for the standard trait method `std::ops::In + //~^ should_implement_trait + unimplemented!() } pub fn index_mut(&mut self, index: usize) -> &mut Self { - //~^ ERROR: method `index_mut` can be confused for the standard trait method `std::ops + //~^ should_implement_trait + unimplemented!() } pub fn into_iter(self) -> Self { - //~^ ERROR: method `into_iter` can be confused for the standard trait method `std::ite + //~^ should_implement_trait + unimplemented!() } pub fn mul(self, rhs: Self) -> Self { - //~^ ERROR: method `mul` can be confused for the standard trait method `std::ops::Mul: + //~^ should_implement_trait + unimplemented!() } pub fn neg(self) -> Self { - //~^ ERROR: method `neg` can be confused for the standard trait method `std::ops::Neg: + //~^ should_implement_trait + unimplemented!() } pub fn next(&mut self) -> Option { - //~^ ERROR: method `next` can be confused for the standard trait method `std::iter::It + //~^ should_implement_trait + unimplemented!() } pub fn not(self) -> Self { - //~^ ERROR: method `not` can be confused for the standard trait method `std::ops::Not: + //~^ should_implement_trait + unimplemented!() } pub fn rem(self, rhs: Self) -> Self { - //~^ ERROR: method `rem` can be confused for the standard trait method `std::ops::Rem: + //~^ should_implement_trait + unimplemented!() } pub fn shl(self, rhs: Self) -> Self { - //~^ ERROR: method `shl` can be confused for the standard trait method `std::ops::Shl: + //~^ should_implement_trait + unimplemented!() } pub fn shr(self, rhs: Self) -> Self { - //~^ ERROR: method `shr` can be confused for the standard trait method `std::ops::Shr: + //~^ should_implement_trait + unimplemented!() } pub fn sub(self, rhs: Self) -> Self { - //~^ ERROR: method `sub` can be confused for the standard trait method `std::ops::Sub: + //~^ should_implement_trait + unimplemented!() } // ********** diff --git a/tests/ui/should_impl_trait/method_list_2.stderr b/tests/ui/should_impl_trait/method_list_2.stderr index b1e5bbbfa4c5..85de74337020 100644 --- a/tests/ui/should_impl_trait/method_list_2.stderr +++ b/tests/ui/should_impl_trait/method_list_2.stderr @@ -3,6 +3,7 @@ error: method `eq` can be confused for the standard trait method `std::cmp::Part | LL | / pub fn eq(&self, other: &Self) -> bool { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -12,10 +13,11 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::should_implement_trait)]` error: method `from_iter` can be confused for the standard trait method `std::iter::FromIterator::from_iter` - --> tests/ui/should_impl_trait/method_list_2.rs:31:5 + --> tests/ui/should_impl_trait/method_list_2.rs:32:5 | LL | / pub fn from_iter(iter: T) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -23,10 +25,11 @@ LL | | } = help: consider implementing the trait `std::iter::FromIterator` or choosing a less ambiguous method name error: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str` - --> tests/ui/should_impl_trait/method_list_2.rs:36:5 + --> tests/ui/should_impl_trait/method_list_2.rs:38:5 | LL | / pub fn from_str(s: &str) -> Result { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -34,10 +37,11 @@ LL | | } = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name error: method `hash` can be confused for the standard trait method `std::hash::Hash::hash` - --> tests/ui/should_impl_trait/method_list_2.rs:41:5 + --> tests/ui/should_impl_trait/method_list_2.rs:44:5 | LL | / pub fn hash(&self, state: &mut T) { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -45,10 +49,11 @@ LL | | } = help: consider implementing the trait `std::hash::Hash` or choosing a less ambiguous method name error: method `index` can be confused for the standard trait method `std::ops::Index::index` - --> tests/ui/should_impl_trait/method_list_2.rs:46:5 + --> tests/ui/should_impl_trait/method_list_2.rs:50:5 | LL | / pub fn index(&self, index: usize) -> &Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -56,10 +61,11 @@ LL | | } = help: consider implementing the trait `std::ops::Index` or choosing a less ambiguous method name error: method `index_mut` can be confused for the standard trait method `std::ops::IndexMut::index_mut` - --> tests/ui/should_impl_trait/method_list_2.rs:51:5 + --> tests/ui/should_impl_trait/method_list_2.rs:56:5 | LL | / pub fn index_mut(&mut self, index: usize) -> &mut Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -67,10 +73,11 @@ LL | | } = help: consider implementing the trait `std::ops::IndexMut` or choosing a less ambiguous method name error: method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter` - --> tests/ui/should_impl_trait/method_list_2.rs:56:5 + --> tests/ui/should_impl_trait/method_list_2.rs:62:5 | LL | / pub fn into_iter(self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -78,10 +85,11 @@ LL | | } = help: consider implementing the trait `std::iter::IntoIterator` or choosing a less ambiguous method name error: method `mul` can be confused for the standard trait method `std::ops::Mul::mul` - --> tests/ui/should_impl_trait/method_list_2.rs:61:5 + --> tests/ui/should_impl_trait/method_list_2.rs:68:5 | LL | / pub fn mul(self, rhs: Self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -89,10 +97,11 @@ LL | | } = help: consider implementing the trait `std::ops::Mul` or choosing a less ambiguous method name error: method `neg` can be confused for the standard trait method `std::ops::Neg::neg` - --> tests/ui/should_impl_trait/method_list_2.rs:66:5 + --> tests/ui/should_impl_trait/method_list_2.rs:74:5 | LL | / pub fn neg(self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -100,10 +109,11 @@ LL | | } = help: consider implementing the trait `std::ops::Neg` or choosing a less ambiguous method name error: method `next` can be confused for the standard trait method `std::iter::Iterator::next` - --> tests/ui/should_impl_trait/method_list_2.rs:71:5 + --> tests/ui/should_impl_trait/method_list_2.rs:80:5 | LL | / pub fn next(&mut self) -> Option { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -111,10 +121,11 @@ LL | | } = help: consider implementing the trait `std::iter::Iterator` or choosing a less ambiguous method name error: method `not` can be confused for the standard trait method `std::ops::Not::not` - --> tests/ui/should_impl_trait/method_list_2.rs:76:5 + --> tests/ui/should_impl_trait/method_list_2.rs:86:5 | LL | / pub fn not(self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -122,10 +133,11 @@ LL | | } = help: consider implementing the trait `std::ops::Not` or choosing a less ambiguous method name error: method `rem` can be confused for the standard trait method `std::ops::Rem::rem` - --> tests/ui/should_impl_trait/method_list_2.rs:81:5 + --> tests/ui/should_impl_trait/method_list_2.rs:92:5 | LL | / pub fn rem(self, rhs: Self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -133,10 +145,11 @@ LL | | } = help: consider implementing the trait `std::ops::Rem` or choosing a less ambiguous method name error: method `shl` can be confused for the standard trait method `std::ops::Shl::shl` - --> tests/ui/should_impl_trait/method_list_2.rs:86:5 + --> tests/ui/should_impl_trait/method_list_2.rs:98:5 | LL | / pub fn shl(self, rhs: Self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -144,10 +157,11 @@ LL | | } = help: consider implementing the trait `std::ops::Shl` or choosing a less ambiguous method name error: method `shr` can be confused for the standard trait method `std::ops::Shr::shr` - --> tests/ui/should_impl_trait/method_list_2.rs:91:5 + --> tests/ui/should_impl_trait/method_list_2.rs:104:5 | LL | / pub fn shr(self, rhs: Self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ @@ -155,10 +169,11 @@ LL | | } = help: consider implementing the trait `std::ops::Shr` or choosing a less ambiguous method name error: method `sub` can be confused for the standard trait method `std::ops::Sub::sub` - --> tests/ui/should_impl_trait/method_list_2.rs:96:5 + --> tests/ui/should_impl_trait/method_list_2.rs:110:5 | LL | / pub fn sub(self, rhs: Self) -> Self { LL | | +LL | | LL | | unimplemented!() LL | | } | |_____^ diff --git a/tests/ui/should_panic_without_expect.rs b/tests/ui/should_panic_without_expect.rs index b554fdaf2249..a209f794b105 100644 --- a/tests/ui/should_panic_without_expect.rs +++ b/tests/ui/should_panic_without_expect.rs @@ -3,6 +3,7 @@ #[test] #[should_panic] +//~^ should_panic_without_expect fn no_message() {} #[test] diff --git a/tests/ui/significant_drop_in_scrutinee.rs b/tests/ui/significant_drop_in_scrutinee.rs index 39d550398d70..db4f8867fa41 100644 --- a/tests/ui/significant_drop_in_scrutinee.rs +++ b/tests/ui/significant_drop_in_scrutinee.rs @@ -58,8 +58,7 @@ fn should_trigger_lint_with_mutex_guard_in_match_scrutinee() { // is preserved until the end of the match, but there is no clear indication that this is the // case. match mutex.lock().unwrap().foo() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee true => { mutex.lock().unwrap().bar(); }, @@ -146,8 +145,7 @@ fn should_trigger_lint_with_wrapped_mutex() { // lifetime is not obvious. Additionally, it is not obvious from looking at the scrutinee that // the temporary contains such a type, making it potentially even more surprising. match s.lock_m().get_the_value() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee 1 => { println!("Got 1. Is it still 1?"); println!("{}", s.lock_m().get_the_value()); @@ -169,8 +167,7 @@ fn should_trigger_lint_with_double_wrapped_mutex() { // looking at the scrutinee that the temporary contains such a type, making it potentially even // more surprising. match s.lock_m_m().get_the_value() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee 1 => { println!("Got 1. Is it still 1?"); println!("{}", s.lock_m().get_the_value()); @@ -219,8 +216,7 @@ fn should_trigger_lint_for_vec() { // which have significant drops. The types with significant drops are also non-obvious when // reading the expression in the scrutinee. match counter.temp_increment().len() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee 2 => { let current_count = counter.i.load(Ordering::Relaxed); println!("Current count {}", current_count); @@ -244,8 +240,7 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { { match (mutex1.lock().unwrap().s.len(), true) { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee (3, _) => { println!("started"); mutex1.lock().unwrap().s.len(); @@ -255,8 +250,7 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { }; match (true, mutex1.lock().unwrap().s.len(), true) { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee (_, 3, _) => { println!("started"); mutex1.lock().unwrap().s.len(); @@ -267,10 +261,8 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() }); match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until - //~| NOTE: this might lead to deadlocks or other unexpected behavior - //~| ERROR: temporary with significant `Drop` in `match` scrutinee will live until - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee + //~| significant_drop_in_scrutinee (3, _, 3) => { println!("started"); mutex1.lock().unwrap().s.len(); @@ -322,8 +314,7 @@ fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() { let mutex = Mutex::new(StateWithField { s: "state".to_owned() }); match mutex.lock().unwrap().s.len() > 1 { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee true => { mutex.lock().unwrap().s.len(); }, @@ -331,8 +322,7 @@ fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() { }; match 1 < mutex.lock().unwrap().s.len() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee true => { mutex.lock().unwrap().s.len(); }, @@ -351,8 +341,8 @@ fn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op( }); match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee + //~| significant_drop_in_scrutinee true => { println!( "{} < {}", @@ -364,8 +354,8 @@ fn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op( }; match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee + //~| significant_drop_in_scrutinee true => { println!( "{} >= {}", @@ -401,8 +391,7 @@ fn should_trigger_lint_for_return_from_closure_in_scrutinee() { // Should trigger lint because the temporary with a significant drop is returned from the // closure but not used directly in any match arms, so it has a potentially surprising lifetime. match get_mutex_guard().s.len() > 1 { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee true => { mutex1.lock().unwrap().s.len(); }, @@ -420,8 +409,7 @@ fn should_trigger_lint_for_return_from_match_in_scrutinee() { // significant drop is but not used directly in any match arms, so it has a potentially // surprising lifetime. match match i { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee 100 => mutex1.lock().unwrap(), _ => mutex2.lock().unwrap(), } @@ -448,8 +436,7 @@ fn should_trigger_lint_for_return_from_if_in_scrutinee() { // with a significant drop is but not used directly in any match arms, so it has a potentially // surprising lifetime. match if i > 1 { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee mutex1.lock().unwrap() } else { mutex2.lock().unwrap() @@ -504,8 +491,7 @@ fn should_trigger_lint_for_boxed_mutex_guard() { // Should trigger lint because a temporary Box holding a type with a significant drop in a match // scrutinee may have a potentially surprising lifetime. match s.lock().deref().deref() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee 0 | 1 => println!("Value was less than 2"), _ => println!("Value is {}", s.lock().deref()), }; @@ -554,32 +540,28 @@ fn should_trigger_lint_in_assign_expr() { let mut i = 100; match mutex.lock().unwrap().i = i { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee _ => { println!("{}", mutex.lock().unwrap().i); }, }; match i = mutex.lock().unwrap().i { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee _ => { println!("{}", mutex.lock().unwrap().i); }, }; match mutex.lock().unwrap().i += 1 { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee _ => { println!("{}", mutex.lock().unwrap().i); }, }; match i += mutex.lock().unwrap().i { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee _ => { println!("{}", mutex.lock().unwrap().i); }, @@ -643,8 +625,7 @@ impl ResultReturner { fn should_trigger_lint_for_non_ref_move_and_clone_suggestion() { let rwlock = RwLock::::new(ResultReturner { s: "1".to_string() }); match rwlock.read().unwrap().to_number() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee Ok(n) => println!("Converted to number: {}", n), Err(e) => println!("Could not convert {} to number", e), }; @@ -671,8 +652,7 @@ fn should_trigger_lint_without_significant_drop_in_arm() { // is preserved until the end of the match, but there is no clear indication that this is the // case. match mutex.lock().unwrap().foo() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee true => do_bar(&mutex), false => {}, }; @@ -734,8 +714,7 @@ fn should_not_trigger_for_significant_drop_ref() { } match guard.take().len() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee 0 => println!("empty"), _ => println!("not empty"), }; @@ -760,8 +739,7 @@ fn should_trigger_lint_if_and_only_if_lifetime_is_irrelevant() { // Should trigger lint even if `copy_old_lifetime()` has a lifetime, as the lifetime of // `&vec` is unrelated to the temporary with significant drop (i.e., the `MutexGuard`). for val in mutex.lock().unwrap().copy_old_lifetime() { - //~^ ERROR: temporary with significant `Drop` in `for` loop condition will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee println!("{}", val); } @@ -800,8 +778,7 @@ fn should_not_trigger_lint_with_explicit_drop() { // Should trigger lint if there is no explicit drop. for val in [mutex.lock().unwrap()[0], 2] { - //~^ ERROR: temporary with significant `Drop` in `for` loop condition will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee println!("{:?}", val); } } @@ -810,8 +787,7 @@ fn should_trigger_lint_in_if_let() { let mutex = Mutex::new(vec![1]); if let Some(val) = mutex.lock().unwrap().first().copied() { - //~^ ERROR: temporary with significant `Drop` in `if let` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee println!("{}", val); } @@ -826,8 +802,7 @@ fn should_trigger_lint_in_while_let() { let mutex = Mutex::new(vec![1]); while let Some(val) = mutex.lock().unwrap().pop() { - //~^ ERROR: temporary with significant `Drop` in `while let` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee println!("{}", val); } } @@ -838,6 +813,7 @@ async fn foo_async(mutex: &Mutex) -> Option> { async fn should_trigger_lint_for_async(mutex: Mutex) -> i32 { match *foo_async(&mutex).await.unwrap() { + //~^ significant_drop_in_scrutinee n if n < 10 => n, _ => 10, } @@ -857,8 +833,7 @@ fn should_trigger_lint_in_match_expr() { // is preserved until the end of the match, but there is no clear indication that this is the // case. let _ = match mutex.lock().unwrap().foo() { - //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the - //~| NOTE: this might lead to deadlocks or other unexpected behavior + //~^ significant_drop_in_scrutinee true => 0, false => 1, }; diff --git a/tests/ui/significant_drop_in_scrutinee.stderr b/tests/ui/significant_drop_in_scrutinee.stderr index f99d862aa6b2..b32b249fd429 100644 --- a/tests/ui/significant_drop_in_scrutinee.stderr +++ b/tests/ui/significant_drop_in_scrutinee.stderr @@ -20,7 +20,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:148:11 + --> tests/ui/significant_drop_in_scrutinee.rs:147:11 | LL | match s.lock_m().get_the_value() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:171:11 + --> tests/ui/significant_drop_in_scrutinee.rs:169:11 | LL | match s.lock_m_m().get_the_value() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:221:11 + --> tests/ui/significant_drop_in_scrutinee.rs:218:11 | LL | match counter.temp_increment().len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:246:16 + --> tests/ui/significant_drop_in_scrutinee.rs:242:16 | LL | match (mutex1.lock().unwrap().s.len(), true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL ~ match (value, true) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:257:22 + --> tests/ui/significant_drop_in_scrutinee.rs:252:22 | LL | match (true, mutex1.lock().unwrap().s.len(), true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL ~ match (true, value, true) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:269:16 + --> tests/ui/significant_drop_in_scrutinee.rs:263:16 | LL | match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL ~ match (value, true, mutex2.lock().unwrap().s.len()) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:269:54 + --> tests/ui/significant_drop_in_scrutinee.rs:263:54 | LL | match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,7 +160,7 @@ LL ~ match (mutex1.lock().unwrap().s.len(), true, value) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:324:11 + --> tests/ui/significant_drop_in_scrutinee.rs:316:11 | LL | match mutex.lock().unwrap().s.len() > 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -179,7 +179,7 @@ LL ~ match value > 1 { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:333:15 + --> tests/ui/significant_drop_in_scrutinee.rs:324:15 | LL | match 1 < mutex.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +198,7 @@ LL ~ match 1 < value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:353:11 + --> tests/ui/significant_drop_in_scrutinee.rs:343:11 | LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ LL ~ match value < mutex2.lock().unwrap().s.len() { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:353:44 + --> tests/ui/significant_drop_in_scrutinee.rs:343:44 | LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -240,7 +240,7 @@ LL ~ match mutex1.lock().unwrap().s.len() < value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:366:11 + --> tests/ui/significant_drop_in_scrutinee.rs:356:11 | LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -261,7 +261,7 @@ LL ~ match value >= mutex2.lock().unwrap().s.len() { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:366:45 + --> tests/ui/significant_drop_in_scrutinee.rs:356:45 | LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -282,7 +282,7 @@ LL ~ match mutex1.lock().unwrap().s.len() >= value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:403:11 + --> tests/ui/significant_drop_in_scrutinee.rs:393:11 | LL | match get_mutex_guard().s.len() > 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -301,14 +301,14 @@ LL ~ match value > 1 { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:422:11 + --> tests/ui/significant_drop_in_scrutinee.rs:411:11 | LL | match match i { | ___________^ LL | | -LL | | LL | | 100 => mutex1.lock().unwrap(), -... | +LL | | _ => mutex2.lock().unwrap(), +LL | | } LL | | .s LL | | .len() | |__________^ @@ -324,7 +324,6 @@ help: try moving the temporary above the match | LL ~ let value = match i { LL + -LL + LL + 100 => mutex1.lock().unwrap(), LL + _ => mutex2.lock().unwrap(), LL + } @@ -334,13 +333,13 @@ LL ~ match value | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:450:11 + --> tests/ui/significant_drop_in_scrutinee.rs:438:11 | LL | match if i > 1 { | ___________^ LL | | -LL | | LL | | mutex1.lock().unwrap() +LL | | } else { ... | LL | | .s LL | | .len() @@ -357,7 +356,6 @@ help: try moving the temporary above the match | LL ~ let value = if i > 1 { LL + -LL + LL + mutex1.lock().unwrap() LL + } else { LL + mutex2.lock().unwrap() @@ -368,7 +366,7 @@ LL ~ match value | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:506:11 + --> tests/ui/significant_drop_in_scrutinee.rs:493:11 | LL | match s.lock().deref().deref() { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -386,7 +384,7 @@ LL ~ match (&value) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:556:11 + --> tests/ui/significant_drop_in_scrutinee.rs:542:11 | LL | match mutex.lock().unwrap().i = i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -405,7 +403,7 @@ LL ~ match () { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:564:15 + --> tests/ui/significant_drop_in_scrutinee.rs:549:15 | LL | match i = mutex.lock().unwrap().i { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -424,7 +422,7 @@ LL ~ match i = value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:572:11 + --> tests/ui/significant_drop_in_scrutinee.rs:556:11 | LL | match mutex.lock().unwrap().i += 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -443,7 +441,7 @@ LL ~ match () { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:580:16 + --> tests/ui/significant_drop_in_scrutinee.rs:563:16 | LL | match i += mutex.lock().unwrap().i { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -462,7 +460,7 @@ LL ~ match i += value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:645:11 + --> tests/ui/significant_drop_in_scrutinee.rs:627:11 | LL | match rwlock.read().unwrap().to_number() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -478,7 +476,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:673:11 + --> tests/ui/significant_drop_in_scrutinee.rs:654:11 | LL | match mutex.lock().unwrap().foo() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -494,7 +492,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:736:11 + --> tests/ui/significant_drop_in_scrutinee.rs:716:11 | LL | match guard.take().len() { | ^^^^^^^^^^^^^^^^^^ @@ -510,7 +508,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression - --> tests/ui/significant_drop_in_scrutinee.rs:762:16 + --> tests/ui/significant_drop_in_scrutinee.rs:741:16 | LL | for val in mutex.lock().unwrap().copy_old_lifetime() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -526,7 +524,7 @@ LL ~ for val in value { | error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression - --> tests/ui/significant_drop_in_scrutinee.rs:802:17 + --> tests/ui/significant_drop_in_scrutinee.rs:780:17 | LL | for val in [mutex.lock().unwrap()[0], 2] { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -542,7 +540,7 @@ LL ~ for val in [value, 2] { | error: temporary with significant `Drop` in `if let` scrutinee will live until the end of the `if let` expression - --> tests/ui/significant_drop_in_scrutinee.rs:812:24 + --> tests/ui/significant_drop_in_scrutinee.rs:789:24 | LL | if let Some(val) = mutex.lock().unwrap().first().copied() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -558,7 +556,7 @@ LL ~ if let Some(val) = value { | error: temporary with significant `Drop` in `while let` scrutinee will live until the end of the `while let` expression - --> tests/ui/significant_drop_in_scrutinee.rs:828:27 + --> tests/ui/significant_drop_in_scrutinee.rs:804:27 | LL | while let Some(val) = mutex.lock().unwrap().pop() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -569,7 +567,7 @@ LL | } = note: this might lead to deadlocks or other unexpected behavior error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:840:11 + --> tests/ui/significant_drop_in_scrutinee.rs:815:11 | LL | match *foo_async(&mutex).await.unwrap() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -585,7 +583,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> tests/ui/significant_drop_in_scrutinee.rs:859:19 + --> tests/ui/significant_drop_in_scrutinee.rs:835:19 | LL | let _ = match mutex.lock().unwrap().foo() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/significant_drop_tightening.fixed b/tests/ui/significant_drop_tightening.fixed index ed05f6e0c8d3..3d416056226c 100644 --- a/tests/ui/significant_drop_tightening.fixed +++ b/tests/ui/significant_drop_tightening.fixed @@ -8,6 +8,7 @@ pub fn complex_return_triggers_the_lint() -> i32 { } let mutex = Mutex::new(1); let lock = mutex.lock().unwrap(); + //~^ significant_drop_tightening let _ = *lock; let _ = *lock; drop(lock); @@ -103,6 +104,7 @@ pub fn unnecessary_contention_with_multiple_owned_results() { { let mutex = Mutex::new(1i32); let lock = mutex.lock().unwrap(); + //~^ significant_drop_tightening let rslt0 = lock.abs(); let rslt1 = lock.is_positive(); drop(lock); @@ -126,6 +128,7 @@ pub fn unnecessary_contention_with_single_owned_results() { let mutex = Mutex::new(1i32); let rslt0 = mutex.lock().unwrap().abs(); + //~^ significant_drop_tightening do_heavy_computation_that_takes_time(rslt0); } @@ -133,6 +136,7 @@ pub fn unnecessary_contention_with_single_owned_results() { let mutex = Mutex::new(vec![1i32]); mutex.lock().unwrap().clear(); + //~^ significant_drop_tightening do_heavy_computation_that_takes_time(()); } diff --git a/tests/ui/significant_drop_tightening.rs b/tests/ui/significant_drop_tightening.rs index e5f17278f0f6..d9c4ad543593 100644 --- a/tests/ui/significant_drop_tightening.rs +++ b/tests/ui/significant_drop_tightening.rs @@ -8,6 +8,7 @@ pub fn complex_return_triggers_the_lint() -> i32 { } let mutex = Mutex::new(1); let lock = mutex.lock().unwrap(); + //~^ significant_drop_tightening let _ = *lock; let _ = *lock; foo() @@ -102,6 +103,7 @@ pub fn unnecessary_contention_with_multiple_owned_results() { { let mutex = Mutex::new(1i32); let lock = mutex.lock().unwrap(); + //~^ significant_drop_tightening let rslt0 = lock.abs(); let rslt1 = lock.is_positive(); do_heavy_computation_that_takes_time((rslt0, rslt1)); @@ -123,12 +125,14 @@ pub fn unnecessary_contention_with_single_owned_results() { { let mutex = Mutex::new(1i32); let lock = mutex.lock().unwrap(); + //~^ significant_drop_tightening let rslt0 = lock.abs(); do_heavy_computation_that_takes_time(rslt0); } { let mutex = Mutex::new(vec![1i32]); let mut lock = mutex.lock().unwrap(); + //~^ significant_drop_tightening lock.clear(); do_heavy_computation_that_takes_time(()); } diff --git a/tests/ui/significant_drop_tightening.stderr b/tests/ui/significant_drop_tightening.stderr index aef774a3d360..25cd9da73a10 100644 --- a/tests/ui/significant_drop_tightening.stderr +++ b/tests/ui/significant_drop_tightening.stderr @@ -23,14 +23,13 @@ LL + drop(lock); | error: temporary with significant `Drop` can be early dropped - --> tests/ui/significant_drop_tightening.rs:104:13 + --> tests/ui/significant_drop_tightening.rs:105:13 | LL | / { LL | | let mutex = Mutex::new(1i32); LL | | let lock = mutex.lock().unwrap(); | | ^^^^ -LL | | let rslt0 = lock.abs(); -LL | | let rslt1 = lock.is_positive(); +... | LL | | do_heavy_computation_that_takes_time((rslt0, rslt1)); LL | | } | |_____- temporary `lock` is currently being dropped at the end of its contained scope @@ -43,13 +42,13 @@ LL + drop(lock); | error: temporary with significant `Drop` can be early dropped - --> tests/ui/significant_drop_tightening.rs:125:13 + --> tests/ui/significant_drop_tightening.rs:127:13 | LL | / { LL | | let mutex = Mutex::new(1i32); LL | | let lock = mutex.lock().unwrap(); | | ^^^^ -LL | | let rslt0 = lock.abs(); +... | LL | | do_heavy_computation_that_takes_time(rslt0); LL | | } | |_____- temporary `lock` is currently being dropped at the end of its contained scope @@ -59,17 +58,18 @@ help: merge the temporary construction with its single usage | LL ~ LL + let rslt0 = mutex.lock().unwrap().abs(); +LL | LL ~ | error: temporary with significant `Drop` can be early dropped - --> tests/ui/significant_drop_tightening.rs:131:17 + --> tests/ui/significant_drop_tightening.rs:134:17 | LL | / { LL | | let mutex = Mutex::new(vec![1i32]); LL | | let mut lock = mutex.lock().unwrap(); | | ^^^^ -LL | | lock.clear(); +... | LL | | do_heavy_computation_that_takes_time(()); LL | | } | |_____- temporary `lock` is currently being dropped at the end of its contained scope @@ -79,6 +79,7 @@ help: merge the temporary construction with its single usage | LL ~ LL + mutex.lock().unwrap().clear(); +LL | LL ~ | diff --git a/tests/ui/similar_names.rs b/tests/ui/similar_names.rs index f09693344915..a6b20b94a4a7 100644 --- a/tests/ui/similar_names.rs +++ b/tests/ui/similar_names.rs @@ -45,12 +45,14 @@ fn main() { let blubx: i32; let bluby: i32; - //~^ ERROR: binding's name is too similar to existing binding + //~^ similar_names + let cake: i32; let cakes: i32; let coke: i32; - //~^ ERROR: binding's name is too similar to existing binding + //~^ similar_names + match 5 { cheese @ 1 => {}, @@ -69,12 +71,14 @@ fn main() { let xyz1abc: i32; let xyz2abc: i32; let xyzeabc: i32; - //~^ ERROR: binding's name is too similar to existing binding + //~^ similar_names + let parser: i32; let parsed: i32; let parsee: i32; - //~^ ERROR: binding's name is too similar to existing binding + //~^ similar_names + let setter: i32; let getter: i32; @@ -96,7 +100,8 @@ fn foo() { let Foo { apple: spring, bpple: sprang, - //~^ ERROR: binding's name is too similar to existing binding + //~^ similar_names + } = unimplemented!(); } diff --git a/tests/ui/similar_names.stderr b/tests/ui/similar_names.stderr index 8d722fb8b564..36255f52e825 100644 --- a/tests/ui/similar_names.stderr +++ b/tests/ui/similar_names.stderr @@ -13,49 +13,49 @@ LL | let blubx: i32; = help: to override `-D warnings` add `#[allow(clippy::similar_names)]` error: binding's name is too similar to existing binding - --> tests/ui/similar_names.rs:52:9 + --> tests/ui/similar_names.rs:53:9 | LL | let coke: i32; | ^^^^ | note: existing binding defined here - --> tests/ui/similar_names.rs:50:9 + --> tests/ui/similar_names.rs:51:9 | LL | let cake: i32; | ^^^^ error: binding's name is too similar to existing binding - --> tests/ui/similar_names.rs:71:9 + --> tests/ui/similar_names.rs:73:9 | LL | let xyzeabc: i32; | ^^^^^^^ | note: existing binding defined here - --> tests/ui/similar_names.rs:69:9 + --> tests/ui/similar_names.rs:71:9 | LL | let xyz1abc: i32; | ^^^^^^^ error: binding's name is too similar to existing binding - --> tests/ui/similar_names.rs:76:9 + --> tests/ui/similar_names.rs:79:9 | LL | let parsee: i32; | ^^^^^^ | note: existing binding defined here - --> tests/ui/similar_names.rs:74:9 + --> tests/ui/similar_names.rs:77:9 | LL | let parser: i32; | ^^^^^^ error: binding's name is too similar to existing binding - --> tests/ui/similar_names.rs:98:16 + --> tests/ui/similar_names.rs:102:16 | LL | bpple: sprang, | ^^^^^^ | note: existing binding defined here - --> tests/ui/similar_names.rs:97:16 + --> tests/ui/similar_names.rs:101:16 | LL | apple: spring, | ^^^^^^ diff --git a/tests/ui/single_call_fn.rs b/tests/ui/single_call_fn.rs index a0597664da55..0894509b73ea 100644 --- a/tests/ui/single_call_fn.rs +++ b/tests/ui/single_call_fn.rs @@ -11,7 +11,9 @@ extern crate proc_macros; pub fn f() {} fn i() {} +//~^ single_call_fn fn j() {} +//~^ single_call_fn fn h() { // Linted @@ -32,6 +34,7 @@ fn g() { } fn c() { +//~^ single_call_fn println!("really"); println!("long"); println!("function..."); @@ -42,6 +45,7 @@ fn d() { } fn a() {} +//~^ single_call_fn fn b() { a(); @@ -87,6 +91,7 @@ fn l() { trait Trait { fn default() {} + //~^ single_call_fn fn foo(&self); } extern "C" { @@ -100,6 +105,7 @@ fn m(v: T) { struct S; impl S { fn foo() {} + //~^ single_call_fn } T::default(); S::foo(); diff --git a/tests/ui/single_call_fn.stderr b/tests/ui/single_call_fn.stderr index 14529beac616..8dd90a123852 100644 --- a/tests/ui/single_call_fn.stderr +++ b/tests/ui/single_call_fn.stderr @@ -5,7 +5,7 @@ LL | fn i() {} | ^^^^^^^^^ | note: used here - --> tests/ui/single_call_fn.rs:18:13 + --> tests/ui/single_call_fn.rs:20:13 | LL | let a = i; | ^ @@ -13,21 +13,22 @@ LL | let a = i; = help: to override `-D warnings` add `#[allow(clippy::single_call_fn)]` error: this function is only used once - --> tests/ui/single_call_fn.rs:14:1 + --> tests/ui/single_call_fn.rs:15:1 | LL | fn j() {} | ^^^^^^^^^ | note: used here - --> tests/ui/single_call_fn.rs:25:9 + --> tests/ui/single_call_fn.rs:27:9 | LL | j(); | ^ error: this function is only used once - --> tests/ui/single_call_fn.rs:34:1 + --> tests/ui/single_call_fn.rs:36:1 | LL | / fn c() { +LL | | LL | | println!("really"); LL | | println!("long"); LL | | println!("function..."); @@ -35,43 +36,43 @@ LL | | } | |_^ | note: used here - --> tests/ui/single_call_fn.rs:41:5 + --> tests/ui/single_call_fn.rs:44:5 | LL | c(); | ^ error: this function is only used once - --> tests/ui/single_call_fn.rs:44:1 + --> tests/ui/single_call_fn.rs:47:1 | LL | fn a() {} | ^^^^^^^^^ | note: used here - --> tests/ui/single_call_fn.rs:47:5 + --> tests/ui/single_call_fn.rs:51:5 | LL | a(); | ^ error: this function is only used once - --> tests/ui/single_call_fn.rs:89:5 + --> tests/ui/single_call_fn.rs:93:5 | LL | fn default() {} | ^^^^^^^^^^^^^^^ | note: used here - --> tests/ui/single_call_fn.rs:104:5 + --> tests/ui/single_call_fn.rs:110:5 | LL | T::default(); | ^^^^^^^^^^ error: this function is only used once - --> tests/ui/single_call_fn.rs:102:9 + --> tests/ui/single_call_fn.rs:107:9 | LL | fn foo() {} | ^^^^^^^^^^^ | note: used here - --> tests/ui/single_call_fn.rs:105:5 + --> tests/ui/single_call_fn.rs:111:5 | LL | S::foo(); | ^^^^^^ diff --git a/tests/ui/single_char_add_str.fixed b/tests/ui/single_char_add_str.fixed index aef15252b1bc..b729cf8b2ca1 100644 --- a/tests/ui/single_char_add_str.fixed +++ b/tests/ui/single_char_add_str.fixed @@ -12,44 +12,65 @@ fn main() { let mut string = String::new(); string.push('R'); + //~^ single_char_add_str string.push('\''); + //~^ single_char_add_str string.push('u'); string.push_str("st"); string.push_str(""); string.push('\x52'); + //~^ single_char_add_str string.push('\u{0052}'); + //~^ single_char_add_str string.push('a'); + //~^ single_char_add_str let c_ref = &'a'; string.push(*c_ref); + //~^ single_char_add_str let c = 'a'; string.push(c); + //~^ single_char_add_str string.push('a'); + //~^ single_char_add_str get_string!().push('ö'); + //~^ single_char_add_str // `insert_str` tests let mut string = String::new(); string.insert(0, 'R'); + //~^ single_char_add_str string.insert(1, '\''); + //~^ single_char_add_str string.insert(0, 'u'); string.insert_str(2, "st"); string.insert_str(0, ""); string.insert(0, '\x52'); + //~^ single_char_add_str string.insert(0, '\u{0052}'); + //~^ single_char_add_str let x: usize = 2; string.insert(x, 'a'); + //~^ single_char_add_str const Y: usize = 1; string.insert(Y, 'a'); + //~^ single_char_add_str string.insert(Y, '"'); + //~^ single_char_add_str string.insert(Y, '\''); + //~^ single_char_add_str string.insert(0, *c_ref); + //~^ single_char_add_str string.insert(0, c); + //~^ single_char_add_str string.insert(0, 'a'); + //~^ single_char_add_str get_string!().insert(1, '?'); + //~^ single_char_add_str } diff --git a/tests/ui/single_char_add_str.rs b/tests/ui/single_char_add_str.rs index 7f97250dacd4..a768c47db391 100644 --- a/tests/ui/single_char_add_str.rs +++ b/tests/ui/single_char_add_str.rs @@ -12,44 +12,65 @@ fn main() { let mut string = String::new(); string.push_str("R"); + //~^ single_char_add_str string.push_str("'"); + //~^ single_char_add_str string.push('u'); string.push_str("st"); string.push_str(""); string.push_str("\x52"); + //~^ single_char_add_str string.push_str("\u{0052}"); + //~^ single_char_add_str string.push_str(r##"a"##); + //~^ single_char_add_str let c_ref = &'a'; string.push_str(&c_ref.to_string()); + //~^ single_char_add_str let c = 'a'; string.push_str(&c.to_string()); + //~^ single_char_add_str string.push_str(&'a'.to_string()); + //~^ single_char_add_str get_string!().push_str("ö"); + //~^ single_char_add_str // `insert_str` tests let mut string = String::new(); string.insert_str(0, "R"); + //~^ single_char_add_str string.insert_str(1, "'"); + //~^ single_char_add_str string.insert(0, 'u'); string.insert_str(2, "st"); string.insert_str(0, ""); string.insert_str(0, "\x52"); + //~^ single_char_add_str string.insert_str(0, "\u{0052}"); + //~^ single_char_add_str let x: usize = 2; string.insert_str(x, r##"a"##); + //~^ single_char_add_str const Y: usize = 1; string.insert_str(Y, r##"a"##); + //~^ single_char_add_str string.insert_str(Y, r##"""##); + //~^ single_char_add_str string.insert_str(Y, r##"'"##); + //~^ single_char_add_str string.insert_str(0, &c_ref.to_string()); + //~^ single_char_add_str string.insert_str(0, &c.to_string()); + //~^ single_char_add_str string.insert_str(0, &'a'.to_string()); + //~^ single_char_add_str get_string!().insert_str(1, "?"); + //~^ single_char_add_str } diff --git a/tests/ui/single_char_add_str.stderr b/tests/ui/single_char_add_str.stderr index 7791c67578aa..a1fae93462c9 100644 --- a/tests/ui/single_char_add_str.stderr +++ b/tests/ui/single_char_add_str.stderr @@ -8,121 +8,121 @@ LL | string.push_str("R"); = help: to override `-D warnings` add `#[allow(clippy::single_char_add_str)]` error: calling `push_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:15:5 + --> tests/ui/single_char_add_str.rs:16:5 | LL | string.push_str("'"); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('\'')` error: calling `push_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:20:5 + --> tests/ui/single_char_add_str.rs:22:5 | LL | string.push_str("\x52"); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('\x52')` error: calling `push_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:21:5 + --> tests/ui/single_char_add_str.rs:24:5 | LL | string.push_str("\u{0052}"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('\u{0052}')` error: calling `push_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:22:5 + --> tests/ui/single_char_add_str.rs:26:5 | LL | string.push_str(r##"a"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('a')` error: calling `push_str()` using a single-character converted to string - --> tests/ui/single_char_add_str.rs:25:5 + --> tests/ui/single_char_add_str.rs:30:5 | LL | string.push_str(&c_ref.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push(*c_ref)` error: calling `push_str()` using a single-character converted to string - --> tests/ui/single_char_add_str.rs:27:5 + --> tests/ui/single_char_add_str.rs:33:5 | LL | string.push_str(&c.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push(c)` error: calling `push_str()` using a single-character converted to string - --> tests/ui/single_char_add_str.rs:28:5 + --> tests/ui/single_char_add_str.rs:35:5 | LL | string.push_str(&'a'.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push('a')` error: calling `push_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:30:5 + --> tests/ui/single_char_add_str.rs:38:5 | LL | get_string!().push_str("ö"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `get_string!().push('ö')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:35:5 + --> tests/ui/single_char_add_str.rs:44:5 | LL | string.insert_str(0, "R"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, 'R')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:36:5 + --> tests/ui/single_char_add_str.rs:46:5 | LL | string.insert_str(1, "'"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(1, '\'')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:41:5 + --> tests/ui/single_char_add_str.rs:52:5 | LL | string.insert_str(0, "\x52"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\x52')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:42:5 + --> tests/ui/single_char_add_str.rs:54:5 | LL | string.insert_str(0, "\u{0052}"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\u{0052}')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:44:5 + --> tests/ui/single_char_add_str.rs:57:5 | LL | string.insert_str(x, r##"a"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(x, 'a')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:46:5 + --> tests/ui/single_char_add_str.rs:60:5 | LL | string.insert_str(Y, r##"a"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, 'a')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:47:5 + --> tests/ui/single_char_add_str.rs:62:5 | LL | string.insert_str(Y, r##"""##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '"')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:48:5 + --> tests/ui/single_char_add_str.rs:64:5 | LL | string.insert_str(Y, r##"'"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '\'')` error: calling `insert_str()` using a single-character converted to string - --> tests/ui/single_char_add_str.rs:50:5 + --> tests/ui/single_char_add_str.rs:67:5 | LL | string.insert_str(0, &c_ref.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, *c_ref)` error: calling `insert_str()` using a single-character converted to string - --> tests/ui/single_char_add_str.rs:51:5 + --> tests/ui/single_char_add_str.rs:69:5 | LL | string.insert_str(0, &c.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, c)` error: calling `insert_str()` using a single-character converted to string - --> tests/ui/single_char_add_str.rs:52:5 + --> tests/ui/single_char_add_str.rs:71:5 | LL | string.insert_str(0, &'a'.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, 'a')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:54:5 + --> tests/ui/single_char_add_str.rs:74:5 | LL | get_string!().insert_str(1, "?"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `get_string!().insert(1, '?')` diff --git a/tests/ui/single_char_lifetime_names.rs b/tests/ui/single_char_lifetime_names.rs index 6731b5b13564..e6a35cfe1642 100644 --- a/tests/ui/single_char_lifetime_names.rs +++ b/tests/ui/single_char_lifetime_names.rs @@ -3,8 +3,10 @@ // Lifetimes should only be linted when they're introduced struct DiagnosticCtx<'a, 'b> -//~^ ERROR: single-character lifetime names are likely uninformative -//~| ERROR: single-character lifetime names are likely uninformative +//~^ single_char_lifetime_names +//~| single_char_lifetime_names + + where 'a: 'b, { @@ -14,8 +16,10 @@ where // Only the lifetimes on the `impl`'s generics should be linted impl<'a, 'b> DiagnosticCtx<'a, 'b> { - //~^ ERROR: single-character lifetime names are likely uninformative - //~| ERROR: single-character lifetime names are likely uninformative +//~^ single_char_lifetime_names +//~| single_char_lifetime_names + + fn new(source: &'a str, unit: &'b ()) -> DiagnosticCtx<'a, 'b> { Self { _source: source, @@ -36,7 +40,8 @@ impl<'src, 'unit> DiagnosticCtx<'src, 'unit> { // Only 'a should be linted here fn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) { - //~^ ERROR: single-character lifetime names are likely uninformative +//~^ single_char_lifetime_names + base.split_once(other) .map(|(left, right)| (left, Some(right))) .unwrap_or((base, None)) diff --git a/tests/ui/single_char_lifetime_names.stderr b/tests/ui/single_char_lifetime_names.stderr index 005c897b19ba..010390ce15cc 100644 --- a/tests/ui/single_char_lifetime_names.stderr +++ b/tests/ui/single_char_lifetime_names.stderr @@ -17,7 +17,7 @@ LL | struct DiagnosticCtx<'a, 'b> = help: use a more informative name error: single-character lifetime names are likely uninformative - --> tests/ui/single_char_lifetime_names.rs:16:6 + --> tests/ui/single_char_lifetime_names.rs:18:6 | LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> { | ^^ @@ -25,7 +25,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> { = help: use a more informative name error: single-character lifetime names are likely uninformative - --> tests/ui/single_char_lifetime_names.rs:16:10 + --> tests/ui/single_char_lifetime_names.rs:18:10 | LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> { | ^^ @@ -33,7 +33,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> { = help: use a more informative name error: single-character lifetime names are likely uninformative - --> tests/ui/single_char_lifetime_names.rs:38:15 + --> tests/ui/single_char_lifetime_names.rs:42:15 | LL | fn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) { | ^^ diff --git a/tests/ui/single_char_pattern.fixed b/tests/ui/single_char_pattern.fixed index a18d6319f89d..717779f03ab2 100644 --- a/tests/ui/single_char_pattern.fixed +++ b/tests/ui/single_char_pattern.fixed @@ -5,6 +5,7 @@ use std::collections::HashSet; fn main() { let x = "foo"; x.split('x'); + //~^ single_char_pattern x.split("xx"); x.split('x'); @@ -16,38 +17,65 @@ fn main() { // Can't use this lint for unicode code points which don't fit in a char x.split("❤️"); x.split_inclusive('x'); + //~^ single_char_pattern x.contains('x'); + //~^ single_char_pattern x.starts_with('x'); + //~^ single_char_pattern x.ends_with('x'); + //~^ single_char_pattern x.find('x'); + //~^ single_char_pattern x.rfind('x'); + //~^ single_char_pattern x.rsplit('x'); + //~^ single_char_pattern x.split_terminator('x'); + //~^ single_char_pattern x.rsplit_terminator('x'); + //~^ single_char_pattern x.splitn(2, 'x'); + //~^ single_char_pattern x.rsplitn(2, 'x'); + //~^ single_char_pattern x.split_once('x'); + //~^ single_char_pattern x.rsplit_once('x'); + //~^ single_char_pattern x.matches('x'); + //~^ single_char_pattern x.rmatches('x'); + //~^ single_char_pattern x.match_indices('x'); + //~^ single_char_pattern x.rmatch_indices('x'); + //~^ single_char_pattern x.trim_start_matches('x'); + //~^ single_char_pattern x.trim_end_matches('x'); + //~^ single_char_pattern x.replace('x', "y"); + //~^ single_char_pattern x.replacen('x', "y", 3); + //~^ single_char_pattern // Make sure we escape characters correctly. x.split('\n'); + //~^ single_char_pattern x.split('\''); + //~^ single_char_pattern x.split('\''); + //~^ single_char_pattern // Issue #11973: Don't escape `"` in `'"'` x.split('"'); + //~^ single_char_pattern let h = HashSet::::new(); h.contains("X"); // should not warn x.replace(';', ",").split(','); // issue #2978 + //~^ single_char_pattern x.starts_with('\x03'); // issue #2996 + //~^ single_char_pattern // Issue #3204 const S: &str = "#"; @@ -55,13 +83,20 @@ fn main() { // Raw string x.split('a'); + //~^ single_char_pattern x.split('a'); + //~^ single_char_pattern x.split('a'); + //~^ single_char_pattern x.split('\''); + //~^ single_char_pattern x.split('#'); + //~^ single_char_pattern // Must escape backslash in raw strings when converting to char #8060 x.split('\\'); + //~^ single_char_pattern x.split('\\'); + //~^ single_char_pattern // should not warn, the char versions are actually slower in some cases x.strip_prefix("x"); diff --git a/tests/ui/single_char_pattern.rs b/tests/ui/single_char_pattern.rs index b52e6fb2fdfb..88f6b85f946f 100644 --- a/tests/ui/single_char_pattern.rs +++ b/tests/ui/single_char_pattern.rs @@ -5,6 +5,7 @@ use std::collections::HashSet; fn main() { let x = "foo"; x.split("x"); + //~^ single_char_pattern x.split("xx"); x.split('x'); @@ -16,38 +17,65 @@ fn main() { // Can't use this lint for unicode code points which don't fit in a char x.split("❤️"); x.split_inclusive("x"); + //~^ single_char_pattern x.contains("x"); + //~^ single_char_pattern x.starts_with("x"); + //~^ single_char_pattern x.ends_with("x"); + //~^ single_char_pattern x.find("x"); + //~^ single_char_pattern x.rfind("x"); + //~^ single_char_pattern x.rsplit("x"); + //~^ single_char_pattern x.split_terminator("x"); + //~^ single_char_pattern x.rsplit_terminator("x"); + //~^ single_char_pattern x.splitn(2, "x"); + //~^ single_char_pattern x.rsplitn(2, "x"); + //~^ single_char_pattern x.split_once("x"); + //~^ single_char_pattern x.rsplit_once("x"); + //~^ single_char_pattern x.matches("x"); + //~^ single_char_pattern x.rmatches("x"); + //~^ single_char_pattern x.match_indices("x"); + //~^ single_char_pattern x.rmatch_indices("x"); + //~^ single_char_pattern x.trim_start_matches("x"); + //~^ single_char_pattern x.trim_end_matches("x"); + //~^ single_char_pattern x.replace("x", "y"); + //~^ single_char_pattern x.replacen("x", "y", 3); + //~^ single_char_pattern // Make sure we escape characters correctly. x.split("\n"); + //~^ single_char_pattern x.split("'"); + //~^ single_char_pattern x.split("\'"); + //~^ single_char_pattern // Issue #11973: Don't escape `"` in `'"'` x.split("\""); + //~^ single_char_pattern let h = HashSet::::new(); h.contains("X"); // should not warn x.replace(';', ",").split(","); // issue #2978 + //~^ single_char_pattern x.starts_with("\x03"); // issue #2996 + //~^ single_char_pattern // Issue #3204 const S: &str = "#"; @@ -55,13 +83,20 @@ fn main() { // Raw string x.split(r"a"); + //~^ single_char_pattern x.split(r#"a"#); + //~^ single_char_pattern x.split(r###"a"###); + //~^ single_char_pattern x.split(r###"'"###); + //~^ single_char_pattern x.split(r###"#"###); + //~^ single_char_pattern // Must escape backslash in raw strings when converting to char #8060 x.split(r#"\"#); + //~^ single_char_pattern x.split(r"\"); + //~^ single_char_pattern // should not warn, the char versions are actually slower in some cases x.strip_prefix("x"); diff --git a/tests/ui/single_char_pattern.stderr b/tests/ui/single_char_pattern.stderr index b2deed23cbd5..80d9c7b04637 100644 --- a/tests/ui/single_char_pattern.stderr +++ b/tests/ui/single_char_pattern.stderr @@ -8,205 +8,205 @@ LL | x.split("x"); = help: to override `-D warnings` add `#[allow(clippy::single_char_pattern)]` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:18:23 + --> tests/ui/single_char_pattern.rs:19:23 | LL | x.split_inclusive("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:19:16 + --> tests/ui/single_char_pattern.rs:21:16 | LL | x.contains("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:20:19 + --> tests/ui/single_char_pattern.rs:23:19 | LL | x.starts_with("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:21:17 + --> tests/ui/single_char_pattern.rs:25:17 | LL | x.ends_with("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:22:12 + --> tests/ui/single_char_pattern.rs:27:12 | LL | x.find("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:23:13 + --> tests/ui/single_char_pattern.rs:29:13 | LL | x.rfind("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:24:14 + --> tests/ui/single_char_pattern.rs:31:14 | LL | x.rsplit("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:25:24 + --> tests/ui/single_char_pattern.rs:33:24 | LL | x.split_terminator("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:26:25 + --> tests/ui/single_char_pattern.rs:35:25 | LL | x.rsplit_terminator("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:27:17 + --> tests/ui/single_char_pattern.rs:37:17 | LL | x.splitn(2, "x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:28:18 + --> tests/ui/single_char_pattern.rs:39:18 | LL | x.rsplitn(2, "x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:29:18 + --> tests/ui/single_char_pattern.rs:41:18 | LL | x.split_once("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:30:19 + --> tests/ui/single_char_pattern.rs:43:19 | LL | x.rsplit_once("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:31:15 + --> tests/ui/single_char_pattern.rs:45:15 | LL | x.matches("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:32:16 + --> tests/ui/single_char_pattern.rs:47:16 | LL | x.rmatches("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:33:21 + --> tests/ui/single_char_pattern.rs:49:21 | LL | x.match_indices("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:34:22 + --> tests/ui/single_char_pattern.rs:51:22 | LL | x.rmatch_indices("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:35:26 + --> tests/ui/single_char_pattern.rs:53:26 | LL | x.trim_start_matches("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:36:24 + --> tests/ui/single_char_pattern.rs:55:24 | LL | x.trim_end_matches("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:37:15 + --> tests/ui/single_char_pattern.rs:57:15 | LL | x.replace("x", "y"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:38:16 + --> tests/ui/single_char_pattern.rs:59:16 | LL | x.replacen("x", "y", 3); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:40:13 + --> tests/ui/single_char_pattern.rs:62:13 | LL | x.split("\n"); | ^^^^ help: consider using a `char`: `'\n'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:41:13 + --> tests/ui/single_char_pattern.rs:64:13 | LL | x.split("'"); | ^^^ help: consider using a `char`: `'\''` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:42:13 + --> tests/ui/single_char_pattern.rs:66:13 | LL | x.split("\'"); | ^^^^ help: consider using a `char`: `'\''` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:44:13 + --> tests/ui/single_char_pattern.rs:69:13 | LL | x.split("\""); | ^^^^ help: consider using a `char`: `'"'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:49:31 + --> tests/ui/single_char_pattern.rs:75:31 | LL | x.replace(';', ",").split(","); // issue #2978 | ^^^ help: consider using a `char`: `','` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:50:19 + --> tests/ui/single_char_pattern.rs:77:19 | LL | x.starts_with("\x03"); // issue #2996 | ^^^^^^ help: consider using a `char`: `'\x03'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:57:13 + --> tests/ui/single_char_pattern.rs:85:13 | LL | x.split(r"a"); | ^^^^ help: consider using a `char`: `'a'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:58:13 + --> tests/ui/single_char_pattern.rs:87:13 | LL | x.split(r#"a"#); | ^^^^^^ help: consider using a `char`: `'a'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:59:13 + --> tests/ui/single_char_pattern.rs:89:13 | LL | x.split(r###"a"###); | ^^^^^^^^^^ help: consider using a `char`: `'a'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:60:13 + --> tests/ui/single_char_pattern.rs:91:13 | LL | x.split(r###"'"###); | ^^^^^^^^^^ help: consider using a `char`: `'\''` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:61:13 + --> tests/ui/single_char_pattern.rs:93:13 | LL | x.split(r###"#"###); | ^^^^^^^^^^ help: consider using a `char`: `'#'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:63:13 + --> tests/ui/single_char_pattern.rs:96:13 | LL | x.split(r#"\"#); | ^^^^^^ help: consider using a `char`: `'\\'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:64:13 + --> tests/ui/single_char_pattern.rs:98:13 | LL | x.split(r"\"); | ^^^^ help: consider using a `char`: `'\\'` diff --git a/tests/ui/single_component_path_imports.fixed b/tests/ui/single_component_path_imports.fixed index 3e81bcd5e487..180a55813b19 100644 --- a/tests/ui/single_component_path_imports.fixed +++ b/tests/ui/single_component_path_imports.fixed @@ -3,6 +3,7 @@ use core; +//~^ single_component_path_imports use serde as edres; @@ -29,6 +30,7 @@ fn main() { mod hello_mod { + //~^ single_component_path_imports #[allow(dead_code)] fn hello_mod() {} } diff --git a/tests/ui/single_component_path_imports.rs b/tests/ui/single_component_path_imports.rs index 2d72f122adf2..888c533c534c 100644 --- a/tests/ui/single_component_path_imports.rs +++ b/tests/ui/single_component_path_imports.rs @@ -4,6 +4,7 @@ use core; use regex; +//~^ single_component_path_imports use serde as edres; @@ -30,6 +31,7 @@ fn main() { mod hello_mod { use regex; + //~^ single_component_path_imports #[allow(dead_code)] fn hello_mod() {} } diff --git a/tests/ui/single_component_path_imports.stderr b/tests/ui/single_component_path_imports.stderr index 95d7e4d85b7c..f1c56b14358f 100644 --- a/tests/ui/single_component_path_imports.stderr +++ b/tests/ui/single_component_path_imports.stderr @@ -8,7 +8,7 @@ LL | use regex; = help: to override `-D warnings` add `#[allow(clippy::single_component_path_imports)]` error: this import is redundant - --> tests/ui/single_component_path_imports.rs:32:5 + --> tests/ui/single_component_path_imports.rs:33:5 | LL | use regex; | ^^^^^^^^^^ help: remove it entirely diff --git a/tests/ui/single_component_path_imports_macro.rs b/tests/ui/single_component_path_imports_macro.rs index fda294a61546..f655ea482d1c 100644 --- a/tests/ui/single_component_path_imports_macro.rs +++ b/tests/ui/single_component_path_imports_macro.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::single_component_path_imports)] #![allow(unused_imports)] diff --git a/tests/ui/single_component_path_imports_nested_first.rs b/tests/ui/single_component_path_imports_nested_first.rs index b4a1ce1d6aec..b1c6e6f94e42 100644 --- a/tests/ui/single_component_path_imports_nested_first.rs +++ b/tests/ui/single_component_path_imports_nested_first.rs @@ -2,8 +2,9 @@ #![allow(unused_imports)] //@no-rustfix use regex; -//~^ ERROR: this import is redundant -//~| NOTE: `-D clippy::single-component-path-imports` implied by `-D warnings` +//~^ single_component_path_imports + + use serde as edres; @@ -15,8 +16,10 @@ fn main() { mod root_nested_use_mod { use {regex, serde}; - //~^ ERROR: this import is redundant - //~| ERROR: this import is redundant + //~^ single_component_path_imports + //~| single_component_path_imports + + #[allow(dead_code)] fn root_nested_use_mod() {} } diff --git a/tests/ui/single_component_path_imports_nested_first.stderr b/tests/ui/single_component_path_imports_nested_first.stderr index 8eec877860e7..8df4d8404eea 100644 --- a/tests/ui/single_component_path_imports_nested_first.stderr +++ b/tests/ui/single_component_path_imports_nested_first.stderr @@ -8,7 +8,7 @@ LL | use regex; = help: to override `-D warnings` add `#[allow(clippy::single_component_path_imports)]` error: this import is redundant - --> tests/ui/single_component_path_imports_nested_first.rs:17:10 + --> tests/ui/single_component_path_imports_nested_first.rs:18:10 | LL | use {regex, serde}; | ^^^^^ @@ -16,7 +16,7 @@ LL | use {regex, serde}; = help: remove this import error: this import is redundant - --> tests/ui/single_component_path_imports_nested_first.rs:17:17 + --> tests/ui/single_component_path_imports_nested_first.rs:18:17 | LL | use {regex, serde}; | ^^^^^ diff --git a/tests/ui/single_component_path_imports_self_after.rs b/tests/ui/single_component_path_imports_self_after.rs index 5723d480a2e1..a0f2cf690809 100644 --- a/tests/ui/single_component_path_imports_self_after.rs +++ b/tests/ui/single_component_path_imports_self_after.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::single_component_path_imports)] #![allow(unused_imports)] diff --git a/tests/ui/single_component_path_imports_self_before.rs b/tests/ui/single_component_path_imports_self_before.rs index 8a4fbf0dc5b6..b80580da10c3 100644 --- a/tests/ui/single_component_path_imports_self_before.rs +++ b/tests/ui/single_component_path_imports_self_before.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![warn(clippy::single_component_path_imports)] #![allow(unused_imports)] diff --git a/tests/ui/single_element_loop.fixed b/tests/ui/single_element_loop.fixed index 64cbd5e9c905..eadf77f0fa50 100644 --- a/tests/ui/single_element_loop.fixed +++ b/tests/ui/single_element_loop.fixed @@ -7,27 +7,33 @@ fn main() { let item1 = 2; { let item = &item1; + //~^ single_element_loop dbg!(item); } { let item = &item1; + //~^ single_element_loop dbg!(item); } for item in 0..5 { + //~^ single_element_loop dbg!(item); } for item in 0..5 { + //~^ single_element_loop dbg!(item); } for item in 0..5 { + //~^ single_element_loop dbg!(item); } for item in 0..5 { + //~^ single_element_loop dbg!(item); } @@ -48,6 +54,7 @@ fn main() { // should lint (issue #10018) { let _ = 42; + //~^ single_element_loop let _f = |n: u32| { for i in 0..n { if i > 10 { @@ -63,6 +70,7 @@ fn main() { { let (Ok(mut _x) | Err(mut _x)) = res_void; + //~^ single_element_loop let ptr: *const bool = std::ptr::null(); } } diff --git a/tests/ui/single_element_loop.rs b/tests/ui/single_element_loop.rs index 92406f1c1cac..6aa9269e56c0 100644 --- a/tests/ui/single_element_loop.rs +++ b/tests/ui/single_element_loop.rs @@ -6,26 +6,32 @@ fn main() { let item1 = 2; for item in &[item1] { + //~^ single_element_loop dbg!(item); } for item in [item1].iter() { + //~^ single_element_loop dbg!(item); } for item in &[0..5] { + //~^ single_element_loop dbg!(item); } for item in [0..5].iter_mut() { + //~^ single_element_loop dbg!(item); } for item in [0..5] { + //~^ single_element_loop dbg!(item); } for item in [0..5].into_iter() { + //~^ single_element_loop dbg!(item); } @@ -45,6 +51,7 @@ fn main() { // should lint (issue #10018) for _ in [42] { + //~^ single_element_loop let _f = |n: u32| { for i in 0..n { if i > 10 { @@ -59,6 +66,7 @@ fn main() { let res_void: Result = Ok(true); for (Ok(mut _x) | Err(mut _x)) in [res_void] { + //~^ single_element_loop let ptr: *const bool = std::ptr::null(); } } diff --git a/tests/ui/single_element_loop.stderr b/tests/ui/single_element_loop.stderr index 73453dd2dfd8..639f8d2d1b98 100644 --- a/tests/ui/single_element_loop.stderr +++ b/tests/ui/single_element_loop.stderr @@ -2,6 +2,7 @@ error: for loop over a single element --> tests/ui/single_element_loop.rs:8:5 | LL | / for item in &[item1] { +LL | | LL | | dbg!(item); LL | | } | |_____^ @@ -12,14 +13,16 @@ help: try | LL ~ { LL + let item = &item1; +LL + LL + dbg!(item); LL + } | error: for loop over a single element - --> tests/ui/single_element_loop.rs:12:5 + --> tests/ui/single_element_loop.rs:13:5 | LL | / for item in [item1].iter() { +LL | | LL | | dbg!(item); LL | | } | |_____^ @@ -28,41 +31,42 @@ help: try | LL ~ { LL + let item = &item1; +LL + LL + dbg!(item); LL + } | error: this loops only once with `item` being `0..5` - --> tests/ui/single_element_loop.rs:16:17 + --> tests/ui/single_element_loop.rs:18:17 | LL | for item in &[0..5] { | ^^^^^^^ help: did you mean to iterate over the range instead?: `0..5` error: this loops only once with `item` being `0..5` - --> tests/ui/single_element_loop.rs:20:17 + --> tests/ui/single_element_loop.rs:23:17 | LL | for item in [0..5].iter_mut() { | ^^^^^^^^^^^^^^^^^ help: did you mean to iterate over the range instead?: `0..5` error: this loops only once with `item` being `0..5` - --> tests/ui/single_element_loop.rs:24:17 + --> tests/ui/single_element_loop.rs:28:17 | LL | for item in [0..5] { | ^^^^^^ help: did you mean to iterate over the range instead?: `0..5` error: this loops only once with `item` being `0..5` - --> tests/ui/single_element_loop.rs:28:17 + --> tests/ui/single_element_loop.rs:33:17 | LL | for item in [0..5].into_iter() { | ^^^^^^^^^^^^^^^^^^ help: did you mean to iterate over the range instead?: `0..5` error: for loop over a single element - --> tests/ui/single_element_loop.rs:47:5 + --> tests/ui/single_element_loop.rs:53:5 | LL | / for _ in [42] { +LL | | LL | | let _f = |n: u32| { LL | | for i in 0..n { -LL | | if i > 10 { ... | LL | | }; LL | | } @@ -72,6 +76,7 @@ help: try | LL ~ { LL + let _ = 42; +LL + LL + let _f = |n: u32| { LL + for i in 0..n { LL + if i > 10 { @@ -84,9 +89,10 @@ LL + } | error: for loop over a single element - --> tests/ui/single_element_loop.rs:61:5 + --> tests/ui/single_element_loop.rs:68:5 | LL | / for (Ok(mut _x) | Err(mut _x)) in [res_void] { +LL | | LL | | let ptr: *const bool = std::ptr::null(); LL | | } | |_____^ @@ -95,6 +101,7 @@ help: try | LL ~ { LL + let (Ok(mut _x) | Err(mut _x)) = res_void; +LL + LL + let ptr: *const bool = std::ptr::null(); LL + } | diff --git a/tests/ui/single_match.fixed b/tests/ui/single_match.fixed index d3d5fd8b35c8..c6ffe93eb7ab 100644 --- a/tests/ui/single_match.fixed +++ b/tests/ui/single_match.fixed @@ -15,6 +15,7 @@ fn single_match() { if let Some(y) = x { println!("{:?}", y); }; + //~^^^^^^ single_match let x = Some(1u8); match x { @@ -27,6 +28,7 @@ fn single_match() { let z = (1u8, 1u8); if let (2..=3, 7..=9) = z { dummy() }; + //~^^^^ single_match // Not linted (pattern guards used) match x { @@ -53,12 +55,15 @@ fn single_match_know_enum() { let y: Result<_, i8> = Ok(1i8); if let Some(y) = x { dummy() }; + //~^^^^ single_match if let Ok(y) = y { dummy() }; + //~^^^^ single_match let c = Cow::Borrowed(""); if let Cow::Borrowed(..) = c { dummy() }; + //~^^^^ single_match let z = Foo::Bar; // no warning @@ -77,6 +82,7 @@ fn single_match_know_enum() { fn if_suggestion() { let x = "test"; if x == "test" { println!() } + //~^^^^ single_match #[derive(PartialEq, Eq)] enum Foo { @@ -87,14 +93,18 @@ fn if_suggestion() { let x = Foo::A; if x == Foo::A { println!() } + //~^^^^ single_match const FOO_C: Foo = Foo::C(0); if x == FOO_C { println!() } + //~^^^^ single_match if x == Foo::A { println!() } + //~^^^^ single_match let x = &x; if x == &Foo::A { println!() } + //~^^^^ single_match enum Bar { A, @@ -109,11 +119,13 @@ fn if_suggestion() { let x = Bar::A; if let Bar::A = x { println!() } + //~^^^^ single_match // issue #7038 struct X; let x = Some(X); if let None = x { println!() }; + //~^^^^ single_match } // See: issue #8282 @@ -133,12 +145,15 @@ fn ranges() { // lint if let (Some(_), _) = x {} + //~^^^^ single_match // lint if let (Some(E::V), _) = x { todo!() } + //~^^^^ single_match // lint if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {} + //~^^^^ single_match // Don't lint, see above. match (Some(E::V), Some(E::V), Some(E::V)) { @@ -211,6 +226,7 @@ fn issue_10808(bar: Option) { let r = &v as *const i32; println!("{}", *r); } } + //~^^^^^^^ single_match if let Some(v) = bar { unsafe { @@ -218,6 +234,7 @@ fn issue_10808(bar: Option) { println!("{}", *r); } } + //~^^^^^^^^^^ single_match } mod issue8634 { @@ -289,6 +306,7 @@ fn issue11365() { } if let Ok(Some(A)) = Ok::<_, u32>(Some(A)) { println!() } + //~^^^^ single_match match &Some(A) { Some(A | B | C) => println!(), @@ -301,10 +319,12 @@ fn issue11365() { } if let Some(A | B) = &Some(A) { println!() } + //~^^^^ single_match } fn issue12758(s: &[u8]) { if &s[0..3] == b"foo" { println!() } + //~^^^^ single_match } #[derive(Eq, PartialEq)] @@ -315,20 +335,26 @@ const CONST_I32: i32 = 1; fn irrefutable_match() { println!(); + //~^^^^ single_match println!(); + //~^^^^ single_match let i = 0; { let a = 1; let b = 2; } + //~^^^^^^^ single_match + //~^^^^ single_match + //~^^^^ single_match println!(); + //~^^^^ single_match let mut x = vec![1i8]; diff --git a/tests/ui/single_match.rs b/tests/ui/single_match.rs index 2f3547c50639..dc758fa4281c 100644 --- a/tests/ui/single_match.rs +++ b/tests/ui/single_match.rs @@ -18,6 +18,7 @@ fn single_match() { }, _ => (), }; + //~^^^^^^ single_match let x = Some(1u8); match x { @@ -33,6 +34,7 @@ fn single_match() { (2..=3, 7..=9) => dummy(), _ => {}, }; + //~^^^^ single_match // Not linted (pattern guards used) match x { @@ -62,11 +64,13 @@ fn single_match_know_enum() { Some(y) => dummy(), None => (), }; + //~^^^^ single_match match y { Ok(y) => dummy(), Err(..) => (), }; + //~^^^^ single_match let c = Cow::Borrowed(""); @@ -74,6 +78,7 @@ fn single_match_know_enum() { Cow::Borrowed(..) => dummy(), Cow::Owned(..) => (), }; + //~^^^^ single_match let z = Foo::Bar; // no warning @@ -95,6 +100,7 @@ fn if_suggestion() { "test" => println!(), _ => (), } + //~^^^^ single_match #[derive(PartialEq, Eq)] enum Foo { @@ -108,23 +114,27 @@ fn if_suggestion() { Foo::A => println!(), _ => (), } + //~^^^^ single_match const FOO_C: Foo = Foo::C(0); match x { FOO_C => println!(), _ => (), } + //~^^^^ single_match match &&x { Foo::A => println!(), _ => (), } + //~^^^^ single_match let x = &x; match &x { Foo::A => println!(), _ => (), } + //~^^^^ single_match enum Bar { A, @@ -142,6 +152,7 @@ fn if_suggestion() { Bar::A => println!(), _ => (), } + //~^^^^ single_match // issue #7038 struct X; @@ -150,6 +161,7 @@ fn if_suggestion() { None => println!(), _ => (), }; + //~^^^^ single_match } // See: issue #8282 @@ -172,18 +184,21 @@ fn ranges() { (Some(_), _) => {}, (None, _) => {}, } + //~^^^^ single_match // lint match x { (Some(E::V), _) => todo!(), (_, _) => {}, } + //~^^^^ single_match // lint match (Some(42), Some(E::V), Some(42)) { (.., Some(E::V), _) => {}, (..) => {}, } + //~^^^^ single_match // Don't lint, see above. match (Some(E::V), Some(E::V), Some(E::V)) { @@ -259,6 +274,7 @@ fn issue_10808(bar: Option) { }, _ => {}, } + //~^^^^^^^ single_match match bar { #[rustfmt::skip] @@ -270,6 +286,7 @@ fn issue_10808(bar: Option) { }, _ => {}, } + //~^^^^^^^^^^ single_match } mod issue8634 { @@ -344,6 +361,7 @@ fn issue11365() { Ok(Some(A)) => println!(), Err(_) | Ok(None | Some(_)) => {}, } + //~^^^^ single_match match &Some(A) { Some(A | B | C) => println!(), @@ -359,6 +377,7 @@ fn issue11365() { Some(A | B) => println!(), None | Some(_) => {}, } + //~^^^^ single_match } fn issue12758(s: &[u8]) { @@ -366,6 +385,7 @@ fn issue12758(s: &[u8]) { b"foo" => println!(), _ => {}, } + //~^^^^ single_match } #[derive(Eq, PartialEq)] @@ -379,11 +399,13 @@ fn irrefutable_match() { DATA => println!(), _ => {}, } + //~^^^^ single_match match CONST_I32 { CONST_I32 => println!(), _ => {}, } + //~^^^^ single_match let i = 0; match i { @@ -393,21 +415,25 @@ fn irrefutable_match() { }, _ => {}, } + //~^^^^^^^ single_match match i { i => {}, _ => {}, } + //~^^^^ single_match match i { i => (), _ => (), } + //~^^^^ single_match match CONST_I32 { CONST_I32 => println!(), _ => {}, } + //~^^^^ single_match let mut x = vec![1i8]; diff --git a/tests/ui/single_match.stderr b/tests/ui/single_match.stderr deleted file mode 100644 index 54bbfbac093c..000000000000 --- a/tests/ui/single_match.stderr +++ /dev/null @@ -1,282 +0,0 @@ -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:15:5 - | -LL | / match x { -LL | | Some(y) => { -LL | | println!("{:?}", y); -LL | | }, -LL | | _ => (), -LL | | }; - | |_____^ - | - = note: `-D clippy::single-match` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::single_match)]` -help: try - | -LL ~ if let Some(y) = x { -LL + println!("{:?}", y); -LL ~ }; - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:32:5 - | -LL | / match z { -LL | | (2..=3, 7..=9) => dummy(), -LL | | _ => {}, -LL | | }; - | |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:61:5 - | -LL | / match x { -LL | | Some(y) => dummy(), -LL | | None => (), -LL | | }; - | |_____^ help: try: `if let Some(y) = x { dummy() }` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:66:5 - | -LL | / match y { -LL | | Ok(y) => dummy(), -LL | | Err(..) => (), -LL | | }; - | |_____^ help: try: `if let Ok(y) = y { dummy() }` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:73:5 - | -LL | / match c { -LL | | Cow::Borrowed(..) => dummy(), -LL | | Cow::Owned(..) => (), -LL | | }; - | |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }` - -error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> tests/ui/single_match.rs:94:5 - | -LL | / match x { -LL | | "test" => println!(), -LL | | _ => (), -LL | | } - | |_____^ help: try: `if x == "test" { println!() }` - -error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> tests/ui/single_match.rs:107:5 - | -LL | / match x { -LL | | Foo::A => println!(), -LL | | _ => (), -LL | | } - | |_____^ help: try: `if x == Foo::A { println!() }` - -error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> tests/ui/single_match.rs:113:5 - | -LL | / match x { -LL | | FOO_C => println!(), -LL | | _ => (), -LL | | } - | |_____^ help: try: `if x == FOO_C { println!() }` - -error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> tests/ui/single_match.rs:118:5 - | -LL | / match &&x { -LL | | Foo::A => println!(), -LL | | _ => (), -LL | | } - | |_____^ help: try: `if x == Foo::A { println!() }` - -error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> tests/ui/single_match.rs:124:5 - | -LL | / match &x { -LL | | Foo::A => println!(), -LL | | _ => (), -LL | | } - | |_____^ help: try: `if x == &Foo::A { println!() }` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:141:5 - | -LL | / match x { -LL | | Bar::A => println!(), -LL | | _ => (), -LL | | } - | |_____^ help: try: `if let Bar::A = x { println!() }` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:149:5 - | -LL | / match x { -LL | | None => println!(), -LL | | _ => (), -LL | | }; - | |_____^ help: try: `if let None = x { println!() }` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:171:5 - | -LL | / match x { -LL | | (Some(_), _) => {}, -LL | | (None, _) => {}, -LL | | } - | |_____^ help: try: `if let (Some(_), _) = x {}` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:177:5 - | -LL | / match x { -LL | | (Some(E::V), _) => todo!(), -LL | | (_, _) => {}, -LL | | } - | |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:183:5 - | -LL | / match (Some(42), Some(E::V), Some(42)) { -LL | | (.., Some(E::V), _) => {}, -LL | | (..) => {}, -LL | | } - | |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:255:5 - | -LL | / match bar { -LL | | Some(v) => unsafe { -LL | | let r = &v as *const i32; -LL | | println!("{}", *r); -LL | | }, -LL | | _ => {}, -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Some(v) = bar { unsafe { -LL + let r = &v as *const i32; -LL + println!("{}", *r); -LL + } } - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:263:5 - | -LL | / match bar { -LL | | #[rustfmt::skip] -LL | | Some(v) => { -LL | | unsafe { -... | -LL | | _ => {}, -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Some(v) = bar { -LL + unsafe { -LL + let r = &v as *const i32; -LL + println!("{}", *r); -LL + } -LL + } - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:343:5 - | -LL | / match Ok::<_, u32>(Some(A)) { -LL | | Ok(Some(A)) => println!(), -LL | | Err(_) | Ok(None | Some(_)) => {}, -LL | | } - | |_____^ help: try: `if let Ok(Some(A)) = Ok::<_, u32>(Some(A)) { println!() }` - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match.rs:358:5 - | -LL | / match &Some(A) { -LL | | Some(A | B) => println!(), -LL | | None | Some(_) => {}, -LL | | } - | |_____^ help: try: `if let Some(A | B) = &Some(A) { println!() }` - -error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> tests/ui/single_match.rs:365:5 - | -LL | / match &s[0..3] { -LL | | b"foo" => println!(), -LL | | _ => {}, -LL | | } - | |_____^ help: try: `if &s[0..3] == b"foo" { println!() }` - -error: this pattern is irrefutable, `match` is useless - --> tests/ui/single_match.rs:378:5 - | -LL | / match DATA { -LL | | DATA => println!(), -LL | | _ => {}, -LL | | } - | |_____^ help: try: `println!();` - -error: this pattern is irrefutable, `match` is useless - --> tests/ui/single_match.rs:383:5 - | -LL | / match CONST_I32 { -LL | | CONST_I32 => println!(), -LL | | _ => {}, -LL | | } - | |_____^ help: try: `println!();` - -error: this pattern is irrefutable, `match` is useless - --> tests/ui/single_match.rs:389:5 - | -LL | / match i { -LL | | i => { -LL | | let a = 1; -LL | | let b = 2; -LL | | }, -LL | | _ => {}, -LL | | } - | |_____^ - | -help: try - | -LL ~ { -LL + let a = 1; -LL + let b = 2; -LL + } - | - -error: this pattern is irrefutable, `match` is useless - --> tests/ui/single_match.rs:397:5 - | -LL | / match i { -LL | | i => {}, -LL | | _ => {}, -LL | | } - | |_____^ help: `match` expression can be removed - -error: this pattern is irrefutable, `match` is useless - --> tests/ui/single_match.rs:402:5 - | -LL | / match i { -LL | | i => (), -LL | | _ => (), -LL | | } - | |_____^ help: `match` expression can be removed - -error: this pattern is irrefutable, `match` is useless - --> tests/ui/single_match.rs:407:5 - | -LL | / match CONST_I32 { -LL | | CONST_I32 => println!(), -LL | | _ => {}, -LL | | } - | |_____^ help: try: `println!();` - -error: aborting due to 26 previous errors - diff --git a/tests/ui/single_match_else.fixed b/tests/ui/single_match_else.fixed index c2ca746976bd..64782bf62a78 100644 --- a/tests/ui/single_match_else.fixed +++ b/tests/ui/single_match_else.fixed @@ -18,6 +18,7 @@ fn unwrap_addr() -> Option<&'static ExprNode> { let x = 5; None }; + //~^^^^^^^ single_match_else // Don't lint with_span!(span match ExprNode::Butterflies { @@ -80,12 +81,14 @@ fn main() { println!("else block"); return } + //~^^^^^^^ single_match_else // lint here if let Some(a) = Some(1) { println!("${:?}", a) } else { println!("else block"); return; } + //~^^^^^^^ single_match_else // lint here use std::convert::Infallible; @@ -93,12 +96,14 @@ fn main() { println!("else block"); return; } + //~^^^^^^^ single_match_else use std::borrow::Cow; if let Cow::Owned(a) = Cow::from("moo") { println!("${:?}", a) } else { println!("else block"); return; } + //~^^^^^^^ single_match_else } fn issue_10808(bar: Option) { @@ -109,6 +114,7 @@ fn issue_10808(bar: Option) { println!("None1"); println!("None2"); } + //~^^^^^^^^^^ single_match_else if let Some(v) = bar { println!("Some"); @@ -118,6 +124,7 @@ fn issue_10808(bar: Option) { let r = &v as *const i32; println!("{}", *r); } } + //~^^^^^^^^^^^ single_match_else if let Some(v) = bar { unsafe { let r = &v as *const i32; @@ -127,6 +134,7 @@ fn issue_10808(bar: Option) { let r = &v as *const i32; println!("{}", *r); } } + //~^^^^^^^^^^^ single_match_else if let Some(v) = bar { unsafe { @@ -137,6 +145,7 @@ fn issue_10808(bar: Option) { println!("None"); println!("None"); } + //~^^^^^^^^^^^^^ single_match_else match bar { Some(v) => { @@ -174,4 +183,5 @@ fn issue_10808(bar: Option) { fn irrefutable_match() -> Option<&'static ExprNode> { Some(&NODE) + //~^^^^^^^ single_match_else } diff --git a/tests/ui/single_match_else.rs b/tests/ui/single_match_else.rs index 2d9e877ee0fe..3f86f4d51803 100644 --- a/tests/ui/single_match_else.rs +++ b/tests/ui/single_match_else.rs @@ -21,6 +21,7 @@ fn unwrap_addr() -> Option<&'static ExprNode> { None }, }; + //~^^^^^^^ single_match_else // Don't lint with_span!(span match ExprNode::Butterflies { @@ -86,6 +87,7 @@ fn main() { return }, } + //~^^^^^^^ single_match_else // lint here match Some(1) { @@ -95,6 +97,7 @@ fn main() { return; }, } + //~^^^^^^^ single_match_else // lint here use std::convert::Infallible; @@ -105,6 +108,7 @@ fn main() { return; } } + //~^^^^^^^ single_match_else use std::borrow::Cow; match Cow::from("moo") { @@ -114,6 +118,7 @@ fn main() { return; } } + //~^^^^^^^ single_match_else } fn issue_10808(bar: Option) { @@ -127,6 +132,7 @@ fn issue_10808(bar: Option) { println!("None2"); }, } + //~^^^^^^^^^^ single_match_else match bar { Some(v) => { @@ -139,6 +145,7 @@ fn issue_10808(bar: Option) { println!("{}", *r); }, } + //~^^^^^^^^^^^ single_match_else match bar { Some(v) => unsafe { @@ -151,6 +158,7 @@ fn issue_10808(bar: Option) { println!("{}", *r); }, } + //~^^^^^^^^^^^ single_match_else match bar { #[rustfmt::skip] @@ -165,6 +173,7 @@ fn issue_10808(bar: Option) { println!("None"); }, } + //~^^^^^^^^^^^^^ single_match_else match bar { Some(v) => { @@ -208,4 +217,5 @@ fn irrefutable_match() -> Option<&'static ExprNode> { None }, } + //~^^^^^^^ single_match_else } diff --git a/tests/ui/single_match_else.stderr b/tests/ui/single_match_else.stderr deleted file mode 100644 index aa494520b841..000000000000 --- a/tests/ui/single_match_else.stderr +++ /dev/null @@ -1,211 +0,0 @@ -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match_else.rs:17:13 - | -LL | let _ = match ExprNode::Butterflies { - | _____________^ -LL | | ExprNode::ExprAddrOf => Some(&NODE), -LL | | _ => { -LL | | let x = 5; -LL | | None -LL | | }, -LL | | }; - | |_____^ - | - = note: `-D clippy::single-match-else` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::single_match_else)]` -help: try - | -LL ~ let _ = if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else { -LL + let x = 5; -LL + None -LL ~ }; - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match_else.rs:82:5 - | -LL | / match Some(1) { -LL | | Some(a) => println!("${:?}", a), -LL | | None => { -LL | | println!("else block"); -LL | | return -LL | | }, -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Some(a) = Some(1) { println!("${:?}", a) } else { -LL + println!("else block"); -LL + return -LL + } - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match_else.rs:91:5 - | -LL | / match Some(1) { -LL | | Some(a) => println!("${:?}", a), -LL | | None => { -LL | | println!("else block"); -LL | | return; -LL | | }, -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Some(a) = Some(1) { println!("${:?}", a) } else { -LL + println!("else block"); -LL + return; -LL + } - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match_else.rs:101:5 - | -LL | / match Result::::Ok(1) { -LL | | Ok(a) => println!("${:?}", a), -LL | | Err(_) => { -LL | | println!("else block"); -... | -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Ok(a) = Result::::Ok(1) { println!("${:?}", a) } else { -LL + println!("else block"); -LL + return; -LL + } - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match_else.rs:110:5 - | -LL | / match Cow::from("moo") { -LL | | Cow::Owned(a) => println!("${:?}", a), -LL | | Cow::Borrowed(_) => { -LL | | println!("else block"); -... | -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Cow::Owned(a) = Cow::from("moo") { println!("${:?}", a) } else { -LL + println!("else block"); -LL + return; -LL + } - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match_else.rs:120:5 - | -LL | / match bar { -LL | | Some(v) => unsafe { -LL | | let r = &v as *const i32; -LL | | println!("{}", *r); -... | -LL | | }, -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Some(v) = bar { unsafe { -LL + let r = &v as *const i32; -LL + println!("{}", *r); -LL + } } else { -LL + println!("None1"); -LL + println!("None2"); -LL + } - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match_else.rs:131:5 - | -LL | / match bar { -LL | | Some(v) => { -LL | | println!("Some"); -LL | | println!("{v}"); -... | -LL | | }, -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Some(v) = bar { -LL + println!("Some"); -LL + println!("{v}"); -LL + } else { unsafe { -LL + let v = 0; -LL + let r = &v as *const i32; -LL + println!("{}", *r); -LL + } } - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match_else.rs:143:5 - | -LL | / match bar { -LL | | Some(v) => unsafe { -LL | | let r = &v as *const i32; -LL | | println!("{}", *r); -... | -LL | | }, -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Some(v) = bar { unsafe { -LL + let r = &v as *const i32; -LL + println!("{}", *r); -LL + } } else { unsafe { -LL + let v = 0; -LL + let r = &v as *const i32; -LL + println!("{}", *r); -LL + } } - | - -error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> tests/ui/single_match_else.rs:155:5 - | -LL | / match bar { -LL | | #[rustfmt::skip] -LL | | Some(v) => { -LL | | unsafe { -... | -LL | | }, -LL | | } - | |_____^ - | -help: try - | -LL ~ if let Some(v) = bar { -LL + unsafe { -LL + let r = &v as *const i32; -LL + println!("{}", *r); -LL + } -LL + } else { -LL + println!("None"); -LL + println!("None"); -LL + } - | - -error: this pattern is irrefutable, `match` is useless - --> tests/ui/single_match_else.rs:204:5 - | -LL | / match ExprNode::Butterflies { -LL | | ExprNode::Butterflies => Some(&NODE), -LL | | _ => { -LL | | let x = 5; -LL | | None -LL | | }, -LL | | } - | |_____^ help: try: `Some(&NODE)` - -error: aborting due to 10 previous errors - diff --git a/tests/ui/single_option_map.rs b/tests/ui/single_option_map.rs index 571beec54799..fd9db9165bdc 100644 --- a/tests/ui/single_option_map.rs +++ b/tests/ui/single_option_map.rs @@ -6,12 +6,14 @@ static ATOM: AtomicUsize = AtomicUsize::new(42); static MAYBE_ATOMIC: Option<&AtomicUsize> = Some(&ATOM); fn h(arg: Option) -> Option { - //~^ ERROR: `fn` that only maps over argument +//~^ single_option_map + arg.map(|x| x * 2) } fn j(arg: Option) -> Option { - //~^ ERROR: `fn` that only maps over argument +//~^ single_option_map + arg.map(|x| x * 2) } @@ -20,7 +22,8 @@ fn mul_args(a: String, b: u64) -> String { } fn mul_args_opt(a: Option, b: u64) -> Option { - //~^ ERROR: `fn` that only maps over argument +//~^ single_option_map + a.map(|val| mul_args(val, b + 1)) } diff --git a/tests/ui/single_option_map.stderr b/tests/ui/single_option_map.stderr index f7d48eba71e8..11865c5b569f 100644 --- a/tests/ui/single_option_map.stderr +++ b/tests/ui/single_option_map.stderr @@ -3,6 +3,7 @@ error: `fn` that only maps over argument | LL | / fn h(arg: Option) -> Option { LL | | +LL | | LL | | arg.map(|x| x * 2) LL | | } | |_^ @@ -12,10 +13,11 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::single_option_map)]` error: `fn` that only maps over argument - --> tests/ui/single_option_map.rs:13:1 + --> tests/ui/single_option_map.rs:14:1 | LL | / fn j(arg: Option) -> Option { LL | | +LL | | LL | | arg.map(|x| x * 2) LL | | } | |_^ @@ -23,10 +25,11 @@ LL | | } = help: move the `.map` to the caller or to an `_opt` function error: `fn` that only maps over argument - --> tests/ui/single_option_map.rs:22:1 + --> tests/ui/single_option_map.rs:24:1 | LL | / fn mul_args_opt(a: Option, b: u64) -> Option { LL | | +LL | | LL | | a.map(|val| mul_args(val, b + 1)) LL | | } | |_^ diff --git a/tests/ui/single_range_in_vec_init.rs b/tests/ui/single_range_in_vec_init.rs index 7887cfc61750..c6c0cb347dc6 100644 --- a/tests/ui/single_range_in_vec_init.rs +++ b/tests/ui/single_range_in_vec_init.rs @@ -24,16 +24,26 @@ fn awa_vec(start: T, end: T) { fn main() { // Lint [0..200]; + //~^ single_range_in_vec_init vec![0..200]; + //~^ single_range_in_vec_init [0u8..200]; + //~^ single_range_in_vec_init [0usize..200]; + //~^ single_range_in_vec_init [0..200usize]; + //~^ single_range_in_vec_init vec![0u8..200]; + //~^ single_range_in_vec_init vec![0usize..200]; + //~^ single_range_in_vec_init vec![0..200usize]; + //~^ single_range_in_vec_init // Only suggest collect [0..200isize]; + //~^ single_range_in_vec_init vec![0..200isize]; + //~^ single_range_in_vec_init // Do not lint [0..200, 0..100]; vec![0..200, 0..100]; diff --git a/tests/ui/single_range_in_vec_init.stderr b/tests/ui/single_range_in_vec_init.stderr index 9c125adb51a7..48f5a94826c6 100644 --- a/tests/ui/single_range_in_vec_init.stderr +++ b/tests/ui/single_range_in_vec_init.stderr @@ -16,7 +16,7 @@ LL | [0; 200]; | ~~~~~~ error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:27:5 + --> tests/ui/single_range_in_vec_init.rs:28:5 | LL | vec![0..200]; | ^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | vec![0; 200]; | ~~~~~~ error: an array of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:28:5 + --> tests/ui/single_range_in_vec_init.rs:30:5 | LL | [0u8..200]; | ^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | [0u8; 200]; | ~~~~~~~~ error: an array of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:29:5 + --> tests/ui/single_range_in_vec_init.rs:32:5 | LL | [0usize..200]; | ^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | [0usize; 200]; | ~~~~~~~~~~~ error: an array of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:30:5 + --> tests/ui/single_range_in_vec_init.rs:34:5 | LL | [0..200usize]; | ^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | [0; 200usize]; | ~~~~~~~~~~~ error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:31:5 + --> tests/ui/single_range_in_vec_init.rs:36:5 | LL | vec![0u8..200]; | ^^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | vec![0u8; 200]; | ~~~~~~~~ error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:32:5 + --> tests/ui/single_range_in_vec_init.rs:38:5 | LL | vec![0usize..200]; | ^^^^^^^^^^^^^^^^^ @@ -106,7 +106,7 @@ LL | vec![0usize; 200]; | ~~~~~~~~~~~ error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:33:5 + --> tests/ui/single_range_in_vec_init.rs:40:5 | LL | vec![0..200usize]; | ^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | vec![0; 200usize]; | ~~~~~~~~~~~ error: an array of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:35:5 + --> tests/ui/single_range_in_vec_init.rs:43:5 | LL | [0..200isize]; | ^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL | (0..200isize).collect::>(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:36:5 + --> tests/ui/single_range_in_vec_init.rs:45:5 | LL | vec![0..200isize]; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/size_of_in_element_count/expressions.rs b/tests/ui/size_of_in_element_count/expressions.rs index f405ba200acd..39c482af78c0 100644 --- a/tests/ui/size_of_in_element_count/expressions.rs +++ b/tests/ui/size_of_in_element_count/expressions.rs @@ -13,15 +13,18 @@ fn main() { // Count expression involving multiplication of size_of (Should trigger the lint) unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::() * SIZE) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + // Count expression involving nested multiplications of size_of (Should trigger the lint) unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * size_of_val(&x[0]) * 2) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + // Count expression involving divisions of size_of (Should trigger the lint) unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::() / 2) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + // Count expression involving divisions by size_of (Should not trigger the lint) unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / size_of::()) }; @@ -31,7 +34,8 @@ fn main() { // Count expression involving recursive divisions by size_of (Should trigger the lint) unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::())) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + // No size_of calls (Should not trigger the lint) unsafe { copy(x.as_ptr(), y.as_mut_ptr(), SIZE) }; diff --git a/tests/ui/size_of_in_element_count/expressions.stderr b/tests/ui/size_of_in_element_count/expressions.stderr index 74be0d7773df..8af8867e04dd 100644 --- a/tests/ui/size_of_in_element_count/expressions.stderr +++ b/tests/ui/size_of_in_element_count/expressions.stderr @@ -9,7 +9,7 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of:: = help: to override `-D warnings` add `#[allow(clippy::size_of_in_element_count)]` error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/expressions.rs:19:62 + --> tests/ui/size_of_in_element_count/expressions.rs:20:62 | LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * size_of_val(&x[0]) * 2) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * si = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/expressions.rs:23:47 + --> tests/ui/size_of_in_element_count/expressions.rs:25:47 | LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::() / 2) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::( = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/expressions.rs:33:47 + --> tests/ui/size_of_in_element_count/expressions.rs:36:47 | LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::())) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/size_of_in_element_count/functions.rs b/tests/ui/size_of_in_element_count/functions.rs index af18136a1dbe..c8bb603d8165 100644 --- a/tests/ui/size_of_in_element_count/functions.rs +++ b/tests/ui/size_of_in_element_count/functions.rs @@ -16,47 +16,66 @@ fn main() { // Count is size_of (Should trigger the lint) unsafe { copy_nonoverlapping::(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::()) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::()) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::()) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::() * SIZE) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { y.as_mut_ptr().sub(size_of::()) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + y.as_ptr().wrapping_sub(size_of::()); - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { y.as_ptr().add(size_of::()) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + y.as_mut_ptr().wrapping_add(size_of::()); - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + unsafe { y.as_ptr().offset(size_of::() as isize) }; - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + y.as_mut_ptr().wrapping_offset(size_of::() as isize); - //~^ ERROR: found a count of bytes instead of a count of elements of `T` + //~^ size_of_in_element_count + } diff --git a/tests/ui/size_of_in_element_count/functions.stderr b/tests/ui/size_of_in_element_count/functions.stderr index de54789b2251..a05f88436a6a 100644 --- a/tests/ui/size_of_in_element_count/functions.stderr +++ b/tests/ui/size_of_in_element_count/functions.stderr @@ -9,7 +9,7 @@ LL | unsafe { copy_nonoverlapping::(x.as_ptr(), y.as_mut_ptr(), size_of = help: to override `-D warnings` add `#[allow(clippy::size_of_in_element_count)]` error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:20:62 + --> tests/ui/size_of_in_element_count/functions.rs:21:62 | LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; | ^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:23:49 + --> tests/ui/size_of_in_element_count/functions.rs:25:49 | LL | unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:25:64 + --> tests/ui/size_of_in_element_count/functions.rs:28:64 | LL | unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of:: tests/ui/size_of_in_element_count/functions.rs:27:51 + --> tests/ui/size_of_in_element_count/functions.rs:31:51 | LL | unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:29:66 + --> tests/ui/size_of_in_element_count/functions.rs:34:66 | LL | unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::< = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:32:47 + --> tests/ui/size_of_in_element_count/functions.rs:38:47 | LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:34:47 + --> tests/ui/size_of_in_element_count/functions.rs:41:47 | LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; | ^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:37:66 + --> tests/ui/size_of_in_element_count/functions.rs:45:66 | LL | unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::() * SIZE) }; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::< = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:40:46 + --> tests/ui/size_of_in_element_count/functions.rs:49:46 | LL | slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:42:38 + --> tests/ui/size_of_in_element_count/functions.rs:52:38 | LL | slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:45:49 + --> tests/ui/size_of_in_element_count/functions.rs:56:49 | LL | unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:47:41 + --> tests/ui/size_of_in_element_count/functions.rs:59:41 | LL | unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:50:33 + --> tests/ui/size_of_in_element_count/functions.rs:63:33 | LL | unsafe { y.as_mut_ptr().sub(size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | unsafe { y.as_mut_ptr().sub(size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:52:29 + --> tests/ui/size_of_in_element_count/functions.rs:66:29 | LL | y.as_ptr().wrapping_sub(size_of::()); | ^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | y.as_ptr().wrapping_sub(size_of::()); = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:54:29 + --> tests/ui/size_of_in_element_count/functions.rs:69:29 | LL | unsafe { y.as_ptr().add(size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | unsafe { y.as_ptr().add(size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:56:33 + --> tests/ui/size_of_in_element_count/functions.rs:72:33 | LL | y.as_mut_ptr().wrapping_add(size_of::()); | ^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ LL | y.as_mut_ptr().wrapping_add(size_of::()); = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:58:32 + --> tests/ui/size_of_in_element_count/functions.rs:75:32 | LL | unsafe { y.as_ptr().offset(size_of::() as isize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | unsafe { y.as_ptr().offset(size_of::() as isize) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:60:36 + --> tests/ui/size_of_in_element_count/functions.rs:78:36 | LL | y.as_mut_ptr().wrapping_offset(size_of::() as isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/size_of_ref.rs b/tests/ui/size_of_ref.rs index 670c6c080eca..06ed216b3422 100644 --- a/tests/ui/size_of_ref.rs +++ b/tests/ui/size_of_ref.rs @@ -11,9 +11,11 @@ fn main() { size_of_val(y); // no lint size_of_val(&&x); - //~^ ERROR: argument to `std::mem::size_of_val()` is a reference to a reference + //~^ size_of_ref + size_of_val(&y); - //~^ ERROR: argument to `std::mem::size_of_val()` is a reference to a reference + //~^ size_of_ref + } struct S { @@ -25,6 +27,7 @@ impl S { /// Get size of object including `self`, in bytes. pub fn size(&self) -> usize { std::mem::size_of_val(&self) + (std::mem::size_of::() * self.data.capacity()) - //~^ ERROR: argument to `std::mem::size_of_val()` is a reference to a reference + //~^ size_of_ref + } } diff --git a/tests/ui/size_of_ref.stderr b/tests/ui/size_of_ref.stderr index bb8f08de531c..0dc64673940e 100644 --- a/tests/ui/size_of_ref.stderr +++ b/tests/ui/size_of_ref.stderr @@ -9,7 +9,7 @@ LL | size_of_val(&&x); = help: to override `-D warnings` add `#[allow(clippy::size_of_ref)]` error: argument to `std::mem::size_of_val()` is a reference to a reference - --> tests/ui/size_of_ref.rs:15:5 + --> tests/ui/size_of_ref.rs:16:5 | LL | size_of_val(&y); | ^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | size_of_val(&y); = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type error: argument to `std::mem::size_of_val()` is a reference to a reference - --> tests/ui/size_of_ref.rs:27:9 + --> tests/ui/size_of_ref.rs:29:9 | LL | std::mem::size_of_val(&self) + (std::mem::size_of::() * self.data.capacity()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/skip_while_next.rs b/tests/ui/skip_while_next.rs index 8e4cd82cec30..96f4604ad42d 100644 --- a/tests/ui/skip_while_next.rs +++ b/tests/ui/skip_while_next.rs @@ -12,9 +12,11 @@ fn skip_while_next() { // Single-line case. let _ = v.iter().skip_while(|&x| *x < 0).next(); + //~^ skip_while_next // Multi-line case. let _ = v.iter().skip_while(|&x| { + //~^ skip_while_next *x < 0 } ).next(); diff --git a/tests/ui/skip_while_next.stderr b/tests/ui/skip_while_next.stderr index 2c1b9eeba3b6..5db8b4bcb522 100644 --- a/tests/ui/skip_while_next.stderr +++ b/tests/ui/skip_while_next.stderr @@ -9,10 +9,11 @@ LL | let _ = v.iter().skip_while(|&x| *x < 0).next(); = help: to override `-D warnings` add `#[allow(clippy::skip_while_next)]` error: called `skip_while(

).next()` on an `Iterator` - --> tests/ui/skip_while_next.rs:17:13 + --> tests/ui/skip_while_next.rs:18:13 | LL | let _ = v.iter().skip_while(|&x| { | _____________^ +LL | | LL | | *x < 0 LL | | } LL | | ).next(); diff --git a/tests/ui/sliced_string_as_bytes.fixed b/tests/ui/sliced_string_as_bytes.fixed index 469ad27a99b9..16c0daff78fd 100644 --- a/tests/ui/sliced_string_as_bytes.fixed +++ b/tests/ui/sliced_string_as_bytes.fixed @@ -26,8 +26,11 @@ fn main() { let string: String = "dolor sit amet".to_owned(); let bytes = &s.as_bytes()[1..5]; + //~^ sliced_string_as_bytes let bytes = &string.as_bytes()[1..]; + //~^ sliced_string_as_bytes let bytes = &"consectetur adipiscing".as_bytes()[..=5]; + //~^ sliced_string_as_bytes let f = Foo; let bytes = f[0..4].as_bytes(); diff --git a/tests/ui/sliced_string_as_bytes.rs b/tests/ui/sliced_string_as_bytes.rs index 4a4605e5a1ae..67985ae5b984 100644 --- a/tests/ui/sliced_string_as_bytes.rs +++ b/tests/ui/sliced_string_as_bytes.rs @@ -26,8 +26,11 @@ fn main() { let string: String = "dolor sit amet".to_owned(); let bytes = s[1..5].as_bytes(); + //~^ sliced_string_as_bytes let bytes = string[1..].as_bytes(); + //~^ sliced_string_as_bytes let bytes = "consectetur adipiscing"[..=5].as_bytes(); + //~^ sliced_string_as_bytes let f = Foo; let bytes = f[0..4].as_bytes(); diff --git a/tests/ui/sliced_string_as_bytes.stderr b/tests/ui/sliced_string_as_bytes.stderr index 1342f4c01a48..ae7f02781f4b 100644 --- a/tests/ui/sliced_string_as_bytes.stderr +++ b/tests/ui/sliced_string_as_bytes.stderr @@ -8,13 +8,13 @@ LL | let bytes = s[1..5].as_bytes(); = help: to override `-D warnings` add `#[allow(clippy::sliced_string_as_bytes)]` error: calling `as_bytes` after slicing a string - --> tests/ui/sliced_string_as_bytes.rs:29:17 + --> tests/ui/sliced_string_as_bytes.rs:30:17 | LL | let bytes = string[1..].as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&string.as_bytes()[1..]` error: calling `as_bytes` after slicing a string - --> tests/ui/sliced_string_as_bytes.rs:30:17 + --> tests/ui/sliced_string_as_bytes.rs:32:17 | LL | let bytes = "consectetur adipiscing"[..=5].as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&"consectetur adipiscing".as_bytes()[..=5]` diff --git a/tests/ui/slow_vector_initialization.rs b/tests/ui/slow_vector_initialization.rs index 4b30fad409e3..6a09d1f36a66 100644 --- a/tests/ui/slow_vector_initialization.rs +++ b/tests/ui/slow_vector_initialization.rs @@ -12,13 +12,15 @@ fn extend_vector() { // Extend with constant expression let len = 300; let mut vec1 = Vec::with_capacity(len); - //~^ ERROR: slow zero-filling initialization - //~| NOTE: `-D clippy::slow-vector-initialization` implied by `-D warnings` + //~^ slow_vector_initialization + + vec1.extend(repeat(0).take(len)); // Extend with len expression let mut vec2 = Vec::with_capacity(len - 10); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec2.extend(repeat(0).take(len - 10)); // Extend with mismatching expression should not be warned @@ -26,7 +28,8 @@ fn extend_vector() { vec3.extend(repeat(0).take(2)); let mut vec4 = Vec::with_capacity(len); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec4.extend(repeat(0).take(vec4.capacity())); } @@ -37,11 +40,13 @@ fn mixed_extend_resize_vector() { // Slow initialization let mut resized_vec = Vec::with_capacity(30); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + resized_vec.resize(30, 0); let mut extend_vec = Vec::with_capacity(30); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + extend_vec.extend(repeat(0).take(30)); } @@ -49,7 +54,8 @@ fn resize_vector() { // Resize with constant expression let len = 300; let mut vec1 = Vec::with_capacity(len); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec1.resize(len, 0); // Resize mismatch len @@ -58,16 +64,19 @@ fn resize_vector() { // Resize with len expression let mut vec3 = Vec::with_capacity(len - 10); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec3.resize(len - 10, 0); let mut vec4 = Vec::with_capacity(len); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec4.resize(vec4.capacity(), 0); // Reinitialization should be warned vec1 = Vec::with_capacity(10); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec1.resize(10, 0); } @@ -75,21 +84,25 @@ fn from_empty_vec() { // Resize with constant expression let len = 300; let mut vec1 = Vec::new(); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec1.resize(len, 0); // Resize with len expression let mut vec3 = Vec::new(); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec3.resize(len - 10, 0); // Reinitialization should be warned vec1 = Vec::new(); - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec1.resize(10, 0); vec1 = vec![]; - //~^ ERROR: slow zero-filling initialization + //~^ slow_vector_initialization + vec1.resize(10, 0); macro_rules! x { diff --git a/tests/ui/slow_vector_initialization.stderr b/tests/ui/slow_vector_initialization.stderr index 4a25cafcddf2..67a0b928618a 100644 --- a/tests/ui/slow_vector_initialization.stderr +++ b/tests/ui/slow_vector_initialization.stderr @@ -11,110 +11,110 @@ LL | | vec1.extend(repeat(0).take(len)); = help: to override `-D warnings` add `#[allow(clippy::slow_vector_initialization)]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:20:20 + --> tests/ui/slow_vector_initialization.rs:21:20 | LL | let mut vec2 = Vec::with_capacity(len - 10); | ____________________^ -LL | | +... | LL | | vec2.extend(repeat(0).take(len - 10)); | |_________________________________________^ help: consider replacing this with: `vec![0; len - 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:28:20 + --> tests/ui/slow_vector_initialization.rs:30:20 | LL | let mut vec4 = Vec::with_capacity(len); | ____________________^ -LL | | +... | LL | | vec4.extend(repeat(0).take(vec4.capacity())); | |________________________________________________^ help: consider replacing this with: `vec![0; len]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:39:27 + --> tests/ui/slow_vector_initialization.rs:42:27 | LL | let mut resized_vec = Vec::with_capacity(30); | ___________________________^ -LL | | +... | LL | | resized_vec.resize(30, 0); | |_____________________________^ help: consider replacing this with: `vec![0; 30]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:43:26 + --> tests/ui/slow_vector_initialization.rs:47:26 | LL | let mut extend_vec = Vec::with_capacity(30); | __________________________^ -LL | | +... | LL | | extend_vec.extend(repeat(0).take(30)); | |_________________________________________^ help: consider replacing this with: `vec![0; 30]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:51:20 + --> tests/ui/slow_vector_initialization.rs:56:20 | LL | let mut vec1 = Vec::with_capacity(len); | ____________________^ -LL | | +... | LL | | vec1.resize(len, 0); | |_______________________^ help: consider replacing this with: `vec![0; len]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:60:20 + --> tests/ui/slow_vector_initialization.rs:66:20 | LL | let mut vec3 = Vec::with_capacity(len - 10); | ____________________^ -LL | | +... | LL | | vec3.resize(len - 10, 0); | |____________________________^ help: consider replacing this with: `vec![0; len - 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:64:20 + --> tests/ui/slow_vector_initialization.rs:71:20 | LL | let mut vec4 = Vec::with_capacity(len); | ____________________^ -LL | | +... | LL | | vec4.resize(vec4.capacity(), 0); | |___________________________________^ help: consider replacing this with: `vec![0; len]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:69:12 + --> tests/ui/slow_vector_initialization.rs:77:12 | LL | vec1 = Vec::with_capacity(10); | ____________^ -LL | | +... | LL | | vec1.resize(10, 0); | |______________________^ help: consider replacing this with: `vec![0; 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:77:20 + --> tests/ui/slow_vector_initialization.rs:86:20 | LL | let mut vec1 = Vec::new(); | ____________________^ -LL | | +... | LL | | vec1.resize(len, 0); | |_______________________^ help: consider replacing this with: `vec![0; len]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:82:20 + --> tests/ui/slow_vector_initialization.rs:92:20 | LL | let mut vec3 = Vec::new(); | ____________________^ -LL | | +... | LL | | vec3.resize(len - 10, 0); | |____________________________^ help: consider replacing this with: `vec![0; len - 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:87:12 + --> tests/ui/slow_vector_initialization.rs:98:12 | LL | vec1 = Vec::new(); | ____________^ -LL | | +... | LL | | vec1.resize(10, 0); | |______________________^ help: consider replacing this with: `vec![0; 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:91:12 + --> tests/ui/slow_vector_initialization.rs:103:12 | LL | vec1 = vec![]; | ____________^ -LL | | +... | LL | | vec1.resize(10, 0); | |______________________^ help: consider replacing this with: `vec![0; 10]` diff --git a/tests/ui/stable_sort_primitive.fixed b/tests/ui/stable_sort_primitive.fixed index 97f3a92238d2..b4870ebad2b3 100644 --- a/tests/ui/stable_sort_primitive.fixed +++ b/tests/ui/stable_sort_primitive.fixed @@ -5,18 +5,25 @@ fn main() { // positive examples let mut vec = vec![1, 3, 2]; vec.sort_unstable(); + //~^ stable_sort_primitive let mut vec = vec![false, false, true]; vec.sort_unstable(); + //~^ stable_sort_primitive let mut vec = vec!['a', 'A', 'c']; vec.sort_unstable(); + //~^ stable_sort_primitive let mut vec = vec!["ab", "cd", "ab", "bc"]; vec.sort_unstable(); + //~^ stable_sort_primitive let mut vec = vec![(2, 1), (1, 2), (2, 5)]; vec.sort_unstable(); + //~^ stable_sort_primitive let mut vec = vec![[2, 1], [1, 2], [2, 5]]; vec.sort_unstable(); + //~^ stable_sort_primitive let mut arr = [1, 3, 2]; arr.sort_unstable(); + //~^ stable_sort_primitive // Negative examples: behavior changes if made unstable let mut vec = vec![1, 3, 2]; vec.sort_by_key(|i| i / 2); diff --git a/tests/ui/stable_sort_primitive.rs b/tests/ui/stable_sort_primitive.rs index 26e3d8e74f71..b3fe64efd620 100644 --- a/tests/ui/stable_sort_primitive.rs +++ b/tests/ui/stable_sort_primitive.rs @@ -5,18 +5,25 @@ fn main() { // positive examples let mut vec = vec![1, 3, 2]; vec.sort(); + //~^ stable_sort_primitive let mut vec = vec![false, false, true]; vec.sort(); + //~^ stable_sort_primitive let mut vec = vec!['a', 'A', 'c']; vec.sort(); + //~^ stable_sort_primitive let mut vec = vec!["ab", "cd", "ab", "bc"]; vec.sort(); + //~^ stable_sort_primitive let mut vec = vec![(2, 1), (1, 2), (2, 5)]; vec.sort(); + //~^ stable_sort_primitive let mut vec = vec![[2, 1], [1, 2], [2, 5]]; vec.sort(); + //~^ stable_sort_primitive let mut arr = [1, 3, 2]; arr.sort(); + //~^ stable_sort_primitive // Negative examples: behavior changes if made unstable let mut vec = vec![1, 3, 2]; vec.sort_by_key(|i| i / 2); diff --git a/tests/ui/stable_sort_primitive.stderr b/tests/ui/stable_sort_primitive.stderr index 66bd4c79bb28..00b45030139a 100644 --- a/tests/ui/stable_sort_primitive.stderr +++ b/tests/ui/stable_sort_primitive.stderr @@ -9,7 +9,7 @@ LL | vec.sort(); = help: to override `-D warnings` add `#[allow(clippy::stable_sort_primitive)]` error: used `sort` on primitive type `bool` - --> tests/ui/stable_sort_primitive.rs:9:5 + --> tests/ui/stable_sort_primitive.rs:10:5 | LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` @@ -17,14 +17,6 @@ LL | vec.sort(); = note: an unstable sort typically performs faster without any observable difference for this data type error: used `sort` on primitive type `char` - --> tests/ui/stable_sort_primitive.rs:11:5 - | -LL | vec.sort(); - | ^^^^^^^^^^ help: try: `vec.sort_unstable()` - | - = note: an unstable sort typically performs faster without any observable difference for this data type - -error: used `sort` on primitive type `str` --> tests/ui/stable_sort_primitive.rs:13:5 | LL | vec.sort(); @@ -32,8 +24,16 @@ LL | vec.sort(); | = note: an unstable sort typically performs faster without any observable difference for this data type +error: used `sort` on primitive type `str` + --> tests/ui/stable_sort_primitive.rs:16:5 + | +LL | vec.sort(); + | ^^^^^^^^^^ help: try: `vec.sort_unstable()` + | + = note: an unstable sort typically performs faster without any observable difference for this data type + error: used `sort` on primitive type `tuple` - --> tests/ui/stable_sort_primitive.rs:15:5 + --> tests/ui/stable_sort_primitive.rs:19:5 | LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` @@ -41,7 +41,7 @@ LL | vec.sort(); = note: an unstable sort typically performs faster without any observable difference for this data type error: used `sort` on primitive type `array` - --> tests/ui/stable_sort_primitive.rs:17:5 + --> tests/ui/stable_sort_primitive.rs:22:5 | LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` @@ -49,7 +49,7 @@ LL | vec.sort(); = note: an unstable sort typically performs faster without any observable difference for this data type error: used `sort` on primitive type `i32` - --> tests/ui/stable_sort_primitive.rs:19:5 + --> tests/ui/stable_sort_primitive.rs:25:5 | LL | arr.sort(); | ^^^^^^^^^^ help: try: `arr.sort_unstable()` diff --git a/tests/ui/starts_ends_with.fixed b/tests/ui/starts_ends_with.fixed index 252b6e5a98c0..3e1ea00a341e 100644 --- a/tests/ui/starts_ends_with.fixed +++ b/tests/ui/starts_ends_with.fixed @@ -5,36 +5,46 @@ fn main() {} #[allow(clippy::unnecessary_operation)] fn starts_with() { "".starts_with(' '); + //~^ chars_next_cmp !"".starts_with(' '); + //~^ chars_next_cmp // Ensure that suggestion is escaped correctly "".starts_with('\n'); + //~^ chars_next_cmp !"".starts_with('\n'); + //~^ chars_next_cmp } fn chars_cmp_with_unwrap() { let s = String::from("foo"); if s.starts_with('f') { + //~^ chars_next_cmp // s.starts_with('f') // Nothing here } if s.ends_with('o') { + //~^ chars_last_cmp // s.ends_with('o') // Nothing here } if s.ends_with('o') { + //~^ chars_last_cmp // s.ends_with('o') // Nothing here } if !s.starts_with('f') { + //~^ chars_next_cmp // !s.starts_with('f') // Nothing here } if !s.ends_with('o') { + //~^ chars_last_cmp // !s.ends_with('o') // Nothing here } if !s.ends_with('\n') { + //~^ chars_last_cmp // !s.ends_with('o') // Nothing here } @@ -43,11 +53,17 @@ fn chars_cmp_with_unwrap() { #[allow(clippy::unnecessary_operation)] fn ends_with() { "".ends_with(' '); + //~^ chars_last_cmp !"".ends_with(' '); + //~^ chars_last_cmp "".ends_with(' '); + //~^ chars_last_cmp !"".ends_with(' '); + //~^ chars_last_cmp // Ensure that suggestion is escaped correctly "".ends_with('\n'); + //~^ chars_last_cmp !"".ends_with('\n'); + //~^ chars_last_cmp } diff --git a/tests/ui/starts_ends_with.rs b/tests/ui/starts_ends_with.rs index 6c5655f31782..ef7143a455f9 100644 --- a/tests/ui/starts_ends_with.rs +++ b/tests/ui/starts_ends_with.rs @@ -5,36 +5,46 @@ fn main() {} #[allow(clippy::unnecessary_operation)] fn starts_with() { "".chars().next() == Some(' '); + //~^ chars_next_cmp Some(' ') != "".chars().next(); + //~^ chars_next_cmp // Ensure that suggestion is escaped correctly "".chars().next() == Some('\n'); + //~^ chars_next_cmp Some('\n') != "".chars().next(); + //~^ chars_next_cmp } fn chars_cmp_with_unwrap() { let s = String::from("foo"); if s.chars().next().unwrap() == 'f' { + //~^ chars_next_cmp // s.starts_with('f') // Nothing here } if s.chars().next_back().unwrap() == 'o' { + //~^ chars_last_cmp // s.ends_with('o') // Nothing here } if s.chars().last().unwrap() == 'o' { + //~^ chars_last_cmp // s.ends_with('o') // Nothing here } if s.chars().next().unwrap() != 'f' { + //~^ chars_next_cmp // !s.starts_with('f') // Nothing here } if s.chars().next_back().unwrap() != 'o' { + //~^ chars_last_cmp // !s.ends_with('o') // Nothing here } if s.chars().last().unwrap() != '\n' { + //~^ chars_last_cmp // !s.ends_with('o') // Nothing here } @@ -43,11 +53,17 @@ fn chars_cmp_with_unwrap() { #[allow(clippy::unnecessary_operation)] fn ends_with() { "".chars().last() == Some(' '); + //~^ chars_last_cmp Some(' ') != "".chars().last(); + //~^ chars_last_cmp "".chars().next_back() == Some(' '); + //~^ chars_last_cmp Some(' ') != "".chars().next_back(); + //~^ chars_last_cmp // Ensure that suggestion is escaped correctly "".chars().last() == Some('\n'); + //~^ chars_last_cmp Some('\n') != "".chars().last(); + //~^ chars_last_cmp } diff --git a/tests/ui/starts_ends_with.stderr b/tests/ui/starts_ends_with.stderr index cee31f1e4cdd..bcb38f2beb7b 100644 --- a/tests/ui/starts_ends_with.stderr +++ b/tests/ui/starts_ends_with.stderr @@ -8,31 +8,31 @@ LL | "".chars().next() == Some(' '); = help: to override `-D warnings` add `#[allow(clippy::chars_next_cmp)]` error: you should use the `starts_with` method - --> tests/ui/starts_ends_with.rs:8:5 + --> tests/ui/starts_ends_with.rs:9:5 | LL | Some(' ') != "".chars().next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".starts_with(' ')` error: you should use the `starts_with` method - --> tests/ui/starts_ends_with.rs:11:5 + --> tests/ui/starts_ends_with.rs:13:5 | LL | "".chars().next() == Some('\n'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".starts_with('\n')` error: you should use the `starts_with` method - --> tests/ui/starts_ends_with.rs:12:5 + --> tests/ui/starts_ends_with.rs:15:5 | LL | Some('\n') != "".chars().next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".starts_with('\n')` error: you should use the `starts_with` method - --> tests/ui/starts_ends_with.rs:17:8 + --> tests/ui/starts_ends_with.rs:21:8 | LL | if s.chars().next().unwrap() == 'f' { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `s.starts_with('f')` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:21:8 + --> tests/ui/starts_ends_with.rs:26:8 | LL | if s.chars().next_back().unwrap() == 'o' { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `s.ends_with('o')` @@ -41,61 +41,61 @@ LL | if s.chars().next_back().unwrap() == 'o' { = help: to override `-D warnings` add `#[allow(clippy::chars_last_cmp)]` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:25:8 + --> tests/ui/starts_ends_with.rs:31:8 | LL | if s.chars().last().unwrap() == 'o' { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `s.ends_with('o')` error: you should use the `starts_with` method - --> tests/ui/starts_ends_with.rs:29:8 + --> tests/ui/starts_ends_with.rs:36:8 | LL | if s.chars().next().unwrap() != 'f' { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.starts_with('f')` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:33:8 + --> tests/ui/starts_ends_with.rs:41:8 | LL | if s.chars().next_back().unwrap() != 'o' { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.ends_with('o')` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:37:8 + --> tests/ui/starts_ends_with.rs:46:8 | LL | if s.chars().last().unwrap() != '\n' { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.ends_with('\n')` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:45:5 + --> tests/ui/starts_ends_with.rs:55:5 | LL | "".chars().last() == Some(' '); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".ends_with(' ')` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:46:5 + --> tests/ui/starts_ends_with.rs:57:5 | LL | Some(' ') != "".chars().last(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".ends_with(' ')` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:47:5 + --> tests/ui/starts_ends_with.rs:59:5 | LL | "".chars().next_back() == Some(' '); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".ends_with(' ')` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:48:5 + --> tests/ui/starts_ends_with.rs:61:5 | LL | Some(' ') != "".chars().next_back(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".ends_with(' ')` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:51:5 + --> tests/ui/starts_ends_with.rs:65:5 | LL | "".chars().last() == Some('\n'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".ends_with('\n')` error: you should use the `ends_with` method - --> tests/ui/starts_ends_with.rs:52:5 + --> tests/ui/starts_ends_with.rs:67:5 | LL | Some('\n') != "".chars().last(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".ends_with('\n')` diff --git a/tests/ui/std_instead_of_core.fixed b/tests/ui/std_instead_of_core.fixed index ec158ee02de8..ab2e801eee25 100644 --- a/tests/ui/std_instead_of_core.fixed +++ b/tests/ui/std_instead_of_core.fixed @@ -89,3 +89,4 @@ fn msrv_1_76(_: std::net::IpAddr) {} #[clippy::msrv = "1.77"] fn msrv_1_77(_: core::net::IpAddr) {} +//~^ std_instead_of_core diff --git a/tests/ui/std_instead_of_core.rs b/tests/ui/std_instead_of_core.rs index 9c3c1658d8fe..f760b3561aed 100644 --- a/tests/ui/std_instead_of_core.rs +++ b/tests/ui/std_instead_of_core.rs @@ -89,3 +89,4 @@ fn msrv_1_76(_: std::net::IpAddr) {} #[clippy::msrv = "1.77"] fn msrv_1_77(_: std::net::IpAddr) {} +//~^ std_instead_of_core diff --git a/tests/ui/str_split.fixed b/tests/ui/str_split.fixed index 57a3c315a877..6aca5051c570 100644 --- a/tests/ui/str_split.fixed +++ b/tests/ui/str_split.fixed @@ -58,25 +58,35 @@ fn main() { // Splitting a `str` variable at "\n" or "\r\n" after trimming should warn let _ = s1.lines(); + //~^ str_split_at_newline #[allow(clippy::single_char_pattern)] let _ = s1.lines(); + //~^ str_split_at_newline let _ = s1.lines(); + //~^ str_split_at_newline // Splitting a `String` variable at "\n" or "\r\n" after trimming should warn let _ = s2.lines(); + //~^ str_split_at_newline #[allow(clippy::single_char_pattern)] let _ = s2.lines(); + //~^ str_split_at_newline let _ = s2.lines(); + //~^ str_split_at_newline // Splitting a variable that derefs into `str` at "\n" or "\r\n" after trimming should warn. let s3 = DerefsIntoStr { s: s1 }; let _ = s3.lines(); + //~^ str_split_at_newline #[allow(clippy::single_char_pattern)] let _ = s3.lines(); + //~^ str_split_at_newline let _ = s3.lines(); + //~^ str_split_at_newline // If the `&str` is generated by a macro then the macro should not be expanded in the suggested fix. let _ = make_str!(s1).lines(); + //~^ str_split_at_newline // CASES THAT SHOULD NOT EMIT A LINT diff --git a/tests/ui/str_split.rs b/tests/ui/str_split.rs index fcff036f2649..11e9862da14b 100644 --- a/tests/ui/str_split.rs +++ b/tests/ui/str_split.rs @@ -58,25 +58,35 @@ fn main() { // Splitting a `str` variable at "\n" or "\r\n" after trimming should warn let _ = s1.trim().split('\n'); + //~^ str_split_at_newline #[allow(clippy::single_char_pattern)] let _ = s1.trim().split("\n"); + //~^ str_split_at_newline let _ = s1.trim().split("\r\n"); + //~^ str_split_at_newline // Splitting a `String` variable at "\n" or "\r\n" after trimming should warn let _ = s2.trim().split('\n'); + //~^ str_split_at_newline #[allow(clippy::single_char_pattern)] let _ = s2.trim().split("\n"); + //~^ str_split_at_newline let _ = s2.trim().split("\r\n"); + //~^ str_split_at_newline // Splitting a variable that derefs into `str` at "\n" or "\r\n" after trimming should warn. let s3 = DerefsIntoStr { s: s1 }; let _ = s3.trim().split('\n'); + //~^ str_split_at_newline #[allow(clippy::single_char_pattern)] let _ = s3.trim().split("\n"); + //~^ str_split_at_newline let _ = s3.trim().split("\r\n"); + //~^ str_split_at_newline // If the `&str` is generated by a macro then the macro should not be expanded in the suggested fix. let _ = make_str!(s1).trim().split('\n'); + //~^ str_split_at_newline // CASES THAT SHOULD NOT EMIT A LINT diff --git a/tests/ui/str_split.stderr b/tests/ui/str_split.stderr index 7b560468f126..c4eca81004c5 100644 --- a/tests/ui/str_split.stderr +++ b/tests/ui/str_split.stderr @@ -8,55 +8,55 @@ LL | let _ = s1.trim().split('\n'); = help: to override `-D warnings` add `#[allow(clippy::str_split_at_newline)]` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:62:13 + --> tests/ui/str_split.rs:63:13 | LL | let _ = s1.trim().split("\n"); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:63:13 + --> tests/ui/str_split.rs:65:13 | LL | let _ = s1.trim().split("\r\n"); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:66:13 + --> tests/ui/str_split.rs:69:13 | LL | let _ = s2.trim().split('\n'); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:68:13 + --> tests/ui/str_split.rs:72:13 | LL | let _ = s2.trim().split("\n"); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:69:13 + --> tests/ui/str_split.rs:74:13 | LL | let _ = s2.trim().split("\r\n"); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:73:13 + --> tests/ui/str_split.rs:79:13 | LL | let _ = s3.trim().split('\n'); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:75:13 + --> tests/ui/str_split.rs:82:13 | LL | let _ = s3.trim().split("\n"); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:76:13 + --> tests/ui/str_split.rs:84:13 | LL | let _ = s3.trim().split("\r\n"); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:79:13 + --> tests/ui/str_split.rs:88:13 | LL | let _ = make_str!(s1).trim().split('\n'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `make_str!(s1).lines()` diff --git a/tests/ui/str_to_string.fixed b/tests/ui/str_to_string.fixed index 52e40b45a8bd..4977e9c944d1 100644 --- a/tests/ui/str_to_string.fixed +++ b/tests/ui/str_to_string.fixed @@ -2,8 +2,10 @@ fn main() { let hello = "hello world".to_owned(); - //~^ ERROR: `to_string()` called on a `&str` + //~^ str_to_string + let msg = &hello[..]; msg.to_owned(); - //~^ ERROR: `to_string()` called on a `&str` + //~^ str_to_string + } diff --git a/tests/ui/str_to_string.rs b/tests/ui/str_to_string.rs index f93b289c29ab..f710761471b6 100644 --- a/tests/ui/str_to_string.rs +++ b/tests/ui/str_to_string.rs @@ -2,8 +2,10 @@ fn main() { let hello = "hello world".to_string(); - //~^ ERROR: `to_string()` called on a `&str` + //~^ str_to_string + let msg = &hello[..]; msg.to_string(); - //~^ ERROR: `to_string()` called on a `&str` + //~^ str_to_string + } diff --git a/tests/ui/str_to_string.stderr b/tests/ui/str_to_string.stderr index a761d96cd6b1..cb7b6b48843a 100644 --- a/tests/ui/str_to_string.stderr +++ b/tests/ui/str_to_string.stderr @@ -8,7 +8,7 @@ LL | let hello = "hello world".to_string(); = help: to override `-D warnings` add `#[allow(clippy::str_to_string)]` error: `to_string()` called on a `&str` - --> tests/ui/str_to_string.rs:7:5 + --> tests/ui/str_to_string.rs:8:5 | LL | msg.to_string(); | ^^^^^^^^^^^^^^^ help: try: `msg.to_owned()` diff --git a/tests/ui/string_add.rs b/tests/ui/string_add.rs index 61c812f16c8c..5c7d13ebcd58 100644 --- a/tests/ui/string_add.rs +++ b/tests/ui/string_add.rs @@ -11,10 +11,12 @@ fn main() { for _ in 1..3 { x = x + "."; + //~^ string_add } let y = String::new(); let z = y + "..."; + //~^ string_add assert_eq!(&x, &z); diff --git a/tests/ui/string_add.stderr b/tests/ui/string_add.stderr index 74ff7372e21a..084a439410f8 100644 --- a/tests/ui/string_add.stderr +++ b/tests/ui/string_add.stderr @@ -8,7 +8,7 @@ LL | x = x + "."; = help: to override `-D warnings` add `#[allow(clippy::string_add)]` error: you added something to a string. Consider using `String::push_str()` instead - --> tests/ui/string_add.rs:17:13 + --> tests/ui/string_add.rs:18:13 | LL | let z = y + "..."; | ^^^^^^^^^ diff --git a/tests/ui/string_add_assign.fixed b/tests/ui/string_add_assign.fixed index 31d84831d09a..a86a304684f2 100644 --- a/tests/ui/string_add_assign.fixed +++ b/tests/ui/string_add_assign.fixed @@ -6,6 +6,8 @@ fn main() { for _ in 1..3 { x += "."; + //~^ string_add_assign + //~| assign_op_pattern } let y = String::new(); @@ -15,5 +17,6 @@ fn main() { let mut x = 1; x += 1; + //~^ assign_op_pattern assert_eq!(2, x); } diff --git a/tests/ui/string_add_assign.rs b/tests/ui/string_add_assign.rs index cdea91573cc7..042e33cf8413 100644 --- a/tests/ui/string_add_assign.rs +++ b/tests/ui/string_add_assign.rs @@ -6,6 +6,8 @@ fn main() { for _ in 1..3 { x = x + "."; + //~^ string_add_assign + //~| assign_op_pattern } let y = String::new(); @@ -15,5 +17,6 @@ fn main() { let mut x = 1; x = x + 1; + //~^ assign_op_pattern assert_eq!(2, x); } diff --git a/tests/ui/string_add_assign.stderr b/tests/ui/string_add_assign.stderr index 50f970084e6b..198772747927 100644 --- a/tests/ui/string_add_assign.stderr +++ b/tests/ui/string_add_assign.stderr @@ -17,7 +17,7 @@ LL | x = x + "."; = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]` error: manual implementation of an assign operation - --> tests/ui/string_add_assign.rs:17:5 + --> tests/ui/string_add_assign.rs:19:5 | LL | x = x + 1; | ^^^^^^^^^ help: replace it with: `x += 1` diff --git a/tests/ui/string_extend.fixed b/tests/ui/string_extend.fixed index 142cb6a34980..17d3d927830f 100644 --- a/tests/ui/string_extend.fixed +++ b/tests/ui/string_extend.fixed @@ -14,12 +14,15 @@ fn main() { s.push_str(abc); s.push_str(abc); + //~^ string_extend_chars s.push_str("abc"); s.push_str("abc"); + //~^ string_extend_chars s.push_str(&def); s.push_str(&def); + //~^ string_extend_chars s.extend(abc.chars().skip(1)); s.extend("abc".chars().skip(1)); @@ -30,4 +33,5 @@ fn main() { // issue #9735 s.push_str(&abc[0..2]); + //~^ string_extend_chars } diff --git a/tests/ui/string_extend.rs b/tests/ui/string_extend.rs index 41c0d29fae9c..e2d54f479439 100644 --- a/tests/ui/string_extend.rs +++ b/tests/ui/string_extend.rs @@ -14,12 +14,15 @@ fn main() { s.push_str(abc); s.extend(abc.chars()); + //~^ string_extend_chars s.push_str("abc"); s.extend("abc".chars()); + //~^ string_extend_chars s.push_str(&def); s.extend(def.chars()); + //~^ string_extend_chars s.extend(abc.chars().skip(1)); s.extend("abc".chars().skip(1)); @@ -30,4 +33,5 @@ fn main() { // issue #9735 s.extend(abc[0..2].chars()); + //~^ string_extend_chars } diff --git a/tests/ui/string_extend.stderr b/tests/ui/string_extend.stderr index fadda786aacb..52aad5a02f6d 100644 --- a/tests/ui/string_extend.stderr +++ b/tests/ui/string_extend.stderr @@ -8,19 +8,19 @@ LL | s.extend(abc.chars()); = help: to override `-D warnings` add `#[allow(clippy::string_extend_chars)]` error: calling `.extend(_.chars())` - --> tests/ui/string_extend.rs:19:5 + --> tests/ui/string_extend.rs:20:5 | LL | s.extend("abc".chars()); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str("abc")` error: calling `.extend(_.chars())` - --> tests/ui/string_extend.rs:22:5 + --> tests/ui/string_extend.rs:24:5 | LL | s.extend(def.chars()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(&def)` error: calling `.extend(_.chars())` - --> tests/ui/string_extend.rs:32:5 + --> tests/ui/string_extend.rs:35:5 | LL | s.extend(abc[0..2].chars()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(&abc[0..2])` diff --git a/tests/ui/string_from_utf8_as_bytes.fixed b/tests/ui/string_from_utf8_as_bytes.fixed index 6aa5a95c6f40..193217114d88 100644 --- a/tests/ui/string_from_utf8_as_bytes.fixed +++ b/tests/ui/string_from_utf8_as_bytes.fixed @@ -2,4 +2,5 @@ fn main() { let _ = Some(&"Hello World!"[6..11]); + //~^ string_from_utf8_as_bytes } diff --git a/tests/ui/string_from_utf8_as_bytes.rs b/tests/ui/string_from_utf8_as_bytes.rs index c8717f7950bd..49beb19ee40f 100644 --- a/tests/ui/string_from_utf8_as_bytes.rs +++ b/tests/ui/string_from_utf8_as_bytes.rs @@ -2,4 +2,5 @@ fn main() { let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]); + //~^ string_from_utf8_as_bytes } diff --git a/tests/ui/string_lit_as_bytes.fixed b/tests/ui/string_lit_as_bytes.fixed index 225d4e90c4e2..2a86dffbc762 100644 --- a/tests/ui/string_lit_as_bytes.fixed +++ b/tests/ui/string_lit_as_bytes.fixed @@ -9,16 +9,21 @@ extern crate macro_rules; macro_rules! b { ($b:literal) => { const B: &[u8] = b"warning"; + //~^ string_lit_as_bytes }; } fn str_lit_as_bytes() { let bs = b"hello there"; + //~^ string_lit_as_bytes let bs = br###"raw string with 3# plus " ""###; + //~^ string_lit_as_bytes let bs = b"lit to string".to_vec(); + //~^ string_lit_as_bytes let bs = b"lit to owned".to_vec(); + //~^ string_lit_as_bytes b!("warning"); @@ -36,8 +41,10 @@ fn str_lit_as_bytes() { let current_version = env!("CARGO_PKG_VERSION").as_bytes(); let includestr = include_bytes!("string_lit_as_bytes.rs"); + //~^ string_lit_as_bytes let _ = b"string with newline\t\n"; + //~^ string_lit_as_bytes let _ = match "x".as_bytes() { b"xx" => 0, diff --git a/tests/ui/string_lit_as_bytes.rs b/tests/ui/string_lit_as_bytes.rs index 3d116214ca42..785d8f1e0f6b 100644 --- a/tests/ui/string_lit_as_bytes.rs +++ b/tests/ui/string_lit_as_bytes.rs @@ -9,16 +9,21 @@ extern crate macro_rules; macro_rules! b { ($b:literal) => { const B: &[u8] = $b.as_bytes(); + //~^ string_lit_as_bytes }; } fn str_lit_as_bytes() { let bs = "hello there".as_bytes(); + //~^ string_lit_as_bytes let bs = r###"raw string with 3# plus " ""###.as_bytes(); + //~^ string_lit_as_bytes let bs = "lit to string".to_string().into_bytes(); + //~^ string_lit_as_bytes let bs = "lit to owned".to_owned().into_bytes(); + //~^ string_lit_as_bytes b!("warning"); @@ -36,8 +41,10 @@ fn str_lit_as_bytes() { let current_version = env!("CARGO_PKG_VERSION").as_bytes(); let includestr = include_str!("string_lit_as_bytes.rs").as_bytes(); + //~^ string_lit_as_bytes let _ = "string with newline\t\n".as_bytes(); + //~^ string_lit_as_bytes let _ = match "x".as_bytes() { b"xx" => 0, diff --git a/tests/ui/string_lit_as_bytes.stderr b/tests/ui/string_lit_as_bytes.stderr index 66b3e6f9462d..9388fbdc775d 100644 --- a/tests/ui/string_lit_as_bytes.stderr +++ b/tests/ui/string_lit_as_bytes.stderr @@ -1,5 +1,5 @@ error: calling `as_bytes()` on a string literal - --> tests/ui/string_lit_as_bytes.rs:16:14 + --> tests/ui/string_lit_as_bytes.rs:17:14 | LL | let bs = "hello there".as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"hello there"` @@ -8,19 +8,19 @@ LL | let bs = "hello there".as_bytes(); = help: to override `-D warnings` add `#[allow(clippy::string_lit_as_bytes)]` error: calling `as_bytes()` on a string literal - --> tests/ui/string_lit_as_bytes.rs:18:14 + --> tests/ui/string_lit_as_bytes.rs:20:14 | LL | let bs = r###"raw string with 3# plus " ""###.as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `br###"raw string with 3# plus " ""###` error: calling `into_bytes()` on a string literal - --> tests/ui/string_lit_as_bytes.rs:20:14 + --> tests/ui/string_lit_as_bytes.rs:23:14 | LL | let bs = "lit to string".to_string().into_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to string".to_vec()` error: calling `into_bytes()` on a string literal - --> tests/ui/string_lit_as_bytes.rs:21:14 + --> tests/ui/string_lit_as_bytes.rs:25:14 | LL | let bs = "lit to owned".to_owned().into_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to owned".to_vec()` @@ -37,13 +37,13 @@ LL | b!("warning"); = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) error: calling `as_bytes()` on `include_str!(..)` - --> tests/ui/string_lit_as_bytes.rs:38:22 + --> tests/ui/string_lit_as_bytes.rs:43:22 | LL | let includestr = include_str!("string_lit_as_bytes.rs").as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("string_lit_as_bytes.rs")` error: calling `as_bytes()` on a string literal - --> tests/ui/string_lit_as_bytes.rs:40:13 + --> tests/ui/string_lit_as_bytes.rs:46:13 | LL | let _ = "string with newline\t\n".as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"string with newline\t\n"` diff --git a/tests/ui/string_lit_chars_any.fixed b/tests/ui/string_lit_chars_any.fixed index 03e20c16ee63..cf05a2c2e835 100644 --- a/tests/ui/string_lit_chars_any.fixed +++ b/tests/ui/string_lit_chars_any.fixed @@ -16,11 +16,16 @@ impl NotStringLit { fn main() { let c = 'c'; matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + //~^ string_lit_chars_any matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + //~^ string_lit_chars_any matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + //~^ string_lit_chars_any matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + //~^ string_lit_chars_any #[rustfmt::skip] matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'); + //~^ string_lit_chars_any // Do not lint NotStringLit.chars().any(|x| x == c); "\\.+*?()|[]{}^$#&-~".chars().any(|x| { diff --git a/tests/ui/string_lit_chars_any.rs b/tests/ui/string_lit_chars_any.rs index 12e6ffb6a9c4..22cfb784ed7d 100644 --- a/tests/ui/string_lit_chars_any.rs +++ b/tests/ui/string_lit_chars_any.rs @@ -16,11 +16,16 @@ impl NotStringLit { fn main() { let c = 'c'; "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == c); + //~^ string_lit_chars_any r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c); + //~^ string_lit_chars_any "\\.+*?()|[]{}^$#&-~".chars().any(|x| c == x); + //~^ string_lit_chars_any r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x); + //~^ string_lit_chars_any #[rustfmt::skip] "\\.+*?()|[]{}^$#&-~".chars().any(|x| { x == c }); + //~^ string_lit_chars_any // Do not lint NotStringLit.chars().any(|x| x == c); "\\.+*?()|[]{}^$#&-~".chars().any(|x| { diff --git a/tests/ui/string_lit_chars_any.stderr b/tests/ui/string_lit_chars_any.stderr index 4d3ca98e6237..b6bfb8d4b791 100644 --- a/tests/ui/string_lit_chars_any.stderr +++ b/tests/ui/string_lit_chars_any.stderr @@ -12,7 +12,7 @@ LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: usage of `.chars().any(...)` to check if a char matches any from a string literal - --> tests/ui/string_lit_chars_any.rs:19:5 + --> tests/ui/string_lit_chars_any.rs:20:5 | LL | r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: usage of `.chars().any(...)` to check if a char matches any from a string literal - --> tests/ui/string_lit_chars_any.rs:20:5 + --> tests/ui/string_lit_chars_any.rs:22:5 | LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| c == x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: usage of `.chars().any(...)` to check if a char matches any from a string literal - --> tests/ui/string_lit_chars_any.rs:21:5 + --> tests/ui/string_lit_chars_any.rs:24:5 | LL | r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: usage of `.chars().any(...)` to check if a char matches any from a string literal - --> tests/ui/string_lit_chars_any.rs:23:5 + --> tests/ui/string_lit_chars_any.rs:27:5 | LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| { x == c }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/string_slice.rs b/tests/ui/string_slice.rs index dc519493a4dd..9251b348af3f 100644 --- a/tests/ui/string_slice.rs +++ b/tests/ui/string_slice.rs @@ -5,15 +5,19 @@ use std::borrow::Cow; fn main() { &"Ölkanne"[1..]; - //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character - //~| NOTE: `-D clippy::string-slice` implied by `-D warnings` + //~^ string_slice + + let m = "Mötörhead"; &m[2..5]; - //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character + //~^ string_slice + let s = String::from(m); &s[0..2]; - //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character + //~^ string_slice + let a = Cow::Borrowed("foo"); &a[0..3]; - //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character + //~^ string_slice + } diff --git a/tests/ui/string_slice.stderr b/tests/ui/string_slice.stderr index bc0fcde34b82..4932152af6b6 100644 --- a/tests/ui/string_slice.stderr +++ b/tests/ui/string_slice.stderr @@ -8,19 +8,19 @@ LL | &"Ölkanne"[1..]; = help: to override `-D warnings` add `#[allow(clippy::string_slice)]` error: indexing into a string may panic if the index is within a UTF-8 character - --> tests/ui/string_slice.rs:11:6 + --> tests/ui/string_slice.rs:12:6 | LL | &m[2..5]; | ^^^^^^^ error: indexing into a string may panic if the index is within a UTF-8 character - --> tests/ui/string_slice.rs:14:6 + --> tests/ui/string_slice.rs:16:6 | LL | &s[0..2]; | ^^^^^^^ error: indexing into a string may panic if the index is within a UTF-8 character - --> tests/ui/string_slice.rs:17:6 + --> tests/ui/string_slice.rs:20:6 | LL | &a[0..3]; | ^^^^^^^ diff --git a/tests/ui/string_to_string.rs b/tests/ui/string_to_string.rs index 007685b60179..e3f5b6cf3bdc 100644 --- a/tests/ui/string_to_string.rs +++ b/tests/ui/string_to_string.rs @@ -4,5 +4,6 @@ fn main() { let mut message = String::from("Hello"); let mut v = message.to_string(); - //~^ ERROR: `to_string()` called on a `String` + //~^ string_to_string + } diff --git a/tests/ui/strlen_on_c_strings.fixed b/tests/ui/strlen_on_c_strings.fixed index 1e7d04ffb9df..31ed1cf03a2d 100644 --- a/tests/ui/strlen_on_c_strings.fixed +++ b/tests/ui/strlen_on_c_strings.fixed @@ -11,22 +11,29 @@ fn main() { // CString let cstring = CString::new("foo").expect("CString::new failed"); let _ = cstring.as_bytes().len(); + //~^ strlen_on_c_strings // CStr let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); let _ = cstr.to_bytes().len(); + //~^ strlen_on_c_strings let _ = cstr.to_bytes().len(); + //~^ strlen_on_c_strings let pcstr: *const &CStr = &cstr; let _ = unsafe { (*pcstr).to_bytes().len() }; + //~^ strlen_on_c_strings unsafe fn unsafe_identity(x: T) -> T { x } let _ = unsafe { unsafe_identity(cstr).to_bytes().len() }; + //~^ strlen_on_c_strings let _ = unsafe { unsafe_identity(cstr) }.to_bytes().len(); + //~^ strlen_on_c_strings let f: unsafe fn(_) -> _ = unsafe_identity; let _ = unsafe { f(cstr).to_bytes().len() }; + //~^ strlen_on_c_strings } diff --git a/tests/ui/strlen_on_c_strings.rs b/tests/ui/strlen_on_c_strings.rs index c3ad03591d4e..0f3798c9fd8a 100644 --- a/tests/ui/strlen_on_c_strings.rs +++ b/tests/ui/strlen_on_c_strings.rs @@ -11,22 +11,29 @@ fn main() { // CString let cstring = CString::new("foo").expect("CString::new failed"); let _ = unsafe { libc::strlen(cstring.as_ptr()) }; + //~^ strlen_on_c_strings // CStr let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); let _ = unsafe { libc::strlen(cstr.as_ptr()) }; + //~^ strlen_on_c_strings let _ = unsafe { strlen(cstr.as_ptr()) }; + //~^ strlen_on_c_strings let pcstr: *const &CStr = &cstr; let _ = unsafe { strlen((*pcstr).as_ptr()) }; + //~^ strlen_on_c_strings unsafe fn unsafe_identity(x: T) -> T { x } let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) }; + //~^ strlen_on_c_strings let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) }; + //~^ strlen_on_c_strings let f: unsafe fn(_) -> _ = unsafe_identity; let _ = unsafe { strlen(f(cstr).as_ptr()) }; + //~^ strlen_on_c_strings } diff --git a/tests/ui/strlen_on_c_strings.stderr b/tests/ui/strlen_on_c_strings.stderr index 8c2a7692659c..b8619fa2df30 100644 --- a/tests/ui/strlen_on_c_strings.stderr +++ b/tests/ui/strlen_on_c_strings.stderr @@ -8,37 +8,37 @@ LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) }; = help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:17:13 + --> tests/ui/strlen_on_c_strings.rs:18:13 | LL | let _ = unsafe { libc::strlen(cstr.as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:19:13 + --> tests/ui/strlen_on_c_strings.rs:21:13 | LL | let _ = unsafe { strlen(cstr.as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:22:22 + --> tests/ui/strlen_on_c_strings.rs:25:22 | LL | let _ = unsafe { strlen((*pcstr).as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*pcstr).to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:27:22 + --> tests/ui/strlen_on_c_strings.rs:31:22 | LL | let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe_identity(cstr).to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:28:13 + --> tests/ui/strlen_on_c_strings.rs:33:13 | LL | let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { unsafe_identity(cstr) }.to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:31:22 + --> tests/ui/strlen_on_c_strings.rs:37:22 | LL | let _ = unsafe { strlen(f(cstr).as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `f(cstr).to_bytes().len()` diff --git a/tests/ui/struct_excessive_bools.rs b/tests/ui/struct_excessive_bools.rs index 8137ce7a81c5..f509c3143a86 100644 --- a/tests/ui/struct_excessive_bools.rs +++ b/tests/ui/struct_excessive_bools.rs @@ -20,7 +20,8 @@ struct Foo { } struct BadFoo { - //~^ ERROR: more than 3 bools in a struct +//~^ struct_excessive_bools + a: bool, b: bool, c: bool, @@ -37,7 +38,8 @@ struct Bar { fn main() { struct FooFoo { - //~^ ERROR: more than 3 bools in a struct + //~^ struct_excessive_bools + a: bool, b: bool, c: bool, diff --git a/tests/ui/struct_excessive_bools.stderr b/tests/ui/struct_excessive_bools.stderr index bdf6f0b7a1da..573af45355a6 100644 --- a/tests/ui/struct_excessive_bools.stderr +++ b/tests/ui/struct_excessive_bools.stderr @@ -3,9 +3,9 @@ error: more than 3 bools in a struct | LL | / struct BadFoo { LL | | +LL | | LL | | a: bool, -LL | | b: bool, -LL | | c: bool, +... | LL | | d: bool, LL | | } | |_^ @@ -15,13 +15,13 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::struct_excessive_bools)]` error: more than 3 bools in a struct - --> tests/ui/struct_excessive_bools.rs:39:5 + --> tests/ui/struct_excessive_bools.rs:40:5 | LL | / struct FooFoo { LL | | +LL | | LL | | a: bool, -LL | | b: bool, -LL | | c: bool, +... | LL | | d: bool, LL | | } | |_____^ diff --git a/tests/ui/struct_fields.rs b/tests/ui/struct_fields.rs index 7c8867bd0fa3..3dce530efffa 100644 --- a/tests/ui/struct_fields.rs +++ b/tests/ui/struct_fields.rs @@ -339,7 +339,9 @@ struct Use { use_foo: bool, //~^ ERROR: field name starts with the struct's name use_bar: bool, + //~^ struct_field_names use_baz: bool, + //~^ struct_field_names } fn main() {} diff --git a/tests/ui/struct_fields.stderr b/tests/ui/struct_fields.stderr index cfda18c708c0..79186cc1cfd8 100644 --- a/tests/ui/struct_fields.stderr +++ b/tests/ui/struct_fields.stderr @@ -276,7 +276,7 @@ LL | use_bar: bool, | ^^^^^^^^^^^^^ error: field name starts with the struct's name - --> tests/ui/struct_fields.rs:342:5 + --> tests/ui/struct_fields.rs:343:5 | LL | use_baz: bool, | ^^^^^^^^^^^^^ diff --git a/tests/ui/suspicious_arithmetic_impl.rs b/tests/ui/suspicious_arithmetic_impl.rs index 07280351e76c..b9207b1b3f91 100644 --- a/tests/ui/suspicious_arithmetic_impl.rs +++ b/tests/ui/suspicious_arithmetic_impl.rs @@ -12,16 +12,18 @@ impl Add for Foo { fn add(self, other: Self) -> Self { Foo(self.0 - other.0) - //~^ ERROR: suspicious use of `-` in `Add` impl - //~| NOTE: `-D clippy::suspicious-arithmetic-impl` implied by `-D warnings` + //~^ suspicious_arithmetic_impl + + } } impl AddAssign for Foo { fn add_assign(&mut self, other: Foo) { *self = *self - other; - //~^ ERROR: suspicious use of `-` in `AddAssign` impl - //~| NOTE: `-D clippy::suspicious-op-assign-impl` implied by `-D warnings` + //~^ suspicious_op_assign_impl + + } } @@ -35,7 +37,8 @@ impl BitOrAssign for Foo { impl MulAssign for Foo { fn mul_assign(&mut self, other: Foo) { self.0 /= other.0; - //~^ ERROR: suspicious use of `/` in `MulAssign` impl + //~^ suspicious_op_assign_impl + } } @@ -74,7 +77,8 @@ impl Rem for Foo { fn rem(self, other: Self) -> Self { Foo(self.0 / other.0) - //~^ ERROR: suspicious use of `/` in `Rem` impl + //~^ suspicious_arithmetic_impl + } } @@ -83,7 +87,8 @@ impl BitAnd for Foo { fn bitand(self, other: Self) -> Self { Foo(self.0 | other.0) - //~^ ERROR: suspicious use of `|` in `BitAnd` impl + //~^ suspicious_arithmetic_impl + } } @@ -92,7 +97,8 @@ impl BitOr for Foo { fn bitor(self, other: Self) -> Self { Foo(self.0 ^ other.0) - //~^ ERROR: suspicious use of `^` in `BitOr` impl + //~^ suspicious_arithmetic_impl + } } @@ -101,7 +107,8 @@ impl BitXor for Foo { fn bitxor(self, other: Self) -> Self { Foo(self.0 & other.0) - //~^ ERROR: suspicious use of `&` in `BitXor` impl + //~^ suspicious_arithmetic_impl + } } @@ -110,7 +117,8 @@ impl Shl for Foo { fn shl(self, other: Self) -> Self { Foo(self.0 >> other.0) - //~^ ERROR: suspicious use of `>>` in `Shl` impl + //~^ suspicious_arithmetic_impl + } } @@ -119,7 +127,8 @@ impl Shr for Foo { fn shr(self, other: Self) -> Self { Foo(self.0 << other.0) - //~^ ERROR: suspicious use of `<<` in `Shr` impl + //~^ suspicious_arithmetic_impl + } } diff --git a/tests/ui/suspicious_arithmetic_impl.stderr b/tests/ui/suspicious_arithmetic_impl.stderr index 1bfca49a635d..a392aa16f1d4 100644 --- a/tests/ui/suspicious_arithmetic_impl.stderr +++ b/tests/ui/suspicious_arithmetic_impl.stderr @@ -8,7 +8,7 @@ LL | Foo(self.0 - other.0) = help: to override `-D warnings` add `#[allow(clippy::suspicious_arithmetic_impl)]` error: suspicious use of `-` in `AddAssign` impl - --> tests/ui/suspicious_arithmetic_impl.rs:22:23 + --> tests/ui/suspicious_arithmetic_impl.rs:23:23 | LL | *self = *self - other; | ^ @@ -17,43 +17,43 @@ LL | *self = *self - other; = help: to override `-D warnings` add `#[allow(clippy::suspicious_op_assign_impl)]` error: suspicious use of `/` in `MulAssign` impl - --> tests/ui/suspicious_arithmetic_impl.rs:37:16 + --> tests/ui/suspicious_arithmetic_impl.rs:39:16 | LL | self.0 /= other.0; | ^^ error: suspicious use of `/` in `Rem` impl - --> tests/ui/suspicious_arithmetic_impl.rs:76:20 + --> tests/ui/suspicious_arithmetic_impl.rs:79:20 | LL | Foo(self.0 / other.0) | ^ error: suspicious use of `|` in `BitAnd` impl - --> tests/ui/suspicious_arithmetic_impl.rs:85:20 + --> tests/ui/suspicious_arithmetic_impl.rs:89:20 | LL | Foo(self.0 | other.0) | ^ error: suspicious use of `^` in `BitOr` impl - --> tests/ui/suspicious_arithmetic_impl.rs:94:20 + --> tests/ui/suspicious_arithmetic_impl.rs:99:20 | LL | Foo(self.0 ^ other.0) | ^ error: suspicious use of `&` in `BitXor` impl - --> tests/ui/suspicious_arithmetic_impl.rs:103:20 + --> tests/ui/suspicious_arithmetic_impl.rs:109:20 | LL | Foo(self.0 & other.0) | ^ error: suspicious use of `>>` in `Shl` impl - --> tests/ui/suspicious_arithmetic_impl.rs:112:20 + --> tests/ui/suspicious_arithmetic_impl.rs:119:20 | LL | Foo(self.0 >> other.0) | ^^ error: suspicious use of `<<` in `Shr` impl - --> tests/ui/suspicious_arithmetic_impl.rs:121:20 + --> tests/ui/suspicious_arithmetic_impl.rs:129:20 | LL | Foo(self.0 << other.0) | ^^ diff --git a/tests/ui/suspicious_command_arg_space.fixed b/tests/ui/suspicious_command_arg_space.fixed index 704d6ea1bb83..5ab070f88dcf 100644 --- a/tests/ui/suspicious_command_arg_space.fixed +++ b/tests/ui/suspicious_command_arg_space.fixed @@ -2,10 +2,12 @@ fn main() { // Things it should warn about: std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); - //~^ ERROR: single argument that looks like it should be multiple arguments - //~| NOTE: `-D clippy::suspicious-command-arg-space` implied by `-D warnings` + //~^ suspicious_command_arg_space + + std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap(); - //~^ ERROR: single argument that looks like it should be multiple arguments + //~^ suspicious_command_arg_space + // Things it should not warn about: std::process::Command::new("echo").arg("hello world").spawn().unwrap(); diff --git a/tests/ui/suspicious_command_arg_space.rs b/tests/ui/suspicious_command_arg_space.rs index 2a2a7557381c..0017bd44dbfe 100644 --- a/tests/ui/suspicious_command_arg_space.rs +++ b/tests/ui/suspicious_command_arg_space.rs @@ -2,10 +2,12 @@ fn main() { // Things it should warn about: std::process::Command::new("echo").arg("-n hello").spawn().unwrap(); - //~^ ERROR: single argument that looks like it should be multiple arguments - //~| NOTE: `-D clippy::suspicious-command-arg-space` implied by `-D warnings` + //~^ suspicious_command_arg_space + + std::process::Command::new("cat").arg("--number file").spawn().unwrap(); - //~^ ERROR: single argument that looks like it should be multiple arguments + //~^ suspicious_command_arg_space + // Things it should not warn about: std::process::Command::new("echo").arg("hello world").spawn().unwrap(); diff --git a/tests/ui/suspicious_command_arg_space.stderr b/tests/ui/suspicious_command_arg_space.stderr index 6fd07d07d7be..f4d7d79def14 100644 --- a/tests/ui/suspicious_command_arg_space.stderr +++ b/tests/ui/suspicious_command_arg_space.stderr @@ -12,7 +12,7 @@ LL | std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap | ~~~~ ~~~~~~~~~~~~~~~ error: single argument that looks like it should be multiple arguments - --> tests/ui/suspicious_command_arg_space.rs:7:43 + --> tests/ui/suspicious_command_arg_space.rs:8:43 | LL | std::process::Command::new("cat").arg("--number file").spawn().unwrap(); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/suspicious_doc_comments.fixed b/tests/ui/suspicious_doc_comments.fixed index 614fc03571e5..58f6ebdb4c7c 100644 --- a/tests/ui/suspicious_doc_comments.fixed +++ b/tests/ui/suspicious_doc_comments.fixed @@ -3,10 +3,12 @@ //! Real module documentation. //! Fake module documentation. +//~^ suspicious_doc_comments fn baz() {} pub mod singleline_outer_doc { //! This module contains useful functions. + //~^ suspicious_doc_comments pub fn bar() {} } @@ -19,6 +21,7 @@ pub mod singleline_inner_doc { pub mod multiline_outer_doc { /*! This module contains useful functions. + //~^ suspicious_doc_comments */ pub fn bar() {} @@ -33,6 +36,7 @@ pub mod multiline_inner_doc { pub mod multiline_outer_doc2 { //! This module + //~^ suspicious_doc_comments //! contains //! useful functions. @@ -41,6 +45,7 @@ pub mod multiline_outer_doc2 { pub mod multiline_outer_doc3 { //! a + //~^ suspicious_doc_comments //! b /// c @@ -49,12 +54,14 @@ pub mod multiline_outer_doc3 { pub mod multiline_outer_doc4 { //! a + //~^ suspicious_doc_comments /// b pub fn bar() {} } pub mod multiline_outer_doc_gap { //! a + //~^ suspicious_doc_comments //! b pub fn bar() {} @@ -67,6 +74,7 @@ pub mod multiline_outer_doc_commented { pub mod outer_doc_macro { //! Very cool macro + //~^ suspicious_doc_comments macro_rules! x { () => {}; } @@ -74,6 +82,7 @@ pub mod outer_doc_macro { pub mod useless_outer_doc { //! Huh. + //~^ suspicious_doc_comments use std::mem; } diff --git a/tests/ui/suspicious_doc_comments.rs b/tests/ui/suspicious_doc_comments.rs index 7dcba0fefc98..26ee028b8c57 100644 --- a/tests/ui/suspicious_doc_comments.rs +++ b/tests/ui/suspicious_doc_comments.rs @@ -3,10 +3,12 @@ //! Real module documentation. ///! Fake module documentation. +//~^ suspicious_doc_comments fn baz() {} pub mod singleline_outer_doc { ///! This module contains useful functions. + //~^ suspicious_doc_comments pub fn bar() {} } @@ -19,6 +21,7 @@ pub mod singleline_inner_doc { pub mod multiline_outer_doc { /**! This module contains useful functions. + //~^ suspicious_doc_comments */ pub fn bar() {} @@ -33,6 +36,7 @@ pub mod multiline_inner_doc { pub mod multiline_outer_doc2 { ///! This module + //~^ suspicious_doc_comments ///! contains ///! useful functions. @@ -41,6 +45,7 @@ pub mod multiline_outer_doc2 { pub mod multiline_outer_doc3 { ///! a + //~^ suspicious_doc_comments ///! b /// c @@ -49,12 +54,14 @@ pub mod multiline_outer_doc3 { pub mod multiline_outer_doc4 { ///! a + //~^ suspicious_doc_comments /// b pub fn bar() {} } pub mod multiline_outer_doc_gap { ///! a + //~^ suspicious_doc_comments ///! b pub fn bar() {} @@ -67,6 +74,7 @@ pub mod multiline_outer_doc_commented { pub mod outer_doc_macro { ///! Very cool macro + //~^ suspicious_doc_comments macro_rules! x { () => {}; } @@ -74,6 +82,7 @@ pub mod outer_doc_macro { pub mod useless_outer_doc { ///! Huh. + //~^ suspicious_doc_comments use std::mem; } diff --git a/tests/ui/suspicious_doc_comments.stderr b/tests/ui/suspicious_doc_comments.stderr index f12053b1595a..8982e98b4daa 100644 --- a/tests/ui/suspicious_doc_comments.stderr +++ b/tests/ui/suspicious_doc_comments.stderr @@ -12,7 +12,7 @@ LL | //! Fake module documentation. | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:9:5 + --> tests/ui/suspicious_doc_comments.rs:10:5 | LL | ///! This module contains useful functions. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,22 +23,25 @@ LL | //! This module contains useful functions. | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:21:5 + --> tests/ui/suspicious_doc_comments.rs:23:5 | LL | / /**! This module contains useful functions. +LL | | LL | | */ | |_______^ | help: use an inner doc comment to document the parent module or crate | LL ~ /*! This module contains useful functions. +LL + LL + */ | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:35:5 + --> tests/ui/suspicious_doc_comments.rs:38:5 | LL | / ///! This module +LL | | LL | | ///! contains LL | | ///! useful functions. | |__________________________^ @@ -46,36 +49,13 @@ LL | | ///! useful functions. help: use an inner doc comment to document the parent module or crate | LL ~ //! This module +LL | LL ~ //! contains LL ~ //! useful functions. | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:43:5 - | -LL | / ///! a -LL | | ///! b - | |__________^ - | -help: use an inner doc comment to document the parent module or crate - | -LL ~ //! a -LL ~ //! b - | - -error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:51:5 - | -LL | ///! a - | ^^^^^^ - | -help: use an inner doc comment to document the parent module or crate - | -LL | //! a - | - -error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:57:5 + --> tests/ui/suspicious_doc_comments.rs:47:5 | LL | / ///! a LL | | @@ -90,7 +70,34 @@ LL ~ //! b | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:69:5 + --> tests/ui/suspicious_doc_comments.rs:56:5 + | +LL | ///! a + | ^^^^^^ + | +help: use an inner doc comment to document the parent module or crate + | +LL | //! a + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> tests/ui/suspicious_doc_comments.rs:63:5 + | +LL | / ///! a +... | +LL | | ///! b + | |__________^ + | +help: use an inner doc comment to document the parent module or crate + | +LL ~ //! a +LL | +LL | +LL ~ //! b + | + +error: this is an outer doc comment and does not apply to the parent module or crate + --> tests/ui/suspicious_doc_comments.rs:76:5 | LL | ///! Very cool macro | ^^^^^^^^^^^^^^^^^^^^ @@ -101,7 +108,7 @@ LL | //! Very cool macro | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments.rs:76:5 + --> tests/ui/suspicious_doc_comments.rs:84:5 | LL | ///! Huh. | ^^^^^^^^^ diff --git a/tests/ui/suspicious_doc_comments_unfixable.rs b/tests/ui/suspicious_doc_comments_unfixable.rs index 9e9c4775748c..255c6f7237df 100644 --- a/tests/ui/suspicious_doc_comments_unfixable.rs +++ b/tests/ui/suspicious_doc_comments_unfixable.rs @@ -2,15 +2,17 @@ #![warn(clippy::suspicious_doc_comments)] //@no-rustfix ///! a -//~^ ERROR: this is an outer doc comment and does not apply to the parent module or crate -//~| NOTE: `-D clippy::suspicious-doc-comments` implied by `-D warnings` +//~^ suspicious_doc_comments + + ///! b /// c ///! d pub fn foo() {} ///! a -//~^ ERROR: this is an outer doc comment and does not apply to the parent module or crate +//~^ suspicious_doc_comments + ///! b /// c ///! d diff --git a/tests/ui/suspicious_doc_comments_unfixable.stderr b/tests/ui/suspicious_doc_comments_unfixable.stderr index d15f16f7c503..ff4cb3358a81 100644 --- a/tests/ui/suspicious_doc_comments_unfixable.stderr +++ b/tests/ui/suspicious_doc_comments_unfixable.stderr @@ -2,9 +2,7 @@ error: this is an outer doc comment and does not apply to the parent module or c --> tests/ui/suspicious_doc_comments_unfixable.rs:4:1 | LL | / ///! a -LL | | -LL | | -LL | | ///! b +... | LL | | /// c LL | | ///! d | |______^ @@ -16,16 +14,18 @@ help: use an inner doc comment to document the parent module or crate LL + //! a LL | LL | +LL | LL + //! b LL | /// c LL + //! d | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments_unfixable.rs:12:1 + --> tests/ui/suspicious_doc_comments_unfixable.rs:13:1 | LL | / ///! a LL | | +LL | | LL | | ///! b LL | | /// c LL | | ///! d @@ -35,6 +35,7 @@ help: use an inner doc comment to document the parent module or crate | LL + //! a LL | +LL | LL + //! b LL | /// c LL + //! d diff --git a/tests/ui/suspicious_else_formatting.rs b/tests/ui/suspicious_else_formatting.rs index 3d5c892eb606..7e57684bd437 100644 --- a/tests/ui/suspicious_else_formatting.rs +++ b/tests/ui/suspicious_else_formatting.rs @@ -20,10 +20,12 @@ fn main() { // weird `else` formatting: if foo() { } { + //~^ suspicious_else_formatting } if foo() { } if foo() { + //~^ suspicious_else_formatting } let _ = { // if as the last expression @@ -31,6 +33,7 @@ fn main() { if foo() { } if foo() { + //~^ suspicious_else_formatting } else { } @@ -39,6 +42,7 @@ fn main() { let _ = { // if in the middle of a block if foo() { } if foo() { + //~^ suspicious_else_formatting } else { } @@ -50,6 +54,7 @@ fn main() { } else { } + //~^^^ suspicious_else_formatting // This is fine, though weird. Allman style braces on the else. if foo() { @@ -62,12 +67,14 @@ fn main() { } else if foo() { // the span of the above error should continue here } + //~^^^ suspicious_else_formatting if foo() { } else if foo() { // the span of the above error should continue here } + //~^^^^ suspicious_else_formatting // those are ok: if foo() { @@ -92,7 +99,6 @@ fn main() { // Almost Allman style braces. Lint these. if foo() { } - else { @@ -105,6 +111,7 @@ fn main() { { } + //~^^^^^^ suspicious_else_formatting // #3864 - Allman style braces if foo() diff --git a/tests/ui/suspicious_else_formatting.stderr b/tests/ui/suspicious_else_formatting.stderr index 28c5a2d904ce..cf2788b67d07 100644 --- a/tests/ui/suspicious_else_formatting.stderr +++ b/tests/ui/suspicious_else_formatting.stderr @@ -9,7 +9,7 @@ LL | } { = help: to override `-D warnings` add `#[allow(clippy::suspicious_else_formatting)]` error: this looks like an `else if` but the `else` is missing - --> tests/ui/suspicious_else_formatting.rs:26:6 + --> tests/ui/suspicious_else_formatting.rs:27:6 | LL | } if foo() { | ^ @@ -17,7 +17,7 @@ LL | } if foo() { = note: to remove this lint, add the missing `else` or add a new line before the second `if` error: this looks like an `else if` but the `else` is missing - --> tests/ui/suspicious_else_formatting.rs:33:10 + --> tests/ui/suspicious_else_formatting.rs:35:10 | LL | } if foo() { | ^ @@ -25,7 +25,7 @@ LL | } if foo() { = note: to remove this lint, add the missing `else` or add a new line before the second `if` error: this looks like an `else if` but the `else` is missing - --> tests/ui/suspicious_else_formatting.rs:41:10 + --> tests/ui/suspicious_else_formatting.rs:44:10 | LL | } if foo() { | ^ @@ -33,7 +33,7 @@ LL | } if foo() { = note: to remove this lint, add the missing `else` or add a new line before the second `if` error: this is an `else {..}` but the formatting might hide it - --> tests/ui/suspicious_else_formatting.rs:50:6 + --> tests/ui/suspicious_else_formatting.rs:54:6 | LL | } else | ______^ @@ -42,19 +42,19 @@ LL | | { | = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}` -error: this is an `else if` but the formatting might hide it - --> tests/ui/suspicious_else_formatting.rs:62:6 - | -LL | } else - | ______^ -LL | | if foo() { // the span of the above error should continue here - | |____^ - | - = note: to remove this lint, remove the `else` or remove the new line between `else` and `if` - error: this is an `else if` but the formatting might hide it --> tests/ui/suspicious_else_formatting.rs:67:6 | +LL | } else + | ______^ +LL | | if foo() { // the span of the above error should continue here + | |____^ + | + = note: to remove this lint, remove the `else` or remove the new line between `else` and `if` + +error: this is an `else if` but the formatting might hide it + --> tests/ui/suspicious_else_formatting.rs:73:6 + | LL | } | ______^ LL | | else @@ -64,19 +64,7 @@ LL | | if foo() { // the span of the above error should continue here = note: to remove this lint, remove the `else` or remove the new line between `else` and `if` error: this is an `else {..}` but the formatting might hide it - --> tests/ui/suspicious_else_formatting.rs:94:6 - | -LL | } - | ______^ -LL | | -LL | | else -LL | | { - | |____^ - | - = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}` - -error: this is an `else {..}` but the formatting might hide it - --> tests/ui/suspicious_else_formatting.rs:102:6 + --> tests/ui/suspicious_else_formatting.rs:108:6 | LL | } | ______^ @@ -87,5 +75,5 @@ LL | | { | = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}` -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors diff --git a/tests/ui/suspicious_map.rs b/tests/ui/suspicious_map.rs index d4a52cb110fb..3e3035a68f49 100644 --- a/tests/ui/suspicious_map.rs +++ b/tests/ui/suspicious_map.rs @@ -3,11 +3,13 @@ fn main() { let _ = (0..3).map(|x| x + 2).count(); - //~^ ERROR: this call to `map()` won't have an effect on the call to `count()` + //~^ suspicious_map + let f = |x| x + 1; let _ = (0..3).map(f).count(); - //~^ ERROR: this call to `map()` won't have an effect on the call to `count()` + //~^ suspicious_map + } fn negative() { diff --git a/tests/ui/suspicious_map.stderr b/tests/ui/suspicious_map.stderr index 769adebaede7..7c08168f0c20 100644 --- a/tests/ui/suspicious_map.stderr +++ b/tests/ui/suspicious_map.stderr @@ -9,7 +9,7 @@ LL | let _ = (0..3).map(|x| x + 2).count(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]` error: this call to `map()` won't have an effect on the call to `count()` - --> tests/ui/suspicious_map.rs:9:13 + --> tests/ui/suspicious_map.rs:10:13 | LL | let _ = (0..3).map(f).count(); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/suspicious_operation_groupings.fixed b/tests/ui/suspicious_operation_groupings.fixed index 60fde6e22cb6..1da292130d05 100644 --- a/tests/ui/suspicious_operation_groupings.fixed +++ b/tests/ui/suspicious_operation_groupings.fixed @@ -15,6 +15,7 @@ impl PartialEq for Vec3 { fn eq(&self, other: &Self) -> bool { // This should trigger the lint because `self.x` is compared to `other.y` self.x == other.x && self.y == other.y && self.z == other.z + //~^ suspicious_operation_groupings } } @@ -28,6 +29,7 @@ struct S { fn buggy_ab_cmp(s1: &S, s2: &S) -> bool { // There's no `s1.b` s1.a < s2.a && s1.b < s2.b + //~^ suspicious_operation_groupings } struct SaOnly { @@ -76,31 +78,38 @@ fn permissable(s1: &S, s2: &S) -> bool { fn non_boolean_operators(s1: &S, s2: &S) -> i32 { // There's no `s2.c` s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + s1.d * s2.d + //~^ suspicious_operation_groupings } fn odd_number_of_pairs(s1: &S, s2: &S) -> i32 { // There's no `s2.b` s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + //~^ suspicious_operation_groupings + //~| suspicious_operation_groupings } fn not_caught_by_eq_op_middle_change_left(s1: &S, s2: &S) -> i32 { // There's no `s1.b` s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + //~^ suspicious_operation_groupings } fn not_caught_by_eq_op_middle_change_right(s1: &S, s2: &S) -> i32 { // There's no `s2.b` s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + //~^ suspicious_operation_groupings } fn not_caught_by_eq_op_start(s1: &S, s2: &S) -> i32 { // There's no `s2.a` s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + //~^ suspicious_operation_groupings } fn not_caught_by_eq_op_end(s1: &S, s2: &S) -> i32 { // There's no `s2.c` s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + //~^ suspicious_operation_groupings } fn the_cross_product_should_not_lint(s1: &S, s2: &S) -> (i32, i32, i32) { @@ -114,56 +123,68 @@ fn the_cross_product_should_not_lint(s1: &S, s2: &S) -> (i32, i32, i32) { fn outer_parens_simple(s1: &S, s2: &S) -> i32 { // There's no `s2.b` (s1.a * s2.a + s1.b * s2.b) + //~^ suspicious_operation_groupings } fn outer_parens(s1: &S, s2: &S) -> i32 { // There's no `s2.c` (s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + s1.d * s2.d) + //~^ suspicious_operation_groupings } fn inner_parens(s1: &S, s2: &S) -> i32 { // There's no `s2.c` (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d) + //~^ suspicious_operation_groupings } fn outer_and_some_inner_parens(s1: &S, s2: &S) -> i32 { // There's no `s2.c` ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d)) + //~^ suspicious_operation_groupings } fn all_parens_balanced_tree(s1: &S, s2: &S) -> i32 { // There's no `s2.c` (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.c) + (s1.d * s2.d))) + //~^ suspicious_operation_groupings + //~| suspicious_operation_groupings } fn all_parens_left_tree(s1: &S, s2: &S) -> i32 { // There's no `s2.c` (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c)) + (s1.d * s2.d)) + //~^ suspicious_operation_groupings } fn all_parens_right_tree(s1: &S, s2: &S) -> i32 { // There's no `s2.c` ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d))) + //~^ suspicious_operation_groupings } fn inside_other_binop_expression(s1: &S, s2: &S) -> i32 { // There's no `s1.b` (s1.a * s2.a + s1.b * s2.b) / 2 + //~^ suspicious_operation_groupings } fn inside_function_call(s1: &S, s2: &S) -> i32 { // There's no `s1.b` i32::swap_bytes(s1.a * s2.a + s1.b * s2.b) + //~^ suspicious_operation_groupings } fn inside_larger_boolean_expression(s1: &S, s2: &S) -> bool { // There's no `s1.c` s1.a > 0 && s1.b > 0 && s1.c == s2.c && s1.d == s2.d + //~^ suspicious_operation_groupings } fn inside_larger_boolean_expression_with_unsorted_ops(s1: &S, s2: &S) -> bool { // There's no `s1.c` s1.a > 0 && s1.c == s2.c && s1.b > 0 && s1.d == s2.d + //~^ suspicious_operation_groupings } struct Nested { @@ -173,6 +194,7 @@ struct Nested { fn changed_middle_ident(n1: &Nested, n2: &Nested) -> bool { // There's no `n2.inner.2.0` (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0 + //~^ suspicious_operation_groupings } // `eq_op` should catch this one. @@ -187,12 +209,14 @@ fn inside_fn_with_similar_expression(s1: &S, s2: &S, strict: bool) -> bool { } else { // There's no `s1.b` in this subexpression s1.a <= s2.a && s1.b <= s2.b + //~^ suspicious_operation_groupings } } fn inside_an_if_statement(s1: &mut S, s2: &S) { // There's no `s1.b` if s1.a < s2.a && s1.b < s2.b { + //~^ suspicious_operation_groupings s1.c = s2.c; } } @@ -200,11 +224,13 @@ fn inside_an_if_statement(s1: &mut S, s2: &S) { fn maximum_unary_minus_right_tree(s1: &S, s2: &S) -> i32 { // There's no `s2.c` -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.c) + -(-s1.d * -s2.d))) + //~^ suspicious_operation_groupings } fn unary_minus_and_an_if_expression(s1: &S, s2: &S) -> i32 { // There's no `s1.b` -(if -s1.a < -s2.a && -s1.b < -s2.b { s1.c } else { s2.a }) + //~^ suspicious_operation_groupings } fn main() {} diff --git a/tests/ui/suspicious_operation_groupings.rs b/tests/ui/suspicious_operation_groupings.rs index ce37148a853b..25ccba182fa5 100644 --- a/tests/ui/suspicious_operation_groupings.rs +++ b/tests/ui/suspicious_operation_groupings.rs @@ -15,6 +15,7 @@ impl PartialEq for Vec3 { fn eq(&self, other: &Self) -> bool { // This should trigger the lint because `self.x` is compared to `other.y` self.x == other.y && self.y == other.y && self.z == other.z + //~^ suspicious_operation_groupings } } @@ -28,6 +29,7 @@ struct S { fn buggy_ab_cmp(s1: &S, s2: &S) -> bool { // There's no `s1.b` s1.a < s2.a && s1.a < s2.b + //~^ suspicious_operation_groupings } struct SaOnly { @@ -76,31 +78,38 @@ fn permissable(s1: &S, s2: &S) -> bool { fn non_boolean_operators(s1: &S, s2: &S) -> i32 { // There's no `s2.c` s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d + //~^ suspicious_operation_groupings } fn odd_number_of_pairs(s1: &S, s2: &S) -> i32 { // There's no `s2.b` s1.a * s2.a + s1.b * s2.c + s1.c * s2.c + //~^ suspicious_operation_groupings + //~| suspicious_operation_groupings } fn not_caught_by_eq_op_middle_change_left(s1: &S, s2: &S) -> i32 { // There's no `s1.b` s1.a * s2.a + s2.b * s2.b + s1.c * s2.c + //~^ suspicious_operation_groupings } fn not_caught_by_eq_op_middle_change_right(s1: &S, s2: &S) -> i32 { // There's no `s2.b` s1.a * s2.a + s1.b * s1.b + s1.c * s2.c + //~^ suspicious_operation_groupings } fn not_caught_by_eq_op_start(s1: &S, s2: &S) -> i32 { // There's no `s2.a` s1.a * s1.a + s1.b * s2.b + s1.c * s2.c + //~^ suspicious_operation_groupings } fn not_caught_by_eq_op_end(s1: &S, s2: &S) -> i32 { // There's no `s2.c` s1.a * s2.a + s1.b * s2.b + s1.c * s1.c + //~^ suspicious_operation_groupings } fn the_cross_product_should_not_lint(s1: &S, s2: &S) -> (i32, i32, i32) { @@ -114,56 +123,68 @@ fn the_cross_product_should_not_lint(s1: &S, s2: &S) -> (i32, i32, i32) { fn outer_parens_simple(s1: &S, s2: &S) -> i32 { // There's no `s2.b` (s1.a * s2.a + s1.b * s1.b) + //~^ suspicious_operation_groupings } fn outer_parens(s1: &S, s2: &S) -> i32 { // There's no `s2.c` (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d) + //~^ suspicious_operation_groupings } fn inner_parens(s1: &S, s2: &S) -> i32 { // There's no `s2.c` (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d) + //~^ suspicious_operation_groupings } fn outer_and_some_inner_parens(s1: &S, s2: &S) -> i32 { // There's no `s2.c` ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)) + //~^ suspicious_operation_groupings } fn all_parens_balanced_tree(s1: &S, s2: &S) -> i32 { // There's no `s2.c` (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d))) + //~^ suspicious_operation_groupings + //~| suspicious_operation_groupings } fn all_parens_left_tree(s1: &S, s2: &S) -> i32 { // There's no `s2.c` (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d)) + //~^ suspicious_operation_groupings } fn all_parens_right_tree(s1: &S, s2: &S) -> i32 { // There's no `s2.c` ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))) + //~^ suspicious_operation_groupings } fn inside_other_binop_expression(s1: &S, s2: &S) -> i32 { // There's no `s1.b` (s1.a * s2.a + s2.b * s2.b) / 2 + //~^ suspicious_operation_groupings } fn inside_function_call(s1: &S, s2: &S) -> i32 { // There's no `s1.b` i32::swap_bytes(s1.a * s2.a + s2.b * s2.b) + //~^ suspicious_operation_groupings } fn inside_larger_boolean_expression(s1: &S, s2: &S) -> bool { // There's no `s1.c` s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d + //~^ suspicious_operation_groupings } fn inside_larger_boolean_expression_with_unsorted_ops(s1: &S, s2: &S) -> bool { // There's no `s1.c` s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d + //~^ suspicious_operation_groupings } struct Nested { @@ -173,6 +194,7 @@ struct Nested { fn changed_middle_ident(n1: &Nested, n2: &Nested) -> bool { // There's no `n2.inner.2.0` (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0 + //~^ suspicious_operation_groupings } // `eq_op` should catch this one. @@ -187,12 +209,14 @@ fn inside_fn_with_similar_expression(s1: &S, s2: &S, strict: bool) -> bool { } else { // There's no `s1.b` in this subexpression s1.a <= s2.a && s1.a <= s2.b + //~^ suspicious_operation_groupings } } fn inside_an_if_statement(s1: &mut S, s2: &S) { // There's no `s1.b` if s1.a < s2.a && s1.a < s2.b { + //~^ suspicious_operation_groupings s1.c = s2.c; } } @@ -200,11 +224,13 @@ fn inside_an_if_statement(s1: &mut S, s2: &S) { fn maximum_unary_minus_right_tree(s1: &S, s2: &S) -> i32 { // There's no `s2.c` -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d))) + //~^ suspicious_operation_groupings } fn unary_minus_and_an_if_expression(s1: &S, s2: &S) -> i32 { // There's no `s1.b` -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a }) + //~^ suspicious_operation_groupings } fn main() {} diff --git a/tests/ui/suspicious_operation_groupings.stderr b/tests/ui/suspicious_operation_groupings.stderr index 7cb066d57e75..b640b2041cd3 100644 --- a/tests/ui/suspicious_operation_groupings.stderr +++ b/tests/ui/suspicious_operation_groupings.stderr @@ -8,151 +8,151 @@ LL | self.x == other.y && self.y == other.y && self.z == other.z = help: to override `-D warnings` add `#[allow(clippy::suspicious_operation_groupings)]` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:30:20 + --> tests/ui/suspicious_operation_groupings.rs:31:20 | LL | s1.a < s2.a && s1.a < s2.b | ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:78:33 + --> tests/ui/suspicious_operation_groupings.rs:80:33 | LL | s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:83:19 + --> tests/ui/suspicious_operation_groupings.rs:86:19 | LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:83:19 + --> tests/ui/suspicious_operation_groupings.rs:86:19 | LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` -error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:88:19 - | -LL | s1.a * s2.a + s2.b * s2.b + s1.c * s2.c - | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` - error: this sequence of operators looks suspiciously like a bug --> tests/ui/suspicious_operation_groupings.rs:93:19 | +LL | s1.a * s2.a + s2.b * s2.b + s1.c * s2.c + | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` + +error: this sequence of operators looks suspiciously like a bug + --> tests/ui/suspicious_operation_groupings.rs:99:19 + | LL | s1.a * s2.a + s1.b * s1.b + s1.c * s2.c | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:98:5 + --> tests/ui/suspicious_operation_groupings.rs:105:5 | LL | s1.a * s1.a + s1.b * s2.b + s1.c * s2.c | ^^^^^^^^^^^ help: did you mean: `s1.a * s2.a` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:103:33 + --> tests/ui/suspicious_operation_groupings.rs:111:33 | LL | s1.a * s2.a + s1.b * s2.b + s1.c * s1.c | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:116:20 + --> tests/ui/suspicious_operation_groupings.rs:125:20 | LL | (s1.a * s2.a + s1.b * s1.b) | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:121:34 + --> tests/ui/suspicious_operation_groupings.rs:131:34 | LL | (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d) | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:126:38 + --> tests/ui/suspicious_operation_groupings.rs:137:38 | LL | (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d) | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:131:39 + --> tests/ui/suspicious_operation_groupings.rs:143:39 | LL | ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)) | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:136:42 + --> tests/ui/suspicious_operation_groupings.rs:149:42 | LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d))) | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:136:42 + --> tests/ui/suspicious_operation_groupings.rs:149:42 | LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d))) | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:141:40 + --> tests/ui/suspicious_operation_groupings.rs:156:40 | LL | (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d)) | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:146:40 + --> tests/ui/suspicious_operation_groupings.rs:162:40 | LL | ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))) | ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:151:20 + --> tests/ui/suspicious_operation_groupings.rs:168:20 | LL | (s1.a * s2.a + s2.b * s2.b) / 2 | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:156:35 + --> tests/ui/suspicious_operation_groupings.rs:174:35 | LL | i32::swap_bytes(s1.a * s2.a + s2.b * s2.b) | ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:161:29 + --> tests/ui/suspicious_operation_groupings.rs:180:29 | LL | s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d | ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:166:17 + --> tests/ui/suspicious_operation_groupings.rs:186:17 | LL | s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d | ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:175:77 + --> tests/ui/suspicious_operation_groupings.rs:196:77 | LL | (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `(n1.inner.2).0 == (n2.inner.2).0` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:189:25 + --> tests/ui/suspicious_operation_groupings.rs:211:25 | LL | s1.a <= s2.a && s1.a <= s2.b | ^^^^^^^^^^^^ help: did you mean: `s1.b <= s2.b` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:195:23 + --> tests/ui/suspicious_operation_groupings.rs:218:23 | LL | if s1.a < s2.a && s1.a < s2.b { | ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:202:48 + --> tests/ui/suspicious_operation_groupings.rs:226:48 | LL | -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d))) | ^^^^^^^^^^^^^ help: did you mean: `-s1.c * -s2.c` error: this sequence of operators looks suspiciously like a bug - --> tests/ui/suspicious_operation_groupings.rs:207:27 + --> tests/ui/suspicious_operation_groupings.rs:232:27 | LL | -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a }) | ^^^^^^^^^^^^^ help: did you mean: `-s1.b < -s2.b` diff --git a/tests/ui/suspicious_splitn.rs b/tests/ui/suspicious_splitn.rs index 7aa609706220..d7c1dd972450 100644 --- a/tests/ui/suspicious_splitn.rs +++ b/tests/ui/suspicious_splitn.rs @@ -8,32 +8,41 @@ fn main() { let _ = [].splitn(0, |&x: &u32| x == 1); let _ = "a,b".splitn(0, ','); - //~^ ERROR: `splitn` called with `0` splits - //~| NOTE: the resulting iterator will always return `None` + //~^ suspicious_splitn + + let _ = "a,b".rsplitn(0, ','); - //~^ ERROR: `rsplitn` called with `0` splits - //~| NOTE: the resulting iterator will always return `None` + //~^ suspicious_splitn + + let _ = "a,b".splitn(1, ','); - //~^ ERROR: `splitn` called with `1` split - //~| NOTE: the resulting iterator will always return the entire string followed by `No + //~^ suspicious_splitn + + let _ = [0, 1, 2].splitn(0, |&x| x == 1); - //~^ ERROR: `splitn` called with `0` splits - //~| NOTE: the resulting iterator will always return `None` + //~^ suspicious_splitn + + let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1); - //~^ ERROR: `splitn_mut` called with `0` splits - //~| NOTE: the resulting iterator will always return `None` + //~^ suspicious_splitn + + let _ = [0, 1, 2].splitn(1, |&x| x == 1); - //~^ ERROR: `splitn` called with `1` split - //~| NOTE: the resulting iterator will always return the entire slice followed by `Non + //~^ suspicious_splitn + + let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1); - //~^ ERROR: `rsplitn_mut` called with `1` split - //~| NOTE: the resulting iterator will always return the entire slice followed by `Non + //~^ suspicious_splitn + + const X: usize = 0; let _ = "a,b".splitn(X + 1, ','); - //~^ ERROR: `splitn` called with `1` split - //~| NOTE: the resulting iterator will always return the entire string followed by `No + //~^ suspicious_splitn + + let _ = "a,b".splitn(X, ','); - //~^ ERROR: `splitn` called with `0` splits - //~| NOTE: the resulting iterator will always return `None` + //~^ suspicious_splitn + + } diff --git a/tests/ui/suspicious_splitn.stderr b/tests/ui/suspicious_splitn.stderr index 6e05bc28d130..1e1a9b22ffbd 100644 --- a/tests/ui/suspicious_splitn.stderr +++ b/tests/ui/suspicious_splitn.stderr @@ -9,7 +9,7 @@ LL | let _ = "a,b".splitn(0, ','); = help: to override `-D warnings` add `#[allow(clippy::suspicious_splitn)]` error: `rsplitn` called with `0` splits - --> tests/ui/suspicious_splitn.rs:13:13 + --> tests/ui/suspicious_splitn.rs:14:13 | LL | let _ = "a,b".rsplitn(0, ','); | ^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = "a,b".rsplitn(0, ','); = note: the resulting iterator will always return `None` error: `splitn` called with `1` split - --> tests/ui/suspicious_splitn.rs:16:13 + --> tests/ui/suspicious_splitn.rs:18:13 | LL | let _ = "a,b".splitn(1, ','); | ^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = "a,b".splitn(1, ','); = note: the resulting iterator will always return the entire string followed by `None` error: `splitn` called with `0` splits - --> tests/ui/suspicious_splitn.rs:19:13 + --> tests/ui/suspicious_splitn.rs:22:13 | LL | let _ = [0, 1, 2].splitn(0, |&x| x == 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = [0, 1, 2].splitn(0, |&x| x == 1); = note: the resulting iterator will always return `None` error: `splitn_mut` called with `0` splits - --> tests/ui/suspicious_splitn.rs:22:13 + --> tests/ui/suspicious_splitn.rs:26:13 | LL | let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1); = note: the resulting iterator will always return `None` error: `splitn` called with `1` split - --> tests/ui/suspicious_splitn.rs:25:13 + --> tests/ui/suspicious_splitn.rs:30:13 | LL | let _ = [0, 1, 2].splitn(1, |&x| x == 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = [0, 1, 2].splitn(1, |&x| x == 1); = note: the resulting iterator will always return the entire slice followed by `None` error: `rsplitn_mut` called with `1` split - --> tests/ui/suspicious_splitn.rs:28:13 + --> tests/ui/suspicious_splitn.rs:34:13 | LL | let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1); = note: the resulting iterator will always return the entire slice followed by `None` error: `splitn` called with `1` split - --> tests/ui/suspicious_splitn.rs:33:13 + --> tests/ui/suspicious_splitn.rs:40:13 | LL | let _ = "a,b".splitn(X + 1, ','); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | let _ = "a,b".splitn(X + 1, ','); = note: the resulting iterator will always return the entire string followed by `None` error: `splitn` called with `0` splits - --> tests/ui/suspicious_splitn.rs:36:13 + --> tests/ui/suspicious_splitn.rs:44:13 | LL | let _ = "a,b".splitn(X, ','); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/suspicious_to_owned.rs b/tests/ui/suspicious_to_owned.rs index 794c2e7174af..bde20f4116c3 100644 --- a/tests/ui/suspicious_to_owned.rs +++ b/tests/ui/suspicious_to_owned.rs @@ -15,8 +15,9 @@ fn main() { // we expect this to be linted let cow = Cow::Borrowed(moo); let _ = cow.to_owned(); - //~^ ERROR: this `to_owned` call clones the Cow<'_, str> itself and does not cause the - //~| NOTE: `-D clippy::suspicious-to-owned` implied by `-D warnings` + //~^ suspicious_to_owned + + // we expect no lints for this let cow = Cow::Borrowed(moo); let _ = cow.into_owned(); @@ -27,7 +28,8 @@ fn main() { // we expect this to be linted let cow = Cow::Borrowed(&moos); let _ = cow.to_owned(); - //~^ ERROR: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cau + //~^ suspicious_to_owned + // we expect no lints for this let cow = Cow::Borrowed(&moos); let _ = cow.into_owned(); @@ -38,7 +40,8 @@ fn main() { // we expect this to be linted let cow = Cow::Borrowed(&moos_vec); let _ = cow.to_owned(); - //~^ ERROR: this `to_owned` call clones the Cow<'_, Vec> itself and does not cau + //~^ suspicious_to_owned + // we expect no lints for this let cow = Cow::Borrowed(&moos_vec); let _ = cow.into_owned(); @@ -49,7 +52,8 @@ fn main() { // we expect this to be linted let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); let _ = cow.to_owned(); - //~^ ERROR: this `to_owned` call clones the Cow<'_, str> itself and does not cause the + //~^ suspicious_to_owned + // we expect no lints for this let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); let _ = cow.into_owned(); @@ -64,8 +68,10 @@ fn main() { // we expect implicit_clone lints for these let _ = String::from(moo).to_owned(); - //~^ ERROR: implicitly cloning a `String` by calling `to_owned` on its dereferenced ty - //~| NOTE: `-D clippy::implicit-clone` implied by `-D warnings` + //~^ implicit_clone + + let _ = moos_vec.to_owned(); - //~^ ERROR: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type + //~^ implicit_clone + } diff --git a/tests/ui/suspicious_to_owned.stderr b/tests/ui/suspicious_to_owned.stderr index 255f211e6550..6c00819b4863 100644 --- a/tests/ui/suspicious_to_owned.stderr +++ b/tests/ui/suspicious_to_owned.stderr @@ -16,7 +16,7 @@ LL | let _ = cow.clone(); | ~~~~~~~~~~~ error: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cause the Cow<'_, [char; 3]> contents to become owned - --> tests/ui/suspicious_to_owned.rs:29:13 + --> tests/ui/suspicious_to_owned.rs:30:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | let _ = cow.clone(); | ~~~~~~~~~~~ error: this `to_owned` call clones the Cow<'_, Vec> itself and does not cause the Cow<'_, Vec> contents to become owned - --> tests/ui/suspicious_to_owned.rs:40:13 + --> tests/ui/suspicious_to_owned.rs:42:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | let _ = cow.clone(); | ~~~~~~~~~~~ error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned - --> tests/ui/suspicious_to_owned.rs:51:13 + --> tests/ui/suspicious_to_owned.rs:54:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | let _ = cow.clone(); | ~~~~~~~~~~~ error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type - --> tests/ui/suspicious_to_owned.rs:66:13 + --> tests/ui/suspicious_to_owned.rs:70:13 | LL | let _ = String::from(moo).to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::from(moo).clone()` @@ -70,7 +70,7 @@ LL | let _ = String::from(moo).to_owned(); = help: to override `-D warnings` add `#[allow(clippy::implicit_clone)]` error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type - --> tests/ui/suspicious_to_owned.rs:69:13 + --> tests/ui/suspicious_to_owned.rs:74:13 | LL | let _ = moos_vec.to_owned(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `moos_vec.clone()` diff --git a/tests/ui/suspicious_unary_op_formatting.rs b/tests/ui/suspicious_unary_op_formatting.rs index a7a62154ee0f..ab9bdde6cf90 100644 --- a/tests/ui/suspicious_unary_op_formatting.rs +++ b/tests/ui/suspicious_unary_op_formatting.rs @@ -7,18 +7,22 @@ fn main() { let a = 42; if a >- 30 {} - //~^ ERROR: by not having a space between `>` and `-` it looks like `>-` is a single o + //~^ suspicious_unary_op_formatting + if a >=- 30 {} - //~^ ERROR: by not having a space between `>=` and `-` it looks like `>=-` is a single + //~^ suspicious_unary_op_formatting + let b = true; let c = false; if b &&! c {} - //~^ ERROR: by not having a space between `&&` and `!` it looks like `&&!` is a single + //~^ suspicious_unary_op_formatting + if a >- 30 {} - //~^ ERROR: by not having a space between `>` and `-` it looks like `>-` is a single o + //~^ suspicious_unary_op_formatting + // those are ok: if a >-30 {} diff --git a/tests/ui/suspicious_unary_op_formatting.stderr b/tests/ui/suspicious_unary_op_formatting.stderr index 379fb17266a9..5fe18aa82435 100644 --- a/tests/ui/suspicious_unary_op_formatting.stderr +++ b/tests/ui/suspicious_unary_op_formatting.stderr @@ -9,7 +9,7 @@ LL | if a >- 30 {} = help: to override `-D warnings` add `#[allow(clippy::suspicious_unary_op_formatting)]` error: by not having a space between `>=` and `-` it looks like `>=-` is a single operator - --> tests/ui/suspicious_unary_op_formatting.rs:11:9 + --> tests/ui/suspicious_unary_op_formatting.rs:12:9 | LL | if a >=- 30 {} | ^^^^^ @@ -17,7 +17,7 @@ LL | if a >=- 30 {} = help: put a space between `>=` and `-` and remove the space after `-` error: by not having a space between `&&` and `!` it looks like `&&!` is a single operator - --> tests/ui/suspicious_unary_op_formatting.rs:17:9 + --> tests/ui/suspicious_unary_op_formatting.rs:19:9 | LL | if b &&! c {} | ^^^^^ @@ -25,7 +25,7 @@ LL | if b &&! c {} = help: put a space between `&&` and `!` and remove the space after `!` error: by not having a space between `>` and `-` it looks like `>-` is a single operator - --> tests/ui/suspicious_unary_op_formatting.rs:20:9 + --> tests/ui/suspicious_unary_op_formatting.rs:23:9 | LL | if a >- 30 {} | ^^^^^^ diff --git a/tests/ui/suspicious_xor_used_as_pow.rs b/tests/ui/suspicious_xor_used_as_pow.rs index a5319e1b2308..229ed3383329 100644 --- a/tests/ui/suspicious_xor_used_as_pow.rs +++ b/tests/ui/suspicious_xor_used_as_pow.rs @@ -11,24 +11,31 @@ macro_rules! macro_test { macro_rules! macro_test_inside { () => { 1 ^ 2 // should warn even if inside macro + //~^ suspicious_xor_used_as_pow }; } fn main() { // Should warn: let _ = 2 ^ 5; - //~^ ERROR: `^` is not the exponentiation operator - //~| NOTE: `-D clippy::suspicious-xor-used-as-pow` implied by `-D warnings` + //~^ suspicious_xor_used_as_pow + + let _ = 2i32 ^ 9i32; - //~^ ERROR: `^` is not the exponentiation operator + //~^ suspicious_xor_used_as_pow + let _ = 2i32 ^ 2i32; - //~^ ERROR: `^` is not the exponentiation operator + //~^ suspicious_xor_used_as_pow + let _ = 50i32 ^ 3i32; - //~^ ERROR: `^` is not the exponentiation operator + //~^ suspicious_xor_used_as_pow + let _ = 5i32 ^ 8i32; - //~^ ERROR: `^` is not the exponentiation operator + //~^ suspicious_xor_used_as_pow + let _ = 2i32 ^ 32i32; - //~^ ERROR: `^` is not the exponentiation operator + //~^ suspicious_xor_used_as_pow + macro_test_inside!(); // Should not warn: diff --git a/tests/ui/suspicious_xor_used_as_pow.stderr b/tests/ui/suspicious_xor_used_as_pow.stderr index 43b03676b1db..3fb3b4a34e53 100644 --- a/tests/ui/suspicious_xor_used_as_pow.stderr +++ b/tests/ui/suspicious_xor_used_as_pow.stderr @@ -1,5 +1,5 @@ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:19:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:20:13 | LL | let _ = 2 ^ 5; | ^^^^^ @@ -12,7 +12,7 @@ LL | let _ = 2.pow(5); | ~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:22:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:24:13 | LL | let _ = 2i32 ^ 9i32; | ^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = 2i32.pow(9i32); | ~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:24:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:27:13 | LL | let _ = 2i32 ^ 2i32; | ^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = 2i32.pow(2i32); | ~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:26:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:30:13 | LL | let _ = 50i32 ^ 3i32; | ^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _ = 50i32.pow(3i32); | ~~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:28:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:33:13 | LL | let _ = 5i32 ^ 8i32; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _ = 5i32.pow(8i32); | ~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:30:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:36:13 | LL | let _ = 2i32 ^ 32i32; | ^^^^^^^^^^^^ diff --git a/tests/ui/swap.rs b/tests/ui/swap.rs index c9ad77629290..51af55ecd27c 100644 --- a/tests/ui/swap.rs +++ b/tests/ui/swap.rs @@ -26,6 +26,7 @@ fn field() { let mut bar = Bar { a: 1, b: 2 }; let temp = bar.a; + //~^ manual_swap bar.a = bar.b; bar.b = temp; @@ -38,6 +39,7 @@ fn field() { fn array() { let mut foo = [1, 2]; let temp = foo[0]; + //~^ manual_swap foo[0] = foo[1]; foo[1] = temp; @@ -47,6 +49,7 @@ fn array() { fn slice() { let foo = &mut [1, 2]; let temp = foo[0]; + //~^ manual_swap foo[0] = foo[1]; foo[1] = temp; @@ -66,6 +69,7 @@ fn unswappable_slice() { fn vec() { let mut foo = vec![1, 2]; let temp = foo[0]; + //~^ manual_swap foo[0] = foo[1]; foo[1] = temp; @@ -77,6 +81,7 @@ fn xor_swap_locals() { let mut a = 0; let mut b = 1; a ^= b; + //~^ manual_swap b ^= a; a ^= b; } @@ -85,6 +90,7 @@ fn xor_field_swap() { // This is an xor-based swap of fields in a struct. let mut bar = Bar { a: 0, b: 1 }; bar.a ^= bar.b; + //~^ manual_swap bar.b ^= bar.a; bar.a ^= bar.b; } @@ -93,6 +99,7 @@ fn xor_slice_swap() { // This is an xor-based swap of a slice let foo = &mut [1, 2]; foo[0] ^= foo[1]; + //~^ manual_swap foo[1] ^= foo[0]; foo[0] ^= foo[1]; } @@ -122,6 +129,7 @@ fn distinct_slice() { let foo = &mut [vec![1, 2], vec![3, 4]]; let bar = &mut [vec![1, 2], vec![3, 4]]; let temp = foo[0][1]; + //~^ manual_swap foo[0][1] = bar[1][0]; bar[1][0] = temp; } @@ -133,31 +141,38 @@ fn main() { let mut b = 1337; a = b; + //~^ almost_swapped b = a; ; let t = a; + //~^ manual_swap a = b; b = t; let mut c = Foo(42); c.0 = a; + //~^ almost_swapped a = c.0; ; let t = c.0; + //~^ manual_swap c.0 = a; a = t; let a = b; + //~^ almost_swapped let b = a; let mut c = 1; let mut d = 2; d = c; + //~^ almost_swapped c = d; let mut b = 1; let a = b; + //~^ almost_swapped b = a; let b = 1; @@ -171,6 +186,7 @@ fn main() { let mut a = 2; let t = b; + //~^ manual_swap b = a; a = t; } @@ -206,6 +222,7 @@ fn issue_8154() { let mut s = &mut s; let s = S3(&mut s); let t = s.0.x; + //~^ manual_swap s.0.x = s.0.y; s.0.y = t; } diff --git a/tests/ui/swap.stderr b/tests/ui/swap.stderr index fad356782479..15f7566d5896 100644 --- a/tests/ui/swap.stderr +++ b/tests/ui/swap.stderr @@ -2,6 +2,7 @@ error: this looks like you are swapping `bar.a` and `bar.b` manually --> tests/ui/swap.rs:28:5 | LL | / let temp = bar.a; +LL | | LL | | bar.a = bar.b; LL | | bar.b = temp; | |_________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);` @@ -11,57 +12,64 @@ LL | | bar.b = temp; = help: to override `-D warnings` add `#[allow(clippy::manual_swap)]` error: this looks like you are swapping elements of `foo` manually - --> tests/ui/swap.rs:40:5 + --> tests/ui/swap.rs:41:5 | LL | / let temp = foo[0]; +LL | | LL | | foo[0] = foo[1]; LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> tests/ui/swap.rs:49:5 + --> tests/ui/swap.rs:51:5 | LL | / let temp = foo[0]; +LL | | LL | | foo[0] = foo[1]; LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> tests/ui/swap.rs:68:5 + --> tests/ui/swap.rs:71:5 | LL | / let temp = foo[0]; +LL | | LL | | foo[0] = foo[1]; LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `a` and `b` manually - --> tests/ui/swap.rs:79:5 + --> tests/ui/swap.rs:83:5 | LL | / a ^= b; +LL | | LL | | b ^= a; LL | | a ^= b; | |___________^ help: try: `std::mem::swap(&mut a, &mut b);` error: this looks like you are swapping `bar.a` and `bar.b` manually - --> tests/ui/swap.rs:87:5 + --> tests/ui/swap.rs:92:5 | LL | / bar.a ^= bar.b; +LL | | LL | | bar.b ^= bar.a; LL | | bar.a ^= bar.b; | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);` error: this looks like you are swapping elements of `foo` manually - --> tests/ui/swap.rs:95:5 + --> tests/ui/swap.rs:101:5 | LL | / foo[0] ^= foo[1]; +LL | | LL | | foo[1] ^= foo[0]; LL | | foo[0] ^= foo[1]; | |_____________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually - --> tests/ui/swap.rs:124:5 + --> tests/ui/swap.rs:131:5 | LL | / let temp = foo[0][1]; +LL | | LL | | foo[0][1] = bar[1][0]; LL | | bar[1][0] = temp; | |_____________________^ help: try: `std::mem::swap(&mut foo[0][1], &mut bar[1][0]);` @@ -69,10 +77,11 @@ LL | | bar[1][0] = temp; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `a` and `b` manually - --> tests/ui/swap.rs:138:7 + --> tests/ui/swap.rs:147:7 | LL | ; let t = a; | _______^ +LL | | LL | | a = b; LL | | b = t; | |__________^ help: try: `std::mem::swap(&mut a, &mut b);` @@ -80,10 +89,11 @@ LL | | b = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `c.0` and `a` manually - --> tests/ui/swap.rs:147:7 + --> tests/ui/swap.rs:158:7 | LL | ; let t = c.0; | _______^ +LL | | LL | | c.0 = a; LL | | a = t; | |__________^ help: try: `std::mem::swap(&mut c.0, &mut a);` @@ -91,9 +101,10 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `b` and `a` manually - --> tests/ui/swap.rs:173:5 + --> tests/ui/swap.rs:188:5 | LL | / let t = b; +LL | | LL | | b = a; LL | | a = t; | |__________^ help: try: `std::mem::swap(&mut b, &mut a);` @@ -101,9 +112,10 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> tests/ui/swap.rs:135:5 + --> tests/ui/swap.rs:143:5 | LL | / a = b; +LL | | LL | | b = a; | |_________^ help: try: `std::mem::swap(&mut a, &mut b)` | @@ -112,45 +124,50 @@ LL | | b = a; = help: to override `-D warnings` add `#[allow(clippy::almost_swapped)]` error: this looks like you are trying to swap `c.0` and `a` - --> tests/ui/swap.rs:144:5 + --> tests/ui/swap.rs:154:5 | LL | / c.0 = a; +LL | | LL | | a = c.0; | |___________^ help: try: `std::mem::swap(&mut c.0, &mut a)` | = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> tests/ui/swap.rs:151:5 + --> tests/ui/swap.rs:163:5 | LL | / let a = b; +LL | | LL | | let b = a; | |_____________^ help: try: `std::mem::swap(&mut a, &mut b)` | = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `d` and `c` - --> tests/ui/swap.rs:156:5 + --> tests/ui/swap.rs:169:5 | LL | / d = c; +LL | | LL | | c = d; | |_________^ help: try: `std::mem::swap(&mut d, &mut c)` | = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> tests/ui/swap.rs:160:5 + --> tests/ui/swap.rs:174:5 | LL | / let a = b; +LL | | LL | | b = a; | |_________^ help: try: `std::mem::swap(&mut a, &mut b)` | = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `s.0.x` and `s.0.y` manually - --> tests/ui/swap.rs:208:5 + --> tests/ui/swap.rs:224:5 | LL | / let t = s.0.x; +LL | | LL | | s.0.x = s.0.y; LL | | s.0.y = t; | |______________^ help: try: `std::mem::swap(&mut s.0.x, &mut s.0.y);` diff --git a/tests/ui/swap_ptr_to_ref.fixed b/tests/ui/swap_ptr_to_ref.fixed index 599bb0e80443..ec46368a95ae 100644 --- a/tests/ui/swap_ptr_to_ref.fixed +++ b/tests/ui/swap_ptr_to_ref.fixed @@ -9,9 +9,13 @@ fn main() { unsafe { core::ptr::swap(y, z); + //~^ swap_ptr_to_ref core::ptr::swap(y, &mut x); + //~^ swap_ptr_to_ref core::ptr::swap(&mut x, y); + //~^ swap_ptr_to_ref core::ptr::swap(addr_of_mut!(x), addr_of_mut!(x)); + //~^ swap_ptr_to_ref } let y = &mut x; diff --git a/tests/ui/swap_ptr_to_ref.rs b/tests/ui/swap_ptr_to_ref.rs index 3a8a8daefddc..6a903ddb006d 100644 --- a/tests/ui/swap_ptr_to_ref.rs +++ b/tests/ui/swap_ptr_to_ref.rs @@ -9,9 +9,13 @@ fn main() { unsafe { core::mem::swap(&mut *y, &mut *z); + //~^ swap_ptr_to_ref core::mem::swap(&mut *y, &mut x); + //~^ swap_ptr_to_ref core::mem::swap(&mut x, &mut *y); + //~^ swap_ptr_to_ref core::mem::swap(&mut *addr_of_mut!(x), &mut *addr_of_mut!(x)); + //~^ swap_ptr_to_ref } let y = &mut x; diff --git a/tests/ui/swap_ptr_to_ref.stderr b/tests/ui/swap_ptr_to_ref.stderr index 019c2f91f0e9..6b851901f82e 100644 --- a/tests/ui/swap_ptr_to_ref.stderr +++ b/tests/ui/swap_ptr_to_ref.stderr @@ -8,19 +8,19 @@ LL | core::mem::swap(&mut *y, &mut *z); = help: to override `-D warnings` add `#[allow(clippy::swap_ptr_to_ref)]` error: call to `core::mem::swap` with a parameter derived from a raw pointer - --> tests/ui/swap_ptr_to_ref.rs:12:9 + --> tests/ui/swap_ptr_to_ref.rs:13:9 | LL | core::mem::swap(&mut *y, &mut x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(y, &mut x)` error: call to `core::mem::swap` with a parameter derived from a raw pointer - --> tests/ui/swap_ptr_to_ref.rs:13:9 + --> tests/ui/swap_ptr_to_ref.rs:15:9 | LL | core::mem::swap(&mut x, &mut *y); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(&mut x, y)` error: call to `core::mem::swap` with a parameter derived from a raw pointer - --> tests/ui/swap_ptr_to_ref.rs:14:9 + --> tests/ui/swap_ptr_to_ref.rs:17:9 | LL | core::mem::swap(&mut *addr_of_mut!(x), &mut *addr_of_mut!(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(addr_of_mut!(x), addr_of_mut!(x))` diff --git a/tests/ui/swap_ptr_to_ref_unfixable.rs b/tests/ui/swap_ptr_to_ref_unfixable.rs index 08e56a5d01b2..9fe5925214a4 100644 --- a/tests/ui/swap_ptr_to_ref_unfixable.rs +++ b/tests/ui/swap_ptr_to_ref_unfixable.rs @@ -12,11 +12,14 @@ fn main() { unsafe { core::mem::swap(addr_of_mut_to_ref!(x), &mut *y); - //~^ ERROR: call to `core::mem::swap` with a parameter derived from a raw pointer - //~| NOTE: `-D clippy::swap-ptr-to-ref` implied by `-D warnings` + //~^ swap_ptr_to_ref + + core::mem::swap(&mut *y, addr_of_mut_to_ref!(x)); - //~^ ERROR: call to `core::mem::swap` with a parameter derived from a raw pointer + //~^ swap_ptr_to_ref + core::mem::swap(addr_of_mut_to_ref!(x), addr_of_mut_to_ref!(x)); - //~^ ERROR: call to `core::mem::swap` with a parameter derived from a raw pointer + //~^ swap_ptr_to_ref + } } diff --git a/tests/ui/swap_ptr_to_ref_unfixable.stderr b/tests/ui/swap_ptr_to_ref_unfixable.stderr index 8a0352049483..f4c7c8db15ac 100644 --- a/tests/ui/swap_ptr_to_ref_unfixable.stderr +++ b/tests/ui/swap_ptr_to_ref_unfixable.stderr @@ -8,13 +8,13 @@ LL | core::mem::swap(addr_of_mut_to_ref!(x), &mut *y); = help: to override `-D warnings` add `#[allow(clippy::swap_ptr_to_ref)]` error: call to `core::mem::swap` with a parameter derived from a raw pointer - --> tests/ui/swap_ptr_to_ref_unfixable.rs:17:9 + --> tests/ui/swap_ptr_to_ref_unfixable.rs:18:9 | LL | core::mem::swap(&mut *y, addr_of_mut_to_ref!(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: call to `core::mem::swap` with a parameter derived from a raw pointer - --> tests/ui/swap_ptr_to_ref_unfixable.rs:19:9 + --> tests/ui/swap_ptr_to_ref_unfixable.rs:21:9 | LL | core::mem::swap(addr_of_mut_to_ref!(x), addr_of_mut_to_ref!(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/tabs_in_doc_comments.fixed b/tests/ui/tabs_in_doc_comments.fixed index 3536c1746df3..ed96cbaa6d3c 100644 --- a/tests/ui/tabs_in_doc_comments.fixed +++ b/tests/ui/tabs_in_doc_comments.fixed @@ -3,15 +3,23 @@ /// /// Struct to hold two strings: /// - first one +//~^ tabs_in_doc_comments +//~| tabs_in_doc_comments /// - second one +//~^ tabs_in_doc_comments +//~| tabs_in_doc_comments pub struct DoubleString { /// /// - First String: + //~^ tabs_in_doc_comments /// - needs to be inside here + //~^ tabs_in_doc_comments first_string: String, /// /// - Second String: + //~^ tabs_in_doc_comments /// - needs to be inside here + //~^ tabs_in_doc_comments second_string: String, } diff --git a/tests/ui/tabs_in_doc_comments.rs b/tests/ui/tabs_in_doc_comments.rs index 033a685066e1..73d4d92a862e 100644 --- a/tests/ui/tabs_in_doc_comments.rs +++ b/tests/ui/tabs_in_doc_comments.rs @@ -3,15 +3,23 @@ /// /// Struct to hold two strings: /// - first one +//~^ tabs_in_doc_comments +//~| tabs_in_doc_comments /// - second one +//~^ tabs_in_doc_comments +//~| tabs_in_doc_comments pub struct DoubleString { /// /// - First String: + //~^ tabs_in_doc_comments /// - needs to be inside here + //~^ tabs_in_doc_comments first_string: String, /// /// - Second String: + //~^ tabs_in_doc_comments /// - needs to be inside here + //~^ tabs_in_doc_comments second_string: String, } diff --git a/tests/ui/tabs_in_doc_comments.stderr b/tests/ui/tabs_in_doc_comments.stderr index f8d30b728e58..331bccaca92d 100644 --- a/tests/ui/tabs_in_doc_comments.stderr +++ b/tests/ui/tabs_in_doc_comments.stderr @@ -14,37 +14,37 @@ LL | /// - first one | ^^^^^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:6:5 + --> tests/ui/tabs_in_doc_comments.rs:8:5 | LL | /// - second one | ^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:6:14 + --> tests/ui/tabs_in_doc_comments.rs:8:14 | LL | /// - second one | ^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:9:9 + --> tests/ui/tabs_in_doc_comments.rs:13:9 | LL | /// - First String: | ^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:10:9 + --> tests/ui/tabs_in_doc_comments.rs:15:9 | LL | /// - needs to be inside here | ^^^^^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:13:9 + --> tests/ui/tabs_in_doc_comments.rs:19:9 | LL | /// - Second String: | ^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:14:9 + --> tests/ui/tabs_in_doc_comments.rs:21:9 | LL | /// - needs to be inside here | ^^^^^^^^ help: consider using four spaces per tab diff --git a/tests/ui/temporary_assignment.rs b/tests/ui/temporary_assignment.rs index d269f91b9fa8..52a9de4ddffd 100644 --- a/tests/ui/temporary_assignment.rs +++ b/tests/ui/temporary_assignment.rs @@ -46,18 +46,22 @@ fn main() { let mut t = (0, 0); Struct { field: 0 }.field = 1; - //~^ ERROR: assignment to temporary - //~| NOTE: `-D clippy::temporary-assignment` implied by `-D warnings` + //~^ temporary_assignment + + MultiStruct { - //~^ ERROR: assignment to temporary + //~^ temporary_assignment + structure: Struct { field: 0 }, } .structure .field = 1; ArrayStruct { array: [0] }.array[0] = 1; - //~^ ERROR: assignment to temporary + //~^ temporary_assignment + (0, 0).0 = 1; - //~^ ERROR: assignment to temporary + //~^ temporary_assignment + // no error s.field = 1; diff --git a/tests/ui/temporary_assignment.stderr b/tests/ui/temporary_assignment.stderr index 7e6529cb2134..561f3d6f1ab9 100644 --- a/tests/ui/temporary_assignment.stderr +++ b/tests/ui/temporary_assignment.stderr @@ -8,23 +8,25 @@ LL | Struct { field: 0 }.field = 1; = help: to override `-D warnings` add `#[allow(clippy::temporary_assignment)]` error: assignment to temporary - --> tests/ui/temporary_assignment.rs:51:5 + --> tests/ui/temporary_assignment.rs:52:5 | LL | / MultiStruct { LL | | +LL | | LL | | structure: Struct { field: 0 }, -... | +LL | | } +LL | | .structure LL | | .field = 1; | |______________^ error: assignment to temporary - --> tests/ui/temporary_assignment.rs:57:5 + --> tests/ui/temporary_assignment.rs:59:5 | LL | ArrayStruct { array: [0] }.array[0] = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: assignment to temporary - --> tests/ui/temporary_assignment.rs:59:5 + --> tests/ui/temporary_assignment.rs:62:5 | LL | (0, 0).0 = 1; | ^^^^^^^^^^^^ diff --git a/tests/ui/test_attr_in_doctest.rs b/tests/ui/test_attr_in_doctest.rs index 4c904f7a09ac..8ca33c677f88 100644 --- a/tests/ui/test_attr_in_doctest.rs +++ b/tests/ui/test_attr_in_doctest.rs @@ -4,6 +4,7 @@ /// /// ``` /// #[test] +//~^ test_attr_in_doctest /// fn should_be_linted() { /// assert_eq!(1, 1); /// } @@ -14,12 +15,14 @@ /// /// ``` /// #[test] +//~^ test_attr_in_doctest /// fn should_also_be_linted() { /// #[cfg(test)] /// assert!(true); /// } /// /// #[test] +//~^ test_attr_in_doctest /// fn should_be_linted_too() { /// assert_eq!("#[test]", " /// #[test] diff --git a/tests/ui/test_attr_in_doctest.stderr b/tests/ui/test_attr_in_doctest.stderr index f950455f2908..b8de466e9698 100644 --- a/tests/ui/test_attr_in_doctest.stderr +++ b/tests/ui/test_attr_in_doctest.stderr @@ -3,6 +3,7 @@ error: unit tests in doctest are not executed | LL | /// #[test] | _____^ +LL | | LL | | /// fn should_be_linted() { | |_______________________^ | @@ -10,18 +11,20 @@ LL | | /// fn should_be_linted() { = help: to override `-D warnings` add `#[allow(clippy::test_attr_in_doctest)]` error: unit tests in doctest are not executed - --> tests/ui/test_attr_in_doctest.rs:16:5 + --> tests/ui/test_attr_in_doctest.rs:17:5 | LL | /// #[test] | _____^ +LL | | LL | | /// fn should_also_be_linted() { | |____________________________^ error: unit tests in doctest are not executed - --> tests/ui/test_attr_in_doctest.rs:22:5 + --> tests/ui/test_attr_in_doctest.rs:24:5 | LL | /// #[test] | _____^ +LL | | LL | | /// fn should_be_linted_too() { | |___________________________^ diff --git a/tests/ui/tests_outside_test_module.rs b/tests/ui/tests_outside_test_module.rs index 0abde4a57bf7..35126c46af08 100644 --- a/tests/ui/tests_outside_test_module.rs +++ b/tests/ui/tests_outside_test_module.rs @@ -1,3 +1,4 @@ +//@require-annotations-for-level: WARN #![allow(unused)] #![warn(clippy::tests_outside_test_module)] diff --git a/tests/ui/tests_outside_test_module.stderr b/tests/ui/tests_outside_test_module.stderr index 09feae6bf2aa..8602a63cc7a4 100644 --- a/tests/ui/tests_outside_test_module.stderr +++ b/tests/ui/tests_outside_test_module.stderr @@ -1,5 +1,5 @@ error: this function marked with #[test] is outside a #[cfg(test)] module - --> tests/ui/tests_outside_test_module.rs:10:1 + --> tests/ui/tests_outside_test_module.rs:11:1 | LL | fn my_test() {} | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/to_digit_is_some.fixed b/tests/ui/to_digit_is_some.fixed index 2ef4c05289fd..627d54c5f738 100644 --- a/tests/ui/to_digit_is_some.fixed +++ b/tests/ui/to_digit_is_some.fixed @@ -5,5 +5,7 @@ fn main() { let d = &c; let _ = d.is_digit(8); + //~^ to_digit_is_some let _ = char::is_digit(c, 8); + //~^ to_digit_is_some } diff --git a/tests/ui/to_digit_is_some.rs b/tests/ui/to_digit_is_some.rs index 54d9545809c5..d4eccc9931f1 100644 --- a/tests/ui/to_digit_is_some.rs +++ b/tests/ui/to_digit_is_some.rs @@ -5,5 +5,7 @@ fn main() { let d = &c; let _ = d.to_digit(8).is_some(); + //~^ to_digit_is_some let _ = char::to_digit(c, 8).is_some(); + //~^ to_digit_is_some } diff --git a/tests/ui/to_digit_is_some.stderr b/tests/ui/to_digit_is_some.stderr index e44106b2e188..f41382a60d53 100644 --- a/tests/ui/to_digit_is_some.stderr +++ b/tests/ui/to_digit_is_some.stderr @@ -8,7 +8,7 @@ LL | let _ = d.to_digit(8).is_some(); = help: to override `-D warnings` add `#[allow(clippy::to_digit_is_some)]` error: use of `.to_digit(..).is_some()` - --> tests/ui/to_digit_is_some.rs:8:13 + --> tests/ui/to_digit_is_some.rs:9:13 | LL | let _ = char::to_digit(c, 8).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `char::is_digit(c, 8)` diff --git a/tests/ui/to_string_in_format_args_incremental.fixed b/tests/ui/to_string_in_format_args_incremental.fixed index 1f7895796366..2a29580e390c 100644 --- a/tests/ui/to_string_in_format_args_incremental.fixed +++ b/tests/ui/to_string_in_format_args_incremental.fixed @@ -5,4 +5,5 @@ fn main() { let s = "Hello, world!"; println!("{}", s); + //~^ to_string_in_format_args } diff --git a/tests/ui/to_string_in_format_args_incremental.rs b/tests/ui/to_string_in_format_args_incremental.rs index 514febe8c92d..18ca82976a40 100644 --- a/tests/ui/to_string_in_format_args_incremental.rs +++ b/tests/ui/to_string_in_format_args_incremental.rs @@ -5,4 +5,5 @@ fn main() { let s = "Hello, world!"; println!("{}", s.to_string()); + //~^ to_string_in_format_args } diff --git a/tests/ui/to_string_trait_impl.rs b/tests/ui/to_string_trait_impl.rs index 7be9f7994f08..f8195e55f9a8 100644 --- a/tests/ui/to_string_trait_impl.rs +++ b/tests/ui/to_string_trait_impl.rs @@ -9,6 +9,7 @@ struct Point { } impl ToString for Point { +//~^ to_string_trait_impl fn to_string(&self) -> String { format!("({}, {})", self.x, self.y) } diff --git a/tests/ui/to_string_trait_impl.stderr b/tests/ui/to_string_trait_impl.stderr index fe8afc215f0c..b24dfa39e011 100644 --- a/tests/ui/to_string_trait_impl.stderr +++ b/tests/ui/to_string_trait_impl.stderr @@ -2,6 +2,7 @@ error: direct implementation of `ToString` --> tests/ui/to_string_trait_impl.rs:11:1 | LL | / impl ToString for Point { +LL | | LL | | fn to_string(&self) -> String { LL | | format!("({}, {})", self.x, self.y) LL | | } diff --git a/tests/ui/too_long_first_doc_paragraph-fix.fixed b/tests/ui/too_long_first_doc_paragraph-fix.fixed index d4a0cdf3447f..7075aefd50b6 100644 --- a/tests/ui/too_long_first_doc_paragraph-fix.fixed +++ b/tests/ui/too_long_first_doc_paragraph-fix.fixed @@ -1,7 +1,9 @@ #![warn(clippy::too_long_first_doc_paragraph)] /// A very short summary. +//~^ too_long_first_doc_paragraph /// +//~^ too_long_first_doc_paragraph /// A much longer explanation that goes into a lot more detail about /// how the thing works, possibly with doclinks and so one, /// and probably spanning a many rows. Blablabla, it needs to be over diff --git a/tests/ui/too_long_first_doc_paragraph-fix.rs b/tests/ui/too_long_first_doc_paragraph-fix.rs index 5a3b6c42a328..844417d741ef 100644 --- a/tests/ui/too_long_first_doc_paragraph-fix.rs +++ b/tests/ui/too_long_first_doc_paragraph-fix.rs @@ -1,6 +1,7 @@ #![warn(clippy::too_long_first_doc_paragraph)] /// A very short summary. +//~^ too_long_first_doc_paragraph /// A much longer explanation that goes into a lot more detail about /// how the thing works, possibly with doclinks and so one, /// and probably spanning a many rows. Blablabla, it needs to be over diff --git a/tests/ui/too_long_first_doc_paragraph-fix.stderr b/tests/ui/too_long_first_doc_paragraph-fix.stderr index 6ef333f0cfd2..d6255ea2029b 100644 --- a/tests/ui/too_long_first_doc_paragraph-fix.stderr +++ b/tests/ui/too_long_first_doc_paragraph-fix.stderr @@ -2,6 +2,7 @@ error: first doc comment paragraph is too long --> tests/ui/too_long_first_doc_paragraph-fix.rs:3:1 | LL | / /// A very short summary. +LL | | LL | | /// A much longer explanation that goes into a lot more detail about LL | | /// how the thing works, possibly with doclinks and so one, LL | | /// and probably spanning a many rows. Blablabla, it needs to be over @@ -13,7 +14,9 @@ LL | | /// 200 characters so I needed to write something longeeeeeeer. help: add an empty line | LL ~ /// A very short summary. +LL + LL + /// +LL + | error: aborting due to 1 previous error diff --git a/tests/ui/too_long_first_doc_paragraph.rs b/tests/ui/too_long_first_doc_paragraph.rs index 7d0a37cde46d..2321e228866c 100644 --- a/tests/ui/too_long_first_doc_paragraph.rs +++ b/tests/ui/too_long_first_doc_paragraph.rs @@ -6,6 +6,7 @@ pub mod foo { // in foo.rs //! A very short summary. + //~^ too_long_first_doc_paragraph //! A much longer explanation that goes into a lot more detail about //! how the thing works, possibly with doclinks and so one, //! and probably spanning a many rows. Blablabla, it needs to be over @@ -13,6 +14,7 @@ pub mod foo { } /// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +//~^ too_long_first_doc_paragraph /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, /// gravida non lacinia at, rhoncus eu lacus. pub struct Bar; @@ -34,6 +36,7 @@ pub enum Enum { } /// Lorem +//~^ too_long_first_doc_paragraph /// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, /// gravida non lacinia at, rhoncus eu lacus. diff --git a/tests/ui/too_long_first_doc_paragraph.stderr b/tests/ui/too_long_first_doc_paragraph.stderr index 95f42349b9b3..2d4abaa9d63c 100644 --- a/tests/ui/too_long_first_doc_paragraph.stderr +++ b/tests/ui/too_long_first_doc_paragraph.stderr @@ -2,6 +2,7 @@ error: first doc comment paragraph is too long --> tests/ui/too_long_first_doc_paragraph.rs:8:5 | LL | / //! A very short summary. +LL | | LL | | //! A much longer explanation that goes into a lot more detail about LL | | //! how the thing works, possibly with doclinks and so one, LL | | //! and probably spanning a many rows. Blablabla, it needs to be over @@ -13,22 +14,26 @@ LL | | //! 200 characters so I needed to write something longeeeeeeer. help: add an empty line | LL ~ //! A very short summary. +LL + LL + //! +LL + LL ~ //! A much longer explanation that goes into a lot more detail about | error: first doc comment paragraph is too long - --> tests/ui/too_long_first_doc_paragraph.rs:15:1 + --> tests/ui/too_long_first_doc_paragraph.rs:16:1 | LL | / /// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +LL | | LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, LL | | /// gravida non lacinia at, rhoncus eu lacus. | |_^ error: first doc comment paragraph is too long - --> tests/ui/too_long_first_doc_paragraph.rs:36:1 + --> tests/ui/too_long_first_doc_paragraph.rs:38:1 | LL | / /// Lorem +LL | | LL | | /// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, LL | | /// gravida non lacinia at, rhoncus eu lacus. diff --git a/tests/ui/toplevel_ref_arg.fixed b/tests/ui/toplevel_ref_arg.fixed index 3eb47a5b5fd6..11d4eaaefda0 100644 --- a/tests/ui/toplevel_ref_arg.fixed +++ b/tests/ui/toplevel_ref_arg.fixed @@ -12,17 +12,22 @@ fn main() { y(1u8); let _x = &1; + //~^ toplevel_ref_arg let _y: &(&_, u8) = &(&1, 2); + //~^ toplevel_ref_arg let _z = &(1 + 2); + //~^ toplevel_ref_arg let _z = &mut (1 + 2); + //~^ toplevel_ref_arg let (ref x, _) = (1, 2); // ok, not top level println!("The answer is {}.", x); let _x = &vec![1, 2, 3]; + //~^ toplevel_ref_arg // Make sure that allowing the lint works #[allow(clippy::toplevel_ref_arg)] @@ -33,6 +38,7 @@ fn main() { // lint in macro inline!(let _y = &42;); + //~^ toplevel_ref_arg // do not lint in external macro external!(let ref _y = 42;); diff --git a/tests/ui/toplevel_ref_arg.rs b/tests/ui/toplevel_ref_arg.rs index cd731387de97..957dd542f5a9 100644 --- a/tests/ui/toplevel_ref_arg.rs +++ b/tests/ui/toplevel_ref_arg.rs @@ -12,17 +12,22 @@ fn main() { y(1u8); let ref _x = 1; + //~^ toplevel_ref_arg let ref _y: (&_, u8) = (&1, 2); + //~^ toplevel_ref_arg let ref _z = 1 + 2; + //~^ toplevel_ref_arg let ref mut _z = 1 + 2; + //~^ toplevel_ref_arg let (ref x, _) = (1, 2); // ok, not top level println!("The answer is {}.", x); let ref _x = vec![1, 2, 3]; + //~^ toplevel_ref_arg // Make sure that allowing the lint works #[allow(clippy::toplevel_ref_arg)] @@ -33,6 +38,7 @@ fn main() { // lint in macro inline!(let ref _y = 42;); + //~^ toplevel_ref_arg // do not lint in external macro external!(let ref _y = 42;); diff --git a/tests/ui/toplevel_ref_arg.stderr b/tests/ui/toplevel_ref_arg.stderr index 61f0fd4a6cd2..42e77f01495b 100644 --- a/tests/ui/toplevel_ref_arg.stderr +++ b/tests/ui/toplevel_ref_arg.stderr @@ -8,31 +8,31 @@ LL | let ref _x = 1; = help: to override `-D warnings` add `#[allow(clippy::toplevel_ref_arg)]` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> tests/ui/toplevel_ref_arg.rs:16:9 + --> tests/ui/toplevel_ref_arg.rs:17:9 | LL | let ref _y: (&_, u8) = (&1, 2); | ----^^^^^^--------------------- help: try: `let _y: &(&_, u8) = &(&1, 2);` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> tests/ui/toplevel_ref_arg.rs:18:9 + --> tests/ui/toplevel_ref_arg.rs:20:9 | LL | let ref _z = 1 + 2; | ----^^^^^^--------- help: try: `let _z = &(1 + 2);` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> tests/ui/toplevel_ref_arg.rs:20:9 + --> tests/ui/toplevel_ref_arg.rs:23:9 | LL | let ref mut _z = 1 + 2; | ----^^^^^^^^^^--------- help: try: `let _z = &mut (1 + 2);` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> tests/ui/toplevel_ref_arg.rs:25:9 + --> tests/ui/toplevel_ref_arg.rs:29:9 | LL | let ref _x = vec![1, 2, 3]; | ----^^^^^^----------------- help: try: `let _x = &vec![1, 2, 3];` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> tests/ui/toplevel_ref_arg.rs:35:17 + --> tests/ui/toplevel_ref_arg.rs:40:17 | LL | inline!(let ref _y = 42;); | ----^^^^^^------ help: try: `let _y = &42;` diff --git a/tests/ui/toplevel_ref_arg_non_rustfix.rs b/tests/ui/toplevel_ref_arg_non_rustfix.rs index 8aaf47b1bd0c..729f528a8e59 100644 --- a/tests/ui/toplevel_ref_arg_non_rustfix.rs +++ b/tests/ui/toplevel_ref_arg_non_rustfix.rs @@ -7,6 +7,7 @@ extern crate proc_macros; use proc_macros::{external, inline_macros}; fn the_answer(ref mut x: u8) { +//~^ toplevel_ref_arg *x = 42; } @@ -18,6 +19,7 @@ fn main() { // lint in macro inline! { fn fun_example(ref _x: usize) {} + //~^ toplevel_ref_arg } // do not lint in external macro diff --git a/tests/ui/toplevel_ref_arg_non_rustfix.stderr b/tests/ui/toplevel_ref_arg_non_rustfix.stderr index 26166e2fc8da..e17b2536874e 100644 --- a/tests/ui/toplevel_ref_arg_non_rustfix.stderr +++ b/tests/ui/toplevel_ref_arg_non_rustfix.stderr @@ -8,7 +8,7 @@ LL | fn the_answer(ref mut x: u8) { = help: to override `-D warnings` add `#[allow(clippy::toplevel_ref_arg)]` error: `ref` directly on a function parameter does not prevent taking ownership of the passed argument. Consider using a reference type instead - --> tests/ui/toplevel_ref_arg_non_rustfix.rs:20:24 + --> tests/ui/toplevel_ref_arg_non_rustfix.rs:21:24 | LL | fn fun_example(ref _x: usize) {} | ^^^^^^ diff --git a/tests/ui/track-diagnostics.rs b/tests/ui/track-diagnostics.rs index 6ab0bce770e2..723ea23e9a63 100644 --- a/tests/ui/track-diagnostics.rs +++ b/tests/ui/track-diagnostics.rs @@ -7,5 +7,6 @@ struct A; struct B; const S: A = B; +//~^ ERROR: mismatched types fn main() {} diff --git a/tests/ui/trailing_empty_array.rs b/tests/ui/trailing_empty_array.rs index ea3b8ff01afa..2297e645c9e6 100644 --- a/tests/ui/trailing_empty_array.rs +++ b/tests/ui/trailing_empty_array.rs @@ -4,39 +4,45 @@ // Do lint: struct RarelyUseful { - //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + field: i32, last: [usize; 0], } struct OnlyField { - //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + first_and_last: [usize; 0], } struct GenericArrayType { - //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + field: i32, last: [T; 0], } #[must_use] struct OnlyAnotherAttribute { - //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + field: i32, last: [usize; 0], } #[derive(Debug)] struct OnlyADeriveAttribute { - //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + field: i32, last: [usize; 0], } const ZERO: usize = 0; struct ZeroSizedWithConst { - //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + field: i32, last: [usize; ZERO], } @@ -46,7 +52,8 @@ const fn compute_zero() -> usize { (4 + 6) - (2 * 5) } struct ZeroSizedWithConstFunction { - //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + field: i32, last: [usize; compute_zero()], } @@ -55,19 +62,23 @@ const fn compute_zero_from_arg(x: usize) -> usize { x - 1 } struct ZeroSizedWithConstFunction2 { - //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + field: i32, last: [usize; compute_zero_from_arg(1)], } struct ZeroSizedArrayWrapper([usize; 0]); -//~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + struct TupleStruct(i32, [usize; 0]); -//~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + struct LotsOfFields { - //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib +//~^ trailing_empty_array + f1: u32, f2: u32, f3: u32, diff --git a/tests/ui/trailing_empty_array.stderr b/tests/ui/trailing_empty_array.stderr index 7ebff372cf75..424d23d07cdf 100644 --- a/tests/ui/trailing_empty_array.stderr +++ b/tests/ui/trailing_empty_array.stderr @@ -3,6 +3,7 @@ error: trailing zero-sized array in a struct which is not marked with a `repr` a | LL | / struct RarelyUseful { LL | | +LL | | LL | | field: i32, LL | | last: [usize; 0], LL | | } @@ -13,10 +14,11 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::trailing_empty_array)]` error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:12:1 + --> tests/ui/trailing_empty_array.rs:13:1 | LL | / struct OnlyField { LL | | +LL | | LL | | first_and_last: [usize; 0], LL | | } | |_^ @@ -24,10 +26,11 @@ LL | | } = help: consider annotating `OnlyField` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:17:1 + --> tests/ui/trailing_empty_array.rs:19:1 | LL | / struct GenericArrayType { LL | | +LL | | LL | | field: i32, LL | | last: [T; 0], LL | | } @@ -36,10 +39,11 @@ LL | | } = help: consider annotating `GenericArrayType` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:24:1 + --> tests/ui/trailing_empty_array.rs:27:1 | LL | / struct OnlyAnotherAttribute { LL | | +LL | | LL | | field: i32, LL | | last: [usize; 0], LL | | } @@ -48,10 +52,11 @@ LL | | } = help: consider annotating `OnlyAnotherAttribute` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:31:1 + --> tests/ui/trailing_empty_array.rs:35:1 | LL | / struct OnlyADeriveAttribute { LL | | +LL | | LL | | field: i32, LL | | last: [usize; 0], LL | | } @@ -60,10 +65,11 @@ LL | | } = help: consider annotating `OnlyADeriveAttribute` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:38:1 + --> tests/ui/trailing_empty_array.rs:43:1 | LL | / struct ZeroSizedWithConst { LL | | +LL | | LL | | field: i32, LL | | last: [usize; ZERO], LL | | } @@ -72,10 +78,11 @@ LL | | } = help: consider annotating `ZeroSizedWithConst` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:48:1 + --> tests/ui/trailing_empty_array.rs:54:1 | LL | / struct ZeroSizedWithConstFunction { LL | | +LL | | LL | | field: i32, LL | | last: [usize; compute_zero()], LL | | } @@ -84,10 +91,11 @@ LL | | } = help: consider annotating `ZeroSizedWithConstFunction` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:57:1 + --> tests/ui/trailing_empty_array.rs:64:1 | LL | / struct ZeroSizedWithConstFunction2 { LL | | +LL | | LL | | field: i32, LL | | last: [usize; compute_zero_from_arg(1)], LL | | } @@ -96,7 +104,7 @@ LL | | } = help: consider annotating `ZeroSizedWithConstFunction2` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:63:1 + --> tests/ui/trailing_empty_array.rs:71:1 | LL | struct ZeroSizedArrayWrapper([usize; 0]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +112,7 @@ LL | struct ZeroSizedArrayWrapper([usize; 0]); = help: consider annotating `ZeroSizedArrayWrapper` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:66:1 + --> tests/ui/trailing_empty_array.rs:75:1 | LL | struct TupleStruct(i32, [usize; 0]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,12 +120,12 @@ LL | struct TupleStruct(i32, [usize; 0]); = help: consider annotating `TupleStruct` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:69:1 + --> tests/ui/trailing_empty_array.rs:79:1 | LL | / struct LotsOfFields { LL | | +LL | | LL | | f1: u32, -LL | | f2: u32, ... | LL | | last: [usize; 0], LL | | } diff --git a/tests/ui/trailing_zeros.fixed b/tests/ui/trailing_zeros.fixed index f7de976f1e00..273dd5d70646 100644 --- a/tests/ui/trailing_zeros.fixed +++ b/tests/ui/trailing_zeros.fixed @@ -4,10 +4,12 @@ fn main() { let x: i32 = 42; let _ = x.trailing_zeros() >= 4; - //~^ ERROR: bit mask could be simplified with a call to `trailing_zeros` - //~| NOTE: `-D clippy::verbose-bit-mask` implied by `-D warnings` + //~^ verbose_bit_mask + + let _ = x.trailing_zeros() >= 5; - //~^ ERROR: bit mask could be simplified with a call to `trailing_zeros` + //~^ verbose_bit_mask + let _ = x & 0b1_1010 == 0; // do not lint let _ = x & 1 == 0; // do not lint } diff --git a/tests/ui/trailing_zeros.rs b/tests/ui/trailing_zeros.rs index a05b09233e21..f3fffa7be840 100644 --- a/tests/ui/trailing_zeros.rs +++ b/tests/ui/trailing_zeros.rs @@ -4,10 +4,12 @@ fn main() { let x: i32 = 42; let _ = (x & 0b1111 == 0); - //~^ ERROR: bit mask could be simplified with a call to `trailing_zeros` - //~| NOTE: `-D clippy::verbose-bit-mask` implied by `-D warnings` + //~^ verbose_bit_mask + + let _ = x & 0b1_1111 == 0; - //~^ ERROR: bit mask could be simplified with a call to `trailing_zeros` + //~^ verbose_bit_mask + let _ = x & 0b1_1010 == 0; // do not lint let _ = x & 1 == 0; // do not lint } diff --git a/tests/ui/trailing_zeros.stderr b/tests/ui/trailing_zeros.stderr index 6f3e7aa1d762..4b608e32a587 100644 --- a/tests/ui/trailing_zeros.stderr +++ b/tests/ui/trailing_zeros.stderr @@ -8,7 +8,7 @@ LL | let _ = (x & 0b1111 == 0); = help: to override `-D warnings` add `#[allow(clippy::verbose_bit_mask)]` error: bit mask could be simplified with a call to `trailing_zeros` - --> tests/ui/trailing_zeros.rs:9:13 + --> tests/ui/trailing_zeros.rs:10:13 | LL | let _ = x & 0b1_1111 == 0; | ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 5` diff --git a/tests/ui/trait_duplication_in_bounds.fixed b/tests/ui/trait_duplication_in_bounds.fixed index 708512793d50..afd0f4d77d3e 100644 --- a/tests/ui/trait_duplication_in_bounds.fixed +++ b/tests/ui/trait_duplication_in_bounds.fixed @@ -5,12 +5,14 @@ use std::any::Any; fn bad_foo(arg0: T, argo1: U) { +//~^ trait_duplication_in_bounds unimplemented!(); } fn bad_bar(arg0: T, arg1: U) where T: Clone + Copy, + //~^ trait_duplication_in_bounds U: Clone + Copy, { unimplemented!(); @@ -39,6 +41,7 @@ trait GoodSelfWhereClause { } trait BadSelfTraitBound: Clone { +//~^ trait_duplication_in_bounds fn f(); } @@ -46,6 +49,7 @@ trait BadSelfWhereClause { fn f() where Self: Clone; + //~^ trait_duplication_in_bounds } trait GoodTraitBound { @@ -60,6 +64,7 @@ trait GoodWhereClause { } trait BadTraitBound { +//~^ trait_duplication_in_bounds fn f(); } @@ -67,6 +72,7 @@ trait BadWhereClause { fn f() where T: Clone + Copy, + //~^ trait_duplication_in_bounds U: Clone + Copy; } @@ -100,6 +106,7 @@ fn good_generic + GenericTrait>(arg0: T) { } fn bad_generic + GenericTrait>(arg0: T) { +//~^ trait_duplication_in_bounds unimplemented!(); } @@ -108,6 +115,7 @@ mod foo { } fn qualified_path(arg0: T) { +//~^ trait_duplication_in_bounds unimplemented!(); } @@ -116,6 +124,7 @@ fn good_trait_object(arg0: &(dyn Any + Send)) { } fn bad_trait_object(arg0: &(dyn Any + Send)) { +//~^ trait_duplication_in_bounds unimplemented!(); } @@ -165,12 +174,14 @@ const fn const_trait_bounds_good() {} const fn const_trait_bounds_bad() {} //~^ trait_duplication_in_bounds + fn projections() where U: ToOwned, V: ToOwned, T: IntoIterator, //~^ trait_duplication_in_bounds + V: IntoIterator + IntoIterator, { } @@ -193,5 +204,6 @@ fn assoc_const_args() where T: AssocConstTrait, //~^ trait_duplication_in_bounds + { } diff --git a/tests/ui/trait_duplication_in_bounds.rs b/tests/ui/trait_duplication_in_bounds.rs index 12db6b65a7ae..4d417e89bd82 100644 --- a/tests/ui/trait_duplication_in_bounds.rs +++ b/tests/ui/trait_duplication_in_bounds.rs @@ -5,12 +5,14 @@ use std::any::Any; fn bad_foo(arg0: T, argo1: U) { +//~^ trait_duplication_in_bounds unimplemented!(); } fn bad_bar(arg0: T, arg1: U) where T: Clone + Clone + Clone + Copy, + //~^ trait_duplication_in_bounds U: Clone + Copy, { unimplemented!(); @@ -39,6 +41,7 @@ trait GoodSelfWhereClause { } trait BadSelfTraitBound: Clone + Clone + Clone { +//~^ trait_duplication_in_bounds fn f(); } @@ -46,6 +49,7 @@ trait BadSelfWhereClause { fn f() where Self: Clone + Clone + Clone; + //~^ trait_duplication_in_bounds } trait GoodTraitBound { @@ -60,6 +64,7 @@ trait GoodWhereClause { } trait BadTraitBound { +//~^ trait_duplication_in_bounds fn f(); } @@ -67,6 +72,7 @@ trait BadWhereClause { fn f() where T: Clone + Clone + Clone + Copy, + //~^ trait_duplication_in_bounds U: Clone + Copy; } @@ -100,6 +106,7 @@ fn good_generic + GenericTrait>(arg0: T) { } fn bad_generic + GenericTrait + GenericTrait>(arg0: T) { +//~^ trait_duplication_in_bounds unimplemented!(); } @@ -108,6 +115,7 @@ mod foo { } fn qualified_path(arg0: T) { +//~^ trait_duplication_in_bounds unimplemented!(); } @@ -116,6 +124,7 @@ fn good_trait_object(arg0: &(dyn Any + Send)) { } fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { +//~^ trait_duplication_in_bounds unimplemented!(); } @@ -165,12 +174,14 @@ const fn const_trait_bounds_good() {} const fn const_trait_bounds_bad() {} //~^ trait_duplication_in_bounds + fn projections() where U: ToOwned, V: ToOwned, T: IntoIterator + IntoIterator, //~^ trait_duplication_in_bounds + V: IntoIterator + IntoIterator, { } @@ -193,5 +204,6 @@ fn assoc_const_args() where T: AssocConstTrait + AssocConstTrait, //~^ trait_duplication_in_bounds + { } diff --git a/tests/ui/trait_duplication_in_bounds.stderr b/tests/ui/trait_duplication_in_bounds.stderr index 83c06eaccd4e..974dfe538799 100644 --- a/tests/ui/trait_duplication_in_bounds.stderr +++ b/tests/ui/trait_duplication_in_bounds.stderr @@ -11,67 +11,67 @@ LL | #![deny(clippy::trait_duplication_in_bounds)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: these where clauses contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:13:8 + --> tests/ui/trait_duplication_in_bounds.rs:14:8 | LL | T: Clone + Clone + Clone + Copy, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` error: these bounds contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:41:26 + --> tests/ui/trait_duplication_in_bounds.rs:43:26 | LL | trait BadSelfTraitBound: Clone + Clone + Clone { | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone` error: these where clauses contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:48:15 + --> tests/ui/trait_duplication_in_bounds.rs:51:15 | LL | Self: Clone + Clone + Clone; | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone` error: these bounds contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:62:24 + --> tests/ui/trait_duplication_in_bounds.rs:66:24 | LL | trait BadTraitBound { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` error: these where clauses contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:69:12 + --> tests/ui/trait_duplication_in_bounds.rs:74:12 | LL | T: Clone + Clone + Clone + Copy, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` error: these bounds contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:102:19 + --> tests/ui/trait_duplication_in_bounds.rs:108:19 | LL | fn bad_generic + GenericTrait + GenericTrait>(arg0: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `GenericTrait + GenericTrait` error: these bounds contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:110:22 + --> tests/ui/trait_duplication_in_bounds.rs:117:22 | LL | fn qualified_path(arg0: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::clone::Clone + foo::Clone` error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds.rs:118:33 + --> tests/ui/trait_duplication_in_bounds.rs:126:33 | LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { | ^^^^^^^^^^^^^^^^^ help: try: `Any + Send` error: these bounds contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:165:36 + --> tests/ui/trait_duplication_in_bounds.rs:174:36 | LL | const fn const_trait_bounds_bad() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `~const ConstTrait` error: these where clauses contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:172:8 + --> tests/ui/trait_duplication_in_bounds.rs:182:8 | LL | T: IntoIterator + IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `IntoIterator` error: these where clauses contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:194:8 + --> tests/ui/trait_duplication_in_bounds.rs:205:8 | LL | T: AssocConstTrait + AssocConstTrait, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait` diff --git a/tests/ui/trait_duplication_in_bounds_unfixable.rs b/tests/ui/trait_duplication_in_bounds_unfixable.rs index b0095bb77b5a..38a42c3bd365 100644 --- a/tests/ui/trait_duplication_in_bounds_unfixable.rs +++ b/tests/ui/trait_duplication_in_bounds_unfixable.rs @@ -5,8 +5,10 @@ use std::collections::BTreeMap; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; fn bad_foo(arg0: T, arg1: Z) -//~^ ERROR: this trait bound is already specified in the where clause -//~| ERROR: this trait bound is already specified in the where clause +//~^ trait_duplication_in_bounds +//~| trait_duplication_in_bounds + + where T: Clone, T: Default, @@ -36,7 +38,8 @@ trait T: Default { fn f() where Self: Default; - //~^ ERROR: this trait bound is already specified in trait declaration + //~^ trait_duplication_in_bounds + } trait U: Default { @@ -51,19 +54,23 @@ trait ZZ: Default { fn f() where Self: Default + Clone; - //~^ ERROR: this trait bound is already specified in trait declaration + //~^ trait_duplication_in_bounds + } trait BadTrait: Default + Clone { fn f() where Self: Default + Clone; - //~^ ERROR: this trait bound is already specified in trait declaration - //~| ERROR: this trait bound is already specified in trait declaration + //~^ trait_duplication_in_bounds + //~| trait_duplication_in_bounds + + fn g() where Self: Default; - //~^ ERROR: this trait bound is already specified in trait declaration + //~^ trait_duplication_in_bounds + fn h() where Self: Copy; @@ -99,7 +106,8 @@ trait FooIter: Iterator { fn bar() where Self: Iterator, - //~^ ERROR: this trait bound is already specified in trait declaration + //~^ trait_duplication_in_bounds + { } } diff --git a/tests/ui/trait_duplication_in_bounds_unfixable.stderr b/tests/ui/trait_duplication_in_bounds_unfixable.stderr index 41029007a98e..c7b8ba01c493 100644 --- a/tests/ui/trait_duplication_in_bounds_unfixable.stderr +++ b/tests/ui/trait_duplication_in_bounds_unfixable.stderr @@ -20,7 +20,7 @@ LL | fn bad_foo(arg0: T, arg1: Z) = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:38:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:40:15 | LL | Self: Default; | ^^^^^^^ @@ -28,7 +28,7 @@ LL | Self: Default; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:53:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:56:15 | LL | Self: Default + Clone; | ^^^^^^^ @@ -36,7 +36,7 @@ LL | Self: Default + Clone; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:60:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:64:15 | LL | Self: Default + Clone; | ^^^^^^^ @@ -44,7 +44,7 @@ LL | Self: Default + Clone; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:60:25 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:64:25 | LL | Self: Default + Clone; | ^^^^^ @@ -52,7 +52,7 @@ LL | Self: Default + Clone; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:65:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:71:15 | LL | Self: Default; | ^^^^^^^ @@ -60,7 +60,7 @@ LL | Self: Default; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:101:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:108:15 | LL | Self: Iterator, | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute.rs b/tests/ui/transmute.rs index 7f5bdea4acf3..0fec14ffd975 100644 --- a/tests/ui/transmute.rs +++ b/tests/ui/transmute.rs @@ -29,41 +29,51 @@ unsafe fn _generic<'a, T, U: 'a>(t: &'a T) { let _: &'a U = core::mem::transmute(t); let _: *const T = core::mem::transmute(t); - //~^ ERROR: transmute from a reference to a pointer - //~| NOTE: `-D clippy::useless-transmute` implied by `-D warnings` + //~^ useless_transmute + + let _: *mut T = core::mem::transmute(t); - //~^ ERROR: transmute from a reference to a pointer + //~^ useless_transmute + let _: *const U = core::mem::transmute(t); - //~^ ERROR: transmute from a reference to a pointer + //~^ useless_transmute + } #[warn(clippy::useless_transmute)] fn useless() { unsafe { let _: Vec = core::mem::transmute(my_vec()); - //~^ ERROR: transmute from a type (`std::vec::Vec`) to itself + //~^ useless_transmute + let _: Vec = core::mem::transmute(my_vec()); - //~^ ERROR: transmute from a type (`std::vec::Vec`) to itself + //~^ useless_transmute + let _: Vec = std::mem::transmute(my_vec()); - //~^ ERROR: transmute from a type (`std::vec::Vec`) to itself + //~^ useless_transmute + let _: Vec = std::mem::transmute(my_vec()); - //~^ ERROR: transmute from a type (`std::vec::Vec`) to itself + //~^ useless_transmute + let _: Vec = my_transmute(my_vec()); - //~^ ERROR: transmute from a type (`std::vec::Vec`) to itself + //~^ useless_transmute + let _: *const usize = std::mem::transmute(5_isize); - //~^ ERROR: transmute from an integer to a pointer + //~^ useless_transmute + let _ = 5_isize as *const usize; let _: *const usize = std::mem::transmute(1 + 1usize); - //~^ ERROR: transmute from an integer to a pointer + //~^ useless_transmute + let _ = (1 + 1_usize) as *const usize; } @@ -95,77 +105,98 @@ fn crosspointer() { unsafe { let _: Usize = core::mem::transmute(int_const_ptr); - //~^ ERROR: transmute from a type (`*const Usize`) to the type that it points to ( - //~| NOTE: `-D clippy::crosspointer-transmute` implied by `-D warnings` + //~^ crosspointer_transmute + + let _: Usize = core::mem::transmute(int_mut_ptr); - //~^ ERROR: transmute from a type (`*mut Usize`) to the type that it points to (`U + //~^ crosspointer_transmute + let _: *const Usize = core::mem::transmute(my_int()); - //~^ ERROR: transmute from a type (`Usize`) to a pointer to that type (`*const Usi + //~^ crosspointer_transmute + let _: *mut Usize = core::mem::transmute(my_int()); - //~^ ERROR: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize + //~^ crosspointer_transmute + } } #[warn(clippy::transmute_int_to_bool)] fn int_to_bool() { let _: bool = unsafe { std::mem::transmute(0_u8) }; - //~^ ERROR: transmute from a `u8` to a `bool` - //~| NOTE: `-D clippy::transmute-int-to-bool` implied by `-D warnings` + //~^ transmute_int_to_bool + + } #[warn(clippy::transmute_int_to_float)] mod int_to_float { fn test() { let _: f16 = unsafe { std::mem::transmute(0_u16) }; - //~^ ERROR: transmute from a `u16` to a `f16` - //~| NOTE: `-D clippy::transmute-int-to-float` implied by `-D warnings` + //~^ transmute_int_to_float + + let _: f16 = unsafe { std::mem::transmute(0_i16) }; - //~^ ERROR: transmute from a `i16` to a `f16` + //~^ transmute_int_to_float + let _: f32 = unsafe { std::mem::transmute(0_u32) }; - //~^ ERROR: transmute from a `u32` to a `f32` + //~^ transmute_int_to_float + let _: f32 = unsafe { std::mem::transmute(0_i32) }; - //~^ ERROR: transmute from a `i32` to a `f32` + //~^ transmute_int_to_float + let _: f64 = unsafe { std::mem::transmute(0_u64) }; - //~^ ERROR: transmute from a `u64` to a `f64` + //~^ transmute_int_to_float + let _: f64 = unsafe { std::mem::transmute(0_i64) }; - //~^ ERROR: transmute from a `i64` to a `f64` + //~^ transmute_int_to_float + let _: f128 = unsafe { std::mem::transmute(0_u128) }; - //~^ ERROR: transmute from a `u128` to a `f128` + //~^ transmute_int_to_float + let _: f128 = unsafe { std::mem::transmute(0_i128) }; - //~^ ERROR: transmute from a `i128` to a `f128` + //~^ transmute_int_to_float + } mod issue_5747 { const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) }; - //~^ ERROR: transmute from a `u16` to a `f16` + //~^ transmute_int_to_float + const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) }; - //~^ ERROR: transmute from a `u32` to a `f32` + //~^ transmute_int_to_float + const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) }; - //~^ ERROR: transmute from a `i64` to a `f64` + //~^ transmute_int_to_float + const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) }; - //~^ ERROR: transmute from a `i128` to a `f128` + //~^ transmute_int_to_float + const fn from_bits_16(v: i16) -> f16 { unsafe { std::mem::transmute(v) } - //~^ ERROR: transmute from a `i16` to a `f16` + //~^ transmute_int_to_float + } const fn from_bits_32(v: i32) -> f32 { unsafe { std::mem::transmute(v) } - //~^ ERROR: transmute from a `i32` to a `f32` + //~^ transmute_int_to_float + } const fn from_bits_64(v: u64) -> f64 { unsafe { std::mem::transmute(v) } - //~^ ERROR: transmute from a `u64` to a `f64` + //~^ transmute_int_to_float + } const fn from_bits_128(v: u128) -> f128 { unsafe { std::mem::transmute(v) } - //~^ ERROR: transmute from a `u128` to a `f128` + //~^ transmute_int_to_float + } } } @@ -174,52 +205,72 @@ mod num_to_bytes { fn test() { unsafe { let _: [u8; 1] = std::mem::transmute(0u8); - //~^ ERROR: transmute from a `u8` to a `[u8; 1]` - //~| NOTE: `-D clippy::transmute-num-to-bytes` implied by `-D warnings` + //~^ transmute_num_to_bytes + + let _: [u8; 4] = std::mem::transmute(0u32); - //~^ ERROR: transmute from a `u32` to a `[u8; 4]` + //~^ transmute_num_to_bytes + let _: [u8; 16] = std::mem::transmute(0u128); - //~^ ERROR: transmute from a `u128` to a `[u8; 16]` + //~^ transmute_num_to_bytes + let _: [u8; 1] = std::mem::transmute(0i8); - //~^ ERROR: transmute from a `i8` to a `[u8; 1]` + //~^ transmute_num_to_bytes + let _: [u8; 4] = std::mem::transmute(0i32); - //~^ ERROR: transmute from a `i32` to a `[u8; 4]` + //~^ transmute_num_to_bytes + let _: [u8; 16] = std::mem::transmute(0i128); - //~^ ERROR: transmute from a `i128` to a `[u8; 16]` + //~^ transmute_num_to_bytes + let _: [u8; 2] = std::mem::transmute(0.0f16); - //~^ ERROR: transmute from a `f16` to a `[u8; 2]` + //~^ transmute_num_to_bytes + let _: [u8; 4] = std::mem::transmute(0.0f32); - //~^ ERROR: transmute from a `f32` to a `[u8; 4]` + //~^ transmute_num_to_bytes + let _: [u8; 8] = std::mem::transmute(0.0f64); - //~^ ERROR: transmute from a `f64` to a `[u8; 8]` + //~^ transmute_num_to_bytes + let _: [u8; 16] = std::mem::transmute(0.0f128); - //~^ ERROR: transmute from a `f128` to a `[u8; 16]` + //~^ transmute_num_to_bytes + } } const fn test_const() { unsafe { let _: [u8; 1] = std::mem::transmute(0u8); - //~^ ERROR: transmute from a `u8` to a `[u8; 1]` + //~^ transmute_num_to_bytes + let _: [u8; 4] = std::mem::transmute(0u32); - //~^ ERROR: transmute from a `u32` to a `[u8; 4]` + //~^ transmute_num_to_bytes + let _: [u8; 16] = std::mem::transmute(0u128); - //~^ ERROR: transmute from a `u128` to a `[u8; 16]` + //~^ transmute_num_to_bytes + let _: [u8; 1] = std::mem::transmute(0i8); - //~^ ERROR: transmute from a `i8` to a `[u8; 1]` + //~^ transmute_num_to_bytes + let _: [u8; 4] = std::mem::transmute(0i32); - //~^ ERROR: transmute from a `i32` to a `[u8; 4]` + //~^ transmute_num_to_bytes + let _: [u8; 16] = std::mem::transmute(0i128); - //~^ ERROR: transmute from a `i128` to a `[u8; 16]` + //~^ transmute_num_to_bytes + let _: [u8; 2] = std::mem::transmute(0.0f16); - //~^ ERROR: transmute from a `f16` to a `[u8; 2]` + //~^ transmute_num_to_bytes + let _: [u8; 4] = std::mem::transmute(0.0f32); - //~^ ERROR: transmute from a `f32` to a `[u8; 4]` + //~^ transmute_num_to_bytes + let _: [u8; 8] = std::mem::transmute(0.0f64); - //~^ ERROR: transmute from a `f64` to a `[u8; 8]` + //~^ transmute_num_to_bytes + let _: [u8; 16] = std::mem::transmute(0.0f128); - //~^ ERROR: transmute from a `f128` to a `[u8; 16]` + //~^ transmute_num_to_bytes + } } } @@ -228,12 +279,15 @@ fn bytes_to_str(mb: &mut [u8]) { const B: &[u8] = b""; let _: &str = unsafe { std::mem::transmute(B) }; - //~^ ERROR: transmute from a `&[u8]` to a `&str` - //~| NOTE: `-D clippy::transmute-bytes-to-str` implied by `-D warnings` + //~^ transmute_bytes_to_str + + let _: &mut str = unsafe { std::mem::transmute(mb) }; - //~^ ERROR: transmute from a `&mut [u8]` to a `&mut str` + //~^ transmute_bytes_to_str + const _: &str = unsafe { std::mem::transmute(B) }; - //~^ ERROR: transmute from a `&[u8]` to a `&str` + //~^ transmute_bytes_to_str + } fn main() {} diff --git a/tests/ui/transmute.stderr b/tests/ui/transmute.stderr index b5032772856e..7db7fad28d80 100644 --- a/tests/ui/transmute.stderr +++ b/tests/ui/transmute.stderr @@ -8,23 +8,17 @@ LL | let _: *const T = core::mem::transmute(t); = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]` error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:35:21 + --> tests/ui/transmute.rs:36:21 | LL | let _: *mut T = core::mem::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T` error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:38:23 + --> tests/ui/transmute.rs:40:23 | LL | let _: *const U = core::mem::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U` -error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:45:27 - | -LL | let _: Vec = core::mem::transmute(my_vec()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: transmute from a type (`std::vec::Vec`) to itself --> tests/ui/transmute.rs:48:27 | @@ -32,37 +26,43 @@ LL | let _: Vec = core::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:51:27 + --> tests/ui/transmute.rs:52:27 + | +LL | let _: Vec = core::mem::transmute(my_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from a type (`std::vec::Vec`) to itself + --> tests/ui/transmute.rs:56:27 | LL | let _: Vec = std::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:54:27 + --> tests/ui/transmute.rs:60:27 | LL | let _: Vec = std::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:57:27 + --> tests/ui/transmute.rs:64:27 | LL | let _: Vec = my_transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^ error: transmute from an integer to a pointer - --> tests/ui/transmute.rs:60:31 + --> tests/ui/transmute.rs:68:31 | LL | let _: *const usize = std::mem::transmute(5_isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize` error: transmute from an integer to a pointer - --> tests/ui/transmute.rs:65:31 + --> tests/ui/transmute.rs:74:31 | LL | let _: *const usize = std::mem::transmute(1 + 1usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize` error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`) - --> tests/ui/transmute.rs:97:24 + --> tests/ui/transmute.rs:107:24 | LL | let _: Usize = core::mem::transmute(int_const_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,25 +71,25 @@ LL | let _: Usize = core::mem::transmute(int_const_ptr); = help: to override `-D warnings` add `#[allow(clippy::crosspointer_transmute)]` error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`) - --> tests/ui/transmute.rs:101:24 + --> tests/ui/transmute.rs:112:24 | LL | let _: Usize = core::mem::transmute(int_mut_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`) - --> tests/ui/transmute.rs:104:31 + --> tests/ui/transmute.rs:116:31 | LL | let _: *const Usize = core::mem::transmute(my_int()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`) - --> tests/ui/transmute.rs:107:29 + --> tests/ui/transmute.rs:120:29 | LL | let _: *mut Usize = core::mem::transmute(my_int()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a `u8` to a `bool` - --> tests/ui/transmute.rs:114:28 + --> tests/ui/transmute.rs:128:28 | LL | let _: bool = unsafe { std::mem::transmute(0_u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0` @@ -98,7 +98,7 @@ LL | let _: bool = unsafe { std::mem::transmute(0_u8) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]` error: transmute from a `u16` to a `f16` - --> tests/ui/transmute.rs:122:31 + --> tests/ui/transmute.rs:137:31 | LL | let _: f16 = unsafe { std::mem::transmute(0_u16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)` @@ -107,97 +107,97 @@ LL | let _: f16 = unsafe { std::mem::transmute(0_u16) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_float)]` error: transmute from a `i16` to a `f16` - --> tests/ui/transmute.rs:125:31 + --> tests/ui/transmute.rs:141:31 | LL | let _: f16 = unsafe { std::mem::transmute(0_i16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_i16 as u16)` error: transmute from a `u32` to a `f32` - --> tests/ui/transmute.rs:127:31 + --> tests/ui/transmute.rs:144:31 | LL | let _: f32 = unsafe { std::mem::transmute(0_u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` error: transmute from a `i32` to a `f32` - --> tests/ui/transmute.rs:129:31 + --> tests/ui/transmute.rs:147:31 | LL | let _: f32 = unsafe { std::mem::transmute(0_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)` error: transmute from a `u64` to a `f64` - --> tests/ui/transmute.rs:131:31 + --> tests/ui/transmute.rs:150:31 | LL | let _: f64 = unsafe { std::mem::transmute(0_u64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)` error: transmute from a `i64` to a `f64` - --> tests/ui/transmute.rs:133:31 + --> tests/ui/transmute.rs:153:31 | LL | let _: f64 = unsafe { std::mem::transmute(0_i64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)` error: transmute from a `u128` to a `f128` - --> tests/ui/transmute.rs:135:32 + --> tests/ui/transmute.rs:156:32 | LL | let _: f128 = unsafe { std::mem::transmute(0_u128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_u128)` error: transmute from a `i128` to a `f128` - --> tests/ui/transmute.rs:137:32 + --> tests/ui/transmute.rs:159:32 | LL | let _: f128 = unsafe { std::mem::transmute(0_i128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` error: transmute from a `u16` to a `f16` - --> tests/ui/transmute.rs:142:39 + --> tests/ui/transmute.rs:165:39 | LL | const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)` error: transmute from a `u32` to a `f32` - --> tests/ui/transmute.rs:144:39 + --> tests/ui/transmute.rs:168:39 | LL | const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` error: transmute from a `i64` to a `f64` - --> tests/ui/transmute.rs:146:39 + --> tests/ui/transmute.rs:171:39 | LL | const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)` error: transmute from a `i128` to a `f128` - --> tests/ui/transmute.rs:148:41 + --> tests/ui/transmute.rs:174:41 | LL | const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` error: transmute from a `i16` to a `f16` - --> tests/ui/transmute.rs:152:22 + --> tests/ui/transmute.rs:179:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(v as u16)` error: transmute from a `i32` to a `f32` - --> tests/ui/transmute.rs:157:22 + --> tests/ui/transmute.rs:185:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(v as u32)` error: transmute from a `u64` to a `f64` - --> tests/ui/transmute.rs:162:22 + --> tests/ui/transmute.rs:191:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(v)` error: transmute from a `u128` to a `f128` - --> tests/ui/transmute.rs:167:22 + --> tests/ui/transmute.rs:197:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(v)` error: transmute from a `u8` to a `[u8; 1]` - --> tests/ui/transmute.rs:176:30 + --> tests/ui/transmute.rs:207:30 | LL | let _: [u8; 1] = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` @@ -206,121 +206,121 @@ LL | let _: [u8; 1] = std::mem::transmute(0u8); = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]` error: transmute from a `u32` to a `[u8; 4]` - --> tests/ui/transmute.rs:179:30 + --> tests/ui/transmute.rs:211:30 | LL | let _: [u8; 4] = std::mem::transmute(0u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` error: transmute from a `u128` to a `[u8; 16]` - --> tests/ui/transmute.rs:181:31 + --> tests/ui/transmute.rs:214:31 | LL | let _: [u8; 16] = std::mem::transmute(0u128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` error: transmute from a `i8` to a `[u8; 1]` - --> tests/ui/transmute.rs:183:30 + --> tests/ui/transmute.rs:217:30 | LL | let _: [u8; 1] = std::mem::transmute(0i8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` error: transmute from a `i32` to a `[u8; 4]` - --> tests/ui/transmute.rs:185:30 + --> tests/ui/transmute.rs:220:30 | LL | let _: [u8; 4] = std::mem::transmute(0i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` error: transmute from a `i128` to a `[u8; 16]` - --> tests/ui/transmute.rs:187:31 + --> tests/ui/transmute.rs:223:31 | LL | let _: [u8; 16] = std::mem::transmute(0i128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` error: transmute from a `f16` to a `[u8; 2]` - --> tests/ui/transmute.rs:190:30 + --> tests/ui/transmute.rs:227:30 | LL | let _: [u8; 2] = std::mem::transmute(0.0f16); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` error: transmute from a `f32` to a `[u8; 4]` - --> tests/ui/transmute.rs:192:30 + --> tests/ui/transmute.rs:230:30 | LL | let _: [u8; 4] = std::mem::transmute(0.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` error: transmute from a `f64` to a `[u8; 8]` - --> tests/ui/transmute.rs:194:30 + --> tests/ui/transmute.rs:233:30 | LL | let _: [u8; 8] = std::mem::transmute(0.0f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` error: transmute from a `f128` to a `[u8; 16]` - --> tests/ui/transmute.rs:196:31 + --> tests/ui/transmute.rs:236:31 | LL | let _: [u8; 16] = std::mem::transmute(0.0f128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` error: transmute from a `u8` to a `[u8; 1]` - --> tests/ui/transmute.rs:202:30 + --> tests/ui/transmute.rs:243:30 | LL | let _: [u8; 1] = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` error: transmute from a `u32` to a `[u8; 4]` - --> tests/ui/transmute.rs:204:30 + --> tests/ui/transmute.rs:246:30 | LL | let _: [u8; 4] = std::mem::transmute(0u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` error: transmute from a `u128` to a `[u8; 16]` - --> tests/ui/transmute.rs:206:31 + --> tests/ui/transmute.rs:249:31 | LL | let _: [u8; 16] = std::mem::transmute(0u128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` error: transmute from a `i8` to a `[u8; 1]` - --> tests/ui/transmute.rs:208:30 + --> tests/ui/transmute.rs:252:30 | LL | let _: [u8; 1] = std::mem::transmute(0i8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` error: transmute from a `i32` to a `[u8; 4]` - --> tests/ui/transmute.rs:210:30 + --> tests/ui/transmute.rs:255:30 | LL | let _: [u8; 4] = std::mem::transmute(0i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` error: transmute from a `i128` to a `[u8; 16]` - --> tests/ui/transmute.rs:212:31 + --> tests/ui/transmute.rs:258:31 | LL | let _: [u8; 16] = std::mem::transmute(0i128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` error: transmute from a `f16` to a `[u8; 2]` - --> tests/ui/transmute.rs:215:30 + --> tests/ui/transmute.rs:262:30 | LL | let _: [u8; 2] = std::mem::transmute(0.0f16); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` error: transmute from a `f32` to a `[u8; 4]` - --> tests/ui/transmute.rs:217:30 + --> tests/ui/transmute.rs:265:30 | LL | let _: [u8; 4] = std::mem::transmute(0.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` error: transmute from a `f64` to a `[u8; 8]` - --> tests/ui/transmute.rs:219:30 + --> tests/ui/transmute.rs:268:30 | LL | let _: [u8; 8] = std::mem::transmute(0.0f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` error: transmute from a `f128` to a `[u8; 16]` - --> tests/ui/transmute.rs:221:31 + --> tests/ui/transmute.rs:271:31 | LL | let _: [u8; 16] = std::mem::transmute(0.0f128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` error: transmute from a `&[u8]` to a `&str` - --> tests/ui/transmute.rs:230:28 + --> tests/ui/transmute.rs:281:28 | LL | let _: &str = unsafe { std::mem::transmute(B) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()` @@ -329,13 +329,13 @@ LL | let _: &str = unsafe { std::mem::transmute(B) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]` error: transmute from a `&mut [u8]` to a `&mut str` - --> tests/ui/transmute.rs:233:32 + --> tests/ui/transmute.rs:285:32 | LL | let _: &mut str = unsafe { std::mem::transmute(mb) }; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()` error: transmute from a `&[u8]` to a `&str` - --> tests/ui/transmute.rs:235:30 + --> tests/ui/transmute.rs:288:30 | LL | const _: &str = unsafe { std::mem::transmute(B) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)` diff --git a/tests/ui/transmute_64bit.rs b/tests/ui/transmute_64bit.rs index fd0ad74bcfa0..9570fa5ab093 100644 --- a/tests/ui/transmute_64bit.rs +++ b/tests/ui/transmute_64bit.rs @@ -4,10 +4,12 @@ fn main() { unsafe { let _: *const usize = std::mem::transmute(6.0f64); - //~^ ERROR: transmute from a `f64` to a pointer - //~| NOTE: `-D clippy::wrong-transmute` implied by `-D warnings` + //~^ wrong_transmute + + let _: *mut usize = std::mem::transmute(6.0f64); - //~^ ERROR: transmute from a `f64` to a pointer + //~^ wrong_transmute + } } diff --git a/tests/ui/transmute_64bit.stderr b/tests/ui/transmute_64bit.stderr index 65fff17f59fa..789eba5247fa 100644 --- a/tests/ui/transmute_64bit.stderr +++ b/tests/ui/transmute_64bit.stderr @@ -8,7 +8,7 @@ LL | let _: *const usize = std::mem::transmute(6.0f64); = help: to override `-D warnings` add `#[allow(clippy::wrong_transmute)]` error: transmute from a `f64` to a pointer - --> tests/ui/transmute_64bit.rs:10:29 + --> tests/ui/transmute_64bit.rs:11:29 | LL | let _: *mut usize = std::mem::transmute(6.0f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute_collection.rs b/tests/ui/transmute_collection.rs index 6748b66e0eb6..20952dfa2839 100644 --- a/tests/ui/transmute_collection.rs +++ b/tests/ui/transmute_collection.rs @@ -8,61 +8,79 @@ fn main() { unsafe { // wrong size let _ = transmute::<_, Vec>(vec![0u8]); - //~^ ERROR: transmute from `std::vec::Vec` to `std::vec::Vec` with mismat - //~| NOTE: `-D clippy::unsound-collection-transmute` implied by `-D warnings` + //~^ unsound_collection_transmute + + // wrong layout let _ = transmute::<_, Vec<[u8; 4]>>(vec![1234u32]); - //~^ ERROR: transmute from `std::vec::Vec` to `std::vec::Vec<[u8; 4]>` with m + //~^ unsound_collection_transmute + // wrong size let _ = transmute::<_, VecDeque>(VecDeque::::new()); - //~^ ERROR: transmute from `std::collections::VecDeque` to `std::collections:: + //~^ unsound_collection_transmute + // wrong layout let _ = transmute::<_, VecDeque>(VecDeque::<[u8; 4]>::new()); - //~^ ERROR: transmute from `std::collections::VecDeque<[u8; 4]>` to `std::collecti + //~^ unsound_collection_transmute + // wrong size let _ = transmute::<_, BinaryHeap>(BinaryHeap::::new()); - //~^ ERROR: transmute from `std::collections::BinaryHeap` to `std::collections + //~^ unsound_collection_transmute + // wrong layout let _ = transmute::<_, BinaryHeap>(BinaryHeap::<[u8; 4]>::new()); - //~^ ERROR: transmute from `std::collections::BinaryHeap<[u8; 4]>` to `std::collec + //~^ unsound_collection_transmute + // wrong size let _ = transmute::<_, BTreeSet>(BTreeSet::::new()); - //~^ ERROR: transmute from `std::collections::BTreeSet` to `std::collections:: + //~^ unsound_collection_transmute + // wrong layout let _ = transmute::<_, BTreeSet>(BTreeSet::<[u8; 4]>::new()); - //~^ ERROR: transmute from `std::collections::BTreeSet<[u8; 4]>` to `std::collecti + //~^ unsound_collection_transmute + // wrong size let _ = transmute::<_, HashSet>(HashSet::::new()); - //~^ ERROR: transmute from `std::collections::HashSet` to `std::collections::H + //~^ unsound_collection_transmute + // wrong layout let _ = transmute::<_, HashSet>(HashSet::<[u8; 4]>::new()); - //~^ ERROR: transmute from `std::collections::HashSet<[u8; 4]>` to `std::collectio + //~^ unsound_collection_transmute + // wrong size let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); - //~^ ERROR: transmute from `std::collections::BTreeMap` to `std::collectio + //~^ unsound_collection_transmute + let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); - //~^ ERROR: transmute from `std::collections::BTreeMap` to `std::collect + //~^ unsound_collection_transmute + // wrong layout let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); - //~^ ERROR: transmute from `std::collections::BTreeMap` to `std::coll + //~^ unsound_collection_transmute + let _ = transmute::<_, BTreeMap>(BTreeMap::<[u8; 4], u32>::new()); - //~^ ERROR: transmute from `std::collections::BTreeMap<[u8; 4], u32>` to `std::col + //~^ unsound_collection_transmute + // wrong size let _ = transmute::<_, HashMap>(HashMap::::new()); - //~^ ERROR: transmute from `std::collections::HashMap` to `std::collection + //~^ unsound_collection_transmute + let _ = transmute::<_, HashMap>(HashMap::::new()); - //~^ ERROR: transmute from `std::collections::HashMap` to `std::collecti + //~^ unsound_collection_transmute + // wrong layout let _ = transmute::<_, HashMap>(HashMap::::new()); - //~^ ERROR: transmute from `std::collections::HashMap` to `std::colle + //~^ unsound_collection_transmute + let _ = transmute::<_, HashMap>(HashMap::<[u8; 4], u32>::new()); - //~^ ERROR: transmute from `std::collections::HashMap<[u8; 4], u32>` to `std::coll + //~^ unsound_collection_transmute + let _ = transmute::<_, Vec>(Vec::>::new()); let _ = transmute::<_, Vec<*mut u32>>(Vec::>::new()); diff --git a/tests/ui/transmute_collection.stderr b/tests/ui/transmute_collection.stderr index 06db9321064b..f887afc9b676 100644 --- a/tests/ui/transmute_collection.stderr +++ b/tests/ui/transmute_collection.stderr @@ -8,103 +8,103 @@ LL | let _ = transmute::<_, Vec>(vec![0u8]); = help: to override `-D warnings` add `#[allow(clippy::unsound_collection_transmute)]` error: transmute from `std::vec::Vec` to `std::vec::Vec<[u8; 4]>` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:14:17 + --> tests/ui/transmute_collection.rs:15:17 | LL | let _ = transmute::<_, Vec<[u8; 4]>>(vec![1234u32]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::VecDeque` to `std::collections::VecDeque` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:18:17 + --> tests/ui/transmute_collection.rs:20:17 | LL | let _ = transmute::<_, VecDeque>(VecDeque::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::VecDeque<[u8; 4]>` to `std::collections::VecDeque` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:21:17 + --> tests/ui/transmute_collection.rs:24:17 | LL | let _ = transmute::<_, VecDeque>(VecDeque::<[u8; 4]>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BinaryHeap` to `std::collections::BinaryHeap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:25:17 + --> tests/ui/transmute_collection.rs:29:17 | LL | let _ = transmute::<_, BinaryHeap>(BinaryHeap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BinaryHeap<[u8; 4]>` to `std::collections::BinaryHeap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:28:17 + --> tests/ui/transmute_collection.rs:33:17 | LL | let _ = transmute::<_, BinaryHeap>(BinaryHeap::<[u8; 4]>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeSet` to `std::collections::BTreeSet` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:32:17 + --> tests/ui/transmute_collection.rs:38:17 | LL | let _ = transmute::<_, BTreeSet>(BTreeSet::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeSet<[u8; 4]>` to `std::collections::BTreeSet` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:35:17 + --> tests/ui/transmute_collection.rs:42:17 | LL | let _ = transmute::<_, BTreeSet>(BTreeSet::<[u8; 4]>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashSet` to `std::collections::HashSet` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:39:17 + --> tests/ui/transmute_collection.rs:47:17 | LL | let _ = transmute::<_, HashSet>(HashSet::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashSet<[u8; 4]>` to `std::collections::HashSet` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:42:17 + --> tests/ui/transmute_collection.rs:51:17 | LL | let _ = transmute::<_, HashSet>(HashSet::<[u8; 4]>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeMap` to `std::collections::BTreeMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:46:17 + --> tests/ui/transmute_collection.rs:56:17 | LL | let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeMap` to `std::collections::BTreeMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:48:17 + --> tests/ui/transmute_collection.rs:59:17 | LL | let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeMap` to `std::collections::BTreeMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:51:17 + --> tests/ui/transmute_collection.rs:63:17 | LL | let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeMap<[u8; 4], u32>` to `std::collections::BTreeMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:53:17 + --> tests/ui/transmute_collection.rs:66:17 | LL | let _ = transmute::<_, BTreeMap>(BTreeMap::<[u8; 4], u32>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashMap` to `std::collections::HashMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:57:17 + --> tests/ui/transmute_collection.rs:71:17 | LL | let _ = transmute::<_, HashMap>(HashMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashMap` to `std::collections::HashMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:59:17 + --> tests/ui/transmute_collection.rs:74:17 | LL | let _ = transmute::<_, HashMap>(HashMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashMap` to `std::collections::HashMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:62:17 + --> tests/ui/transmute_collection.rs:78:17 | LL | let _ = transmute::<_, HashMap>(HashMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashMap<[u8; 4], u32>` to `std::collections::HashMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:64:17 + --> tests/ui/transmute_collection.rs:81:17 | LL | let _ = transmute::<_, HashMap>(HashMap::<[u8; 4], u32>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute_float_to_int.fixed b/tests/ui/transmute_float_to_int.fixed index 075a198918a0..e1feb57ae736 100644 --- a/tests/ui/transmute_float_to_int.fixed +++ b/tests/ui/transmute_float_to_int.fixed @@ -5,48 +5,62 @@ fn float_to_int() { let _: u32 = unsafe { 1f32.to_bits() }; - //~^ ERROR: transmute from a `f32` to a `u32` - //~| NOTE: `-D clippy::transmute-float-to-int` implied by `-D warnings` + //~^ transmute_float_to_int + + let _: i32 = unsafe { 1f32.to_bits() as i32 }; - //~^ ERROR: transmute from a `f32` to a `i32` + //~^ transmute_float_to_int + let _: u64 = unsafe { 1f64.to_bits() }; - //~^ ERROR: transmute from a `f64` to a `u64` + //~^ transmute_float_to_int + let _: i64 = unsafe { 1f64.to_bits() as i64 }; - //~^ ERROR: transmute from a `f64` to a `i64` + //~^ transmute_float_to_int + let _: u64 = unsafe { 1.0f64.to_bits() }; - //~^ ERROR: transmute from a `f64` to a `u64` + //~^ transmute_float_to_int + let _: u64 = unsafe { (-1.0f64).to_bits() }; - //~^ ERROR: transmute from a `f64` to a `u64` + //~^ transmute_float_to_int + } mod issue_5747 { const VALUE16: i16 = unsafe { 1f16.to_bits() as i16 }; - //~^ ERROR: transmute from a `f16` to a `i16` + //~^ transmute_float_to_int + const VALUE32: i32 = unsafe { 1f32.to_bits() as i32 }; - //~^ ERROR: transmute from a `f32` to a `i32` + //~^ transmute_float_to_int + const VALUE64: u64 = unsafe { 1f64.to_bits() }; - //~^ ERROR: transmute from a `f64` to a `u64` + //~^ transmute_float_to_int + const VALUE128: u128 = unsafe { 1f128.to_bits() }; - //~^ ERROR: transmute from a `f128` to a `u128` + //~^ transmute_float_to_int + const fn to_bits_16(v: f16) -> u16 { unsafe { v.to_bits() } - //~^ ERROR: transmute from a `f16` to a `u16` + //~^ transmute_float_to_int + } const fn to_bits_32(v: f32) -> u32 { unsafe { v.to_bits() } - //~^ ERROR: transmute from a `f32` to a `u32` + //~^ transmute_float_to_int + } const fn to_bits_64(v: f64) -> i64 { unsafe { v.to_bits() as i64 } - //~^ ERROR: transmute from a `f64` to a `i64` + //~^ transmute_float_to_int + } const fn to_bits_128(v: f128) -> i128 { unsafe { v.to_bits() as i128 } - //~^ ERROR: transmute from a `f128` to a `i128` + //~^ transmute_float_to_int + } } diff --git a/tests/ui/transmute_float_to_int.rs b/tests/ui/transmute_float_to_int.rs index 12541b2f7cf3..ac2a1a1ad05d 100644 --- a/tests/ui/transmute_float_to_int.rs +++ b/tests/ui/transmute_float_to_int.rs @@ -5,48 +5,62 @@ fn float_to_int() { let _: u32 = unsafe { std::mem::transmute(1f32) }; - //~^ ERROR: transmute from a `f32` to a `u32` - //~| NOTE: `-D clippy::transmute-float-to-int` implied by `-D warnings` + //~^ transmute_float_to_int + + let _: i32 = unsafe { std::mem::transmute(1f32) }; - //~^ ERROR: transmute from a `f32` to a `i32` + //~^ transmute_float_to_int + let _: u64 = unsafe { std::mem::transmute(1f64) }; - //~^ ERROR: transmute from a `f64` to a `u64` + //~^ transmute_float_to_int + let _: i64 = unsafe { std::mem::transmute(1f64) }; - //~^ ERROR: transmute from a `f64` to a `i64` + //~^ transmute_float_to_int + let _: u64 = unsafe { std::mem::transmute(1.0) }; - //~^ ERROR: transmute from a `f64` to a `u64` + //~^ transmute_float_to_int + let _: u64 = unsafe { std::mem::transmute(-1.0) }; - //~^ ERROR: transmute from a `f64` to a `u64` + //~^ transmute_float_to_int + } mod issue_5747 { const VALUE16: i16 = unsafe { std::mem::transmute(1f16) }; - //~^ ERROR: transmute from a `f16` to a `i16` + //~^ transmute_float_to_int + const VALUE32: i32 = unsafe { std::mem::transmute(1f32) }; - //~^ ERROR: transmute from a `f32` to a `i32` + //~^ transmute_float_to_int + const VALUE64: u64 = unsafe { std::mem::transmute(1f64) }; - //~^ ERROR: transmute from a `f64` to a `u64` + //~^ transmute_float_to_int + const VALUE128: u128 = unsafe { std::mem::transmute(1f128) }; - //~^ ERROR: transmute from a `f128` to a `u128` + //~^ transmute_float_to_int + const fn to_bits_16(v: f16) -> u16 { unsafe { std::mem::transmute(v) } - //~^ ERROR: transmute from a `f16` to a `u16` + //~^ transmute_float_to_int + } const fn to_bits_32(v: f32) -> u32 { unsafe { std::mem::transmute(v) } - //~^ ERROR: transmute from a `f32` to a `u32` + //~^ transmute_float_to_int + } const fn to_bits_64(v: f64) -> i64 { unsafe { std::mem::transmute(v) } - //~^ ERROR: transmute from a `f64` to a `i64` + //~^ transmute_float_to_int + } const fn to_bits_128(v: f128) -> i128 { unsafe { std::mem::transmute(v) } - //~^ ERROR: transmute from a `f128` to a `i128` + //~^ transmute_float_to_int + } } diff --git a/tests/ui/transmute_float_to_int.stderr b/tests/ui/transmute_float_to_int.stderr index 0cabab58ab08..551fcb1f7d0d 100644 --- a/tests/ui/transmute_float_to_int.stderr +++ b/tests/ui/transmute_float_to_int.stderr @@ -8,79 +8,79 @@ LL | let _: u32 = unsafe { std::mem::transmute(1f32) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_float_to_int)]` error: transmute from a `f32` to a `i32` - --> tests/ui/transmute_float_to_int.rs:10:27 + --> tests/ui/transmute_float_to_int.rs:11:27 | LL | let _: i32 = unsafe { std::mem::transmute(1f32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:12:27 + --> tests/ui/transmute_float_to_int.rs:14:27 | LL | let _: u64 = unsafe { std::mem::transmute(1f64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()` error: transmute from a `f64` to a `i64` - --> tests/ui/transmute_float_to_int.rs:14:27 + --> tests/ui/transmute_float_to_int.rs:17:27 | LL | let _: i64 = unsafe { std::mem::transmute(1f64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits() as i64` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:16:27 + --> tests/ui/transmute_float_to_int.rs:20:27 | LL | let _: u64 = unsafe { std::mem::transmute(1.0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.0f64.to_bits()` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:18:27 + --> tests/ui/transmute_float_to_int.rs:23:27 | LL | let _: u64 = unsafe { std::mem::transmute(-1.0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()` error: transmute from a `f16` to a `i16` - --> tests/ui/transmute_float_to_int.rs:23:35 + --> tests/ui/transmute_float_to_int.rs:29:35 | LL | const VALUE16: i16 = unsafe { std::mem::transmute(1f16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f16.to_bits() as i16` error: transmute from a `f32` to a `i32` - --> tests/ui/transmute_float_to_int.rs:25:35 + --> tests/ui/transmute_float_to_int.rs:32:35 | LL | const VALUE32: i32 = unsafe { std::mem::transmute(1f32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:27:35 + --> tests/ui/transmute_float_to_int.rs:35:35 | LL | const VALUE64: u64 = unsafe { std::mem::transmute(1f64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()` error: transmute from a `f128` to a `u128` - --> tests/ui/transmute_float_to_int.rs:29:37 + --> tests/ui/transmute_float_to_int.rs:38:37 | LL | const VALUE128: u128 = unsafe { std::mem::transmute(1f128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f128.to_bits()` error: transmute from a `f16` to a `u16` - --> tests/ui/transmute_float_to_int.rs:33:18 + --> tests/ui/transmute_float_to_int.rs:43:18 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits()` error: transmute from a `f32` to a `u32` - --> tests/ui/transmute_float_to_int.rs:38:18 + --> tests/ui/transmute_float_to_int.rs:49:18 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits()` error: transmute from a `f64` to a `i64` - --> tests/ui/transmute_float_to_int.rs:43:18 + --> tests/ui/transmute_float_to_int.rs:55:18 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits() as i64` error: transmute from a `f128` to a `i128` - --> tests/ui/transmute_float_to_int.rs:48:18 + --> tests/ui/transmute_float_to_int.rs:61:18 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits() as i128` diff --git a/tests/ui/transmute_int_to_char.fixed b/tests/ui/transmute_int_to_char.fixed index d3277d1b8c73..e28467f00434 100644 --- a/tests/ui/transmute_int_to_char.fixed +++ b/tests/ui/transmute_int_to_char.fixed @@ -3,10 +3,12 @@ fn int_to_char() { let _: char = unsafe { std::char::from_u32(0_u32).unwrap() }; - //~^ ERROR: transmute from a `u32` to a `char` - //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings` + //~^ transmute_int_to_char + + let _: char = unsafe { std::char::from_u32(0_i32 as u32).unwrap() }; - //~^ ERROR: transmute from a `i32` to a `char` + //~^ transmute_int_to_char + // These shouldn't warn const _: char = unsafe { std::mem::transmute(0_u32) }; diff --git a/tests/ui/transmute_int_to_char.rs b/tests/ui/transmute_int_to_char.rs index d21c4fd6fea3..decdaaa463a9 100644 --- a/tests/ui/transmute_int_to_char.rs +++ b/tests/ui/transmute_int_to_char.rs @@ -3,10 +3,12 @@ fn int_to_char() { let _: char = unsafe { std::mem::transmute(0_u32) }; - //~^ ERROR: transmute from a `u32` to a `char` - //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings` + //~^ transmute_int_to_char + + let _: char = unsafe { std::mem::transmute(0_i32) }; - //~^ ERROR: transmute from a `i32` to a `char` + //~^ transmute_int_to_char + // These shouldn't warn const _: char = unsafe { std::mem::transmute(0_u32) }; diff --git a/tests/ui/transmute_int_to_char.stderr b/tests/ui/transmute_int_to_char.stderr index e3a3620f28b7..5dc58abb38ea 100644 --- a/tests/ui/transmute_int_to_char.stderr +++ b/tests/ui/transmute_int_to_char.stderr @@ -8,7 +8,7 @@ LL | let _: char = unsafe { std::mem::transmute(0_u32) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]` error: transmute from a `i32` to a `char` - --> tests/ui/transmute_int_to_char.rs:8:28 + --> tests/ui/transmute_int_to_char.rs:9:28 | LL | let _: char = unsafe { std::mem::transmute(0_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()` diff --git a/tests/ui/transmute_int_to_char_no_std.fixed b/tests/ui/transmute_int_to_char_no_std.fixed index 32a57645b46f..09a353dc1ae9 100644 --- a/tests/ui/transmute_int_to_char_no_std.fixed +++ b/tests/ui/transmute_int_to_char_no_std.fixed @@ -15,10 +15,12 @@ fn panic(info: &PanicInfo) -> ! { fn int_to_char() { let _: char = unsafe { core::char::from_u32(0_u32).unwrap() }; - //~^ ERROR: transmute from a `u32` to a `char` - //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings` + //~^ transmute_int_to_char + + let _: char = unsafe { core::char::from_u32(0_i32 as u32).unwrap() }; - //~^ ERROR: transmute from a `i32` to a `char` + //~^ transmute_int_to_char + // These shouldn't warn const _: char = unsafe { core::mem::transmute(0_u32) }; diff --git a/tests/ui/transmute_int_to_char_no_std.rs b/tests/ui/transmute_int_to_char_no_std.rs index 942794c32f81..fb47b3ce3ba9 100644 --- a/tests/ui/transmute_int_to_char_no_std.rs +++ b/tests/ui/transmute_int_to_char_no_std.rs @@ -15,10 +15,12 @@ fn panic(info: &PanicInfo) -> ! { fn int_to_char() { let _: char = unsafe { core::mem::transmute(0_u32) }; - //~^ ERROR: transmute from a `u32` to a `char` - //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings` + //~^ transmute_int_to_char + + let _: char = unsafe { core::mem::transmute(0_i32) }; - //~^ ERROR: transmute from a `i32` to a `char` + //~^ transmute_int_to_char + // These shouldn't warn const _: char = unsafe { core::mem::transmute(0_u32) }; diff --git a/tests/ui/transmute_int_to_char_no_std.stderr b/tests/ui/transmute_int_to_char_no_std.stderr index d94580a84d7a..37f996e6277f 100644 --- a/tests/ui/transmute_int_to_char_no_std.stderr +++ b/tests/ui/transmute_int_to_char_no_std.stderr @@ -8,7 +8,7 @@ LL | let _: char = unsafe { core::mem::transmute(0_u32) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]` error: transmute from a `i32` to a `char` - --> tests/ui/transmute_int_to_char_no_std.rs:20:28 + --> tests/ui/transmute_int_to_char_no_std.rs:21:28 | LL | let _: char = unsafe { core::mem::transmute(0_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::char::from_u32(0_i32 as u32).unwrap()` diff --git a/tests/ui/transmute_int_to_non_zero.fixed b/tests/ui/transmute_int_to_non_zero.fixed index 1a48051ec8c4..12d8d20f4d8f 100644 --- a/tests/ui/transmute_int_to_non_zero.fixed +++ b/tests/ui/transmute_int_to_non_zero.fixed @@ -17,27 +17,37 @@ fn main() { let int_i128: i128 = 1; let _: NonZero = unsafe { NonZero::new_unchecked(int_u8) }; - //~^ ERROR: transmute from a `u8` to a `NonZero` - //~| NOTE: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings` + //~^ transmute_int_to_non_zero + + let _: NonZero = unsafe { NonZero::new_unchecked(int_u16) }; - //~^ ERROR: transmute from a `u16` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_u32) }; - //~^ ERROR: transmute from a `u32` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_u64) }; - //~^ ERROR: transmute from a `u64` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_u128) }; - //~^ ERROR: transmute from a `u128` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_i8) }; - //~^ ERROR: transmute from a `i8` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_i16) }; - //~^ ERROR: transmute from a `i16` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_i32) }; - //~^ ERROR: transmute from a `i32` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_i64) }; - //~^ ERROR: transmute from a `i64` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_i128) }; - //~^ ERROR: transmute from a `i128` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_u8) }; let _: NonZero = unsafe { NonZero::new_unchecked(int_u16) }; diff --git a/tests/ui/transmute_int_to_non_zero.rs b/tests/ui/transmute_int_to_non_zero.rs index d8e842fb99ce..a01b9aaa7f2e 100644 --- a/tests/ui/transmute_int_to_non_zero.rs +++ b/tests/ui/transmute_int_to_non_zero.rs @@ -17,27 +17,37 @@ fn main() { let int_i128: i128 = 1; let _: NonZero = unsafe { std::mem::transmute(int_u8) }; - //~^ ERROR: transmute from a `u8` to a `NonZero` - //~| NOTE: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings` + //~^ transmute_int_to_non_zero + + let _: NonZero = unsafe { std::mem::transmute(int_u16) }; - //~^ ERROR: transmute from a `u16` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { std::mem::transmute(int_u32) }; - //~^ ERROR: transmute from a `u32` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { std::mem::transmute(int_u64) }; - //~^ ERROR: transmute from a `u64` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { std::mem::transmute(int_u128) }; - //~^ ERROR: transmute from a `u128` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { std::mem::transmute(int_i8) }; - //~^ ERROR: transmute from a `i8` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { std::mem::transmute(int_i16) }; - //~^ ERROR: transmute from a `i16` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { std::mem::transmute(int_i32) }; - //~^ ERROR: transmute from a `i32` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { std::mem::transmute(int_i64) }; - //~^ ERROR: transmute from a `i64` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { std::mem::transmute(int_i128) }; - //~^ ERROR: transmute from a `i128` to a `NonZero` + //~^ transmute_int_to_non_zero + let _: NonZero = unsafe { NonZero::new_unchecked(int_u8) }; let _: NonZero = unsafe { NonZero::new_unchecked(int_u16) }; diff --git a/tests/ui/transmute_int_to_non_zero.stderr b/tests/ui/transmute_int_to_non_zero.stderr index 199b8ec59d09..1a1cd03248b4 100644 --- a/tests/ui/transmute_int_to_non_zero.stderr +++ b/tests/ui/transmute_int_to_non_zero.stderr @@ -8,55 +8,55 @@ LL | let _: NonZero = unsafe { std::mem::transmute(int_u8) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_non_zero)]` error: transmute from a `u16` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:22:36 + --> tests/ui/transmute_int_to_non_zero.rs:23:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_u16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u16)` error: transmute from a `u32` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:24:36 + --> tests/ui/transmute_int_to_non_zero.rs:26:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u32)` error: transmute from a `u64` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:26:36 + --> tests/ui/transmute_int_to_non_zero.rs:29:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_u64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u64)` error: transmute from a `u128` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:28:37 + --> tests/ui/transmute_int_to_non_zero.rs:32:37 | LL | let _: NonZero = unsafe { std::mem::transmute(int_u128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u128)` error: transmute from a `i8` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:31:35 + --> tests/ui/transmute_int_to_non_zero.rs:36:35 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i8)` error: transmute from a `i16` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:33:36 + --> tests/ui/transmute_int_to_non_zero.rs:39:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i16)` error: transmute from a `i32` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:35:36 + --> tests/ui/transmute_int_to_non_zero.rs:42:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i32)` error: transmute from a `i64` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:37:36 + --> tests/ui/transmute_int_to_non_zero.rs:45:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i64)` error: transmute from a `i128` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:39:37 + --> tests/ui/transmute_int_to_non_zero.rs:48:37 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i128)` diff --git a/tests/ui/transmute_null_to_fn.rs b/tests/ui/transmute_null_to_fn.rs index c0196ad52d43..a9eaf16d05aa 100644 --- a/tests/ui/transmute_null_to_fn.rs +++ b/tests/ui/transmute_null_to_fn.rs @@ -6,9 +6,11 @@ fn one_liners() { unsafe { let _: fn() = std::mem::transmute(0 as *const ()); - //~^ ERROR: transmuting a known null pointer into a function pointer + //~^ transmute_null_to_fn + let _: fn() = std::mem::transmute(std::ptr::null::<()>()); - //~^ ERROR: transmuting a known null pointer into a function pointer + //~^ transmute_null_to_fn + } } @@ -19,7 +21,8 @@ fn transmute_const() { unsafe { // Should raise a lint. let _: fn() = std::mem::transmute(ZPTR); - //~^ ERROR: transmuting a known null pointer into a function pointer + //~^ transmute_null_to_fn + // Should NOT raise a lint. let _: fn() = std::mem::transmute(NOT_ZPTR); } @@ -28,11 +31,14 @@ fn transmute_const() { fn issue_11485() { unsafe { let _: fn() = std::mem::transmute(0 as *const u8 as *const ()); - //~^ ERROR: transmuting a known null pointer into a function pointer + //~^ transmute_null_to_fn + let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8); - //~^ ERROR: transmuting a known null pointer into a function pointer + //~^ transmute_null_to_fn + let _: fn() = std::mem::transmute(ZPTR as *const u8); - //~^ ERROR: transmuting a known null pointer into a function pointer + //~^ transmute_null_to_fn + } } diff --git a/tests/ui/transmute_null_to_fn.stderr b/tests/ui/transmute_null_to_fn.stderr index cea7b42cb801..9b2253c444f4 100644 --- a/tests/ui/transmute_null_to_fn.stderr +++ b/tests/ui/transmute_null_to_fn.stderr @@ -9,7 +9,7 @@ LL | let _: fn() = std::mem::transmute(0 as *const ()); = help: to override `-D warnings` add `#[allow(clippy::transmute_null_to_fn)]` error: transmuting a known null pointer into a function pointer - --> tests/ui/transmute_null_to_fn.rs:10:23 + --> tests/ui/transmute_null_to_fn.rs:11:23 | LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior @@ -17,7 +17,7 @@ LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>()); = help: try wrapping your function pointer type in `Option` instead, and using `None` as a null pointer value error: transmuting a known null pointer into a function pointer - --> tests/ui/transmute_null_to_fn.rs:21:23 + --> tests/ui/transmute_null_to_fn.rs:23:23 | LL | let _: fn() = std::mem::transmute(ZPTR); | ^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior @@ -25,7 +25,7 @@ LL | let _: fn() = std::mem::transmute(ZPTR); = help: try wrapping your function pointer type in `Option` instead, and using `None` as a null pointer value error: transmuting a known null pointer into a function pointer - --> tests/ui/transmute_null_to_fn.rs:30:23 + --> tests/ui/transmute_null_to_fn.rs:33:23 | LL | let _: fn() = std::mem::transmute(0 as *const u8 as *const ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior @@ -33,7 +33,7 @@ LL | let _: fn() = std::mem::transmute(0 as *const u8 as *const ()); = help: try wrapping your function pointer type in `Option` instead, and using `None` as a null pointer value error: transmuting a known null pointer into a function pointer - --> tests/ui/transmute_null_to_fn.rs:32:23 + --> tests/ui/transmute_null_to_fn.rs:36:23 | LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior @@ -41,7 +41,7 @@ LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const = help: try wrapping your function pointer type in `Option` instead, and using `None` as a null pointer value error: transmuting a known null pointer into a function pointer - --> tests/ui/transmute_null_to_fn.rs:34:23 + --> tests/ui/transmute_null_to_fn.rs:39:23 | LL | let _: fn() = std::mem::transmute(ZPTR as *const u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior diff --git a/tests/ui/transmute_ptr_to_ptr.fixed b/tests/ui/transmute_ptr_to_ptr.fixed index 39e67b250526..d595ecf32a1c 100644 --- a/tests/ui/transmute_ptr_to_ptr.fixed +++ b/tests/ui/transmute_ptr_to_ptr.fixed @@ -31,26 +31,35 @@ fn transmute_ptr_to_ptr() { // pointer-to-pointer transmutes; bad let _: *const f32 = ptr.cast::(); //~^ transmute_ptr_to_ptr + let _: *mut f32 = mut_ptr.cast::(); //~^ transmute_ptr_to_ptr + // ref-ref transmutes; bad let _: &f32 = &*(&1u32 as *const u32 as *const f32); //~^ transmute_ptr_to_ptr + let _: &f32 = &*(&1f64 as *const f64 as *const f32); //~^ transmute_ptr_to_ptr + //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not // the same type let _: &mut f32 = &mut *(&mut 1u32 as *mut u32 as *mut f32); //~^ transmute_ptr_to_ptr + let _: &GenericParam = &*(&GenericParam { t: 1u32 } as *const GenericParam as *const GenericParam); //~^ transmute_ptr_to_ptr + let u64_ref: &u64 = &0u64; let u8_ref: &u8 = &*(u64_ref as *const u64 as *const u8); //~^ transmute_ptr_to_ptr + let _: *const u32 = mut_ptr.cast_const(); //~^ transmute_ptr_to_ptr + let _: *mut u32 = ptr.cast_mut(); //~^ transmute_ptr_to_ptr + } // transmute internal lifetimes, should not lint @@ -63,6 +72,7 @@ fn transmute_ptr_to_ptr() { fn lifetime_to_static(v: *mut &()) -> *const &'static () { unsafe { v as *const &() } //~^ transmute_ptr_to_ptr + } // dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959) @@ -77,6 +87,7 @@ const _: &() = { fn msrv_1_37(ptr: *const u8) { unsafe { let _: *const i8 = ptr as *const i8; + //~^ transmute_ptr_to_ptr } } @@ -84,6 +95,7 @@ fn msrv_1_37(ptr: *const u8) { fn msrv_1_38(ptr: *const u8) { unsafe { let _: *const i8 = ptr.cast::(); + //~^ transmute_ptr_to_ptr } } @@ -91,7 +103,9 @@ fn msrv_1_38(ptr: *const u8) { fn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) { unsafe { let _: *mut u8 = ptr as *mut u8; + //~^ transmute_ptr_to_ptr let _: *const u8 = mut_ptr as *const u8; + //~^ transmute_ptr_to_ptr } } @@ -99,7 +113,9 @@ fn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) { fn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) { unsafe { let _: *mut u8 = ptr.cast_mut(); + //~^ transmute_ptr_to_ptr let _: *const u8 = mut_ptr.cast_const(); + //~^ transmute_ptr_to_ptr } } diff --git a/tests/ui/transmute_ptr_to_ptr.rs b/tests/ui/transmute_ptr_to_ptr.rs index 580b28551734..2e72f86dd3b3 100644 --- a/tests/ui/transmute_ptr_to_ptr.rs +++ b/tests/ui/transmute_ptr_to_ptr.rs @@ -31,26 +31,35 @@ fn transmute_ptr_to_ptr() { // pointer-to-pointer transmutes; bad let _: *const f32 = transmute(ptr); //~^ transmute_ptr_to_ptr + let _: *mut f32 = transmute(mut_ptr); //~^ transmute_ptr_to_ptr + // ref-ref transmutes; bad let _: &f32 = transmute(&1u32); //~^ transmute_ptr_to_ptr + let _: &f32 = transmute(&1f64); //~^ transmute_ptr_to_ptr + //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not // the same type let _: &mut f32 = transmute(&mut 1u32); //~^ transmute_ptr_to_ptr + let _: &GenericParam = transmute(&GenericParam { t: 1u32 }); //~^ transmute_ptr_to_ptr + let u64_ref: &u64 = &0u64; let u8_ref: &u8 = transmute(u64_ref); //~^ transmute_ptr_to_ptr + let _: *const u32 = transmute(mut_ptr); //~^ transmute_ptr_to_ptr + let _: *mut u32 = transmute(ptr); //~^ transmute_ptr_to_ptr + } // transmute internal lifetimes, should not lint @@ -63,6 +72,7 @@ fn transmute_ptr_to_ptr() { fn lifetime_to_static(v: *mut &()) -> *const &'static () { unsafe { transmute(v) } //~^ transmute_ptr_to_ptr + } // dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959) @@ -77,6 +87,7 @@ const _: &() = { fn msrv_1_37(ptr: *const u8) { unsafe { let _: *const i8 = transmute(ptr); + //~^ transmute_ptr_to_ptr } } @@ -84,6 +95,7 @@ fn msrv_1_37(ptr: *const u8) { fn msrv_1_38(ptr: *const u8) { unsafe { let _: *const i8 = transmute(ptr); + //~^ transmute_ptr_to_ptr } } @@ -91,7 +103,9 @@ fn msrv_1_38(ptr: *const u8) { fn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) { unsafe { let _: *mut u8 = transmute(ptr); + //~^ transmute_ptr_to_ptr let _: *const u8 = transmute(mut_ptr); + //~^ transmute_ptr_to_ptr } } @@ -99,7 +113,9 @@ fn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) { fn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) { unsafe { let _: *mut u8 = transmute(ptr); + //~^ transmute_ptr_to_ptr let _: *const u8 = transmute(mut_ptr); + //~^ transmute_ptr_to_ptr } } diff --git a/tests/ui/transmute_ptr_to_ptr.stderr b/tests/ui/transmute_ptr_to_ptr.stderr index 8801eb943ce8..3e7e170eff7f 100644 --- a/tests/ui/transmute_ptr_to_ptr.stderr +++ b/tests/ui/transmute_ptr_to_ptr.stderr @@ -12,7 +12,7 @@ LL | let _: *const f32 = ptr.cast::(); | ~~~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:34:27 + --> tests/ui/transmute_ptr_to_ptr.rs:35:27 | LL | let _: *mut f32 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -23,37 +23,37 @@ LL | let _: *mut f32 = mut_ptr.cast::(); | ~~~~~~~~~~~~~~~~~~~~~ error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:37:23 + --> tests/ui/transmute_ptr_to_ptr.rs:39:23 | LL | let _: &f32 = transmute(&1u32); | ^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:39:23 + --> tests/ui/transmute_ptr_to_ptr.rs:42:23 | LL | let _: &f32 = transmute(&1f64); | ^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:43:27 + --> tests/ui/transmute_ptr_to_ptr.rs:47:27 | LL | let _: &mut f32 = transmute(&mut 1u32); | ^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:45:37 + --> tests/ui/transmute_ptr_to_ptr.rs:50:37 | LL | let _: &GenericParam = transmute(&GenericParam { t: 1u32 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam as *const GenericParam)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:48:27 + --> tests/ui/transmute_ptr_to_ptr.rs:54:27 | LL | let u8_ref: &u8 = transmute(u64_ref); | ^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)` error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:50:29 + --> tests/ui/transmute_ptr_to_ptr.rs:57:29 | LL | let _: *const u32 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | let _: *const u32 = mut_ptr.cast_const(); | ~~~~~~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:52:27 + --> tests/ui/transmute_ptr_to_ptr.rs:60:27 | LL | let _: *mut u32 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -75,7 +75,7 @@ LL | let _: *mut u32 = ptr.cast_mut(); | ~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:64:14 + --> tests/ui/transmute_ptr_to_ptr.rs:73:14 | LL | unsafe { transmute(v) } | ^^^^^^^^^^^^ @@ -86,7 +86,7 @@ LL | unsafe { v as *const &() } | ~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:79:28 + --> tests/ui/transmute_ptr_to_ptr.rs:89:28 | LL | let _: *const i8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _: *const i8 = ptr as *const i8; | ~~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:86:28 + --> tests/ui/transmute_ptr_to_ptr.rs:97:28 | LL | let _: *const i8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | let _: *const i8 = ptr.cast::(); | ~~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:93:26 + --> tests/ui/transmute_ptr_to_ptr.rs:105:26 | LL | let _: *mut u8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | let _: *mut u8 = ptr as *mut u8; | ~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:94:28 + --> tests/ui/transmute_ptr_to_ptr.rs:107:28 | LL | let _: *const u8 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -130,7 +130,7 @@ LL | let _: *const u8 = mut_ptr as *const u8; | ~~~~~~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:101:26 + --> tests/ui/transmute_ptr_to_ptr.rs:115:26 | LL | let _: *mut u8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -141,7 +141,7 @@ LL | let _: *mut u8 = ptr.cast_mut(); | ~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:102:28 + --> tests/ui/transmute_ptr_to_ptr.rs:117:28 | LL | let _: *const u8 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute_ptr_to_ref.fixed b/tests/ui/transmute_ptr_to_ref.fixed index 56330d719389..1bd45bc10a39 100644 --- a/tests/ui/transmute_ptr_to_ref.fixed +++ b/tests/ui/transmute_ptr_to_ref.fixed @@ -7,24 +7,31 @@ unsafe fn _ptr_to_ref(p: *const T, m: *mut T, o: *const U, om: *mut U) { let _: &T = &*p; + //~^ transmute_ptr_to_ref let _: &T = &*p; let _: &mut T = &mut *m; + //~^ transmute_ptr_to_ref let _: &mut T = &mut *m; let _: &T = &*m; + //~^ transmute_ptr_to_ref let _: &T = &*m; let _: &mut T = &mut *(p as *mut T); + //~^ transmute_ptr_to_ref let _ = &mut *(p as *mut T); let _: &T = &*(o as *const T); + //~^ transmute_ptr_to_ref let _: &T = &*(o as *const T); let _: &mut T = &mut *(om as *mut T); + //~^ transmute_ptr_to_ref let _: &mut T = &mut *(om as *mut T); let _: &T = &*(om as *const T); + //~^ transmute_ptr_to_ref let _: &T = &*(om as *const T); } @@ -35,20 +42,27 @@ fn _issue1231() { let raw = 42 as *const i32; let _: &Foo = unsafe { &*raw.cast::>() }; + //~^ transmute_ptr_to_ref let _: &Foo<&u8> = unsafe { &*raw.cast::>() }; + //~^ transmute_ptr_to_ref type Bar<'a> = &'a u8; let raw = 42 as *const i32; unsafe { &*(raw as *const u8) }; + //~^ transmute_ptr_to_ref } unsafe fn _issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 { match 0 { 0 => &*x.cast::<&u32>(), + //~^ transmute_ptr_to_ref 1 => &*y.cast::<&u32>(), + //~^ transmute_ptr_to_ref 2 => &*x.cast::<&'b u32>(), + //~^ transmute_ptr_to_ref _ => &*y.cast::<&'b u32>(), + //~^ transmute_ptr_to_ref } } @@ -57,10 +71,14 @@ unsafe fn _meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { let a = 0u32; let a = &a as *const u32; let _: &u32 = &*a; + //~^ transmute_ptr_to_ref let _: &u32 = &*a.cast::(); + //~^ transmute_ptr_to_ref match 0 { 0 => &*x.cast::<&u32>(), + //~^ transmute_ptr_to_ref _ => &*x.cast::<&'b u32>(), + //~^ transmute_ptr_to_ref } } @@ -69,10 +87,14 @@ unsafe fn _under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { let a = 0u32; let a = &a as *const u32; let _: &u32 = &*a; + //~^ transmute_ptr_to_ref let _: &u32 = &*(a as *const u32); + //~^ transmute_ptr_to_ref match 0 { 0 => &*(x as *const () as *const &u32), + //~^ transmute_ptr_to_ref _ => &*(x as *const () as *const &'b u32), + //~^ transmute_ptr_to_ref } } diff --git a/tests/ui/transmute_ptr_to_ref.rs b/tests/ui/transmute_ptr_to_ref.rs index ce1ee8bfbfae..cbe64bf1ea6b 100644 --- a/tests/ui/transmute_ptr_to_ref.rs +++ b/tests/ui/transmute_ptr_to_ref.rs @@ -7,24 +7,31 @@ unsafe fn _ptr_to_ref(p: *const T, m: *mut T, o: *const U, om: *mut U) { let _: &T = std::mem::transmute(p); + //~^ transmute_ptr_to_ref let _: &T = &*p; let _: &mut T = std::mem::transmute(m); + //~^ transmute_ptr_to_ref let _: &mut T = &mut *m; let _: &T = std::mem::transmute(m); + //~^ transmute_ptr_to_ref let _: &T = &*m; let _: &mut T = std::mem::transmute(p as *mut T); + //~^ transmute_ptr_to_ref let _ = &mut *(p as *mut T); let _: &T = std::mem::transmute(o); + //~^ transmute_ptr_to_ref let _: &T = &*(o as *const T); let _: &mut T = std::mem::transmute(om); + //~^ transmute_ptr_to_ref let _: &mut T = &mut *(om as *mut T); let _: &T = std::mem::transmute(om); + //~^ transmute_ptr_to_ref let _: &T = &*(om as *const T); } @@ -35,20 +42,27 @@ fn _issue1231() { let raw = 42 as *const i32; let _: &Foo = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) }; + //~^ transmute_ptr_to_ref let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) }; + //~^ transmute_ptr_to_ref type Bar<'a> = &'a u8; let raw = 42 as *const i32; unsafe { std::mem::transmute::<_, Bar>(raw) }; + //~^ transmute_ptr_to_ref } unsafe fn _issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 { match 0 { 0 => std::mem::transmute(x), + //~^ transmute_ptr_to_ref 1 => std::mem::transmute(y), + //~^ transmute_ptr_to_ref 2 => std::mem::transmute::<_, &&'b u32>(x), + //~^ transmute_ptr_to_ref _ => std::mem::transmute::<_, &&'b u32>(y), + //~^ transmute_ptr_to_ref } } @@ -57,10 +71,14 @@ unsafe fn _meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { let a = 0u32; let a = &a as *const u32; let _: &u32 = std::mem::transmute(a); + //~^ transmute_ptr_to_ref let _: &u32 = std::mem::transmute::<_, &u32>(a); + //~^ transmute_ptr_to_ref match 0 { 0 => std::mem::transmute(x), + //~^ transmute_ptr_to_ref _ => std::mem::transmute::<_, &&'b u32>(x), + //~^ transmute_ptr_to_ref } } @@ -69,10 +87,14 @@ unsafe fn _under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { let a = 0u32; let a = &a as *const u32; let _: &u32 = std::mem::transmute(a); + //~^ transmute_ptr_to_ref let _: &u32 = std::mem::transmute::<_, &u32>(a); + //~^ transmute_ptr_to_ref match 0 { 0 => std::mem::transmute(x), + //~^ transmute_ptr_to_ref _ => std::mem::transmute::<_, &&'b u32>(x), + //~^ transmute_ptr_to_ref } } diff --git a/tests/ui/transmute_ptr_to_ref.stderr b/tests/ui/transmute_ptr_to_ref.stderr index 44cda254c3f7..7fad9b4065a5 100644 --- a/tests/ui/transmute_ptr_to_ref.stderr +++ b/tests/ui/transmute_ptr_to_ref.stderr @@ -8,127 +8,127 @@ LL | let _: &T = std::mem::transmute(p); = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ref)]` error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`) - --> tests/ui/transmute_ptr_to_ref.rs:12:21 + --> tests/ui/transmute_ptr_to_ref.rs:13:21 | LL | let _: &mut T = std::mem::transmute(m); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *m` error: transmute from a pointer type (`*mut T`) to a reference type (`&T`) - --> tests/ui/transmute_ptr_to_ref.rs:15:17 + --> tests/ui/transmute_ptr_to_ref.rs:17:17 | LL | let _: &T = std::mem::transmute(m); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*m` error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`) - --> tests/ui/transmute_ptr_to_ref.rs:18:21 + --> tests/ui/transmute_ptr_to_ref.rs:21:21 | LL | let _: &mut T = std::mem::transmute(p as *mut T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(p as *mut T)` error: transmute from a pointer type (`*const U`) to a reference type (`&T`) - --> tests/ui/transmute_ptr_to_ref.rs:21:17 + --> tests/ui/transmute_ptr_to_ref.rs:25:17 | LL | let _: &T = std::mem::transmute(o); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(o as *const T)` error: transmute from a pointer type (`*mut U`) to a reference type (`&mut T`) - --> tests/ui/transmute_ptr_to_ref.rs:24:21 + --> tests/ui/transmute_ptr_to_ref.rs:29:21 | LL | let _: &mut T = std::mem::transmute(om); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(om as *mut T)` error: transmute from a pointer type (`*mut U`) to a reference type (`&T`) - --> tests/ui/transmute_ptr_to_ref.rs:27:17 + --> tests/ui/transmute_ptr_to_ref.rs:33:17 | LL | let _: &T = std::mem::transmute(om); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(om as *const T)` error: transmute from a pointer type (`*const i32`) to a reference type (`&_issue1231::Foo<'_, u8>`) - --> tests/ui/transmute_ptr_to_ref.rs:37:32 + --> tests/ui/transmute_ptr_to_ref.rs:44:32 | LL | let _: &Foo = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::>()` error: transmute from a pointer type (`*const i32`) to a reference type (`&_issue1231::Foo<'_, &u8>`) - --> tests/ui/transmute_ptr_to_ref.rs:39:33 + --> tests/ui/transmute_ptr_to_ref.rs:47:33 | LL | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::>()` error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`) - --> tests/ui/transmute_ptr_to_ref.rs:43:14 + --> tests/ui/transmute_ptr_to_ref.rs:52:14 | LL | unsafe { std::mem::transmute::<_, Bar>(raw) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const u8)` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:48:14 + --> tests/ui/transmute_ptr_to_ref.rs:58:14 | LL | 0 => std::mem::transmute(x), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:49:14 + --> tests/ui/transmute_ptr_to_ref.rs:60:14 | LL | 1 => std::mem::transmute(y), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:50:14 + --> tests/ui/transmute_ptr_to_ref.rs:62:14 | LL | 2 => std::mem::transmute::<_, &&'b u32>(x), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:51:14 + --> tests/ui/transmute_ptr_to_ref.rs:64:14 | LL | _ => std::mem::transmute::<_, &&'b u32>(y), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&'b u32>()` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:59:19 + --> tests/ui/transmute_ptr_to_ref.rs:73:19 | LL | let _: &u32 = std::mem::transmute(a); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:60:19 + --> tests/ui/transmute_ptr_to_ref.rs:75:19 | LL | let _: &u32 = std::mem::transmute::<_, &u32>(a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a.cast::()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:62:14 + --> tests/ui/transmute_ptr_to_ref.rs:78:14 | LL | 0 => std::mem::transmute(x), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:63:14 + --> tests/ui/transmute_ptr_to_ref.rs:80:14 | LL | _ => std::mem::transmute::<_, &&'b u32>(x), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:71:19 + --> tests/ui/transmute_ptr_to_ref.rs:89:19 | LL | let _: &u32 = std::mem::transmute(a); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:72:19 + --> tests/ui/transmute_ptr_to_ref.rs:91:19 | LL | let _: &u32 = std::mem::transmute::<_, &u32>(a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const u32)` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:74:14 + --> tests/ui/transmute_ptr_to_ref.rs:94:14 | LL | 0 => std::mem::transmute(x), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &u32)` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:75:14 + --> tests/ui/transmute_ptr_to_ref.rs:96:14 | LL | _ => std::mem::transmute::<_, &&'b u32>(x), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &'b u32)` diff --git a/tests/ui/transmute_ref_to_ref.rs b/tests/ui/transmute_ref_to_ref.rs index 44d7af44a805..c2094ab0cad6 100644 --- a/tests/ui/transmute_ref_to_ref.rs +++ b/tests/ui/transmute_ref_to_ref.rs @@ -7,12 +7,15 @@ fn main() { unsafe { let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF]; let bools: &[bool] = unsafe { std::mem::transmute(single_u64) }; - //~^ ERROR: transmute from a reference to a reference + //~^ transmute_ptr_to_ptr + let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321]; let b: &[u8] = unsafe { std::mem::transmute(a) }; - //~^ ERROR: transmute from a reference to a reference + //~^ transmute_ptr_to_ptr + let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8]; let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) }; - //~^ ERROR: transmute from a reference to a reference + //~^ transmute_ptr_to_ptr + } } diff --git a/tests/ui/transmute_ref_to_ref.stderr b/tests/ui/transmute_ref_to_ref.stderr index e2d04cea8959..e8d659f9c5d8 100644 --- a/tests/ui/transmute_ref_to_ref.stderr +++ b/tests/ui/transmute_ref_to_ref.stderr @@ -11,13 +11,13 @@ LL | #![deny(clippy::transmute_ptr_to_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a reference to a reference - --> tests/ui/transmute_ref_to_ref.rs:12:33 + --> tests/ui/transmute_ref_to_ref.rs:13:33 | LL | let b: &[u8] = unsafe { std::mem::transmute(a) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const [u32] as *const [u8])` error: transmute from a reference to a reference - --> tests/ui/transmute_ref_to_ref.rs:15:42 + --> tests/ui/transmute_ref_to_ref.rs:17:42 | LL | let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])` diff --git a/tests/ui/transmute_ref_to_ref_no_std.rs b/tests/ui/transmute_ref_to_ref_no_std.rs index 591770587549..86c4189d87e4 100644 --- a/tests/ui/transmute_ref_to_ref_no_std.rs +++ b/tests/ui/transmute_ref_to_ref_no_std.rs @@ -19,12 +19,15 @@ fn main() { unsafe { let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF]; let bools: &[bool] = unsafe { core::mem::transmute(single_u64) }; - //~^ ERROR: transmute from a reference to a reference + //~^ transmute_ptr_to_ptr + let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321]; let b: &[u8] = unsafe { core::mem::transmute(a) }; - //~^ ERROR: transmute from a reference to a reference + //~^ transmute_ptr_to_ptr + let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8]; let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) }; - //~^ ERROR: transmute from a reference to a reference + //~^ transmute_ptr_to_ptr + } } diff --git a/tests/ui/transmute_ref_to_ref_no_std.stderr b/tests/ui/transmute_ref_to_ref_no_std.stderr index 6a76d6729d05..9aa9ed928a4d 100644 --- a/tests/ui/transmute_ref_to_ref_no_std.stderr +++ b/tests/ui/transmute_ref_to_ref_no_std.stderr @@ -11,13 +11,13 @@ LL | #![deny(clippy::transmute_ptr_to_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a reference to a reference - --> tests/ui/transmute_ref_to_ref_no_std.rs:24:33 + --> tests/ui/transmute_ref_to_ref_no_std.rs:25:33 | LL | let b: &[u8] = unsafe { core::mem::transmute(a) }; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const [u32] as *const [u8])` error: transmute from a reference to a reference - --> tests/ui/transmute_ref_to_ref_no_std.rs:27:42 + --> tests/ui/transmute_ref_to_ref_no_std.rs:29:42 | LL | let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])` diff --git a/tests/ui/transmute_undefined_repr.rs b/tests/ui/transmute_undefined_repr.rs index 5b16d71f1142..db876150f406 100644 --- a/tests/ui/transmute_undefined_repr.rs +++ b/tests/ui/transmute_undefined_repr.rs @@ -32,11 +32,13 @@ fn main() { // Lint, Ty2 is unordered let _: Ty2C = transmute(value::>()); - //~^ ERROR: transmute from `Ty2` which has an undefined layout - //~| NOTE: `-D clippy::transmute-undefined-repr` implied by `-D warnings` + //~^ transmute_undefined_repr + + // Lint, Ty2 is unordered let _: Ty2 = transmute(value::>()); - //~^ ERROR: transmute into `Ty2` which has an undefined layout + //~^ transmute_undefined_repr + // Ok, Ty2 types are the same let _: Ty2 = transmute(value::>>()); @@ -45,24 +47,28 @@ fn main() { // Lint, different Ty2 instances let _: Ty2 = transmute(value::>>()); - //~^ ERROR: transmute from `Ty>` to `Ty2`, both of which h - //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou + //~^ transmute_undefined_repr + + // Lint, different Ty2 instances let _: Ty> = transmute(value::>()); - //~^ ERROR: transmute from `Ty2` to `Ty>`, both of which h - //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou + //~^ transmute_undefined_repr + + let _: Ty<&()> = transmute(value::<&()>()); let _: &() = transmute(value::>()); // Lint, different Ty2 instances let _: &Ty2 = transmute(value::>>()); - //~^ ERROR: transmute from `Ty<&Ty2>` to `&Ty2`, both of which - //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou + //~^ transmute_undefined_repr + + // Lint, different Ty2 instances let _: Ty<&Ty2> = transmute(value::<&Ty2>()); - //~^ ERROR: transmute from `&Ty2` to `Ty<&Ty2>`, both of which - //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou + //~^ transmute_undefined_repr + + // Ok, pointer to usize conversion let _: Ty = transmute(value::<&Ty2>()); @@ -91,12 +97,14 @@ fn main() { // Lint, different Ty2 instances let _: &'static mut Ty2 = transmute(value::>>()); - //~^ ERROR: transmute from `std::boxed::Box>` to `&mut Ty2 - //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou + //~^ transmute_undefined_repr + + // Lint, different Ty2 instances let _: Box> = transmute(value::<&'static mut Ty2>()); - //~^ ERROR: transmute from `&mut Ty2` to `std::boxed::Box> - //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou + //~^ transmute_undefined_repr + + // Ok, type erasure let _: *const () = transmute(value::>>()); @@ -192,12 +200,14 @@ fn main() { // Err let _: *const Ty2 = transmute(value::<*const Ty2C>>()); - //~^ ERROR: transmute into `*const Ty2` which has an undefined layout - //~| NOTE: the contained type `Ty2` has an undefined layout + //~^ transmute_undefined_repr + + // Err let _: *const Ty2C> = transmute(value::<*const Ty2>()); - //~^ ERROR: transmute from `*const Ty2` which has an undefined layout - //~| NOTE: the contained type `Ty2` has an undefined layout + //~^ transmute_undefined_repr + + // Ok let _: NonNull = transmute(value::>()); @@ -243,12 +253,14 @@ fn _with_generics() { // Err let _: Vec> = transmute(value::>>()); - //~^ ERROR: transmute from `std::vec::Vec>` to `std::vec::Vec> = transmute(value::>>()); - //~^ ERROR: transmute from `std::vec::Vec>` to `std::vec::Vec>()); diff --git a/tests/ui/transmute_undefined_repr.stderr b/tests/ui/transmute_undefined_repr.stderr index b41d37a5cd13..a569309b2eb4 100644 --- a/tests/ui/transmute_undefined_repr.stderr +++ b/tests/ui/transmute_undefined_repr.stderr @@ -8,13 +8,13 @@ LL | let _: Ty2C = transmute(value::>()); = help: to override `-D warnings` add `#[allow(clippy::transmute_undefined_repr)]` error: transmute into `Ty2` which has an undefined layout - --> tests/ui/transmute_undefined_repr.rs:38:32 + --> tests/ui/transmute_undefined_repr.rs:39:32 | LL | let _: Ty2 = transmute(value::>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `Ty>` to `Ty2`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:47:32 + --> tests/ui/transmute_undefined_repr.rs:49:32 | LL | let _: Ty2 = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | let _: Ty2 = transmute(value::>>()); = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `Ty2` to `Ty>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:51:36 + --> tests/ui/transmute_undefined_repr.rs:54:36 | LL | let _: Ty> = transmute(value::>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | let _: Ty> = transmute(value::>()); = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `Ty<&Ty2>` to `&Ty2`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:59:33 + --> tests/ui/transmute_undefined_repr.rs:63:33 | LL | let _: &Ty2 = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | let _: &Ty2 = transmute(value::>>()); = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `&Ty2` to `Ty<&Ty2>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:63:37 + --> tests/ui/transmute_undefined_repr.rs:68:37 | LL | let _: Ty<&Ty2> = transmute(value::<&Ty2>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | let _: Ty<&Ty2> = transmute(value::<&Ty2>()); = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `std::boxed::Box>` to `&mut Ty2`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:93:45 + --> tests/ui/transmute_undefined_repr.rs:99:45 | LL | let _: &'static mut Ty2 = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | let _: &'static mut Ty2 = transmute(value::` to `std::boxed::Box>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:97:37 + --> tests/ui/transmute_undefined_repr.rs:104:37 | LL | let _: Box> = transmute(value::<&'static mut Ty2>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -62,7 +62,7 @@ LL | let _: Box> = transmute(value::<&'static mut Ty2` which has an undefined layout - --> tests/ui/transmute_undefined_repr.rs:194:39 + --> tests/ui/transmute_undefined_repr.rs:202:39 | LL | let _: *const Ty2 = transmute(value::<*const Ty2C>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | let _: *const Ty2 = transmute(value::<*const Ty2C` has an undefined layout error: transmute from `*const Ty2` which has an undefined layout - --> tests/ui/transmute_undefined_repr.rs:198:50 + --> tests/ui/transmute_undefined_repr.rs:207:50 | LL | let _: *const Ty2C> = transmute(value::<*const Ty2>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _: *const Ty2C> = transmute(value::<*const T = note: the contained type `Ty2` has an undefined layout error: transmute from `std::vec::Vec>` to `std::vec::Vec>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:245:35 + --> tests/ui/transmute_undefined_repr.rs:255:35 | LL | let _: Vec> = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -86,7 +86,7 @@ LL | let _: Vec> = transmute(value::>>()); = note: two instances of the same generic type (`Vec`) may have different layouts error: transmute from `std::vec::Vec>` to `std::vec::Vec>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:249:35 + --> tests/ui/transmute_undefined_repr.rs:260:35 | LL | let _: Vec> = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/tests/ui/transmutes_expressible_as_ptr_casts.fixed index a4a3ca82e76c..e7ad2a1cbbcb 100644 --- a/tests/ui/transmutes_expressible_as_ptr_casts.fixed +++ b/tests/ui/transmutes_expressible_as_ptr_casts.fixed @@ -15,28 +15,33 @@ fn main() { // e is an integer and U is *U_0, while U_0: Sized; addr-ptr-cast let _ptr_i32_transmute = unsafe { usize::MAX as *const i32 }; + //~^ useless_transmute let ptr_i32 = usize::MAX as *const i32; // e has type *T, U is *U_0, and either U_0: Sized ... let _ptr_i8_transmute = unsafe { ptr_i32.cast::() }; + //~^ transmute_ptr_to_ptr let _ptr_i8 = ptr_i32 as *const i8; let slice_ptr = &[0, 1, 2, 3] as *const [i32]; // ... or pointer_kind(T) = pointer_kind(U_0); ptr-ptr-cast let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] }; + //~^ transmute_ptr_to_ptr let _ptr_to_unsized = slice_ptr as *const [u32]; // TODO: We could try testing vtable casts here too, but maybe // we should wait until std::raw::TraitObject is stabilized? // e has type *T and U is a numeric type, while T: Sized; ptr-addr-cast let _usize_from_int_ptr_transmute = unsafe { ptr_i32 as usize }; + //~^ transmutes_expressible_as_ptr_casts let _usize_from_int_ptr = ptr_i32 as usize; let array_ref: &[i32; 4] = &[1, 2, 3, 4]; // e has type &[T; n] and U is *const T; array-ptr-cast let _array_ptr_transmute = unsafe { array_ref as *const [i32; 4] }; + //~^ useless_transmute let _array_ptr = array_ref as *const [i32; 4]; fn foo(_: usize) -> u8 { @@ -45,13 +50,16 @@ fn main() { // e is a function pointer type and U has type *T, while T: Sized; fptr-ptr-cast let _usize_ptr_transmute = unsafe { foo as *const usize }; + //~^ transmutes_expressible_as_ptr_casts let _usize_ptr_transmute = foo as *const usize; // e is a function pointer type and U is an integer; fptr-addr-cast let _usize_from_fn_ptr_transmute = unsafe { foo as usize }; + //~^ transmutes_expressible_as_ptr_casts let _usize_from_fn_ptr = foo as *const usize; let _usize_from_ref = unsafe { &1u32 as *const u32 as usize }; + //~^ transmutes_expressible_as_ptr_casts } // If a ref-to-ptr cast of this form where the pointer type points to a type other @@ -63,6 +71,7 @@ fn main() { // fall through into `do_check`. fn trigger_do_check_to_emit_error(in_param: &[i32; 1]) -> *const u8 { unsafe { in_param as *const [i32; 1] as *const u8 } + //~^ useless_transmute } #[repr(C)] @@ -81,6 +90,7 @@ fn issue_10449() { fn f() {} let _x: u8 = unsafe { *(f as *const u8) }; + //~^ transmutes_expressible_as_ptr_casts } // Pointers cannot be cast to integers in const contexts diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.rs b/tests/ui/transmutes_expressible_as_ptr_casts.rs index 6aa8e384e268..42a81777a826 100644 --- a/tests/ui/transmutes_expressible_as_ptr_casts.rs +++ b/tests/ui/transmutes_expressible_as_ptr_casts.rs @@ -15,28 +15,33 @@ fn main() { // e is an integer and U is *U_0, while U_0: Sized; addr-ptr-cast let _ptr_i32_transmute = unsafe { transmute::(usize::MAX) }; + //~^ useless_transmute let ptr_i32 = usize::MAX as *const i32; // e has type *T, U is *U_0, and either U_0: Sized ... let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) }; + //~^ transmute_ptr_to_ptr let _ptr_i8 = ptr_i32 as *const i8; let slice_ptr = &[0, 1, 2, 3] as *const [i32]; // ... or pointer_kind(T) = pointer_kind(U_0); ptr-ptr-cast let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) }; + //~^ transmute_ptr_to_ptr let _ptr_to_unsized = slice_ptr as *const [u32]; // TODO: We could try testing vtable casts here too, but maybe // we should wait until std::raw::TraitObject is stabilized? // e has type *T and U is a numeric type, while T: Sized; ptr-addr-cast let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, usize>(ptr_i32) }; + //~^ transmutes_expressible_as_ptr_casts let _usize_from_int_ptr = ptr_i32 as usize; let array_ref: &[i32; 4] = &[1, 2, 3, 4]; // e has type &[T; n] and U is *const T; array-ptr-cast let _array_ptr_transmute = unsafe { transmute::<&[i32; 4], *const [i32; 4]>(array_ref) }; + //~^ useless_transmute let _array_ptr = array_ref as *const [i32; 4]; fn foo(_: usize) -> u8 { @@ -45,13 +50,16 @@ fn main() { // e is a function pointer type and U has type *T, while T: Sized; fptr-ptr-cast let _usize_ptr_transmute = unsafe { transmute:: u8, *const usize>(foo) }; + //~^ transmutes_expressible_as_ptr_casts let _usize_ptr_transmute = foo as *const usize; // e is a function pointer type and U is an integer; fptr-addr-cast let _usize_from_fn_ptr_transmute = unsafe { transmute:: u8, usize>(foo) }; + //~^ transmutes_expressible_as_ptr_casts let _usize_from_fn_ptr = foo as *const usize; let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) }; + //~^ transmutes_expressible_as_ptr_casts } // If a ref-to-ptr cast of this form where the pointer type points to a type other @@ -63,6 +71,7 @@ fn main() { // fall through into `do_check`. fn trigger_do_check_to_emit_error(in_param: &[i32; 1]) -> *const u8 { unsafe { transmute::<&[i32; 1], *const u8>(in_param) } + //~^ useless_transmute } #[repr(C)] @@ -81,6 +90,7 @@ fn issue_10449() { fn f() {} let _x: u8 = unsafe { *std::mem::transmute::(f) }; + //~^ transmutes_expressible_as_ptr_casts } // Pointers cannot be cast to integers in const contexts diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.stderr b/tests/ui/transmutes_expressible_as_ptr_casts.stderr index 2d74967ede56..1dab24a78d87 100644 --- a/tests/ui/transmutes_expressible_as_ptr_casts.stderr +++ b/tests/ui/transmutes_expressible_as_ptr_casts.stderr @@ -8,7 +8,7 @@ LL | let _ptr_i32_transmute = unsafe { transmute::(usize: = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]` error: transmute from a pointer to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:21:38 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:22:38 | LL | let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL | let _ptr_i8_transmute = unsafe { ptr_i32.cast::() }; | ~~~~~~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:27:46 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:29:46 | LL | let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] }; | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:33:50 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:36:50 | LL | let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, usize>(ptr_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr_i32 as usize` @@ -41,37 +41,37 @@ LL | let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, us = help: to override `-D warnings` add `#[allow(clippy::transmutes_expressible_as_ptr_casts)]` error: transmute from a reference to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:39:41 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:43:41 | LL | let _array_ptr_transmute = unsafe { transmute::<&[i32; 4], *const [i32; 4]>(array_ref) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `array_ref as *const [i32; 4]` error: transmute from `fn(usize) -> u8` to `*const usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:47:41 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:52:41 | LL | let _usize_ptr_transmute = unsafe { transmute:: u8, *const usize>(foo) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as *const usize` error: transmute from `fn(usize) -> u8` to `usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:51:49 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:57:49 | LL | let _usize_from_fn_ptr_transmute = unsafe { transmute:: u8, usize>(foo) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as usize` error: transmute from `*const u32` to `usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:54:36 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:61:36 | LL | let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&1u32 as *const u32 as usize` error: transmute from a reference to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:65:14 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:73:14 | LL | unsafe { transmute::<&[i32; 1], *const u8>(in_param) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `in_param as *const [i32; 1] as *const u8` error: transmute from `fn()` to `*const u8` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:83:28 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:92:28 | LL | let _x: u8 = unsafe { *std::mem::transmute::(f) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(f as *const u8)` diff --git a/tests/ui/transmuting_null.rs b/tests/ui/transmuting_null.rs index c2deb6b6c460..91f32a725589 100644 --- a/tests/ui/transmuting_null.rs +++ b/tests/ui/transmuting_null.rs @@ -8,10 +8,12 @@ fn one_liners() { unsafe { let _: &u64 = std::mem::transmute(0 as *const u64); - //~^ ERROR: transmuting a known null pointer into a reference - //~| NOTE: `-D clippy::transmuting-null` implied by `-D warnings` + //~^ transmuting_null + + let _: &u64 = std::mem::transmute(std::ptr::null::()); - //~^ ERROR: transmuting a known null pointer into a reference + //~^ transmuting_null + } } @@ -22,7 +24,8 @@ fn transmute_const() { unsafe { // Should raise a lint. let _: &u64 = std::mem::transmute(ZPTR); - //~^ ERROR: transmuting a known null pointer into a reference + //~^ transmuting_null + // Should NOT raise a lint. let _: &u64 = std::mem::transmute(NOT_ZPTR); } diff --git a/tests/ui/transmuting_null.stderr b/tests/ui/transmuting_null.stderr index 84e6e374d525..2e5fffd3ac28 100644 --- a/tests/ui/transmuting_null.stderr +++ b/tests/ui/transmuting_null.stderr @@ -8,13 +8,13 @@ LL | let _: &u64 = std::mem::transmute(0 as *const u64); = help: to override `-D warnings` add `#[allow(clippy::transmuting_null)]` error: transmuting a known null pointer into a reference - --> tests/ui/transmuting_null.rs:13:23 + --> tests/ui/transmuting_null.rs:14:23 | LL | let _: &u64 = std::mem::transmute(std::ptr::null::()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmuting a known null pointer into a reference - --> tests/ui/transmuting_null.rs:24:23 + --> tests/ui/transmuting_null.rs:26:23 | LL | let _: &u64 = std::mem::transmute(ZPTR); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/trim_split_whitespace.fixed b/tests/ui/trim_split_whitespace.fixed index 6d3daf798a67..c7c241e3075f 100644 --- a/tests/ui/trim_split_whitespace.fixed +++ b/tests/ui/trim_split_whitespace.fixed @@ -59,13 +59,19 @@ impl DerefStrAndCustomTrim { fn main() { // &str let _ = " A B C ".split_whitespace(); // should trigger lint + //~^ trim_split_whitespace let _ = " A B C ".split_whitespace(); // should trigger lint + //~^ trim_split_whitespace let _ = " A B C ".split_whitespace(); // should trigger lint + //~^ trim_split_whitespace // String let _ = (" A B C ").to_string().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace let _ = (" A B C ").to_string().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace let _ = (" A B C ").to_string().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace // Custom let _ = Custom.trim().split_whitespace(); // should not trigger lint @@ -73,6 +79,7 @@ fn main() { // Deref let s = DerefStr(" A B C "); let _ = s.split_whitespace(); // should trigger lint + //~^ trim_split_whitespace // Deref + custom impl let s = DerefStrAndCustom(" A B C "); @@ -81,6 +88,7 @@ fn main() { // Deref + only custom split_ws() impl let s = DerefStrAndCustomSplit(" A B C "); let _ = s.split_whitespace(); // should trigger lint + //~^ trim_split_whitespace // Expl: trim() is called on str (deref) and returns &str. // Thus split_ws() is called on str as well and the custom impl on S is unused diff --git a/tests/ui/trim_split_whitespace.rs b/tests/ui/trim_split_whitespace.rs index b49d9e8b3fab..aa2cd92430ed 100644 --- a/tests/ui/trim_split_whitespace.rs +++ b/tests/ui/trim_split_whitespace.rs @@ -59,13 +59,19 @@ impl DerefStrAndCustomTrim { fn main() { // &str let _ = " A B C ".trim().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace let _ = " A B C ".trim_start().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace let _ = " A B C ".trim_end().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace // String let _ = (" A B C ").to_string().trim().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace let _ = (" A B C ").to_string().trim_start().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace let _ = (" A B C ").to_string().trim_end().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace // Custom let _ = Custom.trim().split_whitespace(); // should not trigger lint @@ -73,6 +79,7 @@ fn main() { // Deref let s = DerefStr(" A B C "); let _ = s.trim().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace // Deref + custom impl let s = DerefStrAndCustom(" A B C "); @@ -81,6 +88,7 @@ fn main() { // Deref + only custom split_ws() impl let s = DerefStrAndCustomSplit(" A B C "); let _ = s.trim().split_whitespace(); // should trigger lint + //~^ trim_split_whitespace // Expl: trim() is called on str (deref) and returns &str. // Thus split_ws() is called on str as well and the custom impl on S is unused diff --git a/tests/ui/trim_split_whitespace.stderr b/tests/ui/trim_split_whitespace.stderr index 6119d21a8e9a..deaec54d9363 100644 --- a/tests/ui/trim_split_whitespace.stderr +++ b/tests/ui/trim_split_whitespace.stderr @@ -8,43 +8,43 @@ LL | let _ = " A B C ".trim().split_whitespace(); // should trigger lint = help: to override `-D warnings` add `#[allow(clippy::trim_split_whitespace)]` error: found call to `str::trim_start` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:62:23 + --> tests/ui/trim_split_whitespace.rs:63:23 | LL | let _ = " A B C ".trim_start().split_whitespace(); // should trigger lint | ^^^^^^^^^^^^^ help: remove `trim_start()` error: found call to `str::trim_end` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:63:23 + --> tests/ui/trim_split_whitespace.rs:65:23 | LL | let _ = " A B C ".trim_end().split_whitespace(); // should trigger lint | ^^^^^^^^^^^ help: remove `trim_end()` error: found call to `str::trim` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:66:37 + --> tests/ui/trim_split_whitespace.rs:69:37 | LL | let _ = (" A B C ").to_string().trim().split_whitespace(); // should trigger lint | ^^^^^^^ help: remove `trim()` error: found call to `str::trim_start` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:67:37 + --> tests/ui/trim_split_whitespace.rs:71:37 | LL | let _ = (" A B C ").to_string().trim_start().split_whitespace(); // should trigger lint | ^^^^^^^^^^^^^ help: remove `trim_start()` error: found call to `str::trim_end` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:68:37 + --> tests/ui/trim_split_whitespace.rs:73:37 | LL | let _ = (" A B C ").to_string().trim_end().split_whitespace(); // should trigger lint | ^^^^^^^^^^^ help: remove `trim_end()` error: found call to `str::trim` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:75:15 + --> tests/ui/trim_split_whitespace.rs:81:15 | LL | let _ = s.trim().split_whitespace(); // should trigger lint | ^^^^^^^ help: remove `trim()` error: found call to `str::trim` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:83:15 + --> tests/ui/trim_split_whitespace.rs:90:15 | LL | let _ = s.trim().split_whitespace(); // should trigger lint | ^^^^^^^ help: remove `trim()` diff --git a/tests/ui/trivially_copy_pass_by_ref.rs b/tests/ui/trivially_copy_pass_by_ref.rs index 043a7b63af3c..37bc6f89a20a 100644 --- a/tests/ui/trivially_copy_pass_by_ref.rs +++ b/tests/ui/trivially_copy_pass_by_ref.rs @@ -52,6 +52,7 @@ fn good_return_explicit_lt_struct<'a>(foo: &'a Foo) -> FooRef<'a> { fn bad(x: &u32, y: &Foo, z: &Baz) {} //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by +//~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by impl Foo { fn good(self, a: &mut u32, b: u32, c: &Bar) {} diff --git a/tests/ui/trivially_copy_pass_by_ref.stderr b/tests/ui/trivially_copy_pass_by_ref.stderr index 4887fb00e742..e813fecf653a 100644 --- a/tests/ui/trivially_copy_pass_by_ref.stderr +++ b/tests/ui/trivially_copy_pass_by_ref.stderr @@ -23,91 +23,91 @@ LL | fn bad(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:61:12 + --> tests/ui/trivially_copy_pass_by_ref.rs:62:12 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^^ help: consider passing by value instead: `self` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:61:22 + --> tests/ui/trivially_copy_pass_by_ref.rs:62:22 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:61:31 + --> tests/ui/trivially_copy_pass_by_ref.rs:62:31 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:61:40 + --> tests/ui/trivially_copy_pass_by_ref.rs:62:40 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:67:16 + --> tests/ui/trivially_copy_pass_by_ref.rs:68:16 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:67:25 + --> tests/ui/trivially_copy_pass_by_ref.rs:68:25 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:67:34 + --> tests/ui/trivially_copy_pass_by_ref.rs:68:34 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:72:35 + --> tests/ui/trivially_copy_pass_by_ref.rs:73:35 | LL | fn bad_issue7518(self, other: &Self) {} | ^^^^^ help: consider passing by value instead: `Self` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:85:16 + --> tests/ui/trivially_copy_pass_by_ref.rs:86:16 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:85:25 + --> tests/ui/trivially_copy_pass_by_ref.rs:86:25 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:85:34 + --> tests/ui/trivially_copy_pass_by_ref.rs:86:34 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:92:34 + --> tests/ui/trivially_copy_pass_by_ref.rs:93:34 | LL | fn trait_method(&self, _foo: &Foo); | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:125:21 + --> tests/ui/trivially_copy_pass_by_ref.rs:126:21 | LL | fn foo_never(x: &i32) { | ^^^^ help: consider passing by value instead: `i32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:131:15 + --> tests/ui/trivially_copy_pass_by_ref.rs:132:15 | LL | fn foo(x: &i32) { | ^^^^ help: consider passing by value instead: `i32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte) - --> tests/ui/trivially_copy_pass_by_ref.rs:159:37 + --> tests/ui/trivially_copy_pass_by_ref.rs:160:37 | LL | fn _unrelated_lifetimes<'a, 'b>(_x: &'a u32, y: &'b u32) -> &'b u32 { | ^^^^^^^ help: consider passing by value instead: `u32` diff --git a/tests/ui/try_err.fixed b/tests/ui/try_err.fixed index f149bfb77740..ea509f9a2da8 100644 --- a/tests/ui/try_err.fixed +++ b/tests/ui/try_err.fixed @@ -20,6 +20,7 @@ pub fn basic_test() -> Result { // To avoid warnings during rustfix if true { return Err(err); + //~^ try_err } Ok(0) } @@ -30,6 +31,7 @@ pub fn into_test() -> Result { // To avoid warnings during rustfix if true { return Err(err.into()); + //~^ try_err } Ok(0) } @@ -50,6 +52,7 @@ pub fn closure_matches_test() -> Result { // To avoid warnings during rustfix if true { return Err(err); + //~^ try_err } Ok(i) }) @@ -69,6 +72,7 @@ pub fn closure_into_test() -> Result { // To avoid warnings during rustfix if true { return Err(err.into()); + //~^ try_err } Ok(i) }) @@ -89,6 +93,7 @@ fn calling_macro() -> Result { match $(Ok::<_, i32>(5)) { Ok(_) => 0, Err(_) => return Err(1), + //~^ try_err } ); // `Err` arg is another macro @@ -96,6 +101,7 @@ fn calling_macro() -> Result { match $(Ok::<_, i32>(5)) { Ok(_) => 0, Err(_) => return Err(inline!(1)), + //~^ try_err } ); Ok(5) @@ -123,6 +129,7 @@ fn main() { pub fn macro_inside(fail: bool) -> Result { if fail { return Err(inline!(inline!(String::from("aasdfasdfasdfa")))); + //~^ try_err } Ok(0) } @@ -130,8 +137,10 @@ pub fn macro_inside(fail: bool) -> Result { pub fn poll_write(n: usize) -> Poll> { if n == 0 { return Poll::Ready(Err(io::ErrorKind::WriteZero.into())) + //~^ try_err } else if n == 1 { return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))) + //~^ try_err }; Poll::Ready(Ok(n)) @@ -140,6 +149,7 @@ pub fn poll_write(n: usize) -> Poll> { pub fn poll_next(ready: bool) -> Poll>> { if !ready { return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into()))) + //~^ try_err } Poll::Ready(None) @@ -149,6 +159,7 @@ pub fn poll_next(ready: bool) -> Poll>> { pub fn try_return(x: bool) -> Result { if x { return Err(42); + //~^ try_err } Ok(0) } diff --git a/tests/ui/try_err.rs b/tests/ui/try_err.rs index 841ec6b5d5c7..295f7bd7089b 100644 --- a/tests/ui/try_err.rs +++ b/tests/ui/try_err.rs @@ -20,6 +20,7 @@ pub fn basic_test() -> Result { // To avoid warnings during rustfix if true { Err(err)?; + //~^ try_err } Ok(0) } @@ -30,6 +31,7 @@ pub fn into_test() -> Result { // To avoid warnings during rustfix if true { Err(err)?; + //~^ try_err } Ok(0) } @@ -50,6 +52,7 @@ pub fn closure_matches_test() -> Result { // To avoid warnings during rustfix if true { Err(err)?; + //~^ try_err } Ok(i) }) @@ -69,6 +72,7 @@ pub fn closure_into_test() -> Result { // To avoid warnings during rustfix if true { Err(err)?; + //~^ try_err } Ok(i) }) @@ -89,6 +93,7 @@ fn calling_macro() -> Result { match $(Ok::<_, i32>(5)) { Ok(_) => 0, Err(_) => Err(1)?, + //~^ try_err } ); // `Err` arg is another macro @@ -96,6 +101,7 @@ fn calling_macro() -> Result { match $(Ok::<_, i32>(5)) { Ok(_) => 0, Err(_) => Err(inline!(1))?, + //~^ try_err } ); Ok(5) @@ -123,6 +129,7 @@ fn main() { pub fn macro_inside(fail: bool) -> Result { if fail { Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?; + //~^ try_err } Ok(0) } @@ -130,8 +137,10 @@ pub fn macro_inside(fail: bool) -> Result { pub fn poll_write(n: usize) -> Poll> { if n == 0 { Err(io::ErrorKind::WriteZero)? + //~^ try_err } else if n == 1 { Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))? + //~^ try_err }; Poll::Ready(Ok(n)) @@ -140,6 +149,7 @@ pub fn poll_write(n: usize) -> Poll> { pub fn poll_next(ready: bool) -> Poll>> { if !ready { Err(io::ErrorKind::NotFound)? + //~^ try_err } Poll::Ready(None) @@ -149,6 +159,7 @@ pub fn poll_next(ready: bool) -> Poll>> { pub fn try_return(x: bool) -> Result { if x { return Err(42)?; + //~^ try_err } Ok(0) } diff --git a/tests/ui/try_err.stderr b/tests/ui/try_err.stderr index fb563d407866..50c2b092d6c8 100644 --- a/tests/ui/try_err.stderr +++ b/tests/ui/try_err.stderr @@ -11,25 +11,25 @@ LL | #![deny(clippy::try_err)] | ^^^^^^^^^^^^^^^ error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:32:9 + --> tests/ui/try_err.rs:33:9 | LL | Err(err)?; | ^^^^^^^^^ help: try: `return Err(err.into())` error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:52:17 + --> tests/ui/try_err.rs:54:17 | LL | Err(err)?; | ^^^^^^^^^ help: try: `return Err(err)` error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:71:17 + --> tests/ui/try_err.rs:74:17 | LL | Err(err)?; | ^^^^^^^^^ help: try: `return Err(err.into())` error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:91:23 + --> tests/ui/try_err.rs:95:23 | LL | Err(_) => Err(1)?, | ^^^^^^^ help: try: `return Err(1)` @@ -37,7 +37,7 @@ LL | Err(_) => Err(1)?, = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:98:23 + --> tests/ui/try_err.rs:103:23 | LL | Err(_) => Err(inline!(1))?, | ^^^^^^^^^^^^^^^^ help: try: `return Err(inline!(1))` @@ -45,31 +45,31 @@ LL | Err(_) => Err(inline!(1))?, = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:125:9 + --> tests/ui/try_err.rs:131:9 | LL | Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Err(inline!(inline!(String::from("aasdfasdfasdfa"))))` error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:132:9 + --> tests/ui/try_err.rs:139:9 | LL | Err(io::ErrorKind::WriteZero)? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))` error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:134:9 + --> tests/ui/try_err.rs:142:9 | LL | Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error")))` error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:142:9 + --> tests/ui/try_err.rs:151:9 | LL | Err(io::ErrorKind::NotFound)? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))` error: returning an `Err(_)` with the `?` operator - --> tests/ui/try_err.rs:151:16 + --> tests/ui/try_err.rs:161:16 | LL | return Err(42)?; | ^^^^^^^^ help: try: `Err(42)` diff --git a/tests/ui/tuple_array_conversions.rs b/tests/ui/tuple_array_conversions.rs index ca79cc104f22..772c41df090e 100644 --- a/tests/ui/tuple_array_conversions.rs +++ b/tests/ui/tuple_array_conversions.rs @@ -8,15 +8,21 @@ extern crate proc_macros; fn main() { let x = [1, 2]; let x = (x[0], x[1]); + //~^ tuple_array_conversions let x = [x.0, x.1]; + //~^ tuple_array_conversions let x = &[1, 2]; let x = (x[0], x[1]); let t1: &[(u32, u32)] = &[(1, 2), (3, 4)]; let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect(); + //~^ tuple_array_conversions t1.iter().for_each(|&(a, b)| _ = [a, b]); + //~^ tuple_array_conversions let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect(); + //~^ tuple_array_conversions t1.iter().for_each(|&(a, b)| _ = [a, b]); + //~^ tuple_array_conversions // Do not lint let v2: Vec<[u32; 2]> = t1.iter().map(|&t| t.into()).collect(); let t3: Vec<(u32, u32)> = v2.iter().map(|&v| v.into()).collect(); @@ -55,9 +61,11 @@ fn main() { // FP #11082; needs discussion let (a, b) = (1.0f64, 2.0f64); let _: &[f64] = &[a, b]; + //~^ tuple_array_conversions // FP #11085; impossible to fix let [src, dest]: [_; 2] = [1, 2]; (src, dest); + //~^ tuple_array_conversions // FP #11100 fn issue_11100_array_to_tuple(this: [&mut i32; 2]) -> (&i32, &mut i32) { let [input, output] = this; @@ -102,7 +110,9 @@ fn msrv_too_low() { fn msrv_juust_right() { let x = [1, 2]; let x = (x[0], x[1]); + //~^ tuple_array_conversions let x = [x.0, x.1]; + //~^ tuple_array_conversions let x = &[1, 2]; let x = (x[0], x[1]); } diff --git a/tests/ui/tuple_array_conversions.stderr b/tests/ui/tuple_array_conversions.stderr index 9e022b3cfb25..6dafb8d285d4 100644 --- a/tests/ui/tuple_array_conversions.stderr +++ b/tests/ui/tuple_array_conversions.stderr @@ -9,7 +9,7 @@ LL | let x = (x[0], x[1]); = help: to override `-D warnings` add `#[allow(clippy::tuple_array_conversions)]` error: it looks like you're trying to convert a tuple to an array - --> tests/ui/tuple_array_conversions.rs:11:13 + --> tests/ui/tuple_array_conversions.rs:12:13 | LL | let x = [x.0, x.1]; | ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let x = [x.0, x.1]; = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed error: it looks like you're trying to convert a tuple to an array - --> tests/ui/tuple_array_conversions.rs:16:53 + --> tests/ui/tuple_array_conversions.rs:18:53 | LL | let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect(); | ^^^^^^ @@ -25,7 +25,7 @@ LL | let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect(); = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed error: it looks like you're trying to convert a tuple to an array - --> tests/ui/tuple_array_conversions.rs:17:38 + --> tests/ui/tuple_array_conversions.rs:20:38 | LL | t1.iter().for_each(|&(a, b)| _ = [a, b]); | ^^^^^^ @@ -33,7 +33,7 @@ LL | t1.iter().for_each(|&(a, b)| _ = [a, b]); = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed error: it looks like you're trying to convert an array to a tuple - --> tests/ui/tuple_array_conversions.rs:18:55 + --> tests/ui/tuple_array_conversions.rs:22:55 | LL | let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect(); | ^^^^^^ @@ -41,7 +41,7 @@ LL | let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect(); = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed error: it looks like you're trying to convert a tuple to an array - --> tests/ui/tuple_array_conversions.rs:19:38 + --> tests/ui/tuple_array_conversions.rs:24:38 | LL | t1.iter().for_each(|&(a, b)| _ = [a, b]); | ^^^^^^ @@ -49,7 +49,7 @@ LL | t1.iter().for_each(|&(a, b)| _ = [a, b]); = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed error: it looks like you're trying to convert a tuple to an array - --> tests/ui/tuple_array_conversions.rs:57:22 + --> tests/ui/tuple_array_conversions.rs:63:22 | LL | let _: &[f64] = &[a, b]; | ^^^^^^ @@ -57,7 +57,7 @@ LL | let _: &[f64] = &[a, b]; = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed error: it looks like you're trying to convert an array to a tuple - --> tests/ui/tuple_array_conversions.rs:60:5 + --> tests/ui/tuple_array_conversions.rs:67:5 | LL | (src, dest); | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | (src, dest); = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed error: it looks like you're trying to convert an array to a tuple - --> tests/ui/tuple_array_conversions.rs:104:13 + --> tests/ui/tuple_array_conversions.rs:112:13 | LL | let x = (x[0], x[1]); | ^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let x = (x[0], x[1]); = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed error: it looks like you're trying to convert a tuple to an array - --> tests/ui/tuple_array_conversions.rs:105:13 + --> tests/ui/tuple_array_conversions.rs:114:13 | LL | let x = [x.0, x.1]; | ^^^^^^^^^^ diff --git a/tests/ui/ty_fn_sig.rs b/tests/ui/ty_fn_sig.rs index 9e2753dcb18d..60767bfad135 100644 --- a/tests/ui/ty_fn_sig.rs +++ b/tests/ui/ty_fn_sig.rs @@ -1,3 +1,4 @@ +//@ check-pass // Regression test pub fn retry(f: F) { diff --git a/tests/ui/type_complexity.rs b/tests/ui/type_complexity.rs index be28ee2da0cd..09c7bcc68408 100644 --- a/tests/ui/type_complexity.rs +++ b/tests/ui/type_complexity.rs @@ -5,42 +5,54 @@ type Alias = Vec>>; // no warning here const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); -//~^ ERROR: very complex type used. Consider factoring parts into `type` definitions -//~| NOTE: `-D clippy::type-complexity` implied by `-D warnings` +//~^ type_complexity + + static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); -//~^ ERROR: very complex type used. Consider factoring parts into `type` definitions +//~^ type_complexity + struct S { f: Vec>>, - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + } struct Ts(Vec>>); -//~^ ERROR: very complex type used. Consider factoring parts into `type` definitions +//~^ type_complexity + enum E { Tuple(Vec>>), - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + Struct { f: Vec>> }, - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + } impl S { const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + fn impl_method(&self, p: Vec>>) {} - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + } trait T { const A: Vec>>; - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + type B = Vec>>; - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + fn method(&self, p: Vec>>); - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + fn def_method(&self, p: Vec>>) {} - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + } // Should not warn since there is likely no way to simplify this (#1013) @@ -53,16 +65,19 @@ impl T for () { } fn test1() -> Vec>> { - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions +//~^ type_complexity + vec![] } fn test2(_x: Vec>>) {} -//~^ ERROR: very complex type used. Consider factoring parts into `type` definitions +//~^ type_complexity + fn test3() { let _y: Vec>> = vec![]; - //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions + //~^ type_complexity + } #[repr(C)] diff --git a/tests/ui/type_complexity.stderr b/tests/ui/type_complexity.stderr index 9e27899e4f90..4926432aab88 100644 --- a/tests/ui/type_complexity.stderr +++ b/tests/ui/type_complexity.stderr @@ -8,85 +8,85 @@ LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]` error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:10:12 + --> tests/ui/type_complexity.rs:11:12 | LL | static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:14:8 + --> tests/ui/type_complexity.rs:16:8 | LL | f: Vec>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:18:11 + --> tests/ui/type_complexity.rs:21:11 | LL | struct Ts(Vec>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:22:11 + --> tests/ui/type_complexity.rs:26:11 | LL | Tuple(Vec>>), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:24:17 + --> tests/ui/type_complexity.rs:29:17 | LL | Struct { f: Vec>> }, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:29:14 + --> tests/ui/type_complexity.rs:35:14 | LL | const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:31:30 + --> tests/ui/type_complexity.rs:38:30 | LL | fn impl_method(&self, p: Vec>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:36:14 + --> tests/ui/type_complexity.rs:44:14 | LL | const A: Vec>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:38:14 + --> tests/ui/type_complexity.rs:47:14 | LL | type B = Vec>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:40:25 + --> tests/ui/type_complexity.rs:50:25 | LL | fn method(&self, p: Vec>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:42:29 + --> tests/ui/type_complexity.rs:53:29 | LL | fn def_method(&self, p: Vec>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:55:15 + --> tests/ui/type_complexity.rs:67:15 | LL | fn test1() -> Vec>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:60:14 + --> tests/ui/type_complexity.rs:73:14 | LL | fn test2(_x: Vec>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:64:13 + --> tests/ui/type_complexity.rs:78:13 | LL | let _y: Vec>> = vec![]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type_id_on_box.fixed b/tests/ui/type_id_on_box.fixed index 3656043700fa..f0d8a4acb2e3 100644 --- a/tests/ui/type_id_on_box.fixed +++ b/tests/ui/type_id_on_box.fixed @@ -29,7 +29,8 @@ fn main() { let any_box: Box = Box::new(0usize); let _ = (*any_box).type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + // Don't lint. We explicitly say "do this instead" if this is intentional let _ = TypeId::of::>(); @@ -38,18 +39,21 @@ fn main() { // 2 derefs are needed here to get to the `dyn Any` let any_box: &Box = &(Box::new(0usize) as Box); let _ = (**any_box).type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + let b = existential(); let _ = b.type_id(); // Don't let b: Box = Box::new(1); let _ = (*b).type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + let b: SomeBox = Box::new(0usize); let _ = (*b).type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + let b = BadBox(Box::new(0usize)); let _ = b.type_id(); // Don't lint. This is a call to `::type_id`. Not `std::boxed::Box`! diff --git a/tests/ui/type_id_on_box.rs b/tests/ui/type_id_on_box.rs index 4bd9e73f2da0..b446ec287b67 100644 --- a/tests/ui/type_id_on_box.rs +++ b/tests/ui/type_id_on_box.rs @@ -29,7 +29,8 @@ fn main() { let any_box: Box = Box::new(0usize); let _ = any_box.type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + // Don't lint. We explicitly say "do this instead" if this is intentional let _ = TypeId::of::>(); @@ -38,18 +39,21 @@ fn main() { // 2 derefs are needed here to get to the `dyn Any` let any_box: &Box = &(Box::new(0usize) as Box); let _ = any_box.type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + let b = existential(); let _ = b.type_id(); // Don't let b: Box = Box::new(1); let _ = b.type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + let b: SomeBox = Box::new(0usize); let _ = b.type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + let b = BadBox(Box::new(0usize)); let _ = b.type_id(); // Don't lint. This is a call to `::type_id`. Not `std::boxed::Box`! diff --git a/tests/ui/type_id_on_box.stderr b/tests/ui/type_id_on_box.stderr index 4528195607da..8004ef71287c 100644 --- a/tests/ui/type_id_on_box.stderr +++ b/tests/ui/type_id_on_box.stderr @@ -12,7 +12,7 @@ LL | let _ = any_box.type_id(); = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]` error: calling `.type_id()` on `Box` - --> tests/ui/type_id_on_box.rs:40:13 + --> tests/ui/type_id_on_box.rs:41:13 | LL | let _ = any_box.type_id(); | -------^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = any_box.type_id(); = note: if this is intentional, use `TypeId::of::>()` instead, which makes it more clear error: calling `.type_id()` on `Box` - --> tests/ui/type_id_on_box.rs:47:13 + --> tests/ui/type_id_on_box.rs:49:13 | LL | let _ = b.type_id(); | -^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = b.type_id(); = note: if this is intentional, use `TypeId::of::>()` instead, which makes it more clear error: calling `.type_id()` on `Box` - --> tests/ui/type_id_on_box.rs:51:13 + --> tests/ui/type_id_on_box.rs:54:13 | LL | let _ = b.type_id(); | -^^^^^^^^^^ diff --git a/tests/ui/type_id_on_box_unfixable.rs b/tests/ui/type_id_on_box_unfixable.rs index 67e398e604b4..4df0ebb897a8 100644 --- a/tests/ui/type_id_on_box_unfixable.rs +++ b/tests/ui/type_id_on_box_unfixable.rs @@ -23,9 +23,11 @@ fn main() { // could) let b: Box = Box::new(1); let _ = b.type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + let b: Box = Box::new(1); let _ = b.type_id(); - //~^ ERROR: calling `.type_id()` on + //~^ type_id_on_box + } diff --git a/tests/ui/type_id_on_box_unfixable.stderr b/tests/ui/type_id_on_box_unfixable.stderr index 539ed481ec10..c653fd7835ff 100644 --- a/tests/ui/type_id_on_box_unfixable.stderr +++ b/tests/ui/type_id_on_box_unfixable.stderr @@ -10,7 +10,7 @@ LL | let _ = b.type_id(); = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]` error: calling `.type_id()` on `Box` - --> tests/ui/type_id_on_box_unfixable.rs:29:13 + --> tests/ui/type_id_on_box_unfixable.rs:30:13 | LL | let _ = b.type_id(); | ^^^^^^^^^^^ diff --git a/tests/ui/unchecked_duration_subtraction.fixed b/tests/ui/unchecked_duration_subtraction.fixed index a0c3330d1777..bddffe44ac4d 100644 --- a/tests/ui/unchecked_duration_subtraction.fixed +++ b/tests/ui/unchecked_duration_subtraction.fixed @@ -7,10 +7,14 @@ fn main() { let second = Duration::from_secs(3); let _ = _first.checked_sub(second).unwrap(); + //~^ unchecked_duration_subtraction let _ = Instant::now().checked_sub(Duration::from_secs(5)).unwrap(); + //~^ unchecked_duration_subtraction let _ = _first.checked_sub(Duration::from_secs(5)).unwrap(); + //~^ unchecked_duration_subtraction let _ = Instant::now().checked_sub(second).unwrap(); + //~^ unchecked_duration_subtraction } diff --git a/tests/ui/unchecked_duration_subtraction.rs b/tests/ui/unchecked_duration_subtraction.rs index fff1d13720d9..bb0f71239642 100644 --- a/tests/ui/unchecked_duration_subtraction.rs +++ b/tests/ui/unchecked_duration_subtraction.rs @@ -7,10 +7,14 @@ fn main() { let second = Duration::from_secs(3); let _ = _first - second; + //~^ unchecked_duration_subtraction let _ = Instant::now() - Duration::from_secs(5); + //~^ unchecked_duration_subtraction let _ = _first - Duration::from_secs(5); + //~^ unchecked_duration_subtraction let _ = Instant::now() - second; + //~^ unchecked_duration_subtraction } diff --git a/tests/ui/unchecked_duration_subtraction.stderr b/tests/ui/unchecked_duration_subtraction.stderr index b5e9bab86b47..be291c320e68 100644 --- a/tests/ui/unchecked_duration_subtraction.stderr +++ b/tests/ui/unchecked_duration_subtraction.stderr @@ -8,19 +8,19 @@ LL | let _ = _first - second; = help: to override `-D warnings` add `#[allow(clippy::unchecked_duration_subtraction)]` error: unchecked subtraction of a 'Duration' from an 'Instant' - --> tests/ui/unchecked_duration_subtraction.rs:11:13 + --> tests/ui/unchecked_duration_subtraction.rs:12:13 | LL | let _ = Instant::now() - Duration::from_secs(5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(Duration::from_secs(5)).unwrap()` error: unchecked subtraction of a 'Duration' from an 'Instant' - --> tests/ui/unchecked_duration_subtraction.rs:13:13 + --> tests/ui/unchecked_duration_subtraction.rs:15:13 | LL | let _ = _first - Duration::from_secs(5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `_first.checked_sub(Duration::from_secs(5)).unwrap()` error: unchecked subtraction of a 'Duration' from an 'Instant' - --> tests/ui/unchecked_duration_subtraction.rs:15:13 + --> tests/ui/unchecked_duration_subtraction.rs:18:13 | LL | let _ = Instant::now() - second; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(second).unwrap()` diff --git a/tests/ui/unconditional_recursion.rs b/tests/ui/unconditional_recursion.rs index b8476a7088a1..6cbd6bffb8db 100644 --- a/tests/ui/unconditional_recursion.rs +++ b/tests/ui/unconditional_recursion.rs @@ -15,11 +15,13 @@ enum Foo { impl PartialEq for Foo { fn ne(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + self != other } fn eq(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + self == other } } @@ -31,9 +33,11 @@ enum Foo2 { impl PartialEq for Foo2 { fn ne(&self, other: &Self) -> bool { + //~^ unconditional_recursion self != &Foo2::B // no error here } fn eq(&self, other: &Self) -> bool { + //~^ unconditional_recursion self == &Foo2::B // no error here } } @@ -45,11 +49,14 @@ enum Foo3 { impl PartialEq for Foo3 { fn ne(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + //~| ERROR: function cannot return without recursing self.ne(other) } fn eq(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + //~| ERROR: function cannot return without recursing + self.eq(other) } } @@ -93,11 +100,13 @@ struct S; // Check the order doesn't matter. impl PartialEq for S { fn ne(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + other != self } fn eq(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + other == self } } @@ -107,12 +116,16 @@ struct S2; // Check that if the same element is compared, it's also triggering the lint. impl PartialEq for S2 { fn ne(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + other != other + //~^ eq_op } fn eq(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + other == other + //~^ eq_op } } @@ -120,12 +133,16 @@ struct S3; impl PartialEq for S3 { fn ne(&self, _other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + self != self + //~^ eq_op } fn eq(&self, _other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + self == self + //~^ eq_op } } @@ -152,7 +169,8 @@ macro_rules! impl_partial_eq { ($ty:ident) => { impl PartialEq for $ty { fn eq(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + self == other } } @@ -181,7 +199,8 @@ struct S7<'a> { impl<'a> PartialEq for S7<'a> { fn eq(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + let mine = &self.field; let theirs = &other.field; mine == theirs @@ -250,7 +269,8 @@ impl std::default::Default for S12 { impl S12 { fn new() -> Self { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + Self::default() } @@ -289,7 +309,8 @@ struct S15<'a> { impl PartialEq for S15<'_> { fn eq(&self, other: &Self) -> bool { - //~^ ERROR: function cannot return without recursing + //~^ unconditional_recursion + let mine = &self.field; let theirs = &other.field; mine.eq(theirs) @@ -360,6 +381,7 @@ struct BadFromTy1<'a>(&'a ()); struct BadIntoTy1<'b>(&'b ()); impl<'a> From> for BadIntoTy1<'static> { fn from(f: BadFromTy1<'a>) -> Self { + //~^ unconditional_recursion f.into() } } @@ -369,6 +391,7 @@ struct BadFromTy2<'a>(&'a ()); struct BadIntoTy2<'b>(&'b ()); impl<'a> From> for BadIntoTy2<'static> { fn from(f: BadFromTy2<'a>) -> Self { + //~^ unconditional_recursion Into::into(f) } } diff --git a/tests/ui/unconditional_recursion.stderr b/tests/ui/unconditional_recursion.stderr index 6a0078ee0906..c6eaa6a0775c 100644 --- a/tests/ui/unconditional_recursion.stderr +++ b/tests/ui/unconditional_recursion.stderr @@ -1,9 +1,9 @@ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:47:5 + --> tests/ui/unconditional_recursion.rs:51:5 | LL | fn ne(&self, other: &Self) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing -LL | +... LL | self.ne(other) | -------------- recursive call site | @@ -12,18 +12,18 @@ LL | self.ne(other) = help: to override `-D warnings` add `#[allow(unconditional_recursion)]` error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:51:5 + --> tests/ui/unconditional_recursion.rs:56:5 | LL | fn eq(&self, other: &Self) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing -LL | +... LL | self.eq(other) | -------------- recursive call site | = help: a `loop` may express intention better if this is on purpose error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:216:5 + --> tests/ui/unconditional_recursion.rs:235:5 | LL | fn to_string(&self) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -34,7 +34,7 @@ LL | self.to_string() = help: a `loop` may express intention better if this is on purpose error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:226:5 + --> tests/ui/unconditional_recursion.rs:245:5 | LL | fn to_string(&self) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -45,7 +45,7 @@ LL | x.to_string() = help: a `loop` may express intention better if this is on purpose error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:237:5 + --> tests/ui/unconditional_recursion.rs:256:5 | LL | fn to_string(&self) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -60,12 +60,13 @@ error: function cannot return without recursing | LL | / fn ne(&self, other: &Self) -> bool { LL | | +LL | | LL | | self != other LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:19:9 + --> tests/ui/unconditional_recursion.rs:20:9 | LL | self != other | ^^^^^^^^^^^^^ @@ -73,125 +74,132 @@ LL | self != other = help: to override `-D warnings` add `#[allow(clippy::unconditional_recursion)]` error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:21:5 + --> tests/ui/unconditional_recursion.rs:22:5 | LL | / fn eq(&self, other: &Self) -> bool { LL | | +LL | | LL | | self == other LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:23:9 + --> tests/ui/unconditional_recursion.rs:25:9 | LL | self == other | ^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:33:5 + --> tests/ui/unconditional_recursion.rs:35:5 | LL | / fn ne(&self, other: &Self) -> bool { +LL | | LL | | self != &Foo2::B // no error here -LL | | } - | |_____^ - | -note: recursive call site - --> tests/ui/unconditional_recursion.rs:34:9 - | -LL | self != &Foo2::B // no error here - | ^^^^^^^^^^^^^^^^ - -error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:36:5 - | -LL | / fn eq(&self, other: &Self) -> bool { -LL | | self == &Foo2::B // no error here LL | | } | |_____^ | note: recursive call site --> tests/ui/unconditional_recursion.rs:37:9 | +LL | self != &Foo2::B // no error here + | ^^^^^^^^^^^^^^^^ + +error: function cannot return without recursing + --> tests/ui/unconditional_recursion.rs:39:5 + | +LL | / fn eq(&self, other: &Self) -> bool { +LL | | +LL | | self == &Foo2::B // no error here +LL | | } + | |_____^ + | +note: recursive call site + --> tests/ui/unconditional_recursion.rs:41:9 + | LL | self == &Foo2::B // no error here | ^^^^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:47:5 + --> tests/ui/unconditional_recursion.rs:51:5 | LL | / fn ne(&self, other: &Self) -> bool { LL | | +LL | | LL | | self.ne(other) LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:49:9 + --> tests/ui/unconditional_recursion.rs:54:9 | LL | self.ne(other) | ^^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:51:5 + --> tests/ui/unconditional_recursion.rs:56:5 | LL | / fn eq(&self, other: &Self) -> bool { -LL | | -LL | | self.eq(other) +... | LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:53:9 + --> tests/ui/unconditional_recursion.rs:60:9 | LL | self.eq(other) | ^^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:95:5 + --> tests/ui/unconditional_recursion.rs:102:5 | LL | / fn ne(&self, other: &Self) -> bool { LL | | +LL | | LL | | other != self LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:97:9 + --> tests/ui/unconditional_recursion.rs:105:9 | LL | other != self | ^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:99:5 + --> tests/ui/unconditional_recursion.rs:107:5 | LL | / fn eq(&self, other: &Self) -> bool { LL | | +LL | | LL | | other == self LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:101:9 + --> tests/ui/unconditional_recursion.rs:110:9 | LL | other == self | ^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:109:5 + --> tests/ui/unconditional_recursion.rs:118:5 | LL | / fn ne(&self, other: &Self) -> bool { LL | | +LL | | LL | | other != other +LL | | LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:111:9 + --> tests/ui/unconditional_recursion.rs:121:9 | LL | other != other | ^^^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/unconditional_recursion.rs:111:9 + --> tests/ui/unconditional_recursion.rs:121:9 | LL | other != other | ^^^^^^^^^^^^^^ @@ -199,73 +207,80 @@ LL | other != other = note: `#[deny(clippy::eq_op)]` on by default error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:113:5 + --> tests/ui/unconditional_recursion.rs:124:5 | LL | / fn eq(&self, other: &Self) -> bool { LL | | +LL | | LL | | other == other +LL | | LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:115:9 + --> tests/ui/unconditional_recursion.rs:127:9 | LL | other == other | ^^^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/unconditional_recursion.rs:115:9 + --> tests/ui/unconditional_recursion.rs:127:9 | LL | other == other | ^^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:122:5 + --> tests/ui/unconditional_recursion.rs:135:5 | LL | / fn ne(&self, _other: &Self) -> bool { LL | | +LL | | LL | | self != self +LL | | LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:124:9 + --> tests/ui/unconditional_recursion.rs:138:9 | LL | self != self | ^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/unconditional_recursion.rs:124:9 + --> tests/ui/unconditional_recursion.rs:138:9 | LL | self != self | ^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:126:5 + --> tests/ui/unconditional_recursion.rs:141:5 | LL | / fn eq(&self, _other: &Self) -> bool { LL | | +LL | | LL | | self == self +LL | | LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:128:9 + --> tests/ui/unconditional_recursion.rs:144:9 | LL | self == self | ^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/unconditional_recursion.rs:128:9 + --> tests/ui/unconditional_recursion.rs:144:9 | LL | self == self | ^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:154:13 + --> tests/ui/unconditional_recursion.rs:171:13 | LL | / fn eq(&self, other: &Self) -> bool { LL | | +LL | | LL | | self == other LL | | } | |_____________^ @@ -274,7 +289,7 @@ LL | impl_partial_eq!(S5); | -------------------- in this macro invocation | note: recursive call site - --> tests/ui/unconditional_recursion.rs:156:17 + --> tests/ui/unconditional_recursion.rs:174:17 | LL | self == other | ^^^^^^^^^^^^^ @@ -284,10 +299,11 @@ LL | impl_partial_eq!(S5); = note: this error originates in the macro `impl_partial_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:183:5 + --> tests/ui/unconditional_recursion.rs:201:5 | LL | / fn eq(&self, other: &Self) -> bool { LL | | +LL | | LL | | let mine = &self.field; LL | | let theirs = &other.field; LL | | mine == theirs @@ -295,31 +311,33 @@ LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:187:9 + --> tests/ui/unconditional_recursion.rs:206:9 | LL | mine == theirs | ^^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:252:5 + --> tests/ui/unconditional_recursion.rs:271:5 | LL | / fn new() -> Self { LL | | +LL | | LL | | Self::default() LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:254:9 + --> tests/ui/unconditional_recursion.rs:274:9 | LL | Self::default() | ^^^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:291:5 + --> tests/ui/unconditional_recursion.rs:311:5 | LL | / fn eq(&self, other: &Self) -> bool { LL | | +LL | | LL | | let mine = &self.field; LL | | let theirs = &other.field; LL | | mine.eq(theirs) @@ -327,35 +345,37 @@ LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:295:9 + --> tests/ui/unconditional_recursion.rs:316:9 | LL | mine.eq(theirs) | ^^^^^^^^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:362:5 + --> tests/ui/unconditional_recursion.rs:383:5 | LL | / fn from(f: BadFromTy1<'a>) -> Self { +LL | | LL | | f.into() LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:363:9 + --> tests/ui/unconditional_recursion.rs:385:9 | LL | f.into() | ^^^^^^^^ error: function cannot return without recursing - --> tests/ui/unconditional_recursion.rs:371:5 + --> tests/ui/unconditional_recursion.rs:393:5 | LL | / fn from(f: BadFromTy2<'a>) -> Self { +LL | | LL | | Into::into(f) LL | | } | |_____^ | note: recursive call site - --> tests/ui/unconditional_recursion.rs:372:9 + --> tests/ui/unconditional_recursion.rs:395:9 | LL | Into::into(f) | ^^^^^^^^^^^^^ diff --git a/tests/ui/unicode.fixed b/tests/ui/unicode.fixed index f9efb4ec34c6..9234b440d964 100644 --- a/tests/ui/unicode.fixed +++ b/tests/ui/unicode.fixed @@ -3,16 +3,20 @@ #[warn(clippy::invisible_characters)] fn zero() { print!("Here >\u{200B}< is a ZWS, and \u{200B}another"); + //~^ invisible_characters print!("This\u{200B}is\u{200B}fine"); print!("Here >\u{AD}< is a SHY, and \u{AD}another"); + //~^ invisible_characters print!("This\u{ad}is\u{ad}fine"); print!("Here >\u{2060}< is a WJ, and \u{2060}another"); + //~^ invisible_characters print!("This\u{2060}is\u{2060}fine"); } #[warn(clippy::unicode_not_nfc)] fn canon() { print!("̀àh?"); + //~^ unicode_not_nfc print!("a\u{0300}h?"); // also ok } @@ -21,13 +25,16 @@ mod non_ascii_literal { fn uni() { print!("\u{dc}ben!"); + //~^ non_ascii_literal print!("\u{DC}ben!"); // this is ok } // issue 8013 fn single_quote() { const _EMPTY_BLOCK: char = '\u{25b1}'; + //~^ non_ascii_literal const _FULL_BLOCK: char = '\u{25b0}'; + //~^ non_ascii_literal } #[test] @@ -48,6 +55,7 @@ mod non_ascii_literal { #[test] fn denied() { let _ = "\u{60b2}\u{3057}\u{3044}\u{304b}\u{306a}\u{3001}\u{3053}\u{3053}\u{306b}\u{65e5}\u{672c}\u{8a9e}\u{3092}\u{66f8}\u{304f}\u{3053}\u{3068}\u{306f}\u{3067}\u{304d}\u{306a}\u{3044}\u{3002}"; + //~^ non_ascii_literal } } } diff --git a/tests/ui/unicode.rs b/tests/ui/unicode.rs index bba613e228ed..ada8bac8e049 100644 --- a/tests/ui/unicode.rs +++ b/tests/ui/unicode.rs @@ -3,16 +3,20 @@ #[warn(clippy::invisible_characters)] fn zero() { print!("Here >​< is a ZWS, and ​another"); + //~^ invisible_characters print!("This\u{200B}is\u{200B}fine"); print!("Here >­< is a SHY, and ­another"); + //~^ invisible_characters print!("This\u{ad}is\u{ad}fine"); print!("Here >⁠< is a WJ, and ⁠another"); + //~^ invisible_characters print!("This\u{2060}is\u{2060}fine"); } #[warn(clippy::unicode_not_nfc)] fn canon() { print!("̀àh?"); + //~^ unicode_not_nfc print!("a\u{0300}h?"); // also ok } @@ -21,13 +25,16 @@ mod non_ascii_literal { fn uni() { print!("Üben!"); + //~^ non_ascii_literal print!("\u{DC}ben!"); // this is ok } // issue 8013 fn single_quote() { const _EMPTY_BLOCK: char = '▱'; + //~^ non_ascii_literal const _FULL_BLOCK: char = '▰'; + //~^ non_ascii_literal } #[test] @@ -48,6 +55,7 @@ mod non_ascii_literal { #[test] fn denied() { let _ = "悲しいかな、ここに日本語を書くことはできない。"; + //~^ non_ascii_literal } } } diff --git a/tests/ui/unicode.stderr b/tests/ui/unicode.stderr index b004493300ee..c761ec89602f 100644 --- a/tests/ui/unicode.stderr +++ b/tests/ui/unicode.stderr @@ -8,19 +8,19 @@ LL | print!("Here >​< is a ZWS, and ​another"); = help: to override `-D warnings` add `#[allow(clippy::invisible_characters)]` error: invisible character detected - --> tests/ui/unicode.rs:7:12 + --> tests/ui/unicode.rs:8:12 | LL | print!("Here >­< is a SHY, and ­another"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >\u{AD}< is a SHY, and \u{AD}another"` error: invisible character detected - --> tests/ui/unicode.rs:9:12 + --> tests/ui/unicode.rs:11:12 | LL | print!("Here >⁠< is a WJ, and ⁠another"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >\u{2060}< is a WJ, and \u{2060}another"` error: non-NFC Unicode sequence detected - --> tests/ui/unicode.rs:15:12 + --> tests/ui/unicode.rs:18:12 | LL | print!("̀àh?"); | ^^^^^ help: consider replacing the string with: `"̀àh?"` @@ -29,37 +29,37 @@ LL | print!("̀àh?"); = help: to override `-D warnings` add `#[allow(clippy::unicode_not_nfc)]` error: literal non-ASCII character detected - --> tests/ui/unicode.rs:23:16 + --> tests/ui/unicode.rs:27:16 | LL | print!("Üben!"); | ^^^^^^^ help: consider replacing the string with: `"\u{dc}ben!"` | note: the lint level is defined here - --> tests/ui/unicode.rs:20:13 + --> tests/ui/unicode.rs:24:13 | LL | #![deny(clippy::non_ascii_literal)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: literal non-ASCII character detected - --> tests/ui/unicode.rs:29:36 + --> tests/ui/unicode.rs:34:36 | LL | const _EMPTY_BLOCK: char = '▱'; | ^^^ help: consider replacing the string with: `'\u{25b1}'` error: literal non-ASCII character detected - --> tests/ui/unicode.rs:30:35 + --> tests/ui/unicode.rs:36:35 | LL | const _FULL_BLOCK: char = '▰'; | ^^^ help: consider replacing the string with: `'\u{25b0}'` error: literal non-ASCII character detected - --> tests/ui/unicode.rs:50:21 + --> tests/ui/unicode.rs:57:21 | LL | let _ = "悲しいかな、ここに日本語を書くことはできない。"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"\u{60b2}\u{3057}\u{3044}\u{304b}\u{306a}\u{3001}\u{3053}\u{3053}\u{306b}\u{65e5}\u{672c}\u{8a9e}\u{3092}\u{66f8}\u{304f}\u{3053}\u{3068}\u{306f}\u{3067}\u{304d}\u{306a}\u{3044}\u{3002}"` | note: the lint level is defined here - --> tests/ui/unicode.rs:39:17 + --> tests/ui/unicode.rs:46:17 | LL | #![deny(clippy::non_ascii_literal)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/uninhabited_references.rs b/tests/ui/uninhabited_references.rs index 3569366ed056..649af4312ce4 100644 --- a/tests/ui/uninhabited_references.rs +++ b/tests/ui/uninhabited_references.rs @@ -3,13 +3,16 @@ #![feature(never_type)] fn ret_uninh_ref() -> &'static std::convert::Infallible { +//~^ uninhabited_references unsafe { std::mem::transmute(&()) } } macro_rules! ret_something { ($name:ident, $ty:ty) => { fn $name(x: &$ty) -> &$ty { + //~^ uninhabited_references &*x + //~^ uninhabited_references } }; } @@ -20,4 +23,5 @@ ret_something!(id_never, !); fn main() { let x = ret_uninh_ref(); let _ = *x; + //~^ uninhabited_references } diff --git a/tests/ui/uninhabited_references.stderr b/tests/ui/uninhabited_references.stderr index 8c9b206f4296..ac05ab5bb4d4 100644 --- a/tests/ui/uninhabited_references.stderr +++ b/tests/ui/uninhabited_references.stderr @@ -8,7 +8,7 @@ LL | fn ret_uninh_ref() -> &'static std::convert::Infallible { = help: to override `-D warnings` add `#[allow(clippy::uninhabited_references)]` error: dereferencing a reference to an uninhabited type would be undefined behavior - --> tests/ui/uninhabited_references.rs:11:30 + --> tests/ui/uninhabited_references.rs:12:30 | LL | fn $name(x: &$ty) -> &$ty { | ^^^^ @@ -19,7 +19,7 @@ LL | ret_something!(id_never, !); = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info) error: dereferencing a reference to an uninhabited type is undefined behavior - --> tests/ui/uninhabited_references.rs:12:14 + --> tests/ui/uninhabited_references.rs:14:14 | LL | &*x | ^^ @@ -30,7 +30,7 @@ LL | ret_something!(id_never, !); = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info) error: dereferencing a reference to an uninhabited type is undefined behavior - --> tests/ui/uninhabited_references.rs:22:13 + --> tests/ui/uninhabited_references.rs:25:13 | LL | let _ = *x; | ^^ diff --git a/tests/ui/uninit.rs b/tests/ui/uninit.rs index 10a4c22b5b91..965ef4a10b39 100644 --- a/tests/ui/uninit.rs +++ b/tests/ui/uninit.rs @@ -10,8 +10,9 @@ union MyOwnMaybeUninit { fn main() { let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; - //~^ ERROR: this call for this type may be undefined behavior - //~| NOTE: `#[deny(clippy::uninit_assumed_init)]` on by default + //~^ uninit_assumed_init + + // This is OK, because ZSTs do not contain data. let _: () = unsafe { MaybeUninit::uninit().assume_init() }; @@ -33,7 +34,8 @@ fn main() { // Was a false negative. let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; - //~^ ERROR: this call for this type may be undefined behavior + //~^ uninit_assumed_init + polymorphic::<()>(); polymorphic_maybe_uninit_array::<10>(); @@ -42,7 +44,8 @@ fn main() { fn polymorphic() { // We are conservative around polymorphic types. let _: T = unsafe { MaybeUninit::uninit().assume_init() }; - //~^ ERROR: this call for this type may be undefined behavior + //~^ uninit_assumed_init + } fn polymorphic_maybe_uninit_array() { diff --git a/tests/ui/uninit.stderr b/tests/ui/uninit.stderr index 81577fe3fd47..9179a2b28dbb 100644 --- a/tests/ui/uninit.stderr +++ b/tests/ui/uninit.stderr @@ -7,13 +7,13 @@ LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; = note: `#[deny(clippy::uninit_assumed_init)]` on by default error: this call for this type may be undefined behavior - --> tests/ui/uninit.rs:35:29 + --> tests/ui/uninit.rs:36:29 | LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call for this type may be undefined behavior - --> tests/ui/uninit.rs:44:29 + --> tests/ui/uninit.rs:46:29 | LL | let _: T = unsafe { MaybeUninit::uninit().assume_init() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/uninit_vec.rs b/tests/ui/uninit_vec.rs index 464f88140bdb..a48397137992 100644 --- a/tests/ui/uninit_vec.rs +++ b/tests/ui/uninit_vec.rs @@ -16,40 +16,46 @@ union MyOwnMaybeUninit { // https://github.com/rust-lang/rust/issues/119620 unsafe fn requires_paramenv() { let mut vec = Vec::>::with_capacity(1); + //~^ uninit_vec vec.set_len(1); } fn main() { // with_capacity() -> set_len() should be detected let mut vec: Vec = Vec::with_capacity(1000); - //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial + //~^ uninit_vec + unsafe { vec.set_len(200); } // reserve() -> set_len() should be detected vec.reserve(1000); - //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial + //~^ uninit_vec + unsafe { vec.set_len(200); } // new() -> set_len() should be detected let mut vec: Vec = Vec::new(); - //~^ ERROR: calling `set_len()` on empty `Vec` creates out-of-bound values + //~^ uninit_vec + unsafe { vec.set_len(200); } // default() -> set_len() should be detected let mut vec: Vec = Default::default(); - //~^ ERROR: calling `set_len()` on empty `Vec` creates out-of-bound values + //~^ uninit_vec + unsafe { vec.set_len(200); } let mut vec: Vec = Vec::default(); - //~^ ERROR: calling `set_len()` on empty `Vec` creates out-of-bound values + //~^ uninit_vec + unsafe { vec.set_len(200); } @@ -57,16 +63,19 @@ fn main() { // test when both calls are enclosed in the same unsafe block unsafe { let mut vec: Vec = Vec::with_capacity(1000); - //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates unini + //~^ uninit_vec + vec.set_len(200); vec.reserve(1000); - //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates unini + //~^ uninit_vec + vec.set_len(200); } let mut vec: Vec = Vec::with_capacity(1000); - //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial + //~^ uninit_vec + unsafe { // test the case where there are other statements in the following unsafe block vec.set_len(200); @@ -76,13 +85,15 @@ fn main() { // handle vec stored in the field of a struct let mut my_vec = MyVec::default(); my_vec.vec.reserve(1000); - //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial + //~^ uninit_vec + unsafe { my_vec.vec.set_len(200); } my_vec.vec = Vec::with_capacity(1000); - //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial + //~^ uninit_vec + unsafe { my_vec.vec.set_len(200); } @@ -137,7 +148,8 @@ fn main() { fn polymorphic() { // We are conservative around polymorphic types. let mut vec: Vec = Vec::with_capacity(1000); - //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates unini + //~^ uninit_vec + unsafe { vec.set_len(10); } @@ -165,6 +177,7 @@ fn main() { let mut vec: Vec> = Vec::with_capacity(1); //~^ uninit_vec + unsafe { vec.set_len(1); } @@ -178,6 +191,7 @@ fn main() { // Enums can have a discriminant that can't be uninit, so this should still warn let mut vec: Vec> = Vec::with_capacity(1); //~^ uninit_vec + unsafe { vec.set_len(1); } diff --git a/tests/ui/uninit_vec.stderr b/tests/ui/uninit_vec.stderr index e7c81cf792f2..7ff6140a2c3e 100644 --- a/tests/ui/uninit_vec.stderr +++ b/tests/ui/uninit_vec.stderr @@ -3,6 +3,7 @@ error: calling `set_len()` immediately after reserving a buffer creates uninitia | LL | let mut vec = Vec::>::with_capacity(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | vec.set_len(1); | ^^^^^^^^^^^^^^ | @@ -11,7 +12,7 @@ LL | vec.set_len(1); = help: to override `-D warnings` add `#[allow(clippy::uninit_vec)]` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:24:5 + --> tests/ui/uninit_vec.rs:25:5 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +23,7 @@ LL | vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:31:5 + --> tests/ui/uninit_vec.rs:33:5 | LL | vec.reserve(1000); | ^^^^^^^^^^^^^^^^^^ @@ -33,7 +34,7 @@ LL | vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` on empty `Vec` creates out-of-bound values - --> tests/ui/uninit_vec.rs:38:5 + --> tests/ui/uninit_vec.rs:41:5 | LL | let mut vec: Vec = Vec::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +43,7 @@ LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ error: calling `set_len()` on empty `Vec` creates out-of-bound values - --> tests/ui/uninit_vec.rs:45:5 + --> tests/ui/uninit_vec.rs:49:5 | LL | let mut vec: Vec = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +52,7 @@ LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ error: calling `set_len()` on empty `Vec` creates out-of-bound values - --> tests/ui/uninit_vec.rs:51:5 + --> tests/ui/uninit_vec.rs:56:5 | LL | let mut vec: Vec = Vec::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +61,7 @@ LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:68:5 + --> tests/ui/uninit_vec.rs:76:5 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,7 +72,7 @@ LL | vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:78:5 + --> tests/ui/uninit_vec.rs:87:5 | LL | my_vec.vec.reserve(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -82,7 +83,7 @@ LL | my_vec.vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:84:5 + --> tests/ui/uninit_vec.rs:94:5 | LL | my_vec.vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,29 +94,29 @@ LL | my_vec.vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:59:9 + --> tests/ui/uninit_vec.rs:65:9 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | +... LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ | = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:63:9 + --> tests/ui/uninit_vec.rs:70:9 | LL | vec.reserve(1000); | ^^^^^^^^^^^^^^^^^^ -LL | +... LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ | = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:139:9 + --> tests/ui/uninit_vec.rs:150:9 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -126,7 +127,7 @@ LL | vec.set_len(10); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:166:9 + --> tests/ui/uninit_vec.rs:178:9 | LL | let mut vec: Vec> = Vec::with_capacity(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,7 +138,7 @@ LL | vec.set_len(1); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> tests/ui/uninit_vec.rs:179:9 + --> tests/ui/uninit_vec.rs:192:9 | LL | let mut vec: Vec> = Vec::with_capacity(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/uninlined_format_args.fixed b/tests/ui/uninlined_format_args.fixed index 111a2e1987c8..444a5b1cfb5f 100644 --- a/tests/ui/uninlined_format_args.fixed +++ b/tests/ui/uninlined_format_args.fixed @@ -43,75 +43,137 @@ fn tester(fn_arg: i32) { let _: &[u8; 3] = b" "; // <- println!("val='{local_i32}'"); + //~^ uninlined_format_args println!("val='{local_i32}'"); // 3 spaces + //~^ uninlined_format_args println!("val='{local_i32}'"); // tab + //~^ uninlined_format_args println!("val='{local_i32}'"); // space+tab + //~^ uninlined_format_args println!("val='{local_i32}'"); // tab+space + //~^ uninlined_format_args println!( + //~^ uninlined_format_args "val='{local_i32}'" ); println!("{local_i32}"); + //~^ uninlined_format_args println!("{fn_arg}"); + //~^ uninlined_format_args println!("{local_i32:?}"); + //~^ uninlined_format_args println!("{local_i32:#?}"); + //~^ uninlined_format_args println!("{local_i32:4}"); + //~^ uninlined_format_args println!("{local_i32:04}"); + //~^ uninlined_format_args println!("{local_i32:<3}"); + //~^ uninlined_format_args println!("{local_i32:#010x}"); + //~^ uninlined_format_args println!("{local_f64:.1}"); + //~^ uninlined_format_args println!("Hello {} is {:.*}", "x", local_i32, local_f64); println!("Hello {} is {:.*}", local_i32, 5, local_f64); println!("Hello {} is {2:.*}", local_i32, 5, local_f64); println!("{local_i32} {local_f64}"); + //~^ uninlined_format_args println!("{}, {}", local_i32, local_opt.unwrap()); println!("{val}"); + //~^ uninlined_format_args println!("{val}"); + //~^ uninlined_format_args println!("{} {1}", local_i32, 42); println!("val='{local_i32}'"); + //~^ uninlined_format_args println!("val='{local_i32}'"); + //~^ uninlined_format_args println!("val='{local_i32}'"); + //~^ uninlined_format_args println!("val='{fn_arg}'"); + //~^ uninlined_format_args println!("{local_i32}"); + //~^ uninlined_format_args println!("{local_i32:?}"); + //~^ uninlined_format_args println!("{local_i32:#?}"); + //~^ uninlined_format_args println!("{local_i32:04}"); + //~^ uninlined_format_args println!("{local_i32:<3}"); + //~^ uninlined_format_args println!("{local_i32:#010x}"); + //~^ uninlined_format_args println!("{local_f64:.1}"); + //~^ uninlined_format_args println!("{local_i32} {local_i32}"); + //~^ uninlined_format_args println!("{local_f64} {local_i32} {local_i32} {local_f64}"); + //~^ uninlined_format_args println!("{local_i32} {local_f64}"); + //~^ uninlined_format_args println!("{local_f64} {local_i32}"); + //~^ uninlined_format_args println!("{local_f64} {local_i32} {local_f64} {local_i32}"); + //~^ uninlined_format_args println!("{1} {0}", "str", local_i32); println!("{local_i32}"); + //~^ uninlined_format_args println!("{local_i32:width$}"); + //~^ uninlined_format_args println!("{local_i32:width$}"); + //~^ uninlined_format_args println!("{local_i32:.prec$}"); + //~^ uninlined_format_args println!("{local_i32:.prec$}"); + //~^ uninlined_format_args println!("{val:val$}"); + //~^ uninlined_format_args println!("{val:val$}"); + //~^ uninlined_format_args println!("{val:val$.val$}"); + //~^ uninlined_format_args println!("{val:val$.val$}"); + //~^ uninlined_format_args println!("{val:val$.val$}"); + //~^ uninlined_format_args println!("{val:val$.val$}"); + //~^ uninlined_format_args println!("{val:val$.val$}"); + //~^ uninlined_format_args println!("{val:val$.val$}"); + //~^ uninlined_format_args println!("{val:val$.val$}"); + //~^ uninlined_format_args println!("{val:val$.val$}"); + //~^ uninlined_format_args println!("{width:width$}"); + //~^ uninlined_format_args println!("{local_i32:width$}"); + //~^ uninlined_format_args println!("{width:width$}"); + //~^ uninlined_format_args println!("{local_i32:width$}"); + //~^ uninlined_format_args println!("{prec:.prec$}"); + //~^ uninlined_format_args println!("{local_i32:.prec$}"); + //~^ uninlined_format_args println!("{prec:.prec$}"); + //~^ uninlined_format_args println!("{local_i32:.prec$}"); + //~^ uninlined_format_args println!("{width:width$.prec$}"); + //~^ uninlined_format_args println!("{width:width$.prec$}"); + //~^ uninlined_format_args println!("{local_f64:width$.prec$}"); + //~^ uninlined_format_args println!("{local_f64:width$.prec$} {local_f64} {width} {prec}"); + //~^ uninlined_format_args println!( + //~^ uninlined_format_args "{local_i32:width$.prec$} {local_i32:prec$.width$} {width:local_i32$.prec$} {width:prec$.local_i32$} {prec:local_i32$.width$} {prec:width$.local_i32$}", ); println!( @@ -122,8 +184,11 @@ fn tester(fn_arg: i32) { 1 + 2 ); println!("Width = {local_i32}, value with width = {local_f64:local_i32$}"); + //~^ uninlined_format_args println!("{local_i32:width$.prec$}"); + //~^ uninlined_format_args println!("{width:width$.prec$}"); + //~^ uninlined_format_args println!("{}", format!("{}", local_i32)); my_println!("{}", local_i32); my_println_args!("{}", local_i32); @@ -143,21 +208,26 @@ fn tester(fn_arg: i32) { println!(no_param_str!(), local_i32); println!( + //~^ uninlined_format_args "{val}", ); println!("{val}"); + //~^ uninlined_format_args println!(with_span!("{0} {1}" "{1} {0}"), local_i32, local_f64); println!("{}", with_span!(span val)); if local_i32 > 0 { panic!("p1 {local_i32}"); + //~^ uninlined_format_args } if local_i32 > 0 { panic!("p2 {local_i32}"); + //~^ uninlined_format_args } if local_i32 > 0 { panic!("p3 {local_i32}"); + //~^ uninlined_format_args } if local_i32 > 0 { panic!("p4 {local_i32}"); @@ -178,6 +248,7 @@ fn _under_msrv() { fn _meets_msrv() { let local_i32 = 1; println!("expand='{local_i32}'"); + //~^ uninlined_format_args } fn _do_not_fire() { @@ -280,7 +351,11 @@ fn user_format() { let local_f64 = 2.0; usr_println!(true, "val='{local_i32}'"); + //~^ uninlined_format_args usr_println!(true, "{local_i32}"); + //~^ uninlined_format_args usr_println!(true, "{local_i32:#010x}"); + //~^ uninlined_format_args usr_println!(true, "{local_f64:.1}"); + //~^ uninlined_format_args } diff --git a/tests/ui/uninlined_format_args.rs b/tests/ui/uninlined_format_args.rs index 81fe24765674..526fd98dfa4b 100644 --- a/tests/ui/uninlined_format_args.rs +++ b/tests/ui/uninlined_format_args.rs @@ -43,77 +43,139 @@ fn tester(fn_arg: i32) { let _: &[u8; 3] = b" "; // <- println!("val='{}'", local_i32); + //~^ uninlined_format_args println!("val='{ }'", local_i32); // 3 spaces + //~^ uninlined_format_args println!("val='{ }'", local_i32); // tab + //~^ uninlined_format_args println!("val='{ }'", local_i32); // space+tab + //~^ uninlined_format_args println!("val='{ }'", local_i32); // tab+space + //~^ uninlined_format_args println!( + //~^ uninlined_format_args "val='{ }'", local_i32 ); println!("{}", local_i32); + //~^ uninlined_format_args println!("{}", fn_arg); + //~^ uninlined_format_args println!("{:?}", local_i32); + //~^ uninlined_format_args println!("{:#?}", local_i32); + //~^ uninlined_format_args println!("{:4}", local_i32); + //~^ uninlined_format_args println!("{:04}", local_i32); + //~^ uninlined_format_args println!("{:<3}", local_i32); + //~^ uninlined_format_args println!("{:#010x}", local_i32); + //~^ uninlined_format_args println!("{:.1}", local_f64); + //~^ uninlined_format_args println!("Hello {} is {:.*}", "x", local_i32, local_f64); println!("Hello {} is {:.*}", local_i32, 5, local_f64); println!("Hello {} is {2:.*}", local_i32, 5, local_f64); println!("{} {}", local_i32, local_f64); + //~^ uninlined_format_args println!("{}, {}", local_i32, local_opt.unwrap()); println!("{}", val); + //~^ uninlined_format_args println!("{}", v = val); + //~^ uninlined_format_args println!("{} {1}", local_i32, 42); println!("val='{\t }'", local_i32); + //~^ uninlined_format_args println!("val='{\n }'", local_i32); + //~^ uninlined_format_args println!("val='{local_i32}'", local_i32 = local_i32); + //~^ uninlined_format_args println!("val='{local_i32}'", local_i32 = fn_arg); + //~^ uninlined_format_args println!("{0}", local_i32); + //~^ uninlined_format_args println!("{0:?}", local_i32); + //~^ uninlined_format_args println!("{0:#?}", local_i32); + //~^ uninlined_format_args println!("{0:04}", local_i32); + //~^ uninlined_format_args println!("{0:<3}", local_i32); + //~^ uninlined_format_args println!("{0:#010x}", local_i32); + //~^ uninlined_format_args println!("{0:.1}", local_f64); + //~^ uninlined_format_args println!("{0} {0}", local_i32); + //~^ uninlined_format_args println!("{1} {} {0} {}", local_i32, local_f64); + //~^ uninlined_format_args println!("{0} {1}", local_i32, local_f64); + //~^ uninlined_format_args println!("{1} {0}", local_i32, local_f64); + //~^ uninlined_format_args println!("{1} {0} {1} {0}", local_i32, local_f64); + //~^ uninlined_format_args println!("{1} {0}", "str", local_i32); println!("{v}", v = local_i32); + //~^ uninlined_format_args println!("{local_i32:0$}", width); + //~^ uninlined_format_args println!("{local_i32:w$}", w = width); + //~^ uninlined_format_args println!("{local_i32:.0$}", prec); + //~^ uninlined_format_args println!("{local_i32:.p$}", p = prec); + //~^ uninlined_format_args println!("{:0$}", v = val); + //~^ uninlined_format_args println!("{0:0$}", v = val); + //~^ uninlined_format_args println!("{:0$.0$}", v = val); + //~^ uninlined_format_args println!("{0:0$.0$}", v = val); + //~^ uninlined_format_args println!("{0:0$.v$}", v = val); + //~^ uninlined_format_args println!("{0:v$.0$}", v = val); + //~^ uninlined_format_args println!("{v:0$.0$}", v = val); + //~^ uninlined_format_args println!("{v:v$.0$}", v = val); + //~^ uninlined_format_args println!("{v:0$.v$}", v = val); + //~^ uninlined_format_args println!("{v:v$.v$}", v = val); + //~^ uninlined_format_args println!("{:0$}", width); + //~^ uninlined_format_args println!("{:1$}", local_i32, width); + //~^ uninlined_format_args println!("{:w$}", w = width); + //~^ uninlined_format_args println!("{:w$}", local_i32, w = width); + //~^ uninlined_format_args println!("{:.0$}", prec); + //~^ uninlined_format_args println!("{:.1$}", local_i32, prec); + //~^ uninlined_format_args println!("{:.p$}", p = prec); + //~^ uninlined_format_args println!("{:.p$}", local_i32, p = prec); + //~^ uninlined_format_args println!("{:0$.1$}", width, prec); + //~^ uninlined_format_args println!("{:0$.w$}", width, w = prec); + //~^ uninlined_format_args println!("{:1$.2$}", local_f64, width, prec); + //~^ uninlined_format_args println!("{:1$.2$} {0} {1} {2}", local_f64, width, prec); + //~^ uninlined_format_args println!( + //~^ uninlined_format_args "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}", local_i32, width, prec, ); @@ -125,8 +187,11 @@ fn tester(fn_arg: i32) { 1 + 2 ); println!("Width = {}, value with width = {:0$}", local_i32, local_f64); + //~^ uninlined_format_args println!("{:w$.p$}", local_i32, w = width, p = prec); + //~^ uninlined_format_args println!("{:w$.p$}", w = width, p = prec); + //~^ uninlined_format_args println!("{}", format!("{}", local_i32)); my_println!("{}", local_i32); my_println_args!("{}", local_i32); @@ -146,23 +211,28 @@ fn tester(fn_arg: i32) { println!(no_param_str!(), local_i32); println!( + //~^ uninlined_format_args "{}", // comment with a comma , in it val, ); println!("{}", /* comment with a comma , in it */ val); + //~^ uninlined_format_args println!(with_span!("{0} {1}" "{1} {0}"), local_i32, local_f64); println!("{}", with_span!(span val)); if local_i32 > 0 { panic!("p1 {}", local_i32); + //~^ uninlined_format_args } if local_i32 > 0 { panic!("p2 {0}", local_i32); + //~^ uninlined_format_args } if local_i32 > 0 { panic!("p3 {local_i32}", local_i32 = local_i32); + //~^ uninlined_format_args } if local_i32 > 0 { panic!("p4 {local_i32}"); @@ -183,6 +253,7 @@ fn _under_msrv() { fn _meets_msrv() { let local_i32 = 1; println!("expand='{}'", local_i32); + //~^ uninlined_format_args } fn _do_not_fire() { @@ -285,7 +356,11 @@ fn user_format() { let local_f64 = 2.0; usr_println!(true, "val='{}'", local_i32); + //~^ uninlined_format_args usr_println!(true, "{}", local_i32); + //~^ uninlined_format_args usr_println!(true, "{:#010x}", local_i32); + //~^ uninlined_format_args usr_println!(true, "{:.1}", local_f64); + //~^ uninlined_format_args } diff --git a/tests/ui/uninlined_format_args.stderr b/tests/ui/uninlined_format_args.stderr index 77961fea2c53..df688bc757c7 100644 --- a/tests/ui/uninlined_format_args.stderr +++ b/tests/ui/uninlined_format_args.stderr @@ -13,7 +13,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:46:5 + --> tests/ui/uninlined_format_args.rs:47:5 | LL | println!("val='{ }'", local_i32); // 3 spaces | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + println!("val='{local_i32}'"); // 3 spaces | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:47:5 + --> tests/ui/uninlined_format_args.rs:49:5 | LL | println!("val='{ }'", local_i32); // tab | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + println!("val='{local_i32}'"); // tab | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:48:5 + --> tests/ui/uninlined_format_args.rs:51:5 | LL | println!("val='{ }'", local_i32); // space+tab | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + println!("val='{local_i32}'"); // space+tab | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:49:5 + --> tests/ui/uninlined_format_args.rs:53:5 | LL | println!("val='{ }'", local_i32); // tab+space | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,9 +61,10 @@ LL + println!("val='{local_i32}'"); // tab+space | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:50:5 + --> tests/ui/uninlined_format_args.rs:55:5 | LL | / println!( +LL | | LL | | "val='{ LL | | }'", LL | | local_i32 @@ -71,7 +72,7 @@ LL | | ); | |_____^ error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:55:5 + --> tests/ui/uninlined_format_args.rs:61:5 | LL | println!("{}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,7 +84,7 @@ LL + println!("{local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:56:5 + --> tests/ui/uninlined_format_args.rs:63:5 | LL | println!("{}", fn_arg); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -95,7 +96,7 @@ LL + println!("{fn_arg}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:57:5 + --> tests/ui/uninlined_format_args.rs:65:5 | LL | println!("{:?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -107,7 +108,7 @@ LL + println!("{local_i32:?}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:58:5 + --> tests/ui/uninlined_format_args.rs:67:5 | LL | println!("{:#?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -119,7 +120,7 @@ LL + println!("{local_i32:#?}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:59:5 + --> tests/ui/uninlined_format_args.rs:69:5 | LL | println!("{:4}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -131,7 +132,7 @@ LL + println!("{local_i32:4}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:60:5 + --> tests/ui/uninlined_format_args.rs:71:5 | LL | println!("{:04}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -143,7 +144,7 @@ LL + println!("{local_i32:04}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:61:5 + --> tests/ui/uninlined_format_args.rs:73:5 | LL | println!("{:<3}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +156,7 @@ LL + println!("{local_i32:<3}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:62:5 + --> tests/ui/uninlined_format_args.rs:75:5 | LL | println!("{:#010x}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -167,7 +168,7 @@ LL + println!("{local_i32:#010x}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:63:5 + --> tests/ui/uninlined_format_args.rs:77:5 | LL | println!("{:.1}", local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -179,7 +180,7 @@ LL + println!("{local_f64:.1}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:67:5 + --> tests/ui/uninlined_format_args.rs:82:5 | LL | println!("{} {}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -191,7 +192,7 @@ LL + println!("{local_i32} {local_f64}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:69:5 + --> tests/ui/uninlined_format_args.rs:85:5 | LL | println!("{}", val); | ^^^^^^^^^^^^^^^^^^^ @@ -203,7 +204,7 @@ LL + println!("{val}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:70:5 + --> tests/ui/uninlined_format_args.rs:87:5 | LL | println!("{}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -215,7 +216,7 @@ LL + println!("{val}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:72:5 + --> tests/ui/uninlined_format_args.rs:90:5 | LL | println!("val='{\t }'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -227,7 +228,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:73:5 + --> tests/ui/uninlined_format_args.rs:92:5 | LL | println!("val='{\n }'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -239,7 +240,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:74:5 + --> tests/ui/uninlined_format_args.rs:94:5 | LL | println!("val='{local_i32}'", local_i32 = local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -251,7 +252,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:75:5 + --> tests/ui/uninlined_format_args.rs:96:5 | LL | println!("val='{local_i32}'", local_i32 = fn_arg); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +264,7 @@ LL + println!("val='{fn_arg}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:76:5 + --> tests/ui/uninlined_format_args.rs:98:5 | LL | println!("{0}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,7 +276,7 @@ LL + println!("{local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:77:5 + --> tests/ui/uninlined_format_args.rs:100:5 | LL | println!("{0:?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -287,7 +288,7 @@ LL + println!("{local_i32:?}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:78:5 + --> tests/ui/uninlined_format_args.rs:102:5 | LL | println!("{0:#?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -299,7 +300,7 @@ LL + println!("{local_i32:#?}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:79:5 + --> tests/ui/uninlined_format_args.rs:104:5 | LL | println!("{0:04}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -311,7 +312,7 @@ LL + println!("{local_i32:04}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:80:5 + --> tests/ui/uninlined_format_args.rs:106:5 | LL | println!("{0:<3}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -323,7 +324,7 @@ LL + println!("{local_i32:<3}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:81:5 + --> tests/ui/uninlined_format_args.rs:108:5 | LL | println!("{0:#010x}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -335,7 +336,7 @@ LL + println!("{local_i32:#010x}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:82:5 + --> tests/ui/uninlined_format_args.rs:110:5 | LL | println!("{0:.1}", local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -347,7 +348,7 @@ LL + println!("{local_f64:.1}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:83:5 + --> tests/ui/uninlined_format_args.rs:112:5 | LL | println!("{0} {0}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -359,7 +360,7 @@ LL + println!("{local_i32} {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:84:5 + --> tests/ui/uninlined_format_args.rs:114:5 | LL | println!("{1} {} {0} {}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -371,7 +372,7 @@ LL + println!("{local_f64} {local_i32} {local_i32} {local_f64}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:85:5 + --> tests/ui/uninlined_format_args.rs:116:5 | LL | println!("{0} {1}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -383,7 +384,7 @@ LL + println!("{local_i32} {local_f64}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:86:5 + --> tests/ui/uninlined_format_args.rs:118:5 | LL | println!("{1} {0}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -395,7 +396,7 @@ LL + println!("{local_f64} {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:87:5 + --> tests/ui/uninlined_format_args.rs:120:5 | LL | println!("{1} {0} {1} {0}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -407,7 +408,7 @@ LL + println!("{local_f64} {local_i32} {local_f64} {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:89:5 + --> tests/ui/uninlined_format_args.rs:123:5 | LL | println!("{v}", v = local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -419,7 +420,7 @@ LL + println!("{local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:90:5 + --> tests/ui/uninlined_format_args.rs:125:5 | LL | println!("{local_i32:0$}", width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -431,7 +432,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:91:5 + --> tests/ui/uninlined_format_args.rs:127:5 | LL | println!("{local_i32:w$}", w = width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -443,7 +444,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:92:5 + --> tests/ui/uninlined_format_args.rs:129:5 | LL | println!("{local_i32:.0$}", prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -455,7 +456,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:93:5 + --> tests/ui/uninlined_format_args.rs:131:5 | LL | println!("{local_i32:.p$}", p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -467,7 +468,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:94:5 + --> tests/ui/uninlined_format_args.rs:133:5 | LL | println!("{:0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -479,7 +480,7 @@ LL + println!("{val:val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:95:5 + --> tests/ui/uninlined_format_args.rs:135:5 | LL | println!("{0:0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -491,7 +492,7 @@ LL + println!("{val:val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:96:5 + --> tests/ui/uninlined_format_args.rs:137:5 | LL | println!("{:0$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -503,7 +504,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:97:5 + --> tests/ui/uninlined_format_args.rs:139:5 | LL | println!("{0:0$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -515,7 +516,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:98:5 + --> tests/ui/uninlined_format_args.rs:141:5 | LL | println!("{0:0$.v$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -527,7 +528,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:99:5 + --> tests/ui/uninlined_format_args.rs:143:5 | LL | println!("{0:v$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -539,7 +540,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:100:5 + --> tests/ui/uninlined_format_args.rs:145:5 | LL | println!("{v:0$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -551,7 +552,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:101:5 + --> tests/ui/uninlined_format_args.rs:147:5 | LL | println!("{v:v$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -563,7 +564,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:102:5 + --> tests/ui/uninlined_format_args.rs:149:5 | LL | println!("{v:0$.v$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -575,7 +576,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:103:5 + --> tests/ui/uninlined_format_args.rs:151:5 | LL | println!("{v:v$.v$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -587,7 +588,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:104:5 + --> tests/ui/uninlined_format_args.rs:153:5 | LL | println!("{:0$}", width); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -599,7 +600,7 @@ LL + println!("{width:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:105:5 + --> tests/ui/uninlined_format_args.rs:155:5 | LL | println!("{:1$}", local_i32, width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -611,7 +612,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:106:5 + --> tests/ui/uninlined_format_args.rs:157:5 | LL | println!("{:w$}", w = width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -623,7 +624,7 @@ LL + println!("{width:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:107:5 + --> tests/ui/uninlined_format_args.rs:159:5 | LL | println!("{:w$}", local_i32, w = width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -635,7 +636,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:108:5 + --> tests/ui/uninlined_format_args.rs:161:5 | LL | println!("{:.0$}", prec); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -647,7 +648,7 @@ LL + println!("{prec:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:109:5 + --> tests/ui/uninlined_format_args.rs:163:5 | LL | println!("{:.1$}", local_i32, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -659,7 +660,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:110:5 + --> tests/ui/uninlined_format_args.rs:165:5 | LL | println!("{:.p$}", p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -671,7 +672,7 @@ LL + println!("{prec:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:111:5 + --> tests/ui/uninlined_format_args.rs:167:5 | LL | println!("{:.p$}", local_i32, p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -683,7 +684,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:112:5 + --> tests/ui/uninlined_format_args.rs:169:5 | LL | println!("{:0$.1$}", width, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -695,7 +696,7 @@ LL + println!("{width:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:113:5 + --> tests/ui/uninlined_format_args.rs:171:5 | LL | println!("{:0$.w$}", width, w = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -707,7 +708,7 @@ LL + println!("{width:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:114:5 + --> tests/ui/uninlined_format_args.rs:173:5 | LL | println!("{:1$.2$}", local_f64, width, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -719,7 +720,7 @@ LL + println!("{local_f64:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:115:5 + --> tests/ui/uninlined_format_args.rs:175:5 | LL | println!("{:1$.2$} {0} {1} {2}", local_f64, width, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -731,16 +732,17 @@ LL + println!("{local_f64:width$.prec$} {local_f64} {width} {prec}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:116:5 + --> tests/ui/uninlined_format_args.rs:177:5 | LL | / println!( +LL | | LL | | "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}", LL | | local_i32, width, prec, LL | | ); | |_____^ error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:127:5 + --> tests/ui/uninlined_format_args.rs:189:5 | LL | println!("Width = {}, value with width = {:0$}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -752,7 +754,7 @@ LL + println!("Width = {local_i32}, value with width = {local_f64:local_i32$ | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:128:5 + --> tests/ui/uninlined_format_args.rs:191:5 | LL | println!("{:w$.p$}", local_i32, w = width, p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -764,7 +766,7 @@ LL + println!("{local_i32:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:129:5 + --> tests/ui/uninlined_format_args.rs:193:5 | LL | println!("{:w$.p$}", w = width, p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -776,17 +778,17 @@ LL + println!("{width:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:148:5 + --> tests/ui/uninlined_format_args.rs:213:5 | LL | / println!( +LL | | LL | | "{}", -LL | | // comment with a comma , in it -LL | | val, +... | LL | | ); | |_____^ error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:153:5 + --> tests/ui/uninlined_format_args.rs:219:5 | LL | println!("{}", /* comment with a comma , in it */ val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -798,7 +800,7 @@ LL + println!("{val}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:159:9 + --> tests/ui/uninlined_format_args.rs:226:9 | LL | panic!("p1 {}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -810,7 +812,7 @@ LL + panic!("p1 {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:162:9 + --> tests/ui/uninlined_format_args.rs:230:9 | LL | panic!("p2 {0}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -822,7 +824,7 @@ LL + panic!("p2 {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:165:9 + --> tests/ui/uninlined_format_args.rs:234:9 | LL | panic!("p3 {local_i32}", local_i32 = local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -834,7 +836,7 @@ LL + panic!("p3 {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:185:5 + --> tests/ui/uninlined_format_args.rs:255:5 | LL | println!("expand='{}'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -846,7 +848,7 @@ LL + println!("expand='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:287:5 + --> tests/ui/uninlined_format_args.rs:358:5 | LL | usr_println!(true, "val='{}'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -858,7 +860,7 @@ LL + usr_println!(true, "val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:288:5 + --> tests/ui/uninlined_format_args.rs:360:5 | LL | usr_println!(true, "{}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -870,7 +872,7 @@ LL + usr_println!(true, "{local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:289:5 + --> tests/ui/uninlined_format_args.rs:362:5 | LL | usr_println!(true, "{:#010x}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -882,7 +884,7 @@ LL + usr_println!(true, "{local_i32:#010x}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:290:5 + --> tests/ui/uninlined_format_args.rs:364:5 | LL | usr_println!(true, "{:.1}", local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/uninlined_format_args_panic.edition2018.fixed b/tests/ui/uninlined_format_args_panic.edition2018.fixed index 9911d1317070..3710036c0589 100644 --- a/tests/ui/uninlined_format_args_panic.edition2018.fixed +++ b/tests/ui/uninlined_format_args_panic.edition2018.fixed @@ -9,15 +9,19 @@ fn main() { let var = 1; println!("val='{var}'"); + //~^ uninlined_format_args if var > 0 { panic!("p1 {}", var); + //~[edition2021]^ uninlined_format_args } if var > 0 { panic!("p2 {0}", var); + //~[edition2021]^ uninlined_format_args } if var > 0 { panic!("p3 {var}", var = var); + //~[edition2021]^ uninlined_format_args } #[allow(non_fmt_panics)] @@ -28,5 +32,7 @@ fn main() { } assert!(var == 1, "p5 {}", var); + //~[edition2021]^ uninlined_format_args debug_assert!(var == 1, "p6 {}", var); + //~[edition2021]^ uninlined_format_args } diff --git a/tests/ui/uninlined_format_args_panic.edition2021.fixed b/tests/ui/uninlined_format_args_panic.edition2021.fixed index 87b74670565f..8a754d313806 100644 --- a/tests/ui/uninlined_format_args_panic.edition2021.fixed +++ b/tests/ui/uninlined_format_args_panic.edition2021.fixed @@ -9,15 +9,19 @@ fn main() { let var = 1; println!("val='{var}'"); + //~^ uninlined_format_args if var > 0 { panic!("p1 {var}"); + //~[edition2021]^ uninlined_format_args } if var > 0 { panic!("p2 {var}"); + //~[edition2021]^ uninlined_format_args } if var > 0 { panic!("p3 {var}"); + //~[edition2021]^ uninlined_format_args } #[allow(non_fmt_panics)] @@ -28,5 +32,7 @@ fn main() { } assert!(var == 1, "p5 {var}"); + //~[edition2021]^ uninlined_format_args debug_assert!(var == 1, "p6 {var}"); + //~[edition2021]^ uninlined_format_args } diff --git a/tests/ui/uninlined_format_args_panic.edition2021.stderr b/tests/ui/uninlined_format_args_panic.edition2021.stderr index 7638d3f8bbad..4db6e6a99312 100644 --- a/tests/ui/uninlined_format_args_panic.edition2021.stderr +++ b/tests/ui/uninlined_format_args_panic.edition2021.stderr @@ -13,7 +13,7 @@ LL + println!("val='{var}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args_panic.rs:14:9 + --> tests/ui/uninlined_format_args_panic.rs:15:9 | LL | panic!("p1 {}", var); | ^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + panic!("p1 {var}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args_panic.rs:17:9 + --> tests/ui/uninlined_format_args_panic.rs:19:9 | LL | panic!("p2 {0}", var); | ^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + panic!("p2 {var}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args_panic.rs:20:9 + --> tests/ui/uninlined_format_args_panic.rs:23:9 | LL | panic!("p3 {var}", var = var); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + panic!("p3 {var}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args_panic.rs:30:5 + --> tests/ui/uninlined_format_args_panic.rs:34:5 | LL | assert!(var == 1, "p5 {}", var); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + assert!(var == 1, "p5 {var}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args_panic.rs:31:5 + --> tests/ui/uninlined_format_args_panic.rs:36:5 | LL | debug_assert!(var == 1, "p6 {}", var); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/uninlined_format_args_panic.rs b/tests/ui/uninlined_format_args_panic.rs index 647c69bc5c41..94de4f057e99 100644 --- a/tests/ui/uninlined_format_args_panic.rs +++ b/tests/ui/uninlined_format_args_panic.rs @@ -9,15 +9,19 @@ fn main() { let var = 1; println!("val='{}'", var); + //~^ uninlined_format_args if var > 0 { panic!("p1 {}", var); + //~[edition2021]^ uninlined_format_args } if var > 0 { panic!("p2 {0}", var); + //~[edition2021]^ uninlined_format_args } if var > 0 { panic!("p3 {var}", var = var); + //~[edition2021]^ uninlined_format_args } #[allow(non_fmt_panics)] @@ -28,5 +32,7 @@ fn main() { } assert!(var == 1, "p5 {}", var); + //~[edition2021]^ uninlined_format_args debug_assert!(var == 1, "p6 {}", var); + //~[edition2021]^ uninlined_format_args } diff --git a/tests/ui/unit_arg.rs b/tests/ui/unit_arg.rs index 2e1390621a6c..3a3962d09143 100644 --- a/tests/ui/unit_arg.rs +++ b/tests/ui/unit_arg.rs @@ -61,23 +61,30 @@ impl Tr for B { fn bad() { foo({ + //~^ unit_arg 1; }); foo(foo(1)); + //~^ unit_arg foo({ + //~^ unit_arg foo(1); foo(2); }); let b = Bar; b.bar({ + //~^ unit_arg 1; }); taking_multiple_units(foo(0), foo(1)); + //~^ unit_arg taking_multiple_units(foo(0), { + //~^ unit_arg foo(1); foo(2); }); taking_multiple_units( + //~^ unit_arg { foo(0); foo(1); @@ -89,9 +96,11 @@ fn bad() { ); // here Some(foo(2)) isn't the top level statement expression, wrap the suggestion in a block None.or(Some(foo(2))); + //~^ unit_arg // in this case, the suggestion can be inlined, no need for a surrounding block // foo(()); foo(()) instead of { foo(()); foo(()) } foo(foo(())); + //~^ unit_arg } fn ok() { @@ -129,6 +138,7 @@ mod issue_2945 { #[allow(dead_code)] fn returning_expr() -> Option<()> { Some(foo(1)) + //~^ unit_arg } fn taking_multiple_units(a: (), b: ()) {} diff --git a/tests/ui/unit_arg.stderr b/tests/ui/unit_arg.stderr index 41ad1a2d3834..2ddb28bd4cc4 100644 --- a/tests/ui/unit_arg.stderr +++ b/tests/ui/unit_arg.stderr @@ -2,6 +2,7 @@ error: passing a unit value to a function --> tests/ui/unit_arg.rs:63:5 | LL | / foo({ +LL | | LL | | 1; LL | | }); | |______^ @@ -15,13 +16,14 @@ LL | 1 help: or move the expression in front of the call and replace it with the unit literal `()` | LL ~ { +LL + LL + 1; LL + }; LL ~ foo(()); | error: passing a unit value to a function - --> tests/ui/unit_arg.rs:66:5 + --> tests/ui/unit_arg.rs:67:5 | LL | foo(foo(1)); | ^^^^^^^^^^^ @@ -33,9 +35,10 @@ LL ~ foo(()); | error: passing a unit value to a function - --> tests/ui/unit_arg.rs:67:5 + --> tests/ui/unit_arg.rs:69:5 | LL | / foo({ +LL | | LL | | foo(1); LL | | foo(2); LL | | }); @@ -48,6 +51,7 @@ LL | foo(2) help: or move the expression in front of the call and replace it with the unit literal `()` | LL ~ { +LL + LL + foo(1); LL + foo(2); LL + }; @@ -55,9 +59,10 @@ LL ~ foo(()); | error: passing a unit value to a function - --> tests/ui/unit_arg.rs:72:5 + --> tests/ui/unit_arg.rs:75:5 | LL | / b.bar({ +LL | | LL | | 1; LL | | }); | |______^ @@ -69,13 +74,14 @@ LL | 1 help: or move the expression in front of the call and replace it with the unit literal `()` | LL ~ { +LL + LL + 1; LL + }; LL ~ b.bar(()); | error: passing unit values to a function - --> tests/ui/unit_arg.rs:75:5 + --> tests/ui/unit_arg.rs:79:5 | LL | taking_multiple_units(foo(0), foo(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -88,9 +94,10 @@ LL ~ taking_multiple_units((), ()); | error: passing unit values to a function - --> tests/ui/unit_arg.rs:76:5 + --> tests/ui/unit_arg.rs:81:5 | LL | / taking_multiple_units(foo(0), { +LL | | LL | | foo(1); LL | | foo(2); LL | | }); @@ -104,6 +111,7 @@ help: or move the expressions in front of the call and replace them with the uni | LL ~ foo(0); LL + { +LL + LL + foo(1); LL + foo(2); LL + }; @@ -111,12 +119,12 @@ LL ~ taking_multiple_units((), ()); | error: passing unit values to a function - --> tests/ui/unit_arg.rs:80:5 + --> tests/ui/unit_arg.rs:86:5 | LL | / taking_multiple_units( +LL | | LL | | { LL | | foo(0); -LL | | foo(1); ... | LL | | }, LL | | ); @@ -141,13 +149,14 @@ LL + foo(2); LL + foo(3); LL + }; LL + taking_multiple_units( +LL + LL + (), LL + (), LL ~ ); | error: passing a unit value to a function - --> tests/ui/unit_arg.rs:91:13 + --> tests/ui/unit_arg.rs:98:13 | LL | None.or(Some(foo(2))); | ^^^^^^^^^^^^ @@ -161,7 +170,7 @@ LL ~ }); | error: passing a unit value to a function - --> tests/ui/unit_arg.rs:94:5 + --> tests/ui/unit_arg.rs:102:5 | LL | foo(foo(())); | ^^^^^^^^^^^^ @@ -173,7 +182,7 @@ LL ~ foo(()); | error: passing a unit value to a function - --> tests/ui/unit_arg.rs:131:5 + --> tests/ui/unit_arg.rs:140:5 | LL | Some(foo(1)) | ^^^^^^^^^^^^ diff --git a/tests/ui/unit_arg_empty_blocks.fixed b/tests/ui/unit_arg_empty_blocks.fixed index a947ded7b1e7..b045a33608d7 100644 --- a/tests/ui/unit_arg_empty_blocks.fixed +++ b/tests/ui/unit_arg_empty_blocks.fixed @@ -14,12 +14,16 @@ fn foo3(t1: T1, t2: T2, t3: T3) { fn bad() { foo(()); + //~^ unit_arg foo3((), 2, 2); + //~^ unit_arg foo(0); taking_two_units((), ()); + //~^ unit_arg foo(0); foo(1); taking_three_units((), (), ()); + //~^ unit_arg } fn taking_two_units(a: (), b: ()) {} diff --git a/tests/ui/unit_arg_empty_blocks.rs b/tests/ui/unit_arg_empty_blocks.rs index 058c4f84a9e8..ab305913f3f6 100644 --- a/tests/ui/unit_arg_empty_blocks.rs +++ b/tests/ui/unit_arg_empty_blocks.rs @@ -14,9 +14,13 @@ fn foo3(t1: T1, t2: T2, t3: T3) { fn bad() { foo({}); + //~^ unit_arg foo3({}, 2, 2); + //~^ unit_arg taking_two_units({}, foo(0)); + //~^ unit_arg taking_three_units({}, foo(0), foo(1)); + //~^ unit_arg } fn taking_two_units(a: (), b: ()) {} diff --git a/tests/ui/unit_arg_empty_blocks.stderr b/tests/ui/unit_arg_empty_blocks.stderr index d971195dda26..2c686d58ecc1 100644 --- a/tests/ui/unit_arg_empty_blocks.stderr +++ b/tests/ui/unit_arg_empty_blocks.stderr @@ -10,7 +10,7 @@ LL | foo({}); = help: to override `-D warnings` add `#[allow(clippy::unit_arg)]` error: passing a unit value to a function - --> tests/ui/unit_arg_empty_blocks.rs:17:5 + --> tests/ui/unit_arg_empty_blocks.rs:18:5 | LL | foo3({}, 2, 2); | ^^^^^--^^^^^^^ @@ -18,7 +18,7 @@ LL | foo3({}, 2, 2); | help: use a unit literal instead: `()` error: passing unit values to a function - --> tests/ui/unit_arg_empty_blocks.rs:18:5 + --> tests/ui/unit_arg_empty_blocks.rs:20:5 | LL | taking_two_units({}, foo(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL ~ taking_two_units((), ()); | error: passing unit values to a function - --> tests/ui/unit_arg_empty_blocks.rs:19:5 + --> tests/ui/unit_arg_empty_blocks.rs:22:5 | LL | taking_three_units({}, foo(0), foo(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unit_cmp.rs b/tests/ui/unit_cmp.rs index cea89026da6f..0b1cccfbadf6 100644 --- a/tests/ui/unit_cmp.rs +++ b/tests/ui/unit_cmp.rs @@ -15,22 +15,25 @@ fn main() { // this warns if { - //~^ ERROR: ==-comparison of unit values detected. This will always be true - //~| NOTE: `-D clippy::unit-cmp` implied by `-D warnings` + //~^ unit_cmp + + true; } == { false; } {} if { - //~^ ERROR: >-comparison of unit values detected. This will always be false + //~^ unit_cmp + true; } > { false; } {} assert_eq!( - //~^ ERROR: `assert_eq` of unit values detected. This will always succeed + //~^ unit_cmp + { true; }, @@ -39,7 +42,8 @@ fn main() { } ); debug_assert_eq!( - //~^ ERROR: `debug_assert_eq` of unit values detected. This will always succeed + //~^ unit_cmp + { true; }, @@ -49,7 +53,8 @@ fn main() { ); assert_ne!( - //~^ ERROR: `assert_ne` of unit values detected. This will always fail + //~^ unit_cmp + { true; }, @@ -58,7 +63,8 @@ fn main() { } ); debug_assert_ne!( - //~^ ERROR: `debug_assert_ne` of unit values detected. This will always fail + //~^ unit_cmp + { true; }, diff --git a/tests/ui/unit_cmp.stderr b/tests/ui/unit_cmp.stderr index 9e067edb8467..0c485edd9736 100644 --- a/tests/ui/unit_cmp.stderr +++ b/tests/ui/unit_cmp.stderr @@ -3,10 +3,7 @@ error: ==-comparison of unit values detected. This will always be true | LL | if { | ________^ -LL | | -LL | | -LL | | true; -LL | | } == { +... | LL | | false; LL | | } {} | |_____^ @@ -15,11 +12,12 @@ LL | | } {} = help: to override `-D warnings` add `#[allow(clippy::unit_cmp)]` error: >-comparison of unit values detected. This will always be false - --> tests/ui/unit_cmp.rs:25:8 + --> tests/ui/unit_cmp.rs:26:8 | LL | if { | ________^ LL | | +LL | | LL | | true; LL | | } > { LL | | false; @@ -27,45 +25,33 @@ LL | | } {} | |_____^ error: `assert_eq` of unit values detected. This will always succeed - --> tests/ui/unit_cmp.rs:32:5 + --> tests/ui/unit_cmp.rs:34:5 | LL | / assert_eq!( -LL | | -LL | | { -LL | | true; ... | LL | | ); | |_____^ error: `debug_assert_eq` of unit values detected. This will always succeed - --> tests/ui/unit_cmp.rs:41:5 + --> tests/ui/unit_cmp.rs:44:5 | LL | / debug_assert_eq!( -LL | | -LL | | { -LL | | true; ... | LL | | ); | |_____^ error: `assert_ne` of unit values detected. This will always fail - --> tests/ui/unit_cmp.rs:51:5 + --> tests/ui/unit_cmp.rs:55:5 | LL | / assert_ne!( -LL | | -LL | | { -LL | | true; ... | LL | | ); | |_____^ error: `debug_assert_ne` of unit values detected. This will always fail - --> tests/ui/unit_cmp.rs:60:5 + --> tests/ui/unit_cmp.rs:65:5 | LL | / debug_assert_ne!( -LL | | -LL | | { -LL | | true; ... | LL | | ); | |_____^ diff --git a/tests/ui/unit_hash.fixed b/tests/ui/unit_hash.fixed index ed0facf1b963..4df67c783d32 100644 --- a/tests/ui/unit_hash.fixed +++ b/tests/ui/unit_hash.fixed @@ -17,18 +17,21 @@ fn main() { match my_enum { Foo::Empty => 0_u8.hash(&mut state), - //~^ ERROR: this call to `hash` on the unit type will do nothing - //~| NOTE: the implementation of `Hash` for `()` is a no-op + //~^ unit_hash + + Foo::WithValue(x) => x.hash(&mut state), } let res = (); 0_u8.hash(&mut state); - //~^ ERROR: this call to `hash` on the unit type will do nothing - //~| NOTE: the implementation of `Hash` for `()` is a no-op + //~^ unit_hash + + #[allow(clippy::unit_arg)] 0_u8.hash(&mut state); - //~^ ERROR: this call to `hash` on the unit type will do nothing - //~| NOTE: the implementation of `Hash` for `()` is a no-op + //~^ unit_hash + + } diff --git a/tests/ui/unit_hash.rs b/tests/ui/unit_hash.rs index f3636d1644da..15f27aab95e1 100644 --- a/tests/ui/unit_hash.rs +++ b/tests/ui/unit_hash.rs @@ -17,18 +17,21 @@ fn main() { match my_enum { Foo::Empty => ().hash(&mut state), - //~^ ERROR: this call to `hash` on the unit type will do nothing - //~| NOTE: the implementation of `Hash` for `()` is a no-op + //~^ unit_hash + + Foo::WithValue(x) => x.hash(&mut state), } let res = (); res.hash(&mut state); - //~^ ERROR: this call to `hash` on the unit type will do nothing - //~| NOTE: the implementation of `Hash` for `()` is a no-op + //~^ unit_hash + + #[allow(clippy::unit_arg)] do_nothing().hash(&mut state); - //~^ ERROR: this call to `hash` on the unit type will do nothing - //~| NOTE: the implementation of `Hash` for `()` is a no-op + //~^ unit_hash + + } diff --git a/tests/ui/unit_hash.stderr b/tests/ui/unit_hash.stderr index b48f3a543b76..be019d398b58 100644 --- a/tests/ui/unit_hash.stderr +++ b/tests/ui/unit_hash.stderr @@ -9,7 +9,7 @@ LL | Foo::Empty => ().hash(&mut state), = help: to override `-D warnings` add `#[allow(clippy::unit_hash)]` error: this call to `hash` on the unit type will do nothing - --> tests/ui/unit_hash.rs:26:5 + --> tests/ui/unit_hash.rs:27:5 | LL | res.hash(&mut state); | ^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)` @@ -17,7 +17,7 @@ LL | res.hash(&mut state); = note: the implementation of `Hash` for `()` is a no-op error: this call to `hash` on the unit type will do nothing - --> tests/ui/unit_hash.rs:31:5 + --> tests/ui/unit_hash.rs:33:5 | LL | do_nothing().hash(&mut state); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)` diff --git a/tests/ui/unit_return_expecting_ord.rs b/tests/ui/unit_return_expecting_ord.rs index 5f62157dd6d5..3585eb5395db 100644 --- a/tests/ui/unit_return_expecting_ord.rs +++ b/tests/ui/unit_return_expecting_ord.rs @@ -16,16 +16,19 @@ fn unit(_i: isize) {} fn main() { let mut structs = vec![Struct { field: 2 }, Struct { field: 1 }]; structs.sort_by_key(|s| { - //~^ ERROR: this closure returns the unit type which also implements Ord + //~^ unit_return_expecting_ord + double(s.field); }); structs.sort_by_key(|s| double(s.field)); structs.is_sorted_by_key(|s| { - //~^ ERROR: this closure returns the unit type which also implements PartialOrd + //~^ unit_return_expecting_ord + double(s.field); }); structs.is_sorted_by_key(|s| { - //~^ ERROR: this closure returns the unit type which also implements PartialOrd + //~^ unit_return_expecting_ord + if s.field > 0 { () } else { @@ -36,5 +39,6 @@ fn main() { return double(s.field); }); structs.sort_by_key(|s| unit(s.field)); - //~^ ERROR: this closure returns the unit type which also implements Ord + //~^ unit_return_expecting_ord + } diff --git a/tests/ui/unit_return_expecting_ord.stderr b/tests/ui/unit_return_expecting_ord.stderr index 329832048e88..d5ce2fb0b51d 100644 --- a/tests/ui/unit_return_expecting_ord.stderr +++ b/tests/ui/unit_return_expecting_ord.stderr @@ -5,7 +5,7 @@ LL | structs.sort_by_key(|s| { | ^^^ | help: probably caused by this trailing semicolon - --> tests/ui/unit_return_expecting_ord.rs:20:24 + --> tests/ui/unit_return_expecting_ord.rs:21:24 | LL | double(s.field); | ^ @@ -13,25 +13,25 @@ LL | double(s.field); = help: to override `-D warnings` add `#[allow(clippy::unit_return_expecting_ord)]` error: this closure returns the unit type which also implements PartialOrd - --> tests/ui/unit_return_expecting_ord.rs:23:30 + --> tests/ui/unit_return_expecting_ord.rs:24:30 | LL | structs.is_sorted_by_key(|s| { | ^^^ | help: probably caused by this trailing semicolon - --> tests/ui/unit_return_expecting_ord.rs:25:24 + --> tests/ui/unit_return_expecting_ord.rs:27:24 | LL | double(s.field); | ^ error: this closure returns the unit type which also implements PartialOrd - --> tests/ui/unit_return_expecting_ord.rs:27:30 + --> tests/ui/unit_return_expecting_ord.rs:29:30 | LL | structs.is_sorted_by_key(|s| { | ^^^ error: this closure returns the unit type which also implements Ord - --> tests/ui/unit_return_expecting_ord.rs:38:25 + --> tests/ui/unit_return_expecting_ord.rs:41:25 | LL | structs.sort_by_key(|s| unit(s.field)); | ^^^ diff --git a/tests/ui/unknown_clippy_lints.fixed b/tests/ui/unknown_clippy_lints.fixed index c0ccd41c19ab..f97452c34eb5 100644 --- a/tests/ui/unknown_clippy_lints.fixed +++ b/tests/ui/unknown_clippy_lints.fixed @@ -1,18 +1,27 @@ #![warn(clippy::pedantic)] // Should suggest lowercase #![allow(clippy::all)] +//~^ ERROR: unknown lint #![warn(clippy::cmp_owned)] +//~^ ERROR: unknown lint // Should suggest similar clippy lint name #[warn(clippy::if_not_else)] +//~^ ERROR: unknown lint #[warn(clippy::unnecessary_cast)] +//~^ ERROR: unknown lint #[warn(clippy::useless_transmute)] +//~^ ERROR: unknown lint // Should suggest rustc lint name(`dead_code`) #[warn(dead_code)] +//~^ ERROR: unknown lint // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`) #[warn(clippy::unused_self)] +//~^ ERROR: unknown lint // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`) #[warn(clippy::redundant_static_lifetimes)] +//~^ ERROR: unknown lint // issue #118183, should report `missing_docs` from rustc lint #[warn(missing_docs)] +//~^ ERROR: unknown lint fn main() {} diff --git a/tests/ui/unknown_clippy_lints.rs b/tests/ui/unknown_clippy_lints.rs index 7a59ad364aa7..2ff4dd80bddc 100644 --- a/tests/ui/unknown_clippy_lints.rs +++ b/tests/ui/unknown_clippy_lints.rs @@ -1,18 +1,27 @@ #![warn(clippy::pedantic)] // Should suggest lowercase #![allow(clippy::All)] +//~^ ERROR: unknown lint #![warn(clippy::CMP_OWNED)] +//~^ ERROR: unknown lint // Should suggest similar clippy lint name #[warn(clippy::if_not_els)] +//~^ ERROR: unknown lint #[warn(clippy::UNNecsaRy_cAst)] +//~^ ERROR: unknown lint #[warn(clippy::useles_transute)] +//~^ ERROR: unknown lint // Should suggest rustc lint name(`dead_code`) #[warn(clippy::dead_cod)] +//~^ ERROR: unknown lint // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`) #[warn(clippy::unused_colle)] +//~^ ERROR: unknown lint // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`) #[warn(clippy::const_static_lifetim)] +//~^ ERROR: unknown lint // issue #118183, should report `missing_docs` from rustc lint #[warn(clippy::missing_docs)] +//~^ ERROR: unknown lint fn main() {} diff --git a/tests/ui/unknown_clippy_lints.stderr b/tests/ui/unknown_clippy_lints.stderr index aa2c2f3c0e20..96a35312755c 100644 --- a/tests/ui/unknown_clippy_lints.stderr +++ b/tests/ui/unknown_clippy_lints.stderr @@ -8,31 +8,31 @@ LL | #![allow(clippy::All)] = help: to override `-D warnings` add `#[allow(unknown_lints)]` error: unknown lint: `clippy::CMP_OWNED` - --> tests/ui/unknown_clippy_lints.rs:4:9 + --> tests/ui/unknown_clippy_lints.rs:5:9 | LL | #![warn(clippy::CMP_OWNED)] | ^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::cmp_owned` error: unknown lint: `clippy::if_not_els` - --> tests/ui/unknown_clippy_lints.rs:7:8 + --> tests/ui/unknown_clippy_lints.rs:9:8 | LL | #[warn(clippy::if_not_els)] | ^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::if_not_else` error: unknown lint: `clippy::UNNecsaRy_cAst` - --> tests/ui/unknown_clippy_lints.rs:8:8 + --> tests/ui/unknown_clippy_lints.rs:11:8 | LL | #[warn(clippy::UNNecsaRy_cAst)] | ^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::unnecessary_cast` error: unknown lint: `clippy::useles_transute` - --> tests/ui/unknown_clippy_lints.rs:9:8 + --> tests/ui/unknown_clippy_lints.rs:13:8 | LL | #[warn(clippy::useles_transute)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::useless_transmute` error: unknown lint: `clippy::dead_cod` - --> tests/ui/unknown_clippy_lints.rs:11:8 + --> tests/ui/unknown_clippy_lints.rs:16:8 | LL | #[warn(clippy::dead_cod)] | ^^^^^^^^^^^^^^^^ @@ -43,19 +43,19 @@ LL | #[warn(dead_code)] | ~~~~~~~~~ error: unknown lint: `clippy::unused_colle` - --> tests/ui/unknown_clippy_lints.rs:13:8 + --> tests/ui/unknown_clippy_lints.rs:19:8 | LL | #[warn(clippy::unused_colle)] | ^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::unused_self` error: unknown lint: `clippy::const_static_lifetim` - --> tests/ui/unknown_clippy_lints.rs:15:8 + --> tests/ui/unknown_clippy_lints.rs:22:8 | LL | #[warn(clippy::const_static_lifetim)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::redundant_static_lifetimes` error: unknown lint: `clippy::missing_docs` - --> tests/ui/unknown_clippy_lints.rs:17:8 + --> tests/ui/unknown_clippy_lints.rs:25:8 | LL | #[warn(clippy::missing_docs)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_box_returns.rs b/tests/ui/unnecessary_box_returns.rs index bcdaca33b644..5037c05a0acb 100644 --- a/tests/ui/unnecessary_box_returns.rs +++ b/tests/ui/unnecessary_box_returns.rs @@ -3,7 +3,8 @@ trait Bar { // lint fn baz(&self) -> Box; - //~^ ERROR: boxed return of the sized type `usize` + //~^ unnecessary_box_returns + } pub struct Foo {} @@ -17,7 +18,8 @@ impl Bar for Foo { impl Foo { fn baz(&self) -> Box { - //~^ ERROR: boxed return of the sized type `usize` + //~^ unnecessary_box_returns + // lint Box::new(13) } @@ -25,13 +27,15 @@ impl Foo { // lint fn bxed_usize() -> Box { - //~^ ERROR: boxed return of the sized type `usize` +//~^ unnecessary_box_returns + Box::new(5) } // lint fn _bxed_foo() -> Box { - //~^ ERROR: boxed return of the sized type `Foo` +//~^ unnecessary_box_returns + Box::new(Foo {}) } diff --git a/tests/ui/unnecessary_box_returns.stderr b/tests/ui/unnecessary_box_returns.stderr index cb88ba1b0016..9df056569a29 100644 --- a/tests/ui/unnecessary_box_returns.stderr +++ b/tests/ui/unnecessary_box_returns.stderr @@ -9,7 +9,7 @@ LL | fn baz(&self) -> Box; = help: to override `-D warnings` add `#[allow(clippy::unnecessary_box_returns)]` error: boxed return of the sized type `usize` - --> tests/ui/unnecessary_box_returns.rs:19:22 + --> tests/ui/unnecessary_box_returns.rs:20:22 | LL | fn baz(&self) -> Box { | ^^^^^^^^^^ help: try: `usize` @@ -17,7 +17,7 @@ LL | fn baz(&self) -> Box { = help: changing this also requires a change to the return expressions in this function error: boxed return of the sized type `usize` - --> tests/ui/unnecessary_box_returns.rs:27:20 + --> tests/ui/unnecessary_box_returns.rs:29:20 | LL | fn bxed_usize() -> Box { | ^^^^^^^^^^ help: try: `usize` @@ -25,7 +25,7 @@ LL | fn bxed_usize() -> Box { = help: changing this also requires a change to the return expressions in this function error: boxed return of the sized type `Foo` - --> tests/ui/unnecessary_box_returns.rs:33:19 + --> tests/ui/unnecessary_box_returns.rs:36:19 | LL | fn _bxed_foo() -> Box { | ^^^^^^^^ help: try: `Foo` diff --git a/tests/ui/unnecessary_cast.fixed b/tests/ui/unnecessary_cast.fixed index c43e50761bd5..abaab6aa9a05 100644 --- a/tests/ui/unnecessary_cast.fixed +++ b/tests/ui/unnecessary_cast.fixed @@ -17,6 +17,7 @@ type PtrMutU8 = *mut u8; fn owo(ptr: *const T) -> *const T { ptr + //~^ unnecessary_cast } fn uwu(ptr: *const T) -> *const U { @@ -52,21 +53,32 @@ fn bbb() -> UnsignedThirtyTwoBitInteger { fn main() { // Test cast_unnecessary 1_i32; + //~^ unnecessary_cast 1_f32; + //~^ unnecessary_cast false; + //~^ unnecessary_cast &1i32 as &i32; -1_i32; + //~^ unnecessary_cast - 1_i32; + //~^ unnecessary_cast -1_f32; + //~^ unnecessary_cast 1_i32; + //~^ unnecessary_cast 1_f32; + //~^ unnecessary_cast let _: *mut u8 = [1u8, 2].as_ptr() as *mut u8; + //~^ unnecessary_cast [1u8, 2].as_ptr(); + //~^ unnecessary_cast [1u8, 2].as_ptr() as *mut u8; [1u8, 2].as_mut_ptr(); + //~^ unnecessary_cast [1u8, 2].as_mut_ptr() as *const u8; [1u8, 2].as_ptr() as PtrConstU8; [1u8, 2].as_ptr() as PtrMutU8; @@ -78,9 +90,12 @@ fn main() { let _: *mut u8 = [1u8, 2].as_mut_ptr() as *mut _; owo::([1u32].as_ptr()); + //~^ unnecessary_cast uwu::([1u32].as_ptr()); + //~^ unnecessary_cast // this will not lint in the function body even though they have the same type, instead here uwu::([1u32].as_ptr()); + //~^ unnecessary_cast // macro version macro_rules! foo { @@ -116,8 +131,10 @@ fn main() { let pid = unsafe { fake_libc::getpid() }; pid as i32; aaa(); + //~^ unnecessary_cast let x = aaa(); aaa(); + //~^ unnecessary_cast // Will not lint currently. bbb() as u32; let x = bbb(); @@ -154,13 +171,21 @@ mod fixable { fn main() { // casting integer literal to float is unnecessary 100_f32; + //~^ unnecessary_cast 100_f64; + //~^ unnecessary_cast 100_f64; + //~^ unnecessary_cast let _ = -100_f32; + //~^ unnecessary_cast let _ = -100_f64; + //~^ unnecessary_cast let _ = -100_f64; + //~^ unnecessary_cast 100_f32; + //~^ unnecessary_cast 100_f64; + //~^ unnecessary_cast // Should not trigger #[rustfmt::skip] let v = vec!(1); @@ -173,32 +198,44 @@ mod fixable { 0b11 as f64; 1_u32; + //~^ unnecessary_cast 0x10_i32; + //~^ unnecessary_cast 0b10_usize; + //~^ unnecessary_cast 0o73_u16; + //~^ unnecessary_cast 1_000_000_000_u32; + //~^ unnecessary_cast 1.0_f64; + //~^ unnecessary_cast 0.5_f32; + //~^ unnecessary_cast 1.0 as u16; let _ = -1_i32; + //~^ unnecessary_cast let _ = -1.0_f32; + //~^ unnecessary_cast let _ = 1 as I32Alias; let _ = &1 as &I32Alias; let x = 1i32; let _ = &{ x }; + //~^ unnecessary_cast } type I32Alias = i32; fn issue_9380() { let _: i32 = -1_i32; + //~^ unnecessary_cast let _: f32 = -(1) as f32; let _: i64 = -1_i64; + //~^ unnecessary_cast let _: i64 = -(1.0) as i64; let _ = -(1 + 1) as i64; @@ -206,8 +243,10 @@ mod fixable { fn issue_9563() { let _: f64 = (-8.0_f64).exp(); + //~^ unnecessary_cast #[allow(ambiguous_negative_literals)] let _: f64 = -8.0_f64.exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior + //~^ unnecessary_cast } fn issue_9562_non_literal() { @@ -216,6 +255,7 @@ mod fixable { } let _num = foo(); + //~^ unnecessary_cast } fn issue_9603() { @@ -226,5 +266,6 @@ mod fixable { // `*x.pow(2)` which tries to dereference the return value rather than `x`. fn issue_11968(x: &usize) -> usize { { *x }.pow(2) + //~^ unnecessary_cast } } diff --git a/tests/ui/unnecessary_cast.rs b/tests/ui/unnecessary_cast.rs index 4a5ca231315e..8f2493def09a 100644 --- a/tests/ui/unnecessary_cast.rs +++ b/tests/ui/unnecessary_cast.rs @@ -17,6 +17,7 @@ type PtrMutU8 = *mut u8; fn owo(ptr: *const T) -> *const T { ptr as *const T + //~^ unnecessary_cast } fn uwu(ptr: *const T) -> *const U { @@ -52,21 +53,32 @@ fn bbb() -> UnsignedThirtyTwoBitInteger { fn main() { // Test cast_unnecessary 1i32 as i32; + //~^ unnecessary_cast 1f32 as f32; + //~^ unnecessary_cast false as bool; + //~^ unnecessary_cast &1i32 as &i32; -1_i32 as i32; + //~^ unnecessary_cast - 1_i32 as i32; + //~^ unnecessary_cast -1f32 as f32; + //~^ unnecessary_cast 1_i32 as i32; + //~^ unnecessary_cast 1_f32 as f32; + //~^ unnecessary_cast let _: *mut u8 = [1u8, 2].as_ptr() as *const u8 as *mut u8; + //~^ unnecessary_cast [1u8, 2].as_ptr() as *const u8; + //~^ unnecessary_cast [1u8, 2].as_ptr() as *mut u8; [1u8, 2].as_mut_ptr() as *mut u8; + //~^ unnecessary_cast [1u8, 2].as_mut_ptr() as *const u8; [1u8, 2].as_ptr() as PtrConstU8; [1u8, 2].as_ptr() as PtrMutU8; @@ -78,9 +90,12 @@ fn main() { let _: *mut u8 = [1u8, 2].as_mut_ptr() as *mut _; owo::([1u32].as_ptr()) as *const u32; + //~^ unnecessary_cast uwu::([1u32].as_ptr()) as *const u8; + //~^ unnecessary_cast // this will not lint in the function body even though they have the same type, instead here uwu::([1u32].as_ptr()) as *const u32; + //~^ unnecessary_cast // macro version macro_rules! foo { @@ -116,8 +131,10 @@ fn main() { let pid = unsafe { fake_libc::getpid() }; pid as i32; aaa() as u32; + //~^ unnecessary_cast let x = aaa(); aaa() as u32; + //~^ unnecessary_cast // Will not lint currently. bbb() as u32; let x = bbb(); @@ -154,13 +171,21 @@ mod fixable { fn main() { // casting integer literal to float is unnecessary 100 as f32; + //~^ unnecessary_cast 100 as f64; + //~^ unnecessary_cast 100_i32 as f64; + //~^ unnecessary_cast let _ = -100 as f32; + //~^ unnecessary_cast let _ = -100 as f64; + //~^ unnecessary_cast let _ = -100_i32 as f64; + //~^ unnecessary_cast 100. as f32; + //~^ unnecessary_cast 100. as f64; + //~^ unnecessary_cast // Should not trigger #[rustfmt::skip] let v = vec!(1); @@ -173,32 +198,44 @@ mod fixable { 0b11 as f64; 1 as u32; + //~^ unnecessary_cast 0x10 as i32; + //~^ unnecessary_cast 0b10 as usize; + //~^ unnecessary_cast 0o73 as u16; + //~^ unnecessary_cast 1_000_000_000 as u32; + //~^ unnecessary_cast 1.0 as f64; + //~^ unnecessary_cast 0.5 as f32; + //~^ unnecessary_cast 1.0 as u16; let _ = -1 as i32; + //~^ unnecessary_cast let _ = -1.0 as f32; + //~^ unnecessary_cast let _ = 1 as I32Alias; let _ = &1 as &I32Alias; let x = 1i32; let _ = &(x as i32); + //~^ unnecessary_cast } type I32Alias = i32; fn issue_9380() { let _: i32 = -(1) as i32; + //~^ unnecessary_cast let _: f32 = -(1) as f32; let _: i64 = -(1) as i64; + //~^ unnecessary_cast let _: i64 = -(1.0) as i64; let _ = -(1 + 1) as i64; @@ -206,8 +243,10 @@ mod fixable { fn issue_9563() { let _: f64 = (-8.0 as f64).exp(); + //~^ unnecessary_cast #[allow(ambiguous_negative_literals)] let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior + //~^ unnecessary_cast } fn issue_9562_non_literal() { @@ -216,6 +255,7 @@ mod fixable { } let _num = foo() as f32; + //~^ unnecessary_cast } fn issue_9603() { @@ -226,5 +266,6 @@ mod fixable { // `*x.pow(2)` which tries to dereference the return value rather than `x`. fn issue_11968(x: &usize) -> usize { (*x as usize).pow(2) + //~^ unnecessary_cast } } diff --git a/tests/ui/unnecessary_cast.stderr b/tests/ui/unnecessary_cast.stderr index 80fd5c13d818..3b8f5d0c5fd1 100644 --- a/tests/ui/unnecessary_cast.stderr +++ b/tests/ui/unnecessary_cast.stderr @@ -8,241 +8,241 @@ LL | ptr as *const T = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]` error: casting integer literal to `i32` is unnecessary - --> tests/ui/unnecessary_cast.rs:54:5 + --> tests/ui/unnecessary_cast.rs:55:5 | LL | 1i32 as i32; | ^^^^^^^^^^^ help: try: `1_i32` error: casting float literal to `f32` is unnecessary - --> tests/ui/unnecessary_cast.rs:55:5 + --> tests/ui/unnecessary_cast.rs:57:5 | LL | 1f32 as f32; | ^^^^^^^^^^^ help: try: `1_f32` error: casting to the same type is unnecessary (`bool` -> `bool`) - --> tests/ui/unnecessary_cast.rs:56:5 + --> tests/ui/unnecessary_cast.rs:59:5 | LL | false as bool; | ^^^^^^^^^^^^^ help: try: `false` error: casting integer literal to `i32` is unnecessary - --> tests/ui/unnecessary_cast.rs:59:5 + --> tests/ui/unnecessary_cast.rs:63:5 | LL | -1_i32 as i32; | ^^^^^^^^^^^^^ help: try: `-1_i32` error: casting integer literal to `i32` is unnecessary - --> tests/ui/unnecessary_cast.rs:60:5 + --> tests/ui/unnecessary_cast.rs:65:5 | LL | - 1_i32 as i32; | ^^^^^^^^^^^^^^ help: try: `- 1_i32` error: casting float literal to `f32` is unnecessary - --> tests/ui/unnecessary_cast.rs:61:5 + --> tests/ui/unnecessary_cast.rs:67:5 | LL | -1f32 as f32; | ^^^^^^^^^^^^ help: try: `-1_f32` error: casting integer literal to `i32` is unnecessary - --> tests/ui/unnecessary_cast.rs:62:5 + --> tests/ui/unnecessary_cast.rs:69:5 | LL | 1_i32 as i32; | ^^^^^^^^^^^^ help: try: `1_i32` error: casting float literal to `f32` is unnecessary - --> tests/ui/unnecessary_cast.rs:63:5 + --> tests/ui/unnecessary_cast.rs:71:5 | LL | 1_f32 as f32; | ^^^^^^^^^^^^ help: try: `1_f32` error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`) - --> tests/ui/unnecessary_cast.rs:65:22 + --> tests/ui/unnecessary_cast.rs:74:22 | LL | let _: *mut u8 = [1u8, 2].as_ptr() as *const u8 as *mut u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_ptr()` error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`) - --> tests/ui/unnecessary_cast.rs:67:5 + --> tests/ui/unnecessary_cast.rs:77:5 | LL | [1u8, 2].as_ptr() as *const u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_ptr()` error: casting raw pointers to the same type and constness is unnecessary (`*mut u8` -> `*mut u8`) - --> tests/ui/unnecessary_cast.rs:69:5 + --> tests/ui/unnecessary_cast.rs:80:5 | LL | [1u8, 2].as_mut_ptr() as *mut u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_mut_ptr()` error: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`) - --> tests/ui/unnecessary_cast.rs:80:5 + --> tests/ui/unnecessary_cast.rs:92:5 | LL | owo::([1u32].as_ptr()) as *const u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `owo::([1u32].as_ptr())` error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`) - --> tests/ui/unnecessary_cast.rs:81:5 + --> tests/ui/unnecessary_cast.rs:94:5 | LL | uwu::([1u32].as_ptr()) as *const u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `uwu::([1u32].as_ptr())` error: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`) - --> tests/ui/unnecessary_cast.rs:83:5 + --> tests/ui/unnecessary_cast.rs:97:5 | LL | uwu::([1u32].as_ptr()) as *const u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `uwu::([1u32].as_ptr())` error: casting to the same type is unnecessary (`u32` -> `u32`) - --> tests/ui/unnecessary_cast.rs:118:5 + --> tests/ui/unnecessary_cast.rs:133:5 | LL | aaa() as u32; | ^^^^^^^^^^^^ help: try: `aaa()` error: casting to the same type is unnecessary (`u32` -> `u32`) - --> tests/ui/unnecessary_cast.rs:120:5 + --> tests/ui/unnecessary_cast.rs:136:5 | LL | aaa() as u32; | ^^^^^^^^^^^^ help: try: `aaa()` error: casting integer literal to `f32` is unnecessary - --> tests/ui/unnecessary_cast.rs:156:9 + --> tests/ui/unnecessary_cast.rs:173:9 | LL | 100 as f32; | ^^^^^^^^^^ help: try: `100_f32` error: casting integer literal to `f64` is unnecessary - --> tests/ui/unnecessary_cast.rs:157:9 + --> tests/ui/unnecessary_cast.rs:175:9 | LL | 100 as f64; | ^^^^^^^^^^ help: try: `100_f64` error: casting integer literal to `f64` is unnecessary - --> tests/ui/unnecessary_cast.rs:158:9 + --> tests/ui/unnecessary_cast.rs:177:9 | LL | 100_i32 as f64; | ^^^^^^^^^^^^^^ help: try: `100_f64` error: casting integer literal to `f32` is unnecessary - --> tests/ui/unnecessary_cast.rs:159:17 + --> tests/ui/unnecessary_cast.rs:179:17 | LL | let _ = -100 as f32; | ^^^^^^^^^^^ help: try: `-100_f32` error: casting integer literal to `f64` is unnecessary - --> tests/ui/unnecessary_cast.rs:160:17 + --> tests/ui/unnecessary_cast.rs:181:17 | LL | let _ = -100 as f64; | ^^^^^^^^^^^ help: try: `-100_f64` error: casting integer literal to `f64` is unnecessary - --> tests/ui/unnecessary_cast.rs:161:17 + --> tests/ui/unnecessary_cast.rs:183:17 | LL | let _ = -100_i32 as f64; | ^^^^^^^^^^^^^^^ help: try: `-100_f64` error: casting float literal to `f32` is unnecessary - --> tests/ui/unnecessary_cast.rs:162:9 + --> tests/ui/unnecessary_cast.rs:185:9 | LL | 100. as f32; | ^^^^^^^^^^^ help: try: `100_f32` error: casting float literal to `f64` is unnecessary - --> tests/ui/unnecessary_cast.rs:163:9 + --> tests/ui/unnecessary_cast.rs:187:9 | LL | 100. as f64; | ^^^^^^^^^^^ help: try: `100_f64` error: casting integer literal to `u32` is unnecessary - --> tests/ui/unnecessary_cast.rs:175:9 + --> tests/ui/unnecessary_cast.rs:200:9 | LL | 1 as u32; | ^^^^^^^^ help: try: `1_u32` error: casting integer literal to `i32` is unnecessary - --> tests/ui/unnecessary_cast.rs:176:9 + --> tests/ui/unnecessary_cast.rs:202:9 | LL | 0x10 as i32; | ^^^^^^^^^^^ help: try: `0x10_i32` error: casting integer literal to `usize` is unnecessary - --> tests/ui/unnecessary_cast.rs:177:9 + --> tests/ui/unnecessary_cast.rs:204:9 | LL | 0b10 as usize; | ^^^^^^^^^^^^^ help: try: `0b10_usize` error: casting integer literal to `u16` is unnecessary - --> tests/ui/unnecessary_cast.rs:178:9 + --> tests/ui/unnecessary_cast.rs:206:9 | LL | 0o73 as u16; | ^^^^^^^^^^^ help: try: `0o73_u16` error: casting integer literal to `u32` is unnecessary - --> tests/ui/unnecessary_cast.rs:179:9 + --> tests/ui/unnecessary_cast.rs:208:9 | LL | 1_000_000_000 as u32; | ^^^^^^^^^^^^^^^^^^^^ help: try: `1_000_000_000_u32` error: casting float literal to `f64` is unnecessary - --> tests/ui/unnecessary_cast.rs:181:9 + --> tests/ui/unnecessary_cast.rs:211:9 | LL | 1.0 as f64; | ^^^^^^^^^^ help: try: `1.0_f64` error: casting float literal to `f32` is unnecessary - --> tests/ui/unnecessary_cast.rs:182:9 + --> tests/ui/unnecessary_cast.rs:213:9 | LL | 0.5 as f32; | ^^^^^^^^^^ help: try: `0.5_f32` error: casting integer literal to `i32` is unnecessary - --> tests/ui/unnecessary_cast.rs:186:17 + --> tests/ui/unnecessary_cast.rs:218:17 | LL | let _ = -1 as i32; | ^^^^^^^^^ help: try: `-1_i32` error: casting float literal to `f32` is unnecessary - --> tests/ui/unnecessary_cast.rs:187:17 + --> tests/ui/unnecessary_cast.rs:220:17 | LL | let _ = -1.0 as f32; | ^^^^^^^^^^^ help: try: `-1.0_f32` error: casting to the same type is unnecessary (`i32` -> `i32`) - --> tests/ui/unnecessary_cast.rs:193:18 + --> tests/ui/unnecessary_cast.rs:227:18 | LL | let _ = &(x as i32); | ^^^^^^^^^^ help: try: `{ x }` error: casting integer literal to `i32` is unnecessary - --> tests/ui/unnecessary_cast.rs:199:22 + --> tests/ui/unnecessary_cast.rs:234:22 | LL | let _: i32 = -(1) as i32; | ^^^^^^^^^^^ help: try: `-1_i32` error: casting integer literal to `i64` is unnecessary - --> tests/ui/unnecessary_cast.rs:201:22 + --> tests/ui/unnecessary_cast.rs:237:22 | LL | let _: i64 = -(1) as i64; | ^^^^^^^^^^^ help: try: `-1_i64` error: casting float literal to `f64` is unnecessary - --> tests/ui/unnecessary_cast.rs:208:22 + --> tests/ui/unnecessary_cast.rs:245:22 | LL | let _: f64 = (-8.0 as f64).exp(); | ^^^^^^^^^^^^^ help: try: `(-8.0_f64)` error: casting float literal to `f64` is unnecessary - --> tests/ui/unnecessary_cast.rs:210:23 + --> tests/ui/unnecessary_cast.rs:248:23 | LL | let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior | ^^^^^^^^^^^^ help: try: `8.0_f64` error: casting to the same type is unnecessary (`f32` -> `f32`) - --> tests/ui/unnecessary_cast.rs:218:20 + --> tests/ui/unnecessary_cast.rs:257:20 | LL | let _num = foo() as f32; | ^^^^^^^^^^^^ help: try: `foo()` error: casting to the same type is unnecessary (`usize` -> `usize`) - --> tests/ui/unnecessary_cast.rs:228:9 + --> tests/ui/unnecessary_cast.rs:268:9 | LL | (*x as usize).pow(2) | ^^^^^^^^^^^^^ help: try: `{ *x }` diff --git a/tests/ui/unnecessary_cast_unfixable.rs b/tests/ui/unnecessary_cast_unfixable.rs index 36adf19c91ca..05dd20c7a114 100644 --- a/tests/ui/unnecessary_cast_unfixable.rs +++ b/tests/ui/unnecessary_cast_unfixable.rs @@ -2,8 +2,9 @@ //@no-rustfix fn main() { let _ = std::ptr::null() as *const u8; - //~^ ERROR: casting raw pointers to the same type and constness is unnecessary (`*cons - //~| NOTE: `-D clippy::unnecessary-cast` implied by `-D warnings` + //~^ unnecessary_cast + + } mod issue11113 { @@ -19,7 +20,8 @@ mod issue11113 { impl TearOff { unsafe fn query(&self) { ((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)() - //~^ ERROR: casting raw pointers to the same type and constness is unnecessary + //~^ unnecessary_cast + } } } diff --git a/tests/ui/unnecessary_cast_unfixable.stderr b/tests/ui/unnecessary_cast_unfixable.stderr index cafaffeae6c3..0047b38850b7 100644 --- a/tests/ui/unnecessary_cast_unfixable.stderr +++ b/tests/ui/unnecessary_cast_unfixable.stderr @@ -8,7 +8,7 @@ LL | let _ = std::ptr::null() as *const u8; = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]` error: casting raw pointers to the same type and constness is unnecessary (`*mut issue11113::Vtbl` -> `*mut issue11113::Vtbl`) - --> tests/ui/unnecessary_cast_unfixable.rs:21:16 + --> tests/ui/unnecessary_cast_unfixable.rs:22:16 | LL | ((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `*(self.object as *mut *mut _)` diff --git a/tests/ui/unnecessary_clippy_cfg.rs b/tests/ui/unnecessary_clippy_cfg.rs index 9915f8b843ef..406c0133c5d3 100644 --- a/tests/ui/unnecessary_clippy_cfg.rs +++ b/tests/ui/unnecessary_clippy_cfg.rs @@ -2,22 +2,32 @@ #![warn(clippy::unnecessary_clippy_cfg)] #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] -//~^ ERROR: no need to put clippy lints behind a `clippy` cfg +//~^ unnecessary_clippy_cfg + #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] -//~^ ERROR: no need to put clippy lints behind a `clippy` cfg +//~^ unnecessary_clippy_cfg + #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] -//~^ ERROR: no need to put clippy lints behind a `clippy` cfg +//~^ unnecessary_clippy_cfg +//~| duplicated_attributes + #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] -//~^ ERROR: no need to put clippy lints behind a `clippy` cfg +//~^ unnecessary_clippy_cfg + #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] -//~^ ERROR: no need to put clippy lints behind a `clippy` cfg +//~^ unnecessary_clippy_cfg + #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] -//~^ ERROR: no need to put clippy lints behind a `clippy` cfg +//~^ unnecessary_clippy_cfg + #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] -//~^ ERROR: no need to put clippy lints behind a `clippy` cfg +//~^ unnecessary_clippy_cfg +//~| duplicated_attributes + #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] -//~^ ERROR: no need to put clippy lints behind a `clippy` cfg +//~^ unnecessary_clippy_cfg + pub struct Bar; fn main() {} diff --git a/tests/ui/unnecessary_clippy_cfg.stderr b/tests/ui/unnecessary_clippy_cfg.stderr index 01f842a657de..f6f36fbf2baa 100644 --- a/tests/ui/unnecessary_clippy_cfg.stderr +++ b/tests/ui/unnecessary_clippy_cfg.stderr @@ -8,7 +8,7 @@ LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] = help: to override `-D warnings` add `#[allow(clippy::unnecessary_clippy_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:6:37 + --> tests/ui/unnecessary_clippy_cfg.rs:7:37 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = note: write instead: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:8:37 + --> tests/ui/unnecessary_clippy_cfg.rs:10:37 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,19 +24,19 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = note: write instead: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:10:1 + --> tests/ui/unnecessary_clippy_cfg.rs:14:1 | LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:13:1 + --> tests/ui/unnecessary_clippy_cfg.rs:18:1 | LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:15:36 + --> tests/ui/unnecessary_clippy_cfg.rs:21:36 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = note: write instead: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:17:36 + --> tests/ui/unnecessary_clippy_cfg.rs:24:36 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,24 +52,24 @@ LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = note: write instead: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:19:1 + --> tests/ui/unnecessary_clippy_cfg.rs:28:1 | LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]` error: duplicated attribute - --> tests/ui/unnecessary_clippy_cfg.rs:8:26 + --> tests/ui/unnecessary_clippy_cfg.rs:10:26 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ | note: first defined here - --> tests/ui/unnecessary_clippy_cfg.rs:6:26 + --> tests/ui/unnecessary_clippy_cfg.rs:7:26 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ help: remove this attribute - --> tests/ui/unnecessary_clippy_cfg.rs:8:26 + --> tests/ui/unnecessary_clippy_cfg.rs:10:26 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ @@ -77,18 +77,18 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]` error: duplicated attribute - --> tests/ui/unnecessary_clippy_cfg.rs:17:25 + --> tests/ui/unnecessary_clippy_cfg.rs:24:25 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ | note: first defined here - --> tests/ui/unnecessary_clippy_cfg.rs:15:25 + --> tests/ui/unnecessary_clippy_cfg.rs:21:25 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ help: remove this attribute - --> tests/ui/unnecessary_clippy_cfg.rs:17:25 + --> tests/ui/unnecessary_clippy_cfg.rs:24:25 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ diff --git a/tests/ui/unnecessary_clone.rs b/tests/ui/unnecessary_clone.rs index 12ac96aa64ca..3ce7c7ef0252 100644 --- a/tests/ui/unnecessary_clone.rs +++ b/tests/ui/unnecessary_clone.rs @@ -21,34 +21,41 @@ fn clone_on_ref_ptr() { let arc_weak = Arc::downgrade(&arc); rc.clone(); - //~^ ERROR: using `.clone()` on a ref-counted pointer - //~| NOTE: `-D clippy::clone-on-ref-ptr` implied by `-D warnings` + //~^ clone_on_ref_ptr + + Rc::clone(&rc); arc.clone(); - //~^ ERROR: using `.clone()` on a ref-counted pointer + //~^ clone_on_ref_ptr + Arc::clone(&arc); rcweak.clone(); - //~^ ERROR: using `.clone()` on a ref-counted pointer + //~^ clone_on_ref_ptr + rc::Weak::clone(&rcweak); arc_weak.clone(); - //~^ ERROR: using `.clone()` on a ref-counted pointer + //~^ clone_on_ref_ptr + sync::Weak::clone(&arc_weak); let x = Arc::new(SomeImpl); let _: Arc = x.clone(); - //~^ ERROR: using `.clone()` on a ref-counted pointer + //~^ clone_on_ref_ptr + } fn clone_on_copy_generic(t: T) { t.clone(); - //~^ ERROR: using `clone` on type `T` which implements the `Copy` trait - //~| NOTE: `-D clippy::clone-on-copy` implied by `-D warnings` + //~^ clone_on_copy + + Some(t).clone(); - //~^ ERROR: using `clone` on type `Option` which implements the `Copy` trait + //~^ clone_on_copy + } mod many_derefs { @@ -83,7 +90,8 @@ mod many_derefs { fn go1() { let a = A; let _: E = a.clone(); - //~^ ERROR: using `clone` on type `E` which implements the `Copy` trait + //~^ clone_on_copy + let _: E = *****a; } } @@ -103,6 +111,7 @@ mod issue2076 { fn func() -> Option> { let rc = Rc::new(42); Some(try_opt!(Some(rc)).clone()) - //~^ ERROR: using `.clone()` on a ref-counted pointer + //~^ clone_on_ref_ptr + } } diff --git a/tests/ui/unnecessary_clone.stderr b/tests/ui/unnecessary_clone.stderr index e34a387c77e2..cf508eb4c645 100644 --- a/tests/ui/unnecessary_clone.stderr +++ b/tests/ui/unnecessary_clone.stderr @@ -8,31 +8,31 @@ LL | rc.clone(); = help: to override `-D warnings` add `#[allow(clippy::clone_on_ref_ptr)]` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:28:5 + --> tests/ui/unnecessary_clone.rs:29:5 | LL | arc.clone(); | ^^^^^^^^^^^ help: try: `Arc::::clone(&arc)` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:32:5 + --> tests/ui/unnecessary_clone.rs:34:5 | LL | rcweak.clone(); | ^^^^^^^^^^^^^^ help: try: `Weak::::clone(&rcweak)` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:36:5 + --> tests/ui/unnecessary_clone.rs:39:5 | LL | arc_weak.clone(); | ^^^^^^^^^^^^^^^^ help: try: `Weak::::clone(&arc_weak)` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:41:33 + --> tests/ui/unnecessary_clone.rs:45:33 | LL | let _: Arc = x.clone(); | ^^^^^^^^^ help: try: `Arc::::clone(&x)` error: using `clone` on type `T` which implements the `Copy` trait - --> tests/ui/unnecessary_clone.rs:46:5 + --> tests/ui/unnecessary_clone.rs:51:5 | LL | t.clone(); | ^^^^^^^^^ help: try removing the `clone` call: `t` @@ -41,19 +41,19 @@ LL | t.clone(); = help: to override `-D warnings` add `#[allow(clippy::clone_on_copy)]` error: using `clone` on type `Option` which implements the `Copy` trait - --> tests/ui/unnecessary_clone.rs:50:5 + --> tests/ui/unnecessary_clone.rs:56:5 | LL | Some(t).clone(); | ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)` error: using `clone` on type `E` which implements the `Copy` trait - --> tests/ui/unnecessary_clone.rs:85:20 + --> tests/ui/unnecessary_clone.rs:92:20 | LL | let _: E = a.clone(); | ^^^^^^^^^ help: try dereferencing it: `*****a` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:105:14 + --> tests/ui/unnecessary_clone.rs:113:14 | LL | Some(try_opt!(Some(rc)).clone()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Rc::::clone(&try_opt!(Some(rc)))` diff --git a/tests/ui/unnecessary_fallible_conversions.fixed b/tests/ui/unnecessary_fallible_conversions.fixed index b6dd1f267743..59d24e9bb7e2 100644 --- a/tests/ui/unnecessary_fallible_conversions.fixed +++ b/tests/ui/unnecessary_fallible_conversions.fixed @@ -4,40 +4,50 @@ fn main() { // --- TryFromMethod `T::try_from(u)` --- let _: i64 = 0i32.into(); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _: i64 = 0i32.into(); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + // --- TryFromFunction `T::try_from(U)` --- let _ = i64::from(0i32); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _ = i64::from(0i32); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + // --- TryIntoFunction `U::try_into(t)` --- let _: i64 = i32::into(0); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _: i64 = i32::into(0i32); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + // --- TryFromFunction `>::try_from(U)` --- let _ = >::from(0); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _ = >::from(0); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + // --- TryIntoFunction `>::try_into(U)` --- let _: i64 = >::into(0); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _: i64 = >::into(0); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + } diff --git a/tests/ui/unnecessary_fallible_conversions.rs b/tests/ui/unnecessary_fallible_conversions.rs index 6f8df7365e89..7e504acb5e21 100644 --- a/tests/ui/unnecessary_fallible_conversions.rs +++ b/tests/ui/unnecessary_fallible_conversions.rs @@ -4,40 +4,50 @@ fn main() { // --- TryFromMethod `T::try_from(u)` --- let _: i64 = 0i32.try_into().unwrap(); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _: i64 = 0i32.try_into().expect("can't happen"); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + // --- TryFromFunction `T::try_from(U)` --- let _ = i64::try_from(0i32).unwrap(); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _ = i64::try_from(0i32).expect("can't happen"); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + // --- TryIntoFunction `U::try_into(t)` --- let _: i64 = i32::try_into(0).unwrap(); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _: i64 = i32::try_into(0i32).expect("can't happen"); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + // --- TryFromFunction `>::try_from(U)` --- let _ = >::try_from(0).unwrap(); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _ = >::try_from(0).expect("can't happen"); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + // --- TryIntoFunction `>::try_into(U)` --- let _: i64 = >::try_into(0).unwrap(); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + let _: i64 = >::try_into(0).expect("can't happen"); - //~^ ERROR: use of a fallible conversion when an infallible one could be used + //~^ unnecessary_fallible_conversions + } diff --git a/tests/ui/unnecessary_fallible_conversions.stderr b/tests/ui/unnecessary_fallible_conversions.stderr index ade3aada9289..160917694c44 100644 --- a/tests/ui/unnecessary_fallible_conversions.stderr +++ b/tests/ui/unnecessary_fallible_conversions.stderr @@ -14,7 +14,7 @@ LL + let _: i64 = 0i32.into(); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:9:23 + --> tests/ui/unnecessary_fallible_conversions.rs:10:23 | LL | let _: i64 = 0i32.try_into().expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL + let _: i64 = 0i32.into(); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:14:13 + --> tests/ui/unnecessary_fallible_conversions.rs:16:13 | LL | let _ = i64::try_from(0i32).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL + let _ = i64::from(0i32); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:17:13 + --> tests/ui/unnecessary_fallible_conversions.rs:20:13 | LL | let _ = i64::try_from(0i32).expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ LL + let _ = i64::from(0i32); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:22:18 + --> tests/ui/unnecessary_fallible_conversions.rs:26:18 | LL | let _: i64 = i32::try_into(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL + let _: i64 = i32::into(0); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:25:18 + --> tests/ui/unnecessary_fallible_conversions.rs:30:18 | LL | let _: i64 = i32::try_into(0i32).expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,7 +79,7 @@ LL + let _: i64 = i32::into(0i32); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:30:13 + --> tests/ui/unnecessary_fallible_conversions.rs:36:13 | LL | let _ = >::try_from(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL + let _ = >::from(0); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:33:13 + --> tests/ui/unnecessary_fallible_conversions.rs:40:13 | LL | let _ = >::try_from(0).expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL + let _ = >::from(0); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:38:18 + --> tests/ui/unnecessary_fallible_conversions.rs:46:18 | LL | let _: i64 = >::try_into(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL + let _: i64 = >::into(0); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:41:18 + --> tests/ui/unnecessary_fallible_conversions.rs:50:18 | LL | let _: i64 = >::try_into(0).expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_filter_map.rs b/tests/ui/unnecessary_filter_map.rs index 8cf102ab0a55..e05161d207ec 100644 --- a/tests/ui/unnecessary_filter_map.rs +++ b/tests/ui/unnecessary_filter_map.rs @@ -3,29 +3,36 @@ fn main() { let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None }); - //~^ ERROR: this `.filter_map` can be written more simply - //~| NOTE: `-D clippy::unnecessary-filter-map` implied by `-D warnings` + //~^ unnecessary_filter_map + + let _ = (0..4).filter_map(|x| { - //~^ ERROR: this `.filter_map` can be written more simply + //~^ unnecessary_filter_map + if x > 1 { return Some(x); }; None }); let _ = (0..4).filter_map(|x| match x { - //~^ ERROR: this `.filter_map` can be written more simply + //~^ unnecessary_filter_map + 0 | 1 => None, _ => Some(x), }); let _ = (0..4).filter_map(|x| Some(x + 1)); - //~^ ERROR: this `.filter_map` can be written more simply + //~^ unnecessary_filter_map + let _ = (0..4).filter_map(i32::checked_abs); let _ = (0..4).filter_map(Some); let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); + //~^ redundant_closure + //~| unnecessary_filter_map + //~| unnecessary_filter_map } fn filter_map_none_changes_item_type() -> impl Iterator { @@ -163,4 +170,5 @@ fn issue11260() { // #11260 is about unnecessary_find_map, but the fix also kind of applies to // unnecessary_filter_map let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n)); + //~^ unnecessary_filter_map } diff --git a/tests/ui/unnecessary_filter_map.stderr b/tests/ui/unnecessary_filter_map.stderr index b21589c5f844..94435ab3effd 100644 --- a/tests/ui/unnecessary_filter_map.stderr +++ b/tests/ui/unnecessary_filter_map.stderr @@ -8,37 +8,38 @@ LL | let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None }); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_filter_map)]` error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:8:13 + --> tests/ui/unnecessary_filter_map.rs:9:13 | LL | let _ = (0..4).filter_map(|x| { | _____________^ LL | | +LL | | LL | | if x > 1 { -LL | | return Some(x); -LL | | }; +... | LL | | None LL | | }); | |______^ help: try instead: `filter` error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:15:13 + --> tests/ui/unnecessary_filter_map.rs:17:13 | LL | let _ = (0..4).filter_map(|x| match x { | _____________^ LL | | +LL | | LL | | 0 | 1 => None, LL | | _ => Some(x), LL | | }); | |______^ help: try instead: `filter` error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:21:13 + --> tests/ui/unnecessary_filter_map.rs:24:13 | LL | let _ = (0..4).filter_map(|x| Some(x + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map` error: redundant closure - --> tests/ui/unnecessary_filter_map.rs:28:57 + --> tests/ui/unnecessary_filter_map.rs:32:57 | LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); | ^^^^^^^^^^^ help: replace the closure with the function itself: `Some` @@ -47,19 +48,19 @@ LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]` error: filter_map is unnecessary - --> tests/ui/unnecessary_filter_map.rs:28:61 + --> tests/ui/unnecessary_filter_map.rs:32:61 | LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); | ^^^^ help: try removing the filter_map error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:28:13 + --> tests/ui/unnecessary_filter_map.rs:32:13 | LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map` error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:165:14 + --> tests/ui/unnecessary_filter_map.rs:172:14 | LL | let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `filter` diff --git a/tests/ui/unnecessary_find_map.rs b/tests/ui/unnecessary_find_map.rs index c357d8532481..f883b4eb38c5 100644 --- a/tests/ui/unnecessary_find_map.rs +++ b/tests/ui/unnecessary_find_map.rs @@ -3,23 +3,27 @@ fn main() { let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None }); - //~^ ERROR: this `.find_map` can be written more simply - //~| NOTE: `-D clippy::unnecessary-find-map` implied by `-D warnings` + //~^ unnecessary_find_map + + let _ = (0..4).find_map(|x| { - //~^ ERROR: this `.find_map` can be written more simply + //~^ unnecessary_find_map + if x > 1 { return Some(x); }; None }); let _ = (0..4).find_map(|x| match x { - //~^ ERROR: this `.find_map` can be written more simply + //~^ unnecessary_find_map + 0 | 1 => None, _ => Some(x), }); let _ = (0..4).find_map(|x| Some(x + 1)); - //~^ ERROR: this `.find_map` can be written more simply + //~^ unnecessary_find_map + let _ = (0..4).find_map(i32::checked_abs); } @@ -31,5 +35,6 @@ fn find_map_none_changes_item_type() -> Option { fn issue11260() { let y = Some(1); let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n)); + //~^ unnecessary_find_map let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(y)); // different option, so can't be just `.find()` } diff --git a/tests/ui/unnecessary_find_map.stderr b/tests/ui/unnecessary_find_map.stderr index 98a6c3d164a6..079c1092784e 100644 --- a/tests/ui/unnecessary_find_map.stderr +++ b/tests/ui/unnecessary_find_map.stderr @@ -8,37 +8,38 @@ LL | let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None }); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_find_map)]` error: this `.find_map` can be written more simply - --> tests/ui/unnecessary_find_map.rs:8:13 + --> tests/ui/unnecessary_find_map.rs:9:13 | LL | let _ = (0..4).find_map(|x| { | _____________^ LL | | +LL | | LL | | if x > 1 { -LL | | return Some(x); -LL | | }; +... | LL | | None LL | | }); | |______^ help: try instead: `find` error: this `.find_map` can be written more simply - --> tests/ui/unnecessary_find_map.rs:15:13 + --> tests/ui/unnecessary_find_map.rs:17:13 | LL | let _ = (0..4).find_map(|x| match x { | _____________^ LL | | +LL | | LL | | 0 | 1 => None, LL | | _ => Some(x), LL | | }); | |______^ help: try instead: `find` error: this `.find_map` can be written more simply - --> tests/ui/unnecessary_find_map.rs:21:13 + --> tests/ui/unnecessary_find_map.rs:24:13 | LL | let _ = (0..4).find_map(|x| Some(x + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map(..).next()` error: this `.find_map` can be written more simply - --> tests/ui/unnecessary_find_map.rs:33:14 + --> tests/ui/unnecessary_find_map.rs:37:14 | LL | let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `find` diff --git a/tests/ui/unnecessary_first_then_check.fixed b/tests/ui/unnecessary_first_then_check.fixed index 7202e1bbd179..aa049eb33751 100644 --- a/tests/ui/unnecessary_first_then_check.fixed +++ b/tests/ui/unnecessary_first_then_check.fixed @@ -4,19 +4,26 @@ fn main() { let s = [1, 2, 3]; let _: bool = !s.is_empty(); + //~^ unnecessary_first_then_check let _: bool = s.is_empty(); + //~^ unnecessary_first_then_check let v = vec![1, 2, 3]; let _: bool = !v.is_empty(); + //~^ unnecessary_first_then_check let n = [[1, 2, 3], [4, 5, 6]]; let _: bool = !n[0].is_empty(); + //~^ unnecessary_first_then_check let _: bool = n[0].is_empty(); + //~^ unnecessary_first_then_check struct Foo { bar: &'static [i32], } let f = [Foo { bar: &[] }]; let _: bool = !f[0].bar.is_empty(); + //~^ unnecessary_first_then_check let _: bool = f[0].bar.is_empty(); + //~^ unnecessary_first_then_check } diff --git a/tests/ui/unnecessary_first_then_check.rs b/tests/ui/unnecessary_first_then_check.rs index 762b95999288..4c2ac3ba40a2 100644 --- a/tests/ui/unnecessary_first_then_check.rs +++ b/tests/ui/unnecessary_first_then_check.rs @@ -4,19 +4,26 @@ fn main() { let s = [1, 2, 3]; let _: bool = s.first().is_some(); + //~^ unnecessary_first_then_check let _: bool = s.first().is_none(); + //~^ unnecessary_first_then_check let v = vec![1, 2, 3]; let _: bool = v.first().is_some(); + //~^ unnecessary_first_then_check let n = [[1, 2, 3], [4, 5, 6]]; let _: bool = n[0].first().is_some(); + //~^ unnecessary_first_then_check let _: bool = n[0].first().is_none(); + //~^ unnecessary_first_then_check struct Foo { bar: &'static [i32], } let f = [Foo { bar: &[] }]; let _: bool = f[0].bar.first().is_some(); + //~^ unnecessary_first_then_check let _: bool = f[0].bar.first().is_none(); + //~^ unnecessary_first_then_check } diff --git a/tests/ui/unnecessary_first_then_check.stderr b/tests/ui/unnecessary_first_then_check.stderr index bbaf7e68edab..408b388ecf71 100644 --- a/tests/ui/unnecessary_first_then_check.stderr +++ b/tests/ui/unnecessary_first_then_check.stderr @@ -8,37 +8,37 @@ LL | let _: bool = s.first().is_some(); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_first_then_check)]` error: unnecessary use of `first().is_none()` to check if slice is empty - --> tests/ui/unnecessary_first_then_check.rs:7:21 + --> tests/ui/unnecessary_first_then_check.rs:8:21 | LL | let _: bool = s.first().is_none(); | ^^^^^^^^^^^^^^^^^ help: replace this with: `is_empty()` error: unnecessary use of `first().is_some()` to check if slice is not empty - --> tests/ui/unnecessary_first_then_check.rs:10:19 + --> tests/ui/unnecessary_first_then_check.rs:12:19 | LL | let _: bool = v.first().is_some(); | ^^^^^^^^^^^^^^^^^^^ help: replace this with: `!v.is_empty()` error: unnecessary use of `first().is_some()` to check if slice is not empty - --> tests/ui/unnecessary_first_then_check.rs:13:19 + --> tests/ui/unnecessary_first_then_check.rs:16:19 | LL | let _: bool = n[0].first().is_some(); | ^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `!n[0].is_empty()` error: unnecessary use of `first().is_none()` to check if slice is empty - --> tests/ui/unnecessary_first_then_check.rs:14:24 + --> tests/ui/unnecessary_first_then_check.rs:18:24 | LL | let _: bool = n[0].first().is_none(); | ^^^^^^^^^^^^^^^^^ help: replace this with: `is_empty()` error: unnecessary use of `first().is_some()` to check if slice is not empty - --> tests/ui/unnecessary_first_then_check.rs:20:19 + --> tests/ui/unnecessary_first_then_check.rs:25:19 | LL | let _: bool = f[0].bar.first().is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `!f[0].bar.is_empty()` error: unnecessary use of `first().is_none()` to check if slice is empty - --> tests/ui/unnecessary_first_then_check.rs:21:28 + --> tests/ui/unnecessary_first_then_check.rs:27:28 | LL | let _: bool = f[0].bar.first().is_none(); | ^^^^^^^^^^^^^^^^^ help: replace this with: `is_empty()` diff --git a/tests/ui/unnecessary_fold.fixed b/tests/ui/unnecessary_fold.fixed index c5bc11b55ab5..2c3f87513c40 100644 --- a/tests/ui/unnecessary_fold.fixed +++ b/tests/ui/unnecessary_fold.fixed @@ -8,19 +8,25 @@ fn is_any(acc: bool, x: usize) -> bool { fn unnecessary_fold() { // Can be replaced by .any let _ = (0..3).any(|x| x > 2); + //~^ unnecessary_fold // Can be replaced by .any (checking suggestion) let _ = (0..3).fold(false, is_any); + //~^ redundant_closure // Can be replaced by .all let _ = (0..3).all(|x| x > 2); + //~^ unnecessary_fold // Can be replaced by .sum let _: i32 = (0..3).sum(); + //~^ unnecessary_fold // Can be replaced by .product let _: i32 = (0..3).product(); + //~^ unnecessary_fold } /// Should trigger the `UNNECESSARY_FOLD` lint, with an error span including exactly `.fold(...)` fn unnecessary_fold_span_for_multi_element_chain() { let _: bool = (0..3).map(|x| 2 * x).any(|x| x > 2); + //~^ unnecessary_fold } /// Calls which should not trigger the `UNNECESSARY_FOLD` lint @@ -51,6 +57,7 @@ fn unnecessary_fold_over_multiple_lines() { .map(|x| x + 1) .filter(|x| x % 2 == 0) .any(|x| x > 2); + //~^ unnecessary_fold } fn issue10000() { @@ -62,16 +69,25 @@ fn issue10000() { fn smoketest_map(mut map: HashMap) { map.insert(0, 0); assert_eq!(map.values().sum::(), 0); + //~^ unnecessary_fold // more cases: let _ = map.values().sum::(); + //~^ unnecessary_fold let _ = map.values().product::(); + //~^ unnecessary_fold let _: i32 = map.values().sum(); + //~^ unnecessary_fold let _: i32 = map.values().product(); + //~^ unnecessary_fold anything(map.values().sum::()); + //~^ unnecessary_fold anything(map.values().product::()); + //~^ unnecessary_fold num(map.values().sum()); + //~^ unnecessary_fold num(map.values().product()); + //~^ unnecessary_fold } smoketest_map(HashMap::new()); diff --git a/tests/ui/unnecessary_fold.rs b/tests/ui/unnecessary_fold.rs index 3a5136eeeaeb..954020046763 100644 --- a/tests/ui/unnecessary_fold.rs +++ b/tests/ui/unnecessary_fold.rs @@ -8,19 +8,25 @@ fn is_any(acc: bool, x: usize) -> bool { fn unnecessary_fold() { // Can be replaced by .any let _ = (0..3).fold(false, |acc, x| acc || x > 2); + //~^ unnecessary_fold // Can be replaced by .any (checking suggestion) let _ = (0..3).fold(false, |acc, x| is_any(acc, x)); + //~^ redundant_closure // Can be replaced by .all let _ = (0..3).fold(true, |acc, x| acc && x > 2); + //~^ unnecessary_fold // Can be replaced by .sum let _: i32 = (0..3).fold(0, |acc, x| acc + x); + //~^ unnecessary_fold // Can be replaced by .product let _: i32 = (0..3).fold(1, |acc, x| acc * x); + //~^ unnecessary_fold } /// Should trigger the `UNNECESSARY_FOLD` lint, with an error span including exactly `.fold(...)` fn unnecessary_fold_span_for_multi_element_chain() { let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2); + //~^ unnecessary_fold } /// Calls which should not trigger the `UNNECESSARY_FOLD` lint @@ -51,6 +57,7 @@ fn unnecessary_fold_over_multiple_lines() { .map(|x| x + 1) .filter(|x| x % 2 == 0) .fold(false, |acc, x| acc || x > 2); + //~^ unnecessary_fold } fn issue10000() { @@ -62,16 +69,25 @@ fn issue10000() { fn smoketest_map(mut map: HashMap) { map.insert(0, 0); assert_eq!(map.values().fold(0, |x, y| x + y), 0); + //~^ unnecessary_fold // more cases: let _ = map.values().fold(0, |x, y| x + y); + //~^ unnecessary_fold let _ = map.values().fold(1, |x, y| x * y); + //~^ unnecessary_fold let _: i32 = map.values().fold(0, |x, y| x + y); + //~^ unnecessary_fold let _: i32 = map.values().fold(1, |x, y| x * y); + //~^ unnecessary_fold anything(map.values().fold(0, |x, y| x + y)); + //~^ unnecessary_fold anything(map.values().fold(1, |x, y| x * y)); + //~^ unnecessary_fold num(map.values().fold(0, |x, y| x + y)); + //~^ unnecessary_fold num(map.values().fold(1, |x, y| x * y)); + //~^ unnecessary_fold } smoketest_map(HashMap::new()); diff --git a/tests/ui/unnecessary_fold.stderr b/tests/ui/unnecessary_fold.stderr index 31abab62f4c6..d82b1f39b48b 100644 --- a/tests/ui/unnecessary_fold.stderr +++ b/tests/ui/unnecessary_fold.stderr @@ -8,7 +8,7 @@ LL | let _ = (0..3).fold(false, |acc, x| acc || x > 2); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fold)]` error: redundant closure - --> tests/ui/unnecessary_fold.rs:12:32 + --> tests/ui/unnecessary_fold.rs:13:32 | LL | let _ = (0..3).fold(false, |acc, x| is_any(acc, x)); | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `is_any` @@ -17,85 +17,85 @@ LL | let _ = (0..3).fold(false, |acc, x| is_any(acc, x)); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:14:20 + --> tests/ui/unnecessary_fold.rs:16:20 | LL | let _ = (0..3).fold(true, |acc, x| acc && x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `all(|x| x > 2)` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:16:25 + --> tests/ui/unnecessary_fold.rs:19:25 | LL | let _: i32 = (0..3).fold(0, |acc, x| acc + x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:18:25 + --> tests/ui/unnecessary_fold.rs:22:25 | LL | let _: i32 = (0..3).fold(1, |acc, x| acc * x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:23:41 + --> tests/ui/unnecessary_fold.rs:28:41 | LL | let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:53:10 + --> tests/ui/unnecessary_fold.rs:59:10 | LL | .fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:64:33 + --> tests/ui/unnecessary_fold.rs:71:33 | LL | assert_eq!(map.values().fold(0, |x, y| x + y), 0); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:67:30 + --> tests/ui/unnecessary_fold.rs:75:30 | LL | let _ = map.values().fold(0, |x, y| x + y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:68:30 + --> tests/ui/unnecessary_fold.rs:77:30 | LL | let _ = map.values().fold(1, |x, y| x * y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:69:35 + --> tests/ui/unnecessary_fold.rs:79:35 | LL | let _: i32 = map.values().fold(0, |x, y| x + y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:70:35 + --> tests/ui/unnecessary_fold.rs:81:35 | LL | let _: i32 = map.values().fold(1, |x, y| x * y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:71:31 + --> tests/ui/unnecessary_fold.rs:83:31 | LL | anything(map.values().fold(0, |x, y| x + y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:72:31 + --> tests/ui/unnecessary_fold.rs:85:31 | LL | anything(map.values().fold(1, |x, y| x * y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:73:26 + --> tests/ui/unnecessary_fold.rs:87:26 | LL | num(map.values().fold(0, |x, y| x + y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:74:26 + --> tests/ui/unnecessary_fold.rs:89:26 | LL | num(map.values().fold(1, |x, y| x * y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` diff --git a/tests/ui/unnecessary_get_then_check.fixed b/tests/ui/unnecessary_get_then_check.fixed index 178a3300c346..6aba66b87318 100644 --- a/tests/ui/unnecessary_get_then_check.fixed +++ b/tests/ui/unnecessary_get_then_check.fixed @@ -4,23 +4,33 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; fn main() { let s: HashSet = HashSet::new(); - let _ = s.contains("a"); //~ ERROR: unnecessary use of `get("a").is_some()` - let _ = !s.contains("a"); //~ ERROR: unnecessary use of `get("a").is_none()` +let _ = s.contains("a"); +//~^ unnecessary_get_then_check +let _ = !s.contains("a"); +//~^ unnecessary_get_then_check let s: HashMap = HashMap::new(); - let _ = s.contains_key("a"); //~ ERROR: unnecessary use of `get("a").is_some()` - let _ = !s.contains_key("a"); //~ ERROR: unnecessary use of `get("a").is_none()` +let _ = s.contains_key("a"); +//~^ unnecessary_get_then_check +let _ = !s.contains_key("a"); +//~^ unnecessary_get_then_check let s: BTreeSet = BTreeSet::new(); - let _ = s.contains("a"); //~ ERROR: unnecessary use of `get("a").is_some()` - let _ = !s.contains("a"); //~ ERROR: unnecessary use of `get("a").is_none()` +let _ = s.contains("a"); +//~^ unnecessary_get_then_check +let _ = !s.contains("a"); +//~^ unnecessary_get_then_check let s: BTreeMap = BTreeMap::new(); - let _ = s.contains_key("a"); //~ ERROR: unnecessary use of `get("a").is_some()` - let _ = !s.contains_key("a"); //~ ERROR: unnecessary use of `get("a").is_none()` +let _ = s.contains_key("a"); +//~^ unnecessary_get_then_check +let _ = !s.contains_key("a"); +//~^ unnecessary_get_then_check // Import to check that the generic annotations are kept! let s: HashSet = HashSet::new(); - let _ = s.contains::("a"); //~ ERROR: unnecessary use of `get::("a").is_some()` - let _ = !s.contains::("a"); //~ ERROR: unnecessary use of `get::("a").is_none()` +let _ = s.contains::("a"); +//~^ unnecessary_get_then_check +let _ = !s.contains::("a"); +//~^ unnecessary_get_then_check } diff --git a/tests/ui/unnecessary_get_then_check.rs b/tests/ui/unnecessary_get_then_check.rs index c197bdef47ea..d56e7d209e4e 100644 --- a/tests/ui/unnecessary_get_then_check.rs +++ b/tests/ui/unnecessary_get_then_check.rs @@ -4,23 +4,33 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; fn main() { let s: HashSet = HashSet::new(); - let _ = s.get("a").is_some(); //~ ERROR: unnecessary use of `get("a").is_some()` - let _ = s.get("a").is_none(); //~ ERROR: unnecessary use of `get("a").is_none()` +let _ = s.get("a").is_some(); +//~^ unnecessary_get_then_check +let _ = s.get("a").is_none(); +//~^ unnecessary_get_then_check let s: HashMap = HashMap::new(); - let _ = s.get("a").is_some(); //~ ERROR: unnecessary use of `get("a").is_some()` - let _ = s.get("a").is_none(); //~ ERROR: unnecessary use of `get("a").is_none()` +let _ = s.get("a").is_some(); +//~^ unnecessary_get_then_check +let _ = s.get("a").is_none(); +//~^ unnecessary_get_then_check let s: BTreeSet = BTreeSet::new(); - let _ = s.get("a").is_some(); //~ ERROR: unnecessary use of `get("a").is_some()` - let _ = s.get("a").is_none(); //~ ERROR: unnecessary use of `get("a").is_none()` +let _ = s.get("a").is_some(); +//~^ unnecessary_get_then_check +let _ = s.get("a").is_none(); +//~^ unnecessary_get_then_check let s: BTreeMap = BTreeMap::new(); - let _ = s.get("a").is_some(); //~ ERROR: unnecessary use of `get("a").is_some()` - let _ = s.get("a").is_none(); //~ ERROR: unnecessary use of `get("a").is_none()` +let _ = s.get("a").is_some(); +//~^ unnecessary_get_then_check +let _ = s.get("a").is_none(); +//~^ unnecessary_get_then_check // Import to check that the generic annotations are kept! let s: HashSet = HashSet::new(); - let _ = s.get::("a").is_some(); //~ ERROR: unnecessary use of `get::("a").is_some()` - let _ = s.get::("a").is_none(); //~ ERROR: unnecessary use of `get::("a").is_none()` +let _ = s.get::("a").is_some(); +//~^ unnecessary_get_then_check +let _ = s.get::("a").is_none(); +//~^ unnecessary_get_then_check } diff --git a/tests/ui/unnecessary_get_then_check.stderr b/tests/ui/unnecessary_get_then_check.stderr index 0477c03d16dd..a33409b30c80 100644 --- a/tests/ui/unnecessary_get_then_check.stderr +++ b/tests/ui/unnecessary_get_then_check.stderr @@ -1,75 +1,75 @@ error: unnecessary use of `get("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:7:15 + --> tests/ui/unnecessary_get_then_check.rs:7:11 | -LL | let _ = s.get("a").is_some(); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains("a")` +LL | let _ = s.get("a").is_some(); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains("a")` | = note: `-D clippy::unnecessary-get-then-check` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_get_then_check)]` error: unnecessary use of `get("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:8:15 + --> tests/ui/unnecessary_get_then_check.rs:9:11 | -LL | let _ = s.get("a").is_none(); - | --^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains("a")` +LL | let _ = s.get("a").is_none(); + | --^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains("a")` error: unnecessary use of `get("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:11:15 + --> tests/ui/unnecessary_get_then_check.rs:13:11 | -LL | let _ = s.get("a").is_some(); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("a")` +LL | let _ = s.get("a").is_some(); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("a")` error: unnecessary use of `get("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:12:15 + --> tests/ui/unnecessary_get_then_check.rs:15:11 | -LL | let _ = s.get("a").is_none(); - | --^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains_key("a")` +LL | let _ = s.get("a").is_none(); + | --^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains_key("a")` error: unnecessary use of `get("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:15:15 + --> tests/ui/unnecessary_get_then_check.rs:19:11 | -LL | let _ = s.get("a").is_some(); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains("a")` +LL | let _ = s.get("a").is_some(); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains("a")` error: unnecessary use of `get("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:16:15 + --> tests/ui/unnecessary_get_then_check.rs:21:11 | -LL | let _ = s.get("a").is_none(); - | --^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains("a")` +LL | let _ = s.get("a").is_none(); + | --^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains("a")` error: unnecessary use of `get("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:19:15 + --> tests/ui/unnecessary_get_then_check.rs:25:11 | -LL | let _ = s.get("a").is_some(); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("a")` +LL | let _ = s.get("a").is_some(); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("a")` error: unnecessary use of `get("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:20:15 + --> tests/ui/unnecessary_get_then_check.rs:27:11 | -LL | let _ = s.get("a").is_none(); - | --^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains_key("a")` +LL | let _ = s.get("a").is_none(); + | --^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains_key("a")` error: unnecessary use of `get::("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:24:15 + --> tests/ui/unnecessary_get_then_check.rs:32:11 | -LL | let _ = s.get::("a").is_some(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains::("a")` +LL | let _ = s.get::("a").is_some(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains::("a")` error: unnecessary use of `get::("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:25:15 + --> tests/ui/unnecessary_get_then_check.rs:34:11 | -LL | let _ = s.get::("a").is_none(); - | --^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains::("a")` +LL | let _ = s.get::("a").is_none(); + | --^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains::("a")` error: aborting due to 10 previous errors diff --git a/tests/ui/unnecessary_iter_cloned.fixed b/tests/ui/unnecessary_iter_cloned.fixed index dc5e163ff04e..533059d91fce 100644 --- a/tests/ui/unnecessary_iter_cloned.fixed +++ b/tests/ui/unnecessary_iter_cloned.fixed @@ -29,6 +29,7 @@ fn main() { // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { for (t, path) in files { + //~^ unnecessary_to_owned let other = match get_file_path(t) { Ok(p) => p, Err(_) => { @@ -44,6 +45,7 @@ fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { fn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool { for (t, path) in files.iter() { + //~^ unnecessary_to_owned let other = match get_file_path(t) { Ok(p) => p, Err(_) => { @@ -175,7 +177,8 @@ mod issue_12821 { fn foo() { let v: Vec<_> = "hello".chars().collect(); for c in v.iter() { - //~^ ERROR: unnecessary use of `cloned` + //~^ unnecessary_to_owned + println!("{c}"); // should not suggest to remove `&` } } @@ -183,8 +186,9 @@ mod issue_12821 { fn bar() { let v: Vec<_> = "hello".chars().collect(); for c in v.iter() { - //~^ ERROR: unnecessary use of `cloned` - let ref_c = c; //~ HELP: remove any references to the binding + //~^ unnecessary_to_owned + +let ref_c = c; println!("{ref_c}"); } } @@ -192,8 +196,9 @@ mod issue_12821 { fn baz() { let v: Vec<_> = "hello".chars().enumerate().collect(); for (i, c) in v.iter() { - //~^ ERROR: unnecessary use of `cloned` - let ref_c = c; //~ HELP: remove any references to the binding + //~^ unnecessary_to_owned + +let ref_c = c; let ref_i = i; println!("{i} {ref_c}"); // should not suggest to remove `&` from `i` } diff --git a/tests/ui/unnecessary_iter_cloned.rs b/tests/ui/unnecessary_iter_cloned.rs index 8f797ac717fb..5e0c2e6d78ec 100644 --- a/tests/ui/unnecessary_iter_cloned.rs +++ b/tests/ui/unnecessary_iter_cloned.rs @@ -29,6 +29,7 @@ fn main() { // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { for (t, path) in files.iter().copied() { + //~^ unnecessary_to_owned let other = match get_file_path(&t) { Ok(p) => p, Err(_) => { @@ -44,6 +45,7 @@ fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { fn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool { for (t, path) in files.iter().copied() { + //~^ unnecessary_to_owned let other = match get_file_path(&t) { Ok(p) => p, Err(_) => { @@ -175,7 +177,8 @@ mod issue_12821 { fn foo() { let v: Vec<_> = "hello".chars().collect(); for c in v.iter().cloned() { - //~^ ERROR: unnecessary use of `cloned` + //~^ unnecessary_to_owned + println!("{c}"); // should not suggest to remove `&` } } @@ -183,8 +186,9 @@ mod issue_12821 { fn bar() { let v: Vec<_> = "hello".chars().collect(); for c in v.iter().cloned() { - //~^ ERROR: unnecessary use of `cloned` - let ref_c = &c; //~ HELP: remove any references to the binding + //~^ unnecessary_to_owned + +let ref_c = &c; println!("{ref_c}"); } } @@ -192,8 +196,9 @@ mod issue_12821 { fn baz() { let v: Vec<_> = "hello".chars().enumerate().collect(); for (i, c) in v.iter().cloned() { - //~^ ERROR: unnecessary use of `cloned` - let ref_c = &c; //~ HELP: remove any references to the binding + //~^ unnecessary_to_owned + +let ref_c = &c; let ref_i = &i; println!("{i} {ref_c}"); // should not suggest to remove `&` from `i` } diff --git a/tests/ui/unnecessary_iter_cloned.stderr b/tests/ui/unnecessary_iter_cloned.stderr index 6f2ae0ab1f35..61ae9acc35cc 100644 --- a/tests/ui/unnecessary_iter_cloned.stderr +++ b/tests/ui/unnecessary_iter_cloned.stderr @@ -9,11 +9,12 @@ LL | for (t, path) in files.iter().copied() { help: remove any references to the binding | LL ~ for (t, path) in files { +LL | LL ~ let other = match get_file_path(t) { | error: unnecessary use of `copied` - --> tests/ui/unnecessary_iter_cloned.rs:46:22 + --> tests/ui/unnecessary_iter_cloned.rs:47:22 | LL | for (t, path) in files.iter().copied() { | ^^^^^^^^^^^^^^^^^^^^^ @@ -21,17 +22,18 @@ LL | for (t, path) in files.iter().copied() { help: remove any references to the binding | LL ~ for (t, path) in files.iter() { +LL | LL ~ let other = match get_file_path(t) { | error: unnecessary use of `cloned` - --> tests/ui/unnecessary_iter_cloned.rs:177:18 + --> tests/ui/unnecessary_iter_cloned.rs:179:18 | LL | for c in v.iter().cloned() { | ^^^^^^^^^^^^^^^^^ help: remove any references to the binding: `v.iter()` error: unnecessary use of `cloned` - --> tests/ui/unnecessary_iter_cloned.rs:185:18 + --> tests/ui/unnecessary_iter_cloned.rs:188:18 | LL | for c in v.iter().cloned() { | ^^^^^^^^^^^^^^^^^ @@ -40,11 +42,12 @@ help: remove any references to the binding | LL ~ for c in v.iter() { LL | -LL ~ let ref_c = c; +LL | +LL ~ let ref_c = c; | error: unnecessary use of `cloned` - --> tests/ui/unnecessary_iter_cloned.rs:194:23 + --> tests/ui/unnecessary_iter_cloned.rs:198:23 | LL | for (i, c) in v.iter().cloned() { | ^^^^^^^^^^^^^^^^^ @@ -53,7 +56,8 @@ help: remove any references to the binding | LL ~ for (i, c) in v.iter() { LL | -LL ~ let ref_c = c; +LL | +LL ~ let ref_c = c; LL ~ let ref_i = i; | diff --git a/tests/ui/unnecessary_join.rs b/tests/ui/unnecessary_join.rs index d042d9e5c212..e58b2696645a 100644 --- a/tests/ui/unnecessary_join.rs +++ b/tests/ui/unnecessary_join.rs @@ -8,6 +8,7 @@ fn main() { .iter() .map(|item| item.to_uppercase()) .collect::>() + //~^ unnecessary_join .join(""); println!("{}", output); @@ -17,6 +18,7 @@ fn main() { .iter() .map(|item| item.to_uppercase()) .collect::>() + //~^ unnecessary_join .join(""); println!("{}", output); diff --git a/tests/ui/unnecessary_join.stderr b/tests/ui/unnecessary_join.stderr index a06a1059033b..a7677fe2f9eb 100644 --- a/tests/ui/unnecessary_join.stderr +++ b/tests/ui/unnecessary_join.stderr @@ -3,6 +3,7 @@ error: called `.collect::>().join("")` on an iterator | LL | .collect::>() | __________^ +LL | | LL | | .join(""); | |_________________^ help: consider using: `collect::()` | @@ -10,10 +11,11 @@ LL | | .join(""); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_join)]` error: called `.collect::>().join("")` on an iterator - --> tests/ui/unnecessary_join.rs:19:10 + --> tests/ui/unnecessary_join.rs:20:10 | LL | .collect::>() | __________^ +LL | | LL | | .join(""); | |_________________^ help: consider using: `collect::()` diff --git a/tests/ui/unnecessary_lazy_eval.fixed b/tests/ui/unnecessary_lazy_eval.fixed index d8031c484e5e..9a3290816389 100644 --- a/tests/ui/unnecessary_lazy_eval.fixed +++ b/tests/ui/unnecessary_lazy_eval.fixed @@ -81,42 +81,69 @@ fn main() { // Should lint - Option let _ = opt.unwrap_or(2); + //~^ unnecessary_lazy_evaluations let _ = opt.unwrap_or(astronomers_pi); + //~^ unnecessary_lazy_evaluations let _ = opt.unwrap_or(ext_str.some_field); + //~^ unnecessary_lazy_evaluations let _ = opt.unwrap_or_else(|| ext_arr[0]); let _ = opt.and(ext_opt); + //~^ unnecessary_lazy_evaluations let _ = opt.or(ext_opt); + //~^ unnecessary_lazy_evaluations let _ = opt.or(None); + //~^ unnecessary_lazy_evaluations let _ = opt.get_or_insert(2); + //~^ unnecessary_lazy_evaluations let _ = opt.ok_or(2); + //~^ unnecessary_lazy_evaluations let _ = nested_tuple_opt.unwrap_or(Some((1, 2))); + //~^ unnecessary_lazy_evaluations let _ = cond.then_some(astronomers_pi); + //~^ unnecessary_lazy_evaluations let _ = true.then_some({}); + //~^ unnecessary_lazy_evaluations let _ = true.then_some({}); + //~^ unnecessary_lazy_evaluations // Should lint - Builtin deref let r = &1; let _ = Some(1).unwrap_or(*r); + //~^ unnecessary_lazy_evaluations let b = Box::new(1); let _ = Some(1).unwrap_or(*b); + //~^ unnecessary_lazy_evaluations // Should lint - Builtin deref through autoderef let _ = Some(1).as_ref().unwrap_or(&r); + //~^ unnecessary_lazy_evaluations let _ = Some(1).as_ref().unwrap_or(&b); + //~^ unnecessary_lazy_evaluations // Cases when unwrap is not called on a simple variable let _ = Some(10).unwrap_or(2); + //~^ unnecessary_lazy_evaluations let _ = Some(10).and(ext_opt); + //~^ unnecessary_lazy_evaluations let _: Option = None.or(ext_opt); + //~^ unnecessary_lazy_evaluations let _ = None.get_or_insert(2); + //~^ unnecessary_lazy_evaluations let _: Result = None.ok_or(2); + //~^ unnecessary_lazy_evaluations let _: Option = None.or(None); + //~^ unnecessary_lazy_evaluations let mut deep = Deep(Some(42)); let _ = deep.0.unwrap_or(2); + //~^ unnecessary_lazy_evaluations let _ = deep.0.and(ext_opt); + //~^ unnecessary_lazy_evaluations let _ = deep.0.or(None); + //~^ unnecessary_lazy_evaluations let _ = deep.0.get_or_insert(2); + //~^ unnecessary_lazy_evaluations let _ = deep.0.ok_or(2); + //~^ unnecessary_lazy_evaluations // Should not lint - Option let _ = opt.unwrap_or_else(|| ext_str.return_some_field()); @@ -148,16 +175,22 @@ fn main() { // should lint, bind_instead_of_map doesn't apply let _: Option = None.or(Some(3)); + //~^ unnecessary_lazy_evaluations let _ = deep.0.or(Some(3)); + //~^ unnecessary_lazy_evaluations let _ = opt.or(Some(3)); + //~^ unnecessary_lazy_evaluations // Should lint - Result let res: Result = Err(5); let res2: Result = Err(SomeStruct { some_field: 5 }); let _ = res2.unwrap_or(2); + //~^ unnecessary_lazy_evaluations let _ = res2.unwrap_or(astronomers_pi); + //~^ unnecessary_lazy_evaluations let _ = res2.unwrap_or(ext_str.some_field); + //~^ unnecessary_lazy_evaluations // Should not lint - Result let _ = res.unwrap_or_else(|err| err); @@ -180,13 +213,20 @@ fn main() { // should lint, bind_instead_of_map doesn't apply let _: Result = res.and(Err(2)); + //~^ unnecessary_lazy_evaluations let _: Result = res.and(Err(astronomers_pi)); + //~^ unnecessary_lazy_evaluations let _: Result = res.and(Err(ext_str.some_field)); + //~^ unnecessary_lazy_evaluations let _: Result = res.or(Ok(2)); + //~^ unnecessary_lazy_evaluations let _: Result = res.or(Ok(astronomers_pi)); + //~^ unnecessary_lazy_evaluations let _: Result = res.or(Ok(ext_str.some_field)); + //~^ unnecessary_lazy_evaluations let _: Result = res. + //~^ unnecessary_lazy_evaluations // some lines // some lines // some lines @@ -217,39 +257,39 @@ fn panicky_arithmetic_ops(x: usize, y: isize) { // See comments in `eager_or_lazy.rs` for the rules that this is meant to follow let _x = false.then_some(i32::MAX + 1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(i32::MAX * 2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(i32::MAX - 1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(i32::MIN - 1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(255u8 << 7); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(255u8 << 8); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(255u8 >> 8); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 255u8 >> x); let _x = false.then_some(i32::MAX + -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(-i32::MAX); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(-i32::MIN); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| -y); let _x = false.then_some(255 >> -7); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(255 << -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(1 / 0); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(x << -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(x << 2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| x + x); let _x = false.then(|| x * x); let _x = false.then(|| x - x); @@ -259,19 +299,19 @@ fn panicky_arithmetic_ops(x: usize, y: isize) { let _x = false.then(|| 1 + x); let _x = false.then_some(x / 0); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(x % 0); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| y / -1); let _x = false.then_some(1 / -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(i32::MIN / -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| i32::MIN / x as i32); let _x = false.then_some(i32::MIN / 0); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then_some(4 / 2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 1 / x); // const eval doesn't read variables, but floating point math never panics, so we can still emit a @@ -279,5 +319,5 @@ fn panicky_arithmetic_ops(x: usize, y: isize) { let f1 = 1.0; let f2 = 2.0; let _x = false.then_some(f1 + f2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations } diff --git a/tests/ui/unnecessary_lazy_eval.rs b/tests/ui/unnecessary_lazy_eval.rs index ea55b1d9a905..2d05ef5c2917 100644 --- a/tests/ui/unnecessary_lazy_eval.rs +++ b/tests/ui/unnecessary_lazy_eval.rs @@ -81,42 +81,69 @@ fn main() { // Should lint - Option let _ = opt.unwrap_or_else(|| 2); + //~^ unnecessary_lazy_evaluations let _ = opt.unwrap_or_else(|| astronomers_pi); + //~^ unnecessary_lazy_evaluations let _ = opt.unwrap_or_else(|| ext_str.some_field); + //~^ unnecessary_lazy_evaluations let _ = opt.unwrap_or_else(|| ext_arr[0]); let _ = opt.and_then(|_| ext_opt); + //~^ unnecessary_lazy_evaluations let _ = opt.or_else(|| ext_opt); + //~^ unnecessary_lazy_evaluations let _ = opt.or_else(|| None); + //~^ unnecessary_lazy_evaluations let _ = opt.get_or_insert_with(|| 2); + //~^ unnecessary_lazy_evaluations let _ = opt.ok_or_else(|| 2); + //~^ unnecessary_lazy_evaluations let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); + //~^ unnecessary_lazy_evaluations let _ = cond.then(|| astronomers_pi); + //~^ unnecessary_lazy_evaluations let _ = true.then(|| -> _ {}); + //~^ unnecessary_lazy_evaluations let _ = true.then(|| {}); + //~^ unnecessary_lazy_evaluations // Should lint - Builtin deref let r = &1; let _ = Some(1).unwrap_or_else(|| *r); + //~^ unnecessary_lazy_evaluations let b = Box::new(1); let _ = Some(1).unwrap_or_else(|| *b); + //~^ unnecessary_lazy_evaluations // Should lint - Builtin deref through autoderef let _ = Some(1).as_ref().unwrap_or_else(|| &r); + //~^ unnecessary_lazy_evaluations let _ = Some(1).as_ref().unwrap_or_else(|| &b); + //~^ unnecessary_lazy_evaluations // Cases when unwrap is not called on a simple variable let _ = Some(10).unwrap_or_else(|| 2); + //~^ unnecessary_lazy_evaluations let _ = Some(10).and_then(|_| ext_opt); + //~^ unnecessary_lazy_evaluations let _: Option = None.or_else(|| ext_opt); + //~^ unnecessary_lazy_evaluations let _ = None.get_or_insert_with(|| 2); + //~^ unnecessary_lazy_evaluations let _: Result = None.ok_or_else(|| 2); + //~^ unnecessary_lazy_evaluations let _: Option = None.or_else(|| None); + //~^ unnecessary_lazy_evaluations let mut deep = Deep(Some(42)); let _ = deep.0.unwrap_or_else(|| 2); + //~^ unnecessary_lazy_evaluations let _ = deep.0.and_then(|_| ext_opt); + //~^ unnecessary_lazy_evaluations let _ = deep.0.or_else(|| None); + //~^ unnecessary_lazy_evaluations let _ = deep.0.get_or_insert_with(|| 2); + //~^ unnecessary_lazy_evaluations let _ = deep.0.ok_or_else(|| 2); + //~^ unnecessary_lazy_evaluations // Should not lint - Option let _ = opt.unwrap_or_else(|| ext_str.return_some_field()); @@ -148,16 +175,22 @@ fn main() { // should lint, bind_instead_of_map doesn't apply let _: Option = None.or_else(|| Some(3)); + //~^ unnecessary_lazy_evaluations let _ = deep.0.or_else(|| Some(3)); + //~^ unnecessary_lazy_evaluations let _ = opt.or_else(|| Some(3)); + //~^ unnecessary_lazy_evaluations // Should lint - Result let res: Result = Err(5); let res2: Result = Err(SomeStruct { some_field: 5 }); let _ = res2.unwrap_or_else(|_| 2); + //~^ unnecessary_lazy_evaluations let _ = res2.unwrap_or_else(|_| astronomers_pi); + //~^ unnecessary_lazy_evaluations let _ = res2.unwrap_or_else(|_| ext_str.some_field); + //~^ unnecessary_lazy_evaluations // Should not lint - Result let _ = res.unwrap_or_else(|err| err); @@ -180,13 +213,20 @@ fn main() { // should lint, bind_instead_of_map doesn't apply let _: Result = res.and_then(|_| Err(2)); + //~^ unnecessary_lazy_evaluations let _: Result = res.and_then(|_| Err(astronomers_pi)); + //~^ unnecessary_lazy_evaluations let _: Result = res.and_then(|_| Err(ext_str.some_field)); + //~^ unnecessary_lazy_evaluations let _: Result = res.or_else(|_| Ok(2)); + //~^ unnecessary_lazy_evaluations let _: Result = res.or_else(|_| Ok(astronomers_pi)); + //~^ unnecessary_lazy_evaluations let _: Result = res.or_else(|_| Ok(ext_str.some_field)); + //~^ unnecessary_lazy_evaluations let _: Result = res. + //~^ unnecessary_lazy_evaluations // some lines // some lines // some lines @@ -217,39 +257,39 @@ fn panicky_arithmetic_ops(x: usize, y: isize) { // See comments in `eager_or_lazy.rs` for the rules that this is meant to follow let _x = false.then(|| i32::MAX + 1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| i32::MAX * 2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| i32::MAX - 1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| i32::MIN - 1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 255u8 << 7); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 255u8 << 8); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 255u8 >> 8); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 255u8 >> x); let _x = false.then(|| i32::MAX + -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| -i32::MAX); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| -i32::MIN); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| -y); let _x = false.then(|| 255 >> -7); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 255 << -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 1 / 0); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| x << -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| x << 2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| x + x); let _x = false.then(|| x * x); let _x = false.then(|| x - x); @@ -259,19 +299,19 @@ fn panicky_arithmetic_ops(x: usize, y: isize) { let _x = false.then(|| 1 + x); let _x = false.then(|| x / 0); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| x % 0); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| y / -1); let _x = false.then(|| 1 / -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| i32::MIN / -1); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| i32::MIN / x as i32); let _x = false.then(|| i32::MIN / 0); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 4 / 2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations let _x = false.then(|| 1 / x); // const eval doesn't read variables, but floating point math never panics, so we can still emit a @@ -279,5 +319,5 @@ fn panicky_arithmetic_ops(x: usize, y: isize) { let f1 = 1.0; let f2 = 2.0; let _x = false.then(|| f1 + f2); - //~^ ERROR: unnecessary closure used with `bool::then` + //~^ unnecessary_lazy_evaluations } diff --git a/tests/ui/unnecessary_lazy_eval.stderr b/tests/ui/unnecessary_lazy_eval.stderr index 35a2144c389f..d1bb08cceadf 100644 --- a/tests/ui/unnecessary_lazy_eval.stderr +++ b/tests/ui/unnecessary_lazy_eval.stderr @@ -12,7 +12,7 @@ LL | let _ = opt.unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:84:13 + --> tests/ui/unnecessary_lazy_eval.rs:85:13 | LL | let _ = opt.unwrap_or_else(|| astronomers_pi); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = opt.unwrap_or(astronomers_pi); | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:85:13 + --> tests/ui/unnecessary_lazy_eval.rs:87:13 | LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = opt.unwrap_or(ext_str.some_field); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:87:13 + --> tests/ui/unnecessary_lazy_eval.rs:90:13 | LL | let _ = opt.and_then(|_| ext_opt); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _ = opt.and(ext_opt); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:88:13 + --> tests/ui/unnecessary_lazy_eval.rs:92:13 | LL | let _ = opt.or_else(|| ext_opt); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _ = opt.or(ext_opt); | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:89:13 + --> tests/ui/unnecessary_lazy_eval.rs:94:13 | LL | let _ = opt.or_else(|| None); | ^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let _ = opt.or(None); | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:90:13 + --> tests/ui/unnecessary_lazy_eval.rs:96:13 | LL | let _ = opt.get_or_insert_with(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _ = opt.get_or_insert(2); | ~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:91:13 + --> tests/ui/unnecessary_lazy_eval.rs:98:13 | LL | let _ = opt.ok_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = opt.ok_or(2); | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:92:13 + --> tests/ui/unnecessary_lazy_eval.rs:100:13 | LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let _ = nested_tuple_opt.unwrap_or(Some((1, 2))); | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:93:13 + --> tests/ui/unnecessary_lazy_eval.rs:102:13 | LL | let _ = cond.then(|| astronomers_pi); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _ = cond.then_some(astronomers_pi); | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:94:13 + --> tests/ui/unnecessary_lazy_eval.rs:104:13 | LL | let _ = true.then(|| -> _ {}); | ^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let _ = true.then_some({}); | ~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:95:13 + --> tests/ui/unnecessary_lazy_eval.rs:106:13 | LL | let _ = true.then(|| {}); | ^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let _ = true.then_some({}); | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:99:13 + --> tests/ui/unnecessary_lazy_eval.rs:111:13 | LL | let _ = Some(1).unwrap_or_else(|| *r); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | let _ = Some(1).unwrap_or(*r); | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:101:13 + --> tests/ui/unnecessary_lazy_eval.rs:114:13 | LL | let _ = Some(1).unwrap_or_else(|| *b); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | let _ = Some(1).unwrap_or(*b); | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:103:13 + --> tests/ui/unnecessary_lazy_eval.rs:117:13 | LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | let _ = Some(1).as_ref().unwrap_or(&r); | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:104:13 + --> tests/ui/unnecessary_lazy_eval.rs:119:13 | LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | let _ = Some(1).as_ref().unwrap_or(&b); | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:107:13 + --> tests/ui/unnecessary_lazy_eval.rs:123:13 | LL | let _ = Some(10).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -188,7 +188,7 @@ LL | let _ = Some(10).unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:108:13 + --> tests/ui/unnecessary_lazy_eval.rs:125:13 | LL | let _ = Some(10).and_then(|_| ext_opt); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | let _ = Some(10).and(ext_opt); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:109:28 + --> tests/ui/unnecessary_lazy_eval.rs:127:28 | LL | let _: Option = None.or_else(|| ext_opt); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,7 +210,7 @@ LL | let _: Option = None.or(ext_opt); | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:110:13 + --> tests/ui/unnecessary_lazy_eval.rs:129:13 | LL | let _ = None.get_or_insert_with(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +221,7 @@ LL | let _ = None.get_or_insert(2); | ~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:111:35 + --> tests/ui/unnecessary_lazy_eval.rs:131:35 | LL | let _: Result = None.ok_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^ @@ -232,7 +232,7 @@ LL | let _: Result = None.ok_or(2); | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:112:28 + --> tests/ui/unnecessary_lazy_eval.rs:133:28 | LL | let _: Option = None.or_else(|| None); | ^^^^^^^^^^^^^^^^^^^^^ @@ -243,7 +243,7 @@ LL | let _: Option = None.or(None); | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:115:13 + --> tests/ui/unnecessary_lazy_eval.rs:137:13 | LL | let _ = deep.0.unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -254,7 +254,7 @@ LL | let _ = deep.0.unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:116:13 + --> tests/ui/unnecessary_lazy_eval.rs:139:13 | LL | let _ = deep.0.and_then(|_| ext_opt); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -265,7 +265,7 @@ LL | let _ = deep.0.and(ext_opt); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:117:13 + --> tests/ui/unnecessary_lazy_eval.rs:141:13 | LL | let _ = deep.0.or_else(|| None); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -276,7 +276,7 @@ LL | let _ = deep.0.or(None); | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:118:13 + --> tests/ui/unnecessary_lazy_eval.rs:143:13 | LL | let _ = deep.0.get_or_insert_with(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -287,7 +287,7 @@ LL | let _ = deep.0.get_or_insert(2); | ~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:119:13 + --> tests/ui/unnecessary_lazy_eval.rs:145:13 | LL | let _ = deep.0.ok_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -298,7 +298,7 @@ LL | let _ = deep.0.ok_or(2); | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:150:28 + --> tests/ui/unnecessary_lazy_eval.rs:177:28 | LL | let _: Option = None.or_else(|| Some(3)); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -309,7 +309,7 @@ LL | let _: Option = None.or(Some(3)); | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:151:13 + --> tests/ui/unnecessary_lazy_eval.rs:179:13 | LL | let _ = deep.0.or_else(|| Some(3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -320,7 +320,7 @@ LL | let _ = deep.0.or(Some(3)); | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` - --> tests/ui/unnecessary_lazy_eval.rs:152:13 + --> tests/ui/unnecessary_lazy_eval.rs:181:13 | LL | let _ = opt.or_else(|| Some(3)); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -331,7 +331,7 @@ LL | let _ = opt.or(Some(3)); | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:158:13 + --> tests/ui/unnecessary_lazy_eval.rs:188:13 | LL | let _ = res2.unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -342,7 +342,7 @@ LL | let _ = res2.unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:159:13 + --> tests/ui/unnecessary_lazy_eval.rs:190:13 | LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -353,7 +353,7 @@ LL | let _ = res2.unwrap_or(astronomers_pi); | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:160:13 + --> tests/ui/unnecessary_lazy_eval.rs:192:13 | LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -364,7 +364,7 @@ LL | let _ = res2.unwrap_or(ext_str.some_field); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:182:35 + --> tests/ui/unnecessary_lazy_eval.rs:215:35 | LL | let _: Result = res.and_then(|_| Err(2)); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -375,7 +375,7 @@ LL | let _: Result = res.and(Err(2)); | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:183:35 + --> tests/ui/unnecessary_lazy_eval.rs:217:35 | LL | let _: Result = res.and_then(|_| Err(astronomers_pi)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -386,7 +386,7 @@ LL | let _: Result = res.and(Err(astronomers_pi)); | ~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:184:35 + --> tests/ui/unnecessary_lazy_eval.rs:219:35 | LL | let _: Result = res.and_then(|_| Err(ext_str.some_field)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -397,7 +397,7 @@ LL | let _: Result = res.and(Err(ext_str.some_field)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:186:35 + --> tests/ui/unnecessary_lazy_eval.rs:222:35 | LL | let _: Result = res.or_else(|_| Ok(2)); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -408,7 +408,7 @@ LL | let _: Result = res.or(Ok(2)); | ~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:187:35 + --> tests/ui/unnecessary_lazy_eval.rs:224:35 | LL | let _: Result = res.or_else(|_| Ok(astronomers_pi)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -419,7 +419,7 @@ LL | let _: Result = res.or(Ok(astronomers_pi)); | ~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:188:35 + --> tests/ui/unnecessary_lazy_eval.rs:226:35 | LL | let _: Result = res.or_else(|_| Ok(ext_str.some_field)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -430,7 +430,7 @@ LL | let _: Result = res.or(Ok(ext_str.some_field)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval.rs:189:35 + --> tests/ui/unnecessary_lazy_eval.rs:228:35 | LL | let _: Result = res. | ___________________________________^ @@ -444,7 +444,7 @@ LL | or(Ok(ext_str.some_field)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:219:14 + --> tests/ui/unnecessary_lazy_eval.rs:259:14 | LL | let _x = false.then(|| i32::MAX + 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -455,7 +455,7 @@ LL | let _x = false.then_some(i32::MAX + 1); | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:221:14 + --> tests/ui/unnecessary_lazy_eval.rs:261:14 | LL | let _x = false.then(|| i32::MAX * 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -466,7 +466,7 @@ LL | let _x = false.then_some(i32::MAX * 2); | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:223:14 + --> tests/ui/unnecessary_lazy_eval.rs:263:14 | LL | let _x = false.then(|| i32::MAX - 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -477,7 +477,7 @@ LL | let _x = false.then_some(i32::MAX - 1); | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:225:14 + --> tests/ui/unnecessary_lazy_eval.rs:265:14 | LL | let _x = false.then(|| i32::MIN - 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -488,7 +488,7 @@ LL | let _x = false.then_some(i32::MIN - 1); | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:227:14 + --> tests/ui/unnecessary_lazy_eval.rs:267:14 | LL | let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -499,7 +499,7 @@ LL | let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:229:14 + --> tests/ui/unnecessary_lazy_eval.rs:269:14 | LL | let _x = false.then(|| 255u8 << 7); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -510,7 +510,7 @@ LL | let _x = false.then_some(255u8 << 7); | ~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:231:14 + --> tests/ui/unnecessary_lazy_eval.rs:271:14 | LL | let _x = false.then(|| 255u8 << 8); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -521,7 +521,7 @@ LL | let _x = false.then_some(255u8 << 8); | ~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:233:14 + --> tests/ui/unnecessary_lazy_eval.rs:273:14 | LL | let _x = false.then(|| 255u8 >> 8); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -532,7 +532,7 @@ LL | let _x = false.then_some(255u8 >> 8); | ~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:236:14 + --> tests/ui/unnecessary_lazy_eval.rs:276:14 | LL | let _x = false.then(|| i32::MAX + -1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -543,7 +543,7 @@ LL | let _x = false.then_some(i32::MAX + -1); | ~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:238:14 + --> tests/ui/unnecessary_lazy_eval.rs:278:14 | LL | let _x = false.then(|| -i32::MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -554,7 +554,7 @@ LL | let _x = false.then_some(-i32::MAX); | ~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:240:14 + --> tests/ui/unnecessary_lazy_eval.rs:280:14 | LL | let _x = false.then(|| -i32::MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -565,7 +565,7 @@ LL | let _x = false.then_some(-i32::MIN); | ~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:243:14 + --> tests/ui/unnecessary_lazy_eval.rs:283:14 | LL | let _x = false.then(|| 255 >> -7); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -576,7 +576,7 @@ LL | let _x = false.then_some(255 >> -7); | ~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:245:14 + --> tests/ui/unnecessary_lazy_eval.rs:285:14 | LL | let _x = false.then(|| 255 << -1); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -587,7 +587,7 @@ LL | let _x = false.then_some(255 << -1); | ~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:247:14 + --> tests/ui/unnecessary_lazy_eval.rs:287:14 | LL | let _x = false.then(|| 1 / 0); | ^^^^^^^^^^^^^^^^^^^^ @@ -598,7 +598,7 @@ LL | let _x = false.then_some(1 / 0); | ~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:249:14 + --> tests/ui/unnecessary_lazy_eval.rs:289:14 | LL | let _x = false.then(|| x << -1); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -609,7 +609,7 @@ LL | let _x = false.then_some(x << -1); | ~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:251:14 + --> tests/ui/unnecessary_lazy_eval.rs:291:14 | LL | let _x = false.then(|| x << 2); | ^^^^^^^^^^^^^^^^^^^^^ @@ -620,7 +620,7 @@ LL | let _x = false.then_some(x << 2); | ~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:261:14 + --> tests/ui/unnecessary_lazy_eval.rs:301:14 | LL | let _x = false.then(|| x / 0); | ^^^^^^^^^^^^^^^^^^^^ @@ -631,7 +631,7 @@ LL | let _x = false.then_some(x / 0); | ~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:263:14 + --> tests/ui/unnecessary_lazy_eval.rs:303:14 | LL | let _x = false.then(|| x % 0); | ^^^^^^^^^^^^^^^^^^^^ @@ -642,7 +642,7 @@ LL | let _x = false.then_some(x % 0); | ~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:266:14 + --> tests/ui/unnecessary_lazy_eval.rs:306:14 | LL | let _x = false.then(|| 1 / -1); | ^^^^^^^^^^^^^^^^^^^^^ @@ -653,7 +653,7 @@ LL | let _x = false.then_some(1 / -1); | ~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:268:14 + --> tests/ui/unnecessary_lazy_eval.rs:308:14 | LL | let _x = false.then(|| i32::MIN / -1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -664,7 +664,7 @@ LL | let _x = false.then_some(i32::MIN / -1); | ~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:271:14 + --> tests/ui/unnecessary_lazy_eval.rs:311:14 | LL | let _x = false.then(|| i32::MIN / 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -675,7 +675,7 @@ LL | let _x = false.then_some(i32::MIN / 0); | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:273:14 + --> tests/ui/unnecessary_lazy_eval.rs:313:14 | LL | let _x = false.then(|| 4 / 2); | ^^^^^^^^^^^^^^^^^^^^ @@ -686,7 +686,7 @@ LL | let _x = false.then_some(4 / 2); | ~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval.rs:281:14 + --> tests/ui/unnecessary_lazy_eval.rs:321:14 | LL | let _x = false.then(|| f1 + f2); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_lazy_eval_unfixable.rs b/tests/ui/unnecessary_lazy_eval_unfixable.rs index 412d4aaafb4a..54a2d4cee36f 100644 --- a/tests/ui/unnecessary_lazy_eval_unfixable.rs +++ b/tests/ui/unnecessary_lazy_eval_unfixable.rs @@ -11,15 +11,18 @@ struct SomeStruct { fn main() { // fix will break type inference let _ = Ok(1).unwrap_or_else(|()| 2); - //~^ ERROR: unnecessary closure used to substitute value for `Result::Err` - //~| NOTE: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings` + //~^ unnecessary_lazy_evaluations + + mod e { pub struct E; } let _ = Ok(1).unwrap_or_else(|e::E| 2); - //~^ ERROR: unnecessary closure used to substitute value for `Result::Err` + //~^ unnecessary_lazy_evaluations + let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); - //~^ ERROR: unnecessary closure used to substitute value for `Result::Err` + //~^ unnecessary_lazy_evaluations + // Fix #6343 let arr = [(Some(1),)]; @@ -29,4 +32,5 @@ fn main() { fn issue11672() { // Return type annotation helps type inference and removing it can break code let _ = true.then(|| -> &[u8] { &[] }); + //~^ unnecessary_lazy_evaluations } diff --git a/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/tests/ui/unnecessary_lazy_eval_unfixable.stderr index 390235b21247..11eecdf6fa4a 100644 --- a/tests/ui/unnecessary_lazy_eval_unfixable.stderr +++ b/tests/ui/unnecessary_lazy_eval_unfixable.stderr @@ -12,7 +12,7 @@ LL | let _ = Ok(1).unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval_unfixable.rs:19:13 + --> tests/ui/unnecessary_lazy_eval_unfixable.rs:20:13 | LL | let _ = Ok(1).unwrap_or_else(|e::E| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = Ok(1).unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval_unfixable.rs:21:13 + --> tests/ui/unnecessary_lazy_eval_unfixable.rs:23:13 | LL | let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = Ok(1).unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval_unfixable.rs:31:13 + --> tests/ui/unnecessary_lazy_eval_unfixable.rs:34:13 | LL | let _ = true.then(|| -> &[u8] { &[] }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_literal_bound.fixed b/tests/ui/unnecessary_literal_bound.fixed index 107e397466d0..5ac38a5b76ae 100644 --- a/tests/ui/unnecessary_literal_bound.fixed +++ b/tests/ui/unnecessary_literal_bound.fixed @@ -7,6 +7,7 @@ struct Struct<'a> { impl Struct<'_> { // Should warn fn returns_lit(&self) -> &'static str { + //~^ unnecessary_literal_bound "Hello" } @@ -27,6 +28,7 @@ impl Struct<'_> { // Should warn fn contionally_returns_literals_explicit(&self, cond: bool) -> &'static str { + //~^ unnecessary_literal_bound if cond { return "Literal"; } @@ -51,6 +53,7 @@ trait ReturnsStr { impl ReturnsStr for u8 { // Should warn, even though not useful without trait refinement fn trait_method(&self) -> &'static str { + //~^ unnecessary_literal_bound "Literal" } } diff --git a/tests/ui/unnecessary_literal_bound.rs b/tests/ui/unnecessary_literal_bound.rs index b371ff9d3a2e..487ca04c6ab3 100644 --- a/tests/ui/unnecessary_literal_bound.rs +++ b/tests/ui/unnecessary_literal_bound.rs @@ -7,6 +7,7 @@ struct Struct<'a> { impl Struct<'_> { // Should warn fn returns_lit(&self) -> &str { + //~^ unnecessary_literal_bound "Hello" } @@ -27,6 +28,7 @@ impl Struct<'_> { // Should warn fn contionally_returns_literals_explicit(&self, cond: bool) -> &str { + //~^ unnecessary_literal_bound if cond { return "Literal"; } @@ -51,6 +53,7 @@ trait ReturnsStr { impl ReturnsStr for u8 { // Should warn, even though not useful without trait refinement fn trait_method(&self) -> &str { + //~^ unnecessary_literal_bound "Literal" } } diff --git a/tests/ui/unnecessary_literal_bound.stderr b/tests/ui/unnecessary_literal_bound.stderr index 512b2f9a0afa..e510d86622d6 100644 --- a/tests/ui/unnecessary_literal_bound.stderr +++ b/tests/ui/unnecessary_literal_bound.stderr @@ -8,13 +8,13 @@ LL | fn returns_lit(&self) -> &str { = help: to override `-D warnings` add `#[allow(clippy::unnecessary_literal_bound)]` error: returning a `str` unnecessarily tied to the lifetime of arguments - --> tests/ui/unnecessary_literal_bound.rs:29:68 + --> tests/ui/unnecessary_literal_bound.rs:30:68 | LL | fn contionally_returns_literals_explicit(&self, cond: bool) -> &str { | ^^^^ help: try: `&'static str` error: returning a `str` unnecessarily tied to the lifetime of arguments - --> tests/ui/unnecessary_literal_bound.rs:53:31 + --> tests/ui/unnecessary_literal_bound.rs:55:31 | LL | fn trait_method(&self) -> &str { | ^^^^ help: try: `&'static str` diff --git a/tests/ui/unnecessary_literal_unwrap.fixed b/tests/ui/unnecessary_literal_unwrap.fixed index b17343aa9ba5..e999dc3ade7f 100644 --- a/tests/ui/unnecessary_literal_unwrap.fixed +++ b/tests/ui/unnecessary_literal_unwrap.fixed @@ -9,73 +9,119 @@ fn unwrap_option_some() { let _val = 1; + //~^ unnecessary_literal_unwrap let _val = 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap } #[rustfmt::skip] // force rustfmt not to remove braces in `|| { 234 }` fn unwrap_option_none() { let _val = panic!(); + //~^ unnecessary_literal_unwrap let _val = panic!("this always happens"); + //~^ unnecessary_literal_unwrap let _val: String = String::default(); + //~^ unnecessary_literal_unwrap let _val: u16 = 234; + //~^ unnecessary_literal_unwrap let _val: u16 = 234; + //~^ unnecessary_literal_unwrap let _val: u16 = { 234 }; + //~^ unnecessary_literal_unwrap let _val: u16 = { 234 }; + //~^ unnecessary_literal_unwrap panic!(); + //~^ unnecessary_literal_unwrap panic!("this always happens"); + //~^ unnecessary_literal_unwrap String::default(); + //~^ unnecessary_literal_unwrap 234; + //~^ unnecessary_literal_unwrap 234; + //~^ unnecessary_literal_unwrap { 234 }; + //~^ unnecessary_literal_unwrap { 234 }; + //~^ unnecessary_literal_unwrap } fn unwrap_result_ok() { let _val = 1; + //~^ unnecessary_literal_unwrap let _val = 1; + //~^ unnecessary_literal_unwrap let _val = panic!("{:?}", 1); + //~^ unnecessary_literal_unwrap let _val = panic!("{1}: {:?}", 1, "this always happens"); + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap panic!("{:?}", 1); + //~^ unnecessary_literal_unwrap panic!("{1}: {:?}", 1, "this always happens"); + //~^ unnecessary_literal_unwrap } fn unwrap_result_err() { let _val = 1; + //~^ unnecessary_literal_unwrap let _val = 1; + //~^ unnecessary_literal_unwrap let _val = panic!("{:?}", 1); + //~^ unnecessary_literal_unwrap let _val = panic!("{1}: {:?}", 1, "this always happens"); + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap panic!("{:?}", 1); + //~^ unnecessary_literal_unwrap panic!("{1}: {:?}", 1, "this always happens"); + //~^ unnecessary_literal_unwrap } fn unwrap_methods_option() { let _val = 1; + //~^ unnecessary_literal_unwrap let _val = 1; + //~^ unnecessary_literal_unwrap let _val = 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap } fn unwrap_methods_result() { let _val = 1; + //~^ unnecessary_literal_unwrap let _val = 1; + //~^ unnecessary_literal_unwrap let _val = 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap 1; + //~^ unnecessary_literal_unwrap } fn unwrap_from_binding() { @@ -90,12 +136,19 @@ fn unwrap_from_binding() { fn unwrap_unchecked() { let _ = 1; + //~^ unnecessary_literal_unwrap let _ = unsafe { 1 + *(&1 as *const i32) }; // needs to keep the unsafe block + //~^ unnecessary_literal_unwrap let _ = 1 + 1; + //~^ unnecessary_literal_unwrap let _ = 1; + //~^ unnecessary_literal_unwrap let _ = unsafe { 1 + *(&1 as *const i32) }; + //~^ unnecessary_literal_unwrap let _ = 1 + 1; + //~^ unnecessary_literal_unwrap let _ = 123; + //~^ unnecessary_literal_unwrap } fn main() { diff --git a/tests/ui/unnecessary_literal_unwrap.rs b/tests/ui/unnecessary_literal_unwrap.rs index 7bd8deea4d1b..1f47d3898bbb 100644 --- a/tests/ui/unnecessary_literal_unwrap.rs +++ b/tests/ui/unnecessary_literal_unwrap.rs @@ -9,73 +9,119 @@ fn unwrap_option_some() { let _val = Some(1).unwrap(); + //~^ unnecessary_literal_unwrap let _val = Some(1).expect("this never happens"); + //~^ unnecessary_literal_unwrap Some(1).unwrap(); + //~^ unnecessary_literal_unwrap Some(1).expect("this never happens"); + //~^ unnecessary_literal_unwrap } #[rustfmt::skip] // force rustfmt not to remove braces in `|| { 234 }` fn unwrap_option_none() { let _val = None::<()>.unwrap(); + //~^ unnecessary_literal_unwrap let _val = None::<()>.expect("this always happens"); + //~^ unnecessary_literal_unwrap let _val: String = None.unwrap_or_default(); + //~^ unnecessary_literal_unwrap let _val: u16 = None.unwrap_or(234); + //~^ unnecessary_literal_unwrap let _val: u16 = None.unwrap_or_else(|| 234); + //~^ unnecessary_literal_unwrap let _val: u16 = None.unwrap_or_else(|| { 234 }); + //~^ unnecessary_literal_unwrap let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 }); + //~^ unnecessary_literal_unwrap None::<()>.unwrap(); + //~^ unnecessary_literal_unwrap None::<()>.expect("this always happens"); + //~^ unnecessary_literal_unwrap None::.unwrap_or_default(); + //~^ unnecessary_literal_unwrap None::.unwrap_or(234); + //~^ unnecessary_literal_unwrap None::.unwrap_or_else(|| 234); + //~^ unnecessary_literal_unwrap None::.unwrap_or_else(|| { 234 }); + //~^ unnecessary_literal_unwrap None::.unwrap_or_else(|| -> u16 { 234 }); + //~^ unnecessary_literal_unwrap } fn unwrap_result_ok() { let _val = Ok::<_, ()>(1).unwrap(); + //~^ unnecessary_literal_unwrap let _val = Ok::<_, ()>(1).expect("this never happens"); + //~^ unnecessary_literal_unwrap let _val = Ok::<_, ()>(1).unwrap_err(); + //~^ unnecessary_literal_unwrap let _val = Ok::<_, ()>(1).expect_err("this always happens"); + //~^ unnecessary_literal_unwrap Ok::<_, ()>(1).unwrap(); + //~^ unnecessary_literal_unwrap Ok::<_, ()>(1).expect("this never happens"); + //~^ unnecessary_literal_unwrap Ok::<_, ()>(1).unwrap_err(); + //~^ unnecessary_literal_unwrap Ok::<_, ()>(1).expect_err("this always happens"); + //~^ unnecessary_literal_unwrap } fn unwrap_result_err() { let _val = Err::<(), _>(1).unwrap_err(); + //~^ unnecessary_literal_unwrap let _val = Err::<(), _>(1).expect_err("this never happens"); + //~^ unnecessary_literal_unwrap let _val = Err::<(), _>(1).unwrap(); + //~^ unnecessary_literal_unwrap let _val = Err::<(), _>(1).expect("this always happens"); + //~^ unnecessary_literal_unwrap Err::<(), _>(1).unwrap_err(); + //~^ unnecessary_literal_unwrap Err::<(), _>(1).expect_err("this never happens"); + //~^ unnecessary_literal_unwrap Err::<(), _>(1).unwrap(); + //~^ unnecessary_literal_unwrap Err::<(), _>(1).expect("this always happens"); + //~^ unnecessary_literal_unwrap } fn unwrap_methods_option() { let _val = Some(1).unwrap_or(2); + //~^ unnecessary_literal_unwrap let _val = Some(1).unwrap_or_default(); + //~^ unnecessary_literal_unwrap let _val = Some(1).unwrap_or_else(|| 2); + //~^ unnecessary_literal_unwrap Some(1).unwrap_or(2); + //~^ unnecessary_literal_unwrap Some(1).unwrap_or_default(); + //~^ unnecessary_literal_unwrap Some(1).unwrap_or_else(|| 2); + //~^ unnecessary_literal_unwrap } fn unwrap_methods_result() { let _val = Ok::<_, ()>(1).unwrap_or(2); + //~^ unnecessary_literal_unwrap let _val = Ok::<_, ()>(1).unwrap_or_default(); + //~^ unnecessary_literal_unwrap let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2); + //~^ unnecessary_literal_unwrap Ok::<_, ()>(1).unwrap_or(2); + //~^ unnecessary_literal_unwrap Ok::<_, ()>(1).unwrap_or_default(); + //~^ unnecessary_literal_unwrap Ok::<_, ()>(1).unwrap_or_else(|_| 2); + //~^ unnecessary_literal_unwrap } fn unwrap_from_binding() { @@ -90,12 +136,19 @@ fn unwrap_from_binding() { fn unwrap_unchecked() { let _ = unsafe { Some(1).unwrap_unchecked() }; + //~^ unnecessary_literal_unwrap let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block + //~^ unnecessary_literal_unwrap let _ = unsafe { Some(1).unwrap_unchecked() } + 1; + //~^ unnecessary_literal_unwrap let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() }; + //~^ unnecessary_literal_unwrap let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) }; + //~^ unnecessary_literal_unwrap let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1; + //~^ unnecessary_literal_unwrap let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() }; + //~^ unnecessary_literal_unwrap } fn main() { diff --git a/tests/ui/unnecessary_literal_unwrap.stderr b/tests/ui/unnecessary_literal_unwrap.stderr index 37ee9195fce6..f4880637375a 100644 --- a/tests/ui/unnecessary_literal_unwrap.stderr +++ b/tests/ui/unnecessary_literal_unwrap.stderr @@ -13,7 +13,7 @@ LL + let _val = 1; | error: used `expect()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:12:16 + --> tests/ui/unnecessary_literal_unwrap.rs:13:16 | LL | let _val = Some(1).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + let _val = 1; | error: used `unwrap()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:14:5 + --> tests/ui/unnecessary_literal_unwrap.rs:16:5 | LL | Some(1).unwrap(); | ^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + 1; | error: used `expect()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:15:5 + --> tests/ui/unnecessary_literal_unwrap.rs:18:5 | LL | Some(1).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,13 +49,13 @@ LL + 1; | error: used `unwrap()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:20:16 + --> tests/ui/unnecessary_literal_unwrap.rs:24:16 | LL | let _val = None::<()>.unwrap(); | ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()` error: used `expect()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:21:16 + --> tests/ui/unnecessary_literal_unwrap.rs:26:16 | LL | let _val = None::<()>.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,13 +66,13 @@ LL | let _val = panic!("this always happens"); | ~~~~~~~ error: used `unwrap_or_default()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:22:24 + --> tests/ui/unnecessary_literal_unwrap.rs:28:24 | LL | let _val: String = None.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `String::default()` error: used `unwrap_or()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:23:21 + --> tests/ui/unnecessary_literal_unwrap.rs:30:21 | LL | let _val: u16 = None.unwrap_or(234); | ^^^^^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL + let _val: u16 = 234; | error: used `unwrap_or_else()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:24:21 + --> tests/ui/unnecessary_literal_unwrap.rs:32:21 | LL | let _val: u16 = None.unwrap_or_else(|| 234); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL + let _val: u16 = 234; | error: used `unwrap_or_else()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:25:21 + --> tests/ui/unnecessary_literal_unwrap.rs:34:21 | LL | let _val: u16 = None.unwrap_or_else(|| { 234 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL + let _val: u16 = { 234 }; | error: used `unwrap_or_else()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:26:21 + --> tests/ui/unnecessary_literal_unwrap.rs:36:21 | LL | let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,13 +120,13 @@ LL + let _val: u16 = { 234 }; | error: used `unwrap()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:28:5 + --> tests/ui/unnecessary_literal_unwrap.rs:39:5 | LL | None::<()>.unwrap(); | ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()` error: used `expect()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:29:5 + --> tests/ui/unnecessary_literal_unwrap.rs:41:5 | LL | None::<()>.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,13 +137,13 @@ LL | panic!("this always happens"); | ~~~~~~~ error: used `unwrap_or_default()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:30:5 + --> tests/ui/unnecessary_literal_unwrap.rs:43:5 | LL | None::.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `String::default()` error: used `unwrap_or()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:31:5 + --> tests/ui/unnecessary_literal_unwrap.rs:45:5 | LL | None::.unwrap_or(234); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL + 234; | error: used `unwrap_or_else()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:32:5 + --> tests/ui/unnecessary_literal_unwrap.rs:47:5 | LL | None::.unwrap_or_else(|| 234); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL + 234; | error: used `unwrap_or_else()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:33:5 + --> tests/ui/unnecessary_literal_unwrap.rs:49:5 | LL | None::.unwrap_or_else(|| { 234 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -179,7 +179,7 @@ LL + { 234 }; | error: used `unwrap_or_else()` on `None` value - --> tests/ui/unnecessary_literal_unwrap.rs:34:5 + --> tests/ui/unnecessary_literal_unwrap.rs:51:5 | LL | None::.unwrap_or_else(|| -> u16 { 234 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -191,7 +191,7 @@ LL + { 234 }; | error: used `unwrap()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:38:16 + --> tests/ui/unnecessary_literal_unwrap.rs:56:16 | LL | let _val = Ok::<_, ()>(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -203,7 +203,7 @@ LL + let _val = 1; | error: used `expect()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:39:16 + --> tests/ui/unnecessary_literal_unwrap.rs:58:16 | LL | let _val = Ok::<_, ()>(1).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -215,7 +215,7 @@ LL + let _val = 1; | error: used `unwrap_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:40:16 + --> tests/ui/unnecessary_literal_unwrap.rs:60:16 | LL | let _val = Ok::<_, ()>(1).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -226,7 +226,7 @@ LL | let _val = panic!("{:?}", 1); | ~~~~~~~~~~~~~~ ~ error: used `expect_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:41:16 + --> tests/ui/unnecessary_literal_unwrap.rs:62:16 | LL | let _val = Ok::<_, ()>(1).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -237,7 +237,7 @@ LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); | ~~~~~~~~~~~~~~~~~~~ ~ error: used `unwrap()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:43:5 + --> tests/ui/unnecessary_literal_unwrap.rs:65:5 | LL | Ok::<_, ()>(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -249,7 +249,7 @@ LL + 1; | error: used `expect()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:44:5 + --> tests/ui/unnecessary_literal_unwrap.rs:67:5 | LL | Ok::<_, ()>(1).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -261,7 +261,7 @@ LL + 1; | error: used `unwrap_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:45:5 + --> tests/ui/unnecessary_literal_unwrap.rs:69:5 | LL | Ok::<_, ()>(1).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -272,7 +272,7 @@ LL | panic!("{:?}", 1); | ~~~~~~~~~~~~~~ ~ error: used `expect_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:46:5 + --> tests/ui/unnecessary_literal_unwrap.rs:71:5 | LL | Ok::<_, ()>(1).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -283,7 +283,7 @@ LL | panic!("{1}: {:?}", 1, "this always happens"); | ~~~~~~~~~~~~~~~~~~~ ~ error: used `unwrap_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:50:16 + --> tests/ui/unnecessary_literal_unwrap.rs:76:16 | LL | let _val = Err::<(), _>(1).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -295,7 +295,7 @@ LL + let _val = 1; | error: used `expect_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:51:16 + --> tests/ui/unnecessary_literal_unwrap.rs:78:16 | LL | let _val = Err::<(), _>(1).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -307,7 +307,7 @@ LL + let _val = 1; | error: used `unwrap()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:52:16 + --> tests/ui/unnecessary_literal_unwrap.rs:80:16 | LL | let _val = Err::<(), _>(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -318,7 +318,7 @@ LL | let _val = panic!("{:?}", 1); | ~~~~~~~~~~~~~~ ~ error: used `expect()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:53:16 + --> tests/ui/unnecessary_literal_unwrap.rs:82:16 | LL | let _val = Err::<(), _>(1).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -329,7 +329,7 @@ LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); | ~~~~~~~~~~~~~~~~~~~ ~ error: used `unwrap_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:55:5 + --> tests/ui/unnecessary_literal_unwrap.rs:85:5 | LL | Err::<(), _>(1).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -341,7 +341,7 @@ LL + 1; | error: used `expect_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:56:5 + --> tests/ui/unnecessary_literal_unwrap.rs:87:5 | LL | Err::<(), _>(1).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -353,7 +353,7 @@ LL + 1; | error: used `unwrap()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:57:5 + --> tests/ui/unnecessary_literal_unwrap.rs:89:5 | LL | Err::<(), _>(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -364,7 +364,7 @@ LL | panic!("{:?}", 1); | ~~~~~~~~~~~~~~ ~ error: used `expect()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:58:5 + --> tests/ui/unnecessary_literal_unwrap.rs:91:5 | LL | Err::<(), _>(1).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -375,7 +375,7 @@ LL | panic!("{1}: {:?}", 1, "this always happens"); | ~~~~~~~~~~~~~~~~~~~ ~ error: used `unwrap_or()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:62:16 + --> tests/ui/unnecessary_literal_unwrap.rs:96:16 | LL | let _val = Some(1).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^ @@ -387,7 +387,7 @@ LL + let _val = 1; | error: used `unwrap_or_default()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:63:16 + --> tests/ui/unnecessary_literal_unwrap.rs:98:16 | LL | let _val = Some(1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -399,7 +399,7 @@ LL + let _val = 1; | error: used `unwrap_or_else()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:64:16 + --> tests/ui/unnecessary_literal_unwrap.rs:100:16 | LL | let _val = Some(1).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -411,7 +411,7 @@ LL + let _val = 1; | error: used `unwrap_or()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:66:5 + --> tests/ui/unnecessary_literal_unwrap.rs:103:5 | LL | Some(1).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^ @@ -423,7 +423,7 @@ LL + 1; | error: used `unwrap_or_default()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:67:5 + --> tests/ui/unnecessary_literal_unwrap.rs:105:5 | LL | Some(1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -435,7 +435,7 @@ LL + 1; | error: used `unwrap_or_else()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:68:5 + --> tests/ui/unnecessary_literal_unwrap.rs:107:5 | LL | Some(1).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -447,7 +447,7 @@ LL + 1; | error: used `unwrap_or()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:72:16 + --> tests/ui/unnecessary_literal_unwrap.rs:112:16 | LL | let _val = Ok::<_, ()>(1).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -459,7 +459,7 @@ LL + let _val = 1; | error: used `unwrap_or_default()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:73:16 + --> tests/ui/unnecessary_literal_unwrap.rs:114:16 | LL | let _val = Ok::<_, ()>(1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -471,7 +471,7 @@ LL + let _val = 1; | error: used `unwrap_or_else()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:74:16 + --> tests/ui/unnecessary_literal_unwrap.rs:116:16 | LL | let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -483,7 +483,7 @@ LL + let _val = 1; | error: used `unwrap_or()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:76:5 + --> tests/ui/unnecessary_literal_unwrap.rs:119:5 | LL | Ok::<_, ()>(1).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -495,7 +495,7 @@ LL + 1; | error: used `unwrap_or_default()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:77:5 + --> tests/ui/unnecessary_literal_unwrap.rs:121:5 | LL | Ok::<_, ()>(1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -507,7 +507,7 @@ LL + 1; | error: used `unwrap_or_else()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:78:5 + --> tests/ui/unnecessary_literal_unwrap.rs:123:5 | LL | Ok::<_, ()>(1).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -519,7 +519,7 @@ LL + 1; | error: used `unwrap_unchecked()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:92:22 + --> tests/ui/unnecessary_literal_unwrap.rs:138:22 | LL | let _ = unsafe { Some(1).unwrap_unchecked() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -531,7 +531,7 @@ LL + let _ = 1; | error: used `unwrap_unchecked()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:93:22 + --> tests/ui/unnecessary_literal_unwrap.rs:140:22 | LL | let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -543,7 +543,7 @@ LL + let _ = unsafe { 1 + *(&1 as *const i32) }; // needs to keep the unsafe | error: used `unwrap_unchecked()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:94:22 + --> tests/ui/unnecessary_literal_unwrap.rs:142:22 | LL | let _ = unsafe { Some(1).unwrap_unchecked() } + 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -555,7 +555,7 @@ LL + let _ = 1 + 1; | error: used `unwrap_unchecked()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:95:22 + --> tests/ui/unnecessary_literal_unwrap.rs:144:22 | LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -567,7 +567,7 @@ LL + let _ = 1; | error: used `unwrap_unchecked()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:96:22 + --> tests/ui/unnecessary_literal_unwrap.rs:146:22 | LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -579,7 +579,7 @@ LL + let _ = unsafe { 1 + *(&1 as *const i32) }; | error: used `unwrap_unchecked()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:97:22 + --> tests/ui/unnecessary_literal_unwrap.rs:148:22 | LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -591,7 +591,7 @@ LL + let _ = 1 + 1; | error: used `unwrap_err_unchecked()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:98:22 + --> tests/ui/unnecessary_literal_unwrap.rs:150:22 | LL | let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_literal_unwrap_unfixable.rs b/tests/ui/unnecessary_literal_unwrap_unfixable.rs index 61058b7988a2..4bb93fc391e6 100644 --- a/tests/ui/unnecessary_literal_unwrap_unfixable.rs +++ b/tests/ui/unnecessary_literal_unwrap_unfixable.rs @@ -5,154 +5,206 @@ fn unwrap_option_some() { let val = Some(1); let _val2 = val.unwrap(); - //~^ ERROR: used `unwrap()` on `Some` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect("this never happens"); - //~^ ERROR: used `expect()` on `Some` value + //~^ unnecessary_literal_unwrap + } fn unwrap_option_some_context() { let _val = Some::([1, 2, 3].iter().sum()).unwrap(); - //~^ ERROR: used `unwrap()` on `Some` value + //~^ unnecessary_literal_unwrap + let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); - //~^ ERROR: used `expect()` on `Some` value + //~^ unnecessary_literal_unwrap + let val = Some::([1, 2, 3].iter().sum()); let _val2 = val.unwrap(); - //~^ ERROR: used `unwrap()` on `Some` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect("this never happens"); - //~^ ERROR: used `expect()` on `Some` value + //~^ unnecessary_literal_unwrap + } fn unwrap_option_none() { let val = None::<()>; let _val2 = val.unwrap(); - //~^ ERROR: used `unwrap()` on `None` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect("this always happens"); - //~^ ERROR: used `expect()` on `None` value + //~^ unnecessary_literal_unwrap + let _val3: u8 = None.unwrap_or_default(); - //~^ ERROR: used `unwrap_or_default()` on `None` value + //~^ unnecessary_literal_unwrap + None::<()>.unwrap_or_default(); - //~^ ERROR: used `unwrap_or_default()` on `None` value + //~^ unnecessary_literal_unwrap + } fn unwrap_result_ok() { let val = Ok::<_, ()>(1); let _val2 = val.unwrap(); - //~^ ERROR: used `unwrap()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect("this never happens"); - //~^ ERROR: used `expect()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_err(); - //~^ ERROR: used `unwrap_err()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect_err("this always happens"); - //~^ ERROR: used `expect_err()` on `Ok` value + //~^ unnecessary_literal_unwrap + } fn unwrap_result_ok_context() { let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); - //~^ ERROR: used `unwrap()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); - //~^ ERROR: used `expect()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); - //~^ ERROR: used `unwrap_err()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); - //~^ ERROR: used `expect_err()` on `Ok` value + //~^ unnecessary_literal_unwrap + let val = Ok::([1, 2, 3].iter().sum()); let _val2 = val.unwrap(); - //~^ ERROR: used `unwrap()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect("this never happens"); - //~^ ERROR: used `expect()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_err(); - //~^ ERROR: used `unwrap_err()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect_err("this always happens"); - //~^ ERROR: used `expect_err()` on `Ok` value + //~^ unnecessary_literal_unwrap + } fn unwrap_result_err() { let val = Err::<(), _>(1); let _val2 = val.unwrap_err(); - //~^ ERROR: used `unwrap_err()` on `Err` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect_err("this never happens"); - //~^ ERROR: used `expect_err()` on `Err` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap(); - //~^ ERROR: used `unwrap()` on `Err` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect("this always happens"); - //~^ ERROR: used `expect()` on `Err` value + //~^ unnecessary_literal_unwrap + } fn unwrap_result_err_context() { let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); - //~^ ERROR: used `unwrap_err()` on `Err` value + //~^ unnecessary_literal_unwrap + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); - //~^ ERROR: used `expect_err()` on `Err` value + //~^ unnecessary_literal_unwrap + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); - //~^ ERROR: used `unwrap()` on `Err` value + //~^ unnecessary_literal_unwrap + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); - //~^ ERROR: used `expect()` on `Err` value + //~^ unnecessary_literal_unwrap + let val = Err::<(), usize>([1, 2, 3].iter().sum()); let _val2 = val.unwrap_err(); - //~^ ERROR: used `unwrap_err()` on `Err` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect_err("this never happens"); - //~^ ERROR: used `expect_err()` on `Err` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap(); - //~^ ERROR: used `unwrap()` on `Err` value + //~^ unnecessary_literal_unwrap + let _val2 = val.expect("this always happens"); - //~^ ERROR: used `expect()` on `Err` value + //~^ unnecessary_literal_unwrap + } fn unwrap_methods_option() { let val = Some(1); let _val2 = val.unwrap_or(2); - //~^ ERROR: used `unwrap_or()` on `Some` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_or_default(); - //~^ ERROR: used `unwrap_or_default()` on `Some` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_or_else(|| 2); - //~^ ERROR: used `unwrap_or_else()` on `Some` value + //~^ unnecessary_literal_unwrap + } fn unwrap_methods_option_context() { let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); - //~^ ERROR: used `unwrap_or()` on `Some` value + //~^ unnecessary_literal_unwrap + let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); - //~^ ERROR: used `unwrap_or_default()` on `Some` value + //~^ unnecessary_literal_unwrap + let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); - //~^ ERROR: used `unwrap_or_else()` on `Some` value + //~^ unnecessary_literal_unwrap + let val = Some::([1, 2, 3].iter().sum()); let _val2 = val.unwrap_or(2); - //~^ ERROR: used `unwrap_or()` on `Some` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_or_default(); - //~^ ERROR: used `unwrap_or_default()` on `Some` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_or_else(|| 2); - //~^ ERROR: used `unwrap_or_else()` on `Some` value + //~^ unnecessary_literal_unwrap + } fn unwrap_methods_result() { let val = Ok::<_, ()>(1); let _val2 = val.unwrap_or(2); - //~^ ERROR: used `unwrap_or()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_or_default(); - //~^ ERROR: used `unwrap_or_default()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_or_else(|_| 2); - //~^ ERROR: used `unwrap_or_else()` on `Ok` value + //~^ unnecessary_literal_unwrap + } fn unwrap_methods_result_context() { let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); - //~^ ERROR: used `unwrap_or()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); - //~^ ERROR: used `unwrap_or_default()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); - //~^ ERROR: used `unwrap_or_else()` on `Ok` value + //~^ unnecessary_literal_unwrap + let val = Ok::([1, 2, 3].iter().sum()); let _val2 = val.unwrap_or(2); - //~^ ERROR: used `unwrap_or()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_or_default(); - //~^ ERROR: used `unwrap_or_default()` on `Ok` value + //~^ unnecessary_literal_unwrap + let _val2 = val.unwrap_or_else(|_| 2); - //~^ ERROR: used `unwrap_or_else()` on `Ok` value + //~^ unnecessary_literal_unwrap + } fn main() { diff --git a/tests/ui/unnecessary_literal_unwrap_unfixable.stderr b/tests/ui/unnecessary_literal_unwrap_unfixable.stderr index b7dd7ae729fd..b579bb74ef74 100644 --- a/tests/ui/unnecessary_literal_unwrap_unfixable.stderr +++ b/tests/ui/unnecessary_literal_unwrap_unfixable.stderr @@ -13,7 +13,7 @@ LL | let val = Some(1); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_literal_unwrap)]` error: used `expect()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:9:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:10:17 | LL | let _val2 = val.expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,589 +25,589 @@ LL | let val = Some(1); | ^^^^^^^ error: used `unwrap()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:14:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:16:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:14:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:16:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:16:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:19:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:16:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:19:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:20:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:24:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Some` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:19:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:23:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:22:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:27:17 | LL | let _val2 = val.expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:19:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:23:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `None` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:28:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:34:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `None` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:27:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:33:15 | LL | let val = None::<()>; | ^^^^^^^^^^ error: used `expect()` on `None` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:30:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:37:17 | LL | let _val2 = val.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `None` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:27:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:33:15 | LL | let val = None::<()>; | ^^^^^^^^^^ error: used `unwrap_or_default()` on `None` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:32:21 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:40:21 | LL | let _val3: u8 = None.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `Default::default()` error: used `unwrap_or_default()` on `None` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:34:5 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:43:5 | LL | None::<()>.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `Default::default()` error: used `unwrap()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:40:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:50:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:39:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `expect()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:42:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:53:17 | LL | let _val2 = val.expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:39:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:44:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:56:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:39:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `expect_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:46:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:59:17 | LL | let _val2 = val.expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:39:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:51:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:65:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:51:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:65:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:53:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:68:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:53:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:68:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:55:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:71:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:55:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:71:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:57:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:74:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:57:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:74:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:61:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:79:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:60:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:78:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:63:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:82:17 | LL | let _val2 = val.expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:60:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:78:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:65:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:85:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:60:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:78:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:67:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:88:17 | LL | let _val2 = val.expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:60:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:78:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:73:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:95:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `expect_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:75:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:98:17 | LL | let _val2 = val.expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `unwrap()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:77:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:101:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Err` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `expect()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:79:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:104:17 | LL | let _val2 = val.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:84:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:110:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:84:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:110:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:86:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:113:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:86:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:113:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:88:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:116:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:88:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:116:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:90:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:119:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:90:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:119:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:124:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:93:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:123:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:96:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:127:17 | LL | let _val2 = val.expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:93:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:123:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:98:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:130:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Err` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:93:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:123:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:100:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:133:17 | LL | let _val2 = val.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:93:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:123:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:106:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:140:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:105:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:139:15 | LL | let val = Some(1); | ^^^^^^^ error: used `unwrap_or_default()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:108:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:143:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:105:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:139:15 | LL | let val = Some(1); | ^^^^^^^ error: used `unwrap_or_else()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:110:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:146:17 | LL | let _val2 = val.unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:105:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:139:15 | LL | let val = Some(1); | ^^^^^^^ error: used `unwrap_or()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:115:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:152:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:115:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:152:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:117:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:155:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:117:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:155:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:119:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:158:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:119:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:158:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:123:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:163:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:122:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:125:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:166:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:122:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:127:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:169:17 | LL | let _val2 = val.unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:122:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:133:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:176:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:132:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:175:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:135:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:179:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:132:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:175:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:137:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:182:17 | LL | let _val2 = val.unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:132:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:175:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:142:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:188:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:142:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:188:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:144:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:191:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:144:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:191:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:146:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:194:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:146:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:194:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:150:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:199:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:149:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:198:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:152:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:202:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:149:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:198:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:154:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:205:17 | LL | let _val2 = val.unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:149:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:198:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_map_on_constructor.fixed b/tests/ui/unnecessary_map_on_constructor.fixed index d0ba7ed749e4..4452fda38c40 100644 --- a/tests/ui/unnecessary_map_on_constructor.fixed +++ b/tests/ui/unnecessary_map_on_constructor.fixed @@ -30,14 +30,22 @@ fn main() { let c: SimpleResult = Err(err); let a = Some(fun(x)); + //~^ unnecessary_map_on_constructor let b: SimpleResult = Ok(fun(x)); + //~^ unnecessary_map_on_constructor let c: SimpleResult = Err(notfun(err)); + //~^ unnecessary_map_on_constructor let a = Option::Some(fun(x)); + //~^ unnecessary_map_on_constructor let b: SimpleResult = SimpleResult::Ok(fun(x)); + //~^ unnecessary_map_on_constructor let c: SimpleResult = SimpleResult::Err(notfun(err)); + //~^ unnecessary_map_on_constructor let b: std::result::Result = Ok(fun(x)); + //~^ unnecessary_map_on_constructor let c: std::result::Result = Err(notfun(err)); + //~^ unnecessary_map_on_constructor let a = Some(fun(x)); let b: SimpleResult = Ok(fun(x)); diff --git a/tests/ui/unnecessary_map_on_constructor.rs b/tests/ui/unnecessary_map_on_constructor.rs index e89e7aad4c40..0cd41f2b363a 100644 --- a/tests/ui/unnecessary_map_on_constructor.rs +++ b/tests/ui/unnecessary_map_on_constructor.rs @@ -30,14 +30,22 @@ fn main() { let c: SimpleResult = Err(err); let a = Some(x).map(fun); + //~^ unnecessary_map_on_constructor let b: SimpleResult = Ok(x).map(fun); + //~^ unnecessary_map_on_constructor let c: SimpleResult = Err(err).map_err(notfun); + //~^ unnecessary_map_on_constructor let a = Option::Some(x).map(fun); + //~^ unnecessary_map_on_constructor let b: SimpleResult = SimpleResult::Ok(x).map(fun); + //~^ unnecessary_map_on_constructor let c: SimpleResult = SimpleResult::Err(err).map_err(notfun); + //~^ unnecessary_map_on_constructor let b: std::result::Result = Ok(x).map(fun); + //~^ unnecessary_map_on_constructor let c: std::result::Result = Err(err).map_err(notfun); + //~^ unnecessary_map_on_constructor let a = Some(fun(x)); let b: SimpleResult = Ok(fun(x)); diff --git a/tests/ui/unnecessary_map_on_constructor.stderr b/tests/ui/unnecessary_map_on_constructor.stderr index ecbf65244154..f29bfec60f72 100644 --- a/tests/ui/unnecessary_map_on_constructor.stderr +++ b/tests/ui/unnecessary_map_on_constructor.stderr @@ -8,43 +8,43 @@ LL | let a = Some(x).map(fun); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_on_constructor)]` error: unnecessary map on constructor Ok(_) - --> tests/ui/unnecessary_map_on_constructor.rs:33:27 + --> tests/ui/unnecessary_map_on_constructor.rs:34:27 | LL | let b: SimpleResult = Ok(x).map(fun); | ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))` error: unnecessary map_err on constructor Err(_) - --> tests/ui/unnecessary_map_on_constructor.rs:34:27 + --> tests/ui/unnecessary_map_on_constructor.rs:36:27 | LL | let c: SimpleResult = Err(err).map_err(notfun); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))` error: unnecessary map on constructor Option::Some(_) - --> tests/ui/unnecessary_map_on_constructor.rs:36:13 + --> tests/ui/unnecessary_map_on_constructor.rs:39:13 | LL | let a = Option::Some(x).map(fun); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Option::Some(fun(x))` error: unnecessary map on constructor SimpleResult::Ok(_) - --> tests/ui/unnecessary_map_on_constructor.rs:37:27 + --> tests/ui/unnecessary_map_on_constructor.rs:41:27 | LL | let b: SimpleResult = SimpleResult::Ok(x).map(fun); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Ok(fun(x))` error: unnecessary map_err on constructor SimpleResult::Err(_) - --> tests/ui/unnecessary_map_on_constructor.rs:38:27 + --> tests/ui/unnecessary_map_on_constructor.rs:43:27 | LL | let c: SimpleResult = SimpleResult::Err(err).map_err(notfun); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Err(notfun(err))` error: unnecessary map on constructor Ok(_) - --> tests/ui/unnecessary_map_on_constructor.rs:39:52 + --> tests/ui/unnecessary_map_on_constructor.rs:45:52 | LL | let b: std::result::Result = Ok(x).map(fun); | ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))` error: unnecessary map_err on constructor Err(_) - --> tests/ui/unnecessary_map_on_constructor.rs:40:52 + --> tests/ui/unnecessary_map_on_constructor.rs:47:52 | LL | let c: std::result::Result = Err(err).map_err(notfun); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))` diff --git a/tests/ui/unnecessary_map_or.fixed b/tests/ui/unnecessary_map_or.fixed index 27532373a7b9..f51da49edabb 100644 --- a/tests/ui/unnecessary_map_or.fixed +++ b/tests/ui/unnecessary_map_or.fixed @@ -11,24 +11,39 @@ extern crate proc_macros; fn main() { // should trigger let _ = Some(5) == Some(5); + //~^ unnecessary_map_or let _ = Some(5) != Some(5); + //~^ unnecessary_map_or let _ = Some(5) == Some(5); let _ = Some(5).is_some_and(|n| { + //~^ unnecessary_map_or let _ = n; 6 >= 5 }); let _ = Some(vec![5]).is_some_and(|n| n == [5]); + //~^ unnecessary_map_or let _ = Some(vec![1]).is_some_and(|n| vec![2] == n); + //~^ unnecessary_map_or let _ = Some(5).is_some_and(|n| n == n); + //~^ unnecessary_map_or let _ = Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 }); + //~^ unnecessary_map_or let _ = Ok::, i32>(vec![5]).is_ok_and(|n| n == [5]); + //~^ unnecessary_map_or let _ = Ok::(5) == Ok(5); + //~^ unnecessary_map_or let _ = (Some(5) == Some(5)).then(|| 1); + //~^ unnecessary_map_or let _ = Some(5).is_none_or(|n| n == 5); + //~^ unnecessary_map_or let _ = Some(5).is_none_or(|n| 5 == n); + //~^ unnecessary_map_or let _ = !(Some(5) == Some(5)); + //~^ unnecessary_map_or let _ = (Some(5) == Some(5)) || false; + //~^ unnecessary_map_or let _ = (Some(5) == Some(5)) as usize; + //~^ unnecessary_map_or macro_rules! x { () => { @@ -53,18 +68,23 @@ fn main() { struct S; let r: Result = Ok(3); let _ = r.is_ok_and(|x| x == 7); + //~^ unnecessary_map_or // lint constructs that are not comparaisons as well let func = |_x| true; let r: Result = Ok(3); let _ = r.is_ok_and(func); + //~^ unnecessary_map_or let _ = Some(5).is_some_and(func); + //~^ unnecessary_map_or let _ = Some(5).is_none_or(func); + //~^ unnecessary_map_or #[derive(PartialEq)] struct S2; let r: Result = Ok(4); let _ = r == Ok(8); + //~^ unnecessary_map_or // do not lint `Result::map_or(true, …)` let r: Result = Ok(4); @@ -85,6 +105,8 @@ fn msrv_1_81() { fn with_refs(o: &mut Option) -> bool { o.is_none_or(|n| n > 5) || (o as &Option).is_none_or(|n| n < 5) + //~^ unnecessary_map_or + //~| unnecessary_map_or } struct S; @@ -98,6 +120,7 @@ impl std::ops::Deref for S { fn with_deref(o: &S) -> bool { o.is_none_or(|n| n > 5) + //~^ unnecessary_map_or } fn issue14201(a: Option, b: Option, s: &String) -> bool { diff --git a/tests/ui/unnecessary_map_or.rs b/tests/ui/unnecessary_map_or.rs index 6496defe1300..a1ae97af2b9f 100644 --- a/tests/ui/unnecessary_map_or.rs +++ b/tests/ui/unnecessary_map_or.rs @@ -11,27 +11,43 @@ extern crate proc_macros; fn main() { // should trigger let _ = Some(5).map_or(false, |n| n == 5); + //~^ unnecessary_map_or let _ = Some(5).map_or(true, |n| n != 5); + //~^ unnecessary_map_or let _ = Some(5).map_or(false, |n| { + //~^ unnecessary_map_or let _ = 1; n == 5 }); let _ = Some(5).map_or(false, |n| { + //~^ unnecessary_map_or let _ = n; 6 >= 5 }); let _ = Some(vec![5]).map_or(false, |n| n == [5]); + //~^ unnecessary_map_or let _ = Some(vec![1]).map_or(false, |n| vec![2] == n); + //~^ unnecessary_map_or let _ = Some(5).map_or(false, |n| n == n); + //~^ unnecessary_map_or let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 }); + //~^ unnecessary_map_or let _ = Ok::, i32>(vec![5]).map_or(false, |n| n == [5]); + //~^ unnecessary_map_or let _ = Ok::(5).map_or(false, |n| n == 5); + //~^ unnecessary_map_or let _ = Some(5).map_or(false, |n| n == 5).then(|| 1); + //~^ unnecessary_map_or let _ = Some(5).map_or(true, |n| n == 5); + //~^ unnecessary_map_or let _ = Some(5).map_or(true, |n| 5 == n); + //~^ unnecessary_map_or let _ = !Some(5).map_or(false, |n| n == 5); + //~^ unnecessary_map_or let _ = Some(5).map_or(false, |n| n == 5) || false; + //~^ unnecessary_map_or let _ = Some(5).map_or(false, |n| n == 5) as usize; + //~^ unnecessary_map_or macro_rules! x { () => { @@ -56,18 +72,23 @@ fn main() { struct S; let r: Result = Ok(3); let _ = r.map_or(false, |x| x == 7); + //~^ unnecessary_map_or // lint constructs that are not comparaisons as well let func = |_x| true; let r: Result = Ok(3); let _ = r.map_or(false, func); + //~^ unnecessary_map_or let _ = Some(5).map_or(false, func); + //~^ unnecessary_map_or let _ = Some(5).map_or(true, func); + //~^ unnecessary_map_or #[derive(PartialEq)] struct S2; let r: Result = Ok(4); let _ = r.map_or(false, |x| x == 8); + //~^ unnecessary_map_or // do not lint `Result::map_or(true, …)` let r: Result = Ok(4); @@ -88,6 +109,8 @@ fn msrv_1_81() { fn with_refs(o: &mut Option) -> bool { o.map_or(true, |n| n > 5) || (o as &Option).map_or(true, |n| n < 5) + //~^ unnecessary_map_or + //~| unnecessary_map_or } struct S; @@ -101,6 +124,7 @@ impl std::ops::Deref for S { fn with_deref(o: &S) -> bool { o.map_or(true, |n| n > 5) + //~^ unnecessary_map_or } fn issue14201(a: Option, b: Option, s: &String) -> bool { diff --git a/tests/ui/unnecessary_map_or.stderr b/tests/ui/unnecessary_map_or.stderr index f672f55dd04d..57a76c21c70d 100644 --- a/tests/ui/unnecessary_map_or.stderr +++ b/tests/ui/unnecessary_map_or.stderr @@ -12,7 +12,7 @@ LL | let _ = Some(5) == Some(5); | ~~~~~~~~~~~~~~~~~~ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:14:13 + --> tests/ui/unnecessary_map_or.rs:15:13 | LL | let _ = Some(5).map_or(true, |n| n != 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,10 +23,11 @@ LL | let _ = Some(5) != Some(5); | ~~~~~~~~~~~~~~~~~~ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:15:13 + --> tests/ui/unnecessary_map_or.rs:17:13 | LL | let _ = Some(5).map_or(false, |n| { | _____________^ +LL | | LL | | let _ = 1; LL | | n == 5 LL | | }); @@ -38,10 +39,11 @@ LL | let _ = Some(5) == Some(5); | ~~~~~~~~~~~~~~~~~~ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:19:13 + --> tests/ui/unnecessary_map_or.rs:22:13 | LL | let _ = Some(5).map_or(false, |n| { | _____________^ +LL | | LL | | let _ = n; LL | | 6 >= 5 LL | | }); @@ -54,7 +56,7 @@ LL + let _ = Some(5).is_some_and(|n| { | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:23:13 + --> tests/ui/unnecessary_map_or.rs:27:13 | LL | let _ = Some(vec![5]).map_or(false, |n| n == [5]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +68,7 @@ LL + let _ = Some(vec![5]).is_some_and(|n| n == [5]); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:24:13 + --> tests/ui/unnecessary_map_or.rs:29:13 | LL | let _ = Some(vec![1]).map_or(false, |n| vec![2] == n); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +80,7 @@ LL + let _ = Some(vec![1]).is_some_and(|n| vec![2] == n); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:25:13 + --> tests/ui/unnecessary_map_or.rs:31:13 | LL | let _ = Some(5).map_or(false, |n| n == n); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,7 +92,7 @@ LL + let _ = Some(5).is_some_and(|n| n == n); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:26:13 + --> tests/ui/unnecessary_map_or.rs:33:13 | LL | let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -102,7 +104,7 @@ LL + let _ = Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 }); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:27:13 + --> tests/ui/unnecessary_map_or.rs:35:13 | LL | let _ = Ok::, i32>(vec![5]).map_or(false, |n| n == [5]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +116,7 @@ LL + let _ = Ok::, i32>(vec![5]).is_ok_and(|n| n == [5]); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:28:13 + --> tests/ui/unnecessary_map_or.rs:37:13 | LL | let _ = Ok::(5).map_or(false, |n| n == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -125,7 +127,7 @@ LL | let _ = Ok::(5) == Ok(5); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:29:13 + --> tests/ui/unnecessary_map_or.rs:39:13 | LL | let _ = Some(5).map_or(false, |n| n == 5).then(|| 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +138,7 @@ LL | let _ = (Some(5) == Some(5)).then(|| 1); | ~~~~~~~~~~~~~~~~~~~~ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:30:13 + --> tests/ui/unnecessary_map_or.rs:41:13 | LL | let _ = Some(5).map_or(true, |n| n == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +150,7 @@ LL + let _ = Some(5).is_none_or(|n| n == 5); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:31:13 + --> tests/ui/unnecessary_map_or.rs:43:13 | LL | let _ = Some(5).map_or(true, |n| 5 == n); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,7 +162,7 @@ LL + let _ = Some(5).is_none_or(|n| 5 == n); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:32:14 + --> tests/ui/unnecessary_map_or.rs:45:14 | LL | let _ = !Some(5).map_or(false, |n| n == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -171,7 +173,7 @@ LL | let _ = !(Some(5) == Some(5)); | ~~~~~~~~~~~~~~~~~~~~ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:33:13 + --> tests/ui/unnecessary_map_or.rs:47:13 | LL | let _ = Some(5).map_or(false, |n| n == 5) || false; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +184,7 @@ LL | let _ = (Some(5) == Some(5)) || false; | ~~~~~~~~~~~~~~~~~~~~ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:34:13 + --> tests/ui/unnecessary_map_or.rs:49:13 | LL | let _ = Some(5).map_or(false, |n| n == 5) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +195,7 @@ LL | let _ = (Some(5) == Some(5)) as usize; | ~~~~~~~~~~~~~~~~~~~~ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:58:13 + --> tests/ui/unnecessary_map_or.rs:74:13 | LL | let _ = r.map_or(false, |x| x == 7); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -205,7 +207,7 @@ LL + let _ = r.is_ok_and(|x| x == 7); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:63:13 + --> tests/ui/unnecessary_map_or.rs:80:13 | LL | let _ = r.map_or(false, func); | ^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +219,7 @@ LL + let _ = r.is_ok_and(func); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:64:13 + --> tests/ui/unnecessary_map_or.rs:82:13 | LL | let _ = Some(5).map_or(false, func); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -229,7 +231,7 @@ LL + let _ = Some(5).is_some_and(func); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:65:13 + --> tests/ui/unnecessary_map_or.rs:84:13 | LL | let _ = Some(5).map_or(true, func); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +243,7 @@ LL + let _ = Some(5).is_none_or(func); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:70:13 + --> tests/ui/unnecessary_map_or.rs:90:13 | LL | let _ = r.map_or(false, |x| x == 8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -252,7 +254,7 @@ LL | let _ = r == Ok(8); | ~~~~~~~~~~ error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:90:5 + --> tests/ui/unnecessary_map_or.rs:111:5 | LL | o.map_or(true, |n| n > 5) || (o as &Option).map_or(true, |n| n < 5) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -264,7 +266,7 @@ LL + o.is_none_or(|n| n > 5) || (o as &Option).map_or(true, |n| n < 5) | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:90:34 + --> tests/ui/unnecessary_map_or.rs:111:34 | LL | o.map_or(true, |n| n > 5) || (o as &Option).map_or(true, |n| n < 5) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -276,7 +278,7 @@ LL + o.map_or(true, |n| n > 5) || (o as &Option).is_none_or(|n| n < 5) | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:103:5 + --> tests/ui/unnecessary_map_or.rs:126:5 | LL | o.map_or(true, |n| n > 5) | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_min_or_max.fixed b/tests/ui/unnecessary_min_or_max.fixed index 1f3e131516ce..2650cae5baf4 100644 --- a/tests/ui/unnecessary_min_or_max.fixed +++ b/tests/ui/unnecessary_min_or_max.fixed @@ -11,30 +11,47 @@ const X: i32 = 1; fn main() { // Both are Literals let _ = (-6_i32); + //~^ unnecessary_min_or_max let _ = 9; + //~^ unnecessary_min_or_max let _ = 6; + //~^ unnecessary_min_or_max let _ = 9_u32; + //~^ unnecessary_min_or_max let _ = 6; + //~^ unnecessary_min_or_max let _ = 7_u8; + //~^ unnecessary_min_or_max let x: u32 = 42; // unsigned with zero let _ = 0; + //~^ unnecessary_min_or_max let _ = x; + //~^ unnecessary_min_or_max let _ = 0_u32; + //~^ unnecessary_min_or_max let _ = x; + //~^ unnecessary_min_or_max let x: i32 = 42; // signed MIN let _ = i32::MIN; + //~^ unnecessary_min_or_max let _ = x; + //~^ unnecessary_min_or_max let _ = i32::MIN; + //~^ unnecessary_min_or_max let _ = x; + //~^ unnecessary_min_or_max let _ = i32::MIN - 0; + //~^ unnecessary_min_or_max let _ = x; + //~^ unnecessary_min_or_max let _ = i32::MIN - 0; + //~^ unnecessary_min_or_max // The below cases shouldn't be lint let mut min = u32::MAX; diff --git a/tests/ui/unnecessary_min_or_max.rs b/tests/ui/unnecessary_min_or_max.rs index 58356b9d49e7..2f3c480b3d15 100644 --- a/tests/ui/unnecessary_min_or_max.rs +++ b/tests/ui/unnecessary_min_or_max.rs @@ -11,30 +11,47 @@ const X: i32 = 1; fn main() { // Both are Literals let _ = (-6_i32).min(9); + //~^ unnecessary_min_or_max let _ = (-6_i32).max(9); + //~^ unnecessary_min_or_max let _ = 9_u32.min(6); + //~^ unnecessary_min_or_max let _ = 9_u32.max(6); + //~^ unnecessary_min_or_max let _ = 6.min(7_u8); + //~^ unnecessary_min_or_max let _ = 6.max(7_u8); + //~^ unnecessary_min_or_max let x: u32 = 42; // unsigned with zero let _ = 0.min(x); + //~^ unnecessary_min_or_max let _ = 0.max(x); + //~^ unnecessary_min_or_max let _ = x.min(0_u32); + //~^ unnecessary_min_or_max let _ = x.max(0_u32); + //~^ unnecessary_min_or_max let x: i32 = 42; // signed MIN let _ = i32::MIN.min(x); + //~^ unnecessary_min_or_max let _ = i32::MIN.max(x); + //~^ unnecessary_min_or_max let _ = x.min(i32::MIN); + //~^ unnecessary_min_or_max let _ = x.max(i32::MIN); + //~^ unnecessary_min_or_max let _ = x.min(i32::MIN - 0); + //~^ unnecessary_min_or_max let _ = x.max(i32::MIN); + //~^ unnecessary_min_or_max let _ = x.min(i32::MIN - 0); + //~^ unnecessary_min_or_max // The below cases shouldn't be lint let mut min = u32::MAX; diff --git a/tests/ui/unnecessary_min_or_max.stderr b/tests/ui/unnecessary_min_or_max.stderr index f5cd31fbaf24..dfe6910dfa5c 100644 --- a/tests/ui/unnecessary_min_or_max.stderr +++ b/tests/ui/unnecessary_min_or_max.stderr @@ -8,97 +8,97 @@ LL | let _ = (-6_i32).min(9); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_min_or_max)]` error: `(-6_i32)` is never greater than `9` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:14:13 + --> tests/ui/unnecessary_min_or_max.rs:15:13 | LL | let _ = (-6_i32).max(9); | ^^^^^^^^^^^^^^^ help: try: `9` error: `9_u32` is never smaller than `6` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:15:13 + --> tests/ui/unnecessary_min_or_max.rs:17:13 | LL | let _ = 9_u32.min(6); | ^^^^^^^^^^^^ help: try: `6` error: `9_u32` is never smaller than `6` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:16:13 + --> tests/ui/unnecessary_min_or_max.rs:19:13 | LL | let _ = 9_u32.max(6); | ^^^^^^^^^^^^ help: try: `9_u32` error: `6` is never greater than `7_u8` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:17:13 + --> tests/ui/unnecessary_min_or_max.rs:21:13 | LL | let _ = 6.min(7_u8); | ^^^^^^^^^^^ help: try: `6` error: `6` is never greater than `7_u8` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:18:13 + --> tests/ui/unnecessary_min_or_max.rs:23:13 | LL | let _ = 6.max(7_u8); | ^^^^^^^^^^^ help: try: `7_u8` error: `0` is never greater than `x` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:22:13 + --> tests/ui/unnecessary_min_or_max.rs:28:13 | LL | let _ = 0.min(x); | ^^^^^^^^ help: try: `0` error: `0` is never greater than `x` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:23:13 + --> tests/ui/unnecessary_min_or_max.rs:30:13 | LL | let _ = 0.max(x); | ^^^^^^^^ help: try: `x` error: `x` is never smaller than `0_u32` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:24:13 + --> tests/ui/unnecessary_min_or_max.rs:32:13 | LL | let _ = x.min(0_u32); | ^^^^^^^^^^^^ help: try: `0_u32` error: `x` is never smaller than `0_u32` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:25:13 + --> tests/ui/unnecessary_min_or_max.rs:34:13 | LL | let _ = x.max(0_u32); | ^^^^^^^^^^^^ help: try: `x` error: `i32::MIN` is never greater than `x` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:29:13 + --> tests/ui/unnecessary_min_or_max.rs:39:13 | LL | let _ = i32::MIN.min(x); | ^^^^^^^^^^^^^^^ help: try: `i32::MIN` error: `i32::MIN` is never greater than `x` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:30:13 + --> tests/ui/unnecessary_min_or_max.rs:41:13 | LL | let _ = i32::MIN.max(x); | ^^^^^^^^^^^^^^^ help: try: `x` error: `x` is never smaller than `i32::MIN` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:31:13 + --> tests/ui/unnecessary_min_or_max.rs:43:13 | LL | let _ = x.min(i32::MIN); | ^^^^^^^^^^^^^^^ help: try: `i32::MIN` error: `x` is never smaller than `i32::MIN` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:32:13 + --> tests/ui/unnecessary_min_or_max.rs:45:13 | LL | let _ = x.max(i32::MIN); | ^^^^^^^^^^^^^^^ help: try: `x` error: `x` is never smaller than `i32::MIN - 0` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:34:13 + --> tests/ui/unnecessary_min_or_max.rs:48:13 | LL | let _ = x.min(i32::MIN - 0); | ^^^^^^^^^^^^^^^^^^^ help: try: `i32::MIN - 0` error: `x` is never smaller than `i32::MIN` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:35:13 + --> tests/ui/unnecessary_min_or_max.rs:50:13 | LL | let _ = x.max(i32::MIN); | ^^^^^^^^^^^^^^^ help: try: `x` error: `x` is never smaller than `i32::MIN - 0` and has therefore no effect - --> tests/ui/unnecessary_min_or_max.rs:37:13 + --> tests/ui/unnecessary_min_or_max.rs:53:13 | LL | let _ = x.min(i32::MIN - 0); | ^^^^^^^^^^^^^^^^^^^ help: try: `i32::MIN - 0` diff --git a/tests/ui/unnecessary_operation.fixed b/tests/ui/unnecessary_operation.fixed index 006f123cbcdf..ec3e64e15b85 100644 --- a/tests/ui/unnecessary_operation.fixed +++ b/tests/ui/unnecessary_operation.fixed @@ -68,22 +68,39 @@ where fn main() { get_number(); + //~^ unnecessary_operation get_number(); + //~^ unnecessary_operation get_struct(); + //~^ unnecessary_operation get_number(); + //~^ unnecessary_operation get_number(); + //~^ unnecessary_operation 5;get_number(); + //~^ unnecessary_operation get_number(); + //~^ unnecessary_operation get_number(); + //~^ unnecessary_operation 5;6;get_number(); + //~^ unnecessary_operation get_number(); + //~^ unnecessary_operation get_number(); + //~^ unnecessary_operation 5;get_number(); + //~^ unnecessary_operation 42;get_number(); + //~^ unnecessary_operation assert!([42, 55].len() > get_usize()); + //~^ unnecessary_operation 42;get_number(); + //~^ unnecessary_operation get_number(); + //~^ unnecessary_operation assert!([42; 55].len() > get_usize()); + //~^ unnecessary_operation get_number(); String::from("blah"); @@ -124,5 +141,6 @@ const _: () = { const fn foo() { assert!([42, 55].len() > get_usize()); - //~^ ERROR: unnecessary operation + //~^ unnecessary_operation + } diff --git a/tests/ui/unnecessary_operation.rs b/tests/ui/unnecessary_operation.rs index b4067c740741..3f903cd04ef8 100644 --- a/tests/ui/unnecessary_operation.rs +++ b/tests/ui/unnecessary_operation.rs @@ -68,26 +68,45 @@ where fn main() { Tuple(get_number()); + //~^ unnecessary_operation Struct { field: get_number() }; + //~^ unnecessary_operation Struct { ..get_struct() }; + //~^ unnecessary_operation Enum::Tuple(get_number()); + //~^ unnecessary_operation Enum::Struct { field: get_number() }; + //~^ unnecessary_operation 5 + get_number(); + //~^ unnecessary_operation *&get_number(); + //~^ unnecessary_operation &get_number(); + //~^ unnecessary_operation (5, 6, get_number()); + //~^ unnecessary_operation get_number()..; + //~^ unnecessary_operation ..get_number(); + //~^ unnecessary_operation 5..get_number(); + //~^ unnecessary_operation [42, get_number()]; + //~^ unnecessary_operation [42, 55][get_usize()]; + //~^ unnecessary_operation (42, get_number()).1; + //~^ unnecessary_operation [get_number(); 55]; + //~^ unnecessary_operation [42; 55][get_usize()]; + //~^ unnecessary_operation { + //~^ unnecessary_operation get_number() }; FooString { + //~^ unnecessary_operation s: String::from("blah"), }; @@ -128,5 +147,6 @@ const _: () = { const fn foo() { [42, 55][get_usize()]; - //~^ ERROR: unnecessary operation + //~^ unnecessary_operation + } diff --git a/tests/ui/unnecessary_operation.stderr b/tests/ui/unnecessary_operation.stderr index 036a9a44bbad..eb98af09e7a3 100644 --- a/tests/ui/unnecessary_operation.stderr +++ b/tests/ui/unnecessary_operation.stderr @@ -8,119 +8,121 @@ LL | Tuple(get_number()); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_operation)]` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:71:5 + --> tests/ui/unnecessary_operation.rs:72:5 | LL | Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:72:5 + --> tests/ui/unnecessary_operation.rs:74:5 | LL | Struct { ..get_struct() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_struct();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:73:5 + --> tests/ui/unnecessary_operation.rs:76:5 | LL | Enum::Tuple(get_number()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:74:5 + --> tests/ui/unnecessary_operation.rs:78:5 | LL | Enum::Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:75:5 + --> tests/ui/unnecessary_operation.rs:80:5 | LL | 5 + get_number(); | ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:76:5 + --> tests/ui/unnecessary_operation.rs:82:5 | LL | *&get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:77:5 + --> tests/ui/unnecessary_operation.rs:84:5 | LL | &get_number(); | ^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:78:5 + --> tests/ui/unnecessary_operation.rs:86:5 | LL | (5, 6, get_number()); | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;6;get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:79:5 + --> tests/ui/unnecessary_operation.rs:88:5 | LL | get_number()..; | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:80:5 + --> tests/ui/unnecessary_operation.rs:90:5 | LL | ..get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:81:5 + --> tests/ui/unnecessary_operation.rs:92:5 | LL | 5..get_number(); | ^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:82:5 + --> tests/ui/unnecessary_operation.rs:94:5 | LL | [42, get_number()]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:83:5 + --> tests/ui/unnecessary_operation.rs:96:5 | LL | [42, 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:84:5 + --> tests/ui/unnecessary_operation.rs:98:5 | LL | (42, get_number()).1; | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:85:5 + --> tests/ui/unnecessary_operation.rs:100:5 | LL | [get_number(); 55]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:86:5 + --> tests/ui/unnecessary_operation.rs:102:5 | LL | [42; 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42; 55].len() > get_usize());` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:87:5 + --> tests/ui/unnecessary_operation.rs:104:5 | LL | / { +LL | | LL | | get_number() LL | | }; | |______^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:90:5 + --> tests/ui/unnecessary_operation.rs:108:5 | LL | / FooString { +LL | | LL | | s: String::from("blah"), LL | | }; | |______^ help: statement can be reduced to: `String::from("blah");` error: unnecessary operation - --> tests/ui/unnecessary_operation.rs:130:5 + --> tests/ui/unnecessary_operation.rs:149:5 | LL | [42, 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());` diff --git a/tests/ui/unnecessary_owned_empty_strings.fixed b/tests/ui/unnecessary_owned_empty_strings.fixed index 75cd63db8a1a..dc0e495be30f 100644 --- a/tests/ui/unnecessary_owned_empty_strings.fixed +++ b/tests/ui/unnecessary_owned_empty_strings.fixed @@ -8,10 +8,12 @@ fn ref_string_argument(_value: &String) {} fn main() { // should be linted ref_str_argument(""); + //~^ unnecessary_owned_empty_strings // should be linted #[allow(clippy::manual_string_new)] ref_str_argument(""); + //~^ unnecessary_owned_empty_strings // should not be linted ref_str_argument(""); diff --git a/tests/ui/unnecessary_owned_empty_strings.rs b/tests/ui/unnecessary_owned_empty_strings.rs index 2edc0bd86d38..e2c5de447444 100644 --- a/tests/ui/unnecessary_owned_empty_strings.rs +++ b/tests/ui/unnecessary_owned_empty_strings.rs @@ -8,10 +8,12 @@ fn ref_string_argument(_value: &String) {} fn main() { // should be linted ref_str_argument(&String::new()); + //~^ unnecessary_owned_empty_strings // should be linted #[allow(clippy::manual_string_new)] ref_str_argument(&String::from("")); + //~^ unnecessary_owned_empty_strings // should not be linted ref_str_argument(""); diff --git a/tests/ui/unnecessary_owned_empty_strings.stderr b/tests/ui/unnecessary_owned_empty_strings.stderr index 1820ea4ef5d8..8bcf3ee88765 100644 --- a/tests/ui/unnecessary_owned_empty_strings.stderr +++ b/tests/ui/unnecessary_owned_empty_strings.stderr @@ -8,7 +8,7 @@ LL | ref_str_argument(&String::new()); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_owned_empty_strings)]` error: usage of `&String::from("")` for a function expecting a `&str` argument - --> tests/ui/unnecessary_owned_empty_strings.rs:14:22 + --> tests/ui/unnecessary_owned_empty_strings.rs:15:22 | LL | ref_str_argument(&String::from("")); | ^^^^^^^^^^^^^^^^^ help: try: `""` diff --git a/tests/ui/unnecessary_result_map_or_else.fixed b/tests/ui/unnecessary_result_map_or_else.fixed index 224e0b52d75d..784a42a04ba8 100644 --- a/tests/ui/unnecessary_result_map_or_else.fixed +++ b/tests/ui/unnecessary_result_map_or_else.fixed @@ -3,16 +3,19 @@ fn main() { let x: Result<(), ()> = Ok(()); - x.unwrap_or_else(|err| err); //~ ERROR: unused "map closure" when calling +x.unwrap_or_else(|err| err); +//~^ unnecessary_result_map_or_else // Type ascribtion. let x: Result<(), ()> = Ok(()); - x.unwrap_or_else(|err: ()| err); //~ ERROR: unused "map closure" when calling +x.unwrap_or_else(|err: ()| err); +//~^ unnecessary_result_map_or_else // Auto-deref. let y = String::new(); let x: Result<&String, &String> = Ok(&y); - let y: &str = x.unwrap_or_else(|err| err); //~ ERROR: unused "map closure" when calling +let y: &str = x.unwrap_or_else(|err| err); +//~^ unnecessary_result_map_or_else // Temporary variable. let x: Result<(), ()> = Ok(()); diff --git a/tests/ui/unnecessary_result_map_or_else.rs b/tests/ui/unnecessary_result_map_or_else.rs index 4fe950a4cfa6..39b15f6d26d0 100644 --- a/tests/ui/unnecessary_result_map_or_else.rs +++ b/tests/ui/unnecessary_result_map_or_else.rs @@ -3,21 +3,25 @@ fn main() { let x: Result<(), ()> = Ok(()); - x.map_or_else(|err| err, |n| n); //~ ERROR: unused "map closure" when calling +x.map_or_else(|err| err, |n| n); +//~^ unnecessary_result_map_or_else // Type ascribtion. let x: Result<(), ()> = Ok(()); - x.map_or_else(|err: ()| err, |n: ()| n); //~ ERROR: unused "map closure" when calling +x.map_or_else(|err: ()| err, |n: ()| n); +//~^ unnecessary_result_map_or_else // Auto-deref. let y = String::new(); let x: Result<&String, &String> = Ok(&y); - let y: &str = x.map_or_else(|err| err, |n| n); //~ ERROR: unused "map closure" when calling +let y: &str = x.map_or_else(|err| err, |n| n); +//~^ unnecessary_result_map_or_else // Temporary variable. let x: Result<(), ()> = Ok(()); x.map_or_else( - //~^ ERROR: unused "map closure" when calling + //~^ unnecessary_result_map_or_else + |err| err, |n| { let tmp = n; diff --git a/tests/ui/unnecessary_result_map_or_else.stderr b/tests/ui/unnecessary_result_map_or_else.stderr index e3a6dbf8ecd8..6334fe5eca68 100644 --- a/tests/ui/unnecessary_result_map_or_else.stderr +++ b/tests/ui/unnecessary_result_map_or_else.stderr @@ -1,31 +1,31 @@ error: unused "map closure" when calling `Result::map_or_else` value - --> tests/ui/unnecessary_result_map_or_else.rs:6:5 + --> tests/ui/unnecessary_result_map_or_else.rs:6:1 | -LL | x.map_or_else(|err| err, |n| n); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)` +LL | x.map_or_else(|err| err, |n| n); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)` | = note: `-D clippy::unnecessary-result-map-or-else` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_result_map_or_else)]` error: unused "map closure" when calling `Result::map_or_else` value - --> tests/ui/unnecessary_result_map_or_else.rs:10:5 + --> tests/ui/unnecessary_result_map_or_else.rs:11:1 | -LL | x.map_or_else(|err: ()| err, |n: ()| n); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err: ()| err)` +LL | x.map_or_else(|err: ()| err, |n: ()| n); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err: ()| err)` error: unused "map closure" when calling `Result::map_or_else` value - --> tests/ui/unnecessary_result_map_or_else.rs:15:19 + --> tests/ui/unnecessary_result_map_or_else.rs:17:15 | -LL | let y: &str = x.map_or_else(|err| err, |n| n); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)` +LL | let y: &str = x.map_or_else(|err| err, |n| n); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)` error: unused "map closure" when calling `Result::map_or_else` value - --> tests/ui/unnecessary_result_map_or_else.rs:19:5 + --> tests/ui/unnecessary_result_map_or_else.rs:22:5 | LL | / x.map_or_else( LL | | +LL | | LL | | |err| err, -LL | | |n| { ... | LL | | }, LL | | ); diff --git a/tests/ui/unnecessary_safety_comment.rs b/tests/ui/unnecessary_safety_comment.rs index bdc6fa0f46bb..3bdeda2724c6 100644 --- a/tests/ui/unnecessary_safety_comment.rs +++ b/tests/ui/unnecessary_safety_comment.rs @@ -4,19 +4,24 @@ mod unsafe_items_invalid_comment { // SAFETY: const CONST: u32 = 0; - //~^ ERROR: constant item has unnecessary safety comment + //~^ unnecessary_safety_comment + // SAFETY: static STATIC: u32 = 0; - //~^ ERROR: static item has unnecessary safety comment + //~^ unnecessary_safety_comment + // SAFETY: struct Struct; - //~^ ERROR: struct has unnecessary safety comment + //~^ unnecessary_safety_comment + // SAFETY: enum Enum {} - //~^ ERROR: enum has unnecessary safety comment + //~^ unnecessary_safety_comment + // SAFETY: mod module {} - //~^ ERROR: module has unnecessary safety comment + //~^ unnecessary_safety_comment + } mod unnecessary_from_macro { @@ -36,6 +41,7 @@ mod unnecessary_from_macro { ($t:ty) => { // Safety: unnecessary impl T for $t {} + //~^ unnecessary_safety_comment }; } @@ -45,15 +51,18 @@ mod unnecessary_from_macro { fn unnecessary_on_stmt_and_expr() -> u32 { // SAFETY: unnecessary let num = 42; - //~^ ERROR: statement has unnecessary safety comment + //~^ unnecessary_safety_comment + // SAFETY: unnecessary if num > 24 {} - //~^ ERROR: statement has unnecessary safety comment + //~^ unnecessary_safety_comment + // SAFETY: unnecessary 24 - //~^ ERROR: expression has unnecessary safety comment + //~^ unnecessary_safety_comment + } mod issue_10084 { diff --git a/tests/ui/unnecessary_safety_comment.stderr b/tests/ui/unnecessary_safety_comment.stderr index 139ed769975b..3f9e35b095b9 100644 --- a/tests/ui/unnecessary_safety_comment.stderr +++ b/tests/ui/unnecessary_safety_comment.stderr @@ -13,55 +13,55 @@ LL | // SAFETY: = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` error: static item has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:9:5 + --> tests/ui/unnecessary_safety_comment.rs:10:5 | LL | static STATIC: u32 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:8:5 + --> tests/ui/unnecessary_safety_comment.rs:9:5 | LL | // SAFETY: | ^^^^^^^^^^ error: struct has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:12:5 + --> tests/ui/unnecessary_safety_comment.rs:14:5 | LL | struct Struct; | ^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:11:5 + --> tests/ui/unnecessary_safety_comment.rs:13:5 | LL | // SAFETY: | ^^^^^^^^^^ error: enum has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:15:5 + --> tests/ui/unnecessary_safety_comment.rs:18:5 | LL | enum Enum {} | ^^^^^^^^^^^^ | -help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:14:5 - | -LL | // SAFETY: - | ^^^^^^^^^^ - -error: module has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:18:5 - | -LL | mod module {} - | ^^^^^^^^^^^^^ - | help: consider removing the safety comment --> tests/ui/unnecessary_safety_comment.rs:17:5 | LL | // SAFETY: | ^^^^^^^^^^ +error: module has unnecessary safety comment + --> tests/ui/unnecessary_safety_comment.rs:22:5 + | +LL | mod module {} + | ^^^^^^^^^^^^^ + | +help: consider removing the safety comment + --> tests/ui/unnecessary_safety_comment.rs:21:5 + | +LL | // SAFETY: + | ^^^^^^^^^^ + error: impl has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:38:13 + --> tests/ui/unnecessary_safety_comment.rs:43:13 | LL | impl T for $t {} | ^^^^^^^^^^^^^^^^ @@ -70,44 +70,44 @@ LL | with_safety_comment!(i32); | ------------------------- in this macro invocation | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:37:13 + --> tests/ui/unnecessary_safety_comment.rs:42:13 | LL | // Safety: unnecessary | ^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `with_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: expression has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:55:5 + --> tests/ui/unnecessary_safety_comment.rs:63:5 | LL | 24 | ^^ | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:54:5 + --> tests/ui/unnecessary_safety_comment.rs:62:5 | LL | // SAFETY: unnecessary | ^^^^^^^^^^^^^^^^^^^^^^ error: statement has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:47:5 + --> tests/ui/unnecessary_safety_comment.rs:53:5 | LL | let num = 42; | ^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:46:5 + --> tests/ui/unnecessary_safety_comment.rs:52:5 | LL | // SAFETY: unnecessary | ^^^^^^^^^^^^^^^^^^^^^^ error: statement has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:51:5 + --> tests/ui/unnecessary_safety_comment.rs:58:5 | LL | if num > 24 {} | ^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:50:5 + --> tests/ui/unnecessary_safety_comment.rs:57:5 | LL | // SAFETY: unnecessary | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_self_imports.fixed b/tests/ui/unnecessary_self_imports.fixed index c265dcd2414f..0fd74705bde0 100644 --- a/tests/ui/unnecessary_self_imports.fixed +++ b/tests/ui/unnecessary_self_imports.fixed @@ -3,7 +3,9 @@ use std::collections::hash_map::{self, *}; use std::fs as alias; +//~^ unnecessary_self_imports use std::io::{self, Read}; use std::rc; +//~^ unnecessary_self_imports fn main() {} diff --git a/tests/ui/unnecessary_self_imports.rs b/tests/ui/unnecessary_self_imports.rs index c3fcf7c951a1..d09c5fcb8caa 100644 --- a/tests/ui/unnecessary_self_imports.rs +++ b/tests/ui/unnecessary_self_imports.rs @@ -3,7 +3,9 @@ use std::collections::hash_map::{self, *}; use std::fs::{self as alias}; +//~^ unnecessary_self_imports use std::io::{self, Read}; use std::rc::{self}; +//~^ unnecessary_self_imports fn main() {} diff --git a/tests/ui/unnecessary_self_imports.stderr b/tests/ui/unnecessary_self_imports.stderr index 9b143b48c9a6..1bb22c46a6c1 100644 --- a/tests/ui/unnecessary_self_imports.stderr +++ b/tests/ui/unnecessary_self_imports.stderr @@ -11,7 +11,7 @@ LL | use std::fs::{self as alias}; = help: to override `-D warnings` add `#[allow(clippy::unnecessary_self_imports)]` error: import ending with `::{self}` - --> tests/ui/unnecessary_self_imports.rs:7:1 + --> tests/ui/unnecessary_self_imports.rs:8:1 | LL | use std::rc::{self}; | ^^^^^^^^^----------- diff --git a/tests/ui/unnecessary_semicolon.edition2021.fixed b/tests/ui/unnecessary_semicolon.edition2021.fixed index 343c88b98155..1dcc6484a195 100644 --- a/tests/ui/unnecessary_semicolon.edition2021.fixed +++ b/tests/ui/unnecessary_semicolon.edition2021.fixed @@ -27,13 +27,15 @@ fn main() { if a == 2 { println!("This is weird"); } - //~^ ERROR: unnecessary semicolon + //~^ unnecessary_semicolon + a.match { 3 => println!("three"), _ => println!("not three"), } - //~^ ERROR: unnecessary semicolon + //~^ unnecessary_semicolon + } // This is a problem in edition 2021 and below @@ -45,6 +47,7 @@ fn borrow_issue() { }, None => {}, }; + //~[edition2024]^ unnecessary_semicolon } fn no_borrow_issue(a: u32, b: u32) { @@ -54,6 +57,7 @@ fn no_borrow_issue(a: u32, b: u32) { }, None => {}, } + //~^ unnecessary_semicolon } fn issue14100() -> bool { diff --git a/tests/ui/unnecessary_semicolon.edition2021.stderr b/tests/ui/unnecessary_semicolon.edition2021.stderr index ccff33084172..3299442a5c1d 100644 --- a/tests/ui/unnecessary_semicolon.edition2021.stderr +++ b/tests/ui/unnecessary_semicolon.edition2021.stderr @@ -8,13 +8,13 @@ LL | }; = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]` error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:35:6 + --> tests/ui/unnecessary_semicolon.rs:36:6 | LL | }; | ^ help: remove error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:56:6 + --> tests/ui/unnecessary_semicolon.rs:59:6 | LL | }; | ^ help: remove diff --git a/tests/ui/unnecessary_semicolon.edition2024.fixed b/tests/ui/unnecessary_semicolon.edition2024.fixed index 1cba5760eb0a..91eef8022ed2 100644 --- a/tests/ui/unnecessary_semicolon.edition2024.fixed +++ b/tests/ui/unnecessary_semicolon.edition2024.fixed @@ -27,13 +27,15 @@ fn main() { if a == 2 { println!("This is weird"); } - //~^ ERROR: unnecessary semicolon + //~^ unnecessary_semicolon + a.match { 3 => println!("three"), _ => println!("not three"), } - //~^ ERROR: unnecessary semicolon + //~^ unnecessary_semicolon + } // This is a problem in edition 2021 and below @@ -45,6 +47,7 @@ fn borrow_issue() { }, None => {}, } + //~[edition2024]^ unnecessary_semicolon } fn no_borrow_issue(a: u32, b: u32) { @@ -54,6 +57,7 @@ fn no_borrow_issue(a: u32, b: u32) { }, None => {}, } + //~^ unnecessary_semicolon } fn issue14100() -> bool { diff --git a/tests/ui/unnecessary_semicolon.edition2024.stderr b/tests/ui/unnecessary_semicolon.edition2024.stderr index 4e526af2147d..98adc2f0a0a2 100644 --- a/tests/ui/unnecessary_semicolon.edition2024.stderr +++ b/tests/ui/unnecessary_semicolon.edition2024.stderr @@ -8,19 +8,19 @@ LL | }; = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]` error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:35:6 + --> tests/ui/unnecessary_semicolon.rs:36:6 | LL | }; | ^ help: remove error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:47:6 + --> tests/ui/unnecessary_semicolon.rs:49:6 | LL | }; | ^ help: remove error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:56:6 + --> tests/ui/unnecessary_semicolon.rs:59:6 | LL | }; | ^ help: remove diff --git a/tests/ui/unnecessary_semicolon.rs b/tests/ui/unnecessary_semicolon.rs index 6abbbd79aaf2..6c48bfae14ce 100644 --- a/tests/ui/unnecessary_semicolon.rs +++ b/tests/ui/unnecessary_semicolon.rs @@ -27,13 +27,15 @@ fn main() { if a == 2 { println!("This is weird"); }; - //~^ ERROR: unnecessary semicolon + //~^ unnecessary_semicolon + a.match { 3 => println!("three"), _ => println!("not three"), }; - //~^ ERROR: unnecessary semicolon + //~^ unnecessary_semicolon + } // This is a problem in edition 2021 and below @@ -45,6 +47,7 @@ fn borrow_issue() { }, None => {}, }; + //~[edition2024]^ unnecessary_semicolon } fn no_borrow_issue(a: u32, b: u32) { @@ -54,6 +57,7 @@ fn no_borrow_issue(a: u32, b: u32) { }, None => {}, }; + //~^ unnecessary_semicolon } fn issue14100() -> bool { diff --git a/tests/ui/unnecessary_sort_by.fixed b/tests/ui/unnecessary_sort_by.fixed index 6b667e00c978..5255ab173efb 100644 --- a/tests/ui/unnecessary_sort_by.fixed +++ b/tests/ui/unnecessary_sort_by.fixed @@ -10,13 +10,19 @@ fn unnecessary_sort_by() { let mut vec: Vec = vec![3, 6, 1, 2, 5]; // Forward examples vec.sort(); + //~^ unnecessary_sort_by vec.sort_unstable(); + //~^ unnecessary_sort_by vec.sort_by_key(|a| (a + 5).abs()); + //~^ unnecessary_sort_by vec.sort_unstable_by_key(|a| id(-a)); + //~^ unnecessary_sort_by // Reverse examples vec.sort_by(|a, b| b.cmp(a)); // not linted to avoid suggesting `Reverse(b)` which would borrow vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs())); + //~^ unnecessary_sort_by vec.sort_unstable_by_key(|b| std::cmp::Reverse(id(-b))); + //~^ unnecessary_sort_by // Negative examples (shouldn't be changed) let c = &7; vec.sort_by(|a, b| (b - a).cmp(&(a - b))); @@ -27,7 +33,9 @@ fn unnecessary_sort_by() { // Vectors of references are fine as long as the resulting key does not borrow let mut vec: Vec<&&&isize> = vec![&&&3, &&&6, &&&1, &&&2, &&&5]; vec.sort_by_key(|a| (***a).abs()); + //~^ unnecessary_sort_by vec.sort_unstable_by_key(|a| (***a).abs()); + //~^ unnecessary_sort_by // `Reverse(b)` would borrow in the following cases, don't lint vec.sort_by(|a, b| b.cmp(a)); vec.sort_unstable_by(|a, b| b.cmp(a)); @@ -87,10 +95,14 @@ mod issue_6001 { // Forward args.sort_by_key(|a| a.name()); + //~^ unnecessary_sort_by args.sort_unstable_by_key(|a| a.name()); + //~^ unnecessary_sort_by // Reverse args.sort_by_key(|b| std::cmp::Reverse(b.name())); + //~^ unnecessary_sort_by args.sort_unstable_by_key(|b| std::cmp::Reverse(b.name())); + //~^ unnecessary_sort_by } } diff --git a/tests/ui/unnecessary_sort_by.rs b/tests/ui/unnecessary_sort_by.rs index 0ff20fb9ef28..65db7ca3f137 100644 --- a/tests/ui/unnecessary_sort_by.rs +++ b/tests/ui/unnecessary_sort_by.rs @@ -10,13 +10,19 @@ fn unnecessary_sort_by() { let mut vec: Vec = vec![3, 6, 1, 2, 5]; // Forward examples vec.sort_by(|a, b| a.cmp(b)); + //~^ unnecessary_sort_by vec.sort_unstable_by(|a, b| a.cmp(b)); + //~^ unnecessary_sort_by vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs())); + //~^ unnecessary_sort_by vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b))); + //~^ unnecessary_sort_by // Reverse examples vec.sort_by(|a, b| b.cmp(a)); // not linted to avoid suggesting `Reverse(b)` which would borrow vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs())); + //~^ unnecessary_sort_by vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a))); + //~^ unnecessary_sort_by // Negative examples (shouldn't be changed) let c = &7; vec.sort_by(|a, b| (b - a).cmp(&(a - b))); @@ -27,7 +33,9 @@ fn unnecessary_sort_by() { // Vectors of references are fine as long as the resulting key does not borrow let mut vec: Vec<&&&isize> = vec![&&&3, &&&6, &&&1, &&&2, &&&5]; vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs())); + //~^ unnecessary_sort_by vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs())); + //~^ unnecessary_sort_by // `Reverse(b)` would borrow in the following cases, don't lint vec.sort_by(|a, b| b.cmp(a)); vec.sort_unstable_by(|a, b| b.cmp(a)); @@ -87,10 +95,14 @@ mod issue_6001 { // Forward args.sort_by(|a, b| a.name().cmp(&b.name())); + //~^ unnecessary_sort_by args.sort_unstable_by(|a, b| a.name().cmp(&b.name())); + //~^ unnecessary_sort_by // Reverse args.sort_by(|a, b| b.name().cmp(&a.name())); + //~^ unnecessary_sort_by args.sort_unstable_by(|a, b| b.name().cmp(&a.name())); + //~^ unnecessary_sort_by } } diff --git a/tests/ui/unnecessary_sort_by.stderr b/tests/ui/unnecessary_sort_by.stderr index e2013a4e6f9d..9a38d3746da8 100644 --- a/tests/ui/unnecessary_sort_by.stderr +++ b/tests/ui/unnecessary_sort_by.stderr @@ -8,67 +8,67 @@ LL | vec.sort_by(|a, b| a.cmp(b)); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]` error: consider using `sort` - --> tests/ui/unnecessary_sort_by.rs:13:5 + --> tests/ui/unnecessary_sort_by.rs:14:5 | LL | vec.sort_unstable_by(|a, b| a.cmp(b)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable()` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:14:5 + --> tests/ui/unnecessary_sort_by.rs:16:5 | LL | vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (a + 5).abs())` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:15:5 + --> tests/ui/unnecessary_sort_by.rs:18:5 | LL | vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| id(-a))` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:18:5 + --> tests/ui/unnecessary_sort_by.rs:22:5 | LL | vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs()))` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:19:5 + --> tests/ui/unnecessary_sort_by.rs:24:5 | LL | vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|b| std::cmp::Reverse(id(-b)))` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:29:5 + --> tests/ui/unnecessary_sort_by.rs:35:5 | LL | vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (***a).abs())` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:30:5 + --> tests/ui/unnecessary_sort_by.rs:37:5 | LL | vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| (***a).abs())` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:89:9 + --> tests/ui/unnecessary_sort_by.rs:97:9 | LL | args.sort_by(|a, b| a.name().cmp(&b.name())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|a| a.name())` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:90:9 + --> tests/ui/unnecessary_sort_by.rs:99:9 | LL | args.sort_unstable_by(|a, b| a.name().cmp(&b.name())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_unstable_by_key(|a| a.name())` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:92:9 + --> tests/ui/unnecessary_sort_by.rs:102:9 | LL | args.sort_by(|a, b| b.name().cmp(&a.name())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|b| std::cmp::Reverse(b.name()))` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by.rs:93:9 + --> tests/ui/unnecessary_sort_by.rs:104:9 | LL | args.sort_unstable_by(|a, b| b.name().cmp(&a.name())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_unstable_by_key(|b| std::cmp::Reverse(b.name()))` diff --git a/tests/ui/unnecessary_sort_by_no_std.fixed b/tests/ui/unnecessary_sort_by_no_std.fixed index c7be000b820c..40e6aecd1b6d 100644 --- a/tests/ui/unnecessary_sort_by_no_std.fixed +++ b/tests/ui/unnecessary_sort_by_no_std.fixed @@ -8,6 +8,7 @@ fn issue_11524() -> Vec { // Should lint and suggest `vec.sort_by_key(|a| a + 1);` vec.sort_by_key(|a| a + 1); + //~^ unnecessary_sort_by vec } @@ -16,5 +17,6 @@ fn issue_11524_2() -> Vec { // Should lint and suggest `vec.sort_by_key(|b| core::cmp::Reverse(b + 1));` vec.sort_by_key(|b| core::cmp::Reverse(b + 1)); + //~^ unnecessary_sort_by vec } diff --git a/tests/ui/unnecessary_sort_by_no_std.rs b/tests/ui/unnecessary_sort_by_no_std.rs index 5f44be97c61f..184c90d959eb 100644 --- a/tests/ui/unnecessary_sort_by_no_std.rs +++ b/tests/ui/unnecessary_sort_by_no_std.rs @@ -8,6 +8,7 @@ fn issue_11524() -> Vec { // Should lint and suggest `vec.sort_by_key(|a| a + 1);` vec.sort_by(|a, b| (a + 1).cmp(&(b + 1))); + //~^ unnecessary_sort_by vec } @@ -16,5 +17,6 @@ fn issue_11524_2() -> Vec { // Should lint and suggest `vec.sort_by_key(|b| core::cmp::Reverse(b + 1));` vec.sort_by(|a, b| (b + 1).cmp(&(a + 1))); + //~^ unnecessary_sort_by vec } diff --git a/tests/ui/unnecessary_sort_by_no_std.stderr b/tests/ui/unnecessary_sort_by_no_std.stderr index a57fbc7a6328..de3ef4123514 100644 --- a/tests/ui/unnecessary_sort_by_no_std.stderr +++ b/tests/ui/unnecessary_sort_by_no_std.stderr @@ -8,7 +8,7 @@ LL | vec.sort_by(|a, b| (a + 1).cmp(&(b + 1))); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]` error: consider using `sort_by_key` - --> tests/ui/unnecessary_sort_by_no_std.rs:18:5 + --> tests/ui/unnecessary_sort_by_no_std.rs:19:5 | LL | vec.sort_by(|a, b| (b + 1).cmp(&(a + 1))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|b| core::cmp::Reverse(b + 1))` diff --git a/tests/ui/unnecessary_struct_initialization.fixed b/tests/ui/unnecessary_struct_initialization.fixed index b0e8f4546353..07dc90acfa30 100644 --- a/tests/ui/unnecessary_struct_initialization.fixed +++ b/tests/ui/unnecessary_struct_initialization.fixed @@ -35,6 +35,7 @@ impl Clone for V { fn clone(&self) -> Self { // Lint: `Self` implements `Copy` *self + //~^ unnecessary_struct_initialization } } @@ -42,9 +43,11 @@ fn main() { // Should lint: `a` would be consumed anyway let a = S { f: String::from("foo") }; let mut b = a; + //~^ unnecessary_struct_initialization // Should lint: `b` would be consumed, and is mutable let c = &mut b; + //~^ unnecessary_struct_initialization // Should not lint as `d` is not mutable let d = S { f: String::from("foo") }; @@ -53,6 +56,7 @@ fn main() { // Should lint as `f` would be consumed anyway let f = S { f: String::from("foo") }; let g = &f; + //~^ unnecessary_struct_initialization // Should lint: the result of an expression is mutable let h = &mut *Box::new(S { f: String::from("foo") }); @@ -77,6 +81,7 @@ fn main() { // Should lint: all fields of `q` would be consumed anyway let q = W { f1: 42, f2: 1337 }; let r = q; + //~^ unnecessary_struct_initialization // Should not lint: not all fields of `t` from same source let s = W { f1: 1337, f2: 42 }; @@ -88,6 +93,7 @@ fn main() { // Should lint: all fields of `v` would be consumed anyway let v = W { f1: 42, f2: 1337 }; let w = v; + //~^ unnecessary_struct_initialization // Should not lint: source differs between fields and base let x = W { f1: 42, f2: 1337 }; @@ -96,6 +102,7 @@ fn main() { // Should lint: range desugars to struct let r1 = 0..5; let r2 = r1; + //~^ unnecessary_struct_initialization references(); shorthand(); @@ -109,6 +116,7 @@ fn references() { // Should lint as `d` is a shared reference let c = W { f1: 42, f2: 1337 }; let d = &c; + //~^ unnecessary_struct_initialization // Should not lint as `e` is not mutable let e = W { f1: 42, f2: 1337 }; @@ -117,6 +125,7 @@ fn references() { // Should lint as `h` is a shared reference let g = W { f1: 42, f2: 1337 }; let h = &g; + //~^ unnecessary_struct_initialization // Should not lint as `j` is copy let i = V { f: 0x1701d }; diff --git a/tests/ui/unnecessary_struct_initialization.rs b/tests/ui/unnecessary_struct_initialization.rs index b0db71af4d4c..2b26bc413b8f 100644 --- a/tests/ui/unnecessary_struct_initialization.rs +++ b/tests/ui/unnecessary_struct_initialization.rs @@ -35,6 +35,7 @@ impl Clone for V { fn clone(&self) -> Self { // Lint: `Self` implements `Copy` Self { ..*self } + //~^ unnecessary_struct_initialization } } @@ -42,9 +43,11 @@ fn main() { // Should lint: `a` would be consumed anyway let a = S { f: String::from("foo") }; let mut b = S { ..a }; + //~^ unnecessary_struct_initialization // Should lint: `b` would be consumed, and is mutable let c = &mut S { ..b }; + //~^ unnecessary_struct_initialization // Should not lint as `d` is not mutable let d = S { f: String::from("foo") }; @@ -53,9 +56,11 @@ fn main() { // Should lint as `f` would be consumed anyway let f = S { f: String::from("foo") }; let g = &S { ..f }; + //~^ unnecessary_struct_initialization // Should lint: the result of an expression is mutable let h = &mut S { + //~^ unnecessary_struct_initialization ..*Box::new(S { f: String::from("foo") }) }; @@ -75,12 +80,14 @@ fn main() { // Should lint: the result of an expression is mutable and temporary let p = &mut T { + //~^ unnecessary_struct_initialization ..*Box::new(T { f: 5 }) }; // Should lint: all fields of `q` would be consumed anyway let q = W { f1: 42, f2: 1337 }; let r = W { f1: q.f1, f2: q.f2 }; + //~^ unnecessary_struct_initialization // Should not lint: not all fields of `t` from same source let s = W { f1: 1337, f2: 42 }; @@ -92,6 +99,7 @@ fn main() { // Should lint: all fields of `v` would be consumed anyway let v = W { f1: 42, f2: 1337 }; let w = W { f1: v.f1, ..v }; + //~^ unnecessary_struct_initialization // Should not lint: source differs between fields and base let x = W { f1: 42, f2: 1337 }; @@ -100,6 +108,7 @@ fn main() { // Should lint: range desugars to struct let r1 = 0..5; let r2 = r1.start..r1.end; + //~^ unnecessary_struct_initialization references(); shorthand(); @@ -113,6 +122,7 @@ fn references() { // Should lint as `d` is a shared reference let c = W { f1: 42, f2: 1337 }; let d = &W { f1: c.f1, f2: c.f2 }; + //~^ unnecessary_struct_initialization // Should not lint as `e` is not mutable let e = W { f1: 42, f2: 1337 }; @@ -121,6 +131,7 @@ fn references() { // Should lint as `h` is a shared reference let g = W { f1: 42, f2: 1337 }; let h = &W { f1: g.f1, ..g }; + //~^ unnecessary_struct_initialization // Should not lint as `j` is copy let i = V { f: 0x1701d }; diff --git a/tests/ui/unnecessary_struct_initialization.stderr b/tests/ui/unnecessary_struct_initialization.stderr index 56982cc0a39f..5177b3252547 100644 --- a/tests/ui/unnecessary_struct_initialization.stderr +++ b/tests/ui/unnecessary_struct_initialization.stderr @@ -8,67 +8,69 @@ LL | Self { ..*self } = help: to override `-D warnings` add `#[allow(clippy::unnecessary_struct_initialization)]` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:44:17 + --> tests/ui/unnecessary_struct_initialization.rs:45:17 | LL | let mut b = S { ..a }; | ^^^^^^^^^ help: replace with: `a` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:47:18 + --> tests/ui/unnecessary_struct_initialization.rs:49:18 | LL | let c = &mut S { ..b }; | ^^^^^^^^^ help: replace with: `b` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:55:14 + --> tests/ui/unnecessary_struct_initialization.rs:58:14 | LL | let g = &S { ..f }; | ^^^^^^^^^ help: replace with: `f` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:58:18 + --> tests/ui/unnecessary_struct_initialization.rs:62:18 | LL | let h = &mut S { | __________________^ +LL | | LL | | ..*Box::new(S { f: String::from("foo") }) LL | | }; | |_____^ help: replace with: `*Box::new(S { f: String::from("foo") })` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:77:18 + --> tests/ui/unnecessary_struct_initialization.rs:82:18 | LL | let p = &mut T { | __________________^ +LL | | LL | | ..*Box::new(T { f: 5 }) LL | | }; | |_____^ help: replace with: `*Box::new(T { f: 5 })` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:83:13 + --> tests/ui/unnecessary_struct_initialization.rs:89:13 | LL | let r = W { f1: q.f1, f2: q.f2 }; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `q` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:94:13 + --> tests/ui/unnecessary_struct_initialization.rs:101:13 | LL | let w = W { f1: v.f1, ..v }; | ^^^^^^^^^^^^^^^^^^^ help: replace with: `v` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:102:14 + --> tests/ui/unnecessary_struct_initialization.rs:110:14 | LL | let r2 = r1.start..r1.end; | ^^^^^^^^^^^^^^^^ help: replace with: `r1` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:115:14 + --> tests/ui/unnecessary_struct_initialization.rs:124:14 | LL | let d = &W { f1: c.f1, f2: c.f2 }; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `c` error: unnecessary struct building - --> tests/ui/unnecessary_struct_initialization.rs:123:14 + --> tests/ui/unnecessary_struct_initialization.rs:133:14 | LL | let h = &W { f1: g.f1, ..g }; | ^^^^^^^^^^^^^^^^^^^ help: replace with: `g` diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed index 027dac419375..a03bfb2eafe3 100644 --- a/tests/ui/unnecessary_to_owned.fixed +++ b/tests/ui/unnecessary_to_owned.fixed @@ -62,82 +62,151 @@ fn main() { let x_ref = &x; require_c_str(&Cow::from(c_str)); + //~^ unnecessary_to_owned require_c_str(c_str); + //~^ unnecessary_to_owned require_os_str(os_str); + //~^ unnecessary_to_owned require_os_str(&Cow::from(os_str)); + //~^ unnecessary_to_owned require_os_str(os_str); + //~^ unnecessary_to_owned require_path(path); + //~^ unnecessary_to_owned require_path(&Cow::from(path)); + //~^ unnecessary_to_owned require_path(path); + //~^ unnecessary_to_owned require_str(s); + //~^ unnecessary_to_owned require_str(&Cow::from(s)); + //~^ unnecessary_to_owned require_str(s); + //~^ unnecessary_to_owned require_str(x_ref.as_ref()); + //~^ unnecessary_to_owned require_slice(slice); + //~^ unnecessary_to_owned require_slice(&Cow::from(slice)); + //~^ unnecessary_to_owned require_slice(array.as_ref()); + //~^ unnecessary_to_owned require_slice(array_ref.as_ref()); + //~^ unnecessary_to_owned require_slice(slice); + //~^ unnecessary_to_owned require_slice(&x_ref.to_owned()); // No longer flagged because of #8759. require_x(&Cow::::Owned(x.clone())); + //~^ unnecessary_to_owned require_x(&x_ref.to_owned()); // No longer flagged because of #8759. require_deref_c_str(c_str); + //~^ unnecessary_to_owned require_deref_os_str(os_str); + //~^ unnecessary_to_owned require_deref_path(path); + //~^ unnecessary_to_owned require_deref_str(s); + //~^ unnecessary_to_owned require_deref_slice(slice); + //~^ unnecessary_to_owned require_impl_deref_c_str(c_str); + //~^ unnecessary_to_owned require_impl_deref_os_str(os_str); + //~^ unnecessary_to_owned require_impl_deref_path(path); + //~^ unnecessary_to_owned require_impl_deref_str(s); + //~^ unnecessary_to_owned require_impl_deref_slice(slice); + //~^ unnecessary_to_owned require_deref_str_slice(s, slice); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_deref_slice_str(slice, s); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_c_str(c_str); + //~^ unnecessary_to_owned require_as_ref_os_str(os_str); + //~^ unnecessary_to_owned require_as_ref_path(path); + //~^ unnecessary_to_owned require_as_ref_str(s); + //~^ unnecessary_to_owned require_as_ref_str(&x); + //~^ unnecessary_to_owned require_as_ref_slice(array); + //~^ unnecessary_to_owned require_as_ref_slice(array_ref); + //~^ unnecessary_to_owned require_as_ref_slice(slice); + //~^ unnecessary_to_owned require_impl_as_ref_c_str(c_str); + //~^ unnecessary_to_owned require_impl_as_ref_os_str(os_str); + //~^ unnecessary_to_owned require_impl_as_ref_path(path); + //~^ unnecessary_to_owned require_impl_as_ref_str(s); + //~^ unnecessary_to_owned require_impl_as_ref_str(&x); + //~^ unnecessary_to_owned require_impl_as_ref_slice(array); + //~^ unnecessary_to_owned require_impl_as_ref_slice(array_ref); + //~^ unnecessary_to_owned require_impl_as_ref_slice(slice); + //~^ unnecessary_to_owned require_as_ref_str_slice(s, array); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_str_slice(s, array_ref); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_str_slice(s, slice); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_slice_str(array, s); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_slice_str(array_ref, s); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_slice_str(slice, s); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned let _ = x.join(x_ref); + //~^ unnecessary_to_owned let _ = slice.iter().copied(); + //~^ unnecessary_to_owned let _ = slice.iter().copied(); + //~^ unnecessary_to_owned let _ = [std::path::PathBuf::new()][..].iter().cloned(); + //~^ unnecessary_to_owned let _ = [std::path::PathBuf::new()][..].iter().cloned(); + //~^ unnecessary_to_owned let _ = slice.iter().copied(); + //~^ unnecessary_to_owned let _ = slice.iter().copied(); + //~^ unnecessary_to_owned let _ = [std::path::PathBuf::new()][..].iter().cloned(); + //~^ unnecessary_to_owned let _ = [std::path::PathBuf::new()][..].iter().cloned(); + //~^ unnecessary_to_owned let _ = check_files(&[FileType::Account]); @@ -153,15 +222,23 @@ fn main() { // The following should be flagged by `redundant_clone`, but not by this lint. require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap()); + //~^ redundant_clone require_os_str(&OsString::from("x")); + //~^ redundant_clone require_path(&std::path::PathBuf::from("x")); + //~^ redundant_clone require_str(&String::from("x")); + //~^ redundant_clone require_slice(&[String::from("x")]); + //~^ redundant_clone let slice = [0u8; 1024]; let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8"); + //~^ unnecessary_to_owned let _ref_str: &str = core::str::from_utf8(b"foo").unwrap(); + //~^ unnecessary_to_owned let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap(); + //~^ unnecessary_to_owned // Expression is of type `&String`, can't suggest `str::from_utf8` here let _ref_string = &String::from_utf8(b"foo".to_vec()).unwrap(); macro_rules! arg_from_macro { @@ -219,6 +296,7 @@ fn require_as_ref_slice_str, V: AsRef>(_: U, _: V) {} // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 fn check_files(file_types: &[FileType]) -> bool { for t in file_types { + //~^ unnecessary_to_owned let path = match get_file_path(t) { Ok(p) => p, Err(_) => { @@ -242,11 +320,13 @@ fn require_string(_: &String) {} fn _msrv_1_35() { // `copied` was stabilized in 1.36, so clippy should use `cloned`. let _ = &["x"][..].iter().cloned(); + //~^ unnecessary_to_owned } #[clippy::msrv = "1.36"] fn _msrv_1_36() { let _ = &["x"][..].iter().copied(); + //~^ unnecessary_to_owned } // https://github.com/rust-lang/rust-clippy/issues/8507 @@ -295,6 +375,7 @@ mod issue_8507 { // Should lint because Y is copy. fn test_y(y: Y) -> Box { Box::new(build(y)) + //~^ unnecessary_to_owned } } @@ -404,6 +485,7 @@ mod issue_9351 { // Should lint fn single_return() -> impl AsRef { id("abc") + //~^ unnecessary_to_owned } // Should not lint @@ -547,6 +629,7 @@ mod issue_11952 { fn bar() { IntoFuture::into_future(foo([], &0)); + //~^ unnecessary_to_owned } } @@ -556,18 +639,23 @@ fn borrow_checks() { fn inner(a: &[&str]) { let mut s = HashSet::from([vec!["a"]]); - s.remove(a); //~ ERROR: unnecessary use of `to_vec` +s.remove(a); +//~^ unnecessary_to_owned } let mut s = HashSet::from(["a".to_string()]); - s.remove("b"); //~ ERROR: unnecessary use of `to_owned` - s.remove("b"); //~ ERROR: unnecessary use of `to_string` +s.remove("b"); +//~^ unnecessary_to_owned +s.remove("b"); +//~^ unnecessary_to_owned // Should not warn. s.remove("b"); let mut s = HashSet::from([vec!["a"]]); - s.remove(["b"].as_slice()); //~ ERROR: unnecessary use of `to_vec` - s.remove((&["b"]).as_slice()); //~ ERROR: unnecessary use of `to_vec` +s.remove(["b"].as_slice()); +//~^ unnecessary_to_owned +s.remove((&["b"]).as_slice()); +//~^ unnecessary_to_owned // Should not warn. s.remove(&["b"].to_vec().clone()); diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs index b89f3d552f84..a03b13d47565 100644 --- a/tests/ui/unnecessary_to_owned.rs +++ b/tests/ui/unnecessary_to_owned.rs @@ -62,82 +62,151 @@ fn main() { let x_ref = &x; require_c_str(&Cow::from(c_str).into_owned()); + //~^ unnecessary_to_owned require_c_str(&c_str.to_owned()); + //~^ unnecessary_to_owned require_os_str(&os_str.to_os_string()); + //~^ unnecessary_to_owned require_os_str(&Cow::from(os_str).into_owned()); + //~^ unnecessary_to_owned require_os_str(&os_str.to_owned()); + //~^ unnecessary_to_owned require_path(&path.to_path_buf()); + //~^ unnecessary_to_owned require_path(&Cow::from(path).into_owned()); + //~^ unnecessary_to_owned require_path(&path.to_owned()); + //~^ unnecessary_to_owned require_str(&s.to_string()); + //~^ unnecessary_to_owned require_str(&Cow::from(s).into_owned()); + //~^ unnecessary_to_owned require_str(&s.to_owned()); + //~^ unnecessary_to_owned require_str(&x_ref.to_string()); + //~^ unnecessary_to_owned require_slice(&slice.to_vec()); + //~^ unnecessary_to_owned require_slice(&Cow::from(slice).into_owned()); + //~^ unnecessary_to_owned require_slice(&array.to_owned()); + //~^ unnecessary_to_owned require_slice(&array_ref.to_owned()); + //~^ unnecessary_to_owned require_slice(&slice.to_owned()); + //~^ unnecessary_to_owned require_slice(&x_ref.to_owned()); // No longer flagged because of #8759. require_x(&Cow::::Owned(x.clone()).into_owned()); + //~^ unnecessary_to_owned require_x(&x_ref.to_owned()); // No longer flagged because of #8759. require_deref_c_str(c_str.to_owned()); + //~^ unnecessary_to_owned require_deref_os_str(os_str.to_owned()); + //~^ unnecessary_to_owned require_deref_path(path.to_owned()); + //~^ unnecessary_to_owned require_deref_str(s.to_owned()); + //~^ unnecessary_to_owned require_deref_slice(slice.to_owned()); + //~^ unnecessary_to_owned require_impl_deref_c_str(c_str.to_owned()); + //~^ unnecessary_to_owned require_impl_deref_os_str(os_str.to_owned()); + //~^ unnecessary_to_owned require_impl_deref_path(path.to_owned()); + //~^ unnecessary_to_owned require_impl_deref_str(s.to_owned()); + //~^ unnecessary_to_owned require_impl_deref_slice(slice.to_owned()); + //~^ unnecessary_to_owned require_deref_str_slice(s.to_owned(), slice.to_owned()); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_deref_slice_str(slice.to_owned(), s.to_owned()); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_c_str(c_str.to_owned()); + //~^ unnecessary_to_owned require_as_ref_os_str(os_str.to_owned()); + //~^ unnecessary_to_owned require_as_ref_path(path.to_owned()); + //~^ unnecessary_to_owned require_as_ref_str(s.to_owned()); + //~^ unnecessary_to_owned require_as_ref_str(x.to_owned()); + //~^ unnecessary_to_owned require_as_ref_slice(array.to_owned()); + //~^ unnecessary_to_owned require_as_ref_slice(array_ref.to_owned()); + //~^ unnecessary_to_owned require_as_ref_slice(slice.to_owned()); + //~^ unnecessary_to_owned require_impl_as_ref_c_str(c_str.to_owned()); + //~^ unnecessary_to_owned require_impl_as_ref_os_str(os_str.to_owned()); + //~^ unnecessary_to_owned require_impl_as_ref_path(path.to_owned()); + //~^ unnecessary_to_owned require_impl_as_ref_str(s.to_owned()); + //~^ unnecessary_to_owned require_impl_as_ref_str(x.to_owned()); + //~^ unnecessary_to_owned require_impl_as_ref_slice(array.to_owned()); + //~^ unnecessary_to_owned require_impl_as_ref_slice(array_ref.to_owned()); + //~^ unnecessary_to_owned require_impl_as_ref_slice(slice.to_owned()); + //~^ unnecessary_to_owned require_as_ref_str_slice(s.to_owned(), array.to_owned()); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_str_slice(s.to_owned(), slice.to_owned()); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_slice_str(array.to_owned(), s.to_owned()); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned require_as_ref_slice_str(slice.to_owned(), s.to_owned()); + //~^ unnecessary_to_owned + //~| unnecessary_to_owned let _ = x.join(&x_ref.to_string()); + //~^ unnecessary_to_owned let _ = slice.to_vec().into_iter(); + //~^ unnecessary_to_owned let _ = slice.to_owned().into_iter(); + //~^ unnecessary_to_owned let _ = [std::path::PathBuf::new()][..].to_vec().into_iter(); + //~^ unnecessary_to_owned let _ = [std::path::PathBuf::new()][..].to_owned().into_iter(); + //~^ unnecessary_to_owned let _ = IntoIterator::into_iter(slice.to_vec()); + //~^ unnecessary_to_owned let _ = IntoIterator::into_iter(slice.to_owned()); + //~^ unnecessary_to_owned let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec()); + //~^ unnecessary_to_owned let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned()); + //~^ unnecessary_to_owned let _ = check_files(&[FileType::Account]); @@ -153,15 +222,23 @@ fn main() { // The following should be flagged by `redundant_clone`, but not by this lint. require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); + //~^ redundant_clone require_os_str(&OsString::from("x").to_os_string()); + //~^ redundant_clone require_path(&std::path::PathBuf::from("x").to_path_buf()); + //~^ redundant_clone require_str(&String::from("x").to_string()); + //~^ redundant_clone require_slice(&[String::from("x")].to_owned()); + //~^ redundant_clone let slice = [0u8; 1024]; let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8"); + //~^ unnecessary_to_owned let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap(); + //~^ unnecessary_to_owned let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap(); + //~^ unnecessary_to_owned // Expression is of type `&String`, can't suggest `str::from_utf8` here let _ref_string = &String::from_utf8(b"foo".to_vec()).unwrap(); macro_rules! arg_from_macro { @@ -219,6 +296,7 @@ fn require_as_ref_slice_str, V: AsRef>(_: U, _: V) {} // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 fn check_files(file_types: &[FileType]) -> bool { for t in file_types.to_vec() { + //~^ unnecessary_to_owned let path = match get_file_path(&t) { Ok(p) => p, Err(_) => { @@ -242,11 +320,13 @@ fn require_string(_: &String) {} fn _msrv_1_35() { // `copied` was stabilized in 1.36, so clippy should use `cloned`. let _ = &["x"][..].to_vec().into_iter(); + //~^ unnecessary_to_owned } #[clippy::msrv = "1.36"] fn _msrv_1_36() { let _ = &["x"][..].to_vec().into_iter(); + //~^ unnecessary_to_owned } // https://github.com/rust-lang/rust-clippy/issues/8507 @@ -295,6 +375,7 @@ mod issue_8507 { // Should lint because Y is copy. fn test_y(y: Y) -> Box { Box::new(build(y.to_string())) + //~^ unnecessary_to_owned } } @@ -404,6 +485,7 @@ mod issue_9351 { // Should lint fn single_return() -> impl AsRef { id("abc".to_string()) + //~^ unnecessary_to_owned } // Should not lint @@ -547,6 +629,7 @@ mod issue_11952 { fn bar() { IntoFuture::into_future(foo([].to_vec(), &0)); + //~^ unnecessary_to_owned } } @@ -556,18 +639,23 @@ fn borrow_checks() { fn inner(a: &[&str]) { let mut s = HashSet::from([vec!["a"]]); - s.remove(&a.to_vec()); //~ ERROR: unnecessary use of `to_vec` +s.remove(&a.to_vec()); +//~^ unnecessary_to_owned } let mut s = HashSet::from(["a".to_string()]); - s.remove(&"b".to_owned()); //~ ERROR: unnecessary use of `to_owned` - s.remove(&"b".to_string()); //~ ERROR: unnecessary use of `to_string` +s.remove(&"b".to_owned()); +//~^ unnecessary_to_owned +s.remove(&"b".to_string()); +//~^ unnecessary_to_owned // Should not warn. s.remove("b"); let mut s = HashSet::from([vec!["a"]]); - s.remove(&["b"].to_vec()); //~ ERROR: unnecessary use of `to_vec` - s.remove(&(&["b"]).to_vec()); //~ ERROR: unnecessary use of `to_vec` +s.remove(&["b"].to_vec()); +//~^ unnecessary_to_owned +s.remove(&(&["b"]).to_vec()); +//~^ unnecessary_to_owned // Should not warn. s.remove(&["b"].to_vec().clone()); diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr index 498ac68cdaa0..23963fd6779a 100644 --- a/tests/ui/unnecessary_to_owned.stderr +++ b/tests/ui/unnecessary_to_owned.stderr @@ -1,11 +1,11 @@ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:155:64 + --> tests/ui/unnecessary_to_owned.rs:224:64 | LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:155:20 + --> tests/ui/unnecessary_to_owned.rs:224:20 | LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,49 +13,49 @@ LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()) = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]` error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:156:40 + --> tests/ui/unnecessary_to_owned.rs:226:40 | LL | require_os_str(&OsString::from("x").to_os_string()); | ^^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:156:21 + --> tests/ui/unnecessary_to_owned.rs:226:21 | LL | require_os_str(&OsString::from("x").to_os_string()); | ^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:157:48 + --> tests/ui/unnecessary_to_owned.rs:228:48 | LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); | ^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:157:19 + --> tests/ui/unnecessary_to_owned.rs:228:19 | LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:158:35 + --> tests/ui/unnecessary_to_owned.rs:230:35 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:158:18 + --> tests/ui/unnecessary_to_owned.rs:230:18 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:159:39 + --> tests/ui/unnecessary_to_owned.rs:232:39 | LL | require_slice(&[String::from("x")].to_owned()); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:159:20 + --> tests/ui/unnecessary_to_owned.rs:232:20 | LL | require_slice(&[String::from("x")].to_owned()); | ^^^^^^^^^^^^^^^^^^^ @@ -70,415 +70,415 @@ LL | require_c_str(&Cow::from(c_str).into_owned()); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:65:19 + --> tests/ui/unnecessary_to_owned.rs:66:19 | LL | require_c_str(&c_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_os_string` - --> tests/ui/unnecessary_to_owned.rs:67:20 + --> tests/ui/unnecessary_to_owned.rs:69:20 | LL | require_os_str(&os_str.to_os_string()); | ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:68:38 + --> tests/ui/unnecessary_to_owned.rs:71:38 | LL | require_os_str(&Cow::from(os_str).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:69:20 + --> tests/ui/unnecessary_to_owned.rs:73:20 | LL | require_os_str(&os_str.to_owned()); | ^^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_path_buf` - --> tests/ui/unnecessary_to_owned.rs:71:18 + --> tests/ui/unnecessary_to_owned.rs:76:18 | LL | require_path(&path.to_path_buf()); | ^^^^^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:72:34 + --> tests/ui/unnecessary_to_owned.rs:78:34 | LL | require_path(&Cow::from(path).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:73:18 + --> tests/ui/unnecessary_to_owned.rs:80:18 | LL | require_path(&path.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:75:17 + --> tests/ui/unnecessary_to_owned.rs:83:17 | LL | require_str(&s.to_string()); | ^^^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:76:30 + --> tests/ui/unnecessary_to_owned.rs:85:30 | LL | require_str(&Cow::from(s).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:77:17 + --> tests/ui/unnecessary_to_owned.rs:87:17 | LL | require_str(&s.to_owned()); | ^^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:78:17 + --> tests/ui/unnecessary_to_owned.rs:89:17 | LL | require_str(&x_ref.to_string()); | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:80:19 + --> tests/ui/unnecessary_to_owned.rs:92:19 | LL | require_slice(&slice.to_vec()); | ^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:81:36 + --> tests/ui/unnecessary_to_owned.rs:94:36 | LL | require_slice(&Cow::from(slice).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:82:19 + --> tests/ui/unnecessary_to_owned.rs:96:19 | LL | require_slice(&array.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:83:19 + --> tests/ui/unnecessary_to_owned.rs:98:19 | LL | require_slice(&array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:84:19 + --> tests/ui/unnecessary_to_owned.rs:100:19 | LL | require_slice(&slice.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:87:42 + --> tests/ui/unnecessary_to_owned.rs:104:42 | LL | require_x(&Cow::::Owned(x.clone()).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:90:25 + --> tests/ui/unnecessary_to_owned.rs:108:25 | LL | require_deref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:91:26 + --> tests/ui/unnecessary_to_owned.rs:110:26 | LL | require_deref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:92:24 + --> tests/ui/unnecessary_to_owned.rs:112:24 | LL | require_deref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:93:23 + --> tests/ui/unnecessary_to_owned.rs:114:23 | LL | require_deref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:94:25 + --> tests/ui/unnecessary_to_owned.rs:116:25 | LL | require_deref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:96:30 + --> tests/ui/unnecessary_to_owned.rs:119:30 | LL | require_impl_deref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:97:31 + --> tests/ui/unnecessary_to_owned.rs:121:31 | LL | require_impl_deref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:98:29 + --> tests/ui/unnecessary_to_owned.rs:123:29 | LL | require_impl_deref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:99:28 + --> tests/ui/unnecessary_to_owned.rs:125:28 | LL | require_impl_deref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:100:30 + --> tests/ui/unnecessary_to_owned.rs:127:30 | LL | require_impl_deref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:102:29 + --> tests/ui/unnecessary_to_owned.rs:130:29 | LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:102:43 + --> tests/ui/unnecessary_to_owned.rs:130:43 | LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:103:29 + --> tests/ui/unnecessary_to_owned.rs:133:29 | LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:103:47 + --> tests/ui/unnecessary_to_owned.rs:133:47 | LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:105:26 + --> tests/ui/unnecessary_to_owned.rs:137:26 | LL | require_as_ref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:106:27 + --> tests/ui/unnecessary_to_owned.rs:139:27 | LL | require_as_ref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:107:25 + --> tests/ui/unnecessary_to_owned.rs:141:25 | LL | require_as_ref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:108:24 + --> tests/ui/unnecessary_to_owned.rs:143:24 | LL | require_as_ref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:109:24 + --> tests/ui/unnecessary_to_owned.rs:145:24 | LL | require_as_ref_str(x.to_owned()); | ^^^^^^^^^^^^ help: use: `&x` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:110:26 + --> tests/ui/unnecessary_to_owned.rs:147:26 | LL | require_as_ref_slice(array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:111:26 + --> tests/ui/unnecessary_to_owned.rs:149:26 | LL | require_as_ref_slice(array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:112:26 + --> tests/ui/unnecessary_to_owned.rs:151:26 | LL | require_as_ref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:114:31 + --> tests/ui/unnecessary_to_owned.rs:154:31 | LL | require_impl_as_ref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:115:32 + --> tests/ui/unnecessary_to_owned.rs:156:32 | LL | require_impl_as_ref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:116:30 + --> tests/ui/unnecessary_to_owned.rs:158:30 | LL | require_impl_as_ref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:117:29 + --> tests/ui/unnecessary_to_owned.rs:160:29 | LL | require_impl_as_ref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:118:29 + --> tests/ui/unnecessary_to_owned.rs:162:29 | LL | require_impl_as_ref_str(x.to_owned()); | ^^^^^^^^^^^^ help: use: `&x` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:119:31 + --> tests/ui/unnecessary_to_owned.rs:164:31 | LL | require_impl_as_ref_slice(array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:120:31 + --> tests/ui/unnecessary_to_owned.rs:166:31 | LL | require_impl_as_ref_slice(array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:121:31 + --> tests/ui/unnecessary_to_owned.rs:168:31 | LL | require_impl_as_ref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:123:30 + --> tests/ui/unnecessary_to_owned.rs:171:30 | LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:123:44 + --> tests/ui/unnecessary_to_owned.rs:171:44 | LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:124:30 + --> tests/ui/unnecessary_to_owned.rs:174:30 | LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:124:44 + --> tests/ui/unnecessary_to_owned.rs:174:44 | LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:125:30 + --> tests/ui/unnecessary_to_owned.rs:177:30 | LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:125:44 + --> tests/ui/unnecessary_to_owned.rs:177:44 | LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:126:30 + --> tests/ui/unnecessary_to_owned.rs:180:30 | LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:126:48 + --> tests/ui/unnecessary_to_owned.rs:180:48 | LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:127:30 + --> tests/ui/unnecessary_to_owned.rs:183:30 | LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:127:52 + --> tests/ui/unnecessary_to_owned.rs:183:52 | LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:128:30 + --> tests/ui/unnecessary_to_owned.rs:186:30 | LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:128:48 + --> tests/ui/unnecessary_to_owned.rs:186:48 | LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:130:20 + --> tests/ui/unnecessary_to_owned.rs:190:20 | LL | let _ = x.join(&x_ref.to_string()); | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:132:13 + --> tests/ui/unnecessary_to_owned.rs:193:13 | LL | let _ = slice.to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:133:13 + --> tests/ui/unnecessary_to_owned.rs:195:13 | LL | let _ = slice.to_owned().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:134:13 + --> tests/ui/unnecessary_to_owned.rs:197:13 | LL | let _ = [std::path::PathBuf::new()][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:135:13 + --> tests/ui/unnecessary_to_owned.rs:199:13 | LL | let _ = [std::path::PathBuf::new()][..].to_owned().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:137:13 + --> tests/ui/unnecessary_to_owned.rs:202:13 | LL | let _ = IntoIterator::into_iter(slice.to_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:138:13 + --> tests/ui/unnecessary_to_owned.rs:204:13 | LL | let _ = IntoIterator::into_iter(slice.to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:139:13 + --> tests/ui/unnecessary_to_owned.rs:206:13 | LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:140:13 + --> tests/ui/unnecessary_to_owned.rs:208:13 | LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:162:26 + --> tests/ui/unnecessary_to_owned.rs:236:26 | LL | let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -490,7 +490,7 @@ LL + let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8"); | error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:163:26 + --> tests/ui/unnecessary_to_owned.rs:238:26 | LL | let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -502,7 +502,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo").unwrap(); | error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:164:26 + --> tests/ui/unnecessary_to_owned.rs:240:26 | LL | let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -514,7 +514,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap(); | error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:221:14 + --> tests/ui/unnecessary_to_owned.rs:298:14 | LL | for t in file_types.to_vec() { | ^^^^^^^^^^^^^^^^^^^ @@ -522,68 +522,69 @@ LL | for t in file_types.to_vec() { help: remove any references to the binding | LL ~ for t in file_types { +LL | LL ~ let path = match get_file_path(t) { | error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:244:14 + --> tests/ui/unnecessary_to_owned.rs:322:14 | LL | let _ = &["x"][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:249:14 + --> tests/ui/unnecessary_to_owned.rs:328:14 | LL | let _ = &["x"][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:297:24 + --> tests/ui/unnecessary_to_owned.rs:377:24 | LL | Box::new(build(y.to_string())) | ^^^^^^^^^^^^^ help: use: `y` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:406:12 + --> tests/ui/unnecessary_to_owned.rs:487:12 | LL | id("abc".to_string()) | ^^^^^^^^^^^^^^^^^ help: use: `"abc"` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:549:37 + --> tests/ui/unnecessary_to_owned.rs:631:37 | LL | IntoFuture::into_future(foo([].to_vec(), &0)); | ^^^^^^^^^^^ help: use: `[]` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:559:18 + --> tests/ui/unnecessary_to_owned.rs:642:10 | -LL | s.remove(&a.to_vec()); - | ^^^^^^^^^^^ help: replace it with: `a` +LL | s.remove(&a.to_vec()); + | ^^^^^^^^^^^ help: replace it with: `a` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:563:14 + --> tests/ui/unnecessary_to_owned.rs:647:10 | -LL | s.remove(&"b".to_owned()); - | ^^^^^^^^^^^^^^^ help: replace it with: `"b"` +LL | s.remove(&"b".to_owned()); + | ^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:564:14 + --> tests/ui/unnecessary_to_owned.rs:649:10 | -LL | s.remove(&"b".to_string()); - | ^^^^^^^^^^^^^^^^ help: replace it with: `"b"` +LL | s.remove(&"b".to_string()); + | ^^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:569:14 + --> tests/ui/unnecessary_to_owned.rs:655:10 | -LL | s.remove(&["b"].to_vec()); - | ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()` +LL | s.remove(&["b"].to_vec()); + | ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:570:14 + --> tests/ui/unnecessary_to_owned.rs:657:10 | -LL | s.remove(&(&["b"]).to_vec()); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()` +LL | s.remove(&(&["b"]).to_vec()); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()` error: aborting due to 88 previous errors diff --git a/tests/ui/unnecessary_to_owned_on_split.fixed b/tests/ui/unnecessary_to_owned_on_split.fixed index e0ba216f41bf..be453758ff3a 100644 --- a/tests/ui/unnecessary_to_owned_on_split.fixed +++ b/tests/ui/unnecessary_to_owned_on_split.fixed @@ -17,22 +17,31 @@ impl ToString for Issue12068 { fn main() { let _ = "a".split('a').next().unwrap(); - //~^ ERROR: unnecessary use of `to_string` + //~^ unnecessary_to_owned + let _ = "a".split("a").next().unwrap(); - //~^ ERROR: unnecessary use of `to_string` + //~^ unnecessary_to_owned + let _ = "a".split('a').next().unwrap(); - //~^ ERROR: unnecessary use of `to_owned` + //~^ unnecessary_to_owned + let _ = "a".split("a").next().unwrap(); - //~^ ERROR: unnecessary use of `to_owned` + //~^ unnecessary_to_owned + let _ = Issue12068.as_ref().split('a').next().unwrap(); - //~^ ERROR: unnecessary use of `to_string` + //~^ unnecessary_to_owned + let _ = [1].split(|x| *x == 2).next().unwrap(); - //~^ ERROR: unnecessary use of `to_vec` + //~^ unnecessary_to_owned + let _ = [1].split(|x| *x == 2).next().unwrap(); - //~^ ERROR: unnecessary use of `to_vec` + //~^ unnecessary_to_owned + let _ = [1].split(|x| *x == 2).next().unwrap(); - //~^ ERROR: unnecessary use of `to_owned` + //~^ unnecessary_to_owned + let _ = [1].split(|x| *x == 2).next().unwrap(); - //~^ ERROR: unnecessary use of `to_owned` + //~^ unnecessary_to_owned + } diff --git a/tests/ui/unnecessary_to_owned_on_split.rs b/tests/ui/unnecessary_to_owned_on_split.rs index 70efc6ebba5d..b6317db80d7c 100644 --- a/tests/ui/unnecessary_to_owned_on_split.rs +++ b/tests/ui/unnecessary_to_owned_on_split.rs @@ -17,22 +17,31 @@ impl ToString for Issue12068 { fn main() { let _ = "a".to_string().split('a').next().unwrap(); - //~^ ERROR: unnecessary use of `to_string` + //~^ unnecessary_to_owned + let _ = "a".to_string().split("a").next().unwrap(); - //~^ ERROR: unnecessary use of `to_string` + //~^ unnecessary_to_owned + let _ = "a".to_owned().split('a').next().unwrap(); - //~^ ERROR: unnecessary use of `to_owned` + //~^ unnecessary_to_owned + let _ = "a".to_owned().split("a").next().unwrap(); - //~^ ERROR: unnecessary use of `to_owned` + //~^ unnecessary_to_owned + let _ = Issue12068.to_string().split('a').next().unwrap(); - //~^ ERROR: unnecessary use of `to_string` + //~^ unnecessary_to_owned + let _ = [1].to_vec().split(|x| *x == 2).next().unwrap(); - //~^ ERROR: unnecessary use of `to_vec` + //~^ unnecessary_to_owned + let _ = [1].to_vec().split(|x| *x == 2).next().unwrap(); - //~^ ERROR: unnecessary use of `to_vec` + //~^ unnecessary_to_owned + let _ = [1].to_owned().split(|x| *x == 2).next().unwrap(); - //~^ ERROR: unnecessary use of `to_owned` + //~^ unnecessary_to_owned + let _ = [1].to_owned().split(|x| *x == 2).next().unwrap(); - //~^ ERROR: unnecessary use of `to_owned` + //~^ unnecessary_to_owned + } diff --git a/tests/ui/unnecessary_to_owned_on_split.stderr b/tests/ui/unnecessary_to_owned_on_split.stderr index cf5c964bcf3c..32cf52381d83 100644 --- a/tests/ui/unnecessary_to_owned_on_split.stderr +++ b/tests/ui/unnecessary_to_owned_on_split.stderr @@ -8,49 +8,49 @@ LL | let _ = "a".to_string().split('a').next().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned_on_split.rs:21:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:22:13 | LL | let _ = "a".to_string().split("a").next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `"a".split("a")` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned_on_split.rs:23:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:25:13 | LL | let _ = "a".to_owned().split('a').next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `"a".split('a')` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned_on_split.rs:25:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:28:13 | LL | let _ = "a".to_owned().split("a").next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `"a".split("a")` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned_on_split.rs:27:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:31:13 | LL | let _ = Issue12068.to_string().split('a').next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Issue12068.as_ref().split('a')` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned_on_split.rs:30:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:35:13 | LL | let _ = [1].to_vec().split(|x| *x == 2).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned_on_split.rs:32:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:38:13 | LL | let _ = [1].to_vec().split(|x| *x == 2).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned_on_split.rs:34:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:41:13 | LL | let _ = [1].to_owned().split(|x| *x == 2).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned_on_split.rs:36:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:44:13 | LL | let _ = [1].to_owned().split(|x| *x == 2).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)` diff --git a/tests/ui/unnecessary_unsafety_doc.rs b/tests/ui/unnecessary_unsafety_doc.rs index 5ad117eb8db6..2fe6c2b23a66 100644 --- a/tests/ui/unnecessary_unsafety_doc.rs +++ b/tests/ui/unnecessary_unsafety_doc.rs @@ -17,6 +17,7 @@ pub fn destroy_the_planet() { /// /// This function shouldn't be called unless the horsemen are ready pub fn apocalypse(universe: &mut ()) { +//~^ unnecessary_safety_doc unimplemented!(); } @@ -43,6 +44,7 @@ mod private_mod { /// /// Unnecessary safety! pub fn republished() { + //~^ unnecessary_safety_doc unimplemented!(); } } @@ -56,6 +58,7 @@ pub trait SafeTraitSafeMethods { /// /// Unnecessary! fn documented(self); + //~^ unnecessary_safety_doc } pub trait SafeTrait { @@ -66,6 +69,7 @@ pub trait SafeTrait { /// /// Unnecessary! pub trait DocumentedSafeTrait { +//~^ unnecessary_safety_doc fn method2(); } @@ -94,6 +98,7 @@ impl Struct { /// /// Unnecessary! pub fn documented() -> Self { + //~^ unnecessary_safety_doc unimplemented!(); } @@ -121,6 +126,7 @@ macro_rules! very_safe { /// /// Driving is very safe already! pub fn drive() { + //~^ unnecessary_safety_doc whee() } }; @@ -149,5 +155,6 @@ pub mod __macro { /// # Implementation safety pub trait DocumentedSafeTraitWithImplementationHeader { +//~^ unnecessary_safety_doc fn method(); } diff --git a/tests/ui/unnecessary_unsafety_doc.stderr b/tests/ui/unnecessary_unsafety_doc.stderr index d8a9f0aa38c3..dd9d8b65f75e 100644 --- a/tests/ui/unnecessary_unsafety_doc.stderr +++ b/tests/ui/unnecessary_unsafety_doc.stderr @@ -8,31 +8,31 @@ LL | pub fn apocalypse(universe: &mut ()) { = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_doc)]` error: safe function's docs have unnecessary `# Safety` section - --> tests/ui/unnecessary_unsafety_doc.rs:45:5 + --> tests/ui/unnecessary_unsafety_doc.rs:46:5 | LL | pub fn republished() { | ^^^^^^^^^^^^^^^^^^^^ error: safe function's docs have unnecessary `# Safety` section - --> tests/ui/unnecessary_unsafety_doc.rs:58:5 + --> tests/ui/unnecessary_unsafety_doc.rs:60:5 | LL | fn documented(self); | ^^^^^^^^^^^^^^^^^^^^ error: docs for safe trait have unnecessary `# Safety` section - --> tests/ui/unnecessary_unsafety_doc.rs:68:1 + --> tests/ui/unnecessary_unsafety_doc.rs:71:1 | LL | pub trait DocumentedSafeTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: safe function's docs have unnecessary `# Safety` section - --> tests/ui/unnecessary_unsafety_doc.rs:96:5 + --> tests/ui/unnecessary_unsafety_doc.rs:100:5 | LL | pub fn documented() -> Self { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: safe function's docs have unnecessary `# Safety` section - --> tests/ui/unnecessary_unsafety_doc.rs:123:9 + --> tests/ui/unnecessary_unsafety_doc.rs:128:9 | LL | pub fn drive() { | ^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL | very_safe!(); = note: this error originates in the macro `very_safe` (in Nightly builds, run with -Z macro-backtrace for more info) error: docs for safe trait have unnecessary `# Safety` section - --> tests/ui/unnecessary_unsafety_doc.rs:151:1 + --> tests/ui/unnecessary_unsafety_doc.rs:157:1 | LL | pub trait DocumentedSafeTraitWithImplementationHeader { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_wraps.rs b/tests/ui/unnecessary_wraps.rs index 200aefff1bbf..dee51ef67c3d 100644 --- a/tests/ui/unnecessary_wraps.rs +++ b/tests/ui/unnecessary_wraps.rs @@ -7,8 +7,9 @@ // should be linted fn func1(a: bool, b: bool) -> Option { - //~^ ERROR: this function's return value is unnecessarily wrapped by `Option` - //~| NOTE: `-D clippy::unnecessary-wraps` implied by `-D warnings` +//~^ unnecessary_wraps + + if a && b { return Some(42); } @@ -22,7 +23,8 @@ fn func1(a: bool, b: bool) -> Option { // should be linted fn func2(a: bool, b: bool) -> Option { - //~^ ERROR: this function's return value is unnecessarily wrapped by `Option` +//~^ unnecessary_wraps + if a && b { return Some(10); } @@ -41,7 +43,8 @@ fn func4(a: bool) -> Option { // should be linted fn func5() -> Option { - //~^ ERROR: this function's return value is unnecessarily wrapped by `Option` +//~^ unnecessary_wraps + Some(1) } @@ -52,7 +55,8 @@ fn func6() -> Option { // should be linted fn func7() -> Result { - //~^ ERROR: this function's return value is unnecessarily wrapped by `Result` +//~^ unnecessary_wraps + Ok(1) } @@ -81,7 +85,8 @@ impl A { // should be linted fn func12() -> Option { - //~^ ERROR: this function's return value is unnecessarily wrapped by `Option` + //~^ unnecessary_wraps + Some(1) } } @@ -109,7 +114,8 @@ fn issue_6384(s: &str) -> Option<&str> { // should be linted fn issue_6640_1(a: bool, b: bool) -> Option<()> { - //~^ ERROR: this function's return value is unnecessary +//~^ unnecessary_wraps + if a && b { return Some(()); } @@ -123,7 +129,8 @@ fn issue_6640_1(a: bool, b: bool) -> Option<()> { // should be linted fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { - //~^ ERROR: this function's return value is unnecessary +//~^ unnecessary_wraps + if a && b { return Ok(()); } diff --git a/tests/ui/unnecessary_wraps.stderr b/tests/ui/unnecessary_wraps.stderr index b304d4dce6ea..c193c4cf91ad 100644 --- a/tests/ui/unnecessary_wraps.stderr +++ b/tests/ui/unnecessary_wraps.stderr @@ -2,9 +2,6 @@ error: this function's return value is unnecessarily wrapped by `Option` --> tests/ui/unnecessary_wraps.rs:9:1 | LL | / fn func1(a: bool, b: bool) -> Option { -LL | | -LL | | -LL | | if a && b { ... | LL | | } | |_^ @@ -27,13 +24,13 @@ LL ~ return 1337; | error: this function's return value is unnecessarily wrapped by `Option` - --> tests/ui/unnecessary_wraps.rs:24:1 + --> tests/ui/unnecessary_wraps.rs:25:1 | LL | / fn func2(a: bool, b: bool) -> Option { LL | | +LL | | LL | | if a && b { -LL | | return Some(10); -LL | | } +... | LL | | if a { Some(20) } else { Some(30) } LL | | } | |_^ @@ -50,10 +47,11 @@ LL ~ if a { 20 } else { 30 } | error: this function's return value is unnecessarily wrapped by `Option` - --> tests/ui/unnecessary_wraps.rs:43:1 + --> tests/ui/unnecessary_wraps.rs:45:1 | LL | / fn func5() -> Option { LL | | +LL | | LL | | Some(1) LL | | } | |_^ @@ -68,10 +66,11 @@ LL | 1 | error: this function's return value is unnecessarily wrapped by `Result` - --> tests/ui/unnecessary_wraps.rs:54:1 + --> tests/ui/unnecessary_wraps.rs:57:1 | LL | / fn func7() -> Result { LL | | +LL | | LL | | Ok(1) LL | | } | |_^ @@ -86,10 +85,11 @@ LL | 1 | error: this function's return value is unnecessarily wrapped by `Option` - --> tests/ui/unnecessary_wraps.rs:83:5 + --> tests/ui/unnecessary_wraps.rs:87:5 | LL | / fn func12() -> Option { LL | | +LL | | LL | | Some(1) LL | | } | |_____^ @@ -104,12 +104,12 @@ LL | 1 | error: this function's return value is unnecessary - --> tests/ui/unnecessary_wraps.rs:111:1 + --> tests/ui/unnecessary_wraps.rs:116:1 | LL | / fn issue_6640_1(a: bool, b: bool) -> Option<()> { LL | | +LL | | LL | | if a && b { -LL | | return Some(()); ... | LL | | } | |_^ @@ -130,12 +130,12 @@ LL ~ return ; | error: this function's return value is unnecessary - --> tests/ui/unnecessary_wraps.rs:125:1 + --> tests/ui/unnecessary_wraps.rs:131:1 | LL | / fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { LL | | +LL | | LL | | if a && b { -LL | | return Ok(()); ... | LL | | } | |_^ diff --git a/tests/ui/unneeded_field_pattern.rs b/tests/ui/unneeded_field_pattern.rs index 1d42f81711bd..e4f6a704024b 100644 --- a/tests/ui/unneeded_field_pattern.rs +++ b/tests/ui/unneeded_field_pattern.rs @@ -16,8 +16,10 @@ fn main() { match f { Foo { a: _, b: 0, .. } => {}, + //~^ unneeded_field_pattern Foo { a: _, b: _, c: _ } => {}, + //~^ unneeded_field_pattern } match f { Foo { b: 0, .. } => {}, // should be OK diff --git a/tests/ui/unneeded_field_pattern.stderr b/tests/ui/unneeded_field_pattern.stderr index 4ea33a5db9e2..27e10f129dd6 100644 --- a/tests/ui/unneeded_field_pattern.stderr +++ b/tests/ui/unneeded_field_pattern.stderr @@ -9,7 +9,7 @@ LL | Foo { a: _, b: 0, .. } => {}, = help: to override `-D warnings` add `#[allow(clippy::unneeded_field_pattern)]` error: all the struct fields are matched to a wildcard pattern, consider using `..` - --> tests/ui/unneeded_field_pattern.rs:20:9 + --> tests/ui/unneeded_field_pattern.rs:21:9 | LL | Foo { a: _, b: _, c: _ } => {}, | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unneeded_struct_pattern.fixed b/tests/ui/unneeded_struct_pattern.fixed index 5bd269896a6b..3f24094ff316 100644 --- a/tests/ui/unneeded_struct_pattern.fixed +++ b/tests/ui/unneeded_struct_pattern.fixed @@ -2,7 +2,8 @@ #![allow( clippy::manual_unwrap_or_default, clippy::manual_unwrap_or, - clippy::redundant_pattern_matching + clippy::redundant_pattern_matching, + clippy::no_effect )] #![warn(clippy::unneeded_struct_pattern)] @@ -15,11 +16,13 @@ fn main() { match Some(114514) { Some(v) => v, None => 0, + //~^ unneeded_struct_pattern }; match Some(1919810) { Some(v) => v, None => 0, + //~^ unneeded_struct_pattern }; match Some(123456) { @@ -30,15 +33,23 @@ fn main() { match Some(Some(123456)) { Some(Some(v)) => v, Some(None) => 0, + //~^ unneeded_struct_pattern None => 0, + //~^ unneeded_struct_pattern }; if let None = Some(0) {} + //~^ unneeded_struct_pattern if let None = Some(0) {} + //~^ unneeded_struct_pattern if let Some(None) = Some(Some(0)) {} + //~^ unneeded_struct_pattern let None = Some(0) else { panic!() }; + //~^ unneeded_struct_pattern let None = Some(0) else { panic!() }; + //~^ unneeded_struct_pattern let Some(None) = Some(Some(0)) else { panic!() }; + //~^ unneeded_struct_pattern enum Custom { HasFields { @@ -54,28 +65,19 @@ fn main() { match Custom::Init { Custom::HasFields { field: value } => value, Custom::HasBracketsNoFields {} => 0, - Custom::NoBrackets => 0, //~ ERROR: struct pattern is not needed for a unit variant - Custom::NoBracketsNonExhaustive => 0, //~ ERROR: struct pattern is not needed for a unit variant _ => 0, }; match Custom::Init { Custom::HasFields { field: value } => value, Custom::HasBracketsNoFields { .. } => 0, - Custom::NoBrackets => 0, //~ ERROR: struct pattern is not needed for a unit variant - Custom::NoBracketsNonExhaustive => 0, //~ ERROR: struct pattern is not needed for a unit variant _ => 0, }; - match Custom::Init { - Custom::NoBrackets if true => 0, //~ ERROR: struct pattern is not needed for a unit variant - _ => 0, - }; + 0; + //~^^^ match_single_binding - match Custom::Init { - Custom::NoBrackets | Custom::NoBracketsNonExhaustive => 0, //~ ERROR: struct pattern is not needed for a unit variant - _ => 0, - }; + 0; if let Custom::HasFields { field: value } = Custom::Init { noop(); @@ -87,23 +89,24 @@ fn main() { noop(); } if let Custom::NoBrackets = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBrackets = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBrackets | Custom::NoBracketsNonExhaustive = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern + //~| unneeded_struct_pattern noop(); } if let Custom::NoBracketsNonExhaustive = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBracketsNonExhaustive = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern noop(); } @@ -118,18 +121,17 @@ fn main() { let Custom::HasBracketsNoFields { .. } = Custom::Init else { panic!() }; - let Custom::NoBrackets = Custom::Init else { panic!() }; //~ ERROR: struct pattern is not needed for a unit variant let Custom::NoBrackets = Custom::Init else { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern panic!() }; let Custom::NoBracketsNonExhaustive = Custom::Init else { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern panic!() }; let Custom::NoBracketsNonExhaustive = Custom::Init else { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern panic!() }; @@ -137,11 +139,7 @@ fn main() { Variant, } - fn pat_in_fn_param_1(Refutable::Variant: Refutable) {} //~ ERROR: struct pattern is not needed for a unit variant - fn pat_in_fn_param_2(Refutable::Variant: Refutable) {} //~ ERROR: struct pattern is not needed for a unit variant - for Refutable::Variant in [] {} //~ ERROR: struct pattern is not needed for a unit variant - for Refutable::Variant in [] {} //~ ERROR: struct pattern is not needed for a unit variant } fn external_crate() { @@ -153,17 +151,9 @@ fn external_crate() { _ => 0, }; - match ExhaustiveUnit { - // Exhaustive variant - ExhaustiveUnit => 0, //~ ERROR: struct pattern is not needed for a unit variant - _ => 0, - }; + 0; - match ExhaustiveUnit { - // Exhaustive variant - ExhaustiveUnit => 0, //~ ERROR: struct pattern is not needed for a unit variant - _ => 0, - }; + 0; match ExhaustiveUnit { ExhaustiveUnit => 0, diff --git a/tests/ui/unneeded_struct_pattern.rs b/tests/ui/unneeded_struct_pattern.rs index c7658617ad37..0e6ae5124822 100644 --- a/tests/ui/unneeded_struct_pattern.rs +++ b/tests/ui/unneeded_struct_pattern.rs @@ -2,7 +2,8 @@ #![allow( clippy::manual_unwrap_or_default, clippy::manual_unwrap_or, - clippy::redundant_pattern_matching + clippy::redundant_pattern_matching, + clippy::no_effect )] #![warn(clippy::unneeded_struct_pattern)] @@ -15,11 +16,13 @@ fn main() { match Some(114514) { Some(v) => v, None {} => 0, + //~^ unneeded_struct_pattern }; match Some(1919810) { Some(v) => v, None { .. } => 0, + //~^ unneeded_struct_pattern }; match Some(123456) { @@ -30,15 +33,23 @@ fn main() { match Some(Some(123456)) { Some(Some(v)) => v, Some(None {}) => 0, + //~^ unneeded_struct_pattern None {} => 0, + //~^ unneeded_struct_pattern }; if let None {} = Some(0) {} + //~^ unneeded_struct_pattern if let None { .. } = Some(0) {} + //~^ unneeded_struct_pattern if let Some(None {}) = Some(Some(0)) {} + //~^ unneeded_struct_pattern let None {} = Some(0) else { panic!() }; + //~^ unneeded_struct_pattern let None { .. } = Some(0) else { panic!() }; + //~^ unneeded_struct_pattern let Some(None {}) = Some(Some(0)) else { panic!() }; + //~^ unneeded_struct_pattern enum Custom { HasFields { @@ -54,26 +65,22 @@ fn main() { match Custom::Init { Custom::HasFields { field: value } => value, Custom::HasBracketsNoFields {} => 0, - Custom::NoBrackets {} => 0, //~ ERROR: struct pattern is not needed for a unit variant - Custom::NoBracketsNonExhaustive {} => 0, //~ ERROR: struct pattern is not needed for a unit variant _ => 0, }; match Custom::Init { Custom::HasFields { field: value } => value, Custom::HasBracketsNoFields { .. } => 0, - Custom::NoBrackets { .. } => 0, //~ ERROR: struct pattern is not needed for a unit variant - Custom::NoBracketsNonExhaustive { .. } => 0, //~ ERROR: struct pattern is not needed for a unit variant _ => 0, }; match Custom::Init { - Custom::NoBrackets {} if true => 0, //~ ERROR: struct pattern is not needed for a unit variant _ => 0, }; + //~^^^ match_single_binding match Custom::Init { - Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0, //~ ERROR: struct pattern is not needed for a unit variant + //~^ match_single_binding _ => 0, }; @@ -87,23 +94,24 @@ fn main() { noop(); } if let Custom::NoBrackets {} = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBrackets { .. } = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern + //~| unneeded_struct_pattern noop(); } if let Custom::NoBracketsNonExhaustive {} = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBracketsNonExhaustive { .. } = Custom::Init { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern noop(); } @@ -118,18 +126,17 @@ fn main() { let Custom::HasBracketsNoFields { .. } = Custom::Init else { panic!() }; - let Custom::NoBrackets {} = Custom::Init else { panic!() }; //~ ERROR: struct pattern is not needed for a unit variant let Custom::NoBrackets { .. } = Custom::Init else { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern panic!() }; let Custom::NoBracketsNonExhaustive {} = Custom::Init else { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern panic!() }; let Custom::NoBracketsNonExhaustive { .. } = Custom::Init else { - //~^ ERROR: struct pattern is not needed for a unit variant + //~^ unneeded_struct_pattern panic!() }; @@ -137,11 +144,7 @@ fn main() { Variant, } - fn pat_in_fn_param_1(Refutable::Variant {}: Refutable) {} //~ ERROR: struct pattern is not needed for a unit variant - fn pat_in_fn_param_2(Refutable::Variant { .. }: Refutable) {} //~ ERROR: struct pattern is not needed for a unit variant - for Refutable::Variant {} in [] {} //~ ERROR: struct pattern is not needed for a unit variant - for Refutable::Variant { .. } in [] {} //~ ERROR: struct pattern is not needed for a unit variant } fn external_crate() { @@ -154,14 +157,14 @@ fn external_crate() { }; match ExhaustiveUnit { + //~^ match_single_binding // Exhaustive variant - ExhaustiveUnit { .. } => 0, //~ ERROR: struct pattern is not needed for a unit variant _ => 0, }; match ExhaustiveUnit { + //~^ match_single_binding // Exhaustive variant - ExhaustiveUnit {} => 0, //~ ERROR: struct pattern is not needed for a unit variant _ => 0, }; diff --git a/tests/ui/unneeded_struct_pattern.stderr b/tests/ui/unneeded_struct_pattern.stderr index 3a7f59583802..9fd698ebf861 100644 --- a/tests/ui/unneeded_struct_pattern.stderr +++ b/tests/ui/unneeded_struct_pattern.stderr @@ -1,5 +1,5 @@ error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:17:13 + --> tests/ui/unneeded_struct_pattern.rs:18:13 | LL | None {} => 0, | ^^^ help: remove the struct pattern @@ -8,196 +8,152 @@ LL | None {} => 0, = help: to override `-D warnings` add `#[allow(clippy::unneeded_struct_pattern)]` error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:22:13 + --> tests/ui/unneeded_struct_pattern.rs:24:13 | LL | None { .. } => 0, | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:32:18 + --> tests/ui/unneeded_struct_pattern.rs:35:18 | LL | Some(None {}) => 0, | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:33:13 + --> tests/ui/unneeded_struct_pattern.rs:37:13 | LL | None {} => 0, | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:36:16 + --> tests/ui/unneeded_struct_pattern.rs:41:16 | LL | if let None {} = Some(0) {} | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:37:16 + --> tests/ui/unneeded_struct_pattern.rs:43:16 | LL | if let None { .. } = Some(0) {} | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:38:21 + --> tests/ui/unneeded_struct_pattern.rs:45:21 | LL | if let Some(None {}) = Some(Some(0)) {} | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:39:13 + --> tests/ui/unneeded_struct_pattern.rs:47:13 | LL | let None {} = Some(0) else { panic!() }; | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:40:13 + --> tests/ui/unneeded_struct_pattern.rs:49:13 | LL | let None { .. } = Some(0) else { panic!() }; | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:41:18 + --> tests/ui/unneeded_struct_pattern.rs:51:18 | LL | let Some(None {}) = Some(Some(0)) else { panic!() }; | ^^^ help: remove the struct pattern -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:57:27 +error: this match could be replaced by its body itself + --> tests/ui/unneeded_struct_pattern.rs:77:5 | -LL | Custom::NoBrackets {} => 0, - | ^^^ help: remove the struct pattern +LL | / match Custom::Init { +LL | | _ => 0, +LL | | }; + | |_____^ help: consider using the match body instead: `0` + | + = note: `-D clippy::match-single-binding` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::match_single_binding)]` + +error: this match could be replaced by its body itself + --> tests/ui/unneeded_struct_pattern.rs:82:5 + | +LL | / match Custom::Init { +LL | | +LL | | _ => 0, +LL | | }; + | |_____^ help: consider using the match body instead: `0` error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:58:40 - | -LL | Custom::NoBracketsNonExhaustive {} => 0, - | ^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:65:27 - | -LL | Custom::NoBrackets { .. } => 0, - | ^^^^^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:66:40 - | -LL | Custom::NoBracketsNonExhaustive { .. } => 0, - | ^^^^^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:71:27 - | -LL | Custom::NoBrackets {} if true => 0, - | ^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:76:27 - | -LL | Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0, - | ^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:76:64 - | -LL | Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0, - | ^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:89:30 + --> tests/ui/unneeded_struct_pattern.rs:96:30 | LL | if let Custom::NoBrackets {} = Custom::Init { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:93:30 + --> tests/ui/unneeded_struct_pattern.rs:100:30 | LL | if let Custom::NoBrackets { .. } = Custom::Init { | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:97:30 + --> tests/ui/unneeded_struct_pattern.rs:104:30 | LL | if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:97:67 + --> tests/ui/unneeded_struct_pattern.rs:104:67 | LL | if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:101:43 + --> tests/ui/unneeded_struct_pattern.rs:109:43 | LL | if let Custom::NoBracketsNonExhaustive {} = Custom::Init { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:105:43 + --> tests/ui/unneeded_struct_pattern.rs:113:43 | LL | if let Custom::NoBracketsNonExhaustive { .. } = Custom::Init { | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:121:27 - | -LL | let Custom::NoBrackets {} = Custom::Init else { panic!() }; - | ^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:123:27 + --> tests/ui/unneeded_struct_pattern.rs:130:27 | LL | let Custom::NoBrackets { .. } = Custom::Init else { | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:127:40 + --> tests/ui/unneeded_struct_pattern.rs:134:40 | LL | let Custom::NoBracketsNonExhaustive {} = Custom::Init else { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:131:40 + --> tests/ui/unneeded_struct_pattern.rs:138:40 | LL | let Custom::NoBracketsNonExhaustive { .. } = Custom::Init else { | ^^^^^^^ help: remove the struct pattern -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:140:44 +error: this match could be replaced by its body itself + --> tests/ui/unneeded_struct_pattern.rs:159:5 | -LL | fn pat_in_fn_param_1(Refutable::Variant {}: Refutable) {} - | ^^^ help: remove the struct pattern +LL | / match ExhaustiveUnit { +LL | | +LL | | // Exhaustive variant +LL | | _ => 0, +LL | | }; + | |_____^ help: consider using the match body instead: `0` -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:141:44 +error: this match could be replaced by its body itself + --> tests/ui/unneeded_struct_pattern.rs:165:5 | -LL | fn pat_in_fn_param_2(Refutable::Variant { .. }: Refutable) {} - | ^^^^^^^ help: remove the struct pattern +LL | / match ExhaustiveUnit { +LL | | +LL | | // Exhaustive variant +LL | | _ => 0, +LL | | }; + | |_____^ help: consider using the match body instead: `0` -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:143:27 - | -LL | for Refutable::Variant {} in [] {} - | ^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:144:27 - | -LL | for Refutable::Variant { .. } in [] {} - | ^^^^^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:158:23 - | -LL | ExhaustiveUnit { .. } => 0, - | ^^^^^^^ help: remove the struct pattern - -error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:164:23 - | -LL | ExhaustiveUnit {} => 0, - | ^^^ help: remove the struct pattern - -error: aborting due to 33 previous errors +error: aborting due to 23 previous errors diff --git a/tests/ui/unneeded_wildcard_pattern.fixed b/tests/ui/unneeded_wildcard_pattern.fixed index cbf91ed4910a..7e6a493b86c1 100644 --- a/tests/ui/unneeded_wildcard_pattern.fixed +++ b/tests/ui/unneeded_wildcard_pattern.fixed @@ -10,11 +10,17 @@ fn main() { let t = (0, 1, 2, 3); if let (0, ..) = t {}; + //~^ unneeded_wildcard_pattern if let (0, ..) = t {}; + //~^ unneeded_wildcard_pattern if let (.., 0) = t {}; + //~^ unneeded_wildcard_pattern if let (.., 0) = t {}; + //~^ unneeded_wildcard_pattern if let (0, ..) = t {}; + //~^ unneeded_wildcard_pattern if let (0, ..) = t {}; + //~^ unneeded_wildcard_pattern if let (_, 0, ..) = t {}; if let (.., 0, _) = t {}; if let (0, _, _, _) = t {}; @@ -24,6 +30,7 @@ fn main() { #[rustfmt::skip] { if let (0, ..,) = t {}; + //~^ unneeded_wildcard_pattern } struct S(usize, usize, usize, usize); @@ -31,11 +38,17 @@ fn main() { let s = S(0, 1, 2, 3); if let S(0, ..) = s {}; + //~^ unneeded_wildcard_pattern if let S(0, ..) = s {}; + //~^ unneeded_wildcard_pattern if let S(.., 0) = s {}; + //~^ unneeded_wildcard_pattern if let S(.., 0) = s {}; + //~^ unneeded_wildcard_pattern if let S(0, ..) = s {}; + //~^ unneeded_wildcard_pattern if let S(0, ..) = s {}; + //~^ unneeded_wildcard_pattern if let S(_, 0, ..) = s {}; if let S(.., 0, _) = s {}; if let S(0, _, _, _) = s {}; @@ -45,6 +58,7 @@ fn main() { #[rustfmt::skip] { if let S(0, ..,) = s {}; + //~^ unneeded_wildcard_pattern } external! { let t = (0, 1, 2, 3); diff --git a/tests/ui/unneeded_wildcard_pattern.rs b/tests/ui/unneeded_wildcard_pattern.rs index 10df2b93d5e0..c91383e2cca5 100644 --- a/tests/ui/unneeded_wildcard_pattern.rs +++ b/tests/ui/unneeded_wildcard_pattern.rs @@ -10,11 +10,17 @@ fn main() { let t = (0, 1, 2, 3); if let (0, .., _) = t {}; + //~^ unneeded_wildcard_pattern if let (0, _, ..) = t {}; + //~^ unneeded_wildcard_pattern if let (_, .., 0) = t {}; + //~^ unneeded_wildcard_pattern if let (.., _, 0) = t {}; + //~^ unneeded_wildcard_pattern if let (0, _, _, ..) = t {}; + //~^ unneeded_wildcard_pattern if let (0, .., _, _) = t {}; + //~^ unneeded_wildcard_pattern if let (_, 0, ..) = t {}; if let (.., 0, _) = t {}; if let (0, _, _, _) = t {}; @@ -24,6 +30,7 @@ fn main() { #[rustfmt::skip] { if let (0, .., _, _,) = t {}; + //~^ unneeded_wildcard_pattern } struct S(usize, usize, usize, usize); @@ -31,11 +38,17 @@ fn main() { let s = S(0, 1, 2, 3); if let S(0, .., _) = s {}; + //~^ unneeded_wildcard_pattern if let S(0, _, ..) = s {}; + //~^ unneeded_wildcard_pattern if let S(_, .., 0) = s {}; + //~^ unneeded_wildcard_pattern if let S(.., _, 0) = s {}; + //~^ unneeded_wildcard_pattern if let S(0, _, _, ..) = s {}; + //~^ unneeded_wildcard_pattern if let S(0, .., _, _) = s {}; + //~^ unneeded_wildcard_pattern if let S(_, 0, ..) = s {}; if let S(.., 0, _) = s {}; if let S(0, _, _, _) = s {}; @@ -45,6 +58,7 @@ fn main() { #[rustfmt::skip] { if let S(0, .., _, _,) = s {}; + //~^ unneeded_wildcard_pattern } external! { let t = (0, 1, 2, 3); diff --git a/tests/ui/unneeded_wildcard_pattern.stderr b/tests/ui/unneeded_wildcard_pattern.stderr index ceb7d7fe9e09..20666268a8ca 100644 --- a/tests/ui/unneeded_wildcard_pattern.stderr +++ b/tests/ui/unneeded_wildcard_pattern.stderr @@ -11,79 +11,79 @@ LL | #![deny(clippy::unneeded_wildcard_pattern)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this pattern is unneeded as the `..` pattern can match that element - --> tests/ui/unneeded_wildcard_pattern.rs:13:16 + --> tests/ui/unneeded_wildcard_pattern.rs:14:16 | LL | if let (0, _, ..) = t {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> tests/ui/unneeded_wildcard_pattern.rs:14:13 + --> tests/ui/unneeded_wildcard_pattern.rs:16:13 | LL | if let (_, .., 0) = t {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> tests/ui/unneeded_wildcard_pattern.rs:15:15 + --> tests/ui/unneeded_wildcard_pattern.rs:18:15 | LL | if let (.., _, 0) = t {}; | ^^^ help: remove it error: these patterns are unneeded as the `..` pattern can match those elements - --> tests/ui/unneeded_wildcard_pattern.rs:16:16 + --> tests/ui/unneeded_wildcard_pattern.rs:20:16 | LL | if let (0, _, _, ..) = t {}; | ^^^^^^ help: remove them error: these patterns are unneeded as the `..` pattern can match those elements - --> tests/ui/unneeded_wildcard_pattern.rs:17:18 + --> tests/ui/unneeded_wildcard_pattern.rs:22:18 | LL | if let (0, .., _, _) = t {}; | ^^^^^^ help: remove them error: these patterns are unneeded as the `..` pattern can match those elements - --> tests/ui/unneeded_wildcard_pattern.rs:26:22 + --> tests/ui/unneeded_wildcard_pattern.rs:32:22 | LL | if let (0, .., _, _,) = t {}; | ^^^^^^ help: remove them error: this pattern is unneeded as the `..` pattern can match that element - --> tests/ui/unneeded_wildcard_pattern.rs:33:19 + --> tests/ui/unneeded_wildcard_pattern.rs:40:19 | LL | if let S(0, .., _) = s {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> tests/ui/unneeded_wildcard_pattern.rs:34:17 + --> tests/ui/unneeded_wildcard_pattern.rs:42:17 | LL | if let S(0, _, ..) = s {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> tests/ui/unneeded_wildcard_pattern.rs:35:14 + --> tests/ui/unneeded_wildcard_pattern.rs:44:14 | LL | if let S(_, .., 0) = s {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> tests/ui/unneeded_wildcard_pattern.rs:36:16 + --> tests/ui/unneeded_wildcard_pattern.rs:46:16 | LL | if let S(.., _, 0) = s {}; | ^^^ help: remove it error: these patterns are unneeded as the `..` pattern can match those elements - --> tests/ui/unneeded_wildcard_pattern.rs:37:17 + --> tests/ui/unneeded_wildcard_pattern.rs:48:17 | LL | if let S(0, _, _, ..) = s {}; | ^^^^^^ help: remove them error: these patterns are unneeded as the `..` pattern can match those elements - --> tests/ui/unneeded_wildcard_pattern.rs:38:19 + --> tests/ui/unneeded_wildcard_pattern.rs:50:19 | LL | if let S(0, .., _, _) = s {}; | ^^^^^^ help: remove them error: these patterns are unneeded as the `..` pattern can match those elements - --> tests/ui/unneeded_wildcard_pattern.rs:47:23 + --> tests/ui/unneeded_wildcard_pattern.rs:60:23 | LL | if let S(0, .., _, _,) = s {}; | ^^^^^^ help: remove them diff --git a/tests/ui/unnested_or_patterns.fixed b/tests/ui/unnested_or_patterns.fixed index 53ec556d1008..791b2fa131f2 100644 --- a/tests/ui/unnested_or_patterns.fixed +++ b/tests/ui/unnested_or_patterns.fixed @@ -14,27 +14,43 @@ fn main() { if let &0 | &2 = &0 {} if let box (0 | 2) = Box::new(0) {} + //~^ unnested_or_patterns if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} + //~^ unnested_or_patterns const C0: Option = Some(1); if let Some(1 | 2) | C0 = None {} + //~^ unnested_or_patterns if let &mut (0 | 2) = &mut 0 {} + //~^ unnested_or_patterns if let x @ (0 | 2) = 0 {} + //~^ unnested_or_patterns if let (0, 1 | 2 | 3) = (0, 0) {} + //~^ unnested_or_patterns if let (1 | 2 | 3, 0) = (0, 0) {} + //~^ unnested_or_patterns if let (x, ..) | (x, 1 | 2) = (0, 1) {} + //~^ unnested_or_patterns if let [0 | 1] = [0] {} + //~^ unnested_or_patterns if let [x, 0 | 1] = [0, 1] {} + //~^ unnested_or_patterns if let [x, 0 | 1 | 2] = [0, 1] {} + //~^ unnested_or_patterns if let [x, ..] | [x, 1 | 2] = [0, 1] {} + //~^ unnested_or_patterns struct TS(u8, u8); if let TS(0 | 1, x) = TS(0, 0) {} + //~^ unnested_or_patterns if let TS(1 | 2 | 3, 0) = TS(0, 0) {} + //~^ unnested_or_patterns if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {} + //~^ unnested_or_patterns struct S { x: u8, y: u8, } if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {} + //~^ unnested_or_patterns if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {} } @@ -46,4 +62,5 @@ fn msrv_1_52() { #[clippy::msrv = "1.53"] fn msrv_1_53() { if let [1 | 53] = [0] {} + //~^ unnested_or_patterns } diff --git a/tests/ui/unnested_or_patterns.rs b/tests/ui/unnested_or_patterns.rs index e5e378e922af..e7e7c7cd2e49 100644 --- a/tests/ui/unnested_or_patterns.rs +++ b/tests/ui/unnested_or_patterns.rs @@ -14,27 +14,43 @@ fn main() { if let &0 | &2 = &0 {} if let box 0 | box 2 = Box::new(0) {} + //~^ unnested_or_patterns if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} + //~^ unnested_or_patterns const C0: Option = Some(1); if let Some(1) | C0 | Some(2) = None {} + //~^ unnested_or_patterns if let &mut 0 | &mut 2 = &mut 0 {} + //~^ unnested_or_patterns if let x @ 0 | x @ 2 = 0 {} + //~^ unnested_or_patterns if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {} + //~^ unnested_or_patterns if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {} + //~^ unnested_or_patterns if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {} + //~^ unnested_or_patterns if let [0] | [1] = [0] {} + //~^ unnested_or_patterns if let [x, 0] | [x, 1] = [0, 1] {} + //~^ unnested_or_patterns if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {} + //~^ unnested_or_patterns if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {} + //~^ unnested_or_patterns struct TS(u8, u8); if let TS(0, x) | TS(1, x) = TS(0, 0) {} + //~^ unnested_or_patterns if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {} + //~^ unnested_or_patterns if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {} + //~^ unnested_or_patterns struct S { x: u8, y: u8, } if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {} + //~^ unnested_or_patterns if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {} } @@ -46,4 +62,5 @@ fn msrv_1_52() { #[clippy::msrv = "1.53"] fn msrv_1_53() { if let [1] | [53] = [0] {} + //~^ unnested_or_patterns } diff --git a/tests/ui/unnested_or_patterns.stderr b/tests/ui/unnested_or_patterns.stderr index bd15ef62368e..3dfd34df4efc 100644 --- a/tests/ui/unnested_or_patterns.stderr +++ b/tests/ui/unnested_or_patterns.stderr @@ -12,7 +12,7 @@ LL | if let box (0 | 2) = Box::new(0) {} | ~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:17:12 + --> tests/ui/unnested_or_patterns.rs:18:12 | LL | if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:19:12 + --> tests/ui/unnested_or_patterns.rs:21:12 | LL | if let Some(1) | C0 | Some(2) = None {} | ^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | if let Some(1 | 2) | C0 = None {} | ~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:20:12 + --> tests/ui/unnested_or_patterns.rs:23:12 | LL | if let &mut 0 | &mut 2 = &mut 0 {} | ^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | if let &mut (0 | 2) = &mut 0 {} | ~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:21:12 + --> tests/ui/unnested_or_patterns.rs:25:12 | LL | if let x @ 0 | x @ 2 = 0 {} | ^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | if let x @ (0 | 2) = 0 {} | ~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:22:12 + --> tests/ui/unnested_or_patterns.rs:27:12 | LL | if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | if let (0, 1 | 2 | 3) = (0, 0) {} | ~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:23:12 + --> tests/ui/unnested_or_patterns.rs:29:12 | LL | if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | if let (1 | 2 | 3, 0) = (0, 0) {} | ~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:24:12 + --> tests/ui/unnested_or_patterns.rs:31:12 | LL | if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | if let (x, ..) | (x, 1 | 2) = (0, 1) {} | ~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:25:12 + --> tests/ui/unnested_or_patterns.rs:33:12 | LL | if let [0] | [1] = [0] {} | ^^^^^^^^^ @@ -100,7 +100,7 @@ LL | if let [0 | 1] = [0] {} | ~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:26:12 + --> tests/ui/unnested_or_patterns.rs:35:12 | LL | if let [x, 0] | [x, 1] = [0, 1] {} | ^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | if let [x, 0 | 1] = [0, 1] {} | ~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:27:12 + --> tests/ui/unnested_or_patterns.rs:37:12 | LL | if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | if let [x, 0 | 1 | 2] = [0, 1] {} | ~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:28:12 + --> tests/ui/unnested_or_patterns.rs:39:12 | LL | if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | if let [x, ..] | [x, 1 | 2] = [0, 1] {} | ~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:30:12 + --> tests/ui/unnested_or_patterns.rs:42:12 | LL | if let TS(0, x) | TS(1, x) = TS(0, 0) {} | ^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | if let TS(0 | 1, x) = TS(0, 0) {} | ~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:31:12 + --> tests/ui/unnested_or_patterns.rs:44:12 | LL | if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | if let TS(1 | 2 | 3, 0) = TS(0, 0) {} | ~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:32:12 + --> tests/ui/unnested_or_patterns.rs:46:12 | LL | if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {} | ~~~~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:37:12 + --> tests/ui/unnested_or_patterns.rs:52:12 | LL | if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {} | ~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns.rs:48:12 + --> tests/ui/unnested_or_patterns.rs:64:12 | LL | if let [1] | [53] = [0] {} | ^^^^^^^^^^ diff --git a/tests/ui/unnested_or_patterns2.fixed b/tests/ui/unnested_or_patterns2.fixed index b2a4e83dadc3..6d601ea5e57f 100644 --- a/tests/ui/unnested_or_patterns2.fixed +++ b/tests/ui/unnested_or_patterns2.fixed @@ -10,11 +10,19 @@ fn main() { if let Some(Some(0 | 1)) = None {} + //~^ unnested_or_patterns if let Some(Some(0 | 1 | 2)) = None {} + //~^ unnested_or_patterns if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {} + //~^ unnested_or_patterns if let Some(Some(0 | 1 | 2)) = None {} + //~^ unnested_or_patterns if let ((0 | 1 | 2,),) = ((0,),) {} + //~^ unnested_or_patterns if let 0 | 1 | 2 = 0 {} + //~^ unnested_or_patterns if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} + //~^ unnested_or_patterns if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {} + //~^ unnested_or_patterns } diff --git a/tests/ui/unnested_or_patterns2.rs b/tests/ui/unnested_or_patterns2.rs index 58435f8990d2..7e5ea0161bff 100644 --- a/tests/ui/unnested_or_patterns2.rs +++ b/tests/ui/unnested_or_patterns2.rs @@ -10,11 +10,19 @@ fn main() { if let Some(Some(0)) | Some(Some(1)) = None {} + //~^ unnested_or_patterns if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {} + //~^ unnested_or_patterns if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {} + //~^ unnested_or_patterns if let Some(Some(0) | Some(1 | 2)) = None {} + //~^ unnested_or_patterns if let ((0,),) | ((1,) | (2,),) = ((0,),) {} + //~^ unnested_or_patterns if let 0 | (1 | 2) = 0 {} + //~^ unnested_or_patterns if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} + //~^ unnested_or_patterns if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} + //~^ unnested_or_patterns } diff --git a/tests/ui/unnested_or_patterns2.stderr b/tests/ui/unnested_or_patterns2.stderr index 54f03937508a..040bb46b0847 100644 --- a/tests/ui/unnested_or_patterns2.stderr +++ b/tests/ui/unnested_or_patterns2.stderr @@ -12,7 +12,7 @@ LL | if let Some(Some(0 | 1)) = None {} | ~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns2.rs:13:12 + --> tests/ui/unnested_or_patterns2.rs:14:12 | LL | if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | if let Some(Some(0 | 1 | 2)) = None {} | ~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns2.rs:14:12 + --> tests/ui/unnested_or_patterns2.rs:16:12 | LL | if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {} | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns2.rs:15:12 + --> tests/ui/unnested_or_patterns2.rs:18:12 | LL | if let Some(Some(0) | Some(1 | 2)) = None {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | if let Some(Some(0 | 1 | 2)) = None {} | ~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns2.rs:16:12 + --> tests/ui/unnested_or_patterns2.rs:20:12 | LL | if let ((0,),) | ((1,) | (2,),) = ((0,),) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | if let ((0 | 1 | 2,),) = ((0,),) {} | ~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns2.rs:17:12 + --> tests/ui/unnested_or_patterns2.rs:22:12 | LL | if let 0 | (1 | 2) = 0 {} | ^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | if let 0 | 1 | 2 = 0 {} | ~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns2.rs:18:12 + --> tests/ui/unnested_or_patterns2.rs:24:12 | LL | if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> tests/ui/unnested_or_patterns2.rs:19:12 + --> tests/ui/unnested_or_patterns2.rs:26:12 | LL | if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unreadable_literal.fixed b/tests/ui/unreadable_literal.fixed index fb9c2672db82..646481ab040b 100644 --- a/tests/ui/unreadable_literal.fixed +++ b/tests/ui/unreadable_literal.fixed @@ -29,14 +29,24 @@ fn main() { 1.123_4_f32, ); let _bad = (0b11_0110_i64, 0x1234_5678_usize, 123_456_f32, 1.234_567_f32); + //~^ unreadable_literal + //~| unreadable_literal + //~| unreadable_literal + //~| unreadable_literal let _good_sci = 1.1234e1; let _bad_sci = 1.123_456e1; + //~^ unreadable_literal let _fail1 = 0x00ab_cdef; + //~^ unreadable_literal let _fail2: u32 = 0xBAFE_BAFE; + //~^ unreadable_literal let _fail3 = 0x0abc_deff; + //~^ unreadable_literal let _fail4: i128 = 0x00ab_cabc_abca_bcab_cabc; + //~^ unreadable_literal let _fail5 = 1.100_300_400; + //~^ unreadable_literal let _ = foo!(); let _ = bar!(); diff --git a/tests/ui/unreadable_literal.rs b/tests/ui/unreadable_literal.rs index 0a24fa852546..973d1a8e196a 100644 --- a/tests/ui/unreadable_literal.rs +++ b/tests/ui/unreadable_literal.rs @@ -29,14 +29,24 @@ fn main() { 1.123_4_f32, ); let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32); + //~^ unreadable_literal + //~| unreadable_literal + //~| unreadable_literal + //~| unreadable_literal let _good_sci = 1.1234e1; let _bad_sci = 1.123456e1; + //~^ unreadable_literal let _fail1 = 0xabcdef; + //~^ unreadable_literal let _fail2: u32 = 0xBAFEBAFE; + //~^ unreadable_literal let _fail3 = 0xabcdeff; + //~^ unreadable_literal let _fail4: i128 = 0xabcabcabcabcabcabc; + //~^ unreadable_literal let _fail5 = 1.100300400; + //~^ unreadable_literal let _ = foo!(); let _ = bar!(); diff --git a/tests/ui/unreadable_literal.stderr b/tests/ui/unreadable_literal.stderr index 5e350d760643..d019bf1b1feb 100644 --- a/tests/ui/unreadable_literal.stderr +++ b/tests/ui/unreadable_literal.stderr @@ -26,37 +26,37 @@ LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32); | ^^^^^^^^^^^^ help: consider: `1.234_567_f32` error: long literal lacking separators - --> tests/ui/unreadable_literal.rs:33:20 + --> tests/ui/unreadable_literal.rs:37:20 | LL | let _bad_sci = 1.123456e1; | ^^^^^^^^^^ help: consider: `1.123_456e1` error: long literal lacking separators - --> tests/ui/unreadable_literal.rs:35:18 + --> tests/ui/unreadable_literal.rs:40:18 | LL | let _fail1 = 0xabcdef; | ^^^^^^^^ help: consider: `0x00ab_cdef` error: long literal lacking separators - --> tests/ui/unreadable_literal.rs:36:23 + --> tests/ui/unreadable_literal.rs:42:23 | LL | let _fail2: u32 = 0xBAFEBAFE; | ^^^^^^^^^^ help: consider: `0xBAFE_BAFE` error: long literal lacking separators - --> tests/ui/unreadable_literal.rs:37:18 + --> tests/ui/unreadable_literal.rs:44:18 | LL | let _fail3 = 0xabcdeff; | ^^^^^^^^^ help: consider: `0x0abc_deff` error: long literal lacking separators - --> tests/ui/unreadable_literal.rs:38:24 + --> tests/ui/unreadable_literal.rs:46:24 | LL | let _fail4: i128 = 0xabcabcabcabcabcabc; | ^^^^^^^^^^^^^^^^^^^^ help: consider: `0x00ab_cabc_abca_bcab_cabc` error: long literal lacking separators - --> tests/ui/unreadable_literal.rs:39:18 + --> tests/ui/unreadable_literal.rs:48:18 | LL | let _fail5 = 1.100300400; | ^^^^^^^^^^^ help: consider: `1.100_300_400` diff --git a/tests/ui/unsafe_removed_from_name.rs b/tests/ui/unsafe_removed_from_name.rs index e9e6c8312f5e..124206e8e353 100644 --- a/tests/ui/unsafe_removed_from_name.rs +++ b/tests/ui/unsafe_removed_from_name.rs @@ -3,11 +3,13 @@ #![warn(clippy::unsafe_removed_from_name)] use std::cell::UnsafeCell as TotallySafeCell; -//~^ ERROR: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCell` -//~| NOTE: `-D clippy::unsafe-removed-from-name` implied by `-D warnings` +//~^ unsafe_removed_from_name + + use std::cell::UnsafeCell as TotallySafeCellAgain; -//~^ ERROR: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCellAgain` +//~^ unsafe_removed_from_name + // Shouldn't error use std::cell::RefCell as ProbablyNotUnsafe; @@ -26,12 +28,15 @@ mod mod_with_some_unsafe_things { } use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety; -//~^ ERROR: removed `unsafe` from the name of `Unsafe` in use as `LieAboutModSafety` +//~^ unsafe_removed_from_name + // merged imports use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B}; -//~^ ERROR: removed `unsafe` from the name of `Unsafe` in use as `A` -//~| ERROR: removed `unsafe` from the name of `Unsafe` in use as `B` +//~^ unsafe_removed_from_name +//~| unsafe_removed_from_name + + // Shouldn't error use mod_with_some_unsafe_things::Safe as IPromiseItsSafeThisTime; diff --git a/tests/ui/unsafe_removed_from_name.stderr b/tests/ui/unsafe_removed_from_name.stderr index 998cdbb579f6..899d438ea76b 100644 --- a/tests/ui/unsafe_removed_from_name.stderr +++ b/tests/ui/unsafe_removed_from_name.stderr @@ -8,25 +8,25 @@ LL | use std::cell::UnsafeCell as TotallySafeCell; = help: to override `-D warnings` add `#[allow(clippy::unsafe_removed_from_name)]` error: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCellAgain` - --> tests/ui/unsafe_removed_from_name.rs:9:1 + --> tests/ui/unsafe_removed_from_name.rs:10:1 | LL | use std::cell::UnsafeCell as TotallySafeCellAgain; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: removed `unsafe` from the name of `Unsafe` in use as `LieAboutModSafety` - --> tests/ui/unsafe_removed_from_name.rs:28:1 + --> tests/ui/unsafe_removed_from_name.rs:30:1 | LL | use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: removed `unsafe` from the name of `Unsafe` in use as `A` - --> tests/ui/unsafe_removed_from_name.rs:32:1 + --> tests/ui/unsafe_removed_from_name.rs:35:1 | LL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: removed `unsafe` from the name of `Unsafe` in use as `B` - --> tests/ui/unsafe_removed_from_name.rs:32:1 + --> tests/ui/unsafe_removed_from_name.rs:35:1 | LL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unseparated_prefix_literals.fixed b/tests/ui/unseparated_prefix_literals.fixed index 93f7f747b7cd..e13dd561d627 100644 --- a/tests/ui/unseparated_prefix_literals.fixed +++ b/tests/ui/unseparated_prefix_literals.fixed @@ -13,6 +13,7 @@ struct Foo; macro_rules! lit_from_macro { () => { 42_usize + //~^ unseparated_literal_suffix }; } @@ -21,15 +22,22 @@ fn main() { let _ok2 = 1234_isize; let _ok3 = 0x123_isize; let _fail1 = 1234_i32; + //~^ unseparated_literal_suffix let _fail2 = 1234_u32; + //~^ unseparated_literal_suffix let _fail3 = 1234_isize; + //~^ unseparated_literal_suffix let _fail4 = 1234_usize; + //~^ unseparated_literal_suffix let _fail5 = 0x123_isize; + //~^ unseparated_literal_suffix let _okf1 = 1.5_f32; let _okf2 = 1_f32; let _failf1 = 1.5_f32; + //~^ unseparated_literal_suffix let _failf2 = 1_f32; + //~^ unseparated_literal_suffix // Test for macro let _ = lit_from_macro!(); @@ -38,4 +46,5 @@ fn main() { let _ = line!(); // Because `assert!` contains `line!()` macro. assert_eq!(4897_u32, 32223); + //~^ unseparated_literal_suffix } diff --git a/tests/ui/unseparated_prefix_literals.rs b/tests/ui/unseparated_prefix_literals.rs index c960ff6b5dcc..6f7b16ccba54 100644 --- a/tests/ui/unseparated_prefix_literals.rs +++ b/tests/ui/unseparated_prefix_literals.rs @@ -13,6 +13,7 @@ struct Foo; macro_rules! lit_from_macro { () => { 42usize + //~^ unseparated_literal_suffix }; } @@ -21,15 +22,22 @@ fn main() { let _ok2 = 1234_isize; let _ok3 = 0x123_isize; let _fail1 = 1234i32; + //~^ unseparated_literal_suffix let _fail2 = 1234u32; + //~^ unseparated_literal_suffix let _fail3 = 1234isize; + //~^ unseparated_literal_suffix let _fail4 = 1234usize; + //~^ unseparated_literal_suffix let _fail5 = 0x123isize; + //~^ unseparated_literal_suffix let _okf1 = 1.5_f32; let _okf2 = 1_f32; let _failf1 = 1.5f32; + //~^ unseparated_literal_suffix let _failf2 = 1f32; + //~^ unseparated_literal_suffix // Test for macro let _ = lit_from_macro!(); @@ -38,4 +46,5 @@ fn main() { let _ = line!(); // Because `assert!` contains `line!()` macro. assert_eq!(4897u32, 32223); + //~^ unseparated_literal_suffix } diff --git a/tests/ui/unseparated_prefix_literals.stderr b/tests/ui/unseparated_prefix_literals.stderr index 1c51f7ada91f..4cfbf5e4b74e 100644 --- a/tests/ui/unseparated_prefix_literals.stderr +++ b/tests/ui/unseparated_prefix_literals.stderr @@ -1,5 +1,5 @@ error: integer type suffix should be separated by an underscore - --> tests/ui/unseparated_prefix_literals.rs:23:18 + --> tests/ui/unseparated_prefix_literals.rs:24:18 | LL | let _fail1 = 1234i32; | ^^^^^^^ help: add an underscore: `1234_i32` @@ -8,37 +8,37 @@ LL | let _fail1 = 1234i32; = help: to override `-D warnings` add `#[allow(clippy::unseparated_literal_suffix)]` error: integer type suffix should be separated by an underscore - --> tests/ui/unseparated_prefix_literals.rs:24:18 + --> tests/ui/unseparated_prefix_literals.rs:26:18 | LL | let _fail2 = 1234u32; | ^^^^^^^ help: add an underscore: `1234_u32` error: integer type suffix should be separated by an underscore - --> tests/ui/unseparated_prefix_literals.rs:25:18 + --> tests/ui/unseparated_prefix_literals.rs:28:18 | LL | let _fail3 = 1234isize; | ^^^^^^^^^ help: add an underscore: `1234_isize` error: integer type suffix should be separated by an underscore - --> tests/ui/unseparated_prefix_literals.rs:26:18 + --> tests/ui/unseparated_prefix_literals.rs:30:18 | LL | let _fail4 = 1234usize; | ^^^^^^^^^ help: add an underscore: `1234_usize` error: integer type suffix should be separated by an underscore - --> tests/ui/unseparated_prefix_literals.rs:27:18 + --> tests/ui/unseparated_prefix_literals.rs:32:18 | LL | let _fail5 = 0x123isize; | ^^^^^^^^^^ help: add an underscore: `0x123_isize` error: float type suffix should be separated by an underscore - --> tests/ui/unseparated_prefix_literals.rs:31:19 + --> tests/ui/unseparated_prefix_literals.rs:37:19 | LL | let _failf1 = 1.5f32; | ^^^^^^ help: add an underscore: `1.5_f32` error: float type suffix should be separated by an underscore - --> tests/ui/unseparated_prefix_literals.rs:32:19 + --> tests/ui/unseparated_prefix_literals.rs:39:19 | LL | let _failf2 = 1f32; | ^^^^ help: add an underscore: `1_f32` @@ -55,7 +55,7 @@ LL | let _ = lit_from_macro!(); = note: this error originates in the macro `lit_from_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: integer type suffix should be separated by an underscore - --> tests/ui/unseparated_prefix_literals.rs:40:16 + --> tests/ui/unseparated_prefix_literals.rs:48:16 | LL | assert_eq!(4897u32, 32223); | ^^^^^^^ help: add an underscore: `4897_u32` diff --git a/tests/ui/unused_async.rs b/tests/ui/unused_async.rs index 838d6f0aa971..225f09ed94e6 100644 --- a/tests/ui/unused_async.rs +++ b/tests/ui/unused_async.rs @@ -10,7 +10,8 @@ mod issue10800 { use std::future::ready; async fn async_block_await() { - //~^ ERROR: unused `async` for function with no await statements + //~^ unused_async + async { ready(()).await; }; @@ -43,7 +44,8 @@ mod issue9695 { async fn f() {} async fn f2() {} async fn f3() {} - //~^ ERROR: unused `async` for function with no await statements + //~^ unused_async + fn needs_async_fn>(_: fn() -> F) {} @@ -72,7 +74,8 @@ mod issue13466 { } async fn foo() -> i32 { - //~^ ERROR: unused `async` for function with no await statements +//~^ unused_async + 4 } @@ -84,7 +87,8 @@ struct S; impl S { async fn unused(&self) -> i32 { - //~^ ERROR: unused `async` for function with no await statements + //~^ unused_async + 1 } diff --git a/tests/ui/unused_async.stderr b/tests/ui/unused_async.stderr index 4811df63658a..5b8d8f5097be 100644 --- a/tests/ui/unused_async.stderr +++ b/tests/ui/unused_async.stderr @@ -3,6 +3,7 @@ error: unused `async` for function with no await statements | LL | / async fn async_block_await() { LL | | +LL | | LL | | async { LL | | ready(()).await; LL | | }; @@ -11,7 +12,7 @@ LL | | } | = help: consider removing the `async` from this function note: `await` used in an async block, which does not require the enclosing function to be `async` - --> tests/ui/unused_async.rs:15:23 + --> tests/ui/unused_async.rs:16:23 | LL | ready(()).await; | ^^^^^ @@ -19,7 +20,7 @@ LL | ready(()).await; = help: to override `-D warnings` add `#[allow(clippy::unused_async)]` error: unused `async` for function with no await statements - --> tests/ui/unused_async.rs:45:5 + --> tests/ui/unused_async.rs:46:5 | LL | async fn f3() {} | ^^^^^^^^^^^^^^^^ @@ -27,10 +28,11 @@ LL | async fn f3() {} = help: consider removing the `async` from this function error: unused `async` for function with no await statements - --> tests/ui/unused_async.rs:74:1 + --> tests/ui/unused_async.rs:76:1 | LL | / async fn foo() -> i32 { LL | | +LL | | LL | | 4 LL | | } | |_^ @@ -38,10 +40,11 @@ LL | | } = help: consider removing the `async` from this function error: unused `async` for function with no await statements - --> tests/ui/unused_async.rs:86:5 + --> tests/ui/unused_async.rs:89:5 | LL | / async fn unused(&self) -> i32 { LL | | +LL | | LL | | 1 LL | | } | |_____^ diff --git a/tests/ui/unused_enumerate_index.fixed b/tests/ui/unused_enumerate_index.fixed index cffd02b0acc8..8c713e273f4a 100644 --- a/tests/ui/unused_enumerate_index.fixed +++ b/tests/ui/unused_enumerate_index.fixed @@ -10,6 +10,7 @@ fn get_enumerate() -> Enumerate> { fn main() { let v = [1, 2, 3]; for x in v.iter() { + //~^ unused_enumerate_index println!("{x}"); } @@ -57,12 +58,15 @@ fn main() { let dummy = Dummy3(vec![1, 2, 3].into_iter()); for x in dummy { + //~^ unused_enumerate_index println!("{x}"); } let _ = vec![1, 2, 3].into_iter().map(|x| println!("{x}")); + //~^ unused_enumerate_index let p = vec![1, 2, 3].into_iter(); + //~^ unused_enumerate_index p.map(|x| println!("{x}")); // This shouldn't trigger the lint. `get_enumerate` may come from an external library on which we @@ -84,6 +88,7 @@ fn main() { }; } _ = mac2!().map(|_v| {}); + //~^ unused_enumerate_index // This shouldn't trigger the lint because of the `allow`. #[allow(clippy::unused_enumerate_index)] @@ -92,15 +97,18 @@ fn main() { // This should keep the explicit type of `x`. let v = [1, 2, 3].iter().copied(); + //~^ unused_enumerate_index let x = v.map(|x: i32| x).sum::(); assert_eq!(x, 6); // This should keep the explicit type of `x`. let v = [1, 2, 3].iter().copied(); + //~^ unused_enumerate_index let x = v.map(|x: i32| x).sum::(); assert_eq!(x, 6); let v = [1, 2, 3].iter().copied(); + //~^ unused_enumerate_index let x = v.map(|x| x).sum::(); assert_eq!(x, 6); } diff --git a/tests/ui/unused_enumerate_index.rs b/tests/ui/unused_enumerate_index.rs index f2b5f8b91247..97018ee985e5 100644 --- a/tests/ui/unused_enumerate_index.rs +++ b/tests/ui/unused_enumerate_index.rs @@ -10,6 +10,7 @@ fn get_enumerate() -> Enumerate> { fn main() { let v = [1, 2, 3]; for (_, x) in v.iter().enumerate() { + //~^ unused_enumerate_index println!("{x}"); } @@ -57,12 +58,15 @@ fn main() { let dummy = Dummy3(vec![1, 2, 3].into_iter()); for (_, x) in dummy.enumerate() { + //~^ unused_enumerate_index println!("{x}"); } let _ = vec![1, 2, 3].into_iter().enumerate().map(|(_, x)| println!("{x}")); + //~^ unused_enumerate_index let p = vec![1, 2, 3].into_iter().enumerate(); + //~^ unused_enumerate_index p.map(|(_, x)| println!("{x}")); // This shouldn't trigger the lint. `get_enumerate` may come from an external library on which we @@ -84,6 +88,7 @@ fn main() { }; } _ = mac2!().enumerate().map(|(_, _v)| {}); + //~^ unused_enumerate_index // This shouldn't trigger the lint because of the `allow`. #[allow(clippy::unused_enumerate_index)] @@ -92,15 +97,18 @@ fn main() { // This should keep the explicit type of `x`. let v = [1, 2, 3].iter().copied().enumerate(); + //~^ unused_enumerate_index let x = v.map(|(_, x): (usize, i32)| x).sum::(); assert_eq!(x, 6); // This should keep the explicit type of `x`. let v = [1, 2, 3].iter().copied().enumerate(); + //~^ unused_enumerate_index let x = v.map(|(_, x): (_, i32)| x).sum::(); assert_eq!(x, 6); let v = [1, 2, 3].iter().copied().enumerate(); + //~^ unused_enumerate_index let x = v.map(|(_, x)| x).sum::(); assert_eq!(x, 6); } diff --git a/tests/ui/unused_enumerate_index.stderr b/tests/ui/unused_enumerate_index.stderr index 6ec07dcbff0a..9ea65631a5f2 100644 --- a/tests/ui/unused_enumerate_index.stderr +++ b/tests/ui/unused_enumerate_index.stderr @@ -12,7 +12,7 @@ LL | for x in v.iter() { | ~ ~~~~~~~~ error: you seem to use `.enumerate()` and immediately discard the index - --> tests/ui/unused_enumerate_index.rs:59:19 + --> tests/ui/unused_enumerate_index.rs:60:19 | LL | for (_, x) in dummy.enumerate() { | ^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | for x in dummy { | ~ ~~~~~ error: you seem to use `.enumerate()` and immediately discard the index - --> tests/ui/unused_enumerate_index.rs:63:39 + --> tests/ui/unused_enumerate_index.rs:65:39 | LL | let _ = vec![1, 2, 3].into_iter().enumerate().map(|(_, x)| println!("{x}")); | ^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL + let _ = vec![1, 2, 3].into_iter().map(|x| println!("{x}")); | error: you seem to use `.enumerate()` and immediately discard the index - --> tests/ui/unused_enumerate_index.rs:65:39 + --> tests/ui/unused_enumerate_index.rs:68:39 | LL | let p = vec![1, 2, 3].into_iter().enumerate(); | ^^^^^^^^^^^ @@ -43,11 +43,12 @@ LL | let p = vec![1, 2, 3].into_iter().enumerate(); help: remove the `.enumerate()` call | LL ~ let p = vec![1, 2, 3].into_iter(); +LL | LL ~ p.map(|x| println!("{x}")); | error: you seem to use `.enumerate()` and immediately discard the index - --> tests/ui/unused_enumerate_index.rs:86:17 + --> tests/ui/unused_enumerate_index.rs:90:17 | LL | _ = mac2!().enumerate().map(|(_, _v)| {}); | ^^^^^^^^^^^ @@ -58,18 +59,6 @@ LL - _ = mac2!().enumerate().map(|(_, _v)| {}); LL + _ = mac2!().map(|_v| {}); | -error: you seem to use `.enumerate()` and immediately discard the index - --> tests/ui/unused_enumerate_index.rs:94:39 - | -LL | let v = [1, 2, 3].iter().copied().enumerate(); - | ^^^^^^^^^^^ - | -help: remove the `.enumerate()` call - | -LL ~ let v = [1, 2, 3].iter().copied(); -LL ~ let x = v.map(|x: i32| x).sum::(); - | - error: you seem to use `.enumerate()` and immediately discard the index --> tests/ui/unused_enumerate_index.rs:99:39 | @@ -79,11 +68,12 @@ LL | let v = [1, 2, 3].iter().copied().enumerate(); help: remove the `.enumerate()` call | LL ~ let v = [1, 2, 3].iter().copied(); +LL | LL ~ let x = v.map(|x: i32| x).sum::(); | error: you seem to use `.enumerate()` and immediately discard the index - --> tests/ui/unused_enumerate_index.rs:103:39 + --> tests/ui/unused_enumerate_index.rs:105:39 | LL | let v = [1, 2, 3].iter().copied().enumerate(); | ^^^^^^^^^^^ @@ -91,6 +81,20 @@ LL | let v = [1, 2, 3].iter().copied().enumerate(); help: remove the `.enumerate()` call | LL ~ let v = [1, 2, 3].iter().copied(); +LL | +LL ~ let x = v.map(|x: i32| x).sum::(); + | + +error: you seem to use `.enumerate()` and immediately discard the index + --> tests/ui/unused_enumerate_index.rs:110:39 + | +LL | let v = [1, 2, 3].iter().copied().enumerate(); + | ^^^^^^^^^^^ + | +help: remove the `.enumerate()` call + | +LL ~ let v = [1, 2, 3].iter().copied(); +LL | LL ~ let x = v.map(|x| x).sum::(); | diff --git a/tests/ui/unused_format_specs.1.fixed b/tests/ui/unused_format_specs.1.fixed index 157c2b08d3cf..850240bab608 100644 --- a/tests/ui/unused_format_specs.1.fixed +++ b/tests/ui/unused_format_specs.1.fixed @@ -10,18 +10,22 @@ macro_rules! format_args_from_macro { fn main() { // prints `.`, not ` .` println!("{:5}.", format!("")); - //~^ ERROR: format specifiers have no effect on `format_args!()` - //~| NOTE: `-D clippy::unused-format-specs` implied by `-D warnings` + //~^ unused_format_specs + + //prints `abcde`, not `abc` println!("{:.3}", format!("abcde")); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + println!("{}.", format_args_from_macro!()); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + let args = format_args!(""); println!("{args}"); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + } fn should_not_lint() { @@ -46,17 +50,21 @@ macro_rules! usr_println { fn should_lint_user() { // prints `.`, not ` .` usr_println!(true, "{:5}.", format!("")); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + //prints `abcde`, not `abc` usr_println!(true, "{:.3}", format!("abcde")); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + usr_println!(true, "{}.", format_args_from_macro!()); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + let args = format_args!(""); usr_println!(true, "{args}"); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + } fn should_not_lint_user() { diff --git a/tests/ui/unused_format_specs.2.fixed b/tests/ui/unused_format_specs.2.fixed index 92c7b951f3ca..f8d5f615e045 100644 --- a/tests/ui/unused_format_specs.2.fixed +++ b/tests/ui/unused_format_specs.2.fixed @@ -10,18 +10,22 @@ macro_rules! format_args_from_macro { fn main() { // prints `.`, not ` .` println!("{}.", format_args!("")); - //~^ ERROR: format specifiers have no effect on `format_args!()` - //~| NOTE: `-D clippy::unused-format-specs` implied by `-D warnings` + //~^ unused_format_specs + + //prints `abcde`, not `abc` println!("{}", format_args!("abcde")); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + println!("{}.", format_args_from_macro!()); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + let args = format_args!(""); println!("{args}"); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + } fn should_not_lint() { @@ -46,17 +50,21 @@ macro_rules! usr_println { fn should_lint_user() { // prints `.`, not ` .` usr_println!(true, "{}.", format_args!("")); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + //prints `abcde`, not `abc` usr_println!(true, "{}", format_args!("abcde")); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + usr_println!(true, "{}.", format_args_from_macro!()); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + let args = format_args!(""); usr_println!(true, "{args}"); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + } fn should_not_lint_user() { diff --git a/tests/ui/unused_format_specs.rs b/tests/ui/unused_format_specs.rs index a5df4d8a8668..777901258a77 100644 --- a/tests/ui/unused_format_specs.rs +++ b/tests/ui/unused_format_specs.rs @@ -10,18 +10,22 @@ macro_rules! format_args_from_macro { fn main() { // prints `.`, not ` .` println!("{:5}.", format_args!("")); - //~^ ERROR: format specifiers have no effect on `format_args!()` - //~| NOTE: `-D clippy::unused-format-specs` implied by `-D warnings` + //~^ unused_format_specs + + //prints `abcde`, not `abc` println!("{:.3}", format_args!("abcde")); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + println!("{:5}.", format_args_from_macro!()); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + let args = format_args!(""); println!("{args:5}"); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + } fn should_not_lint() { @@ -46,17 +50,21 @@ macro_rules! usr_println { fn should_lint_user() { // prints `.`, not ` .` usr_println!(true, "{:5}.", format_args!("")); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + //prints `abcde`, not `abc` usr_println!(true, "{:.3}", format_args!("abcde")); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + usr_println!(true, "{:5}.", format_args_from_macro!()); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + let args = format_args!(""); usr_println!(true, "{args:5}"); - //~^ ERROR: format specifiers have no effect on `format_args!()` + //~^ unused_format_specs + } fn should_not_lint_user() { diff --git a/tests/ui/unused_format_specs.stderr b/tests/ui/unused_format_specs.stderr index df61d59130ef..a88a808afe82 100644 --- a/tests/ui/unused_format_specs.stderr +++ b/tests/ui/unused_format_specs.stderr @@ -17,7 +17,7 @@ LL + println!("{}.", format_args!("")); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:16:15 + --> tests/ui/unused_format_specs.rs:17:15 | LL | println!("{:.3}", format_args!("abcde")); | ^^^^^ @@ -33,7 +33,7 @@ LL + println!("{}", format_args!("abcde")); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:19:15 + --> tests/ui/unused_format_specs.rs:21:15 | LL | println!("{:5}.", format_args_from_macro!()); | ^^^^ @@ -46,7 +46,7 @@ LL + println!("{}.", format_args_from_macro!()); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:23:15 + --> tests/ui/unused_format_specs.rs:26:15 | LL | println!("{args:5}"); | ^^^^^^^^ @@ -59,7 +59,7 @@ LL + println!("{args}"); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:48:25 + --> tests/ui/unused_format_specs.rs:52:25 | LL | usr_println!(true, "{:5}.", format_args!("")); | ^^^^ @@ -75,7 +75,7 @@ LL + usr_println!(true, "{}.", format_args!("")); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:51:25 + --> tests/ui/unused_format_specs.rs:56:25 | LL | usr_println!(true, "{:.3}", format_args!("abcde")); | ^^^^^ @@ -91,7 +91,7 @@ LL + usr_println!(true, "{}", format_args!("abcde")); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:54:25 + --> tests/ui/unused_format_specs.rs:60:25 | LL | usr_println!(true, "{:5}.", format_args_from_macro!()); | ^^^^ @@ -104,7 +104,7 @@ LL + usr_println!(true, "{}.", format_args_from_macro!()); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:58:25 + --> tests/ui/unused_format_specs.rs:65:25 | LL | usr_println!(true, "{args:5}"); | ^^^^^^^^ diff --git a/tests/ui/unused_io_amount.rs b/tests/ui/unused_io_amount.rs index 175c4ca76895..f0531836db1c 100644 --- a/tests/ui/unused_io_amount.rs +++ b/tests/ui/unused_io_amount.rs @@ -8,26 +8,26 @@ use std::io::{self, Read}; fn question_mark(s: &mut T) -> io::Result<()> { s.write(b"test")?; - //~^ ERROR: written amount is not handled + //~^ unused_io_amount let mut buf = [0u8; 4]; s.read(&mut buf)?; - //~^ ERROR: read amount is not handled + //~^ unused_io_amount Ok(()) } fn unwrap(s: &mut T) { s.write(b"test").unwrap(); - //~^ ERROR: written amount is not handled + //~^ unused_io_amount let mut buf = [0u8; 4]; s.read(&mut buf).unwrap(); - //~^ ERROR: read amount is not handled + //~^ unused_io_amount } fn vectored(s: &mut T) -> io::Result<()> { s.read_vectored(&mut [io::IoSliceMut::new(&mut [])])?; - //~^ ERROR: read amount is not handled + //~^ unused_io_amount s.write_vectored(&[io::IoSlice::new(&[])])?; - //~^ ERROR: written amount is not handled + //~^ unused_io_amount Ok(()) } @@ -35,7 +35,7 @@ fn ok(file: &str) -> Option<()> { let mut reader = std::fs::File::open(file).ok()?; let mut result = [0u8; 0]; reader.read(&mut result).ok()?; - //~^ ERROR: read amount is not handled + //~^ unused_io_amount Some(()) } @@ -45,7 +45,7 @@ fn or_else(file: &str) -> io::Result<()> { let mut reader = std::fs::File::open(file)?; let mut result = [0u8; 0]; reader.read(&mut result).or_else(|err| Err(err))?; - //~^ ERROR: read amount is not handled + //~^ unused_io_amount Ok(()) } @@ -58,7 +58,7 @@ fn or(file: &str) -> Result<(), Error> { let mut reader = std::fs::File::open(file).unwrap(); let mut result = [0u8; 0]; reader.read(&mut result).or(Err(Error::Kind))?; - //~^ ERROR: read amount is not handled + //~^ unused_io_amount Ok(()) } @@ -66,7 +66,7 @@ fn combine_or(file: &str) -> Result<(), Error> { let mut reader = std::fs::File::open(file).unwrap(); let mut result = [0u8; 0]; reader - //~^ ERROR: read amount is not handled + //~^ unused_io_amount .read(&mut result) .or(Err(Error::Kind)) .or(Err(Error::Kind)) @@ -76,25 +76,25 @@ fn combine_or(file: &str) -> Result<(), Error> { fn is_ok_err(s: &mut T) { s.write(b"ok").is_ok(); - //~^ ERROR: written amount is not handled + //~^ unused_io_amount s.write(b"err").is_err(); - //~^ ERROR: written amount is not handled + //~^ unused_io_amount let mut buf = [0u8; 0]; s.read(&mut buf).is_ok(); - //~^ ERROR: read amount is not handled + //~^ unused_io_amount s.read(&mut buf).is_err(); - //~^ ERROR: read amount is not handled + //~^ unused_io_amount } async fn bad_async_write(w: &mut W) { w.write(b"hello world").await.unwrap(); - //~^ ERROR: written amount is not handled + //~^ unused_io_amount } async fn bad_async_read(r: &mut R) { let mut buf = [0u8; 0]; r.read(&mut buf[..]).await.unwrap(); - //~^ ERROR: read amount is not handled + //~^ unused_io_amount } async fn io_not_ignored_async_write(mut w: W) { @@ -102,13 +102,14 @@ async fn io_not_ignored_async_write(mut w: W) { // warning about _that_ (or we would, if it were enabled), but we // won't get one about ignoring the return value. w.write(b"hello world"); + //~^ unused_io_amount } fn bad_async_write_closure(w: W) -> impl futures::Future> { let mut w = w; async move { w.write(b"hello world").await?; - //~^ ERROR: written amount is not handled + //~^ unused_io_amount Ok(()) } } @@ -117,7 +118,7 @@ async fn async_read_nested_or(r: &mut R, do_it: bool) -> R let mut buf = [0u8; 1]; if do_it { r.read(&mut buf[..]).await.or(Err(Error::Kind))?; - //~^ ERROR: read amount is not handled + //~^ unused_io_amount } Ok(buf) } @@ -126,13 +127,13 @@ use tokio::io::{AsyncRead as TokioAsyncRead, AsyncReadExt as _, AsyncWrite as To async fn bad_async_write_tokio(w: &mut W) { w.write(b"hello world").await.unwrap(); - //~^ ERROR: written amount is not handled + //~^ unused_io_amount } async fn bad_async_read_tokio(r: &mut R) { let mut buf = [0u8; 0]; r.read(&mut buf[..]).await.unwrap(); - //~^ ERROR: read amount is not handled + //~^ unused_io_amount } async fn undetected_bad_async_write(w: &mut W) { @@ -145,35 +146,31 @@ async fn undetected_bad_async_write(w: &mut W) { fn match_okay_underscore(s: &mut T) { match s.write(b"test") { - //~^ ERROR: written amount is not handled + //~^ unused_io_amount Ok(_) => todo!(), - //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled Err(_) => todo!(), }; let mut buf = [0u8; 4]; match s.read(&mut buf) { - //~^ ERROR: read amount is not handled + //~^ unused_io_amount Ok(_) => todo!(), - //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled Err(_) => todo!(), } } fn match_okay_underscore_read_expr(s: &mut T) { match s.read(&mut [0u8; 4]) { - //~^ ERROR: read amount is not handled + //~^ unused_io_amount Ok(_) => todo!(), - //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled Err(_) => todo!(), } } fn match_okay_underscore_write_expr(s: &mut T) { match s.write(b"test") { - //~^ ERROR: written amount is not handled + //~^ unused_io_amount Ok(_) => todo!(), - //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled Err(_) => todo!(), } } @@ -184,21 +181,21 @@ fn returned_value_should_not_lint(s: &mut T) -> Result< fn if_okay_underscore_read_expr(s: &mut T) { if let Ok(_) = s.read(&mut [0u8; 4]) { - //~^ ERROR: read amount is not handled + //~^ unused_io_amount todo!() } } fn if_okay_underscore_write_expr(s: &mut T) { if let Ok(_) = s.write(b"test") { - //~^ ERROR: written amount is not handled + //~^ unused_io_amount todo!() } } fn if_okay_dots_write_expr(s: &mut T) { if let Ok(..) = s.write(b"test") { - //~^ ERROR: written amount is not handled + //~^ unused_io_amount todo!() } } diff --git a/tests/ui/unused_io_amount.stderr b/tests/ui/unused_io_amount.stderr index 771e463ca010..71bb4c40de84 100644 --- a/tests/ui/unused_io_amount.stderr +++ b/tests/ui/unused_io_amount.stderr @@ -138,7 +138,7 @@ LL | w.write(b"hello world"); = help: use `AsyncWriteExt::write_all` instead, or handle partial writes error: written amount is not handled - --> tests/ui/unused_io_amount.rs:110:9 + --> tests/ui/unused_io_amount.rs:111:9 | LL | w.write(b"hello world").await?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -146,7 +146,7 @@ LL | w.write(b"hello world").await?; = help: use `AsyncWriteExt::write_all` instead, or handle partial writes error: read amount is not handled - --> tests/ui/unused_io_amount.rs:119:9 + --> tests/ui/unused_io_amount.rs:120:9 | LL | r.read(&mut buf[..]).await.or(Err(Error::Kind))?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | r.read(&mut buf[..]).await.or(Err(Error::Kind))?; = help: use `AsyncReadExt::read_exact` instead, or handle partial reads error: written amount is not handled - --> tests/ui/unused_io_amount.rs:128:5 + --> tests/ui/unused_io_amount.rs:129:5 | LL | w.write(b"hello world").await.unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -162,7 +162,7 @@ LL | w.write(b"hello world").await.unwrap(); = help: use `AsyncWriteExt::write_all` instead, or handle partial writes error: read amount is not handled - --> tests/ui/unused_io_amount.rs:134:5 + --> tests/ui/unused_io_amount.rs:135:5 | LL | r.read(&mut buf[..]).await.unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -170,14 +170,14 @@ LL | r.read(&mut buf[..]).await.unwrap(); = help: use `AsyncReadExt::read_exact` instead, or handle partial reads error: written amount is not handled - --> tests/ui/unused_io_amount.rs:147:11 + --> tests/ui/unused_io_amount.rs:148:11 | LL | match s.write(b"test") { | ^^^^^^^^^^^^^^^^ | = help: use `Write::write_all` instead, or handle partial writes note: the result is consumed here, but the amount of I/O bytes remains unhandled - --> tests/ui/unused_io_amount.rs:149:9 + --> tests/ui/unused_io_amount.rs:150:9 | LL | Ok(_) => todo!(), | ^^^^^ @@ -196,66 +196,66 @@ LL | Ok(_) => todo!(), | ^^^^^ error: read amount is not handled - --> tests/ui/unused_io_amount.rs:164:11 + --> tests/ui/unused_io_amount.rs:163:11 | LL | match s.read(&mut [0u8; 4]) { | ^^^^^^^^^^^^^^^^^^^^^ | = help: use `Read::read_exact` instead, or handle partial reads note: the result is consumed here, but the amount of I/O bytes remains unhandled - --> tests/ui/unused_io_amount.rs:166:9 + --> tests/ui/unused_io_amount.rs:165:9 | LL | Ok(_) => todo!(), | ^^^^^ error: written amount is not handled - --> tests/ui/unused_io_amount.rs:173:11 + --> tests/ui/unused_io_amount.rs:171:11 | LL | match s.write(b"test") { | ^^^^^^^^^^^^^^^^ | = help: use `Write::write_all` instead, or handle partial writes note: the result is consumed here, but the amount of I/O bytes remains unhandled - --> tests/ui/unused_io_amount.rs:175:9 + --> tests/ui/unused_io_amount.rs:173:9 | LL | Ok(_) => todo!(), | ^^^^^ error: read amount is not handled - --> tests/ui/unused_io_amount.rs:186:8 + --> tests/ui/unused_io_amount.rs:183:8 | LL | if let Ok(_) = s.read(&mut [0u8; 4]) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use `Read::read_exact` instead, or handle partial reads note: the result is consumed here, but the amount of I/O bytes remains unhandled - --> tests/ui/unused_io_amount.rs:186:12 + --> tests/ui/unused_io_amount.rs:183:12 | LL | if let Ok(_) = s.read(&mut [0u8; 4]) { | ^^^^^ error: written amount is not handled - --> tests/ui/unused_io_amount.rs:193:8 + --> tests/ui/unused_io_amount.rs:190:8 | LL | if let Ok(_) = s.write(b"test") { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use `Write::write_all` instead, or handle partial writes note: the result is consumed here, but the amount of I/O bytes remains unhandled - --> tests/ui/unused_io_amount.rs:193:12 + --> tests/ui/unused_io_amount.rs:190:12 | LL | if let Ok(_) = s.write(b"test") { | ^^^^^ error: written amount is not handled - --> tests/ui/unused_io_amount.rs:200:8 + --> tests/ui/unused_io_amount.rs:197:8 | LL | if let Ok(..) = s.write(b"test") { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use `Write::write_all` instead, or handle partial writes note: the result is consumed here, but the amount of I/O bytes remains unhandled - --> tests/ui/unused_io_amount.rs:200:12 + --> tests/ui/unused_io_amount.rs:197:12 | LL | if let Ok(..) = s.write(b"test") { | ^^^^^^ diff --git a/tests/ui/unused_peekable.rs b/tests/ui/unused_peekable.rs index 5865bba43508..8382db3be005 100644 --- a/tests/ui/unused_peekable.rs +++ b/tests/ui/unused_peekable.rs @@ -11,17 +11,20 @@ fn main() { #[allow(clippy::unused_unit)] fn invalid() { let peekable = std::iter::empty::().peekable(); - //~^ ERROR: `peek` never called on `Peekable` iterator + //~^ unused_peekable + // Only lint `new_local` let old_local = std::iter::empty::().peekable(); let new_local = old_local; - //~^ ERROR: `peek` never called on `Peekable` iterator + //~^ unused_peekable + // Behind mut ref let mut by_mut_ref_test = std::iter::empty::().peekable(); let by_mut_ref = &mut by_mut_ref_test; - //~^ ERROR: `peek` never called on `Peekable` iterator + //~^ unused_peekable + // Explicitly returns `Peekable` fn returns_peekable() -> Peekable> { @@ -29,26 +32,31 @@ fn invalid() { } let peekable_from_fn = returns_peekable(); - //~^ ERROR: `peek` never called on `Peekable` iterator + //~^ unused_peekable + // Using a method not exclusive to `Peekable` let mut peekable_using_iterator_method = std::iter::empty::().peekable(); - //~^ ERROR: `peek` never called on `Peekable` iterator + //~^ unused_peekable + peekable_using_iterator_method.next(); // Passed by ref to another function fn takes_ref(_peek: &Peekable>) {} let passed_along_ref = std::iter::empty::().peekable(); - //~^ ERROR: `peek` never called on `Peekable` iterator + //~^ unused_peekable + takes_ref(&passed_along_ref); // `by_ref` without `peek` let mut by_ref_test = std::iter::empty::().peekable(); let _by_ref = by_ref_test.by_ref(); - //~^ ERROR: `peek` never called on `Peekable` iterator + //~^ unused_peekable + let mut peekable_in_for_loop = std::iter::empty::().peekable(); - //~^ ERROR: `peek` never called on `Peekable` iterator + //~^ unused_peekable + for x in peekable_in_for_loop {} } diff --git a/tests/ui/unused_peekable.stderr b/tests/ui/unused_peekable.stderr index 00c6a52bab33..9b49e32fa8ba 100644 --- a/tests/ui/unused_peekable.stderr +++ b/tests/ui/unused_peekable.stderr @@ -9,7 +9,7 @@ LL | let peekable = std::iter::empty::().peekable(); = help: to override `-D warnings` add `#[allow(clippy::unused_peekable)]` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:18:9 + --> tests/ui/unused_peekable.rs:19:9 | LL | let new_local = old_local; | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let new_local = old_local; = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:23:9 + --> tests/ui/unused_peekable.rs:25:9 | LL | let by_mut_ref = &mut by_mut_ref_test; | ^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let by_mut_ref = &mut by_mut_ref_test; = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:31:9 + --> tests/ui/unused_peekable.rs:34:9 | LL | let peekable_from_fn = returns_peekable(); | ^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let peekable_from_fn = returns_peekable(); = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:35:13 + --> tests/ui/unused_peekable.rs:39:13 | LL | let mut peekable_using_iterator_method = std::iter::empty::().peekable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let mut peekable_using_iterator_method = std::iter::empty::().peek = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:41:9 + --> tests/ui/unused_peekable.rs:46:9 | LL | let passed_along_ref = std::iter::empty::().peekable(); | ^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let passed_along_ref = std::iter::empty::().peekable(); = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:47:9 + --> tests/ui/unused_peekable.rs:53:9 | LL | let _by_ref = by_ref_test.by_ref(); | ^^^^^^^ @@ -57,7 +57,7 @@ LL | let _by_ref = by_ref_test.by_ref(); = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:50:13 + --> tests/ui/unused_peekable.rs:57:13 | LL | let mut peekable_in_for_loop = std::iter::empty::().peekable(); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unused_result_ok.fixed b/tests/ui/unused_result_ok.fixed index e78fde5c9e3c..faedd96216c2 100644 --- a/tests/ui/unused_result_ok.fixed +++ b/tests/ui/unused_result_ok.fixed @@ -7,6 +7,7 @@ extern crate proc_macros; fn bad_style(x: &str) { let _ = x.parse::(); + //~^ unused_result_ok } fn good_style(x: &str) -> Option { @@ -16,6 +17,7 @@ fn good_style(x: &str) -> Option { #[rustfmt::skip] fn strange_parse(x: &str) { let _ = x . parse::(); + //~^ unused_result_ok } macro_rules! v { @@ -27,11 +29,13 @@ macro_rules! v { macro_rules! w { () => { let _ = Ok::<(), ()>(()); + //~^ unused_result_ok }; } fn main() { let _ = v!(); + //~^ unused_result_ok w!(); external! { diff --git a/tests/ui/unused_result_ok.rs b/tests/ui/unused_result_ok.rs index 117d64c4cec6..6ab974861b63 100644 --- a/tests/ui/unused_result_ok.rs +++ b/tests/ui/unused_result_ok.rs @@ -7,6 +7,7 @@ extern crate proc_macros; fn bad_style(x: &str) { x.parse::().ok(); + //~^ unused_result_ok } fn good_style(x: &str) -> Option { @@ -16,6 +17,7 @@ fn good_style(x: &str) -> Option { #[rustfmt::skip] fn strange_parse(x: &str) { x . parse::() . ok (); + //~^ unused_result_ok } macro_rules! v { @@ -27,11 +29,13 @@ macro_rules! v { macro_rules! w { () => { Ok::<(), ()>(()).ok(); + //~^ unused_result_ok }; } fn main() { v!().ok(); + //~^ unused_result_ok w!(); external! { diff --git a/tests/ui/unused_result_ok.stderr b/tests/ui/unused_result_ok.stderr index 241e0c71261e..e6fbd8666514 100644 --- a/tests/ui/unused_result_ok.stderr +++ b/tests/ui/unused_result_ok.stderr @@ -12,7 +12,7 @@ LL | let _ = x.parse::(); | ~~~~~~~~~~~~~~~~~~~~~~~~ error: ignoring a result with `.ok()` is misleading - --> tests/ui/unused_result_ok.rs:18:5 + --> tests/ui/unused_result_ok.rs:19:5 | LL | x . parse::() . ok (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = x . parse::(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: ignoring a result with `.ok()` is misleading - --> tests/ui/unused_result_ok.rs:34:5 + --> tests/ui/unused_result_ok.rs:37:5 | LL | v!().ok(); | ^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = v!(); | ~~~~~~~~~~~~ error: ignoring a result with `.ok()` is misleading - --> tests/ui/unused_result_ok.rs:29:9 + --> tests/ui/unused_result_ok.rs:31:9 | LL | Ok::<(), ()>(()).ok(); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unused_rounding.fixed b/tests/ui/unused_rounding.fixed index 7af2c8650a3d..461d97c55531 100644 --- a/tests/ui/unused_rounding.fixed +++ b/tests/ui/unused_rounding.fixed @@ -4,15 +4,20 @@ fn main() { let _ = 1f32; + //~^ unused_rounding let _ = 1.0f64; + //~^ unused_rounding let _ = 1.00f32; + //~^ unused_rounding let _ = 2e-54f64.floor(); // issue9866 let _ = 3.3_f32.round(); let _ = 3.3_f64.round(); let _ = 3.0_f32; + //~^ unused_rounding let _ = 3_3.0_0_f32; + //~^ unused_rounding let _ = 3_3.0_1_f64.round(); } diff --git a/tests/ui/unused_rounding.rs b/tests/ui/unused_rounding.rs index 1b0b22a9b685..0d5ebf941a5e 100644 --- a/tests/ui/unused_rounding.rs +++ b/tests/ui/unused_rounding.rs @@ -4,15 +4,20 @@ fn main() { let _ = 1f32.ceil(); + //~^ unused_rounding let _ = 1.0f64.floor(); + //~^ unused_rounding let _ = 1.00f32.round(); + //~^ unused_rounding let _ = 2e-54f64.floor(); // issue9866 let _ = 3.3_f32.round(); let _ = 3.3_f64.round(); let _ = 3.0_f32.round(); + //~^ unused_rounding let _ = 3_3.0_0_f32.round(); + //~^ unused_rounding let _ = 3_3.0_1_f64.round(); } diff --git a/tests/ui/unused_rounding.stderr b/tests/ui/unused_rounding.stderr index c5ae2da75f84..494b0cc7352d 100644 --- a/tests/ui/unused_rounding.stderr +++ b/tests/ui/unused_rounding.stderr @@ -8,25 +8,25 @@ LL | let _ = 1f32.ceil(); = help: to override `-D warnings` add `#[allow(clippy::unused_rounding)]` error: used the `floor` method with a whole number float - --> tests/ui/unused_rounding.rs:7:13 + --> tests/ui/unused_rounding.rs:8:13 | LL | let _ = 1.0f64.floor(); | ^^^^^^^^^^^^^^ help: remove the `floor` method call: `1.0f64` error: used the `round` method with a whole number float - --> tests/ui/unused_rounding.rs:8:13 + --> tests/ui/unused_rounding.rs:10:13 | LL | let _ = 1.00f32.round(); | ^^^^^^^^^^^^^^^ help: remove the `round` method call: `1.00f32` error: used the `round` method with a whole number float - --> tests/ui/unused_rounding.rs:14:13 + --> tests/ui/unused_rounding.rs:17:13 | LL | let _ = 3.0_f32.round(); | ^^^^^^^^^^^^^^^ help: remove the `round` method call: `3.0_f32` error: used the `round` method with a whole number float - --> tests/ui/unused_rounding.rs:16:13 + --> tests/ui/unused_rounding.rs:20:13 | LL | let _ = 3_3.0_0_f32.round(); | ^^^^^^^^^^^^^^^^^^^ help: remove the `round` method call: `3_3.0_0_f32` diff --git a/tests/ui/unused_self.rs b/tests/ui/unused_self.rs index d3d06037cb49..fac0b36c33a4 100644 --- a/tests/ui/unused_self.rs +++ b/tests/ui/unused_self.rs @@ -9,25 +9,34 @@ mod unused_self { impl A { fn unused_self_move(self) {} - //~^ ERROR: unused `self` argument + //~^ unused_self + fn unused_self_ref(&self) {} - //~^ ERROR: unused `self` argument + //~^ unused_self + fn unused_self_mut_ref(&mut self) {} - //~^ ERROR: unused `self` argument + //~^ unused_self + fn unused_self_pin_ref(self: Pin<&Self>) {} - //~^ ERROR: unused `self` argument + //~^ unused_self + fn unused_self_pin_mut_ref(self: Pin<&mut Self>) {} - //~^ ERROR: unused `self` argument + //~^ unused_self + fn unused_self_pin_nested(self: Pin>) {} - //~^ ERROR: unused `self` argument + //~^ unused_self + fn unused_self_box(self: Box) {} - //~^ ERROR: unused `self` argument + //~^ unused_self + fn unused_with_other_used_args(&self, x: u8, y: u8) -> u8 { - //~^ ERROR: unused `self` argument + //~^ unused_self + x + y } fn unused_self_class_method(&self) { - //~^ ERROR: unused `self` argument + //~^ unused_self + Self::static_method(); } diff --git a/tests/ui/unused_self.stderr b/tests/ui/unused_self.stderr index 5d5f1b643a4a..e29f5f96c886 100644 --- a/tests/ui/unused_self.stderr +++ b/tests/ui/unused_self.stderr @@ -9,7 +9,7 @@ LL | fn unused_self_move(self) {} = help: to override `-D warnings` add `#[allow(clippy::unused_self)]` error: unused `self` argument - --> tests/ui/unused_self.rs:13:28 + --> tests/ui/unused_self.rs:14:28 | LL | fn unused_self_ref(&self) {} | ^^^^^ @@ -17,7 +17,7 @@ LL | fn unused_self_ref(&self) {} = help: consider refactoring to an associated function error: unused `self` argument - --> tests/ui/unused_self.rs:15:32 + --> tests/ui/unused_self.rs:17:32 | LL | fn unused_self_mut_ref(&mut self) {} | ^^^^^^^^^ @@ -25,7 +25,7 @@ LL | fn unused_self_mut_ref(&mut self) {} = help: consider refactoring to an associated function error: unused `self` argument - --> tests/ui/unused_self.rs:17:32 + --> tests/ui/unused_self.rs:20:32 | LL | fn unused_self_pin_ref(self: Pin<&Self>) {} | ^^^^ @@ -33,7 +33,7 @@ LL | fn unused_self_pin_ref(self: Pin<&Self>) {} = help: consider refactoring to an associated function error: unused `self` argument - --> tests/ui/unused_self.rs:19:36 + --> tests/ui/unused_self.rs:23:36 | LL | fn unused_self_pin_mut_ref(self: Pin<&mut Self>) {} | ^^^^ @@ -41,7 +41,7 @@ LL | fn unused_self_pin_mut_ref(self: Pin<&mut Self>) {} = help: consider refactoring to an associated function error: unused `self` argument - --> tests/ui/unused_self.rs:21:35 + --> tests/ui/unused_self.rs:26:35 | LL | fn unused_self_pin_nested(self: Pin>) {} | ^^^^ @@ -49,7 +49,7 @@ LL | fn unused_self_pin_nested(self: Pin>) {} = help: consider refactoring to an associated function error: unused `self` argument - --> tests/ui/unused_self.rs:23:28 + --> tests/ui/unused_self.rs:29:28 | LL | fn unused_self_box(self: Box) {} | ^^^^ @@ -57,7 +57,7 @@ LL | fn unused_self_box(self: Box) {} = help: consider refactoring to an associated function error: unused `self` argument - --> tests/ui/unused_self.rs:25:40 + --> tests/ui/unused_self.rs:32:40 | LL | fn unused_with_other_used_args(&self, x: u8, y: u8) -> u8 { | ^^^^^ @@ -65,7 +65,7 @@ LL | fn unused_with_other_used_args(&self, x: u8, y: u8) -> u8 { = help: consider refactoring to an associated function error: unused `self` argument - --> tests/ui/unused_self.rs:29:37 + --> tests/ui/unused_self.rs:37:37 | LL | fn unused_self_class_method(&self) { | ^^^^^ diff --git a/tests/ui/unused_trait_names.fixed b/tests/ui/unused_trait_names.fixed index 7dfd0db65aa1..17e32ddfd9d9 100644 --- a/tests/ui/unused_trait_names.fixed +++ b/tests/ui/unused_trait_names.fixed @@ -10,6 +10,7 @@ fn main() {} fn bad() { use std::any::Any as _; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } @@ -29,6 +30,7 @@ fn used_good() { fn multi_bad() { use std::any::{self, Any as _, TypeId}; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } @@ -41,12 +43,14 @@ fn multi_good() { fn renamed_bad() { use std::any::Any as _; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } fn multi_renamed_bad() { use std::any::{Any as _, TypeId as MyTypeId}; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } @@ -70,6 +74,7 @@ mod used_mod_good { mod mod_import_bad { fn mod_import_bad() { use std::any::Any as _; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } @@ -111,6 +116,7 @@ mod nested_mod_used_good3 { mod nested_mod_used_bad { use std::any::Any as _; + //~^ unused_trait_names fn bar() { println!("{:?}", "foo".type_id()); @@ -130,6 +136,7 @@ mod nested_mod_used_bad { // the code would still compile. mod nested_mod_used_bad1 { use std::any::Any as _; + //~^ unused_trait_names use std::any::Any as MyAny; @@ -189,6 +196,7 @@ fn msrv_1_32() { #[clippy::msrv = "1.33"] fn msrv_1_33() { use simple_trait::{MyStruct, MyTrait as _}; + //~^ unused_trait_names MyStruct.do_things(); } @@ -196,6 +204,7 @@ mod lint_inside_macro_expansion_bad { macro_rules! foo { () => { use std::any::Any as _; + //~^ unused_trait_names fn bar() { "bar".type_id(); } @@ -243,6 +252,7 @@ proc_macros::with_span!( #[warn(unused)] mod unused_import { + //~^ ERROR: unused import } #[allow(clippy::unused_trait_names)] diff --git a/tests/ui/unused_trait_names.rs b/tests/ui/unused_trait_names.rs index ce44eedbc79c..3cf8597e5351 100644 --- a/tests/ui/unused_trait_names.rs +++ b/tests/ui/unused_trait_names.rs @@ -10,6 +10,7 @@ fn main() {} fn bad() { use std::any::Any; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } @@ -29,6 +30,7 @@ fn used_good() { fn multi_bad() { use std::any::{self, Any, TypeId}; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } @@ -41,12 +43,14 @@ fn multi_good() { fn renamed_bad() { use std::any::Any as MyAny; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } fn multi_renamed_bad() { use std::any::{Any as MyAny, TypeId as MyTypeId}; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } @@ -70,6 +74,7 @@ mod used_mod_good { mod mod_import_bad { fn mod_import_bad() { use std::any::Any; + //~^ unused_trait_names println!("{:?}", "foo".type_id()); } @@ -111,6 +116,7 @@ mod nested_mod_used_good3 { mod nested_mod_used_bad { use std::any::Any; + //~^ unused_trait_names fn bar() { println!("{:?}", "foo".type_id()); @@ -130,6 +136,7 @@ mod nested_mod_used_bad { // the code would still compile. mod nested_mod_used_bad1 { use std::any::Any; + //~^ unused_trait_names use std::any::Any as MyAny; @@ -189,6 +196,7 @@ fn msrv_1_32() { #[clippy::msrv = "1.33"] fn msrv_1_33() { use simple_trait::{MyStruct, MyTrait}; + //~^ unused_trait_names MyStruct.do_things(); } @@ -196,6 +204,7 @@ mod lint_inside_macro_expansion_bad { macro_rules! foo { () => { use std::any::Any; + //~^ unused_trait_names fn bar() { "bar".type_id(); } @@ -243,6 +252,7 @@ proc_macros::with_span!( #[warn(unused)] mod unused_import { use std::any::Any; + //~^ ERROR: unused import } #[allow(clippy::unused_trait_names)] diff --git a/tests/ui/unused_trait_names.stderr b/tests/ui/unused_trait_names.stderr index f59d8f58a170..3183289d8533 100644 --- a/tests/ui/unused_trait_names.stderr +++ b/tests/ui/unused_trait_names.stderr @@ -1,5 +1,5 @@ error: unused import: `std::any::Any` - --> tests/ui/unused_trait_names.rs:245:9 + --> tests/ui/unused_trait_names.rs:254:9 | LL | use std::any::Any; | ^^^^^^^^^^^^^ @@ -17,49 +17,49 @@ LL | use std::any::Any; = help: to override `-D warnings` add `#[allow(clippy::unused_trait_names)]` error: importing trait that is only used anonymously - --> tests/ui/unused_trait_names.rs:31:26 + --> tests/ui/unused_trait_names.rs:32:26 | LL | use std::any::{self, Any, TypeId}; | ^^^ help: use: `Any as _` error: importing trait that is only used anonymously - --> tests/ui/unused_trait_names.rs:43:19 + --> tests/ui/unused_trait_names.rs:45:19 | LL | use std::any::Any as MyAny; | ^^^^^^^^^^^^ help: use: `Any as _` error: importing trait that is only used anonymously - --> tests/ui/unused_trait_names.rs:49:20 + --> tests/ui/unused_trait_names.rs:52:20 | LL | use std::any::{Any as MyAny, TypeId as MyTypeId}; | ^^^^^^^^^^^^ help: use: `Any as _` error: importing trait that is only used anonymously - --> tests/ui/unused_trait_names.rs:72:23 + --> tests/ui/unused_trait_names.rs:76:23 | LL | use std::any::Any; | ^^^ help: use: `Any as _` error: importing trait that is only used anonymously - --> tests/ui/unused_trait_names.rs:113:19 + --> tests/ui/unused_trait_names.rs:118:19 | LL | use std::any::Any; | ^^^ help: use: `Any as _` error: importing trait that is only used anonymously - --> tests/ui/unused_trait_names.rs:132:19 + --> tests/ui/unused_trait_names.rs:138:19 | LL | use std::any::Any; | ^^^ help: use: `Any as _` error: importing trait that is only used anonymously - --> tests/ui/unused_trait_names.rs:191:34 + --> tests/ui/unused_trait_names.rs:198:34 | LL | use simple_trait::{MyStruct, MyTrait}; | ^^^^^^^ help: use: `MyTrait as _` error: importing trait that is only used anonymously - --> tests/ui/unused_trait_names.rs:198:27 + --> tests/ui/unused_trait_names.rs:206:27 | LL | use std::any::Any; | ^^^ help: use: `Any as _` diff --git a/tests/ui/unused_unit.fixed b/tests/ui/unused_unit.fixed index 04fe2d3b7af1..e3c02681c9fd 100644 --- a/tests/ui/unused_unit.fixed +++ b/tests/ui/unused_unit.fixed @@ -18,8 +18,12 @@ struct Unitter; impl Unitter { #[allow(clippy::no_effect)] pub fn get_unit(&self, f: F, _g: G) + //~^ unused_unit + //~| unused_unit where G: Fn() { + //~^ unused_unit let _y: &dyn Fn() = &f; + //~^ unused_unit (); // this should not lint, as it's not in return type position } } @@ -27,25 +31,35 @@ impl Unitter { impl Into<()> for Unitter { #[rustfmt::skip] fn into(self) { + //~^ unused_unit + //~^ unused_unit } } trait Trait { fn redundant(&self, _f: F, _g: G, _h: H) + //~^ unused_unit where G: FnMut(), + //~^ unused_unit H: Fn(); + //~^ unused_unit } impl Trait for Unitter { fn redundant(&self, _f: F, _g: G, _h: H) + //~^ unused_unit where G: FnMut(), + //~^ unused_unit H: Fn() {} + //~^ unused_unit } fn return_unit() { } +//~^ unused_unit +//~| unused_unit #[allow(clippy::needless_return)] #[allow(clippy::never_loop)] @@ -56,8 +70,10 @@ fn main() { return_unit(); loop { break; + //~^ unused_unit } return; + //~^ unused_unit } // https://github.com/rust-lang/rust-clippy/issues/4076 @@ -75,12 +91,15 @@ fn foo() { #[rustfmt::skip] fn test(){} +//~^ unused_unit #[rustfmt::skip] fn test2(){} +//~^ unused_unit #[rustfmt::skip] fn test3(){} +//~^ unused_unit fn macro_expr() { macro_rules! e { diff --git a/tests/ui/unused_unit.rs b/tests/ui/unused_unit.rs index 25c2ed59873a..4353026c594c 100644 --- a/tests/ui/unused_unit.rs +++ b/tests/ui/unused_unit.rs @@ -18,8 +18,12 @@ struct Unitter; impl Unitter { #[allow(clippy::no_effect)] pub fn get_unit (), G>(&self, f: F, _g: G) -> () + //~^ unused_unit + //~| unused_unit where G: Fn() -> () { + //~^ unused_unit let _y: &dyn Fn() -> () = &f; + //~^ unused_unit (); // this should not lint, as it's not in return type position } } @@ -27,25 +31,35 @@ impl Unitter { impl Into<()> for Unitter { #[rustfmt::skip] fn into(self) -> () { + //~^ unused_unit () + //~^ unused_unit } } trait Trait { fn redundant (), G, H>(&self, _f: F, _g: G, _h: H) + //~^ unused_unit where G: FnMut() -> (), + //~^ unused_unit H: Fn() -> (); + //~^ unused_unit } impl Trait for Unitter { fn redundant (), G, H>(&self, _f: F, _g: G, _h: H) + //~^ unused_unit where G: FnMut() -> (), + //~^ unused_unit H: Fn() -> () {} + //~^ unused_unit } fn return_unit() -> () { () } +//~^ unused_unit +//~| unused_unit #[allow(clippy::needless_return)] #[allow(clippy::never_loop)] @@ -56,8 +70,10 @@ fn main() { return_unit(); loop { break(); + //~^ unused_unit } return(); + //~^ unused_unit } // https://github.com/rust-lang/rust-clippy/issues/4076 @@ -75,12 +91,15 @@ fn foo() { #[rustfmt::skip] fn test()->(){} +//~^ unused_unit #[rustfmt::skip] fn test2() ->(){} +//~^ unused_unit #[rustfmt::skip] fn test3()-> (){} +//~^ unused_unit fn macro_expr() { macro_rules! e { diff --git a/tests/ui/unused_unit.stderr b/tests/ui/unused_unit.stderr index 104159ad5fc6..172fe0655028 100644 --- a/tests/ui/unused_unit.stderr +++ b/tests/ui/unused_unit.stderr @@ -17,49 +17,31 @@ LL | pub fn get_unit (), G>(&self, f: F, _g: G) -> () | ^^^^^^ help: remove the `-> ()` error: unneeded unit return type - --> tests/ui/unused_unit.rs:21:18 + --> tests/ui/unused_unit.rs:23:18 | LL | where G: Fn() -> () { | ^^^^^^ help: remove the `-> ()` error: unneeded unit return type - --> tests/ui/unused_unit.rs:22:26 + --> tests/ui/unused_unit.rs:25:26 | LL | let _y: &dyn Fn() -> () = &f; | ^^^^^^ help: remove the `-> ()` error: unneeded unit return type - --> tests/ui/unused_unit.rs:29:18 + --> tests/ui/unused_unit.rs:33:18 | LL | fn into(self) -> () { | ^^^^^^ help: remove the `-> ()` error: unneeded unit expression - --> tests/ui/unused_unit.rs:30:9 + --> tests/ui/unused_unit.rs:35:9 | LL | () | ^^ help: remove the final `()` error: unneeded unit return type - --> tests/ui/unused_unit.rs:35:29 - | -LL | fn redundant (), G, H>(&self, _f: F, _g: G, _h: H) - | ^^^^^^ help: remove the `-> ()` - -error: unneeded unit return type - --> tests/ui/unused_unit.rs:37:19 - | -LL | G: FnMut() -> (), - | ^^^^^^ help: remove the `-> ()` - -error: unneeded unit return type - --> tests/ui/unused_unit.rs:38:16 - | -LL | H: Fn() -> (); - | ^^^^^^ help: remove the `-> ()` - -error: unneeded unit return type - --> tests/ui/unused_unit.rs:42:29 + --> tests/ui/unused_unit.rs:41:29 | LL | fn redundant (), G, H>(&self, _f: F, _g: G, _h: H) | ^^^^^^ help: remove the `-> ()` @@ -71,49 +53,67 @@ LL | G: FnMut() -> (), | ^^^^^^ help: remove the `-> ()` error: unneeded unit return type - --> tests/ui/unused_unit.rs:45:16 + --> tests/ui/unused_unit.rs:46:16 + | +LL | H: Fn() -> (); + | ^^^^^^ help: remove the `-> ()` + +error: unneeded unit return type + --> tests/ui/unused_unit.rs:51:29 + | +LL | fn redundant (), G, H>(&self, _f: F, _g: G, _h: H) + | ^^^^^^ help: remove the `-> ()` + +error: unneeded unit return type + --> tests/ui/unused_unit.rs:54:19 + | +LL | G: FnMut() -> (), + | ^^^^^^ help: remove the `-> ()` + +error: unneeded unit return type + --> tests/ui/unused_unit.rs:56:16 | LL | H: Fn() -> () {} | ^^^^^^ help: remove the `-> ()` error: unneeded unit return type - --> tests/ui/unused_unit.rs:48:17 + --> tests/ui/unused_unit.rs:60:17 | LL | fn return_unit() -> () { () } | ^^^^^^ help: remove the `-> ()` error: unneeded unit expression - --> tests/ui/unused_unit.rs:48:26 + --> tests/ui/unused_unit.rs:60:26 | LL | fn return_unit() -> () { () } | ^^ help: remove the final `()` error: unneeded `()` - --> tests/ui/unused_unit.rs:58:14 + --> tests/ui/unused_unit.rs:72:14 | LL | break(); | ^^ help: remove the `()` error: unneeded `()` - --> tests/ui/unused_unit.rs:60:11 + --> tests/ui/unused_unit.rs:75:11 | LL | return(); | ^^ help: remove the `()` error: unneeded unit return type - --> tests/ui/unused_unit.rs:77:10 + --> tests/ui/unused_unit.rs:93:10 | LL | fn test()->(){} | ^^^^ help: remove the `-> ()` error: unneeded unit return type - --> tests/ui/unused_unit.rs:80:11 + --> tests/ui/unused_unit.rs:97:11 | LL | fn test2() ->(){} | ^^^^^ help: remove the `-> ()` error: unneeded unit return type - --> tests/ui/unused_unit.rs:83:11 + --> tests/ui/unused_unit.rs:101:11 | LL | fn test3()-> (){} | ^^^^^ help: remove the `-> ()` diff --git a/tests/ui/unwrap.rs b/tests/ui/unwrap.rs index 8ad7e98503bf..637d2da3750e 100644 --- a/tests/ui/unwrap.rs +++ b/tests/ui/unwrap.rs @@ -4,15 +4,18 @@ fn unwrap_option() { let opt = Some(0); let _ = opt.unwrap(); - //~^ ERROR: used `unwrap()` on an `Option` value + //~^ unwrap_used + } fn unwrap_result() { let res: Result = Ok(0); let _ = res.unwrap(); - //~^ ERROR: used `unwrap()` on a `Result` value + //~^ unwrap_used + let _ = res.unwrap_err(); - //~^ ERROR: used `unwrap_err()` on a `Result` value + //~^ unwrap_used + } fn main() { diff --git a/tests/ui/unwrap.stderr b/tests/ui/unwrap.stderr index 3c1b37bc3d9b..c568d8308200 100644 --- a/tests/ui/unwrap.stderr +++ b/tests/ui/unwrap.stderr @@ -10,7 +10,7 @@ LL | let _ = opt.unwrap(); = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]` error: used `unwrap()` on a `Result` value - --> tests/ui/unwrap.rs:12:13 + --> tests/ui/unwrap.rs:13:13 | LL | let _ = res.unwrap(); | ^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | let _ = res.unwrap(); = help: consider using `expect()` to provide a better panic message error: used `unwrap_err()` on a `Result` value - --> tests/ui/unwrap.rs:14:13 + --> tests/ui/unwrap.rs:16:13 | LL | let _ = res.unwrap_err(); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unwrap_expect_used.rs b/tests/ui/unwrap_expect_used.rs index bab99f2ffbdd..c2c9db775370 100644 --- a/tests/ui/unwrap_expect_used.rs +++ b/tests/ui/unwrap_expect_used.rs @@ -25,9 +25,11 @@ impl OptionExt for Option { fn main() { Some(3).unwrap(); - //~^ ERROR: used `unwrap()` on an `Option` value + //~^ unwrap_used + Some(3).expect("Hello world!"); - //~^ ERROR: used `expect()` on an `Option` value + //~^ expect_used + // Don't trigger on unwrap_err on an option Some(3).unwrap_err(); @@ -43,13 +45,16 @@ fn main() { let a: Result = Ok(3); a.unwrap(); - //~^ ERROR: used `unwrap()` on a `Result` value + //~^ unwrap_used + a.expect("Hello world!"); - //~^ ERROR: used `expect()` on a `Result` value + //~^ expect_used + a.unwrap_err(); - //~^ ERROR: used `unwrap_err()` on a `Result` value + //~^ unwrap_used + a.expect_err("Hello error!"); - //~^ ERROR: used `expect_err()` on a `Result` value + //~^ expect_used // Don't trigger in compile time contexts by default const SOME: Option = Some(3); diff --git a/tests/ui/unwrap_expect_used.stderr b/tests/ui/unwrap_expect_used.stderr index 9069522a4df1..7476e372bcbb 100644 --- a/tests/ui/unwrap_expect_used.stderr +++ b/tests/ui/unwrap_expect_used.stderr @@ -9,7 +9,7 @@ LL | Some(3).unwrap(); = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]` error: used `expect()` on an `Option` value - --> tests/ui/unwrap_expect_used.rs:29:5 + --> tests/ui/unwrap_expect_used.rs:30:5 | LL | Some(3).expect("Hello world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | Some(3).expect("Hello world!"); = help: to override `-D warnings` add `#[allow(clippy::expect_used)]` error: used `unwrap()` on a `Result` value - --> tests/ui/unwrap_expect_used.rs:45:5 + --> tests/ui/unwrap_expect_used.rs:47:5 | LL | a.unwrap(); | ^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | a.unwrap(); = note: if this value is an `Err`, it will panic error: used `expect()` on a `Result` value - --> tests/ui/unwrap_expect_used.rs:47:5 + --> tests/ui/unwrap_expect_used.rs:50:5 | LL | a.expect("Hello world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | a.expect("Hello world!"); = note: if this value is an `Err`, it will panic error: used `unwrap_err()` on a `Result` value - --> tests/ui/unwrap_expect_used.rs:49:5 + --> tests/ui/unwrap_expect_used.rs:53:5 | LL | a.unwrap_err(); | ^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL | a.unwrap_err(); = note: if this value is an `Ok`, it will panic error: used `expect_err()` on a `Result` value - --> tests/ui/unwrap_expect_used.rs:51:5 + --> tests/ui/unwrap_expect_used.rs:56:5 | LL | a.expect_err("Hello error!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unwrap_in_result.rs b/tests/ui/unwrap_in_result.rs index 62c6d959c84b..58235d138658 100644 --- a/tests/ui/unwrap_in_result.rs +++ b/tests/ui/unwrap_in_result.rs @@ -20,7 +20,8 @@ impl A { // should be detected fn bad_divisible_by_3(i_str: String) -> Result { - //~^ ERROR: used unwrap or expect in a function that returns result or option + //~^ unwrap_in_result + // checks whether a string represents a number divisible by 3 let i = i_str.parse::().unwrap(); if i % 3 == 0 { @@ -31,7 +32,8 @@ impl A { } fn example_option_expect(i_str: String) -> Option { - //~^ ERROR: used unwrap or expect in a function that returns result or option + //~^ unwrap_in_result + let i = i_str.parse::().expect("not a number"); if i % 3 == 0 { return Some(true); @@ -40,6 +42,7 @@ impl A { } fn in_closure(a: Option) -> Option { + //~^ unwrap_in_result let c = || a.unwrap(); Some(c()) } diff --git a/tests/ui/unwrap_in_result.stderr b/tests/ui/unwrap_in_result.stderr index 201d4ae36ae3..5e3eab813e07 100644 --- a/tests/ui/unwrap_in_result.stderr +++ b/tests/ui/unwrap_in_result.stderr @@ -2,16 +2,13 @@ error: used unwrap or expect in a function that returns result or option --> tests/ui/unwrap_in_result.rs:22:5 | LL | / fn bad_divisible_by_3(i_str: String) -> Result { -LL | | -LL | | // checks whether a string represents a number divisible by 3 -LL | | let i = i_str.parse::().unwrap(); ... | LL | | } | |_____^ | = help: unwrap and expect should not be used in a function that returns result or option note: potential non-recoverable error(s) - --> tests/ui/unwrap_in_result.rs:25:17 + --> tests/ui/unwrap_in_result.rs:26:17 | LL | let i = i_str.parse::().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,12 +16,12 @@ LL | let i = i_str.parse::().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::unwrap_in_result)]` error: used unwrap or expect in a function that returns result or option - --> tests/ui/unwrap_in_result.rs:33:5 + --> tests/ui/unwrap_in_result.rs:34:5 | LL | / fn example_option_expect(i_str: String) -> Option { LL | | +LL | | LL | | let i = i_str.parse::().expect("not a number"); -LL | | if i % 3 == 0 { ... | LL | | None LL | | } @@ -32,15 +29,16 @@ LL | | } | = help: unwrap and expect should not be used in a function that returns result or option note: potential non-recoverable error(s) - --> tests/ui/unwrap_in_result.rs:35:17 + --> tests/ui/unwrap_in_result.rs:37:17 | LL | let i = i_str.parse::().expect("not a number"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used unwrap or expect in a function that returns result or option - --> tests/ui/unwrap_in_result.rs:42:5 + --> tests/ui/unwrap_in_result.rs:44:5 | LL | / fn in_closure(a: Option) -> Option { +LL | | LL | | let c = || a.unwrap(); LL | | Some(c()) LL | | } @@ -48,7 +46,7 @@ LL | | } | = help: unwrap and expect should not be used in a function that returns result or option note: potential non-recoverable error(s) - --> tests/ui/unwrap_in_result.rs:43:20 + --> tests/ui/unwrap_in_result.rs:46:20 | LL | let c = || a.unwrap(); | ^^^^^^^^^^ diff --git a/tests/ui/unwrap_or.fixed b/tests/ui/unwrap_or.fixed index 62bc1966da6f..7a00d346cac5 100644 --- a/tests/ui/unwrap_or.fixed +++ b/tests/ui/unwrap_or.fixed @@ -3,11 +3,13 @@ fn main() { let s = Some(String::from("test string")).unwrap_or_else(|| "Fail".to_string()).len(); - //~^ ERROR: function call inside of `unwrap_or` - //~| NOTE: `-D clippy::or-fun-call` implied by `-D warnings` + //~^ or_fun_call + + } fn new_lines() { let s = Some(String::from("test string")).unwrap_or_else(|| "Fail".to_string()).len(); - //~^ ERROR: function call inside of `unwrap_or` + //~^ or_fun_call + } diff --git a/tests/ui/unwrap_or.rs b/tests/ui/unwrap_or.rs index e8e4b6b7168f..30779ac1b109 100644 --- a/tests/ui/unwrap_or.rs +++ b/tests/ui/unwrap_or.rs @@ -3,11 +3,13 @@ fn main() { let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len(); - //~^ ERROR: function call inside of `unwrap_or` - //~| NOTE: `-D clippy::or-fun-call` implied by `-D warnings` + //~^ or_fun_call + + } fn new_lines() { let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len(); - //~^ ERROR: function call inside of `unwrap_or` + //~^ or_fun_call + } diff --git a/tests/ui/unwrap_or.stderr b/tests/ui/unwrap_or.stderr index b712f8cf693d..b2c20a9e9b5e 100644 --- a/tests/ui/unwrap_or.stderr +++ b/tests/ui/unwrap_or.stderr @@ -8,7 +8,7 @@ LL | let s = Some(String::from("test string")).unwrap_or("Fail".to_string()) = help: to override `-D warnings` add `#[allow(clippy::or_fun_call)]` error: function call inside of `unwrap_or` - --> tests/ui/unwrap_or.rs:11:47 + --> tests/ui/unwrap_or.rs:12:47 | LL | let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| "Fail".to_string())` diff --git a/tests/ui/unwrap_or_else_default.fixed b/tests/ui/unwrap_or_else_default.fixed index 8d5d34175c52..561cbce473de 100644 --- a/tests/ui/unwrap_or_else_default.fixed +++ b/tests/ui/unwrap_or_else_default.fixed @@ -44,6 +44,7 @@ fn unwrap_or_else_default() { let with_new = Some(vec![1]); with_new.unwrap_or_default(); + //~^ unwrap_or_default let with_err: Result<_, ()> = Ok(vec![1]); with_err.unwrap_or_else(make); @@ -58,43 +59,56 @@ fn unwrap_or_else_default() { let with_real_default = None::; with_real_default.unwrap_or_default(); + //~^ unwrap_or_default let with_default_trait = Some(1); with_default_trait.unwrap_or_default(); + //~^ unwrap_or_default let with_default_type = Some(1); with_default_type.unwrap_or_default(); + //~^ unwrap_or_default let with_default_type: Option> = None; with_default_type.unwrap_or_default(); + //~^ unwrap_or_default let empty_string = None::; empty_string.unwrap_or_default(); + //~^ unwrap_or_default } fn type_certainty(option: Option>) { option.unwrap_or_default().push(1); + //~^ unwrap_or_default let option: std::option::Option> = None; option.unwrap_or_default().push(1); + //~^ unwrap_or_default let option: Option> = None; option.unwrap_or_default().push(1); + //~^ unwrap_or_default let option = std::option::Option::>::None; option.unwrap_or_default().push(1); + //~^ unwrap_or_default let option = Option::>::None; option.unwrap_or_default().push(1); + //~^ unwrap_or_default let option = std::option::Option::None::>; option.unwrap_or_default().push(1); + //~^ unwrap_or_default let option = Option::None::>; option.unwrap_or_default().push(1); + //~^ unwrap_or_default let option = None::>; option.unwrap_or_default().push(1); + //~^ unwrap_or_default // should not be changed: type annotation with infer, unconcretized initializer let option: Option> = None; @@ -111,6 +125,7 @@ fn type_certainty(option: Option>) { type Alias = Option>; let option: Alias = Option::>::Some(Vec::new()); option.unwrap_or_default().push(1); + //~^ unwrap_or_default } fn method_call_with_deref() { @@ -128,6 +143,7 @@ fn method_call_with_deref() { let inner_map = outer_map.get_mut(&option.unwrap()).unwrap(); let _ = inner_map.entry(0).or_default(); + //~^ unwrap_or_default } fn missing_suggested_method() { diff --git a/tests/ui/unwrap_or_else_default.rs b/tests/ui/unwrap_or_else_default.rs index adbcb4b44659..8389be964fe6 100644 --- a/tests/ui/unwrap_or_else_default.rs +++ b/tests/ui/unwrap_or_else_default.rs @@ -44,6 +44,7 @@ fn unwrap_or_else_default() { let with_new = Some(vec![1]); with_new.unwrap_or_else(Vec::new); + //~^ unwrap_or_default let with_err: Result<_, ()> = Ok(vec![1]); with_err.unwrap_or_else(make); @@ -58,43 +59,56 @@ fn unwrap_or_else_default() { let with_real_default = None::; with_real_default.unwrap_or_else(::default); + //~^ unwrap_or_default let with_default_trait = Some(1); with_default_trait.unwrap_or_else(Default::default); + //~^ unwrap_or_default let with_default_type = Some(1); with_default_type.unwrap_or_else(u64::default); + //~^ unwrap_or_default let with_default_type: Option> = None; with_default_type.unwrap_or_else(Vec::new); + //~^ unwrap_or_default let empty_string = None::; empty_string.unwrap_or_else(|| "".to_string()); + //~^ unwrap_or_default } fn type_certainty(option: Option>) { option.unwrap_or_else(Vec::new).push(1); + //~^ unwrap_or_default let option: std::option::Option> = None; option.unwrap_or_else(Vec::new).push(1); + //~^ unwrap_or_default let option: Option> = None; option.unwrap_or_else(Vec::new).push(1); + //~^ unwrap_or_default let option = std::option::Option::>::None; option.unwrap_or_else(Vec::new).push(1); + //~^ unwrap_or_default let option = Option::>::None; option.unwrap_or_else(Vec::new).push(1); + //~^ unwrap_or_default let option = std::option::Option::None::>; option.unwrap_or_else(Vec::new).push(1); + //~^ unwrap_or_default let option = Option::None::>; option.unwrap_or_else(Vec::new).push(1); + //~^ unwrap_or_default let option = None::>; option.unwrap_or_else(Vec::new).push(1); + //~^ unwrap_or_default // should not be changed: type annotation with infer, unconcretized initializer let option: Option> = None; @@ -111,6 +125,7 @@ fn type_certainty(option: Option>) { type Alias = Option>; let option: Alias = Option::>::Some(Vec::new()); option.unwrap_or_else(Vec::new).push(1); + //~^ unwrap_or_default } fn method_call_with_deref() { @@ -128,6 +143,7 @@ fn method_call_with_deref() { let inner_map = outer_map.get_mut(&option.unwrap()).unwrap(); let _ = inner_map.entry(0).or_insert_with(Default::default); + //~^ unwrap_or_default } fn missing_suggested_method() { diff --git a/tests/ui/unwrap_or_else_default.stderr b/tests/ui/unwrap_or_else_default.stderr index e4b4a0a1f6aa..a001f7e46add 100644 --- a/tests/ui/unwrap_or_else_default.stderr +++ b/tests/ui/unwrap_or_else_default.stderr @@ -8,47 +8,35 @@ LL | with_new.unwrap_or_else(Vec::new); = help: to override `-D warnings` add `#[allow(clippy::unwrap_or_default)]` error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:60:23 + --> tests/ui/unwrap_or_else_default.rs:61:23 | LL | with_real_default.unwrap_or_else(::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:63:24 + --> tests/ui/unwrap_or_else_default.rs:65:24 | LL | with_default_trait.unwrap_or_else(Default::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:66:23 + --> tests/ui/unwrap_or_else_default.rs:69:23 | LL | with_default_type.unwrap_or_else(u64::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:69:23 + --> tests/ui/unwrap_or_else_default.rs:73:23 | LL | with_default_type.unwrap_or_else(Vec::new); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:72:18 + --> tests/ui/unwrap_or_else_default.rs:77:18 | LL | empty_string.unwrap_or_else(|| "".to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` -error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:76:12 - | -LL | option.unwrap_or_else(Vec::new).push(1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` - -error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:79:12 - | -LL | option.unwrap_or_else(Vec::new).push(1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` - error: use of `unwrap_or_else` to construct default value --> tests/ui/unwrap_or_else_default.rs:82:12 | @@ -56,19 +44,13 @@ LL | option.unwrap_or_else(Vec::new).push(1); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:85:12 + --> tests/ui/unwrap_or_else_default.rs:86:12 | LL | option.unwrap_or_else(Vec::new).push(1); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:88:12 - | -LL | option.unwrap_or_else(Vec::new).push(1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` - -error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:91:12 + --> tests/ui/unwrap_or_else_default.rs:90:12 | LL | option.unwrap_or_else(Vec::new).push(1); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` @@ -80,19 +62,37 @@ LL | option.unwrap_or_else(Vec::new).push(1); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:97:12 + --> tests/ui/unwrap_or_else_default.rs:98:12 | LL | option.unwrap_or_else(Vec::new).push(1); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/unwrap_or_else_default.rs:113:12 + --> tests/ui/unwrap_or_else_default.rs:102:12 + | +LL | option.unwrap_or_else(Vec::new).push(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` + +error: use of `unwrap_or_else` to construct default value + --> tests/ui/unwrap_or_else_default.rs:106:12 + | +LL | option.unwrap_or_else(Vec::new).push(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` + +error: use of `unwrap_or_else` to construct default value + --> tests/ui/unwrap_or_else_default.rs:110:12 + | +LL | option.unwrap_or_else(Vec::new).push(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` + +error: use of `unwrap_or_else` to construct default value + --> tests/ui/unwrap_or_else_default.rs:127:12 | LL | option.unwrap_or_else(Vec::new).push(1); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `or_insert_with` to construct default value - --> tests/ui/unwrap_or_else_default.rs:130:32 + --> tests/ui/unwrap_or_else_default.rs:145:32 | LL | let _ = inner_map.entry(0).or_insert_with(Default::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` diff --git a/tests/ui/upper_case_acronyms.fixed b/tests/ui/upper_case_acronyms.fixed index a8023ed00d21..b8c10b370680 100644 --- a/tests/ui/upper_case_acronyms.fixed +++ b/tests/ui/upper_case_acronyms.fixed @@ -7,22 +7,30 @@ struct CString; // not linted enum Flags { NS, // not linted Cwr, - //~^ ERROR: name `CWR` contains a capitalized acronym - //~| NOTE: `-D clippy::upper-case-acronyms` implied by `-D warnings` + //~^ upper_case_acronyms + + Ece, - //~^ ERROR: name `ECE` contains a capitalized acronym + //~^ upper_case_acronyms + Urg, - //~^ ERROR: name `URG` contains a capitalized acronym + //~^ upper_case_acronyms + Ack, - //~^ ERROR: name `ACK` contains a capitalized acronym + //~^ upper_case_acronyms + Psh, - //~^ ERROR: name `PSH` contains a capitalized acronym + //~^ upper_case_acronyms + Rst, - //~^ ERROR: name `RST` contains a capitalized acronym + //~^ upper_case_acronyms + Syn, - //~^ ERROR: name `SYN` contains a capitalized acronym + //~^ upper_case_acronyms + Fin, - //~^ ERROR: name `FIN` contains a capitalized acronym + //~^ upper_case_acronyms + } // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of @@ -43,18 +51,21 @@ pub enum ParseError { // private, do lint here enum ParseErrorPrivate { Wasd(u8), - //~^ ERROR: name `WASD` contains a capitalized acronym + //~^ upper_case_acronyms + Utf8(std::string::FromUtf8Error), Parse(T, String), } // do lint here struct Json; -//~^ ERROR: name `JSON` contains a capitalized acronym +//~^ upper_case_acronyms + // do lint here enum Yaml { - //~^ ERROR: name `YAML` contains a capitalized acronym +//~^ upper_case_acronyms + Num(u32), Str(String), } @@ -62,7 +73,8 @@ enum Yaml { // test for issue #7708 enum AllowOnField { Disallow, - //~^ ERROR: name `DISALLOW` contains a capitalized acronym + //~^ upper_case_acronyms + #[allow(clippy::upper_case_acronyms)] ALLOW, } diff --git a/tests/ui/upper_case_acronyms.rs b/tests/ui/upper_case_acronyms.rs index c4711b87ec38..4ad6c6d4c8c8 100644 --- a/tests/ui/upper_case_acronyms.rs +++ b/tests/ui/upper_case_acronyms.rs @@ -7,22 +7,30 @@ struct CString; // not linted enum Flags { NS, // not linted CWR, - //~^ ERROR: name `CWR` contains a capitalized acronym - //~| NOTE: `-D clippy::upper-case-acronyms` implied by `-D warnings` + //~^ upper_case_acronyms + + ECE, - //~^ ERROR: name `ECE` contains a capitalized acronym + //~^ upper_case_acronyms + URG, - //~^ ERROR: name `URG` contains a capitalized acronym + //~^ upper_case_acronyms + ACK, - //~^ ERROR: name `ACK` contains a capitalized acronym + //~^ upper_case_acronyms + PSH, - //~^ ERROR: name `PSH` contains a capitalized acronym + //~^ upper_case_acronyms + RST, - //~^ ERROR: name `RST` contains a capitalized acronym + //~^ upper_case_acronyms + SYN, - //~^ ERROR: name `SYN` contains a capitalized acronym + //~^ upper_case_acronyms + FIN, - //~^ ERROR: name `FIN` contains a capitalized acronym + //~^ upper_case_acronyms + } // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of @@ -43,18 +51,21 @@ pub enum ParseError { // private, do lint here enum ParseErrorPrivate { WASD(u8), - //~^ ERROR: name `WASD` contains a capitalized acronym + //~^ upper_case_acronyms + Utf8(std::string::FromUtf8Error), Parse(T, String), } // do lint here struct JSON; -//~^ ERROR: name `JSON` contains a capitalized acronym +//~^ upper_case_acronyms + // do lint here enum YAML { - //~^ ERROR: name `YAML` contains a capitalized acronym +//~^ upper_case_acronyms + Num(u32), Str(String), } @@ -62,7 +73,8 @@ enum YAML { // test for issue #7708 enum AllowOnField { DISALLOW, - //~^ ERROR: name `DISALLOW` contains a capitalized acronym + //~^ upper_case_acronyms + #[allow(clippy::upper_case_acronyms)] ALLOW, } diff --git a/tests/ui/upper_case_acronyms.stderr b/tests/ui/upper_case_acronyms.stderr index 1f8046c8e841..24e1d808d8ed 100644 --- a/tests/ui/upper_case_acronyms.stderr +++ b/tests/ui/upper_case_acronyms.stderr @@ -8,67 +8,67 @@ LL | CWR, = help: to override `-D warnings` add `#[allow(clippy::upper_case_acronyms)]` error: name `ECE` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:12:5 + --> tests/ui/upper_case_acronyms.rs:13:5 | LL | ECE, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Ece` error: name `URG` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:14:5 + --> tests/ui/upper_case_acronyms.rs:16:5 | LL | URG, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Urg` error: name `ACK` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:16:5 + --> tests/ui/upper_case_acronyms.rs:19:5 | LL | ACK, | ^^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ack` error: name `PSH` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:18:5 + --> tests/ui/upper_case_acronyms.rs:22:5 | LL | PSH, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Psh` error: name `RST` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:20:5 + --> tests/ui/upper_case_acronyms.rs:25:5 | LL | RST, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Rst` error: name `SYN` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:22:5 + --> tests/ui/upper_case_acronyms.rs:28:5 | LL | SYN, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Syn` error: name `FIN` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:24:5 + --> tests/ui/upper_case_acronyms.rs:31:5 | LL | FIN, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Fin` error: name `WASD` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:45:5 + --> tests/ui/upper_case_acronyms.rs:53:5 | LL | WASD(u8), | ^^^^ help: consider making the acronym lowercase, except the initial letter: `Wasd` error: name `JSON` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:52:8 + --> tests/ui/upper_case_acronyms.rs:61:8 | LL | struct JSON; | ^^^^ help: consider making the acronym lowercase, except the initial letter: `Json` error: name `YAML` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:56:6 + --> tests/ui/upper_case_acronyms.rs:66:6 | LL | enum YAML { | ^^^^ help: consider making the acronym lowercase, except the initial letter: `Yaml` error: name `DISALLOW` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:64:5 + --> tests/ui/upper_case_acronyms.rs:75:5 | LL | DISALLOW, | ^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `Disallow` diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index b44840d440b2..faabf0e256db 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -21,16 +21,22 @@ mod use_self { impl Foo { fn new() -> Self { + //~^ use_self Self {} + //~^ use_self } fn test() -> Self { + //~^ use_self Self::new() + //~^ use_self } } impl Default for Foo { fn default() -> Self { + //~^ use_self Self::new() + //~^ use_self } } } @@ -72,6 +78,7 @@ mod lifetimes { } fn clone(&self) -> Self { + //~^ use_self Foo { foo_str: self.foo_str } } @@ -105,6 +112,8 @@ mod existential { impl Foo { fn bad(foos: &[Self]) -> impl Iterator { + //~^ use_self + //~| use_self foos.iter() } @@ -120,6 +129,7 @@ mod tuple_structs { impl TS { pub fn ts() -> Self { Self(0) + //~^ use_self } } } @@ -155,7 +165,9 @@ mod nesting { impl Bar { fn bar() -> Self { + //~^ use_self Self { foo: Foo {} } + //~^ use_self } } @@ -167,7 +179,9 @@ mod nesting { // Should lint here fn baz() -> Self { + //~^ use_self Self {} + //~^ use_self } } @@ -185,8 +199,11 @@ mod nesting { fn method2() { let _ = Self::B(42); + //~^ use_self let _ = Self::C { field: true }; + //~^ use_self let _ = Self::A; + //~^ use_self } } } @@ -229,9 +246,12 @@ mod rustfix { fn fun_2() { Self::fun_1(); + //~^ use_self Self::A; + //~^ use_self Self {}; + //~^ use_self } } } @@ -251,6 +271,7 @@ mod issue3567 { impl Test for TestStruct { fn test() -> TestStruct { Self::from_something() + //~^ use_self } } } @@ -265,11 +286,15 @@ mod paths_created_by_lowering { const B: usize = 1; async fn g() -> Self { + //~^ use_self Self {} + //~^ use_self } fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] { &p[Self::A..Self::B] + //~^ use_self + //~| use_self } } @@ -293,7 +318,9 @@ mod generics { impl Foo { // `Self` is applicable here fn foo(value: T) -> Self { + //~^ use_self Self { value } + //~^ use_self } // `Cannot` use `Self` as a return type as the generic types are different @@ -466,6 +493,7 @@ mod nested_paths { impl A { fn test() -> Self { Self::new::(submod::B {}) + //~^ use_self } } } @@ -503,6 +531,7 @@ mod issue7206 { impl<'a> S2> { fn new_again() -> Self { Self::new() + //~^ use_self } } } @@ -540,13 +569,16 @@ mod use_self_in_pat { fn do_stuff(self) { match self { Self::Bar => unimplemented!(), + //~^ use_self Self::Baz => unimplemented!(), + //~^ use_self } match Some(1) { Some(_) => unimplemented!(), None => unimplemented!(), } if let Self::Bar = self { + //~^ use_self unimplemented!() } } @@ -571,16 +603,22 @@ mod issue8845 { fn get_value(&self) -> u8 { match self { Self::Num(n) => *n, + //~^ use_self Self::TupleNums(n, _m) => *n, + //~^ use_self Self::StructNums { one, two: _ } => *one, + //~^ use_self } } fn use_crate(&self) -> u8 { match self { Self::Num(n) => *n, + //~^ use_self Self::TupleNums(n, _m) => *n, + //~^ use_self Self::StructNums { one, two: _ } => *one, + //~^ use_self } } @@ -597,11 +635,13 @@ mod issue8845 { impl Foo { fn get_value(&self) -> u8 { let Self(x) = self; + //~^ use_self *x } fn use_crate(&self) -> u8 { let Self(x) = self; + //~^ use_self *x } } @@ -609,11 +649,13 @@ mod issue8845 { impl Bar { fn get_value(&self) -> u8 { let Self { x, .. } = self; + //~^ use_self *x } fn use_crate(&self) -> u8 { let Self { x, .. } = self; + //~^ use_self *x } } @@ -653,6 +695,7 @@ fn msrv_1_37() { fn foo(self) { match self { Self::A => {}, + //~^ use_self } } } diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 342c724c8e48..b91856e48097 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -21,16 +21,22 @@ mod use_self { impl Foo { fn new() -> Foo { + //~^ use_self Foo {} + //~^ use_self } fn test() -> Foo { + //~^ use_self Foo::new() + //~^ use_self } } impl Default for Foo { fn default() -> Foo { + //~^ use_self Foo::new() + //~^ use_self } } } @@ -72,6 +78,7 @@ mod lifetimes { } fn clone(&self) -> Foo<'a> { + //~^ use_self Foo { foo_str: self.foo_str } } @@ -105,6 +112,8 @@ mod existential { impl Foo { fn bad(foos: &[Foo]) -> impl Iterator { + //~^ use_self + //~| use_self foos.iter() } @@ -120,6 +129,7 @@ mod tuple_structs { impl TS { pub fn ts() -> Self { TS(0) + //~^ use_self } } } @@ -155,7 +165,9 @@ mod nesting { impl Bar { fn bar() -> Bar { + //~^ use_self Bar { foo: Foo {} } + //~^ use_self } } @@ -167,7 +179,9 @@ mod nesting { // Should lint here fn baz() -> Foo { + //~^ use_self Foo {} + //~^ use_self } } @@ -185,8 +199,11 @@ mod nesting { fn method2() { let _ = Enum::B(42); + //~^ use_self let _ = Enum::C { field: true }; + //~^ use_self let _ = Enum::A; + //~^ use_self } } } @@ -229,9 +246,12 @@ mod rustfix { fn fun_2() { nested::A::fun_1(); + //~^ use_self nested::A::A; + //~^ use_self nested::A {}; + //~^ use_self } } } @@ -251,6 +271,7 @@ mod issue3567 { impl Test for TestStruct { fn test() -> TestStruct { TestStruct::from_something() + //~^ use_self } } } @@ -265,11 +286,15 @@ mod paths_created_by_lowering { const B: usize = 1; async fn g() -> S { + //~^ use_self S {} + //~^ use_self } fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] { &p[S::A..S::B] + //~^ use_self + //~| use_self } } @@ -293,7 +318,9 @@ mod generics { impl Foo { // `Self` is applicable here fn foo(value: T) -> Foo { + //~^ use_self Foo:: { value } + //~^ use_self } // `Cannot` use `Self` as a return type as the generic types are different @@ -466,6 +493,7 @@ mod nested_paths { impl A { fn test() -> Self { A::new::(submod::B {}) + //~^ use_self } } } @@ -503,6 +531,7 @@ mod issue7206 { impl<'a> S2> { fn new_again() -> Self { S2::new() + //~^ use_self } } } @@ -540,13 +569,16 @@ mod use_self_in_pat { fn do_stuff(self) { match self { Foo::Bar => unimplemented!(), + //~^ use_self Foo::Baz => unimplemented!(), + //~^ use_self } match Some(1) { Some(_) => unimplemented!(), None => unimplemented!(), } if let Foo::Bar = self { + //~^ use_self unimplemented!() } } @@ -571,16 +603,22 @@ mod issue8845 { fn get_value(&self) -> u8 { match self { Something::Num(n) => *n, + //~^ use_self Something::TupleNums(n, _m) => *n, + //~^ use_self Something::StructNums { one, two: _ } => *one, + //~^ use_self } } fn use_crate(&self) -> u8 { match self { crate::issue8845::Something::Num(n) => *n, + //~^ use_self crate::issue8845::Something::TupleNums(n, _m) => *n, + //~^ use_self crate::issue8845::Something::StructNums { one, two: _ } => *one, + //~^ use_self } } @@ -597,11 +635,13 @@ mod issue8845 { impl Foo { fn get_value(&self) -> u8 { let Foo(x) = self; + //~^ use_self *x } fn use_crate(&self) -> u8 { let crate::issue8845::Foo(x) = self; + //~^ use_self *x } } @@ -609,11 +649,13 @@ mod issue8845 { impl Bar { fn get_value(&self) -> u8 { let Bar { x, .. } = self; + //~^ use_self *x } fn use_crate(&self) -> u8 { let crate::issue8845::Bar { x, .. } = self; + //~^ use_self *x } } @@ -653,6 +695,7 @@ fn msrv_1_37() { fn foo(self) { match self { E::A => {}, + //~^ use_self } } } diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index bd5b685b45d5..781327696ac1 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -8,253 +8,253 @@ LL | fn new() -> Foo { = help: to override `-D warnings` add `#[allow(clippy::use_self)]` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:24:13 + --> tests/ui/use_self.rs:25:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:26:22 + --> tests/ui/use_self.rs:28:22 | LL | fn test() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:27:13 + --> tests/ui/use_self.rs:30:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:32:25 + --> tests/ui/use_self.rs:36:25 | LL | fn default() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:33:13 + --> tests/ui/use_self.rs:38:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:74:28 + --> tests/ui/use_self.rs:80:28 | LL | fn clone(&self) -> Foo<'a> { | ^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:107:24 + --> tests/ui/use_self.rs:114:24 | LL | fn bad(foos: &[Foo]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:107:55 + --> tests/ui/use_self.rs:114:55 | LL | fn bad(foos: &[Foo]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:122:13 + --> tests/ui/use_self.rs:131:13 | LL | TS(0) | ^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:157:29 + --> tests/ui/use_self.rs:167:29 | LL | fn bar() -> Bar { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:158:21 + --> tests/ui/use_self.rs:169:21 | LL | Bar { foo: Foo {} } | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:169:21 + --> tests/ui/use_self.rs:181:21 | LL | fn baz() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:170:13 + --> tests/ui/use_self.rs:183:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:187:21 + --> tests/ui/use_self.rs:201:21 | LL | let _ = Enum::B(42); | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:188:21 + --> tests/ui/use_self.rs:203:21 | LL | let _ = Enum::C { field: true }; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:189:21 + --> tests/ui/use_self.rs:205:21 | LL | let _ = Enum::A; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:231:13 + --> tests/ui/use_self.rs:248:13 | LL | nested::A::fun_1(); | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:232:13 + --> tests/ui/use_self.rs:250:13 | LL | nested::A::A; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:234:13 + --> tests/ui/use_self.rs:253:13 | LL | nested::A {}; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:253:13 + --> tests/ui/use_self.rs:273:13 | LL | TestStruct::from_something() | ^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:267:25 + --> tests/ui/use_self.rs:288:25 | LL | async fn g() -> S { | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:268:13 + --> tests/ui/use_self.rs:290:13 | LL | S {} | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:272:16 + --> tests/ui/use_self.rs:295:16 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:272:22 + --> tests/ui/use_self.rs:295:22 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:295:29 + --> tests/ui/use_self.rs:320:29 | LL | fn foo(value: T) -> Foo { | ^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:296:13 + --> tests/ui/use_self.rs:322:13 | LL | Foo:: { value } | ^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:468:13 + --> tests/ui/use_self.rs:495:13 | LL | A::new::(submod::B {}) | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:505:13 + --> tests/ui/use_self.rs:533:13 | LL | S2::new() | ^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:542:17 + --> tests/ui/use_self.rs:571:17 | LL | Foo::Bar => unimplemented!(), | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:543:17 + --> tests/ui/use_self.rs:573:17 | LL | Foo::Baz => unimplemented!(), | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:549:20 + --> tests/ui/use_self.rs:580:20 | LL | if let Foo::Bar = self { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:573:17 + --> tests/ui/use_self.rs:605:17 | LL | Something::Num(n) => *n, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:574:17 + --> tests/ui/use_self.rs:607:17 | LL | Something::TupleNums(n, _m) => *n, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:575:17 + --> tests/ui/use_self.rs:609:17 | LL | Something::StructNums { one, two: _ } => *one, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:581:17 + --> tests/ui/use_self.rs:616:17 | LL | crate::issue8845::Something::Num(n) => *n, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:582:17 + --> tests/ui/use_self.rs:618:17 | LL | crate::issue8845::Something::TupleNums(n, _m) => *n, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:583:17 + --> tests/ui/use_self.rs:620:17 | LL | crate::issue8845::Something::StructNums { one, two: _ } => *one, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:599:17 + --> tests/ui/use_self.rs:637:17 | LL | let Foo(x) = self; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:604:17 + --> tests/ui/use_self.rs:643:17 | LL | let crate::issue8845::Foo(x) = self; | ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:611:17 + --> tests/ui/use_self.rs:651:17 | LL | let Bar { x, .. } = self; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:616:17 + --> tests/ui/use_self.rs:657:17 | LL | let crate::issue8845::Bar { x, .. } = self; | ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:655:17 + --> tests/ui/use_self.rs:697:17 | LL | E::A => {}, | ^ help: use the applicable keyword: `Self` diff --git a/tests/ui/use_self_trait.fixed b/tests/ui/use_self_trait.fixed index 2758ec7aca1f..2df7eec92f2f 100644 --- a/tests/ui/use_self_trait.fixed +++ b/tests/ui/use_self_trait.fixed @@ -17,28 +17,42 @@ struct Bad; impl SelfTrait for Bad { fn refs(p1: &Self) -> &Self { + //~^ use_self + //~| use_self p1 } fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self { + //~^ use_self + //~| use_self p1 } fn mut_refs(p1: &mut Self) -> &mut Self { + //~^ use_self + //~| use_self p1 } fn nested(_p1: Box, _p2: (&u8, &Self)) {} + //~^ use_self + //~| use_self fn vals(_: Self) -> Self { + //~^ use_self + //~| use_self Self + //~^ use_self } } impl Mul for Bad { type Output = Self; + //~^ use_self fn mul(self, rhs: Self) -> Self { + //~^ use_self + //~| use_self rhs } } @@ -46,6 +60,7 @@ impl Mul for Bad { impl Clone for Bad { fn clone(&self) -> Self { Self + //~^ use_self } } @@ -143,6 +158,7 @@ mod full_path_replacement { impl Error for std::fmt::Error { fn custom(_msg: T) -> Self { Self // Should lint + //~^ use_self } } } diff --git a/tests/ui/use_self_trait.rs b/tests/ui/use_self_trait.rs index 31031e8f50b2..48118e59fe67 100644 --- a/tests/ui/use_self_trait.rs +++ b/tests/ui/use_self_trait.rs @@ -17,28 +17,42 @@ struct Bad; impl SelfTrait for Bad { fn refs(p1: &Bad) -> &Bad { + //~^ use_self + //~| use_self p1 } fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad { + //~^ use_self + //~| use_self p1 } fn mut_refs(p1: &mut Bad) -> &mut Bad { + //~^ use_self + //~| use_self p1 } fn nested(_p1: Box, _p2: (&u8, &Bad)) {} + //~^ use_self + //~| use_self fn vals(_: Bad) -> Bad { + //~^ use_self + //~| use_self Bad + //~^ use_self } } impl Mul for Bad { type Output = Bad; + //~^ use_self fn mul(self, rhs: Bad) -> Bad { + //~^ use_self + //~| use_self rhs } } @@ -46,6 +60,7 @@ impl Mul for Bad { impl Clone for Bad { fn clone(&self) -> Self { Bad + //~^ use_self } } @@ -143,6 +158,7 @@ mod full_path_replacement { impl Error for std::fmt::Error { fn custom(_msg: T) -> Self { std::fmt::Error // Should lint + //~^ use_self } } } diff --git a/tests/ui/use_self_trait.stderr b/tests/ui/use_self_trait.stderr index 9cbb728ebe66..1b664b3b7a28 100644 --- a/tests/ui/use_self_trait.stderr +++ b/tests/ui/use_self_trait.stderr @@ -14,85 +14,85 @@ LL | fn refs(p1: &Bad) -> &Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:23:33 + --> tests/ui/use_self_trait.rs:25:33 | LL | fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:23:49 + --> tests/ui/use_self_trait.rs:25:49 | LL | fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:27:26 + --> tests/ui/use_self_trait.rs:31:26 | LL | fn mut_refs(p1: &mut Bad) -> &mut Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:27:39 + --> tests/ui/use_self_trait.rs:31:39 | LL | fn mut_refs(p1: &mut Bad) -> &mut Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:31:24 + --> tests/ui/use_self_trait.rs:37:24 | LL | fn nested(_p1: Box, _p2: (&u8, &Bad)) {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:31:42 + --> tests/ui/use_self_trait.rs:37:42 | LL | fn nested(_p1: Box, _p2: (&u8, &Bad)) {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:33:16 + --> tests/ui/use_self_trait.rs:41:16 | LL | fn vals(_: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:33:24 + --> tests/ui/use_self_trait.rs:41:24 | LL | fn vals(_: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:34:9 + --> tests/ui/use_self_trait.rs:44:9 | LL | Bad | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:39:19 + --> tests/ui/use_self_trait.rs:50:19 | LL | type Output = Bad; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:41:23 + --> tests/ui/use_self_trait.rs:53:23 | LL | fn mul(self, rhs: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:41:31 + --> tests/ui/use_self_trait.rs:53:31 | LL | fn mul(self, rhs: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:48:9 + --> tests/ui/use_self_trait.rs:62:9 | LL | Bad | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self_trait.rs:145:13 + --> tests/ui/use_self_trait.rs:160:13 | LL | std::fmt::Error // Should lint | ^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` diff --git a/tests/ui/used_underscore_binding.rs b/tests/ui/used_underscore_binding.rs index 84dccf28f3b2..3b063fd16be1 100644 --- a/tests/ui/used_underscore_binding.rs +++ b/tests/ui/used_underscore_binding.rs @@ -21,12 +21,16 @@ macro_rules! test_macro { /// Tests that we lint if we use a binding with a single leading underscore fn prefix_underscore(_foo: u32) -> u32 { _foo + 1 + //~^ used_underscore_binding } /// Tests that we lint if we use a `_`-variable defined outside within a macro expansion fn in_macro_or_desugar(_foo: u32) { println!("{}", _foo); + //~^ used_underscore_binding assert_eq!(_foo, _foo); + //~^ used_underscore_binding + //~| used_underscore_binding test_macro!() + 1; } @@ -40,6 +44,7 @@ struct StructFieldTest { fn in_struct_field() { let mut s = StructFieldTest { _underscore_field: 0 }; s._underscore_field += 1; + //~^ used_underscore_binding } /// Tests that we do not lint if the struct field is used in code created with derive. @@ -101,6 +106,7 @@ async fn await_desugaring() { ({ let _i = 5; uses_i(_i); + //~^ used_underscore_binding foo() }) .await diff --git a/tests/ui/used_underscore_binding.stderr b/tests/ui/used_underscore_binding.stderr index f9e8013d3ad5..7d94d79f9b3b 100644 --- a/tests/ui/used_underscore_binding.stderr +++ b/tests/ui/used_underscore_binding.stderr @@ -13,61 +13,61 @@ LL | fn prefix_underscore(_foo: u32) -> u32 { = help: to override `-D warnings` add `#[allow(clippy::used_underscore_binding)]` error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:28:20 + --> tests/ui/used_underscore_binding.rs:29:20 | LL | println!("{}", _foo); | ^^^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:27:24 + --> tests/ui/used_underscore_binding.rs:28:24 | LL | fn in_macro_or_desugar(_foo: u32) { | ^^^^ error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:29:16 + --> tests/ui/used_underscore_binding.rs:31:16 | LL | assert_eq!(_foo, _foo); | ^^^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:27:24 + --> tests/ui/used_underscore_binding.rs:28:24 | LL | fn in_macro_or_desugar(_foo: u32) { | ^^^^ error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:29:22 + --> tests/ui/used_underscore_binding.rs:31:22 | LL | assert_eq!(_foo, _foo); | ^^^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:27:24 + --> tests/ui/used_underscore_binding.rs:28:24 | LL | fn in_macro_or_desugar(_foo: u32) { | ^^^^ error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:42:5 + --> tests/ui/used_underscore_binding.rs:46:5 | LL | s._underscore_field += 1; | ^^^^^^^^^^^^^^^^^^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:36:5 + --> tests/ui/used_underscore_binding.rs:40:5 | LL | _underscore_field: u32, | ^^^^^^^^^^^^^^^^^^^^^^ error: used underscore-prefixed binding - --> tests/ui/used_underscore_binding.rs:103:16 + --> tests/ui/used_underscore_binding.rs:108:16 | LL | uses_i(_i); | ^^ | note: binding is defined here - --> tests/ui/used_underscore_binding.rs:102:13 + --> tests/ui/used_underscore_binding.rs:107:13 | LL | let _i = 5; | ^^ diff --git a/tests/ui/used_underscore_items.rs b/tests/ui/used_underscore_items.rs index ed76f4e68dc9..3401df6ae743 100644 --- a/tests/ui/used_underscore_items.rs +++ b/tests/ui/used_underscore_items.rs @@ -41,16 +41,25 @@ mod a { fn main() { _foo1(); + //~^ used_underscore_items let _ = _foo2(); + //~^ used_underscore_items a::b::c::_foo3(); + //~^ used_underscore_items let _ = &_FooStruct {}; + //~^ used_underscore_items let _ = _FooStruct {}; + //~^ used_underscore_items let foo_struct = _FooStruct {}; + //~^ used_underscore_items foo_struct._method_call(); + //~^ used_underscore_items let foo_struct2 = a::b::c::_FooStruct2 {}; + //~^ used_underscore_items foo_struct2._method_call(); + //~^ used_underscore_items } // should not lint exteranl crate. diff --git a/tests/ui/used_underscore_items.stderr b/tests/ui/used_underscore_items.stderr index 93ac3a6fec6b..d6e23f1e726a 100644 --- a/tests/ui/used_underscore_items.stderr +++ b/tests/ui/used_underscore_items.stderr @@ -13,7 +13,7 @@ LL | fn _foo1() {} = help: to override `-D warnings` add `#[allow(clippy::used_underscore_items)]` error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:44:13 + --> tests/ui/used_underscore_items.rs:45:13 | LL | let _ = _foo2(); | ^^^^^^^ @@ -25,7 +25,7 @@ LL | fn _foo2() -> i32 { | ^^^^^^^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:45:5 + --> tests/ui/used_underscore_items.rs:47:5 | LL | a::b::c::_foo3(); | ^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | pub fn _foo3() {} | ^^^^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:46:14 + --> tests/ui/used_underscore_items.rs:49:14 | LL | let _ = &_FooStruct {}; | ^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | struct _FooStruct {} | ^^^^^^^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:47:13 + --> tests/ui/used_underscore_items.rs:51:13 | LL | let _ = _FooStruct {}; | ^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | struct _FooStruct {} | ^^^^^^^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:49:22 + --> tests/ui/used_underscore_items.rs:54:22 | LL | let foo_struct = _FooStruct {}; | ^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | struct _FooStruct {} | ^^^^^^^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:50:5 + --> tests/ui/used_underscore_items.rs:56:5 | LL | foo_struct._method_call(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | fn _method_call(self) {} | ^^^^^^^^^^^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:52:23 + --> tests/ui/used_underscore_items.rs:59:23 | LL | let foo_struct2 = a::b::c::_FooStruct2 {}; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | pub struct _FooStruct2 {} | ^^^^^^^^^^^^^^^^^^^^^^ error: used underscore-prefixed item - --> tests/ui/used_underscore_items.rs:53:5 + --> tests/ui/used_underscore_items.rs:61:5 | LL | foo_struct2._method_call(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/useful_asref.rs b/tests/ui/useful_asref.rs index d17db9371ee8..a37c2785bde2 100644 --- a/tests/ui/useful_asref.rs +++ b/tests/ui/useful_asref.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![deny(clippy::useless_asref)] #![allow(clippy::needless_lifetimes)] diff --git a/tests/ui/useless_asref.fixed b/tests/ui/useless_asref.fixed index 2f179200bb37..235b49649001 100644 --- a/tests/ui/useless_asref.fixed +++ b/tests/ui/useless_asref.fixed @@ -48,14 +48,18 @@ fn not_ok() { { let rslice: &[i32] = &*mrslice; foo_rstr(rstr); + //~^ useless_asref foo_rstr(rstr); foo_rslice(rslice); + //~^ useless_asref foo_rslice(rslice); } { foo_mrslice(mrslice); + //~^ useless_asref foo_mrslice(mrslice); foo_rslice(mrslice); + //~^ useless_asref foo_rslice(mrslice); } @@ -63,19 +67,24 @@ fn not_ok() { let rrrrrstr = &&&&rstr; let rrrrrslice = &&&&&*mrslice; foo_rslice(rrrrrslice); + //~^ useless_asref foo_rslice(rrrrrslice); foo_rstr(rrrrrstr); + //~^ useless_asref foo_rstr(rrrrrstr); } { let mrrrrrslice = &mut &mut &mut &mut mrslice; foo_mrslice(mrrrrrslice); + //~^ useless_asref foo_mrslice(mrrrrrslice); foo_rslice(mrrrrrslice); + //~^ useless_asref foo_rslice(mrrrrrslice); } #[allow(unused_parens, clippy::double_parens, clippy::needless_borrow)] foo_rrrrmr((&&&&MoreRef)); + //~^ useless_asref generic_not_ok(mrslice); generic_ok(mrslice); @@ -126,8 +135,10 @@ fn foo_rt(t: &T) { fn generic_not_ok + AsRef + Debug + ?Sized>(mrt: &mut T) { foo_mrt(mrt); + //~^ useless_asref foo_mrt(mrt); foo_rt(mrt); + //~^ useless_asref foo_rt(mrt); } @@ -139,11 +150,14 @@ fn generic_ok + AsRef + ?Sized, T: Debug + ?Sized>(mru: &mut U) { fn foo() { let x = Some(String::new()); let z = x.clone(); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + let z = x.clone(); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + let z = x.clone(); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + } mod issue12135 { @@ -167,16 +181,20 @@ mod issue12135 { pub fn f(x: &Struct) -> Option { x.field.clone(); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + x.field.clone(); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + x.field.clone(); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223 #[allow(clippy::clone_on_copy)] Some(1).clone(); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + x.field.as_ref().map(|v| v.method().clone()) } diff --git a/tests/ui/useless_asref.rs b/tests/ui/useless_asref.rs index 9851a0caac4f..261bbe18e357 100644 --- a/tests/ui/useless_asref.rs +++ b/tests/ui/useless_asref.rs @@ -48,14 +48,18 @@ fn not_ok() { { let rslice: &[i32] = &*mrslice; foo_rstr(rstr.as_ref()); + //~^ useless_asref foo_rstr(rstr); foo_rslice(rslice.as_ref()); + //~^ useless_asref foo_rslice(rslice); } { foo_mrslice(mrslice.as_mut()); + //~^ useless_asref foo_mrslice(mrslice); foo_rslice(mrslice.as_ref()); + //~^ useless_asref foo_rslice(mrslice); } @@ -63,19 +67,24 @@ fn not_ok() { let rrrrrstr = &&&&rstr; let rrrrrslice = &&&&&*mrslice; foo_rslice(rrrrrslice.as_ref()); + //~^ useless_asref foo_rslice(rrrrrslice); foo_rstr(rrrrrstr.as_ref()); + //~^ useless_asref foo_rstr(rrrrrstr); } { let mrrrrrslice = &mut &mut &mut &mut mrslice; foo_mrslice(mrrrrrslice.as_mut()); + //~^ useless_asref foo_mrslice(mrrrrrslice); foo_rslice(mrrrrrslice.as_ref()); + //~^ useless_asref foo_rslice(mrrrrrslice); } #[allow(unused_parens, clippy::double_parens, clippy::needless_borrow)] foo_rrrrmr((&&&&MoreRef).as_ref()); + //~^ useless_asref generic_not_ok(mrslice); generic_ok(mrslice); @@ -126,8 +135,10 @@ fn foo_rt(t: &T) { fn generic_not_ok + AsRef + Debug + ?Sized>(mrt: &mut T) { foo_mrt(mrt.as_mut()); + //~^ useless_asref foo_mrt(mrt); foo_rt(mrt.as_ref()); + //~^ useless_asref foo_rt(mrt); } @@ -139,11 +150,14 @@ fn generic_ok + AsRef + ?Sized, T: Debug + ?Sized>(mru: &mut U) { fn foo() { let x = Some(String::new()); let z = x.as_ref().map(String::clone); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + let z = x.as_ref().map(|z| z.clone()); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + let z = x.as_ref().map(|z| String::clone(z)); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + } mod issue12135 { @@ -167,16 +181,20 @@ mod issue12135 { pub fn f(x: &Struct) -> Option { x.field.as_ref().map(|v| v.clone()); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + x.field.as_ref().map(Clone::clone); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + x.field.as_ref().map(|v| Clone::clone(v)); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223 #[allow(clippy::clone_on_copy)] Some(1).as_ref().map(|&x| x.clone()); - //~^ ERROR: this call to `as_ref.map(...)` does nothing + //~^ useless_asref + x.field.as_ref().map(|v| v.method().clone()) } diff --git a/tests/ui/useless_asref.stderr b/tests/ui/useless_asref.stderr index 5f495c396705..97be7996f008 100644 --- a/tests/ui/useless_asref.stderr +++ b/tests/ui/useless_asref.stderr @@ -11,103 +11,103 @@ LL | #![deny(clippy::useless_asref)] | ^^^^^^^^^^^^^^^^^^^^^ error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:52:20 + --> tests/ui/useless_asref.rs:53:20 | LL | foo_rslice(rslice.as_ref()); | ^^^^^^^^^^^^^^^ help: try: `rslice` error: this call to `as_mut` does nothing - --> tests/ui/useless_asref.rs:56:21 + --> tests/ui/useless_asref.rs:58:21 | LL | foo_mrslice(mrslice.as_mut()); | ^^^^^^^^^^^^^^^^ help: try: `mrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:58:20 + --> tests/ui/useless_asref.rs:61:20 | LL | foo_rslice(mrslice.as_ref()); | ^^^^^^^^^^^^^^^^ help: try: `mrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:65:20 + --> tests/ui/useless_asref.rs:69:20 | LL | foo_rslice(rrrrrslice.as_ref()); | ^^^^^^^^^^^^^^^^^^^ help: try: `rrrrrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:67:18 + --> tests/ui/useless_asref.rs:72:18 | LL | foo_rstr(rrrrrstr.as_ref()); | ^^^^^^^^^^^^^^^^^ help: try: `rrrrrstr` error: this call to `as_mut` does nothing - --> tests/ui/useless_asref.rs:72:21 + --> tests/ui/useless_asref.rs:78:21 | LL | foo_mrslice(mrrrrrslice.as_mut()); | ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:74:20 + --> tests/ui/useless_asref.rs:81:20 | LL | foo_rslice(mrrrrrslice.as_ref()); | ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:78:16 + --> tests/ui/useless_asref.rs:86:16 | LL | foo_rrrrmr((&&&&MoreRef).as_ref()); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&&&&MoreRef)` error: this call to `as_mut` does nothing - --> tests/ui/useless_asref.rs:128:13 + --> tests/ui/useless_asref.rs:137:13 | LL | foo_mrt(mrt.as_mut()); | ^^^^^^^^^^^^ help: try: `mrt` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:130:12 + --> tests/ui/useless_asref.rs:140:12 | LL | foo_rt(mrt.as_ref()); | ^^^^^^^^^^^^ help: try: `mrt` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:141:13 + --> tests/ui/useless_asref.rs:152:13 | LL | let z = x.as_ref().map(String::clone); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:143:13 + --> tests/ui/useless_asref.rs:155:13 | LL | let z = x.as_ref().map(|z| z.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:145:13 + --> tests/ui/useless_asref.rs:158:13 | LL | let z = x.as_ref().map(|z| String::clone(z)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:169:9 + --> tests/ui/useless_asref.rs:183:9 | LL | x.field.as_ref().map(|v| v.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:171:9 + --> tests/ui/useless_asref.rs:186:9 | LL | x.field.as_ref().map(Clone::clone); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:173:9 + --> tests/ui/useless_asref.rs:189:9 | LL | x.field.as_ref().map(|v| Clone::clone(v)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:178:9 + --> tests/ui/useless_asref.rs:195:9 | LL | Some(1).as_ref().map(|&x| x.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(1).clone()` diff --git a/tests/ui/useless_attribute.fixed b/tests/ui/useless_attribute.fixed index de1062f123b7..a96c8f46f551 100644 --- a/tests/ui/useless_attribute.fixed +++ b/tests/ui/useless_attribute.fixed @@ -6,7 +6,9 @@ #![feature(rustc_private)] #![allow(dead_code)] +//~^ useless_attribute #![cfg_attr(clippy, allow(dead_code))] +//~^ useless_attribute #[rustfmt::skip] #[allow(unused_imports)] #[allow(unused_extern_crates)] @@ -18,6 +20,7 @@ extern crate proc_macro_derive; fn test_indented_attr() { #![allow(clippy::almost_swapped)] + //~^ useless_attribute use std::collections::HashSet; let _ = HashSet::::default(); diff --git a/tests/ui/useless_attribute.rs b/tests/ui/useless_attribute.rs index 94657dd1ca37..b26410134bbb 100644 --- a/tests/ui/useless_attribute.rs +++ b/tests/ui/useless_attribute.rs @@ -6,7 +6,9 @@ #![feature(rustc_private)] #[allow(dead_code)] +//~^ useless_attribute #[cfg_attr(clippy, allow(dead_code))] +//~^ useless_attribute #[rustfmt::skip] #[allow(unused_imports)] #[allow(unused_extern_crates)] @@ -18,6 +20,7 @@ extern crate proc_macro_derive; fn test_indented_attr() { #[allow(clippy::almost_swapped)] + //~^ useless_attribute use std::collections::HashSet; let _ = HashSet::::default(); diff --git a/tests/ui/useless_attribute.stderr b/tests/ui/useless_attribute.stderr index 19f0e02de680..91383adf994b 100644 --- a/tests/ui/useless_attribute.stderr +++ b/tests/ui/useless_attribute.stderr @@ -8,13 +8,13 @@ LL | #[allow(dead_code)] = help: to override `-D warnings` add `#[allow(clippy::useless_attribute)]` error: useless lint attribute - --> tests/ui/useless_attribute.rs:9:1 + --> tests/ui/useless_attribute.rs:10:1 | LL | #[cfg_attr(clippy, allow(dead_code))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![cfg_attr(clippy, allow(dead_code)` error: useless lint attribute - --> tests/ui/useless_attribute.rs:20:5 + --> tests/ui/useless_attribute.rs:22:5 | LL | #[allow(clippy::almost_swapped)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![allow(clippy::almost_swapped)]` diff --git a/tests/ui/useless_conversion.fixed b/tests/ui/useless_conversion.fixed index 697d437b3885..2b9ef0209047 100644 --- a/tests/ui/useless_conversion.fixed +++ b/tests/ui/useless_conversion.fixed @@ -7,7 +7,9 @@ use std::ops::ControlFlow; fn test_generic(val: T) -> T { let _ = val; + //~^ useless_conversion val + //~^ useless_conversion } fn test_generic2 + Into, U: From>(val: T) { @@ -20,6 +22,7 @@ fn test_generic2 + Into, U: From>(val: T) { fn test_questionmark() -> Result<(), ()> { { let _: i32 = 0i32; + //~^ useless_conversion Ok(Ok(())) }??; Ok(()) @@ -50,28 +53,33 @@ fn lint_into_iter_on_mutable_local_implementing_iterator_in_expr() { let text = "foo\r\nbar\n\nbaz\n"; let mut lines = text.lines(); if Some("ok") == lines.next() {} + //~^ useless_conversion } fn lint_into_iter_on_expr_implementing_iterator() { let text = "foo\r\nbar\n\nbaz\n"; let mut lines = text.lines(); + //~^ useless_conversion if Some("ok") == lines.next() {} } fn lint_into_iter_on_expr_implementing_iterator_2() { let text = "foo\r\nbar\n\nbaz\n"; if Some("ok") == text.lines().next() {} + //~^ useless_conversion } #[allow(const_item_mutation)] fn lint_into_iter_on_const_implementing_iterator() { const NUMBERS: std::ops::Range = 0..10; let _ = NUMBERS.next(); + //~^ useless_conversion } fn lint_into_iter_on_const_implementing_iterator_2() { const NUMBERS: std::ops::Range = 0..10; let mut n = NUMBERS; + //~^ useless_conversion n.next(); } @@ -134,27 +142,38 @@ fn main() { } let _: String = "foo".to_string(); + //~^ useless_conversion let _: String = "foo".to_string(); + //~^ useless_conversion let _ = "foo".to_string(); + //~^ useless_conversion let _ = format!("A: {:04}", 123); + //~^ useless_conversion let _ = "".lines(); + //~^ useless_conversion let _ = vec![1, 2, 3].into_iter(); + //~^ useless_conversion let _: String = format!("Hello {}", "world"); + //~^ useless_conversion // keep parentheses around `a + b` for suggestion (see #4750) let a: i32 = 1; let b: i32 = 1; let _ = (a + b) * 3; + //~^ useless_conversion // see #7205 let s: Foo<'a'> = Foo; let _: Foo<'b'> = s.into(); let s2: Foo<'a'> = Foo; let _: Foo<'a'> = s2; + //~^ useless_conversion let s3: Foo<'a'> = Foo; let _ = s3; + //~^ useless_conversion let s4: Foo<'a'> = Foo; let _ = vec![s4, s4, s4].into_iter(); + //~^ useless_conversion issue11300::bar(); } @@ -187,12 +206,17 @@ fn explicit_into_iter_fn_arg() { a(vec![1, 2].into_iter()); b(vec![1, 2]); + //~^ useless_conversion c(vec![1, 2]); + //~^ useless_conversion d(vec![1, 2]); + //~^ useless_conversion b([&1, &2, &3].into_iter().cloned()); b(vec![1, 2]); + //~^ useless_conversion b(vec![1, 2]); + //~^ useless_conversion macro_rules! macro_generated { () => { @@ -239,6 +263,7 @@ mod issue11300 { // This should trigger the lint, receiver type [i32; 3] also implements `Helper` foo2::([1, 2, 3]); + //~^ useless_conversion // This again should *not* lint, since X = () and I = std::array::IntoIter, // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter: Helper<()>` is). @@ -247,6 +272,7 @@ mod issue11300 { // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`, // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unnecessary. foo3([1, 2, 3]); + //~^ useless_conversion } fn ice() { @@ -256,6 +282,7 @@ mod issue11300 { } S1.foo([1, 2]); + //~^ useless_conversion // ICE that occurred in itertools trait Itertools { @@ -275,6 +302,7 @@ mod issue11300 { let v0: Vec = vec![0, 2, 4]; let v1: Vec = vec![1, 3, 5, 7]; v0.into_iter().interleave_shortest(v1); + //~^ useless_conversion trait TraitWithLifetime<'a> {} impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {} @@ -303,19 +331,25 @@ impl From> for Foo<'b'> { fn direct_application() { let _: Result<(), std::io::Error> = test_issue_3913(); //~^ useless_conversion + let _: Result<(), std::io::Error> = test_issue_3913(); //~^ useless_conversion + let _: Result<(), std::io::Error> = test_issue_3913(); //~^ useless_conversion + let _: Result<(), std::io::Error> = test_issue_3913(); //~^ useless_conversion + + let c: ControlFlow<()> = ControlFlow::Continue(()); + let _: ControlFlow<()> = c; + //~^ useless_conversion + let c: ControlFlow<()> = ControlFlow::Continue(()); let _: ControlFlow<()> = c; //~^ useless_conversion - let c: ControlFlow<()> = ControlFlow::Continue(()); - let _: ControlFlow<()> = c; - //~^ useless_conversion + struct Absorb; impl From<()> for Absorb { @@ -331,6 +365,7 @@ fn direct_application() { let _: Vec = [1u32].into_iter().collect(); //~^ useless_conversion + // No lint for those let _: Result = test_issue_3913().map(Into::into); let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into); @@ -341,6 +376,7 @@ fn direct_application() { fn gen_identity(x: [T; 3]) -> Vec { x.into_iter().collect() //~^ useless_conversion + } mod issue11819 { @@ -357,6 +393,7 @@ mod issue11819 { { takes_into_iter(&self.my_field); //~^ useless_conversion + } pub fn with_ref_mut<'a>(&'a mut self) @@ -365,6 +402,7 @@ mod issue11819 { { takes_into_iter(&mut self.my_field); //~^ useless_conversion + } pub fn with_deref(&mut self) @@ -374,6 +412,7 @@ mod issue11819 { { takes_into_iter(*self.my_field); //~^ useless_conversion + } pub fn with_reborrow<'a, Y: 'a>(&'a mut self) @@ -383,6 +422,7 @@ mod issue11819 { { takes_into_iter(&*self.my_field); //~^ useless_conversion + } pub fn with_reborrow_mut<'a, Y: 'a>(&'a mut self) @@ -392,6 +432,7 @@ mod issue11819 { { takes_into_iter(&mut *self.my_field); //~^ useless_conversion + } } } diff --git a/tests/ui/useless_conversion.rs b/tests/ui/useless_conversion.rs index 4d8ad61a8c99..84b5b12580e5 100644 --- a/tests/ui/useless_conversion.rs +++ b/tests/ui/useless_conversion.rs @@ -7,7 +7,9 @@ use std::ops::ControlFlow; fn test_generic(val: T) -> T { let _ = T::from(val); + //~^ useless_conversion val.into() + //~^ useless_conversion } fn test_generic2 + Into, U: From>(val: T) { @@ -20,6 +22,7 @@ fn test_generic2 + Into, U: From>(val: T) { fn test_questionmark() -> Result<(), ()> { { let _: i32 = 0i32.into(); + //~^ useless_conversion Ok(Ok(())) }??; Ok(()) @@ -50,28 +53,33 @@ fn lint_into_iter_on_mutable_local_implementing_iterator_in_expr() { let text = "foo\r\nbar\n\nbaz\n"; let mut lines = text.lines(); if Some("ok") == lines.into_iter().next() {} + //~^ useless_conversion } fn lint_into_iter_on_expr_implementing_iterator() { let text = "foo\r\nbar\n\nbaz\n"; let mut lines = text.lines().into_iter(); + //~^ useless_conversion if Some("ok") == lines.next() {} } fn lint_into_iter_on_expr_implementing_iterator_2() { let text = "foo\r\nbar\n\nbaz\n"; if Some("ok") == text.lines().into_iter().next() {} + //~^ useless_conversion } #[allow(const_item_mutation)] fn lint_into_iter_on_const_implementing_iterator() { const NUMBERS: std::ops::Range = 0..10; let _ = NUMBERS.into_iter().next(); + //~^ useless_conversion } fn lint_into_iter_on_const_implementing_iterator_2() { const NUMBERS: std::ops::Range = 0..10; let mut n = NUMBERS.into_iter(); + //~^ useless_conversion n.next(); } @@ -134,27 +142,38 @@ fn main() { } let _: String = "foo".to_string().into(); + //~^ useless_conversion let _: String = From::from("foo".to_string()); + //~^ useless_conversion let _ = String::from("foo".to_string()); + //~^ useless_conversion let _ = String::from(format!("A: {:04}", 123)); + //~^ useless_conversion let _ = "".lines().into_iter(); + //~^ useless_conversion let _ = vec![1, 2, 3].into_iter().into_iter(); + //~^ useless_conversion let _: String = format!("Hello {}", "world").into(); + //~^ useless_conversion // keep parentheses around `a + b` for suggestion (see #4750) let a: i32 = 1; let b: i32 = 1; let _ = i32::from(a + b) * 3; + //~^ useless_conversion // see #7205 let s: Foo<'a'> = Foo; let _: Foo<'b'> = s.into(); let s2: Foo<'a'> = Foo; let _: Foo<'a'> = s2.into(); + //~^ useless_conversion let s3: Foo<'a'> = Foo; let _ = Foo::<'a'>::from(s3); + //~^ useless_conversion let s4: Foo<'a'> = Foo; let _ = vec![s4, s4, s4].into_iter().into_iter(); + //~^ useless_conversion issue11300::bar(); } @@ -187,12 +206,17 @@ fn explicit_into_iter_fn_arg() { a(vec![1, 2].into_iter()); b(vec![1, 2].into_iter()); + //~^ useless_conversion c(vec![1, 2].into_iter()); + //~^ useless_conversion d(vec![1, 2].into_iter()); + //~^ useless_conversion b([&1, &2, &3].into_iter().cloned()); b(vec![1, 2].into_iter().into_iter()); + //~^ useless_conversion b(vec![1, 2].into_iter().into_iter().into_iter()); + //~^ useless_conversion macro_rules! macro_generated { () => { @@ -239,6 +263,7 @@ mod issue11300 { // This should trigger the lint, receiver type [i32; 3] also implements `Helper` foo2::([1, 2, 3].into_iter()); + //~^ useless_conversion // This again should *not* lint, since X = () and I = std::array::IntoIter, // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter: Helper<()>` is). @@ -247,6 +272,7 @@ mod issue11300 { // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`, // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unnecessary. foo3([1, 2, 3].into_iter()); + //~^ useless_conversion } fn ice() { @@ -256,6 +282,7 @@ mod issue11300 { } S1.foo([1, 2].into_iter()); + //~^ useless_conversion // ICE that occurred in itertools trait Itertools { @@ -275,6 +302,7 @@ mod issue11300 { let v0: Vec = vec![0, 2, 4]; let v1: Vec = vec![1, 3, 5, 7]; v0.into_iter().interleave_shortest(v1.into_iter()); + //~^ useless_conversion trait TraitWithLifetime<'a> {} impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {} @@ -303,20 +331,26 @@ impl From> for Foo<'b'> { fn direct_application() { let _: Result<(), std::io::Error> = test_issue_3913().map(Into::into); //~^ useless_conversion + let _: Result<(), std::io::Error> = test_issue_3913().map_err(Into::into); //~^ useless_conversion + let _: Result<(), std::io::Error> = test_issue_3913().map(From::from); //~^ useless_conversion + let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from); //~^ useless_conversion + let c: ControlFlow<()> = ControlFlow::Continue(()); let _: ControlFlow<()> = c.map_break(Into::into); //~^ useless_conversion + let c: ControlFlow<()> = ControlFlow::Continue(()); let _: ControlFlow<()> = c.map_continue(Into::into); //~^ useless_conversion + struct Absorb; impl From<()> for Absorb { fn from(_: ()) -> Self { @@ -331,6 +365,7 @@ fn direct_application() { let _: Vec = [1u32].into_iter().map(Into::into).collect(); //~^ useless_conversion + // No lint for those let _: Result = test_issue_3913().map(Into::into); let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into); @@ -341,6 +376,7 @@ fn direct_application() { fn gen_identity(x: [T; 3]) -> Vec { x.into_iter().map(Into::into).collect() //~^ useless_conversion + } mod issue11819 { @@ -357,6 +393,7 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion + } pub fn with_ref_mut<'a>(&'a mut self) @@ -365,6 +402,7 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion + } pub fn with_deref(&mut self) @@ -374,6 +412,7 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion + } pub fn with_reborrow<'a, Y: 'a>(&'a mut self) @@ -383,6 +422,7 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion + } pub fn with_reborrow_mut<'a, Y: 'a>(&'a mut self) @@ -392,6 +432,7 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion + } } } diff --git a/tests/ui/useless_conversion.stderr b/tests/ui/useless_conversion.stderr index ed50f3071862..39c625429c66 100644 --- a/tests/ui/useless_conversion.stderr +++ b/tests/ui/useless_conversion.stderr @@ -11,115 +11,115 @@ LL | #![deny(clippy::useless_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion.rs:10:5 + --> tests/ui/useless_conversion.rs:11:5 | LL | val.into() | ^^^^^^^^^^ help: consider removing `.into()`: `val` error: useless conversion to the same type: `i32` - --> tests/ui/useless_conversion.rs:22:22 + --> tests/ui/useless_conversion.rs:24:22 | LL | let _: i32 = 0i32.into(); | ^^^^^^^^^^^ help: consider removing `.into()`: `0i32` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:52:22 + --> tests/ui/useless_conversion.rs:55:22 | LL | if Some("ok") == lines.into_iter().next() {} | ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:57:21 + --> tests/ui/useless_conversion.rs:61:21 | LL | let mut lines = text.lines().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:63:22 + --> tests/ui/useless_conversion.rs:68:22 | LL | if Some("ok") == text.lines().into_iter().next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:69:13 + --> tests/ui/useless_conversion.rs:75:13 | LL | let _ = NUMBERS.into_iter().next(); | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:74:17 + --> tests/ui/useless_conversion.rs:81:17 | LL | let mut n = NUMBERS.into_iter(); | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:136:21 + --> tests/ui/useless_conversion.rs:144:21 | LL | let _: String = "foo".to_string().into(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:137:21 + --> tests/ui/useless_conversion.rs:146:21 | LL | let _: String = From::from("foo".to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:138:13 + --> tests/ui/useless_conversion.rs:148:13 | LL | let _ = String::from("foo".to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:139:13 + --> tests/ui/useless_conversion.rs:150:13 | LL | let _ = String::from(format!("A: {:04}", 123)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:140:13 + --> tests/ui/useless_conversion.rs:152:13 | LL | let _ = "".lines().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()` error: useless conversion to the same type: `std::vec::IntoIter` - --> tests/ui/useless_conversion.rs:141:13 + --> tests/ui/useless_conversion.rs:154:13 | LL | let _ = vec![1, 2, 3].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:142:21 + --> tests/ui/useless_conversion.rs:156:21 | LL | let _: String = format!("Hello {}", "world").into(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")` error: useless conversion to the same type: `i32` - --> tests/ui/useless_conversion.rs:147:13 + --> tests/ui/useless_conversion.rs:162:13 | LL | let _ = i32::from(a + b) * 3; | ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)` error: useless conversion to the same type: `Foo<'a'>` - --> tests/ui/useless_conversion.rs:153:23 + --> tests/ui/useless_conversion.rs:169:23 | LL | let _: Foo<'a'> = s2.into(); | ^^^^^^^^^ help: consider removing `.into()`: `s2` error: useless conversion to the same type: `Foo<'a'>` - --> tests/ui/useless_conversion.rs:155:13 + --> tests/ui/useless_conversion.rs:172:13 | LL | let _ = Foo::<'a'>::from(s3); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3` error: useless conversion to the same type: `std::vec::IntoIter>` - --> tests/ui/useless_conversion.rs:157:13 + --> tests/ui/useless_conversion.rs:175:13 | LL | let _ = vec![s4, s4, s4].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:189:7 + --> tests/ui/useless_conversion.rs:208:7 | LL | b(vec![1, 2].into_iter()); | ^^^^^^^^^^------------ @@ -127,13 +127,13 @@ LL | b(vec![1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:179:13 + --> tests/ui/useless_conversion.rs:198:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:190:7 + --> tests/ui/useless_conversion.rs:210:7 | LL | c(vec![1, 2].into_iter()); | ^^^^^^^^^^------------ @@ -141,13 +141,13 @@ LL | c(vec![1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:180:18 + --> tests/ui/useless_conversion.rs:199:18 | LL | fn c(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:191:7 + --> tests/ui/useless_conversion.rs:212:7 | LL | d(vec![1, 2].into_iter()); | ^^^^^^^^^^------------ @@ -155,13 +155,13 @@ LL | d(vec![1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:183:12 + --> tests/ui/useless_conversion.rs:202:12 | LL | T: IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:194:7 + --> tests/ui/useless_conversion.rs:216:7 | LL | b(vec![1, 2].into_iter().into_iter()); | ^^^^^^^^^^------------------------ @@ -169,13 +169,13 @@ LL | b(vec![1, 2].into_iter().into_iter()); | help: consider removing the `.into_iter()`s | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:179:13 + --> tests/ui/useless_conversion.rs:198:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:195:7 + --> tests/ui/useless_conversion.rs:218:7 | LL | b(vec![1, 2].into_iter().into_iter().into_iter()); | ^^^^^^^^^^------------------------------------ @@ -183,13 +183,13 @@ LL | b(vec![1, 2].into_iter().into_iter().into_iter()); | help: consider removing the `.into_iter()`s | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:179:13 + --> tests/ui/useless_conversion.rs:198:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:241:24 + --> tests/ui/useless_conversion.rs:265:24 | LL | foo2::([1, 2, 3].into_iter()); | ^^^^^^^^^------------ @@ -197,13 +197,13 @@ LL | foo2::([1, 2, 3].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:220:12 + --> tests/ui/useless_conversion.rs:244:12 | LL | I: IntoIterator + Helper, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:249:14 + --> tests/ui/useless_conversion.rs:274:14 | LL | foo3([1, 2, 3].into_iter()); | ^^^^^^^^^------------ @@ -211,13 +211,13 @@ LL | foo3([1, 2, 3].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:229:12 + --> tests/ui/useless_conversion.rs:253:12 | LL | I: IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:258:16 + --> tests/ui/useless_conversion.rs:284:16 | LL | S1.foo([1, 2].into_iter()); | ^^^^^^------------ @@ -225,13 +225,13 @@ LL | S1.foo([1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:255:27 + --> tests/ui/useless_conversion.rs:281:27 | LL | pub fn foo(&self, _: I) {} | ^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:277:44 + --> tests/ui/useless_conversion.rs:304:44 | LL | v0.into_iter().interleave_shortest(v1.into_iter()); | ^^------------ @@ -239,67 +239,67 @@ LL | v0.into_iter().interleave_shortest(v1.into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:264:20 + --> tests/ui/useless_conversion.rs:291:20 | LL | J: IntoIterator, | ^^^^^^^^^^^^ error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:304:58 + --> tests/ui/useless_conversion.rs:332:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map(Into::into); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `std::io::Error` - --> tests/ui/useless_conversion.rs:306:58 + --> tests/ui/useless_conversion.rs:335:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map_err(Into::into); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:308:58 + --> tests/ui/useless_conversion.rs:338:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map(From::from); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `std::io::Error` - --> tests/ui/useless_conversion.rs:310:58 + --> tests/ui/useless_conversion.rs:341:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:314:31 + --> tests/ui/useless_conversion.rs:346:31 | LL | let _: ControlFlow<()> = c.map_break(Into::into); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:317:31 + --> tests/ui/useless_conversion.rs:350:31 | LL | let _: ControlFlow<()> = c.map_continue(Into::into); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `u32` - --> tests/ui/useless_conversion.rs:331:41 + --> tests/ui/useless_conversion.rs:365:41 | LL | let _: Vec = [1u32].into_iter().map(Into::into).collect(); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion.rs:342:18 + --> tests/ui/useless_conversion.rs:377:18 | LL | x.into_iter().map(Into::into).collect() | ^^^^^^^^^^^^^^^^ help: consider removing error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:358:29 + --> tests/ui/useless_conversion.rs:394:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:347:32 + --> tests/ui/useless_conversion.rs:383:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -310,13 +310,13 @@ LL + takes_into_iter(&self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:366:29 + --> tests/ui/useless_conversion.rs:403:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:347:32 + --> tests/ui/useless_conversion.rs:383:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -327,13 +327,13 @@ LL + takes_into_iter(&mut self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:375:29 + --> tests/ui/useless_conversion.rs:413:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:347:32 + --> tests/ui/useless_conversion.rs:383:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -344,13 +344,13 @@ LL + takes_into_iter(*self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:384:29 + --> tests/ui/useless_conversion.rs:423:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:347:32 + --> tests/ui/useless_conversion.rs:383:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -361,13 +361,13 @@ LL + takes_into_iter(&*self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:393:29 + --> tests/ui/useless_conversion.rs:433:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:347:32 + --> tests/ui/useless_conversion.rs:383:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/useless_conversion_try.rs b/tests/ui/useless_conversion_try.rs index 23edeae12b83..7f469a819ef2 100644 --- a/tests/ui/useless_conversion_try.rs +++ b/tests/ui/useless_conversion_try.rs @@ -7,9 +7,11 @@ fn test_generic(val: T) -> T { let _ = T::try_from(val).unwrap(); - //~^ ERROR: useless conversion to the same type: `T` + //~^ useless_conversion + val.try_into().unwrap() - //~^ ERROR: useless conversion to the same type: `T` + //~^ useless_conversion + } fn test_generic2 + Into, U: From>(val: T) { @@ -32,19 +34,26 @@ fn main() { let _: String = "foo".try_into().unwrap(); } let _: String = "foo".to_string().try_into().unwrap(); - //~^ ERROR: useless conversion to the same type: `std::string::String` + //~^ useless_conversion + let _: String = TryFrom::try_from("foo".to_string()).unwrap(); - //~^ ERROR: useless conversion to the same type: `std::string::String` + //~^ useless_conversion + let _ = String::try_from("foo".to_string()).unwrap(); - //~^ ERROR: useless conversion to the same type: `std::string::String` + //~^ useless_conversion + let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); - //~^ ERROR: useless conversion to the same type: `std::string::String` + //~^ useless_conversion + let _: String = format!("Hello {}", "world").try_into().unwrap(); - //~^ ERROR: useless conversion to the same type: `std::string::String` + //~^ useless_conversion + let _: String = String::new().try_into().unwrap(); - //~^ ERROR: useless conversion to the same type: `std::string::String` + //~^ useless_conversion + let _: String = match String::from("_").try_into() { - //~^ ERROR: useless conversion to the same type: `std::string::String` + //~^ useless_conversion + Ok(a) => a, Err(_) => String::new(), }; diff --git a/tests/ui/useless_conversion_try.stderr b/tests/ui/useless_conversion_try.stderr index 30a43629dbd6..af2199837bf7 100644 --- a/tests/ui/useless_conversion_try.stderr +++ b/tests/ui/useless_conversion_try.stderr @@ -12,7 +12,7 @@ LL | #![deny(clippy::useless_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion_try.rs:11:5 + --> tests/ui/useless_conversion_try.rs:12:5 | LL | val.try_into().unwrap() | ^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | val.try_into().unwrap() = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:34:21 + --> tests/ui/useless_conversion_try.rs:36:21 | LL | let _: String = "foo".to_string().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | let _: String = "foo".to_string().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:36:21 + --> tests/ui/useless_conversion_try.rs:39:21 | LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); = help: consider removing `TryFrom::try_from()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:38:13 + --> tests/ui/useless_conversion_try.rs:42:13 | LL | let _ = String::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | let _ = String::try_from("foo".to_string()).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:40:13 + --> tests/ui/useless_conversion_try.rs:45:13 | LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:42:21 + --> tests/ui/useless_conversion_try.rs:48:21 | LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:44:21 + --> tests/ui/useless_conversion_try.rs:51:21 | LL | let _: String = String::new().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | let _: String = String::new().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:46:27 + --> tests/ui/useless_conversion_try.rs:54:27 | LL | let _: String = match String::from("_").try_into() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/useless_nonzero_new_unchecked.fixed b/tests/ui/useless_nonzero_new_unchecked.fixed index 03b34afa54ec..8e5e105215a9 100644 --- a/tests/ui/useless_nonzero_new_unchecked.fixed +++ b/tests/ui/useless_nonzero_new_unchecked.fixed @@ -5,7 +5,8 @@ use std::num::{NonZero, NonZeroUsize}; #[clippy::msrv = "1.83"] const fn func() -> NonZeroUsize { const { NonZeroUsize::new(3).unwrap() } - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + } #[clippy::msrv = "1.82"] @@ -35,17 +36,21 @@ macro_rules! nzu { fn main() { const _A: NonZeroUsize = NonZeroUsize::new(3).unwrap(); - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + static _B: NonZero = NonZero::::new(42).unwrap(); - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + const _C: usize = unsafe { NonZeroUsize::new(3).unwrap().get() }; - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + const AUX: usize = 3; const _D: NonZeroUsize = NonZeroUsize::new(AUX).unwrap(); - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + const _X: NonZeroUsize = uns!(NonZeroUsize::new_unchecked(3)); const _Y: NonZeroUsize = unsafe { nzu!() }; diff --git a/tests/ui/useless_nonzero_new_unchecked.rs b/tests/ui/useless_nonzero_new_unchecked.rs index d450e3a03ec5..43fd1f2e5849 100644 --- a/tests/ui/useless_nonzero_new_unchecked.rs +++ b/tests/ui/useless_nonzero_new_unchecked.rs @@ -5,7 +5,8 @@ use std::num::{NonZero, NonZeroUsize}; #[clippy::msrv = "1.83"] const fn func() -> NonZeroUsize { const { unsafe { NonZeroUsize::new_unchecked(3) } } - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + } #[clippy::msrv = "1.82"] @@ -35,17 +36,21 @@ macro_rules! nzu { fn main() { const _A: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) }; - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + static _B: NonZero = unsafe { NonZero::::new_unchecked(42) }; - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() }; - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + const AUX: usize = 3; const _D: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(AUX) }; - //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context + //~^ useless_nonzero_new_unchecked + const _X: NonZeroUsize = uns!(NonZeroUsize::new_unchecked(3)); const _Y: NonZeroUsize = unsafe { nzu!() }; diff --git a/tests/ui/useless_nonzero_new_unchecked.stderr b/tests/ui/useless_nonzero_new_unchecked.stderr index adb146167633..b9fc333dd4f5 100644 --- a/tests/ui/useless_nonzero_new_unchecked.stderr +++ b/tests/ui/useless_nonzero_new_unchecked.stderr @@ -8,19 +8,19 @@ LL | const { unsafe { NonZeroUsize::new_unchecked(3) } } = help: to override `-D warnings` add `#[allow(clippy::useless_nonzero_new_unchecked)]` error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context - --> tests/ui/useless_nonzero_new_unchecked.rs:37:30 + --> tests/ui/useless_nonzero_new_unchecked.rs:38:30 | LL | const _A: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()` error: `NonZero::::new()` and `Option::unwrap()` can be safely used in a `const` context - --> tests/ui/useless_nonzero_new_unchecked.rs:40:30 + --> tests/ui/useless_nonzero_new_unchecked.rs:42:30 | LL | static _B: NonZero = unsafe { NonZero::::new_unchecked(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZero::::new(42).unwrap()` error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context - --> tests/ui/useless_nonzero_new_unchecked.rs:43:32 + --> tests/ui/useless_nonzero_new_unchecked.rs:46:32 | LL | const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()` @@ -28,7 +28,7 @@ LL | const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() }; = note: the fixed expression does not require an `unsafe` context error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context - --> tests/ui/useless_nonzero_new_unchecked.rs:47:30 + --> tests/ui/useless_nonzero_new_unchecked.rs:51:30 | LL | const _D: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(AUX) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(AUX).unwrap()` diff --git a/tests/ui/useless_vec.rs b/tests/ui/useless_vec.rs index 880809f81d7a..65aafb66568f 100644 --- a/tests/ui/useless_vec.rs +++ b/tests/ui/useless_vec.rs @@ -6,7 +6,8 @@ fn foo() { // There should be no suggestion in this case. let _some_variable = vec![ - //~^ useless_vec + //~^ useless_vec + 1, 2, // i'm here to stay 3, 4, // but this one going away ;-; ]; // that is life anyways diff --git a/tests/ui/useless_vec.stderr b/tests/ui/useless_vec.stderr index e47364fb06d3..39927d0b4654 100644 --- a/tests/ui/useless_vec.stderr +++ b/tests/ui/useless_vec.stderr @@ -4,6 +4,7 @@ error: useless use of `vec!` LL | let _some_variable = vec![ | __________________________^ LL | | +LL | | LL | | 1, 2, // i'm here to stay LL | | 3, 4, // but this one going away ;-; LL | | ]; // that is life anyways diff --git a/tests/ui/vec.fixed b/tests/ui/vec.fixed index 9e755a82af45..5b35b2b26243 100644 --- a/tests/ui/vec.fixed +++ b/tests/ui/vec.fixed @@ -28,24 +28,34 @@ impl Line { fn main() { on_slice(&[]); + //~^ useless_vec on_slice(&[]); on_mut_slice(&mut []); + //~^ useless_vec on_slice(&[1, 2]); + //~^ useless_vec on_slice(&[1, 2]); on_mut_slice(&mut [1, 2]); + //~^ useless_vec on_slice(&[1, 2]); + //~^ useless_vec on_slice(&[1, 2]); on_mut_slice(&mut [1, 2]); + //~^ useless_vec #[rustfmt::skip] on_slice(&[1, 2]); + //~^ useless_vec on_slice(&[1, 2]); on_mut_slice(&mut [1, 2]); + //~^ useless_vec on_slice(&[1; 2]); + //~^ useless_vec on_slice(&[1; 2]); on_mut_slice(&mut [1; 2]); + //~^ useless_vec on_vec(&vec![]); on_vec(&vec![1, 2]); @@ -72,17 +82,21 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 let _x: i32 = [1, 2, 3].iter().sum(); + //~^ useless_vec // Do lint let mut x = [1, 2, 3]; + //~^ useless_vec x.fill(123); dbg!(x[0]); dbg!(x.len()); dbg!(x.iter().sum::()); let _x: &[i32] = &[1, 2, 3]; + //~^ useless_vec for _ in [1, 2, 3] {} + //~^ useless_vec // Don't lint let x = vec![1, 2, 3]; @@ -122,6 +136,7 @@ fn issue11075() { } #[allow(clippy::never_loop)] for _string in [repro!(true), repro!(null)] { + //~^ useless_vec unimplemented!(); } @@ -139,6 +154,8 @@ fn issue11075() { } in_macro!(1, [1, 2], [1; 2]); + //~^ useless_vec + //~| useless_vec macro_rules! from_macro { () => { @@ -158,10 +175,12 @@ fn issue11075() { #[clippy::msrv = "1.53"] fn above() { for a in [1, 2, 3] { + //~^ useless_vec let _: usize = a; } for a in [String::new(), String::new()] { + //~^ useless_vec let _: String = a; } } @@ -193,7 +212,8 @@ fn issue11861() { // Do not lint the next line this_macro_needs_vec!(vec![1]); - this_macro_doesnt_need_vec!([1]); //~ ERROR: useless use of `vec!` +this_macro_doesnt_need_vec!([1]); +//~^ useless_vec macro_rules! m { ($x:expr) => { @@ -220,4 +240,5 @@ fn issue_11958() { fn issue_12101() { for a in &[1, 2] {} + //~^ useless_vec } diff --git a/tests/ui/vec.rs b/tests/ui/vec.rs index c483271438b1..c82580b2fd1a 100644 --- a/tests/ui/vec.rs +++ b/tests/ui/vec.rs @@ -28,24 +28,34 @@ impl Line { fn main() { on_slice(&vec![]); + //~^ useless_vec on_slice(&[]); on_mut_slice(&mut vec![]); + //~^ useless_vec on_slice(&vec![1, 2]); + //~^ useless_vec on_slice(&[1, 2]); on_mut_slice(&mut vec![1, 2]); + //~^ useless_vec on_slice(&vec![1, 2]); + //~^ useless_vec on_slice(&[1, 2]); on_mut_slice(&mut vec![1, 2]); + //~^ useless_vec #[rustfmt::skip] on_slice(&vec!(1, 2)); + //~^ useless_vec on_slice(&[1, 2]); on_mut_slice(&mut vec![1, 2]); + //~^ useless_vec on_slice(&vec![1; 2]); + //~^ useless_vec on_slice(&[1; 2]); on_mut_slice(&mut vec![1; 2]); + //~^ useless_vec on_vec(&vec![]); on_vec(&vec![1, 2]); @@ -72,17 +82,21 @@ fn main() { // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 let _x: i32 = vec![1, 2, 3].iter().sum(); + //~^ useless_vec // Do lint let mut x = vec![1, 2, 3]; + //~^ useless_vec x.fill(123); dbg!(x[0]); dbg!(x.len()); dbg!(x.iter().sum::()); let _x: &[i32] = &vec![1, 2, 3]; + //~^ useless_vec for _ in vec![1, 2, 3] {} + //~^ useless_vec // Don't lint let x = vec![1, 2, 3]; @@ -122,6 +136,7 @@ fn issue11075() { } #[allow(clippy::never_loop)] for _string in vec![repro!(true), repro!(null)] { + //~^ useless_vec unimplemented!(); } @@ -139,6 +154,8 @@ fn issue11075() { } in_macro!(1, vec![1, 2], vec![1; 2]); + //~^ useless_vec + //~| useless_vec macro_rules! from_macro { () => { @@ -158,10 +175,12 @@ fn issue11075() { #[clippy::msrv = "1.53"] fn above() { for a in vec![1, 2, 3] { + //~^ useless_vec let _: usize = a; } for a in vec![String::new(), String::new()] { + //~^ useless_vec let _: String = a; } } @@ -193,7 +212,8 @@ fn issue11861() { // Do not lint the next line this_macro_needs_vec!(vec![1]); - this_macro_doesnt_need_vec!(vec![1]); //~ ERROR: useless use of `vec!` +this_macro_doesnt_need_vec!(vec![1]); +//~^ useless_vec macro_rules! m { ($x:expr) => { @@ -220,4 +240,5 @@ fn issue_11958() { fn issue_12101() { for a in &(vec![1, 2]) {} + //~^ useless_vec } diff --git a/tests/ui/vec.stderr b/tests/ui/vec.stderr index 3faea8033fe2..1063e0e37d89 100644 --- a/tests/ui/vec.stderr +++ b/tests/ui/vec.stderr @@ -8,31 +8,19 @@ LL | on_slice(&vec![]); = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]` error: useless use of `vec!` - --> tests/ui/vec.rs:32:18 + --> tests/ui/vec.rs:33:18 | LL | on_mut_slice(&mut vec![]); | ^^^^^^^^^^^ help: you can use a slice directly: `&mut []` error: useless use of `vec!` - --> tests/ui/vec.rs:34:14 + --> tests/ui/vec.rs:36:14 | LL | on_slice(&vec![1, 2]); | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` error: useless use of `vec!` - --> tests/ui/vec.rs:36:18 - | -LL | on_mut_slice(&mut vec![1, 2]); - | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:38:14 - | -LL | on_slice(&vec![1, 2]); - | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:40:18 + --> tests/ui/vec.rs:39:18 | LL | on_mut_slice(&mut vec![1, 2]); | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` @@ -40,89 +28,101 @@ LL | on_mut_slice(&mut vec![1, 2]); error: useless use of `vec!` --> tests/ui/vec.rs:42:14 | -LL | on_slice(&vec!(1, 2)); +LL | on_slice(&vec![1, 2]); | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` error: useless use of `vec!` - --> tests/ui/vec.rs:44:18 + --> tests/ui/vec.rs:45:18 | LL | on_mut_slice(&mut vec![1, 2]); | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` error: useless use of `vec!` - --> tests/ui/vec.rs:46:14 + --> tests/ui/vec.rs:48:14 + | +LL | on_slice(&vec!(1, 2)); + | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` + +error: useless use of `vec!` + --> tests/ui/vec.rs:51:18 + | +LL | on_mut_slice(&mut vec![1, 2]); + | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` + +error: useless use of `vec!` + --> tests/ui/vec.rs:54:14 | LL | on_slice(&vec![1; 2]); | ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]` error: useless use of `vec!` - --> tests/ui/vec.rs:48:18 + --> tests/ui/vec.rs:57:18 | LL | on_mut_slice(&mut vec![1; 2]); | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]` error: useless use of `vec!` - --> tests/ui/vec.rs:74:19 + --> tests/ui/vec.rs:84:19 | LL | let _x: i32 = vec![1, 2, 3].iter().sum(); | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` error: useless use of `vec!` - --> tests/ui/vec.rs:77:17 + --> tests/ui/vec.rs:88:17 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` error: useless use of `vec!` - --> tests/ui/vec.rs:83:22 + --> tests/ui/vec.rs:95:22 | LL | let _x: &[i32] = &vec![1, 2, 3]; | ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` error: useless use of `vec!` - --> tests/ui/vec.rs:85:14 + --> tests/ui/vec.rs:98:14 | LL | for _ in vec![1, 2, 3] {} | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` error: useless use of `vec!` - --> tests/ui/vec.rs:124:20 + --> tests/ui/vec.rs:138:20 | LL | for _string in vec![repro!(true), repro!(null)] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]` error: useless use of `vec!` - --> tests/ui/vec.rs:141:18 + --> tests/ui/vec.rs:156:18 | LL | in_macro!(1, vec![1, 2], vec![1; 2]); | ^^^^^^^^^^ help: you can use an array directly: `[1, 2]` error: useless use of `vec!` - --> tests/ui/vec.rs:141:30 + --> tests/ui/vec.rs:156:30 | LL | in_macro!(1, vec![1, 2], vec![1; 2]); | ^^^^^^^^^^ help: you can use an array directly: `[1; 2]` error: useless use of `vec!` - --> tests/ui/vec.rs:160:14 + --> tests/ui/vec.rs:177:14 | LL | for a in vec![1, 2, 3] { | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` error: useless use of `vec!` - --> tests/ui/vec.rs:164:14 + --> tests/ui/vec.rs:182:14 | LL | for a in vec![String::new(), String::new()] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` error: useless use of `vec!` - --> tests/ui/vec.rs:196:33 + --> tests/ui/vec.rs:215:29 | -LL | this_macro_doesnt_need_vec!(vec![1]); - | ^^^^^^^ help: you can use an array directly: `[1]` +LL | this_macro_doesnt_need_vec!(vec![1]); + | ^^^^^^^ help: you can use an array directly: `[1]` error: useless use of `vec!` - --> tests/ui/vec.rs:222:14 + --> tests/ui/vec.rs:242:14 | LL | for a in &(vec![1, 2]) {} | ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` diff --git a/tests/ui/vec_box_sized.rs b/tests/ui/vec_box_sized.rs index 49eaf8e062af..d32081c26a03 100644 --- a/tests/ui/vec_box_sized.rs +++ b/tests/ui/vec_box_sized.rs @@ -24,22 +24,30 @@ unsafe impl Allocator for DummyAllocator { mod should_trigger { use super::{DummyAllocator, SizedStruct}; const C: Vec> = Vec::new(); + //~^ vec_box static S: Vec> = Vec::new(); + //~^ vec_box struct StructWithVecBox { sized_type: Vec>, + //~^ vec_box } struct A(Vec>); + //~^ vec_box struct B(Vec>>); + //~^ vec_box fn allocator_global_defined_vec() -> Vec, std::alloc::Global> { + //~^ vec_box Vec::new() } fn allocator_global_defined_box() -> Vec> { + //~^ vec_box Vec::new() } fn allocator_match() -> Vec, DummyAllocator> { + //~^ vec_box Vec::new_in(DummyAllocator) } } @@ -77,6 +85,7 @@ mod inner_mod { use super::inner::S; pub fn f() -> Vec> { + //~^ vec_box vec![] } } diff --git a/tests/ui/vec_box_sized.stderr b/tests/ui/vec_box_sized.stderr index 0ffcc8314340..65db267977a6 100644 --- a/tests/ui/vec_box_sized.stderr +++ b/tests/ui/vec_box_sized.stderr @@ -8,49 +8,49 @@ LL | const C: Vec> = Vec::new(); = help: to override `-D warnings` add `#[allow(clippy::vec_box)]` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui/vec_box_sized.rs:27:15 + --> tests/ui/vec_box_sized.rs:28:15 | LL | static S: Vec> = Vec::new(); | ^^^^^^^^^^^^^ help: try: `Vec` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui/vec_box_sized.rs:30:21 + --> tests/ui/vec_box_sized.rs:32:21 | LL | sized_type: Vec>, | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui/vec_box_sized.rs:33:14 + --> tests/ui/vec_box_sized.rs:36:14 | LL | struct A(Vec>); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui/vec_box_sized.rs:34:18 + --> tests/ui/vec_box_sized.rs:38:18 | LL | struct B(Vec>>); | ^^^^^^^^^^^^^^^ help: try: `Vec` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui/vec_box_sized.rs:36:42 + --> tests/ui/vec_box_sized.rs:41:42 | LL | fn allocator_global_defined_vec() -> Vec, std::alloc::Global> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui/vec_box_sized.rs:39:42 + --> tests/ui/vec_box_sized.rs:45:42 | LL | fn allocator_global_defined_box() -> Vec> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui/vec_box_sized.rs:42:29 + --> tests/ui/vec_box_sized.rs:49:29 | LL | fn allocator_match() -> Vec, DummyAllocator> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui/vec_box_sized.rs:79:23 + --> tests/ui/vec_box_sized.rs:87:23 | LL | pub fn f() -> Vec> { | ^^^^^^^^^^^ help: try: `Vec` diff --git a/tests/ui/vec_init_then_push.rs b/tests/ui/vec_init_then_push.rs index 1c60a75c56ae..31cd84d2cf40 100644 --- a/tests/ui/vec_init_then_push.rs +++ b/tests/ui/vec_init_then_push.rs @@ -3,16 +3,19 @@ //@no-rustfix fn main() { let mut def_err: Vec = Default::default(); - //~^ ERROR: calls to `push` immediately after creation - //~| NOTE: `-D clippy::vec-init-then-push` implied by `-D warnings` + //~^ vec_init_then_push + + def_err.push(0); let mut new_err = Vec::::new(); - //~^ ERROR: calls to `push` immediately after creation + //~^ vec_init_then_push + new_err.push(1); let mut cap_err = Vec::with_capacity(2); - //~^ ERROR: calls to `push` immediately after creation + //~^ vec_init_then_push + cap_err.push(0); cap_err.push(1); cap_err.push(2); @@ -25,7 +28,8 @@ fn main() { cap_ok.push(0); new_err = Vec::new(); - //~^ ERROR: calls to `push` immediately after creation + //~^ vec_init_then_push + new_err.push(0); let mut vec = Vec::new(); @@ -76,7 +80,8 @@ fn _cond_push(x: bool) -> Vec { fn _push_then_edit(x: u32) -> Vec { let mut v = Vec::new(); - //~^ ERROR: calls to `push` immediately after creation + //~^ vec_init_then_push + v.push(x); v.push(1); v[0] = v[1] + 5; @@ -85,7 +90,8 @@ fn _push_then_edit(x: u32) -> Vec { fn _cond_push_with_large_start(x: bool) -> Vec { let mut v = Vec::new(); - //~^ ERROR: calls to `push` immediately after creation + //~^ vec_init_then_push + v.push(0); v.push(1); v.push(0); @@ -99,7 +105,8 @@ fn _cond_push_with_large_start(x: bool) -> Vec { } let mut v2 = Vec::new(); - //~^ ERROR: calls to `push` immediately after creation + //~^ vec_init_then_push + v2.push(0); v2.push(1); v2.push(0); @@ -115,7 +122,8 @@ fn _cond_push_with_large_start(x: bool) -> Vec { fn f() { let mut v = Vec::new(); - //~^ ERROR: calls to `push` immediately after creation + //~^ vec_init_then_push + v.push((0i32, 0i32)); let y = v[0].0.abs(); } diff --git a/tests/ui/vec_init_then_push.stderr b/tests/ui/vec_init_then_push.stderr index f35625c9b085..3be277bb07b9 100644 --- a/tests/ui/vec_init_then_push.stderr +++ b/tests/ui/vec_init_then_push.stderr @@ -10,69 +10,71 @@ LL | | def_err.push(0); = help: to override `-D warnings` add `#[allow(clippy::vec_init_then_push)]` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:10:5 + --> tests/ui/vec_init_then_push.rs:11:5 | LL | / let mut new_err = Vec::::new(); -LL | | +... | LL | | new_err.push(1); | |____________________^ help: consider using the `vec![]` macro: `let mut new_err = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:14:5 + --> tests/ui/vec_init_then_push.rs:16:5 | LL | / let mut cap_err = Vec::with_capacity(2); LL | | +LL | | LL | | cap_err.push(0); LL | | cap_err.push(1); LL | | cap_err.push(2); | |____________________^ help: consider using the `vec![]` macro: `let mut cap_err = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:27:5 + --> tests/ui/vec_init_then_push.rs:30:5 | LL | / new_err = Vec::new(); -LL | | +... | LL | | new_err.push(0); | |____________________^ help: consider using the `vec![]` macro: `new_err = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:78:5 + --> tests/ui/vec_init_then_push.rs:82:5 | LL | / let mut v = Vec::new(); LL | | +LL | | LL | | v.push(x); LL | | v.push(1); | |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:87:5 + --> tests/ui/vec_init_then_push.rs:92:5 | LL | / let mut v = Vec::new(); LL | | +LL | | LL | | v.push(0); -LL | | v.push(1); ... | LL | | v.push(1); LL | | v.push(0); | |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:101:5 + --> tests/ui/vec_init_then_push.rs:107:5 | LL | / let mut v2 = Vec::new(); LL | | +LL | | LL | | v2.push(0); -LL | | v2.push(1); ... | LL | | v2.push(1); LL | | v2.push(0); | |_______________^ help: consider using the `vec![]` macro: `let mut v2 = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:117:5 + --> tests/ui/vec_init_then_push.rs:124:5 | LL | / let mut v = Vec::new(); -LL | | +... | LL | | v.push((0i32, 0i32)); | |_________________________^ help: consider using the `vec![]` macro: `let v = vec![..];` diff --git a/tests/ui/vec_resize_to_zero.fixed b/tests/ui/vec_resize_to_zero.fixed index b4c2d8209e76..f5c0ecd72e00 100644 --- a/tests/ui/vec_resize_to_zero.fixed +++ b/tests/ui/vec_resize_to_zero.fixed @@ -5,7 +5,8 @@ fn main() { // applicable here v.clear(); - //~^ ERROR: emptying a vector with `resize` + //~^ vec_resize_to_zero + // not applicable v.resize(2, 5); diff --git a/tests/ui/vec_resize_to_zero.rs b/tests/ui/vec_resize_to_zero.rs index 5b11c940f21a..2b75b475223c 100644 --- a/tests/ui/vec_resize_to_zero.rs +++ b/tests/ui/vec_resize_to_zero.rs @@ -5,7 +5,8 @@ fn main() { // applicable here v.resize(0, 5); - //~^ ERROR: emptying a vector with `resize` + //~^ vec_resize_to_zero + // not applicable v.resize(2, 5); diff --git a/tests/ui/verbose_file_reads.rs b/tests/ui/verbose_file_reads.rs index 9dd4f4e1d9be..374cd39df947 100644 --- a/tests/ui/verbose_file_reads.rs +++ b/tests/ui/verbose_file_reads.rs @@ -21,10 +21,12 @@ fn main() -> std::io::Result<()> { let mut f = File::open(path)?; let mut buffer = Vec::new(); f.read_to_end(&mut buffer)?; - //~^ ERROR: use of `File::read_to_end` + //~^ verbose_file_reads + // ...and this let mut string_buffer = String::new(); f.read_to_string(&mut string_buffer)?; - //~^ ERROR: use of `File::read_to_string` + //~^ verbose_file_reads + Ok(()) } diff --git a/tests/ui/verbose_file_reads.stderr b/tests/ui/verbose_file_reads.stderr index e85068fc7a9c..9e6f6788562f 100644 --- a/tests/ui/verbose_file_reads.stderr +++ b/tests/ui/verbose_file_reads.stderr @@ -9,7 +9,7 @@ LL | f.read_to_end(&mut buffer)?; = help: to override `-D warnings` add `#[allow(clippy::verbose_file_reads)]` error: use of `File::read_to_string` - --> tests/ui/verbose_file_reads.rs:27:5 + --> tests/ui/verbose_file_reads.rs:28:5 | LL | f.read_to_string(&mut string_buffer)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/waker_clone_wake.fixed b/tests/ui/waker_clone_wake.fixed index 9c02b9a90fdd..d7b5000a5d50 100644 --- a/tests/ui/waker_clone_wake.fixed +++ b/tests/ui/waker_clone_wake.fixed @@ -13,8 +13,10 @@ macro_rules! mac { pub fn wake(cx: &mut std::task::Context) { cx.waker().wake_by_ref(); + //~^ waker_clone_wake mac!(cx).wake_by_ref(); + //~^ waker_clone_wake } pub fn no_lint(cx: &mut std::task::Context, c: &Custom) { diff --git a/tests/ui/waker_clone_wake.rs b/tests/ui/waker_clone_wake.rs index edc3bbd8fc08..27fa922d1112 100644 --- a/tests/ui/waker_clone_wake.rs +++ b/tests/ui/waker_clone_wake.rs @@ -13,8 +13,10 @@ macro_rules! mac { pub fn wake(cx: &mut std::task::Context) { cx.waker().clone().wake(); + //~^ waker_clone_wake mac!(cx).clone().wake(); + //~^ waker_clone_wake } pub fn no_lint(cx: &mut std::task::Context, c: &Custom) { diff --git a/tests/ui/waker_clone_wake.stderr b/tests/ui/waker_clone_wake.stderr index bf2c02a76c9b..9eb167d13107 100644 --- a/tests/ui/waker_clone_wake.stderr +++ b/tests/ui/waker_clone_wake.stderr @@ -8,7 +8,7 @@ LL | cx.waker().clone().wake(); = help: to override `-D warnings` add `#[allow(clippy::waker_clone_wake)]` error: cloning a `Waker` only to wake it - --> tests/ui/waker_clone_wake.rs:17:5 + --> tests/ui/waker_clone_wake.rs:18:5 | LL | mac!(cx).clone().wake(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `mac!(cx).wake_by_ref()` diff --git a/tests/ui/while_float.rs b/tests/ui/while_float.rs index a3b0618948e6..06dc700c1980 100644 --- a/tests/ui/while_float.rs +++ b/tests/ui/while_float.rs @@ -2,9 +2,11 @@ fn main() { let mut x = 0.0_f32; while x < 42.0_f32 { + //~^ while_float x += 0.5; } while x < 42.0 { + //~^ while_float x += 1.0; } let mut x = 0; diff --git a/tests/ui/while_float.stderr b/tests/ui/while_float.stderr index b8e934b97c6c..e83e1b925c16 100644 --- a/tests/ui/while_float.stderr +++ b/tests/ui/while_float.stderr @@ -11,7 +11,7 @@ LL | #[deny(clippy::while_float)] | ^^^^^^^^^^^^^^^^^^^ error: while condition comparing floats - --> tests/ui/while_float.rs:7:11 + --> tests/ui/while_float.rs:8:11 | LL | while x < 42.0 { | ^^^^^^^^ diff --git a/tests/ui/while_let_loop.rs b/tests/ui/while_let_loop.rs index fa5325bebffa..ea442b9b2b5c 100644 --- a/tests/ui/while_let_loop.rs +++ b/tests/ui/while_let_loop.rs @@ -4,8 +4,9 @@ fn main() { let y = Some(true); loop { - //~^ ERROR: this loop could be written as a `while let` loop - //~| NOTE: `-D clippy::while-let-loop` implied by `-D warnings` + //~^ while_let_loop + + if let Some(_x) = y { let _v = 1; } else { @@ -23,7 +24,8 @@ fn main() { } loop { - //~^ ERROR: this loop could be written as a `while let` loop + //~^ while_let_loop + match y { Some(_x) => true, None => break, @@ -31,7 +33,8 @@ fn main() { } loop { - //~^ ERROR: this loop could be written as a `while let` loop + //~^ while_let_loop + let x = match y { Some(x) => x, None => break, @@ -41,7 +44,8 @@ fn main() { } loop { - //~^ ERROR: this loop could be written as a `while let` loop + //~^ while_let_loop + let x = match y { Some(x) => x, None => break, @@ -72,7 +76,8 @@ fn main() { // #675, this used to have a wrong suggestion loop { - //~^ ERROR: this loop could be written as a `while let` loop + //~^ while_let_loop + let (e, l) = match "".split_whitespace().next() { Some(word) => (word.is_empty(), word.len()), None => break, diff --git a/tests/ui/while_let_loop.stderr b/tests/ui/while_let_loop.stderr index 10c2311d82f7..3bd8ab85a92f 100644 --- a/tests/ui/while_let_loop.stderr +++ b/tests/ui/while_let_loop.stderr @@ -2,9 +2,6 @@ error: this loop could be written as a `while let` loop --> tests/ui/while_let_loop.rs:6:5 | LL | / loop { -LL | | -LL | | -LL | | if let Some(_x) = y { ... | LL | | } | |_____^ help: try: `while let Some(_x) = y { .. }` @@ -13,47 +10,47 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::while_let_loop)]` error: this loop could be written as a `while let` loop - --> tests/ui/while_let_loop.rs:25:5 + --> tests/ui/while_let_loop.rs:26:5 | LL | / loop { LL | | +LL | | LL | | match y { -LL | | Some(_x) => true, -LL | | None => break, +... | LL | | }; LL | | } | |_____^ help: try: `while let Some(_x) = y { .. }` error: this loop could be written as a `while let` loop - --> tests/ui/while_let_loop.rs:33:5 + --> tests/ui/while_let_loop.rs:35:5 | LL | / loop { LL | | +LL | | LL | | let x = match y { -LL | | Some(x) => x, ... | LL | | let _str = "foo"; LL | | } | |_____^ help: try: `while let Some(x) = y { .. }` error: this loop could be written as a `while let` loop - --> tests/ui/while_let_loop.rs:43:5 + --> tests/ui/while_let_loop.rs:46:5 | LL | / loop { LL | | +LL | | LL | | let x = match y { -LL | | Some(x) => x, ... | LL | | } | |_____^ help: try: `while let Some(x) = y { .. }` error: this loop could be written as a `while let` loop - --> tests/ui/while_let_loop.rs:74:5 + --> tests/ui/while_let_loop.rs:78:5 | LL | / loop { LL | | +LL | | LL | | let (e, l) = match "".split_whitespace().next() { -LL | | Some(word) => (word.is_empty(), word.len()), ... | LL | | let _ = (e, l); LL | | } diff --git a/tests/ui/while_let_on_iterator.fixed b/tests/ui/while_let_on_iterator.fixed index b8087c6e000f..bf4950620340 100644 --- a/tests/ui/while_let_on_iterator.fixed +++ b/tests/ui/while_let_on_iterator.fixed @@ -13,16 +13,19 @@ fn base() { let mut iter = 1..20; for x in iter { + //~^ while_let_on_iterator println!("{}", x); } let mut iter = 1..20; for x in iter { + //~^ while_let_on_iterator println!("{}", x); } let mut iter = 1..20; for _ in iter {} + //~^ while_let_on_iterator let mut iter = 1..20; while let None = iter.next() {} // this is fine (if nonsensical) @@ -99,6 +102,7 @@ fn refutable2() { let mut it = v.windows(2); for [..] in it {} + //~^ while_let_on_iterator let v = vec![[1], [2], [3]]; let mut it = v.iter(); @@ -106,6 +110,7 @@ fn refutable2() { let mut it = v.iter(); for [_x] in it {} + //~^ while_let_on_iterator } // binding @@ -119,6 +124,7 @@ fn refutable2() { let v = vec![[1], [2], [3]]; let mut it = v.iter(); for x @ [_] in it { + //~^ while_let_on_iterator println!("{:?}", x); } } @@ -139,6 +145,7 @@ fn nested_loops() { loop { let mut y = a.iter(); for _ in y { + //~^ while_let_on_iterator // use a for loop here } } @@ -196,6 +203,7 @@ fn issue6491() { let mut it = 1..40; while let Some(n) = it.next() { for m in it.by_ref() { + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -207,8 +215,10 @@ fn issue6491() { // This is fine, inner loop uses a new iterator. let mut it = 1..40; for n in it { + //~^ while_let_on_iterator let mut it = 1..40; for m in it { + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -218,6 +228,7 @@ fn issue6491() { // Weird binding shouldn't change anything. let (mut it, _) = (1..40, 0); for m in it { + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -227,6 +238,7 @@ fn issue6491() { // Used after the loop, needs &mut. let mut it = 1..40; for m in it.by_ref() { + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -244,6 +256,7 @@ fn issue6231() { let mut opt = Some(0); while let Some(n) = opt.take().or_else(|| it.next()) { for m in it.by_ref() { + //~^ while_let_on_iterator if n % 10 == 0 { break; } @@ -259,6 +272,7 @@ fn issue1924() { fn f(&mut self) -> Option { // Used as a field. for i in self.0.by_ref() { + //~^ while_let_on_iterator if !(3..8).contains(&i) { return Some(i); } @@ -291,6 +305,7 @@ fn issue1924() { } // This one is fine, a different field is borrowed for i in self.0.0.0.by_ref() { + //~^ while_let_on_iterator if i == 1 { return self.0.1.take(); } else { @@ -320,6 +335,7 @@ fn issue1924() { // Needs &mut, field of the iterator is accessed after the loop let mut it = S2(1..40, 0); for n in it.by_ref() { + //~^ while_let_on_iterator if n == 0 { break; } @@ -332,6 +348,7 @@ fn issue7249() { let mut x = || { // Needs &mut, the closure can be called multiple times for x in it.by_ref() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -346,6 +363,7 @@ fn issue7510() { let it = &mut it; // Needs to reborrow `it` as the binding isn't mutable for x in it.by_ref() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -357,6 +375,7 @@ fn issue7510() { let it = S(&mut it); // Needs to reborrow `it.0` as the binding isn't mutable for x in it.0.by_ref() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -392,6 +411,7 @@ fn custom_deref() { let mut s = S2(S1 { x: 0..10 }); for x in s.x.by_ref() { + //~^ while_let_on_iterator println!("{}", x); } } @@ -399,6 +419,7 @@ fn custom_deref() { fn issue_8113() { let mut x = [0..10]; for x in x[0].by_ref() { + //~^ while_let_on_iterator println!("{}", x); } } @@ -407,6 +428,7 @@ fn fn_once_closure() { let mut it = 0..10; (|| { for x in it.by_ref() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -417,6 +439,7 @@ fn fn_once_closure() { let mut it = 0..10; f(|| { for x in it { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -427,6 +450,7 @@ fn fn_once_closure() { let mut it = 0..10; f2(|| { for x in it.by_ref() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -437,6 +461,7 @@ fn fn_once_closure() { f3(|| { let mut it = 0..10; for x in it { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -449,6 +474,7 @@ fn fn_once_closure() { let mut it = 0..10; f4(|| { for x in it { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -459,6 +485,7 @@ fn fn_once_closure() { fn issue13123() { let mut it = 0..20; 'label: for n in it { + //~^ while_let_on_iterator if n % 25 == 0 { break 'label; } @@ -468,6 +495,7 @@ fn issue13123() { fn main() { let mut it = 0..20; for _ in it { + //~^ while_let_on_iterator println!("test"); } } diff --git a/tests/ui/while_let_on_iterator.rs b/tests/ui/while_let_on_iterator.rs index 8e02f59b5126..d34b78efc706 100644 --- a/tests/ui/while_let_on_iterator.rs +++ b/tests/ui/while_let_on_iterator.rs @@ -13,16 +13,19 @@ fn base() { let mut iter = 1..20; while let Option::Some(x) = iter.next() { + //~^ while_let_on_iterator println!("{}", x); } let mut iter = 1..20; while let Some(x) = iter.next() { + //~^ while_let_on_iterator println!("{}", x); } let mut iter = 1..20; while let Some(_) = iter.next() {} + //~^ while_let_on_iterator let mut iter = 1..20; while let None = iter.next() {} // this is fine (if nonsensical) @@ -99,6 +102,7 @@ fn refutable2() { let mut it = v.windows(2); while let Some([..]) = it.next() {} + //~^ while_let_on_iterator let v = vec![[1], [2], [3]]; let mut it = v.iter(); @@ -106,6 +110,7 @@ fn refutable2() { let mut it = v.iter(); while let Some([_x]) = it.next() {} + //~^ while_let_on_iterator } // binding @@ -119,6 +124,7 @@ fn refutable2() { let v = vec![[1], [2], [3]]; let mut it = v.iter(); while let Some(x @ [_]) = it.next() { + //~^ while_let_on_iterator println!("{:?}", x); } } @@ -139,6 +145,7 @@ fn nested_loops() { loop { let mut y = a.iter(); while let Some(_) = y.next() { + //~^ while_let_on_iterator // use a for loop here } } @@ -196,6 +203,7 @@ fn issue6491() { let mut it = 1..40; while let Some(n) = it.next() { while let Some(m) = it.next() { + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -207,8 +215,10 @@ fn issue6491() { // This is fine, inner loop uses a new iterator. let mut it = 1..40; while let Some(n) = it.next() { + //~^ while_let_on_iterator let mut it = 1..40; while let Some(m) = it.next() { + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -218,6 +228,7 @@ fn issue6491() { // Weird binding shouldn't change anything. let (mut it, _) = (1..40, 0); while let Some(m) = it.next() { + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -227,6 +238,7 @@ fn issue6491() { // Used after the loop, needs &mut. let mut it = 1..40; while let Some(m) = it.next() { + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -244,6 +256,7 @@ fn issue6231() { let mut opt = Some(0); while let Some(n) = opt.take().or_else(|| it.next()) { while let Some(m) = it.next() { + //~^ while_let_on_iterator if n % 10 == 0 { break; } @@ -259,6 +272,7 @@ fn issue1924() { fn f(&mut self) -> Option { // Used as a field. while let Some(i) = self.0.next() { + //~^ while_let_on_iterator if !(3..8).contains(&i) { return Some(i); } @@ -291,6 +305,7 @@ fn issue1924() { } // This one is fine, a different field is borrowed while let Some(i) = self.0.0.0.next() { + //~^ while_let_on_iterator if i == 1 { return self.0.1.take(); } else { @@ -320,6 +335,7 @@ fn issue1924() { // Needs &mut, field of the iterator is accessed after the loop let mut it = S2(1..40, 0); while let Some(n) = it.next() { + //~^ while_let_on_iterator if n == 0 { break; } @@ -332,6 +348,7 @@ fn issue7249() { let mut x = || { // Needs &mut, the closure can be called multiple times while let Some(x) = it.next() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -346,6 +363,7 @@ fn issue7510() { let it = &mut it; // Needs to reborrow `it` as the binding isn't mutable while let Some(x) = it.next() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -357,6 +375,7 @@ fn issue7510() { let it = S(&mut it); // Needs to reborrow `it.0` as the binding isn't mutable while let Some(x) = it.0.next() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -392,6 +411,7 @@ fn custom_deref() { let mut s = S2(S1 { x: 0..10 }); while let Some(x) = s.x.next() { + //~^ while_let_on_iterator println!("{}", x); } } @@ -399,6 +419,7 @@ fn custom_deref() { fn issue_8113() { let mut x = [0..10]; while let Some(x) = x[0].next() { + //~^ while_let_on_iterator println!("{}", x); } } @@ -407,6 +428,7 @@ fn fn_once_closure() { let mut it = 0..10; (|| { while let Some(x) = it.next() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -417,6 +439,7 @@ fn fn_once_closure() { let mut it = 0..10; f(|| { while let Some(x) = it.next() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -427,6 +450,7 @@ fn fn_once_closure() { let mut it = 0..10; f2(|| { while let Some(x) = it.next() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -437,6 +461,7 @@ fn fn_once_closure() { f3(|| { let mut it = 0..10; while let Some(x) = it.next() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -449,6 +474,7 @@ fn fn_once_closure() { let mut it = 0..10; f4(|| { while let Some(x) = it.next() { + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -459,6 +485,7 @@ fn fn_once_closure() { fn issue13123() { let mut it = 0..20; 'label: while let Some(n) = it.next() { + //~^ while_let_on_iterator if n % 25 == 0 { break 'label; } @@ -468,6 +495,7 @@ fn issue13123() { fn main() { let mut it = 0..20; while let Some(..) = it.next() { + //~^ while_let_on_iterator println!("test"); } } diff --git a/tests/ui/while_let_on_iterator.stderr b/tests/ui/while_let_on_iterator.stderr index d96b26acf345..50f20227b90f 100644 --- a/tests/ui/while_let_on_iterator.stderr +++ b/tests/ui/while_let_on_iterator.stderr @@ -8,59 +8,53 @@ LL | while let Option::Some(x) = iter.next() { = help: to override `-D warnings` add `#[allow(clippy::while_let_on_iterator)]` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:20:5 + --> tests/ui/while_let_on_iterator.rs:21:5 | LL | while let Some(x) = iter.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:25:5 + --> tests/ui/while_let_on_iterator.rs:27:5 | LL | while let Some(_) = iter.next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in iter` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:101:9 + --> tests/ui/while_let_on_iterator.rs:104:9 | LL | while let Some([..]) = it.next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [..] in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:108:9 + --> tests/ui/while_let_on_iterator.rs:112:9 | LL | while let Some([_x]) = it.next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [_x] in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:121:9 + --> tests/ui/while_let_on_iterator.rs:126:9 | LL | while let Some(x @ [_]) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x @ [_] in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:141:9 + --> tests/ui/while_let_on_iterator.rs:147:9 | LL | while let Some(_) = y.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in y` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:198:9 + --> tests/ui/while_let_on_iterator.rs:205:9 | LL | while let Some(m) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:209:5 + --> tests/ui/while_let_on_iterator.rs:217:5 | LL | while let Some(n) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it` -error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:211:9 - | -LL | while let Some(m) = it.next() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it` - error: this loop could be written as a `for` loop --> tests/ui/while_let_on_iterator.rs:220:9 | @@ -68,103 +62,109 @@ LL | while let Some(m) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:229:9 + --> tests/ui/while_let_on_iterator.rs:230:9 + | +LL | while let Some(m) = it.next() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:240:9 | LL | while let Some(m) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:246:9 + --> tests/ui/while_let_on_iterator.rs:258:9 | LL | while let Some(m) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:261:13 + --> tests/ui/while_let_on_iterator.rs:274:13 | LL | while let Some(i) = self.0.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:293:13 + --> tests/ui/while_let_on_iterator.rs:307:13 | LL | while let Some(i) = self.0.0.0.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.0.0.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:322:5 + --> tests/ui/while_let_on_iterator.rs:337:5 | LL | while let Some(n) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:334:9 + --> tests/ui/while_let_on_iterator.rs:350:9 | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:348:5 + --> tests/ui/while_let_on_iterator.rs:365:5 | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:359:5 + --> tests/ui/while_let_on_iterator.rs:377:5 | LL | while let Some(x) = it.0.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.0.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:394:5 + --> tests/ui/while_let_on_iterator.rs:413:5 | LL | while let Some(x) = s.x.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in s.x.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:401:5 + --> tests/ui/while_let_on_iterator.rs:421:5 | LL | while let Some(x) = x[0].next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in x[0].by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:409:9 + --> tests/ui/while_let_on_iterator.rs:430:9 | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:419:9 + --> tests/ui/while_let_on_iterator.rs:441:9 | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:429:9 + --> tests/ui/while_let_on_iterator.rs:452:9 | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:439:9 + --> tests/ui/while_let_on_iterator.rs:463:9 | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:451:9 + --> tests/ui/while_let_on_iterator.rs:476:9 | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:461:5 + --> tests/ui/while_let_on_iterator.rs:487:5 | LL | 'label: while let Some(n) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'label: for n in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:470:5 + --> tests/ui/while_let_on_iterator.rs:497:5 | LL | while let Some(..) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it` diff --git a/tests/ui/wild_in_or_pats.rs b/tests/ui/wild_in_or_pats.rs index bc8a1dbee71d..8d194a38ddf8 100644 --- a/tests/ui/wild_in_or_pats.rs +++ b/tests/ui/wild_in_or_pats.rs @@ -6,7 +6,8 @@ fn main() { dbg!("matched a"); }, "bar" | _ => { - //~^ ERROR: wildcard pattern covers any other pattern as it will match anyway + //~^ wildcard_in_or_patterns + dbg!("matched (bar or) wild"); }, }; @@ -15,7 +16,8 @@ fn main() { dbg!("matched a"); }, "bar" | "bar2" | _ => { - //~^ ERROR: wildcard pattern covers any other pattern as it will match anyway + //~^ wildcard_in_or_patterns + dbg!("matched (bar or bar2 or) wild"); }, }; @@ -24,7 +26,8 @@ fn main() { dbg!("matched a"); }, _ | "bar" | _ => { - //~^ ERROR: wildcard pattern covers any other pattern as it will match anyway + //~^ wildcard_in_or_patterns + dbg!("matched (bar or) wild"); }, }; @@ -33,7 +36,8 @@ fn main() { dbg!("matched a"); }, _ | "bar" => { - //~^ ERROR: wildcard pattern covers any other pattern as it will match anyway + //~^ wildcard_in_or_patterns + dbg!("matched (bar or) wild"); }, }; @@ -67,6 +71,7 @@ fn main() { dbg!("Change the color"); }, ExhaustiveEnum::Quit | _ => { + //~^ wildcard_in_or_patterns dbg!("Quit or other"); }, }; @@ -102,6 +107,7 @@ fn main() { dbg!("On the y axis at {y}"); }, ExhaustiveStruct { x: 1, y: 1 } | _ => { + //~^ wildcard_in_or_patterns dbg!("On neither axis: ({x}, {y})"); }, } diff --git a/tests/ui/wild_in_or_pats.stderr b/tests/ui/wild_in_or_pats.stderr index 5e409d6dfa6d..09b2b533cd3e 100644 --- a/tests/ui/wild_in_or_pats.stderr +++ b/tests/ui/wild_in_or_pats.stderr @@ -9,7 +9,7 @@ LL | "bar" | _ => { = help: to override `-D warnings` add `#[allow(clippy::wildcard_in_or_patterns)]` error: wildcard pattern covers any other pattern as it will match anyway - --> tests/ui/wild_in_or_pats.rs:17:9 + --> tests/ui/wild_in_or_pats.rs:18:9 | LL | "bar" | "bar2" | _ => { | ^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | "bar" | "bar2" | _ => { = help: consider handling `_` separately error: wildcard pattern covers any other pattern as it will match anyway - --> tests/ui/wild_in_or_pats.rs:26:9 + --> tests/ui/wild_in_or_pats.rs:28:9 | LL | _ | "bar" | _ => { | ^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | _ | "bar" | _ => { = help: consider handling `_` separately error: wildcard pattern covers any other pattern as it will match anyway - --> tests/ui/wild_in_or_pats.rs:35:9 + --> tests/ui/wild_in_or_pats.rs:38:9 | LL | _ | "bar" => { | ^^^^^^^^^ @@ -33,7 +33,7 @@ LL | _ | "bar" => { = help: consider handling `_` separately error: wildcard pattern covers any other pattern as it will match anyway - --> tests/ui/wild_in_or_pats.rs:69:9 + --> tests/ui/wild_in_or_pats.rs:73:9 | LL | ExhaustiveEnum::Quit | _ => { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | ExhaustiveEnum::Quit | _ => { = help: consider handling `_` separately error: wildcard pattern covers any other pattern as it will match anyway - --> tests/ui/wild_in_or_pats.rs:104:9 + --> tests/ui/wild_in_or_pats.rs:109:9 | LL | ExhaustiveStruct { x: 1, y: 1 } | _ => { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/wildcard_enum_match_arm.fixed b/tests/ui/wildcard_enum_match_arm.fixed index 1089415733a9..141ff6eb2ac7 100644 --- a/tests/ui/wildcard_enum_match_arm.fixed +++ b/tests/ui/wildcard_enum_match_arm.fixed @@ -37,14 +37,17 @@ fn main() { match color { Color::Red => println!("Red"), Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan => eprintln!("Not red"), + //~^ wildcard_enum_match_arm }; match color { Color::Red => println!("Red"), _not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan => eprintln!("Not red"), + //~^ wildcard_enum_match_arm }; let _str = match color { Color::Red => "Red".to_owned(), not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan => format!("{:?}", not_red), + //~^ wildcard_enum_match_arm }; match color { Color::Red => {}, @@ -61,6 +64,7 @@ fn main() { match color { Color::Rgb(r, _, _) if r > 0 => "Some red", Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan => "No red", + //~^ wildcard_enum_match_arm }; match color { Color::Red | Color::Green | Color::Blue | Color::Cyan => {}, @@ -78,6 +82,7 @@ fn main() { match error_kind { ErrorKind::NotFound => {}, ErrorKind::PermissionDenied | _ => {}, + //~^ wildcard_enum_match_arm } match error_kind { ErrorKind::NotFound => {}, @@ -96,6 +101,7 @@ fn main() { match Enum::A { Enum::A => (), Enum::B | Enum::__Private => (), + //~^ wildcard_enum_match_arm } } } diff --git a/tests/ui/wildcard_enum_match_arm.rs b/tests/ui/wildcard_enum_match_arm.rs index d9285c56f3ef..a13684e9100b 100644 --- a/tests/ui/wildcard_enum_match_arm.rs +++ b/tests/ui/wildcard_enum_match_arm.rs @@ -37,14 +37,17 @@ fn main() { match color { Color::Red => println!("Red"), _ => eprintln!("Not red"), + //~^ wildcard_enum_match_arm }; match color { Color::Red => println!("Red"), _not_red => eprintln!("Not red"), + //~^ wildcard_enum_match_arm }; let _str = match color { Color::Red => "Red".to_owned(), not_red => format!("{:?}", not_red), + //~^ wildcard_enum_match_arm }; match color { Color::Red => {}, @@ -61,6 +64,7 @@ fn main() { match color { Color::Rgb(r, _, _) if r > 0 => "Some red", _ => "No red", + //~^ wildcard_enum_match_arm }; match color { Color::Red | Color::Green | Color::Blue | Color::Cyan => {}, @@ -78,6 +82,7 @@ fn main() { match error_kind { ErrorKind::NotFound => {}, _ => {}, + //~^ wildcard_enum_match_arm } match error_kind { ErrorKind::NotFound => {}, @@ -96,6 +101,7 @@ fn main() { match Enum::A { Enum::A => (), _ => (), + //~^ wildcard_enum_match_arm } } } diff --git a/tests/ui/wildcard_enum_match_arm.stderr b/tests/ui/wildcard_enum_match_arm.stderr index 70ac768aaacd..088c6b7b2841 100644 --- a/tests/ui/wildcard_enum_match_arm.stderr +++ b/tests/ui/wildcard_enum_match_arm.stderr @@ -11,31 +11,31 @@ LL | #![deny(clippy::wildcard_enum_match_arm)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: wildcard match will also match any future added variants - --> tests/ui/wildcard_enum_match_arm.rs:43:9 + --> tests/ui/wildcard_enum_match_arm.rs:44:9 | LL | _not_red => eprintln!("Not red"), | ^^^^^^^^ help: try: `_not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan` error: wildcard match will also match any future added variants - --> tests/ui/wildcard_enum_match_arm.rs:47:9 + --> tests/ui/wildcard_enum_match_arm.rs:49:9 | LL | not_red => format!("{:?}", not_red), | ^^^^^^^ help: try: `not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan` error: wildcard match will also match any future added variants - --> tests/ui/wildcard_enum_match_arm.rs:63:9 + --> tests/ui/wildcard_enum_match_arm.rs:66:9 | LL | _ => "No red", | ^ help: try: `Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan` error: wildcard matches known variants and will also match future added variants - --> tests/ui/wildcard_enum_match_arm.rs:80:9 + --> tests/ui/wildcard_enum_match_arm.rs:84:9 | LL | _ => {}, | ^ help: try: `ErrorKind::PermissionDenied | _` error: wildcard match will also match any future added variants - --> tests/ui/wildcard_enum_match_arm.rs:98:13 + --> tests/ui/wildcard_enum_match_arm.rs:103:13 | LL | _ => (), | ^ help: try: `Enum::B | Enum::__Private` diff --git a/tests/ui/wildcard_imports.fixed b/tests/ui/wildcard_imports.fixed index 46890ee9213f..a26b4a34190c 100644 --- a/tests/ui/wildcard_imports.fixed +++ b/tests/ui/wildcard_imports.fixed @@ -13,15 +13,21 @@ extern crate wildcard_imports_helper; use crate::fn_mod::foo; +//~^ wildcard_imports use crate::mod_mod::inner_mod; +//~^ wildcard_imports use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}; +//~^ wildcard_imports #[macro_use] use crate::struct_mod::{A, inner_struct_mod}; +//~^ wildcard_imports #[allow(unused_imports)] use wildcard_imports_helper::inner::inner_for_self_import; use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar; +//~^ wildcard_imports use wildcard_imports_helper::{ExternA, extern_foo}; +//~^ wildcard_imports use std::io::prelude::*; use wildcard_imports_helper::extern_prelude::v1::*; @@ -92,6 +98,7 @@ mod underscore_mod { fn does_lint() { use self::exports_underscore_ish::{_Deref, dummy}; + //~^ wildcard_imports let _ = (&0).deref(); dummy(); } @@ -123,13 +130,16 @@ mod in_fn_test { fn test_intern() { use crate::fn_mod::foo; + //~^ wildcard_imports foo(); } fn test_extern() { use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo}; + //~^ wildcard_imports use wildcard_imports_helper::{ExternA, extern_foo}; + //~^ wildcard_imports inner_for_self_import::inner_extern_foo(); inner_extern_foo(); @@ -142,6 +152,8 @@ mod in_fn_test { fn test_inner_nested() { #[rustfmt::skip] use self::{inner::inner_foo, inner2::inner_bar}; + //~^ wildcard_imports + //~| wildcard_imports inner_foo(); inner_bar(); @@ -149,6 +161,7 @@ mod in_fn_test { fn test_extern_reexported() { use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}; + //~^ wildcard_imports extern_exported(); let _ = ExternExportedStruct; @@ -178,6 +191,7 @@ mod in_fn_test { fn test_reexported() { use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}; + //~^ wildcard_imports exported(); let _ = ExportedStruct; @@ -187,6 +201,7 @@ fn test_reexported() { #[rustfmt::skip] fn test_weird_formatting() { use crate:: in_fn_test::exported; + //~^ wildcard_imports use crate:: fn_mod::foo; exported(); @@ -198,6 +213,7 @@ mod super_imports { mod should_be_replaced { use super::foofoo; + //~^ wildcard_imports fn with_super() { let _ = foofoo(); @@ -236,6 +252,7 @@ mod super_imports { fn insidefoo() {} mod inner { use super::insidefoo; + //~^ wildcard_imports fn with_super() { let _ = insidefoo(); } @@ -244,6 +261,7 @@ mod super_imports { mod use_explicit_should_be_replaced { use crate::super_imports::foofoo; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); @@ -253,6 +271,7 @@ mod super_imports { mod use_double_super_should_be_replaced { mod inner { use super::super::foofoo; + //~^ wildcard_imports fn with_double_super() { let _ = foofoo(); @@ -262,6 +281,7 @@ mod super_imports { mod use_super_explicit_should_be_replaced { use super::super::super_imports::foofoo; + //~^ wildcard_imports fn with_super_explicit() { let _ = foofoo(); @@ -270,6 +290,7 @@ mod super_imports { mod attestation_should_be_replaced { use super::foofoo; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); diff --git a/tests/ui/wildcard_imports.rs b/tests/ui/wildcard_imports.rs index 1a5586cbb88d..2168f0a8918d 100644 --- a/tests/ui/wildcard_imports.rs +++ b/tests/ui/wildcard_imports.rs @@ -13,15 +13,21 @@ extern crate wildcard_imports_helper; use crate::fn_mod::*; +//~^ wildcard_imports use crate::mod_mod::*; +//~^ wildcard_imports use crate::multi_fn_mod::*; +//~^ wildcard_imports #[macro_use] use crate::struct_mod::*; +//~^ wildcard_imports #[allow(unused_imports)] use wildcard_imports_helper::inner::inner_for_self_import; use wildcard_imports_helper::inner::inner_for_self_import::*; +//~^ wildcard_imports use wildcard_imports_helper::*; +//~^ wildcard_imports use std::io::prelude::*; use wildcard_imports_helper::extern_prelude::v1::*; @@ -92,6 +98,7 @@ mod underscore_mod { fn does_lint() { use self::exports_underscore_ish::*; + //~^ wildcard_imports let _ = (&0).deref(); dummy(); } @@ -123,13 +130,16 @@ mod in_fn_test { fn test_intern() { use crate::fn_mod::*; + //~^ wildcard_imports foo(); } fn test_extern() { use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; + //~^ wildcard_imports use wildcard_imports_helper::*; + //~^ wildcard_imports inner_for_self_import::inner_extern_foo(); inner_extern_foo(); @@ -142,6 +152,8 @@ mod in_fn_test { fn test_inner_nested() { #[rustfmt::skip] use self::{inner::*, inner2::*}; + //~^ wildcard_imports + //~| wildcard_imports inner_foo(); inner_bar(); @@ -149,6 +161,7 @@ mod in_fn_test { fn test_extern_reexported() { use wildcard_imports_helper::*; + //~^ wildcard_imports extern_exported(); let _ = ExternExportedStruct; @@ -178,6 +191,7 @@ mod in_fn_test { fn test_reexported() { use crate::in_fn_test::*; + //~^ wildcard_imports exported(); let _ = ExportedStruct; @@ -187,7 +201,9 @@ fn test_reexported() { #[rustfmt::skip] fn test_weird_formatting() { use crate:: in_fn_test:: * ; + //~^ wildcard_imports use crate:: fn_mod:: + //~^ wildcard_imports *; exported(); @@ -199,6 +215,7 @@ mod super_imports { mod should_be_replaced { use super::*; + //~^ wildcard_imports fn with_super() { let _ = foofoo(); @@ -237,6 +254,7 @@ mod super_imports { fn insidefoo() {} mod inner { use super::*; + //~^ wildcard_imports fn with_super() { let _ = insidefoo(); } @@ -245,6 +263,7 @@ mod super_imports { mod use_explicit_should_be_replaced { use crate::super_imports::*; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); @@ -254,6 +273,7 @@ mod super_imports { mod use_double_super_should_be_replaced { mod inner { use super::super::*; + //~^ wildcard_imports fn with_double_super() { let _ = foofoo(); @@ -263,6 +283,7 @@ mod super_imports { mod use_super_explicit_should_be_replaced { use super::super::super_imports::*; + //~^ wildcard_imports fn with_super_explicit() { let _ = foofoo(); @@ -271,6 +292,7 @@ mod super_imports { mod attestation_should_be_replaced { use super::*; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); diff --git a/tests/ui/wildcard_imports.stderr b/tests/ui/wildcard_imports.stderr index 8e88f216394d..f774126102bc 100644 --- a/tests/ui/wildcard_imports.stderr +++ b/tests/ui/wildcard_imports.stderr @@ -8,129 +8,130 @@ LL | use crate::fn_mod::*; = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:16:5 + --> tests/ui/wildcard_imports.rs:17:5 | LL | use crate::mod_mod::*; | ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:17:5 + --> tests/ui/wildcard_imports.rs:19:5 | LL | use crate::multi_fn_mod::*; | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:19:5 + --> tests/ui/wildcard_imports.rs:22:5 | LL | use crate::struct_mod::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:23:5 + --> tests/ui/wildcard_imports.rs:27:5 | LL | use wildcard_imports_helper::inner::inner_for_self_import::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:24:5 + --> tests/ui/wildcard_imports.rs:29:5 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:94:13 + --> tests/ui/wildcard_imports.rs:100:13 | LL | use self::exports_underscore_ish::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `self::exports_underscore_ish::{_Deref, dummy}` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:125:13 + --> tests/ui/wildcard_imports.rs:132:13 | LL | use crate::fn_mod::*; | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:131:75 + --> tests/ui/wildcard_imports.rs:139:75 | LL | use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; | ^ help: try: `inner_extern_foo` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:132:13 + --> tests/ui/wildcard_imports.rs:141:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:144:20 + --> tests/ui/wildcard_imports.rs:154:20 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^ help: try: `inner::inner_foo` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:144:30 + --> tests/ui/wildcard_imports.rs:154:30 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^^ help: try: `inner2::inner_bar` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:151:13 + --> tests/ui/wildcard_imports.rs:163:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:180:9 + --> tests/ui/wildcard_imports.rs:193:9 | LL | use crate::in_fn_test::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:189:9 + --> tests/ui/wildcard_imports.rs:203:9 | LL | use crate:: in_fn_test:: * ; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:190:9 + --> tests/ui/wildcard_imports.rs:205:9 | LL | use crate:: fn_mod:: | _________^ +LL | | LL | | *; | |_________^ help: try: `crate:: fn_mod::foo` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:201:13 + --> tests/ui/wildcard_imports.rs:217:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:239:17 + --> tests/ui/wildcard_imports.rs:256:17 | LL | use super::*; | ^^^^^^^^ help: try: `super::insidefoo` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:247:13 + --> tests/ui/wildcard_imports.rs:265:13 | LL | use crate::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:256:17 + --> tests/ui/wildcard_imports.rs:275:17 | LL | use super::super::*; | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:265:13 + --> tests/ui/wildcard_imports.rs:285:13 | LL | use super::super::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports.rs:273:13 + --> tests/ui/wildcard_imports.rs:294:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` diff --git a/tests/ui/wildcard_imports_2021.edition2018.fixed b/tests/ui/wildcard_imports_2021.edition2018.fixed index 197dd3b94df0..a3d1aebba8af 100644 --- a/tests/ui/wildcard_imports_2021.edition2018.fixed +++ b/tests/ui/wildcard_imports_2021.edition2018.fixed @@ -11,14 +11,20 @@ extern crate wildcard_imports_helper; use crate::fn_mod::foo; +//~^ wildcard_imports use crate::mod_mod::inner_mod; +//~^ wildcard_imports use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}; +//~^ wildcard_imports use crate::struct_mod::{A, inner_struct_mod}; +//~^ wildcard_imports #[allow(unused_imports)] use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar; +//~^ wildcard_imports use wildcard_imports_helper::prelude::v1::*; use wildcard_imports_helper::{ExternA, extern_foo}; +//~^ wildcard_imports use std::io::prelude::*; @@ -87,6 +93,7 @@ mod underscore_mod { fn does_lint() { use exports_underscore_ish::{_Deref, dummy}; + //~^ wildcard_imports let _ = (&0).deref(); dummy(); } @@ -117,13 +124,16 @@ mod in_fn_test { fn test_intern() { use crate::fn_mod::foo; + //~^ wildcard_imports foo(); } fn test_extern() { use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo}; + //~^ wildcard_imports use wildcard_imports_helper::{ExternA, extern_foo}; + //~^ wildcard_imports inner_for_self_import::inner_extern_foo(); inner_extern_foo(); @@ -136,6 +146,8 @@ mod in_fn_test { fn test_inner_nested() { #[rustfmt::skip] use self::{inner::inner_foo, inner2::inner_bar}; + //~^ wildcard_imports + //~| wildcard_imports inner_foo(); inner_bar(); @@ -143,6 +155,7 @@ mod in_fn_test { fn test_extern_reexported() { use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}; + //~^ wildcard_imports extern_exported(); let _ = ExternExportedStruct; @@ -172,6 +185,7 @@ mod in_fn_test { fn test_reexported() { use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}; + //~^ wildcard_imports exported(); let _ = ExportedStruct; @@ -181,6 +195,7 @@ fn test_reexported() { #[rustfmt::skip] fn test_weird_formatting() { use crate:: in_fn_test::exported; + //~^ wildcard_imports use crate:: fn_mod::foo; exported(); @@ -192,6 +207,7 @@ mod super_imports { mod should_be_replaced { use super::foofoo; + //~^ wildcard_imports fn with_super() { let _ = foofoo(); @@ -230,6 +246,7 @@ mod super_imports { fn insidefoo() {} mod inner { use super::insidefoo; + //~^ wildcard_imports fn with_super() { let _ = insidefoo(); } @@ -238,6 +255,7 @@ mod super_imports { mod use_explicit_should_be_replaced { use crate::super_imports::foofoo; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); @@ -247,6 +265,7 @@ mod super_imports { mod use_double_super_should_be_replaced { mod inner { use super::super::foofoo; + //~^ wildcard_imports fn with_double_super() { let _ = foofoo(); @@ -256,6 +275,7 @@ mod super_imports { mod use_super_explicit_should_be_replaced { use super::super::super_imports::foofoo; + //~^ wildcard_imports fn with_super_explicit() { let _ = foofoo(); @@ -264,6 +284,7 @@ mod super_imports { mod attestation_should_be_replaced { use super::foofoo; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); diff --git a/tests/ui/wildcard_imports_2021.edition2018.stderr b/tests/ui/wildcard_imports_2021.edition2018.stderr index 66adacd95dcc..a1b557f39f0d 100644 --- a/tests/ui/wildcard_imports_2021.edition2018.stderr +++ b/tests/ui/wildcard_imports_2021.edition2018.stderr @@ -8,129 +8,130 @@ LL | use crate::fn_mod::*; = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:14:5 + --> tests/ui/wildcard_imports_2021.rs:15:5 | LL | use crate::mod_mod::*; | ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:15:5 + --> tests/ui/wildcard_imports_2021.rs:17:5 | LL | use crate::multi_fn_mod::*; | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:16:5 + --> tests/ui/wildcard_imports_2021.rs:19:5 | LL | use crate::struct_mod::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:19:5 + --> tests/ui/wildcard_imports_2021.rs:23:5 | LL | use wildcard_imports_helper::inner::inner_for_self_import::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:21:5 + --> tests/ui/wildcard_imports_2021.rs:26:5 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:89:13 + --> tests/ui/wildcard_imports_2021.rs:95:13 | LL | use exports_underscore_ish::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `exports_underscore_ish::{_Deref, dummy}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:119:13 + --> tests/ui/wildcard_imports_2021.rs:126:13 | LL | use crate::fn_mod::*; | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:125:75 + --> tests/ui/wildcard_imports_2021.rs:133:75 | LL | use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; | ^ help: try: `inner_extern_foo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:126:13 + --> tests/ui/wildcard_imports_2021.rs:135:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:138:20 + --> tests/ui/wildcard_imports_2021.rs:148:20 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^ help: try: `inner::inner_foo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:138:30 + --> tests/ui/wildcard_imports_2021.rs:148:30 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^^ help: try: `inner2::inner_bar` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:145:13 + --> tests/ui/wildcard_imports_2021.rs:157:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:174:9 + --> tests/ui/wildcard_imports_2021.rs:187:9 | LL | use crate::in_fn_test::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:183:9 + --> tests/ui/wildcard_imports_2021.rs:197:9 | LL | use crate:: in_fn_test:: * ; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:184:9 + --> tests/ui/wildcard_imports_2021.rs:199:9 | LL | use crate:: fn_mod:: | _________^ +LL | | LL | | *; | |_________^ help: try: `crate:: fn_mod::foo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:195:13 + --> tests/ui/wildcard_imports_2021.rs:211:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:233:17 + --> tests/ui/wildcard_imports_2021.rs:250:17 | LL | use super::*; | ^^^^^^^^ help: try: `super::insidefoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:241:13 + --> tests/ui/wildcard_imports_2021.rs:259:13 | LL | use crate::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:250:17 + --> tests/ui/wildcard_imports_2021.rs:269:17 | LL | use super::super::*; | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:259:13 + --> tests/ui/wildcard_imports_2021.rs:279:13 | LL | use super::super::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:267:13 + --> tests/ui/wildcard_imports_2021.rs:288:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` diff --git a/tests/ui/wildcard_imports_2021.edition2021.fixed b/tests/ui/wildcard_imports_2021.edition2021.fixed index 197dd3b94df0..a3d1aebba8af 100644 --- a/tests/ui/wildcard_imports_2021.edition2021.fixed +++ b/tests/ui/wildcard_imports_2021.edition2021.fixed @@ -11,14 +11,20 @@ extern crate wildcard_imports_helper; use crate::fn_mod::foo; +//~^ wildcard_imports use crate::mod_mod::inner_mod; +//~^ wildcard_imports use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}; +//~^ wildcard_imports use crate::struct_mod::{A, inner_struct_mod}; +//~^ wildcard_imports #[allow(unused_imports)] use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar; +//~^ wildcard_imports use wildcard_imports_helper::prelude::v1::*; use wildcard_imports_helper::{ExternA, extern_foo}; +//~^ wildcard_imports use std::io::prelude::*; @@ -87,6 +93,7 @@ mod underscore_mod { fn does_lint() { use exports_underscore_ish::{_Deref, dummy}; + //~^ wildcard_imports let _ = (&0).deref(); dummy(); } @@ -117,13 +124,16 @@ mod in_fn_test { fn test_intern() { use crate::fn_mod::foo; + //~^ wildcard_imports foo(); } fn test_extern() { use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo}; + //~^ wildcard_imports use wildcard_imports_helper::{ExternA, extern_foo}; + //~^ wildcard_imports inner_for_self_import::inner_extern_foo(); inner_extern_foo(); @@ -136,6 +146,8 @@ mod in_fn_test { fn test_inner_nested() { #[rustfmt::skip] use self::{inner::inner_foo, inner2::inner_bar}; + //~^ wildcard_imports + //~| wildcard_imports inner_foo(); inner_bar(); @@ -143,6 +155,7 @@ mod in_fn_test { fn test_extern_reexported() { use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}; + //~^ wildcard_imports extern_exported(); let _ = ExternExportedStruct; @@ -172,6 +185,7 @@ mod in_fn_test { fn test_reexported() { use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}; + //~^ wildcard_imports exported(); let _ = ExportedStruct; @@ -181,6 +195,7 @@ fn test_reexported() { #[rustfmt::skip] fn test_weird_formatting() { use crate:: in_fn_test::exported; + //~^ wildcard_imports use crate:: fn_mod::foo; exported(); @@ -192,6 +207,7 @@ mod super_imports { mod should_be_replaced { use super::foofoo; + //~^ wildcard_imports fn with_super() { let _ = foofoo(); @@ -230,6 +246,7 @@ mod super_imports { fn insidefoo() {} mod inner { use super::insidefoo; + //~^ wildcard_imports fn with_super() { let _ = insidefoo(); } @@ -238,6 +255,7 @@ mod super_imports { mod use_explicit_should_be_replaced { use crate::super_imports::foofoo; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); @@ -247,6 +265,7 @@ mod super_imports { mod use_double_super_should_be_replaced { mod inner { use super::super::foofoo; + //~^ wildcard_imports fn with_double_super() { let _ = foofoo(); @@ -256,6 +275,7 @@ mod super_imports { mod use_super_explicit_should_be_replaced { use super::super::super_imports::foofoo; + //~^ wildcard_imports fn with_super_explicit() { let _ = foofoo(); @@ -264,6 +284,7 @@ mod super_imports { mod attestation_should_be_replaced { use super::foofoo; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); diff --git a/tests/ui/wildcard_imports_2021.edition2021.stderr b/tests/ui/wildcard_imports_2021.edition2021.stderr index 66adacd95dcc..a1b557f39f0d 100644 --- a/tests/ui/wildcard_imports_2021.edition2021.stderr +++ b/tests/ui/wildcard_imports_2021.edition2021.stderr @@ -8,129 +8,130 @@ LL | use crate::fn_mod::*; = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:14:5 + --> tests/ui/wildcard_imports_2021.rs:15:5 | LL | use crate::mod_mod::*; | ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:15:5 + --> tests/ui/wildcard_imports_2021.rs:17:5 | LL | use crate::multi_fn_mod::*; | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:16:5 + --> tests/ui/wildcard_imports_2021.rs:19:5 | LL | use crate::struct_mod::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:19:5 + --> tests/ui/wildcard_imports_2021.rs:23:5 | LL | use wildcard_imports_helper::inner::inner_for_self_import::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:21:5 + --> tests/ui/wildcard_imports_2021.rs:26:5 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:89:13 + --> tests/ui/wildcard_imports_2021.rs:95:13 | LL | use exports_underscore_ish::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `exports_underscore_ish::{_Deref, dummy}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:119:13 + --> tests/ui/wildcard_imports_2021.rs:126:13 | LL | use crate::fn_mod::*; | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:125:75 + --> tests/ui/wildcard_imports_2021.rs:133:75 | LL | use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; | ^ help: try: `inner_extern_foo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:126:13 + --> tests/ui/wildcard_imports_2021.rs:135:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:138:20 + --> tests/ui/wildcard_imports_2021.rs:148:20 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^ help: try: `inner::inner_foo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:138:30 + --> tests/ui/wildcard_imports_2021.rs:148:30 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^^ help: try: `inner2::inner_bar` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:145:13 + --> tests/ui/wildcard_imports_2021.rs:157:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:174:9 + --> tests/ui/wildcard_imports_2021.rs:187:9 | LL | use crate::in_fn_test::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:183:9 + --> tests/ui/wildcard_imports_2021.rs:197:9 | LL | use crate:: in_fn_test:: * ; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:184:9 + --> tests/ui/wildcard_imports_2021.rs:199:9 | LL | use crate:: fn_mod:: | _________^ +LL | | LL | | *; | |_________^ help: try: `crate:: fn_mod::foo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:195:13 + --> tests/ui/wildcard_imports_2021.rs:211:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:233:17 + --> tests/ui/wildcard_imports_2021.rs:250:17 | LL | use super::*; | ^^^^^^^^ help: try: `super::insidefoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:241:13 + --> tests/ui/wildcard_imports_2021.rs:259:13 | LL | use crate::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:250:17 + --> tests/ui/wildcard_imports_2021.rs:269:17 | LL | use super::super::*; | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:259:13 + --> tests/ui/wildcard_imports_2021.rs:279:13 | LL | use super::super::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` error: usage of wildcard import - --> tests/ui/wildcard_imports_2021.rs:267:13 + --> tests/ui/wildcard_imports_2021.rs:288:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` diff --git a/tests/ui/wildcard_imports_2021.rs b/tests/ui/wildcard_imports_2021.rs index 606ff080e774..8075c15bc14f 100644 --- a/tests/ui/wildcard_imports_2021.rs +++ b/tests/ui/wildcard_imports_2021.rs @@ -11,14 +11,20 @@ extern crate wildcard_imports_helper; use crate::fn_mod::*; +//~^ wildcard_imports use crate::mod_mod::*; +//~^ wildcard_imports use crate::multi_fn_mod::*; +//~^ wildcard_imports use crate::struct_mod::*; +//~^ wildcard_imports #[allow(unused_imports)] use wildcard_imports_helper::inner::inner_for_self_import::*; +//~^ wildcard_imports use wildcard_imports_helper::prelude::v1::*; use wildcard_imports_helper::*; +//~^ wildcard_imports use std::io::prelude::*; @@ -87,6 +93,7 @@ mod underscore_mod { fn does_lint() { use exports_underscore_ish::*; + //~^ wildcard_imports let _ = (&0).deref(); dummy(); } @@ -117,13 +124,16 @@ mod in_fn_test { fn test_intern() { use crate::fn_mod::*; + //~^ wildcard_imports foo(); } fn test_extern() { use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; + //~^ wildcard_imports use wildcard_imports_helper::*; + //~^ wildcard_imports inner_for_self_import::inner_extern_foo(); inner_extern_foo(); @@ -136,6 +146,8 @@ mod in_fn_test { fn test_inner_nested() { #[rustfmt::skip] use self::{inner::*, inner2::*}; + //~^ wildcard_imports + //~| wildcard_imports inner_foo(); inner_bar(); @@ -143,6 +155,7 @@ mod in_fn_test { fn test_extern_reexported() { use wildcard_imports_helper::*; + //~^ wildcard_imports extern_exported(); let _ = ExternExportedStruct; @@ -172,6 +185,7 @@ mod in_fn_test { fn test_reexported() { use crate::in_fn_test::*; + //~^ wildcard_imports exported(); let _ = ExportedStruct; @@ -181,7 +195,9 @@ fn test_reexported() { #[rustfmt::skip] fn test_weird_formatting() { use crate:: in_fn_test:: * ; + //~^ wildcard_imports use crate:: fn_mod:: + //~^ wildcard_imports *; exported(); @@ -193,6 +209,7 @@ mod super_imports { mod should_be_replaced { use super::*; + //~^ wildcard_imports fn with_super() { let _ = foofoo(); @@ -231,6 +248,7 @@ mod super_imports { fn insidefoo() {} mod inner { use super::*; + //~^ wildcard_imports fn with_super() { let _ = insidefoo(); } @@ -239,6 +257,7 @@ mod super_imports { mod use_explicit_should_be_replaced { use crate::super_imports::*; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); @@ -248,6 +267,7 @@ mod super_imports { mod use_double_super_should_be_replaced { mod inner { use super::super::*; + //~^ wildcard_imports fn with_double_super() { let _ = foofoo(); @@ -257,6 +277,7 @@ mod super_imports { mod use_super_explicit_should_be_replaced { use super::super::super_imports::*; + //~^ wildcard_imports fn with_super_explicit() { let _ = foofoo(); @@ -265,6 +286,7 @@ mod super_imports { mod attestation_should_be_replaced { use super::*; + //~^ wildcard_imports fn with_explicit() { let _ = foofoo(); diff --git a/tests/ui/wildcard_imports_cfgtest.rs b/tests/ui/wildcard_imports_cfgtest.rs index 203c4e15b50c..c41458d5bb0a 100644 --- a/tests/ui/wildcard_imports_cfgtest.rs +++ b/tests/ui/wildcard_imports_cfgtest.rs @@ -1,3 +1,4 @@ +//@check-pass //@compile-flags: --test #![warn(clippy::wildcard_imports)] diff --git a/tests/ui/write_literal.fixed b/tests/ui/write_literal.fixed index f1def776e1bc..b82d77aaa418 100644 --- a/tests/ui/write_literal.fixed +++ b/tests/ui/write_literal.fixed @@ -29,46 +29,60 @@ fn main() { // these should throw warnings write!(v, "Hello world"); - //~^ ERROR: literal with an empty format string - //~| NOTE: `-D clippy::write-literal` implied by `-D warnings` + //~^ write_literal + + writeln!(v, "Hello {} world", world); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "Hello world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "a literal {:.4}", 5); - //~^ ERROR: literal with an empty format string + //~^ write_literal + // positional args don't change the fact // that we're using a literal -- this should // throw a warning writeln!(v, "hello world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "world hello"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + // named args shouldn't change anything either writeln!(v, "hello world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "world hello"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + // #10128 writeln!(v, "hello {0} world", 2); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "world {0} hello", 2); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "hello {0} {1}, {bar}", 2, 3, bar = 4); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4); - //~^ ERROR: literal with an empty format string + //~^ write_literal + } fn issue_13959() { let mut v = Vec::new(); writeln!(v, "\""); + //~^ write_literal writeln!( v, " + //~^ write_literal foo \\ \\\\ diff --git a/tests/ui/write_literal.rs b/tests/ui/write_literal.rs index 1b7df91b47e1..e9f5990d7ec6 100644 --- a/tests/ui/write_literal.rs +++ b/tests/ui/write_literal.rs @@ -29,47 +29,61 @@ fn main() { // these should throw warnings write!(v, "Hello {}", "world"); - //~^ ERROR: literal with an empty format string - //~| NOTE: `-D clippy::write-literal` implied by `-D warnings` + //~^ write_literal + + writeln!(v, "Hello {} {}", world, "world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "Hello {}", "world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{} {:.4}", "a literal", 5); - //~^ ERROR: literal with an empty format string + //~^ write_literal + // positional args don't change the fact // that we're using a literal -- this should // throw a warning writeln!(v, "{0} {1}", "hello", "world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{1} {0}", "hello", "world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + // named args shouldn't change anything either writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + // #10128 writeln!(v, "{0} {1} {2}", "hello", 2, "world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{2} {1} {0}", "hello", 2, "world"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{0} {1} {2}, {bar}", "hello", 2, 3, bar = 4); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4); - //~^ ERROR: literal with an empty format string + //~^ write_literal + } fn issue_13959() { let mut v = Vec::new(); writeln!(v, "{}", r#"""#); + //~^ write_literal writeln!( v, "{}", r#" + //~^ write_literal foo \ \\ diff --git a/tests/ui/write_literal.stderr b/tests/ui/write_literal.stderr index 35c93d567cd3..834162473c58 100644 --- a/tests/ui/write_literal.stderr +++ b/tests/ui/write_literal.stderr @@ -13,7 +13,7 @@ LL + write!(v, "Hello world"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:34:39 + --> tests/ui/write_literal.rs:35:39 | LL | writeln!(v, "Hello {} {}", world, "world"); | ^^^^^^^ @@ -25,7 +25,7 @@ LL + writeln!(v, "Hello {} world", world); | error: literal with an empty format string - --> tests/ui/write_literal.rs:36:29 + --> tests/ui/write_literal.rs:38:29 | LL | writeln!(v, "Hello {}", "world"); | ^^^^^^^ @@ -37,7 +37,7 @@ LL + writeln!(v, "Hello world"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:38:29 + --> tests/ui/write_literal.rs:41:29 | LL | writeln!(v, "{} {:.4}", "a literal", 5); | ^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + writeln!(v, "a literal {:.4}", 5); | error: literal with an empty format string - --> tests/ui/write_literal.rs:44:28 + --> tests/ui/write_literal.rs:48:28 | LL | writeln!(v, "{0} {1}", "hello", "world"); | ^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + writeln!(v, "hello world"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:46:28 + --> tests/ui/write_literal.rs:51:28 | LL | writeln!(v, "{1} {0}", "hello", "world"); | ^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + writeln!(v, "world hello"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:50:38 + --> tests/ui/write_literal.rs:56:38 | LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + writeln!(v, "hello world"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:52:38 + --> tests/ui/write_literal.rs:59:38 | LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL + writeln!(v, "world hello"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:56:32 + --> tests/ui/write_literal.rs:64:32 | LL | writeln!(v, "{0} {1} {2}", "hello", 2, "world"); | ^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL + writeln!(v, "hello {0} world", 2); | error: literal with an empty format string - --> tests/ui/write_literal.rs:58:32 + --> tests/ui/write_literal.rs:67:32 | LL | writeln!(v, "{2} {1} {0}", "hello", 2, "world"); | ^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL + writeln!(v, "world {0} hello", 2); | error: literal with an empty format string - --> tests/ui/write_literal.rs:60:39 + --> tests/ui/write_literal.rs:70:39 | LL | writeln!(v, "{0} {1} {2}, {bar}", "hello", 2, 3, bar = 4); | ^^^^^^^ @@ -133,7 +133,7 @@ LL + writeln!(v, "hello {0} {1}, {bar}", 2, 3, bar = 4); | error: literal with an empty format string - --> tests/ui/write_literal.rs:62:41 + --> tests/ui/write_literal.rs:73:41 | LL | writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL + writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4); | error: literal with an empty format string - --> tests/ui/write_literal.rs:68:23 + --> tests/ui/write_literal.rs:80:23 | LL | writeln!(v, "{}", r#"""#); | ^^^^^^ @@ -157,12 +157,12 @@ LL + writeln!(v, "\""); | error: literal with an empty format string - --> tests/ui/write_literal.rs:72:9 + --> tests/ui/write_literal.rs:85:9 | LL | / r#" +LL | | LL | | foo LL | | \ -LL | | \\ ... | LL | | bar LL | | "# @@ -171,6 +171,7 @@ LL | | "# help: try | LL ~ " +LL + LL + foo LL + \\ LL + \\\\ diff --git a/tests/ui/write_literal_2.rs b/tests/ui/write_literal_2.rs index b2ed552d46bc..2edd50c43403 100644 --- a/tests/ui/write_literal_2.rs +++ b/tests/ui/write_literal_2.rs @@ -8,44 +8,58 @@ fn main() { let mut v = Vec::new(); writeln!(v, "{}", "{hello}"); - //~^ ERROR: literal with an empty format string - //~| NOTE: `-D clippy::write-literal` implied by `-D warnings` + //~^ write_literal + + writeln!(v, r"{}", r"{hello}"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{}", '\''); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{}", '"'); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, r"{}", '"'); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, r"{}", '\''); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!( v, "some {}", "hello \ + //~^ write_literal world!", - //~^^ ERROR: literal with an empty format string + ); writeln!( v, "some {}\ {} \\ {}", "1", "2", "3", + //~^ write_literal ); writeln!(v, "{}", "\\"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, r"{}", "\\"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, r#"{}"#, "\\"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{}", r"\"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + writeln!(v, "{}", "\r"); - //~^ ERROR: literal with an empty format string + //~^ write_literal + // hard mode writeln!(v, r#"{}{}"#, '#', '"'); - //~^ ERROR: literal with an empty format string + //~^ write_literal + // should not lint writeln!(v, r"{}", "\r"); } diff --git a/tests/ui/write_literal_2.stderr b/tests/ui/write_literal_2.stderr index 9fba3ce548a0..f3f86586ef85 100644 --- a/tests/ui/write_literal_2.stderr +++ b/tests/ui/write_literal_2.stderr @@ -13,7 +13,7 @@ LL + writeln!(v, "{{hello}}"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:13:24 + --> tests/ui/write_literal_2.rs:14:24 | LL | writeln!(v, r"{}", r"{hello}"); | ^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + writeln!(v, r"{{hello}}"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:15:23 + --> tests/ui/write_literal_2.rs:17:23 | LL | writeln!(v, "{}", '\''); | ^^^^ @@ -37,7 +37,7 @@ LL + writeln!(v, "'"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:17:23 + --> tests/ui/write_literal_2.rs:20:23 | LL | writeln!(v, "{}", '"'); | ^^^ @@ -49,13 +49,13 @@ LL + writeln!(v, "\""); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:19:24 + --> tests/ui/write_literal_2.rs:23:24 | LL | writeln!(v, r"{}", '"'); | ^^^ error: literal with an empty format string - --> tests/ui/write_literal_2.rs:21:24 + --> tests/ui/write_literal_2.rs:26:24 | LL | writeln!(v, r"{}", '\''); | ^^^^ @@ -67,20 +67,22 @@ LL + writeln!(v, r"'"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:26:9 + --> tests/ui/write_literal_2.rs:32:9 | LL | / "hello \ +LL | | LL | | world!", | |_______________^ | help: try | LL ~ "some hello \ +LL + LL ~ world!", | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:34:9 + --> tests/ui/write_literal_2.rs:41:9 | LL | "1", "2", "3", | ^^^^^^^^^^^^^ @@ -92,7 +94,7 @@ LL ~ 2 \\ 3", | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:36:23 + --> tests/ui/write_literal_2.rs:44:23 | LL | writeln!(v, "{}", "\\"); | ^^^^ @@ -104,7 +106,7 @@ LL + writeln!(v, "\\"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:38:24 + --> tests/ui/write_literal_2.rs:47:24 | LL | writeln!(v, r"{}", "\\"); | ^^^^ @@ -116,7 +118,7 @@ LL + writeln!(v, r"\"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:40:26 + --> tests/ui/write_literal_2.rs:50:26 | LL | writeln!(v, r#"{}"#, "\\"); | ^^^^ @@ -128,7 +130,7 @@ LL + writeln!(v, r#"\"#); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:42:23 + --> tests/ui/write_literal_2.rs:53:23 | LL | writeln!(v, "{}", r"\"); | ^^^^ @@ -140,7 +142,7 @@ LL + writeln!(v, "\\"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:44:23 + --> tests/ui/write_literal_2.rs:56:23 | LL | writeln!(v, "{}", "\r"); | ^^^^ @@ -152,7 +154,7 @@ LL + writeln!(v, "\r"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:47:28 + --> tests/ui/write_literal_2.rs:60:28 | LL | writeln!(v, r#"{}{}"#, '#', '"'); | ^^^^^^^^ diff --git a/tests/ui/write_with_newline.fixed b/tests/ui/write_with_newline.fixed index 82afff5c81f5..bd2285d16bcf 100644 --- a/tests/ui/write_with_newline.fixed +++ b/tests/ui/write_with_newline.fixed @@ -10,16 +10,21 @@ fn main() { // These should fail writeln!(v, "Hello"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline - //~| NOTE: `-D clippy::write-with-newline` implied by `-D warnings` + //~^ write_with_newline + + writeln!(v, "Hello {}", "world"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + writeln!(v, "Hello {} {}", "world", "#2"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + writeln!(v, "{}", 1265); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + writeln!(v); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + // These should be fine write!(v, ""); @@ -42,7 +47,8 @@ fn main() { // #3514 write!(v, "\\n"); writeln!(v, "\\"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + write!(v, "\\\\n"); // Raw strings @@ -51,11 +57,13 @@ fn main() { // Literal newlines should also fail writeln!( - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + v ); writeln!( - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + v ); @@ -63,7 +71,8 @@ fn main() { write!(v, "\r\n"); write!(v, "foo\r\n"); writeln!(v, "\\r"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + write!(v, "foo\rbar\n"); // Ignore expanded format strings diff --git a/tests/ui/write_with_newline.rs b/tests/ui/write_with_newline.rs index 96e4bf0fbc4b..b70349ae82e6 100644 --- a/tests/ui/write_with_newline.rs +++ b/tests/ui/write_with_newline.rs @@ -10,16 +10,21 @@ fn main() { // These should fail write!(v, "Hello\n"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline - //~| NOTE: `-D clippy::write-with-newline` implied by `-D warnings` + //~^ write_with_newline + + write!(v, "Hello {}\n", "world"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + write!(v, "Hello {} {}\n", "world", "#2"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + write!(v, "{}\n", 1265); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + write!(v, "\n"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + // These should be fine write!(v, ""); @@ -42,7 +47,8 @@ fn main() { // #3514 write!(v, "\\n"); write!(v, "\\\n"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + write!(v, "\\\\n"); // Raw strings @@ -51,13 +57,15 @@ fn main() { // Literal newlines should also fail write!( - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + v, " " ); write!( - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + v, r" " @@ -67,7 +75,8 @@ fn main() { write!(v, "\r\n"); write!(v, "foo\r\n"); write!(v, "\\r\n"); - //~^ ERROR: using `write!()` with a format string that ends in a single newline + //~^ write_with_newline + write!(v, "foo\rbar\n"); // Ignore expanded format strings diff --git a/tests/ui/write_with_newline.stderr b/tests/ui/write_with_newline.stderr index 7eb741107a7b..9ab17cfdf3af 100644 --- a/tests/ui/write_with_newline.stderr +++ b/tests/ui/write_with_newline.stderr @@ -13,7 +13,7 @@ LL + writeln!(v, "Hello"); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:15:5 + --> tests/ui/write_with_newline.rs:16:5 | LL | write!(v, "Hello {}\n", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + writeln!(v, "Hello {}", "world"); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:17:5 + --> tests/ui/write_with_newline.rs:19:5 | LL | write!(v, "Hello {} {}\n", "world", "#2"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + writeln!(v, "Hello {} {}", "world", "#2"); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:19:5 + --> tests/ui/write_with_newline.rs:22:5 | LL | write!(v, "{}\n", 1265); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + writeln!(v, "{}", 1265); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:21:5 + --> tests/ui/write_with_newline.rs:25:5 | LL | write!(v, "\n"); | ^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + writeln!(v); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:44:5 + --> tests/ui/write_with_newline.rs:49:5 | LL | write!(v, "\\\n"); | ^^^^^^^^^^^^^^^^^ @@ -73,10 +73,11 @@ LL + writeln!(v, "\\"); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:53:5 + --> tests/ui/write_with_newline.rs:59:5 | LL | / write!( LL | | +LL | | LL | | v, LL | | " LL | | " @@ -87,14 +88,16 @@ help: use `writeln!` instead | LL ~ writeln!( LL | +LL | LL ~ v | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:59:5 + --> tests/ui/write_with_newline.rs:66:5 | LL | / write!( LL | | +LL | | LL | | v, LL | | r" LL | | " @@ -105,11 +108,12 @@ help: use `writeln!` instead | LL ~ writeln!( LL | +LL | LL ~ v | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:69:5 + --> tests/ui/write_with_newline.rs:77:5 | LL | write!(v, "\\r\n"); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/writeln_empty_string.fixed b/tests/ui/writeln_empty_string.fixed index f6a7481f6422..5cb702b10f2d 100644 --- a/tests/ui/writeln_empty_string.fixed +++ b/tests/ui/writeln_empty_string.fixed @@ -7,9 +7,11 @@ fn main() { // These should fail writeln!(v); + //~^ writeln_empty_string let mut suggestion = Vec::new(); writeln!(suggestion); + //~^ writeln_empty_string // These should be fine writeln!(v); diff --git a/tests/ui/writeln_empty_string.rs b/tests/ui/writeln_empty_string.rs index 0297dba8c45d..e6478264a578 100644 --- a/tests/ui/writeln_empty_string.rs +++ b/tests/ui/writeln_empty_string.rs @@ -7,9 +7,11 @@ fn main() { // These should fail writeln!(v, ""); + //~^ writeln_empty_string let mut suggestion = Vec::new(); writeln!(suggestion, ""); + //~^ writeln_empty_string // These should be fine writeln!(v); diff --git a/tests/ui/writeln_empty_string.stderr b/tests/ui/writeln_empty_string.stderr index 20ece6a41926..43e76309ba64 100644 --- a/tests/ui/writeln_empty_string.stderr +++ b/tests/ui/writeln_empty_string.stderr @@ -10,7 +10,7 @@ LL | writeln!(v, ""); = help: to override `-D warnings` add `#[allow(clippy::writeln_empty_string)]` error: empty string literal in `writeln!` - --> tests/ui/writeln_empty_string.rs:12:5 + --> tests/ui/writeln_empty_string.rs:13:5 | LL | writeln!(suggestion, ""); | ^^^^^^^^^^^^^^^^^^^----^ diff --git a/tests/ui/wrong_self_convention.rs b/tests/ui/wrong_self_convention.rs index d7ed883b767c..42d600b67f8e 100644 --- a/tests/ui/wrong_self_convention.rs +++ b/tests/ui/wrong_self_convention.rs @@ -14,14 +14,16 @@ impl Foo { fn is_u32(&self) {} fn to_i32(self) {} fn from_i32(self) {} - //~^ ERROR: methods called `from_*` usually take no `self` + //~^ wrong_self_convention + pub fn as_i64(self) {} pub fn into_i64(self) {} pub fn is_i64(self) {} pub fn to_i64(self) {} pub fn from_i64(self) {} - //~^ ERROR: methods called `from_*` usually take no `self` + //~^ wrong_self_convention + // check whether the lint can be allowed at the function level #[allow(clippy::wrong_self_convention)] pub fn from_cake(self) {} @@ -34,30 +36,40 @@ struct Bar; impl Bar { fn as_i32(self) {} - //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mutabl + //~^ wrong_self_convention + fn as_u32(&self) {} fn into_i32(&self) {} - //~^ ERROR: methods called `into_*` usually take `self` by value + //~^ wrong_self_convention + fn into_u32(self) {} fn is_i32(self) {} - //~^ ERROR: methods called `is_*` usually take `self` by mutable reference or `self` b + //~^ wrong_self_convention + fn is_u32(&self) {} fn to_i32(self) {} - //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is not + //~^ wrong_self_convention + fn to_u32(&self) {} fn from_i32(self) {} - //~^ ERROR: methods called `from_*` usually take no `self` + //~^ wrong_self_convention + pub fn as_i64(self) {} - //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mutabl + //~^ wrong_self_convention + pub fn into_i64(&self) {} - //~^ ERROR: methods called `into_*` usually take `self` by value + //~^ wrong_self_convention + pub fn is_i64(self) {} - //~^ ERROR: methods called `is_*` usually take `self` by mutable reference or `self` b + //~^ wrong_self_convention + pub fn to_i64(self) {} - //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is not + //~^ wrong_self_convention + pub fn from_i64(self) {} - //~^ ERROR: methods called `from_*` usually take no `self` + //~^ wrong_self_convention + // test for false positives fn as_(self) {} @@ -103,19 +115,23 @@ mod issue4037 { mod issue6307 { trait T: Sized { fn as_i32(self) {} - //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mu + //~^ wrong_self_convention + fn as_u32(&self) {} fn into_i32(self) {} fn into_i32_ref(&self) {} - //~^ ERROR: methods called `into_*` usually take `self` by value + //~^ wrong_self_convention + fn into_u32(self) {} fn is_i32(self) {} - //~^ ERROR: methods called `is_*` usually take `self` by mutable reference or `sel + //~^ wrong_self_convention + fn is_u32(&self) {} fn to_i32(self) {} fn to_u32(&self) {} fn from_i32(self) {} - //~^ ERROR: methods called `from_*` usually take no `self` + //~^ wrong_self_convention + // check whether the lint can be allowed at the function level #[allow(clippy::wrong_self_convention)] fn from_cake(self) {} @@ -131,19 +147,23 @@ mod issue6307 { trait U { fn as_i32(self); - //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mu + //~^ wrong_self_convention + fn as_u32(&self); fn into_i32(self); fn into_i32_ref(&self); - //~^ ERROR: methods called `into_*` usually take `self` by value + //~^ wrong_self_convention + fn into_u32(self); fn is_i32(self); - //~^ ERROR: methods called `is_*` usually take `self` by mutable reference or `sel + //~^ wrong_self_convention + fn is_u32(&self); fn to_i32(self); fn to_u32(&self); fn from_i32(self); - //~^ ERROR: methods called `from_*` usually take no `self` + //~^ wrong_self_convention + // check whether the lint can be allowed at the function level #[allow(clippy::wrong_self_convention)] fn from_cake(self); @@ -162,14 +182,16 @@ mod issue6307 { fn as_u32(&self); fn into_i32(self); fn into_i32_ref(&self); - //~^ ERROR: methods called `into_*` usually take `self` by value + //~^ wrong_self_convention + fn into_u32(self); fn is_i32(self); fn is_u32(&self); fn to_i32(self); fn to_u32(&self); fn from_i32(self); - //~^ ERROR: methods called `from_*` usually take no `self` + //~^ wrong_self_convention + // check whether the lint can be allowed at the function level #[allow(clippy::wrong_self_convention)] fn from_cake(self); @@ -194,7 +216,8 @@ mod issue6727 { } // trigger lint fn to_u64_v2(&self) -> u64 { - //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is + //~^ wrong_self_convention + 1 } } @@ -204,7 +227,8 @@ mod issue6727 { impl FooNoCopy { // trigger lint fn to_u64(self) -> u64 { - //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is + //~^ wrong_self_convention + 2 } fn to_u64_v2(&self) -> u64 { diff --git a/tests/ui/wrong_self_convention.stderr b/tests/ui/wrong_self_convention.stderr index 5c286721c478..fe6d231578b1 100644 --- a/tests/ui/wrong_self_convention.stderr +++ b/tests/ui/wrong_self_convention.stderr @@ -9,7 +9,7 @@ LL | fn from_i32(self) {} = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]` error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:23:21 + --> tests/ui/wrong_self_convention.rs:24:21 | LL | pub fn from_i64(self) {} | ^^^^ @@ -17,7 +17,7 @@ LL | pub fn from_i64(self) {} = help: consider choosing a less ambiguous name error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/wrong_self_convention.rs:36:15 + --> tests/ui/wrong_self_convention.rs:38:15 | LL | fn as_i32(self) {} | ^^^^ @@ -25,7 +25,7 @@ LL | fn as_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:39:17 + --> tests/ui/wrong_self_convention.rs:42:17 | LL | fn into_i32(&self) {} | ^^^^^ @@ -33,7 +33,7 @@ LL | fn into_i32(&self) {} = help: consider choosing a less ambiguous name error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self` - --> tests/ui/wrong_self_convention.rs:42:15 + --> tests/ui/wrong_self_convention.rs:46:15 | LL | fn is_i32(self) {} | ^^^^ @@ -41,7 +41,7 @@ LL | fn is_i32(self) {} = help: consider choosing a less ambiguous name error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference - --> tests/ui/wrong_self_convention.rs:45:15 + --> tests/ui/wrong_self_convention.rs:50:15 | LL | fn to_i32(self) {} | ^^^^ @@ -49,7 +49,7 @@ LL | fn to_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:48:17 + --> tests/ui/wrong_self_convention.rs:54:17 | LL | fn from_i32(self) {} | ^^^^ @@ -57,7 +57,7 @@ LL | fn from_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/wrong_self_convention.rs:51:19 + --> tests/ui/wrong_self_convention.rs:58:19 | LL | pub fn as_i64(self) {} | ^^^^ @@ -65,7 +65,7 @@ LL | pub fn as_i64(self) {} = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:53:21 + --> tests/ui/wrong_self_convention.rs:61:21 | LL | pub fn into_i64(&self) {} | ^^^^^ @@ -73,7 +73,7 @@ LL | pub fn into_i64(&self) {} = help: consider choosing a less ambiguous name error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self` - --> tests/ui/wrong_self_convention.rs:55:19 + --> tests/ui/wrong_self_convention.rs:64:19 | LL | pub fn is_i64(self) {} | ^^^^ @@ -81,7 +81,7 @@ LL | pub fn is_i64(self) {} = help: consider choosing a less ambiguous name error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference - --> tests/ui/wrong_self_convention.rs:57:19 + --> tests/ui/wrong_self_convention.rs:67:19 | LL | pub fn to_i64(self) {} | ^^^^ @@ -89,7 +89,7 @@ LL | pub fn to_i64(self) {} = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:59:21 + --> tests/ui/wrong_self_convention.rs:70:21 | LL | pub fn from_i64(self) {} | ^^^^ @@ -97,7 +97,7 @@ LL | pub fn from_i64(self) {} = help: consider choosing a less ambiguous name error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/wrong_self_convention.rs:105:19 + --> tests/ui/wrong_self_convention.rs:117:19 | LL | fn as_i32(self) {} | ^^^^ @@ -105,7 +105,7 @@ LL | fn as_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:109:25 + --> tests/ui/wrong_self_convention.rs:122:25 | LL | fn into_i32_ref(&self) {} | ^^^^^ @@ -113,7 +113,7 @@ LL | fn into_i32_ref(&self) {} = help: consider choosing a less ambiguous name error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self` - --> tests/ui/wrong_self_convention.rs:112:19 + --> tests/ui/wrong_self_convention.rs:126:19 | LL | fn is_i32(self) {} | ^^^^ @@ -121,7 +121,7 @@ LL | fn is_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:117:21 + --> tests/ui/wrong_self_convention.rs:132:21 | LL | fn from_i32(self) {} | ^^^^ @@ -129,7 +129,7 @@ LL | fn from_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/wrong_self_convention.rs:133:19 + --> tests/ui/wrong_self_convention.rs:149:19 | LL | fn as_i32(self); | ^^^^ @@ -137,7 +137,7 @@ LL | fn as_i32(self); = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:137:25 + --> tests/ui/wrong_self_convention.rs:154:25 | LL | fn into_i32_ref(&self); | ^^^^^ @@ -145,7 +145,7 @@ LL | fn into_i32_ref(&self); = help: consider choosing a less ambiguous name error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self` - --> tests/ui/wrong_self_convention.rs:140:19 + --> tests/ui/wrong_self_convention.rs:158:19 | LL | fn is_i32(self); | ^^^^ @@ -153,7 +153,7 @@ LL | fn is_i32(self); = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:145:21 + --> tests/ui/wrong_self_convention.rs:164:21 | LL | fn from_i32(self); | ^^^^ @@ -161,7 +161,7 @@ LL | fn from_i32(self); = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:164:25 + --> tests/ui/wrong_self_convention.rs:184:25 | LL | fn into_i32_ref(&self); | ^^^^^ @@ -169,7 +169,7 @@ LL | fn into_i32_ref(&self); = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:171:21 + --> tests/ui/wrong_self_convention.rs:192:21 | LL | fn from_i32(self); | ^^^^ @@ -177,7 +177,7 @@ LL | fn from_i32(self); = help: consider choosing a less ambiguous name error: methods with the following characteristics: (`to_*` and `self` type is `Copy`) usually take `self` by value - --> tests/ui/wrong_self_convention.rs:196:22 + --> tests/ui/wrong_self_convention.rs:218:22 | LL | fn to_u64_v2(&self) -> u64 { | ^^^^^ @@ -185,7 +185,7 @@ LL | fn to_u64_v2(&self) -> u64 { = help: consider choosing a less ambiguous name error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference - --> tests/ui/wrong_self_convention.rs:206:19 + --> tests/ui/wrong_self_convention.rs:229:19 | LL | fn to_u64(self) -> u64 { | ^^^^ diff --git a/tests/ui/wrong_self_convention2.rs b/tests/ui/wrong_self_convention2.rs index 44b70f877be4..0740af48d741 100644 --- a/tests/ui/wrong_self_convention2.rs +++ b/tests/ui/wrong_self_convention2.rs @@ -52,7 +52,8 @@ mod issue7179 { // lint pub fn from_be_self(self) -> Self { - //~^ ERROR: methods called `from_*` usually take no `self` + //~^ wrong_self_convention + S(i32::from_be(self.0)) } } @@ -62,7 +63,8 @@ mod issue7179 { fn from_be(s: Self) -> Self; // lint fn from_be_self(self) -> Self; - //~^ ERROR: methods called `from_*` usually take no `self` + //~^ wrong_self_convention + } trait Foo: Sized { diff --git a/tests/ui/wrong_self_convention2.stderr b/tests/ui/wrong_self_convention2.stderr index 7aabdcd408c6..2eafb95d9bbe 100644 --- a/tests/ui/wrong_self_convention2.stderr +++ b/tests/ui/wrong_self_convention2.stderr @@ -9,7 +9,7 @@ LL | pub fn from_be_self(self) -> Self { = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]` error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention2.rs:64:25 + --> tests/ui/wrong_self_convention2.rs:65:25 | LL | fn from_be_self(self) -> Self; | ^^^^ diff --git a/tests/ui/wrong_self_conventions_mut.rs b/tests/ui/wrong_self_conventions_mut.rs index 9169fc6d71f6..73df332d77ce 100644 --- a/tests/ui/wrong_self_conventions_mut.rs +++ b/tests/ui/wrong_self_conventions_mut.rs @@ -12,7 +12,8 @@ mod issue6758 { impl Test { // If a method starts with `to_` and not ends with `_mut` it should expect `&self` pub fn to_many(&mut self) -> Option<&mut [T]> { - //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is + //~^ wrong_self_convention + match self { Self::Many(data) => Some(data), _ => None, @@ -21,7 +22,8 @@ mod issue6758 { // If a method starts with `to_` and ends with `_mut` it should expect `&mut self` pub fn to_many_mut(&self) -> Option<&[T]> { - //~^ ERROR: methods with the following characteristics: (`to_*` and `*_mut`) usual + //~^ wrong_self_convention + match self { Self::Many(data) => Some(data), _ => None, diff --git a/tests/ui/wrong_self_conventions_mut.stderr b/tests/ui/wrong_self_conventions_mut.stderr index f52a36632101..5ea2e8192efe 100644 --- a/tests/ui/wrong_self_conventions_mut.stderr +++ b/tests/ui/wrong_self_conventions_mut.stderr @@ -9,7 +9,7 @@ LL | pub fn to_many(&mut self) -> Option<&mut [T]> { = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]` error: methods with the following characteristics: (`to_*` and `*_mut`) usually take `self` by mutable reference - --> tests/ui/wrong_self_conventions_mut.rs:23:28 + --> tests/ui/wrong_self_conventions_mut.rs:24:28 | LL | pub fn to_many_mut(&self) -> Option<&[T]> { | ^^^^^ diff --git a/tests/ui/zero_div_zero.rs b/tests/ui/zero_div_zero.rs index 340ed5ef1339..79a309f49933 100644 --- a/tests/ui/zero_div_zero.rs +++ b/tests/ui/zero_div_zero.rs @@ -2,13 +2,17 @@ #[warn(clippy::zero_divided_by_zero)] fn main() { let nan = 0.0 / 0.0; - //~^ ERROR: constant division of `0.0` with `0.0` will always result in NaN + //~^ zero_divided_by_zero + let f64_nan = 0.0 / 0.0f64; - //~^ ERROR: constant division of `0.0` with `0.0` will always result in NaN + //~^ zero_divided_by_zero + let other_f64_nan = 0.0f64 / 0.0; - //~^ ERROR: constant division of `0.0` with `0.0` will always result in NaN + //~^ zero_divided_by_zero + let one_more_f64_nan = 0.0f64 / 0.0f64; - //~^ ERROR: constant division of `0.0` with `0.0` will always result in NaN + //~^ zero_divided_by_zero + let zero = 0.0; let other_zero = 0.0; let other_nan = zero / other_zero; // fine - this lint doesn't propagate constants. diff --git a/tests/ui/zero_div_zero.stderr b/tests/ui/zero_div_zero.stderr index 5294ebdfa5da..bcf752d7c26c 100644 --- a/tests/ui/zero_div_zero.stderr +++ b/tests/ui/zero_div_zero.stderr @@ -9,7 +9,7 @@ LL | let nan = 0.0 / 0.0; = help: to override `-D warnings` add `#[allow(clippy::zero_divided_by_zero)]` error: constant division of `0.0` with `0.0` will always result in NaN - --> tests/ui/zero_div_zero.rs:6:19 + --> tests/ui/zero_div_zero.rs:7:19 | LL | let f64_nan = 0.0 / 0.0f64; | ^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let f64_nan = 0.0 / 0.0f64; = help: consider using `f64::NAN` if you would like a constant representing NaN error: constant division of `0.0` with `0.0` will always result in NaN - --> tests/ui/zero_div_zero.rs:8:25 + --> tests/ui/zero_div_zero.rs:10:25 | LL | let other_f64_nan = 0.0f64 / 0.0; | ^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let other_f64_nan = 0.0f64 / 0.0; = help: consider using `f64::NAN` if you would like a constant representing NaN error: constant division of `0.0` with `0.0` will always result in NaN - --> tests/ui/zero_div_zero.rs:10:28 + --> tests/ui/zero_div_zero.rs:13:28 | LL | let one_more_f64_nan = 0.0f64 / 0.0f64; | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/zero_offset.rs b/tests/ui/zero_offset.rs index c7a69dee4b2d..dd2063ee5d9e 100644 --- a/tests/ui/zero_offset.rs +++ b/tests/ui/zero_offset.rs @@ -3,24 +3,32 @@ fn main() { unsafe { let m = &mut () as *mut (); m.offset(0); - //~^ ERROR: offset calculation on zero-sized value - //~| NOTE: `#[deny(clippy::zst_offset)]` on by default + //~^ zst_offset + + m.wrapping_add(0); - //~^ ERROR: offset calculation on zero-sized value + //~^ zst_offset + m.sub(0); - //~^ ERROR: offset calculation on zero-sized value + //~^ zst_offset + m.wrapping_sub(0); - //~^ ERROR: offset calculation on zero-sized value + //~^ zst_offset + let c = &() as *const (); c.offset(0); - //~^ ERROR: offset calculation on zero-sized value + //~^ zst_offset + c.wrapping_add(0); - //~^ ERROR: offset calculation on zero-sized value + //~^ zst_offset + c.sub(0); - //~^ ERROR: offset calculation on zero-sized value + //~^ zst_offset + c.wrapping_sub(0); - //~^ ERROR: offset calculation on zero-sized value + //~^ zst_offset + let sized = &1 as *const i32; sized.offset(0); diff --git a/tests/ui/zero_offset.stderr b/tests/ui/zero_offset.stderr index a1efe3904c18..4dfde7d4e1b0 100644 --- a/tests/ui/zero_offset.stderr +++ b/tests/ui/zero_offset.stderr @@ -7,43 +7,43 @@ LL | m.offset(0); = note: `#[deny(clippy::zst_offset)]` on by default error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:8:9 + --> tests/ui/zero_offset.rs:9:9 | LL | m.wrapping_add(0); | ^^^^^^^^^^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:10:9 + --> tests/ui/zero_offset.rs:12:9 | LL | m.sub(0); | ^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:12:9 + --> tests/ui/zero_offset.rs:15:9 | LL | m.wrapping_sub(0); | ^^^^^^^^^^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:16:9 + --> tests/ui/zero_offset.rs:20:9 | LL | c.offset(0); | ^^^^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:18:9 + --> tests/ui/zero_offset.rs:23:9 | LL | c.wrapping_add(0); | ^^^^^^^^^^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:20:9 + --> tests/ui/zero_offset.rs:26:9 | LL | c.sub(0); | ^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:22:9 + --> tests/ui/zero_offset.rs:29:9 | LL | c.wrapping_sub(0); | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/zero_ptr.fixed b/tests/ui/zero_ptr.fixed index 5d99bc9b757d..f2375d57f3a2 100644 --- a/tests/ui/zero_ptr.fixed +++ b/tests/ui/zero_ptr.fixed @@ -2,11 +2,16 @@ pub fn foo(_const: *const f32, _mut: *mut i64) {} fn main() { let _ = std::ptr::null::(); + //~^ zero_ptr let _ = std::ptr::null_mut::(); + //~^ zero_ptr let _: *const u8 = std::ptr::null(); + //~^ zero_ptr foo(0 as _, 0 as _); foo(std::ptr::null(), std::ptr::null_mut()); + //~^ zero_ptr + //~| zero_ptr let z = 0; let _ = z as *const usize; // this is currently not caught diff --git a/tests/ui/zero_ptr.rs b/tests/ui/zero_ptr.rs index 09d321c7a18d..ee01e426a43b 100644 --- a/tests/ui/zero_ptr.rs +++ b/tests/ui/zero_ptr.rs @@ -2,11 +2,16 @@ pub fn foo(_const: *const f32, _mut: *mut i64) {} fn main() { let _ = 0 as *const usize; + //~^ zero_ptr let _ = 0 as *mut f64; + //~^ zero_ptr let _: *const u8 = 0 as *const _; + //~^ zero_ptr foo(0 as _, 0 as _); foo(0 as *const _, 0 as *mut _); + //~^ zero_ptr + //~| zero_ptr let z = 0; let _ = z as *const usize; // this is currently not caught diff --git a/tests/ui/zero_ptr.stderr b/tests/ui/zero_ptr.stderr index a580bebd5d3a..8dc781f36258 100644 --- a/tests/ui/zero_ptr.stderr +++ b/tests/ui/zero_ptr.stderr @@ -8,25 +8,25 @@ LL | let _ = 0 as *const usize; = help: to override `-D warnings` add `#[allow(clippy::zero_ptr)]` error: `0 as *mut _` detected - --> tests/ui/zero_ptr.rs:5:13 + --> tests/ui/zero_ptr.rs:6:13 | LL | let _ = 0 as *mut f64; | ^^^^^^^^^^^^^ help: try: `std::ptr::null_mut::()` error: `0 as *const _` detected - --> tests/ui/zero_ptr.rs:6:24 + --> tests/ui/zero_ptr.rs:8:24 | LL | let _: *const u8 = 0 as *const _; | ^^^^^^^^^^^^^ help: try: `std::ptr::null()` error: `0 as *const _` detected - --> tests/ui/zero_ptr.rs:9:9 + --> tests/ui/zero_ptr.rs:12:9 | LL | foo(0 as *const _, 0 as *mut _); | ^^^^^^^^^^^^^ help: try: `std::ptr::null()` error: `0 as *mut _` detected - --> tests/ui/zero_ptr.rs:9:24 + --> tests/ui/zero_ptr.rs:12:24 | LL | foo(0 as *const _, 0 as *mut _); | ^^^^^^^^^^^ help: try: `std::ptr::null_mut()` diff --git a/tests/ui/zero_ptr_no_std.fixed b/tests/ui/zero_ptr_no_std.fixed index 25143eee8cc3..bbb2464e41d2 100644 --- a/tests/ui/zero_ptr_no_std.fixed +++ b/tests/ui/zero_ptr_no_std.fixed @@ -4,7 +4,10 @@ pub fn main(_argc: isize, _argv: *const *const u8) -> isize { let _ = core::ptr::null::(); + //~^ zero_ptr let _ = core::ptr::null_mut::(); + //~^ zero_ptr let _: *const u8 = core::ptr::null(); + //~^ zero_ptr 0 } diff --git a/tests/ui/zero_ptr_no_std.rs b/tests/ui/zero_ptr_no_std.rs index 965733b45d92..22fe2d24e4b1 100644 --- a/tests/ui/zero_ptr_no_std.rs +++ b/tests/ui/zero_ptr_no_std.rs @@ -4,7 +4,10 @@ pub fn main(_argc: isize, _argv: *const *const u8) -> isize { let _ = 0 as *const usize; + //~^ zero_ptr let _ = 0 as *mut f64; + //~^ zero_ptr let _: *const u8 = 0 as *const _; + //~^ zero_ptr 0 } diff --git a/tests/ui/zero_ptr_no_std.stderr b/tests/ui/zero_ptr_no_std.stderr index 014bf312bf32..77978d0a38b2 100644 --- a/tests/ui/zero_ptr_no_std.stderr +++ b/tests/ui/zero_ptr_no_std.stderr @@ -11,13 +11,13 @@ LL | #![deny(clippy::zero_ptr)] | ^^^^^^^^^^^^^^^^ error: `0 as *mut _` detected - --> tests/ui/zero_ptr_no_std.rs:7:13 + --> tests/ui/zero_ptr_no_std.rs:8:13 | LL | let _ = 0 as *mut f64; | ^^^^^^^^^^^^^ help: try: `core::ptr::null_mut::()` error: `0 as *const _` detected - --> tests/ui/zero_ptr_no_std.rs:8:24 + --> tests/ui/zero_ptr_no_std.rs:10:24 | LL | let _: *const u8 = 0 as *const _; | ^^^^^^^^^^^^^ help: try: `core::ptr::null()` diff --git a/tests/ui/zero_repeat_side_effects.fixed b/tests/ui/zero_repeat_side_effects.fixed index 989e8ae70e58..fb9d7880a4a7 100644 --- a/tests/ui/zero_repeat_side_effects.fixed +++ b/tests/ui/zero_repeat_side_effects.fixed @@ -16,27 +16,36 @@ fn main() { // on arrays f(); let a: [i32; 0] = []; + //~^ zero_repeat_side_effects let mut b; f(); b = [] as [i32; 0]; + //~^ zero_repeat_side_effects // on vecs // vecs dont support inferring value of consts f(); let c: std::vec::Vec = vec![]; + //~^ zero_repeat_side_effects let d; f(); d = vec![] as std::vec::Vec; + //~^ zero_repeat_side_effects // for macros println!("side effect"); let e: [(); 0] = []; + //~^ zero_repeat_side_effects // for nested calls { f() }; let g: [i32; 0] = []; + //~^ zero_repeat_side_effects // as function param drop({ f(); vec![] as std::vec::Vec }); + //~^ zero_repeat_side_effects // when singled out/not part of assignment/local { f(); vec![] as std::vec::Vec }; + //~^ zero_repeat_side_effects { f(); [] as [i32; 0] }; + //~^ zero_repeat_side_effects // should not trigger let a = [f(); N]; diff --git a/tests/ui/zero_repeat_side_effects.rs b/tests/ui/zero_repeat_side_effects.rs index 68511f41a95e..8b22ff840244 100644 --- a/tests/ui/zero_repeat_side_effects.rs +++ b/tests/ui/zero_repeat_side_effects.rs @@ -16,27 +16,36 @@ fn main() { // on arrays let a = [f(); 0]; + //~^ zero_repeat_side_effects let mut b; b = [f(); 0]; + //~^ zero_repeat_side_effects // on vecs // vecs dont support inferring value of consts let c = vec![f(); 0]; + //~^ zero_repeat_side_effects let d; d = vec![f(); 0]; + //~^ zero_repeat_side_effects // for macros let e = [println!("side effect"); 0]; + //~^ zero_repeat_side_effects // for nested calls let g = [{ f() }; 0]; + //~^ zero_repeat_side_effects // as function param drop(vec![f(); 0]); + //~^ zero_repeat_side_effects // when singled out/not part of assignment/local vec![f(); 0]; + //~^ zero_repeat_side_effects [f(); 0]; + //~^ zero_repeat_side_effects // should not trigger let a = [f(); N]; diff --git a/tests/ui/zero_repeat_side_effects.stderr b/tests/ui/zero_repeat_side_effects.stderr index d578e22b9716..2dba52e2112e 100644 --- a/tests/ui/zero_repeat_side_effects.stderr +++ b/tests/ui/zero_repeat_side_effects.stderr @@ -8,49 +8,49 @@ LL | let a = [f(); 0]; = help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]` error: function or method calls as the initial value in zero-sized array initializers may cause side effects - --> tests/ui/zero_repeat_side_effects.rs:20:5 + --> tests/ui/zero_repeat_side_effects.rs:21:5 | LL | b = [f(); 0]; | ^^^^^^^^^^^^ help: consider using: `f(); b = [] as [i32; 0]` error: function or method calls as the initial value in zero-sized array initializers may cause side effects - --> tests/ui/zero_repeat_side_effects.rs:24:5 + --> tests/ui/zero_repeat_side_effects.rs:26:5 | LL | let c = vec![f(); 0]; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f(); let c: std::vec::Vec = vec![];` error: function or method calls as the initial value in zero-sized array initializers may cause side effects - --> tests/ui/zero_repeat_side_effects.rs:26:5 + --> tests/ui/zero_repeat_side_effects.rs:29:5 | LL | d = vec![f(); 0]; | ^^^^^^^^^^^^^^^^ help: consider using: `f(); d = vec![] as std::vec::Vec` error: function or method calls as the initial value in zero-sized array initializers may cause side effects - --> tests/ui/zero_repeat_side_effects.rs:29:5 + --> tests/ui/zero_repeat_side_effects.rs:33:5 | LL | let e = [println!("side effect"); 0]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `println!("side effect"); let e: [(); 0] = [];` error: function or method calls as the initial value in zero-sized array initializers may cause side effects - --> tests/ui/zero_repeat_side_effects.rs:32:5 + --> tests/ui/zero_repeat_side_effects.rs:37:5 | LL | let g = [{ f() }; 0]; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `{ f() }; let g: [i32; 0] = [];` error: function or method calls as the initial value in zero-sized array initializers may cause side effects - --> tests/ui/zero_repeat_side_effects.rs:35:10 + --> tests/ui/zero_repeat_side_effects.rs:41:10 | LL | drop(vec![f(); 0]); | ^^^^^^^^^^^^ help: consider using: `{ f(); vec![] as std::vec::Vec }` error: function or method calls as the initial value in zero-sized array initializers may cause side effects - --> tests/ui/zero_repeat_side_effects.rs:38:5 + --> tests/ui/zero_repeat_side_effects.rs:45:5 | LL | vec![f(); 0]; | ^^^^^^^^^^^^ help: consider using: `{ f(); vec![] as std::vec::Vec }` error: function or method calls as the initial value in zero-sized array initializers may cause side effects - --> tests/ui/zero_repeat_side_effects.rs:39:5 + --> tests/ui/zero_repeat_side_effects.rs:47:5 | LL | [f(); 0]; | ^^^^^^^^ help: consider using: `{ f(); [] as [i32; 0] }` diff --git a/tests/ui/zero_sized_btreemap_values.rs b/tests/ui/zero_sized_btreemap_values.rs index 565f639201ff..ddcfce672bf9 100644 --- a/tests/ui/zero_sized_btreemap_values.rs +++ b/tests/ui/zero_sized_btreemap_values.rs @@ -3,28 +3,34 @@ use std::collections::BTreeMap; const CONST_OK: Option> = None; const CONST_NOT_OK: Option> = None; -//~^ ERROR: map with zero-sized value type +//~^ zero_sized_map_values + static STATIC_OK: Option> = None; static STATIC_NOT_OK: Option> = None; -//~^ ERROR: map with zero-sized value type +//~^ zero_sized_map_values + type OkMap = BTreeMap; type NotOkMap = BTreeMap; -//~^ ERROR: map with zero-sized value type +//~^ zero_sized_map_values + enum TestEnum { Ok(BTreeMap), NotOk(BTreeMap), - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + } struct Test { ok: BTreeMap, not_ok: BTreeMap, - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + also_not_ok: Vec>, - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + } trait TestTrait { @@ -33,7 +39,8 @@ trait TestTrait { fn produce_output() -> Self::Output; fn weird_map(&self, map: BTreeMap); - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + } impl Test { @@ -42,7 +49,8 @@ impl Test { } fn not_ok(&self) -> BTreeMap { - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + todo!() } } @@ -60,8 +68,10 @@ impl TestTrait for Test { } fn test(map: BTreeMap, key: &str) -> BTreeMap { - //~^ ERROR: map with zero-sized value type - //~| ERROR: map with zero-sized value type +//~^ zero_sized_map_values +//~| zero_sized_map_values + + todo!(); } @@ -71,10 +81,13 @@ fn test2(map: BTreeMap, key: &str) -> BTreeMap { fn main() { let _: BTreeMap = BTreeMap::new(); - //~^ ERROR: map with zero-sized value type - //~| ERROR: map with zero-sized value type + //~^ zero_sized_map_values + //~| zero_sized_map_values + + let _: BTreeMap = BTreeMap::new(); let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect(); - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + } diff --git a/tests/ui/zero_sized_btreemap_values.stderr b/tests/ui/zero_sized_btreemap_values.stderr index 65fc81e10e6c..f9184dc9ae1f 100644 --- a/tests/ui/zero_sized_btreemap_values.stderr +++ b/tests/ui/zero_sized_btreemap_values.stderr @@ -9,7 +9,7 @@ LL | const CONST_NOT_OK: Option> = None; = help: to override `-D warnings` add `#[allow(clippy::zero_sized_map_values)]` error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:9:30 + --> tests/ui/zero_sized_btreemap_values.rs:10:30 | LL | static STATIC_NOT_OK: Option> = None; | ^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | static STATIC_NOT_OK: Option> = None; = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:13:17 + --> tests/ui/zero_sized_btreemap_values.rs:15:17 | LL | type NotOkMap = BTreeMap; | ^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | type NotOkMap = BTreeMap; = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:18:11 + --> tests/ui/zero_sized_btreemap_values.rs:21:11 | LL | NotOk(BTreeMap), | ^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | NotOk(BTreeMap), = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:24:13 + --> tests/ui/zero_sized_btreemap_values.rs:28:13 | LL | not_ok: BTreeMap, | ^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | not_ok: BTreeMap, = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:26:22 + --> tests/ui/zero_sized_btreemap_values.rs:31:22 | LL | also_not_ok: Vec>, | ^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | also_not_ok: Vec>, = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:35:30 + --> tests/ui/zero_sized_btreemap_values.rs:41:30 | LL | fn weird_map(&self, map: BTreeMap); | ^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn weird_map(&self, map: BTreeMap); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:44:25 + --> tests/ui/zero_sized_btreemap_values.rs:51:25 | LL | fn not_ok(&self) -> BTreeMap { | ^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | fn not_ok(&self) -> BTreeMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:62:14 + --> tests/ui/zero_sized_btreemap_values.rs:70:14 | LL | fn test(map: BTreeMap, key: &str) -> BTreeMap { | ^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | fn test(map: BTreeMap, key: &str) -> BTreeMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:62:50 + --> tests/ui/zero_sized_btreemap_values.rs:70:50 | LL | fn test(map: BTreeMap, key: &str) -> BTreeMap { | ^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | fn test(map: BTreeMap, key: &str) -> BTreeMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:73:35 + --> tests/ui/zero_sized_btreemap_values.rs:83:35 | LL | let _: BTreeMap = BTreeMap::new(); | ^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _: BTreeMap = BTreeMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:73:12 + --> tests/ui/zero_sized_btreemap_values.rs:83:12 | LL | let _: BTreeMap = BTreeMap::new(); | ^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _: BTreeMap = BTreeMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:78:12 + --> tests/ui/zero_sized_btreemap_values.rs:90:12 | LL | let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect(); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/zero_sized_hashmap_values.rs b/tests/ui/zero_sized_hashmap_values.rs index 5498261ee95a..132716da3b27 100644 --- a/tests/ui/zero_sized_hashmap_values.rs +++ b/tests/ui/zero_sized_hashmap_values.rs @@ -3,28 +3,34 @@ use std::collections::HashMap; const CONST_OK: Option> = None; const CONST_NOT_OK: Option> = None; -//~^ ERROR: map with zero-sized value type +//~^ zero_sized_map_values + static STATIC_OK: Option> = None; static STATIC_NOT_OK: Option> = None; -//~^ ERROR: map with zero-sized value type +//~^ zero_sized_map_values + type OkMap = HashMap; type NotOkMap = HashMap; -//~^ ERROR: map with zero-sized value type +//~^ zero_sized_map_values + enum TestEnum { Ok(HashMap), NotOk(HashMap), - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + } struct Test { ok: HashMap, not_ok: HashMap, - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + also_not_ok: Vec>, - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + } trait TestTrait { @@ -33,7 +39,8 @@ trait TestTrait { fn produce_output() -> Self::Output; fn weird_map(&self, map: HashMap); - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + } impl Test { @@ -42,7 +49,8 @@ impl Test { } fn not_ok(&self) -> HashMap { - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + todo!() } } @@ -60,8 +68,10 @@ impl TestTrait for Test { } fn test(map: HashMap, key: &str) -> HashMap { - //~^ ERROR: map with zero-sized value type - //~| ERROR: map with zero-sized value type +//~^ zero_sized_map_values +//~| zero_sized_map_values + + todo!(); } @@ -71,10 +81,13 @@ fn test2(map: HashMap, key: &str) -> HashMap { fn main() { let _: HashMap = HashMap::new(); - //~^ ERROR: map with zero-sized value type - //~| ERROR: map with zero-sized value type + //~^ zero_sized_map_values + //~| zero_sized_map_values + + let _: HashMap = HashMap::new(); let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect(); - //~^ ERROR: map with zero-sized value type + //~^ zero_sized_map_values + } diff --git a/tests/ui/zero_sized_hashmap_values.stderr b/tests/ui/zero_sized_hashmap_values.stderr index 08afef58a2aa..059902047b55 100644 --- a/tests/ui/zero_sized_hashmap_values.stderr +++ b/tests/ui/zero_sized_hashmap_values.stderr @@ -9,7 +9,7 @@ LL | const CONST_NOT_OK: Option> = None; = help: to override `-D warnings` add `#[allow(clippy::zero_sized_map_values)]` error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:9:30 + --> tests/ui/zero_sized_hashmap_values.rs:10:30 | LL | static STATIC_NOT_OK: Option> = None; | ^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | static STATIC_NOT_OK: Option> = None; = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:13:17 + --> tests/ui/zero_sized_hashmap_values.rs:15:17 | LL | type NotOkMap = HashMap; | ^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | type NotOkMap = HashMap; = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:18:11 + --> tests/ui/zero_sized_hashmap_values.rs:21:11 | LL | NotOk(HashMap), | ^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | NotOk(HashMap), = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:24:13 + --> tests/ui/zero_sized_hashmap_values.rs:28:13 | LL | not_ok: HashMap, | ^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | not_ok: HashMap, = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:26:22 + --> tests/ui/zero_sized_hashmap_values.rs:31:22 | LL | also_not_ok: Vec>, | ^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | also_not_ok: Vec>, = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:35:30 + --> tests/ui/zero_sized_hashmap_values.rs:41:30 | LL | fn weird_map(&self, map: HashMap); | ^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn weird_map(&self, map: HashMap); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:44:25 + --> tests/ui/zero_sized_hashmap_values.rs:51:25 | LL | fn not_ok(&self) -> HashMap { | ^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | fn not_ok(&self) -> HashMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:62:14 + --> tests/ui/zero_sized_hashmap_values.rs:70:14 | LL | fn test(map: HashMap, key: &str) -> HashMap { | ^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | fn test(map: HashMap, key: &str) -> HashMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:62:49 + --> tests/ui/zero_sized_hashmap_values.rs:70:49 | LL | fn test(map: HashMap, key: &str) -> HashMap { | ^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | fn test(map: HashMap, key: &str) -> HashMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:73:34 + --> tests/ui/zero_sized_hashmap_values.rs:83:34 | LL | let _: HashMap = HashMap::new(); | ^^^^^^^ @@ -89,7 +89,7 @@ LL | let _: HashMap = HashMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:73:12 + --> tests/ui/zero_sized_hashmap_values.rs:83:12 | LL | let _: HashMap = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _: HashMap = HashMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:78:12 + --> tests/ui/zero_sized_hashmap_values.rs:90:12 | LL | let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect(); | ^^^^^^^^^^^^^ diff --git a/tests/ui/zombie_processes.rs b/tests/ui/zombie_processes.rs index 6f0d2760a860..25bbc02ffb76 100644 --- a/tests/ui/zombie_processes.rs +++ b/tests/ui/zombie_processes.rs @@ -13,6 +13,7 @@ fn main() { { let mut x = Command::new("").spawn().unwrap(); //~^ zombie_processes + x.kill(); x.id(); } @@ -40,6 +41,7 @@ fn main() { { let mut x = Command::new("").spawn().unwrap(); //~^ zombie_processes + let v = &x; // (allow shared refs is fine because one cannot call `.wait()` through that) } @@ -65,6 +67,7 @@ fn main() { { let mut x = Command::new("").spawn().unwrap(); //~^ zombie_processes + if true { std::process::exit(0); } @@ -72,6 +75,7 @@ fn main() { { let mut x = Command::new("").spawn().unwrap(); //~^ zombie_processes + if true { while false {} // Calling `exit()` after leaving a while loop should still be linted. @@ -98,6 +102,7 @@ fn main() { { let mut x = Command::new("").spawn().unwrap(); //~^ zombie_processes + if true { return; } @@ -107,6 +112,7 @@ fn main() { { let mut x = Command::new("").spawn().unwrap(); //~^ zombie_processes + if true { x.wait().unwrap(); } @@ -115,6 +121,7 @@ fn main() { { let mut x = Command::new("").spawn().unwrap(); //~^ zombie_processes + if true { x.wait().unwrap(); } else { @@ -125,6 +132,7 @@ fn main() { { let mut x = Command::new("").spawn().unwrap(); //~^ zombie_processes + if true { // this else block exists to test the other help message } else { diff --git a/tests/ui/zombie_processes.stderr b/tests/ui/zombie_processes.stderr index afc518c60db2..0374d097b1b5 100644 --- a/tests/ui/zombie_processes.stderr +++ b/tests/ui/zombie_processes.stderr @@ -11,7 +11,7 @@ LL | let mut x = Command::new("").spawn().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::zombie_processes)]` error: spawned process is never `wait()`ed on - --> tests/ui/zombie_processes.rs:41:21 + --> tests/ui/zombie_processes.rs:42:21 | LL | let mut x = Command::new("").spawn().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL | let mut x = Command::new("").spawn().unwrap(); = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning error: spawned process is never `wait()`ed on - --> tests/ui/zombie_processes.rs:66:21 + --> tests/ui/zombie_processes.rs:68:21 | LL | let mut x = Command::new("").spawn().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | let mut x = Command::new("").spawn().unwrap(); = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning error: spawned process is never `wait()`ed on - --> tests/ui/zombie_processes.rs:73:21 + --> tests/ui/zombie_processes.rs:76:21 | LL | let mut x = Command::new("").spawn().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,18 +41,18 @@ LL | let mut x = Command::new("").spawn().unwrap(); = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning error: spawned process is not `wait()`ed on in all code paths - --> tests/ui/zombie_processes.rs:99:21 + --> tests/ui/zombie_processes.rs:103:21 | LL | let mut x = Command::new("").spawn().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: no `wait()` call exists on the code path to this early return - --> tests/ui/zombie_processes.rs:102:13 + --> tests/ui/zombie_processes.rs:107:13 | LL | return; | ^^^^^^ note: `wait()` call exists, but it is unreachable due to the early return - --> tests/ui/zombie_processes.rs:104:9 + --> tests/ui/zombie_processes.rs:109:9 | LL | x.wait().unwrap(); | ^ @@ -61,20 +61,20 @@ LL | x.wait().unwrap(); = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning error: spawned process is not `wait()`ed on in all code paths - --> tests/ui/zombie_processes.rs:108:21 + --> tests/ui/zombie_processes.rs:113:21 | LL | let mut x = Command::new("").spawn().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this if expression has a `wait()` call, but it is missing an else block - --> tests/ui/zombie_processes.rs:110:9 + --> tests/ui/zombie_processes.rs:116:9 | LL | / if true { LL | | x.wait().unwrap(); LL | | } | |_________^ note: `wait()` called here - --> tests/ui/zombie_processes.rs:111:13 + --> tests/ui/zombie_processes.rs:117:13 | LL | x.wait().unwrap(); | ^ @@ -83,13 +83,13 @@ LL | x.wait().unwrap(); = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning error: spawned process is not `wait()`ed on in all code paths - --> tests/ui/zombie_processes.rs:116:21 + --> tests/ui/zombie_processes.rs:122:21 | LL | let mut x = Command::new("").spawn().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `wait()` is not called in this if branch - --> tests/ui/zombie_processes.rs:120:10 + --> tests/ui/zombie_processes.rs:127:10 | LL | } else { | __________^ @@ -97,7 +97,7 @@ LL | | // this else block exists to test the other help message LL | | } | |_________^ note: `wait()` is called in the other branch - --> tests/ui/zombie_processes.rs:119:13 + --> tests/ui/zombie_processes.rs:126:13 | LL | x.wait().unwrap(); | ^ @@ -106,20 +106,20 @@ LL | x.wait().unwrap(); = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning error: spawned process is not `wait()`ed on in all code paths - --> tests/ui/zombie_processes.rs:126:21 + --> tests/ui/zombie_processes.rs:133:21 | LL | let mut x = Command::new("").spawn().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `wait()` is not called in this if branch - --> tests/ui/zombie_processes.rs:128:9 + --> tests/ui/zombie_processes.rs:136:9 | LL | / if true { LL | | // this else block exists to test the other help message LL | | } else { | |_________^ note: `wait()` is called in the other branch - --> tests/ui/zombie_processes.rs:131:13 + --> tests/ui/zombie_processes.rs:139:13 | LL | x.wait().unwrap(); | ^ diff --git a/tests/ui/zombie_processes_fixable.fixed b/tests/ui/zombie_processes_fixable.fixed index 6045262f519a..220abbfcfd7b 100644 --- a/tests/ui/zombie_processes_fixable.fixed +++ b/tests/ui/zombie_processes_fixable.fixed @@ -5,16 +5,20 @@ use std::process::{Child, Command}; fn main() { let _ = Command::new("").spawn().unwrap().wait(); - //~^ ERROR: spawned process is never `wait()`ed on + //~^ zombie_processes + Command::new("").spawn().unwrap().wait(); - //~^ ERROR: spawned process is never `wait()`ed on + //~^ zombie_processes + spawn_proc().wait(); - //~^ ERROR: spawned process is never `wait()`ed on + //~^ zombie_processes + spawn_proc().wait().unwrap(); // OK } fn not_main() { Command::new("").spawn().unwrap().wait(); + //~^ zombie_processes } fn spawn_proc() -> Child { diff --git a/tests/ui/zombie_processes_fixable.rs b/tests/ui/zombie_processes_fixable.rs index e1ecb771641e..820a839cd461 100644 --- a/tests/ui/zombie_processes_fixable.rs +++ b/tests/ui/zombie_processes_fixable.rs @@ -5,16 +5,20 @@ use std::process::{Child, Command}; fn main() { let _ = Command::new("").spawn().unwrap(); - //~^ ERROR: spawned process is never `wait()`ed on + //~^ zombie_processes + Command::new("").spawn().unwrap(); - //~^ ERROR: spawned process is never `wait()`ed on + //~^ zombie_processes + spawn_proc(); - //~^ ERROR: spawned process is never `wait()`ed on + //~^ zombie_processes + spawn_proc().wait().unwrap(); // OK } fn not_main() { Command::new("").spawn().unwrap(); + //~^ zombie_processes } fn spawn_proc() -> Child { diff --git a/tests/ui/zombie_processes_fixable.stderr b/tests/ui/zombie_processes_fixable.stderr index e1c40472c325..abc593fe4396 100644 --- a/tests/ui/zombie_processes_fixable.stderr +++ b/tests/ui/zombie_processes_fixable.stderr @@ -10,7 +10,7 @@ LL | let _ = Command::new("").spawn().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::zombie_processes)]` error: spawned process is never `wait()`ed on - --> tests/ui/zombie_processes_fixable.rs:9:5 + --> tests/ui/zombie_processes_fixable.rs:10:5 | LL | Command::new("").spawn().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try: `.wait()` @@ -19,7 +19,7 @@ LL | Command::new("").spawn().unwrap(); = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning error: spawned process is never `wait()`ed on - --> tests/ui/zombie_processes_fixable.rs:11:5 + --> tests/ui/zombie_processes_fixable.rs:13:5 | LL | spawn_proc(); | ^^^^^^^^^^^^- help: try: `.wait()` @@ -28,7 +28,7 @@ LL | spawn_proc(); = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning error: spawned process is never `wait()`ed on - --> tests/ui/zombie_processes_fixable.rs:17:5 + --> tests/ui/zombie_processes_fixable.rs:20:5 | LL | Command::new("").spawn().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try: `.wait()` From 10184ecbe1f5c9036cfbe779adfd4248d070619d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 Feb 2025 18:22:04 +0100 Subject: [PATCH 116/991] Allowed `clippy::tests/ui/attrs.2.fixed` in `tests/ui/attr.rs` because when adding annotations, it doesn't work anymore --- tests/ui/attrs.rs | 2 +- tests/ui/attrs.stderr | 44 +------------------------------------------ 2 files changed, 2 insertions(+), 44 deletions(-) diff --git a/tests/ui/attrs.rs b/tests/ui/attrs.rs index 6f08bb304260..32e4053e74b0 100644 --- a/tests/ui/attrs.rs +++ b/tests/ui/attrs.rs @@ -1,5 +1,5 @@ #![warn(clippy::inline_always, clippy::deprecated_semver)] -#![allow(clippy::assertions_on_constants)] +#![allow(clippy::assertions_on_constants, clippy::empty_line_after_outer_attr)] #![allow(clippy::missing_docs_in_private_items, clippy::panic, clippy::unreachable)] #[inline(always)] diff --git a/tests/ui/attrs.stderr b/tests/ui/attrs.stderr index 74d4068f6331..f4803380cc41 100644 --- a/tests/ui/attrs.stderr +++ b/tests/ui/attrs.stderr @@ -13,24 +13,6 @@ error: the since field must contain a semver-compliant version LL | #[deprecated(since = "1")] | ^^^^^^^^^^^ -error: empty lines after outer attribute - --> tests/ui/attrs.rs:5:1 - | -LL | / #[inline(always)] -... | -LL | | - | |_^ -LL | fn test_attr_lint() { - | ------------------- the attribute applies to this function - | - = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]` - = help: if the empty lines are unintentional remove them -help: if the attribute should apply to the crate use an inner attribute - | -LL | #![inline(always)] - | + - error: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a bad idea --> tests/ui/attrs.rs:5:1 | @@ -40,29 +22,5 @@ LL | #[inline(always)] = note: `-D clippy::inline-always` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::inline_always)]` -error: empty lines after outer attribute - --> tests/ui/attrs.rs:28:1 - | -LL | / #[deprecated(since = "forever")] -... | -LL | | - | |_^ -LL | pub const SOME_CONST: u8 = 42; - | ------------------------ the attribute applies to this constant - | - = help: if the empty lines are unintentional remove them - -error: empty line after outer attribute - --> tests/ui/attrs.rs:34:1 - | -LL | / #[deprecated(since = "1")] -LL | | -LL | | - | |_^ -LL | pub const ANOTHER_CONST: u8 = 23; - | --------------------------- the attribute applies to this constant - | - = help: if the empty line is unintentional remove it - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors From 0a990758fb4293ecadf0a5731d64ac49ebe44b78 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 12 Feb 2025 17:21:40 +0100 Subject: [PATCH 117/991] Handle compilation error in `builtin_type_shadow.rs` --- tests/ui/builtin_type_shadow.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/ui/builtin_type_shadow.rs b/tests/ui/builtin_type_shadow.rs index 41d6207ea3f5..31df0c21b67e 100644 --- a/tests/ui/builtin_type_shadow.rs +++ b/tests/ui/builtin_type_shadow.rs @@ -3,8 +3,7 @@ fn foo(a: u32) -> u32 { //~^ builtin_type_shadow - 42 - + 42 //~ ERROR: mismatched type } fn main() {} From d5ebe505053748b3bbea506f7b6d8d5ee0cf61a2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 12 Feb 2025 17:42:51 +0100 Subject: [PATCH 118/991] Add manual annotations --- tests/ui/expect_tool_lint_rfc_2383.rs | 3 +++ tests/ui/expect_tool_lint_rfc_2383.stderr | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/ui/expect_tool_lint_rfc_2383.rs b/tests/ui/expect_tool_lint_rfc_2383.rs index 2634c56794e7..2295691c8127 100644 --- a/tests/ui/expect_tool_lint_rfc_2383.rs +++ b/tests/ui/expect_tool_lint_rfc_2383.rs @@ -30,11 +30,14 @@ mod rustc_warn { #[expect(dead_code)] //~^ ERROR: this lint expectation is unfulfilled //~| NOTE: `-D unfulfilled-lint-expectations` implied by `-D warnings` + //~| HELP: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]` pub fn rustc_lints() { let x = 42; #[expect(invalid_nan_comparisons)] //~^ ERROR: this lint expectation is unfulfilled + //~| NOTE: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + //~| ERROR: this lint expectation is unfulfilled let _b = x == 5; } } diff --git a/tests/ui/expect_tool_lint_rfc_2383.stderr b/tests/ui/expect_tool_lint_rfc_2383.stderr index 028e22ca724e..b274d5c23693 100644 --- a/tests/ui/expect_tool_lint_rfc_2383.stderr +++ b/tests/ui/expect_tool_lint_rfc_2383.stderr @@ -8,13 +8,13 @@ LL | #[expect(dead_code)] = help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]` error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:36:18 + --> tests/ui/expect_tool_lint_rfc_2383.rs:37:18 | LL | #[expect(invalid_nan_comparisons)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:36:18 + --> tests/ui/expect_tool_lint_rfc_2383.rs:37:18 | LL | #[expect(invalid_nan_comparisons)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,25 +22,25 @@ LL | #[expect(invalid_nan_comparisons)] = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:107:14 + --> tests/ui/expect_tool_lint_rfc_2383.rs:110:14 | LL | #[expect(clippy::almost_swapped)] | ^^^^^^^^^^^^^^^^^^^^^^ error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:115:14 + --> tests/ui/expect_tool_lint_rfc_2383.rs:118:14 | LL | #[expect(clippy::bytes_nth)] | ^^^^^^^^^^^^^^^^^ error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:121:14 + --> tests/ui/expect_tool_lint_rfc_2383.rs:124:14 | LL | #[expect(clippy::if_same_then_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:127:14 + --> tests/ui/expect_tool_lint_rfc_2383.rs:130:14 | LL | #[expect(clippy::overly_complex_bool_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 8a2dae63c3737ed9623035d55ed5e0e90e2942ab Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 12 Feb 2025 17:55:46 +0100 Subject: [PATCH 119/991] Make `if_let_mutex` test pass on both 2021 and 2024 editions --- tests/ui/if_let_mutex.edition2021.stderr | 8 ++++---- tests/ui/if_let_mutex.rs | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/ui/if_let_mutex.edition2021.stderr b/tests/ui/if_let_mutex.edition2021.stderr index 984d6adbb2a4..58afd03c8c24 100644 --- a/tests/ui/if_let_mutex.edition2021.stderr +++ b/tests/ui/if_let_mutex.edition2021.stderr @@ -1,5 +1,5 @@ error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock - --> tests/ui/if_let_mutex.rs:16:5 + --> tests/ui/if_let_mutex.rs:17:5 | LL | if let Err(locked) = m.lock() { | ^ - this Mutex will remain locked for the entire `if let`-block... @@ -19,7 +19,7 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::if_let_mutex)]` error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock - --> tests/ui/if_let_mutex.rs:29:5 + --> tests/ui/if_let_mutex.rs:30:5 | LL | if let Some(locked) = m.lock().unwrap().deref() { | ^ - this Mutex will remain locked for the entire `if let`-block... @@ -37,7 +37,7 @@ LL | | }; = help: move the lock call outside of the `if let ...` expression error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock - --> tests/ui/if_let_mutex.rs:51:5 + --> tests/ui/if_let_mutex.rs:52:5 | LL | if let Ok(i) = mutex.lock() { | ^ ----- this Mutex will remain locked for the entire `if let`-block... @@ -54,7 +54,7 @@ LL | | }; = help: move the lock call outside of the `if let ...` expression error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock - --> tests/ui/if_let_mutex.rs:60:5 + --> tests/ui/if_let_mutex.rs:61:5 | LL | if let Ok(_) = m1.lock() { | ^ -- this Mutex will remain locked for the entire `if let`-block... diff --git a/tests/ui/if_let_mutex.rs b/tests/ui/if_let_mutex.rs index ddf178b63048..72058ea33ee7 100644 --- a/tests/ui/if_let_mutex.rs +++ b/tests/ui/if_let_mutex.rs @@ -3,6 +3,7 @@ //@revisions: edition2021 edition2024 //@[edition2021] edition:2021 //@[edition2024] edition:2024 +//@[edition2024] check-pass #![warn(clippy::if_let_mutex)] #![allow(clippy::redundant_pattern_matching)] @@ -62,10 +63,7 @@ fn multiple_mutexes(m1: &Mutex<()>, m2: &Mutex<()>) { } else { m1.lock(); } - //~^ if_let_mutex - //~^ if_let_mutex - //~^ if_let_mutex - //~^ if_let_mutex + //~[edition2021]^^^^^ if_let_mutex } fn main() {} From 1f94d55a183c493ae2ca2754d9485f89e4ac76ae Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 12 Feb 2025 23:44:38 +0100 Subject: [PATCH 120/991] Fix new tests updates --- tests/ui/as_pointer_underscore.fixed | 2 - tests/ui/as_pointer_underscore.rs | 2 - tests/ui/as_pointer_underscore.stderr | 2 +- tests/ui/as_ptr_cast_mut.rs | 1 - tests/ui/as_ptr_cast_mut.stderr | 2 +- tests/ui/asm_syntax_x86.rs | 2 - tests/ui/asm_syntax_x86.stderr | 2 +- tests/ui/assertions_on_constants.rs | 6 - tests/ui/assertions_on_constants.stderr | 16 +- tests/ui/assign_ops2.rs | 3 - tests/ui/assign_ops2.stderr | 18 +- tests/ui/attrs.rs | 2 - tests/ui/attrs.stderr | 4 +- tests/ui/await_holding_refcell_ref.rs | 2 - tests/ui/await_holding_refcell_ref.stderr | 14 +- tests/ui/bind_instead_of_map_multipart.fixed | 2 +- tests/ui/bind_instead_of_map_multipart.rs | 2 +- tests/ui/bit_masks.rs | 9 - tests/ui/bit_masks.stderr | 30 +-- tests/ui/blanket_clippy_restriction_lints.rs | 3 - .../blanket_clippy_restriction_lints.stderr | 4 +- tests/ui/bool_comparison.fixed | 28 +-- tests/ui/bool_comparison.rs | 28 +-- tests/ui/bool_to_int_with_if.rs | 16 +- tests/ui/borrow_box.fixed | 6 - tests/ui/borrow_box.rs | 6 - tests/ui/borrow_box.stderr | 18 +- tests/ui/borrow_deref_ref_unfixable.rs | 2 - .../borrow_interior_mutable_const/others.rs | 56 ++--- .../others.stderr | 112 ++++----- .../borrow_interior_mutable_const/traits.rs | 68 ++--- .../traits.stderr | 102 ++++---- tests/ui/box_collection.rs | 9 - tests/ui/box_collection.stderr | 16 +- tests/ui/boxed_local.rs | 7 +- tests/ui/boxed_local.stderr | 6 +- .../branches_sharing_code/shared_at_bottom.rs | 10 +- .../shared_at_bottom.stderr | 31 ++- .../ui/branches_sharing_code/shared_at_top.rs | 15 +- .../shared_at_top.stderr | 14 +- .../shared_at_top_and_bottom.rs | 10 +- .../branches_sharing_code/valid_if_blocks.rs | 5 - .../valid_if_blocks.stderr | 16 +- tests/ui/builtin_type_shadow.rs | 2 +- tests/ui/bytecount.rs | 3 - tests/ui/bytecount.stderr | 4 +- tests/ui/cast.rs | 24 -- tests/ui/cast.stderr | 182 +++++++------- tests/ui/cast_alignment.rs | 3 - tests/ui/cast_alignment.stderr | 6 +- tests/ui/cast_enum_constructor.rs | 1 - tests/ui/cast_enum_constructor.stderr | 2 +- tests/ui/cast_lossless_integer.fixed | 13 - tests/ui/cast_lossless_integer.rs | 13 - tests/ui/cast_lossless_integer.stderr | 64 ++--- tests/ui/cast_nan_to_int.rs | 8 - tests/ui/cast_nan_to_int.stderr | 10 +- tests/ui/cast_slice_different_sizes.rs | 20 +- tests/ui/cast_slice_different_sizes.stderr | 28 +-- tests/ui/char_lit_as_u8.rs | 2 - .../ui/checked_unwrap/complex_conditionals.rs | 4 - .../complex_conditionals.stderr | 32 +-- .../ui/checked_unwrap/simple_conditionals.rs | 18 +- .../checked_unwrap/simple_conditionals.stderr | 46 ++-- tests/ui/cmp_null.fixed | 10 +- tests/ui/cmp_null.rs | 10 +- tests/ui/cmp_null.stderr | 8 +- tests/ui/cmp_owned/comparison_flip.fixed | 4 +- tests/ui/cmp_owned/comparison_flip.rs | 4 +- tests/ui/cmp_owned/without_suggestion.rs | 4 - tests/ui/cmp_owned/without_suggestion.stderr | 4 +- tests/ui/cognitive_complexity.rs | 37 ++- tests/ui/cognitive_complexity.stderr | 32 +-- tests/ui/cognitive_complexity_attr_used.rs | 2 +- tests/ui/collapsible_match.rs | 32 +-- tests/ui/collapsible_match.stderr | 62 +++-- tests/ui/collapsible_match2.rs | 14 +- tests/ui/collapsible_match2.stderr | 28 +-- tests/ui/collection_is_never_read.rs | 1 - tests/ui/collection_is_never_read.stderr | 38 +-- tests/ui/comparison_chain.rs | 16 +- tests/ui/comparison_to_empty.fixed | 2 +- tests/ui/comparison_to_empty.rs | 2 +- tests/ui/const_comparisons.rs | 30 --- tests/ui/const_comparisons.stderr | 60 ++--- tests/ui/const_is_empty.rs | 21 +- tests/ui/const_is_empty.stderr | 52 ++-- tests/ui/copy_iterator.rs | 3 +- tests/ui/copy_iterator.stderr | 3 + tests/ui/crashes/ice-11803.rs | 4 +- tests/ui/crashes/ice-2774.fixed | 3 +- tests/ui/crashes/ice-2774.rs | 3 +- tests/ui/crashes/ice-360.rs | 7 +- tests/ui/crashes/ice-360.stderr | 2 +- tests/ui/crashes/ice-3717.fixed | 2 +- tests/ui/crashes/ice-3717.rs | 2 +- tests/ui/crashes/ice-3969.rs | 8 +- tests/ui/crashes/ice-5872.fixed | 2 - tests/ui/crashes/ice-5872.rs | 2 - tests/ui/crashes/ice-6250.rs | 4 +- tests/ui/crashes/ice-6251.rs | 6 +- tests/ui/crashes/ice-7169.fixed | 2 - tests/ui/crashes/ice-7169.rs | 2 - tests/ui/crashes/ice-7869.rs | 3 +- tests/ui/crashes/ice-7869.stderr | 1 - tests/ui/crashes/ice-8250.fixed | 1 - tests/ui/crashes/ice-8250.rs | 1 - tests/ui/crashes/ice-9041.rs | 2 - .../needless_lifetimes_impl_trait.fixed | 2 +- .../crashes/needless_lifetimes_impl_trait.rs | 2 +- .../needless_pass_by_value-w-late-bound.fixed | 1 - .../needless_pass_by_value-w-late-bound.rs | 1 - tests/ui/crate_level_checks/no_std_swap.rs | 1 - .../crate_level_checks/std_main_recursion.rs | 1 - tests/ui/dbg_macro/dbg_macro.fixed | 12 +- tests/ui/dbg_macro/dbg_macro.rs | 12 +- tests/ui/dbg_macro/dbg_macro.stderr | 54 ++-- tests/ui/dbg_macro/dbg_macro_unfixable.rs | 1 - .../declare_interior_mutable_const/enums.rs | 39 ++- .../enums.stderr | 53 ++-- .../declare_interior_mutable_const/others.rs | 2 - .../others.stderr | 4 +- .../declare_interior_mutable_const/traits.rs | 49 ++-- .../traits.stderr | 72 +++--- tests/ui/default_numeric_fallback_f64.fixed | 2 +- tests/ui/default_numeric_fallback_f64.rs | 2 +- tests/ui/default_numeric_fallback_i32.fixed | 2 +- tests/ui/default_numeric_fallback_i32.rs | 2 +- tests/ui/default_union_representation.rs | 12 +- tests/ui/default_union_representation.stderr | 10 +- tests/ui/deref_addrof_double_trigger.rs | 4 - tests/ui/deref_addrof_double_trigger.stderr | 4 +- tests/ui/derivable_impls.rs | 22 +- tests/ui/derive.rs | 10 +- tests/ui/derive_ord_xor_partial_ord.rs | 4 +- tests/ui/disallowed_names.rs | 10 +- tests/ui/disallowed_names.stderr | 26 +- tests/ui/disallowed_script_idents.rs | 1 - tests/ui/diverging_sub_expression.rs | 2 - tests/ui/diverging_sub_expression.stderr | 20 +- tests/ui/doc/issue_12795.fixed | 4 - tests/ui/doc/issue_12795.rs | 4 - tests/ui/doc_errors.rs | 14 +- tests/ui/doc_errors.stderr | 12 +- tests/ui/doc_unsafe.rs | 10 +- tests/ui/double_comparison.fixed | 16 +- tests/ui/double_comparison.rs | 16 +- tests/ui/double_must_use.rs | 8 +- tests/ui/duplicate_underscore_argument.rs | 1 - tests/ui/else_if_without_else.rs | 8 +- tests/ui/empty_drop.rs | 4 +- tests/ui/empty_enum.rs | 1 - .../empty_enum_variants_with_brackets.fixed | 18 +- tests/ui/empty_enum_variants_with_brackets.rs | 18 +- .../empty_enum_variants_with_brackets.stderr | 24 +- .../ui/empty_line_after/doc_comments.1.fixed | 11 +- .../ui/empty_line_after/doc_comments.2.fixed | 13 +- tests/ui/empty_line_after/doc_comments.rs | 11 +- tests/ui/empty_line_after/doc_comments.stderr | 32 +-- tests/ui/empty_loop_no_std.rs | 1 - tests/ui/entry.fixed | 18 +- tests/ui/entry.rs | 22 +- tests/ui/entry_btree.fixed | 2 +- tests/ui/entry_btree.rs | 2 +- tests/ui/entry_with_else.fixed | 14 +- tests/ui/entry_with_else.rs | 14 +- tests/ui/enum_clike_unportable_variant.rs | 10 - tests/ui/enum_clike_unportable_variant.stderr | 16 +- tests/ui/enum_variants.rs | 21 +- tests/ui/enum_variants.stderr | 19 +- tests/ui/eprint_with_newline.fixed | 8 +- tests/ui/eprint_with_newline.rs | 8 +- tests/ui/eprint_with_newline.stderr | 20 +- tests/ui/eq_op.rs | 13 - tests/ui/eq_op.stderr | 56 ++--- tests/ui/equatable_if_let.fixed | 2 +- tests/ui/equatable_if_let.rs | 2 +- tests/ui/erasing_op.rs | 2 - tests/ui/erasing_op.stderr | 8 +- tests/ui/error_impl_error.rs | 6 +- tests/ui/error_impl_error.stderr | 12 +- tests/ui/exhaustive_items.fixed | 6 +- tests/ui/exhaustive_items.rs | 6 +- tests/ui/exit1.rs | 2 - tests/ui/exit2.rs | 2 - tests/ui/expect.rs | 2 - tests/ui/expect.stderr | 4 +- tests/ui/explicit_counter_loop.rs | 22 +- tests/ui/explicit_counter_loop.stderr | 18 +- tests/ui/explicit_deref_methods.fixed | 2 +- tests/ui/explicit_deref_methods.rs | 2 +- tests/ui/extra_unused_lifetimes.rs | 8 +- tests/ui/extra_unused_type_parameters.fixed | 16 +- tests/ui/extra_unused_type_parameters.rs | 16 +- .../extra_unused_type_parameters_unfixable.rs | 3 - ...ra_unused_type_parameters_unfixable.stderr | 4 +- tests/ui/fallible_impl_from.rs | 8 +- tests/ui/filetype_is_file.rs | 6 +- tests/ui/filter_map_bool_then.fixed | 6 +- tests/ui/filter_map_bool_then.rs | 6 +- tests/ui/filter_map_identity.fixed | 20 +- tests/ui/filter_map_identity.rs | 10 +- tests/ui/filter_map_identity.stderr | 42 ++-- tests/ui/float_arithmetic.rs | 5 - tests/ui/float_arithmetic.stderr | 8 +- tests/ui/float_cmp.rs | 3 - tests/ui/float_cmp.stderr | 6 +- tests/ui/float_cmp_const.rs | 3 - tests/ui/float_cmp_const.stderr | 6 +- tests/ui/float_equality_without_abs.rs | 4 - tests/ui/float_equality_without_abs.stderr | 20 +- tests/ui/fn_to_numeric_cast_any.rs | 8 - tests/ui/fn_to_numeric_cast_any.stderr | 32 +-- tests/ui/for_kv_map.fixed | 13 +- tests/ui/for_kv_map.rs | 13 +- tests/ui/for_kv_map.stderr | 10 +- tests/ui/forget_non_drop.rs | 1 - tests/ui/forget_non_drop.stderr | 4 +- tests/ui/format.rs | 2 +- tests/ui/format_args.fixed | 4 +- tests/ui/format_args.rs | 4 +- tests/ui/format_args.stderr | 4 +- tests/ui/format_args_unfixable.rs | 8 +- tests/ui/format_args_unfixable.stderr | 34 ++- tests/ui/format_collect.rs | 4 +- tests/ui/format_collect.stderr | 16 +- tests/ui/format_push_string.rs | 8 +- tests/ui/format_push_string.stderr | 7 +- tests/ui/from_over_into.fixed | 14 +- tests/ui/from_over_into.rs | 14 +- tests/ui/from_over_into_unfixable.rs | 8 +- tests/ui/from_raw_with_void_ptr.rs | 5 - tests/ui/from_raw_with_void_ptr.stderr | 16 +- tests/ui/from_str_radix_10.fixed | 4 - tests/ui/from_str_radix_10.rs | 4 - tests/ui/from_str_radix_10.stderr | 14 +- tests/ui/functions.rs | 9 - tests/ui/functions.stderr | 30 +-- tests/ui/functions_maxlines.rs | 3 +- tests/ui/functions_maxlines.stderr | 3 + tests/ui/future_not_send.rs | 14 +- tests/ui/future_not_send.stderr | 17 +- tests/ui/get_first.fixed | 1 - tests/ui/get_first.rs | 1 - tests/ui/identity_op.fixed | 7 - tests/ui/identity_op.rs | 7 - tests/ui/identity_op.stderr | 50 ++-- tests/ui/if_not_else.fixed | 12 +- tests/ui/if_not_else.rs | 12 +- tests/ui/if_same_then_else.rs | 5 - tests/ui/if_same_then_else.stderr | 20 +- tests/ui/if_same_then_else2.rs | 6 - tests/ui/if_same_then_else2.stderr | 20 +- tests/ui/if_then_some_else_none.fixed | 2 - tests/ui/if_then_some_else_none.rs | 8 +- tests/ui/if_then_some_else_none.stderr | 6 +- tests/ui/ifs_same_cond.rs | 11 +- tests/ui/ifs_same_cond.stderr | 12 +- tests/ui/impl.rs | 7 +- tests/ui/impl_trait_in_params.rs | 9 +- tests/ui/impl_trait_in_params.stderr | 20 +- tests/ui/implicit_hasher.fixed | 10 +- tests/ui/implicit_hasher.rs | 10 +- tests/ui/implicit_saturating_add.rs | 48 ++-- tests/ui/implicit_saturating_sub.rs | 48 ++-- tests/ui/implied_bounds_in_impls.fixed | 10 +- tests/ui/implied_bounds_in_impls.rs | 10 +- tests/ui/incompatible_msrv.rs | 2 - tests/ui/incompatible_msrv.stderr | 2 +- .../ui/inconsistent_struct_constructor.fixed | 4 +- tests/ui/inconsistent_struct_constructor.rs | 4 +- .../if_let_slice_binding.fixed | 21 +- .../if_let_slice_binding.rs | 21 +- .../if_let_slice_binding.stderr | 12 +- tests/ui/ineffective_open_options.fixed | 6 +- tests/ui/ineffective_open_options.rs | 8 +- tests/ui/ineffective_open_options.stderr | 12 +- tests/ui/infallible_destructuring_match.rs | 8 +- tests/ui/infinite_iter.rs | 9 +- tests/ui/infinite_iter.stderr | 27 +- tests/ui/infinite_loop.rs | 33 +-- tests/ui/infinite_loop.stderr | 36 +-- tests/ui/infinite_loops.rs | 42 ++-- tests/ui/inherent_to_string.rs | 4 +- tests/ui/init_numbered_fields.rs | 4 +- tests/ui/inspect_for_each.rs | 2 +- tests/ui/into_iter_on_ref.fixed | 104 ++++---- tests/ui/into_iter_on_ref.rs | 104 ++++---- tests/ui/into_iter_on_ref.stderr | 234 +++++++++--------- tests/ui/into_iter_without_iter.rs | 12 +- tests/ui/invalid_upcast_comparisons.rs | 5 - tests/ui/invalid_upcast_comparisons.stderr | 52 ++-- tests/ui/issue-7447.rs | 2 - tests/ui/issue-7447.stderr | 2 +- tests/ui/issue_2356.fixed | 2 +- tests/ui/issue_2356.rs | 2 +- tests/ui/issue_4266.rs | 5 +- tests/ui/issue_4266.stderr | 4 +- tests/ui/items_after_statement.rs | 7 +- tests/ui/items_after_statement.stderr | 8 +- .../items_after_test_module/root_module.fixed | 2 +- .../ui/items_after_test_module/root_module.rs | 2 +- tests/ui/iter_filter_is_ok.fixed | 13 +- tests/ui/iter_filter_is_ok.rs | 13 +- tests/ui/iter_filter_is_ok.stderr | 18 +- tests/ui/iter_filter_is_some.fixed | 11 +- tests/ui/iter_filter_is_some.rs | 11 +- tests/ui/iter_filter_is_some.stderr | 14 +- tests/ui/iter_kv_map.fixed | 8 +- tests/ui/iter_kv_map.rs | 8 +- tests/ui/iter_kv_map.stderr | 14 +- tests/ui/iter_not_returning_iterator.rs | 6 +- tests/ui/iter_not_returning_iterator.stderr | 4 +- tests/ui/iter_on_empty_collections.fixed | 2 +- tests/ui/iter_on_empty_collections.rs | 2 +- tests/ui/iter_out_of_bounds.rs | 17 +- tests/ui/iter_out_of_bounds.stderr | 22 +- tests/ui/iter_over_hash_type.rs | 26 +- tests/ui/iter_overeager_cloned.fixed | 2 +- tests/ui/iter_overeager_cloned.rs | 2 +- tests/ui/iter_skip_next_unfixable.rs | 2 - tests/ui/iter_skip_next_unfixable.stderr | 4 +- tests/ui/iter_without_into_iter.rs | 16 +- tests/ui/iterator_step_by_zero.rs | 5 - tests/ui/iterator_step_by_zero.stderr | 12 +- tests/ui/join_absolute_paths.rs | 4 - tests/ui/join_absolute_paths.stderr | 6 +- tests/ui/large_enum_variant.rs | 40 +-- tests/ui/large_futures.fixed | 9 +- tests/ui/large_futures.rs | 9 +- tests/ui/large_futures.stderr | 14 +- tests/ui/large_stack_frames.rs | 6 +- tests/ui/large_types_passed_by_value.rs | 4 +- tests/ui/len_without_is_empty.rs | 34 ++- tests/ui/len_without_is_empty.stderr | 40 +-- tests/ui/len_zero.fixed | 24 +- tests/ui/len_zero.rs | 24 +- tests/ui/let_and_return.edition2021.fixed | 11 - tests/ui/let_and_return.edition2021.stderr | 18 +- tests/ui/let_and_return.edition2024.fixed | 11 - tests/ui/let_and_return.edition2024.stderr | 28 +-- tests/ui/let_and_return.rs | 11 - tests/ui/let_if_seq.rs | 3 - tests/ui/let_if_seq.stderr | 17 +- tests/ui/let_underscore_future.rs | 2 - tests/ui/let_underscore_future.stderr | 2 +- tests/ui/let_underscore_must_use.rs | 7 - tests/ui/let_underscore_must_use.stderr | 18 +- tests/ui/let_unit.fixed | 4 +- tests/ui/let_unit.rs | 4 +- tests/ui/linkedlist.rs | 6 +- tests/ui/linkedlist.stderr | 14 +- tests/ui/literals.rs | 13 - tests/ui/literals.stderr | 38 +-- tests/ui/manual_arithmetic_check-2.rs | 2 - tests/ui/manual_arithmetic_check-2.stderr | 16 +- tests/ui/manual_arithmetic_check.fixed | 2 - tests/ui/manual_arithmetic_check.rs | 2 - tests/ui/manual_arithmetic_check.stderr | 4 +- tests/ui/manual_assert.rs | 20 +- tests/ui/manual_async_fn.rs | 18 +- tests/ui/manual_clamp.fixed | 21 -- tests/ui/manual_clamp.rs | 76 ++---- tests/ui/manual_clamp.stderr | 125 +++++++--- tests/ui/manual_div_ceil.fixed | 20 +- tests/ui/manual_div_ceil.rs | 20 +- tests/ui/manual_div_ceil.stderr | 30 +-- tests/ui/manual_filter.rs | 30 +-- tests/ui/manual_filter_map.rs | 2 +- tests/ui/manual_find.rs | 6 +- tests/ui/manual_find.stderr | 8 +- tests/ui/manual_find_fixable.rs | 22 +- tests/ui/manual_flatten.rs | 16 +- tests/ui/manual_ignore_case_cmp.fixed | 8 +- tests/ui/manual_ignore_case_cmp.rs | 8 +- tests/ui/manual_inspect.fixed | 26 +- tests/ui/manual_inspect.rs | 26 +- tests/ui/manual_let_else.rs | 50 ++-- tests/ui/manual_let_else.stderr | 61 +++-- tests/ui/manual_let_else_match.rs | 31 +-- tests/ui/manual_let_else_match.stderr | 30 +-- tests/ui/manual_let_else_question_mark.rs | 4 +- tests/ui/manual_map_option.rs | 38 +-- tests/ui/manual_map_option_2.rs | 14 +- tests/ui/manual_memcpy/with_loop_counters.rs | 23 +- .../manual_memcpy/with_loop_counters.stderr | 24 +- .../ui/manual_memcpy/without_loop_counters.rs | 37 ++- .../without_loop_counters.stderr | 38 +-- tests/ui/manual_non_exhaustive_enum.rs | 4 +- tests/ui/manual_ok_err.rs | 22 +- tests/ui/manual_ok_err.stderr | 20 +- tests/ui/manual_option_as_slice.fixed | 9 +- tests/ui/manual_option_as_slice.rs | 10 +- tests/ui/manual_option_as_slice.stderr | 13 +- tests/ui/manual_retain.rs | 4 +- tests/ui/manual_saturating_arithmetic.rs | 10 +- tests/ui/manual_slice_fill.rs | 8 +- tests/ui/manual_strip.rs | 4 - tests/ui/manual_strip.stderr | 16 +- tests/ui/manual_try_fold.rs | 4 +- tests/ui/manual_unwrap_or.rs | 28 +-- tests/ui/manual_unwrap_or_default.rs | 21 +- tests/ui/manual_unwrap_or_default.stderr | 19 +- .../ui/manual_unwrap_or_default_unfixable.rs | 2 +- tests/ui/many_single_char_names.rs | 5 - tests/ui/many_single_char_names.stderr | 4 +- tests/ui/map_all_any_identity.fixed | 1 - tests/ui/map_all_any_identity.rs | 1 - tests/ui/map_clone.fixed | 12 - tests/ui/map_clone.rs | 12 - tests/ui/map_clone.stderr | 14 +- tests/ui/map_err.rs | 1 - tests/ui/map_flatten.rs | 1 - tests/ui/map_flatten_fixable.fixed | 2 +- tests/ui/map_flatten_fixable.rs | 2 +- tests/ui/map_identity.rs | 4 +- ...map_with_unused_argument_over_ranges.fixed | 2 +- .../map_with_unused_argument_over_ranges.rs | 2 +- tests/ui/match_as_ref.rs | 6 +- tests/ui/match_bool.rs | 39 +-- tests/ui/match_bool.stderr | 50 ++-- tests/ui/match_on_vec_items.rs | 25 +- tests/ui/match_on_vec_items.stderr | 14 +- tests/ui/match_overlapping_arm.rs | 8 - tests/ui/match_overlapping_arm.stderr | 30 +-- tests/ui/match_ref_pats.fixed | 10 +- tests/ui/match_ref_pats.rs | 10 +- tests/ui/match_result_ok.fixed | 2 +- tests/ui/match_result_ok.rs | 2 +- tests/ui/match_same_arms.rs | 28 +-- tests/ui/match_same_arms.stderr | 60 ++--- tests/ui/match_same_arms2.fixed | 33 ++- tests/ui/match_same_arms2.rs | 43 ++-- tests/ui/match_same_arms2.stderr | 86 +++---- tests/ui/match_same_arms_non_exhaustive.fixed | 2 - tests/ui/match_same_arms_non_exhaustive.rs | 2 - .../ui/match_same_arms_non_exhaustive.stderr | 6 +- tests/ui/match_single_binding.rs | 48 ++-- tests/ui/match_single_binding2.fixed | 2 +- tests/ui/match_single_binding2.rs | 6 +- tests/ui/match_wild_err_arm.rs | 9 +- tests/ui/match_wild_err_arm.stderr | 6 +- tests/ui/mem_forget.rs | 8 - tests/ui/mem_forget.stderr | 6 +- tests/ui/mem_replace.stderr | 6 +- tests/ui/methods.rs | 2 +- tests/ui/methods_unfixable.rs | 1 - tests/ui/min_ident_chars.rs | 10 +- tests/ui/min_max.rs | 6 - tests/ui/min_max.stderr | 24 +- tests/ui/min_rust_version_attr.rs | 6 - tests/ui/min_rust_version_attr.stderr | 10 +- tests/ui/mismatching_type_param_order.rs | 10 - tests/ui/mismatching_type_param_order.stderr | 16 +- tests/ui/misnamed_getters.fixed | 37 ++- tests/ui/misnamed_getters.rs | 37 ++- tests/ui/misnamed_getters.stderr | 37 +-- tests/ui/missing_asserts_for_indexing.fixed | 5 - tests/ui/missing_asserts_for_indexing.rs | 5 - tests/ui/missing_asserts_for_indexing.stderr | 82 +++--- .../missing_asserts_for_indexing_unfixable.rs | 3 - ...sing_asserts_for_indexing_unfixable.stderr | 44 ++-- .../missing_const_for_fn/could_be_const.fixed | 36 +-- .../ui/missing_const_for_fn/could_be_const.rs | 36 +-- tests/ui/missing_const_for_thread_local.fixed | 4 - tests/ui/missing_const_for_thread_local.rs | 4 - .../ui/missing_const_for_thread_local.stderr | 10 +- tests/ui/missing_doc.rs | 6 +- tests/ui/missing_doc_crate_missing.rs | 2 - tests/ui/missing_doc_impl.rs | 6 +- tests/ui/missing_fields_in_debug.rs | 6 +- tests/ui/missing_inline.rs | 3 - tests/ui/missing_inline.stderr | 10 +- tests/ui/missing_panics_doc.rs | 24 +- tests/ui/missing_trait_methods.rs | 3 +- tests/ui/missing_trait_methods.stderr | 34 +-- tests/ui/mixed_read_write_in_expression.rs | 6 +- .../ui/mixed_read_write_in_expression.stderr | 12 +- tests/ui/module_inception.rs | 9 +- tests/ui/module_inception.stderr | 10 +- tests/ui/module_name_repetitions.rs | 3 - tests/ui/module_name_repetitions.stderr | 10 +- tests/ui/modulo_arithmetic_float.rs | 21 -- tests/ui/modulo_arithmetic_float.stderr | 30 +-- tests/ui/modulo_arithmetic_integral.rs | 25 -- tests/ui/modulo_arithmetic_integral.stderr | 32 +-- tests/ui/modulo_arithmetic_integral_const.rs | 19 -- .../modulo_arithmetic_integral_const.stderr | 32 +-- tests/ui/modulo_one.rs | 1 - tests/ui/modulo_one.stderr | 10 +- tests/ui/multi_assignments.rs | 3 - tests/ui/multi_assignments.stderr | 10 +- tests/ui/multiple_bound_locations.rs | 6 - tests/ui/multiple_bound_locations.stderr | 10 +- tests/ui/multiple_unsafe_ops_per_block.rs | 14 +- tests/ui/must_use_candidates.fixed | 10 +- tests/ui/must_use_candidates.rs | 10 +- tests/ui/mut_from_ref.rs | 11 +- tests/ui/mut_from_ref.stderr | 16 +- tests/ui/mut_key.rs | 8 +- tests/ui/mut_key.stderr | 26 +- tests/ui/mut_mut.rs | 2 +- tests/ui/mut_range_bound.rs | 10 - tests/ui/mut_range_bound.stderr | 12 +- tests/ui/mut_reference.rs | 3 - tests/ui/mut_reference.stderr | 4 +- tests/ui/mutex_atomic.rs | 3 - tests/ui/mutex_atomic.stderr | 20 +- tests/ui/needless_arbitrary_self_type.fixed | 12 +- tests/ui/needless_arbitrary_self_type.rs | 12 +- tests/ui/needless_as_bytes.fixed | 12 +- tests/ui/needless_as_bytes.rs | 12 +- tests/ui/needless_as_bytes.stderr | 12 +- tests/ui/needless_bitwise_bool.fixed | 2 +- tests/ui/needless_bitwise_bool.rs | 2 +- tests/ui/needless_borrow_pat.fixed | 16 +- tests/ui/needless_borrow_pat.rs | 16 +- tests/ui/needless_borrow_pat.stderr | 22 +- tests/ui/needless_borrowed_ref.fixed | 2 +- tests/ui/needless_borrowed_ref.rs | 2 +- tests/ui/needless_character_iteration.fixed | 3 - tests/ui/needless_character_iteration.rs | 7 +- tests/ui/needless_character_iteration.stderr | 10 +- tests/ui/needless_collect.fixed | 2 +- tests/ui/needless_collect.rs | 2 +- tests/ui/needless_continue.rs | 16 +- tests/ui/needless_continue.stderr | 36 +-- tests/ui/needless_for_each_fixable.fixed | 16 +- tests/ui/needless_for_each_fixable.rs | 16 +- tests/ui/needless_for_each_unfixable.rs | 3 +- tests/ui/needless_for_each_unfixable.stderr | 4 +- tests/ui/needless_if.fixed | 4 +- tests/ui/needless_if.rs | 4 +- tests/ui/needless_lifetimes.fixed | 76 +++--- tests/ui/needless_lifetimes.rs | 76 +++--- tests/ui/needless_match.rs | 22 +- tests/ui/needless_maybe_sized.fixed | 8 +- tests/ui/needless_maybe_sized.rs | 8 +- tests/ui/needless_option_take.fixed | 8 - tests/ui/needless_option_take.rs | 8 - tests/ui/needless_option_take.stderr | 16 +- tests/ui/needless_pass_by_ref_mut.rs | 46 ++-- tests/ui/needless_pass_by_ref_mut.stderr | 62 ++--- tests/ui/needless_pass_by_ref_mut2.fixed | 4 +- tests/ui/needless_pass_by_ref_mut2.rs | 4 +- tests/ui/needless_pass_by_value.rs | 45 ++-- tests/ui/needless_pass_by_value.stderr | 50 ++-- tests/ui/needless_range_loop.rs | 29 ++- tests/ui/needless_range_loop.stderr | 26 +- tests/ui/needless_range_loop2.rs | 17 +- tests/ui/needless_range_loop2.stderr | 14 +- tests/ui/needless_update.rs | 2 - tests/ui/neg_cmp_op_on_partial_ord.rs | 5 - tests/ui/neg_cmp_op_on_partial_ord.stderr | 6 +- tests/ui/never_loop.rs | 33 ++- tests/ui/never_loop.stderr | 30 +-- tests/ui/new_ret_no_self.rs | 24 +- tests/ui/new_ret_no_self.stderr | 28 ++- tests/ui/new_ret_no_self_overflow.rs | 2 +- tests/ui/new_without_default.fixed | 19 +- tests/ui/new_without_default.rs | 19 +- tests/ui/new_without_default.stderr | 20 +- tests/ui/no_effect.rs | 1 - tests/ui/no_effect.stderr | 6 +- tests/ui/no_effect_async_fn.rs | 4 - tests/ui/no_effect_async_fn.stderr | 6 +- tests/ui/no_effect_replace.rs | 3 - tests/ui/no_effect_replace.stderr | 14 +- tests/ui/no_effect_return.rs | 9 - tests/ui/no_effect_return.stderr | 16 +- tests/ui/no_mangle_with_rust_abi.rs | 2 +- tests/ui/no_mangle_with_rust_abi_2021.rs | 2 +- tests/ui/non_canonical_clone_impl.rs | 8 +- tests/ui/non_canonical_partial_ord_impl.fixed | 4 +- tests/ui/non_canonical_partial_ord_impl.rs | 4 +- ...n_canonical_partial_ord_impl_fully_qual.rs | 4 +- tests/ui/non_expressive_names.rs | 24 +- tests/ui/non_expressive_names.stderr | 36 +-- tests/ui/non_zero_suggestions.fixed | 6 - tests/ui/non_zero_suggestions.rs | 6 - tests/ui/non_zero_suggestions.stderr | 10 +- tests/ui/non_zero_suggestions_unfixable.rs | 2 - .../ui/non_zero_suggestions_unfixable.stderr | 4 +- tests/ui/nonminimal_bool.rs | 59 +++-- tests/ui/nonminimal_bool.stderr | 122 ++++----- tests/ui/nonminimal_bool_methods.fixed | 108 ++++---- tests/ui/nonminimal_bool_methods.rs | 108 ++++---- tests/ui/nonminimal_bool_methods.stderr | 168 ++++++------- tests/ui/nonminimal_bool_methods_unfixable.rs | 6 +- .../nonminimal_bool_methods_unfixable.stderr | 12 +- tests/ui/obfuscated_if_else.fixed | 9 - tests/ui/obfuscated_if_else.rs | 9 - tests/ui/obfuscated_if_else.stderr | 24 +- tests/ui/octal_escapes.rs | 30 ++- tests/ui/octal_escapes.stderr | 102 ++++---- tests/ui/ok_expect.rs | 1 - tests/ui/only_used_in_recursion.rs | 36 ++- tests/ui/only_used_in_recursion.stderr | 56 ++--- tests/ui/only_used_in_recursion2.rs | 10 +- tests/ui/op_ref.fixed | 3 - tests/ui/op_ref.rs | 3 - tests/ui/op_ref.stderr | 6 +- tests/ui/open_options.rs | 5 - tests/ui/open_options.stderr | 14 +- tests/ui/open_options_fixable.fixed | 1 - tests/ui/open_options_fixable.rs | 1 - tests/ui/option_filter_map.fixed | 1 - tests/ui/option_filter_map.rs | 3 - tests/ui/option_filter_map.stderr | 12 +- tests/ui/option_if_let_else.fixed | 12 +- tests/ui/option_if_let_else.rs | 36 +-- tests/ui/option_map_or_none.fixed | 2 +- tests/ui/option_map_or_none.rs | 2 +- tests/ui/or_fun_call.fixed | 3 +- tests/ui/or_fun_call.rs | 3 +- tests/ui/or_fun_call.stderr | 12 +- tests/ui/out_of_bounds_indexing/issue-3102.rs | 2 - .../out_of_bounds_indexing/issue-3102.stderr | 2 +- tests/ui/out_of_bounds_indexing/simple.rs | 2 - tests/ui/out_of_bounds_indexing/simple.stderr | 10 +- tests/ui/panic_in_result_fn.rs | 4 +- tests/ui/panic_in_result_fn.stderr | 18 +- tests/ui/panic_in_result_fn_assertions.rs | 3 - tests/ui/panic_in_result_fn_assertions.stderr | 22 +- tests/ui/panicking_macros.rs | 5 - tests/ui/panicking_macros.stderr | 30 +-- tests/ui/panicking_overflow_checks.rs | 24 +- tests/ui/panicking_overflow_checks.stderr | 36 +-- tests/ui/partial_pub_fields.rs | 4 - tests/ui/partial_pub_fields.stderr | 6 +- tests/ui/partialeq_ne_impl.rs | 3 +- tests/ui/partialeq_ne_impl.stderr | 4 +- tests/ui/partialeq_to_none.fixed | 2 +- tests/ui/partialeq_to_none.rs | 2 +- tests/ui/path_ends_with_ext.fixed | 2 - tests/ui/path_ends_with_ext.rs | 2 - tests/ui/path_ends_with_ext.stderr | 2 +- tests/ui/pathbuf_init_then_push.fixed | 8 +- tests/ui/pathbuf_init_then_push.rs | 16 +- tests/ui/pathbuf_init_then_push.stderr | 16 +- tests/ui/pattern_type_mismatch/mutability.rs | 2 - .../pattern_type_mismatch/mutability.stderr | 2 +- .../pattern_alternatives.rs | 1 - .../pattern_type_mismatch/pattern_structs.rs | 2 - .../pattern_structs.stderr | 10 +- .../pattern_type_mismatch/pattern_tuples.rs | 3 - .../pattern_tuples.stderr | 14 +- tests/ui/pattern_type_mismatch/syntax.rs | 9 +- tests/ui/pattern_type_mismatch/syntax.stderr | 16 +- tests/ui/patterns.fixed | 2 +- tests/ui/patterns.rs | 2 +- tests/ui/permissions_set_readonly_false.rs | 1 - tests/ui/pointers_in_nomem_asm_block.rs | 2 - tests/ui/pointers_in_nomem_asm_block.stderr | 2 +- tests/ui/print.rs | 9 - tests/ui/print.stderr | 14 +- tests/ui/print_in_format_impl.rs | 1 - tests/ui/print_in_format_impl.stderr | 12 +- tests/ui/print_literal.fixed | 4 - tests/ui/print_literal.rs | 4 - tests/ui/print_literal.stderr | 34 +-- tests/ui/print_stderr.rs | 1 - tests/ui/print_stderr.stderr | 2 +- tests/ui/print_with_newline.fixed | 8 +- tests/ui/print_with_newline.rs | 8 +- tests/ui/print_with_newline.stderr | 20 +- tests/ui/ptr_arg.rs | 51 ++-- tests/ui/ptr_arg.stderr | 52 ++-- tests/ui/pub_use.rs | 1 - tests/ui/question_mark.rs | 32 +-- tests/ui/rc_clone_in_vec_init/arc.rs | 4 - tests/ui/rc_clone_in_vec_init/arc.stderr | 6 +- tests/ui/rc_clone_in_vec_init/rc.rs | 4 - tests/ui/rc_clone_in_vec_init/rc.stderr | 6 +- tests/ui/rc_clone_in_vec_init/weak.rs | 9 - tests/ui/rc_clone_in_vec_init/weak.stderr | 14 +- tests/ui/rc_mutex.rs | 1 - tests/ui/read_line_without_trim.fixed | 4 +- tests/ui/read_line_without_trim.rs | 4 +- tests/ui/readonly_write_lock.fixed | 1 - tests/ui/readonly_write_lock.rs | 1 - tests/ui/readonly_write_lock.stderr | 2 +- tests/ui/recursive_format_impl.rs | 11 - tests/ui/recursive_format_impl.stderr | 18 +- tests/ui/redundant_allocation.rs | 49 +--- tests/ui/redundant_allocation.stderr | 38 +-- tests/ui/redundant_clone.fixed | 2 +- tests/ui/redundant_clone.rs | 2 +- tests/ui/redundant_closure_call_early.rs | 3 - tests/ui/redundant_closure_call_early.stderr | 2 +- tests/ui/redundant_closure_call_fixable.fixed | 4 +- tests/ui/redundant_closure_call_fixable.rs | 4 +- tests/ui/redundant_closure_call_late.rs | 3 - tests/ui/redundant_closure_call_late.stderr | 4 +- tests/ui/redundant_else.fixed | 14 +- tests/ui/redundant_else.rs | 14 +- tests/ui/redundant_else.stderr | 14 +- tests/ui/redundant_field_names.fixed | 1 - tests/ui/redundant_field_names.rs | 1 - tests/ui/redundant_field_names.stderr | 14 +- tests/ui/redundant_guards.fixed | 2 +- tests/ui/redundant_guards.rs | 2 +- ...edundant_pattern_matching_drop_order.fixed | 6 +- .../redundant_pattern_matching_drop_order.rs | 6 +- ...dundant_pattern_matching_if_let_true.fixed | 4 +- .../redundant_pattern_matching_if_let_true.rs | 4 +- .../redundant_pattern_matching_ipaddr.fixed | 6 +- tests/ui/redundant_pattern_matching_ipaddr.rs | 18 +- .../redundant_pattern_matching_option.fixed | 8 +- tests/ui/redundant_pattern_matching_option.rs | 26 +- .../ui/redundant_pattern_matching_poll.fixed | 6 +- tests/ui/redundant_pattern_matching_poll.rs | 16 +- .../redundant_pattern_matching_result.fixed | 4 +- tests/ui/redundant_pattern_matching_result.rs | 24 +- tests/ui/redundant_pub_crate.fixed | 6 +- tests/ui/redundant_pub_crate.rs | 6 +- .../ui/redundant_static_lifetimes_multiple.rs | 11 - ...redundant_static_lifetimes_multiple.stderr | 16 +- tests/ui/redundant_type_annotations.rs | 16 -- tests/ui/redundant_type_annotations.stderr | 32 +-- tests/ui/ref_binding_to_reference.rs | 13 +- tests/ui/ref_binding_to_reference.stderr | 12 +- tests/ui/ref_option/ref_option.all.fixed | 10 +- tests/ui/ref_option/ref_option.private.fixed | 10 +- tests/ui/ref_option/ref_option.rs | 10 +- tests/ui/ref_option_ref.rs | 11 +- tests/ui/ref_option_ref.stderr | 20 +- tests/ui/ref_patterns.rs | 3 - tests/ui/ref_patterns.stderr | 4 +- tests/ui/repeat_vec_with_capacity.fixed | 3 - tests/ui/repeat_vec_with_capacity.rs | 3 - tests/ui/repeat_vec_with_capacity.stderr | 4 +- tests/ui/repl_uninit.rs | 1 - tests/ui/repl_uninit.stderr | 6 +- tests/ui/repr_packed_without_abi.rs | 4 +- tests/ui/rest_pat_in_fully_bound_structs.rs | 3 - .../ui/rest_pat_in_fully_bound_structs.stderr | 4 +- tests/ui/result_filter_map.rs | 4 - tests/ui/result_filter_map.stderr | 14 +- tests/ui/result_large_err.rs | 24 +- tests/ui/result_map_or_into_option.fixed | 1 - tests/ui/result_map_or_into_option.rs | 1 - tests/ui/result_unit_error.rs | 9 +- tests/ui/result_unit_error.stderr | 6 +- tests/ui/result_unit_error_no_std.rs | 2 +- tests/ui/return_and_then.fixed | 8 +- tests/ui/return_and_then.rs | 4 +- tests/ui/return_and_then.stderr | 6 +- tests/ui/return_self_not_must_use.rs | 4 +- .../reversed_empty_ranges_loops_fixable.fixed | 12 +- .../ui/reversed_empty_ranges_loops_fixable.rs | 12 +- .../reversed_empty_ranges_loops_unfixable.rs | 5 +- ...versed_empty_ranges_loops_unfixable.stderr | 2 +- tests/ui/reversed_empty_ranges_unfixable.rs | 3 - .../ui/reversed_empty_ranges_unfixable.stderr | 4 +- tests/ui/same_functions_in_if_condition.rs | 18 +- .../ui/same_functions_in_if_condition.stderr | 20 +- tests/ui/same_item_push.rs | 6 - tests/ui/same_item_push.stderr | 10 +- tests/ui/same_name_method.rs | 6 - tests/ui/same_name_method.stderr | 22 +- tests/ui/search_is_some_fixable_none.fixed | 4 +- tests/ui/search_is_some_fixable_none.rs | 6 +- tests/ui/self_assignment.rs | 3 - tests/ui/self_assignment.stderr | 20 +- tests/ui/self_named_constructors.rs | 3 +- tests/ui/self_named_constructors.stderr | 4 +- tests/ui/set_contains_or_insert.rs | 28 +-- tests/ui/shadow.rs | 6 +- tests/ui/short_circuit_statement.fixed | 2 - tests/ui/short_circuit_statement.rs | 2 - tests/ui/short_circuit_statement.stderr | 4 +- tests/ui/should_impl_trait/method_list_1.rs | 30 +-- tests/ui/should_impl_trait/method_list_2.rs | 30 +-- tests/ui/significant_drop_in_scrutinee.rs | 62 ++--- tests/ui/similar_names.rs | 5 - tests/ui/similar_names.stderr | 16 +- tests/ui/single_call_fn.rs | 2 +- tests/ui/single_char_lifetime_names.rs | 9 +- tests/ui/single_char_lifetime_names.stderr | 6 +- ...gle_component_path_imports_nested_first.rs | 3 - ...component_path_imports_nested_first.stderr | 4 +- tests/ui/single_element_loop.fixed | 16 +- tests/ui/single_element_loop.rs | 16 +- tests/ui/single_option_map.rs | 6 +- .../size_of_in_element_count/expressions.rs | 4 - .../expressions.stderr | 6 +- .../ui/size_of_in_element_count/functions.rs | 7 - .../size_of_in_element_count/functions.stderr | 34 +-- tests/ui/size_of_ref.rs | 2 - tests/ui/size_of_ref.stderr | 2 +- tests/ui/slow_vector_initialization.rs | 1 - tests/ui/slow_vector_initialization.stderr | 24 +- tests/ui/starts_ends_with.fixed | 12 +- tests/ui/starts_ends_with.rs | 12 +- tests/ui/str_to_string.fixed | 1 - tests/ui/str_to_string.rs | 1 - tests/ui/string_slice.rs | 2 - tests/ui/string_slice.stderr | 6 +- tests/ui/string_to_string.rs | 1 - tests/ui/struct_excessive_bools.rs | 6 +- tests/ui/struct_excessive_bools.stderr | 10 +- tests/ui/suspicious_arithmetic_impl.rs | 11 - tests/ui/suspicious_arithmetic_impl.stderr | 16 +- tests/ui/suspicious_command_arg_space.fixed | 2 - tests/ui/suspicious_command_arg_space.rs | 2 - tests/ui/suspicious_command_arg_space.stderr | 2 +- tests/ui/suspicious_doc_comments.fixed | 2 +- tests/ui/suspicious_doc_comments.rs | 2 +- tests/ui/suspicious_doc_comments.stderr | 2 - tests/ui/suspicious_doc_comments_unfixable.rs | 1 - .../suspicious_doc_comments_unfixable.stderr | 7 +- tests/ui/suspicious_map.rs | 2 - tests/ui/suspicious_map.stderr | 2 +- tests/ui/suspicious_operation_groupings.fixed | 2 +- tests/ui/suspicious_operation_groupings.rs | 2 +- tests/ui/suspicious_splitn.rs | 11 - tests/ui/suspicious_splitn.stderr | 16 +- tests/ui/suspicious_to_owned.rs | 3 - tests/ui/suspicious_to_owned.stderr | 10 +- tests/ui/suspicious_xor_used_as_pow.rs | 1 - tests/ui/suspicious_xor_used_as_pow.stderr | 10 +- tests/ui/swap_ptr_to_ref_unfixable.rs | 2 - tests/ui/swap_ptr_to_ref_unfixable.stderr | 4 +- .../non_expressive_names_error_recovery.fixed | 1 + .../non_expressive_names_error_recovery.rs | 1 + tests/ui/temporary_assignment.rs | 5 +- tests/ui/temporary_assignment.stderr | 10 +- tests/ui/test_attr_in_doctest.rs | 9 +- tests/ui/test_attr_in_doctest.stderr | 4 +- tests/ui/to_string_trait_impl.rs | 2 +- tests/ui/toplevel_ref_arg_non_rustfix.rs | 2 +- tests/ui/trailing_empty_array.rs | 29 +-- tests/ui/trailing_empty_array.stderr | 30 +-- tests/ui/trailing_zeros.fixed | 1 - tests/ui/trailing_zeros.rs | 1 - tests/ui/trailing_zeros.stderr | 2 +- tests/ui/trait_duplication_in_bounds.fixed | 17 +- tests/ui/trait_duplication_in_bounds.rs | 17 +- tests/ui/trait_duplication_in_bounds.stderr | 4 +- .../trait_duplication_in_bounds_unfixable.rs | 16 +- ...ait_duplication_in_bounds_unfixable.stderr | 12 +- tests/ui/transmute.rs | 32 --- tests/ui/transmute.stderr | 124 +++++----- tests/ui/transmute_64bit.rs | 3 - tests/ui/transmute_64bit.stderr | 2 +- tests/ui/transmute_collection.rs | 8 - tests/ui/transmute_collection.stderr | 34 +-- tests/ui/transmute_float_to_int.fixed | 7 - tests/ui/transmute_float_to_int.rs | 7 - tests/ui/transmute_float_to_int.stderr | 26 +- tests/ui/transmute_int_to_char.fixed | 2 - tests/ui/transmute_int_to_char.rs | 2 - tests/ui/transmute_int_to_char.stderr | 2 +- tests/ui/transmute_int_to_char_no_std.fixed | 2 - tests/ui/transmute_int_to_char_no_std.rs | 2 - tests/ui/transmute_int_to_char_no_std.stderr | 2 +- tests/ui/transmute_int_to_non_zero.fixed | 3 - tests/ui/transmute_int_to_non_zero.rs | 3 - tests/ui/transmute_int_to_non_zero.stderr | 18 +- tests/ui/transmute_null_to_fn.rs | 2 - tests/ui/transmute_null_to_fn.stderr | 8 +- tests/ui/transmute_ptr_to_ptr.fixed | 2 - tests/ui/transmute_ptr_to_ptr.rs | 2 - tests/ui/transmute_ptr_to_ptr.stderr | 14 +- tests/ui/transmute_ref_to_ref.rs | 1 - tests/ui/transmute_ref_to_ref_no_std.rs | 1 - tests/ui/transmute_undefined_repr.rs | 17 -- tests/ui/transmute_undefined_repr.stderr | 22 +- tests/ui/transmuting_null.rs | 2 - tests/ui/transmuting_null.stderr | 4 +- tests/ui/type_complexity.rs | 12 +- tests/ui/type_complexity.stderr | 28 +-- tests/ui/type_id_on_box.fixed | 4 - tests/ui/type_id_on_box.rs | 4 - tests/ui/type_id_on_box.stderr | 6 +- tests/ui/type_id_on_box_unfixable.rs | 2 - tests/ui/type_id_on_box_unfixable.stderr | 2 +- tests/ui/unbuffered_bytes.rs | 4 + tests/ui/unbuffered_bytes.stderr | 6 +- tests/ui/unconditional_recursion.rs | 40 +-- tests/ui/uninhabited_references.rs | 4 +- tests/ui/uninit.rs | 4 - tests/ui/uninit.stderr | 4 +- tests/ui/uninlined_format_args.fixed | 6 +- tests/ui/uninlined_format_args.rs | 6 +- tests/ui/unit_arg.rs | 10 +- tests/ui/unit_cmp.rs | 17 +- tests/ui/unit_cmp.stderr | 27 +- tests/ui/unit_hash.fixed | 6 - tests/ui/unit_hash.rs | 6 - tests/ui/unit_hash.stderr | 4 +- tests/ui/unit_return_expecting_ord.rs | 7 +- tests/ui/unnecessary_box_returns.rs | 7 +- tests/ui/unnecessary_box_returns.stderr | 6 +- tests/ui/unnecessary_cast_unfixable.rs | 3 - tests/ui/unnecessary_cast_unfixable.stderr | 2 +- tests/ui/unnecessary_clippy_cfg.rs | 7 - tests/ui/unnecessary_clippy_cfg.stderr | 26 +- tests/ui/unnecessary_clone.rs | 6 - tests/ui/unnecessary_clone.stderr | 16 +- .../ui/unnecessary_fallible_conversions.fixed | 10 - tests/ui/unnecessary_fallible_conversions.rs | 10 - .../unnecessary_fallible_conversions.stderr | 18 +- tests/ui/unnecessary_filter_map.rs | 7 +- tests/ui/unnecessary_filter_map.stderr | 15 +- tests/ui/unnecessary_find_map.rs | 7 +- tests/ui/unnecessary_find_map.stderr | 9 +- tests/ui/unnecessary_fold.fixed | 2 +- tests/ui/unnecessary_fold.rs | 2 +- tests/ui/unnecessary_get_then_check.fixed | 40 +-- tests/ui/unnecessary_get_then_check.rs | 40 +-- tests/ui/unnecessary_get_then_check.stderr | 80 +++--- tests/ui/unnecessary_iter_cloned.fixed | 14 +- tests/ui/unnecessary_iter_cloned.rs | 14 +- tests/ui/unnecessary_iter_cloned.stderr | 4 +- tests/ui/unnecessary_lazy_eval_unfixable.rs | 2 - .../ui/unnecessary_lazy_eval_unfixable.stderr | 6 +- tests/ui/unnecessary_literal_bound.fixed | 6 +- tests/ui/unnecessary_literal_bound.rs | 6 +- .../unnecessary_literal_unwrap_unfixable.rs | 16 -- ...nnecessary_literal_unwrap_unfixable.stderr | 196 +++++++-------- tests/ui/unnecessary_map_or.fixed | 2 +- tests/ui/unnecessary_map_or.rs | 4 +- tests/ui/unnecessary_operation.fixed | 1 - tests/ui/unnecessary_operation.rs | 5 +- tests/ui/unnecessary_result_map_or_else.fixed | 12 +- tests/ui/unnecessary_result_map_or_else.rs | 15 +- .../ui/unnecessary_result_map_or_else.stderr | 20 +- tests/ui/unnecessary_safety_comment.rs | 4 - tests/ui/unnecessary_safety_comment.stderr | 16 +- .../unnecessary_semicolon.edition2021.fixed | 2 - .../unnecessary_semicolon.edition2021.stderr | 4 +- .../unnecessary_semicolon.edition2024.fixed | 2 - .../unnecessary_semicolon.edition2024.stderr | 6 +- tests/ui/unnecessary_semicolon.rs | 2 - tests/ui/unnecessary_struct_initialization.rs | 4 +- tests/ui/unnecessary_to_owned.fixed | 22 +- tests/ui/unnecessary_to_owned.rs | 22 +- tests/ui/unnecessary_to_owned.stderr | 30 +-- tests/ui/unnecessary_to_owned_on_split.fixed | 2 - tests/ui/unnecessary_to_owned_on_split.rs | 2 - tests/ui/unnecessary_to_owned_on_split.stderr | 8 +- tests/ui/unnecessary_unsafety_doc.rs | 12 +- tests/ui/unnecessary_wraps.rs | 15 +- tests/ui/unnecessary_wraps.stderr | 15 +- tests/ui/unneeded_field_pattern.rs | 1 - tests/ui/unneeded_field_pattern.stderr | 2 +- tests/ui/unneeded_struct_pattern.fixed | 20 +- tests/ui/unneeded_struct_pattern.rs | 26 +- tests/ui/unneeded_struct_pattern.stderr | 4 +- tests/ui/unsafe_removed_from_name.rs | 6 - tests/ui/unsafe_removed_from_name.stderr | 8 +- tests/ui/unused_async.rs | 7 +- tests/ui/unused_async.stderr | 4 +- tests/ui/unused_enumerate_index.fixed | 4 +- tests/ui/unused_enumerate_index.rs | 4 +- tests/ui/unused_format_specs.1.fixed | 7 - tests/ui/unused_format_specs.2.fixed | 7 - tests/ui/unused_format_specs.rs | 7 - tests/ui/unused_format_specs.stderr | 14 +- tests/ui/unused_io_amount.rs | 16 +- tests/ui/unused_peekable.rs | 5 - tests/ui/unused_peekable.stderr | 14 +- tests/ui/unused_self.rs | 4 +- tests/ui/unwrap.rs | 2 - tests/ui/unwrap.stderr | 4 +- tests/ui/unwrap_expect_used.rs | 1 - tests/ui/unwrap_expect_used.stderr | 8 +- tests/ui/unwrap_in_result.rs | 6 +- tests/ui/unwrap_or.fixed | 3 - tests/ui/unwrap_or.rs | 3 - tests/ui/unwrap_or.stderr | 2 +- tests/ui/upper_case_acronyms.fixed | 15 +- tests/ui/upper_case_acronyms.rs | 15 +- tests/ui/upper_case_acronyms.stderr | 22 +- tests/ui/use_self.fixed | 22 +- tests/ui/use_self.rs | 22 +- tests/ui/use_self_trait.fixed | 20 +- tests/ui/use_self_trait.rs | 20 +- tests/ui/useless_asref.fixed | 3 - tests/ui/useless_asref.rs | 3 - tests/ui/useless_asref.stderr | 8 +- tests/ui/useless_conversion.fixed | 9 - tests/ui/useless_conversion.rs | 9 - tests/ui/useless_conversion.stderr | 28 +-- tests/ui/useless_conversion_try.rs | 4 +- tests/ui/useless_conversion_try.stderr | 14 +- tests/ui/useless_nonzero_new_unchecked.fixed | 5 - tests/ui/useless_nonzero_new_unchecked.rs | 5 - tests/ui/useless_nonzero_new_unchecked.stderr | 8 +- tests/ui/useless_vec.rs | 3 +- tests/ui/useless_vec.stderr | 1 - tests/ui/vec.fixed | 10 +- tests/ui/vec.rs | 10 +- tests/ui/vec.stderr | 6 +- tests/ui/vec_box_sized.rs | 8 +- tests/ui/vec_init_then_push.rs | 1 - tests/ui/vec_init_then_push.stderr | 14 +- tests/ui/vec_resize_to_zero.fixed | 1 - tests/ui/vec_resize_to_zero.rs | 1 - tests/ui/while_float.rs | 4 +- tests/ui/while_let_loop.rs | 11 +- tests/ui/while_let_loop.stderr | 11 +- tests/ui/while_let_on_iterator.fixed | 50 ++-- tests/ui/while_let_on_iterator.rs | 50 ++-- tests/ui/wild_in_or_pats.rs | 12 +- tests/ui/write_literal.fixed | 5 - tests/ui/write_literal.rs | 5 - tests/ui/write_literal.stderr | 26 +- tests/ui/write_literal_2.rs | 8 +- tests/ui/write_literal_2.stderr | 20 +- tests/ui/write_with_newline.fixed | 8 +- tests/ui/write_with_newline.rs | 8 +- tests/ui/write_with_newline.stderr | 20 +- tests/ui/wrong_self_convention.rs | 7 +- tests/ui/wrong_self_convention.stderr | 46 ++-- tests/ui/wrong_self_convention2.rs | 3 +- tests/ui/wrong_self_conventions_mut.rs | 4 +- tests/ui/zero_offset.rs | 3 - tests/ui/zero_offset.stderr | 14 +- tests/ui/zero_sized_btreemap_values.rs | 16 +- tests/ui/zero_sized_btreemap_values.stderr | 24 +- tests/ui/zero_sized_hashmap_values.rs | 16 +- tests/ui/zero_sized_hashmap_values.stderr | 24 +- 1025 files changed, 6097 insertions(+), 7930 deletions(-) diff --git a/tests/ui/as_pointer_underscore.fixed b/tests/ui/as_pointer_underscore.fixed index 374c8a7f611a..93daae6bc668 100644 --- a/tests/ui/as_pointer_underscore.fixed +++ b/tests/ui/as_pointer_underscore.fixed @@ -7,11 +7,9 @@ struct S; fn f(s: &S) -> usize { &s as *const &S as usize //~^ as_pointer_underscore - } fn g(s: &mut S) -> usize { s as *mut S as usize //~^ as_pointer_underscore - } diff --git a/tests/ui/as_pointer_underscore.rs b/tests/ui/as_pointer_underscore.rs index b194b3f473e2..56f1a8935255 100644 --- a/tests/ui/as_pointer_underscore.rs +++ b/tests/ui/as_pointer_underscore.rs @@ -7,11 +7,9 @@ struct S; fn f(s: &S) -> usize { &s as *const _ as usize //~^ as_pointer_underscore - } fn g(s: &mut S) -> usize { s as *mut _ as usize //~^ as_pointer_underscore - } diff --git a/tests/ui/as_pointer_underscore.stderr b/tests/ui/as_pointer_underscore.stderr index fd9f061322b5..270056f36454 100644 --- a/tests/ui/as_pointer_underscore.stderr +++ b/tests/ui/as_pointer_underscore.stderr @@ -8,7 +8,7 @@ LL | &s as *const _ as usize = help: to override `-D warnings` add `#[allow(clippy::as_pointer_underscore)]` error: using inferred pointer cast - --> tests/ui/as_pointer_underscore.rs:14:10 + --> tests/ui/as_pointer_underscore.rs:13:10 | LL | s as *mut _ as usize | ^^^^^^ help: use explicit type: `*mut S` diff --git a/tests/ui/as_ptr_cast_mut.rs b/tests/ui/as_ptr_cast_mut.rs index 751e4a70b0fa..baf7279adc4a 100644 --- a/tests/ui/as_ptr_cast_mut.rs +++ b/tests/ui/as_ptr_cast_mut.rs @@ -22,7 +22,6 @@ fn main() { let _ = string.as_ptr() as *mut u8; //~^ as_ptr_cast_mut - let _: *mut i8 = string.as_ptr() as *mut _; //~^ as_ptr_cast_mut diff --git a/tests/ui/as_ptr_cast_mut.stderr b/tests/ui/as_ptr_cast_mut.stderr index 67dd7ddb8291..b3fc223ccdba 100644 --- a/tests/ui/as_ptr_cast_mut.stderr +++ b/tests/ui/as_ptr_cast_mut.stderr @@ -8,7 +8,7 @@ LL | let _ = string.as_ptr() as *mut u8; = help: to override `-D warnings` add `#[allow(clippy::as_ptr_cast_mut)]` error: casting the result of `as_ptr` to *mut i8 - --> tests/ui/as_ptr_cast_mut.rs:26:22 + --> tests/ui/as_ptr_cast_mut.rs:25:22 | LL | let _: *mut i8 = string.as_ptr() as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `string.as_mut_ptr()` diff --git a/tests/ui/asm_syntax_x86.rs b/tests/ui/asm_syntax_x86.rs index 0d30b95dcf5e..4e91f27cd318 100644 --- a/tests/ui/asm_syntax_x86.rs +++ b/tests/ui/asm_syntax_x86.rs @@ -40,14 +40,12 @@ mod warn_att { asm!("", options(nostack, att_syntax)); //~^ inline_asm_x86_att_syntax - } global_asm!(""); global_asm!("", options()); global_asm!("", options(att_syntax)); //~^ inline_asm_x86_att_syntax - } fn main() { diff --git a/tests/ui/asm_syntax_x86.stderr b/tests/ui/asm_syntax_x86.stderr index 8e1992b66bca..2dcd955f0347 100644 --- a/tests/ui/asm_syntax_x86.stderr +++ b/tests/ui/asm_syntax_x86.stderr @@ -59,7 +59,7 @@ LL | asm!("", options(nostack, att_syntax)); = help: use Intel x86 assembly syntax error: AT&T x86 assembly syntax used - --> tests/ui/asm_syntax_x86.rs:48:5 + --> tests/ui/asm_syntax_x86.rs:47:5 | LL | global_asm!("", options(att_syntax)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/assertions_on_constants.rs b/tests/ui/assertions_on_constants.rs index 96b9c16d4303..c2516c541475 100644 --- a/tests/ui/assertions_on_constants.rs +++ b/tests/ui/assertions_on_constants.rs @@ -19,17 +19,14 @@ fn main() { assert!(false, "false message"); //~^ assertions_on_constants - let msg = "panic message"; assert!(false, "{}", msg.to_uppercase()); //~^ assertions_on_constants - const B: bool = true; assert!(B); //~^ assertions_on_constants - const C: bool = false; assert!(C); //~^ assertions_on_constants @@ -37,7 +34,6 @@ fn main() { assert!(C, "C message"); //~^ assertions_on_constants - debug_assert!(true); //~^ assertions_on_constants @@ -58,11 +54,9 @@ fn main() { const _: () = assert!(true); //~^ assertions_on_constants - assert!(8 == (7 + 1)); //~^ assertions_on_constants - // Don't lint if the value is dependent on a defined constant: const N: usize = 1024; const _: () = assert!(N.is_power_of_two()); diff --git a/tests/ui/assertions_on_constants.stderr b/tests/ui/assertions_on_constants.stderr index b0e6496982f9..8b7440ec4832 100644 --- a/tests/ui/assertions_on_constants.stderr +++ b/tests/ui/assertions_on_constants.stderr @@ -33,7 +33,7 @@ LL | assert!(false, "false message"); = help: use `panic!(..)` or `unreachable!(..)` error: `assert!(false, ..)` should probably be replaced - --> tests/ui/assertions_on_constants.rs:24:5 + --> tests/ui/assertions_on_constants.rs:23:5 | LL | assert!(false, "{}", msg.to_uppercase()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | assert!(false, "{}", msg.to_uppercase()); = help: use `panic!(..)` or `unreachable!(..)` error: `assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:29:5 + --> tests/ui/assertions_on_constants.rs:27:5 | LL | assert!(B); | ^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | assert!(B); = help: remove it error: `assert!(false)` should probably be replaced - --> tests/ui/assertions_on_constants.rs:34:5 + --> tests/ui/assertions_on_constants.rs:31:5 | LL | assert!(C); | ^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | assert!(C); = help: use `panic!()` or `unreachable!()` error: `assert!(false, ..)` should probably be replaced - --> tests/ui/assertions_on_constants.rs:37:5 + --> tests/ui/assertions_on_constants.rs:34:5 | LL | assert!(C, "C message"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | assert!(C, "C message"); = help: use `panic!(..)` or `unreachable!(..)` error: `debug_assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:41:5 + --> tests/ui/assertions_on_constants.rs:37:5 | LL | debug_assert!(true); | ^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | debug_assert!(true); = help: remove it error: `assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:58:19 + --> tests/ui/assertions_on_constants.rs:54:19 | LL | const _: () = assert!(true); | ^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | const _: () = assert!(true); = help: remove it error: `assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:62:5 + --> tests/ui/assertions_on_constants.rs:57:5 | LL | assert!(8 == (7 + 1)); | ^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | assert!(8 == (7 + 1)); = help: remove it error: `assert!(true)` will be optimized out by the compiler - --> tests/ui/assertions_on_constants.rs:72:5 + --> tests/ui/assertions_on_constants.rs:66:5 | LL | assert!(true); | ^^^^^^^^^^^^^ diff --git a/tests/ui/assign_ops2.rs b/tests/ui/assign_ops2.rs index 7cac9f51ea4e..51867fa6962c 100644 --- a/tests/ui/assign_ops2.rs +++ b/tests/ui/assign_ops2.rs @@ -8,7 +8,6 @@ fn main() { a += a + 1; //~^ misrefactored_assign_op - a += 1 + a; //~^ misrefactored_assign_op @@ -72,8 +71,6 @@ fn cow_add_assign() { buf = buf + cows.clone(); //~^ assign_op_pattern - - // this should not as cow Add is not commutative buf = cows + buf; println!("{}", buf); diff --git a/tests/ui/assign_ops2.stderr b/tests/ui/assign_ops2.stderr index 56b5219dd646..19deebe17850 100644 --- a/tests/ui/assign_ops2.stderr +++ b/tests/ui/assign_ops2.stderr @@ -16,7 +16,7 @@ LL | a = a + a + 1; | ~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:12:5 + --> tests/ui/assign_ops2.rs:11:5 | LL | a += 1 + a; | ^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | a = a + 1 + a; | ~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:15:5 + --> tests/ui/assign_ops2.rs:14:5 | LL | a -= a - 1; | ^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | a = a - (a - 1); | ~~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:18:5 + --> tests/ui/assign_ops2.rs:17:5 | LL | a *= a * 99; | ^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | a = a * a * 99; | ~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:21:5 + --> tests/ui/assign_ops2.rs:20:5 | LL | a *= 42 * a; | ^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | a = a * 42 * a; | ~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:24:5 + --> tests/ui/assign_ops2.rs:23:5 | LL | a /= a / 2; | ^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | a = a / (a / 2); | ~~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:27:5 + --> tests/ui/assign_ops2.rs:26:5 | LL | a %= a % 5; | ^^^^^^^^^^ @@ -106,7 +106,7 @@ LL | a = a % (a % 5); | ~~~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:30:5 + --> tests/ui/assign_ops2.rs:29:5 | LL | a &= a & 1; | ^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | a = a & a & 1; | ~~~~~~~~~~~~~ error: variable appears on both sides of an assignment operation - --> tests/ui/assign_ops2.rs:33:5 + --> tests/ui/assign_ops2.rs:32:5 | LL | a *= a * a; | ^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | a = a * a * a; | ~~~~~~~~~~~~~ error: manual implementation of an assign operation - --> tests/ui/assign_ops2.rs:72:5 + --> tests/ui/assign_ops2.rs:71:5 | LL | buf = buf + cows.clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `buf += cows.clone()` diff --git a/tests/ui/attrs.rs b/tests/ui/attrs.rs index 32e4053e74b0..583a0ada437d 100644 --- a/tests/ui/attrs.rs +++ b/tests/ui/attrs.rs @@ -5,7 +5,6 @@ #[inline(always)] //~^ inline_always - fn test_attr_lint() { assert!(true) } @@ -28,7 +27,6 @@ fn empty_and_false_positive_stmt() { #[deprecated(since = "forever")] //~^ deprecated_semver - pub const SOME_CONST: u8 = 42; #[deprecated(since = "1")] diff --git a/tests/ui/attrs.stderr b/tests/ui/attrs.stderr index f4803380cc41..a7fdceaba6f3 100644 --- a/tests/ui/attrs.stderr +++ b/tests/ui/attrs.stderr @@ -1,5 +1,5 @@ error: the since field must contain a semver-compliant version - --> tests/ui/attrs.rs:28:14 + --> tests/ui/attrs.rs:27:14 | LL | #[deprecated(since = "forever")] | ^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #[deprecated(since = "forever")] = help: to override `-D warnings` add `#[allow(clippy::deprecated_semver)]` error: the since field must contain a semver-compliant version - --> tests/ui/attrs.rs:34:14 + --> tests/ui/attrs.rs:32:14 | LL | #[deprecated(since = "1")] | ^^^^^^^^^^^ diff --git a/tests/ui/await_holding_refcell_ref.rs b/tests/ui/await_holding_refcell_ref.rs index 258e16c07e04..e1db2e387497 100644 --- a/tests/ui/await_holding_refcell_ref.rs +++ b/tests/ui/await_holding_refcell_ref.rs @@ -36,7 +36,6 @@ async fn also_bad(x: &RefCell) -> u32 { let b = x.borrow_mut(); //~^ await_holding_refcell_ref - let second = baz().await; let third = baz().await; @@ -50,7 +49,6 @@ async fn less_bad(x: &RefCell) -> u32 { let b = x.borrow_mut(); //~^ await_holding_refcell_ref - let second = baz().await; drop(b); diff --git a/tests/ui/await_holding_refcell_ref.stderr b/tests/ui/await_holding_refcell_ref.stderr index ce7c71ae8fec..ed8aa747bd07 100644 --- a/tests/ui/await_holding_refcell_ref.stderr +++ b/tests/ui/await_holding_refcell_ref.stderr @@ -34,7 +34,7 @@ LL | let b = x.borrow_mut(); | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:40:24 + --> tests/ui/await_holding_refcell_ref.rs:39:24 | LL | let second = baz().await; | ^^^^^ @@ -43,40 +43,40 @@ LL | let third = baz().await; | ^^^^^ error: this `RefCell` reference is held across an await point - --> tests/ui/await_holding_refcell_ref.rs:50:9 + --> tests/ui/await_holding_refcell_ref.rs:49:9 | LL | let b = x.borrow_mut(); | ^ | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:54:24 + --> tests/ui/await_holding_refcell_ref.rs:52:24 | LL | let second = baz().await; | ^^^^^ error: this `RefCell` reference is held across an await point - --> tests/ui/await_holding_refcell_ref.rs:67:13 + --> tests/ui/await_holding_refcell_ref.rs:65:13 | LL | let b = x.borrow_mut(); | ^ | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:70:15 + --> tests/ui/await_holding_refcell_ref.rs:68:15 | LL | baz().await | ^^^^^ error: this `RefCell` reference is held across an await point - --> tests/ui/await_holding_refcell_ref.rs:81:13 + --> tests/ui/await_holding_refcell_ref.rs:79:13 | LL | let b = x.borrow_mut(); | ^ | = help: ensure the reference is dropped before calling `await` note: these are all the await points this reference is held through - --> tests/ui/await_holding_refcell_ref.rs:84:15 + --> tests/ui/await_holding_refcell_ref.rs:82:15 | LL | baz().await | ^^^^^ diff --git a/tests/ui/bind_instead_of_map_multipart.fixed b/tests/ui/bind_instead_of_map_multipart.fixed index a1da2cfc9fc6..b61ce97fe8e6 100644 --- a/tests/ui/bind_instead_of_map_multipart.fixed +++ b/tests/ui/bind_instead_of_map_multipart.fixed @@ -20,7 +20,7 @@ pub fn main() { fn hard_example() { Some("42").map(|s| { - //~^ bind_instead_of_map + //~^ bind_instead_of_map if { if s == "43" { return 43; diff --git a/tests/ui/bind_instead_of_map_multipart.rs b/tests/ui/bind_instead_of_map_multipart.rs index 5710254ddf6e..37f406def197 100644 --- a/tests/ui/bind_instead_of_map_multipart.rs +++ b/tests/ui/bind_instead_of_map_multipart.rs @@ -20,7 +20,7 @@ pub fn main() { fn hard_example() { Some("42").and_then(|s| { - //~^ bind_instead_of_map + //~^ bind_instead_of_map if { if s == "43" { return Some(43); diff --git a/tests/ui/bit_masks.rs b/tests/ui/bit_masks.rs index b38523a03960..87dcdb3084d0 100644 --- a/tests/ui/bit_masks.rs +++ b/tests/ui/bit_masks.rs @@ -15,9 +15,6 @@ fn main() { //~^ bad_bit_mask //~| erasing_op - - - x & 1 == 1; //ok, distinguishes bit 0 x & 1 == 0; //ok, compared with zero x & 2 == 1; @@ -29,7 +26,6 @@ fn main() { x | 3 == 2; //~^ bad_bit_mask - x & 1 > 1; //~^ bad_bit_mask @@ -51,12 +47,10 @@ fn main() { x | EVEN_MORE_REDIRECTION < 7; //~^ bad_bit_mask - 0 & x == 0; //~^ bad_bit_mask //~| erasing_op - 1 | x > 1; // and should now also match uncommon usage @@ -69,7 +63,6 @@ fn main() { 1 == x & 2; //~^ bad_bit_mask - x | 1 > 2; // no error, because we allowed ineffective bit masks ineffective(); } @@ -82,7 +75,6 @@ fn ineffective() { x | 1 > 3; //~^ ineffective_bit_mask - x | 1 < 4; //~^ ineffective_bit_mask @@ -92,7 +84,6 @@ fn ineffective() { x | 1 >= 8; //~^ ineffective_bit_mask - x | 1 > 2; // not an error (yet), better written as x >= 2 x | 1 >= 7; // not an error (yet), better written as x >= 6 x | 3 > 4; // not an error (yet), better written as x >= 4 diff --git a/tests/ui/bit_masks.stderr b/tests/ui/bit_masks.stderr index 300c93df9250..666ad671edee 100644 --- a/tests/ui/bit_masks.stderr +++ b/tests/ui/bit_masks.stderr @@ -16,73 +16,73 @@ LL | x & 0 == 0; = note: `#[deny(clippy::erasing_op)]` on by default error: incompatible bit mask: `_ & 2` can never be equal to `1` - --> tests/ui/bit_masks.rs:23:5 + --> tests/ui/bit_masks.rs:20:5 | LL | x & 2 == 1; | ^^^^^^^^^^ error: incompatible bit mask: `_ | 3` can never be equal to `2` - --> tests/ui/bit_masks.rs:29:5 + --> tests/ui/bit_masks.rs:26:5 | LL | x | 3 == 2; | ^^^^^^^^^^ error: incompatible bit mask: `_ & 1` will never be higher than `1` - --> tests/ui/bit_masks.rs:33:5 + --> tests/ui/bit_masks.rs:29:5 | LL | x & 1 > 1; | ^^^^^^^^^ error: incompatible bit mask: `_ | 2` will always be higher than `1` - --> tests/ui/bit_masks.rs:39:5 + --> tests/ui/bit_masks.rs:35:5 | LL | x | 2 > 1; | ^^^^^^^^^ error: incompatible bit mask: `_ & 7` can never be equal to `8` - --> tests/ui/bit_masks.rs:48:5 + --> tests/ui/bit_masks.rs:44:5 | LL | x & THREE_BITS == 8; | ^^^^^^^^^^^^^^^^^^^ error: incompatible bit mask: `_ | 7` will never be lower than `7` - --> tests/ui/bit_masks.rs:51:5 + --> tests/ui/bit_masks.rs:47:5 | LL | x | EVEN_MORE_REDIRECTION < 7; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: &-masking with zero - --> tests/ui/bit_masks.rs:55:5 + --> tests/ui/bit_masks.rs:50:5 | LL | 0 & x == 0; | ^^^^^^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/bit_masks.rs:55:5 + --> tests/ui/bit_masks.rs:50:5 | LL | 0 & x == 0; | ^^^^^ error: incompatible bit mask: `_ | 2` will always be higher than `1` - --> tests/ui/bit_masks.rs:63:5 + --> tests/ui/bit_masks.rs:57:5 | LL | 1 < 2 | x; | ^^^^^^^^^ error: incompatible bit mask: `_ | 3` can never be equal to `2` - --> tests/ui/bit_masks.rs:66:5 + --> tests/ui/bit_masks.rs:60:5 | LL | 2 == 3 | x; | ^^^^^^^^^^ error: incompatible bit mask: `_ & 2` can never be equal to `1` - --> tests/ui/bit_masks.rs:69:5 + --> tests/ui/bit_masks.rs:63:5 | LL | 1 == x & 2; | ^^^^^^^^^^ error: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly - --> tests/ui/bit_masks.rs:82:5 + --> tests/ui/bit_masks.rs:75:5 | LL | x | 1 > 3; | ^^^^^^^^^ @@ -91,19 +91,19 @@ LL | x | 1 > 3; = help: to override `-D warnings` add `#[allow(clippy::ineffective_bit_mask)]` error: ineffective bit mask: `x | 1` compared to `4`, is the same as x compared directly - --> tests/ui/bit_masks.rs:86:5 + --> tests/ui/bit_masks.rs:78:5 | LL | x | 1 < 4; | ^^^^^^^^^ error: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly - --> tests/ui/bit_masks.rs:89:5 + --> tests/ui/bit_masks.rs:81:5 | LL | x | 1 <= 3; | ^^^^^^^^^^ error: ineffective bit mask: `x | 1` compared to `8`, is the same as x compared directly - --> tests/ui/bit_masks.rs:92:5 + --> tests/ui/bit_masks.rs:84:5 | LL | x | 1 >= 8; | ^^^^^^^^^^ diff --git a/tests/ui/blanket_clippy_restriction_lints.rs b/tests/ui/blanket_clippy_restriction_lints.rs index 16e2e62c523d..de699309b16d 100644 --- a/tests/ui/blanket_clippy_restriction_lints.rs +++ b/tests/ui/blanket_clippy_restriction_lints.rs @@ -6,12 +6,9 @@ //! Test that the whole restriction group is not enabled #![warn(clippy::restriction)] //~^ blanket_clippy_restriction_lints - #![deny(clippy::restriction)] //~^ blanket_clippy_restriction_lints - #![forbid(clippy::restriction)] //~^ blanket_clippy_restriction_lints - fn main() {} diff --git a/tests/ui/blanket_clippy_restriction_lints.stderr b/tests/ui/blanket_clippy_restriction_lints.stderr index 5bfd7d208307..ff3a7cfc3931 100644 --- a/tests/ui/blanket_clippy_restriction_lints.stderr +++ b/tests/ui/blanket_clippy_restriction_lints.stderr @@ -14,7 +14,7 @@ LL | #![warn(clippy::restriction)] = help: enable the restriction lints you need individually error: `clippy::restriction` is not meant to be enabled as a group - --> tests/ui/blanket_clippy_restriction_lints.rs:10:9 + --> tests/ui/blanket_clippy_restriction_lints.rs:9:9 | LL | #![deny(clippy::restriction)] | ^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | #![deny(clippy::restriction)] = help: enable the restriction lints you need individually error: `clippy::restriction` is not meant to be enabled as a group - --> tests/ui/blanket_clippy_restriction_lints.rs:13:11 + --> tests/ui/blanket_clippy_restriction_lints.rs:11:11 | LL | #![forbid(clippy::restriction)] | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/bool_comparison.fixed b/tests/ui/bool_comparison.fixed index 724bf9253d33..166abbe549c3 100644 --- a/tests/ui/bool_comparison.fixed +++ b/tests/ui/bool_comparison.fixed @@ -5,86 +5,86 @@ fn main() { let x = true; if x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if !x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if !x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if !x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if !x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if !x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if !x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; let y = true; if !x & y { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x & !y { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" diff --git a/tests/ui/bool_comparison.rs b/tests/ui/bool_comparison.rs index 6d11f9efe569..7265c2b4c5a6 100644 --- a/tests/ui/bool_comparison.rs +++ b/tests/ui/bool_comparison.rs @@ -5,86 +5,86 @@ fn main() { let x = true; if x == true { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x == false { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if true == x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if false == x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x != true { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x != false { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if true != x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if false != x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x < true { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if false < x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x > false { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if true > x { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; let y = true; if x < y { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" }; if x > y { - //~^ bool_comparison + //~^ bool_comparison "yes" } else { "no" diff --git a/tests/ui/bool_to_int_with_if.rs b/tests/ui/bool_to_int_with_if.rs index d12b0af5312e..72c7e2c71c56 100644 --- a/tests/ui/bool_to_int_with_if.rs +++ b/tests/ui/bool_to_int_with_if.rs @@ -12,37 +12,37 @@ fn main() { // Should lint // precedence if a { - //~^ bool_to_int_with_if + //~^ bool_to_int_with_if 1 } else { 0 }; if a { - //~^ bool_to_int_with_if + //~^ bool_to_int_with_if 0 } else { 1 }; if !a { - //~^ bool_to_int_with_if + //~^ bool_to_int_with_if 1 } else { 0 }; if a || b { - //~^ bool_to_int_with_if + //~^ bool_to_int_with_if 1 } else { 0 }; if cond(a, b) { - //~^ bool_to_int_with_if + //~^ bool_to_int_with_if 1 } else { 0 }; if x + y < 4 { - //~^ bool_to_int_with_if + //~^ bool_to_int_with_if 1 } else { 0 @@ -52,7 +52,7 @@ fn main() { if a { 123 } else if b { - //~^ bool_to_int_with_if + //~^ bool_to_int_with_if 1 } else { 0 @@ -62,7 +62,7 @@ fn main() { if a { 123 } else if b { - //~^ bool_to_int_with_if + //~^ bool_to_int_with_if 0 } else { 1 diff --git a/tests/ui/borrow_box.fixed b/tests/ui/borrow_box.fixed index 4529138c0edc..e6e7f74af7cf 100644 --- a/tests/ui/borrow_box.fixed +++ b/tests/ui/borrow_box.fixed @@ -24,19 +24,16 @@ pub fn test1(foo: &mut Box) { pub fn test2() { let foo: &bool; //~^ borrowed_box - } struct Test3<'a> { foo: &'a bool, //~^ borrowed_box - } trait Test4 { fn test4(a: &bool); //~^ borrowed_box - } use std::any::Any; @@ -105,7 +102,6 @@ pub fn test15(_display: &(dyn Display + Send)) {} pub fn test16<'a>(_display: &'a (dyn Display + 'a)) {} //~^ borrowed_box - pub fn test17(_display: &impl Display) {} //~^ borrowed_box @@ -115,14 +111,12 @@ pub fn test18(_display: &(impl Display + Send)) {} pub fn test19<'a>(_display: &'a (impl Display + 'a)) {} //~^ borrowed_box - // This exists only to check what happens when parentheses are already present. // Even though the current implementation doesn't put extra parentheses, // it's fine that unnecessary parentheses appear in the future for some reason. pub fn test20(_display: &(dyn Display + Send)) {} //~^ borrowed_box - #[allow(clippy::borrowed_box)] trait Trait { fn f(b: &Box); diff --git a/tests/ui/borrow_box.rs b/tests/ui/borrow_box.rs index 3f2a0168ef42..43cf809306b3 100644 --- a/tests/ui/borrow_box.rs +++ b/tests/ui/borrow_box.rs @@ -24,19 +24,16 @@ pub fn test1(foo: &mut Box) { pub fn test2() { let foo: &Box; //~^ borrowed_box - } struct Test3<'a> { foo: &'a Box, //~^ borrowed_box - } trait Test4 { fn test4(a: &Box); //~^ borrowed_box - } use std::any::Any; @@ -105,7 +102,6 @@ pub fn test15(_display: &Box) {} pub fn test16<'a>(_display: &'a Box) {} //~^ borrowed_box - pub fn test17(_display: &Box) {} //~^ borrowed_box @@ -115,14 +111,12 @@ pub fn test18(_display: &Box) {} pub fn test19<'a>(_display: &'a Box) {} //~^ borrowed_box - // This exists only to check what happens when parentheses are already present. // Even though the current implementation doesn't put extra parentheses, // it's fine that unnecessary parentheses appear in the future for some reason. pub fn test20(_display: &Box<(dyn Display + Send)>) {} //~^ borrowed_box - #[allow(clippy::borrowed_box)] trait Trait { fn f(b: &Box); diff --git a/tests/ui/borrow_box.stderr b/tests/ui/borrow_box.stderr index e23e49f1c88b..dbe3757dd435 100644 --- a/tests/ui/borrow_box.stderr +++ b/tests/ui/borrow_box.stderr @@ -11,55 +11,55 @@ LL | #![deny(clippy::borrowed_box)] | ^^^^^^^^^^^^^^^^^^^^ error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:31:10 + --> tests/ui/borrow_box.rs:30:10 | LL | foo: &'a Box, | ^^^^^^^^^^^^^ help: try: `&'a bool` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:37:17 + --> tests/ui/borrow_box.rs:35:17 | LL | fn test4(a: &Box); | ^^^^^^^^^^ help: try: `&bool` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:99:25 + --> tests/ui/borrow_box.rs:96:25 | LL | pub fn test14(_display: &Box) {} | ^^^^^^^^^^^^^^^^^ help: try: `&dyn Display` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:102:25 + --> tests/ui/borrow_box.rs:99:25 | LL | pub fn test15(_display: &Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:105:29 + --> tests/ui/borrow_box.rs:102:29 | LL | pub fn test16<'a>(_display: &'a Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (dyn Display + 'a)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:109:25 + --> tests/ui/borrow_box.rs:105:25 | LL | pub fn test17(_display: &Box) {} | ^^^^^^^^^^^^^^^^^^ help: try: `&impl Display` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:112:25 + --> tests/ui/borrow_box.rs:108:25 | LL | pub fn test18(_display: &Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(impl Display + Send)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:115:29 + --> tests/ui/borrow_box.rs:111:29 | LL | pub fn test19<'a>(_display: &'a Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (impl Display + 'a)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> tests/ui/borrow_box.rs:122:25 + --> tests/ui/borrow_box.rs:117:25 | LL | pub fn test20(_display: &Box<(dyn Display + Send)>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)` diff --git a/tests/ui/borrow_deref_ref_unfixable.rs b/tests/ui/borrow_deref_ref_unfixable.rs index e51d9912b308..f05a90d2c1fa 100644 --- a/tests/ui/borrow_deref_ref_unfixable.rs +++ b/tests/ui/borrow_deref_ref_unfixable.rs @@ -8,7 +8,5 @@ mod should_lint { let s = &String::new(); let x: &str = &*s; //~^ borrow_deref_ref - - } } diff --git a/tests/ui/borrow_interior_mutable_const/others.rs b/tests/ui/borrow_interior_mutable_const/others.rs index eaf90ce6a8dd..fa729b62d7f5 100644 --- a/tests/ui/borrow_interior_mutable_const/others.rs +++ b/tests/ui/borrow_interior_mutable_const/others.rs @@ -62,20 +62,20 @@ mod issue12979 { const CELL_REF: StaticRef<(UnsafeCell,)> = unsafe { StaticRef::new(std::ptr::null()) }; fn main() { -ATOMIC.store(1, Ordering::SeqCst); -//~^ borrow_interior_mutable_const -assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); -//~^ borrow_interior_mutable_const + ATOMIC.store(1, Ordering::SeqCst); + //~^ borrow_interior_mutable_const + assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); + //~^ borrow_interior_mutable_const let _once = ONCE_INIT; -let _once_ref = &ONCE_INIT; -//~^ borrow_interior_mutable_const -let _once_ref_2 = &&ONCE_INIT; -//~^ borrow_interior_mutable_const -let _once_ref_4 = &&&&ONCE_INIT; -//~^ borrow_interior_mutable_const -let _once_mut = &mut ONCE_INIT; -//~^ borrow_interior_mutable_const + let _once_ref = &ONCE_INIT; + //~^ borrow_interior_mutable_const + let _once_ref_2 = &&ONCE_INIT; + //~^ borrow_interior_mutable_const + let _once_ref_4 = &&&&ONCE_INIT; + //~^ borrow_interior_mutable_const + let _once_mut = &mut ONCE_INIT; + //~^ borrow_interior_mutable_const let _atomic_into_inner = ATOMIC.into_inner(); // these should be all fine. let _twice = (ONCE_INIT, ONCE_INIT); @@ -86,30 +86,30 @@ let _once_mut = &mut ONCE_INIT; let _ref_array_once = &[ONCE_INIT, ONCE_INIT][0]; // referencing projection is still bad. -let _ = &ATOMIC_TUPLE; -//~^ borrow_interior_mutable_const -let _ = &ATOMIC_TUPLE.0; -//~^ borrow_interior_mutable_const -let _ = &(&&&&ATOMIC_TUPLE).0; -//~^ borrow_interior_mutable_const -let _ = &ATOMIC_TUPLE.0[0]; -//~^ borrow_interior_mutable_const -let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); -//~^ borrow_interior_mutable_const + let _ = &ATOMIC_TUPLE; + //~^ borrow_interior_mutable_const + let _ = &ATOMIC_TUPLE.0; + //~^ borrow_interior_mutable_const + let _ = &(&&&&ATOMIC_TUPLE).0; + //~^ borrow_interior_mutable_const + let _ = &ATOMIC_TUPLE.0[0]; + //~^ borrow_interior_mutable_const + let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); + //~^ borrow_interior_mutable_const let _ = &ATOMIC_TUPLE.2; let _ = (&&&&ATOMIC_TUPLE).0; let _ = (&&&&ATOMIC_TUPLE).2; let _ = ATOMIC_TUPLE.0; -let _ = ATOMIC_TUPLE.0[0]; -//~^ borrow_interior_mutable_const + let _ = ATOMIC_TUPLE.0[0]; + //~^ borrow_interior_mutable_const let _ = ATOMIC_TUPLE.1.into_iter(); let _ = ATOMIC_TUPLE.2; let _ = &{ ATOMIC_TUPLE }; -CELL.set(2); -//~^ borrow_interior_mutable_const -assert_eq!(CELL.get(), 6); -//~^ borrow_interior_mutable_const + CELL.set(2); + //~^ borrow_interior_mutable_const + assert_eq!(CELL.get(), 6); + //~^ borrow_interior_mutable_const assert_eq!(INTEGER, 8); assert!(STRING.is_empty()); diff --git a/tests/ui/borrow_interior_mutable_const/others.stderr b/tests/ui/borrow_interior_mutable_const/others.stderr index f15664030151..decea153f717 100644 --- a/tests/ui/borrow_interior_mutable_const/others.stderr +++ b/tests/ui/borrow_interior_mutable_const/others.stderr @@ -1,8 +1,8 @@ error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:65:1 + --> tests/ui/borrow_interior_mutable_const/others.rs:65:5 | -LL | ATOMIC.store(1, Ordering::SeqCst); - | ^^^^^^ +LL | ATOMIC.store(1, Ordering::SeqCst); + | ^^^^^^ | = help: assign this const to a local or static variable, and use the variable here note: the lint level is defined here @@ -12,106 +12,106 @@ LL | #![deny(clippy::borrow_interior_mutable_const)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:67:12 + --> tests/ui/borrow_interior_mutable_const/others.rs:67:16 | -LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); - | ^^^^^^ +LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); + | ^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:71:18 + --> tests/ui/borrow_interior_mutable_const/others.rs:71:22 | -LL | let _once_ref = &ONCE_INIT; - | ^^^^^^^^^ - | - = help: assign this const to a local or static variable, and use the variable here - -error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:73:21 - | -LL | let _once_ref_2 = &&ONCE_INIT; - | ^^^^^^^^^ - | - = help: assign this const to a local or static variable, and use the variable here - -error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:75:23 - | -LL | let _once_ref_4 = &&&&ONCE_INIT; - | ^^^^^^^^^ - | - = help: assign this const to a local or static variable, and use the variable here - -error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:77:22 - | -LL | let _once_mut = &mut ONCE_INIT; +LL | let _once_ref = &ONCE_INIT; | ^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:89:10 + --> tests/ui/borrow_interior_mutable_const/others.rs:73:25 | -LL | let _ = &ATOMIC_TUPLE; - | ^^^^^^^^^^^^ +LL | let _once_ref_2 = &&ONCE_INIT; + | ^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:91:10 + --> tests/ui/borrow_interior_mutable_const/others.rs:75:27 | -LL | let _ = &ATOMIC_TUPLE.0; - | ^^^^^^^^^^^^ +LL | let _once_ref_4 = &&&&ONCE_INIT; + | ^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:93:15 + --> tests/ui/borrow_interior_mutable_const/others.rs:77:26 | -LL | let _ = &(&&&&ATOMIC_TUPLE).0; - | ^^^^^^^^^^^^ +LL | let _once_mut = &mut ONCE_INIT; + | ^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:95:10 + --> tests/ui/borrow_interior_mutable_const/others.rs:89:14 | -LL | let _ = &ATOMIC_TUPLE.0[0]; - | ^^^^^^^^^^^^ +LL | let _ = &ATOMIC_TUPLE; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:97:9 + --> tests/ui/borrow_interior_mutable_const/others.rs:91:14 | -LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); - | ^^^^^^^^^^^^ +LL | let _ = &ATOMIC_TUPLE.0; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:103:9 + --> tests/ui/borrow_interior_mutable_const/others.rs:93:19 | -LL | let _ = ATOMIC_TUPLE.0[0]; - | ^^^^^^^^^^^^ +LL | let _ = &(&&&&ATOMIC_TUPLE).0; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:109:1 + --> tests/ui/borrow_interior_mutable_const/others.rs:95:14 | -LL | CELL.set(2); - | ^^^^ +LL | let _ = &ATOMIC_TUPLE.0[0]; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/others.rs:111:12 + --> tests/ui/borrow_interior_mutable_const/others.rs:97:13 | -LL | assert_eq!(CELL.get(), 6); - | ^^^^ +LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); + | ^^^^^^^^^^^^ + | + = help: assign this const to a local or static variable, and use the variable here + +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/others.rs:103:13 + | +LL | let _ = ATOMIC_TUPLE.0[0]; + | ^^^^^^^^^^^^ + | + = help: assign this const to a local or static variable, and use the variable here + +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/others.rs:109:5 + | +LL | CELL.set(2); + | ^^^^ + | + = help: assign this const to a local or static variable, and use the variable here + +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/others.rs:111:16 + | +LL | assert_eq!(CELL.get(), 6); + | ^^^^ | = help: assign this const to a local or static variable, and use the variable here diff --git a/tests/ui/borrow_interior_mutable_const/traits.rs b/tests/ui/borrow_interior_mutable_const/traits.rs index 8e2b7ffd554f..c4878dbe57b2 100644 --- a/tests/ui/borrow_interior_mutable_const/traits.rs +++ b/tests/ui/borrow_interior_mutable_const/traits.rs @@ -12,8 +12,8 @@ trait ConcreteTypes { const STRING: String; fn function() { -let _ = &Self::ATOMIC; -//~^ borrow_interior_mutable_const + let _ = &Self::ATOMIC; + //~^ borrow_interior_mutable_const let _ = &Self::STRING; } } @@ -24,8 +24,8 @@ impl ConcreteTypes for u64 { fn function() { // Lint this again since implementers can choose not to borrow it. -let _ = &Self::ATOMIC; -//~^ borrow_interior_mutable_const + let _ = &Self::ATOMIC; + //~^ borrow_interior_mutable_const let _ = &Self::STRING; } } @@ -50,8 +50,8 @@ impl GenericTypes for Vec { fn function() { let _ = &Self::TO_REMAIN_GENERIC; -let _ = &Self::TO_BE_CONCRETE; -//~^ borrow_interior_mutable_const + let _ = &Self::TO_BE_CONCRETE; + //~^ borrow_interior_mutable_const } } @@ -86,10 +86,10 @@ impl AssocTypes for Vec { fn function() { let _ = &Self::TO_BE_FROZEN; -let _ = &Self::TO_BE_UNFROZEN; -//~^ borrow_interior_mutable_const -let _ = &Self::WRAPPED_TO_BE_UNFROZEN; -//~^ borrow_interior_mutable_const + let _ = &Self::TO_BE_UNFROZEN; + //~^ borrow_interior_mutable_const + let _ = &Self::WRAPPED_TO_BE_UNFROZEN; + //~^ borrow_interior_mutable_const let _ = &Self::WRAPPED_TO_BE_GENERIC_PARAM; } } @@ -111,8 +111,8 @@ where fn function() { let _ = &Self::NOT_BOUNDED; -let _ = &Self::BOUNDED; -//~^ borrow_interior_mutable_const + let _ = &Self::BOUNDED; + //~^ borrow_interior_mutable_const } } @@ -125,8 +125,8 @@ where fn function() { let _ = &Self::NOT_BOUNDED; -let _ = &Self::BOUNDED; -//~^ borrow_interior_mutable_const + let _ = &Self::BOUNDED; + //~^ borrow_interior_mutable_const } } @@ -155,10 +155,10 @@ impl SelfType for AtomicUsize { const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); fn function() { -let _ = &Self::SELF; -//~^ borrow_interior_mutable_const -let _ = &Self::WRAPPED_SELF; -//~^ borrow_interior_mutable_const + let _ = &Self::SELF; + //~^ borrow_interior_mutable_const + let _ = &Self::WRAPPED_SELF; + //~^ borrow_interior_mutable_const } } @@ -167,10 +167,10 @@ trait BothOfCellAndGeneric { const INDIRECT: Cell<*const T>; fn function() { -let _ = &Self::DIRECT; -//~^ borrow_interior_mutable_const -let _ = &Self::INDIRECT; -//~^ borrow_interior_mutable_const + let _ = &Self::DIRECT; + //~^ borrow_interior_mutable_const + let _ = &Self::INDIRECT; + //~^ borrow_interior_mutable_const } } @@ -179,10 +179,10 @@ impl BothOfCellAndGeneric for Vec { const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null()); fn function() { -let _ = &Self::DIRECT; -//~^ borrow_interior_mutable_const -let _ = &Self::INDIRECT; -//~^ borrow_interior_mutable_const + let _ = &Self::DIRECT; + //~^ borrow_interior_mutable_const + let _ = &Self::INDIRECT; + //~^ borrow_interior_mutable_const } } @@ -201,19 +201,19 @@ where const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); fn function() { -let _ = &Self::ATOMIC; -//~^ borrow_interior_mutable_const + let _ = &Self::ATOMIC; + //~^ borrow_interior_mutable_const let _ = &Self::COW; let _ = &Self::GENERIC_TYPE; let _ = &Self::ASSOC_TYPE; -let _ = &Self::BOUNDED_ASSOC_TYPE; -//~^ borrow_interior_mutable_const + let _ = &Self::BOUNDED_ASSOC_TYPE; + //~^ borrow_interior_mutable_const } } fn main() { -u64::ATOMIC.store(5, Ordering::SeqCst); -//~^ borrow_interior_mutable_const -assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); -//~^ borrow_interior_mutable_const + u64::ATOMIC.store(5, Ordering::SeqCst); + //~^ borrow_interior_mutable_const + assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); + //~^ borrow_interior_mutable_const } diff --git a/tests/ui/borrow_interior_mutable_const/traits.stderr b/tests/ui/borrow_interior_mutable_const/traits.stderr index 6998ba6fc090..cad68ca9260c 100644 --- a/tests/ui/borrow_interior_mutable_const/traits.stderr +++ b/tests/ui/borrow_interior_mutable_const/traits.stderr @@ -1,8 +1,8 @@ error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:15:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:15:18 | -LL | let _ = &Self::ATOMIC; - | ^^^^^^^^^^^^ +LL | let _ = &Self::ATOMIC; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here note: the lint level is defined here @@ -12,130 +12,130 @@ LL | #![deny(clippy::borrow_interior_mutable_const)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:27:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:27:18 | -LL | let _ = &Self::ATOMIC; - | ^^^^^^^^^^^^ +LL | let _ = &Self::ATOMIC; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:53:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:53:18 | -LL | let _ = &Self::TO_BE_CONCRETE; - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::TO_BE_CONCRETE; + | ^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:89:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:89:18 | -LL | let _ = &Self::TO_BE_UNFROZEN; - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::TO_BE_UNFROZEN; + | ^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:91:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:91:18 | -LL | let _ = &Self::WRAPPED_TO_BE_UNFROZEN; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::WRAPPED_TO_BE_UNFROZEN; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:114:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:114:18 | -LL | let _ = &Self::BOUNDED; - | ^^^^^^^^^^^^^ +LL | let _ = &Self::BOUNDED; + | ^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:128:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:128:18 | -LL | let _ = &Self::BOUNDED; - | ^^^^^^^^^^^^^ +LL | let _ = &Self::BOUNDED; + | ^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:158:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:158:18 | -LL | let _ = &Self::SELF; - | ^^^^^^^^^^ +LL | let _ = &Self::SELF; + | ^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:160:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:160:18 | -LL | let _ = &Self::WRAPPED_SELF; - | ^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::WRAPPED_SELF; + | ^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:170:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:170:18 | -LL | let _ = &Self::DIRECT; - | ^^^^^^^^^^^^ +LL | let _ = &Self::DIRECT; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:172:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:172:18 | -LL | let _ = &Self::INDIRECT; - | ^^^^^^^^^^^^^^ +LL | let _ = &Self::INDIRECT; + | ^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:182:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:182:18 | -LL | let _ = &Self::DIRECT; - | ^^^^^^^^^^^^ +LL | let _ = &Self::DIRECT; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:184:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:184:18 | -LL | let _ = &Self::INDIRECT; - | ^^^^^^^^^^^^^^ +LL | let _ = &Self::INDIRECT; + | ^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:204:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:204:18 | -LL | let _ = &Self::ATOMIC; - | ^^^^^^^^^^^^ +LL | let _ = &Self::ATOMIC; + | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:209:10 + --> tests/ui/borrow_interior_mutable_const/traits.rs:209:18 | -LL | let _ = &Self::BOUNDED_ASSOC_TYPE; - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = &Self::BOUNDED_ASSOC_TYPE; + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:215:1 + --> tests/ui/borrow_interior_mutable_const/traits.rs:215:5 | -LL | u64::ATOMIC.store(5, Ordering::SeqCst); - | ^^^^^^^^^^^ +LL | u64::ATOMIC.store(5, Ordering::SeqCst); + | ^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here error: a `const` item with interior mutability should not be borrowed - --> tests/ui/borrow_interior_mutable_const/traits.rs:217:12 + --> tests/ui/borrow_interior_mutable_const/traits.rs:217:16 | -LL | assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); - | ^^^^^^^^^^^ +LL | assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); + | ^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here diff --git a/tests/ui/box_collection.rs b/tests/ui/box_collection.rs index 61117412016a..0f7d3c74ddd0 100644 --- a/tests/ui/box_collection.rs +++ b/tests/ui/box_collection.rs @@ -21,7 +21,6 @@ fn test_macro() { fn test1(foo: Box>) {} //~^ box_collection - fn test2(foo: Box)>) { // pass if #31 is fixed foo(vec![1, 2, 3]) @@ -30,35 +29,27 @@ fn test2(foo: Box)>) { fn test3(foo: Box) {} //~^ box_collection - fn test4(foo: Box>) {} //~^ box_collection - fn test5(foo: Box>) {} //~^ box_collection - fn test6(foo: Box>) {} //~^ box_collection - fn test7(foo: Box>) {} //~^ box_collection - fn test8(foo: Box>) {} //~^ box_collection - fn test9(foo: Box>) {} //~^ box_collection - fn test10(foo: Box>) {} //~^ box_collection - fn test_local_not_linted() { let _: Box>; } diff --git a/tests/ui/box_collection.stderr b/tests/ui/box_collection.stderr index 644556edd572..ebbc3d92b57f 100644 --- a/tests/ui/box_collection.stderr +++ b/tests/ui/box_collection.stderr @@ -9,7 +9,7 @@ LL | fn test1(foo: Box>) {} = help: to override `-D warnings` add `#[allow(clippy::box_collection)]` error: you seem to be trying to use `Box`. Consider using just `String` - --> tests/ui/box_collection.rs:30:15 + --> tests/ui/box_collection.rs:29:15 | LL | fn test3(foo: Box) {} | ^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn test3(foo: Box) {} = help: `String` is already on the heap, `Box` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `HashMap<..>` - --> tests/ui/box_collection.rs:34:15 + --> tests/ui/box_collection.rs:32:15 | LL | fn test4(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | fn test4(foo: Box>) {} = help: `HashMap<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `HashSet<..>` - --> tests/ui/box_collection.rs:38:15 + --> tests/ui/box_collection.rs:35:15 | LL | fn test5(foo: Box>) {} | ^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | fn test5(foo: Box>) {} = help: `HashSet<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `VecDeque<..>` - --> tests/ui/box_collection.rs:42:15 + --> tests/ui/box_collection.rs:38:15 | LL | fn test6(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | fn test6(foo: Box>) {} = help: `VecDeque<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `LinkedList<..>` - --> tests/ui/box_collection.rs:46:15 + --> tests/ui/box_collection.rs:41:15 | LL | fn test7(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | fn test7(foo: Box>) {} = help: `LinkedList<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `BTreeMap<..>` - --> tests/ui/box_collection.rs:50:15 + --> tests/ui/box_collection.rs:44:15 | LL | fn test8(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn test8(foo: Box>) {} = help: `BTreeMap<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `BTreeSet<..>` - --> tests/ui/box_collection.rs:54:15 + --> tests/ui/box_collection.rs:47:15 | LL | fn test9(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | fn test9(foo: Box>) {} = help: `BTreeSet<..>` is already on the heap, `Box>` makes an extra allocation error: you seem to be trying to use `Box>`. Consider using just `BinaryHeap<..>` - --> tests/ui/box_collection.rs:58:16 + --> tests/ui/box_collection.rs:50:16 | LL | fn test10(foo: Box>) {} | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/boxed_local.rs b/tests/ui/boxed_local.rs index fa234dce1a99..3fb685aa36c1 100644 --- a/tests/ui/boxed_local.rs +++ b/tests/ui/boxed_local.rs @@ -38,8 +38,7 @@ fn warn_call() { } fn warn_arg(x: Box) { -//~^ boxed_local - + //~^ boxed_local x.foo(); } @@ -124,7 +123,6 @@ pub struct PeekableSeekable { pub fn new(_needs_name: Box>) -> () {} //~^ boxed_local - /// Regression for #916, #1123 /// /// This shouldn't warn for `boxed_local`as the implementation of a trait @@ -189,7 +187,7 @@ mod issue4804 { // warn on `x: Box` fn default_impl_x(self: Box, x: Box) -> u32 { - //~^ boxed_local + //~^ boxed_local 4 } @@ -199,7 +197,6 @@ mod issue4804 { // warn on `x: Box` fn foo(x: Box) {} //~^ boxed_local - } } diff --git a/tests/ui/boxed_local.stderr b/tests/ui/boxed_local.stderr index 5ce2c8083f15..81ebc4fde498 100644 --- a/tests/ui/boxed_local.stderr +++ b/tests/ui/boxed_local.stderr @@ -8,19 +8,19 @@ LL | fn warn_arg(x: Box) { = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]` error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:124:12 + --> tests/ui/boxed_local.rs:123:12 | LL | pub fn new(_needs_name: Box>) -> () {} | ^^^^^^^^^^^ error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:191:44 + --> tests/ui/boxed_local.rs:189:44 | LL | fn default_impl_x(self: Box, x: Box) -> u32 { | ^ error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:200:16 + --> tests/ui/boxed_local.rs:198:16 | LL | fn foo(x: Box) {} | ^ diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.rs b/tests/ui/branches_sharing_code/shared_at_bottom.rs index 050c8c0d53f2..06472a4f5d57 100644 --- a/tests/ui/branches_sharing_code/shared_at_bottom.rs +++ b/tests/ui/branches_sharing_code/shared_at_bottom.rs @@ -35,7 +35,6 @@ fn simple_examples() { let result = false; //~^ branches_sharing_code - println!("Block end!"); result }; @@ -55,7 +54,6 @@ fn simple_examples() { println!("This is also eq with the else block"); println!("Same end of block"); //~^ branches_sharing_code - } // Use of outer scope value @@ -73,8 +71,7 @@ fn simple_examples() { println!("I'm a local because I use the value `z`: `{}`", z); println!( - //~^ branches_sharing_code - + //~^ branches_sharing_code "I'm moveable because I know: `outer_scope_value`: '{}'", outer_scope_value ); @@ -88,7 +85,6 @@ fn simple_examples() { } else { println!("Hello World"); //~^ branches_sharing_code - } } } @@ -188,8 +184,6 @@ fn added_note_for_expression_use() -> u32 { let _ = 6; x << 2 //~^ branches_sharing_code - - }; if x == 9 { @@ -198,8 +192,6 @@ fn added_note_for_expression_use() -> u32 { let _ = 17; x * 4 //~^ branches_sharing_code - - } } diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/tests/ui/branches_sharing_code/shared_at_bottom.stderr index b7bb07775241..648a99c65ed2 100644 --- a/tests/ui/branches_sharing_code/shared_at_bottom.stderr +++ b/tests/ui/branches_sharing_code/shared_at_bottom.stderr @@ -2,7 +2,9 @@ error: all if blocks contain the same code at the end --> tests/ui/branches_sharing_code/shared_at_bottom.rs:35:5 | LL | / let result = false; -... | +LL | | +LL | | +LL | | println!("Block end!"); LL | | result LL | | }; | |_____^ @@ -19,16 +21,15 @@ LL ~ } LL + let result = false; LL + LL + -LL + LL + println!("Block end!"); LL ~ result; | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:56:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:55:5 | LL | / println!("Same end of block"); -... | +LL | | LL | | } | |_____^ | @@ -39,11 +40,10 @@ LL + println!("Same end of block"); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:75:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:73:5 | LL | / println!( LL | | -LL | | LL | | "I'm moveable because I know: `outer_scope_value`: '{}'", LL | | outer_scope_value LL | | ); @@ -55,17 +55,16 @@ help: consider moving these statements after the if LL ~ } LL + println!( LL + -LL + LL + "I'm moveable because I know: `outer_scope_value`: '{}'", LL + outer_scope_value LL + ); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:89:9 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:86:9 | LL | / println!("Hello World"); -... | +LL | | LL | | } | |_________^ | @@ -76,7 +75,7 @@ LL + println!("Hello World"); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:107:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:103:5 | LL | / let later_used_value = "A string value"; LL | | @@ -97,7 +96,7 @@ LL + println!("{}", later_used_value); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:122:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:118:5 | LL | / let simple_examples = "I now identify as a &str :)"; LL | | @@ -117,10 +116,10 @@ LL + println!("This is the new simple_example: {}", simple_examples); | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:189:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:185:5 | LL | / x << 2 -... | +LL | | LL | | }; | |_____^ | @@ -132,10 +131,10 @@ LL ~ x << 2; | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:199:5 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:193:5 | LL | / x * 4 -... | +LL | | LL | | } | |_____^ | @@ -147,7 +146,7 @@ LL + x * 4 | error: all if blocks contain the same code at the end - --> tests/ui/branches_sharing_code/shared_at_bottom.rs:214:44 + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:206:44 | LL | if x == 17 { b = 1; a = 0x99; } else { a = 0x99; } | ^^^^^^^^^^^ diff --git a/tests/ui/branches_sharing_code/shared_at_top.rs b/tests/ui/branches_sharing_code/shared_at_top.rs index a6f8ce8a3816..694c67d4c85b 100644 --- a/tests/ui/branches_sharing_code/shared_at_top.rs +++ b/tests/ui/branches_sharing_code/shared_at_top.rs @@ -9,7 +9,7 @@ fn simple_examples() { // Simple if true { - //~^ branches_sharing_code + //~^ branches_sharing_code println!("Hello World!"); println!("I'm branch nr: 1"); } else { @@ -17,10 +17,9 @@ fn simple_examples() { println!("I'm branch nr: 2"); } - // Else if if x == 0 { - //~^ branches_sharing_code + //~^ branches_sharing_code let y = 9; println!("The value y was set to: `{}`", y); let _z = y; @@ -40,10 +39,9 @@ fn simple_examples() { println!("Ha, Pascal allows you to start the array where you want") } - // Return a value let _ = if x == 7 { - //~^ branches_sharing_code + //~^ branches_sharing_code let y = 16; println!("What can I say except: \"you're welcome?\""); @@ -63,7 +61,7 @@ fn simple_but_suggestion_is_invalid() { // Can't be automatically moved because used_value_name is getting used again let used_value_name = 19; if x == 10 { - //~^ branches_sharing_code + //~^ branches_sharing_code let used_value_name = "Different type"; println!("Str: {}", used_value_name); let _ = 1; @@ -79,7 +77,7 @@ fn simple_but_suggestion_is_invalid() { let can_be_overridden = 8; let _ = can_be_overridden; if x == 11 { - //~^ branches_sharing_code + //~^ branches_sharing_code let can_be_overridden = "Move me"; println!("I'm also moveable"); @@ -97,7 +95,7 @@ fn check_if_same_than_else_mask() { #[allow(clippy::if_same_then_else)] if x == 2020 { - //~^ branches_sharing_code + //~^ branches_sharing_code println!("This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint."); println!("Because `IF_SAME_THEN_ELSE` is allowed here"); @@ -112,7 +110,6 @@ fn check_if_same_than_else_mask() { println!("This should trigger `IS_SAME_THAN_ELSE` as usual"); } //~^^^^^ if_same_then_else - } #[allow(clippy::vec_init_then_push)] diff --git a/tests/ui/branches_sharing_code/shared_at_top.stderr b/tests/ui/branches_sharing_code/shared_at_top.stderr index 5b0422d5df18..d28e9c7af296 100644 --- a/tests/ui/branches_sharing_code/shared_at_top.stderr +++ b/tests/ui/branches_sharing_code/shared_at_top.stderr @@ -18,7 +18,7 @@ LL + if true { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:22:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:21:5 | LL | / if x == 0 { LL | | @@ -37,7 +37,7 @@ LL + if x == 0 { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:45:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:43:5 | LL | / let _ = if x == 7 { ... | @@ -51,7 +51,7 @@ LL + let _ = if x == 7 { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:65:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:63:5 | LL | / if x == 10 { LL | | @@ -68,7 +68,7 @@ LL + if x == 10 { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:81:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:79:5 | LL | / if x == 11 { LL | | @@ -86,7 +86,7 @@ LL + if x == 11 { | error: all if blocks contain the same code at the start - --> tests/ui/branches_sharing_code/shared_at_top.rs:99:5 + --> tests/ui/branches_sharing_code/shared_at_top.rs:97:5 | LL | / if x == 2020 { LL | | @@ -103,7 +103,7 @@ LL + if x == 2020 { | error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/shared_at_top.rs:109:18 + --> tests/ui/branches_sharing_code/shared_at_top.rs:107:18 | LL | if x == 2019 { | __________________^ @@ -112,7 +112,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/branches_sharing_code/shared_at_top.rs:111:12 + --> tests/ui/branches_sharing_code/shared_at_top.rs:109:12 | LL | } else { | ____________^ diff --git a/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs index 799f58d28430..75334f70f1f6 100644 --- a/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs +++ b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs @@ -15,7 +15,7 @@ fn overlapping_eq_regions() { // Overlap with separator if x == 7 { - //~^ branches_sharing_code + //~^ branches_sharing_code let t = 7; let _overlap_start = t * 2; @@ -33,7 +33,7 @@ fn overlapping_eq_regions() { // Overlap with separator if x == 99 { - //~^ branches_sharing_code + //~^ branches_sharing_code let r = 7; let _overlap_start = r; @@ -64,7 +64,7 @@ fn complexer_example() { let x = 8; let y = 9; if (x > 7 && y < 13) || (x + y) % 2 == 1 { - //~^ branches_sharing_code + //~^ branches_sharing_code let a = 0xcafe; let b = 0xffff00ff; @@ -99,7 +99,7 @@ fn added_note_for_expression_use() -> u32 { let x = 9; let _ = if x == 7 { - //~^ branches_sharing_code + //~^ branches_sharing_code let _ = 19; @@ -113,7 +113,7 @@ fn added_note_for_expression_use() -> u32 { }; if x == 9 { - //~^ branches_sharing_code + //~^ branches_sharing_code let _ = 17; diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.rs b/tests/ui/branches_sharing_code/valid_if_blocks.rs index 23ea86c88f54..d72c5eef87ad 100644 --- a/tests/ui/branches_sharing_code/valid_if_blocks.rs +++ b/tests/ui/branches_sharing_code/valid_if_blocks.rs @@ -110,7 +110,6 @@ fn valid_examples() { } else { } //~^^^ if_same_then_else - } /// This makes sure that the `if_same_then_else` masks the `shared_code_in_if_blocks` lint @@ -130,12 +129,10 @@ fn trigger_other_lint() { } //~^^^^^^^^^ if_same_then_else - // Only same expression let _ = if x == 6 { 7 } else { 7 }; //~^ if_same_then_else - // Same in else if block let _ = if x == 67 { println!("Well I'm the most important block"); @@ -151,7 +148,6 @@ fn trigger_other_lint() { }; //~^^^^^^^^^ if_same_then_else - if x == 0 { println!("I'm single"); } else if x == 68 { @@ -160,7 +156,6 @@ fn trigger_other_lint() { println!("I'm a doppelgänger"); } //~^^^^^ if_same_then_else - } fn main() {} diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.stderr b/tests/ui/branches_sharing_code/valid_if_blocks.stderr index a0c4dd24d6b4..4c7e4141b629 100644 --- a/tests/ui/branches_sharing_code/valid_if_blocks.stderr +++ b/tests/ui/branches_sharing_code/valid_if_blocks.stderr @@ -20,7 +20,7 @@ LL | #![deny(clippy::branches_sharing_code, clippy::if_same_then_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:122:15 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:121:15 | LL | if x == 0 { | _______________^ @@ -31,7 +31,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:126:12 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:125:12 | LL | } else { | ____________^ @@ -42,19 +42,19 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:135:23 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:133:23 | LL | let _ = if x == 6 { 7 } else { 7 }; | ^^^^^ | note: same as this - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:135:34 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:133:34 | LL | let _ = if x == 6 { 7 } else { 7 }; | ^^^^^ error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:143:23 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:140:23 | LL | } else if x == 68 { | _______________________^ @@ -65,7 +65,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:147:12 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:144:12 | LL | } else { | ____________^ @@ -76,7 +76,7 @@ LL | | }; | |_____^ error: this `if` has identical blocks - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:157:23 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:153:23 | LL | } else if x == 68 { | _______________________^ @@ -85,7 +85,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/branches_sharing_code/valid_if_blocks.rs:159:12 + --> tests/ui/branches_sharing_code/valid_if_blocks.rs:155:12 | LL | } else { | ____________^ diff --git a/tests/ui/builtin_type_shadow.rs b/tests/ui/builtin_type_shadow.rs index 31df0c21b67e..eda22b7c38ef 100644 --- a/tests/ui/builtin_type_shadow.rs +++ b/tests/ui/builtin_type_shadow.rs @@ -2,7 +2,7 @@ #![allow(non_camel_case_types)] fn foo(a: u32) -> u32 { -//~^ builtin_type_shadow + //~^ builtin_type_shadow 42 //~ ERROR: mismatched type } diff --git a/tests/ui/bytecount.rs b/tests/ui/bytecount.rs index bad39fcf8f66..f03f99177d54 100644 --- a/tests/ui/bytecount.rs +++ b/tests/ui/bytecount.rs @@ -10,12 +10,10 @@ fn main() { let _ = x.iter().filter(|&&a| a == 0).count(); //~^ naive_bytecount - // naive byte count let _ = (&x[..]).iter().filter(|&a| *a == 0).count(); //~^ naive_bytecount - // not an equality count, OK. let _ = x.iter().filter(|a| **a > 0).count(); @@ -34,7 +32,6 @@ fn main() { let _ = x.iter().filter(|a| b + 1 == **a).count(); //~^ naive_bytecount - let y = vec![0_u16; 3]; // naive count, but not bytes diff --git a/tests/ui/bytecount.stderr b/tests/ui/bytecount.stderr index 9a0986f56478..d1a73fe98358 100644 --- a/tests/ui/bytecount.stderr +++ b/tests/ui/bytecount.stderr @@ -11,13 +11,13 @@ LL | #[deny(clippy::naive_bytecount)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: you appear to be counting bytes the naive way - --> tests/ui/bytecount.rs:15:13 + --> tests/ui/bytecount.rs:14:13 | LL | let _ = (&x[..]).iter().filter(|&a| *a == 0).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count((&x[..]), 0)` error: you appear to be counting bytes the naive way - --> tests/ui/bytecount.rs:34:13 + --> tests/ui/bytecount.rs:32:13 | LL | let _ = x.iter().filter(|a| b + 1 == **a).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count(x, b + 1)` diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index b2e92d36f402..56e4326cdc1d 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -25,7 +25,6 @@ fn main() { x0 as f32; //~^ cast_precision_loss - let x1 = 1i64; x1 as f32; //~^ cast_precision_loss @@ -52,8 +51,6 @@ fn main() { //~^ cast_possible_truncation //~| cast_sign_loss - - 1f64 as f32; //~^ cast_possible_truncation @@ -70,14 +67,11 @@ fn main() { //~^ cast_possible_truncation //~| cast_sign_loss - 1f32 as u32 as u16; //~^ cast_possible_truncation //~| cast_possible_truncation //~| cast_sign_loss - - { let _x: i8 = 1i32 as _; //~^ cast_possible_truncation @@ -91,14 +85,11 @@ fn main() { 1f32 as u8; //~^ cast_possible_truncation //~| cast_sign_loss - - } // Test clippy::cast_possible_wrap 1u8 as i8; //~^ cast_possible_wrap - 1u16 as i16; //~^ cast_possible_wrap @@ -120,14 +111,11 @@ fn main() { //~^ cast_possible_truncation //~| cast_possible_wrap - - // wraps on 32 bit ptr size 1usize as i32; //~^ cast_possible_truncation //~| cast_possible_wrap - // wraps on 64 bit ptr size 1usize as i64; //~^ cast_possible_wrap @@ -138,7 +126,6 @@ fn main() { 1u16 as isize; //~^ cast_possible_wrap - // wraps on 32 bit ptr size 1u32 as isize; //~^ cast_possible_wrap @@ -148,7 +135,6 @@ fn main() { //~^ cast_possible_truncation //~| cast_possible_wrap - // Test clippy::cast_sign_loss 1i32 as u32; -1i32 as u32; @@ -253,7 +239,6 @@ fn main() { (-99999999999i64).min(1) as i8; //~^ cast_possible_truncation - // Test for various operations that remove enough bits for the result to fit (999999u64 & 1) as u8; (999999u64 % 15) as u8; @@ -268,7 +253,6 @@ fn main() { 999999u64.clamp(0, 256) as u8; //~^ cast_possible_truncation - #[derive(Clone, Copy)] enum E1 { A, @@ -295,7 +279,6 @@ fn main() { let _ = Self::B as u8; //~^ cast_enum_truncation - // Don't lint. `255..=256` fits in i16 let _ = self as i16; // Don't lint. @@ -468,7 +451,6 @@ fn issue11642() { (-2_i32).pow(3) as u32; //~^ cast_sign_loss - (3_i32 % 2) as u32; (3_i32 % -2) as u32; (-5_i32 % 2) as u32; @@ -481,14 +463,12 @@ fn issue11642() { (-2_i32 >> 1) as u32; //~^ cast_sign_loss - let x: i32 = 10; (x * x) as u32; //~^ cast_sign_loss (x * x * x) as u32; //~^ cast_sign_loss - let y: i16 = -2; (y * y * y * y * -2) as u16; //~^ cast_sign_loss @@ -502,14 +482,12 @@ fn issue11642() { //~^ cast_sign_loss //~| eq_op - (y + y + y + -2) as u16; //~^ cast_sign_loss (y + y + y + 2) as u16; //~^ cast_sign_loss - let z: i16 = 2; (z + -2) as u16; //~^ cast_sign_loss @@ -547,7 +525,6 @@ fn issue11642() { (a.abs() * b.pow(2) / c.abs()) as u32 //~^ cast_sign_loss - } } @@ -590,5 +567,4 @@ fn issue12721() { (255 % 999999u64) as u8; //~^ cast_possible_truncation - } diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index daabb8192141..484be7905d42 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -8,37 +8,37 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:30:5 + --> tests/ui/cast.rs:29:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:33:5 + --> tests/ui/cast.rs:32:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:37:5 + --> tests/ui/cast.rs:36:5 | LL | x2 as f32; | ^^^^^^^^^ error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:41:5 + --> tests/ui/cast.rs:40:5 | LL | x3 as f32; | ^^^^^^^^^ error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:44:5 + --> tests/ui/cast.rs:43:5 | LL | x3 as f64; | ^^^^^^^^^ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:48:5 + --> tests/ui/cast.rs:47:5 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | 1f32 as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]` error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:51:5 + --> tests/ui/cast.rs:50:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | 1f32 as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:51:5 + --> tests/ui/cast.rs:50:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | 1f32 as u32; = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]` error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:57:5 + --> tests/ui/cast.rs:54:5 | LL | 1f64 as f32; | ^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | 1f64 as f32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:60:5 + --> tests/ui/cast.rs:57:5 | LL | 1i32 as i8; | ^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | i8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u8` may truncate the value - --> tests/ui/cast.rs:63:5 + --> tests/ui/cast.rs:60:5 | LL | 1i32 as u8; | ^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | u8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `f64` to `isize` may truncate the value - --> tests/ui/cast.rs:66:5 + --> tests/ui/cast.rs:63:5 | LL | 1f64 as isize; | ^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | 1f64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may truncate the value - --> tests/ui/cast.rs:69:5 + --> tests/ui/cast.rs:66:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ @@ -113,13 +113,13 @@ LL | 1f64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:69:5 + --> tests/ui/cast.rs:66:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ error: casting `u32` to `u16` may truncate the value - --> tests/ui/cast.rs:74:5 + --> tests/ui/cast.rs:70:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | u16::try_from(1f32 as u32); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:74:5 + --> tests/ui/cast.rs:70:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ @@ -139,13 +139,13 @@ LL | 1f32 as u32 as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:74:5 + --> tests/ui/cast.rs:70:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:82:22 + --> tests/ui/cast.rs:76:22 | LL | let _x: i8 = 1i32 as _; | ^^^^^^^^^ @@ -157,7 +157,7 @@ LL | let _x: i8 = 1i32.try_into(); | ~~~~~~~~~~~~~~~ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:85:9 + --> tests/ui/cast.rs:79:9 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | 1f32 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `i32` may truncate the value - --> tests/ui/cast.rs:88:9 + --> tests/ui/cast.rs:82:9 | LL | 1f64 as i32; | ^^^^^^^^^^^ @@ -173,7 +173,7 @@ LL | 1f64 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may truncate the value - --> tests/ui/cast.rs:91:9 + --> tests/ui/cast.rs:85:9 | LL | 1f32 as u8; | ^^^^^^^^^^ @@ -181,13 +181,13 @@ LL | 1f32 as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:91:9 + --> tests/ui/cast.rs:85:9 | LL | 1f32 as u8; | ^^^^^^^^^^ error: casting `u8` to `i8` may wrap around the value - --> tests/ui/cast.rs:98:5 + --> tests/ui/cast.rs:90:5 | LL | 1u8 as i8; | ^^^^^^^^^ @@ -196,31 +196,31 @@ LL | 1u8 as i8; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `u16` to `i16` may wrap around the value - --> tests/ui/cast.rs:102:5 + --> tests/ui/cast.rs:93:5 | LL | 1u16 as i16; | ^^^^^^^^^^^ error: casting `u32` to `i32` may wrap around the value - --> tests/ui/cast.rs:105:5 + --> tests/ui/cast.rs:96:5 | LL | 1u32 as i32; | ^^^^^^^^^^^ error: casting `u64` to `i64` may wrap around the value - --> tests/ui/cast.rs:108:5 + --> tests/ui/cast.rs:99:5 | LL | 1u64 as i64; | ^^^^^^^^^^^ error: casting `usize` to `isize` may wrap around the value - --> tests/ui/cast.rs:111:5 + --> tests/ui/cast.rs:102:5 | LL | 1usize as isize; | ^^^^^^^^^^^^^^^ error: casting `usize` to `i8` may truncate the value - --> tests/ui/cast.rs:115:5 + --> tests/ui/cast.rs:106:5 | LL | 1usize as i8; | ^^^^^^^^^^^^ @@ -232,7 +232,7 @@ LL | i8::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may truncate the value - --> tests/ui/cast.rs:119:5 + --> tests/ui/cast.rs:110:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -244,7 +244,7 @@ LL | i16::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:119:5 + --> tests/ui/cast.rs:110:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | 1usize as i16; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:126:5 + --> tests/ui/cast.rs:115:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -265,19 +265,19 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:126:5 + --> tests/ui/cast.rs:115:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:132:5 + --> tests/ui/cast.rs:120:5 | LL | 1usize as i64; | ^^^^^^^^^^^^^ error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:138:5 + --> tests/ui/cast.rs:126:5 | LL | 1u16 as isize; | ^^^^^^^^^^^^^ @@ -286,13 +286,13 @@ LL | 1u16 as isize; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:143:5 + --> tests/ui/cast.rs:130:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:147:5 + --> tests/ui/cast.rs:134:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -304,55 +304,55 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:147:5 + --> tests/ui/cast.rs:134:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:154:5 + --> tests/ui/cast.rs:140:5 | LL | -1i32 as u32; | ^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:158:5 + --> tests/ui/cast.rs:144:5 | LL | -1isize as usize; | ^^^^^^^^^^^^^^^^ error: casting `i8` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:170:5 + --> tests/ui/cast.rs:156:5 | LL | (i8::MIN).abs() as u8; | ^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:175:5 + --> tests/ui/cast.rs:161:5 | LL | (-1i64).abs() as u64; | ^^^^^^^^^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:177:5 + --> tests/ui/cast.rs:163:5 | LL | (-1isize).abs() as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:185:5 + --> tests/ui/cast.rs:171:5 | LL | (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:201:5 + --> tests/ui/cast.rs:187:5 | LL | (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `i8` may truncate the value - --> tests/ui/cast.rs:253:5 + --> tests/ui/cast.rs:239:5 | LL | (-99999999999i64).min(1) as i8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -364,7 +364,7 @@ LL | i8::try_from((-99999999999i64).min(1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:268:5 + --> tests/ui/cast.rs:253:5 | LL | 999999u64.clamp(0, 256) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -376,7 +376,7 @@ LL | u8::try_from(999999u64.clamp(0, 256)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E2` to `u8` may truncate the value - --> tests/ui/cast.rs:292:21 + --> tests/ui/cast.rs:276:21 | LL | let _ = self as u8; | ^^^^^^^^^^ @@ -388,7 +388,7 @@ LL | let _ = u8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E2::B` to `u8` will truncate the value - --> tests/ui/cast.rs:295:21 + --> tests/ui/cast.rs:279:21 | LL | let _ = Self::B as u8; | ^^^^^^^^^^^^^ @@ -397,7 +397,7 @@ LL | let _ = Self::B as u8; = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]` error: casting `main::E5` to `i8` may truncate the value - --> tests/ui/cast.rs:338:21 + --> tests/ui/cast.rs:321:21 | LL | let _ = self as i8; | ^^^^^^^^^^ @@ -409,13 +409,13 @@ LL | let _ = i8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E5::A` to `i8` will truncate the value - --> tests/ui/cast.rs:341:21 + --> tests/ui/cast.rs:324:21 | LL | let _ = Self::A as i8; | ^^^^^^^^^^^^^ error: casting `main::E6` to `i16` may truncate the value - --> tests/ui/cast.rs:359:21 + --> tests/ui/cast.rs:342:21 | LL | let _ = self as i16; | ^^^^^^^^^^^ @@ -427,7 +427,7 @@ LL | let _ = i16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:379:21 + --> tests/ui/cast.rs:362:21 | LL | let _ = self as usize; | ^^^^^^^^^^^^^ @@ -439,7 +439,7 @@ LL | let _ = usize::try_from(self); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E10` to `u16` may truncate the value - --> tests/ui/cast.rs:427:21 + --> tests/ui/cast.rs:410:21 | LL | let _ = self as u16; | ^^^^^^^^^^^ @@ -451,7 +451,7 @@ LL | let _ = u16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:439:13 + --> tests/ui/cast.rs:422:13 | LL | let c = (q >> 16) as u8; | ^^^^^^^^^^^^^^^ @@ -463,7 +463,7 @@ LL | let c = u8::try_from(q >> 16); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:444:13 + --> tests/ui/cast.rs:427:13 | LL | let c = (q / 1000) as u8; | ^^^^^^^^^^^^^^^^ @@ -475,85 +475,85 @@ LL | let c = u8::try_from(q / 1000); | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:457:9 + --> tests/ui/cast.rs:440:9 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:463:32 + --> tests/ui/cast.rs:446:32 | LL | let _a = |x: i32| -> u32 { (x * x * x * x) as u32 }; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:466:5 + --> tests/ui/cast.rs:449:5 | LL | (2_i32).checked_pow(3).unwrap() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:468:5 + --> tests/ui/cast.rs:451:5 | LL | (-2_i32).pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:474:5 + --> tests/ui/cast.rs:456:5 | LL | (-5_i32 % 2) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:477:5 + --> tests/ui/cast.rs:459:5 | LL | (-5_i32 % -2) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:481:5 + --> tests/ui/cast.rs:463:5 | LL | (-2_i32 >> 1) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:486:5 + --> tests/ui/cast.rs:467:5 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:488:5 + --> tests/ui/cast.rs:469:5 | LL | (x * x * x) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:493:5 + --> tests/ui/cast.rs:473:5 | LL | (y * y * y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:496:5 + --> tests/ui/cast.rs:476:5 | LL | (y * y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:498:5 + --> tests/ui/cast.rs:478:5 | LL | (y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:501:5 + --> tests/ui/cast.rs:481:5 | LL | (y / y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `/` - --> tests/ui/cast.rs:501:6 + --> tests/ui/cast.rs:481:6 | LL | (y / y * y * -2) as u16; | ^^^^^ @@ -561,97 +561,97 @@ LL | (y / y * y * -2) as u16; = note: `#[deny(clippy::eq_op)]` on by default error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:506:5 + --> tests/ui/cast.rs:485:5 | LL | (y + y + y + -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:509:5 + --> tests/ui/cast.rs:488:5 | LL | (y + y + y + 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:514:5 + --> tests/ui/cast.rs:492:5 | LL | (z + -2) as u16; | ^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:517:5 + --> tests/ui/cast.rs:495:5 | LL | (z + z + 2) as u16; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:521:9 + --> tests/ui/cast.rs:499:9 | LL | (a * a * b * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:523:9 + --> tests/ui/cast.rs:501:9 | LL | (a * b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:526:9 + --> tests/ui/cast.rs:504:9 | LL | (a * -b * c) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:529:9 + --> tests/ui/cast.rs:507:9 | LL | (a * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:531:9 + --> tests/ui/cast.rs:509:9 | LL | (a * -2) as u32; | ^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:534:9 + --> tests/ui/cast.rs:512:9 | LL | (a * b * c * -2) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:537:9 + --> tests/ui/cast.rs:515:9 | LL | (a / b) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:539:9 + --> tests/ui/cast.rs:517:9 | LL | (a / b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:542:9 + --> tests/ui/cast.rs:520:9 | LL | (a / b + b * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:545:9 + --> tests/ui/cast.rs:523:9 | LL | a.saturating_pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:548:9 + --> tests/ui/cast.rs:526:9 | LL | (a.abs() * b.pow(2) / c.abs()) as u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:557:21 + --> tests/ui/cast.rs:534:21 | LL | let _ = i32::MIN as u32; // cast_sign_loss | ^^^^^^^^^^^^^^^ @@ -662,7 +662,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:559:21 + --> tests/ui/cast.rs:536:21 | LL | let _ = u32::MAX as u8; // cast_possible_truncation | ^^^^^^^^^^^^^^ @@ -678,7 +678,7 @@ LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:561:21 + --> tests/ui/cast.rs:538:21 | LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -690,7 +690,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:571:5 + --> tests/ui/cast.rs:548:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -702,13 +702,13 @@ LL | usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:571:5 + --> tests/ui/cast.rs:548:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:588:5 + --> tests/ui/cast.rs:565:5 | LL | (256 & 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ LL | u8::try_from(256 & 999999u64); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:591:5 + --> tests/ui/cast.rs:568:5 | LL | (255 % 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_alignment.rs b/tests/ui/cast_alignment.rs index 1f14cb8a8452..5773ffddb917 100644 --- a/tests/ui/cast_alignment.rs +++ b/tests/ui/cast_alignment.rs @@ -19,11 +19,9 @@ fn main() { (&1u8 as *const u8) as *const u16; //~^ cast_ptr_alignment - (&mut 1u8 as *mut u8) as *mut u16; //~^ cast_ptr_alignment - // cast to more-strictly-aligned type, but with the `pointer::cast` function. (&1u8 as *const u8).cast::(); //~^ cast_ptr_alignment @@ -31,7 +29,6 @@ fn main() { (&mut 1u8 as *mut u8).cast::(); //~^ cast_ptr_alignment - /* These should be ok */ // not a pointer type diff --git a/tests/ui/cast_alignment.stderr b/tests/ui/cast_alignment.stderr index a1598eb1b6b4..6d9a81f0ecfd 100644 --- a/tests/ui/cast_alignment.stderr +++ b/tests/ui/cast_alignment.stderr @@ -8,19 +8,19 @@ LL | (&1u8 as *const u8) as *const u16; = help: to override `-D warnings` add `#[allow(clippy::cast_ptr_alignment)]` error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:23:5 + --> tests/ui/cast_alignment.rs:22:5 | LL | (&mut 1u8 as *mut u8) as *mut u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:28:5 + --> tests/ui/cast_alignment.rs:26:5 | LL | (&1u8 as *const u8).cast::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:31:5 + --> tests/ui/cast_alignment.rs:29:5 | LL | (&mut 1u8 as *mut u8).cast::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_enum_constructor.rs b/tests/ui/cast_enum_constructor.rs index 9de5b4095556..eecf56f71a33 100644 --- a/tests/ui/cast_enum_constructor.rs +++ b/tests/ui/cast_enum_constructor.rs @@ -13,7 +13,6 @@ fn main() { let _ = Foo::Y as usize; //~^ cast_enum_constructor - let _ = Foo::Y as isize; //~^ cast_enum_constructor diff --git a/tests/ui/cast_enum_constructor.stderr b/tests/ui/cast_enum_constructor.stderr index 890d88cacdf2..67cca6807315 100644 --- a/tests/ui/cast_enum_constructor.stderr +++ b/tests/ui/cast_enum_constructor.stderr @@ -8,7 +8,7 @@ LL | let _ = Foo::Y as usize; = help: to override `-D warnings` add `#[allow(clippy::cast_enum_constructor)]` error: cast of an enum tuple constructor to an integer - --> tests/ui/cast_enum_constructor.rs:17:13 + --> tests/ui/cast_enum_constructor.rs:16:13 | LL | let _ = Foo::Y as isize; | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_lossless_integer.fixed b/tests/ui/cast_lossless_integer.fixed index cd689801702a..2af2dbd1282d 100644 --- a/tests/ui/cast_lossless_integer.fixed +++ b/tests/ui/cast_lossless_integer.fixed @@ -29,7 +29,6 @@ fn main() { i128::from(0u8); //~^ cast_lossless - u32::from(0u16); //~^ cast_lossless @@ -48,7 +47,6 @@ fn main() { i128::from(0u16); //~^ cast_lossless - u64::from(0u32); //~^ cast_lossless @@ -61,14 +59,12 @@ fn main() { i128::from(0u32); //~^ cast_lossless - u128::from(0u64); //~^ cast_lossless i128::from(0u64); //~^ cast_lossless - i16::from(0i8); //~^ cast_lossless @@ -81,7 +77,6 @@ fn main() { i128::from(0i8); //~^ cast_lossless - i32::from(0i16); //~^ cast_lossless @@ -91,27 +86,22 @@ fn main() { i128::from(0i16); //~^ cast_lossless - i64::from(0i32); //~^ cast_lossless i128::from(0i32); //~^ cast_lossless - i128::from(0i64); //~^ cast_lossless - // Test with an expression wrapped in parens let _ = u16::from(1u8 + 1u8); //~^ cast_lossless - let _ = I64Alias::from(1i8); //~^ cast_lossless - let _: u16 = 0u8.into(); //~^ cast_lossless @@ -123,7 +113,6 @@ fn main() { let _: u32 = (1i8 as u16).into(); //~^ cast_lossless - } // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, @@ -162,7 +151,6 @@ fn issue11458() { let _ = i32::from(sign_cast!(x, u8, i8) + 1); //~^ cast_lossless - } fn issue12695() { @@ -170,7 +158,6 @@ fn issue12695() { () => { u32::from(1u8) //~^ cast_lossless - }; } diff --git a/tests/ui/cast_lossless_integer.rs b/tests/ui/cast_lossless_integer.rs index 03c1a77c34ad..c65b725bb729 100644 --- a/tests/ui/cast_lossless_integer.rs +++ b/tests/ui/cast_lossless_integer.rs @@ -29,7 +29,6 @@ fn main() { 0u8 as i128; //~^ cast_lossless - 0u16 as u32; //~^ cast_lossless @@ -48,7 +47,6 @@ fn main() { 0u16 as i128; //~^ cast_lossless - 0u32 as u64; //~^ cast_lossless @@ -61,14 +59,12 @@ fn main() { 0u32 as i128; //~^ cast_lossless - 0u64 as u128; //~^ cast_lossless 0u64 as i128; //~^ cast_lossless - 0i8 as i16; //~^ cast_lossless @@ -81,7 +77,6 @@ fn main() { 0i8 as i128; //~^ cast_lossless - 0i16 as i32; //~^ cast_lossless @@ -91,27 +86,22 @@ fn main() { 0i16 as i128; //~^ cast_lossless - 0i32 as i64; //~^ cast_lossless 0i32 as i128; //~^ cast_lossless - 0i64 as i128; //~^ cast_lossless - // Test with an expression wrapped in parens let _ = (1u8 + 1u8) as u16; //~^ cast_lossless - let _ = 1i8 as I64Alias; //~^ cast_lossless - let _: u16 = 0u8 as _; //~^ cast_lossless @@ -123,7 +113,6 @@ fn main() { let _: u32 = 1i8 as u16 as _; //~^ cast_lossless - } // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const, @@ -162,7 +151,6 @@ fn issue11458() { let _ = (sign_cast!(x, u8, i8) + 1) as i32; //~^ cast_lossless - } fn issue12695() { @@ -170,7 +158,6 @@ fn issue12695() { () => { 1u8 as u32 //~^ cast_lossless - }; } diff --git a/tests/ui/cast_lossless_integer.stderr b/tests/ui/cast_lossless_integer.stderr index 3bec773ff861..393c20f68294 100644 --- a/tests/ui/cast_lossless_integer.stderr +++ b/tests/ui/cast_lossless_integer.stderr @@ -97,7 +97,7 @@ LL | i128::from(0u8); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:33:5 + --> tests/ui/cast_lossless_integer.rs:32:5 | LL | 0u16 as u32; | ^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | u32::from(0u16); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:36:5 + --> tests/ui/cast_lossless_integer.rs:35:5 | LL | 0u16 as i32; | ^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | i32::from(0u16); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `u64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:39:5 + --> tests/ui/cast_lossless_integer.rs:38:5 | LL | 0u16 as u64; | ^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | u64::from(0u16); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:42:5 + --> tests/ui/cast_lossless_integer.rs:41:5 | LL | 0u16 as i64; | ^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | i64::from(0u16); | ~~~~~~~~~~~~~~~ error: casts from `u16` to `u128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:45:5 + --> tests/ui/cast_lossless_integer.rs:44:5 | LL | 0u16 as u128; | ^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | u128::from(0u16); | ~~~~~~~~~~~~~~~~ error: casts from `u16` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:48:5 + --> tests/ui/cast_lossless_integer.rs:47:5 | LL | 0u16 as i128; | ^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | i128::from(0u16); | ~~~~~~~~~~~~~~~~ error: casts from `u32` to `u64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:52:5 + --> tests/ui/cast_lossless_integer.rs:50:5 | LL | 0u32 as u64; | ^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | u64::from(0u32); | ~~~~~~~~~~~~~~~ error: casts from `u32` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:55:5 + --> tests/ui/cast_lossless_integer.rs:53:5 | LL | 0u32 as i64; | ^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL | i64::from(0u32); | ~~~~~~~~~~~~~~~ error: casts from `u32` to `u128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:58:5 + --> tests/ui/cast_lossless_integer.rs:56:5 | LL | 0u32 as u128; | ^^^^^^^^^^^^ @@ -205,7 +205,7 @@ LL | u128::from(0u32); | ~~~~~~~~~~~~~~~~ error: casts from `u32` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:61:5 + --> tests/ui/cast_lossless_integer.rs:59:5 | LL | 0u32 as i128; | ^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | i128::from(0u32); | ~~~~~~~~~~~~~~~~ error: casts from `u64` to `u128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:65:5 + --> tests/ui/cast_lossless_integer.rs:62:5 | LL | 0u64 as u128; | ^^^^^^^^^^^^ @@ -229,7 +229,7 @@ LL | u128::from(0u64); | ~~~~~~~~~~~~~~~~ error: casts from `u64` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:68:5 + --> tests/ui/cast_lossless_integer.rs:65:5 | LL | 0u64 as i128; | ^^^^^^^^^^^^ @@ -241,7 +241,7 @@ LL | i128::from(0u64); | ~~~~~~~~~~~~~~~~ error: casts from `i8` to `i16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:72:5 + --> tests/ui/cast_lossless_integer.rs:68:5 | LL | 0i8 as i16; | ^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | i16::from(0i8); | ~~~~~~~~~~~~~~ error: casts from `i8` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:75:5 + --> tests/ui/cast_lossless_integer.rs:71:5 | LL | 0i8 as i32; | ^^^^^^^^^^ @@ -265,7 +265,7 @@ LL | i32::from(0i8); | ~~~~~~~~~~~~~~ error: casts from `i8` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:78:5 + --> tests/ui/cast_lossless_integer.rs:74:5 | LL | 0i8 as i64; | ^^^^^^^^^^ @@ -277,7 +277,7 @@ LL | i64::from(0i8); | ~~~~~~~~~~~~~~ error: casts from `i8` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:81:5 + --> tests/ui/cast_lossless_integer.rs:77:5 | LL | 0i8 as i128; | ^^^^^^^^^^^ @@ -289,7 +289,7 @@ LL | i128::from(0i8); | ~~~~~~~~~~~~~~~ error: casts from `i16` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:85:5 + --> tests/ui/cast_lossless_integer.rs:80:5 | LL | 0i16 as i32; | ^^^^^^^^^^^ @@ -301,7 +301,7 @@ LL | i32::from(0i16); | ~~~~~~~~~~~~~~~ error: casts from `i16` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:88:5 + --> tests/ui/cast_lossless_integer.rs:83:5 | LL | 0i16 as i64; | ^^^^^^^^^^^ @@ -313,7 +313,7 @@ LL | i64::from(0i16); | ~~~~~~~~~~~~~~~ error: casts from `i16` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:91:5 + --> tests/ui/cast_lossless_integer.rs:86:5 | LL | 0i16 as i128; | ^^^^^^^^^^^^ @@ -325,7 +325,7 @@ LL | i128::from(0i16); | ~~~~~~~~~~~~~~~~ error: casts from `i32` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:95:5 + --> tests/ui/cast_lossless_integer.rs:89:5 | LL | 0i32 as i64; | ^^^^^^^^^^^ @@ -337,7 +337,7 @@ LL | i64::from(0i32); | ~~~~~~~~~~~~~~~ error: casts from `i32` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:98:5 + --> tests/ui/cast_lossless_integer.rs:92:5 | LL | 0i32 as i128; | ^^^^^^^^^^^^ @@ -349,7 +349,7 @@ LL | i128::from(0i32); | ~~~~~~~~~~~~~~~~ error: casts from `i64` to `i128` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:102:5 + --> tests/ui/cast_lossless_integer.rs:95:5 | LL | 0i64 as i128; | ^^^^^^^^^^^^ @@ -361,7 +361,7 @@ LL | i128::from(0i64); | ~~~~~~~~~~~~~~~~ error: casts from `u8` to `u16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:107:13 + --> tests/ui/cast_lossless_integer.rs:99:13 | LL | let _ = (1u8 + 1u8) as u16; | ^^^^^^^^^^^^^^^^^^ @@ -373,7 +373,7 @@ LL | let _ = u16::from(1u8 + 1u8); | ~~~~~~~~~~~~~~~~~~~~ error: casts from `i8` to `i64` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:111:13 + --> tests/ui/cast_lossless_integer.rs:102:13 | LL | let _ = 1i8 as I64Alias; | ^^^^^^^^^^^^^^^ @@ -385,7 +385,7 @@ LL | let _ = I64Alias::from(1i8); | ~~~~~~~~~~~~~~~~~~~ error: casts from `u8` to `u16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:115:18 + --> tests/ui/cast_lossless_integer.rs:105:18 | LL | let _: u16 = 0u8 as _; | ^^^^^^^^ @@ -397,7 +397,7 @@ LL | let _: u16 = 0u8.into(); | ~~~~~~~~~~ error: casts from `i8` to `i16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:118:18 + --> tests/ui/cast_lossless_integer.rs:108:18 | LL | let _: i16 = -1i8 as _; | ^^^^^^^^^ @@ -409,7 +409,7 @@ LL | let _: i16 = (-1i8).into(); | ~~~~~~~~~~~~~ error: casts from `u8` to `u16` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:121:18 + --> tests/ui/cast_lossless_integer.rs:111:18 | LL | let _: u16 = (1u8 + 2) as _; | ^^^^^^^^^^^^^^ @@ -421,7 +421,7 @@ LL | let _: u16 = (1u8 + 2).into(); | ~~~~~~~~~~~~~~~~ error: casts from `u16` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:124:18 + --> tests/ui/cast_lossless_integer.rs:114:18 | LL | let _: u32 = 1i8 as u16 as _; | ^^^^^^^^^^^^^^^ @@ -433,7 +433,7 @@ LL | let _: u32 = (1i8 as u16).into(); | ~~~~~~~~~~~~~~~~~~~ error: casts from `i8` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:160:13 + --> tests/ui/cast_lossless_integer.rs:149:13 | LL | let _ = sign_cast!(x, u8, i8) as i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -445,7 +445,7 @@ LL | let _ = i32::from(sign_cast!(x, u8, i8)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casts from `i8` to `i32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:163:13 + --> tests/ui/cast_lossless_integer.rs:152:13 | LL | let _ = (sign_cast!(x, u8, i8) + 1) as i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -457,7 +457,7 @@ LL | let _ = i32::from(sign_cast!(x, u8, i8) + 1); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casts from `u8` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:171:13 + --> tests/ui/cast_lossless_integer.rs:159:13 | LL | 1u8 as u32 | ^^^^^^^^^^ @@ -473,7 +473,7 @@ LL | u32::from(1u8) | error: casts from `u8` to `u32` can be expressed infallibly using `From` - --> tests/ui/cast_lossless_integer.rs:187:13 + --> tests/ui/cast_lossless_integer.rs:174:13 | LL | let _ = 0u8 as ty!(); | ^^^^^^^^^^^^ diff --git a/tests/ui/cast_nan_to_int.rs b/tests/ui/cast_nan_to_int.rs index 227dae3b1c4b..72e61b3542e2 100644 --- a/tests/ui/cast_nan_to_int.rs +++ b/tests/ui/cast_nan_to_int.rs @@ -7,29 +7,21 @@ fn main() { let _ = (0.0_f32 / -0.0) as usize; //~^ cast_nan_to_int - let _ = (f64::INFINITY * -0.0) as usize; //~^ cast_nan_to_int - let _ = (0.0 * f32::INFINITY) as usize; //~^ cast_nan_to_int - - let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize; //~^ cast_nan_to_int - let _ = (f32::INFINITY - f32::INFINITY) as usize; //~^ cast_nan_to_int - let _ = (f32::INFINITY / f32::NEG_INFINITY) as usize; //~^ cast_nan_to_int - - // those won't be linted: let _ = (1.0_f32 / 0.0) as usize; let _ = (f32::INFINITY * f32::NEG_INFINITY) as usize; diff --git a/tests/ui/cast_nan_to_int.stderr b/tests/ui/cast_nan_to_int.stderr index 0f9b3565485f..15ca3876ea18 100644 --- a/tests/ui/cast_nan_to_int.stderr +++ b/tests/ui/cast_nan_to_int.stderr @@ -9,7 +9,7 @@ LL | let _ = (0.0_f32 / -0.0) as usize; = help: to override `-D warnings` add `#[allow(clippy::cast_nan_to_int)]` error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:11:13 + --> tests/ui/cast_nan_to_int.rs:10:13 | LL | let _ = (f64::INFINITY * -0.0) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = (f64::INFINITY * -0.0) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:15:13 + --> tests/ui/cast_nan_to_int.rs:13:13 | LL | let _ = (0.0 * f32::INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = (0.0 * f32::INFINITY) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:20:13 + --> tests/ui/cast_nan_to_int.rs:16:13 | LL | let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:24:13 + --> tests/ui/cast_nan_to_int.rs:19:13 | LL | let _ = (f32::INFINITY - f32::INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = (f32::INFINITY - f32::INFINITY) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:28:13 + --> tests/ui/cast_nan_to_int.rs:22:13 | LL | let _ = (f32::INFINITY / f32::NEG_INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_slice_different_sizes.rs b/tests/ui/cast_slice_different_sizes.rs index 2db14d4f2515..518ed77ab220 100644 --- a/tests/ui/cast_slice_different_sizes.rs +++ b/tests/ui/cast_slice_different_sizes.rs @@ -10,16 +10,13 @@ fn main() { let b = a as *const [u8]; //~^ cast_slice_different_sizes - let c = b as *const [u32]; //~^ cast_slice_different_sizes - // loses data let loss = r_x as *const [i32] as *const [u8]; //~^ cast_slice_different_sizes - // Cast back to same size but different type loses no data, just type conversion // This is weird code but there's no reason for this lint specifically to fire *twice* on it let restore = r_x as *const [i32] as *const [u8] as *const [u32]; @@ -29,7 +26,7 @@ fn main() { //~^ cast_slice_different_sizes let loss_block_2 = { - //~^ cast_slice_different_sizes + //~^ cast_slice_different_sizes let _ = (); r_x as *const [i32] @@ -65,48 +62,47 @@ fn foo2(x: *mut [u8]) -> *mut [u8] { // Test that casts as part of function returns work fn bar(x: *mut [u16]) -> *mut [u8] { -//~^ cast_slice_different_sizes + //~^ cast_slice_different_sizes x as *mut [u8] } fn uwu(x: *mut [u16]) -> *mut [u8] { -//~^ cast_slice_different_sizes + //~^ cast_slice_different_sizes x as *mut _ } fn bar2(x: *mut [u16]) -> *mut [u8] { -//~^ cast_slice_different_sizes + //~^ cast_slice_different_sizes x as _ } // constify fn bar3(x: *mut [u16]) -> *const [u8] { -//~^ cast_slice_different_sizes + //~^ cast_slice_different_sizes x as _ } // unconstify fn bar4(x: *const [u16]) -> *mut [u8] { -//~^ cast_slice_different_sizes + //~^ cast_slice_different_sizes x as _ } // function returns plus blocks fn blocks(x: *mut [u16]) -> *mut [u8] { -//~^ cast_slice_different_sizes + //~^ cast_slice_different_sizes ({ x }) as _ } fn more_blocks(x: *mut [u16]) -> *mut [u8] { -//~^ cast_slice_different_sizes + //~^ cast_slice_different_sizes { ({ x }) as _ } //~^ cast_slice_different_sizes - } diff --git a/tests/ui/cast_slice_different_sizes.stderr b/tests/ui/cast_slice_different_sizes.stderr index e028e13db616..307d37ac2ea8 100644 --- a/tests/ui/cast_slice_different_sizes.stderr +++ b/tests/ui/cast_slice_different_sizes.stderr @@ -7,25 +7,25 @@ LL | let b = a as *const [u8]; = note: `#[deny(clippy::cast_slice_different_sizes)]` on by default error: casting between raw pointers to `[u8]` (element size 1) and `[u32]` (element size 4) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:14:13 + --> tests/ui/cast_slice_different_sizes.rs:13:13 | LL | let c = b as *const [u32]; | ^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(b as *const u32, ..)` error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:19:16 + --> tests/ui/cast_slice_different_sizes.rs:17:16 | LL | let loss = r_x as *const [i32] as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)` error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:28:24 + --> tests/ui/cast_slice_different_sizes.rs:25:24 | LL | let loss_block_1 = { r_x as *const [i32] } as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts({ r_x as *const [i32] } as *const u8, ..)` error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:31:24 + --> tests/ui/cast_slice_different_sizes.rs:28:24 | LL | let loss_block_2 = { | ________________________^ @@ -47,13 +47,13 @@ LL ~ } as *const u8, ..); | error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:50:27 + --> tests/ui/cast_slice_different_sizes.rs:47:27 | LL | let long_chain_loss = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:67:36 + --> tests/ui/cast_slice_different_sizes.rs:64:36 | LL | fn bar(x: *mut [u16]) -> *mut [u8] { | ____________________________________^ @@ -64,7 +64,7 @@ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:73:36 + --> tests/ui/cast_slice_different_sizes.rs:70:36 | LL | fn uwu(x: *mut [u16]) -> *mut [u8] { | ____________________________________^ @@ -75,7 +75,7 @@ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:79:37 + --> tests/ui/cast_slice_different_sizes.rs:76:37 | LL | fn bar2(x: *mut [u16]) -> *mut [u8] { | _____________________________________^ @@ -86,7 +86,7 @@ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:86:39 + --> tests/ui/cast_slice_different_sizes.rs:83:39 | LL | fn bar3(x: *mut [u16]) -> *const [u8] { | _______________________________________^ @@ -97,7 +97,7 @@ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(x as *const u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:93:39 + --> tests/ui/cast_slice_different_sizes.rs:90:39 | LL | fn bar4(x: *const [u16]) -> *mut [u8] { | _______________________________________^ @@ -108,7 +108,7 @@ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:100:39 + --> tests/ui/cast_slice_different_sizes.rs:97:39 | LL | fn blocks(x: *mut [u16]) -> *mut [u8] { | _______________________________________^ @@ -119,19 +119,19 @@ LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:106:44 + --> tests/ui/cast_slice_different_sizes.rs:103:44 | LL | fn more_blocks(x: *mut [u16]) -> *mut [u8] { | ____________________________________________^ LL | | LL | | LL | | { ({ x }) as _ } -... | +LL | | LL | | } | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)` error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count - --> tests/ui/cast_slice_different_sizes.rs:109:5 + --> tests/ui/cast_slice_different_sizes.rs:106:5 | LL | { ({ x }) as _ } | ^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)` diff --git a/tests/ui/char_lit_as_u8.rs b/tests/ui/char_lit_as_u8.rs index 41e3c5e545cb..c8774c7f3091 100644 --- a/tests/ui/char_lit_as_u8.rs +++ b/tests/ui/char_lit_as_u8.rs @@ -4,6 +4,4 @@ fn main() { // no suggestion, since a byte literal won't work. let _ = '❤' as u8; //~^ char_lit_as_u8 - - } diff --git a/tests/ui/checked_unwrap/complex_conditionals.rs b/tests/ui/checked_unwrap/complex_conditionals.rs index 3eedb659ebf6..7d0bcc547a42 100644 --- a/tests/ui/checked_unwrap/complex_conditionals.rs +++ b/tests/ui/checked_unwrap/complex_conditionals.rs @@ -24,7 +24,6 @@ fn test_complex_conditions() { // unnecessary y.unwrap_err(); //~^ unnecessary_unwrap - } else { // not statically determinable whether any of the following will always succeed or always fail: x.unwrap(); @@ -53,7 +52,6 @@ fn test_complex_conditions() { // unnecessary y.unwrap_err(); //~^ unnecessary_unwrap - } let z: Result<(), ()> = Ok(()); if x.is_ok() && !(y.is_ok() || z.is_err()) { @@ -80,7 +78,6 @@ fn test_complex_conditions() { // will panic z.unwrap_err(); //~^ panicking_unwrap - } if x.is_ok() || !(y.is_ok() && z.is_err()) { // not statically determinable whether any of the following will always succeed or always fail: @@ -111,7 +108,6 @@ fn test_complex_conditions() { // unnecessary z.unwrap_err(); //~^ unnecessary_unwrap - } } diff --git a/tests/ui/checked_unwrap/complex_conditionals.stderr b/tests/ui/checked_unwrap/complex_conditionals.stderr index 02118affe731..d3905850c970 100644 --- a/tests/ui/checked_unwrap/complex_conditionals.stderr +++ b/tests/ui/checked_unwrap/complex_conditionals.stderr @@ -50,7 +50,7 @@ LL | y.unwrap_err(); = help: try using `if let` or `match` error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:42:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:41:9 | LL | if x.is_ok() || y.is_ok() { | --------- because of this check @@ -59,7 +59,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:46:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:45:9 | LL | if x.is_ok() || y.is_ok() { | --------- the check is happening here @@ -70,7 +70,7 @@ LL | x.unwrap_err(); = help: try using `if let` or `match` error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:50:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:49:9 | LL | if x.is_ok() || y.is_ok() { | --------- because of this check @@ -79,7 +79,7 @@ LL | y.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:54:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:53:9 | LL | if x.is_ok() || y.is_ok() { | --------- the check is happening here @@ -90,7 +90,7 @@ LL | y.unwrap_err(); = help: try using `if let` or `match` error: called `unwrap` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:61:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:59:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- the check is happening here @@ -101,7 +101,7 @@ LL | x.unwrap(); = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:65:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:63:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- because of this check @@ -110,7 +110,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:69:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:67:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- because of this check @@ -119,7 +119,7 @@ LL | y.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:73:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:71:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- the check is happening here @@ -130,7 +130,7 @@ LL | y.unwrap_err(); = help: try using `if let` or `match` error: called `unwrap` on `z` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/complex_conditionals.rs:77:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:75:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | ---------- the check is happening here @@ -141,7 +141,7 @@ LL | z.unwrap(); = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:81:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:79:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | ---------- because of this check @@ -150,7 +150,7 @@ LL | z.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:92:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:89:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- because of this check @@ -159,7 +159,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:96:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:93:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- the check is happening here @@ -170,7 +170,7 @@ LL | x.unwrap_err(); = help: try using `if let` or `match` error: called `unwrap` on `y` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:100:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:97:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- the check is happening here @@ -181,7 +181,7 @@ LL | y.unwrap(); = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:104:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:101:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- because of this check @@ -190,7 +190,7 @@ LL | y.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:108:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:105:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | ---------- because of this check @@ -199,7 +199,7 @@ LL | z.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `z` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/complex_conditionals.rs:112:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:109:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | ---------- the check is happening here diff --git a/tests/ui/checked_unwrap/simple_conditionals.rs b/tests/ui/checked_unwrap/simple_conditionals.rs index 7736643d894c..4101897d3800 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.rs +++ b/tests/ui/checked_unwrap/simple_conditionals.rs @@ -50,7 +50,6 @@ fn main() { // unnecessary x.expect("an error message"); //~^ unnecessary_unwrap - } else { // will panic x.unwrap(); @@ -59,18 +58,15 @@ fn main() { // will panic x.expect("an error message"); //~^ panicking_unwrap - } if x.is_none() { // will panic x.unwrap(); //~^ panicking_unwrap - } else { // unnecessary x.unwrap(); //~^ unnecessary_unwrap - } m!(x); // ok @@ -92,7 +88,6 @@ fn main() { // will panic x.unwrap_err(); //~^ panicking_unwrap - } else { // will panic x.unwrap(); @@ -105,7 +100,6 @@ fn main() { // unnecessary x.unwrap_err(); //~^ unnecessary_unwrap - } if x.is_err() { // will panic @@ -115,7 +109,6 @@ fn main() { // unnecessary x.unwrap_err(); //~^ unnecessary_unwrap - } else { // unnecessary x.unwrap(); @@ -124,7 +117,6 @@ fn main() { // will panic x.unwrap_err(); //~^ panicking_unwrap - } if x.is_ok() { x = Err(()); @@ -150,11 +142,9 @@ fn issue11371() { if option.is_some() { option.as_ref().unwrap(); //~^ unnecessary_unwrap - } else { option.as_ref().unwrap(); //~^ panicking_unwrap - } let result = Ok::<(), ()>(()); @@ -162,33 +152,27 @@ fn issue11371() { if result.is_ok() { result.as_ref().unwrap(); //~^ unnecessary_unwrap - } else { result.as_ref().unwrap(); //~^ panicking_unwrap - } let mut option = Some(()); if option.is_some() { option.as_mut().unwrap(); //~^ unnecessary_unwrap - } else { option.as_mut().unwrap(); //~^ panicking_unwrap - } let mut result = Ok::<(), ()>(()); if result.is_ok() { result.as_mut().unwrap(); //~^ unnecessary_unwrap - } else { result.as_mut().unwrap(); //~^ panicking_unwrap - } // This should not lint. Statics are, at the time of writing, not linted on anyway, @@ -197,7 +181,7 @@ fn issue11371() { static mut X: Option = Some(123); unsafe { if X.is_some() { - //~^ ERROR: creating a shared reference + //~^ ERROR: creating a shared reference X = None; X.unwrap(); } diff --git a/tests/ui/checked_unwrap/simple_conditionals.stderr b/tests/ui/checked_unwrap/simple_conditionals.stderr index 789a4a8f92bc..c17eaef2326b 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.stderr +++ b/tests/ui/checked_unwrap/simple_conditionals.stderr @@ -23,7 +23,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:56:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:55:9 | LL | if x.is_some() { | ----------- because of this check @@ -38,7 +38,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `expect()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:60:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:59:9 | LL | if x.is_some() { | ----------- because of this check @@ -47,7 +47,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:66:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:64:9 | LL | if x.is_none() { | ----------- because of this check @@ -56,7 +56,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_none` - --> tests/ui/checked_unwrap/simple_conditionals.rs:71:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:68:9 | LL | if x.is_none() { | -------------- help: try: `if let Some() = x` @@ -79,7 +79,7 @@ LL | m!(x); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: called `unwrap` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:85:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:81:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok() = x` @@ -88,7 +88,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `expect` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:89:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:85:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok() = x` @@ -97,7 +97,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:93:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:89:9 | LL | if x.is_ok() { | --------- because of this check @@ -106,7 +106,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:98:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:93:9 | LL | if x.is_ok() { | --------- because of this check @@ -115,7 +115,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: this call to `expect()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:102:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:97:9 | LL | if x.is_ok() { | --------- because of this check @@ -124,7 +124,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:106:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:101:9 | LL | if x.is_ok() { | ------------ help: try: `if let Err() = x` @@ -133,7 +133,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:112:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:106:9 | LL | if x.is_err() { | ---------- because of this check @@ -142,7 +142,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/simple_conditionals.rs:116:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:110:9 | LL | if x.is_err() { | ------------- help: try: `if let Err() = x` @@ -151,7 +151,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/simple_conditionals.rs:121:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:114:9 | LL | if x.is_err() { | ------------- help: try: `if let Ok() = x` @@ -160,7 +160,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:125:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:118:9 | LL | if x.is_err() { | ---------- because of this check @@ -169,7 +169,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:151:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:143:9 | LL | if option.is_some() { | ------------------- help: try: `if let Some() = &option` @@ -177,7 +177,7 @@ LL | option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:155:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:146:9 | LL | if option.is_some() { | ---------------- because of this check @@ -186,7 +186,7 @@ LL | option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:163:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:153:9 | LL | if result.is_ok() { | ----------------- help: try: `if let Ok() = &result` @@ -194,7 +194,7 @@ LL | result.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:167:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:156:9 | LL | if result.is_ok() { | -------------- because of this check @@ -203,7 +203,7 @@ LL | result.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:174:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:162:9 | LL | if option.is_some() { | ------------------- help: try: `if let Some() = &mut option` @@ -211,7 +211,7 @@ LL | option.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:178:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:165:9 | LL | if option.is_some() { | ---------------- because of this check @@ -220,7 +220,7 @@ LL | option.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:185:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:171:9 | LL | if result.is_ok() { | ----------------- help: try: `if let Ok() = &mut result` @@ -228,7 +228,7 @@ LL | result.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:189:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:174:9 | LL | if result.is_ok() { | -------------- because of this check @@ -237,7 +237,7 @@ LL | result.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: creating a shared reference to mutable static is discouraged - --> tests/ui/checked_unwrap/simple_conditionals.rs:199:12 + --> tests/ui/checked_unwrap/simple_conditionals.rs:183:12 | LL | if X.is_some() { | ^^^^^^^^^^^ shared reference to mutable static diff --git a/tests/ui/cmp_null.fixed b/tests/ui/cmp_null.fixed index 27b831950dc7..140ddb10aeb8 100644 --- a/tests/ui/cmp_null.fixed +++ b/tests/ui/cmp_null.fixed @@ -7,13 +7,12 @@ fn main() { let x = 0; let p: *const usize = &x; if p.is_null() { - //~^ cmp_null - + //~^ cmp_null println!("This is surprising!"); } if p.is_null() { - //~^ cmp_null + //~^ cmp_null println!("This is surprising!"); } @@ -21,17 +20,16 @@ fn main() { let mut y = 0; let mut m: *mut usize = &mut y; if m.is_null() { - //~^ cmp_null + //~^ cmp_null println!("This is surprising, too!"); } if m.is_null() { - //~^ cmp_null + //~^ cmp_null println!("This is surprising, too!"); } let _ = (x as *const ()).is_null(); //~^ cmp_null - } diff --git a/tests/ui/cmp_null.rs b/tests/ui/cmp_null.rs index ac1bf83e094c..16ed17765dac 100644 --- a/tests/ui/cmp_null.rs +++ b/tests/ui/cmp_null.rs @@ -7,13 +7,12 @@ fn main() { let x = 0; let p: *const usize = &x; if p == ptr::null() { - //~^ cmp_null - + //~^ cmp_null println!("This is surprising!"); } if ptr::null() == p { - //~^ cmp_null + //~^ cmp_null println!("This is surprising!"); } @@ -21,17 +20,16 @@ fn main() { let mut y = 0; let mut m: *mut usize = &mut y; if m == ptr::null_mut() { - //~^ cmp_null + //~^ cmp_null println!("This is surprising, too!"); } if ptr::null_mut() == m { - //~^ cmp_null + //~^ cmp_null println!("This is surprising, too!"); } let _ = x as *const () == ptr::null(); //~^ cmp_null - } diff --git a/tests/ui/cmp_null.stderr b/tests/ui/cmp_null.stderr index a44dd8067613..6821846d0466 100644 --- a/tests/ui/cmp_null.stderr +++ b/tests/ui/cmp_null.stderr @@ -8,25 +8,25 @@ LL | if p == ptr::null() { = help: to override `-D warnings` add `#[allow(clippy::cmp_null)]` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:15:8 + --> tests/ui/cmp_null.rs:14:8 | LL | if ptr::null() == p { | ^^^^^^^^^^^^^^^^ help: try: `p.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:23:8 + --> tests/ui/cmp_null.rs:22:8 | LL | if m == ptr::null_mut() { | ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:28:8 + --> tests/ui/cmp_null.rs:27:8 | LL | if ptr::null_mut() == m { | ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()` error: comparing with null is better expressed by the `.is_null()` method - --> tests/ui/cmp_null.rs:34:13 + --> tests/ui/cmp_null.rs:33:13 | LL | let _ = x as *const () == ptr::null(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(x as *const ()).is_null()` diff --git a/tests/ui/cmp_owned/comparison_flip.fixed b/tests/ui/cmp_owned/comparison_flip.fixed index a926857c78a1..711fbca1c8d2 100644 --- a/tests/ui/cmp_owned/comparison_flip.fixed +++ b/tests/ui/cmp_owned/comparison_flip.fixed @@ -4,12 +4,12 @@ fn main() { let a = Foo; if a != "bar" { - //~^ cmp_owned + //~^ cmp_owned println!("foo"); } if a != "bar" { - //~^ cmp_owned + //~^ cmp_owned println!("foo"); } } diff --git a/tests/ui/cmp_owned/comparison_flip.rs b/tests/ui/cmp_owned/comparison_flip.rs index 169d472203c5..ce86bb3f7b5c 100644 --- a/tests/ui/cmp_owned/comparison_flip.rs +++ b/tests/ui/cmp_owned/comparison_flip.rs @@ -4,12 +4,12 @@ fn main() { let a = Foo; if a.to_string() != "bar" { - //~^ cmp_owned + //~^ cmp_owned println!("foo"); } if "bar" != a.to_string() { - //~^ cmp_owned + //~^ cmp_owned println!("foo"); } } diff --git a/tests/ui/cmp_owned/without_suggestion.rs b/tests/ui/cmp_owned/without_suggestion.rs index 71bcac44ed7c..4e14c3054d9f 100644 --- a/tests/ui/cmp_owned/without_suggestion.rs +++ b/tests/ui/cmp_owned/without_suggestion.rs @@ -7,14 +7,11 @@ fn main() { y.to_owned() == *x; //~^ cmp_owned - - let x = &&Baz; let y = &Baz; y.to_owned() == **x; //~^ cmp_owned - let x = 0u32; let y = U32Wrapper(x); let _ = U32Wrapper::from(x) == y; @@ -26,7 +23,6 @@ impl PartialEq for Foo { fn eq(&self, other: &Self) -> bool { self.to_owned() == *other //~^ cmp_owned - } } diff --git a/tests/ui/cmp_owned/without_suggestion.stderr b/tests/ui/cmp_owned/without_suggestion.stderr index 6efaf9688e20..c8e2efab4915 100644 --- a/tests/ui/cmp_owned/without_suggestion.stderr +++ b/tests/ui/cmp_owned/without_suggestion.stderr @@ -8,13 +8,13 @@ LL | y.to_owned() == *x; = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]` error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/without_suggestion.rs:14:5 + --> tests/ui/cmp_owned/without_suggestion.rs:12:5 | LL | y.to_owned() == **x; | ^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating error: this creates an owned instance just for comparison - --> tests/ui/cmp_owned/without_suggestion.rs:27:9 + --> tests/ui/cmp_owned/without_suggestion.rs:24:9 | LL | self.to_owned() == *other | ^^^^^^^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating diff --git a/tests/ui/cognitive_complexity.rs b/tests/ui/cognitive_complexity.rs index d750202d00ec..2dbec955f63f 100644 --- a/tests/ui/cognitive_complexity.rs +++ b/tests/ui/cognitive_complexity.rs @@ -91,7 +91,7 @@ fn main() { #[clippy::cognitive_complexity = "1"] fn kaboom() { -//~^ cognitive_complexity + //~^ cognitive_complexity let n = 0; 'a: for i in 0..20 { @@ -151,11 +151,10 @@ fn lots_of_short_circuits2() -> bool { #[clippy::cognitive_complexity = "1"] fn baa() { -//~^ cognitive_complexity - - let x = || match 99 { //~^ cognitive_complexity + let x = || match 99 { + //~^ cognitive_complexity 0 => 0, 1 => 1, 2 => 2, @@ -173,7 +172,7 @@ fn baa() { #[clippy::cognitive_complexity = "1"] fn bar() { -//~^ cognitive_complexity + //~^ cognitive_complexity match 99 { 0 => println!("hi"), @@ -186,7 +185,7 @@ fn bar() { /// Tests are usually complex but simple at the same time. `clippy::cognitive_complexity` used to /// give lots of false-positives in tests. fn dont_warn_on_tests() { -//~^ cognitive_complexity + //~^ cognitive_complexity match 99 { 0 => println!("hi"), @@ -196,7 +195,7 @@ fn dont_warn_on_tests() { #[clippy::cognitive_complexity = "1"] fn barr() { -//~^ cognitive_complexity + //~^ cognitive_complexity match 99 { 0 => println!("hi"), @@ -208,7 +207,7 @@ fn barr() { #[clippy::cognitive_complexity = "1"] fn barr2() { -//~^ cognitive_complexity + //~^ cognitive_complexity match 99 { 0 => println!("hi"), @@ -226,7 +225,7 @@ fn barr2() { #[clippy::cognitive_complexity = "1"] fn barrr() { -//~^ cognitive_complexity + //~^ cognitive_complexity match 99 { 0 => println!("hi"), @@ -238,7 +237,7 @@ fn barrr() { #[clippy::cognitive_complexity = "1"] fn barrr2() { -//~^ cognitive_complexity + //~^ cognitive_complexity match 99 { 0 => println!("hi"), @@ -256,7 +255,7 @@ fn barrr2() { #[clippy::cognitive_complexity = "1"] fn barrrr() { -//~^ cognitive_complexity + //~^ cognitive_complexity match 99 { 0 => println!("hi"), @@ -268,7 +267,7 @@ fn barrrr() { #[clippy::cognitive_complexity = "1"] fn barrrr2() { -//~^ cognitive_complexity + //~^ cognitive_complexity match 99 { 0 => println!("hi"), @@ -286,7 +285,7 @@ fn barrrr2() { #[clippy::cognitive_complexity = "1"] fn cake() { -//~^ cognitive_complexity + //~^ cognitive_complexity if 4 == 5 { println!("yea"); @@ -298,7 +297,7 @@ fn cake() { #[clippy::cognitive_complexity = "1"] pub fn read_file(input_path: &str) -> String { -//~^ cognitive_complexity + //~^ cognitive_complexity use std::fs::File; use std::io::{Read, Write}; @@ -331,7 +330,7 @@ enum Void {} #[clippy::cognitive_complexity = "1"] fn void(void: Void) { -//~^ cognitive_complexity + //~^ cognitive_complexity if true { match void {} @@ -407,7 +406,7 @@ fn early_ret() -> i32 { #[clippy::cognitive_complexity = "1"] fn closures() { let x = |a: i32, b: i32| -> i32 { - //~^ cognitive_complexity + //~^ cognitive_complexity if true { println!("moo"); @@ -422,7 +421,7 @@ struct Moo; #[clippy::cognitive_complexity = "1"] impl Moo { fn moo(&self) { - //~^ cognitive_complexity + //~^ cognitive_complexity if true { println!("moo"); @@ -433,7 +432,7 @@ impl Moo { #[clippy::cognitive_complexity = "1"] mod issue9300 { async fn a() { - //~^ cognitive_complexity + //~^ cognitive_complexity let a = 0; if a == 0 {} @@ -442,7 +441,7 @@ mod issue9300 { pub struct S; impl S { pub async fn async_method() { - //~^ cognitive_complexity + //~^ cognitive_complexity let a = 0; if a == 0 {} diff --git a/tests/ui/cognitive_complexity.stderr b/tests/ui/cognitive_complexity.stderr index 60a834765a6b..52607b87c60e 100644 --- a/tests/ui/cognitive_complexity.stderr +++ b/tests/ui/cognitive_complexity.stderr @@ -33,7 +33,7 @@ LL | let x = || match 99 { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:175:4 + --> tests/ui/cognitive_complexity.rs:174:4 | LL | fn bar() { | ^^^ @@ -41,7 +41,7 @@ LL | fn bar() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:188:4 + --> tests/ui/cognitive_complexity.rs:187:4 | LL | fn dont_warn_on_tests() { | ^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | fn dont_warn_on_tests() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:198:4 + --> tests/ui/cognitive_complexity.rs:197:4 | LL | fn barr() { | ^^^^ @@ -57,7 +57,7 @@ LL | fn barr() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (3/1) - --> tests/ui/cognitive_complexity.rs:210:4 + --> tests/ui/cognitive_complexity.rs:209:4 | LL | fn barr2() { | ^^^^^ @@ -65,7 +65,7 @@ LL | fn barr2() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:228:4 + --> tests/ui/cognitive_complexity.rs:227:4 | LL | fn barrr() { | ^^^^^ @@ -73,7 +73,7 @@ LL | fn barrr() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (3/1) - --> tests/ui/cognitive_complexity.rs:240:4 + --> tests/ui/cognitive_complexity.rs:239:4 | LL | fn barrr2() { | ^^^^^^ @@ -81,7 +81,7 @@ LL | fn barrr2() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:258:4 + --> tests/ui/cognitive_complexity.rs:257:4 | LL | fn barrrr() { | ^^^^^^ @@ -89,7 +89,7 @@ LL | fn barrrr() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (3/1) - --> tests/ui/cognitive_complexity.rs:270:4 + --> tests/ui/cognitive_complexity.rs:269:4 | LL | fn barrrr2() { | ^^^^^^^ @@ -97,7 +97,7 @@ LL | fn barrrr2() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:288:4 + --> tests/ui/cognitive_complexity.rs:287:4 | LL | fn cake() { | ^^^^ @@ -105,7 +105,7 @@ LL | fn cake() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (4/1) - --> tests/ui/cognitive_complexity.rs:300:8 + --> tests/ui/cognitive_complexity.rs:299:8 | LL | pub fn read_file(input_path: &str) -> String { | ^^^^^^^^^ @@ -113,7 +113,7 @@ LL | pub fn read_file(input_path: &str) -> String { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:333:4 + --> tests/ui/cognitive_complexity.rs:332:4 | LL | fn void(void: Void) { | ^^^^ @@ -121,7 +121,7 @@ LL | fn void(void: Void) { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (8/1) - --> tests/ui/cognitive_complexity.rs:386:4 + --> tests/ui/cognitive_complexity.rs:385:4 | LL | fn early_ret() -> i32 { | ^^^^^^^^^ @@ -129,7 +129,7 @@ LL | fn early_ret() -> i32 { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:409:13 + --> tests/ui/cognitive_complexity.rs:408:13 | LL | let x = |a: i32, b: i32| -> i32 { | ^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ LL | let x = |a: i32, b: i32| -> i32 { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:424:8 + --> tests/ui/cognitive_complexity.rs:423:8 | LL | fn moo(&self) { | ^^^ @@ -145,7 +145,7 @@ LL | fn moo(&self) { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:435:14 + --> tests/ui/cognitive_complexity.rs:434:14 | LL | async fn a() { | ^ @@ -153,7 +153,7 @@ LL | async fn a() { = help: you could split it up into multiple smaller functions error: the function has a cognitive complexity of (2/1) - --> tests/ui/cognitive_complexity.rs:444:22 + --> tests/ui/cognitive_complexity.rs:443:22 | LL | pub async fn async_method() { | ^^^^^^^^^^^^ diff --git a/tests/ui/cognitive_complexity_attr_used.rs b/tests/ui/cognitive_complexity_attr_used.rs index ed62dd7b933e..a260fdee3cfd 100644 --- a/tests/ui/cognitive_complexity_attr_used.rs +++ b/tests/ui/cognitive_complexity_attr_used.rs @@ -7,7 +7,7 @@ fn main() { #[clippy::cognitive_complexity = "0"] fn kaboom() { -//~^ cognitive_complexity + //~^ cognitive_complexity if 42 == 43 { panic!(); diff --git a/tests/ui/collapsible_match.rs b/tests/ui/collapsible_match.rs index 14e3ab95dbd1..796cabd4b669 100644 --- a/tests/ui/collapsible_match.rs +++ b/tests/ui/collapsible_match.rs @@ -12,8 +12,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // match without block match res_opt { Ok(val) => match val { - //~^ collapsible_match - + //~^ collapsible_match Some(n) => foo(n), _ => return, }, @@ -23,8 +22,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // match with block match res_opt { Ok(val) => match val { - //~^ collapsible_match - + //~^ collapsible_match Some(n) => foo(n), _ => return, }, @@ -34,7 +32,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // if let, if let if let Ok(val) = res_opt { if let Some(n) = val { - //~^ collapsible_match + //~^ collapsible_match take(n); } @@ -43,7 +41,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // if let else, if let else if let Ok(val) = res_opt { if let Some(n) = val { - //~^ collapsible_match + //~^ collapsible_match take(n); } else { @@ -56,8 +54,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // if let, match if let Ok(val) = res_opt { match val { - //~^ collapsible_match - + //~^ collapsible_match Some(n) => foo(n), _ => (), } @@ -67,7 +64,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> match res_opt { Ok(val) => { if let Some(n) = val { - //~^ collapsible_match + //~^ collapsible_match take(n); } @@ -78,8 +75,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // if let else, match if let Ok(val) = res_opt { match val { - //~^ collapsible_match - + //~^ collapsible_match Some(n) => foo(n), _ => return, } @@ -91,7 +87,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> match res_opt { Ok(val) => { if let Some(n) = val { - //~^ collapsible_match + //~^ collapsible_match take(n); } else { @@ -104,8 +100,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // None in inner match same as outer wild branch match res_opt { Ok(val) => match val { - //~^ collapsible_match - + //~^ collapsible_match Some(n) => foo(n), None => return, }, @@ -115,8 +110,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // None in outer match same as inner wild branch match opt_opt { Some(val) => match val { - //~^ collapsible_match - + //~^ collapsible_match Some(n) => foo(n), _ => return, }, @@ -260,7 +254,7 @@ fn negative_cases(res_opt: Result, String>, res_res: Result>>() { Some(val) => match val { - //~^ collapsible_match + //~^ collapsible_match E::A(val) | E::B(val) => foo(val), _ => return, }, @@ -292,7 +286,7 @@ pub enum Issue9647 { pub fn test_1(x: Issue9647) { if let Issue9647::A { a, .. } = x { if let Some(u) = a { - //~^ collapsible_match + //~^ collapsible_match println!("{u:?}") } @@ -302,7 +296,7 @@ pub fn test_1(x: Issue9647) { pub fn test_2(x: Issue9647) { if let Issue9647::A { a: Some(a), .. } = x { if let Some(u) = a { - //~^ collapsible_match + //~^ collapsible_match println!("{u}") } diff --git a/tests/ui/collapsible_match.stderr b/tests/ui/collapsible_match.stderr index 471e58f27770..5294a9d6975d 100644 --- a/tests/ui/collapsible_match.stderr +++ b/tests/ui/collapsible_match.stderr @@ -4,7 +4,6 @@ error: this `match` can be collapsed into the outer `match` LL | Ok(val) => match val { | ____________________^ LL | | -LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, @@ -15,35 +14,34 @@ help: the outer pattern can be modified to include the inner pattern | LL | Ok(val) => match val { | ^^^ replace this binding -... +LL | LL | Some(n) => foo(n), | ^^^^^^^ with this pattern = note: `-D clippy::collapsible-match` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]` error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:25:20 + --> tests/ui/collapsible_match.rs:24:20 | LL | Ok(val) => match val { | ____________________^ LL | | -LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:25:12 + --> tests/ui/collapsible_match.rs:24:12 | LL | Ok(val) => match val { | ^^^ replace this binding -... +LL | LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:36:9 + --> tests/ui/collapsible_match.rs:34:9 | LL | / if let Some(n) = val { LL | | @@ -53,7 +51,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:35:15 + --> tests/ui/collapsible_match.rs:33:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -61,7 +59,7 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:45:9 + --> tests/ui/collapsible_match.rs:43:9 | LL | / if let Some(n) = val { LL | | @@ -73,7 +71,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:44:15 + --> tests/ui/collapsible_match.rs:42:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -81,18 +79,17 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:58:9 + --> tests/ui/collapsible_match.rs:56:9 | LL | / match val { LL | | -LL | | LL | | Some(n) => foo(n), LL | | _ => (), LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:57:15 + --> tests/ui/collapsible_match.rs:55:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -101,7 +98,7 @@ LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:69:13 + --> tests/ui/collapsible_match.rs:66:13 | LL | / if let Some(n) = val { LL | | @@ -111,7 +108,7 @@ LL | | } | |_____________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:68:12 + --> tests/ui/collapsible_match.rs:65:12 | LL | Ok(val) => { | ^^^ replace this binding @@ -119,18 +116,17 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:80:9 + --> tests/ui/collapsible_match.rs:77:9 | LL | / match val { LL | | -LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:79:15 + --> tests/ui/collapsible_match.rs:76:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -139,7 +135,7 @@ LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:93:13 + --> tests/ui/collapsible_match.rs:89:13 | LL | / if let Some(n) = val { LL | | @@ -151,7 +147,7 @@ LL | | } | |_____________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:92:12 + --> tests/ui/collapsible_match.rs:88:12 | LL | Ok(val) => { | ^^^ replace this binding @@ -159,49 +155,47 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:106:20 + --> tests/ui/collapsible_match.rs:102:20 | LL | Ok(val) => match val { | ____________________^ LL | | -LL | | LL | | Some(n) => foo(n), LL | | None => return, LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:106:12 + --> tests/ui/collapsible_match.rs:102:12 | LL | Ok(val) => match val { | ^^^ replace this binding -... +LL | LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:117:22 + --> tests/ui/collapsible_match.rs:112:22 | LL | Some(val) => match val { | ______________________^ LL | | -LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:117:14 + --> tests/ui/collapsible_match.rs:112:14 | LL | Some(val) => match val { | ^^^ replace this binding -... +LL | LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:262:22 + --> tests/ui/collapsible_match.rs:256:22 | LL | Some(val) => match val { | ______________________^ @@ -212,7 +206,7 @@ LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:262:14 + --> tests/ui/collapsible_match.rs:256:14 | LL | Some(val) => match val { | ^^^ replace this binding @@ -221,7 +215,7 @@ LL | E::A(val) | E::B(val) => foo(val), | ^^^^^^^^^^^^^^^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:294:9 + --> tests/ui/collapsible_match.rs:288:9 | LL | / if let Some(u) = a { LL | | @@ -231,7 +225,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:293:27 + --> tests/ui/collapsible_match.rs:287:27 | LL | if let Issue9647::A { a, .. } = x { | ^ replace this binding @@ -239,7 +233,7 @@ LL | if let Some(u) = a { | ^^^^^^^ with this pattern, prefixed by `a`: error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:304:9 + --> tests/ui/collapsible_match.rs:298:9 | LL | / if let Some(u) = a { LL | | @@ -249,7 +243,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:303:35 + --> tests/ui/collapsible_match.rs:297:35 | LL | if let Issue9647::A { a: Some(a), .. } = x { | ^ replace this binding diff --git a/tests/ui/collapsible_match2.rs b/tests/ui/collapsible_match2.rs index 1831fc3f0e35..ba7f2f2720dc 100644 --- a/tests/ui/collapsible_match2.rs +++ b/tests/ui/collapsible_match2.rs @@ -11,8 +11,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> { match res_opt { Ok(val) if make() => match val { - //~^ collapsible_match - + //~^ collapsible_match Some(n) => foo(n), _ => return, }, @@ -20,8 +19,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> } match res_opt { Ok(val) => match val { - //~^ collapsible_match - + //~^ collapsible_match Some(n) => foo(n), _ => return, }, @@ -36,7 +34,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> ($outer:expr => $pat:pat, $e:expr => $inner_pat:pat, $then:expr) => { match $outer { $pat => match $e { - //~^ collapsible_match + //~^ collapsible_match $inner_pat => $then, _ => return, }, @@ -54,8 +52,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // deref reference value match Some(&[1]) { Some(s) => match *s { - //~^ collapsible_match - + //~^ collapsible_match [n] => foo(n), _ => (), }, @@ -65,8 +62,7 @@ fn lint_cases(opt_opt: Option>, res_opt: Result, String> // ref pattern and deref match Some(&[1]) { Some(ref s) => match s { - //~^ collapsible_match - + //~^ collapsible_match [n] => foo(n), _ => (), }, diff --git a/tests/ui/collapsible_match2.stderr b/tests/ui/collapsible_match2.stderr index 322c583fda77..7b2730637528 100644 --- a/tests/ui/collapsible_match2.stderr +++ b/tests/ui/collapsible_match2.stderr @@ -4,7 +4,6 @@ error: this `match` can be collapsed into the outer `match` LL | Ok(val) if make() => match val { | __________________________________^ LL | | -LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, @@ -15,35 +14,34 @@ help: the outer pattern can be modified to include the inner pattern | LL | Ok(val) if make() => match val { | ^^^ replace this binding -... +LL | LL | Some(n) => foo(n), | ^^^^^^^ with this pattern = note: `-D clippy::collapsible-match` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]` error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match2.rs:22:24 + --> tests/ui/collapsible_match2.rs:21:24 | LL | Ok(val) => match val { | ________________________^ LL | | -LL | | LL | | Some(n) => foo(n), LL | | _ => return, LL | | }, | |_____________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match2.rs:22:16 + --> tests/ui/collapsible_match2.rs:21:16 | LL | Ok(val) => match val { | ^^^ replace this binding -... +LL | LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match2.rs:38:29 + --> tests/ui/collapsible_match2.rs:36:29 | LL | $pat => match $e { | _____________________________^ @@ -57,7 +55,7 @@ LL | mac!(res_opt => Ok(val), val => Some(n), foo(n)); | ------------------------------------------------ in this macro invocation | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match2.rs:51:28 + --> tests/ui/collapsible_match2.rs:49:28 | LL | mac!(res_opt => Ok(val), val => Some(n), foo(n)); | ^^^ ^^^^^^^ with this pattern @@ -66,44 +64,42 @@ LL | mac!(res_opt => Ok(val), val => Some(n), foo(n)); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match2.rs:56:20 + --> tests/ui/collapsible_match2.rs:54:20 | LL | Some(s) => match *s { | ____________________^ LL | | -LL | | LL | | [n] => foo(n), LL | | _ => (), LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match2.rs:56:14 + --> tests/ui/collapsible_match2.rs:54:14 | LL | Some(s) => match *s { | ^ replace this binding -... +LL | LL | [n] => foo(n), | ^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match2.rs:67:24 + --> tests/ui/collapsible_match2.rs:64:24 | LL | Some(ref s) => match s { | ________________________^ LL | | -LL | | LL | | [n] => foo(n), LL | | _ => (), LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match2.rs:67:14 + --> tests/ui/collapsible_match2.rs:64:14 | LL | Some(ref s) => match s { | ^^^^^ replace this binding -... +LL | LL | [n] => foo(n), | ^^^ with this pattern diff --git a/tests/ui/collection_is_never_read.rs b/tests/ui/collection_is_never_read.rs index 406b5f8f9f69..77cc84fef177 100644 --- a/tests/ui/collection_is_never_read.rs +++ b/tests/ui/collection_is_never_read.rs @@ -21,7 +21,6 @@ fn write_without_read() { let mut x = HashMap::new(); //~^ collection_is_never_read - x.insert(1, 2); } diff --git a/tests/ui/collection_is_never_read.stderr b/tests/ui/collection_is_never_read.stderr index 674552629f7d..d92b84c4a652 100644 --- a/tests/ui/collection_is_never_read.stderr +++ b/tests/ui/collection_is_never_read.stderr @@ -8,115 +8,115 @@ LL | let mut x = HashMap::new(); = help: to override `-D warnings` add `#[allow(clippy::collection_is_never_read)]` error: collection is never read - --> tests/ui/collection_is_never_read.rs:63:5 + --> tests/ui/collection_is_never_read.rs:62:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:80:5 + --> tests/ui/collection_is_never_read.rs:79:5 | LL | let mut x = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:87:5 + --> tests/ui/collection_is_never_read.rs:86:5 | LL | let mut x = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:97:5 + --> tests/ui/collection_is_never_read.rs:96:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:105:5 + --> tests/ui/collection_is_never_read.rs:104:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:113:5 + --> tests/ui/collection_is_never_read.rs:112:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:122:5 + --> tests/ui/collection_is_never_read.rs:121:5 | LL | let mut x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:141:5 + --> tests/ui/collection_is_never_read.rs:140:5 | LL | let mut x = HashSet::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:157:5 + --> tests/ui/collection_is_never_read.rs:156:5 | LL | let x = vec![1, 2, 3]; | ^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:194:5 + --> tests/ui/collection_is_never_read.rs:193:5 | LL | let mut x = std::collections::BTreeMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:199:5 + --> tests/ui/collection_is_never_read.rs:198:5 | LL | let mut x = std::collections::BTreeSet::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:204:5 + --> tests/ui/collection_is_never_read.rs:203:5 | LL | let mut x = std::collections::BinaryHeap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:209:5 + --> tests/ui/collection_is_never_read.rs:208:5 | LL | let mut x = std::collections::HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:214:5 + --> tests/ui/collection_is_never_read.rs:213:5 | LL | let mut x = std::collections::HashSet::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:219:5 + --> tests/ui/collection_is_never_read.rs:218:5 | LL | let mut x = std::collections::LinkedList::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:224:5 + --> tests/ui/collection_is_never_read.rs:223:5 | LL | let mut x = Some(true); | ^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:229:5 + --> tests/ui/collection_is_never_read.rs:228:5 | LL | let mut x = String::from("hello"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:234:5 + --> tests/ui/collection_is_never_read.rs:233:5 | LL | let mut x = Vec::new(); | ^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> tests/ui/collection_is_never_read.rs:240:5 + --> tests/ui/collection_is_never_read.rs:239:5 | LL | let mut x = std::collections::VecDeque::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/comparison_chain.rs b/tests/ui/comparison_chain.rs index 418c88b7d5a3..669690a4d42c 100644 --- a/tests/ui/comparison_chain.rs +++ b/tests/ui/comparison_chain.rs @@ -13,7 +13,7 @@ fn f(x: u8, y: u8, z: u8) { } if x > y { - //~^ comparison_chain + //~^ comparison_chain a() } else if x < y { @@ -28,7 +28,7 @@ fn f(x: u8, y: u8, z: u8) { } if x > y { - //~^ comparison_chain + //~^ comparison_chain a() } else if x < y { @@ -38,7 +38,7 @@ fn f(x: u8, y: u8, z: u8) { } if x > y { - //~^ comparison_chain + //~^ comparison_chain a() } else if y > x { @@ -48,7 +48,7 @@ fn f(x: u8, y: u8, z: u8) { } if x > 1 { - //~^ comparison_chain + //~^ comparison_chain a() } else if x < 1 { @@ -124,7 +124,7 @@ fn g(x: f64, y: f64, z: f64) { fn h(x: T, y: T, z: T) { if x > y { - //~^ comparison_chain + //~^ comparison_chain a() } else if x < y { @@ -132,7 +132,7 @@ fn h(x: T, y: T, z: T) { } if x > y { - //~^ comparison_chain + //~^ comparison_chain a() } else if x < y { @@ -142,7 +142,7 @@ fn h(x: T, y: T, z: T) { } if x > y { - //~^ comparison_chain + //~^ comparison_chain a() } else if y > x { @@ -249,7 +249,7 @@ const fn sign_i8(n: i8) -> Sign { fn needs_parens() -> &'static str { let (x, y) = (1, 2); if x + 1 > y * 2 { - //~^ comparison_chain + //~^ comparison_chain "aa" } else if x + 1 < y * 2 { diff --git a/tests/ui/comparison_to_empty.fixed b/tests/ui/comparison_to_empty.fixed index 205abe31cd86..dfbb61683840 100644 --- a/tests/ui/comparison_to_empty.fixed +++ b/tests/ui/comparison_to_empty.fixed @@ -25,7 +25,7 @@ fn main() { if s.is_empty() //~^ comparison_to_empty && s.is_empty() - //~^ comparison_to_empty + //~^ comparison_to_empty {} // Allow comparisons to non-empty diff --git a/tests/ui/comparison_to_empty.rs b/tests/ui/comparison_to_empty.rs index 4da6327050a8..61cdb2bbe9f8 100644 --- a/tests/ui/comparison_to_empty.rs +++ b/tests/ui/comparison_to_empty.rs @@ -25,7 +25,7 @@ fn main() { if let [] = &*s //~^ comparison_to_empty && s == [] - //~^ comparison_to_empty + //~^ comparison_to_empty {} // Allow comparisons to non-empty diff --git a/tests/ui/const_comparisons.rs b/tests/ui/const_comparisons.rs index 0df4b8eb356e..b732d7d142fc 100644 --- a/tests/ui/const_comparisons.rs +++ b/tests/ui/const_comparisons.rs @@ -45,52 +45,38 @@ fn main() { status_code <= 400 && status_code > 500; //~^ impossible_comparisons - status_code > 500 && status_code < 400; //~^ impossible_comparisons - status_code < 500 && status_code > 500; //~^ impossible_comparisons - - // More complex expressions status_code < { 400 } && status_code > { 500 }; //~^ impossible_comparisons - status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR; //~^ impossible_comparisons - status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR; //~^ impossible_comparisons - status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR; //~^ impossible_comparisons - - // Comparing two different types, via the `impl PartialOrd for Status` status < { 400 } && status > { 500 }; //~^ impossible_comparisons - status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR; //~^ impossible_comparisons - status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR; //~^ impossible_comparisons - status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR; //~^ impossible_comparisons - - // Yoda conditions // Correct 500 <= status_code && 600 > status_code; @@ -100,13 +86,10 @@ fn main() { 500 >= status_code && 600 < status_code; //~^ impossible_comparisons - // Incorrect 500 >= status_code && status_code > 600; //~^ impossible_comparisons - - // Yoda conditions, comparing two different types // Correct 500 <= status && 600 > status; @@ -116,13 +99,10 @@ fn main() { 500 >= status && 600 < status; //~^ impossible_comparisons - // Incorrect 500 >= status && status > 600; //~^ impossible_comparisons - - // Expressions where one of the sides has no effect status_code < 200 && status_code <= 299; //~^ redundant_comparisons @@ -130,7 +110,6 @@ fn main() { status_code > 200 && status_code >= 299; //~^ redundant_comparisons - // Useless left status_code >= 500 && status_code > 500; //~^ redundant_comparisons @@ -147,29 +126,20 @@ fn main() { status_code < 500 && status_code <= 500; //~^ redundant_comparisons - // Other types let name = "Steve"; name < "Jennifer" && name > "Shannon"; //~^ impossible_comparisons - - let numbers = [1, 2]; numbers < [3, 4] && numbers > [5, 6]; //~^ impossible_comparisons - - let letter = 'a'; letter < 'b' && letter > 'c'; //~^ impossible_comparisons - - let area = 42.0; area < std::f32::consts::E && area > std::f32::consts::PI; //~^ impossible_comparisons - - } diff --git a/tests/ui/const_comparisons.stderr b/tests/ui/const_comparisons.stderr index 2f3f5c9523e3..48a2c6e8d487 100644 --- a/tests/ui/const_comparisons.stderr +++ b/tests/ui/const_comparisons.stderr @@ -9,7 +9,7 @@ LL | status_code <= 400 && status_code > 500; = help: to override `-D warnings` add `#[allow(clippy::impossible_comparisons)]` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:49:5 + --> tests/ui/const_comparisons.rs:48:5 | LL | status_code > 500 && status_code < 400; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | status_code > 500 && status_code < 400; = note: since `500` > `400`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:53:5 + --> tests/ui/const_comparisons.rs:51:5 | LL | status_code < 500 && status_code > 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | status_code < 500 && status_code > 500; = note: `status_code` cannot simultaneously be greater than and less than `500` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:59:5 + --> tests/ui/const_comparisons.rs:55:5 | LL | status_code < { 400 } && status_code > { 500 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | status_code < { 400 } && status_code > { 500 }; = note: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:63:5 + --> tests/ui/const_comparisons.rs:58:5 | LL | status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR; = note: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:67:5 + --> tests/ui/const_comparisons.rs:61:5 | LL | status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR; = note: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:71:5 + --> tests/ui/const_comparisons.rs:64:5 | LL | status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR; = note: `status_code` cannot simultaneously be greater than and less than `STATUS_SERVER_ERROR` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:77:5 + --> tests/ui/const_comparisons.rs:68:5 | LL | status < { 400 } && status > { 500 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | status < { 400 } && status > { 500 }; = note: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any value of `status` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:81:5 + --> tests/ui/const_comparisons.rs:71:5 | LL | status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR; = note: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:85:5 + --> tests/ui/const_comparisons.rs:74:5 | LL | status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR; = note: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:89:5 + --> tests/ui/const_comparisons.rs:77:5 | LL | status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR; = note: `status` cannot simultaneously be greater than and less than `STATUS_SERVER_ERROR` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:100:5 + --> tests/ui/const_comparisons.rs:86:5 | LL | 500 >= status_code && 600 < status_code; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | 500 >= status_code && 600 < status_code; = note: since `500` < `600`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:105:5 + --> tests/ui/const_comparisons.rs:90:5 | LL | 500 >= status_code && status_code > 600; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | 500 >= status_code && status_code > 600; = note: since `500` < `600`, the expression evaluates to false for any value of `status_code` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:116:5 + --> tests/ui/const_comparisons.rs:99:5 | LL | 500 >= status && 600 < status; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | 500 >= status && 600 < status; = note: since `500` < `600`, the expression evaluates to false for any value of `status` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:121:5 + --> tests/ui/const_comparisons.rs:103:5 | LL | 500 >= status && status > 600; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,13 +121,13 @@ LL | 500 >= status && status > 600; = note: since `500` < `600`, the expression evaluates to false for any value of `status` error: right-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:127:5 + --> tests/ui/const_comparisons.rs:107:5 | LL | status_code < 200 && status_code <= 299; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code < 200` evaluates to true, status_code <= 299` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:127:23 + --> tests/ui/const_comparisons.rs:107:23 | LL | status_code < 200 && status_code <= 299; | ^^^^^^^^^^^^^^^^^^^^^ @@ -135,67 +135,67 @@ LL | status_code < 200 && status_code <= 299; = help: to override `-D warnings` add `#[allow(clippy::redundant_comparisons)]` error: left-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:130:5 + --> tests/ui/const_comparisons.rs:110:5 | LL | status_code > 200 && status_code >= 299; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code >= 299` evaluates to true, status_code > 200` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:130:5 + --> tests/ui/const_comparisons.rs:110:5 | LL | status_code > 200 && status_code >= 299; | ^^^^^^^^^^^^^^^^^^^^^ error: left-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:135:5 + --> tests/ui/const_comparisons.rs:114:5 | LL | status_code >= 500 && status_code > 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code > 500` evaluates to true, status_code >= 500` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:135:5 + --> tests/ui/const_comparisons.rs:114:5 | LL | status_code >= 500 && status_code > 500; | ^^^^^^^^^^^^^^^^^^^^^^ error: right-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:139:5 + --> tests/ui/const_comparisons.rs:118:5 | LL | status_code > 500 && status_code >= 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code > 500` evaluates to true, status_code >= 500` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:139:23 + --> tests/ui/const_comparisons.rs:118:23 | LL | status_code > 500 && status_code >= 500; | ^^^^^^^^^^^^^^^^^^^^^ error: left-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:143:5 + --> tests/ui/const_comparisons.rs:122:5 | LL | status_code <= 500 && status_code < 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code < 500` evaluates to true, status_code <= 500` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:143:5 + --> tests/ui/const_comparisons.rs:122:5 | LL | status_code <= 500 && status_code < 500; | ^^^^^^^^^^^^^^^^^^^^^^ error: right-hand side of `&&` operator has no effect - --> tests/ui/const_comparisons.rs:147:5 + --> tests/ui/const_comparisons.rs:126:5 | LL | status_code < 500 && status_code <= 500; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `if `status_code < 500` evaluates to true, status_code <= 500` will always evaluate to true as well - --> tests/ui/const_comparisons.rs:147:23 + --> tests/ui/const_comparisons.rs:126:23 | LL | status_code < 500 && status_code <= 500; | ^^^^^^^^^^^^^^^^^^^^^ error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:153:5 + --> tests/ui/const_comparisons.rs:131:5 | LL | name < "Jennifer" && name > "Shannon"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -203,7 +203,7 @@ LL | name < "Jennifer" && name > "Shannon"; = note: since `"Jennifer"` < `"Shannon"`, the expression evaluates to false for any value of `name` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:159:5 + --> tests/ui/const_comparisons.rs:135:5 | LL | numbers < [3, 4] && numbers > [5, 6]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +211,7 @@ LL | numbers < [3, 4] && numbers > [5, 6]; = note: since `[3, 4]` < `[5, 6]`, the expression evaluates to false for any value of `numbers` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:165:5 + --> tests/ui/const_comparisons.rs:139:5 | LL | letter < 'b' && letter > 'c'; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ LL | letter < 'b' && letter > 'c'; = note: since `'b'` < `'c'`, the expression evaluates to false for any value of `letter` error: boolean expression will never evaluate to 'true' - --> tests/ui/const_comparisons.rs:171:5 + --> tests/ui/const_comparisons.rs:143:5 | LL | area < std::f32::consts::E && area > std::f32::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const_is_empty.rs b/tests/ui/const_is_empty.rs index 29891ae4c0e5..8bb4f0e5d975 100644 --- a/tests/ui/const_is_empty.rs +++ b/tests/ui/const_is_empty.rs @@ -3,23 +3,19 @@ fn test_literal() { if "".is_empty() { - //~^ const_is_empty - + //~^ const_is_empty } if "foobar".is_empty() { - //~^ const_is_empty - + //~^ const_is_empty } } fn test_byte_literal() { if b"".is_empty() { - //~^ const_is_empty - + //~^ const_is_empty } if b"foobar".is_empty() { - //~^ const_is_empty - + //~^ const_is_empty } } @@ -36,12 +32,10 @@ fn test_propagated() { let empty2 = empty; let non_empty2 = non_empty; if empty2.is_empty() { - //~^ const_is_empty - + //~^ const_is_empty } if non_empty2.is_empty() { - //~^ const_is_empty - + //~^ const_is_empty } } @@ -106,7 +100,6 @@ fn test_from_const() { let _ = NON_EMPTY_SLICE_REPEAT.is_empty(); //~^ const_is_empty - } fn main() { @@ -123,7 +116,6 @@ fn main() { let _ = b"".is_empty(); //~^ const_is_empty - } fn str_from_arg(var: &str) { @@ -178,7 +170,6 @@ fn not_cfg_conditioned() { #[cfg(not(target_os = "inexistent"))] let _ = val.is_empty(); //~^ const_is_empty - } const fn const_rand() -> &'static str { diff --git a/tests/ui/const_is_empty.stderr b/tests/ui/const_is_empty.stderr index 9557ad18dfc8..2ba189058e83 100644 --- a/tests/ui/const_is_empty.stderr +++ b/tests/ui/const_is_empty.stderr @@ -8,157 +8,157 @@ LL | if "".is_empty() { = help: to override `-D warnings` add `#[allow(clippy::const_is_empty)]` error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:9:8 + --> tests/ui/const_is_empty.rs:8:8 | LL | if "foobar".is_empty() { | ^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:16:8 + --> tests/ui/const_is_empty.rs:14:8 | LL | if b"".is_empty() { | ^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:20:8 + --> tests/ui/const_is_empty.rs:17:8 | LL | if b"foobar".is_empty() { | ^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:38:8 + --> tests/ui/const_is_empty.rs:34:8 | LL | if empty2.is_empty() { | ^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:42:8 + --> tests/ui/const_is_empty.rs:37:8 | LL | if non_empty2.is_empty() { | ^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:65:13 + --> tests/ui/const_is_empty.rs:59:13 | LL | let _ = EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:68:13 + --> tests/ui/const_is_empty.rs:62:13 | LL | let _ = NON_EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:71:13 + --> tests/ui/const_is_empty.rs:65:13 | LL | let _ = EMPTY_BSTR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:74:13 + --> tests/ui/const_is_empty.rs:68:13 | LL | let _ = NON_EMPTY_BSTR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:77:13 + --> tests/ui/const_is_empty.rs:71:13 | LL | let _ = EMPTY_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:80:13 + --> tests/ui/const_is_empty.rs:74:13 | LL | let _ = EMPTY_ARRAY_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:83:13 + --> tests/ui/const_is_empty.rs:77:13 | LL | let _ = EMPTY_U8_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:86:13 + --> tests/ui/const_is_empty.rs:80:13 | LL | let _ = NON_EMPTY_U8_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:89:13 + --> tests/ui/const_is_empty.rs:83:13 | LL | let _ = NON_EMPTY_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:92:13 + --> tests/ui/const_is_empty.rs:86:13 | LL | let _ = NON_EMPTY_ARRAY_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:95:13 + --> tests/ui/const_is_empty.rs:89:13 | LL | let _ = EMPTY_REF_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:98:13 + --> tests/ui/const_is_empty.rs:92:13 | LL | let _ = NON_EMPTY_REF_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:101:13 + --> tests/ui/const_is_empty.rs:95:13 | LL | let _ = EMPTY_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:104:13 + --> tests/ui/const_is_empty.rs:98:13 | LL | let _ = NON_EMPTY_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:107:13 + --> tests/ui/const_is_empty.rs:101:13 | LL | let _ = NON_EMPTY_SLICE_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:114:13 + --> tests/ui/const_is_empty.rs:107:13 | LL | let _ = value.is_empty(); | ^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:118:13 + --> tests/ui/const_is_empty.rs:111:13 | LL | let _ = x.is_empty(); | ^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:121:13 + --> tests/ui/const_is_empty.rs:114:13 | LL | let _ = "".is_empty(); | ^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:124:13 + --> tests/ui/const_is_empty.rs:117:13 | LL | let _ = b"".is_empty(); | ^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:179:13 + --> tests/ui/const_is_empty.rs:171:13 | LL | let _ = val.is_empty(); | ^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:211:9 + --> tests/ui/const_is_empty.rs:202:9 | LL | EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/copy_iterator.rs b/tests/ui/copy_iterator.rs index f048f7541bc6..5639583289d2 100644 --- a/tests/ui/copy_iterator.rs +++ b/tests/ui/copy_iterator.rs @@ -5,8 +5,7 @@ struct Countdown(u8); impl Iterator for Countdown { -//~^ copy_iterator - + //~^ copy_iterator type Item = u8; diff --git a/tests/ui/copy_iterator.stderr b/tests/ui/copy_iterator.stderr index 86fd326c36c5..2f6378a85fee 100644 --- a/tests/ui/copy_iterator.stderr +++ b/tests/ui/copy_iterator.stderr @@ -2,6 +2,9 @@ error: you are implementing `Iterator` on a `Copy` type --> tests/ui/copy_iterator.rs:7:1 | LL | / impl Iterator for Countdown { +LL | | +LL | | +LL | | type Item = u8; ... | LL | | } | |_^ diff --git a/tests/ui/crashes/ice-11803.rs b/tests/ui/crashes/ice-11803.rs index aced75b3ad12..e85f31909388 100644 --- a/tests/ui/crashes/ice-11803.rs +++ b/tests/ui/crashes/ice-11803.rs @@ -3,8 +3,8 @@ #![warn(clippy::impl_trait_in_params)] pub fn g>>() { -//~^ impl_trait_in_params -//~| impl_trait_in_params + //~^ impl_trait_in_params + //~| impl_trait_in_params extern "C" fn implementation_detail() {} } diff --git a/tests/ui/crashes/ice-2774.fixed b/tests/ui/crashes/ice-2774.fixed index d096584fa75c..35d969441763 100644 --- a/tests/ui/crashes/ice-2774.fixed +++ b/tests/ui/crashes/ice-2774.fixed @@ -13,8 +13,7 @@ pub struct Foo; #[allow(clippy::implicit_hasher)] // This should not cause a "cannot relate bound region" ICE. pub fn add_barfoos_to_foos(bars: &HashSet<&Bar>) { -//~^ needless_lifetimes - + //~^ needless_lifetimes let mut foos = HashSet::new(); foos.extend(bars.iter().map(|b| &b.foo)); diff --git a/tests/ui/crashes/ice-2774.rs b/tests/ui/crashes/ice-2774.rs index 83fb7be626df..1eb6df0095ed 100644 --- a/tests/ui/crashes/ice-2774.rs +++ b/tests/ui/crashes/ice-2774.rs @@ -13,8 +13,7 @@ pub struct Foo; #[allow(clippy::implicit_hasher)] // This should not cause a "cannot relate bound region" ICE. pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) { -//~^ needless_lifetimes - + //~^ needless_lifetimes let mut foos = HashSet::new(); foos.extend(bars.iter().map(|b| &b.foo)); diff --git a/tests/ui/crashes/ice-360.rs b/tests/ui/crashes/ice-360.rs index 43becad3183f..cb8176a2973f 100644 --- a/tests/ui/crashes/ice-360.rs +++ b/tests/ui/crashes/ice-360.rs @@ -3,10 +3,8 @@ fn main() {} fn no_panic(slice: &[T]) { let mut iter = slice.iter(); loop { - //~^ never_loop - //~| while_let_loop - - + //~^ never_loop + //~| while_let_loop let _ = match iter.next() { Some(ele) => ele, @@ -14,6 +12,5 @@ fn no_panic(slice: &[T]) { }; loop {} //~^ empty_loop - } } diff --git a/tests/ui/crashes/ice-360.stderr b/tests/ui/crashes/ice-360.stderr index e4bd436abc54..9961eb21485d 100644 --- a/tests/ui/crashes/ice-360.stderr +++ b/tests/ui/crashes/ice-360.stderr @@ -20,7 +20,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::while_let_loop)]` error: empty `loop {}` wastes CPU cycles - --> tests/ui/crashes/ice-360.rs:15:9 + --> tests/ui/crashes/ice-360.rs:13:9 | LL | loop {} | ^^^^^^^ diff --git a/tests/ui/crashes/ice-3717.fixed b/tests/ui/crashes/ice-3717.fixed index 0d7c38f95217..5581b67fa5c4 100644 --- a/tests/ui/crashes/ice-3717.fixed +++ b/tests/ui/crashes/ice-3717.fixed @@ -5,7 +5,7 @@ use std::collections::HashSet; fn main() {} pub fn ice_3717(_: &HashSet) { -//~^ implicit_hasher + //~^ implicit_hasher let _ = [0u8; 0]; let _: HashSet = HashSet::default(); diff --git a/tests/ui/crashes/ice-3717.rs b/tests/ui/crashes/ice-3717.rs index 7c286abf32b0..c612270865c5 100644 --- a/tests/ui/crashes/ice-3717.rs +++ b/tests/ui/crashes/ice-3717.rs @@ -5,7 +5,7 @@ use std::collections::HashSet; fn main() {} pub fn ice_3717(_: &HashSet) { -//~^ implicit_hasher + //~^ implicit_hasher let _ = [0u8; 0]; let _: HashSet = HashSet::new(); diff --git a/tests/ui/crashes/ice-3969.rs b/tests/ui/crashes/ice-3969.rs index 1db7f0ad8b5b..fa3ca6f1d538 100644 --- a/tests/ui/crashes/ice-3969.rs +++ b/tests/ui/crashes/ice-3969.rs @@ -23,7 +23,7 @@ where fn unsized_local() where for<'a> Dst: Sized, -//~^ ERROR: trait bound + //~^ ERROR: trait bound { let x: Dst = *(Box::new(Dst { x: 1 }) as Box>); } @@ -31,7 +31,7 @@ where fn return_str() -> str where str: Sized, -//~^ ERROR: trait bound + //~^ ERROR: trait bound { *"Sized".to_string().into_boxed_str() } @@ -39,7 +39,7 @@ where fn use_op(s: String) -> String where String: ::std::ops::Neg, -//~^ ERROR: trait bound + //~^ ERROR: trait bound { -s } @@ -47,7 +47,7 @@ where fn use_for() where i32: Iterator, -//~^ ERROR: trait bound + //~^ ERROR: trait bound { for _ in 2i32 {} } diff --git a/tests/ui/crashes/ice-5872.fixed b/tests/ui/crashes/ice-5872.fixed index a3235c3c7b7c..521fa15e1846 100644 --- a/tests/ui/crashes/ice-5872.fixed +++ b/tests/ui/crashes/ice-5872.fixed @@ -3,6 +3,4 @@ fn main() { let _ = vec![1, 2, 3].into_iter().next().is_none(); //~^ needless_collect - - } diff --git a/tests/ui/crashes/ice-5872.rs b/tests/ui/crashes/ice-5872.rs index 7d3ad01f56e7..10235ea8ab7f 100644 --- a/tests/ui/crashes/ice-5872.rs +++ b/tests/ui/crashes/ice-5872.rs @@ -3,6 +3,4 @@ fn main() { let _ = vec![1, 2, 3].into_iter().collect::>().is_empty(); //~^ needless_collect - - } diff --git a/tests/ui/crashes/ice-6250.rs b/tests/ui/crashes/ice-6250.rs index 37db2ce68757..65cdce793142 100644 --- a/tests/ui/crashes/ice-6250.rs +++ b/tests/ui/crashes/ice-6250.rs @@ -10,8 +10,8 @@ pub fn list_data(cache: &Cache, key: usize) { if /* let */ Some(reference) = cache.data.get(key) { - //~^ ERROR: mismatched types - //~| ERROR: mismatched types + //~^ ERROR: mismatched types + //~| ERROR: mismatched types unimplemented!() } } diff --git a/tests/ui/crashes/ice-6251.rs b/tests/ui/crashes/ice-6251.rs index 8191a53b3e59..a58265752ec3 100644 --- a/tests/ui/crashes/ice-6251.rs +++ b/tests/ui/crashes/ice-6251.rs @@ -2,8 +2,8 @@ // assertion failed: `(left == right)` ; different DefIds //@no-rustfix fn bug() -> impl Iterator { -//~^ ERROR: the size for values -//~| ERROR: the size for values -//~| ERROR: mismatched types + //~^ ERROR: the size for values + //~| ERROR: the size for values + //~| ERROR: mismatched types std::iter::empty() } diff --git a/tests/ui/crashes/ice-7169.fixed b/tests/ui/crashes/ice-7169.fixed index d69b472a3617..71a40ad7de71 100644 --- a/tests/ui/crashes/ice-7169.fixed +++ b/tests/ui/crashes/ice-7169.fixed @@ -9,6 +9,4 @@ struct A { fn main() { if Ok::<_, ()>(A::::default()).is_ok() {} //~^ redundant_pattern_matching - - } diff --git a/tests/ui/crashes/ice-7169.rs b/tests/ui/crashes/ice-7169.rs index 918f2b0f0b3c..d43e2cc164d7 100644 --- a/tests/ui/crashes/ice-7169.rs +++ b/tests/ui/crashes/ice-7169.rs @@ -9,6 +9,4 @@ struct A { fn main() { if let Ok(_) = Ok::<_, ()>(A::::default()) {} //~^ redundant_pattern_matching - - } diff --git a/tests/ui/crashes/ice-7869.rs b/tests/ui/crashes/ice-7869.rs index 68648462b57a..a5b557849aba 100644 --- a/tests/ui/crashes/ice-7869.rs +++ b/tests/ui/crashes/ice-7869.rs @@ -1,6 +1,5 @@ enum Tila { -//~^ enum_variant_names - + //~^ enum_variant_names TyöAlkoi, TyöKeskeytyi, TyöValmis, diff --git a/tests/ui/crashes/ice-7869.stderr b/tests/ui/crashes/ice-7869.stderr index 7d70e3834e9d..2377b4fd5b6b 100644 --- a/tests/ui/crashes/ice-7869.stderr +++ b/tests/ui/crashes/ice-7869.stderr @@ -3,7 +3,6 @@ error: all variants have the same prefix: `Työ` | LL | / enum Tila { LL | | -LL | | LL | | TyöAlkoi, LL | | TyöKeskeytyi, LL | | TyöValmis, diff --git a/tests/ui/crashes/ice-8250.fixed b/tests/ui/crashes/ice-8250.fixed index 2474c47944ef..b0c2ddb2450d 100644 --- a/tests/ui/crashes/ice-8250.fixed +++ b/tests/ui/crashes/ice-8250.fixed @@ -2,7 +2,6 @@ fn _f(s: &str) -> Option<()> { let _ = s[1..].split('.').next()?; //~^ needless_splitn - Some(()) } diff --git a/tests/ui/crashes/ice-8250.rs b/tests/ui/crashes/ice-8250.rs index 8f938246f37a..ee0eb8e1eb1a 100644 --- a/tests/ui/crashes/ice-8250.rs +++ b/tests/ui/crashes/ice-8250.rs @@ -2,7 +2,6 @@ fn _f(s: &str) -> Option<()> { let _ = s[1..].splitn(2, '.').next()?; //~^ needless_splitn - Some(()) } diff --git a/tests/ui/crashes/ice-9041.rs b/tests/ui/crashes/ice-9041.rs index 69e74e6e394b..4b2a0f953114 100644 --- a/tests/ui/crashes/ice-9041.rs +++ b/tests/ui/crashes/ice-9041.rs @@ -4,8 +4,6 @@ pub fn has_thing(things: &[Thing]) -> bool { let is_thing_ready = |_peer: &Thing| -> bool { todo!() }; things.iter().find(|p| is_thing_ready(p)).is_some() //~^ search_is_some - - } fn main() {} diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.fixed b/tests/ui/crashes/needless_lifetimes_impl_trait.fixed index cc5ed052d264..da3b82a60c5f 100644 --- a/tests/ui/crashes/needless_lifetimes_impl_trait.fixed +++ b/tests/ui/crashes/needless_lifetimes_impl_trait.fixed @@ -14,7 +14,7 @@ impl Foo for Baz<'_> {} impl Bar { fn baz(&self) -> impl Foo + '_ { - //~^ needless_lifetimes + //~^ needless_lifetimes Baz { bar: self } } diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.rs b/tests/ui/crashes/needless_lifetimes_impl_trait.rs index 258fb3118ef0..456d315926db 100644 --- a/tests/ui/crashes/needless_lifetimes_impl_trait.rs +++ b/tests/ui/crashes/needless_lifetimes_impl_trait.rs @@ -14,7 +14,7 @@ impl<'a> Foo for Baz<'a> {} impl Bar { fn baz<'a>(&'a self) -> impl Foo + 'a { - //~^ needless_lifetimes + //~^ needless_lifetimes Baz { bar: self } } diff --git a/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed b/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed index 128ff4a1c036..7d7286ceb99a 100644 --- a/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed +++ b/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed @@ -7,5 +7,4 @@ struct Foo<'a>(&'a [(); 100]); fn test(x: &Foo<'_>) {} //~^ needless_pass_by_value - fn main() {} diff --git a/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs b/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs index b82cc831c6e0..949cd5de7fb8 100644 --- a/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs +++ b/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs @@ -7,5 +7,4 @@ struct Foo<'a>(&'a [(); 100]); fn test(x: Foo<'_>) {} //~^ needless_pass_by_value - fn main() {} diff --git a/tests/ui/crate_level_checks/no_std_swap.rs b/tests/ui/crate_level_checks/no_std_swap.rs index e332e10ea4ba..66ca97690c17 100644 --- a/tests/ui/crate_level_checks/no_std_swap.rs +++ b/tests/ui/crate_level_checks/no_std_swap.rs @@ -11,6 +11,5 @@ pub fn main() { a = b; //~^ almost_swapped - b = a; } diff --git a/tests/ui/crate_level_checks/std_main_recursion.rs b/tests/ui/crate_level_checks/std_main_recursion.rs index b582d560668a..50f82b59a96e 100644 --- a/tests/ui/crate_level_checks/std_main_recursion.rs +++ b/tests/ui/crate_level_checks/std_main_recursion.rs @@ -4,5 +4,4 @@ fn main() { println!("Hello, World!"); main(); //~^ main_recursion - } diff --git a/tests/ui/dbg_macro/dbg_macro.fixed b/tests/ui/dbg_macro/dbg_macro.fixed index de715db8faab..fd1a0d8934b3 100644 --- a/tests/ui/dbg_macro/dbg_macro.fixed +++ b/tests/ui/dbg_macro/dbg_macro.fixed @@ -4,21 +4,18 @@ fn foo(n: u32) -> u32 { if let Some(n) = n.checked_sub(4) { n } else { n } //~^ dbg_macro - } fn bar(_: ()) {} fn factorial(n: u32) -> u32 { if n <= 1 { - //~^ dbg_macro + //~^ dbg_macro 1 //~^ dbg_macro - } else { n * factorial(n - 1) //~^ dbg_macro - } } @@ -31,7 +28,6 @@ fn main() { (1, 2, 3, 4, 5); //~^ dbg_macro - } fn issue9914() { @@ -49,7 +45,6 @@ fn issue9914() { () => { //~^ dbg_macro - }; } @@ -91,7 +86,6 @@ mod issue7274 { define_thing!(MyThing, { 2; //~^ dbg_macro - }); } @@ -99,14 +93,12 @@ mod issue7274 { pub fn issue8481() { 1; //~^ dbg_macro - } #[cfg(test)] fn foo2() { 1; //~^ dbg_macro - } #[cfg(test)] @@ -114,7 +106,6 @@ mod mod1 { fn func() { 1; //~^ dbg_macro - } } @@ -125,6 +116,5 @@ mod issue12131 { print!("{}", s); //~^ dbg_macro - } } diff --git a/tests/ui/dbg_macro/dbg_macro.rs b/tests/ui/dbg_macro/dbg_macro.rs index 90a72d131667..c96e2c7251c2 100644 --- a/tests/ui/dbg_macro/dbg_macro.rs +++ b/tests/ui/dbg_macro/dbg_macro.rs @@ -4,21 +4,18 @@ fn foo(n: u32) -> u32 { if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } //~^ dbg_macro - } fn bar(_: ()) {} fn factorial(n: u32) -> u32 { if dbg!(n <= 1) { - //~^ dbg_macro + //~^ dbg_macro dbg!(1) //~^ dbg_macro - } else { dbg!(n * factorial(n - 1)) //~^ dbg_macro - } } @@ -31,7 +28,6 @@ fn main() { dbg!(1, 2, 3, 4, 5); //~^ dbg_macro - } fn issue9914() { @@ -49,7 +45,6 @@ fn issue9914() { () => { dbg!(); //~^ dbg_macro - }; } @@ -91,7 +86,6 @@ mod issue7274 { define_thing!(MyThing, { dbg!(2); //~^ dbg_macro - }); } @@ -99,14 +93,12 @@ mod issue7274 { pub fn issue8481() { dbg!(1); //~^ dbg_macro - } #[cfg(test)] fn foo2() { dbg!(1); //~^ dbg_macro - } #[cfg(test)] @@ -114,7 +106,6 @@ mod mod1 { fn func() { dbg!(1); //~^ dbg_macro - } } @@ -125,6 +116,5 @@ mod issue12131 { print!("{}", dbg!(s)); //~^ dbg_macro - } } diff --git a/tests/ui/dbg_macro/dbg_macro.stderr b/tests/ui/dbg_macro/dbg_macro.stderr index ee0cfc12b347..83b497a539c0 100644 --- a/tests/ui/dbg_macro/dbg_macro.stderr +++ b/tests/ui/dbg_macro/dbg_macro.stderr @@ -12,7 +12,7 @@ LL | if let Some(n) = n.checked_sub(4) { n } else { n } | ~~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:12:8 + --> tests/ui/dbg_macro/dbg_macro.rs:11:8 | LL | if dbg!(n <= 1) { | ^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | if n <= 1 { | ~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:15:9 + --> tests/ui/dbg_macro/dbg_macro.rs:14:9 | LL | dbg!(1) | ^^^^^^^ @@ -34,7 +34,7 @@ LL | 1 | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:19:9 + --> tests/ui/dbg_macro/dbg_macro.rs:17:9 | LL | dbg!(n * factorial(n - 1)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | n * factorial(n - 1) | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:26:5 + --> tests/ui/dbg_macro/dbg_macro.rs:23:5 | LL | dbg!(42); | ^^^^^^^^ @@ -56,7 +56,7 @@ LL | 42; | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:29:14 + --> tests/ui/dbg_macro/dbg_macro.rs:26:14 | LL | foo(3) + dbg!(factorial(4)); | ^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | foo(3) + factorial(4); | ~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:32:5 + --> tests/ui/dbg_macro/dbg_macro.rs:29:5 | LL | dbg!(1, 2, 3, 4, 5); | ^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | (1, 2, 3, 4, 5); | ~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:56:5 + --> tests/ui/dbg_macro/dbg_macro.rs:51:5 | LL | dbg!(); | ^^^^^^ @@ -89,7 +89,7 @@ LL - dbg!(); | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:60:13 + --> tests/ui/dbg_macro/dbg_macro.rs:55:13 | LL | let _ = dbg!(); | ^^^^^^ @@ -100,7 +100,7 @@ LL | let _ = (); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:63:9 + --> tests/ui/dbg_macro/dbg_macro.rs:58:9 | LL | bar(dbg!()); | ^^^^^^ @@ -111,7 +111,7 @@ LL | bar(()); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:66:10 + --> tests/ui/dbg_macro/dbg_macro.rs:61:10 | LL | foo!(dbg!()); | ^^^^^^ @@ -122,7 +122,7 @@ LL | foo!(()); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:69:16 + --> tests/ui/dbg_macro/dbg_macro.rs:64:16 | LL | foo2!(foo!(dbg!())); | ^^^^^^ @@ -133,7 +133,7 @@ LL | foo2!(foo!(())); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:50:13 + --> tests/ui/dbg_macro/dbg_macro.rs:46:13 | LL | dbg!(); | ^^^^^^ @@ -148,7 +148,7 @@ LL - dbg!(); | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:92:9 + --> tests/ui/dbg_macro/dbg_macro.rs:87:9 | LL | dbg!(2); | ^^^^^^^ @@ -158,6 +158,17 @@ help: remove the invocation before committing it to a version control system LL | 2; | ~ +error: the `dbg!` macro is intended as a debugging tool + --> tests/ui/dbg_macro/dbg_macro.rs:94:5 + | +LL | dbg!(1); + | ^^^^^^^ + | +help: remove the invocation before committing it to a version control system + | +LL | 1; + | ~ + error: the `dbg!` macro is intended as a debugging tool --> tests/ui/dbg_macro/dbg_macro.rs:100:5 | @@ -170,18 +181,7 @@ LL | 1; | ~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:107:5 - | -LL | dbg!(1); - | ^^^^^^^ - | -help: remove the invocation before committing it to a version control system - | -LL | 1; - | ~ - -error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:115:9 + --> tests/ui/dbg_macro/dbg_macro.rs:107:9 | LL | dbg!(1); | ^^^^^^^ @@ -192,7 +192,7 @@ LL | 1; | ~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:123:31 + --> tests/ui/dbg_macro/dbg_macro.rs:114:31 | LL | println!("dbg: {:?}", dbg!(s)); | ^^^^^^^ @@ -203,7 +203,7 @@ LL | println!("dbg: {:?}", s); | ~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui/dbg_macro/dbg_macro.rs:126:22 + --> tests/ui/dbg_macro/dbg_macro.rs:117:22 | LL | print!("{}", dbg!(s)); | ^^^^^^^ diff --git a/tests/ui/dbg_macro/dbg_macro_unfixable.rs b/tests/ui/dbg_macro/dbg_macro_unfixable.rs index bd16306b89db..1a5119651b53 100644 --- a/tests/ui/dbg_macro/dbg_macro_unfixable.rs +++ b/tests/ui/dbg_macro/dbg_macro_unfixable.rs @@ -14,5 +14,4 @@ fn main() { dbg!(1, 2, dbg!(3, 4)); //~^ dbg_macro //~| dbg_macro - } diff --git a/tests/ui/declare_interior_mutable_const/enums.rs b/tests/ui/declare_interior_mutable_const/enums.rs index 0f454786156e..c87468277fb3 100644 --- a/tests/ui/declare_interior_mutable_const/enums.rs +++ b/tests/ui/declare_interior_mutable_const/enums.rs @@ -45,8 +45,7 @@ struct NestedOutermost { // a constant with enums should be linted according to its value, no matter how structs involve. const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost { -//~^ declare_interior_mutable_const - + //~^ declare_interior_mutable_const outer: NestedOuter::NestedInner(NestedInner { inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)), }), @@ -60,14 +59,14 @@ const NESTED_FROZEN_VARIANT: NestedOutermost = NestedOutermost { trait AssocConsts { // When there's no default value, lint it only according to its type. // Further details are on the corresponding code (`NonCopyConst::check_trait_item`). -const TO_BE_UNFROZEN_VARIANT: OptionalCell; -//~^ declare_interior_mutable_const -const TO_BE_FROZEN_VARIANT: OptionalCell; -//~^ declare_interior_mutable_const + const TO_BE_UNFROZEN_VARIANT: OptionalCell; + //~^ declare_interior_mutable_const + const TO_BE_FROZEN_VARIANT: OptionalCell; + //~^ declare_interior_mutable_const // Lint default values accordingly. -const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); -//~^ declare_interior_mutable_const + const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); + //~^ declare_interior_mutable_const const DEFAULTED_ON_FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen; } @@ -93,8 +92,8 @@ trait AssocTypes { impl AssocTypes for u64 { type ToBeUnfrozen = AtomicUsize; -const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); -//~^ declare_interior_mutable_const + const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); + //~^ declare_interior_mutable_const const TO_BE_FROZEN_VARIANT: Option = None; } @@ -106,30 +105,30 @@ enum BothOfCellAndGeneric { } impl BothOfCellAndGeneric { -const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); -//~^ declare_interior_mutable_const + const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); + //~^ declare_interior_mutable_const // This is a false positive. The argument about this is on `is_value_unfrozen_raw` -const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); -//~^ declare_interior_mutable_const + const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); + //~^ declare_interior_mutable_const const FROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Frozen(5); // This is what is likely to be a false negative when one tries to fix // the `GENERIC_VARIANT` false positive. -const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); -//~^ declare_interior_mutable_const + const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); + //~^ declare_interior_mutable_const } // associated types here is basically the same as the one above. trait BothOfCellAndGenericWithAssocType { type AssocType; -const UNFROZEN_VARIANT: BothOfCellAndGeneric = -//~^ declare_interior_mutable_const + const UNFROZEN_VARIANT: BothOfCellAndGeneric = + //~^ declare_interior_mutable_const BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); -const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); -//~^ declare_interior_mutable_const + const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); + //~^ declare_interior_mutable_const const FROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Frozen(5); } diff --git a/tests/ui/declare_interior_mutable_const/enums.stderr b/tests/ui/declare_interior_mutable_const/enums.stderr index a6f14ec71feb..32839d14f0ed 100644 --- a/tests/ui/declare_interior_mutable_const/enums.stderr +++ b/tests/ui/declare_interior_mutable_const/enums.stderr @@ -21,7 +21,6 @@ error: a `const` item should not be interior mutable | LL | / const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost { LL | | -LL | | LL | | outer: NestedOuter::NestedInner(NestedInner { LL | | inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)), LL | | }), @@ -31,60 +30,60 @@ LL | | }; = help: consider making this a static item error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:63:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:62:5 | -LL | const TO_BE_UNFROZEN_VARIANT: OptionalCell; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_UNFROZEN_VARIANT: OptionalCell; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:65:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:64:5 | -LL | const TO_BE_FROZEN_VARIANT: OptionalCell; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_FROZEN_VARIANT: OptionalCell; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:69:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:68:5 | -LL | const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:96:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:95:5 | -LL | const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:109:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:108:5 | -LL | const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:113:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:112:5 | -LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:120:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:119:5 | -LL | const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:128:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:127:5 | -LL | / const UNFROZEN_VARIANT: BothOfCellAndGeneric = +LL | / const UNFROZEN_VARIANT: BothOfCellAndGeneric = LL | | LL | | BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); | |____________________________________________________________________^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/enums.rs:131:1 + --> tests/ui/declare_interior_mutable_const/enums.rs:130:5 | -LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 12 previous errors diff --git a/tests/ui/declare_interior_mutable_const/others.rs b/tests/ui/declare_interior_mutable_const/others.rs index 9820626ae454..7ce04a3f2c34 100644 --- a/tests/ui/declare_interior_mutable_const/others.rs +++ b/tests/ui/declare_interior_mutable_const/others.rs @@ -14,12 +14,10 @@ const CELL: Cell = Cell::new(6); const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec, u8) = ([ATOMIC], Vec::new(), 7); //~^ declare_interior_mutable_const - macro_rules! declare_const { ($name:ident: $ty:ty = $e:expr) => { const $name: $ty = $e; //~^ declare_interior_mutable_const - }; } declare_const!(_ONCE: Once = Once::new()); diff --git a/tests/ui/declare_interior_mutable_const/others.stderr b/tests/ui/declare_interior_mutable_const/others.stderr index 3c388e3bcf37..09299b290416 100644 --- a/tests/ui/declare_interior_mutable_const/others.stderr +++ b/tests/ui/declare_interior_mutable_const/others.stderr @@ -25,7 +25,7 @@ LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec, u8) = ([ATOMIC], V = help: consider making this a static item error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:20:9 + --> tests/ui/declare_interior_mutable_const/others.rs:19:9 | LL | const $name: $ty = $e; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | declare_const!(_ONCE: Once = Once::new()); = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:49:13 + --> tests/ui/declare_interior_mutable_const/others.rs:47:13 | LL | const _BAZ: Cell = Cell::new(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/declare_interior_mutable_const/traits.rs b/tests/ui/declare_interior_mutable_const/traits.rs index 83d6c1307ea2..d3139be6859f 100644 --- a/tests/ui/declare_interior_mutable_const/traits.rs +++ b/tests/ui/declare_interior_mutable_const/traits.rs @@ -8,14 +8,13 @@ macro_rules! declare_const { ($name:ident: $ty:ty = $e:expr) => { const $name: $ty = $e; //~^ declare_interior_mutable_const - }; } // a constant whose type is a concrete type should be linted at the definition site. trait ConcreteTypes { -const ATOMIC: AtomicUsize; -//~^ declare_interior_mutable_const + const ATOMIC: AtomicUsize; + //~^ declare_interior_mutable_const const INTEGER: u64; const STRING: String; declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); @@ -43,8 +42,8 @@ trait GenericTypes { impl GenericTypes for u64 { const TO_REMAIN_GENERIC: T = T::DEFAULT; -const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); -//~^ declare_interior_mutable_const + const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); + //~^ declare_interior_mutable_const } // a helper type used below @@ -69,10 +68,10 @@ impl AssocTypes for Vec { type ToBeGenericParam = T; const TO_BE_FROZEN: Self::ToBeFrozen = 12; -const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); -//~^ declare_interior_mutable_const -const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); -//~^ declare_interior_mutable_const + const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); + //~^ declare_interior_mutable_const + const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); + //~^ declare_interior_mutable_const const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper = Wrapper(T::DEFAULT); } @@ -91,8 +90,8 @@ where T: AssocTypesHelper, { const NOT_BOUNDED: T::NotToBeBounded; -const BOUNDED: T::ToBeBounded; -//~^ declare_interior_mutable_const + const BOUNDED: T::ToBeBounded; + //~^ declare_interior_mutable_const } impl AssocTypesFromGenericParam for u64 @@ -120,24 +119,24 @@ impl SelfType for u64 { impl SelfType for AtomicUsize { // this (interior mutable `Self` const) exists in `parking_lot`. // `const_trait_impl` will replace it in the future, hopefully. -const SELF: Self = AtomicUsize::new(17); -//~^ declare_interior_mutable_const -const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); -//~^ declare_interior_mutable_const + const SELF: Self = AtomicUsize::new(17); + //~^ declare_interior_mutable_const + const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); + //~^ declare_interior_mutable_const } // Even though a constant contains a generic type, if it also have an interior mutable type, // it should be linted at the definition site. trait BothOfCellAndGeneric { -const DIRECT: Cell; -//~^ declare_interior_mutable_const -const INDIRECT: Cell<*const T>; -//~^ declare_interior_mutable_const + const DIRECT: Cell; + //~^ declare_interior_mutable_const + const INDIRECT: Cell<*const T>; + //~^ declare_interior_mutable_const } impl BothOfCellAndGeneric for u64 { -const DIRECT: Cell = Cell::new(T::DEFAULT); -//~^ declare_interior_mutable_const + const DIRECT: Cell = Cell::new(T::DEFAULT); + //~^ declare_interior_mutable_const const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null()); } @@ -149,15 +148,15 @@ impl Local where T: ConstDefault + AssocTypesHelper, { -const ATOMIC: AtomicUsize = AtomicUsize::new(18); -//~^ declare_interior_mutable_const + const ATOMIC: AtomicUsize = AtomicUsize::new(18); + //~^ declare_interior_mutable_const const COW: Cow<'static, str> = Cow::Borrowed("tuvwxy"); const GENERIC_TYPE: T = T::DEFAULT; const ASSOC_TYPE: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED; -const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); -//~^ declare_interior_mutable_const + const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); + //~^ declare_interior_mutable_const } fn main() {} diff --git a/tests/ui/declare_interior_mutable_const/traits.stderr b/tests/ui/declare_interior_mutable_const/traits.stderr index 1be6b9d2ec60..b03dd7a08403 100644 --- a/tests/ui/declare_interior_mutable_const/traits.stderr +++ b/tests/ui/declare_interior_mutable_const/traits.stderr @@ -1,8 +1,8 @@ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:17:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:16:5 | -LL | const ATOMIC: AtomicUsize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const ATOMIC: AtomicUsize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` @@ -19,70 +19,70 @@ LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:46:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:45:5 | -LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:72:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:71:5 | -LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:74:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:73:5 | -LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:94:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:93:5 | -LL | const BOUNDED: T::ToBeBounded; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const BOUNDED: T::ToBeBounded; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:123:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:122:5 | -LL | const SELF: Self = AtomicUsize::new(17); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const SELF: Self = AtomicUsize::new(17); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:125:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:124:5 | -LL | const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:132:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:131:5 | -LL | const DIRECT: Cell; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | const DIRECT: Cell; + | ^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:134:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:133:5 | -LL | const INDIRECT: Cell<*const T>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const INDIRECT: Cell<*const T>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:139:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:138:5 | -LL | const DIRECT: Cell = Cell::new(T::DEFAULT); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const DIRECT: Cell = Cell::new(T::DEFAULT); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:152:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:151:5 | -LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:159:1 + --> tests/ui/declare_interior_mutable_const/traits.rs:158:5 | -LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 13 previous errors diff --git a/tests/ui/default_numeric_fallback_f64.fixed b/tests/ui/default_numeric_fallback_f64.fixed index a4d66f951f75..cf1ccab688c5 100644 --- a/tests/ui/default_numeric_fallback_f64.fixed +++ b/tests/ui/default_numeric_fallback_f64.fixed @@ -30,7 +30,7 @@ mod basic_expr { //~| default_numeric_fallback //~| default_numeric_fallback let x = match 1.0_f64 { - //~^ default_numeric_fallback + //~^ default_numeric_fallback _ => 1.0_f64, //~^ default_numeric_fallback }; diff --git a/tests/ui/default_numeric_fallback_f64.rs b/tests/ui/default_numeric_fallback_f64.rs index d1446c35557f..345e65e0b4f9 100644 --- a/tests/ui/default_numeric_fallback_f64.rs +++ b/tests/ui/default_numeric_fallback_f64.rs @@ -30,7 +30,7 @@ mod basic_expr { //~| default_numeric_fallback //~| default_numeric_fallback let x = match 1. { - //~^ default_numeric_fallback + //~^ default_numeric_fallback _ => 1., //~^ default_numeric_fallback }; diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed index e95c49dd6b66..496408aa9e87 100644 --- a/tests/ui/default_numeric_fallback_i32.fixed +++ b/tests/ui/default_numeric_fallback_i32.fixed @@ -29,7 +29,7 @@ mod basic_expr { //~| default_numeric_fallback //~| default_numeric_fallback let x = match 1_i32 { - //~^ default_numeric_fallback + //~^ default_numeric_fallback 1_i32 => 1_i32, //~^ default_numeric_fallback //~| default_numeric_fallback diff --git a/tests/ui/default_numeric_fallback_i32.rs b/tests/ui/default_numeric_fallback_i32.rs index 377c8934c5be..90fcf4091ddc 100644 --- a/tests/ui/default_numeric_fallback_i32.rs +++ b/tests/ui/default_numeric_fallback_i32.rs @@ -29,7 +29,7 @@ mod basic_expr { //~| default_numeric_fallback //~| default_numeric_fallback let x = match 1 { - //~^ default_numeric_fallback + //~^ default_numeric_fallback 1 => 1, //~^ default_numeric_fallback //~| default_numeric_fallback diff --git a/tests/ui/default_union_representation.rs b/tests/ui/default_union_representation.rs index 90d1a20e6d8d..92c429c79a07 100644 --- a/tests/ui/default_union_representation.rs +++ b/tests/ui/default_union_representation.rs @@ -3,8 +3,7 @@ #![allow(clippy::repr_packed_without_abi)] union NoAttribute { -//~^ default_union_representation - + //~^ default_union_representation a: i32, b: u32, } @@ -17,8 +16,7 @@ union ReprC { #[repr(packed)] union ReprPacked { -//~^ default_union_representation - + //~^ default_union_representation a: i32, b: u32, } @@ -37,8 +35,7 @@ union ReprCAlign { #[repr(align(32))] union ReprAlign { -//~^ default_union_representation - + //~^ default_union_representation a: i32, b: u32, } @@ -59,8 +56,7 @@ union ZSTsAndField2 { f3: (), } union ZSTAndTwoFields { -//~^ default_union_representation - + //~^ default_union_representation f0: u32, f1: u64, f2: (), diff --git a/tests/ui/default_union_representation.stderr b/tests/ui/default_union_representation.stderr index 07c106d4092d..d558a3e8de1b 100644 --- a/tests/ui/default_union_representation.stderr +++ b/tests/ui/default_union_representation.stderr @@ -3,7 +3,6 @@ error: this union has the default representation | LL | / union NoAttribute { LL | | -LL | | LL | | a: i32, LL | | b: u32, LL | | } @@ -14,11 +13,10 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::default_union_representation)]` error: this union has the default representation - --> tests/ui/default_union_representation.rs:19:1 + --> tests/ui/default_union_representation.rs:18:1 | LL | / union ReprPacked { LL | | -LL | | LL | | a: i32, LL | | b: u32, LL | | } @@ -27,11 +25,10 @@ LL | | } = help: consider annotating `ReprPacked` with `#[repr(C)]` to explicitly specify memory layout error: this union has the default representation - --> tests/ui/default_union_representation.rs:39:1 + --> tests/ui/default_union_representation.rs:37:1 | LL | / union ReprAlign { LL | | -LL | | LL | | a: i32, LL | | b: u32, LL | | } @@ -40,11 +37,10 @@ LL | | } = help: consider annotating `ReprAlign` with `#[repr(C)]` to explicitly specify memory layout error: this union has the default representation - --> tests/ui/default_union_representation.rs:61:1 + --> tests/ui/default_union_representation.rs:58:1 | LL | / union ZSTAndTwoFields { LL | | -LL | | LL | | f0: u32, LL | | f1: u64, LL | | f2: (), diff --git a/tests/ui/deref_addrof_double_trigger.rs b/tests/ui/deref_addrof_double_trigger.rs index 928907f516a4..b08b2aba2319 100644 --- a/tests/ui/deref_addrof_double_trigger.rs +++ b/tests/ui/deref_addrof_double_trigger.rs @@ -10,13 +10,10 @@ fn main() { let b = **&&a; //~^ deref_addrof - - { let mut x = 10; let y = *&mut x; //~^ deref_addrof - } { @@ -25,6 +22,5 @@ fn main() { let mut x = 10; let y = **&mut &mut x; //~^ deref_addrof - } } diff --git a/tests/ui/deref_addrof_double_trigger.stderr b/tests/ui/deref_addrof_double_trigger.stderr index 8e69f986b056..9ac60dd6d544 100644 --- a/tests/ui/deref_addrof_double_trigger.stderr +++ b/tests/ui/deref_addrof_double_trigger.stderr @@ -8,13 +8,13 @@ LL | let b = **&&a; = help: to override `-D warnings` add `#[allow(clippy::deref_addrof)]` error: immediately dereferencing a reference - --> tests/ui/deref_addrof_double_trigger.rs:17:17 + --> tests/ui/deref_addrof_double_trigger.rs:15:17 | LL | let y = *&mut x; | ^^^^^^^ help: try: `x` error: immediately dereferencing a reference - --> tests/ui/deref_addrof_double_trigger.rs:26:18 + --> tests/ui/deref_addrof_double_trigger.rs:23:18 | LL | let y = **&mut &mut x; | ^^^^^^^^^^^^ help: try: `&mut x` diff --git a/tests/ui/derivable_impls.rs b/tests/ui/derivable_impls.rs index 1df2d88824b0..4826c5497b4a 100644 --- a/tests/ui/derivable_impls.rs +++ b/tests/ui/derivable_impls.rs @@ -18,7 +18,7 @@ struct FooDefault<'a> { } impl std::default::Default for FooDefault<'_> { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { Self { a: false, @@ -40,7 +40,7 @@ impl std::default::Default for FooDefault<'_> { struct TupleDefault(bool, i32, u64); impl std::default::Default for TupleDefault { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { Self(false, 0, 0u64) } @@ -93,7 +93,7 @@ impl Default for FooNDVec { struct StrDefault<'a>(&'a str); impl Default for StrDefault<'_> { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { Self("") } @@ -120,7 +120,7 @@ mac!(0); struct Y(u32); impl Default for Y { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { Self(mac!()) } @@ -160,7 +160,7 @@ struct WithoutSelfCurly { } impl Default for WithoutSelfCurly { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { WithoutSelfCurly { a: false } } @@ -169,7 +169,7 @@ impl Default for WithoutSelfCurly { struct WithoutSelfParan(bool); impl Default for WithoutSelfParan { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { WithoutSelfParan(false) } @@ -192,7 +192,7 @@ pub struct DirectDefaultDefaultCall { } impl Default for DirectDefaultDefaultCall { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { // When calling `Default::default()` in all fields, we know it is the same as deriving. Self { v: Default::default() } @@ -204,7 +204,7 @@ pub struct EquivalentToDefaultDefaultCallVec { } impl Default for EquivalentToDefaultDefaultCallVec { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { // The body of `::default()` is `Vec::new()`, so they are equivalent. Self { v: Vec::new() } @@ -232,7 +232,7 @@ pub struct EquivalentToDefaultDefaultCallLocal { } impl Default for EquivalentToDefaultDefaultCallLocal { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { // The body of `::default()` is `S::new()`, so they are equivalent. Self { v: S::new() } @@ -272,7 +272,7 @@ pub struct RepeatDefault1 { } impl Default for RepeatDefault1 { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { RepeatDefault1 { a: [0; 32] } } @@ -307,7 +307,7 @@ pub enum SimpleEnum { } impl Default for SimpleEnum { -//~^ derivable_impls + //~^ derivable_impls fn default() -> Self { SimpleEnum::Bar } diff --git a/tests/ui/derive.rs b/tests/ui/derive.rs index 2e8b5959d498..75d888c31070 100644 --- a/tests/ui/derive.rs +++ b/tests/ui/derive.rs @@ -11,7 +11,7 @@ struct Qux; impl Clone for Qux { -//~^ expl_impl_clone_on_copy + //~^ expl_impl_clone_on_copy fn clone(&self) -> Self { Qux @@ -37,7 +37,7 @@ struct Lt<'a> { } impl<'a> Clone for Lt<'a> { -//~^ expl_impl_clone_on_copy + //~^ expl_impl_clone_on_copy fn clone(&self) -> Self { unimplemented!() @@ -50,7 +50,7 @@ struct BigArray { } impl Clone for BigArray { -//~^ expl_impl_clone_on_copy + //~^ expl_impl_clone_on_copy fn clone(&self) -> Self { unimplemented!() @@ -63,7 +63,7 @@ struct FnPtr { } impl Clone for FnPtr { -//~^ expl_impl_clone_on_copy + //~^ expl_impl_clone_on_copy fn clone(&self) -> Self { unimplemented!() @@ -85,7 +85,7 @@ impl Clone for Generic { #[derive(Copy)] struct Generic2(T); impl Clone for Generic2 { -//~^ expl_impl_clone_on_copy + //~^ expl_impl_clone_on_copy fn clone(&self) -> Self { Self(self.0.clone()) diff --git a/tests/ui/derive_ord_xor_partial_ord.rs b/tests/ui/derive_ord_xor_partial_ord.rs index 0a2a1ee7bc9f..3ef4ee9463dc 100644 --- a/tests/ui/derive_ord_xor_partial_ord.rs +++ b/tests/ui/derive_ord_xor_partial_ord.rs @@ -45,7 +45,7 @@ impl PartialOrd for DeriveOrdWithExplicitType struct DerivePartialOrd; impl std::cmp::Ord for DerivePartialOrd { -//~^ derive_ord_xor_partial_ord + //~^ derive_ord_xor_partial_ord fn cmp(&self, other: &Self) -> Ordering { Ordering::Less @@ -67,7 +67,7 @@ mod use_ord { struct DerivePartialOrdInUseOrd; impl Ord for DerivePartialOrdInUseOrd { - //~^ derive_ord_xor_partial_ord + //~^ derive_ord_xor_partial_ord fn cmp(&self, other: &Self) -> Ordering { Ordering::Less diff --git a/tests/ui/disallowed_names.rs b/tests/ui/disallowed_names.rs index d6e26dfcf202..30fbdbc1fdc8 100644 --- a/tests/ui/disallowed_names.rs +++ b/tests/ui/disallowed_names.rs @@ -12,8 +12,6 @@ fn test(foo: ()) {} //~^ disallowed_names - - fn main() { let foo = 42; //~^ disallowed_names @@ -38,22 +36,18 @@ fn main() { //~^ disallowed_names //~| disallowed_names //~| disallowed_names - - - _ => (), } } fn issue_1647(mut foo: u8) { -//~^ disallowed_names + //~^ disallowed_names let mut baz = 0; //~^ disallowed_names if let Some(mut quux) = Some(42) {} //~^ disallowed_names - } fn issue_1647_ref() { @@ -62,7 +56,6 @@ fn issue_1647_ref() { if let Some(ref quux) = Some(42) {} //~^ disallowed_names - } fn issue_1647_ref_mut() { @@ -71,7 +64,6 @@ fn issue_1647_ref_mut() { if let Some(ref mut quux) = Some(42) {} //~^ disallowed_names - } #[cfg(test)] diff --git a/tests/ui/disallowed_names.stderr b/tests/ui/disallowed_names.stderr index e412d27e7fca..09398ebbab77 100644 --- a/tests/ui/disallowed_names.stderr +++ b/tests/ui/disallowed_names.stderr @@ -8,79 +8,79 @@ LL | fn test(foo: ()) {} = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]` error: use of a disallowed/placeholder name `foo` - --> tests/ui/disallowed_names.rs:18:9 + --> tests/ui/disallowed_names.rs:16:9 | LL | let foo = 42; | ^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:21:9 + --> tests/ui/disallowed_names.rs:19:9 | LL | let baz = 42; | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:24:9 + --> tests/ui/disallowed_names.rs:22:9 | LL | let quux = 42; | ^^^^ error: use of a disallowed/placeholder name `foo` - --> tests/ui/disallowed_names.rs:37:10 + --> tests/ui/disallowed_names.rs:35:10 | LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:37:20 + --> tests/ui/disallowed_names.rs:35:20 | LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:37:26 + --> tests/ui/disallowed_names.rs:35:26 | LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^^ error: use of a disallowed/placeholder name `foo` - --> tests/ui/disallowed_names.rs:48:19 + --> tests/ui/disallowed_names.rs:43:19 | LL | fn issue_1647(mut foo: u8) { | ^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:51:13 + --> tests/ui/disallowed_names.rs:46:13 | LL | let mut baz = 0; | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:54:21 + --> tests/ui/disallowed_names.rs:49:21 | LL | if let Some(mut quux) = Some(42) {} | ^^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:60:13 + --> tests/ui/disallowed_names.rs:54:13 | LL | let ref baz = 0; | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:63:21 + --> tests/ui/disallowed_names.rs:57:21 | LL | if let Some(ref quux) = Some(42) {} | ^^^^ error: use of a disallowed/placeholder name `baz` - --> tests/ui/disallowed_names.rs:69:17 + --> tests/ui/disallowed_names.rs:62:17 | LL | let ref mut baz = 0; | ^^^ error: use of a disallowed/placeholder name `quux` - --> tests/ui/disallowed_names.rs:72:25 + --> tests/ui/disallowed_names.rs:65:25 | LL | if let Some(ref mut quux) = Some(42) {} | ^^^^ diff --git a/tests/ui/disallowed_script_idents.rs b/tests/ui/disallowed_script_idents.rs index 00308d0063a8..08fd1d9669ee 100644 --- a/tests/ui/disallowed_script_idents.rs +++ b/tests/ui/disallowed_script_idents.rs @@ -14,5 +14,4 @@ fn main() { // Same for japanese. let カウンタ = 10; //~^ disallowed_script_idents - } diff --git a/tests/ui/diverging_sub_expression.rs b/tests/ui/diverging_sub_expression.rs index e3b40a0cae11..b226ba69799e 100644 --- a/tests/ui/diverging_sub_expression.rs +++ b/tests/ui/diverging_sub_expression.rs @@ -20,10 +20,8 @@ fn main() { b || diverge(); //~^ diverging_sub_expression - b || A.foo(); //~^ diverging_sub_expression - } #[allow(dead_code, unused_variables)] diff --git a/tests/ui/diverging_sub_expression.stderr b/tests/ui/diverging_sub_expression.stderr index 617c7a0be8ab..3e417aa39cd8 100644 --- a/tests/ui/diverging_sub_expression.stderr +++ b/tests/ui/diverging_sub_expression.stderr @@ -8,31 +8,31 @@ LL | b || diverge(); = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]` error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:24:10 + --> tests/ui/diverging_sub_expression.rs:23:10 | LL | b || A.foo(); | ^^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:36:26 + --> tests/ui/diverging_sub_expression.rs:34:26 | LL | 6 => true || return, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:39:26 + --> tests/ui/diverging_sub_expression.rs:37:26 | LL | 7 => true || continue, | ^^^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:44:26 + --> tests/ui/diverging_sub_expression.rs:42:26 | LL | 3 => true || diverge(), | ^^^^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:49:30 + --> tests/ui/diverging_sub_expression.rs:47:30 | LL | _ => true || panic!("boo"), | ^^^^^^^^^^^^^ @@ -40,31 +40,31 @@ LL | _ => true || panic!("boo"), = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:54:29 + --> tests/ui/diverging_sub_expression.rs:52:29 | LL | 15 => true || { return; }, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:57:30 + --> tests/ui/diverging_sub_expression.rs:55:30 | LL | 16 => false || { return; }, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:61:29 + --> tests/ui/diverging_sub_expression.rs:59:29 | LL | 17 => true || { return }, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:64:30 + --> tests/ui/diverging_sub_expression.rs:62:30 | LL | 18 => false || { return }, | ^^^^^^ error: sub-expression diverges - --> tests/ui/diverging_sub_expression.rs:75:26 + --> tests/ui/diverging_sub_expression.rs:73:26 | LL | _ => true || break, | ^^^^^ diff --git a/tests/ui/doc/issue_12795.fixed b/tests/ui/doc/issue_12795.fixed index ff252c07ae8c..4172438a82a6 100644 --- a/tests/ui/doc/issue_12795.fixed +++ b/tests/ui/doc/issue_12795.fixed @@ -6,8 +6,4 @@ //~| doc_markdown //~| doc_markdown - - - - pub fn main() {} diff --git a/tests/ui/doc/issue_12795.rs b/tests/ui/doc/issue_12795.rs index b7e89cf4ea0e..dbc03cc70865 100644 --- a/tests/ui/doc/issue_12795.rs +++ b/tests/ui/doc/issue_12795.rs @@ -6,8 +6,4 @@ //~| doc_markdown //~| doc_markdown - - - - pub fn main() {} diff --git a/tests/ui/doc_errors.rs b/tests/ui/doc_errors.rs index 65783b22a58c..f67e3216c01e 100644 --- a/tests/ui/doc_errors.rs +++ b/tests/ui/doc_errors.rs @@ -5,28 +5,27 @@ use std::io; pub fn pub_fn_missing_errors_header() -> Result<(), ()> { -//~^ missing_errors_doc - + //~^ missing_errors_doc unimplemented!(); } pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> { -//~^ missing_errors_doc + //~^ missing_errors_doc unimplemented!(); } /// This is not sufficiently documented. pub fn pub_fn_returning_io_result() -> io::Result<()> { -//~^ missing_errors_doc + //~^ missing_errors_doc unimplemented!(); } /// This is not sufficiently documented. pub async fn async_pub_fn_returning_io_result() -> io::Result<()> { -//~^ missing_errors_doc + //~^ missing_errors_doc unimplemented!(); } @@ -58,14 +57,14 @@ pub struct Struct1; impl Struct1 { /// This is not sufficiently documented. pub fn pub_method_missing_errors_header() -> Result<(), ()> { - //~^ missing_errors_doc + //~^ missing_errors_doc unimplemented!(); } /// This is not sufficiently documented. pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> { - //~^ missing_errors_doc + //~^ missing_errors_doc unimplemented!(); } @@ -119,7 +118,6 @@ pub trait Trait1 { fn trait_method_missing_errors_header() -> Result<(), ()>; //~^ missing_errors_doc - /// # Errors /// A description of the errors goes here. fn trait_method_with_errors_header() -> Result<(), ()>; diff --git a/tests/ui/doc_errors.stderr b/tests/ui/doc_errors.stderr index e719c186e600..aeb2516e5123 100644 --- a/tests/ui/doc_errors.stderr +++ b/tests/ui/doc_errors.stderr @@ -8,37 +8,37 @@ LL | pub fn pub_fn_missing_errors_header() -> Result<(), ()> { = help: to override `-D warnings` add `#[allow(clippy::missing_errors_doc)]` error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:14:1 + --> tests/ui/doc_errors.rs:13:1 | LL | pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:21:1 + --> tests/ui/doc_errors.rs:20:1 | LL | pub fn pub_fn_returning_io_result() -> io::Result<()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:28:1 + --> tests/ui/doc_errors.rs:27:1 | LL | pub async fn async_pub_fn_returning_io_result() -> io::Result<()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:60:5 + --> tests/ui/doc_errors.rs:59:5 | LL | pub fn pub_method_missing_errors_header() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:67:5 + --> tests/ui/doc_errors.rs:66:5 | LL | pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function returning `Result` missing `# Errors` section - --> tests/ui/doc_errors.rs:119:5 + --> tests/ui/doc_errors.rs:118:5 | LL | fn trait_method_missing_errors_header() -> Result<(), ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/doc_unsafe.rs b/tests/ui/doc_unsafe.rs index ccdc59bfb5a2..1bdf01e4e22e 100644 --- a/tests/ui/doc_unsafe.rs +++ b/tests/ui/doc_unsafe.rs @@ -7,7 +7,7 @@ use proc_macros::external; /// This is not sufficiently documented pub unsafe fn destroy_the_planet() { -//~^ missing_safety_doc + //~^ missing_safety_doc unimplemented!(); } @@ -31,7 +31,7 @@ mod private_mod { } pub unsafe fn republished() { - //~^ missing_safety_doc + //~^ missing_safety_doc unimplemented!(); } } @@ -47,7 +47,7 @@ pub trait SafeTraitUnsafeMethods { } pub unsafe trait UnsafeTrait { -//~^ missing_safety_doc + //~^ missing_safety_doc fn method(); } @@ -78,7 +78,7 @@ unsafe impl DocumentedUnsafeTrait for Struct { impl Struct { pub unsafe fn more_undocumented_unsafe() -> Self { - //~^ missing_safety_doc + //~^ missing_safety_doc unimplemented!(); } @@ -95,7 +95,7 @@ impl Struct { macro_rules! very_unsafe { () => { pub unsafe fn whee() { - //~^ missing_safety_doc + //~^ missing_safety_doc unimplemented!() } diff --git a/tests/ui/double_comparison.fixed b/tests/ui/double_comparison.fixed index e9d707cdb53d..685e3319bf9a 100644 --- a/tests/ui/double_comparison.fixed +++ b/tests/ui/double_comparison.fixed @@ -4,35 +4,35 @@ fn main() { let x = 1; let y = 2; if x <= y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x <= y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x >= y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x >= y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x != y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x != y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x == y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x == y { - //~^ double_comparisons + //~^ double_comparisons // do something } } diff --git a/tests/ui/double_comparison.rs b/tests/ui/double_comparison.rs index 4b9a141747db..3670a050e88d 100644 --- a/tests/ui/double_comparison.rs +++ b/tests/ui/double_comparison.rs @@ -4,35 +4,35 @@ fn main() { let x = 1; let y = 2; if x == y || x < y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x < y || x == y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x == y || x > y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x > y || x == y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x < y || x > y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x > y || x < y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x <= y && x >= y { - //~^ double_comparisons + //~^ double_comparisons // do something } if x >= y && x <= y { - //~^ double_comparisons + //~^ double_comparisons // do something } } diff --git a/tests/ui/double_must_use.rs b/tests/ui/double_must_use.rs index 1f69afad25d4..3d4aaa9baa49 100644 --- a/tests/ui/double_must_use.rs +++ b/tests/ui/double_must_use.rs @@ -3,21 +3,21 @@ #[must_use] pub fn must_use_result() -> Result<(), ()> { -//~^ double_must_use + //~^ double_must_use unimplemented!(); } #[must_use] pub fn must_use_tuple() -> (Result<(), ()>, u8) { -//~^ double_must_use + //~^ double_must_use unimplemented!(); } #[must_use] pub fn must_use_array() -> [Result<(), ()>; 1] { -//~^ double_must_use + //~^ double_must_use unimplemented!(); } @@ -35,7 +35,7 @@ async fn async_must_use() -> usize { #[must_use] async fn async_must_use_result() -> Result<(), ()> { -//~^ double_must_use + //~^ double_must_use Ok(()) } diff --git a/tests/ui/duplicate_underscore_argument.rs b/tests/ui/duplicate_underscore_argument.rs index cb4930363e8f..b71f5a20a843 100644 --- a/tests/ui/duplicate_underscore_argument.rs +++ b/tests/ui/duplicate_underscore_argument.rs @@ -3,7 +3,6 @@ fn join_the_dark_side(darth: i32, _darth: i32) {} //~^ duplicate_underscore_argument - fn join_the_light_side(knight: i32, _master: i32) {} // the Force is strong with this one fn main() { diff --git a/tests/ui/else_if_without_else.rs b/tests/ui/else_if_without_else.rs index 8c0df6ee8786..05d56600e100 100644 --- a/tests/ui/else_if_without_else.rs +++ b/tests/ui/else_if_without_else.rs @@ -49,7 +49,7 @@ fn main() { if bla1() { println!("if"); } else if bla2() { - //~^ else_if_without_else + //~^ else_if_without_else println!("else if"); } @@ -59,7 +59,7 @@ fn main() { } else if bla2() { println!("else if 1"); } else if bla3() { - //~^ else_if_without_else + //~^ else_if_without_else println!("else if 2"); } @@ -87,7 +87,7 @@ fn main() { } else if bla4() { println!("else if 3"); } else if bla5() { - //~^ else_if_without_else + //~^ else_if_without_else println!("else if 4"); } @@ -118,7 +118,7 @@ fn main() { } else if bla4() { println!("else if 3"); } else if bla5() { - //~^ else_if_without_else + //~^ else_if_without_else println!("else if 4"); } diff --git a/tests/ui/empty_drop.rs b/tests/ui/empty_drop.rs index c2dc7a0193a3..5793f783a724 100644 --- a/tests/ui/empty_drop.rs +++ b/tests/ui/empty_drop.rs @@ -5,7 +5,7 @@ struct Foo; impl Drop for Foo { -//~^ empty_drop + //~^ empty_drop fn drop(&mut self) {} } @@ -22,7 +22,7 @@ impl Drop for Bar { struct Baz; impl Drop for Baz { -//~^ empty_drop + //~^ empty_drop fn drop(&mut self) { {} } diff --git a/tests/ui/empty_enum.rs b/tests/ui/empty_enum.rs index cc22a76734fe..439fd0974f5f 100644 --- a/tests/ui/empty_enum.rs +++ b/tests/ui/empty_enum.rs @@ -5,5 +5,4 @@ enum Empty {} //~^ empty_enum - fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.fixed b/tests/ui/empty_enum_variants_with_brackets.fixed index 8316d3b8fd34..885f6a50025e 100644 --- a/tests/ui/empty_enum_variants_with_brackets.fixed +++ b/tests/ui/empty_enum_variants_with_brackets.fixed @@ -4,20 +4,20 @@ pub enum PublicTestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error NonEmptyParentheses(i32, i32), // No error -EmptyBraces, -//~^ empty_enum_variants_with_brackets -EmptyParentheses, -//~^ empty_enum_variants_with_brackets + EmptyBraces, + //~^ empty_enum_variants_with_brackets + EmptyParentheses, + //~^ empty_enum_variants_with_brackets } enum TestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error NonEmptyParentheses(i32, i32), // No error -EmptyBraces, -//~^ empty_enum_variants_with_brackets -EmptyParentheses, -//~^ empty_enum_variants_with_brackets - AnotherEnum, // No error + EmptyBraces, + //~^ empty_enum_variants_with_brackets + EmptyParentheses, + //~^ empty_enum_variants_with_brackets + AnotherEnum, // No error } enum TestEnumWithFeatures { diff --git a/tests/ui/empty_enum_variants_with_brackets.rs b/tests/ui/empty_enum_variants_with_brackets.rs index 6cce2533b979..092712ee2ead 100644 --- a/tests/ui/empty_enum_variants_with_brackets.rs +++ b/tests/ui/empty_enum_variants_with_brackets.rs @@ -4,20 +4,20 @@ pub enum PublicTestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error NonEmptyParentheses(i32, i32), // No error -EmptyBraces {}, -//~^ empty_enum_variants_with_brackets -EmptyParentheses(), -//~^ empty_enum_variants_with_brackets + EmptyBraces {}, + //~^ empty_enum_variants_with_brackets + EmptyParentheses(), + //~^ empty_enum_variants_with_brackets } enum TestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error NonEmptyParentheses(i32, i32), // No error -EmptyBraces {}, -//~^ empty_enum_variants_with_brackets -EmptyParentheses(), -//~^ empty_enum_variants_with_brackets - AnotherEnum, // No error + EmptyBraces {}, + //~^ empty_enum_variants_with_brackets + EmptyParentheses(), + //~^ empty_enum_variants_with_brackets + AnotherEnum, // No error } enum TestEnumWithFeatures { diff --git a/tests/ui/empty_enum_variants_with_brackets.stderr b/tests/ui/empty_enum_variants_with_brackets.stderr index f49e526584c8..a9ae3b476dd6 100644 --- a/tests/ui/empty_enum_variants_with_brackets.stderr +++ b/tests/ui/empty_enum_variants_with_brackets.stderr @@ -1,34 +1,34 @@ error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:7:12 + --> tests/ui/empty_enum_variants_with_brackets.rs:7:16 | -LL | EmptyBraces {}, - | ^^^ +LL | EmptyBraces {}, + | ^^^ | = note: `-D clippy::empty-enum-variants-with-brackets` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::empty_enum_variants_with_brackets)]` = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:9:17 + --> tests/ui/empty_enum_variants_with_brackets.rs:9:21 | -LL | EmptyParentheses(), - | ^^ +LL | EmptyParentheses(), + | ^^ | = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:16:12 + --> tests/ui/empty_enum_variants_with_brackets.rs:16:16 | -LL | EmptyBraces {}, - | ^^^ +LL | EmptyBraces {}, + | ^^^ | = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:18:17 + --> tests/ui/empty_enum_variants_with_brackets.rs:18:21 | -LL | EmptyParentheses(), - | ^^ +LL | EmptyParentheses(), + | ^^ | = help: remove the brackets diff --git a/tests/ui/empty_line_after/doc_comments.1.fixed b/tests/ui/empty_line_after/doc_comments.1.fixed index cf2cc497799f..c1a15f47ba10 100644 --- a/tests/ui/empty_line_after/doc_comments.1.fixed +++ b/tests/ui/empty_line_after/doc_comments.1.fixed @@ -1,6 +1,5 @@ #![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)] - /// Meant to be an /// inner doc comment /// for the crate @@ -23,14 +22,12 @@ mod some_mod { fn some_noop() {} } - /// # Indented //~^ empty_line_after_doc_comments /// Blank line fn indented() {} } - /// This should produce a warning //~^ empty_line_after_doc_comments fn with_doc_and_newline() {} @@ -40,7 +37,6 @@ fn with_doc_and_newline() {} /// some comment fn with_no_newline_and_comment() {} - /// This doc comment should produce a warning //~^ empty_line_after_doc_comments /** This is also a doc comment and is part of the warning @@ -57,7 +53,6 @@ mod misattributed { // fn old_code() {} fn new_code() {} - /// Docs /// for OldA //~^ empty_line_after_doc_comments @@ -74,23 +69,21 @@ mod misattributed { mod block_comments { /** - //~^ empty_line_after_doc_comments * Meant to be inner doc comment */ + //~^^^ empty_line_after_doc_comments fn first_in_module() {} - /** - //~^ empty_line_after_doc_comments * Docs for `old_code` */ + //~^^^ empty_line_after_doc_comments /* fn old_code() {} */ /** * Docs for `new_code` */ fn new_code() {} - /// Docs for `old_code2` //~^ empty_line_after_doc_comments /* fn old_code2() {} */ diff --git a/tests/ui/empty_line_after/doc_comments.2.fixed b/tests/ui/empty_line_after/doc_comments.2.fixed index ee02e2f87d2d..abec7b54c632 100644 --- a/tests/ui/empty_line_after/doc_comments.2.fixed +++ b/tests/ui/empty_line_after/doc_comments.2.fixed @@ -1,6 +1,5 @@ #![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)] - // /// Meant to be an // /// inner doc comment // /// for the crate @@ -25,7 +24,6 @@ mod some_mod { fn some_noop() {} } - // /// # Indented //~^ empty_line_after_doc_comments @@ -33,7 +31,6 @@ mod some_mod { fn indented() {} } - // /// This should produce a warning //~^ empty_line_after_doc_comments @@ -44,7 +41,6 @@ fn with_doc_and_newline() {} /// some comment fn with_no_newline_and_comment() {} - // /// This doc comment should produce a warning //~^ empty_line_after_doc_comments @@ -64,7 +60,6 @@ mod misattributed { fn new_code() {} - // /// Docs // /// for OldA //~^ empty_line_after_doc_comments @@ -82,18 +77,17 @@ mod misattributed { mod block_comments { - /*! - //~^ empty_line_after_doc_comments + /* * Meant to be inner doc comment */ + //~^^^ empty_line_after_doc_comments fn first_in_module() {} - /* - //~^ empty_line_after_doc_comments * Docs for `old_code` */ + //~^^^ empty_line_after_doc_comments /* fn old_code() {} */ /** @@ -101,7 +95,6 @@ mod block_comments { */ fn new_code() {} - // /// Docs for `old_code2` //~^ empty_line_after_doc_comments /* fn old_code2() {} */ diff --git a/tests/ui/empty_line_after/doc_comments.rs b/tests/ui/empty_line_after/doc_comments.rs index 789f14f39777..d225768f6125 100644 --- a/tests/ui/empty_line_after/doc_comments.rs +++ b/tests/ui/empty_line_after/doc_comments.rs @@ -1,6 +1,5 @@ #![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)] - /// Meant to be an /// inner doc comment /// for the crate @@ -25,7 +24,6 @@ mod some_mod { fn some_noop() {} } - /// # Indented //~^ empty_line_after_doc_comments @@ -33,7 +31,6 @@ mod some_mod { fn indented() {} } - /// This should produce a warning //~^ empty_line_after_doc_comments @@ -44,7 +41,6 @@ fn with_doc_and_newline() {} /// some comment fn with_no_newline_and_comment() {} - /// This doc comment should produce a warning //~^ empty_line_after_doc_comments @@ -64,7 +60,6 @@ mod misattributed { fn new_code() {} - /// Docs /// for OldA //~^ empty_line_after_doc_comments @@ -83,17 +78,16 @@ mod misattributed { mod block_comments { /** - //~^ empty_line_after_doc_comments * Meant to be inner doc comment */ + //~^^^ empty_line_after_doc_comments fn first_in_module() {} - /** - //~^ empty_line_after_doc_comments * Docs for `old_code` */ + //~^^^ empty_line_after_doc_comments /* fn old_code() {} */ /** @@ -101,7 +95,6 @@ mod block_comments { */ fn new_code() {} - /// Docs for `old_code2` //~^ empty_line_after_doc_comments /* fn old_code2() {} */ diff --git a/tests/ui/empty_line_after/doc_comments.stderr b/tests/ui/empty_line_after/doc_comments.stderr index 91745dac3a79..9b627e8df1ff 100644 --- a/tests/ui/empty_line_after/doc_comments.stderr +++ b/tests/ui/empty_line_after/doc_comments.stderr @@ -1,5 +1,5 @@ error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:6:1 + --> tests/ui/empty_line_after/doc_comments.rs:5:1 | LL | / /// for the crate LL | | @@ -19,7 +19,7 @@ LL ~ // /// for the crate | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:15:5 + --> tests/ui/empty_line_after/doc_comments.rs:14:5 | LL | / /// for the module LL | | @@ -37,7 +37,7 @@ LL ~ // /// for the module | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:29:5 + --> tests/ui/empty_line_after/doc_comments.rs:27:5 | LL | / /// # Indented LL | | @@ -54,7 +54,7 @@ LL | // /// # Indented | ++ error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:37:1 + --> tests/ui/empty_line_after/doc_comments.rs:34:1 | LL | / /// This should produce a warning LL | | @@ -70,7 +70,7 @@ LL | // /// This should produce a warning | ++ error: empty lines after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:48:1 + --> tests/ui/empty_line_after/doc_comments.rs:44:1 | LL | / /// This doc comment should produce a warning LL | | @@ -93,7 +93,7 @@ LL ~ /* This is also a doc comment and is part of the warning | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:61:5 + --> tests/ui/empty_line_after/doc_comments.rs:57:5 | LL | / /// docs for `old_code` ... | @@ -109,7 +109,7 @@ LL | // /// docs for `old_code` | ++ error: empty lines after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:69:5 + --> tests/ui/empty_line_after/doc_comments.rs:64:5 | LL | / /// for OldA ... | @@ -132,31 +132,31 @@ LL ~ // /// for OldB | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:85:5 + --> tests/ui/empty_line_after/doc_comments.rs:80:5 | LL | / /** -LL | | LL | | * Meant to be inner doc comment LL | | */ +LL | | LL | | | |_^ LL | fn first_in_module() {} | -------------------- the comment documents this function | = help: if the empty line is unintentional remove it -help: if the comment should document the parent module use an inner doc comment +help: if the doc comment should not document `first_in_module` comment it out + | +LL - /** +LL + /* | -LL | /*! - | ~ error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:93:5 + --> tests/ui/empty_line_after/doc_comments.rs:87:5 | LL | / /** -LL | | LL | | * Docs for `old_code` LL | | */ -LL | | /* fn old_code() {} */ +... | LL | | | |_^ ... @@ -171,7 +171,7 @@ LL + /* | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:105:5 + --> tests/ui/empty_line_after/doc_comments.rs:98:5 | LL | / /// Docs for `old_code2` LL | | diff --git a/tests/ui/empty_loop_no_std.rs b/tests/ui/empty_loop_no_std.rs index c3b2bafe2f87..6407bd678f9c 100644 --- a/tests/ui/empty_loop_no_std.rs +++ b/tests/ui/empty_loop_no_std.rs @@ -9,5 +9,4 @@ pub fn main(argc: isize, argv: *const *const u8) -> isize { // This should trigger the lint loop {} //~^ empty_loop - } diff --git a/tests/ui/entry.fixed b/tests/ui/entry.fixed index 87dc7a8de920..9856fa9b39fd 100644 --- a/tests/ui/entry.fixed +++ b/tests/ui/entry.fixed @@ -25,7 +25,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // semicolon on insert, use or_insert_with(..) m.entry(k).or_insert_with(|| { - //~^ map_entry + //~^ map_entry if true { v } else { @@ -35,7 +35,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // semicolon on if, use or_insert_with(..) m.entry(k).or_insert_with(|| { - //~^ map_entry + //~^ map_entry if true { v } else { @@ -45,7 +45,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // early return, use if let if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { - //~^ map_entry + //~^ map_entry if true { e.insert(v); } else { @@ -56,14 +56,14 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // use or_insert_with(..) m.entry(k).or_insert_with(|| { - //~^ map_entry + //~^ map_entry foo(); v }); // semicolon on insert and match, use or_insert_with(..) m.entry(k).or_insert_with(|| { - //~^ map_entry + //~^ map_entry match 0 { 1 if true => { v @@ -76,7 +76,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // one branch doesn't insert, use if let if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { - //~^ map_entry + //~^ map_entry match 0 { 0 => foo(), _ => { @@ -87,7 +87,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // use or_insert_with m.entry(k).or_insert_with(|| { - //~^ map_entry + //~^ map_entry foo(); match 0 { 0 if false => { @@ -152,7 +152,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // or_insert_with. Partial move of a local declared in the closure is ok. m.entry(k).or_insert_with(|| { - //~^ map_entry + //~^ map_entry let x = (String::new(), String::new()); let _ = x.0; v @@ -186,7 +186,7 @@ pub fn issue_11935() { fn issue12489(map: &mut HashMap) -> Option<()> { if let std::collections::hash_map::Entry::Vacant(e) = map.entry(1) { - //~^ map_entry + //~^ map_entry let Some(1) = Some(2) else { return None; }; diff --git a/tests/ui/entry.rs b/tests/ui/entry.rs index c795d3b97590..bb8ebb4eac08 100644 --- a/tests/ui/entry.rs +++ b/tests/ui/entry.rs @@ -22,13 +22,13 @@ fn foo() {} fn hash_map(m: &mut HashMap, m2: &mut HashMap, k: K, k2: K, v: V, v2: V) { // or_insert(v) if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry m.insert(k, v); } // semicolon on insert, use or_insert_with(..) if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry if true { m.insert(k, v); } else { @@ -38,7 +38,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // semicolon on if, use or_insert_with(..) if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry if true { m.insert(k, v) } else { @@ -48,7 +48,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // early return, use if let if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry if true { m.insert(k, v); } else { @@ -59,14 +59,14 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // use or_insert_with(..) if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry foo(); m.insert(k, v); } // semicolon on insert and match, use or_insert_with(..) if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry match 0 { 1 if true => { m.insert(k, v); @@ -79,7 +79,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // one branch doesn't insert, use if let if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry match 0 { 0 => foo(), _ => { @@ -90,7 +90,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // use or_insert_with if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry foo(); match 0 { 0 if false => { @@ -125,7 +125,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // macro_expansion test, use or_insert(..) if !m.contains_key(&m!(k)) { - //~^ map_entry + //~^ map_entry m.insert(m!(k), m!(v)); } @@ -158,7 +158,7 @@ fn hash_map(m: &mut HashMap, m2: &mut HashMa // or_insert_with. Partial move of a local declared in the closure is ok. if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry let x = (String::new(), String::new()); let _ = x.0; m.insert(k, v); @@ -192,7 +192,7 @@ pub fn issue_11935() { fn issue12489(map: &mut HashMap) -> Option<()> { if !map.contains_key(&1) { - //~^ map_entry + //~^ map_entry let Some(1) = Some(2) else { return None; }; diff --git a/tests/ui/entry_btree.fixed b/tests/ui/entry_btree.fixed index 518f503475fc..1218202f02b9 100644 --- a/tests/ui/entry_btree.fixed +++ b/tests/ui/entry_btree.fixed @@ -8,7 +8,7 @@ fn foo() {} fn btree_map(m: &mut BTreeMap, k: K, v: V) { // insert then do something, use if let if let std::collections::btree_map::Entry::Vacant(e) = m.entry(k) { - //~^ map_entry + //~^ map_entry e.insert(v); foo(); } diff --git a/tests/ui/entry_btree.rs b/tests/ui/entry_btree.rs index 4e4b3a502e03..b795e32158ad 100644 --- a/tests/ui/entry_btree.rs +++ b/tests/ui/entry_btree.rs @@ -8,7 +8,7 @@ fn foo() {} fn btree_map(m: &mut BTreeMap, k: K, v: V) { // insert then do something, use if let if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry m.insert(k, v); foo(); } diff --git a/tests/ui/entry_with_else.fixed b/tests/ui/entry_with_else.fixed index 995611803908..76e6998235c2 100644 --- a/tests/ui/entry_with_else.fixed +++ b/tests/ui/entry_with_else.fixed @@ -13,7 +13,7 @@ fn foo() {} fn insert_if_absent0(m: &mut HashMap, k: K, v: V, v2: V) { match m.entry(k) { std::collections::hash_map::Entry::Vacant(e) => { - //~^ map_entry + //~^ map_entry e.insert(v); } std::collections::hash_map::Entry::Occupied(mut e) => { @@ -23,7 +23,7 @@ fn insert_if_absent0(m: &mut HashMap, k: K, match m.entry(k) { std::collections::hash_map::Entry::Occupied(mut e) => { - //~^ map_entry + //~^ map_entry e.insert(v); } std::collections::hash_map::Entry::Vacant(e) => { @@ -32,7 +32,7 @@ fn insert_if_absent0(m: &mut HashMap, k: K, } if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { - //~^ map_entry + //~^ map_entry e.insert(v); } else { foo(); @@ -41,13 +41,13 @@ fn insert_if_absent0(m: &mut HashMap, k: K, if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) { e.insert(v); } else { - //~^ map_entry + //~^ map_entry foo(); } match m.entry(k) { std::collections::hash_map::Entry::Vacant(e) => { - //~^ map_entry + //~^ map_entry e.insert(v); } std::collections::hash_map::Entry::Occupied(mut e) => { @@ -57,7 +57,7 @@ fn insert_if_absent0(m: &mut HashMap, k: K, match m.entry(k) { std::collections::hash_map::Entry::Occupied(mut e) => { - //~^ map_entry + //~^ map_entry if true { Some(e.insert(v)) } else { Some(e.insert(v2)) } } std::collections::hash_map::Entry::Vacant(e) => { @@ -67,7 +67,7 @@ fn insert_if_absent0(m: &mut HashMap, k: K, }; if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) { - //~^ map_entry + //~^ map_entry foo(); Some(e.insert(v)) } else { diff --git a/tests/ui/entry_with_else.rs b/tests/ui/entry_with_else.rs index dcfafedc11f8..1669cdc0c7cf 100644 --- a/tests/ui/entry_with_else.rs +++ b/tests/ui/entry_with_else.rs @@ -12,49 +12,49 @@ fn foo() {} fn insert_if_absent0(m: &mut HashMap, k: K, v: V, v2: V) { if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry m.insert(k, v); } else { m.insert(k, v2); } if m.contains_key(&k) { - //~^ map_entry + //~^ map_entry m.insert(k, v); } else { m.insert(k, v2); } if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry m.insert(k, v); } else { foo(); } if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry foo(); } else { m.insert(k, v); } if !m.contains_key(&k) { - //~^ map_entry + //~^ map_entry m.insert(k, v); } else { m.insert(k, v2); } if m.contains_key(&k) { - //~^ map_entry + //~^ map_entry if true { m.insert(k, v) } else { m.insert(k, v2) } } else { m.insert(k, v) }; if m.contains_key(&k) { - //~^ map_entry + //~^ map_entry foo(); m.insert(k, v) } else { diff --git a/tests/ui/enum_clike_unportable_variant.rs b/tests/ui/enum_clike_unportable_variant.rs index f54cca9c611c..4ff2024b25e9 100644 --- a/tests/ui/enum_clike_unportable_variant.rs +++ b/tests/ui/enum_clike_unportable_variant.rs @@ -7,8 +7,6 @@ enum NonPortable { X = 0x1_0000_0000, //~^ enum_clike_unportable_variant - - Y = 0, Z = 0x7FFF_FFFF, A = 0xFFFF_FFFF, @@ -17,12 +15,10 @@ enum NonPortable { enum NonPortableNoHint { X = 0x1_0000_0000, //~^ enum_clike_unportable_variant - Y = 0, Z = 0x7FFF_FFFF, A = 0xFFFF_FFFF, //~^ enum_clike_unportable_variant - } #[repr(isize)] @@ -31,14 +27,11 @@ enum NonPortableSigned { Y = 0x7FFF_FFFF, Z = 0xFFFF_FFFF, //~^ enum_clike_unportable_variant - A = 0x1_0000_0000, //~^ enum_clike_unportable_variant - B = i32::MIN as isize, C = (i32::MIN as isize) - 1, //~^ enum_clike_unportable_variant - } enum NonPortableSignedNoHint { @@ -46,17 +39,14 @@ enum NonPortableSignedNoHint { Y = 0x7FFF_FFFF, Z = 0xFFFF_FFFF, //~^ enum_clike_unportable_variant - A = 0x1_0000_0000, //~^ enum_clike_unportable_variant - } #[repr(usize)] enum NonPortable2 { X = ::Number, //~^ enum_clike_unportable_variant - Y = 0, } diff --git a/tests/ui/enum_clike_unportable_variant.stderr b/tests/ui/enum_clike_unportable_variant.stderr index ade2106ad96c..5a022a6fe8a6 100644 --- a/tests/ui/enum_clike_unportable_variant.stderr +++ b/tests/ui/enum_clike_unportable_variant.stderr @@ -8,49 +8,49 @@ LL | X = 0x1_0000_0000, = help: to override `-D warnings` add `#[allow(clippy::enum_clike_unportable_variant)]` error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:18:5 + --> tests/ui/enum_clike_unportable_variant.rs:16:5 | LL | X = 0x1_0000_0000, | ^^^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:23:5 + --> tests/ui/enum_clike_unportable_variant.rs:20:5 | LL | A = 0xFFFF_FFFF, | ^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:32:5 + --> tests/ui/enum_clike_unportable_variant.rs:28:5 | LL | Z = 0xFFFF_FFFF, | ^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:35:5 + --> tests/ui/enum_clike_unportable_variant.rs:30:5 | LL | A = 0x1_0000_0000, | ^^^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:39:5 + --> tests/ui/enum_clike_unportable_variant.rs:33:5 | LL | C = (i32::MIN as isize) - 1, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:47:5 + --> tests/ui/enum_clike_unportable_variant.rs:40:5 | LL | Z = 0xFFFF_FFFF, | ^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:50:5 + --> tests/ui/enum_clike_unportable_variant.rs:42:5 | LL | A = 0x1_0000_0000, | ^^^^^^^^^^^^^^^^^ error: C-like enum variant discriminant is not portable to 32-bit targets - --> tests/ui/enum_clike_unportable_variant.rs:57:5 + --> tests/ui/enum_clike_unportable_variant.rs:48:5 | LL | X = ::Number, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/enum_variants.rs b/tests/ui/enum_variants.rs index f3c81b2111ce..f7bbf83654f1 100644 --- a/tests/ui/enum_variants.rs +++ b/tests/ui/enum_variants.rs @@ -12,7 +12,7 @@ enum FakeCallType2 { } enum Foo { -//~^ enum_variant_names + //~^ enum_variant_names cFoo, //~^ enum_variant_names cBar, @@ -25,7 +25,7 @@ enum Fooo { } enum Food { -//~^ enum_variant_names + //~^ enum_variant_names FoodGood, //~^ enum_variant_names FoodMiddle, @@ -39,8 +39,7 @@ enum Stuff { } enum BadCallType { -//~^ enum_variant_names - + //~^ enum_variant_names CallTypeCall, CallTypeCreate, CallTypeDestroy, @@ -53,7 +52,7 @@ enum TwoCallType { } enum Consts { -//~^ enum_variant_names + //~^ enum_variant_names ConstantInt, ConstantCake, ConstantLie, @@ -66,7 +65,7 @@ enum Two { } enum Something { -//~^ enum_variant_names + //~^ enum_variant_names CCall, CCreate, CCryogenize, @@ -89,7 +88,7 @@ enum Sealll { } enum Seallll { -//~^ enum_variant_names + //~^ enum_variant_names WithOutCake, WithOutTea, WithOut, @@ -145,14 +144,14 @@ pub enum NetworkLayer { // should lint suggesting `IData`, not only `Data` (see #4639) enum IDataRequest { -//~^ enum_variant_names + //~^ enum_variant_names PutIData(String), GetIData(String), DeleteUnpubIData(String), } enum HIDataRequest { -//~^ enum_variant_names + //~^ enum_variant_names PutHIData(String), GetHIData(String), DeleteUnpubHIData(String), @@ -173,7 +172,7 @@ enum Phase { mod issue9018 { enum DoLint { - //~^ enum_variant_names + //~^ enum_variant_names _TypeCreate, _TypeRead, _TypeUpdate, @@ -181,7 +180,7 @@ mod issue9018 { } enum DoLintToo { - //~^ enum_variant_names + //~^ enum_variant_names _CreateType, _UpdateType, _DeleteType, diff --git a/tests/ui/enum_variants.stderr b/tests/ui/enum_variants.stderr index 2f0b0e6149d2..cca9d50033cf 100644 --- a/tests/ui/enum_variants.stderr +++ b/tests/ui/enum_variants.stderr @@ -55,7 +55,6 @@ error: all variants have the same prefix: `CallType` | LL | / enum BadCallType { LL | | -LL | | LL | | CallTypeCall, LL | | CallTypeCreate, LL | | CallTypeDestroy, @@ -65,7 +64,7 @@ LL | | } = help: remove the prefixes and use full paths to the variants instead of glob imports error: all variants have the same prefix: `Constant` - --> tests/ui/enum_variants.rs:55:1 + --> tests/ui/enum_variants.rs:54:1 | LL | / enum Consts { LL | | @@ -78,7 +77,7 @@ LL | | } = help: remove the prefixes and use full paths to the variants instead of glob imports error: all variants have the same prefix: `C` - --> tests/ui/enum_variants.rs:68:1 + --> tests/ui/enum_variants.rs:67:1 | LL | / enum Something { LL | | @@ -91,7 +90,7 @@ LL | | } = help: remove the prefixes and use full paths to the variants instead of glob imports error: all variants have the same prefix: `WithOut` - --> tests/ui/enum_variants.rs:91:1 + --> tests/ui/enum_variants.rs:90:1 | LL | / enum Seallll { LL | | @@ -104,7 +103,7 @@ LL | | } = help: remove the prefixes and use full paths to the variants instead of glob imports error: all variants have the same postfix: `IData` - --> tests/ui/enum_variants.rs:147:1 + --> tests/ui/enum_variants.rs:146:1 | LL | / enum IDataRequest { LL | | @@ -117,7 +116,7 @@ LL | | } = help: remove the postfixes and use full paths to the variants instead of glob imports error: all variants have the same postfix: `HIData` - --> tests/ui/enum_variants.rs:154:1 + --> tests/ui/enum_variants.rs:153:1 | LL | / enum HIDataRequest { LL | | @@ -130,7 +129,7 @@ LL | | } = help: remove the postfixes and use full paths to the variants instead of glob imports error: all variants have the same prefix: `_Type` - --> tests/ui/enum_variants.rs:175:5 + --> tests/ui/enum_variants.rs:174:5 | LL | / enum DoLint { LL | | @@ -144,7 +143,7 @@ LL | | } = help: remove the prefixes and use full paths to the variants instead of glob imports error: all variants have the same postfix: `Type` - --> tests/ui/enum_variants.rs:183:5 + --> tests/ui/enum_variants.rs:182:5 | LL | / enum DoLintToo { LL | | @@ -157,13 +156,13 @@ LL | | } = help: remove the postfixes and use full paths to the variants instead of glob imports error: variant name starts with the enum's name - --> tests/ui/enum_variants.rs:212:9 + --> tests/ui/enum_variants.rs:211:9 | LL | DataDependent, | ^^^^^^^^^^^^^ error: variant name starts with the enum's name - --> tests/ui/enum_variants.rs:217:9 + --> tests/ui/enum_variants.rs:216:9 | LL | DatasDependent, | ^^^^^^^^^^^^^^ diff --git a/tests/ui/eprint_with_newline.fixed b/tests/ui/eprint_with_newline.fixed index cb6cff419e9d..c50a707ace92 100644 --- a/tests/ui/eprint_with_newline.fixed +++ b/tests/ui/eprint_with_newline.fixed @@ -5,7 +5,6 @@ fn main() { eprintln!("Hello"); //~^ print_with_newline - eprintln!("Hello {}", "world"); //~^ print_with_newline @@ -18,7 +17,6 @@ fn main() { eprintln!(); //~^ print_with_newline - // these are all fine eprint!(""); eprint!("Hello"); @@ -50,13 +48,11 @@ fn main() { // Literal newlines should also fail eprintln!( - //~^ print_with_newline - + //~^ print_with_newline ); eprintln!( - //~^ print_with_newline - + //~^ print_with_newline ); diff --git a/tests/ui/eprint_with_newline.rs b/tests/ui/eprint_with_newline.rs index cfe503cec1f1..2c90480bdc78 100644 --- a/tests/ui/eprint_with_newline.rs +++ b/tests/ui/eprint_with_newline.rs @@ -5,7 +5,6 @@ fn main() { eprint!("Hello\n"); //~^ print_with_newline - eprint!("Hello {}\n", "world"); //~^ print_with_newline @@ -18,7 +17,6 @@ fn main() { eprint!("\n"); //~^ print_with_newline - // these are all fine eprint!(""); eprint!("Hello"); @@ -50,14 +48,12 @@ fn main() { // Literal newlines should also fail eprint!( - //~^ print_with_newline - + //~^ print_with_newline " " ); eprint!( - //~^ print_with_newline - + //~^ print_with_newline r" " ); diff --git a/tests/ui/eprint_with_newline.stderr b/tests/ui/eprint_with_newline.stderr index 87dcb9126b6d..c78cffd40c99 100644 --- a/tests/ui/eprint_with_newline.stderr +++ b/tests/ui/eprint_with_newline.stderr @@ -13,7 +13,7 @@ LL + eprintln!("Hello"); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:9:5 + --> tests/ui/eprint_with_newline.rs:8:5 | LL | eprint!("Hello {}\n", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + eprintln!("Hello {}", "world"); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:12:5 + --> tests/ui/eprint_with_newline.rs:11:5 | LL | eprint!("Hello {} {}\n", "world", "#2"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + eprintln!("Hello {} {}", "world", "#2"); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:15:5 + --> tests/ui/eprint_with_newline.rs:14:5 | LL | eprint!("{}\n", 1265); | ^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + eprintln!("{}", 1265); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:18:5 + --> tests/ui/eprint_with_newline.rs:17:5 | LL | eprint!("\n"); | ^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + eprintln!(); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:42:5 + --> tests/ui/eprint_with_newline.rs:40:5 | LL | eprint!("\\\n"); | ^^^^^^^^^^^^^^^ @@ -73,11 +73,10 @@ LL + eprintln!("\\"); | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:52:5 + --> tests/ui/eprint_with_newline.rs:50:5 | LL | / eprint!( LL | | -LL | | LL | | " LL | | " LL | | ); @@ -87,16 +86,14 @@ help: use `eprintln!` instead | LL ~ eprintln!( LL | -LL | LL ~ | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:58:5 + --> tests/ui/eprint_with_newline.rs:55:5 | LL | / eprint!( LL | | -LL | | LL | | r" LL | | " LL | | ); @@ -106,12 +103,11 @@ help: use `eprintln!` instead | LL ~ eprintln!( LL | -LL | LL ~ | error: using `eprint!()` with a format string that ends in a single newline - --> tests/ui/eprint_with_newline.rs:68:5 + --> tests/ui/eprint_with_newline.rs:64:5 | LL | eprint!("\\r\n"); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/eq_op.rs b/tests/ui/eq_op.rs index 757a7e011903..ced0452ee9a8 100644 --- a/tests/ui/eq_op.rs +++ b/tests/ui/eq_op.rs @@ -7,7 +7,6 @@ fn main() { let _ = 1 == 1; //~^ eq_op - let _ = "no" == "no"; //~^ eq_op @@ -25,8 +24,6 @@ fn main() { let _ = x != x; //~^ eq_op - - // casts, methods, parentheses let _ = (1u32 as u64) & (1u32 as u64); //~^ eq_op @@ -47,12 +44,9 @@ fn main() { //~| eq_op //~| eq_op - - let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4; //~^ eq_op - // various other things let _ = ([1] != [1]); //~^ eq_op @@ -70,8 +64,6 @@ fn main() { //~^ eq_op //~| eq_op - - let _ = 1 - 1; //~^ eq_op @@ -81,11 +73,9 @@ fn main() { let _ = true && true; //~^ eq_op - let _ = true || true; //~^ eq_op - let a: u32 = 0; let b: u32 = 0; @@ -101,7 +91,6 @@ fn main() { let _ = a <= b && b >= a; //~^ eq_op - let mut a = vec![1]; let _ = a == a; //~^ eq_op @@ -117,7 +106,6 @@ fn main() { const C: u32 = A / B; // ok, different named constants const D: u32 = A / A; //~^ eq_op - } macro_rules! check_if_named_foo { @@ -150,7 +138,6 @@ fn check_nested(n1: &Nested, n2: &Nested) -> bool { // `n2.inner.0.0` mistyped as `n1.inner.0.0` (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0 //~^ eq_op - } #[test] diff --git a/tests/ui/eq_op.stderr b/tests/ui/eq_op.stderr index bd9362f3e0dd..1696f09d6d17 100644 --- a/tests/ui/eq_op.stderr +++ b/tests/ui/eq_op.stderr @@ -8,31 +8,31 @@ LL | let _ = 1 == 1; = help: to override `-D warnings` add `#[allow(clippy::eq_op)]` error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:11:13 + --> tests/ui/eq_op.rs:10:13 | LL | let _ = "no" == "no"; | ^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/eq_op.rs:15:13 + --> tests/ui/eq_op.rs:14:13 | LL | let _ = false != false; | ^^^^^^^^^^^^^^ error: equal expressions as operands to `<` - --> tests/ui/eq_op.rs:18:13 + --> tests/ui/eq_op.rs:17:13 | LL | let _ = 1.5 < 1.5; | ^^^^^^^^^ error: equal expressions as operands to `>=` - --> tests/ui/eq_op.rs:21:13 + --> tests/ui/eq_op.rs:20:13 | LL | let _ = 1u64 >= 1u64; | ^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/eq_op.rs:25:13 + --> tests/ui/eq_op.rs:24:13 | LL | let _ = x != x; | ^^^^^^ @@ -40,139 +40,139 @@ LL | let _ = x != x; = note: if you intended to check if the operand is NaN, use `.is_nan()` instead error: equal expressions as operands to `&` - --> tests/ui/eq_op.rs:31:13 + --> tests/ui/eq_op.rs:28:13 | LL | let _ = (1u32 as u64) & (1u32 as u64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `^` - --> tests/ui/eq_op.rs:36:17 + --> tests/ui/eq_op.rs:33:17 | LL | let _ = 1 ^ ((((((1)))))); | ^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `<` - --> tests/ui/eq_op.rs:42:13 + --> tests/ui/eq_op.rs:39:13 | LL | let _ = (-(2) < -(2)); | ^^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:45:13 + --> tests/ui/eq_op.rs:42:13 | LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `&` - --> tests/ui/eq_op.rs:45:14 + --> tests/ui/eq_op.rs:42:14 | LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); | ^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `&` - --> tests/ui/eq_op.rs:45:35 + --> tests/ui/eq_op.rs:42:35 | LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); | ^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:52:13 + --> tests/ui/eq_op.rs:47:13 | LL | let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/eq_op.rs:57:13 + --> tests/ui/eq_op.rs:51:13 | LL | let _ = ([1] != [1]); | ^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> tests/ui/eq_op.rs:60:13 + --> tests/ui/eq_op.rs:54:13 | LL | let _ = ((1, 2) != (1, 2)); | ^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:66:13 + --> tests/ui/eq_op.rs:60:13 | LL | let _ = 1 + 1 == 2; | ^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:69:13 + --> tests/ui/eq_op.rs:63:13 | LL | let _ = 1 - 1 == 0; | ^^^^^^^^^^ error: equal expressions as operands to `-` - --> tests/ui/eq_op.rs:69:13 + --> tests/ui/eq_op.rs:63:13 | LL | let _ = 1 - 1 == 0; | ^^^^^ error: equal expressions as operands to `-` - --> tests/ui/eq_op.rs:75:13 + --> tests/ui/eq_op.rs:67:13 | LL | let _ = 1 - 1; | ^^^^^ error: equal expressions as operands to `/` - --> tests/ui/eq_op.rs:78:13 + --> tests/ui/eq_op.rs:70:13 | LL | let _ = 1 / 1; | ^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:81:13 + --> tests/ui/eq_op.rs:73:13 | LL | let _ = true && true; | ^^^^^^^^^^^^ error: equal expressions as operands to `||` - --> tests/ui/eq_op.rs:85:13 + --> tests/ui/eq_op.rs:76:13 | LL | let _ = true || true; | ^^^^^^^^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:92:13 + --> tests/ui/eq_op.rs:82:13 | LL | let _ = a == b && b == a; | ^^^^^^^^^^^^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:95:13 + --> tests/ui/eq_op.rs:85:13 | LL | let _ = a != b && b != a; | ^^^^^^^^^^^^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:98:13 + --> tests/ui/eq_op.rs:88:13 | LL | let _ = a < b && b > a; | ^^^^^^^^^^^^^^ error: equal expressions as operands to `&&` - --> tests/ui/eq_op.rs:101:13 + --> tests/ui/eq_op.rs:91:13 | LL | let _ = a <= b && b >= a; | ^^^^^^^^^^^^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:106:13 + --> tests/ui/eq_op.rs:95:13 | LL | let _ = a == a; | ^^^^^^ error: equal expressions as operands to `/` - --> tests/ui/eq_op.rs:118:20 + --> tests/ui/eq_op.rs:107:20 | LL | const D: u32 = A / A; | ^^^^^ error: equal expressions as operands to `==` - --> tests/ui/eq_op.rs:151:5 + --> tests/ui/eq_op.rs:139:5 | LL | (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/equatable_if_let.fixed b/tests/ui/equatable_if_let.fixed index 2f39c34cb394..166b1387ba26 100644 --- a/tests/ui/equatable_if_let.fixed +++ b/tests/ui/equatable_if_let.fixed @@ -97,7 +97,7 @@ fn main() { //~^ equatable_if_let if "abc" == inline!("abc") { - //~^ equatable_if_let + //~^ equatable_if_let println!("OK"); } diff --git a/tests/ui/equatable_if_let.rs b/tests/ui/equatable_if_let.rs index f7289a9ee56f..09c2483ae6d4 100644 --- a/tests/ui/equatable_if_let.rs +++ b/tests/ui/equatable_if_let.rs @@ -97,7 +97,7 @@ fn main() { //~^ equatable_if_let if let inline!("abc") = "abc" { - //~^ equatable_if_let + //~^ equatable_if_let println!("OK"); } diff --git a/tests/ui/erasing_op.rs b/tests/ui/erasing_op.rs index 9387a20cb5a0..9237b9eb11f0 100644 --- a/tests/ui/erasing_op.rs +++ b/tests/ui/erasing_op.rs @@ -35,7 +35,6 @@ fn test(x: u8) { x * 0; //~^ erasing_op - 0 & x; //~^ erasing_op @@ -48,7 +47,6 @@ fn test(x: u8) { Vec1 { x: 5 } * 0; //~^ erasing_op - } fn main() { diff --git a/tests/ui/erasing_op.stderr b/tests/ui/erasing_op.stderr index 7029fac6c130..94730b066801 100644 --- a/tests/ui/erasing_op.stderr +++ b/tests/ui/erasing_op.stderr @@ -8,25 +8,25 @@ LL | x * 0; = help: to override `-D warnings` add `#[allow(clippy::erasing_op)]` error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/erasing_op.rs:39:5 + --> tests/ui/erasing_op.rs:38:5 | LL | 0 & x; | ^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/erasing_op.rs:42:5 + --> tests/ui/erasing_op.rs:41:5 | LL | 0 / x; | ^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/erasing_op.rs:46:5 + --> tests/ui/erasing_op.rs:45:5 | LL | 0 * Vec1 { x: 5 }; | ^^^^^^^^^^^^^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> tests/ui/erasing_op.rs:49:5 + --> tests/ui/erasing_op.rs:48:5 | LL | Vec1 { x: 5 } * 0; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/error_impl_error.rs b/tests/ui/error_impl_error.rs index 3606e1bcefbb..5c88888f38ea 100644 --- a/tests/ui/error_impl_error.rs +++ b/tests/ui/error_impl_error.rs @@ -7,7 +7,6 @@ pub mod a { pub struct Error; //~^ error_impl_error - impl std::fmt::Display for Error { fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { todo!() @@ -22,7 +21,6 @@ mod b { pub(super) enum Error {} //~^ error_impl_error - impl std::fmt::Display for Error { fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { todo!() @@ -34,8 +32,7 @@ mod b { pub mod c { pub union Error { - //~^ error_impl_error - + //~^ error_impl_error a: u32, b: u32, } @@ -58,7 +55,6 @@ pub mod c { pub mod d { pub type Error = std::fmt::Error; //~^ error_impl_error - } mod e { diff --git a/tests/ui/error_impl_error.stderr b/tests/ui/error_impl_error.stderr index 4fa1ffeb4c92..087d43d1d083 100644 --- a/tests/ui/error_impl_error.stderr +++ b/tests/ui/error_impl_error.stderr @@ -5,7 +5,7 @@ LL | pub struct Error; | ^^^^^ | note: `Error` was implemented here - --> tests/ui/error_impl_error.rs:17:5 + --> tests/ui/error_impl_error.rs:16:5 | LL | impl std::error::Error for Error {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,31 +13,31 @@ LL | impl std::error::Error for Error {} = help: to override `-D warnings` add `#[allow(clippy::error_impl_error)]` error: exported type named `Error` that implements `Error` - --> tests/ui/error_impl_error.rs:22:21 + --> tests/ui/error_impl_error.rs:21:21 | LL | pub(super) enum Error {} | ^^^^^ | note: `Error` was implemented here - --> tests/ui/error_impl_error.rs:32:5 + --> tests/ui/error_impl_error.rs:30:5 | LL | impl std::error::Error for Error {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: exported type named `Error` that implements `Error` - --> tests/ui/error_impl_error.rs:36:15 + --> tests/ui/error_impl_error.rs:34:15 | LL | pub union Error { | ^^^^^ | note: `Error` was implemented here - --> tests/ui/error_impl_error.rs:55:5 + --> tests/ui/error_impl_error.rs:52:5 | LL | impl std::error::Error for Error {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: exported type alias named `Error` that implements `Error` - --> tests/ui/error_impl_error.rs:59:14 + --> tests/ui/error_impl_error.rs:56:14 | LL | pub type Error = std::fmt::Error; | ^^^^^ diff --git a/tests/ui/exhaustive_items.fixed b/tests/ui/exhaustive_items.fixed index a3c584c2a269..79c74aeefbd8 100644 --- a/tests/ui/exhaustive_items.fixed +++ b/tests/ui/exhaustive_items.fixed @@ -8,7 +8,7 @@ fn main() { pub mod enums { #[non_exhaustive] pub enum Exhaustive { - //~^ exhaustive_enums + //~^ exhaustive_enums Foo, Bar, Baz, @@ -19,7 +19,7 @@ pub mod enums { #[repr(C)] #[non_exhaustive] pub enum ExhaustiveWithAttrs { - //~^ exhaustive_enums + //~^ exhaustive_enums Foo, Bar, Baz, @@ -56,7 +56,7 @@ pub mod enums { pub mod structs { #[non_exhaustive] pub struct Exhaustive { - //~^ exhaustive_structs + //~^ exhaustive_structs pub foo: u8, pub bar: String, } diff --git a/tests/ui/exhaustive_items.rs b/tests/ui/exhaustive_items.rs index b1f0c789b709..4e851f4c492e 100644 --- a/tests/ui/exhaustive_items.rs +++ b/tests/ui/exhaustive_items.rs @@ -7,7 +7,7 @@ fn main() { pub mod enums { pub enum Exhaustive { - //~^ exhaustive_enums + //~^ exhaustive_enums Foo, Bar, Baz, @@ -17,7 +17,7 @@ pub mod enums { /// Some docs #[repr(C)] pub enum ExhaustiveWithAttrs { - //~^ exhaustive_enums + //~^ exhaustive_enums Foo, Bar, Baz, @@ -53,7 +53,7 @@ pub mod enums { pub mod structs { pub struct Exhaustive { - //~^ exhaustive_structs + //~^ exhaustive_structs pub foo: u8, pub bar: String, } diff --git a/tests/ui/exit1.rs b/tests/ui/exit1.rs index 127c72aac99f..be8752cc7d8e 100644 --- a/tests/ui/exit1.rs +++ b/tests/ui/exit1.rs @@ -4,8 +4,6 @@ fn not_main() { if true { std::process::exit(4); //~^ exit - - } } diff --git a/tests/ui/exit2.rs b/tests/ui/exit2.rs index 2e2c4828afe6..2be8a84b6d4b 100644 --- a/tests/ui/exit2.rs +++ b/tests/ui/exit2.rs @@ -3,8 +3,6 @@ fn also_not_main() { std::process::exit(3); //~^ exit - - } fn main() { diff --git a/tests/ui/expect.rs b/tests/ui/expect.rs index 575c29e6f31c..8f7379f00214 100644 --- a/tests/ui/expect.rs +++ b/tests/ui/expect.rs @@ -5,7 +5,6 @@ fn expect_option() { let opt = Some(0); let _ = opt.expect(""); //~^ expect_used - } fn expect_result() { @@ -15,7 +14,6 @@ fn expect_result() { let _ = res.expect_err(""); //~^ expect_used - } fn main() { diff --git a/tests/ui/expect.stderr b/tests/ui/expect.stderr index b44429a3b71d..70cf3072003e 100644 --- a/tests/ui/expect.stderr +++ b/tests/ui/expect.stderr @@ -9,7 +9,7 @@ LL | let _ = opt.expect(""); = help: to override `-D warnings` add `#[allow(clippy::expect_used)]` error: used `expect()` on a `Result` value - --> tests/ui/expect.rs:13:13 + --> tests/ui/expect.rs:12:13 | LL | let _ = res.expect(""); | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = res.expect(""); = note: if this value is an `Err`, it will panic error: used `expect_err()` on a `Result` value - --> tests/ui/expect.rs:16:13 + --> tests/ui/expect.rs:15:13 | LL | let _ = res.expect_err(""); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/explicit_counter_loop.rs b/tests/ui/explicit_counter_loop.rs index 585e261c2f43..8340d99ace22 100644 --- a/tests/ui/explicit_counter_loop.rs +++ b/tests/ui/explicit_counter_loop.rs @@ -5,8 +5,7 @@ fn main() { let mut vec = vec![1, 2, 3, 4]; let mut _index = 0; for _v in &vec { - //~^ explicit_counter_loop - + //~^ explicit_counter_loop _index += 1 } @@ -14,21 +13,21 @@ fn main() { let mut _index = 1; _index = 0; for _v in &vec { - //~^ explicit_counter_loop + //~^ explicit_counter_loop _index += 1 } let mut _index = 0; for _v in &mut vec { - //~^ explicit_counter_loop + //~^ explicit_counter_loop _index += 1; } let mut _index = 0; for _v in vec { - //~^ explicit_counter_loop + //~^ explicit_counter_loop _index += 1; } @@ -117,7 +116,7 @@ mod issue_1219 { let text = "banana"; let mut count = 0; for ch in text.chars() { - //~^ explicit_counter_loop + //~^ explicit_counter_loop println!("{}", count); count += 1; @@ -130,7 +129,7 @@ mod issue_1219 { let text = "banana"; let mut count = 0; for ch in text.chars() { - //~^ explicit_counter_loop + //~^ explicit_counter_loop println!("{}", count); count += 1; @@ -190,7 +189,7 @@ mod issue_1670 { pub fn test() { let mut count = 0; for _i in 3..10 { - //~^ explicit_counter_loop + //~^ explicit_counter_loop count += 1; } @@ -232,7 +231,7 @@ mod issue_7920 { // should suggest `enumerate` for _item in slice { - //~^ explicit_counter_loop + //~^ explicit_counter_loop if idx_usize == index_usize { break; @@ -246,8 +245,7 @@ mod issue_7920 { // should suggest `zip` for _item in slice { - //~^ explicit_counter_loop - + //~^ explicit_counter_loop if idx_u32 == index_u32 { break; @@ -293,7 +291,7 @@ mod issue_13123 { let mut vec = vec![1, 2, 3, 4]; let mut _index = 0; 'label: for v in vec { - //~^ explicit_counter_loop + //~^ explicit_counter_loop _index += 1; if v == 1 { break 'label; diff --git a/tests/ui/explicit_counter_loop.stderr b/tests/ui/explicit_counter_loop.stderr index c565bd4cf356..a73516558c20 100644 --- a/tests/ui/explicit_counter_loop.stderr +++ b/tests/ui/explicit_counter_loop.stderr @@ -8,49 +8,49 @@ LL | for _v in &vec { = help: to override `-D warnings` add `#[allow(clippy::explicit_counter_loop)]` error: the variable `_index` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:16:5 + --> tests/ui/explicit_counter_loop.rs:15:5 | LL | for _v in &vec { | ^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter().enumerate()` error: the variable `_index` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:23:5 + --> tests/ui/explicit_counter_loop.rs:22:5 | LL | for _v in &mut vec { | ^^^^^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter_mut().enumerate()` error: the variable `_index` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:30:5 + --> tests/ui/explicit_counter_loop.rs:29:5 | LL | for _v in vec { | ^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.into_iter().enumerate()` error: the variable `count` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:119:9 + --> tests/ui/explicit_counter_loop.rs:118:9 | LL | for ch in text.chars() { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()` error: the variable `count` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:132:9 + --> tests/ui/explicit_counter_loop.rs:131:9 | LL | for ch in text.chars() { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()` error: the variable `count` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:192:9 + --> tests/ui/explicit_counter_loop.rs:191:9 | LL | for _i in 3..10 { | ^^^^^^^^^^^^^^^ help: consider using: `for (count, _i) in (3..10).enumerate()` error: the variable `idx_usize` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:234:9 + --> tests/ui/explicit_counter_loop.rs:233:9 | LL | for _item in slice { | ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_usize, _item) in slice.iter().enumerate()` error: the variable `idx_u32` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:248:9 + --> tests/ui/explicit_counter_loop.rs:247:9 | LL | for _item in slice { | ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_u32, _item) in (0_u32..).zip(slice.iter())` @@ -58,7 +58,7 @@ LL | for _item in slice { = note: `idx_u32` is of type `u32`, making it ineligible for `Iterator::enumerate` error: the variable `_index` is used as a loop counter - --> tests/ui/explicit_counter_loop.rs:295:9 + --> tests/ui/explicit_counter_loop.rs:293:9 | LL | 'label: for v in vec { | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `'label: for (_index, v) in vec.into_iter().enumerate()` diff --git a/tests/ui/explicit_deref_methods.fixed b/tests/ui/explicit_deref_methods.fixed index ae63f7cbfd8c..0d1a5f80f3d5 100644 --- a/tests/ui/explicit_deref_methods.fixed +++ b/tests/ui/explicit_deref_methods.fixed @@ -67,7 +67,7 @@ fn main() { #[allow(clippy::match_single_binding)] match &*a { - //~^ explicit_deref_methods + //~^ explicit_deref_methods _ => (), } diff --git a/tests/ui/explicit_deref_methods.rs b/tests/ui/explicit_deref_methods.rs index a1378bda85fa..8d4a899cd260 100644 --- a/tests/ui/explicit_deref_methods.rs +++ b/tests/ui/explicit_deref_methods.rs @@ -67,7 +67,7 @@ fn main() { #[allow(clippy::match_single_binding)] match a.deref() { - //~^ explicit_deref_methods + //~^ explicit_deref_methods _ => (), } diff --git a/tests/ui/extra_unused_lifetimes.rs b/tests/ui/extra_unused_lifetimes.rs index fb853bb58305..5fdcd5a7e078 100644 --- a/tests/ui/extra_unused_lifetimes.rs +++ b/tests/ui/extra_unused_lifetimes.rs @@ -84,16 +84,16 @@ mod issue6437 { pub struct Scalar; impl<'a> std::ops::AddAssign<&Scalar> for &mut Scalar { - //~^ extra_unused_lifetimes + //~^ extra_unused_lifetimes fn add_assign(&mut self, _rhs: &Scalar) { unimplemented!(); } } impl<'b> Scalar { - //~^ extra_unused_lifetimes - pub fn something<'c>() -> Self { //~^ extra_unused_lifetimes + pub fn something<'c>() -> Self { + //~^ extra_unused_lifetimes Self } } @@ -123,7 +123,7 @@ mod second_case { // Should lint. The response to the above comment incorrectly called this a false positive. The // lifetime `'a` can be removed, as demonstrated below. impl<'a, T: Source + ?Sized + 'a> Source for Box { - //~^ extra_unused_lifetimes + //~^ extra_unused_lifetimes fn hey() {} } diff --git a/tests/ui/extra_unused_type_parameters.fixed b/tests/ui/extra_unused_type_parameters.fixed index 1ab74d398314..32d4f6c69390 100644 --- a/tests/ui/extra_unused_type_parameters.fixed +++ b/tests/ui/extra_unused_type_parameters.fixed @@ -7,17 +7,17 @@ extern crate proc_macros; use proc_macros::with_span; fn unused_ty(x: u8) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } fn unused_multi(x: u8) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } fn unused_with_lt<'a>(x: &'a u8) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } @@ -30,12 +30,12 @@ fn used_ret(x: u8) -> T { } fn unused_bounded(x: U) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!(); } fn some_unused(b: B, c: C) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!(); } @@ -61,7 +61,7 @@ struct S; impl S { fn unused_ty_impl(&self) { - //~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } } @@ -84,7 +84,7 @@ where } fn unused_opaque(dummy: impl Default) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } @@ -98,7 +98,7 @@ mod unexported_trait_bounds { } fn unused_with_priv_trait_bound() { - //~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!(); } } diff --git a/tests/ui/extra_unused_type_parameters.rs b/tests/ui/extra_unused_type_parameters.rs index 0837efef27bb..c1e6f32ca12f 100644 --- a/tests/ui/extra_unused_type_parameters.rs +++ b/tests/ui/extra_unused_type_parameters.rs @@ -7,17 +7,17 @@ extern crate proc_macros; use proc_macros::with_span; fn unused_ty(x: u8) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } fn unused_multi(x: u8) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } fn unused_with_lt<'a, T>(x: &'a u8) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } @@ -30,12 +30,12 @@ fn used_ret(x: u8) -> T { } fn unused_bounded(x: U) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!(); } fn some_unused, E>(b: B, c: C) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!(); } @@ -61,7 +61,7 @@ struct S; impl S { fn unused_ty_impl(&self) { - //~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } } @@ -84,7 +84,7 @@ where } fn unused_opaque(dummy: impl Default) { -//~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!() } @@ -98,7 +98,7 @@ mod unexported_trait_bounds { } fn unused_with_priv_trait_bound() { - //~^ extra_unused_type_parameters + //~^ extra_unused_type_parameters unimplemented!(); } } diff --git a/tests/ui/extra_unused_type_parameters_unfixable.rs b/tests/ui/extra_unused_type_parameters_unfixable.rs index e69c924af00d..87ce517a0a45 100644 --- a/tests/ui/extra_unused_type_parameters_unfixable.rs +++ b/tests/ui/extra_unused_type_parameters_unfixable.rs @@ -2,7 +2,6 @@ fn unused_where_clause(x: U) //~^ extra_unused_type_parameters - where T: Default, { @@ -11,7 +10,6 @@ where fn unused_multi_where_clause(x: U) //~^ extra_unused_type_parameters - where T: Default, { @@ -20,7 +18,6 @@ where fn unused_all_where_clause() //~^ extra_unused_type_parameters - where T: Default, { diff --git a/tests/ui/extra_unused_type_parameters_unfixable.stderr b/tests/ui/extra_unused_type_parameters_unfixable.stderr index 8accb7e5924e..0765c4160936 100644 --- a/tests/ui/extra_unused_type_parameters_unfixable.stderr +++ b/tests/ui/extra_unused_type_parameters_unfixable.stderr @@ -9,7 +9,7 @@ LL | fn unused_where_clause(x: U) = help: to override `-D warnings` add `#[allow(clippy::extra_unused_type_parameters)]` error: type parameters go unused in function definition: T, V - --> tests/ui/extra_unused_type_parameters_unfixable.rs:12:30 + --> tests/ui/extra_unused_type_parameters_unfixable.rs:11:30 | LL | fn unused_multi_where_clause(x: U) | ^ ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn unused_multi_where_clause(x: U) = help: consider removing the parameters error: type parameters go unused in function definition: T, U, V - --> tests/ui/extra_unused_type_parameters_unfixable.rs:21:28 + --> tests/ui/extra_unused_type_parameters_unfixable.rs:19:28 | LL | fn unused_all_where_clause() | ^ ^^^^^^^^^^ ^^^^^^^^^^ diff --git a/tests/ui/fallible_impl_from.rs b/tests/ui/fallible_impl_from.rs index 56bd8a482684..1c62c1e937b6 100644 --- a/tests/ui/fallible_impl_from.rs +++ b/tests/ui/fallible_impl_from.rs @@ -4,7 +4,7 @@ // docs example struct Foo(i32); impl From for Foo { -//~^ fallible_impl_from + //~^ fallible_impl_from fn from(s: String) -> Self { Foo(s.parse().unwrap()) @@ -27,7 +27,7 @@ impl From for Valid { struct Invalid; impl From for Invalid { -//~^ fallible_impl_from + //~^ fallible_impl_from fn from(i: usize) -> Invalid { if i != 42 { @@ -38,7 +38,7 @@ impl From for Invalid { } impl From> for Invalid { -//~^ fallible_impl_from + //~^ fallible_impl_from fn from(s: Option) -> Invalid { let s = s.unwrap(); @@ -58,7 +58,7 @@ impl ProjStrTrait for Box { type ProjString = String; } impl<'a> From<&'a mut as ProjStrTrait>::ProjString> for Invalid { -//~^ fallible_impl_from + //~^ fallible_impl_from fn from(s: &'a mut as ProjStrTrait>::ProjString) -> Invalid { if s.parse::().ok().unwrap() != 42 { diff --git a/tests/ui/filetype_is_file.rs b/tests/ui/filetype_is_file.rs index 0e9c160e4a90..8ca01b91210f 100644 --- a/tests/ui/filetype_is_file.rs +++ b/tests/ui/filetype_is_file.rs @@ -7,21 +7,21 @@ fn main() -> std::io::Result<()> { // !filetype.is_dir() if fs::metadata("foo.txt")?.file_type().is_file() { - //~^ filetype_is_file + //~^ filetype_is_file // read file } // positive of filetype.is_dir() if !fs::metadata("foo.txt")?.file_type().is_file() { - //~^ filetype_is_file + //~^ filetype_is_file // handle dir } // false positive of filetype.is_dir() if !fs::metadata("foo.txt")?.file_type().is_file().bitor(true) { - //~^ filetype_is_file + //~^ filetype_is_file // ... } diff --git a/tests/ui/filter_map_bool_then.fixed b/tests/ui/filter_map_bool_then.fixed index 6d9564dc828b..b3e112f19eb4 100644 --- a/tests/ui/filter_map_bool_then.fixed +++ b/tests/ui/filter_map_bool_then.fixed @@ -23,17 +23,17 @@ fn main() { v.clone() .into_iter() .filter(|&i| (i % 2 == 0)).map(|i| i + 1); - //~^ filter_map_bool_then + //~^ filter_map_bool_then v.clone() .into_iter() .filter(|&i| i != 1000) .filter(|&i| (i % 2 == 0)).map(|i| i + 1); - //~^ filter_map_bool_then + //~^ filter_map_bool_then v.iter() .copied() .filter(|&i| i != 1000) .filter(|&i| (i.clone() % 2 == 0)).map(|i| i + 1); - //~^ filter_map_bool_then + //~^ filter_map_bool_then // Despite this is non-copy, `is_copy` still returns true (at least now) because it's `&NonCopy`, // and any `&` is `Copy`. So since we can dereference it in `filter` (since it's then `&&NonCopy`), // we can lint this and still get the same input type. diff --git a/tests/ui/filter_map_bool_then.rs b/tests/ui/filter_map_bool_then.rs index dffd798da254..d996b3cb3c52 100644 --- a/tests/ui/filter_map_bool_then.rs +++ b/tests/ui/filter_map_bool_then.rs @@ -23,17 +23,17 @@ fn main() { v.clone() .into_iter() .filter_map(|i| -> Option<_> { (i % 2 == 0).then(|| i + 1) }); - //~^ filter_map_bool_then + //~^ filter_map_bool_then v.clone() .into_iter() .filter(|&i| i != 1000) .filter_map(|i| (i % 2 == 0).then(|| i + 1)); - //~^ filter_map_bool_then + //~^ filter_map_bool_then v.iter() .copied() .filter(|&i| i != 1000) .filter_map(|i| (i.clone() % 2 == 0).then(|| i + 1)); - //~^ filter_map_bool_then + //~^ filter_map_bool_then // Despite this is non-copy, `is_copy` still returns true (at least now) because it's `&NonCopy`, // and any `&` is `Copy`. So since we can dereference it in `filter` (since it's then `&&NonCopy`), // we can lint this and still get the same input type. diff --git a/tests/ui/filter_map_identity.fixed b/tests/ui/filter_map_identity.fixed index 40c3f58da976..c9e2c5f5049f 100644 --- a/tests/ui/filter_map_identity.fixed +++ b/tests/ui/filter_map_identity.fixed @@ -40,14 +40,6 @@ fn main() { copy_vec_non_inferred().into_iter().flatten(); //~^ filter_map_identity - - non_copy_vec().into_iter().flatten(); - //~^ filter_map_identity - - non_copy_vec().into_iter().flatten(); - //~^ filter_map_identity - - non_copy_vec().into_iter().flatten(); //~^ filter_map_identity @@ -60,6 +52,11 @@ fn main() { non_copy_vec().into_iter().flatten(); //~^ filter_map_identity + non_copy_vec().into_iter().flatten(); + //~^ filter_map_identity + + non_copy_vec().into_iter().flatten(); + //~^ filter_map_identity copy_vec::().into_iter().flatten(); //~^ filter_map_identity @@ -73,7 +70,6 @@ fn main() { copy_vec::().into_iter().flatten(); //~^ filter_map_identity - // we are forced to pass the type in the call. copy_vec::().into_iter().flatten(); //~^ filter_map_identity @@ -89,18 +85,16 @@ fn main() { #[rustfmt::skip] copy_vec::().into_iter().flatten(); - //~^ filter_map_identity + //~^ filter_map_identity #[rustfmt::skip] copy_vec::().into_iter().flatten(); - //~^ filter_map_identity - + //~^ filter_map_identity // note, the compiler requires that we pass the type to `opaque`. This is mostly for reference, // it behaves the same as copy_vec. opaque::().into_iter().flatten(); //~^ filter_map_identity - } } diff --git a/tests/ui/filter_map_identity.rs b/tests/ui/filter_map_identity.rs index f11f80437e85..4c8d48f5221f 100644 --- a/tests/ui/filter_map_identity.rs +++ b/tests/ui/filter_map_identity.rs @@ -40,14 +40,12 @@ fn main() { copy_vec_non_inferred().into_iter().filter_map(|x| return x); //~^ filter_map_identity - non_copy_vec().into_iter().filter_map(|x| x); //~^ filter_map_identity non_copy_vec().into_iter().filter_map(|x| x); //~^ filter_map_identity - non_copy_vec().into_iter().filter_map(std::convert::identity); //~^ filter_map_identity @@ -60,7 +58,6 @@ fn main() { non_copy_vec().into_iter().filter_map(|x| return x); //~^ filter_map_identity - copy_vec::().into_iter().filter_map(|x: Option<_>| x); //~^ filter_map_identity @@ -73,7 +70,6 @@ fn main() { copy_vec::().into_iter().filter_map(|x: Option<_>| return x); //~^ filter_map_identity - // we are forced to pass the type in the call. copy_vec::().into_iter().filter_map(|x: Option| x); //~^ filter_map_identity @@ -89,18 +85,16 @@ fn main() { #[rustfmt::skip] copy_vec::().into_iter().filter_map(|x: Option| -> Option {{ x }}); - //~^ filter_map_identity + //~^ filter_map_identity #[rustfmt::skip] copy_vec::().into_iter().filter_map(|x: Option| -> Option {{ return x }}); - //~^ filter_map_identity - + //~^ filter_map_identity // note, the compiler requires that we pass the type to `opaque`. This is mostly for reference, // it behaves the same as copy_vec. opaque::().into_iter().filter_map(|x| x); //~^ filter_map_identity - } } diff --git a/tests/ui/filter_map_identity.stderr b/tests/ui/filter_map_identity.stderr index 4223343251f1..26b6e0bc7b34 100644 --- a/tests/ui/filter_map_identity.stderr +++ b/tests/ui/filter_map_identity.stderr @@ -32,41 +32,47 @@ LL | copy_vec_non_inferred().into_iter().filter_map(|x| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:44:36 + --> tests/ui/filter_map_identity.rs:43:36 | LL | non_copy_vec().into_iter().filter_map(|x| x); | ^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:47:36 + --> tests/ui/filter_map_identity.rs:46:36 | LL | non_copy_vec().into_iter().filter_map(|x| x); | ^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:51:36 + --> tests/ui/filter_map_identity.rs:49:36 | LL | non_copy_vec().into_iter().filter_map(std::convert::identity); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:54:36 + --> tests/ui/filter_map_identity.rs:52:36 | LL | non_copy_vec().into_iter().filter_map(identity); | ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:57:36 + --> tests/ui/filter_map_identity.rs:55:36 | LL | non_copy_vec().into_iter().filter_map(|x| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:60:36 + --> tests/ui/filter_map_identity.rs:58:36 | LL | non_copy_vec().into_iter().filter_map(|x| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` +error: use of `filter_map` with an identity function + --> tests/ui/filter_map_identity.rs:61:39 + | +LL | copy_vec::().into_iter().filter_map(|x: Option<_>| x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` + error: use of `filter_map` with an identity function --> tests/ui/filter_map_identity.rs:64:39 | @@ -76,8 +82,8 @@ LL | copy_vec::().into_iter().filter_map(|x: Option<_>| x); error: use of `filter_map` with an identity function --> tests/ui/filter_map_identity.rs:67:39 | -LL | copy_vec::().into_iter().filter_map(|x: Option<_>| x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` +LL | copy_vec::().into_iter().filter_map(|x: Option<_>| return x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function --> tests/ui/filter_map_identity.rs:70:39 @@ -86,49 +92,43 @@ LL | copy_vec::().into_iter().filter_map(|x: Option<_>| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:73:39 - | -LL | copy_vec::().into_iter().filter_map(|x: Option<_>| return x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` - -error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:78:39 + --> tests/ui/filter_map_identity.rs:74:39 | LL | copy_vec::().into_iter().filter_map(|x: Option| x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:81:39 + --> tests/ui/filter_map_identity.rs:77:39 | LL | copy_vec::().into_iter().filter_map(|x: Option| x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:84:39 + --> tests/ui/filter_map_identity.rs:80:39 | LL | copy_vec::().into_iter().filter_map(|x: Option| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:87:39 + --> tests/ui/filter_map_identity.rs:83:39 | LL | copy_vec::().into_iter().filter_map(|x: Option| return x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:91:43 + --> tests/ui/filter_map_identity.rs:87:43 | LL | copy_vec::().into_iter().filter_map(|x: Option| -> Option {{ x }}); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:95:43 + --> tests/ui/filter_map_identity.rs:91:43 | LL | copy_vec::().into_iter().filter_map(|x: Option| -> Option {{ return x }}); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()` error: use of `filter_map` with an identity function - --> tests/ui/filter_map_identity.rs:101:37 + --> tests/ui/filter_map_identity.rs:96:37 | LL | opaque::().into_iter().filter_map(|x| x); | ^^^^^^^^^^^^^^^^^ help: try: `flatten()` diff --git a/tests/ui/float_arithmetic.rs b/tests/ui/float_arithmetic.rs index 3b87d2ec066d..3c447bc94c66 100644 --- a/tests/ui/float_arithmetic.rs +++ b/tests/ui/float_arithmetic.rs @@ -58,30 +58,25 @@ pub fn float_arith_ref() { &3.5_f32 + &1.3_f32; //~^ float_arithmetic - } pub fn float_foo(f: &f32) -> f32 { let a = 5.1; a + f //~^ float_arithmetic - } pub fn float_bar(f1: &f32, f2: &f32) -> f32 { f1 + f2 //~^ float_arithmetic - } pub fn float_baz(f1: f32, f2: &f32) -> f32 { f1 + f2 //~^ float_arithmetic - } pub fn float_qux(f1: f32, f2: f32) -> f32 { (&f1 + &f2) //~^ float_arithmetic - } diff --git a/tests/ui/float_arithmetic.stderr b/tests/ui/float_arithmetic.stderr index c01fdf8b46ec..8704f7bbd7c4 100644 --- a/tests/ui/float_arithmetic.stderr +++ b/tests/ui/float_arithmetic.stderr @@ -80,25 +80,25 @@ LL | &3.5_f32 + &1.3_f32; | ^^^^^^^^^^^^^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:66:5 + --> tests/ui/float_arithmetic.rs:65:5 | LL | a + f | ^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:72:5 + --> tests/ui/float_arithmetic.rs:70:5 | LL | f1 + f2 | ^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:78:5 + --> tests/ui/float_arithmetic.rs:75:5 | LL | f1 + f2 | ^^^^^^^ error: floating-point arithmetic detected - --> tests/ui/float_arithmetic.rs:84:5 + --> tests/ui/float_arithmetic.rs:80:5 | LL | (&f1 + &f2) | ^^^^^^^^^^^ diff --git a/tests/ui/float_cmp.rs b/tests/ui/float_cmp.rs index 84cf67ed4f10..ce0ffd8a2192 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -84,7 +84,6 @@ fn main() { twice(x) != twice(ONE as f64); //~^ float_cmp - x < 0.0; // no errors, lower or greater comparisons need no fuzzyness x > 0.0; x <= 0.0; @@ -106,7 +105,6 @@ fn main() { NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; //~^ float_cmp - let a1: [f32; 1] = [0.0]; let a2: [f32; 1] = [1.1]; @@ -116,7 +114,6 @@ fn main() { a1[0] == a2[0]; //~^ float_cmp - // no errors - comparing signums is ok let x32 = 3.21f32; 1.23f32.signum() == x32.signum(); diff --git a/tests/ui/float_cmp.stderr b/tests/ui/float_cmp.stderr index 1b57e15bbb97..e573c0baeac2 100644 --- a/tests/ui/float_cmp.stderr +++ b/tests/ui/float_cmp.stderr @@ -20,19 +20,19 @@ LL | twice(x) != twice(ONE as f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:106:5 + --> tests/ui/float_cmp.rs:105:5 | LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:113:5 + --> tests/ui/float_cmp.rs:111:5 | LL | a1 == a2; | ^^^^^^^^ error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:116:5 + --> tests/ui/float_cmp.rs:114:5 | LL | a1[0] == a2[0]; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin` diff --git a/tests/ui/float_cmp_const.rs b/tests/ui/float_cmp_const.rs index 86b3e5d46a06..3af53f2e84a2 100644 --- a/tests/ui/float_cmp_const.rs +++ b/tests/ui/float_cmp_const.rs @@ -28,7 +28,6 @@ fn main() { x as f32 == ONE; //~^ float_cmp_const - let v = 0.9; v == ONE; //~^ float_cmp_const @@ -36,7 +35,6 @@ fn main() { v != ONE; //~^ float_cmp_const - // no errors, lower than or greater than comparisons v < ONE; v > ONE; @@ -69,5 +67,4 @@ fn main() { // has errors NON_ZERO_ARRAY == NON_ZERO_ARRAY2; //~^ float_cmp_const - } diff --git a/tests/ui/float_cmp_const.stderr b/tests/ui/float_cmp_const.stderr index c2c7b229870a..482a55a54be6 100644 --- a/tests/ui/float_cmp_const.stderr +++ b/tests/ui/float_cmp_const.stderr @@ -32,19 +32,19 @@ LL | x as f32 == ONE; | ^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x as f32 - ONE).abs() < error_margin` error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:33:5 + --> tests/ui/float_cmp_const.rs:32:5 | LL | v == ONE; | ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() < error_margin` error: strict comparison of `f32` or `f64` constant - --> tests/ui/float_cmp_const.rs:36:5 + --> tests/ui/float_cmp_const.rs:35:5 | LL | v != ONE; | ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() > error_margin` error: strict comparison of `f32` or `f64` constant arrays - --> tests/ui/float_cmp_const.rs:70:5 + --> tests/ui/float_cmp_const.rs:68:5 | LL | NON_ZERO_ARRAY == NON_ZERO_ARRAY2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/float_equality_without_abs.rs b/tests/ui/float_equality_without_abs.rs index db0a4f492607..a1548db6710d 100644 --- a/tests/ui/float_equality_without_abs.rs +++ b/tests/ui/float_equality_without_abs.rs @@ -6,8 +6,6 @@ pub fn is_roughly_equal(a: f32, b: f32) -> bool { (a - b) < f32::EPSILON //~^ float_equality_without_abs - - } pub fn main() { @@ -31,7 +29,6 @@ pub fn main() { let _ = 1.0 - 2.0 < f32::EPSILON; //~^ float_equality_without_abs - let _ = f32::EPSILON > (a - b); //~^ float_equality_without_abs @@ -47,7 +44,6 @@ pub fn main() { let _ = f32::EPSILON > 1.0 - 2.0; //~^ float_equality_without_abs - // those are correct let _ = (a - b).abs() < f32::EPSILON; let _ = (a as f64 - b as f64).abs() < f64::EPSILON; diff --git a/tests/ui/float_equality_without_abs.stderr b/tests/ui/float_equality_without_abs.stderr index 5696ec54d765..d4c89ce72ba9 100644 --- a/tests/ui/float_equality_without_abs.stderr +++ b/tests/ui/float_equality_without_abs.stderr @@ -10,7 +10,7 @@ LL | (a - b) < f32::EPSILON = help: to override `-D warnings` add `#[allow(clippy::float_equality_without_abs)]` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:19:13 + --> tests/ui/float_equality_without_abs.rs:17:13 | LL | let _ = (a - b) < f32::EPSILON; | -------^^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | let _ = (a - b) < f32::EPSILON; | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:22:13 + --> tests/ui/float_equality_without_abs.rs:20:13 | LL | let _ = a - b < f32::EPSILON; | -----^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let _ = a - b < f32::EPSILON; | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:25:13 + --> tests/ui/float_equality_without_abs.rs:23:13 | LL | let _ = a - b.abs() < f32::EPSILON; | -----------^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = a - b.abs() < f32::EPSILON; | help: add `.abs()`: `(a - b.abs()).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:28:13 + --> tests/ui/float_equality_without_abs.rs:26:13 | LL | let _ = (a as f64 - b as f64) < f64::EPSILON; | ---------------------^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | let _ = (a as f64 - b as f64) < f64::EPSILON; | help: add `.abs()`: `(a as f64 - b as f64).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:31:13 + --> tests/ui/float_equality_without_abs.rs:29:13 | LL | let _ = 1.0 - 2.0 < f32::EPSILON; | ---------^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | let _ = 1.0 - 2.0 < f32::EPSILON; | help: add `.abs()`: `(1.0 - 2.0).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:35:13 + --> tests/ui/float_equality_without_abs.rs:32:13 | LL | let _ = f32::EPSILON > (a - b); | ^^^^^^^^^^^^^^^------- @@ -58,7 +58,7 @@ LL | let _ = f32::EPSILON > (a - b); | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:38:13 + --> tests/ui/float_equality_without_abs.rs:35:13 | LL | let _ = f32::EPSILON > a - b; | ^^^^^^^^^^^^^^^----- @@ -66,7 +66,7 @@ LL | let _ = f32::EPSILON > a - b; | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:41:13 + --> tests/ui/float_equality_without_abs.rs:38:13 | LL | let _ = f32::EPSILON > a - b.abs(); | ^^^^^^^^^^^^^^^----------- @@ -74,7 +74,7 @@ LL | let _ = f32::EPSILON > a - b.abs(); | help: add `.abs()`: `(a - b.abs()).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:44:13 + --> tests/ui/float_equality_without_abs.rs:41:13 | LL | let _ = f64::EPSILON > (a as f64 - b as f64); | ^^^^^^^^^^^^^^^--------------------- @@ -82,7 +82,7 @@ LL | let _ = f64::EPSILON > (a as f64 - b as f64); | help: add `.abs()`: `(a as f64 - b as f64).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:47:13 + --> tests/ui/float_equality_without_abs.rs:44:13 | LL | let _ = f32::EPSILON > 1.0 - 2.0; | ^^^^^^^^^^^^^^^--------- diff --git a/tests/ui/fn_to_numeric_cast_any.rs b/tests/ui/fn_to_numeric_cast_any.rs index 3359e24c2b6a..42f2128cd378 100644 --- a/tests/ui/fn_to_numeric_cast_any.rs +++ b/tests/ui/fn_to_numeric_cast_any.rs @@ -23,7 +23,6 @@ fn fn_pointer_to_integer() { let _ = foo as i8; //~^ fn_to_numeric_cast_any - let _ = foo as i16; //~^ fn_to_numeric_cast_any @@ -39,7 +38,6 @@ fn fn_pointer_to_integer() { let _ = foo as isize; //~^ fn_to_numeric_cast_any - let _ = foo as u8; //~^ fn_to_numeric_cast_any @@ -57,25 +55,21 @@ fn fn_pointer_to_integer() { let _ = foo as usize; //~^ fn_to_numeric_cast_any - } fn static_method_to_integer() { let _ = Struct::static_method as usize; //~^ fn_to_numeric_cast_any - } fn fn_with_fn_arg(f: fn(i32) -> u32) -> usize { f as usize //~^ fn_to_numeric_cast_any - } fn fn_with_generic_static_trait_method() -> usize { T::static_method as usize //~^ fn_to_numeric_cast_any - } fn closure_to_fn_to_integer() { @@ -83,13 +77,11 @@ fn closure_to_fn_to_integer() { let _ = (clos as fn(u32) -> u32) as usize; //~^ fn_to_numeric_cast_any - } fn fn_to_raw_ptr() { let _ = foo as *const (); //~^ fn_to_numeric_cast_any - } fn cast_fn_to_self() { diff --git a/tests/ui/fn_to_numeric_cast_any.stderr b/tests/ui/fn_to_numeric_cast_any.stderr index c6a7b2403395..0a98952faef1 100644 --- a/tests/ui/fn_to_numeric_cast_any.stderr +++ b/tests/ui/fn_to_numeric_cast_any.stderr @@ -12,7 +12,7 @@ LL | let _ = foo() as i8; | ~~~~~~~~~~~ error: casting function pointer `foo` to `i16` - --> tests/ui/fn_to_numeric_cast_any.rs:27:13 + --> tests/ui/fn_to_numeric_cast_any.rs:26:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = foo() as i16; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `i32` - --> tests/ui/fn_to_numeric_cast_any.rs:30:13 + --> tests/ui/fn_to_numeric_cast_any.rs:29:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = foo() as i32; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast_any.rs:33:13 + --> tests/ui/fn_to_numeric_cast_any.rs:32:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _ = foo() as i64; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast_any.rs:36:13 + --> tests/ui/fn_to_numeric_cast_any.rs:35:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _ = foo() as i128; | ~~~~~~~~~~~~~ error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast_any.rs:39:13 + --> tests/ui/fn_to_numeric_cast_any.rs:38:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let _ = foo() as isize; | ~~~~~~~~~~~~~~ error: casting function pointer `foo` to `u8` - --> tests/ui/fn_to_numeric_cast_any.rs:43:13 + --> tests/ui/fn_to_numeric_cast_any.rs:41:13 | LL | let _ = foo as u8; | ^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _ = foo() as u8; | ~~~~~~~~~~~ error: casting function pointer `foo` to `u16` - --> tests/ui/fn_to_numeric_cast_any.rs:46:13 + --> tests/ui/fn_to_numeric_cast_any.rs:44:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = foo() as u16; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `u32` - --> tests/ui/fn_to_numeric_cast_any.rs:49:13 + --> tests/ui/fn_to_numeric_cast_any.rs:47:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let _ = foo() as u32; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast_any.rs:52:13 + --> tests/ui/fn_to_numeric_cast_any.rs:50:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _ = foo() as u64; | ~~~~~~~~~~~~ error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast_any.rs:55:13 + --> tests/ui/fn_to_numeric_cast_any.rs:53:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let _ = foo() as u128; | ~~~~~~~~~~~~~ error: casting function pointer `foo` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:58:13 + --> tests/ui/fn_to_numeric_cast_any.rs:56:13 | LL | let _ = foo as usize; | ^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let _ = foo() as usize; | ~~~~~~~~~~~~~~ error: casting function pointer `Struct::static_method` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:64:13 + --> tests/ui/fn_to_numeric_cast_any.rs:61:13 | LL | let _ = Struct::static_method as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | let _ = Struct::static_method() as usize; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting function pointer `f` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:70:5 + --> tests/ui/fn_to_numeric_cast_any.rs:66:5 | LL | f as usize | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | f() as usize | error: casting function pointer `T::static_method` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:76:5 + --> tests/ui/fn_to_numeric_cast_any.rs:71:5 | LL | T::static_method as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | T::static_method() as usize | error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:84:13 + --> tests/ui/fn_to_numeric_cast_any.rs:78:13 | LL | let _ = (clos as fn(u32) -> u32) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | let _ = (clos as fn(u32) -> u32)() as usize; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting function pointer `foo` to `*const ()` - --> tests/ui/fn_to_numeric_cast_any.rs:90:13 + --> tests/ui/fn_to_numeric_cast_any.rs:83:13 | LL | let _ = foo as *const (); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/for_kv_map.fixed b/tests/ui/for_kv_map.fixed index 402098e9394b..2a68b7443fbf 100644 --- a/tests/ui/for_kv_map.fixed +++ b/tests/ui/for_kv_map.fixed @@ -7,15 +7,14 @@ use std::rc::Rc; fn main() { let m: HashMap = HashMap::new(); for v in m.values() { - //~^ for_kv_map - + //~^ for_kv_map let _v = v; } let m: Rc> = Rc::new(HashMap::new()); for v in (*m).values() { - //~^ for_kv_map + //~^ for_kv_map let _v = v; // Here the `*` is not actually necessary, but the test tests that we don't @@ -25,14 +24,14 @@ fn main() { let mut m: HashMap = HashMap::new(); for v in m.values_mut() { - //~^ for_kv_map + //~^ for_kv_map let _v = v; } let m: &mut HashMap = &mut HashMap::new(); for v in (*m).values_mut() { - //~^ for_kv_map + //~^ for_kv_map let _v = v; } @@ -40,7 +39,7 @@ fn main() { let m: HashMap = HashMap::new(); let rm = &m; for k in rm.keys() { - //~^ for_kv_map + //~^ for_kv_map let _k = k; } @@ -48,7 +47,7 @@ fn main() { let m: HashMap = HashMap::new(); let rm = &m; 'label: for k in rm.keys() { - //~^ for_kv_map + //~^ for_kv_map let _k = k; if *k == 0u64 { diff --git a/tests/ui/for_kv_map.rs b/tests/ui/for_kv_map.rs index 407590747a4b..485a97815e3c 100644 --- a/tests/ui/for_kv_map.rs +++ b/tests/ui/for_kv_map.rs @@ -7,15 +7,14 @@ use std::rc::Rc; fn main() { let m: HashMap = HashMap::new(); for (_, v) in &m { - //~^ for_kv_map - + //~^ for_kv_map let _v = v; } let m: Rc> = Rc::new(HashMap::new()); for (_, v) in &*m { - //~^ for_kv_map + //~^ for_kv_map let _v = v; // Here the `*` is not actually necessary, but the test tests that we don't @@ -25,14 +24,14 @@ fn main() { let mut m: HashMap = HashMap::new(); for (_, v) in &mut m { - //~^ for_kv_map + //~^ for_kv_map let _v = v; } let m: &mut HashMap = &mut HashMap::new(); for (_, v) in &mut *m { - //~^ for_kv_map + //~^ for_kv_map let _v = v; } @@ -40,7 +39,7 @@ fn main() { let m: HashMap = HashMap::new(); let rm = &m; for (k, _value) in rm { - //~^ for_kv_map + //~^ for_kv_map let _k = k; } @@ -48,7 +47,7 @@ fn main() { let m: HashMap = HashMap::new(); let rm = &m; 'label: for (k, _value) in rm { - //~^ for_kv_map + //~^ for_kv_map let _k = k; if *k == 0u64 { diff --git a/tests/ui/for_kv_map.stderr b/tests/ui/for_kv_map.stderr index 5c28da81a961..878c43532194 100644 --- a/tests/ui/for_kv_map.stderr +++ b/tests/ui/for_kv_map.stderr @@ -12,7 +12,7 @@ LL | for v in m.values() { | ~ ~~~~~~~~~~ error: you seem to want to iterate on a map's values - --> tests/ui/for_kv_map.rs:17:19 + --> tests/ui/for_kv_map.rs:16:19 | LL | for (_, v) in &*m { | ^^^ @@ -23,7 +23,7 @@ LL | for v in (*m).values() { | ~ ~~~~~~~~~~~~~ error: you seem to want to iterate on a map's values - --> tests/ui/for_kv_map.rs:27:19 + --> tests/ui/for_kv_map.rs:26:19 | LL | for (_, v) in &mut m { | ^^^^^^ @@ -34,7 +34,7 @@ LL | for v in m.values_mut() { | ~ ~~~~~~~~~~~~~~ error: you seem to want to iterate on a map's values - --> tests/ui/for_kv_map.rs:34:19 + --> tests/ui/for_kv_map.rs:33:19 | LL | for (_, v) in &mut *m { | ^^^^^^^ @@ -45,7 +45,7 @@ LL | for v in (*m).values_mut() { | ~ ~~~~~~~~~~~~~~~~~ error: you seem to want to iterate on a map's keys - --> tests/ui/for_kv_map.rs:42:24 + --> tests/ui/for_kv_map.rs:41:24 | LL | for (k, _value) in rm { | ^^ @@ -56,7 +56,7 @@ LL | for k in rm.keys() { | ~ ~~~~~~~~~ error: you seem to want to iterate on a map's keys - --> tests/ui/for_kv_map.rs:50:32 + --> tests/ui/for_kv_map.rs:49:32 | LL | 'label: for (k, _value) in rm { | ^^ diff --git a/tests/ui/forget_non_drop.rs b/tests/ui/forget_non_drop.rs index a69fa0f20359..0235709b1f1c 100644 --- a/tests/ui/forget_non_drop.rs +++ b/tests/ui/forget_non_drop.rs @@ -13,7 +13,6 @@ fn main() { forget(Foo); //~^ forget_non_drop - struct Bar; impl Drop for Bar { fn drop(&mut self) {} diff --git a/tests/ui/forget_non_drop.stderr b/tests/ui/forget_non_drop.stderr index 0bff152a7132..e121984154c7 100644 --- a/tests/ui/forget_non_drop.stderr +++ b/tests/ui/forget_non_drop.stderr @@ -13,13 +13,13 @@ LL | forget(Foo); = help: to override `-D warnings` add `#[allow(clippy::forget_non_drop)]` error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it - --> tests/ui/forget_non_drop.rs:26:5 + --> tests/ui/forget_non_drop.rs:25:5 | LL | forget(Baz(Foo)); | ^^^^^^^^^^^^^^^^ | note: argument has type `main::Baz` - --> tests/ui/forget_non_drop.rs:26:12 + --> tests/ui/forget_non_drop.rs:25:12 | LL | forget(Baz(Foo)); | ^^^^^^^^ diff --git a/tests/ui/format.rs b/tests/ui/format.rs index b40eb9d1eb9e..06371378f27e 100644 --- a/tests/ui/format.rs +++ b/tests/ui/format.rs @@ -24,7 +24,7 @@ fn main() { format!("{{}} abc {{}}"); //~^ useless_format format!( - //~^ useless_format + //~^ useless_format r##"foo {{}} " bar"## ); diff --git a/tests/ui/format_args.fixed b/tests/ui/format_args.fixed index 075450451b24..edfdaa23ca12 100644 --- a/tests/ui/format_args.fixed +++ b/tests/ui/format_args.fixed @@ -79,13 +79,13 @@ fn main() { let _ = write!( stdout(), "error: something failed at {}", - Location::caller() + Location::caller(), //~^ to_string_in_format_args ); let _ = writeln!( stdout(), "error: something failed at {}", - Location::caller() + Location::caller(), //~^ to_string_in_format_args ); print!("error: something failed at {}", Location::caller()); diff --git a/tests/ui/format_args.rs b/tests/ui/format_args.rs index 4d7a018732c7..367560d577dd 100644 --- a/tests/ui/format_args.rs +++ b/tests/ui/format_args.rs @@ -79,13 +79,13 @@ fn main() { let _ = write!( stdout(), "error: something failed at {}", - Location::caller().to_string() + Location::caller().to_string(), //~^ to_string_in_format_args ); let _ = writeln!( stdout(), "error: something failed at {}", - Location::caller().to_string() + Location::caller().to_string(), //~^ to_string_in_format_args ); print!("error: something failed at {}", Location::caller().to_string()); diff --git a/tests/ui/format_args.stderr b/tests/ui/format_args.stderr index 68c3c9c322d9..589c341ce859 100644 --- a/tests/ui/format_args.stderr +++ b/tests/ui/format_args.stderr @@ -10,13 +10,13 @@ LL | let _ = format!("error: something failed at {}", Location::caller().to_ error: `to_string` applied to a type that implements `Display` in `write!` args --> tests/ui/format_args.rs:82:27 | -LL | Location::caller().to_string() +LL | Location::caller().to_string(), | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `writeln!` args --> tests/ui/format_args.rs:88:27 | -LL | Location::caller().to_string() +LL | Location::caller().to_string(), | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `print!` args diff --git a/tests/ui/format_args_unfixable.rs b/tests/ui/format_args_unfixable.rs index adbdaca7313b..08cd7dbe54f7 100644 --- a/tests/ui/format_args_unfixable.rs +++ b/tests/ui/format_args_unfixable.rs @@ -48,15 +48,13 @@ fn main() { //~^ format_in_format_args let _ = write!( - //~^ format_in_format_args - + //~^ format_in_format_args stdout(), "error: {}", format!("something failed at {}", Location::caller()) ); let _ = writeln!( - //~^ format_in_format_args - + //~^ format_in_format_args stdout(), "error: {}", format!("something failed at {}", Location::caller()) @@ -85,7 +83,6 @@ fn main() { panic!("error: {}", format!("something failed at {}", Location::caller())); //~^ format_in_format_args - // negative tests println!("error: {}", format_args!("something failed at {}", Location::caller())); println!("error: {:>70}", format!("something failed at {}", Location::caller())); @@ -171,5 +168,4 @@ fn user_format() { usr_println!(true, "error: {}", format!("boom at {} {0}", Location::caller())); //~^ format_in_format_args - } diff --git a/tests/ui/format_args_unfixable.stderr b/tests/ui/format_args_unfixable.stderr index 82af72229066..1271e80b60a7 100644 --- a/tests/ui/format_args_unfixable.stderr +++ b/tests/ui/format_args_unfixable.stderr @@ -78,7 +78,6 @@ error: `format!` in `write!` args LL | let _ = write!( | _____________^ LL | | -LL | | LL | | stdout(), LL | | "error: {}", LL | | format!("something failed at {}", Location::caller()) @@ -89,12 +88,11 @@ LL | | ); = help: or consider changing `format!` to `format_args!` error: `format!` in `writeln!` args - --> tests/ui/format_args_unfixable.rs:57:13 + --> tests/ui/format_args_unfixable.rs:56:13 | LL | let _ = writeln!( | _____________^ LL | | -LL | | LL | | stdout(), LL | | "error: {}", LL | | format!("something failed at {}", Location::caller()) @@ -105,7 +103,7 @@ LL | | ); = help: or consider changing `format!` to `format_args!` error: `format!` in `print!` args - --> tests/ui/format_args_unfixable.rs:64:5 + --> tests/ui/format_args_unfixable.rs:62:5 | LL | print!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +112,7 @@ LL | print!("error: {}", format!("something failed at {}", Location::caller( = help: or consider changing `format!` to `format_args!` error: `format!` in `eprint!` args - --> tests/ui/format_args_unfixable.rs:67:5 + --> tests/ui/format_args_unfixable.rs:65:5 | LL | eprint!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,7 +121,7 @@ LL | eprint!("error: {}", format!("something failed at {}", Location::caller = help: or consider changing `format!` to `format_args!` error: `format!` in `eprintln!` args - --> tests/ui/format_args_unfixable.rs:70:5 + --> tests/ui/format_args_unfixable.rs:68:5 | LL | eprintln!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +130,7 @@ LL | eprintln!("error: {}", format!("something failed at {}", Location::call = help: or consider changing `format!` to `format_args!` error: `format!` in `format_args!` args - --> tests/ui/format_args_unfixable.rs:73:13 + --> tests/ui/format_args_unfixable.rs:71:13 | LL | let _ = format_args!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -141,7 +139,7 @@ LL | let _ = format_args!("error: {}", format!("something failed at {}", Loc = help: or consider changing `format!` to `format_args!` error: `format!` in `assert!` args - --> tests/ui/format_args_unfixable.rs:76:5 + --> tests/ui/format_args_unfixable.rs:74:5 | LL | assert!(true, "error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -150,7 +148,7 @@ LL | assert!(true, "error: {}", format!("something failed at {}", Location:: = help: or consider changing `format!` to `format_args!` error: `format!` in `assert_eq!` args - --> tests/ui/format_args_unfixable.rs:79:5 + --> tests/ui/format_args_unfixable.rs:77:5 | LL | assert_eq!(0, 0, "error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -159,7 +157,7 @@ LL | assert_eq!(0, 0, "error: {}", format!("something failed at {}", Locatio = help: or consider changing `format!` to `format_args!` error: `format!` in `assert_ne!` args - --> tests/ui/format_args_unfixable.rs:82:5 + --> tests/ui/format_args_unfixable.rs:80:5 | LL | assert_ne!(0, 0, "error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -168,7 +166,7 @@ LL | assert_ne!(0, 0, "error: {}", format!("something failed at {}", Locatio = help: or consider changing `format!` to `format_args!` error: `format!` in `panic!` args - --> tests/ui/format_args_unfixable.rs:85:5 + --> tests/ui/format_args_unfixable.rs:83:5 | LL | panic!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +175,7 @@ LL | panic!("error: {}", format!("something failed at {}", Location::caller( = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:154:5 + --> tests/ui/format_args_unfixable.rs:151:5 | LL | usr_println!(true, "error: {}", format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -186,7 +184,7 @@ LL | usr_println!(true, "error: {}", format!("boom at {}", Location::caller( = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:157:5 + --> tests/ui/format_args_unfixable.rs:154:5 | LL | usr_println!(true, "{}: {}", error, format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -195,7 +193,7 @@ LL | usr_println!(true, "{}: {}", error, format!("boom at {}", Location::cal = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:160:5 + --> tests/ui/format_args_unfixable.rs:157:5 | LL | usr_println!(true, "{:?}: {}", error, format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -204,7 +202,7 @@ LL | usr_println!(true, "{:?}: {}", error, format!("boom at {}", Location::c = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:163:5 + --> tests/ui/format_args_unfixable.rs:160:5 | LL | usr_println!(true, "{{}}: {}", format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -213,7 +211,7 @@ LL | usr_println!(true, "{{}}: {}", format!("boom at {}", Location::caller() = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:166:5 + --> tests/ui/format_args_unfixable.rs:163:5 | LL | usr_println!(true, r#"error: "{}""#, format!("boom at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -222,7 +220,7 @@ LL | usr_println!(true, r#"error: "{}""#, format!("boom at {}", Location::ca = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:169:5 + --> tests/ui/format_args_unfixable.rs:166:5 | LL | usr_println!(true, "error: {}", format!(r#"boom at "{}""#, Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +229,7 @@ LL | usr_println!(true, "error: {}", format!(r#"boom at "{}""#, Location::ca = help: or consider changing `format!` to `format_args!` error: `format!` in `usr_println!` args - --> tests/ui/format_args_unfixable.rs:172:5 + --> tests/ui/format_args_unfixable.rs:169:5 | LL | usr_println!(true, "error: {}", format!("boom at {} {0}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/format_collect.rs b/tests/ui/format_collect.rs index 85dbd5692fef..8f8633a52d86 100644 --- a/tests/ui/format_collect.rs +++ b/tests/ui/format_collect.rs @@ -4,7 +4,6 @@ fn hex_encode(bytes: &[u8]) -> String { bytes.iter().map(|b| format!("{b:02X}")).collect() //~^ format_collect - } #[rustfmt::skip] @@ -26,8 +25,7 @@ fn from_macro(bytes: &[u8]) -> String { fn with_block() -> String { (1..10) - //~^ format_collect - + //~^ format_collect .map(|s| { let y = 1; format!("{s} {y}") diff --git a/tests/ui/format_collect.stderr b/tests/ui/format_collect.stderr index a87951efa543..343e38a87b71 100644 --- a/tests/ui/format_collect.stderr +++ b/tests/ui/format_collect.stderr @@ -19,42 +19,42 @@ LL | bytes.iter().map(|b| format!("{b:02X}")).collect() = help: to override `-D warnings` add `#[allow(clippy::format_collect)]` error: use of `format!` to build up a string from an iterator - --> tests/ui/format_collect.rs:12:5 + --> tests/ui/format_collect.rs:11:5 | LL | bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: call `fold` instead - --> tests/ui/format_collect.rs:12:18 + --> tests/ui/format_collect.rs:11:18 | LL | bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect() | ^^^ help: ... and use the `write!` macro here - --> tests/ui/format_collect.rs:12:32 + --> tests/ui/format_collect.rs:11:32 | LL | bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect() | ^^^^^^^^^^^^^^^^^^ = note: this can be written more efficiently by appending to a `String` directly error: use of `format!` to build up a string from an iterator - --> tests/ui/format_collect.rs:28:5 + --> tests/ui/format_collect.rs:27:5 | LL | / (1..10) LL | | -LL | | LL | | .map(|s| { -... | +LL | | let y = 1; +LL | | format!("{s} {y}") LL | | }) LL | | .collect() | |__________________^ | help: call `fold` instead - --> tests/ui/format_collect.rs:31:10 + --> tests/ui/format_collect.rs:29:10 | LL | .map(|s| { | ^^^ help: ... and use the `write!` macro here - --> tests/ui/format_collect.rs:33:13 + --> tests/ui/format_collect.rs:31:13 | LL | format!("{s} {y}") | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/format_push_string.rs b/tests/ui/format_push_string.rs index c047118b5f50..056ef59ff0e2 100644 --- a/tests/ui/format_push_string.rs +++ b/tests/ui/format_push_string.rs @@ -7,7 +7,6 @@ fn main() { string.push_str(&format!("{:?}", 5678)); //~^ format_push_string - } mod issue9493 { @@ -15,7 +14,7 @@ mod issue9493 { let mut hex = String::with_capacity(vector.len() * 2); for byte in vector { hex += &(if upper { - //~^ format_push_string + //~^ format_push_string format!("{byte:02X}") } else { @@ -29,7 +28,7 @@ mod issue9493 { let mut s = String::new(); // if let s += &(if let Some(_a) = Some(1234) { - //~^ format_push_string + //~^ format_push_string format!("{}", 1234) } else { @@ -37,8 +36,7 @@ mod issue9493 { }); // match s += &(match Some(1234) { - //~^ format_push_string - + //~^ format_push_string Some(_) => format!("{}", 1234), None => format!("{}", 1234), }); diff --git a/tests/ui/format_push_string.stderr b/tests/ui/format_push_string.stderr index a496371938e9..bba2a8947c43 100644 --- a/tests/ui/format_push_string.stderr +++ b/tests/ui/format_push_string.stderr @@ -17,7 +17,7 @@ LL | string.push_str(&format!("{:?}", 5678)); = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:17:13 + --> tests/ui/format_push_string.rs:16:13 | LL | / hex += &(if upper { LL | | @@ -31,7 +31,7 @@ LL | | }); = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:31:9 + --> tests/ui/format_push_string.rs:30:9 | LL | / s += &(if let Some(_a) = Some(1234) { LL | | @@ -45,11 +45,10 @@ LL | | }); = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:39:9 + --> tests/ui/format_push_string.rs:38:9 | LL | / s += &(match Some(1234) { LL | | -LL | | LL | | Some(_) => format!("{}", 1234), LL | | None => format!("{}", 1234), LL | | }); diff --git a/tests/ui/from_over_into.fixed b/tests/ui/from_over_into.fixed index 85befb87fe5b..7d6780a0e02c 100644 --- a/tests/ui/from_over_into.fixed +++ b/tests/ui/from_over_into.fixed @@ -7,7 +7,7 @@ struct StringWrapper(String); impl From for StringWrapper { -//~^ from_over_into + //~^ from_over_into fn from(val: String) -> Self { StringWrapper(val) } @@ -16,7 +16,7 @@ impl From for StringWrapper { struct SelfType(String); impl From for SelfType { -//~^ from_over_into + //~^ from_over_into fn from(val: String) -> Self { SelfType(String::new()) } @@ -32,7 +32,7 @@ impl X { struct SelfKeywords; impl From for SelfKeywords { -//~^ from_over_into + //~^ from_over_into fn from(val: X) -> Self { let _ = X; let _ = X::FOO; @@ -45,7 +45,7 @@ impl From for SelfKeywords { struct ExplicitPaths(bool); impl core::convert::From for bool { -//~^ from_over_into + //~^ from_over_into fn from(mut val: crate::ExplicitPaths) -> Self { let in_closure = || val.0; @@ -66,7 +66,7 @@ impl From for A { struct PathInExpansion; impl From for String { -//~^ from_over_into + //~^ from_over_into fn from(val: PathInExpansion) -> Self { // non self/Self paths in expansions are fine panic!() @@ -89,7 +89,7 @@ fn msrv_1_41() { struct FromOverInto(Vec); impl From> for FromOverInto { - //~^ from_over_into + //~^ from_over_into fn from(val: Vec) -> Self { FromOverInto(val) } @@ -100,7 +100,7 @@ fn issue_12138() { struct Hello; impl From for () { - //~^ from_over_into + //~^ from_over_into fn from(val: Hello) {} } } diff --git a/tests/ui/from_over_into.rs b/tests/ui/from_over_into.rs index d4bdad56473a..387ddde359c1 100644 --- a/tests/ui/from_over_into.rs +++ b/tests/ui/from_over_into.rs @@ -7,7 +7,7 @@ struct StringWrapper(String); impl Into for String { -//~^ from_over_into + //~^ from_over_into fn into(self) -> StringWrapper { StringWrapper(self) } @@ -16,7 +16,7 @@ impl Into for String { struct SelfType(String); impl Into for String { -//~^ from_over_into + //~^ from_over_into fn into(self) -> SelfType { SelfType(Self::new()) } @@ -32,7 +32,7 @@ impl X { struct SelfKeywords; impl Into for X { -//~^ from_over_into + //~^ from_over_into fn into(self) -> SelfKeywords { let _ = Self; let _ = Self::FOO; @@ -45,7 +45,7 @@ impl Into for X { struct ExplicitPaths(bool); impl core::convert::Into for crate::ExplicitPaths { -//~^ from_over_into + //~^ from_over_into fn into(mut self) -> bool { let in_closure = || self.0; @@ -66,7 +66,7 @@ impl From for A { struct PathInExpansion; impl Into for PathInExpansion { -//~^ from_over_into + //~^ from_over_into fn into(self) -> String { // non self/Self paths in expansions are fine panic!() @@ -89,7 +89,7 @@ fn msrv_1_41() { struct FromOverInto(Vec); impl Into> for Vec { - //~^ from_over_into + //~^ from_over_into fn into(self) -> FromOverInto { FromOverInto(self) } @@ -100,7 +100,7 @@ fn issue_12138() { struct Hello; impl Into<()> for Hello { - //~^ from_over_into + //~^ from_over_into fn into(self) {} } } diff --git a/tests/ui/from_over_into_unfixable.rs b/tests/ui/from_over_into_unfixable.rs index 23aab9b52e1b..de90c7c21a65 100644 --- a/tests/ui/from_over_into_unfixable.rs +++ b/tests/ui/from_over_into_unfixable.rs @@ -9,7 +9,7 @@ macro_rules! in_macro { } impl Into for String { -//~^ from_over_into + //~^ from_over_into fn into(self) -> InMacro { InMacro(in_macro!()) @@ -19,7 +19,7 @@ impl Into for String { struct WeirdUpperSelf; impl Into for &'static [u8] { -//~^ from_over_into + //~^ from_over_into fn into(self) -> WeirdUpperSelf { let _ = Self::default(); @@ -30,7 +30,7 @@ impl Into for &'static [u8] { struct ContainsVal; impl Into for ContainsVal { -//~^ from_over_into + //~^ from_over_into fn into(self) -> u8 { let val = 1; @@ -43,7 +43,7 @@ pub struct Lval(T); pub struct Rval(T); impl Into> for Lval { -//~^ from_over_into + //~^ from_over_into fn into(self) -> Rval { Rval(self) diff --git a/tests/ui/from_raw_with_void_ptr.rs b/tests/ui/from_raw_with_void_ptr.rs index 840508ad340d..390313884433 100644 --- a/tests/ui/from_raw_with_void_ptr.rs +++ b/tests/ui/from_raw_with_void_ptr.rs @@ -11,7 +11,6 @@ fn main() { let _ = unsafe { Box::from_raw(ptr) }; //~^ from_raw_with_void_ptr - // shouldn't be linted let _ = unsafe { Box::from_raw(ptr as *mut usize) }; @@ -24,22 +23,18 @@ fn main() { let _ = unsafe { Rc::from_raw(ptr) }; //~^ from_raw_with_void_ptr - // must lint let ptr = Arc::into_raw(Arc::new(42usize)) as *mut c_void; let _ = unsafe { Arc::from_raw(ptr) }; //~^ from_raw_with_void_ptr - // must lint let ptr = std::rc::Weak::into_raw(Rc::downgrade(&Rc::new(42usize))) as *mut c_void; let _ = unsafe { std::rc::Weak::from_raw(ptr) }; //~^ from_raw_with_void_ptr - // must lint let ptr = std::sync::Weak::into_raw(Arc::downgrade(&Arc::new(42usize))) as *mut c_void; let _ = unsafe { std::sync::Weak::from_raw(ptr) }; //~^ from_raw_with_void_ptr - } diff --git a/tests/ui/from_raw_with_void_ptr.stderr b/tests/ui/from_raw_with_void_ptr.stderr index ab55cfd48a5b..e5bcb783d18b 100644 --- a/tests/ui/from_raw_with_void_ptr.stderr +++ b/tests/ui/from_raw_with_void_ptr.stderr @@ -13,49 +13,49 @@ LL | let _ = unsafe { Box::from_raw(ptr) }; = help: to override `-D warnings` add `#[allow(clippy::from_raw_with_void_ptr)]` error: creating a `Rc` from a void raw pointer - --> tests/ui/from_raw_with_void_ptr.rs:24:22 + --> tests/ui/from_raw_with_void_ptr.rs:23:22 | LL | let _ = unsafe { Rc::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> tests/ui/from_raw_with_void_ptr.rs:24:35 + --> tests/ui/from_raw_with_void_ptr.rs:23:35 | LL | let _ = unsafe { Rc::from_raw(ptr) }; | ^^^ error: creating a `Arc` from a void raw pointer - --> tests/ui/from_raw_with_void_ptr.rs:30:22 + --> tests/ui/from_raw_with_void_ptr.rs:28:22 | LL | let _ = unsafe { Arc::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> tests/ui/from_raw_with_void_ptr.rs:30:36 + --> tests/ui/from_raw_with_void_ptr.rs:28:36 | LL | let _ = unsafe { Arc::from_raw(ptr) }; | ^^^ error: creating a `Weak` from a void raw pointer - --> tests/ui/from_raw_with_void_ptr.rs:36:22 + --> tests/ui/from_raw_with_void_ptr.rs:33:22 | LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> tests/ui/from_raw_with_void_ptr.rs:36:46 + --> tests/ui/from_raw_with_void_ptr.rs:33:46 | LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) }; | ^^^ error: creating a `Weak` from a void raw pointer - --> tests/ui/from_raw_with_void_ptr.rs:42:22 + --> tests/ui/from_raw_with_void_ptr.rs:38:22 | LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> tests/ui/from_raw_with_void_ptr.rs:42:48 + --> tests/ui/from_raw_with_void_ptr.rs:38:48 | LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) }; | ^^^ diff --git a/tests/ui/from_str_radix_10.fixed b/tests/ui/from_str_radix_10.fixed index e9f4de518bbc..4b8fd778685e 100644 --- a/tests/ui/from_str_radix_10.fixed +++ b/tests/ui/from_str_radix_10.fixed @@ -28,7 +28,6 @@ fn main() -> Result<(), Box> { "30".parse::()?; //~^ from_str_radix_10 - "24".parse::()?; //~^ from_str_radix_10 @@ -44,17 +43,14 @@ fn main() -> Result<(), Box> { (Test + Test).parse::()?; //~^ from_str_radix_10 - let string = "300"; string.parse::()?; //~^ from_str_radix_10 - let stringier = "400".to_string(); stringier.parse::()?; //~^ from_str_radix_10 - // none of these should trigger the lint u16::from_str_radix("20", 3)?; i32::from_str_radix("45", 12)?; diff --git a/tests/ui/from_str_radix_10.rs b/tests/ui/from_str_radix_10.rs index 9ebead7f75ba..89002b11a995 100644 --- a/tests/ui/from_str_radix_10.rs +++ b/tests/ui/from_str_radix_10.rs @@ -28,7 +28,6 @@ fn main() -> Result<(), Box> { u32::from_str_radix("30", 10)?; //~^ from_str_radix_10 - i64::from_str_radix("24", 10)?; //~^ from_str_radix_10 @@ -44,17 +43,14 @@ fn main() -> Result<(), Box> { i128::from_str_radix(Test + Test, 10)?; //~^ from_str_radix_10 - let string = "300"; i32::from_str_radix(string, 10)?; //~^ from_str_radix_10 - let stringier = "400".to_string(); i32::from_str_radix(&stringier, 10)?; //~^ from_str_radix_10 - // none of these should trigger the lint u16::from_str_radix("20", 3)?; i32::from_str_radix("45", 12)?; diff --git a/tests/ui/from_str_radix_10.stderr b/tests/ui/from_str_radix_10.stderr index 7f0a12a03f3c..c693e8f50ff6 100644 --- a/tests/ui/from_str_radix_10.stderr +++ b/tests/ui/from_str_radix_10.stderr @@ -8,43 +8,43 @@ LL | u32::from_str_radix("30", 10)?; = help: to override `-D warnings` add `#[allow(clippy::from_str_radix_10)]` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:32:5 + --> tests/ui/from_str_radix_10.rs:31:5 | LL | i64::from_str_radix("24", 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"24".parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:35:5 + --> tests/ui/from_str_radix_10.rs:34:5 | LL | isize::from_str_radix("100", 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"100".parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:38:5 + --> tests/ui/from_str_radix_10.rs:37:5 | LL | u8::from_str_radix("7", 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"7".parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:41:5 + --> tests/ui/from_str_radix_10.rs:40:5 | LL | u16::from_str_radix(&("10".to_owned() + "5"), 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `("10".to_owned() + "5").parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:44:5 + --> tests/ui/from_str_radix_10.rs:43:5 | LL | i128::from_str_radix(Test + Test, 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(Test + Test).parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:49:5 + --> tests/ui/from_str_radix_10.rs:47:5 | LL | i32::from_str_radix(string, 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.parse::()` error: this call to `from_str_radix` can be replaced with a call to `str::parse` - --> tests/ui/from_str_radix_10.rs:54:5 + --> tests/ui/from_str_radix_10.rs:51:5 | LL | i32::from_str_radix(&stringier, 10)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `stringier.parse::()` diff --git a/tests/ui/functions.rs b/tests/ui/functions.rs index 9114dd96ce4d..9c1ca8bf9300 100644 --- a/tests/ui/functions.rs +++ b/tests/ui/functions.rs @@ -8,8 +8,6 @@ fn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} //~^ too_many_arguments - - #[rustfmt::skip] fn bad_multiline( //~^ too_many_arguments @@ -50,7 +48,6 @@ pub trait Foo { fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()); //~^ too_many_arguments - fn ptr(p: *const u8); } @@ -60,7 +57,6 @@ impl Bar { fn good_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {} fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} //~^ too_many_arguments - } // ok, we don’t want to warn implementations @@ -72,13 +68,11 @@ impl Foo for Bar { println!("{}", unsafe { *p }); //~^ not_unsafe_ptr_arg_deref - println!("{:?}", unsafe { p.as_ref() }); //~^ not_unsafe_ptr_arg_deref unsafe { std::ptr::read(p) }; //~^ not_unsafe_ptr_arg_deref - } } @@ -97,7 +91,6 @@ pub fn public(p: *const u8) { unsafe { std::ptr::read(p) }; //~^ not_unsafe_ptr_arg_deref - } type Alias = *const u8; @@ -111,7 +104,6 @@ pub fn type_alias(p: Alias) { unsafe { std::ptr::read(p) }; //~^ not_unsafe_ptr_arg_deref - } impl Bar { @@ -128,7 +120,6 @@ impl Bar { unsafe { std::ptr::read(p) }; //~^ not_unsafe_ptr_arg_deref - } pub fn public_ok(self, p: *const u8) { diff --git a/tests/ui/functions.stderr b/tests/ui/functions.stderr index 4e3cf2edb085..c8770023f77a 100644 --- a/tests/ui/functions.stderr +++ b/tests/ui/functions.stderr @@ -8,7 +8,7 @@ LL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]` error: this function has too many arguments (8/7) - --> tests/ui/functions.rs:14:1 + --> tests/ui/functions.rs:12:1 | LL | / fn bad_multiline( LL | | @@ -20,19 +20,19 @@ LL | | ) { | |_^ error: this function has too many arguments (8/7) - --> tests/ui/functions.rs:50:5 + --> tests/ui/functions.rs:48:5 | LL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this function has too many arguments (8/7) - --> tests/ui/functions.rs:61:5 + --> tests/ui/functions.rs:58:5 | LL | fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:72:34 + --> tests/ui/functions.rs:68:34 | LL | println!("{}", unsafe { *p }); | ^ @@ -41,67 +41,67 @@ LL | println!("{}", unsafe { *p }); = help: to override `-D warnings` add `#[allow(clippy::not_unsafe_ptr_arg_deref)]` error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:76:35 + --> tests/ui/functions.rs:71:35 | LL | println!("{:?}", unsafe { p.as_ref() }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:79:33 + --> tests/ui/functions.rs:74:33 | LL | unsafe { std::ptr::read(p) }; | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:92:30 + --> tests/ui/functions.rs:86:30 | LL | println!("{}", unsafe { *p }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:95:31 + --> tests/ui/functions.rs:89:31 | LL | println!("{:?}", unsafe { p.as_ref() }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:98:29 + --> tests/ui/functions.rs:92:29 | LL | unsafe { std::ptr::read(p) }; | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:106:30 + --> tests/ui/functions.rs:99:30 | LL | println!("{}", unsafe { *p }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:109:31 + --> tests/ui/functions.rs:102:31 | LL | println!("{:?}", unsafe { p.as_ref() }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:112:29 + --> tests/ui/functions.rs:105:29 | LL | unsafe { std::ptr::read(p) }; | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:123:34 + --> tests/ui/functions.rs:115:34 | LL | println!("{}", unsafe { *p }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:126:35 + --> tests/ui/functions.rs:118:35 | LL | println!("{:?}", unsafe { p.as_ref() }); | ^ error: this public function might dereference a raw pointer but is not marked `unsafe` - --> tests/ui/functions.rs:129:33 + --> tests/ui/functions.rs:121:33 | LL | unsafe { std::ptr::read(p) }; | ^ diff --git a/tests/ui/functions_maxlines.rs b/tests/ui/functions_maxlines.rs index 3c32e88c6880..e0990dadaaa9 100644 --- a/tests/ui/functions_maxlines.rs +++ b/tests/ui/functions_maxlines.rs @@ -56,8 +56,7 @@ fn good_lines() { } fn bad_lines() { -//~^ too_many_lines - + //~^ too_many_lines println!("Dont get confused by braces: {{}}"); println!("This is bad."); diff --git a/tests/ui/functions_maxlines.stderr b/tests/ui/functions_maxlines.stderr index 82d5fc8d5859..f42a2b2a22a2 100644 --- a/tests/ui/functions_maxlines.stderr +++ b/tests/ui/functions_maxlines.stderr @@ -2,6 +2,9 @@ error: this function has too many lines (102/100) --> tests/ui/functions_maxlines.rs:58:1 | LL | / fn bad_lines() { +LL | | +LL | | +LL | | println!("Dont get confused by braces: {{}}"); ... | LL | | println!("This is bad."); LL | | } diff --git a/tests/ui/future_not_send.rs b/tests/ui/future_not_send.rs index 1df0b1334827..662ecb9c955d 100644 --- a/tests/ui/future_not_send.rs +++ b/tests/ui/future_not_send.rs @@ -6,13 +6,13 @@ use std::rc::Rc; use std::sync::Arc; async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { -//~^ future_not_send + //~^ future_not_send async { true }.await } pub async fn public_future(rc: Rc<[u8]>) { -//~^ future_not_send + //~^ future_not_send async { true }.await; } @@ -22,7 +22,7 @@ pub async fn public_send(arc: Arc<[u8]>) -> bool { } async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { -//~^ future_not_send + //~^ future_not_send true } @@ -30,7 +30,6 @@ async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { pub async fn public_future2(rc: Rc<[u8]>) {} //~^ future_not_send - pub async fn public_send2(arc: Arc<[u8]>) -> bool { false } @@ -41,14 +40,14 @@ struct Dummy { impl Dummy { async fn private_future(&self) -> usize { - //~^ future_not_send + //~^ future_not_send async { true }.await; self.rc.len() } pub async fn public_future(&self) { - //~^ future_not_send + //~^ future_not_send self.private_future().await; } @@ -61,7 +60,6 @@ impl Dummy { async fn generic_future(t: T) -> T //~^ future_not_send - where T: Send, { @@ -83,7 +81,7 @@ async fn maybe_send_generic_future2 Fut, Fut: Future>(f: F) { } async fn generic_future_always_unsend(_: Rc) { -//~^ future_not_send + //~^ future_not_send async { true }.await; } diff --git a/tests/ui/future_not_send.stderr b/tests/ui/future_not_send.stderr index 4dcff55942a6..e366dc2d2195 100644 --- a/tests/ui/future_not_send.stderr +++ b/tests/ui/future_not_send.stderr @@ -71,13 +71,13 @@ LL | pub async fn public_future2(rc: Rc<[u8]>) {} = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:43:5 + --> tests/ui/future_not_send.rs:42:5 | LL | async fn private_future(&self) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:46:24 + --> tests/ui/future_not_send.rs:45:24 | LL | async fn private_future(&self) -> usize { | ----- has type `&Dummy` which is not `Send` @@ -87,30 +87,29 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:50:5 + --> tests/ui/future_not_send.rs:49:5 | LL | pub async fn public_future(&self) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` | note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` - --> tests/ui/future_not_send.rs:50:32 + --> tests/ui/future_not_send.rs:49:32 | LL | pub async fn public_future(&self) { | ^^^^^ has type `&Dummy` which is not `Send`, because `Dummy` is not `Sync` = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:62:1 + --> tests/ui/future_not_send.rs:61:1 | LL | / async fn generic_future(t: T) -> T LL | | -LL | | LL | | where LL | | T: Send, | |____________^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:69:20 + --> tests/ui/future_not_send.rs:67:20 | LL | let rt = &t; | -- has type `&T` which is not `Send` @@ -119,13 +118,13 @@ LL | async { true }.await; = note: `T` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:85:1 + --> tests/ui/future_not_send.rs:83:1 | LL | async fn generic_future_always_unsend(_: Rc) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `generic_future_always_unsend` is not `Send` | note: future is not `Send` as this value is used across an await - --> tests/ui/future_not_send.rs:88:20 + --> tests/ui/future_not_send.rs:86:20 | LL | async fn generic_future_always_unsend(_: Rc) { | - has type `std::rc::Rc` which is not `Send` diff --git a/tests/ui/get_first.fixed b/tests/ui/get_first.fixed index 090fe48096ae..584080defa1e 100644 --- a/tests/ui/get_first.fixed +++ b/tests/ui/get_first.fixed @@ -51,5 +51,4 @@ fn main() { let non_primitives = [vec![1, 2], vec![3, 4]]; let _ = non_primitives.first(); //~^ get_first - } diff --git a/tests/ui/get_first.rs b/tests/ui/get_first.rs index c85d5aa89ca2..f01fbdf43c6d 100644 --- a/tests/ui/get_first.rs +++ b/tests/ui/get_first.rs @@ -51,5 +51,4 @@ fn main() { let non_primitives = [vec![1, 2], vec![3, 4]]; let _ = non_primitives.get(0); //~^ get_first - } diff --git a/tests/ui/identity_op.fixed b/tests/ui/identity_op.fixed index b3836bda2b6f..a1b556029987 100644 --- a/tests/ui/identity_op.fixed +++ b/tests/ui/identity_op.fixed @@ -217,7 +217,6 @@ fn issue_12050() { let _: i32 = *x; //~^ identity_op - } { let x = &&0i32; @@ -227,7 +226,6 @@ fn issue_12050() { let x = &&0i32; let _: i32 = **x; //~^ identity_op - } { // this is just silly @@ -250,7 +248,6 @@ fn issue_12050() { let _: i32 = **&&*&x; //~^ identity_op - } { // this is getting ridiculous, but we should still see the same @@ -261,7 +258,6 @@ fn issue_12050() { let _: i32 = ***&&*&x; //~^ identity_op - } } @@ -284,7 +280,6 @@ fn issue_13470() { let _: u64 = 5u64 + ((x + y)) as u64; //~^ identity_op - // If we don't maintain the parens here, the behavior changes let _ = -(x + y); //~^ identity_op @@ -312,10 +307,8 @@ fn issue_13470() { let _ = 2i32 + (x * y); //~^ identity_op - let x = 1i16; let y = 1i16; let _: u64 = 1u64 + ((x as i32 + y as i32) as u64); //~^ identity_op - } diff --git a/tests/ui/identity_op.rs b/tests/ui/identity_op.rs index 9d545a95bdd3..f603e1078e4e 100644 --- a/tests/ui/identity_op.rs +++ b/tests/ui/identity_op.rs @@ -217,7 +217,6 @@ fn issue_12050() { let _: i32 = x + 0; //~^ identity_op - } { let x = &&0i32; @@ -227,7 +226,6 @@ fn issue_12050() { let x = &&0i32; let _: i32 = *x + 0; //~^ identity_op - } { // this is just silly @@ -250,7 +248,6 @@ fn issue_12050() { let _: i32 = **&&*&x + 0; //~^ identity_op - } { // this is getting ridiculous, but we should still see the same @@ -261,7 +258,6 @@ fn issue_12050() { let _: i32 = **&&*&x + 0; //~^ identity_op - } } @@ -284,7 +280,6 @@ fn issue_13470() { let _: u64 = 5u64 + ((x + y) + 0i32) as u64; //~^ identity_op - // If we don't maintain the parens here, the behavior changes let _ = -(x + y + 0i32); //~^ identity_op @@ -312,10 +307,8 @@ fn issue_13470() { let _ = 2i32 + (x * y * 1i32); //~^ identity_op - let x = 1i16; let y = 1i16; let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64); //~^ identity_op - } diff --git a/tests/ui/identity_op.stderr b/tests/ui/identity_op.stderr index 8952f2fb7b8b..8f9c2b603c49 100644 --- a/tests/ui/identity_op.stderr +++ b/tests/ui/identity_op.stderr @@ -254,53 +254,59 @@ LL | let _: i32 = x + 0; | ^^^^^ help: consider reducing it to: `*x` error: this operation has no effect - --> tests/ui/identity_op.rs:224:22 + --> tests/ui/identity_op.rs:223:22 | LL | let _: i32 = **x + 0; | ^^^^^^^ help: consider reducing it to: `**x` error: this operation has no effect - --> tests/ui/identity_op.rs:228:22 + --> tests/ui/identity_op.rs:227:22 | LL | let _: i32 = *x + 0; | ^^^^^^ help: consider reducing it to: `**x` error: this operation has no effect - --> tests/ui/identity_op.rs:235:22 + --> tests/ui/identity_op.rs:233:22 | LL | let _: i32 = ***x + 0; | ^^^^^^^^ help: consider reducing it to: `***x` error: this operation has no effect - --> tests/ui/identity_op.rs:238:22 + --> tests/ui/identity_op.rs:236:22 | LL | let _: i32 = **x + 0; | ^^^^^^^ help: consider reducing it to: `***x` error: this operation has no effect - --> tests/ui/identity_op.rs:242:22 + --> tests/ui/identity_op.rs:240:22 | LL | let _: i32 = *&x + 0; | ^^^^^^^ help: consider reducing it to: `*&x` error: this operation has no effect - --> tests/ui/identity_op.rs:245:22 + --> tests/ui/identity_op.rs:243:22 | LL | let _: i32 = **&&x + 0; | ^^^^^^^^^ help: consider reducing it to: `**&&x` error: this operation has no effect - --> tests/ui/identity_op.rs:248:22 + --> tests/ui/identity_op.rs:246:22 | LL | let _: i32 = *&*&x + 0; | ^^^^^^^^^ help: consider reducing it to: `*&*&x` error: this operation has no effect - --> tests/ui/identity_op.rs:251:22 + --> tests/ui/identity_op.rs:249:22 | LL | let _: i32 = **&&*&x + 0; | ^^^^^^^^^^^ help: consider reducing it to: `**&&*&x` +error: this operation has no effect + --> tests/ui/identity_op.rs:256:22 + | +LL | let _: i32 = **&&*&x + 0; + | ^^^^^^^^^^^ help: consider reducing it to: `***&&*&x` + error: this operation has no effect --> tests/ui/identity_op.rs:259:22 | @@ -308,73 +314,67 @@ LL | let _: i32 = **&&*&x + 0; | ^^^^^^^^^^^ help: consider reducing it to: `***&&*&x` error: this operation has no effect - --> tests/ui/identity_op.rs:262:22 - | -LL | let _: i32 = **&&*&x + 0; - | ^^^^^^^^^^^ help: consider reducing it to: `***&&*&x` - -error: this operation has no effect - --> tests/ui/identity_op.rs:272:18 + --> tests/ui/identity_op.rs:268:18 | LL | let _: u64 = (x + y + 0i32) as u64; | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)` error: this operation has no effect - --> tests/ui/identity_op.rs:276:25 + --> tests/ui/identity_op.rs:272:25 | LL | let _: u64 = 1u64 & (x + y + 0i32) as u64; | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)` error: this operation has no effect - --> tests/ui/identity_op.rs:280:25 + --> tests/ui/identity_op.rs:276:25 | LL | let _: u64 = 1u64 & ((x + y) + 0i32) as u64; | ^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x + y))` error: this operation has no effect - --> tests/ui/identity_op.rs:284:25 + --> tests/ui/identity_op.rs:280:25 | LL | let _: u64 = 5u64 + ((x + y) + 0i32) as u64; | ^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x + y))` error: this operation has no effect - --> tests/ui/identity_op.rs:289:14 + --> tests/ui/identity_op.rs:284:14 | LL | let _ = -(x + y + 0i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)` error: this operation has no effect - --> tests/ui/identity_op.rs:293:14 + --> tests/ui/identity_op.rs:288:14 | LL | let _ = -(x / y / 1i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x / y)` error: this operation has no effect - --> tests/ui/identity_op.rs:297:20 + --> tests/ui/identity_op.rs:292:20 | LL | let _ = 2i32 * (x + y + 0i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)` error: this operation has no effect - --> tests/ui/identity_op.rs:302:20 + --> tests/ui/identity_op.rs:297:20 | LL | let _ = 2i32 - (x - y - 0i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x - y)` error: this operation has no effect - --> tests/ui/identity_op.rs:307:17 + --> tests/ui/identity_op.rs:302:17 | LL | let _ = 2 + (x + (y * z) + 0); | ^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(x + (y * z))` error: this operation has no effect - --> tests/ui/identity_op.rs:312:20 + --> tests/ui/identity_op.rs:307:20 | LL | let _ = 2i32 + (x * y * 1i32); | ^^^^^^^^^^^^^^ help: consider reducing it to: `(x * y)` error: this operation has no effect - --> tests/ui/identity_op.rs:318:25 + --> tests/ui/identity_op.rs:312:25 | LL | let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x as i32 + y as i32) as u64)` diff --git a/tests/ui/if_not_else.fixed b/tests/ui/if_not_else.fixed index 1b58bdda5217..d26a15156cd8 100644 --- a/tests/ui/if_not_else.fixed +++ b/tests/ui/if_not_else.fixed @@ -12,14 +12,14 @@ fn main() { if bla() { println!("Bunny"); } else { - //~^ if_not_else + //~^ if_not_else println!("Bugs"); } if 4 == 5 { println!("Bunny"); } else { - //~^ if_not_else + //~^ if_not_else println!("Bugs"); } @@ -34,7 +34,7 @@ fn main() { if (foo() && bla()) { println!("both true"); } else { - //~^ if_not_else + //~^ if_not_else #[cfg(not(debug_assertions))] println!("not debug"); #[cfg(debug_assertions)] @@ -53,7 +53,7 @@ fn with_comments() { if foo() { println!("foo"); /* foo */ } else { - //~^ if_not_else + //~^ if_not_else /* foo is false */ println!("foo is false"); } @@ -61,7 +61,7 @@ fn with_comments() { if bla() { println!("bla"); // bla } else { - //~^ if_not_else + //~^ if_not_else // bla is false println!("bla"); } @@ -72,7 +72,7 @@ fn with_annotations() { if foo() { println!("foo"); /* foo */ } else { - //~^ if_not_else + //~^ if_not_else /* foo is false */ println!("foo is false"); } diff --git a/tests/ui/if_not_else.rs b/tests/ui/if_not_else.rs index 0d035e283774..6171cf116495 100644 --- a/tests/ui/if_not_else.rs +++ b/tests/ui/if_not_else.rs @@ -10,14 +10,14 @@ fn bla() -> bool { fn main() { if !bla() { - //~^ if_not_else + //~^ if_not_else println!("Bugs"); } else { println!("Bunny"); } if 4 != 5 { - //~^ if_not_else + //~^ if_not_else println!("Bugs"); } else { @@ -32,7 +32,7 @@ fn main() { } if !(foo() && bla()) { - //~^ if_not_else + //~^ if_not_else #[cfg(not(debug_assertions))] println!("not debug"); #[cfg(debug_assertions)] @@ -51,7 +51,7 @@ fn main() { fn with_comments() { if !foo() { - //~^ if_not_else + //~^ if_not_else /* foo is false */ println!("foo is false"); } else { @@ -59,7 +59,7 @@ fn with_comments() { } if !bla() { - //~^ if_not_else + //~^ if_not_else // bla is false println!("bla"); } else { @@ -70,7 +70,7 @@ fn with_comments() { fn with_annotations() { #[cfg(debug_assertions)] if !foo() { - //~^ if_not_else + //~^ if_not_else /* foo is false */ println!("foo is false"); } else { diff --git a/tests/ui/if_same_then_else.rs b/tests/ui/if_same_then_else.rs index 5eaf4015b77b..6d2e63e7299a 100644 --- a/tests/ui/if_same_then_else.rs +++ b/tests/ui/if_same_then_else.rs @@ -39,7 +39,6 @@ fn if_same_then_else() { } //~^^^^^^^^^^^^^^^^^ if_same_then_else - if true { Foo { bar: 42 }; } else { @@ -68,11 +67,9 @@ fn if_same_then_else() { let _ = if true { 0.0 } else { 0.0 }; //~^ if_same_then_else - let _ = if true { -0.0 } else { -0.0 }; //~^ if_same_then_else - let _ = if true { 0.0 } else { -0.0 }; // Different NaNs @@ -85,7 +82,6 @@ fn if_same_then_else() { let _ = if true { 42 } else { 42 }; //~^ if_same_then_else - if true { let bar = if true { 42 } else { 43 }; @@ -103,7 +99,6 @@ fn if_same_then_else() { } //~^^^^^^^^^^^^^^^ if_same_then_else - if true { let _ = match 42 { 42 => 1, diff --git a/tests/ui/if_same_then_else.stderr b/tests/ui/if_same_then_else.stderr index e715dbfa2258..b76da3fb1cb5 100644 --- a/tests/ui/if_same_then_else.stderr +++ b/tests/ui/if_same_then_else.stderr @@ -27,43 +27,43 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]` error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:68:21 + --> tests/ui/if_same_then_else.rs:67:21 | LL | let _ = if true { 0.0 } else { 0.0 }; | ^^^^^^^ | note: same as this - --> tests/ui/if_same_then_else.rs:68:34 + --> tests/ui/if_same_then_else.rs:67:34 | LL | let _ = if true { 0.0 } else { 0.0 }; | ^^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:72:21 + --> tests/ui/if_same_then_else.rs:70:21 | LL | let _ = if true { -0.0 } else { -0.0 }; | ^^^^^^^^ | note: same as this - --> tests/ui/if_same_then_else.rs:72:35 + --> tests/ui/if_same_then_else.rs:70:35 | LL | let _ = if true { -0.0 } else { -0.0 }; | ^^^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:85:21 + --> tests/ui/if_same_then_else.rs:82:21 | LL | let _ = if true { 42 } else { 42 }; | ^^^^^^ | note: same as this - --> tests/ui/if_same_then_else.rs:85:33 + --> tests/ui/if_same_then_else.rs:82:33 | LL | let _ = if true { 42 } else { 42 }; | ^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:89:13 + --> tests/ui/if_same_then_else.rs:85:13 | LL | if true { | _____________^ @@ -76,7 +76,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else.rs:96:12 + --> tests/ui/if_same_then_else.rs:92:12 | LL | } else { | ____________^ @@ -89,7 +89,7 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:243:14 + --> tests/ui/if_same_then_else.rs:238:14 | LL | if x { | ______________^ @@ -98,7 +98,7 @@ LL | | } else { | |_________^ | note: same as this - --> tests/ui/if_same_then_else.rs:245:16 + --> tests/ui/if_same_then_else.rs:240:16 | LL | } else { | ________________^ diff --git a/tests/ui/if_same_then_else2.rs b/tests/ui/if_same_then_else2.rs index 2ccd85224cd3..5b74aecdacbe 100644 --- a/tests/ui/if_same_then_else2.rs +++ b/tests/ui/if_same_then_else2.rs @@ -33,7 +33,6 @@ fn if_same_then_else2() -> Result<&'static str, ()> { } //~^^^^^^^^^^^^^^^^^^^ if_same_then_else - if true { if let Some(a) = Some(42) {} } else { @@ -41,7 +40,6 @@ fn if_same_then_else2() -> Result<&'static str, ()> { } //~^^^^^ if_same_then_else - if true { if let (1, .., 3) = (1, 2, 3) {} } else { @@ -49,7 +47,6 @@ fn if_same_then_else2() -> Result<&'static str, ()> { } //~^^^^^ if_same_then_else - if true { if let (1, .., 3) = (1, 2, 3) {} } else { @@ -96,7 +93,6 @@ fn if_same_then_else2() -> Result<&'static str, ()> { let _ = if true { f32::NAN } else { f32::NAN }; //~^ if_same_then_else - if true { Ok("foo")?; } else { @@ -104,7 +100,6 @@ fn if_same_then_else2() -> Result<&'static str, ()> { } //~^^^^^ if_same_then_else - if true { let foo = ""; return Ok(&foo[0..]); @@ -131,7 +126,6 @@ fn if_same_then_else2() -> Result<&'static str, ()> { } //~^^^^^^^ if_same_then_else - // False positive `if_same_then_else`: `let (x, y)` vs. `let (y, x)`; see issue #3559. if true { let foo = ""; diff --git a/tests/ui/if_same_then_else2.stderr b/tests/ui/if_same_then_else2.stderr index 3465482f9872..369d6f667372 100644 --- a/tests/ui/if_same_then_else2.stderr +++ b/tests/ui/if_same_then_else2.stderr @@ -25,7 +25,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]` error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:37:13 + --> tests/ui/if_same_then_else2.rs:36:13 | LL | if true { | _____________^ @@ -34,7 +34,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else2.rs:39:12 + --> tests/ui/if_same_then_else2.rs:38:12 | LL | } else { | ____________^ @@ -43,7 +43,7 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:45:13 + --> tests/ui/if_same_then_else2.rs:43:13 | LL | if true { | _____________^ @@ -52,7 +52,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else2.rs:47:12 + --> tests/ui/if_same_then_else2.rs:45:12 | LL | } else { | ____________^ @@ -61,19 +61,19 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:96:21 + --> tests/ui/if_same_then_else2.rs:93:21 | LL | let _ = if true { f32::NAN } else { f32::NAN }; | ^^^^^^^^^^^^ | note: same as this - --> tests/ui/if_same_then_else2.rs:96:39 + --> tests/ui/if_same_then_else2.rs:93:39 | LL | let _ = if true { f32::NAN } else { f32::NAN }; | ^^^^^^^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:100:13 + --> tests/ui/if_same_then_else2.rs:96:13 | LL | if true { | _____________^ @@ -82,7 +82,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else2.rs:102:12 + --> tests/ui/if_same_then_else2.rs:98:12 | LL | } else { | ____________^ @@ -91,7 +91,7 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else2.rs:125:20 + --> tests/ui/if_same_then_else2.rs:120:20 | LL | } else if true { | ____________________^ @@ -101,7 +101,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else2.rs:128:12 + --> tests/ui/if_same_then_else2.rs:123:12 | LL | } else { | ____________^ diff --git a/tests/ui/if_then_some_else_none.fixed b/tests/ui/if_then_some_else_none.fixed index 1f9ea9bf9bc0..f774608712d1 100644 --- a/tests/ui/if_then_some_else_none.fixed +++ b/tests/ui/if_then_some_else_none.fixed @@ -13,13 +13,11 @@ fn main() { let _ = x.and_then(|o| (o < 32).then_some(o)); //~^ if_then_some_else_none - // Should issue an error. Unary expression `!x` should be parenthesized. let x = true; let _ = (!x).then_some(0); //~^ if_then_some_else_none - // Should not issue an error since the `else` block has a statement besides `None`. let _ = if foo() { println!("true!"); diff --git a/tests/ui/if_then_some_else_none.rs b/tests/ui/if_then_some_else_none.rs index 238d524a5522..8b8ff0a6ea00 100644 --- a/tests/ui/if_then_some_else_none.rs +++ b/tests/ui/if_then_some_else_none.rs @@ -4,7 +4,7 @@ fn main() { // Should issue an error. let _ = if foo() { - //~^ if_then_some_else_none + //~^ if_then_some_else_none println!("true!"); Some("foo") @@ -14,7 +14,7 @@ fn main() { // Should issue an error when macros are used. let _ = if matches!(true, true) { - //~^ if_then_some_else_none + //~^ if_then_some_else_none println!("true!"); Some(matches!(true, false)) @@ -27,13 +27,11 @@ fn main() { let _ = x.and_then(|o| if o < 32 { Some(o) } else { None }); //~^ if_then_some_else_none - // Should issue an error. Unary expression `!x` should be parenthesized. let x = true; let _ = if !x { Some(0) } else { None }; //~^ if_then_some_else_none - // Should not issue an error since the `else` block has a statement besides `None`. let _ = if foo() { println!("true!"); @@ -88,7 +86,7 @@ fn _msrv_1_49() { #[clippy::msrv = "1.50"] fn _msrv_1_50() { let _ = if foo() { - //~^ if_then_some_else_none + //~^ if_then_some_else_none println!("true!"); Some(150) diff --git a/tests/ui/if_then_some_else_none.stderr b/tests/ui/if_then_some_else_none.stderr index a996dec236d6..71285574ef24 100644 --- a/tests/ui/if_then_some_else_none.stderr +++ b/tests/ui/if_then_some_else_none.stderr @@ -34,13 +34,13 @@ LL | let _ = x.and_then(|o| if o < 32 { Some(o) } else { None }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(o < 32).then_some(o)` error: this could be simplified with `bool::then_some` - --> tests/ui/if_then_some_else_none.rs:33:13 + --> tests/ui/if_then_some_else_none.rs:32:13 | LL | let _ = if !x { Some(0) } else { None }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(!x).then_some(0)` error: this could be simplified with `bool::then` - --> tests/ui/if_then_some_else_none.rs:90:13 + --> tests/ui/if_then_some_else_none.rs:88:13 | LL | let _ = if foo() { | _____________^ @@ -53,7 +53,7 @@ LL | | }; | |_____^ help: try: `foo().then(|| { println!("true!"); 150 })` error: this could be simplified with `bool::then` - --> tests/ui/if_then_some_else_none.rs:140:5 + --> tests/ui/if_then_some_else_none.rs:138:5 | LL | if s == "1" { Some(true) } else { None } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(s == "1").then(|| true)` diff --git a/tests/ui/ifs_same_cond.rs b/tests/ui/ifs_same_cond.rs index 202b164d03ba..6ecb7cb1eba9 100644 --- a/tests/ui/ifs_same_cond.rs +++ b/tests/ui/ifs_same_cond.rs @@ -12,21 +12,18 @@ fn ifs_same_cond() { if b { } else if b { - //~^ ifs_same_cond - + //~^ ifs_same_cond } if a == 1 { } else if a == 1 { - //~^ ifs_same_cond - + //~^ ifs_same_cond } if 2 * a == 1 { } else if 2 * a == 2 { } else if 2 * a == 1 { - //~^ ifs_same_cond - + //~^ ifs_same_cond } else if a == 1 { } @@ -59,7 +56,7 @@ fn issue10272() { let a = String::from("ha"); if a.contains("ah") { } else if a.contains("ah") { - //~^ ifs_same_cond + //~^ ifs_same_cond // Trigger this lint } else if a.contains("ha") { diff --git a/tests/ui/ifs_same_cond.stderr b/tests/ui/ifs_same_cond.stderr index a45e01d26227..81fbb921e846 100644 --- a/tests/ui/ifs_same_cond.stderr +++ b/tests/ui/ifs_same_cond.stderr @@ -13,37 +13,37 @@ LL | if b { = help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]` error: this `if` has the same condition as a previous `if` - --> tests/ui/ifs_same_cond.rs:20:15 + --> tests/ui/ifs_same_cond.rs:19:15 | LL | } else if a == 1 { | ^^^^^^ | note: same as this - --> tests/ui/ifs_same_cond.rs:19:8 + --> tests/ui/ifs_same_cond.rs:18:8 | LL | if a == 1 { | ^^^^^^ error: this `if` has the same condition as a previous `if` - --> tests/ui/ifs_same_cond.rs:27:15 + --> tests/ui/ifs_same_cond.rs:25:15 | LL | } else if 2 * a == 1 { | ^^^^^^^^^^ | note: same as this - --> tests/ui/ifs_same_cond.rs:25:8 + --> tests/ui/ifs_same_cond.rs:23:8 | LL | if 2 * a == 1 { | ^^^^^^^^^^ error: this `if` has the same condition as a previous `if` - --> tests/ui/ifs_same_cond.rs:61:15 + --> tests/ui/ifs_same_cond.rs:58:15 | LL | } else if a.contains("ah") { | ^^^^^^^^^^^^^^^^ | note: same as this - --> tests/ui/ifs_same_cond.rs:60:8 + --> tests/ui/ifs_same_cond.rs:57:8 | LL | if a.contains("ah") { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl.rs b/tests/ui/impl.rs index 423c8d501741..1b9e4a5cdee1 100644 --- a/tests/ui/impl.rs +++ b/tests/ui/impl.rs @@ -8,7 +8,7 @@ impl MyStruct { } impl MyStruct { -//~^ multiple_inherent_impl + //~^ multiple_inherent_impl fn second() {} } @@ -24,7 +24,7 @@ mod submod { } impl super::MyStruct { - //~^ multiple_inherent_impl + //~^ multiple_inherent_impl fn third() {} } @@ -46,7 +46,7 @@ impl WithArgs { fn f2() {} } impl WithArgs { -//~^ multiple_inherent_impl + //~^ multiple_inherent_impl fn f3() {} } @@ -71,5 +71,4 @@ impl OneAllowedImpl {} impl OneAllowedImpl {} // Lint, only one of the three blocks is allowed. //~^ multiple_inherent_impl - fn main() {} diff --git a/tests/ui/impl_trait_in_params.rs b/tests/ui/impl_trait_in_params.rs index 6d502a685bf7..2039f6339a87 100644 --- a/tests/ui/impl_trait_in_params.rs +++ b/tests/ui/impl_trait_in_params.rs @@ -12,7 +12,6 @@ pub fn a(_: impl Trait) {} pub fn c(_: C, _: impl Trait) {} //~^ impl_trait_in_params - // Shouldn't warn pub fn b(_: B) {} @@ -35,12 +34,12 @@ trait Private { struct S; impl S { -pub fn h(_: impl Trait) {} -//~^ impl_trait_in_params + pub fn h(_: impl Trait) {} + //~^ impl_trait_in_params fn i(_: impl Trait) {} pub fn j(_: J) {} -pub fn k>(_: K, _: impl AnotherTrait) {} -//~^ impl_trait_in_params + pub fn k>(_: K, _: impl AnotherTrait) {} + //~^ impl_trait_in_params } // Trying with traits diff --git a/tests/ui/impl_trait_in_params.stderr b/tests/ui/impl_trait_in_params.stderr index ad735d034317..c904d5843c93 100644 --- a/tests/ui/impl_trait_in_params.stderr +++ b/tests/ui/impl_trait_in_params.stderr @@ -23,26 +23,26 @@ LL | pub fn c(_: C, _: impl Trait) {} | +++++++++++++++++++++++++++++++ error: `impl Trait` used as a function parameter - --> tests/ui/impl_trait_in_params.rs:38:13 + --> tests/ui/impl_trait_in_params.rs:37:17 | -LL | pub fn h(_: impl Trait) {} - | ^^^^^^^^^^ +LL | pub fn h(_: impl Trait) {} + | ^^^^^^^^^^ | help: add a type parameter | -LL | pub fn h<{ /* Generic name */ }: Trait>(_: impl Trait) {} - | +++++++++++++++++++++++++++++++ +LL | pub fn h<{ /* Generic name */ }: Trait>(_: impl Trait) {} + | +++++++++++++++++++++++++++++++ error: `impl Trait` used as a function parameter - --> tests/ui/impl_trait_in_params.rs:42:41 + --> tests/ui/impl_trait_in_params.rs:41:45 | -LL | pub fn k>(_: K, _: impl AnotherTrait) {} - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | pub fn k>(_: K, _: impl AnotherTrait) {} + | ^^^^^^^^^^^^^^^^^^^^^^ | help: add a type parameter | -LL | pub fn k, { /* Generic name */ }: AnotherTrait>(_: K, _: impl AnotherTrait) {} - | +++++++++++++++++++++++++++++++++++++++++++ +LL | pub fn k, { /* Generic name */ }: AnotherTrait>(_: K, _: impl AnotherTrait) {} + | +++++++++++++++++++++++++++++++++++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/implicit_hasher.fixed b/tests/ui/implicit_hasher.fixed index fd6c4ffc9122..bea5b9afc43a 100644 --- a/tests/ui/implicit_hasher.fixed +++ b/tests/ui/implicit_hasher.fixed @@ -13,7 +13,7 @@ pub trait Foo: Sized { } impl Foo for HashMap { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { // OK, don't suggest to modify these let _: HashMap = HashMap::new(); @@ -23,13 +23,13 @@ impl Foo for HashMap } } impl Foo for (HashMap,) { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Default::default()),)) } } impl Foo for HashMap { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default())) } @@ -47,13 +47,13 @@ impl Foo for HashMap { } impl Foo for HashSet { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default())) } } impl Foo for HashSet { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default())) } diff --git a/tests/ui/implicit_hasher.rs b/tests/ui/implicit_hasher.rs index 29a1afd2efc8..afdf4da61650 100644 --- a/tests/ui/implicit_hasher.rs +++ b/tests/ui/implicit_hasher.rs @@ -13,7 +13,7 @@ pub trait Foo: Sized { } impl Foo for HashMap { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { // OK, don't suggest to modify these let _: HashMap = HashMap::new(); @@ -23,13 +23,13 @@ impl Foo for HashMap { } } impl Foo for (HashMap,) { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { ((HashMap::new(),), (HashMap::with_capacity(10),)) } } impl Foo for HashMap { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { (HashMap::new(), HashMap::with_capacity(10)) } @@ -47,13 +47,13 @@ impl Foo for HashMap { } impl Foo for HashSet { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { (HashSet::new(), HashSet::with_capacity(10)) } } impl Foo for HashSet { -//~^ implicit_hasher + //~^ implicit_hasher fn make() -> (Self, Self) { (HashSet::new(), HashSet::with_capacity(10)) } diff --git a/tests/ui/implicit_saturating_add.rs b/tests/ui/implicit_saturating_add.rs index 2396db8daa0c..d9d035bdcd31 100644 --- a/tests/ui/implicit_saturating_add.rs +++ b/tests/ui/implicit_saturating_add.rs @@ -19,12 +19,12 @@ fn main() { } if u_8 != u8::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_8 += 1; } if u_8 < u8::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_8 += 1; } @@ -33,107 +33,107 @@ fn main() { } if u_16 != u16::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_16 += 1; } if u_16 < u16::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_16 += 1; } if u16::MAX > u_16 { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_16 += 1; } if u_32 != u32::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_32 += 1; } if u_32 < u32::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_32 += 1; } if u32::MAX > u_32 { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_32 += 1; } if u_64 != u64::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_64 += 1; } if u_64 < u64::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_64 += 1; } if u64::MAX > u_64 { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_64 += 1; } if i_8 != i8::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_8 += 1; } if i_8 < i8::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_8 += 1; } if i8::MAX > i_8 { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_8 += 1; } if i_16 != i16::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_16 += 1; } if i_16 < i16::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_16 += 1; } if i16::MAX > i_16 { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_16 += 1; } if i_32 != i32::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_32 += 1; } if i_32 < i32::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_32 += 1; } if i32::MAX > i_32 { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_32 += 1; } if i_64 != i64::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_64 += 1; } if i_64 < i64::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_64 += 1; } if i64::MAX > i_64 { - //~^ implicit_saturating_add + //~^ implicit_saturating_add i_64 += 1; } @@ -170,7 +170,7 @@ fn main() { if u_32 < 42 { println!("brace yourself!"); } else if u_32 < u32::MAX { - //~^ implicit_saturating_add + //~^ implicit_saturating_add u_32 += 1; } } diff --git a/tests/ui/implicit_saturating_sub.rs b/tests/ui/implicit_saturating_sub.rs index 5b7221b7060f..140cf0338602 100644 --- a/tests/ui/implicit_saturating_sub.rs +++ b/tests/ui/implicit_saturating_sub.rs @@ -25,7 +25,7 @@ fn main() { // Lint if u_8 > 0 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub u_8 = u_8 - 1; } @@ -33,7 +33,7 @@ fn main() { 10 => { // Lint if u_8 > 0 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub u_8 -= 1; } }, @@ -48,7 +48,7 @@ fn main() { // Lint if u_16 > 0 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub u_16 -= 1; } @@ -59,7 +59,7 @@ fn main() { // Lint if u_32 != 0 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub u_32 -= 1; } @@ -81,19 +81,19 @@ fn main() { // Lint if u_64 > 0 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub u_64 -= 1; } // Lint if 0 < u_64 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub u_64 -= 1; } // Lint if 0 != u_64 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub u_64 -= 1; } @@ -115,7 +115,7 @@ fn main() { // Lint if u_usize > 0 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub u_usize -= 1; } @@ -128,25 +128,25 @@ fn main() { // Lint if i_8 > i8::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_8 -= 1; } // Lint if i_8 > i8::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_8 -= 1; } // Lint if i_8 != i8::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_8 -= 1; } // Lint if i_8 != i8::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_8 -= 1; } @@ -157,25 +157,25 @@ fn main() { // Lint if i_16 > i16::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_16 -= 1; } // Lint if i_16 > i16::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_16 -= 1; } // Lint if i_16 != i16::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_16 -= 1; } // Lint if i_16 != i16::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_16 -= 1; } @@ -186,25 +186,25 @@ fn main() { // Lint if i_32 > i32::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_32 -= 1; } // Lint if i_32 > i32::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_32 -= 1; } // Lint if i_32 != i32::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_32 -= 1; } // Lint if i_32 != i32::MIN { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_32 -= 1; } @@ -215,19 +215,19 @@ fn main() { // Lint if i64::MIN < i_64 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_64 -= 1; } // Lint if i64::MIN != i_64 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_64 -= 1; } // Lint if i64::MIN < i_64 { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub i_64 -= 1; } @@ -296,7 +296,7 @@ fn regression_13524(a: usize, b: usize, c: bool) -> usize { if c { 123 } else if a >= b { - //~^ implicit_saturating_sub + //~^ implicit_saturating_sub 0 } else { b - a diff --git a/tests/ui/implied_bounds_in_impls.fixed b/tests/ui/implied_bounds_in_impls.fixed index fe44d7c64b6e..bac7af59491f 100644 --- a/tests/ui/implied_bounds_in_impls.fixed +++ b/tests/ui/implied_bounds_in_impls.fixed @@ -11,7 +11,7 @@ fn normal_deref(x: T) -> impl Deref { // Deref implied by DerefMut fn deref_derefmut(x: T) -> impl DerefMut { -//~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls Box::new(x) } @@ -63,14 +63,14 @@ struct SomeStruct; impl SomeStruct { // Check that it works in inherent impl blocks. fn f() -> impl DerefMut { - //~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls Box::new(123) } } impl SomeTrait for SomeStruct { // Check that it works in trait impls. fn f() -> impl DerefMut { - //~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls Box::new(42) } } @@ -98,13 +98,13 @@ mod issue11422 { mod issue11435 { // Associated type needs to be included on DoubleEndedIterator in the suggestion fn my_iter() -> impl DoubleEndedIterator { - //~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls 0..5 } // Removing the `Clone` bound should include the `+` behind it in its remove suggestion fn f() -> impl Copy { - //~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls 1 } diff --git a/tests/ui/implied_bounds_in_impls.rs b/tests/ui/implied_bounds_in_impls.rs index 0e100262d2d9..2014cd46ada7 100644 --- a/tests/ui/implied_bounds_in_impls.rs +++ b/tests/ui/implied_bounds_in_impls.rs @@ -11,7 +11,7 @@ fn normal_deref(x: T) -> impl Deref { // Deref implied by DerefMut fn deref_derefmut(x: T) -> impl Deref + DerefMut { -//~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls Box::new(x) } @@ -63,14 +63,14 @@ struct SomeStruct; impl SomeStruct { // Check that it works in inherent impl blocks. fn f() -> impl Deref + DerefMut { - //~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls Box::new(123) } } impl SomeTrait for SomeStruct { // Check that it works in trait impls. fn f() -> impl Deref + DerefMut { - //~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls Box::new(42) } } @@ -98,13 +98,13 @@ mod issue11422 { mod issue11435 { // Associated type needs to be included on DoubleEndedIterator in the suggestion fn my_iter() -> impl Iterator + DoubleEndedIterator { - //~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls 0..5 } // Removing the `Clone` bound should include the `+` behind it in its remove suggestion fn f() -> impl Copy + Clone { - //~^ implied_bounds_in_impls + //~^ implied_bounds_in_impls 1 } diff --git a/tests/ui/incompatible_msrv.rs b/tests/ui/incompatible_msrv.rs index 523c754437aa..b4fea4cae5ed 100644 --- a/tests/ui/incompatible_msrv.rs +++ b/tests/ui/incompatible_msrv.rs @@ -16,12 +16,10 @@ fn foo() { if let Entry::Vacant(v) = map.entry("poneyland") { v.into_key(); //~^ incompatible_msrv - } // Should warn for `sleep` but not for `Duration` (which was added in `1.3.0`). sleep(Duration::new(1, 0)); //~^ incompatible_msrv - } #[test] diff --git a/tests/ui/incompatible_msrv.stderr b/tests/ui/incompatible_msrv.stderr index f14e9810b203..56c9eae5aafa 100644 --- a/tests/ui/incompatible_msrv.stderr +++ b/tests/ui/incompatible_msrv.stderr @@ -14,7 +14,7 @@ LL | v.into_key(); | ^^^^^^^^^^ error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0` - --> tests/ui/incompatible_msrv.rs:22:5 + --> tests/ui/incompatible_msrv.rs:21:5 | LL | sleep(Duration::new(1, 0)); | ^^^^^ diff --git a/tests/ui/inconsistent_struct_constructor.fixed b/tests/ui/inconsistent_struct_constructor.fixed index 1b3f27a45d6a..66232c0b9d8e 100644 --- a/tests/ui/inconsistent_struct_constructor.fixed +++ b/tests/ui/inconsistent_struct_constructor.fixed @@ -34,7 +34,7 @@ mod without_base { // Should lint. Foo { x, y, z }; - //~^ inconsistent_struct_constructor + //~^ inconsistent_struct_constructor // Should NOT lint. // issue #7069. @@ -66,7 +66,7 @@ mod with_base { z, ..Default::default() }; - //~^^^^ inconsistent_struct_constructor + //~^^^^ inconsistent_struct_constructor // Should NOT lint because the order is consistent with the definition. Foo { diff --git a/tests/ui/inconsistent_struct_constructor.rs b/tests/ui/inconsistent_struct_constructor.rs index ec29bdaf93f0..8dd228e72ed7 100644 --- a/tests/ui/inconsistent_struct_constructor.rs +++ b/tests/ui/inconsistent_struct_constructor.rs @@ -34,7 +34,7 @@ mod without_base { // Should lint. Foo { y, x, z }; - //~^ inconsistent_struct_constructor + //~^ inconsistent_struct_constructor // Should NOT lint. // issue #7069. @@ -66,7 +66,7 @@ mod with_base { x, ..Default::default() }; - //~^^^^ inconsistent_struct_constructor + //~^^^^ inconsistent_struct_constructor // Should NOT lint because the order is consistent with the definition. Foo { diff --git a/tests/ui/index_refutable_slice/if_let_slice_binding.fixed b/tests/ui/index_refutable_slice/if_let_slice_binding.fixed index f5f66d6eca61..e19aa4acb4c1 100644 --- a/tests/ui/index_refutable_slice/if_let_slice_binding.fixed +++ b/tests/ui/index_refutable_slice/if_let_slice_binding.fixed @@ -12,7 +12,7 @@ fn lintable_examples() { // Try with reference let slice: Option<&[u32]> = Some(&[1, 2, 3]); if let Some([slice_0, ..]) = slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{}", slice_0); } @@ -20,7 +20,7 @@ fn lintable_examples() { // Try with copy let slice: Option<[u32; 3]> = Some([1, 2, 3]); if let Some([slice_0, ..]) = slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{}", slice_0); } @@ -28,7 +28,7 @@ fn lintable_examples() { // Try with long slice and small indices let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]); if let Some([slice_0, _, slice_2, ..]) = slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{}", slice_2); println!("{}", slice_0); @@ -37,7 +37,7 @@ fn lintable_examples() { // Multiple bindings let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]); if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{}", slice_0); } @@ -46,9 +46,8 @@ fn lintable_examples() { let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]); let b_wrapped: Option<[u32; 2]> = Some([4, 6]); if let (SomeEnum::Three([_, _, a_2, ..]), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) { - //~^ index_refutable_slice - //~| index_refutable_slice - + //~^ index_refutable_slice + //~| index_refutable_slice println!("{} -> {}", a_2, b_1); } @@ -57,7 +56,7 @@ fn lintable_examples() { // borrowed and `String` doesn't implement copy let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); if let Some([_, ref slice_1, ..]) = slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{:?}", slice_1); } @@ -67,7 +66,7 @@ fn lintable_examples() { // a reference let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); if let Some([slice_0, ..]) = &slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{:?}", slice_0); } @@ -138,7 +137,7 @@ fn check_slice_in_struct() { // Test 1: Field access if let Some([slice_0, ..]) = wrap.inner { - //~^ index_refutable_slice + //~^ index_refutable_slice if wrap.is_awesome { println!("This is awesome! {}", slice_0); @@ -147,7 +146,7 @@ fn check_slice_in_struct() { // Test 2: function access if let Some([slice_0, ..]) = wrap.inner { - //~^ index_refutable_slice + //~^ index_refutable_slice if wrap.is_super_awesome() { println!("This is super awesome! {}", slice_0); diff --git a/tests/ui/index_refutable_slice/if_let_slice_binding.rs b/tests/ui/index_refutable_slice/if_let_slice_binding.rs index 408fd85cfe6a..290393568554 100644 --- a/tests/ui/index_refutable_slice/if_let_slice_binding.rs +++ b/tests/ui/index_refutable_slice/if_let_slice_binding.rs @@ -12,7 +12,7 @@ fn lintable_examples() { // Try with reference let slice: Option<&[u32]> = Some(&[1, 2, 3]); if let Some(slice) = slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{}", slice[0]); } @@ -20,7 +20,7 @@ fn lintable_examples() { // Try with copy let slice: Option<[u32; 3]> = Some([1, 2, 3]); if let Some(slice) = slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{}", slice[0]); } @@ -28,7 +28,7 @@ fn lintable_examples() { // Try with long slice and small indices let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]); if let Some(slice) = slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{}", slice[2]); println!("{}", slice[0]); @@ -37,7 +37,7 @@ fn lintable_examples() { // Multiple bindings let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]); if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{}", slice[0]); } @@ -46,9 +46,8 @@ fn lintable_examples() { let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]); let b_wrapped: Option<[u32; 2]> = Some([4, 6]); if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) { - //~^ index_refutable_slice - //~| index_refutable_slice - + //~^ index_refutable_slice + //~| index_refutable_slice println!("{} -> {}", a[2], b[1]); } @@ -57,7 +56,7 @@ fn lintable_examples() { // borrowed and `String` doesn't implement copy let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); if let Some(ref slice) = slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{:?}", slice[1]); } @@ -67,7 +66,7 @@ fn lintable_examples() { // a reference let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); if let Some(slice) = &slice { - //~^ index_refutable_slice + //~^ index_refutable_slice println!("{:?}", slice[0]); } @@ -138,7 +137,7 @@ fn check_slice_in_struct() { // Test 1: Field access if let Some(slice) = wrap.inner { - //~^ index_refutable_slice + //~^ index_refutable_slice if wrap.is_awesome { println!("This is awesome! {}", slice[0]); @@ -147,7 +146,7 @@ fn check_slice_in_struct() { // Test 2: function access if let Some(slice) = wrap.inner { - //~^ index_refutable_slice + //~^ index_refutable_slice if wrap.is_super_awesome() { println!("This is super awesome! {}", slice[0]); diff --git a/tests/ui/index_refutable_slice/if_let_slice_binding.stderr b/tests/ui/index_refutable_slice/if_let_slice_binding.stderr index 6abbc3d7dfad..04bc9838d0c2 100644 --- a/tests/ui/index_refutable_slice/if_let_slice_binding.stderr +++ b/tests/ui/index_refutable_slice/if_let_slice_binding.stderr @@ -70,7 +70,7 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let (SomeEnum::Three([_, _, a_2, ..]), Some(b)) = (a_wrapped, b_wrapped) { LL | -... +LL | LL | LL ~ println!("{} -> {}", a_2, b[1]); | @@ -85,13 +85,13 @@ help: replace the binding and indexed access with a slice pattern | LL ~ if let (SomeEnum::Three(a), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) { LL | -... +LL | LL | LL ~ println!("{} -> {}", a[2], b_1); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:59:21 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:58:21 | LL | if let Some(ref slice) = slice { | ^^^^^ @@ -105,7 +105,7 @@ LL ~ println!("{:?}", slice_1); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:69:17 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:68:17 | LL | if let Some(slice) = &slice { | ^^^^^ @@ -119,7 +119,7 @@ LL ~ println!("{:?}", slice_0); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:140:17 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:139:17 | LL | if let Some(slice) = wrap.inner { | ^^^^^ @@ -134,7 +134,7 @@ LL ~ println!("This is awesome! {}", slice_0); | error: this binding can be a slice pattern to avoid indexing - --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:149:17 + --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:148:17 | LL | if let Some(slice) = wrap.inner { | ^^^^^ diff --git a/tests/ui/ineffective_open_options.fixed b/tests/ui/ineffective_open_options.fixed index c229278e78b2..03b73f99961a 100644 --- a/tests/ui/ineffective_open_options.fixed +++ b/tests/ui/ineffective_open_options.fixed @@ -5,7 +5,8 @@ use std::fs::OpenOptions; fn main() { let file = OpenOptions::new() .create(true) -//~^ ineffective_open_options + + //~^ ineffective_open_options .append(true) .open("dump.json") .unwrap(); @@ -13,7 +14,8 @@ fn main() { let file = OpenOptions::new() .create(true) .append(true) -//~^ ineffective_open_options + + //~^ ineffective_open_options .open("dump.json") .unwrap(); diff --git a/tests/ui/ineffective_open_options.rs b/tests/ui/ineffective_open_options.rs index ed1fe79a2782..e333a71490fb 100644 --- a/tests/ui/ineffective_open_options.rs +++ b/tests/ui/ineffective_open_options.rs @@ -5,8 +5,8 @@ use std::fs::OpenOptions; fn main() { let file = OpenOptions::new() .create(true) -.write(true) -//~^ ineffective_open_options + .write(true) + //~^ ineffective_open_options .append(true) .open("dump.json") .unwrap(); @@ -14,8 +14,8 @@ fn main() { let file = OpenOptions::new() .create(true) .append(true) -.write(true) -//~^ ineffective_open_options + .write(true) + //~^ ineffective_open_options .open("dump.json") .unwrap(); diff --git a/tests/ui/ineffective_open_options.stderr b/tests/ui/ineffective_open_options.stderr index afc97ecd755c..42bb0438dcee 100644 --- a/tests/ui/ineffective_open_options.stderr +++ b/tests/ui/ineffective_open_options.stderr @@ -1,17 +1,17 @@ error: unnecessary use of `.write(true)` because there is `.append(true)` - --> tests/ui/ineffective_open_options.rs:8:1 + --> tests/ui/ineffective_open_options.rs:8:9 | -LL | .write(true) - | ^^^^^^^^^^^^ help: remove `.write(true)` +LL | .write(true) + | ^^^^^^^^^^^^ help: remove `.write(true)` | = note: `-D clippy::ineffective-open-options` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::ineffective_open_options)]` error: unnecessary use of `.write(true)` because there is `.append(true)` - --> tests/ui/ineffective_open_options.rs:17:1 + --> tests/ui/ineffective_open_options.rs:17:9 | -LL | .write(true) - | ^^^^^^^^^^^^ help: remove `.write(true)` +LL | .write(true) + | ^^^^^^^^^^^^ help: remove `.write(true)` error: aborting due to 2 previous errors diff --git a/tests/ui/infallible_destructuring_match.rs b/tests/ui/infallible_destructuring_match.rs index 3db3aca18f23..5db30ebca88f 100644 --- a/tests/ui/infallible_destructuring_match.rs +++ b/tests/ui/infallible_destructuring_match.rs @@ -26,7 +26,7 @@ fn infallible_destructuring_match_enum() { // This should lint! let data = match wrapper { - //~^ infallible_destructuring_match + //~^ infallible_destructuring_match SingleVariantEnum::Variant(i) => i, }; @@ -59,7 +59,7 @@ fn infallible_destructuring_match_struct() { // This should lint! let data = match wrapper { - //~^ infallible_destructuring_match + //~^ infallible_destructuring_match TupleStruct(i) => i, }; @@ -84,7 +84,7 @@ fn infallible_destructuring_match_struct_with_noncopy() { // This should lint! (keeping `ref` in the suggestion) let data = match wrapper { - //~^ infallible_destructuring_match + //~^ infallible_destructuring_match TupleStructWithNonCopy(ref n) => n, }; @@ -104,7 +104,7 @@ fn never_enum() { // This should lint! let data = match wrapper { - //~^ infallible_destructuring_match + //~^ infallible_destructuring_match Ok(i) => i, }; diff --git a/tests/ui/infinite_iter.rs b/tests/ui/infinite_iter.rs index 2f8cc954e70c..002a791a6579 100644 --- a/tests/ui/infinite_iter.rs +++ b/tests/ui/infinite_iter.rs @@ -26,8 +26,7 @@ fn infinite_iters() { .min(); // infinite iter (0..8_u32) - //~^ infinite_iter - + //~^ infinite_iter .rev() .cycle() .map(|x| x + 1_u32) @@ -60,8 +59,7 @@ fn potential_infinite_iters() { // maybe infinite iter (1..) - //~^ maybe_infinite_iter - + //~^ maybe_infinite_iter .scan(0, |state, x| { *state += x; Some(*state) @@ -83,7 +81,6 @@ fn potential_infinite_iters() { (0..).all(|x| x == 24); //~^ maybe_infinite_iter - // not infinite (0..).zip(0..42).take_while(|&(x, _)| x != 42).count(); // iterator is not exhausted @@ -110,8 +107,6 @@ mod finite_collect { let _: HashSet = (0..).collect(); //~^ infinite_iter - - // Some data structures don't collect infinitely, such as `ArrayVec` let _: C = (0..).collect(); } diff --git a/tests/ui/infinite_iter.stderr b/tests/ui/infinite_iter.stderr index ef3836a5ab59..47133a2ea62e 100644 --- a/tests/ui/infinite_iter.stderr +++ b/tests/ui/infinite_iter.stderr @@ -27,7 +27,6 @@ error: infinite iteration detected | LL | / (0..8_u32) LL | | -LL | | LL | | .rev() LL | | .cycle() LL | | .map(|x| x + 1_u32) @@ -35,73 +34,73 @@ LL | | .for_each(|x| println!("{}", x)); | |________________________________________^ error: infinite iteration detected - --> tests/ui/infinite_iter.rs:38:5 + --> tests/ui/infinite_iter.rs:37:5 | LL | (0_usize..).flat_map(|x| 0..x).product::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: infinite iteration detected - --> tests/ui/infinite_iter.rs:42:5 + --> tests/ui/infinite_iter.rs:41:5 | LL | (0_u64..).filter(|x| x % 2 == 0).last(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:54:5 + --> tests/ui/infinite_iter.rs:53:5 | LL | (0..).zip((0..).take_while(square_is_lower_64)).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> tests/ui/infinite_iter.rs:51:8 + --> tests/ui/infinite_iter.rs:50:8 | LL | #[deny(clippy::maybe_infinite_iter)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:58:5 + --> tests/ui/infinite_iter.rs:57:5 | LL | repeat(42).take_while(|x| *x == 42).chain(0..42).max(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:62:5 + --> tests/ui/infinite_iter.rs:61:5 | LL | / (1..) LL | | -LL | | LL | | .scan(0, |state, x| { -... | +LL | | *state += x; +LL | | Some(*state) LL | | }) LL | | .min(); | |______________^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:71:5 + --> tests/ui/infinite_iter.rs:69:5 | LL | (0..).find(|x| *x == 24); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:75:5 + --> tests/ui/infinite_iter.rs:73:5 | LL | (0..).position(|x| x == 24); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:79:5 + --> tests/ui/infinite_iter.rs:77:5 | LL | (0..).any(|x| x == 24); | ^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected - --> tests/ui/infinite_iter.rs:83:5 + --> tests/ui/infinite_iter.rs:81:5 | LL | (0..).all(|x| x == 24); | ^^^^^^^^^^^^^^^^^^^^^^ error: infinite iteration detected - --> tests/ui/infinite_iter.rs:110:31 + --> tests/ui/infinite_iter.rs:107:31 | LL | let _: HashSet = (0..).collect(); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/infinite_loop.rs b/tests/ui/infinite_loop.rs index 02d40e84eed9..4a0968918bfb 100644 --- a/tests/ui/infinite_loop.rs +++ b/tests/ui/infinite_loop.rs @@ -20,16 +20,14 @@ fn immutable_condition() { // Should warn when all vars mentioned are immutable let y = 0; while y < 10 { - //~^ while_immutable_condition - + //~^ while_immutable_condition println!("KO - y is immutable"); } let x = 0; while y < 10 && x < 3 { - //~^ while_immutable_condition - + //~^ while_immutable_condition let mut k = 1; k += 2; @@ -38,8 +36,7 @@ fn immutable_condition() { let cond = false; while !cond { - //~^ while_immutable_condition - + //~^ while_immutable_condition println!("KO - cond immutable"); } @@ -85,23 +82,20 @@ fn unused_var() { let (mut i, mut j) = (0, 0); while i < 3 { - //~^ while_immutable_condition - + //~^ while_immutable_condition j = 3; println!("KO - i not mentioned"); } while i < 3 && j > 0 { - //~^ while_immutable_condition - + //~^ while_immutable_condition println!("KO - i and j not mentioned"); } while i < 3 { - //~^ while_immutable_condition - + //~^ while_immutable_condition let mut i = 5; fn_mutref(&mut i); @@ -118,16 +112,14 @@ fn used_immutable() { let mut i = 0; while i < 3 { - //~^ while_immutable_condition - + //~^ while_immutable_condition fn_constref(&i); println!("KO - const reference"); } while i < 3 { - //~^ while_immutable_condition - + //~^ while_immutable_condition fn_val(i); println!("KO - passed by value"); @@ -195,8 +187,7 @@ impl Counter { fn print_n(&self, n: usize) { while self.count < n { - //~^ while_immutable_condition - + //~^ while_immutable_condition println!("KO - {} is not mutated", self.count); } @@ -206,8 +197,7 @@ impl Counter { fn while_loop_with_break_and_return() { let y = 0; while y < 10 { - //~^ while_immutable_condition - + //~^ while_immutable_condition if y == 0 { break; @@ -216,8 +206,7 @@ fn while_loop_with_break_and_return() { } while y < 10 { - //~^ while_immutable_condition - + //~^ while_immutable_condition if y == 0 { return; diff --git a/tests/ui/infinite_loop.stderr b/tests/ui/infinite_loop.stderr index f2876fd6ddb8..7ba1374d64f4 100644 --- a/tests/ui/infinite_loop.stderr +++ b/tests/ui/infinite_loop.stderr @@ -8,7 +8,7 @@ LL | while y < 10 { = note: `#[deny(clippy::while_immutable_condition)]` on by default error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:30:11 + --> tests/ui/infinite_loop.rs:29:11 | LL | while y < 10 && x < 3 { | ^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | while y < 10 && x < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:40:11 + --> tests/ui/infinite_loop.rs:38:11 | LL | while !cond { | ^^^^^ @@ -24,7 +24,7 @@ LL | while !cond { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:87:11 + --> tests/ui/infinite_loop.rs:84:11 | LL | while i < 3 { | ^^^^^ @@ -32,7 +32,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:95:11 + --> tests/ui/infinite_loop.rs:91:11 | LL | while i < 3 && j > 0 { | ^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | while i < 3 && j > 0 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:102:11 + --> tests/ui/infinite_loop.rs:97:11 | LL | while i < 3 { | ^^^^^ @@ -48,7 +48,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:120:11 + --> tests/ui/infinite_loop.rs:114:11 | LL | while i < 3 { | ^^^^^ @@ -56,7 +56,7 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:128:11 + --> tests/ui/infinite_loop.rs:121:11 | LL | while i < 3 { | ^^^^^ @@ -64,13 +64,23 @@ LL | while i < 3 { = note: this may lead to an infinite or to a never running loop error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:197:15 + --> tests/ui/infinite_loop.rs:189:15 | LL | while self.count < n { | ^^^^^^^^^^^^^^ | = note: this may lead to an infinite or to a never running loop +error: variables in the condition are not mutated in the loop body + --> tests/ui/infinite_loop.rs:199:11 + | +LL | while y < 10 { + | ^^^^^^ + | + = note: this may lead to an infinite or to a never running loop + = note: this loop contains `return`s or `break`s + = help: rewrite it as `if cond { loop { } }` + error: variables in the condition are not mutated in the loop body --> tests/ui/infinite_loop.rs:208:11 | @@ -81,15 +91,5 @@ LL | while y < 10 { = note: this loop contains `return`s or `break`s = help: rewrite it as `if cond { loop { } }` -error: variables in the condition are not mutated in the loop body - --> tests/ui/infinite_loop.rs:218:11 - | -LL | while y < 10 { - | ^^^^^^ - | - = note: this may lead to an infinite or to a never running loop - = note: this loop contains `return`s or `break`s - = help: rewrite it as `if cond { loop { } }` - error: aborting due to 11 previous errors diff --git a/tests/ui/infinite_loops.rs b/tests/ui/infinite_loops.rs index b5c1a5688eca..eaa8d0088068 100644 --- a/tests/ui/infinite_loops.rs +++ b/tests/ui/infinite_loops.rs @@ -11,18 +11,18 @@ fn do_something() {} fn no_break() { loop { - //~^ infinite_loop + //~^ infinite_loop do_something(); } } fn all_inf() { loop { - //~^ infinite_loop - loop { //~^ infinite_loop - loop { + loop { //~^ infinite_loop + loop { + //~^ infinite_loop do_something(); } } @@ -36,7 +36,7 @@ fn no_break_return_some_ty() -> Option { return None; } loop { - //~^ infinite_loop + //~^ infinite_loop do_something(); } } @@ -49,7 +49,7 @@ fn no_break_never_ret() -> ! { fn no_break_never_ret_noise() { loop { - //~^ infinite_loop + //~^ infinite_loop fn inner_fn() -> ! { std::process::exit(0); } @@ -93,7 +93,7 @@ fn has_indirect_break_2(stop_num: i32) { fn break_inner_but_not_outer_1(cond: bool) { loop { - //~^ infinite_loop + //~^ infinite_loop loop { if cond { break; @@ -104,7 +104,7 @@ fn break_inner_but_not_outer_1(cond: bool) { fn break_inner_but_not_outer_2(cond: bool) { loop { - //~^ infinite_loop + //~^ infinite_loop 'inner: loop { loop { if cond { @@ -118,7 +118,7 @@ fn break_inner_but_not_outer_2(cond: bool) { fn break_outer_but_not_inner() { loop { loop { - //~^ infinite_loop + //~^ infinite_loop do_something(); } break; @@ -141,7 +141,7 @@ fn break_wrong_loop(cond: bool) { // 'inner has statement to break 'outer loop, but it was broken out of early by a labeled child loop 'outer: loop { loop { - //~^ infinite_loop + //~^ infinite_loop 'inner: loop { loop { loop { @@ -181,7 +181,7 @@ enum Foo { fn match_like() { let opt: Option = Some(1); loop { - //~^ infinite_loop + //~^ infinite_loop match opt { Some(v) => { println!("{v}"); @@ -222,12 +222,12 @@ fn match_like() { } loop { - //~^ infinite_loop + //~^ infinite_loop let _x = matches!(result, Ok(v) if v != 0).then_some(0); } loop { - //~^ infinite_loop + //~^ infinite_loop // This `return` does not return the function, so it doesn't count let _x = matches!(result, Ok(v) if v != 0).then(|| { if true { @@ -332,7 +332,7 @@ fn exit_directly(cond: bool) { trait MyTrait { fn problematic_trait_method() { loop { - //~^ infinite_loop + //~^ infinite_loop do_something(); } } @@ -342,7 +342,7 @@ trait MyTrait { impl MyTrait for String { fn could_be_problematic() { loop { - //~^ infinite_loop + //~^ infinite_loop do_something(); } } @@ -351,7 +351,7 @@ impl MyTrait for String { fn inf_loop_in_closure() { let _loop_forever = || { loop { - //~^ infinite_loop + //~^ infinite_loop do_something(); } }; @@ -365,7 +365,7 @@ fn inf_loop_in_closure() { fn inf_loop_in_res() -> Result<(), i32> { Ok(loop { - //~^ infinite_loop + //~^ infinite_loop do_something() }) } @@ -408,16 +408,16 @@ fn continue_outer() { // This should lint as we continue the loop itself 'infinite: loop { - //~^ infinite_loop + //~^ infinite_loop loop { continue 'infinite; } } // This should lint as we continue an inner loop loop { - //~^ infinite_loop - 'inner: loop { //~^ infinite_loop + 'inner: loop { + //~^ infinite_loop loop { continue 'inner; } @@ -426,7 +426,7 @@ fn continue_outer() { // This should lint as we continue the loop itself loop { - //~^ infinite_loop + //~^ infinite_loop continue; } } diff --git a/tests/ui/inherent_to_string.rs b/tests/ui/inherent_to_string.rs index a1a810dad1e4..30977f2d93ac 100644 --- a/tests/ui/inherent_to_string.rs +++ b/tests/ui/inherent_to_string.rs @@ -20,7 +20,7 @@ struct J; impl A { // Should be detected; emit warning fn to_string(&self) -> String { - //~^ inherent_to_string + //~^ inherent_to_string "A.to_string()".to_string() } @@ -46,7 +46,7 @@ impl B { impl C { // Should be detected and emit error as C also implements Display fn to_string(&self) -> String { - //~^ inherent_to_string_shadow_display + //~^ inherent_to_string_shadow_display "C.to_string()".to_string() } diff --git a/tests/ui/init_numbered_fields.rs b/tests/ui/init_numbered_fields.rs index dc33921e3df9..ae5dfe889575 100644 --- a/tests/ui/init_numbered_fields.rs +++ b/tests/ui/init_numbered_fields.rs @@ -15,7 +15,7 @@ fn main() { // This should lint let _ = TupleStruct { - //~^ init_numbered_fields + //~^ init_numbered_fields 0: 1u32, 1: 42, 2: 23u8, @@ -23,7 +23,7 @@ fn main() { // This should also lint and order the fields correctly let _ = TupleStruct { - //~^ init_numbered_fields + //~^ init_numbered_fields 0: 1u32, 2: 2u8, 1: 3u32, diff --git a/tests/ui/inspect_for_each.rs b/tests/ui/inspect_for_each.rs index d3eb7fcbba4d..8bfd9cec66dc 100644 --- a/tests/ui/inspect_for_each.rs +++ b/tests/ui/inspect_for_each.rs @@ -5,7 +5,7 @@ fn main() { let mut b: Vec = Vec::new(); a.into_iter().inspect(|x| assert!(*x > 0)).for_each(|x| { - //~^ inspect_for_each + //~^ inspect_for_each let y = do_some(x); let z = do_more(y); diff --git a/tests/ui/into_iter_on_ref.fixed b/tests/ui/into_iter_on_ref.fixed index 6d62a6547427..7626569fd422 100644 --- a/tests/ui/into_iter_on_ref.fixed +++ b/tests/ui/into_iter_on_ref.fixed @@ -10,60 +10,60 @@ fn main() { for _ in &vec![X, X] {} let _ = vec![1, 2, 3].into_iter(); -let _ = (&vec![1, 2, 3]).iter(); -//~^ into_iter_on_ref -let _ = std::rc::Rc::from(&[X][..]).iter(); -//~^ into_iter_on_ref -let _ = std::sync::Arc::from(&[X][..]).iter(); -//~^ into_iter_on_ref + let _ = (&vec![1, 2, 3]).iter(); + //~^ into_iter_on_ref + let _ = std::rc::Rc::from(&[X][..]).iter(); + //~^ into_iter_on_ref + let _ = std::sync::Arc::from(&[X][..]).iter(); + //~^ into_iter_on_ref -let _ = (&&&&&&&[1, 2, 3]).iter(); -//~^ into_iter_on_ref -let _ = (&&&&mut &&&[1, 2, 3]).iter(); -//~^ into_iter_on_ref -let _ = (&mut &mut &mut [1, 2, 3]).iter_mut(); -//~^ into_iter_on_ref + let _ = (&&&&&&&[1, 2, 3]).iter(); + //~^ into_iter_on_ref + let _ = (&&&&mut &&&[1, 2, 3]).iter(); + //~^ into_iter_on_ref + let _ = (&mut &mut &mut [1, 2, 3]).iter_mut(); + //~^ into_iter_on_ref -let _ = (&Some(4)).iter(); -//~^ into_iter_on_ref -let _ = (&mut Some(5)).iter_mut(); -//~^ into_iter_on_ref -let _ = (&Ok::<_, i32>(6)).iter(); -//~^ into_iter_on_ref -let _ = (&mut Err::(7)).iter_mut(); -//~^ into_iter_on_ref -let _ = (&Vec::::new()).iter(); -//~^ into_iter_on_ref -let _ = (&mut Vec::::new()).iter_mut(); -//~^ into_iter_on_ref -let _ = (&BTreeMap::::new()).iter(); -//~^ into_iter_on_ref -let _ = (&mut BTreeMap::::new()).iter_mut(); -//~^ into_iter_on_ref -let _ = (&VecDeque::::new()).iter(); -//~^ into_iter_on_ref -let _ = (&mut VecDeque::::new()).iter_mut(); -//~^ into_iter_on_ref -let _ = (&LinkedList::::new()).iter(); -//~^ into_iter_on_ref -let _ = (&mut LinkedList::::new()).iter_mut(); -//~^ into_iter_on_ref -let _ = (&HashMap::::new()).iter(); -//~^ into_iter_on_ref -let _ = (&mut HashMap::::new()).iter_mut(); -//~^ into_iter_on_ref + let _ = (&Some(4)).iter(); + //~^ into_iter_on_ref + let _ = (&mut Some(5)).iter_mut(); + //~^ into_iter_on_ref + let _ = (&Ok::<_, i32>(6)).iter(); + //~^ into_iter_on_ref + let _ = (&mut Err::(7)).iter_mut(); + //~^ into_iter_on_ref + let _ = (&Vec::::new()).iter(); + //~^ into_iter_on_ref + let _ = (&mut Vec::::new()).iter_mut(); + //~^ into_iter_on_ref + let _ = (&BTreeMap::::new()).iter(); + //~^ into_iter_on_ref + let _ = (&mut BTreeMap::::new()).iter_mut(); + //~^ into_iter_on_ref + let _ = (&VecDeque::::new()).iter(); + //~^ into_iter_on_ref + let _ = (&mut VecDeque::::new()).iter_mut(); + //~^ into_iter_on_ref + let _ = (&LinkedList::::new()).iter(); + //~^ into_iter_on_ref + let _ = (&mut LinkedList::::new()).iter_mut(); + //~^ into_iter_on_ref + let _ = (&HashMap::::new()).iter(); + //~^ into_iter_on_ref + let _ = (&mut HashMap::::new()).iter_mut(); + //~^ into_iter_on_ref -let _ = (&BTreeSet::::new()).iter(); -//~^ into_iter_on_ref -let _ = (&BinaryHeap::::new()).iter(); -//~^ into_iter_on_ref -let _ = (&HashSet::::new()).iter(); -//~^ into_iter_on_ref -let _ = std::path::Path::new("12/34").iter(); -//~^ into_iter_on_ref -let _ = std::path::PathBuf::from("12/34").iter(); -//~^ into_iter_on_ref + let _ = (&BTreeSet::::new()).iter(); + //~^ into_iter_on_ref + let _ = (&BinaryHeap::::new()).iter(); + //~^ into_iter_on_ref + let _ = (&HashSet::::new()).iter(); + //~^ into_iter_on_ref + let _ = std::path::Path::new("12/34").iter(); + //~^ into_iter_on_ref + let _ = std::path::PathBuf::from("12/34").iter(); + //~^ into_iter_on_ref -let _ = (&[1, 2, 3]).iter().next(); -//~^ into_iter_on_ref + let _ = (&[1, 2, 3]).iter().next(); + //~^ into_iter_on_ref } diff --git a/tests/ui/into_iter_on_ref.rs b/tests/ui/into_iter_on_ref.rs index 3e678761d751..286a62c69ce5 100644 --- a/tests/ui/into_iter_on_ref.rs +++ b/tests/ui/into_iter_on_ref.rs @@ -10,60 +10,60 @@ fn main() { for _ in &vec![X, X] {} let _ = vec![1, 2, 3].into_iter(); -let _ = (&vec![1, 2, 3]).into_iter(); -//~^ into_iter_on_ref -let _ = std::rc::Rc::from(&[X][..]).into_iter(); -//~^ into_iter_on_ref -let _ = std::sync::Arc::from(&[X][..]).into_iter(); -//~^ into_iter_on_ref + let _ = (&vec![1, 2, 3]).into_iter(); + //~^ into_iter_on_ref + let _ = std::rc::Rc::from(&[X][..]).into_iter(); + //~^ into_iter_on_ref + let _ = std::sync::Arc::from(&[X][..]).into_iter(); + //~^ into_iter_on_ref -let _ = (&&&&&&&[1, 2, 3]).into_iter(); -//~^ into_iter_on_ref -let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); -//~^ into_iter_on_ref -let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); -//~^ into_iter_on_ref + let _ = (&&&&&&&[1, 2, 3]).into_iter(); + //~^ into_iter_on_ref + let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); + //~^ into_iter_on_ref + let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); + //~^ into_iter_on_ref -let _ = (&Some(4)).into_iter(); -//~^ into_iter_on_ref -let _ = (&mut Some(5)).into_iter(); -//~^ into_iter_on_ref -let _ = (&Ok::<_, i32>(6)).into_iter(); -//~^ into_iter_on_ref -let _ = (&mut Err::(7)).into_iter(); -//~^ into_iter_on_ref -let _ = (&Vec::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&mut Vec::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&BTreeMap::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&mut BTreeMap::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&VecDeque::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&mut VecDeque::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&LinkedList::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&mut LinkedList::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&HashMap::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&mut HashMap::::new()).into_iter(); -//~^ into_iter_on_ref + let _ = (&Some(4)).into_iter(); + //~^ into_iter_on_ref + let _ = (&mut Some(5)).into_iter(); + //~^ into_iter_on_ref + let _ = (&Ok::<_, i32>(6)).into_iter(); + //~^ into_iter_on_ref + let _ = (&mut Err::(7)).into_iter(); + //~^ into_iter_on_ref + let _ = (&Vec::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&mut Vec::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&BTreeMap::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&mut BTreeMap::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&VecDeque::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&mut VecDeque::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&LinkedList::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&mut LinkedList::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&HashMap::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&mut HashMap::::new()).into_iter(); + //~^ into_iter_on_ref -let _ = (&BTreeSet::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&BinaryHeap::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = (&HashSet::::new()).into_iter(); -//~^ into_iter_on_ref -let _ = std::path::Path::new("12/34").into_iter(); -//~^ into_iter_on_ref -let _ = std::path::PathBuf::from("12/34").into_iter(); -//~^ into_iter_on_ref + let _ = (&BTreeSet::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&BinaryHeap::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = (&HashSet::::new()).into_iter(); + //~^ into_iter_on_ref + let _ = std::path::Path::new("12/34").into_iter(); + //~^ into_iter_on_ref + let _ = std::path::PathBuf::from("12/34").into_iter(); + //~^ into_iter_on_ref -let _ = (&[1, 2, 3]).into_iter().next(); -//~^ into_iter_on_ref + let _ = (&[1, 2, 3]).into_iter().next(); + //~^ into_iter_on_ref } diff --git a/tests/ui/into_iter_on_ref.stderr b/tests/ui/into_iter_on_ref.stderr index 2c472fca9da5..57ff097a6ca2 100644 --- a/tests/ui/into_iter_on_ref.stderr +++ b/tests/ui/into_iter_on_ref.stderr @@ -1,161 +1,161 @@ error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec` - --> tests/ui/into_iter_on_ref.rs:13:26 + --> tests/ui/into_iter_on_ref.rs:13:30 | -LL | let _ = (&vec![1, 2, 3]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&vec![1, 2, 3]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` | = note: `-D clippy::into-iter-on-ref` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::into_iter_on_ref)]` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice` - --> tests/ui/into_iter_on_ref.rs:15:37 + --> tests/ui/into_iter_on_ref.rs:15:41 | -LL | let _ = std::rc::Rc::from(&[X][..]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = std::rc::Rc::from(&[X][..]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice` - --> tests/ui/into_iter_on_ref.rs:17:40 + --> tests/ui/into_iter_on_ref.rs:17:44 | -LL | let _ = std::sync::Arc::from(&[X][..]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = std::sync::Arc::from(&[X][..]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` - --> tests/ui/into_iter_on_ref.rs:20:28 + --> tests/ui/into_iter_on_ref.rs:20:32 | -LL | let _ = (&&&&&&&[1, 2, 3]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` - --> tests/ui/into_iter_on_ref.rs:22:32 - | -LL | let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); +LL | let _ = (&&&&&&&[1, 2, 3]).into_iter(); | ^^^^^^^^^ help: call directly: `iter` -error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `array` - --> tests/ui/into_iter_on_ref.rs:24:36 +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` + --> tests/ui/into_iter_on_ref.rs:22:36 | -LL | let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `array` + --> tests/ui/into_iter_on_ref.rs:24:40 + | +LL | let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Option` - --> tests/ui/into_iter_on_ref.rs:27:20 + --> tests/ui/into_iter_on_ref.rs:27:24 | -LL | let _ = (&Some(4)).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&Some(4)).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Option` - --> tests/ui/into_iter_on_ref.rs:29:24 + --> tests/ui/into_iter_on_ref.rs:29:28 | -LL | let _ = (&mut Some(5)).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&mut Some(5)).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Result` - --> tests/ui/into_iter_on_ref.rs:31:28 + --> tests/ui/into_iter_on_ref.rs:31:32 | -LL | let _ = (&Ok::<_, i32>(6)).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&Ok::<_, i32>(6)).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Result` - --> tests/ui/into_iter_on_ref.rs:33:33 + --> tests/ui/into_iter_on_ref.rs:33:37 | -LL | let _ = (&mut Err::(7)).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` +LL | let _ = (&mut Err::(7)).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec` - --> tests/ui/into_iter_on_ref.rs:35:30 + --> tests/ui/into_iter_on_ref.rs:35:34 | -LL | let _ = (&Vec::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - -error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Vec` - --> tests/ui/into_iter_on_ref.rs:37:34 - | -LL | let _ = (&mut Vec::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` - -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeMap` - --> tests/ui/into_iter_on_ref.rs:39:40 - | -LL | let _ = (&BTreeMap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - -error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `BTreeMap` - --> tests/ui/into_iter_on_ref.rs:41:44 - | -LL | let _ = (&mut BTreeMap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` - -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `VecDeque` - --> tests/ui/into_iter_on_ref.rs:43:35 - | -LL | let _ = (&VecDeque::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - -error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `VecDeque` - --> tests/ui/into_iter_on_ref.rs:45:39 - | -LL | let _ = (&mut VecDeque::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` - -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `LinkedList` - --> tests/ui/into_iter_on_ref.rs:47:37 - | -LL | let _ = (&LinkedList::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - -error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `LinkedList` - --> tests/ui/into_iter_on_ref.rs:49:41 - | -LL | let _ = (&mut LinkedList::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` - -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashMap` - --> tests/ui/into_iter_on_ref.rs:51:39 - | -LL | let _ = (&HashMap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - -error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `HashMap` - --> tests/ui/into_iter_on_ref.rs:53:43 - | -LL | let _ = (&mut HashMap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter_mut` - -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeSet` - --> tests/ui/into_iter_on_ref.rs:56:35 - | -LL | let _ = (&BTreeSet::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BinaryHeap` - --> tests/ui/into_iter_on_ref.rs:58:37 - | -LL | let _ = (&BinaryHeap::::new()).into_iter(); - | ^^^^^^^^^ help: call directly: `iter` - -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashSet` - --> tests/ui/into_iter_on_ref.rs:60:34 - | -LL | let _ = (&HashSet::::new()).into_iter(); +LL | let _ = (&Vec::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Path` - --> tests/ui/into_iter_on_ref.rs:62:39 +error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Vec` + --> tests/ui/into_iter_on_ref.rs:37:38 | -LL | let _ = std::path::Path::new("12/34").into_iter(); +LL | let _ = (&mut Vec::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeMap` + --> tests/ui/into_iter_on_ref.rs:39:44 + | +LL | let _ = (&BTreeMap::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `BTreeMap` + --> tests/ui/into_iter_on_ref.rs:41:48 + | +LL | let _ = (&mut BTreeMap::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `VecDeque` + --> tests/ui/into_iter_on_ref.rs:43:39 + | +LL | let _ = (&VecDeque::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `PathBuf` - --> tests/ui/into_iter_on_ref.rs:64:43 +error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `VecDeque` + --> tests/ui/into_iter_on_ref.rs:45:43 | -LL | let _ = std::path::PathBuf::from("12/34").into_iter(); +LL | let _ = (&mut VecDeque::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `LinkedList` + --> tests/ui/into_iter_on_ref.rs:47:41 + | +LL | let _ = (&LinkedList::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `LinkedList` + --> tests/ui/into_iter_on_ref.rs:49:45 + | +LL | let _ = (&mut LinkedList::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashMap` + --> tests/ui/into_iter_on_ref.rs:51:43 + | +LL | let _ = (&HashMap::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` -error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` - --> tests/ui/into_iter_on_ref.rs:67:22 +error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `HashMap` + --> tests/ui/into_iter_on_ref.rs:53:47 | -LL | let _ = (&[1, 2, 3]).into_iter().next(); - | ^^^^^^^^^ help: call directly: `iter` +LL | let _ = (&mut HashMap::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter_mut` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeSet` + --> tests/ui/into_iter_on_ref.rs:56:39 + | +LL | let _ = (&BTreeSet::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BinaryHeap` + --> tests/ui/into_iter_on_ref.rs:58:41 + | +LL | let _ = (&BinaryHeap::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashSet` + --> tests/ui/into_iter_on_ref.rs:60:38 + | +LL | let _ = (&HashSet::::new()).into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Path` + --> tests/ui/into_iter_on_ref.rs:62:43 + | +LL | let _ = std::path::Path::new("12/34").into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `PathBuf` + --> tests/ui/into_iter_on_ref.rs:64:47 + | +LL | let _ = std::path::PathBuf::from("12/34").into_iter(); + | ^^^^^^^^^ help: call directly: `iter` + +error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` + --> tests/ui/into_iter_on_ref.rs:67:26 + | +LL | let _ = (&[1, 2, 3]).into_iter().next(); + | ^^^^^^^^^ help: call directly: `iter` error: aborting due to 26 previous errors diff --git a/tests/ui/into_iter_without_iter.rs b/tests/ui/into_iter_without_iter.rs index 368313af6f91..45e34b3930ad 100644 --- a/tests/ui/into_iter_without_iter.rs +++ b/tests/ui/into_iter_without_iter.rs @@ -7,7 +7,7 @@ use std::iter::IntoIterator; pub struct S1; impl<'a> IntoIterator for &'a S1 { -//~^ into_iter_without_iter + //~^ into_iter_without_iter type IntoIter = std::slice::Iter<'a, u8>; type Item = &'a u8; fn into_iter(self) -> Self::IntoIter { @@ -15,7 +15,7 @@ impl<'a> IntoIterator for &'a S1 { } } impl<'a> IntoIterator for &'a mut S1 { -//~^ into_iter_without_iter + //~^ into_iter_without_iter type IntoIter = std::slice::IterMut<'a, u8>; type Item = &'a mut u8; fn into_iter(self) -> Self::IntoIter { @@ -25,7 +25,7 @@ impl<'a> IntoIterator for &'a mut S1 { pub struct S2(T); impl<'a, T> IntoIterator for &'a S2 { -//~^ into_iter_without_iter + //~^ into_iter_without_iter type IntoIter = std::slice::Iter<'a, T>; type Item = &'a T; fn into_iter(self) -> Self::IntoIter { @@ -33,7 +33,7 @@ impl<'a, T> IntoIterator for &'a S2 { } } impl<'a, T> IntoIterator for &'a mut S2 { -//~^ into_iter_without_iter + //~^ into_iter_without_iter type IntoIter = std::slice::IterMut<'a, T>; type Item = &'a mut T; fn into_iter(self) -> Self::IntoIter { @@ -84,7 +84,7 @@ impl<'a, T> IntoIterator for &S4<'a, T> { } impl<'a, T> IntoIterator for &mut S4<'a, T> { -//~^ into_iter_without_iter + //~^ into_iter_without_iter type IntoIter = std::slice::IterMut<'a, T>; type Item = &'a mut T; fn into_iter(self) -> Self::IntoIter { @@ -118,7 +118,7 @@ pub struct Issue12037; macro_rules! generate_impl { () => { impl<'a> IntoIterator for &'a Issue12037 { - //~^ into_iter_without_iter + //~^ into_iter_without_iter type IntoIter = std::slice::Iter<'a, u8>; type Item = &'a u8; fn into_iter(self) -> Self::IntoIter { diff --git a/tests/ui/invalid_upcast_comparisons.rs b/tests/ui/invalid_upcast_comparisons.rs index bb2166862efc..4f3194869f43 100644 --- a/tests/ui/invalid_upcast_comparisons.rs +++ b/tests/ui/invalid_upcast_comparisons.rs @@ -21,7 +21,6 @@ fn main() { (u8 as u32) > 300; //~^ invalid_upcast_comparisons - (u8 as i32) > 300; //~^ invalid_upcast_comparisons @@ -68,7 +67,6 @@ fn main() { 300 != (u8 as i32); //~^ invalid_upcast_comparisons - // always false, since u8 -> i32 doesn't wrap (u8 as i32) < 0; //~^ invalid_upcast_comparisons @@ -83,7 +81,6 @@ fn main() { -5 == (u8 as i32); //~^ invalid_upcast_comparisons - // always false, since no u8 can be 1337 1337 == (u8 as i32); //~^ invalid_upcast_comparisons @@ -98,7 +95,6 @@ fn main() { 1337 != (u8 as u32); //~^ invalid_upcast_comparisons - // Those are Ok: (u8 as u32) > 20; 42 == (u8 as i32); @@ -135,6 +131,5 @@ fn main() { -5 >= (u8 as i32); //~^ invalid_upcast_comparisons - -5 == (u32 as i32); } diff --git a/tests/ui/invalid_upcast_comparisons.stderr b/tests/ui/invalid_upcast_comparisons.stderr index 911022c005c9..ef36f18eabc9 100644 --- a/tests/ui/invalid_upcast_comparisons.stderr +++ b/tests/ui/invalid_upcast_comparisons.stderr @@ -8,157 +8,157 @@ LL | (u8 as u32) > 300; = help: to override `-D warnings` add `#[allow(clippy::invalid_upcast_comparisons)]` error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:25:5 + --> tests/ui/invalid_upcast_comparisons.rs:24:5 | LL | (u8 as i32) > 300; | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:28:5 + --> tests/ui/invalid_upcast_comparisons.rs:27:5 | LL | (u8 as u32) == 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:31:5 + --> tests/ui/invalid_upcast_comparisons.rs:30:5 | LL | (u8 as i32) == 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:34:5 + --> tests/ui/invalid_upcast_comparisons.rs:33:5 | LL | 300 < (u8 as u32); | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:37:5 + --> tests/ui/invalid_upcast_comparisons.rs:36:5 | LL | 300 < (u8 as i32); | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:40:5 + --> tests/ui/invalid_upcast_comparisons.rs:39:5 | LL | 300 == (u8 as u32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:43:5 + --> tests/ui/invalid_upcast_comparisons.rs:42:5 | LL | 300 == (u8 as i32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:47:5 + --> tests/ui/invalid_upcast_comparisons.rs:46:5 | LL | (u8 as u32) <= 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:50:5 + --> tests/ui/invalid_upcast_comparisons.rs:49:5 | LL | (u8 as i32) <= 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:53:5 + --> tests/ui/invalid_upcast_comparisons.rs:52:5 | LL | (u8 as u32) != 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:56:5 + --> tests/ui/invalid_upcast_comparisons.rs:55:5 | LL | (u8 as i32) != 300; | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:59:5 + --> tests/ui/invalid_upcast_comparisons.rs:58:5 | LL | 300 >= (u8 as u32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:62:5 + --> tests/ui/invalid_upcast_comparisons.rs:61:5 | LL | 300 >= (u8 as i32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:65:5 + --> tests/ui/invalid_upcast_comparisons.rs:64:5 | LL | 300 != (u8 as u32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:68:5 + --> tests/ui/invalid_upcast_comparisons.rs:67:5 | LL | 300 != (u8 as i32); | ^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:73:5 + --> tests/ui/invalid_upcast_comparisons.rs:71:5 | LL | (u8 as i32) < 0; | ^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:76:5 + --> tests/ui/invalid_upcast_comparisons.rs:74:5 | LL | -5 != (u8 as i32); | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:80:5 + --> tests/ui/invalid_upcast_comparisons.rs:78:5 | LL | (u8 as i32) >= 0; | ^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:83:5 + --> tests/ui/invalid_upcast_comparisons.rs:81:5 | LL | -5 == (u8 as i32); | ^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:88:5 + --> tests/ui/invalid_upcast_comparisons.rs:85:5 | LL | 1337 == (u8 as i32); | ^^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:91:5 + --> tests/ui/invalid_upcast_comparisons.rs:88:5 | LL | 1337 == (u8 as u32); | ^^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:95:5 + --> tests/ui/invalid_upcast_comparisons.rs:92:5 | LL | 1337 != (u8 as i32); | ^^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:98:5 + --> tests/ui/invalid_upcast_comparisons.rs:95:5 | LL | 1337 != (u8 as u32); | ^^^^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always true - --> tests/ui/invalid_upcast_comparisons.rs:114:5 + --> tests/ui/invalid_upcast_comparisons.rs:110:5 | LL | (u8 as i32) > -1; | ^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:117:5 + --> tests/ui/invalid_upcast_comparisons.rs:113:5 | LL | (u8 as i32) < -1; | ^^^^^^^^^^^^^^^^ error: because of the numeric bounds on `u8` prior to casting, this expression is always false - --> tests/ui/invalid_upcast_comparisons.rs:135:5 + --> tests/ui/invalid_upcast_comparisons.rs:131:5 | LL | -5 >= (u8 as i32); | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issue-7447.rs b/tests/ui/issue-7447.rs index 25ace345ad14..452011de1195 100644 --- a/tests/ui/issue-7447.rs +++ b/tests/ui/issue-7447.rs @@ -26,8 +26,6 @@ fn main() { byte_view(panic!()); //~^ diverging_sub_expression - group_entries(panic!()); //~^ diverging_sub_expression - } diff --git a/tests/ui/issue-7447.stderr b/tests/ui/issue-7447.stderr index 1ba53631b52d..5e28c1423840 100644 --- a/tests/ui/issue-7447.stderr +++ b/tests/ui/issue-7447.stderr @@ -9,7 +9,7 @@ LL | byte_view(panic!()); = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: sub-expression diverges - --> tests/ui/issue-7447.rs:30:19 + --> tests/ui/issue-7447.rs:29:19 | LL | group_entries(panic!()); | ^^^^^^^^ diff --git a/tests/ui/issue_2356.fixed b/tests/ui/issue_2356.fixed index c96d3c1a24f9..46ba653eba2c 100644 --- a/tests/ui/issue_2356.fixed +++ b/tests/ui/issue_2356.fixed @@ -15,7 +15,7 @@ impl Foo { fn foo2>(mut it: I) { for e in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{:?}", e); } } diff --git a/tests/ui/issue_2356.rs b/tests/ui/issue_2356.rs index a4040cb37ced..defe2584a93e 100644 --- a/tests/ui/issue_2356.rs +++ b/tests/ui/issue_2356.rs @@ -15,7 +15,7 @@ impl Foo { fn foo2>(mut it: I) { while let Some(e) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{:?}", e); } } diff --git a/tests/ui/issue_4266.rs b/tests/ui/issue_4266.rs index aabf72a93ce2..664f0b84a207 100644 --- a/tests/ui/issue_4266.rs +++ b/tests/ui/issue_4266.rs @@ -4,12 +4,11 @@ async fn sink1<'a>(_: &'a str) {} // lint //~^ needless_lifetimes - async fn sink1_elided(_: &str) {} // ok // lint async fn one_to_one<'a>(s: &'a str) -> &'a str { -//~^ needless_lifetimes + //~^ needless_lifetimes s } @@ -31,7 +30,7 @@ struct Foo; impl Foo { // ok pub async fn new(&mut self) -> Self { - //~^ wrong_self_convention + //~^ wrong_self_convention Foo {} } diff --git a/tests/ui/issue_4266.stderr b/tests/ui/issue_4266.stderr index ce0588521810..0e181025430f 100644 --- a/tests/ui/issue_4266.stderr +++ b/tests/ui/issue_4266.stderr @@ -8,13 +8,13 @@ LL | async fn sink1<'a>(_: &'a str) {} // lint = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]` error: the following explicit lifetimes could be elided: 'a - --> tests/ui/issue_4266.rs:11:21 + --> tests/ui/issue_4266.rs:10:21 | LL | async fn one_to_one<'a>(s: &'a str) -> &'a str { | ^^ ^^ ^^ error: methods called `new` usually take no `self` - --> tests/ui/issue_4266.rs:33:22 + --> tests/ui/issue_4266.rs:32:22 | LL | pub async fn new(&mut self) -> Self { | ^^^^^^^^^ diff --git a/tests/ui/items_after_statement.rs b/tests/ui/items_after_statement.rs index db3583464e9a..b97c831f37ec 100644 --- a/tests/ui/items_after_statement.rs +++ b/tests/ui/items_after_statement.rs @@ -11,8 +11,7 @@ fn ok() { fn last() { foo(); fn foo() { - //~^ items_after_statements - + //~^ items_after_statements println!("foo"); } @@ -21,7 +20,7 @@ fn last() { fn main() { foo(); fn foo() { - //~^ items_after_statements + //~^ items_after_statements println!("foo"); } @@ -36,7 +35,7 @@ fn mac() { () => {{ a = 6; fn say_something() { - //~^ items_after_statements + //~^ items_after_statements println!("something"); } }}; diff --git a/tests/ui/items_after_statement.stderr b/tests/ui/items_after_statement.stderr index d6186f1305a0..7a5ae2c8d47d 100644 --- a/tests/ui/items_after_statement.stderr +++ b/tests/ui/items_after_statement.stderr @@ -2,7 +2,9 @@ error: adding items after statements is confusing, since items exist from the st --> tests/ui/items_after_statement.rs:13:5 | LL | / fn foo() { -... | +LL | | +LL | | +LL | | println!("foo"); LL | | } | |_____^ | @@ -10,7 +12,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::items_after_statements)]` error: adding items after statements is confusing, since items exist from the start of the scope - --> tests/ui/items_after_statement.rs:23:5 + --> tests/ui/items_after_statement.rs:22:5 | LL | / fn foo() { LL | | @@ -20,7 +22,7 @@ LL | | } | |_____^ error: adding items after statements is confusing, since items exist from the start of the scope - --> tests/ui/items_after_statement.rs:38:13 + --> tests/ui/items_after_statement.rs:37:13 | LL | / fn say_something() { LL | | diff --git a/tests/ui/items_after_test_module/root_module.fixed b/tests/ui/items_after_test_module/root_module.fixed index 25eff3d38f76..f036b368a667 100644 --- a/tests/ui/items_after_test_module/root_module.fixed +++ b/tests/ui/items_after_test_module/root_module.fixed @@ -17,7 +17,7 @@ macro_rules! should_lint { #[allow(clippy::allow_attributes)] #[cfg(test)] mod tests { -//~^ items_after_test_module + //~^ items_after_test_module #[test] fn hi() {} } diff --git a/tests/ui/items_after_test_module/root_module.rs b/tests/ui/items_after_test_module/root_module.rs index 94afffd92de5..de0cbb120330 100644 --- a/tests/ui/items_after_test_module/root_module.rs +++ b/tests/ui/items_after_test_module/root_module.rs @@ -10,7 +10,7 @@ fn should_not_lint() {} #[allow(clippy::allow_attributes)] #[cfg(test)] mod tests { -//~^ items_after_test_module + //~^ items_after_test_module #[test] fn hi() {} } diff --git a/tests/ui/iter_filter_is_ok.fixed b/tests/ui/iter_filter_is_ok.fixed index d3aeeff7d7b4..3223e19d23a7 100644 --- a/tests/ui/iter_filter_is_ok.fixed +++ b/tests/ui/iter_filter_is_ok.fixed @@ -17,55 +17,46 @@ fn main() { #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().flatten(); //~^ iter_filter_is_ok - } { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); //~^ iter_filter_is_ok - let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); //~^ iter_filter_is_ok - #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().flatten(); //~^ iter_filter_is_ok - } { let _ = vec![Ok(1), Err(2), Ok(3)] .into_iter() .flatten(); - //~^ iter_filter_is_ok - + //~^ iter_filter_is_ok let _ = vec![Ok(1), Err(2), Ok(3)] .into_iter() .flatten(); - //~^ iter_filter_is_ok + //~^ iter_filter_is_ok #[rustfmt::skip] let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); //~^ iter_filter_is_ok - } { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); //~^ iter_filter_is_ok - let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten(); //~^ iter_filter_is_ok - #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().flatten(); //~^ iter_filter_is_ok - } } diff --git a/tests/ui/iter_filter_is_ok.rs b/tests/ui/iter_filter_is_ok.rs index 7ed974876693..973653819850 100644 --- a/tests/ui/iter_filter_is_ok.rs +++ b/tests/ui/iter_filter_is_ok.rs @@ -17,55 +17,46 @@ fn main() { #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| { o.is_ok() }); //~^ iter_filter_is_ok - } { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok()); //~^ iter_filter_is_ok - let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok()); //~^ iter_filter_is_ok - #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().filter(|&o| { o.is_ok() }); //~^ iter_filter_is_ok - } { let _ = vec![Ok(1), Err(2), Ok(3)] .into_iter() .filter(std::result::Result::is_ok); - //~^ iter_filter_is_ok - + //~^ iter_filter_is_ok let _ = vec![Ok(1), Err(2), Ok(3)] .into_iter() .filter(|a| std::result::Result::is_ok(a)); - //~^ iter_filter_is_ok + //~^ iter_filter_is_ok #[rustfmt::skip] let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| { std::result::Result::is_ok(a) }); //~^ iter_filter_is_ok - } { let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok()); //~^ iter_filter_is_ok - let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok()); //~^ iter_filter_is_ok - #[rustfmt::skip] let _ = vec![Ok(1), Err(2)].into_iter().filter(|ref o| { o.is_ok() }); //~^ iter_filter_is_ok - } } diff --git a/tests/ui/iter_filter_is_ok.stderr b/tests/ui/iter_filter_is_ok.stderr index 56c60c093a4b..b7fd0d25cc23 100644 --- a/tests/ui/iter_filter_is_ok.stderr +++ b/tests/ui/iter_filter_is_ok.stderr @@ -20,55 +20,55 @@ LL | let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| { o.is_ok() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:24:56 + --> tests/ui/iter_filter_is_ok.rs:23:56 | LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:28:56 + --> tests/ui/iter_filter_is_ok.rs:26:56 | LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:33:49 + --> tests/ui/iter_filter_is_ok.rs:30:49 | LL | let _ = vec![Ok(1), Err(2)].into_iter().filter(|&o| { o.is_ok() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:41:14 + --> tests/ui/iter_filter_is_ok.rs:37:14 | LL | .filter(std::result::Result::is_ok); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:47:14 + --> tests/ui/iter_filter_is_ok.rs:42:14 | LL | .filter(|a| std::result::Result::is_ok(a)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:51:56 + --> tests/ui/iter_filter_is_ok.rs:46:56 | LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| { std::result::Result::is_ok(a) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:57:56 + --> tests/ui/iter_filter_is_ok.rs:51:56 | LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:61:56 + --> tests/ui/iter_filter_is_ok.rs:54:56 | LL | let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_ok` on iterator over `Result`s - --> tests/ui/iter_filter_is_ok.rs:66:49 + --> tests/ui/iter_filter_is_ok.rs:58:49 | LL | let _ = vec![Ok(1), Err(2)].into_iter().filter(|ref o| { o.is_ok() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` diff --git a/tests/ui/iter_filter_is_some.fixed b/tests/ui/iter_filter_is_some.fixed index f76e7a619079..99e764e957fb 100644 --- a/tests/ui/iter_filter_is_some.fixed +++ b/tests/ui/iter_filter_is_some.fixed @@ -21,47 +21,40 @@ fn main() { #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); //~^ iter_filter_is_some - } { let _ = vec![Some(1), None, Some(3)] .into_iter() .flatten(); - //~^ iter_filter_is_some - + //~^ iter_filter_is_some let _ = vec![Some(1), None, Some(3)] .into_iter() .flatten(); - //~^ iter_filter_is_some + //~^ iter_filter_is_some #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); //~^ iter_filter_is_some - } { let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); //~^ iter_filter_is_some - #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); //~^ iter_filter_is_some - } { let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); //~^ iter_filter_is_some - #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().flatten(); //~^ iter_filter_is_some - } } diff --git a/tests/ui/iter_filter_is_some.rs b/tests/ui/iter_filter_is_some.rs index 536af0021420..ecb7a04ab4df 100644 --- a/tests/ui/iter_filter_is_some.rs +++ b/tests/ui/iter_filter_is_some.rs @@ -21,47 +21,40 @@ fn main() { #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| { o.is_some() }); //~^ iter_filter_is_some - } { let _ = vec![Some(1), None, Some(3)] .into_iter() .filter(std::option::Option::is_some); - //~^ iter_filter_is_some - + //~^ iter_filter_is_some let _ = vec![Some(1), None, Some(3)] .into_iter() .filter(|a| std::option::Option::is_some(a)); - //~^ iter_filter_is_some + //~^ iter_filter_is_some #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| { std::option::Option::is_some(a) }); //~^ iter_filter_is_some - } { let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&a| a.is_some()); //~^ iter_filter_is_some - #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&o| { o.is_some() }); //~^ iter_filter_is_some - } { let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref a| a.is_some()); //~^ iter_filter_is_some - #[rustfmt::skip] let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref o| { o.is_some() }); //~^ iter_filter_is_some - } } diff --git a/tests/ui/iter_filter_is_some.stderr b/tests/ui/iter_filter_is_some.stderr index d1653fe1b7a3..cd01a3e05cd0 100644 --- a/tests/ui/iter_filter_is_some.stderr +++ b/tests/ui/iter_filter_is_some.stderr @@ -20,43 +20,43 @@ LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| { o.is_ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:30:14 + --> tests/ui/iter_filter_is_some.rs:29:14 | LL | .filter(std::option::Option::is_some); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:36:14 + --> tests/ui/iter_filter_is_some.rs:34:14 | LL | .filter(|a| std::option::Option::is_some(a)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:40:58 + --> tests/ui/iter_filter_is_some.rs:38:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| { std::option::Option::is_some(a) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:46:58 + --> tests/ui/iter_filter_is_some.rs:43:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&a| a.is_some()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:51:58 + --> tests/ui/iter_filter_is_some.rs:47:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&o| { o.is_some() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:57:58 + --> tests/ui/iter_filter_is_some.rs:52:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref a| a.is_some()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `is_some` on iterator over `Option` - --> tests/ui/iter_filter_is_some.rs:62:58 + --> tests/ui/iter_filter_is_some.rs:56:58 | LL | let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref o| { o.is_some() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` diff --git a/tests/ui/iter_kv_map.fixed b/tests/ui/iter_kv_map.fixed index b9d86d8dd803..7fcab6592e26 100644 --- a/tests/ui/iter_kv_map.fixed +++ b/tests/ui/iter_kv_map.fixed @@ -52,7 +52,7 @@ fn main() { // Preserve the mut in the fix. let _ = map - //~^ iter_kv_map + //~^ iter_kv_map .clone().into_values().map(|mut val| { val += 2; val @@ -106,7 +106,7 @@ fn main() { // Preserve the mut in the fix. let _ = map - //~^ iter_kv_map + //~^ iter_kv_map .clone().into_values().map(|mut val| { val += 2; val @@ -138,7 +138,6 @@ fn msrv_1_53() { let _ = map.values().map(|v| v + 2).collect::>(); //~^ iter_kv_map - } #[clippy::msrv = "1.54"] @@ -152,14 +151,12 @@ fn msrv_1_54() { let _ = map.clone().into_keys().map(|key| key + 2).collect::>(); //~^ iter_kv_map - let _ = map.clone().into_values().collect::>(); //~^ iter_kv_map let _ = map.clone().into_values().map(|val| val + 2).collect::>(); //~^ iter_kv_map - let _ = map.keys().collect::>(); //~^ iter_kv_map @@ -168,5 +165,4 @@ fn msrv_1_54() { let _ = map.values().map(|v| v + 2).collect::>(); //~^ iter_kv_map - } diff --git a/tests/ui/iter_kv_map.rs b/tests/ui/iter_kv_map.rs index b14786180b1f..b590aef7b803 100644 --- a/tests/ui/iter_kv_map.rs +++ b/tests/ui/iter_kv_map.rs @@ -52,7 +52,7 @@ fn main() { // Preserve the mut in the fix. let _ = map - //~^ iter_kv_map + //~^ iter_kv_map .clone() .into_iter() .map(|(_, mut val)| { @@ -108,7 +108,7 @@ fn main() { // Preserve the mut in the fix. let _ = map - //~^ iter_kv_map + //~^ iter_kv_map .clone() .into_iter() .map(|(_, mut val)| { @@ -142,7 +142,6 @@ fn msrv_1_53() { let _ = map.iter().map(|(_, v)| v + 2).collect::>(); //~^ iter_kv_map - } #[clippy::msrv = "1.54"] @@ -156,14 +155,12 @@ fn msrv_1_54() { let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); //~^ iter_kv_map - let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); //~^ iter_kv_map let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); //~^ iter_kv_map - let _ = map.iter().map(|(key, _)| key).collect::>(); //~^ iter_kv_map @@ -172,5 +169,4 @@ fn msrv_1_54() { let _ = map.iter().map(|(_, v)| v + 2).collect::>(); //~^ iter_kv_map - } diff --git a/tests/ui/iter_kv_map.stderr b/tests/ui/iter_kv_map.stderr index d99fea1124a7..00d566ed14a2 100644 --- a/tests/ui/iter_kv_map.stderr +++ b/tests/ui/iter_kv_map.stderr @@ -222,43 +222,43 @@ LL | let _ = map.iter().map(|(_, v)| v + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:153:13 + --> tests/ui/iter_kv_map.rs:152:13 | LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:156:13 + --> tests/ui/iter_kv_map.rs:155:13 | LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:160:13 + --> tests/ui/iter_kv_map.rs:158:13 | LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:163:13 + --> tests/ui/iter_kv_map.rs:161:13 | LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:167:13 + --> tests/ui/iter_kv_map.rs:164:13 | LL | let _ = map.iter().map(|(key, _)| key).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:170:13 + --> tests/ui/iter_kv_map.rs:167:13 | LL | let _ = map.iter().map(|(_, value)| value).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:173:13 + --> tests/ui/iter_kv_map.rs:170:13 | LL | let _ = map.iter().map(|(_, v)| v + 2).collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` diff --git a/tests/ui/iter_not_returning_iterator.rs b/tests/ui/iter_not_returning_iterator.rs index 4c0c667be80f..5c8c8eb4a43d 100644 --- a/tests/ui/iter_not_returning_iterator.rs +++ b/tests/ui/iter_not_returning_iterator.rs @@ -28,14 +28,13 @@ struct Counter2 { impl Data2 { fn iter(&self) -> Counter2 { - //~^ iter_not_returning_iterator - + //~^ iter_not_returning_iterator todo!() } fn iter_mut(&self) -> Counter2 { - //~^ iter_not_returning_iterator + //~^ iter_not_returning_iterator todo!() } @@ -54,7 +53,6 @@ trait Iter { type I; fn iter(&self) -> Self::I; //~^ iter_not_returning_iterator - } impl Iter for () { diff --git a/tests/ui/iter_not_returning_iterator.stderr b/tests/ui/iter_not_returning_iterator.stderr index 8c0ebd847110..74ee8325d53e 100644 --- a/tests/ui/iter_not_returning_iterator.stderr +++ b/tests/ui/iter_not_returning_iterator.stderr @@ -8,13 +8,13 @@ LL | fn iter(&self) -> Counter2 { = help: to override `-D warnings` add `#[allow(clippy::iter_not_returning_iterator)]` error: this method is named `iter_mut` but its return type does not implement `Iterator` - --> tests/ui/iter_not_returning_iterator.rs:37:5 + --> tests/ui/iter_not_returning_iterator.rs:36:5 | LL | fn iter_mut(&self) -> Counter2 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this method is named `iter` but its return type does not implement `Iterator` - --> tests/ui/iter_not_returning_iterator.rs:55:5 + --> tests/ui/iter_not_returning_iterator.rs:54:5 | LL | fn iter(&self) -> Self::I; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/iter_on_empty_collections.fixed b/tests/ui/iter_on_empty_collections.fixed index e1e4e331843b..0c2100034e18 100644 --- a/tests/ui/iter_on_empty_collections.fixed +++ b/tests/ui/iter_on_empty_collections.fixed @@ -32,7 +32,7 @@ fn array() { // Don't trigger when the empty collection iter is relied upon for its concrete type // But do trigger if it is just an iterator, despite being an argument to a method for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain(std::iter::empty()) { - //~^ iter_on_empty_collections + //~^ iter_on_empty_collections println!("{i}"); } diff --git a/tests/ui/iter_on_empty_collections.rs b/tests/ui/iter_on_empty_collections.rs index 3a4ad7fb372a..0fb7a32d3691 100644 --- a/tests/ui/iter_on_empty_collections.rs +++ b/tests/ui/iter_on_empty_collections.rs @@ -32,7 +32,7 @@ fn array() { // Don't trigger when the empty collection iter is relied upon for its concrete type // But do trigger if it is just an iterator, despite being an argument to a method for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain([].iter()) { - //~^ iter_on_empty_collections + //~^ iter_on_empty_collections println!("{i}"); } diff --git a/tests/ui/iter_out_of_bounds.rs b/tests/ui/iter_out_of_bounds.rs index 243dce9939c1..b34e4ad78240 100644 --- a/tests/ui/iter_out_of_bounds.rs +++ b/tests/ui/iter_out_of_bounds.rs @@ -10,12 +10,12 @@ fn opaque_empty_iter() -> impl Iterator { fn main() { #[allow(clippy::never_loop)] for _ in [1, 2, 3].iter().skip(4) { - //~^ iter_out_of_bounds + //~^ iter_out_of_bounds unreachable!(); } for (i, _) in [1, 2, 3].iter().take(4).enumerate() { - //~^ iter_out_of_bounds + //~^ iter_out_of_bounds assert!(i <= 2); } @@ -24,56 +24,45 @@ fn main() { for _ in (&&&&&&[1, 2, 3]).iter().take(4) {} //~^ iter_out_of_bounds - for _ in [1, 2, 3].iter().skip(4) {} //~^ iter_out_of_bounds - for _ in [1; 3].iter().skip(4) {} //~^ iter_out_of_bounds - // Should not lint for _ in opaque_empty_iter().skip(1) {} for _ in vec![1, 2, 3].iter().skip(4) {} //~^ iter_out_of_bounds - for _ in vec![1; 3].iter().skip(4) {} //~^ iter_out_of_bounds - let x = [1, 2, 3]; for _ in x.iter().skip(4) {} //~^ iter_out_of_bounds - let n = 4; for _ in x.iter().skip(n) {} //~^ iter_out_of_bounds - let empty = std::iter::empty::; for _ in empty().skip(1) {} //~^ iter_out_of_bounds - for _ in empty().take(1) {} //~^ iter_out_of_bounds - for _ in std::iter::once(1).skip(2) {} //~^ iter_out_of_bounds - for _ in std::iter::once(1).take(2) {} //~^ iter_out_of_bounds - for x in [].iter().take(1) { - //~^ iter_out_of_bounds + //~^ iter_out_of_bounds let _: &i32 = x; } diff --git a/tests/ui/iter_out_of_bounds.stderr b/tests/ui/iter_out_of_bounds.stderr index 42984e00e1d4..19ac60b9d0ac 100644 --- a/tests/ui/iter_out_of_bounds.stderr +++ b/tests/ui/iter_out_of_bounds.stderr @@ -28,7 +28,7 @@ LL | for _ in (&&&&&&[1, 2, 3]).iter().take(4) {} = note: this operation is useless and the returned iterator will simply yield the same items error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:28:14 + --> tests/ui/iter_out_of_bounds.rs:27:14 | LL | for _ in [1, 2, 3].iter().skip(4) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | for _ in [1, 2, 3].iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:32:14 + --> tests/ui/iter_out_of_bounds.rs:30:14 | LL | for _ in [1; 3].iter().skip(4) {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | for _ in [1; 3].iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:39:14 + --> tests/ui/iter_out_of_bounds.rs:36:14 | LL | for _ in vec![1, 2, 3].iter().skip(4) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | for _ in vec![1, 2, 3].iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:43:14 + --> tests/ui/iter_out_of_bounds.rs:39:14 | LL | for _ in vec![1; 3].iter().skip(4) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | for _ in vec![1; 3].iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:48:14 + --> tests/ui/iter_out_of_bounds.rs:43:14 | LL | for _ in x.iter().skip(4) {} | ^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | for _ in x.iter().skip(4) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:53:14 + --> tests/ui/iter_out_of_bounds.rs:47:14 | LL | for _ in x.iter().skip(n) {} | ^^^^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | for _ in x.iter().skip(n) {} = note: this operation is useless and will create an empty iterator error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:59:14 + --> tests/ui/iter_out_of_bounds.rs:52:14 | LL | for _ in empty().skip(1) {} | ^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | for _ in empty().skip(1) {} = note: this operation is useless and will create an empty iterator error: this `.take()` call takes more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:63:14 + --> tests/ui/iter_out_of_bounds.rs:55:14 | LL | for _ in empty().take(1) {} | ^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL | for _ in empty().take(1) {} = note: this operation is useless and the returned iterator will simply yield the same items error: this `.skip()` call skips more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:67:14 + --> tests/ui/iter_out_of_bounds.rs:58:14 | LL | for _ in std::iter::once(1).skip(2) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | for _ in std::iter::once(1).skip(2) {} = note: this operation is useless and will create an empty iterator error: this `.take()` call takes more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:71:14 + --> tests/ui/iter_out_of_bounds.rs:61:14 | LL | for _ in std::iter::once(1).take(2) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | for _ in std::iter::once(1).take(2) {} = note: this operation is useless and the returned iterator will simply yield the same items error: this `.take()` call takes more items than the iterator will produce - --> tests/ui/iter_out_of_bounds.rs:75:14 + --> tests/ui/iter_out_of_bounds.rs:64:14 | LL | for x in [].iter().take(1) { | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/iter_over_hash_type.rs b/tests/ui/iter_over_hash_type.rs index 0dd9544cfe01..914cc9df0de9 100644 --- a/tests/ui/iter_over_hash_type.rs +++ b/tests/ui/iter_over_hash_type.rs @@ -16,59 +16,59 @@ fn main() { // test hashset for x in &hash_set { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } for x in hash_set.iter() { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } for x in hash_set.clone() { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } for x in hash_set.drain() { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } // test hashmap for (x, y) in &hash_map { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = (x, y); } for x in hash_map.keys() { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } for x in hash_map.values() { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } for x in hash_map.values_mut() { - //~^ iter_over_hash_type + //~^ iter_over_hash_type *x += 1; } for x in hash_map.iter() { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } for x in hash_map.clone() { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } for x in hash_map.drain() { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } // test type-aliased hashers for x in fx_hash_set { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } for x in fx_hash_map { - //~^ iter_over_hash_type + //~^ iter_over_hash_type let _ = x; } diff --git a/tests/ui/iter_overeager_cloned.fixed b/tests/ui/iter_overeager_cloned.fixed index bc6cf76a58d8..999912690290 100644 --- a/tests/ui/iter_overeager_cloned.fixed +++ b/tests/ui/iter_overeager_cloned.fixed @@ -28,7 +28,7 @@ fn main() { //~^ iter_overeager_cloned let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))] - //~^ iter_overeager_cloned + //~^ iter_overeager_cloned .iter() .flatten().cloned(); diff --git a/tests/ui/iter_overeager_cloned.rs b/tests/ui/iter_overeager_cloned.rs index 094760893c3e..6a860dad5afd 100644 --- a/tests/ui/iter_overeager_cloned.rs +++ b/tests/ui/iter_overeager_cloned.rs @@ -28,7 +28,7 @@ fn main() { //~^ iter_overeager_cloned let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))] - //~^ iter_overeager_cloned + //~^ iter_overeager_cloned .iter() .cloned() .flatten(); diff --git a/tests/ui/iter_skip_next_unfixable.rs b/tests/ui/iter_skip_next_unfixable.rs index 273ccd25ddcc..3f855b54d12a 100644 --- a/tests/ui/iter_skip_next_unfixable.rs +++ b/tests/ui/iter_skip_next_unfixable.rs @@ -12,7 +12,6 @@ fn main() { if let Some(s) = Some(test_string.split('|').map(|s| s.trim())) { let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); //~^ iter_skip_next - }; fn check(s: T) where @@ -20,6 +19,5 @@ fn main() { { let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); //~^ iter_skip_next - } } diff --git a/tests/ui/iter_skip_next_unfixable.stderr b/tests/ui/iter_skip_next_unfixable.stderr index cfbf75d85304..44c5c1f85442 100644 --- a/tests/ui/iter_skip_next_unfixable.stderr +++ b/tests/ui/iter_skip_next_unfixable.stderr @@ -25,13 +25,13 @@ LL | if let Some(s) = Some(test_string.split('|').map(|s| s.trim())) { | ^ error: called `skip(..).next()` on an iterator - --> tests/ui/iter_skip_next_unfixable.rs:21:29 + --> tests/ui/iter_skip_next_unfixable.rs:20:29 | LL | let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` | help: for this change `s` has to be mutable - --> tests/ui/iter_skip_next_unfixable.rs:17:17 + --> tests/ui/iter_skip_next_unfixable.rs:16:17 | LL | fn check(s: T) | ^ diff --git a/tests/ui/iter_without_into_iter.rs b/tests/ui/iter_without_into_iter.rs index 80fb736b9bde..dc3149be2cb4 100644 --- a/tests/ui/iter_without_into_iter.rs +++ b/tests/ui/iter_without_into_iter.rs @@ -7,11 +7,11 @@ extern crate proc_macros; pub struct S1; impl S1 { pub fn iter(&self) -> std::slice::Iter<'_, u8> { - //~^ iter_without_into_iter + //~^ iter_without_into_iter [].iter() } pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { - //~^ iter_without_into_iter + //~^ iter_without_into_iter [].iter_mut() } } @@ -27,11 +27,11 @@ impl S2 { pub struct S3<'a>(&'a mut [u8]); impl<'a> S3<'a> { pub fn iter(&self) -> std::slice::Iter<'_, u8> { - //~^ iter_without_into_iter + //~^ iter_without_into_iter self.0.iter() } pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { - //~^ iter_without_into_iter + //~^ iter_without_into_iter self.0.iter_mut() } } @@ -68,7 +68,7 @@ impl S7 { pub struct S8(T); impl S8 { pub fn iter(&self) -> std::slice::Iter<'static, T> { - //~^ iter_without_into_iter + //~^ iter_without_into_iter todo!() } } @@ -77,11 +77,11 @@ impl S8 { pub struct S9(T); impl S9 { pub fn iter(&self) -> std::slice::Iter<'_, T> { - //~^ iter_without_into_iter + //~^ iter_without_into_iter todo!() } pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { - //~^ iter_without_into_iter + //~^ iter_without_into_iter todo!() } } @@ -130,7 +130,7 @@ macro_rules! generate_impl { () => { impl Issue12037 { fn iter(&self) -> std::slice::Iter<'_, u8> { - //~^ iter_without_into_iter + //~^ iter_without_into_iter todo!() } } diff --git a/tests/ui/iterator_step_by_zero.rs b/tests/ui/iterator_step_by_zero.rs index c416095cb426..a729101bd403 100644 --- a/tests/ui/iterator_step_by_zero.rs +++ b/tests/ui/iterator_step_by_zero.rs @@ -4,14 +4,12 @@ fn main() { let _ = vec!["A", "B", "B"].iter().step_by(0); //~^ iterator_step_by_zero - let _ = "XXX".chars().step_by(0); //~^ iterator_step_by_zero let _ = (0..1).step_by(0); //~^ iterator_step_by_zero - // No error, not an iterator. let y = NotIterator; y.step_by(0); @@ -25,17 +23,14 @@ fn main() { let _ = (1..=2).step_by(0); //~^ iterator_step_by_zero - let x = 0..1; let _ = x.step_by(0); //~^ iterator_step_by_zero - // check const eval let v1 = vec![1, 2, 3]; let _ = v1.iter().step_by(2 / 3); //~^ iterator_step_by_zero - } struct NotIterator; diff --git a/tests/ui/iterator_step_by_zero.stderr b/tests/ui/iterator_step_by_zero.stderr index 8cc79a978bca..0ff916b6dd5e 100644 --- a/tests/ui/iterator_step_by_zero.stderr +++ b/tests/ui/iterator_step_by_zero.stderr @@ -8,37 +8,37 @@ LL | let _ = vec!["A", "B", "B"].iter().step_by(0); = help: to override `-D warnings` add `#[allow(clippy::iterator_step_by_zero)]` error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:8:13 + --> tests/ui/iterator_step_by_zero.rs:7:13 | LL | let _ = "XXX".chars().step_by(0); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:11:13 + --> tests/ui/iterator_step_by_zero.rs:10:13 | LL | let _ = (0..1).step_by(0); | ^^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:22:13 + --> tests/ui/iterator_step_by_zero.rs:20:13 | LL | let _ = (1..).step_by(0); | ^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:25:13 + --> tests/ui/iterator_step_by_zero.rs:23:13 | LL | let _ = (1..=2).step_by(0); | ^^^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:30:13 + --> tests/ui/iterator_step_by_zero.rs:27:13 | LL | let _ = x.step_by(0); | ^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> tests/ui/iterator_step_by_zero.rs:36:13 + --> tests/ui/iterator_step_by_zero.rs:32:13 | LL | let _ = v1.iter().step_by(2 / 3); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/join_absolute_paths.rs b/tests/ui/join_absolute_paths.rs index ada160d963a6..144c9147c2a1 100644 --- a/tests/ui/join_absolute_paths.rs +++ b/tests/ui/join_absolute_paths.rs @@ -10,22 +10,18 @@ fn main() { path.join("/sh"); //~^ join_absolute_paths - let path = Path::new("C:\\Users"); path.join("\\user"); //~^ join_absolute_paths - let path = PathBuf::from("/bin"); path.join("/sh"); //~^ join_absolute_paths - let path = PathBuf::from("/bin"); path.join(r#"/sh"#); //~^ join_absolute_paths - let path: &[&str] = &["/bin"]; path.join("/sh"); diff --git a/tests/ui/join_absolute_paths.stderr b/tests/ui/join_absolute_paths.stderr index 94e8beb38446..e7fd5508823a 100644 --- a/tests/ui/join_absolute_paths.stderr +++ b/tests/ui/join_absolute_paths.stderr @@ -17,7 +17,7 @@ LL | PathBuf::from("/sh"); | ~~~~~~~~~~~~~~~~~~~~ error: argument to `Path::join` starts with a path separator - --> tests/ui/join_absolute_paths.rs:15:15 + --> tests/ui/join_absolute_paths.rs:14:15 | LL | path.join("\\user"); | ^^^^^^^^ @@ -33,7 +33,7 @@ LL | PathBuf::from("\\user"); | ~~~~~~~~~~~~~~~~~~~~~~~ error: argument to `Path::join` starts with a path separator - --> tests/ui/join_absolute_paths.rs:20:15 + --> tests/ui/join_absolute_paths.rs:18:15 | LL | path.join("/sh"); | ^^^^^ @@ -49,7 +49,7 @@ LL | PathBuf::from("/sh"); | ~~~~~~~~~~~~~~~~~~~~ error: argument to `Path::join` starts with a path separator - --> tests/ui/join_absolute_paths.rs:25:15 + --> tests/ui/join_absolute_paths.rs:22:15 | LL | path.join(r#"/sh"#); | ^^^^^^^^ diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs index 0ed562f90bc0..9e0fc03cb4e1 100644 --- a/tests/ui/large_enum_variant.rs +++ b/tests/ui/large_enum_variant.rs @@ -9,7 +9,7 @@ extern crate proc_macros; use proc_macros::external; enum LargeEnum { -//~^ large_enum_variant + //~^ large_enum_variant A(i32), B([i32; 8000]), } @@ -34,26 +34,26 @@ enum LargeEnumGeneric { } enum LargeEnum2 { -//~^ large_enum_variant + //~^ large_enum_variant VariantOk(i32, u32), ContainingLargeEnum(LargeEnum), } enum LargeEnum3 { -//~^ large_enum_variant + //~^ large_enum_variant ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), VoidVariant, StructLikeLittle { x: i32, y: i32 }, } enum LargeEnum4 { -//~^ large_enum_variant + //~^ large_enum_variant VariantOk(i32, u32), StructLikeLarge { x: [i32; 8000], y: i32 }, } enum LargeEnum5 { -//~^ large_enum_variant + //~^ large_enum_variant VariantOk(i32, u32), StructLikeLarge2 { x: [i32; 8000] }, } @@ -70,32 +70,32 @@ enum LargeEnum6 { } enum LargeEnum7 { -//~^ large_enum_variant + //~^ large_enum_variant A, B([u8; 1255]), C([u8; 200]), } enum LargeEnum8 { -//~^ large_enum_variant + //~^ large_enum_variant VariantOk(i32, u32), ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), } enum LargeEnum9 { -//~^ large_enum_variant + //~^ large_enum_variant A(Struct<()>), B(Struct2), } enum LargeEnumOk2 { -//~^ large_enum_variant + //~^ large_enum_variant A(T), B(Struct2), } enum LargeEnumOk3 { -//~^ large_enum_variant + //~^ large_enum_variant A(Struct), B(Struct2), } @@ -111,13 +111,13 @@ struct Struct2 { #[derive(Copy, Clone)] enum CopyableLargeEnum { -//~^ large_enum_variant + //~^ large_enum_variant A(bool), B([u64; 8000]), } enum ManuallyCopyLargeEnum { -//~^ large_enum_variant + //~^ large_enum_variant A(bool), B([u64; 8000]), } @@ -131,7 +131,7 @@ impl Clone for ManuallyCopyLargeEnum { impl Copy for ManuallyCopyLargeEnum {} enum SomeGenericPossiblyCopyEnum { -//~^ large_enum_variant + //~^ large_enum_variant A(bool, std::marker::PhantomData), B([u64; 4000]), } @@ -145,7 +145,7 @@ impl Clone for SomeGenericPossiblyCopyEnum { impl Copy for SomeGenericPossiblyCopyEnum {} enum LargeEnumWithGenerics { -//~^ large_enum_variant + //~^ large_enum_variant Small, Large((T, [u8; 512])), } @@ -155,7 +155,7 @@ struct Foo { } enum WithGenerics { -//~^ large_enum_variant + //~^ large_enum_variant Large([Foo; 64]), Small(u8), } @@ -166,13 +166,13 @@ enum PossiblyLargeEnumWithConst { } enum LargeEnumOfConst { -//~^ large_enum_variant + //~^ large_enum_variant Ok, Error(PossiblyLargeEnumWithConst<256>), } enum WithRecursion { -//~^ large_enum_variant + //~^ large_enum_variant Large([u64; 64]), Recursive(Box), } @@ -183,7 +183,7 @@ enum WithRecursionAndGenerics { } enum LargeEnumWithGenericsAndRecursive { -//~^ large_enum_variant + //~^ large_enum_variant Ok(), Error(WithRecursionAndGenerics), } @@ -219,13 +219,13 @@ mod issue11915 { } enum NoWarnings { - //~^ large_enum_variant + //~^ large_enum_variant BigBoi(PublishWithBytes), _SmallBoi(u8), } enum MakesClippyAngry { - //~^ large_enum_variant + //~^ large_enum_variant BigBoi(PublishWithVec), _SmallBoi(u8), } diff --git a/tests/ui/large_futures.fixed b/tests/ui/large_futures.fixed index dabb96e42918..c2159c58de1e 100644 --- a/tests/ui/large_futures.fixed +++ b/tests/ui/large_futures.fixed @@ -9,12 +9,9 @@ async fn wait() { let f = async { Box::pin(big_fut([0u8; 1024 * 16])).await; //~^ large_futures - - }; Box::pin(f).await //~^ large_futures - } async fn calls_fut(fut: impl std::future::Future) { loop { @@ -26,7 +23,6 @@ async fn calls_fut(fut: impl std::future::Future) { } else { Box::pin(wait()).await; //~^ large_futures - } } } @@ -38,7 +34,6 @@ pub async fn test() { Box::pin(calls_fut(fut)).await; //~^ large_futures - } pub fn foo() -> impl std::future::Future { @@ -51,7 +46,7 @@ pub fn foo() -> impl std::future::Future { pub async fn lines() { Box::pin(async { - //~^ large_futures + //~^ large_futures let x = [0i32; 1024 * 16]; async {}.await; @@ -64,7 +59,7 @@ pub async fn macro_expn() { macro_rules! macro_ { () => { Box::pin(async { - //~^ large_futures + //~^ large_futures let x = [0i32; 1024 * 16]; async {}.await; println!("macro: {:?}", x); diff --git a/tests/ui/large_futures.rs b/tests/ui/large_futures.rs index bafb0e2e3ba5..567f6344afea 100644 --- a/tests/ui/large_futures.rs +++ b/tests/ui/large_futures.rs @@ -9,12 +9,9 @@ async fn wait() { let f = async { big_fut([0u8; 1024 * 16]).await; //~^ large_futures - - }; f.await //~^ large_futures - } async fn calls_fut(fut: impl std::future::Future) { loop { @@ -26,7 +23,6 @@ async fn calls_fut(fut: impl std::future::Future) { } else { wait().await; //~^ large_futures - } } } @@ -38,7 +34,6 @@ pub async fn test() { calls_fut(fut).await; //~^ large_futures - } pub fn foo() -> impl std::future::Future { @@ -51,7 +46,7 @@ pub fn foo() -> impl std::future::Future { pub async fn lines() { async { - //~^ large_futures + //~^ large_futures let x = [0i32; 1024 * 16]; async {}.await; @@ -64,7 +59,7 @@ pub async fn macro_expn() { macro_rules! macro_ { () => { async { - //~^ large_futures + //~^ large_futures let x = [0i32; 1024 * 16]; async {}.await; println!("macro: {:?}", x); diff --git a/tests/ui/large_futures.stderr b/tests/ui/large_futures.stderr index cefc4769e846..fd6ba4e3563d 100644 --- a/tests/ui/large_futures.stderr +++ b/tests/ui/large_futures.stderr @@ -8,37 +8,37 @@ LL | big_fut([0u8; 1024 * 16]).await; = help: to override `-D warnings` add `#[allow(clippy::large_futures)]` error: large future with a size of 16386 bytes - --> tests/ui/large_futures.rs:15:5 + --> tests/ui/large_futures.rs:13:5 | LL | f.await | ^ help: consider `Box::pin` on it: `Box::pin(f)` error: large future with a size of 16387 bytes - --> tests/ui/large_futures.rs:21:9 + --> tests/ui/large_futures.rs:18:9 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 16387 bytes - --> tests/ui/large_futures.rs:27:13 + --> tests/ui/large_futures.rs:24:13 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:36:5 + --> tests/ui/large_futures.rs:32:5 | LL | foo().await; | ^^^^^ help: consider `Box::pin` on it: `Box::pin(foo())` error: large future with a size of 49159 bytes - --> tests/ui/large_futures.rs:39:5 + --> tests/ui/large_futures.rs:35:5 | LL | calls_fut(fut).await; | ^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(calls_fut(fut))` error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:53:5 + --> tests/ui/large_futures.rs:48:5 | LL | / async { LL | | @@ -61,7 +61,7 @@ LL + }) | error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:66:13 + --> tests/ui/large_futures.rs:61:13 | LL | / async { LL | | diff --git a/tests/ui/large_stack_frames.rs b/tests/ui/large_stack_frames.rs index 81d89cc1c5ca..3ed124f69ef3 100644 --- a/tests/ui/large_stack_frames.rs +++ b/tests/ui/large_stack_frames.rs @@ -25,7 +25,7 @@ impl Default for ArrayDefault { } fn many_small_arrays() { -//~^ large_stack_frames + //~^ large_stack_frames let x = [0u8; 500_000]; let x2 = [0u8; 500_000]; @@ -36,13 +36,13 @@ fn many_small_arrays() { } fn large_return_value() -> ArrayDefault<1_000_000> { -//~^ large_stack_frames + //~^ large_stack_frames Default::default() } fn large_fn_arg(x: ArrayDefault<1_000_000>) { -//~^ large_stack_frames + //~^ large_stack_frames black_box(&x); } diff --git a/tests/ui/large_types_passed_by_value.rs b/tests/ui/large_types_passed_by_value.rs index cd0c88b6834c..562a46306e06 100644 --- a/tests/ui/large_types_passed_by_value.rs +++ b/tests/ui/large_types_passed_by_value.rs @@ -62,12 +62,12 @@ fn foo_always(x: LargeAndCopy) { } #[inline(never)] fn foo_never(x: LargeAndCopy) { -//~^ large_types_passed_by_value + //~^ large_types_passed_by_value todo!(); } #[inline] fn foo(x: LargeAndCopy) { -//~^ large_types_passed_by_value + //~^ large_types_passed_by_value todo!(); } diff --git a/tests/ui/len_without_is_empty.rs b/tests/ui/len_without_is_empty.rs index 781c28d04bec..011833072d76 100644 --- a/tests/ui/len_without_is_empty.rs +++ b/tests/ui/len_without_is_empty.rs @@ -5,8 +5,7 @@ pub struct PubOne; impl PubOne { pub fn len(&self) -> isize { - //~^ len_without_is_empty - + //~^ len_without_is_empty 1 } @@ -56,7 +55,7 @@ impl PubAllowedStruct { } pub trait PubTraitsToo { -//~^ len_without_is_empty + //~^ len_without_is_empty fn len(&self) -> isize; } @@ -71,7 +70,7 @@ pub struct HasIsEmpty; impl HasIsEmpty { pub fn len(&self) -> isize { - //~^ len_without_is_empty + //~^ len_without_is_empty 1 } @@ -85,7 +84,7 @@ pub struct HasWrongIsEmpty; impl HasWrongIsEmpty { pub fn len(&self) -> isize { - //~^ len_without_is_empty + //~^ len_without_is_empty 1 } @@ -99,7 +98,7 @@ pub struct MismatchedSelf; impl MismatchedSelf { pub fn len(self) -> isize { - //~^ len_without_is_empty + //~^ len_without_is_empty 1 } @@ -180,7 +179,7 @@ pub trait InheritingEmpty: Empty { pub trait Foo: Sized {} pub trait DependsOnFoo: Foo { -//~^ len_without_is_empty + //~^ len_without_is_empty fn len(&mut self) -> usize; } @@ -227,7 +226,7 @@ impl OptionalLen2 { pub struct OptionalLen3; impl OptionalLen3 { pub fn len(&self) -> usize { - //~^ len_without_is_empty + //~^ len_without_is_empty 0 } @@ -241,9 +240,8 @@ impl OptionalLen3 { pub struct ResultLen; impl ResultLen { pub fn len(&self) -> Result { - //~^ len_without_is_empty - //~| result_unit_err - + //~^ len_without_is_empty + //~| result_unit_err Ok(0) } @@ -257,13 +255,13 @@ impl ResultLen { pub struct ResultLen2; impl ResultLen2 { pub fn len(&self) -> Result { - //~^ result_unit_err + //~^ result_unit_err Ok(0) } pub fn is_empty(&self) -> Result { - //~^ result_unit_err + //~^ result_unit_err Ok(true) } @@ -272,7 +270,7 @@ impl ResultLen2 { pub struct ResultLen3; impl ResultLen3 { pub fn len(&self) -> Result { - //~^ result_unit_err + //~^ result_unit_err Ok(0) } @@ -315,7 +313,7 @@ impl AsyncLenWithoutIsEmpty { } pub async fn len(&self) -> usize { - //~^ len_without_is_empty + //~^ len_without_is_empty usize::from(!self.async_task().await) } @@ -329,7 +327,7 @@ impl AsyncOptionLenWithoutIsEmpty { } pub async fn len(&self) -> Option { - //~^ len_without_is_empty + //~^ len_without_is_empty None } @@ -352,7 +350,7 @@ impl AsyncResultLenWithoutIsEmpty { } pub async fn len(&self) -> Result { - //~^ len_without_is_empty + //~^ len_without_is_empty Err(()) } @@ -469,7 +467,7 @@ pub struct Aliased2; pub type Alias2 = Aliased2; impl Alias2 { pub fn len(&self) -> usize { - //~^ len_without_is_empty + //~^ len_without_is_empty todo!() } diff --git a/tests/ui/len_without_is_empty.stderr b/tests/ui/len_without_is_empty.stderr index 0fd445c720bd..748a55712f88 100644 --- a/tests/ui/len_without_is_empty.stderr +++ b/tests/ui/len_without_is_empty.stderr @@ -8,7 +8,7 @@ LL | pub fn len(&self) -> isize { = help: to override `-D warnings` add `#[allow(clippy::len_without_is_empty)]` error: trait `PubTraitsToo` has a `len` method but no (possibly inherited) `is_empty` method - --> tests/ui/len_without_is_empty.rs:58:1 + --> tests/ui/len_without_is_empty.rs:57:1 | LL | / pub trait PubTraitsToo { LL | | @@ -18,45 +18,45 @@ LL | | } | |_^ error: struct `HasIsEmpty` has a public `len` method, but a private `is_empty` method - --> tests/ui/len_without_is_empty.rs:73:5 + --> tests/ui/len_without_is_empty.rs:72:5 | LL | pub fn len(&self) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:79:5 + --> tests/ui/len_without_is_empty.rs:78:5 | LL | fn is_empty(&self) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: struct `HasWrongIsEmpty` has a public `len` method, but the `is_empty` method has an unexpected signature - --> tests/ui/len_without_is_empty.rs:87:5 + --> tests/ui/len_without_is_empty.rs:86:5 | LL | pub fn len(&self) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:93:5 + --> tests/ui/len_without_is_empty.rs:92:5 | LL | pub fn is_empty(&self, x: u32) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature: `(&self) -> bool` error: struct `MismatchedSelf` has a public `len` method, but the `is_empty` method has an unexpected signature - --> tests/ui/len_without_is_empty.rs:101:5 + --> tests/ui/len_without_is_empty.rs:100:5 | LL | pub fn len(self) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:107:5 + --> tests/ui/len_without_is_empty.rs:106:5 | LL | pub fn is_empty(&self) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature: `(self) -> bool` error: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty` method - --> tests/ui/len_without_is_empty.rs:182:1 + --> tests/ui/len_without_is_empty.rs:181:1 | LL | / pub trait DependsOnFoo: Foo { LL | | @@ -66,33 +66,33 @@ LL | | } | |_^ error: struct `OptionalLen3` has a public `len` method, but the `is_empty` method has an unexpected signature - --> tests/ui/len_without_is_empty.rs:229:5 + --> tests/ui/len_without_is_empty.rs:228:5 | LL | pub fn len(&self) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:236:5 + --> tests/ui/len_without_is_empty.rs:235:5 | LL | pub fn is_empty(&self) -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature: `(&self) -> bool` error: struct `ResultLen` has a public `len` method, but the `is_empty` method has an unexpected signature - --> tests/ui/len_without_is_empty.rs:243:5 + --> tests/ui/len_without_is_empty.rs:242:5 | LL | pub fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `is_empty` defined here - --> tests/ui/len_without_is_empty.rs:252:5 + --> tests/ui/len_without_is_empty.rs:250:5 | LL | pub fn is_empty(&self) -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature: `(&self) -> bool` or `(&self) -> Result error: this returns a `Result<_, ()>` - --> tests/ui/len_without_is_empty.rs:243:5 + --> tests/ui/len_without_is_empty.rs:242:5 | LL | pub fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -102,7 +102,7 @@ LL | pub fn len(&self) -> Result { = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]` error: this returns a `Result<_, ()>` - --> tests/ui/len_without_is_empty.rs:259:5 + --> tests/ui/len_without_is_empty.rs:257:5 | LL | pub fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -110,7 +110,7 @@ LL | pub fn len(&self) -> Result { = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/len_without_is_empty.rs:265:5 + --> tests/ui/len_without_is_empty.rs:263:5 | LL | pub fn is_empty(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | pub fn is_empty(&self) -> Result { = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/len_without_is_empty.rs:274:5 + --> tests/ui/len_without_is_empty.rs:272:5 | LL | pub fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -126,25 +126,25 @@ LL | pub fn len(&self) -> Result { = help: use a custom `Error` type instead error: struct `AsyncLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method - --> tests/ui/len_without_is_empty.rs:317:5 + --> tests/ui/len_without_is_empty.rs:315:5 | LL | pub async fn len(&self) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: struct `AsyncOptionLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method - --> tests/ui/len_without_is_empty.rs:331:5 + --> tests/ui/len_without_is_empty.rs:329:5 | LL | pub async fn len(&self) -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method - --> tests/ui/len_without_is_empty.rs:354:5 + --> tests/ui/len_without_is_empty.rs:352:5 | LL | pub async fn len(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `Alias2` has a public `len` method, but no `is_empty` method - --> tests/ui/len_without_is_empty.rs:471:5 + --> tests/ui/len_without_is_empty.rs:469:5 | LL | pub fn len(&self) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/len_zero.fixed b/tests/ui/len_zero.fixed index e24a569cfde8..b8573ef13b0e 100644 --- a/tests/ui/len_zero.fixed +++ b/tests/ui/len_zero.fixed @@ -86,7 +86,7 @@ impl Deref for DerefToString { fn main() { let x = [1, 2]; if x.is_empty() { - //~^ len_zero + //~^ len_zero println!("This should not happen!"); } @@ -134,23 +134,23 @@ fn main() { let has_is_empty = HasIsEmpty; if has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if has_is_empty.len() > 1 { @@ -162,23 +162,23 @@ fn main() { println!("This can happen."); } if has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if !has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if has_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if 1 < has_is_empty.len() { @@ -193,7 +193,7 @@ fn main() { let with_is_empty: &dyn WithIsEmpty = &Wither; if with_is_empty.is_empty() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } assert!(!with_is_empty.is_empty()); diff --git a/tests/ui/len_zero.rs b/tests/ui/len_zero.rs index b558dd9a215e..ef3c49c1ab30 100644 --- a/tests/ui/len_zero.rs +++ b/tests/ui/len_zero.rs @@ -86,7 +86,7 @@ impl Deref for DerefToString { fn main() { let x = [1, 2]; if x.len() == 0 { - //~^ len_zero + //~^ len_zero println!("This should not happen!"); } @@ -134,23 +134,23 @@ fn main() { let has_is_empty = HasIsEmpty; if has_is_empty.len() == 0 { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if has_is_empty.len() != 0 { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if has_is_empty.len() > 0 { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if has_is_empty.len() < 1 { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if has_is_empty.len() >= 1 { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if has_is_empty.len() > 1 { @@ -162,23 +162,23 @@ fn main() { println!("This can happen."); } if 0 == has_is_empty.len() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if 0 != has_is_empty.len() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if 0 < has_is_empty.len() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if 1 <= has_is_empty.len() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if 1 > has_is_empty.len() { - //~^ len_zero + //~^ len_zero println!("Or this!"); } if 1 < has_is_empty.len() { @@ -193,7 +193,7 @@ fn main() { let with_is_empty: &dyn WithIsEmpty = &Wither; if with_is_empty.len() == 0 { - //~^ len_zero + //~^ len_zero println!("Or this!"); } assert!(!with_is_empty.is_empty()); diff --git a/tests/ui/let_and_return.edition2021.fixed b/tests/ui/let_and_return.edition2021.fixed index 83e4a0298a7d..70d503018e0f 100644 --- a/tests/ui/let_and_return.edition2021.fixed +++ b/tests/ui/let_and_return.edition2021.fixed @@ -12,8 +12,6 @@ fn test() -> i32 { 5 //~^ let_and_return - - } fn test_inner() -> i32 { @@ -21,7 +19,6 @@ fn test_inner() -> i32 { 5 //~^ let_and_return - } else { 0 } @@ -85,7 +82,6 @@ fn issue_3792() -> String { stdin.lock().lines().next().unwrap().unwrap() //~^ let_and_return - } tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7); @@ -181,7 +177,6 @@ mod issue_5729 { (Arc::clone(&self.foo)) as _ //~^ let_and_return - } } } @@ -201,7 +196,6 @@ mod issue_11335 { E::B(x) => x, }) as _ //~^ let_and_return - } } } @@ -228,21 +222,18 @@ fn issue12801() { (if true { "a".to_string() } else { "b".to_string() } + "c") //~^ let_and_return - } fn no_par_needed() -> String { "c".to_string() + if true { "a" } else { "b" } //~^ let_and_return - } fn conjunctive_blocks() -> String { ({ "a".to_string() } + "b" + { "c" } + "d") //~^ let_and_return - } #[allow(clippy::overly_complex_bool_expr)] @@ -251,13 +242,11 @@ fn issue12801() { (if true { 2 } else { 3 } << 4) //~^ let_and_return - }; let _ = || { ({ true } || { false } && { 2 <= 3 }) //~^ let_and_return - }; } } diff --git a/tests/ui/let_and_return.edition2021.stderr b/tests/ui/let_and_return.edition2021.stderr index 4302053c7815..f9536d1b5477 100644 --- a/tests/ui/let_and_return.edition2021.stderr +++ b/tests/ui/let_and_return.edition2021.stderr @@ -15,7 +15,7 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:22:9 + --> tests/ui/let_and_return.rs:20:9 | LL | let x = 5; | ---------- unnecessary `let` binding @@ -29,7 +29,7 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:86:5 + --> tests/ui/let_and_return.rs:83:5 | LL | let line = stdin.lock().lines().next().unwrap().unwrap(); | --------------------------------------------------------- unnecessary `let` binding @@ -43,7 +43,7 @@ LL ~ stdin.lock().lines().next().unwrap().unwrap() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:182:13 + --> tests/ui/let_and_return.rs:178:13 | LL | let clone = Arc::clone(&self.foo); | ---------------------------------- unnecessary `let` binding @@ -57,7 +57,7 @@ LL ~ (Arc::clone(&self.foo)) as _ | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:202:13 + --> tests/ui/let_and_return.rs:197:13 | LL | / let result = match self { LL | | E::A(x) => x, @@ -79,7 +79,7 @@ LL + }) as _ | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:229:9 + --> tests/ui/let_and_return.rs:223:9 | LL | let s = if true { "a".to_string() } else { "b".to_string() } + "c"; | ------------------------------------------------------------------- unnecessary `let` binding @@ -93,7 +93,7 @@ LL ~ (if true { "a".to_string() } else { "b".to_string() } + "c") | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:236:9 + --> tests/ui/let_and_return.rs:229:9 | LL | let s = "c".to_string() + if true { "a" } else { "b" }; | ------------------------------------------------------- unnecessary `let` binding @@ -107,7 +107,7 @@ LL ~ "c".to_string() + if true { "a" } else { "b" } | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:243:9 + --> tests/ui/let_and_return.rs:235:9 | LL | let s = { "a".to_string() } + "b" + { "c" } + "d"; | -------------------------------------------------- unnecessary `let` binding @@ -121,7 +121,7 @@ LL ~ ({ "a".to_string() } + "b" + { "c" } + "d") | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:252:13 + --> tests/ui/let_and_return.rs:243:13 | LL | let s = if true { 2 } else { 3 } << 4; | -------------------------------------- unnecessary `let` binding @@ -135,7 +135,7 @@ LL ~ (if true { 2 } else { 3 } << 4) | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:258:13 + --> tests/ui/let_and_return.rs:248:13 | LL | let s = { true } || { false } && { 2 <= 3 }; | -------------------------------------------- unnecessary `let` binding diff --git a/tests/ui/let_and_return.edition2024.fixed b/tests/ui/let_and_return.edition2024.fixed index 4846d6ada3ca..9990c3b71205 100644 --- a/tests/ui/let_and_return.edition2024.fixed +++ b/tests/ui/let_and_return.edition2024.fixed @@ -12,8 +12,6 @@ fn test() -> i32 { 5 //~^ let_and_return - - } fn test_inner() -> i32 { @@ -21,7 +19,6 @@ fn test_inner() -> i32 { 5 //~^ let_and_return - } else { 0 } @@ -85,7 +82,6 @@ fn issue_3792() -> String { stdin.lock().lines().next().unwrap().unwrap() //~^ let_and_return - } tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7); @@ -181,7 +177,6 @@ mod issue_5729 { (Arc::clone(&self.foo)) as _ //~^ let_and_return - } } } @@ -201,7 +196,6 @@ mod issue_11335 { E::B(x) => x, }) as _ //~^ let_and_return - } } } @@ -228,21 +222,18 @@ fn issue12801() { (if true { "a".to_string() } else { "b".to_string() } + "c") //~^ let_and_return - } fn no_par_needed() -> String { "c".to_string() + if true { "a" } else { "b" } //~^ let_and_return - } fn conjunctive_blocks() -> String { ({ "a".to_string() } + "b" + { "c" } + "d") //~^ let_and_return - } #[allow(clippy::overly_complex_bool_expr)] @@ -251,13 +242,11 @@ fn issue12801() { (if true { 2 } else { 3 } << 4) //~^ let_and_return - }; let _ = || { ({ true } || { false } && { 2 <= 3 }) //~^ let_and_return - }; } } diff --git a/tests/ui/let_and_return.edition2024.stderr b/tests/ui/let_and_return.edition2024.stderr index 4b7f1a019f27..ca378fa43232 100644 --- a/tests/ui/let_and_return.edition2024.stderr +++ b/tests/ui/let_and_return.edition2024.stderr @@ -15,7 +15,7 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:22:9 + --> tests/ui/let_and_return.rs:20:9 | LL | let x = 5; | ---------- unnecessary `let` binding @@ -29,7 +29,7 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:86:5 + --> tests/ui/let_and_return.rs:83:5 | LL | let line = stdin.lock().lines().next().unwrap().unwrap(); | --------------------------------------------------------- unnecessary `let` binding @@ -43,7 +43,7 @@ LL ~ stdin.lock().lines().next().unwrap().unwrap() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:110:9 + --> tests/ui/let_and_return.rs:106:9 | LL | let ret = value.borrow().baz(); | ------------------------------- unnecessary `let` binding @@ -57,7 +57,7 @@ LL ~ value.borrow().baz() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:121:9 + --> tests/ui/let_and_return.rs:117:9 | LL | let ret = f(|| value.borrow().baz())(); | --------------------------------------- unnecessary `let` binding @@ -71,7 +71,7 @@ LL ~ f(|| value.borrow().baz())() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:153:13 + --> tests/ui/let_and_return.rs:149:13 | LL | let value = some_foo(&x).value(); | --------------------------------- unnecessary `let` binding @@ -85,7 +85,7 @@ LL ~ some_foo(&x).value() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:160:13 + --> tests/ui/let_and_return.rs:156:13 | LL | let value = Foo::new(&x).value(); | --------------------------------- unnecessary `let` binding @@ -99,7 +99,7 @@ LL ~ Foo::new(&x).value() | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:182:13 + --> tests/ui/let_and_return.rs:178:13 | LL | let clone = Arc::clone(&self.foo); | ---------------------------------- unnecessary `let` binding @@ -113,7 +113,7 @@ LL ~ (Arc::clone(&self.foo)) as _ | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:202:13 + --> tests/ui/let_and_return.rs:197:13 | LL | / let result = match self { LL | | E::A(x) => x, @@ -135,7 +135,7 @@ LL + }) as _ | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:229:9 + --> tests/ui/let_and_return.rs:223:9 | LL | let s = if true { "a".to_string() } else { "b".to_string() } + "c"; | ------------------------------------------------------------------- unnecessary `let` binding @@ -149,7 +149,7 @@ LL ~ (if true { "a".to_string() } else { "b".to_string() } + "c") | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:236:9 + --> tests/ui/let_and_return.rs:229:9 | LL | let s = "c".to_string() + if true { "a" } else { "b" }; | ------------------------------------------------------- unnecessary `let` binding @@ -163,7 +163,7 @@ LL ~ "c".to_string() + if true { "a" } else { "b" } | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:243:9 + --> tests/ui/let_and_return.rs:235:9 | LL | let s = { "a".to_string() } + "b" + { "c" } + "d"; | -------------------------------------------------- unnecessary `let` binding @@ -177,7 +177,7 @@ LL ~ ({ "a".to_string() } + "b" + { "c" } + "d") | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:252:13 + --> tests/ui/let_and_return.rs:243:13 | LL | let s = if true { 2 } else { 3 } << 4; | -------------------------------------- unnecessary `let` binding @@ -191,7 +191,7 @@ LL ~ (if true { 2 } else { 3 } << 4) | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:258:13 + --> tests/ui/let_and_return.rs:248:13 | LL | let s = { true } || { false } && { 2 <= 3 }; | -------------------------------------------- unnecessary `let` binding @@ -205,7 +205,7 @@ LL ~ ({ true } || { false } && { 2 <= 3 }) | error: returning the result of a `let` binding from a block - --> tests/ui/let_and_return.rs:271:5 + --> tests/ui/let_and_return.rs:260:5 | LL | / let r = match &*v.borrow() { LL | | Some(v) => Ok(Ok(v[0])), diff --git a/tests/ui/let_and_return.rs b/tests/ui/let_and_return.rs index ab5338837a53..48c20cdd60db 100644 --- a/tests/ui/let_and_return.rs +++ b/tests/ui/let_and_return.rs @@ -12,8 +12,6 @@ fn test() -> i32 { let x = 5; x //~^ let_and_return - - } fn test_inner() -> i32 { @@ -21,7 +19,6 @@ fn test_inner() -> i32 { let x = 5; x //~^ let_and_return - } else { 0 } @@ -85,7 +82,6 @@ fn issue_3792() -> String { let line = stdin.lock().lines().next().unwrap().unwrap(); line //~^ let_and_return - } tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7); @@ -181,7 +177,6 @@ mod issue_5729 { let clone = Arc::clone(&self.foo); clone //~^ let_and_return - } } } @@ -201,7 +196,6 @@ mod issue_11335 { result //~^ let_and_return - } } } @@ -228,21 +222,18 @@ fn issue12801() { let s = if true { "a".to_string() } else { "b".to_string() } + "c"; s //~^ let_and_return - } fn no_par_needed() -> String { let s = "c".to_string() + if true { "a" } else { "b" }; s //~^ let_and_return - } fn conjunctive_blocks() -> String { let s = { "a".to_string() } + "b" + { "c" } + "d"; s //~^ let_and_return - } #[allow(clippy::overly_complex_bool_expr)] @@ -251,13 +242,11 @@ fn issue12801() { let s = if true { 2 } else { 3 } << 4; s //~^ let_and_return - }; let _ = || { let s = { true } || { false } && { 2 <= 3 }; s //~^ let_and_return - }; } } diff --git a/tests/ui/let_if_seq.rs b/tests/ui/let_if_seq.rs index cc482155eda7..2db206212aa5 100644 --- a/tests/ui/let_if_seq.rs +++ b/tests/ui/let_if_seq.rs @@ -77,7 +77,6 @@ fn main() { let mut foo = 0; //~^ useless_let_if_seq - if f() { foo = 42; } @@ -85,7 +84,6 @@ fn main() { let mut bar = 0; //~^ useless_let_if_seq - if f() { f(); bar = 42; @@ -127,7 +125,6 @@ fn main() { let mut baz = 0; //~^ useless_let_if_seq - if f() { baz = 42; } diff --git a/tests/ui/let_if_seq.stderr b/tests/ui/let_if_seq.stderr index b63a31b99129..f59d42bf4c8d 100644 --- a/tests/ui/let_if_seq.stderr +++ b/tests/ui/let_if_seq.stderr @@ -2,7 +2,9 @@ error: `if _ { .. } else { .. }` is an expression --> tests/ui/let_if_seq.rs:77:5 | LL | / let mut foo = 0; -... | +LL | | +LL | | +LL | | if f() { LL | | foo = 42; LL | | } | |_____^ help: it is more idiomatic to write: `let foo = if f() { 42 } else { 0 };` @@ -12,9 +14,12 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::useless_let_if_seq)]` error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:85:5 + --> tests/ui/let_if_seq.rs:84:5 | LL | / let mut bar = 0; +LL | | +LL | | +LL | | if f() { ... | LL | | f(); LL | | } @@ -23,7 +28,7 @@ LL | | } = note: you might not need `mut` at all error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:96:5 + --> tests/ui/let_if_seq.rs:94:5 | LL | / let quz; LL | | @@ -35,10 +40,12 @@ LL | | } | |_____^ help: it is more idiomatic to write: `let quz = if f() { 42 } else { 0 };` error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:127:5 + --> tests/ui/let_if_seq.rs:125:5 | LL | / let mut baz = 0; -... | +LL | | +LL | | +LL | | if f() { LL | | baz = 42; LL | | } | |_____^ help: it is more idiomatic to write: `let baz = if f() { 42 } else { 0 };` diff --git a/tests/ui/let_underscore_future.rs b/tests/ui/let_underscore_future.rs index 2d57e83fd54d..6347c792280e 100644 --- a/tests/ui/let_underscore_future.rs +++ b/tests/ui/let_underscore_future.rs @@ -17,10 +17,8 @@ fn main() { let _ = custom(); //~^ let_underscore_future - let mut future = some_async_fn(); do_something_to_future(&mut future); let _ = future; //~^ let_underscore_future - } diff --git a/tests/ui/let_underscore_future.stderr b/tests/ui/let_underscore_future.stderr index e59e1f68911a..baa489551d4a 100644 --- a/tests/ui/let_underscore_future.stderr +++ b/tests/ui/let_underscore_future.stderr @@ -17,7 +17,7 @@ LL | let _ = custom(); = help: consider awaiting the future or dropping explicitly with `std::mem::drop` error: non-binding `let` on a future - --> tests/ui/let_underscore_future.rs:23:5 + --> tests/ui/let_underscore_future.rs:22:5 | LL | let _ = future; | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/let_underscore_must_use.rs b/tests/ui/let_underscore_must_use.rs index 730e586eea79..5cf31ec63c66 100644 --- a/tests/ui/let_underscore_must_use.rs +++ b/tests/ui/let_underscore_must_use.rs @@ -74,7 +74,6 @@ fn main() { let _ = l(0_u32); //~^ let_underscore_must_use - let s = S {}; let _ = s.f(); @@ -91,29 +90,23 @@ fn main() { let _ = S::p(); //~^ let_underscore_must_use - let _ = S::a(); //~^ let_underscore_must_use - let _ = if true { Ok(()) } else { Err(()) }; //~^ let_underscore_must_use - let a = Result::<(), ()>::Ok(()); let _ = a.is_ok(); //~^ let_underscore_must_use - let _ = a.map(|_| ()); //~^ let_underscore_must_use - let _ = a; //~^ let_underscore_must_use - #[allow(clippy::let_underscore_must_use)] let _ = a; } diff --git a/tests/ui/let_underscore_must_use.stderr b/tests/ui/let_underscore_must_use.stderr index fda2a2b2adaa..130ea11646fd 100644 --- a/tests/ui/let_underscore_must_use.stderr +++ b/tests/ui/let_underscore_must_use.stderr @@ -25,7 +25,7 @@ LL | let _ = l(0_u32); = help: consider explicitly using function result error: non-binding `let` on a result of a `#[must_use]` function - --> tests/ui/let_underscore_must_use.rs:80:5 + --> tests/ui/let_underscore_must_use.rs:79:5 | LL | let _ = s.f(); | ^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = s.f(); = help: consider explicitly using function result error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:83:5 + --> tests/ui/let_underscore_must_use.rs:82:5 | LL | let _ = s.g(); | ^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = s.g(); = help: consider explicitly using expression value error: non-binding `let` on a result of a `#[must_use]` function - --> tests/ui/let_underscore_must_use.rs:88:5 + --> tests/ui/let_underscore_must_use.rs:87:5 | LL | let _ = S::h(); | ^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = S::h(); = help: consider explicitly using function result error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:91:5 + --> tests/ui/let_underscore_must_use.rs:90:5 | LL | let _ = S::p(); | ^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = S::p(); = help: consider explicitly using expression value error: non-binding `let` on a result of a `#[must_use]` function - --> tests/ui/let_underscore_must_use.rs:95:5 + --> tests/ui/let_underscore_must_use.rs:93:5 | LL | let _ = S::a(); | ^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | let _ = S::a(); = help: consider explicitly using function result error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:99:5 + --> tests/ui/let_underscore_must_use.rs:96:5 | LL | let _ = if true { Ok(()) } else { Err(()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let _ = if true { Ok(()) } else { Err(()) }; = help: consider explicitly using expression value error: non-binding `let` on a result of a `#[must_use]` function - --> tests/ui/let_underscore_must_use.rs:105:5 + --> tests/ui/let_underscore_must_use.rs:101:5 | LL | let _ = a.is_ok(); | ^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | let _ = a.is_ok(); = help: consider explicitly using function result error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:109:5 + --> tests/ui/let_underscore_must_use.rs:104:5 | LL | let _ = a.map(|_| ()); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = a.map(|_| ()); = help: consider explicitly using expression value error: non-binding `let` on an expression with `#[must_use]` type - --> tests/ui/let_underscore_must_use.rs:113:5 + --> tests/ui/let_underscore_must_use.rs:107:5 | LL | let _ = a; | ^^^^^^^^^^ diff --git a/tests/ui/let_unit.fixed b/tests/ui/let_unit.fixed index 23145bd132f5..5e7a2ad37a84 100644 --- a/tests/ui/let_unit.fixed +++ b/tests/ui/let_unit.fixed @@ -58,7 +58,7 @@ fn multiline_sugg() { let v: Vec = vec![2]; v - //~^ let_unit_value + //~^ let_unit_value .into_iter() .map(|i| i * 2) .filter(|i| i % 2 == 0) @@ -108,7 +108,7 @@ fn _returns_generic() { let x: () = if true { f() } else { f2(0) }; match Some(0) { - //~^ let_unit_value + //~^ let_unit_value None => f2(1), Some(0) => f(), Some(1) => f2(3), diff --git a/tests/ui/let_unit.rs b/tests/ui/let_unit.rs index 59800b553a8c..7b06f6940121 100644 --- a/tests/ui/let_unit.rs +++ b/tests/ui/let_unit.rs @@ -58,7 +58,7 @@ fn multiline_sugg() { let v: Vec = vec![2]; let _ = v - //~^ let_unit_value + //~^ let_unit_value .into_iter() .map(|i| i * 2) .filter(|i| i % 2 == 0) @@ -108,7 +108,7 @@ fn _returns_generic() { let x: () = if true { f() } else { f2(0) }; let x = match Some(0) { - //~^ let_unit_value + //~^ let_unit_value None => f2(1), Some(0) => f(), Some(1) => f2(3), diff --git a/tests/ui/linkedlist.rs b/tests/ui/linkedlist.rs index eddbe730c174..64a9ba0029da 100644 --- a/tests/ui/linkedlist.rs +++ b/tests/ui/linkedlist.rs @@ -11,7 +11,6 @@ const C: LinkedList = LinkedList::new(); static S: LinkedList = LinkedList::new(); //~^ linkedlist - trait Foo { type Baz = LinkedList; //~^ linkedlist @@ -21,7 +20,6 @@ trait Foo { const BAR: Option>; //~^ linkedlist - } // Ok, we don’t want to warn for implementations; see issue #605. @@ -33,13 +31,11 @@ impl Foo for LinkedList { pub struct Bar { priv_linked_list_field: LinkedList, //~^ linkedlist - pub pub_linked_list_field: LinkedList, } impl Bar { fn foo(_: LinkedList) {} //~^ linkedlist - } // All of these test should be trigger the lint because they are not @@ -48,7 +44,7 @@ fn test(my_favorite_linked_list: LinkedList) {} //~^ linkedlist fn test_ret() -> Option> { -//~^ linkedlist + //~^ linkedlist None } diff --git a/tests/ui/linkedlist.stderr b/tests/ui/linkedlist.stderr index 22382d49e3a4..419fbcc7e188 100644 --- a/tests/ui/linkedlist.stderr +++ b/tests/ui/linkedlist.stderr @@ -17,7 +17,7 @@ LL | static S: LinkedList = LinkedList::new(); = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:16:16 + --> tests/ui/linkedlist.rs:15:16 | LL | type Baz = LinkedList; | ^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | type Baz = LinkedList; = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:19:15 + --> tests/ui/linkedlist.rs:18:15 | LL | fn foo(_: LinkedList); | ^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | fn foo(_: LinkedList); = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:22:23 + --> tests/ui/linkedlist.rs:21:23 | LL | const BAR: Option>; | ^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | const BAR: Option>; = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:34:29 + --> tests/ui/linkedlist.rs:32:29 | LL | priv_linked_list_field: LinkedList, | ^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | priv_linked_list_field: LinkedList, = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:40:15 + --> tests/ui/linkedlist.rs:37:15 | LL | fn foo(_: LinkedList) {} | ^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn foo(_: LinkedList) {} = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:47:34 + --> tests/ui/linkedlist.rs:43:34 | LL | fn test(my_favorite_linked_list: LinkedList) {} | ^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | fn test(my_favorite_linked_list: LinkedList) {} = help: a `VecDeque` might work error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? - --> tests/ui/linkedlist.rs:50:25 + --> tests/ui/linkedlist.rs:46:25 | LL | fn test_ret() -> Option> { | ^^^^^^^^^^^^^^ diff --git a/tests/ui/literals.rs b/tests/ui/literals.rs index 300a2d7802dd..d21d49310a07 100644 --- a/tests/ui/literals.rs +++ b/tests/ui/literals.rs @@ -13,7 +13,6 @@ fn main() { let ok4 = 0xab_cd_i32; //~^ separated_literal_suffix - let ok5 = 0xAB_CD_u32; //~^ separated_literal_suffix @@ -23,25 +22,18 @@ fn main() { let fail1 = 0xabCD; //~^ mixed_case_hex_literals - let fail2 = 0xabCD_u32; //~^ separated_literal_suffix //~| mixed_case_hex_literals - let fail2 = 0xabCD_isize; //~^ separated_literal_suffix //~| mixed_case_hex_literals - let fail_multi_zero = 000_123usize; //~^ unseparated_literal_suffix //~| zero_prefixed_literal - - - - let ok9 = 0; let ok10 = 0_i64; //~^ separated_literal_suffix @@ -49,7 +41,6 @@ fn main() { let fail8 = 0123; //~^ zero_prefixed_literal - let ok11 = 0o123; let ok12 = 0b10_1010; @@ -65,18 +56,15 @@ fn main() { let fail19 = 12_3456_21; //~^ inconsistent_digit_grouping - let fail22 = 3__4___23; //~^ inconsistent_digit_grouping let fail23 = 3__16___23; //~^ inconsistent_digit_grouping - let fail24 = 0xAB_ABC_AB; //~^ unusual_byte_groupings - let fail25 = 0b01_100_101; let ok26 = 0x6_A0_BF; let ok27 = 0b1_0010_0101; @@ -92,5 +80,4 @@ fn issue9651() { let _ = 089; //~^ zero_prefixed_literal - } diff --git a/tests/ui/literals.stderr b/tests/ui/literals.stderr index 1e19af071f82..dcee7169c0a8 100644 --- a/tests/ui/literals.stderr +++ b/tests/ui/literals.stderr @@ -8,19 +8,19 @@ LL | let ok4 = 0xab_cd_i32; = help: to override `-D warnings` add `#[allow(clippy::separated_literal_suffix)]` error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:17:15 + --> tests/ui/literals.rs:16:15 | LL | let ok5 = 0xAB_CD_u32; | ^^^^^^^^^^^ help: remove the underscore: `0xAB_CDu32` error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:20:15 + --> tests/ui/literals.rs:19:15 | LL | let ok5 = 0xAB_CD_isize; | ^^^^^^^^^^^^^ help: remove the underscore: `0xAB_CDisize` error: inconsistent casing in hexadecimal literal - --> tests/ui/literals.rs:23:17 + --> tests/ui/literals.rs:22:17 | LL | let fail1 = 0xabCD; | ^^^^^^ @@ -29,31 +29,31 @@ LL | let fail1 = 0xabCD; = help: to override `-D warnings` add `#[allow(clippy::mixed_case_hex_literals)]` error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:27:17 + --> tests/ui/literals.rs:25:17 | LL | let fail2 = 0xabCD_u32; | ^^^^^^^^^^ help: remove the underscore: `0xabCDu32` error: inconsistent casing in hexadecimal literal - --> tests/ui/literals.rs:27:17 + --> tests/ui/literals.rs:25:17 | LL | let fail2 = 0xabCD_u32; | ^^^^^^^^^^ error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:32:17 + --> tests/ui/literals.rs:29:17 | LL | let fail2 = 0xabCD_isize; | ^^^^^^^^^^^^ help: remove the underscore: `0xabCDisize` error: inconsistent casing in hexadecimal literal - --> tests/ui/literals.rs:32:17 + --> tests/ui/literals.rs:29:17 | LL | let fail2 = 0xabCD_isize; | ^^^^^^^^^^^^ error: integer type suffix should be separated by an underscore - --> tests/ui/literals.rs:37:27 + --> tests/ui/literals.rs:33:27 | LL | let fail_multi_zero = 000_123usize; | ^^^^^^^^^^^^ help: add an underscore: `000_123_usize` @@ -62,7 +62,7 @@ LL | let fail_multi_zero = 000_123usize; = help: to override `-D warnings` add `#[allow(clippy::unseparated_literal_suffix)]` error: this is a decimal constant - --> tests/ui/literals.rs:37:27 + --> tests/ui/literals.rs:33:27 | LL | let fail_multi_zero = 000_123usize; | ^^^^^^^^^^^^ @@ -79,13 +79,13 @@ LL | let fail_multi_zero = 0o123usize; | ~~~~~~~~~~ error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:46:16 + --> tests/ui/literals.rs:38:16 | LL | let ok10 = 0_i64; | ^^^^^ help: remove the underscore: `0i64` error: this is a decimal constant - --> tests/ui/literals.rs:49:17 + --> tests/ui/literals.rs:41:17 | LL | let fail8 = 0123; | ^^^^ @@ -100,13 +100,13 @@ LL | let fail8 = 0o123; | ~~~~~ error: integer type suffix should not be separated by an underscore - --> tests/ui/literals.rs:60:16 + --> tests/ui/literals.rs:51:16 | LL | let ok17 = 0x123_4567_8901_usize; | ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901usize` error: digits grouped inconsistently by underscores - --> tests/ui/literals.rs:65:18 + --> tests/ui/literals.rs:56:18 | LL | let fail19 = 12_3456_21; | ^^^^^^^^^^ help: consider: `12_345_621` @@ -115,19 +115,19 @@ LL | let fail19 = 12_3456_21; = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]` error: digits grouped inconsistently by underscores - --> tests/ui/literals.rs:69:18 + --> tests/ui/literals.rs:59:18 | LL | let fail22 = 3__4___23; | ^^^^^^^^^ help: consider: `3_423` error: digits grouped inconsistently by underscores - --> tests/ui/literals.rs:72:18 + --> tests/ui/literals.rs:62:18 | LL | let fail23 = 3__16___23; | ^^^^^^^^^^ help: consider: `31_623` error: digits of hex, binary or octal literal not in groups of equal size - --> tests/ui/literals.rs:76:18 + --> tests/ui/literals.rs:65:18 | LL | let fail24 = 0xAB_ABC_AB; | ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB` @@ -136,7 +136,7 @@ LL | let fail24 = 0xAB_ABC_AB; = help: to override `-D warnings` add `#[allow(clippy::unusual_byte_groupings)]` error: this is a decimal constant - --> tests/ui/literals.rs:87:13 + --> tests/ui/literals.rs:75:13 | LL | let _ = 08; | ^^ @@ -147,7 +147,7 @@ LL | let _ = 8; | ~ error: this is a decimal constant - --> tests/ui/literals.rs:90:13 + --> tests/ui/literals.rs:78:13 | LL | let _ = 09; | ^^ @@ -158,7 +158,7 @@ LL | let _ = 9; | ~ error: this is a decimal constant - --> tests/ui/literals.rs:93:13 + --> tests/ui/literals.rs:81:13 | LL | let _ = 089; | ^^^ diff --git a/tests/ui/manual_arithmetic_check-2.rs b/tests/ui/manual_arithmetic_check-2.rs index 51515e7d9dcf..749d15f1cbd8 100644 --- a/tests/ui/manual_arithmetic_check-2.rs +++ b/tests/ui/manual_arithmetic_check-2.rs @@ -12,7 +12,6 @@ fn main() { let result = if b < a { b - a } else { 0 }; //~^ inverted_saturating_sub - let result = if a > b { 0 } else { a - b }; //~^ inverted_saturating_sub @@ -25,7 +24,6 @@ fn main() { let result = if b <= a { 0 } else { a - b }; //~^ inverted_saturating_sub - let af = 12f32; let bf = 13f32; // Should not lint! diff --git a/tests/ui/manual_arithmetic_check-2.stderr b/tests/ui/manual_arithmetic_check-2.stderr index 3d51a8be670c..8841210befda 100644 --- a/tests/ui/manual_arithmetic_check-2.stderr +++ b/tests/ui/manual_arithmetic_check-2.stderr @@ -24,49 +24,49 @@ LL | let result = if b < a { b - a } else { 0 }; | ^^^^^ error: inverted arithmetic check before subtraction - --> tests/ui/manual_arithmetic_check-2.rs:16:23 + --> tests/ui/manual_arithmetic_check-2.rs:15:23 | LL | let result = if a > b { 0 } else { a - b }; | ^ ----- help: try replacing it with: `b - a` | note: this subtraction underflows when `a < b` - --> tests/ui/manual_arithmetic_check-2.rs:16:40 + --> tests/ui/manual_arithmetic_check-2.rs:15:40 | LL | let result = if a > b { 0 } else { a - b }; | ^^^^^ error: inverted arithmetic check before subtraction - --> tests/ui/manual_arithmetic_check-2.rs:19:23 + --> tests/ui/manual_arithmetic_check-2.rs:18:23 | LL | let result = if a >= b { 0 } else { a - b }; | ^^ ----- help: try replacing it with: `b - a` | note: this subtraction underflows when `a < b` - --> tests/ui/manual_arithmetic_check-2.rs:19:41 + --> tests/ui/manual_arithmetic_check-2.rs:18:41 | LL | let result = if a >= b { 0 } else { a - b }; | ^^^^^ error: inverted arithmetic check before subtraction - --> tests/ui/manual_arithmetic_check-2.rs:22:23 + --> tests/ui/manual_arithmetic_check-2.rs:21:23 | LL | let result = if b < a { 0 } else { a - b }; | ^ ----- help: try replacing it with: `b - a` | note: this subtraction underflows when `a < b` - --> tests/ui/manual_arithmetic_check-2.rs:22:40 + --> tests/ui/manual_arithmetic_check-2.rs:21:40 | LL | let result = if b < a { 0 } else { a - b }; | ^^^^^ error: inverted arithmetic check before subtraction - --> tests/ui/manual_arithmetic_check-2.rs:25:23 + --> tests/ui/manual_arithmetic_check-2.rs:24:23 | LL | let result = if b <= a { 0 } else { a - b }; | ^^ ----- help: try replacing it with: `b - a` | note: this subtraction underflows when `a < b` - --> tests/ui/manual_arithmetic_check-2.rs:25:41 + --> tests/ui/manual_arithmetic_check-2.rs:24:41 | LL | let result = if b <= a { 0 } else { a - b }; | ^^^^^ diff --git a/tests/ui/manual_arithmetic_check.fixed b/tests/ui/manual_arithmetic_check.fixed index 5bda101c7b7c..99ed1faf90a6 100644 --- a/tests/ui/manual_arithmetic_check.fixed +++ b/tests/ui/manual_arithmetic_check.fixed @@ -12,14 +12,12 @@ fn main() { let result = a.saturating_sub(b); //~^ implicit_saturating_sub - let result = a.saturating_sub(b); //~^ implicit_saturating_sub let result = a.saturating_sub(b); //~^ implicit_saturating_sub - // Should not warn! let result = if a > b { a - b } else { a - c }; diff --git a/tests/ui/manual_arithmetic_check.rs b/tests/ui/manual_arithmetic_check.rs index ba296c736f01..cf202fa35a6a 100644 --- a/tests/ui/manual_arithmetic_check.rs +++ b/tests/ui/manual_arithmetic_check.rs @@ -12,14 +12,12 @@ fn main() { let result = if b < a { a - b } else { 0 }; //~^ implicit_saturating_sub - let result = if a < b { 0 } else { a - b }; //~^ implicit_saturating_sub let result = if b > a { 0 } else { a - b }; //~^ implicit_saturating_sub - // Should not warn! let result = if a > b { a - b } else { a - c }; diff --git a/tests/ui/manual_arithmetic_check.stderr b/tests/ui/manual_arithmetic_check.stderr index fe5663f586f4..b1598a5d06dc 100644 --- a/tests/ui/manual_arithmetic_check.stderr +++ b/tests/ui/manual_arithmetic_check.stderr @@ -14,13 +14,13 @@ LL | let result = if b < a { a - b } else { 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)` error: manual arithmetic check found - --> tests/ui/manual_arithmetic_check.rs:16:18 + --> tests/ui/manual_arithmetic_check.rs:15:18 | LL | let result = if a < b { 0 } else { a - b }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)` error: manual arithmetic check found - --> tests/ui/manual_arithmetic_check.rs:19:18 + --> tests/ui/manual_arithmetic_check.rs:18:18 | LL | let result = if b > a { 0 } else { a - b }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)` diff --git a/tests/ui/manual_assert.rs b/tests/ui/manual_assert.rs index 2c9b17bb8b1b..46a42c3d00af 100644 --- a/tests/ui/manual_assert.rs +++ b/tests/ui/manual_assert.rs @@ -30,11 +30,11 @@ fn main() { panic!("qaqaq{:?}", a); } if !a.is_empty() { - //~^ manual_assert + //~^ manual_assert panic!("qaqaq{:?}", a); } if !a.is_empty() { - //~^ manual_assert + //~^ manual_assert panic!("qwqwq"); } if a.len() == 3 { @@ -52,27 +52,27 @@ fn main() { } let b = vec![1, 2, 3]; if b.is_empty() { - //~^ manual_assert + //~^ manual_assert panic!("panic1"); } if b.is_empty() && a.is_empty() { - //~^ manual_assert + //~^ manual_assert panic!("panic2"); } if a.is_empty() && !b.is_empty() { - //~^ manual_assert + //~^ manual_assert panic!("panic3"); } if b.is_empty() || a.is_empty() { - //~^ manual_assert + //~^ manual_assert panic!("panic4"); } if a.is_empty() || !b.is_empty() { - //~^ manual_assert + //~^ manual_assert panic!("panic5"); } if a.is_empty() { - //~^ manual_assert + //~^ manual_assert panic!("with expansion {}", one!()) } if a.is_empty() { @@ -85,7 +85,7 @@ fn main() { fn issue7730(a: u8) { // Suggestion should preserve comment if a > 2 { - //~^ manual_assert + //~^ manual_assert // comment /* this is a multiline @@ -100,7 +100,7 @@ fn issue12505() { impl Foo { const BAR: () = if N == 0 { - //~^ manual_assert + //~^ manual_assert panic!() }; } diff --git a/tests/ui/manual_async_fn.rs b/tests/ui/manual_async_fn.rs index a699e40868d7..fe367b4bc7b9 100644 --- a/tests/ui/manual_async_fn.rs +++ b/tests/ui/manual_async_fn.rs @@ -4,7 +4,7 @@ use std::future::Future; fn fut() -> impl Future { -//~^ manual_async_fn + //~^ manual_async_fn async { 42 } } @@ -21,7 +21,7 @@ fn fut3()-> impl Future { } fn empty_fut() -> impl Future { -//~^ manual_async_fn + //~^ manual_async_fn async {} } @@ -38,7 +38,7 @@ fn empty_fut3()-> impl Future { } fn core_fut() -> impl core::future::Future { -//~^ manual_async_fn + //~^ manual_async_fn async move { 42 } } @@ -61,7 +61,7 @@ async fn already_async() -> impl Future { struct S; impl S { fn inh_fut() -> impl Future { - //~^ manual_async_fn + //~^ manual_async_fn async { // NOTE: this code is here just to check that the indentation is correct in the suggested fix let a = 42; @@ -97,7 +97,7 @@ impl S { // Tests related to lifetime capture fn elided(_: &i32) -> impl Future + '_ { -//~^ manual_async_fn + //~^ manual_async_fn async { 42 } } @@ -108,7 +108,7 @@ fn elided_not_bound(_: &i32) -> impl Future { #[allow(clippy::needless_lifetimes)] fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { -//~^ manual_async_fn + //~^ manual_async_fn async { 42 } } @@ -138,17 +138,17 @@ mod issue_5765 { } pub fn issue_10450() -> impl Future { -//~^ manual_async_fn + //~^ manual_async_fn async { 42 } } pub(crate) fn issue_10450_2() -> impl Future { -//~^ manual_async_fn + //~^ manual_async_fn async { 42 } } pub(self) fn issue_10450_3() -> impl Future { -//~^ manual_async_fn + //~^ manual_async_fn async { 42 } } diff --git a/tests/ui/manual_clamp.fixed b/tests/ui/manual_clamp.fixed index 1e2b1d009907..2450a4f4c611 100644 --- a/tests/ui/manual_clamp.fixed +++ b/tests/ui/manual_clamp.fixed @@ -152,13 +152,9 @@ fn const_main() { let x4 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - - let x5 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - - let x6 = input.clamp(CONST_MIN, CONST_MAX); let x7 = input.clamp(CONST_MIN, CONST_MAX); @@ -191,68 +187,51 @@ fn const_main() { let x16 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - let x17 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - let x18 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - let x19 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - let x20 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - let x21 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - let x22 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - let x23 = input.clamp(CONST_MIN, CONST_MAX); //~^ manual_clamp - let input: f64 = cmp_min_max(1) as f64; let x24 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); //~^ manual_clamp - let x25 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); //~^ manual_clamp - let x26 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); //~^ manual_clamp - let x27 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); //~^ manual_clamp - let x28 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); //~^ manual_clamp - let x29 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); //~^ manual_clamp - let x30 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); //~^ manual_clamp - let x31 = input.clamp(CONST_F64_MIN, CONST_F64_MAX); //~^ manual_clamp - - } let mut x32 = input; x32 = x32.clamp(CONST_MIN, CONST_MAX); diff --git a/tests/ui/manual_clamp.rs b/tests/ui/manual_clamp.rs index bf40e09969a4..ee341d50768f 100644 --- a/tests/ui/manual_clamp.rs +++ b/tests/ui/manual_clamp.rs @@ -142,8 +142,7 @@ fn const_main() { let input = 0; // Min and max are const, so this should trigger the lint. let x0 = if CONST_MAX < input { - //~^ manual_clamp - + //~^ manual_clamp CONST_MAX } else if CONST_MIN > input { @@ -153,8 +152,7 @@ fn const_main() { }; let x1 = if input > CONST_MAX { - //~^ manual_clamp - + //~^ manual_clamp CONST_MAX } else if input < CONST_MIN { @@ -164,8 +162,7 @@ fn const_main() { }; let x2 = if input < CONST_MIN { - //~^ manual_clamp - + //~^ manual_clamp CONST_MIN } else if input > CONST_MAX { @@ -175,8 +172,7 @@ fn const_main() { }; let x3 = if CONST_MIN > input { - //~^ manual_clamp - + //~^ manual_clamp CONST_MIN } else if CONST_MAX < input { @@ -188,35 +184,25 @@ fn const_main() { let x4 = input.max(CONST_MIN).min(CONST_MAX); //~^ manual_clamp - - let x5 = input.min(CONST_MAX).max(CONST_MIN); //~^ manual_clamp - - let x6 = match input { - //~^ manual_clamp - - + //~^ manual_clamp x if x > CONST_MAX => CONST_MAX, x if x < CONST_MIN => CONST_MIN, x => x, }; let x7 = match input { - //~^ manual_clamp - - + //~^ manual_clamp x if x < CONST_MIN => CONST_MIN, x if x > CONST_MAX => CONST_MAX, x => x, }; let x8 = match input { - //~^ manual_clamp - - + //~^ manual_clamp x if CONST_MAX < x => CONST_MAX, x if CONST_MIN > x => CONST_MIN, x => x, @@ -224,8 +210,7 @@ fn const_main() { let mut x9 = input; if x9 < CONST_MIN { - //~^ manual_clamp - + //~^ manual_clamp x9 = CONST_MIN; } @@ -234,9 +219,7 @@ fn const_main() { } let x10 = match input { - //~^ manual_clamp - - + //~^ manual_clamp x if CONST_MIN > x => CONST_MIN, x if CONST_MAX < x => CONST_MAX, x => x, @@ -245,8 +228,7 @@ fn const_main() { let mut x11 = input; let _ = 1; if x11 > CONST_MAX { - //~^ manual_clamp - + //~^ manual_clamp x11 = CONST_MAX; } @@ -256,8 +238,7 @@ fn const_main() { let mut x12 = input; if CONST_MIN > x12 { - //~^ manual_clamp - + //~^ manual_clamp x12 = CONST_MIN; } @@ -267,8 +248,7 @@ fn const_main() { let mut x13 = input; if CONST_MAX < x13 { - //~^ manual_clamp - + //~^ manual_clamp x13 = CONST_MAX; } @@ -277,8 +257,7 @@ fn const_main() { } let x14 = if input > CONST_MAX { - //~^ manual_clamp - + //~^ manual_clamp CONST_MAX } else if input < CONST_MIN { @@ -289,8 +268,7 @@ fn const_main() { { let input = 0.0f64; let x15 = if input > CONST_F64_MAX { - //~^ manual_clamp - + //~^ manual_clamp CONST_F64_MAX } else if input < CONST_F64_MIN { @@ -305,73 +283,55 @@ fn const_main() { let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); //~^ manual_clamp - let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); //~^ manual_clamp - let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); //~^ manual_clamp - let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); //~^ manual_clamp - let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); //~^ manual_clamp - let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); //~^ manual_clamp - let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); //~^ manual_clamp - let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); //~^ manual_clamp - let input: f64 = cmp_min_max(1) as f64; let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); //~^ manual_clamp - let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); //~^ manual_clamp - let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); //~^ manual_clamp - let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); //~^ manual_clamp - let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); //~^ manual_clamp - let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); //~^ manual_clamp - let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); //~^ manual_clamp - let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); //~^ manual_clamp - - } let mut x32 = input; if x32 < CONST_MIN { - //~^ manual_clamp - + //~^ manual_clamp x32 = CONST_MIN; } else if x32 > CONST_MAX { @@ -401,8 +361,7 @@ fn const_main() { // It's important this be the last set of statements let mut x35 = input; if CONST_MAX < x35 { - //~^ manual_clamp - + //~^ manual_clamp x35 = CONST_MAX; } @@ -564,8 +523,7 @@ fn msrv_1_49() { fn msrv_1_50() { let input = 0; let _ = if input > CONST_MAX { - //~^ manual_clamp - + //~^ manual_clamp CONST_MAX } else if input < CONST_MIN { diff --git a/tests/ui/manual_clamp.stderr b/tests/ui/manual_clamp.stderr index ca7da23efec2..4a0e4fa51646 100644 --- a/tests/ui/manual_clamp.stderr +++ b/tests/ui/manual_clamp.stderr @@ -1,7 +1,10 @@ error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:226:5 + --> tests/ui/manual_clamp.rs:212:5 | LL | / if x9 < CONST_MIN { +LL | | +LL | | +LL | | x9 = CONST_MIN; ... | LL | | x9 = CONST_MAX; LL | | } @@ -12,9 +15,12 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_clamp)]` error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:247:5 + --> tests/ui/manual_clamp.rs:230:5 | LL | / if x11 > CONST_MAX { +LL | | +LL | | +LL | | x11 = CONST_MAX; ... | LL | | x11 = CONST_MIN; LL | | } @@ -23,9 +29,12 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:258:5 + --> tests/ui/manual_clamp.rs:240:5 | LL | / if CONST_MIN > x12 { +LL | | +LL | | +LL | | x12 = CONST_MIN; ... | LL | | x12 = CONST_MAX; LL | | } @@ -34,9 +43,12 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:269:5 + --> tests/ui/manual_clamp.rs:250:5 | LL | / if CONST_MAX < x13 { +LL | | +LL | | +LL | | x13 = CONST_MAX; ... | LL | | x13 = CONST_MIN; LL | | } @@ -45,9 +57,12 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:403:5 + --> tests/ui/manual_clamp.rs:363:5 | LL | / if CONST_MAX < x35 { +LL | | +LL | | +LL | | x35 = CONST_MAX; ... | LL | | x35 = CONST_MIN; LL | | } @@ -60,6 +75,9 @@ error: clamp-like pattern without using clamp function | LL | let x0 = if CONST_MAX < input { | ______________^ +LL | | +LL | | +LL | | CONST_MAX ... | LL | | input LL | | }; @@ -68,10 +86,13 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:155:14 + --> tests/ui/manual_clamp.rs:154:14 | LL | let x1 = if input > CONST_MAX { | ______________^ +LL | | +LL | | +LL | | CONST_MAX ... | LL | | input LL | | }; @@ -80,10 +101,13 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:166:14 + --> tests/ui/manual_clamp.rs:164:14 | LL | let x2 = if input < CONST_MIN { | ______________^ +LL | | +LL | | +LL | | CONST_MIN ... | LL | | input LL | | }; @@ -92,10 +116,13 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:177:14 + --> tests/ui/manual_clamp.rs:174:14 | LL | let x3 = if CONST_MIN > input { | ______________^ +LL | | +LL | | +LL | | CONST_MIN ... | LL | | input LL | | }; @@ -104,7 +131,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:188:14 + --> tests/ui/manual_clamp.rs:184:14 | LL | let x4 = input.max(CONST_MIN).min(CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -112,7 +139,7 @@ LL | let x4 = input.max(CONST_MIN).min(CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:193:14 + --> tests/ui/manual_clamp.rs:187:14 | LL | let x5 = input.min(CONST_MAX).max(CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -120,11 +147,13 @@ LL | let x5 = input.min(CONST_MAX).max(CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:198:14 + --> tests/ui/manual_clamp.rs:190:14 | LL | let x6 = match input { | ______________^ -... | +LL | | +LL | | x if x > CONST_MAX => CONST_MAX, +LL | | x if x < CONST_MIN => CONST_MIN, LL | | x => x, LL | | }; | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -132,11 +161,13 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:207:14 + --> tests/ui/manual_clamp.rs:197:14 | LL | let x7 = match input { | ______________^ -... | +LL | | +LL | | x if x < CONST_MIN => CONST_MIN, +LL | | x if x > CONST_MAX => CONST_MAX, LL | | x => x, LL | | }; | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -144,11 +175,13 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:216:14 + --> tests/ui/manual_clamp.rs:204:14 | LL | let x8 = match input { | ______________^ -... | +LL | | +LL | | x if CONST_MAX < x => CONST_MAX, +LL | | x if CONST_MIN > x => CONST_MIN, LL | | x => x, LL | | }; | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -156,11 +189,13 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:236:15 + --> tests/ui/manual_clamp.rs:221:15 | LL | let x10 = match input { | _______________^ -... | +LL | | +LL | | x if CONST_MIN > x => CONST_MIN, +LL | | x if CONST_MAX < x => CONST_MAX, LL | | x => x, LL | | }; | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -168,10 +203,13 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:279:15 + --> tests/ui/manual_clamp.rs:259:15 | LL | let x14 = if input > CONST_MAX { | _______________^ +LL | | +LL | | +LL | | CONST_MAX ... | LL | | input LL | | }; @@ -180,10 +218,13 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:291:19 + --> tests/ui/manual_clamp.rs:270:19 | LL | let x15 = if input > CONST_F64_MAX { | ___________________^ +LL | | +LL | | +LL | | CONST_F64_MAX ... | LL | | input LL | | }; @@ -193,7 +234,7 @@ LL | | }; = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:305:19 + --> tests/ui/manual_clamp.rs:283:19 | LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -201,7 +242,7 @@ LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:309:19 + --> tests/ui/manual_clamp.rs:286:19 | LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -209,7 +250,7 @@ LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:313:19 + --> tests/ui/manual_clamp.rs:289:19 | LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -217,7 +258,7 @@ LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:317:19 + --> tests/ui/manual_clamp.rs:292:19 | LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -225,7 +266,7 @@ LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:321:19 + --> tests/ui/manual_clamp.rs:295:19 | LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -233,7 +274,7 @@ LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:325:19 + --> tests/ui/manual_clamp.rs:298:19 | LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -241,7 +282,7 @@ LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:329:19 + --> tests/ui/manual_clamp.rs:301:19 | LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -249,7 +290,7 @@ LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:333:19 + --> tests/ui/manual_clamp.rs:304:19 | LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -257,7 +298,7 @@ LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:338:19 + --> tests/ui/manual_clamp.rs:308:19 | LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -266,7 +307,7 @@ LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:342:19 + --> tests/ui/manual_clamp.rs:311:19 | LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -275,7 +316,7 @@ LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:346:19 + --> tests/ui/manual_clamp.rs:314:19 | LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -284,7 +325,7 @@ LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:350:19 + --> tests/ui/manual_clamp.rs:317:19 | LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -293,7 +334,7 @@ LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:354:19 + --> tests/ui/manual_clamp.rs:320:19 | LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -302,7 +343,7 @@ LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:358:19 + --> tests/ui/manual_clamp.rs:323:19 | LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -311,7 +352,7 @@ LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:362:19 + --> tests/ui/manual_clamp.rs:326:19 | LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -320,7 +361,7 @@ LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:366:19 + --> tests/ui/manual_clamp.rs:329:19 | LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -329,10 +370,13 @@ LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:372:5 + --> tests/ui/manual_clamp.rs:333:5 | LL | / if x32 < CONST_MIN { -... | +LL | | +LL | | +LL | | x32 = CONST_MIN; +LL | | } else if x32 > CONST_MAX { LL | | x32 = CONST_MAX; LL | | } | |_____^ help: replace with clamp: `x32 = x32.clamp(CONST_MIN, CONST_MAX);` @@ -340,10 +384,13 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:566:13 + --> tests/ui/manual_clamp.rs:525:13 | LL | let _ = if input > CONST_MAX { | _____________^ +LL | | +LL | | +LL | | CONST_MAX ... | LL | | input LL | | }; diff --git a/tests/ui/manual_div_ceil.fixed b/tests/ui/manual_div_ceil.fixed index 6657c695abea..57fe8917afe8 100644 --- a/tests/ui/manual_div_ceil.fixed +++ b/tests/ui/manual_div_ceil.fixed @@ -6,17 +6,17 @@ fn main() { let z = 11_u32; // Lint -let _ = x.div_ceil(y); -//~^ manual_div_ceil -let _ = x.div_ceil(y); -//~^ manual_div_ceil -let _ = x.div_ceil(y); -//~^ manual_div_ceil + let _ = x.div_ceil(y); + //~^ manual_div_ceil + let _ = x.div_ceil(y); + //~^ manual_div_ceil + let _ = x.div_ceil(y); + //~^ manual_div_ceil -let _ = 7_u32.div_ceil(4); -//~^ manual_div_ceil -let _ = (7_i32 as u32).div_ceil(4); -//~^ manual_div_ceil + let _ = 7_u32.div_ceil(4); + //~^ manual_div_ceil + let _ = (7_i32 as u32).div_ceil(4); + //~^ manual_div_ceil // No lint let _ = (x + (y - 2)) / y; diff --git a/tests/ui/manual_div_ceil.rs b/tests/ui/manual_div_ceil.rs index 2c8506e84cb5..ec343513e5ce 100644 --- a/tests/ui/manual_div_ceil.rs +++ b/tests/ui/manual_div_ceil.rs @@ -6,17 +6,17 @@ fn main() { let z = 11_u32; // Lint -let _ = (x + (y - 1)) / y; -//~^ manual_div_ceil -let _ = ((y - 1) + x) / y; -//~^ manual_div_ceil -let _ = (x + y - 1) / y; -//~^ manual_div_ceil + let _ = (x + (y - 1)) / y; + //~^ manual_div_ceil + let _ = ((y - 1) + x) / y; + //~^ manual_div_ceil + let _ = (x + y - 1) / y; + //~^ manual_div_ceil -let _ = (7_u32 + (4 - 1)) / 4; -//~^ manual_div_ceil -let _ = (7_i32 as u32 + (4 - 1)) / 4; -//~^ manual_div_ceil + let _ = (7_u32 + (4 - 1)) / 4; + //~^ manual_div_ceil + let _ = (7_i32 as u32 + (4 - 1)) / 4; + //~^ manual_div_ceil // No lint let _ = (x + (y - 2)) / y; diff --git a/tests/ui/manual_div_ceil.stderr b/tests/ui/manual_div_ceil.stderr index d6793dcfb5f3..8e14ab274269 100644 --- a/tests/ui/manual_div_ceil.stderr +++ b/tests/ui/manual_div_ceil.stderr @@ -1,35 +1,35 @@ error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:9:9 + --> tests/ui/manual_div_ceil.rs:9:13 | -LL | let _ = (x + (y - 1)) / y; - | ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` +LL | let _ = (x + (y - 1)) / y; + | ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` | = note: `-D clippy::manual-div-ceil` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::manual_div_ceil)]` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:11:9 + --> tests/ui/manual_div_ceil.rs:11:13 | -LL | let _ = ((y - 1) + x) / y; - | ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` +LL | let _ = ((y - 1) + x) / y; + | ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:13:9 + --> tests/ui/manual_div_ceil.rs:13:13 | -LL | let _ = (x + y - 1) / y; - | ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` +LL | let _ = (x + y - 1) / y; + | ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:16:9 + --> tests/ui/manual_div_ceil.rs:16:13 | -LL | let _ = (7_u32 + (4 - 1)) / 4; - | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `7_u32.div_ceil(4)` +LL | let _ = (7_u32 + (4 - 1)) / 4; + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `7_u32.div_ceil(4)` error: manually reimplementing `div_ceil` - --> tests/ui/manual_div_ceil.rs:18:9 + --> tests/ui/manual_div_ceil.rs:18:13 | -LL | let _ = (7_i32 as u32 + (4 - 1)) / 4; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)` +LL | let _ = (7_i32 as u32 + (4 - 1)) / 4; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)` error: manually reimplementing `div_ceil` --> tests/ui/manual_div_ceil.rs:39:13 diff --git a/tests/ui/manual_filter.rs b/tests/ui/manual_filter.rs index a83a316f95ad..a9d0c35f8bb7 100644 --- a/tests/ui/manual_filter.rs +++ b/tests/ui/manual_filter.rs @@ -3,7 +3,7 @@ fn main() { match Some(0) { - //~^ manual_filter + //~^ manual_filter None => None, Some(x) => { if x > 0 { @@ -15,7 +15,7 @@ fn main() { }; match Some(1) { - //~^ manual_filter + //~^ manual_filter Some(x) => { if x > 0 { None @@ -27,7 +27,7 @@ fn main() { }; match Some(2) { - //~^ manual_filter + //~^ manual_filter Some(x) => { if x > 0 { None @@ -39,7 +39,7 @@ fn main() { }; match Some(3) { - //~^ manual_filter + //~^ manual_filter Some(x) => { if x > 0 { Some(x) @@ -52,7 +52,7 @@ fn main() { let y = Some(4); match y { - //~^ manual_filter + //~^ manual_filter // Some(4) None => None, Some(x) => { @@ -65,7 +65,7 @@ fn main() { }; match Some(5) { - //~^ manual_filter + //~^ manual_filter Some(x) => { if x > 0 { Some(x) @@ -77,7 +77,7 @@ fn main() { }; match Some(6) { - //~^ manual_filter + //~^ manual_filter Some(ref x) => { if x > &0 { Some(x) @@ -90,7 +90,7 @@ fn main() { let external_cond = true; match Some(String::new()) { - //~^ manual_filter + //~^ manual_filter Some(x) => { if external_cond { Some(x) @@ -102,14 +102,14 @@ fn main() { }; if let Some(x) = Some(7) { - //~^ manual_filter + //~^ manual_filter if external_cond { Some(x) } else { None } } else { None }; match &Some(8) { - //~^ manual_filter + //~^ manual_filter &Some(x) => { if x != 0 { Some(x) @@ -121,7 +121,7 @@ fn main() { }; match Some(9) { - //~^ manual_filter + //~^ manual_filter Some(x) => { if x > 10 && x < 100 { Some(x) @@ -148,7 +148,7 @@ fn main() { #[allow(clippy::blocks_in_conditions)] match Some(11) { - //~^ manual_filter + //~^ manual_filter // Lint, statement is preserved by `.filter` Some(x) => { if { @@ -193,7 +193,7 @@ fn main() { true } let _ = match Some(14) { - //~^ manual_filter + //~^ manual_filter Some(x) => { if unsafe { f(x) } { Some(x) @@ -204,7 +204,7 @@ fn main() { None => None, }; let _ = match Some(15) { - //~^ manual_filter + //~^ manual_filter Some(x) => unsafe { if f(x) { Some(x) } else { None } }, None => None, }; @@ -213,7 +213,7 @@ fn main() { if let Some(_) = Some(16) { Some(16) } else if let Some(x) = Some(16) { - //~^ manual_filter + //~^ manual_filter // Lint starting from here if x % 2 == 0 { Some(x) } else { None } } else { diff --git a/tests/ui/manual_filter_map.rs b/tests/ui/manual_filter_map.rs index 75e15d3b5a5a..013c88da6b36 100644 --- a/tests/ui/manual_filter_map.rs +++ b/tests/ui/manual_filter_map.rs @@ -171,7 +171,7 @@ fn issue8010() { let iter = [Enum::A(123), Enum::B].into_iter(); let _x = iter.clone().filter(|x| matches!(x, Enum::A(_))).map(|x| match x { - //~^ manual_filter_map + //~^ manual_filter_map Enum::A(s) => s, _ => unreachable!(), }); diff --git a/tests/ui/manual_find.rs b/tests/ui/manual_find.rs index d3c24d0b8849..20b557f21d14 100644 --- a/tests/ui/manual_find.rs +++ b/tests/ui/manual_find.rs @@ -3,8 +3,7 @@ //@no-rustfix fn vec_string(strings: Vec) -> Option { for s in strings { - //~^ manual_find - + //~^ manual_find if s == String::new() { return Some(s); @@ -15,8 +14,7 @@ fn vec_string(strings: Vec) -> Option { fn tuple(arr: Vec<(String, i32)>) -> Option { for (s, _) in arr { - //~^ manual_find - + //~^ manual_find if s == String::new() { return Some(s); diff --git a/tests/ui/manual_find.stderr b/tests/ui/manual_find.stderr index 2dbe0b16b75a..a4e7878a247c 100644 --- a/tests/ui/manual_find.stderr +++ b/tests/ui/manual_find.stderr @@ -2,6 +2,9 @@ error: manual implementation of `Iterator::find` --> tests/ui/manual_find.rs:5:5 | LL | / for s in strings { +LL | | +LL | | +LL | | if s == String::new() { ... | LL | | None | |________^ help: replace with an iterator: `strings.into_iter().find(|s| s == String::new())` @@ -11,9 +14,12 @@ LL | | None = help: to override `-D warnings` add `#[allow(clippy::manual_find)]` error: manual implementation of `Iterator::find` - --> tests/ui/manual_find.rs:17:5 + --> tests/ui/manual_find.rs:16:5 | LL | / for (s, _) in arr { +LL | | +LL | | +LL | | if s == String::new() { ... | LL | | None | |________^ help: replace with an iterator: `arr.into_iter().map(|(s, _)| s).find(|s| s == String::new())` diff --git a/tests/ui/manual_find_fixable.rs b/tests/ui/manual_find_fixable.rs index 3966d8df89b9..08a7dd2c6eee 100644 --- a/tests/ui/manual_find_fixable.rs +++ b/tests/ui/manual_find_fixable.rs @@ -8,7 +8,7 @@ const ARRAY: &[u32; 5] = &[2, 7, 1, 9, 3]; fn lookup(n: u32) -> Option { for &v in ARRAY { - //~^ manual_find + //~^ manual_find if v == n { return Some(v); } @@ -18,7 +18,7 @@ fn lookup(n: u32) -> Option { fn with_pat(arr: Vec<(u32, u32)>) -> Option { for (a, _) in arr { - //~^ manual_find + //~^ manual_find if a % 2 == 0 { return Some(a); } @@ -32,7 +32,7 @@ struct Data { } fn with_struct(arr: Vec) -> Option { for el in arr { - //~^ manual_find + //~^ manual_find if el.name.len() == 10 { return Some(el); } @@ -43,7 +43,7 @@ fn with_struct(arr: Vec) -> Option { struct Tuple(usize, usize); fn with_tuple_struct(arr: Vec) -> Option { for Tuple(a, _) in arr { - //~^ manual_find + //~^ manual_find if a >= 3 { return Some(a); } @@ -59,7 +59,7 @@ impl A { } fn with_method_call(arr: Vec) -> Option { for el in arr { - //~^ manual_find + //~^ manual_find if el.should_keep() { return Some(el); } @@ -70,7 +70,7 @@ fn with_method_call(arr: Vec) -> Option { fn with_closure(arr: Vec) -> Option { let f = |el: u32| -> u32 { el + 10 }; for el in arr { - //~^ manual_find + //~^ manual_find if f(el) == 20 { return Some(el); } @@ -81,7 +81,7 @@ fn with_closure(arr: Vec) -> Option { fn with_closure2(arr: HashMap) -> Option { let f = |el: i32| -> bool { el == 10 }; for &el in arr.values() { - //~^ manual_find + //~^ manual_find if f(el) { return Some(el); } @@ -91,7 +91,7 @@ fn with_closure2(arr: HashMap) -> Option { fn with_bool(arr: Vec) -> Option { for el in arr { - //~^ manual_find + //~^ manual_find if el.is_true { return Some(el); } @@ -122,7 +122,7 @@ fn with_else(arr: Vec) -> Option { fn tuple_with_ref(v: [(u8, &u8); 3]) -> Option { for (_, &x) in v { - //~^ manual_find + //~^ manual_find if x > 10 { return Some(x); } @@ -132,7 +132,7 @@ fn tuple_with_ref(v: [(u8, &u8); 3]) -> Option { fn ref_to_tuple_with_ref(v: &[(u8, &u8)]) -> Option { for &(_, &x) in v { - //~^ manual_find + //~^ manual_find if x > 10 { return Some(x); } @@ -142,7 +142,7 @@ fn ref_to_tuple_with_ref(v: &[(u8, &u8)]) -> Option { fn explicit_ret(arr: Vec) -> Option { for x in arr { - //~^ manual_find + //~^ manual_find if x >= 5 { return Some(x); } diff --git a/tests/ui/manual_flatten.rs b/tests/ui/manual_flatten.rs index e22025c6f1a8..97f35c36e24c 100644 --- a/tests/ui/manual_flatten.rs +++ b/tests/ui/manual_flatten.rs @@ -5,7 +5,7 @@ fn main() { // Test for loop over implicitly adjusted `Iterator` with `if let` expression let x = vec![Some(1), Some(2), Some(3)]; for n in x { - //~^ manual_flatten + //~^ manual_flatten if let Some(y) = n { println!("{}", y); @@ -15,7 +15,7 @@ fn main() { // Test for loop over implicitly adjusted `Iterator` with `if let` statement let y: Vec> = vec![]; for n in y.clone() { - //~^ manual_flatten + //~^ manual_flatten if let Ok(n) = n { println!("{}", n); @@ -24,7 +24,7 @@ fn main() { // Test for loop over by reference for n in &y { - //~^ manual_flatten + //~^ manual_flatten if let Ok(n) = n { println!("{}", n); @@ -34,7 +34,7 @@ fn main() { // Test for loop over an implicit reference let z = &y; for n in z { - //~^ manual_flatten + //~^ manual_flatten if let Ok(n) = n { println!("{}", n); @@ -45,7 +45,7 @@ fn main() { let z = vec![Some(1), Some(2), Some(3)]; let z = z.iter(); for n in z { - //~^ manual_flatten + //~^ manual_flatten if let Some(m) = n { println!("{}", m); @@ -80,7 +80,7 @@ fn main() { let vec_of_ref = vec![&Some(1)]; for n in &vec_of_ref { - //~^ manual_flatten + //~^ manual_flatten if let Some(n) = n { println!("{:?}", n); @@ -89,7 +89,7 @@ fn main() { let vec_of_ref = &vec_of_ref; for n in vec_of_ref { - //~^ manual_flatten + //~^ manual_flatten if let Some(n) = n { println!("{:?}", n); @@ -98,7 +98,7 @@ fn main() { let slice_of_ref = &[&Some(1)]; for n in slice_of_ref { - //~^ manual_flatten + //~^ manual_flatten if let Some(n) = n { println!("{:?}", n); diff --git a/tests/ui/manual_ignore_case_cmp.fixed b/tests/ui/manual_ignore_case_cmp.fixed index a75b0702a5ff..c1c929585cfd 100644 --- a/tests/ui/manual_ignore_case_cmp.fixed +++ b/tests/ui/manual_ignore_case_cmp.fixed @@ -7,11 +7,11 @@ fn main() {} fn variants(a: &str, b: &str) { if a.eq_ignore_ascii_case(b) { - //~^ manual_ignore_case_cmp + //~^ manual_ignore_case_cmp return; } if a.eq_ignore_ascii_case(b) { - //~^ manual_ignore_case_cmp + //~^ manual_ignore_case_cmp return; } let r = a.eq_ignore_ascii_case(b); @@ -22,11 +22,11 @@ fn variants(a: &str, b: &str) { //~^ manual_ignore_case_cmp // != if !a.eq_ignore_ascii_case(b) { - //~^ manual_ignore_case_cmp + //~^ manual_ignore_case_cmp return; } if !a.eq_ignore_ascii_case(b) { - //~^ manual_ignore_case_cmp + //~^ manual_ignore_case_cmp return; } let r = !a.eq_ignore_ascii_case(b); diff --git a/tests/ui/manual_ignore_case_cmp.rs b/tests/ui/manual_ignore_case_cmp.rs index 822f171a4506..ca401e595fe9 100644 --- a/tests/ui/manual_ignore_case_cmp.rs +++ b/tests/ui/manual_ignore_case_cmp.rs @@ -7,11 +7,11 @@ fn main() {} fn variants(a: &str, b: &str) { if a.to_ascii_lowercase() == b.to_ascii_lowercase() { - //~^ manual_ignore_case_cmp + //~^ manual_ignore_case_cmp return; } if a.to_ascii_uppercase() == b.to_ascii_uppercase() { - //~^ manual_ignore_case_cmp + //~^ manual_ignore_case_cmp return; } let r = a.to_ascii_lowercase() == b.to_ascii_lowercase(); @@ -22,11 +22,11 @@ fn variants(a: &str, b: &str) { //~^ manual_ignore_case_cmp // != if a.to_ascii_lowercase() != b.to_ascii_lowercase() { - //~^ manual_ignore_case_cmp + //~^ manual_ignore_case_cmp return; } if a.to_ascii_uppercase() != b.to_ascii_uppercase() { - //~^ manual_ignore_case_cmp + //~^ manual_ignore_case_cmp return; } let r = a.to_ascii_lowercase() != b.to_ascii_lowercase(); diff --git a/tests/ui/manual_inspect.fixed b/tests/ui/manual_inspect.fixed index 8512da0bdf62..44f15d61f856 100644 --- a/tests/ui/manual_inspect.fixed +++ b/tests/ui/manual_inspect.fixed @@ -3,29 +3,29 @@ fn main() { let _ = Some(0).inspect(|&x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x); }); let _ = Some(0).inspect(|&x| { - //~^ manual_inspect + //~^ manual_inspect println!("{x}"); }); let _ = Some(0).inspect(|&x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x * 5 + 1); }); let _ = Some(0).inspect(|&x| { - //~^ manual_inspect + //~^ manual_inspect if x == 0 { panic!(); } }); let _ = Some(0).inspect(|&x| { - //~^ manual_inspect + //~^ manual_inspect if &x == &0 { let _y = x; panic!(); @@ -76,7 +76,7 @@ fn main() { } let _ = Some((String::new(), 0u32)).inspect(|x| { - //~^ manual_inspect + //~^ manual_inspect if x.1 == 0 { let _x = x.1; panic!(); @@ -102,7 +102,7 @@ fn main() { }); let _ = Some(String::new()).inspect(|x| { - //~^ manual_inspect + //~^ manual_inspect if x.is_empty() { let _ = || { let _x = x; @@ -113,7 +113,7 @@ fn main() { }); let _ = Some(0).inspect(|&x| { - //~^ manual_inspect + //~^ manual_inspect if x == 0 { let _ = || { let _x = x; @@ -128,7 +128,7 @@ fn main() { struct Cell2(core::cell::Cell); let _ = Some(Cell2(Cell::new(0u32))).inspect(|x| { - //~^ manual_inspect + //~^ manual_inspect x.0.set(1); }); @@ -144,20 +144,20 @@ fn main() { } let _: Result<_, ()> = Ok(0).inspect(|&x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x); }); let _: Result<(), _> = Err(0).inspect_err(|&x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x); }); let _ = [0] - //~^ suspicious_map + //~^ suspicious_map .into_iter() .inspect(|&x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x); }) .count(); diff --git a/tests/ui/manual_inspect.rs b/tests/ui/manual_inspect.rs index 7f07394d4b22..d34f2abce6ae 100644 --- a/tests/ui/manual_inspect.rs +++ b/tests/ui/manual_inspect.rs @@ -3,25 +3,25 @@ fn main() { let _ = Some(0).map(|x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x); x }); let _ = Some(0).map(|x| { - //~^ manual_inspect + //~^ manual_inspect println!("{x}"); x }); let _ = Some(0).map(|x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x * 5 + 1); x }); let _ = Some(0).map(|x| { - //~^ manual_inspect + //~^ manual_inspect if x == 0 { panic!(); } @@ -29,7 +29,7 @@ fn main() { }); let _ = Some(0).map(|x| { - //~^ manual_inspect + //~^ manual_inspect if &x == &0 { let _y = x; panic!(); @@ -81,7 +81,7 @@ fn main() { } let _ = Some((String::new(), 0u32)).map(|x| { - //~^ manual_inspect + //~^ manual_inspect if x.1 == 0 { let _x = x.1; panic!(); @@ -108,7 +108,7 @@ fn main() { }); let _ = Some(String::new()).map(|x| { - //~^ manual_inspect + //~^ manual_inspect if x.is_empty() { let _ = || { let _x = &x; @@ -120,7 +120,7 @@ fn main() { }); let _ = Some(0).map(|x| { - //~^ manual_inspect + //~^ manual_inspect if x == 0 { let _ = || { let _x = x; @@ -136,7 +136,7 @@ fn main() { struct Cell2(core::cell::Cell); let _ = Some(Cell2(Cell::new(0u32))).map(|x| { - //~^ manual_inspect + //~^ manual_inspect x.0.set(1); x }); @@ -153,22 +153,22 @@ fn main() { } let _: Result<_, ()> = Ok(0).map(|x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x); x }); let _: Result<(), _> = Err(0).map_err(|x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x); x }); let _ = [0] - //~^ suspicious_map + //~^ suspicious_map .into_iter() .map(|x| { - //~^ manual_inspect + //~^ manual_inspect println!("{}", x); x }) diff --git a/tests/ui/manual_let_else.rs b/tests/ui/manual_let_else.rs index e5ef55c0b8a8..d2350d97ed00 100644 --- a/tests/ui/manual_let_else.rs +++ b/tests/ui/manual_let_else.rs @@ -29,9 +29,8 @@ fn fire() { let v = if let Some(v_some) = g() { v_some } else { return }; //~^ manual_let_else - let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -39,7 +38,7 @@ fn fire() { }; let v = if let Some(v) = g() { - //~^ manual_let_else + //~^ manual_let_else // Blocks around the identity should have no impact { { v } } @@ -56,17 +55,15 @@ fn fire() { let v = if let Some(v_some) = g() { v_some } else { break }; //~^ manual_let_else - } // panic also diverges let v = if let Some(v_some) = g() { v_some } else { panic!() }; //~^ manual_let_else - // abort also diverges let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -75,7 +72,7 @@ fn fire() { // If whose two branches diverge also diverges let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -84,7 +81,7 @@ fn fire() { // Diverging after an if still makes the block diverge: let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -94,7 +91,7 @@ fn fire() { // The final expression will need to be turned into a statement. let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -104,7 +101,7 @@ fn fire() { // Even if the result is buried multiple expressions deep. let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -121,7 +118,7 @@ fn fire() { // Or if a break gives the value. let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -133,7 +130,7 @@ fn fire() { // Even if the break is in a weird position. let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -150,7 +147,7 @@ fn fire() { // A match diverges if all branches diverge: let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -162,7 +159,7 @@ fn fire() { // An if's expression can cause divergence: let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -171,7 +168,7 @@ fn fire() { // An expression of a match can cause divergence: let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -182,7 +179,7 @@ fn fire() { // Top level else if let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else if true { @@ -193,7 +190,7 @@ fn fire() { // All match arms diverge let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -212,7 +209,7 @@ fn fire() { // Tuples supported for the declared variables let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) { - //~^ manual_let_else + //~^ manual_let_else v_some } else { @@ -221,7 +218,7 @@ fn fire() { // Tuples supported with multiple bindings let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) { - //~^ manual_let_else + //~^ manual_let_else (w_some, v_some) } else { @@ -244,16 +241,14 @@ fn fire() { let v = if let Variant::A(a, 0) = e() { a } else { return }; //~^ manual_let_else - // `mut v` is inserted into the pattern let mut v = if let Variant::B(b) = e() { b } else { return }; //~^ manual_let_else - // Nesting works let nested = Ok(Some(e())); let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { - //~^ manual_let_else + //~^ manual_let_else b } else { @@ -263,15 +258,13 @@ fn fire() { let v = if let Variant::A(.., a) = e() { a } else { return }; //~^ manual_let_else - // () is preserved: a bit of an edge case but make sure it stays around let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; //~^ manual_let_else - // Tuple structs work let w = if let Some(S { v: x }) = Some(S { v: 0 }) { - //~^ manual_let_else + //~^ manual_let_else x } else { @@ -280,7 +273,7 @@ fn fire() { // Field init shorthand is suggested let v = if let Some(S { v: x }) = Some(S { v: 0 }) { - //~^ manual_let_else + //~^ manual_let_else x } else { @@ -289,7 +282,7 @@ fn fire() { // Multi-field structs also work let (x, S { v }, w) = if let Some(U { v, w, x }) = None::>> { - //~^ manual_let_else + //~^ manual_let_else (x, v, w) } else { @@ -407,8 +400,7 @@ fn not_fire() { let ff = Some(1); let _ = match ff { - //~^ manual_let_else - + //~^ manual_let_else Some(value) => value, _ => macro_call!(), }; diff --git a/tests/ui/manual_let_else.stderr b/tests/ui/manual_let_else.stderr index 8982a1c567bf..8f5cba64d545 100644 --- a/tests/ui/manual_let_else.stderr +++ b/tests/ui/manual_let_else.stderr @@ -8,7 +8,7 @@ LL | let v = if let Some(v_some) = g() { v_some } else { return }; = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:33:5 + --> tests/ui/manual_let_else.rs:32:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -27,7 +27,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:41:5 + --> tests/ui/manual_let_else.rs:40:5 | LL | / let v = if let Some(v) = g() { ... | @@ -45,25 +45,25 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:54:9 + --> tests/ui/manual_let_else.rs:53:9 | LL | let v = if let Some(v_some) = g() { v_some } else { continue }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:57:9 + --> tests/ui/manual_let_else.rs:56:9 | LL | let v = if let Some(v_some) = g() { v_some } else { break }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:63:5 + --> tests/ui/manual_let_else.rs:61:5 | LL | let v = if let Some(v_some) = g() { v_some } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:68:5 + --> tests/ui/manual_let_else.rs:65:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -82,7 +82,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:77:5 + --> tests/ui/manual_let_else.rs:74:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -101,7 +101,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:86:5 + --> tests/ui/manual_let_else.rs:83:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -121,7 +121,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:96:5 + --> tests/ui/manual_let_else.rs:93:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -141,7 +141,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:106:5 + --> tests/ui/manual_let_else.rs:103:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -167,7 +167,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:123:5 + --> tests/ui/manual_let_else.rs:120:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -188,7 +188,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:135:5 + --> tests/ui/manual_let_else.rs:132:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -214,7 +214,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:152:5 + --> tests/ui/manual_let_else.rs:149:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -236,7 +236,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:164:5 + --> tests/ui/manual_let_else.rs:161:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -255,7 +255,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:173:5 + --> tests/ui/manual_let_else.rs:170:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -276,7 +276,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:184:5 + --> tests/ui/manual_let_else.rs:181:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -297,7 +297,7 @@ LL + } }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:195:5 + --> tests/ui/manual_let_else.rs:192:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -325,7 +325,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:214:5 + --> tests/ui/manual_let_else.rs:211:5 | LL | / let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) { LL | | @@ -344,7 +344,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:223:5 + --> tests/ui/manual_let_else.rs:220:5 | LL | / let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) { LL | | @@ -363,7 +363,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:234:13 + --> tests/ui/manual_let_else.rs:231:13 | LL | let $n = if let Some(v) = $e { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };` @@ -374,19 +374,19 @@ LL | create_binding_if_some!(w, g()); = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info) error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:244:5 + --> tests/ui/manual_let_else.rs:241:5 | LL | let v = if let Variant::A(a, 0) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:249:5 + --> tests/ui/manual_let_else.rs:245:5 | LL | let mut v = if let Variant::B(b) = e() { b } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:255:5 + --> tests/ui/manual_let_else.rs:250:5 | LL | / let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { LL | | @@ -405,19 +405,19 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:263:5 + --> tests/ui/manual_let_else.rs:258:5 | LL | let v = if let Variant::A(.., a) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:268:5 + --> tests/ui/manual_let_else.rs:262:5 | LL | let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:273:5 + --> tests/ui/manual_let_else.rs:266:5 | LL | / let w = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | @@ -436,7 +436,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:282:5 + --> tests/ui/manual_let_else.rs:275:5 | LL | / let v = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | @@ -455,7 +455,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:291:5 + --> tests/ui/manual_let_else.rs:284:5 | LL | / let (x, S { v }, w) = if let Some(U { v, w, x }) = None::>> { LL | | @@ -474,18 +474,17 @@ LL + }; | error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:409:5 + --> tests/ui/manual_let_else.rs:402:5 | LL | / let _ = match ff { LL | | -LL | | LL | | Some(value) => value, LL | | _ => macro_call!(), LL | | }; | |______^ help: consider writing: `let Some(_) = ff else { macro_call!() };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else.rs:487:9 + --> tests/ui/manual_let_else.rs:479:9 | LL | let v = if let Some(v_some) = g() { v_some } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };` diff --git a/tests/ui/manual_let_else_match.rs b/tests/ui/manual_let_else_match.rs index cdb407030111..6416753bac10 100644 --- a/tests/ui/manual_let_else_match.rs +++ b/tests/ui/manual_let_else_match.rs @@ -34,16 +34,13 @@ fn main() {} fn fire() { let v = match g() { - //~^ manual_let_else - - + //~^ manual_let_else Some(v_some) => v_some, None => return, }; let v = match g() { - //~^ manual_let_else - + //~^ manual_let_else Some(v_some) => v_some, _ => return, }; @@ -51,15 +48,13 @@ fn fire() { loop { // More complex pattern for the identity arm and diverging arm let v = match h() { - //~^ manual_let_else - + //~^ manual_let_else (Some(v), None) | (None, Some(v)) => v, (Some(_), Some(_)) | (None, None) => continue, }; // Custom enums are supported as long as the "else" arm is a simple _ let v = match build_enum() { - //~^ manual_let_else - + //~^ manual_let_else Variant::Bar(v) | Variant::Baz(v) => v, _ => continue, }; @@ -68,16 +63,14 @@ fn fire() { // There is a _ in the diverging arm // TODO also support unused bindings aka _v let v = match f() { - //~^ manual_let_else - + //~^ manual_let_else Ok(v) => v, Err(_) => return, }; // Err(()) is an allowed pattern let v = match f().map_err(|_| ()) { - //~^ manual_let_else - + //~^ manual_let_else Ok(v) => v, Err(()) => return, }; @@ -85,23 +78,20 @@ fn fire() { let f = Variant::Bar(1); let _value = match f { - //~^ manual_let_else - + //~^ manual_let_else Variant::Bar(v) | Variant::Baz(v) => v, _ => return, }; let _value = match Some(build_enum()) { - //~^ manual_let_else - + //~^ manual_let_else Some(Variant::Bar(v) | Variant::Baz(v)) => v, _ => return, }; let data = [1_u8, 2, 3, 4, 0, 0, 0, 0]; let data = match data.as_slice() { - //~^ manual_let_else - + //~^ manual_let_else [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data, _ => return, }; @@ -182,8 +172,7 @@ fn not_fire() { fn issue11579() { let msg = match Some("hi") { - //~^ manual_let_else - + //~^ manual_let_else Some(m) => m, _ => unreachable!("can't happen"), }; diff --git a/tests/ui/manual_let_else_match.stderr b/tests/ui/manual_let_else_match.stderr index 6a65186d6b53..393562c629ba 100644 --- a/tests/ui/manual_let_else_match.stderr +++ b/tests/ui/manual_let_else_match.stderr @@ -2,7 +2,8 @@ error: this could be rewritten as `let...else` --> tests/ui/manual_let_else_match.rs:36:5 | LL | / let v = match g() { -... | +LL | | +LL | | Some(v_some) => v_some, LL | | None => return, LL | | }; | |______^ help: consider writing: `let Some(v) = g() else { return };` @@ -11,99 +12,90 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:44:5 + --> tests/ui/manual_let_else_match.rs:42:5 | LL | / let v = match g() { LL | | -LL | | LL | | Some(v_some) => v_some, LL | | _ => return, LL | | }; | |______^ help: consider writing: `let Some(v) = g() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:53:9 + --> tests/ui/manual_let_else_match.rs:50:9 | LL | / let v = match h() { LL | | -LL | | LL | | (Some(v), None) | (None, Some(v)) => v, LL | | (Some(_), Some(_)) | (None, None) => continue, LL | | }; | |__________^ help: consider writing: `let ((Some(v), None) | (None, Some(v))) = h() else { continue };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:60:9 + --> tests/ui/manual_let_else_match.rs:56:9 | LL | / let v = match build_enum() { LL | | -LL | | LL | | Variant::Bar(v) | Variant::Baz(v) => v, LL | | _ => continue, LL | | }; | |__________^ help: consider writing: `let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:70:5 + --> tests/ui/manual_let_else_match.rs:65:5 | LL | / let v = match f() { LL | | -LL | | LL | | Ok(v) => v, LL | | Err(_) => return, LL | | }; | |______^ help: consider writing: `let Ok(v) = f() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:78:5 + --> tests/ui/manual_let_else_match.rs:72:5 | LL | / let v = match f().map_err(|_| ()) { LL | | -LL | | LL | | Ok(v) => v, LL | | Err(()) => return, LL | | }; | |______^ help: consider writing: `let Ok(v) = f().map_err(|_| ()) else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:87:5 + --> tests/ui/manual_let_else_match.rs:80:5 | LL | / let _value = match f { LL | | -LL | | LL | | Variant::Bar(v) | Variant::Baz(v) => v, LL | | _ => return, LL | | }; | |______^ help: consider writing: `let (Variant::Bar(_value) | Variant::Baz(_value)) = f else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:94:5 + --> tests/ui/manual_let_else_match.rs:86:5 | LL | / let _value = match Some(build_enum()) { LL | | -LL | | LL | | Some(Variant::Bar(v) | Variant::Baz(v)) => v, LL | | _ => return, LL | | }; | |______^ help: consider writing: `let Some(Variant::Bar(_value) | Variant::Baz(_value)) = Some(build_enum()) else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:102:5 + --> tests/ui/manual_let_else_match.rs:93:5 | LL | / let data = match data.as_slice() { LL | | -LL | | LL | | [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data, LL | | _ => return, LL | | }; | |______^ help: consider writing: `let ([data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0]) = data.as_slice() else { return };` error: this could be rewritten as `let...else` - --> tests/ui/manual_let_else_match.rs:184:5 + --> tests/ui/manual_let_else_match.rs:174:5 | LL | / let msg = match Some("hi") { LL | | -LL | | LL | | Some(m) => m, LL | | _ => unreachable!("can't happen"), LL | | }; diff --git a/tests/ui/manual_let_else_question_mark.rs b/tests/ui/manual_let_else_question_mark.rs index a07801ce0681..8b43d59816f9 100644 --- a/tests/ui/manual_let_else_question_mark.rs +++ b/tests/ui/manual_let_else_question_mark.rs @@ -43,7 +43,7 @@ fn foo() -> Option<()> { // Do fire manual_let_else in this instance: question mark cannot be used here due to the return // body. let v = if let Some(v_some) = g() { - //~^ manual_let_else + //~^ manual_let_else v_some } else { return Some(()); @@ -55,7 +55,7 @@ fn foo() -> Option<()> { #[allow(clippy::question_mark)] { let v = match g() { - //~^ manual_let_else + //~^ manual_let_else Some(v_some) => v_some, _ => return None, }; diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs index 9d7cf754f4b8..9477d0d795d2 100644 --- a/tests/ui/manual_map_option.rs +++ b/tests/ui/manual_map_option.rs @@ -12,25 +12,25 @@ fn main() { match Some(0) { - //~^ manual_map + //~^ manual_map Some(_) => Some(2), None:: => None, }; match Some(0) { - //~^ manual_map + //~^ manual_map Some(x) => Some(x + 1), _ => None, }; match Some("") { - //~^ manual_map + //~^ manual_map Some(x) => Some(x.is_empty()), None => None, }; if let Some(x) = Some(0) { - //~^ manual_map + //~^ manual_map Some(!x) } else { None @@ -44,7 +44,7 @@ fn main() { }; match Some(&String::new()) { - //~^ manual_map + //~^ manual_map Some(x) => Some(str::len(x)), None => None, }; @@ -55,31 +55,31 @@ fn main() { }; match &Some([0, 1]) { - //~^ manual_map + //~^ manual_map Some(x) => Some(x[0]), &None => None, }; match &Some(0) { - //~^ manual_map + //~^ manual_map &Some(x) => Some(x * 2), None => None, }; match Some(String::new()) { - //~^ manual_map + //~^ manual_map Some(ref x) => Some(x.is_empty()), _ => None, }; match &&Some(String::new()) { - //~^ manual_map + //~^ manual_map Some(x) => Some(x.len()), _ => None, }; match &&Some(0) { - //~^ manual_map + //~^ manual_map &&Some(x) => Some(x + x), &&_ => None, }; @@ -93,38 +93,38 @@ fn main() { #[allow(clippy::option_map_unit_fn)] { match &mut Some(String::new()) { - //~^ manual_map + //~^ manual_map Some(x) => Some(x.push_str("")), None => None, }; } match &mut Some(String::new()) { - //~^ manual_map + //~^ manual_map Some(ref x) => Some(x.len()), None => None, }; match &mut &Some(String::new()) { - //~^ manual_map + //~^ manual_map Some(x) => Some(x.is_empty()), &mut _ => None, }; match Some((0, 1, 2)) { - //~^ manual_map + //~^ manual_map Some((x, y, z)) => Some(x + y + z), None => None, }; match Some([1, 2, 3]) { - //~^ manual_map + //~^ manual_map Some([first, ..]) => Some(first), None => None, }; match &Some((String::new(), "test")) { - //~^ manual_map + //~^ manual_map Some((x, y)) => Some((y, x)), None => None, }; @@ -194,7 +194,7 @@ fn main() { }; match option_env!("") { - //~^ manual_map + //~^ manual_map Some(x) => Some(String::from(x)), None => None, }; @@ -215,7 +215,7 @@ fn main() { if let Some(_) = Some(0) { Some(0) } else if let Some(x) = Some(0) { - //~^ manual_map + //~^ manual_map Some(x + 1) } else { None @@ -224,7 +224,7 @@ fn main() { if true { Some(0) } else if let Some(x) = Some(0) { - //~^ manual_map + //~^ manual_map Some(x + 1) } else { None diff --git a/tests/ui/manual_map_option_2.rs b/tests/ui/manual_map_option_2.rs index 9f45349d5c89..069c2381f6db 100644 --- a/tests/ui/manual_map_option_2.rs +++ b/tests/ui/manual_map_option_2.rs @@ -4,7 +4,7 @@ fn main() { // Lint. `y` is declared within the arm, so it isn't captured by the map closure let _ = match Some(0) { - //~^ manual_map + //~^ manual_map Some(x) => Some({ let y = (String::new(), String::new()); (x, y.0) @@ -47,7 +47,7 @@ fn main() { let s = Some(String::new()); // Lint. `s` is captured by reference, so no lifetime issues. let _ = match &s { - //~^ manual_map + //~^ manual_map Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), None => None, }; @@ -63,18 +63,18 @@ fn main() { } unsafe { let _ = match Some(0) { - //~^ manual_map + //~^ manual_map Some(x) => Some(f(x)), None => None, }; } let _ = match Some(0) { - //~^ manual_map + //~^ manual_map Some(x) => unsafe { Some(f(x)) }, None => None, }; let _ = match Some(0) { - //~^ manual_map + //~^ manual_map Some(x) => Some(unsafe { f(x) }), None => None, }; @@ -111,7 +111,7 @@ mod with_type_coercion { }; let _ = match Some(0) { - //~^ manual_map + //~^ manual_map Some(_) => Some(match f() { Ok(res) => Ok(Box::new(res)), _ => Err(()), @@ -134,7 +134,7 @@ mod with_type_coercion { }); let _: Option> = match Some(0) { - //~^ manual_map + //~^ manual_map Some(_) => Some(g(x)), None => None, }; diff --git a/tests/ui/manual_memcpy/with_loop_counters.rs b/tests/ui/manual_memcpy/with_loop_counters.rs index eee6c8235daa..c83a26cab21a 100644 --- a/tests/ui/manual_memcpy/with_loop_counters.rs +++ b/tests/ui/manual_memcpy/with_loop_counters.rs @@ -3,8 +3,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let mut count = 0; for i in 3..src.len() { - //~^ manual_memcpy - + //~^ manual_memcpy dst[i] = src[count]; count += 1; @@ -12,7 +11,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) let mut count = 0; for i in 3..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[count] = src[i]; count += 1; @@ -20,7 +19,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) let mut count = 3; for i in 0..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[count] = src[i]; count += 1; @@ -28,7 +27,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) let mut count = 3; for i in 0..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[count]; count += 1; @@ -36,7 +35,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) let mut count = 0; for i in 3..(3 + src.len()) { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[count]; count += 1; @@ -44,7 +43,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) let mut count = 3; for i in 5..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[count - 2]; count += 1; @@ -52,7 +51,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) let mut count = 2; for i in 0..dst.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[count]; count += 1; @@ -60,7 +59,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) let mut count = 5; for i in 3..10 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[count]; count += 1; @@ -69,7 +68,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) let mut count = 3; let mut count2 = 30; for i in 0..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[count] = src[i]; dst2[count2] = src[i]; @@ -81,7 +80,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) // arithmetic ones let mut count = 0 << 1; for i in 0..1 << 1 { - //~^ manual_memcpy + //~^ manual_memcpy dst[count] = src[i + 2]; count += 1; @@ -90,7 +89,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) // make sure incrementing expressions without semicolons at the end of loops are handled correctly. let mut count = 0; for i in 3..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[count]; count += 1 diff --git a/tests/ui/manual_memcpy/with_loop_counters.stderr b/tests/ui/manual_memcpy/with_loop_counters.stderr index fe42842b969b..70da8309f398 100644 --- a/tests/ui/manual_memcpy/with_loop_counters.stderr +++ b/tests/ui/manual_memcpy/with_loop_counters.stderr @@ -2,7 +2,9 @@ error: it looks like you're manually copying between slices --> tests/ui/manual_memcpy/with_loop_counters.rs:5:5 | LL | / for i in 3..src.len() { -... | +LL | | +LL | | +LL | | dst[i] = src[count]; LL | | count += 1; LL | | } | |_____^ help: try replacing the loop by: `dst[3..src.len()].copy_from_slice(&src[..(src.len() - 3)]);` @@ -11,7 +13,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:14:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:13:5 | LL | / for i in 3..src.len() { LL | | @@ -22,7 +24,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..(src.len() - 3)].copy_from_slice(&src[3..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:22:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:21:5 | LL | / for i in 0..src.len() { LL | | @@ -33,7 +35,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[3..(src.len() + 3)].copy_from_slice(&src[..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:30:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:29:5 | LL | / for i in 0..src.len() { LL | | @@ -44,7 +46,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[3..(src.len() + 3)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:38:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:37:5 | LL | / for i in 3..(3 + src.len()) { LL | | @@ -55,7 +57,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[3..(3 + src.len())].copy_from_slice(&src[..(3 + src.len() - 3)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:46:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:45:5 | LL | / for i in 5..src.len() { LL | | @@ -66,7 +68,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[5..src.len()].copy_from_slice(&src[(3 - 2)..((src.len() - 2) + 3 - 5)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:54:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:53:5 | LL | / for i in 0..dst.len() { LL | | @@ -77,7 +79,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[2..(dst.len() + 2)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:62:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:61:5 | LL | / for i in 3..10 { LL | | @@ -88,7 +90,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[3..10].copy_from_slice(&src[5..(10 + 5 - 3)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:71:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:70:5 | LL | / for i in 0..src.len() { LL | | @@ -106,7 +108,7 @@ LL + dst2[30..(src.len() + 30)].copy_from_slice(&src[..]); | error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:83:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:82:5 | LL | / for i in 0..1 << 1 { LL | | @@ -117,7 +119,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[(0 << 1)..((1 << 1) + (0 << 1))].copy_from_slice(&src[2..((1 << 1) + 2)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/with_loop_counters.rs:92:5 + --> tests/ui/manual_memcpy/with_loop_counters.rs:91:5 | LL | / for i in 3..src.len() { LL | | diff --git a/tests/ui/manual_memcpy/without_loop_counters.rs b/tests/ui/manual_memcpy/without_loop_counters.rs index 65254df0aab4..a3b8763812d7 100644 --- a/tests/ui/manual_memcpy/without_loop_counters.rs +++ b/tests/ui/manual_memcpy/without_loop_counters.rs @@ -12,36 +12,35 @@ const LOOP_OFFSET: usize = 5000; pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { // plain manual memcpy for i in 0..src.len() { - //~^ manual_memcpy - + //~^ manual_memcpy dst[i] = src[i]; } // dst offset memcpy for i in 0..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i + 10] = src[i]; } // src offset memcpy for i in 0..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i + 10]; } // src offset memcpy for i in 11..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i - 10]; } // overwrite entire dst for i in 0..dst.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i]; } @@ -56,7 +55,7 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { // multiple copies - suggest two memcpy statements for i in 10..256 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i - 5]; dst2[i + 500] = src[i] @@ -70,7 +69,7 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let some_var = 5; // Offset in variable for i in 10..LOOP_OFFSET { - //~^ manual_memcpy + //~^ manual_memcpy dst[i + LOOP_OFFSET] = src[i - some_var]; } @@ -85,7 +84,7 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { // make sure vectors are supported for i in 0..src_vec.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst_vec[i] = src_vec[i]; } @@ -116,27 +115,27 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let from = 1; for i in from..from + src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i - from]; } for i in from..from + 3 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i - from]; } #[allow(clippy::identity_op)] for i in 0..5 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i - 0] = src[i]; } #[allow(clippy::reversed_empty_ranges)] for i in 0..0 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i]; } @@ -161,21 +160,21 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let src = [0, 1, 2, 3, 4]; let mut dst = [0; 4]; for i in 0..4 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i]; } let mut dst = [0; 6]; for i in 0..5 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i]; } let mut dst = [0; 5]; for i in 0..5 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i]; } @@ -223,14 +222,14 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { let src = [[0; 5]; 5]; let mut dst = [0; 5]; for i in 0..5 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[0][i]; } let src = [[[0; 5]; 5]; 5]; for i in 0..5 { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[0][1][i]; } @@ -239,7 +238,7 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { #[warn(clippy::needless_range_loop, clippy::manual_memcpy)] pub fn manual_clone(src: &[String], dst: &mut [String]) { for i in 0..src.len() { - //~^ manual_memcpy + //~^ manual_memcpy dst[i] = src[i].clone(); } diff --git a/tests/ui/manual_memcpy/without_loop_counters.stderr b/tests/ui/manual_memcpy/without_loop_counters.stderr index 2599bc02c3ca..0e656dcbc63a 100644 --- a/tests/ui/manual_memcpy/without_loop_counters.stderr +++ b/tests/ui/manual_memcpy/without_loop_counters.stderr @@ -2,7 +2,9 @@ error: it looks like you're manually copying between slices --> tests/ui/manual_memcpy/without_loop_counters.rs:14:5 | LL | / for i in 0..src.len() { -... | +LL | | +LL | | +LL | | dst[i] = src[i]; LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[..]);` | @@ -10,7 +12,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:22:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:21:5 | LL | / for i in 0..src.len() { LL | | @@ -20,7 +22,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[10..(src.len() + 10)].copy_from_slice(&src[..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:29:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:28:5 | LL | / for i in 0..src.len() { LL | | @@ -30,7 +32,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:36:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:35:5 | LL | / for i in 11..src.len() { LL | | @@ -40,7 +42,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:43:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:42:5 | LL | / for i in 0..dst.len() { LL | | @@ -50,7 +52,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..dst.len()]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:58:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:57:5 | LL | / for i in 10..256 { LL | | @@ -67,7 +69,7 @@ LL + dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]); | error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:72:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:71:5 | LL | / for i in 10..LOOP_OFFSET { LL | | @@ -77,7 +79,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:87:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:86:5 | LL | / for i in 0..src_vec.len() { LL | | @@ -87,7 +89,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:118:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:117:5 | LL | / for i in from..from + src.len() { LL | | @@ -97,7 +99,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:124:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:123:5 | LL | / for i in from..from + 3 { LL | | @@ -107,7 +109,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:131:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:130:5 | LL | / for i in 0..5 { LL | | @@ -117,7 +119,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:138:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:137:5 | LL | / for i in 0..0 { LL | | @@ -127,7 +129,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..0].copy_from_slice(&src[..0]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:163:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:162:5 | LL | / for i in 0..4 { LL | | @@ -137,7 +139,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..4]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:170:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:169:5 | LL | / for i in 0..5 { LL | | @@ -147,7 +149,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:177:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:176:5 | LL | / for i in 0..5 { LL | | @@ -157,7 +159,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:225:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:224:5 | LL | / for i in 0..5 { LL | | @@ -167,7 +169,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:232:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:231:5 | LL | / for i in 0..5 { LL | | @@ -177,7 +179,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0][1]);` error: it looks like you're manually copying between slices - --> tests/ui/manual_memcpy/without_loop_counters.rs:241:5 + --> tests/ui/manual_memcpy/without_loop_counters.rs:240:5 | LL | / for i in 0..src.len() { LL | | diff --git a/tests/ui/manual_non_exhaustive_enum.rs b/tests/ui/manual_non_exhaustive_enum.rs index aaa5b549e734..bb22165d478f 100644 --- a/tests/ui/manual_non_exhaustive_enum.rs +++ b/tests/ui/manual_non_exhaustive_enum.rs @@ -2,7 +2,7 @@ #![allow(unused)] //@no-rustfix pub enum E { -//~^ manual_non_exhaustive + //~^ manual_non_exhaustive A, B, #[doc(hidden)] @@ -27,7 +27,7 @@ pub enum NoDocHidden { // name of variant with doc hidden does not start with underscore pub enum NoUnderscore { -//~^ manual_non_exhaustive + //~^ manual_non_exhaustive A, B, #[doc(hidden)] diff --git a/tests/ui/manual_ok_err.rs b/tests/ui/manual_ok_err.rs index 976311604a38..77300b7af539 100644 --- a/tests/ui/manual_ok_err.rs +++ b/tests/ui/manual_ok_err.rs @@ -6,35 +6,31 @@ fn funcall() -> Result { fn main() { let _ = match funcall() { - //~^ manual_ok_err - + //~^ manual_ok_err Ok(v) => Some(v), Err(_) => None, }; let _ = match funcall() { - //~^ manual_ok_err - + //~^ manual_ok_err Ok(v) => Some(v), _v => None, }; let _ = match funcall() { - //~^ manual_ok_err - + //~^ manual_ok_err Err(v) => Some(v), Ok(_) => None, }; let _ = match funcall() { - //~^ manual_ok_err - + //~^ manual_ok_err Err(v) => Some(v), _v => None, }; let _ = if let Ok(v) = funcall() { - //~^ manual_ok_err + //~^ manual_ok_err Some(v) } else { @@ -42,7 +38,7 @@ fn main() { }; let _ = if let Err(v) = funcall() { - //~^ manual_ok_err + //~^ manual_ok_err Some(v) } else { @@ -51,8 +47,7 @@ fn main() { #[allow(clippy::redundant_pattern)] let _ = match funcall() { - //~^ manual_ok_err - + //~^ manual_ok_err Ok(v) => Some(v), _v @ _ => None, }; @@ -69,8 +64,7 @@ fn main() { // Suggestion should be properly parenthesized let _ = match -S { - //~^ manual_ok_err - + //~^ manual_ok_err Ok(v) => Some(v), _ => None, }; diff --git a/tests/ui/manual_ok_err.stderr b/tests/ui/manual_ok_err.stderr index ea430dd3eb45..f10f52cc4c97 100644 --- a/tests/ui/manual_ok_err.stderr +++ b/tests/ui/manual_ok_err.stderr @@ -4,7 +4,6 @@ error: manual implementation of `ok` LL | let _ = match funcall() { | _____________^ LL | | -LL | | LL | | Ok(v) => Some(v), LL | | Err(_) => None, LL | | }; @@ -14,43 +13,40 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_ok_err)]` error: manual implementation of `ok` - --> tests/ui/manual_ok_err.rs:15:13 + --> tests/ui/manual_ok_err.rs:14:13 | LL | let _ = match funcall() { | _____________^ LL | | -LL | | LL | | Ok(v) => Some(v), LL | | _v => None, LL | | }; | |_____^ help: replace with: `funcall().ok()` error: manual implementation of `err` - --> tests/ui/manual_ok_err.rs:22:13 + --> tests/ui/manual_ok_err.rs:20:13 | LL | let _ = match funcall() { | _____________^ LL | | -LL | | LL | | Err(v) => Some(v), LL | | Ok(_) => None, LL | | }; | |_____^ help: replace with: `funcall().err()` error: manual implementation of `err` - --> tests/ui/manual_ok_err.rs:29:13 + --> tests/ui/manual_ok_err.rs:26:13 | LL | let _ = match funcall() { | _____________^ LL | | -LL | | LL | | Err(v) => Some(v), LL | | _v => None, LL | | }; | |_____^ help: replace with: `funcall().err()` error: manual implementation of `ok` - --> tests/ui/manual_ok_err.rs:36:13 + --> tests/ui/manual_ok_err.rs:32:13 | LL | let _ = if let Ok(v) = funcall() { | _____________^ @@ -63,7 +59,7 @@ LL | | }; | |_____^ help: replace with: `funcall().ok()` error: manual implementation of `err` - --> tests/ui/manual_ok_err.rs:44:13 + --> tests/ui/manual_ok_err.rs:40:13 | LL | let _ = if let Err(v) = funcall() { | _____________^ @@ -76,24 +72,22 @@ LL | | }; | |_____^ help: replace with: `funcall().err()` error: manual implementation of `ok` - --> tests/ui/manual_ok_err.rs:53:13 + --> tests/ui/manual_ok_err.rs:49:13 | LL | let _ = match funcall() { | _____________^ LL | | -LL | | LL | | Ok(v) => Some(v), LL | | _v @ _ => None, LL | | }; | |_____^ help: replace with: `funcall().ok()` error: manual implementation of `ok` - --> tests/ui/manual_ok_err.rs:71:13 + --> tests/ui/manual_ok_err.rs:66:13 | LL | let _ = match -S { | _____________^ LL | | -LL | | LL | | Ok(v) => Some(v), LL | | _ => None, LL | | }; diff --git a/tests/ui/manual_option_as_slice.fixed b/tests/ui/manual_option_as_slice.fixed index 17a412017a43..48337d7654de 100644 --- a/tests/ui/manual_option_as_slice.fixed +++ b/tests/ui/manual_option_as_slice.fixed @@ -9,24 +9,19 @@ fn check(x: Option) { _ = x.as_slice(); //~^ manual_option_as_slice + _ = x.as_slice(); + //~^ manual_option_as_slice _ = x.as_slice(); //~^ manual_option_as_slice - _ = x.as_slice(); //~^ manual_option_as_slice - - _ = x.as_slice(); - //~^ manual_option_as_slice - - { use std::slice::from_ref; _ = x.as_slice(); //~^ manual_option_as_slice - } // possible false positives diff --git a/tests/ui/manual_option_as_slice.rs b/tests/ui/manual_option_as_slice.rs index 71166399cbea..e1a97a6b2711 100644 --- a/tests/ui/manual_option_as_slice.rs +++ b/tests/ui/manual_option_as_slice.rs @@ -3,14 +3,13 @@ fn check(x: Option) { _ = match x.as_ref() { - //~^ manual_option_as_slice - + //~^ manual_option_as_slice Some(f) => std::slice::from_ref(f), None => &[], }; _ = if let Some(f) = x.as_ref() { - //~^ manual_option_as_slice + //~^ manual_option_as_slice std::slice::from_ref(f) } else { @@ -20,24 +19,19 @@ fn check(x: Option) { _ = x.as_ref().map_or(&[][..], std::slice::from_ref); //~^ manual_option_as_slice - _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref); //~^ manual_option_as_slice - _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default(); //~^ manual_option_as_slice - _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref); //~^ manual_option_as_slice - { use std::slice::from_ref; _ = x.as_ref().map_or_else(<&[_]>::default, from_ref); //~^ manual_option_as_slice - } // possible false positives diff --git a/tests/ui/manual_option_as_slice.stderr b/tests/ui/manual_option_as_slice.stderr index 3a07c6a02dae..e240ae8eb7d9 100644 --- a/tests/ui/manual_option_as_slice.stderr +++ b/tests/ui/manual_option_as_slice.stderr @@ -4,7 +4,6 @@ error: use `Option::as_slice` LL | _ = match x.as_ref() { | _________^ LL | | -LL | | LL | | Some(f) => std::slice::from_ref(f), LL | | None => &[], LL | | }; @@ -14,7 +13,7 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_option_as_slice)]` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:12:9 + --> tests/ui/manual_option_as_slice.rs:11:9 | LL | _ = if let Some(f) = x.as_ref() { | _________^ @@ -27,31 +26,31 @@ LL | | }; | |_____^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:20:9 + --> tests/ui/manual_option_as_slice.rs:19:9 | LL | _ = x.as_ref().map_or(&[][..], std::slice::from_ref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:24:9 + --> tests/ui/manual_option_as_slice.rs:22:9 | LL | _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:28:9 + --> tests/ui/manual_option_as_slice.rs:25:9 | LL | _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:32:9 + --> tests/ui/manual_option_as_slice.rs:28:9 | LL | _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` error: use `Option::as_slice` - --> tests/ui/manual_option_as_slice.rs:38:13 + --> tests/ui/manual_option_as_slice.rs:33:13 | LL | _ = x.as_ref().map_or_else(<&[_]>::default, from_ref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()` diff --git a/tests/ui/manual_retain.rs b/tests/ui/manual_retain.rs index 61e2d73b544f..cd05a41f3f25 100644 --- a/tests/ui/manual_retain.rs +++ b/tests/ui/manual_retain.rs @@ -69,7 +69,7 @@ fn btree_map_retain() { btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect(); //~^ manual_retain btree_map = btree_map - //~^ manual_retain + //~^ manual_retain .into_iter() .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0)) .collect(); @@ -141,7 +141,7 @@ fn hash_map_retain() { hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect(); //~^ manual_retain hash_map = hash_map - //~^ manual_retain + //~^ manual_retain .into_iter() .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0)) .collect(); diff --git a/tests/ui/manual_saturating_arithmetic.rs b/tests/ui/manual_saturating_arithmetic.rs index c0d7f26916ee..98246a5cd96c 100644 --- a/tests/ui/manual_saturating_arithmetic.rs +++ b/tests/ui/manual_saturating_arithmetic.rs @@ -10,7 +10,7 @@ fn main() { let _ = 1u8.checked_add(1).unwrap_or(255); //~^ manual_saturating_arithmetic let _ = 1u128 - //~^ manual_saturating_arithmetic + //~^ manual_saturating_arithmetic .checked_add(1) .unwrap_or(340_282_366_920_938_463_463_374_607_431_768_211_455); let _ = 1u32.checked_add(1).unwrap_or(1234); // ok @@ -34,7 +34,7 @@ fn main() { let _ = 1i8.checked_add(1).unwrap_or(127); //~^ manual_saturating_arithmetic let _ = 1i128 - //~^ manual_saturating_arithmetic + //~^ manual_saturating_arithmetic .checked_add(1) .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727); let _ = 1i32.checked_add(-1).unwrap_or(i32::min_value()); @@ -44,7 +44,7 @@ fn main() { let _ = 1i8.checked_add(-1).unwrap_or(-128); //~^ manual_saturating_arithmetic let _ = 1i128 - //~^ manual_saturating_arithmetic + //~^ manual_saturating_arithmetic .checked_add(-1) .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728); let _ = 1i32.checked_add(1).unwrap_or(1234); // ok @@ -58,7 +58,7 @@ fn main() { let _ = 1i8.checked_sub(1).unwrap_or(-128); //~^ manual_saturating_arithmetic let _ = 1i128 - //~^ manual_saturating_arithmetic + //~^ manual_saturating_arithmetic .checked_sub(1) .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728); let _ = 1i32.checked_sub(-1).unwrap_or(i32::max_value()); @@ -68,7 +68,7 @@ fn main() { let _ = 1i8.checked_sub(-1).unwrap_or(127); //~^ manual_saturating_arithmetic let _ = 1i128 - //~^ manual_saturating_arithmetic + //~^ manual_saturating_arithmetic .checked_sub(-1) .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727); let _ = 1i32.checked_sub(1).unwrap_or(1234); // ok diff --git a/tests/ui/manual_slice_fill.rs b/tests/ui/manual_slice_fill.rs index cd62a476d174..f758f47bbcb0 100644 --- a/tests/ui/manual_slice_fill.rs +++ b/tests/ui/manual_slice_fill.rs @@ -23,25 +23,25 @@ fn should_lint() { let mut some_slice = [1, 2, 3, 4, 5]; for i in 0..some_slice.len() { - //~^ manual_slice_fill + //~^ manual_slice_fill some_slice[i] = 0; } let x = 5; for i in 0..some_slice.len() { - //~^ manual_slice_fill + //~^ manual_slice_fill some_slice[i] = x; } for i in &mut some_slice { - //~^ manual_slice_fill + //~^ manual_slice_fill *i = 0; } // This should trigger `manual_slice_fill`, but the applicability is `MaybeIncorrect` since comments // within the loop might be purely informational. for i in 0..some_slice.len() { - //~^ manual_slice_fill + //~^ manual_slice_fill some_slice[i] = 0; // foo } diff --git a/tests/ui/manual_strip.rs b/tests/ui/manual_strip.rs index d3dbf301d9c0..ce53c99e6b50 100644 --- a/tests/ui/manual_strip.rs +++ b/tests/ui/manual_strip.rs @@ -36,7 +36,6 @@ fn main() { if s.starts_with(prefix) { str::to_string(&s[prefix.len()..]); //~^ manual_strip - } // Constant prefix @@ -53,7 +52,6 @@ fn main() { if TARGET.starts_with(prefix) { str::to_string(&TARGET[prefix.len()..]); //~^ manual_strip - } // String target - not mutated. @@ -61,7 +59,6 @@ fn main() { if s1.starts_with("ab") { s1[2..].to_uppercase(); //~^ manual_strip - } // String target - mutated. (Don't lint.) @@ -93,6 +90,5 @@ fn msrv_1_45() { if s.starts_with('a') { s[1..].to_string(); //~^ manual_strip - } } diff --git a/tests/ui/manual_strip.stderr b/tests/ui/manual_strip.stderr index 78967e521baa..41d15da610c4 100644 --- a/tests/ui/manual_strip.stderr +++ b/tests/ui/manual_strip.stderr @@ -84,13 +84,13 @@ LL ~ str::to_string(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:45:24 + --> tests/ui/manual_strip.rs:44:24 | LL | str::to_string(&s[PREFIX.len()..]); | ^^^^^^^^^^^^^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:44:5 + --> tests/ui/manual_strip.rs:43:5 | LL | if s.starts_with(PREFIX) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,13 +104,13 @@ LL ~ str::to_string(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:54:24 + --> tests/ui/manual_strip.rs:53:24 | LL | str::to_string(&TARGET[prefix.len()..]); | ^^^^^^^^^^^^^^^^^^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:53:5 + --> tests/ui/manual_strip.rs:52:5 | LL | if TARGET.starts_with(prefix) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,13 +121,13 @@ LL ~ str::to_string(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:62:9 + --> tests/ui/manual_strip.rs:60:9 | LL | s1[2..].to_uppercase(); | ^^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:61:5 + --> tests/ui/manual_strip.rs:59:5 | LL | if s1.starts_with("ab") { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -138,13 +138,13 @@ LL ~ .to_uppercase(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:94:9 + --> tests/ui/manual_strip.rs:91:9 | LL | s[1..].to_string(); | ^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:93:5 + --> tests/ui/manual_strip.rs:90:5 | LL | if s.starts_with('a') { | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/manual_try_fold.rs b/tests/ui/manual_try_fold.rs index 749fc7c7b683..c91ea41bb84c 100644 --- a/tests/ui/manual_try_fold.rs +++ b/tests/ui/manual_try_fold.rs @@ -62,11 +62,11 @@ fn main() { [1, 2, 3] .iter() .fold(NotOption(0i32, 0i32), |sum, i| NotOption(0i32, 0i32)); - //~^ manual_try_fold + //~^ manual_try_fold [1, 2, 3] .iter() .fold(NotOptionButWorse(0i32), |sum, i| NotOptionButWorse(0i32)); - //~^ manual_try_fold + //~^ manual_try_fold // Do not lint [1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)).unwrap(); [1, 2, 3].iter().fold(0i32, |sum, i| sum + i); diff --git a/tests/ui/manual_unwrap_or.rs b/tests/ui/manual_unwrap_or.rs index 80a677d726ef..c88b6f95da68 100644 --- a/tests/ui/manual_unwrap_or.rs +++ b/tests/ui/manual_unwrap_or.rs @@ -9,21 +9,21 @@ fn option_unwrap_or() { // int case match Some(1) { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Some(i) => i, None => 42, }; // int case reversed match Some(1) { - //~^ manual_unwrap_or + //~^ manual_unwrap_or None => 42, Some(i) => i, }; // richer none expr match Some(1) { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Some(i) => i, None => 1 + 42, }; @@ -42,7 +42,7 @@ fn option_unwrap_or() { // string case match Some("Bob") { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Some(i) => i, None => "Alice", }; @@ -90,7 +90,7 @@ fn option_unwrap_or() { }; if let Some(x) = Some(1) { - //~^ manual_unwrap_or + //~^ manual_unwrap_or x } else { 42 @@ -124,7 +124,7 @@ fn option_unwrap_or() { fn result_unwrap_or() { // int case match Ok::(1) { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Ok(i) => i, Err(_) => 42, }; @@ -132,14 +132,14 @@ fn result_unwrap_or() { // int case, scrutinee is a binding let a = Ok::(1); match a { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Ok(i) => i, Err(_) => 42, }; // int case, suggestion must surround Result expr with parentheses match Ok(1) as Result { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Ok(i) => i, Err(_) => 42, }; @@ -153,21 +153,21 @@ fn result_unwrap_or() { } let s = S {}; match s.method() { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Some(i) => i, None => 42, }; // int case reversed match Ok::(1) { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Err(_) => 42, Ok(i) => i, }; // richer none expr match Ok::(1) { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Ok(i) => i, Err(_) => 1 + 42, }; @@ -186,7 +186,7 @@ fn result_unwrap_or() { // string case match Ok::<&str, &str>("Bob") { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Ok(i) => i, Err(_) => "Alice", }; @@ -223,7 +223,7 @@ fn result_unwrap_or() { }; if let Ok(x) = Ok::(1) { - //~^ manual_unwrap_or + //~^ manual_unwrap_or x } else { 42 @@ -278,7 +278,7 @@ mod issue6965 { fn test() { let _ = match some_macro!() { - //~^ manual_unwrap_or + //~^ manual_unwrap_or Some(val) => val, None => 0, }; diff --git a/tests/ui/manual_unwrap_or_default.rs b/tests/ui/manual_unwrap_or_default.rs index 1ef07cf84bde..bedb3f0af0f3 100644 --- a/tests/ui/manual_unwrap_or_default.rs +++ b/tests/ui/manual_unwrap_or_default.rs @@ -4,39 +4,35 @@ fn main() { let x: Option> = None; match x { - //~^ manual_unwrap_or_default - + //~^ manual_unwrap_or_default Some(v) => v, None => Vec::default(), }; let x: Option> = None; match x { - //~^ manual_unwrap_or_default - + //~^ manual_unwrap_or_default Some(v) => v, _ => Vec::default(), }; let x: Option = None; match x { - //~^ manual_unwrap_or_default - + //~^ manual_unwrap_or_default Some(v) => v, None => String::new(), }; let x: Option> = None; match x { - //~^ manual_unwrap_or_default - + //~^ manual_unwrap_or_default None => Vec::default(), Some(v) => v, }; let x: Option> = None; if let Some(v) = x { - //~^ manual_unwrap_or_default + //~^ manual_unwrap_or_default v } else { @@ -55,15 +51,14 @@ fn main() { let x: Result = Ok(String::new()); match x { - //~^ manual_unwrap_or_default - + //~^ manual_unwrap_or_default Ok(v) => v, Err(_) => String::new(), }; let x: Result = Ok(String::new()); if let Ok(v) = x { - //~^ manual_unwrap_or_default + //~^ manual_unwrap_or_default v } else { @@ -76,7 +71,7 @@ unsafe fn no_deref_ptr(a: Option, b: *const Option) -> i32 { match a { // `*b` being correct depends on `a == Some(_)` Some(_) => match *b { - //~^ manual_unwrap_or_default + //~^ manual_unwrap_or_default Some(v) => v, _ => 0, }, diff --git a/tests/ui/manual_unwrap_or_default.stderr b/tests/ui/manual_unwrap_or_default.stderr index ff388ba85d51..ca9aa159152e 100644 --- a/tests/ui/manual_unwrap_or_default.stderr +++ b/tests/ui/manual_unwrap_or_default.stderr @@ -3,7 +3,6 @@ error: match can be simplified with `.unwrap_or_default()` | LL | / match x { LL | | -LL | | LL | | Some(v) => v, LL | | None => Vec::default(), LL | | }; @@ -13,40 +12,37 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or_default)]` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:14:5 + --> tests/ui/manual_unwrap_or_default.rs:13:5 | LL | / match x { LL | | -LL | | LL | | Some(v) => v, LL | | _ => Vec::default(), LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:22:5 + --> tests/ui/manual_unwrap_or_default.rs:20:5 | LL | / match x { LL | | -LL | | LL | | Some(v) => v, LL | | None => String::new(), LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:30:5 + --> tests/ui/manual_unwrap_or_default.rs:27:5 | LL | / match x { LL | | -LL | | LL | | None => Vec::default(), LL | | Some(v) => v, LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: if let can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:38:5 + --> tests/ui/manual_unwrap_or_default.rs:34:5 | LL | / if let Some(v) = x { LL | | @@ -58,18 +54,17 @@ LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:57:5 + --> tests/ui/manual_unwrap_or_default.rs:53:5 | LL | / match x { LL | | -LL | | LL | | Ok(v) => v, LL | | Err(_) => String::new(), LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: if let can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:65:5 + --> tests/ui/manual_unwrap_or_default.rs:60:5 | LL | / if let Ok(v) = x { LL | | @@ -81,7 +76,7 @@ LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:78:20 + --> tests/ui/manual_unwrap_or_default.rs:73:20 | LL | Some(_) => match *b { | ____________________^ diff --git a/tests/ui/manual_unwrap_or_default_unfixable.rs b/tests/ui/manual_unwrap_or_default_unfixable.rs index fb61d639f9c0..c48a4d5ee515 100644 --- a/tests/ui/manual_unwrap_or_default_unfixable.rs +++ b/tests/ui/manual_unwrap_or_default_unfixable.rs @@ -3,7 +3,7 @@ fn issue_12670() { // no auto: type not found #[allow(clippy::match_result_ok)] let _ = if let Some(x) = "1".parse().ok() { - //~^ manual_unwrap_or_default + //~^ manual_unwrap_or_default x } else { i32::default() diff --git a/tests/ui/many_single_char_names.rs b/tests/ui/many_single_char_names.rs index 6e662e246061..b60109224855 100644 --- a/tests/ui/many_single_char_names.rs +++ b/tests/ui/many_single_char_names.rs @@ -7,9 +7,6 @@ fn bla() { //~| many_single_char_names //~| many_single_char_names - - - let (b, c, d): (i32, i64, i16); { { @@ -37,11 +34,9 @@ fn bla() { fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {} //~^ many_single_char_names - fn bindings2() { let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!(); //~^ many_single_char_names - } fn shadowing() { diff --git a/tests/ui/many_single_char_names.stderr b/tests/ui/many_single_char_names.stderr index ad45f9a34fd4..131836ef7c88 100644 --- a/tests/ui/many_single_char_names.stderr +++ b/tests/ui/many_single_char_names.stderr @@ -40,13 +40,13 @@ LL | e => panic!(), | ^ error: 8 bindings with single-character names in scope - --> tests/ui/many_single_char_names.rs:37:13 + --> tests/ui/many_single_char_names.rs:34:13 | LL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {} | ^ ^ ^ ^ ^ ^ ^ ^ error: 8 bindings with single-character names in scope - --> tests/ui/many_single_char_names.rs:42:10 + --> tests/ui/many_single_char_names.rs:38:10 | LL | let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!(); | ^ ^ ^ ^ ^ ^ ^ ^ diff --git a/tests/ui/map_all_any_identity.fixed b/tests/ui/map_all_any_identity.fixed index 436b94bde0fc..35543d239752 100644 --- a/tests/ui/map_all_any_identity.fixed +++ b/tests/ui/map_all_any_identity.fixed @@ -7,7 +7,6 @@ fn main() { let _ = ["foo"].into_iter().all(|s| s == "foo"); //~^ map_all_any_identity - // // Do not lint // diff --git a/tests/ui/map_all_any_identity.rs b/tests/ui/map_all_any_identity.rs index 68fe7b77f5c6..704eb821aaaa 100644 --- a/tests/ui/map_all_any_identity.rs +++ b/tests/ui/map_all_any_identity.rs @@ -7,7 +7,6 @@ fn main() { let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity); //~^ map_all_any_identity - // // Do not lint // diff --git a/tests/ui/map_clone.fixed b/tests/ui/map_clone.fixed index 5e2c31bb31df..8db4b21be684 100644 --- a/tests/ui/map_clone.fixed +++ b/tests/ui/map_clone.fixed @@ -78,23 +78,17 @@ fn main() { let y = x.cloned(); //~^ map_clone - let y = x.cloned(); //~^ map_clone - - let x: Option = Some(0); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.copied(); //~^ map_clone - let y = x.copied(); //~^ map_clone - - // Should not suggest `copied` or `cloned` here since `T` is not a reference. let x: Option = Some(0); let y = x.map(|x| u32::clone(&x)); @@ -106,23 +100,17 @@ fn main() { let y = x.cloned(); //~^ map_clone - let y = x.cloned(); //~^ map_clone - - let x: Result = Ok(0); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.copied(); //~^ map_clone - let y = x.copied(); //~^ map_clone - - // Should not suggest `copied` or `cloned` here since `T` is not a reference. let x: Result = Ok(0); let y = x.map(|x| u32::clone(&x)); diff --git a/tests/ui/map_clone.rs b/tests/ui/map_clone.rs index f15889d64c52..a726e3561634 100644 --- a/tests/ui/map_clone.rs +++ b/tests/ui/map_clone.rs @@ -78,23 +78,17 @@ fn main() { let y = x.map(Clone::clone); //~^ map_clone - let y = x.map(String::clone); //~^ map_clone - - let x: Option = Some(0); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.map(|x| u32::clone(x)); //~^ map_clone - let y = x.map(|x| Clone::clone(x)); //~^ map_clone - - // Should not suggest `copied` or `cloned` here since `T` is not a reference. let x: Option = Some(0); let y = x.map(|x| u32::clone(&x)); @@ -106,23 +100,17 @@ fn main() { let y = x.map(|x| String::clone(x)); //~^ map_clone - let y = x.map(|x| Clone::clone(x)); //~^ map_clone - - let x: Result = Ok(0); let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint. let y = x.map(|x| u32::clone(x)); //~^ map_clone - let y = x.map(|x| Clone::clone(x)); //~^ map_clone - - // Should not suggest `copied` or `cloned` here since `T` is not a reference. let x: Result = Ok(0); let y = x.map(|x| u32::clone(&x)); diff --git a/tests/ui/map_clone.stderr b/tests/ui/map_clone.stderr index 5c88ec579328..8bf54e4e8aee 100644 --- a/tests/ui/map_clone.stderr +++ b/tests/ui/map_clone.stderr @@ -50,43 +50,43 @@ LL | let y = x.map(Clone::clone); | ^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:82:13 + --> tests/ui/map_clone.rs:81:13 | LL | let y = x.map(String::clone); | ^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:89:13 + --> tests/ui/map_clone.rs:86:13 | LL | let y = x.map(|x| u32::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:93:13 + --> tests/ui/map_clone.rs:89:13 | LL | let y = x.map(|x| Clone::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:106:13 + --> tests/ui/map_clone.rs:100:13 | LL | let y = x.map(|x| String::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:110:13 + --> tests/ui/map_clone.rs:103:13 | LL | let y = x.map(|x| Clone::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:117:13 + --> tests/ui/map_clone.rs:108:13 | LL | let y = x.map(|x| u32::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()` error: you are explicitly cloning with `.map()` - --> tests/ui/map_clone.rs:121:13 + --> tests/ui/map_clone.rs:111:13 | LL | let y = x.map(|x| Clone::clone(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()` diff --git a/tests/ui/map_err.rs b/tests/ui/map_err.rs index 43f6ea0b3ae0..0f0c8f6c71cf 100644 --- a/tests/ui/map_err.rs +++ b/tests/ui/map_err.rs @@ -22,7 +22,6 @@ fn main() -> Result<(), Errors> { println!("{:?}", x.map_err(|_| Errors::Ignored)); //~^ map_err_ignore - // Should not warn you because you explicitly ignore the parameter // using a named wildcard value println!("{:?}", x.map_err(|_foo| Errors::Ignored)); diff --git a/tests/ui/map_flatten.rs b/tests/ui/map_flatten.rs index e16a11f83ed5..d7e9c9d9900d 100644 --- a/tests/ui/map_flatten.rs +++ b/tests/ui/map_flatten.rs @@ -67,7 +67,6 @@ fn no_suggestion_if_comments_present() { // a lovely comment explaining the code in very detail .map(|x| x.iter()) //~^ map_flatten - // the answer to life, the universe and everything could be here .flatten(); } diff --git a/tests/ui/map_flatten_fixable.fixed b/tests/ui/map_flatten_fixable.fixed index a5dc17cc06ca..948fec970d86 100644 --- a/tests/ui/map_flatten_fixable.fixed +++ b/tests/ui/map_flatten_fixable.fixed @@ -42,7 +42,7 @@ fn issue8734() { let _ = [0u8, 1, 2, 3] .into_iter() .flat_map(|n| match n { - //~^ map_flatten + //~^ map_flatten 1 => [n .saturating_add(1) .saturating_add(1) diff --git a/tests/ui/map_flatten_fixable.rs b/tests/ui/map_flatten_fixable.rs index 57b8e7943f41..67a91ab94147 100644 --- a/tests/ui/map_flatten_fixable.rs +++ b/tests/ui/map_flatten_fixable.rs @@ -42,7 +42,7 @@ fn issue8734() { let _ = [0u8, 1, 2, 3] .into_iter() .map(|n| match n { - //~^ map_flatten + //~^ map_flatten 1 => [n .saturating_add(1) .saturating_add(1) diff --git a/tests/ui/map_identity.rs b/tests/ui/map_identity.rs index 7c891dda79ce..e839c551364b 100644 --- a/tests/ui/map_identity.rs +++ b/tests/ui/map_identity.rs @@ -12,7 +12,7 @@ fn main() { let _: Option = Some(3).map(|x| x); //~^ map_identity let _: Result = Ok(-3).map(|x| { - //~^ map_identity + //~^ map_identity return x; }); // should not lint @@ -36,7 +36,7 @@ fn issue7189() { let _ = x.clone().map(|(x, y)| (x, y)); //~^ map_identity let _ = x.clone().map(|(x, y)| { - //~^ map_identity + //~^ map_identity return (x, y); }); let _ = x.clone().map(|(x, y)| return (x, y)); diff --git a/tests/ui/map_with_unused_argument_over_ranges.fixed b/tests/ui/map_with_unused_argument_over_ranges.fixed index 08bc1c7a6283..254c46ecae38 100644 --- a/tests/ui/map_with_unused_argument_over_ranges.fixed +++ b/tests/ui/map_with_unused_argument_over_ranges.fixed @@ -35,7 +35,7 @@ fn main() { std::iter::repeat_n(3, 10); //~^ map_with_unused_argument_over_ranges std::iter::repeat_with(|| { - //~^ map_with_unused_argument_over_ranges + //~^ map_with_unused_argument_over_ranges let x = 3; x + 2 }).take(10); diff --git a/tests/ui/map_with_unused_argument_over_ranges.rs b/tests/ui/map_with_unused_argument_over_ranges.rs index 151ebdf97e5d..05c8d64f8012 100644 --- a/tests/ui/map_with_unused_argument_over_ranges.rs +++ b/tests/ui/map_with_unused_argument_over_ranges.rs @@ -35,7 +35,7 @@ fn main() { (0..10).map(|_| 3); //~^ map_with_unused_argument_over_ranges (0..10).map(|_| { - //~^ map_with_unused_argument_over_ranges + //~^ map_with_unused_argument_over_ranges let x = 3; x + 2 }); diff --git a/tests/ui/match_as_ref.rs b/tests/ui/match_as_ref.rs index 7eaabcdc3d0e..3a5b1227331e 100644 --- a/tests/ui/match_as_ref.rs +++ b/tests/ui/match_as_ref.rs @@ -4,14 +4,14 @@ fn match_as_ref() { let owned: Option<()> = None; let borrowed: Option<&()> = match owned { - //~^ match_as_ref + //~^ match_as_ref None => None, Some(ref v) => Some(v), }; let mut mut_owned: Option<()> = None; let borrow_mut: Option<&mut ()> = match mut_owned { - //~^ match_as_ref + //~^ match_as_ref None => None, Some(ref mut v) => Some(v), }; @@ -30,7 +30,7 @@ mod issue4437 { impl Error for E { fn source(&self) -> Option<&(dyn Error + 'static)> { match self.source { - //~^ match_as_ref + //~^ match_as_ref Some(ref s) => Some(s), None => None, } diff --git a/tests/ui/match_bool.rs b/tests/ui/match_bool.rs index 7d4afd3f2890..719b4e51eb6d 100644 --- a/tests/ui/match_bool.rs +++ b/tests/ui/match_bool.rs @@ -5,23 +5,20 @@ fn match_bool() { let test: bool = true; match test { - //~^ match_bool - + //~^ match_bool true => 0, false => 42, }; let option = 1; match option == 1 { - //~^ match_bool - + //~^ match_bool true => 1, false => 0, }; match test { - //~^ match_bool - + //~^ match_bool true => (), false => { println!("Noooo!"); @@ -29,8 +26,7 @@ fn match_bool() { }; match test { - //~^ match_bool - + //~^ match_bool false => { println!("Noooo!"); }, @@ -38,8 +34,7 @@ fn match_bool() { }; match test && test { - //~^ match_bool - + //~^ match_bool false => { println!("Noooo!"); }, @@ -47,8 +42,7 @@ fn match_bool() { }; match test { - //~^ match_bool - + //~^ match_bool false => { println!("Noooo!"); }, @@ -73,43 +67,37 @@ fn match_bool() { }; let _ = match test { - //~^ match_bool - + //~^ match_bool true if option == 5 => 10, _ => 1, }; let _ = match test { - //~^ match_bool - + //~^ match_bool false if option == 5 => 10, _ => 1, }; match test { - //~^ match_bool - + //~^ match_bool true if option == 5 => println!("Hello"), _ => (), }; match test { - //~^ match_bool - + //~^ match_bool true if option == 5 => (), _ => println!("Hello"), }; match test { - //~^ match_bool - + //~^ match_bool false if option == 5 => println!("Hello"), _ => (), }; match test { - //~^ match_bool - + //~^ match_bool false if option == 5 => (), _ => println!("Hello"), }; @@ -117,8 +105,7 @@ fn match_bool() { fn issue14099() { match true { - //~^ match_bool - + //~^ match_bool true => 'a: { break 'a; }, diff --git a/tests/ui/match_bool.stderr b/tests/ui/match_bool.stderr index c25aad27cef2..c05742e56339 100644 --- a/tests/ui/match_bool.stderr +++ b/tests/ui/match_bool.stderr @@ -3,7 +3,6 @@ error: `match` on a boolean expression | LL | / match test { LL | | -LL | | LL | | true => 0, LL | | false => 42, LL | | }; @@ -16,24 +15,23 @@ LL | #![deny(clippy::match_bool)] | ^^^^^^^^^^^^^^^^^^ error: `match` on a boolean expression - --> tests/ui/match_bool.rs:15:5 + --> tests/ui/match_bool.rs:14:5 | LL | / match option == 1 { LL | | -LL | | LL | | true => 1, LL | | false => 0, LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if option == 1 { 1 } else { 0 }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:22:5 + --> tests/ui/match_bool.rs:20:5 | LL | / match test { LL | | -LL | | LL | | true => (), -... | +LL | | false => { +LL | | println!("Noooo!"); LL | | }, LL | | }; | |_____^ @@ -46,13 +44,13 @@ LL ~ }; | error: `match` on a boolean expression - --> tests/ui/match_bool.rs:31:5 + --> tests/ui/match_bool.rs:28:5 | LL | / match test { LL | | -LL | | LL | | false => { -... | +LL | | println!("Noooo!"); +LL | | }, LL | | _ => (), LL | | }; | |_____^ @@ -65,13 +63,13 @@ LL ~ }; | error: `match` on a boolean expression - --> tests/ui/match_bool.rs:40:5 + --> tests/ui/match_bool.rs:36:5 | LL | / match test && test { LL | | -LL | | LL | | false => { -... | +LL | | println!("Noooo!"); +LL | | }, LL | | _ => (), LL | | }; | |_____^ @@ -84,12 +82,12 @@ LL ~ }; | error: `match` on a boolean expression - --> tests/ui/match_bool.rs:49:5 + --> tests/ui/match_bool.rs:44:5 | LL | / match test { LL | | -LL | | LL | | false => { +LL | | println!("Noooo!"); ... | LL | | }, LL | | }; @@ -105,81 +103,75 @@ LL ~ }; | error: `match` on a boolean expression - --> tests/ui/match_bool.rs:75:13 + --> tests/ui/match_bool.rs:69:13 | LL | let _ = match test { | _____________^ LL | | -LL | | LL | | true if option == 5 => 10, LL | | _ => 1, LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if test && option == 5 { 10 } else { 1 }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:82:13 + --> tests/ui/match_bool.rs:75:13 | LL | let _ = match test { | _____________^ LL | | -LL | | LL | | false if option == 5 => 10, LL | | _ => 1, LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if !test && option == 5 { 10 } else { 1 }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:89:5 + --> tests/ui/match_bool.rs:81:5 | LL | / match test { LL | | -LL | | LL | | true if option == 5 => println!("Hello"), LL | | _ => (), LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if test && option == 5 { println!("Hello") }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:96:5 + --> tests/ui/match_bool.rs:87:5 | LL | / match test { LL | | -LL | | LL | | true if option == 5 => (), LL | | _ => println!("Hello"), LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if !(test && option == 5) { println!("Hello") }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:103:5 + --> tests/ui/match_bool.rs:93:5 | LL | / match test { LL | | -LL | | LL | | false if option == 5 => println!("Hello"), LL | | _ => (), LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if !test && option == 5 { println!("Hello") }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:110:5 + --> tests/ui/match_bool.rs:99:5 | LL | / match test { LL | | -LL | | LL | | false if option == 5 => (), LL | | _ => println!("Hello"), LL | | }; | |_____^ help: consider using an `if`/`else` expression: `if !(!test && option == 5) { println!("Hello") }` error: `match` on a boolean expression - --> tests/ui/match_bool.rs:119:5 + --> tests/ui/match_bool.rs:107:5 | LL | / match true { LL | | -LL | | LL | | true => 'a: { -... | +LL | | break 'a; +LL | | }, LL | | _ => (), LL | | } | |_____^ diff --git a/tests/ui/match_on_vec_items.rs b/tests/ui/match_on_vec_items.rs index 1b7ce69f3ae7..f3174ec9734d 100644 --- a/tests/ui/match_on_vec_items.rs +++ b/tests/ui/match_on_vec_items.rs @@ -8,9 +8,7 @@ fn match_with_wildcard() { // Lint, may panic match arr[idx] { - //~^ match_on_vec_items - - + //~^ match_on_vec_items 0 => println!("0"), 1 => println!("1"), _ => {}, @@ -18,8 +16,7 @@ fn match_with_wildcard() { // Lint, may panic match arr[range] { - //~^ match_on_vec_items - + //~^ match_on_vec_items [0, 1] => println!("0 1"), [1, 2] => println!("1 2"), _ => {}, @@ -33,8 +30,7 @@ fn match_without_wildcard() { // Lint, may panic match arr[idx] { - //~^ match_on_vec_items - + //~^ match_on_vec_items 0 => println!("0"), 1 => println!("1"), num => {}, @@ -42,8 +38,7 @@ fn match_without_wildcard() { // Lint, may panic match arr[range] { - //~^ match_on_vec_items - + //~^ match_on_vec_items [0, 1] => println!("0 1"), [1, 2] => println!("1 2"), [ref sub @ ..] => {}, @@ -57,8 +52,7 @@ fn match_wildcard_and_action() { // Lint, may panic match arr[idx] { - //~^ match_on_vec_items - + //~^ match_on_vec_items 0 => println!("0"), 1 => println!("1"), _ => println!("Hello, World!"), @@ -66,8 +60,7 @@ fn match_wildcard_and_action() { // Lint, may panic match arr[range] { - //~^ match_on_vec_items - + //~^ match_on_vec_items [0, 1] => println!("0 1"), [1, 2] => println!("1 2"), _ => println!("Hello, World!"), @@ -81,8 +74,7 @@ fn match_vec_ref() { // Lint, may panic match arr[idx] { - //~^ match_on_vec_items - + //~^ match_on_vec_items 0 => println!("0"), 1 => println!("1"), _ => {}, @@ -90,8 +82,7 @@ fn match_vec_ref() { // Lint, may panic match arr[range] { - //~^ match_on_vec_items - + //~^ match_on_vec_items [0, 1] => println!("0 1"), [1, 2] => println!("1 2"), _ => {}, diff --git a/tests/ui/match_on_vec_items.stderr b/tests/ui/match_on_vec_items.stderr index b00b2cb662a0..ae79e1305f7f 100644 --- a/tests/ui/match_on_vec_items.stderr +++ b/tests/ui/match_on_vec_items.stderr @@ -8,43 +8,43 @@ LL | match arr[idx] { = help: to override `-D warnings` add `#[allow(clippy::match_on_vec_items)]` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:20:11 + --> tests/ui/match_on_vec_items.rs:18:11 | LL | match arr[range] { | ^^^^^^^^^^ help: try: `arr.get(range)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:35:11 + --> tests/ui/match_on_vec_items.rs:32:11 | LL | match arr[idx] { | ^^^^^^^^ help: try: `arr.get(idx)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:44:11 + --> tests/ui/match_on_vec_items.rs:40:11 | LL | match arr[range] { | ^^^^^^^^^^ help: try: `arr.get(range)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:59:11 + --> tests/ui/match_on_vec_items.rs:54:11 | LL | match arr[idx] { | ^^^^^^^^ help: try: `arr.get(idx)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:68:11 + --> tests/ui/match_on_vec_items.rs:62:11 | LL | match arr[range] { | ^^^^^^^^^^ help: try: `arr.get(range)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:83:11 + --> tests/ui/match_on_vec_items.rs:76:11 | LL | match arr[idx] { | ^^^^^^^^ help: try: `arr.get(idx)` error: indexing into a vector may panic - --> tests/ui/match_on_vec_items.rs:92:11 + --> tests/ui/match_on_vec_items.rs:84:11 | LL | match arr[range] { | ^^^^^^^^^^ help: try: `arr.get(range)` diff --git a/tests/ui/match_overlapping_arm.rs b/tests/ui/match_overlapping_arm.rs index 3885731264f7..176287e3d2e0 100644 --- a/tests/ui/match_overlapping_arm.rs +++ b/tests/ui/match_overlapping_arm.rs @@ -8,7 +8,6 @@ fn overlapping() { match 42 { 0..=10 => println!("0..=10"), //~^ match_overlapping_arm - 0..=11 => println!("0..=11"), _ => (), } @@ -16,7 +15,6 @@ fn overlapping() { match 42 { 0..=5 => println!("0..=5"), //~^ match_overlapping_arm - 6..=7 => println!("6..=7"), FOO..=11 => println!("FOO..=11"), _ => (), @@ -55,7 +53,6 @@ fn overlapping() { match 42 { 0..11 => println!("0..11"), //~^ match_overlapping_arm - 0..=11 => println!("0..=11"), _ => (), } @@ -82,14 +79,12 @@ fn overlapping() { 5..14 => println!("5..14"), 0..=10 => println!("0..=10"), //~^ match_overlapping_arm - _ => (), } match 42 { 0..7 => println!("0..7"), //~^ match_overlapping_arm - 0..=10 => println!("0..=10"), _ => (), } @@ -103,7 +98,6 @@ fn overlapping() { match 42 { ..=23 => println!("..=23"), //~^ match_overlapping_arm - ..26 => println!("..26"), _ => (), } @@ -114,7 +108,6 @@ fn overlapping() { 0..=20 => (), 21..=30 => (), //~^ match_overlapping_arm - 21..=40 => (), _ => (), } @@ -130,7 +123,6 @@ fn overlapping() { match 42u128 { 0..=0x0000_0000_0000_00ff => (), //~^ match_overlapping_arm - 0..=0x0000_0000_0000_ffff => (), 0..=0x0000_0000_ffff_ffff => (), 0..=0xffff_ffff_ffff_ffff => (), diff --git a/tests/ui/match_overlapping_arm.stderr b/tests/ui/match_overlapping_arm.stderr index cc928b4066a9..a60a09a07990 100644 --- a/tests/ui/match_overlapping_arm.stderr +++ b/tests/ui/match_overlapping_arm.stderr @@ -5,7 +5,7 @@ LL | 0..=10 => println!("0..=10"), | ^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:12:9 + --> tests/ui/match_overlapping_arm.rs:11:9 | LL | 0..=11 => println!("0..=11"), | ^^^^^^ @@ -13,85 +13,85 @@ LL | 0..=11 => println!("0..=11"), = help: to override `-D warnings` add `#[allow(clippy::match_overlapping_arm)]` error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:17:9 + --> tests/ui/match_overlapping_arm.rs:16:9 | LL | 0..=5 => println!("0..=5"), | ^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:21:9 + --> tests/ui/match_overlapping_arm.rs:19:9 | LL | FOO..=11 => println!("FOO..=11"), | ^^^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:56:9 + --> tests/ui/match_overlapping_arm.rs:54:9 | LL | 0..11 => println!("0..11"), | ^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:59:9 + --> tests/ui/match_overlapping_arm.rs:56:9 | LL | 0..=11 => println!("0..=11"), | ^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:83:9 + --> tests/ui/match_overlapping_arm.rs:80:9 | LL | 0..=10 => println!("0..=10"), | ^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:82:9 + --> tests/ui/match_overlapping_arm.rs:79:9 | LL | 5..14 => println!("5..14"), | ^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:90:9 + --> tests/ui/match_overlapping_arm.rs:86:9 | LL | 0..7 => println!("0..7"), | ^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:93:9 + --> tests/ui/match_overlapping_arm.rs:88:9 | LL | 0..=10 => println!("0..=10"), | ^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:104:9 + --> tests/ui/match_overlapping_arm.rs:99:9 | LL | ..=23 => println!("..=23"), | ^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:107:9 + --> tests/ui/match_overlapping_arm.rs:101:9 | LL | ..26 => println!("..26"), | ^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:115:9 + --> tests/ui/match_overlapping_arm.rs:109:9 | LL | 21..=30 => (), | ^^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:118:9 + --> tests/ui/match_overlapping_arm.rs:111:9 | LL | 21..=40 => (), | ^^^^^^^ error: some ranges overlap - --> tests/ui/match_overlapping_arm.rs:131:9 + --> tests/ui/match_overlapping_arm.rs:124:9 | LL | 0..=0x0000_0000_0000_00ff => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: overlaps with this - --> tests/ui/match_overlapping_arm.rs:134:9 + --> tests/ui/match_overlapping_arm.rs:126:9 | LL | 0..=0x0000_0000_0000_ffff => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/match_ref_pats.fixed b/tests/ui/match_ref_pats.fixed index 8ada28985198..8add3da0c99f 100644 --- a/tests/ui/match_ref_pats.fixed +++ b/tests/ui/match_ref_pats.fixed @@ -6,7 +6,7 @@ fn ref_pats() { { let v = &Some(0); match *v { - //~^ match_ref_pats + //~^ match_ref_pats Some(v) => println!("{:?}", v), None => println!("none"), } @@ -24,7 +24,7 @@ fn ref_pats() { // Special case: using `&` both in expr and pats. let w = Some(0); match w { - //~^ match_ref_pats + //~^ match_ref_pats Some(v) => println!("{:?}", v), None => println!("none"), } @@ -37,13 +37,13 @@ fn ref_pats() { let a = &Some(0); if a.is_none() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching println!("none"); } let b = Some(0); if b.is_none() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching println!("none"); } } @@ -104,7 +104,7 @@ mod issue_7740 { fn issue_7740() { // Issue #7740 match *foobar_variant!(0) { - //~^ match_ref_pats + //~^ match_ref_pats FooBar::Foo => println!("Foo"), FooBar::Bar => println!("Bar"), FooBar::FooBar => println!("FooBar"), diff --git a/tests/ui/match_ref_pats.rs b/tests/ui/match_ref_pats.rs index cac6240bde31..07889b0dfc24 100644 --- a/tests/ui/match_ref_pats.rs +++ b/tests/ui/match_ref_pats.rs @@ -6,7 +6,7 @@ fn ref_pats() { { let v = &Some(0); match v { - //~^ match_ref_pats + //~^ match_ref_pats &Some(v) => println!("{:?}", v), &None => println!("none"), } @@ -24,7 +24,7 @@ fn ref_pats() { // Special case: using `&` both in expr and pats. let w = Some(0); match &w { - //~^ match_ref_pats + //~^ match_ref_pats &Some(v) => println!("{:?}", v), &None => println!("none"), } @@ -37,13 +37,13 @@ fn ref_pats() { let a = &Some(0); if let &None = a { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching println!("none"); } let b = Some(0); if let &None = &b { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching println!("none"); } } @@ -104,7 +104,7 @@ mod issue_7740 { fn issue_7740() { // Issue #7740 match foobar_variant!(0) { - //~^ match_ref_pats + //~^ match_ref_pats &FooBar::Foo => println!("Foo"), &FooBar::Bar => println!("Bar"), &FooBar::FooBar => println!("FooBar"), diff --git a/tests/ui/match_result_ok.fixed b/tests/ui/match_result_ok.fixed index 2032394f0e92..0e630e6a2904 100644 --- a/tests/ui/match_result_ok.fixed +++ b/tests/ui/match_result_ok.fixed @@ -49,7 +49,7 @@ impl Wat { fn base_1(x: i32) { let mut wat = Wat { counter: x }; while let Ok(a) = wat.next() { - //~^ match_result_ok + //~^ match_result_ok println!("{}", a); } } diff --git a/tests/ui/match_result_ok.rs b/tests/ui/match_result_ok.rs index c15e32d112d4..63bf6e8ab508 100644 --- a/tests/ui/match_result_ok.rs +++ b/tests/ui/match_result_ok.rs @@ -49,7 +49,7 @@ impl Wat { fn base_1(x: i32) { let mut wat = Wat { counter: x }; while let Some(a) = wat.next().ok() { - //~^ match_result_ok + //~^ match_result_ok println!("{}", a); } } diff --git a/tests/ui/match_same_arms.rs b/tests/ui/match_same_arms.rs index 073c66930357..55441948e91b 100644 --- a/tests/ui/match_same_arms.rs +++ b/tests/ui/match_same_arms.rs @@ -9,37 +9,36 @@ pub enum Abc { fn match_same_arms() { let _ = match Abc::A { -Abc::A => 0, -//~^ match_same_arms + Abc::A => 0, + //~^ match_same_arms Abc::B => 1, _ => 0, }; match (1, 2, 3) { -(1, .., 3) => 42, -//~^ match_same_arms + (1, .., 3) => 42, + //~^ match_same_arms (.., 3) => 42, _ => 0, }; let _ = match 42 { 42 => 1, -51 => 1, -//~^ match_same_arms -41 => 2, -//~^ match_same_arms + 51 => 1, + //~^ match_same_arms + 41 => 2, + //~^ match_same_arms 52 => 2, _ => 0, }; let _ = match 42 { 1 => 2, -2 => 2, -//~^ match_same_arms -//~| match_same_arms - -3 => 2, -//~^ match_same_arms + 2 => 2, + //~^ match_same_arms + //~| match_same_arms + 3 => 2, + //~^ match_same_arms 4 => 3, _ => 0, }; @@ -58,7 +57,6 @@ mod issue4244 { CommandInfo::BuiltIn { name, .. } => name.to_string(), CommandInfo::External { name, .. } => name.to_string(), //~^ match_same_arms - } } } diff --git a/tests/ui/match_same_arms.stderr b/tests/ui/match_same_arms.stderr index a269c4f39267..3744b83d89cc 100644 --- a/tests/ui/match_same_arms.stderr +++ b/tests/ui/match_same_arms.stderr @@ -1,9 +1,9 @@ error: this match arm has an identical body to the `_` wildcard arm - --> tests/ui/match_same_arms.rs:12:1 + --> tests/ui/match_same_arms.rs:12:9 | -LL | / Abc::A => 0, +LL | / Abc::A => 0, LL | | - | |_^ help: try removing the arm + | |________^ help: try removing the arm | = help: or try changing either arm body note: `_` wildcard arm here @@ -15,66 +15,66 @@ LL | _ => 0, = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]` error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:19:1 + --> tests/ui/match_same_arms.rs:19:9 | -LL | (1, .., 3) => 42, - | ^^^^^^^^^^^^^^^^ +LL | (1, .., 3) => 42, + | ^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ (1, .., 3) | (.., 3) => 42, +LL ~ (1, .., 3) | (.., 3) => 42, LL | LL ~ _ => 0, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:27:1 + --> tests/ui/match_same_arms.rs:27:9 | -LL | 51 => 1, - | ^^^^^^^ +LL | 51 => 1, + | ^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - 42 => 1, -LL - 51 => 1, +LL - 51 => 1, LL + 51 | 42 => 1, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:29:1 + --> tests/ui/match_same_arms.rs:29:9 | -LL | 41 => 2, - | ^^^^^^^ +LL | 41 => 2, + | ^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ 41 | 52 => 2, +LL ~ 41 | 52 => 2, LL | LL ~ _ => 0, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:37:1 + --> tests/ui/match_same_arms.rs:37:9 | -LL | 2 => 2, - | ^^^^^^ +LL | 2 => 2, + | ^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - 1 => 2, -LL - 2 => 2, +LL - 2 => 2, LL + 2 | 1 => 2, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:41:1 + --> tests/ui/match_same_arms.rs:40:9 | -LL | 3 => 2, - | ^^^^^^ +LL | 3 => 2, + | ^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm @@ -82,24 +82,26 @@ help: or try merging the arm patterns and removing the obsolete arm LL ~ 2 => 2, LL | LL | -LL | -LL ~ 3 | 1 => 2, +LL ~ 3 | 1 => 2, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:37:1 + --> tests/ui/match_same_arms.rs:37:9 | -LL | 2 => 2, - | ^^^^^^ +LL | 2 => 2, + | ^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ 2 | 3 => 2, +LL ~ 2 | 3 => 2, +LL | +LL | +LL ~ | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms.rs:59:17 + --> tests/ui/match_same_arms.rs:58:17 | LL | CommandInfo::External { name, .. } => name.to_string(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/match_same_arms2.fixed b/tests/ui/match_same_arms2.fixed index 855c3287532c..0d93e2c728d7 100644 --- a/tests/ui/match_same_arms2.fixed +++ b/tests/ui/match_same_arms2.fixed @@ -26,16 +26,15 @@ fn match_same_arms() { }, }; - let _ = match 42 { 51 | 42 => foo(), -//~^ match_same_arms + //~^ match_same_arms _ => true, }; let _ = match Some(42) { None | Some(_) => 24, -//~^ match_same_arms + //~^ match_same_arms }; let _ = match Some(42) { @@ -57,7 +56,7 @@ fn match_same_arms() { match (Some(42), Some(42)) { (None, Some(a)) | (Some(a), None) => bar(a), -//~^ match_same_arms + //~^ match_same_arms _ => (), } @@ -71,13 +70,13 @@ fn match_same_arms() { let _ = match (Some(42), Some(42)) { (None, Some(a)) | (Some(a), None) if a == 42 => a, -//~^ match_same_arms + //~^ match_same_arms _ => 0, }; match (Some(42), Some(42)) { -(Some(a), ..) | (.., Some(a)) => bar(a), -//~^ match_same_arms + (Some(a), ..) | (.., Some(a)) => bar(a), + //~^ match_same_arms _ => (), } @@ -110,8 +109,8 @@ fn match_same_arms() { } match (x, Some(1i32)) { -(Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), -//~^ match_same_arms + (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), + //~^ match_same_arms _ => println!("err"), } @@ -126,7 +125,7 @@ fn match_same_arms() { match x { Ok(_tmp) => println!("ok"), Ok(_) | Ok(3) => println!("ok"), -//~^ match_same_arms + //~^ match_same_arms Err(_) => { unreachable!(); }, @@ -159,7 +158,6 @@ fn match_same_arms() { }, } - match_expr_like_matches_macro_priority(); } @@ -202,8 +200,8 @@ fn main() { // Suggest moving `Foo::Z(_)` up. let _ = match Foo::X(0) { -Foo::X(0) | Foo::Z(_) => 1, -//~^ match_same_arms + Foo::X(0) | Foo::Z(_) => 1, + //~^ match_same_arms Foo::X(_) | Foo::Y(_) => 2, _ => 0, }; @@ -211,8 +209,8 @@ Foo::X(0) | Foo::Z(_) => 1, // Suggest moving `Foo::X(0)` down. let _ = match Foo::X(0) { Foo::Y(_) | Foo::Z(0) => 2, -Foo::Z(_) | Foo::X(0) => 1, -//~^ match_same_arms + Foo::Z(_) | Foo::X(0) => 1, + //~^ match_same_arms _ => 0, }; @@ -234,8 +232,8 @@ Foo::Z(_) | Foo::X(0) => 1, let _ = match None { Some(Bar { y: 10, z: 0, .. }) => 2, None => 50, -Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, -//~^ match_same_arms + Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, + //~^ match_same_arms _ => 200, }; @@ -266,7 +264,6 @@ mod with_lifetime { match *self { MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s, //~^ match_same_arms - } } } diff --git a/tests/ui/match_same_arms2.rs b/tests/ui/match_same_arms2.rs index 73a4fd432551..b0ebc4784f33 100644 --- a/tests/ui/match_same_arms2.rs +++ b/tests/ui/match_same_arms2.rs @@ -35,18 +35,17 @@ fn match_same_arms() { }, }; - let _ = match 42 { 42 => foo(), -51 => foo(), -//~^ match_same_arms + 51 => foo(), + //~^ match_same_arms _ => true, }; let _ = match Some(42) { Some(_) => 24, -None => 24, -//~^ match_same_arms + None => 24, + //~^ match_same_arms }; let _ = match Some(42) { @@ -68,8 +67,8 @@ None => 24, match (Some(42), Some(42)) { (Some(a), None) => bar(a), -(None, Some(a)) => bar(a), -//~^ match_same_arms + (None, Some(a)) => bar(a), + //~^ match_same_arms _ => (), } @@ -83,14 +82,14 @@ None => 24, let _ = match (Some(42), Some(42)) { (Some(a), None) if a == 42 => a, -(None, Some(a)) if a == 42 => a, -//~^ match_same_arms + (None, Some(a)) if a == 42 => a, + //~^ match_same_arms _ => 0, }; match (Some(42), Some(42)) { -(Some(a), ..) => bar(a), -//~^ match_same_arms + (Some(a), ..) => bar(a), + //~^ match_same_arms (.., Some(a)) => bar(a), _ => (), } @@ -124,8 +123,8 @@ None => 24, } match (x, Some(1i32)) { -(Ok(x), Some(_)) => println!("ok {}", x), -//~^ match_same_arms + (Ok(x), Some(_)) => println!("ok {}", x), + //~^ match_same_arms (Ok(_), Some(x)) => println!("ok {}", x), _ => println!("err"), } @@ -141,8 +140,8 @@ None => 24, match x { Ok(_tmp) => println!("ok"), Ok(3) => println!("ok"), -Ok(_) => println!("ok"), -//~^ match_same_arms + Ok(_) => println!("ok"), + //~^ match_same_arms Err(_) => { unreachable!(); }, @@ -178,7 +177,6 @@ Ok(_) => println!("ok"), }, } - match_expr_like_matches_macro_priority(); } @@ -221,8 +219,8 @@ fn main() { // Suggest moving `Foo::Z(_)` up. let _ = match Foo::X(0) { -Foo::X(0) => 1, -//~^ match_same_arms + Foo::X(0) => 1, + //~^ match_same_arms Foo::X(_) | Foo::Y(_) => 2, Foo::Z(_) => 1, _ => 0, @@ -232,8 +230,8 @@ Foo::X(0) => 1, let _ = match Foo::X(0) { Foo::X(0) => 1, Foo::Y(_) | Foo::Z(0) => 2, -Foo::Z(_) => 1, -//~^ match_same_arms + Foo::Z(_) => 1, + //~^ match_same_arms _ => 0, }; @@ -256,8 +254,8 @@ Foo::Z(_) => 1, Some(Bar { x: 0, y: 5, .. }) => 1, Some(Bar { y: 10, z: 0, .. }) => 2, None => 50, -Some(Bar { y: 0, x: 5, .. }) => 1, -//~^ match_same_arms + Some(Bar { y: 0, x: 5, .. }) => 1, + //~^ match_same_arms _ => 200, }; @@ -290,7 +288,6 @@ mod with_lifetime { MaybeStaticStr::Static(s) => s, MaybeStaticStr::Borrowed(s) => s, //~^ match_same_arms - } } } diff --git a/tests/ui/match_same_arms2.stderr b/tests/ui/match_same_arms2.stderr index c67ac5475aae..21a8743cc324 100644 --- a/tests/ui/match_same_arms2.stderr +++ b/tests/ui/match_same_arms2.stderr @@ -26,105 +26,105 @@ LL | | }, = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]` error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:41:1 + --> tests/ui/match_same_arms2.rs:40:9 | -LL | 51 => foo(), - | ^^^^^^^^^^^ +LL | 51 => foo(), + | ^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - 42 => foo(), -LL - 51 => foo(), +LL - 51 => foo(), LL + 51 | 42 => foo(), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:48:1 + --> tests/ui/match_same_arms2.rs:47:9 | -LL | None => 24, - | ^^^^^^^^^^ +LL | None => 24, + | ^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - Some(_) => 24, -LL - None => 24, +LL - None => 24, LL + None | Some(_) => 24, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:71:1 + --> tests/ui/match_same_arms2.rs:70:9 | -LL | (None, Some(a)) => bar(a), - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (None, Some(a)) => bar(a), + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - (Some(a), None) => bar(a), -LL - (None, Some(a)) => bar(a), +LL - (None, Some(a)) => bar(a), LL + (None, Some(a)) | (Some(a), None) => bar(a), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:86:1 + --> tests/ui/match_same_arms2.rs:85:9 | -LL | (None, Some(a)) if a == 42 => a, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (None, Some(a)) if a == 42 => a, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - (Some(a), None) if a == 42 => a, -LL - (None, Some(a)) if a == 42 => a, +LL - (None, Some(a)) if a == 42 => a, LL + (None, Some(a)) | (Some(a), None) if a == 42 => a, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:92:1 + --> tests/ui/match_same_arms2.rs:91:9 | -LL | (Some(a), ..) => bar(a), - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | (Some(a), ..) => bar(a), + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ (Some(a), ..) | (.., Some(a)) => bar(a), +LL ~ (Some(a), ..) | (.., Some(a)) => bar(a), LL | LL ~ _ => (), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:127:1 + --> tests/ui/match_same_arms2.rs:126:9 | -LL | (Ok(x), Some(_)) => println!("ok {}", x), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (Ok(x), Some(_)) => println!("ok {}", x), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), +LL ~ (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), LL | LL ~ _ => println!("err"), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:144:1 + --> tests/ui/match_same_arms2.rs:143:9 | -LL | Ok(_) => println!("ok"), - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | Ok(_) => println!("ok"), + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL - Ok(3) => println!("ok"), -LL - Ok(_) => println!("ok"), +LL - Ok(_) => println!("ok"), LL + Ok(_) | Ok(3) => println!("ok"), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:172:9 + --> tests/ui/match_same_arms2.rs:171:9 | LL | / 1 => { LL | | empty!(0); @@ -142,49 +142,49 @@ LL + 1 | 0 => { | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:224:1 + --> tests/ui/match_same_arms2.rs:222:9 | -LL | Foo::X(0) => 1, - | ^^^^^^^^^^^^^^ +LL | Foo::X(0) => 1, + | ^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | -LL ~ Foo::X(0) | Foo::Z(_) => 1, +LL ~ Foo::X(0) | Foo::Z(_) => 1, LL | LL | Foo::X(_) | Foo::Y(_) => 2, LL ~ _ => 0, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:235:1 + --> tests/ui/match_same_arms2.rs:233:9 | -LL | Foo::Z(_) => 1, - | ^^^^^^^^^^^^^^ +LL | Foo::Z(_) => 1, + | ^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL ~ Foo::Y(_) | Foo::Z(0) => 2, -LL ~ Foo::Z(_) | Foo::X(0) => 1, +LL ~ Foo::Z(_) | Foo::X(0) => 1, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:259:1 + --> tests/ui/match_same_arms2.rs:257:9 | -LL | Some(Bar { y: 0, x: 5, .. }) => 1, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Some(Bar { y: 0, x: 5, .. }) => 1, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try changing either arm body help: or try merging the arm patterns and removing the obsolete arm | LL ~ Some(Bar { y: 10, z: 0, .. }) => 2, LL | None => 50, -LL ~ Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, +LL ~ Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:274:9 + --> tests/ui/match_same_arms2.rs:272:9 | LL | 1 => cfg!(not_enable), | ^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +198,7 @@ LL + 1 | 0 => cfg!(not_enable), | error: this match arm has an identical body to another arm - --> tests/ui/match_same_arms2.rs:291:17 + --> tests/ui/match_same_arms2.rs:289:17 | LL | MaybeStaticStr::Borrowed(s) => s, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/match_same_arms_non_exhaustive.fixed b/tests/ui/match_same_arms_non_exhaustive.fixed index 71041cff8d0a..0c9398933b80 100644 --- a/tests/ui/match_same_arms_non_exhaustive.fixed +++ b/tests/ui/match_same_arms_non_exhaustive.fixed @@ -42,7 +42,6 @@ pub fn g(x: Ordering) { Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), //~^ match_same_arms - _ => repeat(), } } @@ -56,7 +55,6 @@ mod g { Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), //~^ match_same_arms - _ => repeat(), } } diff --git a/tests/ui/match_same_arms_non_exhaustive.rs b/tests/ui/match_same_arms_non_exhaustive.rs index 45dc5d78883b..304a9e5c28e7 100644 --- a/tests/ui/match_same_arms_non_exhaustive.rs +++ b/tests/ui/match_same_arms_non_exhaustive.rs @@ -43,7 +43,6 @@ pub fn g(x: Ordering) { Ordering::Acquire => println!("acquire"), Ordering::AcqRel | Ordering::SeqCst => repeat(), //~^ match_same_arms - _ => repeat(), } } @@ -58,7 +57,6 @@ mod g { Ordering::Acquire => println!("acquire"), Ordering::AcqRel | Ordering::SeqCst => repeat(), //~^ match_same_arms - _ => repeat(), } } diff --git a/tests/ui/match_same_arms_non_exhaustive.stderr b/tests/ui/match_same_arms_non_exhaustive.stderr index 1033203c7237..aa7f8c95dce8 100644 --- a/tests/ui/match_same_arms_non_exhaustive.stderr +++ b/tests/ui/match_same_arms_non_exhaustive.stderr @@ -7,7 +7,7 @@ LL | | | = help: or try changing either arm body note: `_` wildcard arm here - --> tests/ui/match_same_arms_non_exhaustive.rs:47:9 + --> tests/ui/match_same_arms_non_exhaustive.rs:46:9 | LL | _ => repeat(), | ^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | _ => repeat(), = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]` error: this match arm has an identical body to the `_` wildcard arm - --> tests/ui/match_same_arms_non_exhaustive.rs:59:13 + --> tests/ui/match_same_arms_non_exhaustive.rs:58:13 | LL | / Ordering::AcqRel | Ordering::SeqCst => repeat(), LL | | @@ -23,7 +23,7 @@ LL | | | = help: or try changing either arm body note: `_` wildcard arm here - --> tests/ui/match_same_arms_non_exhaustive.rs:62:13 + --> tests/ui/match_same_arms_non_exhaustive.rs:60:13 | LL | _ => repeat(), | ^^^^^^^^^^^^^ diff --git a/tests/ui/match_single_binding.rs b/tests/ui/match_single_binding.rs index 27fd7d601abf..ada51254c6cd 100644 --- a/tests/ui/match_single_binding.rs +++ b/tests/ui/match_single_binding.rs @@ -31,14 +31,14 @@ fn main() { let c = 3; // Lint match (a, b, c) { - //~^ match_single_binding + //~^ match_single_binding (x, y, z) => { println!("{} {} {}", x, y, z); }, } // Lint match (a, b, c) { - //~^ match_single_binding + //~^ match_single_binding (x, y, z) => println!("{} {} {}", x, y, z), } // Ok @@ -56,12 +56,12 @@ fn main() { } // Lint match a { - //~^ match_single_binding + //~^ match_single_binding _ => println!("whatever"), } // Lint match a { - //~^ match_single_binding + //~^ match_single_binding _ => { let x = 29; println!("x has a value of {}", x); @@ -69,7 +69,7 @@ fn main() { } // Lint match a { - //~^ match_single_binding + //~^ match_single_binding _ => { let e = 5 * a; if e >= 5 { @@ -80,29 +80,29 @@ fn main() { // Lint let p = Point { x: 0, y: 7 }; match p { - //~^ match_single_binding + //~^ match_single_binding Point { x, y } => println!("Coords: ({}, {})", x, y), } // Lint match p { - //~^ match_single_binding + //~^ match_single_binding Point { x: x1, y: y1 } => println!("Coords: ({}, {})", x1, y1), } // Lint let x = 5; match x { - //~^ match_single_binding + //~^ match_single_binding ref r => println!("Got a reference to {}", r), } // Lint let mut x = 5; match x { - //~^ match_single_binding + //~^ match_single_binding ref mut mr => println!("Got a mutable reference to {}", mr), } // Lint let product = match coords() { - //~^ match_single_binding + //~^ match_single_binding Point { x, y } => x * y, }; // Lint @@ -111,7 +111,7 @@ fn main() { let _ = v .iter() .map(|i| match i.unwrap() { - //~^ match_single_binding + //~^ match_single_binding unwrapped => unwrapped, }) .collect::>(); @@ -138,7 +138,7 @@ fn main() { // Lint let x = 1; match x { - //~^ match_single_binding + //~^ match_single_binding // => _ => println!("Not an array index start"), } @@ -148,7 +148,7 @@ fn issue_8723() { let (mut val, idx) = ("a b", 1); val = match val.split_at(idx) { - //~^ match_single_binding + //~^ match_single_binding (pre, suf) => { println!("{}", pre); suf @@ -162,14 +162,14 @@ fn side_effects() {} fn issue_9575() { let _ = || match side_effects() { - //~^ match_single_binding + //~^ match_single_binding _ => println!("Needs curlies"), }; } fn issue_9725(r: Option) { match r { - //~^ match_single_binding + //~^ match_single_binding x => match x { Some(_) => { println!("Some"); @@ -183,46 +183,46 @@ fn issue_9725(r: Option) { fn issue_10447() -> usize { match 1 { - //~^ match_single_binding + //~^ match_single_binding _ => (), } let a = match 1 { - //~^ match_single_binding + //~^ match_single_binding _ => (), }; match 1 { - //~^ match_single_binding + //~^ match_single_binding _ => side_effects(), } let b = match 1 { - //~^ match_single_binding + //~^ match_single_binding _ => side_effects(), }; match 1 { - //~^ match_single_binding + //~^ match_single_binding _ => println!("1"), } let c = match 1 { - //~^ match_single_binding + //~^ match_single_binding _ => println!("1"), }; let in_expr = [ match 1 { - //~^ match_single_binding + //~^ match_single_binding _ => (), }, match 1 { - //~^ match_single_binding + //~^ match_single_binding _ => side_effects(), }, match 1 { - //~^ match_single_binding + //~^ match_single_binding _ => println!("1"), }, ]; diff --git a/tests/ui/match_single_binding2.fixed b/tests/ui/match_single_binding2.fixed index 1d34f179ea4a..988121f50d0f 100644 --- a/tests/ui/match_single_binding2.fixed +++ b/tests/ui/match_single_binding2.fixed @@ -45,7 +45,7 @@ fn main() { // issue #7094 let x = 1; match x { - //~^ match_single_binding + //~^ match_single_binding 0 => 1, _ => 2, }; diff --git a/tests/ui/match_single_binding2.rs b/tests/ui/match_single_binding2.rs index 8c18d7c133c1..a4fb2bd6f381 100644 --- a/tests/ui/match_single_binding2.rs +++ b/tests/ui/match_single_binding2.rs @@ -15,7 +15,7 @@ fn main() { fn size_hint(iter: &AppendIter) -> (usize, Option) { match &iter.inner { Some((iter, _item)) => match iter.size_hint() { - //~^ match_single_binding + //~^ match_single_binding (min, max) => (min.saturating_add(1), max.and_then(|max| max.checked_add(1))), }, None => (0, Some(0)), @@ -41,7 +41,7 @@ fn main() { // Lint (scrutinee has side effects) // issue #7094 match side_effects() { - //~^ match_single_binding + //~^ match_single_binding _ => println!("Side effects"), } @@ -49,7 +49,7 @@ fn main() { // issue #7094 let x = 1; match match x { - //~^ match_single_binding + //~^ match_single_binding 0 => 1, _ => 2, } { diff --git a/tests/ui/match_wild_err_arm.rs b/tests/ui/match_wild_err_arm.rs index f7f7c398d647..d18d4047e2a6 100644 --- a/tests/ui/match_wild_err_arm.rs +++ b/tests/ui/match_wild_err_arm.rs @@ -22,8 +22,6 @@ fn match_wild_err_arm() { Ok(_) => println!("ok"), Err(_) => panic!("err"), //~^ match_wild_err_arm - - } match x { @@ -31,16 +29,13 @@ fn match_wild_err_arm() { Ok(_) => println!("ok"), Err(_) => panic!(), //~^ match_wild_err_arm - - } match x { Ok(3) => println!("ok"), Ok(_) => println!("ok"), Err(_) => { - //~^ match_wild_err_arm - + //~^ match_wild_err_arm panic!(); }, @@ -51,8 +46,6 @@ fn match_wild_err_arm() { Ok(_) => println!("ok"), Err(_e) => panic!(), //~^ match_wild_err_arm - - } // Allowed when used in `panic!`. diff --git a/tests/ui/match_wild_err_arm.stderr b/tests/ui/match_wild_err_arm.stderr index ec0ca602f5f9..fc65924f0873 100644 --- a/tests/ui/match_wild_err_arm.stderr +++ b/tests/ui/match_wild_err_arm.stderr @@ -9,7 +9,7 @@ LL | Err(_) => panic!("err"), = help: to override `-D warnings` add `#[allow(clippy::match_wild_err_arm)]` error: `Err(_)` matches all errors - --> tests/ui/match_wild_err_arm.rs:32:9 + --> tests/ui/match_wild_err_arm.rs:30:9 | LL | Err(_) => panic!(), | ^^^^^^ @@ -17,7 +17,7 @@ LL | Err(_) => panic!(), = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_)` matches all errors - --> tests/ui/match_wild_err_arm.rs:41:9 + --> tests/ui/match_wild_err_arm.rs:37:9 | LL | Err(_) => { | ^^^^^^ @@ -25,7 +25,7 @@ LL | Err(_) => { = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_e)` matches all errors - --> tests/ui/match_wild_err_arm.rs:52:9 + --> tests/ui/match_wild_err_arm.rs:47:9 | LL | Err(_e) => panic!(), | ^^^^^^^ diff --git a/tests/ui/mem_forget.rs b/tests/ui/mem_forget.rs index ad9bd079b98d..b510af8ac6f1 100644 --- a/tests/ui/mem_forget.rs +++ b/tests/ui/mem_forget.rs @@ -14,25 +14,17 @@ fn main() { memstuff::forget(six); //~^ mem_forget - - let seven: Rc = Rc::new(7); std::mem::forget(seven); //~^ mem_forget - - let eight: Vec = vec![8]; forgetSomething(eight); //~^ mem_forget - - let string = String::new(); std::mem::forget(string); //~^ mem_forget - - std::mem::forget(7); } diff --git a/tests/ui/mem_forget.stderr b/tests/ui/mem_forget.stderr index 4dd1efc1a240..049db54a04b0 100644 --- a/tests/ui/mem_forget.stderr +++ b/tests/ui/mem_forget.stderr @@ -9,7 +9,7 @@ LL | memstuff::forget(six); = help: to override `-D warnings` add `#[allow(clippy::mem_forget)]` error: usage of `mem::forget` on `Drop` type - --> tests/ui/mem_forget.rs:20:5 + --> tests/ui/mem_forget.rs:18:5 | LL | std::mem::forget(seven); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | std::mem::forget(seven); = note: argument has type `std::rc::Rc` error: usage of `mem::forget` on `Drop` type - --> tests/ui/mem_forget.rs:26:5 + --> tests/ui/mem_forget.rs:22:5 | LL | forgetSomething(eight); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | forgetSomething(eight); = note: argument has type `std::vec::Vec` error: usage of `mem::forget` on type with `Drop` fields - --> tests/ui/mem_forget.rs:32:5 + --> tests/ui/mem_forget.rs:26:5 | LL | std::mem::forget(string); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/mem_replace.stderr b/tests/ui/mem_replace.stderr index 98417df8c84b..fb4a367266d3 100644 --- a/tests/ui/mem_replace.stderr +++ b/tests/ui/mem_replace.stderr @@ -161,7 +161,7 @@ LL | let _ = std::mem::replace(&mut b.val, String::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)` error: replacing an `Option` with `Some(..)` - --> tests/ui/mem_replace.rs:138:20 + --> tests/ui/mem_replace.rs:164:20 | LL | let replaced = mem::replace(&mut an_option, Some(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `an_option.replace(1)` @@ -170,13 +170,13 @@ LL | let replaced = mem::replace(&mut an_option, Some(1)); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_some)]` error: replacing an `Option` with `Some(..)` - --> tests/ui/mem_replace.rs:142:20 + --> tests/ui/mem_replace.rs:168:20 | LL | let replaced = mem::replace(an_option, Some(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `an_option.replace(1)` error: replacing an `Option` with `Some(..)` - --> tests/ui/mem_replace.rs:147:20 + --> tests/ui/mem_replace.rs:173:20 | LL | let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `(if b { &mut opt1 } else { &mut opt2 }).replace(1)` diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs index a7e37b2e8d23..85a4d59e5ca0 100644 --- a/tests/ui/methods.rs +++ b/tests/ui/methods.rs @@ -101,7 +101,7 @@ struct BadNew; impl BadNew { fn new() -> i32 { - //~^ new_ret_no_self + //~^ new_ret_no_self 0 } } diff --git a/tests/ui/methods_unfixable.rs b/tests/ui/methods_unfixable.rs index a9881080d6f4..c19a769f7974 100644 --- a/tests/ui/methods_unfixable.rs +++ b/tests/ui/methods_unfixable.rs @@ -8,5 +8,4 @@ pub fn issue10029() { let iter = (0..10); let _ = iter.filter(|_| true).next(); //~^ filter_next - } diff --git a/tests/ui/min_ident_chars.rs b/tests/ui/min_ident_chars.rs index 5eae52d5c25c..f473ac848a8e 100644 --- a/tests/ui/min_ident_chars.rs +++ b/tests/ui/min_ident_chars.rs @@ -7,7 +7,7 @@ extern crate proc_macros; use proc_macros::{external, with_span}; struct A { -//~^ min_ident_chars + //~^ min_ident_chars a: u32, //~^ min_ident_chars i: u32, @@ -21,7 +21,7 @@ struct B(u32); //~^ min_ident_chars struct O { -//~^ min_ident_chars + //~^ min_ident_chars o: u32, //~^ min_ident_chars } @@ -29,7 +29,7 @@ struct O { struct i; enum C { -//~^ min_ident_chars + //~^ min_ident_chars D, //~^ min_ident_chars E, @@ -116,8 +116,8 @@ fn main() { fn b() {} //~^ min_ident_chars fn wrong_pythagoras(a: f32, b: f32) -> f32 { -//~^ min_ident_chars -//~| min_ident_chars + //~^ min_ident_chars + //~| min_ident_chars a * a + a * b } diff --git a/tests/ui/min_max.rs b/tests/ui/min_max.rs index 1b1a6a0eb10b..f3eeb85f20ed 100644 --- a/tests/ui/min_max.rs +++ b/tests/ui/min_max.rs @@ -22,7 +22,6 @@ fn main() { min(1, max(3, x)); //~^ min_max - min(max(3, x), 1); //~^ min_max @@ -32,11 +31,9 @@ fn main() { max(3, min(x, 1)); //~^ min_max - my_max(3, my_min(x, 1)); //~^ min_max - min(3, max(1, x)); // ok, could be 1, 2 or 3 depending on x min(1, max(LARGE, x)); // no error, we don't lookup consts here @@ -51,7 +48,6 @@ fn main() { max(min(s, "Apple"), "Zoo"); //~^ min_max - max("Apple", min(s, "Zoo")); // ok let f = 3f32; @@ -64,7 +60,6 @@ fn main() { f.max(3f32).min(1f32); //~^ min_max - x.max(1).min(3); // ok x.min(3).max(1); // ok f.min(3f32).max(1f32); // ok @@ -80,7 +75,6 @@ fn main() { s.min("Apple").max("Zoo"); //~^ min_max - s.min("Zoo").max("Apple"); // ok let not_ord = NotOrd(1); diff --git a/tests/ui/min_max.stderr b/tests/ui/min_max.stderr index 91b3d722b3c6..84b4d3754552 100644 --- a/tests/ui/min_max.stderr +++ b/tests/ui/min_max.stderr @@ -8,73 +8,73 @@ LL | min(1, max(3, x)); = help: to override `-D warnings` add `#[allow(clippy::min_max)]` error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:26:5 + --> tests/ui/min_max.rs:25:5 | LL | min(max(3, x), 1); | ^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:29:5 + --> tests/ui/min_max.rs:28:5 | LL | max(min(x, 1), 3); | ^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:32:5 + --> tests/ui/min_max.rs:31:5 | LL | max(3, min(x, 1)); | ^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:36:5 + --> tests/ui/min_max.rs:34:5 | LL | my_max(3, my_min(x, 1)); | ^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:48:5 + --> tests/ui/min_max.rs:45:5 | LL | min("Apple", max("Zoo", s)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:51:5 + --> tests/ui/min_max.rs:48:5 | LL | max(min(s, "Apple"), "Zoo"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:58:5 + --> tests/ui/min_max.rs:54:5 | LL | x.min(1).max(3); | ^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:61:5 + --> tests/ui/min_max.rs:57:5 | LL | x.max(3).min(1); | ^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:64:5 + --> tests/ui/min_max.rs:60:5 | LL | f.max(3f32).min(1f32); | ^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:72:5 + --> tests/ui/min_max.rs:67:5 | LL | max(x.min(1), 3); | ^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:77:5 + --> tests/ui/min_max.rs:72:5 | LL | s.max("Zoo").min("Apple"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> tests/ui/min_max.rs:80:5 + --> tests/ui/min_max.rs:75:5 | LL | s.min("Apple").max("Zoo"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/min_rust_version_attr.rs b/tests/ui/min_rust_version_attr.rs index 4793eb9726d6..4627bef28a29 100644 --- a/tests/ui/min_rust_version_attr.rs +++ b/tests/ui/min_rust_version_attr.rs @@ -12,14 +12,12 @@ fn just_under_msrv() { fn meets_msrv() { let log2_10 = 3.321928094887362; //~^ approx_constant - } #[clippy::msrv = "1.44.0"] fn just_above_msrv() { let log2_10 = 3.321928094887362; //~^ approx_constant - } #[clippy::msrv = "1.42"] @@ -31,7 +29,6 @@ fn no_patch_under() { fn no_patch_meets() { let log2_10 = 3.321928094887362; //~^ approx_constant - } fn inner_attr_under() { @@ -43,7 +40,6 @@ fn inner_attr_meets() { #![clippy::msrv = "1.43"] let log2_10 = 3.321928094887362; //~^ approx_constant - } // https://github.com/rust-lang/rust-clippy/issues/6920 @@ -56,7 +52,6 @@ fn scoping() { let log2_10 = 3.321928094887362; //~^ approx_constant - mod a { #![clippy::msrv = "1.42.0"] @@ -64,7 +59,6 @@ fn scoping() { #![clippy::msrv = "1.43.0"] let log2_10 = 3.321928094887362; //~^ approx_constant - } fn should_not_warn() { diff --git a/tests/ui/min_rust_version_attr.stderr b/tests/ui/min_rust_version_attr.stderr index 6d4a8d9bd86e..809b1cfe73bf 100644 --- a/tests/ui/min_rust_version_attr.stderr +++ b/tests/ui/min_rust_version_attr.stderr @@ -8,7 +8,7 @@ LL | let log2_10 = 3.321928094887362; = note: `#[deny(clippy::approx_constant)]` on by default error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:20:19 + --> tests/ui/min_rust_version_attr.rs:19:19 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let log2_10 = 3.321928094887362; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:32:19 + --> tests/ui/min_rust_version_attr.rs:30:19 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | let log2_10 = 3.321928094887362; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:44:19 + --> tests/ui/min_rust_version_attr.rs:41:19 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | let log2_10 = 3.321928094887362; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:56:19 + --> tests/ui/min_rust_version_attr.rs:52:19 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | let log2_10 = 3.321928094887362; = help: consider using the constant directly error: approximate value of `f{32, 64}::consts::LOG2_10` found - --> tests/ui/min_rust_version_attr.rs:65:27 + --> tests/ui/min_rust_version_attr.rs:60:27 | LL | let log2_10 = 3.321928094887362; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/mismatching_type_param_order.rs b/tests/ui/mismatching_type_param_order.rs index 7e6044d0f5ff..11ff865b583b 100644 --- a/tests/ui/mismatching_type_param_order.rs +++ b/tests/ui/mismatching_type_param_order.rs @@ -12,13 +12,10 @@ fn main() { //~^ mismatching_type_param_order //~| mismatching_type_param_order - - // lint on the 2nd param impl Foo {} //~^ mismatching_type_param_order - // should not lint impl Foo {} @@ -32,8 +29,6 @@ fn main() { //~^ mismatching_type_param_order //~| mismatching_type_param_order - - struct Bar { x: i32, } @@ -53,9 +48,6 @@ fn main() { //~| mismatching_type_param_order //~| mismatching_type_param_order - - - // also works for unions union FooUnion where @@ -69,8 +61,6 @@ fn main() { //~^ mismatching_type_param_order //~| mismatching_type_param_order - - impl FooUnion where A: Copy, diff --git a/tests/ui/mismatching_type_param_order.stderr b/tests/ui/mismatching_type_param_order.stderr index 817ab8c99796..214d9d734d1b 100644 --- a/tests/ui/mismatching_type_param_order.stderr +++ b/tests/ui/mismatching_type_param_order.stderr @@ -17,7 +17,7 @@ LL | impl Foo {} = help: try `B`, or a name that does not conflict with `Foo`'s generic params error: `Foo` has a similarly named generic type parameter `A` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:18:23 + --> tests/ui/mismatching_type_param_order.rs:16:23 | LL | impl Foo {} | ^ @@ -25,7 +25,7 @@ LL | impl Foo {} = help: try `B`, or a name that does not conflict with `Foo`'s generic params error: `FooLifetime` has a similarly named generic type parameter `B` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:31:44 + --> tests/ui/mismatching_type_param_order.rs:28:44 | LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {} | ^ @@ -33,7 +33,7 @@ LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {} = help: try `A`, or a name that does not conflict with `FooLifetime`'s generic params error: `FooLifetime` has a similarly named generic type parameter `A` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:31:47 + --> tests/ui/mismatching_type_param_order.rs:28:47 | LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {} | ^ @@ -41,7 +41,7 @@ LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {} = help: try `B`, or a name that does not conflict with `FooLifetime`'s generic params error: `FooEnum` has a similarly named generic type parameter `C` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:51:27 + --> tests/ui/mismatching_type_param_order.rs:46:27 | LL | impl FooEnum {} | ^ @@ -49,7 +49,7 @@ LL | impl FooEnum {} = help: try `A`, or a name that does not conflict with `FooEnum`'s generic params error: `FooEnum` has a similarly named generic type parameter `A` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:51:30 + --> tests/ui/mismatching_type_param_order.rs:46:30 | LL | impl FooEnum {} | ^ @@ -57,7 +57,7 @@ LL | impl FooEnum {} = help: try `B`, or a name that does not conflict with `FooEnum`'s generic params error: `FooEnum` has a similarly named generic type parameter `B` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:51:33 + --> tests/ui/mismatching_type_param_order.rs:46:33 | LL | impl FooEnum {} | ^ @@ -65,7 +65,7 @@ LL | impl FooEnum {} = help: try `C`, or a name that does not conflict with `FooEnum`'s generic params error: `FooUnion` has a similarly named generic type parameter `B` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:68:31 + --> tests/ui/mismatching_type_param_order.rs:60:31 | LL | impl FooUnion where A: Copy {} | ^ @@ -73,7 +73,7 @@ LL | impl FooUnion where A: Copy {} = help: try `A`, or a name that does not conflict with `FooUnion`'s generic params error: `FooUnion` has a similarly named generic type parameter `A` in its declaration, but in a different order - --> tests/ui/mismatching_type_param_order.rs:68:34 + --> tests/ui/mismatching_type_param_order.rs:60:34 | LL | impl FooUnion where A: Copy {} | ^ diff --git a/tests/ui/misnamed_getters.fixed b/tests/ui/misnamed_getters.fixed index 81af604e2e63..cada5307b1c8 100644 --- a/tests/ui/misnamed_getters.fixed +++ b/tests/ui/misnamed_getters.fixed @@ -10,37 +10,36 @@ struct A { impl A { fn a(&self) -> &u8 { - //~^ misnamed_getters - + //~^ misnamed_getters &self.a } fn a_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.a } fn b(self) -> u8 { - //~^ misnamed_getters + //~^ misnamed_getters self.b } fn b_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.b } fn c(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.c } fn c_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.c } @@ -53,24 +52,24 @@ union B { impl B { unsafe fn a(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.a } unsafe fn a_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.a } unsafe fn b(self) -> u8 { - //~^ misnamed_getters + //~^ misnamed_getters self.b } unsafe fn b_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.b } @@ -84,24 +83,24 @@ impl B { } unsafe fn a_unchecked(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.a } unsafe fn a_unchecked_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.a } unsafe fn b_unchecked(self) -> u8 { - //~^ misnamed_getters + //~^ misnamed_getters self.b } unsafe fn b_unchecked_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.b } @@ -135,23 +134,23 @@ impl core::ops::DerefMut for D { impl D { fn a(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.a } fn a_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.a } fn d(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.d } fn d_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.d } diff --git a/tests/ui/misnamed_getters.rs b/tests/ui/misnamed_getters.rs index cb83ae02ccf1..f529c56b4717 100644 --- a/tests/ui/misnamed_getters.rs +++ b/tests/ui/misnamed_getters.rs @@ -10,37 +10,36 @@ struct A { impl A { fn a(&self) -> &u8 { - //~^ misnamed_getters - + //~^ misnamed_getters &self.b } fn a_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.b } fn b(self) -> u8 { - //~^ misnamed_getters + //~^ misnamed_getters self.a } fn b_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.a } fn c(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.b } fn c_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.a } @@ -53,24 +52,24 @@ union B { impl B { unsafe fn a(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.b } unsafe fn a_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.b } unsafe fn b(self) -> u8 { - //~^ misnamed_getters + //~^ misnamed_getters self.a } unsafe fn b_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.a } @@ -84,24 +83,24 @@ impl B { } unsafe fn a_unchecked(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.b } unsafe fn a_unchecked_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.b } unsafe fn b_unchecked(self) -> u8 { - //~^ misnamed_getters + //~^ misnamed_getters self.a } unsafe fn b_unchecked_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.a } @@ -135,23 +134,23 @@ impl core::ops::DerefMut for D { impl D { fn a(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.b } fn a_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.b } fn d(&self) -> &u8 { - //~^ misnamed_getters + //~^ misnamed_getters &self.b } fn d_mut(&mut self) -> &mut u8 { - //~^ misnamed_getters + //~^ misnamed_getters &mut self.b } diff --git a/tests/ui/misnamed_getters.stderr b/tests/ui/misnamed_getters.stderr index e3ea40b7a94e..5dd1d75bcf6f 100644 --- a/tests/ui/misnamed_getters.stderr +++ b/tests/ui/misnamed_getters.stderr @@ -2,7 +2,8 @@ error: getter function appears to return the wrong field --> tests/ui/misnamed_getters.rs:12:5 | LL | / fn a(&self) -> &u8 { -... | +LL | | +LL | | LL | | &self.b | | ------- help: consider using: `&self.a` LL | | } @@ -12,7 +13,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::misnamed_getters)]` error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:18:5 + --> tests/ui/misnamed_getters.rs:17:5 | LL | / fn a_mut(&mut self) -> &mut u8 { LL | | @@ -23,7 +24,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:24:5 + --> tests/ui/misnamed_getters.rs:23:5 | LL | / fn b(self) -> u8 { LL | | @@ -34,7 +35,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:30:5 + --> tests/ui/misnamed_getters.rs:29:5 | LL | / fn b_mut(&mut self) -> &mut u8 { LL | | @@ -45,7 +46,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:36:5 + --> tests/ui/misnamed_getters.rs:35:5 | LL | / fn c(&self) -> &u8 { LL | | @@ -56,7 +57,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:42:5 + --> tests/ui/misnamed_getters.rs:41:5 | LL | / fn c_mut(&mut self) -> &mut u8 { LL | | @@ -67,7 +68,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:55:5 + --> tests/ui/misnamed_getters.rs:54:5 | LL | / unsafe fn a(&self) -> &u8 { LL | | @@ -78,7 +79,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:60:5 + --> tests/ui/misnamed_getters.rs:59:5 | LL | / unsafe fn a_mut(&mut self) -> &mut u8 { LL | | @@ -89,7 +90,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:66:5 + --> tests/ui/misnamed_getters.rs:65:5 | LL | / unsafe fn b(self) -> u8 { LL | | @@ -100,7 +101,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:72:5 + --> tests/ui/misnamed_getters.rs:71:5 | LL | / unsafe fn b_mut(&mut self) -> &mut u8 { LL | | @@ -111,7 +112,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:86:5 + --> tests/ui/misnamed_getters.rs:85:5 | LL | / unsafe fn a_unchecked(&self) -> &u8 { LL | | @@ -122,7 +123,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:91:5 + --> tests/ui/misnamed_getters.rs:90:5 | LL | / unsafe fn a_unchecked_mut(&mut self) -> &mut u8 { LL | | @@ -133,7 +134,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:97:5 + --> tests/ui/misnamed_getters.rs:96:5 | LL | / unsafe fn b_unchecked(self) -> u8 { LL | | @@ -144,7 +145,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:103:5 + --> tests/ui/misnamed_getters.rs:102:5 | LL | / unsafe fn b_unchecked_mut(&mut self) -> &mut u8 { LL | | @@ -155,7 +156,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:137:5 + --> tests/ui/misnamed_getters.rs:136:5 | LL | / fn a(&self) -> &u8 { LL | | @@ -166,7 +167,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:142:5 + --> tests/ui/misnamed_getters.rs:141:5 | LL | / fn a_mut(&mut self) -> &mut u8 { LL | | @@ -177,7 +178,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:148:5 + --> tests/ui/misnamed_getters.rs:147:5 | LL | / fn d(&self) -> &u8 { LL | | @@ -188,7 +189,7 @@ LL | | } | |_____^ error: getter function appears to return the wrong field - --> tests/ui/misnamed_getters.rs:153:5 + --> tests/ui/misnamed_getters.rs:152:5 | LL | / fn d_mut(&mut self) -> &mut u8 { LL | | diff --git a/tests/ui/missing_asserts_for_indexing.fixed b/tests/ui/missing_asserts_for_indexing.fixed index ce23c45b5214..3bbafe0bba3f 100644 --- a/tests/ui/missing_asserts_for_indexing.fixed +++ b/tests/ui/missing_asserts_for_indexing.fixed @@ -29,28 +29,24 @@ fn sum_with_assert_lt(v: &[u8]) -> u8 { assert!(v.len() > 4); v[0] + v[1] + v[2] + v[3] + v[4] //~^ missing_asserts_for_indexing - } fn sum_with_assert_le(v: &[u8]) -> u8 { assert!(v.len() > 4); v[0] + v[1] + v[2] + v[3] + v[4] //~^ missing_asserts_for_indexing - } fn sum_with_incorrect_assert_len(v: &[u8]) -> u8 { assert!(v.len() > 4); v[0] + v[1] + v[2] + v[3] + v[4] //~^ missing_asserts_for_indexing - } fn sum_with_incorrect_assert_len2(v: &[u8]) -> u8 { assert!(v.len() > 4); v[0] + v[1] + v[2] + v[3] + v[4] //~^ missing_asserts_for_indexing - } // ok, don't lint for single array access @@ -103,7 +99,6 @@ fn index_different_slices_wrong_len(v1: &[u8], v2: &[u8]) { let _ = v2[5] + v2[15]; //~^ missing_asserts_for_indexing - } fn index_different_slices_one_wrong_len(v1: &[u8], v2: &[u8]) { assert!(v1.len() > 12); diff --git a/tests/ui/missing_asserts_for_indexing.rs b/tests/ui/missing_asserts_for_indexing.rs index 2d129c6b7e2c..f8ea0173c13f 100644 --- a/tests/ui/missing_asserts_for_indexing.rs +++ b/tests/ui/missing_asserts_for_indexing.rs @@ -29,28 +29,24 @@ fn sum_with_assert_lt(v: &[u8]) -> u8 { assert!(v.len() < 5); v[0] + v[1] + v[2] + v[3] + v[4] //~^ missing_asserts_for_indexing - } fn sum_with_assert_le(v: &[u8]) -> u8 { assert!(v.len() <= 5); v[0] + v[1] + v[2] + v[3] + v[4] //~^ missing_asserts_for_indexing - } fn sum_with_incorrect_assert_len(v: &[u8]) -> u8 { assert!(v.len() > 3); v[0] + v[1] + v[2] + v[3] + v[4] //~^ missing_asserts_for_indexing - } fn sum_with_incorrect_assert_len2(v: &[u8]) -> u8 { assert!(v.len() >= 4); v[0] + v[1] + v[2] + v[3] + v[4] //~^ missing_asserts_for_indexing - } // ok, don't lint for single array access @@ -103,7 +99,6 @@ fn index_different_slices_wrong_len(v1: &[u8], v2: &[u8]) { let _ = v2[5] + v2[15]; //~^ missing_asserts_for_indexing - } fn index_different_slices_one_wrong_len(v1: &[u8], v2: &[u8]) { assert!(v1.len() >= 12); diff --git a/tests/ui/missing_asserts_for_indexing.stderr b/tests/ui/missing_asserts_for_indexing.stderr index a1559d21150b..5d30920ccf52 100644 --- a/tests/ui/missing_asserts_for_indexing.stderr +++ b/tests/ui/missing_asserts_for_indexing.stderr @@ -36,7 +36,7 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]` error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:37:5 + --> tests/ui/missing_asserts_for_indexing.rs:36:5 | LL | assert!(v.len() <= 5); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` @@ -44,34 +44,34 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:37:5 + --> tests/ui/missing_asserts_for_indexing.rs:36:5 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:37:12 + --> tests/ui/missing_asserts_for_indexing.rs:36:12 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:37:19 + --> tests/ui/missing_asserts_for_indexing.rs:36:19 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:37:26 + --> tests/ui/missing_asserts_for_indexing.rs:36:26 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:37:33 + --> tests/ui/missing_asserts_for_indexing.rs:36:33 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:44:5 + --> tests/ui/missing_asserts_for_indexing.rs:42:5 | LL | assert!(v.len() > 3); | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` @@ -79,34 +79,34 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:44:5 + --> tests/ui/missing_asserts_for_indexing.rs:42:5 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:44:12 + --> tests/ui/missing_asserts_for_indexing.rs:42:12 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:44:19 + --> tests/ui/missing_asserts_for_indexing.rs:42:19 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:44:26 + --> tests/ui/missing_asserts_for_indexing.rs:42:26 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:44:33 + --> tests/ui/missing_asserts_for_indexing.rs:42:33 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:51:5 + --> tests/ui/missing_asserts_for_indexing.rs:48:5 | LL | assert!(v.len() >= 4); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` @@ -114,34 +114,34 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:51:5 + --> tests/ui/missing_asserts_for_indexing.rs:48:5 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:51:12 + --> tests/ui/missing_asserts_for_indexing.rs:48:12 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:51:19 + --> tests/ui/missing_asserts_for_indexing.rs:48:19 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:51:26 + --> tests/ui/missing_asserts_for_indexing.rs:48:26 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:51:33 + --> tests/ui/missing_asserts_for_indexing.rs:48:33 | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:70:13 + --> tests/ui/missing_asserts_for_indexing.rs:66:13 | LL | assert!(v.len() >= 3); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 3)` @@ -152,19 +152,19 @@ LL | | let _ = v[1..4]; | |___________________^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:70:13 + --> tests/ui/missing_asserts_for_indexing.rs:66:13 | LL | let _ = v[0]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:73:13 + --> tests/ui/missing_asserts_for_indexing.rs:69:13 | LL | let _ = v[1..4]; | ^^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:85:13 + --> tests/ui/missing_asserts_for_indexing.rs:81:13 | LL | assert!(v.len() >= 4); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` @@ -175,19 +175,19 @@ LL | | let _ = v[1..=4]; | |____________________^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:85:13 + --> tests/ui/missing_asserts_for_indexing.rs:81:13 | LL | let _ = v[0]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:88:13 + --> tests/ui/missing_asserts_for_indexing.rs:84:13 | LL | let _ = v[1..=4]; | ^^^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:101:13 + --> tests/ui/missing_asserts_for_indexing.rs:97:13 | LL | assert!(v1.len() >= 12); | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` @@ -196,19 +196,19 @@ LL | let _ = v1[0] + v1[12]; | ^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:101:13 + --> tests/ui/missing_asserts_for_indexing.rs:97:13 | LL | let _ = v1[0] + v1[12]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:101:21 + --> tests/ui/missing_asserts_for_indexing.rs:97:21 | LL | let _ = v1[0] + v1[12]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:104:13 + --> tests/ui/missing_asserts_for_indexing.rs:100:13 | LL | assert!(v2.len() >= 15); | ----------------------- help: provide the highest index that is indexed with: `assert!(v2.len() > 15)` @@ -217,19 +217,19 @@ LL | let _ = v2[5] + v2[15]; | ^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:104:13 + --> tests/ui/missing_asserts_for_indexing.rs:100:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:104:21 + --> tests/ui/missing_asserts_for_indexing.rs:100:21 | LL | let _ = v2[5] + v2[15]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:111:13 + --> tests/ui/missing_asserts_for_indexing.rs:106:13 | LL | assert!(v1.len() >= 12); | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` @@ -238,19 +238,19 @@ LL | let _ = v1[0] + v1[12]; | ^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:111:13 + --> tests/ui/missing_asserts_for_indexing.rs:106:13 | LL | let _ = v1[0] + v1[12]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:111:21 + --> tests/ui/missing_asserts_for_indexing.rs:106:21 | LL | let _ = v1[0] + v1[12]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:136:13 + --> tests/ui/missing_asserts_for_indexing.rs:131:13 | LL | assert!(v1.len() == 2); | ---------------------- help: provide the highest index that is indexed with: `assert!(v1.len() == 3)` @@ -259,24 +259,24 @@ LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:136:13 + --> tests/ui/missing_asserts_for_indexing.rs:131:13 | LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:136:21 + --> tests/ui/missing_asserts_for_indexing.rs:131:21 | LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:136:29 + --> tests/ui/missing_asserts_for_indexing.rs:131:29 | LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index - --> tests/ui/missing_asserts_for_indexing.rs:141:13 + --> tests/ui/missing_asserts_for_indexing.rs:136:13 | LL | assert!(2 == v3.len()); | ---------------------- help: provide the highest index that is indexed with: `assert!(v3.len() == 3)` @@ -285,17 +285,17 @@ LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^^^^^^^^^^^^^^^^^ | note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:141:13 + --> tests/ui/missing_asserts_for_indexing.rs:136:13 | LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:141:21 + --> tests/ui/missing_asserts_for_indexing.rs:136:21 | LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:141:29 + --> tests/ui/missing_asserts_for_indexing.rs:136:29 | LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ diff --git a/tests/ui/missing_asserts_for_indexing_unfixable.rs b/tests/ui/missing_asserts_for_indexing_unfixable.rs index c2083a90a19a..a520151a2dd9 100644 --- a/tests/ui/missing_asserts_for_indexing_unfixable.rs +++ b/tests/ui/missing_asserts_for_indexing_unfixable.rs @@ -4,7 +4,6 @@ fn sum(v: &[u8]) -> u8 { v[0] + v[1] + v[2] + v[3] + v[4] //~^ missing_asserts_for_indexing - } fn subslice(v: &[u8]) { @@ -45,7 +44,6 @@ struct Foo<'a> { fn index_struct_field(f: &Foo<'_>) { let _ = f.v[0] + f.v[1]; //~^ missing_asserts_for_indexing - } fn index_struct_different_fields(f: &Foo<'_>) { @@ -60,7 +58,6 @@ fn shadowing() { let x: &[i32] = &[1]; let _ = x[0] + x[1]; //~^ missing_asserts_for_indexing - } pub fn issue11856(values: &[i32]) -> usize { diff --git a/tests/ui/missing_asserts_for_indexing_unfixable.stderr b/tests/ui/missing_asserts_for_indexing_unfixable.stderr index f6557fb2e50f..24109b052a8a 100644 --- a/tests/ui/missing_asserts_for_indexing_unfixable.stderr +++ b/tests/ui/missing_asserts_for_indexing_unfixable.stderr @@ -35,7 +35,7 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]` error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:11:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:10:13 | LL | let _ = v[0]; | _____________^ @@ -45,19 +45,19 @@ LL | | let _ = v[1..4]; | = help: consider asserting the length before indexing: `assert!(v.len() > 3);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:11:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:10:13 | LL | let _ = v[0]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:14:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:13:13 | LL | let _ = v[1..4]; | ^^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:18:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:17:13 | LL | let a = v[0]; | _____________^ @@ -69,112 +69,112 @@ LL | | let c = v[2]; | = help: consider asserting the length before indexing: `assert!(v.len() > 2);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:18:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:17:13 | LL | let a = v[0]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:21:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:20:13 | LL | let b = v[1]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:22:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:21:13 | LL | let c = v[2]; | ^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:27:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:13 | LL | let _ = v1[0] + v1[12]; | ^^^^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(v1.len() > 12);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:27:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:13 | LL | let _ = v1[0] + v1[12]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:27:21 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:21 | LL | let _ = v1[0] + v1[12]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:29:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(v2.len() > 15);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:29:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:29:21 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:21 | LL | let _ = v2[5] + v2[15]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:36:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(v2.len() > 15);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:36:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:13 | LL | let _ = v2[5] + v2[15]; | ^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:36:21 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:21 | LL | let _ = v2[5] + v2[15]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:46:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:13 | LL | let _ = f.v[0] + f.v[1]; | ^^^^^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(f.v.len() > 1);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:46:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:13 | LL | let _ = f.v[0] + f.v[1]; | ^^^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:46:22 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:22 | LL | let _ = f.v[0] + f.v[1]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:61:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:13 | LL | let _ = x[0] + x[1]; | ^^^^^^^^^^^ | = help: consider asserting the length before indexing: `assert!(x.len() > 1);` note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:61:13 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:13 | LL | let _ = x[0] + x[1]; | ^^^^ note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:61:20 + --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:20 | LL | let _ = x[0] + x[1]; | ^^^^ diff --git a/tests/ui/missing_const_for_fn/could_be_const.fixed b/tests/ui/missing_const_for_fn/could_be_const.fixed index 592302c34ae6..10df44e73b85 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.fixed +++ b/tests/ui/missing_const_for_fn/could_be_const.fixed @@ -11,44 +11,44 @@ struct Game { impl Game { // Could be const pub const fn new() -> Self { - //~^ missing_const_for_fn + //~^ missing_const_for_fn Self { guess: 42 } } const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] { - //~^ missing_const_for_fn + //~^ missing_const_for_fn b } } // Could be const const fn one() -> i32 { -//~^ missing_const_for_fn + //~^ missing_const_for_fn 1 } // Could also be const const fn two() -> i32 { -//~^ missing_const_for_fn + //~^ missing_const_for_fn let abc = 2; abc } // Could be const (since Rust 1.39) const fn string() -> String { -//~^ missing_const_for_fn + //~^ missing_const_for_fn String::new() } // Could be const const unsafe fn four() -> i32 { -//~^ missing_const_for_fn + //~^ missing_const_for_fn 4 } // Could also be const const fn generic(t: T) -> T { -//~^ missing_const_for_fn + //~^ missing_const_for_fn t } @@ -57,7 +57,7 @@ fn sub(x: u32) -> usize { } const fn generic_arr(t: [T; 1]) -> T { -//~^ missing_const_for_fn + //~^ missing_const_for_fn t[0] } @@ -71,7 +71,7 @@ mod with_drop { impl B { // This can be const, because `a` is passed by reference pub const fn b(self, a: &A) -> B { - //~^ missing_const_for_fn + //~^ missing_const_for_fn B } } @@ -81,7 +81,7 @@ mod with_drop { mod const_fn_stabilized_before_msrv { // This could be const because `u8::is_ascii_digit` is a stable const function in 1.47. const fn const_fn_stabilized_before_msrv(byte: u8) { - //~^ missing_const_for_fn + //~^ missing_const_for_fn byte.is_ascii_digit(); } } @@ -93,7 +93,7 @@ fn msrv_1_45() -> i32 { #[clippy::msrv = "1.46"] const fn msrv_1_46() -> i32 { -//~^ missing_const_for_fn + //~^ missing_const_for_fn 46 } @@ -121,12 +121,12 @@ mod msrv { impl Foo { #[clippy::msrv = "1.58"] const fn deref_ptr_can_be_const(self) -> usize { - //~^ missing_const_for_fn + //~^ missing_const_for_fn unsafe { *self.0 as usize } } const fn deref_copied_val(self) -> usize { - //~^ missing_const_for_fn + //~^ missing_const_for_fn *self.1 as usize } } @@ -137,7 +137,7 @@ mod msrv { #[clippy::msrv = "1.56"] const fn union_access_can_be_const() { - //~^ missing_const_for_fn + //~^ missing_const_for_fn let bar = Bar { val: 1 }; let _ = unsafe { bar.val }; } @@ -167,13 +167,13 @@ mod issue12677 { impl Wrapper { #[must_use] pub const fn new(strings: Vec) -> Self { - //~^ missing_const_for_fn + //~^ missing_const_for_fn Self { strings } } #[must_use] pub const fn empty() -> Self { - //~^ missing_const_for_fn + //~^ missing_const_for_fn Self { strings: Vec::new() } } } @@ -185,7 +185,7 @@ mod issue12677 { impl Other { pub const fn new(text: String) -> Self { - //~^ missing_const_for_fn + //~^ missing_const_for_fn let vec = Vec::new(); Self { text, vec } } @@ -218,6 +218,6 @@ mod extern_fn { } const fn mut_add(x: &mut i32) { -//~^ missing_const_for_fn + //~^ missing_const_for_fn *x += 1; } diff --git a/tests/ui/missing_const_for_fn/could_be_const.rs b/tests/ui/missing_const_for_fn/could_be_const.rs index f689f9bb7f92..bc44b34daef7 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/tests/ui/missing_const_for_fn/could_be_const.rs @@ -11,44 +11,44 @@ struct Game { impl Game { // Could be const pub fn new() -> Self { - //~^ missing_const_for_fn + //~^ missing_const_for_fn Self { guess: 42 } } fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] { - //~^ missing_const_for_fn + //~^ missing_const_for_fn b } } // Could be const fn one() -> i32 { -//~^ missing_const_for_fn + //~^ missing_const_for_fn 1 } // Could also be const fn two() -> i32 { -//~^ missing_const_for_fn + //~^ missing_const_for_fn let abc = 2; abc } // Could be const (since Rust 1.39) fn string() -> String { -//~^ missing_const_for_fn + //~^ missing_const_for_fn String::new() } // Could be const unsafe fn four() -> i32 { -//~^ missing_const_for_fn + //~^ missing_const_for_fn 4 } // Could also be const fn generic(t: T) -> T { -//~^ missing_const_for_fn + //~^ missing_const_for_fn t } @@ -57,7 +57,7 @@ fn sub(x: u32) -> usize { } fn generic_arr(t: [T; 1]) -> T { -//~^ missing_const_for_fn + //~^ missing_const_for_fn t[0] } @@ -71,7 +71,7 @@ mod with_drop { impl B { // This can be const, because `a` is passed by reference pub fn b(self, a: &A) -> B { - //~^ missing_const_for_fn + //~^ missing_const_for_fn B } } @@ -81,7 +81,7 @@ mod with_drop { mod const_fn_stabilized_before_msrv { // This could be const because `u8::is_ascii_digit` is a stable const function in 1.47. fn const_fn_stabilized_before_msrv(byte: u8) { - //~^ missing_const_for_fn + //~^ missing_const_for_fn byte.is_ascii_digit(); } } @@ -93,7 +93,7 @@ fn msrv_1_45() -> i32 { #[clippy::msrv = "1.46"] fn msrv_1_46() -> i32 { -//~^ missing_const_for_fn + //~^ missing_const_for_fn 46 } @@ -121,12 +121,12 @@ mod msrv { impl Foo { #[clippy::msrv = "1.58"] fn deref_ptr_can_be_const(self) -> usize { - //~^ missing_const_for_fn + //~^ missing_const_for_fn unsafe { *self.0 as usize } } fn deref_copied_val(self) -> usize { - //~^ missing_const_for_fn + //~^ missing_const_for_fn *self.1 as usize } } @@ -137,7 +137,7 @@ mod msrv { #[clippy::msrv = "1.56"] fn union_access_can_be_const() { - //~^ missing_const_for_fn + //~^ missing_const_for_fn let bar = Bar { val: 1 }; let _ = unsafe { bar.val }; } @@ -167,13 +167,13 @@ mod issue12677 { impl Wrapper { #[must_use] pub fn new(strings: Vec) -> Self { - //~^ missing_const_for_fn + //~^ missing_const_for_fn Self { strings } } #[must_use] pub fn empty() -> Self { - //~^ missing_const_for_fn + //~^ missing_const_for_fn Self { strings: Vec::new() } } } @@ -185,7 +185,7 @@ mod issue12677 { impl Other { pub fn new(text: String) -> Self { - //~^ missing_const_for_fn + //~^ missing_const_for_fn let vec = Vec::new(); Self { text, vec } } @@ -218,6 +218,6 @@ mod extern_fn { } fn mut_add(x: &mut i32) { -//~^ missing_const_for_fn + //~^ missing_const_for_fn *x += 1; } diff --git a/tests/ui/missing_const_for_thread_local.fixed b/tests/ui/missing_const_for_thread_local.fixed index 281d7a6c9da3..2efe10c153da 100644 --- a/tests/ui/missing_const_for_thread_local.fixed +++ b/tests/ui/missing_const_for_thread_local.fixed @@ -9,7 +9,6 @@ fn main() { //~^ missing_const_for_thread_local } - // don't lint thread_local! { static BUF_2: RefCell = const { RefCell::new(String::new()) }; @@ -20,7 +19,6 @@ fn main() { //~^ missing_const_for_thread_local } - // lint and suggest const for all non const items thread_local! { static BUF_3_CAN_BE_MADE_CONST: RefCell = const { RefCell::new(String::new()) }; @@ -30,8 +28,6 @@ fn main() { //~^ missing_const_for_thread_local } - - thread_local! { static PEEL_ME: i32 = const { 1 }; //~^ missing_const_for_thread_local diff --git a/tests/ui/missing_const_for_thread_local.rs b/tests/ui/missing_const_for_thread_local.rs index 07239e5fa617..119cc5a99fa0 100644 --- a/tests/ui/missing_const_for_thread_local.rs +++ b/tests/ui/missing_const_for_thread_local.rs @@ -9,7 +9,6 @@ fn main() { //~^ missing_const_for_thread_local } - // don't lint thread_local! { static BUF_2: RefCell = const { RefCell::new(String::new()) }; @@ -20,7 +19,6 @@ fn main() { //~^ missing_const_for_thread_local } - // lint and suggest const for all non const items thread_local! { static BUF_3_CAN_BE_MADE_CONST: RefCell = RefCell::new(String::new()); @@ -30,8 +28,6 @@ fn main() { //~^ missing_const_for_thread_local } - - thread_local! { static PEEL_ME: i32 = { 1 }; //~^ missing_const_for_thread_local diff --git a/tests/ui/missing_const_for_thread_local.stderr b/tests/ui/missing_const_for_thread_local.stderr index 76104a3761eb..4e90c10c92f8 100644 --- a/tests/ui/missing_const_for_thread_local.stderr +++ b/tests/ui/missing_const_for_thread_local.stderr @@ -8,31 +8,31 @@ LL | static BUF_1: RefCell = RefCell::new(String::new()); = help: to override `-D warnings` add `#[allow(clippy::missing_const_for_thread_local)]` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:19:29 + --> tests/ui/missing_const_for_thread_local.rs:18:29 | LL | static SIMPLE:i32 = 1; | ^ help: replace with: `const { 1 }` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:26:59 + --> tests/ui/missing_const_for_thread_local.rs:24:59 | LL | static BUF_3_CAN_BE_MADE_CONST: RefCell = RefCell::new(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(String::new()) }` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:29:59 + --> tests/ui/missing_const_for_thread_local.rs:27:59 | LL | static BUF_4_CAN_BE_MADE_CONST: RefCell = RefCell::new(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(String::new()) }` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:36:31 + --> tests/ui/missing_const_for_thread_local.rs:32:31 | LL | static PEEL_ME: i32 = { 1 }; | ^^^^^ help: replace with: `const { 1 }` error: initializer for `thread_local` value can be made `const` - --> tests/ui/missing_const_for_thread_local.rs:39:36 + --> tests/ui/missing_const_for_thread_local.rs:35:36 | LL | static PEEL_ME_MANY: i32 = { let x = 1; x * x }; | ^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { { let x = 1; x * x } }` diff --git a/tests/ui/missing_doc.rs b/tests/ui/missing_doc.rs index 301c46e0f1b9..705de959cb7d 100644 --- a/tests/ui/missing_doc.rs +++ b/tests/ui/missing_doc.rs @@ -43,7 +43,7 @@ mod a { } enum Baz { -//~^ missing_docs_in_private_items + //~^ missing_docs_in_private_items BazA { a: isize, b: isize }, //~^ missing_docs_in_private_items //~| missing_docs_in_private_items @@ -94,7 +94,7 @@ pub static BAR3: u32 = 0; pub static BAR4: u32 = 0; mod internal_impl { -//~^ missing_docs_in_private_items + //~^ missing_docs_in_private_items /// dox pub fn documented() {} pub fn undocumented1() {} @@ -133,7 +133,7 @@ with_span!(span pub const FOO2_PM: u32 = 0;); const _: () = (); fn issue13298() { -//~^ missing_docs_in_private_items + //~^ missing_docs_in_private_items // Rustdoc doesn't generate documentation for items within other items like fns or consts const MSG: &str = "Hello, world!"; } diff --git a/tests/ui/missing_doc_crate_missing.rs b/tests/ui/missing_doc_crate_missing.rs index 70e96f4dd547..f55d8b67cb84 100644 --- a/tests/ui/missing_doc_crate_missing.rs +++ b/tests/ui/missing_doc_crate_missing.rs @@ -1,6 +1,4 @@ #![warn(clippy::missing_docs_in_private_items)] //~^ missing_docs_in_private_items - - fn main() {} diff --git a/tests/ui/missing_doc_impl.rs b/tests/ui/missing_doc_impl.rs index e2d268c4e3bd..034ce31dfe76 100644 --- a/tests/ui/missing_doc_impl.rs +++ b/tests/ui/missing_doc_impl.rs @@ -11,7 +11,7 @@ extern crate proc_macros; use proc_macros::with_span; struct Foo { -//~^ missing_docs_in_private_items + //~^ missing_docs_in_private_items a: isize, //~^ missing_docs_in_private_items b: isize, @@ -69,7 +69,7 @@ pub trait E: Sized { impl Foo { pub fn new() -> Self { - //~^ missing_docs_in_private_items + //~^ missing_docs_in_private_items Foo { a: 0, b: 0 } } fn bar() {} @@ -82,7 +82,7 @@ impl PubFoo { pub fn foo1() {} #[must_use = "yep"] fn foo2() -> u32 { - //~^ missing_docs_in_private_items + //~^ missing_docs_in_private_items 1 } #[allow(clippy::missing_docs_in_private_items)] diff --git a/tests/ui/missing_fields_in_debug.rs b/tests/ui/missing_fields_in_debug.rs index bf69eae05169..14803b5485a1 100644 --- a/tests/ui/missing_fields_in_debug.rs +++ b/tests/ui/missing_fields_in_debug.rs @@ -12,7 +12,7 @@ struct NamedStruct1Ignored { } impl fmt::Debug for NamedStruct1Ignored { -//~^ missing_fields_in_debug + //~^ missing_fields_in_debug // unused field: hidden fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -32,7 +32,7 @@ struct NamedStructMultipleIgnored { } impl fmt::Debug for NamedStructMultipleIgnored { -//~^ missing_fields_in_debug + //~^ missing_fields_in_debug // unused fields: hidden, hidden2, hidden4 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -95,7 +95,7 @@ struct MultiExprDebugImpl { // ok impl fmt::Debug for MultiExprDebugImpl { -//~^ missing_fields_in_debug + //~^ missing_fields_in_debug fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { let mut f = formatter.debug_struct("MultiExprDebugImpl"); diff --git a/tests/ui/missing_inline.rs b/tests/ui/missing_inline.rs index ec21de4ca41c..c1801005b777 100644 --- a/tests/ui/missing_inline.rs +++ b/tests/ui/missing_inline.rs @@ -20,7 +20,6 @@ fn foo() {} pub fn pub_foo() {} //~^ missing_inline_in_public_items - #[inline] pub fn pub_foo_inline() {} // ok #[inline(always)] @@ -64,7 +63,6 @@ impl PubBar for PubFoo { // missing #[inline] fn PubBar_c() {} //~^ missing_inline_in_public_items - } // do not need inline because Foo is not exported @@ -77,7 +75,6 @@ impl PubFoo { // missing #[inline] pub fn PubFooImpl() {} //~^ missing_inline_in_public_items - } // do not lint this since users cannot control the external code diff --git a/tests/ui/missing_inline.stderr b/tests/ui/missing_inline.stderr index 2ce335a696ce..99ee828e805c 100644 --- a/tests/ui/missing_inline.stderr +++ b/tests/ui/missing_inline.stderr @@ -8,31 +8,31 @@ LL | pub fn pub_foo() {} = help: to override `-D warnings` add `#[allow(clippy::missing_inline_in_public_items)]` error: missing `#[inline]` for a default trait method - --> tests/ui/missing_inline.rs:40:5 + --> tests/ui/missing_inline.rs:39:5 | LL | fn PubBar_b() {} | ^^^^^^^^^^^^^^^^ error: missing `#[inline]` for a method - --> tests/ui/missing_inline.rs:57:5 + --> tests/ui/missing_inline.rs:56:5 | LL | fn PubBar_a() {} | ^^^^^^^^^^^^^^^^ error: missing `#[inline]` for a method - --> tests/ui/missing_inline.rs:61:5 + --> tests/ui/missing_inline.rs:60:5 | LL | fn PubBar_b() {} | ^^^^^^^^^^^^^^^^ error: missing `#[inline]` for a method - --> tests/ui/missing_inline.rs:65:5 + --> tests/ui/missing_inline.rs:64:5 | LL | fn PubBar_c() {} | ^^^^^^^^^^^^^^^^ error: missing `#[inline]` for a method - --> tests/ui/missing_inline.rs:78:5 + --> tests/ui/missing_inline.rs:76:5 | LL | pub fn PubFooImpl() {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/missing_panics_doc.rs b/tests/ui/missing_panics_doc.rs index f8aeffb3d041..95e361c5d555 100644 --- a/tests/ui/missing_panics_doc.rs +++ b/tests/ui/missing_panics_doc.rs @@ -11,20 +11,20 @@ fn main() {} /// This needs to be documented pub fn unwrap() { -//~^ missing_panics_doc + //~^ missing_panics_doc let result = Err("Hi"); result.unwrap() } /// This needs to be documented pub fn panic() { -//~^ missing_panics_doc + //~^ missing_panics_doc panic!("This function panics") } /// This needs to be documented pub fn inner_body(opt: Option) { -//~^ missing_panics_doc + //~^ missing_panics_doc opt.map(|x| { if x == 10 { panic!() @@ -34,20 +34,20 @@ pub fn inner_body(opt: Option) { /// This needs to be documented pub fn unreachable_and_panic() { -//~^ missing_panics_doc + //~^ missing_panics_doc if true { unreachable!() } else { panic!() } } /// This needs to be documented pub fn assert_eq() { -//~^ missing_panics_doc + //~^ missing_panics_doc let x = 0; assert_eq!(x, 0); } /// This needs to be documented pub fn assert_ne() { -//~^ missing_panics_doc + //~^ missing_panics_doc let x = 0; assert_ne!(x, 0); } @@ -155,36 +155,36 @@ pub fn debug_assertions() { // `pub` is required, because the lint does not consider unreachable items pub mod issue10240 { pub fn option_unwrap(v: &[T]) -> &T { - //~^ missing_panics_doc + //~^ missing_panics_doc let o: Option<&T> = v.last(); o.unwrap() } pub fn option_expect(v: &[T]) -> &T { - //~^ missing_panics_doc + //~^ missing_panics_doc let o: Option<&T> = v.last(); o.expect("passed an empty thing") } pub fn result_unwrap(v: &[T]) -> &T { - //~^ missing_panics_doc + //~^ missing_panics_doc let res: Result<&T, &str> = v.last().ok_or("oh noes"); res.unwrap() } pub fn result_expect(v: &[T]) -> &T { - //~^ missing_panics_doc + //~^ missing_panics_doc let res: Result<&T, &str> = v.last().ok_or("oh noes"); res.expect("passed an empty thing") } pub fn last_unwrap(v: &[u32]) -> u32 { - //~^ missing_panics_doc + //~^ missing_panics_doc *v.last().unwrap() } pub fn last_expect(v: &[u32]) -> u32 { - //~^ missing_panics_doc + //~^ missing_panics_doc *v.last().expect("passed an empty thing") } } diff --git a/tests/ui/missing_trait_methods.rs b/tests/ui/missing_trait_methods.rs index bcca5e1ae5bd..7af186ba3322 100644 --- a/tests/ui/missing_trait_methods.rs +++ b/tests/ui/missing_trait_methods.rs @@ -22,9 +22,8 @@ struct Partial; impl A for Partial {} //~^ missing_trait_methods - impl B for Partial { -//~^ missing_trait_methods + //~^ missing_trait_methods fn required() {} diff --git a/tests/ui/missing_trait_methods.stderr b/tests/ui/missing_trait_methods.stderr index 4af7b9ae1ea9..d9fb8951ab3d 100644 --- a/tests/ui/missing_trait_methods.stderr +++ b/tests/ui/missing_trait_methods.stderr @@ -13,7 +13,7 @@ LL | fn provided() {} = help: to override `-D warnings` add `#[allow(clippy::missing_trait_methods)]` error: missing trait method provided by default: `b` - --> tests/ui/missing_trait_methods.rs:26:1 + --> tests/ui/missing_trait_methods.rs:25:1 | LL | impl B for Partial { | ^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,19 @@ LL | fn b<'a, T: AsRef<[u8]>>(a: &'a T) -> &'a [u8] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing trait method provided by default: `one` - --> tests/ui/missing_trait_methods.rs:60:1 + --> tests/ui/missing_trait_methods.rs:59:1 + | +LL | impl MissingMultiple for Partial {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: implement the method + --> tests/ui/missing_trait_methods.rs:54:5 + | +LL | fn one() {} + | ^^^^^^^^ + +error: missing trait method provided by default: `two` + --> tests/ui/missing_trait_methods.rs:59:1 | LL | impl MissingMultiple for Partial {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,11 +45,11 @@ LL | impl MissingMultiple for Partial {} help: implement the method --> tests/ui/missing_trait_methods.rs:55:5 | -LL | fn one() {} +LL | fn two() {} | ^^^^^^^^ -error: missing trait method provided by default: `two` - --> tests/ui/missing_trait_methods.rs:60:1 +error: missing trait method provided by default: `three` + --> tests/ui/missing_trait_methods.rs:59:1 | LL | impl MissingMultiple for Partial {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,18 +57,6 @@ LL | impl MissingMultiple for Partial {} help: implement the method --> tests/ui/missing_trait_methods.rs:56:5 | -LL | fn two() {} - | ^^^^^^^^ - -error: missing trait method provided by default: `three` - --> tests/ui/missing_trait_methods.rs:60:1 - | -LL | impl MissingMultiple for Partial {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: implement the method - --> tests/ui/missing_trait_methods.rs:57:5 - | LL | fn three() {} | ^^^^^^^^^^ diff --git a/tests/ui/mixed_read_write_in_expression.rs b/tests/ui/mixed_read_write_in_expression.rs index cff7996243bb..2ead166bf801 100644 --- a/tests/ui/mixed_read_write_in_expression.rs +++ b/tests/ui/mixed_read_write_in_expression.rs @@ -14,10 +14,9 @@ fn main() { } + x; //~^ mixed_read_write_in_expression - // Example from iss#277 x += { - //~^ mixed_read_write_in_expression + //~^ mixed_read_write_in_expression x = 20; 2 @@ -33,7 +32,6 @@ fn main() { let foo = Foo { a: x, //~^ mixed_read_write_in_expression - ..{ x = 6; base @@ -43,7 +41,7 @@ fn main() { let closure = || { let mut x = 0; x += { - //~^ mixed_read_write_in_expression + //~^ mixed_read_write_in_expression x = 20; 2 diff --git a/tests/ui/mixed_read_write_in_expression.stderr b/tests/ui/mixed_read_write_in_expression.stderr index ebb3e691e6b7..e34dce2bb132 100644 --- a/tests/ui/mixed_read_write_in_expression.stderr +++ b/tests/ui/mixed_read_write_in_expression.stderr @@ -13,37 +13,37 @@ LL | x = 1; = help: to override `-D warnings` add `#[allow(clippy::mixed_read_write_in_expression)]` error: unsequenced read of `x` - --> tests/ui/mixed_read_write_in_expression.rs:19:5 + --> tests/ui/mixed_read_write_in_expression.rs:18:5 | LL | x += { | ^ | note: whether read occurs before this write depends on evaluation order - --> tests/ui/mixed_read_write_in_expression.rs:22:9 + --> tests/ui/mixed_read_write_in_expression.rs:21:9 | LL | x = 20; | ^^^^^^ error: unsequenced read of `x` - --> tests/ui/mixed_read_write_in_expression.rs:34:12 + --> tests/ui/mixed_read_write_in_expression.rs:33:12 | LL | a: x, | ^ | note: whether read occurs before this write depends on evaluation order - --> tests/ui/mixed_read_write_in_expression.rs:38:13 + --> tests/ui/mixed_read_write_in_expression.rs:36:13 | LL | x = 6; | ^^^^^ error: unsequenced read of `x` - --> tests/ui/mixed_read_write_in_expression.rs:45:9 + --> tests/ui/mixed_read_write_in_expression.rs:43:9 | LL | x += { | ^ | note: whether read occurs before this write depends on evaluation order - --> tests/ui/mixed_read_write_in_expression.rs:48:13 + --> tests/ui/mixed_read_write_in_expression.rs:46:13 | LL | x = 20; | ^^^^^^ diff --git a/tests/ui/module_inception.rs b/tests/ui/module_inception.rs index f04f0c5eeeba..15b7fb877770 100644 --- a/tests/ui/module_inception.rs +++ b/tests/ui/module_inception.rs @@ -3,15 +3,14 @@ pub mod foo2 { pub mod bar2 { pub mod bar2 { - //~^ module_inception - + //~^ module_inception pub mod foo2 {} } pub mod foo2 {} } pub mod foo2 { - //~^ module_inception + //~^ module_inception pub mod bar2 {} } @@ -20,14 +19,14 @@ pub mod foo2 { mod foo { mod bar { mod bar { - //~^ module_inception + //~^ module_inception mod foo {} } mod foo {} } mod foo { - //~^ module_inception + //~^ module_inception mod bar {} } diff --git a/tests/ui/module_inception.stderr b/tests/ui/module_inception.stderr index 3aaf304ac0e5..8e7d555cebc6 100644 --- a/tests/ui/module_inception.stderr +++ b/tests/ui/module_inception.stderr @@ -2,7 +2,9 @@ error: module has the same name as its containing module --> tests/ui/module_inception.rs:5:9 | LL | / pub mod bar2 { -... | +LL | | +LL | | +LL | | pub mod foo2 {} LL | | } | |_________^ | @@ -10,7 +12,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::module_inception)]` error: module has the same name as its containing module - --> tests/ui/module_inception.rs:13:5 + --> tests/ui/module_inception.rs:12:5 | LL | / pub mod foo2 { LL | | @@ -20,7 +22,7 @@ LL | | } | |_____^ error: module has the same name as its containing module - --> tests/ui/module_inception.rs:22:9 + --> tests/ui/module_inception.rs:21:9 | LL | / mod bar { LL | | @@ -30,7 +32,7 @@ LL | | } | |_________^ error: module has the same name as its containing module - --> tests/ui/module_inception.rs:29:5 + --> tests/ui/module_inception.rs:28:5 | LL | / mod foo { LL | | diff --git a/tests/ui/module_name_repetitions.rs b/tests/ui/module_name_repetitions.rs index b45120a8d10c..2fde98d7927c 100644 --- a/tests/ui/module_name_repetitions.rs +++ b/tests/ui/module_name_repetitions.rs @@ -8,7 +8,6 @@ pub mod foo { pub fn foo_bar() {} //~^ module_name_repetitions - pub fn bar_foo() {} //~^ module_name_repetitions @@ -21,7 +20,6 @@ pub mod foo { pub struct Foo7Bar; //~^ module_name_repetitions - // Should not warn pub struct Foobar; @@ -35,7 +33,6 @@ pub mod foo { pub use error::FooError; //~^ module_name_repetitions - // FIXME: This should also warn because it creates the public path `foo::FooIter`. mod iter { pub struct FooIter; diff --git a/tests/ui/module_name_repetitions.stderr b/tests/ui/module_name_repetitions.stderr index 664a816ae5d1..9000c44a3902 100644 --- a/tests/ui/module_name_repetitions.stderr +++ b/tests/ui/module_name_repetitions.stderr @@ -8,31 +8,31 @@ LL | pub fn foo_bar() {} = help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]` error: item name ends with its containing module's name - --> tests/ui/module_name_repetitions.rs:12:12 + --> tests/ui/module_name_repetitions.rs:11:12 | LL | pub fn bar_foo() {} | ^^^^^^^ error: item name starts with its containing module's name - --> tests/ui/module_name_repetitions.rs:15:16 + --> tests/ui/module_name_repetitions.rs:14:16 | LL | pub struct FooCake; | ^^^^^^^ error: item name ends with its containing module's name - --> tests/ui/module_name_repetitions.rs:18:14 + --> tests/ui/module_name_repetitions.rs:17:14 | LL | pub enum CakeFoo {} | ^^^^^^^ error: item name starts with its containing module's name - --> tests/ui/module_name_repetitions.rs:21:16 + --> tests/ui/module_name_repetitions.rs:20:16 | LL | pub struct Foo7Bar; | ^^^^^^^ error: item name starts with its containing module's name - --> tests/ui/module_name_repetitions.rs:35:20 + --> tests/ui/module_name_repetitions.rs:33:20 | LL | pub use error::FooError; | ^^^^^^^^ diff --git a/tests/ui/modulo_arithmetic_float.rs b/tests/ui/modulo_arithmetic_float.rs index 1b622151bcc2..0e08174f686e 100644 --- a/tests/ui/modulo_arithmetic_float.rs +++ b/tests/ui/modulo_arithmetic_float.rs @@ -8,82 +8,61 @@ fn main() { -1.6 % 2.1; //~^ modulo_arithmetic - 1.6 % -2.1; //~^ modulo_arithmetic - (1.1 - 2.3) % (1.1 + 2.3); //~^ modulo_arithmetic - (1.1 + 2.3) % (1.1 - 2.3); //~^ modulo_arithmetic - - // Lint on floating point numbers let a_f16: f16 = -1.6; let mut b_f16: f16 = 2.1; a_f16 % b_f16; //~^ modulo_arithmetic - b_f16 % a_f16; //~^ modulo_arithmetic - b_f16 %= a_f16; //~^ modulo_arithmetic - - // Lint on floating point numbers let a_f32: f32 = -1.6; let mut b_f32: f32 = 2.1; a_f32 % b_f32; //~^ modulo_arithmetic - b_f32 % a_f32; //~^ modulo_arithmetic - b_f32 %= a_f32; //~^ modulo_arithmetic - - let a_f64: f64 = -1.6; let mut b_f64: f64 = 2.1; a_f64 % b_f64; //~^ modulo_arithmetic - b_f64 % a_f64; //~^ modulo_arithmetic - b_f64 %= a_f64; //~^ modulo_arithmetic - - let a_f128: f128 = -1.6; let mut b_f128: f128 = 2.1; a_f128 % b_f128; //~^ modulo_arithmetic - b_f128 % a_f128; //~^ modulo_arithmetic - b_f128 %= a_f128; //~^ modulo_arithmetic - - // No lint when both sides are const and of the same sign 1.6 % 2.1; -1.6 % -2.1; diff --git a/tests/ui/modulo_arithmetic_float.stderr b/tests/ui/modulo_arithmetic_float.stderr index 9eb9a328664b..91b5c80ce9f4 100644 --- a/tests/ui/modulo_arithmetic_float.stderr +++ b/tests/ui/modulo_arithmetic_float.stderr @@ -9,7 +9,7 @@ LL | -1.6 % 2.1; = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]` error: you are using modulo operator on constants with different signs: `1.600 % -2.100` - --> tests/ui/modulo_arithmetic_float.rs:12:5 + --> tests/ui/modulo_arithmetic_float.rs:11:5 | LL | 1.6 % -2.1; | ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | 1.6 % -2.1; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on constants with different signs: `-1.200 % 3.400` - --> tests/ui/modulo_arithmetic_float.rs:16:5 + --> tests/ui/modulo_arithmetic_float.rs:14:5 | LL | (1.1 - 2.3) % (1.1 + 2.3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | (1.1 - 2.3) % (1.1 + 2.3); = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on constants with different signs: `3.400 % -1.200` - --> tests/ui/modulo_arithmetic_float.rs:20:5 + --> tests/ui/modulo_arithmetic_float.rs:17:5 | LL | (1.1 + 2.3) % (1.1 - 2.3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | (1.1 + 2.3) % (1.1 - 2.3); = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:28:5 + --> tests/ui/modulo_arithmetic_float.rs:23:5 | LL | a_f16 % b_f16; | ^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | a_f16 % b_f16; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:32:5 + --> tests/ui/modulo_arithmetic_float.rs:26:5 | LL | b_f16 % a_f16; | ^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | b_f16 % a_f16; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:36:5 + --> tests/ui/modulo_arithmetic_float.rs:29:5 | LL | b_f16 %= a_f16; | ^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | b_f16 %= a_f16; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:44:5 + --> tests/ui/modulo_arithmetic_float.rs:35:5 | LL | a_f32 % b_f32; | ^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | a_f32 % b_f32; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:48:5 + --> tests/ui/modulo_arithmetic_float.rs:38:5 | LL | b_f32 % a_f32; | ^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | b_f32 % a_f32; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:52:5 + --> tests/ui/modulo_arithmetic_float.rs:41:5 | LL | b_f32 %= a_f32; | ^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | b_f32 %= a_f32; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:59:5 + --> tests/ui/modulo_arithmetic_float.rs:46:5 | LL | a_f64 % b_f64; | ^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | a_f64 % b_f64; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:63:5 + --> tests/ui/modulo_arithmetic_float.rs:49:5 | LL | b_f64 % a_f64; | ^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | b_f64 % a_f64; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:67:5 + --> tests/ui/modulo_arithmetic_float.rs:52:5 | LL | b_f64 %= a_f64; | ^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | b_f64 %= a_f64; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:74:5 + --> tests/ui/modulo_arithmetic_float.rs:57:5 | LL | a_f128 % b_f128; | ^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | a_f128 % b_f128; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:78:5 + --> tests/ui/modulo_arithmetic_float.rs:60:5 | LL | b_f128 % a_f128; | ^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | b_f128 % a_f128; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:82:5 + --> tests/ui/modulo_arithmetic_float.rs:63:5 | LL | b_f128 %= a_f128; | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/modulo_arithmetic_integral.rs b/tests/ui/modulo_arithmetic_integral.rs index e3a6df7c88f3..d7cd910e43cb 100644 --- a/tests/ui/modulo_arithmetic_integral.rs +++ b/tests/ui/modulo_arithmetic_integral.rs @@ -8,93 +8,68 @@ fn main() { a % b; //~^ modulo_arithmetic - b % a; //~^ modulo_arithmetic - b %= a; //~^ modulo_arithmetic - - let a_i8: i8 = 1; let mut b_i8: i8 = 2; a_i8 % b_i8; //~^ modulo_arithmetic - b_i8 %= a_i8; //~^ modulo_arithmetic - - let a_i16: i16 = 1; let mut b_i16: i16 = 2; a_i16 % b_i16; //~^ modulo_arithmetic - b_i16 %= a_i16; //~^ modulo_arithmetic - - let a_i32: i32 = 1; let mut b_i32: i32 = 2; a_i32 % b_i32; //~^ modulo_arithmetic - b_i32 %= a_i32; //~^ modulo_arithmetic - - let a_i64: i64 = 1; let mut b_i64: i64 = 2; a_i64 % b_i64; //~^ modulo_arithmetic - b_i64 %= a_i64; //~^ modulo_arithmetic - - let a_i128: i128 = 1; let mut b_i128: i128 = 2; a_i128 % b_i128; //~^ modulo_arithmetic - b_i128 %= a_i128; //~^ modulo_arithmetic - - let a_isize: isize = 1; let mut b_isize: isize = 2; a_isize % b_isize; //~^ modulo_arithmetic - b_isize %= a_isize; //~^ modulo_arithmetic - - let a = 1; let mut b = 2; a % b; //~^ modulo_arithmetic - b %= a; //~^ modulo_arithmetic - - // No lint on unsigned integral value let a_u8: u8 = 17; let b_u8: u8 = 3; diff --git a/tests/ui/modulo_arithmetic_integral.stderr b/tests/ui/modulo_arithmetic_integral.stderr index 32cf45240c1b..d1b71cdab5e4 100644 --- a/tests/ui/modulo_arithmetic_integral.stderr +++ b/tests/ui/modulo_arithmetic_integral.stderr @@ -10,7 +10,7 @@ LL | a % b; = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]` error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:12:5 + --> tests/ui/modulo_arithmetic_integral.rs:11:5 | LL | b % a; | ^^^^^ @@ -19,7 +19,7 @@ LL | b % a; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:16:5 + --> tests/ui/modulo_arithmetic_integral.rs:14:5 | LL | b %= a; | ^^^^^^ @@ -28,7 +28,7 @@ LL | b %= a; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:23:5 + --> tests/ui/modulo_arithmetic_integral.rs:19:5 | LL | a_i8 % b_i8; | ^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | a_i8 % b_i8; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:27:5 + --> tests/ui/modulo_arithmetic_integral.rs:22:5 | LL | b_i8 %= a_i8; | ^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | b_i8 %= a_i8; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:34:5 + --> tests/ui/modulo_arithmetic_integral.rs:27:5 | LL | a_i16 % b_i16; | ^^^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | a_i16 % b_i16; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:38:5 + --> tests/ui/modulo_arithmetic_integral.rs:30:5 | LL | b_i16 %= a_i16; | ^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | b_i16 %= a_i16; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:45:5 + --> tests/ui/modulo_arithmetic_integral.rs:35:5 | LL | a_i32 % b_i32; | ^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | a_i32 % b_i32; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:49:5 + --> tests/ui/modulo_arithmetic_integral.rs:38:5 | LL | b_i32 %= a_i32; | ^^^^^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | b_i32 %= a_i32; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:56:5 + --> tests/ui/modulo_arithmetic_integral.rs:43:5 | LL | a_i64 % b_i64; | ^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | a_i64 % b_i64; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:60:5 + --> tests/ui/modulo_arithmetic_integral.rs:46:5 | LL | b_i64 %= a_i64; | ^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | b_i64 %= a_i64; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:67:5 + --> tests/ui/modulo_arithmetic_integral.rs:51:5 | LL | a_i128 % b_i128; | ^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | a_i128 % b_i128; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:71:5 + --> tests/ui/modulo_arithmetic_integral.rs:54:5 | LL | b_i128 %= a_i128; | ^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | b_i128 %= a_i128; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:78:5 + --> tests/ui/modulo_arithmetic_integral.rs:59:5 | LL | a_isize % b_isize; | ^^^^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | a_isize % b_isize; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:82:5 + --> tests/ui/modulo_arithmetic_integral.rs:62:5 | LL | b_isize %= a_isize; | ^^^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | b_isize %= a_isize; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:89:5 + --> tests/ui/modulo_arithmetic_integral.rs:67:5 | LL | a % b; | ^^^^^ @@ -145,7 +145,7 @@ LL | a % b; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_integral.rs:93:5 + --> tests/ui/modulo_arithmetic_integral.rs:70:5 | LL | b %= a; | ^^^^^^ diff --git a/tests/ui/modulo_arithmetic_integral_const.rs b/tests/ui/modulo_arithmetic_integral_const.rs index ddcf4b219073..9f5fb697df0e 100644 --- a/tests/ui/modulo_arithmetic_integral_const.rs +++ b/tests/ui/modulo_arithmetic_integral_const.rs @@ -11,73 +11,54 @@ fn main() { -1 % 2; //~^ modulo_arithmetic - 1 % -2; //~^ modulo_arithmetic - (1 - 2) % (1 + 2); //~^ modulo_arithmetic - (1 + 2) % (1 - 2); //~^ modulo_arithmetic - 35 * (7 - 4 * 2) % (-500 * -600); //~^ modulo_arithmetic - - -1i8 % 2i8; //~^ modulo_arithmetic - 1i8 % -2i8; //~^ modulo_arithmetic - -1i16 % 2i16; //~^ modulo_arithmetic - 1i16 % -2i16; //~^ modulo_arithmetic - -1i32 % 2i32; //~^ modulo_arithmetic - 1i32 % -2i32; //~^ modulo_arithmetic - -1i64 % 2i64; //~^ modulo_arithmetic - 1i64 % -2i64; //~^ modulo_arithmetic - -1i128 % 2i128; //~^ modulo_arithmetic - 1i128 % -2i128; //~^ modulo_arithmetic - -1isize % 2isize; //~^ modulo_arithmetic - 1isize % -2isize; //~^ modulo_arithmetic - - // No lint when both sides are const and of the same sign 1 % 2; -1 % -2; diff --git a/tests/ui/modulo_arithmetic_integral_const.stderr b/tests/ui/modulo_arithmetic_integral_const.stderr index 49a5a2c6433a..12edee8cf425 100644 --- a/tests/ui/modulo_arithmetic_integral_const.stderr +++ b/tests/ui/modulo_arithmetic_integral_const.stderr @@ -10,7 +10,7 @@ LL | -1 % 2; = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]` error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:15:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:14:5 | LL | 1 % -2; | ^^^^^^ @@ -19,7 +19,7 @@ LL | 1 % -2; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 3` - --> tests/ui/modulo_arithmetic_integral_const.rs:19:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:17:5 | LL | (1 - 2) % (1 + 2); | ^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | (1 - 2) % (1 + 2); = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `3 % -1` - --> tests/ui/modulo_arithmetic_integral_const.rs:23:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:20:5 | LL | (1 + 2) % (1 - 2); | ^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | (1 + 2) % (1 - 2); = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-35 % 300000` - --> tests/ui/modulo_arithmetic_integral_const.rs:27:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:23:5 | LL | 35 * (7 - 4 * 2) % (-500 * -600); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | 35 * (7 - 4 * 2) % (-500 * -600); = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:32:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:26:5 | LL | -1i8 % 2i8; | ^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | -1i8 % 2i8; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:36:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:29:5 | LL | 1i8 % -2i8; | ^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | 1i8 % -2i8; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:40:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:32:5 | LL | -1i16 % 2i16; | ^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | -1i16 % 2i16; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:44:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:35:5 | LL | 1i16 % -2i16; | ^^^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | 1i16 % -2i16; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:48:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:38:5 | LL | -1i32 % 2i32; | ^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | -1i32 % 2i32; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:52:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:41:5 | LL | 1i32 % -2i32; | ^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | 1i32 % -2i32; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:56:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:44:5 | LL | -1i64 % 2i64; | ^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | -1i64 % 2i64; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:60:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:47:5 | LL | 1i64 % -2i64; | ^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | 1i64 % -2i64; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:64:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:50:5 | LL | -1i128 % 2i128; | ^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | -1i128 % 2i128; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:68:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:53:5 | LL | 1i128 % -2i128; | ^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | 1i128 % -2i128; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `-1 % 2` - --> tests/ui/modulo_arithmetic_integral_const.rs:72:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:56:5 | LL | -1isize % 2isize; | ^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | -1isize % 2isize; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on constants with different signs: `1 % -2` - --> tests/ui/modulo_arithmetic_integral_const.rs:76:5 + --> tests/ui/modulo_arithmetic_integral_const.rs:59:5 | LL | 1isize % -2isize; | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/modulo_one.rs b/tests/ui/modulo_one.rs index 6ad038e60744..63ae61059cb8 100644 --- a/tests/ui/modulo_one.rs +++ b/tests/ui/modulo_one.rs @@ -9,7 +9,6 @@ fn main() { 10 % 1; //~^ modulo_one - 10 % -1; //~^ modulo_one diff --git a/tests/ui/modulo_one.stderr b/tests/ui/modulo_one.stderr index 1eb886123d85..1c9c79d1c621 100644 --- a/tests/ui/modulo_one.stderr +++ b/tests/ui/modulo_one.stderr @@ -8,31 +8,31 @@ LL | 10 % 1; = help: to override `-D warnings` add `#[allow(clippy::modulo_one)]` error: any number modulo -1 will panic/overflow or result in 0 - --> tests/ui/modulo_one.rs:13:5 + --> tests/ui/modulo_one.rs:12:5 | LL | 10 % -1; | ^^^^^^^ error: any number modulo -1 will panic/overflow or result in 0 - --> tests/ui/modulo_one.rs:18:5 + --> tests/ui/modulo_one.rs:17:5 | LL | i32::MIN % (-1); | ^^^^^^^^^^^^^^^ error: any number modulo 1 will be 0 - --> tests/ui/modulo_one.rs:25:5 + --> tests/ui/modulo_one.rs:24:5 | LL | 2 % ONE; | ^^^^^^^ error: any number modulo -1 will panic/overflow or result in 0 - --> tests/ui/modulo_one.rs:30:5 + --> tests/ui/modulo_one.rs:29:5 | LL | 2 % NEG_ONE; | ^^^^^^^^^^^ error: any number modulo -1 will panic/overflow or result in 0 - --> tests/ui/modulo_one.rs:36:5 + --> tests/ui/modulo_one.rs:35:5 | LL | INT_MIN % NEG_ONE; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/multi_assignments.rs b/tests/ui/multi_assignments.rs index 651cdc5773de..5a0d9a7aa37c 100644 --- a/tests/ui/multi_assignments.rs +++ b/tests/ui/multi_assignments.rs @@ -4,12 +4,10 @@ fn main() { a = b = c; //~^ multi_assignments - a = b = c = d; //~^ multi_assignments //~| multi_assignments - a = b = { c }; //~^ multi_assignments @@ -18,5 +16,4 @@ fn main() { a = (b = c); //~^ multi_assignments - } diff --git a/tests/ui/multi_assignments.stderr b/tests/ui/multi_assignments.stderr index 3c5bbcdea5f3..f56489c0b4b7 100644 --- a/tests/ui/multi_assignments.stderr +++ b/tests/ui/multi_assignments.stderr @@ -8,31 +8,31 @@ LL | a = b = c; = help: to override `-D warnings` add `#[allow(clippy::multi_assignments)]` error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:8:5 + --> tests/ui/multi_assignments.rs:7:5 | LL | a = b = c = d; | ^^^^^^^^^^^^^ error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:8:9 + --> tests/ui/multi_assignments.rs:7:9 | LL | a = b = c = d; | ^^^^^^^^^ error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:13:5 + --> tests/ui/multi_assignments.rs:11:5 | LL | a = b = { c }; | ^^^^^^^^^^^^^ error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:16:5 + --> tests/ui/multi_assignments.rs:14:5 | LL | a = { b = c }; | ^^^^^^^^^^^^^ error: assignments don't nest intuitively - --> tests/ui/multi_assignments.rs:19:5 + --> tests/ui/multi_assignments.rs:17:5 | LL | a = (b = c); | ^^^^^^^^^^^ diff --git a/tests/ui/multiple_bound_locations.rs b/tests/ui/multiple_bound_locations.rs index 45524c90b7f2..95b269d8935d 100644 --- a/tests/ui/multiple_bound_locations.rs +++ b/tests/ui/multiple_bound_locations.rs @@ -2,7 +2,6 @@ fn ty(a: F) //~^ multiple_bound_locations - where F: Sized, { @@ -10,7 +9,6 @@ where fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str) //~^ multiple_bound_locations - where 'b: 'c, { @@ -18,7 +16,6 @@ where fn ty_pred() //~^ multiple_bound_locations - where for<'a> F: Send + 'a, { @@ -29,7 +26,6 @@ struct B; impl B { fn ty(a: F) //~^ multiple_bound_locations - where F: Sized, { @@ -37,7 +33,6 @@ impl B { fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str) //~^ multiple_bound_locations - where 'b: 'c, { @@ -45,7 +40,6 @@ impl B { fn ty_pred() //~^ multiple_bound_locations - where for<'a> F: Send + 'a, { diff --git a/tests/ui/multiple_bound_locations.stderr b/tests/ui/multiple_bound_locations.stderr index bccc57fe7054..22dd2e0a5524 100644 --- a/tests/ui/multiple_bound_locations.stderr +++ b/tests/ui/multiple_bound_locations.stderr @@ -11,7 +11,7 @@ LL | F: Sized, = help: to override `-D warnings` add `#[allow(clippy::multiple_bound_locations)]` error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:11:17 + --> tests/ui/multiple_bound_locations.rs:10:17 | LL | fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str) | ^^ @@ -20,7 +20,7 @@ LL | 'b: 'c, | ^^ error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:19:12 + --> tests/ui/multiple_bound_locations.rs:17:12 | LL | fn ty_pred() | ^ @@ -29,7 +29,7 @@ LL | for<'a> F: Send + 'a, | ^ error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:30:11 + --> tests/ui/multiple_bound_locations.rs:27:11 | LL | fn ty(a: F) | ^ @@ -38,7 +38,7 @@ LL | F: Sized, | ^ error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:38:21 + --> tests/ui/multiple_bound_locations.rs:34:21 | LL | fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str) | ^^ @@ -47,7 +47,7 @@ LL | 'b: 'c, | ^^ error: bound is defined in more than one place - --> tests/ui/multiple_bound_locations.rs:46:16 + --> tests/ui/multiple_bound_locations.rs:41:16 | LL | fn ty_pred() | ^ diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index cc5d455f78cf..016fd89a7b7a 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -36,7 +36,7 @@ static mut STATIC: i32 = 0; fn test1() { unsafe { - //~^ multiple_unsafe_ops_per_block + //~^ multiple_unsafe_ops_per_block STATIC += 1; not_very_safe(); } @@ -46,7 +46,7 @@ fn test2() { let u = U { i: 0 }; unsafe { - //~^ multiple_unsafe_ops_per_block + //~^ multiple_unsafe_ops_per_block drop(u.u); *raw_ptr(); } @@ -54,7 +54,7 @@ fn test2() { fn test3() { unsafe { - //~^ multiple_unsafe_ops_per_block + //~^ multiple_unsafe_ops_per_block asm!("nop"); sample.not_very_safe(); STATIC = 0; @@ -64,7 +64,7 @@ fn test3() { fn test_all() { let u = U { i: 0 }; unsafe { - //~^ multiple_unsafe_ops_per_block + //~^ multiple_unsafe_ops_per_block drop(u.u); drop(STATIC); sample.not_very_safe(); @@ -128,7 +128,7 @@ fn issue10259() { fn _fn_ptr(x: unsafe fn()) { unsafe { - //~^ multiple_unsafe_ops_per_block + //~^ multiple_unsafe_ops_per_block x(); x(); } @@ -140,7 +140,7 @@ fn _assoc_const() { } fn _f() { unsafe { - //~^ multiple_unsafe_ops_per_block + //~^ multiple_unsafe_ops_per_block T::X(); T::X(); } @@ -151,7 +151,7 @@ fn _field_fn_ptr(x: unsafe fn()) { struct X(unsafe fn()); let x = X(x); unsafe { - //~^ multiple_unsafe_ops_per_block + //~^ multiple_unsafe_ops_per_block x.0(); x.0(); } diff --git a/tests/ui/must_use_candidates.fixed b/tests/ui/must_use_candidates.fixed index 7c70c7f6399f..b5d356a50217 100644 --- a/tests/ui/must_use_candidates.fixed +++ b/tests/ui/must_use_candidates.fixed @@ -14,13 +14,13 @@ pub struct MyAtomic(AtomicBool); pub struct MyPure; #[must_use] pub fn pure(i: u8) -> u8 { -//~^ must_use_candidate + //~^ must_use_candidate i } impl MyPure { #[must_use] pub fn inherent_pure(&self) -> u8 { - //~^ must_use_candidate + //~^ must_use_candidate 0 } } @@ -52,7 +52,7 @@ pub fn with_callback bool>(f: &F) -> bool { } #[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool { -//~^ must_use_candidate + //~^ must_use_candidate true } @@ -65,7 +65,7 @@ pub fn atomics(b: &AtomicBool) -> bool { } #[must_use] pub fn rcd(_x: Rc) -> bool { -//~^ must_use_candidate + //~^ must_use_candidate true } @@ -74,7 +74,7 @@ pub fn rcmut(_x: Rc<&mut u32>) -> bool { } #[must_use] pub fn arcd(_x: Arc) -> bool { -//~^ must_use_candidate + //~^ must_use_candidate false } diff --git a/tests/ui/must_use_candidates.rs b/tests/ui/must_use_candidates.rs index a422e952dbcd..14ea16662fdb 100644 --- a/tests/ui/must_use_candidates.rs +++ b/tests/ui/must_use_candidates.rs @@ -14,13 +14,13 @@ pub struct MyAtomic(AtomicBool); pub struct MyPure; pub fn pure(i: u8) -> u8 { -//~^ must_use_candidate + //~^ must_use_candidate i } impl MyPure { pub fn inherent_pure(&self) -> u8 { - //~^ must_use_candidate + //~^ must_use_candidate 0 } } @@ -52,7 +52,7 @@ pub fn with_callback bool>(f: &F) -> bool { } pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool { -//~^ must_use_candidate + //~^ must_use_candidate true } @@ -65,7 +65,7 @@ pub fn atomics(b: &AtomicBool) -> bool { } pub fn rcd(_x: Rc) -> bool { -//~^ must_use_candidate + //~^ must_use_candidate true } @@ -74,7 +74,7 @@ pub fn rcmut(_x: Rc<&mut u32>) -> bool { } pub fn arcd(_x: Arc) -> bool { -//~^ must_use_candidate + //~^ must_use_candidate false } diff --git a/tests/ui/mut_from_ref.rs b/tests/ui/mut_from_ref.rs index d2d82135d641..b8c10f3eeb8f 100644 --- a/tests/ui/mut_from_ref.rs +++ b/tests/ui/mut_from_ref.rs @@ -5,7 +5,7 @@ struct Foo; impl Foo { fn this_wont_hurt_a_bit(&self) -> &mut Foo { - //~^ mut_from_ref + //~^ mut_from_ref unsafe { unimplemented!() } } @@ -14,7 +14,6 @@ impl Foo { trait Ouch { fn ouch(x: &Foo) -> &mut Foo; //~^ mut_from_ref - } impl Ouch for Foo { @@ -24,19 +23,19 @@ impl Ouch for Foo { } fn fail(x: &u32) -> &mut u16 { -//~^ mut_from_ref + //~^ mut_from_ref unsafe { unimplemented!() } } fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 { -//~^ mut_from_ref + //~^ mut_from_ref unsafe { unimplemented!() } } fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 { -//~^ mut_from_ref + //~^ mut_from_ref unsafe { unimplemented!() } } @@ -52,7 +51,7 @@ fn also_works<'a>(x: &'a u32, y: &'a mut u32) -> &'a mut u32 { } unsafe fn also_broken(x: &u32) -> &mut u32 { -//~^ mut_from_ref + //~^ mut_from_ref unimplemented!() } diff --git a/tests/ui/mut_from_ref.stderr b/tests/ui/mut_from_ref.stderr index 593e7acdaed8..8c3c8e0c3d85 100644 --- a/tests/ui/mut_from_ref.stderr +++ b/tests/ui/mut_from_ref.stderr @@ -25,49 +25,49 @@ LL | fn ouch(x: &Foo) -> &mut Foo; | ^^^^ error: mutable borrow from immutable input(s) - --> tests/ui/mut_from_ref.rs:26:21 + --> tests/ui/mut_from_ref.rs:25:21 | LL | fn fail(x: &u32) -> &mut u16 { | ^^^^^^^^ | note: immutable borrow here - --> tests/ui/mut_from_ref.rs:26:12 + --> tests/ui/mut_from_ref.rs:25:12 | LL | fn fail(x: &u32) -> &mut u16 { | ^^^^ error: mutable borrow from immutable input(s) - --> tests/ui/mut_from_ref.rs:32:50 + --> tests/ui/mut_from_ref.rs:31:50 | LL | fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 { | ^^^^^^^^^^^ | note: immutable borrow here - --> tests/ui/mut_from_ref.rs:32:25 + --> tests/ui/mut_from_ref.rs:31:25 | LL | fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 { | ^^^^^^^ error: mutable borrow from immutable input(s) - --> tests/ui/mut_from_ref.rs:38:67 + --> tests/ui/mut_from_ref.rs:37:67 | LL | fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 { | ^^^^^^^^^^^ | note: immutable borrow here - --> tests/ui/mut_from_ref.rs:38:27 + --> tests/ui/mut_from_ref.rs:37:27 | LL | fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 { | ^^^^^^^ ^^^^^^^ error: mutable borrow from immutable input(s) - --> tests/ui/mut_from_ref.rs:54:35 + --> tests/ui/mut_from_ref.rs:53:35 | LL | unsafe fn also_broken(x: &u32) -> &mut u32 { | ^^^^^^^^ | note: immutable borrow here - --> tests/ui/mut_from_ref.rs:54:26 + --> tests/ui/mut_from_ref.rs:53:26 | LL | unsafe fn also_broken(x: &u32) -> &mut u32 { | ^^^^ diff --git a/tests/ui/mut_key.rs b/tests/ui/mut_key.rs index 55b7fe2bcca0..29dc2d020132 100644 --- a/tests/ui/mut_key.rs +++ b/tests/ui/mut_key.rs @@ -29,10 +29,8 @@ impl Hash for Key { } fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> HashSet { -//~^ mutable_key_type -//~| mutable_key_type - - + //~^ mutable_key_type + //~| mutable_key_type let _other: HashMap = HashMap::new(); //~^ mutable_key_type @@ -66,7 +64,6 @@ fn tuples(_m: &mut HashMap<((), U), ()>) {} fn tuples_bad(_m: &mut HashMap<(Key, U), bool>) {} //~^ mutable_key_type - fn main() { let _ = should_not_take_this_arg(&mut HashMap::new(), 1); this_is_ok(&mut HashMap::new()); @@ -112,7 +109,6 @@ fn main() { let _map = HashMap::>, usize>::new(); //~^ mutable_key_type - // Not interior mutability let _map = HashMap::<&mut usize, usize>::new(); let _map = HashMap::, usize>::new(); diff --git a/tests/ui/mut_key.stderr b/tests/ui/mut_key.stderr index 1887604b080a..0d504584fbae 100644 --- a/tests/ui/mut_key.stderr +++ b/tests/ui/mut_key.stderr @@ -21,7 +21,7 @@ LL | fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> Hash = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:37:5 + --> tests/ui/mut_key.rs:35:5 | LL | let _other: HashMap = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | let _other: HashMap = HashMap::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:66:22 + --> tests/ui/mut_key.rs:64:22 | LL | fn tuples_bad(_m: &mut HashMap<(Key, U), bool>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | fn tuples_bad(_m: &mut HashMap<(Key, U), bool>) {} = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:80:5 + --> tests/ui/mut_key.rs:77:5 | LL | let _map = HashMap::, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | let _map = HashMap::, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:83:5 + --> tests/ui/mut_key.rs:80:5 | LL | let _map = HashMap::<&mut Cell, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | let _map = HashMap::<&mut Cell, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:87:5 + --> tests/ui/mut_key.rs:84:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:90:5 + --> tests/ui/mut_key.rs:87:5 | LL | let _map = HashMap::, ()>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | let _map = HashMap::, ()>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:93:5 + --> tests/ui/mut_key.rs:90:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:96:5 + --> tests/ui/mut_key.rs:93:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -101,7 +101,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:99:5 + --> tests/ui/mut_key.rs:96:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:102:5 + --> tests/ui/mut_key.rs:99:5 | LL | let _map = HashMap::>>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let _map = HashMap::>>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:106:5 + --> tests/ui/mut_key.rs:103:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:109:5 + --> tests/ui/mut_key.rs:106:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL | let _map = HashMap::>, usize>::new(); = note: ... because it contains `UnsafeCell`, which has interior mutability error: mutable key type - --> tests/ui/mut_key.rs:112:5 + --> tests/ui/mut_key.rs:109:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/mut_mut.rs b/tests/ui/mut_mut.rs index 47f52621794b..bbcdbc89b6a4 100644 --- a/tests/ui/mut_mut.rs +++ b/tests/ui/mut_mut.rs @@ -13,7 +13,7 @@ extern crate proc_macros; use proc_macros::{external, inline_macros}; fn fun(x: &mut &mut u32) -> bool { -//~^ mut_mut + //~^ mut_mut **x > 0 } diff --git a/tests/ui/mut_range_bound.rs b/tests/ui/mut_range_bound.rs index 326afb42ccb2..107a6229b86d 100644 --- a/tests/ui/mut_range_bound.rs +++ b/tests/ui/mut_range_bound.rs @@ -7,8 +7,6 @@ fn mut_range_bound_upper() { for i in 0..m { m = 5; //~^ mut_range_bound - - } } @@ -17,8 +15,6 @@ fn mut_range_bound_lower() { for i in m..10 { m *= 2; //~^ mut_range_bound - - } } @@ -29,11 +25,8 @@ fn mut_range_bound_both() { m = 5; //~^ mut_range_bound - n = 7; //~^ mut_range_bound - - } } @@ -50,7 +43,6 @@ fn mut_borrow_range_bound() { let n = &mut m; //~^ mut_range_bound - *n += 1; } } @@ -86,7 +78,6 @@ fn mut_range_bound_no_immediate_break() { m = 2; //~^ mut_range_bound - if m == 4 { break; } @@ -99,7 +90,6 @@ fn mut_range_bound_no_immediate_break() { n = 1; //~^ mut_range_bound - let _ = 2; break; } diff --git a/tests/ui/mut_range_bound.stderr b/tests/ui/mut_range_bound.stderr index 3dbc70f87f0f..3aae6e2dca6d 100644 --- a/tests/ui/mut_range_bound.stderr +++ b/tests/ui/mut_range_bound.stderr @@ -9,7 +9,7 @@ LL | m = 5; = help: to override `-D warnings` add `#[allow(clippy::mut_range_bound)]` error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:18:9 + --> tests/ui/mut_range_bound.rs:16:9 | LL | m *= 2; | ^ @@ -17,7 +17,7 @@ LL | m *= 2; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:29:9 + --> tests/ui/mut_range_bound.rs:25:9 | LL | m = 5; | ^ @@ -25,7 +25,7 @@ LL | m = 5; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:33:9 + --> tests/ui/mut_range_bound.rs:28:9 | LL | n = 7; | ^ @@ -33,7 +33,7 @@ LL | n = 7; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:50:22 + --> tests/ui/mut_range_bound.rs:43:22 | LL | let n = &mut m; | ^ @@ -41,7 +41,7 @@ LL | let n = &mut m; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:86:9 + --> tests/ui/mut_range_bound.rs:78:9 | LL | m = 2; | ^ @@ -49,7 +49,7 @@ LL | m = 2; = note: the range of the loop is unchanged error: attempt to mutate range bound within loop - --> tests/ui/mut_range_bound.rs:99:13 + --> tests/ui/mut_range_bound.rs:90:13 | LL | n = 1; | ^ diff --git a/tests/ui/mut_reference.rs b/tests/ui/mut_reference.rs index 4ae57940cf2d..f664c373cdc3 100644 --- a/tests/ui/mut_reference.rs +++ b/tests/ui/mut_reference.rs @@ -30,18 +30,15 @@ fn main() { takes_an_immutable_reference(&mut 42); //~^ unnecessary_mut_passed - let as_ptr: fn(&i32) = takes_an_immutable_reference; as_ptr(&mut 42); //~^ unnecessary_mut_passed - // Methods let my_struct = MyStruct; my_struct.takes_an_immutable_reference(&mut 42); //~^ unnecessary_mut_passed - // No error // Functions diff --git a/tests/ui/mut_reference.stderr b/tests/ui/mut_reference.stderr index fb489360a1a3..474221329c25 100644 --- a/tests/ui/mut_reference.stderr +++ b/tests/ui/mut_reference.stderr @@ -8,13 +8,13 @@ LL | takes_an_immutable_reference(&mut 42); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_mut_passed)]` error: the function `as_ptr` doesn't need a mutable reference - --> tests/ui/mut_reference.rs:35:12 + --> tests/ui/mut_reference.rs:34:12 | LL | as_ptr(&mut 42); | ^^^^^^^ error: the method `takes_an_immutable_reference` doesn't need a mutable reference - --> tests/ui/mut_reference.rs:41:44 + --> tests/ui/mut_reference.rs:39:44 | LL | my_struct.takes_an_immutable_reference(&mut 42); | ^^^^^^^ diff --git a/tests/ui/mutex_atomic.rs b/tests/ui/mutex_atomic.rs index 993ea880d66b..80a712a9286a 100644 --- a/tests/ui/mutex_atomic.rs +++ b/tests/ui/mutex_atomic.rs @@ -8,7 +8,6 @@ fn main() { Mutex::new(true); //~^ mutex_atomic - Mutex::new(5usize); //~^ mutex_atomic @@ -25,7 +24,6 @@ fn main() { Mutex::new(0u32); //~^ mutex_integer - Mutex::new(0i32); //~^ mutex_integer @@ -43,7 +41,6 @@ fn main() { Mutex::new(X); //~^ mutex_integer - // there are no 128 atomics, so these two should not lint { Mutex::new(0u128); diff --git a/tests/ui/mutex_atomic.stderr b/tests/ui/mutex_atomic.stderr index 83be2ef995ce..838fc1d7c36e 100644 --- a/tests/ui/mutex_atomic.stderr +++ b/tests/ui/mutex_atomic.stderr @@ -8,31 +8,31 @@ LL | Mutex::new(true); = help: to override `-D warnings` add `#[allow(clippy::mutex_atomic)]` error: consider using an `AtomicUsize` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:12:5 + --> tests/ui/mutex_atomic.rs:11:5 | LL | Mutex::new(5usize); | ^^^^^^^^^^^^^^^^^^ error: consider using an `AtomicIsize` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:15:5 + --> tests/ui/mutex_atomic.rs:14:5 | LL | Mutex::new(9isize); | ^^^^^^^^^^^^^^^^^^ error: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:19:5 + --> tests/ui/mutex_atomic.rs:18:5 | LL | Mutex::new(&x as *const u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:22:5 + --> tests/ui/mutex_atomic.rs:21:5 | LL | Mutex::new(&mut x as *mut u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: consider using an `AtomicU32` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:25:5 + --> tests/ui/mutex_atomic.rs:24:5 | LL | Mutex::new(0u32); | ^^^^^^^^^^^^^^^^ @@ -41,31 +41,31 @@ LL | Mutex::new(0u32); = help: to override `-D warnings` add `#[allow(clippy::mutex_integer)]` error: consider using an `AtomicI32` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:29:5 + --> tests/ui/mutex_atomic.rs:27:5 | LL | Mutex::new(0i32); | ^^^^^^^^^^^^^^^^ error: consider using an `AtomicU8` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:33:5 + --> tests/ui/mutex_atomic.rs:31:5 | LL | Mutex::new(0u8); | ^^^^^^^^^^^^^^^ error: consider using an `AtomicI16` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:36:5 + --> tests/ui/mutex_atomic.rs:34:5 | LL | Mutex::new(0i16); | ^^^^^^^^^^^^^^^^ error: consider using an `AtomicI8` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:39:25 + --> tests/ui/mutex_atomic.rs:37:25 | LL | let _x: Mutex = Mutex::new(0); | ^^^^^^^^^^^^^ error: consider using an `AtomicI64` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>` - --> tests/ui/mutex_atomic.rs:43:5 + --> tests/ui/mutex_atomic.rs:41:5 | LL | Mutex::new(X); | ^^^^^^^^^^^^^ diff --git a/tests/ui/needless_arbitrary_self_type.fixed b/tests/ui/needless_arbitrary_self_type.fixed index 22dd127f01f3..adb9096c9f24 100644 --- a/tests/ui/needless_arbitrary_self_type.fixed +++ b/tests/ui/needless_arbitrary_self_type.fixed @@ -8,7 +8,7 @@ pub enum ValType { impl ValType { pub fn bad(self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -17,7 +17,7 @@ impl ValType { } pub fn mut_bad(mut self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -26,7 +26,7 @@ impl ValType { } pub fn ref_bad(&self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -35,7 +35,7 @@ impl ValType { } pub fn ref_bad_with_lifetime<'a>(&'a self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -44,7 +44,7 @@ impl ValType { } pub fn mut_ref_bad(&mut self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -53,7 +53,7 @@ impl ValType { } pub fn mut_ref_bad_with_lifetime<'a>(&'a mut self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } diff --git a/tests/ui/needless_arbitrary_self_type.rs b/tests/ui/needless_arbitrary_self_type.rs index 5b1702bfdf96..550546ed24fd 100644 --- a/tests/ui/needless_arbitrary_self_type.rs +++ b/tests/ui/needless_arbitrary_self_type.rs @@ -8,7 +8,7 @@ pub enum ValType { impl ValType { pub fn bad(self: Self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -17,7 +17,7 @@ impl ValType { } pub fn mut_bad(mut self: Self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -26,7 +26,7 @@ impl ValType { } pub fn ref_bad(self: &Self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -35,7 +35,7 @@ impl ValType { } pub fn ref_bad_with_lifetime<'a>(self: &'a Self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -44,7 +44,7 @@ impl ValType { } pub fn mut_ref_bad(self: &mut Self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } @@ -53,7 +53,7 @@ impl ValType { } pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) { - //~^ needless_arbitrary_self_type + //~^ needless_arbitrary_self_type unimplemented!(); } diff --git a/tests/ui/needless_as_bytes.fixed b/tests/ui/needless_as_bytes.fixed index 2f9e82218889..9cbc7b9c2651 100644 --- a/tests/ui/needless_as_bytes.fixed +++ b/tests/ui/needless_as_bytes.fixed @@ -15,34 +15,30 @@ impl S { fn main() { if "some string".is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes println!("len = {}", "some string".len()); //~^ needless_as_bytes - } if "some string".is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes println!("len = {}", "some string".len()); //~^ needless_as_bytes - } let s = String::from("yet another string"); if s.is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes println!("len = {}", s.len()); //~^ needless_as_bytes - } if s.is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes println!("len = {}", s.len()); //~^ needless_as_bytes - } // Do not lint diff --git a/tests/ui/needless_as_bytes.rs b/tests/ui/needless_as_bytes.rs index 2f0fc352d192..7de699647e85 100644 --- a/tests/ui/needless_as_bytes.rs +++ b/tests/ui/needless_as_bytes.rs @@ -15,34 +15,30 @@ impl S { fn main() { if "some string".as_bytes().is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes println!("len = {}", "some string".as_bytes().len()); //~^ needless_as_bytes - } if "some string".bytes().is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes println!("len = {}", "some string".bytes().len()); //~^ needless_as_bytes - } let s = String::from("yet another string"); if s.as_bytes().is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes println!("len = {}", s.as_bytes().len()); //~^ needless_as_bytes - } if s.bytes().is_empty() { - //~^ needless_as_bytes + //~^ needless_as_bytes println!("len = {}", s.bytes().len()); //~^ needless_as_bytes - } // Do not lint diff --git a/tests/ui/needless_as_bytes.stderr b/tests/ui/needless_as_bytes.stderr index 72746c05b8e2..0eead9815f8a 100644 --- a/tests/ui/needless_as_bytes.stderr +++ b/tests/ui/needless_as_bytes.stderr @@ -14,37 +14,37 @@ LL | println!("len = {}", "some string".as_bytes().len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()` error: needless call to `bytes` - --> tests/ui/needless_as_bytes.rs:24:8 + --> tests/ui/needless_as_bytes.rs:23:8 | LL | if "some string".bytes().is_empty() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `"some string".is_empty()` error: needless call to `bytes` - --> tests/ui/needless_as_bytes.rs:27:30 + --> tests/ui/needless_as_bytes.rs:26:30 | LL | println!("len = {}", "some string".bytes().len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()` error: needless call to `as_bytes` - --> tests/ui/needless_as_bytes.rs:33:8 + --> tests/ui/needless_as_bytes.rs:31:8 | LL | if s.as_bytes().is_empty() { | ^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()` error: needless call to `as_bytes` - --> tests/ui/needless_as_bytes.rs:36:30 + --> tests/ui/needless_as_bytes.rs:34:30 | LL | println!("len = {}", s.as_bytes().len()); | ^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()` error: needless call to `bytes` - --> tests/ui/needless_as_bytes.rs:40:8 + --> tests/ui/needless_as_bytes.rs:37:8 | LL | if s.bytes().is_empty() { | ^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()` error: needless call to `bytes` - --> tests/ui/needless_as_bytes.rs:43:30 + --> tests/ui/needless_as_bytes.rs:40:30 | LL | println!("len = {}", s.bytes().len()); | ^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()` diff --git a/tests/ui/needless_bitwise_bool.fixed b/tests/ui/needless_bitwise_bool.fixed index 7fc36e0f94b4..89a3c1474f25 100644 --- a/tests/ui/needless_bitwise_bool.fixed +++ b/tests/ui/needless_bitwise_bool.fixed @@ -21,7 +21,7 @@ fn main() { println!("true") } if y && !x { - //~^ needless_bitwise_bool + //~^ needless_bitwise_bool println!("true") } diff --git a/tests/ui/needless_bitwise_bool.rs b/tests/ui/needless_bitwise_bool.rs index dcbc08334a77..f5aa7a9f3d9e 100644 --- a/tests/ui/needless_bitwise_bool.rs +++ b/tests/ui/needless_bitwise_bool.rs @@ -21,7 +21,7 @@ fn main() { println!("true") } if y & !x { - //~^ needless_bitwise_bool + //~^ needless_bitwise_bool println!("true") } diff --git a/tests/ui/needless_borrow_pat.fixed b/tests/ui/needless_borrow_pat.fixed index d067f1c6016b..fe966a716df7 100644 --- a/tests/ui/needless_borrow_pat.fixed +++ b/tests/ui/needless_borrow_pat.fixed @@ -58,8 +58,6 @@ fn main() { let _: &String = match Some(&x) { Some(x) => x, //~^ needless_borrow - - None => return, }; @@ -67,14 +65,13 @@ fn main() { let _: &String = match Some(&x) { Some(x) => x, //~^ needless_borrow - None => return, }; // Err, reference to a &String let _: &String = match Some(&x) { Some(x) => { - //~^ needless_borrow + //~^ needless_borrow f1(x); f1(x); @@ -87,13 +84,12 @@ fn main() { match Some(&x) { Some(x) => m1!(x), //~^ needless_borrow - None => return, }; // Err, reference to a &String let _ = |&x: &&String| { - //~^ needless_borrow + //~^ needless_borrow let _: &String = x; }; @@ -113,7 +109,6 @@ fn main() { let _: u32 = match Some(&x) { Some(x) => x.0, //~^ needless_borrow - None => return, }; @@ -125,7 +120,6 @@ fn main() { let _: &u32 = match E::A(&0) { E::A(x) | E::B(x) => x, //~^ needless_borrow - }; // Err, reference to &String. @@ -142,7 +136,7 @@ fn main() { // Err, reference to a &String fn f2<'a>(&x: &&'a String) -> &'a String { -//~^ needless_borrow + //~^ needless_borrow let _: &String = x; x @@ -151,7 +145,7 @@ fn f2<'a>(&x: &&'a String) -> &'a String { trait T1 { // Err, reference to a &String fn f(&x: &&String) { - //~^ needless_borrow + //~^ needless_borrow let _: &String = x; } @@ -161,7 +155,7 @@ struct S; impl T1 for S { // Err, reference to a &String fn f(&x: &&String) { - //~^ needless_borrow + //~^ needless_borrow let _: &String = x; } diff --git a/tests/ui/needless_borrow_pat.rs b/tests/ui/needless_borrow_pat.rs index 7c39183d7916..a6b43855cad1 100644 --- a/tests/ui/needless_borrow_pat.rs +++ b/tests/ui/needless_borrow_pat.rs @@ -58,8 +58,6 @@ fn main() { let _: &String = match Some(&x) { Some(ref x) => x, //~^ needless_borrow - - None => return, }; @@ -67,14 +65,13 @@ fn main() { let _: &String = match Some(&x) { Some(ref x) => *x, //~^ needless_borrow - None => return, }; // Err, reference to a &String let _: &String = match Some(&x) { Some(ref x) => { - //~^ needless_borrow + //~^ needless_borrow f1(x); f1(*x); @@ -87,13 +84,12 @@ fn main() { match Some(&x) { Some(ref x) => m1!(x), //~^ needless_borrow - None => return, }; // Err, reference to a &String let _ = |&ref x: &&String| { - //~^ needless_borrow + //~^ needless_borrow let _: &String = x; }; @@ -113,7 +109,6 @@ fn main() { let _: u32 = match Some(&x) { Some(ref x) => x.0, //~^ needless_borrow - None => return, }; @@ -125,7 +120,6 @@ fn main() { let _: &u32 = match E::A(&0) { E::A(ref x) | E::B(ref x) => *x, //~^ needless_borrow - }; // Err, reference to &String. @@ -142,7 +136,7 @@ fn main() { // Err, reference to a &String fn f2<'a>(&ref x: &&'a String) -> &'a String { -//~^ needless_borrow + //~^ needless_borrow let _: &String = x; *x @@ -151,7 +145,7 @@ fn f2<'a>(&ref x: &&'a String) -> &'a String { trait T1 { // Err, reference to a &String fn f(&ref x: &&String) { - //~^ needless_borrow + //~^ needless_borrow let _: &String = x; } @@ -161,7 +155,7 @@ struct S; impl T1 for S { // Err, reference to a &String fn f(&ref x: &&String) { - //~^ needless_borrow + //~^ needless_borrow let _: &String = *x; } diff --git a/tests/ui/needless_borrow_pat.stderr b/tests/ui/needless_borrow_pat.stderr index 7e1b3694e30f..018e74a4f11d 100644 --- a/tests/ui/needless_borrow_pat.stderr +++ b/tests/ui/needless_borrow_pat.stderr @@ -8,7 +8,7 @@ LL | Some(ref x) => x, = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:68:14 + --> tests/ui/needless_borrow_pat.rs:66:14 | LL | Some(ref x) => *x, | ^^^^^ @@ -19,7 +19,7 @@ LL | Some(x) => x, | ~ ~ error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:76:14 + --> tests/ui/needless_borrow_pat.rs:73:14 | LL | Some(ref x) => { | ^^^^^ @@ -34,19 +34,19 @@ LL ~ f1(x); | error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:88:14 + --> tests/ui/needless_borrow_pat.rs:85:14 | LL | Some(ref x) => m1!(x), | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:95:15 + --> tests/ui/needless_borrow_pat.rs:91:15 | LL | let _ = |&ref x: &&String| { | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:102:10 + --> tests/ui/needless_borrow_pat.rs:98:10 | LL | let (ref y,) = (&x,); | ^^^^^ @@ -60,13 +60,13 @@ LL ~ let _: &String = y; | error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:114:14 + --> tests/ui/needless_borrow_pat.rs:110:14 | LL | Some(ref x) => x.0, | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:126:14 + --> tests/ui/needless_borrow_pat.rs:121:14 | LL | E::A(ref x) | E::B(ref x) => *x, | ^^^^^ ^^^^^ @@ -77,13 +77,13 @@ LL | E::A(x) | E::B(x) => x, | ~ ~ ~ error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:134:21 + --> tests/ui/needless_borrow_pat.rs:128:21 | LL | if let Some(ref x) = Some(&String::new()); | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:144:12 + --> tests/ui/needless_borrow_pat.rs:138:12 | LL | fn f2<'a>(&ref x: &&'a String) -> &'a String { | ^^^^^ @@ -98,13 +98,13 @@ LL ~ x | error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:153:11 + --> tests/ui/needless_borrow_pat.rs:147:11 | LL | fn f(&ref x: &&String) { | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference - --> tests/ui/needless_borrow_pat.rs:163:11 + --> tests/ui/needless_borrow_pat.rs:157:11 | LL | fn f(&ref x: &&String) { | ^^^^^ diff --git a/tests/ui/needless_borrowed_ref.fixed b/tests/ui/needless_borrowed_ref.fixed index 1cad115e96d1..e4504bc2784c 100644 --- a/tests/ui/needless_borrowed_ref.fixed +++ b/tests/ui/needless_borrowed_ref.fixed @@ -69,7 +69,7 @@ fn should_lint( //~^ needless_borrowed_reference if let Struct { - //~^ needless_borrowed_reference + //~^ needless_borrowed_reference a, b: b, c: renamed, diff --git a/tests/ui/needless_borrowed_ref.rs b/tests/ui/needless_borrowed_ref.rs index ae6377fd4421..7edfda60b979 100644 --- a/tests/ui/needless_borrowed_ref.rs +++ b/tests/ui/needless_borrowed_ref.rs @@ -69,7 +69,7 @@ fn should_lint( //~^ needless_borrowed_reference if let &Struct { - //~^ needless_borrowed_reference + //~^ needless_borrowed_reference ref a, b: ref b, c: ref renamed, diff --git a/tests/ui/needless_character_iteration.fixed b/tests/ui/needless_character_iteration.fixed index 584b578fa8be..e25db9bb590f 100644 --- a/tests/ui/needless_character_iteration.fixed +++ b/tests/ui/needless_character_iteration.fixed @@ -27,7 +27,6 @@ fn main() { !"foo".is_ascii(); //~^ needless_character_iteration - let s = String::new(); s.is_ascii(); //~^ needless_character_iteration @@ -35,14 +34,12 @@ fn main() { !"foo".to_string().is_ascii(); //~^ needless_character_iteration - "foo".is_ascii(); !"foo".is_ascii(); S::default().field().is_ascii(); //~^ needless_character_iteration - // Should not lint! "foo".chars().all(|c| { let x = c; diff --git a/tests/ui/needless_character_iteration.rs b/tests/ui/needless_character_iteration.rs index 1ef5c3a79a3e..9b184dab6bc8 100644 --- a/tests/ui/needless_character_iteration.rs +++ b/tests/ui/needless_character_iteration.rs @@ -27,7 +27,6 @@ fn main() { "foo".chars().any(|c| !char::is_ascii(&c)); //~^ needless_character_iteration - let s = String::new(); s.chars().all(|c| c.is_ascii()); //~^ needless_character_iteration @@ -35,15 +34,14 @@ fn main() { "foo".to_string().chars().any(|c| !c.is_ascii()); //~^ needless_character_iteration - "foo".chars().all(|c| { - //~^ needless_character_iteration + //~^ needless_character_iteration let x = c; x.is_ascii() }); "foo".chars().any(|c| { - //~^ needless_character_iteration + //~^ needless_character_iteration let x = c; !x.is_ascii() @@ -52,7 +50,6 @@ fn main() { S::default().field().chars().all(|x| x.is_ascii()); //~^ needless_character_iteration - // Should not lint! "foo".chars().all(|c| { let x = c; diff --git a/tests/ui/needless_character_iteration.stderr b/tests/ui/needless_character_iteration.stderr index 29e5a674e0c5..995404996644 100644 --- a/tests/ui/needless_character_iteration.stderr +++ b/tests/ui/needless_character_iteration.stderr @@ -26,19 +26,19 @@ LL | "foo".chars().any(|c| !char::is_ascii(&c)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:32:5 + --> tests/ui/needless_character_iteration.rs:31:5 | LL | s.chars().all(|c| c.is_ascii()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:35:5 + --> tests/ui/needless_character_iteration.rs:34:5 | LL | "foo".to_string().chars().any(|c| !c.is_ascii()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".to_string().is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:39:5 + --> tests/ui/needless_character_iteration.rs:37:5 | LL | / "foo".chars().all(|c| { LL | | @@ -49,7 +49,7 @@ LL | | }); | |______^ help: try: `"foo".is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:45:5 + --> tests/ui/needless_character_iteration.rs:43:5 | LL | / "foo".chars().any(|c| { LL | | @@ -60,7 +60,7 @@ LL | | }); | |______^ help: try: `!"foo".is_ascii()` error: checking if a string is ascii using iterators - --> tests/ui/needless_character_iteration.rs:52:5 + --> tests/ui/needless_character_iteration.rs:50:5 | LL | S::default().field().chars().all(|x| x.is_ascii()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `S::default().field().is_ascii()` diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index c2267b84de42..104941dc9937 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -9,7 +9,7 @@ fn main() { let len = sample.iter().count(); //~^ needless_collect if sample.iter().next().is_none() { - //~^ needless_collect + //~^ needless_collect // Empty } sample.iter().cloned().any(|x| x == 1); diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index 854bc3fff19d..7f05f51b82e9 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -9,7 +9,7 @@ fn main() { let len = sample.iter().collect::>().len(); //~^ needless_collect if sample.iter().collect::>().is_empty() { - //~^ needless_collect + //~^ needless_collect // Empty } sample.iter().cloned().collect::>().contains(&1); diff --git a/tests/ui/needless_continue.rs b/tests/ui/needless_continue.rs index 0adef7e72ee4..e873db6dee14 100644 --- a/tests/ui/needless_continue.rs +++ b/tests/ui/needless_continue.rs @@ -28,7 +28,7 @@ fn main() { let i = 0; println!("bar {} ", i); } else { - //~^ needless_continue + //~^ needless_continue continue; } @@ -45,7 +45,7 @@ fn main() { } if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 { - //~^ needless_continue + //~^ needless_continue continue; } else { @@ -61,7 +61,6 @@ fn simple_loop() { loop { continue; //~^ needless_continue - } } @@ -70,7 +69,6 @@ fn simple_loop2() { println!("bleh"); continue; //~^ needless_continue - } } @@ -98,7 +96,6 @@ fn simple_loop5() { println!("bleh"); { continue } //~^ needless_continue - } } @@ -149,7 +146,7 @@ mod issue_2329 { if condition() { println!("bar-3"); } else { - //~^ needless_continue + //~^ needless_continue continue 'inner; } @@ -157,7 +154,7 @@ mod issue_2329 { update_condition(); if condition() { - //~^ needless_continue + //~^ needless_continue continue; } else { @@ -182,7 +179,6 @@ fn issue_13641() { 'b: loop { continue 'b; //~^ needless_continue - } } } @@ -221,7 +217,7 @@ mod issue_4077 { loop { if true { } else { - //~^ needless_continue + //~^ needless_continue // redundant `else` continue; // redundant `continue` } @@ -229,7 +225,7 @@ mod issue_4077 { loop { if some_expr() { - //~^ needless_continue + //~^ needless_continue continue; } else { do_something(); diff --git a/tests/ui/needless_continue.stderr b/tests/ui/needless_continue.stderr index 947e61cac12e..878c1e731e32 100644 --- a/tests/ui/needless_continue.stderr +++ b/tests/ui/needless_continue.stderr @@ -71,7 +71,7 @@ LL | continue; = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:71:9 + --> tests/ui/needless_continue.rs:70:9 | LL | continue; | ^^^^^^^^ @@ -79,7 +79,7 @@ LL | continue; = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:80:9 + --> tests/ui/needless_continue.rs:78:9 | LL | continue | ^^^^^^^^ @@ -87,7 +87,7 @@ LL | continue = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:90:9 + --> tests/ui/needless_continue.rs:88:9 | LL | continue | ^^^^^^^^ @@ -95,7 +95,7 @@ LL | continue = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:99:11 + --> tests/ui/needless_continue.rs:97:11 | LL | { continue } | ^^^^^^^^ @@ -103,7 +103,7 @@ LL | { continue } = help: consider dropping the `continue` expression error: this `else` block is redundant - --> tests/ui/needless_continue.rs:151:24 + --> tests/ui/needless_continue.rs:148:24 | LL | } else { | ________________________^ @@ -130,7 +130,7 @@ LL | | } } error: there is no need for an explicit `else` block for this `if` expression - --> tests/ui/needless_continue.rs:159:17 + --> tests/ui/needless_continue.rs:156:17 | LL | / if condition() { LL | | @@ -152,13 +152,21 @@ LL | | } } error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:183:13 + --> tests/ui/needless_continue.rs:180:13 | LL | continue 'b; | ^^^^^^^^^^^ | = help: consider dropping the `continue` expression +error: this `continue` expression is redundant + --> tests/ui/needless_continue.rs:196:21 + | +LL | continue 'inner; + | ^^^^^^^^^^^^^^^ + | + = help: consider dropping the `continue` expression + error: this `continue` expression is redundant --> tests/ui/needless_continue.rs:200:21 | @@ -168,15 +176,7 @@ LL | continue 'inner; = help: consider dropping the `continue` expression error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:204:21 - | -LL | continue 'inner; - | ^^^^^^^^^^^^^^^ - | - = help: consider dropping the `continue` expression - -error: this `continue` expression is redundant - --> tests/ui/needless_continue.rs:215:21 + --> tests/ui/needless_continue.rs:211:21 | LL | continue; | ^^^^^^^^ @@ -184,7 +184,7 @@ LL | continue; = help: consider dropping the `continue` expression error: this `else` block is redundant - --> tests/ui/needless_continue.rs:223:20 + --> tests/ui/needless_continue.rs:219:20 | LL | } else { | ____________________^ @@ -201,7 +201,7 @@ LL | | } } error: there is no need for an explicit `else` block for this `if` expression - --> tests/ui/needless_continue.rs:231:13 + --> tests/ui/needless_continue.rs:227:13 | LL | / if some_expr() { LL | | diff --git a/tests/ui/needless_for_each_fixable.fixed b/tests/ui/needless_for_each_fixable.fixed index 873bad552af1..fa23e18318f1 100644 --- a/tests/ui/needless_for_each_fixable.fixed +++ b/tests/ui/needless_for_each_fixable.fixed @@ -13,34 +13,34 @@ fn should_lint() { let v: Vec = Vec::new(); let mut acc = 0; for elem in v.iter() { - //~^ needless_for_each + //~^ needless_for_each acc += elem; } for elem in v.into_iter() { - //~^ needless_for_each + //~^ needless_for_each acc += elem; } for elem in [1, 2, 3].iter() { - //~^ needless_for_each + //~^ needless_for_each acc += elem; } let mut hash_map: HashMap = HashMap::new(); for (k, v) in hash_map.iter() { - //~^ needless_for_each + //~^ needless_for_each acc += k + v; } for (k, v) in hash_map.iter_mut() { - //~^ needless_for_each + //~^ needless_for_each acc += *k + *v; } for k in hash_map.keys() { - //~^ needless_for_each + //~^ needless_for_each acc += k; } for v in hash_map.values() { - //~^ needless_for_each + //~^ needless_for_each acc += v; } @@ -48,7 +48,7 @@ fn should_lint() { Vec::new() } for elem in my_vec().iter() { - //~^ needless_for_each + //~^ needless_for_each acc += elem; } } diff --git a/tests/ui/needless_for_each_fixable.rs b/tests/ui/needless_for_each_fixable.rs index 5e650dfc06c1..2c7e68a6f512 100644 --- a/tests/ui/needless_for_each_fixable.rs +++ b/tests/ui/needless_for_each_fixable.rs @@ -13,34 +13,34 @@ fn should_lint() { let v: Vec = Vec::new(); let mut acc = 0; v.iter().for_each(|elem| { - //~^ needless_for_each + //~^ needless_for_each acc += elem; }); v.into_iter().for_each(|elem| { - //~^ needless_for_each + //~^ needless_for_each acc += elem; }); [1, 2, 3].iter().for_each(|elem| { - //~^ needless_for_each + //~^ needless_for_each acc += elem; }); let mut hash_map: HashMap = HashMap::new(); hash_map.iter().for_each(|(k, v)| { - //~^ needless_for_each + //~^ needless_for_each acc += k + v; }); hash_map.iter_mut().for_each(|(k, v)| { - //~^ needless_for_each + //~^ needless_for_each acc += *k + *v; }); hash_map.keys().for_each(|k| { - //~^ needless_for_each + //~^ needless_for_each acc += k; }); hash_map.values().for_each(|v| { - //~^ needless_for_each + //~^ needless_for_each acc += v; }); @@ -48,7 +48,7 @@ fn should_lint() { Vec::new() } my_vec().iter().for_each(|elem| { - //~^ needless_for_each + //~^ needless_for_each acc += elem; }); } diff --git a/tests/ui/needless_for_each_unfixable.rs b/tests/ui/needless_for_each_unfixable.rs index 56faa471ed8c..159cbe49828f 100644 --- a/tests/ui/needless_for_each_unfixable.rs +++ b/tests/ui/needless_for_each_unfixable.rs @@ -6,8 +6,7 @@ fn main() { let v: Vec = Vec::new(); // This is unfixable because the closure includes `return`. v.iter().for_each(|v| { - //~^ needless_for_each - + //~^ needless_for_each if *v == 10 { return; diff --git a/tests/ui/needless_for_each_unfixable.stderr b/tests/ui/needless_for_each_unfixable.stderr index 37470a8a622e..7e42bd133f06 100644 --- a/tests/ui/needless_for_each_unfixable.stderr +++ b/tests/ui/needless_for_each_unfixable.stderr @@ -2,6 +2,9 @@ error: needless use of `for_each` --> tests/ui/needless_for_each_unfixable.rs:8:5 | LL | / v.iter().for_each(|v| { +LL | | +LL | | +LL | | if *v == 10 { ... | LL | | }); | |_______^ @@ -13,7 +16,6 @@ help: try LL ~ for v in v.iter() { LL + LL + -LL + LL + if *v == 10 { LL + return; LL + } else { diff --git a/tests/ui/needless_if.fixed b/tests/ui/needless_if.fixed index 1e2842a27aa6..6208ca19b82b 100644 --- a/tests/ui/needless_if.fixed +++ b/tests/ui/needless_if.fixed @@ -34,7 +34,7 @@ fn main() { } else { } ({ - //~^ needless_if + //~^ needless_if return; }); // Do not lint if `else if` is present @@ -51,7 +51,7 @@ fn main() { {} // Can lint nested `if let`s ({ - //~^ needless_if + //~^ needless_if if let true = true && true { diff --git a/tests/ui/needless_if.rs b/tests/ui/needless_if.rs index a753c66da5a5..b459ff877be6 100644 --- a/tests/ui/needless_if.rs +++ b/tests/ui/needless_if.rs @@ -34,7 +34,7 @@ fn main() { } else { } if { - //~^ needless_if + //~^ needless_if return; } {} // Do not lint if `else if` is present @@ -51,7 +51,7 @@ fn main() { {} // Can lint nested `if let`s if { - //~^ needless_if + //~^ needless_if if let true = true && true { diff --git a/tests/ui/needless_lifetimes.fixed b/tests/ui/needless_lifetimes.fixed index 3cfbce84cd9b..283635d42def 100644 --- a/tests/ui/needless_lifetimes.fixed +++ b/tests/ui/needless_lifetimes.fixed @@ -31,7 +31,7 @@ fn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) {} fn mut_and_static_input(_x: &mut u8, _y: &'static str) {} fn in_and_out(x: &u8, _y: u8) -> &u8 { -//~^ needless_lifetimes + //~^ needless_lifetimes x } @@ -44,7 +44,7 @@ fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 { // fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 // ^^^ fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 { -//~^ needless_lifetimes + //~^ needless_lifetimes x } @@ -52,7 +52,7 @@ fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 { // fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 // ^^^ fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 { -//~^ needless_lifetimes + //~^ needless_lifetimes y } @@ -70,7 +70,7 @@ fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 { // fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> // ^^^ fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> { -//~^ needless_lifetimes + //~^ needless_lifetimes Ok(x) } @@ -78,7 +78,7 @@ fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> { // fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> // ^^^ fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> { -//~^ needless_lifetimes + //~^ needless_lifetimes Ok(y) } @@ -88,7 +88,7 @@ fn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 { } fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> { -//~^ needless_lifetimes + //~^ needless_lifetimes Ok(x) } @@ -163,7 +163,7 @@ struct X { impl X { fn self_and_out(&self) -> &u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes &self.x } @@ -171,7 +171,7 @@ impl X { // fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 // ^^^ fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes &self.x } @@ -179,7 +179,7 @@ impl X { // fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 // ^^^^^ fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes x } @@ -204,7 +204,7 @@ fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 { } fn struct_with_lt(_foo: Foo<'_>) -> &str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -223,7 +223,7 @@ fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str { // fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str // ^^ fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -232,7 +232,7 @@ fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { // fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str // ^^^^ fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -248,14 +248,14 @@ fn trait_obj_elided<'a>(_arg: &'a dyn WithLifetime) -> &'a str { // Should warn because there is no lifetime on `Drop`, so this would be // unambiguous if we elided the lifetime. fn trait_obj_elided2(_arg: &dyn Drop) -> &str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } type FooAlias<'a> = Foo<'a>; fn alias_with_lt(_foo: FooAlias<'_>) -> &str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -274,7 +274,7 @@ fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str { // fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str // ^^ fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -283,12 +283,12 @@ fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { // fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str // ^^^^^^^^^ fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } fn named_input_elided_output(_arg: &str) -> &str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -297,7 +297,7 @@ fn elided_input_named_output<'a>(_arg: &str) -> &'a str { } fn trait_bound_ok>(_: &u8, _: T) { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } fn trait_bound<'a, T: WithLifetime<'a>>(_: &'a u8, _: T) { @@ -334,7 +334,7 @@ struct Cow<'a> { x: &'a str, } fn out_return_type_lts(e: &str) -> Cow<'_> { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -362,7 +362,7 @@ mod issue2944 { //~^ needless_lifetimes impl Bar { fn baz(&self) -> impl Foo + '_ { - //~^ needless_lifetimes + //~^ needless_lifetimes Baz { bar: self } } } @@ -395,7 +395,7 @@ mod nested_elision_sites { f(i) } fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(&i32) -> &i32) -> &i32 { - //~^ needless_lifetimes + //~^ needless_lifetimes f(i) } @@ -405,7 +405,7 @@ mod nested_elision_sites { } // lint fn generics_elidable &i32>(i: &i32, f: T) -> &i32 { - //~^ needless_lifetimes + //~^ needless_lifetimes f(i) } @@ -434,7 +434,7 @@ mod nested_elision_sites { } // lint fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 { - //~^ needless_lifetimes + //~^ needless_lifetimes f(i) } @@ -448,11 +448,11 @@ mod nested_elision_sites { // lint fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 { - //~^ needless_lifetimes + //~^ needless_lifetimes |f| 42 } fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) { - //~^ needless_lifetimes + //~^ needless_lifetimes |f| () } } @@ -475,21 +475,21 @@ mod issue7296 { struct Foo; impl Foo { fn implicit(&self) -> &() { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } fn implicit_mut(&mut self) -> &() { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit(self: &Arc) -> &() { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit_mut(self: &mut Rc) -> &() { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } #[clippy::msrv = "1.80"] @@ -502,7 +502,7 @@ mod issue7296 { } fn lifetime_elsewhere(self: Box, here: &()) -> &() { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } } @@ -511,7 +511,7 @@ mod issue7296 { fn implicit(&self) -> &(); //~^ needless_lifetimes fn implicit_provided(&self) -> &() { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } @@ -520,7 +520,7 @@ mod issue7296 { //~^ needless_lifetimes #[clippy::msrv = "1.81"] fn explicit_provided(self: &Arc) -> &() { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } #[clippy::msrv = "1.80"] @@ -533,7 +533,7 @@ mod issue7296 { fn lifetime_elsewhere(self: Box, here: &()) -> &(); //~^ needless_lifetimes fn lifetime_elsewhere_provided(self: Box, here: &()) -> &() { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } } @@ -554,13 +554,13 @@ mod pr_9743_output_lifetime_checks { // lint: only one input fn one_input(x: &u8) -> &u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } // lint: multiple inputs, output would not be elided fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) -> &'b u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -673,7 +673,7 @@ mod issue13923 { } impl<'t> ContentString<'t> { - //~^ needless_lifetimes + //~^ needless_lifetimes // `'py` can be elided because of `&self` fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { match self { @@ -684,7 +684,7 @@ mod issue13923 { } impl<'t> ContentString<'t> { - //~^ needless_lifetimes + //~^ needless_lifetimes // `'py` can be elided because of `&'_ self` fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { match self { @@ -705,7 +705,7 @@ mod issue13923 { } impl<'t> ContentString<'t> { - //~^ needless_lifetimes + //~^ needless_lifetimes // `'py` can be elided because of `&Self` fn map_content5( self: std::pin::Pin<&Self>, diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs index 612e7546d962..2853870473db 100644 --- a/tests/ui/needless_lifetimes.rs +++ b/tests/ui/needless_lifetimes.rs @@ -31,7 +31,7 @@ fn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) {} fn mut_and_static_input(_x: &mut u8, _y: &'static str) {} fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 { -//~^ needless_lifetimes + //~^ needless_lifetimes x } @@ -44,7 +44,7 @@ fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 { // fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 // ^^^ fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 { -//~^ needless_lifetimes + //~^ needless_lifetimes x } @@ -52,7 +52,7 @@ fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 { // fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 // ^^^ fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 { -//~^ needless_lifetimes + //~^ needless_lifetimes y } @@ -70,7 +70,7 @@ fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 { // fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> // ^^^ fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> { -//~^ needless_lifetimes + //~^ needless_lifetimes Ok(x) } @@ -78,7 +78,7 @@ fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> { // fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> // ^^^ fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> { -//~^ needless_lifetimes + //~^ needless_lifetimes Ok(y) } @@ -88,7 +88,7 @@ fn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 { } fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> { -//~^ needless_lifetimes + //~^ needless_lifetimes Ok(x) } @@ -163,7 +163,7 @@ struct X { impl X { fn self_and_out<'s>(&'s self) -> &'s u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes &self.x } @@ -171,7 +171,7 @@ impl X { // fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 // ^^^ fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes &self.x } @@ -179,7 +179,7 @@ impl X { // fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 // ^^^^^ fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes x } @@ -204,7 +204,7 @@ fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 { } fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -223,7 +223,7 @@ fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str { // fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str // ^^ fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -232,7 +232,7 @@ fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { // fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str // ^^^^ fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -248,14 +248,14 @@ fn trait_obj_elided<'a>(_arg: &'a dyn WithLifetime) -> &'a str { // Should warn because there is no lifetime on `Drop`, so this would be // unambiguous if we elided the lifetime. fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } type FooAlias<'a> = Foo<'a>; fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -274,7 +274,7 @@ fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str { // fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str // ^^ fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -283,12 +283,12 @@ fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { // fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str // ^^^^^^^^^ fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } fn named_input_elided_output<'a>(_arg: &'a str) -> &str { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -297,7 +297,7 @@ fn elided_input_named_output<'a>(_arg: &str) -> &'a str { } fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } fn trait_bound<'a, T: WithLifetime<'a>>(_: &'a u8, _: T) { @@ -334,7 +334,7 @@ struct Cow<'a> { x: &'a str, } fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { -//~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -362,7 +362,7 @@ mod issue2944 { //~^ needless_lifetimes impl Bar { fn baz<'a>(&'a self) -> impl Foo + 'a { - //~^ needless_lifetimes + //~^ needless_lifetimes Baz { bar: self } } } @@ -395,7 +395,7 @@ mod nested_elision_sites { f(i) } fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 { - //~^ needless_lifetimes + //~^ needless_lifetimes f(i) } @@ -405,7 +405,7 @@ mod nested_elision_sites { } // lint fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 { - //~^ needless_lifetimes + //~^ needless_lifetimes f(i) } @@ -434,7 +434,7 @@ mod nested_elision_sites { } // lint fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 { - //~^ needless_lifetimes + //~^ needless_lifetimes f(i) } @@ -448,11 +448,11 @@ mod nested_elision_sites { // lint fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 { - //~^ needless_lifetimes + //~^ needless_lifetimes |f| 42 } fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) { - //~^ needless_lifetimes + //~^ needless_lifetimes |f| () } } @@ -475,21 +475,21 @@ mod issue7296 { struct Foo; impl Foo { fn implicit<'a>(&'a self) -> &'a () { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } fn implicit_mut<'a>(&'a mut self) -> &'a () { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit<'a>(self: &'a Arc) -> &'a () { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } #[clippy::msrv = "1.81"] fn explicit_mut<'a>(self: &'a mut Rc) -> &'a () { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } #[clippy::msrv = "1.80"] @@ -502,7 +502,7 @@ mod issue7296 { } fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a () { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } } @@ -511,7 +511,7 @@ mod issue7296 { fn implicit<'a>(&'a self) -> &'a (); //~^ needless_lifetimes fn implicit_provided<'a>(&'a self) -> &'a () { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } @@ -520,7 +520,7 @@ mod issue7296 { //~^ needless_lifetimes #[clippy::msrv = "1.81"] fn explicit_provided<'a>(self: &'a Arc) -> &'a () { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } #[clippy::msrv = "1.80"] @@ -533,7 +533,7 @@ mod issue7296 { fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a (); //~^ needless_lifetimes fn lifetime_elsewhere_provided<'a>(self: Box, here: &'a ()) -> &'a () { - //~^ needless_lifetimes + //~^ needless_lifetimes &() } } @@ -554,13 +554,13 @@ mod pr_9743_output_lifetime_checks { // lint: only one input fn one_input<'a>(x: &'a u8) -> &'a u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } // lint: multiple inputs, output would not be elided fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 { - //~^ needless_lifetimes + //~^ needless_lifetimes unimplemented!() } @@ -673,7 +673,7 @@ mod issue13923 { } impl<'t, 'py> ContentString<'t> { - //~^ needless_lifetimes + //~^ needless_lifetimes // `'py` can be elided because of `&self` fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { match self { @@ -684,7 +684,7 @@ mod issue13923 { } impl<'t, 'py> ContentString<'t> { - //~^ needless_lifetimes + //~^ needless_lifetimes // `'py` can be elided because of `&'_ self` fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { match self { @@ -705,7 +705,7 @@ mod issue13923 { } impl<'t, 'py> ContentString<'t> { - //~^ needless_lifetimes + //~^ needless_lifetimes // `'py` can be elided because of `&Self` fn map_content5( self: std::pin::Pin<&Self>, diff --git a/tests/ui/needless_match.rs b/tests/ui/needless_match.rs index 848490d9b35e..1cb670edc60f 100644 --- a/tests/ui/needless_match.rs +++ b/tests/ui/needless_match.rs @@ -13,7 +13,7 @@ enum Simple { fn useless_match() { let i = 10; let _: i32 = match i { - //~^ needless_match + //~^ needless_match 0 => 0, 1 => 1, 2 => 2, @@ -21,7 +21,7 @@ fn useless_match() { }; let s = "test"; let _: &str = match s { - //~^ needless_match + //~^ needless_match "a" => "a", "b" => "b", s => s, @@ -31,7 +31,7 @@ fn useless_match() { fn custom_type_match() { let se = Simple::A; let _: Simple = match se { - //~^ needless_match + //~^ needless_match Simple::A => Simple::A, Simple::B => Simple::B, Simple::C => Simple::C, @@ -54,7 +54,7 @@ fn custom_type_match() { fn option_match(x: Option) { let _: Option = match x { - //~^ needless_match + //~^ needless_match Some(a) => Some(a), None => None, }; @@ -71,12 +71,12 @@ fn func_ret_err(err: T) -> Result { fn result_match() { let _: Result = match Ok(1) { - //~^ needless_match + //~^ needless_match Ok(a) => Ok(a), Err(err) => Err(err), }; let _: Result = match func_ret_err(0_i32) { - //~^ needless_match + //~^ needless_match Err(err) => Err(err), Ok(a) => Ok(a), }; @@ -136,7 +136,7 @@ fn if_let_result() { fn if_let_custom_enum(x: Simple) { let _: Simple = if let Simple::A = x { - //~^ needless_match + //~^ needless_match Simple::A } else if let Simple::B = x { Simple::B @@ -176,7 +176,7 @@ mod issue8542 { let bb = false; let _: Complex = match ce { - //~^ needless_match + //~^ needless_match Complex::A(a) => Complex::A(a), Complex::B(a, b) => Complex::B(a, b), Complex::C(a, b, c) => Complex::C(a, b, c), @@ -261,14 +261,14 @@ mod issue9084 { // should lint let _ = match e { - //~^ needless_match + //~^ needless_match _ if some_bool => e, _ => e, }; // should lint let _ = match e { - //~^ needless_match + //~^ needless_match Some(i) => Some(i), _ if some_bool => e, _ => e, @@ -350,7 +350,7 @@ pub fn issue13574() -> Option<()> { // Same const, should lint let _ = { if let Some(num) = A { - //~^ needless_match + //~^ needless_match Some(num) } else if let Some(num) = A { Some(num) diff --git a/tests/ui/needless_maybe_sized.fixed b/tests/ui/needless_maybe_sized.fixed index 68252ba54fd4..f8b164396990 100644 --- a/tests/ui/needless_maybe_sized.fixed +++ b/tests/ui/needless_maybe_sized.fixed @@ -51,23 +51,23 @@ struct Struct(T); //~^ needless_maybe_sized impl Struct { -//~^ needless_maybe_sized + //~^ needless_maybe_sized fn method(&self) {} //~^ needless_maybe_sized } enum Enum { -//~^ needless_maybe_sized + //~^ needless_maybe_sized Variant(&'static T), } union Union<'a, T: Sized> { -//~^ needless_maybe_sized + //~^ needless_maybe_sized a: &'a T, } trait Trait { -//~^ needless_maybe_sized + //~^ needless_maybe_sized fn trait_method() {} //~^ needless_maybe_sized diff --git a/tests/ui/needless_maybe_sized.rs b/tests/ui/needless_maybe_sized.rs index 0cafc0d9ff6e..e4312b40563f 100644 --- a/tests/ui/needless_maybe_sized.rs +++ b/tests/ui/needless_maybe_sized.rs @@ -54,23 +54,23 @@ struct Struct(T); //~^ needless_maybe_sized impl Struct { -//~^ needless_maybe_sized + //~^ needless_maybe_sized fn method(&self) {} //~^ needless_maybe_sized } enum Enum { -//~^ needless_maybe_sized + //~^ needless_maybe_sized Variant(&'static T), } union Union<'a, T: Sized + ?Sized> { -//~^ needless_maybe_sized + //~^ needless_maybe_sized a: &'a T, } trait Trait { -//~^ needless_maybe_sized + //~^ needless_maybe_sized fn trait_method() {} //~^ needless_maybe_sized diff --git a/tests/ui/needless_option_take.fixed b/tests/ui/needless_option_take.fixed index ae2bfab0e06d..a8bd50b79899 100644 --- a/tests/ui/needless_option_take.fixed +++ b/tests/ui/needless_option_take.fixed @@ -23,7 +23,6 @@ fn main() { x.as_ref(); //~^ needless_option_take - println!("Testing non erroneous option_take_on_temporary"); let mut x = Some(3); let y = x.as_mut(); @@ -35,33 +34,26 @@ fn main() { let y = x.replace(289); //~^ needless_option_take - let y = Some(3).as_mut(); //~^ needless_option_take - let y = Option::as_mut(&mut x); //~^ needless_option_take - let x = return_option(); let x = return_option(); //~^ needless_option_take - let x = MyStruct::get_option(); let x = MyStruct::get_option(); //~^ needless_option_take - let mut my_vec = vec![1, 2, 3]; my_vec.push(4); let y = my_vec.first(); let y = my_vec.first(); //~^ needless_option_take - let y = my_vec.first(); //~^ needless_option_take - } diff --git a/tests/ui/needless_option_take.rs b/tests/ui/needless_option_take.rs index 723930f59a11..8141ee43db11 100644 --- a/tests/ui/needless_option_take.rs +++ b/tests/ui/needless_option_take.rs @@ -23,7 +23,6 @@ fn main() { x.as_ref().take(); //~^ needless_option_take - println!("Testing non erroneous option_take_on_temporary"); let mut x = Some(3); let y = x.as_mut(); @@ -35,33 +34,26 @@ fn main() { let y = x.replace(289).take(); //~^ needless_option_take - let y = Some(3).as_mut().take(); //~^ needless_option_take - let y = Option::as_mut(&mut x).take(); //~^ needless_option_take - let x = return_option(); let x = return_option().take(); //~^ needless_option_take - let x = MyStruct::get_option(); let x = MyStruct::get_option().take(); //~^ needless_option_take - let mut my_vec = vec![1, 2, 3]; my_vec.push(4); let y = my_vec.first(); let y = my_vec.first().take(); //~^ needless_option_take - let y = my_vec.first().take(); //~^ needless_option_take - } diff --git a/tests/ui/needless_option_take.stderr b/tests/ui/needless_option_take.stderr index 271e1a0c7915..9054463c07cd 100644 --- a/tests/ui/needless_option_take.stderr +++ b/tests/ui/needless_option_take.stderr @@ -11,7 +11,7 @@ LL | x.as_ref().take(); = help: to override `-D warnings` add `#[allow(clippy::needless_option_take)]` error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:32:13 + --> tests/ui/needless_option_take.rs:31:13 | LL | let y = x.as_mut().take(); | ^^^^^^^^^^------- @@ -21,7 +21,7 @@ LL | let y = x.as_mut().take(); = note: `as_mut` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:35:13 + --> tests/ui/needless_option_take.rs:34:13 | LL | let y = x.replace(289).take(); | ^^^^^^^^^^^^^^------- @@ -31,7 +31,7 @@ LL | let y = x.replace(289).take(); = note: `replace` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:39:13 + --> tests/ui/needless_option_take.rs:37:13 | LL | let y = Some(3).as_mut().take(); | ^^^^^^^^^^^^^^^^------- @@ -41,7 +41,7 @@ LL | let y = Some(3).as_mut().take(); = note: `as_mut` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:43:13 + --> tests/ui/needless_option_take.rs:40:13 | LL | let y = Option::as_mut(&mut x).take(); | ^^^^^^^^^^^^^^^^^^^^^^------- @@ -51,7 +51,7 @@ LL | let y = Option::as_mut(&mut x).take(); = note: `as_mut` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:48:13 + --> tests/ui/needless_option_take.rs:44:13 | LL | let x = return_option().take(); | ^^^^^^^^^^^^^^^------- @@ -61,7 +61,7 @@ LL | let x = return_option().take(); = note: `return_option` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:53:13 + --> tests/ui/needless_option_take.rs:48:13 | LL | let x = MyStruct::get_option().take(); | ^^^^^^^^^^^^^^^^^^^^^^------- @@ -71,7 +71,7 @@ LL | let x = MyStruct::get_option().take(); = note: `get_option` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:60:13 + --> tests/ui/needless_option_take.rs:54:13 | LL | let y = my_vec.first().take(); | ^^^^^^^^^^^^^^------- @@ -81,7 +81,7 @@ LL | let y = my_vec.first().take(); = note: `first` creates a temporary value, so calling take() has no effect error: called `Option::take()` on a temporary value - --> tests/ui/needless_option_take.rs:64:13 + --> tests/ui/needless_option_take.rs:57:13 | LL | let y = my_vec.first().take(); | ^^^^^^^^^^^^^^------- diff --git a/tests/ui/needless_pass_by_ref_mut.rs b/tests/ui/needless_pass_by_ref_mut.rs index 415a13163805..f0c5a716ac99 100644 --- a/tests/ui/needless_pass_by_ref_mut.rs +++ b/tests/ui/needless_pass_by_ref_mut.rs @@ -9,7 +9,7 @@ use std::ptr::NonNull; fn foo(s: &mut Vec, b: &u32, x: &mut u32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut *x += *b + s.len() as u32; } @@ -35,7 +35,7 @@ fn foo5(s: &mut Vec) { } fn foo6(s: &mut Vec) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut non_mut_ref(s); } @@ -48,9 +48,8 @@ impl Bar { fn bar(&mut self) {} //~^ needless_pass_by_ref_mut - fn mushroom(&self, vec: &mut Vec) -> usize { - //~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut vec.len() } @@ -128,43 +127,43 @@ async fn f7(x: &mut i32, y: i32, z: &mut i32, a: i32) { } async fn a1(x: &mut i32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut println!("{:?}", x); } async fn a2(x: &mut i32, y: String) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut println!("{:?}", x); } async fn a3(x: &mut i32, y: String, z: String) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut println!("{:?}", x); } async fn a4(x: &mut i32, y: i32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut println!("{:?}", x); } async fn a5(x: i32, y: &mut i32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut println!("{:?}", x); } async fn a6(x: i32, y: &mut i32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut println!("{:?}", x); } async fn a7(x: i32, y: i32, z: &mut i32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut println!("{:?}", z); } async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { -//~^ needless_pass_by_ref_mut -//~| needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut + //~| needless_pass_by_ref_mut println!("{:?}", z); } @@ -201,14 +200,10 @@ fn lint_attr(s: &mut u32) {} fn cfg_warn(s: &mut u32) {} //~^ needless_pass_by_ref_mut - - #[cfg(not(feature = "a"))] mod foo { fn cfg_warn(s: &mut u32) {} //~^ needless_pass_by_ref_mut - - } // Should not warn. @@ -221,7 +216,7 @@ async fn inner_async(x: &mut i32, y: &mut u32) { } async fn inner_async2(x: &mut i32, y: &mut u32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut async { *x += 1; @@ -230,7 +225,7 @@ async fn inner_async2(x: &mut i32, y: &mut u32) { } async fn inner_async3(x: &mut i32, y: &mut u32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut async { *y += 1; @@ -250,7 +245,7 @@ async fn async_vec2(b: &mut Vec) { fn non_mut(n: &str) {} //Should warn async fn call_in_closure1(n: &mut str) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut (|| non_mut(n))() } fn str_mut(str: &mut String) -> bool { @@ -270,7 +265,7 @@ async fn closure(n: &mut usize) -> impl '_ + FnMut() { // Should warn. fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut || *n + 1 } @@ -282,7 +277,7 @@ async fn closure3(n: &mut usize) { // Should warn. async fn closure4(n: &mut usize) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut (|| { let _x = *n + 1; @@ -340,9 +335,8 @@ impl MutSelf { //~^ needless_pass_by_ref_mut async fn foo(&mut self, u: &mut i32, v: &mut u32) { - //~^ needless_pass_by_ref_mut - //~| needless_pass_by_ref_mut - + //~^ needless_pass_by_ref_mut + //~| needless_pass_by_ref_mut async { *u += 1; @@ -350,7 +344,7 @@ impl MutSelf { .await; } async fn foo2(&mut self, u: &mut i32, v: &mut u32) { - //~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut async { self.a += 1; diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr index 0492acf7cc08..6637a255b5f5 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -20,67 +20,67 @@ LL | fn bar(&mut self) {} | ^^^^^^^^^ help: consider changing to: `&self` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:52:29 + --> tests/ui/needless_pass_by_ref_mut.rs:51:29 | LL | fn mushroom(&self, vec: &mut Vec) -> usize { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:130:16 + --> tests/ui/needless_pass_by_ref_mut.rs:129:16 | LL | async fn a1(x: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:135:16 + --> tests/ui/needless_pass_by_ref_mut.rs:134:16 | LL | async fn a2(x: &mut i32, y: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:140:16 + --> tests/ui/needless_pass_by_ref_mut.rs:139:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:145:16 + --> tests/ui/needless_pass_by_ref_mut.rs:144:16 | LL | async fn a4(x: &mut i32, y: i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:150:24 + --> tests/ui/needless_pass_by_ref_mut.rs:149:24 | LL | async fn a5(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:155:24 + --> tests/ui/needless_pass_by_ref_mut.rs:154:24 | LL | async fn a6(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:160:32 + --> tests/ui/needless_pass_by_ref_mut.rs:159:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:165:24 + --> tests/ui/needless_pass_by_ref_mut.rs:164:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:165:45 + --> tests/ui/needless_pass_by_ref_mut.rs:164:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:201:16 + --> tests/ui/needless_pass_by_ref_mut.rs:200:16 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -88,7 +88,7 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:208:20 + --> tests/ui/needless_pass_by_ref_mut.rs:205:20 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -96,115 +96,115 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:223:39 + --> tests/ui/needless_pass_by_ref_mut.rs:218:39 | LL | async fn inner_async2(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:232:26 + --> tests/ui/needless_pass_by_ref_mut.rs:227:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:252:30 + --> tests/ui/needless_pass_by_ref_mut.rs:247:30 | LL | async fn call_in_closure1(n: &mut str) { | ^^^^^^^^ help: consider changing to: `&str` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:272:16 + --> tests/ui/needless_pass_by_ref_mut.rs:267:16 | LL | fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { | ^^^^^^^^^^ help: consider changing to: `&usize` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:284:22 + --> tests/ui/needless_pass_by_ref_mut.rs:279:22 | LL | async fn closure4(n: &mut usize) { | ^^^^^^^^^^ help: consider changing to: `&usize` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:339:12 + --> tests/ui/needless_pass_by_ref_mut.rs:334:12 | LL | fn bar(&mut self) {} | ^^^^^^^^^ help: consider changing to: `&self` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:342:18 + --> tests/ui/needless_pass_by_ref_mut.rs:337:18 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { | ^^^^^^^^^ help: consider changing to: `&self` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:342:45 + --> tests/ui/needless_pass_by_ref_mut.rs:337:45 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:352:46 + --> tests/ui/needless_pass_by_ref_mut.rs:346:46 | LL | async fn foo2(&mut self, u: &mut i32, v: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:369:18 + --> tests/ui/needless_pass_by_ref_mut.rs:363:18 | LL | fn _empty_tup(x: &mut (())) {} | ^^^^^^^^^ help: consider changing to: `&()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:371:19 + --> tests/ui/needless_pass_by_ref_mut.rs:365:19 | LL | fn _single_tup(x: &mut ((i32,))) {} | ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:373:18 + --> tests/ui/needless_pass_by_ref_mut.rs:367:18 | LL | fn _multi_tup(x: &mut ((i32, u32))) {} | ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:375:11 + --> tests/ui/needless_pass_by_ref_mut.rs:369:11 | LL | fn _fn(x: &mut (fn())) {} | ^^^^^^^^^^^ help: consider changing to: `&fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:378:23 + --> tests/ui/needless_pass_by_ref_mut.rs:372:23 | LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:380:20 + --> tests/ui/needless_pass_by_ref_mut.rs:374:20 | LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:382:18 + --> tests/ui/needless_pass_by_ref_mut.rs:376:18 | LL | fn _unsafe_fn(x: &mut unsafe fn()) {} | ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:384:25 + --> tests/ui/needless_pass_by_ref_mut.rs:378:25 | LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:386:20 + --> tests/ui/needless_pass_by_ref_mut.rs:380:20 | LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:388:20 + --> tests/ui/needless_pass_by_ref_mut.rs:382:20 | LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)` diff --git a/tests/ui/needless_pass_by_ref_mut2.fixed b/tests/ui/needless_pass_by_ref_mut2.fixed index fc40f8c8ca30..0e2ac0202364 100644 --- a/tests/ui/needless_pass_by_ref_mut2.fixed +++ b/tests/ui/needless_pass_by_ref_mut2.fixed @@ -6,7 +6,7 @@ #![warn(clippy::needless_pass_by_ref_mut)] async fn inner_async3(x: &i32, y: &mut u32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut async { *y += 1; @@ -15,7 +15,7 @@ async fn inner_async3(x: &i32, y: &mut u32) { } async fn inner_async4(u: &mut i32, v: &u32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut async { *u += 1; diff --git a/tests/ui/needless_pass_by_ref_mut2.rs b/tests/ui/needless_pass_by_ref_mut2.rs index f921a7684236..9201d9a27298 100644 --- a/tests/ui/needless_pass_by_ref_mut2.rs +++ b/tests/ui/needless_pass_by_ref_mut2.rs @@ -6,7 +6,7 @@ #![warn(clippy::needless_pass_by_ref_mut)] async fn inner_async3(x: &mut i32, y: &mut u32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut async { *y += 1; @@ -15,7 +15,7 @@ async fn inner_async3(x: &mut i32, y: &mut u32) { } async fn inner_async4(u: &mut i32, v: &mut u32) { -//~^ needless_pass_by_ref_mut + //~^ needless_pass_by_ref_mut async { *u += 1; diff --git a/tests/ui/needless_pass_by_value.rs b/tests/ui/needless_pass_by_value.rs index faa68c8140cb..885fb409417b 100644 --- a/tests/ui/needless_pass_by_value.rs +++ b/tests/ui/needless_pass_by_value.rs @@ -17,8 +17,7 @@ use std::mem::MaybeUninit; // `v` should be warned // `w`, `x` and `y` are allowed (moved or mutated) fn foo(v: Vec, w: Vec, mut x: Vec, y: Vec) -> Vec { -//~^ needless_pass_by_value - + //~^ needless_pass_by_value assert_eq!(v.len(), 42); @@ -34,9 +33,8 @@ fn consume(_: T) {} struct Wrapper(String); fn bar(x: String, y: Wrapper) { -//~^ needless_pass_by_value -//~| needless_pass_by_value - + //~^ needless_pass_by_value + //~| needless_pass_by_value assert_eq!(x.len(), 42); assert_eq!(y.0.len(), 42); @@ -44,7 +42,7 @@ fn bar(x: String, y: Wrapper) { // V implements `Borrow`, but should be warned correctly fn test_borrow_trait, U: AsRef, V>(t: T, u: U, v: V) { -//~^ needless_pass_by_value + //~^ needless_pass_by_value println!("{}", t.borrow()); println!("{}", u.as_ref()); @@ -58,7 +56,7 @@ fn test_fn i32>(f: F) { // x should be warned, but y is ok fn test_match(x: Option>, y: Option>) { -//~^ needless_pass_by_value + //~^ needless_pass_by_value match x { Some(Some(_)) => 1, // not moved @@ -73,9 +71,8 @@ fn test_match(x: Option>, y: Option>) { // x and y should be warned, but z is ok fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) { -//~^ needless_pass_by_value -//~| needless_pass_by_value - + //~^ needless_pass_by_value + //~| needless_pass_by_value let Wrapper(s) = z; // moved let Wrapper(ref t) = y; // not moved @@ -95,15 +92,11 @@ impl Serialize for i32 {} fn test_blanket_ref(vals: T, serializable: S) {} //~^ needless_pass_by_value - fn issue_2114(s: String, t: String, u: Vec, v: Vec) { -//~^ needless_pass_by_value -//~| needless_pass_by_value -//~| needless_pass_by_value -//~| needless_pass_by_value - - - + //~^ needless_pass_by_value + //~| needless_pass_by_value + //~| needless_pass_by_value + //~| needless_pass_by_value s.capacity(); let _ = t.clone(); @@ -119,10 +112,8 @@ impl S { // taking `self` by value is always allowed s: String, //~^ needless_pass_by_value - t: String, //~^ needless_pass_by_value - ) -> usize { s.len() + t.capacity() } @@ -134,8 +125,6 @@ impl S { fn baz(&self, uu: U, ss: Self) {} //~^ needless_pass_by_value //~| needless_pass_by_value - - } trait FalsePositive { @@ -158,7 +147,7 @@ fn range>(range: T) { struct CopyWrapper(u32); fn bar_copy(x: u32, y: CopyWrapper) { -//~^ needless_pass_by_value + //~^ needless_pass_by_value assert_eq!(x, 42); assert_eq!(y.0, 42); @@ -166,11 +155,9 @@ fn bar_copy(x: u32, y: CopyWrapper) { // x and y should be warned, but z is ok fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { -//~^ needless_pass_by_value -//~| needless_pass_by_value -//~| needless_pass_by_value - - + //~^ needless_pass_by_value + //~| needless_pass_by_value + //~| needless_pass_by_value let CopyWrapper(s) = z; // moved let CopyWrapper(ref t) = y; // not moved @@ -186,14 +173,12 @@ impl<'b, T> Bar<'b, T> for T {} fn some_fun<'b, S: Bar<'b, ()>>(items: S) {} //~^ needless_pass_by_value - // Also this should not cause an ICE. See #2831 trait Club<'a, A> {} impl Club<'static, T> for T {} fn more_fun(items: impl Club<'static, i32>) {} //~^ needless_pass_by_value - fn is_sync(_: T) where T: Sync, diff --git a/tests/ui/needless_pass_by_value.stderr b/tests/ui/needless_pass_by_value.stderr index 414ce347403a..47e008688215 100644 --- a/tests/ui/needless_pass_by_value.stderr +++ b/tests/ui/needless_pass_by_value.stderr @@ -8,55 +8,55 @@ LL | fn foo(v: Vec, w: Vec, mut x: Vec, y: Vec) -> Vec tests/ui/needless_pass_by_value.rs:36:11 + --> tests/ui/needless_pass_by_value.rs:35:11 | LL | fn bar(x: String, y: Wrapper) { | ^^^^^^ help: consider changing the type to: `&str` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:36:22 + --> tests/ui/needless_pass_by_value.rs:35:22 | LL | fn bar(x: String, y: Wrapper) { | ^^^^^^^ help: consider taking a reference instead: `&Wrapper` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:46:71 + --> tests/ui/needless_pass_by_value.rs:44:71 | LL | fn test_borrow_trait, U: AsRef, V>(t: T, u: U, v: V) { | ^ help: consider taking a reference instead: `&V` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:60:18 + --> tests/ui/needless_pass_by_value.rs:58:18 | LL | fn test_match(x: Option>, y: Option>) { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&Option>` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:75:24 + --> tests/ui/needless_pass_by_value.rs:73:24 | LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) { | ^^^^^^^ help: consider taking a reference instead: `&Wrapper` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:75:36 + --> tests/ui/needless_pass_by_value.rs:73:36 | LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) { | ^^^^^^^ help: consider taking a reference instead: `&Wrapper` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:95:49 + --> tests/ui/needless_pass_by_value.rs:92:49 | LL | fn test_blanket_ref(vals: T, serializable: S) {} | ^ help: consider taking a reference instead: `&T` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:99:18 + --> tests/ui/needless_pass_by_value.rs:95:18 | LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | ^^^^^^ help: consider taking a reference instead: `&String` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:99:29 + --> tests/ui/needless_pass_by_value.rs:95:29 | LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | ^^^^^^ @@ -71,13 +71,13 @@ LL | let _ = t.to_string(); | ~~~~~~~~~~~~~ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:99:40 + --> tests/ui/needless_pass_by_value.rs:95:40 | LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | ^^^^^^^^ help: consider taking a reference instead: `&Vec` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:99:53 + --> tests/ui/needless_pass_by_value.rs:95:53 | LL | fn issue_2114(s: String, t: String, u: Vec, v: Vec) { | ^^^^^^^^ @@ -92,85 +92,85 @@ LL | let _ = v.to_owned(); | ~~~~~~~~~~~~ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:120:12 + --> tests/ui/needless_pass_by_value.rs:113:12 | LL | s: String, | ^^^^^^ help: consider changing the type to: `&str` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:123:12 + --> tests/ui/needless_pass_by_value.rs:115:12 | LL | t: String, | ^^^^^^ help: consider taking a reference instead: `&String` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:134:23 + --> tests/ui/needless_pass_by_value.rs:125:23 | LL | fn baz(&self, uu: U, ss: Self) {} | ^ help: consider taking a reference instead: `&U` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:134:30 + --> tests/ui/needless_pass_by_value.rs:125:30 | LL | fn baz(&self, uu: U, ss: Self) {} | ^^^^ help: consider taking a reference instead: `&Self` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:160:24 + --> tests/ui/needless_pass_by_value.rs:149:24 | LL | fn bar_copy(x: u32, y: CopyWrapper) { | ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper` | help: or consider marking this type as `Copy` - --> tests/ui/needless_pass_by_value.rs:158:1 + --> tests/ui/needless_pass_by_value.rs:147:1 | LL | struct CopyWrapper(u32); | ^^^^^^^^^^^^^^^^^^ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:168:29 + --> tests/ui/needless_pass_by_value.rs:157:29 | LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { | ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper` | help: or consider marking this type as `Copy` - --> tests/ui/needless_pass_by_value.rs:158:1 + --> tests/ui/needless_pass_by_value.rs:147:1 | LL | struct CopyWrapper(u32); | ^^^^^^^^^^^^^^^^^^ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:168:45 + --> tests/ui/needless_pass_by_value.rs:157:45 | LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { | ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper` | help: or consider marking this type as `Copy` - --> tests/ui/needless_pass_by_value.rs:158:1 + --> tests/ui/needless_pass_by_value.rs:147:1 | LL | struct CopyWrapper(u32); | ^^^^^^^^^^^^^^^^^^ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:168:61 + --> tests/ui/needless_pass_by_value.rs:157:61 | LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) { | ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper` | help: or consider marking this type as `Copy` - --> tests/ui/needless_pass_by_value.rs:158:1 + --> tests/ui/needless_pass_by_value.rs:147:1 | LL | struct CopyWrapper(u32); | ^^^^^^^^^^^^^^^^^^ error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:186:40 + --> tests/ui/needless_pass_by_value.rs:173:40 | LL | fn some_fun<'b, S: Bar<'b, ()>>(items: S) {} | ^ help: consider taking a reference instead: `&S` error: this argument is passed by value, but not consumed in the function body - --> tests/ui/needless_pass_by_value.rs:193:20 + --> tests/ui/needless_pass_by_value.rs:179:20 | LL | fn more_fun(items: impl Club<'static, i32>) {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&impl Club<'static, i32>` diff --git a/tests/ui/needless_range_loop.rs b/tests/ui/needless_range_loop.rs index ff9699e35691..8a1c1be289cf 100644 --- a/tests/ui/needless_range_loop.rs +++ b/tests/ui/needless_range_loop.rs @@ -14,8 +14,7 @@ fn main() { let mut vec = vec![1, 2, 3, 4]; let vec2 = vec![1, 2, 3, 4]; for i in 0..vec.len() { - //~^ needless_range_loop - + //~^ needless_range_loop println!("{}", vec[i]); } @@ -26,26 +25,26 @@ fn main() { } for i in 0..vec.len() { - //~^ needless_range_loop + //~^ needless_range_loop let _ = vec[i]; } // ICE #746 for j in 0..4 { - //~^ needless_range_loop + //~^ needless_range_loop println!("{:?}", STATIC[j]); } for j in 0..4 { - //~^ needless_range_loop + //~^ needless_range_loop println!("{:?}", CONST[j]); } for i in 0..vec.len() { - //~^ needless_range_loop + //~^ needless_range_loop println!("{} {}", vec[i], i); } @@ -55,56 +54,56 @@ fn main() { } for i in 0..vec.len() { - //~^ needless_range_loop + //~^ needless_range_loop println!("{}", vec2[i]); } for i in 5..vec.len() { - //~^ needless_range_loop + //~^ needless_range_loop println!("{}", vec[i]); } for i in 0..MAX_LEN { - //~^ needless_range_loop + //~^ needless_range_loop println!("{}", vec[i]); } for i in 0..=MAX_LEN { - //~^ needless_range_loop + //~^ needless_range_loop println!("{}", vec[i]); } for i in 5..10 { - //~^ needless_range_loop + //~^ needless_range_loop println!("{}", vec[i]); } for i in 5..=10 { - //~^ needless_range_loop + //~^ needless_range_loop println!("{}", vec[i]); } for i in 5..vec.len() { - //~^ needless_range_loop + //~^ needless_range_loop println!("{} {}", vec[i], i); } for i in 5..10 { - //~^ needless_range_loop + //~^ needless_range_loop println!("{} {}", vec[i], i); } // #2542 for i in 0..vec.len() { - //~^ needless_range_loop + //~^ needless_range_loop vec[i] = Some(1).unwrap_or_else(|| panic!("error on {}", i)); } diff --git a/tests/ui/needless_range_loop.stderr b/tests/ui/needless_range_loop.stderr index a15830d721b6..86c2b550b071 100644 --- a/tests/ui/needless_range_loop.stderr +++ b/tests/ui/needless_range_loop.stderr @@ -12,7 +12,7 @@ LL | for in &vec { | ~~~~~~ ~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:28:14 + --> tests/ui/needless_range_loop.rs:27:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | for in &vec { | ~~~~~~ ~~~~ error: the loop variable `j` is only used to index `STATIC` - --> tests/ui/needless_range_loop.rs:35:14 + --> tests/ui/needless_range_loop.rs:34:14 | LL | for j in 0..4 { | ^^^^ @@ -34,7 +34,7 @@ LL | for in &STATIC { | ~~~~~~ ~~~~~~~ error: the loop variable `j` is only used to index `CONST` - --> tests/ui/needless_range_loop.rs:41:14 + --> tests/ui/needless_range_loop.rs:40:14 | LL | for j in 0..4 { | ^^^^ @@ -45,7 +45,7 @@ LL | for in &CONST { | ~~~~~~ ~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:47:14 + --> tests/ui/needless_range_loop.rs:46:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | for (i, ) in vec.iter().enumerate() { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec2` - --> tests/ui/needless_range_loop.rs:57:14 + --> tests/ui/needless_range_loop.rs:56:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | for in vec2.iter().take(vec.len()) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:63:14 + --> tests/ui/needless_range_loop.rs:62:14 | LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | for in vec.iter().skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:69:14 + --> tests/ui/needless_range_loop.rs:68:14 | LL | for i in 0..MAX_LEN { | ^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | for in vec.iter().take(MAX_LEN) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:75:14 + --> tests/ui/needless_range_loop.rs:74:14 | LL | for i in 0..=MAX_LEN { | ^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | for in vec.iter().take(MAX_LEN + 1) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:81:14 + --> tests/ui/needless_range_loop.rs:80:14 | LL | for i in 5..10 { | ^^^^^ @@ -111,7 +111,7 @@ LL | for in vec.iter().take(10).skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop.rs:87:14 + --> tests/ui/needless_range_loop.rs:86:14 | LL | for i in 5..=10 { | ^^^^^^ @@ -122,7 +122,7 @@ LL | for in vec.iter().take(10 + 1).skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:93:14 + --> tests/ui/needless_range_loop.rs:92:14 | LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | for (i, ) in vec.iter().enumerate().skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:99:14 + --> tests/ui/needless_range_loop.rs:98:14 | LL | for i in 5..10 { | ^^^^^ @@ -144,7 +144,7 @@ LL | for (i, ) in vec.iter().enumerate().take(10).skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> tests/ui/needless_range_loop.rs:106:14 + --> tests/ui/needless_range_loop.rs:105:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ diff --git a/tests/ui/needless_range_loop2.rs b/tests/ui/needless_range_loop2.rs index 8a591a4bddae..68784a8df19d 100644 --- a/tests/ui/needless_range_loop2.rs +++ b/tests/ui/needless_range_loop2.rs @@ -9,8 +9,7 @@ fn main() { let ns = vec![2, 3, 5, 7]; for i in 3..10 { - //~^ needless_range_loop - + //~^ needless_range_loop println!("{}", ns[i]); } @@ -33,7 +32,7 @@ fn main() { let mut ms = vec![1, 2, 3, 4, 5, 6]; for i in 0..ms.len() { - //~^ needless_range_loop + //~^ needless_range_loop ms[i] *= 2; } @@ -41,7 +40,7 @@ fn main() { let mut ms = vec![1, 2, 3, 4, 5, 6]; for i in 0..ms.len() { - //~^ needless_range_loop + //~^ needless_range_loop let x = &mut ms[i]; *x *= 2; @@ -67,7 +66,7 @@ fn main() { let mut vec = vec![0; 9]; for i in x..x + 4 { - //~^ needless_range_loop + //~^ needless_range_loop vec[i] += 1; } @@ -76,7 +75,7 @@ fn main() { let mut vec = vec![0; 10]; for i in x..=x + 4 { - //~^ needless_range_loop + //~^ needless_range_loop vec[i] += 1; } @@ -84,19 +83,19 @@ fn main() { let arr = [1, 2, 3]; for i in 0..3 { - //~^ needless_range_loop + //~^ needless_range_loop println!("{}", arr[i]); } for i in 0..2 { - //~^ needless_range_loop + //~^ needless_range_loop println!("{}", arr[i]); } for i in 1..3 { - //~^ needless_range_loop + //~^ needless_range_loop println!("{}", arr[i]); } diff --git a/tests/ui/needless_range_loop2.stderr b/tests/ui/needless_range_loop2.stderr index 34357c3db02f..0531e8e8f856 100644 --- a/tests/ui/needless_range_loop2.stderr +++ b/tests/ui/needless_range_loop2.stderr @@ -12,7 +12,7 @@ LL | for in ns.iter().take(10).skip(3) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `ms` - --> tests/ui/needless_range_loop2.rs:35:14 + --> tests/ui/needless_range_loop2.rs:34:14 | LL | for i in 0..ms.len() { | ^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | for in &mut ms { | ~~~~~~ ~~~~~~~ error: the loop variable `i` is only used to index `ms` - --> tests/ui/needless_range_loop2.rs:43:14 + --> tests/ui/needless_range_loop2.rs:42:14 | LL | for i in 0..ms.len() { | ^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | for in &mut ms { | ~~~~~~ ~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop2.rs:69:14 + --> tests/ui/needless_range_loop2.rs:68:14 | LL | for i in x..x + 4 { | ^^^^^^^^ @@ -45,7 +45,7 @@ LL | for in vec.iter_mut().skip(x).take(4) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> tests/ui/needless_range_loop2.rs:78:14 + --> tests/ui/needless_range_loop2.rs:77:14 | LL | for i in x..=x + 4 { | ^^^^^^^^^ @@ -56,7 +56,7 @@ LL | for in vec.iter_mut().skip(x).take(4 + 1) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `arr` - --> tests/ui/needless_range_loop2.rs:86:14 + --> tests/ui/needless_range_loop2.rs:85:14 | LL | for i in 0..3 { | ^^^^ @@ -67,7 +67,7 @@ LL | for in &arr { | ~~~~~~ ~~~~ error: the loop variable `i` is only used to index `arr` - --> tests/ui/needless_range_loop2.rs:92:14 + --> tests/ui/needless_range_loop2.rs:91:14 | LL | for i in 0..2 { | ^^^^ @@ -78,7 +78,7 @@ LL | for in arr.iter().take(2) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `arr` - --> tests/ui/needless_range_loop2.rs:98:14 + --> tests/ui/needless_range_loop2.rs:97:14 | LL | for i in 1..3 { | ^^^^ diff --git a/tests/ui/needless_update.rs b/tests/ui/needless_update.rs index 6e91c957e811..62e349234319 100644 --- a/tests/ui/needless_update.rs +++ b/tests/ui/needless_update.rs @@ -19,8 +19,6 @@ fn main() { S { a: 1, b: 1, ..base }; //~^ needless_update - - let base = T { x: 0, y: 0 }; T { ..base }; // no error T { x: 1, ..base }; // no error diff --git a/tests/ui/neg_cmp_op_on_partial_ord.rs b/tests/ui/neg_cmp_op_on_partial_ord.rs index 7d24429b5867..27b51b428170 100644 --- a/tests/ui/neg_cmp_op_on_partial_ord.rs +++ b/tests/ui/neg_cmp_op_on_partial_ord.rs @@ -16,23 +16,18 @@ fn main() { let _not_less = !(a_value < another_value); //~^ neg_cmp_op_on_partial_ord - - // Not Less or Equal but potentially Greater or Uncomparable. let _not_less_or_equal = !(a_value <= another_value); //~^ neg_cmp_op_on_partial_ord - // Not Greater but potentially Less, Equal or Uncomparable. let _not_greater = !(a_value > another_value); //~^ neg_cmp_op_on_partial_ord - // Not Greater or Equal but potentially Less or Uncomparable. let _not_greater_or_equal = !(a_value >= another_value); //~^ neg_cmp_op_on_partial_ord - // --- Good --- let _not_less = match a_value.partial_cmp(&another_value) { diff --git a/tests/ui/neg_cmp_op_on_partial_ord.stderr b/tests/ui/neg_cmp_op_on_partial_ord.stderr index f6347b7d56cd..3c11d5b8826a 100644 --- a/tests/ui/neg_cmp_op_on_partial_ord.stderr +++ b/tests/ui/neg_cmp_op_on_partial_ord.stderr @@ -8,19 +8,19 @@ LL | let _not_less = !(a_value < another_value); = help: to override `-D warnings` add `#[allow(clippy::neg_cmp_op_on_partial_ord)]` error: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable - --> tests/ui/neg_cmp_op_on_partial_ord.rs:22:30 + --> tests/ui/neg_cmp_op_on_partial_ord.rs:20:30 | LL | let _not_less_or_equal = !(a_value <= another_value); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable - --> tests/ui/neg_cmp_op_on_partial_ord.rs:27:24 + --> tests/ui/neg_cmp_op_on_partial_ord.rs:24:24 | LL | let _not_greater = !(a_value > another_value); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable - --> tests/ui/neg_cmp_op_on_partial_ord.rs:32:33 + --> tests/ui/neg_cmp_op_on_partial_ord.rs:28:33 | LL | let _not_greater_or_equal = !(a_value >= another_value); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/never_loop.rs b/tests/ui/never_loop.rs index c366e7d86310..2d8e04c192e4 100644 --- a/tests/ui/never_loop.rs +++ b/tests/ui/never_loop.rs @@ -10,8 +10,7 @@ fn test1() { let mut x = 0; loop { - //~^ never_loop - + //~^ never_loop // clippy::never_loop x += 1; @@ -35,7 +34,7 @@ fn test2() { fn test3() { let mut x = 0; loop { - //~^ never_loop + //~^ never_loop // never loops x += 1; @@ -57,11 +56,11 @@ fn test4() { fn test5() { let i = 0; loop { - //~^ never_loop + //~^ never_loop // never loops while i == 0 { - //~^ never_loop + //~^ never_loop // never loops break; @@ -75,7 +74,7 @@ fn test6() { 'outer: loop { x += 1; loop { - //~^ never_loop + //~^ never_loop // never loops if x == 5 { @@ -113,7 +112,7 @@ fn test8() { fn test9() { let x = Some(1); while let Some(y) = x { - //~^ never_loop + //~^ never_loop // never loops return; @@ -122,7 +121,7 @@ fn test9() { fn test10() { for x in 0..10 { - //~^ never_loop + //~^ never_loop // never loops match x { @@ -172,7 +171,7 @@ pub fn test13() { pub fn test14() { let mut a = true; 'outer: while a { - //~^ never_loop + //~^ never_loop // never loops while a { @@ -189,7 +188,7 @@ pub fn test14() { pub fn test15() { 'label: loop { while false { - //~^ never_loop + //~^ never_loop break 'label; } @@ -242,7 +241,7 @@ pub fn test18() { }; // never loops let _ = loop { - //~^ never_loop + //~^ never_loop let Some(x) = x else { return; @@ -265,14 +264,12 @@ pub fn test19() { pub fn test20() { 'a: loop { - //~^ never_loop + //~^ never_loop 'b: { break 'b 'c: { break 'a; //~^ diverging_sub_expression - - }; } } @@ -304,7 +301,7 @@ pub fn test23() { for _ in 0..10 { 'block: { for _ in 0..20 { - //~^ never_loop + //~^ never_loop break 'block; } @@ -389,7 +386,7 @@ pub fn test31(b: bool) { 'a: loop { 'b: { 'c: loop { - //~^ never_loop + //~^ never_loop if b { break 'c } else { break 'b } } @@ -401,12 +398,12 @@ pub fn test31(b: bool) { pub fn test32() { loop { - //~^ never_loop + //~^ never_loop panic!("oh no"); } loop { - //~^ never_loop + //~^ never_loop unimplemented!("not yet"); } diff --git a/tests/ui/never_loop.stderr b/tests/ui/never_loop.stderr index 6d492f8eb9da..72bf8da51dfe 100644 --- a/tests/ui/never_loop.stderr +++ b/tests/ui/never_loop.stderr @@ -10,7 +10,7 @@ LL | | } = note: `#[deny(clippy::never_loop)]` on by default error: this loop never actually loops - --> tests/ui/never_loop.rs:37:5 + --> tests/ui/never_loop.rs:36:5 | LL | / loop { ... | @@ -19,7 +19,7 @@ LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:59:5 + --> tests/ui/never_loop.rs:58:5 | LL | / loop { ... | @@ -28,7 +28,7 @@ LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:63:9 + --> tests/ui/never_loop.rs:62:9 | LL | / while i == 0 { ... | @@ -36,7 +36,7 @@ LL | | } | |_________^ error: this loop never actually loops - --> tests/ui/never_loop.rs:77:9 + --> tests/ui/never_loop.rs:76:9 | LL | / loop { ... | @@ -45,7 +45,7 @@ LL | | } | |_________^ error: this loop never actually loops - --> tests/ui/never_loop.rs:115:5 + --> tests/ui/never_loop.rs:114:5 | LL | / while let Some(y) = x { ... | @@ -53,7 +53,7 @@ LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:124:5 + --> tests/ui/never_loop.rs:123:5 | LL | / for x in 0..10 { ... | @@ -66,7 +66,7 @@ LL | if let Some(x) = (0..10).next() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: this loop never actually loops - --> tests/ui/never_loop.rs:174:5 + --> tests/ui/never_loop.rs:173:5 | LL | / 'outer: while a { ... | @@ -75,7 +75,7 @@ LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:191:9 + --> tests/ui/never_loop.rs:190:9 | LL | / while false { LL | | @@ -85,7 +85,7 @@ LL | | } | |_________^ error: this loop never actually loops - --> tests/ui/never_loop.rs:244:13 + --> tests/ui/never_loop.rs:243:13 | LL | let _ = loop { | _____________^ @@ -98,7 +98,7 @@ LL | | }; | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:267:5 + --> tests/ui/never_loop.rs:266:5 | LL | / 'a: loop { LL | | @@ -109,7 +109,7 @@ LL | | } | |_____^ error: sub-expression diverges - --> tests/ui/never_loop.rs:272:17 + --> tests/ui/never_loop.rs:271:17 | LL | break 'a; | ^^^^^^^^ @@ -118,7 +118,7 @@ LL | break 'a; = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]` error: this loop never actually loops - --> tests/ui/never_loop.rs:306:13 + --> tests/ui/never_loop.rs:303:13 | LL | / for _ in 0..20 { LL | | @@ -133,7 +133,7 @@ LL | if let Some(_) = (0..20).next() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: this loop never actually loops - --> tests/ui/never_loop.rs:391:13 + --> tests/ui/never_loop.rs:388:13 | LL | / 'c: loop { LL | | @@ -143,7 +143,7 @@ LL | | } | |_____________^ error: this loop never actually loops - --> tests/ui/never_loop.rs:403:5 + --> tests/ui/never_loop.rs:400:5 | LL | / loop { LL | | @@ -153,7 +153,7 @@ LL | | } | |_____^ error: this loop never actually loops - --> tests/ui/never_loop.rs:408:5 + --> tests/ui/never_loop.rs:405:5 | LL | / loop { LL | | diff --git a/tests/ui/new_ret_no_self.rs b/tests/ui/new_ret_no_self.rs index fc7dea97e48a..d61973f09b17 100644 --- a/tests/ui/new_ret_no_self.rs +++ b/tests/ui/new_ret_no_self.rs @@ -48,8 +48,7 @@ impl R for S3 { impl S3 { // should trigger the lint pub fn new(_: String) -> impl R { - //~^ new_ret_no_self - + //~^ new_ret_no_self S3 } @@ -83,7 +82,7 @@ struct U; impl U { // should trigger lint pub fn new() -> u32 { - //~^ new_ret_no_self + //~^ new_ret_no_self unimplemented!(); } @@ -94,7 +93,7 @@ struct V; impl V { // should trigger lint pub fn new(_: String) -> u32 { - //~^ new_ret_no_self + //~^ new_ret_no_self unimplemented!(); } @@ -132,7 +131,7 @@ struct TupleReturnerBad; impl TupleReturnerBad { // should trigger lint pub fn new() -> (u32, u32) { - //~^ new_ret_no_self + //~^ new_ret_no_self unimplemented!(); } @@ -161,7 +160,7 @@ struct MutPointerReturnerBad; impl MutPointerReturnerBad { // should trigger lint pub fn new() -> *mut V { - //~^ new_ret_no_self + //~^ new_ret_no_self unimplemented!(); } @@ -181,7 +180,7 @@ struct GenericReturnerBad; impl GenericReturnerBad { // should trigger lint pub fn new() -> Option { - //~^ new_ret_no_self + //~^ new_ret_no_self unimplemented!(); } @@ -237,7 +236,6 @@ mod issue5435 { // should trigger lint as we are in trait definition fn new() -> String; //~^ new_ret_no_self - } pub struct StructRet; impl TraitRet for StructRet { @@ -251,7 +249,6 @@ mod issue5435 { // should trigger lint fn new(_: String) -> String; //~^ new_ret_no_self - } trait TupleReturnerOk { @@ -287,7 +284,7 @@ mod issue5435 { trait TupleReturnerBad { // should trigger lint fn new() -> (u32, u32) { - //~^ new_ret_no_self + //~^ new_ret_no_self unimplemented!(); } @@ -316,7 +313,7 @@ mod issue5435 { trait MutPointerReturnerBad { // should trigger lint fn new() -> *mut V { - //~^ new_ret_no_self + //~^ new_ret_no_self unimplemented!(); } @@ -388,7 +385,7 @@ mod issue7344 { impl RetImplTraitNoSelf { // should trigger lint fn new(t: T) -> impl Into { - //~^ new_ret_no_self + //~^ new_ret_no_self 1 } @@ -409,8 +406,7 @@ mod issue7344 { impl RetImplTraitNoSelf2 { // should trigger lint fn new(t: T) -> impl Trait2<(), i32> { - //~^ new_ret_no_self - + //~^ new_ret_no_self } } diff --git a/tests/ui/new_ret_no_self.stderr b/tests/ui/new_ret_no_self.stderr index e31282c3fb7e..a758c746f918 100644 --- a/tests/ui/new_ret_no_self.stderr +++ b/tests/ui/new_ret_no_self.stderr @@ -2,7 +2,9 @@ error: methods called `new` usually return `Self` --> tests/ui/new_ret_no_self.rs:50:5 | LL | / pub fn new(_: String) -> impl R { -... | +LL | | +LL | | +LL | | S3 LL | | } | |_____^ | @@ -10,7 +12,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::new_ret_no_self)]` error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:85:5 + --> tests/ui/new_ret_no_self.rs:84:5 | LL | / pub fn new() -> u32 { LL | | @@ -20,7 +22,7 @@ LL | | } | |_____^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:96:5 + --> tests/ui/new_ret_no_self.rs:95:5 | LL | / pub fn new(_: String) -> u32 { LL | | @@ -30,7 +32,7 @@ LL | | } | |_____^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:134:5 + --> tests/ui/new_ret_no_self.rs:133:5 | LL | / pub fn new() -> (u32, u32) { LL | | @@ -40,7 +42,7 @@ LL | | } | |_____^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:163:5 + --> tests/ui/new_ret_no_self.rs:162:5 | LL | / pub fn new() -> *mut V { LL | | @@ -50,7 +52,7 @@ LL | | } | |_____^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:183:5 + --> tests/ui/new_ret_no_self.rs:182:5 | LL | / pub fn new() -> Option { LL | | @@ -60,19 +62,19 @@ LL | | } | |_____^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:238:9 + --> tests/ui/new_ret_no_self.rs:237:9 | LL | fn new() -> String; | ^^^^^^^^^^^^^^^^^^^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:252:9 + --> tests/ui/new_ret_no_self.rs:250:9 | LL | fn new(_: String) -> String; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:289:9 + --> tests/ui/new_ret_no_self.rs:286:9 | LL | / fn new() -> (u32, u32) { LL | | @@ -82,7 +84,7 @@ LL | | } | |_________^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:318:9 + --> tests/ui/new_ret_no_self.rs:315:9 | LL | / fn new() -> *mut V { LL | | @@ -92,7 +94,7 @@ LL | | } | |_________^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:390:9 + --> tests/ui/new_ret_no_self.rs:387:9 | LL | / fn new(t: T) -> impl Into { LL | | @@ -102,10 +104,10 @@ LL | | } | |_________^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:411:9 + --> tests/ui/new_ret_no_self.rs:408:9 | LL | / fn new(t: T) -> impl Trait2<(), i32> { -... | +LL | | LL | | } | |_________^ diff --git a/tests/ui/new_ret_no_self_overflow.rs b/tests/ui/new_ret_no_self_overflow.rs index db7ce9c4054e..8a85c5662276 100644 --- a/tests/ui/new_ret_no_self_overflow.rs +++ b/tests/ui/new_ret_no_self_overflow.rs @@ -18,7 +18,7 @@ mod issue10041 { impl Bomb2 { pub fn new() -> X { - //~^ ERROR: overflow evaluating the requirement + //~^ ERROR: overflow evaluating the requirement 0i32 } } diff --git a/tests/ui/new_without_default.fixed b/tests/ui/new_without_default.fixed index 8fd703200835..277c335cd885 100644 --- a/tests/ui/new_without_default.fixed +++ b/tests/ui/new_without_default.fixed @@ -17,8 +17,7 @@ impl Default for Foo { impl Foo { pub fn new() -> Foo { - //~^ new_without_default - + //~^ new_without_default Foo } @@ -34,7 +33,7 @@ impl Default for Bar { impl Bar { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default Bar } @@ -106,7 +105,7 @@ impl<'c> Default for LtKo<'c> { impl<'c> LtKo<'c> { pub fn new() -> LtKo<'c> { - //~^ new_without_default + //~^ new_without_default unimplemented!() } @@ -146,7 +145,7 @@ impl Default for Const { impl Const { pub const fn new() -> Const { - //~^ new_without_default + //~^ new_without_default Const } // While Default is not const, it can still call const functions, so we should lint this } @@ -213,7 +212,7 @@ impl Default for NewNotEqualToDerive { impl NewNotEqualToDerive { // This `new` implementation is not equal to a derived `Default`, so do not suggest deriving. pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default NewNotEqualToDerive { foo: 1 } } @@ -229,7 +228,7 @@ impl Default for FooGenerics { impl FooGenerics { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default Self(Default::default()) } @@ -244,7 +243,7 @@ impl Default for BarGenerics { impl BarGenerics { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default Self(Default::default()) } @@ -263,7 +262,7 @@ pub mod issue7220 { impl Foo { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default todo!() } @@ -319,7 +318,7 @@ where K: std::hash::Hash + Eq + PartialEq, { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default Self { _kv: None } } } diff --git a/tests/ui/new_without_default.rs b/tests/ui/new_without_default.rs index 856f515e4aba..f2844897c93d 100644 --- a/tests/ui/new_without_default.rs +++ b/tests/ui/new_without_default.rs @@ -11,8 +11,7 @@ pub struct Foo; impl Foo { pub fn new() -> Foo { - //~^ new_without_default - + //~^ new_without_default Foo } @@ -22,7 +21,7 @@ pub struct Bar; impl Bar { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default Bar } @@ -88,7 +87,7 @@ pub struct LtKo<'a> { impl<'c> LtKo<'c> { pub fn new() -> LtKo<'c> { - //~^ new_without_default + //~^ new_without_default unimplemented!() } @@ -122,7 +121,7 @@ pub struct Const; impl Const { pub const fn new() -> Const { - //~^ new_without_default + //~^ new_without_default Const } // While Default is not const, it can still call const functions, so we should lint this } @@ -183,7 +182,7 @@ pub struct NewNotEqualToDerive { impl NewNotEqualToDerive { // This `new` implementation is not equal to a derived `Default`, so do not suggest deriving. pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default NewNotEqualToDerive { foo: 1 } } @@ -193,7 +192,7 @@ impl NewNotEqualToDerive { pub struct FooGenerics(std::marker::PhantomData); impl FooGenerics { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default Self(Default::default()) } @@ -202,7 +201,7 @@ impl FooGenerics { pub struct BarGenerics(std::marker::PhantomData); impl BarGenerics { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default Self(Default::default()) } @@ -215,7 +214,7 @@ pub mod issue7220 { impl Foo { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default todo!() } @@ -262,7 +261,7 @@ where K: std::hash::Hash + Eq + PartialEq, { pub fn new() -> Self { - //~^ new_without_default + //~^ new_without_default Self { _kv: None } } } diff --git a/tests/ui/new_without_default.stderr b/tests/ui/new_without_default.stderr index 1a122d341a08..70a65aba464b 100644 --- a/tests/ui/new_without_default.stderr +++ b/tests/ui/new_without_default.stderr @@ -2,7 +2,9 @@ error: you should consider adding a `Default` implementation for `Foo` --> tests/ui/new_without_default.rs:13:5 | LL | / pub fn new() -> Foo { -... | +LL | | +LL | | +LL | | Foo LL | | } | |_____^ | @@ -18,7 +20,7 @@ LL + } | error: you should consider adding a `Default` implementation for `Bar` - --> tests/ui/new_without_default.rs:24:5 + --> tests/ui/new_without_default.rs:23:5 | LL | / pub fn new() -> Self { LL | | @@ -37,7 +39,7 @@ LL + } | error: you should consider adding a `Default` implementation for `LtKo<'c>` - --> tests/ui/new_without_default.rs:90:5 + --> tests/ui/new_without_default.rs:89:5 | LL | / pub fn new() -> LtKo<'c> { LL | | @@ -56,7 +58,7 @@ LL + } | error: you should consider adding a `Default` implementation for `Const` - --> tests/ui/new_without_default.rs:124:5 + --> tests/ui/new_without_default.rs:123:5 | LL | / pub const fn new() -> Const { LL | | @@ -74,7 +76,7 @@ LL + } | error: you should consider adding a `Default` implementation for `NewNotEqualToDerive` - --> tests/ui/new_without_default.rs:185:5 + --> tests/ui/new_without_default.rs:184:5 | LL | / pub fn new() -> Self { LL | | @@ -93,7 +95,7 @@ LL + } | error: you should consider adding a `Default` implementation for `FooGenerics` - --> tests/ui/new_without_default.rs:195:5 + --> tests/ui/new_without_default.rs:194:5 | LL | / pub fn new() -> Self { LL | | @@ -112,7 +114,7 @@ LL + } | error: you should consider adding a `Default` implementation for `BarGenerics` - --> tests/ui/new_without_default.rs:204:5 + --> tests/ui/new_without_default.rs:203:5 | LL | / pub fn new() -> Self { LL | | @@ -131,7 +133,7 @@ LL + } | error: you should consider adding a `Default` implementation for `Foo` - --> tests/ui/new_without_default.rs:217:9 + --> tests/ui/new_without_default.rs:216:9 | LL | / pub fn new() -> Self { LL | | @@ -152,7 +154,7 @@ LL ~ impl Foo { | error: you should consider adding a `Default` implementation for `MyStruct` - --> tests/ui/new_without_default.rs:264:5 + --> tests/ui/new_without_default.rs:263:5 | LL | / pub fn new() -> Self { LL | | diff --git a/tests/ui/no_effect.rs b/tests/ui/no_effect.rs index cd992aed15e2..703c2a3d9847 100644 --- a/tests/ui/no_effect.rs +++ b/tests/ui/no_effect.rs @@ -186,7 +186,6 @@ fn main() { let _unused = 1; //~^ no_effect_underscore_binding - let _penguin = || println!("Some helpful closure"); //~^ no_effect_underscore_binding diff --git a/tests/ui/no_effect.stderr b/tests/ui/no_effect.stderr index 617a43aaf60d..58a9380cbfde 100644 --- a/tests/ui/no_effect.stderr +++ b/tests/ui/no_effect.stderr @@ -149,19 +149,19 @@ LL | let _unused = 1; = help: to override `-D warnings` add `#[allow(clippy::no_effect_underscore_binding)]` error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect.rs:190:9 + --> tests/ui/no_effect.rs:189:9 | LL | let _penguin = || println!("Some helpful closure"); | ^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect.rs:193:9 + --> tests/ui/no_effect.rs:192:9 | LL | let _duck = Struct { field: 0 }; | ^^^^^ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect.rs:196:9 + --> tests/ui/no_effect.rs:195:9 | LL | let _cat = [2, 4, 6, 8][2]; | ^^^^ diff --git a/tests/ui/no_effect_async_fn.rs b/tests/ui/no_effect_async_fn.rs index 6fb3ccab8a08..a036a7e27bef 100644 --- a/tests/ui/no_effect_async_fn.rs +++ b/tests/ui/no_effect_async_fn.rs @@ -13,7 +13,6 @@ impl AsyncTrait for Bar { let _a = 0; //~^ no_effect_underscore_binding - // Shouldn't lint `binding to `_` prefixed variable with no side-effect` let _b = num(); @@ -21,7 +20,6 @@ impl AsyncTrait for Bar { let _c = 0; //~^ no_effect_underscore_binding - // Shouldn't lint `binding to `_` prefixed variable with no side-effect` let _d = num(); } @@ -34,7 +32,6 @@ async fn foo(_i: u64) { let _a = 0; //~^ no_effect_underscore_binding - // Shouldn't lint `binding to `_` prefixed variable with no side-effect` let _b = num(); @@ -42,7 +39,6 @@ async fn foo(_i: u64) { let _c = 0; //~^ no_effect_underscore_binding - // Shouldn't lint `binding to `_` prefixed variable with no side-effect` let _d = num(); } diff --git a/tests/ui/no_effect_async_fn.stderr b/tests/ui/no_effect_async_fn.stderr index 96ad7b9d6075..2325eb9aae59 100644 --- a/tests/ui/no_effect_async_fn.stderr +++ b/tests/ui/no_effect_async_fn.stderr @@ -1,5 +1,5 @@ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect_async_fn.rs:21:17 + --> tests/ui/no_effect_async_fn.rs:20:17 | LL | let _c = 0; | ^^ @@ -14,13 +14,13 @@ LL | let _a = 0; | ^^ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect_async_fn.rs:42:13 + --> tests/ui/no_effect_async_fn.rs:39:13 | LL | let _c = 0; | ^^ error: binding to `_` prefixed variable with no side-effect - --> tests/ui/no_effect_async_fn.rs:34:9 + --> tests/ui/no_effect_async_fn.rs:32:9 | LL | let _a = 0; | ^^ diff --git a/tests/ui/no_effect_replace.rs b/tests/ui/no_effect_replace.rs index dc8e66f69ff5..245898f50740 100644 --- a/tests/ui/no_effect_replace.rs +++ b/tests/ui/no_effect_replace.rs @@ -4,14 +4,12 @@ fn main() { let _ = "12345".replace('1', "1"); //~^ no_effect_replace - let _ = "12345".replace("12", "12"); //~^ no_effect_replace let _ = String::new().replace("12", "12"); //~^ no_effect_replace - let _ = "12345".replacen('1', "1", 1); //~^ no_effect_replace @@ -21,7 +19,6 @@ fn main() { let _ = String::new().replacen("12", "12", 1); //~^ no_effect_replace - let _ = "12345".replace("12", "22"); let _ = "12345".replacen("12", "22", 1); diff --git a/tests/ui/no_effect_replace.stderr b/tests/ui/no_effect_replace.stderr index 3861d042e6f5..33d13b1d72e8 100644 --- a/tests/ui/no_effect_replace.stderr +++ b/tests/ui/no_effect_replace.stderr @@ -8,43 +8,43 @@ LL | let _ = "12345".replace('1', "1"); = help: to override `-D warnings` add `#[allow(clippy::no_effect_replace)]` error: replacing text with itself - --> tests/ui/no_effect_replace.rs:8:13 + --> tests/ui/no_effect_replace.rs:7:13 | LL | let _ = "12345".replace("12", "12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:11:13 + --> tests/ui/no_effect_replace.rs:10:13 | LL | let _ = String::new().replace("12", "12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:15:13 + --> tests/ui/no_effect_replace.rs:13:13 | LL | let _ = "12345".replacen('1', "1", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:18:13 + --> tests/ui/no_effect_replace.rs:16:13 | LL | let _ = "12345".replacen("12", "12", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:21:13 + --> tests/ui/no_effect_replace.rs:19:13 | LL | let _ = String::new().replacen("12", "12", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:29:13 + --> tests/ui/no_effect_replace.rs:26:13 | LL | let _ = "hello".replace(&x.f(), &x.f()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: replacing text with itself - --> tests/ui/no_effect_replace.rs:34:13 + --> tests/ui/no_effect_replace.rs:31:13 | LL | let _ = "hello".replace(&y(), &y()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/no_effect_return.rs b/tests/ui/no_effect_return.rs index 8bfd8367f104..4ba2fe07785d 100644 --- a/tests/ui/no_effect_return.rs +++ b/tests/ui/no_effect_return.rs @@ -8,8 +8,6 @@ fn a() -> u32 { { 0u32; //~^ no_effect - - } 0 } @@ -18,7 +16,6 @@ async fn b() -> u32 { { 0u32; //~^ no_effect - } 0 } @@ -28,7 +25,6 @@ async fn c() -> C { { 0i32 as C; //~^ no_effect - } 0 } @@ -49,7 +45,6 @@ fn e() -> u32 { // mismatched types 0u16; //~^ no_effect - } 0 } @@ -58,7 +53,6 @@ fn f() -> [u16; 1] { { [1u16]; //~^ no_effect - } [1] } @@ -67,7 +61,6 @@ fn g() -> ControlFlow<()> { { ControlFlow::Break::<()>(()); //~^ no_effect - } ControlFlow::Continue(()) } @@ -86,7 +79,6 @@ fn i() -> () { // does not suggest on function with explicit unit return type (); //~^ no_effect - } () } @@ -96,7 +88,6 @@ fn j() { // does not suggest on function without explicit return type (); //~^ no_effect - } () } diff --git a/tests/ui/no_effect_return.stderr b/tests/ui/no_effect_return.stderr index f6ff2ded33e0..e7bf7e4cd4f4 100644 --- a/tests/ui/no_effect_return.stderr +++ b/tests/ui/no_effect_return.stderr @@ -10,7 +10,7 @@ LL | 0u32; = help: to override `-D warnings` add `#[allow(clippy::no_effect)]` error: statement with no effect - --> tests/ui/no_effect_return.rs:19:9 + --> tests/ui/no_effect_return.rs:17:9 | LL | 0u32; | -^^^^ @@ -18,7 +18,7 @@ LL | 0u32; | help: did you mean to return it?: `return` error: statement with no effect - --> tests/ui/no_effect_return.rs:29:9 + --> tests/ui/no_effect_return.rs:26:9 | LL | 0i32 as C; | -^^^^^^^^^ @@ -26,19 +26,19 @@ LL | 0i32 as C; | help: did you mean to return it?: `return` error: statement with no effect - --> tests/ui/no_effect_return.rs:39:9 + --> tests/ui/no_effect_return.rs:35:9 | LL | 0u128; | ^^^^^^ error: statement with no effect - --> tests/ui/no_effect_return.rs:50:9 + --> tests/ui/no_effect_return.rs:46:9 | LL | 0u16; | ^^^^^ error: statement with no effect - --> tests/ui/no_effect_return.rs:59:9 + --> tests/ui/no_effect_return.rs:54:9 | LL | [1u16]; | -^^^^^^ @@ -46,7 +46,7 @@ LL | [1u16]; | help: did you mean to return it?: `return` error: statement with no effect - --> tests/ui/no_effect_return.rs:68:9 + --> tests/ui/no_effect_return.rs:62:9 | LL | ControlFlow::Break::<()>(()); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | ControlFlow::Break::<()>(()); | help: did you mean to return it?: `return` error: statement with no effect - --> tests/ui/no_effect_return.rs:87:9 + --> tests/ui/no_effect_return.rs:80:9 | LL | (); | ^^^ error: statement with no effect - --> tests/ui/no_effect_return.rs:97:9 + --> tests/ui/no_effect_return.rs:89:9 | LL | (); | ^^^ diff --git a/tests/ui/no_mangle_with_rust_abi.rs b/tests/ui/no_mangle_with_rust_abi.rs index 99b731d4a597..0d09b3ceecde 100644 --- a/tests/ui/no_mangle_with_rust_abi.rs +++ b/tests/ui/no_mangle_with_rust_abi.rs @@ -24,7 +24,7 @@ unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} #[unsafe(no_mangle)] fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( -//~^ no_mangle_with_rust_abi + //~^ no_mangle_with_rust_abi arg_one: u32, arg_two: usize, ) -> u32 { diff --git a/tests/ui/no_mangle_with_rust_abi_2021.rs b/tests/ui/no_mangle_with_rust_abi_2021.rs index eba653889064..3d5c70cad2f3 100644 --- a/tests/ui/no_mangle_with_rust_abi_2021.rs +++ b/tests/ui/no_mangle_with_rust_abi_2021.rs @@ -28,7 +28,7 @@ unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} #[no_mangle] fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( -//~^ no_mangle_with_rust_abi + //~^ no_mangle_with_rust_abi arg_one: u32, arg_two: usize, ) -> u32 { diff --git a/tests/ui/non_canonical_clone_impl.rs b/tests/ui/non_canonical_clone_impl.rs index d735122e1845..7d101915517f 100644 --- a/tests/ui/non_canonical_clone_impl.rs +++ b/tests/ui/non_canonical_clone_impl.rs @@ -12,12 +12,12 @@ struct A(u32); impl Clone for A { fn clone(&self) -> Self { - //~^ non_canonical_clone_impl + //~^ non_canonical_clone_impl Self(self.0) } fn clone_from(&mut self, source: &Self) { - //~^ non_canonical_clone_impl + //~^ non_canonical_clone_impl source.clone(); *self = source.clone(); } @@ -85,12 +85,12 @@ struct F(u32); impl Clone for F { fn clone(&self) -> Self { - //~^ non_canonical_clone_impl + //~^ non_canonical_clone_impl Self(self.0) } fn clone_from(&mut self, source: &Self) { - //~^ non_canonical_clone_impl + //~^ non_canonical_clone_impl source.clone(); *self = source.clone(); } diff --git a/tests/ui/non_canonical_partial_ord_impl.fixed b/tests/ui/non_canonical_partial_ord_impl.fixed index 7d1211522f18..8774c666db11 100644 --- a/tests/ui/non_canonical_partial_ord_impl.fixed +++ b/tests/ui/non_canonical_partial_ord_impl.fixed @@ -14,7 +14,7 @@ impl Ord for A { } impl PartialOrd for A { -//~^ non_canonical_partial_ord_impl + //~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } @@ -47,7 +47,7 @@ impl Ord for C { } impl PartialOrd for C { -//~^ non_canonical_partial_ord_impl + //~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } diff --git a/tests/ui/non_canonical_partial_ord_impl.rs b/tests/ui/non_canonical_partial_ord_impl.rs index 4f3310557992..568b97c8fff7 100644 --- a/tests/ui/non_canonical_partial_ord_impl.rs +++ b/tests/ui/non_canonical_partial_ord_impl.rs @@ -14,7 +14,7 @@ impl Ord for A { } impl PartialOrd for A { -//~^ non_canonical_partial_ord_impl + //~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { todo!(); } @@ -49,7 +49,7 @@ impl Ord for C { } impl PartialOrd for C { -//~^ non_canonical_partial_ord_impl + //~^ non_canonical_partial_ord_impl fn partial_cmp(&self, _: &Self) -> Option { todo!(); } diff --git a/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs b/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs index cbd1ae57be4a..99cd7ebac60c 100644 --- a/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs +++ b/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs @@ -21,7 +21,7 @@ impl cmp::Ord for A { } impl PartialOrd for A { -//~^ non_canonical_partial_ord_impl + //~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { // NOTE: This suggestion is wrong, as `Ord` is not in scope. But this should be fine as it isn't // automatically applied @@ -45,7 +45,7 @@ impl cmp::Ord for B { } impl PartialOrd for B { -//~^ non_canonical_partial_ord_impl + //~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { // This calls `B.cmp`, not `Ord::cmp`! Some(self.cmp(other)) diff --git a/tests/ui/non_expressive_names.rs b/tests/ui/non_expressive_names.rs index 69e90c3d670b..b772c754f8b7 100644 --- a/tests/ui/non_expressive_names.rs +++ b/tests/ui/non_expressive_names.rs @@ -25,12 +25,12 @@ impl MaybeInst { } fn underscores_and_numbers() { -let _1 = 1; -//~^ just_underscores_and_digits -let ____1 = 1; -//~^ just_underscores_and_digits -let __1___2 = 12; -//~^ just_underscores_and_digits + let _1 = 1; + //~^ just_underscores_and_digits + let ____1 = 1; + //~^ just_underscores_and_digits + let __1___2 = 12; + //~^ just_underscores_and_digits let _1_ok = 1; } @@ -51,12 +51,12 @@ struct Bar; impl Bar { fn bar() { -let _1 = 1; -//~^ just_underscores_and_digits -let ____1 = 1; -//~^ just_underscores_and_digits -let __1___2 = 12; -//~^ just_underscores_and_digits + let _1 = 1; + //~^ just_underscores_and_digits + let ____1 = 1; + //~^ just_underscores_and_digits + let __1___2 = 12; + //~^ just_underscores_and_digits let _1_ok = 1; } } diff --git a/tests/ui/non_expressive_names.stderr b/tests/ui/non_expressive_names.stderr index 7aa67e1ca415..3bd77a730fe7 100644 --- a/tests/ui/non_expressive_names.stderr +++ b/tests/ui/non_expressive_names.stderr @@ -1,41 +1,41 @@ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:28:5 + --> tests/ui/non_expressive_names.rs:28:9 | -LL | let _1 = 1; - | ^^ +LL | let _1 = 1; + | ^^ | = note: `-D clippy::just-underscores-and-digits` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::just_underscores_and_digits)]` error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:30:5 + --> tests/ui/non_expressive_names.rs:30:9 | -LL | let ____1 = 1; - | ^^^^^ +LL | let ____1 = 1; + | ^^^^^ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:32:5 + --> tests/ui/non_expressive_names.rs:32:9 | -LL | let __1___2 = 12; - | ^^^^^^^ +LL | let __1___2 = 12; + | ^^^^^^^ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:54:5 + --> tests/ui/non_expressive_names.rs:54:13 | -LL | let _1 = 1; - | ^^ +LL | let _1 = 1; + | ^^ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:56:5 + --> tests/ui/non_expressive_names.rs:56:13 | -LL | let ____1 = 1; - | ^^^^^ +LL | let ____1 = 1; + | ^^^^^ error: consider choosing a more descriptive name - --> tests/ui/non_expressive_names.rs:58:5 + --> tests/ui/non_expressive_names.rs:58:13 | -LL | let __1___2 = 12; - | ^^^^^^^ +LL | let __1___2 = 12; + | ^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/non_zero_suggestions.fixed b/tests/ui/non_zero_suggestions.fixed index 1459832be75e..4573896ecd67 100644 --- a/tests/ui/non_zero_suggestions.fixed +++ b/tests/ui/non_zero_suggestions.fixed @@ -9,22 +9,18 @@ fn main() { let r1 = x / NonZeroU64::from(y); //~^ non_zero_suggestions - let r2 = x % NonZeroU64::from(y); //~^ non_zero_suggestions - // U16 -> U32 let a: u32 = 50; let b = NonZeroU16::new(5).unwrap(); let r3 = a / NonZeroU32::from(b); //~^ non_zero_suggestions - let x = NonZeroU64::from(NonZeroU32::new(5).unwrap()); //~^ non_zero_suggestions - /// Negative test cases (lint should not trigger) // Left hand side expressions should not be triggered let c: u32 = 50; @@ -55,7 +51,6 @@ fn main() { fn divide_numbers(x: u64, y: NonZeroU32) -> u64 { x / NonZeroU64::from(y) //~^ non_zero_suggestions - } struct Calculator { @@ -66,6 +61,5 @@ impl Calculator { fn divide(&self, divisor: NonZeroU32) -> u64 { self.value / NonZeroU64::from(divisor) //~^ non_zero_suggestions - } } diff --git a/tests/ui/non_zero_suggestions.rs b/tests/ui/non_zero_suggestions.rs index 72a38131a132..3e7081e0c1c0 100644 --- a/tests/ui/non_zero_suggestions.rs +++ b/tests/ui/non_zero_suggestions.rs @@ -9,22 +9,18 @@ fn main() { let r1 = x / u64::from(y.get()); //~^ non_zero_suggestions - let r2 = x % u64::from(y.get()); //~^ non_zero_suggestions - // U16 -> U32 let a: u32 = 50; let b = NonZeroU16::new(5).unwrap(); let r3 = a / u32::from(b.get()); //~^ non_zero_suggestions - let x = u64::from(NonZeroU32::new(5).unwrap().get()); //~^ non_zero_suggestions - /// Negative test cases (lint should not trigger) // Left hand side expressions should not be triggered let c: u32 = 50; @@ -55,7 +51,6 @@ fn main() { fn divide_numbers(x: u64, y: NonZeroU32) -> u64 { x / u64::from(y.get()) //~^ non_zero_suggestions - } struct Calculator { @@ -66,6 +61,5 @@ impl Calculator { fn divide(&self, divisor: NonZeroU32) -> u64 { self.value / u64::from(divisor.get()) //~^ non_zero_suggestions - } } diff --git a/tests/ui/non_zero_suggestions.stderr b/tests/ui/non_zero_suggestions.stderr index f7ed71dcf56c..7a57f7983be7 100644 --- a/tests/ui/non_zero_suggestions.stderr +++ b/tests/ui/non_zero_suggestions.stderr @@ -8,31 +8,31 @@ LL | let r1 = x / u64::from(y.get()); = help: to override `-D warnings` add `#[allow(clippy::non_zero_suggestions)]` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:13:18 + --> tests/ui/non_zero_suggestions.rs:12:18 | LL | let r2 = x % u64::from(y.get()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)` error: consider using `NonZeroU32::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:20:18 + --> tests/ui/non_zero_suggestions.rs:18:18 | LL | let r3 = a / u32::from(b.get()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU32::from(b)` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:24:13 + --> tests/ui/non_zero_suggestions.rs:21:13 | LL | let x = u64::from(NonZeroU32::new(5).unwrap().get()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(NonZeroU32::new(5).unwrap())` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:56:9 + --> tests/ui/non_zero_suggestions.rs:52:9 | LL | x / u64::from(y.get()) | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions.rs:67:22 + --> tests/ui/non_zero_suggestions.rs:62:22 | LL | self.value / u64::from(divisor.get()) | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(divisor)` diff --git a/tests/ui/non_zero_suggestions_unfixable.rs b/tests/ui/non_zero_suggestions_unfixable.rs index 4adbdf7bcc74..1224356236c7 100644 --- a/tests/ui/non_zero_suggestions_unfixable.rs +++ b/tests/ui/non_zero_suggestions_unfixable.rs @@ -6,7 +6,6 @@ fn main() { let x: u64 = u64::from(NonZeroU32::new(5).unwrap().get()); //~^ non_zero_suggestions - let n = NonZeroU32::new(20).unwrap(); let y = u64::from(n.get()); //~^ non_zero_suggestions @@ -20,7 +19,6 @@ fn main() { fn return_non_zero(x: u64, y: NonZeroU32) -> u64 { u64::from(y.get()) //~^ non_zero_suggestions - } fn some_fn_that_only_takes_u64(_: u64) {} diff --git a/tests/ui/non_zero_suggestions_unfixable.stderr b/tests/ui/non_zero_suggestions_unfixable.stderr index dff70dada26d..d2ac983d4f7f 100644 --- a/tests/ui/non_zero_suggestions_unfixable.stderr +++ b/tests/ui/non_zero_suggestions_unfixable.stderr @@ -8,13 +8,13 @@ LL | let x: u64 = u64::from(NonZeroU32::new(5).unwrap().get()); = help: to override `-D warnings` add `#[allow(clippy::non_zero_suggestions)]` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions_unfixable.rs:11:13 + --> tests/ui/non_zero_suggestions_unfixable.rs:10:13 | LL | let y = u64::from(n.get()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(n)` error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion - --> tests/ui/non_zero_suggestions_unfixable.rs:21:5 + --> tests/ui/non_zero_suggestions_unfixable.rs:20:5 | LL | u64::from(y.get()) | ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)` diff --git a/tests/ui/nonminimal_bool.rs b/tests/ui/nonminimal_bool.rs index 1d41b2b9a84c..a155ff3508be 100644 --- a/tests/ui/nonminimal_bool.rs +++ b/tests/ui/nonminimal_bool.rs @@ -17,7 +17,6 @@ fn main() { let _ = !true; //~^ nonminimal_bool - let _ = !false; //~^ nonminimal_bool @@ -38,7 +37,6 @@ fn main() { let _ = !a && !(b && c); //~^ nonminimal_bool - } fn equality_stuff() { @@ -60,7 +58,6 @@ fn equality_stuff() { let _ = a != b && !(a != b && c == d); //~^ nonminimal_bool - } fn issue3847(a: u32, b: u32) -> bool { @@ -91,7 +88,7 @@ fn check_expect() { fn issue9428() { if matches!(true, true) && true { - //~^ nonminimal_bool + //~^ nonminimal_bool println!("foo"); } @@ -171,35 +168,35 @@ fn issue11932() { fn issue_5794() { let a = 0; -if !(12 == a) {} -//~^ nonminimal_bool -if !(a == 12) {} -//~^ nonminimal_bool -if !(12 != a) {} -//~^ nonminimal_bool -if !(a != 12) {} -//~^ nonminimal_bool + if !(12 == a) {} + //~^ nonminimal_bool + if !(a == 12) {} + //~^ nonminimal_bool + if !(12 != a) {} + //~^ nonminimal_bool + if !(a != 12) {} + //~^ nonminimal_bool let b = true; let c = false; -if !b == true {} -//~^ nonminimal_bool -//~| bool_comparison -//~| bool_comparison -if !b != true {} -//~^ nonminimal_bool -//~| bool_comparison -if true == !b {} -//~^ nonminimal_bool -//~| bool_comparison -//~| bool_comparison -if true != !b {} -//~^ nonminimal_bool -//~| bool_comparison -if !b == !c {} -//~^ nonminimal_bool -if !b != !c {} -//~^ nonminimal_bool + if !b == true {} + //~^ nonminimal_bool + //~| bool_comparison + //~| bool_comparison + if !b != true {} + //~^ nonminimal_bool + //~| bool_comparison + if true == !b {} + //~^ nonminimal_bool + //~| bool_comparison + //~| bool_comparison + if true != !b {} + //~^ nonminimal_bool + //~| bool_comparison + if !b == !c {} + //~^ nonminimal_bool + if !b != !c {} + //~^ nonminimal_bool } fn issue_12371(x: usize) -> bool { @@ -215,7 +212,7 @@ fn many_ops(a: bool, b: bool, c: bool, d: bool, e: bool, f: bool) -> bool { fn issue14184(a: f32, b: bool) { if !(a < 2.0 && !b) { - //~^ nonminimal_bool + //~^ nonminimal_bool println!("Hi"); } } diff --git a/tests/ui/nonminimal_bool.stderr b/tests/ui/nonminimal_bool.stderr index ca2c7ab8232a..06d3615c6e26 100644 --- a/tests/ui/nonminimal_bool.stderr +++ b/tests/ui/nonminimal_bool.stderr @@ -8,43 +8,43 @@ LL | let _ = !true; = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:21:13 + --> tests/ui/nonminimal_bool.rs:20:13 | LL | let _ = !false; | ^^^^^^ help: try: `true` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:24:13 + --> tests/ui/nonminimal_bool.rs:23:13 | LL | let _ = !!a; | ^^^ help: try: `a` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:27:13 + --> tests/ui/nonminimal_bool.rs:26:13 | LL | let _ = false || a; | ^^^^^^^^^^ help: try: `a` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:33:13 + --> tests/ui/nonminimal_bool.rs:32:13 | LL | let _ = !(!a && b); | ^^^^^^^^^^ help: try: `a || !b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:36:13 + --> tests/ui/nonminimal_bool.rs:35:13 | LL | let _ = !(!a || b); | ^^^^^^^^^^ help: try: `a && !b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:39:13 + --> tests/ui/nonminimal_bool.rs:38:13 | LL | let _ = !a && !(b && c); | ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:49:13 + --> tests/ui/nonminimal_bool.rs:47:13 | LL | let _ = a == b && c == 5 && a == b; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = a == b && c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:52:13 + --> tests/ui/nonminimal_bool.rs:50:13 | LL | let _ = a == b || c == 5 || a == b; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | let _ = a == b || c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:55:13 + --> tests/ui/nonminimal_bool.rs:53:13 | LL | let _ = a == b && c == 5 && b == a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | let _ = a == b && c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:58:13 + --> tests/ui/nonminimal_bool.rs:56:13 | LL | let _ = a != b || !(a != b || c == d); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL | let _ = a != b || c != d; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:61:13 + --> tests/ui/nonminimal_bool.rs:59:13 | LL | let _ = a != b && !(a != b && c == d); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,112 +109,112 @@ LL | let _ = a != b && c != d; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:93:8 + --> tests/ui/nonminimal_bool.rs:90:8 | LL | if matches!(true, true) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(true, true)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:174:4 + --> tests/ui/nonminimal_bool.rs:171:8 | -LL | if !(12 == a) {} - | ^^^^^^^^^^ help: try: `(12 != a)` +LL | if !(12 == a) {} + | ^^^^^^^^^^ help: try: `(12 != a)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:176:4 + --> tests/ui/nonminimal_bool.rs:173:8 | -LL | if !(a == 12) {} - | ^^^^^^^^^^ help: try: `(a != 12)` +LL | if !(a == 12) {} + | ^^^^^^^^^^ help: try: `(a != 12)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:178:4 + --> tests/ui/nonminimal_bool.rs:175:8 | -LL | if !(12 != a) {} - | ^^^^^^^^^^ help: try: `(12 == a)` +LL | if !(12 != a) {} + | ^^^^^^^^^^ help: try: `(12 == a)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:180:4 + --> tests/ui/nonminimal_bool.rs:177:8 | -LL | if !(a != 12) {} - | ^^^^^^^^^^ help: try: `(a == 12)` +LL | if !(a != 12) {} + | ^^^^^^^^^^ help: try: `(a == 12)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:185:4 + --> tests/ui/nonminimal_bool.rs:182:8 | -LL | if !b == true {} - | ^^^^^^^^^^ help: try: `b != true` +LL | if !b == true {} + | ^^^^^^^^^^ help: try: `b != true` error: this comparison might be written more concisely - --> tests/ui/nonminimal_bool.rs:185:4 + --> tests/ui/nonminimal_bool.rs:182:8 | -LL | if !b == true {} - | ^^^^^^^^^^ help: try simplifying it as shown: `b != true` +LL | if !b == true {} + | ^^^^^^^^^^ help: try simplifying it as shown: `b != true` | = note: `-D clippy::bool-comparison` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]` error: equality checks against true are unnecessary - --> tests/ui/nonminimal_bool.rs:185:4 + --> tests/ui/nonminimal_bool.rs:182:8 | -LL | if !b == true {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!b` +LL | if !b == true {} + | ^^^^^^^^^^ help: try simplifying it as shown: `!b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:189:4 + --> tests/ui/nonminimal_bool.rs:186:8 | -LL | if !b != true {} - | ^^^^^^^^^^ help: try: `b == true` +LL | if !b != true {} + | ^^^^^^^^^^ help: try: `b == true` error: inequality checks against true can be replaced by a negation - --> tests/ui/nonminimal_bool.rs:189:4 + --> tests/ui/nonminimal_bool.rs:186:8 | -LL | if !b != true {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` +LL | if !b != true {} + | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:192:4 + --> tests/ui/nonminimal_bool.rs:189:8 | -LL | if true == !b {} - | ^^^^^^^^^^ help: try: `true != b` +LL | if true == !b {} + | ^^^^^^^^^^ help: try: `true != b` error: this comparison might be written more concisely - --> tests/ui/nonminimal_bool.rs:192:4 + --> tests/ui/nonminimal_bool.rs:189:8 | -LL | if true == !b {} - | ^^^^^^^^^^ help: try simplifying it as shown: `true != b` +LL | if true == !b {} + | ^^^^^^^^^^ help: try simplifying it as shown: `true != b` error: equality checks against true are unnecessary - --> tests/ui/nonminimal_bool.rs:192:4 + --> tests/ui/nonminimal_bool.rs:189:8 | -LL | if true == !b {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!b` +LL | if true == !b {} + | ^^^^^^^^^^ help: try simplifying it as shown: `!b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:196:4 + --> tests/ui/nonminimal_bool.rs:193:8 | -LL | if true != !b {} - | ^^^^^^^^^^ help: try: `true == b` +LL | if true != !b {} + | ^^^^^^^^^^ help: try: `true == b` error: inequality checks against true can be replaced by a negation - --> tests/ui/nonminimal_bool.rs:196:4 + --> tests/ui/nonminimal_bool.rs:193:8 | -LL | if true != !b {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` +LL | if true != !b {} + | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:199:4 + --> tests/ui/nonminimal_bool.rs:196:8 | -LL | if !b == !c {} - | ^^^^^^^^ help: try: `b == c` +LL | if !b == !c {} + | ^^^^^^^^ help: try: `b == c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:201:4 + --> tests/ui/nonminimal_bool.rs:198:8 | -LL | if !b != !c {} - | ^^^^^^^^ help: try: `b != c` +LL | if !b != !c {} + | ^^^^^^^^ help: try: `b != c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:217:8 + --> tests/ui/nonminimal_bool.rs:214:8 | LL | if !(a < 2.0 && !b) { | ^^^^^^^^^^^^^^^^ help: try: `!(a < 2.0) || b` diff --git a/tests/ui/nonminimal_bool_methods.fixed b/tests/ui/nonminimal_bool_methods.fixed index 4b11dc2b5dda..c2377491f25b 100644 --- a/tests/ui/nonminimal_bool_methods.fixed +++ b/tests/ui/nonminimal_bool_methods.fixed @@ -123,34 +123,34 @@ fn dont_warn_for_negated_partial_ord_comparison() { fn issue_12625() { let a = 0; let b = 0; -if ((a as u64) < b) {} -//~^ nonminimal_bool -if ((a as u64) < b) {} -//~^ nonminimal_bool -if (a as u64 > b) {} -//~^ nonminimal_bool + if ((a as u64) < b) {} + //~^ nonminimal_bool + if ((a as u64) < b) {} + //~^ nonminimal_bool + if (a as u64 > b) {} + //~^ nonminimal_bool } fn issue_12761() { let a = 0; let b = 0; let c = 0; -if (a < b) as i32 == c {} -//~^ nonminimal_bool -if (a < b) | (a > c) {} -//~^ nonminimal_bool -//~| nonminimal_bool + if (a < b) as i32 == c {} + //~^ nonminimal_bool + if (a < b) | (a > c) {} + //~^ nonminimal_bool + //~| nonminimal_bool let opt: Option = Some(1); let res: Result = Ok(1); -if res.is_err() as i32 == c {} -//~^ nonminimal_bool -if res.is_err() | opt.is_some() {} -//~^ nonminimal_bool -//~| nonminimal_bool + if res.is_err() as i32 == c {} + //~^ nonminimal_bool + if res.is_err() | opt.is_some() {} + //~^ nonminimal_bool + //~| nonminimal_bool fn a(a: bool) -> bool { -(4 <= 3).b() -//~^ nonminimal_bool + (4 <= 3).b() + //~^ nonminimal_bool } trait B { @@ -175,18 +175,18 @@ fn issue_13436() { _ = opt.is_some_and(|x| x == 1000); _ = opt.is_some_and(|x| x != 1000); _ = opt.is_some_and(not_zero); -_ = opt.is_none_or(|x| x >= 1000); -//~^ nonminimal_bool -_ = opt.is_none_or(|x| x > 1000); -//~^ nonminimal_bool -_ = opt.is_none_or(|x| x <= 1000); -//~^ nonminimal_bool -_ = opt.is_none_or(|x| x < 1000); -//~^ nonminimal_bool -_ = opt.is_none_or(|x| x != 1000); -//~^ nonminimal_bool -_ = opt.is_none_or(|x| x == 1000); -//~^ nonminimal_bool + _ = opt.is_none_or(|x| x >= 1000); + //~^ nonminimal_bool + _ = opt.is_none_or(|x| x > 1000); + //~^ nonminimal_bool + _ = opt.is_none_or(|x| x <= 1000); + //~^ nonminimal_bool + _ = opt.is_none_or(|x| x < 1000); + //~^ nonminimal_bool + _ = opt.is_none_or(|x| x != 1000); + //~^ nonminimal_bool + _ = opt.is_none_or(|x| x == 1000); + //~^ nonminimal_bool _ = !opt.is_some_and(not_zero); _ = opt.is_none_or(|x| x < 1000); _ = opt.is_none_or(|x| x <= 1000); @@ -195,45 +195,45 @@ _ = opt.is_none_or(|x| x == 1000); _ = opt.is_none_or(|x| x == 1000); _ = opt.is_none_or(|x| x != 1000); _ = opt.is_none_or(not_zero); -_ = opt.is_some_and(|x| x >= 1000); -//~^ nonminimal_bool -_ = opt.is_some_and(|x| x > 1000); -//~^ nonminimal_bool -_ = opt.is_some_and(|x| x <= 1000); -//~^ nonminimal_bool -_ = opt.is_some_and(|x| x < 1000); -//~^ nonminimal_bool -_ = opt.is_some_and(|x| x != 1000); -//~^ nonminimal_bool -_ = opt.is_some_and(|x| x == 1000); -//~^ nonminimal_bool + _ = opt.is_some_and(|x| x >= 1000); + //~^ nonminimal_bool + _ = opt.is_some_and(|x| x > 1000); + //~^ nonminimal_bool + _ = opt.is_some_and(|x| x <= 1000); + //~^ nonminimal_bool + _ = opt.is_some_and(|x| x < 1000); + //~^ nonminimal_bool + _ = opt.is_some_and(|x| x != 1000); + //~^ nonminimal_bool + _ = opt.is_some_and(|x| x == 1000); + //~^ nonminimal_bool _ = !opt.is_none_or(not_zero); let opt = Some(true); _ = opt.is_some_and(|x| x); _ = opt.is_some_and(|x| !x); _ = !opt.is_some_and(|x| x); -_ = opt.is_none_or(|x| x); -//~^ nonminimal_bool + _ = opt.is_none_or(|x| x); + //~^ nonminimal_bool _ = opt.is_none_or(|x| x); _ = opt.is_none_or(|x| !x); _ = !opt.is_none_or(|x| x); -_ = opt.is_some_and(|x| x); -//~^ nonminimal_bool + _ = opt.is_some_and(|x| x); + //~^ nonminimal_bool let opt: Option> = Some(Ok(123)); _ = opt.is_some_and(|x| x.is_ok()); _ = opt.is_some_and(|x| x.is_err()); _ = opt.is_none_or(|x| x.is_ok()); _ = opt.is_none_or(|x| x.is_err()); -_ = opt.is_none_or(|x| x.is_err()); -//~^ nonminimal_bool -_ = opt.is_none_or(|x| x.is_ok()); -//~^ nonminimal_bool -_ = opt.is_some_and(|x| x.is_err()); -//~^ nonminimal_bool -_ = opt.is_some_and(|x| x.is_ok()); -//~^ nonminimal_bool + _ = opt.is_none_or(|x| x.is_err()); + //~^ nonminimal_bool + _ = opt.is_none_or(|x| x.is_ok()); + //~^ nonminimal_bool + _ = opt.is_some_and(|x| x.is_err()); + //~^ nonminimal_bool + _ = opt.is_some_and(|x| x.is_ok()); + //~^ nonminimal_bool #[clippy::msrv = "1.81"] fn before_stabilization() { diff --git a/tests/ui/nonminimal_bool_methods.rs b/tests/ui/nonminimal_bool_methods.rs index 3e574de2d156..1ae0f0064c6b 100644 --- a/tests/ui/nonminimal_bool_methods.rs +++ b/tests/ui/nonminimal_bool_methods.rs @@ -123,34 +123,34 @@ fn dont_warn_for_negated_partial_ord_comparison() { fn issue_12625() { let a = 0; let b = 0; -if !(a as u64 >= b) {} -//~^ nonminimal_bool -if !((a as u64) >= b) {} -//~^ nonminimal_bool -if !(a as u64 <= b) {} -//~^ nonminimal_bool + if !(a as u64 >= b) {} + //~^ nonminimal_bool + if !((a as u64) >= b) {} + //~^ nonminimal_bool + if !(a as u64 <= b) {} + //~^ nonminimal_bool } fn issue_12761() { let a = 0; let b = 0; let c = 0; -if !(a >= b) as i32 == c {} -//~^ nonminimal_bool -if !(a >= b) | !(a <= c) {} -//~^ nonminimal_bool -//~| nonminimal_bool + if !(a >= b) as i32 == c {} + //~^ nonminimal_bool + if !(a >= b) | !(a <= c) {} + //~^ nonminimal_bool + //~| nonminimal_bool let opt: Option = Some(1); let res: Result = Ok(1); -if !res.is_ok() as i32 == c {} -//~^ nonminimal_bool -if !res.is_ok() | !opt.is_none() {} -//~^ nonminimal_bool -//~| nonminimal_bool + if !res.is_ok() as i32 == c {} + //~^ nonminimal_bool + if !res.is_ok() | !opt.is_none() {} + //~^ nonminimal_bool + //~| nonminimal_bool fn a(a: bool) -> bool { -(!(4 > 3)).b() -//~^ nonminimal_bool + (!(4 > 3)).b() + //~^ nonminimal_bool } trait B { @@ -175,18 +175,18 @@ fn issue_13436() { _ = opt.is_some_and(|x| x == 1000); _ = opt.is_some_and(|x| x != 1000); _ = opt.is_some_and(not_zero); -_ = !opt.is_some_and(|x| x < 1000); -//~^ nonminimal_bool -_ = !opt.is_some_and(|x| x <= 1000); -//~^ nonminimal_bool -_ = !opt.is_some_and(|x| x > 1000); -//~^ nonminimal_bool -_ = !opt.is_some_and(|x| x >= 1000); -//~^ nonminimal_bool -_ = !opt.is_some_and(|x| x == 1000); -//~^ nonminimal_bool -_ = !opt.is_some_and(|x| x != 1000); -//~^ nonminimal_bool + _ = !opt.is_some_and(|x| x < 1000); + //~^ nonminimal_bool + _ = !opt.is_some_and(|x| x <= 1000); + //~^ nonminimal_bool + _ = !opt.is_some_and(|x| x > 1000); + //~^ nonminimal_bool + _ = !opt.is_some_and(|x| x >= 1000); + //~^ nonminimal_bool + _ = !opt.is_some_and(|x| x == 1000); + //~^ nonminimal_bool + _ = !opt.is_some_and(|x| x != 1000); + //~^ nonminimal_bool _ = !opt.is_some_and(not_zero); _ = opt.is_none_or(|x| x < 1000); _ = opt.is_none_or(|x| x <= 1000); @@ -195,45 +195,45 @@ _ = !opt.is_some_and(|x| x != 1000); _ = opt.is_none_or(|x| x == 1000); _ = opt.is_none_or(|x| x != 1000); _ = opt.is_none_or(not_zero); -_ = !opt.is_none_or(|x| x < 1000); -//~^ nonminimal_bool -_ = !opt.is_none_or(|x| x <= 1000); -//~^ nonminimal_bool -_ = !opt.is_none_or(|x| x > 1000); -//~^ nonminimal_bool -_ = !opt.is_none_or(|x| x >= 1000); -//~^ nonminimal_bool -_ = !opt.is_none_or(|x| x == 1000); -//~^ nonminimal_bool -_ = !opt.is_none_or(|x| x != 1000); -//~^ nonminimal_bool + _ = !opt.is_none_or(|x| x < 1000); + //~^ nonminimal_bool + _ = !opt.is_none_or(|x| x <= 1000); + //~^ nonminimal_bool + _ = !opt.is_none_or(|x| x > 1000); + //~^ nonminimal_bool + _ = !opt.is_none_or(|x| x >= 1000); + //~^ nonminimal_bool + _ = !opt.is_none_or(|x| x == 1000); + //~^ nonminimal_bool + _ = !opt.is_none_or(|x| x != 1000); + //~^ nonminimal_bool _ = !opt.is_none_or(not_zero); let opt = Some(true); _ = opt.is_some_and(|x| x); _ = opt.is_some_and(|x| !x); _ = !opt.is_some_and(|x| x); -_ = !opt.is_some_and(|x| !x); -//~^ nonminimal_bool + _ = !opt.is_some_and(|x| !x); + //~^ nonminimal_bool _ = opt.is_none_or(|x| x); _ = opt.is_none_or(|x| !x); _ = !opt.is_none_or(|x| x); -_ = !opt.is_none_or(|x| !x); -//~^ nonminimal_bool + _ = !opt.is_none_or(|x| !x); + //~^ nonminimal_bool let opt: Option> = Some(Ok(123)); _ = opt.is_some_and(|x| x.is_ok()); _ = opt.is_some_and(|x| x.is_err()); _ = opt.is_none_or(|x| x.is_ok()); _ = opt.is_none_or(|x| x.is_err()); -_ = !opt.is_some_and(|x| x.is_ok()); -//~^ nonminimal_bool -_ = !opt.is_some_and(|x| x.is_err()); -//~^ nonminimal_bool -_ = !opt.is_none_or(|x| x.is_ok()); -//~^ nonminimal_bool -_ = !opt.is_none_or(|x| x.is_err()); -//~^ nonminimal_bool + _ = !opt.is_some_and(|x| x.is_ok()); + //~^ nonminimal_bool + _ = !opt.is_some_and(|x| x.is_err()); + //~^ nonminimal_bool + _ = !opt.is_none_or(|x| x.is_ok()); + //~^ nonminimal_bool + _ = !opt.is_none_or(|x| x.is_err()); + //~^ nonminimal_bool #[clippy::msrv = "1.81"] fn before_stabilization() { diff --git a/tests/ui/nonminimal_bool_methods.stderr b/tests/ui/nonminimal_bool_methods.stderr index 3f03b8613596..b5155b3b1696 100644 --- a/tests/ui/nonminimal_bool_methods.stderr +++ b/tests/ui/nonminimal_bool_methods.stderr @@ -80,172 +80,172 @@ LL | if !res.is_none() {} | ^^^^^^^^^^^^^^ help: try: `res.is_some()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:126:4 + --> tests/ui/nonminimal_bool_methods.rs:126:8 | -LL | if !(a as u64 >= b) {} - | ^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)` +LL | if !(a as u64 >= b) {} + | ^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:128:4 + --> tests/ui/nonminimal_bool_methods.rs:128:8 | -LL | if !((a as u64) >= b) {} - | ^^^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)` +LL | if !((a as u64) >= b) {} + | ^^^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:130:4 + --> tests/ui/nonminimal_bool_methods.rs:130:8 | -LL | if !(a as u64 <= b) {} - | ^^^^^^^^^^^^^^^^ help: try: `(a as u64 > b)` +LL | if !(a as u64 <= b) {} + | ^^^^^^^^^^^^^^^^ help: try: `(a as u64 > b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:138:4 + --> tests/ui/nonminimal_bool_methods.rs:138:8 | -LL | if !(a >= b) as i32 == c {} - | ^^^^^^^^^ help: try: `(a < b)` +LL | if !(a >= b) as i32 == c {} + | ^^^^^^^^^ help: try: `(a < b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:140:4 + --> tests/ui/nonminimal_bool_methods.rs:140:8 | -LL | if !(a >= b) | !(a <= c) {} - | ^^^^^^^^^ help: try: `(a < b)` +LL | if !(a >= b) | !(a <= c) {} + | ^^^^^^^^^ help: try: `(a < b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:140:16 + --> tests/ui/nonminimal_bool_methods.rs:140:20 | -LL | if !(a >= b) | !(a <= c) {} - | ^^^^^^^^^ help: try: `(a > c)` +LL | if !(a >= b) | !(a <= c) {} + | ^^^^^^^^^ help: try: `(a > c)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:145:4 + --> tests/ui/nonminimal_bool_methods.rs:145:8 | -LL | if !res.is_ok() as i32 == c {} - | ^^^^^^^^^^^^ help: try: `res.is_err()` +LL | if !res.is_ok() as i32 == c {} + | ^^^^^^^^^^^^ help: try: `res.is_err()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:147:4 + --> tests/ui/nonminimal_bool_methods.rs:147:8 | -LL | if !res.is_ok() | !opt.is_none() {} - | ^^^^^^^^^^^^ help: try: `res.is_err()` +LL | if !res.is_ok() | !opt.is_none() {} + | ^^^^^^^^^^^^ help: try: `res.is_err()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:147:19 + --> tests/ui/nonminimal_bool_methods.rs:147:23 | -LL | if !res.is_ok() | !opt.is_none() {} - | ^^^^^^^^^^^^^^ help: try: `opt.is_some()` +LL | if !res.is_ok() | !opt.is_none() {} + | ^^^^^^^^^^^^^^ help: try: `opt.is_some()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:152:1 + --> tests/ui/nonminimal_bool_methods.rs:152:9 | -LL | (!(4 > 3)).b() - | ^^^^^^^^^^ help: try: `(4 <= 3)` +LL | (!(4 > 3)).b() + | ^^^^^^^^^^ help: try: `(4 <= 3)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:178:5 + --> tests/ui/nonminimal_bool_methods.rs:178:9 | -LL | _ = !opt.is_some_and(|x| x < 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x >= 1000)` +LL | _ = !opt.is_some_and(|x| x < 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x >= 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:180:5 + --> tests/ui/nonminimal_bool_methods.rs:180:9 | -LL | _ = !opt.is_some_and(|x| x <= 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x > 1000)` +LL | _ = !opt.is_some_and(|x| x <= 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x > 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:182:5 + --> tests/ui/nonminimal_bool_methods.rs:182:9 | -LL | _ = !opt.is_some_and(|x| x > 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x <= 1000)` +LL | _ = !opt.is_some_and(|x| x > 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x <= 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:184:5 + --> tests/ui/nonminimal_bool_methods.rs:184:9 | -LL | _ = !opt.is_some_and(|x| x >= 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x < 1000)` +LL | _ = !opt.is_some_and(|x| x >= 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x < 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:186:5 + --> tests/ui/nonminimal_bool_methods.rs:186:9 | -LL | _ = !opt.is_some_and(|x| x == 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x != 1000)` +LL | _ = !opt.is_some_and(|x| x == 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x != 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:188:5 + --> tests/ui/nonminimal_bool_methods.rs:188:9 | -LL | _ = !opt.is_some_and(|x| x != 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x == 1000)` +LL | _ = !opt.is_some_and(|x| x != 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x == 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:198:5 + --> tests/ui/nonminimal_bool_methods.rs:198:9 | -LL | _ = !opt.is_none_or(|x| x < 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x >= 1000)` +LL | _ = !opt.is_none_or(|x| x < 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x >= 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:200:5 + --> tests/ui/nonminimal_bool_methods.rs:200:9 | -LL | _ = !opt.is_none_or(|x| x <= 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x > 1000)` +LL | _ = !opt.is_none_or(|x| x <= 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x > 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:202:5 + --> tests/ui/nonminimal_bool_methods.rs:202:9 | -LL | _ = !opt.is_none_or(|x| x > 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x <= 1000)` +LL | _ = !opt.is_none_or(|x| x > 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x <= 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:204:5 + --> tests/ui/nonminimal_bool_methods.rs:204:9 | -LL | _ = !opt.is_none_or(|x| x >= 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x < 1000)` +LL | _ = !opt.is_none_or(|x| x >= 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x < 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:206:5 + --> tests/ui/nonminimal_bool_methods.rs:206:9 | -LL | _ = !opt.is_none_or(|x| x == 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x != 1000)` +LL | _ = !opt.is_none_or(|x| x == 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x != 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:208:5 + --> tests/ui/nonminimal_bool_methods.rs:208:9 | -LL | _ = !opt.is_none_or(|x| x != 1000); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x == 1000)` +LL | _ = !opt.is_none_or(|x| x != 1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x == 1000)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:216:5 + --> tests/ui/nonminimal_bool_methods.rs:216:9 | -LL | _ = !opt.is_some_and(|x| !x); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x)` +LL | _ = !opt.is_some_and(|x| !x); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:221:5 + --> tests/ui/nonminimal_bool_methods.rs:221:9 | -LL | _ = !opt.is_none_or(|x| !x); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x)` +LL | _ = !opt.is_none_or(|x| !x); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:229:5 + --> tests/ui/nonminimal_bool_methods.rs:229:9 | -LL | _ = !opt.is_some_and(|x| x.is_ok()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_err())` +LL | _ = !opt.is_some_and(|x| x.is_ok()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_err())` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:231:5 + --> tests/ui/nonminimal_bool_methods.rs:231:9 | -LL | _ = !opt.is_some_and(|x| x.is_err()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_ok())` +LL | _ = !opt.is_some_and(|x| x.is_err()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_ok())` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:233:5 + --> tests/ui/nonminimal_bool_methods.rs:233:9 | -LL | _ = !opt.is_none_or(|x| x.is_ok()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_err())` +LL | _ = !opt.is_none_or(|x| x.is_ok()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_err())` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:235:5 + --> tests/ui/nonminimal_bool_methods.rs:235:9 | -LL | _ = !opt.is_none_or(|x| x.is_err()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_ok())` +LL | _ = !opt.is_none_or(|x| x.is_err()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_ok())` error: aborting due to 41 previous errors diff --git a/tests/ui/nonminimal_bool_methods_unfixable.rs b/tests/ui/nonminimal_bool_methods_unfixable.rs index aba156ac8ea9..850eba4851b8 100644 --- a/tests/ui/nonminimal_bool_methods_unfixable.rs +++ b/tests/ui/nonminimal_bool_methods_unfixable.rs @@ -3,9 +3,9 @@ fn issue_13436() { let opt_opt = Some(Some(500)); -_ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); -//~^ nonminimal_bool -//~| nonminimal_bool + _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); + //~^ nonminimal_bool + //~| nonminimal_bool } fn main() {} diff --git a/tests/ui/nonminimal_bool_methods_unfixable.stderr b/tests/ui/nonminimal_bool_methods_unfixable.stderr index c228bafad325..5a90155844cd 100644 --- a/tests/ui/nonminimal_bool_methods_unfixable.stderr +++ b/tests/ui/nonminimal_bool_methods_unfixable.stderr @@ -1,17 +1,17 @@ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:5 + --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:9 | -LL | _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt_opt.is_none_or(|x| x.is_some_and(|y| y != 1000))` +LL | _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt_opt.is_none_or(|x| x.is_some_and(|y| y != 1000))` | = note: `-D clippy::nonminimal-bool` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:30 + --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:34 | -LL | _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_none_or(|y| y == 1000)` +LL | _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_none_or(|y| y == 1000)` error: aborting due to 2 previous errors diff --git a/tests/ui/obfuscated_if_else.fixed b/tests/ui/obfuscated_if_else.fixed index 61a8fdddcd7d..b7a9cc836475 100644 --- a/tests/ui/obfuscated_if_else.fixed +++ b/tests/ui/obfuscated_if_else.fixed @@ -8,7 +8,6 @@ fn main() { if true { "a" } else { "b" }; //~^ obfuscated_if_else - let a = 1; if a == 1 { "a" } else { "b" }; //~^ obfuscated_if_else @@ -16,7 +15,6 @@ fn main() { if a == 1 { "a" } else { "b" }; //~^ obfuscated_if_else - let partial = (a == 1).then_some("a"); partial.unwrap_or("b"); // not lint @@ -26,7 +24,6 @@ fn main() { if true { () } else { a += 2 }; //~^ obfuscated_if_else - } fn issue11141() { @@ -34,31 +31,25 @@ fn issue11141() { let _ = (if true { 40 } else { 17 }) | 2; //~^ obfuscated_if_else - // Parentheses are required only for the leftmost expression let _ = (if true { 30 } else { 17 }) | if true { 2 } else { 3 } | if true { 10 } else { 1 }; //~^ obfuscated_if_else //~| obfuscated_if_else //~| obfuscated_if_else - // Parentheses are not required around the right side of a binary expression let _ = 2 | if true { 40 } else { 17 }; //~^ obfuscated_if_else - // Parentheses are not required for a cast let _ = if true { 42 } else { 17 } as u8; //~^ obfuscated_if_else - // Parentheses are not required for a deref let _ = *if true { &42 } else { &17 }; //~^ obfuscated_if_else - // Parentheses are not required for a deref followed by a cast let _ = *if true { &42 } else { &17 } as u8; //~^ obfuscated_if_else - } diff --git a/tests/ui/obfuscated_if_else.rs b/tests/ui/obfuscated_if_else.rs index 0eaafe8b66ad..a6470fedd5c6 100644 --- a/tests/ui/obfuscated_if_else.rs +++ b/tests/ui/obfuscated_if_else.rs @@ -8,7 +8,6 @@ fn main() { true.then(|| "a").unwrap_or("b"); //~^ obfuscated_if_else - let a = 1; (a == 1).then_some("a").unwrap_or("b"); //~^ obfuscated_if_else @@ -16,7 +15,6 @@ fn main() { (a == 1).then(|| "a").unwrap_or("b"); //~^ obfuscated_if_else - let partial = (a == 1).then_some("a"); partial.unwrap_or("b"); // not lint @@ -26,7 +24,6 @@ fn main() { true.then_some(()).unwrap_or(a += 2); //~^ obfuscated_if_else - } fn issue11141() { @@ -34,31 +31,25 @@ fn issue11141() { let _ = true.then_some(40).unwrap_or(17) | 2; //~^ obfuscated_if_else - // Parentheses are required only for the leftmost expression let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); //~^ obfuscated_if_else //~| obfuscated_if_else //~| obfuscated_if_else - // Parentheses are not required around the right side of a binary expression let _ = 2 | true.then_some(40).unwrap_or(17); //~^ obfuscated_if_else - // Parentheses are not required for a cast let _ = true.then_some(42).unwrap_or(17) as u8; //~^ obfuscated_if_else - // Parentheses are not required for a deref let _ = *true.then_some(&42).unwrap_or(&17); //~^ obfuscated_if_else - // Parentheses are not required for a deref followed by a cast let _ = *true.then_some(&42).unwrap_or(&17) as u8; //~^ obfuscated_if_else - } diff --git a/tests/ui/obfuscated_if_else.stderr b/tests/ui/obfuscated_if_else.stderr index 2d635871950f..84caa848ece6 100644 --- a/tests/ui/obfuscated_if_else.stderr +++ b/tests/ui/obfuscated_if_else.stderr @@ -14,73 +14,73 @@ LL | true.then(|| "a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:13:5 + --> tests/ui/obfuscated_if_else.rs:12:5 | LL | (a == 1).then_some("a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:16:5 + --> tests/ui/obfuscated_if_else.rs:15:5 | LL | (a == 1).then(|| "a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:24:5 + --> tests/ui/obfuscated_if_else.rs:22:5 | LL | true.then_some(a += 1).unwrap_or(()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { a += 1 } else { () }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:27:5 + --> tests/ui/obfuscated_if_else.rs:25:5 | LL | true.then_some(()).unwrap_or(a += 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { a += 2 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:34:13 + --> tests/ui/obfuscated_if_else.rs:31:13 | LL | let _ = true.then_some(40).unwrap_or(17) | 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 40 } else { 17 })` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:39:13 + --> tests/ui/obfuscated_if_else.rs:35:13 | LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 30 } else { 17 })` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:39:48 + --> tests/ui/obfuscated_if_else.rs:35:48 | LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 2 } else { 3 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:39:81 + --> tests/ui/obfuscated_if_else.rs:35:81 | LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 10 } else { 1 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:46:17 + --> tests/ui/obfuscated_if_else.rs:41:17 | LL | let _ = 2 | true.then_some(40).unwrap_or(17); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 40 } else { 17 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:51:13 + --> tests/ui/obfuscated_if_else.rs:45:13 | LL | let _ = true.then_some(42).unwrap_or(17) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 42 } else { 17 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:56:14 + --> tests/ui/obfuscated_if_else.rs:49:14 | LL | let _ = *true.then_some(&42).unwrap_or(&17); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:61:14 + --> tests/ui/obfuscated_if_else.rs:53:14 | LL | let _ = *true.then_some(&42).unwrap_or(&17) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` diff --git a/tests/ui/octal_escapes.rs b/tests/ui/octal_escapes.rs index 08e0316d1124..d91d6c1d7bee 100644 --- a/tests/ui/octal_escapes.rs +++ b/tests/ui/octal_escapes.rs @@ -2,31 +2,29 @@ #![warn(clippy::octal_escapes)] fn main() { -let _bad1 = "\033[0m"; -//~^ octal_escapes -let _bad2 = b"\033[0m"; -//~^ octal_escapes -let _bad3 = "\\\033[0m"; -//~^ octal_escapes + let _bad1 = "\033[0m"; + //~^ octal_escapes + let _bad2 = b"\033[0m"; + //~^ octal_escapes + let _bad3 = "\\\033[0m"; + //~^ octal_escapes // maximum 3 digits (\012 is the escape) -let _bad4 = "\01234567"; -//~^ octal_escapes -let _bad5 = "\0\03"; -//~^ octal_escapes + let _bad4 = "\01234567"; + //~^ octal_escapes + let _bad5 = "\0\03"; + //~^ octal_escapes let _bad6 = "Text-\055\077-MoreText"; //~^ octal_escapes //~| octal_escapes - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; //~^ octal_escapes //~| octal_escapes - -let _bad8 = "锈\01锈"; -//~^ octal_escapes -let _bad9 = "锈\011锈"; -//~^ octal_escapes + let _bad8 = "锈\01锈"; + //~^ octal_escapes + let _bad9 = "锈\011锈"; + //~^ octal_escapes let _good1 = "\\033[0m"; let _good2 = "\0\\0"; diff --git a/tests/ui/octal_escapes.stderr b/tests/ui/octal_escapes.stderr index 2f838a84dd48..024308cbf429 100644 --- a/tests/ui/octal_escapes.stderr +++ b/tests/ui/octal_escapes.stderr @@ -1,80 +1,80 @@ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:5:14 + --> tests/ui/octal_escapes.rs:5:18 | -LL | let _bad1 = "\033[0m"; - | ^^^^ +LL | let _bad1 = "\033[0m"; + | ^^^^ | = help: octal escapes are not supported, `\0` is always null = note: `-D clippy::octal-escapes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::octal_escapes)]` help: if an octal escape is intended, use a hex escape instead | -LL | let _bad1 = "\x1b[0m"; - | ~~~~ +LL | let _bad1 = "\x1b[0m"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad1 = "\x0033[0m"; - | ~~~~~~ +LL | let _bad1 = "\x0033[0m"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:7:15 + --> tests/ui/octal_escapes.rs:7:19 | -LL | let _bad2 = b"\033[0m"; - | ^^^^ +LL | let _bad2 = b"\033[0m"; + | ^^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad2 = b"\x1b[0m"; - | ~~~~ +LL | let _bad2 = b"\x1b[0m"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad2 = b"\x0033[0m"; - | ~~~~~~ +LL | let _bad2 = b"\x0033[0m"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:9:16 + --> tests/ui/octal_escapes.rs:9:20 | -LL | let _bad3 = "\\\033[0m"; - | ^^^^ +LL | let _bad3 = "\\\033[0m"; + | ^^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad3 = "\\\x1b[0m"; - | ~~~~ +LL | let _bad3 = "\\\x1b[0m"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad3 = "\\\x0033[0m"; - | ~~~~~~ +LL | let _bad3 = "\\\x0033[0m"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:12:14 + --> tests/ui/octal_escapes.rs:12:18 | -LL | let _bad4 = "\01234567"; - | ^^^^ +LL | let _bad4 = "\01234567"; + | ^^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad4 = "\x0a34567"; - | ~~~~ +LL | let _bad4 = "\x0a34567"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad4 = "\x001234567"; - | ~~~~~~ +LL | let _bad4 = "\x001234567"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:14:16 + --> tests/ui/octal_escapes.rs:14:20 | -LL | let _bad5 = "\0\03"; - | ^^^ +LL | let _bad5 = "\0\03"; + | ^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad5 = "\0\x03"; - | ~~~~ +LL | let _bad5 = "\0\x03"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad5 = "\0\x0003"; - | ~~~~~~ +LL | let _bad5 = "\0\x0003"; + | ~~~~~~ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:16:23 @@ -107,7 +107,7 @@ LL | let _bad6 = "Text-\055\x0077-MoreText"; | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:21:31 + --> tests/ui/octal_escapes.rs:20:31 | LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | ^^^ @@ -122,7 +122,7 @@ LL | let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:21:34 + --> tests/ui/octal_escapes.rs:20:34 | LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | ^^^ @@ -137,34 +137,34 @@ LL | let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:26:15 + --> tests/ui/octal_escapes.rs:24:19 | -LL | let _bad8 = "锈\01锈"; - | ^^^ +LL | let _bad8 = "锈\01锈"; + | ^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad8 = "锈\x01锈"; - | ~~~~ +LL | let _bad8 = "锈\x01锈"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad8 = "锈\x0001锈"; - | ~~~~~~ +LL | let _bad8 = "锈\x0001锈"; + | ~~~~~~ error: octal-looking escape in a literal - --> tests/ui/octal_escapes.rs:28:15 + --> tests/ui/octal_escapes.rs:26:19 | -LL | let _bad9 = "锈\011锈"; - | ^^^^ +LL | let _bad9 = "锈\011锈"; + | ^^^^ | help: if an octal escape is intended, use a hex escape instead | -LL | let _bad9 = "锈\x09锈"; - | ~~~~ +LL | let _bad9 = "锈\x09锈"; + | ~~~~ help: if a null escape is intended, disambiguate using | -LL | let _bad9 = "锈\x0011锈"; - | ~~~~~~ +LL | let _bad9 = "锈\x0011锈"; + | ~~~~~~ error: aborting due to 11 previous errors diff --git a/tests/ui/ok_expect.rs b/tests/ui/ok_expect.rs index 33702878ddb7..efb56f242a74 100644 --- a/tests/ui/ok_expect.rs +++ b/tests/ui/ok_expect.rs @@ -35,5 +35,4 @@ fn main() { let res6: Result = Ok(0); res6.ok().expect("meh"); //~^ ok_expect - } diff --git a/tests/ui/only_used_in_recursion.rs b/tests/ui/only_used_in_recursion.rs index cf872920a6e2..7d6075ba9ea4 100644 --- a/tests/ui/only_used_in_recursion.rs +++ b/tests/ui/only_used_in_recursion.rs @@ -9,21 +9,20 @@ fn _simple2(x: u32) -> u32 { } fn _one_unused(flag: u32, a: usize) -> usize { -//~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 } else { _one_unused(flag - 1, a) } } fn _two_unused(flag: u32, a: u32, b: i32) -> usize { -//~^ only_used_in_recursion -//~| only_used_in_recursion - + //~^ only_used_in_recursion + //~| only_used_in_recursion if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) } } fn _with_calc(flag: u32, a: i64) -> usize { -//~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 @@ -38,9 +37,8 @@ fn _used_with_flag(flag: u32, a: u32) -> usize { } fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { -//~^ only_used_in_recursion -//~| only_used_in_recursion - + //~^ only_used_in_recursion + //~| only_used_in_recursion if flag == 0 { 0 @@ -50,9 +48,8 @@ fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { } fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { -//~^ only_used_in_recursion -//~| only_used_in_recursion - + //~^ only_used_in_recursion + //~| only_used_in_recursion if flag == 0 { 0 @@ -62,7 +59,7 @@ fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { } fn _not_primitive(flag: u32, b: String) -> usize { -//~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 } else { _not_primitive(flag - 1, b) } } @@ -71,15 +68,14 @@ struct A; impl A { fn _method(flag: usize, a: usize) -> usize { - //~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 } else { Self::_method(flag - 1, a) } } fn _method_self(&self, flag: usize, a: usize) -> usize { - //~^ only_used_in_recursion - //~| only_used_in_recursion - + //~^ only_used_in_recursion + //~| only_used_in_recursion if flag == 0 { 0 } else { self._method_self(flag - 1, a) } } @@ -92,13 +88,13 @@ trait B { impl B for A { fn method(flag: u32, a: usize) -> usize { - //~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 } else { Self::method(flag - 1, a) } } fn method_self(&self, flag: u32, a: usize) -> usize { - //~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 } else { self.method_self(flag - 1, a) } } @@ -126,13 +122,13 @@ impl B for u32 { trait C { fn method(flag: u32, a: usize) -> usize { - //~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 } else { Self::method(flag - 1, a) } } fn method_self(&self, flag: u32, a: usize) -> usize { - //~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 } else { self.method_self(flag - 1, a) } } diff --git a/tests/ui/only_used_in_recursion.stderr b/tests/ui/only_used_in_recursion.stderr index 1f1aa75be662..ca08319e1120 100644 --- a/tests/ui/only_used_in_recursion.stderr +++ b/tests/ui/only_used_in_recursion.stderr @@ -19,7 +19,7 @@ LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:22:53 + --> tests/ui/only_used_in_recursion.rs:21:53 | LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) } | ^ @@ -31,163 +31,163 @@ LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:22:56 + --> tests/ui/only_used_in_recursion.rs:21:56 | LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:25:26 + --> tests/ui/only_used_in_recursion.rs:24:26 | LL | fn _with_calc(flag: u32, a: i64) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:31:32 + --> tests/ui/only_used_in_recursion.rs:30:32 | LL | _with_calc(flag - 1, (-a + 10) * 5) | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:40:33 + --> tests/ui/only_used_in_recursion.rs:39:33 | LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:48:38 + --> tests/ui/only_used_in_recursion.rs:46:38 | LL | _used_with_unused(flag - 1, -a, a + b) | ^ ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:40:41 + --> tests/ui/only_used_in_recursion.rs:39:41 | LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:48:45 + --> tests/ui/only_used_in_recursion.rs:46:45 | LL | _used_with_unused(flag - 1, -a, a + b) | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:52:35 + --> tests/ui/only_used_in_recursion.rs:50:35 | LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:60:39 + --> tests/ui/only_used_in_recursion.rs:57:39 | LL | _codependent_unused(flag - 1, a * b, a + b) | ^ ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:52:43 + --> tests/ui/only_used_in_recursion.rs:50:43 | LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:60:43 + --> tests/ui/only_used_in_recursion.rs:57:43 | LL | _codependent_unused(flag - 1, a * b, a + b) | ^ ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:64:30 + --> tests/ui/only_used_in_recursion.rs:61:30 | LL | fn _not_primitive(flag: u32, b: String) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:67:56 + --> tests/ui/only_used_in_recursion.rs:64:56 | LL | if flag == 0 { 0 } else { _not_primitive(flag - 1, b) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:73:29 + --> tests/ui/only_used_in_recursion.rs:70:29 | LL | fn _method(flag: usize, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:76:59 + --> tests/ui/only_used_in_recursion.rs:73:59 | LL | if flag == 0 { 0 } else { Self::_method(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:79:22 + --> tests/ui/only_used_in_recursion.rs:76:22 | LL | fn _method_self(&self, flag: usize, a: usize) -> usize { | ^^^^ | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:84:35 + --> tests/ui/only_used_in_recursion.rs:80:35 | LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) } | ^^^^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:79:41 + --> tests/ui/only_used_in_recursion.rs:76:41 | LL | fn _method_self(&self, flag: usize, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:84:63 + --> tests/ui/only_used_in_recursion.rs:80:63 | LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:94:26 + --> tests/ui/only_used_in_recursion.rs:90:26 | LL | fn method(flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:97:58 + --> tests/ui/only_used_in_recursion.rs:93:58 | LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:100:38 + --> tests/ui/only_used_in_recursion.rs:96:38 | LL | fn method_self(&self, flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:103:62 + --> tests/ui/only_used_in_recursion.rs:99:62 | LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:128:26 + --> tests/ui/only_used_in_recursion.rs:124:26 | LL | fn method(flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:131:58 + --> tests/ui/only_used_in_recursion.rs:127:58 | LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) } | ^ error: parameter is only used in recursion - --> tests/ui/only_used_in_recursion.rs:134:38 + --> tests/ui/only_used_in_recursion.rs:130:38 | LL | fn method_self(&self, flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: parameter used here - --> tests/ui/only_used_in_recursion.rs:137:62 + --> tests/ui/only_used_in_recursion.rs:133:62 | LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) } | ^ diff --git a/tests/ui/only_used_in_recursion2.rs b/tests/ui/only_used_in_recursion2.rs index e4639c8b8a45..2fe4e7b35d38 100644 --- a/tests/ui/only_used_in_recursion2.rs +++ b/tests/ui/only_used_in_recursion2.rs @@ -1,10 +1,10 @@ #![warn(clippy::only_used_in_recursion)] //@no-rustfix fn _with_inner(flag: u32, a: u32, b: u32) -> usize { -//~^ only_used_in_recursion + //~^ only_used_in_recursion fn inner(flag: u32, a: u32) -> u32 { - //~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 } else { inner(flag, a) } } @@ -14,7 +14,7 @@ fn _with_inner(flag: u32, a: u32, b: u32) -> usize { } fn _with_closure(a: Option, b: u32, f: impl Fn(u32, u32) -> Option) -> u32 { -//~^ only_used_in_recursion + //~^ only_used_in_recursion if let Some(x) = a.and_then(|x| f(x, x)) { _with_closure(Some(x), b, f) @@ -66,7 +66,7 @@ impl E<()> for () { } fn overwritten_param(flag: u32, mut a: usize) -> usize { -//~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { return 0; @@ -79,7 +79,7 @@ fn overwritten_param(flag: u32, mut a: usize) -> usize { } fn field_direct(flag: u32, mut a: (usize,)) -> usize { -//~^ only_used_in_recursion + //~^ only_used_in_recursion if flag == 0 { 0 diff --git a/tests/ui/op_ref.fixed b/tests/ui/op_ref.fixed index a67f883fe2e2..46a59e419cce 100644 --- a/tests/ui/op_ref.fixed +++ b/tests/ui/op_ref.fixed @@ -11,8 +11,6 @@ fn main() { let foo = 5 - 6; //~^ op_ref - - let bar = String::new(); let bar = "foo" == &bar; @@ -58,7 +56,6 @@ fn main() { let y = Y(2); let z = x & y; //~^ op_ref - } #[derive(Clone, Copy)] diff --git a/tests/ui/op_ref.rs b/tests/ui/op_ref.rs index 798484c9fe9e..e10840ff4b97 100644 --- a/tests/ui/op_ref.rs +++ b/tests/ui/op_ref.rs @@ -11,8 +11,6 @@ fn main() { let foo = &5 - &6; //~^ op_ref - - let bar = String::new(); let bar = "foo" == &bar; @@ -58,7 +56,6 @@ fn main() { let y = Y(2); let z = x & &y; //~^ op_ref - } #[derive(Clone, Copy)] diff --git a/tests/ui/op_ref.stderr b/tests/ui/op_ref.stderr index 86d0be4272c6..f3fb3920ee1f 100644 --- a/tests/ui/op_ref.stderr +++ b/tests/ui/op_ref.stderr @@ -12,7 +12,7 @@ LL | let foo = 5 - 6; | ~ ~ error: taken reference of right operand - --> tests/ui/op_ref.rs:59:13 + --> tests/ui/op_ref.rs:57:13 | LL | let z = x & &y; | ^^^^-- @@ -20,7 +20,7 @@ LL | let z = x & &y; | help: use the right value directly: `y` error: taken reference of right operand - --> tests/ui/op_ref.rs:94:17 + --> tests/ui/op_ref.rs:91:17 | LL | let _ = one * &self; | ^^^^^^----- @@ -28,7 +28,7 @@ LL | let _ = one * &self; | help: use the right value directly: `self` error: taken reference of right operand - --> tests/ui/op_ref.rs:97:17 + --> tests/ui/op_ref.rs:94:17 | LL | let _ = two + &three; | ^^^^^^------ diff --git a/tests/ui/open_options.rs b/tests/ui/open_options.rs index acc2a5f86164..f2f6e6edb4de 100644 --- a/tests/ui/open_options.rs +++ b/tests/ui/open_options.rs @@ -17,11 +17,9 @@ fn main() { OpenOptions::new().read(true).truncate(true).open("foo.txt"); //~^ nonsensical_open_options - OpenOptions::new().append(true).truncate(true).open("foo.txt"); //~^ nonsensical_open_options - OpenOptions::new().read(true).read(false).open("foo.txt"); //~^ nonsensical_open_options @@ -30,7 +28,6 @@ fn main() { .truncate(true) // Ensure we don't trigger suspicious open options by having create without truncate .create(false) //~^ nonsensical_open_options - .open("foo.txt"); OpenOptions::new().write(true).write(false).open("foo.txt"); //~^ nonsensical_open_options @@ -41,11 +38,9 @@ fn main() { OpenOptions::new().truncate(true).truncate(false).open("foo.txt"); //~^ nonsensical_open_options - std::fs::File::options().read(true).read(false).open("foo.txt"); //~^ nonsensical_open_options - let mut options = std::fs::OpenOptions::new(); options.read(true); options.read(false); diff --git a/tests/ui/open_options.stderr b/tests/ui/open_options.stderr index 27d8d01f3b5f..11b2d55fa058 100644 --- a/tests/ui/open_options.stderr +++ b/tests/ui/open_options.stderr @@ -8,43 +8,43 @@ LL | OpenOptions::new().read(true).truncate(true).open("foo.txt"); = help: to override `-D warnings` add `#[allow(clippy::nonsensical_open_options)]` error: file opened with `append` and `truncate` - --> tests/ui/open_options.rs:21:5 + --> tests/ui/open_options.rs:20:5 | LL | OpenOptions::new().append(true).truncate(true).open("foo.txt"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the method `read` is called more than once - --> tests/ui/open_options.rs:25:35 + --> tests/ui/open_options.rs:23:35 | LL | OpenOptions::new().read(true).read(false).open("foo.txt"); | ^^^^^^^^^^^ error: the method `create` is called more than once - --> tests/ui/open_options.rs:31:10 + --> tests/ui/open_options.rs:29:10 | LL | .create(false) | ^^^^^^^^^^^^^ error: the method `write` is called more than once - --> tests/ui/open_options.rs:35:36 + --> tests/ui/open_options.rs:32:36 | LL | OpenOptions::new().write(true).write(false).open("foo.txt"); | ^^^^^^^^^^^^ error: the method `append` is called more than once - --> tests/ui/open_options.rs:38:37 + --> tests/ui/open_options.rs:35:37 | LL | OpenOptions::new().append(true).append(false).open("foo.txt"); | ^^^^^^^^^^^^^ error: the method `truncate` is called more than once - --> tests/ui/open_options.rs:41:39 + --> tests/ui/open_options.rs:38:39 | LL | OpenOptions::new().truncate(true).truncate(false).open("foo.txt"); | ^^^^^^^^^^^^^^^ error: the method `read` is called more than once - --> tests/ui/open_options.rs:45:41 + --> tests/ui/open_options.rs:41:41 | LL | std::fs::File::options().read(true).read(false).open("foo.txt"); | ^^^^^^^^^^^ diff --git a/tests/ui/open_options_fixable.fixed b/tests/ui/open_options_fixable.fixed index 7ba5a8782bef..7f601eec2cf0 100644 --- a/tests/ui/open_options_fixable.fixed +++ b/tests/ui/open_options_fixable.fixed @@ -4,5 +4,4 @@ use std::fs::OpenOptions; fn main() { OpenOptions::new().create(true).truncate(true).open("foo.txt"); //~^ suspicious_open_options - } diff --git a/tests/ui/open_options_fixable.rs b/tests/ui/open_options_fixable.rs index 230d6d782074..5f03528d7a56 100644 --- a/tests/ui/open_options_fixable.rs +++ b/tests/ui/open_options_fixable.rs @@ -4,5 +4,4 @@ use std::fs::OpenOptions; fn main() { OpenOptions::new().create(true).open("foo.txt"); //~^ suspicious_open_options - } diff --git a/tests/ui/option_filter_map.fixed b/tests/ui/option_filter_map.fixed index d8d3ba7edd28..d390c41af53c 100644 --- a/tests/ui/option_filter_map.fixed +++ b/tests/ui/option_filter_map.fixed @@ -14,7 +14,6 @@ fn main() { let _ = Some(1).map(odds_out).flatten(); //~^ option_filter_map - let _ = vec![Some(1)].into_iter().flatten(); //~^ option_filter_map diff --git a/tests/ui/option_filter_map.rs b/tests/ui/option_filter_map.rs index 68abaff01b44..2d3b983a7670 100644 --- a/tests/ui/option_filter_map.rs +++ b/tests/ui/option_filter_map.rs @@ -14,7 +14,6 @@ fn main() { let _ = Some(1).map(odds_out).filter(|o| o.is_some()).map(|o| o.unwrap()); //~^ option_filter_map - let _ = vec![Some(1)].into_iter().filter(Option::is_some).map(Option::unwrap); //~^ option_filter_map @@ -26,14 +25,12 @@ fn main() { .map(odds_out) .filter(Option::is_some) //~^ option_filter_map - .map(Option::unwrap); let _ = vec![1] .into_iter() .map(odds_out) .filter(|o| o.is_some()) //~^ option_filter_map - .map(|o| o.unwrap()); } diff --git a/tests/ui/option_filter_map.stderr b/tests/ui/option_filter_map.stderr index 24a3a2d7605c..df3c1f9d47b8 100644 --- a/tests/ui/option_filter_map.stderr +++ b/tests/ui/option_filter_map.stderr @@ -26,32 +26,32 @@ LL | let _ = Some(1).map(odds_out).filter(|o| o.is_some()).map(|o| o.unwrap( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:18:39 + --> tests/ui/option_filter_map.rs:17:39 | LL | let _ = vec![Some(1)].into_iter().filter(Option::is_some).map(Option::unwrap); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:21:39 + --> tests/ui/option_filter_map.rs:20:39 | LL | let _ = vec![Some(1)].into_iter().filter(|o| o.is_some()).map(|o| o.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:27:10 + --> tests/ui/option_filter_map.rs:26:10 | LL | .filter(Option::is_some) | __________^ -... | +LL | | LL | | .map(Option::unwrap); | |____________________________^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Some` followed by `unwrap` - --> tests/ui/option_filter_map.rs:34:10 + --> tests/ui/option_filter_map.rs:32:10 | LL | .filter(|o| o.is_some()) | __________^ -... | +LL | | LL | | .map(|o| o.unwrap()); | |____________________________^ help: consider using `flatten` instead: `flatten()` diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index eb1aabe63e75..56b313244e36 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -28,19 +28,19 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { let _ = num.as_ref().map_or(&0, |s| s); //~^ option_if_let_else let _ = num.as_mut().map_or(&0, |s| { - //~^ option_if_let_else + //~^ option_if_let_else *s += 1; s }); let _ = num.as_ref().map_or(&0, |s| s); //~^ option_if_let_else let _ = num.map_or(0, |mut s| { - //~^ option_if_let_else + //~^ option_if_let_else s += 1; s }); let _ = num.as_mut().map_or(&0, |s| { - //~^ option_if_let_else + //~^ option_if_let_else *s += 1; s }); @@ -48,7 +48,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { fn longer_body(arg: Option) -> u32 { arg.map_or(13, |x| { - //~^ option_if_let_else + //~^ option_if_let_else let y = x * x; y * y }) @@ -105,7 +105,7 @@ fn test_result_impure_else(variable: Result) -> bool { println!("Err"); false }, |binding| { - //~^ option_if_let_else + //~^ option_if_let_else println!("Ok {binding}"); true }) @@ -167,7 +167,7 @@ fn main() { let s = String::new(); // Lint, `Some` branch consumes `s`, but else branch doesn't use `s`. let _ = Some(0).map_or(1, |x| { - //~^ option_if_let_else + //~^ option_if_let_else let s = s; s.len() + x }); diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index f2e2de02a93d..4a4bb141ed54 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -10,7 +10,7 @@ fn bad1(string: Option<&str>) -> (bool, &str) { if let Some(x) = string { - //~^ option_if_let_else + //~^ option_if_let_else (true, x) } else { (false, "hello") @@ -33,7 +33,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { let _ = if let Some(s) = &num { s } else { &0 }; //~^ option_if_let_else let _ = if let Some(s) = &mut num { - //~^ option_if_let_else + //~^ option_if_let_else *s += 1; s } else { @@ -42,14 +42,14 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { let _ = if let Some(ref s) = num { s } else { &0 }; //~^ option_if_let_else let _ = if let Some(mut s) = num { - //~^ option_if_let_else + //~^ option_if_let_else s += 1; s } else { 0 }; let _ = if let Some(ref mut s) = num { - //~^ option_if_let_else + //~^ option_if_let_else *s += 1; s } else { @@ -59,7 +59,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { fn longer_body(arg: Option) -> u32 { if let Some(x) = arg { - //~^ option_if_let_else + //~^ option_if_let_else let y = x * x; y * y } else { @@ -73,7 +73,7 @@ fn impure_else(arg: Option) { 1 }; let _ = if let Some(x) = arg { - //~^ option_if_let_else + //~^ option_if_let_else x } else { // map_or_else must be suggested @@ -83,7 +83,7 @@ fn impure_else(arg: Option) { fn test_map_or_else(arg: Option) { let _ = if let Some(x) = arg { - //~^ option_if_let_else + //~^ option_if_let_else x * x * x * x } else { let mut y = 1; @@ -117,7 +117,7 @@ fn pattern_to_vec(pattern: &str) -> Vec { .split('/') .flat_map(|s| { if let Some(idx) = s.find('.') { - //~^ option_if_let_else + //~^ option_if_let_else vec![s[..idx].to_string(), s[idx..].to_string()] } else { vec![s.to_string()] @@ -129,7 +129,7 @@ fn pattern_to_vec(pattern: &str) -> Vec { // #10335 fn test_result_impure_else(variable: Result) -> bool { if let Ok(binding) = variable { - //~^ option_if_let_else + //~^ option_if_let_else println!("Ok {binding}"); true } else { @@ -165,7 +165,7 @@ fn main() { let _ = impure_else(None); let _ = if let Some(x) = Some(0) { - //~^ option_if_let_else + //~^ option_if_let_else loop { if x == 0 { break x; @@ -199,7 +199,7 @@ fn main() { let s = String::new(); // Lint, `Some` branch consumes `s`, but else branch doesn't use `s`. let _ = if let Some(x) = Some(0) { - //~^ option_if_let_else + //~^ option_if_let_else let s = s; s.len() + x } else { @@ -239,24 +239,24 @@ fn main() { // issue #8492 let _ = match s { - //~^ option_if_let_else + //~^ option_if_let_else Some(string) => string.len(), None => 1, }; let _ = match Some(10) { - //~^ option_if_let_else + //~^ option_if_let_else Some(a) => a + 1, None => 5, }; let res: Result = Ok(5); let _ = match res { - //~^ option_if_let_else + //~^ option_if_let_else Ok(a) => a + 1, _ => 1, }; let _ = match res { - //~^ option_if_let_else + //~^ option_if_let_else Err(_) => 1, Ok(a) => a + 1, }; @@ -279,7 +279,7 @@ mod issue10729 { pub fn reproduce(initial: &Option) { // 👇 needs `.as_ref()` because initial is an `&Option<_>` let _ = match initial { - //~^ option_if_let_else + //~^ option_if_let_else Some(value) => do_something(value), None => 42, }; @@ -287,7 +287,7 @@ mod issue10729 { pub fn reproduce2(initial: &mut Option) { let _ = match initial { - //~^ option_if_let_else + //~^ option_if_let_else Some(value) => do_something2(value), None => 42, }; @@ -311,7 +311,7 @@ fn issue11429() { let opt: Option> = None; let mut _hashmap = if let Some(hm) = &opt { - //~^ option_if_let_else + //~^ option_if_let_else hm.clone() } else { HashMap::new() diff --git a/tests/ui/option_map_or_none.fixed b/tests/ui/option_map_or_none.fixed index c4d9f25bd28c..183bf32e5361 100644 --- a/tests/ui/option_map_or_none.fixed +++ b/tests/ui/option_map_or_none.fixed @@ -16,7 +16,7 @@ fn main() { let _: Option = opt.and_then(bar); //~^ option_map_or_none let _: Option = opt.and_then(|x| { - //~^ option_map_or_none + //~^ option_map_or_none let offset = 0; let height = x; Some(offset + height) diff --git a/tests/ui/option_map_or_none.rs b/tests/ui/option_map_or_none.rs index c3143f50cb6c..626f206b2598 100644 --- a/tests/ui/option_map_or_none.rs +++ b/tests/ui/option_map_or_none.rs @@ -19,7 +19,7 @@ fn main() { let _: Option = opt.map_or(None, bar); //~^ option_map_or_none let _: Option = opt.map_or(None, |x| { - //~^ option_map_or_none + //~^ option_map_or_none let offset = 0; let height = x; Some(offset + height) diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed index 73ba4394e983..7014e20c1f85 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -373,7 +373,6 @@ fn fn_call_in_nested_expr() { } let opt: Option = Some(1); - let _ = opt.unwrap_or_else(f); // suggest `.unwrap_or_else(f)` //~^ or_fun_call // @@ -383,7 +382,7 @@ fn fn_call_in_nested_expr() { // let _ = opt.unwrap_or_else(|| { - //~^ or_fun_call + //~^ or_fun_call let x = f(); x + 1 }); diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index ed3469178196..d8a0ab033c4d 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -373,7 +373,6 @@ fn fn_call_in_nested_expr() { } let opt: Option = Some(1); - let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)` //~^ or_fun_call // @@ -383,7 +382,7 @@ fn fn_call_in_nested_expr() { // let _ = opt.unwrap_or({ - //~^ or_fun_call + //~^ or_fun_call let x = f(); x + 1 }); diff --git a/tests/ui/or_fun_call.stderr b/tests/ui/or_fun_call.stderr index a1eaf08e4458..0cc8ad39421c 100644 --- a/tests/ui/or_fun_call.stderr +++ b/tests/ui/or_fun_call.stderr @@ -197,19 +197,19 @@ LL | let _ = stringy.unwrap_or_else(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:377:17 + --> tests/ui/or_fun_call.rs:376:17 | LL | let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(f)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:381:17 + --> tests/ui/or_fun_call.rs:380:17 | LL | let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| f() + 1)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:385:17 + --> tests/ui/or_fun_call.rs:384:17 | LL | let _ = opt.unwrap_or({ | _________________^ @@ -229,19 +229,19 @@ LL ~ }); | error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:391:17 + --> tests/ui/or_fun_call.rs:390:17 | LL | let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)` | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| f() + 1, |v| v)` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:395:17 + --> tests/ui/or_fun_call.rs:394:17 | LL | let _ = opt.unwrap_or({ i32::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:402:21 + --> tests/ui/or_fun_call.rs:401:21 | LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })` diff --git a/tests/ui/out_of_bounds_indexing/issue-3102.rs b/tests/ui/out_of_bounds_indexing/issue-3102.rs index 3ba35482780d..e1e0fa02a937 100644 --- a/tests/ui/out_of_bounds_indexing/issue-3102.rs +++ b/tests/ui/out_of_bounds_indexing/issue-3102.rs @@ -9,8 +9,6 @@ fn main() { &x[num..10]; //~^ out_of_bounds_indexing - &x[10..num]; //~^ out_of_bounds_indexing - } diff --git a/tests/ui/out_of_bounds_indexing/issue-3102.stderr b/tests/ui/out_of_bounds_indexing/issue-3102.stderr index 304adcfdc2d3..8bf0152601df 100644 --- a/tests/ui/out_of_bounds_indexing/issue-3102.stderr +++ b/tests/ui/out_of_bounds_indexing/issue-3102.stderr @@ -8,7 +8,7 @@ LL | &x[num..10]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/issue-3102.rs:13:8 + --> tests/ui/out_of_bounds_indexing/issue-3102.rs:12:8 | LL | &x[10..num]; | ^^ diff --git a/tests/ui/out_of_bounds_indexing/simple.rs b/tests/ui/out_of_bounds_indexing/simple.rs index 86f29f9ee408..e613e527eee4 100644 --- a/tests/ui/out_of_bounds_indexing/simple.rs +++ b/tests/ui/out_of_bounds_indexing/simple.rs @@ -7,7 +7,6 @@ fn main() { &x[..=4]; //~^ out_of_bounds_indexing - &x[1..5]; //~^ out_of_bounds_indexing @@ -23,7 +22,6 @@ fn main() { &x[0..=4]; //~^ out_of_bounds_indexing - &x[4..]; // Ok, should not produce stderr. &x[..4]; // Ok, should not produce stderr. &x[..]; // Ok, should not produce stderr. diff --git a/tests/ui/out_of_bounds_indexing/simple.stderr b/tests/ui/out_of_bounds_indexing/simple.stderr index 47f36e51bffa..f89531733431 100644 --- a/tests/ui/out_of_bounds_indexing/simple.stderr +++ b/tests/ui/out_of_bounds_indexing/simple.stderr @@ -8,31 +8,31 @@ LL | &x[..=4]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:11:11 + --> tests/ui/out_of_bounds_indexing/simple.rs:10:11 | LL | &x[1..5]; | ^ error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:14:8 + --> tests/ui/out_of_bounds_indexing/simple.rs:13:8 | LL | &x[5..]; | ^ error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:17:10 + --> tests/ui/out_of_bounds_indexing/simple.rs:16:10 | LL | &x[..5]; | ^ error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:20:8 + --> tests/ui/out_of_bounds_indexing/simple.rs:19:8 | LL | &x[5..].iter().map(|x| 2 * x).collect::>(); | ^ error: range is out of bounds - --> tests/ui/out_of_bounds_indexing/simple.rs:23:12 + --> tests/ui/out_of_bounds_indexing/simple.rs:22:12 | LL | &x[0..=4]; | ^ diff --git a/tests/ui/panic_in_result_fn.rs b/tests/ui/panic_in_result_fn.rs index dc0fc65fd777..005e38db9021 100644 --- a/tests/ui/panic_in_result_fn.rs +++ b/tests/ui/panic_in_result_fn.rs @@ -5,7 +5,6 @@ struct A; impl A { fn result_with_panic() -> Result // should emit lint //~^ panic_in_result_fn - { panic!("error"); } @@ -53,13 +52,12 @@ impl A { fn function_result_with_panic() -> Result // should emit lint //~^ panic_in_result_fn - { panic!("error"); } fn in_closure() -> Result { -//~^ panic_in_result_fn + //~^ panic_in_result_fn let c = || panic!(); c() } diff --git a/tests/ui/panic_in_result_fn.stderr b/tests/ui/panic_in_result_fn.stderr index 17fd03733abc..1067f4fac11c 100644 --- a/tests/ui/panic_in_result_fn.stderr +++ b/tests/ui/panic_in_result_fn.stderr @@ -2,13 +2,15 @@ error: used `panic!()` or assertion in a function that returns `Result` --> tests/ui/panic_in_result_fn.rs:6:5 | LL | / fn result_with_panic() -> Result // should emit lint -... | +LL | | +LL | | { +LL | | panic!("error"); LL | | } | |_____^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn.rs:10:9 + --> tests/ui/panic_in_result_fn.rs:9:9 | LL | panic!("error"); | ^^^^^^^^^^^^^^^ @@ -16,22 +18,24 @@ LL | panic!("error"); = help: to override `-D warnings` add `#[allow(clippy::panic_in_result_fn)]` error: used `panic!()` or assertion in a function that returns `Result` - --> tests/ui/panic_in_result_fn.rs:54:1 + --> tests/ui/panic_in_result_fn.rs:53:1 | LL | / fn function_result_with_panic() -> Result // should emit lint -... | +LL | | +LL | | { +LL | | panic!("error"); LL | | } | |_^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn.rs:58:5 + --> tests/ui/panic_in_result_fn.rs:56:5 | LL | panic!("error"); | ^^^^^^^^^^^^^^^ error: used `panic!()` or assertion in a function that returns `Result` - --> tests/ui/panic_in_result_fn.rs:61:1 + --> tests/ui/panic_in_result_fn.rs:59:1 | LL | / fn in_closure() -> Result { LL | | @@ -42,7 +46,7 @@ LL | | } | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn.rs:63:16 + --> tests/ui/panic_in_result_fn.rs:61:16 | LL | let c = || panic!(); | ^^^^^^^^ diff --git a/tests/ui/panic_in_result_fn_assertions.rs b/tests/ui/panic_in_result_fn_assertions.rs index 894e63f8ff1e..4e7028241579 100644 --- a/tests/ui/panic_in_result_fn_assertions.rs +++ b/tests/ui/panic_in_result_fn_assertions.rs @@ -6,7 +6,6 @@ struct A; impl A { fn result_with_assert_with_message(x: i32) -> Result // should emit lint //~^ panic_in_result_fn - { assert!(x == 5, "wrong argument"); Ok(true) @@ -14,7 +13,6 @@ impl A { fn result_with_assert_eq(x: i32) -> Result // should emit lint //~^ panic_in_result_fn - { assert_eq!(x, 5); Ok(true) @@ -22,7 +20,6 @@ impl A { fn result_with_assert_ne(x: i32) -> Result // should emit lint //~^ panic_in_result_fn - { assert_ne!(x, 1); Ok(true) diff --git a/tests/ui/panic_in_result_fn_assertions.stderr b/tests/ui/panic_in_result_fn_assertions.stderr index 46bc16fe8e16..cdb7762510d9 100644 --- a/tests/ui/panic_in_result_fn_assertions.stderr +++ b/tests/ui/panic_in_result_fn_assertions.stderr @@ -2,14 +2,16 @@ error: used `panic!()` or assertion in a function that returns `Result` --> tests/ui/panic_in_result_fn_assertions.rs:7:5 | LL | / fn result_with_assert_with_message(x: i32) -> Result // should emit lint -... | +LL | | +LL | | { +LL | | assert!(x == 5, "wrong argument"); LL | | Ok(true) LL | | } | |_____^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn_assertions.rs:11:9 + --> tests/ui/panic_in_result_fn_assertions.rs:10:9 | LL | assert!(x == 5, "wrong argument"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,33 +19,37 @@ LL | assert!(x == 5, "wrong argument"); = help: to override `-D warnings` add `#[allow(clippy::panic_in_result_fn)]` error: used `panic!()` or assertion in a function that returns `Result` - --> tests/ui/panic_in_result_fn_assertions.rs:15:5 + --> tests/ui/panic_in_result_fn_assertions.rs:14:5 | LL | / fn result_with_assert_eq(x: i32) -> Result // should emit lint -... | +LL | | +LL | | { +LL | | assert_eq!(x, 5); LL | | Ok(true) LL | | } | |_____^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn_assertions.rs:19:9 + --> tests/ui/panic_in_result_fn_assertions.rs:17:9 | LL | assert_eq!(x, 5); | ^^^^^^^^^^^^^^^^ error: used `panic!()` or assertion in a function that returns `Result` - --> tests/ui/panic_in_result_fn_assertions.rs:23:5 + --> tests/ui/panic_in_result_fn_assertions.rs:21:5 | LL | / fn result_with_assert_ne(x: i32) -> Result // should emit lint -... | +LL | | +LL | | { +LL | | assert_ne!(x, 1); LL | | Ok(true) LL | | } | |_____^ | = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking - --> tests/ui/panic_in_result_fn_assertions.rs:27:9 + --> tests/ui/panic_in_result_fn_assertions.rs:24:9 | LL | assert_ne!(x, 1); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/panicking_macros.rs b/tests/ui/panicking_macros.rs index a718dd925216..65854d7eb4bf 100644 --- a/tests/ui/panicking_macros.rs +++ b/tests/ui/panicking_macros.rs @@ -22,7 +22,6 @@ fn panic() { panic!(); //~^ panic - panic!("message"); //~^ panic @@ -37,7 +36,6 @@ fn todo() { todo!(); //~^ todo - todo!("message"); //~^ todo @@ -52,7 +50,6 @@ fn unimplemented() { unimplemented!(); //~^ unimplemented - unimplemented!("message"); //~^ unimplemented @@ -67,7 +64,6 @@ fn unreachable() { unreachable!(); //~^ unreachable - unreachable!("message"); //~^ unreachable @@ -90,7 +86,6 @@ fn core_versions() { unreachable!(); //~^ unreachable - } fn assert() { diff --git a/tests/ui/panicking_macros.stderr b/tests/ui/panicking_macros.stderr index 0c2b4508a803..03e459e4ec6e 100644 --- a/tests/ui/panicking_macros.stderr +++ b/tests/ui/panicking_macros.stderr @@ -8,19 +8,19 @@ LL | panic!(); = help: to override `-D warnings` add `#[allow(clippy::panic)]` error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:26:5 + --> tests/ui/panicking_macros.rs:25:5 | LL | panic!("message"); | ^^^^^^^^^^^^^^^^^ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:29:5 + --> tests/ui/panicking_macros.rs:28:5 | LL | panic!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:37:5 + --> tests/ui/panicking_macros.rs:36:5 | LL | todo!(); | ^^^^^^^ @@ -29,19 +29,19 @@ LL | todo!(); = help: to override `-D warnings` add `#[allow(clippy::todo)]` error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:41:5 + --> tests/ui/panicking_macros.rs:39:5 | LL | todo!("message"); | ^^^^^^^^^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:44:5 + --> tests/ui/panicking_macros.rs:42:5 | LL | todo!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:52:5 + --> tests/ui/panicking_macros.rs:50:5 | LL | unimplemented!(); | ^^^^^^^^^^^^^^^^ @@ -50,19 +50,19 @@ LL | unimplemented!(); = help: to override `-D warnings` add `#[allow(clippy::unimplemented)]` error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:56:5 + --> tests/ui/panicking_macros.rs:53:5 | LL | unimplemented!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:59:5 + --> tests/ui/panicking_macros.rs:56:5 | LL | unimplemented!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:67:5 + --> tests/ui/panicking_macros.rs:64:5 | LL | unreachable!(); | ^^^^^^^^^^^^^^ @@ -71,37 +71,37 @@ LL | unreachable!(); = help: to override `-D warnings` add `#[allow(clippy::unreachable)]` error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:71:5 + --> tests/ui/panicking_macros.rs:67:5 | LL | unreachable!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:74:5 + --> tests/ui/panicking_macros.rs:70:5 | LL | unreachable!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:82:5 + --> tests/ui/panicking_macros.rs:78:5 | LL | panic!(); | ^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:85:5 + --> tests/ui/panicking_macros.rs:81:5 | LL | todo!(); | ^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:88:5 + --> tests/ui/panicking_macros.rs:84:5 | LL | unimplemented!(); | ^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:91:5 + --> tests/ui/panicking_macros.rs:87:5 | LL | unreachable!(); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/panicking_overflow_checks.rs b/tests/ui/panicking_overflow_checks.rs index 57a829d50d2c..29789c949756 100644 --- a/tests/ui/panicking_overflow_checks.rs +++ b/tests/ui/panicking_overflow_checks.rs @@ -2,20 +2,20 @@ #![allow(clippy::needless_if)] fn test(a: u32, b: u32, c: u32) { -if a + b < a {} -//~^ panicking_overflow_checks -if a > a + b {} -//~^ panicking_overflow_checks -if a + b < b {} -//~^ panicking_overflow_checks -if b > a + b {} -//~^ panicking_overflow_checks + if a + b < a {} + //~^ panicking_overflow_checks + if a > a + b {} + //~^ panicking_overflow_checks + if a + b < b {} + //~^ panicking_overflow_checks + if b > a + b {} + //~^ panicking_overflow_checks if a - b > b {} if b < a - b {} -if a - b > a {} -//~^ panicking_overflow_checks -if a < a - b {} -//~^ panicking_overflow_checks + if a - b > a {} + //~^ panicking_overflow_checks + if a < a - b {} + //~^ panicking_overflow_checks if a + b < c {} if c > a + b {} if a - b < c {} diff --git a/tests/ui/panicking_overflow_checks.stderr b/tests/ui/panicking_overflow_checks.stderr index 3bb209ccfa7e..3022c9e52b0c 100644 --- a/tests/ui/panicking_overflow_checks.stderr +++ b/tests/ui/panicking_overflow_checks.stderr @@ -1,41 +1,41 @@ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:5:4 + --> tests/ui/panicking_overflow_checks.rs:5:8 | -LL | if a + b < a {} - | ^^^^^^^^^ +LL | if a + b < a {} + | ^^^^^^^^^ | = note: `-D clippy::panicking-overflow-checks` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::panicking_overflow_checks)]` error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:7:4 + --> tests/ui/panicking_overflow_checks.rs:7:8 | -LL | if a > a + b {} - | ^^^^^^^^^ +LL | if a > a + b {} + | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:9:4 + --> tests/ui/panicking_overflow_checks.rs:9:8 | -LL | if a + b < b {} - | ^^^^^^^^^ +LL | if a + b < b {} + | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:11:4 + --> tests/ui/panicking_overflow_checks.rs:11:8 | -LL | if b > a + b {} - | ^^^^^^^^^ +LL | if b > a + b {} + | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:15:4 + --> tests/ui/panicking_overflow_checks.rs:15:8 | -LL | if a - b > a {} - | ^^^^^^^^^ +LL | if a - b > a {} + | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> tests/ui/panicking_overflow_checks.rs:17:4 + --> tests/ui/panicking_overflow_checks.rs:17:8 | -LL | if a < a - b {} - | ^^^^^^^^^ +LL | if a < a - b {} + | ^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/partial_pub_fields.rs b/tests/ui/partial_pub_fields.rs index a0ee4f2b0496..27f4b2a0b4fc 100644 --- a/tests/ui/partial_pub_fields.rs +++ b/tests/ui/partial_pub_fields.rs @@ -9,7 +9,6 @@ fn main() { files: HashMap, pub paths: HashMap, //~^ partial_pub_fields - } pub struct Color { @@ -17,18 +16,15 @@ fn main() { pub g: u8, b: u8, //~^ partial_pub_fields - } pub struct Point(i32, pub i32); //~^ partial_pub_fields - pub struct Visibility { r#pub: bool, pub pos: u32, //~^ partial_pub_fields - } // Don't lint on empty structs; diff --git a/tests/ui/partial_pub_fields.stderr b/tests/ui/partial_pub_fields.stderr index 4232f3e82e45..af3b2f758757 100644 --- a/tests/ui/partial_pub_fields.stderr +++ b/tests/ui/partial_pub_fields.stderr @@ -9,7 +9,7 @@ LL | pub paths: HashMap, = help: to override `-D warnings` add `#[allow(clippy::partial_pub_fields)]` error: mixed usage of pub and non-pub fields - --> tests/ui/partial_pub_fields.rs:18:9 + --> tests/ui/partial_pub_fields.rs:17:9 | LL | b: u8, | ^ @@ -17,7 +17,7 @@ LL | b: u8, = help: consider using public field here error: mixed usage of pub and non-pub fields - --> tests/ui/partial_pub_fields.rs:23:27 + --> tests/ui/partial_pub_fields.rs:21:27 | LL | pub struct Point(i32, pub i32); | ^^^ @@ -25,7 +25,7 @@ LL | pub struct Point(i32, pub i32); = help: consider using private field here error: mixed usage of pub and non-pub fields - --> tests/ui/partial_pub_fields.rs:29:9 + --> tests/ui/partial_pub_fields.rs:26:9 | LL | pub pos: u32, | ^^^ diff --git a/tests/ui/partialeq_ne_impl.rs b/tests/ui/partialeq_ne_impl.rs index 42c235b381ef..a3b2b68708ba 100644 --- a/tests/ui/partialeq_ne_impl.rs +++ b/tests/ui/partialeq_ne_impl.rs @@ -7,8 +7,7 @@ impl PartialEq for Foo { true } fn ne(&self, _: &Foo) -> bool { - //~^ partialeq_ne_impl - + //~^ partialeq_ne_impl false } diff --git a/tests/ui/partialeq_ne_impl.stderr b/tests/ui/partialeq_ne_impl.stderr index ffc26afa075d..dc01a375060b 100644 --- a/tests/ui/partialeq_ne_impl.stderr +++ b/tests/ui/partialeq_ne_impl.stderr @@ -2,7 +2,9 @@ error: re-implementing `PartialEq::ne` is unnecessary --> tests/ui/partialeq_ne_impl.rs:9:5 | LL | / fn ne(&self, _: &Foo) -> bool { -... | +LL | | +LL | | +LL | | false LL | | } | |_____^ | diff --git a/tests/ui/partialeq_to_none.fixed b/tests/ui/partialeq_to_none.fixed index d650e28f2b68..e700cc56349f 100644 --- a/tests/ui/partialeq_to_none.fixed +++ b/tests/ui/partialeq_to_none.fixed @@ -64,7 +64,7 @@ fn main() { //~^ partialeq_to_none let _ = { - //~^ partialeq_to_none + //~^ partialeq_to_none /* This comment runs long */ diff --git a/tests/ui/partialeq_to_none.rs b/tests/ui/partialeq_to_none.rs index 77804b0765f1..1bae076dd337 100644 --- a/tests/ui/partialeq_to_none.rs +++ b/tests/ui/partialeq_to_none.rs @@ -64,7 +64,7 @@ fn main() { //~^ partialeq_to_none let _ = { - //~^ partialeq_to_none + //~^ partialeq_to_none /* This comment runs long */ diff --git a/tests/ui/path_ends_with_ext.fixed b/tests/ui/path_ends_with_ext.fixed index a20925f9ba67..fa4286e11644 100644 --- a/tests/ui/path_ends_with_ext.fixed +++ b/tests/ui/path_ends_with_ext.fixed @@ -11,7 +11,6 @@ fn test(path: &Path) { path.extension().is_some_and(|ext| ext == "md"); //~^ path_ends_with_ext - // some "extensions" are allowed by default path.ends_with(".git"); @@ -32,7 +31,6 @@ fn test(path: &Path) { fn under_msv(path: &Path) -> bool { path.extension().map_or(false, |ext| ext == "md") //~^ path_ends_with_ext - } fn main() {} diff --git a/tests/ui/path_ends_with_ext.rs b/tests/ui/path_ends_with_ext.rs index e20620e983d0..00d7ede8ef93 100644 --- a/tests/ui/path_ends_with_ext.rs +++ b/tests/ui/path_ends_with_ext.rs @@ -11,7 +11,6 @@ fn test(path: &Path) { path.ends_with(".md"); //~^ path_ends_with_ext - // some "extensions" are allowed by default path.ends_with(".git"); @@ -32,7 +31,6 @@ fn test(path: &Path) { fn under_msv(path: &Path) -> bool { path.ends_with(".md") //~^ path_ends_with_ext - } fn main() {} diff --git a/tests/ui/path_ends_with_ext.stderr b/tests/ui/path_ends_with_ext.stderr index 7016b8e5b8fb..deab71ff7626 100644 --- a/tests/ui/path_ends_with_ext.stderr +++ b/tests/ui/path_ends_with_ext.stderr @@ -8,7 +8,7 @@ LL | path.ends_with(".md"); = help: to override `-D warnings` add `#[allow(clippy::path_ends_with_ext)]` error: this looks like a failed attempt at checking for the file extension - --> tests/ui/path_ends_with_ext.rs:33:5 + --> tests/ui/path_ends_with_ext.rs:32:5 | LL | path.ends_with(".md") | ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().map_or(false, |ext| ext == "md")` diff --git a/tests/ui/pathbuf_init_then_push.fixed b/tests/ui/pathbuf_init_then_push.fixed index 43cc65f8dfbf..2a90b8ce2814 100644 --- a/tests/ui/pathbuf_init_then_push.fixed +++ b/tests/ui/pathbuf_init_then_push.fixed @@ -3,14 +3,14 @@ use std::path::PathBuf; fn main() { -let mut path_buf = PathBuf::from("foo"); + let mut path_buf = PathBuf::from("foo"); -path_buf = PathBuf::from("foo").join("bar"); + path_buf = PathBuf::from("foo").join("bar"); let bar = "bar"; -path_buf = PathBuf::from("foo").join(bar); + path_buf = PathBuf::from("foo").join(bar); -let mut path_buf = PathBuf::from("foo").join("bar").join("buz"); + let mut path_buf = PathBuf::from("foo").join("bar").join("buz"); let mut x = PathBuf::new(); println!("{}", x.display()); diff --git a/tests/ui/pathbuf_init_then_push.rs b/tests/ui/pathbuf_init_then_push.rs index f3adb6d27abf..7b65392e9519 100644 --- a/tests/ui/pathbuf_init_then_push.rs +++ b/tests/ui/pathbuf_init_then_push.rs @@ -3,21 +3,21 @@ use std::path::PathBuf; fn main() { -let mut path_buf = PathBuf::new(); -//~^ pathbuf_init_then_push + let mut path_buf = PathBuf::new(); + //~^ pathbuf_init_then_push path_buf.push("foo"); -path_buf = PathBuf::from("foo"); -//~^ pathbuf_init_then_push + path_buf = PathBuf::from("foo"); + //~^ pathbuf_init_then_push path_buf.push("bar"); let bar = "bar"; -path_buf = PathBuf::from("foo"); -//~^ pathbuf_init_then_push + path_buf = PathBuf::from("foo"); + //~^ pathbuf_init_then_push path_buf.push(bar); -let mut path_buf = PathBuf::from("foo").join("bar"); -//~^ pathbuf_init_then_push + let mut path_buf = PathBuf::from("foo").join("bar"); + //~^ pathbuf_init_then_push path_buf.push("buz"); let mut x = PathBuf::new(); diff --git a/tests/ui/pathbuf_init_then_push.stderr b/tests/ui/pathbuf_init_then_push.stderr index 80e7b836fce3..1aa730a0bea2 100644 --- a/tests/ui/pathbuf_init_then_push.stderr +++ b/tests/ui/pathbuf_init_then_push.stderr @@ -1,7 +1,7 @@ error: calls to `push` immediately after creation - --> tests/ui/pathbuf_init_then_push.rs:6:1 + --> tests/ui/pathbuf_init_then_push.rs:6:5 | -LL | / let mut path_buf = PathBuf::new(); +LL | / let mut path_buf = PathBuf::new(); LL | | LL | | path_buf.push("foo"); | |_________________________^ help: consider using the `.join()`: `let mut path_buf = PathBuf::from("foo");` @@ -10,25 +10,25 @@ LL | | path_buf.push("foo"); = help: to override `-D warnings` add `#[allow(clippy::pathbuf_init_then_push)]` error: calls to `push` immediately after creation - --> tests/ui/pathbuf_init_then_push.rs:10:1 + --> tests/ui/pathbuf_init_then_push.rs:10:5 | -LL | / path_buf = PathBuf::from("foo"); +LL | / path_buf = PathBuf::from("foo"); LL | | LL | | path_buf.push("bar"); | |_________________________^ help: consider using the `.join()`: `path_buf = PathBuf::from("foo").join("bar");` error: calls to `push` immediately after creation - --> tests/ui/pathbuf_init_then_push.rs:15:1 + --> tests/ui/pathbuf_init_then_push.rs:15:5 | -LL | / path_buf = PathBuf::from("foo"); +LL | / path_buf = PathBuf::from("foo"); LL | | LL | | path_buf.push(bar); | |_______________________^ help: consider using the `.join()`: `path_buf = PathBuf::from("foo").join(bar);` error: calls to `push` immediately after creation - --> tests/ui/pathbuf_init_then_push.rs:19:1 + --> tests/ui/pathbuf_init_then_push.rs:19:5 | -LL | / let mut path_buf = PathBuf::from("foo").join("bar"); +LL | / let mut path_buf = PathBuf::from("foo").join("bar"); LL | | LL | | path_buf.push("buz"); | |_________________________^ help: consider using the `.join()`: `let mut path_buf = PathBuf::from("foo").join("bar").join("buz");` diff --git a/tests/ui/pattern_type_mismatch/mutability.rs b/tests/ui/pattern_type_mismatch/mutability.rs index c62b33681439..bdac3764bf16 100644 --- a/tests/ui/pattern_type_mismatch/mutability.rs +++ b/tests/ui/pattern_type_mismatch/mutability.rs @@ -8,7 +8,6 @@ fn should_lint() { match value { Some(_) => (), //~^ pattern_type_mismatch - _ => (), } @@ -16,7 +15,6 @@ fn should_lint() { match value { Some(_) => (), //~^ pattern_type_mismatch - _ => (), } } diff --git a/tests/ui/pattern_type_mismatch/mutability.stderr b/tests/ui/pattern_type_mismatch/mutability.stderr index 805fc99ea212..e795ded7386d 100644 --- a/tests/ui/pattern_type_mismatch/mutability.stderr +++ b/tests/ui/pattern_type_mismatch/mutability.stderr @@ -9,7 +9,7 @@ LL | Some(_) => (), = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]` error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/mutability.rs:17:9 + --> tests/ui/pattern_type_mismatch/mutability.rs:16:9 | LL | Some(_) => (), | ^^^^^^^ diff --git a/tests/ui/pattern_type_mismatch/pattern_alternatives.rs b/tests/ui/pattern_type_mismatch/pattern_alternatives.rs index 9df08bfe7246..3c789f570b03 100644 --- a/tests/ui/pattern_type_mismatch/pattern_alternatives.rs +++ b/tests/ui/pattern_type_mismatch/pattern_alternatives.rs @@ -21,7 +21,6 @@ fn alternatives() { if let Value::B | Value::A(Some(_)) = *ref_value {} //~^ pattern_type_mismatch - // ok if let &Value::B | &Value::A(_) = ref_value {} if let Value::B | Value::A(_) = *ref_value {} diff --git a/tests/ui/pattern_type_mismatch/pattern_structs.rs b/tests/ui/pattern_type_mismatch/pattern_structs.rs index 862953120b4c..7fc53d591a91 100644 --- a/tests/ui/pattern_type_mismatch/pattern_structs.rs +++ b/tests/ui/pattern_type_mismatch/pattern_structs.rs @@ -19,7 +19,6 @@ fn struct_types() { if let Struct { ref_inner: Some(_) } = *ref_value {} //~^ pattern_type_mismatch - // ok let &Struct { .. } = ref_value; let Struct { .. } = *ref_value; @@ -50,7 +49,6 @@ fn struct_enum_variants() { if let StructEnum::Empty = ref_value {} //~^ pattern_type_mismatch - // ok if let &StructEnum::Var { .. } = ref_value {} if let StructEnum::Var { .. } = *ref_value {} diff --git a/tests/ui/pattern_type_mismatch/pattern_structs.stderr b/tests/ui/pattern_type_mismatch/pattern_structs.stderr index bdb11c73a457..70f7bdc38906 100644 --- a/tests/ui/pattern_type_mismatch/pattern_structs.stderr +++ b/tests/ui/pattern_type_mismatch/pattern_structs.stderr @@ -25,7 +25,7 @@ LL | if let Struct { ref_inner: Some(_) } = *ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:38:12 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:37:12 | LL | if let StructEnum::Var { .. } = ref_value {} | ^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | if let StructEnum::Var { .. } = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:41:12 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:40:12 | LL | if let StructEnum::Var { inner_ref: Some(_) } = ref_value {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | if let StructEnum::Var { inner_ref: Some(_) } = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:44:42 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:43:42 | LL | if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {} | ^^^^^^^ @@ -49,7 +49,7 @@ LL | if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:47:41 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:46:41 | LL | if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {} | ^^^^^^^ @@ -57,7 +57,7 @@ LL | if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_structs.rs:50:12 + --> tests/ui/pattern_type_mismatch/pattern_structs.rs:49:12 | LL | if let StructEnum::Empty = ref_value {} | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/pattern_type_mismatch/pattern_tuples.rs b/tests/ui/pattern_type_mismatch/pattern_tuples.rs index 4847e1a30a20..ecd95d9ae2b3 100644 --- a/tests/ui/pattern_type_mismatch/pattern_tuples.rs +++ b/tests/ui/pattern_type_mismatch/pattern_tuples.rs @@ -17,7 +17,6 @@ fn tuple_types() { if let TupleStruct(Some(_)) = *ref_value {} //~^ pattern_type_mismatch - // ok let &TupleStruct(_) = ref_value; let TupleStruct(_) = *ref_value; @@ -45,7 +44,6 @@ fn tuple_enum_variants() { if let TupleEnum::Empty = ref_value {} //~^ pattern_type_mismatch - // ok if let &TupleEnum::Var(_) = ref_value {} if let TupleEnum::Var(_) = *ref_value {} @@ -68,7 +66,6 @@ fn plain_tuples() { if let (_a, Some(_)) = *ref_value {} //~^ pattern_type_mismatch - // ok let &(_a, _b) = ref_value; let (_a, _b) = *ref_value; diff --git a/tests/ui/pattern_type_mismatch/pattern_tuples.stderr b/tests/ui/pattern_type_mismatch/pattern_tuples.stderr index 8a80a888f775..d47c5d509c3f 100644 --- a/tests/ui/pattern_type_mismatch/pattern_tuples.stderr +++ b/tests/ui/pattern_type_mismatch/pattern_tuples.stderr @@ -25,7 +25,7 @@ LL | if let TupleStruct(Some(_)) = *ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:36:12 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:35:12 | LL | if let TupleEnum::Var(_) = ref_value {} | ^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | if let TupleEnum::Var(_) = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:39:28 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:38:28 | LL | if let &TupleEnum::Var(Some(_)) = ref_value {} | ^^^^^^^ @@ -41,7 +41,7 @@ LL | if let &TupleEnum::Var(Some(_)) = ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:42:27 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:41:27 | LL | if let TupleEnum::Var(Some(_)) = *ref_value {} | ^^^^^^^ @@ -49,7 +49,7 @@ LL | if let TupleEnum::Var(Some(_)) = *ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:45:12 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:44:12 | LL | if let TupleEnum::Empty = ref_value {} | ^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | if let TupleEnum::Empty = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:62:9 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:60:9 | LL | let (_a, _b) = ref_value; | ^^^^^^^^ @@ -65,7 +65,7 @@ LL | let (_a, _b) = ref_value; = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:65:18 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:63:18 | LL | if let &(_a, Some(_)) = ref_value {} | ^^^^^^^ @@ -73,7 +73,7 @@ LL | if let &(_a, Some(_)) = ref_value {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:68:17 + --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:66:17 | LL | if let (_a, Some(_)) = *ref_value {} | ^^^^^^^ diff --git a/tests/ui/pattern_type_mismatch/syntax.rs b/tests/ui/pattern_type_mismatch/syntax.rs index 77e9ec772aa8..0bbc26a0c27c 100644 --- a/tests/ui/pattern_type_mismatch/syntax.rs +++ b/tests/ui/pattern_type_mismatch/syntax.rs @@ -10,7 +10,6 @@ fn syntax_match() { match ref_value { Some(_) => (), //~^ pattern_type_mismatch - None => (), } @@ -32,7 +31,6 @@ fn syntax_if_let() { if let Some(_) = ref_value {} //~^ pattern_type_mismatch - // ok if let &Some(_) = ref_value {} if let Some(_) = *ref_value {} @@ -43,7 +41,7 @@ fn syntax_while_let() { // not ok while let Some(_) = ref_value { - //~^ pattern_type_mismatch + //~^ pattern_type_mismatch break; } @@ -65,7 +63,6 @@ fn syntax_for() { for (_a, _b) in slice.iter() {} //~^ pattern_type_mismatch - // ok for &(_a, _b) in slice.iter() {} } @@ -77,7 +74,6 @@ fn syntax_let() { let (_n, _m) = ref_value; //~^ pattern_type_mismatch - // ok let &(_n, _m) = ref_value; let (_n, _m) = *ref_value; @@ -88,7 +84,6 @@ fn syntax_fn() { fn foo((_a, _b): &(i32, i32)) {} //~^ pattern_type_mismatch - // ok fn foo_ok_1(&(_a, _b): &(i32, i32)) {} } @@ -104,7 +99,6 @@ fn syntax_closure() { foo(|(_a, _b)| ()); //~^ pattern_type_mismatch - // ok foo(|&(_a, _b)| ()); } @@ -121,7 +115,6 @@ fn macro_with_expression() { matching_macro!(match value { Some(_) => (), //~^ pattern_type_mismatch - _ => (), }); diff --git a/tests/ui/pattern_type_mismatch/syntax.stderr b/tests/ui/pattern_type_mismatch/syntax.stderr index eec9ea70c69d..3f6b5feb9b07 100644 --- a/tests/ui/pattern_type_mismatch/syntax.stderr +++ b/tests/ui/pattern_type_mismatch/syntax.stderr @@ -9,7 +9,7 @@ LL | Some(_) => (), = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]` error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:32:12 + --> tests/ui/pattern_type_mismatch/syntax.rs:31:12 | LL | if let Some(_) = ref_value {} | ^^^^^^^ @@ -17,7 +17,7 @@ LL | if let Some(_) = ref_value {} = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:45:15 + --> tests/ui/pattern_type_mismatch/syntax.rs:43:15 | LL | while let Some(_) = ref_value { | ^^^^^^^ @@ -25,7 +25,7 @@ LL | while let Some(_) = ref_value { = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:65:9 + --> tests/ui/pattern_type_mismatch/syntax.rs:63:9 | LL | for (_a, _b) in slice.iter() {} | ^^^^^^^^ @@ -33,7 +33,7 @@ LL | for (_a, _b) in slice.iter() {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:77:9 + --> tests/ui/pattern_type_mismatch/syntax.rs:74:9 | LL | let (_n, _m) = ref_value; | ^^^^^^^^ @@ -41,7 +41,7 @@ LL | let (_n, _m) = ref_value; = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:88:12 + --> tests/ui/pattern_type_mismatch/syntax.rs:84:12 | LL | fn foo((_a, _b): &(i32, i32)) {} | ^^^^^^^^ @@ -49,7 +49,7 @@ LL | fn foo((_a, _b): &(i32, i32)) {} = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:104:10 + --> tests/ui/pattern_type_mismatch/syntax.rs:99:10 | LL | foo(|(_a, _b)| ()); | ^^^^^^^^ @@ -57,7 +57,7 @@ LL | foo(|(_a, _b)| ()); = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:122:9 + --> tests/ui/pattern_type_mismatch/syntax.rs:116:9 | LL | Some(_) => (), | ^^^^^^^ @@ -65,7 +65,7 @@ LL | Some(_) => (), = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings error: type of pattern does not match the expression type - --> tests/ui/pattern_type_mismatch/syntax.rs:144:17 + --> tests/ui/pattern_type_mismatch/syntax.rs:137:17 | LL | Some(_) => (), | ^^^^^^^ diff --git a/tests/ui/patterns.fixed b/tests/ui/patterns.fixed index a119096865a0..bcb8ecfc38d2 100644 --- a/tests/ui/patterns.fixed +++ b/tests/ui/patterns.fixed @@ -28,7 +28,7 @@ fn main() { // required "ref" left out in suggestion: #5271 match mutv { ref mut x => { - //~^ redundant_pattern + //~^ redundant_pattern x.push(4); println!("vec: {:?}", x); }, diff --git a/tests/ui/patterns.rs b/tests/ui/patterns.rs index 4ba6ac319af9..19639ebd13d6 100644 --- a/tests/ui/patterns.rs +++ b/tests/ui/patterns.rs @@ -28,7 +28,7 @@ fn main() { // required "ref" left out in suggestion: #5271 match mutv { ref mut x @ _ => { - //~^ redundant_pattern + //~^ redundant_pattern x.push(4); println!("vec: {:?}", x); }, diff --git a/tests/ui/permissions_set_readonly_false.rs b/tests/ui/permissions_set_readonly_false.rs index 652ffd724d95..ccca523da551 100644 --- a/tests/ui/permissions_set_readonly_false.rs +++ b/tests/ui/permissions_set_readonly_false.rs @@ -19,7 +19,6 @@ fn main() { permissions.set_readonly(false); //~^ permissions_set_readonly_false - // no lint permissions.set_readonly(true); diff --git a/tests/ui/pointers_in_nomem_asm_block.rs b/tests/ui/pointers_in_nomem_asm_block.rs index 6d23bd78e919..171716be2602 100644 --- a/tests/ui/pointers_in_nomem_asm_block.rs +++ b/tests/ui/pointers_in_nomem_asm_block.rs @@ -26,11 +26,9 @@ unsafe fn nomem_good(p: &i32) { unsafe fn nomem_bad2(p: &mut i32) { asm!("asdf {p}", p = in(reg) p, options(nomem, nostack, preserves_flags)); //~^ pointers_in_nomem_asm_block - } unsafe fn nomem_fn(p: extern "C" fn()) { asm!("call {p}", p = in(reg) p, options(nomem)); //~^ pointers_in_nomem_asm_block - } diff --git a/tests/ui/pointers_in_nomem_asm_block.stderr b/tests/ui/pointers_in_nomem_asm_block.stderr index 6de9c476312a..ca24e34f63c0 100644 --- a/tests/ui/pointers_in_nomem_asm_block.stderr +++ b/tests/ui/pointers_in_nomem_asm_block.stderr @@ -22,7 +22,7 @@ LL | asm!("asdf {p}", p = in(reg) p, options(nomem, nostack, preserves_flags = note: if this is intentional and no pointers are read or written to, consider allowing the lint error: passing pointers to nomem asm block - --> tests/ui/pointers_in_nomem_asm_block.rs:33:22 + --> tests/ui/pointers_in_nomem_asm_block.rs:32:22 | LL | asm!("call {p}", p = in(reg) p, options(nomem)); | ^^^^^^^^^^^^^ diff --git a/tests/ui/print.rs b/tests/ui/print.rs index 7f7b8eb15b5d..ee3d9dc0de03 100644 --- a/tests/ui/print.rs +++ b/tests/ui/print.rs @@ -10,8 +10,6 @@ impl Display for Foo { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "{:?}", 43.1415) //~^ use_debug - - } } @@ -26,27 +24,20 @@ fn main() { println!("Hello"); //~^ print_stdout - print!("Hello"); //~^ print_stdout - print!("Hello {}", "World"); //~^ print_stdout - print!("Hello {:?}", "World"); //~^ print_stdout //~| use_debug - - print!("Hello {:#?}", "#orld"); //~^ print_stdout //~| use_debug - - assert_eq!(42, 1337); vec![1, 2]; diff --git a/tests/ui/print.stderr b/tests/ui/print.stderr index 4e9d4135486c..9dd216bd1449 100644 --- a/tests/ui/print.stderr +++ b/tests/ui/print.stderr @@ -8,7 +8,7 @@ LL | write!(f, "{:?}", 43.1415) = help: to override `-D warnings` add `#[allow(clippy::use_debug)]` error: use of `println!` - --> tests/ui/print.rs:26:5 + --> tests/ui/print.rs:24:5 | LL | println!("Hello"); | ^^^^^^^^^^^^^^^^^ @@ -17,37 +17,37 @@ LL | println!("Hello"); = help: to override `-D warnings` add `#[allow(clippy::print_stdout)]` error: use of `print!` - --> tests/ui/print.rs:30:5 + --> tests/ui/print.rs:27:5 | LL | print!("Hello"); | ^^^^^^^^^^^^^^^ error: use of `print!` - --> tests/ui/print.rs:34:5 + --> tests/ui/print.rs:30:5 | LL | print!("Hello {}", "World"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `print!` - --> tests/ui/print.rs:38:5 + --> tests/ui/print.rs:33:5 | LL | print!("Hello {:?}", "World"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `Debug`-based formatting - --> tests/ui/print.rs:38:19 + --> tests/ui/print.rs:33:19 | LL | print!("Hello {:?}", "World"); | ^^^^ error: use of `print!` - --> tests/ui/print.rs:44:5 + --> tests/ui/print.rs:37:5 | LL | print!("Hello {:#?}", "#orld"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `Debug`-based formatting - --> tests/ui/print.rs:44:19 + --> tests/ui/print.rs:37:19 | LL | print!("Hello {:#?}", "#orld"); | ^^^^^ diff --git a/tests/ui/print_in_format_impl.rs b/tests/ui/print_in_format_impl.rs index fdf630355044..8bc704921220 100644 --- a/tests/ui/print_in_format_impl.rs +++ b/tests/ui/print_in_format_impl.rs @@ -20,7 +20,6 @@ impl Debug for Foo { print!("{}", 1); //~^ print_in_format_impl - println!("{}", 2); //~^ print_in_format_impl diff --git a/tests/ui/print_in_format_impl.stderr b/tests/ui/print_in_format_impl.stderr index 1a9c62d39e03..91d6ce953849 100644 --- a/tests/ui/print_in_format_impl.stderr +++ b/tests/ui/print_in_format_impl.stderr @@ -8,37 +8,37 @@ LL | print!("{}", 1); = help: to override `-D warnings` add `#[allow(clippy::print_in_format_impl)]` error: use of `println!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:24:9 + --> tests/ui/print_in_format_impl.rs:23:9 | LL | println!("{}", 2); | ^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)` error: use of `eprint!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:27:9 + --> tests/ui/print_in_format_impl.rs:26:9 | LL | eprint!("{}", 3); | ^^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)` error: use of `eprintln!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:30:9 + --> tests/ui/print_in_format_impl.rs:29:9 | LL | eprintln!("{}", 4); | ^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)` error: use of `println!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:34:13 + --> tests/ui/print_in_format_impl.rs:33:13 | LL | println!("nested"); | ^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)` error: use of `print!` in `Display` impl - --> tests/ui/print_in_format_impl.rs:49:9 + --> tests/ui/print_in_format_impl.rs:48:9 | LL | print!("Display"); | ^^^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)` error: use of `println!` in `Debug` impl - --> tests/ui/print_in_format_impl.rs:61:9 + --> tests/ui/print_in_format_impl.rs:60:9 | LL | println!("UnnamedFormatter"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(..)` diff --git a/tests/ui/print_literal.fixed b/tests/ui/print_literal.fixed index bcf022badc6e..24c45a4a61b9 100644 --- a/tests/ui/print_literal.fixed +++ b/tests/ui/print_literal.fixed @@ -27,7 +27,6 @@ fn main() { print!("Hello world"); //~^ print_literal - println!("Hello {} world", world); //~^ print_literal @@ -37,7 +36,6 @@ fn main() { println!("a literal {:.4}", 5); //~^ print_literal - // positional args don't change the fact // that we're using a literal -- this should // throw a warning @@ -47,7 +45,6 @@ fn main() { println!("world hello"); //~^ print_literal - // named args shouldn't change anything either println!("hello world"); //~^ print_literal @@ -55,7 +52,6 @@ fn main() { println!("world hello"); //~^ print_literal - // The string literal from `file!()` has a callsite span that isn't marked as coming from an // expansion println!("file: {}", file!()); diff --git a/tests/ui/print_literal.rs b/tests/ui/print_literal.rs index 96c150ae4810..42ae589ca639 100644 --- a/tests/ui/print_literal.rs +++ b/tests/ui/print_literal.rs @@ -27,7 +27,6 @@ fn main() { print!("Hello {}", "world"); //~^ print_literal - println!("Hello {} {}", world, "world"); //~^ print_literal @@ -37,7 +36,6 @@ fn main() { println!("{} {:.4}", "a literal", 5); //~^ print_literal - // positional args don't change the fact // that we're using a literal -- this should // throw a warning @@ -47,7 +45,6 @@ fn main() { println!("{1} {0}", "hello", "world"); //~^ print_literal - // named args shouldn't change anything either println!("{foo} {bar}", foo = "hello", bar = "world"); //~^ print_literal @@ -55,7 +52,6 @@ fn main() { println!("{bar} {foo}", foo = "hello", bar = "world"); //~^ print_literal - // The string literal from `file!()` has a callsite span that isn't marked as coming from an // expansion println!("file: {}", file!()); diff --git a/tests/ui/print_literal.stderr b/tests/ui/print_literal.stderr index c2bc7d495f27..da663000686f 100644 --- a/tests/ui/print_literal.stderr +++ b/tests/ui/print_literal.stderr @@ -13,7 +13,7 @@ LL + print!("Hello world"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:31:36 + --> tests/ui/print_literal.rs:30:36 | LL | println!("Hello {} {}", world, "world"); | ^^^^^^^ @@ -25,7 +25,7 @@ LL + println!("Hello {} world", world); | error: literal with an empty format string - --> tests/ui/print_literal.rs:34:26 + --> tests/ui/print_literal.rs:33:26 | LL | println!("Hello {}", "world"); | ^^^^^^^ @@ -37,7 +37,7 @@ LL + println!("Hello world"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:37:26 + --> tests/ui/print_literal.rs:36:26 | LL | println!("{} {:.4}", "a literal", 5); | ^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + println!("a literal {:.4}", 5); | error: literal with an empty format string - --> tests/ui/print_literal.rs:44:25 + --> tests/ui/print_literal.rs:42:25 | LL | println!("{0} {1}", "hello", "world"); | ^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + println!("hello world"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:47:25 + --> tests/ui/print_literal.rs:45:25 | LL | println!("{1} {0}", "hello", "world"); | ^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + println!("world hello"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:52:35 + --> tests/ui/print_literal.rs:49:35 | LL | println!("{foo} {bar}", foo = "hello", bar = "world"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + println!("hello world"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:55:35 + --> tests/ui/print_literal.rs:52:35 | LL | println!("{bar} {foo}", foo = "hello", bar = "world"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL + println!("world hello"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:64:20 + --> tests/ui/print_literal.rs:60:20 | LL | println!("{}", "{} \x00 \u{ab123} \\\u{ab123} {:?}"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL + println!("{{}} \x00 \u{ab123} \\\u{ab123} {{:?}}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:66:20 + --> tests/ui/print_literal.rs:62:20 | LL | println!("{}", "\\\u{1234}"); | ^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL + println!("\\\u{1234}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:71:20 + --> tests/ui/print_literal.rs:67:20 | LL | println!("{}", r"\u{ab123} \u{{"); | ^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL + println!("\\u{{ab123}} \\u{{{{"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:73:21 + --> tests/ui/print_literal.rs:69:21 | LL | println!(r"{}", r"\u{ab123} \u{{"); | ^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL + println!(r"\u{{ab123}} \u{{{{"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:75:20 + --> tests/ui/print_literal.rs:71:20 | LL | println!("{}", r"\{ab123} \u{{"); | ^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL + println!("\\{{ab123}} \\u{{{{"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:77:20 + --> tests/ui/print_literal.rs:73:20 | LL | println!("{}", "\\u{ab123}"); | ^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL + println!("\\u{{ab123}}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:79:20 + --> tests/ui/print_literal.rs:75:20 | LL | println!("{}", "\\\\u{1234}"); | ^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + println!("\\\\u{{1234}}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:82:35 + --> tests/ui/print_literal.rs:78:35 | LL | println!("mixed: {} {world}", "{hello}"); | ^^^^^^^^^ @@ -193,7 +193,7 @@ LL + println!("mixed: {{hello}} {world}"); | error: literal with an empty format string - --> tests/ui/print_literal.rs:87:20 + --> tests/ui/print_literal.rs:83:20 | LL | println!("{}", r#"""#); | ^^^^^^ @@ -205,7 +205,7 @@ LL + println!("\""); | error: literal with an empty format string - --> tests/ui/print_literal.rs:91:9 + --> tests/ui/print_literal.rs:87:9 | LL | / r#" LL | | diff --git a/tests/ui/print_stderr.rs b/tests/ui/print_stderr.rs index 2ad2c97b7cc1..a086dfd37758 100644 --- a/tests/ui/print_stderr.rs +++ b/tests/ui/print_stderr.rs @@ -4,7 +4,6 @@ fn main() { eprintln!("Hello"); //~^ print_stderr - println!("This should not do anything"); eprint!("World"); //~^ print_stderr diff --git a/tests/ui/print_stderr.stderr b/tests/ui/print_stderr.stderr index 7dfe72934c64..17019b886905 100644 --- a/tests/ui/print_stderr.stderr +++ b/tests/ui/print_stderr.stderr @@ -8,7 +8,7 @@ LL | eprintln!("Hello"); = help: to override `-D warnings` add `#[allow(clippy::print_stderr)]` error: use of `eprint!` - --> tests/ui/print_stderr.rs:9:5 + --> tests/ui/print_stderr.rs:8:5 | LL | eprint!("World"); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/print_with_newline.fixed b/tests/ui/print_with_newline.fixed index 79bd8a2c8d36..96c5ee4c1e92 100644 --- a/tests/ui/print_with_newline.fixed +++ b/tests/ui/print_with_newline.fixed @@ -7,7 +7,6 @@ fn main() { println!("Hello"); //~^ print_with_newline - println!("Hello {}", "world"); //~^ print_with_newline @@ -20,7 +19,6 @@ fn main() { println!(); //~^ print_with_newline - // these are all fine print!(""); print!("Hello"); @@ -52,13 +50,11 @@ fn main() { // Literal newlines should also fail println!( - //~^ print_with_newline - + //~^ print_with_newline ); println!( - //~^ print_with_newline - + //~^ print_with_newline ); diff --git a/tests/ui/print_with_newline.rs b/tests/ui/print_with_newline.rs index a9cbd214fc61..60d1e4788308 100644 --- a/tests/ui/print_with_newline.rs +++ b/tests/ui/print_with_newline.rs @@ -7,7 +7,6 @@ fn main() { print!("Hello\n"); //~^ print_with_newline - print!("Hello {}\n", "world"); //~^ print_with_newline @@ -20,7 +19,6 @@ fn main() { print!("\n"); //~^ print_with_newline - // these are all fine print!(""); print!("Hello"); @@ -52,14 +50,12 @@ fn main() { // Literal newlines should also fail print!( - //~^ print_with_newline - + //~^ print_with_newline " " ); print!( - //~^ print_with_newline - + //~^ print_with_newline r" " ); diff --git a/tests/ui/print_with_newline.stderr b/tests/ui/print_with_newline.stderr index 45f858d68966..9ead0fca113b 100644 --- a/tests/ui/print_with_newline.stderr +++ b/tests/ui/print_with_newline.stderr @@ -13,7 +13,7 @@ LL + println!("Hello"); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:11:5 + --> tests/ui/print_with_newline.rs:10:5 | LL | print!("Hello {}\n", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + println!("Hello {}", "world"); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:14:5 + --> tests/ui/print_with_newline.rs:13:5 | LL | print!("Hello {} {}\n", "world", "#2"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + println!("Hello {} {}", "world", "#2"); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:17:5 + --> tests/ui/print_with_newline.rs:16:5 | LL | print!("{}\n", 1265); | ^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + println!("{}", 1265); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:20:5 + --> tests/ui/print_with_newline.rs:19:5 | LL | print!("\n"); | ^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + println!(); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:44:5 + --> tests/ui/print_with_newline.rs:42:5 | LL | print!("\\\n"); | ^^^^^^^^^^^^^^ @@ -73,11 +73,10 @@ LL + println!("\\"); | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:54:5 + --> tests/ui/print_with_newline.rs:52:5 | LL | / print!( LL | | -LL | | LL | | " LL | | " LL | | ); @@ -87,16 +86,14 @@ help: use `println!` instead | LL ~ println!( LL | -LL | LL ~ | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:60:5 + --> tests/ui/print_with_newline.rs:57:5 | LL | / print!( LL | | -LL | | LL | | r" LL | | " LL | | ); @@ -106,12 +103,11 @@ help: use `println!` instead | LL ~ println!( LL | -LL | LL ~ | error: using `print!()` with a format string that ends in a single newline - --> tests/ui/print_with_newline.rs:71:5 + --> tests/ui/print_with_newline.rs:67:5 | LL | print!("\\r\n"); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/ptr_arg.rs b/tests/ui/ptr_arg.rs index e8332cb97e1b..2d77bf06ff94 100644 --- a/tests/ui/ptr_arg.rs +++ b/tests/ui/ptr_arg.rs @@ -11,45 +11,44 @@ use std::borrow::Cow; use std::path::{Path, PathBuf}; fn do_vec(x: &Vec) { -//~^ ptr_arg - + //~^ ptr_arg //Nothing here } fn do_vec_mut(x: &mut Vec) { -//~^ ptr_arg + //~^ ptr_arg //Nothing here } fn do_vec_mut2(x: &mut Vec) { -//~^ ptr_arg + //~^ ptr_arg x.len(); x.is_empty(); } fn do_str(x: &String) { -//~^ ptr_arg + //~^ ptr_arg //Nothing here either } fn do_str_mut(x: &mut String) { -//~^ ptr_arg + //~^ ptr_arg //Nothing here either } fn do_path(x: &PathBuf) { -//~^ ptr_arg + //~^ ptr_arg //Nothing here either } fn do_path_mut(x: &mut PathBuf) { -//~^ ptr_arg + //~^ ptr_arg //Nothing here either } @@ -74,7 +73,7 @@ impl Foo for Bar { } fn cloned(x: &Vec) -> Vec { -//~^ ptr_arg + //~^ ptr_arg let e = x.clone(); let f = e.clone(); // OK @@ -85,7 +84,7 @@ fn cloned(x: &Vec) -> Vec { } fn str_cloned(x: &String) -> String { -//~^ ptr_arg + //~^ ptr_arg let a = x.clone(); let b = x.clone(); @@ -95,7 +94,7 @@ fn str_cloned(x: &String) -> String { } fn path_cloned(x: &PathBuf) -> PathBuf { -//~^ ptr_arg + //~^ ptr_arg let a = x.clone(); let b = x.clone(); @@ -105,7 +104,7 @@ fn path_cloned(x: &PathBuf) -> PathBuf { } fn false_positive_capacity(x: &Vec, y: &String) { -//~^ ptr_arg + //~^ ptr_arg let a = x.capacity(); let b = y.clone(); @@ -123,7 +122,6 @@ fn false_positive_capacity_too(x: &String) -> String { fn test_cow_with_ref(c: &Cow<[i32]>) {} //~^ ptr_arg - fn test_cow(c: Cow<[i32]>) { let _c = c; } @@ -154,7 +152,6 @@ mod issue_5644 { fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec, _s: &String) {} //~^ ptr_arg - struct S; impl S { fn allowed( @@ -183,21 +180,21 @@ mod issue6509 { use std::path::PathBuf; fn foo_vec(vec: &Vec) { - //~^ ptr_arg + //~^ ptr_arg let _ = vec.clone().pop(); let _ = vec.clone().clone(); } fn foo_path(path: &PathBuf) { - //~^ ptr_arg + //~^ ptr_arg let _ = path.clone().pop(); let _ = path.clone().clone(); } fn foo_str(str: &PathBuf) { - //~^ ptr_arg + //~^ ptr_arg let _ = str.clone().pop(); let _ = str.clone().clone(); @@ -205,7 +202,7 @@ mod issue6509 { } fn mut_vec_slice_methods(v: &mut Vec) { -//~^ ptr_arg + //~^ ptr_arg v.copy_within(1..5, 10); } @@ -269,9 +266,9 @@ fn dyn_trait_ok(a: &mut Vec, b: &mut String, c: &mut PathBuf) { } fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { -//~^ ptr_arg -//~| ptr_arg -//~| ptr_arg + //~^ ptr_arg + //~| ptr_arg + //~| ptr_arg trait T {} impl T for Vec {} @@ -296,26 +293,26 @@ mod issue_9218 { // This one has an anonymous lifetime so it's not okay fn cow_elided_lifetime<'a>(input: &'a Cow) -> &'a str { - //~^ ptr_arg + //~^ ptr_arg todo!() } // These two's return types don't use 'a so it's not okay fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str { - //~^ ptr_arg + //~^ ptr_arg todo!() } fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str { - //~^ ptr_arg + //~^ ptr_arg todo!() } // Inferred to be `&'a str`, afaik. fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str { - //~^ ERROR: elided lifetime has a name + //~^ ERROR: elided lifetime has a name todo!() } } @@ -348,8 +345,8 @@ mod issue_13308 { // Other cases that are still ok to lint and ideally shouldn't regress fn good(v1: &String, v2: &String) { - //~^ ptr_arg - //~| ptr_arg + //~^ ptr_arg + //~| ptr_arg h1(v1); h2(String::new(), v2); diff --git a/tests/ui/ptr_arg.stderr b/tests/ui/ptr_arg.stderr index 94fa2184fd64..741e60cbd749 100644 --- a/tests/ui/ptr_arg.stderr +++ b/tests/ui/ptr_arg.stderr @@ -1,5 +1,5 @@ error: elided lifetime has a name - --> tests/ui/ptr_arg.rs:317:56 + --> tests/ui/ptr_arg.rs:314:56 | LL | fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str { | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` @@ -17,49 +17,49 @@ LL | fn do_vec(x: &Vec) { = help: to override `-D warnings` add `#[allow(clippy::ptr_arg)]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:20:18 + --> tests/ui/ptr_arg.rs:19:18 | LL | fn do_vec_mut(x: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:26:19 + --> tests/ui/ptr_arg.rs:25:19 | LL | fn do_vec_mut2(x: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:33:14 + --> tests/ui/ptr_arg.rs:32:14 | LL | fn do_str(x: &String) { | ^^^^^^^ help: change this to: `&str` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:39:18 + --> tests/ui/ptr_arg.rs:38:18 | LL | fn do_str_mut(x: &mut String) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:45:15 + --> tests/ui/ptr_arg.rs:44:15 | LL | fn do_path(x: &PathBuf) { | ^^^^^^^^ help: change this to: `&Path` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:51:19 + --> tests/ui/ptr_arg.rs:50:19 | LL | fn do_path_mut(x: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:61:18 + --> tests/ui/ptr_arg.rs:60:18 | LL | fn do_vec(x: &Vec); | ^^^^^^^^^ help: change this to: `&[i64]` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:76:14 + --> tests/ui/ptr_arg.rs:75:14 | LL | fn cloned(x: &Vec) -> Vec { | ^^^^^^^^ @@ -78,7 +78,7 @@ LL ~ x.to_owned() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:87:18 + --> tests/ui/ptr_arg.rs:86:18 | LL | fn str_cloned(x: &String) -> String { | ^^^^^^^ @@ -96,7 +96,7 @@ LL ~ x.to_owned() | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:97:19 + --> tests/ui/ptr_arg.rs:96:19 | LL | fn path_cloned(x: &PathBuf) -> PathBuf { | ^^^^^^^^ @@ -114,7 +114,7 @@ LL ~ x.to_path_buf() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:107:44 + --> tests/ui/ptr_arg.rs:106:44 | LL | fn false_positive_capacity(x: &Vec, y: &String) { | ^^^^^^^ @@ -130,19 +130,19 @@ LL ~ let c = y; | error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:123:25 + --> tests/ui/ptr_arg.rs:122:25 | LL | fn test_cow_with_ref(c: &Cow<[i32]>) {} | ^^^^^^^^^^^ help: change this to: `&[i32]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:154:66 + --> tests/ui/ptr_arg.rs:152:66 | LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec, _s: &String) {} | ^^^^^^^ help: change this to: `&str` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:185:21 + --> tests/ui/ptr_arg.rs:182:21 | LL | fn foo_vec(vec: &Vec) { | ^^^^^^^^ @@ -157,7 +157,7 @@ LL ~ let _ = vec.to_owned().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:192:23 + --> tests/ui/ptr_arg.rs:189:23 | LL | fn foo_path(path: &PathBuf) { | ^^^^^^^^ @@ -172,7 +172,7 @@ LL ~ let _ = path.to_path_buf().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:199:21 + --> tests/ui/ptr_arg.rs:196:21 | LL | fn foo_str(str: &PathBuf) { | ^^^^^^^^ @@ -187,55 +187,55 @@ LL ~ let _ = str.to_path_buf().clone(); | error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:207:29 + --> tests/ui/ptr_arg.rs:204:29 | LL | fn mut_vec_slice_methods(v: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:271:17 + --> tests/ui/ptr_arg.rs:268:17 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:271:35 + --> tests/ui/ptr_arg.rs:268:35 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:271:51 + --> tests/ui/ptr_arg.rs:268:51 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:298:39 + --> tests/ui/ptr_arg.rs:295:39 | LL | fn cow_elided_lifetime<'a>(input: &'a Cow) -> &'a str { | ^^^^^^^^^^^^ help: change this to: `&str` error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:305:36 + --> tests/ui/ptr_arg.rs:302:36 | LL | fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str { | ^^^^^^^^^^^^^^^^ help: change this to: `&str` error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:310:40 + --> tests/ui/ptr_arg.rs:307:40 | LL | fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str { | ^^^^^^^^^^^^^^^^ help: change this to: `&str` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:350:17 + --> tests/ui/ptr_arg.rs:347:17 | LL | fn good(v1: &String, v2: &String) { | ^^^^^^^ help: change this to: `&str` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:350:30 + --> tests/ui/ptr_arg.rs:347:30 | LL | fn good(v1: &String, v2: &String) { | ^^^^^^^ help: change this to: `&str` diff --git a/tests/ui/pub_use.rs b/tests/ui/pub_use.rs index 4c2c3dfb30cb..be4d1b2a964b 100644 --- a/tests/ui/pub_use.rs +++ b/tests/ui/pub_use.rs @@ -9,7 +9,6 @@ pub mod outer { // should be linted pub use inner::Test; //~^ pub_use - } // should not be linted diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs index 609a4d3251e7..fffaa803f39c 100644 --- a/tests/ui/question_mark.rs +++ b/tests/ui/question_mark.rs @@ -5,7 +5,7 @@ fn some_func(a: Option) -> Option { if a.is_none() { - //~^ question_mark + //~^ question_mark return None; } @@ -86,7 +86,7 @@ pub struct MoveStruct { impl MoveStruct { pub fn ref_func(&self) -> Option> { if self.opt.is_none() { - //~^ question_mark + //~^ question_mark return None; } @@ -95,7 +95,7 @@ impl MoveStruct { pub fn mov_func_reuse(self) -> Option> { if self.opt.is_none() { - //~^ question_mark + //~^ question_mark return None; } @@ -104,7 +104,7 @@ impl MoveStruct { pub fn mov_func_no_use(self) -> Option> { if self.opt.is_none() { - //~^ question_mark + //~^ question_mark return None; } Some(Vec::new()) @@ -112,7 +112,7 @@ impl MoveStruct { pub fn if_let_ref_func(self) -> Option> { let v: &Vec<_> = if let Some(ref v) = self.opt { - //~^ question_mark + //~^ question_mark v } else { return None; @@ -123,7 +123,7 @@ impl MoveStruct { pub fn if_let_mov_func(self) -> Option> { let v = if let Some(v) = self.opt { - //~^ question_mark + //~^ question_mark v } else { return None; @@ -145,12 +145,12 @@ fn func() -> Option { } if f().is_none() { - //~^ question_mark + //~^ question_mark return None; } let _val = match f() { - //~^ question_mark + //~^ question_mark Some(val) => val, None => return None, }; @@ -161,13 +161,13 @@ fn func() -> Option { }; match f() { - //~^ question_mark + //~^ question_mark Some(val) => val, None => return None, }; match opt_none!() { - //~^ question_mark + //~^ question_mark Some(x) => x, None => return None, }; @@ -197,18 +197,18 @@ fn result_func(x: Result) -> Result { //~^ question_mark if x.is_err() { - //~^ question_mark + //~^ question_mark return x; } let _val = match func_returning_result() { - //~^ question_mark + //~^ question_mark Ok(val) => val, Err(err) => return Err(err), }; match func_returning_result() { - //~^ question_mark + //~^ question_mark Ok(val) => val, Err(err) => return Err(err), }; @@ -300,7 +300,7 @@ fn do_something() {} fn err_immediate_return() -> Result { if let Err(err) = func_returning_result() { - //~^ question_mark + //~^ question_mark return Err(err); } Ok(1) @@ -308,7 +308,7 @@ fn err_immediate_return() -> Result { fn err_immediate_return_and_do_something() -> Result { if let Err(err) = func_returning_result() { - //~^ question_mark + //~^ question_mark return Err(err); } do_something(); @@ -386,7 +386,7 @@ fn issue6828_nested_body() -> Option { try { fn f2(a: Option) -> Option { if a.is_none() { - //~^ question_mark + //~^ question_mark return None; // do lint here, the outer `try` is not relevant here // https://github.com/rust-lang/rust-clippy/pull/11001#issuecomment-1610636867 diff --git a/tests/ui/rc_clone_in_vec_init/arc.rs b/tests/ui/rc_clone_in_vec_init/arc.rs index 3b3e5dc643e1..ad5d131f34bc 100644 --- a/tests/ui/rc_clone_in_vec_init/arc.rs +++ b/tests/ui/rc_clone_in_vec_init/arc.rs @@ -8,8 +8,6 @@ fn main() {} fn should_warn_simple_case() { let v = vec![Arc::new("x".to_string()); 2]; //~^ rc_clone_in_vec_init - - } fn should_warn_simple_case_with_big_indentation() { @@ -19,8 +17,6 @@ fn should_warn_simple_case_with_big_indentation() { if true { let v = vec![Arc::new("x".to_string()); 2]; //~^ rc_clone_in_vec_init - - } } } diff --git a/tests/ui/rc_clone_in_vec_init/arc.stderr b/tests/ui/rc_clone_in_vec_init/arc.stderr index 5d70bfc85363..598d3c0ae577 100644 --- a/tests/ui/rc_clone_in_vec_init/arc.stderr +++ b/tests/ui/rc_clone_in_vec_init/arc.stderr @@ -24,7 +24,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/arc.rs:20:21 + --> tests/ui/rc_clone_in_vec_init/arc.rs:18:21 | LL | let v = vec![Arc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/arc.rs:29:13 + --> tests/ui/rc_clone_in_vec_init/arc.rs:25:13 | LL | let v = vec![ | _____________^ @@ -74,7 +74,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/arc.rs:41:14 + --> tests/ui/rc_clone_in_vec_init/arc.rs:37:14 | LL | let v1 = vec![ | ______________^ diff --git a/tests/ui/rc_clone_in_vec_init/rc.rs b/tests/ui/rc_clone_in_vec_init/rc.rs index e93408798585..d5af17c29e1d 100644 --- a/tests/ui/rc_clone_in_vec_init/rc.rs +++ b/tests/ui/rc_clone_in_vec_init/rc.rs @@ -9,8 +9,6 @@ fn main() {} fn should_warn_simple_case() { let v = vec![Rc::new("x".to_string()); 2]; //~^ rc_clone_in_vec_init - - } fn should_warn_simple_case_with_big_indentation() { @@ -20,8 +18,6 @@ fn should_warn_simple_case_with_big_indentation() { if true { let v = vec![Rc::new("x".to_string()); 2]; //~^ rc_clone_in_vec_init - - } } } diff --git a/tests/ui/rc_clone_in_vec_init/rc.stderr b/tests/ui/rc_clone_in_vec_init/rc.stderr index 57ea31f9ff89..60d7f33ada9c 100644 --- a/tests/ui/rc_clone_in_vec_init/rc.stderr +++ b/tests/ui/rc_clone_in_vec_init/rc.stderr @@ -24,7 +24,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/rc.rs:21:21 + --> tests/ui/rc_clone_in_vec_init/rc.rs:19:21 | LL | let v = vec![Rc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/rc.rs:30:13 + --> tests/ui/rc_clone_in_vec_init/rc.rs:26:13 | LL | let v = vec![ | _____________^ @@ -74,7 +74,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/rc.rs:42:14 + --> tests/ui/rc_clone_in_vec_init/rc.rs:38:14 | LL | let v1 = vec![ | ______________^ diff --git a/tests/ui/rc_clone_in_vec_init/weak.rs b/tests/ui/rc_clone_in_vec_init/weak.rs index af1ec1601dcf..add09b6ba859 100644 --- a/tests/ui/rc_clone_in_vec_init/weak.rs +++ b/tests/ui/rc_clone_in_vec_init/weak.rs @@ -10,20 +10,14 @@ fn should_warn_simple_case() { let v = vec![SyncWeak::::new(); 2]; //~^ rc_clone_in_vec_init - let v2 = vec![UnSyncWeak::::new(); 2]; //~^ rc_clone_in_vec_init - - let v = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; //~^ rc_clone_in_vec_init - let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; //~^ rc_clone_in_vec_init - - } fn should_warn_simple_case_with_big_indentation() { @@ -34,11 +28,8 @@ fn should_warn_simple_case_with_big_indentation() { let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; //~^ rc_clone_in_vec_init - let v2 = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; //~^ rc_clone_in_vec_init - - } } } diff --git a/tests/ui/rc_clone_in_vec_init/weak.stderr b/tests/ui/rc_clone_in_vec_init/weak.stderr index 26974dd7446c..8bd018ab586c 100644 --- a/tests/ui/rc_clone_in_vec_init/weak.stderr +++ b/tests/ui/rc_clone_in_vec_init/weak.stderr @@ -24,7 +24,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:14:14 + --> tests/ui/rc_clone_in_vec_init/weak.rs:13:14 | LL | let v2 = vec![UnSyncWeak::::new(); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:19:13 + --> tests/ui/rc_clone_in_vec_init/weak.rs:16:13 | LL | let v = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:23:13 + --> tests/ui/rc_clone_in_vec_init/weak.rs:19:13 | LL | let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,7 +93,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:34:21 + --> tests/ui/rc_clone_in_vec_init/weak.rs:28:21 | LL | let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -116,7 +116,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:38:22 + --> tests/ui/rc_clone_in_vec_init/weak.rs:31:22 | LL | let v2 = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:47:13 + --> tests/ui/rc_clone_in_vec_init/weak.rs:38:13 | LL | let v = vec![ | _____________^ @@ -166,7 +166,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> tests/ui/rc_clone_in_vec_init/weak.rs:59:14 + --> tests/ui/rc_clone_in_vec_init/weak.rs:50:14 | LL | let v1 = vec![ | ______________^ diff --git a/tests/ui/rc_mutex.rs b/tests/ui/rc_mutex.rs index cccbc751f417..c8700e13b11e 100644 --- a/tests/ui/rc_mutex.rs +++ b/tests/ui/rc_mutex.rs @@ -33,7 +33,6 @@ fn test2(foo: Rc>) {} fn test3(foo: Rc>>) {} //~^ rc_mutex - // All of these test should be allowed because they are part of the // public api and `avoid_breaking_exported_api` is `false` by default. pub fn pub_test1(foo: Rc>) {} diff --git a/tests/ui/read_line_without_trim.fixed b/tests/ui/read_line_without_trim.fixed index 9263a398ad85..e7f208e78d20 100644 --- a/tests/ui/read_line_without_trim.fixed +++ b/tests/ui/read_line_without_trim.fixed @@ -41,14 +41,14 @@ fn main() { let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); if input.trim_end() == "foo" { - //~^ read_line_without_trim + //~^ read_line_without_trim println!("This will never ever execute!"); } let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); if input.trim_end().ends_with("foo") { - //~^ read_line_without_trim + //~^ read_line_without_trim println!("Neither will this"); } } diff --git a/tests/ui/read_line_without_trim.rs b/tests/ui/read_line_without_trim.rs index ba5196bb51ba..6664278b5a87 100644 --- a/tests/ui/read_line_without_trim.rs +++ b/tests/ui/read_line_without_trim.rs @@ -41,14 +41,14 @@ fn main() { let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); if input == "foo" { - //~^ read_line_without_trim + //~^ read_line_without_trim println!("This will never ever execute!"); } let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); if input.ends_with("foo") { - //~^ read_line_without_trim + //~^ read_line_without_trim println!("Neither will this"); } } diff --git a/tests/ui/readonly_write_lock.fixed b/tests/ui/readonly_write_lock.fixed index 21822444f35f..0cb91247232b 100644 --- a/tests/ui/readonly_write_lock.fixed +++ b/tests/ui/readonly_write_lock.fixed @@ -16,7 +16,6 @@ fn main() { let writer = lock.read().unwrap(); //~^ readonly_write_lock - dbg!(&writer); } diff --git a/tests/ui/readonly_write_lock.rs b/tests/ui/readonly_write_lock.rs index b3fd1a611cc8..843755fe792c 100644 --- a/tests/ui/readonly_write_lock.rs +++ b/tests/ui/readonly_write_lock.rs @@ -16,7 +16,6 @@ fn main() { let writer = lock.write().unwrap(); //~^ readonly_write_lock - dbg!(&writer); } diff --git a/tests/ui/readonly_write_lock.stderr b/tests/ui/readonly_write_lock.stderr index a3f88e92bfae..6b1ef3c4720f 100644 --- a/tests/ui/readonly_write_lock.stderr +++ b/tests/ui/readonly_write_lock.stderr @@ -8,7 +8,7 @@ LL | let writer = lock.write().unwrap(); = help: to override `-D warnings` add `#[allow(clippy::readonly_write_lock)]` error: this write lock is used only for reading - --> tests/ui/readonly_write_lock.rs:24:22 + --> tests/ui/readonly_write_lock.rs:23:22 | LL | let writer = lock.write().unwrap(); | ^^^^^^^^^^^^ help: consider using a read lock instead: `lock.read()` diff --git a/tests/ui/recursive_format_impl.rs b/tests/ui/recursive_format_impl.rs index d9b3a15eb9b1..9f46fef62354 100644 --- a/tests/ui/recursive_format_impl.rs +++ b/tests/ui/recursive_format_impl.rs @@ -30,8 +30,6 @@ impl fmt::Display for A { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.to_string()) //~^ recursive_format_impl - - } } @@ -77,7 +75,6 @@ impl std::fmt::Display for G { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self) //~^ recursive_format_impl - } } @@ -88,7 +85,6 @@ impl std::fmt::Display for H { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", &self) //~^ recursive_format_impl - } } @@ -96,7 +92,6 @@ impl std::fmt::Debug for H { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", &self) //~^ recursive_format_impl - } } @@ -107,7 +102,6 @@ impl std::fmt::Display for H2 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", &&&self) //~^ recursive_format_impl - } } @@ -183,7 +177,6 @@ impl std::fmt::Display for J { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", &*self) //~^ recursive_format_impl - } } @@ -191,7 +184,6 @@ impl std::fmt::Debug for J { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{:?}", &*self) //~^ recursive_format_impl - } } @@ -209,7 +201,6 @@ impl std::fmt::Display for J2 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", *self) //~^ recursive_format_impl - } } @@ -227,7 +218,6 @@ impl std::fmt::Display for J3 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", **&&*self) //~^ recursive_format_impl - } } @@ -245,7 +235,6 @@ impl std::fmt::Display for J4 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", &&**&&*self) //~^ recursive_format_impl - } } diff --git a/tests/ui/recursive_format_impl.stderr b/tests/ui/recursive_format_impl.stderr index 515f18d5b477..31960c7193b4 100644 --- a/tests/ui/recursive_format_impl.stderr +++ b/tests/ui/recursive_format_impl.stderr @@ -8,7 +8,7 @@ LL | write!(f, "{}", self.to_string()) = help: to override `-D warnings` add `#[allow(clippy::recursive_format_impl)]` error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:78:9 + --> tests/ui/recursive_format_impl.rs:76:9 | LL | write!(f, "{}", self) | ^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | write!(f, "{}", self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:89:9 + --> tests/ui/recursive_format_impl.rs:86:9 | LL | write!(f, "{}", &self) | ^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | write!(f, "{}", &self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Debug` in `impl Debug` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:97:9 + --> tests/ui/recursive_format_impl.rs:93:9 | LL | write!(f, "{:?}", &self) | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | write!(f, "{:?}", &self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:108:9 + --> tests/ui/recursive_format_impl.rs:103:9 | LL | write!(f, "{}", &&&self) | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | write!(f, "{}", &&&self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:184:9 + --> tests/ui/recursive_format_impl.rs:178:9 | LL | write!(f, "{}", &*self) | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | write!(f, "{}", &*self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Debug` in `impl Debug` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:192:9 + --> tests/ui/recursive_format_impl.rs:185:9 | LL | write!(f, "{:?}", &*self) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | write!(f, "{:?}", &*self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:210:9 + --> tests/ui/recursive_format_impl.rs:202:9 | LL | write!(f, "{}", *self) | ^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | write!(f, "{}", *self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:228:9 + --> tests/ui/recursive_format_impl.rs:219:9 | LL | write!(f, "{}", **&&*self) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | write!(f, "{}", **&&*self) = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error: using `self` as `Display` in `impl Display` will cause infinite recursion - --> tests/ui/recursive_format_impl.rs:246:9 + --> tests/ui/recursive_format_impl.rs:236:9 | LL | write!(f, "{}", &&**&&*self) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_allocation.rs b/tests/ui/redundant_allocation.rs index e3bf6c58b153..0562f7dcc761 100644 --- a/tests/ui/redundant_allocation.rs +++ b/tests/ui/redundant_allocation.rs @@ -16,26 +16,18 @@ mod outer_box { pub fn box_test6(foo: Box>) {} //~^ redundant_allocation - - pub fn box_test7(foo: Box>) {} //~^ redundant_allocation - - pub fn box_test8() -> Box>> { - //~^ redundant_allocation - + //~^ redundant_allocation unimplemented!(); } pub fn box_test9(foo: Box>) -> Box>> { - //~^ redundant_allocation - //~| redundant_allocation - - - + //~^ redundant_allocation + //~| redundant_allocation unimplemented!(); } @@ -50,26 +42,18 @@ mod outer_rc { pub fn rc_test5(a: Rc>) {} //~^ redundant_allocation - - pub fn rc_test7(a: Rc>) {} //~^ redundant_allocation - - pub fn rc_test8() -> Rc>> { - //~^ redundant_allocation - + //~^ redundant_allocation unimplemented!(); } pub fn rc_test9(foo: Rc>) -> Rc>> { - //~^ redundant_allocation - //~| redundant_allocation - - - + //~^ redundant_allocation + //~| redundant_allocation unimplemented!(); } @@ -84,26 +68,18 @@ mod outer_arc { pub fn arc_test5(a: Arc>) {} //~^ redundant_allocation - - pub fn arc_test6(a: Arc>) {} //~^ redundant_allocation - - pub fn arc_test8() -> Arc>> { - //~^ redundant_allocation - + //~^ redundant_allocation unimplemented!(); } pub fn arc_test9(foo: Arc>) -> Arc>> { - //~^ redundant_allocation - //~| redundant_allocation - - - + //~^ redundant_allocation + //~| redundant_allocation unimplemented!(); } @@ -128,8 +104,6 @@ mod box_dyn { pub fn test_arc(_: Arc>) {} pub fn test_rc_box(_: Rc>>) {} //~^ redundant_allocation - - } // https://github.com/rust-lang/rust-clippy/issues/8604 @@ -164,19 +138,14 @@ mod box_fat_ptr { pub fn test_rc_box_str(_: Rc>>) {} //~^ redundant_allocation - pub fn test_rc_box_slice(_: Rc>>) {} //~^ redundant_allocation - pub fn test_rc_box_path(_: Rc>>) {} //~^ redundant_allocation - pub fn test_rc_box_custom(_: Rc>>) {} //~^ redundant_allocation - - } // https://github.com/rust-lang/rust-clippy/issues/11417 diff --git a/tests/ui/redundant_allocation.stderr b/tests/ui/redundant_allocation.stderr index 407cdef1c20d..44d30f95d7bc 100644 --- a/tests/ui/redundant_allocation.stderr +++ b/tests/ui/redundant_allocation.stderr @@ -10,7 +10,7 @@ LL | pub fn box_test6(foo: Box>) {} = help: to override `-D warnings` add `#[allow(clippy::redundant_allocation)]` error: usage of `Box>` - --> tests/ui/redundant_allocation.rs:21:30 + --> tests/ui/redundant_allocation.rs:19:30 | LL | pub fn box_test7(foo: Box>) {} | ^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | pub fn box_test7(foo: Box>) {} = help: consider using just `Box` or `Arc` error: usage of `Box>>` - --> tests/ui/redundant_allocation.rs:26:27 + --> tests/ui/redundant_allocation.rs:22:27 | LL | pub fn box_test8() -> Box>> { | ^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | pub fn box_test8() -> Box>> { = help: consider using just `Box>` or `Rc>` error: usage of `Box>` - --> tests/ui/redundant_allocation.rs:33:30 + --> tests/ui/redundant_allocation.rs:28:30 | LL | pub fn box_test9(foo: Box>) -> Box>> { | ^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | pub fn box_test9(foo: Box>) -> Box>> { = help: consider using just `Box` or `Arc` error: usage of `Box>>` - --> tests/ui/redundant_allocation.rs:33:46 + --> tests/ui/redundant_allocation.rs:28:46 | LL | pub fn box_test9(foo: Box>) -> Box>> { | ^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | pub fn box_test9(foo: Box>) -> Box>> { = help: consider using just `Box>` or `Arc>` error: usage of `Rc>` - --> tests/ui/redundant_allocation.rs:50:24 + --> tests/ui/redundant_allocation.rs:42:24 | LL | pub fn rc_test5(a: Rc>) {} | ^^^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | pub fn rc_test5(a: Rc>) {} = help: consider using just `Rc` or `Box` error: usage of `Rc>` - --> tests/ui/redundant_allocation.rs:55:24 + --> tests/ui/redundant_allocation.rs:45:24 | LL | pub fn rc_test7(a: Rc>) {} | ^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | pub fn rc_test7(a: Rc>) {} = help: consider using just `Rc` or `Arc` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:60:26 + --> tests/ui/redundant_allocation.rs:48:26 | LL | pub fn rc_test8() -> Rc>> { | ^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | pub fn rc_test8() -> Rc>> { = help: consider using just `Rc>` or `Box>` error: usage of `Rc>` - --> tests/ui/redundant_allocation.rs:67:29 + --> tests/ui/redundant_allocation.rs:54:29 | LL | pub fn rc_test9(foo: Rc>) -> Rc>> { | ^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | pub fn rc_test9(foo: Rc>) -> Rc>> { = help: consider using just `Rc` or `Arc` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:67:44 + --> tests/ui/redundant_allocation.rs:54:44 | LL | pub fn rc_test9(foo: Rc>) -> Rc>> { | ^^^^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | pub fn rc_test9(foo: Rc>) -> Rc>> { = help: consider using just `Rc>` or `Arc>` error: usage of `Arc>` - --> tests/ui/redundant_allocation.rs:84:25 + --> tests/ui/redundant_allocation.rs:68:25 | LL | pub fn arc_test5(a: Arc>) {} | ^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | pub fn arc_test5(a: Arc>) {} = help: consider using just `Arc` or `Box` error: usage of `Arc>` - --> tests/ui/redundant_allocation.rs:89:25 + --> tests/ui/redundant_allocation.rs:71:25 | LL | pub fn arc_test6(a: Arc>) {} | ^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | pub fn arc_test6(a: Arc>) {} = help: consider using just `Arc` or `Rc` error: usage of `Arc>>` - --> tests/ui/redundant_allocation.rs:94:27 + --> tests/ui/redundant_allocation.rs:74:27 | LL | pub fn arc_test8() -> Arc>> { | ^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | pub fn arc_test8() -> Arc>> { = help: consider using just `Arc>` or `Box>` error: usage of `Arc>` - --> tests/ui/redundant_allocation.rs:101:30 + --> tests/ui/redundant_allocation.rs:80:30 | LL | pub fn arc_test9(foo: Arc>) -> Arc>> { | ^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | pub fn arc_test9(foo: Arc>) -> Arc>> { = help: consider using just `Arc` or `Rc` error: usage of `Arc>>` - --> tests/ui/redundant_allocation.rs:101:45 + --> tests/ui/redundant_allocation.rs:80:45 | LL | pub fn arc_test9(foo: Arc>) -> Arc>> { | ^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | pub fn arc_test9(foo: Arc>) -> Arc>> { = help: consider using just `Arc>` or `Rc>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:129:27 + --> tests/ui/redundant_allocation.rs:105:27 | LL | pub fn test_rc_box(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | pub fn test_rc_box(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:164:31 + --> tests/ui/redundant_allocation.rs:138:31 | LL | pub fn test_rc_box_str(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | pub fn test_rc_box_str(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:168:33 + --> tests/ui/redundant_allocation.rs:141:33 | LL | pub fn test_rc_box_slice(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ LL | pub fn test_rc_box_slice(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:172:32 + --> tests/ui/redundant_allocation.rs:144:32 | LL | pub fn test_rc_box_path(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | pub fn test_rc_box_path(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> tests/ui/redundant_allocation.rs:176:34 + --> tests/ui/redundant_allocation.rs:147:34 | LL | pub fn test_rc_box_custom(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_clone.fixed b/tests/ui/redundant_clone.fixed index e0657246bd00..23c00b34a00a 100644 --- a/tests/ui/redundant_clone.fixed +++ b/tests/ui/redundant_clone.fixed @@ -221,7 +221,7 @@ fn clone_then_move_cloned() { let x = Alpha; // ok, data is moved while the clone is in use. foo(&x, move || { - //~^ redundant_clone + //~^ redundant_clone let _ = x; }); diff --git a/tests/ui/redundant_clone.rs b/tests/ui/redundant_clone.rs index 53e60a44d7df..f9fe8ba0236d 100644 --- a/tests/ui/redundant_clone.rs +++ b/tests/ui/redundant_clone.rs @@ -221,7 +221,7 @@ fn clone_then_move_cloned() { let x = Alpha; // ok, data is moved while the clone is in use. foo(&x.clone(), move || { - //~^ redundant_clone + //~^ redundant_clone let _ = x; }); diff --git a/tests/ui/redundant_closure_call_early.rs b/tests/ui/redundant_closure_call_early.rs index 2f4feeed9ae6..722f7c03909f 100644 --- a/tests/ui/redundant_closure_call_early.rs +++ b/tests/ui/redundant_closure_call_early.rs @@ -9,13 +9,10 @@ fn main() { let mut k = (|m| m + 1)(i); //~^ redundant_closure_call - - // lint here k = (|a, b| a * b)(1, 5); //~^ redundant_closure_call - // don't lint these #[allow(clippy::needless_return)] (|| return 2)(); diff --git a/tests/ui/redundant_closure_call_early.stderr b/tests/ui/redundant_closure_call_early.stderr index 4cfde9a64b57..1dd24baf9dae 100644 --- a/tests/ui/redundant_closure_call_early.stderr +++ b/tests/ui/redundant_closure_call_early.stderr @@ -8,7 +8,7 @@ LL | let mut k = (|m| m + 1)(i); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_early.rs:15:9 + --> tests/ui/redundant_closure_call_early.rs:13:9 | LL | k = (|a, b| a * b)(1, 5); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_closure_call_fixable.fixed b/tests/ui/redundant_closure_call_fixable.fixed index 528a2000693e..099c118e64e3 100644 --- a/tests/ui/redundant_closure_call_fixable.fixed +++ b/tests/ui/redundant_closure_call_fixable.fixed @@ -15,13 +15,13 @@ fn main() { let a = 42; //~^ redundant_closure_call let b = async { - //~^ redundant_closure_call + //~^ redundant_closure_call let x = something().await; let y = something_else().await; x * y }; let c = { - //~^ redundant_closure_call + //~^ redundant_closure_call let x = 21; let y = 2; x * y diff --git a/tests/ui/redundant_closure_call_fixable.rs b/tests/ui/redundant_closure_call_fixable.rs index c3cbd8d61ada..da5dd7ef263b 100644 --- a/tests/ui/redundant_closure_call_fixable.rs +++ b/tests/ui/redundant_closure_call_fixable.rs @@ -15,13 +15,13 @@ fn main() { let a = (|| 42)(); //~^ redundant_closure_call let b = (async || { - //~^ redundant_closure_call + //~^ redundant_closure_call let x = something().await; let y = something_else().await; x * y })(); let c = (|| { - //~^ redundant_closure_call + //~^ redundant_closure_call let x = 21; let y = 2; x * y diff --git a/tests/ui/redundant_closure_call_late.rs b/tests/ui/redundant_closure_call_late.rs index c697fedb871e..fd997b1b5fa7 100644 --- a/tests/ui/redundant_closure_call_late.rs +++ b/tests/ui/redundant_closure_call_late.rs @@ -16,8 +16,6 @@ fn main() { i = redun_closure(); //~^ redundant_closure_call - - // shadowed closures are supported, lint here let shadowed_closure = || 1; i = shadowed_closure(); @@ -27,7 +25,6 @@ fn main() { i = shadowed_closure(); //~^ redundant_closure_call - // don't lint here let shadowed_closure = || 2; i = shadowed_closure(); diff --git a/tests/ui/redundant_closure_call_late.stderr b/tests/ui/redundant_closure_call_late.stderr index abe7ac7b6595..ce2a21c23872 100644 --- a/tests/ui/redundant_closure_call_late.stderr +++ b/tests/ui/redundant_closure_call_late.stderr @@ -8,13 +8,13 @@ LL | i = redun_closure(); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]` error: closure called just once immediately after it was declared - --> tests/ui/redundant_closure_call_late.rs:23:5 + --> tests/ui/redundant_closure_call_late.rs:21:5 | LL | i = shadowed_closure(); | ^^^^^^^^^^^^^^^^^^^^^^ error: closure called just once immediately after it was declared - --> tests/ui/redundant_closure_call_late.rs:27:5 + --> tests/ui/redundant_closure_call_late.rs:25:5 | LL | i = shadowed_closure(); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_else.fixed b/tests/ui/redundant_else.fixed index 4dc325330249..8a3279f50180 100644 --- a/tests/ui/redundant_else.fixed +++ b/tests/ui/redundant_else.fixed @@ -10,7 +10,7 @@ fn main() { } //~^ redundant_else - println!("yet don't pull down your hedge."); + println!("yet don't pull down your hedge."); // continue if foo() { println!("He that lies down with Dogs,"); @@ -18,7 +18,7 @@ fn main() { } //~^ redundant_else - println!("shall rise up with fleas."); + println!("shall rise up with fleas."); // match block if foo() { match foo() { @@ -28,7 +28,7 @@ fn main() { } //~^ redundant_else - println!("You may delay, but time will not."); + println!("You may delay, but time will not."); } // else if if foo() { @@ -38,7 +38,7 @@ fn main() { } //~^ redundant_else - println!("A fat kitchen makes a lean will."); + println!("A fat kitchen makes a lean will."); // let binding outside of block let _ = { if foo() { @@ -46,7 +46,7 @@ fn main() { } //~^ redundant_else - 1 + 1 }; // else if with let binding outside of block let _ = { @@ -57,7 +57,7 @@ fn main() { } //~^ redundant_else - 2 + 2 }; // inside if let let _ = if let Some(1) = foo() { @@ -67,7 +67,7 @@ fn main() { } //~^ redundant_else - 1 + 1 } else { 1 }; diff --git a/tests/ui/redundant_else.rs b/tests/ui/redundant_else.rs index 842cb4bc9411..78abf4247a56 100644 --- a/tests/ui/redundant_else.rs +++ b/tests/ui/redundant_else.rs @@ -8,7 +8,7 @@ fn main() { println!("Love your neighbor;"); break; } else { - //~^ redundant_else + //~^ redundant_else println!("yet don't pull down your hedge."); } @@ -17,7 +17,7 @@ fn main() { println!("He that lies down with Dogs,"); continue; } else { - //~^ redundant_else + //~^ redundant_else println!("shall rise up with fleas."); } @@ -28,7 +28,7 @@ fn main() { _ => return, } } else { - //~^ redundant_else + //~^ redundant_else println!("You may delay, but time will not."); } @@ -39,7 +39,7 @@ fn main() { } else if foo() { return; } else { - //~^ redundant_else + //~^ redundant_else println!("A fat kitchen makes a lean will."); } @@ -48,7 +48,7 @@ fn main() { if foo() { return; } else { - //~^ redundant_else + //~^ redundant_else 1 } @@ -60,7 +60,7 @@ fn main() { } else if foo() { return; } else { - //~^ redundant_else + //~^ redundant_else 2 } @@ -71,7 +71,7 @@ fn main() { if foo() { return; } else { - //~^ redundant_else + //~^ redundant_else 1 } diff --git a/tests/ui/redundant_else.stderr b/tests/ui/redundant_else.stderr index 2cb0fd6f127f..0902c97af0dd 100644 --- a/tests/ui/redundant_else.stderr +++ b/tests/ui/redundant_else.stderr @@ -16,7 +16,7 @@ help: remove the `else` block and move the contents out LL ~ } LL + LL + -LL + println!("yet don't pull down your hedge."); +LL + println!("yet don't pull down your hedge."); | error: redundant else block @@ -35,7 +35,7 @@ help: remove the `else` block and move the contents out LL ~ } LL + LL + -LL + println!("shall rise up with fleas."); +LL + println!("shall rise up with fleas."); | error: redundant else block @@ -54,7 +54,7 @@ help: remove the `else` block and move the contents out LL ~ } LL + LL + -LL + println!("You may delay, but time will not."); +LL + println!("You may delay, but time will not."); | error: redundant else block @@ -73,7 +73,7 @@ help: remove the `else` block and move the contents out LL ~ } LL + LL + -LL + println!("A fat kitchen makes a lean will."); +LL + println!("A fat kitchen makes a lean will."); | error: redundant else block @@ -92,7 +92,7 @@ help: remove the `else` block and move the contents out LL ~ } LL + LL + -LL + 1 +LL + 1 | error: redundant else block @@ -111,7 +111,7 @@ help: remove the `else` block and move the contents out LL ~ } LL + LL + -LL + 2 +LL + 2 | error: redundant else block @@ -130,7 +130,7 @@ help: remove the `else` block and move the contents out LL ~ } LL + LL + -LL + 1 +LL + 1 | error: aborting due to 7 previous errors diff --git a/tests/ui/redundant_field_names.fixed b/tests/ui/redundant_field_names.fixed index 142828a2b2d8..4c922030eb66 100644 --- a/tests/ui/redundant_field_names.fixed +++ b/tests/ui/redundant_field_names.fixed @@ -34,7 +34,6 @@ fn main() { //~^ redundant_field_names age, //~^ redundant_field_names - name, //should be ok buzz: fizz, //should be ok foo: foo::BAR, //should be ok diff --git a/tests/ui/redundant_field_names.rs b/tests/ui/redundant_field_names.rs index 15fef11a0408..7d03e269cf25 100644 --- a/tests/ui/redundant_field_names.rs +++ b/tests/ui/redundant_field_names.rs @@ -34,7 +34,6 @@ fn main() { //~^ redundant_field_names age: age, //~^ redundant_field_names - name, //should be ok buzz: fizz, //should be ok foo: foo::BAR, //should be ok diff --git a/tests/ui/redundant_field_names.stderr b/tests/ui/redundant_field_names.stderr index 78b8a4f1118e..5554c28b7cff 100644 --- a/tests/ui/redundant_field_names.stderr +++ b/tests/ui/redundant_field_names.stderr @@ -14,37 +14,37 @@ LL | age: age, | ^^^^^^^^ help: replace it with: `age` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:57:25 + --> tests/ui/redundant_field_names.rs:56:25 | LL | let _ = RangeFrom { start: start }; | ^^^^^^^^^^^^ help: replace it with: `start` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:59:23 + --> tests/ui/redundant_field_names.rs:58:23 | LL | let _ = RangeTo { end: end }; | ^^^^^^^^ help: replace it with: `end` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:61:21 + --> tests/ui/redundant_field_names.rs:60:21 | LL | let _ = Range { start: start, end: end }; | ^^^^^^^^^^^^ help: replace it with: `start` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:61:35 + --> tests/ui/redundant_field_names.rs:60:35 | LL | let _ = Range { start: start, end: end }; | ^^^^^^^^ help: replace it with: `end` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:65:32 + --> tests/ui/redundant_field_names.rs:64:32 | LL | let _ = RangeToInclusive { end: end }; | ^^^^^^^^ help: replace it with: `end` error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:78:25 + --> tests/ui/redundant_field_names.rs:77:25 | LL | let _ = S { v: v }; | ^^^^ help: replace it with: `v` @@ -55,7 +55,7 @@ LL | internal!(v); = note: this error originates in the macro `internal` (in Nightly builds, run with -Z macro-backtrace for more info) error: redundant field names in struct initialization - --> tests/ui/redundant_field_names.rs:107:25 + --> tests/ui/redundant_field_names.rs:106:25 | LL | let _ = RangeFrom { start: start }; | ^^^^^^^^^^^^ help: replace it with: `start` diff --git a/tests/ui/redundant_guards.fixed b/tests/ui/redundant_guards.fixed index c7e6f44ad83e..9dd9d341db2e 100644 --- a/tests/ui/redundant_guards.fixed +++ b/tests/ui/redundant_guards.fixed @@ -52,7 +52,7 @@ fn main() { Some(Some(1)) if true => .., //~^ redundant_guards Some(Some(1)) => { - //~^ redundant_guards + //~^ redundant_guards println!("a"); .. }, diff --git a/tests/ui/redundant_guards.rs b/tests/ui/redundant_guards.rs index d3c55c18884d..e9950d3bbd1d 100644 --- a/tests/ui/redundant_guards.rs +++ b/tests/ui/redundant_guards.rs @@ -52,7 +52,7 @@ fn main() { Some(x) if matches!(x, Some(1) if true) => .., //~^ redundant_guards Some(x) if matches!(x, Some(1)) => { - //~^ redundant_guards + //~^ redundant_guards println!("a"); .. }, diff --git a/tests/ui/redundant_pattern_matching_drop_order.fixed b/tests/ui/redundant_pattern_matching_drop_order.fixed index 4de47a1ad3ee..1141b5db3ebf 100644 --- a/tests/ui/redundant_pattern_matching_drop_order.fixed +++ b/tests/ui/redundant_pattern_matching_drop_order.fixed @@ -22,7 +22,7 @@ fn main() { //~^ redundant_pattern_matching } if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching } else { } if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok() {} @@ -46,7 +46,7 @@ fn main() { //~^ redundant_pattern_matching } if None::>.is_none() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching } else { } @@ -69,7 +69,7 @@ fn main() { //~^ redundant_pattern_matching } if Pending::>.is_pending() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching } else { } diff --git a/tests/ui/redundant_pattern_matching_drop_order.rs b/tests/ui/redundant_pattern_matching_drop_order.rs index 4e37837c1fe6..f60ddf468309 100644 --- a/tests/ui/redundant_pattern_matching_drop_order.rs +++ b/tests/ui/redundant_pattern_matching_drop_order.rs @@ -22,7 +22,7 @@ fn main() { //~^ redundant_pattern_matching } if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching } else { } if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {} @@ -46,7 +46,7 @@ fn main() { //~^ redundant_pattern_matching } if let None = None::> { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching } else { } @@ -69,7 +69,7 @@ fn main() { //~^ redundant_pattern_matching } if let Pending = Pending::> { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching } else { } diff --git a/tests/ui/redundant_pattern_matching_if_let_true.fixed b/tests/ui/redundant_pattern_matching_if_let_true.fixed index f40cd01d16cb..980455da2ee7 100644 --- a/tests/ui/redundant_pattern_matching_if_let_true.fixed +++ b/tests/ui/redundant_pattern_matching_if_let_true.fixed @@ -27,11 +27,11 @@ fn main() { //~^ redundant_pattern_matching if let (true, true) = (k > 1, k > 2) {} while k > 1 { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching k += 1; } while condition!() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching k += 1; } diff --git a/tests/ui/redundant_pattern_matching_if_let_true.rs b/tests/ui/redundant_pattern_matching_if_let_true.rs index 143c279e41c1..9cb0fe2e65f6 100644 --- a/tests/ui/redundant_pattern_matching_if_let_true.rs +++ b/tests/ui/redundant_pattern_matching_if_let_true.rs @@ -27,11 +27,11 @@ fn main() { //~^ redundant_pattern_matching if let (true, true) = (k > 1, k > 2) {} while let true = k > 1 { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching k += 1; } while let true = condition!() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching k += 1; } diff --git a/tests/ui/redundant_pattern_matching_ipaddr.fixed b/tests/ui/redundant_pattern_matching_ipaddr.fixed index 05ea8f75dc89..549c97d9534a 100644 --- a/tests/ui/redundant_pattern_matching_ipaddr.fixed +++ b/tests/ui/redundant_pattern_matching_ipaddr.fixed @@ -52,7 +52,7 @@ fn main() { V6(Ipv6Addr::LOCALHOST).is_ipv4(); let _ = if V4(Ipv4Addr::LOCALHOST).is_ipv4() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching true } else { false @@ -61,10 +61,10 @@ fn main() { ipaddr_const(); let _ = if gen_ipaddr().is_ipv4() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 1 } else if gen_ipaddr().is_ipv6() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 2 } else { 3 diff --git a/tests/ui/redundant_pattern_matching_ipaddr.rs b/tests/ui/redundant_pattern_matching_ipaddr.rs index 4ff9b2204e8a..decb1396d56d 100644 --- a/tests/ui/redundant_pattern_matching_ipaddr.rs +++ b/tests/ui/redundant_pattern_matching_ipaddr.rs @@ -44,31 +44,31 @@ fn main() { } match V4(Ipv4Addr::LOCALHOST) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching V4(_) => true, V6(_) => false, }; match V4(Ipv4Addr::LOCALHOST) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching V4(_) => false, V6(_) => true, }; match V6(Ipv6Addr::LOCALHOST) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching V4(_) => false, V6(_) => true, }; match V6(Ipv6Addr::LOCALHOST) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching V4(_) => true, V6(_) => false, }; let _ = if let V4(_) = V4(Ipv4Addr::LOCALHOST) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching true } else { false @@ -77,10 +77,10 @@ fn main() { ipaddr_const(); let _ = if let V4(_) = gen_ipaddr() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 1 } else if let V6(_) = gen_ipaddr() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 2 } else { 3 @@ -105,13 +105,13 @@ const fn ipaddr_const() { //~^ redundant_pattern_matching match V4(Ipv4Addr::LOCALHOST) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching V4(_) => true, V6(_) => false, }; match V6(Ipv6Addr::LOCALHOST) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching V4(_) => false, V6(_) => true, }; diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed index 7d45bb63a395..711196f8e19b 100644 --- a/tests/ui/redundant_pattern_matching_option.fixed +++ b/tests/ui/redundant_pattern_matching_option.fixed @@ -38,7 +38,7 @@ fn main() { //~^ redundant_pattern_matching if Some(42).is_some() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching foo(); } else { bar(); @@ -55,7 +55,7 @@ fn main() { let mut v = vec![1, 2, 3]; while v.pop().is_some() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching foo(); } @@ -78,10 +78,10 @@ fn main() { issue10803(); let _ = if gen_opt().is_some() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 1 } else if gen_opt().is_none() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 2 } else { 3 diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs index 3d02bade4409..41106840cb8d 100644 --- a/tests/ui/redundant_pattern_matching_option.rs +++ b/tests/ui/redundant_pattern_matching_option.rs @@ -38,7 +38,7 @@ fn main() { //~^ redundant_pattern_matching if let Some(_) = Some(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching foo(); } else { bar(); @@ -55,7 +55,7 @@ fn main() { let mut v = vec![1, 2, 3]; while let Some(_) = v.pop() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching foo(); } @@ -64,19 +64,19 @@ fn main() { if Some(42).is_some() {} match Some(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Some(_) => true, None => false, }; match None::<()> { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Some(_) => false, None => true, }; let _ = match None::<()> { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Some(_) => false, None => true, }; @@ -90,10 +90,10 @@ fn main() { issue10803(); let _ = if let Some(_) = gen_opt() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 1 } else if let None = gen_opt() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 2 } else { 3 @@ -128,13 +128,13 @@ const fn issue6067() { //~^ redundant_pattern_matching match Some(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Some(_) => true, None => false, }; match None::<()> { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Some(_) => false, None => true, }; @@ -152,25 +152,25 @@ fn issue10726() { let x = Some(42); match x { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Some(_) => true, _ => false, }; match x { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching None => true, _ => false, }; match x { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Some(_) => false, _ => true, }; match x { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching None => false, _ => true, }; diff --git a/tests/ui/redundant_pattern_matching_poll.fixed b/tests/ui/redundant_pattern_matching_poll.fixed index f3ffb6b3c755..c8e18e8676f2 100644 --- a/tests/ui/redundant_pattern_matching_poll.fixed +++ b/tests/ui/redundant_pattern_matching_poll.fixed @@ -19,7 +19,7 @@ fn main() { //~^ redundant_pattern_matching if Ready(42).is_ready() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching foo(); } else { bar(); @@ -59,10 +59,10 @@ fn main() { poll_const(); let _ = if gen_poll().is_ready() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 1 } else if gen_poll().is_pending() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 2 } else { 3 diff --git a/tests/ui/redundant_pattern_matching_poll.rs b/tests/ui/redundant_pattern_matching_poll.rs index 30e80b24521d..727503d21a54 100644 --- a/tests/ui/redundant_pattern_matching_poll.rs +++ b/tests/ui/redundant_pattern_matching_poll.rs @@ -19,7 +19,7 @@ fn main() { //~^ redundant_pattern_matching if let Ready(_) = Ready(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching foo(); } else { bar(); @@ -47,19 +47,19 @@ fn main() { if Ready(42).is_ready() {} match Ready(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ready(_) => true, Pending => false, }; match Pending::<()> { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ready(_) => false, Pending => true, }; let _ = match Pending::<()> { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ready(_) => false, Pending => true, }; @@ -71,10 +71,10 @@ fn main() { poll_const(); let _ = if let Ready(_) = gen_poll() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 1 } else if let Pending = gen_poll() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 2 } else { 3 @@ -103,13 +103,13 @@ const fn poll_const() { //~^ redundant_pattern_matching match Ready(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ready(_) => true, Pending => false, }; match Pending::<()> { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ready(_) => false, Pending => true, }; diff --git a/tests/ui/redundant_pattern_matching_result.fixed b/tests/ui/redundant_pattern_matching_result.fixed index 3bb9dacf4618..115879608314 100644 --- a/tests/ui/redundant_pattern_matching_result.fixed +++ b/tests/ui/redundant_pattern_matching_result.fixed @@ -53,10 +53,10 @@ fn main() { issue10803(); let _ = if gen_res().is_ok() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 1 } else if gen_res().is_err() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 2 } else { 3 diff --git a/tests/ui/redundant_pattern_matching_result.rs b/tests/ui/redundant_pattern_matching_result.rs index f2632286ea3c..35f8f91b3152 100644 --- a/tests/ui/redundant_pattern_matching_result.rs +++ b/tests/ui/redundant_pattern_matching_result.rs @@ -36,25 +36,25 @@ fn main() { } match Ok::(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ok(_) => true, Err(_) => false, }; match Ok::(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ok(_) => false, Err(_) => true, }; match Err::(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ok(_) => false, Err(_) => true, }; match Err::(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ok(_) => true, Err(_) => false, }; @@ -69,10 +69,10 @@ fn main() { issue10803(); let _ = if let Ok(_) = gen_res() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 1 } else if let Err(_) = gen_res() { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching 2 } else { 3 @@ -138,13 +138,13 @@ const fn issue6067() { //~^ redundant_pattern_matching match Ok::(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ok(_) => true, Err(_) => false, }; match Err::(42) { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ok(_) => false, Err(_) => true, }; @@ -155,25 +155,25 @@ fn issue10726() { let x: Result = Ok(42); match x { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ok(_) => true, _ => false, }; match x { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Ok(_) => false, _ => true, }; match x { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Err(_) => true, _ => false, }; match x { - //~^ redundant_pattern_matching + //~^ redundant_pattern_matching Err(_) => false, _ => true, }; diff --git a/tests/ui/redundant_pub_crate.fixed b/tests/ui/redundant_pub_crate.fixed index 2072282bd2c3..7424af19a999 100644 --- a/tests/ui/redundant_pub_crate.fixed +++ b/tests/ui/redundant_pub_crate.fixed @@ -16,7 +16,7 @@ mod m1 { } pub mod m1_2 { - //~^ redundant_pub_crate + //~^ redundant_pub_crate //:^ private due to m1 fn f() {} pub fn g() {} // private due to m1_2 and m1 @@ -46,7 +46,7 @@ pub(crate) mod m2 { } pub mod m2_2 { - //~^ redundant_pub_crate + //~^ redundant_pub_crate //:^ already crate visible due to m2 fn f() {} pub fn g() {} // already crate visible due to m2_2 and m2 @@ -103,7 +103,7 @@ mod m4 { } pub mod m4_2 { - //~^ redundant_pub_crate + //~^ redundant_pub_crate //:^ private: not re-exported by `pub use m4::*` fn f() {} pub fn g() {} // private due to m4_2 diff --git a/tests/ui/redundant_pub_crate.rs b/tests/ui/redundant_pub_crate.rs index d8eaa8cdbc69..a995ed592289 100644 --- a/tests/ui/redundant_pub_crate.rs +++ b/tests/ui/redundant_pub_crate.rs @@ -16,7 +16,7 @@ mod m1 { } pub(crate) mod m1_2 { - //~^ redundant_pub_crate + //~^ redundant_pub_crate //:^ private due to m1 fn f() {} pub(crate) fn g() {} // private due to m1_2 and m1 @@ -46,7 +46,7 @@ pub(crate) mod m2 { } pub(crate) mod m2_2 { - //~^ redundant_pub_crate + //~^ redundant_pub_crate //:^ already crate visible due to m2 fn f() {} pub(crate) fn g() {} // already crate visible due to m2_2 and m2 @@ -103,7 +103,7 @@ mod m4 { } pub(crate) mod m4_2 { - //~^ redundant_pub_crate + //~^ redundant_pub_crate //:^ private: not re-exported by `pub use m4::*` fn f() {} pub(crate) fn g() {} // private due to m4_2 diff --git a/tests/ui/redundant_static_lifetimes_multiple.rs b/tests/ui/redundant_static_lifetimes_multiple.rs index 02f3829d8c03..8cb6e4491842 100644 --- a/tests/ui/redundant_static_lifetimes_multiple.rs +++ b/tests/ui/redundant_static_lifetimes_multiple.rs @@ -5,31 +5,20 @@ const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ER //~^ redundant_static_lifetimes //~| redundant_static_lifetimes - - - const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; //~^ redundant_static_lifetimes //~| redundant_static_lifetimes - - static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static //~^ redundant_static_lifetimes //~| redundant_static_lifetimes - - static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static //~^ redundant_static_lifetimes //~| redundant_static_lifetimes - - static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; //~^ redundant_static_lifetimes //~| redundant_static_lifetimes - - fn main() {} diff --git a/tests/ui/redundant_static_lifetimes_multiple.stderr b/tests/ui/redundant_static_lifetimes_multiple.stderr index 486a23b06089..aed16204f1c2 100644 --- a/tests/ui/redundant_static_lifetimes_multiple.stderr +++ b/tests/ui/redundant_static_lifetimes_multiple.stderr @@ -14,49 +14,49 @@ LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; | -^^^^^^^---- help: consider removing `'static`: `&str` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:11:29 + --> tests/ui/redundant_static_lifetimes_multiple.rs:8:29 | LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; | -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]` error: constants have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:11:39 + --> tests/ui/redundant_static_lifetimes_multiple.rs:8:39 | LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:17:40 + --> tests/ui/redundant_static_lifetimes_multiple.rs:12:40 | LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:17:55 + --> tests/ui/redundant_static_lifetimes_multiple.rs:12:55 | LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:23:26 + --> tests/ui/redundant_static_lifetimes_multiple.rs:16:26 | LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static | -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:23:38 + --> tests/ui/redundant_static_lifetimes_multiple.rs:16:38 | LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:29:37 + --> tests/ui/redundant_static_lifetimes_multiple.rs:20:37 | LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; | -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]` error: statics have by default a `'static` lifetime - --> tests/ui/redundant_static_lifetimes_multiple.rs:29:47 + --> tests/ui/redundant_static_lifetimes_multiple.rs:20:47 | LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; | -^^^^^^^---- help: consider removing `'static`: `&str` diff --git a/tests/ui/redundant_type_annotations.rs b/tests/ui/redundant_type_annotations.rs index 5023ec7ee576..55c19d194a49 100644 --- a/tests/ui/redundant_type_annotations.rs +++ b/tests/ui/redundant_type_annotations.rs @@ -81,13 +81,11 @@ impl Pie { let v: u32 = self.return_an_int(); //~^ redundant_type_annotations - let v: &u32 = self.return_a_ref(); //~^ redundant_type_annotations let v: &Slice = self.return_a_ref_to_struct(); //~^ redundant_type_annotations - } } @@ -162,38 +160,29 @@ fn test_functions() { let _return: String = return_a_string(); //~^ redundant_type_annotations - let _return: Pie = return_a_struct(); //~^ redundant_type_annotations - let _return: Pizza = return_an_enum(); //~^ redundant_type_annotations - let _return: u32 = return_an_int(); //~^ redundant_type_annotations - let _return: String = String::new(); //~^ redundant_type_annotations - let new_pie: Pie = Pie::new(); //~^ redundant_type_annotations - let _return: u32 = new_pie.return_an_int(); //~^ redundant_type_annotations - let _return: u32 = Pie::associated_return_an_int(); //~^ redundant_type_annotations - let _return: String = Pie::associated_return_a_string(); //~^ redundant_type_annotations - } fn test_simple_types() { @@ -202,22 +191,17 @@ fn test_simple_types() { let _var: u32 = u32::MAX; //~^ redundant_type_annotations - let _var: u32 = 5_u32; //~^ redundant_type_annotations - let _var: &str = "test"; //~^ redundant_type_annotations - let _var: &[u8; 4] = b"test"; //~^ redundant_type_annotations - let _var: bool = false; //~^ redundant_type_annotations - } fn issue12212() { diff --git a/tests/ui/redundant_type_annotations.stderr b/tests/ui/redundant_type_annotations.stderr index de78ad5e4b48..d2f04cc4768e 100644 --- a/tests/ui/redundant_type_annotations.stderr +++ b/tests/ui/redundant_type_annotations.stderr @@ -8,97 +8,97 @@ LL | let v: u32 = self.return_an_int(); = help: to override `-D warnings` add `#[allow(clippy::redundant_type_annotations)]` error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:85:9 + --> tests/ui/redundant_type_annotations.rs:84:9 | LL | let v: &u32 = self.return_a_ref(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:88:9 + --> tests/ui/redundant_type_annotations.rs:87:9 | LL | let v: &Slice = self.return_a_ref_to_struct(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:162:5 + --> tests/ui/redundant_type_annotations.rs:160:5 | LL | let _return: String = return_a_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:166:5 + --> tests/ui/redundant_type_annotations.rs:163:5 | LL | let _return: Pie = return_a_struct(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:170:5 + --> tests/ui/redundant_type_annotations.rs:166:5 | LL | let _return: Pizza = return_an_enum(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:174:5 + --> tests/ui/redundant_type_annotations.rs:169:5 | LL | let _return: u32 = return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:178:5 + --> tests/ui/redundant_type_annotations.rs:172:5 | LL | let _return: String = String::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:182:5 + --> tests/ui/redundant_type_annotations.rs:175:5 | LL | let new_pie: Pie = Pie::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:186:5 + --> tests/ui/redundant_type_annotations.rs:178:5 | LL | let _return: u32 = new_pie.return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:190:5 + --> tests/ui/redundant_type_annotations.rs:181:5 | LL | let _return: u32 = Pie::associated_return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:194:5 + --> tests/ui/redundant_type_annotations.rs:184:5 | LL | let _return: String = Pie::associated_return_a_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:202:5 + --> tests/ui/redundant_type_annotations.rs:191:5 | LL | let _var: u32 = u32::MAX; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:206:5 + --> tests/ui/redundant_type_annotations.rs:194:5 | LL | let _var: u32 = 5_u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:210:5 + --> tests/ui/redundant_type_annotations.rs:197:5 | LL | let _var: &str = "test"; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:214:5 + --> tests/ui/redundant_type_annotations.rs:200:5 | LL | let _var: &[u8; 4] = b"test"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> tests/ui/redundant_type_annotations.rs:218:5 + --> tests/ui/redundant_type_annotations.rs:203:5 | LL | let _var: bool = false; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/ref_binding_to_reference.rs b/tests/ui/ref_binding_to_reference.rs index 55df796c41dc..365fd8edea78 100644 --- a/tests/ui/ref_binding_to_reference.rs +++ b/tests/ui/ref_binding_to_reference.rs @@ -29,15 +29,13 @@ fn main() { let _: &&String = match Some(&x) { Some(ref x) => x, //~^ ref_binding_to_reference - - None => return, }; // Err, reference to a &String let _: &&String = match Some(&x) { Some(ref x) => { - //~^ ref_binding_to_reference + //~^ ref_binding_to_reference f1(x); f1(*x); @@ -50,13 +48,12 @@ fn main() { match Some(&x) { Some(ref x) => m2!(x), //~^ ref_binding_to_reference - None => return, } // Err, reference to a &String let _ = |&ref x: &&String| { - //~^ ref_binding_to_reference + //~^ ref_binding_to_reference let _: &&String = x; }; @@ -64,7 +61,7 @@ fn main() { // Err, reference to a &String fn f2<'a>(&ref x: &&'a String) -> &'a String { -//~^ ref_binding_to_reference + //~^ ref_binding_to_reference let _: &&String = x; *x @@ -73,7 +70,7 @@ fn f2<'a>(&ref x: &&'a String) -> &'a String { trait T1 { // Err, reference to a &String fn f(&ref x: &&String) { - //~^ ref_binding_to_reference + //~^ ref_binding_to_reference let _: &&String = x; } @@ -83,7 +80,7 @@ struct S; impl T1 for S { // Err, reference to a &String fn f(&ref x: &&String) { - //~^ ref_binding_to_reference + //~^ ref_binding_to_reference let _: &&String = x; } diff --git a/tests/ui/ref_binding_to_reference.stderr b/tests/ui/ref_binding_to_reference.stderr index 66e769ec61b3..d245355c139d 100644 --- a/tests/ui/ref_binding_to_reference.stderr +++ b/tests/ui/ref_binding_to_reference.stderr @@ -12,7 +12,7 @@ LL | Some(x) => &x, | ~ ~~ error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:39:14 + --> tests/ui/ref_binding_to_reference.rs:37:14 | LL | Some(ref x) => { | ^^^^^ @@ -28,7 +28,7 @@ LL ~ &x | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:51:14 + --> tests/ui/ref_binding_to_reference.rs:49:14 | LL | Some(ref x) => m2!(x), | ^^^^^ @@ -39,7 +39,7 @@ LL | Some(x) => m2!(&x), | ~ ~~ error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:58:15 + --> tests/ui/ref_binding_to_reference.rs:55:15 | LL | let _ = |&ref x: &&String| { | ^^^^^ @@ -53,7 +53,7 @@ LL ~ let _: &&String = &x; | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:66:12 + --> tests/ui/ref_binding_to_reference.rs:63:12 | LL | fn f2<'a>(&ref x: &&'a String) -> &'a String { | ^^^^^ @@ -68,7 +68,7 @@ LL ~ x | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:75:11 + --> tests/ui/ref_binding_to_reference.rs:72:11 | LL | fn f(&ref x: &&String) { | ^^^^^ @@ -82,7 +82,7 @@ LL ~ let _: &&String = &x; | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:85:11 + --> tests/ui/ref_binding_to_reference.rs:82:11 | LL | fn f(&ref x: &&String) { | ^^^^^ diff --git a/tests/ui/ref_option/ref_option.all.fixed b/tests/ui/ref_option/ref_option.all.fixed index d7b0e13e5bb9..4159e916f199 100644 --- a/tests/ui/ref_option/ref_option.all.fixed +++ b/tests/ui/ref_option/ref_option.all.fixed @@ -12,17 +12,17 @@ fn opt_gen(a: Option<&T>) {} fn opt_string(a: std::option::Option<&String>) {} //~^ ref_option fn ret_string<'a>(p: &'a str) -> Option<&'a u8> { -//~^ ref_option + //~^ ref_option panic!() } fn ret_string_static() -> Option<&'static u8> { -//~^ ref_option + //~^ ref_option panic!() } fn mult_string(a: Option<&String>, b: Option<&Vec>) {} //~^ ref_option fn ret_box<'a>() -> Option<&'a Box> { -//~^ ref_option + //~^ ref_option panic!() } @@ -51,14 +51,14 @@ impl PubStruct { pub fn pub_opt_params(&self, a: Option<&()>) {} //~[all]^ ref_option pub fn pub_opt_ret(&self) -> Option<&String> { - //~[all]^ ref_option + //~[all]^ ref_option panic!() } fn private_opt_params(&self, a: Option<&()>) {} //~^ ref_option fn private_opt_ret(&self) -> Option<&String> { - //~^ ref_option + //~^ ref_option panic!() } } diff --git a/tests/ui/ref_option/ref_option.private.fixed b/tests/ui/ref_option/ref_option.private.fixed index 4036c6a08dca..3b158befb926 100644 --- a/tests/ui/ref_option/ref_option.private.fixed +++ b/tests/ui/ref_option/ref_option.private.fixed @@ -12,17 +12,17 @@ fn opt_gen(a: Option<&T>) {} fn opt_string(a: std::option::Option<&String>) {} //~^ ref_option fn ret_string<'a>(p: &'a str) -> Option<&'a u8> { -//~^ ref_option + //~^ ref_option panic!() } fn ret_string_static() -> Option<&'static u8> { -//~^ ref_option + //~^ ref_option panic!() } fn mult_string(a: Option<&String>, b: Option<&Vec>) {} //~^ ref_option fn ret_box<'a>() -> Option<&'a Box> { -//~^ ref_option + //~^ ref_option panic!() } @@ -51,14 +51,14 @@ impl PubStruct { pub fn pub_opt_params(&self, a: &Option<()>) {} //~[all]^ ref_option pub fn pub_opt_ret(&self) -> &Option { - //~[all]^ ref_option + //~[all]^ ref_option panic!() } fn private_opt_params(&self, a: Option<&()>) {} //~^ ref_option fn private_opt_ret(&self) -> Option<&String> { - //~^ ref_option + //~^ ref_option panic!() } } diff --git a/tests/ui/ref_option/ref_option.rs b/tests/ui/ref_option/ref_option.rs index 86b5c6fe896b..35cd94174f8b 100644 --- a/tests/ui/ref_option/ref_option.rs +++ b/tests/ui/ref_option/ref_option.rs @@ -12,17 +12,17 @@ fn opt_gen(a: &Option) {} fn opt_string(a: &std::option::Option) {} //~^ ref_option fn ret_string<'a>(p: &'a str) -> &'a Option { -//~^ ref_option + //~^ ref_option panic!() } fn ret_string_static() -> &'static Option { -//~^ ref_option + //~^ ref_option panic!() } fn mult_string(a: &Option, b: &Option>) {} //~^ ref_option fn ret_box<'a>() -> &'a Option> { -//~^ ref_option + //~^ ref_option panic!() } @@ -51,14 +51,14 @@ impl PubStruct { pub fn pub_opt_params(&self, a: &Option<()>) {} //~[all]^ ref_option pub fn pub_opt_ret(&self) -> &Option { - //~[all]^ ref_option + //~[all]^ ref_option panic!() } fn private_opt_params(&self, a: &Option<()>) {} //~^ ref_option fn private_opt_ret(&self) -> &Option { - //~^ ref_option + //~^ ref_option panic!() } } diff --git a/tests/ui/ref_option_ref.rs b/tests/ui/ref_option_ref.rs index de936cb08108..9632611f7df4 100644 --- a/tests/ui/ref_option_ref.rs +++ b/tests/ui/ref_option_ref.rs @@ -10,25 +10,21 @@ static THRESHOLD: i32 = 10; static REF_THRESHOLD: &Option<&i32> = &Some(&THRESHOLD); //~^ ref_option_ref - const CONST_THRESHOLD: &i32 = &10; const REF_CONST: &Option<&i32> = &Some(CONST_THRESHOLD); //~^ ref_option_ref - type RefOptRefU32<'a> = &'a Option<&'a u32>; //~^ ref_option_ref type RefOptRef<'a, T> = &'a Option<&'a T>; //~^ ref_option_ref - fn foo(data: &Option<&u32>) {} //~^ ref_option_ref - fn bar(data: &u32) -> &Option<&u32> { -//~^ ref_option_ref + //~^ ref_option_ref &None } @@ -36,18 +32,15 @@ fn bar(data: &u32) -> &Option<&u32> { struct StructRef<'a> { data: &'a Option<&'a u32>, //~^ ref_option_ref - } struct StructTupleRef<'a>(u32, &'a Option<&'a u32>); //~^ ref_option_ref - enum EnumRef<'a> { Variant1(u32), Variant2(&'a Option<&'a u32>), //~^ ref_option_ref - } trait RefOptTrait { @@ -59,14 +52,12 @@ impl RefOptTrait for u32 { type A = &'static Option<&'static Self>; //~^ ref_option_ref - fn foo(&self, _: Self::A) {} } fn main() { let x: &Option<&u32> = &None; //~^ ref_option_ref - } fn issue9682(arg: &Option<&mut String>) { diff --git a/tests/ui/ref_option_ref.stderr b/tests/ui/ref_option_ref.stderr index fcafbc5ea18e..25064a61ee88 100644 --- a/tests/ui/ref_option_ref.stderr +++ b/tests/ui/ref_option_ref.stderr @@ -8,61 +8,61 @@ LL | static REF_THRESHOLD: &Option<&i32> = &Some(&THRESHOLD); = help: to override `-D warnings` add `#[allow(clippy::ref_option_ref)]` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:15:18 + --> tests/ui/ref_option_ref.rs:14:18 | LL | const REF_CONST: &Option<&i32> = &Some(CONST_THRESHOLD); | ^^^^^^^^^^^^^ help: try: `Option<&i32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:19:25 + --> tests/ui/ref_option_ref.rs:17:25 | LL | type RefOptRefU32<'a> = &'a Option<&'a u32>; | ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:22:25 + --> tests/ui/ref_option_ref.rs:20:25 | LL | type RefOptRef<'a, T> = &'a Option<&'a T>; | ^^^^^^^^^^^^^^^^^ help: try: `Option<&'a T>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:26:14 + --> tests/ui/ref_option_ref.rs:23:14 | LL | fn foo(data: &Option<&u32>) {} | ^^^^^^^^^^^^^ help: try: `Option<&u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:30:23 + --> tests/ui/ref_option_ref.rs:26:23 | LL | fn bar(data: &u32) -> &Option<&u32> { | ^^^^^^^^^^^^^ help: try: `Option<&u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:37:11 + --> tests/ui/ref_option_ref.rs:33:11 | LL | data: &'a Option<&'a u32>, | ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:42:32 + --> tests/ui/ref_option_ref.rs:37:32 | LL | struct StructTupleRef<'a>(u32, &'a Option<&'a u32>); | ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:48:14 + --> tests/ui/ref_option_ref.rs:42:14 | LL | Variant2(&'a Option<&'a u32>), | ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:59:14 + --> tests/ui/ref_option_ref.rs:52:14 | LL | type A = &'static Option<&'static Self>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'static Self>` error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>` - --> tests/ui/ref_option_ref.rs:67:12 + --> tests/ui/ref_option_ref.rs:59:12 | LL | let x: &Option<&u32> = &None; | ^^^^^^^^^^^^^ help: try: `Option<&u32>` diff --git a/tests/ui/ref_patterns.rs b/tests/ui/ref_patterns.rs index 214778b78b5b..2905af13ccb6 100644 --- a/tests/ui/ref_patterns.rs +++ b/tests/ui/ref_patterns.rs @@ -7,7 +7,6 @@ fn use_in_pattern() { None => {}, Some(ref opt) => {}, //~^ ref_patterns - } } @@ -15,11 +14,9 @@ fn use_in_binding() { let x = 5; let ref y = x; //~^ ref_patterns - } fn use_in_parameter(ref x: i32) {} //~^ ref_patterns - fn main() {} diff --git a/tests/ui/ref_patterns.stderr b/tests/ui/ref_patterns.stderr index bf63189a15b0..9e2d036e3483 100644 --- a/tests/ui/ref_patterns.stderr +++ b/tests/ui/ref_patterns.stderr @@ -9,7 +9,7 @@ LL | Some(ref opt) => {}, = help: to override `-D warnings` add `#[allow(clippy::ref_patterns)]` error: usage of ref pattern - --> tests/ui/ref_patterns.rs:16:9 + --> tests/ui/ref_patterns.rs:15:9 | LL | let ref y = x; | ^^^^^ @@ -17,7 +17,7 @@ LL | let ref y = x; = help: consider using `&` for clarity instead error: usage of ref pattern - --> tests/ui/ref_patterns.rs:21:21 + --> tests/ui/ref_patterns.rs:19:21 | LL | fn use_in_parameter(ref x: i32) {} | ^^^^^ diff --git a/tests/ui/repeat_vec_with_capacity.fixed b/tests/ui/repeat_vec_with_capacity.fixed index 318839db221e..5c6736a9a4ee 100644 --- a/tests/ui/repeat_vec_with_capacity.fixed +++ b/tests/ui/repeat_vec_with_capacity.fixed @@ -5,14 +5,12 @@ fn main() { { (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::>(); //~^ repeat_vec_with_capacity - } { let n = 123; (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::>(); //~^ repeat_vec_with_capacity - } { @@ -28,7 +26,6 @@ fn main() { { std::iter::repeat_with(|| Vec::<()>::with_capacity(42)); //~^ repeat_vec_with_capacity - } { diff --git a/tests/ui/repeat_vec_with_capacity.rs b/tests/ui/repeat_vec_with_capacity.rs index 0ce4658c1089..2646794822c0 100644 --- a/tests/ui/repeat_vec_with_capacity.rs +++ b/tests/ui/repeat_vec_with_capacity.rs @@ -5,14 +5,12 @@ fn main() { { vec![Vec::<()>::with_capacity(42); 123]; //~^ repeat_vec_with_capacity - } { let n = 123; vec![Vec::<()>::with_capacity(42); n]; //~^ repeat_vec_with_capacity - } { @@ -28,7 +26,6 @@ fn main() { { std::iter::repeat(Vec::<()>::with_capacity(42)); //~^ repeat_vec_with_capacity - } { diff --git a/tests/ui/repeat_vec_with_capacity.stderr b/tests/ui/repeat_vec_with_capacity.stderr index bdfd58137b0b..43027c9cb892 100644 --- a/tests/ui/repeat_vec_with_capacity.stderr +++ b/tests/ui/repeat_vec_with_capacity.stderr @@ -13,7 +13,7 @@ LL | (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::>(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity - --> tests/ui/repeat_vec_with_capacity.rs:13:9 + --> tests/ui/repeat_vec_with_capacity.rs:12:9 | LL | vec![Vec::<()>::with_capacity(42); n]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::>(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity - --> tests/ui/repeat_vec_with_capacity.rs:29:9 + --> tests/ui/repeat_vec_with_capacity.rs:27:9 | LL | std::iter::repeat(Vec::<()>::with_capacity(42)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repl_uninit.rs b/tests/ui/repl_uninit.rs index f9887eedcf46..e9469d4c5e2f 100644 --- a/tests/ui/repl_uninit.rs +++ b/tests/ui/repl_uninit.rs @@ -15,7 +15,6 @@ fn main() { let taken_v = mem::replace(&mut v, mem::uninitialized()); //~^ mem_replace_with_uninit - let new_v = might_panic(taken_v); std::mem::forget(mem::replace(&mut v, new_v)); } diff --git a/tests/ui/repl_uninit.stderr b/tests/ui/repl_uninit.stderr index 6e314d0dd166..08b0b265942d 100644 --- a/tests/ui/repl_uninit.stderr +++ b/tests/ui/repl_uninit.stderr @@ -8,13 +8,13 @@ LL | let taken_v = mem::replace(&mut v, mem::uninitialized()); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_uninit)]` error: replacing with `mem::MaybeUninit::uninit().assume_init()` - --> tests/ui/repl_uninit.rs:24:23 + --> tests/ui/repl_uninit.rs:23:23 | LL | let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)` error: replacing with `mem::zeroed()` - --> tests/ui/repl_uninit.rs:32:23 + --> tests/ui/repl_uninit.rs:31:23 | LL | let taken_v = mem::replace(&mut v, mem::zeroed()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | let taken_v = mem::replace(&mut v, mem::zeroed()); = help: consider using a default value or the `take_mut` crate instead error: replacing with `mem::uninitialized()` - --> tests/ui/repl_uninit.rs:46:28 + --> tests/ui/repl_uninit.rs:45:28 | LL | let taken_u = unsafe { mem::replace(uref, mem::uninitialized()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(uref)` diff --git a/tests/ui/repr_packed_without_abi.rs b/tests/ui/repr_packed_without_abi.rs index 4f51d4b9aec6..c5f1852e98b8 100644 --- a/tests/ui/repr_packed_without_abi.rs +++ b/tests/ui/repr_packed_without_abi.rs @@ -2,14 +2,14 @@ #[repr(packed)] struct NetworkPacketHeader { -//~^ repr_packed_without_abi + //~^ repr_packed_without_abi header_length: u8, header_version: u16, } #[repr(packed)] union Foo { -//~^ repr_packed_without_abi + //~^ repr_packed_without_abi a: u8, b: u16, } diff --git a/tests/ui/rest_pat_in_fully_bound_structs.rs b/tests/ui/rest_pat_in_fully_bound_structs.rs index fd6cf0d1ce1f..bede01688972 100644 --- a/tests/ui/rest_pat_in_fully_bound_structs.rs +++ b/tests/ui/rest_pat_in_fully_bound_structs.rs @@ -22,10 +22,8 @@ fn main() { match a_struct { A { a: 5, b: 42, c: "", .. } => {}, // Lint //~^ rest_pat_in_fully_bound_structs - A { a: 0, b: 0, c: "", .. } => {}, // Lint //~^ rest_pat_in_fully_bound_structs - _ => {}, } @@ -33,7 +31,6 @@ fn main() { A { a: 5, b: 42, .. } => {}, A { a: 0, b: 0, c: "", .. } => {}, // Lint //~^ rest_pat_in_fully_bound_structs - _ => {}, } diff --git a/tests/ui/rest_pat_in_fully_bound_structs.stderr b/tests/ui/rest_pat_in_fully_bound_structs.stderr index 72cf778ca64c..d048933ddb7b 100644 --- a/tests/ui/rest_pat_in_fully_bound_structs.stderr +++ b/tests/ui/rest_pat_in_fully_bound_structs.stderr @@ -9,7 +9,7 @@ LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint = help: to override `-D warnings` add `#[allow(clippy::rest_pat_in_fully_bound_structs)]` error: unnecessary use of `..` pattern in struct binding. All fields were already bound - --> tests/ui/rest_pat_in_fully_bound_structs.rs:26:9 + --> tests/ui/rest_pat_in_fully_bound_structs.rs:25:9 | LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint = help: consider removing `..` from this binding error: unnecessary use of `..` pattern in struct binding. All fields were already bound - --> tests/ui/rest_pat_in_fully_bound_structs.rs:34:9 + --> tests/ui/rest_pat_in_fully_bound_structs.rs:32:9 | LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/result_filter_map.rs b/tests/ui/result_filter_map.rs index f5e0a9da9ea5..ebd9c4288e3b 100644 --- a/tests/ui/result_filter_map.rs +++ b/tests/ui/result_filter_map.rs @@ -12,14 +12,12 @@ fn main() { .into_iter() .filter(Result::is_ok) //~^ result_filter_map - .map(Result::unwrap); let _ = vec![Ok(1) as Result] .into_iter() .filter(|o| o.is_ok()) //~^ result_filter_map - .map(|o| o.unwrap()); let _ = vec![1] @@ -27,13 +25,11 @@ fn main() { .map(odds_out) .filter(Result::is_ok) //~^ result_filter_map - .map(Result::unwrap); let _ = vec![1] .into_iter() .map(odds_out) .filter(|o| o.is_ok()) //~^ result_filter_map - .map(|o| o.unwrap()); } diff --git a/tests/ui/result_filter_map.stderr b/tests/ui/result_filter_map.stderr index f3ff5173c171..12eb7083b5a8 100644 --- a/tests/ui/result_filter_map.stderr +++ b/tests/ui/result_filter_map.stderr @@ -3,7 +3,7 @@ error: `filter` for `Ok` followed by `unwrap` | LL | .filter(Result::is_ok) | __________^ -... | +LL | | LL | | .map(Result::unwrap); | |____________________________^ help: consider using `flatten` instead: `flatten()` | @@ -11,29 +11,29 @@ LL | | .map(Result::unwrap); = help: to override `-D warnings` add `#[allow(clippy::result_filter_map)]` error: `filter` for `Ok` followed by `unwrap` - --> tests/ui/result_filter_map.rs:20:10 + --> tests/ui/result_filter_map.rs:19:10 | LL | .filter(|o| o.is_ok()) | __________^ -... | +LL | | LL | | .map(|o| o.unwrap()); | |____________________________^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Ok` followed by `unwrap` - --> tests/ui/result_filter_map.rs:28:10 + --> tests/ui/result_filter_map.rs:26:10 | LL | .filter(Result::is_ok) | __________^ -... | +LL | | LL | | .map(Result::unwrap); | |____________________________^ help: consider using `flatten` instead: `flatten()` error: `filter` for `Ok` followed by `unwrap` - --> tests/ui/result_filter_map.rs:35:10 + --> tests/ui/result_filter_map.rs:32:10 | LL | .filter(|o| o.is_ok()) | __________^ -... | +LL | | LL | | .map(|o| o.unwrap()); | |____________________________^ help: consider using `flatten` instead: `flatten()` diff --git a/tests/ui/result_large_err.rs b/tests/ui/result_large_err.rs index bdcf40a99ab9..fa57b3f553fc 100644 --- a/tests/ui/result_large_err.rs +++ b/tests/ui/result_large_err.rs @@ -8,7 +8,7 @@ pub fn small_err() -> Result<(), u128> { } pub fn large_err() -> Result<(), [u8; 512]> { -//~^ result_large_err + //~^ result_large_err Ok(()) } @@ -21,21 +21,21 @@ pub struct FullyDefinedLargeError { impl FullyDefinedLargeError { pub fn ret() -> Result<(), Self> { - //~^ result_large_err + //~^ result_large_err Ok(()) } } pub fn struct_error() -> Result<(), FullyDefinedLargeError> { -//~^ result_large_err + //~^ result_large_err Ok(()) } type Fdlr = std::result::Result; pub fn large_err_via_type_alias(x: T) -> Fdlr { -//~^ result_large_err + //~^ result_large_err Ok(x) } @@ -45,7 +45,7 @@ pub fn param_small_error() -> Result<(), (R, u128)> { } pub fn param_large_error() -> Result<(), (u128, R, FullyDefinedLargeError)> { -//~^ result_large_err + //~^ result_large_err Ok(()) } @@ -58,7 +58,7 @@ pub enum LargeErrorVariants { impl LargeErrorVariants<()> { pub fn large_enum_error() -> Result<(), Self> { - //~^ result_large_err + //~^ result_large_err Ok(()) } @@ -72,7 +72,7 @@ enum MultipleLargeVariants { impl MultipleLargeVariants { fn large_enum_error() -> Result<(), Self> { - //~^ result_large_err + //~^ result_large_err Ok(()) } @@ -80,7 +80,7 @@ impl MultipleLargeVariants { trait TraitForcesLargeError { fn large_error() -> Result<(), [u8; 512]> { - //~^ result_large_err + //~^ result_large_err Ok(()) } @@ -101,7 +101,7 @@ pub union FullyDefinedUnionError { } pub fn large_union_err() -> Result<(), FullyDefinedUnionError> { -//~^ result_large_err + //~^ result_large_err Ok(()) } @@ -112,7 +112,7 @@ pub union UnionError { } pub fn param_large_union() -> Result<(), UnionError> { -//~^ result_large_err + //~^ result_large_err Ok(()) } @@ -123,13 +123,13 @@ pub struct ArrayError { } pub fn array_error_subst() -> Result<(), ArrayError> { -//~^ result_large_err + //~^ result_large_err Ok(()) } pub fn array_error() -> Result<(), ArrayError<(i32, T), U>> { -//~^ result_large_err + //~^ result_large_err Ok(()) } diff --git a/tests/ui/result_map_or_into_option.fixed b/tests/ui/result_map_or_into_option.fixed index 47ba2b03bfc4..4cf218b84642 100644 --- a/tests/ui/result_map_or_into_option.fixed +++ b/tests/ui/result_map_or_into_option.fixed @@ -12,7 +12,6 @@ fn main() { let _ = opt.ok(); //~^ result_map_or_into_option - let rewrap = |s: u32| -> Option { Some(s) }; // A non-Some `f` arg should not emit the lint diff --git a/tests/ui/result_map_or_into_option.rs b/tests/ui/result_map_or_into_option.rs index 3c6b2f0e836f..9a0bde8569e8 100644 --- a/tests/ui/result_map_or_into_option.rs +++ b/tests/ui/result_map_or_into_option.rs @@ -12,7 +12,6 @@ fn main() { let _ = opt.map_or_else(|_| { None }, Some); //~^ result_map_or_into_option - let rewrap = |s: u32| -> Option { Some(s) }; // A non-Some `f` arg should not emit the lint diff --git a/tests/ui/result_unit_error.rs b/tests/ui/result_unit_error.rs index a6cf36bff913..ddbe0eb556c8 100644 --- a/tests/ui/result_unit_error.rs +++ b/tests/ui/result_unit_error.rs @@ -1,7 +1,7 @@ #![warn(clippy::result_unit_err)] pub fn returns_unit_error() -> Result { -//~^ result_unit_err + //~^ result_unit_err Err(()) } @@ -14,9 +14,8 @@ pub trait HasUnitError { fn get_that_error(&self) -> Result; //~^ result_unit_err - fn get_this_one_too(&self) -> Result { - //~^ result_unit_err + //~^ result_unit_err Err(()) } @@ -36,7 +35,7 @@ pub struct UnitErrorHolder; impl UnitErrorHolder { pub fn unit_error(&self) -> Result { - //~^ result_unit_err + //~^ result_unit_err Ok(0) } @@ -47,7 +46,7 @@ pub mod issue_6546 { type ResInv = Result; pub fn should_lint() -> ResInv<(), usize> { - //~^ result_unit_err + //~^ result_unit_err Ok(0) } diff --git a/tests/ui/result_unit_error.stderr b/tests/ui/result_unit_error.stderr index a59271f8f72e..d6c0924d8868 100644 --- a/tests/ui/result_unit_error.stderr +++ b/tests/ui/result_unit_error.stderr @@ -17,7 +17,7 @@ LL | fn get_that_error(&self) -> Result; = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/result_unit_error.rs:18:5 + --> tests/ui/result_unit_error.rs:17:5 | LL | fn get_this_one_too(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | fn get_this_one_too(&self) -> Result { = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/result_unit_error.rs:38:5 + --> tests/ui/result_unit_error.rs:37:5 | LL | pub fn unit_error(&self) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | pub fn unit_error(&self) -> Result { = help: use a custom `Error` type instead error: this returns a `Result<_, ()>` - --> tests/ui/result_unit_error.rs:49:5 + --> tests/ui/result_unit_error.rs:48:5 | LL | pub fn should_lint() -> ResInv<(), usize> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/result_unit_error_no_std.rs b/tests/ui/result_unit_error_no_std.rs index cd2b17a52234..8a1849b8490a 100644 --- a/tests/ui/result_unit_error_no_std.rs +++ b/tests/ui/result_unit_error_no_std.rs @@ -10,7 +10,7 @@ pub fn returns_unit_error_no_lint() -> Result { #[clippy::msrv = "1.81"] pub fn returns_unit_error_lint() -> Result { -//~^ result_unit_err + //~^ result_unit_err Err(()) } diff --git a/tests/ui/return_and_then.fixed b/tests/ui/return_and_then.fixed index 732854d2b969..74efa14eeec8 100644 --- a/tests/ui/return_and_then.fixed +++ b/tests/ui/return_and_then.fixed @@ -4,9 +4,9 @@ fn main() { fn test_opt_block(opt: Option) -> Option { let n = opt?; //~^ return_and_then - let mut ret = n + 1; - ret += n; - if n > 1 { Some(ret) } else { None } + let mut ret = n + 1; + ret += n; + if n > 1 { Some(ret) } else { None } } fn test_opt_func(opt: Option) -> Option { @@ -43,7 +43,7 @@ fn main() { fn test_tmp_only() -> Option { // unused temporary: vec![1, 2, 4] let x = Some(match (vec![1, 2, 3], vec![1, 2, 4]) { - //~^ return_and_then + //~^ return_and_then (a, _) if a.len() > 1 => a, (_, b) => b, })?; diff --git a/tests/ui/return_and_then.rs b/tests/ui/return_and_then.rs index cfefee373c78..188dc57e588c 100644 --- a/tests/ui/return_and_then.rs +++ b/tests/ui/return_and_then.rs @@ -3,7 +3,7 @@ fn main() { fn test_opt_block(opt: Option) -> Option { opt.and_then(|n| { - //~^ return_and_then + //~^ return_and_then let mut ret = n + 1; ret += n; if n > 1 { Some(ret) } else { None } @@ -39,7 +39,7 @@ fn main() { fn test_tmp_only() -> Option { // unused temporary: vec![1, 2, 4] Some(match (vec![1, 2, 3], vec![1, 2, 4]) { - //~^ return_and_then + //~^ return_and_then (a, _) if a.len() > 1 => a, (_, b) => b, }) diff --git a/tests/ui/return_and_then.stderr b/tests/ui/return_and_then.stderr index ef5f7417de78..cc611c3dba67 100644 --- a/tests/ui/return_and_then.stderr +++ b/tests/ui/return_and_then.stderr @@ -15,9 +15,9 @@ help: try | LL ~ let n = opt?; LL + -LL + let mut ret = n + 1; -LL + ret += n; -LL + if n > 1 { Some(ret) } else { None } +LL + let mut ret = n + 1; +LL + ret += n; +LL + if n > 1 { Some(ret) } else { None } | error: use the question mark operator instead of an `and_then` call diff --git a/tests/ui/return_self_not_must_use.rs b/tests/ui/return_self_not_must_use.rs index 2e9a29aea0d7..83965662d15e 100644 --- a/tests/ui/return_self_not_must_use.rs +++ b/tests/ui/return_self_not_must_use.rs @@ -18,12 +18,12 @@ impl Bar { Self } pub fn foo(&self) -> Self { - //~^ return_self_not_must_use + //~^ return_self_not_must_use Self } pub fn bar(self) -> Self { - //~^ return_self_not_must_use + //~^ return_self_not_must_use self } diff --git a/tests/ui/reversed_empty_ranges_loops_fixable.fixed b/tests/ui/reversed_empty_ranges_loops_fixable.fixed index 5d7f852e4e53..55080da8a137 100644 --- a/tests/ui/reversed_empty_ranges_loops_fixable.fixed +++ b/tests/ui/reversed_empty_ranges_loops_fixable.fixed @@ -5,17 +5,17 @@ fn main() { const MAX_LEN: usize = 42; for i in (0..10).rev() { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } for i in (0..=10).rev() { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } for i in (0..MAX_LEN).rev() { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } @@ -35,18 +35,18 @@ fn main() { } for i in (0..10).rev().map(|x| x * 2) { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } // testing that the empty range lint folds constants for i in (5 + 4..10).rev() { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } for i in ((3 - 1)..(5 + 2)).rev() { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } diff --git a/tests/ui/reversed_empty_ranges_loops_fixable.rs b/tests/ui/reversed_empty_ranges_loops_fixable.rs index b65d4adb090a..e51557bc2796 100644 --- a/tests/ui/reversed_empty_ranges_loops_fixable.rs +++ b/tests/ui/reversed_empty_ranges_loops_fixable.rs @@ -5,17 +5,17 @@ fn main() { const MAX_LEN: usize = 42; for i in 10..0 { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } for i in 10..=0 { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } for i in MAX_LEN..0 { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } @@ -35,18 +35,18 @@ fn main() { } for i in (10..0).map(|x| x * 2) { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } // testing that the empty range lint folds constants for i in 10..5 + 4 { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } for i in (5 + 2)..(3 - 1) { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } diff --git a/tests/ui/reversed_empty_ranges_loops_unfixable.rs b/tests/ui/reversed_empty_ranges_loops_unfixable.rs index 4fc7fb50a9ec..00aa20d25bda 100644 --- a/tests/ui/reversed_empty_ranges_loops_unfixable.rs +++ b/tests/ui/reversed_empty_ranges_loops_unfixable.rs @@ -3,14 +3,13 @@ fn main() { for i in 5..5 { - //~^ reversed_empty_ranges - + //~^ reversed_empty_ranges println!("{}", i); } for i in (5 + 2)..(8 - 1) { - //~^ reversed_empty_ranges + //~^ reversed_empty_ranges println!("{}", i); } diff --git a/tests/ui/reversed_empty_ranges_loops_unfixable.stderr b/tests/ui/reversed_empty_ranges_loops_unfixable.stderr index b5c17aad46bc..b9e6fa04a34c 100644 --- a/tests/ui/reversed_empty_ranges_loops_unfixable.stderr +++ b/tests/ui/reversed_empty_ranges_loops_unfixable.stderr @@ -8,7 +8,7 @@ LL | for i in 5..5 { = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]` error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_loops_unfixable.rs:12:14 + --> tests/ui/reversed_empty_ranges_loops_unfixable.rs:11:14 | LL | for i in (5 + 2)..(8 - 1) { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/reversed_empty_ranges_unfixable.rs b/tests/ui/reversed_empty_ranges_unfixable.rs index 1ed35786a0da..7bf434544378 100644 --- a/tests/ui/reversed_empty_ranges_unfixable.rs +++ b/tests/ui/reversed_empty_ranges_unfixable.rs @@ -8,15 +8,12 @@ fn main() { let _ = &arr[3usize..=1usize]; //~^ reversed_empty_ranges - let _ = &arr[SOME_NUM..1]; //~^ reversed_empty_ranges - for _ in ANSWER..ANSWER {} //~^ reversed_empty_ranges - // Should not be linted, see issue #5689 let _ = (42 + 10..42 + 10).map(|x| x / 2).find(|&x| x == 21); } diff --git a/tests/ui/reversed_empty_ranges_unfixable.stderr b/tests/ui/reversed_empty_ranges_unfixable.stderr index 770d916bad66..bc2b9576c41d 100644 --- a/tests/ui/reversed_empty_ranges_unfixable.stderr +++ b/tests/ui/reversed_empty_ranges_unfixable.stderr @@ -8,13 +8,13 @@ LL | let _ = &arr[3usize..=1usize]; = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]` error: this range is reversed and using it to index a slice will panic at run-time - --> tests/ui/reversed_empty_ranges_unfixable.rs:12:18 + --> tests/ui/reversed_empty_ranges_unfixable.rs:11:18 | LL | let _ = &arr[SOME_NUM..1]; | ^^^^^^^^^^^ error: this range is empty so it will yield no values - --> tests/ui/reversed_empty_ranges_unfixable.rs:16:14 + --> tests/ui/reversed_empty_ranges_unfixable.rs:14:14 | LL | for _ in ANSWER..ANSWER {} | ^^^^^^^^^^^^^^ diff --git a/tests/ui/same_functions_in_if_condition.rs b/tests/ui/same_functions_in_if_condition.rs index 47954392178a..b7ed3aab0043 100644 --- a/tests/ui/same_functions_in_if_condition.rs +++ b/tests/ui/same_functions_in_if_condition.rs @@ -37,39 +37,33 @@ fn ifs_same_cond_fn() { if function() { } else if function() { - //~^ same_functions_in_if_condition - + //~^ same_functions_in_if_condition } if fn_arg(a) { } else if fn_arg(a) { - //~^ same_functions_in_if_condition - + //~^ same_functions_in_if_condition } if obj.method() { } else if obj.method() { - //~^ same_functions_in_if_condition - + //~^ same_functions_in_if_condition } if obj.method_arg(a) { } else if obj.method_arg(a) { - //~^ same_functions_in_if_condition - + //~^ same_functions_in_if_condition } let mut v = vec![1]; if v.pop().is_none() { } else if v.pop().is_none() { - //~^ same_functions_in_if_condition - + //~^ same_functions_in_if_condition } if v.len() == 42 { } else if v.len() == 42 { - //~^ same_functions_in_if_condition - + //~^ same_functions_in_if_condition } if v.len() == 1 { diff --git a/tests/ui/same_functions_in_if_condition.stderr b/tests/ui/same_functions_in_if_condition.stderr index 0d40c8359557..6cd4f96c13e3 100644 --- a/tests/ui/same_functions_in_if_condition.stderr +++ b/tests/ui/same_functions_in_if_condition.stderr @@ -16,61 +16,61 @@ LL | #![deny(clippy::same_functions_in_if_condition)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:45:15 + --> tests/ui/same_functions_in_if_condition.rs:44:15 | LL | } else if fn_arg(a) { | ^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:44:8 + --> tests/ui/same_functions_in_if_condition.rs:43:8 | LL | if fn_arg(a) { | ^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:51:15 + --> tests/ui/same_functions_in_if_condition.rs:49:15 | LL | } else if obj.method() { | ^^^^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:50:8 + --> tests/ui/same_functions_in_if_condition.rs:48:8 | LL | if obj.method() { | ^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:57:15 + --> tests/ui/same_functions_in_if_condition.rs:54:15 | LL | } else if obj.method_arg(a) { | ^^^^^^^^^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:56:8 + --> tests/ui/same_functions_in_if_condition.rs:53:8 | LL | if obj.method_arg(a) { | ^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:64:15 + --> tests/ui/same_functions_in_if_condition.rs:60:15 | LL | } else if v.pop().is_none() { | ^^^^^^^^^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:63:8 + --> tests/ui/same_functions_in_if_condition.rs:59:8 | LL | if v.pop().is_none() { | ^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> tests/ui/same_functions_in_if_condition.rs:70:15 + --> tests/ui/same_functions_in_if_condition.rs:65:15 | LL | } else if v.len() == 42 { | ^^^^^^^^^^^^^ | note: same as this - --> tests/ui/same_functions_in_if_condition.rs:69:8 + --> tests/ui/same_functions_in_if_condition.rs:64:8 | LL | if v.len() == 42 { | ^^^^^^^^^^^^^ diff --git a/tests/ui/same_item_push.rs b/tests/ui/same_item_push.rs index dbe9c729bc56..a08e8872a932 100644 --- a/tests/ui/same_item_push.rs +++ b/tests/ui/same_item_push.rs @@ -22,7 +22,6 @@ fn main() { for _ in 5..=20 { vec.push(item); //~^ same_item_push - } let mut vec: Vec = Vec::new(); @@ -30,21 +29,18 @@ fn main() { let item = 2; vec.push(item); //~^ same_item_push - } let mut vec: Vec = Vec::new(); for _ in 0..15 { vec.push(13); //~^ same_item_push - } let mut vec = Vec::new(); for _ in 0..20 { vec.push(VALUE); //~^ same_item_push - } let mut vec = Vec::new(); @@ -52,7 +48,6 @@ fn main() { for _ in 0..20 { vec.push(item); //~^ same_item_push - } #[clippy::msrv = "1.81"] @@ -62,7 +57,6 @@ fn main() { for _ in 0..20 { vec.push(item); //~^ same_item_push - } } diff --git a/tests/ui/same_item_push.stderr b/tests/ui/same_item_push.stderr index d2bf5069a846..e3fa4f9cbcec 100644 --- a/tests/ui/same_item_push.stderr +++ b/tests/ui/same_item_push.stderr @@ -10,7 +10,7 @@ LL | vec.push(item); = help: to override `-D warnings` add `#[allow(clippy::same_item_push)]` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:31:9 + --> tests/ui/same_item_push.rs:30:9 | LL | vec.push(item); | ^^^ @@ -19,7 +19,7 @@ LL | vec.push(item); = help: or `vec.extend(std::iter::repeat_n(item, SIZE))` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:38:9 + --> tests/ui/same_item_push.rs:36:9 | LL | vec.push(13); | ^^^ @@ -28,7 +28,7 @@ LL | vec.push(13); = help: or `vec.extend(std::iter::repeat_n(13, SIZE))` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:45:9 + --> tests/ui/same_item_push.rs:42:9 | LL | vec.push(VALUE); | ^^^ @@ -37,7 +37,7 @@ LL | vec.push(VALUE); = help: or `vec.extend(std::iter::repeat_n(VALUE, SIZE))` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:53:9 + --> tests/ui/same_item_push.rs:49:9 | LL | vec.push(item); | ^^^ @@ -46,7 +46,7 @@ LL | vec.push(item); = help: or `vec.extend(std::iter::repeat_n(item, SIZE))` error: it looks like the same item is being pushed into this `Vec` - --> tests/ui/same_item_push.rs:63:13 + --> tests/ui/same_item_push.rs:58:13 | LL | vec.push(item); | ^^^ diff --git a/tests/ui/same_name_method.rs b/tests/ui/same_name_method.rs index 398f3a7d5f91..43c664b1505f 100644 --- a/tests/ui/same_name_method.rs +++ b/tests/ui/same_name_method.rs @@ -19,7 +19,6 @@ mod should_lint { impl S { fn foo() {} //~^ same_name_method - } impl T1 for S { @@ -35,7 +34,6 @@ mod should_lint { impl S { fn clone() {} //~^ same_name_method - } } @@ -47,7 +45,6 @@ mod should_lint { impl S { fn foo() {} //~^ same_name_method - } impl T1 for S { @@ -63,7 +60,6 @@ mod should_lint { impl S { fn foo() {} //~^ same_name_method - } impl T1 for S {} @@ -78,8 +74,6 @@ mod should_lint { fn foo() {} //~^ same_name_method //~| same_name_method - - } impl T1 for S {} diff --git a/tests/ui/same_name_method.stderr b/tests/ui/same_name_method.stderr index d3bf386ea545..fefdb5c9c23d 100644 --- a/tests/ui/same_name_method.stderr +++ b/tests/ui/same_name_method.stderr @@ -5,7 +5,7 @@ LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:26:13 + --> tests/ui/same_name_method.rs:25:13 | LL | fn foo() {} | ^^^^^^^^^^^ @@ -13,62 +13,62 @@ LL | fn foo() {} = help: to override `-D warnings` add `#[allow(clippy::same_name_method)]` error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:36:13 + --> tests/ui/same_name_method.rs:35:13 | LL | fn clone() {} | ^^^^^^^^^^^^^ | note: existing `clone` defined here - --> tests/ui/same_name_method.rs:32:18 + --> tests/ui/same_name_method.rs:31:18 | LL | #[derive(Clone)] | ^^^^^ = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:48:13 + --> tests/ui/same_name_method.rs:46:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:54:13 + --> tests/ui/same_name_method.rs:51:13 | LL | fn foo() {} | ^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:64:13 + --> tests/ui/same_name_method.rs:61:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:69:9 + --> tests/ui/same_name_method.rs:65:9 | LL | impl T1 for S {} | ^^^^^^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:78:13 + --> tests/ui/same_name_method.rs:74:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:85:9 + --> tests/ui/same_name_method.rs:79:9 | LL | impl T1 for S {} | ^^^^^^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:78:13 + --> tests/ui/same_name_method.rs:74:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:87:9 + --> tests/ui/same_name_method.rs:81:9 | LL | impl T2 for S {} | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/search_is_some_fixable_none.fixed b/tests/ui/search_is_some_fixable_none.fixed index e33f32d5bdb8..8169550b0d55 100644 --- a/tests/ui/search_is_some_fixable_none.fixed +++ b/tests/ui/search_is_some_fixable_none.fixed @@ -105,7 +105,7 @@ mod issue7392 { let vfoo = vec![(42, Foo { foo: 1, bar: 2 })]; let _ = !vfoo - //~^ search_is_some + //~^ search_is_some .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2); } @@ -174,7 +174,7 @@ mod issue7392 { }, }]; let _ = !vfoo - //~^ search_is_some + //~^ search_is_some .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2); } diff --git a/tests/ui/search_is_some_fixable_none.rs b/tests/ui/search_is_some_fixable_none.rs index 86885c7d3be3..5935f0dd7e29 100644 --- a/tests/ui/search_is_some_fixable_none.rs +++ b/tests/ui/search_is_some_fixable_none.rs @@ -23,7 +23,7 @@ fn main() { let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none(); //~^ search_is_some let _ = (1..3) - //~^ search_is_some + //~^ search_is_some .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1) .is_none(); @@ -108,7 +108,7 @@ mod issue7392 { let vfoo = vec![(42, Foo { foo: 1, bar: 2 })]; let _ = vfoo - //~^ search_is_some + //~^ search_is_some .iter() .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2) .is_none(); @@ -179,7 +179,7 @@ mod issue7392 { }, }]; let _ = vfoo - //~^ search_is_some + //~^ search_is_some .iter() .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2) .is_none(); diff --git a/tests/ui/self_assignment.rs b/tests/ui/self_assignment.rs index a12a2829ba1a..6e82b42cf6d7 100644 --- a/tests/ui/self_assignment.rs +++ b/tests/ui/self_assignment.rs @@ -13,7 +13,6 @@ pub fn positives(mut a: usize, b: &mut u32, mut s: S) { a = a; //~^ self_assignment - *b = *b; //~^ self_assignment @@ -38,14 +37,12 @@ pub fn positives(mut a: usize, b: &mut u32, mut s: S) { s.b[a + 10] = s.b[10 + a]; //~^ self_assignment - let mut t = (0, 1); t.1 = t.1; //~^ self_assignment t.0 = (t.0); //~^ self_assignment - } pub fn negatives_not_equal(mut a: usize, b: &mut usize, mut s: S) { diff --git a/tests/ui/self_assignment.stderr b/tests/ui/self_assignment.stderr index 02c5b4195e9c..e9a2164187ce 100644 --- a/tests/ui/self_assignment.stderr +++ b/tests/ui/self_assignment.stderr @@ -8,61 +8,61 @@ LL | a = a; = help: to override `-D warnings` add `#[allow(clippy::self_assignment)]` error: self-assignment of `*b` to `*b` - --> tests/ui/self_assignment.rs:17:5 + --> tests/ui/self_assignment.rs:16:5 | LL | *b = *b; | ^^^^^^^ error: self-assignment of `s` to `s` - --> tests/ui/self_assignment.rs:20:5 + --> tests/ui/self_assignment.rs:19:5 | LL | s = s; | ^^^^^ error: self-assignment of `s.a` to `s.a` - --> tests/ui/self_assignment.rs:23:5 + --> tests/ui/self_assignment.rs:22:5 | LL | s.a = s.a; | ^^^^^^^^^ error: self-assignment of `s.b[5 + 4]` to `s.b[9]` - --> tests/ui/self_assignment.rs:26:5 + --> tests/ui/self_assignment.rs:25:5 | LL | s.b[9] = s.b[5 + 4]; | ^^^^^^^^^^^^^^^^^^^ error: self-assignment of `s.c[0][1]` to `s.c[0][1]` - --> tests/ui/self_assignment.rs:29:5 + --> tests/ui/self_assignment.rs:28:5 | LL | s.c[0][1] = s.c[0][1]; | ^^^^^^^^^^^^^^^^^^^^^ error: self-assignment of `s.b[a]` to `s.b[a]` - --> tests/ui/self_assignment.rs:32:5 + --> tests/ui/self_assignment.rs:31:5 | LL | s.b[a] = s.b[a]; | ^^^^^^^^^^^^^^^ error: self-assignment of `*s.e` to `*s.e` - --> tests/ui/self_assignment.rs:35:5 + --> tests/ui/self_assignment.rs:34:5 | LL | *s.e = *s.e; | ^^^^^^^^^^^ error: self-assignment of `s.b[10 + a]` to `s.b[a + 10]` - --> tests/ui/self_assignment.rs:38:5 + --> tests/ui/self_assignment.rs:37:5 | LL | s.b[a + 10] = s.b[10 + a]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: self-assignment of `t.1` to `t.1` - --> tests/ui/self_assignment.rs:43:5 + --> tests/ui/self_assignment.rs:41:5 | LL | t.1 = t.1; | ^^^^^^^^^ error: self-assignment of `(t.0)` to `t.0` - --> tests/ui/self_assignment.rs:46:5 + --> tests/ui/self_assignment.rs:44:5 | LL | t.0 = (t.0); | ^^^^^^^^^^^ diff --git a/tests/ui/self_named_constructors.rs b/tests/ui/self_named_constructors.rs index 3dcd20b58c9d..8b6453e0d1d7 100644 --- a/tests/ui/self_named_constructors.rs +++ b/tests/ui/self_named_constructors.rs @@ -5,8 +5,7 @@ struct ShouldNotSpawn; impl ShouldSpawn { pub fn should_spawn() -> ShouldSpawn { - //~^ self_named_constructors - + //~^ self_named_constructors ShouldSpawn } diff --git a/tests/ui/self_named_constructors.stderr b/tests/ui/self_named_constructors.stderr index 54d7fb939796..1d8b44f6bc2b 100644 --- a/tests/ui/self_named_constructors.stderr +++ b/tests/ui/self_named_constructors.stderr @@ -2,7 +2,9 @@ error: constructor `should_spawn` has the same name as the type --> tests/ui/self_named_constructors.rs:7:5 | LL | / pub fn should_spawn() -> ShouldSpawn { -... | +LL | | +LL | | +LL | | ShouldSpawn LL | | } | |_____^ | diff --git a/tests/ui/set_contains_or_insert.rs b/tests/ui/set_contains_or_insert.rs index 0e54afe91a80..575cfda139a4 100644 --- a/tests/ui/set_contains_or_insert.rs +++ b/tests/ui/set_contains_or_insert.rs @@ -10,42 +10,42 @@ fn should_warn_hashset() { let value = 5; if !set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if !set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); } if !!set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if (&set).contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); } let borrow_value = &6; if !set.contains(borrow_value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(*borrow_value); } let borrow_set = &mut set; if !borrow_set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert borrow_set.insert(value); } } @@ -84,42 +84,42 @@ fn should_warn_btreeset() { let value = 5; if !set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if !set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); } if !!set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); println!("Just a comment"); } if (&set).contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(value); } let borrow_value = &6; if !set.contains(borrow_value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert set.insert(*borrow_value); } let borrow_set = &mut set; if !borrow_set.contains(&value) { - //~^ set_contains_or_insert + //~^ set_contains_or_insert borrow_set.insert(value); } } diff --git a/tests/ui/shadow.rs b/tests/ui/shadow.rs index b44705dfc7d6..7d503a1cf6c1 100644 --- a/tests/ui/shadow.rs +++ b/tests/ui/shadow.rs @@ -49,7 +49,7 @@ fn shadow_reuse() -> Option<()> { //~^ shadow_reuse let y = 1; let y = match y { - //~^ shadow_reuse + //~^ shadow_reuse 1 => 2, _ => 3, }; @@ -77,7 +77,7 @@ fn syntax() { match Some(1) { Some(1) => {}, Some(x) => { - //~^ shadow_unrelated + //~^ shadow_unrelated let x = 1; //~^ shadow_unrelated }, @@ -88,7 +88,7 @@ fn syntax() { while let Some(x) = Some(1) {} //~^ shadow_unrelated let _ = |[x]: [u32; 1]| { - //~^ shadow_unrelated + //~^ shadow_unrelated let x = 1; //~^ shadow_unrelated }; diff --git a/tests/ui/short_circuit_statement.fixed b/tests/ui/short_circuit_statement.fixed index 672f692db51e..133d296e259c 100644 --- a/tests/ui/short_circuit_statement.fixed +++ b/tests/ui/short_circuit_statement.fixed @@ -17,7 +17,6 @@ fn main() { if !(f() || g()) { H * 2; } //~^ short_circuit_statement - macro_rules! mac { ($f:ident or $g:ident) => { $f() || $g() @@ -36,7 +35,6 @@ fn main() { if !mac!() { mac!(); } //~^ short_circuit_statement - // Do not lint if the expression comes from a macro mac!(); } diff --git a/tests/ui/short_circuit_statement.rs b/tests/ui/short_circuit_statement.rs index ca8913c8e637..4275ae64fdd6 100644 --- a/tests/ui/short_circuit_statement.rs +++ b/tests/ui/short_circuit_statement.rs @@ -17,7 +17,6 @@ fn main() { (f() || g()) || (H * 2); //~^ short_circuit_statement - macro_rules! mac { ($f:ident or $g:ident) => { $f() || $g() @@ -36,7 +35,6 @@ fn main() { mac!() || mac!(); //~^ short_circuit_statement - // Do not lint if the expression comes from a macro mac!(); } diff --git a/tests/ui/short_circuit_statement.stderr b/tests/ui/short_circuit_statement.stderr index f69f411b4885..acd28d41a33a 100644 --- a/tests/ui/short_circuit_statement.stderr +++ b/tests/ui/short_circuit_statement.stderr @@ -32,13 +32,13 @@ LL | (f() || g()) || (H * 2); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `if !(f() || g()) { H * 2; }` error: boolean short circuit operator in statement may be clearer using an explicit test - --> tests/ui/short_circuit_statement.rs:33:5 + --> tests/ui/short_circuit_statement.rs:32:5 | LL | mac!() && mac!(); | ^^^^^^^^^^^^^^^^^ help: replace it with: `if mac!() { mac!(); }` error: boolean short circuit operator in statement may be clearer using an explicit test - --> tests/ui/short_circuit_statement.rs:36:5 + --> tests/ui/short_circuit_statement.rs:35:5 | LL | mac!() || mac!(); | ^^^^^^^^^^^^^^^^^ help: replace it with: `if !mac!() { mac!(); }` diff --git a/tests/ui/should_impl_trait/method_list_1.rs b/tests/ui/should_impl_trait/method_list_1.rs index 664d8aab7568..87b3a7d2fa0c 100644 --- a/tests/ui/should_impl_trait/method_list_1.rs +++ b/tests/ui/should_impl_trait/method_list_1.rs @@ -23,91 +23,91 @@ impl T { // trait method list part 1, should lint all // ***************************************** pub fn add(self, other: T) -> T { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn as_mut(&mut self) -> &mut T { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn as_ref(&self) -> &T { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn bitand(self, rhs: T) -> T { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn bitor(self, rhs: Self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn bitxor(self, rhs: Self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn borrow(&self) -> &str { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn borrow_mut(&mut self) -> &mut str { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn clone(&self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn cmp(&self, other: &Self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn default() -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn deref(&self) -> &Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn deref_mut(&mut self) -> &mut Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn div(self, rhs: Self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn drop(&mut self) { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } diff --git a/tests/ui/should_impl_trait/method_list_2.rs b/tests/ui/should_impl_trait/method_list_2.rs index 29b96c33ce9c..f0c4d4f15cb6 100644 --- a/tests/ui/should_impl_trait/method_list_2.rs +++ b/tests/ui/should_impl_trait/method_list_2.rs @@ -24,91 +24,91 @@ impl T { // ***************************************** pub fn eq(&self, other: &Self) -> bool { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn from_iter(iter: T) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn from_str(s: &str) -> Result { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn hash(&self, state: &mut T) { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn index(&self, index: usize) -> &Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn index_mut(&mut self, index: usize) -> &mut Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn into_iter(self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn mul(self, rhs: Self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn neg(self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn next(&mut self) -> Option { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn not(self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn rem(self, rhs: Self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn shl(self, rhs: Self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn shr(self, rhs: Self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } pub fn sub(self, rhs: Self) -> Self { - //~^ should_implement_trait + //~^ should_implement_trait unimplemented!() } diff --git a/tests/ui/significant_drop_in_scrutinee.rs b/tests/ui/significant_drop_in_scrutinee.rs index db4f8867fa41..4f65a06680d6 100644 --- a/tests/ui/significant_drop_in_scrutinee.rs +++ b/tests/ui/significant_drop_in_scrutinee.rs @@ -58,7 +58,7 @@ fn should_trigger_lint_with_mutex_guard_in_match_scrutinee() { // is preserved until the end of the match, but there is no clear indication that this is the // case. match mutex.lock().unwrap().foo() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee true => { mutex.lock().unwrap().bar(); }, @@ -145,7 +145,7 @@ fn should_trigger_lint_with_wrapped_mutex() { // lifetime is not obvious. Additionally, it is not obvious from looking at the scrutinee that // the temporary contains such a type, making it potentially even more surprising. match s.lock_m().get_the_value() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee 1 => { println!("Got 1. Is it still 1?"); println!("{}", s.lock_m().get_the_value()); @@ -167,7 +167,7 @@ fn should_trigger_lint_with_double_wrapped_mutex() { // looking at the scrutinee that the temporary contains such a type, making it potentially even // more surprising. match s.lock_m_m().get_the_value() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee 1 => { println!("Got 1. Is it still 1?"); println!("{}", s.lock_m().get_the_value()); @@ -216,7 +216,7 @@ fn should_trigger_lint_for_vec() { // which have significant drops. The types with significant drops are also non-obvious when // reading the expression in the scrutinee. match counter.temp_increment().len() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee 2 => { let current_count = counter.i.load(Ordering::Relaxed); println!("Current count {}", current_count); @@ -240,7 +240,7 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { { match (mutex1.lock().unwrap().s.len(), true) { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee (3, _) => { println!("started"); mutex1.lock().unwrap().s.len(); @@ -250,7 +250,7 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { }; match (true, mutex1.lock().unwrap().s.len(), true) { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee (_, 3, _) => { println!("started"); mutex1.lock().unwrap().s.len(); @@ -261,8 +261,8 @@ fn should_trigger_lint_for_tuple_in_scrutinee() { let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() }); match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) { - //~^ significant_drop_in_scrutinee - //~| significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee + //~| significant_drop_in_scrutinee (3, _, 3) => { println!("started"); mutex1.lock().unwrap().s.len(); @@ -314,7 +314,7 @@ fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() { let mutex = Mutex::new(StateWithField { s: "state".to_owned() }); match mutex.lock().unwrap().s.len() > 1 { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee true => { mutex.lock().unwrap().s.len(); }, @@ -322,7 +322,7 @@ fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() { }; match 1 < mutex.lock().unwrap().s.len() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee true => { mutex.lock().unwrap().s.len(); }, @@ -341,8 +341,8 @@ fn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op( }); match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { - //~^ significant_drop_in_scrutinee - //~| significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee + //~| significant_drop_in_scrutinee true => { println!( "{} < {}", @@ -354,8 +354,8 @@ fn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op( }; match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { - //~^ significant_drop_in_scrutinee - //~| significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee + //~| significant_drop_in_scrutinee true => { println!( "{} >= {}", @@ -391,7 +391,7 @@ fn should_trigger_lint_for_return_from_closure_in_scrutinee() { // Should trigger lint because the temporary with a significant drop is returned from the // closure but not used directly in any match arms, so it has a potentially surprising lifetime. match get_mutex_guard().s.len() > 1 { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee true => { mutex1.lock().unwrap().s.len(); }, @@ -409,7 +409,7 @@ fn should_trigger_lint_for_return_from_match_in_scrutinee() { // significant drop is but not used directly in any match arms, so it has a potentially // surprising lifetime. match match i { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee 100 => mutex1.lock().unwrap(), _ => mutex2.lock().unwrap(), } @@ -436,7 +436,7 @@ fn should_trigger_lint_for_return_from_if_in_scrutinee() { // with a significant drop is but not used directly in any match arms, so it has a potentially // surprising lifetime. match if i > 1 { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee mutex1.lock().unwrap() } else { mutex2.lock().unwrap() @@ -491,7 +491,7 @@ fn should_trigger_lint_for_boxed_mutex_guard() { // Should trigger lint because a temporary Box holding a type with a significant drop in a match // scrutinee may have a potentially surprising lifetime. match s.lock().deref().deref() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee 0 | 1 => println!("Value was less than 2"), _ => println!("Value is {}", s.lock().deref()), }; @@ -540,28 +540,28 @@ fn should_trigger_lint_in_assign_expr() { let mut i = 100; match mutex.lock().unwrap().i = i { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee _ => { println!("{}", mutex.lock().unwrap().i); }, }; match i = mutex.lock().unwrap().i { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee _ => { println!("{}", mutex.lock().unwrap().i); }, }; match mutex.lock().unwrap().i += 1 { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee _ => { println!("{}", mutex.lock().unwrap().i); }, }; match i += mutex.lock().unwrap().i { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee _ => { println!("{}", mutex.lock().unwrap().i); }, @@ -625,7 +625,7 @@ impl ResultReturner { fn should_trigger_lint_for_non_ref_move_and_clone_suggestion() { let rwlock = RwLock::::new(ResultReturner { s: "1".to_string() }); match rwlock.read().unwrap().to_number() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee Ok(n) => println!("Converted to number: {}", n), Err(e) => println!("Could not convert {} to number", e), }; @@ -652,7 +652,7 @@ fn should_trigger_lint_without_significant_drop_in_arm() { // is preserved until the end of the match, but there is no clear indication that this is the // case. match mutex.lock().unwrap().foo() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee true => do_bar(&mutex), false => {}, }; @@ -714,7 +714,7 @@ fn should_not_trigger_for_significant_drop_ref() { } match guard.take().len() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee 0 => println!("empty"), _ => println!("not empty"), }; @@ -739,7 +739,7 @@ fn should_trigger_lint_if_and_only_if_lifetime_is_irrelevant() { // Should trigger lint even if `copy_old_lifetime()` has a lifetime, as the lifetime of // `&vec` is unrelated to the temporary with significant drop (i.e., the `MutexGuard`). for val in mutex.lock().unwrap().copy_old_lifetime() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee println!("{}", val); } @@ -778,7 +778,7 @@ fn should_not_trigger_lint_with_explicit_drop() { // Should trigger lint if there is no explicit drop. for val in [mutex.lock().unwrap()[0], 2] { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee println!("{:?}", val); } } @@ -787,7 +787,7 @@ fn should_trigger_lint_in_if_let() { let mutex = Mutex::new(vec![1]); if let Some(val) = mutex.lock().unwrap().first().copied() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee println!("{}", val); } @@ -802,7 +802,7 @@ fn should_trigger_lint_in_while_let() { let mutex = Mutex::new(vec![1]); while let Some(val) = mutex.lock().unwrap().pop() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee println!("{}", val); } } @@ -813,7 +813,7 @@ async fn foo_async(mutex: &Mutex) -> Option> { async fn should_trigger_lint_for_async(mutex: Mutex) -> i32 { match *foo_async(&mutex).await.unwrap() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee n if n < 10 => n, _ => 10, } @@ -833,7 +833,7 @@ fn should_trigger_lint_in_match_expr() { // is preserved until the end of the match, but there is no clear indication that this is the // case. let _ = match mutex.lock().unwrap().foo() { - //~^ significant_drop_in_scrutinee + //~^ significant_drop_in_scrutinee true => 0, false => 1, }; diff --git a/tests/ui/similar_names.rs b/tests/ui/similar_names.rs index a6b20b94a4a7..69b6ab6220bf 100644 --- a/tests/ui/similar_names.rs +++ b/tests/ui/similar_names.rs @@ -47,13 +47,11 @@ fn main() { let bluby: i32; //~^ similar_names - let cake: i32; let cakes: i32; let coke: i32; //~^ similar_names - match 5 { cheese @ 1 => {}, rabbit => panic!(), @@ -73,13 +71,11 @@ fn main() { let xyzeabc: i32; //~^ similar_names - let parser: i32; let parsed: i32; let parsee: i32; //~^ similar_names - let setter: i32; let getter: i32; let tx1: i32; @@ -101,7 +97,6 @@ fn foo() { apple: spring, bpple: sprang, //~^ similar_names - } = unimplemented!(); } diff --git a/tests/ui/similar_names.stderr b/tests/ui/similar_names.stderr index 36255f52e825..8d722fb8b564 100644 --- a/tests/ui/similar_names.stderr +++ b/tests/ui/similar_names.stderr @@ -13,49 +13,49 @@ LL | let blubx: i32; = help: to override `-D warnings` add `#[allow(clippy::similar_names)]` error: binding's name is too similar to existing binding - --> tests/ui/similar_names.rs:53:9 + --> tests/ui/similar_names.rs:52:9 | LL | let coke: i32; | ^^^^ | note: existing binding defined here - --> tests/ui/similar_names.rs:51:9 + --> tests/ui/similar_names.rs:50:9 | LL | let cake: i32; | ^^^^ error: binding's name is too similar to existing binding - --> tests/ui/similar_names.rs:73:9 + --> tests/ui/similar_names.rs:71:9 | LL | let xyzeabc: i32; | ^^^^^^^ | note: existing binding defined here - --> tests/ui/similar_names.rs:71:9 + --> tests/ui/similar_names.rs:69:9 | LL | let xyz1abc: i32; | ^^^^^^^ error: binding's name is too similar to existing binding - --> tests/ui/similar_names.rs:79:9 + --> tests/ui/similar_names.rs:76:9 | LL | let parsee: i32; | ^^^^^^ | note: existing binding defined here - --> tests/ui/similar_names.rs:77:9 + --> tests/ui/similar_names.rs:74:9 | LL | let parser: i32; | ^^^^^^ error: binding's name is too similar to existing binding - --> tests/ui/similar_names.rs:102:16 + --> tests/ui/similar_names.rs:98:16 | LL | bpple: sprang, | ^^^^^^ | note: existing binding defined here - --> tests/ui/similar_names.rs:101:16 + --> tests/ui/similar_names.rs:97:16 | LL | apple: spring, | ^^^^^^ diff --git a/tests/ui/single_call_fn.rs b/tests/ui/single_call_fn.rs index 0894509b73ea..c1cc4032bec9 100644 --- a/tests/ui/single_call_fn.rs +++ b/tests/ui/single_call_fn.rs @@ -34,7 +34,7 @@ fn g() { } fn c() { -//~^ single_call_fn + //~^ single_call_fn println!("really"); println!("long"); println!("function..."); diff --git a/tests/ui/single_char_lifetime_names.rs b/tests/ui/single_char_lifetime_names.rs index e6a35cfe1642..f4dcf46b0e2d 100644 --- a/tests/ui/single_char_lifetime_names.rs +++ b/tests/ui/single_char_lifetime_names.rs @@ -5,8 +5,6 @@ struct DiagnosticCtx<'a, 'b> //~^ single_char_lifetime_names //~| single_char_lifetime_names - - where 'a: 'b, { @@ -16,9 +14,8 @@ where // Only the lifetimes on the `impl`'s generics should be linted impl<'a, 'b> DiagnosticCtx<'a, 'b> { -//~^ single_char_lifetime_names -//~| single_char_lifetime_names - + //~^ single_char_lifetime_names + //~| single_char_lifetime_names fn new(source: &'a str, unit: &'b ()) -> DiagnosticCtx<'a, 'b> { Self { @@ -40,7 +37,7 @@ impl<'src, 'unit> DiagnosticCtx<'src, 'unit> { // Only 'a should be linted here fn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) { -//~^ single_char_lifetime_names + //~^ single_char_lifetime_names base.split_once(other) .map(|(left, right)| (left, Some(right))) diff --git a/tests/ui/single_char_lifetime_names.stderr b/tests/ui/single_char_lifetime_names.stderr index 010390ce15cc..834b654baa57 100644 --- a/tests/ui/single_char_lifetime_names.stderr +++ b/tests/ui/single_char_lifetime_names.stderr @@ -17,7 +17,7 @@ LL | struct DiagnosticCtx<'a, 'b> = help: use a more informative name error: single-character lifetime names are likely uninformative - --> tests/ui/single_char_lifetime_names.rs:18:6 + --> tests/ui/single_char_lifetime_names.rs:16:6 | LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> { | ^^ @@ -25,7 +25,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> { = help: use a more informative name error: single-character lifetime names are likely uninformative - --> tests/ui/single_char_lifetime_names.rs:18:10 + --> tests/ui/single_char_lifetime_names.rs:16:10 | LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> { | ^^ @@ -33,7 +33,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> { = help: use a more informative name error: single-character lifetime names are likely uninformative - --> tests/ui/single_char_lifetime_names.rs:42:15 + --> tests/ui/single_char_lifetime_names.rs:39:15 | LL | fn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) { | ^^ diff --git a/tests/ui/single_component_path_imports_nested_first.rs b/tests/ui/single_component_path_imports_nested_first.rs index b1c6e6f94e42..acfda8b3a9c8 100644 --- a/tests/ui/single_component_path_imports_nested_first.rs +++ b/tests/ui/single_component_path_imports_nested_first.rs @@ -4,8 +4,6 @@ use regex; //~^ single_component_path_imports - - use serde as edres; pub use serde; @@ -19,7 +17,6 @@ mod root_nested_use_mod { //~^ single_component_path_imports //~| single_component_path_imports - #[allow(dead_code)] fn root_nested_use_mod() {} } diff --git a/tests/ui/single_component_path_imports_nested_first.stderr b/tests/ui/single_component_path_imports_nested_first.stderr index 8df4d8404eea..6dbfd2711b4a 100644 --- a/tests/ui/single_component_path_imports_nested_first.stderr +++ b/tests/ui/single_component_path_imports_nested_first.stderr @@ -8,7 +8,7 @@ LL | use regex; = help: to override `-D warnings` add `#[allow(clippy::single_component_path_imports)]` error: this import is redundant - --> tests/ui/single_component_path_imports_nested_first.rs:18:10 + --> tests/ui/single_component_path_imports_nested_first.rs:16:10 | LL | use {regex, serde}; | ^^^^^ @@ -16,7 +16,7 @@ LL | use {regex, serde}; = help: remove this import error: this import is redundant - --> tests/ui/single_component_path_imports_nested_first.rs:18:17 + --> tests/ui/single_component_path_imports_nested_first.rs:16:17 | LL | use {regex, serde}; | ^^^^^ diff --git a/tests/ui/single_element_loop.fixed b/tests/ui/single_element_loop.fixed index eadf77f0fa50..76c3cf56c11e 100644 --- a/tests/ui/single_element_loop.fixed +++ b/tests/ui/single_element_loop.fixed @@ -7,33 +7,33 @@ fn main() { let item1 = 2; { let item = &item1; - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } { let item = &item1; - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } for item in 0..5 { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } for item in 0..5 { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } for item in 0..5 { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } for item in 0..5 { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } @@ -54,7 +54,7 @@ fn main() { // should lint (issue #10018) { let _ = 42; - //~^ single_element_loop + //~^ single_element_loop let _f = |n: u32| { for i in 0..n { if i > 10 { @@ -70,7 +70,7 @@ fn main() { { let (Ok(mut _x) | Err(mut _x)) = res_void; - //~^ single_element_loop + //~^ single_element_loop let ptr: *const bool = std::ptr::null(); } } diff --git a/tests/ui/single_element_loop.rs b/tests/ui/single_element_loop.rs index 6aa9269e56c0..2eb928397b0a 100644 --- a/tests/ui/single_element_loop.rs +++ b/tests/ui/single_element_loop.rs @@ -6,32 +6,32 @@ fn main() { let item1 = 2; for item in &[item1] { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } for item in [item1].iter() { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } for item in &[0..5] { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } for item in [0..5].iter_mut() { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } for item in [0..5] { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } for item in [0..5].into_iter() { - //~^ single_element_loop + //~^ single_element_loop dbg!(item); } @@ -51,7 +51,7 @@ fn main() { // should lint (issue #10018) for _ in [42] { - //~^ single_element_loop + //~^ single_element_loop let _f = |n: u32| { for i in 0..n { if i > 10 { @@ -66,7 +66,7 @@ fn main() { let res_void: Result = Ok(true); for (Ok(mut _x) | Err(mut _x)) in [res_void] { - //~^ single_element_loop + //~^ single_element_loop let ptr: *const bool = std::ptr::null(); } } diff --git a/tests/ui/single_option_map.rs b/tests/ui/single_option_map.rs index fd9db9165bdc..6126582f4635 100644 --- a/tests/ui/single_option_map.rs +++ b/tests/ui/single_option_map.rs @@ -6,13 +6,13 @@ static ATOM: AtomicUsize = AtomicUsize::new(42); static MAYBE_ATOMIC: Option<&AtomicUsize> = Some(&ATOM); fn h(arg: Option) -> Option { -//~^ single_option_map + //~^ single_option_map arg.map(|x| x * 2) } fn j(arg: Option) -> Option { -//~^ single_option_map + //~^ single_option_map arg.map(|x| x * 2) } @@ -22,7 +22,7 @@ fn mul_args(a: String, b: u64) -> String { } fn mul_args_opt(a: Option, b: u64) -> Option { -//~^ single_option_map + //~^ single_option_map a.map(|val| mul_args(val, b + 1)) } diff --git a/tests/ui/size_of_in_element_count/expressions.rs b/tests/ui/size_of_in_element_count/expressions.rs index 39c482af78c0..3fe4d923441d 100644 --- a/tests/ui/size_of_in_element_count/expressions.rs +++ b/tests/ui/size_of_in_element_count/expressions.rs @@ -15,17 +15,14 @@ fn main() { unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::() * SIZE) }; //~^ size_of_in_element_count - // Count expression involving nested multiplications of size_of (Should trigger the lint) unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * size_of_val(&x[0]) * 2) }; //~^ size_of_in_element_count - // Count expression involving divisions of size_of (Should trigger the lint) unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::() / 2) }; //~^ size_of_in_element_count - // Count expression involving divisions by size_of (Should not trigger the lint) unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / size_of::()) }; @@ -36,7 +33,6 @@ fn main() { unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::())) }; //~^ size_of_in_element_count - // No size_of calls (Should not trigger the lint) unsafe { copy(x.as_ptr(), y.as_mut_ptr(), SIZE) }; } diff --git a/tests/ui/size_of_in_element_count/expressions.stderr b/tests/ui/size_of_in_element_count/expressions.stderr index 8af8867e04dd..74be0d7773df 100644 --- a/tests/ui/size_of_in_element_count/expressions.stderr +++ b/tests/ui/size_of_in_element_count/expressions.stderr @@ -9,7 +9,7 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of:: = help: to override `-D warnings` add `#[allow(clippy::size_of_in_element_count)]` error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/expressions.rs:20:62 + --> tests/ui/size_of_in_element_count/expressions.rs:19:62 | LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * size_of_val(&x[0]) * 2) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * si = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/expressions.rs:25:47 + --> tests/ui/size_of_in_element_count/expressions.rs:23:47 | LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::() / 2) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::( = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/expressions.rs:36:47 + --> tests/ui/size_of_in_element_count/expressions.rs:33:47 | LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::())) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/size_of_in_element_count/functions.rs b/tests/ui/size_of_in_element_count/functions.rs index c8bb603d8165..afd12edec1ed 100644 --- a/tests/ui/size_of_in_element_count/functions.rs +++ b/tests/ui/size_of_in_element_count/functions.rs @@ -21,7 +21,6 @@ fn main() { unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; //~^ size_of_in_element_count - unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; //~^ size_of_in_element_count @@ -34,32 +33,27 @@ fn main() { unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::()) }; //~^ size_of_in_element_count - unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; //~^ size_of_in_element_count unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; //~^ size_of_in_element_count - unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::() * SIZE) }; //~^ size_of_in_element_count - slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); //~^ size_of_in_element_count slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); //~^ size_of_in_element_count - unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; //~^ size_of_in_element_count unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; //~^ size_of_in_element_count - unsafe { y.as_mut_ptr().sub(size_of::()) }; //~^ size_of_in_element_count @@ -77,5 +71,4 @@ fn main() { y.as_mut_ptr().wrapping_offset(size_of::() as isize); //~^ size_of_in_element_count - } diff --git a/tests/ui/size_of_in_element_count/functions.stderr b/tests/ui/size_of_in_element_count/functions.stderr index a05f88436a6a..f11c33167669 100644 --- a/tests/ui/size_of_in_element_count/functions.stderr +++ b/tests/ui/size_of_in_element_count/functions.stderr @@ -17,7 +17,7 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:25:49 + --> tests/ui/size_of_in_element_count/functions.rs:24:49 | LL | unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:28:64 + --> tests/ui/size_of_in_element_count/functions.rs:27:64 | LL | unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of:: tests/ui/size_of_in_element_count/functions.rs:31:51 + --> tests/ui/size_of_in_element_count/functions.rs:30:51 | LL | unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:34:66 + --> tests/ui/size_of_in_element_count/functions.rs:33:66 | LL | unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::< = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:38:47 + --> tests/ui/size_of_in_element_count/functions.rs:36:47 | LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:41:47 + --> tests/ui/size_of_in_element_count/functions.rs:39:47 | LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; | ^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:45:66 + --> tests/ui/size_of_in_element_count/functions.rs:42:66 | LL | unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::() * SIZE) }; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::< = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:49:46 + --> tests/ui/size_of_in_element_count/functions.rs:45:46 | LL | slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE); = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:52:38 + --> tests/ui/size_of_in_element_count/functions.rs:48:38 | LL | slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | slice_from_raw_parts(y.as_ptr(), size_of::() * SIZE); = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:56:49 + --> tests/ui/size_of_in_element_count/functions.rs:51:49 | LL | unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::() * SIZE) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:59:41 + --> tests/ui/size_of_in_element_count/functions.rs:54:41 | LL | unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | unsafe { from_raw_parts(y.as_ptr(), size_of::() * SIZE) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:63:33 + --> tests/ui/size_of_in_element_count/functions.rs:57:33 | LL | unsafe { y.as_mut_ptr().sub(size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | unsafe { y.as_mut_ptr().sub(size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:66:29 + --> tests/ui/size_of_in_element_count/functions.rs:60:29 | LL | y.as_ptr().wrapping_sub(size_of::()); | ^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | y.as_ptr().wrapping_sub(size_of::()); = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:69:29 + --> tests/ui/size_of_in_element_count/functions.rs:63:29 | LL | unsafe { y.as_ptr().add(size_of::()) }; | ^^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | unsafe { y.as_ptr().add(size_of::()) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:72:33 + --> tests/ui/size_of_in_element_count/functions.rs:66:33 | LL | y.as_mut_ptr().wrapping_add(size_of::()); | ^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ LL | y.as_mut_ptr().wrapping_add(size_of::()); = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:75:32 + --> tests/ui/size_of_in_element_count/functions.rs:69:32 | LL | unsafe { y.as_ptr().offset(size_of::() as isize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | unsafe { y.as_ptr().offset(size_of::() as isize) }; = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type error: found a count of bytes instead of a count of elements of `T` - --> tests/ui/size_of_in_element_count/functions.rs:78:36 + --> tests/ui/size_of_in_element_count/functions.rs:72:36 | LL | y.as_mut_ptr().wrapping_offset(size_of::() as isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/size_of_ref.rs b/tests/ui/size_of_ref.rs index 06ed216b3422..9a6a9419f681 100644 --- a/tests/ui/size_of_ref.rs +++ b/tests/ui/size_of_ref.rs @@ -15,7 +15,6 @@ fn main() { size_of_val(&y); //~^ size_of_ref - } struct S { @@ -28,6 +27,5 @@ impl S { pub fn size(&self) -> usize { std::mem::size_of_val(&self) + (std::mem::size_of::() * self.data.capacity()) //~^ size_of_ref - } } diff --git a/tests/ui/size_of_ref.stderr b/tests/ui/size_of_ref.stderr index 0dc64673940e..6ac0b0dd2f06 100644 --- a/tests/ui/size_of_ref.stderr +++ b/tests/ui/size_of_ref.stderr @@ -17,7 +17,7 @@ LL | size_of_val(&y); = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type error: argument to `std::mem::size_of_val()` is a reference to a reference - --> tests/ui/size_of_ref.rs:29:9 + --> tests/ui/size_of_ref.rs:28:9 | LL | std::mem::size_of_val(&self) + (std::mem::size_of::() * self.data.capacity()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/slow_vector_initialization.rs b/tests/ui/slow_vector_initialization.rs index 6a09d1f36a66..52f2a52fbbb8 100644 --- a/tests/ui/slow_vector_initialization.rs +++ b/tests/ui/slow_vector_initialization.rs @@ -14,7 +14,6 @@ fn extend_vector() { let mut vec1 = Vec::with_capacity(len); //~^ slow_vector_initialization - vec1.extend(repeat(0).take(len)); // Extend with len expression diff --git a/tests/ui/slow_vector_initialization.stderr b/tests/ui/slow_vector_initialization.stderr index 67a0b928618a..e83eef826472 100644 --- a/tests/ui/slow_vector_initialization.stderr +++ b/tests/ui/slow_vector_initialization.stderr @@ -11,7 +11,7 @@ LL | | vec1.extend(repeat(0).take(len)); = help: to override `-D warnings` add `#[allow(clippy::slow_vector_initialization)]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:21:20 + --> tests/ui/slow_vector_initialization.rs:20:20 | LL | let mut vec2 = Vec::with_capacity(len - 10); | ____________________^ @@ -20,7 +20,7 @@ LL | | vec2.extend(repeat(0).take(len - 10)); | |_________________________________________^ help: consider replacing this with: `vec![0; len - 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:30:20 + --> tests/ui/slow_vector_initialization.rs:29:20 | LL | let mut vec4 = Vec::with_capacity(len); | ____________________^ @@ -29,7 +29,7 @@ LL | | vec4.extend(repeat(0).take(vec4.capacity())); | |________________________________________________^ help: consider replacing this with: `vec![0; len]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:42:27 + --> tests/ui/slow_vector_initialization.rs:41:27 | LL | let mut resized_vec = Vec::with_capacity(30); | ___________________________^ @@ -38,7 +38,7 @@ LL | | resized_vec.resize(30, 0); | |_____________________________^ help: consider replacing this with: `vec![0; 30]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:47:26 + --> tests/ui/slow_vector_initialization.rs:46:26 | LL | let mut extend_vec = Vec::with_capacity(30); | __________________________^ @@ -47,7 +47,7 @@ LL | | extend_vec.extend(repeat(0).take(30)); | |_________________________________________^ help: consider replacing this with: `vec![0; 30]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:56:20 + --> tests/ui/slow_vector_initialization.rs:55:20 | LL | let mut vec1 = Vec::with_capacity(len); | ____________________^ @@ -56,7 +56,7 @@ LL | | vec1.resize(len, 0); | |_______________________^ help: consider replacing this with: `vec![0; len]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:66:20 + --> tests/ui/slow_vector_initialization.rs:65:20 | LL | let mut vec3 = Vec::with_capacity(len - 10); | ____________________^ @@ -65,7 +65,7 @@ LL | | vec3.resize(len - 10, 0); | |____________________________^ help: consider replacing this with: `vec![0; len - 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:71:20 + --> tests/ui/slow_vector_initialization.rs:70:20 | LL | let mut vec4 = Vec::with_capacity(len); | ____________________^ @@ -74,7 +74,7 @@ LL | | vec4.resize(vec4.capacity(), 0); | |___________________________________^ help: consider replacing this with: `vec![0; len]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:77:12 + --> tests/ui/slow_vector_initialization.rs:76:12 | LL | vec1 = Vec::with_capacity(10); | ____________^ @@ -83,7 +83,7 @@ LL | | vec1.resize(10, 0); | |______________________^ help: consider replacing this with: `vec![0; 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:86:20 + --> tests/ui/slow_vector_initialization.rs:85:20 | LL | let mut vec1 = Vec::new(); | ____________________^ @@ -92,7 +92,7 @@ LL | | vec1.resize(len, 0); | |_______________________^ help: consider replacing this with: `vec![0; len]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:92:20 + --> tests/ui/slow_vector_initialization.rs:91:20 | LL | let mut vec3 = Vec::new(); | ____________________^ @@ -101,7 +101,7 @@ LL | | vec3.resize(len - 10, 0); | |____________________________^ help: consider replacing this with: `vec![0; len - 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:98:12 + --> tests/ui/slow_vector_initialization.rs:97:12 | LL | vec1 = Vec::new(); | ____________^ @@ -110,7 +110,7 @@ LL | | vec1.resize(10, 0); | |______________________^ help: consider replacing this with: `vec![0; 10]` error: slow zero-filling initialization - --> tests/ui/slow_vector_initialization.rs:103:12 + --> tests/ui/slow_vector_initialization.rs:102:12 | LL | vec1 = vec![]; | ____________^ diff --git a/tests/ui/starts_ends_with.fixed b/tests/ui/starts_ends_with.fixed index 3e1ea00a341e..b4f9d5867703 100644 --- a/tests/ui/starts_ends_with.fixed +++ b/tests/ui/starts_ends_with.fixed @@ -19,32 +19,32 @@ fn starts_with() { fn chars_cmp_with_unwrap() { let s = String::from("foo"); if s.starts_with('f') { - //~^ chars_next_cmp + //~^ chars_next_cmp // s.starts_with('f') // Nothing here } if s.ends_with('o') { - //~^ chars_last_cmp + //~^ chars_last_cmp // s.ends_with('o') // Nothing here } if s.ends_with('o') { - //~^ chars_last_cmp + //~^ chars_last_cmp // s.ends_with('o') // Nothing here } if !s.starts_with('f') { - //~^ chars_next_cmp + //~^ chars_next_cmp // !s.starts_with('f') // Nothing here } if !s.ends_with('o') { - //~^ chars_last_cmp + //~^ chars_last_cmp // !s.ends_with('o') // Nothing here } if !s.ends_with('\n') { - //~^ chars_last_cmp + //~^ chars_last_cmp // !s.ends_with('o') // Nothing here } diff --git a/tests/ui/starts_ends_with.rs b/tests/ui/starts_ends_with.rs index ef7143a455f9..dae04ac4a62d 100644 --- a/tests/ui/starts_ends_with.rs +++ b/tests/ui/starts_ends_with.rs @@ -19,32 +19,32 @@ fn starts_with() { fn chars_cmp_with_unwrap() { let s = String::from("foo"); if s.chars().next().unwrap() == 'f' { - //~^ chars_next_cmp + //~^ chars_next_cmp // s.starts_with('f') // Nothing here } if s.chars().next_back().unwrap() == 'o' { - //~^ chars_last_cmp + //~^ chars_last_cmp // s.ends_with('o') // Nothing here } if s.chars().last().unwrap() == 'o' { - //~^ chars_last_cmp + //~^ chars_last_cmp // s.ends_with('o') // Nothing here } if s.chars().next().unwrap() != 'f' { - //~^ chars_next_cmp + //~^ chars_next_cmp // !s.starts_with('f') // Nothing here } if s.chars().next_back().unwrap() != 'o' { - //~^ chars_last_cmp + //~^ chars_last_cmp // !s.ends_with('o') // Nothing here } if s.chars().last().unwrap() != '\n' { - //~^ chars_last_cmp + //~^ chars_last_cmp // !s.ends_with('o') // Nothing here } diff --git a/tests/ui/str_to_string.fixed b/tests/ui/str_to_string.fixed index 4977e9c944d1..2941c4dbd33d 100644 --- a/tests/ui/str_to_string.fixed +++ b/tests/ui/str_to_string.fixed @@ -7,5 +7,4 @@ fn main() { let msg = &hello[..]; msg.to_owned(); //~^ str_to_string - } diff --git a/tests/ui/str_to_string.rs b/tests/ui/str_to_string.rs index f710761471b6..4c4d2bb18062 100644 --- a/tests/ui/str_to_string.rs +++ b/tests/ui/str_to_string.rs @@ -7,5 +7,4 @@ fn main() { let msg = &hello[..]; msg.to_string(); //~^ str_to_string - } diff --git a/tests/ui/string_slice.rs b/tests/ui/string_slice.rs index 9251b348af3f..0acc48c1f412 100644 --- a/tests/ui/string_slice.rs +++ b/tests/ui/string_slice.rs @@ -7,7 +7,6 @@ fn main() { &"Ölkanne"[1..]; //~^ string_slice - let m = "Mötörhead"; &m[2..5]; //~^ string_slice @@ -19,5 +18,4 @@ fn main() { let a = Cow::Borrowed("foo"); &a[0..3]; //~^ string_slice - } diff --git a/tests/ui/string_slice.stderr b/tests/ui/string_slice.stderr index 4932152af6b6..f99413c6dfc6 100644 --- a/tests/ui/string_slice.stderr +++ b/tests/ui/string_slice.stderr @@ -8,19 +8,19 @@ LL | &"Ölkanne"[1..]; = help: to override `-D warnings` add `#[allow(clippy::string_slice)]` error: indexing into a string may panic if the index is within a UTF-8 character - --> tests/ui/string_slice.rs:12:6 + --> tests/ui/string_slice.rs:11:6 | LL | &m[2..5]; | ^^^^^^^ error: indexing into a string may panic if the index is within a UTF-8 character - --> tests/ui/string_slice.rs:16:6 + --> tests/ui/string_slice.rs:15:6 | LL | &s[0..2]; | ^^^^^^^ error: indexing into a string may panic if the index is within a UTF-8 character - --> tests/ui/string_slice.rs:20:6 + --> tests/ui/string_slice.rs:19:6 | LL | &a[0..3]; | ^^^^^^^ diff --git a/tests/ui/string_to_string.rs b/tests/ui/string_to_string.rs index e3f5b6cf3bdc..94174e1253b8 100644 --- a/tests/ui/string_to_string.rs +++ b/tests/ui/string_to_string.rs @@ -5,5 +5,4 @@ fn main() { let mut message = String::from("Hello"); let mut v = message.to_string(); //~^ string_to_string - } diff --git a/tests/ui/struct_excessive_bools.rs b/tests/ui/struct_excessive_bools.rs index f509c3143a86..36cbc6278030 100644 --- a/tests/ui/struct_excessive_bools.rs +++ b/tests/ui/struct_excessive_bools.rs @@ -20,8 +20,7 @@ struct Foo { } struct BadFoo { -//~^ struct_excessive_bools - + //~^ struct_excessive_bools a: bool, b: bool, c: bool, @@ -38,8 +37,7 @@ struct Bar { fn main() { struct FooFoo { - //~^ struct_excessive_bools - + //~^ struct_excessive_bools a: bool, b: bool, c: bool, diff --git a/tests/ui/struct_excessive_bools.stderr b/tests/ui/struct_excessive_bools.stderr index 573af45355a6..bdf6f0b7a1da 100644 --- a/tests/ui/struct_excessive_bools.stderr +++ b/tests/ui/struct_excessive_bools.stderr @@ -3,9 +3,9 @@ error: more than 3 bools in a struct | LL | / struct BadFoo { LL | | -LL | | LL | | a: bool, -... | +LL | | b: bool, +LL | | c: bool, LL | | d: bool, LL | | } | |_^ @@ -15,13 +15,13 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::struct_excessive_bools)]` error: more than 3 bools in a struct - --> tests/ui/struct_excessive_bools.rs:40:5 + --> tests/ui/struct_excessive_bools.rs:39:5 | LL | / struct FooFoo { LL | | -LL | | LL | | a: bool, -... | +LL | | b: bool, +LL | | c: bool, LL | | d: bool, LL | | } | |_____^ diff --git a/tests/ui/suspicious_arithmetic_impl.rs b/tests/ui/suspicious_arithmetic_impl.rs index b9207b1b3f91..9798d2049c62 100644 --- a/tests/ui/suspicious_arithmetic_impl.rs +++ b/tests/ui/suspicious_arithmetic_impl.rs @@ -13,8 +13,6 @@ impl Add for Foo { fn add(self, other: Self) -> Self { Foo(self.0 - other.0) //~^ suspicious_arithmetic_impl - - } } @@ -22,8 +20,6 @@ impl AddAssign for Foo { fn add_assign(&mut self, other: Foo) { *self = *self - other; //~^ suspicious_op_assign_impl - - } } @@ -38,7 +34,6 @@ impl MulAssign for Foo { fn mul_assign(&mut self, other: Foo) { self.0 /= other.0; //~^ suspicious_op_assign_impl - } } @@ -78,7 +73,6 @@ impl Rem for Foo { fn rem(self, other: Self) -> Self { Foo(self.0 / other.0) //~^ suspicious_arithmetic_impl - } } @@ -88,7 +82,6 @@ impl BitAnd for Foo { fn bitand(self, other: Self) -> Self { Foo(self.0 | other.0) //~^ suspicious_arithmetic_impl - } } @@ -98,7 +91,6 @@ impl BitOr for Foo { fn bitor(self, other: Self) -> Self { Foo(self.0 ^ other.0) //~^ suspicious_arithmetic_impl - } } @@ -108,7 +100,6 @@ impl BitXor for Foo { fn bitxor(self, other: Self) -> Self { Foo(self.0 & other.0) //~^ suspicious_arithmetic_impl - } } @@ -118,7 +109,6 @@ impl Shl for Foo { fn shl(self, other: Self) -> Self { Foo(self.0 >> other.0) //~^ suspicious_arithmetic_impl - } } @@ -128,7 +118,6 @@ impl Shr for Foo { fn shr(self, other: Self) -> Self { Foo(self.0 << other.0) //~^ suspicious_arithmetic_impl - } } diff --git a/tests/ui/suspicious_arithmetic_impl.stderr b/tests/ui/suspicious_arithmetic_impl.stderr index a392aa16f1d4..2d8aac4db2a7 100644 --- a/tests/ui/suspicious_arithmetic_impl.stderr +++ b/tests/ui/suspicious_arithmetic_impl.stderr @@ -8,7 +8,7 @@ LL | Foo(self.0 - other.0) = help: to override `-D warnings` add `#[allow(clippy::suspicious_arithmetic_impl)]` error: suspicious use of `-` in `AddAssign` impl - --> tests/ui/suspicious_arithmetic_impl.rs:23:23 + --> tests/ui/suspicious_arithmetic_impl.rs:21:23 | LL | *self = *self - other; | ^ @@ -17,43 +17,43 @@ LL | *self = *self - other; = help: to override `-D warnings` add `#[allow(clippy::suspicious_op_assign_impl)]` error: suspicious use of `/` in `MulAssign` impl - --> tests/ui/suspicious_arithmetic_impl.rs:39:16 + --> tests/ui/suspicious_arithmetic_impl.rs:35:16 | LL | self.0 /= other.0; | ^^ error: suspicious use of `/` in `Rem` impl - --> tests/ui/suspicious_arithmetic_impl.rs:79:20 + --> tests/ui/suspicious_arithmetic_impl.rs:74:20 | LL | Foo(self.0 / other.0) | ^ error: suspicious use of `|` in `BitAnd` impl - --> tests/ui/suspicious_arithmetic_impl.rs:89:20 + --> tests/ui/suspicious_arithmetic_impl.rs:83:20 | LL | Foo(self.0 | other.0) | ^ error: suspicious use of `^` in `BitOr` impl - --> tests/ui/suspicious_arithmetic_impl.rs:99:20 + --> tests/ui/suspicious_arithmetic_impl.rs:92:20 | LL | Foo(self.0 ^ other.0) | ^ error: suspicious use of `&` in `BitXor` impl - --> tests/ui/suspicious_arithmetic_impl.rs:109:20 + --> tests/ui/suspicious_arithmetic_impl.rs:101:20 | LL | Foo(self.0 & other.0) | ^ error: suspicious use of `>>` in `Shl` impl - --> tests/ui/suspicious_arithmetic_impl.rs:119:20 + --> tests/ui/suspicious_arithmetic_impl.rs:110:20 | LL | Foo(self.0 >> other.0) | ^^ error: suspicious use of `<<` in `Shr` impl - --> tests/ui/suspicious_arithmetic_impl.rs:129:20 + --> tests/ui/suspicious_arithmetic_impl.rs:119:20 | LL | Foo(self.0 << other.0) | ^^ diff --git a/tests/ui/suspicious_command_arg_space.fixed b/tests/ui/suspicious_command_arg_space.fixed index 5ab070f88dcf..0a0d90f75e57 100644 --- a/tests/ui/suspicious_command_arg_space.fixed +++ b/tests/ui/suspicious_command_arg_space.fixed @@ -4,11 +4,9 @@ fn main() { std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); //~^ suspicious_command_arg_space - std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap(); //~^ suspicious_command_arg_space - // Things it should not warn about: std::process::Command::new("echo").arg("hello world").spawn().unwrap(); std::process::Command::new("a").arg("--fmt=%a %b %c").spawn().unwrap(); diff --git a/tests/ui/suspicious_command_arg_space.rs b/tests/ui/suspicious_command_arg_space.rs index 0017bd44dbfe..78bdfbdf0cb6 100644 --- a/tests/ui/suspicious_command_arg_space.rs +++ b/tests/ui/suspicious_command_arg_space.rs @@ -4,11 +4,9 @@ fn main() { std::process::Command::new("echo").arg("-n hello").spawn().unwrap(); //~^ suspicious_command_arg_space - std::process::Command::new("cat").arg("--number file").spawn().unwrap(); //~^ suspicious_command_arg_space - // Things it should not warn about: std::process::Command::new("echo").arg("hello world").spawn().unwrap(); std::process::Command::new("a").arg("--fmt=%a %b %c").spawn().unwrap(); diff --git a/tests/ui/suspicious_command_arg_space.stderr b/tests/ui/suspicious_command_arg_space.stderr index f4d7d79def14..6fd07d07d7be 100644 --- a/tests/ui/suspicious_command_arg_space.stderr +++ b/tests/ui/suspicious_command_arg_space.stderr @@ -12,7 +12,7 @@ LL | std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap | ~~~~ ~~~~~~~~~~~~~~~ error: single argument that looks like it should be multiple arguments - --> tests/ui/suspicious_command_arg_space.rs:8:43 + --> tests/ui/suspicious_command_arg_space.rs:7:43 | LL | std::process::Command::new("cat").arg("--number file").spawn().unwrap(); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/suspicious_doc_comments.fixed b/tests/ui/suspicious_doc_comments.fixed index 58f6ebdb4c7c..0c878afc66e1 100644 --- a/tests/ui/suspicious_doc_comments.fixed +++ b/tests/ui/suspicious_doc_comments.fixed @@ -21,8 +21,8 @@ pub mod singleline_inner_doc { pub mod multiline_outer_doc { /*! This module contains useful functions. - //~^ suspicious_doc_comments */ + //~^^ suspicious_doc_comments pub fn bar() {} } diff --git a/tests/ui/suspicious_doc_comments.rs b/tests/ui/suspicious_doc_comments.rs index 26ee028b8c57..d89fe4f1bec7 100644 --- a/tests/ui/suspicious_doc_comments.rs +++ b/tests/ui/suspicious_doc_comments.rs @@ -21,8 +21,8 @@ pub mod singleline_inner_doc { pub mod multiline_outer_doc { /**! This module contains useful functions. - //~^ suspicious_doc_comments */ + //~^^ suspicious_doc_comments pub fn bar() {} } diff --git a/tests/ui/suspicious_doc_comments.stderr b/tests/ui/suspicious_doc_comments.stderr index 8982e98b4daa..61363ff9bd20 100644 --- a/tests/ui/suspicious_doc_comments.stderr +++ b/tests/ui/suspicious_doc_comments.stderr @@ -26,14 +26,12 @@ error: this is an outer doc comment and does not apply to the parent module or c --> tests/ui/suspicious_doc_comments.rs:23:5 | LL | / /**! This module contains useful functions. -LL | | LL | | */ | |_______^ | help: use an inner doc comment to document the parent module or crate | LL ~ /*! This module contains useful functions. -LL + LL + */ | diff --git a/tests/ui/suspicious_doc_comments_unfixable.rs b/tests/ui/suspicious_doc_comments_unfixable.rs index 255c6f7237df..e526de5ca2c3 100644 --- a/tests/ui/suspicious_doc_comments_unfixable.rs +++ b/tests/ui/suspicious_doc_comments_unfixable.rs @@ -4,7 +4,6 @@ ///! a //~^ suspicious_doc_comments - ///! b /// c ///! d diff --git a/tests/ui/suspicious_doc_comments_unfixable.stderr b/tests/ui/suspicious_doc_comments_unfixable.stderr index ff4cb3358a81..234a22021df3 100644 --- a/tests/ui/suspicious_doc_comments_unfixable.stderr +++ b/tests/ui/suspicious_doc_comments_unfixable.stderr @@ -2,7 +2,9 @@ error: this is an outer doc comment and does not apply to the parent module or c --> tests/ui/suspicious_doc_comments_unfixable.rs:4:1 | LL | / ///! a -... | +LL | | +LL | | +LL | | ///! b LL | | /// c LL | | ///! d | |______^ @@ -14,14 +16,13 @@ help: use an inner doc comment to document the parent module or crate LL + //! a LL | LL | -LL | LL + //! b LL | /// c LL + //! d | error: this is an outer doc comment and does not apply to the parent module or crate - --> tests/ui/suspicious_doc_comments_unfixable.rs:13:1 + --> tests/ui/suspicious_doc_comments_unfixable.rs:12:1 | LL | / ///! a LL | | diff --git a/tests/ui/suspicious_map.rs b/tests/ui/suspicious_map.rs index 3e3035a68f49..86e48e29bb9e 100644 --- a/tests/ui/suspicious_map.rs +++ b/tests/ui/suspicious_map.rs @@ -5,11 +5,9 @@ fn main() { let _ = (0..3).map(|x| x + 2).count(); //~^ suspicious_map - let f = |x| x + 1; let _ = (0..3).map(f).count(); //~^ suspicious_map - } fn negative() { diff --git a/tests/ui/suspicious_map.stderr b/tests/ui/suspicious_map.stderr index 7c08168f0c20..769adebaede7 100644 --- a/tests/ui/suspicious_map.stderr +++ b/tests/ui/suspicious_map.stderr @@ -9,7 +9,7 @@ LL | let _ = (0..3).map(|x| x + 2).count(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]` error: this call to `map()` won't have an effect on the call to `count()` - --> tests/ui/suspicious_map.rs:10:13 + --> tests/ui/suspicious_map.rs:9:13 | LL | let _ = (0..3).map(f).count(); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/suspicious_operation_groupings.fixed b/tests/ui/suspicious_operation_groupings.fixed index 1da292130d05..37054222bd62 100644 --- a/tests/ui/suspicious_operation_groupings.fixed +++ b/tests/ui/suspicious_operation_groupings.fixed @@ -216,7 +216,7 @@ fn inside_fn_with_similar_expression(s1: &S, s2: &S, strict: bool) -> bool { fn inside_an_if_statement(s1: &mut S, s2: &S) { // There's no `s1.b` if s1.a < s2.a && s1.b < s2.b { - //~^ suspicious_operation_groupings + //~^ suspicious_operation_groupings s1.c = s2.c; } } diff --git a/tests/ui/suspicious_operation_groupings.rs b/tests/ui/suspicious_operation_groupings.rs index 25ccba182fa5..f4d1c3c70b56 100644 --- a/tests/ui/suspicious_operation_groupings.rs +++ b/tests/ui/suspicious_operation_groupings.rs @@ -216,7 +216,7 @@ fn inside_fn_with_similar_expression(s1: &S, s2: &S, strict: bool) -> bool { fn inside_an_if_statement(s1: &mut S, s2: &S) { // There's no `s1.b` if s1.a < s2.a && s1.a < s2.b { - //~^ suspicious_operation_groupings + //~^ suspicious_operation_groupings s1.c = s2.c; } } diff --git a/tests/ui/suspicious_splitn.rs b/tests/ui/suspicious_splitn.rs index d7c1dd972450..535f62c6bede 100644 --- a/tests/ui/suspicious_splitn.rs +++ b/tests/ui/suspicious_splitn.rs @@ -10,39 +10,28 @@ fn main() { let _ = "a,b".splitn(0, ','); //~^ suspicious_splitn - let _ = "a,b".rsplitn(0, ','); //~^ suspicious_splitn - let _ = "a,b".splitn(1, ','); //~^ suspicious_splitn - let _ = [0, 1, 2].splitn(0, |&x| x == 1); //~^ suspicious_splitn - let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1); //~^ suspicious_splitn - let _ = [0, 1, 2].splitn(1, |&x| x == 1); //~^ suspicious_splitn - let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1); //~^ suspicious_splitn - - const X: usize = 0; let _ = "a,b".splitn(X + 1, ','); //~^ suspicious_splitn - let _ = "a,b".splitn(X, ','); //~^ suspicious_splitn - - } diff --git a/tests/ui/suspicious_splitn.stderr b/tests/ui/suspicious_splitn.stderr index 1e1a9b22ffbd..910c905bc990 100644 --- a/tests/ui/suspicious_splitn.stderr +++ b/tests/ui/suspicious_splitn.stderr @@ -9,7 +9,7 @@ LL | let _ = "a,b".splitn(0, ','); = help: to override `-D warnings` add `#[allow(clippy::suspicious_splitn)]` error: `rsplitn` called with `0` splits - --> tests/ui/suspicious_splitn.rs:14:13 + --> tests/ui/suspicious_splitn.rs:13:13 | LL | let _ = "a,b".rsplitn(0, ','); | ^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = "a,b".rsplitn(0, ','); = note: the resulting iterator will always return `None` error: `splitn` called with `1` split - --> tests/ui/suspicious_splitn.rs:18:13 + --> tests/ui/suspicious_splitn.rs:16:13 | LL | let _ = "a,b".splitn(1, ','); | ^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = "a,b".splitn(1, ','); = note: the resulting iterator will always return the entire string followed by `None` error: `splitn` called with `0` splits - --> tests/ui/suspicious_splitn.rs:22:13 + --> tests/ui/suspicious_splitn.rs:19:13 | LL | let _ = [0, 1, 2].splitn(0, |&x| x == 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = [0, 1, 2].splitn(0, |&x| x == 1); = note: the resulting iterator will always return `None` error: `splitn_mut` called with `0` splits - --> tests/ui/suspicious_splitn.rs:26:13 + --> tests/ui/suspicious_splitn.rs:22:13 | LL | let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1); = note: the resulting iterator will always return `None` error: `splitn` called with `1` split - --> tests/ui/suspicious_splitn.rs:30:13 + --> tests/ui/suspicious_splitn.rs:25:13 | LL | let _ = [0, 1, 2].splitn(1, |&x| x == 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = [0, 1, 2].splitn(1, |&x| x == 1); = note: the resulting iterator will always return the entire slice followed by `None` error: `rsplitn_mut` called with `1` split - --> tests/ui/suspicious_splitn.rs:34:13 + --> tests/ui/suspicious_splitn.rs:28:13 | LL | let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1); = note: the resulting iterator will always return the entire slice followed by `None` error: `splitn` called with `1` split - --> tests/ui/suspicious_splitn.rs:40:13 + --> tests/ui/suspicious_splitn.rs:32:13 | LL | let _ = "a,b".splitn(X + 1, ','); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | let _ = "a,b".splitn(X + 1, ','); = note: the resulting iterator will always return the entire string followed by `None` error: `splitn` called with `0` splits - --> tests/ui/suspicious_splitn.rs:44:13 + --> tests/ui/suspicious_splitn.rs:35:13 | LL | let _ = "a,b".splitn(X, ','); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/suspicious_to_owned.rs b/tests/ui/suspicious_to_owned.rs index bde20f4116c3..2eec05ccaf4c 100644 --- a/tests/ui/suspicious_to_owned.rs +++ b/tests/ui/suspicious_to_owned.rs @@ -17,7 +17,6 @@ fn main() { let _ = cow.to_owned(); //~^ suspicious_to_owned - // we expect no lints for this let cow = Cow::Borrowed(moo); let _ = cow.into_owned(); @@ -70,8 +69,6 @@ fn main() { let _ = String::from(moo).to_owned(); //~^ implicit_clone - let _ = moos_vec.to_owned(); //~^ implicit_clone - } diff --git a/tests/ui/suspicious_to_owned.stderr b/tests/ui/suspicious_to_owned.stderr index 6c00819b4863..cc6f5b7d3a5a 100644 --- a/tests/ui/suspicious_to_owned.stderr +++ b/tests/ui/suspicious_to_owned.stderr @@ -16,7 +16,7 @@ LL | let _ = cow.clone(); | ~~~~~~~~~~~ error: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cause the Cow<'_, [char; 3]> contents to become owned - --> tests/ui/suspicious_to_owned.rs:30:13 + --> tests/ui/suspicious_to_owned.rs:29:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | let _ = cow.clone(); | ~~~~~~~~~~~ error: this `to_owned` call clones the Cow<'_, Vec> itself and does not cause the Cow<'_, Vec> contents to become owned - --> tests/ui/suspicious_to_owned.rs:42:13 + --> tests/ui/suspicious_to_owned.rs:41:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | let _ = cow.clone(); | ~~~~~~~~~~~ error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned - --> tests/ui/suspicious_to_owned.rs:54:13 + --> tests/ui/suspicious_to_owned.rs:53:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | let _ = cow.clone(); | ~~~~~~~~~~~ error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type - --> tests/ui/suspicious_to_owned.rs:70:13 + --> tests/ui/suspicious_to_owned.rs:69:13 | LL | let _ = String::from(moo).to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::from(moo).clone()` @@ -70,7 +70,7 @@ LL | let _ = String::from(moo).to_owned(); = help: to override `-D warnings` add `#[allow(clippy::implicit_clone)]` error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type - --> tests/ui/suspicious_to_owned.rs:74:13 + --> tests/ui/suspicious_to_owned.rs:72:13 | LL | let _ = moos_vec.to_owned(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `moos_vec.clone()` diff --git a/tests/ui/suspicious_xor_used_as_pow.rs b/tests/ui/suspicious_xor_used_as_pow.rs index 229ed3383329..e0290b7ce8f1 100644 --- a/tests/ui/suspicious_xor_used_as_pow.rs +++ b/tests/ui/suspicious_xor_used_as_pow.rs @@ -20,7 +20,6 @@ fn main() { let _ = 2 ^ 5; //~^ suspicious_xor_used_as_pow - let _ = 2i32 ^ 9i32; //~^ suspicious_xor_used_as_pow diff --git a/tests/ui/suspicious_xor_used_as_pow.stderr b/tests/ui/suspicious_xor_used_as_pow.stderr index 3fb3b4a34e53..d08773a8759a 100644 --- a/tests/ui/suspicious_xor_used_as_pow.stderr +++ b/tests/ui/suspicious_xor_used_as_pow.stderr @@ -12,7 +12,7 @@ LL | let _ = 2.pow(5); | ~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:24:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:23:13 | LL | let _ = 2i32 ^ 9i32; | ^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = 2i32.pow(9i32); | ~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:27:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:26:13 | LL | let _ = 2i32 ^ 2i32; | ^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = 2i32.pow(2i32); | ~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:30:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:29:13 | LL | let _ = 50i32 ^ 3i32; | ^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _ = 50i32.pow(3i32); | ~~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:33:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:32:13 | LL | let _ = 5i32 ^ 8i32; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _ = 5i32.pow(8i32); | ~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:36:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:35:13 | LL | let _ = 2i32 ^ 32i32; | ^^^^^^^^^^^^ diff --git a/tests/ui/swap_ptr_to_ref_unfixable.rs b/tests/ui/swap_ptr_to_ref_unfixable.rs index 9fe5925214a4..9c7cf27096cc 100644 --- a/tests/ui/swap_ptr_to_ref_unfixable.rs +++ b/tests/ui/swap_ptr_to_ref_unfixable.rs @@ -14,12 +14,10 @@ fn main() { core::mem::swap(addr_of_mut_to_ref!(x), &mut *y); //~^ swap_ptr_to_ref - core::mem::swap(&mut *y, addr_of_mut_to_ref!(x)); //~^ swap_ptr_to_ref core::mem::swap(addr_of_mut_to_ref!(x), addr_of_mut_to_ref!(x)); //~^ swap_ptr_to_ref - } } diff --git a/tests/ui/swap_ptr_to_ref_unfixable.stderr b/tests/ui/swap_ptr_to_ref_unfixable.stderr index f4c7c8db15ac..3bb9d87b70a5 100644 --- a/tests/ui/swap_ptr_to_ref_unfixable.stderr +++ b/tests/ui/swap_ptr_to_ref_unfixable.stderr @@ -8,13 +8,13 @@ LL | core::mem::swap(addr_of_mut_to_ref!(x), &mut *y); = help: to override `-D warnings` add `#[allow(clippy::swap_ptr_to_ref)]` error: call to `core::mem::swap` with a parameter derived from a raw pointer - --> tests/ui/swap_ptr_to_ref_unfixable.rs:18:9 + --> tests/ui/swap_ptr_to_ref_unfixable.rs:17:9 | LL | core::mem::swap(&mut *y, addr_of_mut_to_ref!(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: call to `core::mem::swap` with a parameter derived from a raw pointer - --> tests/ui/swap_ptr_to_ref_unfixable.rs:21:9 + --> tests/ui/swap_ptr_to_ref_unfixable.rs:20:9 | LL | core::mem::swap(addr_of_mut_to_ref!(x), addr_of_mut_to_ref!(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.fixed b/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.fixed index 5e5821a140de..c96a53ba2cd1 100644 --- a/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.fixed +++ b/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.fixed @@ -4,5 +4,6 @@ use std::marker::PhantomData; pub struct Aa(PhantomData); fn aa(a: Aa) { +//~^ ERROR: expected one of } diff --git a/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.rs b/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.rs index d6e1da0e0898..a3a35eb26d10 100644 --- a/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.rs +++ b/tests/ui/syntax-error-recovery/non_expressive_names_error_recovery.rs @@ -4,5 +4,6 @@ use std::marker::PhantomData; pub struct Aa(PhantomData); fn aa(a: Aa tests/ui/temporary_assignment.rs:52:5 + --> tests/ui/temporary_assignment.rs:51:5 | LL | / MultiStruct { LL | | -LL | | LL | | structure: Struct { field: 0 }, -LL | | } -LL | | .structure +... | LL | | .field = 1; | |______________^ error: assignment to temporary - --> tests/ui/temporary_assignment.rs:59:5 + --> tests/ui/temporary_assignment.rs:57:5 | LL | ArrayStruct { array: [0] }.array[0] = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: assignment to temporary - --> tests/ui/temporary_assignment.rs:62:5 + --> tests/ui/temporary_assignment.rs:60:5 | LL | (0, 0).0 = 1; | ^^^^^^^^^^^^ diff --git a/tests/ui/test_attr_in_doctest.rs b/tests/ui/test_attr_in_doctest.rs index 8ca33c677f88..6cffd813b835 100644 --- a/tests/ui/test_attr_in_doctest.rs +++ b/tests/ui/test_attr_in_doctest.rs @@ -9,10 +9,9 @@ /// assert_eq!(1, 1); /// } /// ``` -/// +/// /// Make sure we catch multiple tests in one example, /// and show that we really parse the attr: -/// /// ``` /// #[test] //~^ test_attr_in_doctest @@ -29,24 +28,20 @@ /// "); /// } /// ``` -/// +/// /// We don't catch examples that aren't run: -/// /// ```ignore /// #[test] /// fn ignored() { todo!() } /// ``` -/// /// ```no_run /// #[test] /// fn ignored() { todo!() } /// ``` -/// /// ```compile_fail /// #[test] /// fn ignored() { Err(()) } /// ``` -/// /// ```txt /// #[test] /// fn not_even_rust() { panic!("Ouch") } diff --git a/tests/ui/test_attr_in_doctest.stderr b/tests/ui/test_attr_in_doctest.stderr index b8de466e9698..166b9b417b62 100644 --- a/tests/ui/test_attr_in_doctest.stderr +++ b/tests/ui/test_attr_in_doctest.stderr @@ -11,7 +11,7 @@ LL | | /// fn should_be_linted() { = help: to override `-D warnings` add `#[allow(clippy::test_attr_in_doctest)]` error: unit tests in doctest are not executed - --> tests/ui/test_attr_in_doctest.rs:17:5 + --> tests/ui/test_attr_in_doctest.rs:16:5 | LL | /// #[test] | _____^ @@ -20,7 +20,7 @@ LL | | /// fn should_also_be_linted() { | |____________________________^ error: unit tests in doctest are not executed - --> tests/ui/test_attr_in_doctest.rs:24:5 + --> tests/ui/test_attr_in_doctest.rs:23:5 | LL | /// #[test] | _____^ diff --git a/tests/ui/to_string_trait_impl.rs b/tests/ui/to_string_trait_impl.rs index f8195e55f9a8..646ec4db1f11 100644 --- a/tests/ui/to_string_trait_impl.rs +++ b/tests/ui/to_string_trait_impl.rs @@ -9,7 +9,7 @@ struct Point { } impl ToString for Point { -//~^ to_string_trait_impl + //~^ to_string_trait_impl fn to_string(&self) -> String { format!("({}, {})", self.x, self.y) } diff --git a/tests/ui/toplevel_ref_arg_non_rustfix.rs b/tests/ui/toplevel_ref_arg_non_rustfix.rs index 729f528a8e59..87c84a7ee14a 100644 --- a/tests/ui/toplevel_ref_arg_non_rustfix.rs +++ b/tests/ui/toplevel_ref_arg_non_rustfix.rs @@ -7,7 +7,7 @@ extern crate proc_macros; use proc_macros::{external, inline_macros}; fn the_answer(ref mut x: u8) { -//~^ toplevel_ref_arg + //~^ toplevel_ref_arg *x = 42; } diff --git a/tests/ui/trailing_empty_array.rs b/tests/ui/trailing_empty_array.rs index 2297e645c9e6..a8c3ffdb0dab 100644 --- a/tests/ui/trailing_empty_array.rs +++ b/tests/ui/trailing_empty_array.rs @@ -4,45 +4,39 @@ // Do lint: struct RarelyUseful { -//~^ trailing_empty_array - + //~^ trailing_empty_array field: i32, last: [usize; 0], } struct OnlyField { -//~^ trailing_empty_array - + //~^ trailing_empty_array first_and_last: [usize; 0], } struct GenericArrayType { -//~^ trailing_empty_array - + //~^ trailing_empty_array field: i32, last: [T; 0], } #[must_use] struct OnlyAnotherAttribute { -//~^ trailing_empty_array - + //~^ trailing_empty_array field: i32, last: [usize; 0], } #[derive(Debug)] struct OnlyADeriveAttribute { -//~^ trailing_empty_array - + //~^ trailing_empty_array field: i32, last: [usize; 0], } const ZERO: usize = 0; struct ZeroSizedWithConst { -//~^ trailing_empty_array - + //~^ trailing_empty_array field: i32, last: [usize; ZERO], } @@ -52,8 +46,7 @@ const fn compute_zero() -> usize { (4 + 6) - (2 * 5) } struct ZeroSizedWithConstFunction { -//~^ trailing_empty_array - + //~^ trailing_empty_array field: i32, last: [usize; compute_zero()], } @@ -62,8 +55,7 @@ const fn compute_zero_from_arg(x: usize) -> usize { x - 1 } struct ZeroSizedWithConstFunction2 { -//~^ trailing_empty_array - + //~^ trailing_empty_array field: i32, last: [usize; compute_zero_from_arg(1)], } @@ -71,14 +63,11 @@ struct ZeroSizedWithConstFunction2 { struct ZeroSizedArrayWrapper([usize; 0]); //~^ trailing_empty_array - struct TupleStruct(i32, [usize; 0]); //~^ trailing_empty_array - struct LotsOfFields { -//~^ trailing_empty_array - + //~^ trailing_empty_array f1: u32, f2: u32, f3: u32, diff --git a/tests/ui/trailing_empty_array.stderr b/tests/ui/trailing_empty_array.stderr index 424d23d07cdf..7ebff372cf75 100644 --- a/tests/ui/trailing_empty_array.stderr +++ b/tests/ui/trailing_empty_array.stderr @@ -3,7 +3,6 @@ error: trailing zero-sized array in a struct which is not marked with a `repr` a | LL | / struct RarelyUseful { LL | | -LL | | LL | | field: i32, LL | | last: [usize; 0], LL | | } @@ -14,11 +13,10 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::trailing_empty_array)]` error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:13:1 + --> tests/ui/trailing_empty_array.rs:12:1 | LL | / struct OnlyField { LL | | -LL | | LL | | first_and_last: [usize; 0], LL | | } | |_^ @@ -26,11 +24,10 @@ LL | | } = help: consider annotating `OnlyField` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:19:1 + --> tests/ui/trailing_empty_array.rs:17:1 | LL | / struct GenericArrayType { LL | | -LL | | LL | | field: i32, LL | | last: [T; 0], LL | | } @@ -39,11 +36,10 @@ LL | | } = help: consider annotating `GenericArrayType` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:27:1 + --> tests/ui/trailing_empty_array.rs:24:1 | LL | / struct OnlyAnotherAttribute { LL | | -LL | | LL | | field: i32, LL | | last: [usize; 0], LL | | } @@ -52,11 +48,10 @@ LL | | } = help: consider annotating `OnlyAnotherAttribute` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:35:1 + --> tests/ui/trailing_empty_array.rs:31:1 | LL | / struct OnlyADeriveAttribute { LL | | -LL | | LL | | field: i32, LL | | last: [usize; 0], LL | | } @@ -65,11 +60,10 @@ LL | | } = help: consider annotating `OnlyADeriveAttribute` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:43:1 + --> tests/ui/trailing_empty_array.rs:38:1 | LL | / struct ZeroSizedWithConst { LL | | -LL | | LL | | field: i32, LL | | last: [usize; ZERO], LL | | } @@ -78,11 +72,10 @@ LL | | } = help: consider annotating `ZeroSizedWithConst` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:54:1 + --> tests/ui/trailing_empty_array.rs:48:1 | LL | / struct ZeroSizedWithConstFunction { LL | | -LL | | LL | | field: i32, LL | | last: [usize; compute_zero()], LL | | } @@ -91,11 +84,10 @@ LL | | } = help: consider annotating `ZeroSizedWithConstFunction` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:64:1 + --> tests/ui/trailing_empty_array.rs:57:1 | LL | / struct ZeroSizedWithConstFunction2 { LL | | -LL | | LL | | field: i32, LL | | last: [usize; compute_zero_from_arg(1)], LL | | } @@ -104,7 +96,7 @@ LL | | } = help: consider annotating `ZeroSizedWithConstFunction2` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:71:1 + --> tests/ui/trailing_empty_array.rs:63:1 | LL | struct ZeroSizedArrayWrapper([usize; 0]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +104,7 @@ LL | struct ZeroSizedArrayWrapper([usize; 0]); = help: consider annotating `ZeroSizedArrayWrapper` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:75:1 + --> tests/ui/trailing_empty_array.rs:66:1 | LL | struct TupleStruct(i32, [usize; 0]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,12 +112,12 @@ LL | struct TupleStruct(i32, [usize; 0]); = help: consider annotating `TupleStruct` with `#[repr(C)]` or another `repr` attribute error: trailing zero-sized array in a struct which is not marked with a `repr` attribute - --> tests/ui/trailing_empty_array.rs:79:1 + --> tests/ui/trailing_empty_array.rs:69:1 | LL | / struct LotsOfFields { LL | | -LL | | LL | | f1: u32, +LL | | f2: u32, ... | LL | | last: [usize; 0], LL | | } diff --git a/tests/ui/trailing_zeros.fixed b/tests/ui/trailing_zeros.fixed index 273dd5d70646..8c30b062fb18 100644 --- a/tests/ui/trailing_zeros.fixed +++ b/tests/ui/trailing_zeros.fixed @@ -6,7 +6,6 @@ fn main() { let _ = x.trailing_zeros() >= 4; //~^ verbose_bit_mask - let _ = x.trailing_zeros() >= 5; //~^ verbose_bit_mask diff --git a/tests/ui/trailing_zeros.rs b/tests/ui/trailing_zeros.rs index f3fffa7be840..369a31557392 100644 --- a/tests/ui/trailing_zeros.rs +++ b/tests/ui/trailing_zeros.rs @@ -6,7 +6,6 @@ fn main() { let _ = (x & 0b1111 == 0); //~^ verbose_bit_mask - let _ = x & 0b1_1111 == 0; //~^ verbose_bit_mask diff --git a/tests/ui/trailing_zeros.stderr b/tests/ui/trailing_zeros.stderr index 4b608e32a587..6f3e7aa1d762 100644 --- a/tests/ui/trailing_zeros.stderr +++ b/tests/ui/trailing_zeros.stderr @@ -8,7 +8,7 @@ LL | let _ = (x & 0b1111 == 0); = help: to override `-D warnings` add `#[allow(clippy::verbose_bit_mask)]` error: bit mask could be simplified with a call to `trailing_zeros` - --> tests/ui/trailing_zeros.rs:10:13 + --> tests/ui/trailing_zeros.rs:9:13 | LL | let _ = x & 0b1_1111 == 0; | ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 5` diff --git a/tests/ui/trait_duplication_in_bounds.fixed b/tests/ui/trait_duplication_in_bounds.fixed index afd0f4d77d3e..666ff78b2189 100644 --- a/tests/ui/trait_duplication_in_bounds.fixed +++ b/tests/ui/trait_duplication_in_bounds.fixed @@ -5,7 +5,7 @@ use std::any::Any; fn bad_foo(arg0: T, argo1: U) { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds unimplemented!(); } @@ -41,7 +41,7 @@ trait GoodSelfWhereClause { } trait BadSelfTraitBound: Clone { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds fn f(); } @@ -49,7 +49,7 @@ trait BadSelfWhereClause { fn f() where Self: Clone; - //~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds } trait GoodTraitBound { @@ -64,7 +64,7 @@ trait GoodWhereClause { } trait BadTraitBound { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds fn f(); } @@ -106,7 +106,7 @@ fn good_generic + GenericTrait>(arg0: T) { } fn bad_generic + GenericTrait>(arg0: T) { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds unimplemented!(); } @@ -115,7 +115,7 @@ mod foo { } fn qualified_path(arg0: T) { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds unimplemented!(); } @@ -124,7 +124,7 @@ fn good_trait_object(arg0: &(dyn Any + Send)) { } fn bad_trait_object(arg0: &(dyn Any + Send)) { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds unimplemented!(); } @@ -174,14 +174,12 @@ const fn const_trait_bounds_good() {} const fn const_trait_bounds_bad() {} //~^ trait_duplication_in_bounds - fn projections() where U: ToOwned, V: ToOwned, T: IntoIterator, //~^ trait_duplication_in_bounds - V: IntoIterator + IntoIterator, { } @@ -204,6 +202,5 @@ fn assoc_const_args() where T: AssocConstTrait, //~^ trait_duplication_in_bounds - { } diff --git a/tests/ui/trait_duplication_in_bounds.rs b/tests/ui/trait_duplication_in_bounds.rs index 4d417e89bd82..a1a86fe058e6 100644 --- a/tests/ui/trait_duplication_in_bounds.rs +++ b/tests/ui/trait_duplication_in_bounds.rs @@ -5,7 +5,7 @@ use std::any::Any; fn bad_foo(arg0: T, argo1: U) { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds unimplemented!(); } @@ -41,7 +41,7 @@ trait GoodSelfWhereClause { } trait BadSelfTraitBound: Clone + Clone + Clone { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds fn f(); } @@ -49,7 +49,7 @@ trait BadSelfWhereClause { fn f() where Self: Clone + Clone + Clone; - //~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds } trait GoodTraitBound { @@ -64,7 +64,7 @@ trait GoodWhereClause { } trait BadTraitBound { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds fn f(); } @@ -106,7 +106,7 @@ fn good_generic + GenericTrait>(arg0: T) { } fn bad_generic + GenericTrait + GenericTrait>(arg0: T) { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds unimplemented!(); } @@ -115,7 +115,7 @@ mod foo { } fn qualified_path(arg0: T) { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds unimplemented!(); } @@ -124,7 +124,7 @@ fn good_trait_object(arg0: &(dyn Any + Send)) { } fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { -//~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds unimplemented!(); } @@ -174,14 +174,12 @@ const fn const_trait_bounds_good() {} const fn const_trait_bounds_bad() {} //~^ trait_duplication_in_bounds - fn projections() where U: ToOwned, V: ToOwned, T: IntoIterator + IntoIterator, //~^ trait_duplication_in_bounds - V: IntoIterator + IntoIterator, { } @@ -204,6 +202,5 @@ fn assoc_const_args() where T: AssocConstTrait + AssocConstTrait, //~^ trait_duplication_in_bounds - { } diff --git a/tests/ui/trait_duplication_in_bounds.stderr b/tests/ui/trait_duplication_in_bounds.stderr index 974dfe538799..d76b4e458480 100644 --- a/tests/ui/trait_duplication_in_bounds.stderr +++ b/tests/ui/trait_duplication_in_bounds.stderr @@ -65,13 +65,13 @@ LL | const fn const_trait_bounds_bad() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `~const ConstTrait` error: these where clauses contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:182:8 + --> tests/ui/trait_duplication_in_bounds.rs:181:8 | LL | T: IntoIterator + IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `IntoIterator` error: these where clauses contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:205:8 + --> tests/ui/trait_duplication_in_bounds.rs:203:8 | LL | T: AssocConstTrait + AssocConstTrait, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait` diff --git a/tests/ui/trait_duplication_in_bounds_unfixable.rs b/tests/ui/trait_duplication_in_bounds_unfixable.rs index 38a42c3bd365..cf72ed844a78 100644 --- a/tests/ui/trait_duplication_in_bounds_unfixable.rs +++ b/tests/ui/trait_duplication_in_bounds_unfixable.rs @@ -7,8 +7,6 @@ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; fn bad_foo(arg0: T, arg1: Z) //~^ trait_duplication_in_bounds //~| trait_duplication_in_bounds - - where T: Clone, T: Default, @@ -38,8 +36,7 @@ trait T: Default { fn f() where Self: Default; - //~^ trait_duplication_in_bounds - + //~^ trait_duplication_in_bounds } trait U: Default { @@ -54,22 +51,20 @@ trait ZZ: Default { fn f() where Self: Default + Clone; - //~^ trait_duplication_in_bounds - + //~^ trait_duplication_in_bounds } trait BadTrait: Default + Clone { fn f() where Self: Default + Clone; - //~^ trait_duplication_in_bounds - //~| trait_duplication_in_bounds - + //~^ trait_duplication_in_bounds + //~| trait_duplication_in_bounds fn g() where Self: Default; - //~^ trait_duplication_in_bounds + //~^ trait_duplication_in_bounds fn h() where @@ -107,7 +102,6 @@ trait FooIter: Iterator { where Self: Iterator, //~^ trait_duplication_in_bounds - { } } diff --git a/tests/ui/trait_duplication_in_bounds_unfixable.stderr b/tests/ui/trait_duplication_in_bounds_unfixable.stderr index c7b8ba01c493..546d39518e1f 100644 --- a/tests/ui/trait_duplication_in_bounds_unfixable.stderr +++ b/tests/ui/trait_duplication_in_bounds_unfixable.stderr @@ -20,7 +20,7 @@ LL | fn bad_foo(arg0: T, arg1: Z) = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:40:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:38:15 | LL | Self: Default; | ^^^^^^^ @@ -28,7 +28,7 @@ LL | Self: Default; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:56:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:53:15 | LL | Self: Default + Clone; | ^^^^^^^ @@ -36,7 +36,7 @@ LL | Self: Default + Clone; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:64:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:60:15 | LL | Self: Default + Clone; | ^^^^^^^ @@ -44,7 +44,7 @@ LL | Self: Default + Clone; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:64:25 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:60:25 | LL | Self: Default + Clone; | ^^^^^ @@ -52,7 +52,7 @@ LL | Self: Default + Clone; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:71:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:66:15 | LL | Self: Default; | ^^^^^^^ @@ -60,7 +60,7 @@ LL | Self: Default; = help: consider removing this trait bound error: this trait bound is already specified in trait declaration - --> tests/ui/trait_duplication_in_bounds_unfixable.rs:108:15 + --> tests/ui/trait_duplication_in_bounds_unfixable.rs:103:15 | LL | Self: Iterator, | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute.rs b/tests/ui/transmute.rs index 0fec14ffd975..3aecde398dc3 100644 --- a/tests/ui/transmute.rs +++ b/tests/ui/transmute.rs @@ -31,15 +31,11 @@ unsafe fn _generic<'a, T, U: 'a>(t: &'a T) { let _: *const T = core::mem::transmute(t); //~^ useless_transmute - - let _: *mut T = core::mem::transmute(t); //~^ useless_transmute - let _: *const U = core::mem::transmute(t); //~^ useless_transmute - } #[warn(clippy::useless_transmute)] @@ -48,33 +44,26 @@ fn useless() { let _: Vec = core::mem::transmute(my_vec()); //~^ useless_transmute - let _: Vec = core::mem::transmute(my_vec()); //~^ useless_transmute - let _: Vec = std::mem::transmute(my_vec()); //~^ useless_transmute - let _: Vec = std::mem::transmute(my_vec()); //~^ useless_transmute - let _: Vec = my_transmute(my_vec()); //~^ useless_transmute - let _: *const usize = std::mem::transmute(5_isize); //~^ useless_transmute - let _ = 5_isize as *const usize; let _: *const usize = std::mem::transmute(1 + 1usize); //~^ useless_transmute - let _ = (1 + 1_usize) as *const usize; } @@ -107,19 +96,14 @@ fn crosspointer() { let _: Usize = core::mem::transmute(int_const_ptr); //~^ crosspointer_transmute - - let _: Usize = core::mem::transmute(int_mut_ptr); //~^ crosspointer_transmute - let _: *const Usize = core::mem::transmute(my_int()); //~^ crosspointer_transmute - let _: *mut Usize = core::mem::transmute(my_int()); //~^ crosspointer_transmute - } } @@ -127,8 +111,6 @@ fn crosspointer() { fn int_to_bool() { let _: bool = unsafe { std::mem::transmute(0_u8) }; //~^ transmute_int_to_bool - - } #[warn(clippy::transmute_int_to_float)] @@ -137,7 +119,6 @@ mod int_to_float { let _: f16 = unsafe { std::mem::transmute(0_u16) }; //~^ transmute_int_to_float - let _: f16 = unsafe { std::mem::transmute(0_i16) }; //~^ transmute_int_to_float @@ -158,7 +139,6 @@ mod int_to_float { let _: f128 = unsafe { std::mem::transmute(0_i128) }; //~^ transmute_int_to_float - } mod issue_5747 { @@ -174,29 +154,24 @@ mod int_to_float { const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) }; //~^ transmute_int_to_float - const fn from_bits_16(v: i16) -> f16 { unsafe { std::mem::transmute(v) } //~^ transmute_int_to_float - } const fn from_bits_32(v: i32) -> f32 { unsafe { std::mem::transmute(v) } //~^ transmute_int_to_float - } const fn from_bits_64(v: u64) -> f64 { unsafe { std::mem::transmute(v) } //~^ transmute_int_to_float - } const fn from_bits_128(v: u128) -> f128 { unsafe { std::mem::transmute(v) } //~^ transmute_int_to_float - } } } @@ -207,7 +182,6 @@ mod num_to_bytes { let _: [u8; 1] = std::mem::transmute(0u8); //~^ transmute_num_to_bytes - let _: [u8; 4] = std::mem::transmute(0u32); //~^ transmute_num_to_bytes @@ -223,7 +197,6 @@ mod num_to_bytes { let _: [u8; 16] = std::mem::transmute(0i128); //~^ transmute_num_to_bytes - let _: [u8; 2] = std::mem::transmute(0.0f16); //~^ transmute_num_to_bytes @@ -235,7 +208,6 @@ mod num_to_bytes { let _: [u8; 16] = std::mem::transmute(0.0f128); //~^ transmute_num_to_bytes - } } const fn test_const() { @@ -258,7 +230,6 @@ mod num_to_bytes { let _: [u8; 16] = std::mem::transmute(0i128); //~^ transmute_num_to_bytes - let _: [u8; 2] = std::mem::transmute(0.0f16); //~^ transmute_num_to_bytes @@ -270,7 +241,6 @@ mod num_to_bytes { let _: [u8; 16] = std::mem::transmute(0.0f128); //~^ transmute_num_to_bytes - } } } @@ -281,13 +251,11 @@ fn bytes_to_str(mb: &mut [u8]) { let _: &str = unsafe { std::mem::transmute(B) }; //~^ transmute_bytes_to_str - let _: &mut str = unsafe { std::mem::transmute(mb) }; //~^ transmute_bytes_to_str const _: &str = unsafe { std::mem::transmute(B) }; //~^ transmute_bytes_to_str - } fn main() {} diff --git a/tests/ui/transmute.stderr b/tests/ui/transmute.stderr index 7db7fad28d80..e0d28437aafc 100644 --- a/tests/ui/transmute.stderr +++ b/tests/ui/transmute.stderr @@ -8,61 +8,61 @@ LL | let _: *const T = core::mem::transmute(t); = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]` error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:36:21 + --> tests/ui/transmute.rs:34:21 | LL | let _: *mut T = core::mem::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T` error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:40:23 + --> tests/ui/transmute.rs:37:23 | LL | let _: *const U = core::mem::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U` error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:48:27 + --> tests/ui/transmute.rs:44:27 | LL | let _: Vec = core::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:52:27 + --> tests/ui/transmute.rs:47:27 | LL | let _: Vec = core::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: transmute from a type (`std::vec::Vec`) to itself + --> tests/ui/transmute.rs:50:27 + | +LL | let _: Vec = std::mem::transmute(my_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from a type (`std::vec::Vec`) to itself + --> tests/ui/transmute.rs:53:27 + | +LL | let _: Vec = std::mem::transmute(my_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: transmute from a type (`std::vec::Vec`) to itself --> tests/ui/transmute.rs:56:27 | -LL | let _: Vec = std::mem::transmute(my_vec()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:60:27 - | -LL | let _: Vec = std::mem::transmute(my_vec()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:64:27 - | LL | let _: Vec = my_transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^ error: transmute from an integer to a pointer - --> tests/ui/transmute.rs:68:31 + --> tests/ui/transmute.rs:59:31 | LL | let _: *const usize = std::mem::transmute(5_isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize` error: transmute from an integer to a pointer - --> tests/ui/transmute.rs:74:31 + --> tests/ui/transmute.rs:64:31 | LL | let _: *const usize = std::mem::transmute(1 + 1usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize` error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`) - --> tests/ui/transmute.rs:107:24 + --> tests/ui/transmute.rs:96:24 | LL | let _: Usize = core::mem::transmute(int_const_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,25 +71,25 @@ LL | let _: Usize = core::mem::transmute(int_const_ptr); = help: to override `-D warnings` add `#[allow(clippy::crosspointer_transmute)]` error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`) - --> tests/ui/transmute.rs:112:24 + --> tests/ui/transmute.rs:99:24 | LL | let _: Usize = core::mem::transmute(int_mut_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`) - --> tests/ui/transmute.rs:116:31 + --> tests/ui/transmute.rs:102:31 | LL | let _: *const Usize = core::mem::transmute(my_int()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`) - --> tests/ui/transmute.rs:120:29 + --> tests/ui/transmute.rs:105:29 | LL | let _: *mut Usize = core::mem::transmute(my_int()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a `u8` to a `bool` - --> tests/ui/transmute.rs:128:28 + --> tests/ui/transmute.rs:112:28 | LL | let _: bool = unsafe { std::mem::transmute(0_u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0` @@ -98,7 +98,7 @@ LL | let _: bool = unsafe { std::mem::transmute(0_u8) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]` error: transmute from a `u16` to a `f16` - --> tests/ui/transmute.rs:137:31 + --> tests/ui/transmute.rs:119:31 | LL | let _: f16 = unsafe { std::mem::transmute(0_u16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)` @@ -107,97 +107,97 @@ LL | let _: f16 = unsafe { std::mem::transmute(0_u16) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_float)]` error: transmute from a `i16` to a `f16` - --> tests/ui/transmute.rs:141:31 + --> tests/ui/transmute.rs:122:31 | LL | let _: f16 = unsafe { std::mem::transmute(0_i16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_i16 as u16)` error: transmute from a `u32` to a `f32` - --> tests/ui/transmute.rs:144:31 + --> tests/ui/transmute.rs:125:31 | LL | let _: f32 = unsafe { std::mem::transmute(0_u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` error: transmute from a `i32` to a `f32` - --> tests/ui/transmute.rs:147:31 + --> tests/ui/transmute.rs:128:31 | LL | let _: f32 = unsafe { std::mem::transmute(0_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)` error: transmute from a `u64` to a `f64` - --> tests/ui/transmute.rs:150:31 + --> tests/ui/transmute.rs:131:31 | LL | let _: f64 = unsafe { std::mem::transmute(0_u64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)` error: transmute from a `i64` to a `f64` - --> tests/ui/transmute.rs:153:31 + --> tests/ui/transmute.rs:134:31 | LL | let _: f64 = unsafe { std::mem::transmute(0_i64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)` error: transmute from a `u128` to a `f128` - --> tests/ui/transmute.rs:156:32 + --> tests/ui/transmute.rs:137:32 | LL | let _: f128 = unsafe { std::mem::transmute(0_u128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_u128)` error: transmute from a `i128` to a `f128` - --> tests/ui/transmute.rs:159:32 + --> tests/ui/transmute.rs:140:32 | LL | let _: f128 = unsafe { std::mem::transmute(0_i128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` error: transmute from a `u16` to a `f16` - --> tests/ui/transmute.rs:165:39 + --> tests/ui/transmute.rs:145:39 | LL | const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)` error: transmute from a `u32` to a `f32` - --> tests/ui/transmute.rs:168:39 + --> tests/ui/transmute.rs:148:39 | LL | const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` error: transmute from a `i64` to a `f64` - --> tests/ui/transmute.rs:171:39 + --> tests/ui/transmute.rs:151:39 | LL | const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)` error: transmute from a `i128` to a `f128` - --> tests/ui/transmute.rs:174:41 + --> tests/ui/transmute.rs:154:41 | LL | const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` error: transmute from a `i16` to a `f16` - --> tests/ui/transmute.rs:179:22 + --> tests/ui/transmute.rs:158:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(v as u16)` error: transmute from a `i32` to a `f32` - --> tests/ui/transmute.rs:185:22 + --> tests/ui/transmute.rs:163:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(v as u32)` error: transmute from a `u64` to a `f64` - --> tests/ui/transmute.rs:191:22 + --> tests/ui/transmute.rs:168:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(v)` error: transmute from a `u128` to a `f128` - --> tests/ui/transmute.rs:197:22 + --> tests/ui/transmute.rs:173:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(v)` error: transmute from a `u8` to a `[u8; 1]` - --> tests/ui/transmute.rs:207:30 + --> tests/ui/transmute.rs:182:30 | LL | let _: [u8; 1] = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` @@ -206,121 +206,121 @@ LL | let _: [u8; 1] = std::mem::transmute(0u8); = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]` error: transmute from a `u32` to a `[u8; 4]` - --> tests/ui/transmute.rs:211:30 + --> tests/ui/transmute.rs:185:30 | LL | let _: [u8; 4] = std::mem::transmute(0u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` error: transmute from a `u128` to a `[u8; 16]` - --> tests/ui/transmute.rs:214:31 + --> tests/ui/transmute.rs:188:31 | LL | let _: [u8; 16] = std::mem::transmute(0u128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` error: transmute from a `i8` to a `[u8; 1]` - --> tests/ui/transmute.rs:217:30 + --> tests/ui/transmute.rs:191:30 | LL | let _: [u8; 1] = std::mem::transmute(0i8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` error: transmute from a `i32` to a `[u8; 4]` - --> tests/ui/transmute.rs:220:30 + --> tests/ui/transmute.rs:194:30 | LL | let _: [u8; 4] = std::mem::transmute(0i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` error: transmute from a `i128` to a `[u8; 16]` - --> tests/ui/transmute.rs:223:31 + --> tests/ui/transmute.rs:197:31 | LL | let _: [u8; 16] = std::mem::transmute(0i128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` error: transmute from a `f16` to a `[u8; 2]` - --> tests/ui/transmute.rs:227:30 + --> tests/ui/transmute.rs:200:30 | LL | let _: [u8; 2] = std::mem::transmute(0.0f16); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` error: transmute from a `f32` to a `[u8; 4]` - --> tests/ui/transmute.rs:230:30 + --> tests/ui/transmute.rs:203:30 | LL | let _: [u8; 4] = std::mem::transmute(0.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` error: transmute from a `f64` to a `[u8; 8]` - --> tests/ui/transmute.rs:233:30 + --> tests/ui/transmute.rs:206:30 | LL | let _: [u8; 8] = std::mem::transmute(0.0f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` error: transmute from a `f128` to a `[u8; 16]` - --> tests/ui/transmute.rs:236:31 + --> tests/ui/transmute.rs:209:31 | LL | let _: [u8; 16] = std::mem::transmute(0.0f128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` error: transmute from a `u8` to a `[u8; 1]` - --> tests/ui/transmute.rs:243:30 + --> tests/ui/transmute.rs:215:30 | LL | let _: [u8; 1] = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` error: transmute from a `u32` to a `[u8; 4]` - --> tests/ui/transmute.rs:246:30 + --> tests/ui/transmute.rs:218:30 | LL | let _: [u8; 4] = std::mem::transmute(0u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` error: transmute from a `u128` to a `[u8; 16]` - --> tests/ui/transmute.rs:249:31 + --> tests/ui/transmute.rs:221:31 | LL | let _: [u8; 16] = std::mem::transmute(0u128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` error: transmute from a `i8` to a `[u8; 1]` - --> tests/ui/transmute.rs:252:30 + --> tests/ui/transmute.rs:224:30 | LL | let _: [u8; 1] = std::mem::transmute(0i8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` error: transmute from a `i32` to a `[u8; 4]` - --> tests/ui/transmute.rs:255:30 + --> tests/ui/transmute.rs:227:30 | LL | let _: [u8; 4] = std::mem::transmute(0i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` error: transmute from a `i128` to a `[u8; 16]` - --> tests/ui/transmute.rs:258:31 + --> tests/ui/transmute.rs:230:31 | LL | let _: [u8; 16] = std::mem::transmute(0i128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` error: transmute from a `f16` to a `[u8; 2]` - --> tests/ui/transmute.rs:262:30 + --> tests/ui/transmute.rs:233:30 | LL | let _: [u8; 2] = std::mem::transmute(0.0f16); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` error: transmute from a `f32` to a `[u8; 4]` - --> tests/ui/transmute.rs:265:30 + --> tests/ui/transmute.rs:236:30 | LL | let _: [u8; 4] = std::mem::transmute(0.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` error: transmute from a `f64` to a `[u8; 8]` - --> tests/ui/transmute.rs:268:30 + --> tests/ui/transmute.rs:239:30 | LL | let _: [u8; 8] = std::mem::transmute(0.0f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` error: transmute from a `f128` to a `[u8; 16]` - --> tests/ui/transmute.rs:271:31 + --> tests/ui/transmute.rs:242:31 | LL | let _: [u8; 16] = std::mem::transmute(0.0f128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` error: transmute from a `&[u8]` to a `&str` - --> tests/ui/transmute.rs:281:28 + --> tests/ui/transmute.rs:251:28 | LL | let _: &str = unsafe { std::mem::transmute(B) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()` @@ -329,13 +329,13 @@ LL | let _: &str = unsafe { std::mem::transmute(B) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]` error: transmute from a `&mut [u8]` to a `&mut str` - --> tests/ui/transmute.rs:285:32 + --> tests/ui/transmute.rs:254:32 | LL | let _: &mut str = unsafe { std::mem::transmute(mb) }; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()` error: transmute from a `&[u8]` to a `&str` - --> tests/ui/transmute.rs:288:30 + --> tests/ui/transmute.rs:257:30 | LL | const _: &str = unsafe { std::mem::transmute(B) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)` diff --git a/tests/ui/transmute_64bit.rs b/tests/ui/transmute_64bit.rs index 9570fa5ab093..1a4bfffdc322 100644 --- a/tests/ui/transmute_64bit.rs +++ b/tests/ui/transmute_64bit.rs @@ -6,10 +6,7 @@ fn main() { let _: *const usize = std::mem::transmute(6.0f64); //~^ wrong_transmute - - let _: *mut usize = std::mem::transmute(6.0f64); //~^ wrong_transmute - } } diff --git a/tests/ui/transmute_64bit.stderr b/tests/ui/transmute_64bit.stderr index 789eba5247fa..e75b81671e09 100644 --- a/tests/ui/transmute_64bit.stderr +++ b/tests/ui/transmute_64bit.stderr @@ -8,7 +8,7 @@ LL | let _: *const usize = std::mem::transmute(6.0f64); = help: to override `-D warnings` add `#[allow(clippy::wrong_transmute)]` error: transmute from a `f64` to a pointer - --> tests/ui/transmute_64bit.rs:11:29 + --> tests/ui/transmute_64bit.rs:9:29 | LL | let _: *mut usize = std::mem::transmute(6.0f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute_collection.rs b/tests/ui/transmute_collection.rs index 20952dfa2839..74d7f5e38bf8 100644 --- a/tests/ui/transmute_collection.rs +++ b/tests/ui/transmute_collection.rs @@ -10,12 +10,10 @@ fn main() { let _ = transmute::<_, Vec>(vec![0u8]); //~^ unsound_collection_transmute - // wrong layout let _ = transmute::<_, Vec<[u8; 4]>>(vec![1234u32]); //~^ unsound_collection_transmute - // wrong size let _ = transmute::<_, VecDeque>(VecDeque::::new()); //~^ unsound_collection_transmute @@ -24,7 +22,6 @@ fn main() { let _ = transmute::<_, VecDeque>(VecDeque::<[u8; 4]>::new()); //~^ unsound_collection_transmute - // wrong size let _ = transmute::<_, BinaryHeap>(BinaryHeap::::new()); //~^ unsound_collection_transmute @@ -33,7 +30,6 @@ fn main() { let _ = transmute::<_, BinaryHeap>(BinaryHeap::<[u8; 4]>::new()); //~^ unsound_collection_transmute - // wrong size let _ = transmute::<_, BTreeSet>(BTreeSet::::new()); //~^ unsound_collection_transmute @@ -42,7 +38,6 @@ fn main() { let _ = transmute::<_, BTreeSet>(BTreeSet::<[u8; 4]>::new()); //~^ unsound_collection_transmute - // wrong size let _ = transmute::<_, HashSet>(HashSet::::new()); //~^ unsound_collection_transmute @@ -51,7 +46,6 @@ fn main() { let _ = transmute::<_, HashSet>(HashSet::<[u8; 4]>::new()); //~^ unsound_collection_transmute - // wrong size let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); //~^ unsound_collection_transmute @@ -66,7 +60,6 @@ fn main() { let _ = transmute::<_, BTreeMap>(BTreeMap::<[u8; 4], u32>::new()); //~^ unsound_collection_transmute - // wrong size let _ = transmute::<_, HashMap>(HashMap::::new()); //~^ unsound_collection_transmute @@ -81,7 +74,6 @@ fn main() { let _ = transmute::<_, HashMap>(HashMap::<[u8; 4], u32>::new()); //~^ unsound_collection_transmute - let _ = transmute::<_, Vec>(Vec::>::new()); let _ = transmute::<_, Vec<*mut u32>>(Vec::>::new()); } diff --git a/tests/ui/transmute_collection.stderr b/tests/ui/transmute_collection.stderr index f887afc9b676..ac2de07f6bf2 100644 --- a/tests/ui/transmute_collection.stderr +++ b/tests/ui/transmute_collection.stderr @@ -8,103 +8,103 @@ LL | let _ = transmute::<_, Vec>(vec![0u8]); = help: to override `-D warnings` add `#[allow(clippy::unsound_collection_transmute)]` error: transmute from `std::vec::Vec` to `std::vec::Vec<[u8; 4]>` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:15:17 + --> tests/ui/transmute_collection.rs:14:17 | LL | let _ = transmute::<_, Vec<[u8; 4]>>(vec![1234u32]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::VecDeque` to `std::collections::VecDeque` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:20:17 + --> tests/ui/transmute_collection.rs:18:17 | LL | let _ = transmute::<_, VecDeque>(VecDeque::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::VecDeque<[u8; 4]>` to `std::collections::VecDeque` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:24:17 + --> tests/ui/transmute_collection.rs:22:17 | LL | let _ = transmute::<_, VecDeque>(VecDeque::<[u8; 4]>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BinaryHeap` to `std::collections::BinaryHeap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:29:17 + --> tests/ui/transmute_collection.rs:26:17 | LL | let _ = transmute::<_, BinaryHeap>(BinaryHeap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BinaryHeap<[u8; 4]>` to `std::collections::BinaryHeap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:33:17 + --> tests/ui/transmute_collection.rs:30:17 | LL | let _ = transmute::<_, BinaryHeap>(BinaryHeap::<[u8; 4]>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeSet` to `std::collections::BTreeSet` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:38:17 + --> tests/ui/transmute_collection.rs:34:17 | LL | let _ = transmute::<_, BTreeSet>(BTreeSet::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeSet<[u8; 4]>` to `std::collections::BTreeSet` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:42:17 + --> tests/ui/transmute_collection.rs:38:17 | LL | let _ = transmute::<_, BTreeSet>(BTreeSet::<[u8; 4]>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashSet` to `std::collections::HashSet` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:47:17 + --> tests/ui/transmute_collection.rs:42:17 | LL | let _ = transmute::<_, HashSet>(HashSet::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashSet<[u8; 4]>` to `std::collections::HashSet` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:51:17 + --> tests/ui/transmute_collection.rs:46:17 | LL | let _ = transmute::<_, HashSet>(HashSet::<[u8; 4]>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeMap` to `std::collections::BTreeMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:56:17 + --> tests/ui/transmute_collection.rs:50:17 | LL | let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeMap` to `std::collections::BTreeMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:59:17 + --> tests/ui/transmute_collection.rs:53:17 | LL | let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeMap` to `std::collections::BTreeMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:63:17 + --> tests/ui/transmute_collection.rs:57:17 | LL | let _ = transmute::<_, BTreeMap>(BTreeMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::BTreeMap<[u8; 4], u32>` to `std::collections::BTreeMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:66:17 + --> tests/ui/transmute_collection.rs:60:17 | LL | let _ = transmute::<_, BTreeMap>(BTreeMap::<[u8; 4], u32>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashMap` to `std::collections::HashMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:71:17 + --> tests/ui/transmute_collection.rs:64:17 | LL | let _ = transmute::<_, HashMap>(HashMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashMap` to `std::collections::HashMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:74:17 + --> tests/ui/transmute_collection.rs:67:17 | LL | let _ = transmute::<_, HashMap>(HashMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashMap` to `std::collections::HashMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:78:17 + --> tests/ui/transmute_collection.rs:71:17 | LL | let _ = transmute::<_, HashMap>(HashMap::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `std::collections::HashMap<[u8; 4], u32>` to `std::collections::HashMap` with mismatched layout is unsound - --> tests/ui/transmute_collection.rs:81:17 + --> tests/ui/transmute_collection.rs:74:17 | LL | let _ = transmute::<_, HashMap>(HashMap::<[u8; 4], u32>::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute_float_to_int.fixed b/tests/ui/transmute_float_to_int.fixed index e1feb57ae736..1f97b997eaa0 100644 --- a/tests/ui/transmute_float_to_int.fixed +++ b/tests/ui/transmute_float_to_int.fixed @@ -7,7 +7,6 @@ fn float_to_int() { let _: u32 = unsafe { 1f32.to_bits() }; //~^ transmute_float_to_int - let _: i32 = unsafe { 1f32.to_bits() as i32 }; //~^ transmute_float_to_int @@ -22,7 +21,6 @@ fn float_to_int() { let _: u64 = unsafe { (-1.0f64).to_bits() }; //~^ transmute_float_to_int - } mod issue_5747 { @@ -38,29 +36,24 @@ mod issue_5747 { const VALUE128: u128 = unsafe { 1f128.to_bits() }; //~^ transmute_float_to_int - const fn to_bits_16(v: f16) -> u16 { unsafe { v.to_bits() } //~^ transmute_float_to_int - } const fn to_bits_32(v: f32) -> u32 { unsafe { v.to_bits() } //~^ transmute_float_to_int - } const fn to_bits_64(v: f64) -> i64 { unsafe { v.to_bits() as i64 } //~^ transmute_float_to_int - } const fn to_bits_128(v: f128) -> i128 { unsafe { v.to_bits() as i128 } //~^ transmute_float_to_int - } } diff --git a/tests/ui/transmute_float_to_int.rs b/tests/ui/transmute_float_to_int.rs index ac2a1a1ad05d..788a7e1026c6 100644 --- a/tests/ui/transmute_float_to_int.rs +++ b/tests/ui/transmute_float_to_int.rs @@ -7,7 +7,6 @@ fn float_to_int() { let _: u32 = unsafe { std::mem::transmute(1f32) }; //~^ transmute_float_to_int - let _: i32 = unsafe { std::mem::transmute(1f32) }; //~^ transmute_float_to_int @@ -22,7 +21,6 @@ fn float_to_int() { let _: u64 = unsafe { std::mem::transmute(-1.0) }; //~^ transmute_float_to_int - } mod issue_5747 { @@ -38,29 +36,24 @@ mod issue_5747 { const VALUE128: u128 = unsafe { std::mem::transmute(1f128) }; //~^ transmute_float_to_int - const fn to_bits_16(v: f16) -> u16 { unsafe { std::mem::transmute(v) } //~^ transmute_float_to_int - } const fn to_bits_32(v: f32) -> u32 { unsafe { std::mem::transmute(v) } //~^ transmute_float_to_int - } const fn to_bits_64(v: f64) -> i64 { unsafe { std::mem::transmute(v) } //~^ transmute_float_to_int - } const fn to_bits_128(v: f128) -> i128 { unsafe { std::mem::transmute(v) } //~^ transmute_float_to_int - } } diff --git a/tests/ui/transmute_float_to_int.stderr b/tests/ui/transmute_float_to_int.stderr index 551fcb1f7d0d..223cbc4e90c0 100644 --- a/tests/ui/transmute_float_to_int.stderr +++ b/tests/ui/transmute_float_to_int.stderr @@ -8,79 +8,79 @@ LL | let _: u32 = unsafe { std::mem::transmute(1f32) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_float_to_int)]` error: transmute from a `f32` to a `i32` - --> tests/ui/transmute_float_to_int.rs:11:27 + --> tests/ui/transmute_float_to_int.rs:10:27 | LL | let _: i32 = unsafe { std::mem::transmute(1f32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:14:27 + --> tests/ui/transmute_float_to_int.rs:13:27 | LL | let _: u64 = unsafe { std::mem::transmute(1f64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()` error: transmute from a `f64` to a `i64` - --> tests/ui/transmute_float_to_int.rs:17:27 + --> tests/ui/transmute_float_to_int.rs:16:27 | LL | let _: i64 = unsafe { std::mem::transmute(1f64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits() as i64` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:20:27 + --> tests/ui/transmute_float_to_int.rs:19:27 | LL | let _: u64 = unsafe { std::mem::transmute(1.0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.0f64.to_bits()` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:23:27 + --> tests/ui/transmute_float_to_int.rs:22:27 | LL | let _: u64 = unsafe { std::mem::transmute(-1.0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()` error: transmute from a `f16` to a `i16` - --> tests/ui/transmute_float_to_int.rs:29:35 + --> tests/ui/transmute_float_to_int.rs:27:35 | LL | const VALUE16: i16 = unsafe { std::mem::transmute(1f16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f16.to_bits() as i16` error: transmute from a `f32` to a `i32` - --> tests/ui/transmute_float_to_int.rs:32:35 + --> tests/ui/transmute_float_to_int.rs:30:35 | LL | const VALUE32: i32 = unsafe { std::mem::transmute(1f32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:35:35 + --> tests/ui/transmute_float_to_int.rs:33:35 | LL | const VALUE64: u64 = unsafe { std::mem::transmute(1f64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()` error: transmute from a `f128` to a `u128` - --> tests/ui/transmute_float_to_int.rs:38:37 + --> tests/ui/transmute_float_to_int.rs:36:37 | LL | const VALUE128: u128 = unsafe { std::mem::transmute(1f128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f128.to_bits()` error: transmute from a `f16` to a `u16` - --> tests/ui/transmute_float_to_int.rs:43:18 + --> tests/ui/transmute_float_to_int.rs:40:18 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits()` error: transmute from a `f32` to a `u32` - --> tests/ui/transmute_float_to_int.rs:49:18 + --> tests/ui/transmute_float_to_int.rs:45:18 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits()` error: transmute from a `f64` to a `i64` - --> tests/ui/transmute_float_to_int.rs:55:18 + --> tests/ui/transmute_float_to_int.rs:50:18 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits() as i64` error: transmute from a `f128` to a `i128` - --> tests/ui/transmute_float_to_int.rs:61:18 + --> tests/ui/transmute_float_to_int.rs:55:18 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits() as i128` diff --git a/tests/ui/transmute_int_to_char.fixed b/tests/ui/transmute_int_to_char.fixed index e28467f00434..b5425a2e9e85 100644 --- a/tests/ui/transmute_int_to_char.fixed +++ b/tests/ui/transmute_int_to_char.fixed @@ -5,11 +5,9 @@ fn int_to_char() { let _: char = unsafe { std::char::from_u32(0_u32).unwrap() }; //~^ transmute_int_to_char - let _: char = unsafe { std::char::from_u32(0_i32 as u32).unwrap() }; //~^ transmute_int_to_char - // These shouldn't warn const _: char = unsafe { std::mem::transmute(0_u32) }; const _: char = unsafe { std::mem::transmute(0_i32) }; diff --git a/tests/ui/transmute_int_to_char.rs b/tests/ui/transmute_int_to_char.rs index decdaaa463a9..b24bb177c9fc 100644 --- a/tests/ui/transmute_int_to_char.rs +++ b/tests/ui/transmute_int_to_char.rs @@ -5,11 +5,9 @@ fn int_to_char() { let _: char = unsafe { std::mem::transmute(0_u32) }; //~^ transmute_int_to_char - let _: char = unsafe { std::mem::transmute(0_i32) }; //~^ transmute_int_to_char - // These shouldn't warn const _: char = unsafe { std::mem::transmute(0_u32) }; const _: char = unsafe { std::mem::transmute(0_i32) }; diff --git a/tests/ui/transmute_int_to_char.stderr b/tests/ui/transmute_int_to_char.stderr index 5dc58abb38ea..e3a3620f28b7 100644 --- a/tests/ui/transmute_int_to_char.stderr +++ b/tests/ui/transmute_int_to_char.stderr @@ -8,7 +8,7 @@ LL | let _: char = unsafe { std::mem::transmute(0_u32) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]` error: transmute from a `i32` to a `char` - --> tests/ui/transmute_int_to_char.rs:9:28 + --> tests/ui/transmute_int_to_char.rs:8:28 | LL | let _: char = unsafe { std::mem::transmute(0_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()` diff --git a/tests/ui/transmute_int_to_char_no_std.fixed b/tests/ui/transmute_int_to_char_no_std.fixed index 09a353dc1ae9..e525751e306e 100644 --- a/tests/ui/transmute_int_to_char_no_std.fixed +++ b/tests/ui/transmute_int_to_char_no_std.fixed @@ -17,11 +17,9 @@ fn int_to_char() { let _: char = unsafe { core::char::from_u32(0_u32).unwrap() }; //~^ transmute_int_to_char - let _: char = unsafe { core::char::from_u32(0_i32 as u32).unwrap() }; //~^ transmute_int_to_char - // These shouldn't warn const _: char = unsafe { core::mem::transmute(0_u32) }; const _: char = unsafe { core::mem::transmute(0_i32) }; diff --git a/tests/ui/transmute_int_to_char_no_std.rs b/tests/ui/transmute_int_to_char_no_std.rs index fb47b3ce3ba9..7cb508ceaf3b 100644 --- a/tests/ui/transmute_int_to_char_no_std.rs +++ b/tests/ui/transmute_int_to_char_no_std.rs @@ -17,11 +17,9 @@ fn int_to_char() { let _: char = unsafe { core::mem::transmute(0_u32) }; //~^ transmute_int_to_char - let _: char = unsafe { core::mem::transmute(0_i32) }; //~^ transmute_int_to_char - // These shouldn't warn const _: char = unsafe { core::mem::transmute(0_u32) }; const _: char = unsafe { core::mem::transmute(0_i32) }; diff --git a/tests/ui/transmute_int_to_char_no_std.stderr b/tests/ui/transmute_int_to_char_no_std.stderr index 37f996e6277f..d94580a84d7a 100644 --- a/tests/ui/transmute_int_to_char_no_std.stderr +++ b/tests/ui/transmute_int_to_char_no_std.stderr @@ -8,7 +8,7 @@ LL | let _: char = unsafe { core::mem::transmute(0_u32) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]` error: transmute from a `i32` to a `char` - --> tests/ui/transmute_int_to_char_no_std.rs:21:28 + --> tests/ui/transmute_int_to_char_no_std.rs:20:28 | LL | let _: char = unsafe { core::mem::transmute(0_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::char::from_u32(0_i32 as u32).unwrap()` diff --git a/tests/ui/transmute_int_to_non_zero.fixed b/tests/ui/transmute_int_to_non_zero.fixed index 12d8d20f4d8f..273090fef387 100644 --- a/tests/ui/transmute_int_to_non_zero.fixed +++ b/tests/ui/transmute_int_to_non_zero.fixed @@ -19,7 +19,6 @@ fn main() { let _: NonZero = unsafe { NonZero::new_unchecked(int_u8) }; //~^ transmute_int_to_non_zero - let _: NonZero = unsafe { NonZero::new_unchecked(int_u16) }; //~^ transmute_int_to_non_zero @@ -32,7 +31,6 @@ fn main() { let _: NonZero = unsafe { NonZero::new_unchecked(int_u128) }; //~^ transmute_int_to_non_zero - let _: NonZero = unsafe { NonZero::new_unchecked(int_i8) }; //~^ transmute_int_to_non_zero @@ -48,7 +46,6 @@ fn main() { let _: NonZero = unsafe { NonZero::new_unchecked(int_i128) }; //~^ transmute_int_to_non_zero - let _: NonZero = unsafe { NonZero::new_unchecked(int_u8) }; let _: NonZero = unsafe { NonZero::new_unchecked(int_u16) }; let _: NonZero = unsafe { NonZero::new_unchecked(int_u32) }; diff --git a/tests/ui/transmute_int_to_non_zero.rs b/tests/ui/transmute_int_to_non_zero.rs index a01b9aaa7f2e..f27bc9b42d42 100644 --- a/tests/ui/transmute_int_to_non_zero.rs +++ b/tests/ui/transmute_int_to_non_zero.rs @@ -19,7 +19,6 @@ fn main() { let _: NonZero = unsafe { std::mem::transmute(int_u8) }; //~^ transmute_int_to_non_zero - let _: NonZero = unsafe { std::mem::transmute(int_u16) }; //~^ transmute_int_to_non_zero @@ -32,7 +31,6 @@ fn main() { let _: NonZero = unsafe { std::mem::transmute(int_u128) }; //~^ transmute_int_to_non_zero - let _: NonZero = unsafe { std::mem::transmute(int_i8) }; //~^ transmute_int_to_non_zero @@ -48,7 +46,6 @@ fn main() { let _: NonZero = unsafe { std::mem::transmute(int_i128) }; //~^ transmute_int_to_non_zero - let _: NonZero = unsafe { NonZero::new_unchecked(int_u8) }; let _: NonZero = unsafe { NonZero::new_unchecked(int_u16) }; let _: NonZero = unsafe { NonZero::new_unchecked(int_u32) }; diff --git a/tests/ui/transmute_int_to_non_zero.stderr b/tests/ui/transmute_int_to_non_zero.stderr index 1a1cd03248b4..995ab11a5bc9 100644 --- a/tests/ui/transmute_int_to_non_zero.stderr +++ b/tests/ui/transmute_int_to_non_zero.stderr @@ -8,55 +8,55 @@ LL | let _: NonZero = unsafe { std::mem::transmute(int_u8) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_non_zero)]` error: transmute from a `u16` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:23:36 + --> tests/ui/transmute_int_to_non_zero.rs:22:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_u16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u16)` error: transmute from a `u32` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:26:36 + --> tests/ui/transmute_int_to_non_zero.rs:25:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u32)` error: transmute from a `u64` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:29:36 + --> tests/ui/transmute_int_to_non_zero.rs:28:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_u64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u64)` error: transmute from a `u128` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:32:37 + --> tests/ui/transmute_int_to_non_zero.rs:31:37 | LL | let _: NonZero = unsafe { std::mem::transmute(int_u128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u128)` error: transmute from a `i8` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:36:35 + --> tests/ui/transmute_int_to_non_zero.rs:34:35 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i8)` error: transmute from a `i16` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:39:36 + --> tests/ui/transmute_int_to_non_zero.rs:37:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i16)` error: transmute from a `i32` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:42:36 + --> tests/ui/transmute_int_to_non_zero.rs:40:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i32)` error: transmute from a `i64` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:45:36 + --> tests/ui/transmute_int_to_non_zero.rs:43:36 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i64)` error: transmute from a `i128` to a `NonZero` - --> tests/ui/transmute_int_to_non_zero.rs:48:37 + --> tests/ui/transmute_int_to_non_zero.rs:46:37 | LL | let _: NonZero = unsafe { std::mem::transmute(int_i128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i128)` diff --git a/tests/ui/transmute_null_to_fn.rs b/tests/ui/transmute_null_to_fn.rs index a9eaf16d05aa..e88f05bb662e 100644 --- a/tests/ui/transmute_null_to_fn.rs +++ b/tests/ui/transmute_null_to_fn.rs @@ -10,7 +10,6 @@ fn one_liners() { let _: fn() = std::mem::transmute(std::ptr::null::<()>()); //~^ transmute_null_to_fn - } } @@ -38,7 +37,6 @@ fn issue_11485() { let _: fn() = std::mem::transmute(ZPTR as *const u8); //~^ transmute_null_to_fn - } } diff --git a/tests/ui/transmute_null_to_fn.stderr b/tests/ui/transmute_null_to_fn.stderr index 9b2253c444f4..f7d80147445d 100644 --- a/tests/ui/transmute_null_to_fn.stderr +++ b/tests/ui/transmute_null_to_fn.stderr @@ -17,7 +17,7 @@ LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>()); = help: try wrapping your function pointer type in `Option` instead, and using `None` as a null pointer value error: transmuting a known null pointer into a function pointer - --> tests/ui/transmute_null_to_fn.rs:23:23 + --> tests/ui/transmute_null_to_fn.rs:22:23 | LL | let _: fn() = std::mem::transmute(ZPTR); | ^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior @@ -25,7 +25,7 @@ LL | let _: fn() = std::mem::transmute(ZPTR); = help: try wrapping your function pointer type in `Option` instead, and using `None` as a null pointer value error: transmuting a known null pointer into a function pointer - --> tests/ui/transmute_null_to_fn.rs:33:23 + --> tests/ui/transmute_null_to_fn.rs:32:23 | LL | let _: fn() = std::mem::transmute(0 as *const u8 as *const ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior @@ -33,7 +33,7 @@ LL | let _: fn() = std::mem::transmute(0 as *const u8 as *const ()); = help: try wrapping your function pointer type in `Option` instead, and using `None` as a null pointer value error: transmuting a known null pointer into a function pointer - --> tests/ui/transmute_null_to_fn.rs:36:23 + --> tests/ui/transmute_null_to_fn.rs:35:23 | LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior @@ -41,7 +41,7 @@ LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const = help: try wrapping your function pointer type in `Option` instead, and using `None` as a null pointer value error: transmuting a known null pointer into a function pointer - --> tests/ui/transmute_null_to_fn.rs:39:23 + --> tests/ui/transmute_null_to_fn.rs:38:23 | LL | let _: fn() = std::mem::transmute(ZPTR as *const u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior diff --git a/tests/ui/transmute_ptr_to_ptr.fixed b/tests/ui/transmute_ptr_to_ptr.fixed index d595ecf32a1c..3a67be5f45d0 100644 --- a/tests/ui/transmute_ptr_to_ptr.fixed +++ b/tests/ui/transmute_ptr_to_ptr.fixed @@ -59,7 +59,6 @@ fn transmute_ptr_to_ptr() { let _: *mut u32 = ptr.cast_mut(); //~^ transmute_ptr_to_ptr - } // transmute internal lifetimes, should not lint @@ -72,7 +71,6 @@ fn transmute_ptr_to_ptr() { fn lifetime_to_static(v: *mut &()) -> *const &'static () { unsafe { v as *const &() } //~^ transmute_ptr_to_ptr - } // dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959) diff --git a/tests/ui/transmute_ptr_to_ptr.rs b/tests/ui/transmute_ptr_to_ptr.rs index 2e72f86dd3b3..01ad3a3296b1 100644 --- a/tests/ui/transmute_ptr_to_ptr.rs +++ b/tests/ui/transmute_ptr_to_ptr.rs @@ -59,7 +59,6 @@ fn transmute_ptr_to_ptr() { let _: *mut u32 = transmute(ptr); //~^ transmute_ptr_to_ptr - } // transmute internal lifetimes, should not lint @@ -72,7 +71,6 @@ fn transmute_ptr_to_ptr() { fn lifetime_to_static(v: *mut &()) -> *const &'static () { unsafe { transmute(v) } //~^ transmute_ptr_to_ptr - } // dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959) diff --git a/tests/ui/transmute_ptr_to_ptr.stderr b/tests/ui/transmute_ptr_to_ptr.stderr index 3e7e170eff7f..0ff1cd3c090b 100644 --- a/tests/ui/transmute_ptr_to_ptr.stderr +++ b/tests/ui/transmute_ptr_to_ptr.stderr @@ -75,7 +75,7 @@ LL | let _: *mut u32 = ptr.cast_mut(); | ~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:73:14 + --> tests/ui/transmute_ptr_to_ptr.rs:72:14 | LL | unsafe { transmute(v) } | ^^^^^^^^^^^^ @@ -86,7 +86,7 @@ LL | unsafe { v as *const &() } | ~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:89:28 + --> tests/ui/transmute_ptr_to_ptr.rs:87:28 | LL | let _: *const i8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _: *const i8 = ptr as *const i8; | ~~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:97:28 + --> tests/ui/transmute_ptr_to_ptr.rs:95:28 | LL | let _: *const i8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | let _: *const i8 = ptr.cast::(); | ~~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:105:26 + --> tests/ui/transmute_ptr_to_ptr.rs:103:26 | LL | let _: *mut u8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | let _: *mut u8 = ptr as *mut u8; | ~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:107:28 + --> tests/ui/transmute_ptr_to_ptr.rs:105:28 | LL | let _: *const u8 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -130,7 +130,7 @@ LL | let _: *const u8 = mut_ptr as *const u8; | ~~~~~~~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:115:26 + --> tests/ui/transmute_ptr_to_ptr.rs:113:26 | LL | let _: *mut u8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -141,7 +141,7 @@ LL | let _: *mut u8 = ptr.cast_mut(); | ~~~~~~~~~~~~~~ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:117:28 + --> tests/ui/transmute_ptr_to_ptr.rs:115:28 | LL | let _: *const u8 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute_ref_to_ref.rs b/tests/ui/transmute_ref_to_ref.rs index c2094ab0cad6..8bdf07b4a428 100644 --- a/tests/ui/transmute_ref_to_ref.rs +++ b/tests/ui/transmute_ref_to_ref.rs @@ -16,6 +16,5 @@ fn main() { let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8]; let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) }; //~^ transmute_ptr_to_ptr - } } diff --git a/tests/ui/transmute_ref_to_ref_no_std.rs b/tests/ui/transmute_ref_to_ref_no_std.rs index 86c4189d87e4..faa776f2afce 100644 --- a/tests/ui/transmute_ref_to_ref_no_std.rs +++ b/tests/ui/transmute_ref_to_ref_no_std.rs @@ -28,6 +28,5 @@ fn main() { let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8]; let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) }; //~^ transmute_ptr_to_ptr - } } diff --git a/tests/ui/transmute_undefined_repr.rs b/tests/ui/transmute_undefined_repr.rs index db876150f406..a449d6a4302f 100644 --- a/tests/ui/transmute_undefined_repr.rs +++ b/tests/ui/transmute_undefined_repr.rs @@ -34,12 +34,10 @@ fn main() { let _: Ty2C = transmute(value::>()); //~^ transmute_undefined_repr - // Lint, Ty2 is unordered let _: Ty2 = transmute(value::>()); //~^ transmute_undefined_repr - // Ok, Ty2 types are the same let _: Ty2 = transmute(value::>>()); // Ok, Ty2 types are the same @@ -49,13 +47,10 @@ fn main() { let _: Ty2 = transmute(value::>>()); //~^ transmute_undefined_repr - // Lint, different Ty2 instances let _: Ty> = transmute(value::>()); //~^ transmute_undefined_repr - - let _: Ty<&()> = transmute(value::<&()>()); let _: &() = transmute(value::>()); @@ -63,13 +58,10 @@ fn main() { let _: &Ty2 = transmute(value::>>()); //~^ transmute_undefined_repr - // Lint, different Ty2 instances let _: Ty<&Ty2> = transmute(value::<&Ty2>()); //~^ transmute_undefined_repr - - // Ok, pointer to usize conversion let _: Ty = transmute(value::<&Ty2>()); // Ok, pointer to usize conversion @@ -99,13 +91,10 @@ fn main() { let _: &'static mut Ty2 = transmute(value::>>()); //~^ transmute_undefined_repr - // Lint, different Ty2 instances let _: Box> = transmute(value::<&'static mut Ty2>()); //~^ transmute_undefined_repr - - // Ok, type erasure let _: *const () = transmute(value::>>()); // Ok, reverse type erasure @@ -202,13 +191,10 @@ fn main() { let _: *const Ty2 = transmute(value::<*const Ty2C>>()); //~^ transmute_undefined_repr - // Err let _: *const Ty2C> = transmute(value::<*const Ty2>()); //~^ transmute_undefined_repr - - // Ok let _: NonNull = transmute(value::>()); // Ok @@ -255,13 +241,10 @@ fn _with_generics() { let _: Vec> = transmute(value::>>()); //~^ transmute_undefined_repr - // Err let _: Vec> = transmute(value::>>()); //~^ transmute_undefined_repr - - // Ok let _: *const u32 = transmute(value::>()); // Ok diff --git a/tests/ui/transmute_undefined_repr.stderr b/tests/ui/transmute_undefined_repr.stderr index a569309b2eb4..a259ef784c78 100644 --- a/tests/ui/transmute_undefined_repr.stderr +++ b/tests/ui/transmute_undefined_repr.stderr @@ -8,13 +8,13 @@ LL | let _: Ty2C = transmute(value::>()); = help: to override `-D warnings` add `#[allow(clippy::transmute_undefined_repr)]` error: transmute into `Ty2` which has an undefined layout - --> tests/ui/transmute_undefined_repr.rs:39:32 + --> tests/ui/transmute_undefined_repr.rs:38:32 | LL | let _: Ty2 = transmute(value::>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from `Ty>` to `Ty2`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:49:32 + --> tests/ui/transmute_undefined_repr.rs:47:32 | LL | let _: Ty2 = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | let _: Ty2 = transmute(value::>>()); = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `Ty2` to `Ty>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:54:36 + --> tests/ui/transmute_undefined_repr.rs:51:36 | LL | let _: Ty> = transmute(value::>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | let _: Ty> = transmute(value::>()); = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `Ty<&Ty2>` to `&Ty2`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:63:33 + --> tests/ui/transmute_undefined_repr.rs:58:33 | LL | let _: &Ty2 = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | let _: &Ty2 = transmute(value::>>()); = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `&Ty2` to `Ty<&Ty2>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:68:37 + --> tests/ui/transmute_undefined_repr.rs:62:37 | LL | let _: Ty<&Ty2> = transmute(value::<&Ty2>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | let _: Ty<&Ty2> = transmute(value::<&Ty2>()); = note: two instances of the same generic type (`Ty2`) may have different layouts error: transmute from `std::boxed::Box>` to `&mut Ty2`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:99:45 + --> tests/ui/transmute_undefined_repr.rs:91:45 | LL | let _: &'static mut Ty2 = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | let _: &'static mut Ty2 = transmute(value::` to `std::boxed::Box>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:104:37 + --> tests/ui/transmute_undefined_repr.rs:95:37 | LL | let _: Box> = transmute(value::<&'static mut Ty2>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -62,7 +62,7 @@ LL | let _: Box> = transmute(value::<&'static mut Ty2` which has an undefined layout - --> tests/ui/transmute_undefined_repr.rs:202:39 + --> tests/ui/transmute_undefined_repr.rs:191:39 | LL | let _: *const Ty2 = transmute(value::<*const Ty2C>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | let _: *const Ty2 = transmute(value::<*const Ty2C` has an undefined layout error: transmute from `*const Ty2` which has an undefined layout - --> tests/ui/transmute_undefined_repr.rs:207:50 + --> tests/ui/transmute_undefined_repr.rs:195:50 | LL | let _: *const Ty2C> = transmute(value::<*const Ty2>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _: *const Ty2C> = transmute(value::<*const T = note: the contained type `Ty2` has an undefined layout error: transmute from `std::vec::Vec>` to `std::vec::Vec>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:255:35 + --> tests/ui/transmute_undefined_repr.rs:241:35 | LL | let _: Vec> = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -86,7 +86,7 @@ LL | let _: Vec> = transmute(value::>>()); = note: two instances of the same generic type (`Vec`) may have different layouts error: transmute from `std::vec::Vec>` to `std::vec::Vec>`, both of which have an undefined layout - --> tests/ui/transmute_undefined_repr.rs:260:35 + --> tests/ui/transmute_undefined_repr.rs:245:35 | LL | let _: Vec> = transmute(value::>>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmuting_null.rs b/tests/ui/transmuting_null.rs index 91f32a725589..bcd35bbd4e72 100644 --- a/tests/ui/transmuting_null.rs +++ b/tests/ui/transmuting_null.rs @@ -10,10 +10,8 @@ fn one_liners() { let _: &u64 = std::mem::transmute(0 as *const u64); //~^ transmuting_null - let _: &u64 = std::mem::transmute(std::ptr::null::()); //~^ transmuting_null - } } diff --git a/tests/ui/transmuting_null.stderr b/tests/ui/transmuting_null.stderr index 2e5fffd3ac28..84e6e374d525 100644 --- a/tests/ui/transmuting_null.stderr +++ b/tests/ui/transmuting_null.stderr @@ -8,13 +8,13 @@ LL | let _: &u64 = std::mem::transmute(0 as *const u64); = help: to override `-D warnings` add `#[allow(clippy::transmuting_null)]` error: transmuting a known null pointer into a reference - --> tests/ui/transmuting_null.rs:14:23 + --> tests/ui/transmuting_null.rs:13:23 | LL | let _: &u64 = std::mem::transmute(std::ptr::null::()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmuting a known null pointer into a reference - --> tests/ui/transmuting_null.rs:26:23 + --> tests/ui/transmuting_null.rs:24:23 | LL | let _: &u64 = std::mem::transmute(ZPTR); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type_complexity.rs b/tests/ui/type_complexity.rs index 09c7bcc68408..89c4955c9f6f 100644 --- a/tests/ui/type_complexity.rs +++ b/tests/ui/type_complexity.rs @@ -7,28 +7,22 @@ type Alias = Vec>>; // no warning here const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); //~^ type_complexity - static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); //~^ type_complexity - struct S { f: Vec>>, //~^ type_complexity - } struct Ts(Vec>>); //~^ type_complexity - enum E { Tuple(Vec>>), //~^ type_complexity - Struct { f: Vec>> }, //~^ type_complexity - } impl S { @@ -37,7 +31,6 @@ impl S { fn impl_method(&self, p: Vec>>) {} //~^ type_complexity - } trait T { @@ -52,7 +45,6 @@ trait T { fn def_method(&self, p: Vec>>) {} //~^ type_complexity - } // Should not warn since there is likely no way to simplify this (#1013) @@ -65,7 +57,7 @@ impl T for () { } fn test1() -> Vec>> { -//~^ type_complexity + //~^ type_complexity vec![] } @@ -73,11 +65,9 @@ fn test1() -> Vec>> { fn test2(_x: Vec>>) {} //~^ type_complexity - fn test3() { let _y: Vec>> = vec![]; //~^ type_complexity - } #[repr(C)] diff --git a/tests/ui/type_complexity.stderr b/tests/ui/type_complexity.stderr index 4926432aab88..181e04d38e9a 100644 --- a/tests/ui/type_complexity.stderr +++ b/tests/ui/type_complexity.stderr @@ -8,85 +8,85 @@ LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]` error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:11:12 + --> tests/ui/type_complexity.rs:10:12 | LL | static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:16:8 + --> tests/ui/type_complexity.rs:14:8 | LL | f: Vec>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:21:11 + --> tests/ui/type_complexity.rs:18:11 | LL | struct Ts(Vec>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:26:11 + --> tests/ui/type_complexity.rs:22:11 | LL | Tuple(Vec>>), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:29:17 + --> tests/ui/type_complexity.rs:24:17 | LL | Struct { f: Vec>> }, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:35:14 + --> tests/ui/type_complexity.rs:29:14 | LL | const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:38:30 + --> tests/ui/type_complexity.rs:32:30 | LL | fn impl_method(&self, p: Vec>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:44:14 + --> tests/ui/type_complexity.rs:37:14 | LL | const A: Vec>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:47:14 + --> tests/ui/type_complexity.rs:40:14 | LL | type B = Vec>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:50:25 + --> tests/ui/type_complexity.rs:43:25 | LL | fn method(&self, p: Vec>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:53:29 + --> tests/ui/type_complexity.rs:46:29 | LL | fn def_method(&self, p: Vec>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:67:15 + --> tests/ui/type_complexity.rs:59:15 | LL | fn test1() -> Vec>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:73:14 + --> tests/ui/type_complexity.rs:65:14 | LL | fn test2(_x: Vec>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:78:13 + --> tests/ui/type_complexity.rs:69:13 | LL | let _y: Vec>> = vec![]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type_id_on_box.fixed b/tests/ui/type_id_on_box.fixed index f0d8a4acb2e3..2e241c36b34a 100644 --- a/tests/ui/type_id_on_box.fixed +++ b/tests/ui/type_id_on_box.fixed @@ -31,7 +31,6 @@ fn main() { let _ = (*any_box).type_id(); //~^ type_id_on_box - // Don't lint. We explicitly say "do this instead" if this is intentional let _ = TypeId::of::>(); let _ = (*any_box).type_id(); @@ -41,7 +40,6 @@ fn main() { let _ = (**any_box).type_id(); //~^ type_id_on_box - let b = existential(); let _ = b.type_id(); // Don't @@ -49,12 +47,10 @@ fn main() { let _ = (*b).type_id(); //~^ type_id_on_box - let b: SomeBox = Box::new(0usize); let _ = (*b).type_id(); //~^ type_id_on_box - let b = BadBox(Box::new(0usize)); let _ = b.type_id(); // Don't lint. This is a call to `::type_id`. Not `std::boxed::Box`! } diff --git a/tests/ui/type_id_on_box.rs b/tests/ui/type_id_on_box.rs index b446ec287b67..46fac632894c 100644 --- a/tests/ui/type_id_on_box.rs +++ b/tests/ui/type_id_on_box.rs @@ -31,7 +31,6 @@ fn main() { let _ = any_box.type_id(); //~^ type_id_on_box - // Don't lint. We explicitly say "do this instead" if this is intentional let _ = TypeId::of::>(); let _ = (*any_box).type_id(); @@ -41,7 +40,6 @@ fn main() { let _ = any_box.type_id(); //~^ type_id_on_box - let b = existential(); let _ = b.type_id(); // Don't @@ -49,12 +47,10 @@ fn main() { let _ = b.type_id(); //~^ type_id_on_box - let b: SomeBox = Box::new(0usize); let _ = b.type_id(); //~^ type_id_on_box - let b = BadBox(Box::new(0usize)); let _ = b.type_id(); // Don't lint. This is a call to `::type_id`. Not `std::boxed::Box`! } diff --git a/tests/ui/type_id_on_box.stderr b/tests/ui/type_id_on_box.stderr index 8004ef71287c..4528195607da 100644 --- a/tests/ui/type_id_on_box.stderr +++ b/tests/ui/type_id_on_box.stderr @@ -12,7 +12,7 @@ LL | let _ = any_box.type_id(); = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]` error: calling `.type_id()` on `Box` - --> tests/ui/type_id_on_box.rs:41:13 + --> tests/ui/type_id_on_box.rs:40:13 | LL | let _ = any_box.type_id(); | -------^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = any_box.type_id(); = note: if this is intentional, use `TypeId::of::>()` instead, which makes it more clear error: calling `.type_id()` on `Box` - --> tests/ui/type_id_on_box.rs:49:13 + --> tests/ui/type_id_on_box.rs:47:13 | LL | let _ = b.type_id(); | -^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = b.type_id(); = note: if this is intentional, use `TypeId::of::>()` instead, which makes it more clear error: calling `.type_id()` on `Box` - --> tests/ui/type_id_on_box.rs:54:13 + --> tests/ui/type_id_on_box.rs:51:13 | LL | let _ = b.type_id(); | -^^^^^^^^^^ diff --git a/tests/ui/type_id_on_box_unfixable.rs b/tests/ui/type_id_on_box_unfixable.rs index 4df0ebb897a8..58d245d56aa5 100644 --- a/tests/ui/type_id_on_box_unfixable.rs +++ b/tests/ui/type_id_on_box_unfixable.rs @@ -25,9 +25,7 @@ fn main() { let _ = b.type_id(); //~^ type_id_on_box - let b: Box = Box::new(1); let _ = b.type_id(); //~^ type_id_on_box - } diff --git a/tests/ui/type_id_on_box_unfixable.stderr b/tests/ui/type_id_on_box_unfixable.stderr index c653fd7835ff..539ed481ec10 100644 --- a/tests/ui/type_id_on_box_unfixable.stderr +++ b/tests/ui/type_id_on_box_unfixable.stderr @@ -10,7 +10,7 @@ LL | let _ = b.type_id(); = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]` error: calling `.type_id()` on `Box` - --> tests/ui/type_id_on_box_unfixable.rs:30:13 + --> tests/ui/type_id_on_box_unfixable.rs:29:13 | LL | let _ = b.type_id(); | ^^^^^^^^^^^ diff --git a/tests/ui/unbuffered_bytes.rs b/tests/ui/unbuffered_bytes.rs index 82c8839e8391..87199c7e335d 100644 --- a/tests/ui/unbuffered_bytes.rs +++ b/tests/ui/unbuffered_bytes.rs @@ -8,10 +8,12 @@ fn main() { // File is not buffered, should complain let file = File::open("./bytes.txt").unwrap(); file.bytes(); + //~^ unbuffered_bytes // TcpStream is not buffered, should complain let tcp_stream: TcpStream = TcpStream::connect("127.0.0.1:80").unwrap(); tcp_stream.bytes(); + //~^ unbuffered_bytes // BufReader is buffered, should not complain let file = BufReader::new(File::open("./bytes.txt").unwrap()); @@ -24,6 +26,7 @@ fn main() { // Stdio would acquire the lock for every byte, should complain let s: Stdin = stdin(); s.bytes(); + //~^ unbuffered_bytes // But when locking stdin, this is fine so should not complain let s: Stdin = stdin(); @@ -34,4 +37,5 @@ fn main() { fn use_read(r: R) { // Callers of `use_read` may choose a `R` that is not buffered r.bytes(); + //~^ unbuffered_bytes } diff --git a/tests/ui/unbuffered_bytes.stderr b/tests/ui/unbuffered_bytes.stderr index 3303d579fedc..7505eb9e363a 100644 --- a/tests/ui/unbuffered_bytes.stderr +++ b/tests/ui/unbuffered_bytes.stderr @@ -9,7 +9,7 @@ LL | file.bytes(); = help: to override `-D warnings` add `#[allow(clippy::unbuffered_bytes)]` error: calling .bytes() is very inefficient when data is not in memory - --> tests/ui/unbuffered_bytes.rs:14:5 + --> tests/ui/unbuffered_bytes.rs:15:5 | LL | tcp_stream.bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | tcp_stream.bytes(); = help: consider using `BufReader` error: calling .bytes() is very inefficient when data is not in memory - --> tests/ui/unbuffered_bytes.rs:26:5 + --> tests/ui/unbuffered_bytes.rs:28:5 | LL | s.bytes(); | ^^^^^^^^^ @@ -25,7 +25,7 @@ LL | s.bytes(); = help: consider using `BufReader` error: calling .bytes() is very inefficient when data is not in memory - --> tests/ui/unbuffered_bytes.rs:36:5 + --> tests/ui/unbuffered_bytes.rs:39:5 | LL | r.bytes(); | ^^^^^^^^^ diff --git a/tests/ui/unconditional_recursion.rs b/tests/ui/unconditional_recursion.rs index 6cbd6bffb8db..d9f4c07dc902 100644 --- a/tests/ui/unconditional_recursion.rs +++ b/tests/ui/unconditional_recursion.rs @@ -15,12 +15,12 @@ enum Foo { impl PartialEq for Foo { fn ne(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion self != other } fn eq(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion self == other } @@ -33,11 +33,11 @@ enum Foo2 { impl PartialEq for Foo2 { fn ne(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion self != &Foo2::B // no error here } fn eq(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion self == &Foo2::B // no error here } } @@ -49,13 +49,13 @@ enum Foo3 { impl PartialEq for Foo3 { fn ne(&self, other: &Self) -> bool { - //~^ unconditional_recursion - //~| ERROR: function cannot return without recursing + //~^ unconditional_recursion + //~| ERROR: function cannot return without recursing self.ne(other) } fn eq(&self, other: &Self) -> bool { - //~^ unconditional_recursion - //~| ERROR: function cannot return without recursing + //~^ unconditional_recursion + //~| ERROR: function cannot return without recursing self.eq(other) } @@ -100,12 +100,12 @@ struct S; // Check the order doesn't matter. impl PartialEq for S { fn ne(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion other != self } fn eq(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion other == self } @@ -116,13 +116,13 @@ struct S2; // Check that if the same element is compared, it's also triggering the lint. impl PartialEq for S2 { fn ne(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion other != other //~^ eq_op } fn eq(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion other == other //~^ eq_op @@ -133,13 +133,13 @@ struct S3; impl PartialEq for S3 { fn ne(&self, _other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion self != self //~^ eq_op } fn eq(&self, _other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion self == self //~^ eq_op @@ -169,7 +169,7 @@ macro_rules! impl_partial_eq { ($ty:ident) => { impl PartialEq for $ty { fn eq(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion self == other } @@ -199,7 +199,7 @@ struct S7<'a> { impl<'a> PartialEq for S7<'a> { fn eq(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion let mine = &self.field; let theirs = &other.field; @@ -269,7 +269,7 @@ impl std::default::Default for S12 { impl S12 { fn new() -> Self { - //~^ unconditional_recursion + //~^ unconditional_recursion Self::default() } @@ -309,7 +309,7 @@ struct S15<'a> { impl PartialEq for S15<'_> { fn eq(&self, other: &Self) -> bool { - //~^ unconditional_recursion + //~^ unconditional_recursion let mine = &self.field; let theirs = &other.field; @@ -381,7 +381,7 @@ struct BadFromTy1<'a>(&'a ()); struct BadIntoTy1<'b>(&'b ()); impl<'a> From> for BadIntoTy1<'static> { fn from(f: BadFromTy1<'a>) -> Self { - //~^ unconditional_recursion + //~^ unconditional_recursion f.into() } } @@ -391,7 +391,7 @@ struct BadFromTy2<'a>(&'a ()); struct BadIntoTy2<'b>(&'b ()); impl<'a> From> for BadIntoTy2<'static> { fn from(f: BadFromTy2<'a>) -> Self { - //~^ unconditional_recursion + //~^ unconditional_recursion Into::into(f) } } diff --git a/tests/ui/uninhabited_references.rs b/tests/ui/uninhabited_references.rs index 649af4312ce4..9b3616ad5187 100644 --- a/tests/ui/uninhabited_references.rs +++ b/tests/ui/uninhabited_references.rs @@ -3,14 +3,14 @@ #![feature(never_type)] fn ret_uninh_ref() -> &'static std::convert::Infallible { -//~^ uninhabited_references + //~^ uninhabited_references unsafe { std::mem::transmute(&()) } } macro_rules! ret_something { ($name:ident, $ty:ty) => { fn $name(x: &$ty) -> &$ty { - //~^ uninhabited_references + //~^ uninhabited_references &*x //~^ uninhabited_references } diff --git a/tests/ui/uninit.rs b/tests/ui/uninit.rs index 965ef4a10b39..f74248c8aea8 100644 --- a/tests/ui/uninit.rs +++ b/tests/ui/uninit.rs @@ -12,8 +12,6 @@ fn main() { let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; //~^ uninit_assumed_init - - // This is OK, because ZSTs do not contain data. let _: () = unsafe { MaybeUninit::uninit().assume_init() }; @@ -36,7 +34,6 @@ fn main() { let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; //~^ uninit_assumed_init - polymorphic::<()>(); polymorphic_maybe_uninit_array::<10>(); polymorphic_maybe_uninit::(); @@ -45,7 +42,6 @@ fn main() { // We are conservative around polymorphic types. let _: T = unsafe { MaybeUninit::uninit().assume_init() }; //~^ uninit_assumed_init - } fn polymorphic_maybe_uninit_array() { diff --git a/tests/ui/uninit.stderr b/tests/ui/uninit.stderr index 9179a2b28dbb..d6f54dd61ca0 100644 --- a/tests/ui/uninit.stderr +++ b/tests/ui/uninit.stderr @@ -7,13 +7,13 @@ LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; = note: `#[deny(clippy::uninit_assumed_init)]` on by default error: this call for this type may be undefined behavior - --> tests/ui/uninit.rs:36:29 + --> tests/ui/uninit.rs:34:29 | LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call for this type may be undefined behavior - --> tests/ui/uninit.rs:46:29 + --> tests/ui/uninit.rs:43:29 | LL | let _: T = unsafe { MaybeUninit::uninit().assume_init() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/uninlined_format_args.fixed b/tests/ui/uninlined_format_args.fixed index 444a5b1cfb5f..6db094babb24 100644 --- a/tests/ui/uninlined_format_args.fixed +++ b/tests/ui/uninlined_format_args.fixed @@ -53,7 +53,7 @@ fn tester(fn_arg: i32) { println!("val='{local_i32}'"); // tab+space //~^ uninlined_format_args println!( - //~^ uninlined_format_args + //~^ uninlined_format_args "val='{local_i32}'" ); println!("{local_i32}"); @@ -173,7 +173,7 @@ fn tester(fn_arg: i32) { println!("{local_f64:width$.prec$} {local_f64} {width} {prec}"); //~^ uninlined_format_args println!( - //~^ uninlined_format_args + //~^ uninlined_format_args "{local_i32:width$.prec$} {local_i32:prec$.width$} {width:local_i32$.prec$} {width:prec$.local_i32$} {prec:local_i32$.width$} {prec:width$.local_i32$}", ); println!( @@ -208,7 +208,7 @@ fn tester(fn_arg: i32) { println!(no_param_str!(), local_i32); println!( - //~^ uninlined_format_args + //~^ uninlined_format_args "{val}", ); println!("{val}"); diff --git a/tests/ui/uninlined_format_args.rs b/tests/ui/uninlined_format_args.rs index 526fd98dfa4b..7ca61b800219 100644 --- a/tests/ui/uninlined_format_args.rs +++ b/tests/ui/uninlined_format_args.rs @@ -53,7 +53,7 @@ fn tester(fn_arg: i32) { println!("val='{ }'", local_i32); // tab+space //~^ uninlined_format_args println!( - //~^ uninlined_format_args + //~^ uninlined_format_args "val='{ }'", local_i32 @@ -175,7 +175,7 @@ fn tester(fn_arg: i32) { println!("{:1$.2$} {0} {1} {2}", local_f64, width, prec); //~^ uninlined_format_args println!( - //~^ uninlined_format_args + //~^ uninlined_format_args "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}", local_i32, width, prec, ); @@ -211,7 +211,7 @@ fn tester(fn_arg: i32) { println!(no_param_str!(), local_i32); println!( - //~^ uninlined_format_args + //~^ uninlined_format_args "{}", // comment with a comma , in it val, diff --git a/tests/ui/unit_arg.rs b/tests/ui/unit_arg.rs index 3a3962d09143..22a6a26dab62 100644 --- a/tests/ui/unit_arg.rs +++ b/tests/ui/unit_arg.rs @@ -61,30 +61,30 @@ impl Tr for B { fn bad() { foo({ - //~^ unit_arg + //~^ unit_arg 1; }); foo(foo(1)); //~^ unit_arg foo({ - //~^ unit_arg + //~^ unit_arg foo(1); foo(2); }); let b = Bar; b.bar({ - //~^ unit_arg + //~^ unit_arg 1; }); taking_multiple_units(foo(0), foo(1)); //~^ unit_arg taking_multiple_units(foo(0), { - //~^ unit_arg + //~^ unit_arg foo(1); foo(2); }); taking_multiple_units( - //~^ unit_arg + //~^ unit_arg { foo(0); foo(1); diff --git a/tests/ui/unit_cmp.rs b/tests/ui/unit_cmp.rs index 0b1cccfbadf6..93f5b87c3d2a 100644 --- a/tests/ui/unit_cmp.rs +++ b/tests/ui/unit_cmp.rs @@ -15,8 +15,7 @@ fn main() { // this warns if { - //~^ unit_cmp - + //~^ unit_cmp true; } == { @@ -24,7 +23,7 @@ fn main() { } {} if { - //~^ unit_cmp + //~^ unit_cmp true; } > { @@ -32,8 +31,7 @@ fn main() { } {} assert_eq!( - //~^ unit_cmp - + //~^ unit_cmp { true; }, @@ -42,8 +40,7 @@ fn main() { } ); debug_assert_eq!( - //~^ unit_cmp - + //~^ unit_cmp { true; }, @@ -53,8 +50,7 @@ fn main() { ); assert_ne!( - //~^ unit_cmp - + //~^ unit_cmp { true; }, @@ -63,8 +59,7 @@ fn main() { } ); debug_assert_ne!( - //~^ unit_cmp - + //~^ unit_cmp { true; }, diff --git a/tests/ui/unit_cmp.stderr b/tests/ui/unit_cmp.stderr index 0c485edd9736..8f26749fd860 100644 --- a/tests/ui/unit_cmp.stderr +++ b/tests/ui/unit_cmp.stderr @@ -3,7 +3,10 @@ error: ==-comparison of unit values detected. This will always be true | LL | if { | ________^ -... | +LL | | +LL | | +LL | | true; +LL | | } == { LL | | false; LL | | } {} | |_____^ @@ -12,7 +15,7 @@ LL | | } {} = help: to override `-D warnings` add `#[allow(clippy::unit_cmp)]` error: >-comparison of unit values detected. This will always be false - --> tests/ui/unit_cmp.rs:26:8 + --> tests/ui/unit_cmp.rs:25:8 | LL | if { | ________^ @@ -25,33 +28,45 @@ LL | | } {} | |_____^ error: `assert_eq` of unit values detected. This will always succeed - --> tests/ui/unit_cmp.rs:34:5 + --> tests/ui/unit_cmp.rs:33:5 | LL | / assert_eq!( +LL | | +LL | | { +LL | | true; ... | LL | | ); | |_____^ error: `debug_assert_eq` of unit values detected. This will always succeed - --> tests/ui/unit_cmp.rs:44:5 + --> tests/ui/unit_cmp.rs:42:5 | LL | / debug_assert_eq!( +LL | | +LL | | { +LL | | true; ... | LL | | ); | |_____^ error: `assert_ne` of unit values detected. This will always fail - --> tests/ui/unit_cmp.rs:55:5 + --> tests/ui/unit_cmp.rs:52:5 | LL | / assert_ne!( +LL | | +LL | | { +LL | | true; ... | LL | | ); | |_____^ error: `debug_assert_ne` of unit values detected. This will always fail - --> tests/ui/unit_cmp.rs:65:5 + --> tests/ui/unit_cmp.rs:61:5 | LL | / debug_assert_ne!( +LL | | +LL | | { +LL | | true; ... | LL | | ); | |_____^ diff --git a/tests/ui/unit_hash.fixed b/tests/ui/unit_hash.fixed index 4df67c783d32..25c90e6ddc4c 100644 --- a/tests/ui/unit_hash.fixed +++ b/tests/ui/unit_hash.fixed @@ -18,8 +18,6 @@ fn main() { match my_enum { Foo::Empty => 0_u8.hash(&mut state), //~^ unit_hash - - Foo::WithValue(x) => x.hash(&mut state), } @@ -27,11 +25,7 @@ fn main() { 0_u8.hash(&mut state); //~^ unit_hash - - #[allow(clippy::unit_arg)] 0_u8.hash(&mut state); //~^ unit_hash - - } diff --git a/tests/ui/unit_hash.rs b/tests/ui/unit_hash.rs index 15f27aab95e1..b04cca6adf2a 100644 --- a/tests/ui/unit_hash.rs +++ b/tests/ui/unit_hash.rs @@ -18,8 +18,6 @@ fn main() { match my_enum { Foo::Empty => ().hash(&mut state), //~^ unit_hash - - Foo::WithValue(x) => x.hash(&mut state), } @@ -27,11 +25,7 @@ fn main() { res.hash(&mut state); //~^ unit_hash - - #[allow(clippy::unit_arg)] do_nothing().hash(&mut state); //~^ unit_hash - - } diff --git a/tests/ui/unit_hash.stderr b/tests/ui/unit_hash.stderr index be019d398b58..d1cabf89f8e7 100644 --- a/tests/ui/unit_hash.stderr +++ b/tests/ui/unit_hash.stderr @@ -9,7 +9,7 @@ LL | Foo::Empty => ().hash(&mut state), = help: to override `-D warnings` add `#[allow(clippy::unit_hash)]` error: this call to `hash` on the unit type will do nothing - --> tests/ui/unit_hash.rs:27:5 + --> tests/ui/unit_hash.rs:25:5 | LL | res.hash(&mut state); | ^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)` @@ -17,7 +17,7 @@ LL | res.hash(&mut state); = note: the implementation of `Hash` for `()` is a no-op error: this call to `hash` on the unit type will do nothing - --> tests/ui/unit_hash.rs:33:5 + --> tests/ui/unit_hash.rs:29:5 | LL | do_nothing().hash(&mut state); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)` diff --git a/tests/ui/unit_return_expecting_ord.rs b/tests/ui/unit_return_expecting_ord.rs index 3585eb5395db..74cd30472684 100644 --- a/tests/ui/unit_return_expecting_ord.rs +++ b/tests/ui/unit_return_expecting_ord.rs @@ -16,18 +16,18 @@ fn unit(_i: isize) {} fn main() { let mut structs = vec![Struct { field: 2 }, Struct { field: 1 }]; structs.sort_by_key(|s| { - //~^ unit_return_expecting_ord + //~^ unit_return_expecting_ord double(s.field); }); structs.sort_by_key(|s| double(s.field)); structs.is_sorted_by_key(|s| { - //~^ unit_return_expecting_ord + //~^ unit_return_expecting_ord double(s.field); }); structs.is_sorted_by_key(|s| { - //~^ unit_return_expecting_ord + //~^ unit_return_expecting_ord if s.field > 0 { () @@ -40,5 +40,4 @@ fn main() { }); structs.sort_by_key(|s| unit(s.field)); //~^ unit_return_expecting_ord - } diff --git a/tests/ui/unnecessary_box_returns.rs b/tests/ui/unnecessary_box_returns.rs index 5037c05a0acb..a7ab7e90be06 100644 --- a/tests/ui/unnecessary_box_returns.rs +++ b/tests/ui/unnecessary_box_returns.rs @@ -4,7 +4,6 @@ trait Bar { // lint fn baz(&self) -> Box; //~^ unnecessary_box_returns - } pub struct Foo {} @@ -18,7 +17,7 @@ impl Bar for Foo { impl Foo { fn baz(&self) -> Box { - //~^ unnecessary_box_returns + //~^ unnecessary_box_returns // lint Box::new(13) @@ -27,14 +26,14 @@ impl Foo { // lint fn bxed_usize() -> Box { -//~^ unnecessary_box_returns + //~^ unnecessary_box_returns Box::new(5) } // lint fn _bxed_foo() -> Box { -//~^ unnecessary_box_returns + //~^ unnecessary_box_returns Box::new(Foo {}) } diff --git a/tests/ui/unnecessary_box_returns.stderr b/tests/ui/unnecessary_box_returns.stderr index 9df056569a29..ab1d90f13b92 100644 --- a/tests/ui/unnecessary_box_returns.stderr +++ b/tests/ui/unnecessary_box_returns.stderr @@ -9,7 +9,7 @@ LL | fn baz(&self) -> Box; = help: to override `-D warnings` add `#[allow(clippy::unnecessary_box_returns)]` error: boxed return of the sized type `usize` - --> tests/ui/unnecessary_box_returns.rs:20:22 + --> tests/ui/unnecessary_box_returns.rs:19:22 | LL | fn baz(&self) -> Box { | ^^^^^^^^^^ help: try: `usize` @@ -17,7 +17,7 @@ LL | fn baz(&self) -> Box { = help: changing this also requires a change to the return expressions in this function error: boxed return of the sized type `usize` - --> tests/ui/unnecessary_box_returns.rs:29:20 + --> tests/ui/unnecessary_box_returns.rs:28:20 | LL | fn bxed_usize() -> Box { | ^^^^^^^^^^ help: try: `usize` @@ -25,7 +25,7 @@ LL | fn bxed_usize() -> Box { = help: changing this also requires a change to the return expressions in this function error: boxed return of the sized type `Foo` - --> tests/ui/unnecessary_box_returns.rs:36:19 + --> tests/ui/unnecessary_box_returns.rs:35:19 | LL | fn _bxed_foo() -> Box { | ^^^^^^^^ help: try: `Foo` diff --git a/tests/ui/unnecessary_cast_unfixable.rs b/tests/ui/unnecessary_cast_unfixable.rs index 05dd20c7a114..2bb64c3e80e3 100644 --- a/tests/ui/unnecessary_cast_unfixable.rs +++ b/tests/ui/unnecessary_cast_unfixable.rs @@ -3,8 +3,6 @@ fn main() { let _ = std::ptr::null() as *const u8; //~^ unnecessary_cast - - } mod issue11113 { @@ -21,7 +19,6 @@ mod issue11113 { unsafe fn query(&self) { ((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)() //~^ unnecessary_cast - } } } diff --git a/tests/ui/unnecessary_cast_unfixable.stderr b/tests/ui/unnecessary_cast_unfixable.stderr index 0047b38850b7..6ba1c7873066 100644 --- a/tests/ui/unnecessary_cast_unfixable.stderr +++ b/tests/ui/unnecessary_cast_unfixable.stderr @@ -8,7 +8,7 @@ LL | let _ = std::ptr::null() as *const u8; = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]` error: casting raw pointers to the same type and constness is unnecessary (`*mut issue11113::Vtbl` -> `*mut issue11113::Vtbl`) - --> tests/ui/unnecessary_cast_unfixable.rs:22:16 + --> tests/ui/unnecessary_cast_unfixable.rs:20:16 | LL | ((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `*(self.object as *mut *mut _)` diff --git a/tests/ui/unnecessary_clippy_cfg.rs b/tests/ui/unnecessary_clippy_cfg.rs index 406c0133c5d3..e7e01248dfbe 100644 --- a/tests/ui/unnecessary_clippy_cfg.rs +++ b/tests/ui/unnecessary_clippy_cfg.rs @@ -3,28 +3,21 @@ #![warn(clippy::unnecessary_clippy_cfg)] #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] //~^ unnecessary_clippy_cfg - #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] //~^ unnecessary_clippy_cfg - #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] //~^ unnecessary_clippy_cfg //~| duplicated_attributes - #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] //~^ unnecessary_clippy_cfg - #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] //~^ unnecessary_clippy_cfg - #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] //~^ unnecessary_clippy_cfg - #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] //~^ unnecessary_clippy_cfg //~| duplicated_attributes - #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] //~^ unnecessary_clippy_cfg diff --git a/tests/ui/unnecessary_clippy_cfg.stderr b/tests/ui/unnecessary_clippy_cfg.stderr index f6f36fbf2baa..f66c68949548 100644 --- a/tests/ui/unnecessary_clippy_cfg.stderr +++ b/tests/ui/unnecessary_clippy_cfg.stderr @@ -8,7 +8,7 @@ LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] = help: to override `-D warnings` add `#[allow(clippy::unnecessary_clippy_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:7:37 + --> tests/ui/unnecessary_clippy_cfg.rs:6:37 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = note: write instead: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:10:37 + --> tests/ui/unnecessary_clippy_cfg.rs:8:37 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,19 +24,19 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = note: write instead: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:14:1 + --> tests/ui/unnecessary_clippy_cfg.rs:11:1 | LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:18:1 + --> tests/ui/unnecessary_clippy_cfg.rs:14:1 | LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:21:36 + --> tests/ui/unnecessary_clippy_cfg.rs:16:36 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = note: write instead: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:24:36 + --> tests/ui/unnecessary_clippy_cfg.rs:18:36 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,24 +52,24 @@ LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = note: write instead: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:28:1 + --> tests/ui/unnecessary_clippy_cfg.rs:21:1 | LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]` error: duplicated attribute - --> tests/ui/unnecessary_clippy_cfg.rs:10:26 + --> tests/ui/unnecessary_clippy_cfg.rs:8:26 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ | note: first defined here - --> tests/ui/unnecessary_clippy_cfg.rs:7:26 + --> tests/ui/unnecessary_clippy_cfg.rs:6:26 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ help: remove this attribute - --> tests/ui/unnecessary_clippy_cfg.rs:10:26 + --> tests/ui/unnecessary_clippy_cfg.rs:8:26 | LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ @@ -77,18 +77,18 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]` error: duplicated attribute - --> tests/ui/unnecessary_clippy_cfg.rs:24:25 + --> tests/ui/unnecessary_clippy_cfg.rs:18:25 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ | note: first defined here - --> tests/ui/unnecessary_clippy_cfg.rs:21:25 + --> tests/ui/unnecessary_clippy_cfg.rs:16:25 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ help: remove this attribute - --> tests/ui/unnecessary_clippy_cfg.rs:24:25 + --> tests/ui/unnecessary_clippy_cfg.rs:18:25 | LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ diff --git a/tests/ui/unnecessary_clone.rs b/tests/ui/unnecessary_clone.rs index 3ce7c7ef0252..7335b6f9f039 100644 --- a/tests/ui/unnecessary_clone.rs +++ b/tests/ui/unnecessary_clone.rs @@ -23,7 +23,6 @@ fn clone_on_ref_ptr() { rc.clone(); //~^ clone_on_ref_ptr - Rc::clone(&rc); arc.clone(); @@ -44,18 +43,14 @@ fn clone_on_ref_ptr() { let x = Arc::new(SomeImpl); let _: Arc = x.clone(); //~^ clone_on_ref_ptr - } fn clone_on_copy_generic(t: T) { t.clone(); //~^ clone_on_copy - - Some(t).clone(); //~^ clone_on_copy - } mod many_derefs { @@ -112,6 +107,5 @@ mod issue2076 { let rc = Rc::new(42); Some(try_opt!(Some(rc)).clone()) //~^ clone_on_ref_ptr - } } diff --git a/tests/ui/unnecessary_clone.stderr b/tests/ui/unnecessary_clone.stderr index cf508eb4c645..a4fdf09cd5dc 100644 --- a/tests/ui/unnecessary_clone.stderr +++ b/tests/ui/unnecessary_clone.stderr @@ -8,31 +8,31 @@ LL | rc.clone(); = help: to override `-D warnings` add `#[allow(clippy::clone_on_ref_ptr)]` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:29:5 + --> tests/ui/unnecessary_clone.rs:28:5 | LL | arc.clone(); | ^^^^^^^^^^^ help: try: `Arc::::clone(&arc)` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:34:5 + --> tests/ui/unnecessary_clone.rs:33:5 | LL | rcweak.clone(); | ^^^^^^^^^^^^^^ help: try: `Weak::::clone(&rcweak)` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:39:5 + --> tests/ui/unnecessary_clone.rs:38:5 | LL | arc_weak.clone(); | ^^^^^^^^^^^^^^^^ help: try: `Weak::::clone(&arc_weak)` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:45:33 + --> tests/ui/unnecessary_clone.rs:44:33 | LL | let _: Arc = x.clone(); | ^^^^^^^^^ help: try: `Arc::::clone(&x)` error: using `clone` on type `T` which implements the `Copy` trait - --> tests/ui/unnecessary_clone.rs:51:5 + --> tests/ui/unnecessary_clone.rs:49:5 | LL | t.clone(); | ^^^^^^^^^ help: try removing the `clone` call: `t` @@ -41,19 +41,19 @@ LL | t.clone(); = help: to override `-D warnings` add `#[allow(clippy::clone_on_copy)]` error: using `clone` on type `Option` which implements the `Copy` trait - --> tests/ui/unnecessary_clone.rs:56:5 + --> tests/ui/unnecessary_clone.rs:52:5 | LL | Some(t).clone(); | ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)` error: using `clone` on type `E` which implements the `Copy` trait - --> tests/ui/unnecessary_clone.rs:92:20 + --> tests/ui/unnecessary_clone.rs:87:20 | LL | let _: E = a.clone(); | ^^^^^^^^^ help: try dereferencing it: `*****a` error: using `.clone()` on a ref-counted pointer - --> tests/ui/unnecessary_clone.rs:113:14 + --> tests/ui/unnecessary_clone.rs:108:14 | LL | Some(try_opt!(Some(rc)).clone()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Rc::::clone(&try_opt!(Some(rc)))` diff --git a/tests/ui/unnecessary_fallible_conversions.fixed b/tests/ui/unnecessary_fallible_conversions.fixed index 59d24e9bb7e2..bae8f066cf12 100644 --- a/tests/ui/unnecessary_fallible_conversions.fixed +++ b/tests/ui/unnecessary_fallible_conversions.fixed @@ -6,48 +6,38 @@ fn main() { let _: i64 = 0i32.into(); //~^ unnecessary_fallible_conversions - let _: i64 = 0i32.into(); //~^ unnecessary_fallible_conversions - // --- TryFromFunction `T::try_from(U)` --- let _ = i64::from(0i32); //~^ unnecessary_fallible_conversions - let _ = i64::from(0i32); //~^ unnecessary_fallible_conversions - // --- TryIntoFunction `U::try_into(t)` --- let _: i64 = i32::into(0); //~^ unnecessary_fallible_conversions - let _: i64 = i32::into(0i32); //~^ unnecessary_fallible_conversions - // --- TryFromFunction `>::try_from(U)` --- let _ = >::from(0); //~^ unnecessary_fallible_conversions - let _ = >::from(0); //~^ unnecessary_fallible_conversions - // --- TryIntoFunction `>::try_into(U)` --- let _: i64 = >::into(0); //~^ unnecessary_fallible_conversions - let _: i64 = >::into(0); //~^ unnecessary_fallible_conversions - } diff --git a/tests/ui/unnecessary_fallible_conversions.rs b/tests/ui/unnecessary_fallible_conversions.rs index 7e504acb5e21..04c9826f3765 100644 --- a/tests/ui/unnecessary_fallible_conversions.rs +++ b/tests/ui/unnecessary_fallible_conversions.rs @@ -6,48 +6,38 @@ fn main() { let _: i64 = 0i32.try_into().unwrap(); //~^ unnecessary_fallible_conversions - let _: i64 = 0i32.try_into().expect("can't happen"); //~^ unnecessary_fallible_conversions - // --- TryFromFunction `T::try_from(U)` --- let _ = i64::try_from(0i32).unwrap(); //~^ unnecessary_fallible_conversions - let _ = i64::try_from(0i32).expect("can't happen"); //~^ unnecessary_fallible_conversions - // --- TryIntoFunction `U::try_into(t)` --- let _: i64 = i32::try_into(0).unwrap(); //~^ unnecessary_fallible_conversions - let _: i64 = i32::try_into(0i32).expect("can't happen"); //~^ unnecessary_fallible_conversions - // --- TryFromFunction `>::try_from(U)` --- let _ = >::try_from(0).unwrap(); //~^ unnecessary_fallible_conversions - let _ = >::try_from(0).expect("can't happen"); //~^ unnecessary_fallible_conversions - // --- TryIntoFunction `>::try_into(U)` --- let _: i64 = >::try_into(0).unwrap(); //~^ unnecessary_fallible_conversions - let _: i64 = >::try_into(0).expect("can't happen"); //~^ unnecessary_fallible_conversions - } diff --git a/tests/ui/unnecessary_fallible_conversions.stderr b/tests/ui/unnecessary_fallible_conversions.stderr index 160917694c44..ade3aada9289 100644 --- a/tests/ui/unnecessary_fallible_conversions.stderr +++ b/tests/ui/unnecessary_fallible_conversions.stderr @@ -14,7 +14,7 @@ LL + let _: i64 = 0i32.into(); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:10:23 + --> tests/ui/unnecessary_fallible_conversions.rs:9:23 | LL | let _: i64 = 0i32.try_into().expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL + let _: i64 = 0i32.into(); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:16:13 + --> tests/ui/unnecessary_fallible_conversions.rs:14:13 | LL | let _ = i64::try_from(0i32).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL + let _ = i64::from(0i32); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:20:13 + --> tests/ui/unnecessary_fallible_conversions.rs:17:13 | LL | let _ = i64::try_from(0i32).expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ LL + let _ = i64::from(0i32); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:26:18 + --> tests/ui/unnecessary_fallible_conversions.rs:22:18 | LL | let _: i64 = i32::try_into(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL + let _: i64 = i32::into(0); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:30:18 + --> tests/ui/unnecessary_fallible_conversions.rs:25:18 | LL | let _: i64 = i32::try_into(0i32).expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,7 +79,7 @@ LL + let _: i64 = i32::into(0i32); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:36:13 + --> tests/ui/unnecessary_fallible_conversions.rs:30:13 | LL | let _ = >::try_from(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL + let _ = >::from(0); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:40:13 + --> tests/ui/unnecessary_fallible_conversions.rs:33:13 | LL | let _ = >::try_from(0).expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL + let _ = >::from(0); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:46:18 + --> tests/ui/unnecessary_fallible_conversions.rs:38:18 | LL | let _: i64 = >::try_into(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL + let _: i64 = >::into(0); | error: use of a fallible conversion when an infallible one could be used - --> tests/ui/unnecessary_fallible_conversions.rs:50:18 + --> tests/ui/unnecessary_fallible_conversions.rs:41:18 | LL | let _: i64 = >::try_into(0).expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_filter_map.rs b/tests/ui/unnecessary_filter_map.rs index e05161d207ec..c4f1b6bc7e3d 100644 --- a/tests/ui/unnecessary_filter_map.rs +++ b/tests/ui/unnecessary_filter_map.rs @@ -5,9 +5,8 @@ fn main() { let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None }); //~^ unnecessary_filter_map - let _ = (0..4).filter_map(|x| { - //~^ unnecessary_filter_map + //~^ unnecessary_filter_map if x > 1 { return Some(x); @@ -15,8 +14,7 @@ fn main() { None }); let _ = (0..4).filter_map(|x| match x { - //~^ unnecessary_filter_map - + //~^ unnecessary_filter_map 0 | 1 => None, _ => Some(x), }); @@ -24,7 +22,6 @@ fn main() { let _ = (0..4).filter_map(|x| Some(x + 1)); //~^ unnecessary_filter_map - let _ = (0..4).filter_map(i32::checked_abs); let _ = (0..4).filter_map(Some); diff --git a/tests/ui/unnecessary_filter_map.stderr b/tests/ui/unnecessary_filter_map.stderr index 94435ab3effd..6683444b7273 100644 --- a/tests/ui/unnecessary_filter_map.stderr +++ b/tests/ui/unnecessary_filter_map.stderr @@ -8,7 +8,7 @@ LL | let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None }); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_filter_map)]` error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:9:13 + --> tests/ui/unnecessary_filter_map.rs:8:13 | LL | let _ = (0..4).filter_map(|x| { | _____________^ @@ -21,25 +21,24 @@ LL | | }); | |______^ help: try instead: `filter` error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:17:13 + --> tests/ui/unnecessary_filter_map.rs:16:13 | LL | let _ = (0..4).filter_map(|x| match x { | _____________^ LL | | -LL | | LL | | 0 | 1 => None, LL | | _ => Some(x), LL | | }); | |______^ help: try instead: `filter` error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:24:13 + --> tests/ui/unnecessary_filter_map.rs:22:13 | LL | let _ = (0..4).filter_map(|x| Some(x + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map` error: redundant closure - --> tests/ui/unnecessary_filter_map.rs:32:57 + --> tests/ui/unnecessary_filter_map.rs:29:57 | LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); | ^^^^^^^^^^^ help: replace the closure with the function itself: `Some` @@ -48,19 +47,19 @@ LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]` error: filter_map is unnecessary - --> tests/ui/unnecessary_filter_map.rs:32:61 + --> tests/ui/unnecessary_filter_map.rs:29:61 | LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); | ^^^^ help: try removing the filter_map error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:32:13 + --> tests/ui/unnecessary_filter_map.rs:29:13 | LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map` error: this `.filter_map` can be written more simply - --> tests/ui/unnecessary_filter_map.rs:172:14 + --> tests/ui/unnecessary_filter_map.rs:169:14 | LL | let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `filter` diff --git a/tests/ui/unnecessary_find_map.rs b/tests/ui/unnecessary_find_map.rs index f883b4eb38c5..8c8a3799f021 100644 --- a/tests/ui/unnecessary_find_map.rs +++ b/tests/ui/unnecessary_find_map.rs @@ -5,9 +5,8 @@ fn main() { let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None }); //~^ unnecessary_find_map - let _ = (0..4).find_map(|x| { - //~^ unnecessary_find_map + //~^ unnecessary_find_map if x > 1 { return Some(x); @@ -15,8 +14,7 @@ fn main() { None }); let _ = (0..4).find_map(|x| match x { - //~^ unnecessary_find_map - + //~^ unnecessary_find_map 0 | 1 => None, _ => Some(x), }); @@ -24,7 +22,6 @@ fn main() { let _ = (0..4).find_map(|x| Some(x + 1)); //~^ unnecessary_find_map - let _ = (0..4).find_map(i32::checked_abs); } diff --git a/tests/ui/unnecessary_find_map.stderr b/tests/ui/unnecessary_find_map.stderr index 079c1092784e..94e320773a6f 100644 --- a/tests/ui/unnecessary_find_map.stderr +++ b/tests/ui/unnecessary_find_map.stderr @@ -8,7 +8,7 @@ LL | let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None }); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_find_map)]` error: this `.find_map` can be written more simply - --> tests/ui/unnecessary_find_map.rs:9:13 + --> tests/ui/unnecessary_find_map.rs:8:13 | LL | let _ = (0..4).find_map(|x| { | _____________^ @@ -21,25 +21,24 @@ LL | | }); | |______^ help: try instead: `find` error: this `.find_map` can be written more simply - --> tests/ui/unnecessary_find_map.rs:17:13 + --> tests/ui/unnecessary_find_map.rs:16:13 | LL | let _ = (0..4).find_map(|x| match x { | _____________^ LL | | -LL | | LL | | 0 | 1 => None, LL | | _ => Some(x), LL | | }); | |______^ help: try instead: `find` error: this `.find_map` can be written more simply - --> tests/ui/unnecessary_find_map.rs:24:13 + --> tests/ui/unnecessary_find_map.rs:22:13 | LL | let _ = (0..4).find_map(|x| Some(x + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map(..).next()` error: this `.find_map` can be written more simply - --> tests/ui/unnecessary_find_map.rs:37:14 + --> tests/ui/unnecessary_find_map.rs:34:14 | LL | let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `find` diff --git a/tests/ui/unnecessary_fold.fixed b/tests/ui/unnecessary_fold.fixed index 2c3f87513c40..1c331be75094 100644 --- a/tests/ui/unnecessary_fold.fixed +++ b/tests/ui/unnecessary_fold.fixed @@ -57,7 +57,7 @@ fn unnecessary_fold_over_multiple_lines() { .map(|x| x + 1) .filter(|x| x % 2 == 0) .any(|x| x > 2); - //~^ unnecessary_fold + //~^ unnecessary_fold } fn issue10000() { diff --git a/tests/ui/unnecessary_fold.rs b/tests/ui/unnecessary_fold.rs index 954020046763..e2050e37e3b1 100644 --- a/tests/ui/unnecessary_fold.rs +++ b/tests/ui/unnecessary_fold.rs @@ -57,7 +57,7 @@ fn unnecessary_fold_over_multiple_lines() { .map(|x| x + 1) .filter(|x| x % 2 == 0) .fold(false, |acc, x| acc || x > 2); - //~^ unnecessary_fold + //~^ unnecessary_fold } fn issue10000() { diff --git a/tests/ui/unnecessary_get_then_check.fixed b/tests/ui/unnecessary_get_then_check.fixed index 6aba66b87318..c6da769544e0 100644 --- a/tests/ui/unnecessary_get_then_check.fixed +++ b/tests/ui/unnecessary_get_then_check.fixed @@ -4,33 +4,33 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; fn main() { let s: HashSet = HashSet::new(); -let _ = s.contains("a"); -//~^ unnecessary_get_then_check -let _ = !s.contains("a"); -//~^ unnecessary_get_then_check + let _ = s.contains("a"); + //~^ unnecessary_get_then_check + let _ = !s.contains("a"); + //~^ unnecessary_get_then_check let s: HashMap = HashMap::new(); -let _ = s.contains_key("a"); -//~^ unnecessary_get_then_check -let _ = !s.contains_key("a"); -//~^ unnecessary_get_then_check + let _ = s.contains_key("a"); + //~^ unnecessary_get_then_check + let _ = !s.contains_key("a"); + //~^ unnecessary_get_then_check let s: BTreeSet = BTreeSet::new(); -let _ = s.contains("a"); -//~^ unnecessary_get_then_check -let _ = !s.contains("a"); -//~^ unnecessary_get_then_check + let _ = s.contains("a"); + //~^ unnecessary_get_then_check + let _ = !s.contains("a"); + //~^ unnecessary_get_then_check let s: BTreeMap = BTreeMap::new(); -let _ = s.contains_key("a"); -//~^ unnecessary_get_then_check -let _ = !s.contains_key("a"); -//~^ unnecessary_get_then_check + let _ = s.contains_key("a"); + //~^ unnecessary_get_then_check + let _ = !s.contains_key("a"); + //~^ unnecessary_get_then_check // Import to check that the generic annotations are kept! let s: HashSet = HashSet::new(); -let _ = s.contains::("a"); -//~^ unnecessary_get_then_check -let _ = !s.contains::("a"); -//~^ unnecessary_get_then_check + let _ = s.contains::("a"); + //~^ unnecessary_get_then_check + let _ = !s.contains::("a"); + //~^ unnecessary_get_then_check } diff --git a/tests/ui/unnecessary_get_then_check.rs b/tests/ui/unnecessary_get_then_check.rs index d56e7d209e4e..323ccc2136ce 100644 --- a/tests/ui/unnecessary_get_then_check.rs +++ b/tests/ui/unnecessary_get_then_check.rs @@ -4,33 +4,33 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; fn main() { let s: HashSet = HashSet::new(); -let _ = s.get("a").is_some(); -//~^ unnecessary_get_then_check -let _ = s.get("a").is_none(); -//~^ unnecessary_get_then_check + let _ = s.get("a").is_some(); + //~^ unnecessary_get_then_check + let _ = s.get("a").is_none(); + //~^ unnecessary_get_then_check let s: HashMap = HashMap::new(); -let _ = s.get("a").is_some(); -//~^ unnecessary_get_then_check -let _ = s.get("a").is_none(); -//~^ unnecessary_get_then_check + let _ = s.get("a").is_some(); + //~^ unnecessary_get_then_check + let _ = s.get("a").is_none(); + //~^ unnecessary_get_then_check let s: BTreeSet = BTreeSet::new(); -let _ = s.get("a").is_some(); -//~^ unnecessary_get_then_check -let _ = s.get("a").is_none(); -//~^ unnecessary_get_then_check + let _ = s.get("a").is_some(); + //~^ unnecessary_get_then_check + let _ = s.get("a").is_none(); + //~^ unnecessary_get_then_check let s: BTreeMap = BTreeMap::new(); -let _ = s.get("a").is_some(); -//~^ unnecessary_get_then_check -let _ = s.get("a").is_none(); -//~^ unnecessary_get_then_check + let _ = s.get("a").is_some(); + //~^ unnecessary_get_then_check + let _ = s.get("a").is_none(); + //~^ unnecessary_get_then_check // Import to check that the generic annotations are kept! let s: HashSet = HashSet::new(); -let _ = s.get::("a").is_some(); -//~^ unnecessary_get_then_check -let _ = s.get::("a").is_none(); -//~^ unnecessary_get_then_check + let _ = s.get::("a").is_some(); + //~^ unnecessary_get_then_check + let _ = s.get::("a").is_none(); + //~^ unnecessary_get_then_check } diff --git a/tests/ui/unnecessary_get_then_check.stderr b/tests/ui/unnecessary_get_then_check.stderr index a33409b30c80..5ecb3d4e29dd 100644 --- a/tests/ui/unnecessary_get_then_check.stderr +++ b/tests/ui/unnecessary_get_then_check.stderr @@ -1,75 +1,75 @@ error: unnecessary use of `get("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:7:11 + --> tests/ui/unnecessary_get_then_check.rs:7:15 | -LL | let _ = s.get("a").is_some(); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains("a")` +LL | let _ = s.get("a").is_some(); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains("a")` | = note: `-D clippy::unnecessary-get-then-check` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_get_then_check)]` error: unnecessary use of `get("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:9:11 + --> tests/ui/unnecessary_get_then_check.rs:9:15 | -LL | let _ = s.get("a").is_none(); - | --^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains("a")` +LL | let _ = s.get("a").is_none(); + | --^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains("a")` error: unnecessary use of `get("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:13:11 + --> tests/ui/unnecessary_get_then_check.rs:13:15 | -LL | let _ = s.get("a").is_some(); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("a")` +LL | let _ = s.get("a").is_some(); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("a")` error: unnecessary use of `get("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:15:11 + --> tests/ui/unnecessary_get_then_check.rs:15:15 | -LL | let _ = s.get("a").is_none(); - | --^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains_key("a")` +LL | let _ = s.get("a").is_none(); + | --^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains_key("a")` error: unnecessary use of `get("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:19:11 + --> tests/ui/unnecessary_get_then_check.rs:19:15 | -LL | let _ = s.get("a").is_some(); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains("a")` +LL | let _ = s.get("a").is_some(); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains("a")` error: unnecessary use of `get("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:21:11 + --> tests/ui/unnecessary_get_then_check.rs:21:15 | -LL | let _ = s.get("a").is_none(); - | --^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains("a")` +LL | let _ = s.get("a").is_none(); + | --^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains("a")` error: unnecessary use of `get("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:25:11 + --> tests/ui/unnecessary_get_then_check.rs:25:15 | -LL | let _ = s.get("a").is_some(); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("a")` +LL | let _ = s.get("a").is_some(); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key("a")` error: unnecessary use of `get("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:27:11 + --> tests/ui/unnecessary_get_then_check.rs:27:15 | -LL | let _ = s.get("a").is_none(); - | --^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains_key("a")` +LL | let _ = s.get("a").is_none(); + | --^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains_key("a")` error: unnecessary use of `get::("a").is_some()` - --> tests/ui/unnecessary_get_then_check.rs:32:11 + --> tests/ui/unnecessary_get_then_check.rs:32:15 | -LL | let _ = s.get::("a").is_some(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains::("a")` +LL | let _ = s.get::("a").is_some(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains::("a")` error: unnecessary use of `get::("a").is_none()` - --> tests/ui/unnecessary_get_then_check.rs:34:11 + --> tests/ui/unnecessary_get_then_check.rs:34:15 | -LL | let _ = s.get::("a").is_none(); - | --^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | help: replace it with: `!s.contains::("a")` +LL | let _ = s.get::("a").is_none(); + | --^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: replace it with: `!s.contains::("a")` error: aborting due to 10 previous errors diff --git a/tests/ui/unnecessary_iter_cloned.fixed b/tests/ui/unnecessary_iter_cloned.fixed index 533059d91fce..aed2dbe1f1ce 100644 --- a/tests/ui/unnecessary_iter_cloned.fixed +++ b/tests/ui/unnecessary_iter_cloned.fixed @@ -29,7 +29,7 @@ fn main() { // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { for (t, path) in files { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned let other = match get_file_path(t) { Ok(p) => p, Err(_) => { @@ -45,7 +45,7 @@ fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { fn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool { for (t, path) in files.iter() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned let other = match get_file_path(t) { Ok(p) => p, Err(_) => { @@ -177,7 +177,7 @@ mod issue_12821 { fn foo() { let v: Vec<_> = "hello".chars().collect(); for c in v.iter() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned println!("{c}"); // should not suggest to remove `&` } @@ -186,9 +186,9 @@ mod issue_12821 { fn bar() { let v: Vec<_> = "hello".chars().collect(); for c in v.iter() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned -let ref_c = c; + let ref_c = c; println!("{ref_c}"); } } @@ -196,9 +196,9 @@ let ref_c = c; fn baz() { let v: Vec<_> = "hello".chars().enumerate().collect(); for (i, c) in v.iter() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned -let ref_c = c; + let ref_c = c; let ref_i = i; println!("{i} {ref_c}"); // should not suggest to remove `&` from `i` } diff --git a/tests/ui/unnecessary_iter_cloned.rs b/tests/ui/unnecessary_iter_cloned.rs index 5e0c2e6d78ec..12fdd150e423 100644 --- a/tests/ui/unnecessary_iter_cloned.rs +++ b/tests/ui/unnecessary_iter_cloned.rs @@ -29,7 +29,7 @@ fn main() { // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { for (t, path) in files.iter().copied() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned let other = match get_file_path(&t) { Ok(p) => p, Err(_) => { @@ -45,7 +45,7 @@ fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { fn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool { for (t, path) in files.iter().copied() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned let other = match get_file_path(&t) { Ok(p) => p, Err(_) => { @@ -177,7 +177,7 @@ mod issue_12821 { fn foo() { let v: Vec<_> = "hello".chars().collect(); for c in v.iter().cloned() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned println!("{c}"); // should not suggest to remove `&` } @@ -186,9 +186,9 @@ mod issue_12821 { fn bar() { let v: Vec<_> = "hello".chars().collect(); for c in v.iter().cloned() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned -let ref_c = &c; + let ref_c = &c; println!("{ref_c}"); } } @@ -196,9 +196,9 @@ let ref_c = &c; fn baz() { let v: Vec<_> = "hello".chars().enumerate().collect(); for (i, c) in v.iter().cloned() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned -let ref_c = &c; + let ref_c = &c; let ref_i = &i; println!("{i} {ref_c}"); // should not suggest to remove `&` from `i` } diff --git a/tests/ui/unnecessary_iter_cloned.stderr b/tests/ui/unnecessary_iter_cloned.stderr index 61ae9acc35cc..632c8f371106 100644 --- a/tests/ui/unnecessary_iter_cloned.stderr +++ b/tests/ui/unnecessary_iter_cloned.stderr @@ -43,7 +43,7 @@ help: remove any references to the binding LL ~ for c in v.iter() { LL | LL | -LL ~ let ref_c = c; +LL ~ let ref_c = c; | error: unnecessary use of `cloned` @@ -57,7 +57,7 @@ help: remove any references to the binding LL ~ for (i, c) in v.iter() { LL | LL | -LL ~ let ref_c = c; +LL ~ let ref_c = c; LL ~ let ref_i = i; | diff --git a/tests/ui/unnecessary_lazy_eval_unfixable.rs b/tests/ui/unnecessary_lazy_eval_unfixable.rs index 54a2d4cee36f..6d28d544dfe0 100644 --- a/tests/ui/unnecessary_lazy_eval_unfixable.rs +++ b/tests/ui/unnecessary_lazy_eval_unfixable.rs @@ -13,7 +13,6 @@ fn main() { let _ = Ok(1).unwrap_or_else(|()| 2); //~^ unnecessary_lazy_evaluations - mod e { pub struct E; } @@ -23,7 +22,6 @@ fn main() { let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); //~^ unnecessary_lazy_evaluations - // Fix #6343 let arr = [(Some(1),)]; Some(&0).and_then(|&i| arr[i].0); diff --git a/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/tests/ui/unnecessary_lazy_eval_unfixable.stderr index 11eecdf6fa4a..0a62b312f71c 100644 --- a/tests/ui/unnecessary_lazy_eval_unfixable.stderr +++ b/tests/ui/unnecessary_lazy_eval_unfixable.stderr @@ -12,7 +12,7 @@ LL | let _ = Ok(1).unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval_unfixable.rs:20:13 + --> tests/ui/unnecessary_lazy_eval_unfixable.rs:19:13 | LL | let _ = Ok(1).unwrap_or_else(|e::E| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = Ok(1).unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` - --> tests/ui/unnecessary_lazy_eval_unfixable.rs:23:13 + --> tests/ui/unnecessary_lazy_eval_unfixable.rs:22:13 | LL | let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = Ok(1).unwrap_or(2); | ~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` - --> tests/ui/unnecessary_lazy_eval_unfixable.rs:34:13 + --> tests/ui/unnecessary_lazy_eval_unfixable.rs:32:13 | LL | let _ = true.then(|| -> &[u8] { &[] }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_literal_bound.fixed b/tests/ui/unnecessary_literal_bound.fixed index 5ac38a5b76ae..ec0d2db154ce 100644 --- a/tests/ui/unnecessary_literal_bound.fixed +++ b/tests/ui/unnecessary_literal_bound.fixed @@ -7,7 +7,7 @@ struct Struct<'a> { impl Struct<'_> { // Should warn fn returns_lit(&self) -> &'static str { - //~^ unnecessary_literal_bound + //~^ unnecessary_literal_bound "Hello" } @@ -28,7 +28,7 @@ impl Struct<'_> { // Should warn fn contionally_returns_literals_explicit(&self, cond: bool) -> &'static str { - //~^ unnecessary_literal_bound + //~^ unnecessary_literal_bound if cond { return "Literal"; } @@ -53,7 +53,7 @@ trait ReturnsStr { impl ReturnsStr for u8 { // Should warn, even though not useful without trait refinement fn trait_method(&self) -> &'static str { - //~^ unnecessary_literal_bound + //~^ unnecessary_literal_bound "Literal" } } diff --git a/tests/ui/unnecessary_literal_bound.rs b/tests/ui/unnecessary_literal_bound.rs index 487ca04c6ab3..713dee4d30a6 100644 --- a/tests/ui/unnecessary_literal_bound.rs +++ b/tests/ui/unnecessary_literal_bound.rs @@ -7,7 +7,7 @@ struct Struct<'a> { impl Struct<'_> { // Should warn fn returns_lit(&self) -> &str { - //~^ unnecessary_literal_bound + //~^ unnecessary_literal_bound "Hello" } @@ -28,7 +28,7 @@ impl Struct<'_> { // Should warn fn contionally_returns_literals_explicit(&self, cond: bool) -> &str { - //~^ unnecessary_literal_bound + //~^ unnecessary_literal_bound if cond { return "Literal"; } @@ -53,7 +53,7 @@ trait ReturnsStr { impl ReturnsStr for u8 { // Should warn, even though not useful without trait refinement fn trait_method(&self) -> &str { - //~^ unnecessary_literal_bound + //~^ unnecessary_literal_bound "Literal" } } diff --git a/tests/ui/unnecessary_literal_unwrap_unfixable.rs b/tests/ui/unnecessary_literal_unwrap_unfixable.rs index 4bb93fc391e6..b6cba4e6a568 100644 --- a/tests/ui/unnecessary_literal_unwrap_unfixable.rs +++ b/tests/ui/unnecessary_literal_unwrap_unfixable.rs @@ -9,7 +9,6 @@ fn unwrap_option_some() { let _val2 = val.expect("this never happens"); //~^ unnecessary_literal_unwrap - } fn unwrap_option_some_context() { @@ -19,14 +18,12 @@ fn unwrap_option_some_context() { let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); //~^ unnecessary_literal_unwrap - let val = Some::([1, 2, 3].iter().sum()); let _val2 = val.unwrap(); //~^ unnecessary_literal_unwrap let _val2 = val.expect("this never happens"); //~^ unnecessary_literal_unwrap - } fn unwrap_option_none() { @@ -42,7 +39,6 @@ fn unwrap_option_none() { None::<()>.unwrap_or_default(); //~^ unnecessary_literal_unwrap - } fn unwrap_result_ok() { @@ -58,7 +54,6 @@ fn unwrap_result_ok() { let _val2 = val.expect_err("this always happens"); //~^ unnecessary_literal_unwrap - } fn unwrap_result_ok_context() { @@ -74,7 +69,6 @@ fn unwrap_result_ok_context() { let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); //~^ unnecessary_literal_unwrap - let val = Ok::([1, 2, 3].iter().sum()); let _val2 = val.unwrap(); //~^ unnecessary_literal_unwrap @@ -87,7 +81,6 @@ fn unwrap_result_ok_context() { let _val2 = val.expect_err("this always happens"); //~^ unnecessary_literal_unwrap - } fn unwrap_result_err() { @@ -103,7 +96,6 @@ fn unwrap_result_err() { let _val2 = val.expect("this always happens"); //~^ unnecessary_literal_unwrap - } fn unwrap_result_err_context() { @@ -119,7 +111,6 @@ fn unwrap_result_err_context() { let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); //~^ unnecessary_literal_unwrap - let val = Err::<(), usize>([1, 2, 3].iter().sum()); let _val2 = val.unwrap_err(); //~^ unnecessary_literal_unwrap @@ -132,7 +123,6 @@ fn unwrap_result_err_context() { let _val2 = val.expect("this always happens"); //~^ unnecessary_literal_unwrap - } fn unwrap_methods_option() { @@ -145,7 +135,6 @@ fn unwrap_methods_option() { let _val2 = val.unwrap_or_else(|| 2); //~^ unnecessary_literal_unwrap - } fn unwrap_methods_option_context() { @@ -158,7 +147,6 @@ fn unwrap_methods_option_context() { let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); //~^ unnecessary_literal_unwrap - let val = Some::([1, 2, 3].iter().sum()); let _val2 = val.unwrap_or(2); //~^ unnecessary_literal_unwrap @@ -168,7 +156,6 @@ fn unwrap_methods_option_context() { let _val2 = val.unwrap_or_else(|| 2); //~^ unnecessary_literal_unwrap - } fn unwrap_methods_result() { @@ -181,7 +168,6 @@ fn unwrap_methods_result() { let _val2 = val.unwrap_or_else(|_| 2); //~^ unnecessary_literal_unwrap - } fn unwrap_methods_result_context() { @@ -194,7 +180,6 @@ fn unwrap_methods_result_context() { let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); //~^ unnecessary_literal_unwrap - let val = Ok::([1, 2, 3].iter().sum()); let _val2 = val.unwrap_or(2); //~^ unnecessary_literal_unwrap @@ -204,7 +189,6 @@ fn unwrap_methods_result_context() { let _val2 = val.unwrap_or_else(|_| 2); //~^ unnecessary_literal_unwrap - } fn main() { diff --git a/tests/ui/unnecessary_literal_unwrap_unfixable.stderr b/tests/ui/unnecessary_literal_unwrap_unfixable.stderr index b579bb74ef74..4994eeded776 100644 --- a/tests/ui/unnecessary_literal_unwrap_unfixable.stderr +++ b/tests/ui/unnecessary_literal_unwrap_unfixable.stderr @@ -25,589 +25,589 @@ LL | let val = Some(1); | ^^^^^^^ error: used `unwrap()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:16:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:15:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:16:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:15:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:19:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:18:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:19:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:18:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:24:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:22:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Some` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:23:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:21:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:27:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:25:17 | LL | let _val2 = val.expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:23:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:21:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `None` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:34:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:31:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `None` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:33:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:30:15 | LL | let val = None::<()>; | ^^^^^^^^^^ error: used `expect()` on `None` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:37:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:34:17 | LL | let _val2 = val.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `None` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:33:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:30:15 | LL | let val = None::<()>; | ^^^^^^^^^^ error: used `unwrap_or_default()` on `None` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:40:21 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:37:21 | LL | let _val3: u8 = None.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `Default::default()` error: used `unwrap_or_default()` on `None` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:43:5 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:40:5 | LL | None::<()>.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `Default::default()` error: used `unwrap()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:50:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:46:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:45:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `expect()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:53:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:17 | LL | let _val2 = val.expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:45:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:56:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:52:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:45:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `expect_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:59:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:55:17 | LL | let _val2 = val.expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:45:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:65:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:60:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:65:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:60:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:68:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:63:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:68:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:63:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:71:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:66:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:71:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:66:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:74:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:69:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:74:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:69:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:79:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:73:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:78:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:82:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:76:17 | LL | let _val2 = val.expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:78:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:85:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:79:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:78:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:88:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:82:17 | LL | let _val2 = val.expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:78:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:95:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:88:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:87:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `expect_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:98:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:91:17 | LL | let _val2 = val.expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:87:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `unwrap()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:101:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Err` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:87:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `expect()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:104:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:97:17 | LL | let _val2 = val.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:87:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:110:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:102:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:110:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:102:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:113:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:105:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:113:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:105:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:116:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:108:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:116:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:108:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:119:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:111:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:119:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:111:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:124:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:115:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:123:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:114:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:127:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:118:17 | LL | let _val2 = val.expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect_err()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:123:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:114:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:130:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:121:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Err` and `unwrap()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:123:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:114:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:133:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:124:17 | LL | let _val2 = val.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:123:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:114:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:140:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:130:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:139:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:129:15 | LL | let val = Some(1); | ^^^^^^^ error: used `unwrap_or_default()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:143:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:133:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:139:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:129:15 | LL | let val = Some(1); | ^^^^^^^ error: used `unwrap_or_else()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:146:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:136:17 | LL | let _val2 = val.unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:139:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:129:15 | LL | let val = Some(1); | ^^^^^^^ error: used `unwrap_or()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:152:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:141:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:152:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:141:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:155:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:144:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:155:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:144:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:158:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:147:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:158:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:147:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:163:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:151:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:150:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:166:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:154:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:150:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:169:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:157:17 | LL | let _val2 = val.unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:150:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:176:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:163:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:175:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:179:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:166:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:175:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:182:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:169:17 | LL | let _val2 = val.unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:175:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:188:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:174:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:188:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:174:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:191:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:177:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:191:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:177:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:194:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:180:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:194:16 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:180:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:199:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:184:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:198:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:183:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:202:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:187:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_default()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:198:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:183:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:205:17 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:190:17 | LL | let _val2 = val.unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_else()` - --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:198:15 + --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:183:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_map_or.fixed b/tests/ui/unnecessary_map_or.fixed index f51da49edabb..01646faea4b6 100644 --- a/tests/ui/unnecessary_map_or.fixed +++ b/tests/ui/unnecessary_map_or.fixed @@ -16,7 +16,7 @@ fn main() { //~^ unnecessary_map_or let _ = Some(5) == Some(5); let _ = Some(5).is_some_and(|n| { - //~^ unnecessary_map_or + //~^ unnecessary_map_or let _ = n; 6 >= 5 }); diff --git a/tests/ui/unnecessary_map_or.rs b/tests/ui/unnecessary_map_or.rs index a1ae97af2b9f..10669f2a7f1a 100644 --- a/tests/ui/unnecessary_map_or.rs +++ b/tests/ui/unnecessary_map_or.rs @@ -15,12 +15,12 @@ fn main() { let _ = Some(5).map_or(true, |n| n != 5); //~^ unnecessary_map_or let _ = Some(5).map_or(false, |n| { - //~^ unnecessary_map_or + //~^ unnecessary_map_or let _ = 1; n == 5 }); let _ = Some(5).map_or(false, |n| { - //~^ unnecessary_map_or + //~^ unnecessary_map_or let _ = n; 6 >= 5 }); diff --git a/tests/ui/unnecessary_operation.fixed b/tests/ui/unnecessary_operation.fixed index ec3e64e15b85..05dfb72f48d2 100644 --- a/tests/ui/unnecessary_operation.fixed +++ b/tests/ui/unnecessary_operation.fixed @@ -142,5 +142,4 @@ const _: () = { const fn foo() { assert!([42, 55].len() > get_usize()); //~^ unnecessary_operation - } diff --git a/tests/ui/unnecessary_operation.rs b/tests/ui/unnecessary_operation.rs index 3f903cd04ef8..6ef74c3eb1c1 100644 --- a/tests/ui/unnecessary_operation.rs +++ b/tests/ui/unnecessary_operation.rs @@ -102,11 +102,11 @@ fn main() { [42; 55][get_usize()]; //~^ unnecessary_operation { - //~^ unnecessary_operation + //~^ unnecessary_operation get_number() }; FooString { - //~^ unnecessary_operation + //~^ unnecessary_operation s: String::from("blah"), }; @@ -148,5 +148,4 @@ const _: () = { const fn foo() { [42, 55][get_usize()]; //~^ unnecessary_operation - } diff --git a/tests/ui/unnecessary_result_map_or_else.fixed b/tests/ui/unnecessary_result_map_or_else.fixed index 784a42a04ba8..5d7e3fa355fd 100644 --- a/tests/ui/unnecessary_result_map_or_else.fixed +++ b/tests/ui/unnecessary_result_map_or_else.fixed @@ -3,19 +3,19 @@ fn main() { let x: Result<(), ()> = Ok(()); -x.unwrap_or_else(|err| err); -//~^ unnecessary_result_map_or_else + x.unwrap_or_else(|err| err); + //~^ unnecessary_result_map_or_else // Type ascribtion. let x: Result<(), ()> = Ok(()); -x.unwrap_or_else(|err: ()| err); -//~^ unnecessary_result_map_or_else + x.unwrap_or_else(|err: ()| err); + //~^ unnecessary_result_map_or_else // Auto-deref. let y = String::new(); let x: Result<&String, &String> = Ok(&y); -let y: &str = x.unwrap_or_else(|err| err); -//~^ unnecessary_result_map_or_else + let y: &str = x.unwrap_or_else(|err| err); + //~^ unnecessary_result_map_or_else // Temporary variable. let x: Result<(), ()> = Ok(()); diff --git a/tests/ui/unnecessary_result_map_or_else.rs b/tests/ui/unnecessary_result_map_or_else.rs index 39b15f6d26d0..d2bab0f9d9c1 100644 --- a/tests/ui/unnecessary_result_map_or_else.rs +++ b/tests/ui/unnecessary_result_map_or_else.rs @@ -3,25 +3,24 @@ fn main() { let x: Result<(), ()> = Ok(()); -x.map_or_else(|err| err, |n| n); -//~^ unnecessary_result_map_or_else + x.map_or_else(|err| err, |n| n); + //~^ unnecessary_result_map_or_else // Type ascribtion. let x: Result<(), ()> = Ok(()); -x.map_or_else(|err: ()| err, |n: ()| n); -//~^ unnecessary_result_map_or_else + x.map_or_else(|err: ()| err, |n: ()| n); + //~^ unnecessary_result_map_or_else // Auto-deref. let y = String::new(); let x: Result<&String, &String> = Ok(&y); -let y: &str = x.map_or_else(|err| err, |n| n); -//~^ unnecessary_result_map_or_else + let y: &str = x.map_or_else(|err| err, |n| n); + //~^ unnecessary_result_map_or_else // Temporary variable. let x: Result<(), ()> = Ok(()); x.map_or_else( - //~^ unnecessary_result_map_or_else - + //~^ unnecessary_result_map_or_else |err| err, |n| { let tmp = n; diff --git a/tests/ui/unnecessary_result_map_or_else.stderr b/tests/ui/unnecessary_result_map_or_else.stderr index 6334fe5eca68..e6afa50217cc 100644 --- a/tests/ui/unnecessary_result_map_or_else.stderr +++ b/tests/ui/unnecessary_result_map_or_else.stderr @@ -1,31 +1,31 @@ error: unused "map closure" when calling `Result::map_or_else` value - --> tests/ui/unnecessary_result_map_or_else.rs:6:1 + --> tests/ui/unnecessary_result_map_or_else.rs:6:5 | -LL | x.map_or_else(|err| err, |n| n); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)` +LL | x.map_or_else(|err| err, |n| n); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)` | = note: `-D clippy::unnecessary-result-map-or-else` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_result_map_or_else)]` error: unused "map closure" when calling `Result::map_or_else` value - --> tests/ui/unnecessary_result_map_or_else.rs:11:1 + --> tests/ui/unnecessary_result_map_or_else.rs:11:5 | -LL | x.map_or_else(|err: ()| err, |n: ()| n); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err: ()| err)` +LL | x.map_or_else(|err: ()| err, |n: ()| n); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err: ()| err)` error: unused "map closure" when calling `Result::map_or_else` value - --> tests/ui/unnecessary_result_map_or_else.rs:17:15 + --> tests/ui/unnecessary_result_map_or_else.rs:17:19 | -LL | let y: &str = x.map_or_else(|err| err, |n| n); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)` +LL | let y: &str = x.map_or_else(|err| err, |n| n); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)` error: unused "map closure" when calling `Result::map_or_else` value --> tests/ui/unnecessary_result_map_or_else.rs:22:5 | LL | / x.map_or_else( LL | | -LL | | LL | | |err| err, +LL | | |n| { ... | LL | | }, LL | | ); diff --git a/tests/ui/unnecessary_safety_comment.rs b/tests/ui/unnecessary_safety_comment.rs index 3bdeda2724c6..4440089b3633 100644 --- a/tests/ui/unnecessary_safety_comment.rs +++ b/tests/ui/unnecessary_safety_comment.rs @@ -21,7 +21,6 @@ mod unsafe_items_invalid_comment { // SAFETY: mod module {} //~^ unnecessary_safety_comment - } mod unnecessary_from_macro { @@ -53,16 +52,13 @@ fn unnecessary_on_stmt_and_expr() -> u32 { let num = 42; //~^ unnecessary_safety_comment - // SAFETY: unnecessary if num > 24 {} //~^ unnecessary_safety_comment - // SAFETY: unnecessary 24 //~^ unnecessary_safety_comment - } mod issue_10084 { diff --git a/tests/ui/unnecessary_safety_comment.stderr b/tests/ui/unnecessary_safety_comment.stderr index 3f9e35b095b9..b56e8b354931 100644 --- a/tests/ui/unnecessary_safety_comment.stderr +++ b/tests/ui/unnecessary_safety_comment.stderr @@ -61,7 +61,7 @@ LL | // SAFETY: | ^^^^^^^^^^ error: impl has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:43:13 + --> tests/ui/unnecessary_safety_comment.rs:42:13 | LL | impl T for $t {} | ^^^^^^^^^^^^^^^^ @@ -70,44 +70,44 @@ LL | with_safety_comment!(i32); | ------------------------- in this macro invocation | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:42:13 + --> tests/ui/unnecessary_safety_comment.rs:41:13 | LL | // Safety: unnecessary | ^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `with_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: expression has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:63:5 + --> tests/ui/unnecessary_safety_comment.rs:60:5 | LL | 24 | ^^ | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:62:5 + --> tests/ui/unnecessary_safety_comment.rs:59:5 | LL | // SAFETY: unnecessary | ^^^^^^^^^^^^^^^^^^^^^^ error: statement has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:53:5 + --> tests/ui/unnecessary_safety_comment.rs:52:5 | LL | let num = 42; | ^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:52:5 + --> tests/ui/unnecessary_safety_comment.rs:51:5 | LL | // SAFETY: unnecessary | ^^^^^^^^^^^^^^^^^^^^^^ error: statement has unnecessary safety comment - --> tests/ui/unnecessary_safety_comment.rs:58:5 + --> tests/ui/unnecessary_safety_comment.rs:56:5 | LL | if num > 24 {} | ^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui/unnecessary_safety_comment.rs:57:5 + --> tests/ui/unnecessary_safety_comment.rs:55:5 | LL | // SAFETY: unnecessary | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_semicolon.edition2021.fixed b/tests/ui/unnecessary_semicolon.edition2021.fixed index 1dcc6484a195..f10d804c8ccc 100644 --- a/tests/ui/unnecessary_semicolon.edition2021.fixed +++ b/tests/ui/unnecessary_semicolon.edition2021.fixed @@ -29,13 +29,11 @@ fn main() { } //~^ unnecessary_semicolon - a.match { 3 => println!("three"), _ => println!("not three"), } //~^ unnecessary_semicolon - } // This is a problem in edition 2021 and below diff --git a/tests/ui/unnecessary_semicolon.edition2021.stderr b/tests/ui/unnecessary_semicolon.edition2021.stderr index 3299442a5c1d..a3b139f73805 100644 --- a/tests/ui/unnecessary_semicolon.edition2021.stderr +++ b/tests/ui/unnecessary_semicolon.edition2021.stderr @@ -8,13 +8,13 @@ LL | }; = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]` error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:36:6 + --> tests/ui/unnecessary_semicolon.rs:35:6 | LL | }; | ^ help: remove error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:59:6 + --> tests/ui/unnecessary_semicolon.rs:57:6 | LL | }; | ^ help: remove diff --git a/tests/ui/unnecessary_semicolon.edition2024.fixed b/tests/ui/unnecessary_semicolon.edition2024.fixed index 91eef8022ed2..32a3bb9b4081 100644 --- a/tests/ui/unnecessary_semicolon.edition2024.fixed +++ b/tests/ui/unnecessary_semicolon.edition2024.fixed @@ -29,13 +29,11 @@ fn main() { } //~^ unnecessary_semicolon - a.match { 3 => println!("three"), _ => println!("not three"), } //~^ unnecessary_semicolon - } // This is a problem in edition 2021 and below diff --git a/tests/ui/unnecessary_semicolon.edition2024.stderr b/tests/ui/unnecessary_semicolon.edition2024.stderr index 98adc2f0a0a2..d5ccae7fdf58 100644 --- a/tests/ui/unnecessary_semicolon.edition2024.stderr +++ b/tests/ui/unnecessary_semicolon.edition2024.stderr @@ -8,19 +8,19 @@ LL | }; = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]` error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:36:6 + --> tests/ui/unnecessary_semicolon.rs:35:6 | LL | }; | ^ help: remove error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:49:6 + --> tests/ui/unnecessary_semicolon.rs:47:6 | LL | }; | ^ help: remove error: unnecessary semicolon - --> tests/ui/unnecessary_semicolon.rs:59:6 + --> tests/ui/unnecessary_semicolon.rs:57:6 | LL | }; | ^ help: remove diff --git a/tests/ui/unnecessary_semicolon.rs b/tests/ui/unnecessary_semicolon.rs index 6c48bfae14ce..91b282180224 100644 --- a/tests/ui/unnecessary_semicolon.rs +++ b/tests/ui/unnecessary_semicolon.rs @@ -29,13 +29,11 @@ fn main() { }; //~^ unnecessary_semicolon - a.match { 3 => println!("three"), _ => println!("not three"), }; //~^ unnecessary_semicolon - } // This is a problem in edition 2021 and below diff --git a/tests/ui/unnecessary_struct_initialization.rs b/tests/ui/unnecessary_struct_initialization.rs index 2b26bc413b8f..12a444fc878b 100644 --- a/tests/ui/unnecessary_struct_initialization.rs +++ b/tests/ui/unnecessary_struct_initialization.rs @@ -60,7 +60,7 @@ fn main() { // Should lint: the result of an expression is mutable let h = &mut S { - //~^ unnecessary_struct_initialization + //~^ unnecessary_struct_initialization ..*Box::new(S { f: String::from("foo") }) }; @@ -80,7 +80,7 @@ fn main() { // Should lint: the result of an expression is mutable and temporary let p = &mut T { - //~^ unnecessary_struct_initialization + //~^ unnecessary_struct_initialization ..*Box::new(T { f: 5 }) }; diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed index a03bfb2eafe3..136dafda27ea 100644 --- a/tests/ui/unnecessary_to_owned.fixed +++ b/tests/ui/unnecessary_to_owned.fixed @@ -296,7 +296,7 @@ fn require_as_ref_slice_str, V: AsRef>(_: U, _: V) {} // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 fn check_files(file_types: &[FileType]) -> bool { for t in file_types { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned let path = match get_file_path(t) { Ok(p) => p, Err(_) => { @@ -639,23 +639,23 @@ fn borrow_checks() { fn inner(a: &[&str]) { let mut s = HashSet::from([vec!["a"]]); -s.remove(a); -//~^ unnecessary_to_owned + s.remove(a); + //~^ unnecessary_to_owned } let mut s = HashSet::from(["a".to_string()]); -s.remove("b"); -//~^ unnecessary_to_owned -s.remove("b"); -//~^ unnecessary_to_owned + s.remove("b"); + //~^ unnecessary_to_owned + s.remove("b"); + //~^ unnecessary_to_owned // Should not warn. s.remove("b"); let mut s = HashSet::from([vec!["a"]]); -s.remove(["b"].as_slice()); -//~^ unnecessary_to_owned -s.remove((&["b"]).as_slice()); -//~^ unnecessary_to_owned + s.remove(["b"].as_slice()); + //~^ unnecessary_to_owned + s.remove((&["b"]).as_slice()); + //~^ unnecessary_to_owned // Should not warn. s.remove(&["b"].to_vec().clone()); diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs index a03b13d47565..0948ac5de3ef 100644 --- a/tests/ui/unnecessary_to_owned.rs +++ b/tests/ui/unnecessary_to_owned.rs @@ -296,7 +296,7 @@ fn require_as_ref_slice_str, V: AsRef>(_: U, _: V) {} // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 fn check_files(file_types: &[FileType]) -> bool { for t in file_types.to_vec() { - //~^ unnecessary_to_owned + //~^ unnecessary_to_owned let path = match get_file_path(&t) { Ok(p) => p, Err(_) => { @@ -639,23 +639,23 @@ fn borrow_checks() { fn inner(a: &[&str]) { let mut s = HashSet::from([vec!["a"]]); -s.remove(&a.to_vec()); -//~^ unnecessary_to_owned + s.remove(&a.to_vec()); + //~^ unnecessary_to_owned } let mut s = HashSet::from(["a".to_string()]); -s.remove(&"b".to_owned()); -//~^ unnecessary_to_owned -s.remove(&"b".to_string()); -//~^ unnecessary_to_owned + s.remove(&"b".to_owned()); + //~^ unnecessary_to_owned + s.remove(&"b".to_string()); + //~^ unnecessary_to_owned // Should not warn. s.remove("b"); let mut s = HashSet::from([vec!["a"]]); -s.remove(&["b"].to_vec()); -//~^ unnecessary_to_owned -s.remove(&(&["b"]).to_vec()); -//~^ unnecessary_to_owned + s.remove(&["b"].to_vec()); + //~^ unnecessary_to_owned + s.remove(&(&["b"]).to_vec()); + //~^ unnecessary_to_owned // Should not warn. s.remove(&["b"].to_vec().clone()); diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr index 23963fd6779a..f8ad85dbed02 100644 --- a/tests/ui/unnecessary_to_owned.stderr +++ b/tests/ui/unnecessary_to_owned.stderr @@ -557,34 +557,34 @@ LL | IntoFuture::into_future(foo([].to_vec(), &0)); | ^^^^^^^^^^^ help: use: `[]` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:642:10 + --> tests/ui/unnecessary_to_owned.rs:642:18 | -LL | s.remove(&a.to_vec()); - | ^^^^^^^^^^^ help: replace it with: `a` +LL | s.remove(&a.to_vec()); + | ^^^^^^^^^^^ help: replace it with: `a` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:647:10 + --> tests/ui/unnecessary_to_owned.rs:647:14 | -LL | s.remove(&"b".to_owned()); - | ^^^^^^^^^^^^^^^ help: replace it with: `"b"` +LL | s.remove(&"b".to_owned()); + | ^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:649:10 + --> tests/ui/unnecessary_to_owned.rs:649:14 | -LL | s.remove(&"b".to_string()); - | ^^^^^^^^^^^^^^^^ help: replace it with: `"b"` +LL | s.remove(&"b".to_string()); + | ^^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:655:10 + --> tests/ui/unnecessary_to_owned.rs:655:14 | -LL | s.remove(&["b"].to_vec()); - | ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()` +LL | s.remove(&["b"].to_vec()); + | ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:657:10 + --> tests/ui/unnecessary_to_owned.rs:657:14 | -LL | s.remove(&(&["b"]).to_vec()); - | ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()` +LL | s.remove(&(&["b"]).to_vec()); + | ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()` error: aborting due to 88 previous errors diff --git a/tests/ui/unnecessary_to_owned_on_split.fixed b/tests/ui/unnecessary_to_owned_on_split.fixed index be453758ff3a..f43d92a2d9ba 100644 --- a/tests/ui/unnecessary_to_owned_on_split.fixed +++ b/tests/ui/unnecessary_to_owned_on_split.fixed @@ -31,7 +31,6 @@ fn main() { let _ = Issue12068.as_ref().split('a').next().unwrap(); //~^ unnecessary_to_owned - let _ = [1].split(|x| *x == 2).next().unwrap(); //~^ unnecessary_to_owned @@ -43,5 +42,4 @@ fn main() { let _ = [1].split(|x| *x == 2).next().unwrap(); //~^ unnecessary_to_owned - } diff --git a/tests/ui/unnecessary_to_owned_on_split.rs b/tests/ui/unnecessary_to_owned_on_split.rs index b6317db80d7c..bdf5f98bf61e 100644 --- a/tests/ui/unnecessary_to_owned_on_split.rs +++ b/tests/ui/unnecessary_to_owned_on_split.rs @@ -31,7 +31,6 @@ fn main() { let _ = Issue12068.to_string().split('a').next().unwrap(); //~^ unnecessary_to_owned - let _ = [1].to_vec().split(|x| *x == 2).next().unwrap(); //~^ unnecessary_to_owned @@ -43,5 +42,4 @@ fn main() { let _ = [1].to_owned().split(|x| *x == 2).next().unwrap(); //~^ unnecessary_to_owned - } diff --git a/tests/ui/unnecessary_to_owned_on_split.stderr b/tests/ui/unnecessary_to_owned_on_split.stderr index 32cf52381d83..5e4fbb1035d6 100644 --- a/tests/ui/unnecessary_to_owned_on_split.stderr +++ b/tests/ui/unnecessary_to_owned_on_split.stderr @@ -32,25 +32,25 @@ LL | let _ = Issue12068.to_string().split('a').next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Issue12068.as_ref().split('a')` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned_on_split.rs:35:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:34:13 | LL | let _ = [1].to_vec().split(|x| *x == 2).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned_on_split.rs:38:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:37:13 | LL | let _ = [1].to_vec().split(|x| *x == 2).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned_on_split.rs:41:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:40:13 | LL | let _ = [1].to_owned().split(|x| *x == 2).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned_on_split.rs:44:13 + --> tests/ui/unnecessary_to_owned_on_split.rs:43:13 | LL | let _ = [1].to_owned().split(|x| *x == 2).next().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)` diff --git a/tests/ui/unnecessary_unsafety_doc.rs b/tests/ui/unnecessary_unsafety_doc.rs index 2fe6c2b23a66..7a847d2e3b50 100644 --- a/tests/ui/unnecessary_unsafety_doc.rs +++ b/tests/ui/unnecessary_unsafety_doc.rs @@ -17,7 +17,7 @@ pub fn destroy_the_planet() { /// /// This function shouldn't be called unless the horsemen are ready pub fn apocalypse(universe: &mut ()) { -//~^ unnecessary_safety_doc + //~^ unnecessary_safety_doc unimplemented!(); } @@ -44,7 +44,7 @@ mod private_mod { /// /// Unnecessary safety! pub fn republished() { - //~^ unnecessary_safety_doc + //~^ unnecessary_safety_doc unimplemented!(); } } @@ -69,7 +69,7 @@ pub trait SafeTrait { /// /// Unnecessary! pub trait DocumentedSafeTrait { -//~^ unnecessary_safety_doc + //~^ unnecessary_safety_doc fn method2(); } @@ -98,7 +98,7 @@ impl Struct { /// /// Unnecessary! pub fn documented() -> Self { - //~^ unnecessary_safety_doc + //~^ unnecessary_safety_doc unimplemented!(); } @@ -126,7 +126,7 @@ macro_rules! very_safe { /// /// Driving is very safe already! pub fn drive() { - //~^ unnecessary_safety_doc + //~^ unnecessary_safety_doc whee() } }; @@ -155,6 +155,6 @@ pub mod __macro { /// # Implementation safety pub trait DocumentedSafeTraitWithImplementationHeader { -//~^ unnecessary_safety_doc + //~^ unnecessary_safety_doc fn method(); } diff --git a/tests/ui/unnecessary_wraps.rs b/tests/ui/unnecessary_wraps.rs index dee51ef67c3d..4770ef3b4830 100644 --- a/tests/ui/unnecessary_wraps.rs +++ b/tests/ui/unnecessary_wraps.rs @@ -7,8 +7,7 @@ // should be linted fn func1(a: bool, b: bool) -> Option { -//~^ unnecessary_wraps - + //~^ unnecessary_wraps if a && b { return Some(42); @@ -23,7 +22,7 @@ fn func1(a: bool, b: bool) -> Option { // should be linted fn func2(a: bool, b: bool) -> Option { -//~^ unnecessary_wraps + //~^ unnecessary_wraps if a && b { return Some(10); @@ -43,7 +42,7 @@ fn func4(a: bool) -> Option { // should be linted fn func5() -> Option { -//~^ unnecessary_wraps + //~^ unnecessary_wraps Some(1) } @@ -55,7 +54,7 @@ fn func6() -> Option { // should be linted fn func7() -> Result { -//~^ unnecessary_wraps + //~^ unnecessary_wraps Ok(1) } @@ -85,7 +84,7 @@ impl A { // should be linted fn func12() -> Option { - //~^ unnecessary_wraps + //~^ unnecessary_wraps Some(1) } @@ -114,7 +113,7 @@ fn issue_6384(s: &str) -> Option<&str> { // should be linted fn issue_6640_1(a: bool, b: bool) -> Option<()> { -//~^ unnecessary_wraps + //~^ unnecessary_wraps if a && b { return Some(()); @@ -129,7 +128,7 @@ fn issue_6640_1(a: bool, b: bool) -> Option<()> { // should be linted fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { -//~^ unnecessary_wraps + //~^ unnecessary_wraps if a && b { return Ok(()); diff --git a/tests/ui/unnecessary_wraps.stderr b/tests/ui/unnecessary_wraps.stderr index c193c4cf91ad..53fd8bd44146 100644 --- a/tests/ui/unnecessary_wraps.stderr +++ b/tests/ui/unnecessary_wraps.stderr @@ -2,6 +2,9 @@ error: this function's return value is unnecessarily wrapped by `Option` --> tests/ui/unnecessary_wraps.rs:9:1 | LL | / fn func1(a: bool, b: bool) -> Option { +LL | | +LL | | +LL | | if a && b { ... | LL | | } | |_^ @@ -24,7 +27,7 @@ LL ~ return 1337; | error: this function's return value is unnecessarily wrapped by `Option` - --> tests/ui/unnecessary_wraps.rs:25:1 + --> tests/ui/unnecessary_wraps.rs:24:1 | LL | / fn func2(a: bool, b: bool) -> Option { LL | | @@ -47,7 +50,7 @@ LL ~ if a { 20 } else { 30 } | error: this function's return value is unnecessarily wrapped by `Option` - --> tests/ui/unnecessary_wraps.rs:45:1 + --> tests/ui/unnecessary_wraps.rs:44:1 | LL | / fn func5() -> Option { LL | | @@ -66,7 +69,7 @@ LL | 1 | error: this function's return value is unnecessarily wrapped by `Result` - --> tests/ui/unnecessary_wraps.rs:57:1 + --> tests/ui/unnecessary_wraps.rs:56:1 | LL | / fn func7() -> Result { LL | | @@ -85,7 +88,7 @@ LL | 1 | error: this function's return value is unnecessarily wrapped by `Option` - --> tests/ui/unnecessary_wraps.rs:87:5 + --> tests/ui/unnecessary_wraps.rs:86:5 | LL | / fn func12() -> Option { LL | | @@ -104,7 +107,7 @@ LL | 1 | error: this function's return value is unnecessary - --> tests/ui/unnecessary_wraps.rs:116:1 + --> tests/ui/unnecessary_wraps.rs:115:1 | LL | / fn issue_6640_1(a: bool, b: bool) -> Option<()> { LL | | @@ -130,7 +133,7 @@ LL ~ return ; | error: this function's return value is unnecessary - --> tests/ui/unnecessary_wraps.rs:131:1 + --> tests/ui/unnecessary_wraps.rs:130:1 | LL | / fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> { LL | | diff --git a/tests/ui/unneeded_field_pattern.rs b/tests/ui/unneeded_field_pattern.rs index e4f6a704024b..327b64e7c4aa 100644 --- a/tests/ui/unneeded_field_pattern.rs +++ b/tests/ui/unneeded_field_pattern.rs @@ -17,7 +17,6 @@ fn main() { match f { Foo { a: _, b: 0, .. } => {}, //~^ unneeded_field_pattern - Foo { a: _, b: _, c: _ } => {}, //~^ unneeded_field_pattern } diff --git a/tests/ui/unneeded_field_pattern.stderr b/tests/ui/unneeded_field_pattern.stderr index 27e10f129dd6..4ea33a5db9e2 100644 --- a/tests/ui/unneeded_field_pattern.stderr +++ b/tests/ui/unneeded_field_pattern.stderr @@ -9,7 +9,7 @@ LL | Foo { a: _, b: 0, .. } => {}, = help: to override `-D warnings` add `#[allow(clippy::unneeded_field_pattern)]` error: all the struct fields are matched to a wildcard pattern, consider using `..` - --> tests/ui/unneeded_field_pattern.rs:21:9 + --> tests/ui/unneeded_field_pattern.rs:20:9 | LL | Foo { a: _, b: _, c: _ } => {}, | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unneeded_struct_pattern.fixed b/tests/ui/unneeded_struct_pattern.fixed index 3f24094ff316..1fcaa29c51f0 100644 --- a/tests/ui/unneeded_struct_pattern.fixed +++ b/tests/ui/unneeded_struct_pattern.fixed @@ -89,24 +89,24 @@ fn main() { noop(); } if let Custom::NoBrackets = Custom::Init { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBrackets = Custom::Init { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBrackets | Custom::NoBracketsNonExhaustive = Custom::Init { - //~^ unneeded_struct_pattern - //~| unneeded_struct_pattern + //~^ unneeded_struct_pattern + //~| unneeded_struct_pattern noop(); } if let Custom::NoBracketsNonExhaustive = Custom::Init { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBracketsNonExhaustive = Custom::Init { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern noop(); } @@ -123,23 +123,21 @@ fn main() { }; let Custom::NoBrackets = Custom::Init else { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern panic!() }; let Custom::NoBracketsNonExhaustive = Custom::Init else { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern panic!() }; let Custom::NoBracketsNonExhaustive = Custom::Init else { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern panic!() }; enum Refutable { Variant, } - - } fn external_crate() { diff --git a/tests/ui/unneeded_struct_pattern.rs b/tests/ui/unneeded_struct_pattern.rs index 0e6ae5124822..e51311afd5f8 100644 --- a/tests/ui/unneeded_struct_pattern.rs +++ b/tests/ui/unneeded_struct_pattern.rs @@ -80,7 +80,7 @@ fn main() { //~^^^ match_single_binding match Custom::Init { - //~^ match_single_binding + //~^ match_single_binding _ => 0, }; @@ -94,24 +94,24 @@ fn main() { noop(); } if let Custom::NoBrackets {} = Custom::Init { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBrackets { .. } = Custom::Init { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init { - //~^ unneeded_struct_pattern - //~| unneeded_struct_pattern + //~^ unneeded_struct_pattern + //~| unneeded_struct_pattern noop(); } if let Custom::NoBracketsNonExhaustive {} = Custom::Init { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern noop(); } if let Custom::NoBracketsNonExhaustive { .. } = Custom::Init { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern noop(); } @@ -128,23 +128,21 @@ fn main() { }; let Custom::NoBrackets { .. } = Custom::Init else { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern panic!() }; let Custom::NoBracketsNonExhaustive {} = Custom::Init else { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern panic!() }; let Custom::NoBracketsNonExhaustive { .. } = Custom::Init else { - //~^ unneeded_struct_pattern + //~^ unneeded_struct_pattern panic!() }; enum Refutable { Variant, } - - } fn external_crate() { @@ -157,13 +155,13 @@ fn external_crate() { }; match ExhaustiveUnit { - //~^ match_single_binding + //~^ match_single_binding // Exhaustive variant _ => 0, }; match ExhaustiveUnit { - //~^ match_single_binding + //~^ match_single_binding // Exhaustive variant _ => 0, }; diff --git a/tests/ui/unneeded_struct_pattern.stderr b/tests/ui/unneeded_struct_pattern.stderr index 9fd698ebf861..5630795823c4 100644 --- a/tests/ui/unneeded_struct_pattern.stderr +++ b/tests/ui/unneeded_struct_pattern.stderr @@ -136,7 +136,7 @@ LL | let Custom::NoBracketsNonExhaustive { .. } = Custom::Init else { | ^^^^^^^ help: remove the struct pattern error: this match could be replaced by its body itself - --> tests/ui/unneeded_struct_pattern.rs:159:5 + --> tests/ui/unneeded_struct_pattern.rs:157:5 | LL | / match ExhaustiveUnit { LL | | @@ -146,7 +146,7 @@ LL | | }; | |_____^ help: consider using the match body instead: `0` error: this match could be replaced by its body itself - --> tests/ui/unneeded_struct_pattern.rs:165:5 + --> tests/ui/unneeded_struct_pattern.rs:163:5 | LL | / match ExhaustiveUnit { LL | | diff --git a/tests/ui/unsafe_removed_from_name.rs b/tests/ui/unsafe_removed_from_name.rs index 124206e8e353..2e1d8b60a0e2 100644 --- a/tests/ui/unsafe_removed_from_name.rs +++ b/tests/ui/unsafe_removed_from_name.rs @@ -5,12 +5,9 @@ use std::cell::UnsafeCell as TotallySafeCell; //~^ unsafe_removed_from_name - - use std::cell::UnsafeCell as TotallySafeCellAgain; //~^ unsafe_removed_from_name - // Shouldn't error use std::cell::RefCell as ProbablyNotUnsafe; @@ -30,14 +27,11 @@ mod mod_with_some_unsafe_things { use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety; //~^ unsafe_removed_from_name - // merged imports use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B}; //~^ unsafe_removed_from_name //~| unsafe_removed_from_name - - // Shouldn't error use mod_with_some_unsafe_things::Safe as IPromiseItsSafeThisTime; diff --git a/tests/ui/unsafe_removed_from_name.stderr b/tests/ui/unsafe_removed_from_name.stderr index 899d438ea76b..5268c16ec9ba 100644 --- a/tests/ui/unsafe_removed_from_name.stderr +++ b/tests/ui/unsafe_removed_from_name.stderr @@ -8,25 +8,25 @@ LL | use std::cell::UnsafeCell as TotallySafeCell; = help: to override `-D warnings` add `#[allow(clippy::unsafe_removed_from_name)]` error: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCellAgain` - --> tests/ui/unsafe_removed_from_name.rs:10:1 + --> tests/ui/unsafe_removed_from_name.rs:8:1 | LL | use std::cell::UnsafeCell as TotallySafeCellAgain; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: removed `unsafe` from the name of `Unsafe` in use as `LieAboutModSafety` - --> tests/ui/unsafe_removed_from_name.rs:30:1 + --> tests/ui/unsafe_removed_from_name.rs:27:1 | LL | use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: removed `unsafe` from the name of `Unsafe` in use as `A` - --> tests/ui/unsafe_removed_from_name.rs:35:1 + --> tests/ui/unsafe_removed_from_name.rs:31:1 | LL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: removed `unsafe` from the name of `Unsafe` in use as `B` - --> tests/ui/unsafe_removed_from_name.rs:35:1 + --> tests/ui/unsafe_removed_from_name.rs:31:1 | LL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unused_async.rs b/tests/ui/unused_async.rs index 225f09ed94e6..5aaf7b9f5b59 100644 --- a/tests/ui/unused_async.rs +++ b/tests/ui/unused_async.rs @@ -10,7 +10,7 @@ mod issue10800 { use std::future::ready; async fn async_block_await() { - //~^ unused_async + //~^ unused_async async { ready(()).await; @@ -46,7 +46,6 @@ mod issue9695 { async fn f3() {} //~^ unused_async - fn needs_async_fn>(_: fn() -> F) {} fn test() { @@ -74,7 +73,7 @@ mod issue13466 { } async fn foo() -> i32 { -//~^ unused_async + //~^ unused_async 4 } @@ -87,7 +86,7 @@ struct S; impl S { async fn unused(&self) -> i32 { - //~^ unused_async + //~^ unused_async 1 } diff --git a/tests/ui/unused_async.stderr b/tests/ui/unused_async.stderr index 5b8d8f5097be..f95fdd865300 100644 --- a/tests/ui/unused_async.stderr +++ b/tests/ui/unused_async.stderr @@ -28,7 +28,7 @@ LL | async fn f3() {} = help: consider removing the `async` from this function error: unused `async` for function with no await statements - --> tests/ui/unused_async.rs:76:1 + --> tests/ui/unused_async.rs:75:1 | LL | / async fn foo() -> i32 { LL | | @@ -40,7 +40,7 @@ LL | | } = help: consider removing the `async` from this function error: unused `async` for function with no await statements - --> tests/ui/unused_async.rs:89:5 + --> tests/ui/unused_async.rs:88:5 | LL | / async fn unused(&self) -> i32 { LL | | diff --git a/tests/ui/unused_enumerate_index.fixed b/tests/ui/unused_enumerate_index.fixed index 8c713e273f4a..258e52971cea 100644 --- a/tests/ui/unused_enumerate_index.fixed +++ b/tests/ui/unused_enumerate_index.fixed @@ -10,7 +10,7 @@ fn get_enumerate() -> Enumerate> { fn main() { let v = [1, 2, 3]; for x in v.iter() { - //~^ unused_enumerate_index + //~^ unused_enumerate_index println!("{x}"); } @@ -58,7 +58,7 @@ fn main() { let dummy = Dummy3(vec![1, 2, 3].into_iter()); for x in dummy { - //~^ unused_enumerate_index + //~^ unused_enumerate_index println!("{x}"); } diff --git a/tests/ui/unused_enumerate_index.rs b/tests/ui/unused_enumerate_index.rs index 97018ee985e5..a17e3259a9b0 100644 --- a/tests/ui/unused_enumerate_index.rs +++ b/tests/ui/unused_enumerate_index.rs @@ -10,7 +10,7 @@ fn get_enumerate() -> Enumerate> { fn main() { let v = [1, 2, 3]; for (_, x) in v.iter().enumerate() { - //~^ unused_enumerate_index + //~^ unused_enumerate_index println!("{x}"); } @@ -58,7 +58,7 @@ fn main() { let dummy = Dummy3(vec![1, 2, 3].into_iter()); for (_, x) in dummy.enumerate() { - //~^ unused_enumerate_index + //~^ unused_enumerate_index println!("{x}"); } diff --git a/tests/ui/unused_format_specs.1.fixed b/tests/ui/unused_format_specs.1.fixed index 850240bab608..05bd1df9a523 100644 --- a/tests/ui/unused_format_specs.1.fixed +++ b/tests/ui/unused_format_specs.1.fixed @@ -12,20 +12,16 @@ fn main() { println!("{:5}.", format!("")); //~^ unused_format_specs - //prints `abcde`, not `abc` println!("{:.3}", format!("abcde")); //~^ unused_format_specs - println!("{}.", format_args_from_macro!()); //~^ unused_format_specs - let args = format_args!(""); println!("{args}"); //~^ unused_format_specs - } fn should_not_lint() { @@ -56,15 +52,12 @@ fn should_lint_user() { usr_println!(true, "{:.3}", format!("abcde")); //~^ unused_format_specs - usr_println!(true, "{}.", format_args_from_macro!()); //~^ unused_format_specs - let args = format_args!(""); usr_println!(true, "{args}"); //~^ unused_format_specs - } fn should_not_lint_user() { diff --git a/tests/ui/unused_format_specs.2.fixed b/tests/ui/unused_format_specs.2.fixed index f8d5f615e045..c1f3d4fa20c6 100644 --- a/tests/ui/unused_format_specs.2.fixed +++ b/tests/ui/unused_format_specs.2.fixed @@ -12,20 +12,16 @@ fn main() { println!("{}.", format_args!("")); //~^ unused_format_specs - //prints `abcde`, not `abc` println!("{}", format_args!("abcde")); //~^ unused_format_specs - println!("{}.", format_args_from_macro!()); //~^ unused_format_specs - let args = format_args!(""); println!("{args}"); //~^ unused_format_specs - } fn should_not_lint() { @@ -56,15 +52,12 @@ fn should_lint_user() { usr_println!(true, "{}", format_args!("abcde")); //~^ unused_format_specs - usr_println!(true, "{}.", format_args_from_macro!()); //~^ unused_format_specs - let args = format_args!(""); usr_println!(true, "{args}"); //~^ unused_format_specs - } fn should_not_lint_user() { diff --git a/tests/ui/unused_format_specs.rs b/tests/ui/unused_format_specs.rs index 777901258a77..b47047ba34e5 100644 --- a/tests/ui/unused_format_specs.rs +++ b/tests/ui/unused_format_specs.rs @@ -12,20 +12,16 @@ fn main() { println!("{:5}.", format_args!("")); //~^ unused_format_specs - //prints `abcde`, not `abc` println!("{:.3}", format_args!("abcde")); //~^ unused_format_specs - println!("{:5}.", format_args_from_macro!()); //~^ unused_format_specs - let args = format_args!(""); println!("{args:5}"); //~^ unused_format_specs - } fn should_not_lint() { @@ -56,15 +52,12 @@ fn should_lint_user() { usr_println!(true, "{:.3}", format_args!("abcde")); //~^ unused_format_specs - usr_println!(true, "{:5}.", format_args_from_macro!()); //~^ unused_format_specs - let args = format_args!(""); usr_println!(true, "{args:5}"); //~^ unused_format_specs - } fn should_not_lint_user() { diff --git a/tests/ui/unused_format_specs.stderr b/tests/ui/unused_format_specs.stderr index a88a808afe82..704e4987ec4a 100644 --- a/tests/ui/unused_format_specs.stderr +++ b/tests/ui/unused_format_specs.stderr @@ -17,7 +17,7 @@ LL + println!("{}.", format_args!("")); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:17:15 + --> tests/ui/unused_format_specs.rs:16:15 | LL | println!("{:.3}", format_args!("abcde")); | ^^^^^ @@ -33,7 +33,7 @@ LL + println!("{}", format_args!("abcde")); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:21:15 + --> tests/ui/unused_format_specs.rs:19:15 | LL | println!("{:5}.", format_args_from_macro!()); | ^^^^ @@ -46,7 +46,7 @@ LL + println!("{}.", format_args_from_macro!()); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:26:15 + --> tests/ui/unused_format_specs.rs:23:15 | LL | println!("{args:5}"); | ^^^^^^^^ @@ -59,7 +59,7 @@ LL + println!("{args}"); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:52:25 + --> tests/ui/unused_format_specs.rs:48:25 | LL | usr_println!(true, "{:5}.", format_args!("")); | ^^^^ @@ -75,7 +75,7 @@ LL + usr_println!(true, "{}.", format_args!("")); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:56:25 + --> tests/ui/unused_format_specs.rs:52:25 | LL | usr_println!(true, "{:.3}", format_args!("abcde")); | ^^^^^ @@ -91,7 +91,7 @@ LL + usr_println!(true, "{}", format_args!("abcde")); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:60:25 + --> tests/ui/unused_format_specs.rs:55:25 | LL | usr_println!(true, "{:5}.", format_args_from_macro!()); | ^^^^ @@ -104,7 +104,7 @@ LL + usr_println!(true, "{}.", format_args_from_macro!()); | error: format specifiers have no effect on `format_args!()` - --> tests/ui/unused_format_specs.rs:65:25 + --> tests/ui/unused_format_specs.rs:59:25 | LL | usr_println!(true, "{args:5}"); | ^^^^^^^^ diff --git a/tests/ui/unused_io_amount.rs b/tests/ui/unused_io_amount.rs index f0531836db1c..32a50375806a 100644 --- a/tests/ui/unused_io_amount.rs +++ b/tests/ui/unused_io_amount.rs @@ -66,7 +66,7 @@ fn combine_or(file: &str) -> Result<(), Error> { let mut reader = std::fs::File::open(file).unwrap(); let mut result = [0u8; 0]; reader - //~^ unused_io_amount + //~^ unused_io_amount .read(&mut result) .or(Err(Error::Kind)) .or(Err(Error::Kind)) @@ -146,14 +146,14 @@ async fn undetected_bad_async_write(w: &mut W) { fn match_okay_underscore(s: &mut T) { match s.write(b"test") { - //~^ unused_io_amount + //~^ unused_io_amount Ok(_) => todo!(), Err(_) => todo!(), }; let mut buf = [0u8; 4]; match s.read(&mut buf) { - //~^ unused_io_amount + //~^ unused_io_amount Ok(_) => todo!(), Err(_) => todo!(), } @@ -161,7 +161,7 @@ fn match_okay_underscore(s: &mut T) { fn match_okay_underscore_read_expr(s: &mut T) { match s.read(&mut [0u8; 4]) { - //~^ unused_io_amount + //~^ unused_io_amount Ok(_) => todo!(), Err(_) => todo!(), } @@ -169,7 +169,7 @@ fn match_okay_underscore_read_expr(s: &mut T) { fn match_okay_underscore_write_expr(s: &mut T) { match s.write(b"test") { - //~^ unused_io_amount + //~^ unused_io_amount Ok(_) => todo!(), Err(_) => todo!(), } @@ -181,21 +181,21 @@ fn returned_value_should_not_lint(s: &mut T) -> Result< fn if_okay_underscore_read_expr(s: &mut T) { if let Ok(_) = s.read(&mut [0u8; 4]) { - //~^ unused_io_amount + //~^ unused_io_amount todo!() } } fn if_okay_underscore_write_expr(s: &mut T) { if let Ok(_) = s.write(b"test") { - //~^ unused_io_amount + //~^ unused_io_amount todo!() } } fn if_okay_dots_write_expr(s: &mut T) { if let Ok(..) = s.write(b"test") { - //~^ unused_io_amount + //~^ unused_io_amount todo!() } } diff --git a/tests/ui/unused_peekable.rs b/tests/ui/unused_peekable.rs index 8382db3be005..e7fe297764eb 100644 --- a/tests/ui/unused_peekable.rs +++ b/tests/ui/unused_peekable.rs @@ -13,19 +13,16 @@ fn invalid() { let peekable = std::iter::empty::().peekable(); //~^ unused_peekable - // Only lint `new_local` let old_local = std::iter::empty::().peekable(); let new_local = old_local; //~^ unused_peekable - // Behind mut ref let mut by_mut_ref_test = std::iter::empty::().peekable(); let by_mut_ref = &mut by_mut_ref_test; //~^ unused_peekable - // Explicitly returns `Peekable` fn returns_peekable() -> Peekable> { std::iter::empty().peekable() @@ -34,7 +31,6 @@ fn invalid() { let peekable_from_fn = returns_peekable(); //~^ unused_peekable - // Using a method not exclusive to `Peekable` let mut peekable_using_iterator_method = std::iter::empty::().peekable(); //~^ unused_peekable @@ -53,7 +49,6 @@ fn invalid() { let _by_ref = by_ref_test.by_ref(); //~^ unused_peekable - let mut peekable_in_for_loop = std::iter::empty::().peekable(); //~^ unused_peekable diff --git a/tests/ui/unused_peekable.stderr b/tests/ui/unused_peekable.stderr index 9b49e32fa8ba..9330d8c58001 100644 --- a/tests/ui/unused_peekable.stderr +++ b/tests/ui/unused_peekable.stderr @@ -9,7 +9,7 @@ LL | let peekable = std::iter::empty::().peekable(); = help: to override `-D warnings` add `#[allow(clippy::unused_peekable)]` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:19:9 + --> tests/ui/unused_peekable.rs:18:9 | LL | let new_local = old_local; | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let new_local = old_local; = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:25:9 + --> tests/ui/unused_peekable.rs:23:9 | LL | let by_mut_ref = &mut by_mut_ref_test; | ^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let by_mut_ref = &mut by_mut_ref_test; = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:34:9 + --> tests/ui/unused_peekable.rs:31:9 | LL | let peekable_from_fn = returns_peekable(); | ^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let peekable_from_fn = returns_peekable(); = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:39:13 + --> tests/ui/unused_peekable.rs:35:13 | LL | let mut peekable_using_iterator_method = std::iter::empty::().peekable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let mut peekable_using_iterator_method = std::iter::empty::().peek = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:46:9 + --> tests/ui/unused_peekable.rs:42:9 | LL | let passed_along_ref = std::iter::empty::().peekable(); | ^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let passed_along_ref = std::iter::empty::().peekable(); = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:53:9 + --> tests/ui/unused_peekable.rs:49:9 | LL | let _by_ref = by_ref_test.by_ref(); | ^^^^^^^ @@ -57,7 +57,7 @@ LL | let _by_ref = by_ref_test.by_ref(); = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> tests/ui/unused_peekable.rs:57:13 + --> tests/ui/unused_peekable.rs:52:13 | LL | let mut peekable_in_for_loop = std::iter::empty::().peekable(); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unused_self.rs b/tests/ui/unused_self.rs index fac0b36c33a4..cb80d946aced 100644 --- a/tests/ui/unused_self.rs +++ b/tests/ui/unused_self.rs @@ -30,12 +30,12 @@ mod unused_self { //~^ unused_self fn unused_with_other_used_args(&self, x: u8, y: u8) -> u8 { - //~^ unused_self + //~^ unused_self x + y } fn unused_self_class_method(&self) { - //~^ unused_self + //~^ unused_self Self::static_method(); } diff --git a/tests/ui/unwrap.rs b/tests/ui/unwrap.rs index 637d2da3750e..3191b396f99b 100644 --- a/tests/ui/unwrap.rs +++ b/tests/ui/unwrap.rs @@ -5,7 +5,6 @@ fn unwrap_option() { let opt = Some(0); let _ = opt.unwrap(); //~^ unwrap_used - } fn unwrap_result() { @@ -15,7 +14,6 @@ fn unwrap_result() { let _ = res.unwrap_err(); //~^ unwrap_used - } fn main() { diff --git a/tests/ui/unwrap.stderr b/tests/ui/unwrap.stderr index c568d8308200..c242541a6bd7 100644 --- a/tests/ui/unwrap.stderr +++ b/tests/ui/unwrap.stderr @@ -10,7 +10,7 @@ LL | let _ = opt.unwrap(); = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]` error: used `unwrap()` on a `Result` value - --> tests/ui/unwrap.rs:13:13 + --> tests/ui/unwrap.rs:12:13 | LL | let _ = res.unwrap(); | ^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | let _ = res.unwrap(); = help: consider using `expect()` to provide a better panic message error: used `unwrap_err()` on a `Result` value - --> tests/ui/unwrap.rs:16:13 + --> tests/ui/unwrap.rs:15:13 | LL | let _ = res.unwrap_err(); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unwrap_expect_used.rs b/tests/ui/unwrap_expect_used.rs index c2c9db775370..d0bb571273b5 100644 --- a/tests/ui/unwrap_expect_used.rs +++ b/tests/ui/unwrap_expect_used.rs @@ -30,7 +30,6 @@ fn main() { Some(3).expect("Hello world!"); //~^ expect_used - // Don't trigger on unwrap_err on an option Some(3).unwrap_err(); Some(3).expect_err("Hello none!"); diff --git a/tests/ui/unwrap_expect_used.stderr b/tests/ui/unwrap_expect_used.stderr index 7476e372bcbb..79eac3f58ccb 100644 --- a/tests/ui/unwrap_expect_used.stderr +++ b/tests/ui/unwrap_expect_used.stderr @@ -19,7 +19,7 @@ LL | Some(3).expect("Hello world!"); = help: to override `-D warnings` add `#[allow(clippy::expect_used)]` error: used `unwrap()` on a `Result` value - --> tests/ui/unwrap_expect_used.rs:47:5 + --> tests/ui/unwrap_expect_used.rs:46:5 | LL | a.unwrap(); | ^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | a.unwrap(); = note: if this value is an `Err`, it will panic error: used `expect()` on a `Result` value - --> tests/ui/unwrap_expect_used.rs:50:5 + --> tests/ui/unwrap_expect_used.rs:49:5 | LL | a.expect("Hello world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | a.expect("Hello world!"); = note: if this value is an `Err`, it will panic error: used `unwrap_err()` on a `Result` value - --> tests/ui/unwrap_expect_used.rs:53:5 + --> tests/ui/unwrap_expect_used.rs:52:5 | LL | a.unwrap_err(); | ^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL | a.unwrap_err(); = note: if this value is an `Ok`, it will panic error: used `expect_err()` on a `Result` value - --> tests/ui/unwrap_expect_used.rs:56:5 + --> tests/ui/unwrap_expect_used.rs:55:5 | LL | a.expect_err("Hello error!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unwrap_in_result.rs b/tests/ui/unwrap_in_result.rs index 58235d138658..4e872c67b423 100644 --- a/tests/ui/unwrap_in_result.rs +++ b/tests/ui/unwrap_in_result.rs @@ -20,7 +20,7 @@ impl A { // should be detected fn bad_divisible_by_3(i_str: String) -> Result { - //~^ unwrap_in_result + //~^ unwrap_in_result // checks whether a string represents a number divisible by 3 let i = i_str.parse::().unwrap(); @@ -32,7 +32,7 @@ impl A { } fn example_option_expect(i_str: String) -> Option { - //~^ unwrap_in_result + //~^ unwrap_in_result let i = i_str.parse::().expect("not a number"); if i % 3 == 0 { @@ -42,7 +42,7 @@ impl A { } fn in_closure(a: Option) -> Option { - //~^ unwrap_in_result + //~^ unwrap_in_result let c = || a.unwrap(); Some(c()) } diff --git a/tests/ui/unwrap_or.fixed b/tests/ui/unwrap_or.fixed index 7a00d346cac5..c794ed577032 100644 --- a/tests/ui/unwrap_or.fixed +++ b/tests/ui/unwrap_or.fixed @@ -4,12 +4,9 @@ fn main() { let s = Some(String::from("test string")).unwrap_or_else(|| "Fail".to_string()).len(); //~^ or_fun_call - - } fn new_lines() { let s = Some(String::from("test string")).unwrap_or_else(|| "Fail".to_string()).len(); //~^ or_fun_call - } diff --git a/tests/ui/unwrap_or.rs b/tests/ui/unwrap_or.rs index 30779ac1b109..11a6883b7403 100644 --- a/tests/ui/unwrap_or.rs +++ b/tests/ui/unwrap_or.rs @@ -4,12 +4,9 @@ fn main() { let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len(); //~^ or_fun_call - - } fn new_lines() { let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len(); //~^ or_fun_call - } diff --git a/tests/ui/unwrap_or.stderr b/tests/ui/unwrap_or.stderr index b2c20a9e9b5e..e95633680acc 100644 --- a/tests/ui/unwrap_or.stderr +++ b/tests/ui/unwrap_or.stderr @@ -8,7 +8,7 @@ LL | let s = Some(String::from("test string")).unwrap_or("Fail".to_string()) = help: to override `-D warnings` add `#[allow(clippy::or_fun_call)]` error: function call inside of `unwrap_or` - --> tests/ui/unwrap_or.rs:12:47 + --> tests/ui/unwrap_or.rs:10:47 | LL | let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| "Fail".to_string())` diff --git a/tests/ui/upper_case_acronyms.fixed b/tests/ui/upper_case_acronyms.fixed index b8c10b370680..da44c8e3026e 100644 --- a/tests/ui/upper_case_acronyms.fixed +++ b/tests/ui/upper_case_acronyms.fixed @@ -8,29 +8,20 @@ enum Flags { NS, // not linted Cwr, //~^ upper_case_acronyms - - Ece, //~^ upper_case_acronyms - Urg, //~^ upper_case_acronyms - Ack, //~^ upper_case_acronyms - Psh, //~^ upper_case_acronyms - Rst, //~^ upper_case_acronyms - Syn, //~^ upper_case_acronyms - Fin, //~^ upper_case_acronyms - } // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of @@ -52,7 +43,6 @@ pub enum ParseError { enum ParseErrorPrivate { Wasd(u8), //~^ upper_case_acronyms - Utf8(std::string::FromUtf8Error), Parse(T, String), } @@ -61,11 +51,9 @@ enum ParseErrorPrivate { struct Json; //~^ upper_case_acronyms - // do lint here enum Yaml { -//~^ upper_case_acronyms - + //~^ upper_case_acronyms Num(u32), Str(String), } @@ -74,7 +62,6 @@ enum Yaml { enum AllowOnField { Disallow, //~^ upper_case_acronyms - #[allow(clippy::upper_case_acronyms)] ALLOW, } diff --git a/tests/ui/upper_case_acronyms.rs b/tests/ui/upper_case_acronyms.rs index 4ad6c6d4c8c8..d223b02acda9 100644 --- a/tests/ui/upper_case_acronyms.rs +++ b/tests/ui/upper_case_acronyms.rs @@ -8,29 +8,20 @@ enum Flags { NS, // not linted CWR, //~^ upper_case_acronyms - - ECE, //~^ upper_case_acronyms - URG, //~^ upper_case_acronyms - ACK, //~^ upper_case_acronyms - PSH, //~^ upper_case_acronyms - RST, //~^ upper_case_acronyms - SYN, //~^ upper_case_acronyms - FIN, //~^ upper_case_acronyms - } // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of @@ -52,7 +43,6 @@ pub enum ParseError { enum ParseErrorPrivate { WASD(u8), //~^ upper_case_acronyms - Utf8(std::string::FromUtf8Error), Parse(T, String), } @@ -61,11 +51,9 @@ enum ParseErrorPrivate { struct JSON; //~^ upper_case_acronyms - // do lint here enum YAML { -//~^ upper_case_acronyms - + //~^ upper_case_acronyms Num(u32), Str(String), } @@ -74,7 +62,6 @@ enum YAML { enum AllowOnField { DISALLOW, //~^ upper_case_acronyms - #[allow(clippy::upper_case_acronyms)] ALLOW, } diff --git a/tests/ui/upper_case_acronyms.stderr b/tests/ui/upper_case_acronyms.stderr index 24e1d808d8ed..dd548fc143e2 100644 --- a/tests/ui/upper_case_acronyms.stderr +++ b/tests/ui/upper_case_acronyms.stderr @@ -8,67 +8,67 @@ LL | CWR, = help: to override `-D warnings` add `#[allow(clippy::upper_case_acronyms)]` error: name `ECE` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:13:5 + --> tests/ui/upper_case_acronyms.rs:11:5 | LL | ECE, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Ece` error: name `URG` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:16:5 + --> tests/ui/upper_case_acronyms.rs:13:5 | LL | URG, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Urg` error: name `ACK` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:19:5 + --> tests/ui/upper_case_acronyms.rs:15:5 | LL | ACK, | ^^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ack` error: name `PSH` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:22:5 + --> tests/ui/upper_case_acronyms.rs:17:5 | LL | PSH, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Psh` error: name `RST` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:25:5 + --> tests/ui/upper_case_acronyms.rs:19:5 | LL | RST, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Rst` error: name `SYN` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:28:5 + --> tests/ui/upper_case_acronyms.rs:21:5 | LL | SYN, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Syn` error: name `FIN` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:31:5 + --> tests/ui/upper_case_acronyms.rs:23:5 | LL | FIN, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Fin` error: name `WASD` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:53:5 + --> tests/ui/upper_case_acronyms.rs:44:5 | LL | WASD(u8), | ^^^^ help: consider making the acronym lowercase, except the initial letter: `Wasd` error: name `JSON` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:61:8 + --> tests/ui/upper_case_acronyms.rs:51:8 | LL | struct JSON; | ^^^^ help: consider making the acronym lowercase, except the initial letter: `Json` error: name `YAML` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:66:6 + --> tests/ui/upper_case_acronyms.rs:55:6 | LL | enum YAML { | ^^^^ help: consider making the acronym lowercase, except the initial letter: `Yaml` error: name `DISALLOW` contains a capitalized acronym - --> tests/ui/upper_case_acronyms.rs:75:5 + --> tests/ui/upper_case_acronyms.rs:63:5 | LL | DISALLOW, | ^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `Disallow` diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index faabf0e256db..f15e5e0a5bb4 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -21,12 +21,12 @@ mod use_self { impl Foo { fn new() -> Self { - //~^ use_self + //~^ use_self Self {} //~^ use_self } fn test() -> Self { - //~^ use_self + //~^ use_self Self::new() //~^ use_self } @@ -34,7 +34,7 @@ mod use_self { impl Default for Foo { fn default() -> Self { - //~^ use_self + //~^ use_self Self::new() //~^ use_self } @@ -78,7 +78,7 @@ mod lifetimes { } fn clone(&self) -> Self { - //~^ use_self + //~^ use_self Foo { foo_str: self.foo_str } } @@ -112,8 +112,8 @@ mod existential { impl Foo { fn bad(foos: &[Self]) -> impl Iterator { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self foos.iter() } @@ -165,7 +165,7 @@ mod nesting { impl Bar { fn bar() -> Self { - //~^ use_self + //~^ use_self Self { foo: Foo {} } //~^ use_self } @@ -179,7 +179,7 @@ mod nesting { // Should lint here fn baz() -> Self { - //~^ use_self + //~^ use_self Self {} //~^ use_self } @@ -286,7 +286,7 @@ mod paths_created_by_lowering { const B: usize = 1; async fn g() -> Self { - //~^ use_self + //~^ use_self Self {} //~^ use_self } @@ -318,7 +318,7 @@ mod generics { impl Foo { // `Self` is applicable here fn foo(value: T) -> Self { - //~^ use_self + //~^ use_self Self { value } //~^ use_self } @@ -578,7 +578,7 @@ mod use_self_in_pat { None => unimplemented!(), } if let Self::Bar = self { - //~^ use_self + //~^ use_self unimplemented!() } } diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index b91856e48097..b6376938611e 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -21,12 +21,12 @@ mod use_self { impl Foo { fn new() -> Foo { - //~^ use_self + //~^ use_self Foo {} //~^ use_self } fn test() -> Foo { - //~^ use_self + //~^ use_self Foo::new() //~^ use_self } @@ -34,7 +34,7 @@ mod use_self { impl Default for Foo { fn default() -> Foo { - //~^ use_self + //~^ use_self Foo::new() //~^ use_self } @@ -78,7 +78,7 @@ mod lifetimes { } fn clone(&self) -> Foo<'a> { - //~^ use_self + //~^ use_self Foo { foo_str: self.foo_str } } @@ -112,8 +112,8 @@ mod existential { impl Foo { fn bad(foos: &[Foo]) -> impl Iterator { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self foos.iter() } @@ -165,7 +165,7 @@ mod nesting { impl Bar { fn bar() -> Bar { - //~^ use_self + //~^ use_self Bar { foo: Foo {} } //~^ use_self } @@ -179,7 +179,7 @@ mod nesting { // Should lint here fn baz() -> Foo { - //~^ use_self + //~^ use_self Foo {} //~^ use_self } @@ -286,7 +286,7 @@ mod paths_created_by_lowering { const B: usize = 1; async fn g() -> S { - //~^ use_self + //~^ use_self S {} //~^ use_self } @@ -318,7 +318,7 @@ mod generics { impl Foo { // `Self` is applicable here fn foo(value: T) -> Foo { - //~^ use_self + //~^ use_self Foo:: { value } //~^ use_self } @@ -578,7 +578,7 @@ mod use_self_in_pat { None => unimplemented!(), } if let Foo::Bar = self { - //~^ use_self + //~^ use_self unimplemented!() } } diff --git a/tests/ui/use_self_trait.fixed b/tests/ui/use_self_trait.fixed index 2df7eec92f2f..820282d8da54 100644 --- a/tests/ui/use_self_trait.fixed +++ b/tests/ui/use_self_trait.fixed @@ -17,20 +17,20 @@ struct Bad; impl SelfTrait for Bad { fn refs(p1: &Self) -> &Self { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self p1 } fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self p1 } fn mut_refs(p1: &mut Self) -> &mut Self { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self p1 } @@ -39,8 +39,8 @@ impl SelfTrait for Bad { //~| use_self fn vals(_: Self) -> Self { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self Self //~^ use_self } @@ -51,8 +51,8 @@ impl Mul for Bad { //~^ use_self fn mul(self, rhs: Self) -> Self { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self rhs } } diff --git a/tests/ui/use_self_trait.rs b/tests/ui/use_self_trait.rs index 48118e59fe67..aa9761e5609f 100644 --- a/tests/ui/use_self_trait.rs +++ b/tests/ui/use_self_trait.rs @@ -17,20 +17,20 @@ struct Bad; impl SelfTrait for Bad { fn refs(p1: &Bad) -> &Bad { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self p1 } fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self p1 } fn mut_refs(p1: &mut Bad) -> &mut Bad { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self p1 } @@ -39,8 +39,8 @@ impl SelfTrait for Bad { //~| use_self fn vals(_: Bad) -> Bad { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self Bad //~^ use_self } @@ -51,8 +51,8 @@ impl Mul for Bad { //~^ use_self fn mul(self, rhs: Bad) -> Bad { - //~^ use_self - //~| use_self + //~^ use_self + //~| use_self rhs } } diff --git a/tests/ui/useless_asref.fixed b/tests/ui/useless_asref.fixed index 235b49649001..e399bd76fc1e 100644 --- a/tests/ui/useless_asref.fixed +++ b/tests/ui/useless_asref.fixed @@ -157,7 +157,6 @@ fn foo() { let z = x.clone(); //~^ useless_asref - } mod issue12135 { @@ -189,13 +188,11 @@ mod issue12135 { x.field.clone(); //~^ useless_asref - // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223 #[allow(clippy::clone_on_copy)] Some(1).clone(); //~^ useless_asref - x.field.as_ref().map(|v| v.method().clone()) } } diff --git a/tests/ui/useless_asref.rs b/tests/ui/useless_asref.rs index 261bbe18e357..4c76a2ecf7b0 100644 --- a/tests/ui/useless_asref.rs +++ b/tests/ui/useless_asref.rs @@ -157,7 +157,6 @@ fn foo() { let z = x.as_ref().map(|z| String::clone(z)); //~^ useless_asref - } mod issue12135 { @@ -189,13 +188,11 @@ mod issue12135 { x.field.as_ref().map(|v| Clone::clone(v)); //~^ useless_asref - // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223 #[allow(clippy::clone_on_copy)] Some(1).as_ref().map(|&x| x.clone()); //~^ useless_asref - x.field.as_ref().map(|v| v.method().clone()) } } diff --git a/tests/ui/useless_asref.stderr b/tests/ui/useless_asref.stderr index 97be7996f008..d0ca10936fd5 100644 --- a/tests/ui/useless_asref.stderr +++ b/tests/ui/useless_asref.stderr @@ -89,25 +89,25 @@ LL | let z = x.as_ref().map(|z| String::clone(z)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:183:9 + --> tests/ui/useless_asref.rs:182:9 | LL | x.field.as_ref().map(|v| v.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:186:9 + --> tests/ui/useless_asref.rs:185:9 | LL | x.field.as_ref().map(Clone::clone); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:189:9 + --> tests/ui/useless_asref.rs:188:9 | LL | x.field.as_ref().map(|v| Clone::clone(v)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:195:9 + --> tests/ui/useless_asref.rs:193:9 | LL | Some(1).as_ref().map(|&x| x.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(1).clone()` diff --git a/tests/ui/useless_conversion.fixed b/tests/ui/useless_conversion.fixed index 2b9ef0209047..489caacf2123 100644 --- a/tests/ui/useless_conversion.fixed +++ b/tests/ui/useless_conversion.fixed @@ -341,7 +341,6 @@ fn direct_application() { let _: Result<(), std::io::Error> = test_issue_3913(); //~^ useless_conversion - let c: ControlFlow<()> = ControlFlow::Continue(()); let _: ControlFlow<()> = c; //~^ useless_conversion @@ -350,7 +349,6 @@ fn direct_application() { let _: ControlFlow<()> = c; //~^ useless_conversion - struct Absorb; impl From<()> for Absorb { fn from(_: ()) -> Self { @@ -365,7 +363,6 @@ fn direct_application() { let _: Vec = [1u32].into_iter().collect(); //~^ useless_conversion - // No lint for those let _: Result = test_issue_3913().map(Into::into); let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into); @@ -376,7 +373,6 @@ fn direct_application() { fn gen_identity(x: [T; 3]) -> Vec { x.into_iter().collect() //~^ useless_conversion - } mod issue11819 { @@ -393,7 +389,6 @@ mod issue11819 { { takes_into_iter(&self.my_field); //~^ useless_conversion - } pub fn with_ref_mut<'a>(&'a mut self) @@ -402,7 +397,6 @@ mod issue11819 { { takes_into_iter(&mut self.my_field); //~^ useless_conversion - } pub fn with_deref(&mut self) @@ -412,7 +406,6 @@ mod issue11819 { { takes_into_iter(*self.my_field); //~^ useless_conversion - } pub fn with_reborrow<'a, Y: 'a>(&'a mut self) @@ -422,7 +415,6 @@ mod issue11819 { { takes_into_iter(&*self.my_field); //~^ useless_conversion - } pub fn with_reborrow_mut<'a, Y: 'a>(&'a mut self) @@ -432,7 +424,6 @@ mod issue11819 { { takes_into_iter(&mut *self.my_field); //~^ useless_conversion - } } } diff --git a/tests/ui/useless_conversion.rs b/tests/ui/useless_conversion.rs index 84b5b12580e5..4f3a3b00ea20 100644 --- a/tests/ui/useless_conversion.rs +++ b/tests/ui/useless_conversion.rs @@ -341,7 +341,6 @@ fn direct_application() { let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from); //~^ useless_conversion - let c: ControlFlow<()> = ControlFlow::Continue(()); let _: ControlFlow<()> = c.map_break(Into::into); //~^ useless_conversion @@ -350,7 +349,6 @@ fn direct_application() { let _: ControlFlow<()> = c.map_continue(Into::into); //~^ useless_conversion - struct Absorb; impl From<()> for Absorb { fn from(_: ()) -> Self { @@ -365,7 +363,6 @@ fn direct_application() { let _: Vec = [1u32].into_iter().map(Into::into).collect(); //~^ useless_conversion - // No lint for those let _: Result = test_issue_3913().map(Into::into); let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into); @@ -376,7 +373,6 @@ fn direct_application() { fn gen_identity(x: [T; 3]) -> Vec { x.into_iter().map(Into::into).collect() //~^ useless_conversion - } mod issue11819 { @@ -393,7 +389,6 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion - } pub fn with_ref_mut<'a>(&'a mut self) @@ -402,7 +397,6 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion - } pub fn with_deref(&mut self) @@ -412,7 +406,6 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion - } pub fn with_reborrow<'a, Y: 'a>(&'a mut self) @@ -422,7 +415,6 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion - } pub fn with_reborrow_mut<'a, Y: 'a>(&'a mut self) @@ -432,7 +424,6 @@ mod issue11819 { { takes_into_iter(self.my_field.into_iter()); //~^ useless_conversion - } } } diff --git a/tests/ui/useless_conversion.stderr b/tests/ui/useless_conversion.stderr index 39c625429c66..3cde2a786e46 100644 --- a/tests/ui/useless_conversion.stderr +++ b/tests/ui/useless_conversion.stderr @@ -269,37 +269,37 @@ LL | let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::fro | ^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:346:31 + --> tests/ui/useless_conversion.rs:345:31 | LL | let _: ControlFlow<()> = c.map_break(Into::into); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:350:31 + --> tests/ui/useless_conversion.rs:349:31 | LL | let _: ControlFlow<()> = c.map_continue(Into::into); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `u32` - --> tests/ui/useless_conversion.rs:365:41 + --> tests/ui/useless_conversion.rs:363:41 | LL | let _: Vec = [1u32].into_iter().map(Into::into).collect(); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion.rs:377:18 + --> tests/ui/useless_conversion.rs:374:18 | LL | x.into_iter().map(Into::into).collect() | ^^^^^^^^^^^^^^^^ help: consider removing error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:394:29 + --> tests/ui/useless_conversion.rs:390:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:383:32 + --> tests/ui/useless_conversion.rs:379:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -310,13 +310,13 @@ LL + takes_into_iter(&self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:403:29 + --> tests/ui/useless_conversion.rs:398:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:383:32 + --> tests/ui/useless_conversion.rs:379:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -327,13 +327,13 @@ LL + takes_into_iter(&mut self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:413:29 + --> tests/ui/useless_conversion.rs:407:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:383:32 + --> tests/ui/useless_conversion.rs:379:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -344,13 +344,13 @@ LL + takes_into_iter(*self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:423:29 + --> tests/ui/useless_conversion.rs:416:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:383:32 + --> tests/ui/useless_conversion.rs:379:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -361,13 +361,13 @@ LL + takes_into_iter(&*self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:433:29 + --> tests/ui/useless_conversion.rs:425:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:383:32 + --> tests/ui/useless_conversion.rs:379:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/useless_conversion_try.rs b/tests/ui/useless_conversion_try.rs index 7f469a819ef2..d16506d94aa3 100644 --- a/tests/ui/useless_conversion_try.rs +++ b/tests/ui/useless_conversion_try.rs @@ -11,7 +11,6 @@ fn test_generic(val: T) -> T { val.try_into().unwrap() //~^ useless_conversion - } fn test_generic2 + Into, U: From>(val: T) { @@ -52,8 +51,7 @@ fn main() { //~^ useless_conversion let _: String = match String::from("_").try_into() { - //~^ useless_conversion - + //~^ useless_conversion Ok(a) => a, Err(_) => String::new(), }; diff --git a/tests/ui/useless_conversion_try.stderr b/tests/ui/useless_conversion_try.stderr index af2199837bf7..1c62426c8952 100644 --- a/tests/ui/useless_conversion_try.stderr +++ b/tests/ui/useless_conversion_try.stderr @@ -20,7 +20,7 @@ LL | val.try_into().unwrap() = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:36:21 + --> tests/ui/useless_conversion_try.rs:35:21 | LL | let _: String = "foo".to_string().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | let _: String = "foo".to_string().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:39:21 + --> tests/ui/useless_conversion_try.rs:38:21 | LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); = help: consider removing `TryFrom::try_from()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:42:13 + --> tests/ui/useless_conversion_try.rs:41:13 | LL | let _ = String::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | let _ = String::try_from("foo".to_string()).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:45:13 + --> tests/ui/useless_conversion_try.rs:44:13 | LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:48:21 + --> tests/ui/useless_conversion_try.rs:47:21 | LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:51:21 + --> tests/ui/useless_conversion_try.rs:50:21 | LL | let _: String = String::new().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | let _: String = String::new().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:54:27 + --> tests/ui/useless_conversion_try.rs:53:27 | LL | let _: String = match String::from("_").try_into() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/useless_nonzero_new_unchecked.fixed b/tests/ui/useless_nonzero_new_unchecked.fixed index 8e5e105215a9..f7f60bbe3f8d 100644 --- a/tests/ui/useless_nonzero_new_unchecked.fixed +++ b/tests/ui/useless_nonzero_new_unchecked.fixed @@ -6,7 +6,6 @@ use std::num::{NonZero, NonZeroUsize}; const fn func() -> NonZeroUsize { const { NonZeroUsize::new(3).unwrap() } //~^ useless_nonzero_new_unchecked - } #[clippy::msrv = "1.82"] @@ -38,20 +37,16 @@ fn main() { const _A: NonZeroUsize = NonZeroUsize::new(3).unwrap(); //~^ useless_nonzero_new_unchecked - static _B: NonZero = NonZero::::new(42).unwrap(); //~^ useless_nonzero_new_unchecked - const _C: usize = unsafe { NonZeroUsize::new(3).unwrap().get() }; //~^ useless_nonzero_new_unchecked - const AUX: usize = 3; const _D: NonZeroUsize = NonZeroUsize::new(AUX).unwrap(); //~^ useless_nonzero_new_unchecked - const _X: NonZeroUsize = uns!(NonZeroUsize::new_unchecked(3)); const _Y: NonZeroUsize = unsafe { nzu!() }; } diff --git a/tests/ui/useless_nonzero_new_unchecked.rs b/tests/ui/useless_nonzero_new_unchecked.rs index 43fd1f2e5849..c90a63915efb 100644 --- a/tests/ui/useless_nonzero_new_unchecked.rs +++ b/tests/ui/useless_nonzero_new_unchecked.rs @@ -6,7 +6,6 @@ use std::num::{NonZero, NonZeroUsize}; const fn func() -> NonZeroUsize { const { unsafe { NonZeroUsize::new_unchecked(3) } } //~^ useless_nonzero_new_unchecked - } #[clippy::msrv = "1.82"] @@ -38,20 +37,16 @@ fn main() { const _A: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) }; //~^ useless_nonzero_new_unchecked - static _B: NonZero = unsafe { NonZero::::new_unchecked(42) }; //~^ useless_nonzero_new_unchecked - const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() }; //~^ useless_nonzero_new_unchecked - const AUX: usize = 3; const _D: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(AUX) }; //~^ useless_nonzero_new_unchecked - const _X: NonZeroUsize = uns!(NonZeroUsize::new_unchecked(3)); const _Y: NonZeroUsize = unsafe { nzu!() }; } diff --git a/tests/ui/useless_nonzero_new_unchecked.stderr b/tests/ui/useless_nonzero_new_unchecked.stderr index b9fc333dd4f5..adb146167633 100644 --- a/tests/ui/useless_nonzero_new_unchecked.stderr +++ b/tests/ui/useless_nonzero_new_unchecked.stderr @@ -8,19 +8,19 @@ LL | const { unsafe { NonZeroUsize::new_unchecked(3) } } = help: to override `-D warnings` add `#[allow(clippy::useless_nonzero_new_unchecked)]` error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context - --> tests/ui/useless_nonzero_new_unchecked.rs:38:30 + --> tests/ui/useless_nonzero_new_unchecked.rs:37:30 | LL | const _A: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()` error: `NonZero::::new()` and `Option::unwrap()` can be safely used in a `const` context - --> tests/ui/useless_nonzero_new_unchecked.rs:42:30 + --> tests/ui/useless_nonzero_new_unchecked.rs:40:30 | LL | static _B: NonZero = unsafe { NonZero::::new_unchecked(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZero::::new(42).unwrap()` error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context - --> tests/ui/useless_nonzero_new_unchecked.rs:46:32 + --> tests/ui/useless_nonzero_new_unchecked.rs:43:32 | LL | const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()` @@ -28,7 +28,7 @@ LL | const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() }; = note: the fixed expression does not require an `unsafe` context error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context - --> tests/ui/useless_nonzero_new_unchecked.rs:51:30 + --> tests/ui/useless_nonzero_new_unchecked.rs:47:30 | LL | const _D: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(AUX) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(AUX).unwrap()` diff --git a/tests/ui/useless_vec.rs b/tests/ui/useless_vec.rs index 65aafb66568f..880809f81d7a 100644 --- a/tests/ui/useless_vec.rs +++ b/tests/ui/useless_vec.rs @@ -6,8 +6,7 @@ fn foo() { // There should be no suggestion in this case. let _some_variable = vec![ - //~^ useless_vec - + //~^ useless_vec 1, 2, // i'm here to stay 3, 4, // but this one going away ;-; ]; // that is life anyways diff --git a/tests/ui/useless_vec.stderr b/tests/ui/useless_vec.stderr index 39927d0b4654..e47364fb06d3 100644 --- a/tests/ui/useless_vec.stderr +++ b/tests/ui/useless_vec.stderr @@ -4,7 +4,6 @@ error: useless use of `vec!` LL | let _some_variable = vec![ | __________________________^ LL | | -LL | | LL | | 1, 2, // i'm here to stay LL | | 3, 4, // but this one going away ;-; LL | | ]; // that is life anyways diff --git a/tests/ui/vec.fixed b/tests/ui/vec.fixed index 5b35b2b26243..f360a8afadf6 100644 --- a/tests/ui/vec.fixed +++ b/tests/ui/vec.fixed @@ -136,7 +136,7 @@ fn issue11075() { } #[allow(clippy::never_loop)] for _string in [repro!(true), repro!(null)] { - //~^ useless_vec + //~^ useless_vec unimplemented!(); } @@ -175,12 +175,12 @@ fn issue11075() { #[clippy::msrv = "1.53"] fn above() { for a in [1, 2, 3] { - //~^ useless_vec + //~^ useless_vec let _: usize = a; } for a in [String::new(), String::new()] { - //~^ useless_vec + //~^ useless_vec let _: String = a; } } @@ -212,8 +212,8 @@ fn issue11861() { // Do not lint the next line this_macro_needs_vec!(vec![1]); -this_macro_doesnt_need_vec!([1]); -//~^ useless_vec + this_macro_doesnt_need_vec!([1]); + //~^ useless_vec macro_rules! m { ($x:expr) => { diff --git a/tests/ui/vec.rs b/tests/ui/vec.rs index c82580b2fd1a..a779d33557cb 100644 --- a/tests/ui/vec.rs +++ b/tests/ui/vec.rs @@ -136,7 +136,7 @@ fn issue11075() { } #[allow(clippy::never_loop)] for _string in vec![repro!(true), repro!(null)] { - //~^ useless_vec + //~^ useless_vec unimplemented!(); } @@ -175,12 +175,12 @@ fn issue11075() { #[clippy::msrv = "1.53"] fn above() { for a in vec![1, 2, 3] { - //~^ useless_vec + //~^ useless_vec let _: usize = a; } for a in vec![String::new(), String::new()] { - //~^ useless_vec + //~^ useless_vec let _: String = a; } } @@ -212,8 +212,8 @@ fn issue11861() { // Do not lint the next line this_macro_needs_vec!(vec![1]); -this_macro_doesnt_need_vec!(vec![1]); -//~^ useless_vec + this_macro_doesnt_need_vec!(vec![1]); + //~^ useless_vec macro_rules! m { ($x:expr) => { diff --git a/tests/ui/vec.stderr b/tests/ui/vec.stderr index 1063e0e37d89..806d6617200f 100644 --- a/tests/ui/vec.stderr +++ b/tests/ui/vec.stderr @@ -116,10 +116,10 @@ LL | for a in vec![String::new(), String::new()] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` error: useless use of `vec!` - --> tests/ui/vec.rs:215:29 + --> tests/ui/vec.rs:215:33 | -LL | this_macro_doesnt_need_vec!(vec![1]); - | ^^^^^^^ help: you can use an array directly: `[1]` +LL | this_macro_doesnt_need_vec!(vec![1]); + | ^^^^^^^ help: you can use an array directly: `[1]` error: useless use of `vec!` --> tests/ui/vec.rs:242:14 diff --git a/tests/ui/vec_box_sized.rs b/tests/ui/vec_box_sized.rs index d32081c26a03..897add423b6d 100644 --- a/tests/ui/vec_box_sized.rs +++ b/tests/ui/vec_box_sized.rs @@ -39,15 +39,15 @@ mod should_trigger { //~^ vec_box fn allocator_global_defined_vec() -> Vec, std::alloc::Global> { - //~^ vec_box + //~^ vec_box Vec::new() } fn allocator_global_defined_box() -> Vec> { - //~^ vec_box + //~^ vec_box Vec::new() } fn allocator_match() -> Vec, DummyAllocator> { - //~^ vec_box + //~^ vec_box Vec::new_in(DummyAllocator) } } @@ -85,7 +85,7 @@ mod inner_mod { use super::inner::S; pub fn f() -> Vec> { - //~^ vec_box + //~^ vec_box vec![] } } diff --git a/tests/ui/vec_init_then_push.rs b/tests/ui/vec_init_then_push.rs index 31cd84d2cf40..a32187edfea6 100644 --- a/tests/ui/vec_init_then_push.rs +++ b/tests/ui/vec_init_then_push.rs @@ -5,7 +5,6 @@ fn main() { let mut def_err: Vec = Default::default(); //~^ vec_init_then_push - def_err.push(0); let mut new_err = Vec::::new(); diff --git a/tests/ui/vec_init_then_push.stderr b/tests/ui/vec_init_then_push.stderr index 3be277bb07b9..1900ad7bd6a0 100644 --- a/tests/ui/vec_init_then_push.stderr +++ b/tests/ui/vec_init_then_push.stderr @@ -10,7 +10,7 @@ LL | | def_err.push(0); = help: to override `-D warnings` add `#[allow(clippy::vec_init_then_push)]` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:11:5 + --> tests/ui/vec_init_then_push.rs:10:5 | LL | / let mut new_err = Vec::::new(); ... | @@ -18,7 +18,7 @@ LL | | new_err.push(1); | |____________________^ help: consider using the `vec![]` macro: `let mut new_err = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:16:5 + --> tests/ui/vec_init_then_push.rs:15:5 | LL | / let mut cap_err = Vec::with_capacity(2); LL | | @@ -29,7 +29,7 @@ LL | | cap_err.push(2); | |____________________^ help: consider using the `vec![]` macro: `let mut cap_err = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:30:5 + --> tests/ui/vec_init_then_push.rs:29:5 | LL | / new_err = Vec::new(); ... | @@ -37,7 +37,7 @@ LL | | new_err.push(0); | |____________________^ help: consider using the `vec![]` macro: `new_err = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:82:5 + --> tests/ui/vec_init_then_push.rs:81:5 | LL | / let mut v = Vec::new(); LL | | @@ -47,7 +47,7 @@ LL | | v.push(1); | |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:92:5 + --> tests/ui/vec_init_then_push.rs:91:5 | LL | / let mut v = Vec::new(); LL | | @@ -59,7 +59,7 @@ LL | | v.push(0); | |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:107:5 + --> tests/ui/vec_init_then_push.rs:106:5 | LL | / let mut v2 = Vec::new(); LL | | @@ -71,7 +71,7 @@ LL | | v2.push(0); | |_______________^ help: consider using the `vec![]` macro: `let mut v2 = vec![..];` error: calls to `push` immediately after creation - --> tests/ui/vec_init_then_push.rs:124:5 + --> tests/ui/vec_init_then_push.rs:123:5 | LL | / let mut v = Vec::new(); ... | diff --git a/tests/ui/vec_resize_to_zero.fixed b/tests/ui/vec_resize_to_zero.fixed index f5c0ecd72e00..260943f655e3 100644 --- a/tests/ui/vec_resize_to_zero.fixed +++ b/tests/ui/vec_resize_to_zero.fixed @@ -7,7 +7,6 @@ fn main() { v.clear(); //~^ vec_resize_to_zero - // not applicable v.resize(2, 5); diff --git a/tests/ui/vec_resize_to_zero.rs b/tests/ui/vec_resize_to_zero.rs index 2b75b475223c..d6054715143c 100644 --- a/tests/ui/vec_resize_to_zero.rs +++ b/tests/ui/vec_resize_to_zero.rs @@ -7,7 +7,6 @@ fn main() { v.resize(0, 5); //~^ vec_resize_to_zero - // not applicable v.resize(2, 5); diff --git a/tests/ui/while_float.rs b/tests/ui/while_float.rs index 06dc700c1980..727b954ffcca 100644 --- a/tests/ui/while_float.rs +++ b/tests/ui/while_float.rs @@ -2,11 +2,11 @@ fn main() { let mut x = 0.0_f32; while x < 42.0_f32 { - //~^ while_float + //~^ while_float x += 0.5; } while x < 42.0 { - //~^ while_float + //~^ while_float x += 1.0; } let mut x = 0; diff --git a/tests/ui/while_let_loop.rs b/tests/ui/while_let_loop.rs index ea442b9b2b5c..d591ab984cfa 100644 --- a/tests/ui/while_let_loop.rs +++ b/tests/ui/while_let_loop.rs @@ -4,8 +4,7 @@ fn main() { let y = Some(true); loop { - //~^ while_let_loop - + //~^ while_let_loop if let Some(_x) = y { let _v = 1; @@ -24,7 +23,7 @@ fn main() { } loop { - //~^ while_let_loop + //~^ while_let_loop match y { Some(_x) => true, @@ -33,7 +32,7 @@ fn main() { } loop { - //~^ while_let_loop + //~^ while_let_loop let x = match y { Some(x) => x, @@ -44,7 +43,7 @@ fn main() { } loop { - //~^ while_let_loop + //~^ while_let_loop let x = match y { Some(x) => x, @@ -76,7 +75,7 @@ fn main() { // #675, this used to have a wrong suggestion loop { - //~^ while_let_loop + //~^ while_let_loop let (e, l) = match "".split_whitespace().next() { Some(word) => (word.is_empty(), word.len()), diff --git a/tests/ui/while_let_loop.stderr b/tests/ui/while_let_loop.stderr index 3bd8ab85a92f..bd482857e675 100644 --- a/tests/ui/while_let_loop.stderr +++ b/tests/ui/while_let_loop.stderr @@ -2,6 +2,9 @@ error: this loop could be written as a `while let` loop --> tests/ui/while_let_loop.rs:6:5 | LL | / loop { +LL | | +LL | | +LL | | if let Some(_x) = y { ... | LL | | } | |_____^ help: try: `while let Some(_x) = y { .. }` @@ -10,7 +13,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::while_let_loop)]` error: this loop could be written as a `while let` loop - --> tests/ui/while_let_loop.rs:26:5 + --> tests/ui/while_let_loop.rs:25:5 | LL | / loop { LL | | @@ -22,7 +25,7 @@ LL | | } | |_____^ help: try: `while let Some(_x) = y { .. }` error: this loop could be written as a `while let` loop - --> tests/ui/while_let_loop.rs:35:5 + --> tests/ui/while_let_loop.rs:34:5 | LL | / loop { LL | | @@ -34,7 +37,7 @@ LL | | } | |_____^ help: try: `while let Some(x) = y { .. }` error: this loop could be written as a `while let` loop - --> tests/ui/while_let_loop.rs:46:5 + --> tests/ui/while_let_loop.rs:45:5 | LL | / loop { LL | | @@ -45,7 +48,7 @@ LL | | } | |_____^ help: try: `while let Some(x) = y { .. }` error: this loop could be written as a `while let` loop - --> tests/ui/while_let_loop.rs:78:5 + --> tests/ui/while_let_loop.rs:77:5 | LL | / loop { LL | | diff --git a/tests/ui/while_let_on_iterator.fixed b/tests/ui/while_let_on_iterator.fixed index bf4950620340..f9ccefab5898 100644 --- a/tests/ui/while_let_on_iterator.fixed +++ b/tests/ui/while_let_on_iterator.fixed @@ -13,13 +13,13 @@ fn base() { let mut iter = 1..20; for x in iter { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{}", x); } let mut iter = 1..20; for x in iter { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{}", x); } @@ -124,7 +124,7 @@ fn refutable2() { let v = vec![[1], [2], [3]]; let mut it = v.iter(); for x @ [_] in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{:?}", x); } } @@ -145,7 +145,7 @@ fn nested_loops() { loop { let mut y = a.iter(); for _ in y { - //~^ while_let_on_iterator + //~^ while_let_on_iterator // use a for loop here } } @@ -203,7 +203,7 @@ fn issue6491() { let mut it = 1..40; while let Some(n) = it.next() { for m in it.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -215,10 +215,10 @@ fn issue6491() { // This is fine, inner loop uses a new iterator. let mut it = 1..40; for n in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator let mut it = 1..40; for m in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -228,7 +228,7 @@ fn issue6491() { // Weird binding shouldn't change anything. let (mut it, _) = (1..40, 0); for m in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -238,7 +238,7 @@ fn issue6491() { // Used after the loop, needs &mut. let mut it = 1..40; for m in it.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -256,7 +256,7 @@ fn issue6231() { let mut opt = Some(0); while let Some(n) = opt.take().or_else(|| it.next()) { for m in it.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if n % 10 == 0 { break; } @@ -272,7 +272,7 @@ fn issue1924() { fn f(&mut self) -> Option { // Used as a field. for i in self.0.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if !(3..8).contains(&i) { return Some(i); } @@ -305,7 +305,7 @@ fn issue1924() { } // This one is fine, a different field is borrowed for i in self.0.0.0.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if i == 1 { return self.0.1.take(); } else { @@ -335,7 +335,7 @@ fn issue1924() { // Needs &mut, field of the iterator is accessed after the loop let mut it = S2(1..40, 0); for n in it.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if n == 0 { break; } @@ -348,7 +348,7 @@ fn issue7249() { let mut x = || { // Needs &mut, the closure can be called multiple times for x in it.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -363,7 +363,7 @@ fn issue7510() { let it = &mut it; // Needs to reborrow `it` as the binding isn't mutable for x in it.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -375,7 +375,7 @@ fn issue7510() { let it = S(&mut it); // Needs to reborrow `it.0` as the binding isn't mutable for x in it.0.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -411,7 +411,7 @@ fn custom_deref() { let mut s = S2(S1 { x: 0..10 }); for x in s.x.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{}", x); } } @@ -419,7 +419,7 @@ fn custom_deref() { fn issue_8113() { let mut x = [0..10]; for x in x[0].by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{}", x); } } @@ -428,7 +428,7 @@ fn fn_once_closure() { let mut it = 0..10; (|| { for x in it.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -439,7 +439,7 @@ fn fn_once_closure() { let mut it = 0..10; f(|| { for x in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -450,7 +450,7 @@ fn fn_once_closure() { let mut it = 0..10; f2(|| { for x in it.by_ref() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -461,7 +461,7 @@ fn fn_once_closure() { f3(|| { let mut it = 0..10; for x in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -474,7 +474,7 @@ fn fn_once_closure() { let mut it = 0..10; f4(|| { for x in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -485,7 +485,7 @@ fn fn_once_closure() { fn issue13123() { let mut it = 0..20; 'label: for n in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if n % 25 == 0 { break 'label; } @@ -495,7 +495,7 @@ fn issue13123() { fn main() { let mut it = 0..20; for _ in it { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("test"); } } diff --git a/tests/ui/while_let_on_iterator.rs b/tests/ui/while_let_on_iterator.rs index d34b78efc706..f957f2e5a523 100644 --- a/tests/ui/while_let_on_iterator.rs +++ b/tests/ui/while_let_on_iterator.rs @@ -13,13 +13,13 @@ fn base() { let mut iter = 1..20; while let Option::Some(x) = iter.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{}", x); } let mut iter = 1..20; while let Some(x) = iter.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{}", x); } @@ -124,7 +124,7 @@ fn refutable2() { let v = vec![[1], [2], [3]]; let mut it = v.iter(); while let Some(x @ [_]) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{:?}", x); } } @@ -145,7 +145,7 @@ fn nested_loops() { loop { let mut y = a.iter(); while let Some(_) = y.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator // use a for loop here } } @@ -203,7 +203,7 @@ fn issue6491() { let mut it = 1..40; while let Some(n) = it.next() { while let Some(m) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -215,10 +215,10 @@ fn issue6491() { // This is fine, inner loop uses a new iterator. let mut it = 1..40; while let Some(n) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator let mut it = 1..40; while let Some(m) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -228,7 +228,7 @@ fn issue6491() { // Weird binding shouldn't change anything. let (mut it, _) = (1..40, 0); while let Some(m) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -238,7 +238,7 @@ fn issue6491() { // Used after the loop, needs &mut. let mut it = 1..40; while let Some(m) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if m % 10 == 0 { break; } @@ -256,7 +256,7 @@ fn issue6231() { let mut opt = Some(0); while let Some(n) = opt.take().or_else(|| it.next()) { while let Some(m) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if n % 10 == 0 { break; } @@ -272,7 +272,7 @@ fn issue1924() { fn f(&mut self) -> Option { // Used as a field. while let Some(i) = self.0.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if !(3..8).contains(&i) { return Some(i); } @@ -305,7 +305,7 @@ fn issue1924() { } // This one is fine, a different field is borrowed while let Some(i) = self.0.0.0.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if i == 1 { return self.0.1.take(); } else { @@ -335,7 +335,7 @@ fn issue1924() { // Needs &mut, field of the iterator is accessed after the loop let mut it = S2(1..40, 0); while let Some(n) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if n == 0 { break; } @@ -348,7 +348,7 @@ fn issue7249() { let mut x = || { // Needs &mut, the closure can be called multiple times while let Some(x) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -363,7 +363,7 @@ fn issue7510() { let it = &mut it; // Needs to reborrow `it` as the binding isn't mutable while let Some(x) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -375,7 +375,7 @@ fn issue7510() { let it = S(&mut it); // Needs to reborrow `it.0` as the binding isn't mutable while let Some(x) = it.0.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -411,7 +411,7 @@ fn custom_deref() { let mut s = S2(S1 { x: 0..10 }); while let Some(x) = s.x.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{}", x); } } @@ -419,7 +419,7 @@ fn custom_deref() { fn issue_8113() { let mut x = [0..10]; while let Some(x) = x[0].next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("{}", x); } } @@ -428,7 +428,7 @@ fn fn_once_closure() { let mut it = 0..10; (|| { while let Some(x) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -439,7 +439,7 @@ fn fn_once_closure() { let mut it = 0..10; f(|| { while let Some(x) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -450,7 +450,7 @@ fn fn_once_closure() { let mut it = 0..10; f2(|| { while let Some(x) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -461,7 +461,7 @@ fn fn_once_closure() { f3(|| { let mut it = 0..10; while let Some(x) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -474,7 +474,7 @@ fn fn_once_closure() { let mut it = 0..10; f4(|| { while let Some(x) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if x % 2 == 0 { break; } @@ -485,7 +485,7 @@ fn fn_once_closure() { fn issue13123() { let mut it = 0..20; 'label: while let Some(n) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator if n % 25 == 0 { break 'label; } @@ -495,7 +495,7 @@ fn issue13123() { fn main() { let mut it = 0..20; while let Some(..) = it.next() { - //~^ while_let_on_iterator + //~^ while_let_on_iterator println!("test"); } } diff --git a/tests/ui/wild_in_or_pats.rs b/tests/ui/wild_in_or_pats.rs index 8d194a38ddf8..ced13cc50c5d 100644 --- a/tests/ui/wild_in_or_pats.rs +++ b/tests/ui/wild_in_or_pats.rs @@ -6,7 +6,7 @@ fn main() { dbg!("matched a"); }, "bar" | _ => { - //~^ wildcard_in_or_patterns + //~^ wildcard_in_or_patterns dbg!("matched (bar or) wild"); }, @@ -16,7 +16,7 @@ fn main() { dbg!("matched a"); }, "bar" | "bar2" | _ => { - //~^ wildcard_in_or_patterns + //~^ wildcard_in_or_patterns dbg!("matched (bar or bar2 or) wild"); }, @@ -26,7 +26,7 @@ fn main() { dbg!("matched a"); }, _ | "bar" | _ => { - //~^ wildcard_in_or_patterns + //~^ wildcard_in_or_patterns dbg!("matched (bar or) wild"); }, @@ -36,7 +36,7 @@ fn main() { dbg!("matched a"); }, _ | "bar" => { - //~^ wildcard_in_or_patterns + //~^ wildcard_in_or_patterns dbg!("matched (bar or) wild"); }, @@ -71,7 +71,7 @@ fn main() { dbg!("Change the color"); }, ExhaustiveEnum::Quit | _ => { - //~^ wildcard_in_or_patterns + //~^ wildcard_in_or_patterns dbg!("Quit or other"); }, }; @@ -107,7 +107,7 @@ fn main() { dbg!("On the y axis at {y}"); }, ExhaustiveStruct { x: 1, y: 1 } | _ => { - //~^ wildcard_in_or_patterns + //~^ wildcard_in_or_patterns dbg!("On neither axis: ({x}, {y})"); }, } diff --git a/tests/ui/write_literal.fixed b/tests/ui/write_literal.fixed index b82d77aaa418..e84f768e33d0 100644 --- a/tests/ui/write_literal.fixed +++ b/tests/ui/write_literal.fixed @@ -31,7 +31,6 @@ fn main() { write!(v, "Hello world"); //~^ write_literal - writeln!(v, "Hello {} world", world); //~^ write_literal @@ -41,7 +40,6 @@ fn main() { writeln!(v, "a literal {:.4}", 5); //~^ write_literal - // positional args don't change the fact // that we're using a literal -- this should // throw a warning @@ -51,7 +49,6 @@ fn main() { writeln!(v, "world hello"); //~^ write_literal - // named args shouldn't change anything either writeln!(v, "hello world"); //~^ write_literal @@ -59,7 +56,6 @@ fn main() { writeln!(v, "world hello"); //~^ write_literal - // #10128 writeln!(v, "hello {0} world", 2); //~^ write_literal @@ -72,7 +68,6 @@ fn main() { writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4); //~^ write_literal - } fn issue_13959() { diff --git a/tests/ui/write_literal.rs b/tests/ui/write_literal.rs index e9f5990d7ec6..fc29fcbede7e 100644 --- a/tests/ui/write_literal.rs +++ b/tests/ui/write_literal.rs @@ -31,7 +31,6 @@ fn main() { write!(v, "Hello {}", "world"); //~^ write_literal - writeln!(v, "Hello {} {}", world, "world"); //~^ write_literal @@ -41,7 +40,6 @@ fn main() { writeln!(v, "{} {:.4}", "a literal", 5); //~^ write_literal - // positional args don't change the fact // that we're using a literal -- this should // throw a warning @@ -51,7 +49,6 @@ fn main() { writeln!(v, "{1} {0}", "hello", "world"); //~^ write_literal - // named args shouldn't change anything either writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); //~^ write_literal @@ -59,7 +56,6 @@ fn main() { writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); //~^ write_literal - // #10128 writeln!(v, "{0} {1} {2}", "hello", 2, "world"); //~^ write_literal @@ -72,7 +68,6 @@ fn main() { writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4); //~^ write_literal - } fn issue_13959() { diff --git a/tests/ui/write_literal.stderr b/tests/ui/write_literal.stderr index 834162473c58..d53c2a7de2e0 100644 --- a/tests/ui/write_literal.stderr +++ b/tests/ui/write_literal.stderr @@ -13,7 +13,7 @@ LL + write!(v, "Hello world"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:35:39 + --> tests/ui/write_literal.rs:34:39 | LL | writeln!(v, "Hello {} {}", world, "world"); | ^^^^^^^ @@ -25,7 +25,7 @@ LL + writeln!(v, "Hello {} world", world); | error: literal with an empty format string - --> tests/ui/write_literal.rs:38:29 + --> tests/ui/write_literal.rs:37:29 | LL | writeln!(v, "Hello {}", "world"); | ^^^^^^^ @@ -37,7 +37,7 @@ LL + writeln!(v, "Hello world"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:41:29 + --> tests/ui/write_literal.rs:40:29 | LL | writeln!(v, "{} {:.4}", "a literal", 5); | ^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + writeln!(v, "a literal {:.4}", 5); | error: literal with an empty format string - --> tests/ui/write_literal.rs:48:28 + --> tests/ui/write_literal.rs:46:28 | LL | writeln!(v, "{0} {1}", "hello", "world"); | ^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + writeln!(v, "hello world"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:51:28 + --> tests/ui/write_literal.rs:49:28 | LL | writeln!(v, "{1} {0}", "hello", "world"); | ^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + writeln!(v, "world hello"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:56:38 + --> tests/ui/write_literal.rs:53:38 | LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + writeln!(v, "hello world"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:59:38 + --> tests/ui/write_literal.rs:56:38 | LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL + writeln!(v, "world hello"); | error: literal with an empty format string - --> tests/ui/write_literal.rs:64:32 + --> tests/ui/write_literal.rs:60:32 | LL | writeln!(v, "{0} {1} {2}", "hello", 2, "world"); | ^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL + writeln!(v, "hello {0} world", 2); | error: literal with an empty format string - --> tests/ui/write_literal.rs:67:32 + --> tests/ui/write_literal.rs:63:32 | LL | writeln!(v, "{2} {1} {0}", "hello", 2, "world"); | ^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL + writeln!(v, "world {0} hello", 2); | error: literal with an empty format string - --> tests/ui/write_literal.rs:70:39 + --> tests/ui/write_literal.rs:66:39 | LL | writeln!(v, "{0} {1} {2}, {bar}", "hello", 2, 3, bar = 4); | ^^^^^^^ @@ -133,7 +133,7 @@ LL + writeln!(v, "hello {0} {1}, {bar}", 2, 3, bar = 4); | error: literal with an empty format string - --> tests/ui/write_literal.rs:73:41 + --> tests/ui/write_literal.rs:69:41 | LL | writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL + writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4); | error: literal with an empty format string - --> tests/ui/write_literal.rs:80:23 + --> tests/ui/write_literal.rs:75:23 | LL | writeln!(v, "{}", r#"""#); | ^^^^^^ @@ -157,7 +157,7 @@ LL + writeln!(v, "\""); | error: literal with an empty format string - --> tests/ui/write_literal.rs:85:9 + --> tests/ui/write_literal.rs:80:9 | LL | / r#" LL | | diff --git a/tests/ui/write_literal_2.rs b/tests/ui/write_literal_2.rs index 2edd50c43403..f896782aaf3b 100644 --- a/tests/ui/write_literal_2.rs +++ b/tests/ui/write_literal_2.rs @@ -10,7 +10,6 @@ fn main() { writeln!(v, "{}", "{hello}"); //~^ write_literal - writeln!(v, r"{}", r"{hello}"); //~^ write_literal @@ -32,14 +31,15 @@ fn main() { "hello \ //~^ write_literal world!", - ); writeln!( v, "some {}\ {} \\ {}", - "1", "2", "3", - //~^ write_literal + "1", + "2", + "3", + //~^^^ write_literal ); writeln!(v, "{}", "\\"); //~^ write_literal diff --git a/tests/ui/write_literal_2.stderr b/tests/ui/write_literal_2.stderr index f3f86586ef85..29803d6a8b18 100644 --- a/tests/ui/write_literal_2.stderr +++ b/tests/ui/write_literal_2.stderr @@ -13,7 +13,7 @@ LL + writeln!(v, "{{hello}}"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:14:24 + --> tests/ui/write_literal_2.rs:13:24 | LL | writeln!(v, r"{}", r"{hello}"); | ^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + writeln!(v, r"{{hello}}"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:17:23 + --> tests/ui/write_literal_2.rs:16:23 | LL | writeln!(v, "{}", '\''); | ^^^^ @@ -37,7 +37,7 @@ LL + writeln!(v, "'"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:20:23 + --> tests/ui/write_literal_2.rs:19:23 | LL | writeln!(v, "{}", '"'); | ^^^ @@ -49,13 +49,13 @@ LL + writeln!(v, "\""); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:23:24 + --> tests/ui/write_literal_2.rs:22:24 | LL | writeln!(v, r"{}", '"'); | ^^^ error: literal with an empty format string - --> tests/ui/write_literal_2.rs:26:24 + --> tests/ui/write_literal_2.rs:25:24 | LL | writeln!(v, r"{}", '\''); | ^^^^ @@ -67,7 +67,7 @@ LL + writeln!(v, r"'"); | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:32:9 + --> tests/ui/write_literal_2.rs:31:9 | LL | / "hello \ LL | | @@ -82,10 +82,12 @@ LL ~ world!", | error: literal with an empty format string - --> tests/ui/write_literal_2.rs:41:9 + --> tests/ui/write_literal_2.rs:39:9 | -LL | "1", "2", "3", - | ^^^^^^^^^^^^^ +LL | / "1", +LL | | "2", +LL | | "3", + | |___________^ | help: try | diff --git a/tests/ui/write_with_newline.fixed b/tests/ui/write_with_newline.fixed index bd2285d16bcf..40742bbbb427 100644 --- a/tests/ui/write_with_newline.fixed +++ b/tests/ui/write_with_newline.fixed @@ -12,7 +12,6 @@ fn main() { writeln!(v, "Hello"); //~^ write_with_newline - writeln!(v, "Hello {}", "world"); //~^ write_with_newline @@ -25,7 +24,6 @@ fn main() { writeln!(v); //~^ write_with_newline - // These should be fine write!(v, ""); write!(v, "Hello"); @@ -57,13 +55,11 @@ fn main() { // Literal newlines should also fail writeln!( - //~^ write_with_newline - + //~^ write_with_newline v ); writeln!( - //~^ write_with_newline - + //~^ write_with_newline v ); diff --git a/tests/ui/write_with_newline.rs b/tests/ui/write_with_newline.rs index b70349ae82e6..ad6af69e7813 100644 --- a/tests/ui/write_with_newline.rs +++ b/tests/ui/write_with_newline.rs @@ -12,7 +12,6 @@ fn main() { write!(v, "Hello\n"); //~^ write_with_newline - write!(v, "Hello {}\n", "world"); //~^ write_with_newline @@ -25,7 +24,6 @@ fn main() { write!(v, "\n"); //~^ write_with_newline - // These should be fine write!(v, ""); write!(v, "Hello"); @@ -57,15 +55,13 @@ fn main() { // Literal newlines should also fail write!( - //~^ write_with_newline - + //~^ write_with_newline v, " " ); write!( - //~^ write_with_newline - + //~^ write_with_newline v, r" " diff --git a/tests/ui/write_with_newline.stderr b/tests/ui/write_with_newline.stderr index 9ab17cfdf3af..7243b7943df0 100644 --- a/tests/ui/write_with_newline.stderr +++ b/tests/ui/write_with_newline.stderr @@ -13,7 +13,7 @@ LL + writeln!(v, "Hello"); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:16:5 + --> tests/ui/write_with_newline.rs:15:5 | LL | write!(v, "Hello {}\n", "world"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + writeln!(v, "Hello {}", "world"); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:19:5 + --> tests/ui/write_with_newline.rs:18:5 | LL | write!(v, "Hello {} {}\n", "world", "#2"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + writeln!(v, "Hello {} {}", "world", "#2"); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:22:5 + --> tests/ui/write_with_newline.rs:21:5 | LL | write!(v, "{}\n", 1265); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + writeln!(v, "{}", 1265); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:25:5 + --> tests/ui/write_with_newline.rs:24:5 | LL | write!(v, "\n"); | ^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + writeln!(v); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:49:5 + --> tests/ui/write_with_newline.rs:47:5 | LL | write!(v, "\\\n"); | ^^^^^^^^^^^^^^^^^ @@ -73,11 +73,10 @@ LL + writeln!(v, "\\"); | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:59:5 + --> tests/ui/write_with_newline.rs:57:5 | LL | / write!( LL | | -LL | | LL | | v, LL | | " LL | | " @@ -88,16 +87,14 @@ help: use `writeln!` instead | LL ~ writeln!( LL | -LL | LL ~ v | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:66:5 + --> tests/ui/write_with_newline.rs:63:5 | LL | / write!( LL | | -LL | | LL | | v, LL | | r" LL | | " @@ -108,12 +105,11 @@ help: use `writeln!` instead | LL ~ writeln!( LL | -LL | LL ~ v | error: using `write!()` with a format string that ends in a single newline - --> tests/ui/write_with_newline.rs:77:5 + --> tests/ui/write_with_newline.rs:73:5 | LL | write!(v, "\\r\n"); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/wrong_self_convention.rs b/tests/ui/wrong_self_convention.rs index 42d600b67f8e..840dfe7c6524 100644 --- a/tests/ui/wrong_self_convention.rs +++ b/tests/ui/wrong_self_convention.rs @@ -16,7 +16,6 @@ impl Foo { fn from_i32(self) {} //~^ wrong_self_convention - pub fn as_i64(self) {} pub fn into_i64(self) {} pub fn is_i64(self) {} @@ -54,7 +53,6 @@ impl Bar { fn from_i32(self) {} //~^ wrong_self_convention - pub fn as_i64(self) {} //~^ wrong_self_convention @@ -70,7 +68,6 @@ impl Bar { pub fn from_i64(self) {} //~^ wrong_self_convention - // test for false positives fn as_(self) {} fn into_(&self) {} @@ -216,7 +213,7 @@ mod issue6727 { } // trigger lint fn to_u64_v2(&self) -> u64 { - //~^ wrong_self_convention + //~^ wrong_self_convention 1 } @@ -227,7 +224,7 @@ mod issue6727 { impl FooNoCopy { // trigger lint fn to_u64(self) -> u64 { - //~^ wrong_self_convention + //~^ wrong_self_convention 2 } diff --git a/tests/ui/wrong_self_convention.stderr b/tests/ui/wrong_self_convention.stderr index fe6d231578b1..e720ddf3fae1 100644 --- a/tests/ui/wrong_self_convention.stderr +++ b/tests/ui/wrong_self_convention.stderr @@ -9,7 +9,7 @@ LL | fn from_i32(self) {} = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]` error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:24:21 + --> tests/ui/wrong_self_convention.rs:23:21 | LL | pub fn from_i64(self) {} | ^^^^ @@ -17,7 +17,7 @@ LL | pub fn from_i64(self) {} = help: consider choosing a less ambiguous name error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/wrong_self_convention.rs:38:15 + --> tests/ui/wrong_self_convention.rs:37:15 | LL | fn as_i32(self) {} | ^^^^ @@ -25,7 +25,7 @@ LL | fn as_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:42:17 + --> tests/ui/wrong_self_convention.rs:41:17 | LL | fn into_i32(&self) {} | ^^^^^ @@ -33,7 +33,7 @@ LL | fn into_i32(&self) {} = help: consider choosing a less ambiguous name error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self` - --> tests/ui/wrong_self_convention.rs:46:15 + --> tests/ui/wrong_self_convention.rs:45:15 | LL | fn is_i32(self) {} | ^^^^ @@ -41,7 +41,7 @@ LL | fn is_i32(self) {} = help: consider choosing a less ambiguous name error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference - --> tests/ui/wrong_self_convention.rs:50:15 + --> tests/ui/wrong_self_convention.rs:49:15 | LL | fn to_i32(self) {} | ^^^^ @@ -49,7 +49,7 @@ LL | fn to_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:54:17 + --> tests/ui/wrong_self_convention.rs:53:17 | LL | fn from_i32(self) {} | ^^^^ @@ -57,7 +57,7 @@ LL | fn from_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/wrong_self_convention.rs:58:19 + --> tests/ui/wrong_self_convention.rs:56:19 | LL | pub fn as_i64(self) {} | ^^^^ @@ -65,7 +65,7 @@ LL | pub fn as_i64(self) {} = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:61:21 + --> tests/ui/wrong_self_convention.rs:59:21 | LL | pub fn into_i64(&self) {} | ^^^^^ @@ -73,7 +73,7 @@ LL | pub fn into_i64(&self) {} = help: consider choosing a less ambiguous name error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self` - --> tests/ui/wrong_self_convention.rs:64:19 + --> tests/ui/wrong_self_convention.rs:62:19 | LL | pub fn is_i64(self) {} | ^^^^ @@ -81,7 +81,7 @@ LL | pub fn is_i64(self) {} = help: consider choosing a less ambiguous name error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference - --> tests/ui/wrong_self_convention.rs:67:19 + --> tests/ui/wrong_self_convention.rs:65:19 | LL | pub fn to_i64(self) {} | ^^^^ @@ -89,7 +89,7 @@ LL | pub fn to_i64(self) {} = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:70:21 + --> tests/ui/wrong_self_convention.rs:68:21 | LL | pub fn from_i64(self) {} | ^^^^ @@ -97,7 +97,7 @@ LL | pub fn from_i64(self) {} = help: consider choosing a less ambiguous name error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/wrong_self_convention.rs:117:19 + --> tests/ui/wrong_self_convention.rs:114:19 | LL | fn as_i32(self) {} | ^^^^ @@ -105,7 +105,7 @@ LL | fn as_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:122:25 + --> tests/ui/wrong_self_convention.rs:119:25 | LL | fn into_i32_ref(&self) {} | ^^^^^ @@ -113,7 +113,7 @@ LL | fn into_i32_ref(&self) {} = help: consider choosing a less ambiguous name error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self` - --> tests/ui/wrong_self_convention.rs:126:19 + --> tests/ui/wrong_self_convention.rs:123:19 | LL | fn is_i32(self) {} | ^^^^ @@ -121,7 +121,7 @@ LL | fn is_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:132:21 + --> tests/ui/wrong_self_convention.rs:129:21 | LL | fn from_i32(self) {} | ^^^^ @@ -129,7 +129,7 @@ LL | fn from_i32(self) {} = help: consider choosing a less ambiguous name error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/wrong_self_convention.rs:149:19 + --> tests/ui/wrong_self_convention.rs:146:19 | LL | fn as_i32(self); | ^^^^ @@ -137,7 +137,7 @@ LL | fn as_i32(self); = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:154:25 + --> tests/ui/wrong_self_convention.rs:151:25 | LL | fn into_i32_ref(&self); | ^^^^^ @@ -145,7 +145,7 @@ LL | fn into_i32_ref(&self); = help: consider choosing a less ambiguous name error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self` - --> tests/ui/wrong_self_convention.rs:158:19 + --> tests/ui/wrong_self_convention.rs:155:19 | LL | fn is_i32(self); | ^^^^ @@ -153,7 +153,7 @@ LL | fn is_i32(self); = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:164:21 + --> tests/ui/wrong_self_convention.rs:161:21 | LL | fn from_i32(self); | ^^^^ @@ -161,7 +161,7 @@ LL | fn from_i32(self); = help: consider choosing a less ambiguous name error: methods called `into_*` usually take `self` by value - --> tests/ui/wrong_self_convention.rs:184:25 + --> tests/ui/wrong_self_convention.rs:181:25 | LL | fn into_i32_ref(&self); | ^^^^^ @@ -169,7 +169,7 @@ LL | fn into_i32_ref(&self); = help: consider choosing a less ambiguous name error: methods called `from_*` usually take no `self` - --> tests/ui/wrong_self_convention.rs:192:21 + --> tests/ui/wrong_self_convention.rs:189:21 | LL | fn from_i32(self); | ^^^^ @@ -177,7 +177,7 @@ LL | fn from_i32(self); = help: consider choosing a less ambiguous name error: methods with the following characteristics: (`to_*` and `self` type is `Copy`) usually take `self` by value - --> tests/ui/wrong_self_convention.rs:218:22 + --> tests/ui/wrong_self_convention.rs:215:22 | LL | fn to_u64_v2(&self) -> u64 { | ^^^^^ @@ -185,7 +185,7 @@ LL | fn to_u64_v2(&self) -> u64 { = help: consider choosing a less ambiguous name error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference - --> tests/ui/wrong_self_convention.rs:229:19 + --> tests/ui/wrong_self_convention.rs:226:19 | LL | fn to_u64(self) -> u64 { | ^^^^ diff --git a/tests/ui/wrong_self_convention2.rs b/tests/ui/wrong_self_convention2.rs index 0740af48d741..0a3e4982a49a 100644 --- a/tests/ui/wrong_self_convention2.rs +++ b/tests/ui/wrong_self_convention2.rs @@ -52,7 +52,7 @@ mod issue7179 { // lint pub fn from_be_self(self) -> Self { - //~^ wrong_self_convention + //~^ wrong_self_convention S(i32::from_be(self.0)) } @@ -64,7 +64,6 @@ mod issue7179 { // lint fn from_be_self(self) -> Self; //~^ wrong_self_convention - } trait Foo: Sized { diff --git a/tests/ui/wrong_self_conventions_mut.rs b/tests/ui/wrong_self_conventions_mut.rs index 73df332d77ce..eb6f08fff424 100644 --- a/tests/ui/wrong_self_conventions_mut.rs +++ b/tests/ui/wrong_self_conventions_mut.rs @@ -12,7 +12,7 @@ mod issue6758 { impl Test { // If a method starts with `to_` and not ends with `_mut` it should expect `&self` pub fn to_many(&mut self) -> Option<&mut [T]> { - //~^ wrong_self_convention + //~^ wrong_self_convention match self { Self::Many(data) => Some(data), @@ -22,7 +22,7 @@ mod issue6758 { // If a method starts with `to_` and ends with `_mut` it should expect `&mut self` pub fn to_many_mut(&self) -> Option<&[T]> { - //~^ wrong_self_convention + //~^ wrong_self_convention match self { Self::Many(data) => Some(data), diff --git a/tests/ui/zero_offset.rs b/tests/ui/zero_offset.rs index dd2063ee5d9e..bedb09536c53 100644 --- a/tests/ui/zero_offset.rs +++ b/tests/ui/zero_offset.rs @@ -5,7 +5,6 @@ fn main() { m.offset(0); //~^ zst_offset - m.wrapping_add(0); //~^ zst_offset @@ -15,7 +14,6 @@ fn main() { m.wrapping_sub(0); //~^ zst_offset - let c = &() as *const (); c.offset(0); //~^ zst_offset @@ -29,7 +27,6 @@ fn main() { c.wrapping_sub(0); //~^ zst_offset - let sized = &1 as *const i32; sized.offset(0); } diff --git a/tests/ui/zero_offset.stderr b/tests/ui/zero_offset.stderr index 4dfde7d4e1b0..b69c7b92d56a 100644 --- a/tests/ui/zero_offset.stderr +++ b/tests/ui/zero_offset.stderr @@ -7,43 +7,43 @@ LL | m.offset(0); = note: `#[deny(clippy::zst_offset)]` on by default error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:9:9 + --> tests/ui/zero_offset.rs:8:9 | LL | m.wrapping_add(0); | ^^^^^^^^^^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:12:9 + --> tests/ui/zero_offset.rs:11:9 | LL | m.sub(0); | ^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:15:9 + --> tests/ui/zero_offset.rs:14:9 | LL | m.wrapping_sub(0); | ^^^^^^^^^^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:20:9 + --> tests/ui/zero_offset.rs:18:9 | LL | c.offset(0); | ^^^^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:23:9 + --> tests/ui/zero_offset.rs:21:9 | LL | c.wrapping_add(0); | ^^^^^^^^^^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:26:9 + --> tests/ui/zero_offset.rs:24:9 | LL | c.sub(0); | ^^^^^^^^ error: offset calculation on zero-sized value - --> tests/ui/zero_offset.rs:29:9 + --> tests/ui/zero_offset.rs:27:9 | LL | c.wrapping_sub(0); | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/zero_sized_btreemap_values.rs b/tests/ui/zero_sized_btreemap_values.rs index ddcfce672bf9..cdeea15f28bc 100644 --- a/tests/ui/zero_sized_btreemap_values.rs +++ b/tests/ui/zero_sized_btreemap_values.rs @@ -5,32 +5,26 @@ const CONST_OK: Option> = None; const CONST_NOT_OK: Option> = None; //~^ zero_sized_map_values - static STATIC_OK: Option> = None; static STATIC_NOT_OK: Option> = None; //~^ zero_sized_map_values - type OkMap = BTreeMap; type NotOkMap = BTreeMap; //~^ zero_sized_map_values - enum TestEnum { Ok(BTreeMap), NotOk(BTreeMap), //~^ zero_sized_map_values - } struct Test { ok: BTreeMap, not_ok: BTreeMap, //~^ zero_sized_map_values - also_not_ok: Vec>, //~^ zero_sized_map_values - } trait TestTrait { @@ -40,7 +34,6 @@ trait TestTrait { fn weird_map(&self, map: BTreeMap); //~^ zero_sized_map_values - } impl Test { @@ -49,7 +42,7 @@ impl Test { } fn not_ok(&self) -> BTreeMap { - //~^ zero_sized_map_values + //~^ zero_sized_map_values todo!() } @@ -68,9 +61,8 @@ impl TestTrait for Test { } fn test(map: BTreeMap, key: &str) -> BTreeMap { -//~^ zero_sized_map_values -//~| zero_sized_map_values - + //~^ zero_sized_map_values + //~| zero_sized_map_values todo!(); } @@ -84,10 +76,8 @@ fn main() { //~^ zero_sized_map_values //~| zero_sized_map_values - let _: BTreeMap = BTreeMap::new(); let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect(); //~^ zero_sized_map_values - } diff --git a/tests/ui/zero_sized_btreemap_values.stderr b/tests/ui/zero_sized_btreemap_values.stderr index f9184dc9ae1f..40acb0b211f7 100644 --- a/tests/ui/zero_sized_btreemap_values.stderr +++ b/tests/ui/zero_sized_btreemap_values.stderr @@ -9,7 +9,7 @@ LL | const CONST_NOT_OK: Option> = None; = help: to override `-D warnings` add `#[allow(clippy::zero_sized_map_values)]` error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:10:30 + --> tests/ui/zero_sized_btreemap_values.rs:9:30 | LL | static STATIC_NOT_OK: Option> = None; | ^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | static STATIC_NOT_OK: Option> = None; = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:15:17 + --> tests/ui/zero_sized_btreemap_values.rs:13:17 | LL | type NotOkMap = BTreeMap; | ^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | type NotOkMap = BTreeMap; = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:21:11 + --> tests/ui/zero_sized_btreemap_values.rs:18:11 | LL | NotOk(BTreeMap), | ^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | NotOk(BTreeMap), = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:28:13 + --> tests/ui/zero_sized_btreemap_values.rs:24:13 | LL | not_ok: BTreeMap, | ^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | not_ok: BTreeMap, = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:31:22 + --> tests/ui/zero_sized_btreemap_values.rs:26:22 | LL | also_not_ok: Vec>, | ^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | also_not_ok: Vec>, = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:41:30 + --> tests/ui/zero_sized_btreemap_values.rs:35:30 | LL | fn weird_map(&self, map: BTreeMap); | ^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn weird_map(&self, map: BTreeMap); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:51:25 + --> tests/ui/zero_sized_btreemap_values.rs:44:25 | LL | fn not_ok(&self) -> BTreeMap { | ^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | fn not_ok(&self) -> BTreeMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:70:14 + --> tests/ui/zero_sized_btreemap_values.rs:63:14 | LL | fn test(map: BTreeMap, key: &str) -> BTreeMap { | ^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | fn test(map: BTreeMap, key: &str) -> BTreeMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:70:50 + --> tests/ui/zero_sized_btreemap_values.rs:63:50 | LL | fn test(map: BTreeMap, key: &str) -> BTreeMap { | ^^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | fn test(map: BTreeMap, key: &str) -> BTreeMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:83:35 + --> tests/ui/zero_sized_btreemap_values.rs:75:35 | LL | let _: BTreeMap = BTreeMap::new(); | ^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _: BTreeMap = BTreeMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:83:12 + --> tests/ui/zero_sized_btreemap_values.rs:75:12 | LL | let _: BTreeMap = BTreeMap::new(); | ^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _: BTreeMap = BTreeMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_btreemap_values.rs:90:12 + --> tests/ui/zero_sized_btreemap_values.rs:81:12 | LL | let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect(); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/zero_sized_hashmap_values.rs b/tests/ui/zero_sized_hashmap_values.rs index 132716da3b27..4beeef421f30 100644 --- a/tests/ui/zero_sized_hashmap_values.rs +++ b/tests/ui/zero_sized_hashmap_values.rs @@ -5,32 +5,26 @@ const CONST_OK: Option> = None; const CONST_NOT_OK: Option> = None; //~^ zero_sized_map_values - static STATIC_OK: Option> = None; static STATIC_NOT_OK: Option> = None; //~^ zero_sized_map_values - type OkMap = HashMap; type NotOkMap = HashMap; //~^ zero_sized_map_values - enum TestEnum { Ok(HashMap), NotOk(HashMap), //~^ zero_sized_map_values - } struct Test { ok: HashMap, not_ok: HashMap, //~^ zero_sized_map_values - also_not_ok: Vec>, //~^ zero_sized_map_values - } trait TestTrait { @@ -40,7 +34,6 @@ trait TestTrait { fn weird_map(&self, map: HashMap); //~^ zero_sized_map_values - } impl Test { @@ -49,7 +42,7 @@ impl Test { } fn not_ok(&self) -> HashMap { - //~^ zero_sized_map_values + //~^ zero_sized_map_values todo!() } @@ -68,9 +61,8 @@ impl TestTrait for Test { } fn test(map: HashMap, key: &str) -> HashMap { -//~^ zero_sized_map_values -//~| zero_sized_map_values - + //~^ zero_sized_map_values + //~| zero_sized_map_values todo!(); } @@ -84,10 +76,8 @@ fn main() { //~^ zero_sized_map_values //~| zero_sized_map_values - let _: HashMap = HashMap::new(); let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect(); //~^ zero_sized_map_values - } diff --git a/tests/ui/zero_sized_hashmap_values.stderr b/tests/ui/zero_sized_hashmap_values.stderr index 059902047b55..ed8536acfe8f 100644 --- a/tests/ui/zero_sized_hashmap_values.stderr +++ b/tests/ui/zero_sized_hashmap_values.stderr @@ -9,7 +9,7 @@ LL | const CONST_NOT_OK: Option> = None; = help: to override `-D warnings` add `#[allow(clippy::zero_sized_map_values)]` error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:10:30 + --> tests/ui/zero_sized_hashmap_values.rs:9:30 | LL | static STATIC_NOT_OK: Option> = None; | ^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | static STATIC_NOT_OK: Option> = None; = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:15:17 + --> tests/ui/zero_sized_hashmap_values.rs:13:17 | LL | type NotOkMap = HashMap; | ^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | type NotOkMap = HashMap; = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:21:11 + --> tests/ui/zero_sized_hashmap_values.rs:18:11 | LL | NotOk(HashMap), | ^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | NotOk(HashMap), = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:28:13 + --> tests/ui/zero_sized_hashmap_values.rs:24:13 | LL | not_ok: HashMap, | ^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | not_ok: HashMap, = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:31:22 + --> tests/ui/zero_sized_hashmap_values.rs:26:22 | LL | also_not_ok: Vec>, | ^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | also_not_ok: Vec>, = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:41:30 + --> tests/ui/zero_sized_hashmap_values.rs:35:30 | LL | fn weird_map(&self, map: HashMap); | ^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn weird_map(&self, map: HashMap); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:51:25 + --> tests/ui/zero_sized_hashmap_values.rs:44:25 | LL | fn not_ok(&self) -> HashMap { | ^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | fn not_ok(&self) -> HashMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:70:14 + --> tests/ui/zero_sized_hashmap_values.rs:63:14 | LL | fn test(map: HashMap, key: &str) -> HashMap { | ^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | fn test(map: HashMap, key: &str) -> HashMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:70:49 + --> tests/ui/zero_sized_hashmap_values.rs:63:49 | LL | fn test(map: HashMap, key: &str) -> HashMap { | ^^^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | fn test(map: HashMap, key: &str) -> HashMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:83:34 + --> tests/ui/zero_sized_hashmap_values.rs:75:34 | LL | let _: HashMap = HashMap::new(); | ^^^^^^^ @@ -89,7 +89,7 @@ LL | let _: HashMap = HashMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:83:12 + --> tests/ui/zero_sized_hashmap_values.rs:75:12 | LL | let _: HashMap = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _: HashMap = HashMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:90:12 + --> tests/ui/zero_sized_hashmap_values.rs:81:12 | LL | let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect(); | ^^^^^^^^^^^^^ From a2c890fa0fd14273d98c160229184f02734a5800 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 13 Feb 2025 00:10:26 +0100 Subject: [PATCH 121/991] Make fmt (weirdly) happy --- tests/ui/borrow_deref_ref.fixed | 3 +- tests/ui/borrow_deref_ref.rs | 3 +- tests/ui/cast.rs | 9 +- tests/ui/cast.stderr | 12 +- tests/ui/clone_on_copy.fixed | 3 +- tests/ui/clone_on_copy.rs | 3 +- tests/ui/cloned_instead_of_copied.fixed | 6 +- tests/ui/cloned_instead_of_copied.rs | 6 +- tests/ui/cloned_instead_of_copied.stderr | 4 +- tests/ui/collapsible_else_if.stderr | 154 ++++++++++ tests/ui/collapsible_if.stderr | 139 +++++++++ tests/ui/crashes/ice-5835.1.fixed | 11 + tests/ui/crashes/ice-5835.2.fixed | 13 + tests/ui/deref_by_slicing.fixed | 12 +- tests/ui/deref_by_slicing.rs | 12 +- tests/ui/deref_by_slicing.stderr | 10 +- tests/ui/eta.fixed | 9 +- tests/ui/eta.rs | 9 +- tests/ui/eta.stderr | 66 ++-- tests/ui/explicit_auto_deref.fixed | 9 +- tests/ui/explicit_auto_deref.rs | 9 +- tests/ui/explicit_auto_deref.stderr | 82 ++--- .../ui/literal_string_with_formatting_arg.rs | 3 +- tests/ui/manual_instant_elapsed.fixed | 3 +- tests/ui/manual_instant_elapsed.rs | 3 +- tests/ui/manual_slice_size_calculation.fixed | 24 +- tests/ui/manual_slice_size_calculation.rs | 24 +- tests/ui/manual_slice_size_calculation.stderr | 16 +- tests/ui/mistyped_literal_suffix.fixed | 21 +- tests/ui/mistyped_literal_suffix.rs | 21 +- tests/ui/mistyped_literal_suffix.stderr | 26 +- .../global_allow.stderr | 20 ++ tests/ui/needless_bool/simple.stderr | 45 +++ tests/ui/needless_bool_assign.stderr | 55 ++++ tests/ui/needless_borrow.fixed | 6 +- tests/ui/needless_borrow.rs | 6 +- tests/ui/needless_borrow.stderr | 54 ++-- .../needless_borrows_for_generic_args.fixed | 6 +- tests/ui/needless_borrows_for_generic_args.rs | 6 +- .../needless_borrows_for_generic_args.stderr | 2 +- tests/ui/needless_else.stderr | 13 + tests/ui/option_env_unwrap.rs | 3 +- tests/ui/option_env_unwrap.stderr | 8 +- tests/ui/or_fun_call.fixed | 9 +- tests/ui/or_fun_call.rs | 9 +- tests/ui/or_fun_call.stderr | 10 +- tests/ui/or_then_unwrap.fixed | 9 +- tests/ui/or_then_unwrap.rs | 9 +- tests/ui/or_then_unwrap.stderr | 4 +- .../redundant_pattern_matching_option.fixed | 3 +- tests/ui/redundant_pattern_matching_option.rs | 3 +- .../redundant_pattern_matching_option.stderr | 58 ++-- tests/ui/redundant_pub_crate.fixed | 39 ++- tests/ui/redundant_pub_crate.rs | 39 ++- tests/ui/redundant_pub_crate.stderr | 30 +- tests/ui/redundant_slicing.fixed | 6 +- tests/ui/redundant_slicing.rs | 6 +- tests/ui/redundant_slicing.stderr | 4 +- tests/ui/search_is_some_fixable_none.fixed | 3 +- tests/ui/search_is_some_fixable_none.rs | 3 +- tests/ui/search_is_some_fixable_none.stderr | 106 +++---- tests/ui/search_is_some_fixable_some.fixed | 3 +- tests/ui/search_is_some_fixable_some.rs | 3 +- tests/ui/search_is_some_fixable_some.stderr | 90 +++--- tests/ui/single_char_pattern.fixed | 6 +- tests/ui/single_char_pattern.rs | 6 +- tests/ui/single_char_pattern.stderr | 16 +- tests/ui/single_match.stderr | 282 ++++++++++++++++++ tests/ui/single_match_else.stderr | 211 +++++++++++++ tests/ui/suspicious_xor_used_as_pow.rs | 3 +- tests/ui/suspicious_xor_used_as_pow.stderr | 12 +- tests/ui/trim_split_whitespace.fixed | 24 +- tests/ui/trim_split_whitespace.rs | 24 +- tests/ui/trim_split_whitespace.stderr | 14 +- tests/ui/uninlined_format_args.fixed | 12 +- tests/ui/uninlined_format_args.rs | 12 +- tests/ui/uninlined_format_args.stderr | 146 ++++----- tests/ui/unnecessary_cast.fixed | 3 +- tests/ui/unnecessary_cast.rs | 3 +- tests/ui/unnecessary_cast.stderr | 4 +- tests/ui/unnecessary_literal_unwrap.fixed | 3 +- tests/ui/unnecessary_literal_unwrap.rs | 3 +- tests/ui/unnecessary_literal_unwrap.stderr | 10 +- tests/ui/use_self_trait.fixed | 3 +- tests/ui/use_self_trait.rs | 3 +- 85 files changed, 1647 insertions(+), 548 deletions(-) create mode 100644 tests/ui/collapsible_else_if.stderr create mode 100644 tests/ui/collapsible_if.stderr create mode 100644 tests/ui/crashes/ice-5835.1.fixed create mode 100644 tests/ui/crashes/ice-5835.2.fixed create mode 100644 tests/ui/mixed_attributes_style/global_allow.stderr create mode 100644 tests/ui/needless_bool/simple.stderr create mode 100644 tests/ui/needless_bool_assign.stderr create mode 100644 tests/ui/needless_else.stderr create mode 100644 tests/ui/single_match.stderr create mode 100644 tests/ui/single_match_else.stderr diff --git a/tests/ui/borrow_deref_ref.fixed b/tests/ui/borrow_deref_ref.fixed index 93cd3e3b5e59..17c224f10bfe 100644 --- a/tests/ui/borrow_deref_ref.fixed +++ b/tests/ui/borrow_deref_ref.fixed @@ -69,7 +69,8 @@ mod false_negative { let x = &12; let addr_x = &x as *const _ as usize; let addr_y = &x as *const _ as usize; // assert ok - //~^ borrow_deref_ref + // + //~^^ borrow_deref_ref // let addr_y = &x as *const _ as usize; // assert fail assert_ne!(addr_x, addr_y); } diff --git a/tests/ui/borrow_deref_ref.rs b/tests/ui/borrow_deref_ref.rs index 1e41d24998f9..130ed2903dc6 100644 --- a/tests/ui/borrow_deref_ref.rs +++ b/tests/ui/borrow_deref_ref.rs @@ -69,7 +69,8 @@ mod false_negative { let x = &12; let addr_x = &x as *const _ as usize; let addr_y = &&*x as *const _ as usize; // assert ok - //~^ borrow_deref_ref + // + //~^^ borrow_deref_ref // let addr_y = &x as *const _ as usize; // assert fail assert_ne!(addr_x, addr_y); } diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index 56e4326cdc1d..88c2549f4dc5 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -532,11 +532,14 @@ fn issue11738() { macro_rules! m { () => { let _ = i32::MIN as u32; // cast_sign_loss - //~^ cast_sign_loss + // + //~^^ cast_sign_loss let _ = u32::MAX as u8; // cast_possible_truncation - //~^ cast_possible_truncation + // + //~^^ cast_possible_truncation let _ = std::f64::consts::PI as f32; // cast_possible_truncation - //~^ cast_possible_truncation + // + //~^^ cast_possible_truncation let _ = 0i8 as i32; // cast_lossless }; } diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 484be7905d42..1c5ff52ae722 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -662,7 +662,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:536:21 + --> tests/ui/cast.rs:537:21 | LL | let _ = u32::MAX as u8; // cast_possible_truncation | ^^^^^^^^^^^^^^ @@ -678,7 +678,7 @@ LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:538:21 + --> tests/ui/cast.rs:540:21 | LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -690,7 +690,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:548:5 + --> tests/ui/cast.rs:551:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -702,13 +702,13 @@ LL | usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:548:5 + --> tests/ui/cast.rs:551:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:565:5 + --> tests/ui/cast.rs:568:5 | LL | (256 & 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ LL | u8::try_from(256 & 999999u64); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:568:5 + --> tests/ui/cast.rs:571:5 | LL | (255 % 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/clone_on_copy.fixed b/tests/ui/clone_on_copy.fixed index f965aa5c182d..2dd8af152515 100644 --- a/tests/ui/clone_on_copy.fixed +++ b/tests/ui/clone_on_copy.fixed @@ -81,6 +81,7 @@ fn clone_on_copy() -> Option<(i32)> { // Issue #9277 let opt: &Option = &None; let value = (*opt)?; // operator precedence needed (*opt)? - //~^ clone_on_copy + // + //~^^ clone_on_copy None } diff --git a/tests/ui/clone_on_copy.rs b/tests/ui/clone_on_copy.rs index f6a542296de1..a371afb04a78 100644 --- a/tests/ui/clone_on_copy.rs +++ b/tests/ui/clone_on_copy.rs @@ -81,6 +81,7 @@ fn clone_on_copy() -> Option<(i32)> { // Issue #9277 let opt: &Option = &None; let value = opt.clone()?; // operator precedence needed (*opt)? - //~^ clone_on_copy + // + //~^^ clone_on_copy None } diff --git a/tests/ui/cloned_instead_of_copied.fixed b/tests/ui/cloned_instead_of_copied.fixed index 94784b4747e8..0a1a59ddf9b8 100644 --- a/tests/ui/cloned_instead_of_copied.fixed +++ b/tests/ui/cloned_instead_of_copied.fixed @@ -30,13 +30,15 @@ fn msrv_1_34() { fn msrv_1_35() { let _ = [1].iter().cloned(); let _ = Some(&1).copied(); // Option::copied needs 1.35 - //~^ cloned_instead_of_copied + // + //~^^ cloned_instead_of_copied } #[clippy::msrv = "1.36"] fn msrv_1_36() { let _ = [1].iter().copied(); // Iterator::copied needs 1.36 - //~^ cloned_instead_of_copied + // + //~^^ cloned_instead_of_copied let _ = Some(&1).copied(); //~^ cloned_instead_of_copied } diff --git a/tests/ui/cloned_instead_of_copied.rs b/tests/ui/cloned_instead_of_copied.rs index 54e01e369f9d..c452dd007a1e 100644 --- a/tests/ui/cloned_instead_of_copied.rs +++ b/tests/ui/cloned_instead_of_copied.rs @@ -30,13 +30,15 @@ fn msrv_1_34() { fn msrv_1_35() { let _ = [1].iter().cloned(); let _ = Some(&1).cloned(); // Option::copied needs 1.35 - //~^ cloned_instead_of_copied + // + //~^^ cloned_instead_of_copied } #[clippy::msrv = "1.36"] fn msrv_1_36() { let _ = [1].iter().cloned(); // Iterator::copied needs 1.36 - //~^ cloned_instead_of_copied + // + //~^^ cloned_instead_of_copied let _ = Some(&1).cloned(); //~^ cloned_instead_of_copied } diff --git a/tests/ui/cloned_instead_of_copied.stderr b/tests/ui/cloned_instead_of_copied.stderr index 70ac0a767daf..bd741e41321b 100644 --- a/tests/ui/cloned_instead_of_copied.stderr +++ b/tests/ui/cloned_instead_of_copied.stderr @@ -38,13 +38,13 @@ LL | let _ = Some(&1).cloned(); // Option::copied needs 1.35 | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> tests/ui/cloned_instead_of_copied.rs:38:24 + --> tests/ui/cloned_instead_of_copied.rs:39:24 | LL | let _ = [1].iter().cloned(); // Iterator::copied needs 1.36 | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> tests/ui/cloned_instead_of_copied.rs:40:22 + --> tests/ui/cloned_instead_of_copied.rs:42:22 | LL | let _ = Some(&1).cloned(); | ^^^^^^ help: try: `copied` diff --git a/tests/ui/collapsible_else_if.stderr b/tests/ui/collapsible_else_if.stderr new file mode 100644 index 000000000000..7d80894cadbb --- /dev/null +++ b/tests/ui/collapsible_else_if.stderr @@ -0,0 +1,154 @@ +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:11:12 + | +LL | } else { + | ____________^ +LL | | if y == "world" { +LL | | println!("world!") +LL | | } +LL | | } + | |_____^ + | + = note: `-D clippy::collapsible-else-if` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::collapsible_else_if)]` +help: collapse nested if block + | +LL ~ } else if y == "world" { +LL + println!("world!") +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:20:12 + | +LL | } else { + | ____________^ +LL | | if let Some(42) = Some(42) { +LL | | println!("world!") +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else if let Some(42) = Some(42) { +LL + println!("world!") +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:29:12 + | +LL | } else { + | ____________^ +LL | | if y == "world" { +LL | | println!("world") +... | +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else if y == "world" { +LL + println!("world") +LL + } +LL + else { +LL + println!("!") +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:41:12 + | +LL | } else { + | ____________^ +LL | | if let Some(42) = Some(42) { +LL | | println!("world") +... | +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else if let Some(42) = Some(42) { +LL + println!("world") +LL + } +LL + else { +LL + println!("!") +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:53:12 + | +LL | } else { + | ____________^ +LL | | if let Some(42) = Some(42) { +LL | | println!("world") +... | +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else if let Some(42) = Some(42) { +LL + println!("world") +LL + } +LL + else { +LL + println!("!") +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:65:12 + | +LL | } else { + | ____________^ +LL | | if x == "hello" { +LL | | println!("world") +... | +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else if x == "hello" { +LL + println!("world") +LL + } +LL + else { +LL + println!("!") +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:77:12 + | +LL | } else { + | ____________^ +LL | | if let Some(42) = Some(42) { +LL | | println!("world") +... | +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else if let Some(42) = Some(42) { +LL + println!("world") +LL + } +LL + else { +LL + println!("!") +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:100:10 + | +LL | }else{ + | __________^ +LL | | if false {} +LL | | } + | |_____^ help: collapse nested if block: `if false {}` + +error: aborting due to 8 previous errors + diff --git a/tests/ui/collapsible_if.stderr b/tests/ui/collapsible_if.stderr new file mode 100644 index 000000000000..3cc3fe5534f2 --- /dev/null +++ b/tests/ui/collapsible_if.stderr @@ -0,0 +1,139 @@ +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:15:5 + | +LL | / if x == "hello" { +LL | | if y == "world" { +LL | | println!("Hello world!"); +LL | | } +LL | | } + | |_____^ + | + = note: `-D clippy::collapsible-if` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::collapsible_if)]` +help: collapse nested if block + | +LL ~ if x == "hello" && y == "world" { +LL + println!("Hello world!"); +LL + } + | + +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:22:5 + | +LL | / if x == "hello" || x == "world" { +LL | | if y == "world" || y == "hello" { +LL | | println!("Hello world!"); +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ if (x == "hello" || x == "world") && (y == "world" || y == "hello") { +LL + println!("Hello world!"); +LL + } + | + +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:29:5 + | +LL | / if x == "hello" && x == "world" { +LL | | if y == "world" || y == "hello" { +LL | | println!("Hello world!"); +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ if x == "hello" && x == "world" && (y == "world" || y == "hello") { +LL + println!("Hello world!"); +LL + } + | + +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:36:5 + | +LL | / if x == "hello" || x == "world" { +LL | | if y == "world" && y == "hello" { +LL | | println!("Hello world!"); +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ if (x == "hello" || x == "world") && y == "world" && y == "hello" { +LL + println!("Hello world!"); +LL + } + | + +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:43:5 + | +LL | / if x == "hello" && x == "world" { +LL | | if y == "world" && y == "hello" { +LL | | println!("Hello world!"); +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ if x == "hello" && x == "world" && y == "world" && y == "hello" { +LL + println!("Hello world!"); +LL + } + | + +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:50:5 + | +LL | / if 42 == 1337 { +LL | | if 'a' != 'A' { +LL | | println!("world!") +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ if 42 == 1337 && 'a' != 'A' { +LL + println!("world!") +LL + } + | + +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:107:5 + | +LL | / if x == "hello" { +LL | | if y == "world" { // Collapsible +LL | | println!("Hello world!"); +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ if x == "hello" && y == "world" { // Collapsible +LL + println!("Hello world!"); +LL + } + | + +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:167:5 + | +LL | / if matches!(true, true) { +LL | | if matches!(true, true) {} +LL | | } + | |_____^ help: collapse nested if block: `if matches!(true, true) && matches!(true, true) {}` + +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:173:5 + | +LL | / if matches!(true, true) && truth() { +LL | | if matches!(true, true) {} +LL | | } + | |_____^ help: collapse nested if block: `if matches!(true, true) && truth() && matches!(true, true) {}` + +error: aborting due to 9 previous errors + diff --git a/tests/ui/crashes/ice-5835.1.fixed b/tests/ui/crashes/ice-5835.1.fixed new file mode 100644 index 000000000000..acd61a9bd6c3 --- /dev/null +++ b/tests/ui/crashes/ice-5835.1.fixed @@ -0,0 +1,11 @@ +#[rustfmt::skip] +pub struct Foo { + /// 位 + //~^ tabs_in_doc_comments + //~| empty_line_after_doc_comments + /// ^ Do not remove this tab character. + /// It was required to trigger the ICE. + pub bar: u8, +} + +fn main() {} diff --git a/tests/ui/crashes/ice-5835.2.fixed b/tests/ui/crashes/ice-5835.2.fixed new file mode 100644 index 000000000000..71d2ec0c0018 --- /dev/null +++ b/tests/ui/crashes/ice-5835.2.fixed @@ -0,0 +1,13 @@ +#[rustfmt::skip] +pub struct Foo { + // /// 位 + //~^ tabs_in_doc_comments + //~| empty_line_after_doc_comments + + + /// ^ Do not remove this tab character. + /// It was required to trigger the ICE. + pub bar: u8, +} + +fn main() {} diff --git a/tests/ui/deref_by_slicing.fixed b/tests/ui/deref_by_slicing.fixed index 78a8f292bc9a..ba03904040b4 100644 --- a/tests/ui/deref_by_slicing.fixed +++ b/tests/ui/deref_by_slicing.fixed @@ -16,7 +16,8 @@ fn main() { let mut_slice = &mut **ref_vec; //~^ deref_by_slicing let _ = &mut *mut_slice; // Err, re-borrows slice - //~^ deref_by_slicing + // + //~^^ deref_by_slicing let s = String::new(); let _ = &*s; @@ -24,16 +25,19 @@ fn main() { static S: &[u8] = &[0, 1, 2]; let _ = &mut &*S; // Err, re-borrows slice - //~^ deref_by_slicing + // + //~^^ deref_by_slicing let slice: &[u32] = &[0u32, 1u32]; let slice_ref = &slice; let _ = *slice_ref; // Err, derefs slice - //~^ deref_by_slicing + // + //~^^ deref_by_slicing let bytes: &[u8] = &[]; let _ = (&*bytes).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice - //~^ deref_by_slicing + // + //~^^ deref_by_slicing // issue 12751 let a = &mut [1, 2, 3][..]; diff --git a/tests/ui/deref_by_slicing.rs b/tests/ui/deref_by_slicing.rs index 205cad63ddac..fdaac9467f86 100644 --- a/tests/ui/deref_by_slicing.rs +++ b/tests/ui/deref_by_slicing.rs @@ -16,7 +16,8 @@ fn main() { let mut_slice = &mut ref_vec[..]; //~^ deref_by_slicing let _ = &mut mut_slice[..]; // Err, re-borrows slice - //~^ deref_by_slicing + // + //~^^ deref_by_slicing let s = String::new(); let _ = &s[..]; @@ -24,16 +25,19 @@ fn main() { static S: &[u8] = &[0, 1, 2]; let _ = &mut &S[..]; // Err, re-borrows slice - //~^ deref_by_slicing + // + //~^^ deref_by_slicing let slice: &[u32] = &[0u32, 1u32]; let slice_ref = &slice; let _ = &slice_ref[..]; // Err, derefs slice - //~^ deref_by_slicing + // + //~^^ deref_by_slicing let bytes: &[u8] = &[]; let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice - //~^ deref_by_slicing + // + //~^^ deref_by_slicing // issue 12751 let a = &mut [1, 2, 3][..]; diff --git a/tests/ui/deref_by_slicing.stderr b/tests/ui/deref_by_slicing.stderr index a1fda3b3ec50..4a379a83dfa7 100644 --- a/tests/ui/deref_by_slicing.stderr +++ b/tests/ui/deref_by_slicing.stderr @@ -32,31 +32,31 @@ LL | let _ = &mut mut_slice[..]; // Err, re-borrows slice | ^^^^^^^^^^^^^^^^^^ help: reborrow the original value instead: `&mut *mut_slice` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:22:13 + --> tests/ui/deref_by_slicing.rs:23:13 | LL | let _ = &s[..]; | ^^^^^^ help: dereference the original value instead: `&*s` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:26:18 + --> tests/ui/deref_by_slicing.rs:27:18 | LL | let _ = &mut &S[..]; // Err, re-borrows slice | ^^^^^^ help: reborrow the original value instead: `&*S` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:31:13 + --> tests/ui/deref_by_slicing.rs:33:13 | LL | let _ = &slice_ref[..]; // Err, derefs slice | ^^^^^^^^^^^^^^ help: dereference the original value instead: `*slice_ref` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:35:13 + --> tests/ui/deref_by_slicing.rs:38:13 | LL | let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice | ^^^^^^^^^^^^ help: reborrow the original value instead: `(&*bytes)` error: slicing when dereferencing would work - --> tests/ui/deref_by_slicing.rs:40:13 + --> tests/ui/deref_by_slicing.rs:44:13 | LL | let _ = &a[..]; | ^^^^^^ help: reborrow the original value instead: `&*a` diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed index 2be5c7d2b4b0..0ba631fda051 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -34,11 +34,14 @@ fn main() { true.then(|| mac!()); // don't lint function in macro expansion Some(1).map(closure_mac!()); // don't lint closure in macro expansion let _: Option> = true.then(std::vec::Vec::new); // special case vec! - //~^ redundant_closure + // + //~^^ redundant_closure let d = Some(1u8).map(|a| foo(foo2(a))); //is adjusted? - //~^ redundant_closure + // + //~^^ redundant_closure all(&[1, 2, 3], &&2, below); //is adjusted - //~^ redundant_closure + // + //~^^ redundant_closure unsafe { Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn } diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index 7c9a92306b95..4d8b29d450c5 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -34,11 +34,14 @@ fn main() { true.then(|| mac!()); // don't lint function in macro expansion Some(1).map(closure_mac!()); // don't lint closure in macro expansion let _: Option> = true.then(|| vec![]); // special case vec! - //~^ redundant_closure + // + //~^^ redundant_closure let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? - //~^ redundant_closure + // + //~^^ redundant_closure all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted - //~^ redundant_closure + // + //~^^ redundant_closure unsafe { Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn } diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index 434a034a4f8e..8bc08add2fab 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -14,25 +14,25 @@ LL | let _: Option> = true.then(|| vec![]); // special case vec! | ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new` error: redundant closure - --> tests/ui/eta.rs:38:35 + --> tests/ui/eta.rs:39:35 | LL | let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? | ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2` error: redundant closure - --> tests/ui/eta.rs:40:26 + --> tests/ui/eta.rs:42:26 | LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted | ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below` error: redundant closure - --> tests/ui/eta.rs:48:27 + --> tests/ui/eta.rs:51:27 | LL | let e = Some(1u8).map(|a| generic(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic` error: redundant closure - --> tests/ui/eta.rs:101:51 + --> tests/ui/eta.rs:104:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); | ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo` @@ -41,175 +41,175 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_for_method_calls)]` error: redundant closure - --> tests/ui/eta.rs:103:51 + --> tests/ui/eta.rs:106:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo()); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo` error: redundant closure - --> tests/ui/eta.rs:106:42 + --> tests/ui/eta.rs:109:42 | LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear()); | ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear` error: redundant closure - --> tests/ui/eta.rs:111:29 + --> tests/ui/eta.rs:114:29 | LL | let e = Some("str").map(|s| s.to_string()); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string` error: redundant closure - --> tests/ui/eta.rs:113:27 + --> tests/ui/eta.rs:116:27 | LL | let e = Some('a').map(|s| s.to_uppercase()); | ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase` error: redundant closure - --> tests/ui/eta.rs:116:65 + --> tests/ui/eta.rs:119:65 | LL | let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase` error: redundant closure - --> tests/ui/eta.rs:133:23 + --> tests/ui/eta.rs:136:23 | LL | let _ = x.map(|x| x.parse::()); | ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `str::parse::` error: redundant closure - --> tests/ui/eta.rs:186:22 + --> tests/ui/eta.rs:189:22 | LL | requires_fn_once(|| x()); | ^^^^^^ help: replace the closure with the function itself: `x` error: redundant closure - --> tests/ui/eta.rs:194:27 + --> tests/ui/eta.rs:197:27 | LL | let a = Some(1u8).map(|a| foo_ptr(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr` error: redundant closure - --> tests/ui/eta.rs:200:27 + --> tests/ui/eta.rs:203:27 | LL | let a = Some(1u8).map(|a| closure(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure` error: redundant closure - --> tests/ui/eta.rs:233:28 + --> tests/ui/eta.rs:236:28 | LL | x.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> tests/ui/eta.rs:235:28 + --> tests/ui/eta.rs:238:28 | LL | y.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> tests/ui/eta.rs:237:28 + --> tests/ui/eta.rs:240:28 | LL | z.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res` error: redundant closure - --> tests/ui/eta.rs:245:21 + --> tests/ui/eta.rs:248:21 | LL | Some(1).map(|n| closure(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure` error: redundant closure - --> tests/ui/eta.rs:250:21 + --> tests/ui/eta.rs:253:21 | LL | Some(1).map(|n| in_loop(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop` error: redundant closure - --> tests/ui/eta.rs:344:18 + --> tests/ui/eta.rs:347:18 | LL | takes_fn_mut(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> tests/ui/eta.rs:348:19 + --> tests/ui/eta.rs:351:19 | LL | takes_fn_once(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> tests/ui/eta.rs:353:26 + --> tests/ui/eta.rs:356:26 | LL | move || takes_fn_mut(|| f_used_once()) | ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once` error: redundant closure - --> tests/ui/eta.rs:366:19 + --> tests/ui/eta.rs:369:19 | LL | array_opt.map(|a| a.as_slice()); | ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice` error: redundant closure - --> tests/ui/eta.rs:370:19 + --> tests/ui/eta.rs:373:19 | LL | slice_opt.map(|s| s.len()); | ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len` error: redundant closure - --> tests/ui/eta.rs:374:17 + --> tests/ui/eta.rs:377:17 | LL | ptr_opt.map(|p| p.is_null()); | ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null` error: redundant closure - --> tests/ui/eta.rs:379:17 + --> tests/ui/eta.rs:382:17 | LL | dyn_opt.map(|d| d.method_on_dyn()); | ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `::method_on_dyn` error: redundant closure - --> tests/ui/eta.rs:440:19 + --> tests/ui/eta.rs:443:19 | LL | let _ = f(&0, |x, y| f2(x, y)); | ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2` error: redundant closure - --> tests/ui/eta.rs:469:22 + --> tests/ui/eta.rs:472:22 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Test::method` error: redundant closure - --> tests/ui/eta.rs:474:22 + --> tests/ui/eta.rs:477:22 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `super::Outer::method` error: redundant closure - --> tests/ui/eta.rs:488:18 + --> tests/ui/eta.rs:491:18 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `test_mod::Test::method` error: redundant closure - --> tests/ui/eta.rs:496:30 + --> tests/ui/eta.rs:499:30 | LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method` error: redundant closure - --> tests/ui/eta.rs:516:38 + --> tests/ui/eta.rs:519:38 | LL | let x = Box::new(|| None.map(|x| f(x))); | ^^^^^^^^ help: replace the closure with the function itself: `&f` error: redundant closure - --> tests/ui/eta.rs:521:38 + --> tests/ui/eta.rs:524:38 | LL | let x = Box::new(|| None.map(|x| f(x))); | ^^^^^^^^ help: replace the closure with the function itself: `f` error: redundant closure - --> tests/ui/eta.rs:539:35 + --> tests/ui/eta.rs:542:35 | LL | let _field = bind.or_else(|| get_default()).unwrap(); | ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default` diff --git a/tests/ui/explicit_auto_deref.fixed b/tests/ui/explicit_auto_deref.fixed index c7edf33012e0..7235f7d5b82a 100644 --- a/tests/ui/explicit_auto_deref.fixed +++ b/tests/ui/explicit_auto_deref.fixed @@ -81,7 +81,8 @@ fn main() { f_ref_t(&*s); // Don't lint. Inferred type would change. f_str_t(&s, &*s); // Don't lint second param. - //~^ explicit_auto_deref + // + //~^^ explicit_auto_deref let b = Box::new(Box::new(Box::new(5))); let _: &Box = &b; @@ -239,9 +240,11 @@ fn main() { } f_str(&ref_str); // `needless_borrow` will suggest removing both references - //~^ explicit_auto_deref + // + //~^^ explicit_auto_deref f_str(&ref_str); // `needless_borrow` will suggest removing only one reference - //~^ explicit_auto_deref + // + //~^^ explicit_auto_deref let x = &&40; unsafe { diff --git a/tests/ui/explicit_auto_deref.rs b/tests/ui/explicit_auto_deref.rs index 4d2b2fc3fc39..c4d2b28ff4b5 100644 --- a/tests/ui/explicit_auto_deref.rs +++ b/tests/ui/explicit_auto_deref.rs @@ -81,7 +81,8 @@ fn main() { f_ref_t(&*s); // Don't lint. Inferred type would change. f_str_t(&*s, &*s); // Don't lint second param. - //~^ explicit_auto_deref + // + //~^^ explicit_auto_deref let b = Box::new(Box::new(Box::new(5))); let _: &Box = &**b; @@ -239,9 +240,11 @@ fn main() { } f_str(&&*ref_str); // `needless_borrow` will suggest removing both references - //~^ explicit_auto_deref + // + //~^^ explicit_auto_deref f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference - //~^ explicit_auto_deref + // + //~^^ explicit_auto_deref let x = &&40; unsafe { diff --git a/tests/ui/explicit_auto_deref.stderr b/tests/ui/explicit_auto_deref.stderr index e1cfb214864f..ba4cd86e0b5a 100644 --- a/tests/ui/explicit_auto_deref.stderr +++ b/tests/ui/explicit_auto_deref.stderr @@ -32,247 +32,247 @@ LL | f_str_t(&*s, &*s); // Don't lint second param. | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:87:24 + --> tests/ui/explicit_auto_deref.rs:88:24 | LL | let _: &Box = &**b; | ^^^^ help: try: `&b` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:94:7 + --> tests/ui/explicit_auto_deref.rs:95:7 | LL | c(&*s); | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:101:9 + --> tests/ui/explicit_auto_deref.rs:102:9 | LL | &**x | ^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:106:11 + --> tests/ui/explicit_auto_deref.rs:107:11 | LL | { &**x } | ^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:111:9 + --> tests/ui/explicit_auto_deref.rs:112:9 | LL | &**{ x } | ^^^^^^^^ help: try: `{ x }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:116:9 + --> tests/ui/explicit_auto_deref.rs:117:9 | LL | &***x | ^^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:134:12 + --> tests/ui/explicit_auto_deref.rs:135:12 | LL | f1(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:136:12 + --> tests/ui/explicit_auto_deref.rs:137:12 | LL | f2(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:138:12 + --> tests/ui/explicit_auto_deref.rs:139:12 | LL | f3(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:140:27 + --> tests/ui/explicit_auto_deref.rs:141:27 | LL | f4.callable_str()(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:142:12 + --> tests/ui/explicit_auto_deref.rs:143:12 | LL | f5(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:144:12 + --> tests/ui/explicit_auto_deref.rs:145:12 | LL | f6(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:146:27 + --> tests/ui/explicit_auto_deref.rs:147:27 | LL | f7.callable_str()(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:148:25 + --> tests/ui/explicit_auto_deref.rs:149:25 | LL | f8.callable_t()(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:150:12 + --> tests/ui/explicit_auto_deref.rs:151:12 | LL | f9(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:152:13 + --> tests/ui/explicit_auto_deref.rs:153:13 | LL | f10(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:154:26 + --> tests/ui/explicit_auto_deref.rs:155:26 | LL | f11.callable_t()(&*x); | ^^^ help: try: `&x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:159:16 + --> tests/ui/explicit_auto_deref.rs:160:16 | LL | let _ = S1(&*s); | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:165:21 + --> tests/ui/explicit_auto_deref.rs:166:21 | LL | let _ = S2 { s: &*s }; | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:182:30 + --> tests/ui/explicit_auto_deref.rs:183:30 | LL | let _ = Self::S1(&**s); | ^^^^ help: try: `s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:184:35 + --> tests/ui/explicit_auto_deref.rs:185:35 | LL | let _ = Self::S2 { s: &**s }; | ^^^^ help: try: `s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:188:20 + --> tests/ui/explicit_auto_deref.rs:189:20 | LL | let _ = E1::S1(&*s); | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:190:25 + --> tests/ui/explicit_auto_deref.rs:191:25 | LL | let _ = E1::S2 { s: &*s }; | ^^^ help: try: `&s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:209:13 + --> tests/ui/explicit_auto_deref.rs:210:13 | LL | let _ = (*b).foo; | ^^^^ help: try: `b` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:211:13 + --> tests/ui/explicit_auto_deref.rs:212:13 | LL | let _ = (**b).foo; | ^^^^^ help: try: `b` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:227:19 + --> tests/ui/explicit_auto_deref.rs:228:19 | LL | let _ = f_str(*ref_str); | ^^^^^^^^ help: try: `ref_str` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:230:19 + --> tests/ui/explicit_auto_deref.rs:231:19 | LL | let _ = f_str(**ref_ref_str); | ^^^^^^^^^^^^^ help: try: `ref_ref_str` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:241:12 + --> tests/ui/explicit_auto_deref.rs:242:12 | LL | f_str(&&*ref_str); // `needless_borrow` will suggest removing both references | ^^^^^^^^^ help: try: `ref_str` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:243:12 + --> tests/ui/explicit_auto_deref.rs:245:12 | LL | f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference | ^^^^^^^^^^ help: try: `ref_str` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:253:41 + --> tests/ui/explicit_auto_deref.rs:256:41 | LL | let _ = || -> &'static str { return *s }; | ^^ help: try: `s` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:273:9 + --> tests/ui/explicit_auto_deref.rs:276:9 | LL | &**x | ^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:297:8 + --> tests/ui/explicit_auto_deref.rs:300:8 | LL | c1(*x); | ^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:301:20 + --> tests/ui/explicit_auto_deref.rs:304:20 | LL | return *x; | ^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:304:9 + --> tests/ui/explicit_auto_deref.rs:307:9 | LL | *x | ^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:339:20 + --> tests/ui/explicit_auto_deref.rs:342:20 | LL | Some(x) => &mut *x, | ^^^^^^^ help: try: `x` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:373:22 + --> tests/ui/explicit_auto_deref.rs:376:22 | LL | let _ = &mut (*{ x.u }).x; | ^^^^^^^^^^ help: try: `{ x.u }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:380:22 + --> tests/ui/explicit_auto_deref.rs:383:22 | LL | let _ = &mut (**x.u).x; | ^^^^^^^ help: try: `(*x.u)` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:382:22 + --> tests/ui/explicit_auto_deref.rs:385:22 | LL | let _ = &mut (**{ x.u }).x; | ^^^^^^^^^^^ help: try: `{ x.u }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:387:22 + --> tests/ui/explicit_auto_deref.rs:390:22 | LL | let _ = &mut (*x.u).x; | ^^^^^^ help: try: `x.u` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:389:22 + --> tests/ui/explicit_auto_deref.rs:392:22 | LL | let _ = &mut (*{ x.u }).x; | ^^^^^^^^^^ help: try: `{ x.u }` error: deref which would be done by auto-deref - --> tests/ui/explicit_auto_deref.rs:413:13 + --> tests/ui/explicit_auto_deref.rs:416:13 | LL | foo(&*wrapped_bar); | ^^^^^^^^^^^^^ help: try: `&wrapped_bar` diff --git a/tests/ui/literal_string_with_formatting_arg.rs b/tests/ui/literal_string_with_formatting_arg.rs index b6f865b1ef28..d54cceae53eb 100644 --- a/tests/ui/literal_string_with_formatting_arg.rs +++ b/tests/ui/literal_string_with_formatting_arg.rs @@ -52,7 +52,8 @@ fn main() { x.expect("{{y:?}"); x.expect(" {0}"); // If it only contains an integer, we ignore it. x.expect(r##" {x:?} "##); // `x` doesn't exist so we shoud not lint - //~^ literal_string_with_formatting_args + // + //~^^ literal_string_with_formatting_args x.expect("{y:...}"); let _ = "fn main {\n\ }"; diff --git a/tests/ui/manual_instant_elapsed.fixed b/tests/ui/manual_instant_elapsed.fixed index 4ef22002226e..187802bb76c9 100644 --- a/tests/ui/manual_instant_elapsed.fixed +++ b/tests/ui/manual_instant_elapsed.fixed @@ -25,5 +25,6 @@ fn main() { let ref_to_instant = &Instant::now(); (*ref_to_instant).elapsed(); // to ensure parens are added correctly - //~^ manual_instant_elapsed + // + //~^^ manual_instant_elapsed } diff --git a/tests/ui/manual_instant_elapsed.rs b/tests/ui/manual_instant_elapsed.rs index 4586b33cf880..61e14e5a3d9d 100644 --- a/tests/ui/manual_instant_elapsed.rs +++ b/tests/ui/manual_instant_elapsed.rs @@ -25,5 +25,6 @@ fn main() { let ref_to_instant = &Instant::now(); Instant::now() - *ref_to_instant; // to ensure parens are added correctly - //~^ manual_instant_elapsed + // + //~^^ manual_instant_elapsed } diff --git a/tests/ui/manual_slice_size_calculation.fixed b/tests/ui/manual_slice_size_calculation.fixed index 91ada0b75d5c..294d1e1506de 100644 --- a/tests/ui/manual_slice_size_calculation.fixed +++ b/tests/ui/manual_slice_size_calculation.fixed @@ -15,24 +15,32 @@ fn main() { // True positives: let _ = std::mem::size_of_val(s_i32); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = std::mem::size_of_val(s_i32); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = std::mem::size_of_val(s_i32) * 5; // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = std::mem::size_of_val(*s_i32_ref); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = std::mem::size_of_val(**s_i32_ref_ref); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let len = s_i32.len(); let size = size_of::(); let _ = std::mem::size_of_val(s_i32); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = std::mem::size_of_val(s_i32); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = std::mem::size_of_val(s_i32); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = std::mem::size_of_val(external!(&[1u64][..])); //~^ manual_slice_size_calculation diff --git a/tests/ui/manual_slice_size_calculation.rs b/tests/ui/manual_slice_size_calculation.rs index 0ef3793619c4..ae5225663139 100644 --- a/tests/ui/manual_slice_size_calculation.rs +++ b/tests/ui/manual_slice_size_calculation.rs @@ -15,24 +15,32 @@ fn main() { // True positives: let _ = s_i32.len() * size_of::(); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = size_of::() * s_i32.len(); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = size_of::() * s_i32.len() * 5; // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = size_of::() * s_i32_ref.len(); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = size_of::() * s_i32_ref_ref.len(); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let len = s_i32.len(); let size = size_of::(); let _ = len * size_of::(); // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = s_i32.len() * size; // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = len * size; // WARNING - //~^ manual_slice_size_calculation + // + //~^^ manual_slice_size_calculation let _ = external!(&[1u64][..]).len() * size_of::(); //~^ manual_slice_size_calculation diff --git a/tests/ui/manual_slice_size_calculation.stderr b/tests/ui/manual_slice_size_calculation.stderr index d752e8356aa8..f07e97a1c863 100644 --- a/tests/ui/manual_slice_size_calculation.stderr +++ b/tests/ui/manual_slice_size_calculation.stderr @@ -8,49 +8,49 @@ LL | let _ = s_i32.len() * size_of::(); // WARNING = help: to override `-D warnings` add `#[allow(clippy::manual_slice_size_calculation)]` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:19:13 + --> tests/ui/manual_slice_size_calculation.rs:20:13 | LL | let _ = size_of::() * s_i32.len(); // WARNING | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:21:13 + --> tests/ui/manual_slice_size_calculation.rs:23:13 | LL | let _ = size_of::() * s_i32.len() * 5; // WARNING | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:23:13 + --> tests/ui/manual_slice_size_calculation.rs:26:13 | LL | let _ = size_of::() * s_i32_ref.len(); // WARNING | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(*s_i32_ref)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:25:13 + --> tests/ui/manual_slice_size_calculation.rs:29:13 | LL | let _ = size_of::() * s_i32_ref_ref.len(); // WARNING | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(**s_i32_ref_ref)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:30:13 + --> tests/ui/manual_slice_size_calculation.rs:35:13 | LL | let _ = len * size_of::(); // WARNING | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:32:13 + --> tests/ui/manual_slice_size_calculation.rs:38:13 | LL | let _ = s_i32.len() * size; // WARNING | ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:34:13 + --> tests/ui/manual_slice_size_calculation.rs:41:13 | LL | let _ = len * size; // WARNING | ^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> tests/ui/manual_slice_size_calculation.rs:37:13 + --> tests/ui/manual_slice_size_calculation.rs:45:13 | LL | let _ = external!(&[1u64][..]).len() * size_of::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` diff --git a/tests/ui/mistyped_literal_suffix.fixed b/tests/ui/mistyped_literal_suffix.fixed index 50ef32e47c03..a0190acc5d4b 100644 --- a/tests/ui/mistyped_literal_suffix.fixed +++ b/tests/ui/mistyped_literal_suffix.fixed @@ -18,15 +18,19 @@ fn main() { let fail15 = 4_i64; //~^ mistyped_literal_suffixes let fail16 = 7_i8; // - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let fail17 = 23_i16; // - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let ok18 = 23_128; let fail20 = 2_i8; // - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let fail21 = 4_i16; // - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let ok24 = 12.34_64; let fail25 = 1E2_f32; @@ -41,9 +45,11 @@ fn main() { // testing that the suggestion actually fits in its type let fail30 = 127_i8; // should be i8 - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let fail31 = 240_u8; // should be u8 - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let ok32 = 360_8; // doesn't fit in either, should be ignored let fail33 = 0x1234_i16; //~^ mistyped_literal_suffixes @@ -51,7 +57,8 @@ fn main() { //~^ mistyped_literal_suffixes let ok35 = 0x12345_16; let fail36 = 0xFFFF_FFFF_FFFF_FFFF_u64; // u64 - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes // issue #6129 let ok37 = 123_32.123; diff --git a/tests/ui/mistyped_literal_suffix.rs b/tests/ui/mistyped_literal_suffix.rs index 92f827608b10..12a26204e755 100644 --- a/tests/ui/mistyped_literal_suffix.rs +++ b/tests/ui/mistyped_literal_suffix.rs @@ -18,15 +18,19 @@ fn main() { let fail15 = 4_64; //~^ mistyped_literal_suffixes let fail16 = 7_8; // - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let fail17 = 23_16; // - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let ok18 = 23_128; let fail20 = 2__8; // - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let fail21 = 4___16; // - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let ok24 = 12.34_64; let fail25 = 1E2_32; @@ -41,9 +45,11 @@ fn main() { // testing that the suggestion actually fits in its type let fail30 = 127_8; // should be i8 - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let fail31 = 240_8; // should be u8 - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes let ok32 = 360_8; // doesn't fit in either, should be ignored let fail33 = 0x1234_16; //~^ mistyped_literal_suffixes @@ -51,7 +57,8 @@ fn main() { //~^ mistyped_literal_suffixes let ok35 = 0x12345_16; let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64 - //~^ mistyped_literal_suffixes + // + //~^^ mistyped_literal_suffixes // issue #6129 let ok37 = 123_32.123; diff --git a/tests/ui/mistyped_literal_suffix.stderr b/tests/ui/mistyped_literal_suffix.stderr index 2fb3012b84f6..9c6b2fab21c3 100644 --- a/tests/ui/mistyped_literal_suffix.stderr +++ b/tests/ui/mistyped_literal_suffix.stderr @@ -19,79 +19,79 @@ LL | let fail16 = 7_8; // | ^^^ help: did you mean to write: `7_i8` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:22:18 + --> tests/ui/mistyped_literal_suffix.rs:23:18 | LL | let fail17 = 23_16; // | ^^^^^ help: did you mean to write: `23_i16` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:26:18 + --> tests/ui/mistyped_literal_suffix.rs:28:18 | LL | let fail20 = 2__8; // | ^^^^ help: did you mean to write: `2_i8` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:28:18 + --> tests/ui/mistyped_literal_suffix.rs:31:18 | LL | let fail21 = 4___16; // | ^^^^^^ help: did you mean to write: `4_i16` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:32:18 + --> tests/ui/mistyped_literal_suffix.rs:36:18 | LL | let fail25 = 1E2_32; | ^^^^^^ help: did you mean to write: `1E2_f32` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:34:18 + --> tests/ui/mistyped_literal_suffix.rs:38:18 | LL | let fail26 = 43E7_64; | ^^^^^^^ help: did you mean to write: `43E7_f64` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:36:18 + --> tests/ui/mistyped_literal_suffix.rs:40:18 | LL | let fail27 = 243E17_32; | ^^^^^^^^^ help: did you mean to write: `243E17_f32` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:38:18 + --> tests/ui/mistyped_literal_suffix.rs:42:18 | LL | let fail28 = 241251235E723_64; | ^^^^^^^^^^^^^^^^ help: did you mean to write: `241_251_235E723_f64` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:43:18 + --> tests/ui/mistyped_literal_suffix.rs:47:18 | LL | let fail30 = 127_8; // should be i8 | ^^^^^ help: did you mean to write: `127_i8` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:45:18 + --> tests/ui/mistyped_literal_suffix.rs:50:18 | LL | let fail31 = 240_8; // should be u8 | ^^^^^ help: did you mean to write: `240_u8` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:48:18 + --> tests/ui/mistyped_literal_suffix.rs:54:18 | LL | let fail33 = 0x1234_16; | ^^^^^^^^^ help: did you mean to write: `0x1234_i16` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:50:18 + --> tests/ui/mistyped_literal_suffix.rs:56:18 | LL | let fail34 = 0xABCD_16; | ^^^^^^^^^ help: did you mean to write: `0xABCD_u16` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:53:18 + --> tests/ui/mistyped_literal_suffix.rs:59:18 | LL | let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64 | ^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `0xFFFF_FFFF_FFFF_FFFF_u64` error: mistyped literal suffix - --> tests/ui/mistyped_literal_suffix.rs:60:13 + --> tests/ui/mistyped_literal_suffix.rs:67:13 | LL | let _ = 1.12345E1_32; | ^^^^^^^^^^^^ help: did you mean to write: `1.123_45E1_f32` diff --git a/tests/ui/mixed_attributes_style/global_allow.stderr b/tests/ui/mixed_attributes_style/global_allow.stderr new file mode 100644 index 000000000000..5fc1d2ac0c3e --- /dev/null +++ b/tests/ui/mixed_attributes_style/global_allow.stderr @@ -0,0 +1,20 @@ +error: empty line after outer attribute + --> tests/ui/mixed_attributes_style/auxiliary/submodule.rs:5:1 + | +LL | / #[allow(unused)] +LL | | +LL | | + | |_^ +LL | mod foo { + | ------- the attribute applies to this module + | + = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]` + = help: if the empty line is unintentional remove it +help: if the attribute should apply to the parent module use an inner attribute + | +LL | #![allow(unused)] + | + + +error: aborting due to 1 previous error + diff --git a/tests/ui/needless_bool/simple.stderr b/tests/ui/needless_bool/simple.stderr new file mode 100644 index 000000000000..077e9b5df47c --- /dev/null +++ b/tests/ui/needless_bool/simple.stderr @@ -0,0 +1,45 @@ +error: this if-then-else expression will always return true + --> tests/ui/needless_bool/simple.rs:14:5 + | +LL | / if x { +LL | | true +LL | | } else { +LL | | true +LL | | }; + | |_____^ + | + = note: `-D clippy::needless-bool` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]` + +error: this if-then-else expression will always return false + --> tests/ui/needless_bool/simple.rs:20:5 + | +LL | / if x { +LL | | false +LL | | } else { +LL | | false +LL | | }; + | |_____^ + +error: this if-then-else expression will always return true + --> tests/ui/needless_bool/simple.rs:36:5 + | +LL | / if x { +LL | | return true; +LL | | } else { +LL | | return true; +LL | | }; + | |_____^ + +error: this if-then-else expression will always return false + --> tests/ui/needless_bool/simple.rs:45:5 + | +LL | / if x { +LL | | return false; +LL | | } else { +LL | | return false; +LL | | }; + | |_____^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/needless_bool_assign.stderr b/tests/ui/needless_bool_assign.stderr new file mode 100644 index 000000000000..f33a4bc0c592 --- /dev/null +++ b/tests/ui/needless_bool_assign.stderr @@ -0,0 +1,55 @@ +error: this if-then-else expression assigns a bool literal + --> tests/ui/needless_bool_assign.rs:13:5 + | +LL | / if random() && random() { +LL | | a.field = true; +LL | | } else { +LL | | a.field = false +LL | | } + | |_____^ help: you can reduce it to: `a.field = random() && random();` + | + = note: `-D clippy::needless-bool-assign` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_bool_assign)]` + +error: this if-then-else expression assigns a bool literal + --> tests/ui/needless_bool_assign.rs:19:5 + | +LL | / if random() && random() { +LL | | a.field = false; +LL | | } else { +LL | | a.field = true +LL | | } + | |_____^ help: you can reduce it to: `a.field = !(random() && random());` + +error: this if-then-else expression assigns a bool literal + --> tests/ui/needless_bool_assign.rs:34:5 + | +LL | / if random() { +LL | | a.field = true; +LL | | } else { +LL | | a.field = true; +LL | | } + | |_____^ help: you can reduce it to: `random(); a.field = true;` + +error: this `if` has identical blocks + --> tests/ui/needless_bool_assign.rs:34:17 + | +LL | if random() { + | _________________^ +LL | | a.field = true; +LL | | } else { + | |_____^ + | +note: same as this + --> tests/ui/needless_bool_assign.rs:36:12 + | +LL | } else { + | ____________^ +LL | | a.field = true; +LL | | } + | |_____^ + = note: `-D clippy::if-same-then-else` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed index 7bd42d17f3a4..d7d344452c5d 100644 --- a/tests/ui/needless_borrow.fixed +++ b/tests/ui/needless_borrow.fixed @@ -14,12 +14,14 @@ fn main() { let ref_a = &a; let _ = x(&a); // no warning let _ = x(&a); // warn - //~^ needless_borrow + // + //~^^ needless_borrow let mut b = 5; mut_ref(&mut b); // no warning mut_ref(&mut b); // warn - //~^ needless_borrow + // + //~^^ needless_borrow let s = &String::from("hi"); let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs index a5b337140b5b..1f05b90b4728 100644 --- a/tests/ui/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -14,12 +14,14 @@ fn main() { let ref_a = &a; let _ = x(&a); // no warning let _ = x(&&a); // warn - //~^ needless_borrow + // + //~^^ needless_borrow let mut b = 5; mut_ref(&mut b); // no warning mut_ref(&mut &mut b); // warn - //~^ needless_borrow + // + //~^^ needless_borrow let s = &String::from("hi"); let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr index b574948962de..b036b1e47d18 100644 --- a/tests/ui/needless_borrow.stderr +++ b/tests/ui/needless_borrow.stderr @@ -8,163 +8,163 @@ LL | let _ = x(&&a); // warn = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:21:13 + --> tests/ui/needless_borrow.rs:22:13 | LL | mut_ref(&mut &mut b); // warn | ^^^^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:34:13 + --> tests/ui/needless_borrow.rs:36:13 | LL | &&a | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:37:15 + --> tests/ui/needless_borrow.rs:39:15 | LL | 46 => &&a, | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:44:27 + --> tests/ui/needless_borrow.rs:46:27 | LL | break &ref_a; | ^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:52:15 + --> tests/ui/needless_borrow.rs:54:15 | LL | let _ = x(&&&a); | ^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:54:15 + --> tests/ui/needless_borrow.rs:56:15 | LL | let _ = x(&mut &&a); | ^^^^^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:56:15 + --> tests/ui/needless_borrow.rs:58:15 | LL | let _ = x(&&&mut b); | ^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:58:15 + --> tests/ui/needless_borrow.rs:60:15 | LL | let _ = x(&&ref_a); | ^^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:62:11 + --> tests/ui/needless_borrow.rs:64:11 | LL | x(&b); | ^^ help: change this to: `b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:70:13 + --> tests/ui/needless_borrow.rs:72:13 | LL | mut_ref(&mut x); | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:72:13 + --> tests/ui/needless_borrow.rs:74:13 | LL | mut_ref(&mut &mut x); | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:74:23 + --> tests/ui/needless_borrow.rs:76:23 | LL | let y: &mut i32 = &mut x; | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:76:23 + --> tests/ui/needless_borrow.rs:78:23 | LL | let y: &mut i32 = &mut &mut x; | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:86:14 + --> tests/ui/needless_borrow.rs:88:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:93:14 + --> tests/ui/needless_borrow.rs:95:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:106:13 + --> tests/ui/needless_borrow.rs:108:13 | LL | let _ = (&x).0; | ^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:109:22 + --> tests/ui/needless_borrow.rs:111:22 | LL | let _ = unsafe { (&*x).0 }; | ^^^^^ help: change this to: `(*x)` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:120:5 + --> tests/ui/needless_borrow.rs:122:5 | LL | (&&()).foo(); | ^^^^^^ help: change this to: `(&())` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:130:5 + --> tests/ui/needless_borrow.rs:132:5 | LL | (&&5).foo(); | ^^^^^ help: change this to: `(&5)` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:157:23 + --> tests/ui/needless_borrow.rs:159:23 | LL | let x: (&str,) = (&"",); | ^^^ help: change this to: `""` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:200:13 + --> tests/ui/needless_borrow.rs:202:13 | LL | (&self.f)() | ^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:210:13 + --> tests/ui/needless_borrow.rs:212:13 | LL | (&mut self.f)() | ^^^^^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:248:22 + --> tests/ui/needless_borrow.rs:250:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:256:22 + --> tests/ui/needless_borrow.rs:258:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:261:22 + --> tests/ui/needless_borrow.rs:263:22 | LL | let _ = &mut (&mut x.u).x; | ^^^^^^^^^^ help: change this to: `x.u` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:263:22 + --> tests/ui/needless_borrow.rs:265:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:285:23 + --> tests/ui/needless_borrow.rs:287:23 | LL | option.unwrap_or((&x.0,)); | ^^^^ help: change this to: `x.0` diff --git a/tests/ui/needless_borrows_for_generic_args.fixed b/tests/ui/needless_borrows_for_generic_args.fixed index 374caeacfd28..8dea0d259772 100644 --- a/tests/ui/needless_borrows_for_generic_args.fixed +++ b/tests/ui/needless_borrows_for_generic_args.fixed @@ -338,11 +338,13 @@ fn main() { let x = String::new(); f(&x); // Don't lint, not a copy, makes it unavailable later f(String::new()); // Lint, makes no difference - //~^ needless_borrows_for_generic_args + // + //~^^ needless_borrows_for_generic_args let y = "".to_owned(); f(&y); // Don't lint f("".to_owned()); // Lint - //~^ needless_borrows_for_generic_args + // + //~^^ needless_borrows_for_generic_args } { fn takes_writer(_: T) {} diff --git a/tests/ui/needless_borrows_for_generic_args.rs b/tests/ui/needless_borrows_for_generic_args.rs index 06e2a4505211..bc2db6774e96 100644 --- a/tests/ui/needless_borrows_for_generic_args.rs +++ b/tests/ui/needless_borrows_for_generic_args.rs @@ -338,11 +338,13 @@ fn main() { let x = String::new(); f(&x); // Don't lint, not a copy, makes it unavailable later f(&String::new()); // Lint, makes no difference - //~^ needless_borrows_for_generic_args + // + //~^^ needless_borrows_for_generic_args let y = "".to_owned(); f(&y); // Don't lint f(&"".to_owned()); // Lint - //~^ needless_borrows_for_generic_args + // + //~^^ needless_borrows_for_generic_args } { fn takes_writer(_: T) {} diff --git a/tests/ui/needless_borrows_for_generic_args.stderr b/tests/ui/needless_borrows_for_generic_args.stderr index 6b5a0b4b1b67..8829854e3073 100644 --- a/tests/ui/needless_borrows_for_generic_args.stderr +++ b/tests/ui/needless_borrows_for_generic_args.stderr @@ -62,7 +62,7 @@ LL | f(&String::new()); // Lint, makes no difference | ^^^^^^^^^^^^^^ help: change this to: `String::new()` error: the borrowed expression implements the required traits - --> tests/ui/needless_borrows_for_generic_args.rs:344:11 + --> tests/ui/needless_borrows_for_generic_args.rs:345:11 | LL | f(&"".to_owned()); // Lint | ^^^^^^^^^^^^^^ help: change this to: `"".to_owned()` diff --git a/tests/ui/needless_else.stderr b/tests/ui/needless_else.stderr new file mode 100644 index 000000000000..77ead31b31cc --- /dev/null +++ b/tests/ui/needless_else.stderr @@ -0,0 +1,13 @@ +error: this `else` branch is empty + --> tests/ui/needless_else.rs:23:7 + | +LL | } else { + | _______^ +LL | | } + | |_____^ help: you can remove it + | + = note: `-D clippy::needless-else` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_else)]` + +error: aborting due to 1 previous error + diff --git a/tests/ui/option_env_unwrap.rs b/tests/ui/option_env_unwrap.rs index f5e57284df49..b8476830efe5 100644 --- a/tests/ui/option_env_unwrap.rs +++ b/tests/ui/option_env_unwrap.rs @@ -12,7 +12,8 @@ fn main() { let _ = option_env!("PATH").expect("environment variable PATH isn't set"); //~^ option_env_unwrap let _ = option_env!("__Y__do_not_use").unwrap(); // This test only works if you don't have a __Y__do_not_use env variable in your environment. - //~^ option_env_unwrap + // + //~^^ option_env_unwrap let _ = inline!(option_env!($"PATH").unwrap()); //~^ option_env_unwrap let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set")); diff --git a/tests/ui/option_env_unwrap.stderr b/tests/ui/option_env_unwrap.stderr index cee0fe6bf9ae..bbcbfedb7882 100644 --- a/tests/ui/option_env_unwrap.stderr +++ b/tests/ui/option_env_unwrap.stderr @@ -25,7 +25,7 @@ LL | let _ = option_env!("__Y__do_not_use").unwrap(); // This test only work = help: consider using the `env!` macro instead error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:16:21 + --> tests/ui/option_env_unwrap.rs:17:21 | LL | let _ = inline!(option_env!($"PATH").unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = inline!(option_env!($"PATH").unwrap()); = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:18:21 + --> tests/ui/option_env_unwrap.rs:19:21 | LL | let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL | let _ = inline!(option_env!($"PATH").expect($"environment variable PATH = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:20:13 + --> tests/ui/option_env_unwrap.rs:21:13 | LL | let _ = external!(option_env!($"PATH").unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | let _ = external!(option_env!($"PATH").unwrap()); = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> tests/ui/option_env_unwrap.rs:22:13 + --> tests/ui/option_env_unwrap.rs:23:13 | LL | let _ = external!(option_env!($"PATH").expect($"environment variable PATH isn't set")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed index 7014e20c1f85..1794ac57fe5b 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -374,11 +374,13 @@ fn fn_call_in_nested_expr() { let opt: Option = Some(1); let _ = opt.unwrap_or_else(f); // suggest `.unwrap_or_else(f)` - //~^ or_fun_call + // + //~^^ or_fun_call // let _ = opt.unwrap_or_else(|| f() + 1); // suggest `.unwrap_or_else(|| f() + 1)` - //~^ or_fun_call + // + //~^^ or_fun_call // let _ = opt.unwrap_or_else(|| { @@ -388,7 +390,8 @@ fn fn_call_in_nested_expr() { }); let _ = opt.map_or_else(|| f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)` - //~^ or_fun_call + // + //~^^ or_fun_call // let _ = opt.unwrap_or_default(); diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index d8a0ab033c4d..256db343c057 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -374,11 +374,13 @@ fn fn_call_in_nested_expr() { let opt: Option = Some(1); let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)` - //~^ or_fun_call + // + //~^^ or_fun_call // let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)` - //~^ or_fun_call + // + //~^^ or_fun_call // let _ = opt.unwrap_or({ @@ -388,7 +390,8 @@ fn fn_call_in_nested_expr() { }); let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)` - //~^ or_fun_call + // + //~^^ or_fun_call // let _ = opt.unwrap_or({ i32::default() }); diff --git a/tests/ui/or_fun_call.stderr b/tests/ui/or_fun_call.stderr index 0cc8ad39421c..93c87b2f12cd 100644 --- a/tests/ui/or_fun_call.stderr +++ b/tests/ui/or_fun_call.stderr @@ -203,13 +203,13 @@ LL | let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(f)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:380:17 + --> tests/ui/or_fun_call.rs:381:17 | LL | let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| f() + 1)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:384:17 + --> tests/ui/or_fun_call.rs:386:17 | LL | let _ = opt.unwrap_or({ | _________________^ @@ -229,19 +229,19 @@ LL ~ }); | error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:390:17 + --> tests/ui/or_fun_call.rs:392:17 | LL | let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)` | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| f() + 1, |v| v)` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:394:17 + --> tests/ui/or_fun_call.rs:397:17 | LL | let _ = opt.unwrap_or({ i32::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:401:21 + --> tests/ui/or_fun_call.rs:404:21 | LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })` diff --git a/tests/ui/or_then_unwrap.fixed b/tests/ui/or_then_unwrap.fixed index 19db0e47279c..ba9beef57afa 100644 --- a/tests/ui/or_then_unwrap.fixed +++ b/tests/ui/or_then_unwrap.fixed @@ -20,16 +20,19 @@ impl SomeOtherStruct { fn main() { let option: Option<&str> = None; let _ = option.unwrap_or("fallback"); // should trigger lint - //~^ or_then_unwrap + // + //~^^ or_then_unwrap let result: Result<&str, &str> = Err("Error"); let _ = result.unwrap_or("fallback"); // should trigger lint - //~^ or_then_unwrap + // + //~^^ or_then_unwrap // as part of a method chain let option: Option<&str> = None; let _ = option.map(|v| v).unwrap_or("fallback").to_string().chars(); // should trigger lint - //~^ or_then_unwrap + // + //~^^ or_then_unwrap // Not Option/Result let instance = SomeStruct {}; diff --git a/tests/ui/or_then_unwrap.rs b/tests/ui/or_then_unwrap.rs index 7af03b523f73..fac90249a243 100644 --- a/tests/ui/or_then_unwrap.rs +++ b/tests/ui/or_then_unwrap.rs @@ -20,16 +20,19 @@ impl SomeOtherStruct { fn main() { let option: Option<&str> = None; let _ = option.or(Some("fallback")).unwrap(); // should trigger lint - //~^ or_then_unwrap + // + //~^^ or_then_unwrap let result: Result<&str, &str> = Err("Error"); let _ = result.or::<&str>(Ok("fallback")).unwrap(); // should trigger lint - //~^ or_then_unwrap + // + //~^^ or_then_unwrap // as part of a method chain let option: Option<&str> = None; let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint - //~^ or_then_unwrap + // + //~^^ or_then_unwrap // Not Option/Result let instance = SomeStruct {}; diff --git a/tests/ui/or_then_unwrap.stderr b/tests/ui/or_then_unwrap.stderr index d64cc58a790b..1160498c6053 100644 --- a/tests/ui/or_then_unwrap.stderr +++ b/tests/ui/or_then_unwrap.stderr @@ -8,13 +8,13 @@ LL | let _ = option.or(Some("fallback")).unwrap(); // should trigger lint = help: to override `-D warnings` add `#[allow(clippy::or_then_unwrap)]` error: found `.or(Ok(…)).unwrap()` - --> tests/ui/or_then_unwrap.rs:26:20 + --> tests/ui/or_then_unwrap.rs:27:20 | LL | let _ = result.or::<&str>(Ok("fallback")).unwrap(); // should trigger lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")` error: found `.or(Some(…)).unwrap()` - --> tests/ui/or_then_unwrap.rs:31:31 + --> tests/ui/or_then_unwrap.rs:33:31 | LL | let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")` diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed index 711196f8e19b..5585006dc362 100644 --- a/tests/ui/redundant_pattern_matching_option.fixed +++ b/tests/ui/redundant_pattern_matching_option.fixed @@ -17,7 +17,8 @@ fn issue_11174(boolean: bool, maybe_some: Option) -> bool { fn issue_11174_edge_cases(boolean: bool, boolean2: bool, maybe_some: Option) { let _ = maybe_some.is_none() && (boolean || boolean2); // guard needs parentheses - //~^ redundant_pattern_matching + // + //~^^ redundant_pattern_matching let _ = match maybe_some { // can't use `matches!` here // because `expr` metavars in macros don't allow let exprs diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs index 41106840cb8d..581a432f38e1 100644 --- a/tests/ui/redundant_pattern_matching_option.rs +++ b/tests/ui/redundant_pattern_matching_option.rs @@ -17,7 +17,8 @@ fn issue_11174(boolean: bool, maybe_some: Option) -> bool { fn issue_11174_edge_cases(boolean: bool, boolean2: bool, maybe_some: Option) { let _ = matches!(maybe_some, None if boolean || boolean2); // guard needs parentheses - //~^ redundant_pattern_matching + // + //~^^ redundant_pattern_matching let _ = match maybe_some { // can't use `matches!` here // because `expr` metavars in macros don't allow let exprs diff --git a/tests/ui/redundant_pattern_matching_option.stderr b/tests/ui/redundant_pattern_matching_option.stderr index 0dfa05970ce3..681602567d2f 100644 --- a/tests/ui/redundant_pattern_matching_option.stderr +++ b/tests/ui/redundant_pattern_matching_option.stderr @@ -14,49 +14,49 @@ LL | let _ = matches!(maybe_some, None if boolean || boolean2); // guard nee | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (boolean || boolean2)` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:34:12 + --> tests/ui/redundant_pattern_matching_option.rs:35:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:37:12 + --> tests/ui/redundant_pattern_matching_option.rs:38:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:40:12 + --> tests/ui/redundant_pattern_matching_option.rs:41:12 | LL | if let Some(_) = Some(42) { | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:47:15 + --> tests/ui/redundant_pattern_matching_option.rs:48:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:50:15 + --> tests/ui/redundant_pattern_matching_option.rs:51:15 | LL | while let None = Some(42) {} | ----------^^^^----------- help: try: `while Some(42).is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:53:15 + --> tests/ui/redundant_pattern_matching_option.rs:54:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:57:15 + --> tests/ui/redundant_pattern_matching_option.rs:58:15 | LL | while let Some(_) = v.pop() { | ----------^^^^^^^---------- help: try: `while v.pop().is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:66:5 + --> tests/ui/redundant_pattern_matching_option.rs:67:5 | LL | / match Some(42) { LL | | @@ -66,7 +66,7 @@ LL | | }; | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:72:5 + --> tests/ui/redundant_pattern_matching_option.rs:73:5 | LL | / match None::<()> { LL | | @@ -76,7 +76,7 @@ LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:78:13 + --> tests/ui/redundant_pattern_matching_option.rs:79:13 | LL | let _ = match None::<()> { | _____________^ @@ -87,55 +87,55 @@ LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:85:20 + --> tests/ui/redundant_pattern_matching_option.rs:86:20 | LL | let _ = if let Some(_) = opt { true } else { false }; | -------^^^^^^^------ help: try: `if opt.is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:92:20 + --> tests/ui/redundant_pattern_matching_option.rs:93:20 | LL | let _ = if let Some(_) = gen_opt() { | -------^^^^^^^------------ help: try: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:95:19 + --> tests/ui/redundant_pattern_matching_option.rs:96:19 | LL | } else if let None = gen_opt() { | -------^^^^------------ help: try: `if gen_opt().is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:102:12 + --> tests/ui/redundant_pattern_matching_option.rs:103:12 | LL | if let Some(..) = gen_opt() {} | -------^^^^^^^^------------ help: try: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:118:12 + --> tests/ui/redundant_pattern_matching_option.rs:119:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:121:12 + --> tests/ui/redundant_pattern_matching_option.rs:122:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:124:15 + --> tests/ui/redundant_pattern_matching_option.rs:125:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:127:15 + --> tests/ui/redundant_pattern_matching_option.rs:128:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:130:5 + --> tests/ui/redundant_pattern_matching_option.rs:131:5 | LL | / match Some(42) { LL | | @@ -145,7 +145,7 @@ LL | | }; | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:136:5 + --> tests/ui/redundant_pattern_matching_option.rs:137:5 | LL | / match None::<()> { LL | | @@ -155,19 +155,19 @@ LL | | }; | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:145:12 + --> tests/ui/redundant_pattern_matching_option.rs:146:12 | LL | if let None = *(&None::<()>) {} | -------^^^^----------------- help: try: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:147:12 + --> tests/ui/redundant_pattern_matching_option.rs:148:12 | LL | if let None = *&None::<()> {} | -------^^^^--------------- help: try: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:154:5 + --> tests/ui/redundant_pattern_matching_option.rs:155:5 | LL | / match x { LL | | @@ -177,7 +177,7 @@ LL | | }; | |_____^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:160:5 + --> tests/ui/redundant_pattern_matching_option.rs:161:5 | LL | / match x { LL | | @@ -187,7 +187,7 @@ LL | | }; | |_____^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:166:5 + --> tests/ui/redundant_pattern_matching_option.rs:167:5 | LL | / match x { LL | | @@ -197,7 +197,7 @@ LL | | }; | |_____^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:172:5 + --> tests/ui/redundant_pattern_matching_option.rs:173:5 | LL | / match x { LL | | @@ -207,19 +207,19 @@ LL | | }; | |_____^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_some()` - --> tests/ui/redundant_pattern_matching_option.rs:188:13 + --> tests/ui/redundant_pattern_matching_option.rs:189:13 | LL | let _ = matches!(x, Some(_)); | ^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_some()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:191:13 + --> tests/ui/redundant_pattern_matching_option.rs:192:13 | LL | let _ = matches!(x, None); | ^^^^^^^^^^^^^^^^^ help: try: `x.is_none()` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/redundant_pattern_matching_option.rs:202:17 + --> tests/ui/redundant_pattern_matching_option.rs:203:17 | LL | let _ = matches!(*p, None); | ^^^^^^^^^^^^^^^^^^ help: try: `(*p).is_none()` diff --git a/tests/ui/redundant_pub_crate.fixed b/tests/ui/redundant_pub_crate.fixed index 7424af19a999..a6450123f4c9 100644 --- a/tests/ui/redundant_pub_crate.fixed +++ b/tests/ui/redundant_pub_crate.fixed @@ -5,13 +5,15 @@ mod m1 { fn f() {} pub fn g() {} // private due to m1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} mod m1_1 { fn f() {} pub fn g() {} // private due to m1_1 and m1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -20,14 +22,16 @@ mod m1 { //:^ private due to m1 fn f() {} pub fn g() {} // private due to m1_2 and m1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } pub mod m1_3 { fn f() {} pub fn g() {} // private due to m1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } } @@ -35,13 +39,15 @@ mod m1 { pub(crate) mod m2 { fn f() {} pub fn g() {} // already crate visible due to m2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} mod m2_1 { fn f() {} pub fn g() {} // private due to m2_1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -50,14 +56,16 @@ pub(crate) mod m2 { //:^ already crate visible due to m2 fn f() {} pub fn g() {} // already crate visible due to m2_2 and m2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } pub mod m2_3 { fn f() {} pub fn g() {} // already crate visible due to m2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } } @@ -70,7 +78,8 @@ pub mod m3 { mod m3_1 { fn f() {} pub fn g() {} // private due to m3_1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -78,7 +87,8 @@ pub mod m3 { //:^ ok fn f() {} pub fn g() {} // already crate visible due to m3_2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -92,13 +102,15 @@ pub mod m3 { mod m4 { fn f() {} pub fn g() {} // private: not re-exported by `pub use m4::*` - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} mod m4_1 { fn f() {} pub fn g() {} // private due to m4_1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -107,7 +119,8 @@ mod m4 { //:^ private: not re-exported by `pub use m4::*` fn f() {} pub fn g() {} // private due to m4_2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } diff --git a/tests/ui/redundant_pub_crate.rs b/tests/ui/redundant_pub_crate.rs index a995ed592289..7415d34d50cc 100644 --- a/tests/ui/redundant_pub_crate.rs +++ b/tests/ui/redundant_pub_crate.rs @@ -5,13 +5,15 @@ mod m1 { fn f() {} pub(crate) fn g() {} // private due to m1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} mod m1_1 { fn f() {} pub(crate) fn g() {} // private due to m1_1 and m1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -20,14 +22,16 @@ mod m1 { //:^ private due to m1 fn f() {} pub(crate) fn g() {} // private due to m1_2 and m1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } pub mod m1_3 { fn f() {} pub(crate) fn g() {} // private due to m1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } } @@ -35,13 +39,15 @@ mod m1 { pub(crate) mod m2 { fn f() {} pub(crate) fn g() {} // already crate visible due to m2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} mod m2_1 { fn f() {} pub(crate) fn g() {} // private due to m2_1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -50,14 +56,16 @@ pub(crate) mod m2 { //:^ already crate visible due to m2 fn f() {} pub(crate) fn g() {} // already crate visible due to m2_2 and m2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } pub mod m2_3 { fn f() {} pub(crate) fn g() {} // already crate visible due to m2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } } @@ -70,7 +78,8 @@ pub mod m3 { mod m3_1 { fn f() {} pub(crate) fn g() {} // private due to m3_1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -78,7 +87,8 @@ pub mod m3 { //:^ ok fn f() {} pub(crate) fn g() {} // already crate visible due to m3_2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -92,13 +102,15 @@ pub mod m3 { mod m4 { fn f() {} pub(crate) fn g() {} // private: not re-exported by `pub use m4::*` - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} mod m4_1 { fn f() {} pub(crate) fn g() {} // private due to m4_1 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } @@ -107,7 +119,8 @@ mod m4 { //:^ private: not re-exported by `pub use m4::*` fn f() {} pub(crate) fn g() {} // private due to m4_2 - //~^ redundant_pub_crate + // + //~^^ redundant_pub_crate pub fn h() {} } diff --git a/tests/ui/redundant_pub_crate.stderr b/tests/ui/redundant_pub_crate.stderr index 90be83d948bd..95909ea8b066 100644 --- a/tests/ui/redundant_pub_crate.stderr +++ b/tests/ui/redundant_pub_crate.stderr @@ -10,7 +10,7 @@ LL | pub(crate) fn g() {} // private due to m1 = help: to override `-D warnings` add `#[allow(clippy::redundant_pub_crate)]` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:13:9 + --> tests/ui/redundant_pub_crate.rs:14:9 | LL | pub(crate) fn g() {} // private due to m1_1 and m1 | ----------^^^^^ @@ -18,7 +18,7 @@ LL | pub(crate) fn g() {} // private due to m1_1 and m1 | help: consider using: `pub` error: pub(crate) module inside private module - --> tests/ui/redundant_pub_crate.rs:18:5 + --> tests/ui/redundant_pub_crate.rs:20:5 | LL | pub(crate) mod m1_2 { | ----------^^^^^^^^^ @@ -26,7 +26,7 @@ LL | pub(crate) mod m1_2 { | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:22:9 + --> tests/ui/redundant_pub_crate.rs:24:9 | LL | pub(crate) fn g() {} // private due to m1_2 and m1 | ----------^^^^^ @@ -34,7 +34,7 @@ LL | pub(crate) fn g() {} // private due to m1_2 and m1 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:29:9 + --> tests/ui/redundant_pub_crate.rs:32:9 | LL | pub(crate) fn g() {} // private due to m1 | ----------^^^^^ @@ -42,7 +42,7 @@ LL | pub(crate) fn g() {} // private due to m1 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:37:5 + --> tests/ui/redundant_pub_crate.rs:41:5 | LL | pub(crate) fn g() {} // already crate visible due to m2 | ----------^^^^^ @@ -50,7 +50,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m2 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:43:9 + --> tests/ui/redundant_pub_crate.rs:48:9 | LL | pub(crate) fn g() {} // private due to m2_1 | ----------^^^^^ @@ -58,7 +58,7 @@ LL | pub(crate) fn g() {} // private due to m2_1 | help: consider using: `pub` error: pub(crate) module inside private module - --> tests/ui/redundant_pub_crate.rs:48:5 + --> tests/ui/redundant_pub_crate.rs:54:5 | LL | pub(crate) mod m2_2 { | ----------^^^^^^^^^ @@ -66,7 +66,7 @@ LL | pub(crate) mod m2_2 { | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:52:9 + --> tests/ui/redundant_pub_crate.rs:58:9 | LL | pub(crate) fn g() {} // already crate visible due to m2_2 and m2 | ----------^^^^^ @@ -74,7 +74,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m2_2 and m2 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:59:9 + --> tests/ui/redundant_pub_crate.rs:66:9 | LL | pub(crate) fn g() {} // already crate visible due to m2 | ----------^^^^^ @@ -82,7 +82,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m2 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:72:9 + --> tests/ui/redundant_pub_crate.rs:80:9 | LL | pub(crate) fn g() {} // private due to m3_1 | ----------^^^^^ @@ -90,7 +90,7 @@ LL | pub(crate) fn g() {} // private due to m3_1 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:80:9 + --> tests/ui/redundant_pub_crate.rs:89:9 | LL | pub(crate) fn g() {} // already crate visible due to m3_2 | ----------^^^^^ @@ -98,7 +98,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m3_2 | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:94:5 + --> tests/ui/redundant_pub_crate.rs:104:5 | LL | pub(crate) fn g() {} // private: not re-exported by `pub use m4::*` | ----------^^^^^ @@ -106,7 +106,7 @@ LL | pub(crate) fn g() {} // private: not re-exported by `pub use m4::*` | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:100:9 + --> tests/ui/redundant_pub_crate.rs:111:9 | LL | pub(crate) fn g() {} // private due to m4_1 | ----------^^^^^ @@ -114,7 +114,7 @@ LL | pub(crate) fn g() {} // private due to m4_1 | help: consider using: `pub` error: pub(crate) module inside private module - --> tests/ui/redundant_pub_crate.rs:105:5 + --> tests/ui/redundant_pub_crate.rs:117:5 | LL | pub(crate) mod m4_2 { | ----------^^^^^^^^^ @@ -122,7 +122,7 @@ LL | pub(crate) mod m4_2 { | help: consider using: `pub` error: pub(crate) function inside private module - --> tests/ui/redundant_pub_crate.rs:109:9 + --> tests/ui/redundant_pub_crate.rs:121:9 | LL | pub(crate) fn g() {} // private due to m4_2 | ----------^^^^^ diff --git a/tests/ui/redundant_slicing.fixed b/tests/ui/redundant_slicing.fixed index d640de71e446..385a5d97cf1a 100644 --- a/tests/ui/redundant_slicing.fixed +++ b/tests/ui/redundant_slicing.fixed @@ -6,12 +6,14 @@ use std::io::Read; fn main() { let slice: &[u32] = &[0]; let _ = slice; // Redundant slice - //~^ redundant_slicing + // + //~^^ redundant_slicing let v = vec![0]; let _ = &v[..]; // Ok, results in `&[_]` let _ = (&*v); // Outer borrow is redundant - //~^ redundant_slicing + // + //~^^ redundant_slicing static S: &[u8] = &[0, 1, 2]; let _ = &mut &S[..]; // Ok, re-borrows slice diff --git a/tests/ui/redundant_slicing.rs b/tests/ui/redundant_slicing.rs index 34596cf84799..04f181da250d 100644 --- a/tests/ui/redundant_slicing.rs +++ b/tests/ui/redundant_slicing.rs @@ -6,12 +6,14 @@ use std::io::Read; fn main() { let slice: &[u32] = &[0]; let _ = &slice[..]; // Redundant slice - //~^ redundant_slicing + // + //~^^ redundant_slicing let v = vec![0]; let _ = &v[..]; // Ok, results in `&[_]` let _ = &(&*v)[..]; // Outer borrow is redundant - //~^ redundant_slicing + // + //~^^ redundant_slicing static S: &[u8] = &[0, 1, 2]; let _ = &mut &S[..]; // Ok, re-borrows slice diff --git a/tests/ui/redundant_slicing.stderr b/tests/ui/redundant_slicing.stderr index 47a61b41e978..964111bccf88 100644 --- a/tests/ui/redundant_slicing.stderr +++ b/tests/ui/redundant_slicing.stderr @@ -8,13 +8,13 @@ LL | let _ = &slice[..]; // Redundant slice = help: to override `-D warnings` add `#[allow(clippy::redundant_slicing)]` error: redundant slicing of the whole range - --> tests/ui/redundant_slicing.rs:13:13 + --> tests/ui/redundant_slicing.rs:14:13 | LL | let _ = &(&*v)[..]; // Outer borrow is redundant | ^^^^^^^^^^ help: use the original value instead: `(&*v)` error: redundant slicing of the whole range - --> tests/ui/redundant_slicing.rs:31:13 + --> tests/ui/redundant_slicing.rs:33:13 | LL | let _ = &m!(slice)[..]; | ^^^^^^^^^^^^^^ help: use the original value instead: `slice` diff --git a/tests/ui/search_is_some_fixable_none.fixed b/tests/ui/search_is_some_fixable_none.fixed index 8169550b0d55..e6355bdf792f 100644 --- a/tests/ui/search_is_some_fixable_none.fixed +++ b/tests/ui/search_is_some_fixable_none.fixed @@ -9,7 +9,8 @@ fn main() { let _ = !v.iter().any(|x| *x < 0); //~^ search_is_some let _ = !(0..1).any(|x| **y == x); // one dereference less - //~^ search_is_some + // + //~^^ search_is_some let _ = !(0..1).any(|x| x == 0); //~^ search_is_some let _ = !v.iter().any(|x| *x == 0); diff --git a/tests/ui/search_is_some_fixable_none.rs b/tests/ui/search_is_some_fixable_none.rs index 5935f0dd7e29..8cc80f122f08 100644 --- a/tests/ui/search_is_some_fixable_none.rs +++ b/tests/ui/search_is_some_fixable_none.rs @@ -9,7 +9,8 @@ fn main() { let _ = v.iter().find(|&x| *x < 0).is_none(); //~^ search_is_some let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less - //~^ search_is_some + // + //~^^ search_is_some let _ = (0..1).find(|x| *x == 0).is_none(); //~^ search_is_some let _ = v.iter().find(|x| **x == 0).is_none(); diff --git a/tests/ui/search_is_some_fixable_none.stderr b/tests/ui/search_is_some_fixable_none.stderr index e134df9f63c9..ccc17025222d 100644 --- a/tests/ui/search_is_some_fixable_none.stderr +++ b/tests/ui/search_is_some_fixable_none.stderr @@ -14,43 +14,43 @@ LL | let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| **y == x)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:13:13 + --> tests/ui/search_is_some_fixable_none.rs:14:13 | LL | let _ = (0..1).find(|x| *x == 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| x == 0)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:15:13 + --> tests/ui/search_is_some_fixable_none.rs:16:13 | LL | let _ = v.iter().find(|x| **x == 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 0)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:17:13 + --> tests/ui/search_is_some_fixable_none.rs:18:13 | LL | let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(4..5).any(|x| x == 1 || x == 3 || x == 5)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:19:13 + --> tests/ui/search_is_some_fixable_none.rs:20:13 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:21:13 + --> tests/ui/search_is_some_fixable_none.rs:22:13 | LL | let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:23:13 + --> tests/ui/search_is_some_fixable_none.rs:24:13 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:25:13 + --> tests/ui/search_is_some_fixable_none.rs:26:13 | LL | let _ = (1..3) | _____________^ @@ -60,91 +60,91 @@ LL | | .is_none(); | |__________________^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)` error: called `is_none()` after searching an `Iterator` with `position` - --> tests/ui/search_is_some_fixable_none.rs:31:13 + --> tests/ui/search_is_some_fixable_none.rs:32:13 | LL | let _ = v.iter().position(|&x| x < 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)` error: called `is_none()` after searching an `Iterator` with `rposition` - --> tests/ui/search_is_some_fixable_none.rs:35:13 + --> tests/ui/search_is_some_fixable_none.rs:36:13 | LL | let _ = v.iter().rposition(|&x| x < 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:42:13 + --> tests/ui/search_is_some_fixable_none.rs:43:13 | LL | let _ = "hello world".find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:44:13 + --> tests/ui/search_is_some_fixable_none.rs:45:13 | LL | let _ = "hello world".find(&s2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains(&s2)` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:46:13 + --> tests/ui/search_is_some_fixable_none.rs:47:13 | LL | let _ = "hello world".find(&s2[2..]).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains(&s2[2..])` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:49:13 + --> tests/ui/search_is_some_fixable_none.rs:50:13 | LL | let _ = s1.find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:51:13 + --> tests/ui/search_is_some_fixable_none.rs:52:13 | LL | let _ = s1.find(&s2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2)` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:53:13 + --> tests/ui/search_is_some_fixable_none.rs:54:13 | LL | let _ = s1.find(&s2[2..]).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2[2..])` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:56:13 + --> tests/ui/search_is_some_fixable_none.rs:57:13 | LL | let _ = s1[2..].find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:58:13 + --> tests/ui/search_is_some_fixable_none.rs:59:13 | LL | let _ = s1[2..].find(&s2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2)` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:60:13 + --> tests/ui/search_is_some_fixable_none.rs:61:13 | LL | let _ = s1[2..].find(&s2[2..]).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2[2..])` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:77:25 + --> tests/ui/search_is_some_fixable_none.rs:78:25 | LL | .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == &cc)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:94:30 + --> tests/ui/search_is_some_fixable_none.rs:95:30 | LL | .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == cc)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:106:17 + --> tests/ui/search_is_some_fixable_none.rs:107:17 | LL | let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.foo == 1 && v.bar == 2)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:110:17 + --> tests/ui/search_is_some_fixable_none.rs:111:17 | LL | let _ = vfoo | _________________^ @@ -162,55 +162,55 @@ LL ~ .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2); | error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:119:17 + --> tests/ui/search_is_some_fixable_none.rs:120:17 | LL | let _ = vfoo.iter().find(|a| a[0] == 42).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|a| a[0] == 42)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:126:17 + --> tests/ui/search_is_some_fixable_none.rs:127:17 | LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:145:17 + --> tests/ui/search_is_some_fixable_none.rs:146:17 | LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:147:17 + --> tests/ui/search_is_some_fixable_none.rs:148:17 | LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![String::from("Hey hey")].iter().any(|s| s.len() == 2)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:151:17 + --> tests/ui/search_is_some_fixable_none.rs:152:17 | LL | let _ = v.iter().find(|x| deref_enough(**x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| deref_enough(*x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:153:17 + --> tests/ui/search_is_some_fixable_none.rs:154:17 | LL | let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| deref_enough(*x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:157:17 + --> tests/ui/search_is_some_fixable_none.rs:158:17 | LL | let _ = v.iter().find(|x| arg_no_deref(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| arg_no_deref(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:160:17 + --> tests/ui/search_is_some_fixable_none.rs:161:17 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| arg_no_deref(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:181:17 + --> tests/ui/search_is_some_fixable_none.rs:182:17 | LL | let _ = vfoo | _________________^ @@ -228,133 +228,133 @@ LL ~ .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] | error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:198:17 + --> tests/ui/search_is_some_fixable_none.rs:199:17 | LL | let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.inner[0].bar == 2)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:204:17 + --> tests/ui/search_is_some_fixable_none.rs:205:17 | LL | let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|x| (**x)[0] == 9)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:218:17 + --> tests/ui/search_is_some_fixable_none.rs:219:17 | LL | let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.by_ref(&v.bar))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:223:17 + --> tests/ui/search_is_some_fixable_none.rs:224:17 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:225:17 + --> tests/ui/search_is_some_fixable_none.rs:226:17 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:245:17 + --> tests/ui/search_is_some_fixable_none.rs:246:17 | LL | let _ = v.iter().find(|s| s[0].is_empty()).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| s[0].is_empty())` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:247:17 + --> tests/ui/search_is_some_fixable_none.rs:248:17 | LL | let _ = v.iter().find(|s| test_string_1(&s[0])).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| test_string_1(&s[0]))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:257:17 + --> tests/ui/search_is_some_fixable_none.rs:258:17 | LL | let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| fp.field.is_power_of_two())` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:259:17 + --> tests/ui/search_is_some_fixable_none.rs:260:17 | LL | let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_1(fp.field))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:261:17 + --> tests/ui/search_is_some_fixable_none.rs:262:17 | LL | let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_2(*fp.field))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:278:17 + --> tests/ui/search_is_some_fixable_none.rs:279:17 | LL | let _ = v.iter().find(|x| **x == 42).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 42)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:280:17 + --> tests/ui/search_is_some_fixable_none.rs:281:17 | LL | Foo.bar(v.iter().find(|x| **x == 42).is_none()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 42)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:286:9 + --> tests/ui/search_is_some_fixable_none.rs:287:9 | LL | v.iter().find(|x| **x == 42).is_none().then(computations); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!v.iter().any(|x| *x == 42))` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_none.rs:292:9 + --> tests/ui/search_is_some_fixable_none.rs:293:9 | LL | v.iter().find(|x| **x == 42).is_none().then_some(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!v.iter().any(|x| *x == 42))` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:298:17 + --> tests/ui/search_is_some_fixable_none.rs:299:17 | LL | let _ = s.find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:300:17 + --> tests/ui/search_is_some_fixable_none.rs:301:17 | LL | Foo.bar(s.find("world").is_none()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:303:17 + --> tests/ui/search_is_some_fixable_none.rs:304:17 | LL | let _ = s.find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:305:17 + --> tests/ui/search_is_some_fixable_none.rs:306:17 | LL | Foo.bar(s.find("world").is_none()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:311:17 + --> tests/ui/search_is_some_fixable_none.rs:312:17 | LL | let _ = s.find("world").is_none().then(computations); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:314:17 + --> tests/ui/search_is_some_fixable_none.rs:315:17 | LL | let _ = s.find("world").is_none().then(computations); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:320:17 + --> tests/ui/search_is_some_fixable_none.rs:321:17 | LL | let _ = s.find("world").is_none().then_some(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` error: called `is_none()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_none.rs:323:17 + --> tests/ui/search_is_some_fixable_none.rs:324:17 | LL | let _ = s.find("world").is_none().then_some(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` diff --git a/tests/ui/search_is_some_fixable_some.fixed b/tests/ui/search_is_some_fixable_some.fixed index 69467796e0c9..6ab0593eecde 100644 --- a/tests/ui/search_is_some_fixable_some.fixed +++ b/tests/ui/search_is_some_fixable_some.fixed @@ -9,7 +9,8 @@ fn main() { let _ = v.iter().any(|x| *x < 0); //~^ search_is_some let _ = (0..1).any(|x| **y == x); // one dereference less - //~^ search_is_some + // + //~^^ search_is_some let _ = (0..1).any(|x| x == 0); //~^ search_is_some let _ = v.iter().any(|x| *x == 0); diff --git a/tests/ui/search_is_some_fixable_some.rs b/tests/ui/search_is_some_fixable_some.rs index 0ca80a563e28..35094cdf2c07 100644 --- a/tests/ui/search_is_some_fixable_some.rs +++ b/tests/ui/search_is_some_fixable_some.rs @@ -9,7 +9,8 @@ fn main() { let _ = v.iter().find(|&x| *x < 0).is_some(); //~^ search_is_some let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less - //~^ search_is_some + // + //~^^ search_is_some let _ = (0..1).find(|x| *x == 0).is_some(); //~^ search_is_some let _ = v.iter().find(|x| **x == 0).is_some(); diff --git a/tests/ui/search_is_some_fixable_some.stderr b/tests/ui/search_is_some_fixable_some.stderr index 3f18b0fdd3c3..af719b78831a 100644 --- a/tests/ui/search_is_some_fixable_some.stderr +++ b/tests/ui/search_is_some_fixable_some.stderr @@ -14,43 +14,43 @@ LL | let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| **y == x)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:13:20 + --> tests/ui/search_is_some_fixable_some.rs:14:20 | LL | let _ = (0..1).find(|x| *x == 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:15:22 + --> tests/ui/search_is_some_fixable_some.rs:16:22 | LL | let _ = v.iter().find(|x| **x == 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| *x == 0)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:17:20 + --> tests/ui/search_is_some_fixable_some.rs:18:20 | LL | let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 1 || x == 3 || x == 5)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:19:20 + --> tests/ui/search_is_some_fixable_some.rs:20:20 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:21:20 + --> tests/ui/search_is_some_fixable_some.rs:22:20 | LL | let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0 || [1, 2, 3].contains(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:23:20 + --> tests/ui/search_is_some_fixable_some.rs:24:20 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:26:10 + --> tests/ui/search_is_some_fixable_some.rs:27:10 | LL | .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1) | __________^ @@ -59,91 +59,91 @@ LL | | .is_some(); | |__________________^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)` error: called `is_some()` after searching an `Iterator` with `position` - --> tests/ui/search_is_some_fixable_some.rs:31:22 + --> tests/ui/search_is_some_fixable_some.rs:32:22 | LL | let _ = v.iter().position(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)` error: called `is_some()` after searching an `Iterator` with `rposition` - --> tests/ui/search_is_some_fixable_some.rs:35:22 + --> tests/ui/search_is_some_fixable_some.rs:36:22 | LL | let _ = v.iter().rposition(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:41:27 + --> tests/ui/search_is_some_fixable_some.rs:42:27 | LL | let _ = "hello world".find("world").is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:43:27 + --> tests/ui/search_is_some_fixable_some.rs:44:27 | LL | let _ = "hello world".find(&s2).is_some(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:45:27 + --> tests/ui/search_is_some_fixable_some.rs:46:27 | LL | let _ = "hello world".find(&s2[2..]).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:48:16 + --> tests/ui/search_is_some_fixable_some.rs:49:16 | LL | let _ = s1.find("world").is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:50:16 + --> tests/ui/search_is_some_fixable_some.rs:51:16 | LL | let _ = s1.find(&s2).is_some(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:52:16 + --> tests/ui/search_is_some_fixable_some.rs:53:16 | LL | let _ = s1.find(&s2[2..]).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:55:21 + --> tests/ui/search_is_some_fixable_some.rs:56:21 | LL | let _ = s1[2..].find("world").is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:57:21 + --> tests/ui/search_is_some_fixable_some.rs:58:21 | LL | let _ = s1[2..].find(&s2).is_some(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)` error: called `is_some()` after calling `find()` on a string - --> tests/ui/search_is_some_fixable_some.rs:59:21 + --> tests/ui/search_is_some_fixable_some.rs:60:21 | LL | let _ = s1[2..].find(&s2[2..]).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:76:44 + --> tests/ui/search_is_some_fixable_some.rs:77:44 | LL | .filter(|c| filter_hand.iter().find(|cc| c == cc).is_some()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == &cc)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:93:49 + --> tests/ui/search_is_some_fixable_some.rs:94:49 | LL | .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_some()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == cc)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:105:29 + --> tests/ui/search_is_some_fixable_some.rs:106:29 | LL | let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.foo == 1 && v.bar == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:111:14 + --> tests/ui/search_is_some_fixable_some.rs:112:14 | LL | .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2) | ______________^ @@ -152,55 +152,55 @@ LL | | .is_some(); | |______________________^ help: consider using: `any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:118:29 + --> tests/ui/search_is_some_fixable_some.rs:119:29 | LL | let _ = vfoo.iter().find(|a| a[0] == 42).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|a| a[0] == 42)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:125:29 + --> tests/ui/search_is_some_fixable_some.rs:126:29 | LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|sub| sub[1..4].len() == 3)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:144:30 + --> tests/ui/search_is_some_fixable_some.rs:145:30 | LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|ppp_x: &&u32| please(ppp_x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:146:50 + --> tests/ui/search_is_some_fixable_some.rs:147:50 | LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s.len() == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:150:26 + --> tests/ui/search_is_some_fixable_some.rs:151:26 | LL | let _ = v.iter().find(|x| deref_enough(**x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| deref_enough(*x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:152:26 + --> tests/ui/search_is_some_fixable_some.rs:153:26 | LL | let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| deref_enough(*x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:156:26 + --> tests/ui/search_is_some_fixable_some.rs:157:26 | LL | let _ = v.iter().find(|x| arg_no_deref(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| arg_no_deref(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:159:26 + --> tests/ui/search_is_some_fixable_some.rs:160:26 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:182:14 + --> tests/ui/search_is_some_fixable_some.rs:183:14 | LL | .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2) | ______________^ @@ -209,85 +209,85 @@ LL | | .is_some(); | |______________________^ help: consider using: `any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:197:29 + --> tests/ui/search_is_some_fixable_some.rs:198:29 | LL | let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.inner[0].bar == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:203:29 + --> tests/ui/search_is_some_fixable_some.rs:204:29 | LL | let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| (**x)[0] == 9)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:217:29 + --> tests/ui/search_is_some_fixable_some.rs:218:29 | LL | let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.by_ref(&v.bar))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:222:55 + --> tests/ui/search_is_some_fixable_some.rs:223:55 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:224:55 + --> tests/ui/search_is_some_fixable_some.rs:225:55 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:244:26 + --> tests/ui/search_is_some_fixable_some.rs:245:26 | LL | let _ = v.iter().find(|s| s[0].is_empty()).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s[0].is_empty())` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:246:26 + --> tests/ui/search_is_some_fixable_some.rs:247:26 | LL | let _ = v.iter().find(|s| test_string_1(&s[0])).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| test_string_1(&s[0]))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:256:26 + --> tests/ui/search_is_some_fixable_some.rs:257:26 | LL | let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| fp.field.is_power_of_two())` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:258:26 + --> tests/ui/search_is_some_fixable_some.rs:259:26 | LL | let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_1(fp.field))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:260:26 + --> tests/ui/search_is_some_fixable_some.rs:261:26 | LL | let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_2(*fp.field))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:276:18 + --> tests/ui/search_is_some_fixable_some.rs:277:18 | LL | v.iter().find(|x: &&u32| func(x)).is_some() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| func(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:286:26 + --> tests/ui/search_is_some_fixable_some.rs:287:26 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref_impl(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_impl(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:290:26 + --> tests/ui/search_is_some_fixable_some.rs:291:26 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref_dyn(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_dyn(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:294:26 + --> tests/ui/search_is_some_fixable_some.rs:295:26 | LL | let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| (*arg_no_deref_dyn)(&x))` diff --git a/tests/ui/single_char_pattern.fixed b/tests/ui/single_char_pattern.fixed index 717779f03ab2..9bf9d6630441 100644 --- a/tests/ui/single_char_pattern.fixed +++ b/tests/ui/single_char_pattern.fixed @@ -73,9 +73,11 @@ fn main() { h.contains("X"); // should not warn x.replace(';', ",").split(','); // issue #2978 - //~^ single_char_pattern + // + //~^^ single_char_pattern x.starts_with('\x03'); // issue #2996 - //~^ single_char_pattern + // + //~^^ single_char_pattern // Issue #3204 const S: &str = "#"; diff --git a/tests/ui/single_char_pattern.rs b/tests/ui/single_char_pattern.rs index 88f6b85f946f..0560a848fe9d 100644 --- a/tests/ui/single_char_pattern.rs +++ b/tests/ui/single_char_pattern.rs @@ -73,9 +73,11 @@ fn main() { h.contains("X"); // should not warn x.replace(';', ",").split(","); // issue #2978 - //~^ single_char_pattern + // + //~^^ single_char_pattern x.starts_with("\x03"); // issue #2996 - //~^ single_char_pattern + // + //~^^ single_char_pattern // Issue #3204 const S: &str = "#"; diff --git a/tests/ui/single_char_pattern.stderr b/tests/ui/single_char_pattern.stderr index 80d9c7b04637..aa4ba28884a8 100644 --- a/tests/ui/single_char_pattern.stderr +++ b/tests/ui/single_char_pattern.stderr @@ -164,49 +164,49 @@ LL | x.replace(';', ",").split(","); // issue #2978 | ^^^ help: consider using a `char`: `','` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:77:19 + --> tests/ui/single_char_pattern.rs:78:19 | LL | x.starts_with("\x03"); // issue #2996 | ^^^^^^ help: consider using a `char`: `'\x03'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:85:13 + --> tests/ui/single_char_pattern.rs:87:13 | LL | x.split(r"a"); | ^^^^ help: consider using a `char`: `'a'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:87:13 + --> tests/ui/single_char_pattern.rs:89:13 | LL | x.split(r#"a"#); | ^^^^^^ help: consider using a `char`: `'a'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:89:13 + --> tests/ui/single_char_pattern.rs:91:13 | LL | x.split(r###"a"###); | ^^^^^^^^^^ help: consider using a `char`: `'a'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:91:13 + --> tests/ui/single_char_pattern.rs:93:13 | LL | x.split(r###"'"###); | ^^^^^^^^^^ help: consider using a `char`: `'\''` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:93:13 + --> tests/ui/single_char_pattern.rs:95:13 | LL | x.split(r###"#"###); | ^^^^^^^^^^ help: consider using a `char`: `'#'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:96:13 + --> tests/ui/single_char_pattern.rs:98:13 | LL | x.split(r#"\"#); | ^^^^^^ help: consider using a `char`: `'\\'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:98:13 + --> tests/ui/single_char_pattern.rs:100:13 | LL | x.split(r"\"); | ^^^^ help: consider using a `char`: `'\\'` diff --git a/tests/ui/single_match.stderr b/tests/ui/single_match.stderr new file mode 100644 index 000000000000..c88296959489 --- /dev/null +++ b/tests/ui/single_match.stderr @@ -0,0 +1,282 @@ +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:15:5 + | +LL | / match x { +LL | | Some(y) => { +LL | | println!("{:?}", y); +LL | | }, +LL | | _ => (), +LL | | }; + | |_____^ + | + = note: `-D clippy::single-match` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::single_match)]` +help: try + | +LL ~ if let Some(y) = x { +LL + println!("{:?}", y); +LL ~ }; + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:33:5 + | +LL | / match z { +LL | | (2..=3, 7..=9) => dummy(), +LL | | _ => {}, +LL | | }; + | |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:63:5 + | +LL | / match x { +LL | | Some(y) => dummy(), +LL | | None => (), +LL | | }; + | |_____^ help: try: `if let Some(y) = x { dummy() }` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:69:5 + | +LL | / match y { +LL | | Ok(y) => dummy(), +LL | | Err(..) => (), +LL | | }; + | |_____^ help: try: `if let Ok(y) = y { dummy() }` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:77:5 + | +LL | / match c { +LL | | Cow::Borrowed(..) => dummy(), +LL | | Cow::Owned(..) => (), +LL | | }; + | |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }` + +error: you seem to be trying to use `match` for an equality check. Consider using `if` + --> tests/ui/single_match.rs:99:5 + | +LL | / match x { +LL | | "test" => println!(), +LL | | _ => (), +LL | | } + | |_____^ help: try: `if x == "test" { println!() }` + +error: you seem to be trying to use `match` for an equality check. Consider using `if` + --> tests/ui/single_match.rs:113:5 + | +LL | / match x { +LL | | Foo::A => println!(), +LL | | _ => (), +LL | | } + | |_____^ help: try: `if x == Foo::A { println!() }` + +error: you seem to be trying to use `match` for an equality check. Consider using `if` + --> tests/ui/single_match.rs:120:5 + | +LL | / match x { +LL | | FOO_C => println!(), +LL | | _ => (), +LL | | } + | |_____^ help: try: `if x == FOO_C { println!() }` + +error: you seem to be trying to use `match` for an equality check. Consider using `if` + --> tests/ui/single_match.rs:126:5 + | +LL | / match &&x { +LL | | Foo::A => println!(), +LL | | _ => (), +LL | | } + | |_____^ help: try: `if x == Foo::A { println!() }` + +error: you seem to be trying to use `match` for an equality check. Consider using `if` + --> tests/ui/single_match.rs:133:5 + | +LL | / match &x { +LL | | Foo::A => println!(), +LL | | _ => (), +LL | | } + | |_____^ help: try: `if x == &Foo::A { println!() }` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:151:5 + | +LL | / match x { +LL | | Bar::A => println!(), +LL | | _ => (), +LL | | } + | |_____^ help: try: `if let Bar::A = x { println!() }` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:160:5 + | +LL | / match x { +LL | | None => println!(), +LL | | _ => (), +LL | | }; + | |_____^ help: try: `if let None = x { println!() }` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:183:5 + | +LL | / match x { +LL | | (Some(_), _) => {}, +LL | | (None, _) => {}, +LL | | } + | |_____^ help: try: `if let (Some(_), _) = x {}` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:190:5 + | +LL | / match x { +LL | | (Some(E::V), _) => todo!(), +LL | | (_, _) => {}, +LL | | } + | |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:197:5 + | +LL | / match (Some(42), Some(E::V), Some(42)) { +LL | | (.., Some(E::V), _) => {}, +LL | | (..) => {}, +LL | | } + | |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:270:5 + | +LL | / match bar { +LL | | Some(v) => unsafe { +LL | | let r = &v as *const i32; +LL | | println!("{}", *r); +LL | | }, +LL | | _ => {}, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:279:5 + | +LL | / match bar { +LL | | #[rustfmt::skip] +LL | | Some(v) => { +LL | | unsafe { +... | +LL | | _ => {}, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { +LL + unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } +LL + } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:360:5 + | +LL | / match Ok::<_, u32>(Some(A)) { +LL | | Ok(Some(A)) => println!(), +LL | | Err(_) | Ok(None | Some(_)) => {}, +LL | | } + | |_____^ help: try: `if let Ok(Some(A)) = Ok::<_, u32>(Some(A)) { println!() }` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match.rs:376:5 + | +LL | / match &Some(A) { +LL | | Some(A | B) => println!(), +LL | | None | Some(_) => {}, +LL | | } + | |_____^ help: try: `if let Some(A | B) = &Some(A) { println!() }` + +error: you seem to be trying to use `match` for an equality check. Consider using `if` + --> tests/ui/single_match.rs:384:5 + | +LL | / match &s[0..3] { +LL | | b"foo" => println!(), +LL | | _ => {}, +LL | | } + | |_____^ help: try: `if &s[0..3] == b"foo" { println!() }` + +error: this pattern is irrefutable, `match` is useless + --> tests/ui/single_match.rs:398:5 + | +LL | / match DATA { +LL | | DATA => println!(), +LL | | _ => {}, +LL | | } + | |_____^ help: try: `println!();` + +error: this pattern is irrefutable, `match` is useless + --> tests/ui/single_match.rs:404:5 + | +LL | / match CONST_I32 { +LL | | CONST_I32 => println!(), +LL | | _ => {}, +LL | | } + | |_____^ help: try: `println!();` + +error: this pattern is irrefutable, `match` is useless + --> tests/ui/single_match.rs:411:5 + | +LL | / match i { +LL | | i => { +LL | | let a = 1; +LL | | let b = 2; +LL | | }, +LL | | _ => {}, +LL | | } + | |_____^ + | +help: try + | +LL ~ { +LL + let a = 1; +LL + let b = 2; +LL + } + | + +error: this pattern is irrefutable, `match` is useless + --> tests/ui/single_match.rs:420:5 + | +LL | / match i { +LL | | i => {}, +LL | | _ => {}, +LL | | } + | |_____^ help: `match` expression can be removed + +error: this pattern is irrefutable, `match` is useless + --> tests/ui/single_match.rs:426:5 + | +LL | / match i { +LL | | i => (), +LL | | _ => (), +LL | | } + | |_____^ help: `match` expression can be removed + +error: this pattern is irrefutable, `match` is useless + --> tests/ui/single_match.rs:432:5 + | +LL | / match CONST_I32 { +LL | | CONST_I32 => println!(), +LL | | _ => {}, +LL | | } + | |_____^ help: try: `println!();` + +error: aborting due to 26 previous errors + diff --git a/tests/ui/single_match_else.stderr b/tests/ui/single_match_else.stderr new file mode 100644 index 000000000000..7d4ba5fb75ef --- /dev/null +++ b/tests/ui/single_match_else.stderr @@ -0,0 +1,211 @@ +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match_else.rs:17:13 + | +LL | let _ = match ExprNode::Butterflies { + | _____________^ +LL | | ExprNode::ExprAddrOf => Some(&NODE), +LL | | _ => { +LL | | let x = 5; +LL | | None +LL | | }, +LL | | }; + | |_____^ + | + = note: `-D clippy::single-match-else` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::single_match_else)]` +help: try + | +LL ~ let _ = if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else { +LL + let x = 5; +LL + None +LL ~ }; + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match_else.rs:83:5 + | +LL | / match Some(1) { +LL | | Some(a) => println!("${:?}", a), +LL | | None => { +LL | | println!("else block"); +LL | | return +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(a) = Some(1) { println!("${:?}", a) } else { +LL + println!("else block"); +LL + return +LL + } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match_else.rs:93:5 + | +LL | / match Some(1) { +LL | | Some(a) => println!("${:?}", a), +LL | | None => { +LL | | println!("else block"); +LL | | return; +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(a) = Some(1) { println!("${:?}", a) } else { +LL + println!("else block"); +LL + return; +LL + } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match_else.rs:104:5 + | +LL | / match Result::::Ok(1) { +LL | | Ok(a) => println!("${:?}", a), +LL | | Err(_) => { +LL | | println!("else block"); +... | +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Ok(a) = Result::::Ok(1) { println!("${:?}", a) } else { +LL + println!("else block"); +LL + return; +LL + } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match_else.rs:114:5 + | +LL | / match Cow::from("moo") { +LL | | Cow::Owned(a) => println!("${:?}", a), +LL | | Cow::Borrowed(_) => { +LL | | println!("else block"); +... | +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Cow::Owned(a) = Cow::from("moo") { println!("${:?}", a) } else { +LL + println!("else block"); +LL + return; +LL + } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match_else.rs:125:5 + | +LL | / match bar { +LL | | Some(v) => unsafe { +LL | | let r = &v as *const i32; +LL | | println!("{}", *r); +... | +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } else { +LL + println!("None1"); +LL + println!("None2"); +LL + } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match_else.rs:137:5 + | +LL | / match bar { +LL | | Some(v) => { +LL | | println!("Some"); +LL | | println!("{v}"); +... | +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { +LL + println!("Some"); +LL + println!("{v}"); +LL + } else { unsafe { +LL + let v = 0; +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match_else.rs:150:5 + | +LL | / match bar { +LL | | Some(v) => unsafe { +LL | | let r = &v as *const i32; +LL | | println!("{}", *r); +... | +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } else { unsafe { +LL + let v = 0; +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> tests/ui/single_match_else.rs:163:5 + | +LL | / match bar { +LL | | #[rustfmt::skip] +LL | | Some(v) => { +LL | | unsafe { +... | +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { +LL + unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } +LL + } else { +LL + println!("None"); +LL + println!("None"); +LL + } + | + +error: this pattern is irrefutable, `match` is useless + --> tests/ui/single_match_else.rs:213:5 + | +LL | / match ExprNode::Butterflies { +LL | | ExprNode::Butterflies => Some(&NODE), +LL | | _ => { +LL | | let x = 5; +LL | | None +LL | | }, +LL | | } + | |_____^ help: try: `Some(&NODE)` + +error: aborting due to 10 previous errors + diff --git a/tests/ui/suspicious_xor_used_as_pow.rs b/tests/ui/suspicious_xor_used_as_pow.rs index e0290b7ce8f1..40a8d8c366ba 100644 --- a/tests/ui/suspicious_xor_used_as_pow.rs +++ b/tests/ui/suspicious_xor_used_as_pow.rs @@ -11,7 +11,8 @@ macro_rules! macro_test { macro_rules! macro_test_inside { () => { 1 ^ 2 // should warn even if inside macro - //~^ suspicious_xor_used_as_pow + // + //~^^ suspicious_xor_used_as_pow }; } diff --git a/tests/ui/suspicious_xor_used_as_pow.stderr b/tests/ui/suspicious_xor_used_as_pow.stderr index d08773a8759a..0913154a26e2 100644 --- a/tests/ui/suspicious_xor_used_as_pow.stderr +++ b/tests/ui/suspicious_xor_used_as_pow.stderr @@ -1,5 +1,5 @@ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:20:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:21:13 | LL | let _ = 2 ^ 5; | ^^^^^ @@ -12,7 +12,7 @@ LL | let _ = 2.pow(5); | ~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:23:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:24:13 | LL | let _ = 2i32 ^ 9i32; | ^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = 2i32.pow(9i32); | ~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:26:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:27:13 | LL | let _ = 2i32 ^ 2i32; | ^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = 2i32.pow(2i32); | ~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:29:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:30:13 | LL | let _ = 50i32 ^ 3i32; | ^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _ = 50i32.pow(3i32); | ~~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:32:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:33:13 | LL | let _ = 5i32 ^ 8i32; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _ = 5i32.pow(8i32); | ~~~~~~~~~~~~~~ error: `^` is not the exponentiation operator - --> tests/ui/suspicious_xor_used_as_pow.rs:35:13 + --> tests/ui/suspicious_xor_used_as_pow.rs:36:13 | LL | let _ = 2i32 ^ 32i32; | ^^^^^^^^^^^^ diff --git a/tests/ui/trim_split_whitespace.fixed b/tests/ui/trim_split_whitespace.fixed index c7c241e3075f..434e91b7d953 100644 --- a/tests/ui/trim_split_whitespace.fixed +++ b/tests/ui/trim_split_whitespace.fixed @@ -59,19 +59,25 @@ impl DerefStrAndCustomTrim { fn main() { // &str let _ = " A B C ".split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace let _ = " A B C ".split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace let _ = " A B C ".split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace // String let _ = (" A B C ").to_string().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace let _ = (" A B C ").to_string().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace let _ = (" A B C ").to_string().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace // Custom let _ = Custom.trim().split_whitespace(); // should not trigger lint @@ -79,7 +85,8 @@ fn main() { // Deref let s = DerefStr(" A B C "); let _ = s.split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace // Deref + custom impl let s = DerefStrAndCustom(" A B C "); @@ -88,7 +95,8 @@ fn main() { // Deref + only custom split_ws() impl let s = DerefStrAndCustomSplit(" A B C "); let _ = s.split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace // Expl: trim() is called on str (deref) and returns &str. // Thus split_ws() is called on str as well and the custom impl on S is unused diff --git a/tests/ui/trim_split_whitespace.rs b/tests/ui/trim_split_whitespace.rs index aa2cd92430ed..b939ecdfba85 100644 --- a/tests/ui/trim_split_whitespace.rs +++ b/tests/ui/trim_split_whitespace.rs @@ -59,19 +59,25 @@ impl DerefStrAndCustomTrim { fn main() { // &str let _ = " A B C ".trim().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace let _ = " A B C ".trim_start().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace let _ = " A B C ".trim_end().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace // String let _ = (" A B C ").to_string().trim().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace let _ = (" A B C ").to_string().trim_start().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace let _ = (" A B C ").to_string().trim_end().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace // Custom let _ = Custom.trim().split_whitespace(); // should not trigger lint @@ -79,7 +85,8 @@ fn main() { // Deref let s = DerefStr(" A B C "); let _ = s.trim().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace // Deref + custom impl let s = DerefStrAndCustom(" A B C "); @@ -88,7 +95,8 @@ fn main() { // Deref + only custom split_ws() impl let s = DerefStrAndCustomSplit(" A B C "); let _ = s.trim().split_whitespace(); // should trigger lint - //~^ trim_split_whitespace + // + //~^^ trim_split_whitespace // Expl: trim() is called on str (deref) and returns &str. // Thus split_ws() is called on str as well and the custom impl on S is unused diff --git a/tests/ui/trim_split_whitespace.stderr b/tests/ui/trim_split_whitespace.stderr index deaec54d9363..f242dd802115 100644 --- a/tests/ui/trim_split_whitespace.stderr +++ b/tests/ui/trim_split_whitespace.stderr @@ -8,43 +8,43 @@ LL | let _ = " A B C ".trim().split_whitespace(); // should trigger lint = help: to override `-D warnings` add `#[allow(clippy::trim_split_whitespace)]` error: found call to `str::trim_start` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:63:23 + --> tests/ui/trim_split_whitespace.rs:64:23 | LL | let _ = " A B C ".trim_start().split_whitespace(); // should trigger lint | ^^^^^^^^^^^^^ help: remove `trim_start()` error: found call to `str::trim_end` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:65:23 + --> tests/ui/trim_split_whitespace.rs:67:23 | LL | let _ = " A B C ".trim_end().split_whitespace(); // should trigger lint | ^^^^^^^^^^^ help: remove `trim_end()` error: found call to `str::trim` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:69:37 + --> tests/ui/trim_split_whitespace.rs:72:37 | LL | let _ = (" A B C ").to_string().trim().split_whitespace(); // should trigger lint | ^^^^^^^ help: remove `trim()` error: found call to `str::trim_start` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:71:37 + --> tests/ui/trim_split_whitespace.rs:75:37 | LL | let _ = (" A B C ").to_string().trim_start().split_whitespace(); // should trigger lint | ^^^^^^^^^^^^^ help: remove `trim_start()` error: found call to `str::trim_end` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:73:37 + --> tests/ui/trim_split_whitespace.rs:78:37 | LL | let _ = (" A B C ").to_string().trim_end().split_whitespace(); // should trigger lint | ^^^^^^^^^^^ help: remove `trim_end()` error: found call to `str::trim` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:81:15 + --> tests/ui/trim_split_whitespace.rs:87:15 | LL | let _ = s.trim().split_whitespace(); // should trigger lint | ^^^^^^^ help: remove `trim()` error: found call to `str::trim` before `str::split_whitespace` - --> tests/ui/trim_split_whitespace.rs:90:15 + --> tests/ui/trim_split_whitespace.rs:97:15 | LL | let _ = s.trim().split_whitespace(); // should trigger lint | ^^^^^^^ help: remove `trim()` diff --git a/tests/ui/uninlined_format_args.fixed b/tests/ui/uninlined_format_args.fixed index 6db094babb24..7b609d9163a9 100644 --- a/tests/ui/uninlined_format_args.fixed +++ b/tests/ui/uninlined_format_args.fixed @@ -45,13 +45,17 @@ fn tester(fn_arg: i32) { println!("val='{local_i32}'"); //~^ uninlined_format_args println!("val='{local_i32}'"); // 3 spaces - //~^ uninlined_format_args + // + //~^^ uninlined_format_args println!("val='{local_i32}'"); // tab - //~^ uninlined_format_args + // + //~^^ uninlined_format_args println!("val='{local_i32}'"); // space+tab - //~^ uninlined_format_args + // + //~^^ uninlined_format_args println!("val='{local_i32}'"); // tab+space - //~^ uninlined_format_args + // + //~^^ uninlined_format_args println!( //~^ uninlined_format_args "val='{local_i32}'" diff --git a/tests/ui/uninlined_format_args.rs b/tests/ui/uninlined_format_args.rs index 7ca61b800219..14e0b6caabc0 100644 --- a/tests/ui/uninlined_format_args.rs +++ b/tests/ui/uninlined_format_args.rs @@ -45,13 +45,17 @@ fn tester(fn_arg: i32) { println!("val='{}'", local_i32); //~^ uninlined_format_args println!("val='{ }'", local_i32); // 3 spaces - //~^ uninlined_format_args + // + //~^^ uninlined_format_args println!("val='{ }'", local_i32); // tab - //~^ uninlined_format_args + // + //~^^ uninlined_format_args println!("val='{ }'", local_i32); // space+tab - //~^ uninlined_format_args + // + //~^^ uninlined_format_args println!("val='{ }'", local_i32); // tab+space - //~^ uninlined_format_args + // + //~^^ uninlined_format_args println!( //~^ uninlined_format_args "val='{ diff --git a/tests/ui/uninlined_format_args.stderr b/tests/ui/uninlined_format_args.stderr index df688bc757c7..7e62a095eadf 100644 --- a/tests/ui/uninlined_format_args.stderr +++ b/tests/ui/uninlined_format_args.stderr @@ -25,7 +25,7 @@ LL + println!("val='{local_i32}'"); // 3 spaces | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:49:5 + --> tests/ui/uninlined_format_args.rs:50:5 | LL | println!("val='{ }'", local_i32); // tab | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + println!("val='{local_i32}'"); // tab | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:51:5 + --> tests/ui/uninlined_format_args.rs:53:5 | LL | println!("val='{ }'", local_i32); // space+tab | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + println!("val='{local_i32}'"); // space+tab | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:53:5 + --> tests/ui/uninlined_format_args.rs:56:5 | LL | println!("val='{ }'", local_i32); // tab+space | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + println!("val='{local_i32}'"); // tab+space | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:55:5 + --> tests/ui/uninlined_format_args.rs:59:5 | LL | / println!( LL | | @@ -72,7 +72,7 @@ LL | | ); | |_____^ error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:61:5 + --> tests/ui/uninlined_format_args.rs:65:5 | LL | println!("{}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL + println!("{local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:63:5 + --> tests/ui/uninlined_format_args.rs:67:5 | LL | println!("{}", fn_arg); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL + println!("{fn_arg}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:65:5 + --> tests/ui/uninlined_format_args.rs:69:5 | LL | println!("{:?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL + println!("{local_i32:?}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:67:5 + --> tests/ui/uninlined_format_args.rs:71:5 | LL | println!("{:#?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL + println!("{local_i32:#?}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:69:5 + --> tests/ui/uninlined_format_args.rs:73:5 | LL | println!("{:4}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL + println!("{local_i32:4}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:71:5 + --> tests/ui/uninlined_format_args.rs:75:5 | LL | println!("{:04}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL + println!("{local_i32:04}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:73:5 + --> tests/ui/uninlined_format_args.rs:77:5 | LL | println!("{:<3}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL + println!("{local_i32:<3}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:75:5 + --> tests/ui/uninlined_format_args.rs:79:5 | LL | println!("{:#010x}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -168,7 +168,7 @@ LL + println!("{local_i32:#010x}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:77:5 + --> tests/ui/uninlined_format_args.rs:81:5 | LL | println!("{:.1}", local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -180,7 +180,7 @@ LL + println!("{local_f64:.1}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:82:5 + --> tests/ui/uninlined_format_args.rs:86:5 | LL | println!("{} {}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -192,7 +192,7 @@ LL + println!("{local_i32} {local_f64}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:85:5 + --> tests/ui/uninlined_format_args.rs:89:5 | LL | println!("{}", val); | ^^^^^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL + println!("{val}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:87:5 + --> tests/ui/uninlined_format_args.rs:91:5 | LL | println!("{}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -216,7 +216,7 @@ LL + println!("{val}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:90:5 + --> tests/ui/uninlined_format_args.rs:94:5 | LL | println!("val='{\t }'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -228,7 +228,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:92:5 + --> tests/ui/uninlined_format_args.rs:96:5 | LL | println!("val='{\n }'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -240,7 +240,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:94:5 + --> tests/ui/uninlined_format_args.rs:98:5 | LL | println!("val='{local_i32}'", local_i32 = local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -252,7 +252,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:96:5 + --> tests/ui/uninlined_format_args.rs:100:5 | LL | println!("val='{local_i32}'", local_i32 = fn_arg); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -264,7 +264,7 @@ LL + println!("val='{fn_arg}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:98:5 + --> tests/ui/uninlined_format_args.rs:102:5 | LL | println!("{0}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -276,7 +276,7 @@ LL + println!("{local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:100:5 + --> tests/ui/uninlined_format_args.rs:104:5 | LL | println!("{0:?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -288,7 +288,7 @@ LL + println!("{local_i32:?}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:102:5 + --> tests/ui/uninlined_format_args.rs:106:5 | LL | println!("{0:#?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -300,7 +300,7 @@ LL + println!("{local_i32:#?}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:104:5 + --> tests/ui/uninlined_format_args.rs:108:5 | LL | println!("{0:04}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -312,7 +312,7 @@ LL + println!("{local_i32:04}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:106:5 + --> tests/ui/uninlined_format_args.rs:110:5 | LL | println!("{0:<3}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -324,7 +324,7 @@ LL + println!("{local_i32:<3}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:108:5 + --> tests/ui/uninlined_format_args.rs:112:5 | LL | println!("{0:#010x}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,7 +336,7 @@ LL + println!("{local_i32:#010x}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:110:5 + --> tests/ui/uninlined_format_args.rs:114:5 | LL | println!("{0:.1}", local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -348,7 +348,7 @@ LL + println!("{local_f64:.1}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:112:5 + --> tests/ui/uninlined_format_args.rs:116:5 | LL | println!("{0} {0}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -360,7 +360,7 @@ LL + println!("{local_i32} {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:114:5 + --> tests/ui/uninlined_format_args.rs:118:5 | LL | println!("{1} {} {0} {}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -372,7 +372,7 @@ LL + println!("{local_f64} {local_i32} {local_i32} {local_f64}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:116:5 + --> tests/ui/uninlined_format_args.rs:120:5 | LL | println!("{0} {1}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -384,7 +384,7 @@ LL + println!("{local_i32} {local_f64}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:118:5 + --> tests/ui/uninlined_format_args.rs:122:5 | LL | println!("{1} {0}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -396,7 +396,7 @@ LL + println!("{local_f64} {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:120:5 + --> tests/ui/uninlined_format_args.rs:124:5 | LL | println!("{1} {0} {1} {0}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -408,7 +408,7 @@ LL + println!("{local_f64} {local_i32} {local_f64} {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:123:5 + --> tests/ui/uninlined_format_args.rs:127:5 | LL | println!("{v}", v = local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -420,7 +420,7 @@ LL + println!("{local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:125:5 + --> tests/ui/uninlined_format_args.rs:129:5 | LL | println!("{local_i32:0$}", width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -432,7 +432,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:127:5 + --> tests/ui/uninlined_format_args.rs:131:5 | LL | println!("{local_i32:w$}", w = width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -444,7 +444,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:129:5 + --> tests/ui/uninlined_format_args.rs:133:5 | LL | println!("{local_i32:.0$}", prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -456,7 +456,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:131:5 + --> tests/ui/uninlined_format_args.rs:135:5 | LL | println!("{local_i32:.p$}", p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -468,7 +468,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:133:5 + --> tests/ui/uninlined_format_args.rs:137:5 | LL | println!("{:0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -480,7 +480,7 @@ LL + println!("{val:val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:135:5 + --> tests/ui/uninlined_format_args.rs:139:5 | LL | println!("{0:0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -492,7 +492,7 @@ LL + println!("{val:val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:137:5 + --> tests/ui/uninlined_format_args.rs:141:5 | LL | println!("{:0$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -504,7 +504,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:139:5 + --> tests/ui/uninlined_format_args.rs:143:5 | LL | println!("{0:0$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -516,7 +516,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:141:5 + --> tests/ui/uninlined_format_args.rs:145:5 | LL | println!("{0:0$.v$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -528,7 +528,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:143:5 + --> tests/ui/uninlined_format_args.rs:147:5 | LL | println!("{0:v$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -540,7 +540,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:145:5 + --> tests/ui/uninlined_format_args.rs:149:5 | LL | println!("{v:0$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -552,7 +552,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:147:5 + --> tests/ui/uninlined_format_args.rs:151:5 | LL | println!("{v:v$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -564,7 +564,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:149:5 + --> tests/ui/uninlined_format_args.rs:153:5 | LL | println!("{v:0$.v$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -576,7 +576,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:151:5 + --> tests/ui/uninlined_format_args.rs:155:5 | LL | println!("{v:v$.v$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -588,7 +588,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:153:5 + --> tests/ui/uninlined_format_args.rs:157:5 | LL | println!("{:0$}", width); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -600,7 +600,7 @@ LL + println!("{width:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:155:5 + --> tests/ui/uninlined_format_args.rs:159:5 | LL | println!("{:1$}", local_i32, width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -612,7 +612,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:157:5 + --> tests/ui/uninlined_format_args.rs:161:5 | LL | println!("{:w$}", w = width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -624,7 +624,7 @@ LL + println!("{width:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:159:5 + --> tests/ui/uninlined_format_args.rs:163:5 | LL | println!("{:w$}", local_i32, w = width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -636,7 +636,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:161:5 + --> tests/ui/uninlined_format_args.rs:165:5 | LL | println!("{:.0$}", prec); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -648,7 +648,7 @@ LL + println!("{prec:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:163:5 + --> tests/ui/uninlined_format_args.rs:167:5 | LL | println!("{:.1$}", local_i32, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -660,7 +660,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:165:5 + --> tests/ui/uninlined_format_args.rs:169:5 | LL | println!("{:.p$}", p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -672,7 +672,7 @@ LL + println!("{prec:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:167:5 + --> tests/ui/uninlined_format_args.rs:171:5 | LL | println!("{:.p$}", local_i32, p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -684,7 +684,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:169:5 + --> tests/ui/uninlined_format_args.rs:173:5 | LL | println!("{:0$.1$}", width, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -696,7 +696,7 @@ LL + println!("{width:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:171:5 + --> tests/ui/uninlined_format_args.rs:175:5 | LL | println!("{:0$.w$}", width, w = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -708,7 +708,7 @@ LL + println!("{width:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:173:5 + --> tests/ui/uninlined_format_args.rs:177:5 | LL | println!("{:1$.2$}", local_f64, width, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ LL + println!("{local_f64:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:175:5 + --> tests/ui/uninlined_format_args.rs:179:5 | LL | println!("{:1$.2$} {0} {1} {2}", local_f64, width, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -732,7 +732,7 @@ LL + println!("{local_f64:width$.prec$} {local_f64} {width} {prec}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:177:5 + --> tests/ui/uninlined_format_args.rs:181:5 | LL | / println!( LL | | @@ -742,7 +742,7 @@ LL | | ); | |_____^ error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:189:5 + --> tests/ui/uninlined_format_args.rs:193:5 | LL | println!("Width = {}, value with width = {:0$}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -754,7 +754,7 @@ LL + println!("Width = {local_i32}, value with width = {local_f64:local_i32$ | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:191:5 + --> tests/ui/uninlined_format_args.rs:195:5 | LL | println!("{:w$.p$}", local_i32, w = width, p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -766,7 +766,7 @@ LL + println!("{local_i32:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:193:5 + --> tests/ui/uninlined_format_args.rs:197:5 | LL | println!("{:w$.p$}", w = width, p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -778,7 +778,7 @@ LL + println!("{width:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:213:5 + --> tests/ui/uninlined_format_args.rs:217:5 | LL | / println!( LL | | @@ -788,7 +788,7 @@ LL | | ); | |_____^ error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:219:5 + --> tests/ui/uninlined_format_args.rs:223:5 | LL | println!("{}", /* comment with a comma , in it */ val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -800,7 +800,7 @@ LL + println!("{val}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:226:9 + --> tests/ui/uninlined_format_args.rs:230:9 | LL | panic!("p1 {}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -812,7 +812,7 @@ LL + panic!("p1 {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:230:9 + --> tests/ui/uninlined_format_args.rs:234:9 | LL | panic!("p2 {0}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -824,7 +824,7 @@ LL + panic!("p2 {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:234:9 + --> tests/ui/uninlined_format_args.rs:238:9 | LL | panic!("p3 {local_i32}", local_i32 = local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -836,7 +836,7 @@ LL + panic!("p3 {local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:255:5 + --> tests/ui/uninlined_format_args.rs:259:5 | LL | println!("expand='{}'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -848,7 +848,7 @@ LL + println!("expand='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:358:5 + --> tests/ui/uninlined_format_args.rs:362:5 | LL | usr_println!(true, "val='{}'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -860,7 +860,7 @@ LL + usr_println!(true, "val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:360:5 + --> tests/ui/uninlined_format_args.rs:364:5 | LL | usr_println!(true, "{}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -872,7 +872,7 @@ LL + usr_println!(true, "{local_i32}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:362:5 + --> tests/ui/uninlined_format_args.rs:366:5 | LL | usr_println!(true, "{:#010x}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -884,7 +884,7 @@ LL + usr_println!(true, "{local_i32:#010x}"); | error: variables can be used directly in the `format!` string - --> tests/ui/uninlined_format_args.rs:364:5 + --> tests/ui/uninlined_format_args.rs:368:5 | LL | usr_println!(true, "{:.1}", local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_cast.fixed b/tests/ui/unnecessary_cast.fixed index abaab6aa9a05..ba167e79a308 100644 --- a/tests/ui/unnecessary_cast.fixed +++ b/tests/ui/unnecessary_cast.fixed @@ -246,7 +246,8 @@ mod fixable { //~^ unnecessary_cast #[allow(ambiguous_negative_literals)] let _: f64 = -8.0_f64.exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior - //~^ unnecessary_cast + // + //~^^ unnecessary_cast } fn issue_9562_non_literal() { diff --git a/tests/ui/unnecessary_cast.rs b/tests/ui/unnecessary_cast.rs index 8f2493def09a..0f90a8b05965 100644 --- a/tests/ui/unnecessary_cast.rs +++ b/tests/ui/unnecessary_cast.rs @@ -246,7 +246,8 @@ mod fixable { //~^ unnecessary_cast #[allow(ambiguous_negative_literals)] let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior - //~^ unnecessary_cast + // + //~^^ unnecessary_cast } fn issue_9562_non_literal() { diff --git a/tests/ui/unnecessary_cast.stderr b/tests/ui/unnecessary_cast.stderr index 3b8f5d0c5fd1..c83770c1a299 100644 --- a/tests/ui/unnecessary_cast.stderr +++ b/tests/ui/unnecessary_cast.stderr @@ -236,13 +236,13 @@ LL | let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp() | ^^^^^^^^^^^^ help: try: `8.0_f64` error: casting to the same type is unnecessary (`f32` -> `f32`) - --> tests/ui/unnecessary_cast.rs:257:20 + --> tests/ui/unnecessary_cast.rs:258:20 | LL | let _num = foo() as f32; | ^^^^^^^^^^^^ help: try: `foo()` error: casting to the same type is unnecessary (`usize` -> `usize`) - --> tests/ui/unnecessary_cast.rs:268:9 + --> tests/ui/unnecessary_cast.rs:269:9 | LL | (*x as usize).pow(2) | ^^^^^^^^^^^^^ help: try: `{ *x }` diff --git a/tests/ui/unnecessary_literal_unwrap.fixed b/tests/ui/unnecessary_literal_unwrap.fixed index e999dc3ade7f..877f4ad41c7e 100644 --- a/tests/ui/unnecessary_literal_unwrap.fixed +++ b/tests/ui/unnecessary_literal_unwrap.fixed @@ -138,7 +138,8 @@ fn unwrap_unchecked() { let _ = 1; //~^ unnecessary_literal_unwrap let _ = unsafe { 1 + *(&1 as *const i32) }; // needs to keep the unsafe block - //~^ unnecessary_literal_unwrap + // + //~^^ unnecessary_literal_unwrap let _ = 1 + 1; //~^ unnecessary_literal_unwrap let _ = 1; diff --git a/tests/ui/unnecessary_literal_unwrap.rs b/tests/ui/unnecessary_literal_unwrap.rs index 1f47d3898bbb..c0a35ae78a71 100644 --- a/tests/ui/unnecessary_literal_unwrap.rs +++ b/tests/ui/unnecessary_literal_unwrap.rs @@ -138,7 +138,8 @@ fn unwrap_unchecked() { let _ = unsafe { Some(1).unwrap_unchecked() }; //~^ unnecessary_literal_unwrap let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block - //~^ unnecessary_literal_unwrap + // + //~^^ unnecessary_literal_unwrap let _ = unsafe { Some(1).unwrap_unchecked() } + 1; //~^ unnecessary_literal_unwrap let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() }; diff --git a/tests/ui/unnecessary_literal_unwrap.stderr b/tests/ui/unnecessary_literal_unwrap.stderr index f4880637375a..7d6e096a1c93 100644 --- a/tests/ui/unnecessary_literal_unwrap.stderr +++ b/tests/ui/unnecessary_literal_unwrap.stderr @@ -543,7 +543,7 @@ LL + let _ = unsafe { 1 + *(&1 as *const i32) }; // needs to keep the unsafe | error: used `unwrap_unchecked()` on `Some` value - --> tests/ui/unnecessary_literal_unwrap.rs:142:22 + --> tests/ui/unnecessary_literal_unwrap.rs:143:22 | LL | let _ = unsafe { Some(1).unwrap_unchecked() } + 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -555,7 +555,7 @@ LL + let _ = 1 + 1; | error: used `unwrap_unchecked()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:144:22 + --> tests/ui/unnecessary_literal_unwrap.rs:145:22 | LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -567,7 +567,7 @@ LL + let _ = 1; | error: used `unwrap_unchecked()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:146:22 + --> tests/ui/unnecessary_literal_unwrap.rs:147:22 | LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -579,7 +579,7 @@ LL + let _ = unsafe { 1 + *(&1 as *const i32) }; | error: used `unwrap_unchecked()` on `Ok` value - --> tests/ui/unnecessary_literal_unwrap.rs:148:22 + --> tests/ui/unnecessary_literal_unwrap.rs:149:22 | LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -591,7 +591,7 @@ LL + let _ = 1 + 1; | error: used `unwrap_err_unchecked()` on `Err` value - --> tests/ui/unnecessary_literal_unwrap.rs:150:22 + --> tests/ui/unnecessary_literal_unwrap.rs:151:22 | LL | let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/use_self_trait.fixed b/tests/ui/use_self_trait.fixed index 820282d8da54..c5d800dc94e1 100644 --- a/tests/ui/use_self_trait.fixed +++ b/tests/ui/use_self_trait.fixed @@ -158,7 +158,8 @@ mod full_path_replacement { impl Error for std::fmt::Error { fn custom(_msg: T) -> Self { Self // Should lint - //~^ use_self + // + //~^^ use_self } } } diff --git a/tests/ui/use_self_trait.rs b/tests/ui/use_self_trait.rs index aa9761e5609f..dcf5820afc26 100644 --- a/tests/ui/use_self_trait.rs +++ b/tests/ui/use_self_trait.rs @@ -158,7 +158,8 @@ mod full_path_replacement { impl Error for std::fmt::Error { fn custom(_msg: T) -> Self { std::fmt::Error // Should lint - //~^ use_self + // + //~^^ use_self } } } From 3053bad40af1022b1f16d2778612dfeeef73e362 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 13 Feb 2025 12:58:03 +0100 Subject: [PATCH 122/991] Update ui-toml tests --- .../absolute_paths_2015.default.stderr | 14 --- .../absolute_paths/absolute_paths_2015.rs | 5 +- .../uninlined_format_args.fixed | 6 ++ .../uninlined_format_args.rs | 6 ++ .../uninlined_format_args.stderr | 10 +- .../ordering_good.rs | 5 + .../ordering_good_var_1.rs | 1 + .../ordering_mixed.default.stderr | 67 +++++++------ .../ordering_mixed.rs | 17 ++++ .../ordering_mixed_var_1.rs | 8 ++ .../ordering_mixed_var_1.var_1.stderr | 28 +++--- .../ordering_only_enum.rs | 1 + .../ordering_only_impl.only_impl.stderr | 6 +- .../ordering_only_impl.rs | 3 + .../ordering_only_trait.only_trait.stderr | 8 +- .../ordering_only_trait.rs | 3 + .../arithmetic_side_effects_allowed.rs | 9 ++ .../arithmetic_side_effects_allowed.stderr | 16 ++-- .../array_size_threshold.rs | 2 + .../array_size_threshold.stderr | 2 +- .../await_holding_invalid_type.rs | 3 + .../await_holding_invalid_type.stderr | 4 +- .../await_holding_invalid_type.rs | 1 + .../borrow_interior_mutable_const/ignore.rs | 1 + .../conf_deprecated_key.rs | 1 + tests/ui-toml/dbg_macro/dbg_macro.fixed | 7 ++ tests/ui-toml/dbg_macro/dbg_macro.rs | 7 ++ tests/ui-toml/dbg_macro/dbg_macro.stderr | 12 +-- .../declare_interior_mutable_const/ignore.rs | 1 + .../disallowed_macros/disallowed_macros.rs | 16 ++++ .../disallowed_macros.stderr | 31 +++--- .../disallowed_names.rs | 2 + .../disallowed_names.stderr | 2 +- .../disallowed_names.rs | 1 + .../doc_markdown.fixed | 1 + .../doc_valid_idents_append/doc_markdown.rs | 1 + .../doc_markdown.fixed | 3 + .../doc_valid_idents_replace/doc_markdown.rs | 3 + .../doc_markdown.stderr | 2 +- .../duplicated_keys.rs | 1 + .../duplicated_keys.rs | 1 + .../excessive_nesting/excessive_nesting.rs | 37 ++++++++ .../excessive_nesting.stderr | 77 ++++++++------- tests/ui-toml/expect_used/expect_used.rs | 6 +- tests/ui-toml/expect_used/expect_used.stderr | 6 +- .../extra_unused_type_parameters.rs | 1 + .../ui-toml/fn_params_excessive_bools/test.rs | 1 + tests/ui-toml/functions_maxlines/test.rs | 4 + tests/ui-toml/functions_maxlines/test.stderr | 10 +- .../conf_no_false_negatives.rs | 1 + tests/ui-toml/ifs_same_cond/ifs_same_cond.rs | 1 + .../indexing_slicing/indexing_slicing.rs | 1 + .../allowed_prefixes/item_name_repetitions.rs | 1 + .../item_name_repetitions.rs | 1 + .../threshold0/item_name_repetitions.rs | 2 + .../ui-toml/large_futures/large_futures.fixed | 1 + tests/ui-toml/large_futures/large_futures.rs | 1 + .../large_include_file/large_include_file.rs | 2 +- .../lint_decimal_readability/test.fixed | 2 + .../ui-toml/lint_decimal_readability/test.rs | 2 + .../lint_decimal_readability/test.stderr | 2 +- .../macro_metavars_in_unsafe/default/test.rs | 29 +++--- .../min_ident_chars/min_ident_chars.rs | 8 ++ .../min_ident_chars/min_ident_chars.stderr | 14 +-- .../min_rust_version/min_rust_version.fixed | 1 + .../min_rust_version/min_rust_version.rs | 1 + .../conf_missing_enforced_import_rename.fixed | 6 ++ .../conf_missing_enforced_import_rename.rs | 6 ++ ...conf_missing_enforced_import_rename.stderr | 10 +- .../module_inception/module_inception.rs | 2 + .../module_inception/module_inception.stderr | 4 +- .../modulo_arithmetic/modulo_arithmetic.rs | 4 + .../modulo_arithmetic.stderr | 6 +- tests/ui-toml/mut_key/mut_key.rs | 1 + .../needless_raw_string_hashes.fixed | 3 + .../needless_raw_string_hashes.rs | 3 + .../needless_raw_string_hashes.stderr | 4 +- .../conf_nonstandard_macro_braces.fixed | 8 ++ .../conf_nonstandard_macro_braces.rs | 8 ++ .../conf_nonstandard_macro_braces.stderr | 14 +-- tests/ui-toml/panic/panic.rs | 2 + tests/ui-toml/panic/panic.stderr | 2 +- .../path_ends_with_ext/path_ends_with_ext.rs | 2 + tests/ui-toml/print_macro/print_macro.rs | 2 + tests/ui-toml/print_macro/print_macro.stderr | 2 +- .../pub_crate_missing_doc.rs | 7 ++ .../pub_crate_missing_doc.stderr | 14 +-- ...ub_underscore_fields.all_pub_fields.stderr | 12 +-- .../pub_underscore_fields.rs | 7 ++ .../renamed_function_params.default.stderr | 6 +- .../renamed_function_params.extend.stderr | 4 +- .../renamed_function_params.rs | 11 ++- .../replaceable_disallowed_types.fixed | 1 + .../replaceable_disallowed_types.rs | 1 + tests/ui-toml/semicolon_block/both.fixed | 4 + tests/ui-toml/semicolon_block/both.rs | 4 + tests/ui-toml/semicolon_block/both.stderr | 7 +- .../semicolon_inside_block.fixed | 1 + .../semicolon_block/semicolon_inside_block.rs | 1 + .../semicolon_inside_block.stderr | 1 + .../semicolon_outside_block.fixed | 3 + .../semicolon_outside_block.rs | 3 + .../semicolon_outside_block.stderr | 4 +- .../strict_non_send_fields_in_send_ty/test.rs | 4 + .../test.stderr | 24 ++--- tests/ui-toml/struct_excessive_bools/test.rs | 1 + .../struct_excessive_bools/test.stderr | 1 + tests/ui-toml/suppress_lint_in_const/test.rs | 6 ++ .../suppress_lint_in_const/test.stderr | 10 +- .../conf_french_disallowed_name.rs | 7 ++ .../conf_french_disallowed_name.stderr | 12 +-- .../conf_disallowed_methods.rs | 14 +++ .../conf_disallowed_methods.stderr | 26 ++--- .../conf_disallowed_types.rs | 21 ++++ .../conf_disallowed_types.stderr | 40 ++++---- ...conf_inconsistent_struct_constructor.fixed | 5 + .../conf_inconsistent_struct_constructor.rs | 5 + ...onf_inconsistent_struct_constructor.stderr | 16 +++- .../replaceable_disallowed_methods.fixed | 2 + .../replaceable_disallowed_methods.rs | 2 + .../replaceable_disallowed_methods.stderr | 2 +- tests/ui-toml/toml_trivially_copy/test.rs | 2 + .../toml_unknown_key/conf_unknown_key.rs | 4 +- .../undocumented_unsafe_blocks.default.stderr | 75 ++++++++------- ...undocumented_unsafe_blocks.disabled.stderr | 95 +++++++++---------- .../undocumented_unsafe_blocks.rs | 46 +++++++++ tests/ui-toml/unwrap_used/unwrap_used.fixed | 28 ++++++ tests/ui-toml/unwrap_used/unwrap_used.rs | 28 ++++++ tests/ui-toml/unwrap_used/unwrap_used.stderr | 52 +++++----- .../upper_case_acronyms.fixed | 13 +++ .../upper_case_acronyms.rs | 13 +++ .../upper_case_acronyms.stderr | 24 ++--- tests/ui-toml/useless_vec/useless_vec.fixed | 1 + tests/ui-toml/useless_vec/useless_vec.rs | 1 + tests/ui-toml/vec_box_sized/test.fixed | 3 + tests/ui-toml/vec_box_sized/test.rs | 3 + tests/ui-toml/vec_box_sized/test.stderr | 4 +- .../zero_single_char_names.rs | 1 + 138 files changed, 888 insertions(+), 413 deletions(-) delete mode 100644 tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr diff --git a/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr b/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr deleted file mode 100644 index 6fc495f01808..000000000000 --- a/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:15:13 - | -LL | let _ = ::m1::m2::X; - | ^^^^^^^^^^^ - | -note: the lint level is defined here - --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:6:9 - | -LL | #![deny(clippy::absolute_paths)] - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui-toml/absolute_paths/absolute_paths_2015.rs b/tests/ui-toml/absolute_paths/absolute_paths_2015.rs index 033c47809191..ea556b7e437d 100644 --- a/tests/ui-toml/absolute_paths/absolute_paths_2015.rs +++ b/tests/ui-toml/absolute_paths/absolute_paths_2015.rs @@ -2,6 +2,7 @@ //@[default]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default //@[allow_crates]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates //@edition:2015 +//@check-pass #![deny(clippy::absolute_paths)] @@ -11,6 +12,4 @@ mod m1 { } } -fn main() { - let _ = ::m1::m2::X; //~[default] absolute_paths -} +fn main() {} diff --git a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed index c04543da94b9..e12a94a4b205 100644 --- a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed +++ b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed @@ -7,8 +7,14 @@ fn main() { let local_opt: Option = Some(3); println!("val='{local_i32}'"); + //~^ uninlined_format_args println!("Hello x is {local_f64:.local_i32$}"); + //~^ uninlined_format_args + //~| print_literal println!("Hello {local_i32} is {local_f64:.*}", 5); + //~^ uninlined_format_args println!("Hello {local_i32} is {local_f64:.*}", 5); + //~^ uninlined_format_args println!("{local_i32}, {}", local_opt.unwrap()); + //~^ uninlined_format_args } diff --git a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs index 813830d80b83..ad5aec133e91 100644 --- a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs +++ b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs @@ -7,8 +7,14 @@ fn main() { let local_opt: Option = Some(3); println!("val='{}'", local_i32); + //~^ uninlined_format_args println!("Hello {} is {:.*}", "x", local_i32, local_f64); + //~^ uninlined_format_args + //~| print_literal println!("Hello {} is {:.*}", local_i32, 5, local_f64); + //~^ uninlined_format_args println!("Hello {} is {2:.*}", local_i32, 5, local_f64); + //~^ uninlined_format_args println!("{}, {}", local_i32, local_opt.unwrap()); + //~^ uninlined_format_args } diff --git a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr index 73ef620bd12e..3ffe61b8ed72 100644 --- a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr +++ b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr @@ -13,7 +13,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:10:5 + --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:11:5 | LL | println!("Hello {} is {:.*}", "x", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + println!("Hello {} is {local_f64:.local_i32$}", "x"); | error: literal with an empty format string - --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:10:35 + --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:11:35 | LL | println!("Hello {} is {:.*}", "x", local_i32, local_f64); | ^^^ @@ -39,7 +39,7 @@ LL + println!("Hello x is {:.*}", local_i32, local_f64); | error: variables can be used directly in the `format!` string - --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:11:5 + --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:14:5 | LL | println!("Hello {} is {:.*}", local_i32, 5, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL + println!("Hello {local_i32} is {local_f64:.*}", 5); | error: variables can be used directly in the `format!` string - --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:12:5 + --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:16:5 | LL | println!("Hello {} is {2:.*}", local_i32, 5, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -63,7 +63,7 @@ LL + println!("Hello {local_i32} is {local_f64:.*}", 5); | error: variables can be used directly in the `format!` string - --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:13:5 + --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:18:5 | LL | println!("{}, {}", local_i32, local_opt.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs index e9bcc30c15e0..05eb40506db4 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs @@ -5,6 +5,11 @@ //@[bad_conf_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1 //@[bad_conf_2] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2 //@[bad_conf_3] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3 +//@[default] check-pass +//@[default_exp] check-pass +//@[bad_conf_1] error-in-other-file: +//@[bad_conf_2] error-in-other-file: +//@[bad_conf_3] error-in-other-file: #![allow(dead_code)] #![warn(clippy::arbitrary_source_item_ordering)] diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_good_var_1.rs b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good_var_1.rs index 0fccbd4790bc..fb2d2e64bcea 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_good_var_1.rs +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good_var_1.rs @@ -1,6 +1,7 @@ //@aux-build:../../ui/auxiliary/proc_macros.rs //@revisions: var_1 //@[var_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/var_1 +//@check-pass #![allow(dead_code)] #![warn(clippy::arbitrary_source_item_ordering)] diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr index ee2868869deb..3605952bddc9 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr @@ -1,11 +1,11 @@ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:21:14 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:22:14 | LL | use std::rc::Weak; | ^^^^ | note: should be placed before `SNAKE_CASE` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:19:7 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:20:7 | LL | const SNAKE_CASE: &str = "zzzzzzzz"; | ^^^^^^^^^^ @@ -13,18 +13,18 @@ LL | const SNAKE_CASE: &str = "zzzzzzzz"; = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]` error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:64:1 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:67:1 | LL | / impl CloneSelf for StructOrdered { +LL | | LL | | fn clone_self(&self) -> Self { LL | | Self { -LL | | a: true, ... | LL | | } | |_^ | note: should be placed before the following item - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:54:1 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:57:1 | LL | / impl Default for StructOrdered { LL | | fn default() -> Self { @@ -35,55 +35,54 @@ LL | | } | |_^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:136:7 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:145:7 | LL | const ZIS_SHOULD_BE_REALLY_EARLY: () = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: should be placed before `TraitUnorderedItemKinds` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:124:7 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:132:7 | LL | trait TraitUnorderedItemKinds { | ^^^^^^^^^^^^^^^^^^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:151:1 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:163:1 | LL | impl BasicEmptyTrait for StructOrdered {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: should be placed before the following item - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:138:1 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:148:1 | LL | / impl TraitUnordered for StructUnordered { LL | | const A: bool = false; LL | | const C: bool = false; LL | | const B: bool = false; ... | -LL | | fn b() {} LL | | } | |_^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:170:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:184:5 | LL | mod this_is_in_the_wrong_position { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: should be placed before `main` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:165:4 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:179:4 | LL | fn main() { | ^^^^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:178:7 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:194:7 | LL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: should be placed before `ZisShouldBeBeforeZeMainFn` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:176:8 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:192:8 | LL | struct ZisShouldBeBeforeZeMainFn; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -101,121 +100,121 @@ LL | const BEFORE: i8 = 0; | ^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:38:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:40:5 | LL | B, | ^ | note: should be placed before `C` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:37:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:39:5 | LL | C, | ^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:88:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:92:5 | LL | b: bool, | ^ | note: should be placed before `c` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:87:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:91:5 | LL | c: bool, | ^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:96:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:101:5 | LL | b: bool, | ^ | note: should be placed before `c` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:95:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:100:5 | LL | c: bool, | ^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:115:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:121:11 | LL | const B: bool; | ^ | note: should be placed before `C` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:114:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:120:11 | LL | const C: bool; | ^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:121:8 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:128:8 | LL | fn b(); | ^ | note: should be placed before `c` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:120:8 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:127:8 | LL | fn c(); | ^ error: incorrect ordering of trait items (defined order: [Const, Type, Fn]) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:127:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:135:5 | LL | const A: bool; | ^^^^^^^^^^^^^^ | note: should be placed before `SomeType` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:125:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:133:5 | LL | type SomeType; | ^^^^^^^^^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:141:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:151:11 | LL | const B: bool = false; | ^ | note: should be placed before `C` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:140:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:150:11 | LL | const C: bool = false; | ^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:147:8 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:158:8 | LL | fn b() {} | ^ | note: should be placed before `c` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:146:8 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:157:8 | LL | fn c() {} | ^ error: incorrect ordering of impl items (defined order: [Const, Type, Fn]) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:156:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:169:5 | LL | const A: bool = false; | ^^^^^^^^^^^^^^^^^^^^^^ | note: should be placed before `SomeType` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:154:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:167:5 | LL | type SomeType = (); | ^^^^^^^^^^^^^^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:172:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:11 | LL | const A: i8 = 1; | ^ | note: should be placed before `C` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:186:11 | LL | const C: i8 = 0; | ^ diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs index 2765bf935b7c..9e65a9cca0da 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs @@ -10,6 +10,7 @@ mod i_am_just_right { const BEFORE: i8 = 0; const AFTER: i8 = 0; + //~^ arbitrary_source_item_ordering } // Use statements should not be linted internally - this is normally auto-sorted using rustfmt. @@ -19,6 +20,7 @@ use std::sync::{Arc, Barrier, RwLock}; const SNAKE_CASE: &str = "zzzzzzzz"; use std::rc::Weak; +//~^ arbitrary_source_item_ordering trait BasicEmptyTrait {} @@ -36,6 +38,7 @@ enum EnumUnordered { A, C, B, + //~^ arbitrary_source_item_ordering } #[allow(clippy::arbitrary_source_item_ordering)] @@ -62,6 +65,7 @@ impl Default for StructOrdered { } impl CloneSelf for StructOrdered { + //~^ arbitrary_source_item_ordering fn clone_self(&self) -> Self { Self { a: true, @@ -86,6 +90,7 @@ struct StructUnordered { a: bool, c: bool, b: bool, + //~^ arbitrary_source_item_ordering d: bool, } @@ -94,6 +99,7 @@ struct StructUnorderedGeneric { a: bool, c: bool, b: bool, + //~^ arbitrary_source_item_ordering d: bool, } @@ -113,18 +119,21 @@ trait TraitUnordered { const A: bool; const C: bool; const B: bool; + //~^ arbitrary_source_item_ordering type SomeType; fn a(); fn c(); fn b(); + //~^ arbitrary_source_item_ordering } trait TraitUnorderedItemKinds { type SomeType; const A: bool; + //~^ arbitrary_source_item_ordering const B: bool; const C: bool; @@ -134,26 +143,31 @@ trait TraitUnorderedItemKinds { } const ZIS_SHOULD_BE_REALLY_EARLY: () = (); +//~^ arbitrary_source_item_ordering impl TraitUnordered for StructUnordered { const A: bool = false; const C: bool = false; const B: bool = false; + //~^ arbitrary_source_item_ordering type SomeType = (); fn a() {} fn c() {} fn b() {} + //~^ arbitrary_source_item_ordering } // Trait impls should be located just after the type they implement it for. impl BasicEmptyTrait for StructOrdered {} +//~^ arbitrary_source_item_ordering impl TraitUnorderedItemKinds for StructUnordered { type SomeType = (); const A: bool = false; + //~^ arbitrary_source_item_ordering const B: bool = false; const C: bool = false; @@ -168,14 +182,17 @@ fn main() { /// Note that the linting pass is stopped before recursing into this module. mod this_is_in_the_wrong_position { + //~^ arbitrary_source_item_ordering const C: i8 = 0; const A: i8 = 1; + //~^ arbitrary_source_item_ordering } #[derive(Default, std::clone::Clone)] struct ZisShouldBeBeforeZeMainFn; const ZIS_SHOULD_BE_EVEN_EARLIER: () = (); +//~^ arbitrary_source_item_ordering #[cfg(test)] mod test { diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs index 44902336573c..96b2fb16f8f5 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs @@ -103,20 +103,24 @@ impl TraitUnordered for StructUnordered { fn a() {} fn c() {} fn b() {} + //~^ arbitrary_source_item_ordering type SomeType = (); const A: bool = false; const C: bool = false; const B: bool = false; + //~^ arbitrary_source_item_ordering } impl TraitUnorderedItemKinds for StructUnordered { const A: bool = false; type SomeType = (); + //~^ arbitrary_source_item_ordering fn a() {} + //~^ arbitrary_source_item_ordering } struct StructUnorderedGeneric { @@ -143,20 +147,24 @@ trait TraitUnordered { fn a(); fn c(); fn b(); + //~^ arbitrary_source_item_ordering type SomeType; const A: bool; const C: bool; const B: bool; + //~^ arbitrary_source_item_ordering } trait TraitUnorderedItemKinds { const A: bool; type SomeType; + //~^ arbitrary_source_item_ordering fn a(); + //~^ arbitrary_source_item_ordering } #[derive(std::clone::Clone, Default)] diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr index f31f7f68c17e..730f12c38a0d 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr @@ -13,85 +13,85 @@ LL | fn c() {} = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]` error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:111:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:112:11 | LL | const B: bool = false; | ^ | note: should be placed before `C` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:110:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:111:11 | LL | const C: bool = false; | ^ error: incorrect ordering of impl items (defined order: [Fn, Type, Const]) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:117:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5 | LL | type SomeType = (); | ^^^^^^^^^^^^^^^^^^^ | note: should be placed before `A` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:115:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:117:5 | LL | const A: bool = false; | ^^^^^^^^^^^^^^^^^^^^^^ error: incorrect ordering of impl items (defined order: [Fn, Type, Const]) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:122:5 | LL | fn a() {} | ^^^^^^^^^ | note: should be placed before `SomeType` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:117:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5 | LL | type SomeType = (); | ^^^^^^^^^^^^^^^^^^^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:145:8 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:149:8 | LL | fn b(); | ^ | note: should be placed before `c` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:144:8 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:148:8 | LL | fn c(); | ^ error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:151:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:156:11 | LL | const B: bool; | ^ | note: should be placed before `C` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:150:11 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:155:11 | LL | const C: bool; | ^ error: incorrect ordering of trait items (defined order: [Fn, Type, Const]) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:157:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5 | LL | type SomeType; | ^^^^^^^^^^^^^^ | note: should be placed before `A` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:155:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:161:5 | LL | const A: bool; | ^^^^^^^^^^^^^^ error: incorrect ordering of trait items (defined order: [Fn, Type, Const]) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:159:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:166:5 | LL | fn a(); | ^^^^^^^ | note: should be placed before `SomeType` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:157:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5 | LL | type SomeType; | ^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs index e8002c4a1633..4e8ed5e550a3 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs @@ -20,6 +20,7 @@ enum EnumOrdered { enum EnumUnordered { B, A, + //~^ arbitrary_source_item_ordering } trait TraitUnordered { diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr index 40348ecbdae1..77596ba23946 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr @@ -13,7 +13,7 @@ LL | fn b() {} = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]` error: incorrect ordering of impl items (defined order: [Const, Type, Fn]) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:45:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5 | LL | type SomeType = i8; | ^^^^^^^^^^^^^^^^^^^ @@ -25,13 +25,13 @@ LL | fn a() {} | ^^^^^^^^^ error: incorrect ordering of impl items (defined order: [Const, Type, Fn]) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:47:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:49:5 | LL | const A: bool = true; | ^^^^^^^^^^^^^^^^^^^^^ | note: should be placed before `SomeType` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:45:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5 | LL | type SomeType = i8; | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs index bd969c865b5a..56e2e188be6a 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs @@ -41,10 +41,13 @@ trait TraitUnordered { impl BasicTrait for StructUnordered { fn b() {} fn a() {} + //~^ arbitrary_source_item_ordering type SomeType = i8; + //~^ arbitrary_source_item_ordering const A: bool = true; + //~^ arbitrary_source_item_ordering } trait TraitUnorderedItemKinds { diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr index 9b86ebd48e3d..3d903330be8f 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr @@ -13,25 +13,25 @@ LL | const B: bool; = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]` error: incorrect ordering of items (must be alphabetically ordered) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:37:8 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:38:8 | LL | fn a(); | ^ | note: should be placed before `b` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:36:8 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:37:8 | LL | fn b(); | ^ error: incorrect ordering of trait items (defined order: [Const, Type, Fn]) - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:43:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:45:5 | LL | const A: bool; | ^^^^^^^^^^^^^^ | note: should be placed before `SomeType` - --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:41:5 + --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:43:5 | LL | type SomeType; | ^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs index 979a52ecb100..d885a20ca50a 100644 --- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs +++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs @@ -30,17 +30,20 @@ enum EnumUnordered { trait TraitUnordered { const B: bool; const A: bool; + //~^ arbitrary_source_item_ordering type SomeType; fn b(); fn a(); + //~^ arbitrary_source_item_ordering } trait TraitUnorderedItemKinds { type SomeType; const A: bool; + //~^ arbitrary_source_item_ordering fn a(); } diff --git a/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs b/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs index 33f7c8ba8042..01a84a526c09 100644 --- a/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs +++ b/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs @@ -67,6 +67,7 @@ fn lhs_and_rhs_are_equal() { let _ = Bar + Bar; // not on the list let _ = Baz + Baz; + //~^ arithmetic_side_effects } fn lhs_is_different() { @@ -78,13 +79,16 @@ fn lhs_is_different() { let _ = 1i32 + Bar; // not on the list let _ = 1i32 + Baz; + //~^ arithmetic_side_effects // not on the list let _ = 1i64 + Foo; + //~^ arithmetic_side_effects // is implicitly on the list let _ = 1i64 + Bar; // not on the list let _ = 1i64 + Baz; + //~^ arithmetic_side_effects } fn rhs_is_different() { @@ -96,13 +100,16 @@ fn rhs_is_different() { let _ = Bar + 1i32; // not on the list let _ = Baz + 1i32; + //~^ arithmetic_side_effects // not on the list let _ = Foo + 1i64; + //~^ arithmetic_side_effects // is implicitly on the list let _ = Bar + 1i64; // not on the list let _ = Baz + 1i64; + //~^ arithmetic_side_effects } fn unary() { @@ -112,8 +119,10 @@ fn unary() { let _ = -Foo; // not on the list let _ = -Bar; + //~^ arithmetic_side_effects // not on the list let _ = -Baz; + //~^ arithmetic_side_effects } fn main() {} diff --git a/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr b/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr index 3c5216023b54..93efcc01c88f 100644 --- a/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr +++ b/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr @@ -8,49 +8,49 @@ LL | let _ = Baz + Baz; = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]` error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:80:13 + --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:81:13 | LL | let _ = 1i32 + Baz; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:83:13 + --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:85:13 | LL | let _ = 1i64 + Foo; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:87:13 + --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:90:13 | LL | let _ = 1i64 + Baz; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:98:13 + --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:102:13 | LL | let _ = Baz + 1i32; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:101:13 + --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:106:13 | LL | let _ = Foo + 1i64; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:105:13 + --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:111:13 | LL | let _ = Baz + 1i64; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:114:13 + --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:121:13 | LL | let _ = -Bar; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:116:13 + --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:124:13 | LL | let _ = -Baz; | ^^^^ diff --git a/tests/ui-toml/array_size_threshold/array_size_threshold.rs b/tests/ui-toml/array_size_threshold/array_size_threshold.rs index d36159e12639..b8652137378e 100644 --- a/tests/ui-toml/array_size_threshold/array_size_threshold.rs +++ b/tests/ui-toml/array_size_threshold/array_size_threshold.rs @@ -2,9 +2,11 @@ #![warn(clippy::large_const_arrays, clippy::large_stack_arrays)] //@no-rustfix const ABOVE: [u8; 11] = [0; 11]; +//~^ large_const_arrays const BELOW: [u8; 10] = [0; 10]; fn main() { let above = [0u8; 11]; + //~^ large_stack_arrays let below = [0u8; 10]; } diff --git a/tests/ui-toml/array_size_threshold/array_size_threshold.stderr b/tests/ui-toml/array_size_threshold/array_size_threshold.stderr index 41cb85b67df8..c962e8094076 100644 --- a/tests/ui-toml/array_size_threshold/array_size_threshold.stderr +++ b/tests/ui-toml/array_size_threshold/array_size_threshold.stderr @@ -10,7 +10,7 @@ LL | const ABOVE: [u8; 11] = [0; 11]; = help: to override `-D warnings` add `#[allow(clippy::large_const_arrays)]` error: allocating a local array larger than 10 bytes - --> tests/ui-toml/array_size_threshold/array_size_threshold.rs:8:17 + --> tests/ui-toml/array_size_threshold/array_size_threshold.rs:9:17 | LL | let above = [0u8; 11]; | ^^^^^^^^^ diff --git a/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs b/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs index 868cf00a8d46..6a9a49324db9 100644 --- a/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs +++ b/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs @@ -3,11 +3,13 @@ use std::net::Ipv4Addr; async fn bad() -> u32 { let _x = String::from("hello"); + //~^ await_holding_invalid_type baz().await } async fn bad_reason() -> u32 { let x = Ipv4Addr::new(127, 0, 0, 1); + //~^ await_holding_invalid_type let y = baz().await; let _x = x; y @@ -31,6 +33,7 @@ async fn baz() -> u32 { fn block_bad() -> impl std::future::Future { async move { let _x = String::from("hi!"); + //~^ await_holding_invalid_type baz().await } } diff --git a/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr b/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr index 39b8634be109..deb7f49db9e1 100644 --- a/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr +++ b/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr @@ -9,13 +9,13 @@ LL | let _x = String::from("hello"); = help: to override `-D warnings` add `#[allow(clippy::await_holding_invalid_type)]` error: holding a disallowed type across an await point `std::net::Ipv4Addr` - --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:10:9 + --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:11:9 | LL | let x = Ipv4Addr::new(127, 0, 0, 1); | ^ error: holding a disallowed type across an await point `std::string::String` - --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:33:13 + --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:35:13 | LL | let _x = String::from("hi!"); | ^^ diff --git a/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.rs b/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.rs index f328e4d9d04c..b5a1f3def61e 100644 --- a/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.rs +++ b/tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.rs @@ -1 +1,2 @@ +//@error-in-other-file: fn main() {} diff --git a/tests/ui-toml/borrow_interior_mutable_const/ignore.rs b/tests/ui-toml/borrow_interior_mutable_const/ignore.rs index 79c7cef6ce1b..0514419fd189 100644 --- a/tests/ui-toml/borrow_interior_mutable_const/ignore.rs +++ b/tests/ui-toml/borrow_interior_mutable_const/ignore.rs @@ -1,4 +1,5 @@ //@compile-flags: --crate-name borrow_interior_mutable_const_ignore +//@check-pass #![warn(clippy::borrow_interior_mutable_const)] #![allow(clippy::declare_interior_mutable_const)] diff --git a/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs b/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs index 7f1c512d7c97..ecb43dc34a8a 100644 --- a/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs +++ b/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs @@ -4,6 +4,7 @@ fn main() {} #[warn(clippy::cognitive_complexity)] fn cognitive_complexity() { + //~^ cognitive_complexity let x = vec![1, 2, 3]; for i in x { if i == 1 { diff --git a/tests/ui-toml/dbg_macro/dbg_macro.fixed b/tests/ui-toml/dbg_macro/dbg_macro.fixed index d42b29ba21a6..a91414559324 100644 --- a/tests/ui-toml/dbg_macro/dbg_macro.fixed +++ b/tests/ui-toml/dbg_macro/dbg_macro.fixed @@ -4,20 +4,27 @@ fn foo(n: u32) -> u32 { if let Some(n) = n.checked_sub(4) { n } else { n } + //~^ dbg_macro } fn factorial(n: u32) -> u32 { if n <= 1 { + //~^ dbg_macro 1 + //~^ dbg_macro } else { n * factorial(n - 1) + //~^ dbg_macro } } fn main() { 42; + //~^ dbg_macro foo(3) + factorial(4); + //~^ dbg_macro (1, 2, 3, 4, 5); + //~^ dbg_macro } #[test] diff --git a/tests/ui-toml/dbg_macro/dbg_macro.rs b/tests/ui-toml/dbg_macro/dbg_macro.rs index bd189b1576f9..6565f2e3cf7c 100644 --- a/tests/ui-toml/dbg_macro/dbg_macro.rs +++ b/tests/ui-toml/dbg_macro/dbg_macro.rs @@ -4,20 +4,27 @@ fn foo(n: u32) -> u32 { if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } + //~^ dbg_macro } fn factorial(n: u32) -> u32 { if dbg!(n <= 1) { + //~^ dbg_macro dbg!(1) + //~^ dbg_macro } else { dbg!(n * factorial(n - 1)) + //~^ dbg_macro } } fn main() { dbg!(42); + //~^ dbg_macro foo(3) + dbg!(factorial(4)); + //~^ dbg_macro dbg!(1, 2, 3, 4, 5); + //~^ dbg_macro } #[test] diff --git a/tests/ui-toml/dbg_macro/dbg_macro.stderr b/tests/ui-toml/dbg_macro/dbg_macro.stderr index 129fab5ff97a..3d869f97c0af 100644 --- a/tests/ui-toml/dbg_macro/dbg_macro.stderr +++ b/tests/ui-toml/dbg_macro/dbg_macro.stderr @@ -12,7 +12,7 @@ LL | if let Some(n) = n.checked_sub(4) { n } else { n } | ~~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui-toml/dbg_macro/dbg_macro.rs:10:8 + --> tests/ui-toml/dbg_macro/dbg_macro.rs:11:8 | LL | if dbg!(n <= 1) { | ^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | if n <= 1 { | ~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui-toml/dbg_macro/dbg_macro.rs:11:9 + --> tests/ui-toml/dbg_macro/dbg_macro.rs:13:9 | LL | dbg!(1) | ^^^^^^^ @@ -34,7 +34,7 @@ LL | 1 | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui-toml/dbg_macro/dbg_macro.rs:13:9 + --> tests/ui-toml/dbg_macro/dbg_macro.rs:16:9 | LL | dbg!(n * factorial(n - 1)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | n * factorial(n - 1) | error: the `dbg!` macro is intended as a debugging tool - --> tests/ui-toml/dbg_macro/dbg_macro.rs:18:5 + --> tests/ui-toml/dbg_macro/dbg_macro.rs:22:5 | LL | dbg!(42); | ^^^^^^^^ @@ -56,7 +56,7 @@ LL | 42; | ~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui-toml/dbg_macro/dbg_macro.rs:19:14 + --> tests/ui-toml/dbg_macro/dbg_macro.rs:24:14 | LL | foo(3) + dbg!(factorial(4)); | ^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | foo(3) + factorial(4); | ~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> tests/ui-toml/dbg_macro/dbg_macro.rs:20:5 + --> tests/ui-toml/dbg_macro/dbg_macro.rs:26:5 | LL | dbg!(1, 2, 3, 4, 5); | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/declare_interior_mutable_const/ignore.rs b/tests/ui-toml/declare_interior_mutable_const/ignore.rs index 6385cf4f852f..49ffc7a939de 100644 --- a/tests/ui-toml/declare_interior_mutable_const/ignore.rs +++ b/tests/ui-toml/declare_interior_mutable_const/ignore.rs @@ -1,4 +1,5 @@ //@compile-flags: --crate-name declare_interior_mutable_const_ignore +//@check-pass #![warn(clippy::declare_interior_mutable_const)] #![allow(clippy::borrow_interior_mutable_const)] diff --git a/tests/ui-toml/disallowed_macros/disallowed_macros.rs b/tests/ui-toml/disallowed_macros/disallowed_macros.rs index e63a99e74cbb..cfe19606ef4a 100644 --- a/tests/ui-toml/disallowed_macros/disallowed_macros.rs +++ b/tests/ui-toml/disallowed_macros/disallowed_macros.rs @@ -11,38 +11,54 @@ use serde::Serialize; fn main() { println!("one"); + //~^ disallowed_macros println!("two"); + //~^ disallowed_macros cfg!(unix); + //~^ disallowed_macros vec![1, 2, 3]; + //~^ disallowed_macros #[derive(Serialize)] + //~^ disallowed_macros struct Derive; let _ = macros::expr!(); + //~^ disallowed_macros macros::stmt!(); + //~^ disallowed_macros let macros::pat!() = 1; + //~^ disallowed_macros let _: macros::ty!() = ""; + //~^ disallowed_macros macros::item!(); + //~^ disallowed_macros let _ = macros::binop!(1); + //~^ disallowed_macros eprintln!("allowed"); } macros::attr! { +//~^ disallowed_macros struct S; } impl S { macros::item!(); + //~^ disallowed_macros } trait Y { macros::item!(); + //~^ disallowed_macros } impl Y for S { macros::item!(); + //~^ disallowed_macros } #[derive(Derive)] +//~^ disallowed_macros struct Foo; diff --git a/tests/ui-toml/disallowed_macros/disallowed_macros.stderr b/tests/ui-toml/disallowed_macros/disallowed_macros.stderr index 6a6c6168a1f5..589995fa87d9 100644 --- a/tests/ui-toml/disallowed_macros/disallowed_macros.stderr +++ b/tests/ui-toml/disallowed_macros/disallowed_macros.stderr @@ -1,5 +1,5 @@ error: use of a disallowed macro `serde::Serialize` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:18:14 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:22:14 | LL | #[derive(Serialize)] | ^^^^^^^^^ @@ -9,15 +9,16 @@ LL | #[derive(Serialize)] = help: to override `-D warnings` add `#[allow(clippy::disallowed_macros)]` error: use of a disallowed macro `macros::attr` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:31:1 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:42:1 | LL | / macros::attr! { +LL | | LL | | struct S; LL | | } | |_^ error: use of a disallowed macro `proc_macros::Derive` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:47:10 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:62:10 | LL | #[derive(Derive)] | ^^^^^^ @@ -29,73 +30,73 @@ LL | println!("one"); | ^^^^^^^^^^^^^^^ error: use of a disallowed macro `std::println` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:14:5 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:15:5 | LL | println!("two"); | ^^^^^^^^^^^^^^^ error: use of a disallowed macro `std::cfg` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:15:5 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:17:5 | LL | cfg!(unix); | ^^^^^^^^^^ error: use of a disallowed macro `std::vec` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:16:5 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:19:5 | LL | vec![1, 2, 3]; | ^^^^^^^^^^^^^ error: use of a disallowed macro `macros::expr` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:21:13 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:26:13 | LL | let _ = macros::expr!(); | ^^^^^^^^^^^^^^^ error: use of a disallowed macro `macros::stmt` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:22:5 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:28:5 | LL | macros::stmt!(); | ^^^^^^^^^^^^^^^ error: use of a disallowed macro `macros::pat` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:23:9 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:30:9 | LL | let macros::pat!() = 1; | ^^^^^^^^^^^^^^ error: use of a disallowed macro `macros::ty` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:24:12 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:32:12 | LL | let _: macros::ty!() = ""; | ^^^^^^^^^^^^^ error: use of a disallowed macro `macros::item` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:25:5 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:34:5 | LL | macros::item!(); | ^^^^^^^^^^^^^^^ error: use of a disallowed macro `macros::binop` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:26:13 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:36:13 | LL | let _ = macros::binop!(1); | ^^^^^^^^^^^^^^^^^ error: use of a disallowed macro `macros::item` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:36:5 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:48:5 | LL | macros::item!(); | ^^^^^^^^^^^^^^^ error: use of a disallowed macro `macros::item` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:40:5 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:53:5 | LL | macros::item!(); | ^^^^^^^^^^^^^^^ error: use of a disallowed macro `macros::item` - --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:44:5 + --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:58:5 | LL | macros::item!(); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/disallowed_names_append/disallowed_names.rs b/tests/ui-toml/disallowed_names_append/disallowed_names.rs index 61ae8de8e335..ea7e31a119dc 100644 --- a/tests/ui-toml/disallowed_names_append/disallowed_names.rs +++ b/tests/ui-toml/disallowed_names_append/disallowed_names.rs @@ -3,8 +3,10 @@ fn main() { // `foo` is part of the default configuration let foo = "bar"; + //~^ disallowed_names // `ducks` was unrightfully disallowed let ducks = ["quack", "quack"]; + //~^ disallowed_names // `fox` is okay let fox = ["what", "does", "the", "fox", "say", "?"]; } diff --git a/tests/ui-toml/disallowed_names_append/disallowed_names.stderr b/tests/ui-toml/disallowed_names_append/disallowed_names.stderr index e6481c9cc63b..6b7a3fbd8c8d 100644 --- a/tests/ui-toml/disallowed_names_append/disallowed_names.stderr +++ b/tests/ui-toml/disallowed_names_append/disallowed_names.stderr @@ -8,7 +8,7 @@ LL | let foo = "bar"; = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]` error: use of a disallowed/placeholder name `ducks` - --> tests/ui-toml/disallowed_names_append/disallowed_names.rs:7:9 + --> tests/ui-toml/disallowed_names_append/disallowed_names.rs:8:9 | LL | let ducks = ["quack", "quack"]; | ^^^^^ diff --git a/tests/ui-toml/disallowed_names_replace/disallowed_names.rs b/tests/ui-toml/disallowed_names_replace/disallowed_names.rs index 61ae8de8e335..dd79795d76a2 100644 --- a/tests/ui-toml/disallowed_names_replace/disallowed_names.rs +++ b/tests/ui-toml/disallowed_names_replace/disallowed_names.rs @@ -5,6 +5,7 @@ fn main() { let foo = "bar"; // `ducks` was unrightfully disallowed let ducks = ["quack", "quack"]; + //~^ disallowed_names // `fox` is okay let fox = ["what", "does", "the", "fox", "say", "?"]; } diff --git a/tests/ui-toml/doc_valid_idents_append/doc_markdown.fixed b/tests/ui-toml/doc_valid_idents_append/doc_markdown.fixed index f16e138da2be..e295712e85f4 100644 --- a/tests/ui-toml/doc_valid_idents_append/doc_markdown.fixed +++ b/tests/ui-toml/doc_valid_idents_append/doc_markdown.fixed @@ -7,6 +7,7 @@ fn allowed_name() {} fn default_name() {} /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. +//~^ doc_markdown fn unknown_name() {} fn main() {} diff --git a/tests/ui-toml/doc_valid_idents_append/doc_markdown.rs b/tests/ui-toml/doc_valid_idents_append/doc_markdown.rs index 327a592e9cad..192652a7f65b 100644 --- a/tests/ui-toml/doc_valid_idents_append/doc_markdown.rs +++ b/tests/ui-toml/doc_valid_idents_append/doc_markdown.rs @@ -7,6 +7,7 @@ fn allowed_name() {} fn default_name() {} /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted. +//~^ doc_markdown fn unknown_name() {} fn main() {} diff --git a/tests/ui-toml/doc_valid_idents_replace/doc_markdown.fixed b/tests/ui-toml/doc_valid_idents_replace/doc_markdown.fixed index af6ec675e81b..48a6f5fe61e6 100644 --- a/tests/ui-toml/doc_valid_idents_replace/doc_markdown.fixed +++ b/tests/ui-toml/doc_valid_idents_replace/doc_markdown.fixed @@ -4,9 +4,12 @@ fn allowed_name() {} /// `OAuth` and `LaTeX` are inside Clippy's default list. +//~^ doc_markdown +//~| doc_markdown fn default_name() {} /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted. +//~^ doc_markdown fn unknown_name() {} fn main() {} diff --git a/tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs b/tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs index 327a592e9cad..f700c1ab0336 100644 --- a/tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs +++ b/tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs @@ -4,9 +4,12 @@ fn allowed_name() {} /// OAuth and LaTeX are inside Clippy's default list. +//~^ doc_markdown +//~| doc_markdown fn default_name() {} /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted. +//~^ doc_markdown fn unknown_name() {} fn main() {} diff --git a/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr b/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr index d4d8a579798c..cb5f5abda6c6 100644 --- a/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr +++ b/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr @@ -23,7 +23,7 @@ LL | /// OAuth and `LaTeX` are inside Clippy's default list. | ~~~~~~~ error: item in documentation is missing backticks - --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:9:5 + --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:11:5 | LL | /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted. | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.rs b/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.rs index f328e4d9d04c..b5a1f3def61e 100644 --- a/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.rs +++ b/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.rs @@ -1 +1,2 @@ +//@error-in-other-file: fn main() {} diff --git a/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.rs b/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.rs index f328e4d9d04c..b5a1f3def61e 100644 --- a/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.rs +++ b/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.rs @@ -1 +1,2 @@ +//@error-in-other-file: fn main() {} diff --git a/tests/ui-toml/excessive_nesting/excessive_nesting.rs b/tests/ui-toml/excessive_nesting/excessive_nesting.rs index 858aab528a91..205cd8ba4ee8 100644 --- a/tests/ui-toml/excessive_nesting/excessive_nesting.rs +++ b/tests/ui-toml/excessive_nesting/excessive_nesting.rs @@ -23,6 +23,7 @@ static X: u32 = { let y = { let z = { let w = { 3 }; + //~^ excessive_nesting w }; z @@ -69,6 +70,7 @@ impl A { struct C; impl C { + //~^ excessive_nesting pub fn c() {} } } @@ -83,6 +85,7 @@ trait Lol { fn bb() { fn cc() { let x = { 1 }; // not a warning, but cc is + //~^ excessive_nesting } let x = { 1 }; // warning @@ -100,6 +103,7 @@ pub mod a { pub mod c { pub mod d { pub mod e { + //~^ excessive_nesting pub mod f {} } // not here } // only warning should be here @@ -113,13 +117,17 @@ fn main() { let a = A; a_but_not({{{{{{{{0}}}}}}}}); + //~^ excessive_nesting a.a({{{{{{{{{0}}}}}}}}}); + //~^ excessive_nesting (0, {{{{{{{1}}}}}}}); + //~^ excessive_nesting if true { if true { if true { if true { + //~^ excessive_nesting if true { } @@ -132,6 +140,7 @@ fn main() { let x = (|| { let y = (|| { let z = (|| { + //~^ excessive_nesting let w = { 3 }; w })(); @@ -151,38 +160,64 @@ fn main() { // this is a mess, but that's intentional let mut y = 1; y += {{{{{5}}}}}; + //~^ excessive_nesting let z = y + {{{{{{{{{5}}}}}}}}}; + //~^ excessive_nesting [0, {{{{{{{{{{0}}}}}}}}}}]; + //~^ excessive_nesting let mut xx = [0; {{{{{{{{100}}}}}}}}]; + //~^ excessive_nesting xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}]; + //~^ excessive_nesting &mut {{{{{{{{{{y}}}}}}}}}}; + //~^ excessive_nesting for i in {{{{xx}}}} {{{{{{{{}}}}}}}} + //~^ excessive_nesting + //~| excessive_nesting while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} + //~^ excessive_nesting + //~| excessive_nesting while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} + //~^ excessive_nesting + //~| excessive_nesting let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} }; + //~^ excessive_nesting {{{{1;}}}}..{{{{{{3}}}}}}; + //~^ excessive_nesting + //~| excessive_nesting {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; + //~^ excessive_nesting + //~| excessive_nesting ..{{{{{{{5}}}}}}}; + //~^ excessive_nesting ..={{{{{3}}}}}; + //~^ excessive_nesting {{{{{1;}}}}}..; + //~^ excessive_nesting loop { break {{{{1}}}} }; + //~^ excessive_nesting loop {{{{{{}}}}}} + //~^ excessive_nesting match {{{{{{true}}}}}} { + //~^ excessive_nesting true => {{{{}}}}, + //~^ excessive_nesting false => {{{{}}}}, + //~^ excessive_nesting } { { { { + //~^ excessive_nesting println!("warning! :)"); } } @@ -192,10 +227,12 @@ fn main() { async fn b() -> u32 { async fn c() -> u32 {{{{{{{0}}}}}}} + //~^ excessive_nesting c().await } async fn a() { {{{{b().await}}}}; + //~^ excessive_nesting } diff --git a/tests/ui-toml/excessive_nesting/excessive_nesting.stderr b/tests/ui-toml/excessive_nesting/excessive_nesting.stderr index 9cf6fc66757d..bc2c4b8612ec 100644 --- a/tests/ui-toml/excessive_nesting/excessive_nesting.stderr +++ b/tests/ui-toml/excessive_nesting/excessive_nesting.stderr @@ -9,9 +9,10 @@ LL | let w = { 3 }; = help: to override `-D warnings` add `#[allow(clippy::excessive_nesting)]` error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:71:17 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:72:17 | LL | / impl C { +LL | | LL | | pub fn c() {} LL | | } | |_________________^ @@ -19,7 +20,7 @@ LL | | } = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:85:25 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:87:25 | LL | let x = { 1 }; // not a warning, but cc is | ^^^^^ @@ -27,9 +28,10 @@ LL | let x = { 1 }; // not a warning, but cc is = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:102:17 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:105:17 | LL | / pub mod e { +LL | | LL | | pub mod f {} LL | | } // not here | |_________________^ @@ -37,7 +39,7 @@ LL | | } // not here = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:115:18 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:119:18 | LL | a_but_not({{{{{{{{0}}}}}}}}); | ^^^^^^^^^^^ @@ -45,7 +47,7 @@ LL | a_but_not({{{{{{{{0}}}}}}}}); = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:116:12 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:121:12 | LL | a.a({{{{{{{{{0}}}}}}}}}); | ^^^^^^^^^^^^^ @@ -53,7 +55,7 @@ LL | a.a({{{{{{{{{0}}}}}}}}}); = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:117:12 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:123:12 | LL | (0, {{{{{{{1}}}}}}}); | ^^^^^^^^^ @@ -61,10 +63,11 @@ LL | (0, {{{{{{{1}}}}}}}); = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:122:25 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:129:25 | LL | if true { | _________________________^ +LL | | LL | | if true { ... | LL | | } @@ -73,10 +76,11 @@ LL | | } = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:134:29 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:142:29 | LL | let z = (|| { | _____________________________^ +LL | | LL | | let w = { 3 }; LL | | w LL | | })(); @@ -85,7 +89,7 @@ LL | | })(); = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:153:13 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:162:13 | LL | y += {{{{{5}}}}}; | ^^^^^ @@ -93,7 +97,7 @@ LL | y += {{{{{5}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:154:20 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:20 | LL | let z = y + {{{{{{{{{5}}}}}}}}}; | ^^^^^^^^^^^^^ @@ -101,7 +105,7 @@ LL | let z = y + {{{{{{{{{5}}}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:155:12 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:166:12 | LL | [0, {{{{{{{{{{0}}}}}}}}}}]; | ^^^^^^^^^^^^^^^ @@ -109,7 +113,7 @@ LL | [0, {{{{{{{{{{0}}}}}}}}}}]; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:156:25 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:168:25 | LL | let mut xx = [0; {{{{{{{{100}}}}}}}}]; | ^^^^^^^^^^^^^ @@ -117,7 +121,7 @@ LL | let mut xx = [0; {{{{{{{{100}}}}}}}}]; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:157:11 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:170:11 | LL | xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -125,7 +129,7 @@ LL | xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}]; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:158:13 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:172:13 | LL | &mut {{{{{{{{{{y}}}}}}}}}}; | ^^^^^^^^^^^^^^^ @@ -133,7 +137,7 @@ LL | &mut {{{{{{{{{{y}}}}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:160:17 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:175:17 | LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} | ^^^^ @@ -141,7 +145,7 @@ LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:160:28 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:175:28 | LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} | ^^^^^^^^^^ @@ -149,7 +153,7 @@ LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:162:28 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:179:28 | LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} | ^^^^^^^^^^^^^ @@ -157,7 +161,7 @@ LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:162:48 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:179:48 | LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} | ^^^^^^^^ @@ -165,7 +169,7 @@ LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:14 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:183:14 | LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} | ^^^^^^^^^^^^^^ @@ -173,7 +177,7 @@ LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:35 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:183:35 | LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} | ^^^^^^^^^^^^ @@ -181,7 +185,7 @@ LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:166:23 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:187:23 | LL | let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +193,7 @@ LL | let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} }; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:168:8 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:190:8 | LL | {{{{1;}}}}..{{{{{{3}}}}}}; | ^^^^ @@ -197,7 +201,7 @@ LL | {{{{1;}}}}..{{{{{{3}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:168:20 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:190:20 | LL | {{{{1;}}}}..{{{{{{3}}}}}}; | ^^^^^^^ @@ -205,7 +209,7 @@ LL | {{{{1;}}}}..{{{{{{3}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:169:8 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:193:8 | LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; | ^^^^ @@ -213,7 +217,7 @@ LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:169:21 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:193:21 | LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +225,7 @@ LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:170:10 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:196:10 | LL | ..{{{{{{{5}}}}}}}; | ^^^^^^^^^ @@ -229,7 +233,7 @@ LL | ..{{{{{{{5}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:171:11 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:198:11 | LL | ..={{{{{3}}}}}; | ^^^^^ @@ -237,7 +241,7 @@ LL | ..={{{{{3}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:172:8 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:200:8 | LL | {{{{{1;}}}}}..; | ^^^^^^ @@ -245,7 +249,7 @@ LL | {{{{{1;}}}}}..; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:174:20 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:203:20 | LL | loop { break {{{{1}}}} }; | ^^^^^ @@ -253,7 +257,7 @@ LL | loop { break {{{{1}}}} }; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:175:13 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:205:13 | LL | loop {{{{{{}}}}}} | ^^^^^^ @@ -261,7 +265,7 @@ LL | loop {{{{{{}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:177:14 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:208:14 | LL | match {{{{{{true}}}}}} { | ^^^^^^^^^^ @@ -269,7 +273,7 @@ LL | match {{{{{{true}}}}}} { = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:178:20 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:210:20 | LL | true => {{{{}}}}, | ^^ @@ -277,7 +281,7 @@ LL | true => {{{{}}}}, = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:179:21 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:212:21 | LL | false => {{{{}}}}, | ^^ @@ -285,9 +289,10 @@ LL | false => {{{{}}}}, = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:185:17 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:219:17 | LL | / { +LL | | LL | | println!("warning! :)"); LL | | } | |_________________^ @@ -295,7 +300,7 @@ LL | | } = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:194:28 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:229:28 | LL | async fn c() -> u32 {{{{{{{0}}}}}}} | ^^^^^^^^^ @@ -303,7 +308,7 @@ LL | async fn c() -> u32 {{{{{{{0}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:200:8 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:236:8 | LL | {{{{b().await}}}}; | ^^^^^^^^^^^ diff --git a/tests/ui-toml/expect_used/expect_used.rs b/tests/ui-toml/expect_used/expect_used.rs index f0b92329f97a..9955c9b6baa1 100644 --- a/tests/ui-toml/expect_used/expect_used.rs +++ b/tests/ui-toml/expect_used/expect_used.rs @@ -6,11 +6,13 @@ fn expect_option() { let opt = Some(0); let _ = opt.expect(""); + //~^ expect_used } fn expect_result() { let res: Result = Ok(0); let _ = res.expect(""); + //~^ expect_used } fn main() { @@ -19,10 +21,10 @@ fn main() { const SOME: Option = Some(3); const UNWRAPPED: i32 = SOME.expect("Not three?"); - //~^ ERROR: used `expect()` on an `Option` value + //~^ expect_used const { SOME.expect("Still not three?"); - //~^ ERROR: used `expect()` on an `Option` value + //~^ expect_used } } diff --git a/tests/ui-toml/expect_used/expect_used.stderr b/tests/ui-toml/expect_used/expect_used.stderr index b28bb7b7e0d1..3bb471e6dfcc 100644 --- a/tests/ui-toml/expect_used/expect_used.stderr +++ b/tests/ui-toml/expect_used/expect_used.stderr @@ -9,7 +9,7 @@ LL | let _ = opt.expect(""); = help: to override `-D warnings` add `#[allow(clippy::expect_used)]` error: used `expect()` on a `Result` value - --> tests/ui-toml/expect_used/expect_used.rs:13:13 + --> tests/ui-toml/expect_used/expect_used.rs:14:13 | LL | let _ = res.expect(""); | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = res.expect(""); = note: if this value is an `Err`, it will panic error: used `expect()` on an `Option` value - --> tests/ui-toml/expect_used/expect_used.rs:21:28 + --> tests/ui-toml/expect_used/expect_used.rs:23:28 | LL | const UNWRAPPED: i32 = SOME.expect("Not three?"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | const UNWRAPPED: i32 = SOME.expect("Not three?"); = note: if this value is `None`, it will panic error: used `expect()` on an `Option` value - --> tests/ui-toml/expect_used/expect_used.rs:24:9 + --> tests/ui-toml/expect_used/expect_used.rs:26:9 | LL | SOME.expect("Still not three?"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/extra_unused_type_parameters/extra_unused_type_parameters.rs b/tests/ui-toml/extra_unused_type_parameters/extra_unused_type_parameters.rs index 5655232455cb..1256c93c0fa1 100644 --- a/tests/ui-toml/extra_unused_type_parameters/extra_unused_type_parameters.rs +++ b/tests/ui-toml/extra_unused_type_parameters/extra_unused_type_parameters.rs @@ -1,3 +1,4 @@ +//@check-pass pub struct S; impl S { diff --git a/tests/ui-toml/fn_params_excessive_bools/test.rs b/tests/ui-toml/fn_params_excessive_bools/test.rs index 42897b389edf..af8b8a7991ab 100644 --- a/tests/ui-toml/fn_params_excessive_bools/test.rs +++ b/tests/ui-toml/fn_params_excessive_bools/test.rs @@ -2,5 +2,6 @@ fn f(_: bool) {} fn g(_: bool, _: bool) {} +//~^ fn_params_excessive_bools fn main() {} diff --git a/tests/ui-toml/functions_maxlines/test.rs b/tests/ui-toml/functions_maxlines/test.rs index 4ac0378544c7..09d76a9b2657 100644 --- a/tests/ui-toml/functions_maxlines/test.rs +++ b/tests/ui-toml/functions_maxlines/test.rs @@ -17,18 +17,21 @@ fn many_comments_but_one_line_of_code() { // This should be considered two and a fail. fn too_many_lines() { + //~^ too_many_lines println!("This is bad."); println!("This is bad."); } // This should only fail once (#7517). async fn async_too_many_lines() { + //~^ too_many_lines println!("This is bad."); println!("This is bad."); } // This should fail only once, without failing on the closure. fn closure_too_many_lines() { + //~^ too_many_lines let _ = { println!("This is bad."); println!("This is bad."); @@ -51,6 +54,7 @@ fn comment_after_code() { // This should fail since it is technically two lines. #[rustfmt::skip] fn comment_before_code() { +//~^ too_many_lines let _ = "test"; /* This comment extends to the front of the code but this line should still count. */ let _ = 5; diff --git a/tests/ui-toml/functions_maxlines/test.stderr b/tests/ui-toml/functions_maxlines/test.stderr index cb188a868c44..14a49cb76c1c 100644 --- a/tests/ui-toml/functions_maxlines/test.stderr +++ b/tests/ui-toml/functions_maxlines/test.stderr @@ -2,6 +2,7 @@ error: this function has too many lines (2/1) --> tests/ui-toml/functions_maxlines/test.rs:19:1 | LL | / fn too_many_lines() { +LL | | LL | | println!("This is bad."); LL | | println!("This is bad."); LL | | } @@ -11,18 +12,20 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::too_many_lines)]` error: this function has too many lines (4/1) - --> tests/ui-toml/functions_maxlines/test.rs:25:1 + --> tests/ui-toml/functions_maxlines/test.rs:26:1 | LL | / async fn async_too_many_lines() { +LL | | LL | | println!("This is bad."); LL | | println!("This is bad."); LL | | } | |_^ error: this function has too many lines (4/1) - --> tests/ui-toml/functions_maxlines/test.rs:31:1 + --> tests/ui-toml/functions_maxlines/test.rs:33:1 | LL | / fn closure_too_many_lines() { +LL | | LL | | let _ = { LL | | println!("This is bad."); LL | | println!("This is bad."); @@ -31,9 +34,10 @@ LL | | } | |_^ error: this function has too many lines (2/1) - --> tests/ui-toml/functions_maxlines/test.rs:53:1 + --> tests/ui-toml/functions_maxlines/test.rs:56:1 | LL | / fn comment_before_code() { +LL | | LL | | let _ = "test"; LL | | /* This comment extends to the front of LL | | the code but this line should still count. */ let _ = 5; diff --git a/tests/ui-toml/good_toml_no_false_negatives/conf_no_false_negatives.rs b/tests/ui-toml/good_toml_no_false_negatives/conf_no_false_negatives.rs index f328e4d9d04c..9763a0977801 100644 --- a/tests/ui-toml/good_toml_no_false_negatives/conf_no_false_negatives.rs +++ b/tests/ui-toml/good_toml_no_false_negatives/conf_no_false_negatives.rs @@ -1 +1,2 @@ +//@check-pass fn main() {} diff --git a/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs b/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs index 4882416c414a..e953a2a4e90b 100644 --- a/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs +++ b/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs @@ -13,6 +13,7 @@ fn issue10272() { if x.get() { } else if !x.take() { } else if x.get() { + //~^ ifs_same_cond } else { } } diff --git a/tests/ui-toml/indexing_slicing/indexing_slicing.rs b/tests/ui-toml/indexing_slicing/indexing_slicing.rs index 0a0da88ea1fa..dd741be91d29 100644 --- a/tests/ui-toml/indexing_slicing/indexing_slicing.rs +++ b/tests/ui-toml/indexing_slicing/indexing_slicing.rs @@ -6,6 +6,7 @@ fn main() { let x = [1, 2, 3, 4]; let index: usize = 1; &x[index..]; + //~^ indexing_slicing } #[cfg(test)] diff --git a/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs b/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs index 2ae673a6def0..d6b0a3017920 100644 --- a/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs +++ b/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs @@ -7,6 +7,7 @@ pub mod foo { // this line should produce a warning: pub fn to_foo() {} + //~^ module_name_repetitions // but this line shouldn't pub fn bar_foo() {} diff --git a/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs b/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs index dbd61992c0d6..347430f3d2f9 100644 --- a/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs +++ b/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs @@ -7,6 +7,7 @@ pub mod foo { // this line should produce a warning: pub fn something_foo() {} + //~^ module_name_repetitions // but none of the following should: pub fn bar_foo() {} diff --git a/tests/ui-toml/item_name_repetitions/threshold0/item_name_repetitions.rs b/tests/ui-toml/item_name_repetitions/threshold0/item_name_repetitions.rs index b633dcbd19e4..f05e2410f7e2 100644 --- a/tests/ui-toml/item_name_repetitions/threshold0/item_name_repetitions.rs +++ b/tests/ui-toml/item_name_repetitions/threshold0/item_name_repetitions.rs @@ -1,3 +1,5 @@ +//@check-pass + struct Data {} enum Actions {} diff --git a/tests/ui-toml/large_futures/large_futures.fixed b/tests/ui-toml/large_futures/large_futures.fixed index 7dea9fb95b4b..17d6553a283b 100644 --- a/tests/ui-toml/large_futures/large_futures.fixed +++ b/tests/ui-toml/large_futures/large_futures.fixed @@ -16,6 +16,7 @@ pub async fn should_not_warn() { pub async fn bar() { Box::pin(should_warn()).await; + //~^ large_futures async { let x = [0u8; 1024]; diff --git a/tests/ui-toml/large_futures/large_futures.rs b/tests/ui-toml/large_futures/large_futures.rs index 4158df8b5ff5..bc601227e562 100644 --- a/tests/ui-toml/large_futures/large_futures.rs +++ b/tests/ui-toml/large_futures/large_futures.rs @@ -16,6 +16,7 @@ pub async fn should_not_warn() { pub async fn bar() { should_warn().await; + //~^ large_futures async { let x = [0u8; 1024]; diff --git a/tests/ui-toml/large_include_file/large_include_file.rs b/tests/ui-toml/large_include_file/large_include_file.rs index 184c6d17ba41..685ef1689e72 100644 --- a/tests/ui-toml/large_include_file/large_include_file.rs +++ b/tests/ui-toml/large_include_file/large_include_file.rs @@ -2,7 +2,7 @@ #![allow(clippy::literal_string_with_formatting_args)] // Good -const GOOD_INCLUDE_BYTES: &[u8; 68] = include_bytes!("../../ui/author.rs"); +const GOOD_INCLUDE_BYTES: &[u8; 84] = include_bytes!("../../ui/author.rs"); const GOOD_INCLUDE_STR: &str = include_str!("../../ui/author.rs"); #[allow(clippy::large_include_file)] diff --git a/tests/ui-toml/lint_decimal_readability/test.fixed b/tests/ui-toml/lint_decimal_readability/test.fixed index f013153f5166..2d76824128bf 100644 --- a/tests/ui-toml/lint_decimal_readability/test.fixed +++ b/tests/ui-toml/lint_decimal_readability/test.fixed @@ -17,7 +17,9 @@ fn main() { // due to clippy::inconsistent-digit-grouping let _fail1 = 100_200_300.123_456_789; + //~^ inconsistent_digit_grouping // fail due to the integer part let _fail2 = 100_200_300.300_200_100; + //~^ unreadable_literal } diff --git a/tests/ui-toml/lint_decimal_readability/test.rs b/tests/ui-toml/lint_decimal_readability/test.rs index bd5110138c8c..b42e31085217 100644 --- a/tests/ui-toml/lint_decimal_readability/test.rs +++ b/tests/ui-toml/lint_decimal_readability/test.rs @@ -17,7 +17,9 @@ fn main() { // due to clippy::inconsistent-digit-grouping let _fail1 = 100_200_300.123456789; + //~^ inconsistent_digit_grouping // fail due to the integer part let _fail2 = 100200300.300200100; + //~^ unreadable_literal } diff --git a/tests/ui-toml/lint_decimal_readability/test.stderr b/tests/ui-toml/lint_decimal_readability/test.stderr index 766722d35ab7..c4e164c67ed8 100644 --- a/tests/ui-toml/lint_decimal_readability/test.stderr +++ b/tests/ui-toml/lint_decimal_readability/test.stderr @@ -8,7 +8,7 @@ LL | let _fail1 = 100_200_300.123456789; = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]` error: long literal lacking separators - --> tests/ui-toml/lint_decimal_readability/test.rs:22:18 + --> tests/ui-toml/lint_decimal_readability/test.rs:23:18 | LL | let _fail2 = 100200300.300200100; | ^^^^^^^^^^^^^^^^^^^ help: consider: `100_200_300.300_200_100` diff --git a/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs b/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs index 3dafea56514d..2465fe45645f 100644 --- a/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs +++ b/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs @@ -17,7 +17,7 @@ macro_rules! allow_works { macro_rules! simple { ($v:expr) => { unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe dbg!($v); } }; @@ -28,7 +28,7 @@ macro_rules! simple { macro_rules! raw_symbol { ($r#mod:expr, $r#unsafe:expr) => { unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $r#mod; } $r#unsafe; @@ -40,7 +40,7 @@ macro_rules! multilevel_unsafe { ($v:expr) => { unsafe { unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $v; } } @@ -65,7 +65,7 @@ macro_rules! in_function_with_unsafe { unsafe { fn f() { unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $v; } } @@ -93,7 +93,7 @@ macro_rules! const_generic_in_struct { const M: i32 = { 1; unsafe { $inside_unsafe } - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe }, const N: i32 = { $outside_unsafe }, >; @@ -108,7 +108,7 @@ macro_rules! fn_with_const_generic { fn f() { $outside_unsafe; unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $inside_unsafe; } } @@ -120,7 +120,7 @@ macro_rules! fn_with_const_generic { macro_rules! variables { ($inside_unsafe:expr, $outside_unsafe:expr) => { unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $inside_unsafe; let inside_unsafe = 1; inside_unsafe; @@ -135,7 +135,7 @@ macro_rules! variables { macro_rules! multiple_matchers { ($inside_unsafe:expr, $outside_unsafe:expr) => { unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $inside_unsafe; } $outside_unsafe; @@ -144,7 +144,7 @@ macro_rules! multiple_matchers { $( $v; unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $x; } );+ @@ -156,11 +156,11 @@ macro_rules! multiple_unsafe_blocks { ($w:expr, $x:expr, $y:expr) => { $w; unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $x; } unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $x; $y; } @@ -169,7 +169,7 @@ macro_rules! multiple_unsafe_blocks { pub macro macro2_0($v:expr) { unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $v; } } @@ -220,7 +220,7 @@ macro_rules! unsafe_from_root_ctxt { macro_rules! nested_macro_helper { ($v:expr) => {{ unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe $v; } }}; @@ -230,7 +230,7 @@ macro_rules! nested_macro_helper { macro_rules! nested_macros { ($v:expr, $v2:expr) => {{ unsafe { - //~^ ERROR: this macro expands metavariables in an unsafe block + //~^ macro_metavars_in_unsafe nested_macro_helper!($v); $v; } @@ -243,6 +243,7 @@ pub mod issue13219 { ($e:expr) => { // Metavariable in a block tail expression unsafe { $e } + //~^ macro_metavars_in_unsafe }; } pub fn f(p: *const i32) -> i32 { diff --git a/tests/ui-toml/min_ident_chars/min_ident_chars.rs b/tests/ui-toml/min_ident_chars/min_ident_chars.rs index ded3c72c3e04..385e23d69bcd 100644 --- a/tests/ui-toml/min_ident_chars/min_ident_chars.rs +++ b/tests/ui-toml/min_ident_chars/min_ident_chars.rs @@ -4,19 +4,27 @@ extern crate extern_types; use extern_types::{Aaa, LONGER, M, N as W}; +//~^ min_ident_chars pub const N: u32 = 0; +//~^ min_ident_chars pub const LONG: u32 = 32; struct Owo { Uwu: u128, aaa: Aaa, + //~^ min_ident_chars } fn main() { let wha = 1; let vvv = 1; + //~^ min_ident_chars let uuu = 1; + //~^ min_ident_chars let (mut a, mut b) = (1, 2); + //~^ min_ident_chars + //~| min_ident_chars for i in 0..1000 {} + //~^ min_ident_chars } diff --git a/tests/ui-toml/min_ident_chars/min_ident_chars.stderr b/tests/ui-toml/min_ident_chars/min_ident_chars.stderr index 63a057aca279..be795f4daff2 100644 --- a/tests/ui-toml/min_ident_chars/min_ident_chars.stderr +++ b/tests/ui-toml/min_ident_chars/min_ident_chars.stderr @@ -8,43 +8,43 @@ LL | use extern_types::{Aaa, LONGER, M, N as W}; = help: to override `-D warnings` add `#[allow(clippy::min_ident_chars)]` error: this ident is too short (1 <= 3) - --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:8:11 + --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:9:11 | LL | pub const N: u32 = 0; | ^ error: this ident is too short (3 <= 3) - --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:13:5 + --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:15:5 | LL | aaa: Aaa, | ^^^ error: this ident is too short (3 <= 3) - --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:18:9 + --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:21:9 | LL | let vvv = 1; | ^^^ error: this ident is too short (3 <= 3) - --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:19:9 + --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:23:9 | LL | let uuu = 1; | ^^^ error: this ident is too short (1 <= 3) - --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:20:14 + --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:25:14 | LL | let (mut a, mut b) = (1, 2); | ^ error: this ident is too short (1 <= 3) - --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:20:21 + --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:25:21 | LL | let (mut a, mut b) = (1, 2); | ^ error: this ident is too short (1 <= 3) - --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:21:9 + --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:28:9 | LL | for i in 0..1000 {} | ^ diff --git a/tests/ui-toml/min_rust_version/min_rust_version.fixed b/tests/ui-toml/min_rust_version/min_rust_version.fixed index 497f783087a1..685f77b7efe8 100644 --- a/tests/ui-toml/min_rust_version/min_rust_version.fixed +++ b/tests/ui-toml/min_rust_version/min_rust_version.fixed @@ -72,6 +72,7 @@ fn check_index_refutable_slice() { fn map_clone_suggest_copied() { // This should still trigger the lint but suggest `cloned()` instead of `copied()` let _: Option = Some(&16).cloned(); + //~^ map_clone } fn borrow_as_ptr() { diff --git a/tests/ui-toml/min_rust_version/min_rust_version.rs b/tests/ui-toml/min_rust_version/min_rust_version.rs index 6e7874108a34..0bf073af8903 100644 --- a/tests/ui-toml/min_rust_version/min_rust_version.rs +++ b/tests/ui-toml/min_rust_version/min_rust_version.rs @@ -72,6 +72,7 @@ fn check_index_refutable_slice() { fn map_clone_suggest_copied() { // This should still trigger the lint but suggest `cloned()` instead of `copied()` let _: Option = Some(&16).map(|b| *b); + //~^ map_clone } fn borrow_as_ptr() { diff --git a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed index a6072111dc06..3e882f496985 100644 --- a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed +++ b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed @@ -3,14 +3,20 @@ use std::alloc as colla; use std::option::Option as Maybe; use std::process::{Child as Kid, exit as goodbye}; +//~^ missing_enforced_import_renames use std::thread::sleep as thread_sleep; +//~^ missing_enforced_import_renames #[rustfmt::skip] use std::{ any::{type_name as ident, Any}, + //~^ missing_enforced_import_renames clone as foo, + //~^ missing_enforced_import_renames sync :: Mutex as StdMutie, + //~^ missing_enforced_import_renames }; fn main() { use std::collections::BTreeMap as Map; + //~^ missing_enforced_import_renames } diff --git a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs index c2b61aab5b3c..32255af5117f 100644 --- a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs +++ b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs @@ -3,14 +3,20 @@ use std::alloc as colla; use std::option::Option as Maybe; use std::process::{Child as Kid, exit as wrong_exit}; +//~^ missing_enforced_import_renames use std::thread::sleep; +//~^ missing_enforced_import_renames #[rustfmt::skip] use std::{ any::{type_name, Any}, + //~^ missing_enforced_import_renames clone, + //~^ missing_enforced_import_renames sync :: Mutex, + //~^ missing_enforced_import_renames }; fn main() { use std::collections::BTreeMap as OopsWrongRename; + //~^ missing_enforced_import_renames } diff --git a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr index d3bb07ec47fd..982b144eb872 100644 --- a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr +++ b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr @@ -8,31 +8,31 @@ LL | use std::process::{Child as Kid, exit as wrong_exit}; = help: to override `-D warnings` add `#[allow(clippy::missing_enforced_import_renames)]` error: this import should be renamed - --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:6:1 + --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:7:1 | LL | use std::thread::sleep; | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `use std::thread::sleep as thread_sleep` error: this import should be renamed - --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:9:11 + --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:11:11 | LL | any::{type_name, Any}, | ^^^^^^^^^ help: try: `type_name as ident` error: this import should be renamed - --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:10:5 + --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:13:5 | LL | clone, | ^^^^^ help: try: `clone as foo` error: this import should be renamed - --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:11:5 + --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:15:5 | LL | sync :: Mutex, | ^^^^^^^^^^^^^ help: try: `sync :: Mutex as StdMutie` error: this import should be renamed - --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:15:5 + --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:20:5 | LL | use std::collections::BTreeMap as OopsWrongRename; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `use std::collections::BTreeMap as Map` diff --git a/tests/ui-toml/module_inception/module_inception.rs b/tests/ui-toml/module_inception/module_inception.rs index cd495c884a43..94866a7e81bf 100644 --- a/tests/ui-toml/module_inception/module_inception.rs +++ b/tests/ui-toml/module_inception/module_inception.rs @@ -4,11 +4,13 @@ pub mod foo2 { pub mod bar2 { pub mod bar2 { + //~^ module_inception pub mod foo2 {} } pub mod foo2 {} } pub mod foo2 { + //~^ module_inception pub mod bar2 {} } } diff --git a/tests/ui-toml/module_inception/module_inception.stderr b/tests/ui-toml/module_inception/module_inception.stderr index 75e78c829226..efef1d010233 100644 --- a/tests/ui-toml/module_inception/module_inception.stderr +++ b/tests/ui-toml/module_inception/module_inception.stderr @@ -2,6 +2,7 @@ error: module has the same name as its containing module --> tests/ui-toml/module_inception/module_inception.rs:6:9 | LL | / pub mod bar2 { +LL | | LL | | pub mod foo2 {} LL | | } | |_________^ @@ -10,9 +11,10 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::module_inception)]` error: module has the same name as its containing module - --> tests/ui-toml/module_inception/module_inception.rs:11:5 + --> tests/ui-toml/module_inception/module_inception.rs:12:5 | LL | / pub mod foo2 { +LL | | LL | | pub mod bar2 {} LL | | } | |_____^ diff --git a/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs b/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs index 27d27564baf3..7e42f095cbba 100644 --- a/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs +++ b/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs @@ -4,7 +4,11 @@ fn main() { let a = -1; let b = 2; let c = a % b == 0; + //~^ modulo_arithmetic let c = a % b != 0; + //~^ modulo_arithmetic let c = 0 == a % b; + //~^ modulo_arithmetic let c = 0 != a % b; + //~^ modulo_arithmetic } diff --git a/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.stderr b/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.stderr index 8d01b66522c6..02286f66f4d1 100644 --- a/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.stderr +++ b/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.stderr @@ -10,7 +10,7 @@ LL | let c = a % b == 0; = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]` error: you are using modulo operator on types that might have different signs - --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:7:13 + --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:8:13 | LL | let c = a % b != 0; | ^^^^^ @@ -19,7 +19,7 @@ LL | let c = a % b != 0; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:8:18 + --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:10:18 | LL | let c = 0 == a % b; | ^^^^^ @@ -28,7 +28,7 @@ LL | let c = 0 == a % b; = note: or consider using `rem_euclid` or similar function error: you are using modulo operator on types that might have different signs - --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:9:18 + --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:12:18 | LL | let c = 0 != a % b; | ^^^^^ diff --git a/tests/ui-toml/mut_key/mut_key.rs b/tests/ui-toml/mut_key/mut_key.rs index 3a8e3741e20c..b23c2340b7d6 100644 --- a/tests/ui-toml/mut_key/mut_key.rs +++ b/tests/ui-toml/mut_key/mut_key.rs @@ -1,4 +1,5 @@ //@compile-flags: --crate-name mut_key +//@check-pass #![warn(clippy::mutable_key_type)] diff --git a/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.fixed b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.fixed index fd20bdff6e25..6b386046efa7 100644 --- a/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.fixed +++ b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.fixed @@ -4,6 +4,9 @@ fn main() { r#"\aaa"#; r#"\aaa"#; + //~^ needless_raw_string_hashes r#"Hello "world"!"#; + //~^ needless_raw_string_hashes r####" "### "## "# "####; + //~^ needless_raw_string_hashes } diff --git a/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs index 3c6c24637006..f928e590d45c 100644 --- a/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs +++ b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs @@ -4,6 +4,9 @@ fn main() { r#"\aaa"#; r##"\aaa"##; + //~^ needless_raw_string_hashes r##"Hello "world"!"##; + //~^ needless_raw_string_hashes r######" "### "## "# "######; + //~^ needless_raw_string_hashes } diff --git a/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.stderr b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.stderr index 421ad66e4c96..43d02837c6cc 100644 --- a/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.stderr +++ b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.stderr @@ -13,7 +13,7 @@ LL + r#"\aaa"#; | error: unnecessary hashes around raw string literal - --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:7:5 + --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:8:5 | LL | r##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + r#"Hello "world"!"#; | error: unnecessary hashes around raw string literal - --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:8:5 + --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:10:5 | LL | r######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed index 673106f0b12d..8da607ec6584 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed @@ -16,6 +16,7 @@ proc_macro_derive::foo_bar!(); macro_rules! test { () => { vec![0, 0, 0] + //~^ nonstandard_macro_braces }; } @@ -41,10 +42,15 @@ macro_rules! printlnfoo { #[rustfmt::skip] fn main() { let _ = vec![1, 2, 3]; + //~^ nonstandard_macro_braces let _ = format!("ugh {} stop being such a good compiler", "hello"); + //~^ nonstandard_macro_braces let _ = matches!({}, ()); + //~^ nonstandard_macro_braces let _ = quote!{let x = 1;}; + //~^ nonstandard_macro_braces let _ = quote::quote!{match match match}; + //~^ nonstandard_macro_braces let _ = test!(); // trigger when macro def is inside our own crate let _ = vec![1,2,3]; @@ -54,8 +60,10 @@ fn main() { let _ = test2!["{}{}{}", 1, 2, 3]; let _: type_pos![usize] = vec![]; + //~^ nonstandard_macro_braces eprint!["test if user config overrides defaults"]; + //~^ nonstandard_macro_braces printlnfoo!["test if printlnfoo is triggered by println"]; } diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs index b9c69037be07..e35844a209fa 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs @@ -16,6 +16,7 @@ proc_macro_derive::foo_bar!(); macro_rules! test { () => { vec!{0, 0, 0} + //~^ nonstandard_macro_braces }; } @@ -41,10 +42,15 @@ macro_rules! printlnfoo { #[rustfmt::skip] fn main() { let _ = vec! {1, 2, 3}; + //~^ nonstandard_macro_braces let _ = format!["ugh {} stop being such a good compiler", "hello"]; + //~^ nonstandard_macro_braces let _ = matches!{{}, ()}; + //~^ nonstandard_macro_braces let _ = quote!(let x = 1;); + //~^ nonstandard_macro_braces let _ = quote::quote!(match match match); + //~^ nonstandard_macro_braces let _ = test!(); // trigger when macro def is inside our own crate let _ = vec![1,2,3]; @@ -54,8 +60,10 @@ fn main() { let _ = test2!["{}{}{}", 1, 2, 3]; let _: type_pos!(usize) = vec![]; + //~^ nonstandard_macro_braces eprint!("test if user config overrides defaults"); + //~^ nonstandard_macro_braces printlnfoo!["test if printlnfoo is triggered by println"]; } diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr index c2c76e444cfe..fda6addc7aa3 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr @@ -1,5 +1,5 @@ error: use of irregular braces for `vec!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:43:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:44:13 | LL | let _ = vec! {1, 2, 3}; | ^^^^^^^^^^^^^^ help: consider writing: `vec![1, 2, 3]` @@ -8,25 +8,25 @@ LL | let _ = vec! {1, 2, 3}; = help: to override `-D warnings` add `#[allow(clippy::nonstandard_macro_braces)]` error: use of irregular braces for `format!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:44:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:46:13 | LL | let _ = format!["ugh {} stop being such a good compiler", "hello"]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `format!("ugh {} stop being such a good compiler", "hello")` error: use of irregular braces for `matches!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:45:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:48:13 | LL | let _ = matches!{{}, ()}; | ^^^^^^^^^^^^^^^^ help: consider writing: `matches!({}, ())` error: use of irregular braces for `quote!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:46:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:50:13 | LL | let _ = quote!(let x = 1;); | ^^^^^^^^^^^^^^^^^^ help: consider writing: `quote!{let x = 1;}` error: use of irregular braces for `quote::quote!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:47:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:52:13 | LL | let _ = quote::quote!(match match match); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `quote::quote!{match match match}` @@ -43,13 +43,13 @@ LL | let _ = test!(); // trigger when macro def is inside our own crate = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error: use of irregular braces for `type_pos!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:56:12 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:62:12 | LL | let _: type_pos!(usize) = vec![]; | ^^^^^^^^^^^^^^^^ help: consider writing: `type_pos![usize]` error: use of irregular braces for `eprint!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:58:5 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:65:5 | LL | eprint!("test if user config overrides defaults"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `eprint!["test if user config overrides defaults"]` diff --git a/tests/ui-toml/panic/panic.rs b/tests/ui-toml/panic/panic.rs index b6264c950e45..7bdc896453d8 100644 --- a/tests/ui-toml/panic/panic.rs +++ b/tests/ui-toml/panic/panic.rs @@ -10,11 +10,13 @@ fn main() { match a { Enam::A => {}, _ => panic!(""), + //~^ panic } } fn issue_13292() { panic_any("should lint") + //~^ panic } #[test] diff --git a/tests/ui-toml/panic/panic.stderr b/tests/ui-toml/panic/panic.stderr index a034207d919f..5dfecfe51ddb 100644 --- a/tests/ui-toml/panic/panic.stderr +++ b/tests/ui-toml/panic/panic.stderr @@ -8,7 +8,7 @@ LL | _ => panic!(""), = help: to override `-D warnings` add `#[allow(clippy::panic)]` error: `panic_any` should not be present in production code - --> tests/ui-toml/panic/panic.rs:17:5 + --> tests/ui-toml/panic/panic.rs:18:5 | LL | panic_any("should lint") | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs b/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs index a34b15f4ac9a..455623cec43e 100644 --- a/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs +++ b/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs @@ -1,3 +1,5 @@ +//@check-pass + #![warn(clippy::path_ends_with_ext)] use std::path::Path; diff --git a/tests/ui-toml/print_macro/print_macro.rs b/tests/ui-toml/print_macro/print_macro.rs index 3a8b30cca36a..74f3ba7e7fa9 100644 --- a/tests/ui-toml/print_macro/print_macro.rs +++ b/tests/ui-toml/print_macro/print_macro.rs @@ -4,7 +4,9 @@ fn foo(n: u32) { print!("{n}"); + //~^ print_stdout eprint!("{n}"); + //~^ print_stderr } #[test] diff --git a/tests/ui-toml/print_macro/print_macro.stderr b/tests/ui-toml/print_macro/print_macro.stderr index fea11107c7ca..835af7ef8c72 100644 --- a/tests/ui-toml/print_macro/print_macro.stderr +++ b/tests/ui-toml/print_macro/print_macro.stderr @@ -8,7 +8,7 @@ LL | print!("{n}"); = help: to override `-D warnings` add `#[allow(clippy::print_stdout)]` error: use of `eprint!` - --> tests/ui-toml/print_macro/print_macro.rs:7:5 + --> tests/ui-toml/print_macro/print_macro.rs:8:5 | LL | eprint!("{n}"); | ^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs b/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs index cd53f5044599..6a1d2b51abc8 100644 --- a/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs +++ b/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs @@ -11,9 +11,11 @@ mod my_mod { /// some docs pub(crate) fn crate_with_docs() {} pub(crate) fn crate_no_docs() {} + //~^ missing_docs_in_private_items /// some docs pub(super) fn super_with_docs() {} pub(super) fn super_no_docs() {} + //~^ missing_docs_in_private_items mod my_sub { /// some docs @@ -22,6 +24,7 @@ mod my_mod { /// some docs pub(crate) fn sub_crate_with_docs() {} pub(crate) fn sub_crate_no_docs() {} + //~^ missing_docs_in_private_items /// some docs pub(super) fn sub_super_with_docs() {} pub(super) fn sub_super_no_docs() {} @@ -32,15 +35,18 @@ mod my_mod { /// some docs pub(crate) crate_field_with_docs: (), pub(crate) crate_field_no_docs: (), + //~^ missing_docs_in_private_items /// some docs priv_field_with_docs: (), priv_field_no_docs: (), } pub(crate) struct CrateStructNoDocs { + //~^ missing_docs_in_private_items /// some docs pub(crate) crate_field_with_docs: (), pub(crate) crate_field_no_docs: (), + //~^ missing_docs_in_private_items /// some docs priv_field_with_docs: (), priv_field_no_docs: (), @@ -50,6 +56,7 @@ mod my_mod { /// some docs type CrateTypedefWithDocs = String; type CrateTypedefNoDocs = String; +//~^ missing_docs_in_private_items /// some docs pub type PubTypedefWithDocs = String; pub type PubTypedefNoDocs = String; diff --git a/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr b/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr index 9cf79fccb60b..0d70276de42d 100644 --- a/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr +++ b/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr @@ -8,43 +8,43 @@ LL | pub(crate) fn crate_no_docs() {} = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` error: missing documentation for a function - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:16:5 + --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:17:5 | LL | pub(super) fn super_no_docs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:24:9 + --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:26:9 | LL | pub(crate) fn sub_crate_no_docs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a struct field - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:34:9 + --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:37:9 | LL | pub(crate) crate_field_no_docs: (), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a struct - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:40:5 + --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:44:5 | LL | / pub(crate) struct CrateStructNoDocs { +LL | | LL | | /// some docs LL | | pub(crate) crate_field_with_docs: (), -LL | | pub(crate) crate_field_no_docs: (), ... | LL | | priv_field_no_docs: (), LL | | } | |_____^ error: missing documentation for a struct field - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:43:9 + --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:48:9 | LL | pub(crate) crate_field_no_docs: (), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a type alias - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:52:1 + --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:58:1 | LL | type CrateTypedefNoDocs = String; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/pub_underscore_fields/pub_underscore_fields.all_pub_fields.stderr b/tests/ui-toml/pub_underscore_fields/pub_underscore_fields.all_pub_fields.stderr index dd1035e53fa9..335ff403d062 100644 --- a/tests/ui-toml/pub_underscore_fields/pub_underscore_fields.all_pub_fields.stderr +++ b/tests/ui-toml/pub_underscore_fields/pub_underscore_fields.all_pub_fields.stderr @@ -9,7 +9,7 @@ LL | pub _b: u8, = help: to override `-D warnings` add `#[allow(clippy::pub_underscore_fields)]` error: field marked as public but also inferred as unused because it's prefixed with `_` - --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:23:13 + --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:24:13 | LL | pub(in crate::inner) _f: Option<()>, | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | pub(in crate::inner) _f: Option<()>, = help: consider removing the underscore, or making the field private error: field marked as public but also inferred as unused because it's prefixed with `_` - --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:27:13 + --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:29:13 | LL | pub _g: String, | ^^^^^^ @@ -25,7 +25,7 @@ LL | pub _g: String, = help: consider removing the underscore, or making the field private error: field marked as public but also inferred as unused because it's prefixed with `_` - --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:34:9 + --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:37:9 | LL | pub _a: usize, | ^^^^^^ @@ -33,7 +33,7 @@ LL | pub _a: usize, = help: consider removing the underscore, or making the field private error: field marked as public but also inferred as unused because it's prefixed with `_` - --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:41:9 + --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:45:9 | LL | pub _c: i64, | ^^^^^^ @@ -41,7 +41,7 @@ LL | pub _c: i64, = help: consider removing the underscore, or making the field private error: field marked as public but also inferred as unused because it's prefixed with `_` - --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:44:9 + --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:49:9 | LL | pub _e: Option, | ^^^^^^ @@ -49,7 +49,7 @@ LL | pub _e: Option, = help: consider removing the underscore, or making the field private error: field marked as public but also inferred as unused because it's prefixed with `_` - --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:57:9 + --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:63:9 | LL | pub(crate) _b: Option, | ^^^^^^^^^^^^^ diff --git a/tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs b/tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs index 4ee8dbb88347..2c1d3cf23647 100644 --- a/tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs +++ b/tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs @@ -13,6 +13,7 @@ pub mod inner { pub struct PubSuper { pub(super) a: usize, pub _b: u8, + //~^ pub_underscore_fields _c: i32, pub _mark: marker::PhantomData, } @@ -21,10 +22,12 @@ pub mod inner { pub struct PubModVisibility { pub(in crate::inner) e: bool, pub(in crate::inner) _f: Option<()>, + //~[all_pub_fields]^ pub_underscore_fields } struct PrivateStructPubField { pub _g: String, + //~[all_pub_fields]^ pub_underscore_fields } } } @@ -32,6 +35,7 @@ pub mod inner { fn main() { pub struct StructWithOneViolation { pub _a: usize, + //~[all_pub_fields]^ pub_underscore_fields } // should handle structs with multiple violations @@ -39,9 +43,11 @@ fn main() { a: u8, _b: usize, pub _c: i64, + //~[all_pub_fields]^ pub_underscore_fields #[doc(hidden)] pub d: String, pub _e: Option, + //~[all_pub_fields]^ pub_underscore_fields } // shouldn't warn on anonymous fields @@ -55,6 +61,7 @@ fn main() { pub struct PubCrate { pub(crate) a: String, pub(crate) _b: Option, + //~[all_pub_fields]^ pub_underscore_fields } // shouldn't warn on fields named pub diff --git a/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr b/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr index 2d700f607592..e7e526628ce7 100644 --- a/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr +++ b/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr @@ -20,13 +20,13 @@ LL | fn foo(&self, i_dont_wanna_use_your_name: u8) {} // only lint in `exten | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the default name: `val` error: renamed function parameter of trait impl - --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:55:31 + --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:57:31 | LL | fn hash(&self, states: &mut H) { | ^^^^^^ help: consider using the default name: `state` error: renamed function parameters of trait impl - --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:59:30 + --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:61:30 | LL | fn hash_slice(date: &[Self], states: &mut H) { | ^^^^ ^^^^^^ @@ -37,7 +37,7 @@ LL | fn hash_slice(data: &[Self], state: &mut H) { | ~~~~ ~~~~~ error: renamed function parameter of trait impl - --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:80:18 + --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:82:18 | LL | fn add(self, b: B) -> C { | ^ help: consider using the default name: `rhs` diff --git a/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr b/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr index e57554fa613a..46e5f34b1761 100644 --- a/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr +++ b/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr @@ -14,13 +14,13 @@ LL | fn ne(&self, rhs: &Self) -> bool { | ^^^ help: consider using the default name: `other` error: renamed function parameter of trait impl - --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:55:31 + --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:57:31 | LL | fn hash(&self, states: &mut H) { | ^^^^^^ help: consider using the default name: `state` error: renamed function parameters of trait impl - --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:59:30 + --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:61:30 | LL | fn hash_slice(date: &[Self], states: &mut H) { | ^^^^ ^^^^^^ diff --git a/tests/ui-toml/renamed_function_params/renamed_function_params.rs b/tests/ui-toml/renamed_function_params/renamed_function_params.rs index f3eb910abbd6..26ca1d860947 100644 --- a/tests/ui-toml/renamed_function_params/renamed_function_params.rs +++ b/tests/ui-toml/renamed_function_params/renamed_function_params.rs @@ -28,11 +28,11 @@ impl std::convert::From for String { } impl PartialEq for B { fn eq(&self, rhs: &Self) -> bool { - //~^ ERROR: renamed function parameter of trait impl + //~^ renamed_function_params self.0 == rhs.0 } fn ne(&self, rhs: &Self) -> bool { - //~^ ERROR: renamed function parameter of trait impl + //~^ renamed_function_params self.0 != rhs.0 } } @@ -46,6 +46,8 @@ trait MyTrait { impl MyTrait for B { fn foo(&self, i_dont_wanna_use_your_name: u8) {} // only lint in `extend` + // + //~[default]^^ renamed_function_params fn bar(_a: u8, _: u8) {} fn baz(self, val: u8) {} fn quz(&self, val: u8) {} @@ -53,11 +55,11 @@ impl MyTrait for B { impl Hash for B { fn hash(&self, states: &mut H) { - //~^ ERROR: renamed function parameter of trait impl + //~^ renamed_function_params self.0.hash(states); } fn hash_slice(date: &[Self], states: &mut H) { - //~^ ERROR: renamed function parameters of trait impl + //~^ renamed_function_params for d in date { d.hash(states); } @@ -78,6 +80,7 @@ enum C { impl std::ops::Add for C { type Output = C; fn add(self, b: B) -> C { + //~[default]^ renamed_function_params // only lint in `extend` C::B(b.0) } diff --git a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed index 6546981bd81c..f0dab64d78c6 100644 --- a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed +++ b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed @@ -13,4 +13,5 @@ mod wrapper { fn main() { let _ = wrapper::String::from("x"); + //~^ disallowed_types } diff --git a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs index d76f1af481de..2585e6f90fc4 100644 --- a/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs +++ b/tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs @@ -13,4 +13,5 @@ mod wrapper { fn main() { let _ = String::from("x"); + //~^ disallowed_types } diff --git a/tests/ui-toml/semicolon_block/both.fixed b/tests/ui-toml/semicolon_block/both.fixed index 306cd23c8239..33f490fad6e8 100644 --- a/tests/ui-toml/semicolon_block/both.fixed +++ b/tests/ui-toml/semicolon_block/both.fixed @@ -40,12 +40,15 @@ fn main() { unsafe { unit_fn_block() }; { unit_fn_block() }; + //~^ semicolon_outside_block unsafe { unit_fn_block() }; + //~^ semicolon_outside_block { unit_fn_block(); }; unsafe { unit_fn_block(); }; { + //~^ semicolon_inside_block unit_fn_block(); unit_fn_block(); } @@ -60,6 +63,7 @@ fn main() { { m!(()) }; { m!(()) }; + //~^ semicolon_outside_block { m!(()); }; m!(0); m!(1); diff --git a/tests/ui-toml/semicolon_block/both.rs b/tests/ui-toml/semicolon_block/both.rs index b9f012cfbb0d..8e650979e6c9 100644 --- a/tests/ui-toml/semicolon_block/both.rs +++ b/tests/ui-toml/semicolon_block/both.rs @@ -40,12 +40,15 @@ fn main() { unsafe { unit_fn_block() }; { unit_fn_block(); } + //~^ semicolon_outside_block unsafe { unit_fn_block(); } + //~^ semicolon_outside_block { unit_fn_block(); }; unsafe { unit_fn_block(); }; { + //~^ semicolon_inside_block unit_fn_block(); unit_fn_block() }; @@ -60,6 +63,7 @@ fn main() { { m!(()) }; { m!(()); } + //~^ semicolon_outside_block { m!(()); }; m!(0); m!(1); diff --git a/tests/ui-toml/semicolon_block/both.stderr b/tests/ui-toml/semicolon_block/both.stderr index 7d7749b282f0..c2aad39b6832 100644 --- a/tests/ui-toml/semicolon_block/both.stderr +++ b/tests/ui-toml/semicolon_block/both.stderr @@ -13,7 +13,7 @@ LL + { unit_fn_block() }; | error: consider moving the `;` outside the block for consistent formatting - --> tests/ui-toml/semicolon_block/both.rs:43:5 + --> tests/ui-toml/semicolon_block/both.rs:44:5 | LL | unsafe { unit_fn_block(); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,9 +25,10 @@ LL + unsafe { unit_fn_block() }; | error: consider moving the `;` inside the block for consistent formatting - --> tests/ui-toml/semicolon_block/both.rs:48:5 + --> tests/ui-toml/semicolon_block/both.rs:50:5 | LL | / { +LL | | LL | | unit_fn_block(); LL | | unit_fn_block() LL | | }; @@ -42,7 +43,7 @@ LL ~ } | error: consider moving the `;` outside the block for consistent formatting - --> tests/ui-toml/semicolon_block/both.rs:62:5 + --> tests/ui-toml/semicolon_block/both.rs:65:5 | LL | { m!(()); } | ^^^^^^^^^^^ diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed b/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed index 5b7f8e00c7a0..7b1af090e933 100644 --- a/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed @@ -45,6 +45,7 @@ fn main() { unsafe { unit_fn_block(); }; { + //~^ semicolon_inside_block unit_fn_block(); unit_fn_block(); } diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.rs b/tests/ui-toml/semicolon_block/semicolon_inside_block.rs index 3a81661cd16f..e243d4514da2 100644 --- a/tests/ui-toml/semicolon_block/semicolon_inside_block.rs +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.rs @@ -45,6 +45,7 @@ fn main() { unsafe { unit_fn_block(); }; { + //~^ semicolon_inside_block unit_fn_block(); unit_fn_block() }; diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr b/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr index b1638e40206d..4d4e43f6b9c1 100644 --- a/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr @@ -2,6 +2,7 @@ error: consider moving the `;` inside the block for consistent formatting --> tests/ui-toml/semicolon_block/semicolon_inside_block.rs:47:5 | LL | / { +LL | | LL | | unit_fn_block(); LL | | unit_fn_block() LL | | }; diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed b/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed index 14604eaea7e4..f6aa49fc8868 100644 --- a/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed @@ -39,7 +39,9 @@ fn main() { unsafe { unit_fn_block() }; { unit_fn_block() }; + //~^ semicolon_outside_block unsafe { unit_fn_block() }; + //~^ semicolon_outside_block { unit_fn_block(); }; unsafe { unit_fn_block(); }; @@ -59,6 +61,7 @@ fn main() { { m!(()) }; { m!(()) }; + //~^ semicolon_outside_block { m!(()); }; m!(0); m!(1); diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.rs b/tests/ui-toml/semicolon_block/semicolon_outside_block.rs index c767201469ab..0d25a29627fb 100644 --- a/tests/ui-toml/semicolon_block/semicolon_outside_block.rs +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.rs @@ -39,7 +39,9 @@ fn main() { unsafe { unit_fn_block() }; { unit_fn_block(); } + //~^ semicolon_outside_block unsafe { unit_fn_block(); } + //~^ semicolon_outside_block { unit_fn_block(); }; unsafe { unit_fn_block(); }; @@ -59,6 +61,7 @@ fn main() { { m!(()) }; { m!(()); } + //~^ semicolon_outside_block { m!(()); }; m!(0); m!(1); diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr b/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr index 7bcb63a6abbb..18400da07a89 100644 --- a/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr @@ -13,7 +13,7 @@ LL + { unit_fn_block() }; | error: consider moving the `;` outside the block for consistent formatting - --> tests/ui-toml/semicolon_block/semicolon_outside_block.rs:42:5 + --> tests/ui-toml/semicolon_block/semicolon_outside_block.rs:43:5 | LL | unsafe { unit_fn_block(); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + unsafe { unit_fn_block() }; | error: consider moving the `;` outside the block for consistent formatting - --> tests/ui-toml/semicolon_block/semicolon_outside_block.rs:61:5 + --> tests/ui-toml/semicolon_block/semicolon_outside_block.rs:63:5 | LL | { m!(()); } | ^^^^^^^^^^^ diff --git a/tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs b/tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs index 90c2439dc34f..08a8e1186d5c 100644 --- a/tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs +++ b/tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs @@ -9,6 +9,7 @@ pub struct NoGeneric { } unsafe impl Send for NoGeneric {} +//~^ non_send_fields_in_send_ty pub struct MultiField { field1: T, @@ -17,6 +18,7 @@ pub struct MultiField { } unsafe impl Send for MultiField {} +//~^ non_send_fields_in_send_ty pub enum MyOption { MySome(T), @@ -24,6 +26,7 @@ pub enum MyOption { } unsafe impl Send for MyOption {} +//~^ non_send_fields_in_send_ty // All fields are disallowed when raw pointer heuristic is off extern "C" { @@ -39,5 +42,6 @@ pub struct HeuristicTest { } unsafe impl Send for HeuristicTest {} +//~^ non_send_fields_in_send_ty fn main() {} diff --git a/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr b/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr index bd1b75458fd1..cdb4a2f44513 100644 --- a/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr +++ b/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr @@ -14,75 +14,75 @@ LL | rc_is_not_send: Rc, = help: to override `-D warnings` add `#[allow(clippy::non_send_fields_in_send_ty)]` error: some fields in `MultiField` are not safe to be sent to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:19:1 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:20:1 | LL | unsafe impl Send for MultiField {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: it is not safe to send field `field1` to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:14:5 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:15:5 | LL | field1: T, | ^^^^^^^^^ = help: add `T: Send` bound in `Send` impl note: it is not safe to send field `field2` to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:15:5 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:16:5 | LL | field2: T, | ^^^^^^^^^ = help: add `T: Send` bound in `Send` impl note: it is not safe to send field `field3` to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:16:5 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:17:5 | LL | field3: T, | ^^^^^^^^^ = help: add `T: Send` bound in `Send` impl error: some fields in `MyOption` are not safe to be sent to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:26:1 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:28:1 | LL | unsafe impl Send for MyOption {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: it is not safe to send field `0` to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:22:12 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:24:12 | LL | MySome(T), | ^ = help: add `T: Send` bound in `Send` impl error: some fields in `HeuristicTest` are not safe to be sent to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:41:1 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:44:1 | LL | unsafe impl Send for HeuristicTest {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: it is not safe to send field `field1` to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:34:5 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:37:5 | LL | field1: Vec<*const NonSend>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use a thread-safe type that implements `Send` note: it is not safe to send field `field2` to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:35:5 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:38:5 | LL | field2: [*const NonSend; 3], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use a thread-safe type that implements `Send` note: it is not safe to send field `field3` to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:36:5 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:39:5 | LL | field3: (*const NonSend, *const NonSend, *const NonSend), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use a thread-safe type that implements `Send` note: it is not safe to send field `field4` to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:37:5 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:40:5 | LL | field4: (*const NonSend, Rc), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use a thread-safe type that implements `Send` note: it is not safe to send field `field5` to another thread - --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:38:5 + --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:41:5 | LL | field5: Vec>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/struct_excessive_bools/test.rs b/tests/ui-toml/struct_excessive_bools/test.rs index 32dd80246fab..590cd6eeaa47 100644 --- a/tests/ui-toml/struct_excessive_bools/test.rs +++ b/tests/ui-toml/struct_excessive_bools/test.rs @@ -1,6 +1,7 @@ #![warn(clippy::struct_excessive_bools)] struct S { + //~^ struct_excessive_bools a: bool, } diff --git a/tests/ui-toml/struct_excessive_bools/test.stderr b/tests/ui-toml/struct_excessive_bools/test.stderr index ddf8ec0e5217..d70c76055df8 100644 --- a/tests/ui-toml/struct_excessive_bools/test.stderr +++ b/tests/ui-toml/struct_excessive_bools/test.stderr @@ -2,6 +2,7 @@ error: more than 0 bools in a struct --> tests/ui-toml/struct_excessive_bools/test.rs:3:1 | LL | / struct S { +LL | | LL | | a: bool, LL | | } | |_^ diff --git a/tests/ui-toml/suppress_lint_in_const/test.rs b/tests/ui-toml/suppress_lint_in_const/test.rs index 4613a74b85d8..b077b848837a 100644 --- a/tests/ui-toml/suppress_lint_in_const/test.rs +++ b/tests/ui-toml/suppress_lint_in_const/test.rs @@ -25,6 +25,7 @@ fn main() { let x = [1, 2, 3, 4]; let index: usize = 1; x[index]; + //~^ indexing_slicing x[4]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays. x[1 << 3]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays. @@ -40,15 +41,20 @@ fn main() { let v = vec![0; 5]; v[0]; + //~^ indexing_slicing v[10]; + //~^ indexing_slicing v[1 << 3]; + //~^ indexing_slicing const N: usize = 15; // Out of bounds const M: usize = 3; // In bounds x[N]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays. x[M]; // Ok, should not produce stderr. v[N]; + //~^ indexing_slicing v[M]; + //~^ indexing_slicing } /// An opaque integer representation diff --git a/tests/ui-toml/suppress_lint_in_const/test.stderr b/tests/ui-toml/suppress_lint_in_const/test.stderr index 120f5c35cb03..4c78a6b924cf 100644 --- a/tests/ui-toml/suppress_lint_in_const/test.stderr +++ b/tests/ui-toml/suppress_lint_in_const/test.stderr @@ -9,7 +9,7 @@ LL | x[index]; = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]` error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:42:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5 | LL | v[0]; | ^^^^ @@ -17,7 +17,7 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:45:5 | LL | v[10]; | ^^^^^ @@ -25,7 +25,7 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:44:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:47:5 | LL | v[1 << 3]; | ^^^^^^^^^ @@ -33,7 +33,7 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:50:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:54:5 | LL | v[N]; | ^^^^ @@ -41,7 +41,7 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:51:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:56:5 | LL | v[M]; | ^^^^ diff --git a/tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs b/tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs index 2f86b3eda4c5..6555e4291959 100644 --- a/tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs +++ b/tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs @@ -4,17 +4,24 @@ #![warn(clippy::disallowed_names)] fn test(toto: ()) {} +//~^ disallowed_names fn main() { let toto = 42; + //~^ disallowed_names let tata = 42; + //~^ disallowed_names let titi = 42; + //~^ disallowed_names let tatab = 42; let tatatataic = 42; match (42, Some(1337), Some(0)) { (toto, Some(tata), titi @ Some(_)) => (), + //~^ disallowed_names + //~| disallowed_names + //~| disallowed_names _ => (), } } diff --git a/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr b/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr index 6cd0f9b0d7cb..9096ffca2796 100644 --- a/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr +++ b/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr @@ -8,37 +8,37 @@ LL | fn test(toto: ()) {} = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]` error: use of a disallowed/placeholder name `toto` - --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:9:9 + --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:10:9 | LL | let toto = 42; | ^^^^ error: use of a disallowed/placeholder name `tata` - --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:10:9 + --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:12:9 | LL | let tata = 42; | ^^^^ error: use of a disallowed/placeholder name `titi` - --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:11:9 + --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:14:9 | LL | let titi = 42; | ^^^^ error: use of a disallowed/placeholder name `toto` - --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:17:10 + --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:21:10 | LL | (toto, Some(tata), titi @ Some(_)) => (), | ^^^^ error: use of a disallowed/placeholder name `tata` - --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:17:21 + --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:21:21 | LL | (toto, Some(tata), titi @ Some(_)) => (), | ^^^^ error: use of a disallowed/placeholder name `titi` - --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:17:28 + --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:21:28 | LL | (toto, Some(tata), titi @ Some(_)) => (), | ^^^^ diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs index 0986290bb0e6..dd170d6baf85 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs @@ -31,30 +31,44 @@ mod local_mod { fn main() { let re = Regex::new(r"ab.*c").unwrap(); + //~^ disallowed_methods re.is_match("abc"); + //~^ disallowed_methods let mut a = vec![1, 2, 3, 4]; a.iter().sum::(); + //~^ disallowed_methods a.sort_unstable(); + //~^ disallowed_methods // FIXME(f16_f128): add a clamp test once the function is available let _ = 2.0f32.clamp(3.0f32, 4.0f32); + //~^ disallowed_methods let _ = 2.0f64.clamp(3.0f64, 4.0f64); let indirect: fn(&str) -> Result = Regex::new; + //~^ disallowed_methods let re = indirect(".").unwrap(); let in_call = Box::new(f32::clamp); + //~^ disallowed_methods let in_method_call = ["^", "$"].into_iter().map(Regex::new); + //~^ disallowed_methods // resolve ambiguity between `futures::stream::select_all` the module and the function let same_name_as_module = select_all(vec![empty::<()>()]); + //~^ disallowed_methods local_fn(); + //~^ disallowed_methods local_mod::f(); + //~^ disallowed_methods let s = Struct; s.method(); + //~^ disallowed_methods s.provided_method(); + //~^ disallowed_methods s.implemented_method(); + //~^ disallowed_methods } diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr index edda35d647ab..f7dda81eb936 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr @@ -8,7 +8,7 @@ LL | let re = Regex::new(r"ab.*c").unwrap(); = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]` error: use of a disallowed method `regex::Regex::is_match` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:34:8 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:35:8 | LL | re.is_match("abc"); | ^^^^^^^^ @@ -16,73 +16,73 @@ LL | re.is_match("abc"); = note: no matching allowed error: use of a disallowed method `std::iter::Iterator::sum` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:37:14 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:39:14 | LL | a.iter().sum::(); | ^^^ error: use of a disallowed method `slice::sort_unstable` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:39:7 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:42:7 | LL | a.sort_unstable(); | ^^^^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:42:20 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:46:20 | LL | let _ = 2.0f32.clamp(3.0f32, 4.0f32); | ^^^^^ error: use of a disallowed method `regex::Regex::new` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:45:61 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:50:61 | LL | let indirect: fn(&str) -> Result = Regex::new; | ^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:48:28 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:54:28 | LL | let in_call = Box::new(f32::clamp); | ^^^^^^^^^^ error: use of a disallowed method `regex::Regex::new` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:49:53 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:56:53 | LL | let in_method_call = ["^", "$"].into_iter().map(Regex::new); | ^^^^^^^^^^ error: use of a disallowed method `futures::stream::select_all` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:52:31 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:60:31 | LL | let same_name_as_module = select_all(vec![empty::<()>()]); | ^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_fn` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:54:5 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:63:5 | LL | local_fn(); | ^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_mod::f` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:55:5 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:65:5 | LL | local_mod::f(); | ^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Struct::method` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:57:7 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:68:7 | LL | s.method(); | ^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::provided_method` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:58:7 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:70:7 | LL | s.provided_method(); | ^^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::implemented_method` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:59:7 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:72:7 | LL | s.implemented_method(); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs b/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs index f02bd07cfe7b..82c9abe8beb4 100644 --- a/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs +++ b/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs @@ -5,40 +5,61 @@ extern crate syn; use std::sync as foo; use std::sync::atomic::AtomicU32; +//~^ disallowed_types use std::time::Instant as Sneaky; +//~^ disallowed_types struct HashMap; fn bad_return_type() -> fn() -> Sneaky { + //~^ disallowed_types todo!() } fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {} +//~^ disallowed_types +//~| disallowed_types fn trait_obj(_: &dyn std::io::Read) {} +//~^ disallowed_types fn full_and_single_path_prim(_: usize, _: bool) {} +//~^ disallowed_types +//~| disallowed_types fn const_generics() {} +//~^ disallowed_types struct GenArg([u8; U]); +//~^ disallowed_types static BAD: foo::atomic::AtomicPtr<()> = foo::atomic::AtomicPtr::new(std::ptr::null_mut()); fn ip(_: std::net::Ipv4Addr) {} +//~^ disallowed_types fn listener(_: std::net::TcpListener) {} +//~^ disallowed_types #[allow(clippy::diverging_sub_expression)] fn main() { let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new(); + //~^ disallowed_types + //~| disallowed_types let _ = Sneaky::now(); + //~^ disallowed_types let _ = foo::atomic::AtomicU32::new(0); + //~^ disallowed_types static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1); + //~^ disallowed_types + //~| disallowed_types let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default(); + //~^ disallowed_types let _ = syn::Ident::new("", todo!()); + //~^ disallowed_types let _ = HashMap; let _: usize = 64_usize; + //~^ disallowed_types } mod useless_attribute { diff --git a/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr b/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr index 322cde15526a..18bc36ca1e33 100644 --- a/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr +++ b/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr @@ -8,61 +8,61 @@ LL | use std::sync::atomic::AtomicU32; = help: to override `-D warnings` add `#[allow(clippy::disallowed_types)]` error: use of a disallowed type `std::time::Instant` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:8:1 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:9:1 | LL | use std::time::Instant as Sneaky; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed type `std::time::Instant` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:12:33 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:14:33 | LL | fn bad_return_type() -> fn() -> Sneaky { | ^^^^^^ error: use of a disallowed type `std::time::Instant` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:16:28 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:19:28 | LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {} | ^^^^^^ error: use of a disallowed type `std::sync::atomic::AtomicU32` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:16:39 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:19:39 | LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {} | ^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed type `std::io::Read` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:18:22 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:23:22 | LL | fn trait_obj(_: &dyn std::io::Read) {} | ^^^^^^^^^^^^^ error: use of a disallowed type `std::primitive::usize` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:20:33 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:26:33 | LL | fn full_and_single_path_prim(_: usize, _: bool) {} | ^^^^^ error: use of a disallowed type `bool` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:20:43 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:26:43 | LL | fn full_and_single_path_prim(_: usize, _: bool) {} | ^^^^ error: use of a disallowed type `std::primitive::usize` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:22:28 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:30:28 | LL | fn const_generics() {} | ^^^^^ error: use of a disallowed type `std::primitive::usize` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:24:24 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:33:24 | LL | struct GenArg([u8; U]); | ^^^^^ error: use of a disallowed type `std::net::Ipv4Addr` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:28:10 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:38:10 | LL | fn ip(_: std::net::Ipv4Addr) {} | ^^^^^^^^^^^^^^^^^^ @@ -70,61 +70,61 @@ LL | fn ip(_: std::net::Ipv4Addr) {} = note: no IPv4 allowed error: use of a disallowed type `std::net::TcpListener` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:30:16 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:41:16 | LL | fn listener(_: std::net::TcpListener) {} | ^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed type `std::collections::HashMap` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:34:48 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:46:48 | LL | let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed type `std::collections::HashMap` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:34:12 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:46:12 | LL | let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed type `std::time::Instant` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:35:13 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:49:13 | LL | let _ = Sneaky::now(); | ^^^^^^ error: use of a disallowed type `std::sync::atomic::AtomicU32` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:36:13 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:51:13 | LL | let _ = foo::atomic::AtomicU32::new(0); | ^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed type `std::sync::atomic::AtomicU32` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:37:17 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:53:17 | LL | static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed type `std::sync::atomic::AtomicU32` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:37:48 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:53:48 | LL | static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1); | ^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed type `syn::TypePath` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:38:43 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:56:43 | LL | let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default(); | ^^^^^^^^^^^^^ error: use of a disallowed type `proc_macro2::Ident` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:39:13 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:58:13 | LL | let _ = syn::Ident::new("", todo!()); | ^^^^^^^^^^ error: use of a disallowed type `std::primitive::usize` - --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:41:12 + --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:61:12 | LL | let _: usize = 64_usize; | ^^^^^ diff --git a/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed b/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed index 8092e40ff9f1..d44f5fb84bd5 100644 --- a/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed +++ b/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed @@ -16,9 +16,11 @@ fn main() { let z = 1; Foo { x, y, z: z }; + //~^ inconsistent_struct_constructor Foo { x, + //~^ inconsistent_struct_constructor z: z, ..Default::default() }; @@ -35,6 +37,7 @@ mod field_attributes { BodyVisitor { macro_unsafe_blocks: Vec::new(), #[expect(clippy::bool_to_int_with_if)] // obfuscates the meaning + //~^ inconsistent_struct_constructor expn_depth: if condition { 1 } else { 0 }, }; } @@ -53,6 +56,7 @@ mod cfgs_between_fields { } let s = S { a: 3, + //~^ inconsistent_struct_constructor b: 2, #[cfg(all())] c: 1, @@ -70,6 +74,7 @@ mod cfgs_between_fields { } let s = S { a: 3, + //~^ inconsistent_struct_constructor #[cfg(any())] c: 1, b: 2, diff --git a/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs b/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs index cd1aff966528..77ac2b4e7c11 100644 --- a/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs +++ b/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs @@ -16,9 +16,11 @@ fn main() { let z = 1; Foo { y, x, z: z }; + //~^ inconsistent_struct_constructor Foo { z: z, + //~^ inconsistent_struct_constructor x, ..Default::default() }; @@ -34,6 +36,7 @@ mod field_attributes { fn check_body(condition: bool) { BodyVisitor { #[expect(clippy::bool_to_int_with_if)] // obfuscates the meaning + //~^ inconsistent_struct_constructor expn_depth: if condition { 1 } else { 0 }, macro_unsafe_blocks: Vec::new(), }; @@ -53,6 +56,7 @@ mod cfgs_between_fields { } let s = S { d: 0, + //~^ inconsistent_struct_constructor #[cfg(all())] c: 1, b: 2, @@ -70,6 +74,7 @@ mod cfgs_between_fields { } let s = S { d: 0, + //~^ inconsistent_struct_constructor #[cfg(any())] c: 1, b: 2, diff --git a/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.stderr b/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.stderr index d2533960b84c..be85fa574480 100644 --- a/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.stderr +++ b/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.stderr @@ -8,22 +8,25 @@ LL | Foo { y, x, z: z }; = help: to override `-D warnings` add `#[allow(clippy::inconsistent_struct_constructor)]` error: struct constructor field order is inconsistent with struct definition field order - --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:21:9 + --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:22:9 | LL | / z: z, +LL | | LL | | x, | |_________^ | help: if the field evaluation order doesn't matter, try | LL ~ x, +LL + LL ~ z: z, | error: struct constructor field order is inconsistent with struct definition field order - --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:36:13 + --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:38:13 | LL | / #[expect(clippy::bool_to_int_with_if)] // obfuscates the meaning +LL | | LL | | expn_depth: if condition { 1 } else { 0 }, LL | | macro_unsafe_blocks: Vec::new(), | |___________________________________________^ @@ -32,13 +35,15 @@ help: if the field evaluation order doesn't matter, try | LL ~ macro_unsafe_blocks: Vec::new(), LL + #[expect(clippy::bool_to_int_with_if)] // obfuscates the meaning +LL + LL ~ expn_depth: if condition { 1 } else { 0 }, | error: struct constructor field order is inconsistent with struct definition field order - --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:55:13 + --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:58:13 | LL | / d: 0, +LL | | LL | | #[cfg(all())] LL | | c: 1, LL | | b: 2, @@ -48,6 +53,7 @@ LL | | a: 3, help: if the field evaluation order doesn't matter, try | LL ~ a: 3, +LL + LL + b: 2, LL + #[cfg(all())] LL + c: 1, @@ -55,9 +61,10 @@ LL ~ d: 0, | error: struct constructor field order is inconsistent with struct definition field order - --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:72:13 + --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:76:13 | LL | / d: 0, +LL | | LL | | #[cfg(any())] LL | | c: 1, LL | | b: 2, @@ -67,6 +74,7 @@ LL | | a: 3, help: if the field evaluation order doesn't matter, try | LL ~ a: 3, +LL + LL + #[cfg(any())] LL + c: 1, LL + b: 2, diff --git a/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.fixed b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.fixed index dae7ce76ba28..df28e0bc94be 100644 --- a/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.fixed +++ b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.fixed @@ -4,5 +4,7 @@ fn good() {} fn main() { good(); + //~^ disallowed_methods good(); + //~^ disallowed_methods } diff --git a/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs index 53678ffdf1c9..9257f0e3e1a7 100644 --- a/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs +++ b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs @@ -4,5 +4,7 @@ fn good() {} fn main() { bad(); + //~^ disallowed_methods questionable(); + //~^ disallowed_methods } diff --git a/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.stderr b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.stderr index b85592029420..6f70b4ae6a9e 100644 --- a/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.stderr +++ b/tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.stderr @@ -8,7 +8,7 @@ LL | bad(); = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]` error: use of a disallowed method `replaceable_disallowed_methods::questionable` - --> tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs:7:5 + --> tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs:8:5 | LL | questionable(); | ^^^^^^^^^^^^ help: a better function exists: `good` diff --git a/tests/ui-toml/toml_trivially_copy/test.rs b/tests/ui-toml/toml_trivially_copy/test.rs index 145a2ce441d3..46f21eef9740 100644 --- a/tests/ui-toml/toml_trivially_copy/test.rs +++ b/tests/ui-toml/toml_trivially_copy/test.rs @@ -13,6 +13,8 @@ struct Bar(u32); fn good(a: &mut u32, b: u32, c: &Bar, d: &u32) {} fn bad(x: &u16, y: &Foo) {} +//~^ trivially_copy_pass_by_ref +//~| trivially_copy_pass_by_ref fn main() { let (mut a, b, c, d, x, y) = (0, 0, Bar(0), 0, 0, Foo(0)); diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs b/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs index 49139b60a9f4..8d02924c9d93 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs @@ -1,4 +1,6 @@ //@no-rustfix -//@error-in-other-file: unknown field `foobar`, expected one of +//@error-in-other-file: unknown field +//@error-in-other-file: error reading Clippy +//@error-in-other-file: error reading Clippy fn main() {} diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr index 9677beeb2c24..32ed78151d23 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr @@ -9,7 +9,7 @@ LL | /* Safety: */ unsafe {} = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]` error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275:5 | LL | unsafe {} | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:14 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:29 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:29 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:48 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:48 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:18 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:18 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:37 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:37 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:286:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:293:14 | LL | let _ = *unsafe { &42 }; | ^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | let _ = *unsafe { &42 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:291:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:299:19 | LL | let _ = match unsafe {} { | ^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let _ = match unsafe {} { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:297:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306:14 | LL | let _ = &unsafe {}; | ^^^^^^^^^ @@ -81,7 +81,7 @@ LL | let _ = &unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:301:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:311:14 | LL | let _ = [unsafe {}; 5]; | ^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = [unsafe {}; 5]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:305:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316:13 | LL | let _ = unsafe {}; | ^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _ = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:315:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:327:8 | LL | t!(unsafe {}); | ^^^^^^^^^ @@ -105,7 +105,7 @@ LL | t!(unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:321:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334:13 | LL | unsafe {} | ^^^^^^^^^ @@ -117,7 +117,7 @@ LL | t!(); = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:329:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:5 | LL | unsafe {} // SAFETY: | ^^^^^^^^^ @@ -125,7 +125,7 @@ LL | unsafe {} // SAFETY: = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:333:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:349:5 | LL | unsafe { | ^^^^^^^^ @@ -133,7 +133,7 @@ LL | unsafe { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:360:5 | LL | unsafe {}; | ^^^^^^^^^ @@ -141,7 +141,7 @@ LL | unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:20 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:365:20 | LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:373:5 | LL | unsafe impl A for () {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | unsafe impl A for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:361:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:381:9 | LL | unsafe impl B for (u32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | unsafe impl B for (u32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:382:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:407:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:429:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:415:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:439:5 | LL | unsafe impl T for (i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -197,7 +197,7 @@ LL | unsafe impl T for (i32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:407:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:429:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | no_safety_comment!(u32); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:421:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:446:5 | LL | unsafe impl T for (bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | unsafe impl T for (bool) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:467:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:493:5 | LL | unsafe impl NoComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -225,7 +225,7 @@ LL | unsafe impl NoComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:471:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:498:19 | LL | /* SAFETY: */ unsafe impl InlineComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,7 +233,7 @@ LL | /* SAFETY: */ unsafe impl InlineComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:475:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:503:5 | LL | unsafe impl TrailingComment for () {} // SAFETY: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,13 +241,13 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: = help: consider adding a safety comment on the preceding line error: constant item has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 | LL | const BIG_NUMBER: i32 = 1000000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:478:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:507:5 | LL | // SAFETY: | ^^^^^^^^^^ @@ -255,7 +255,7 @@ LL | // SAFETY: = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5 | LL | unsafe impl Interference for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | unsafe impl Interference for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:487:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:518:5 | LL | unsafe impl ImplInFn for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -271,7 +271,7 @@ LL | unsafe impl ImplInFn for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:1 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:528:1 | LL | unsafe impl CrateRoot for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,24 +279,23 @@ LL | unsafe impl CrateRoot for () {} = help: consider adding a safety comment on the preceding line error: statement has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:543:5 | LL | / let _ = { +LL | | LL | | if unsafe { true } { -LL | | todo!(); -LL | | } else { ... | LL | | }; | |______^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:542:5 | LL | // SAFETY: this is more than one level away, so it should warn | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:12 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:545:12 | LL | if unsafe { true } { | ^^^^^^^^^^^^^^^ @@ -304,7 +303,7 @@ LL | if unsafe { true } { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:513:23 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:549:23 | LL | let bar = unsafe {}; | ^^^^^^^^^ diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr index 0eccdd428008..83a6986addf2 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr @@ -9,7 +9,7 @@ LL | /* Safety: */ unsafe {} = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]` error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275:5 | LL | unsafe {} | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:14 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:29 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:29 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:48 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:48 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:18 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:18 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:37 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:37 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:286:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:293:14 | LL | let _ = *unsafe { &42 }; | ^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | let _ = *unsafe { &42 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:291:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:299:19 | LL | let _ = match unsafe {} { | ^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let _ = match unsafe {} { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:297:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306:14 | LL | let _ = &unsafe {}; | ^^^^^^^^^ @@ -81,7 +81,7 @@ LL | let _ = &unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:301:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:311:14 | LL | let _ = [unsafe {}; 5]; | ^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = [unsafe {}; 5]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:305:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316:13 | LL | let _ = unsafe {}; | ^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _ = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:315:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:327:8 | LL | t!(unsafe {}); | ^^^^^^^^^ @@ -105,7 +105,7 @@ LL | t!(unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:321:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334:13 | LL | unsafe {} | ^^^^^^^^^ @@ -117,7 +117,7 @@ LL | t!(); = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:329:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:5 | LL | unsafe {} // SAFETY: | ^^^^^^^^^ @@ -125,7 +125,7 @@ LL | unsafe {} // SAFETY: = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:333:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:349:5 | LL | unsafe { | ^^^^^^^^ @@ -133,7 +133,7 @@ LL | unsafe { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:360:5 | LL | unsafe {}; | ^^^^^^^^^ @@ -141,7 +141,7 @@ LL | unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:20 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:365:20 | LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:373:5 | LL | unsafe impl A for () {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | unsafe impl A for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:361:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:381:9 | LL | unsafe impl B for (u32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | unsafe impl B for (u32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:382:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:407:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:429:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:415:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:439:5 | LL | unsafe impl T for (i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -197,7 +197,7 @@ LL | unsafe impl T for (i32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:407:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:429:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | no_safety_comment!(u32); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:421:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:446:5 | LL | unsafe impl T for (bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | unsafe impl T for (bool) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:467:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:493:5 | LL | unsafe impl NoComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -225,7 +225,7 @@ LL | unsafe impl NoComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:471:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:498:19 | LL | /* SAFETY: */ unsafe impl InlineComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,7 +233,7 @@ LL | /* SAFETY: */ unsafe impl InlineComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:475:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:503:5 | LL | unsafe impl TrailingComment for () {} // SAFETY: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,13 +241,13 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: = help: consider adding a safety comment on the preceding line error: constant item has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 | LL | const BIG_NUMBER: i32 = 1000000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:478:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:507:5 | LL | // SAFETY: | ^^^^^^^^^^ @@ -255,7 +255,7 @@ LL | // SAFETY: = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5 | LL | unsafe impl Interference for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | unsafe impl Interference for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:487:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:518:5 | LL | unsafe impl ImplInFn for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -271,7 +271,7 @@ LL | unsafe impl ImplInFn for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:1 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:528:1 | LL | unsafe impl CrateRoot for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +279,7 @@ LL | unsafe impl CrateRoot for () {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:539:9 | LL | unsafe {}; | ^^^^^^^^^ @@ -287,24 +287,23 @@ LL | unsafe {}; = help: consider adding a safety comment on the preceding line error: statement has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:543:5 | LL | / let _ = { +LL | | LL | | if unsafe { true } { -LL | | todo!(); -LL | | } else { ... | LL | | }; | |______^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:542:5 | LL | // SAFETY: this is more than one level away, so it should warn | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:12 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:545:12 | LL | if unsafe { true } { | ^^^^^^^^^^^^^^^ @@ -312,7 +311,7 @@ LL | if unsafe { true } { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:513:23 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:549:23 | LL | let bar = unsafe {}; | ^^^^^^^^^ @@ -320,7 +319,7 @@ LL | let bar = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:531:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:568:9 | LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -328,7 +327,7 @@ LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:535:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:573:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,7 +335,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:539:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:578:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -344,7 +343,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:545:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:585:5 | LL | unsafe {} | ^^^^^^^^^ @@ -352,7 +351,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:549:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:590:5 | LL | unsafe { | ^^^^^^^^ @@ -360,7 +359,7 @@ LL | unsafe { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:556:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:598:9 | LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -368,7 +367,7 @@ LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:561:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:604:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -376,7 +375,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:567:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:611:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -384,7 +383,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:572:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:617:5 | LL | unsafe {} | ^^^^^^^^^ diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs index 02170e1f7402..6a3fda3df5c3 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs @@ -268,41 +268,53 @@ fn in_closure(x: *const u32) { #[rustfmt::skip] fn inline_block_comment() { /* Safety: */ unsafe {} + //~^ undocumented_unsafe_blocks } fn no_comment() { unsafe {} + //~^ undocumented_unsafe_blocks } fn no_comment_array() { let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; + //~^ undocumented_unsafe_blocks + //~| undocumented_unsafe_blocks + //~| undocumented_unsafe_blocks } fn no_comment_tuple() { let _ = (42, unsafe {}, "test", unsafe {}); + //~^ undocumented_unsafe_blocks + //~| undocumented_unsafe_blocks } fn no_comment_unary() { let _ = *unsafe { &42 }; + //~^ undocumented_unsafe_blocks } #[allow(clippy::match_single_binding)] fn no_comment_match() { let _ = match unsafe {} { + //~^ undocumented_unsafe_blocks _ => {}, }; } fn no_comment_addr_of() { let _ = &unsafe {}; + //~^ undocumented_unsafe_blocks } fn no_comment_repeat() { let _ = [unsafe {}; 5]; + //~^ undocumented_unsafe_blocks } fn local_no_comment() { let _ = unsafe {}; + //~^ undocumented_unsafe_blocks } fn no_comment_macro_call() { @@ -313,12 +325,14 @@ fn no_comment_macro_call() { } t!(unsafe {}); + //~^ undocumented_unsafe_blocks } fn no_comment_macro_def() { macro_rules! t { () => { unsafe {} + //~^ undocumented_unsafe_blocks }; } @@ -327,10 +341,13 @@ fn no_comment_macro_def() { fn trailing_comment() { unsafe {} // SAFETY: + // + //~^^ undocumented_unsafe_blocks } fn internal_comment() { unsafe { + //~^ undocumented_unsafe_blocks // SAFETY: } } @@ -341,10 +358,12 @@ fn interference() { let _ = 42; unsafe {}; + //~^ undocumented_unsafe_blocks } pub fn print_binary_tree() { println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); + //~^ undocumented_unsafe_blocks } mod unsafe_impl_smoke_test { @@ -352,6 +371,7 @@ mod unsafe_impl_smoke_test { // error: no safety comment unsafe impl A for () {} + //~^ undocumented_unsafe_blocks // Safety: ok unsafe impl A for (i32) {} @@ -359,6 +379,7 @@ mod unsafe_impl_smoke_test { mod sub_mod { // error: unsafe impl B for (u32) {} + //~^ undocumented_unsafe_blocks unsafe trait B {} } @@ -380,6 +401,7 @@ mod unsafe_impl_from_macro { macro_rules! no_safety_comment { ($t:ty) => { unsafe impl T for $t {} + //~^ undocumented_unsafe_blocks }; } @@ -405,6 +427,8 @@ mod unsafe_impl_macro_and_not_macro { macro_rules! no_safety_comment { ($t:ty) => { unsafe impl T for $t {} + //~^ undocumented_unsafe_blocks + //~| undocumented_unsafe_blocks }; } @@ -413,12 +437,14 @@ mod unsafe_impl_macro_and_not_macro { // error unsafe impl T for (i32) {} + //~^ undocumented_unsafe_blocks // ok no_safety_comment!(u32); // error unsafe impl T for (bool) {} + //~^ undocumented_unsafe_blocks } #[rustfmt::skip] @@ -465,19 +491,24 @@ mod unsafe_impl_invalid_comment { unsafe trait NoComment {} unsafe impl NoComment for () {} + //~^ undocumented_unsafe_blocks unsafe trait InlineComment {} /* SAFETY: */ unsafe impl InlineComment for () {} + //~^ undocumented_unsafe_blocks unsafe trait TrailingComment {} unsafe impl TrailingComment for () {} // SAFETY: + //~^ undocumented_unsafe_blocks unsafe trait Interference {} // SAFETY: const BIG_NUMBER: i32 = 1000000; + //~^ unnecessary_safety_comment unsafe impl Interference for () {} + //~^ undocumented_unsafe_blocks } unsafe trait ImplInFn {} @@ -485,6 +516,7 @@ unsafe trait ImplInFn {} fn impl_in_fn() { // error unsafe impl ImplInFn for () {} + //~^ undocumented_unsafe_blocks // SAFETY: ok unsafe impl ImplInFn for (i32) {} @@ -494,6 +526,7 @@ unsafe trait CrateRoot {} // error unsafe impl CrateRoot for () {} +//~^ undocumented_unsafe_blocks // SAFETY: ok unsafe impl CrateRoot for (i32) {} @@ -504,13 +537,17 @@ fn nested_block_separation_issue_9142() { // we need this comment to avoid rustfmt putting // it all on one line unsafe {}; + //~[disabled]^ undocumented_unsafe_blocks // SAFETY: this is more than one level away, so it should warn let _ = { + //~^ unnecessary_safety_comment if unsafe { true } { + //~^ undocumented_unsafe_blocks todo!(); } else { let bar = unsafe {}; + //~^ undocumented_unsafe_blocks todo!(); bar } @@ -529,24 +566,29 @@ fn separate_line_from_let_issue_10832() { // SAFETY: fail ONLY if `accept-comment-above-statement = false` let _some_variable_with_a_very_long_name_to_break_the_line = unsafe { a_function_with_a_very_long_name_to_break_the_line() }; + //~[disabled]^ undocumented_unsafe_blocks // SAFETY: fail ONLY if `accept-comment-above-statement = false` const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + //~[disabled]^ undocumented_unsafe_blocks // SAFETY: fail ONLY if `accept-comment-above-statement = false` static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + //~[disabled]^ undocumented_unsafe_blocks } fn above_expr_attribute_issue_8679() { // SAFETY: fail ONLY if `accept-comment-above-attribute = false` #[allow(unsafe_code)] unsafe {} + //~[disabled]^ undocumented_unsafe_blocks // SAFETY: fail ONLY if `accept-comment-above-attribute = false` #[expect(unsafe_code, reason = "totally safe")] unsafe { + //~[disabled]^ undocumented_unsafe_blocks *std::ptr::null::() }; @@ -554,22 +596,26 @@ fn above_expr_attribute_issue_8679() { #[allow(unsafe_code)] let _some_variable_with_a_very_long_name_to_break_the_line = unsafe { a_function_with_a_very_long_name_to_break_the_line() }; + //~[disabled]^ undocumented_unsafe_blocks // SAFETY: fail ONLY if `accept-comment-above-attribute = false` #[allow(unsafe_code)] const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + //~[disabled]^ undocumented_unsafe_blocks // SAFETY: fail ONLY if `accept-comment-above-attribute = false` #[allow(unsafe_code)] #[allow(non_upper_case_globals)] static _some_static_with_a_very_long_name_to_break_the_line: u32 = unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + //~[disabled]^ undocumented_unsafe_blocks // SAFETY: #[allow(unsafe_code)] // This shouldn't work either unsafe {} + //~[disabled]^ undocumented_unsafe_blocks } mod issue_11246 { diff --git a/tests/ui-toml/unwrap_used/unwrap_used.fixed b/tests/ui-toml/unwrap_used/unwrap_used.fixed index cdb8fa0454cd..9b4eaa208eb2 100644 --- a/tests/ui-toml/unwrap_used/unwrap_used.fixed +++ b/tests/ui-toml/unwrap_used/unwrap_used.fixed @@ -36,23 +36,45 @@ fn main() { { // Test `get().unwrap()` let _ = &boxed_slice[1]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_slice[0]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_vec[0]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_vecdeque[0]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_hashmap[&1]; + //~^ get_unwrap + //~| unwrap_used let _ = &some_btreemap[&1]; + //~^ get_unwrap + //~| unwrap_used #[allow(clippy::unwrap_used)] let _ = false_positive.get(0).unwrap(); // Test with deref let _: u8 = boxed_slice[1]; + //~^ get_unwrap + //~| unwrap_used } { // Test `get_mut().unwrap()` boxed_slice[0] = 1; + //~^ get_unwrap + //~| unwrap_used some_slice[0] = 1; + //~^ get_unwrap + //~| unwrap_used some_vec[0] = 1; + //~^ get_unwrap + //~| unwrap_used some_vecdeque[0] = 1; + //~^ get_unwrap + //~| unwrap_used // Check false positives #[allow(clippy::unwrap_used)] { @@ -65,7 +87,11 @@ fn main() { { // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()` let _ = some_vec[0..1].to_vec(); + //~^ get_unwrap + //~| unwrap_used let _ = some_vec[0..1].to_vec(); + //~^ get_unwrap + //~| unwrap_used } } @@ -73,6 +99,7 @@ fn main() { fn test() { let boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); let _ = &boxed_slice[1]; + //~^ get_unwrap } #[cfg(test)] @@ -92,5 +119,6 @@ mod issue9612 { let _a: u8 = 5.try_into().expect(""); // should still warn let _ = &Box::new([0])[1]; + //~^ get_unwrap } } diff --git a/tests/ui-toml/unwrap_used/unwrap_used.rs b/tests/ui-toml/unwrap_used/unwrap_used.rs index e53d53db5f7a..4845efa68733 100644 --- a/tests/ui-toml/unwrap_used/unwrap_used.rs +++ b/tests/ui-toml/unwrap_used/unwrap_used.rs @@ -36,23 +36,45 @@ fn main() { { // Test `get().unwrap()` let _ = boxed_slice.get(1).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_slice.get(0).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_vec.get(0).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_vecdeque.get(0).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_hashmap.get(&1).unwrap(); + //~^ get_unwrap + //~| unwrap_used let _ = some_btreemap.get(&1).unwrap(); + //~^ get_unwrap + //~| unwrap_used #[allow(clippy::unwrap_used)] let _ = false_positive.get(0).unwrap(); // Test with deref let _: u8 = *boxed_slice.get(1).unwrap(); + //~^ get_unwrap + //~| unwrap_used } { // Test `get_mut().unwrap()` *boxed_slice.get_mut(0).unwrap() = 1; + //~^ get_unwrap + //~| unwrap_used *some_slice.get_mut(0).unwrap() = 1; + //~^ get_unwrap + //~| unwrap_used *some_vec.get_mut(0).unwrap() = 1; + //~^ get_unwrap + //~| unwrap_used *some_vecdeque.get_mut(0).unwrap() = 1; + //~^ get_unwrap + //~| unwrap_used // Check false positives #[allow(clippy::unwrap_used)] { @@ -65,7 +87,11 @@ fn main() { { // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()` let _ = some_vec.get(0..1).unwrap().to_vec(); + //~^ get_unwrap + //~| unwrap_used let _ = some_vec.get_mut(0..1).unwrap().to_vec(); + //~^ get_unwrap + //~| unwrap_used } } @@ -73,6 +99,7 @@ fn main() { fn test() { let boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); let _ = boxed_slice.get(1).unwrap(); + //~^ get_unwrap } #[cfg(test)] @@ -92,5 +119,6 @@ mod issue9612 { let _a: u8 = 5.try_into().expect(""); // should still warn let _ = Box::new([0]).get(1).unwrap(); + //~^ get_unwrap } } diff --git a/tests/ui-toml/unwrap_used/unwrap_used.stderr b/tests/ui-toml/unwrap_used/unwrap_used.stderr index b58ce9b8af3e..cb9a3f6887dc 100644 --- a/tests/ui-toml/unwrap_used/unwrap_used.stderr +++ b/tests/ui-toml/unwrap_used/unwrap_used.stderr @@ -23,7 +23,7 @@ LL | let _ = boxed_slice.get(1).unwrap(); = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]` error: called `.get().unwrap()` on a slice - --> tests/ui-toml/unwrap_used/unwrap_used.rs:39:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17 | LL | let _ = some_slice.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = &some_slice[0]; | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:39:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17 | LL | let _ = some_slice.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL | let _ = some_slice.get(0).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec - --> tests/ui-toml/unwrap_used/unwrap_used.rs:40:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:44:17 | LL | let _ = some_vec.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | let _ = &some_vec[0]; | ~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:40:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:44:17 | LL | let _ = some_vec.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -63,7 +63,7 @@ LL | let _ = some_vec.get(0).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a VecDeque - --> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:47:17 | LL | let _ = some_vecdeque.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | let _ = &some_vecdeque[0]; | ~~~~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:47:17 | LL | let _ = some_vecdeque.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | let _ = some_vecdeque.get(0).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a HashMap - --> tests/ui-toml/unwrap_used/unwrap_used.rs:42:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:50:17 | LL | let _ = some_hashmap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | let _ = &some_hashmap[&1]; | ~~~~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:42:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:50:17 | LL | let _ = some_hashmap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL | let _ = some_hashmap.get(&1).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a BTreeMap - --> tests/ui-toml/unwrap_used/unwrap_used.rs:43:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:53:17 | LL | let _ = some_btreemap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | let _ = &some_btreemap[&1]; | ~~~~~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:43:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:53:17 | LL | let _ = some_btreemap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ LL | let _ = some_btreemap.get(&1).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice - --> tests/ui-toml/unwrap_used/unwrap_used.rs:47:21 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:59:21 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -134,7 +134,7 @@ LL | let _: u8 = boxed_slice[1]; | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:47:22 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:59:22 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -143,7 +143,7 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap(); = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice - --> tests/ui-toml/unwrap_used/unwrap_used.rs:52:9 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:66:9 | LL | *boxed_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | boxed_slice[0] = 1; | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:52:10 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:66:10 | LL | *boxed_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1; = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice - --> tests/ui-toml/unwrap_used/unwrap_used.rs:53:9 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:69:9 | LL | *some_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +174,7 @@ LL | some_slice[0] = 1; | ~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:53:10 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:69:10 | LL | *some_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +183,7 @@ LL | *some_slice.get_mut(0).unwrap() = 1; = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec - --> tests/ui-toml/unwrap_used/unwrap_used.rs:54:9 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:72:9 | LL | *some_vec.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -194,7 +194,7 @@ LL | some_vec[0] = 1; | ~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:54:10 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:72:10 | LL | *some_vec.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -203,7 +203,7 @@ LL | *some_vec.get_mut(0).unwrap() = 1; = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a VecDeque - --> tests/ui-toml/unwrap_used/unwrap_used.rs:55:9 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:75:9 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -214,7 +214,7 @@ LL | some_vecdeque[0] = 1; | ~~~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:55:10 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:75:10 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -223,7 +223,7 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1; = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec - --> tests/ui-toml/unwrap_used/unwrap_used.rs:67:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:89:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -234,7 +234,7 @@ LL | let _ = some_vec[0..1].to_vec(); | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:67:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:89:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -243,7 +243,7 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec(); = help: consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec - --> tests/ui-toml/unwrap_used/unwrap_used.rs:68:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:92:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -254,7 +254,7 @@ LL | let _ = some_vec[0..1].to_vec(); | ~~~~~~~~~~~~~~ error: used `unwrap()` on an `Option` value - --> tests/ui-toml/unwrap_used/unwrap_used.rs:68:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:92:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); = help: consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice - --> tests/ui-toml/unwrap_used/unwrap_used.rs:75:13 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:101:13 | LL | let _ = boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -274,7 +274,7 @@ LL | let _ = &boxed_slice[1]; | ~~~~~~~~~~~~~~~ error: called `.get().unwrap()` on a slice - --> tests/ui-toml/unwrap_used/unwrap_used.rs:94:17 + --> tests/ui-toml/unwrap_used/unwrap_used.rs:121:17 | LL | let _ = Box::new([0]).get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.fixed b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.fixed index afb889f157f0..4f1f9ca07273 100644 --- a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.fixed +++ b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.fixed @@ -1,24 +1,35 @@ #![warn(clippy::upper_case_acronyms)] struct HttpResponse; // not linted by default, but with cfg option +//~^ upper_case_acronyms struct CString; // not linted enum Flags { Ns, // not linted + //~^ upper_case_acronyms Cwr, + //~^ upper_case_acronyms Ece, + //~^ upper_case_acronyms Urg, + //~^ upper_case_acronyms Ack, + //~^ upper_case_acronyms Psh, + //~^ upper_case_acronyms Rst, + //~^ upper_case_acronyms Syn, + //~^ upper_case_acronyms Fin, + //~^ upper_case_acronyms } // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of // `GccLlvmSomething` struct GccllvmSomething; +//~^ upper_case_acronyms // don't warn on public items pub struct MIXEDCapital; @@ -36,7 +47,9 @@ pub enum ParseError { // private, do lint here enum ParseErrorPrivate { Wasd(u8), + //~^ upper_case_acronyms WasdMixed(String), + //~^ upper_case_acronyms Utf8(std::string::FromUtf8Error), Parse(T, String), } diff --git a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs index 1a5cf1b1947c..da522aadfdd7 100644 --- a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs +++ b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs @@ -1,24 +1,35 @@ #![warn(clippy::upper_case_acronyms)] struct HTTPResponse; // not linted by default, but with cfg option +//~^ upper_case_acronyms struct CString; // not linted enum Flags { NS, // not linted + //~^ upper_case_acronyms CWR, + //~^ upper_case_acronyms ECE, + //~^ upper_case_acronyms URG, + //~^ upper_case_acronyms ACK, + //~^ upper_case_acronyms PSH, + //~^ upper_case_acronyms RST, + //~^ upper_case_acronyms SYN, + //~^ upper_case_acronyms FIN, + //~^ upper_case_acronyms } // linted with cfg option, beware that lint suggests `GccllvmSomething` instead of // `GccLlvmSomething` struct GCCLLVMSomething; +//~^ upper_case_acronyms // don't warn on public items pub struct MIXEDCapital; @@ -36,7 +47,9 @@ pub enum ParseError { // private, do lint here enum ParseErrorPrivate { WASD(u8), + //~^ upper_case_acronyms WASDMixed(String), + //~^ upper_case_acronyms Utf8(std::string::FromUtf8Error), Parse(T, String), } diff --git a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr index 88917603ff8c..e1706b7472c0 100644 --- a/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr +++ b/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr @@ -8,73 +8,73 @@ LL | struct HTTPResponse; // not linted by default, but with cfg option = help: to override `-D warnings` add `#[allow(clippy::upper_case_acronyms)]` error: name `NS` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:8:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:9:5 | LL | NS, // not linted | ^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ns` error: name `CWR` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:9:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:11:5 | LL | CWR, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Cwr` error: name `ECE` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:10:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:13:5 | LL | ECE, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Ece` error: name `URG` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:11:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:15:5 | LL | URG, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Urg` error: name `ACK` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:12:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:17:5 | LL | ACK, | ^^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ack` error: name `PSH` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:13:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:19:5 | LL | PSH, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Psh` error: name `RST` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:14:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:21:5 | LL | RST, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Rst` error: name `SYN` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:15:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:23:5 | LL | SYN, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Syn` error: name `FIN` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:16:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:25:5 | LL | FIN, | ^^^ help: consider making the acronym lowercase, except the initial letter: `Fin` error: name `GCCLLVMSomething` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:21:8 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:31:8 | LL | struct GCCLLVMSomething; | ^^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `GccllvmSomething` error: name `WASD` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:38:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:49:5 | LL | WASD(u8), | ^^^^ help: consider making the acronym lowercase, except the initial letter: `Wasd` error: name `WASDMixed` contains a capitalized acronym - --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:39:5 + --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:51:5 | LL | WASDMixed(String), | ^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `WasdMixed` diff --git a/tests/ui-toml/useless_vec/useless_vec.fixed b/tests/ui-toml/useless_vec/useless_vec.fixed index 08323a0dcc90..6181abc6ea57 100644 --- a/tests/ui-toml/useless_vec/useless_vec.fixed +++ b/tests/ui-toml/useless_vec/useless_vec.fixed @@ -6,6 +6,7 @@ fn foo(_: &[u32]) {} fn main() { foo(&[1_u32]); + //~^ useless_vec } #[test] diff --git a/tests/ui-toml/useless_vec/useless_vec.rs b/tests/ui-toml/useless_vec/useless_vec.rs index 1f4b27c53429..bffdcc59752b 100644 --- a/tests/ui-toml/useless_vec/useless_vec.rs +++ b/tests/ui-toml/useless_vec/useless_vec.rs @@ -6,6 +6,7 @@ fn foo(_: &[u32]) {} fn main() { foo(&vec![1_u32]); + //~^ useless_vec } #[test] diff --git a/tests/ui-toml/vec_box_sized/test.fixed b/tests/ui-toml/vec_box_sized/test.fixed index bb4936401ceb..423c761f1b17 100644 --- a/tests/ui-toml/vec_box_sized/test.fixed +++ b/tests/ui-toml/vec_box_sized/test.fixed @@ -7,10 +7,13 @@ struct C { } struct Foo(Vec); +//~^ vec_box struct Bar(Vec); +//~^ vec_box struct Quux(Vec>); struct Baz(Vec>); struct BarBaz(Vec>); struct FooBarBaz(Vec); +//~^ vec_box fn main() {} diff --git a/tests/ui-toml/vec_box_sized/test.rs b/tests/ui-toml/vec_box_sized/test.rs index 4c46deb585b6..fd9a13430021 100644 --- a/tests/ui-toml/vec_box_sized/test.rs +++ b/tests/ui-toml/vec_box_sized/test.rs @@ -7,10 +7,13 @@ struct C { } struct Foo(Vec>); +//~^ vec_box struct Bar(Vec>); +//~^ vec_box struct Quux(Vec>); struct Baz(Vec>); struct BarBaz(Vec>); struct FooBarBaz(Vec>); +//~^ vec_box fn main() {} diff --git a/tests/ui-toml/vec_box_sized/test.stderr b/tests/ui-toml/vec_box_sized/test.stderr index 8c0750d86663..b80b9492c3ca 100644 --- a/tests/ui-toml/vec_box_sized/test.stderr +++ b/tests/ui-toml/vec_box_sized/test.stderr @@ -8,13 +8,13 @@ LL | struct Foo(Vec>); = help: to override `-D warnings` add `#[allow(clippy::vec_box)]` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui-toml/vec_box_sized/test.rs:10:12 + --> tests/ui-toml/vec_box_sized/test.rs:11:12 | LL | struct Bar(Vec>); | ^^^^^^^^^^^^^ help: try: `Vec` error: `Vec` is already on the heap, the boxing is unnecessary - --> tests/ui-toml/vec_box_sized/test.rs:14:18 + --> tests/ui-toml/vec_box_sized/test.rs:16:18 | LL | struct FooBarBaz(Vec>); | ^^^^^^^^^^^ help: try: `Vec` diff --git a/tests/ui-toml/zero_single_char_names/zero_single_char_names.rs b/tests/ui-toml/zero_single_char_names/zero_single_char_names.rs index 22aaa242b9b9..d335b12d41ec 100644 --- a/tests/ui-toml/zero_single_char_names/zero_single_char_names.rs +++ b/tests/ui-toml/zero_single_char_names/zero_single_char_names.rs @@ -1,3 +1,4 @@ +//@check-pass #![warn(clippy::many_single_char_names)] fn main() {} From 0841f6e9dc3fa7f6be2b2c59f52a68988e4dda5a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 13 Feb 2025 14:15:08 +0100 Subject: [PATCH 123/991] Don't make ui test annotations madatory for `ui-cargo` --- tests/compile-test.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 838ca2919a26..8d725d743dba 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -139,7 +139,7 @@ impl TestContext { } } - fn base_config(&self, test_dir: &str) -> Config { + fn base_config(&self, test_dir: &str, mandatory_annotations: bool) -> Config { let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into())); let mut config = Config { output_conflict_handling: OutputConflictHandling::Error, @@ -153,7 +153,11 @@ impl TestContext { }; let defaults = config.comment_defaults.base(); defaults.exit_status = None.into(); - defaults.require_annotations = Some(Spanned::dummy(true)).into(); + if mandatory_annotations { + defaults.require_annotations = Some(Spanned::dummy(true)).into(); + } else { + defaults.require_annotations = None.into(); + } defaults.diagnostic_code_prefix = Some(Spanned::dummy("clippy::".into())).into(); defaults.set_custom("rustfix", RustfixMode::Everything); if let Some(collector) = self.diagnostic_collector.clone() { @@ -197,7 +201,7 @@ impl TestContext { } fn run_ui(cx: &TestContext) { - let mut config = cx.base_config("ui"); + let mut config = cx.base_config("ui", true); config .program .envs @@ -216,7 +220,7 @@ fn run_internal_tests(cx: &TestContext) { if !RUN_INTERNAL_TESTS { return; } - let mut config = cx.base_config("ui-internal"); + let mut config = cx.base_config("ui-internal", true); config.bless_command = Some("cargo uitest --features internal -- -- --bless".into()); ui_test::run_tests_generic( @@ -229,7 +233,7 @@ fn run_internal_tests(cx: &TestContext) { } fn run_ui_toml(cx: &TestContext) { - let mut config = cx.base_config("ui-toml"); + let mut config = cx.base_config("ui-toml", true); config .comment_defaults @@ -259,7 +263,7 @@ fn run_ui_cargo(cx: &TestContext) { return; } - let mut config = cx.base_config("ui-cargo"); + let mut config = cx.base_config("ui-cargo", false); config.program.input_file_flag = CommandBuilder::cargo().input_file_flag; config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag; config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()]; From a50953c1b96bf2c7b2c5bd7411f11fbcf67e8aeb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 13 Feb 2025 14:42:33 +0100 Subject: [PATCH 124/991] Disable mandatory annotations for `ui-internals` tests for now until we find a solution for `tests/ui-internal/custom_ice_message.rs` --- tests/compile-test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 8d725d743dba..837096d00620 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -220,7 +220,7 @@ fn run_internal_tests(cx: &TestContext) { if !RUN_INTERNAL_TESTS { return; } - let mut config = cx.base_config("ui-internal", true); + let mut config = cx.base_config("ui-internal", false); config.bless_command = Some("cargo uitest --features internal -- -- --bless".into()); ui_test::run_tests_generic( From cc915cced82359b9816b3016958dadf6a503fb6f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 15 Feb 2025 13:44:26 +0100 Subject: [PATCH 125/991] Add missing ui annotations to new ui tests --- tests/ui/unnecessary_map_or.fixed | 2 ++ tests/ui/unnecessary_map_or.rs | 2 ++ tests/ui/unnecessary_map_or.stderr | 4 ++-- tests/ui/{literal_string_with_formatting_args}.rs | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/ui/unnecessary_map_or.fixed b/tests/ui/unnecessary_map_or.fixed index 01646faea4b6..3c7243972845 100644 --- a/tests/ui/unnecessary_map_or.fixed +++ b/tests/ui/unnecessary_map_or.fixed @@ -125,6 +125,8 @@ fn with_deref(o: &S) -> bool { fn issue14201(a: Option, b: Option, s: &String) -> bool { let x = a.is_some_and(|a| a == *s); + //~^ unnecessary_map_or let y = b.is_none_or(|b| b == *s); + //~^ unnecessary_map_or x && y } diff --git a/tests/ui/unnecessary_map_or.rs b/tests/ui/unnecessary_map_or.rs index 10669f2a7f1a..e734a27badab 100644 --- a/tests/ui/unnecessary_map_or.rs +++ b/tests/ui/unnecessary_map_or.rs @@ -129,6 +129,8 @@ fn with_deref(o: &S) -> bool { fn issue14201(a: Option, b: Option, s: &String) -> bool { let x = a.map_or(false, |a| a == *s); + //~^ unnecessary_map_or let y = b.map_or(true, |b| b == *s); + //~^ unnecessary_map_or x && y } diff --git a/tests/ui/unnecessary_map_or.stderr b/tests/ui/unnecessary_map_or.stderr index 57a76c21c70d..fb469e1f472e 100644 --- a/tests/ui/unnecessary_map_or.stderr +++ b/tests/ui/unnecessary_map_or.stderr @@ -290,7 +290,7 @@ LL + o.is_none_or(|n| n > 5) | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:107:13 + --> tests/ui/unnecessary_map_or.rs:131:13 | LL | let x = a.map_or(false, |a| a == *s); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -302,7 +302,7 @@ LL + let x = a.is_some_and(|a| a == *s); | error: this `map_or` can be simplified - --> tests/ui/unnecessary_map_or.rs:108:13 + --> tests/ui/unnecessary_map_or.rs:133:13 | LL | let y = b.map_or(true, |b| b == *s); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/{literal_string_with_formatting_args}.rs b/tests/ui/{literal_string_with_formatting_args}.rs index 0f5b36e67503..3096558a516a 100644 --- a/tests/ui/{literal_string_with_formatting_args}.rs +++ b/tests/ui/{literal_string_with_formatting_args}.rs @@ -1,3 +1,5 @@ +//@check-pass + // Regression test for . // The `dbg` macro generates a literal with the name of the current file, so // we need to ensure the lint is not emitted in this case. From 211f79d84e3e6a9c2be01dc3025b01f3e23474d9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 15 Feb 2025 14:05:59 +0100 Subject: [PATCH 126/991] Fix `tests/ui-toml/absolute_paths/absolute_paths_2015.rs` test --- .../absolute_paths_2015.default.stderr | 14 ++++++++++++++ .../ui-toml/absolute_paths/absolute_paths_2015.rs | 6 ++++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr diff --git a/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr b/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr new file mode 100644 index 000000000000..b946514454aa --- /dev/null +++ b/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr @@ -0,0 +1,14 @@ +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:16:13 + | +LL | let _ = ::m1::m2::X; + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:7:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui-toml/absolute_paths/absolute_paths_2015.rs b/tests/ui-toml/absolute_paths/absolute_paths_2015.rs index ea556b7e437d..86981f979556 100644 --- a/tests/ui-toml/absolute_paths/absolute_paths_2015.rs +++ b/tests/ui-toml/absolute_paths/absolute_paths_2015.rs @@ -1,8 +1,8 @@ //@revisions: default allow_crates //@[default]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default //@[allow_crates]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates +//@[allow_crates]check-pass //@edition:2015 -//@check-pass #![deny(clippy::absolute_paths)] @@ -12,4 +12,6 @@ mod m1 { } } -fn main() {} +fn main() { + let _ = ::m1::m2::X; //~[default] absolute_paths +} From 0fcc2dba925cd60f6a518e60f9be9017c26cd174 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sat, 15 Feb 2025 14:51:03 +0100 Subject: [PATCH 127/991] Fix 32 bits tests --- tests/ui/cast_size.32bit.stderr | 36 ++++++------- tests/ui/fn_to_numeric_cast.32bit.stderr | 44 ++++++++-------- tests/ui/large_enum_variant.32bit.stderr | 64 +++++++++++++++--------- 3 files changed, 81 insertions(+), 63 deletions(-) diff --git a/tests/ui/cast_size.32bit.stderr b/tests/ui/cast_size.32bit.stderr index 8ff3464676c3..d2c845dc8217 100644 --- a/tests/ui/cast_size.32bit.stderr +++ b/tests/ui/cast_size.32bit.stderr @@ -13,7 +13,7 @@ LL | i8::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:21:5 + --> tests/ui/cast_size.rs:22:5 | LL | x0 as f32; | ^^^^^^^^^ @@ -22,25 +22,25 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:22:5 + --> tests/ui/cast_size.rs:24:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:23:5 + --> tests/ui/cast_size.rs:26:5 | LL | x0 as f64; | ^^^^^^^^^ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:24:5 + --> tests/ui/cast_size.rs:28:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `isize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:28:5 + --> tests/ui/cast_size.rs:33:5 | LL | 1isize as i32; | ^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | i32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:29:5 + --> tests/ui/cast_size.rs:35:5 | LL | 1isize as u32; | ^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | u32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:30:5 + --> tests/ui/cast_size.rs:37:5 | LL | 1usize as u32; | ^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | u32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:31:5 + --> tests/ui/cast_size.rs:39:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:31:5 + --> tests/ui/cast_size.rs:39:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | 1usize as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `i64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:32:5 + --> tests/ui/cast_size.rs:42:5 | LL | 1i64 as isize; | ^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | isize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:33:5 + --> tests/ui/cast_size.rs:44:5 | LL | 1i64 as usize; | ^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | usize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:34:5 + --> tests/ui/cast_size.rs:46:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -133,13 +133,13 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:34:5 + --> tests/ui/cast_size.rs:46:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:35:5 + --> tests/ui/cast_size.rs:49:5 | LL | 1u64 as usize; | ^^^^^^^^^^^^^ @@ -151,25 +151,25 @@ LL | usize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:36:5 + --> tests/ui/cast_size.rs:51:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:43:5 + --> tests/ui/cast_size.rs:59:5 | LL | 999_999_999 as f32; | ^^^^^^^^^^^^^^^^^^ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:44:5 + --> tests/ui/cast_size.rs:61:5 | LL | 9_999_999_999_999_999usize as f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: literal out of range for `usize` - --> tests/ui/cast_size.rs:44:5 + --> tests/ui/cast_size.rs:61:5 | LL | 9_999_999_999_999_999usize as f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/fn_to_numeric_cast.32bit.stderr b/tests/ui/fn_to_numeric_cast.32bit.stderr index 65991a3989ac..7093f8caf101 100644 --- a/tests/ui/fn_to_numeric_cast.32bit.stderr +++ b/tests/ui/fn_to_numeric_cast.32bit.stderr @@ -8,13 +8,13 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]` error: casting function pointer `foo` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:11:13 + --> tests/ui/fn_to_numeric_cast.rs:12:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i32` - --> tests/ui/fn_to_numeric_cast.rs:12:13 + --> tests/ui/fn_to_numeric_cast.rs:14:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ help: try: `foo as usize` @@ -23,121 +23,121 @@ LL | let _ = foo as i32; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]` error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:13:13 + --> tests/ui/fn_to_numeric_cast.rs:16:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:14:13 + --> tests/ui/fn_to_numeric_cast.rs:18:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:15:13 + --> tests/ui/fn_to_numeric_cast.rs:20:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:17:13 + --> tests/ui/fn_to_numeric_cast.rs:23:13 | LL | let _ = foo as u8; | ^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:18:13 + --> tests/ui/fn_to_numeric_cast.rs:25:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u32` - --> tests/ui/fn_to_numeric_cast.rs:19:13 + --> tests/ui/fn_to_numeric_cast.rs:27:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:20:13 + --> tests/ui/fn_to_numeric_cast.rs:29:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:21:13 + --> tests/ui/fn_to_numeric_cast.rs:31:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `abc` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:34:13 + --> tests/ui/fn_to_numeric_cast.rs:45:13 | LL | let _ = abc as i8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:35:13 + --> tests/ui/fn_to_numeric_cast.rs:47:13 | LL | let _ = abc as i16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i32` - --> tests/ui/fn_to_numeric_cast.rs:36:13 + --> tests/ui/fn_to_numeric_cast.rs:49:13 | LL | let _ = abc as i32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:37:13 + --> tests/ui/fn_to_numeric_cast.rs:51:13 | LL | let _ = abc as i64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:38:13 + --> tests/ui/fn_to_numeric_cast.rs:53:13 | LL | let _ = abc as i128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:39:13 + --> tests/ui/fn_to_numeric_cast.rs:55:13 | LL | let _ = abc as isize; | ^^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:41:13 + --> tests/ui/fn_to_numeric_cast.rs:58:13 | LL | let _ = abc as u8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:42:13 + --> tests/ui/fn_to_numeric_cast.rs:60:13 | LL | let _ = abc as u16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u32` - --> tests/ui/fn_to_numeric_cast.rs:43:13 + --> tests/ui/fn_to_numeric_cast.rs:62:13 | LL | let _ = abc as u32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:44:13 + --> tests/ui/fn_to_numeric_cast.rs:64:13 | LL | let _ = abc as u64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:45:13 + --> tests/ui/fn_to_numeric_cast.rs:66:13 | LL | let _ = abc as u128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `f` to `i32` - --> tests/ui/fn_to_numeric_cast.rs:52:5 + --> tests/ui/fn_to_numeric_cast.rs:74:5 | LL | f as i32 | ^^^^^^^^ help: try: `f as usize` diff --git a/tests/ui/large_enum_variant.32bit.stderr b/tests/ui/large_enum_variant.32bit.stderr index 36f3d930b535..af09a56854aa 100644 --- a/tests/ui/large_enum_variant.32bit.stderr +++ b/tests/ui/large_enum_variant.32bit.stderr @@ -2,6 +2,7 @@ error: large size difference between variants --> tests/ui/large_enum_variant.rs:11:1 | LL | / enum LargeEnum { +LL | | LL | | A(i32), | | ------ the second-largest variant contains at least 4 bytes LL | | B([i32; 8000]), @@ -17,9 +18,10 @@ LL | B(Box<[i32; 8000]>), | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:35:1 + --> tests/ui/large_enum_variant.rs:36:1 | LL | / enum LargeEnum2 { +LL | | LL | | VariantOk(i32, u32), | | ------------------- the second-largest variant contains at least 8 bytes LL | | ContainingLargeEnum(LargeEnum), @@ -33,9 +35,10 @@ LL | ContainingLargeEnum(Box), | ~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:40:1 + --> tests/ui/large_enum_variant.rs:42:1 | LL | / enum LargeEnum3 { +LL | | LL | | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), | | --------------------------------------------------------- the largest variant contains at least 70004 bytes LL | | VoidVariant, @@ -50,9 +53,10 @@ LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:46:1 + --> tests/ui/large_enum_variant.rs:49:1 | LL | / enum LargeEnum4 { +LL | | LL | | VariantOk(i32, u32), | | ------------------- the second-largest variant contains at least 8 bytes LL | | StructLikeLarge { x: [i32; 8000], y: i32 }, @@ -66,9 +70,10 @@ LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:51:1 + --> tests/ui/large_enum_variant.rs:55:1 | LL | / enum LargeEnum5 { +LL | | LL | | VariantOk(i32, u32), | | ------------------- the second-largest variant contains at least 8 bytes LL | | StructLikeLarge2 { x: [i32; 8000] }, @@ -82,9 +87,10 @@ LL | StructLikeLarge2 { x: Box<[i32; 8000]> }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:67:1 + --> tests/ui/large_enum_variant.rs:72:1 | LL | / enum LargeEnum7 { +LL | | LL | | A, LL | | B([u8; 1255]), | | ------------- the largest variant contains at least 1255 bytes @@ -99,9 +105,10 @@ LL | B(Box<[u8; 1255]>), | ~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:73:1 + --> tests/ui/large_enum_variant.rs:79:1 | LL | / enum LargeEnum8 { +LL | | LL | | VariantOk(i32, u32), | | ------------------- the second-largest variant contains at least 8 bytes LL | | ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), @@ -115,9 +122,10 @@ LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]> | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:78:1 + --> tests/ui/large_enum_variant.rs:85:1 | LL | / enum LargeEnum9 { +LL | | LL | | A(Struct<()>), | | ------------- the second-largest variant contains at least 4 bytes LL | | B(Struct2), @@ -131,9 +139,10 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:83:1 + --> tests/ui/large_enum_variant.rs:91:1 | LL | / enum LargeEnumOk2 { +LL | | LL | | A(T), | | ---- the second-largest variant contains at least 0 bytes LL | | B(Struct2), @@ -147,9 +156,10 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:88:1 + --> tests/ui/large_enum_variant.rs:97:1 | LL | / enum LargeEnumOk3 { +LL | | LL | | A(Struct), | | ------------ the second-largest variant contains at least 4 bytes LL | | B(Struct2), @@ -163,9 +173,10 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:103:1 + --> tests/ui/large_enum_variant.rs:113:1 | LL | / enum CopyableLargeEnum { +LL | | LL | | A(bool), | | ------- the second-largest variant contains at least 1 bytes LL | | B([u64; 8000]), @@ -174,20 +185,21 @@ LL | | } | |_^ the entire enum is at least 64004 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:103:6 + --> tests/ui/large_enum_variant.rs:113:6 | LL | enum CopyableLargeEnum { | ^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:105:5 + --> tests/ui/large_enum_variant.rs:116:5 | LL | B([u64; 8000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:108:1 + --> tests/ui/large_enum_variant.rs:119:1 | LL | / enum ManuallyCopyLargeEnum { +LL | | LL | | A(bool), | | ------- the second-largest variant contains at least 1 bytes LL | | B([u64; 8000]), @@ -196,20 +208,21 @@ LL | | } | |_^ the entire enum is at least 64004 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:108:6 + --> tests/ui/large_enum_variant.rs:119:6 | LL | enum ManuallyCopyLargeEnum { | ^^^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:110:5 + --> tests/ui/large_enum_variant.rs:122:5 | LL | B([u64; 8000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:121:1 + --> tests/ui/large_enum_variant.rs:133:1 | LL | / enum SomeGenericPossiblyCopyEnum { +LL | | LL | | A(bool, std::marker::PhantomData), | | ------------------------------------ the second-largest variant contains at least 1 bytes LL | | B([u64; 4000]), @@ -218,20 +231,21 @@ LL | | } | |_^ the entire enum is at least 32004 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:121:6 + --> tests/ui/large_enum_variant.rs:133:6 | LL | enum SomeGenericPossiblyCopyEnum { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:123:5 + --> tests/ui/large_enum_variant.rs:136:5 | LL | B([u64; 4000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:134:1 + --> tests/ui/large_enum_variant.rs:147:1 | LL | / enum LargeEnumWithGenerics { +LL | | LL | | Small, | | ----- the second-largest variant carries no data at all LL | | Large((T, [u8; 512])), @@ -245,9 +259,10 @@ LL | Large(Box<(T, [u8; 512])>), | ~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:143:1 + --> tests/ui/large_enum_variant.rs:157:1 | LL | / enum WithGenerics { +LL | | LL | | Large([Foo; 64]), | | --------------------- the largest variant contains at least 512 bytes LL | | Small(u8), @@ -261,9 +276,10 @@ LL | Large(Box<[Foo; 64]>), | ~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:153:1 + --> tests/ui/large_enum_variant.rs:168:1 | LL | / enum LargeEnumOfConst { +LL | | LL | | Ok, | | -- the second-largest variant carries no data at all LL | | Error(PossiblyLargeEnumWithConst<256>), @@ -277,9 +293,10 @@ LL | Error(Box>), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:158:1 + --> tests/ui/large_enum_variant.rs:174:1 | LL | / enum WithRecursion { +LL | | LL | | Large([u64; 64]), | | ---------------- the largest variant contains at least 512 bytes LL | | Recursive(Box), @@ -293,9 +310,10 @@ LL | Large(Box<[u64; 64]>), | ~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:168:1 + --> tests/ui/large_enum_variant.rs:185:1 | LL | / enum LargeEnumWithGenericsAndRecursive { +LL | | LL | | Ok(), | | ---- the second-largest variant carries no data at all LL | | Error(WithRecursionAndGenerics), From 8ae4e7f76dcf5e30ed40ecda537792a3f93f15fb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 15 Feb 2025 14:59:48 +0100 Subject: [PATCH 128/991] Fix `tests/ui/transmute_32bit.rs` annotations --- tests/ui/transmute_32bit.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ui/transmute_32bit.rs b/tests/ui/transmute_32bit.rs index e162bbb2d929..997f43ab12b5 100644 --- a/tests/ui/transmute_32bit.rs +++ b/tests/ui/transmute_32bit.rs @@ -3,12 +3,12 @@ #[warn(clippy::wrong_transmute)] fn main() { unsafe { - let _: *const usize = std::mem::transmute(6.0f32); + let _: *const usize = std::mem::transmute(6.0f32); //~ wrong_transmute - let _: *mut usize = std::mem::transmute(6.0f32); + let _: *mut usize = std::mem::transmute(6.0f32); //~ wrong_transmute - let _: *const usize = std::mem::transmute('x'); + let _: *const usize = std::mem::transmute('x'); //~ wrong_transmute - let _: *mut usize = std::mem::transmute('x'); + let _: *mut usize = std::mem::transmute('x'); //~ wrong_transmute } } From 2c0c661e56185cd50170d1f1251add4a584a88f2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 15 Feb 2025 15:21:22 +0100 Subject: [PATCH 129/991] Better handle 32bit/64bit-specific ui tests --- tests/ui/cast_size.32bit.stderr | 38 ++++++++--------- tests/ui/cast_size.64bit.stderr | 36 ++++++++-------- tests/ui/cast_size.rs | 5 ++- tests/ui/fn_to_numeric_cast.32bit.stderr | 46 ++++++++++----------- tests/ui/fn_to_numeric_cast.64bit.stderr | 46 ++++++++++----------- tests/ui/fn_to_numeric_cast.rs | 19 ++++++--- tests/ui/large_enum_variant.32bit.stderr | 48 +++++++++++----------- tests/ui/large_enum_variant.64bit.stderr | 52 ++++++++++++------------ tests/ui/large_enum_variant.rs | 8 ++-- 9 files changed, 155 insertions(+), 143 deletions(-) diff --git a/tests/ui/cast_size.32bit.stderr b/tests/ui/cast_size.32bit.stderr index d2c845dc8217..637dd6fddea1 100644 --- a/tests/ui/cast_size.32bit.stderr +++ b/tests/ui/cast_size.32bit.stderr @@ -1,5 +1,5 @@ error: casting `isize` to `i8` may truncate the value - --> tests/ui/cast_size.rs:15:5 + --> tests/ui/cast_size.rs:17:5 | LL | 1isize as i8; | ^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | i8::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:22:5 + --> tests/ui/cast_size.rs:24:5 | LL | x0 as f32; | ^^^^^^^^^ @@ -22,25 +22,25 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:24:5 + --> tests/ui/cast_size.rs:26:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:26:5 + --> tests/ui/cast_size.rs:28:5 | LL | x0 as f64; | ^^^^^^^^^ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:28:5 + --> tests/ui/cast_size.rs:30:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `isize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:33:5 + --> tests/ui/cast_size.rs:35:5 | LL | 1isize as i32; | ^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | i32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:35:5 + --> tests/ui/cast_size.rs:37:5 | LL | 1isize as u32; | ^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | u32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:37:5 + --> tests/ui/cast_size.rs:39:5 | LL | 1usize as u32; | ^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | u32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:39:5 + --> tests/ui/cast_size.rs:41:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:39:5 + --> tests/ui/cast_size.rs:41:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | 1usize as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `i64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:42:5 + --> tests/ui/cast_size.rs:44:5 | LL | 1i64 as isize; | ^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | isize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:44:5 + --> tests/ui/cast_size.rs:46:5 | LL | 1i64 as usize; | ^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | usize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:46:5 + --> tests/ui/cast_size.rs:48:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -133,13 +133,13 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:46:5 + --> tests/ui/cast_size.rs:48:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:49:5 + --> tests/ui/cast_size.rs:51:5 | LL | 1u64 as usize; | ^^^^^^^^^^^^^ @@ -151,25 +151,25 @@ LL | usize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:51:5 + --> tests/ui/cast_size.rs:53:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:59:5 + --> tests/ui/cast_size.rs:61:5 | LL | 999_999_999 as f32; | ^^^^^^^^^^^^^^^^^^ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:61:5 + --> tests/ui/cast_size.rs:63:5 | LL | 9_999_999_999_999_999usize as f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: literal out of range for `usize` - --> tests/ui/cast_size.rs:61:5 + --> tests/ui/cast_size.rs:63:5 | LL | 9_999_999_999_999_999usize as f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_size.64bit.stderr b/tests/ui/cast_size.64bit.stderr index d67040bcc1cb..0e12ecb6f2da 100644 --- a/tests/ui/cast_size.64bit.stderr +++ b/tests/ui/cast_size.64bit.stderr @@ -1,5 +1,5 @@ error: casting `isize` to `i8` may truncate the value - --> tests/ui/cast_size.rs:15:5 + --> tests/ui/cast_size.rs:17:5 | LL | 1isize as i8; | ^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | i8::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:22:5 + --> tests/ui/cast_size.rs:24:5 | LL | x0 as f32; | ^^^^^^^^^ @@ -22,25 +22,25 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:24:5 + --> tests/ui/cast_size.rs:26:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:26:5 + --> tests/ui/cast_size.rs:28:5 | LL | x0 as f64; | ^^^^^^^^^ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:28:5 + --> tests/ui/cast_size.rs:30:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `isize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:33:5 + --> tests/ui/cast_size.rs:35:5 | LL | 1isize as i32; | ^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | i32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:35:5 + --> tests/ui/cast_size.rs:37:5 | LL | 1isize as u32; | ^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | u32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:37:5 + --> tests/ui/cast_size.rs:39:5 | LL | 1usize as u32; | ^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | u32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:39:5 + --> tests/ui/cast_size.rs:41:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:39:5 + --> tests/ui/cast_size.rs:41:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | 1usize as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `i64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:42:5 + --> tests/ui/cast_size.rs:44:5 | LL | 1i64 as isize; | ^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | isize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:44:5 + --> tests/ui/cast_size.rs:46:5 | LL | 1i64 as usize; | ^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | usize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:46:5 + --> tests/ui/cast_size.rs:48:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -133,13 +133,13 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:46:5 + --> tests/ui/cast_size.rs:48:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:49:5 + --> tests/ui/cast_size.rs:51:5 | LL | 1u64 as usize; | ^^^^^^^^^^^^^ @@ -151,19 +151,19 @@ LL | usize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:51:5 + --> tests/ui/cast_size.rs:53:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:59:5 + --> tests/ui/cast_size.rs:61:5 | LL | 999_999_999 as f32; | ^^^^^^^^^^^^^^^^^^ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:61:5 + --> tests/ui/cast_size.rs:63:5 | LL | 9_999_999_999_999_999usize as f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_size.rs b/tests/ui/cast_size.rs index 9fc07b2ae4fd..f7c294357702 100644 --- a/tests/ui/cast_size.rs +++ b/tests/ui/cast_size.rs @@ -1,4 +1,6 @@ -//@stderr-per-bitwidth +//@revisions: 32bit 64bit +//@[32bit]ignore-bitwidth: 64 +//@[64bit]ignore-bitwidth: 32 //@no-rustfix #![warn( @@ -60,5 +62,6 @@ fn main() { //~^ cast_precision_loss 9_999_999_999_999_999usize as f64; //~^ cast_precision_loss + //~[32bit]^^ overflowing_literals // 999_999_999_999_999_999_999_999_999_999u128 as f128; } diff --git a/tests/ui/fn_to_numeric_cast.32bit.stderr b/tests/ui/fn_to_numeric_cast.32bit.stderr index 7093f8caf101..2affd0b7d6e9 100644 --- a/tests/ui/fn_to_numeric_cast.32bit.stderr +++ b/tests/ui/fn_to_numeric_cast.32bit.stderr @@ -1,5 +1,5 @@ error: casting function pointer `foo` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:10:13 + --> tests/ui/fn_to_numeric_cast.rs:12:13 | LL | let _ = foo as i8; | ^^^^^^^^^ help: try: `foo as usize` @@ -8,13 +8,13 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]` error: casting function pointer `foo` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:12:13 + --> tests/ui/fn_to_numeric_cast.rs:14:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i32` - --> tests/ui/fn_to_numeric_cast.rs:14:13 + --> tests/ui/fn_to_numeric_cast.rs:16:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ help: try: `foo as usize` @@ -23,121 +23,121 @@ LL | let _ = foo as i32; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]` error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:16:13 + --> tests/ui/fn_to_numeric_cast.rs:19:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:18:13 + --> tests/ui/fn_to_numeric_cast.rs:21:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:20:13 + --> tests/ui/fn_to_numeric_cast.rs:23:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:23:13 + --> tests/ui/fn_to_numeric_cast.rs:26:13 | LL | let _ = foo as u8; | ^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:25:13 + --> tests/ui/fn_to_numeric_cast.rs:28:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u32` - --> tests/ui/fn_to_numeric_cast.rs:27:13 + --> tests/ui/fn_to_numeric_cast.rs:30:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:29:13 + --> tests/ui/fn_to_numeric_cast.rs:33:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:31:13 + --> tests/ui/fn_to_numeric_cast.rs:35:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `abc` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:45:13 + --> tests/ui/fn_to_numeric_cast.rs:49:13 | LL | let _ = abc as i8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:47:13 + --> tests/ui/fn_to_numeric_cast.rs:51:13 | LL | let _ = abc as i16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i32` - --> tests/ui/fn_to_numeric_cast.rs:49:13 + --> tests/ui/fn_to_numeric_cast.rs:53:13 | LL | let _ = abc as i32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:51:13 + --> tests/ui/fn_to_numeric_cast.rs:56:13 | LL | let _ = abc as i64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:53:13 + --> tests/ui/fn_to_numeric_cast.rs:58:13 | LL | let _ = abc as i128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:55:13 + --> tests/ui/fn_to_numeric_cast.rs:60:13 | LL | let _ = abc as isize; | ^^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:58:13 + --> tests/ui/fn_to_numeric_cast.rs:63:13 | LL | let _ = abc as u8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:60:13 + --> tests/ui/fn_to_numeric_cast.rs:65:13 | LL | let _ = abc as u16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u32` - --> tests/ui/fn_to_numeric_cast.rs:62:13 + --> tests/ui/fn_to_numeric_cast.rs:67:13 | LL | let _ = abc as u32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:64:13 + --> tests/ui/fn_to_numeric_cast.rs:70:13 | LL | let _ = abc as u64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:66:13 + --> tests/ui/fn_to_numeric_cast.rs:72:13 | LL | let _ = abc as u128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `f` to `i32` - --> tests/ui/fn_to_numeric_cast.rs:74:5 + --> tests/ui/fn_to_numeric_cast.rs:80:5 | LL | f as i32 | ^^^^^^^^ help: try: `f as usize` diff --git a/tests/ui/fn_to_numeric_cast.64bit.stderr b/tests/ui/fn_to_numeric_cast.64bit.stderr index 1c2a0dab10b5..48961d14f2bb 100644 --- a/tests/ui/fn_to_numeric_cast.64bit.stderr +++ b/tests/ui/fn_to_numeric_cast.64bit.stderr @@ -1,5 +1,5 @@ error: casting function pointer `foo` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:10:13 + --> tests/ui/fn_to_numeric_cast.rs:12:13 | LL | let _ = foo as i8; | ^^^^^^^^^ help: try: `foo as usize` @@ -8,19 +8,19 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]` error: casting function pointer `foo` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:12:13 + --> tests/ui/fn_to_numeric_cast.rs:14:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:14:13 + --> tests/ui/fn_to_numeric_cast.rs:16:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:16:13 + --> tests/ui/fn_to_numeric_cast.rs:19:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ help: try: `foo as usize` @@ -29,115 +29,115 @@ LL | let _ = foo as i64; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]` error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:18:13 + --> tests/ui/fn_to_numeric_cast.rs:21:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:20:13 + --> tests/ui/fn_to_numeric_cast.rs:23:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:23:13 + --> tests/ui/fn_to_numeric_cast.rs:26:13 | LL | let _ = foo as u8; | ^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:25:13 + --> tests/ui/fn_to_numeric_cast.rs:28:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:27:13 + --> tests/ui/fn_to_numeric_cast.rs:30:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:29:13 + --> tests/ui/fn_to_numeric_cast.rs:33:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:31:13 + --> tests/ui/fn_to_numeric_cast.rs:35:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `abc` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:45:13 + --> tests/ui/fn_to_numeric_cast.rs:49:13 | LL | let _ = abc as i8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:47:13 + --> tests/ui/fn_to_numeric_cast.rs:51:13 | LL | let _ = abc as i16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:49:13 + --> tests/ui/fn_to_numeric_cast.rs:53:13 | LL | let _ = abc as i32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:51:13 + --> tests/ui/fn_to_numeric_cast.rs:56:13 | LL | let _ = abc as i64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:53:13 + --> tests/ui/fn_to_numeric_cast.rs:58:13 | LL | let _ = abc as i128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:55:13 + --> tests/ui/fn_to_numeric_cast.rs:60:13 | LL | let _ = abc as isize; | ^^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:58:13 + --> tests/ui/fn_to_numeric_cast.rs:63:13 | LL | let _ = abc as u8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:60:13 + --> tests/ui/fn_to_numeric_cast.rs:65:13 | LL | let _ = abc as u16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:62:13 + --> tests/ui/fn_to_numeric_cast.rs:67:13 | LL | let _ = abc as u32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:64:13 + --> tests/ui/fn_to_numeric_cast.rs:70:13 | LL | let _ = abc as u64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:66:13 + --> tests/ui/fn_to_numeric_cast.rs:72:13 | LL | let _ = abc as u128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `f` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:74:5 + --> tests/ui/fn_to_numeric_cast.rs:80:5 | LL | f as i32 | ^^^^^^^^ help: try: `f as usize` diff --git a/tests/ui/fn_to_numeric_cast.rs b/tests/ui/fn_to_numeric_cast.rs index 70be37c0f959..b09938dfc562 100644 --- a/tests/ui/fn_to_numeric_cast.rs +++ b/tests/ui/fn_to_numeric_cast.rs @@ -1,4 +1,6 @@ -//@stderr-per-bitwidth +//@revisions: 32bit 64bit +//@[32bit]ignore-bitwidth: 64 +//@[64bit]ignore-bitwidth: 32 //@no-rustfix #![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)] @@ -12,7 +14,8 @@ fn test_function_to_numeric_cast() { let _ = foo as i16; //~^ fn_to_numeric_cast_with_truncation let _ = foo as i32; - //~^ fn_to_numeric_cast_with_truncation + //~[64bit]^ fn_to_numeric_cast_with_truncation + //~[32bit]^^ fn_to_numeric_cast let _ = foo as i64; //~^ fn_to_numeric_cast let _ = foo as i128; @@ -25,7 +28,8 @@ fn test_function_to_numeric_cast() { let _ = foo as u16; //~^ fn_to_numeric_cast_with_truncation let _ = foo as u32; - //~^ fn_to_numeric_cast_with_truncation + //~[64bit]^ fn_to_numeric_cast_with_truncation + //~[32bit]^^ fn_to_numeric_cast let _ = foo as u64; //~^ fn_to_numeric_cast let _ = foo as u128; @@ -47,7 +51,8 @@ fn test_function_var_to_numeric_cast() { let _ = abc as i16; //~^ fn_to_numeric_cast_with_truncation let _ = abc as i32; - //~^ fn_to_numeric_cast_with_truncation + //~[64bit]^ fn_to_numeric_cast_with_truncation + //~[32bit]^^ fn_to_numeric_cast let _ = abc as i64; //~^ fn_to_numeric_cast let _ = abc as i128; @@ -60,7 +65,8 @@ fn test_function_var_to_numeric_cast() { let _ = abc as u16; //~^ fn_to_numeric_cast_with_truncation let _ = abc as u32; - //~^ fn_to_numeric_cast_with_truncation + //~[64bit]^ fn_to_numeric_cast_with_truncation + //~[32bit]^^ fn_to_numeric_cast let _ = abc as u64; //~^ fn_to_numeric_cast let _ = abc as u128; @@ -72,7 +78,8 @@ fn test_function_var_to_numeric_cast() { fn fn_with_fn_args(f: fn(i32) -> i32) -> i32 { f as i32 - //~^ fn_to_numeric_cast_with_truncation + //~[64bit]^ fn_to_numeric_cast_with_truncation + //~[32bit]^^ ERROR: literal out of range for `usize` } fn main() {} diff --git a/tests/ui/large_enum_variant.32bit.stderr b/tests/ui/large_enum_variant.32bit.stderr index af09a56854aa..7f66207ce797 100644 --- a/tests/ui/large_enum_variant.32bit.stderr +++ b/tests/ui/large_enum_variant.32bit.stderr @@ -1,5 +1,5 @@ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:11:1 + --> tests/ui/large_enum_variant.rs:13:1 | LL | / enum LargeEnum { LL | | @@ -18,7 +18,7 @@ LL | B(Box<[i32; 8000]>), | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:36:1 + --> tests/ui/large_enum_variant.rs:38:1 | LL | / enum LargeEnum2 { LL | | @@ -35,7 +35,7 @@ LL | ContainingLargeEnum(Box), | ~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:42:1 + --> tests/ui/large_enum_variant.rs:44:1 | LL | / enum LargeEnum3 { LL | | @@ -53,7 +53,7 @@ LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:49:1 + --> tests/ui/large_enum_variant.rs:51:1 | LL | / enum LargeEnum4 { LL | | @@ -70,7 +70,7 @@ LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:55:1 + --> tests/ui/large_enum_variant.rs:57:1 | LL | / enum LargeEnum5 { LL | | @@ -87,7 +87,7 @@ LL | StructLikeLarge2 { x: Box<[i32; 8000]> }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:72:1 + --> tests/ui/large_enum_variant.rs:74:1 | LL | / enum LargeEnum7 { LL | | @@ -105,7 +105,7 @@ LL | B(Box<[u8; 1255]>), | ~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:79:1 + --> tests/ui/large_enum_variant.rs:81:1 | LL | / enum LargeEnum8 { LL | | @@ -122,7 +122,7 @@ LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]> | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:85:1 + --> tests/ui/large_enum_variant.rs:87:1 | LL | / enum LargeEnum9 { LL | | @@ -139,7 +139,7 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:91:1 + --> tests/ui/large_enum_variant.rs:93:1 | LL | / enum LargeEnumOk2 { LL | | @@ -156,7 +156,7 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:97:1 + --> tests/ui/large_enum_variant.rs:99:1 | LL | / enum LargeEnumOk3 { LL | | @@ -173,7 +173,7 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:113:1 + --> tests/ui/large_enum_variant.rs:115:1 | LL | / enum CopyableLargeEnum { LL | | @@ -185,18 +185,18 @@ LL | | } | |_^ the entire enum is at least 64004 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:113:6 + --> tests/ui/large_enum_variant.rs:115:6 | LL | enum CopyableLargeEnum { | ^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:116:5 + --> tests/ui/large_enum_variant.rs:118:5 | LL | B([u64; 8000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:119:1 + --> tests/ui/large_enum_variant.rs:121:1 | LL | / enum ManuallyCopyLargeEnum { LL | | @@ -208,18 +208,18 @@ LL | | } | |_^ the entire enum is at least 64004 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:119:6 + --> tests/ui/large_enum_variant.rs:121:6 | LL | enum ManuallyCopyLargeEnum { | ^^^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:122:5 + --> tests/ui/large_enum_variant.rs:124:5 | LL | B([u64; 8000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:133:1 + --> tests/ui/large_enum_variant.rs:135:1 | LL | / enum SomeGenericPossiblyCopyEnum { LL | | @@ -231,18 +231,18 @@ LL | | } | |_^ the entire enum is at least 32004 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:133:6 + --> tests/ui/large_enum_variant.rs:135:6 | LL | enum SomeGenericPossiblyCopyEnum { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:136:5 + --> tests/ui/large_enum_variant.rs:138:5 | LL | B([u64; 4000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:147:1 + --> tests/ui/large_enum_variant.rs:149:1 | LL | / enum LargeEnumWithGenerics { LL | | @@ -259,7 +259,7 @@ LL | Large(Box<(T, [u8; 512])>), | ~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:157:1 + --> tests/ui/large_enum_variant.rs:159:1 | LL | / enum WithGenerics { LL | | @@ -276,7 +276,7 @@ LL | Large(Box<[Foo; 64]>), | ~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:168:1 + --> tests/ui/large_enum_variant.rs:170:1 | LL | / enum LargeEnumOfConst { LL | | @@ -293,7 +293,7 @@ LL | Error(Box>), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:174:1 + --> tests/ui/large_enum_variant.rs:176:1 | LL | / enum WithRecursion { LL | | @@ -310,7 +310,7 @@ LL | Large(Box<[u64; 64]>), | ~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:185:1 + --> tests/ui/large_enum_variant.rs:187:1 | LL | / enum LargeEnumWithGenericsAndRecursive { LL | | diff --git a/tests/ui/large_enum_variant.64bit.stderr b/tests/ui/large_enum_variant.64bit.stderr index 8f70ad2b5b72..dbc4c125e610 100644 --- a/tests/ui/large_enum_variant.64bit.stderr +++ b/tests/ui/large_enum_variant.64bit.stderr @@ -1,5 +1,5 @@ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:11:1 + --> tests/ui/large_enum_variant.rs:13:1 | LL | / enum LargeEnum { LL | | @@ -18,7 +18,7 @@ LL | B(Box<[i32; 8000]>), | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:36:1 + --> tests/ui/large_enum_variant.rs:38:1 | LL | / enum LargeEnum2 { LL | | @@ -35,7 +35,7 @@ LL | ContainingLargeEnum(Box), | ~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:42:1 + --> tests/ui/large_enum_variant.rs:44:1 | LL | / enum LargeEnum3 { LL | | @@ -53,7 +53,7 @@ LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:49:1 + --> tests/ui/large_enum_variant.rs:51:1 | LL | / enum LargeEnum4 { LL | | @@ -70,7 +70,7 @@ LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:55:1 + --> tests/ui/large_enum_variant.rs:57:1 | LL | / enum LargeEnum5 { LL | | @@ -87,7 +87,7 @@ LL | StructLikeLarge2 { x: Box<[i32; 8000]> }, | ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:72:1 + --> tests/ui/large_enum_variant.rs:74:1 | LL | / enum LargeEnum7 { LL | | @@ -105,7 +105,7 @@ LL | B(Box<[u8; 1255]>), | ~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:79:1 + --> tests/ui/large_enum_variant.rs:81:1 | LL | / enum LargeEnum8 { LL | | @@ -122,7 +122,7 @@ LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]> | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:85:1 + --> tests/ui/large_enum_variant.rs:87:1 | LL | / enum LargeEnum9 { LL | | @@ -139,7 +139,7 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:91:1 + --> tests/ui/large_enum_variant.rs:93:1 | LL | / enum LargeEnumOk2 { LL | | @@ -156,7 +156,7 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:97:1 + --> tests/ui/large_enum_variant.rs:99:1 | LL | / enum LargeEnumOk3 { LL | | @@ -173,7 +173,7 @@ LL | B(Box), | ~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:113:1 + --> tests/ui/large_enum_variant.rs:115:1 | LL | / enum CopyableLargeEnum { LL | | @@ -185,18 +185,18 @@ LL | | } | |_^ the entire enum is at least 64008 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:113:6 + --> tests/ui/large_enum_variant.rs:115:6 | LL | enum CopyableLargeEnum { | ^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:116:5 + --> tests/ui/large_enum_variant.rs:118:5 | LL | B([u64; 8000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:119:1 + --> tests/ui/large_enum_variant.rs:121:1 | LL | / enum ManuallyCopyLargeEnum { LL | | @@ -208,18 +208,18 @@ LL | | } | |_^ the entire enum is at least 64008 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:119:6 + --> tests/ui/large_enum_variant.rs:121:6 | LL | enum ManuallyCopyLargeEnum { | ^^^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:122:5 + --> tests/ui/large_enum_variant.rs:124:5 | LL | B([u64; 8000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:133:1 + --> tests/ui/large_enum_variant.rs:135:1 | LL | / enum SomeGenericPossiblyCopyEnum { LL | | @@ -231,18 +231,18 @@ LL | | } | |_^ the entire enum is at least 32008 bytes | note: boxing a variant would require the type no longer be `Copy` - --> tests/ui/large_enum_variant.rs:133:6 + --> tests/ui/large_enum_variant.rs:135:6 | LL | enum SomeGenericPossiblyCopyEnum { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider boxing the large fields to reduce the total size of the enum - --> tests/ui/large_enum_variant.rs:136:5 + --> tests/ui/large_enum_variant.rs:138:5 | LL | B([u64; 4000]), | ^^^^^^^^^^^^^^ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:147:1 + --> tests/ui/large_enum_variant.rs:149:1 | LL | / enum LargeEnumWithGenerics { LL | | @@ -259,7 +259,7 @@ LL | Large(Box<(T, [u8; 512])>), | ~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:157:1 + --> tests/ui/large_enum_variant.rs:159:1 | LL | / enum WithGenerics { LL | | @@ -276,7 +276,7 @@ LL | Large(Box<[Foo; 64]>), | ~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:168:1 + --> tests/ui/large_enum_variant.rs:170:1 | LL | / enum LargeEnumOfConst { LL | | @@ -293,7 +293,7 @@ LL | Error(Box>), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:174:1 + --> tests/ui/large_enum_variant.rs:176:1 | LL | / enum WithRecursion { LL | | @@ -310,7 +310,7 @@ LL | Large(Box<[u64; 64]>), | ~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:185:1 + --> tests/ui/large_enum_variant.rs:187:1 | LL | / enum LargeEnumWithGenericsAndRecursive { LL | | @@ -327,7 +327,7 @@ LL | Error(Box>), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:221:5 + --> tests/ui/large_enum_variant.rs:223:5 | LL | / enum NoWarnings { LL | | @@ -344,7 +344,7 @@ LL | BigBoi(Box), | ~~~~~~~~~~~~~~~~~~~~~ error: large size difference between variants - --> tests/ui/large_enum_variant.rs:227:5 + --> tests/ui/large_enum_variant.rs:229:5 | LL | / enum MakesClippyAngry { LL | | diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs index 9e0fc03cb4e1..9cf6318ca342 100644 --- a/tests/ui/large_enum_variant.rs +++ b/tests/ui/large_enum_variant.rs @@ -1,6 +1,8 @@ -//@stderr-per-bitwidth +//@revisions: 32bit 64bit //@aux-build:proc_macros.rs //@no-rustfix +//@[32bit]ignore-bitwidth: 64 +//@[64bit]ignore-bitwidth: 32 #![allow(dead_code)] #![allow(unused_variables)] #![warn(clippy::large_enum_variant)] @@ -219,13 +221,13 @@ mod issue11915 { } enum NoWarnings { - //~^ large_enum_variant + //~[64bit]^ large_enum_variant BigBoi(PublishWithBytes), _SmallBoi(u8), } enum MakesClippyAngry { - //~^ large_enum_variant + //~[64bit]^ large_enum_variant BigBoi(PublishWithVec), _SmallBoi(u8), } From 847bd6707d6a6d2a91dca93ad91119adee611a43 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 15 Feb 2025 15:41:30 +0100 Subject: [PATCH 130/991] f --- tests/ui/cast_size.rs | 2 +- tests/ui/fn_to_numeric_cast.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/cast_size.rs b/tests/ui/cast_size.rs index f7c294357702..e92401808867 100644 --- a/tests/ui/cast_size.rs +++ b/tests/ui/cast_size.rs @@ -62,6 +62,6 @@ fn main() { //~^ cast_precision_loss 9_999_999_999_999_999usize as f64; //~^ cast_precision_loss - //~[32bit]^^ overflowing_literals + //~[32bit]^^ ERROR: literal out of range for `usize` // 999_999_999_999_999_999_999_999_999_999u128 as f128; } diff --git a/tests/ui/fn_to_numeric_cast.rs b/tests/ui/fn_to_numeric_cast.rs index b09938dfc562..f53cbacdb377 100644 --- a/tests/ui/fn_to_numeric_cast.rs +++ b/tests/ui/fn_to_numeric_cast.rs @@ -79,7 +79,7 @@ fn test_function_var_to_numeric_cast() { fn fn_with_fn_args(f: fn(i32) -> i32) -> i32 { f as i32 //~[64bit]^ fn_to_numeric_cast_with_truncation - //~[32bit]^^ ERROR: literal out of range for `usize` + //~[32bit]^^ fn_to_numeric_cast } fn main() {} From e0a62acc8826875dcf2ff17750f6c28fcc69c2f4 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 2 Feb 2025 17:23:00 +0100 Subject: [PATCH 131/991] Add `clippy_utils::is_mutable()` --- clippy_utils/src/lib.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 0d9502c50db6..8130f2951c06 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -3675,3 +3675,24 @@ pub fn expr_requires_coercion<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) - _ => false, } } + +/// Returns `true` if `expr` designates a mutable static, a mutable local binding, or an expression +/// that can be owned. +pub fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + if let Some(hir_id) = path_to_local(expr) + && let Node::Pat(pat) = cx.tcx.hir_node(hir_id) + { + matches!(pat.kind, PatKind::Binding(BindingMode::MUT, ..)) + } else if let ExprKind::Path(p) = &expr.kind + && let Some(mutability) = cx + .qpath_res(p, expr.hir_id) + .opt_def_id() + .and_then(|id| cx.tcx.static_mutability(id)) + { + mutability == Mutability::Mut + } else if let ExprKind::Field(parent, _) = expr.kind { + is_mutable(cx, parent) + } else { + true + } +} From 35ad69c124d67faa72e3a61f77118d1fb0585002 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Mon, 10 Feb 2025 17:56:53 +0100 Subject: [PATCH 132/991] Cleanup: remove useless `span_is_local()` calls in `manual_slice_fill` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In both instances, `!assign_val.span.from_expansion()` – which is more restrictive than `span_is_local(assign_val.span)` – has been required already. --- clippy_lints/src/loops/manual_slice_fill.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/clippy_lints/src/loops/manual_slice_fill.rs b/clippy_lints/src/loops/manual_slice_fill.rs index bece83eaf3d8..70766b0b4e4b 100644 --- a/clippy_lints/src/loops/manual_slice_fill.rs +++ b/clippy_lints/src/loops/manual_slice_fill.rs @@ -1,6 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::eager_or_lazy::switch_to_eager_eval; -use clippy_utils::macros::span_is_local; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{HasSession, snippet_with_applicability}; use clippy_utils::ty::implements_trait; @@ -55,7 +54,6 @@ pub(super) fn check<'tcx>( && !assignval.span.from_expansion() // It is generally not equivalent to use the `fill` method if `assignval` can have side effects && switch_to_eager_eval(cx, assignval) - && span_is_local(assignval.span) // The `fill` method requires that the slice's element type implements the `Clone` trait. && let Some(clone_trait) = cx.tcx.lang_items().clone_trait() && implements_trait(cx, cx.typeck_results().expr_ty(slice), clone_trait, &[]) @@ -78,7 +76,6 @@ pub(super) fn check<'tcx>( && local == pat.hir_id && !assignval.span.from_expansion() && switch_to_eager_eval(cx, assignval) - && span_is_local(assignval.span) // The `fill` method cannot be used if the slice's element type does not implement the `Clone` trait. && let Some(clone_trait) = cx.tcx.lang_items().clone_trait() && implements_trait(cx, cx.typeck_results().expr_ty(recv), clone_trait, &[]) From 510d3b69fc2e13f7cc2cb485716aba6908f147dc Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 2 Feb 2025 19:11:14 +0100 Subject: [PATCH 133/991] Use `clippy_utils::is_mutable()` in `unnecessary_struct_initialization` --- .../src/unnecessary_struct_initialization.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/unnecessary_struct_initialization.rs b/clippy_lints/src/unnecessary_struct_initialization.rs index 1df229c330eb..5792b6b3178d 100644 --- a/clippy_lints/src/unnecessary_struct_initialization.rs +++ b/clippy_lints/src/unnecessary_struct_initialization.rs @@ -1,8 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; use clippy_utils::ty::is_copy; -use clippy_utils::{get_parent_expr, path_to_local}; -use rustc_hir::{BindingMode, Expr, ExprField, ExprKind, Node, PatKind, Path, QPath, StructTailExpr, UnOp}; +use clippy_utils::{get_parent_expr, is_mutable, path_to_local}; +use rustc_hir::{Expr, ExprField, ExprKind, Path, QPath, StructTailExpr, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -157,16 +157,6 @@ fn same_path_in_all_fields<'tcx>( } } -fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - if let Some(hir_id) = path_to_local(expr) - && let Node::Pat(pat) = cx.tcx.hir_node(hir_id) - { - matches!(pat.kind, PatKind::Binding(BindingMode::MUT, ..)) - } else { - true - } -} - fn check_references(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool { if let Some(parent) = get_parent_expr(cx, expr_a) && let parent_ty = cx.typeck_results().expr_ty_adjusted(parent) From 44aa75fd2aa94850103215c8e67b0d0baa24b6b7 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Mon, 10 Feb 2025 18:05:11 +0100 Subject: [PATCH 134/991] `manual_slice_fill`: initializer must not reference the iterator ```rust let mut tmp = vec![1, 2, 3]; for b in &mut tmp { *b = !*b; } ``` must not suggest the invalid `tmp.fill(!*b)`. --- clippy_lints/src/loops/manual_slice_fill.rs | 2 ++ tests/ui/manual_slice_fill.fixed | 8 ++++++++ tests/ui/manual_slice_fill.rs | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/clippy_lints/src/loops/manual_slice_fill.rs b/clippy_lints/src/loops/manual_slice_fill.rs index 70766b0b4e4b..a97641788621 100644 --- a/clippy_lints/src/loops/manual_slice_fill.rs +++ b/clippy_lints/src/loops/manual_slice_fill.rs @@ -76,6 +76,8 @@ pub(super) fn check<'tcx>( && local == pat.hir_id && !assignval.span.from_expansion() && switch_to_eager_eval(cx, assignval) + // `assignval` must not reference the iterator + && !is_local_used(cx, assignval, local) // The `fill` method cannot be used if the slice's element type does not implement the `Clone` trait. && let Some(clone_trait) = cx.tcx.lang_items().clone_trait() && implements_trait(cx, cx.typeck_results().expr_ty(recv), clone_trait, &[]) diff --git a/tests/ui/manual_slice_fill.fixed b/tests/ui/manual_slice_fill.fixed index 80e271117fc1..bba863247f5d 100644 --- a/tests/ui/manual_slice_fill.fixed +++ b/tests/ui/manual_slice_fill.fixed @@ -115,3 +115,11 @@ fn issue_14192() { tmp[0] = i; } } + +fn issue14189() { + // Should not lint because `!*b` is not constant + let mut tmp = vec![1, 2, 3]; + for b in &mut tmp { + *b = !*b; + } +} diff --git a/tests/ui/manual_slice_fill.rs b/tests/ui/manual_slice_fill.rs index f758f47bbcb0..44c60dc40f07 100644 --- a/tests/ui/manual_slice_fill.rs +++ b/tests/ui/manual_slice_fill.rs @@ -128,3 +128,11 @@ fn issue_14192() { tmp[0] = i; } } + +fn issue14189() { + // Should not lint because `!*b` is not constant + let mut tmp = vec![1, 2, 3]; + for b in &mut tmp { + *b = !*b; + } +} From 01d7a324dc66dfca20e1644419688c9d12b8f486 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Mon, 10 Feb 2025 13:09:31 +0100 Subject: [PATCH 135/991] `manual_strip`: use existing identifier instead of placeholder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the manually stripped entity receives a name as the first use through a simple `let` statement, this name can be used in the generated `if let Some(…)` expression instead of a placeholder. --- clippy_lints/src/manual_strip.rs | 73 +++++++++++++++++++++------- tests/ui/manual_strip.rs | 17 +++++++ tests/ui/manual_strip.stderr | 47 ++++++++++++++++-- tests/ui/manual_strip_fixable.fixed | 15 ++++++ tests/ui/manual_strip_fixable.rs | 17 +++++++ tests/ui/manual_strip_fixable.stderr | 40 +++++++++++++++ 6 files changed, 188 insertions(+), 21 deletions(-) create mode 100644 tests/ui/manual_strip_fixable.fixed create mode 100644 tests/ui/manual_strip_fixable.rs create mode 100644 tests/ui/manual_strip_fixable.stderr diff --git a/clippy_lints/src/manual_strip.rs b/clippy_lints/src/manual_strip.rs index d69384a2cb70..daed88b492e6 100644 --- a/clippy_lints/src/manual_strip.rs +++ b/clippy_lints/src/manual_strip.rs @@ -2,19 +2,21 @@ use clippy_config::Conf; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet; +use clippy_utils::source::snippet_with_applicability; use clippy_utils::usage::mutated_variables; use clippy_utils::{eq_expr_value, higher}; +use rustc_ast::BindingMode; use rustc_ast::ast::LitKind; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::intravisit::{Visitor, walk_expr}; -use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_hir::intravisit::{Visitor, walk_expr, walk_pat}; +use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, Node, PatKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext as _}; use rustc_middle::ty; use rustc_session::impl_lint_pass; use rustc_span::source_map::Spanned; -use rustc_span::{Span, sym}; +use rustc_span::{Symbol, sym}; use std::iter; declare_clippy_lint! { @@ -95,7 +97,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip { return; } - let strippings = find_stripping(cx, strip_kind, target_res, pattern, then); + let (strippings, bindings) = find_stripping(cx, strip_kind, target_res, pattern, then); if !strippings.is_empty() { let kind_word = match strip_kind { StripKind::Prefix => "prefix", @@ -103,10 +105,29 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip { }; let test_span = expr.span.until(then.span); + + // If the first use is a simple `let` statement, reuse its identifier in the `if let Some(…)` and + // remove the `let` statement as long as the identifier is never bound again within the lexical + // scope of interest. + let (ident_name, let_stmt_span, skip, mut app) = if let Node::LetStmt(let_stmt) = + cx.tcx.parent_hir_node(strippings[0].hir_id) + && let PatKind::Binding(BindingMode::NONE, _, ident, None) = &let_stmt.pat.kind + && bindings.get(&ident.name) == Some(&1) + { + ( + ident.name.as_str(), + Some(cx.sess().source_map().span_extend_while_whitespace(let_stmt.span)), + 1, + Applicability::MachineApplicable, + ) + } else { + ("", None, 0, Applicability::HasPlaceholders) + }; + span_lint_and_then( cx, MANUAL_STRIP, - strippings[0], + strippings[0].span, format!("stripping a {kind_word} manually"), |diag| { diag.span_note(test_span, format!("the {kind_word} was tested here")); @@ -115,14 +136,20 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip { iter::once(( test_span, format!( - "if let Some() = {}.strip_{kind_word}({}) ", - snippet(cx, target_arg.span, ".."), - snippet(cx, pattern.span, "..") + "if let Some({ident_name}) = {}.strip_{kind_word}({}) ", + snippet_with_applicability(cx, target_arg.span, "_", &mut app), + snippet_with_applicability(cx, pattern.span, "_", &mut app) ), )) - .chain(strippings.into_iter().map(|span| (span, "".into()))) + .chain(let_stmt_span.map(|span| (span, String::new()))) + .chain( + strippings + .into_iter() + .skip(skip) + .map(|expr| (expr.span, ident_name.into())), + ) .collect(), - Applicability::HasPlaceholders, + app, ); }, ); @@ -188,19 +215,21 @@ fn peel_ref<'a>(expr: &'a Expr<'_>) -> &'a Expr<'a> { /// Find expressions where `target` is stripped using the length of `pattern`. /// We'll suggest replacing these expressions with the result of the `strip_{prefix,suffix}` /// method. +/// Also, all bindings found during the visit are counted and returned. fn find_stripping<'tcx>( cx: &LateContext<'tcx>, strip_kind: StripKind, target: Res, pattern: &'tcx Expr<'_>, - expr: &'tcx Expr<'_>, -) -> Vec { + expr: &'tcx Expr<'tcx>, +) -> (Vec<&'tcx Expr<'tcx>>, FxHashMap) { struct StrippingFinder<'a, 'tcx> { cx: &'a LateContext<'tcx>, strip_kind: StripKind, target: Res, pattern: &'tcx Expr<'tcx>, - results: Vec, + results: Vec<&'tcx Expr<'tcx>>, + bindings: FxHashMap, } impl<'tcx> Visitor<'tcx> for StrippingFinder<'_, 'tcx> { @@ -215,7 +244,7 @@ fn find_stripping<'tcx>( match (self.strip_kind, start, end) { (StripKind::Prefix, Some(start), None) => { if eq_pattern_length(self.cx, self.pattern, start) { - self.results.push(ex.span); + self.results.push(ex); return; } }, @@ -232,7 +261,7 @@ fn find_stripping<'tcx>( && self.cx.qpath_res(left_path, left_arg.hir_id) == self.target && eq_pattern_length(self.cx, self.pattern, right) { - self.results.push(ex.span); + self.results.push(ex); return; } }, @@ -242,6 +271,13 @@ fn find_stripping<'tcx>( walk_expr(self, ex); } + + fn visit_pat(&mut self, pat: &'tcx rustc_hir::Pat<'tcx>) -> Self::Result { + if let PatKind::Binding(_, _, ident, _) = pat.kind { + *self.bindings.entry(ident.name).or_default() += 1; + } + walk_pat(self, pat); + } } let mut finder = StrippingFinder { @@ -250,7 +286,8 @@ fn find_stripping<'tcx>( target, pattern, results: vec![], + bindings: FxHashMap::default(), }; walk_expr(&mut finder, expr); - finder.results + (finder.results, finder.bindings) } diff --git a/tests/ui/manual_strip.rs b/tests/ui/manual_strip.rs index ce53c99e6b50..086b75a39875 100644 --- a/tests/ui/manual_strip.rs +++ b/tests/ui/manual_strip.rs @@ -74,6 +74,23 @@ fn main() { if s3.starts_with("ab") { s4[2..].to_string(); } + + // Don't propose to reuse the `stripped` identifier as it is overriden + if s.starts_with("ab") { + let stripped = &s["ab".len()..]; + //~^ ERROR: stripping a prefix manually + let stripped = format!("{stripped}-"); + println!("{stripped}{}", &s["ab".len()..]); + } + + // Don't propose to reuse the `stripped` identifier as it is mutable + if s.starts_with("ab") { + let mut stripped = &s["ab".len()..]; + //~^ ERROR: stripping a prefix manually + stripped = ""; + let stripped = format!("{stripped}-"); + println!("{stripped}{}", &s["ab".len()..]); + } } #[clippy::msrv = "1.44"] diff --git a/tests/ui/manual_strip.stderr b/tests/ui/manual_strip.stderr index 41d15da610c4..a323ef700e76 100644 --- a/tests/ui/manual_strip.stderr +++ b/tests/ui/manual_strip.stderr @@ -138,13 +138,54 @@ LL ~ .to_uppercase(); | error: stripping a prefix manually - --> tests/ui/manual_strip.rs:91:9 + --> tests/ui/manual_strip.rs:80:24 + | +LL | let stripped = &s["ab".len()..]; + | ^^^^^^^^^^^^^^^^ + | +note: the prefix was tested here + --> tests/ui/manual_strip.rs:79:5 + | +LL | if s.starts_with("ab") { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: try using the `strip_prefix` method + | +LL ~ if let Some() = s.strip_prefix("ab") { +LL ~ let stripped = ; +LL | +LL | let stripped = format!("{stripped}-"); +LL ~ println!("{stripped}{}", ); + | + +error: stripping a prefix manually + --> tests/ui/manual_strip.rs:88:28 + | +LL | let mut stripped = &s["ab".len()..]; + | ^^^^^^^^^^^^^^^^ + | +note: the prefix was tested here + --> tests/ui/manual_strip.rs:87:5 + | +LL | if s.starts_with("ab") { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: try using the `strip_prefix` method + | +LL ~ if let Some() = s.strip_prefix("ab") { +LL ~ let mut stripped = ; +LL | +LL | stripped = ""; +LL | let stripped = format!("{stripped}-"); +LL ~ println!("{stripped}{}", ); + | + +error: stripping a prefix manually + --> tests/ui/manual_strip.rs:108:9 | LL | s[1..].to_string(); | ^^^^^^ | note: the prefix was tested here - --> tests/ui/manual_strip.rs:90:5 + --> tests/ui/manual_strip.rs:107:5 | LL | if s.starts_with('a') { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -154,5 +195,5 @@ LL ~ if let Some() = s.strip_prefix('a') { LL ~ .to_string(); | -error: aborting due to 8 previous errors +error: aborting due to 10 previous errors diff --git a/tests/ui/manual_strip_fixable.fixed b/tests/ui/manual_strip_fixable.fixed new file mode 100644 index 000000000000..75a3f1645de3 --- /dev/null +++ b/tests/ui/manual_strip_fixable.fixed @@ -0,0 +1,15 @@ +#![warn(clippy::manual_strip)] + +fn main() { + let s = "abc"; + + if let Some(stripped) = s.strip_prefix("ab") { + //~^ ERROR: stripping a prefix manually + println!("{stripped}{}", stripped); + } + + if let Some(stripped) = s.strip_suffix("bc") { + //~^ ERROR: stripping a suffix manually + println!("{stripped}{}", stripped); + } +} diff --git a/tests/ui/manual_strip_fixable.rs b/tests/ui/manual_strip_fixable.rs new file mode 100644 index 000000000000..5080068449e2 --- /dev/null +++ b/tests/ui/manual_strip_fixable.rs @@ -0,0 +1,17 @@ +#![warn(clippy::manual_strip)] + +fn main() { + let s = "abc"; + + if s.starts_with("ab") { + let stripped = &s["ab".len()..]; + //~^ ERROR: stripping a prefix manually + println!("{stripped}{}", &s["ab".len()..]); + } + + if s.ends_with("bc") { + let stripped = &s[..s.len() - "bc".len()]; + //~^ ERROR: stripping a suffix manually + println!("{stripped}{}", &s[..s.len() - "bc".len()]); + } +} diff --git a/tests/ui/manual_strip_fixable.stderr b/tests/ui/manual_strip_fixable.stderr new file mode 100644 index 000000000000..1c276e5d8fdf --- /dev/null +++ b/tests/ui/manual_strip_fixable.stderr @@ -0,0 +1,40 @@ +error: stripping a prefix manually + --> tests/ui/manual_strip_fixable.rs:7:24 + | +LL | let stripped = &s["ab".len()..]; + | ^^^^^^^^^^^^^^^^ + | +note: the prefix was tested here + --> tests/ui/manual_strip_fixable.rs:6:5 + | +LL | if s.starts_with("ab") { + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::manual-strip` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_strip)]` +help: try using the `strip_prefix` method + | +LL ~ if let Some(stripped) = s.strip_prefix("ab") { +LL ~ +LL ~ println!("{stripped}{}", stripped); + | + +error: stripping a suffix manually + --> tests/ui/manual_strip_fixable.rs:13:24 + | +LL | let stripped = &s[..s.len() - "bc".len()]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the suffix was tested here + --> tests/ui/manual_strip_fixable.rs:12:5 + | +LL | if s.ends_with("bc") { + | ^^^^^^^^^^^^^^^^^^^^^ +help: try using the `strip_suffix` method + | +LL ~ if let Some(stripped) = s.strip_suffix("bc") { +LL ~ +LL ~ println!("{stripped}{}", stripped); + | + +error: aborting due to 2 previous errors + From 17472a9f80e6143538f5c29d9bbc0f1acf8dae4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 30 Jan 2025 15:07:24 +0100 Subject: [PATCH 136/991] Improve GCC build in bootstrap --- src/bootstrap/src/core/build_steps/compile.rs | 9 ++++ src/bootstrap/src/core/build_steps/gcc.rs | 51 ++++++++++++++----- src/bootstrap/src/core/build_steps/test.rs | 7 ++- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 479327d63695..44469da1e648 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -17,6 +17,7 @@ use std::{env, fs, str}; use serde_derive::Deserialize; +use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags}; use crate::core::build_steps::tool::SourceType; use crate::core::build_steps::{dist, llvm}; use crate::core::builder; @@ -1500,6 +1501,14 @@ impl Step for CodegenBackend { .arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml"))); rustc_cargo_env(builder, &mut cargo, target, compiler.stage); + // Ideally, we'd have a separate step for the individual codegen backends, + // like we have in tests (test::CodegenGCC) but that would require a lot of restructuring. + // If the logic gets more complicated, it should probably be done. + if backend == "gcc" { + let gcc = builder.ensure(Gcc { target }); + add_cg_gcc_cargo_flags(&mut cargo, &gcc); + } + let tmp_stamp = BuildStamp::new(&out_dir).with_prefix("tmp"); let _guard = builder.msg_build(compiler, format_args!("codegen backend {backend}"), target); diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 98b8635132b0..3edca8834e06 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -9,13 +9,13 @@ //! ensure that they're always in place if needed. use std::fs; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::sync::OnceLock; use build_helper::ci::CiEnv; use crate::Kind; -use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::core::builder::{Builder, Cargo, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash}; use crate::utils::exec::command; @@ -29,7 +29,8 @@ pub struct Meta { } pub enum GccBuildStatus { - AlreadyBuilt, + /// libgccjit is already built at this path + AlreadyBuilt(PathBuf), ShouldBuild(Meta), } @@ -41,9 +42,6 @@ pub fn prebuilt_gcc_config(builder: &Builder<'_>, target: TargetSelection) -> Gc // Initialize the gcc submodule if not initialized already. builder.config.update_submodule("src/gcc"); - // FIXME (GuillaumeGomez): To be done once gccjit has been built in the CI. - // builder.config.maybe_download_ci_gcc(); - let root = builder.src.join("src/gcc"); let out_dir = builder.gcc_out(target).join("build"); let install_dir = builder.gcc_out(target).join("install"); @@ -70,19 +68,37 @@ pub fn prebuilt_gcc_config(builder: &Builder<'_>, target: TargetSelection) -> Gc stamp.path().display() )); } - return GccBuildStatus::AlreadyBuilt; + let path = libgccjit_built_path(&install_dir); + if path.is_file() { + return GccBuildStatus::AlreadyBuilt(path); + } else { + builder.info(&format!( + "GCC stamp is up-to-date, but the libgccjit.so file was not found at `{}`", + path.display(), + )); + } } GccBuildStatus::ShouldBuild(Meta { stamp, out_dir, install_dir, root }) } +/// Returns the path to a libgccjit.so file in the install directory of GCC. +fn libgccjit_built_path(install_dir: &Path) -> PathBuf { + install_dir.join("lib/libgccjit.so") +} + #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Gcc { pub target: TargetSelection, } +#[derive(Clone)] +pub struct GccOutput { + pub libgccjit: PathBuf, +} + impl Step for Gcc { - type Output = bool; + type Output = GccOutput; const ONLY_HOSTS: bool = true; @@ -94,14 +110,14 @@ impl Step for Gcc { run.builder.ensure(Gcc { target: run.target }); } - /// Compile GCC for `target`. - fn run(self, builder: &Builder<'_>) -> bool { + /// Compile GCC (specifically `libgccjit`) for `target`. + fn run(self, builder: &Builder<'_>) -> Self::Output { let target = self.target; // If GCC has already been built, we avoid building it again. let Meta { stamp, out_dir, install_dir, root } = match prebuilt_gcc_config(builder, target) { - GccBuildStatus::AlreadyBuilt => return true, + GccBuildStatus::AlreadyBuilt(path) => return GccOutput { libgccjit: path }, GccBuildStatus::ShouldBuild(m) => m, }; @@ -110,8 +126,9 @@ impl Step for Gcc { let _time = helpers::timeit(builder); t!(fs::create_dir_all(&out_dir)); + let libgccjit_path = libgccjit_built_path(&install_dir); if builder.config.dry_run() { - return true; + return GccOutput { libgccjit: libgccjit_path }; } // GCC creates files (e.g. symlinks to the downloaded dependencies) @@ -173,11 +190,17 @@ impl Step for Gcc { let lib_alias = install_dir.join("lib/libgccjit.so.0"); if !lib_alias.exists() { - t!(builder.symlink_file(install_dir.join("lib/libgccjit.so"), lib_alias,)); + t!(builder.symlink_file(&libgccjit_path, lib_alias)); } t!(stamp.write()); - true + GccOutput { libgccjit: libgccjit_path } } } + +/// Configures a Cargo invocation so that it can build the GCC codegen backend. +pub fn add_cg_gcc_cargo_flags(cargo: &mut Cargo, gcc: &GccOutput) { + // Add the path to libgccjit.so to the linker search paths. + cargo.rustflag(&format!("-L{}", gcc.libgccjit.parent().unwrap().display())); +} diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 26ed0e5deaa0..c3eceda0d1a6 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -12,6 +12,7 @@ use clap_complete::shells; use crate::core::build_steps::compile::run_cargo; use crate::core::build_steps::doc::DocumentationFormat; +use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags}; use crate::core::build_steps::llvm::get_llvm_version; use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget; use crate::core::build_steps::tool::{self, SourceType, Tool}; @@ -3520,6 +3521,8 @@ impl Step for CodegenGCC { let compiler = self.compiler; let target = self.target; + let gcc = builder.ensure(Gcc { target }); + builder.ensure( compile::Std::new(compiler, target) .extra_rust_args(&["-Csymbol-mangling-version=v0", "-Cpanic=abort"]), @@ -3546,6 +3549,7 @@ impl Step for CodegenGCC { .arg("--manifest-path") .arg(builder.src.join("compiler/rustc_codegen_gcc/build_system/Cargo.toml")); compile::rustc_cargo_env(builder, &mut cargo, target, compiler.stage); + add_cg_gcc_cargo_flags(&mut cargo, &gcc); // Avoid incremental cache issues when changing rustc cargo.env("CARGO_BUILD_INCREMENTAL", "false"); @@ -3578,9 +3582,10 @@ impl Step for CodegenGCC { .env("CG_RUSTFLAGS", "-Alinker-messages") .arg("--") .arg("test") - .arg("--use-system-gcc") .arg("--use-backend") .arg("gcc") + .arg("--gcc-path") + .arg(gcc.libgccjit.parent().unwrap()) .arg("--out-dir") .arg(builder.stage_out(compiler, Mode::ToolRustc).join("cg_gcc")) .arg("--release") From b4d9d025382c8dd89d5a0f362bde676254d886ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 14 Feb 2025 18:46:52 +0100 Subject: [PATCH 137/991] Install bzip2 It is apparently required to download GCC dependencies. --- src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile index 374d12cc087e..aefc0f376f68 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile @@ -3,6 +3,7 @@ FROM ubuntu:24.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ + bzip2 \ g++ \ gcc-multilib \ make \ From 58be00a4f58496fce5df9176270ce63707d948c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 15 Feb 2025 11:54:46 +0100 Subject: [PATCH 138/991] Update license metadata --- license-metadata.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/license-metadata.json b/license-metadata.json index 4cf9bea2861d..4fb59210854e 100644 --- a/license-metadata.json +++ b/license-metadata.json @@ -13,7 +13,8 @@ "directories": [], "files": [ "analyzer-decls.h", - "malloc-macro.h" + "malloc-macro.h", + "sarif-path-role.h" ], "license": { "copyright": [ From 91548d0fe33eeab33db48e81d7a07d7edee0965a Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Sat, 8 Feb 2025 22:10:12 +0900 Subject: [PATCH 139/991] prevent `useless_asref` from suggesting `.clone()` on types without the `Clone` trait --- clippy_lints/src/methods/useless_asref.rs | 5 +++- tests/ui/useless_asref.fixed | 30 +++++++++++++++++++ tests/ui/useless_asref.rs | 30 +++++++++++++++++++ tests/ui/useless_asref.stderr | 36 +++++++++++------------ 4 files changed, 82 insertions(+), 19 deletions(-) diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs index 6d3da42775f4..58bce32c1ac6 100644 --- a/clippy_lints/src/methods/useless_asref.rs +++ b/clippy_lints/src/methods/useless_asref.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::ty::{should_call_clone_as_function, walk_ptrs_ty_depth}; +use clippy_utils::ty::{implements_trait, should_call_clone_as_function, walk_ptrs_ty_depth}; use clippy_utils::{ get_parent_expr, is_diag_trait_item, match_def_path, path_to_local_id, peel_blocks, strip_pat_refs, }; @@ -101,6 +101,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, && is_calling_clone(cx, arg) // And that we are not recommending recv.clone() over Arc::clone() or similar && !should_call_clone_as_function(cx, rcv_ty) + // https://github.com/rust-lang/rust-clippy/issues/12357 + && let Some(clone_trait) = cx.tcx.lang_items().clone_trait() + && implements_trait(cx, cx.typeck_results().expr_ty(recvr), clone_trait, &[]) { lint_as_ref_clone(cx, expr.span.with_hi(parent.span.hi()), recvr, call_name); } diff --git a/tests/ui/useless_asref.fixed b/tests/ui/useless_asref.fixed index e399bd76fc1e..8c1f948fb580 100644 --- a/tests/ui/useless_asref.fixed +++ b/tests/ui/useless_asref.fixed @@ -8,6 +8,7 @@ )] use std::fmt::Debug; +use std::ops::Deref; use std::rc::{Rc, Weak as RcWeak}; use std::sync::{Arc, Weak as ArcWeak}; @@ -218,6 +219,35 @@ fn issue_14088() { let _: Option<&str> = s.as_ref().map(|x| x.as_ref()); } +pub struct Wrap { + inner: T, +} + +impl Deref for Wrap { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +struct NonCloneableError; + +pub struct Issue12357 { + current: Option>>, +} + +impl Issue12357 { + fn f(&self) -> Option> { + self.current.as_ref().map(|p| Arc::clone(p)) + } + + fn g(&self) { + let result: Result = Ok("Hello".to_string()); + let cloned = result.as_ref().map(|s| s.clone()); + } +} + fn main() { not_ok(); ok(); diff --git a/tests/ui/useless_asref.rs b/tests/ui/useless_asref.rs index 4c76a2ecf7b0..d9db2d4f5596 100644 --- a/tests/ui/useless_asref.rs +++ b/tests/ui/useless_asref.rs @@ -8,6 +8,7 @@ )] use std::fmt::Debug; +use std::ops::Deref; use std::rc::{Rc, Weak as RcWeak}; use std::sync::{Arc, Weak as ArcWeak}; @@ -218,6 +219,35 @@ fn issue_14088() { let _: Option<&str> = s.as_ref().map(|x| x.as_ref()); } +pub struct Wrap { + inner: T, +} + +impl Deref for Wrap { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +struct NonCloneableError; + +pub struct Issue12357 { + current: Option>>, +} + +impl Issue12357 { + fn f(&self) -> Option> { + self.current.as_ref().map(|p| Arc::clone(p)) + } + + fn g(&self) { + let result: Result = Ok("Hello".to_string()); + let cloned = result.as_ref().map(|s| s.clone()); + } +} + fn main() { not_ok(); ok(); diff --git a/tests/ui/useless_asref.stderr b/tests/ui/useless_asref.stderr index d0ca10936fd5..8255f5d9d2ab 100644 --- a/tests/ui/useless_asref.stderr +++ b/tests/ui/useless_asref.stderr @@ -1,5 +1,5 @@ error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:50:18 + --> tests/ui/useless_asref.rs:51:18 | LL | foo_rstr(rstr.as_ref()); | ^^^^^^^^^^^^^ help: try: `rstr` @@ -11,103 +11,103 @@ LL | #![deny(clippy::useless_asref)] | ^^^^^^^^^^^^^^^^^^^^^ error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:53:20 + --> tests/ui/useless_asref.rs:54:20 | LL | foo_rslice(rslice.as_ref()); | ^^^^^^^^^^^^^^^ help: try: `rslice` error: this call to `as_mut` does nothing - --> tests/ui/useless_asref.rs:58:21 + --> tests/ui/useless_asref.rs:59:21 | LL | foo_mrslice(mrslice.as_mut()); | ^^^^^^^^^^^^^^^^ help: try: `mrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:61:20 + --> tests/ui/useless_asref.rs:62:20 | LL | foo_rslice(mrslice.as_ref()); | ^^^^^^^^^^^^^^^^ help: try: `mrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:69:20 + --> tests/ui/useless_asref.rs:70:20 | LL | foo_rslice(rrrrrslice.as_ref()); | ^^^^^^^^^^^^^^^^^^^ help: try: `rrrrrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:72:18 + --> tests/ui/useless_asref.rs:73:18 | LL | foo_rstr(rrrrrstr.as_ref()); | ^^^^^^^^^^^^^^^^^ help: try: `rrrrrstr` error: this call to `as_mut` does nothing - --> tests/ui/useless_asref.rs:78:21 + --> tests/ui/useless_asref.rs:79:21 | LL | foo_mrslice(mrrrrrslice.as_mut()); | ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:81:20 + --> tests/ui/useless_asref.rs:82:20 | LL | foo_rslice(mrrrrrslice.as_ref()); | ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:86:16 + --> tests/ui/useless_asref.rs:87:16 | LL | foo_rrrrmr((&&&&MoreRef).as_ref()); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&&&&MoreRef)` error: this call to `as_mut` does nothing - --> tests/ui/useless_asref.rs:137:13 + --> tests/ui/useless_asref.rs:138:13 | LL | foo_mrt(mrt.as_mut()); | ^^^^^^^^^^^^ help: try: `mrt` error: this call to `as_ref` does nothing - --> tests/ui/useless_asref.rs:140:12 + --> tests/ui/useless_asref.rs:141:12 | LL | foo_rt(mrt.as_ref()); | ^^^^^^^^^^^^ help: try: `mrt` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:152:13 + --> tests/ui/useless_asref.rs:153:13 | LL | let z = x.as_ref().map(String::clone); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:155:13 + --> tests/ui/useless_asref.rs:156:13 | LL | let z = x.as_ref().map(|z| z.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:158:13 + --> tests/ui/useless_asref.rs:159:13 | LL | let z = x.as_ref().map(|z| String::clone(z)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:182:9 + --> tests/ui/useless_asref.rs:183:9 | LL | x.field.as_ref().map(|v| v.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:185:9 + --> tests/ui/useless_asref.rs:186:9 | LL | x.field.as_ref().map(Clone::clone); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:188:9 + --> tests/ui/useless_asref.rs:189:9 | LL | x.field.as_ref().map(|v| Clone::clone(v)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()` error: this call to `as_ref.map(...)` does nothing - --> tests/ui/useless_asref.rs:193:9 + --> tests/ui/useless_asref.rs:194:9 | LL | Some(1).as_ref().map(|&x| x.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(1).clone()` From fd17bfe57d615673f94e1c4a5686222ad03a1056 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Tue, 11 Feb 2025 15:16:32 +0900 Subject: [PATCH 140/991] add `manual_contains` lint --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/methods/manual_contains.rs | 113 ++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 30 ++++++ tests/ui/manual_contains.fixed | 98 +++++++++++++++++ tests/ui/manual_contains.rs | 98 +++++++++++++++++ tests/ui/manual_contains.stderr | 77 +++++++++++++ tests/ui/needless_collect.fixed | 8 +- tests/ui/needless_collect.rs | 8 +- tests/ui/needless_collect.stderr | 38 +++---- tests/ui/search_is_some_fixable_none.fixed | 2 +- tests/ui/search_is_some_fixable_none.rs | 2 +- tests/ui/search_is_some_fixable_some.fixed | 2 +- tests/ui/search_is_some_fixable_some.rs | 2 +- 14 files changed, 455 insertions(+), 25 deletions(-) create mode 100644 clippy_lints/src/methods/manual_contains.rs create mode 100644 tests/ui/manual_contains.fixed create mode 100644 tests/ui/manual_contains.rs create mode 100644 tests/ui/manual_contains.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index a1ea3ce8f79d..2b8695f66279 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5743,6 +5743,7 @@ Released 2018-09-13 [`manual_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits [`manual_c_str_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals [`manual_clamp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp +[`manual_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_contains [`manual_div_ceil`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_div_ceil [`manual_filter`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter [`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter_map diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 1f00fb82c6db..4b439d3a7a2d 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -418,6 +418,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::methods::ITER_SKIP_ZERO_INFO, crate::methods::ITER_WITH_DRAIN_INFO, crate::methods::JOIN_ABSOLUTE_PATHS_INFO, + crate::methods::MANUAL_CONTAINS_INFO, crate::methods::MANUAL_C_STR_LITERALS_INFO, crate::methods::MANUAL_FILTER_MAP_INFO, crate::methods::MANUAL_FIND_MAP_INFO, diff --git a/clippy_lints/src/methods/manual_contains.rs b/clippy_lints/src/methods/manual_contains.rs new file mode 100644 index 000000000000..61bf32cc19bb --- /dev/null +++ b/clippy_lints/src/methods/manual_contains.rs @@ -0,0 +1,113 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::eager_or_lazy::switch_to_eager_eval; +use clippy_utils::peel_hir_pat_refs; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::sugg::Sugg; +use rustc_ast::UnOp; +use rustc_errors::Applicability; +use rustc_hir::def::Res; +use rustc_hir::{BinOpKind, Body, Expr, ExprKind, HirId, QPath}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self}; +use rustc_span::source_map::Spanned; + +use super::MANUAL_CONTAINS; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, closure_arg: &Expr<'_>) { + let mut app = Applicability::MachineApplicable; + + if !expr.span.from_expansion() + // check if `iter().any()` can be replaced with `contains()` + && let ExprKind::Closure(closure) = closure_arg.kind + && let Body{params: [param],value} = cx.tcx.hir().body(closure.body) + && let ExprKind::Binary(op, lhs, rhs) = value.kind + && let (peeled_ref_pat, _) = peel_hir_pat_refs(param.pat) + && let Some((snip,snip_expr)) = can_replace_with_contains(cx, op, lhs, rhs, peeled_ref_pat.hir_id, &mut app) + && let ref_type = cx.typeck_results().expr_ty_adjusted(recv) + && let ty::Ref(_, inner_type, _) = ref_type.kind() + && let ty::Slice(slice_type) = inner_type.kind() + && *slice_type == cx.typeck_results().expr_ty(snip_expr) + { + span_lint_and_sugg( + cx, + MANUAL_CONTAINS, + expr.span, + "using `contains()` instead of `iter().any()` is more efficient", + "try", + format!( + "{}.contains({})", + snippet_with_applicability(cx, recv.span, "_", &mut app), + snip + ), + app, + ); + } +} + +enum EligibleArg { + IsClosureArg, + ContainsArg(String), +} + +fn try_get_eligible_arg<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'tcx>, + closure_arg_id: HirId, + applicability: &mut Applicability, +) -> Option<(EligibleArg, &'tcx Expr<'tcx>)> { + let mut get_snippet = |expr: &Expr<'_>, needs_borrow: bool| { + let sugg = Sugg::hir_with_applicability(cx, expr, "_", applicability); + EligibleArg::ContainsArg((if needs_borrow { sugg.addr() } else { sugg }).to_string()) + }; + + match expr.kind { + ExprKind::Path(QPath::Resolved(_, path)) => { + if path.res == Res::Local(closure_arg_id) { + Some((EligibleArg::IsClosureArg, expr)) + } else { + Some((get_snippet(expr, true), expr)) + } + }, + ExprKind::Unary(UnOp::Deref, inner) => { + if let ExprKind::Path(QPath::Resolved(_, path)) = inner.kind { + if path.res == Res::Local(closure_arg_id) { + Some((EligibleArg::IsClosureArg, expr)) + } else { + Some((get_snippet(inner, false), expr)) + } + } else { + None + } + }, + _ => { + if switch_to_eager_eval(cx, expr) { + Some((get_snippet(expr, true), expr)) + } else { + None + } + }, + } +} + +fn can_replace_with_contains<'tcx>( + cx: &LateContext<'tcx>, + bin_op: Spanned, + left_expr: &'tcx Expr<'tcx>, + right_expr: &'tcx Expr<'tcx>, + closure_arg_id: HirId, + applicability: &mut Applicability, +) -> Option<(String, &'tcx Expr<'tcx>)> { + if bin_op.node != BinOpKind::Eq { + return None; + } + + let left_candidate = try_get_eligible_arg(cx, left_expr, closure_arg_id, applicability)?; + let right_candidate = try_get_eligible_arg(cx, right_expr, closure_arg_id, applicability)?; + match (left_candidate, right_candidate) { + ((EligibleArg::IsClosureArg, _), (EligibleArg::ContainsArg(snip), candidate_expr)) + | ((EligibleArg::ContainsArg(snip), candidate_expr), (EligibleArg::IsClosureArg, _)) => { + Some((snip, candidate_expr)) + }, + _ => None, + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 7e9db66ff864..7e66016b89d9 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -54,6 +54,7 @@ mod iter_with_drain; mod iterator_step_by_zero; mod join_absolute_paths; mod manual_c_str_literals; +mod manual_contains; mod manual_inspect; mod manual_is_variant_and; mod manual_next_back; @@ -4434,6 +4435,31 @@ declare_clippy_lint! { "calling .bytes() is very inefficient when data is not in memory" } +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of `iter().any()` on slices when it can be replaced with `contains()` and suggests doing so. + /// + /// ### Why is this bad? + /// `contains()` is more concise and idiomatic, sometimes more fast. + /// + /// ### Example + /// ```no_run + /// fn foo(values: &[u8]) -> bool { + /// values.iter().any(|&v| v == 10) + /// } + /// ``` + /// Use instead: + /// ```no_run + /// fn foo(values: &[u8]) -> bool { + /// values.contains(&10) + /// } + /// ``` + #[clippy::version = "1.86.0"] + pub MANUAL_CONTAINS, + perf, + "unnecessary `iter().any()` on slices that can be replaced with `contains()`" +} + #[expect(clippy::struct_excessive_bools)] pub struct Methods { avoid_breaking_exported_api: bool, @@ -4609,6 +4635,7 @@ impl_lint_pass!(Methods => [ SLICED_STRING_AS_BYTES, RETURN_AND_THEN, UNBUFFERED_BYTES, + MANUAL_CONTAINS, ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -4866,6 +4893,9 @@ impl Methods { Some(("map", _, [map_arg], _, map_call_span)) => { map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, "any"); }, + Some(("iter", iter_recv, ..)) => { + manual_contains::check(cx, expr, iter_recv, arg); + }, _ => {}, } }, diff --git a/tests/ui/manual_contains.fixed b/tests/ui/manual_contains.fixed new file mode 100644 index 000000000000..d26c948a7817 --- /dev/null +++ b/tests/ui/manual_contains.fixed @@ -0,0 +1,98 @@ +#![warn(clippy::manual_contains)] +#![allow(clippy::eq_op, clippy::useless_vec)] + +fn should_lint() { + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.contains(&4); + //~^ manual_contains + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.contains(&4); + //~^ manual_contains + + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.contains(&10); + //~^ manual_contains + + let num = 14; + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.contains(&num); + //~^ manual_contains + + let num = 14; + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.contains(&num); + //~^ manual_contains + + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.contains(&4); + //~^ manual_contains + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.contains(&4); + //~^ manual_contains + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let a = &4; + let _ = values.contains(a); + //~^ manual_contains + + let vec = vec!["1", "2", "3", "4", "5", "6"]; + let values = &vec[..]; + let _ = values.contains(&"4"); + //~^ manual_contains + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.contains(&(4 + 1)); + //~^ manual_contains +} + +fn should_not_lint() { + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.iter().any(|&v| v > 10); + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.iter().any(|&v| v % 2 == 0); + let _ = values.iter().any(|&v| v * 2 == 6); + let _ = values.iter().any(|&v| v == v); + let _ = values.iter().any(|&v| 4 == 4); + let _ = values.contains(&4); + + let a = 1; + let b = 2; + let _ = values.iter().any(|&v| a == b); + let _ = values.iter().any(|&v| a == 4); + + let vec: Vec = vec!["1", "2", "3", "4", "5", "6"] + .iter() + .map(|&x| x.to_string()) + .collect(); + let values = &vec[..]; + let _ = values.iter().any(|v| v == "4"); + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let mut counter = 0; + let mut count = || { + counter += 1; + counter + }; + let _ = values.iter().any(|&v| v == count()); + let _ = values.iter().any(|&v| v == v * 2); +} + +fn foo(values: &[u8]) -> bool { + values.contains(&10) + //~^ manual_contains +} + +fn bar(values: [u8; 3]) -> bool { + values.contains(&10) + //~^ manual_contains +} diff --git a/tests/ui/manual_contains.rs b/tests/ui/manual_contains.rs new file mode 100644 index 000000000000..fe67d2ee5d5c --- /dev/null +++ b/tests/ui/manual_contains.rs @@ -0,0 +1,98 @@ +#![warn(clippy::manual_contains)] +#![allow(clippy::eq_op, clippy::useless_vec)] + +fn should_lint() { + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.iter().any(|&v| v == 4); + //~^ manual_contains + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.iter().any(|&v| v == 4); + //~^ manual_contains + + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.iter().any(|&v| v == 10); + //~^ manual_contains + + let num = 14; + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.iter().any(|&v| v == num); + //~^ manual_contains + + let num = 14; + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.iter().any(|&v| num == v); + //~^ manual_contains + + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.iter().any(|v| *v == 4); + //~^ manual_contains + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.iter().any(|&v| 4 == v); + //~^ manual_contains + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let a = &4; + let _ = values.iter().any(|v| *v == *a); + //~^ manual_contains + + let vec = vec!["1", "2", "3", "4", "5", "6"]; + let values = &vec[..]; + let _ = values.iter().any(|&v| v == "4"); + //~^ manual_contains + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.iter().any(|&v| v == 4 + 1); + //~^ manual_contains +} + +fn should_not_lint() { + let values: [u8; 6] = [3, 14, 15, 92, 6, 5]; + let _ = values.iter().any(|&v| v > 10); + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let _ = values.iter().any(|&v| v % 2 == 0); + let _ = values.iter().any(|&v| v * 2 == 6); + let _ = values.iter().any(|&v| v == v); + let _ = values.iter().any(|&v| 4 == 4); + let _ = values.contains(&4); + + let a = 1; + let b = 2; + let _ = values.iter().any(|&v| a == b); + let _ = values.iter().any(|&v| a == 4); + + let vec: Vec = vec!["1", "2", "3", "4", "5", "6"] + .iter() + .map(|&x| x.to_string()) + .collect(); + let values = &vec[..]; + let _ = values.iter().any(|v| v == "4"); + + let vec: Vec = vec![1, 2, 3, 4, 5, 6]; + let values = &vec[..]; + let mut counter = 0; + let mut count = || { + counter += 1; + counter + }; + let _ = values.iter().any(|&v| v == count()); + let _ = values.iter().any(|&v| v == v * 2); +} + +fn foo(values: &[u8]) -> bool { + values.iter().any(|&v| v == 10) + //~^ manual_contains +} + +fn bar(values: [u8; 3]) -> bool { + values.iter().any(|&v| v == 10) + //~^ manual_contains +} diff --git a/tests/ui/manual_contains.stderr b/tests/ui/manual_contains.stderr new file mode 100644 index 000000000000..e6e2dea560c6 --- /dev/null +++ b/tests/ui/manual_contains.stderr @@ -0,0 +1,77 @@ +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:7:13 + | +LL | let _ = values.iter().any(|&v| v == 4); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&4)` + | + = note: `-D clippy::manual-contains` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_contains)]` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:12:13 + | +LL | let _ = values.iter().any(|&v| v == 4); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&4)` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:16:13 + | +LL | let _ = values.iter().any(|&v| v == 10); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&10)` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:21:13 + | +LL | let _ = values.iter().any(|&v| v == num); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&num)` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:26:13 + | +LL | let _ = values.iter().any(|&v| num == v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&num)` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:30:13 + | +LL | let _ = values.iter().any(|v| *v == 4); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&4)` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:35:13 + | +LL | let _ = values.iter().any(|&v| 4 == v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&4)` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:41:13 + | +LL | let _ = values.iter().any(|v| *v == *a); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(a)` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:46:13 + | +LL | let _ = values.iter().any(|&v| v == "4"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&"4")` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:51:13 + | +LL | let _ = values.iter().any(|&v| v == 4 + 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&(4 + 1))` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:91:5 + | +LL | values.iter().any(|&v| v == 10) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&10)` + +error: using `contains()` instead of `iter().any()` is more efficient + --> tests/ui/manual_contains.rs:96:5 + | +LL | values.iter().any(|&v| v == 10) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&10)` + +error: aborting due to 12 previous errors + diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index 104941dc9937..bad8c307586c 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -1,4 +1,10 @@ -#![allow(unused, clippy::needless_if, clippy::suspicious_map, clippy::iter_count)] +#![allow( + unused, + clippy::needless_if, + clippy::suspicious_map, + clippy::iter_count, + clippy::manual_contains +)] use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList}; diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index 7f05f51b82e9..3dfb5194f404 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -1,4 +1,10 @@ -#![allow(unused, clippy::needless_if, clippy::suspicious_map, clippy::iter_count)] +#![allow( + unused, + clippy::needless_if, + clippy::suspicious_map, + clippy::iter_count, + clippy::manual_contains +)] use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList}; diff --git a/tests/ui/needless_collect.stderr b/tests/ui/needless_collect.stderr index cba54f0af6bf..00745eb2923c 100644 --- a/tests/ui/needless_collect.stderr +++ b/tests/ui/needless_collect.stderr @@ -1,5 +1,5 @@ error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:9:29 + --> tests/ui/needless_collect.rs:15:29 | LL | let len = sample.iter().collect::>().len(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()` @@ -8,109 +8,109 @@ LL | let len = sample.iter().collect::>().len(); = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:11:22 + --> tests/ui/needless_collect.rs:17:22 | LL | if sample.iter().collect::>().is_empty() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:15:28 + --> tests/ui/needless_collect.rs:21:28 | LL | sample.iter().cloned().collect::>().contains(&1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:21:35 + --> tests/ui/needless_collect.rs:27:35 | LL | sample.iter().map(|x| (x, x)).collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:23:35 + --> tests/ui/needless_collect.rs:29:35 | LL | sample.iter().map(|x| (x, x)).collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:31:19 + --> tests/ui/needless_collect.rs:37:19 | LL | sample.iter().collect::>().len(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:33:19 + --> tests/ui/needless_collect.rs:39:19 | LL | sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:35:28 + --> tests/ui/needless_collect.rs:41:28 | LL | sample.iter().cloned().collect::>().contains(&1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:37:19 + --> tests/ui/needless_collect.rs:43:19 | LL | sample.iter().collect::>().contains(&&1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &1)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:41:19 + --> tests/ui/needless_collect.rs:47:19 | LL | sample.iter().collect::>().len(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:43:19 + --> tests/ui/needless_collect.rs:49:19 | LL | sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:49:27 + --> tests/ui/needless_collect.rs:55:27 | LL | let _ = sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:51:27 + --> tests/ui/needless_collect.rs:57:27 | LL | let _ = sample.iter().collect::>().contains(&&0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:74:27 + --> tests/ui/needless_collect.rs:80:27 | LL | let _ = sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:76:27 + --> tests/ui/needless_collect.rs:82:27 | LL | let _ = sample.iter().collect::>().contains(&&0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:81:40 + --> tests/ui/needless_collect.rs:87:40 | LL | Vec::::new().extend((0..10).collect::>()); | ^^^^^^^^^^^^^^^^^^^^ help: remove this call error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:83:20 + --> tests/ui/needless_collect.rs:89:20 | LL | foo((0..10).collect::>()); | ^^^^^^^^^^^^^^^^^^^^ help: remove this call error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:85:49 + --> tests/ui/needless_collect.rs:91:49 | LL | bar((0..10).collect::>(), (0..10).collect::>()); | ^^^^^^^^^^^^^^^^^^^^ help: remove this call error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:87:37 + --> tests/ui/needless_collect.rs:93:37 | LL | baz((0..10), (), ('a'..='z').collect::>()) | ^^^^^^^^^^^^^^^^^^^^ help: remove this call diff --git a/tests/ui/search_is_some_fixable_none.fixed b/tests/ui/search_is_some_fixable_none.fixed index e6355bdf792f..847e5140d3e6 100644 --- a/tests/ui/search_is_some_fixable_none.fixed +++ b/tests/ui/search_is_some_fixable_none.fixed @@ -1,4 +1,4 @@ -#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec, clippy::manual_contains)] #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_none.rs b/tests/ui/search_is_some_fixable_none.rs index 8cc80f122f08..e976d12600cc 100644 --- a/tests/ui/search_is_some_fixable_none.rs +++ b/tests/ui/search_is_some_fixable_none.rs @@ -1,4 +1,4 @@ -#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec, clippy::manual_contains)] #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_some.fixed b/tests/ui/search_is_some_fixable_some.fixed index 6ab0593eecde..05e88b8528f1 100644 --- a/tests/ui/search_is_some_fixable_some.fixed +++ b/tests/ui/search_is_some_fixable_some.fixed @@ -1,4 +1,4 @@ -#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec, clippy::manual_contains)] #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_some.rs b/tests/ui/search_is_some_fixable_some.rs index 35094cdf2c07..caab816f2436 100644 --- a/tests/ui/search_is_some_fixable_some.rs +++ b/tests/ui/search_is_some_fixable_some.rs @@ -1,4 +1,4 @@ -#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec, clippy::manual_contains)] #![warn(clippy::search_is_some)] fn main() { From 1c0e120d8b6e78c8e18cce2f0068b85542567d9b Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Tue, 11 Feb 2025 17:53:37 +0900 Subject: [PATCH 141/991] apply `manual_contains` to Clippy sources --- clippy_lints/src/booleans.rs | 2 +- clippy_lints/src/casts/cast_sign_loss.rs | 4 ++-- clippy_lints/src/size_of_in_element_count.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index ee21f9379a52..58a011713a7b 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -555,7 +555,7 @@ impl<'tcx> NonminimalBoolVisitor<'_, 'tcx> { _ => simplified.push(Bool::Not(Box::new(simple.clone()))), } let simple_negated = simple_negate(simple); - if simplified.iter().any(|s| *s == simple_negated) { + if simplified.contains(&simple_negated) { continue; } simplified.push(simple_negated); diff --git a/clippy_lints/src/casts/cast_sign_loss.rs b/clippy_lints/src/casts/cast_sign_loss.rs index 45045e58ac75..c8abf9dac9af 100644 --- a/clippy_lints/src/casts/cast_sign_loss.rs +++ b/clippy_lints/src/casts/cast_sign_loss.rs @@ -142,11 +142,11 @@ fn expr_sign<'cx, 'tcx>(cx: &LateContext<'cx>, mut expr: &'tcx Expr<'tcx>, ty: i expr = recv; } - if METHODS_POW.iter().any(|&name| method_name == name) + if METHODS_POW.contains(&method_name) && let [arg] = args { return pow_call_result_sign(cx, caller, arg); - } else if METHODS_RET_POSITIVE.iter().any(|&name| method_name == name) { + } else if METHODS_RET_POSITIVE.contains(&method_name) { return Sign::ZeroOrPositive; } } diff --git a/clippy_lints/src/size_of_in_element_count.rs b/clippy_lints/src/size_of_in_element_count.rs index b22c638fc363..dc19236011bd 100644 --- a/clippy_lints/src/size_of_in_element_count.rs +++ b/clippy_lints/src/size_of_in_element_count.rs @@ -99,7 +99,7 @@ fn get_pointee_ty_and_count_expr<'tcx>( if let ExprKind::MethodCall(method_path, ptr_self, [.., count], _) = expr.kind // Find calls to copy_{from,to}{,_nonoverlapping} && let method_ident = method_path.ident.as_str() - && METHODS.iter().any(|m| *m == method_ident) + && METHODS.contains(&method_ident) // Get the pointee type && let ty::RawPtr(pointee_ty, _) = From f0a6af0baa886c1559dafc9e943850800a9fabc8 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sat, 15 Feb 2025 23:36:01 +0100 Subject: [PATCH 142/991] remove MaybeUninit::uninit_array --- library/core/src/mem/maybe_uninit.rs | 36 ---------------------------- 1 file changed, 36 deletions(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 2c7f1d86341a..80888c4f9d80 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -331,42 +331,6 @@ impl MaybeUninit { MaybeUninit { uninit: () } } - /// Creates a new array of `MaybeUninit` items, in an uninitialized state. - /// - /// Note: in a future Rust version this method may become unnecessary - /// when Rust allows - /// [inline const expressions](https://github.com/rust-lang/rust/issues/76001). - /// The example below could then use `let mut buf = [const { MaybeUninit::::uninit() }; 32];`. - /// - /// # Examples - /// - /// ```no_run - /// #![feature(maybe_uninit_uninit_array, maybe_uninit_slice)] - /// - /// use std::mem::MaybeUninit; - /// - /// unsafe extern "C" { - /// fn read_into_buffer(ptr: *mut u8, max_len: usize) -> usize; - /// } - /// - /// /// Returns a (possibly smaller) slice of data that was actually read - /// fn read(buf: &mut [MaybeUninit]) -> &[u8] { - /// unsafe { - /// let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len()); - /// buf[..len].assume_init_ref() - /// } - /// } - /// - /// let mut buf: [MaybeUninit; 32] = MaybeUninit::uninit_array(); - /// let data = read(&mut buf); - /// ``` - #[unstable(feature = "maybe_uninit_uninit_array", issue = "96097")] - #[must_use] - #[inline(always)] - pub const fn uninit_array() -> [Self; N] { - [const { MaybeUninit::uninit() }; N] - } - /// Creates a new `MaybeUninit` in an uninitialized state, with the memory being /// filled with `0` bytes. It depends on `T` whether that already makes for /// proper initialization. For example, `MaybeUninit::zeroed()` is initialized, From a12d5a02851f05f1899e59b4ad2be41607f43132 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Sun, 16 Feb 2025 14:22:18 +0900 Subject: [PATCH 143/991] add suggestion example for `cast_possible_wrap` --- clippy_lints/src/casts/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 521bd394901a..78c0acf72b9a 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -134,8 +134,14 @@ declare_clippy_lint! { /// /// ### Example /// ```no_run - /// u32::MAX as i32; // will yield a value of `-1` + /// let _ = u32::MAX as i32; // will yield a value of `-1` /// ``` + /// + /// Use instead: + /// ```no_run + /// let _ = i32::try_from(u32::MAX).ok(); + /// ``` + /// #[clippy::version = "pre 1.29.0"] pub CAST_POSSIBLE_WRAP, pedantic, From acdf9133aca8c5684a7c16f0c7fa0a72cac6a4a3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Feb 2025 08:37:44 +0100 Subject: [PATCH 144/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 9f84dda4397e..dbf61312b5d3 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -54a0f387ea8c7bcb79b8e40c074a484d31b51990 +500a686ba8bb1b51df7e7f8f81d286b2e20209ff From 6dd477ad5ad0e83f60892425170f828c718f6332 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 16 Feb 2025 12:43:08 +0100 Subject: [PATCH 145/991] Add `--allow-no-vcs` to `cargo dev dogfood --fix` Some developers might prefer to use alternate VCS, such as Jujutsu, which are not detected by `cargo fix`. This forwards the `--allow-no-vcs` command line argument to `cargo fix`. --- clippy_dev/src/dogfood.rs | 7 ++++++- clippy_dev/src/main.rs | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/clippy_dev/src/dogfood.rs b/clippy_dev/src/dogfood.rs index 75a4cbd2f92e..05fa24d8d4ee 100644 --- a/clippy_dev/src/dogfood.rs +++ b/clippy_dev/src/dogfood.rs @@ -4,7 +4,8 @@ use std::process::Command; /// # Panics /// /// Panics if unable to run the dogfood test -pub fn dogfood(fix: bool, allow_dirty: bool, allow_staged: bool) { +#[allow(clippy::fn_params_excessive_bools)] +pub fn dogfood(fix: bool, allow_dirty: bool, allow_staged: bool, allow_no_vcs: bool) { let mut cmd = Command::new("cargo"); cmd.current_dir(clippy_project_root()) @@ -25,6 +26,10 @@ pub fn dogfood(fix: bool, allow_dirty: bool, allow_staged: bool) { dogfood_args.push("--allow-staged"); } + if allow_no_vcs { + dogfood_args.push("--allow-no-vcs"); + } + cmd.env("__CLIPPY_DOGFOOD_ARGS", dogfood_args.join(" ")); exit_if_err(cmd.status()); diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs index 93a74ba83871..81a2ebd025be 100644 --- a/clippy_dev/src/main.rs +++ b/clippy_dev/src/main.rs @@ -17,7 +17,8 @@ fn main() { fix, allow_dirty, allow_staged, - } => dogfood::dogfood(fix, allow_dirty, allow_staged), + allow_no_vcs, + } => dogfood::dogfood(fix, allow_dirty, allow_staged, allow_no_vcs), DevCommand::Fmt { check, verbose } => fmt::run(check, verbose), DevCommand::UpdateLints { print_only, check } => { if print_only { @@ -106,6 +107,9 @@ enum DevCommand { #[arg(long, requires = "fix")] /// Fix code even if the working directory has staged changes allow_staged: bool, + #[arg(long, requires = "fix")] + /// Fix code even if a VCS was not detected + allow_no_vcs: bool, }, /// Run rustfmt on all projects and tests Fmt { From ef7e9fe70481dddf5a5b1dc8a915ee34596c0263 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Sun, 16 Feb 2025 13:38:59 +0100 Subject: [PATCH 146/991] Update version attribute for 1.85 clippy lints --- clippy_lints/src/attrs/mod.rs | 2 +- clippy_lints/src/casts/mod.rs | 2 +- clippy_lints/src/doc/mod.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index 92efd1a4ddcd..e0aab8c95a8e 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -305,7 +305,7 @@ declare_clippy_lint! { /// header_version: u16 /// } /// ``` - #[clippy::version = "1.84.0"] + #[clippy::version = "1.85.0"] pub REPR_PACKED_WITHOUT_ABI, suspicious, "ensures that `repr(packed)` always comes with a qualified ABI" diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 521bd394901a..aab69ac59eaa 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -747,7 +747,7 @@ declare_clippy_lint! { /// t as *const T as usize /// } /// ``` - #[clippy::version = "1.81.0"] + #[clippy::version = "1.85.0"] pub AS_POINTER_UNDERSCORE, restriction, "detects `as *mut _` and `as *const _` conversion" diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 7b07d302d4f8..b5fb492b96c8 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -612,7 +612,7 @@ declare_clippy_lint! { /// ```no_run /// #![cfg_attr(doc, doc = include_str!("some_file.md"))] /// ``` - #[clippy::version = "1.84.0"] + #[clippy::version = "1.85.0"] pub DOC_INCLUDE_WITHOUT_CFG, restriction, "check if files included in documentation are behind `cfg(doc)`" @@ -638,7 +638,7 @@ declare_clippy_lint! { /// //! /// //! [link]: destination (for link reference definition) /// ``` - #[clippy::version = "1.84.0"] + #[clippy::version = "1.85.0"] pub DOC_NESTED_REFDEFS, suspicious, "link reference defined in list item or quote" From 3e637202321834f41f5f1dcda6816dceb535da78 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Sun, 16 Feb 2025 13:40:11 +0100 Subject: [PATCH 147/991] Changelog for Clippy 1.85 :parrot: --- CHANGELOG.md | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b8695f66279..6f7e5ae92ca8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,53 @@ document. ## Unreleased / Beta / In Rust Nightly -[786fbd6d...master](https://github.com/rust-lang/rust-clippy/compare/786fbd6d...master) +[609cd310...master](https://github.com/rust-lang/rust-clippy/compare/609cd310...master) + +## Rust 1.85 + +Current stable, released 2025-02-20 + +[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-11-15T19%3A31%3A08Z..2024-12-26T13%3A59%3A48Z+base%3Amaster) + +### New Lints + +* Added [`repr_packed_without_abi`] to `suspicious` + [#13398](https://github.com/rust-lang/rust-clippy/pull/13398) +* Added [`as_pointer_underscore`] to `restriction` + [#13251](https://github.com/rust-lang/rust-clippy/pull/13251) +* Added [`doc_nested_refdefs`] to `suspicious` + [#13707](https://github.com/rust-lang/rust-clippy/pull/13707) +* Added [`literal_string_with_formatting_args`] to `nursery` + [#13410](https://github.com/rust-lang/rust-clippy/pull/13410) +* Added [`doc_include_without_cfg`] to `restriction` + [#13625](https://github.com/rust-lang/rust-clippy/pull/13625) + +### Enhancements + +* [`indexing_slicing`]: Can now be allowed in tests using the [`allow-indexing-slicing-in-tests`] + configuration + [#13854](https://github.com/rust-lang/rust-clippy/pull/13854) +* [`if_let_mutex`]: disable lint from Edition 2024 since + [if_let_rescope](https://github.com/rust-lang/rust/issues/131154) was stabilized + [#13695](https://github.com/rust-lang/rust-clippy/pull/13695) +* [`format_in_format_args`], [`recursive_format_impl`], [`to_string_in_format_args`], + [`uninlined_format_args`], [`unused_format_specs`]: Can now support 3er party format macros + if they're marked with the `#[clippy::format_args]` attribute + [#9948](https://github.com/rust-lang/rust-clippy/pull/9948) + +### ICE Fixes + +* [`trait_duplication_in_bounds`]: fix ICE on duplicate type or constant bound + [#13722](https://github.com/rust-lang/rust-clippy/pull/13722) + +### Others + +* `clippy_utils` is now published to crates.io. Note that this crate is and will remain unstable. + [#13700](https://github.com/rust-lang/rust-clippy/pull/13700) ## Rust 1.84 -Current stable, released 2025-01-09 +Released 2025-01-09 [View all 84 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-10-03T21%3A23%3A58Z..2024-11-14T17%3A41%3A37Z+base%3Amaster) From f68f0b3e118de3a0ce15524413ef1a04b164242c Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 16 Feb 2025 01:18:29 +0300 Subject: [PATCH 148/991] clippy: string_from_utf8_as_bytes: also detect inherent `from_utf8` --- clippy_lints/src/strings.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 6164a6191db0..4a5f143a2d34 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -2,8 +2,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_the use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::ty::is_type_lang_item; use clippy_utils::{ - SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, is_path_diagnostic_item, - method_calls, peel_blocks, + SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, method_calls, path_def_id, + peel_blocks, }; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; @@ -253,8 +253,9 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { use rustc_ast::LitKind; if let ExprKind::Call(fun, [bytes_arg]) = e.kind - // Find std::str::converts::from_utf8 - && is_path_diagnostic_item(cx, fun, sym::str_from_utf8) + // Find `std::str::converts::from_utf8` or `std::primitive::str::from_utf8` + && let Some(sym::str_from_utf8 | sym::str_inherent_from_utf8) = + path_def_id(cx, fun).and_then(|id| cx.tcx.get_diagnostic_name(id)) // Find string::as_bytes && let ExprKind::AddrOf(BorrowKind::Ref, _, args) = bytes_arg.kind From 058ae80a55a97e6a077f5b464cebcae3c6b4ea56 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Sun, 16 Feb 2025 14:43:18 +0000 Subject: [PATCH 149/991] Add `cargo dev setup toolchain --standalone` --- clippy_dev/src/main.rs | 20 ++++++++++++++++++-- clippy_dev/src/setup/toolchain.rs | 27 +++++++++++++++++++++------ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs index 93a74ba83871..1c36de0ac61b 100644 --- a/clippy_dev/src/main.rs +++ b/clippy_dev/src/main.rs @@ -53,7 +53,12 @@ fn main() { setup::git_hook::install_hook(force_override); } }, - SetupSubcommand::Toolchain { force, release, name } => setup::toolchain::create(force, release, &name), + SetupSubcommand::Toolchain { + standalone, + force, + release, + name, + } => setup::toolchain::create(standalone, force, release, &name), SetupSubcommand::VscodeTasks { remove, force_override } => { if remove { setup::vscode::remove_tasks(); @@ -267,14 +272,25 @@ enum SetupSubcommand { force_override: bool, }, /// Install a rustup toolchain pointing to the local clippy build + /// + /// This creates a toolchain with symlinks pointing at + /// `target/.../{clippy-driver,cargo-clippy}`, rebuilds of the project will be reflected in the + /// created toolchain unless `--standalone` is passed Toolchain { + #[arg(long, short)] + /// Create a standalone toolchain by copying the clippy binaries instead + /// of symlinking them + /// + /// Use this for example to create a toolchain, make a small change and then make another + /// toolchain with a different name in order to easily compare the two + standalone: bool, #[arg(long, short)] /// Override an existing toolchain force: bool, #[arg(long, short)] /// Point to --release clippy binary release: bool, - #[arg(long, default_value = "clippy")] + #[arg(long, short, default_value = "clippy")] /// Name of the toolchain name: String, }, diff --git a/clippy_dev/src/setup/toolchain.rs b/clippy_dev/src/setup/toolchain.rs index 8d98c6c92d9d..2966629cf70a 100644 --- a/clippy_dev/src/setup/toolchain.rs +++ b/clippy_dev/src/setup/toolchain.rs @@ -3,11 +3,14 @@ use std::env::current_dir; use std::ffi::OsStr; use std::fs; use std::path::{Path, PathBuf}; +use std::process::Command; use walkdir::WalkDir; +use crate::utils::exit_if_err; + use super::verify_inside_clippy_dir; -pub fn create(force: bool, release: bool, name: &str) { +pub fn create(standalone: bool, force: bool, release: bool, name: &str) { if !verify_inside_clippy_dir() { return; } @@ -48,14 +51,22 @@ pub fn create(force: bool, release: bool, name: &str) { } } - symlink_bin("cargo-clippy", &dest, release); - symlink_bin("clippy-driver", &dest, release); + let status = Command::new("cargo") + .arg("build") + .args(release.then_some("--release")) + .status(); + exit_if_err(status); + + install_bin("cargo-clippy", &dest, standalone, release); + install_bin("clippy-driver", &dest, standalone, release); println!("Created toolchain {name}, use it in other projects with e.g. `cargo +{name} clippy`"); - println!("Note: This will need to be re-run whenever the Clippy `rust-toolchain` changes"); + if !standalone { + println!("Note: This will need to be re-run whenever the Clippy `rust-toolchain` changes"); + } } -fn symlink_bin(bin: &str, dest: &Path, release: bool) { +fn install_bin(bin: &str, dest: &Path, standalone: bool, release: bool) { #[cfg(windows)] use std::os::windows::fs::symlink_file as symlink; @@ -71,5 +82,9 @@ fn symlink_bin(bin: &str, dest: &Path, release: bool) { let mut dest = dest.to_path_buf(); dest.extend(["bin", &file_name]); - symlink(src, dest).unwrap(); + if standalone { + fs::copy(src, dest).unwrap(); + } else { + symlink(src, dest).unwrap(); + } } From d03ae8ba6ba0ec4f9c67f1982db8467d231fb646 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Sun, 16 Feb 2025 15:38:07 +0000 Subject: [PATCH 150/991] `ui_test` annotation cleanup --- tests/ui/asm_syntax_not_x86.rs | 6 +- tests/ui/attrs.rs | 5 +- tests/ui/attrs.stderr | 4 +- tests/ui/crashes/ice-5835.fixed | 10 + tests/ui/crashes/ice-5835.rs | 5 +- tests/ui/crashes/ice-5835.stderr | 20 +- tests/ui/doc/unbalanced_ticks.rs | 25 +-- tests/ui/doc/unbalanced_ticks.stderr | 172 ++++++++---------- tests/ui/doc_link_with_quotes.rs | 1 - tests/ui/doc_link_with_quotes.stderr | 4 +- .../ui/empty_line_after/doc_comments.1.fixed | 23 +-- .../ui/empty_line_after/doc_comments.2.fixed | 50 +++-- tests/ui/empty_line_after/doc_comments.rs | 23 +-- tests/ui/empty_line_after/doc_comments.stderr | 67 +++---- .../auxiliary/submodule.rs | 2 - .../ui/mixed_attributes_style/global_allow.rs | 5 +- .../global_allow.stderr | 20 -- .../mixed_attributes_style/mod_declaration.rs | 1 - .../mod_declaration.stderr | 22 +-- tests/ui/suspicious_else_formatting.rs | 3 +- tests/ui/suspicious_else_formatting.stderr | 16 +- tests/ui/unneeded_struct_pattern.fixed | 39 +++- tests/ui/unneeded_struct_pattern.rs | 24 ++- tests/ui/unneeded_struct_pattern.stderr | 152 ++++++++++------ 24 files changed, 342 insertions(+), 357 deletions(-) create mode 100644 tests/ui/crashes/ice-5835.fixed delete mode 100644 tests/ui/mixed_attributes_style/global_allow.stderr diff --git a/tests/ui/asm_syntax_not_x86.rs b/tests/ui/asm_syntax_not_x86.rs index 91fde12680cc..edcd5247f18c 100644 --- a/tests/ui/asm_syntax_not_x86.rs +++ b/tests/ui/asm_syntax_not_x86.rs @@ -1,5 +1,6 @@ //@ignore-target: i686 x86 //@needs-asm-support +//@check-pass #[warn(clippy::inline_asm_x86_intel_syntax)] #[warn(clippy::inline_asm_x86_att_syntax)] @@ -8,17 +9,12 @@ mod dont_warn { pub(super) unsafe fn use_asm() { asm!(""); - //~^ inline_asm_x86_intel_syntax asm!("", options()); - //~^ inline_asm_x86_intel_syntax asm!("", options(nostack)); - //~^ inline_asm_x86_intel_syntax } global_asm!(""); - //~^ inline_asm_x86_intel_syntax global_asm!("", options()); - //~^ inline_asm_x86_intel_syntax } fn main() { diff --git a/tests/ui/attrs.rs b/tests/ui/attrs.rs index 583a0ada437d..f60c71837d5e 100644 --- a/tests/ui/attrs.rs +++ b/tests/ui/attrs.rs @@ -1,10 +1,9 @@ #![warn(clippy::inline_always, clippy::deprecated_semver)] -#![allow(clippy::assertions_on_constants, clippy::empty_line_after_outer_attr)] +#![allow(clippy::assertions_on_constants)] #![allow(clippy::missing_docs_in_private_items, clippy::panic, clippy::unreachable)] #[inline(always)] //~^ inline_always - fn test_attr_lint() { assert!(true) } @@ -26,12 +25,10 @@ fn empty_and_false_positive_stmt() { #[deprecated(since = "forever")] //~^ deprecated_semver - pub const SOME_CONST: u8 = 42; #[deprecated(since = "1")] //~^ deprecated_semver - pub const ANOTHER_CONST: u8 = 23; #[deprecated(since = "0.1.1")] diff --git a/tests/ui/attrs.stderr b/tests/ui/attrs.stderr index a7fdceaba6f3..85b318cc0fdb 100644 --- a/tests/ui/attrs.stderr +++ b/tests/ui/attrs.stderr @@ -1,5 +1,5 @@ error: the since field must contain a semver-compliant version - --> tests/ui/attrs.rs:27:14 + --> tests/ui/attrs.rs:26:14 | LL | #[deprecated(since = "forever")] | ^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #[deprecated(since = "forever")] = help: to override `-D warnings` add `#[allow(clippy::deprecated_semver)]` error: the since field must contain a semver-compliant version - --> tests/ui/attrs.rs:32:14 + --> tests/ui/attrs.rs:30:14 | LL | #[deprecated(since = "1")] | ^^^^^^^^^^^ diff --git a/tests/ui/crashes/ice-5835.fixed b/tests/ui/crashes/ice-5835.fixed new file mode 100644 index 000000000000..e9c24b8e9f09 --- /dev/null +++ b/tests/ui/crashes/ice-5835.fixed @@ -0,0 +1,10 @@ +#[rustfmt::skip] +pub struct Foo { + //~v tabs_in_doc_comments + /// 位 + /// ^ Do not remove this tab character. + /// It was required to trigger the ICE. + pub bar: u8, +} + +fn main() {} diff --git a/tests/ui/crashes/ice-5835.rs b/tests/ui/crashes/ice-5835.rs index 149ba4786181..99858f45933e 100644 --- a/tests/ui/crashes/ice-5835.rs +++ b/tests/ui/crashes/ice-5835.rs @@ -1,10 +1,7 @@ #[rustfmt::skip] pub struct Foo { + //~v tabs_in_doc_comments /// 位 - //~^ tabs_in_doc_comments - //~| empty_line_after_doc_comments - - /// ^ Do not remove this tab character. /// It was required to trigger the ICE. pub bar: u8, diff --git a/tests/ui/crashes/ice-5835.stderr b/tests/ui/crashes/ice-5835.stderr index b342b43d0416..4ef91e4116b2 100644 --- a/tests/ui/crashes/ice-5835.stderr +++ b/tests/ui/crashes/ice-5835.stderr @@ -1,5 +1,5 @@ error: using tabs in doc comments is not recommended - --> tests/ui/crashes/ice-5835.rs:3:10 + --> tests/ui/crashes/ice-5835.rs:4:10 | LL | /// 位 | ^^^^ help: consider using four spaces per tab @@ -7,21 +7,5 @@ LL | /// 位 = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]` -error: empty lines after doc comment - --> tests/ui/crashes/ice-5835.rs:3:5 - | -LL | / /// 位 -... | -LL | | - | |_^ - | - = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]` - = help: if the empty lines are unintentional remove them -help: if the doc comment should not document `bar` comment it out - | -LL | // /// 位 - | ++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/doc/unbalanced_ticks.rs b/tests/ui/doc/unbalanced_ticks.rs index 8adbb1f7f714..e8cfe44a6789 100644 --- a/tests/ui/doc/unbalanced_ticks.rs +++ b/tests/ui/doc/unbalanced_ticks.rs @@ -5,22 +5,20 @@ #![warn(clippy::doc_markdown)] /// This is a doc comment with `unbalanced_tick marks and several words that -//~^ empty_line_after_doc_comments - +//~^ doc_markdown /// should be `encompassed_by` tick marks because they `contain_underscores`. /// Because of the initial `unbalanced_tick` pair, the error message is /// very `confusing_and_misleading`. fn main() {} /// This paragraph has `unbalanced_tick marks and should stop_linting. -//~^ empty_line_after_doc_comments - +//~^ doc_markdown /// /// This paragraph is fine and should_be linted normally. - +//~^ doc_markdown /// /// Double unbalanced backtick from ``here to here` should lint. - +//~^ doc_markdown /// /// Double balanced back ticks ``start end`` is fine. fn multiple_paragraphs() {} @@ -34,16 +32,15 @@ fn in_code_block() {} /// # `Fine` /// /// ## not_fine -//~^ empty_line_after_doc_comments - +//~^ doc_markdown /// /// ### `unbalanced - +//~^ doc_markdown /// /// - This `item has unbalanced tick marks - +//~^ doc_markdown /// - This item needs backticks_here - +//~^ doc_markdown fn other_markdown() {} #[rustfmt::skip] @@ -54,8 +51,7 @@ fn other_markdown() {} fn issue_7421() {} /// ` -//~^ empty_line_after_doc_comments - +//~^ doc_markdown fn escape_0() {} /// Escaped \` backticks don't count. @@ -65,8 +61,7 @@ fn escape_1() {} fn escape_2() {} /// Escaped \` ` backticks don't count, but unescaped backticks do. -//~^ empty_line_after_doc_comments - +//~^ doc_markdown fn escape_3() {} /// Backslashes ` \` within code blocks don't count. diff --git a/tests/ui/doc/unbalanced_ticks.stderr b/tests/ui/doc/unbalanced_ticks.stderr index 563d86376481..50324010e97f 100644 --- a/tests/ui/doc/unbalanced_ticks.stderr +++ b/tests/ui/doc/unbalanced_ticks.stderr @@ -1,112 +1,98 @@ -error: empty line after doc comment - --> tests/ui/doc/unbalanced_ticks.rs:7:1 +error: backticks are unbalanced + --> tests/ui/doc/unbalanced_ticks.rs:7:5 | -LL | / /// This is a doc comment with `unbalanced_tick marks and several words that +LL | /// This is a doc comment with `unbalanced_tick marks and several words that + | _____^ LL | | -LL | | - | |_^ -... -LL | fn main() {} - | --------- the comment documents this function +LL | | /// should be `encompassed_by` tick marks because they `contain_underscores`. +LL | | /// Because of the initial `unbalanced_tick` pair, the error message is +LL | | /// very `confusing_and_misleading`. + | |____________________________________^ | - = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]` - = help: if the empty line is unintentional remove it -help: if the doc comment should not document `main` comment it out - | -LL | // /// This is a doc comment with `unbalanced_tick marks and several words that - | ++ + = help: a backtick may be missing a pair + = note: `-D clippy::doc-markdown` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]` -error: empty lines after doc comment - --> tests/ui/doc/unbalanced_ticks.rs:15:1 +error: backticks are unbalanced + --> tests/ui/doc/unbalanced_ticks.rs:14:5 | -LL | / /// This paragraph has `unbalanced_tick marks and should stop_linting. -LL | | -LL | | -LL | | /// -... | -LL | | /// Double unbalanced backtick from ``here to here` should lint. -LL | | - | |_^ -... -LL | fn multiple_paragraphs() {} - | ------------------------ the comment documents this function - | - = help: if the empty lines are unintentional remove them -help: if the doc comment should not document `multiple_paragraphs` comment it out - | -LL ~ // /// This paragraph has `unbalanced_tick marks and should stop_linting. -LL | -LL | -LL ~ // /// -LL ~ // /// This paragraph is fine and should_be linted normally. -LL | -LL ~ // /// -LL ~ // /// Double unbalanced backtick from ``here to here` should lint. +LL | /// This paragraph has `unbalanced_tick marks and should stop_linting. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: a backtick may be missing a pair -error: empty lines after doc comment - --> tests/ui/doc/unbalanced_ticks.rs:36:1 +error: item in documentation is missing backticks + --> tests/ui/doc/unbalanced_ticks.rs:17:32 | -LL | / /// ## not_fine -LL | | -LL | | -LL | | /// -... | -LL | | /// - This item needs backticks_here -LL | | - | |_^ -LL | fn other_markdown() {} - | ------------------- the comment documents this function +LL | /// This paragraph is fine and should_be linted normally. + | ^^^^^^^^^ | - = help: if the empty lines are unintentional remove them -help: if the doc comment should not document `other_markdown` comment it out - | -LL ~ // /// # `Fine` -LL ~ // /// -LL ~ // /// ## not_fine -LL | -LL | -LL ~ // /// -LL ~ // /// ### `unbalanced -LL | -LL ~ // /// -LL ~ // /// - This `item has unbalanced tick marks -LL | -LL ~ // /// - This item needs backticks_here +help: try | +LL | /// This paragraph is fine and `should_be` linted normally. + | ~~~~~~~~~~~ -error: empty line after doc comment - --> tests/ui/doc/unbalanced_ticks.rs:56:1 +error: backticks are unbalanced + --> tests/ui/doc/unbalanced_ticks.rs:20:5 | -LL | / /// ` -LL | | -LL | | - | |_^ -LL | fn escape_0() {} - | ------------- the comment documents this function +LL | /// Double unbalanced backtick from ``here to here` should lint. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: if the empty line is unintentional remove it -help: if the doc comment should not document `escape_0` comment it out - | -LL | // /// ` - | ++ + = help: a backtick may be missing a pair -error: empty line after doc comment - --> tests/ui/doc/unbalanced_ticks.rs:67:1 +error: item in documentation is missing backticks + --> tests/ui/doc/unbalanced_ticks.rs:34:8 | -LL | / /// Escaped \` ` backticks don't count, but unescaped backticks do. -LL | | -LL | | - | |_^ -LL | fn escape_3() {} - | ------------- the comment documents this function +LL | /// ## not_fine + | ^^^^^^^^ | - = help: if the empty line is unintentional remove it -help: if the doc comment should not document `escape_3` comment it out +help: try | -LL | // /// Escaped \` ` backticks don't count, but unescaped backticks do. - | ++ +LL | /// ## `not_fine` + | ~~~~~~~~~~ -error: aborting due to 5 previous errors +error: backticks are unbalanced + --> tests/ui/doc/unbalanced_ticks.rs:37:5 + | +LL | /// ### `unbalanced + | ^^^^^^^^^^^^^^^ + | + = help: a backtick may be missing a pair + +error: backticks are unbalanced + --> tests/ui/doc/unbalanced_ticks.rs:40:5 + | +LL | /// - This `item has unbalanced tick marks + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: a backtick may be missing a pair + +error: item in documentation is missing backticks + --> tests/ui/doc/unbalanced_ticks.rs:42:23 + | +LL | /// - This item needs backticks_here + | ^^^^^^^^^^^^^^ + | +help: try + | +LL | /// - This item needs `backticks_here` + | ~~~~~~~~~~~~~~~~ + +error: backticks are unbalanced + --> tests/ui/doc/unbalanced_ticks.rs:53:5 + | +LL | /// ` + | ^ + | + = help: a backtick may be missing a pair + +error: backticks are unbalanced + --> tests/ui/doc/unbalanced_ticks.rs:63:5 + | +LL | /// Escaped \` ` backticks don't count, but unescaped backticks do. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: a backtick may be missing a pair + +error: aborting due to 10 previous errors diff --git a/tests/ui/doc_link_with_quotes.rs b/tests/ui/doc_link_with_quotes.rs index e2614e6b4318..0c0e273da6db 100644 --- a/tests/ui/doc_link_with_quotes.rs +++ b/tests/ui/doc_link_with_quotes.rs @@ -1,5 +1,4 @@ #![warn(clippy::doc_link_with_quotes)] -#![allow(clippy::empty_line_after_doc_comments)] fn main() { foo() diff --git a/tests/ui/doc_link_with_quotes.stderr b/tests/ui/doc_link_with_quotes.stderr index 1c1d8e0ffd52..47c60390310c 100644 --- a/tests/ui/doc_link_with_quotes.stderr +++ b/tests/ui/doc_link_with_quotes.stderr @@ -1,5 +1,5 @@ error: possible intra-doc link using quotes instead of backticks - --> tests/ui/doc_link_with_quotes.rs:8:12 + --> tests/ui/doc_link_with_quotes.rs:7:12 | LL | /// Calls ['bar'] uselessly | ^^^^^ @@ -8,7 +8,7 @@ LL | /// Calls ['bar'] uselessly = help: to override `-D warnings` add `#[allow(clippy::doc_link_with_quotes)]` error: possible intra-doc link using quotes instead of backticks - --> tests/ui/doc_link_with_quotes.rs:14:12 + --> tests/ui/doc_link_with_quotes.rs:13:12 | LL | /// Calls ["bar"] uselessly | ^^^^^ diff --git a/tests/ui/empty_line_after/doc_comments.1.fixed b/tests/ui/empty_line_after/doc_comments.1.fixed index c1a15f47ba10..fd6a94b6a80c 100644 --- a/tests/ui/empty_line_after/doc_comments.1.fixed +++ b/tests/ui/empty_line_after/doc_comments.1.fixed @@ -1,17 +1,16 @@ #![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)] +//~vvv empty_line_after_doc_comments /// Meant to be an /// inner doc comment /// for the crate -//~^ empty_line_after_doc_comments fn first_in_crate() {} mod m { - + //~vvv empty_line_after_doc_comments /// Meant to be an /// inner doc comment /// for the module - //~^ empty_line_after_doc_comments fn first_in_module() {} } @@ -22,14 +21,14 @@ mod some_mod { fn some_noop() {} } + //~v empty_line_after_doc_comments /// # Indented - //~^ empty_line_after_doc_comments /// Blank line fn indented() {} } +//~v empty_line_after_doc_comments /// This should produce a warning -//~^ empty_line_after_doc_comments fn with_doc_and_newline() {} // This should *NOT* produce a warning @@ -37,8 +36,8 @@ fn with_doc_and_newline() {} /// some comment fn with_no_newline_and_comment() {} +//~v empty_line_after_doc_comments /// This doc comment should produce a warning -//~^ empty_line_after_doc_comments /** This is also a doc comment and is part of the warning */ #[allow(non_camel_case_types)] @@ -47,15 +46,14 @@ fn with_no_newline_and_comment() {} fn three_attributes() {} mod misattributed { - + //~v empty_line_after_doc_comments /// docs for `old_code` - //~^ empty_line_after_doc_comments // fn old_code() {} fn new_code() {} + //~vv empty_line_after_doc_comments /// Docs /// for OldA - //~^ empty_line_after_doc_comments // struct OldA; /// Docs /// for OldB @@ -67,25 +65,24 @@ mod misattributed { } mod block_comments { - + //~v empty_line_after_doc_comments /** * Meant to be inner doc comment */ - //~^^^ empty_line_after_doc_comments fn first_in_module() {} + //~v empty_line_after_doc_comments /** * Docs for `old_code` */ - //~^^^ empty_line_after_doc_comments /* fn old_code() {} */ /** * Docs for `new_code` */ fn new_code() {} + //~v empty_line_after_doc_comments /// Docs for `old_code2` - //~^ empty_line_after_doc_comments /* fn old_code2() {} */ /// Docs for `new_code2` fn new_code2() {} diff --git a/tests/ui/empty_line_after/doc_comments.2.fixed b/tests/ui/empty_line_after/doc_comments.2.fixed index abec7b54c632..7a57dcd92332 100644 --- a/tests/ui/empty_line_after/doc_comments.2.fixed +++ b/tests/ui/empty_line_after/doc_comments.2.fixed @@ -1,18 +1,17 @@ #![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)] -// /// Meant to be an -// /// inner doc comment -// /// for the crate -//~^ empty_line_after_doc_comments +//~vvv empty_line_after_doc_comments +//! Meant to be an +//! inner doc comment +//! for the crate fn first_in_crate() {} mod m { - - // /// Meant to be an - // /// inner doc comment - // /// for the module - //~^ empty_line_after_doc_comments + //~vvv empty_line_after_doc_comments + //! Meant to be an + //! inner doc comment + //! for the module fn first_in_module() {} } @@ -24,16 +23,15 @@ mod some_mod { fn some_noop() {} } - // /// # Indented - //~^ empty_line_after_doc_comments - + //~v empty_line_after_doc_comments + /// # Indented + /// /// Blank line fn indented() {} } -// /// This should produce a warning -//~^ empty_line_after_doc_comments - +//~v empty_line_after_doc_comments +/// This should produce a warning fn with_doc_and_newline() {} // This should *NOT* produce a warning @@ -41,28 +39,25 @@ fn with_doc_and_newline() {} /// some comment fn with_no_newline_and_comment() {} -// /// This doc comment should produce a warning -//~^ empty_line_after_doc_comments - -/* This is also a doc comment and is part of the warning +//~v empty_line_after_doc_comments +/// This doc comment should produce a warning +/** This is also a doc comment and is part of the warning */ - #[allow(non_camel_case_types)] #[allow(missing_docs)] #[allow(dead_code)] fn three_attributes() {} mod misattributed { - + //~v empty_line_after_doc_comments // /// docs for `old_code` - //~^ empty_line_after_doc_comments // fn old_code() {} fn new_code() {} + //~vv empty_line_after_doc_comments // /// Docs // /// for OldA - //~^ empty_line_after_doc_comments // struct OldA; // /// Docs @@ -76,18 +71,17 @@ mod misattributed { } mod block_comments { - - /* + //~v empty_line_after_doc_comments + /*! * Meant to be inner doc comment */ - //~^^^ empty_line_after_doc_comments fn first_in_module() {} + //~v empty_line_after_doc_comments /* * Docs for `old_code` */ - //~^^^ empty_line_after_doc_comments /* fn old_code() {} */ /** @@ -95,8 +89,8 @@ mod block_comments { */ fn new_code() {} + //~v empty_line_after_doc_comments // /// Docs for `old_code2` - //~^ empty_line_after_doc_comments /* fn old_code2() {} */ /// Docs for `new_code2` diff --git a/tests/ui/empty_line_after/doc_comments.rs b/tests/ui/empty_line_after/doc_comments.rs index d225768f6125..1da761a5c3d5 100644 --- a/tests/ui/empty_line_after/doc_comments.rs +++ b/tests/ui/empty_line_after/doc_comments.rs @@ -1,18 +1,17 @@ #![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)] +//~vvv empty_line_after_doc_comments /// Meant to be an /// inner doc comment /// for the crate -//~^ empty_line_after_doc_comments fn first_in_crate() {} mod m { - + //~vvv empty_line_after_doc_comments /// Meant to be an /// inner doc comment /// for the module - //~^ empty_line_after_doc_comments fn first_in_module() {} } @@ -24,15 +23,15 @@ mod some_mod { fn some_noop() {} } + //~v empty_line_after_doc_comments /// # Indented - //~^ empty_line_after_doc_comments /// Blank line fn indented() {} } +//~v empty_line_after_doc_comments /// This should produce a warning -//~^ empty_line_after_doc_comments fn with_doc_and_newline() {} @@ -41,8 +40,8 @@ fn with_doc_and_newline() {} /// some comment fn with_no_newline_and_comment() {} +//~v empty_line_after_doc_comments /// This doc comment should produce a warning -//~^ empty_line_after_doc_comments /** This is also a doc comment and is part of the warning */ @@ -53,16 +52,15 @@ fn with_no_newline_and_comment() {} fn three_attributes() {} mod misattributed { - + //~v empty_line_after_doc_comments /// docs for `old_code` - //~^ empty_line_after_doc_comments // fn old_code() {} fn new_code() {} + //~vv empty_line_after_doc_comments /// Docs /// for OldA - //~^ empty_line_after_doc_comments // struct OldA; /// Docs @@ -76,18 +74,17 @@ mod misattributed { } mod block_comments { - + //~v empty_line_after_doc_comments /** * Meant to be inner doc comment */ - //~^^^ empty_line_after_doc_comments fn first_in_module() {} + //~v empty_line_after_doc_comments /** * Docs for `old_code` */ - //~^^^ empty_line_after_doc_comments /* fn old_code() {} */ /** @@ -95,8 +92,8 @@ mod block_comments { */ fn new_code() {} + //~v empty_line_after_doc_comments /// Docs for `old_code2` - //~^ empty_line_after_doc_comments /* fn old_code2() {} */ /// Docs for `new_code2` diff --git a/tests/ui/empty_line_after/doc_comments.stderr b/tests/ui/empty_line_after/doc_comments.stderr index 9b627e8df1ff..c5d5f3d37594 100644 --- a/tests/ui/empty_line_after/doc_comments.stderr +++ b/tests/ui/empty_line_after/doc_comments.stderr @@ -1,8 +1,7 @@ error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:5:1 + --> tests/ui/empty_line_after/doc_comments.rs:6:1 | LL | / /// for the crate -LL | | LL | | | |_^ LL | fn first_in_crate() {} @@ -11,36 +10,34 @@ LL | fn first_in_crate() {} = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]` = help: if the empty line is unintentional remove it -help: if the doc comment should not document `first_in_crate` comment it out +help: if the comment should document the crate use an inner doc comment | -LL ~ // /// Meant to be an -LL ~ // /// inner doc comment -LL ~ // /// for the crate +LL ~ //! Meant to be an +LL ~ //! inner doc comment +LL ~ //! for the crate | error: empty line after doc comment --> tests/ui/empty_line_after/doc_comments.rs:14:5 | LL | / /// for the module -LL | | LL | | | |_^ LL | fn first_in_module() {} | -------------------- the comment documents this function | = help: if the empty line is unintentional remove it -help: if the doc comment should not document `first_in_module` comment it out +help: if the comment should document the parent module use an inner doc comment | -LL ~ // /// Meant to be an -LL ~ // /// inner doc comment -LL ~ // /// for the module +LL ~ //! Meant to be an +LL ~ //! inner doc comment +LL ~ //! for the module | error: empty line after doc comment --> tests/ui/empty_line_after/doc_comments.rs:27:5 | LL | / /// # Indented -LL | | LL | | | |_^ LL | /// Blank line @@ -48,33 +45,27 @@ LL | fn indented() {} | ------------- the comment documents this function | = help: if the empty line is unintentional remove it -help: if the doc comment should not document `indented` comment it out +help: if the documentation should include the empty line include it in the comment + | +LL | /// | -LL | // /// # Indented - | ++ error: empty line after doc comment --> tests/ui/empty_line_after/doc_comments.rs:34:1 | LL | / /// This should produce a warning -LL | | LL | | | |_^ LL | fn with_doc_and_newline() {} | ------------------------- the comment documents this function | = help: if the empty line is unintentional remove it -help: if the doc comment should not document `with_doc_and_newline` comment it out - | -LL | // /// This should produce a warning - | ++ error: empty lines after doc comment --> tests/ui/empty_line_after/doc_comments.rs:44:1 | LL | / /// This doc comment should produce a warning LL | | -LL | | LL | | /** This is also a doc comment and is part of the warning LL | | */ LL | | @@ -84,19 +75,12 @@ LL | fn three_attributes() {} | --------------------- the comment documents this function | = help: if the empty lines are unintentional remove them -help: if the doc comment should not document `three_attributes` comment it out - | -LL ~ // /// This doc comment should produce a warning -LL | -LL | -LL ~ /* This is also a doc comment and is part of the warning - | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:57:5 + --> tests/ui/empty_line_after/doc_comments.rs:56:5 | LL | / /// docs for `old_code` -... | +LL | | // fn old_code() {} LL | | | |_^ LL | fn new_code() {} @@ -109,9 +93,12 @@ LL | // /// docs for `old_code` | ++ error: empty lines after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:64:5 + --> tests/ui/empty_line_after/doc_comments.rs:63:5 | LL | / /// for OldA +LL | | // struct OldA; +LL | | +LL | | /// Docs ... | LL | | | |_^ @@ -124,7 +111,6 @@ help: if the doc comment should not document `Multiple` comment it out | LL ~ // /// Docs LL ~ // /// for OldA -LL | LL | // struct OldA; LL | LL ~ // /// Docs @@ -132,31 +118,29 @@ LL ~ // /// for OldB | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:80:5 + --> tests/ui/empty_line_after/doc_comments.rs:78:5 | LL | / /** LL | | * Meant to be inner doc comment LL | | */ -LL | | LL | | | |_^ LL | fn first_in_module() {} | -------------------- the comment documents this function | = help: if the empty line is unintentional remove it -help: if the doc comment should not document `first_in_module` comment it out - | -LL - /** -LL + /* +help: if the comment should document the parent module use an inner doc comment | +LL | /*! + | ~ error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:87:5 + --> tests/ui/empty_line_after/doc_comments.rs:85:5 | LL | / /** LL | | * Docs for `old_code` LL | | */ -... | +LL | | /* fn old_code() {} */ LL | | | |_^ ... @@ -171,10 +155,9 @@ LL + /* | error: empty line after doc comment - --> tests/ui/empty_line_after/doc_comments.rs:98:5 + --> tests/ui/empty_line_after/doc_comments.rs:96:5 | LL | / /// Docs for `old_code2` -LL | | LL | | /* fn old_code2() {} */ LL | | | |_^ diff --git a/tests/ui/mixed_attributes_style/auxiliary/submodule.rs b/tests/ui/mixed_attributes_style/auxiliary/submodule.rs index 61615c5d3a64..43d22940415f 100644 --- a/tests/ui/mixed_attributes_style/auxiliary/submodule.rs +++ b/tests/ui/mixed_attributes_style/auxiliary/submodule.rs @@ -3,8 +3,6 @@ #![allow(dead_code)] #[allow(unused)] -//~^ mixed_attributes_style - mod foo { #![allow(dead_code)] } diff --git a/tests/ui/mixed_attributes_style/global_allow.rs b/tests/ui/mixed_attributes_style/global_allow.rs index c68a5462afea..19a45e720a60 100644 --- a/tests/ui/mixed_attributes_style/global_allow.rs +++ b/tests/ui/mixed_attributes_style/global_allow.rs @@ -1,6 +1,5 @@ -//@error-in-other-file: -//@no-rustfix -// issue 12436 +// https://github.com/rust-lang/rust-clippy/issues/12436 +//@check-pass #![allow(clippy::mixed_attributes_style)] #[path = "auxiliary/submodule.rs"] diff --git a/tests/ui/mixed_attributes_style/global_allow.stderr b/tests/ui/mixed_attributes_style/global_allow.stderr deleted file mode 100644 index 5fc1d2ac0c3e..000000000000 --- a/tests/ui/mixed_attributes_style/global_allow.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: empty line after outer attribute - --> tests/ui/mixed_attributes_style/auxiliary/submodule.rs:5:1 - | -LL | / #[allow(unused)] -LL | | -LL | | - | |_^ -LL | mod foo { - | ------- the attribute applies to this module - | - = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]` - = help: if the empty line is unintentional remove it -help: if the attribute should apply to the parent module use an inner attribute - | -LL | #![allow(unused)] - | + - -error: aborting due to 1 previous error - diff --git a/tests/ui/mixed_attributes_style/mod_declaration.rs b/tests/ui/mixed_attributes_style/mod_declaration.rs index f2aad9a21e99..8cef6a80048a 100644 --- a/tests/ui/mixed_attributes_style/mod_declaration.rs +++ b/tests/ui/mixed_attributes_style/mod_declaration.rs @@ -1,4 +1,3 @@ -//@error-in-other-file: empty line after outer attribute //@error-in-other-file: item has both inner and outer attributes //@no-rustfix #[path = "auxiliary/submodule.rs"] // don't lint. diff --git a/tests/ui/mixed_attributes_style/mod_declaration.stderr b/tests/ui/mixed_attributes_style/mod_declaration.stderr index 13ec97fbc1af..1239742a05b7 100644 --- a/tests/ui/mixed_attributes_style/mod_declaration.stderr +++ b/tests/ui/mixed_attributes_style/mod_declaration.stderr @@ -2,8 +2,6 @@ error: item has both inner and outer attributes --> tests/ui/mixed_attributes_style/auxiliary/submodule.rs:5:1 | LL | / #[allow(unused)] -LL | | -LL | | LL | | mod foo { LL | | #![allow(dead_code)] | |________________________^ @@ -11,23 +9,5 @@ LL | | #![allow(dead_code)] = note: `-D clippy::mixed-attributes-style` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::mixed_attributes_style)]` -error: empty line after outer attribute - --> tests/ui/mixed_attributes_style/auxiliary/submodule.rs:5:1 - | -LL | / #[allow(unused)] -LL | | -LL | | - | |_^ -LL | mod foo { - | ------- the attribute applies to this module - | - = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]` - = help: if the empty line is unintentional remove it -help: if the attribute should apply to the parent module use an inner attribute - | -LL | #![allow(unused)] - | + - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/suspicious_else_formatting.rs b/tests/ui/suspicious_else_formatting.rs index 7e57684bd437..28a3b551116d 100644 --- a/tests/ui/suspicious_else_formatting.rs +++ b/tests/ui/suspicious_else_formatting.rs @@ -99,10 +99,11 @@ fn main() { // Almost Allman style braces. Lint these. if foo() { } + else { - } + //~^^^^^ suspicious_else_formatting if foo() { } diff --git a/tests/ui/suspicious_else_formatting.stderr b/tests/ui/suspicious_else_formatting.stderr index cf2788b67d07..affd20b22d9c 100644 --- a/tests/ui/suspicious_else_formatting.stderr +++ b/tests/ui/suspicious_else_formatting.stderr @@ -64,7 +64,19 @@ LL | | if foo() { // the span of the above error should continue here = note: to remove this lint, remove the `else` or remove the new line between `else` and `if` error: this is an `else {..}` but the formatting might hide it - --> tests/ui/suspicious_else_formatting.rs:108:6 + --> tests/ui/suspicious_else_formatting.rs:101:6 + | +LL | } + | ______^ +LL | | +LL | | else +LL | | { + | |____^ + | + = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}` + +error: this is an `else {..}` but the formatting might hide it + --> tests/ui/suspicious_else_formatting.rs:109:6 | LL | } | ______^ @@ -75,5 +87,5 @@ LL | | { | = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}` -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/tests/ui/unneeded_struct_pattern.fixed b/tests/ui/unneeded_struct_pattern.fixed index 1fcaa29c51f0..665ab98913be 100644 --- a/tests/ui/unneeded_struct_pattern.fixed +++ b/tests/ui/unneeded_struct_pattern.fixed @@ -2,8 +2,7 @@ #![allow( clippy::manual_unwrap_or_default, clippy::manual_unwrap_or, - clippy::redundant_pattern_matching, - clippy::no_effect + clippy::redundant_pattern_matching )] #![warn(clippy::unneeded_struct_pattern)] @@ -65,19 +64,30 @@ fn main() { match Custom::Init { Custom::HasFields { field: value } => value, Custom::HasBracketsNoFields {} => 0, + Custom::NoBrackets => 0, //~ unneeded_struct_pattern + Custom::NoBracketsNonExhaustive => 0, //~ unneeded_struct_pattern _ => 0, }; match Custom::Init { Custom::HasFields { field: value } => value, Custom::HasBracketsNoFields { .. } => 0, + Custom::NoBrackets => 0, //~ unneeded_struct_pattern + Custom::NoBracketsNonExhaustive => 0, //~ unneeded_struct_pattern _ => 0, }; - 0; - //~^^^ match_single_binding + match Custom::Init { + Custom::NoBrackets if true => 0, //~ unneeded_struct_pattern + _ => 0, + }; - 0; + match Custom::Init { + Custom::NoBrackets | Custom::NoBracketsNonExhaustive => 0, + //~^ unneeded_struct_pattern + //~| unneeded_struct_pattern + _ => 0, + }; if let Custom::HasFields { field: value } = Custom::Init { noop(); @@ -121,6 +131,7 @@ fn main() { let Custom::HasBracketsNoFields { .. } = Custom::Init else { panic!() }; + let Custom::NoBrackets = Custom::Init else { panic!() }; //~ unneeded_struct_pattern let Custom::NoBrackets = Custom::Init else { //~^ unneeded_struct_pattern @@ -138,6 +149,12 @@ fn main() { enum Refutable { Variant, } + + fn pat_in_fn_param_1(Refutable::Variant: Refutable) {} //~ unneeded_struct_pattern + fn pat_in_fn_param_2(Refutable::Variant: Refutable) {} //~ unneeded_struct_pattern + + for Refutable::Variant in [] {} //~ unneeded_struct_pattern + for Refutable::Variant in [] {} //~ unneeded_struct_pattern } fn external_crate() { @@ -149,9 +166,17 @@ fn external_crate() { _ => 0, }; - 0; + match ExhaustiveUnit { + // Exhaustive variant + ExhaustiveUnit => 0, //~ unneeded_struct_pattern + _ => 0, + }; - 0; + match ExhaustiveUnit { + // Exhaustive variant + ExhaustiveUnit => 0, //~ unneeded_struct_pattern + _ => 0, + }; match ExhaustiveUnit { ExhaustiveUnit => 0, diff --git a/tests/ui/unneeded_struct_pattern.rs b/tests/ui/unneeded_struct_pattern.rs index e51311afd5f8..7cadb6c7fbb5 100644 --- a/tests/ui/unneeded_struct_pattern.rs +++ b/tests/ui/unneeded_struct_pattern.rs @@ -2,8 +2,7 @@ #![allow( clippy::manual_unwrap_or_default, clippy::manual_unwrap_or, - clippy::redundant_pattern_matching, - clippy::no_effect + clippy::redundant_pattern_matching )] #![warn(clippy::unneeded_struct_pattern)] @@ -65,22 +64,28 @@ fn main() { match Custom::Init { Custom::HasFields { field: value } => value, Custom::HasBracketsNoFields {} => 0, + Custom::NoBrackets {} => 0, //~ unneeded_struct_pattern + Custom::NoBracketsNonExhaustive {} => 0, //~ unneeded_struct_pattern _ => 0, }; match Custom::Init { Custom::HasFields { field: value } => value, Custom::HasBracketsNoFields { .. } => 0, + Custom::NoBrackets { .. } => 0, //~ unneeded_struct_pattern + Custom::NoBracketsNonExhaustive { .. } => 0, //~ unneeded_struct_pattern _ => 0, }; match Custom::Init { + Custom::NoBrackets {} if true => 0, //~ unneeded_struct_pattern _ => 0, }; - //~^^^ match_single_binding match Custom::Init { - //~^ match_single_binding + Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0, + //~^ unneeded_struct_pattern + //~| unneeded_struct_pattern _ => 0, }; @@ -126,6 +131,7 @@ fn main() { let Custom::HasBracketsNoFields { .. } = Custom::Init else { panic!() }; + let Custom::NoBrackets {} = Custom::Init else { panic!() }; //~ unneeded_struct_pattern let Custom::NoBrackets { .. } = Custom::Init else { //~^ unneeded_struct_pattern @@ -143,6 +149,12 @@ fn main() { enum Refutable { Variant, } + + fn pat_in_fn_param_1(Refutable::Variant {}: Refutable) {} //~ unneeded_struct_pattern + fn pat_in_fn_param_2(Refutable::Variant { .. }: Refutable) {} //~ unneeded_struct_pattern + + for Refutable::Variant {} in [] {} //~ unneeded_struct_pattern + for Refutable::Variant { .. } in [] {} //~ unneeded_struct_pattern } fn external_crate() { @@ -155,14 +167,14 @@ fn external_crate() { }; match ExhaustiveUnit { - //~^ match_single_binding // Exhaustive variant + ExhaustiveUnit { .. } => 0, //~ unneeded_struct_pattern _ => 0, }; match ExhaustiveUnit { - //~^ match_single_binding // Exhaustive variant + ExhaustiveUnit {} => 0, //~ unneeded_struct_pattern _ => 0, }; diff --git a/tests/ui/unneeded_struct_pattern.stderr b/tests/ui/unneeded_struct_pattern.stderr index 5630795823c4..7c0c3c9e4462 100644 --- a/tests/ui/unneeded_struct_pattern.stderr +++ b/tests/ui/unneeded_struct_pattern.stderr @@ -1,5 +1,5 @@ error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:18:13 + --> tests/ui/unneeded_struct_pattern.rs:17:13 | LL | None {} => 0, | ^^^ help: remove the struct pattern @@ -8,152 +8,196 @@ LL | None {} => 0, = help: to override `-D warnings` add `#[allow(clippy::unneeded_struct_pattern)]` error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:24:13 + --> tests/ui/unneeded_struct_pattern.rs:23:13 | LL | None { .. } => 0, | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:35:18 + --> tests/ui/unneeded_struct_pattern.rs:34:18 | LL | Some(None {}) => 0, | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:37:13 + --> tests/ui/unneeded_struct_pattern.rs:36:13 | LL | None {} => 0, | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:41:16 + --> tests/ui/unneeded_struct_pattern.rs:40:16 | LL | if let None {} = Some(0) {} | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:43:16 + --> tests/ui/unneeded_struct_pattern.rs:42:16 | LL | if let None { .. } = Some(0) {} | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:45:21 + --> tests/ui/unneeded_struct_pattern.rs:44:21 | LL | if let Some(None {}) = Some(Some(0)) {} | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:47:13 + --> tests/ui/unneeded_struct_pattern.rs:46:13 | LL | let None {} = Some(0) else { panic!() }; | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:49:13 + --> tests/ui/unneeded_struct_pattern.rs:48:13 | LL | let None { .. } = Some(0) else { panic!() }; | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:51:18 + --> tests/ui/unneeded_struct_pattern.rs:50:18 | LL | let Some(None {}) = Some(Some(0)) else { panic!() }; | ^^^ help: remove the struct pattern -error: this match could be replaced by its body itself - --> tests/ui/unneeded_struct_pattern.rs:77:5 +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:67:27 | -LL | / match Custom::Init { -LL | | _ => 0, -LL | | }; - | |_____^ help: consider using the match body instead: `0` - | - = note: `-D clippy::match-single-binding` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::match_single_binding)]` - -error: this match could be replaced by its body itself - --> tests/ui/unneeded_struct_pattern.rs:82:5 - | -LL | / match Custom::Init { -LL | | -LL | | _ => 0, -LL | | }; - | |_____^ help: consider using the match body instead: `0` +LL | Custom::NoBrackets {} => 0, + | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:96:30 + --> tests/ui/unneeded_struct_pattern.rs:68:40 + | +LL | Custom::NoBracketsNonExhaustive {} => 0, + | ^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:75:27 + | +LL | Custom::NoBrackets { .. } => 0, + | ^^^^^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:76:40 + | +LL | Custom::NoBracketsNonExhaustive { .. } => 0, + | ^^^^^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:81:27 + | +LL | Custom::NoBrackets {} if true => 0, + | ^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:86:27 + | +LL | Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0, + | ^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:86:64 + | +LL | Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0, + | ^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:101:30 | LL | if let Custom::NoBrackets {} = Custom::Init { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:100:30 + --> tests/ui/unneeded_struct_pattern.rs:105:30 | LL | if let Custom::NoBrackets { .. } = Custom::Init { | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:104:30 + --> tests/ui/unneeded_struct_pattern.rs:109:30 | LL | if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:104:67 + --> tests/ui/unneeded_struct_pattern.rs:109:67 | LL | if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:109:43 + --> tests/ui/unneeded_struct_pattern.rs:114:43 | LL | if let Custom::NoBracketsNonExhaustive {} = Custom::Init { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:113:43 + --> tests/ui/unneeded_struct_pattern.rs:118:43 | LL | if let Custom::NoBracketsNonExhaustive { .. } = Custom::Init { | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:130:27 + --> tests/ui/unneeded_struct_pattern.rs:134:27 + | +LL | let Custom::NoBrackets {} = Custom::Init else { panic!() }; + | ^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:136:27 | LL | let Custom::NoBrackets { .. } = Custom::Init else { | ^^^^^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:134:40 + --> tests/ui/unneeded_struct_pattern.rs:140:40 | LL | let Custom::NoBracketsNonExhaustive {} = Custom::Init else { | ^^^ help: remove the struct pattern error: struct pattern is not needed for a unit variant - --> tests/ui/unneeded_struct_pattern.rs:138:40 + --> tests/ui/unneeded_struct_pattern.rs:144:40 | LL | let Custom::NoBracketsNonExhaustive { .. } = Custom::Init else { | ^^^^^^^ help: remove the struct pattern -error: this match could be replaced by its body itself - --> tests/ui/unneeded_struct_pattern.rs:157:5 +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:153:44 | -LL | / match ExhaustiveUnit { -LL | | -LL | | // Exhaustive variant -LL | | _ => 0, -LL | | }; - | |_____^ help: consider using the match body instead: `0` +LL | fn pat_in_fn_param_1(Refutable::Variant {}: Refutable) {} + | ^^^ help: remove the struct pattern -error: this match could be replaced by its body itself - --> tests/ui/unneeded_struct_pattern.rs:163:5 +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:154:44 | -LL | / match ExhaustiveUnit { -LL | | -LL | | // Exhaustive variant -LL | | _ => 0, -LL | | }; - | |_____^ help: consider using the match body instead: `0` +LL | fn pat_in_fn_param_2(Refutable::Variant { .. }: Refutable) {} + | ^^^^^^^ help: remove the struct pattern -error: aborting due to 23 previous errors +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:156:27 + | +LL | for Refutable::Variant {} in [] {} + | ^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:157:27 + | +LL | for Refutable::Variant { .. } in [] {} + | ^^^^^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:171:23 + | +LL | ExhaustiveUnit { .. } => 0, + | ^^^^^^^ help: remove the struct pattern + +error: struct pattern is not needed for a unit variant + --> tests/ui/unneeded_struct_pattern.rs:177:23 + | +LL | ExhaustiveUnit {} => 0, + | ^^^ help: remove the struct pattern + +error: aborting due to 33 previous errors From 622e8f4812b8bcd9a3501ca7d299987fff733b68 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Sun, 12 Jan 2025 23:27:35 +0100 Subject: [PATCH 151/991] apply random float error to most floating-point operations --- src/tools/miri/src/intrinsics/mod.rs | 108 ++++++-- src/tools/miri/src/math.rs | 16 ++ src/tools/miri/src/shims/foreign_items.rs | 40 ++- src/tools/miri/tests/pass/float.rs | 323 ++++++++++++++++++---- 4 files changed, 403 insertions(+), 84 deletions(-) diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index ec4fdfe0bacf..377f3a902ed7 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -7,12 +7,13 @@ use rand::Rng; use rustc_abi::Size; use rustc_apfloat::{Float, Round}; use rustc_middle::mir; -use rustc_middle::ty::{self, FloatTy}; +use rustc_middle::ty::{self, FloatTy, ScalarInt}; use rustc_span::{Symbol, sym}; use self::atomic::EvalContextExt as _; use self::helpers::{ToHost, ToSoft, check_intrinsic_arg_count}; use self::simd::EvalContextExt as _; +use crate::math::apply_random_float_error_ulp; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -206,10 +207,26 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } + "sqrtf32" => { + let [f] = check_intrinsic_arg_count(args)?; + let f = this.read_scalar(f)?.to_f32()?; + // Sqrt is specified to be fully precise. + let res = math::sqrt(f); + let res = this.adjust_nan(res, &[f]); + this.write_scalar(res, dest)?; + } + "sqrtf64" => { + let [f] = check_intrinsic_arg_count(args)?; + let f = this.read_scalar(f)?.to_f64()?; + // Sqrt is specified to be fully precise. + let res = math::sqrt(f); + let res = this.adjust_nan(res, &[f]); + this.write_scalar(res, dest)?; + } + #[rustfmt::skip] | "sinf32" | "cosf32" - | "sqrtf32" | "expf32" | "exp2f32" | "logf32" @@ -218,26 +235,33 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { => { let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; - // Using host floats except for sqrt (but it's fine, these operations do not have + // Using host floats (but it's fine, these operations do not have // guaranteed precision). + let host = f.to_host(); let res = match intrinsic_name { - "sinf32" => f.to_host().sin().to_soft(), - "cosf32" => f.to_host().cos().to_soft(), - "sqrtf32" => math::sqrt(f), - "expf32" => f.to_host().exp().to_soft(), - "exp2f32" => f.to_host().exp2().to_soft(), - "logf32" => f.to_host().ln().to_soft(), - "log10f32" => f.to_host().log10().to_soft(), - "log2f32" => f.to_host().log2().to_soft(), + "sinf32" => host.sin(), + "cosf32" => host.cos(), + "expf32" => host.exp(), + "exp2f32" => host.exp2(), + "logf32" => host.ln(), + "log10f32" => host.log10(), + "log2f32" => host.log2(), _ => bug!(), }; + let res = res.to_soft(); + // Apply a relative error of 16ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = apply_random_float_error_ulp( + this, + res, + 4 + ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } #[rustfmt::skip] | "sinf64" | "cosf64" - | "sqrtf64" | "expf64" | "exp2f64" | "logf64" @@ -246,19 +270,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { => { let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; - // Using host floats except for sqrt (but it's fine, these operations do not have + // Using host floats (but it's fine, these operations do not have // guaranteed precision). + let host = f.to_host(); let res = match intrinsic_name { - "sinf64" => f.to_host().sin().to_soft(), - "cosf64" => f.to_host().cos().to_soft(), - "sqrtf64" => math::sqrt(f), - "expf64" => f.to_host().exp().to_soft(), - "exp2f64" => f.to_host().exp2().to_soft(), - "logf64" => f.to_host().ln().to_soft(), - "log10f64" => f.to_host().log10().to_soft(), - "log2f64" => f.to_host().log2().to_soft(), + "sinf64" => host.sin(), + "cosf64" => host.cos(), + "expf64" => host.exp(), + "exp2f64" => host.exp2(), + "logf64" => host.ln(), + "log10f64" => host.log10(), + "log2f64" => host.log2(), _ => bug!(), }; + let res = res.to_soft(); + // Apply a relative error of 16ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = apply_random_float_error_ulp( + this, + res, + 4 + ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } @@ -316,6 +348,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "powf32" => { + // FIXME: apply random relative error but without altering behaviour of powf let [f1, f2] = check_intrinsic_arg_count(args)?; let f1 = this.read_scalar(f1)?.to_f32()?; let f2 = this.read_scalar(f2)?.to_f32()?; @@ -325,6 +358,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "powf64" => { + // FIXME: apply random relative error but without altering behaviour of powf let [f1, f2] = check_intrinsic_arg_count(args)?; let f1 = this.read_scalar(f1)?.to_f64()?; let f2 = this.read_scalar(f2)?.to_f64()?; @@ -335,6 +369,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "powif32" => { + // FIXME: apply random relative error but without altering behaviour of powi let [f, i] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; let i = this.read_scalar(i)?.to_i32()?; @@ -344,6 +379,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "powif64" => { + // FIXME: apply random relative error but without altering behaviour of powi let [f, i] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; let i = this.read_scalar(i)?.to_i32()?; @@ -372,7 +408,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { _ => bug!(), }; let res = this.binary_op(op, &a, &b)?; - // `binary_op` already called `generate_nan` if necessary. + // `binary_op` already called `generate_nan` if needed. + // Apply a relative error of 16ULP to simulate non-deterministic precision loss + // due to optimizations. + let res = apply_random_float_error_to_imm(this, res)?; this.write_immediate(*res, dest)?; } @@ -418,11 +457,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { _ => {} } let res = this.binary_op(op, &a, &b)?; + // This cannot be a NaN so we also don't have to apply any non-determinism. + // (Also, `binary_op` already called `generate_nan` if needed.) if !float_finite(&res)? { throw_ub_format!("`{intrinsic_name}` intrinsic produced non-finite value as result"); } - // This cannot be a NaN so we also don't have to apply any non-determinism. - // (Also, `binary_op` already called `generate_nan` if needed.) + // Apply a relative error of 16ULP to simulate non-deterministic precision loss + // due to optimizations. + let res = apply_random_float_error_to_imm(this, res)?; this.write_immediate(*res, dest)?; } @@ -455,3 +497,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(EmulateItemResult::NeedsReturn) } } + +/// Applies a random 16ULP floating point error to `val` and returns the new value. +/// Will fail if `val` is not a floating point number. +fn apply_random_float_error_to_imm<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, + val: ImmTy<'tcx>, +) -> InterpResult<'tcx, ImmTy<'tcx>> { + let scalar = val.to_scalar_int()?; + let res: ScalarInt = match val.layout.ty.kind() { + ty::Float(FloatTy::F16) => apply_random_float_error_ulp(ecx, scalar.to_f16(), 4).into(), + ty::Float(FloatTy::F32) => apply_random_float_error_ulp(ecx, scalar.to_f32(), 4).into(), + ty::Float(FloatTy::F64) => apply_random_float_error_ulp(ecx, scalar.to_f64(), 4).into(), + ty::Float(FloatTy::F128) => apply_random_float_error_ulp(ecx, scalar.to_f128(), 4).into(), + _ => bug!("intrinsic called with non-float input type"), + }; + + interp_ok(ImmTy::from_scalar_int(res, val.layout)) +} diff --git a/src/tools/miri/src/math.rs b/src/tools/miri/src/math.rs index 7117f722fee8..fdd021f85394 100644 --- a/src/tools/miri/src/math.rs +++ b/src/tools/miri/src/math.rs @@ -27,6 +27,22 @@ pub(crate) fn apply_random_float_error( (val * (F::from_u128(1).value + err).value).value } +/// [`apply_random_float_error`] gives instructions to apply a 2^N ULP error. +/// This function implements these instructions such that applying a 2^N ULP error is less error prone. +/// So for a 2^N ULP error, you would pass N as the `ulp_exponent` argument. +pub(crate) fn apply_random_float_error_ulp( + ecx: &mut crate::MiriInterpCx<'_>, + val: F, + ulp_exponent: u32, +) -> F { + let n = i32::try_from(ulp_exponent) + .expect("`err_scale_for_ulp`: exponent is too large to create an error scale"); + // we know this fits + let prec = i32::try_from(F::PRECISION).unwrap(); + let err_scale = -(prec - n - 1); + apply_random_float_error(ecx, val, err_scale) +} + pub(crate) fn sqrt(x: IeeeFloat) -> IeeeFloat { match x.category() { // preserve zero sign diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index bedc1ebdc950..f7746ca81f29 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -765,7 +765,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "erfcf" => f_host.erfc(), _ => bug!(), }; - let res = res.to_soft(); + // Apply a relative error of 16ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = math::apply_random_float_error_ulp( + this, + res.to_soft(), + 4 + ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } @@ -788,6 +794,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "fdimf" => f1.to_host().abs_sub(f2.to_host()).to_soft(), _ => bug!(), }; + // Apply a relative error of 16ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = math::apply_random_float_error_ulp( + this, + res, + 4 + ); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; } @@ -826,7 +839,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "erfc" => f_host.erfc(), _ => bug!(), }; - let res = res.to_soft(); + // Apply a relative error of 16ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = math::apply_random_float_error_ulp( + this, + res.to_soft(), + 4 + ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } @@ -849,6 +868,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "fdim" => f1.to_host().abs_sub(f2.to_host()).to_soft(), _ => bug!(), }; + // Apply a relative error of 16ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = math::apply_random_float_error_ulp( + this, + res, + 4 + ); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; } @@ -874,7 +900,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Using host floats (but it's fine, these operations do not have guaranteed precision). let (res, sign) = x.to_host().ln_gamma(); this.write_int(sign, &signp)?; - let res = this.adjust_nan(res.to_soft(), &[x]); + // Apply a relative error of 16ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = math::apply_random_float_error_ulp(this, res.to_soft(), 4); + let res = this.adjust_nan(res, &[x]); this.write_scalar(res, dest)?; } "lgamma_r" => { @@ -885,7 +914,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Using host floats (but it's fine, these operations do not have guaranteed precision). let (res, sign) = x.to_host().ln_gamma(); this.write_int(sign, &signp)?; - let res = this.adjust_nan(res.to_soft(), &[x]); + // Apply a relative error of 16ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = math::apply_random_float_error_ulp(this, res.to_soft(), 4); + let res = this.adjust_nan(res, &[x]); this.write_scalar(res, dest)?; } diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 51cafbb3f43b..808495c73d37 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -13,11 +13,85 @@ use std::fmt::{Debug, Display, LowerHex}; use std::hint::black_box; use std::{f32, f64}; +/// Another way of checking if 2 floating-point numbers are almost equal to eachother. +/// Using `a` and `b` as floating-point numbers: +/// +/// Instead of performing a simple EPSILON check (which we used at first): +/// The absolute difference between 'a' and 'b' must not be greater than some E (10^-6, ...) +/// +/// We will now use ULP: `Units in the Last Place` or `Units of Least Precision`, +/// more specific, the difference in ULP of `a` and `b`. +/// First: The ULP of a float 'a' is the smallest possible change at 'a', so the ULP difference represents how +/// many discrete floating-point steps are needed to reach 'b' from 'a'. +/// +/// ULP(a) is the distance between the 2 closest floating-point numbers `x` and `y` around `a`, satisfying x < a < y, x != y. +/// To use this to calculate the ULP difference we have to halve it (we need it at `a`, but we just went "up" and "down", halving it gives us this ULP). +/// Then take the difference of `b` and `a` and divide it by that ULP and finally round it. +/// We know now how many floating-point changes we have to apply to `a` to get to `b`. +/// +/// So if this ULP difference is less than or equal to our chosen upper bound +/// we can say that `a` and `b` are approximately equal, because they lie "close" enough to each other to be considered equal. +/// +/// Note: We can see that checking `a` and `b` with different signs has no meaning, but we should not forget +/// -0.0 and +0.0. +/// +/// Essentially ULP can be seen as a distance metric of floating-point numbers, but with +/// the same amount of "spacing" between all consecutive representable values. So even though 2 very large floating point numbers +/// have a large value difference, their ULP can still be 1, so they are still "approximatly equal", +/// but the EPSILON check would have failed. +/// +fn approx_eq_check( + actual: F, + expected: F, + allowed_ulp: F::Int, +) -> Result<(), NotApproxEq> +where + F::Int: PartialOrd, +{ + let actual_signum = actual.signum(); + let expected_signum = expected.signum(); + + if actual_signum != expected_signum { + // Floats with different signs must both be 0. + if actual != expected { + return Err(NotApproxEq::SignsDiffer); + } + } else { + let ulp = (expected.next_up() - expected.next_down()).halve(); + let ulp_diff = ((actual - expected) / ulp).round().as_int(); + + if ulp_diff > allowed_ulp { + return Err(NotApproxEq::UlpFail(ulp_diff)); + } + } + Ok(()) +} + +/// Give more context to execution and result of [`approx_eq_check`]. +enum NotApproxEq { + SignsDiffer, + + /// Contains the actual ulp value calculated. + UlpFail(F::Int), +} + macro_rules! assert_approx_eq { - ($a:expr, $b:expr) => {{ - let (a, b) = (&$a, &$b); - assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b); + ($a:expr, $b:expr, $ulp:expr) => {{ + let (a, b) = ($a, $b); + let allowed_ulp = $ulp; + match approx_eq_check(a, b, allowed_ulp) { + Err(NotApproxEq::SignsDiffer) => + panic!("{a:?} is not approximately equal to {b:?}: signs differ"), + Err(NotApproxEq::UlpFail(actual_ulp)) => + panic!("{a:?} is not approximately equal to {b:?}\nulp diff: {actual_ulp} > {allowed_ulp}"), + Ok(_) => {} + }; }}; + + ($a:expr, $b: expr) => { + // accept up to 64ULP (16ULP for host floats and 16ULP for miri artificial error and 32 for any rounding errors) + assert_approx_eq!($a, $b, 64); + }; } fn main() { @@ -27,15 +101,23 @@ fn main() { ops(); nan_casts(); rounding(); - mul_add(); libm(); + mul_add(); test_fast(); test_algebraic(); test_fmuladd(); test_min_max_nondet(); + test_non_determinism(); } -trait Float: Copy + PartialEq + Debug { +trait Float: + Copy + + PartialEq + + Debug + + std::ops::Sub + + std::cmp::PartialOrd + + std::ops::Div +{ /// The unsigned integer with the same bit width as this float type Int: Copy + PartialEq + LowerHex + Debug; const BITS: u32 = size_of::() as u32 * 8; @@ -49,6 +131,15 @@ trait Float: Copy + PartialEq + Debug { const EXPONENT_BIAS: u32 = Self::EXPONENT_SAT >> 1; fn to_bits(self) -> Self::Int; + + // to make "approx_eq_check" generic + fn signum(self) -> Self; + fn next_up(self) -> Self; + fn next_down(self) -> Self; + fn round(self) -> Self; + // self / 2 + fn halve(self) -> Self; + fn as_int(self) -> Self::Int; } macro_rules! impl_float { @@ -61,6 +152,27 @@ macro_rules! impl_float { fn to_bits(self) -> Self::Int { self.to_bits() } + + fn signum(self) -> Self { + self.signum() + } + fn next_up(self) -> Self { + self.next_up() + } + fn next_down(self) -> Self { + self.next_down() + } + fn round(self) -> Self { + self.round() + } + + fn halve(self) -> Self { + self / 2.0 + } + + fn as_int(self) -> Self::Int { + self as Self::Int + } } }; } @@ -1005,8 +1117,8 @@ pub fn libm() { #[allow(deprecated)] { - assert_approx_eq!(5.0f32.abs_sub(3.0), 2.0); - assert_approx_eq!(3.0f64.abs_sub(5.0), 0.0); + assert_approx_eq!(5.0f32.abs_sub(3.0), 2.0f32); + assert_approx_eq!(3.0f64.abs_sub(5.0), 0.0f64); } assert_approx_eq!(27.0f32.cbrt(), 3.0f32); @@ -1023,30 +1135,30 @@ pub fn libm() { assert_approx_eq!(0f32.sin(), 0f32); assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64); - assert_approx_eq!(f32::consts::FRAC_PI_6.sin(), 0.5); - assert_approx_eq!(f64::consts::FRAC_PI_6.sin(), 0.5); + assert_approx_eq!(f32::consts::FRAC_PI_6.sin(), 0.5f32); + assert_approx_eq!(f64::consts::FRAC_PI_6.sin(), 0.5f64); assert_approx_eq!(f32::consts::FRAC_PI_4.sin().asin(), f32::consts::FRAC_PI_4); assert_approx_eq!(f64::consts::FRAC_PI_4.sin().asin(), f64::consts::FRAC_PI_4); assert_approx_eq!(1.0f32.sinh(), 1.1752012f32); - assert_approx_eq!(1.0f64.sinh(), 1.1752012f64); + assert_approx_eq!(1.0f64.sinh(), 1.1752011936438014f64); assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32); assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64); assert_approx_eq!(0f32.cos(), 1f32); assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64); - assert_approx_eq!(f32::consts::FRAC_PI_3.cos(), 0.5); - assert_approx_eq!(f64::consts::FRAC_PI_3.cos(), 0.5); + assert_approx_eq!(f32::consts::FRAC_PI_3.cos(), 0.5f32); + assert_approx_eq!(f64::consts::FRAC_PI_3.cos(), 0.5f64); assert_approx_eq!(f32::consts::FRAC_PI_4.cos().acos(), f32::consts::FRAC_PI_4); assert_approx_eq!(f64::consts::FRAC_PI_4.cos().acos(), f64::consts::FRAC_PI_4); assert_approx_eq!(1.0f32.cosh(), 1.54308f32); - assert_approx_eq!(1.0f64.cosh(), 1.54308f64); + assert_approx_eq!(1.0f64.cosh(), 1.5430806348152437f64); assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32); assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64); assert_approx_eq!(1.0f32.tan(), 1.557408f32); - assert_approx_eq!(1.0f64.tan(), 1.557408f64); + assert_approx_eq!(1.0f64.tan(), 1.5574077246549023f64); assert_approx_eq!(1.0_f32, 1.0_f32.tan().atan()); assert_approx_eq!(1.0_f64, 1.0_f64.tan().atan()); assert_approx_eq!(1.0f32.atan2(2.0f32), 0.46364761f32); @@ -1063,8 +1175,8 @@ pub fn libm() { assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32); assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64); - assert_approx_eq!(5.0f32.gamma(), 24.0); - assert_approx_eq!(5.0f64.gamma(), 24.0); + assert_approx_eq!(5.0f32.gamma(), 24.0f32); + assert_approx_eq!(5.0f64.gamma(), 24.0f64); assert_approx_eq!((-0.5f32).gamma(), (-2.0) * f32::consts::PI.sqrt()); assert_approx_eq!((-0.5f64).gamma(), (-2.0) * f64::consts::PI.sqrt()); @@ -1091,11 +1203,11 @@ fn test_fast() { pub fn test_operations_f16(a: f16, b: f16) { // make sure they all map to the correct operation unsafe { - assert_eq!(fadd_fast(a, b), a + b); - assert_eq!(fsub_fast(a, b), a - b); - assert_eq!(fmul_fast(a, b), a * b); - assert_eq!(fdiv_fast(a, b), a / b); - assert_eq!(frem_fast(a, b), a % b); + assert_approx_eq!(fadd_fast(a, b), a + b); + assert_approx_eq!(fsub_fast(a, b), a - b); + assert_approx_eq!(fmul_fast(a, b), a * b); + assert_approx_eq!(fdiv_fast(a, b), a / b); + assert_approx_eq!(frem_fast(a, b), a % b); } } @@ -1103,11 +1215,11 @@ fn test_fast() { pub fn test_operations_f32(a: f32, b: f32) { // make sure they all map to the correct operation unsafe { - assert_eq!(fadd_fast(a, b), a + b); - assert_eq!(fsub_fast(a, b), a - b); - assert_eq!(fmul_fast(a, b), a * b); - assert_eq!(fdiv_fast(a, b), a / b); - assert_eq!(frem_fast(a, b), a % b); + assert_approx_eq!(fadd_fast(a, b), a + b); + assert_approx_eq!(fsub_fast(a, b), a - b); + assert_approx_eq!(fmul_fast(a, b), a * b); + assert_approx_eq!(fdiv_fast(a, b), a / b); + assert_approx_eq!(frem_fast(a, b), a % b); } } @@ -1115,11 +1227,11 @@ fn test_fast() { pub fn test_operations_f64(a: f64, b: f64) { // make sure they all map to the correct operation unsafe { - assert_eq!(fadd_fast(a, b), a + b); - assert_eq!(fsub_fast(a, b), a - b); - assert_eq!(fmul_fast(a, b), a * b); - assert_eq!(fdiv_fast(a, b), a / b); - assert_eq!(frem_fast(a, b), a % b); + assert_approx_eq!(fadd_fast(a, b), a + b); + assert_approx_eq!(fsub_fast(a, b), a - b); + assert_approx_eq!(fmul_fast(a, b), a * b); + assert_approx_eq!(fdiv_fast(a, b), a / b); + assert_approx_eq!(frem_fast(a, b), a % b); } } @@ -1127,11 +1239,11 @@ fn test_fast() { pub fn test_operations_f128(a: f128, b: f128) { // make sure they all map to the correct operation unsafe { - assert_eq!(fadd_fast(a, b), a + b); - assert_eq!(fsub_fast(a, b), a - b); - assert_eq!(fmul_fast(a, b), a * b); - assert_eq!(fdiv_fast(a, b), a / b); - assert_eq!(frem_fast(a, b), a % b); + assert_approx_eq!(fadd_fast(a, b), a + b); + assert_approx_eq!(fsub_fast(a, b), a - b); + assert_approx_eq!(fmul_fast(a, b), a * b); + assert_approx_eq!(fdiv_fast(a, b), a / b); + assert_approx_eq!(frem_fast(a, b), a % b); } } @@ -1153,41 +1265,41 @@ fn test_algebraic() { #[inline(never)] pub fn test_operations_f16(a: f16, b: f16) { // make sure they all map to the correct operation - assert_eq!(fadd_algebraic(a, b), a + b); - assert_eq!(fsub_algebraic(a, b), a - b); - assert_eq!(fmul_algebraic(a, b), a * b); - assert_eq!(fdiv_algebraic(a, b), a / b); - assert_eq!(frem_algebraic(a, b), a % b); + assert_approx_eq!(fadd_algebraic(a, b), a + b); + assert_approx_eq!(fsub_algebraic(a, b), a - b); + assert_approx_eq!(fmul_algebraic(a, b), a * b); + assert_approx_eq!(fdiv_algebraic(a, b), a / b); + assert_approx_eq!(frem_algebraic(a, b), a % b); } #[inline(never)] pub fn test_operations_f32(a: f32, b: f32) { // make sure they all map to the correct operation - assert_eq!(fadd_algebraic(a, b), a + b); - assert_eq!(fsub_algebraic(a, b), a - b); - assert_eq!(fmul_algebraic(a, b), a * b); - assert_eq!(fdiv_algebraic(a, b), a / b); - assert_eq!(frem_algebraic(a, b), a % b); + assert_approx_eq!(fadd_algebraic(a, b), a + b); + assert_approx_eq!(fsub_algebraic(a, b), a - b); + assert_approx_eq!(fmul_algebraic(a, b), a * b); + assert_approx_eq!(fdiv_algebraic(a, b), a / b); + assert_approx_eq!(frem_algebraic(a, b), a % b); } #[inline(never)] pub fn test_operations_f64(a: f64, b: f64) { // make sure they all map to the correct operation - assert_eq!(fadd_algebraic(a, b), a + b); - assert_eq!(fsub_algebraic(a, b), a - b); - assert_eq!(fmul_algebraic(a, b), a * b); - assert_eq!(fdiv_algebraic(a, b), a / b); - assert_eq!(frem_algebraic(a, b), a % b); + assert_approx_eq!(fadd_algebraic(a, b), a + b); + assert_approx_eq!(fsub_algebraic(a, b), a - b); + assert_approx_eq!(fmul_algebraic(a, b), a * b); + assert_approx_eq!(fdiv_algebraic(a, b), a / b); + assert_approx_eq!(frem_algebraic(a, b), a % b); } #[inline(never)] pub fn test_operations_f128(a: f128, b: f128) { // make sure they all map to the correct operation - assert_eq!(fadd_algebraic(a, b), a + b); - assert_eq!(fsub_algebraic(a, b), a - b); - assert_eq!(fmul_algebraic(a, b), a * b); - assert_eq!(fdiv_algebraic(a, b), a / b); - assert_eq!(frem_algebraic(a, b), a % b); + assert_approx_eq!(fadd_algebraic(a, b), a + b); + assert_approx_eq!(fsub_algebraic(a, b), a - b); + assert_approx_eq!(fmul_algebraic(a, b), a * b); + assert_approx_eq!(fdiv_algebraic(a, b), a / b); + assert_approx_eq!(frem_algebraic(a, b), a % b); } test_operations_f16(11., 2.); @@ -1245,3 +1357,102 @@ fn test_min_max_nondet() { ensure_both(|| f128::min(0.0, -0.0).is_sign_positive()); ensure_both(|| f128::max(0.0, -0.0).is_sign_positive()); } + +fn test_non_determinism() { + use std::intrinsics::{ + fadd_algebraic, fadd_fast, fdiv_algebraic, fdiv_fast, fmul_algebraic, fmul_fast, + frem_algebraic, frem_fast, fsub_algebraic, fsub_fast, + }; + use std::{f32, f64}; + // TODO: Also test powi and powf when the non-determinism is implemented for them + + /// Ensure that the operation is non-deterministic + #[track_caller] + fn ensure_nondet(f: impl Fn() -> T) { + let rounds = 16; + let first = f(); + for _ in 1..rounds { + if f() != first { + // We saw two different values! + return; + } + } + // We saw the same thing N times. + panic!("expected non-determinism, got {rounds} times the same result: {first:?}"); + } + + macro_rules! test_operations_f { + ($a:expr, $b:expr) => { + ensure_nondet(|| fadd_algebraic($a, $b)); + ensure_nondet(|| fsub_algebraic($a, $b)); + ensure_nondet(|| fmul_algebraic($a, $b)); + ensure_nondet(|| fdiv_algebraic($a, $b)); + ensure_nondet(|| frem_algebraic($a, $b)); + + unsafe { + ensure_nondet(|| fadd_fast($a, $b)); + ensure_nondet(|| fsub_fast($a, $b)); + ensure_nondet(|| fmul_fast($a, $b)); + ensure_nondet(|| fdiv_fast($a, $b)); + ensure_nondet(|| frem_fast($a, $b)); + } + }; + } + + pub fn test_operations_f16(a: f16, b: f16) { + test_operations_f!(a, b); + } + pub fn test_operations_f32(a: f32, b: f32) { + test_operations_f!(a, b); + ensure_nondet(|| a.log(b)); + ensure_nondet(|| a.exp()); + ensure_nondet(|| 10f32.exp2()); + ensure_nondet(|| f32::consts::E.ln()); + ensure_nondet(|| 1f32.ln_1p()); + ensure_nondet(|| 10f32.log10()); + ensure_nondet(|| 8f32.log2()); + ensure_nondet(|| 27.0f32.cbrt()); + ensure_nondet(|| 3.0f32.hypot(4.0f32)); + ensure_nondet(|| 1f32.sin()); + ensure_nondet(|| 0f32.cos()); + ensure_nondet(|| 1.0f32.sinh()); + ensure_nondet(|| 1.0f32.asinh()); + ensure_nondet(|| 1.0f32.cosh()); + ensure_nondet(|| 2.0f32.acosh()); + ensure_nondet(|| 1.0f32.tan()); + ensure_nondet(|| 1.0f32.tanh()); + ensure_nondet(|| 1.0f32.atan2(2.0f32)); + ensure_nondet(|| 0.5f32.atanh()); + ensure_nondet(|| 5.0f32.gamma()); + } + pub fn test_operations_f64(a: f64, b: f64) { + test_operations_f!(a, b); + ensure_nondet(|| a.log(b)); + ensure_nondet(|| a.exp()); + ensure_nondet(|| 50f64.exp2()); + ensure_nondet(|| 3f64.ln()); + ensure_nondet(|| 1f64.ln_1p()); + ensure_nondet(|| f64::consts::E.log10()); + ensure_nondet(|| f64::consts::E.log2()); + ensure_nondet(|| 1f64.sin()); + ensure_nondet(|| 0f64.cos()); + ensure_nondet(|| 27.0f64.cbrt()); + ensure_nondet(|| 3.0f64.hypot(4.0f64)); + ensure_nondet(|| 1.0f64.sinh()); + ensure_nondet(|| 1.0f64.asinh()); + ensure_nondet(|| 1.0f64.cosh()); + ensure_nondet(|| 3.0f64.acosh()); + ensure_nondet(|| 1.0f64.tan()); + ensure_nondet(|| 1.0f64.tanh()); + ensure_nondet(|| 0.5f64.atanh()); + ensure_nondet(|| 5.0f64.gamma()); + } + pub fn test_operations_f128(a: f128, b: f128) { + test_operations_f!(a, b); + } + + test_operations_f16(5., 7.); + test_operations_f32(12., 5.); + test_operations_f64(19., 11.); + test_operations_f128(25., 18.); +} From 1849256a267186949e922c657b15bb9f2e893498 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Feb 2025 19:07:21 +0100 Subject: [PATCH 152/991] add erf and erfc to nondet tests, and reduce how much we're changing the float test --- src/tools/miri/src/intrinsics/mod.rs | 21 ++-- src/tools/miri/src/shims/foreign_items.rs | 14 ++- src/tools/miri/tests/pass/float.rs | 138 +++++----------------- 3 files changed, 48 insertions(+), 125 deletions(-) diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 377f3a902ed7..a8655aee0ca2 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -254,7 +254,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = apply_random_float_error_ulp( this, res, - 4 + 4, // log2(16) ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; @@ -289,7 +289,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = apply_random_float_error_ulp( this, res, - 4 + 4, // log2(16) ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; @@ -411,7 +411,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `binary_op` already called `generate_nan` if needed. // Apply a relative error of 16ULP to simulate non-deterministic precision loss // due to optimizations. - let res = apply_random_float_error_to_imm(this, res)?; + let res = apply_random_float_error_to_imm(this, res, 4 /* log2(16) */)?; this.write_immediate(*res, dest)?; } @@ -464,7 +464,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Apply a relative error of 16ULP to simulate non-deterministic precision loss // due to optimizations. - let res = apply_random_float_error_to_imm(this, res)?; + let res = apply_random_float_error_to_imm(this, res, 4 /* log2(16) */)?; this.write_immediate(*res, dest)?; } @@ -503,13 +503,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn apply_random_float_error_to_imm<'tcx>( ecx: &mut MiriInterpCx<'tcx>, val: ImmTy<'tcx>, + ulp_exponent: u32, ) -> InterpResult<'tcx, ImmTy<'tcx>> { let scalar = val.to_scalar_int()?; let res: ScalarInt = match val.layout.ty.kind() { - ty::Float(FloatTy::F16) => apply_random_float_error_ulp(ecx, scalar.to_f16(), 4).into(), - ty::Float(FloatTy::F32) => apply_random_float_error_ulp(ecx, scalar.to_f32(), 4).into(), - ty::Float(FloatTy::F64) => apply_random_float_error_ulp(ecx, scalar.to_f64(), 4).into(), - ty::Float(FloatTy::F128) => apply_random_float_error_ulp(ecx, scalar.to_f128(), 4).into(), + ty::Float(FloatTy::F16) => + apply_random_float_error_ulp(ecx, scalar.to_f16(), ulp_exponent).into(), + ty::Float(FloatTy::F32) => + apply_random_float_error_ulp(ecx, scalar.to_f32(), ulp_exponent).into(), + ty::Float(FloatTy::F64) => + apply_random_float_error_ulp(ecx, scalar.to_f64(), ulp_exponent).into(), + ty::Float(FloatTy::F128) => + apply_random_float_error_ulp(ecx, scalar.to_f128(), ulp_exponent).into(), _ => bug!("intrinsic called with non-float input type"), }; diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index f7746ca81f29..ec8f6663822d 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -770,7 +770,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = math::apply_random_float_error_ulp( this, res.to_soft(), - 4 + 4, // log2(16) ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; @@ -799,7 +799,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = math::apply_random_float_error_ulp( this, res, - 4 + 4, // log2(16) ); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; @@ -844,7 +844,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = math::apply_random_float_error_ulp( this, res.to_soft(), - 4 + 4, // log2(16) ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; @@ -873,7 +873,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = math::apply_random_float_error_ulp( this, res, - 4 + 4, // log2(16) ); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; @@ -902,7 +902,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_int(sign, &signp)?; // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = math::apply_random_float_error_ulp(this, res.to_soft(), 4); + let res = + math::apply_random_float_error_ulp(this, res.to_soft(), 4 /* log2(16) */); let res = this.adjust_nan(res, &[x]); this.write_scalar(res, dest)?; } @@ -916,7 +917,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_int(sign, &signp)?; // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = math::apply_random_float_error_ulp(this, res.to_soft(), 4); + let res = + math::apply_random_float_error_ulp(this, res.to_soft(), 4 /* log2(16) */); let res = this.adjust_nan(res, &[x]); this.write_scalar(res, dest)?; } diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 808495c73d37..0eb7d6e83095 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -13,78 +13,27 @@ use std::fmt::{Debug, Display, LowerHex}; use std::hint::black_box; use std::{f32, f64}; -/// Another way of checking if 2 floating-point numbers are almost equal to eachother. -/// Using `a` and `b` as floating-point numbers: +/// Compare the two floats, allowing for $ulp many ULPs of error. /// -/// Instead of performing a simple EPSILON check (which we used at first): -/// The absolute difference between 'a' and 'b' must not be greater than some E (10^-6, ...) -/// -/// We will now use ULP: `Units in the Last Place` or `Units of Least Precision`, -/// more specific, the difference in ULP of `a` and `b`. -/// First: The ULP of a float 'a' is the smallest possible change at 'a', so the ULP difference represents how -/// many discrete floating-point steps are needed to reach 'b' from 'a'. -/// -/// ULP(a) is the distance between the 2 closest floating-point numbers `x` and `y` around `a`, satisfying x < a < y, x != y. -/// To use this to calculate the ULP difference we have to halve it (we need it at `a`, but we just went "up" and "down", halving it gives us this ULP). -/// Then take the difference of `b` and `a` and divide it by that ULP and finally round it. -/// We know now how many floating-point changes we have to apply to `a` to get to `b`. -/// -/// So if this ULP difference is less than or equal to our chosen upper bound -/// we can say that `a` and `b` are approximately equal, because they lie "close" enough to each other to be considered equal. -/// -/// Note: We can see that checking `a` and `b` with different signs has no meaning, but we should not forget -/// -0.0 and +0.0. +/// ULP means "Units in the Last Place" or "Units of Least Precision". +/// The ULP of a float `a`` is the smallest possible change at `a`, so the ULP difference represents how +/// many discrete floating-point steps are needed to reach the actual value from the expected value. /// /// Essentially ULP can be seen as a distance metric of floating-point numbers, but with /// the same amount of "spacing" between all consecutive representable values. So even though 2 very large floating point numbers /// have a large value difference, their ULP can still be 1, so they are still "approximatly equal", /// but the EPSILON check would have failed. -/// -fn approx_eq_check( - actual: F, - expected: F, - allowed_ulp: F::Int, -) -> Result<(), NotApproxEq> -where - F::Int: PartialOrd, -{ - let actual_signum = actual.signum(); - let expected_signum = expected.signum(); - - if actual_signum != expected_signum { - // Floats with different signs must both be 0. - if actual != expected { - return Err(NotApproxEq::SignsDiffer); - } - } else { - let ulp = (expected.next_up() - expected.next_down()).halve(); - let ulp_diff = ((actual - expected) / ulp).round().as_int(); - - if ulp_diff > allowed_ulp { - return Err(NotApproxEq::UlpFail(ulp_diff)); - } - } - Ok(()) -} - -/// Give more context to execution and result of [`approx_eq_check`]. -enum NotApproxEq { - SignsDiffer, - - /// Contains the actual ulp value calculated. - UlpFail(F::Int), -} - macro_rules! assert_approx_eq { ($a:expr, $b:expr, $ulp:expr) => {{ - let (a, b) = ($a, $b); - let allowed_ulp = $ulp; - match approx_eq_check(a, b, allowed_ulp) { - Err(NotApproxEq::SignsDiffer) => - panic!("{a:?} is not approximately equal to {b:?}: signs differ"), - Err(NotApproxEq::UlpFail(actual_ulp)) => - panic!("{a:?} is not approximately equal to {b:?}\nulp diff: {actual_ulp} > {allowed_ulp}"), - Ok(_) => {} + let (actual, expected) = ($a, $b); + let allowed_ulp_diff = $ulp; + let _force_same_type = actual == expected; + // Approximate the ULP by taking half the distance between the number one place "up" + // and the number one place "down". + let ulp = (expected.next_up() - expected.next_down()) / 2.0; + let ulp_diff = ((actual - expected) / ulp).abs().round() as i32; + if ulp_diff > allowed_ulp_diff { + panic!("{actual:?} is not approximately equal to {expected:?}\ndifference in ULP: {ulp_diff} > {allowed_ulp_diff}"); }; }}; @@ -101,8 +50,8 @@ fn main() { ops(); nan_casts(); rounding(); - libm(); mul_add(); + libm(); test_fast(); test_algebraic(); test_fmuladd(); @@ -110,14 +59,7 @@ fn main() { test_non_determinism(); } -trait Float: - Copy - + PartialEq - + Debug - + std::ops::Sub - + std::cmp::PartialOrd - + std::ops::Div -{ +trait Float: Copy + PartialEq + Debug { /// The unsigned integer with the same bit width as this float type Int: Copy + PartialEq + LowerHex + Debug; const BITS: u32 = size_of::() as u32 * 8; @@ -131,15 +73,6 @@ trait Float: const EXPONENT_BIAS: u32 = Self::EXPONENT_SAT >> 1; fn to_bits(self) -> Self::Int; - - // to make "approx_eq_check" generic - fn signum(self) -> Self; - fn next_up(self) -> Self; - fn next_down(self) -> Self; - fn round(self) -> Self; - // self / 2 - fn halve(self) -> Self; - fn as_int(self) -> Self::Int; } macro_rules! impl_float { @@ -152,27 +85,6 @@ macro_rules! impl_float { fn to_bits(self) -> Self::Int { self.to_bits() } - - fn signum(self) -> Self { - self.signum() - } - fn next_up(self) -> Self { - self.next_up() - } - fn next_down(self) -> Self { - self.next_down() - } - fn round(self) -> Self { - self.round() - } - - fn halve(self) -> Self { - self / 2.0 - } - - fn as_int(self) -> Self::Int { - self as Self::Int - } } }; } @@ -1117,8 +1029,8 @@ pub fn libm() { #[allow(deprecated)] { - assert_approx_eq!(5.0f32.abs_sub(3.0), 2.0f32); - assert_approx_eq!(3.0f64.abs_sub(5.0), 0.0f64); + assert_approx_eq!(5.0f32.abs_sub(3.0), 2.0); + assert_approx_eq!(3.0f64.abs_sub(5.0), 0.0); } assert_approx_eq!(27.0f32.cbrt(), 3.0f32); @@ -1135,8 +1047,8 @@ pub fn libm() { assert_approx_eq!(0f32.sin(), 0f32); assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64); - assert_approx_eq!(f32::consts::FRAC_PI_6.sin(), 0.5f32); - assert_approx_eq!(f64::consts::FRAC_PI_6.sin(), 0.5f64); + assert_approx_eq!(f32::consts::FRAC_PI_6.sin(), 0.5); + assert_approx_eq!(f64::consts::FRAC_PI_6.sin(), 0.5); assert_approx_eq!(f32::consts::FRAC_PI_4.sin().asin(), f32::consts::FRAC_PI_4); assert_approx_eq!(f64::consts::FRAC_PI_4.sin().asin(), f64::consts::FRAC_PI_4); @@ -1147,8 +1059,8 @@ pub fn libm() { assert_approx_eq!(0f32.cos(), 1f32); assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64); - assert_approx_eq!(f32::consts::FRAC_PI_3.cos(), 0.5f32); - assert_approx_eq!(f64::consts::FRAC_PI_3.cos(), 0.5f64); + assert_approx_eq!(f32::consts::FRAC_PI_3.cos(), 0.5); + assert_approx_eq!(f64::consts::FRAC_PI_3.cos(), 0.5); assert_approx_eq!(f32::consts::FRAC_PI_4.cos().acos(), f32::consts::FRAC_PI_4); assert_approx_eq!(f64::consts::FRAC_PI_4.cos().acos(), f64::consts::FRAC_PI_4); @@ -1175,8 +1087,8 @@ pub fn libm() { assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32); assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64); - assert_approx_eq!(5.0f32.gamma(), 24.0f32); - assert_approx_eq!(5.0f64.gamma(), 24.0f64); + assert_approx_eq!(5.0f32.gamma(), 24.0); + assert_approx_eq!(5.0f64.gamma(), 24.0); assert_approx_eq!((-0.5f32).gamma(), (-2.0) * f32::consts::PI.sqrt()); assert_approx_eq!((-0.5f64).gamma(), (-2.0) * f64::consts::PI.sqrt()); @@ -1424,6 +1336,8 @@ fn test_non_determinism() { ensure_nondet(|| 1.0f32.atan2(2.0f32)); ensure_nondet(|| 0.5f32.atanh()); ensure_nondet(|| 5.0f32.gamma()); + ensure_nondet(|| 5.0f32.erf()); + ensure_nondet(|| 5.0f32.erfc()); } pub fn test_operations_f64(a: f64, b: f64) { test_operations_f!(a, b); @@ -1446,6 +1360,8 @@ fn test_non_determinism() { ensure_nondet(|| 1.0f64.tanh()); ensure_nondet(|| 0.5f64.atanh()); ensure_nondet(|| 5.0f64.gamma()); + ensure_nondet(|| 5.0f64.erf()); + ensure_nondet(|| 5.0f64.erfc()); } pub fn test_operations_f128(a: f128, b: f128) { test_operations_f!(a, b); From 8cf9eea5b3640fc119db11a70107ef09b44a5082 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 3 Feb 2025 10:45:49 +1100 Subject: [PATCH 153/991] Move some `Map` methods onto `TyCtxt`. The end goal is to eliminate `Map` altogether. I added a `hir_` prefix to all of them, that seemed simplest. The exceptions are `module_items` which became `hir_module_free_items` because there was already a `hir_module_items`, and `items` which became `hir_free_items` for consistency with `hir_module_free_items`. --- .../src/arbitrary_source_item_ordering.rs | 2 +- clippy_lints/src/async_yields_async.rs | 4 ++-- clippy_lints/src/attrs/utils.rs | 6 ++--- clippy_lints/src/booleans.rs | 2 +- clippy_lints/src/collection_is_never_read.rs | 2 +- clippy_lints/src/derivable_impls.rs | 2 +- clippy_lints/src/doc/missing_headers.rs | 2 +- clippy_lints/src/doc/mod.rs | 4 ++-- clippy_lints/src/empty_drop.rs | 2 +- clippy_lints/src/eta_reduction.rs | 2 +- .../src/extra_unused_type_parameters.rs | 2 +- clippy_lints/src/fallible_impl_from.rs | 4 ++-- clippy_lints/src/format_impl.rs | 2 +- clippy_lints/src/from_over_into.rs | 4 ++-- .../src/functions/impl_trait_in_params.rs | 2 +- clippy_lints/src/functions/must_use.rs | 6 ++--- .../src/functions/not_unsafe_ptr_arg_deref.rs | 2 +- clippy_lints/src/implicit_hasher.rs | 4 ++-- clippy_lints/src/infinite_iter.rs | 2 +- clippy_lints/src/items_after_statements.rs | 2 +- clippy_lints/src/items_after_test_module.rs | 4 ++-- clippy_lints/src/iter_without_into_iter.rs | 2 +- clippy_lints/src/len_zero.rs | 2 +- clippy_lints/src/lifetimes.rs | 2 +- clippy_lints/src/lines_filter_map_ok.rs | 2 +- clippy_lints/src/loops/needless_range_loop.rs | 2 +- .../src/loops/while_let_on_iterator.rs | 2 +- clippy_lints/src/manual_async_fn.rs | 2 +- clippy_lints/src/manual_option_as_slice.rs | 2 +- clippy_lints/src/manual_retain.rs | 6 ++--- clippy_lints/src/map_unit_fn.rs | 2 +- .../src/methods/bind_instead_of_map.rs | 2 +- clippy_lints/src/methods/bytecount.rs | 2 +- clippy_lints/src/methods/filter_map.rs | 6 ++--- .../src/methods/filter_map_bool_then.rs | 4 ++-- clippy_lints/src/methods/format_collect.rs | 2 +- clippy_lints/src/methods/iter_filter.rs | 2 +- clippy_lints/src/methods/iter_kv_map.rs | 2 +- .../src/methods/iter_overeager_cloned.rs | 2 +- clippy_lints/src/methods/manual_inspect.rs | 4 ++-- clippy_lints/src/methods/manual_ok_or.rs | 2 +- clippy_lints/src/methods/map_clone.rs | 2 +- clippy_lints/src/methods/map_err_ignore.rs | 2 +- .../map_with_unused_argument_over_ranges.rs | 2 +- clippy_lints/src/methods/mod.rs | 4 ++-- .../methods/needless_character_iteration.rs | 2 +- clippy_lints/src/methods/needless_collect.rs | 2 +- .../src/methods/obfuscated_if_else.rs | 2 +- .../src/methods/option_as_ref_deref.rs | 2 +- .../src/methods/option_map_or_none.rs | 2 +- clippy_lints/src/methods/or_fun_call.rs | 2 +- .../src/methods/result_map_or_else_none.rs | 2 +- clippy_lints/src/methods/return_and_then.rs | 2 +- clippy_lints/src/methods/search_is_some.rs | 2 +- clippy_lints/src/methods/suspicious_map.rs | 2 +- .../src/methods/unnecessary_filter_map.rs | 2 +- clippy_lints/src/methods/unnecessary_fold.rs | 2 +- .../src/methods/unnecessary_lazy_eval.rs | 2 +- .../src/methods/unnecessary_literal_unwrap.rs | 2 +- .../src/methods/unnecessary_map_or.rs | 2 +- .../methods/unnecessary_result_map_or_else.rs | 2 +- .../src/methods/unnecessary_sort_by.rs | 2 +- .../src/methods/unnecessary_to_owned.rs | 2 +- .../src/methods/unused_enumerate_index.rs | 2 +- clippy_lints/src/methods/useless_asref.rs | 2 +- clippy_lints/src/missing_fields_in_debug.rs | 4 ++-- clippy_lints/src/missing_inline.rs | 4 ++-- clippy_lints/src/needless_for_each.rs | 2 +- clippy_lints/src/needless_pass_by_ref_mut.rs | 3 +-- clippy_lints/src/new_without_default.rs | 2 +- clippy_lints/src/non_canonical_impls.rs | 4 ++-- clippy_lints/src/non_std_lazy_statics.rs | 2 +- clippy_lints/src/pass_by_ref_or_value.rs | 2 +- clippy_lints/src/redundant_async_block.rs | 2 +- clippy_lints/src/redundant_closure_call.rs | 4 ++-- clippy_lints/src/returns.rs | 2 +- clippy_lints/src/same_name_method.rs | 4 ++-- clippy_lints/src/string_patterns.rs | 2 +- clippy_lints/src/suspicious_trait_impl.rs | 2 +- clippy_lints/src/trait_bounds.rs | 2 +- clippy_lints/src/types/borrowed_box.rs | 4 ++-- clippy_lints/src/unconditional_recursion.rs | 4 ++-- .../src/undocumented_unsafe_blocks.rs | 6 ++--- clippy_lints/src/unit_return_expecting_ord.rs | 2 +- clippy_lints/src/unit_types/let_unit_value.rs | 2 +- clippy_lints/src/unused_self.rs | 2 +- clippy_lints/src/unwrap_in_result.rs | 2 +- clippy_lints/src/utils/author.rs | 4 ++-- .../utils/internal_lints/collapsible_calls.rs | 2 +- .../src/utils/internal_lints/invalid_paths.rs | 2 +- .../internal_lints/lint_without_lint_pass.rs | 2 +- clippy_lints/src/zero_repeat_side_effects.rs | 3 +-- clippy_utils/src/check_proc_macro.rs | 2 +- clippy_utils/src/consts.rs | 8 +++---- clippy_utils/src/hir_utils.rs | 8 +++---- clippy_utils/src/lib.rs | 22 +++++++++---------- clippy_utils/src/ptr.rs | 2 +- clippy_utils/src/sugg.rs | 2 +- clippy_utils/src/visitors.rs | 4 ++-- tests/ui/author/blocks.stdout | 4 ++-- tests/ui/author/macro_in_closure.stdout | 2 +- tests/ui/author/repeat.stdout | 2 +- 102 files changed, 146 insertions(+), 150 deletions(-) diff --git a/clippy_lints/src/arbitrary_source_item_ordering.rs b/clippy_lints/src/arbitrary_source_item_ordering.rs index f519a65fc272..aff40fa846be 100644 --- a/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -338,7 +338,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { return; } - let items = module.item_ids.iter().map(|&id| cx.tcx.hir().item(id)); + let items = module.item_ids.iter().map(|&id| cx.tcx.hir_item(id)); // Iterates over the items within a module. // diff --git a/clippy_lints/src/async_yields_async.rs b/clippy_lints/src/async_yields_async.rs index eeaa3de3725f..013819b0da8a 100644 --- a/clippy_lints/src/async_yields_async.rs +++ b/clippy_lints/src/async_yields_async.rs @@ -60,12 +60,12 @@ impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync { // XXXkhuey maybe we should? return; }, - CoroutineSource::Block => cx.tcx.hir().body(*body_id).value, + CoroutineSource::Block => cx.tcx.hir_body(*body_id).value, CoroutineSource::Closure => { // Like `async fn`, async closures are wrapped in an additional block // to move all of the closure's arguments into the future. - let async_closure_body = cx.tcx.hir().body(*body_id).value; + let async_closure_body = cx.tcx.hir_body(*body_id).value; let ExprKind::Block(block, _) = async_closure_body.kind else { return; }; diff --git a/clippy_lints/src/attrs/utils.rs b/clippy_lints/src/attrs/utils.rs index 152e6ec70a18..a667649f7343 100644 --- a/clippy_lints/src/attrs/utils.rs +++ b/clippy_lints/src/attrs/utils.rs @@ -22,7 +22,7 @@ pub(super) fn is_lint_level(symbol: Symbol, attr_id: AttrId) -> bool { pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool { if let ItemKind::Fn { body: eid, .. } = item.kind { - is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value) + is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value) } else { true } @@ -30,7 +30,7 @@ pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool { pub(super) fn is_relevant_impl(cx: &LateContext<'_>, item: &ImplItem<'_>) -> bool { match item.kind { - ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value), + ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value), _ => false, } } @@ -39,7 +39,7 @@ pub(super) fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> b match item.kind { TraitItemKind::Fn(_, TraitFn::Required(_)) => true, TraitItemKind::Fn(_, TraitFn::Provided(eid)) => { - is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value) + is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value) }, _ => false, } diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index f8c30d1c881d..f30f16997d76 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -452,7 +452,7 @@ fn simplify_not(cx: &LateContext<'_>, curr_msrv: &Msrv, expr: &Expr<'_>) -> Opti }) }, ExprKind::Closure(closure) => { - let body = cx.tcx.hir().body(closure.body); + let body = cx.tcx.hir_body(closure.body); let params = body .params .iter() diff --git a/clippy_lints/src/collection_is_never_read.rs b/clippy_lints/src/collection_is_never_read.rs index 8276e53648c0..1279be34ed8f 100644 --- a/clippy_lints/src/collection_is_never_read.rs +++ b/clippy_lints/src/collection_is_never_read.rs @@ -118,7 +118,7 @@ fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirI let is_read_in_closure_arg = args.iter().any(|arg| { if let ExprKind::Closure(closure) = arg.kind // To keep things simple, we only check the first param to see if its read. - && let Body { params: [param, ..], value } = cx.tcx.hir().body(closure.body) + && let Body { params: [param, ..], value } = cx.tcx.hir_body(closure.body) { !has_no_read_access(cx, param.hir_id, *value) } else { diff --git a/clippy_lints/src/derivable_impls.rs b/clippy_lints/src/derivable_impls.rs index 9569081ad088..bb445e0155f6 100644 --- a/clippy_lints/src/derivable_impls.rs +++ b/clippy_lints/src/derivable_impls.rs @@ -197,7 +197,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && let impl_item_hir = child.id.hir_id() && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind - && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b) + && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() && let attrs = cx.tcx.hir().attrs(item.hir_id()) && !attrs.iter().any(|attr| attr.doc_str().is_some()) diff --git a/clippy_lints/src/doc/missing_headers.rs b/clippy_lints/src/doc/missing_headers.rs index 8e2af6bf14a6..d1ffbb6ffe25 100644 --- a/clippy_lints/src/doc/missing_headers.rs +++ b/clippy_lints/src/doc/missing_headers.rs @@ -68,7 +68,7 @@ pub fn check( } else if let Some(body_id) = body_id && let Some(future) = cx.tcx.lang_items().future_trait() && let typeck = cx.tcx.typeck_body(body_id) - && let body = cx.tcx.hir().body(body_id) + && let body = cx.tcx.hir_body(body_id) && let ret_ty = typeck.expr_ty(body.value) && implements_trait_with_env( cx.tcx, diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 42e1f7fd950d..36baf492a540 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -597,7 +597,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation { if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || item.span.in_external_macro(cx.tcx.sess.source_map())) { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let panic_info = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value); missing_headers::check( @@ -649,7 +649,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation { && !impl_item.span.in_external_macro(cx.tcx.sess.source_map()) && !is_trait_impl_item(cx, impl_item.hir_id()) { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(impl_item.owner_id), body.value); missing_headers::check( diff --git a/clippy_lints/src/empty_drop.rs b/clippy_lints/src/empty_drop.rs index 10a84b1b2ff2..d557a36c7ac2 100644 --- a/clippy_lints/src/empty_drop.rs +++ b/clippy_lints/src/empty_drop.rs @@ -44,7 +44,7 @@ impl LateLintPass<'_> for EmptyDrop { && let impl_item_hir = child.id.hir_id() && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind - && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b) + && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) && let func_expr = peel_blocks(func_expr) && let ExprKind::Block(block, _) = func_expr.kind && block.stmts.is_empty() diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index ae3acc1c4b19..d1782d582f4d 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -97,7 +97,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx && matches!(c.fn_decl.output, FnRetTy::DefaultReturn(_)) && !expr.span.from_expansion() { - cx.tcx.hir().body(c.body) + cx.tcx.hir_body(c.body) } else { return; }; diff --git a/clippy_lints/src/extra_unused_type_parameters.rs b/clippy_lints/src/extra_unused_type_parameters.rs index 5d93aceb33ff..6ccea22e191c 100644 --- a/clippy_lints/src/extra_unused_type_parameters.rs +++ b/clippy_lints/src/extra_unused_type_parameters.rs @@ -247,7 +247,7 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> { } fn is_empty_body(cx: &LateContext<'_>, body: BodyId) -> bool { - matches!(cx.tcx.hir().body(body).value.kind, ExprKind::Block(b, _) if b.stmts.is_empty() && b.expr.is_none()) + matches!(cx.tcx.hir_body(body).value.kind, ExprKind::Block(b, _) if b.stmts.is_empty() && b.expr.is_none()) } impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters { diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index f822432cce63..f67d38d932b9 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -98,10 +98,10 @@ fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::Impl for impl_item in impl_items { if impl_item.ident.name == sym::from - && let ImplItemKind::Fn(_, body_id) = cx.tcx.hir().impl_item(impl_item.id).kind + && let ImplItemKind::Fn(_, body_id) = cx.tcx.hir_impl_item(impl_item.id).kind { // check the body for `begin_panic` or `unwrap` - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let mut fpu = FindPanicUnwrap { lcx: cx, typeck_results: cx.tcx.typeck(impl_item.id.owner_id.def_id), diff --git a/clippy_lints/src/format_impl.rs b/clippy_lints/src/format_impl.rs index 5619cb0ab1b0..ff75fcf2b417 100644 --- a/clippy_lints/src/format_impl.rs +++ b/clippy_lints/src/format_impl.rs @@ -262,7 +262,7 @@ fn is_format_trait_impl(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) -> Optio && let Some(name) = cx.tcx.get_diagnostic_name(did) && matches!(name, sym::Debug | sym::Display) { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let formatter_name = body .params .get(1) diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs index 9a73d0c0993f..167377972db9 100644 --- a/clippy_lints/src/from_over_into.rs +++ b/clippy_lints/src/from_over_into.rs @@ -175,11 +175,11 @@ fn convert_to_from( // bad suggestion/fix. return None; } - let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id); + let impl_item = cx.tcx.hir_impl_item(impl_item_ref.id); let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else { return None; }; - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let [input] = body.params else { return None }; let PatKind::Binding(.., self_ident, None) = input.pat.kind else { return None; diff --git a/clippy_lints/src/functions/impl_trait_in_params.rs b/clippy_lints/src/functions/impl_trait_in_params.rs index 752dbc0db4db..6d1c55d06938 100644 --- a/clippy_lints/src/functions/impl_trait_in_params.rs +++ b/clippy_lints/src/functions/impl_trait_in_params.rs @@ -56,7 +56,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { && let hir::ItemKind::Impl(impl_) = item.kind && let hir::Impl { of_trait, .. } = *impl_ && of_trait.is_none() - && let body = cx.tcx.hir().body(body_id) + && let body = cx.tcx.hir_body(body_id) && cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() && !is_in_test(cx.tcx, impl_item.hir_id()) { diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index e480805cac2f..e6e3ea59a9f6 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -37,7 +37,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_> check_must_use_candidate( cx, sig.decl, - cx.tcx.hir().body(*body_id), + cx.tcx.hir_body(*body_id), item.span, item.owner_id, item.span.with_hi(sig.decl.output.span().hi()), @@ -59,7 +59,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp check_must_use_candidate( cx, sig.decl, - cx.tcx.hir().body(*body_id), + cx.tcx.hir_body(*body_id), item.span, item.owner_id, item.span.with_hi(sig.decl.output.span().hi()), @@ -79,7 +79,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); } else if let hir::TraitFn::Provided(eid) = *eid { - let body = cx.tcx.hir().body(eid); + let body = cx.tcx.hir_body(eid); if attr.is_none() && is_public && !is_proc_macro(attrs) { check_must_use_candidate( cx, diff --git a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs index 8a74951ef63e..906bbd006d46 100644 --- a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs +++ b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs @@ -30,7 +30,7 @@ pub(super) fn check_fn<'tcx>( pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) { if let hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(eid)) = item.kind { - let body = cx.tcx.hir().body(eid); + let body = cx.tcx.hir_body(eid); check_raw_ptr(cx, sig.header.safety(), sig.decl, body, item.owner_id.def_id); } } diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 47a5c19215b8..1b39663f4f81 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { }); let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target); - for item in impl_.items.iter().map(|item| cx.tcx.hir().impl_item(item.id)) { + for item in impl_.items.iter().map(|item| cx.tcx.hir_impl_item(item.id)) { ctr_vis.visit_impl_item(item); } @@ -154,7 +154,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { body: body_id, .. } => { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); for ty in sig.decl.inputs { let mut vis = ImplicitHasherTypeVisitor::new(cx); diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index d3aade31f14f..3cb47d8ef919 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -159,7 +159,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { } if method.ident.name.as_str() == "flat_map" && args.len() == 1 { if let ExprKind::Closure(&Closure { body, .. }) = args[0].kind { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); return is_infinite(cx, body.value); } } diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs index f5ad79a00279..021d43cefdda 100644 --- a/clippy_lints/src/items_after_statements.rs +++ b/clippy_lints/src/items_after_statements.rs @@ -59,7 +59,7 @@ impl LateLintPass<'_> for ItemsAfterStatements { .iter() .skip_while(|stmt| matches!(stmt.kind, StmtKind::Item(..))) .filter_map(|stmt| match stmt.kind { - StmtKind::Item(id) => Some(cx.tcx.hir().item(id)), + StmtKind::Item(id) => Some(cx.tcx.hir_item(id)), _ => None, }) // Ignore macros since they can only see previously defined locals. diff --git a/clippy_lints/src/items_after_test_module.rs b/clippy_lints/src/items_after_test_module.rs index 1ac549b74ac6..9df044f25eb7 100644 --- a/clippy_lints/src/items_after_test_module.rs +++ b/clippy_lints/src/items_after_test_module.rs @@ -58,7 +58,7 @@ fn cfg_test_module<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool { impl LateLintPass<'_> for ItemsAfterTestModule { fn check_mod(&mut self, cx: &LateContext<'_>, module: &Mod<'_>, _: HirId) { - let mut items = module.item_ids.iter().map(|&id| cx.tcx.hir().item(id)); + let mut items = module.item_ids.iter().map(|&id| cx.tcx.hir_item(id)); let Some((mod_pos, test_mod)) = items.by_ref().enumerate().find(|(_, item)| cfg_test_module(cx, item)) else { return; @@ -91,7 +91,7 @@ impl LateLintPass<'_> for ItemsAfterTestModule { "items after a test module", |diag| { if let Some(prev) = mod_pos.checked_sub(1) - && let prev = cx.tcx.hir().item(module.item_ids[prev]) + && let prev = cx.tcx.hir_item(module.item_ids[prev]) && let items_span = last.span.with_lo(test_mod.span.hi()) && let Some(items) = items_span.get_source_text(cx) { diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs index 238f66d66755..173232c511a5 100644 --- a/clippy_lints/src/iter_without_into_iter.rs +++ b/clippy_lints/src/iter_without_into_iter.rs @@ -142,7 +142,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter { }) && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| { if item.ident.name.as_str() == "IntoIter" { - Some(cx.tcx.hir().impl_item(item.id).expect_type().span) + Some(cx.tcx.hir_impl_item(item.id).expect_type().span) } else { None } diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 26bea8d633a3..98ba52f12707 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -316,7 +316,7 @@ enum LenOutput { fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { if let ty::Alias(_, alias_ty) = ty.kind() - && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id) + && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(alias_ty.def_id) && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin && let [GenericBound::Trait(trait_ref)] = &opaque.bounds && let Some(segment) = trait_ref.trait_ref.path.segments.last() diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 860c0584accf..8eb45109d68c 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -275,7 +275,7 @@ fn could_use_elision<'tcx>( } if let Some(body_id) = body { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let first_ident = body.params.first().and_then(|param| param.pat.simple_ident()); if non_elidable_self_type(cx, func, first_ident, msrv) { diff --git a/clippy_lints/src/lines_filter_map_ok.rs b/clippy_lints/src/lines_filter_map_ok.rs index 8206c75927b7..f022598651b7 100644 --- a/clippy_lints/src/lines_filter_map_ok.rs +++ b/clippy_lints/src/lines_filter_map_ok.rs @@ -101,7 +101,7 @@ fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> boo ExprKind::Closure(Closure { body, .. }) => { if let Body { params: [param], value, .. - } = cx.tcx.hir().body(*body) + } = cx.tcx.hir_body(*body) && let ExprKind::MethodCall(method, receiver, [], _) = value.kind && path_to_local_id(receiver, param.pat.hir_id) && let Some(method_did) = cx.typeck_results().type_dependent_def_id(value.hir_id) diff --git a/clippy_lints/src/loops/needless_range_loop.rs b/clippy_lints/src/loops/needless_range_loop.rs index 2e6442156ef6..e98c3c9698ba 100644 --- a/clippy_lints/src/loops/needless_range_loop.rs +++ b/clippy_lints/src/loops/needless_range_loop.rs @@ -370,7 +370,7 @@ impl<'tcx> Visitor<'tcx> for VarVisitor<'_, 'tcx> { } }, ExprKind::Closure(&Closure { body, .. }) => { - let body = self.cx.tcx.hir().body(body); + let body = self.cx.tcx.hir_body(body); self.visit_expr(body.value); }, _ => walk_expr(self, expr), diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs index b7e37c1a876f..e31b474c83f6 100644 --- a/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/clippy_lints/src/loops/while_let_on_iterator.rs @@ -351,7 +351,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: & loop_id: loop_expr.hir_id, after_loop: false, }; - v.visit_expr(cx.tcx.hir().body(cx.enclosing_body.unwrap()).value) + v.visit_expr(cx.tcx.hir_body(cx.enclosing_body.unwrap()).value) .is_break() } } diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs index 9f3b0957eab1..6f3a7d8cccc8 100644 --- a/clippy_lints/src/manual_async_fn.rs +++ b/clippy_lints/src/manual_async_fn.rs @@ -168,7 +168,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Block)) = kind { - return Some(cx.tcx.hir().body(body)); + return Some(cx.tcx.hir_body(body)); } None diff --git a/clippy_lints/src/manual_option_as_slice.rs b/clippy_lints/src/manual_option_as_slice.rs index 5c40c945c690..e4360518b66e 100644 --- a/clippy_lints/src/manual_option_as_slice.rs +++ b/clippy_lints/src/manual_option_as_slice.rs @@ -191,7 +191,7 @@ fn check_arms(cx: &LateContext<'_>, none_arm: &Arm<'_>, some_arm: &Arm<'_>) -> b fn returns_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { match expr.kind { ExprKind::Path(_) => clippy_utils::is_path_diagnostic_item(cx, expr, sym::default_fn), - ExprKind::Closure(cl) => is_empty_slice(cx, cx.tcx.hir().body(cl.body).value), + ExprKind::Closure(cl) => is_empty_slice(cx, cx.tcx.hir_body(cl.body).value), _ => false, } } diff --git a/clippy_lints/src/manual_retain.rs b/clippy_lints/src/manual_retain.rs index 708980ac503d..0a4e756096e9 100644 --- a/clippy_lints/src/manual_retain.rs +++ b/clippy_lints/src/manual_retain.rs @@ -92,7 +92,7 @@ fn check_into_iter( && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = target_expr.kind && let hir::ExprKind::Closure(closure) = closure_expr.kind - && let filter_body = cx.tcx.hir().body(closure.body) + && let filter_body = cx.tcx.hir_body(closure.body) && let [filter_params] = filter_body.params { if match_map_type(cx, left_expr) { @@ -139,7 +139,7 @@ fn check_iter( && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind && let hir::ExprKind::Closure(closure) = closure_expr.kind - && let filter_body = cx.tcx.hir().body(closure.body) + && let filter_body = cx.tcx.hir_body(closure.body) && let [filter_params] = filter_body.params { match filter_params.pat.kind { @@ -198,7 +198,7 @@ fn check_to_owned( && SpanlessEq::new(cx).eq_expr(left_expr, str_expr) && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind && let hir::ExprKind::Closure(closure) = closure_expr.kind - && let filter_body = cx.tcx.hir().body(closure.body) + && let filter_body = cx.tcx.hir_body(closure.body) && let [filter_params] = filter_body.params { if let hir::PatKind::Ref(pat, _) = filter_params.pat.kind { diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index 3221a04d2d03..56aead85e7c4 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -163,7 +163,7 @@ fn unit_closure<'tcx>( expr: &hir::Expr<'_>, ) -> Option<(&'tcx hir::Param<'tcx>, &'tcx hir::Expr<'tcx>)> { if let hir::ExprKind::Closure(&hir::Closure { fn_decl, body, .. }) = expr.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let body_expr = &body.value && fn_decl.inputs.len() == 1 && is_unit_expression(cx, body_expr) diff --git a/clippy_lints/src/methods/bind_instead_of_map.rs b/clippy_lints/src/methods/bind_instead_of_map.rs index 91a5de16e967..1e9b29f567f4 100644 --- a/clippy_lints/src/methods/bind_instead_of_map.rs +++ b/clippy_lints/src/methods/bind_instead_of_map.rs @@ -163,7 +163,7 @@ impl BindInsteadOfMap { match arg.kind { hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) => { - let closure_body = cx.tcx.hir().body(body); + let closure_body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(closure_body.value); if self.lint_closure_autofixable(cx, expr, recv, closure_expr, fn_decl_span) { diff --git a/clippy_lints/src/methods/bytecount.rs b/clippy_lints/src/methods/bytecount.rs index 687272e550bb..0498f317442a 100644 --- a/clippy_lints/src/methods/bytecount.rs +++ b/clippy_lints/src/methods/bytecount.rs @@ -18,7 +18,7 @@ pub(super) fn check<'tcx>( filter_arg: &'tcx Expr<'_>, ) { if let ExprKind::Closure(&Closure { body, .. }) = filter_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let [param] = body.params && let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind && let ExprKind::Binary(ref op, l, r) = body.value.kind diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs index c1653b65e982..5b9df6c2bfdd 100644 --- a/clippy_lints/src/methods/filter_map.rs +++ b/clippy_lints/src/methods/filter_map.rs @@ -22,7 +22,7 @@ fn is_method(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol) -> bool ExprKind::Path(QPath::Resolved(_, segments)) => segments.segments.last().unwrap().ident.name == method_name, ExprKind::MethodCall(segment, _, _, _) => segment.ident.name == method_name, ExprKind::Closure(Closure { body, .. }) => { - let body = cx.tcx.hir().body(*body); + let body = cx.tcx.hir_body(*body); let closure_expr = peel_blocks(body.value); match closure_expr.kind { ExprKind::MethodCall(PathSegment { ident, .. }, receiver, ..) => { @@ -404,7 +404,7 @@ fn is_find_or_filter<'a>( if is_trait_method(cx, map_recv, sym::Iterator) // filter(|x| ...is_some())... && let ExprKind::Closure(&Closure { body: filter_body_id, .. }) = filter_arg.kind - && let filter_body = cx.tcx.hir().body(filter_body_id) + && let filter_body = cx.tcx.hir_body(filter_body_id) && let [filter_param] = filter_body.params // optional ref pattern: `filter(|&x| ..)` && let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _) = filter_param.pat.kind { @@ -417,7 +417,7 @@ fn is_find_or_filter<'a>( && let Some(mut offending_expr) = OffendingFilterExpr::hir(cx, filter_body.value, filter_param_id) && let ExprKind::Closure(&Closure { body: map_body_id, .. }) = map_arg.kind - && let map_body = cx.tcx.hir().body(map_body_id) + && let map_body = cx.tcx.hir_body(map_body_id) && let [map_param] = map_body.params && let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind diff --git a/clippy_lints/src/methods/filter_map_bool_then.rs b/clippy_lints/src/methods/filter_map_bool_then.rs index d550c1454668..f7e116c5310e 100644 --- a/clippy_lints/src/methods/filter_map_bool_then.rs +++ b/clippy_lints/src/methods/filter_map_bool_then.rs @@ -14,7 +14,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: & if !expr.span.in_external_macro(cx.sess().source_map()) && is_trait_method(cx, expr, sym::Iterator) && let ExprKind::Closure(closure) = arg.kind - && let body = cx.tcx.hir().body(closure.body) + && let body = cx.tcx.hir_body(closure.body) && let value = peel_blocks(body.value) // Indexing should be fine as `filter_map` always has 1 input, we unfortunately need both // `inputs` and `params` here as we need both the type and the span @@ -31,7 +31,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: & && is_copy(cx, param_ty) && let ExprKind::MethodCall(_, recv, [then_arg], _) = value.kind && let ExprKind::Closure(then_closure) = then_arg.kind - && let then_body = peel_blocks(cx.tcx.hir().body(then_closure.body).value) + && let then_body = peel_blocks(cx.tcx.hir_body(then_closure.body).value) && let Some(def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id) && cx.tcx.is_diagnostic_item(sym::bool_then, def_id) && !is_from_proc_macro(cx, expr) diff --git a/clippy_lints/src/methods/format_collect.rs b/clippy_lints/src/methods/format_collect.rs index 3e5162ef4580..1b28596d50da 100644 --- a/clippy_lints/src/methods/format_collect.rs +++ b/clippy_lints/src/methods/format_collect.rs @@ -19,7 +19,7 @@ fn peel_non_expn_blocks<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx> pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, map_arg: &Expr<'_>, map_span: Span) { if is_type_lang_item(cx, cx.typeck_results().expr_ty(expr), LangItem::String) && let ExprKind::Closure(closure) = map_arg.kind - && let body = cx.tcx.hir().body(closure.body) + && let body = cx.tcx.hir_body(closure.body) && let Some(value) = peel_non_expn_blocks(body.value) && let Some(mac) = root_macro_call_first_node(cx, value) && is_format_macro(cx, mac.def_id) diff --git a/clippy_lints/src/methods/iter_filter.rs b/clippy_lints/src/methods/iter_filter.rs index 30387ba62a73..76a0c0061e52 100644 --- a/clippy_lints/src/methods/iter_filter.rs +++ b/clippy_lints/src/methods/iter_filter.rs @@ -95,7 +95,7 @@ fn is_method( false }, ExprKind::Closure(&hir::Closure { body, .. }) => { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(body.value); let params = body.params.iter().map(|param| param.pat).collect::>(); is_method(cx, closure_expr, type_symbol, method_name, params.as_slice()) diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index 299f6d101123..518041177e92 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>( && let Body { params: [p], value: body_expr, - } = cx.tcx.hir().body(c.body) + } = cx.tcx.hir_body(c.body) && let PatKind::Tuple([key_pat, val_pat], _) = p.pat.kind && let (replacement_kind, annotation, bound_ident) = match (&key_pat.kind, &val_pat.kind) { (key, PatKind::Binding(ann, _, value, _)) if pat_is_wild(cx, key, m_arg) => ("value", ann, value), diff --git a/clippy_lints/src/methods/iter_overeager_cloned.rs b/clippy_lints/src/methods/iter_overeager_cloned.rs index 5ccb5243e903..a80977459f21 100644 --- a/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -62,7 +62,7 @@ pub(super) fn check<'tcx>( let ExprKind::Closure(closure) = expr.kind else { return; }; - let body @ Body { params: [p], .. } = cx.tcx.hir().body(closure.body) else { + let body @ Body { params: [p], .. } = cx.tcx.hir_body(closure.body) else { return; }; let mut delegate = MoveDelegate { diff --git a/clippy_lints/src/methods/manual_inspect.rs b/clippy_lints/src/methods/manual_inspect.rs index 20e4d233525a..de37df2394d3 100644 --- a/clippy_lints/src/methods/manual_inspect.rs +++ b/clippy_lints/src/methods/manual_inspect.rs @@ -22,7 +22,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: && (is_diag_trait_item(cx, fn_id, sym::Iterator) || (msrv.meets(msrvs::OPTION_RESULT_INSPECT) && (is_diag_item_method(cx, fn_id, sym::Option) || is_diag_item_method(cx, fn_id, sym::Result)))) - && let body = cx.tcx.hir().body(c.body) + && let body = cx.tcx.hir_body(c.body) && let [param] = body.params && let PatKind::Binding(BindingMode(ByRef::No, Mutability::Not), arg_id, _, None) = param.pat.kind && let arg_ty = typeck.node_type(arg_id) @@ -45,7 +45,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: let can_lint = for_each_expr_without_closures(block.stmts, |e| { if let ExprKind::Closure(c) = e.kind { // Nested closures don't need to treat returns specially. - let _: Option = for_each_expr(cx, cx.tcx.hir().body(c.body).value, |e| { + let _: Option = for_each_expr(cx, cx.tcx.hir_body(c.body).value, |e| { if path_to_local_id(e, arg_id) { let (kind, same_ctxt) = check_use(cx, e); match (kind, same_ctxt && e.span.ctxt() == ctxt) { diff --git a/clippy_lints/src/methods/manual_ok_or.rs b/clippy_lints/src/methods/manual_ok_or.rs index 4321dd6b0e09..8265c93bfe9f 100644 --- a/clippy_lints/src/methods/manual_ok_or.rs +++ b/clippy_lints/src/methods/manual_ok_or.rs @@ -44,7 +44,7 @@ fn is_ok_wrapping(cx: &LateContext<'_>, map_expr: &Expr<'_>) -> bool { match map_expr.kind { ExprKind::Path(ref qpath) if is_res_lang_ctor(cx, cx.qpath_res(qpath, map_expr.hir_id), ResultOk) => true, ExprKind::Closure(closure) => { - let body = cx.tcx.hir().body(closure.body); + let body = cx.tcx.hir_body(closure.body); if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind && let ExprKind::Call(callee, [ok_arg]) = body.value.kind && is_res_lang_ctor(cx, path_res(cx, callee), ResultOk) diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs index 1252f7ccd357..b2705e1ffc2d 100644 --- a/clippy_lints/src/methods/map_clone.rs +++ b/clippy_lints/src/methods/map_clone.rs @@ -47,7 +47,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_ { match arg.kind { hir::ExprKind::Closure(&hir::Closure { body, .. }) => { - let closure_body = cx.tcx.hir().body(body); + let closure_body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(closure_body.value); match closure_body.params[0].pat.kind { hir::PatKind::Ref(inner, Mutability::Not) => { diff --git a/clippy_lints/src/methods/map_err_ignore.rs b/clippy_lints/src/methods/map_err_ignore.rs index 162f0ac564d7..5d0d4dae35fa 100644 --- a/clippy_lints/src/methods/map_err_ignore.rs +++ b/clippy_lints/src/methods/map_err_ignore.rs @@ -16,7 +16,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) { fn_decl_span, .. }) = arg.kind - && let closure_body = cx.tcx.hir().body(body) + && let closure_body = cx.tcx.hir_body(body) && let [param] = closure_body.params && let PatKind::Wild = param.pat.kind { diff --git a/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs b/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs index 78656ace831d..35dd7c082c90 100644 --- a/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs +++ b/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs @@ -68,7 +68,7 @@ pub(super) fn check( let mut applicability = Applicability::MaybeIncorrect; if let Some(range) = higher::Range::hir(receiver) && let ExprKind::Closure(Closure { body, .. }) = arg.kind - && let body_hir = cx.tcx.hir().body(*body) + && let body_hir = cx.tcx.hir_body(*body) && let Body { params: [param], value: body_expr, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 0a8eafad0e84..ccc5cd4fa417 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -4716,7 +4716,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if sig.decl.implicit_self.has_implicit_self() && !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id)) - && let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir().body(id)).next() + && let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir_body(id)).next() && let Some(first_arg_ty) = first_arg_ty_opt { wrong_self_convention::check( @@ -4852,7 +4852,7 @@ impl Methods { ), Some(("chars", recv, _, _, _)) if let ExprKind::Closure(arg) = arg.kind - && let body = cx.tcx.hir().body(arg.body) + && let body = cx.tcx.hir_body(arg.body) && let [param] = body.params => { string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), &self.msrv); diff --git a/clippy_lints/src/methods/needless_character_iteration.rs b/clippy_lints/src/methods/needless_character_iteration.rs index 6993150fb57a..743aacf05885 100644 --- a/clippy_lints/src/methods/needless_character_iteration.rs +++ b/clippy_lints/src/methods/needless_character_iteration.rs @@ -99,7 +99,7 @@ fn handle_expr( pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>, closure_arg: &Expr<'_>, is_all: bool) { if let ExprKind::Closure(&Closure { body, .. }) = closure_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let Some(first_param) = body.params.first() && let ExprKind::MethodCall(method, mut recv, [], _) = recv.kind && method.ident.name.as_str() == "chars" diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 2780c3f8af5c..5664ffba1a0e 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -498,7 +498,7 @@ fn get_captured_ids(cx: &LateContext<'_>, ty: Ty<'_>) -> HirIdSet { } }, ty::Closure(def_id, _) => { - let closure_hir_node = cx.tcx.hir().get_if_local(*def_id).unwrap(); + let closure_hir_node = cx.tcx.hir_get_if_local(*def_id).unwrap(); if let Node::Expr(closure_expr) = closure_hir_node { can_move_expr_to_closure(cx, closure_expr) .unwrap() diff --git a/clippy_lints/src/methods/obfuscated_if_else.rs b/clippy_lints/src/methods/obfuscated_if_else.rs index b71f79f84824..e0905374ddaa 100644 --- a/clippy_lints/src/methods/obfuscated_if_else.rs +++ b/clippy_lints/src/methods/obfuscated_if_else.rs @@ -27,7 +27,7 @@ pub(super) fn check<'tcx>( let if_then = match then_method_name { "then" if let ExprKind::Closure(closure) = then_arg.kind => { - let body = cx.tcx.hir().body(closure.body); + let body = cx.tcx.hir_body(closure.body); snippet_with_applicability(cx, body.value.span, "..", &mut applicability) }, "then_some" => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability), diff --git a/clippy_lints/src/methods/option_as_ref_deref.rs b/clippy_lints/src/methods/option_as_ref_deref.rs index 8d97d1c72a6b..469fcccbe4f6 100644 --- a/clippy_lints/src/methods/option_as_ref_deref.rs +++ b/clippy_lints/src/methods/option_as_ref_deref.rs @@ -54,7 +54,7 @@ pub(super) fn check( }) }, hir::ExprKind::Closure(&hir::Closure { body, .. }) => { - let closure_body = cx.tcx.hir().body(body); + let closure_body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(closure_body.value); match &closure_expr.kind { diff --git a/clippy_lints/src/methods/option_map_or_none.rs b/clippy_lints/src/methods/option_map_or_none.rs index 193deafccf65..1a273f77fb7d 100644 --- a/clippy_lints/src/methods/option_map_or_none.rs +++ b/clippy_lints/src/methods/option_map_or_none.rs @@ -60,7 +60,7 @@ pub(super) fn check<'tcx>( let self_snippet = snippet(cx, recv.span, ".."); if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = map_arg.kind && let arg_snippet = snippet(cx, fn_decl_span, "..") - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let Some((func, [arg_char])) = reduce_unit_expression(body.value) && let Some(id) = path_def_id(cx, func).map(|ctor_id| cx.tcx.parent(ctor_id)) && Some(id) == cx.tcx.lang_items().option_some_variant() diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index 6b39b753885e..f5f404070cab 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -253,7 +253,7 @@ pub(super) fn check<'tcx>( fn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool { if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = e.kind { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); if body.params.is_empty() && let hir::Expr { kind, .. } = &body.value diff --git a/clippy_lints/src/methods/result_map_or_else_none.rs b/clippy_lints/src/methods/result_map_or_else_none.rs index 3b0dc506305b..af619c9e3bb1 100644 --- a/clippy_lints/src/methods/result_map_or_else_none.rs +++ b/clippy_lints/src/methods/result_map_or_else_none.rs @@ -23,7 +23,7 @@ pub(super) fn check<'tcx>( // We check that it is mapped as `Some`. && is_res_lang_ctor(cx, path_res(cx, map_arg), OptionSome) && let hir::ExprKind::Closure(&hir::Closure { body, .. }) = def_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) // And finally we check that we return a `None` in the "else case". && is_res_lang_ctor(cx, path_res(cx, peel_blocks(body.value)), OptionNone) { diff --git a/clippy_lints/src/methods/return_and_then.rs b/clippy_lints/src/methods/return_and_then.rs index 7b1199ad1e2d..68ffa81a2781 100644 --- a/clippy_lints/src/methods/return_and_then.rs +++ b/clippy_lints/src/methods/return_and_then.rs @@ -44,7 +44,7 @@ pub(super) fn check<'tcx>( }; let closure_arg = fn_decl.inputs[0]; - let closure_expr = peel_blocks(cx.tcx.hir().body(body).value); + let closure_expr = peel_blocks(cx.tcx.hir_body(body).value); let mut applicability = Applicability::MachineApplicable; let arg_snip = snippet_with_applicability(cx, closure_arg.span, "_", &mut applicability); diff --git a/clippy_lints/src/methods/search_is_some.rs b/clippy_lints/src/methods/search_is_some.rs index 4ab165a5528b..97c8ce2bcdd2 100644 --- a/clippy_lints/src/methods/search_is_some.rs +++ b/clippy_lints/src/methods/search_is_some.rs @@ -37,7 +37,7 @@ pub(super) fn check<'tcx>( let mut applicability = Applicability::MachineApplicable; let any_search_snippet = if search_method == "find" && let ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind - && let closure_body = cx.tcx.hir().body(body) + && let closure_body = cx.tcx.hir_body(body) && let Some(closure_arg) = closure_body.params.first() { if let PatKind::Ref(..) = closure_arg.pat.kind { diff --git a/clippy_lints/src/methods/suspicious_map.rs b/clippy_lints/src/methods/suspicious_map.rs index ed49233acb7f..1bd48525f12d 100644 --- a/clippy_lints/src/methods/suspicious_map.rs +++ b/clippy_lints/src/methods/suspicious_map.rs @@ -10,7 +10,7 @@ use super::SUSPICIOUS_MAP; pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) { if is_trait_method(cx, count_recv, sym::Iterator) && let hir::ExprKind::Closure(closure) = expr_or_init(cx, map_arg).kind - && let closure_body = cx.tcx.hir().body(closure.body) + && let closure_body = cx.tcx.hir_body(closure.body) && !cx.typeck_results().expr_ty(closure_body.value).is_unit() { if let Some(map_mutated_vars) = mutated_variables(closure_body.value, cx) { diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 5b9e9e70e477..ca42a9ac04e0 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -20,7 +20,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a } if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); let arg_id = body.params[0].pat.hir_id; let mutates_arg = mutated_variables(body.value, cx).is_none_or(|used_mutably| used_mutably.contains(&arg_id)); let (clone_or_copy_needed, _) = clone_or_copy_needed(cx, body.params[0].pat, body.value); diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index e7adf3b43ba5..8e3cc9abe832 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -62,7 +62,7 @@ fn check_fold_with_op( ) { if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = acc.kind // Extract the body of the closure passed to fold - && let closure_body = cx.tcx.hir().body(body) + && let closure_body = cx.tcx.hir_body(body) && let closure_expr = peel_blocks(closure_body.value) // Check if the closure body is of the form `acc some_expr(x)` diff --git a/clippy_lints/src/methods/unnecessary_lazy_eval.rs b/clippy_lints/src/methods/unnecessary_lazy_eval.rs index 7af550fa7c68..9f4080100da2 100644 --- a/clippy_lints/src/methods/unnecessary_lazy_eval.rs +++ b/clippy_lints/src/methods/unnecessary_lazy_eval.rs @@ -25,7 +25,7 @@ pub(super) fn check<'tcx>( if is_option || is_result || is_bool { if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl, .. }) = arg.kind { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); let body_expr = &body.value; if usage::BindingUsageFinder::are_params_used(cx, body) || is_from_proc_macro(cx, expr) { diff --git a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs index 10112b62878a..00690aca6d13 100644 --- a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs +++ b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs @@ -99,7 +99,7 @@ pub(super) fn check( ("None", "unwrap_or_else", _) => match args[0].kind { hir::ExprKind::Closure(hir::Closure { body, .. }) => Some(vec![ ( - expr.span.with_hi(cx.tcx.hir().body(*body).value.span.lo()), + expr.span.with_hi(cx.tcx.hir_body(*body).value.span.lo()), String::new(), ), (expr.span.with_lo(args[0].span.hi()), String::new()), diff --git a/clippy_lints/src/methods/unnecessary_map_or.rs b/clippy_lints/src/methods/unnecessary_map_or.rs index 6dea1506d0e3..5f88a7fd31f2 100644 --- a/clippy_lints/src/methods/unnecessary_map_or.rs +++ b/clippy_lints/src/methods/unnecessary_map_or.rs @@ -63,7 +63,7 @@ pub(super) fn check<'a>( let ext_def_span = def.span.until(map.span); let (sugg, method, applicability) = if let ExprKind::Closure(map_closure) = map.kind - && let closure_body = cx.tcx.hir().body(map_closure.body) + && let closure_body = cx.tcx.hir_body(map_closure.body) && let closure_body_value = closure_body.value.peel_blocks() && let ExprKind::Binary(op, l, r) = closure_body_value.kind && let Some(param) = closure_body.params.first() diff --git a/clippy_lints/src/methods/unnecessary_result_map_or_else.rs b/clippy_lints/src/methods/unnecessary_result_map_or_else.rs index dc50717112d8..f84d0d6dff0a 100644 --- a/clippy_lints/src/methods/unnecessary_result_map_or_else.rs +++ b/clippy_lints/src/methods/unnecessary_result_map_or_else.rs @@ -53,7 +53,7 @@ pub(super) fn check<'tcx>( // lint if the caller of `map_or_else()` is a `Result` if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result) && let ExprKind::Closure(&Closure { body, .. }) = map_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let Some(first_param) = body.params.first() { let body_expr = peel_blocks(body.value); diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs index f0b29213e1e5..fb4984914eb0 100644 --- a/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -117,7 +117,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp && let Some(impl_id) = cx.tcx.impl_of_method(method_id) && cx.tcx.type_of(impl_id).instantiate_identity().is_slice() && let ExprKind::Closure(&Closure { body, .. }) = arg.kind - && let closure_body = cx.tcx.hir().body(body) + && let closure_body = cx.tcx.hir_body(body) && let &[ Param { pat: diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index 7d72310c1c44..e80d99dca56d 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -506,7 +506,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< if has_lifetime(output_ty) && has_lifetime(ty) { return false; } - let body = cx.tcx.hir().body(*body_id); + let body = cx.tcx.hir_body(*body_id); let body_expr = &body.value; let mut count = 0; return find_all_ret_expressions(cx, body_expr, |_| { diff --git a/clippy_lints/src/methods/unused_enumerate_index.rs b/clippy_lints/src/methods/unused_enumerate_index.rs index 0aec26f10111..af466fe091c2 100644 --- a/clippy_lints/src/methods/unused_enumerate_index.rs +++ b/clippy_lints/src/methods/unused_enumerate_index.rs @@ -46,7 +46,7 @@ pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>, && is_trait_method(cx, call_expr, sym::Iterator) // And the map argument is a closure && let ExprKind::Closure(closure) = closure_arg.kind - && let closure_body = cx.tcx.hir().body(closure.body) + && let closure_body = cx.tcx.hir_body(closure.body) // And that closure has one argument ... && let [closure_param] = closure_body.params // .. which is a tuple of 2 elements diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs index 82313257e5c4..19152362fb5f 100644 --- a/clippy_lints/src/methods/useless_asref.rs +++ b/clippy_lints/src/methods/useless_asref.rs @@ -113,7 +113,7 @@ fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { match arg.kind { hir::ExprKind::Closure(&hir::Closure { body, .. }) // If it's a closure, we need to check what is called. - if let closure_body = cx.tcx.hir().body(body) + if let closure_body = cx.tcx.hir_body(body) && let [param] = closure_body.params && let hir::PatKind::Binding(_, local_id, ..) = strip_pat_refs(param.pat).kind => { diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs index e9ec23b1efa6..675989156cad 100644 --- a/clippy_lints/src/missing_fields_in_debug.rs +++ b/clippy_lints/src/missing_fields_in_debug.rs @@ -213,8 +213,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { && !item.span.from_expansion() // find `Debug::fmt` function && let Some(fmt_item) = items.iter().find(|i| i.ident.name == sym::fmt) - && let ImplItem { kind: ImplItemKind::Fn(_, body_id), .. } = cx.tcx.hir().impl_item(fmt_item.id) - && let body = cx.tcx.hir().body(*body_id) + && let ImplItem { kind: ImplItemKind::Fn(_, body_id), .. } = cx.tcx.hir_impl_item(fmt_item.id) + && let body = cx.tcx.hir_body(*body_id) && let ExprKind::Block(block, _) = body.value.kind // inspect `self` && let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs() diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 18385ac92692..fdc0930e957a 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { // note: we need to check if the trait is exported so we can't use // `LateLintPass::check_trait_item` here. for tit in trait_items { - let tit_ = cx.tcx.hir().trait_item(tit.id); + let tit_ = cx.tcx.hir_trait_item(tit.id); match tit_.kind { hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {}, hir::TraitItemKind::Fn(..) => { @@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { // trait method with default body needs inline in case // an impl is not provided let desc = "a default trait method"; - let item = cx.tcx.hir().trait_item(tit.id); + let item = cx.tcx.hir_trait_item(tit.id); let attrs = cx.tcx.hir().attrs(item.hir_id()); check_missing_inline_attrs(cx, attrs, item.span, desc); } diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs index 93e20f37ef8a..90b27f5dbac8 100644 --- a/clippy_lints/src/needless_for_each.rs +++ b/clippy_lints/src/needless_for_each.rs @@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach { // Skip the lint if the body is not block because this is simpler than `for` loop. // e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop. && let ExprKind::Closure(&Closure { body, .. }) = for_each_arg.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) // Skip the lint if the body is not safe, so as not to suggest `for … in … unsafe {}` // and suggesting `for … in … { unsafe { } }` is a little ugly. && let ExprKind::Block(Block { rules: BlockCheckMode::DefaultBlock, .. }, ..) = body.value.kind diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 996251fdf162..6a1dc5e41a07 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -103,7 +103,6 @@ fn check_closures<'tcx>( checked_closures: &mut FxHashSet, closures: FxIndexSet, ) { - let hir = cx.tcx.hir(); for closure in closures { if !checked_closures.insert(closure) { continue; @@ -114,7 +113,7 @@ fn check_closures<'tcx>( .tcx .hir_node_by_def_id(closure) .associated_body() - .map(|(_, body_id)| hir.body(body_id)) + .map(|(_, body_id)| cx.tcx.hir_body(body_id)) { euv::ExprUseVisitor::for_clippy(cx, closure, &mut *ctx) .consume_body(body) diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index cc56df3a23d7..cf407e51f7af 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { { for assoc_item in *items { if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) { - let impl_item = cx.tcx.hir().impl_item(assoc_item.id); + let impl_item = cx.tcx.hir_impl_item(assoc_item.id); if impl_item.span.in_external_macro(cx.sess().source_map()) { return; } diff --git a/clippy_lints/src/non_canonical_impls.rs b/clippy_lints/src/non_canonical_impls.rs index dad1e8a3d6a1..448bb603cf2c 100644 --- a/clippy_lints/src/non_canonical_impls.rs +++ b/clippy_lints/src/non_canonical_impls.rs @@ -121,10 +121,10 @@ impl LateLintPass<'_> for NonCanonicalImpls { if cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) { return; } - let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir().impl_item(impl_item.impl_item_id()).kind else { + let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir_impl_item(impl_item.impl_item_id()).kind else { return; }; - let body = cx.tcx.hir().body(impl_item_id); + let body = cx.tcx.hir_body(impl_item_id); let ExprKind::Block(block, ..) = body.value.kind else { return; }; diff --git a/clippy_lints/src/non_std_lazy_statics.rs b/clippy_lints/src/non_std_lazy_statics.rs index 22116505a1c1..774a182d089f 100644 --- a/clippy_lints/src/non_std_lazy_statics.rs +++ b/clippy_lints/src/non_std_lazy_statics.rs @@ -214,7 +214,7 @@ impl LazyInfo { && state.once_cell_sync_lazy.contains(&path_def_id) { let ty_span_no_args = path_span_without_args(path); - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); // visit body to collect `Lazy::new` calls let mut new_fn_calls = FxIndexMap::default(); diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index 95403403217a..73c31b83b51f 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -136,7 +136,7 @@ impl PassByRefOrValue { } let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); - let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir().body(id)); + let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir_body(id)); // Gather all the lifetimes found in the output type which may affect whether // `TRIVIALLY_COPY_PASS_BY_REF` should be linted. diff --git a/clippy_lints/src/redundant_async_block.rs b/clippy_lints/src/redundant_async_block.rs index 65fd312b3a09..bc5e8fd2c258 100644 --- a/clippy_lints/src/redundant_async_block.rs +++ b/clippy_lints/src/redundant_async_block.rs @@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock { /// any variable by ref. fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { if let ExprKind::Closure(Closure { body, def_id, kind, .. }) = expr.kind - && let body = cx.tcx.hir().body(*body) + && let body = cx.tcx.hir_body(*body) && matches!( kind, ClosureKind::Coroutine(CoroutineKind::Desugared( diff --git a/clippy_lints/src/redundant_closure_call.rs b/clippy_lints/src/redundant_closure_call.rs index 91d023500ca6..54e507655e9c 100644 --- a/clippy_lints/src/redundant_closure_call.rs +++ b/clippy_lints/src/redundant_closure_call.rs @@ -90,7 +90,7 @@ fn find_innermost_closure<'tcx>( let mut data = None; while let ExprKind::Closure(closure) = expr.kind - && let body = cx.tcx.hir().body(closure.body) + && let body = cx.tcx.hir_body(closure.body) && { let mut visitor = ReturnVisitor; !visitor.visit_expr(body.value).is_break() @@ -179,7 +179,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { // Like `async fn`, async closures are wrapped in an additional block // to move all of the closure's arguments into the future. - let async_closure_body = cx.tcx.hir().body(closure.body).value; + let async_closure_body = cx.tcx.hir_body(closure.body).value; let ExprKind::Block(block, _) = async_closure_body.kind else { return; }; diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index a1cf16e6ce9f..9f0ea84246dd 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -205,7 +205,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { // Ensure this is not the final stmt, otherwise removing it would cause a compile error && let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id)) && let ItemKind::Fn { body, .. } = item.kind - && let block = cx.tcx.hir().body(body).value + && let block = cx.tcx.hir_body(body).value && let ExprKind::Block(block, _) = block.kind && !is_inside_let_else(cx.tcx, expr) && let [.., final_stmt] = block.stmts diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs index 29914d4379fe..552135b15fd8 100644 --- a/clippy_lints/src/same_name_method.rs +++ b/clippy_lints/src/same_name_method.rs @@ -50,9 +50,9 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { let mut map = FxHashMap::::default(); - for id in cx.tcx.hir().items() { + for id in cx.tcx.hir_free_items() { if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. }) - && let item = cx.tcx.hir().item(id) + && let item = cx.tcx.hir_item(id) && let ItemKind::Impl(Impl { items, of_trait, diff --git a/clippy_lints/src/string_patterns.rs b/clippy_lints/src/string_patterns.rs index 3834087f7977..694ad4f6347b 100644 --- a/clippy_lints/src/string_patterns.rs +++ b/clippy_lints/src/string_patterns.rs @@ -138,7 +138,7 @@ fn get_char_span<'tcx>(cx: &'_ LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Optio fn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr<'_>, msrv: &Msrv) { if let ExprKind::Closure(closure) = method_arg.kind - && let body = cx.tcx.hir().body(closure.body) + && let body = cx.tcx.hir_body(closure.body) && let Some(PatKind::Binding(_, binding, ..)) = body.params.first().map(|p| p.pat.kind) { let mut set_char_spans: Vec = Vec::new(); diff --git a/clippy_lints/src/suspicious_trait_impl.rs b/clippy_lints/src/suspicious_trait_impl.rs index e9779d437d43..9326b2adaffb 100644 --- a/clippy_lints/src/suspicious_trait_impl.rs +++ b/clippy_lints/src/suspicious_trait_impl.rs @@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl { && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id && let hir::Node::ImplItem(impl_item) = cx.tcx.hir_node_by_def_id(parent_fn) && let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind - && let body = cx.tcx.hir().body(body_id) + && let body = cx.tcx.hir_body(body_id) && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id && let Some(trait_ref) = trait_ref_of_method(cx, parent_fn) && let trait_id = trait_ref.path.res.def_id() diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index 790e0965198d..cbf7b126632e 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -135,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { && let Some(Node::Item(Item { kind: ItemKind::Trait(_, _, _, self_bounds, _), .. - })) = cx.tcx.hir().get_if_local(*def_id) + })) = cx.tcx.hir_get_if_local(*def_id) { if self_bounds_map.is_empty() { for bound in *self_bounds { diff --git a/clippy_lints/src/types/borrowed_box.rs b/clippy_lints/src/types/borrowed_box.rs index 2e97772407fd..004ad03e7085 100644 --- a/clippy_lints/src/types/borrowed_box.rs +++ b/clippy_lints/src/types/borrowed_box.rs @@ -96,10 +96,10 @@ fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool { fn get_bounds_if_impl_trait<'tcx>(cx: &LateContext<'tcx>, qpath: &QPath<'_>, id: HirId) -> Option> { if let Some(did) = cx.qpath_res(qpath, id).opt_def_id() - && let Some(Node::GenericParam(generic_param)) = cx.tcx.hir().get_if_local(did) + && let Some(Node::GenericParam(generic_param)) = cx.tcx.hir_get_if_local(did) && let GenericParamKind::Type { synthetic, .. } = generic_param.kind && synthetic - && let Some(generics) = cx.tcx.hir().get_generics(id.owner.def_id) + && let Some(generics) = cx.tcx.hir_get_generics(id.owner.def_id) && let Some(pred) = generics.bounds_for_param(did.expect_local()).next() { Some(pred.bounds) diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs index 207f2ef4563a..16fe035802fa 100644 --- a/clippy_lints/src/unconditional_recursion.rs +++ b/clippy_lints/src/unconditional_recursion.rs @@ -326,9 +326,9 @@ impl UnconditionalRecursion { .find(|item| { item.kind == AssocKind::Fn && item.def_id.is_local() && item.name == kw::Default }) - && let Some(body_node) = cx.tcx.hir().get_if_local(assoc_item.def_id) + && let Some(body_node) = cx.tcx.hir_get_if_local(assoc_item.def_id) && let Some(body_id) = body_node.body_id() - && let body = cx.tcx.hir().body(body_id) + && let body = cx.tcx.hir_body(body_id) // We don't want to keep it if it has conditional return. && let [return_expr] = get_return_calls_in_body(body).as_slice() && let ExprKind::Call(call_expr, _) = return_expr.kind diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index b3d269080930..c8e3c46f2f6f 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -245,7 +245,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { // const and static items only need a safety comment if their body is an unsafe block, lint otherwise (&ItemKind::Const(.., body) | &ItemKind::Static(.., body), HasSafetyComment::Yes(pos)) => { if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); if !matches!( body.value.kind, hir::ExprKind::Block(block, _) if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) @@ -558,7 +558,7 @@ fn comment_start_before_item_in_mod( // some_item /* comment */ unsafe impl T {} // ^-------^ returns the end of this span // ^---------------^ finally checks comments in this range - let prev_item = cx.tcx.hir().item(parent_mod.item_ids[idx - 1]); + let prev_item = cx.tcx.hir_item(parent_mod.item_ids[idx - 1]); if let Some(sp) = walk_span_to_context(prev_item.span, SyntaxContext::root()) { return Some(sp.hi()); } @@ -605,7 +605,7 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span fn get_body_search_span(cx: &LateContext<'_>) -> Option { let body = cx.enclosing_body?; let map = cx.tcx.hir(); - let mut span = map.body(body).value.span; + let mut span = cx.tcx.hir_body(body).value.span; let mut maybe_global_var = false; for (_, node) in map.parent_iter(body.hir_id) { match node { diff --git a/clippy_lints/src/unit_return_expecting_ord.rs b/clippy_lints/src/unit_return_expecting_ord.rs index 87478a120dd0..67ceac92dbc0 100644 --- a/clippy_lints/src/unit_return_expecting_ord.rs +++ b/clippy_lints/src/unit_return_expecting_ord.rs @@ -123,7 +123,7 @@ fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Spa && let ty = cx.tcx.instantiate_bound_regions_with_erased(ret_ty) && ty.is_unit() { - let body = cx.tcx.hir().body(body); + let body = cx.tcx.hir_body(body); if let ExprKind::Block(block, _) = body.value.kind && block.expr.is_none() && let Some(stmt) = block.stmts.last() diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs index 00b80e827d8a..87f184e13ce1 100644 --- a/clippy_lints/src/unit_types/let_unit_value.rs +++ b/clippy_lints/src/unit_types/let_unit_value.rs @@ -84,7 +84,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) { if let PatKind::Binding(_, binding_hir_id, ..) = local.pat.kind && let Some(body_id) = cx.enclosing_body.as_ref() { - let body = cx.tcx.hir().body(*body_id); + let body = cx.tcx.hir_body(*body_id); // Collect variable usages let mut visitor = UnitVariableCollector::new(binding_hir_id); diff --git a/clippy_lints/src/unused_self.rs b/clippy_lints/src/unused_self.rs index 781f51aa9b07..d8305a628290 100644 --- a/clippy_lints/src/unused_self.rs +++ b/clippy_lints/src/unused_self.rs @@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { && assoc_item.fn_has_self_parameter && let ImplItemKind::Fn(.., body_id) = &impl_item.kind && (!cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) || !self.avoid_breaking_exported_api) - && let body = cx.tcx.hir().body(*body_id) + && let body = cx.tcx.hir_body(*body_id) && let [self_param, ..] = body.params && !is_local_used(cx, body, self_param.pat.hir_id) && !contains_todo(cx, body) diff --git a/clippy_lints/src/unwrap_in_result.rs b/clippy_lints/src/unwrap_in_result.rs index 9b9a2ffbbc80..f870eb71e19b 100644 --- a/clippy_lints/src/unwrap_in_result.rs +++ b/clippy_lints/src/unwrap_in_result.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for UnwrapInResult { fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_item: &'tcx hir::ImplItem<'_>) { if let ImplItemKind::Fn(_, body_id) = impl_item.kind { - let body = cx.tcx.hir().body(body_id); + let body = cx.tcx.hir_body(body_id); let typeck = cx.tcx.typeck(impl_item.owner_id.def_id); let mut result = Vec::new(); let _: Option = for_each_expr(cx, body.value, |e| { diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 6bad78cf8718..ce489054e16e 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -637,9 +637,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { } fn body(&self, body_id: &Binding) { - let expr = self.cx.tcx.hir().body(body_id.value).value; + let expr = self.cx.tcx.hir_body(body_id.value).value; bind!(self, expr); - chain!(self, "{expr} = &cx.tcx.hir().body({body_id}).value"); + chain!(self, "{expr} = &cx.tcx.hir_body({body_id}).value"); self.expr(expr); } diff --git a/clippy_lints/src/utils/internal_lints/collapsible_calls.rs b/clippy_lints/src/utils/internal_lints/collapsible_calls.rs index eaeb754a23f1..2e6fb7c4ce4d 100644 --- a/clippy_lints/src/utils/internal_lints/collapsible_calls.rs +++ b/clippy_lints/src/utils/internal_lints/collapsible_calls.rs @@ -80,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls { if let ExprKind::Call(func, [call_cx, call_lint, call_sp, call_msg, call_f]) = expr.kind && is_expr_path_def_path(cx, func, &["clippy_utils", "diagnostics", "span_lint_and_then"]) && let ExprKind::Closure(&Closure { body, .. }) = call_f.kind - && let body = cx.tcx.hir().body(body) + && let body = cx.tcx.hir_body(body) && let only_expr = peel_blocks_with_stmt(body.value) && let ExprKind::MethodCall(ps, recv, span_call_args, _) = &only_expr.kind && let ExprKind::Path(..) = recv.kind diff --git a/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/clippy_lints/src/utils/internal_lints/invalid_paths.rs index 08c178ed229f..252ac5e67682 100644 --- a/clippy_lints/src/utils/internal_lints/invalid_paths.rs +++ b/clippy_lints/src/utils/internal_lints/invalid_paths.rs @@ -37,7 +37,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths { ty::TypingEnv::post_analysis(cx.tcx, item.owner_id), cx.tcx.typeck(item.owner_id), ) - .eval_simple(cx.tcx.hir().body(body_id).value) + .eval_simple(cx.tcx.hir_body(body_id).value) && let Some(path) = path .iter() .map(|x| { diff --git a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index dac1951489ca..315c83507d07 100644 --- a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass { if is_lint_ref_type(cx, ty) { check_invalid_clippy_version_attribute(cx, item); - let expr = &cx.tcx.hir().body(body_id).value; + let expr = &cx.tcx.hir_body(body_id).value; let fields = if let ExprKind::AddrOf(_, _, inner_exp) = expr.kind && let ExprKind::Struct(_, struct_fields, _) = inner_exp.kind { diff --git a/clippy_lints/src/zero_repeat_side_effects.rs b/clippy_lints/src/zero_repeat_side_effects.rs index 05f856507697..30fdf22fdbb0 100644 --- a/clippy_lints/src/zero_repeat_side_effects.rs +++ b/clippy_lints/src/zero_repeat_side_effects.rs @@ -47,7 +47,6 @@ declare_lint_pass!(ZeroRepeatSideEffects => [ZERO_REPEAT_SIDE_EFFECTS]); impl LateLintPass<'_> for ZeroRepeatSideEffects { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &rustc_hir::Expr<'_>) { - let hir_map = cx.tcx.hir(); if let Some(args) = VecArgs::hir(cx, expr) && let VecArgs::Repeat(inner_expr, len) = args && let ExprKind::Lit(l) = len.kind @@ -62,7 +61,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects { // sessions). else if let ExprKind::Repeat(inner_expr, const_arg) = expr.kind && let ConstArgKind::Anon(anon_const) = const_arg.kind - && let length_expr = hir_map.body(anon_const.body).value + && let length_expr = cx.tcx.hir_body(anon_const.body).value && !length_expr.span.from_expansion() && let ExprKind::Lit(literal) = length_expr.kind && let LitKind::Int(Pu128(0), _) = literal.node diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 59aaaa3d9fb7..4f48fb3b8a96 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -192,7 +192,7 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) { }, ExprKind::Closure(&Closure { body, .. }) => ( Pat::Str(""), - expr_search_pat_inner(tcx, tcx.hir().body(body).value, outer_span).1, + expr_search_pat_inner(tcx, tcx.hir_body(body).value, outer_span).1, ), ExprKind::Block( Block { diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index db82c458f703..4f707e34abf9 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -455,7 +455,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { Some(val) } }, - PatExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir().body(*body).value), + PatExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir_body(*body).value), PatExprKind::Path(qpath) => self.qpath(qpath, pat_expr.hir_id), } } @@ -483,7 +483,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { /// Simple constant folding: Insert an expression, get a constant or none. fn expr(&self, e: &Expr<'_>) -> Option> { match e.kind { - ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir().body(body).value), + ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir_body(body).value), ExprKind::DropTemps(e) => self.expr(e), ExprKind::Path(ref qpath) => self.qpath(qpath, e.hir_id), ExprKind::Block(block, _) => self.block(block), @@ -550,7 +550,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { /// leaves the local crate. pub fn eval_is_empty(&self, e: &Expr<'_>) -> Option { match e.kind { - ExprKind::ConstBlock(ConstBlock { body, .. }) => self.eval_is_empty(self.tcx.hir().body(body).value), + ExprKind::ConstBlock(ConstBlock { body, .. }) => self.eval_is_empty(self.tcx.hir_body(body).value), ExprKind::DropTemps(e) => self.eval_is_empty(e), ExprKind::Path(ref qpath) => { if !self @@ -645,7 +645,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { Res::Def(DefKind::Const | DefKind::AssocConst, def_id) => { // Check if this constant is based on `cfg!(..)`, // which is NOT constant for our purposes. - if let Some(node) = self.tcx.hir().get_if_local(def_id) + if let Some(node) = self.tcx.hir_get_if_local(def_id) && let Node::Item(Item { kind: ItemKind::Const(.., body_id), .. diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 4bbf28115a68..9ee30094d608 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -273,8 +273,8 @@ impl HirEqInterExpr<'_, '_, '_> { self.inner.cx.tcx.typeck_body(right), )); let res = self.eq_expr( - self.inner.cx.tcx.hir().body(left).value, - self.inner.cx.tcx.hir().body(right).value, + self.inner.cx.tcx.hir_body(left).value, + self.inner.cx.tcx.hir_body(right).value, ); self.inner.maybe_typeck_results = old_maybe_typeck_results; res @@ -906,7 +906,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { }) => { std::mem::discriminant(&capture_clause).hash(&mut self.s); // closures inherit TypeckResults - self.hash_expr(self.cx.tcx.hir().body(body).value); + self.hash_expr(self.cx.tcx.hir_body(body).value); }, ExprKind::ConstBlock(ref l_id) => { self.hash_body(l_id.body); @@ -1316,7 +1316,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { pub fn hash_body(&mut self, body_id: BodyId) { // swap out TypeckResults when hashing a body let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body_id)); - self.hash_expr(self.cx.tcx.hir().body(body_id).value); + self.hash_expr(self.cx.tcx.hir_body(body_id).value); self.maybe_typeck_results = old_maybe_typeck_results; } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 79cc50665800..c4ba4c94c946 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -652,8 +652,6 @@ fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) } fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symbol) -> Vec { - let hir = tcx.hir(); - let root_mod; let item_kind = match tcx.hir_node_by_def_id(local_id) { Node::Crate(r#mod) => { @@ -677,7 +675,7 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb ItemKind::Mod(r#mod) => r#mod .item_ids .iter() - .filter_map(|&item_id| res(hir.item(item_id).ident, item_id.owner_id)) + .filter_map(|&item_id| res(tcx.hir_item(item_id).ident, item_id.owner_id)) .collect(), ItemKind::Impl(r#impl) => r#impl .items @@ -944,7 +942,7 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)), ExprKind::Repeat(x, len) => { if let ConstArgKind::Anon(anon_const) = len.kind - && let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind + && let ExprKind::Lit(const_lit) = cx.tcx.hir_body(anon_const.body).value.kind && let LitKind::Int(v, _) = const_lit.node && v <= 32 && is_default_equivalent(cx, x) @@ -974,7 +972,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: & ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec), ExprKind::Repeat(_, len) => { if let ConstArgKind::Anon(anon_const) = len.kind - && let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind + && let ExprKind::Lit(const_lit) = cx.tcx.hir_body(anon_const.body).value.kind && let LitKind::Int(v, _) = const_lit.node { return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec); @@ -1424,7 +1422,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio | Node::ImplItem(&ImplItem { kind: ImplItemKind::Fn(_, eid), .. - }) => match cx.tcx.hir().body(eid).value.kind { + }) => match cx.tcx.hir_body(eid).value.kind { ExprKind::Block(block, _) => Some(block), _ => None, }, @@ -2067,7 +2065,7 @@ pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'t .. }, _, - ) = tcx.hir().body(body).value.kind + ) = tcx.hir_body(body).value.kind { return Some(expr); } @@ -2175,7 +2173,7 @@ pub fn is_expr_untyped_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) ExprKind::Closure(&Closure { body, fn_decl, .. }) if fn_decl.inputs.iter().all(|ty| matches!(ty.kind, TyKind::Infer(()))) => { - is_body_identity_function(cx, cx.tcx.hir().body(body)) + is_body_identity_function(cx, cx.tcx.hir_body(body)) }, ExprKind::Path(QPath::Resolved(_, path)) if path.segments.iter().all(|seg| seg.infer_args) @@ -2197,7 +2195,7 @@ pub fn is_expr_untyped_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) /// errors. pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { match expr.kind { - ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir().body(body)), + ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir_body(body)), _ => path_def_id(cx, expr).is_some_and(|id| cx.tcx.is_diagnostic_item(sym::convert_identity, id)), } } @@ -2552,9 +2550,9 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym Entry::Occupied(entry) => f(entry.get()), Entry::Vacant(entry) => { let mut names = Vec::new(); - for id in tcx.hir().module_items(module) { + for id in tcx.hir_module_free_items(module) { if matches!(tcx.def_kind(id.owner_id), DefKind::Const) - && let item = tcx.hir().item(id) + && let item = tcx.hir_item(id) && let ItemKind::Const(ty, _generics, _body) = item.kind { if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind { @@ -2932,7 +2930,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> ExprU #[allow(unreachable_patterns)] Some(ControlFlow::Break(_)) => unreachable!("type of node is ControlFlow"), None => ExprUseCtxt { - node: Node::Crate(cx.tcx.hir().root_module()), + node: Node::Crate(cx.tcx.hir_root_module()), child_id: HirId::INVALID, adjustments: &[], is_ty_unified: true, diff --git a/clippy_utils/src/ptr.rs b/clippy_utils/src/ptr.rs index 273c1b0defab..360c6251a57c 100644 --- a/clippy_utils/src/ptr.rs +++ b/clippy_utils/src/ptr.rs @@ -13,7 +13,7 @@ pub fn get_spans( idx: usize, replacements: &[(&'static str, &'static str)], ) -> Option)>> { - if let Some(body) = opt_body_id.map(|id| cx.tcx.hir().body(id)) { + if let Some(body) = opt_body_id.map(|id| cx.tcx.hir_body(id)) { if let PatKind::Binding(_, binding_id, _, _) = strip_pat_refs(body.params[idx].pat).kind { extract_clone_suggestions(cx, binding_id, replacements, body) } else { diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 088abd7c4791..d5e0e2e3436e 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -809,7 +809,7 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti fn_decl, def_id, body, .. }) = closure.kind { - let closure_body = cx.tcx.hir().body(body); + let closure_body = cx.tcx.hir_body(body); // is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`) // a type annotation is present if param `kind` is different from `TyKind::Infer` let closure_arg_is_type_annotated_double_ref = if let TyKind::Ref(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs index 70910f5bf52d..9b35ecee1dd1 100644 --- a/clippy_utils/src/visitors.rs +++ b/clippy_utils/src/visitors.rs @@ -296,7 +296,7 @@ where /// Checks if the given resolved path is used in the given body. pub fn is_res_used(cx: &LateContext<'_>, res: Res, body: BodyId) -> bool { - for_each_expr(cx, cx.tcx.hir().body(body).value, |e| { + for_each_expr(cx, cx.tcx.hir_body(body).value, |e| { if let ExprKind::Path(p) = &e.kind { if cx.qpath_res(p, e.hir_id) == res { return ControlFlow::Break(()); @@ -456,7 +456,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { } } fn visit_nested_item(&mut self, id: ItemId) -> Self::Result { - if let ItemKind::Impl(i) = &self.cx.tcx.hir().item(id).kind + if let ItemKind::Impl(i) = &self.cx.tcx.hir_item(id).kind && i.safety.is_unsafe() { ControlFlow::Break(()) diff --git a/tests/ui/author/blocks.stdout b/tests/ui/author/blocks.stdout index 6bf48d5ba4ef..54325f9776c5 100644 --- a/tests/ui/author/blocks.stdout +++ b/tests/ui/author/blocks.stdout @@ -42,10 +42,10 @@ if let ExprKind::Block(block, None) = expr.kind } if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::CoroutineClosure(CoroutineDesugaring::Async), .. } = expr.kind && let FnRetTy::DefaultReturn(_) = fn_decl.output - && expr1 = &cx.tcx.hir().body(body_id).value + && expr1 = &cx.tcx.hir_body(body_id).value && let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind && let FnRetTy::DefaultReturn(_) = fn_decl1.output - && expr2 = &cx.tcx.hir().body(body_id1).value + && expr2 = &cx.tcx.hir_body(body_id1).value && let ExprKind::Block(block, None) = expr2.kind && block.stmts.is_empty() && let Some(trailing_expr) = block.expr diff --git a/tests/ui/author/macro_in_closure.stdout b/tests/ui/author/macro_in_closure.stdout index 66caf382d897..3186d0cbc276 100644 --- a/tests/ui/author/macro_in_closure.stdout +++ b/tests/ui/author/macro_in_closure.stdout @@ -2,7 +2,7 @@ if let StmtKind::Let(local) = stmt.kind && let Some(init) = local.init && let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = init.kind && let FnRetTy::DefaultReturn(_) = fn_decl.output - && expr = &cx.tcx.hir().body(body_id).value + && expr = &cx.tcx.hir_body(body_id).value && let ExprKind::Block(block, None) = expr.kind && block.stmts.len() == 1 && let StmtKind::Semi(e) = block.stmts[0].kind diff --git a/tests/ui/author/repeat.stdout b/tests/ui/author/repeat.stdout index 1a608734ada9..f2c6b3f807f1 100644 --- a/tests/ui/author/repeat.stdout +++ b/tests/ui/author/repeat.stdout @@ -2,7 +2,7 @@ if let ExprKind::Repeat(value, length) = expr.kind && let ExprKind::Lit(ref lit) = value.kind && let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node && let ConstArgKind::Anon(anon_const) = length.kind - && expr1 = &cx.tcx.hir().body(anon_const.body).value + && expr1 = &cx.tcx.hir_body(anon_const.body).value && let ExprKind::Lit(ref lit1) = expr1.kind && let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node { From 91481e3bcf4df9bee2a61c99894096864b9d7e83 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 3 Feb 2025 14:42:01 +1100 Subject: [PATCH 154/991] Overhaul the `intravisit::Map` trait. First of all, note that `Map` has three different relevant meanings. - The `intravisit::Map` trait. - The `map::Map` struct. - The `NestedFilter::Map` associated type. The `intravisit::Map` trait is impl'd twice. - For `!`, where the methods are all unreachable. - For `map::Map`, which gets HIR stuff from the `TyCtxt`. As part of getting rid of `map::Map`, this commit changes `impl intravisit::Map for map::Map` to `impl intravisit::Map for TyCtxt`. It's fairly straightforward except various things are renamed, because the existing names would no longer have made sense. - `trait intravisit::Map` becomes `trait intravisit::HirTyCtxt`, so named because it gets some HIR stuff from a `TyCtxt`. - `NestedFilter::Map` assoc type becomes `NestedFilter::MaybeTyCtxt`, because it's always `!` or `TyCtxt`. - `Visitor::nested_visit_map` becomes `Visitor::maybe_tcx`. I deliberately made the new trait and associated type names different to avoid the old `type Map: Map` situation, which I found confusing. We now have `type MaybeTyCtxt: HirTyCtxt`. --- clippy_lints/src/derive.rs | 4 ++-- clippy_lints/src/doc/mod.rs | 4 ++-- .../src/extra_unused_type_parameters.rs | 4 ++-- clippy_lints/src/from_over_into.rs | 4 ++-- clippy_lints/src/implicit_hasher.rs | 4 ++-- clippy_lints/src/index_refutable_slice.rs | 4 ++-- clippy_lints/src/lifetimes.rs | 8 ++++---- clippy_lints/src/loops/utils.rs | 4 ++-- .../src/loops/while_let_on_iterator.rs | 8 ++++---- clippy_lints/src/methods/needless_collect.rs | 4 ++-- .../src/methods/option_map_unwrap_or.rs | 8 ++++---- clippy_lints/src/methods/utils.rs | 4 ++-- clippy_lints/src/mutable_debug_assertion.rs | 4 ++-- clippy_lints/src/ptr.rs | 4 ++-- clippy_lints/src/redundant_closure_call.rs | 4 ++-- clippy_lints/src/unconditional_recursion.rs | 7 ++----- clippy_lints/src/unused_async.rs | 4 ++-- clippy_lints/src/unused_peekable.rs | 4 ++-- clippy_lints/src/unwrap.rs | 4 ++-- .../internal_lints/lint_without_lint_pass.rs | 2 +- clippy_lints/src/zombie_processes.rs | 4 ++-- clippy_utils/src/lib.rs | 4 ++-- clippy_utils/src/usage.rs | 4 ++-- clippy_utils/src/visitors.rs | 20 +++++++++---------- 24 files changed, 61 insertions(+), 64 deletions(-) diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 91ddbb44ff89..db3e6034c5ba 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -437,8 +437,8 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { walk_expr(self, expr) } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 36baf492a540..93c2b7a2d182 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -1079,8 +1079,8 @@ impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> { // Panics in const blocks will cause compilation to fail. fn visit_anon_const(&mut self, _: &'tcx AnonConst) {} - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/extra_unused_type_parameters.rs b/clippy_lints/src/extra_unused_type_parameters.rs index 6ccea22e191c..6a217b6182ce 100644 --- a/clippy_lints/src/extra_unused_type_parameters.rs +++ b/clippy_lints/src/extra_unused_type_parameters.rs @@ -241,8 +241,8 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs index 167377972db9..41bf6e81916a 100644 --- a/clippy_lints/src/from_over_into.rs +++ b/clippy_lints/src/from_over_into.rs @@ -134,8 +134,8 @@ impl<'tcx> Visitor<'tcx> for SelfFinder<'_, 'tcx> { type Result = ControlFlow<()>; type NestedFilter = OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> Self::Result { diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 1b39663f4f81..d2545e57652a 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -363,7 +363,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> { walk_expr(self, e); } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs index 15650c4f7329..deac51ab4c49 100644 --- a/clippy_lints/src/index_refutable_slice.rs +++ b/clippy_lints/src/index_refutable_slice.rs @@ -223,8 +223,8 @@ struct SliceIndexLintingVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'_, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 8eb45109d68c..f08812017b9c 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -19,8 +19,8 @@ use rustc_hir::{ WherePredicateKind, lang_items, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter as middle_nested_filter; +use rustc_middle::ty::TyCtxt; use rustc_session::impl_lint_pass; use rustc_span::Span; use rustc_span::def_id::LocalDefId; @@ -582,7 +582,7 @@ impl<'tcx, F> Visitor<'tcx> for LifetimeChecker<'_, 'tcx, F> where F: NestedFilter<'tcx>, { - type Map = Map<'tcx>; + type MaybeTyCtxt = TyCtxt<'tcx>; type NestedFilter = F; // for lifetimes as parameters of generics @@ -628,8 +628,8 @@ where self.lifetime_elision_impossible = false; } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/loops/utils.rs b/clippy_lints/src/loops/utils.rs index 51fde5288ab9..a5185d38e7c3 100644 --- a/clippy_lints/src/loops/utils.rs +++ b/clippy_lints/src/loops/utils.rs @@ -240,8 +240,8 @@ impl<'tcx> Visitor<'tcx> for InitializeVisitor<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs index e31b474c83f6..6000ff7a3609 100644 --- a/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/clippy_lints/src/loops/while_let_on_iterator.rs @@ -245,8 +245,8 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: & impl<'tcx> Visitor<'tcx> for AfterLoopVisitor<'_, '_, 'tcx> { type NestedFilter = OnlyBodies; type Result = ControlFlow<()>; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result { @@ -288,8 +288,8 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: & } impl<'tcx> Visitor<'tcx> for NestedLoopVisitor<'_, '_, 'tcx> { type NestedFilter = OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_local(&mut self, l: &'tcx LetStmt<'_>) { diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 5664ffba1a0e..45f79dd44f2a 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -456,8 +456,8 @@ impl<'tcx> Visitor<'tcx> for UsedCountVisitor<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index 7c4dc4ffb202..4a8a221e8c36 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -143,8 +143,8 @@ impl<'tcx> Visitor<'tcx> for UnwrapVisitor<'_, 'tcx> { walk_path(self, path); } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } @@ -174,7 +174,7 @@ impl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> { rustc_hir::intravisit::walk_expr(self, expr) } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/methods/utils.rs b/clippy_lints/src/methods/utils.rs index 6e39e7be2c43..3611b341897a 100644 --- a/clippy_lints/src/methods/utils.rs +++ b/clippy_lints/src/methods/utils.rs @@ -89,8 +89,8 @@ struct CloneOrCopyVisitor<'cx, 'tcx> { impl<'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'_, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { diff --git a/clippy_lints/src/mutable_debug_assertion.rs b/clippy_lints/src/mutable_debug_assertion.rs index 152635a5c35c..13a23a13b9c2 100644 --- a/clippy_lints/src/mutable_debug_assertion.rs +++ b/clippy_lints/src/mutable_debug_assertion.rs @@ -119,7 +119,7 @@ impl<'tcx> Visitor<'tcx> for MutArgVisitor<'_, 'tcx> { walk_expr(self, expr); } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 7fba4b6a6c8b..9b241edf4ccf 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -583,8 +583,8 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[ } impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_anon_const(&mut self, _: &'tcx AnonConst) {} diff --git a/clippy_lints/src/redundant_closure_call.rs b/clippy_lints/src/redundant_closure_call.rs index 54e507655e9c..1498a49a7a4a 100644 --- a/clippy_lints/src/redundant_closure_call.rs +++ b/clippy_lints/src/redundant_closure_call.rs @@ -241,8 +241,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { hir_visit::walk_expr(self, expr); } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } let mut closure_usage_count = ClosureUsageCount { cx, path, count: 0 }; diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs index 16fe035802fa..529f85be3720 100644 --- a/clippy_lints/src/unconditional_recursion.rs +++ b/clippy_lints/src/unconditional_recursion.rs @@ -9,7 +9,6 @@ use rustc_hir::intravisit::{FnKind, Visitor, walk_body, walk_expr}; use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind}; use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt}; use rustc_session::impl_lint_pass; @@ -275,7 +274,6 @@ fn is_default_method_on_current_ty<'tcx>(tcx: TyCtxt<'tcx>, qpath: QPath<'tcx>, struct CheckCalls<'a, 'tcx> { cx: &'a LateContext<'tcx>, - map: Map<'tcx>, implemented_ty_id: DefId, method_span: Span, } @@ -287,8 +285,8 @@ where type NestedFilter = nested_filter::OnlyBodies; type Result = ControlFlow<()>; - fn nested_visit_map(&mut self) -> Self::Map { - self.map + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> { @@ -380,7 +378,6 @@ impl UnconditionalRecursion { { let mut c = CheckCalls { cx, - map: cx.tcx.hir(), implemented_ty_id, method_span, }; diff --git a/clippy_lints/src/unused_async.rs b/clippy_lints/src/unused_async.rs index d00bd7f2b3db..1c1c841e9641 100644 --- a/clippy_lints/src/unused_async.rs +++ b/clippy_lints/src/unused_async.rs @@ -101,8 +101,8 @@ impl<'tcx> Visitor<'tcx> for AsyncFnVisitor<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/unused_peekable.rs b/clippy_lints/src/unused_peekable.rs index 71aa57e0a14c..0f9b05c84d4b 100644 --- a/clippy_lints/src/unused_peekable.rs +++ b/clippy_lints/src/unused_peekable.rs @@ -112,8 +112,8 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> { type NestedFilter = OnlyBodies; type Result = ControlFlow<()>; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> ControlFlow<()> { diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index 6a952c0d97aa..76b9bbbd32fd 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -374,8 +374,8 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index 315c83507d07..e31da9e9f611 100644 --- a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -277,7 +277,7 @@ impl<'tcx> Visitor<'tcx> for LintCollector<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { self.cx.tcx.hir() } } diff --git a/clippy_lints/src/zombie_processes.rs b/clippy_lints/src/zombie_processes.rs index 4df34891a2b1..9bd00b1e5c8c 100644 --- a/clippy_lints/src/zombie_processes.rs +++ b/clippy_lints/src/zombie_processes.rs @@ -249,8 +249,8 @@ impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> { walk_expr(self, ex) } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index c4ba4c94c946..ccf32f42a47b 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1370,8 +1370,8 @@ impl<'tcx> Visitor<'tcx> for ContainsName<'_, 'tcx> { } } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_utils/src/usage.rs b/clippy_utils/src/usage.rs index 37f729668925..3bf518f7fe70 100644 --- a/clippy_utils/src/usage.rs +++ b/clippy_utils/src/usage.rs @@ -133,8 +133,8 @@ impl<'tcx> Visitor<'tcx> for BindingUsageFinder<'_, 'tcx> { ControlFlow::Continue(()) } - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } } diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs index 9b35ecee1dd1..2ac0efd7e392 100644 --- a/clippy_utils/src/visitors.rs +++ b/clippy_utils/src/visitors.rs @@ -154,8 +154,8 @@ pub fn for_each_expr<'tcx, B, C: Continue>( type NestedFilter = nested_filter::OnlyBodies; type Result = ControlFlow; - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) -> Self::Result { @@ -412,8 +412,8 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { type NestedFilter = nested_filter::OnlyBodies; type Result = ControlFlow<()>; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result { match e.kind { @@ -477,8 +477,8 @@ pub fn contains_unsafe_block<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { type Result = ControlFlow<()>; type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_block(&mut self, b: &'tcx Block<'_>) -> Self::Result { @@ -544,8 +544,8 @@ pub fn for_each_local_use_after_expr<'tcx, B>( } impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow, B> Visitor<'tcx> for V<'_, 'tcx, F, B> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) { @@ -729,8 +729,8 @@ pub fn for_each_local_assignment<'tcx, B>( } impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow, B> Visitor<'tcx> for V<'_, 'tcx, F, B> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.cx.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx } fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) { From d1fb18e2b7e584fe92607f413015c418b9c206ac Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 20 Jan 2025 19:48:55 +0200 Subject: [PATCH 155/991] Calculate drop glue and show it on hover Also fix the `needs_drop()` intrinsic. Unions also need this information (to err if they have a drop-needing field), but this will come in a follow-up PR. --- .../hir-ty/src/consteval/tests/intrinsics.rs | 35 +- .../rust-analyzer/crates/hir-ty/src/db.rs | 7 +- .../rust-analyzer/crates/hir-ty/src/drop.rs | 209 ++++++ .../rust-analyzer/crates/hir-ty/src/lib.rs | 2 + .../crates/hir-ty/src/mir/eval/shim.rs | 11 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 35 +- .../rust-analyzer/crates/ide/src/hover.rs | 1 + .../crates/ide/src/hover/render.rs | 95 ++- .../crates/ide/src/hover/tests.rs | 594 ++++++++++++++++++ .../crates/ide/src/static_index.rs | 1 + .../crates/rust-analyzer/src/config.rs | 3 + .../docs/book/src/configuration_generated.md | 5 + .../rust-analyzer/editors/code/package.json | 10 + 13 files changed, 1002 insertions(+), 6 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/hir-ty/src/drop.rs diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs index c1ac7ae173b8..ee375d60deb8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs @@ -354,12 +354,43 @@ fn overflowing_add() { fn needs_drop() { check_number( r#" - //- minicore: copy, sized + //- minicore: drop, manually_drop, copy, sized + use core::mem::ManuallyDrop; extern "rust-intrinsic" { pub fn needs_drop() -> bool; } struct X; - const GOAL: bool = !needs_drop::() && needs_drop::(); + struct NeedsDrop; + impl Drop for NeedsDrop { + fn drop(&mut self) {} + } + enum Enum { + A(T), + B(X), + } + const fn val_needs_drop(_v: T) -> bool { needs_drop::() } + const fn closure_needs_drop() -> bool { + let a = NeedsDrop; + let b = X; + !val_needs_drop(|| &a) && val_needs_drop(move || &a) && !val_needs_drop(move || &b) + } + const fn opaque() -> impl Sized { + || {} + } + const fn opaque_copy() -> impl Sized + Copy { + || {} + } + trait Everything {} + impl Everything for T {} + const GOAL: bool = !needs_drop::() && !needs_drop::() + && needs_drop::() && !needs_drop::>() + && needs_drop::<[NeedsDrop; 1]>() && !needs_drop::<[NeedsDrop; 0]>() + && needs_drop::<(X, NeedsDrop)>() + && needs_drop::>() && !needs_drop::>() + && closure_needs_drop() + && !val_needs_drop(opaque()) && !val_needs_drop(opaque_copy()) + && needs_drop::<[NeedsDrop]>() && needs_drop::() + && !needs_drop::<&dyn Everything>() && !needs_drop::(); "#, 1, ); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index 6b0568266708..76031491d9a0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -13,6 +13,7 @@ use hir_def::{ ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, TypeOrConstParamId, VariantId, }; +use hir_expand::name::Name; use la_arena::ArenaMap; use smallvec::SmallVec; use triomphe::Arc; @@ -20,6 +21,7 @@ use triomphe::Arc; use crate::{ chalk_db, consteval::ConstEvalError, + drop::DropGlue, dyn_compatibility::DynCompatibilityViolation, layout::{Layout, LayoutError}, lower::{Diagnostics, GenericDefaults, GenericPredicates}, @@ -28,7 +30,6 @@ use crate::{ Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner, PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId, }; -use hir_expand::name::Name; #[ra_salsa::query_group(HirDatabaseStorage)] pub trait HirDatabase: DefDatabase + Upcast { @@ -305,6 +306,10 @@ pub trait HirDatabase: DefDatabase + Upcast { block: Option, env: chalk_ir::Environment, ) -> chalk_ir::ProgramClauses; + + #[ra_salsa::invoke(crate::drop::has_drop_glue)] + #[ra_salsa::cycle(crate::drop::has_drop_glue_recover)] + fn has_drop_glue(&self, ty: Ty, env: Arc) -> DropGlue {} } #[test] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs new file mode 100644 index 000000000000..351926c86c47 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs @@ -0,0 +1,209 @@ +//! Utilities for computing drop info about types. + +use base_db::ra_salsa; +use chalk_ir::cast::Cast; +use hir_def::data::adt::StructFlags; +use hir_def::lang_item::LangItem; +use hir_def::AdtId; +use stdx::never; +use triomphe::Arc; + +use crate::{ + db::HirDatabase, method_resolution::TyFingerprint, AliasTy, Canonical, CanonicalVarKinds, + InEnvironment, Interner, ProjectionTy, TraitEnvironment, Ty, TyBuilder, TyKind, +}; +use crate::{ConcreteConst, ConstScalar, ConstValue}; + +fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool { + let module = match adt { + AdtId::EnumId(id) => db.lookup_intern_enum(id).container, + AdtId::StructId(id) => db.lookup_intern_struct(id).container, + AdtId::UnionId(id) => db.lookup_intern_union(id).container, + }; + let Some(drop_trait) = + db.lang_item(module.krate(), LangItem::Drop).and_then(|it| it.as_trait()) + else { + return false; + }; + let impls = match module.containing_block() { + Some(block) => match db.trait_impls_in_block(block) { + Some(it) => it, + None => return false, + }, + None => db.trait_impls_in_crate(module.krate()), + }; + let result = impls.for_trait_and_self_ty(drop_trait, TyFingerprint::Adt(adt)).next().is_some(); + result +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum DropGlue { + // Order of variants is important. + None, + /// May have a drop glue if some type parameter has it. + /// + /// For the compiler this is considered as a positive result, IDE distinguishes this from "yes". + DependOnParams, + HasDropGlue, +} + +pub(crate) fn has_drop_glue(db: &dyn HirDatabase, ty: Ty, env: Arc) -> DropGlue { + match ty.kind(Interner) { + TyKind::Adt(adt, subst) => { + if has_destructor(db, adt.0) { + return DropGlue::HasDropGlue; + } + match adt.0 { + AdtId::StructId(id) => { + if db.struct_data(id).flags.contains(StructFlags::IS_MANUALLY_DROP) { + return DropGlue::None; + } + db.field_types(id.into()) + .iter() + .map(|(_, field_ty)| { + db.has_drop_glue( + field_ty.clone().substitute(Interner, subst), + env.clone(), + ) + }) + .max() + .unwrap_or(DropGlue::None) + } + // Unions cannot have fields with destructors. + AdtId::UnionId(_) => DropGlue::None, + AdtId::EnumId(id) => db + .enum_data(id) + .variants + .iter() + .map(|&(variant, _)| { + db.field_types(variant.into()) + .iter() + .map(|(_, field_ty)| { + db.has_drop_glue( + field_ty.clone().substitute(Interner, subst), + env.clone(), + ) + }) + .max() + .unwrap_or(DropGlue::None) + }) + .max() + .unwrap_or(DropGlue::None), + } + } + TyKind::Tuple(_, subst) => subst + .iter(Interner) + .map(|ty| ty.assert_ty_ref(Interner)) + .map(|ty| db.has_drop_glue(ty.clone(), env.clone())) + .max() + .unwrap_or(DropGlue::None), + TyKind::Array(ty, len) => { + if let ConstValue::Concrete(ConcreteConst { interned: ConstScalar::Bytes(len, _) }) = + &len.data(Interner).value + { + match (&**len).try_into() { + Ok(len) => { + let len = usize::from_le_bytes(len); + if len == 0 { + // Arrays of size 0 don't have drop glue. + return DropGlue::None; + } + } + Err(_) => { + never!("const array size with non-usize len"); + } + } + } + db.has_drop_glue(ty.clone(), env) + } + TyKind::Slice(ty) => db.has_drop_glue(ty.clone(), env), + TyKind::Closure(closure_id, subst) => { + let owner = db.lookup_intern_closure((*closure_id).into()).0; + let infer = db.infer(owner); + let (captures, _) = infer.closure_info(closure_id); + let env = db.trait_environment_for_body(owner); + captures + .iter() + .map(|capture| db.has_drop_glue(capture.ty(subst), env.clone())) + .max() + .unwrap_or(DropGlue::None) + } + // FIXME: Handle coroutines. + TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) => DropGlue::None, + TyKind::Ref(..) + | TyKind::Raw(..) + | TyKind::FnDef(..) + | TyKind::Str + | TyKind::Never + | TyKind::Scalar(_) + | TyKind::Function(_) + | TyKind::Foreign(_) + | TyKind::Error => DropGlue::None, + TyKind::Dyn(_) => DropGlue::HasDropGlue, + TyKind::AssociatedType(assoc_type_id, subst) => projection_has_drop_glue( + db, + env, + ProjectionTy { associated_ty_id: *assoc_type_id, substitution: subst.clone() }, + ty, + ), + TyKind::Alias(AliasTy::Projection(projection)) => { + projection_has_drop_glue(db, env, projection.clone(), ty) + } + TyKind::OpaqueType(..) | TyKind::Alias(AliasTy::Opaque(_)) => { + if is_copy(db, ty, env) { + DropGlue::None + } else { + DropGlue::HasDropGlue + } + } + TyKind::Placeholder(_) | TyKind::BoundVar(_) => { + if is_copy(db, ty, env) { + DropGlue::None + } else { + DropGlue::DependOnParams + } + } + TyKind::InferenceVar(..) => unreachable!("inference vars shouldn't exist out of inference"), + } +} + +fn projection_has_drop_glue( + db: &dyn HirDatabase, + env: Arc, + projection: ProjectionTy, + ty: Ty, +) -> DropGlue { + let normalized = db.normalize_projection(projection, env.clone()); + match normalized.kind(Interner) { + TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(..) => { + if is_copy(db, ty, env) { + DropGlue::None + } else { + DropGlue::DependOnParams + } + } + _ => db.has_drop_glue(normalized, env), + } +} + +fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc) -> bool { + let Some(copy_trait) = db.lang_item(env.krate, LangItem::Copy).and_then(|it| it.as_trait()) + else { + return false; + }; + let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build(); + let goal = Canonical { + value: InEnvironment::new(&env.env, trait_ref.cast(Interner)), + binders: CanonicalVarKinds::empty(Interner), + }; + db.trait_solve(env.krate, env.block, goal).is_some() +} + +pub(crate) fn has_drop_glue_recover( + _db: &dyn HirDatabase, + _cycle: &ra_salsa::Cycle, + _ty: &Ty, + _env: &Arc, +) -> DropGlue { + DropGlue::None +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 55d81875a2be..748016f7ceda 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -24,6 +24,7 @@ extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis; mod builder; mod chalk_db; mod chalk_ext; +mod drop; mod infer; mod inhabitedness; mod interner; @@ -81,6 +82,7 @@ use crate::{ pub use autoderef::autoderef; pub use builder::{ParamKind, TyBuilder}; pub use chalk_ext::*; +pub use drop::DropGlue; pub use infer::{ cast::CastError, closure::{CaptureKind, CapturedItem}, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index 38b189a517f2..7d3376f56be1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -11,6 +11,7 @@ use hir_def::{ }; use hir_expand::name::Name; use intern::{sym, Symbol}; +use stdx::never; use crate::{ error_lifetime, @@ -20,6 +21,7 @@ use crate::{ LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Substitution, Ty, TyBuilder, TyExt, }, + DropGlue, }; mod simd; @@ -853,7 +855,14 @@ impl Evaluator<'_> { "size_of generic arg is not provided".into(), )); }; - let result = !ty.clone().is_copy(self.db, locals.body.owner); + let result = match self.db.has_drop_glue(ty.clone(), self.trait_env.clone()) { + DropGlue::HasDropGlue => true, + DropGlue::None => false, + DropGlue::DependOnParams => { + never!("should be fully monomorphized now"); + true + } + }; destination.write_from_bytes(self, &[u8::from(result)]) } "ptr_guaranteed_cmp" => { diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 5923a1bc30ea..727d31cffb51 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -152,7 +152,7 @@ pub use { layout::LayoutError, method_resolution::TyFingerprint, mir::{MirEvalError, MirLowerError}, - CastError, FnAbi, PointerCast, Safety, Variance, + CastError, DropGlue, FnAbi, PointerCast, Safety, Variance, }, // FIXME: Properly encapsulate mir hir_ty::{mir, Interner as ChalkTyInterner}, @@ -1391,6 +1391,10 @@ impl Struct { Type::from_def(db, self.id) } + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + Type::from_def_placeholders(db, self.id) + } + pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type { Type::from_value_def(db, self.id) } @@ -1436,6 +1440,10 @@ impl Union { Type::from_def(db, self.id) } + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + Type::from_def_placeholders(db, self.id) + } + pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type { Type::from_value_def(db, self.id) } @@ -1490,6 +1498,10 @@ impl Enum { Type::from_def(db, self.id) } + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + Type::from_def_placeholders(db, self.id) + } + /// The type of the enum variant bodies. pub fn variant_body_ty(self, db: &dyn HirDatabase) -> Type { Type::new_for_crate( @@ -2929,6 +2941,10 @@ impl TypeAlias { Type::from_def(db, self.id) } + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + Type::from_def_placeholders(db, self.id) + } + pub fn name(self, db: &dyn HirDatabase) -> Name { db.type_alias_data(self.id).name.clone() } @@ -4708,6 +4724,19 @@ impl Type { Type::new(db, def, ty.substitute(Interner, &substs)) } + fn from_def_placeholders(db: &dyn HirDatabase, def: impl Into + HasResolver) -> Type { + let ty = db.ty(def.into()); + let substs = TyBuilder::placeholder_subst( + db, + match def.into() { + TyDefId::AdtId(it) => GenericDefId::AdtId(it), + TyDefId::TypeAliasId(it) => GenericDefId::TypeAliasId(it), + TyDefId::BuiltinType(_) => return Type::new(db, def, ty.skip_binders().clone()), + }, + ); + Type::new(db, def, ty.substitute(Interner, &substs)) + } + fn from_value_def(db: &dyn HirDatabase, def: impl Into + HasResolver) -> Type { let Some(ty) = db.value_ty(def.into()) else { return Type::new(db, def, TyKind::Error.intern(Interner)); @@ -5737,6 +5766,10 @@ impl Type { db.layout_of_ty(self.ty.clone(), self.env.clone()) .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap())) } + + pub fn drop_glue(&self, db: &dyn HirDatabase) -> DropGlue { + db.has_drop_glue(self.ty.clone(), self.env.clone()) + } } #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index 95a720e7e452..9a3e77f3a932 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -38,6 +38,7 @@ pub struct HoverConfig { pub max_fields_count: Option, pub max_enum_variants_count: Option, pub max_subst_ty_len: SubstTyLen, + pub show_drop_glue: bool, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index c996230c3a1f..c5a83e58cea1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -3,7 +3,7 @@ use std::{env, mem, ops::Not}; use either::Either; use hir::{ - db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind, + db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind, DropGlue, DynCompatibilityViolation, HasCrate, HasSource, HirDisplay, Layout, LayoutError, MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef, }; @@ -629,6 +629,89 @@ pub(super) fn definition( _ => None, }; + let drop_info = || { + if !config.show_drop_glue { + return None; + } + let drop_info = match def { + Definition::Field(field) => { + DropInfo { drop_glue: field.ty(db).drop_glue(db), has_dtor: None } + } + Definition::Adt(Adt::Struct(strukt)) => { + let struct_drop_glue = strukt.ty_placeholders(db).drop_glue(db); + let mut fields_drop_glue = strukt + .fields(db) + .iter() + .map(|field| field.ty(db).drop_glue(db)) + .max() + .unwrap_or(DropGlue::None); + let has_dtor = match (fields_drop_glue, struct_drop_glue) { + (DropGlue::None, _) => struct_drop_glue != DropGlue::None, + (_, DropGlue::None) => { + // This is `ManuallyDrop`. + fields_drop_glue = DropGlue::None; + false + } + (_, _) => struct_drop_glue > fields_drop_glue, + }; + DropInfo { drop_glue: fields_drop_glue, has_dtor: Some(has_dtor) } + } + // Unions cannot have fields with drop glue. + Definition::Adt(Adt::Union(union)) => DropInfo { + drop_glue: DropGlue::None, + has_dtor: Some(union.ty_placeholders(db).drop_glue(db) != DropGlue::None), + }, + Definition::Adt(Adt::Enum(enum_)) => { + let enum_drop_glue = enum_.ty_placeholders(db).drop_glue(db); + let fields_drop_glue = enum_ + .variants(db) + .iter() + .map(|variant| { + variant + .fields(db) + .iter() + .map(|field| field.ty(db).drop_glue(db)) + .max() + .unwrap_or(DropGlue::None) + }) + .max() + .unwrap_or(DropGlue::None); + DropInfo { + drop_glue: fields_drop_glue, + has_dtor: Some(enum_drop_glue > fields_drop_glue), + } + } + Definition::Variant(variant) => { + let fields_drop_glue = variant + .fields(db) + .iter() + .map(|field| field.ty(db).drop_glue(db)) + .max() + .unwrap_or(DropGlue::None); + DropInfo { drop_glue: fields_drop_glue, has_dtor: None } + } + Definition::TypeAlias(type_alias) => { + DropInfo { drop_glue: type_alias.ty_placeholders(db).drop_glue(db), has_dtor: None } + } + Definition::Local(local) => { + DropInfo { drop_glue: local.ty(db).drop_glue(db), has_dtor: None } + } + _ => return None, + }; + let rendered_drop_glue = match drop_info.drop_glue { + DropGlue::None => "does not contain types with destructors (drop glue)", + DropGlue::DependOnParams => { + "may contain types with destructors (drop glue) depending on type parameters" + } + DropGlue::HasDropGlue => "contain types with destructors (drop glue)", + }; + Some(match drop_info.has_dtor { + Some(true) => format!("{}; has a destructor", rendered_drop_glue), + Some(false) => format!("{}; doesn't have a destructor", rendered_drop_glue), + None => rendered_drop_glue.to_owned(), + }) + }; + let dyn_compatibility_info = || match def { Definition::Trait(it) => { let mut dyn_compatibility_info = String::new(); @@ -661,6 +744,10 @@ pub(super) fn definition( extra.push_str("\n___\n"); extra.push_str(&dyn_compatibility_info); } + if let Some(drop_info) = drop_info() { + extra.push_str("\n___\n"); + extra.push_str(&drop_info); + } } let mut desc = String::new(); desc.push_str(&label); @@ -703,6 +790,12 @@ pub(super) fn definition( ) } +#[derive(Debug)] +struct DropInfo { + drop_glue: DropGlue, + has_dtor: Option, +} + pub(super) fn literal( sema: &Semantics<'_, RootDatabase>, token: SyntaxToken, diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 8c32cc9720af..7c720d97cb6d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -21,6 +21,7 @@ const HOVER_BASE_CONFIG: HoverConfig = HoverConfig { max_fields_count: Some(5), max_enum_variants_count: Some(5), max_subst_ty_len: super::SubstTyLen::Unlimited, + show_drop_glue: true, }; fn check_hover_no_result(#[rust_analyzer::rust_fixture] ra_fixture: &str) { @@ -567,6 +568,10 @@ fn main() { --- size = 8, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -812,6 +817,10 @@ struct Foo { fiel$0d_a: u8, field_b: i32, field_c: i16 } --- size = 1, align = 1, offset = 6 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -863,6 +872,10 @@ fn main() { --- size = 4, align = 4, offset = 0 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -933,6 +946,10 @@ struct Foo$0(pub u32) where u32: Copy; --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -959,6 +976,10 @@ struct Foo$0 { field: u32 } --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check( @@ -984,6 +1005,10 @@ struct Foo$0 where u32: Copy { field: u32 } --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1013,6 +1038,10 @@ fn hover_record_struct_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1036,6 +1065,10 @@ fn hover_record_struct_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1062,6 +1095,10 @@ fn hover_record_struct_limit() { --- size = 16 (0x10), align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1083,6 +1120,10 @@ fn hover_record_struct_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1104,6 +1145,10 @@ fn hover_record_struct_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); @@ -1127,6 +1172,10 @@ fn hover_record_struct_limit() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1152,6 +1201,10 @@ fn hover_record_variant_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_fields_limit( @@ -1173,6 +1226,10 @@ fn hover_record_variant_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_fields_limit( @@ -1194,6 +1251,10 @@ fn hover_record_variant_limit() { --- size = 16 (0x10), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_fields_limit( @@ -1215,6 +1276,10 @@ fn hover_record_variant_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_fields_limit( @@ -1236,6 +1301,10 @@ fn hover_record_variant_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -1262,6 +1331,10 @@ fn hover_enum_limit() { --- size = 1, align = 1, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_enum_variants_limit( @@ -1284,6 +1357,10 @@ fn hover_enum_limit() { --- size = 1, align = 1, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_enum_variants_limit( @@ -1303,6 +1380,10 @@ fn hover_enum_limit() { --- size = 1, align = 1, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_enum_variants_limit( @@ -1322,6 +1403,10 @@ fn hover_enum_limit() { --- size = 1, align = 1, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_enum_variants_limit( @@ -1359,6 +1444,10 @@ fn hover_enum_limit() { --- size = 12 (0xC), align = 4, niches = a lot + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1385,6 +1474,10 @@ fn hover_union_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1407,6 +1500,10 @@ fn hover_union_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1426,6 +1523,10 @@ fn hover_union_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1445,6 +1546,10 @@ fn hover_union_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1471,6 +1576,10 @@ struct Foo$0 where u32: Copy; --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1493,6 +1602,10 @@ type Fo$0o: Trait = S where T: Trait; where T: Trait, ``` + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -1642,6 +1755,10 @@ fn main() { --- size = 8, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_range( @@ -1697,6 +1814,10 @@ fn main() { let b$0ar = Some(12); } --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -1724,6 +1845,10 @@ enum Option { --- + does not contain types with destructors (drop glue) + + --- + The None variant "#]], ); @@ -1784,6 +1909,10 @@ fn hover_for_local_variable_pat() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ) } @@ -1816,6 +1945,10 @@ fn hover_for_param_edge() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ) } @@ -1838,6 +1971,10 @@ fn hover_for_param_with_multiple_traits() { ```rust _x: impl Deref + DerefMut ``` + + --- + + may contain types with destructors (drop glue) depending on type parameters "#]], ) } @@ -1864,6 +2001,10 @@ fn main() { let foo_$0test = Thing::new(); } --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ) } @@ -2613,6 +2754,10 @@ fn test_hover_function_pointer_show_identifiers() { --- size = 8, align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -2635,6 +2780,10 @@ fn test_hover_function_pointer_no_identifier() { --- size = 8, align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -2881,6 +3030,10 @@ pub struct B$0ar --- + does not contain types with destructors (drop glue); doesn't have a destructor + + --- + [external](https://www.google.com) "#]], ); @@ -2912,6 +3065,10 @@ pub struct B$0ar --- + does not contain types with destructors (drop glue); doesn't have a destructor + + --- + [baz](Baz) "#]], ); @@ -3002,6 +3159,10 @@ fn test_hover_layout_of_variant() { --- size = 4, align = 2 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -3023,6 +3184,10 @@ fn test_hover_layout_of_variant_generic() { ```rust None ``` + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -3048,6 +3213,10 @@ struct S$0(core::marker::PhantomData); --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -3076,6 +3245,10 @@ fn test_hover_layout_of_enum() { --- size = 16 (0x10), align = 8, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -3094,6 +3267,10 @@ fn test_hover_no_memory_layout() { ```rust field_a: u8 ``` + + --- + + does not contain types with destructors (drop glue) "#]], ); @@ -4405,6 +4582,10 @@ fn main() { --- + does not contain types with destructors (drop glue) + + --- + ```rust ra_test_fixture::S ``` @@ -4416,6 +4597,10 @@ fn main() { --- size = 4, align = 4, offset = 0 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4441,6 +4626,10 @@ struct S$0T(T); --- size = 0, align = 1 + + --- + + may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor "#]], ); } @@ -4466,6 +4655,10 @@ struct S$0T(T); --- size = 0, align = 1 + + --- + + may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor "#]], ); } @@ -4492,6 +4685,10 @@ struct S$0T(T); --- size = 0, align = 1 + + --- + + may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor "#]], ); } @@ -4516,6 +4713,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4540,6 +4741,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4564,6 +4769,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4588,6 +4797,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4612,6 +4825,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4635,6 +4852,10 @@ impl Foo { --- size = 8, align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4659,6 +4880,10 @@ impl Foo { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -5149,6 +5374,10 @@ type Fo$0o2 = Foo<2>; --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -5202,6 +5431,10 @@ enum E { --- + does not contain types with destructors (drop glue) + + --- + This is a doc "#]], ); @@ -5231,6 +5464,10 @@ enum E { --- + does not contain types with destructors (drop glue) + + --- + This is a doc "#]], ); @@ -5261,6 +5498,10 @@ enum E { --- + does not contain types with destructors (drop glue) + + --- + This is a doc "#]], ); @@ -5291,6 +5532,10 @@ enum E { --- + does not contain types with destructors (drop glue) + + --- + This is a doc "#]], ); @@ -6219,6 +6464,10 @@ fn main() { --- size = 32 (0x20), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -7518,6 +7767,10 @@ enum Enum { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -7544,6 +7797,10 @@ enum Enum { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -8214,6 +8471,10 @@ fn test() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -8863,6 +9124,10 @@ fn main(notable$0: u32) {} --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -8955,6 +9220,10 @@ extern "C" { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -9101,6 +9370,10 @@ struct Pedro$0<'a> { --- size = 16 (0x10), align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ) } @@ -9118,6 +9391,10 @@ fn main(a$0: impl T) {} ```rust a: impl T + ?Sized ``` + + --- + + may contain types with destructors (drop glue) depending on type parameters "#]], ); } @@ -9139,6 +9416,10 @@ fn main(a$0: T) {} --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -9192,6 +9473,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -9529,6 +9814,10 @@ type A$0 = B; --- + does not contain types with destructors (drop glue) + + --- + *This is the documentation for* `struct B` Docs for B @@ -9562,6 +9851,10 @@ type A$0 = B; --- + does not contain types with destructors (drop glue) + + --- + *This is the documentation for* `struct C` Docs for C @@ -9596,6 +9889,10 @@ type A$0 = B; --- + does not contain types with destructors (drop glue) + + --- + *This is the documentation for* `struct C` Docs for C @@ -9625,6 +9922,10 @@ type A$0 = B; --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); @@ -9749,6 +10050,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); @@ -9777,6 +10082,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); @@ -9812,6 +10121,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -10134,6 +10447,10 @@ fn bar() { --- + does not contain types with destructors (drop glue) + + --- + ```rust ra_test_fixture::Foo ``` @@ -10144,6 +10461,10 @@ fn bar() { --- + may contain types with destructors (drop glue) depending on type parameters + + --- + `T` = `i32` "#]], ); @@ -10353,3 +10674,276 @@ macro_rules! str { "#]], ); } + +#[test] +fn drop_glue() { + check( + r#" +struct NoDrop$0; + "#, + expect![[r#" + *NoDrop* + + ```rust + ra_test_fixture + ``` + + ```rust + struct NoDrop + ``` + + --- + + size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); + check( + r#" +//- minicore: drop +struct NeedsDrop$0; +impl Drop for NeedsDrop { + fn drop(&mut self) {} +} + "#, + expect![[r#" + *NeedsDrop* + + ```rust + ra_test_fixture + ``` + + ```rust + struct NeedsDrop + ``` + + --- + + size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); has a destructor + "#]], + ); + check( + r#" +//- minicore: manually_drop, drop +struct NeedsDrop; +impl Drop for NeedsDrop { + fn drop(&mut self) {} +} +type NoDrop$0 = core::mem::ManuallyDrop; + "#, + expect![[r#" + *NoDrop* + + ```rust + ra_test_fixture + ``` + + ```rust + type NoDrop = core::mem::ManuallyDrop + ``` + + --- + + size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) + "#]], + ); + check( + r#" +//- minicore: drop +struct NeedsDrop; +impl Drop for NeedsDrop { + fn drop(&mut self) {} +} +struct DropField$0 { + _x: i32, + _y: NeedsDrop, +} + "#, + expect![[r#" + *DropField* + + ```rust + ra_test_fixture + ``` + + ```rust + struct DropField { + _x: i32, + _y: NeedsDrop, + } + ``` + + --- + + size = 4, align = 4 + + --- + + contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); + check( + r#" +//- minicore: sized +type Foo$0 = impl Sized; + "#, + expect![[r#" + *Foo* + + ```rust + ra_test_fixture + ``` + + ```rust + type Foo = impl Sized + ``` + + --- + + contain types with destructors (drop glue) + "#]], + ); + check( + r#" +//- minicore: drop +struct NeedsDrop; +impl Drop for NeedsDrop { + fn drop(&mut self) {} +} +enum Enum { + A$0(&'static str), + B(NeedsDrop) +} + "#, + expect![[r#" + *A* + + ```rust + ra_test_fixture::Enum + ``` + + ```rust + A(&'static str) + ``` + + --- + + size = 16 (0x10), align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue) + "#]], + ); + check( + r#" +struct Foo$0(T); + "#, + expect![[r#" + *Foo* + + ```rust + ra_test_fixture + ``` + + ```rust + struct Foo(T) + ``` + + --- + + may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor + "#]], + ); + check( + r#" +//- minicore: copy +struct Foo$0(T); + "#, + expect![[r#" + *Foo* + + ```rust + ra_test_fixture + ``` + + ```rust + struct Foo(T) + where + T: Copy, + ``` + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); + check( + r#" +//- minicore: copy +trait Trait { + type Assoc: Copy; +} +struct Foo$0(T::Assoc); + "#, + expect![[r#" + *Foo* + + ```rust + ra_test_fixture + ``` + + ```rust + struct Foo(::Assoc) + where + T: Trait, + ``` + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); + check( + r#" +#[rustc_coherence_is_core] + +#[lang = "manually_drop"] +#[repr(transparent)] +pub struct ManuallyDrop$0 { + value: T, +} + "#, + expect![[r#" + *ManuallyDrop* + + ```rust + ra_test_fixture + ``` + + ```rust + pub struct ManuallyDrop + where + T: ?Sized, + { + value: T, + } + ``` + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 07553a87d28f..41957bad7e07 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -187,6 +187,7 @@ impl StaticIndex<'_> { max_fields_count: Some(5), max_enum_variants_count: Some(5), max_subst_ty_len: SubstTyLen::Unlimited, + show_drop_glue: true, }; let tokens = tokens.filter(|token| { matches!( diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index d7e9a5c586c9..5c7b088e680d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -128,6 +128,8 @@ config_data! { /// Whether to show keyword hover popups. Only applies when /// `#rust-analyzer.hover.documentation.enable#` is set. hover_documentation_keywords_enable: bool = true, + /// Whether to show drop glue information on hover. + hover_dropGlue_enable: bool = true, /// Use markdown syntax for links on hover. hover_links_enable: bool = true, /// Whether to show what types are used as generic arguments in calls etc. on hover, and what is their max length to show such types, beyond it they will be shown with ellipsis. @@ -1630,6 +1632,7 @@ impl Config { Some(MaxSubstitutionLength::Limit(limit)) => ide::SubstTyLen::LimitTo(*limit), None => ide::SubstTyLen::Unlimited, }, + show_drop_glue: *self.hover_dropGlue_enable(), } } diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index 0c6674b1408e..1cbe51836f47 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -559,6 +559,11 @@ also need to add the folders to Code's `files.watcherExclude`. `#rust-analyzer.hover.documentation.enable#` is set. +**rust-analyzer.hover.dropGlue.enable** (default: true) + + Whether to show drop glue information on hover. + + **rust-analyzer.hover.links.enable** (default: true) Use markdown syntax for links on hover. diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 3f09033051ba..a7c8506a45e6 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -1641,6 +1641,16 @@ } } }, + { + "title": "hover", + "properties": { + "rust-analyzer.hover.dropGlue.enable": { + "markdownDescription": "Whether to show drop glue information on hover.", + "default": true, + "type": "boolean" + } + } + }, { "title": "hover", "properties": { From 639b7134df7a43d01d2c9964eab4c9d8881d3372 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 17 Feb 2025 05:08:57 +0000 Subject: [PATCH 156/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index dbf61312b5d3..0ea62d4d8502 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -500a686ba8bb1b51df7e7f8f81d286b2e20209ff +d1fb81e8dd5354ddf7cb334d5a234cab7f64b3bb From 822e45b1862956eb51fd3624604cbc6abf89f49a Mon Sep 17 00:00:00 2001 From: Fridtjof Stoldt Date: Mon, 17 Feb 2025 11:55:44 +0100 Subject: [PATCH 157/991] "Typo Catch Check" passed by @flip1995 This was *totally* intentional to check if this would get caught :P Co-authored-by: Philipp Krones --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f7e5ae92ca8..f25c5b061f4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,7 @@ Current stable, released 2025-02-20 [if_let_rescope](https://github.com/rust-lang/rust/issues/131154) was stabilized [#13695](https://github.com/rust-lang/rust-clippy/pull/13695) * [`format_in_format_args`], [`recursive_format_impl`], [`to_string_in_format_args`], - [`uninlined_format_args`], [`unused_format_specs`]: Can now support 3er party format macros + [`uninlined_format_args`], [`unused_format_specs`]: Can now support 3rd party format macros if they're marked with the `#[clippy::format_args]` attribute [#9948](https://github.com/rust-lang/rust-clippy/pull/9948) From dcc3d0fac937e80309e88473b8693a1b07b4cc1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 12:55:29 +0100 Subject: [PATCH 158/991] Implement CI tooling in Rust --- src/ci/citool/Cargo.lock | 345 ++++++++++++++++++++++++++++++++++++++ src/ci/citool/Cargo.toml | 13 ++ src/ci/citool/README.md | 2 + src/ci/citool/src/main.rs | 293 ++++++++++++++++++++++++++++++++ 4 files changed, 653 insertions(+) create mode 100644 src/ci/citool/Cargo.lock create mode 100644 src/ci/citool/Cargo.toml create mode 100644 src/ci/citool/README.md create mode 100644 src/ci/citool/src/main.rs diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock new file mode 100644 index 000000000000..d7931af464e1 --- /dev/null +++ b/src/ci/citool/Cargo.lock @@ -0,0 +1,345 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + +[[package]] +name = "citool" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "serde", + "serde_json", + "serde_yaml", +] + +[[package]] +name = "clap" +version = "4.5.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "once_cell" +version = "1.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" + +[[package]] +name = "proc-macro2" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml new file mode 100644 index 000000000000..40c6e5b4dc22 --- /dev/null +++ b/src/ci/citool/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "citool" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1" +clap = { version = "4.5", features = ["derive"] } +serde = { version = "1", features = ["derive"] } +serde_yaml = "0.9" +serde_json = "1" + +[workspace] diff --git a/src/ci/citool/README.md b/src/ci/citool/README.md new file mode 100644 index 000000000000..685a255f1525 --- /dev/null +++ b/src/ci/citool/README.md @@ -0,0 +1,2 @@ +# CI tooling +This is a simple Rust script that determines which jobs should be executed on CI based on the situation (pull request, try job, merge attempt). It also provides a simple way of executing (some) CI jobs locally. diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs new file mode 100644 index 000000000000..5f0202e9c34b --- /dev/null +++ b/src/ci/citool/src/main.rs @@ -0,0 +1,293 @@ +use std::collections::HashMap; +use std::path::Path; + +use anyhow::Context; +use clap::Parser; +use serde_yaml::Value; + +const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); +const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml"); + +/// Representation of a job loaded from the jobs.yml file. +#[derive(serde::Deserialize, Debug, Clone)] +struct Job { + /// Name of the job, e.g. mingw-check + name: String, + /// GitHub runner on which the job should be executed + os: String, + env: HashMap, + /// Should the job be only executed on a specific channel? + #[serde(default)] + only_on_channel: Option, + /// Rest of attributes that will be passed through to GitHub actions + #[serde(flatten)] + extra_keys: HashMap, +} + +#[derive(serde::Deserialize, Debug)] +struct JobEnvironments { + #[serde(rename = "pr")] + pr_env: HashMap, + #[serde(rename = "try")] + try_env: HashMap, + #[serde(rename = "auto")] + auto_env: HashMap, +} + +#[derive(serde::Deserialize, Debug)] +struct JobDatabase { + #[serde(rename = "pr")] + pr_jobs: Vec, + #[serde(rename = "try")] + try_jobs: Vec, + #[serde(rename = "auto")] + auto_jobs: Vec, + + /// Shared environments for the individual run types. + envs: JobEnvironments, +} + +impl JobDatabase { + fn find_auto_job_by_name(&self, name: &str) -> Option { + self.auto_jobs.iter().find(|j| j.name == name).cloned() + } +} + +fn load_job_db(path: &Path) -> anyhow::Result { + let db = std::fs::read_to_string(path)?; + let mut db: Value = serde_yaml::from_str(&db)?; + + // We need to expand merge keys (<<), because serde_yaml can't deal with them + // `apply_merge` only applies the merge once, so do it a few times to unwrap nested merges. + db.apply_merge()?; + db.apply_merge()?; + + let db: JobDatabase = serde_yaml::from_value(db)?; + Ok(db) +} + +/// Representation of a job outputted to a GitHub Actions workflow. +#[derive(serde::Serialize, Debug)] +struct GithubActionsJob { + name: String, + full_name: String, + os: String, + env: HashMap, + #[serde(flatten)] + extra_keys: HashMap, +} + +/// Type of workflow that is being executed on CI +#[derive(Debug)] +enum RunType { + /// Workflows that run after a push to a PR branch + PullRequest, + /// Try run started with @bors try + TryJob { custom_jobs: Option> }, + /// Merge attempt workflow + AutoJob, +} + +struct GitHubContext { + event_name: String, + branch_ref: String, + commit_message: Option, +} + +impl GitHubContext { + fn get_run_type(&self) -> Option { + if self.event_name == "pull_request" { + return Some(RunType::PullRequest); + } else if self.event_name == "push" { + let is_try_build = + ["refs/heads/try", "refs/heads/try-perf", "refs/heads/automation/bors/try"] + .iter() + .any(|r| **r == self.branch_ref); + // Unrolled branch from a rollup for testing perf + // This should **not** allow custom try jobs + let is_unrolled_perf_build = self.branch_ref == "refs/heads/try-perf"; + if is_try_build { + let custom_jobs = + if !is_unrolled_perf_build { Some(self.get_custom_jobs()) } else { None }; + return Some(RunType::TryJob { custom_jobs }); + } + + if self.branch_ref == "refs/heads/auto" { + return Some(RunType::AutoJob); + } + } + None + } + + /// Tries to parse names of specific CI jobs that should be executed in the form of + /// try-job: + /// from the commit message of the passed GitHub context. + fn get_custom_jobs(&self) -> Vec { + if let Some(ref msg) = self.commit_message { + msg.lines() + .filter_map(|line| line.trim().strip_prefix("try-job: ")) + .map(|l| l.to_string()) + .collect() + } else { + vec![] + } + } +} + +fn load_env_var(name: &str) -> anyhow::Result { + std::env::var(name).with_context(|| format!("Cannot find variable {name}")) +} + +fn load_github_ctx() -> anyhow::Result { + let event_name = load_env_var("GITHUB_EVENT_NAME")?; + let commit_message = + if event_name == "push" { Some(load_env_var("COMMIT_MESSAGE")?) } else { None }; + + Ok(GitHubContext { event_name, branch_ref: load_env_var("GITHUB_REF")?, commit_message }) +} + +/// Skip CI jobs that are not supposed to be executed on the given `channel`. +fn skip_jobs(jobs: Vec, channel: &str) -> Vec { + jobs.into_iter() + .filter(|job| { + job.only_on_channel.is_none() || job.only_on_channel.as_deref() == Some(channel) + }) + .collect() +} + +fn to_string_map(map: &HashMap) -> HashMap { + map.iter() + .map(|(key, value)| { + ( + key.clone(), + serde_yaml::to_string(value) + .expect("Cannot serialize YAML value to string") + .trim() + .to_string(), + ) + }) + .collect() +} + +fn calculate_jobs( + run_type: &RunType, + db: &JobDatabase, + channel: &str, +) -> anyhow::Result> { + let (jobs, prefix, base_env) = match run_type { + RunType::PullRequest => (db.pr_jobs.clone(), "PR", &db.envs.pr_env), + RunType::TryJob { custom_jobs } => { + let jobs = if let Some(custom_jobs) = custom_jobs { + if custom_jobs.len() > 10 { + return Err(anyhow::anyhow!( + "It is only possible to schedule up to 10 custom jobs, received {} custom jobs", + custom_jobs.len() + )); + } + + let mut jobs = vec![]; + let mut unknown_jobs = vec![]; + for custom_job in custom_jobs { + if let Some(job) = db.find_auto_job_by_name(custom_job) { + jobs.push(job); + } else { + unknown_jobs.push(custom_job.clone()); + } + } + if !unknown_jobs.is_empty() { + return Err(anyhow::anyhow!( + "Custom job(s) `{}` not found in auto jobs", + unknown_jobs.join(", ") + )); + } + jobs + } else { + db.try_jobs.clone() + }; + (jobs, "try", &db.envs.try_env) + } + RunType::AutoJob => (db.auto_jobs.clone(), "auto", &db.envs.auto_env), + }; + let jobs = skip_jobs(jobs, channel); + let jobs = jobs + .into_iter() + .map(|job| { + let mut env: HashMap = to_string_map(base_env); + env.extend(to_string_map(&job.env)); + let full_name = format!("{prefix} - {}", job.name); + + GithubActionsJob { + name: job.name, + full_name, + os: job.os, + env, + extra_keys: job + .extra_keys + .into_iter() + .map(|(key, value)| { + ( + key, + serde_json::to_value(&value) + .expect("Cannot convert extra key value from YAML to JSON"), + ) + }) + .collect(), + } + }) + .collect(); + + Ok(jobs) +} + +fn calculate_job_matrix( + db: JobDatabase, + gh_ctx: GitHubContext, + channel: &str, +) -> anyhow::Result<()> { + let run_type = gh_ctx.get_run_type().ok_or_else(|| { + anyhow::anyhow!("Cannot determine the type of workflow that is being executed") + })?; + eprintln!("Run type: {run_type:?}"); + + let jobs = calculate_jobs(&run_type, &db, channel)?; + if jobs.is_empty() { + return Err(anyhow::anyhow!("Computed job list is empty")); + } + + let run_type = match run_type { + RunType::PullRequest => "pr", + RunType::TryJob { .. } => "try", + RunType::AutoJob => "auto", + }; + + eprintln!("Output:\njobs={jobs:?}\nrun_type={run_type}"); + println!("jobs={}", serde_json::to_string(&jobs)?); + println!("run_type={run_type}"); + + Ok(()) +} + +#[derive(clap::Parser)] +enum Args { + /// Calculate a list of jobs that should be executed on CI. + /// Should only be used on CI inside GitHub actions. + CalculateJobMatrix, +} + +fn main() -> anyhow::Result<()> { + let args = Args::parse(); + let db = load_job_db(Path::new(JOBS_YML_PATH)).context("Cannot load jobs.yml")?; + + match args { + Args::CalculateJobMatrix => { + let gh_ctx = load_github_ctx() + .context("Cannot load environment variables from GitHub Actions")?; + let channel = std::fs::read_to_string(Path::new(CI_DIRECTORY).join("channel")) + .context("Cannot read channel file")?; + + calculate_job_matrix(db, gh_ctx, &channel).context("Failed to calculate job matrix")?; + } + } + + Ok(()) +} From 4f0141f6652058f03d76f3ff6195bc4bce13c2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 12:55:34 +0100 Subject: [PATCH 159/991] Add missing base-job directive --- src/ci/github-actions/jobs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 64e64867de26..bbcc01a0c299 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -51,9 +51,11 @@ runners: # Free some disk space to avoid running out of space during the build. free_disk: true os: ubuntu-24.04-arm + <<: *base-job - &job-aarch64-linux-8c os: ubuntu-22.04-arm64-8core-32gb + <<: *base-job envs: env-x86_64-apple-tests: &env-x86_64-apple-tests SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact From a789f9e283e26e07a10680dad0d4533b5a33ded9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 13:13:33 +0100 Subject: [PATCH 160/991] Add local job execution to `citool` --- src/ci/citool/src/main.rs | 82 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 5f0202e9c34b..d01e32bb575e 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -1,11 +1,13 @@ use std::collections::HashMap; use std::path::Path; +use std::process::Command; use anyhow::Context; use clap::Parser; use serde_yaml::Value; const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); +const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker"); const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml"); /// Representation of a job loaded from the jobs.yml file. @@ -24,6 +26,21 @@ struct Job { extra_keys: HashMap, } +impl Job { + fn is_linux(&self) -> bool { + self.os.contains("ubuntu") + } + + /// By default, the Docker image of a job is based on its name. + /// However, it can be overridden by its IMAGE environment variable. + fn image(&self) -> String { + self.env + .get("IMAGE") + .map(|v| v.as_str().expect("IMAGE value should be a string").to_string()) + .unwrap_or_else(|| self.name.clone()) + } +} + #[derive(serde::Deserialize, Debug)] struct JobEnvironments { #[serde(rename = "pr")] @@ -267,11 +284,75 @@ fn calculate_job_matrix( Ok(()) } +fn find_linux_job<'a>(jobs: &'a [Job], name: &str) -> anyhow::Result<&'a Job> { + let Some(job) = jobs.iter().find(|j| j.name == name) else { + let available_jobs: Vec<&Job> = jobs.iter().filter(|j| j.is_linux()).collect(); + let mut available_jobs = + available_jobs.iter().map(|j| j.name.to_string()).collect::>(); + available_jobs.sort(); + return Err(anyhow::anyhow!( + "Job {name} not found. The following jobs are available:\n{}", + available_jobs.join(", ") + )); + }; + if !job.is_linux() { + return Err(anyhow::anyhow!("Only Linux jobs can be executed locally")); + } + + Ok(job) +} + +fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> anyhow::Result<()> { + let jobs = match job_type { + JobType::Auto => &db.auto_jobs, + JobType::PR => &db.pr_jobs, + }; + let job = find_linux_job(&jobs, &name).with_context(|| format!("Cannot find job {name}"))?; + + let mut custom_env: HashMap = HashMap::new(); + // Replicate src/ci/scripts/setup-environment.sh + // Adds custom environment variables to the job + if name.starts_with("dist-") { + if name.ends_with("-alt") { + custom_env.insert("DEPLOY_ALT".to_string(), "1".to_string()); + } else { + custom_env.insert("DEPLOY".to_string(), "1".to_string()); + } + } + custom_env.extend(to_string_map(&job.env)); + + let mut cmd = Command::new(Path::new(DOCKER_DIRECTORY).join("run.sh")); + cmd.arg(job.image()); + cmd.envs(custom_env); + + eprintln!("Executing {cmd:?}"); + + let result = cmd.spawn()?.wait()?; + if !result.success() { Err(anyhow::anyhow!("Job failed")) } else { Ok(()) } +} + #[derive(clap::Parser)] enum Args { /// Calculate a list of jobs that should be executed on CI. /// Should only be used on CI inside GitHub actions. CalculateJobMatrix, + /// Execute a given CI job locally. + #[clap(name = "run-local")] + RunJobLocally { + /// Name of the job that should be executed. + name: String, + /// Type of the job that should be executed. + #[clap(long = "type", default_value = "auto")] + job_type: JobType, + }, +} + +#[derive(clap::ValueEnum, Clone)] +enum JobType { + /// Merge attempt ("auto") job + Auto, + /// Pull request job + PR, } fn main() -> anyhow::Result<()> { @@ -287,6 +368,7 @@ fn main() -> anyhow::Result<()> { calculate_job_matrix(db, gh_ctx, &channel).context("Failed to calculate job matrix")?; } + Args::RunJobLocally { job_type, name } => run_workflow_locally(db, job_type, name)?, } Ok(()) From 87c49f025f55c7efac5db30501f7a5255eba895b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 13:14:42 +0100 Subject: [PATCH 161/991] Use citool in CI --- .github/workflows/ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0934e42b277e..b936028fa2e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,8 @@ # This file defines our primary CI workflow that runs on pull requests # and also on pushes to special branches (auto, try). # -# The actual definition of the executed jobs is calculated by a Python -# script located at src/ci/github-actions/ci.py, which +# The actual definition of the executed jobs is calculated by a +# script located at src/ci/citool, which # uses job definition data from src/ci/github-actions/jobs.yml. # You should primarily modify the `jobs.yml` file if you want to modify # what jobs are executed in CI. @@ -56,7 +56,9 @@ jobs: - name: Calculate the CI job matrix env: COMMIT_MESSAGE: ${{ github.event.head_commit.message }} - run: python3 src/ci/github-actions/ci.py calculate-job-matrix >> $GITHUB_OUTPUT + run: | + cd src/ci/citool + cargo run calculate-job-matrix >> $GITHUB_OUTPUT id: jobs job: name: ${{ matrix.full_name }} From 1a0970d4ce5c10a830cb12581edc73a08cd88b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 13:14:49 +0100 Subject: [PATCH 162/991] Delete the previous Python script --- src/ci/github-actions/ci.py | 318 ------------------------------------ 1 file changed, 318 deletions(-) delete mode 100755 src/ci/github-actions/ci.py diff --git a/src/ci/github-actions/ci.py b/src/ci/github-actions/ci.py deleted file mode 100755 index c93766ef33a0..000000000000 --- a/src/ci/github-actions/ci.py +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/env python3 - -""" -This script contains CI functionality. -It can be used to generate a matrix of jobs that should -be executed on CI, or run a specific CI job locally. - -It reads job definitions from `src/ci/github-actions/jobs.yml`. -""" - -import argparse -import dataclasses -import json -import logging -import os -import re -import subprocess -import typing -from pathlib import Path -from typing import List, Dict, Any, Optional - -import yaml - -CI_DIR = Path(__file__).absolute().parent.parent -JOBS_YAML_PATH = Path(__file__).absolute().parent / "jobs.yml" - -Job = Dict[str, Any] - - -def add_job_properties(jobs: List[Dict], prefix: str) -> List[Job]: - """ - Modify the `name` attribute of each job, based on its base name and the given `prefix`. - Add an `image` attribute to each job, based on its image. - """ - modified_jobs = [] - for job in jobs: - # Create a copy of the `job` dictionary to avoid modifying `jobs` - new_job = dict(job) - new_job["image"] = get_job_image(new_job) - new_job["full_name"] = f"{prefix} - {new_job['name']}" - modified_jobs.append(new_job) - return modified_jobs - - -def add_base_env(jobs: List[Job], environment: Dict[str, str]) -> List[Job]: - """ - Prepends `environment` to the `env` attribute of each job. - The `env` of each job has higher precedence than `environment`. - """ - modified_jobs = [] - for job in jobs: - env = environment.copy() - env.update(job.get("env", {})) - - new_job = dict(job) - new_job["env"] = env - modified_jobs.append(new_job) - return modified_jobs - - -@dataclasses.dataclass -class PRRunType: - pass - - -@dataclasses.dataclass -class TryRunType: - custom_jobs: List[str] - - -@dataclasses.dataclass -class AutoRunType: - pass - - -WorkflowRunType = typing.Union[PRRunType, TryRunType, AutoRunType] - - -@dataclasses.dataclass -class GitHubCtx: - event_name: str - ref: str - repository: str - commit_message: Optional[str] - - -def get_custom_jobs(ctx: GitHubCtx) -> List[str]: - """ - Tries to parse names of specific CI jobs that should be executed in the form of - try-job: - from the commit message of the passed GitHub context. - """ - if ctx.commit_message is None: - return [] - - regex = re.compile(r"^try-job: (.*)", re.MULTILINE) - jobs = [] - for match in regex.finditer(ctx.commit_message): - jobs.append(match.group(1)) - return jobs - - -def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]: - if ctx.event_name == "pull_request": - return PRRunType() - elif ctx.event_name == "push": - try_build = ctx.ref in ( - "refs/heads/try", - "refs/heads/try-perf", - "refs/heads/automation/bors/try", - ) - - # Unrolled branch from a rollup for testing perf - # This should **not** allow custom try jobs - is_unrolled_perf_build = ctx.ref == "refs/heads/try-perf" - - if try_build: - custom_jobs = [] - if not is_unrolled_perf_build: - custom_jobs = get_custom_jobs(ctx) - return TryRunType(custom_jobs=custom_jobs) - - if ctx.ref == "refs/heads/auto": - return AutoRunType() - - return None - - -def calculate_jobs(run_type: WorkflowRunType, job_data: Dict[str, Any]) -> List[Job]: - if isinstance(run_type, PRRunType): - return add_base_env( - add_job_properties(job_data["pr"], "PR"), job_data["envs"]["pr"] - ) - elif isinstance(run_type, TryRunType): - jobs = job_data["try"] - custom_jobs = run_type.custom_jobs - if custom_jobs: - if len(custom_jobs) > 10: - raise Exception( - f"It is only possible to schedule up to 10 custom jobs, " - f"received {len(custom_jobs)} jobs" - ) - - jobs = [] - unknown_jobs = [] - for custom_job in custom_jobs: - job = [j for j in job_data["auto"] if j["name"] == custom_job] - if not job: - unknown_jobs.append(custom_job) - continue - jobs.append(job[0]) - if unknown_jobs: - raise Exception( - f"Custom job(s) `{unknown_jobs}` not found in auto jobs" - ) - - return add_base_env(add_job_properties(jobs, "try"), job_data["envs"]["try"]) - elif isinstance(run_type, AutoRunType): - return add_base_env( - add_job_properties(job_data["auto"], "auto"), job_data["envs"]["auto"] - ) - - return [] - - -def skip_jobs(jobs: List[Dict[str, Any]], channel: str) -> List[Job]: - """ - Skip CI jobs that are not supposed to be executed on the given `channel`. - """ - return [j for j in jobs if j.get("only_on_channel", channel) == channel] - - -def get_github_ctx() -> GitHubCtx: - event_name = os.environ["GITHUB_EVENT_NAME"] - - commit_message = None - if event_name == "push": - commit_message = os.environ["COMMIT_MESSAGE"] - return GitHubCtx( - event_name=event_name, - ref=os.environ["GITHUB_REF"], - repository=os.environ["GITHUB_REPOSITORY"], - commit_message=commit_message, - ) - - -def format_run_type(run_type: WorkflowRunType) -> str: - if isinstance(run_type, PRRunType): - return "pr" - elif isinstance(run_type, AutoRunType): - return "auto" - elif isinstance(run_type, TryRunType): - return "try" - else: - raise AssertionError() - - -def get_job_image(job: Job) -> str: - """ - By default, the Docker image of a job is based on its name. - However, it can be overridden by its IMAGE environment variable. - """ - env = job.get("env", {}) - # Return the IMAGE environment variable if it exists, otherwise return the job name - return env.get("IMAGE", job["name"]) - - -def is_linux_job(job: Job) -> bool: - return "ubuntu" in job["os"] - - -def find_linux_job(job_data: Dict[str, Any], job_name: str, pr_jobs: bool) -> Job: - candidates = job_data["pr"] if pr_jobs else job_data["auto"] - jobs = [job for job in candidates if job.get("name") == job_name] - if len(jobs) == 0: - available_jobs = "\n".join( - sorted(job["name"] for job in candidates if is_linux_job(job)) - ) - raise Exception(f"""Job `{job_name}` not found in {'pr' if pr_jobs else 'auto'} jobs. -The following jobs are available: -{available_jobs}""") - assert len(jobs) == 1 - - job = jobs[0] - if not is_linux_job(job): - raise Exception("Only Linux jobs can be executed locally") - return job - - -def run_workflow_locally(job_data: Dict[str, Any], job_name: str, pr_jobs: bool): - DOCKER_DIR = Path(__file__).absolute().parent.parent / "docker" - - job = find_linux_job(job_data, job_name=job_name, pr_jobs=pr_jobs) - - custom_env = {} - # Replicate src/ci/scripts/setup-environment.sh - # Adds custom environment variables to the job - if job_name.startswith("dist-"): - if job_name.endswith("-alt"): - custom_env["DEPLOY_ALT"] = "1" - else: - custom_env["DEPLOY"] = "1" - custom_env.update({k: str(v) for (k, v) in job.get("env", {}).items()}) - - args = [str(DOCKER_DIR / "run.sh"), get_job_image(job)] - env_formatted = [f"{k}={v}" for (k, v) in sorted(custom_env.items())] - print(f"Executing `{' '.join(env_formatted)} {' '.join(args)}`") - - env = os.environ.copy() - env.update(custom_env) - - subprocess.run(args, env=env, check=True) - - -def calculate_job_matrix(job_data: Dict[str, Any]): - github_ctx = get_github_ctx() - - run_type = find_run_type(github_ctx) - logging.info(f"Job type: {run_type}") - - with open(CI_DIR / "channel") as f: - channel = f.read().strip() - - jobs = [] - if run_type is not None: - jobs = calculate_jobs(run_type, job_data) - jobs = skip_jobs(jobs, channel) - - if not jobs: - raise Exception("Scheduled job list is empty, this is an error") - - run_type = format_run_type(run_type) - - logging.info(f"Output:\n{yaml.dump(dict(jobs=jobs, run_type=run_type), indent=4)}") - print(f"jobs={json.dumps(jobs)}") - print(f"run_type={run_type}") - - -def create_cli_parser(): - parser = argparse.ArgumentParser( - prog="ci.py", description="Generate or run CI workflows" - ) - subparsers = parser.add_subparsers( - help="Command to execute", dest="command", required=True - ) - subparsers.add_parser( - "calculate-job-matrix", - help="Generate a matrix of jobs that should be executed in CI", - ) - run_parser = subparsers.add_parser( - "run-local", help="Run a CI jobs locally (on Linux)" - ) - run_parser.add_argument( - "job_name", - help="CI job that should be executed. By default, a merge (auto) " - "job with the given name will be executed", - ) - run_parser.add_argument( - "--pr", action="store_true", help="Run a PR job instead of an auto job" - ) - return parser - - -if __name__ == "__main__": - logging.basicConfig(level=logging.INFO) - - with open(JOBS_YAML_PATH) as f: - data = yaml.safe_load(f) - - parser = create_cli_parser() - args = parser.parse_args() - - if args.command == "calculate-job-matrix": - calculate_job_matrix(data) - elif args.command == "run-local": - run_workflow_locally(data, args.job_name, args.pr) - else: - raise Exception(f"Unknown command {args.command}") From 7f154fa4d1035f9954605dc13d3d257662533e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 13:21:40 +0100 Subject: [PATCH 163/991] Update documentation --- .github/workflows/ci.yml | 4 ++-- src/ci/docker/README.md | 6 +++--- src/doc/rustc-dev-guide/src/building/optimized-build.md | 2 +- src/doc/rustc-dev-guide/src/tests/ci.md | 6 +++--- src/doc/rustc-dev-guide/src/tests/docker.md | 9 +++++++++ 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b936028fa2e7..b01494630b44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,8 @@ # This file defines our primary CI workflow that runs on pull requests # and also on pushes to special branches (auto, try). # -# The actual definition of the executed jobs is calculated by a -# script located at src/ci/citool, which +# The actual definition of the executed jobs is calculated by the +# `src/ci/citool` crate, which # uses job definition data from src/ci/github-actions/jobs.yml. # You should primarily modify the `jobs.yml` file if you want to modify # what jobs are executed in CI. diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 2b1de43c2f68..a1a3a1c37ced 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -8,15 +8,15 @@ Note that a single Docker image can be used by multiple CI jobs, so the job name is the important thing that you should know. You can examine the existing CI jobs in the [`jobs.yml`](../github-actions/jobs.yml) file. -To run a specific CI job locally, you can use the following script: +To run a specific CI job locally, you can use the `citool` Rust crate: ``` -python3 ./src/ci/github-actions/ci.py run-local +cargo --manifest-path src/ci/citool/Cargo.toml run run-local ``` For example, to run the `x86_64-gnu-llvm-18-1` job: ``` -python3 ./src/ci/github-actions/ci.py run-local x86_64-gnu-llvm-18-1 +cargo --manifest-path src/ci/citool/Cargo.toml run run-local x86_64-gnu-llvm-18-1 ``` The job will output artifacts in an `obj/` dir at the root of a repository. Note diff --git a/src/doc/rustc-dev-guide/src/building/optimized-build.md b/src/doc/rustc-dev-guide/src/building/optimized-build.md index 8feda59829b4..f8ca1d0dc391 100644 --- a/src/doc/rustc-dev-guide/src/building/optimized-build.md +++ b/src/doc/rustc-dev-guide/src/building/optimized-build.md @@ -126,4 +126,4 @@ Here is an example of how can `opt-dist` be used locally (outside of CI): [`Environment`]: https://github.com/rust-lang/rust/blob/ee451f8faccf3050c76cdcd82543c917b40c7962/src/tools/opt-dist/src/environment.rs#L5 > Note: if you want to run the actual CI pipeline, instead of running `opt-dist` locally, -> you can execute `python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux`. +> you can execute `cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux`. diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index a4b22392f197..ae6adb678af1 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -28,7 +28,7 @@ Our CI is primarily executed on [GitHub Actions], with a single workflow defined in [`.github/workflows/ci.yml`], which contains a bunch of steps that are unified for all CI jobs that we execute. When a commit is pushed to a corresponding branch or a PR, the workflow executes the -[`src/ci/github-actions/ci.py`] script, which dynamically generates the specific CI +[`src/ci/citool`] crate, which dynamically generates the specific CI jobs that should be executed. This script uses the [`jobs.yml`] file as an input, which contains a declarative configuration of all our CI jobs. @@ -299,7 +299,7 @@ platform’s custom [Docker container]. This has a lot of advantages for us: - We can avoid reinstalling tools (like QEMU or the Android emulator) every time thanks to Docker image caching. - Users can run the same tests in the same environment locally by just running - `python3 src/ci/github-actions/ci.py run-local `, which is awesome to debug failures. Note that there are only linux docker images available locally due to licensing and + `cargo run --manifest-path src/ci/citool/Cargo.toml run-local `, which is awesome to debug failures. Note that there are only linux docker images available locally due to licensing and other restrictions. The docker images prefixed with `dist-` are used for building artifacts while @@ -443,7 +443,7 @@ this: [GitHub Actions]: https://github.com/rust-lang/rust/actions [`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml [`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml -[`src/ci/github-actions/ci.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/ci.py +[`src/ci/citool`]: https://github.com/rust-lang/rust/blob/master/src/ci/citool [rust-lang-ci]: https://github.com/rust-lang-ci/rust/actions [bors]: https://github.com/bors [homu]: https://github.com/rust-lang/homu diff --git a/src/doc/rustc-dev-guide/src/tests/docker.md b/src/doc/rustc-dev-guide/src/tests/docker.md index 2ca08d42130a..a8a388ef90cf 100644 --- a/src/doc/rustc-dev-guide/src/tests/docker.md +++ b/src/doc/rustc-dev-guide/src/tests/docker.md @@ -53,6 +53,15 @@ Some additional notes about using the interactive mode: containers. With the container name, run `docker exec -it /bin/bash` where `` is the container name like `4ba195e95cef`. +The approach described above is a relatively low-level interface for running the Docker images +directly. If you want to run a full CI Linux job locally with Docker, in a way that is as close to CI as possible, you can use the following command: + +```bash +cargo run --manifest-path src/ci/citool/Cargo.toml run-local +# For example: +cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux-alt +``` + [Docker]: https://www.docker.com/ [`src/ci/docker`]: https://github.com/rust-lang/rust/tree/master/src/ci/docker [`src/ci/docker/run.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/run.sh From 3742f0b1901462ea1a96c8713c07586ee72d925c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 14:26:03 +0100 Subject: [PATCH 164/991] Apply review comments --- src/ci/citool/src/main.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index d01e32bb575e..9a22d1264fae 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -10,7 +10,7 @@ const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker"); const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml"); -/// Representation of a job loaded from the jobs.yml file. +/// Representation of a job loaded from the `src/ci/github-actions/jobs.yml` file. #[derive(serde::Deserialize, Debug, Clone)] struct Job { /// Name of the job, e.g. mingw-check @@ -86,7 +86,10 @@ fn load_job_db(path: &Path) -> anyhow::Result { /// Representation of a job outputted to a GitHub Actions workflow. #[derive(serde::Serialize, Debug)] struct GithubActionsJob { + /// The main identifier of the job, used by CI scripts to determine what should be executed. name: String, + /// Helper label displayed in GitHub Actions interface, containing the job name and a run type + /// prefix (PR/try/auto). full_name: String, os: String, env: HashMap, @@ -277,7 +280,9 @@ fn calculate_job_matrix( RunType::AutoJob => "auto", }; - eprintln!("Output:\njobs={jobs:?}\nrun_type={run_type}"); + eprintln!("Output"); + eprintln!("jobs={jobs:?}"); + eprintln!("run_type={run_type}"); println!("jobs={}", serde_json::to_string(&jobs)?); println!("run_type={run_type}"); From 77bd646023118c10d901cb1d521cf00df6358afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 16:19:14 +0100 Subject: [PATCH 165/991] Add comment to [workspace] --- src/ci/citool/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index 40c6e5b4dc22..d6423d7ae4ba 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -10,4 +10,7 @@ serde = { version = "1", features = ["derive"] } serde_yaml = "0.9" serde_json = "1" +# Tell cargo that citool is its own workspace. +# If this is omitted, cargo will look for a workspace elsewhere. +# We want to avoid this, since citool is independent of the other crates. [workspace] From 8083fd4b495236535ac235c890e1b439b6b1f888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 16:34:16 +0100 Subject: [PATCH 166/991] Add tests --- src/ci/citool/Cargo.lock | 70 +++++++++++++++ src/ci/citool/Cargo.toml | 3 + src/ci/citool/src/main.rs | 81 +++++++++-------- src/ci/citool/tests/jobs.rs | 64 +++++++++++++ src/ci/citool/tests/test-jobs.yml | 145 ++++++++++++++++++++++++++++++ 5 files changed, 324 insertions(+), 39 deletions(-) create mode 100644 src/ci/citool/tests/jobs.rs create mode 100644 src/ci/citool/tests/test-jobs.yml diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index d7931af464e1..39b6b44da643 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -64,6 +64,7 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", + "insta", "serde", "serde_json", "serde_yaml", @@ -115,6 +116,24 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "console" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "windows-sys", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "equivalent" version = "1.0.1" @@ -143,6 +162,19 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "insta" +version = "1.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71c1b125e30d93896b365e156c33dadfffab45ee8400afcbba4752f59de08a86" +dependencies = [ + "console", + "linked-hash-map", + "once_cell", + "pin-project", + "similar", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -155,6 +187,18 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "memchr" version = "2.7.4" @@ -167,6 +211,26 @@ version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +[[package]] +name = "pin-project" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.93" @@ -236,6 +300,12 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "strsim" version = "0.11.1" diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index d6423d7ae4ba..e77c67c71477 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -10,6 +10,9 @@ serde = { version = "1", features = ["derive"] } serde_yaml = "0.9" serde_json = "1" +[dev-dependencies] +insta = "1" + # Tell cargo that citool is its own workspace. # If this is omitted, cargo will look for a workspace elsewhere. # We want to avoid this, since citool is independent of the other crates. diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 9a22d1264fae..b8d741004239 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -1,5 +1,5 @@ -use std::collections::HashMap; -use std::path::Path; +use std::collections::BTreeMap; +use std::path::{Path, PathBuf}; use std::process::Command; use anyhow::Context; @@ -17,13 +17,13 @@ struct Job { name: String, /// GitHub runner on which the job should be executed os: String, - env: HashMap, + env: BTreeMap, /// Should the job be only executed on a specific channel? #[serde(default)] only_on_channel: Option, /// Rest of attributes that will be passed through to GitHub actions #[serde(flatten)] - extra_keys: HashMap, + extra_keys: BTreeMap, } impl Job { @@ -44,11 +44,11 @@ impl Job { #[derive(serde::Deserialize, Debug)] struct JobEnvironments { #[serde(rename = "pr")] - pr_env: HashMap, + pr_env: BTreeMap, #[serde(rename = "try")] - try_env: HashMap, + try_env: BTreeMap, #[serde(rename = "auto")] - auto_env: HashMap, + auto_env: BTreeMap, } #[derive(serde::Deserialize, Debug)] @@ -71,7 +71,7 @@ impl JobDatabase { } fn load_job_db(path: &Path) -> anyhow::Result { - let db = std::fs::read_to_string(path)?; + let db = read_to_string(path)?; let mut db: Value = serde_yaml::from_str(&db)?; // We need to expand merge keys (<<), because serde_yaml can't deal with them @@ -92,9 +92,9 @@ struct GithubActionsJob { /// prefix (PR/try/auto). full_name: String, os: String, - env: HashMap, + env: BTreeMap, #[serde(flatten)] - extra_keys: HashMap, + extra_keys: BTreeMap, } /// Type of workflow that is being executed on CI @@ -116,27 +116,17 @@ struct GitHubContext { impl GitHubContext { fn get_run_type(&self) -> Option { - if self.event_name == "pull_request" { - return Some(RunType::PullRequest); - } else if self.event_name == "push" { - let is_try_build = - ["refs/heads/try", "refs/heads/try-perf", "refs/heads/automation/bors/try"] - .iter() - .any(|r| **r == self.branch_ref); - // Unrolled branch from a rollup for testing perf - // This should **not** allow custom try jobs - let is_unrolled_perf_build = self.branch_ref == "refs/heads/try-perf"; - if is_try_build { - let custom_jobs = - if !is_unrolled_perf_build { Some(self.get_custom_jobs()) } else { None }; - return Some(RunType::TryJob { custom_jobs }); - } - - if self.branch_ref == "refs/heads/auto" { - return Some(RunType::AutoJob); + match (self.event_name.as_str(), self.branch_ref.as_str()) { + ("pull_request", _) => Some(RunType::PullRequest), + ("push", "refs/heads/try-perf") => Some(RunType::TryJob { custom_jobs: None }), + ("push", "refs/heads/try" | "refs/heads/automation/bors/try") => { + let custom_jobs = self.get_custom_jobs(); + let custom_jobs = if !custom_jobs.is_empty() { Some(custom_jobs) } else { None }; + Some(RunType::TryJob { custom_jobs }) } + ("push", "refs/heads/auto") => Some(RunType::AutoJob), + _ => None, } - None } /// Tries to parse names of specific CI jobs that should be executed in the form of @@ -175,7 +165,7 @@ fn skip_jobs(jobs: Vec, channel: &str) -> Vec { .collect() } -fn to_string_map(map: &HashMap) -> HashMap { +fn to_string_map(map: &BTreeMap) -> BTreeMap { map.iter() .map(|(key, value)| { ( @@ -232,7 +222,7 @@ fn calculate_jobs( let jobs = jobs .into_iter() .map(|job| { - let mut env: HashMap = to_string_map(base_env); + let mut env: BTreeMap = to_string_map(base_env); env.extend(to_string_map(&job.env)); let full_name = format!("{prefix} - {}", job.name); @@ -312,9 +302,9 @@ fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> any JobType::Auto => &db.auto_jobs, JobType::PR => &db.pr_jobs, }; - let job = find_linux_job(&jobs, &name).with_context(|| format!("Cannot find job {name}"))?; + let job = find_linux_job(jobs, &name).with_context(|| format!("Cannot find job {name}"))?; - let mut custom_env: HashMap = HashMap::new(); + let mut custom_env: BTreeMap = BTreeMap::new(); // Replicate src/ci/scripts/setup-environment.sh // Adds custom environment variables to the job if name.starts_with("dist-") { @@ -340,7 +330,10 @@ fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> any enum Args { /// Calculate a list of jobs that should be executed on CI. /// Should only be used on CI inside GitHub actions. - CalculateJobMatrix, + CalculateJobMatrix { + #[clap(long)] + jobs_file: Option, + }, /// Execute a given CI job locally. #[clap(name = "run-local")] RunJobLocally { @@ -362,19 +355,29 @@ enum JobType { fn main() -> anyhow::Result<()> { let args = Args::parse(); - let db = load_job_db(Path::new(JOBS_YML_PATH)).context("Cannot load jobs.yml")?; + let default_jobs_file = Path::new(JOBS_YML_PATH); + let load_db = |jobs_path| load_job_db(jobs_path).context("Cannot load jobs.yml"); match args { - Args::CalculateJobMatrix => { + Args::CalculateJobMatrix { jobs_file } => { + let jobs_path = jobs_file.as_deref().unwrap_or(default_jobs_file); let gh_ctx = load_github_ctx() .context("Cannot load environment variables from GitHub Actions")?; - let channel = std::fs::read_to_string(Path::new(CI_DIRECTORY).join("channel")) + let channel = read_to_string(Path::new(CI_DIRECTORY).join("channel")) .context("Cannot read channel file")?; - calculate_job_matrix(db, gh_ctx, &channel).context("Failed to calculate job matrix")?; + calculate_job_matrix(load_db(jobs_path)?, gh_ctx, &channel) + .context("Failed to calculate job matrix")?; + } + Args::RunJobLocally { job_type, name } => { + run_workflow_locally(load_db(default_jobs_file)?, job_type, name)? } - Args::RunJobLocally { job_type, name } => run_workflow_locally(db, job_type, name)?, } Ok(()) } + +fn read_to_string>(path: P) -> anyhow::Result { + let error = format!("Cannot read file {:?}", path.as_ref()); + std::fs::read_to_string(path).context(error) +} diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs new file mode 100644 index 000000000000..1d81d58f8931 --- /dev/null +++ b/src/ci/citool/tests/jobs.rs @@ -0,0 +1,64 @@ +use std::process::{Command, Stdio}; + +const TEST_JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/test-jobs.yml"); + +#[test] +fn auto_jobs() { + let stdout = get_matrix("push", "commit", "refs/heads/auto"); + insta::assert_snapshot!(stdout, @r#" + jobs=[{"name":"aarch64-gnu","full_name":"auto - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"x86_64-gnu-llvm-18-1","full_name":"auto - x86_64-gnu-llvm-18-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DOCKER_SCRIPT":"stage_2_test_set1.sh","IMAGE":"x86_64-gnu-llvm-18","READ_ONLY_SRC":"0","RUST_BACKTRACE":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"aarch64-apple","full_name":"auto - aarch64-apple","os":"macos-14","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set rust.jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","SELECT_XCODE":"/Applications/Xcode_15.4.app","TOOLSTATE_PUBLISH":1,"USE_XCODE_CLANG":1}},{"name":"dist-i686-msvc","full_name":"auto - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}}] + run_type=auto + "#); +} + +#[test] +fn try_jobs() { + let stdout = get_matrix("push", "commit", "refs/heads/try"); + insta::assert_snapshot!(stdout, @r#" + jobs=[{"name":"dist-x86_64-linux","full_name":"try - dist-x86_64-linux","os":"ubuntu-22.04-16core-64gb","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_TRY_BUILD":1,"TOOLSTATE_PUBLISH":1}}] + run_type=try + "#); +} + +#[test] +fn try_custom_jobs() { + let stdout = get_matrix( + "push", + r#"This is a test PR + +try-job: aarch64-gnu +try-job: dist-i686-msvc"#, + "refs/heads/try", + ); + insta::assert_snapshot!(stdout, @r#" + jobs=[{"name":"aarch64-gnu","full_name":"try - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DIST_TRY_BUILD":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"dist-i686-msvc","full_name":"try - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"DIST_TRY_BUILD":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}}] + run_type=try + "#); +} + +#[test] +fn pr_jobs() { + let stdout = get_matrix("pull_request", "commit", "refs/heads/pr/1234"); + insta::assert_snapshot!(stdout, @r#" + jobs=[{"name":"mingw-check","full_name":"PR - mingw-check","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"mingw-check-tidy","full_name":"PR - mingw-check-tidy","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"continue_on_error":true,"free_disk":true}] + run_type=pr + "#); +} + +fn get_matrix(event_name: &str, commit_msg: &str, branch_ref: &str) -> String { + let output = Command::new("cargo") + .args(["run", "-q", "calculate-job-matrix", "--jobs-file", TEST_JOBS_YML_PATH]) + .env("GITHUB_EVENT_NAME", event_name) + .env("COMMIT_MESSAGE", commit_msg) + .env("GITHUB_REF", branch_ref) + .stdout(Stdio::piped()) + .output() + .expect("Failed to execute command"); + + let stdout = String::from_utf8(output.stdout).unwrap(); + let stderr = String::from_utf8(output.stderr).unwrap(); + if !output.status.success() { + panic!("cargo run failed: {}\n{}", stdout, stderr); + } + stdout +} diff --git a/src/ci/citool/tests/test-jobs.yml b/src/ci/citool/tests/test-jobs.yml new file mode 100644 index 000000000000..56b9ced20719 --- /dev/null +++ b/src/ci/citool/tests/test-jobs.yml @@ -0,0 +1,145 @@ +runners: + - &base-job + env: { } + + - &job-linux-4c + os: ubuntu-24.04 + # Free some disk space to avoid running out of space during the build. + free_disk: true + <<: *base-job + + - &job-linux-16c + os: ubuntu-22.04-16core-64gb + <<: *base-job + + - &job-macos-m1 + os: macos-14 + <<: *base-job + + - &job-windows + os: windows-2022 + <<: *base-job + + - &job-aarch64-linux + # Free some disk space to avoid running out of space during the build. + free_disk: true + os: ubuntu-22.04-arm + <<: *base-job +envs: + env-x86_64-apple-tests: &env-x86_64-apple-tests + SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact + RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + # Ensure that host tooling is tested on our minimum supported macOS version. + MACOSX_DEPLOYMENT_TARGET: 10.12 + MACOSX_STD_DEPLOYMENT_TARGET: 10.12 + SELECT_XCODE: /Applications/Xcode_15.2.app + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + NO_OVERFLOW_CHECKS: 1 + + production: + &production + DEPLOY_BUCKET: rust-lang-ci2 + # AWS_SECRET_ACCESS_KEYs are stored in GitHub's secrets storage, named + # AWS_SECRET_ACCESS_KEY_. Including the key id in the name allows to + # rotate them in a single branch while keeping the old key in another + # branch, which wouldn't be possible if the key was named with the kind + # (caches, artifacts...). + CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL + ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 + AWS_REGION: us-west-1 + TOOLSTATE_PUBLISH: 1 + + try: + <<: *production + # The following env var activates faster `try` builds in `opt-dist` by, e.g. + # - building only the more commonly useful components (we rarely need e.g. rust-docs in try + # builds) + # - not running `opt-dist`'s post-optimization smoke tests on the resulting toolchain + # + # If you *want* these to happen however, temporarily comment it before triggering a try build. + DIST_TRY_BUILD: 1 + + auto: + <<: *production + + pr: + PR_CI_JOB: 1 + +# Jobs that run on each push to a pull request (PR) +# These jobs automatically inherit envs.pr, to avoid repeating +# it in each job definition. +pr: + - name: mingw-check + <<: *job-linux-4c + - name: mingw-check-tidy + continue_on_error: true + <<: *job-linux-4c + +# Jobs that run when you perform a try build (@bors try) +# These jobs automatically inherit envs.try, to avoid repeating +# it in each job definition. +try: + - name: dist-x86_64-linux + env: + CODEGEN_BACKENDS: llvm,cranelift + <<: *job-linux-16c + +# Main CI jobs that have to be green to merge a commit into master +# These jobs automatically inherit envs.auto, to avoid repeating +# it in each job definition. +auto: + - name: aarch64-gnu + <<: *job-aarch64-linux + + # The x86_64-gnu-llvm-18 job is split into multiple jobs to run tests in parallel. + # x86_64-gnu-llvm-18-1 skips tests that run in x86_64-gnu-llvm-18-{2,3}. + - name: x86_64-gnu-llvm-18-1 + env: + RUST_BACKTRACE: 1 + READ_ONLY_SRC: "0" + IMAGE: x86_64-gnu-llvm-18 + DOCKER_SCRIPT: stage_2_test_set1.sh + <<: *job-linux-4c + + + #################### + # macOS Builders # + #################### + + - name: aarch64-apple + env: + SCRIPT: ./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin + RUST_CONFIGURE_ARGS: >- + --enable-sanitizers + --enable-profiler + --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + SELECT_XCODE: /Applications/Xcode_15.4.app + USE_XCODE_CLANG: 1 + # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else + # supports the hardware, so only need to test it there. + MACOSX_DEPLOYMENT_TARGET: 11.0 + MACOSX_STD_DEPLOYMENT_TARGET: 11.0 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + NO_OVERFLOW_CHECKS: 1 + <<: *job-macos-m1 + + ###################### + # Windows Builders # + ###################### + + - name: dist-i686-msvc + env: + RUST_CONFIGURE_ARGS: >- + --build=i686-pc-windows-msvc + --host=i686-pc-windows-msvc + --target=i686-pc-windows-msvc,i586-pc-windows-msvc + --enable-full-tools + --enable-profiler + SCRIPT: python x.py dist bootstrap --include-default-paths + DIST_REQUIRE_ALL_TOOLS: 1 + CODEGEN_BACKENDS: llvm,cranelift + <<: *job-windows From ae6d93ce13406fec8d6649af46f1ae6723172292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Feb 2025 18:08:27 +0100 Subject: [PATCH 167/991] Test citool on CI --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b01494630b44..fdeb1aa07efd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,6 +58,7 @@ jobs: COMMIT_MESSAGE: ${{ github.event.head_commit.message }} run: | cd src/ci/citool + cargo test cargo run calculate-job-matrix >> $GITHUB_OUTPUT id: jobs job: From 8ccaf48fcd6e859244aeb476327bdd710da5735b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 17 Feb 2025 12:21:17 +0100 Subject: [PATCH 168/991] Avoid double serialization of environment strings --- src/ci/citool/src/main.rs | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index b8d741004239..e3eba6b9afc5 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -92,7 +92,7 @@ struct GithubActionsJob { /// prefix (PR/try/auto). full_name: String, os: String, - env: BTreeMap, + env: BTreeMap, #[serde(flatten)] extra_keys: BTreeMap, } @@ -165,15 +165,12 @@ fn skip_jobs(jobs: Vec, channel: &str) -> Vec { .collect() } -fn to_string_map(map: &BTreeMap) -> BTreeMap { - map.iter() +fn yaml_map_to_json(map: &BTreeMap) -> BTreeMap { + map.into_iter() .map(|(key, value)| { ( key.clone(), - serde_yaml::to_string(value) - .expect("Cannot serialize YAML value to string") - .trim() - .to_string(), + serde_json::to_value(&value).expect("Cannot convert map value from YAML to JSON"), ) }) .collect() @@ -222,8 +219,8 @@ fn calculate_jobs( let jobs = jobs .into_iter() .map(|job| { - let mut env: BTreeMap = to_string_map(base_env); - env.extend(to_string_map(&job.env)); + let mut env: BTreeMap = yaml_map_to_json(base_env); + env.extend(yaml_map_to_json(&job.env)); let full_name = format!("{prefix} - {}", job.name); GithubActionsJob { @@ -231,17 +228,7 @@ fn calculate_jobs( full_name, os: job.os, env, - extra_keys: job - .extra_keys - .into_iter() - .map(|(key, value)| { - ( - key, - serde_json::to_value(&value) - .expect("Cannot convert extra key value from YAML to JSON"), - ) - }) - .collect(), + extra_keys: yaml_map_to_json(&job.extra_keys), } }) .collect(); @@ -314,7 +301,15 @@ fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> any custom_env.insert("DEPLOY".to_string(), "1".to_string()); } } - custom_env.extend(to_string_map(&job.env)); + custom_env.extend(job.env.iter().map(|(key, value)| { + let value = match value { + Value::Bool(value) => value.to_string(), + Value::Number(value) => value.to_string(), + Value::String(value) => value.clone(), + _ => panic!("Unexpected type for environment variable {key} Only bool/number/string is supported.") + }; + (key.clone(), value) + })); let mut cmd = Command::new(Path::new(DOCKER_DIRECTORY).join("run.sh")); cmd.arg(job.image()); From f35c88043b6177710f3c762c886810f28dadbe76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 17 Feb 2025 12:21:24 +0100 Subject: [PATCH 169/991] Trim try-job names --- src/ci/citool/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index e3eba6b9afc5..f0d075d8562b 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -136,7 +136,7 @@ impl GitHubContext { if let Some(ref msg) = self.commit_message { msg.lines() .filter_map(|line| line.trim().strip_prefix("try-job: ")) - .map(|l| l.to_string()) + .map(|l| l.trim().to_string()) .collect() } else { vec![] From 31acbd3f902da4eba6fe7eaf07cb862ebac9d67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 17 Feb 2025 12:21:41 +0100 Subject: [PATCH 170/991] Trim channel To avoid including a newline at the end, which broke `only_on_channel` comparison. --- src/ci/citool/src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index f0d075d8562b..ad9cc8b82a6f 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -359,7 +359,9 @@ fn main() -> anyhow::Result<()> { let gh_ctx = load_github_ctx() .context("Cannot load environment variables from GitHub Actions")?; let channel = read_to_string(Path::new(CI_DIRECTORY).join("channel")) - .context("Cannot read channel file")?; + .context("Cannot read channel file")? + .trim() + .to_string(); calculate_job_matrix(load_db(jobs_path)?, gh_ctx, &channel) .context("Failed to calculate job matrix")?; From ba7d5d11ae50554a56a789dbe7a5e8cf08d42c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 17 Feb 2025 12:34:43 +0100 Subject: [PATCH 171/991] Changed `.display()` to `.to_str()` --- src/bootstrap/src/core/build_steps/gcc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 3edca8834e06..e8b6a577cea5 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -202,5 +202,5 @@ impl Step for Gcc { /// Configures a Cargo invocation so that it can build the GCC codegen backend. pub fn add_cg_gcc_cargo_flags(cargo: &mut Cargo, gcc: &GccOutput) { // Add the path to libgccjit.so to the linker search paths. - cargo.rustflag(&format!("-L{}", gcc.libgccjit.parent().unwrap().display())); + cargo.rustflag(&format!("-L{}", gcc.libgccjit.parent().unwrap().to_str().unwrap())); } From 9cd1de573bbd48a1d5785dfc90bfffb78814c4ed Mon Sep 17 00:00:00 2001 From: makai410 Date: Mon, 17 Feb 2025 21:19:36 +0800 Subject: [PATCH 172/991] suggest swapping equality on e0277 --- .../traits/fulfillment_errors.rs | 6 +++ .../src/error_reporting/traits/suggestions.rs | 47 +++++++++++++++++++ .../partialeq_suggest_swap_on_e0277.rs | 11 +++++ .../partialeq_suggest_swap_on_e0277.stderr | 24 ++++++++++ 4 files changed, 88 insertions(+) create mode 100644 tests/ui/suggestions/partialeq_suggest_swap_on_e0277.rs create mode 100644 tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 19e2679ae4da..2c2fffe34c61 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2126,6 +2126,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &mut vec![], &mut Default::default(), ); + self.suggest_swapping_lhs_and_rhs( + err, + obligation.predicate, + obligation.param_env, + obligation.cause.code(), + ); self.suggest_unsized_bound_if_applicable(err, obligation); if let Some(span) = err.span.primary_span() && let Some(mut diag) = diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 6df7fac949c2..7deaebe61256 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4843,6 +4843,53 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); true } + pub(crate) fn suggest_swapping_lhs_and_rhs( + &self, + err: &mut Diag<'_>, + predicate: T, + param_env: ty::ParamEnv<'tcx>, + cause_code: &ObligationCauseCode<'tcx>, + ) where + T: Upcast, ty::Predicate<'tcx>>, + { + let tcx = self.tcx; + let predicate = predicate.upcast(tcx); + match *cause_code { + ObligationCauseCode::BinOp { + lhs_hir_id, + rhs_hir_id: Some(rhs_hir_id), + rhs_span: Some(rhs_span), + .. + } if let Some(typeck_results) = &self.typeck_results + && let hir::Node::Expr(lhs) = tcx.hir_node(lhs_hir_id) + && let hir::Node::Expr(rhs) = tcx.hir_node(rhs_hir_id) + && let Some(lhs_ty) = typeck_results.expr_ty_opt(lhs) + && let Some(rhs_ty) = typeck_results.expr_ty_opt(rhs) => + { + if let Some(pred) = predicate.as_trait_clause() + && tcx.is_lang_item(pred.def_id(), LangItem::PartialEq) + && self + .infcx + .type_implements_trait(pred.def_id(), [rhs_ty, lhs_ty], param_env) + .must_apply_modulo_regions() + { + let lhs_span = tcx.hir().span(lhs_hir_id); + let sm = tcx.sess.source_map(); + if let Ok(rhs_snippet) = sm.span_to_snippet(rhs_span) + && let Ok(lhs_snippet) = sm.span_to_snippet(lhs_span) + { + err.note(format!("`{rhs_ty}` implements `PartialEq<{lhs_ty}>`")); + err.multipart_suggestion( + "consider swapping the equality", + vec![(lhs_span, rhs_snippet), (rhs_span, lhs_snippet)], + Applicability::MaybeIncorrect, + ); + } + } + } + _ => {} + } + } } /// Add a hint to add a missing borrow or remove an unnecessary one. diff --git a/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.rs b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.rs new file mode 100644 index 000000000000..2ebbed3c740f --- /dev/null +++ b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.rs @@ -0,0 +1,11 @@ +struct T(String); + +impl PartialEq for T { + fn eq(&self, other: &String) -> bool { + &self.0 == other + } +} + +fn main() { + String::from("Girls Band Cry") == T(String::from("Girls Band Cry")); //~ can't compare `String` with `T` [E0277] +} diff --git a/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr new file mode 100644 index 000000000000..ebe103ef19a1 --- /dev/null +++ b/tests/ui/suggestions/partialeq_suggest_swap_on_e0277.stderr @@ -0,0 +1,24 @@ +error[E0277]: can't compare `String` with `T` + --> $DIR/partialeq_suggest_swap_on_e0277.rs:10:36 + | +LL | String::from("Girls Band Cry") == T(String::from("Girls Band Cry")); + | ^^ no implementation for `String == T` + | + = help: the trait `PartialEq` is not implemented for `String` + = help: the following other types implement trait `PartialEq`: + `String` implements `PartialEq<&str>` + `String` implements `PartialEq` + `String` implements `PartialEq` + `String` implements `PartialEq>` + `String` implements `PartialEq` + `String` implements `PartialEq` + = note: `T` implements `PartialEq` +help: consider swapping the equality + | +LL - String::from("Girls Band Cry") == T(String::from("Girls Band Cry")); +LL + T(String::from("Girls Band Cry")) == String::from("Girls Band Cry"); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 66d19d84ae1a83bba0317e2c991cadb2ab28a064 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Mon, 17 Feb 2025 15:22:46 +0100 Subject: [PATCH 173/991] =?UTF-8?q?`manual=5Fok=5Ferr`:=20blockify=20the?= =?UTF-8?q?=20replacement=20of=20an=20`else=20if=20=E2=80=A6`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the part being replaced is an `if` expression following an `else`, the replacement expression must be blockified. --- clippy_lints/src/matches/manual_ok_err.rs | 15 +++++++++++++-- tests/ui/manual_ok_err.fixed | 9 +++++++++ tests/ui/manual_ok_err.rs | 11 +++++++++++ tests/ui/manual_ok_err.stderr | 20 +++++++++++++++++++- 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/matches/manual_ok_err.rs b/clippy_lints/src/matches/manual_ok_err.rs index 3deaaf96c1e8..576e42a564c2 100644 --- a/clippy_lints/src/matches/manual_ok_err.rs +++ b/clippy_lints/src/matches/manual_ok_err.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::{indent_of, reindent_multiline}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::option_arg_ty; -use clippy_utils::{is_res_lang_ctor, path_res, peel_blocks, span_contains_comment}; +use clippy_utils::{get_parent_expr, is_res_lang_ctor, path_res, peel_blocks, span_contains_comment}; use rustc_ast::BindingMode; use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr}; @@ -132,13 +133,23 @@ fn apply_lint(cx: &LateContext<'_>, expr: &Expr<'_>, scrutinee: &Expr<'_>, is_ok Applicability::MachineApplicable }; let scrut = Sugg::hir_with_applicability(cx, scrutinee, "..", &mut app).maybe_par(); + let sugg = format!("{scrut}.{method}()"); + // If the expression being expanded is the `if …` part of an `else if …`, it must be blockified. + let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr) + && let ExprKind::If(_, _, Some(else_part)) = parent_expr.kind + && else_part.hir_id == expr.hir_id + { + reindent_multiline(&format!("{{\n {sugg}\n}}"), true, indent_of(cx, parent_expr.span)) + } else { + sugg + }; span_lint_and_sugg( cx, MANUAL_OK_ERR, expr.span, format!("manual implementation of `{method}`"), "replace with", - format!("{scrut}.{method}()"), + sugg, app, ); } diff --git a/tests/ui/manual_ok_err.fixed b/tests/ui/manual_ok_err.fixed index e7e0464c4787..bc169b64be9f 100644 --- a/tests/ui/manual_ok_err.fixed +++ b/tests/ui/manual_ok_err.fixed @@ -89,3 +89,12 @@ const fn cf(x: Result) -> Option { Err(_) => None, } } + +fn issue14239() { + let _ = if false { + None + } else { + "1".parse::().ok() + }; + //~^^^^^ manual_ok_err +} diff --git a/tests/ui/manual_ok_err.rs b/tests/ui/manual_ok_err.rs index 77300b7af539..03c730d4b4e4 100644 --- a/tests/ui/manual_ok_err.rs +++ b/tests/ui/manual_ok_err.rs @@ -125,3 +125,14 @@ const fn cf(x: Result) -> Option { Err(_) => None, } } + +fn issue14239() { + let _ = if false { + None + } else if let Ok(n) = "1".parse::() { + Some(n) + } else { + None + }; + //~^^^^^ manual_ok_err +} diff --git a/tests/ui/manual_ok_err.stderr b/tests/ui/manual_ok_err.stderr index f10f52cc4c97..13fceacda107 100644 --- a/tests/ui/manual_ok_err.stderr +++ b/tests/ui/manual_ok_err.stderr @@ -93,5 +93,23 @@ LL | | _ => None, LL | | }; | |_____^ help: replace with: `(-S).ok()` -error: aborting due to 8 previous errors +error: manual implementation of `ok` + --> tests/ui/manual_ok_err.rs:132:12 + | +LL | } else if let Ok(n) = "1".parse::() { + | ____________^ +LL | | Some(n) +LL | | } else { +LL | | None +LL | | }; + | |_____^ + | +help: replace with + | +LL ~ } else { +LL + "1".parse::().ok() +LL ~ }; + | + +error: aborting due to 9 previous errors From 01085cb16a78fb18bfdb0330180128e294f50eba Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 17 Feb 2025 10:36:08 -0500 Subject: [PATCH 174/991] Update mention of `ref_to_mut` to `invalid_reference_casting` This lint was renamed in 50da77521e922f17735b9d97461925ca0f3dec1c. While I'm here convert the list of separate lints into a proper list for ease of use and clarify which lints are in clippy and which are in rustc. --- clippy_lints/src/as_conversions.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/as_conversions.rs b/clippy_lints/src/as_conversions.rs index 847653ed6e98..78102772927c 100644 --- a/clippy_lints/src/as_conversions.rs +++ b/clippy_lints/src/as_conversions.rs @@ -9,12 +9,24 @@ declare_clippy_lint! { /// Checks for usage of `as` conversions. /// /// Note that this lint is specialized in linting *every single* use of `as` - /// regardless of whether good alternatives exist or not. - /// If you want more precise lints for `as`, please consider using these separate lints: - /// `unnecessary_cast`, `cast_lossless/cast_possible_truncation/cast_possible_wrap/cast_precision_loss/cast_sign_loss`, - /// `fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`. - /// There is a good explanation the reason why this lint should work in this way and how it is useful - /// [in this issue](https://github.com/rust-lang/rust-clippy/issues/5122). + /// regardless of whether good alternatives exist or not. If you want more + /// precise lints for `as`, please consider using these separate lints: + /// + /// - clippy::cast_lossless + /// - clippy::cast_possible_truncation + /// - clippy::cast_possible_wrap + /// - clippy::cast_precision_loss + /// - clippy::cast_sign_loss + /// - clippy::char_lit_as_u8 + /// - clippy::fn_to_numeric_cast + /// - clippy::fn_to_numeric_cast_with_truncation + /// - clippy::ptr_as_ptr + /// - clippy::unnecessary_cast + /// - invalid_reference_casting + /// + /// There is a good explanation the reason why this lint should work in this + /// way and how it is useful [in this + /// issue](https://github.com/rust-lang/rust-clippy/issues/5122). /// /// ### Why restrict this? /// `as` conversions will perform many kinds of From 835e6a694b543af769c84a99659505b2418d640e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 17 Feb 2025 14:17:57 +1100 Subject: [PATCH 175/991] Move methods from `Map` to `TyCtxt`, part 2. Continuing the work started in #136466. Every method gains a `hir_` prefix, though for the ones that already have a `par_` or `try_par_` prefix I added the `hir_` after that. --- clippy_lints/src/default_numeric_fallback.rs | 3 +-- clippy_lints/src/enum_clike.rs | 2 +- clippy_lints/src/functions/impl_trait_in_params.rs | 4 ++-- clippy_lints/src/functions/renamed_function_params.rs | 2 +- clippy_lints/src/manual_float_methods.rs | 2 +- clippy_lints/src/methods/option_map_unwrap_or.rs | 3 +-- clippy_lints/src/needless_borrows_for_generic_args.rs | 4 ++-- clippy_lints/src/needless_pass_by_ref_mut.rs | 2 +- clippy_lints/src/operators/arithmetic_side_effects.rs | 8 ++++---- clippy_lints/src/operators/numeric_arithmetic.rs | 8 ++++---- clippy_lints/src/redundant_locals.rs | 2 +- clippy_lints/src/shadow.rs | 8 +++----- clippy_lints/src/single_call_fn.rs | 3 +-- .../src/transmute/missing_transmute_annotations.rs | 4 ++-- clippy_lints/src/unconditional_recursion.rs | 4 ++-- clippy_lints/src/utils/author.rs | 3 +-- .../src/utils/internal_lints/lint_without_lint_pass.rs | 2 +- clippy_utils/src/lib.rs | 10 ++++------ clippy_utils/src/mir/mod.rs | 4 ++-- clippy_utils/src/ty/mod.rs | 4 ++-- 20 files changed, 37 insertions(+), 45 deletions(-) diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs index 772268e7899e..784214c29af9 100644 --- a/clippy_lints/src/default_numeric_fallback.rs +++ b/clippy_lints/src/default_numeric_fallback.rs @@ -52,11 +52,10 @@ declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]); impl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback { fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { - let hir = cx.tcx.hir(); // NOTE: this is different from `clippy_utils::is_inside_always_const_context`. // Inline const supports type inference. let is_parent_const = matches!( - hir.body_const_context(hir.body_owner_def_id(body.id())), + cx.tcx.hir_body_const_context(cx.tcx.hir_body_owner_def_id(body.id())), Some(ConstContext::Const { inline: false } | ConstContext::Static(_)) ); let mut visitor = NumericFallbackVisitor::new(cx, is_parent_const); diff --git a/clippy_lints/src/enum_clike.rs b/clippy_lints/src/enum_clike.rs index a090a987d4fc..2e1f8ac615a2 100644 --- a/clippy_lints/src/enum_clike.rs +++ b/clippy_lints/src/enum_clike.rs @@ -41,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant { if let ItemKind::Enum(def, _) = &item.kind { for var in def.variants { if let Some(anon_const) = &var.disr_expr { - let def_id = cx.tcx.hir().body_owner_def_id(anon_const.body); + let def_id = cx.tcx.hir_body_owner_def_id(anon_const.body); let mut ty = cx.tcx.type_of(def_id.to_def_id()).instantiate_identity(); let constant = cx .tcx diff --git a/clippy_lints/src/functions/impl_trait_in_params.rs b/clippy_lints/src/functions/impl_trait_in_params.rs index 6d1c55d06938..cb83b1395d26 100644 --- a/clippy_lints/src/functions/impl_trait_in_params.rs +++ b/clippy_lints/src/functions/impl_trait_in_params.rs @@ -39,7 +39,7 @@ fn report(cx: &LateContext<'_>, param: &GenericParam<'_>, generics: &Generics<'_ pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: &'tcx Body<'_>, hir_id: HirId) { if let FnKind::ItemFn(_, generics, _) = kind - && cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() + && cx.tcx.visibility(cx.tcx.hir_body_owner_def_id(body.id())).is_public() && !is_in_test(cx.tcx, hir_id) { for param in generics.params { @@ -57,7 +57,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { && let hir::Impl { of_trait, .. } = *impl_ && of_trait.is_none() && let body = cx.tcx.hir_body(body_id) - && cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() + && cx.tcx.visibility(cx.tcx.hir_body_owner_def_id(body.id())).is_public() && !is_in_test(cx.tcx, impl_item.hir_id()) { for param in impl_item.generics.params { diff --git a/clippy_lints/src/functions/renamed_function_params.rs b/clippy_lints/src/functions/renamed_function_params.rs index ac2e866e4ff7..5ad83f886e2e 100644 --- a/clippy_lints/src/functions/renamed_function_params.rs +++ b/clippy_lints/src/functions/renamed_function_params.rs @@ -22,7 +22,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored && let Some(did) = trait_item_def_id_of_impl(items, item.owner_id) && !is_from_ignored_trait(trait_ref, ignored_traits) { - let mut param_idents_iter = cx.tcx.hir().body_param_names(body_id); + let mut param_idents_iter = cx.tcx.hir_body_param_names(body_id); let mut default_param_idents_iter = cx.tcx.fn_arg_names(did).iter().copied(); let renames = RenamedFnArgs::new(&mut default_param_idents_iter, &mut param_idents_iter); diff --git a/clippy_lints/src/manual_float_methods.rs b/clippy_lints/src/manual_float_methods.rs index 052e6502da92..2a5aa12d126c 100644 --- a/clippy_lints/src/manual_float_methods.rs +++ b/clippy_lints/src/manual_float_methods.rs @@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods { && exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2 && !expr.span.in_external_macro(cx.sess().source_map()) && ( - is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into()) + is_not_const(cx.tcx, cx.tcx.hir_enclosing_body_owner(expr.hir_id).into()) || self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY) ) && let [first, second, const_1, const_2] = exprs diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index 4a8a221e8c36..b1107d8cc72f 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -58,8 +58,7 @@ pub(super) fn check<'tcx>( unwrap_or_span: unwrap_arg.span, }; - let map = cx.tcx.hir(); - let body = map.body_owned_by(map.enclosing_body_owner(expr.hir_id)); + let body = cx.tcx.hir_body_owned_by(cx.tcx.hir_enclosing_body_owner(expr.hir_id)); // Visit the body, and return if we've found a reference if reference_visitor.visit_body(body).is_break() { diff --git a/clippy_lints/src/needless_borrows_for_generic_args.rs b/clippy_lints/src/needless_borrows_for_generic_args.rs index 7f91e555054d..ea1d7e5d4382 100644 --- a/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { if self .possible_borrowers .last() - .is_some_and(|&(local_def_id, _)| local_def_id == cx.tcx.hir().body_owner_def_id(body.id())) + .is_some_and(|&(local_def_id, _)| local_def_id == cx.tcx.hir_body_owner_def_id(body.id())) { self.possible_borrowers.pop(); } @@ -359,7 +359,7 @@ fn referent_used_exactly_once<'tcx>( && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind && !place.is_indirect_first_projection() { - let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id); + let body_owner_local_def_id = cx.tcx.hir_enclosing_body_owner(reference.hir_id); if possible_borrowers .last() .is_none_or(|&(local_def_id, _)| local_def_id != body_owner_local_def_id) diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 6a1dc5e41a07..5e85d23718a9 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -352,7 +352,7 @@ impl MutablyUsedVariablesCtxt<'_> { fn is_in_unsafe_block(&self, item: HirId) -> bool { let hir = self.tcx.hir(); for (parent, node) in hir.parent_iter(item) { - if let Some(fn_sig) = hir.fn_sig_by_hir_id(parent) { + if let Some(fn_sig) = self.tcx.hir_fn_sig_by_hir_id(parent) { return fn_sig.header.is_unsafe(); } else if let Node::Block(block) = node { if matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) { diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs index 9d07a14718da..594101427f5a 100644 --- a/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -349,10 +349,10 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { } fn check_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); - let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); + let body_owner_def_id = cx.tcx.hir_body_owner_def_id(body.id()); - let body_owner_kind = cx.tcx.hir().body_owner_kind(body_owner_def_id); + let body_owner_kind = cx.tcx.hir_body_owner_kind(body_owner_def_id); if let hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) = body_owner_kind { let body_span = cx.tcx.hir().span_with_body(body_owner); if let Some(span) = self.const_span @@ -365,7 +365,7 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { } fn check_body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); let body_span = cx.tcx.hir().span(body_owner); if let Some(span) = self.const_span && span.contains(body_span) diff --git a/clippy_lints/src/operators/numeric_arithmetic.rs b/clippy_lints/src/operators/numeric_arithmetic.rs index 2083f2bf628d..cda99a362dca 100644 --- a/clippy_lints/src/operators/numeric_arithmetic.rs +++ b/clippy_lints/src/operators/numeric_arithmetic.rs @@ -68,10 +68,10 @@ impl Context { } pub fn enter_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); - let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); + let body_owner_def_id = cx.tcx.hir_body_owner_def_id(body.id()); - match cx.tcx.hir().body_owner_kind(body_owner_def_id) { + match cx.tcx.hir_body_owner_kind(body_owner_def_id) { hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const { .. } => { let body_span = cx.tcx.hir().span_with_body(body_owner); @@ -87,7 +87,7 @@ impl Context { } pub fn body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); let body_span = cx.tcx.hir().span_with_body(body_owner); if let Some(span) = self.const_span { diff --git a/clippy_lints/src/redundant_locals.rs b/clippy_lints/src/redundant_locals.rs index ebe3e7c20196..e15e12629209 100644 --- a/clippy_lints/src/redundant_locals.rs +++ b/clippy_lints/src/redundant_locals.rs @@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals { /// assert_static(closure); /// ``` fn is_by_value_closure_capture(cx: &LateContext<'_>, redefinition: HirId, root_variable: HirId) -> bool { - let closure_def_id = cx.tcx.hir().enclosing_body_owner(redefinition); + let closure_def_id = cx.tcx.hir_enclosing_body_owner(redefinition); cx.tcx.is_closure_like(closure_def_id.to_def_id()) && cx.tcx.closure_captures(closure_def_id).iter().any(|c| { diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 83199ba0f707..a931e39bac9c 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -149,17 +149,15 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { } fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) { - let hir = cx.tcx.hir(); - let owner_id = hir.body_owner_def_id(body.id()); - if !matches!(hir.body_owner_kind(owner_id), BodyOwnerKind::Closure) { + let owner_id = cx.tcx.hir_body_owner_def_id(body.id()); + if !matches!(cx.tcx.hir_body_owner_kind(owner_id), BodyOwnerKind::Closure) { self.bindings.push((FxHashMap::default(), owner_id)); } } fn check_body_post(&mut self, cx: &LateContext<'_>, body: &Body<'_>) { - let hir = cx.tcx.hir(); if !matches!( - hir.body_owner_kind(hir.body_owner_def_id(body.id())), + cx.tcx.hir_body_owner_kind(cx.tcx.hir_body_owner_def_id(body.id())), BodyOwnerKind::Closure ) { self.bindings.pop(); diff --git a/clippy_lints/src/single_call_fn.rs b/clippy_lints/src/single_call_fn.rs index fdbccbaa8a59..1a2fb77acc15 100644 --- a/clippy_lints/src/single_call_fn.rs +++ b/clippy_lints/src/single_call_fn.rs @@ -90,8 +90,7 @@ impl SingleCallFn { || fn_span.in_external_macro(cx.sess().source_map()) || cx .tcx - .hir() - .maybe_body_owned_by(fn_def_id) + .hir_maybe_body_owned_by(fn_def_id) .is_none_or(|body| is_in_test_function(cx.tcx, body.value.hir_id)) || match cx.tcx.hir_node(fn_hir_id) { Node::Item(item) => is_from_proc_macro(cx, item), diff --git a/clippy_lints/src/transmute/missing_transmute_annotations.rs b/clippy_lints/src/transmute/missing_transmute_annotations.rs index 4961dd6b280a..0b5d83ef58ca 100644 --- a/clippy_lints/src/transmute/missing_transmute_annotations.rs +++ b/clippy_lints/src/transmute/missing_transmute_annotations.rs @@ -28,8 +28,8 @@ fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) } fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool { - let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id); - if let Some(body) = cx.tcx.hir().maybe_body_owned_by(def_id) { + let def_id = cx.tcx.hir_enclosing_body_owner(expr_hir_id); + if let Some(body) = cx.tcx.hir_maybe_body_owned_by(def_id) { return body.value.peel_blocks().hir_id == expr_hir_id; } false diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs index 529f85be3720..76a0b927df42 100644 --- a/clippy_lints/src/unconditional_recursion.rs +++ b/clippy_lints/src/unconditional_recursion.rs @@ -331,8 +331,8 @@ impl UnconditionalRecursion { && let [return_expr] = get_return_calls_in_body(body).as_slice() && let ExprKind::Call(call_expr, _) = return_expr.kind // We need to use typeck here to infer the actual function being called. - && let body_def_id = cx.tcx.hir().enclosing_body_owner(call_expr.hir_id) - && let Some(body_owner) = cx.tcx.hir().maybe_body_owned_by(body_def_id) + && let body_def_id = cx.tcx.hir_enclosing_body_owner(call_expr.hir_id) + && let Some(body_owner) = cx.tcx.hir_maybe_body_owned_by(body_def_id) && let typeck = cx.tcx.typeck_body(body_owner.id()) && let Some(call_def_id) = typeck.type_dependent_def_id(call_expr.hir_id) { diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index ce489054e16e..5fc166438e84 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -132,8 +132,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_item(cx: &LateContext<'_>, hir_id: HirId) { - let hir = cx.tcx.hir(); - if let Some(body) = hir.maybe_body_owned_by(hir_id.expect_owner().def_id) { + if let Some(body) = cx.tcx.hir_maybe_body_owned_by(hir_id.expect_owner().def_id) { check_node(cx, hir_id, |v| { v.expr(&v.bind("expr", body.value)); }); diff --git a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index e31da9e9f611..d6f10f1e4b80 100644 --- a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -156,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass { output: &mut self.registered_lints, cx, }; - let body = cx.tcx.hir().body_owned_by( + let body = cx.tcx.hir_body_owned_by( impl_item_refs .iter() .find(|iiref| iiref.ident.as_str() == "lint_vec") diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index ccf32f42a47b..15e395731ade 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -237,8 +237,7 @@ pub fn is_in_const_context(cx: &LateContext<'_>) -> bool { debug_assert!(cx.enclosing_body.is_some(), "`LateContext` has no enclosing body"); cx.enclosing_body.is_some_and(|id| { cx.tcx - .hir() - .body_const_context(cx.tcx.hir().body_owner_def_id(id)) + .hir_body_const_context(cx.tcx.hir_body_owner_def_id(id)) .is_some() }) } @@ -251,8 +250,7 @@ pub fn is_in_const_context(cx: &LateContext<'_>) -> bool { /// * associated constants pub fn is_inside_always_const_context(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { use ConstContext::{Const, ConstFn, Static}; - let hir = tcx.hir(); - let Some(ctx) = hir.body_const_context(hir.enclosing_body_owner(hir_id)) else { + let Some(ctx) = tcx.hir_body_const_context(tcx.hir_enclosing_body_owner(hir_id)) else { return false; }; match ctx { @@ -1648,7 +1646,7 @@ pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool if is_integer_literal(e, value) { return true; } - let enclosing_body = cx.tcx.hir().enclosing_body_owner(e.hir_id); + let enclosing_body = cx.tcx.hir_enclosing_body_owner(e.hir_id); if let Some(Constant::Int(v)) = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), cx.tcx.typeck(enclosing_body)).eval(e) { @@ -2762,7 +2760,7 @@ impl<'tcx> ExprUseCtxt<'tcx> { Node::Expr(use_expr) => match use_expr.kind { ExprKind::Ret(_) => ExprUseNode::Return(OwnerId { - def_id: cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), + def_id: cx.tcx.hir_body_owner_def_id(cx.enclosing_body.unwrap()), }), ExprKind::Closure(closure) => ExprUseNode::Return(OwnerId { def_id: closure.def_id }), diff --git a/clippy_utils/src/mir/mod.rs b/clippy_utils/src/mir/mod.rs index 85250f81dc47..637c0bafd964 100644 --- a/clippy_utils/src/mir/mod.rs +++ b/clippy_utils/src/mir/mod.rs @@ -136,8 +136,8 @@ pub fn used_exactly_once(mir: &Body<'_>, local: Local) -> Option { /// Returns the `mir::Body` containing the node associated with `hir_id`. #[allow(clippy::module_name_repetitions)] pub fn enclosing_mir(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<&Body<'_>> { - let body_owner_local_def_id = tcx.hir().enclosing_body_owner(hir_id); - if tcx.hir().body_owner_kind(body_owner_local_def_id).is_fn_or_closure() { + let body_owner_local_def_id = tcx.hir_enclosing_body_owner(hir_id); + if tcx.hir_body_owner_kind(body_owner_local_def_id).is_fn_or_closure() { Some(tcx.optimized_mir(body_owner_local_def_id.to_def_id())) } else { None diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index a5374f6904e3..8eef6a7f57ed 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -267,7 +267,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>( // through calling `body_owner_kind`, which would panic if the callee // does not have a body. if let Some(callee_id) = callee_id { - let _ = tcx.hir().body_owner_kind(callee_id); + let _ = tcx.hir_body_owner_kind(callee_id); } let ty = tcx.erase_regions(ty); @@ -705,7 +705,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option { let decl = id .as_local() - .and_then(|id| cx.tcx.hir().fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(id))); + .and_then(|id| cx.tcx.hir_fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(id))); Some(ExprFnSig::Closure(decl, subs.as_closure().sig())) }, ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))), From 3a3aedee10e6d34ca6889bd4b2b4f535f6ea0cbf Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Mon, 17 Feb 2025 16:27:42 -0800 Subject: [PATCH 176/991] Update some comparison tests now that they pass in LLVM20 --- library/core/src/cmp.rs | 8 +-- .../codegen/comparison-operators-2-struct.rs | 61 +++++++++++++++++++ tests/codegen/comparison-operators-2-tuple.rs | 38 ++++++------ 3 files changed, 82 insertions(+), 25 deletions(-) create mode 100644 tests/codegen/comparison-operators-2-struct.rs diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 594236cf1d96..c8ced78c4d79 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1369,7 +1369,7 @@ pub trait PartialOrd: PartialEq { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "cmp_partialord_lt"] fn lt(&self, other: &Rhs) -> bool { - matches!(self.partial_cmp(other), Some(Less)) + self.partial_cmp(other).is_some_and(Ordering::is_lt) } /// Tests less than or equal to (for `self` and `other`) and is used by the @@ -1387,7 +1387,7 @@ pub trait PartialOrd: PartialEq { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "cmp_partialord_le"] fn le(&self, other: &Rhs) -> bool { - matches!(self.partial_cmp(other), Some(Less | Equal)) + self.partial_cmp(other).is_some_and(Ordering::is_le) } /// Tests greater than (for `self` and `other`) and is used by the `>` @@ -1405,7 +1405,7 @@ pub trait PartialOrd: PartialEq { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "cmp_partialord_gt"] fn gt(&self, other: &Rhs) -> bool { - matches!(self.partial_cmp(other), Some(Greater)) + self.partial_cmp(other).is_some_and(Ordering::is_gt) } /// Tests greater than or equal to (for `self` and `other`) and is used by @@ -1423,7 +1423,7 @@ pub trait PartialOrd: PartialEq { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "cmp_partialord_ge"] fn ge(&self, other: &Rhs) -> bool { - matches!(self.partial_cmp(other), Some(Greater | Equal)) + self.partial_cmp(other).is_some_and(Ordering::is_ge) } } diff --git a/tests/codegen/comparison-operators-2-struct.rs b/tests/codegen/comparison-operators-2-struct.rs new file mode 100644 index 000000000000..e179066ebfd7 --- /dev/null +++ b/tests/codegen/comparison-operators-2-struct.rs @@ -0,0 +1,61 @@ +//@ compile-flags: -C opt-level=1 +//@ min-llvm-version: 20 + +// The `derive(PartialOrd)` for a 2-field type doesn't override `lt`/`le`/`gt`/`ge`. +// This double-checks that the `Option` intermediate values used +// in the operators for such a type all optimize away. + +#![crate_type = "lib"] + +use std::cmp::Ordering; + +#[derive(PartialOrd, PartialEq)] +pub struct Foo(i32, u32); + +// CHECK-LABEL: @check_lt( +// CHECK-SAME: i32{{.+}}%[[A0:.+]], i32{{.+}}%[[A1:.+]], i32{{.+}}%[[B0:.+]], i32{{.+}}%[[B1:.+]]) +#[no_mangle] +pub fn check_lt(a: Foo, b: Foo) -> bool { + // CHECK-DAG: %[[EQ:.+]] = icmp eq i32 %[[A0]], %[[B0]] + // CHECK-DAG: %[[R0:.+]] = icmp slt i32 %[[A0]], %[[B0]] + // CHECK-DAG: %[[R1:.+]] = icmp ult i32 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[R1]], i1 %[[R0]] + // CHECK-NEXT: ret i1 %[[R]] + a < b +} + +// CHECK-LABEL: @check_le( +// CHECK-SAME: i32{{.+}}%[[A0:.+]], i32{{.+}}%[[A1:.+]], i32{{.+}}%[[B0:.+]], i32{{.+}}%[[B1:.+]]) +#[no_mangle] +pub fn check_le(a: Foo, b: Foo) -> bool { + // CHECK-DAG: %[[EQ:.+]] = icmp eq i32 %[[A0]], %[[B0]] + // CHECK-DAG: %[[R0:.+]] = icmp sle i32 %[[A0]], %[[B0]] + // CHECK-DAG: %[[R1:.+]] = icmp ule i32 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[R1]], i1 %[[R0]] + // CHECK-NEXT: ret i1 %[[R]] + a <= b +} + +// CHECK-LABEL: @check_gt( +// CHECK-SAME: i32{{.+}}%[[A0:.+]], i32{{.+}}%[[A1:.+]], i32{{.+}}%[[B0:.+]], i32{{.+}}%[[B1:.+]]) +#[no_mangle] +pub fn check_gt(a: Foo, b: Foo) -> bool { + // CHECK-DAG: %[[EQ:.+]] = icmp eq i32 %[[A0]], %[[B0]] + // CHECK-DAG: %[[R0:.+]] = icmp sgt i32 %[[A0]], %[[B0]] + // CHECK-DAG: %[[R1:.+]] = icmp ugt i32 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[R1]], i1 %[[R0]] + // CHECK-NEXT: ret i1 %[[R]] + a > b +} + +// CHECK-LABEL: @check_ge( +// CHECK-SAME: i32{{.+}}%[[A0:.+]], i32{{.+}}%[[A1:.+]], i32{{.+}}%[[B0:.+]], i32{{.+}}%[[B1:.+]]) +#[no_mangle] +pub fn check_ge(a: Foo, b: Foo) -> bool { + // CHECK-DAG: %[[EQ:.+]] = icmp eq i32 %[[A0]], %[[B0]] + // CHECK-DAG: %[[R0:.+]] = icmp sge i32 %[[A0]], %[[B0]] + // CHECK-DAG: %[[R1:.+]] = icmp uge i32 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[R1]], i1 %[[R0]] + // CHECK-NEXT: ret i1 %[[R]] + a >= b +} diff --git a/tests/codegen/comparison-operators-2-tuple.rs b/tests/codegen/comparison-operators-2-tuple.rs index 8e2915e84eb7..91a99f9b91f9 100644 --- a/tests/codegen/comparison-operators-2-tuple.rs +++ b/tests/codegen/comparison-operators-2-tuple.rs @@ -1,5 +1,6 @@ //@ compile-flags: -C opt-level=1 -Z merge-functions=disabled //@ only-x86_64 +//@ min-llvm-version: 20 #![crate_type = "lib"] @@ -65,12 +66,7 @@ pub fn check_ge_direct(a: TwoTuple, b: TwoTuple) -> bool { } // -// These ones are harder, since there are more intermediate values to remove. -// -// `<` seems to be getting lucky right now, so test that doesn't regress. -// -// The others, however, aren't managing to optimize away the extra `select`s yet. -// See for more about this. +// These used to not optimize as well, but thanks to LLVM 20 they work now 🎉 // // CHECK-LABEL: @check_lt_via_cmp @@ -89,11 +85,11 @@ pub fn check_lt_via_cmp(a: TwoTuple, b: TwoTuple) -> bool { // CHECK-SAME: (i16 noundef %[[A0:.+]], i16 noundef %[[A1:.+]], i16 noundef %[[B0:.+]], i16 noundef %[[B1:.+]]) #[no_mangle] pub fn check_le_via_cmp(a: TwoTuple, b: TwoTuple) -> bool { - // FIXME-CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] - // FIXME-CHECK-DAG: %[[CMP0:.+]] = icmp sle i16 %[[A0]], %[[B0]] - // FIXME-CHECK-DAG: %[[CMP1:.+]] = icmp ule i16 %[[A1]], %[[B1]] - // FIXME-CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] - // FIXME-CHECK: ret i1 %[[R]] + // CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP0:.+]] = icmp sle i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP1:.+]] = icmp ule i16 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] + // CHECK: ret i1 %[[R]] Ord::cmp(&a, &b).is_le() } @@ -101,11 +97,11 @@ pub fn check_le_via_cmp(a: TwoTuple, b: TwoTuple) -> bool { // CHECK-SAME: (i16 noundef %[[A0:.+]], i16 noundef %[[A1:.+]], i16 noundef %[[B0:.+]], i16 noundef %[[B1:.+]]) #[no_mangle] pub fn check_gt_via_cmp(a: TwoTuple, b: TwoTuple) -> bool { - // FIXME-CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] - // FIXME-CHECK-DAG: %[[CMP0:.+]] = icmp sgt i16 %[[A0]], %[[B0]] - // FIXME-CHECK-DAG: %[[CMP1:.+]] = icmp ugt i16 %[[A1]], %[[B1]] - // FIXME-CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] - // FIXME-CHECK: ret i1 %[[R]] + // CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP0:.+]] = icmp sgt i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP1:.+]] = icmp ugt i16 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] + // CHECK: ret i1 %[[R]] Ord::cmp(&a, &b).is_gt() } @@ -113,10 +109,10 @@ pub fn check_gt_via_cmp(a: TwoTuple, b: TwoTuple) -> bool { // CHECK-SAME: (i16 noundef %[[A0:.+]], i16 noundef %[[A1:.+]], i16 noundef %[[B0:.+]], i16 noundef %[[B1:.+]]) #[no_mangle] pub fn check_ge_via_cmp(a: TwoTuple, b: TwoTuple) -> bool { - // FIXME-CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] - // FIXME-CHECK-DAG: %[[CMP0:.+]] = icmp sge i16 %[[A0]], %[[B0]] - // FIXME-CHECK-DAG: %[[CMP1:.+]] = icmp uge i16 %[[A1]], %[[B1]] - // FIXME-CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] - // FIXME-CHECK: ret i1 %[[R]] + // CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP0:.+]] = icmp sge i16 %[[A0]], %[[B0]] + // CHECK-DAG: %[[CMP1:.+]] = icmp uge i16 %[[A1]], %[[B1]] + // CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]] + // CHECK: ret i1 %[[R]] Ord::cmp(&a, &b).is_ge() } From 758ec1d33239ac0d7c8b427a7945e75900cdb689 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Tue, 18 Feb 2025 11:04:53 +0100 Subject: [PATCH 177/991] remove an unneeded `#![feature]` --- clippy_lints/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 6708be5b332c..5349b27de4a3 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1,5 +1,4 @@ #![feature(array_windows)] -#![feature(binary_heap_into_iter_sorted)] #![feature(box_patterns)] #![feature(macro_metavar_expr_concat)] #![feature(f128)] From 45f7a60d313f75709690bfcb1cc4232d0f44ed3f Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 2 Feb 2025 17:16:36 +0100 Subject: [PATCH 178/991] `.last()` to `.next_back()` requires a mutable receiver In the case where `iter` is a `DoubleEndedIterator`, replacing a call to `iter.last()` (which consumes `iter`) by `iter.next_back()` (which requires a mutable reference to `iter`) cannot be done when `iter` Is not a mutable binding or a mutable reference. When `iter` is a local binding, it can be made mutable by fixing its definition site. --- .../src/methods/double_ended_iterator_last.rs | 42 ++++++++++--- tests/ui/double_ended_iterator_last.fixed | 30 +++++++-- tests/ui/double_ended_iterator_last.rs | 30 +++++++-- tests/ui/double_ended_iterator_last.stderr | 62 +++++++++++++++++-- .../double_ended_iterator_last_unfixable.rs | 8 +++ ...ouble_ended_iterator_last_unfixable.stderr | 18 ++++++ 6 files changed, 169 insertions(+), 21 deletions(-) create mode 100644 tests/ui/double_ended_iterator_last_unfixable.rs create mode 100644 tests/ui/double_ended_iterator_last_unfixable.stderr diff --git a/clippy_lints/src/methods/double_ended_iterator_last.rs b/clippy_lints/src/methods/double_ended_iterator_last.rs index 208172980c9f..19797cc32f59 100644 --- a/clippy_lints/src/methods/double_ended_iterator_last.rs +++ b/clippy_lints/src/methods/double_ended_iterator_last.rs @@ -1,8 +1,8 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::is_trait_method; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::implements_trait; +use clippy_utils::{is_mutable, is_trait_method, path_to_local}; use rustc_errors::Applicability; -use rustc_hir::Expr; +use rustc_hir::{Expr, Node, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty::Instance; use rustc_span::{Span, sym}; @@ -28,14 +28,40 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, self_expr: &'_ Exp // if the resolved method is the same as the provided definition && fn_def.def_id() == last_def.def_id { - span_lint_and_sugg( + let mut sugg = vec![(call_span, String::from("next_back()"))]; + let mut dont_apply = false; + // if `self_expr` is a reference, it is mutable because it is used for `.last()` + if !(is_mutable(cx, self_expr) || self_type.is_ref()) { + if let Some(hir_id) = path_to_local(self_expr) + && let Node::Pat(pat) = cx.tcx.hir_node(hir_id) + && let PatKind::Binding(_, _, ident, _) = pat.kind + { + sugg.push((ident.span.shrink_to_lo(), String::from("mut "))); + } else { + // If we can't make the binding mutable, make the suggestion `Unspecified` to prevent it from being + // automatically applied, and add a complementary help message. + dont_apply = true; + } + } + span_lint_and_then( cx, DOUBLE_ENDED_ITERATOR_LAST, - call_span, + expr.span, "called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator", - "try", - "next_back()".to_string(), - Applicability::MachineApplicable, + |diag| { + diag.multipart_suggestion( + "try", + sugg, + if dont_apply { + Applicability::Unspecified + } else { + Applicability::MachineApplicable + }, + ); + if dont_apply { + diag.span_note(self_expr.span, "this must be made mutable to use `.next_back()`"); + } + }, ); } } diff --git a/tests/ui/double_ended_iterator_last.fixed b/tests/ui/double_ended_iterator_last.fixed index 08f3d4907153..09eba48ea89a 100644 --- a/tests/ui/double_ended_iterator_last.fixed +++ b/tests/ui/double_ended_iterator_last.fixed @@ -2,8 +2,7 @@ // Typical case pub fn last_arg(s: &str) -> Option<&str> { - s.split(' ').next_back() - //~^ double_ended_iterator_last + s.split(' ').next_back() //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` } fn main() { @@ -20,8 +19,7 @@ fn main() { Some(()) } } - let _ = DeIterator.next_back(); - //~^ double_ended_iterator_last + let _ = DeIterator.next_back(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` // Should not apply to other methods of Iterator let _ = DeIterator.count(); @@ -53,3 +51,27 @@ fn main() { } let _ = CustomLast.last(); } + +fn issue_14139() { + let mut index = [true, true, false, false, false, true].iter(); + let mut subindex = index.by_ref().take(3); + let _ = subindex.next_back(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + + let mut index = [true, true, false, false, false, true].iter(); + let mut subindex = index.by_ref().take(3); + let _ = subindex.next_back(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + + let mut index = [true, true, false, false, false, true].iter(); + let mut subindex = index.by_ref().take(3); + let subindex = &mut subindex; + let _ = subindex.next_back(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + + let mut index = [true, true, false, false, false, true].iter(); + let mut subindex = index.by_ref().take(3); + let subindex = &mut subindex; + let _ = subindex.next_back(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + + let mut index = [true, true, false, false, false, true].iter(); + let (mut subindex, _) = (index.by_ref().take(3), 42); + let _ = subindex.next_back(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` +} diff --git a/tests/ui/double_ended_iterator_last.rs b/tests/ui/double_ended_iterator_last.rs index 2c2f311805ef..2bde5e3ecb31 100644 --- a/tests/ui/double_ended_iterator_last.rs +++ b/tests/ui/double_ended_iterator_last.rs @@ -2,8 +2,7 @@ // Typical case pub fn last_arg(s: &str) -> Option<&str> { - s.split(' ').last() - //~^ double_ended_iterator_last + s.split(' ').last() //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` } fn main() { @@ -20,8 +19,7 @@ fn main() { Some(()) } } - let _ = DeIterator.last(); - //~^ double_ended_iterator_last + let _ = DeIterator.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` // Should not apply to other methods of Iterator let _ = DeIterator.count(); @@ -53,3 +51,27 @@ fn main() { } let _ = CustomLast.last(); } + +fn issue_14139() { + let mut index = [true, true, false, false, false, true].iter(); + let subindex = index.by_ref().take(3); + let _ = subindex.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + + let mut index = [true, true, false, false, false, true].iter(); + let mut subindex = index.by_ref().take(3); + let _ = subindex.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + + let mut index = [true, true, false, false, false, true].iter(); + let mut subindex = index.by_ref().take(3); + let subindex = &mut subindex; + let _ = subindex.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + + let mut index = [true, true, false, false, false, true].iter(); + let mut subindex = index.by_ref().take(3); + let subindex = &mut subindex; + let _ = subindex.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + + let mut index = [true, true, false, false, false, true].iter(); + let (subindex, _) = (index.by_ref().take(3), 42); + let _ = subindex.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` +} diff --git a/tests/ui/double_ended_iterator_last.stderr b/tests/ui/double_ended_iterator_last.stderr index ea1962176a61..6c900b078262 100644 --- a/tests/ui/double_ended_iterator_last.stderr +++ b/tests/ui/double_ended_iterator_last.stderr @@ -1,17 +1,69 @@ error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator - --> tests/ui/double_ended_iterator_last.rs:5:18 + --> tests/ui/double_ended_iterator_last.rs:5:5 | LL | s.split(' ').last() - | ^^^^^^ help: try: `next_back()` + | ^^^^^^^^^^^^^------ + | | + | help: try: `next_back()` | = note: `-D clippy::double-ended-iterator-last` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::double_ended_iterator_last)]` error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator - --> tests/ui/double_ended_iterator_last.rs:23:24 + --> tests/ui/double_ended_iterator_last.rs:22:13 | LL | let _ = DeIterator.last(); - | ^^^^^^ help: try: `next_back()` + | ^^^^^^^^^^^------ + | | + | help: try: `next_back()` -error: aborting due to 2 previous errors +error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator + --> tests/ui/double_ended_iterator_last.rs:58:13 + | +LL | let _ = subindex.last(); + | ^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ let mut subindex = index.by_ref().take(3); +LL ~ let _ = subindex.next_back(); + | + +error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator + --> tests/ui/double_ended_iterator_last.rs:62:13 + | +LL | let _ = subindex.last(); + | ^^^^^^^^^------ + | | + | help: try: `next_back()` + +error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator + --> tests/ui/double_ended_iterator_last.rs:67:13 + | +LL | let _ = subindex.last(); + | ^^^^^^^^^------ + | | + | help: try: `next_back()` + +error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator + --> tests/ui/double_ended_iterator_last.rs:72:13 + | +LL | let _ = subindex.last(); + | ^^^^^^^^^------ + | | + | help: try: `next_back()` + +error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator + --> tests/ui/double_ended_iterator_last.rs:76:13 + | +LL | let _ = subindex.last(); + | ^^^^^^^^^^^^^^^ + | +help: try + | +LL ~ let (mut subindex, _) = (index.by_ref().take(3), 42); +LL ~ let _ = subindex.next_back(); + | + +error: aborting due to 7 previous errors diff --git a/tests/ui/double_ended_iterator_last_unfixable.rs b/tests/ui/double_ended_iterator_last_unfixable.rs new file mode 100644 index 000000000000..edc2a05649dd --- /dev/null +++ b/tests/ui/double_ended_iterator_last_unfixable.rs @@ -0,0 +1,8 @@ +//@no-rustfix +#![warn(clippy::double_ended_iterator_last)] + +fn main() { + let mut index = [true, true, false, false, false, true].iter(); + let subindex = (index.by_ref().take(3), 42); + let _ = subindex.0.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` +} diff --git a/tests/ui/double_ended_iterator_last_unfixable.stderr b/tests/ui/double_ended_iterator_last_unfixable.stderr new file mode 100644 index 000000000000..9dd3f9386481 --- /dev/null +++ b/tests/ui/double_ended_iterator_last_unfixable.stderr @@ -0,0 +1,18 @@ +error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator + --> tests/ui/double_ended_iterator_last_unfixable.rs:7:13 + | +LL | let _ = subindex.0.last(); + | ^^^^^^^^^^^------ + | | + | help: try: `next_back()` + | +note: this must be made mutable to use `.next_back()` + --> tests/ui/double_ended_iterator_last_unfixable.rs:7:13 + | +LL | let _ = subindex.0.last(); + | ^^^^^^^^^^ + = note: `-D clippy::double-ended-iterator-last` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::double_ended_iterator_last)]` + +error: aborting due to 1 previous error + From 477a2eeb3dd5a430bb3845c8f8041ff369232967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 19 Feb 2025 02:00:02 +0800 Subject: [PATCH 179/991] std::fs: slightly reformat `remove_dir_all` error docs To make the error cases easier to spot on a quick glance. --- library/std/src/fs.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 6001a2e2f391..2b3a84d0a12c 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2841,9 +2841,11 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// /// See [`fs::remove_file`] and [`fs::remove_dir`]. /// -/// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root `path`. -/// As a result, the directory you are deleting must exist, meaning that this function is not idempotent. -/// Additionally, `remove_dir_all` will also fail if the `path` is not a directory. +/// [`remove_dir_all`] will fail if [`remove_dir`] or [`remove_file`] fail on *any* constituent +/// paths, *including* the root `path`. Consequently, +/// +/// - The directory you are deleting *must* exist, meaning that this function is *not idempotent*. +/// - [`remove_dir_all`] will fail if the `path` is *not* a directory. /// /// Consider ignoring the error if validating the removal is not required for your use case. /// From 939429a8b98b98d7a8f942f8e55b6b3639865497 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Wed, 19 Feb 2025 05:50:45 +0900 Subject: [PATCH 180/991] update `rustfix` link --- book/src/development/adding_lints.md | 2 +- book/src/development/writing_tests.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/development/adding_lints.md b/book/src/development/adding_lints.md index 48506127dee4..60135e96c5a5 100644 --- a/book/src/development/adding_lints.md +++ b/book/src/development/adding_lints.md @@ -169,7 +169,7 @@ from the lint to the code of the test file and compare that to the contents of a Use `cargo bless` to automatically generate the `.fixed` file while running the tests. -[rustfix]: https://github.com/rust-lang/rustfix +[rustfix]: https://github.com/rust-lang/cargo/tree/master/crates/rustfix ## Testing manually diff --git a/book/src/development/writing_tests.md b/book/src/development/writing_tests.md index 39a5ad966885..d4cca2a72f0b 100644 --- a/book/src/development/writing_tests.md +++ b/book/src/development/writing_tests.md @@ -203,7 +203,7 @@ We'll talk about suggestions more in depth in a [later chapter](emitting_lints.m Use `cargo bless` to automatically generate the `.fixed` file after running the tests. -[`rustfix`]: https://github.com/rust-lang/rustfix +[`rustfix`]: https://github.com/rust-lang/cargo/tree/master/crates/rustfix [`span_lint_and_sugg`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html ## Testing Manually From 20eb224a559c3bd74ed97efc7c98c0a25f5b5225 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Wed, 19 Feb 2025 05:06:01 +0000 Subject: [PATCH 181/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 0ea62d4d8502..a2a2f28ea71c 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -d1fb81e8dd5354ddf7cb334d5a234cab7f64b3bb +17c1c329a5512d718b67ef6797538b154016cd34 From e2cdfed0ea09e430f1b24351856b224eda3683d9 Mon Sep 17 00:00:00 2001 From: yanglsh Date: Wed, 5 Feb 2025 02:32:18 -0700 Subject: [PATCH 182/991] fix: `map_entry` FP on struct member --- clippy_lints/src/entry.rs | 17 ++++++++++++++++- tests/ui/entry.fixed | 23 +++++++++++++++++++++++ tests/ui/entry.rs | 23 +++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index 99d635aa5cc0..f8a5cf53cda0 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context}; +use clippy_utils::visitors::for_each_expr; use clippy_utils::{ SpanlessEq, can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified, peel_hir_expr_while, @@ -12,6 +13,7 @@ use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::{DUMMY_SP, Span, SyntaxContext, sym}; +use std::ops::ControlFlow; declare_clippy_lint! { /// ### What it does @@ -500,7 +502,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> { self.visit_non_tail_expr(insert_expr.value); self.is_single_insert = is_single_insert; }, - _ if SpanlessEq::new(self.cx).eq_expr(self.map, expr) => { + _ if is_any_expr_in_map_used(self.cx, self.map, expr) => { self.is_map_used = true; }, _ => match expr.kind { @@ -562,6 +564,19 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> { } } +/// Check if the given expression is used for each sub-expression in the given map. +/// For example, in map `a.b.c.my_map`, The expression `a.b.c.my_map`, `a.b.c`, `a.b`, and `a` are +/// all checked. +fn is_any_expr_in_map_used<'tcx>(cx: &LateContext<'tcx>, map: &'tcx Expr<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { + for_each_expr(cx, map, |e| { + if SpanlessEq::new(cx).eq_expr(e, expr) { + return ControlFlow::Break(()); + } + ControlFlow::Continue(()) + }) + .is_some() +} + struct InsertSearchResults<'tcx> { edits: Vec>, allow_insert_closure: bool, diff --git a/tests/ui/entry.fixed b/tests/ui/entry.fixed index 9856fa9b39fd..d52299306fd0 100644 --- a/tests/ui/entry.fixed +++ b/tests/ui/entry.fixed @@ -195,4 +195,27 @@ fn issue12489(map: &mut HashMap) -> Option<()> { Some(()) } +mod issue13934 { + use std::collections::HashMap; + + struct Member {} + + pub struct Foo { + members: HashMap, + } + + impl Foo { + pub fn should_also_not_cause_lint(&mut self, input: u8) { + if self.members.contains_key(&input) { + todo!(); + } else { + self.other(); + self.members.insert(input, Member {}); + } + } + + fn other(&self) {} + } +} + fn main() {} diff --git a/tests/ui/entry.rs b/tests/ui/entry.rs index bb8ebb4eac08..25cd6eaa4132 100644 --- a/tests/ui/entry.rs +++ b/tests/ui/entry.rs @@ -201,4 +201,27 @@ fn issue12489(map: &mut HashMap) -> Option<()> { Some(()) } +mod issue13934 { + use std::collections::HashMap; + + struct Member {} + + pub struct Foo { + members: HashMap, + } + + impl Foo { + pub fn should_also_not_cause_lint(&mut self, input: u8) { + if self.members.contains_key(&input) { + todo!(); + } else { + self.other(); + self.members.insert(input, Member {}); + } + } + + fn other(&self) {} + } +} + fn main() {} From dcd643a6524f0f18a17df9fecb6e9821c1f5b33b Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 14 Feb 2025 18:00:13 +0100 Subject: [PATCH 183/991] `double_ended_iterator_last`: note when drop order is changed `iter.last()` will drop all elements of `iter` in order, while `iter.next_back()` will drop the non-last elements of `iter` when `iter` goes out of scope since `.next_back()` does not consume its argument. When the transformation proposed by `double_ended_iterator_last` would concern an iterator whose element type has a significant drop, a note is added to warn about the possible drop order change, and the suggestion is switched from `MachineApplicable` to `MaybeIncorrect`. --- .../src/methods/double_ended_iterator_last.rs | 7 +++++++ tests/ui/double_ended_iterator_last.fixed | 15 +++++++++++++++ tests/ui/double_ended_iterator_last.rs | 15 +++++++++++++++ tests/ui/double_ended_iterator_last.stderr | 15 ++++++++++++++- .../ui/double_ended_iterator_last_unfixable.rs | 15 +++++++++++++++ .../double_ended_iterator_last_unfixable.stderr | 17 ++++++++++++++++- 6 files changed, 82 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/methods/double_ended_iterator_last.rs b/clippy_lints/src/methods/double_ended_iterator_last.rs index 19797cc32f59..e82211bbf3ef 100644 --- a/clippy_lints/src/methods/double_ended_iterator_last.rs +++ b/clippy_lints/src/methods/double_ended_iterator_last.rs @@ -49,15 +49,22 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, self_expr: &'_ Exp expr.span, "called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator", |diag| { + let expr_ty = cx.typeck_results().expr_ty(expr); + let droppable_elements = expr_ty.has_significant_drop(cx.tcx, cx.typing_env()); diag.multipart_suggestion( "try", sugg, if dont_apply { Applicability::Unspecified + } else if droppable_elements { + Applicability::MaybeIncorrect } else { Applicability::MachineApplicable }, ); + if droppable_elements { + diag.note("this change will alter drop order which may be undesirable"); + } if dont_apply { diag.span_note(self_expr.span, "this must be made mutable to use `.next_back()`"); } diff --git a/tests/ui/double_ended_iterator_last.fixed b/tests/ui/double_ended_iterator_last.fixed index 09eba48ea89a..17d0d71a8854 100644 --- a/tests/ui/double_ended_iterator_last.fixed +++ b/tests/ui/double_ended_iterator_last.fixed @@ -75,3 +75,18 @@ fn issue_14139() { let (mut subindex, _) = (index.by_ref().take(3), 42); let _ = subindex.next_back(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` } + +fn drop_order() { + struct S(&'static str); + impl std::ops::Drop for S { + fn drop(&mut self) { + println!("Dropping {}", self.0); + } + } + + let v = vec![S("one"), S("two"), S("three")]; + let mut v = v.into_iter(); + println!("Last element is {}", v.next_back().unwrap().0); + //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + println!("Done"); +} diff --git a/tests/ui/double_ended_iterator_last.rs b/tests/ui/double_ended_iterator_last.rs index 2bde5e3ecb31..41bc669b1719 100644 --- a/tests/ui/double_ended_iterator_last.rs +++ b/tests/ui/double_ended_iterator_last.rs @@ -75,3 +75,18 @@ fn issue_14139() { let (subindex, _) = (index.by_ref().take(3), 42); let _ = subindex.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` } + +fn drop_order() { + struct S(&'static str); + impl std::ops::Drop for S { + fn drop(&mut self) { + println!("Dropping {}", self.0); + } + } + + let v = vec![S("one"), S("two"), S("three")]; + let v = v.into_iter(); + println!("Last element is {}", v.last().unwrap().0); + //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + println!("Done"); +} diff --git a/tests/ui/double_ended_iterator_last.stderr b/tests/ui/double_ended_iterator_last.stderr index 6c900b078262..1702a24d7a05 100644 --- a/tests/ui/double_ended_iterator_last.stderr +++ b/tests/ui/double_ended_iterator_last.stderr @@ -65,5 +65,18 @@ LL ~ let (mut subindex, _) = (index.by_ref().take(3), 42); LL ~ let _ = subindex.next_back(); | -error: aborting due to 7 previous errors +error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator + --> tests/ui/double_ended_iterator_last.rs:89:36 + | +LL | println!("Last element is {}", v.last().unwrap().0); + | ^^^^^^^^ + | + = note: this change will alter drop order which may be undesirable +help: try + | +LL ~ let mut v = v.into_iter(); +LL ~ println!("Last element is {}", v.next_back().unwrap().0); + | + +error: aborting due to 8 previous errors diff --git a/tests/ui/double_ended_iterator_last_unfixable.rs b/tests/ui/double_ended_iterator_last_unfixable.rs index edc2a05649dd..3f125c7f20c1 100644 --- a/tests/ui/double_ended_iterator_last_unfixable.rs +++ b/tests/ui/double_ended_iterator_last_unfixable.rs @@ -6,3 +6,18 @@ fn main() { let subindex = (index.by_ref().take(3), 42); let _ = subindex.0.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator` } + +fn drop_order() { + struct S(&'static str); + impl std::ops::Drop for S { + fn drop(&mut self) { + println!("Dropping {}", self.0); + } + } + + let v = vec![S("one"), S("two"), S("three")]; + let v = (v.into_iter(), 42); + println!("Last element is {}", v.0.last().unwrap().0); + //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator` + println!("Done"); +} diff --git a/tests/ui/double_ended_iterator_last_unfixable.stderr b/tests/ui/double_ended_iterator_last_unfixable.stderr index 9dd3f9386481..f4be757d00d2 100644 --- a/tests/ui/double_ended_iterator_last_unfixable.stderr +++ b/tests/ui/double_ended_iterator_last_unfixable.stderr @@ -14,5 +14,20 @@ LL | let _ = subindex.0.last(); = note: `-D clippy::double-ended-iterator-last` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::double_ended_iterator_last)]` -error: aborting due to 1 previous error +error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator + --> tests/ui/double_ended_iterator_last_unfixable.rs:20:36 + | +LL | println!("Last element is {}", v.0.last().unwrap().0); + | ^^^^------ + | | + | help: try: `next_back()` + | + = note: this change will alter drop order which may be undesirable +note: this must be made mutable to use `.next_back()` + --> tests/ui/double_ended_iterator_last_unfixable.rs:20:36 + | +LL | println!("Last element is {}", v.0.last().unwrap().0); + | ^^^ + +error: aborting due to 2 previous errors From 83f5cbad188a905ec5793002b36e5d27a7a20890 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Sun, 5 Jan 2025 13:34:27 +0100 Subject: [PATCH 184/991] add `owned_cow` lint --- CHANGELOG.md | 1 + book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/types/mod.rs | 62 ++++++++- clippy_lints/src/types/owned_cow.rs | 66 ++++++++++ tests/ui/owned_cow.fixed | 23 ++++ tests/ui/owned_cow.rs | 23 ++++ tests/ui/owned_cow.stderr | 41 ++++++ tests/ui/unnecessary_to_owned.fixed | 3 +- tests/ui/unnecessary_to_owned.rs | 3 +- tests/ui/unnecessary_to_owned.stderr | 186 +++++++++++++-------------- 12 files changed, 315 insertions(+), 96 deletions(-) create mode 100644 clippy_lints/src/types/owned_cow.rs create mode 100644 tests/ui/owned_cow.fixed create mode 100644 tests/ui/owned_cow.rs create mode 100644 tests/ui/owned_cow.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b8695f66279..a4d20b2586ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5942,6 +5942,7 @@ Released 2018-09-13 [`out_of_bounds_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing [`overflow_check_conditional`]: https://rust-lang.github.io/rust-clippy/master/index.html#overflow_check_conditional [`overly_complex_bool_expr`]: https://rust-lang.github.io/rust-clippy/master/index.html#overly_complex_bool_expr +[`owned_cow`]: https://rust-lang.github.io/rust-clippy/master/index.html#owned_cow [`panic`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic [`panic_in_result_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_in_result_fn [`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 0e264cdcd4a3..1fb59ca85fe8 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -380,6 +380,7 @@ Suppress lints whenever the suggested change would cause breakage for other crat * [`linkedlist`](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist) * [`needless_pass_by_ref_mut`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut) * [`option_option`](https://rust-lang.github.io/rust-clippy/master/index.html#option_option) +* [`owned_cow`](https://rust-lang.github.io/rust-clippy/master/index.html#owned_cow) * [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer) * [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex) * [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index cac4408fff0e..9436ba7f1809 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -438,6 +438,7 @@ define_Conf! { linkedlist, needless_pass_by_ref_mut, option_option, + owned_cow, rc_buffer, rc_mutex, redundant_allocation, diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 4b439d3a7a2d..011eed25552c 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -745,6 +745,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::types::BOX_COLLECTION_INFO, crate::types::LINKEDLIST_INFO, crate::types::OPTION_OPTION_INFO, + crate::types::OWNED_COW_INFO, crate::types::RC_BUFFER_INFO, crate::types::RC_MUTEX_INFO, crate::types::REDUNDANT_ALLOCATION_INFO, diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 579cbf447a2b..7385b13578da 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -2,6 +2,7 @@ mod borrowed_box; mod box_collection; mod linked_list; mod option_option; +mod owned_cow; mod rc_buffer; mod rc_mutex; mod redundant_allocation; @@ -355,13 +356,63 @@ declare_clippy_lint! { "usage of `Rc>`" } +declare_clippy_lint! { + /// ### What it does + /// Detects needlessly owned `Cow` types. + /// + /// ### Why is this bad? + /// The borrowed types are usually more flexible, in that e.g. a + /// `Cow<'_, str>` can accept both `&str` and `String` while + /// `Cow<'_, String>` can only accept `&String` and `String`. In + /// particular, `&str` is more general, because it allows for string + /// literals while `&String` can only be borrowed from a heap-owned + /// `String`). + /// + /// ### Known Problems + /// The lint does not check for usage of the type. There may be external + /// interfaces that require the use of an owned type. + /// + /// At least the `CString` type also has a different API than `CStr`: The + /// former has an `as_bytes` method which the latter calls `to_bytes`. + /// There is no guarantee that other types won't gain additional methods + /// leading to a similar mismatch. + /// + /// In addition, the lint only checks for the known problematic types + /// `String`, `Vec<_>`, `CString`, `OsString` and `PathBuf`. Custom types + /// that implement `ToOwned` will not be detected. + /// + /// ### Example + /// ```no_run + /// let wrogn: std::borrow::Cow<'_, Vec>; + /// ``` + /// Use instead: + /// ```no_run + /// let right: std::borrow::Cow<'_, [u8]>; + /// ``` + #[clippy::version = "1.85.0"] + pub OWNED_COW, + style, + "needlessly owned Cow type" +} + pub struct Types { vec_box_size_threshold: u64, type_complexity_threshold: u64, avoid_breaking_exported_api: bool, } -impl_lint_pass!(Types => [BOX_COLLECTION, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION, RC_BUFFER, RC_MUTEX, TYPE_COMPLEXITY]); +impl_lint_pass!(Types => [ + BOX_COLLECTION, + VEC_BOX, + OPTION_OPTION, + LINKEDLIST, + BORROWED_BOX, + REDUNDANT_ALLOCATION, + RC_BUFFER, + RC_MUTEX, + TYPE_COMPLEXITY, + OWNED_COW +]); impl<'tcx> LateLintPass<'tcx> for Types { fn check_fn( @@ -561,6 +612,7 @@ impl Types { triggered |= option_option::check(cx, hir_ty, qpath, def_id); triggered |= linked_list::check(cx, hir_ty, def_id); triggered |= rc_mutex::check(cx, hir_ty, qpath, def_id); + triggered |= owned_cow::check(cx, qpath, def_id); if triggered { return; @@ -612,6 +664,14 @@ impl Types { QPath::LangItem(..) => {}, } }, + TyKind::Path(ref qpath) => { + let res = cx.qpath_res(qpath, hir_ty.hir_id); + if let Some(def_id) = res.opt_def_id() + && self.is_type_change_allowed(context) + { + owned_cow::check(cx, qpath, def_id); + } + }, TyKind::Ref(lt, ref mut_ty) => { context.is_nested_call = true; if !borrowed_box::check(cx, hir_ty, lt, mut_ty) { diff --git a/clippy_lints/src/types/owned_cow.rs b/clippy_lints/src/types/owned_cow.rs new file mode 100644 index 000000000000..8933994d1855 --- /dev/null +++ b/clippy_lints/src/types/owned_cow.rs @@ -0,0 +1,66 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_opt; +use rustc_errors::Applicability; +use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir}; +use rustc_lint::LateContext; +use rustc_span::{Span, sym}; + +pub(super) fn check(cx: &LateContext<'_>, qpath: &hir::QPath<'_>, def_id: DefId) -> bool { + if cx.tcx.is_diagnostic_item(sym::Cow, def_id) + && let hir::QPath::Resolved(_, path) = qpath + && let [.., last_seg] = path.segments + && let Some(args) = last_seg.args + && let [_lt, carg] = args.args + && let hir::GenericArg::Type(cty) = carg + && let Some((span, repl)) = replacement(cx, cty.as_unambig_ty()) + { + span_lint_and_sugg( + cx, + super::OWNED_COW, + span, + "needlessly owned Cow type", + "use", + repl, + Applicability::Unspecified, + ); + return true; + } + false +} + +fn replacement(cx: &LateContext<'_>, cty: &hir::Ty<'_>) -> Option<(Span, String)> { + if clippy_utils::is_path_lang_item(cx, cty, hir::LangItem::String) { + return Some((cty.span, "str".into())); + } + if clippy_utils::is_path_diagnostic_item(cx, cty, sym::Vec) { + return if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = cty.kind + && let [.., last_seg] = path.segments + && let Some(args) = last_seg.args + && let [t, ..] = args.args + && let Some(snip) = snippet_opt(cx, t.span()) + { + Some((cty.span, format!("[{snip}]"))) + } else { + None + }; + } + if clippy_utils::is_path_diagnostic_item(cx, cty, sym::cstring_type) { + return Some(( + cty.span, + (if clippy_utils::is_no_std_crate(cx) { + "core::ffi::CStr" + } else { + "std::ffi::CStr" + }) + .into(), + )); + } + // Neither OsString nor PathBuf are available outside std + for (diag, repl) in [(sym::OsString, "std::ffi::OsStr"), (sym::PathBuf, "std::path::Path")] { + if clippy_utils::is_path_diagnostic_item(cx, cty, diag) { + return Some((cty.span, repl.into())); + } + } + None +} diff --git a/tests/ui/owned_cow.fixed b/tests/ui/owned_cow.fixed new file mode 100644 index 000000000000..b62e9107a561 --- /dev/null +++ b/tests/ui/owned_cow.fixed @@ -0,0 +1,23 @@ +#![warn(clippy::owned_cow)] + +use std::borrow::Cow; +use std::ffi::{CString, OsString}; +use std::path::PathBuf; + +fn main() { + let x: Cow<'static, str> = Cow::Owned(String::from("Hi!")); + //~^ ERROR: needlessly owned Cow type + let y: Cow<'_, [u8]> = Cow::Owned(vec![]); + //~^ ERROR: needlessly owned Cow type + let z: Cow<'_, [_]> = Cow::Owned(vec![2_i32]); + //~^ ERROR: needlessly owned Cow type + let o: Cow<'_, std::ffi::OsStr> = Cow::Owned(OsString::new()); + //~^ ERROR: needlessly owned Cow type + let c: Cow<'_, std::ffi::CStr> = Cow::Owned(CString::new("").unwrap()); + //~^ ERROR: needlessly owned Cow type + let p: Cow<'_, std::path::Path> = Cow::Owned(PathBuf::new()); + //~^ ERROR: needlessly owned Cow type + + // false positive: borrowed type + let b: Cow<'_, str> = Cow::Borrowed("Hi!"); +} diff --git a/tests/ui/owned_cow.rs b/tests/ui/owned_cow.rs new file mode 100644 index 000000000000..0e0f14711b7f --- /dev/null +++ b/tests/ui/owned_cow.rs @@ -0,0 +1,23 @@ +#![warn(clippy::owned_cow)] + +use std::borrow::Cow; +use std::ffi::{CString, OsString}; +use std::path::PathBuf; + +fn main() { + let x: Cow<'static, String> = Cow::Owned(String::from("Hi!")); + //~^ ERROR: needlessly owned Cow type + let y: Cow<'_, Vec> = Cow::Owned(vec![]); + //~^ ERROR: needlessly owned Cow type + let z: Cow<'_, Vec<_>> = Cow::Owned(vec![2_i32]); + //~^ ERROR: needlessly owned Cow type + let o: Cow<'_, OsString> = Cow::Owned(OsString::new()); + //~^ ERROR: needlessly owned Cow type + let c: Cow<'_, CString> = Cow::Owned(CString::new("").unwrap()); + //~^ ERROR: needlessly owned Cow type + let p: Cow<'_, PathBuf> = Cow::Owned(PathBuf::new()); + //~^ ERROR: needlessly owned Cow type + + // false positive: borrowed type + let b: Cow<'_, str> = Cow::Borrowed("Hi!"); +} diff --git a/tests/ui/owned_cow.stderr b/tests/ui/owned_cow.stderr new file mode 100644 index 000000000000..8985d6db623d --- /dev/null +++ b/tests/ui/owned_cow.stderr @@ -0,0 +1,41 @@ +error: needlessly owned Cow type + --> tests/ui/owned_cow.rs:8:25 + | +LL | let x: Cow<'static, String> = Cow::Owned(String::from("Hi!")); + | ^^^^^^ help: use: `str` + | + = note: `-D clippy::owned-cow` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::owned_cow)]` + +error: needlessly owned Cow type + --> tests/ui/owned_cow.rs:10:20 + | +LL | let y: Cow<'_, Vec> = Cow::Owned(vec![]); + | ^^^^^^^ help: use: `[u8]` + +error: needlessly owned Cow type + --> tests/ui/owned_cow.rs:12:20 + | +LL | let z: Cow<'_, Vec<_>> = Cow::Owned(vec![2_i32]); + | ^^^^^^ help: use: `[_]` + +error: needlessly owned Cow type + --> tests/ui/owned_cow.rs:14:20 + | +LL | let o: Cow<'_, OsString> = Cow::Owned(OsString::new()); + | ^^^^^^^^ help: use: `std::ffi::OsStr` + +error: needlessly owned Cow type + --> tests/ui/owned_cow.rs:16:20 + | +LL | let c: Cow<'_, CString> = Cow::Owned(CString::new("").unwrap()); + | ^^^^^^^ help: use: `std::ffi::CStr` + +error: needlessly owned Cow type + --> tests/ui/owned_cow.rs:18:20 + | +LL | let p: Cow<'_, PathBuf> = Cow::Owned(PathBuf::new()); + | ^^^^^^^ help: use: `std::path::Path` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed index 136dafda27ea..bf271aef763b 100644 --- a/tests/ui/unnecessary_to_owned.fixed +++ b/tests/ui/unnecessary_to_owned.fixed @@ -3,7 +3,8 @@ clippy::needless_borrows_for_generic_args, clippy::ptr_arg, clippy::manual_async_fn, - clippy::needless_lifetimes + clippy::needless_lifetimes, + clippy::owned_cow )] #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)] diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs index 0948ac5de3ef..95b95ab6bd22 100644 --- a/tests/ui/unnecessary_to_owned.rs +++ b/tests/ui/unnecessary_to_owned.rs @@ -3,7 +3,8 @@ clippy::needless_borrows_for_generic_args, clippy::ptr_arg, clippy::manual_async_fn, - clippy::needless_lifetimes + clippy::needless_lifetimes, + clippy::owned_cow )] #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)] diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr index f8ad85dbed02..4daa3876e60e 100644 --- a/tests/ui/unnecessary_to_owned.stderr +++ b/tests/ui/unnecessary_to_owned.stderr @@ -1,11 +1,11 @@ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:224:64 + --> tests/ui/unnecessary_to_owned.rs:225:64 | LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:224:20 + --> tests/ui/unnecessary_to_owned.rs:225:20 | LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,55 +13,55 @@ LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()) = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]` error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:226:40 + --> tests/ui/unnecessary_to_owned.rs:227:40 | LL | require_os_str(&OsString::from("x").to_os_string()); | ^^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:226:21 + --> tests/ui/unnecessary_to_owned.rs:227:21 | LL | require_os_str(&OsString::from("x").to_os_string()); | ^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:228:48 + --> tests/ui/unnecessary_to_owned.rs:229:48 | LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); | ^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:228:19 + --> tests/ui/unnecessary_to_owned.rs:229:19 | LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:230:35 + --> tests/ui/unnecessary_to_owned.rs:231:35 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:230:18 + --> tests/ui/unnecessary_to_owned.rs:231:18 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:232:39 + --> tests/ui/unnecessary_to_owned.rs:233:39 | LL | require_slice(&[String::from("x")].to_owned()); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:232:20 + --> tests/ui/unnecessary_to_owned.rs:233:20 | LL | require_slice(&[String::from("x")].to_owned()); | ^^^^^^^^^^^^^^^^^^^ error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:64:36 + --> tests/ui/unnecessary_to_owned.rs:65:36 | LL | require_c_str(&Cow::from(c_str).into_owned()); | ^^^^^^^^^^^^^ help: remove this @@ -70,415 +70,415 @@ LL | require_c_str(&Cow::from(c_str).into_owned()); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:66:19 + --> tests/ui/unnecessary_to_owned.rs:67:19 | LL | require_c_str(&c_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_os_string` - --> tests/ui/unnecessary_to_owned.rs:69:20 + --> tests/ui/unnecessary_to_owned.rs:70:20 | LL | require_os_str(&os_str.to_os_string()); | ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:71:38 + --> tests/ui/unnecessary_to_owned.rs:72:38 | LL | require_os_str(&Cow::from(os_str).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:73:20 + --> tests/ui/unnecessary_to_owned.rs:74:20 | LL | require_os_str(&os_str.to_owned()); | ^^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_path_buf` - --> tests/ui/unnecessary_to_owned.rs:76:18 + --> tests/ui/unnecessary_to_owned.rs:77:18 | LL | require_path(&path.to_path_buf()); | ^^^^^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:78:34 + --> tests/ui/unnecessary_to_owned.rs:79:34 | LL | require_path(&Cow::from(path).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:80:18 + --> tests/ui/unnecessary_to_owned.rs:81:18 | LL | require_path(&path.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:83:17 + --> tests/ui/unnecessary_to_owned.rs:84:17 | LL | require_str(&s.to_string()); | ^^^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:85:30 + --> tests/ui/unnecessary_to_owned.rs:86:30 | LL | require_str(&Cow::from(s).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:87:17 + --> tests/ui/unnecessary_to_owned.rs:88:17 | LL | require_str(&s.to_owned()); | ^^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:89:17 + --> tests/ui/unnecessary_to_owned.rs:90:17 | LL | require_str(&x_ref.to_string()); | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:92:19 + --> tests/ui/unnecessary_to_owned.rs:93:19 | LL | require_slice(&slice.to_vec()); | ^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:94:36 + --> tests/ui/unnecessary_to_owned.rs:95:36 | LL | require_slice(&Cow::from(slice).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:96:19 + --> tests/ui/unnecessary_to_owned.rs:97:19 | LL | require_slice(&array.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:98:19 + --> tests/ui/unnecessary_to_owned.rs:99:19 | LL | require_slice(&array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:100:19 + --> tests/ui/unnecessary_to_owned.rs:101:19 | LL | require_slice(&slice.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:104:42 + --> tests/ui/unnecessary_to_owned.rs:105:42 | LL | require_x(&Cow::::Owned(x.clone()).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:108:25 + --> tests/ui/unnecessary_to_owned.rs:109:25 | LL | require_deref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:110:26 + --> tests/ui/unnecessary_to_owned.rs:111:26 | LL | require_deref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:112:24 + --> tests/ui/unnecessary_to_owned.rs:113:24 | LL | require_deref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:114:23 + --> tests/ui/unnecessary_to_owned.rs:115:23 | LL | require_deref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:116:25 + --> tests/ui/unnecessary_to_owned.rs:117:25 | LL | require_deref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:119:30 + --> tests/ui/unnecessary_to_owned.rs:120:30 | LL | require_impl_deref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:121:31 + --> tests/ui/unnecessary_to_owned.rs:122:31 | LL | require_impl_deref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:123:29 + --> tests/ui/unnecessary_to_owned.rs:124:29 | LL | require_impl_deref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:125:28 + --> tests/ui/unnecessary_to_owned.rs:126:28 | LL | require_impl_deref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:127:30 + --> tests/ui/unnecessary_to_owned.rs:128:30 | LL | require_impl_deref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:130:29 + --> tests/ui/unnecessary_to_owned.rs:131:29 | LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:130:43 + --> tests/ui/unnecessary_to_owned.rs:131:43 | LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:133:29 + --> tests/ui/unnecessary_to_owned.rs:134:29 | LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:133:47 + --> tests/ui/unnecessary_to_owned.rs:134:47 | LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:137:26 + --> tests/ui/unnecessary_to_owned.rs:138:26 | LL | require_as_ref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:139:27 + --> tests/ui/unnecessary_to_owned.rs:140:27 | LL | require_as_ref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:141:25 + --> tests/ui/unnecessary_to_owned.rs:142:25 | LL | require_as_ref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:143:24 + --> tests/ui/unnecessary_to_owned.rs:144:24 | LL | require_as_ref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:145:24 + --> tests/ui/unnecessary_to_owned.rs:146:24 | LL | require_as_ref_str(x.to_owned()); | ^^^^^^^^^^^^ help: use: `&x` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:147:26 + --> tests/ui/unnecessary_to_owned.rs:148:26 | LL | require_as_ref_slice(array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:149:26 + --> tests/ui/unnecessary_to_owned.rs:150:26 | LL | require_as_ref_slice(array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:151:26 + --> tests/ui/unnecessary_to_owned.rs:152:26 | LL | require_as_ref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:154:31 + --> tests/ui/unnecessary_to_owned.rs:155:31 | LL | require_impl_as_ref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:156:32 + --> tests/ui/unnecessary_to_owned.rs:157:32 | LL | require_impl_as_ref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:158:30 + --> tests/ui/unnecessary_to_owned.rs:159:30 | LL | require_impl_as_ref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:160:29 + --> tests/ui/unnecessary_to_owned.rs:161:29 | LL | require_impl_as_ref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:162:29 + --> tests/ui/unnecessary_to_owned.rs:163:29 | LL | require_impl_as_ref_str(x.to_owned()); | ^^^^^^^^^^^^ help: use: `&x` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:164:31 + --> tests/ui/unnecessary_to_owned.rs:165:31 | LL | require_impl_as_ref_slice(array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:166:31 + --> tests/ui/unnecessary_to_owned.rs:167:31 | LL | require_impl_as_ref_slice(array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:168:31 + --> tests/ui/unnecessary_to_owned.rs:169:31 | LL | require_impl_as_ref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:171:30 + --> tests/ui/unnecessary_to_owned.rs:172:30 | LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:171:44 + --> tests/ui/unnecessary_to_owned.rs:172:44 | LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:174:30 + --> tests/ui/unnecessary_to_owned.rs:175:30 | LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:174:44 + --> tests/ui/unnecessary_to_owned.rs:175:44 | LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:177:30 + --> tests/ui/unnecessary_to_owned.rs:178:30 | LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:177:44 + --> tests/ui/unnecessary_to_owned.rs:178:44 | LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:180:30 + --> tests/ui/unnecessary_to_owned.rs:181:30 | LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:180:48 + --> tests/ui/unnecessary_to_owned.rs:181:48 | LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:183:30 + --> tests/ui/unnecessary_to_owned.rs:184:30 | LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:183:52 + --> tests/ui/unnecessary_to_owned.rs:184:52 | LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:186:30 + --> tests/ui/unnecessary_to_owned.rs:187:30 | LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:186:48 + --> tests/ui/unnecessary_to_owned.rs:187:48 | LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:190:20 + --> tests/ui/unnecessary_to_owned.rs:191:20 | LL | let _ = x.join(&x_ref.to_string()); | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:193:13 + --> tests/ui/unnecessary_to_owned.rs:194:13 | LL | let _ = slice.to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:195:13 + --> tests/ui/unnecessary_to_owned.rs:196:13 | LL | let _ = slice.to_owned().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:197:13 + --> tests/ui/unnecessary_to_owned.rs:198:13 | LL | let _ = [std::path::PathBuf::new()][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:199:13 + --> tests/ui/unnecessary_to_owned.rs:200:13 | LL | let _ = [std::path::PathBuf::new()][..].to_owned().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:202:13 + --> tests/ui/unnecessary_to_owned.rs:203:13 | LL | let _ = IntoIterator::into_iter(slice.to_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:204:13 + --> tests/ui/unnecessary_to_owned.rs:205:13 | LL | let _ = IntoIterator::into_iter(slice.to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:206:13 + --> tests/ui/unnecessary_to_owned.rs:207:13 | LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:208:13 + --> tests/ui/unnecessary_to_owned.rs:209:13 | LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:236:26 + --> tests/ui/unnecessary_to_owned.rs:237:26 | LL | let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -490,7 +490,7 @@ LL + let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8"); | error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:238:26 + --> tests/ui/unnecessary_to_owned.rs:239:26 | LL | let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -502,7 +502,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo").unwrap(); | error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:240:26 + --> tests/ui/unnecessary_to_owned.rs:241:26 | LL | let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -514,7 +514,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap(); | error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:298:14 + --> tests/ui/unnecessary_to_owned.rs:299:14 | LL | for t in file_types.to_vec() { | ^^^^^^^^^^^^^^^^^^^ @@ -527,61 +527,61 @@ LL ~ let path = match get_file_path(t) { | error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:322:14 + --> tests/ui/unnecessary_to_owned.rs:323:14 | LL | let _ = &["x"][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:328:14 + --> tests/ui/unnecessary_to_owned.rs:329:14 | LL | let _ = &["x"][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:377:24 + --> tests/ui/unnecessary_to_owned.rs:378:24 | LL | Box::new(build(y.to_string())) | ^^^^^^^^^^^^^ help: use: `y` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:487:12 + --> tests/ui/unnecessary_to_owned.rs:488:12 | LL | id("abc".to_string()) | ^^^^^^^^^^^^^^^^^ help: use: `"abc"` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:631:37 + --> tests/ui/unnecessary_to_owned.rs:632:37 | LL | IntoFuture::into_future(foo([].to_vec(), &0)); | ^^^^^^^^^^^ help: use: `[]` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:642:18 + --> tests/ui/unnecessary_to_owned.rs:643:18 | LL | s.remove(&a.to_vec()); | ^^^^^^^^^^^ help: replace it with: `a` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:647:14 + --> tests/ui/unnecessary_to_owned.rs:648:14 | LL | s.remove(&"b".to_owned()); | ^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:649:14 + --> tests/ui/unnecessary_to_owned.rs:650:14 | LL | s.remove(&"b".to_string()); | ^^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:655:14 + --> tests/ui/unnecessary_to_owned.rs:656:14 | LL | s.remove(&["b"].to_vec()); | ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:657:14 + --> tests/ui/unnecessary_to_owned.rs:658:14 | LL | s.remove(&(&["b"]).to_vec()); | ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()` From 0842f2c65c766301be488256a18d89e90c3b6304 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Wed, 5 Feb 2025 19:37:27 -0800 Subject: [PATCH 185/991] Add fast path for displaying pre-validated Wtf8Buf --- library/std/src/sys/os_str/wtf8.rs | 4 ++-- library/std/src/sys_common/wtf8.rs | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index 19728d33990a..8acec6f949fc 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -41,13 +41,13 @@ impl AsInner for Buf { impl fmt::Debug for Buf { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self.as_slice(), f) + fmt::Debug::fmt(&self.inner, f) } } impl fmt::Display for Buf { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.as_slice(), f) + fmt::Display::fmt(&self.inner, f) } } diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 952c39132b05..01cbb3e24ff8 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -169,6 +169,18 @@ impl fmt::Debug for Wtf8Buf { } } +/// Formats the string with unpaired surrogates substituted with the replacement +/// character, U+FFFD. +impl fmt::Display for Wtf8Buf { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(s) = self.as_known_utf8() { + fmt::Display::fmt(s, formatter) + } else { + fmt::Display::fmt(&**self, formatter) + } + } +} + impl Wtf8Buf { /// Creates a new, empty WTF-8 string. #[inline] @@ -262,6 +274,18 @@ impl Wtf8Buf { unsafe { Wtf8::from_mut_bytes_unchecked(&mut self.bytes) } } + /// Converts the string to UTF-8 without validation, if it was created from + /// valid UTF-8. + #[inline] + fn as_known_utf8(&self) -> Option<&str> { + if self.is_known_utf8 { + // SAFETY: The buffer is known to be valid UTF-8. + Some(unsafe { str::from_utf8_unchecked(self.as_bytes()) }) + } else { + None + } + } + /// Reserves capacity for at least `additional` more bytes to be inserted /// in the given `Wtf8Buf`. /// The collection may reserve more space to avoid frequent reallocations. From eb14652770451022d424a1c301a4416514464932 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Fri, 7 Feb 2025 11:54:02 -0800 Subject: [PATCH 186/991] Skip scanning for surrogates when not known valid --- library/std/src/sys_common/wtf8.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 01cbb3e24ff8..f9ec112b1974 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -388,7 +388,7 @@ impl Wtf8Buf { _ => { // If we'll be pushing a string containing a surrogate, we may // no longer have UTF-8. - if other.next_surrogate(0).is_some() { + if self.is_known_utf8 && other.next_surrogate(0).is_some() { self.is_known_utf8 = false; } From 90bd46bfc3e3a7c1ff67e7693f1b354264bb253b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 19 Feb 2025 14:08:52 +1100 Subject: [PATCH 187/991] Simplify `Postorder` customization. `Postorder` has a `C: Customization<'tcx>` parameter, that gives it flexibility about how it computes successors. But in practice, there are only two `impls` of `Customization`, and one is for the unit type. This commit simplifies things by removing the generic parameter and replacing it with an `Option`. --- clippy_utils/src/mir/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_utils/src/mir/mod.rs b/clippy_utils/src/mir/mod.rs index 637c0bafd964..ffcfcd240ea5 100644 --- a/clippy_utils/src/mir/mod.rs +++ b/clippy_utils/src/mir/mod.rs @@ -30,7 +30,7 @@ pub fn visit_local_usage(locals: &[Local], mir: &Body<'_>, location: Location) - locals.len() ]; - traversal::Postorder::new(&mir.basic_blocks, location.block, ()) + traversal::Postorder::new(&mir.basic_blocks, location.block, None) .collect::>() .into_iter() .rev() From c293af9b57a3eae2969d49f629b67bb3d88c1bf3 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Wed, 19 Feb 2025 21:06:48 -0700 Subject: [PATCH 188/991] add `IntoBounds::intersect` and `RangeBounds::is_empty` --- library/core/src/ops/range.rs | 140 +++++++++++++++++- .../method-suggestion-no-duplication.stderr | 3 +- 2 files changed, 137 insertions(+), 6 deletions(-) diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index 5580faefacc0..e0c442e52921 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -771,13 +771,11 @@ pub trait RangeBounds { /// # Examples /// /// ``` - /// # fn main() { /// use std::ops::Bound::*; /// use std::ops::RangeBounds; /// /// assert_eq!((..10).start_bound(), Unbounded); /// assert_eq!((3..10).start_bound(), Included(&3)); - /// # } /// ``` #[stable(feature = "collections_range", since = "1.28.0")] fn start_bound(&self) -> Bound<&T>; @@ -789,13 +787,11 @@ pub trait RangeBounds { /// # Examples /// /// ``` - /// # fn main() { /// use std::ops::Bound::*; /// use std::ops::RangeBounds; /// /// assert_eq!((3..).end_bound(), Unbounded); /// assert_eq!((3..10).end_bound(), Excluded(&10)); - /// # } /// ``` #[stable(feature = "collections_range", since = "1.28.0")] fn end_bound(&self) -> Bound<&T>; @@ -829,6 +825,71 @@ pub trait RangeBounds { Unbounded => true, }) } + + /// Returns `true` if the range contains no items. + /// One-sided ranges (`RangeFrom`, etc) always return `true`. + /// + /// # Examples + /// + /// ``` + /// #![feature(range_bounds_is_empty)] + /// use std::ops::RangeBounds; + /// + /// assert!(!(3..).is_empty()); + /// assert!(!(..2).is_empty()); + /// assert!(!RangeBounds::is_empty(&(3..5))); + /// assert!( RangeBounds::is_empty(&(3..3))); + /// assert!( RangeBounds::is_empty(&(3..2))); + /// ``` + /// + /// The range is empty if either side is incomparable: + /// + /// ``` + /// #![feature(range_bounds_is_empty)] + /// use std::ops::RangeBounds; + /// + /// assert!(!RangeBounds::is_empty(&(3.0..5.0))); + /// assert!( RangeBounds::is_empty(&(3.0..f32::NAN))); + /// assert!( RangeBounds::is_empty(&(f32::NAN..5.0))); + /// ``` + /// + /// But never empty is either side is unbounded: + /// + /// ``` + /// #![feature(range_bounds_is_empty)] + /// use std::ops::RangeBounds; + /// + /// assert!(!(..0).is_empty()); + /// assert!(!(i32::MAX..).is_empty()); + /// assert!(!RangeBounds::::is_empty(&(..))); + /// ``` + /// + /// `(Excluded(a), Excluded(b))` is only empty if `a >= b`: + /// + /// ``` + /// #![feature(range_bounds_is_empty)] + /// use std::ops::Bound::*; + /// use std::ops::RangeBounds; + /// + /// assert!(!(Excluded(1), Excluded(3)).is_empty()); + /// assert!(!(Excluded(1), Excluded(2)).is_empty()); + /// assert!( (Excluded(1), Excluded(1)).is_empty()); + /// assert!( (Excluded(2), Excluded(1)).is_empty()); + /// assert!( (Excluded(3), Excluded(1)).is_empty()); + /// ``` + #[unstable(feature = "range_bounds_is_empty", issue = "137300")] + fn is_empty(&self) -> bool + where + T: PartialOrd, + { + !match (self.start_bound(), self.end_bound()) { + (Unbounded, _) | (_, Unbounded) => true, + (Included(start), Excluded(end)) + | (Excluded(start), Included(end)) + | (Excluded(start), Excluded(end)) => start < end, + (Included(start), Included(end)) => start <= end, + } + } } /// Used to convert a range into start and end bounds, consuming the @@ -845,7 +906,6 @@ pub trait IntoBounds: RangeBounds { /// /// ``` /// #![feature(range_into_bounds)] - /// /// use std::ops::Bound::*; /// use std::ops::IntoBounds; /// @@ -853,6 +913,76 @@ pub trait IntoBounds: RangeBounds { /// assert_eq!((..=7).into_bounds(), (Unbounded, Included(7))); /// ``` fn into_bounds(self) -> (Bound, Bound); + + /// Compute the intersection of `self` and `other`. + /// + /// # Examples + /// + /// ``` + /// #![feature(range_into_bounds)] + /// use std::ops::Bound::*; + /// use std::ops::IntoBounds; + /// + /// assert_eq!((3..).intersect(..5), (Included(3), Excluded(5))); + /// assert_eq!((-12..387).intersect(0..256), (Included(0), Excluded(256))); + /// assert_eq!((1..5).intersect(..), (Included(1), Excluded(5))); + /// assert_eq!((1..=9).intersect(0..10), (Included(1), Included(9))); + /// assert_eq!((7..=13).intersect(8..13), (Included(8), Excluded(13))); + /// ``` + /// + /// Combine with `is_empty` to determine if two ranges overlap. + /// + /// ``` + /// #![feature(range_into_bounds)] + /// #![feature(range_bounds_is_empty)] + /// use std::ops::{RangeBounds, IntoBounds}; + /// + /// assert!(!(3..).intersect(..5).is_empty()); + /// assert!(!(-12..387).intersect(0..256).is_empty()); + /// assert!((1..5).intersect(6..).is_empty()); + /// ``` + fn intersect(self, other: R) -> (Bound, Bound) + where + Self: Sized, + T: Ord, + R: Sized + IntoBounds, + { + let (self_start, self_end) = IntoBounds::into_bounds(self); + let (other_start, other_end) = IntoBounds::into_bounds(other); + + let start = match (self_start, other_start) { + (Included(a), Included(b)) => Included(Ord::max(a, b)), + (Excluded(a), Excluded(b)) => Excluded(Ord::max(a, b)), + (Unbounded, Unbounded) => Unbounded, + + (x, Unbounded) | (Unbounded, x) => x, + + (Included(i), Excluded(e)) | (Excluded(e), Included(i)) => { + if i > e { + Included(i) + } else { + Excluded(e) + } + } + }; + let end = match (self_end, other_end) { + (Included(a), Included(b)) => Included(Ord::min(a, b)), + (Excluded(a), Excluded(b)) => Excluded(Ord::min(a, b)), + (Unbounded, Unbounded) => Unbounded, + + (x, Unbounded) | (Unbounded, x) => x, + + (Included(i), Excluded(e)) | (Excluded(e), Included(i)) => { + if i < e { + Included(i) + } else { + Excluded(e) + } + } + }; + + (start, end) + } } use self::Bound::{Excluded, Included, Unbounded}; diff --git a/tests/ui/impl-trait/method-suggestion-no-duplication.stderr b/tests/ui/impl-trait/method-suggestion-no-duplication.stderr index c401269da83c..6bc57f89467d 100644 --- a/tests/ui/impl-trait/method-suggestion-no-duplication.stderr +++ b/tests/ui/impl-trait/method-suggestion-no-duplication.stderr @@ -8,8 +8,9 @@ LL | foo(|s| s.is_empty()); | ^^^^^^^^ method not found in `Foo` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `is_empty`, perhaps you need to implement it: + = note: the following traits define an item `is_empty`, perhaps you need to implement one of them: candidate #1: `ExactSizeIterator` + candidate #2: `RangeBounds` error: aborting due to 1 previous error From 72538180a665485ef0f14fbdba7b0d9bf09e0044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 20 Feb 2025 08:55:15 +0100 Subject: [PATCH 189/991] Remove GitHub job summaries They don't seem to be used by miri contributors, and they pollute job summaries in rust-lang/rust. --- src/tools/miri/tests/ui.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index 3bc953c3a5fb..0e8db0f3f600 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -217,15 +217,10 @@ fn run_tests( ui_test::default_file_filter, // This could be used to overwrite the `Config` on a per-test basis. |_, _| {}, - ( - match args.format { - Format::Terse => status_emitter::Text::quiet(), - Format::Pretty => status_emitter::Text::verbose(), - }, - status_emitter::Gha:: { - name: format!("{mode:?} {path} ({target})"), - }, - ), + match args.format { + Format::Terse => status_emitter::Text::quiet(), + Format::Pretty => status_emitter::Text::verbose(), + }, ) } From cf1242c461e035fd2cfb99f620e810015744cac4 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 19 Feb 2025 07:16:25 +0100 Subject: [PATCH 190/991] Enable `f16` for MIPS It seems as if `f16` works on MIPS now according to my testing on Rust master with LLVM 20, and I was asked to create PRs with my changes. I only tested on the flavour of `mipsel-unknown-linux-gnu` hardware that happens to be available to me, so I can't say anything about other MIPS hardware, but from a casual skimming of the LLVM code ([1], [2]) it seems like `f16` should work on all MIPS hardware. So enable it for all MIPS hardware. [1]: https://github.com/rust-lang/llvm-project/blob/rustc/20.1-2025-02-13/llvm/lib/Target/Mips/MipsISelLowering.h#L370 [2]: https://github.com/rust-lang/llvm-project/blob/rustc/20.1-2025-02-13/llvm/lib/CodeGen/TargetLoweringBase.cpp#L1367-L1388 --- library/std/build.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/std/build.rs b/library/std/build.rs index 8dc326a3dde6..723d1eb02e07 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -107,7 +107,6 @@ fn main() { ("csky", _) => false, ("hexagon", _) => false, ("loongarch64", _) => false, - ("mips" | "mips64" | "mips32r6" | "mips64r6", _) => false, ("powerpc" | "powerpc64", _) => false, ("sparc" | "sparc64", _) => false, ("wasm32" | "wasm64", _) => false, From 30fc90976a1683df4416d30a37f3286d6cafb8b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 20 Feb 2025 12:56:35 +0100 Subject: [PATCH 191/991] Add explanation comment Co-authored-by: Ralf Jung --- src/tools/miri/tests/ui.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index 0e8db0f3f600..85ce38f57d63 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -217,6 +217,7 @@ fn run_tests( ui_test::default_file_filter, // This could be used to overwrite the `Config` on a per-test basis. |_, _| {}, + // No GHA output as that would also show in the main rustc repo. match args.format { Format::Terse => status_emitter::Text::quiet(), Format::Pretty => status_emitter::Text::verbose(), From 8f6b18494641a9457b94e9f42bc88846e42dadbb Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 13 Feb 2025 09:53:08 +0000 Subject: [PATCH 192/991] Turn order dependent trait objects future incompat warning into a hard error --- compiler/rustc_lint_defs/src/builtin.rs | 37 -------- compiler/rustc_middle/src/query/mod.rs | 6 -- compiler/rustc_middle/src/ty/mod.rs | 47 +--------- .../src/traits/select/mod.rs | 14 +-- .../src/traits/specialize/mod.rs | 9 +- .../traits/specialize/specialization_graph.rs | 7 -- compiler/rustc_ty_utils/src/ty.rs | 58 +------------ .../lint-incoherent-auto-trait-objects.rs | 3 - .../lint-incoherent-auto-trait-objects.stderr | 65 ++------------ .../ui/traits/issue-33140-hack-boundaries.rs | 2 +- .../traits/issue-33140-hack-boundaries.stderr | 22 ++--- .../object/issue-33140-traitobject-crate.rs | 12 +-- .../issue-33140-traitobject-crate.stderr | 86 +++---------------- 13 files changed, 38 insertions(+), 330 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 10bf4ec77ed9..3c77d86535cb 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -73,7 +73,6 @@ declare_lint_pass! { NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, NON_CONTIGUOUS_RANGE_ENDPOINTS, NON_EXHAUSTIVE_OMITTED_PATTERNS, - ORDER_DEPENDENT_TRAIT_OBJECTS, OUT_OF_SCOPE_MACRO_CALLS, OVERLAPPING_RANGE_ENDPOINTS, PATTERNS_IN_FNS_WITHOUT_BODY, @@ -1502,42 +1501,6 @@ declare_lint! { }; } -declare_lint! { - /// The `order_dependent_trait_objects` lint detects a trait coherency - /// violation that would allow creating two trait impls for the same - /// dynamic trait object involving marker traits. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// pub trait Trait {} - /// - /// impl Trait for dyn Send + Sync { } - /// impl Trait for dyn Sync + Send { } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// A previous bug caused the compiler to interpret traits with different - /// orders (such as `Send + Sync` and `Sync + Send`) as distinct types - /// when they were intended to be treated the same. This allowed code to - /// define separate trait implementations when there should be a coherence - /// error. This is a [future-incompatible] lint to transition this to a - /// hard error in the future. See [issue #56484] for more details. - /// - /// [issue #56484]: https://github.com/rust-lang/rust/issues/56484 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub ORDER_DEPENDENT_TRAIT_OBJECTS, - Deny, - "trait-object types were treated as different depending on marker-trait order", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #56484 ", - }; -} - declare_lint! { /// The `coherence_leak_check` lint detects conflicting implementations of /// a trait that are only distinguished by the old leak-check code. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7c4ea06a7461..0e7bc19a9a94 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -985,12 +985,6 @@ rustc_queries! { separate_provide_extern } - query self_ty_of_trait_impl_enabling_order_dep_trait_object_hack( - key: DefId - ) -> Option>> { - desc { |tcx| "computing self type wrt issue #33140 `{}`", tcx.def_path_str(key) } - } - /// Maps a `DefId` of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a1d44882e63f..041f1f9fc90c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1424,39 +1424,6 @@ pub enum ImplOverlapKind { /// Whether or not the impl is permitted due to the trait being a `#[marker]` trait marker: bool, }, - /// These impls are allowed to overlap, but that raises an - /// issue #33140 future-compatibility warning (tracked in #56484). - /// - /// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's - /// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different. - /// - /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied on - /// that difference, doing what reduces to the following set of impls: - /// - /// ```compile_fail,(E0119) - /// trait Trait {} - /// impl Trait for dyn Send + Sync {} - /// impl Trait for dyn Sync + Send {} - /// ``` - /// - /// Obviously, once we made these types be identical, that code causes a coherence - /// error and a fairly big headache for us. However, luckily for us, the trait - /// `Trait` used in this case is basically a marker trait, and therefore having - /// overlapping impls for it is sound. - /// - /// To handle this, we basically regard the trait as a marker trait, with an additional - /// future-compatibility warning. To avoid accidentally "stabilizing" this feature, - /// it has the following restrictions: - /// - /// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be - /// positive impls. - /// 2. The trait-ref of both impls must be equal. - /// 3. The trait-ref of both impls must be a trait object type consisting only of - /// marker traits. - /// 4. Neither of the impls can have any where-clauses. - /// - /// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed. - FutureCompatOrderDepTraitObjects, } /// Useful source information about where a desugared associated type for an @@ -1629,7 +1596,7 @@ impl<'tcx> TyCtxt<'tcx> { }) } - /// Returns `true` if the impls are the same polarity and the trait either + /// Returns `Some` if the impls are the same polarity and the trait either /// has no items or is annotated `#[marker]` and prevents item overrides. #[instrument(level = "debug", skip(self), ret)] pub fn impls_are_allowed_to_overlap( @@ -1670,18 +1637,6 @@ impl<'tcx> TyCtxt<'tcx> { return Some(ImplOverlapKind::Permitted { marker: true }); } - if let Some(self_ty1) = - self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id1) - && let Some(self_ty2) = - self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id2) - { - if self_ty1 == self_ty2 { - return Some(ImplOverlapKind::FutureCompatOrderDepTraitObjects); - } else { - debug!("found {self_ty1:?} != {self_ty2:?}"); - } - } - None } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 436ce3dddd9f..7eba7fd64264 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1920,9 +1920,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let mut impl_candidate = None; for c in impls { if let Some(prev) = impl_candidate.replace(c) { - if self.prefer_lhs_over_victim(has_non_region_infer, c, prev) { + if self.prefer_lhs_over_victim(has_non_region_infer, c, prev.0) { // Ok, prefer `c` over the previous entry - } else if self.prefer_lhs_over_victim(has_non_region_infer, prev, c) { + } else if self.prefer_lhs_over_victim(has_non_region_infer, prev, c.0) { // Ok, keep `prev` instead of the new entry impl_candidate = Some(prev); } else { @@ -1981,7 +1981,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { &self, has_non_region_infer: bool, (lhs, lhs_evaluation): (DefId, EvaluationResult), - (victim, victim_evaluation): (DefId, EvaluationResult), + victim: DefId, ) -> bool { let tcx = self.tcx(); // See if we can toss out `victim` based on specialization. @@ -1997,14 +1997,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } match tcx.impls_are_allowed_to_overlap(lhs, victim) { - // For #33140 the impl headers must be exactly equal, the trait must not have - // any associated items and there are no where-clauses. - // - // We can just arbitrarily drop one of the impls. - Some(ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects) => { - assert_eq!(lhs_evaluation, victim_evaluation); - true - } // For candidates which already reference errors it doesn't really // matter what we do 🤷 Some(ty::ImplOverlapKind::Permitted { marker: false }) => { diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index cb3e81f5477f..448ac558cad7 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -20,7 +20,7 @@ use rustc_middle::bug; use rustc_middle::query::LocalCrate; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; -use rustc_session::lint::builtin::{COHERENCE_LEAK_CHECK, ORDER_DEPENDENT_TRAIT_OBJECTS}; +use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym}; use rustc_type_ir::solve::NoSolution; use specialization_graph::GraphExt; @@ -557,13 +557,9 @@ fn report_conflicting_impls<'tcx>( let msg = || { format!( - "conflicting implementations of trait `{}`{}{}", + "conflicting implementations of trait `{}`{}", overlap.trait_ref.print_trait_sugared(), overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")), - match used_to_be_allowed { - Some(FutureCompatOverlapErrorKind::OrderDepTraitObjects) => ": (E0119)", - _ => "", - } ) }; @@ -588,7 +584,6 @@ fn report_conflicting_impls<'tcx>( } Some(kind) => { let lint = match kind { - FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS, FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK, }; tcx.node_span_lint(lint, tcx.local_def_id_to_hir_id(impl_def_id), impl_span, |err| { diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index f39c611d19fe..11fd1d16a117 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -12,7 +12,6 @@ use crate::traits; #[derive(Copy, Clone, Debug)] pub enum FutureCompatOverlapErrorKind { - OrderDepTraitObjects, LeakCheck, } @@ -151,12 +150,6 @@ impl<'tcx> Children { { match overlap_kind { ty::ImplOverlapKind::Permitted { marker: _ } => {} - ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects => { - *last_lint_mut = Some(FutureCompatOverlapError { - error: create_overlap_error(overlap), - kind: FutureCompatOverlapErrorKind::OrderDepTraitObjects, - }); - } } return Ok((false, false)); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 8ed45b4e5415..cd0caf4fe9fa 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -6,13 +6,11 @@ use rustc_index::bit_set::DenseBitSet; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::fold::fold_regions; -use rustc_middle::ty::{ - self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, -}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast}; use rustc_span::DUMMY_SP; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_trait_selection::traits; -use tracing::{debug, instrument}; +use tracing::instrument; #[instrument(level = "debug", skip(tcx), ret)] fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option> { @@ -257,57 +255,6 @@ fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty: typing_env.with_post_analysis_normalized(tcx).param_env } -/// If the given trait impl enables exploiting the former order dependence of trait objects, -/// returns its self type; otherwise, returns `None`. -/// -/// See [`ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects`] for more details. -#[instrument(level = "debug", skip(tcx))] -fn self_ty_of_trait_impl_enabling_order_dep_trait_object_hack( - tcx: TyCtxt<'_>, - def_id: DefId, -) -> Option>> { - let impl_ = - tcx.impl_trait_header(def_id).unwrap_or_else(|| bug!("called on inherent impl {def_id:?}")); - - let trait_ref = impl_.trait_ref.skip_binder(); - debug!(?trait_ref); - - let is_marker_like = impl_.polarity == ty::ImplPolarity::Positive - && tcx.associated_item_def_ids(trait_ref.def_id).is_empty(); - - // Check whether these impls would be ok for a marker trait. - if !is_marker_like { - debug!("not marker-like!"); - return None; - } - - // impl must be `impl Trait for dyn Marker1 + Marker2 + ...` - if trait_ref.args.len() != 1 { - debug!("impl has args!"); - return None; - } - - let predicates = tcx.predicates_of(def_id); - if predicates.parent.is_some() || !predicates.predicates.is_empty() { - debug!(?predicates, "impl has predicates!"); - return None; - } - - let self_ty = trait_ref.self_ty(); - let self_ty_matches = match self_ty.kind() { - ty::Dynamic(data, re, _) if re.is_static() => data.principal().is_none(), - _ => false, - }; - - if self_ty_matches { - debug!("MATCHES!"); - Some(EarlyBinder::bind(self_ty)) - } else { - debug!("non-matching self type"); - None - } -} - /// Check if a function is async. fn asyncness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Asyncness { let node = tcx.hir_node_by_def_id(def_id); @@ -367,7 +314,6 @@ pub(crate) fn provide(providers: &mut Providers) { adt_sized_constraint, param_env, param_env_normalized_for_post_analysis, - self_ty_of_trait_impl_enabling_order_dep_trait_object_hack, defaultness, unsizing_params_for_adt, ..*providers diff --git a/tests/ui/lint/lint-incoherent-auto-trait-objects.rs b/tests/ui/lint/lint-incoherent-auto-trait-objects.rs index d53b51447602..d34e6658435d 100644 --- a/tests/ui/lint/lint-incoherent-auto-trait-objects.rs +++ b/tests/ui/lint/lint-incoherent-auto-trait-objects.rs @@ -4,16 +4,13 @@ impl Foo for dyn Send {} impl Foo for dyn Send + Send {} //~^ ERROR conflicting implementations -//~| hard error impl Foo for dyn Send + Sync {} impl Foo for dyn Sync + Send {} //~^ ERROR conflicting implementations -//~| hard error impl Foo for dyn Send + Sync + Send {} //~^ ERROR conflicting implementations -//~| hard error fn main() {} diff --git a/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr b/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr index 553ab3869b33..28e8f74672da 100644 --- a/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr +++ b/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr @@ -1,4 +1,4 @@ -error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119) +error[E0119]: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)` --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1 | LL | impl Foo for dyn Send {} @@ -6,76 +6,25 @@ LL | impl Foo for dyn Send {} LL | LL | impl Foo for dyn Send + Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 - = note: `#[deny(order_dependent_trait_objects)]` on by default -error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1 +error[E0119]: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)` + --> $DIR/lint-incoherent-auto-trait-objects.rs:10:1 | LL | impl Foo for dyn Send + Sync {} | ---------------------------- first implementation here LL | LL | impl Foo for dyn Sync + Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 -error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1 +error[E0119]: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)` + --> $DIR/lint-incoherent-auto-trait-objects.rs:13:1 | -LL | impl Foo for dyn Sync + Send {} +LL | impl Foo for dyn Send + Sync {} | ---------------------------- first implementation here ... LL | impl Foo for dyn Send + Sync + Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 error: aborting due to 3 previous errors -Future incompatibility report: Future breakage diagnostic: -error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119) - --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1 - | -LL | impl Foo for dyn Send {} - | --------------------- first implementation here -LL | -LL | impl Foo for dyn Send + Send {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 - = note: `#[deny(order_dependent_trait_objects)]` on by default - -Future breakage diagnostic: -error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1 - | -LL | impl Foo for dyn Send + Sync {} - | ---------------------------- first implementation here -LL | -LL | impl Foo for dyn Sync + Send {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 - = note: `#[deny(order_dependent_trait_objects)]` on by default - -Future breakage diagnostic: -error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1 - | -LL | impl Foo for dyn Sync + Send {} - | ---------------------------- first implementation here -... -LL | impl Foo for dyn Send + Sync + Send {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 - = note: `#[deny(order_dependent_trait_objects)]` on by default - +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/issue-33140-hack-boundaries.rs b/tests/ui/traits/issue-33140-hack-boundaries.rs index d091162fced6..06786dcc8fe8 100644 --- a/tests/ui/traits/issue-33140-hack-boundaries.rs +++ b/tests/ui/traits/issue-33140-hack-boundaries.rs @@ -1,5 +1,4 @@ #![feature(negative_impls)] -#![allow(order_dependent_trait_objects)] // Check that the issue #33140 hack does not allow unintended things. @@ -8,6 +7,7 @@ trait Trait0 {} impl Trait0 for dyn Send {} impl Trait0 for dyn Send {} +//~^ ERROR: E0119 // Problem 1: associated types trait Trait1 { diff --git a/tests/ui/traits/issue-33140-hack-boundaries.stderr b/tests/ui/traits/issue-33140-hack-boundaries.stderr index d9c4efbb721c..ed3ae2b31675 100644 --- a/tests/ui/traits/issue-33140-hack-boundaries.stderr +++ b/tests/ui/traits/issue-33140-hack-boundaries.stderr @@ -1,3 +1,11 @@ +error[E0119]: conflicting implementations of trait `Trait0` for type `(dyn Send + 'static)` + --> $DIR/issue-33140-hack-boundaries.rs:9:1 + | +LL | impl Trait0 for dyn Send {} + | ------------------------ first implementation here +LL | impl Trait0 for dyn Send {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)` + error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn Send + 'static)` --> $DIR/issue-33140-hack-boundaries.rs:18:1 | @@ -62,19 +70,7 @@ LL | impl Trait5 for dyn Send {} LL | impl Trait5 for dyn Send where u32: Copy {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)` -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0119, E0751. For more information about an error, try `rustc --explain E0119`. -Future incompatibility report: Future breakage diagnostic: -warning: conflicting implementations of trait `Trait0` for type `(dyn Send + 'static)`: (E0119) - --> $DIR/issue-33140-hack-boundaries.rs:10:1 - | -LL | impl Trait0 for dyn Send {} - | ------------------------ first implementation here -LL | impl Trait0 for dyn Send {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 - diff --git a/tests/ui/traits/object/issue-33140-traitobject-crate.rs b/tests/ui/traits/object/issue-33140-traitobject-crate.rs index 00ef6430d638..ff7cd30644b7 100644 --- a/tests/ui/traits/object/issue-33140-traitobject-crate.rs +++ b/tests/ui/traits/object/issue-33140-traitobject-crate.rs @@ -1,6 +1,3 @@ -//@ check-pass - -#![warn(order_dependent_trait_objects)] #![allow(dyn_drop)] // Check that traitobject 0.1.0 compiles @@ -84,15 +81,12 @@ unsafe impl Trait for dyn (::std::iter::Iterator) + Send + Sync { } unsafe impl Trait for dyn (::std::marker::Send) + Send { } unsafe impl Trait for dyn (::std::marker::Send) + Sync { } unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } -//~^ WARNING conflicting implementations of trait `Trait` for type -//~| WARNING this was previously accepted by the compiler but is being phased out +//~^ ERROR conflicting implementations of trait `Trait` for type unsafe impl Trait for dyn (::std::marker::Sync) + Send { } -//~^ WARNING conflicting implementations of trait `Trait` for type -//~| WARNING this was previously accepted by the compiler but is being phased out +//~^ ERROR conflicting implementations of trait `Trait` for type unsafe impl Trait for dyn (::std::marker::Sync) + Sync { } unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { } -//~^ WARNING conflicting implementations of trait `Trait` for type -//~| WARNING this was previously accepted by the compiler but is being phased out +//~^ ERROR conflicting implementations of trait `Trait` for type unsafe impl Trait for dyn (::std::ops::Drop) + Send { } unsafe impl Trait for dyn (::std::ops::Drop) + Sync { } unsafe impl Trait for dyn (::std::ops::Drop) + Send + Sync { } diff --git a/tests/ui/traits/object/issue-33140-traitobject-crate.stderr b/tests/ui/traits/object/issue-33140-traitobject-crate.stderr index 525401f9d69e..a01c7990db36 100644 --- a/tests/ui/traits/object/issue-33140-traitobject-crate.stderr +++ b/tests/ui/traits/object/issue-33140-traitobject-crate.stderr @@ -1,95 +1,29 @@ -warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/issue-33140-traitobject-crate.rs:86:1 +error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)` + --> $DIR/issue-33140-traitobject-crate.rs:83:1 | LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { } | ------------------------------------------------------ first implementation here LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 -note: the lint level is defined here - --> $DIR/issue-33140-traitobject-crate.rs:3:9 - | -LL | #![warn(order_dependent_trait_objects)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/issue-33140-traitobject-crate.rs:89:1 - | -LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } - | ------------------------------------------------------------- first implementation here -... -LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 - -warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/issue-33140-traitobject-crate.rs:93:1 - | -LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { } - | ------------------------------------------------------ first implementation here -... -LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 - -warning: 3 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/issue-33140-traitobject-crate.rs:86:1 +error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)` + --> $DIR/issue-33140-traitobject-crate.rs:85:1 | LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { } | ------------------------------------------------------ first implementation here -LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 -note: the lint level is defined here - --> $DIR/issue-33140-traitobject-crate.rs:3:9 - | -LL | #![warn(order_dependent_trait_objects)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/issue-33140-traitobject-crate.rs:89:1 - | -LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } - | ------------------------------------------------------------- first implementation here ... LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 -note: the lint level is defined here - --> $DIR/issue-33140-traitobject-crate.rs:3:9 - | -LL | #![warn(order_dependent_trait_objects)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Future breakage diagnostic: -warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119) - --> $DIR/issue-33140-traitobject-crate.rs:93:1 +error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)` + --> $DIR/issue-33140-traitobject-crate.rs:88:1 | -LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { } +LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { } | ------------------------------------------------------ first implementation here ... LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 -note: the lint level is defined here - --> $DIR/issue-33140-traitobject-crate.rs:3:9 - | -LL | #![warn(order_dependent_trait_objects)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0119`. From 3c9a0ab38c498fc67a5e120094b9d610e6be6a9f Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Thu, 20 Feb 2025 23:26:51 +0900 Subject: [PATCH 193/991] rename the MSRV alias `MANUAL_DIV_CEIL` to `DIV_CEIL` --- clippy_lints/src/manual_div_ceil.rs | 2 +- clippy_utils/src/msrvs.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/manual_div_ceil.rs b/clippy_lints/src/manual_div_ceil.rs index 04357cdd8f66..dd242c4168c6 100644 --- a/clippy_lints/src/manual_div_ceil.rs +++ b/clippy_lints/src/manual_div_ceil.rs @@ -59,7 +59,7 @@ impl_lint_pass!(ManualDivCeil => [MANUAL_DIV_CEIL]); impl<'tcx> LateLintPass<'tcx> for ManualDivCeil { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { - if !self.msrv.meets(msrvs::MANUAL_DIV_CEIL) { + if !self.msrv.meets(msrvs::DIV_CEIL) { return; } diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 2e8bcfaa7af0..bf8106042f31 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -28,7 +28,7 @@ msrv_aliases! { 1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT } 1,75,0 { OPTION_AS_SLICE } 1,74,0 { REPR_RUST } - 1,73,0 { MANUAL_DIV_CEIL } + 1,73,0 { DIV_CEIL } 1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE } 1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN } 1,68,0 { PATH_MAIN_SEPARATOR_STR } From 8844a969caaaa32ae20826fae2f41640a023aa81 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 20 Feb 2025 15:26:51 +0100 Subject: [PATCH 194/991] Bump Clippy version -> 0.1.87 --- Cargo.toml | 2 +- clippy_config/Cargo.toml | 2 +- clippy_lints/Cargo.toml | 2 +- clippy_utils/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6c19e7af5f8b..23b2b4ff0b47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "clippy" # begin autogenerated version -version = "0.1.86" +version = "0.1.87" # end autogenerated version description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index e473a5839402..934725fccb8e 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "clippy_config" # begin autogenerated version -version = "0.1.86" +version = "0.1.87" # end autogenerated version edition = "2024" publish = false diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index c62a7ec783b6..54347043a13d 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "clippy_lints" # begin autogenerated version -version = "0.1.86" +version = "0.1.87" # end autogenerated version description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index 68b7e1592e2e..ba4bb1d177c5 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "clippy_utils" # begin autogenerated version -version = "0.1.86" +version = "0.1.87" # end autogenerated version edition = "2024" description = "Helpful tools for writing lints, provided as they are used in Clippy" From 55f32d9259c37a9306838b5792153604d8b4461e Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Thu, 20 Feb 2025 23:27:15 +0900 Subject: [PATCH 195/991] add missing MSRV configuration information for `manual_div_ceil` --- book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 0e264cdcd4a3..78e29640714f 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -764,6 +764,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits) * [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals) * [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp) +* [`manual_div_ceil`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_div_ceil) * [`manual_flatten`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten) * [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one) * [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index cac4408fff0e..05e7d26faedd 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -619,6 +619,7 @@ define_Conf! { manual_bits, manual_c_str_literals, manual_clamp, + manual_div_ceil, manual_flatten, manual_hash_one, manual_is_ascii_check, From 934471ce30a1630397518b56a29a5ea04b059353 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 20 Feb 2025 15:27:19 +0100 Subject: [PATCH 196/991] Bump nightly version -> 2025-02-20 --- clippy_utils/README.md | 2 +- rust-toolchain | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 41f3b1cbd507..e513d9354507 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-02-06 +nightly-2025-02-20 ``` diff --git a/rust-toolchain b/rust-toolchain index ab760287e83a..4956ab5d3775 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-02-06" +channel = "nightly-2025-02-20" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" From e6be02eaf5372d82690d8724ff8cf3718076bb48 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 20 Feb 2025 15:54:12 +0100 Subject: [PATCH 197/991] Rustup: fix 32bit tests --- tests/ui/cast_size.32bit.stderr | 45 ++++++++------ tests/ui/large_enum_variant.32bit.stderr | 75 ++++++++++++++---------- 2 files changed, 72 insertions(+), 48 deletions(-) diff --git a/tests/ui/cast_size.32bit.stderr b/tests/ui/cast_size.32bit.stderr index 637dd6fddea1..cb1620e36a26 100644 --- a/tests/ui/cast_size.32bit.stderr +++ b/tests/ui/cast_size.32bit.stderr @@ -9,8 +9,9 @@ LL | 1isize as i8; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]` help: ... or use `try_from` and handle the error accordingly | -LL | i8::try_from(1isize); - | ~~~~~~~~~~~~~~~~~~~~ +LL - 1isize as i8; +LL + i8::try_from(1isize); + | error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:24:5 @@ -48,8 +49,9 @@ LL | 1isize as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i32::try_from(1isize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1isize as i32; +LL + i32::try_from(1isize); + | error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:37:5 @@ -60,8 +62,9 @@ LL | 1isize as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u32::try_from(1isize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1isize as u32; +LL + u32::try_from(1isize); + | error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:39:5 @@ -72,8 +75,9 @@ LL | 1usize as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | u32::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as u32; +LL + u32::try_from(1usize); + | error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:41:5 @@ -84,8 +88,9 @@ LL | 1usize as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | i32::try_from(1usize); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1usize as i32; +LL + i32::try_from(1usize); + | error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:41:5 @@ -105,8 +110,9 @@ LL | 1i64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | isize::try_from(1i64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1i64 as isize; +LL + isize::try_from(1i64); + | error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:46:5 @@ -117,8 +123,9 @@ LL | 1i64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | usize::try_from(1i64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1i64 as usize; +LL + usize::try_from(1i64); + | error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:48:5 @@ -129,8 +136,9 @@ LL | 1u64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | isize::try_from(1u64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1u64 as isize; +LL + isize::try_from(1u64); + | error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers --> tests/ui/cast_size.rs:48:5 @@ -147,8 +155,9 @@ LL | 1u64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... help: ... or use `try_from` and handle the error accordingly | -LL | usize::try_from(1u64); - | ~~~~~~~~~~~~~~~~~~~~~ +LL - 1u64 as usize; +LL + usize::try_from(1u64); + | error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers --> tests/ui/cast_size.rs:53:5 diff --git a/tests/ui/large_enum_variant.32bit.stderr b/tests/ui/large_enum_variant.32bit.stderr index 7f66207ce797..80ca5daa1d57 100644 --- a/tests/ui/large_enum_variant.32bit.stderr +++ b/tests/ui/large_enum_variant.32bit.stderr @@ -14,8 +14,9 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]` help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<[i32; 8000]>), - | ~~~~~~~~~~~~~~~~ +LL - B([i32; 8000]), +LL + B(Box<[i32; 8000]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:38:1 @@ -31,8 +32,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | ContainingLargeEnum(Box), - | ~~~~~~~~~~~~~~ +LL - ContainingLargeEnum(LargeEnum), +LL + ContainingLargeEnum(Box), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:44:1 @@ -49,8 +51,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), - | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), +LL + ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:51:1 @@ -66,8 +69,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, - | ~~~~~~~~~~~~~~~~ +LL - StructLikeLarge { x: [i32; 8000], y: i32 }, +LL + StructLikeLarge { x: Box<[i32; 8000]>, y: i32 }, + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:57:1 @@ -83,8 +87,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | StructLikeLarge2 { x: Box<[i32; 8000]> }, - | ~~~~~~~~~~~~~~~~ +LL - StructLikeLarge2 { x: [i32; 8000] }, +LL + StructLikeLarge2 { x: Box<[i32; 8000]> }, + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:74:1 @@ -101,8 +106,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box<[u8; 1255]>), - | ~~~~~~~~~~~~~~~ +LL - B([u8; 1255]), +LL + B(Box<[u8; 1255]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:81:1 @@ -118,8 +124,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]), - | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +LL - ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), +LL + ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:87:1 @@ -135,8 +142,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box), - | ~~~~~~~~~~~~ +LL - B(Struct2), +LL + B(Box), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:93:1 @@ -152,8 +160,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box), - | ~~~~~~~~~~~~ +LL - B(Struct2), +LL + B(Box), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:99:1 @@ -169,8 +178,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | B(Box), - | ~~~~~~~~~~~~ +LL - B(Struct2), +LL + B(Box), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:115:1 @@ -255,8 +265,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Large(Box<(T, [u8; 512])>), - | ~~~~~~~~~~~~~~~~~~~ +LL - Large((T, [u8; 512])), +LL + Large(Box<(T, [u8; 512])>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:159:1 @@ -272,8 +283,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Large(Box<[Foo; 64]>), - | ~~~~~~~~~~~~~~~~~~~ +LL - Large([Foo; 64]), +LL + Large(Box<[Foo; 64]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:170:1 @@ -289,8 +301,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Error(Box>), - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - Error(PossiblyLargeEnumWithConst<256>), +LL + Error(Box>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:176:1 @@ -306,8 +319,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Large(Box<[u64; 64]>), - | ~~~~~~~~~~~~~~ +LL - Large([u64; 64]), +LL + Large(Box<[u64; 64]>), + | error: large size difference between variants --> tests/ui/large_enum_variant.rs:187:1 @@ -323,8 +337,9 @@ LL | | } | help: consider boxing the large fields to reduce the total size of the enum | -LL | Error(Box>), - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - Error(WithRecursionAndGenerics), +LL + Error(Box>), + | error: aborting due to 18 previous errors From 2335fd69bc7a124eb37e366c3e4dc78a4a6774f6 Mon Sep 17 00:00:00 2001 From: tiif Date: Fri, 21 Feb 2025 00:06:50 +0800 Subject: [PATCH 198/991] Resolve some FIXME from socketpair test --- src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs index bbf0e2159530..9163fd3d06fa 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs @@ -88,8 +88,7 @@ fn test_socketpair_threaded() { assert_eq!(res, 5); assert_eq!(buf, "abcde".as_bytes()); }); - // FIXME: we should yield here once blocking is implemented. - //thread::yield_now(); + thread::yield_now(); let data = "abcde".as_bytes().as_ptr(); let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); @@ -97,14 +96,11 @@ fn test_socketpair_threaded() { // Read and write from different direction let thread2 = thread::spawn(move || { - // FIXME: we should yield here once blocking is implemented. - //thread::yield_now(); + thread::yield_now(); let data = "12345".as_bytes().as_ptr(); let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) }; assert_eq!(res, 5); }); - // FIXME: we should not yield here once blocking is implemented. - thread::yield_now(); let mut buf: [u8; 5] = [0; 5]; let res = unsafe { libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; assert_eq!(res, 5); From acfbbc65b54600a4e3b16d6c63258e51907336fe Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 20 Feb 2025 17:54:49 +0100 Subject: [PATCH 199/991] Remove obsolete comment and simplify code The `IoBufRead` diagnostic has been added during the latest rustup. --- clippy_lints/src/methods/unbuffered_bytes.rs | 34 ++++++++------------ 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/clippy_lints/src/methods/unbuffered_bytes.rs b/clippy_lints/src/methods/unbuffered_bytes.rs index c4d2515a7bcb..dd5566f8c8ba 100644 --- a/clippy_lints/src/methods/unbuffered_bytes.rs +++ b/clippy_lints/src/methods/unbuffered_bytes.rs @@ -7,25 +7,19 @@ use rustc_lint::LateContext; use rustc_span::sym; pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) { - let ty = cx.typeck_results().expr_ty_adjusted(recv); - - // If the .bytes() call is a call from the Read trait - if is_trait_method(cx, expr, sym::IoRead) { - // Retrieve the DefId of the BufRead trait - // FIXME: add a diagnostic item for `BufRead` - let Some(buf_read) = cx.tcx.get_diagnostic_item(sym::IoBufRead) else { - return; - }; - // And the implementor of the trait is not buffered - if !implements_trait(cx, ty, buf_read, &[]) { - span_lint_and_help( - cx, - UNBUFFERED_BYTES, - expr.span, - "calling .bytes() is very inefficient when data is not in memory", - None, - "consider using `BufReader`", - ); - } + // Lint if the `.bytes()` call is from the `Read` trait and the implementor is not buffered. + if is_trait_method(cx, expr, sym::IoRead) + && let Some(buf_read) = cx.tcx.get_diagnostic_item(sym::IoBufRead) + && let ty = cx.typeck_results().expr_ty_adjusted(recv) + && !implements_trait(cx, ty, buf_read, &[]) + { + span_lint_and_help( + cx, + UNBUFFERED_BYTES, + expr.span, + "calling .bytes() is very inefficient when data is not in memory", + None, + "consider using `BufReader`", + ); } } From 2bead2717b6ddfd9dc6d39d41ec031ce9c50e664 Mon Sep 17 00:00:00 2001 From: Henry Jiang Date: Wed, 12 Feb 2025 13:36:23 -0500 Subject: [PATCH 200/991] remove : from stack-protector-heuristics-effect.rs filecheck --- .../stack-protector/stack-protector-heuristics-effect.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs index 57fc601a2e0c..fa9e149388d7 100644 --- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs +++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs @@ -19,7 +19,7 @@ #![allow(incomplete_features)] #![feature(unsized_locals, unsized_fn_params)] -// CHECK-LABEL: emptyfn: +// CHECK-LABEL: emptyfn #[no_mangle] pub fn emptyfn() { // all: __stack_chk_fail @@ -63,7 +63,7 @@ pub fn array_u8_1(f: fn(*const u8)) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: array_u8_small: +// CHECK-LABEL: array_u8_small #[no_mangle] pub fn array_u8_small(f: fn(*const u8)) { let a = [0u8; 2]; @@ -80,7 +80,7 @@ pub fn array_u8_small(f: fn(*const u8)) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: array_u8_large: +// CHECK-LABEL: array_u8_large #[no_mangle] pub fn array_u8_large(f: fn(*const u8)) { let a = [0u8; 9]; @@ -99,7 +99,7 @@ pub fn array_u8_large(f: fn(*const u8)) { #[derive(Copy, Clone)] pub struct ByteSizedNewtype(u8); -// CHECK-LABEL: array_bytesizednewtype_9: +// CHECK-LABEL: array_bytesizednewtype_9 #[no_mangle] pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { let a = [ByteSizedNewtype(0); 9]; From 2c752bcf559975995eb8086a7fa6a7f9b5ba0de8 Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Thu, 20 Feb 2025 11:47:14 -0600 Subject: [PATCH 201/991] Undeprecate env::home_dir --- library/std/src/env.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/library/std/src/env.rs b/library/std/src/env.rs index adbd68896241..5a931b077cdb 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -641,11 +641,6 @@ impl Error for JoinPathsError { /// None => println!("Impossible to get your home dir!"), /// } /// ``` -#[deprecated( - since = "1.29.0", - note = "This function's behavior may be unexpected on Windows. \ - Consider using a crate from crates.io instead." -)] #[must_use] #[stable(feature = "env", since = "1.0.0")] pub fn home_dir() -> Option { From fb8c993e15858ff6653977355055df4c016a60d6 Mon Sep 17 00:00:00 2001 From: Henry Jiang Date: Thu, 20 Feb 2025 13:31:12 -0500 Subject: [PATCH 202/991] fix label suffix --- .../stack-protector-heuristics-effect.rs | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs index fa9e149388d7..91c83fa2f5ba 100644 --- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs +++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs @@ -19,7 +19,7 @@ #![allow(incomplete_features)] #![feature(unsized_locals, unsized_fn_params)] -// CHECK-LABEL: emptyfn +// CHECK-LABEL: emptyfn{{:|\[}} #[no_mangle] pub fn emptyfn() { // all: __stack_chk_fail @@ -29,7 +29,7 @@ pub fn emptyfn() { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: array_char +// CHECK-LABEL: array_char{{:|\[}} #[no_mangle] pub fn array_char(f: fn(*const char)) { let a = ['c'; 1]; @@ -47,7 +47,7 @@ pub fn array_char(f: fn(*const char)) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: array_u8_1 +// CHECK-LABEL: array_u8_1{{:|\[}} #[no_mangle] pub fn array_u8_1(f: fn(*const u8)) { let a = [0u8; 1]; @@ -63,7 +63,7 @@ pub fn array_u8_1(f: fn(*const u8)) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: array_u8_small +// CHECK-LABEL: array_u8_small{{:|\[}} #[no_mangle] pub fn array_u8_small(f: fn(*const u8)) { let a = [0u8; 2]; @@ -80,7 +80,7 @@ pub fn array_u8_small(f: fn(*const u8)) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: array_u8_large +// CHECK-LABEL: array_u8_large{{:|\[}} #[no_mangle] pub fn array_u8_large(f: fn(*const u8)) { let a = [0u8; 9]; @@ -99,7 +99,7 @@ pub fn array_u8_large(f: fn(*const u8)) { #[derive(Copy, Clone)] pub struct ByteSizedNewtype(u8); -// CHECK-LABEL: array_bytesizednewtype_9 +// CHECK-LABEL: array_bytesizednewtype_9{{:|\[}} #[no_mangle] pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { let a = [ByteSizedNewtype(0); 9]; @@ -115,7 +115,7 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: local_var_addr_used_indirectly +// CHECK-LABEL: local_var_addr_used_indirectly{{:|\[}} #[no_mangle] pub fn local_var_addr_used_indirectly(f: fn(bool)) { let a = 5; @@ -142,7 +142,7 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: local_string_addr_taken +// CHECK-LABEL: local_string_addr_taken{{:|\[}} #[no_mangle] pub fn local_string_addr_taken(f: fn(&String)) { let x = String::new(); @@ -168,7 +168,7 @@ impl SelfByRef for i32 { } } -// CHECK-LABEL: local_var_addr_taken_used_locally_only +// CHECK-LABEL: local_var_addr_taken_used_locally_only{{:|\[}} #[no_mangle] pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32)) { let x = factory(); @@ -195,7 +195,7 @@ pub struct Gigastruct { members: u64, } -// CHECK-LABEL: local_large_var_moved +// CHECK-LABEL: local_large_var_moved{{:|\[}} #[no_mangle] pub fn local_large_var_moved(f: fn(Gigastruct)) { let x = Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 }; @@ -224,7 +224,7 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: local_large_var_cloned +// CHECK-LABEL: local_large_var_cloned{{:|\[}} #[no_mangle] pub fn local_large_var_cloned(f: fn(Gigastruct)) { f(Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 }); @@ -281,7 +281,7 @@ extern "C" { fn alloca(size: usize) -> *mut (); } -// CHECK-LABEL: alloca_small_compile_time_constant_arg +// CHECK-LABEL: alloca_small_compile_time_constant_arg{{:|\[}} #[no_mangle] pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { f(unsafe { alloca(8) }); @@ -293,7 +293,7 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: alloca_large_compile_time_constant_arg +// CHECK-LABEL: alloca_large_compile_time_constant_arg{{:|\[}} #[no_mangle] pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { f(unsafe { alloca(9) }); @@ -305,7 +305,7 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: alloca_dynamic_arg +// CHECK-LABEL: alloca_dynamic_arg{{:|\[}} #[no_mangle] pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { f(unsafe { alloca(n) }); @@ -324,7 +324,7 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // this is support for the "unsized locals" unstable feature: // https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html. -// CHECK-LABEL: unsized_fn_param +// CHECK-LABEL: unsized_fn_param{{:|\[}} #[no_mangle] pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { let n = if l { 1 } else { 2 }; @@ -344,7 +344,7 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // missing-NOT: __stack_chk_fail } -// CHECK-LABEL: unsized_local +// CHECK-LABEL: unsized_local{{:|\[}} #[no_mangle] pub fn unsized_local(s: &[u8], l: bool, f: fn(&mut [u8])) { let n = if l { 1 } else { 2 }; From 917d2eb78ac514bf3e3a41b38cb148bf918a0b8d Mon Sep 17 00:00:00 2001 From: Curtis D'Alves Date: Thu, 20 Feb 2025 14:31:19 -0500 Subject: [PATCH 203/991] add verbatim linker to AIXLinker --- compiler/rustc_codegen_ssa/src/back/linker.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e3ace01c1eb5..432bb692fb1e 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1643,9 +1643,9 @@ impl<'a> Linker for AixLinker<'a> { } } - fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) { + fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _as_needed: bool) { self.hint_dynamic(); - self.link_or_cc_arg(format!("-l{name}")); + self.link_or_cc_arg(if verbatim { String::from(name) } else { format!("-l{name}") }); } fn link_dylib_by_path(&mut self, path: &Path, _as_needed: bool) { @@ -1656,7 +1656,7 @@ impl<'a> Linker for AixLinker<'a> { fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.link_or_cc_arg(format!("-l{name}")); + self.link_or_cc_arg(if verbatim { String::from(name) } else { format!("-l{name}") }); } else { let mut arg = OsString::from("-bkeepfile:"); arg.push(find_native_static_library(name, verbatim, self.sess)); From 41a34552c75d647f6b6f72cbe0c682515711a48d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 13 Feb 2025 14:00:39 +1100 Subject: [PATCH 204/991] Rename `ClearCrossCrate::assert_crate_local`. As `unwrap_crate_local`, because it follows exactly the standard form of an `unwrap` function. --- clippy_lints/src/redundant_clone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index fb1bc494bd94..cfa622aea582 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -205,7 +205,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { let node = mir.source_scopes[scope] .local_data .as_ref() - .assert_crate_local() + .unwrap_crate_local() .lint_root; if let Some(snip) = span.get_source_text(cx) From fef0ea905acb3f66c6957d4e12d22d35424fd40f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Feb 2025 23:05:38 +0000 Subject: [PATCH 205/991] More sophisticated span trimming --- tests/ui/borrow_deref_ref_unfixable.stderr | 5 +- tests/ui/fn_to_numeric_cast_any.stderr | 81 +++++++++------------- tests/ui/implicit_hasher.stderr | 15 ++-- tests/ui/literals.stderr | 5 +- tests/ui/octal_escapes.stderr | 75 ++++++++------------ tests/ui/suspicious_to_owned.stderr | 20 +++--- 6 files changed, 80 insertions(+), 121 deletions(-) diff --git a/tests/ui/borrow_deref_ref_unfixable.stderr b/tests/ui/borrow_deref_ref_unfixable.stderr index 71f43af46c24..b8a0eedeb9ee 100644 --- a/tests/ui/borrow_deref_ref_unfixable.stderr +++ b/tests/ui/borrow_deref_ref_unfixable.stderr @@ -13,9 +13,8 @@ LL + let x: &str = s; | help: if you would like to deref, try using `&**` | -LL - let x: &str = &*s; -LL + let x: &str = &**s; - | +LL | let x: &str = &**s; + | + error: aborting due to 1 previous error diff --git a/tests/ui/fn_to_numeric_cast_any.stderr b/tests/ui/fn_to_numeric_cast_any.stderr index c069c9d1672d..895297a04006 100644 --- a/tests/ui/fn_to_numeric_cast_any.stderr +++ b/tests/ui/fn_to_numeric_cast_any.stderr @@ -8,9 +8,8 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_any)]` help: did you mean to invoke the function? | -LL - let _ = foo as i8; -LL + let _ = foo() as i8; - | +LL | let _ = foo() as i8; + | ++ error: casting function pointer `foo` to `i16` --> tests/ui/fn_to_numeric_cast_any.rs:26:13 @@ -20,9 +19,8 @@ LL | let _ = foo as i16; | help: did you mean to invoke the function? | -LL - let _ = foo as i16; -LL + let _ = foo() as i16; - | +LL | let _ = foo() as i16; + | ++ error: casting function pointer `foo` to `i32` --> tests/ui/fn_to_numeric_cast_any.rs:28:13 @@ -32,9 +30,8 @@ LL | let _ = foo as i32; | help: did you mean to invoke the function? | -LL - let _ = foo as i32; -LL + let _ = foo() as i32; - | +LL | let _ = foo() as i32; + | ++ error: casting function pointer `foo` to `i64` --> tests/ui/fn_to_numeric_cast_any.rs:30:13 @@ -44,9 +41,8 @@ LL | let _ = foo as i64; | help: did you mean to invoke the function? | -LL - let _ = foo as i64; -LL + let _ = foo() as i64; - | +LL | let _ = foo() as i64; + | ++ error: casting function pointer `foo` to `i128` --> tests/ui/fn_to_numeric_cast_any.rs:32:13 @@ -56,9 +52,8 @@ LL | let _ = foo as i128; | help: did you mean to invoke the function? | -LL - let _ = foo as i128; -LL + let _ = foo() as i128; - | +LL | let _ = foo() as i128; + | ++ error: casting function pointer `foo` to `isize` --> tests/ui/fn_to_numeric_cast_any.rs:34:13 @@ -68,9 +63,8 @@ LL | let _ = foo as isize; | help: did you mean to invoke the function? | -LL - let _ = foo as isize; -LL + let _ = foo() as isize; - | +LL | let _ = foo() as isize; + | ++ error: casting function pointer `foo` to `u8` --> tests/ui/fn_to_numeric_cast_any.rs:37:13 @@ -80,9 +74,8 @@ LL | let _ = foo as u8; | help: did you mean to invoke the function? | -LL - let _ = foo as u8; -LL + let _ = foo() as u8; - | +LL | let _ = foo() as u8; + | ++ error: casting function pointer `foo` to `u16` --> tests/ui/fn_to_numeric_cast_any.rs:39:13 @@ -92,9 +85,8 @@ LL | let _ = foo as u16; | help: did you mean to invoke the function? | -LL - let _ = foo as u16; -LL + let _ = foo() as u16; - | +LL | let _ = foo() as u16; + | ++ error: casting function pointer `foo` to `u32` --> tests/ui/fn_to_numeric_cast_any.rs:41:13 @@ -104,9 +96,8 @@ LL | let _ = foo as u32; | help: did you mean to invoke the function? | -LL - let _ = foo as u32; -LL + let _ = foo() as u32; - | +LL | let _ = foo() as u32; + | ++ error: casting function pointer `foo` to `u64` --> tests/ui/fn_to_numeric_cast_any.rs:43:13 @@ -116,9 +107,8 @@ LL | let _ = foo as u64; | help: did you mean to invoke the function? | -LL - let _ = foo as u64; -LL + let _ = foo() as u64; - | +LL | let _ = foo() as u64; + | ++ error: casting function pointer `foo` to `u128` --> tests/ui/fn_to_numeric_cast_any.rs:45:13 @@ -128,9 +118,8 @@ LL | let _ = foo as u128; | help: did you mean to invoke the function? | -LL - let _ = foo as u128; -LL + let _ = foo() as u128; - | +LL | let _ = foo() as u128; + | ++ error: casting function pointer `foo` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:47:13 @@ -140,9 +129,8 @@ LL | let _ = foo as usize; | help: did you mean to invoke the function? | -LL - let _ = foo as usize; -LL + let _ = foo() as usize; - | +LL | let _ = foo() as usize; + | ++ error: casting function pointer `Struct::static_method` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:52:13 @@ -152,9 +140,8 @@ LL | let _ = Struct::static_method as usize; | help: did you mean to invoke the function? | -LL - let _ = Struct::static_method as usize; -LL + let _ = Struct::static_method() as usize; - | +LL | let _ = Struct::static_method() as usize; + | ++ error: casting function pointer `f` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:57:5 @@ -164,8 +151,7 @@ LL | f as usize | help: did you mean to invoke the function? | -LL - f as usize -LL + f() as usize +LL | f() as usize | error: casting function pointer `T::static_method` to `usize` @@ -176,8 +162,7 @@ LL | T::static_method as usize | help: did you mean to invoke the function? | -LL - T::static_method as usize -LL + T::static_method() as usize +LL | T::static_method() as usize | error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` @@ -188,9 +173,8 @@ LL | let _ = (clos as fn(u32) -> u32) as usize; | help: did you mean to invoke the function? | -LL - let _ = (clos as fn(u32) -> u32) as usize; -LL + let _ = (clos as fn(u32) -> u32)() as usize; - | +LL | let _ = (clos as fn(u32) -> u32)() as usize; + | ++ error: casting function pointer `foo` to `*const ()` --> tests/ui/fn_to_numeric_cast_any.rs:74:13 @@ -200,9 +184,8 @@ LL | let _ = foo as *const (); | help: did you mean to invoke the function? | -LL - let _ = foo as *const (); -LL + let _ = foo() as *const (); - | +LL | let _ = foo() as *const (); + | ++ error: aborting due to 17 previous errors diff --git a/tests/ui/implicit_hasher.stderr b/tests/ui/implicit_hasher.stderr index 6e964c65a2e4..01d08a1bd9b2 100644 --- a/tests/ui/implicit_hasher.stderr +++ b/tests/ui/implicit_hasher.stderr @@ -78,9 +78,8 @@ LL | pub fn map(map: &mut HashMap) {} | help: add a type parameter for `BuildHasher` | -LL - pub fn map(map: &mut HashMap) {} -LL + pub fn map(map: &mut HashMap) {} - | +LL | pub fn map(map: &mut HashMap) {} + | +++++++++++++++++++++++++++++ +++ error: parameter of type `HashSet` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:70:22 @@ -90,9 +89,8 @@ LL | pub fn set(set: &mut HashSet) {} | help: add a type parameter for `BuildHasher` | -LL - pub fn set(set: &mut HashSet) {} -LL + pub fn set(set: &mut HashSet) {} - | +LL | pub fn set(set: &mut HashSet) {} + | +++++++++++++++++++++++++++++ +++ error: impl for `HashMap` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:76:43 @@ -116,9 +114,8 @@ LL | pub async fn election_vote(_data: HashMap) {} | help: add a type parameter for `BuildHasher` | -LL - pub async fn election_vote(_data: HashMap) {} -LL + pub async fn election_vote(_data: HashMap) {} - | +LL | pub async fn election_vote(_data: HashMap) {} + | +++++++++++++++++++++++++++++ +++ error: aborting due to 9 previous errors diff --git a/tests/ui/literals.stderr b/tests/ui/literals.stderr index a9192825b354..576b38a47d2d 100644 --- a/tests/ui/literals.stderr +++ b/tests/ui/literals.stderr @@ -99,9 +99,8 @@ LL + let fail8 = 123; | help: if you mean to use an octal constant, use `0o` | -LL - let fail8 = 0123; -LL + let fail8 = 0o123; - | +LL | let fail8 = 0o123; + | + error: integer type suffix should not be separated by an underscore --> tests/ui/literals.rs:48:16 diff --git a/tests/ui/octal_escapes.stderr b/tests/ui/octal_escapes.stderr index c8a89ac8bea4..61c781e316ef 100644 --- a/tests/ui/octal_escapes.stderr +++ b/tests/ui/octal_escapes.stderr @@ -14,9 +14,8 @@ LL + let _bad1 = "\x1b[0m"; | help: if a null escape is intended, disambiguate using | -LL - let _bad1 = "\033[0m"; -LL + let _bad1 = "\x0033[0m"; - | +LL | let _bad1 = "\x0033[0m"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:6:19 @@ -31,9 +30,8 @@ LL + let _bad2 = b"\x1b[0m"; | help: if a null escape is intended, disambiguate using | -LL - let _bad2 = b"\033[0m"; -LL + let _bad2 = b"\x0033[0m"; - | +LL | let _bad2 = b"\x0033[0m"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:7:20 @@ -48,9 +46,8 @@ LL + let _bad3 = "\\\x1b[0m"; | help: if a null escape is intended, disambiguate using | -LL - let _bad3 = "\\\033[0m"; -LL + let _bad3 = "\\\x0033[0m"; - | +LL | let _bad3 = "\\\x0033[0m"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:9:18 @@ -65,9 +62,8 @@ LL + let _bad4 = "\x0a34567"; | help: if a null escape is intended, disambiguate using | -LL - let _bad4 = "\01234567"; -LL + let _bad4 = "\x001234567"; - | +LL | let _bad4 = "\x001234567"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:10:20 @@ -77,14 +73,12 @@ LL | let _bad5 = "\0\03"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad5 = "\0\03"; -LL + let _bad5 = "\0\x03"; - | +LL | let _bad5 = "\0\x03"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad5 = "\0\03"; -LL + let _bad5 = "\0\x0003"; - | +LL | let _bad5 = "\0\x0003"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:23 @@ -99,9 +93,8 @@ LL + let _bad6 = "Text-\x2d\077-MoreText"; | help: if a null escape is intended, disambiguate using | -LL - let _bad6 = "Text-\055\077-MoreText"; -LL + let _bad6 = "Text-\x0055\077-MoreText"; - | +LL | let _bad6 = "Text-\x0055\077-MoreText"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:27 @@ -116,9 +109,8 @@ LL + let _bad6 = "Text-\055\x3f-MoreText"; | help: if a null escape is intended, disambiguate using | -LL - let _bad6 = "Text-\055\077-MoreText"; -LL + let _bad6 = "Text-\055\x0077-MoreText"; - | +LL | let _bad6 = "Text-\055\x0077-MoreText"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:31 @@ -128,14 +120,12 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:34 @@ -145,14 +135,12 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:17:19 @@ -162,14 +150,12 @@ LL | let _bad8 = "锈\01锈"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad8 = "锈\01锈"; -LL + let _bad8 = "锈\x01锈"; - | +LL | let _bad8 = "锈\x01锈"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad8 = "锈\01锈"; -LL + let _bad8 = "锈\x0001锈"; - | +LL | let _bad8 = "锈\x0001锈"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:18:19 @@ -184,9 +170,8 @@ LL + let _bad9 = "锈\x09锈"; | help: if a null escape is intended, disambiguate using | -LL - let _bad9 = "锈\011锈"; -LL + let _bad9 = "锈\x0011锈"; - | +LL | let _bad9 = "锈\x0011锈"; + | ++ error: aborting due to 11 previous errors diff --git a/tests/ui/suspicious_to_owned.stderr b/tests/ui/suspicious_to_owned.stderr index 74bbcfcca51e..2c26565d5ef1 100644 --- a/tests/ui/suspicious_to_owned.stderr +++ b/tests/ui/suspicious_to_owned.stderr @@ -8,9 +8,8 @@ LL | let _ = cow.to_owned(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_to_owned)]` help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); @@ -25,9 +24,8 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); @@ -42,9 +40,8 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); @@ -59,9 +56,8 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); From a04e819b937471a89dff103a83139fea7ed9125f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 21 Feb 2025 00:29:56 +0000 Subject: [PATCH 206/991] Trim suggestion part before generating highlights --- tests/ui/async_yields_async.stderr | 12 ++++++------ tests/ui/fn_to_numeric_cast_any.stderr | 4 ++-- tests/ui/implicit_return.stderr | 14 ++++++-------- tests/ui/manual_flatten.stderr | 8 +++----- tests/ui/too_long_first_doc_paragraph-fix.stderr | 2 +- tests/ui/too_long_first_doc_paragraph.stderr | 4 ++-- 6 files changed, 20 insertions(+), 24 deletions(-) diff --git a/tests/ui/async_yields_async.stderr b/tests/ui/async_yields_async.stderr index 474914299d06..8c023d0d61f4 100644 --- a/tests/ui/async_yields_async.stderr +++ b/tests/ui/async_yields_async.stderr @@ -14,9 +14,9 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::async_yields_async)]` help: consider awaiting this value | -LL ~ async { -LL + 3 -LL + }.await +LL | async { +LL | 3 +LL ~ }.await | error: an async construct yields a type which is itself awaitable @@ -46,9 +46,9 @@ LL | | }; | help: consider awaiting this value | -LL ~ async { -LL + 3 -LL + }.await +LL | async { +LL | 3 +LL ~ }.await | error: an async construct yields a type which is itself awaitable diff --git a/tests/ui/fn_to_numeric_cast_any.stderr b/tests/ui/fn_to_numeric_cast_any.stderr index 895297a04006..0238e3a91369 100644 --- a/tests/ui/fn_to_numeric_cast_any.stderr +++ b/tests/ui/fn_to_numeric_cast_any.stderr @@ -152,7 +152,7 @@ LL | f as usize help: did you mean to invoke the function? | LL | f() as usize - | + | ++ error: casting function pointer `T::static_method` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:62:5 @@ -163,7 +163,7 @@ LL | T::static_method as usize help: did you mean to invoke the function? | LL | T::static_method() as usize - | + | ++ error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:69:13 diff --git a/tests/ui/implicit_return.stderr b/tests/ui/implicit_return.stderr index 7ea72307450c..936a779fa747 100644 --- a/tests/ui/implicit_return.stderr +++ b/tests/ui/implicit_return.stderr @@ -9,7 +9,7 @@ LL | true help: add `return` as shown | LL | return true - | + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:19:15 @@ -122,7 +122,7 @@ LL | format!("test {}", "test") help: add `return` as shown | LL | return format!("test {}", "test") - | + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:90:5 @@ -133,7 +133,7 @@ LL | m!(true, false) help: add `return` as shown | LL | return m!(true, false) - | + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:96:13 @@ -169,10 +169,8 @@ LL | | } | help: add `return` as shown | -LL ~ return loop { -LL + m!(true); -LL + } - | +LL | return loop { + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:130:5 @@ -183,7 +181,7 @@ LL | true help: add `return` as shown | LL | return true - | + | ++++++ error: aborting due to 16 previous errors diff --git a/tests/ui/manual_flatten.stderr b/tests/ui/manual_flatten.stderr index cf1b0a1c8bbf..93f7f11b5e64 100644 --- a/tests/ui/manual_flatten.stderr +++ b/tests/ui/manual_flatten.stderr @@ -196,11 +196,9 @@ LL | | } | |_________^ help: try | -LL ~ for n in vec![ -LL + -LL + Some(1), -LL + Some(2), -LL + Some(3) +LL | for n in vec![ +... +LL | Some(3) LL ~ ].iter().flatten() { | diff --git a/tests/ui/too_long_first_doc_paragraph-fix.stderr b/tests/ui/too_long_first_doc_paragraph-fix.stderr index 6ef333f0cfd2..84a574017a9b 100644 --- a/tests/ui/too_long_first_doc_paragraph-fix.stderr +++ b/tests/ui/too_long_first_doc_paragraph-fix.stderr @@ -12,7 +12,7 @@ LL | | /// 200 characters so I needed to write something longeeeeeeer. = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]` help: add an empty line | -LL ~ /// A very short summary. +LL | /// A very short summary. LL + /// | diff --git a/tests/ui/too_long_first_doc_paragraph.stderr b/tests/ui/too_long_first_doc_paragraph.stderr index 95f42349b9b3..8bc853132ec0 100644 --- a/tests/ui/too_long_first_doc_paragraph.stderr +++ b/tests/ui/too_long_first_doc_paragraph.stderr @@ -12,8 +12,8 @@ LL | | //! 200 characters so I needed to write something longeeeeeeer. = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]` help: add an empty line | -LL ~ //! A very short summary. -LL + //! +LL | //! A very short summary. +LL ~ //! LL ~ //! A much longer explanation that goes into a lot more detail about | From 812b1dec4abb52a38652956d8b82d9bbe0162999 Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 20 Feb 2025 18:18:01 -0800 Subject: [PATCH 207/991] ref_pat_eat_one_layer_2024: add context and examples to the unstable book --- .../ref-pat-eat-one-layer-2024-structural.md | 26 +++++++++++++++--- .../ref-pat-eat-one-layer-2024.md | 27 ++++++++++++++++--- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md index bfdb579cd352..b2f59732801b 100644 --- a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md +++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md @@ -9,12 +9,32 @@ The tracking issue for this feature is: [#123076] This feature is incomplete and not yet intended for general use. This implements experimental, Edition-dependent match ergonomics under consideration for inclusion -in Rust. -For more information, see the corresponding typing rules for [Editions 2021 and earlier] and for -[Editions 2024 and later]. +in Rust, allowing `&` patterns in more places. For example: +```rust,edition2024 +#![feature(ref_pat_eat_one_layer_2024_structural)] +#![allow(incomplete_features)] +# +# // Tests type equality in a way that avoids coercing `&&T` or `&mut T` to `&T`. +# trait Eq {} +# impl Eq for T {} +# fn has_type(_: impl Eq) {} + +// `&` can match against a `ref` binding mode instead of a reference type: +let (x, &y) = &(0, 1); +has_type::<&u8>(x); +has_type::(y); + +// `&` can match against `&mut` references: +let &z = &mut 2; +has_type::(z); +``` + +For specifics, see the corresponding typing rules for [Editions 2021 and earlier] and for +[Editions 2024 and later]. For more information on binding modes, see [The Rust Reference]. For alternative experimental match ergonomics, see the feature [`ref_pat_eat_one_layer_2024`](./ref-pat-eat-one-layer-2024.md). [Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQEBAAAAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false [Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAgEBAQEBAgIAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false +[The Rust Reference]: https://doc.rust-lang.org/reference/patterns.html#binding-modes diff --git a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md index 0c90cec0dbdd..f7c85eec2d28 100644 --- a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md +++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md @@ -9,12 +9,33 @@ The tracking issue for this feature is: [#123076] This feature is incomplete and not yet intended for general use. This implements experimental, Edition-dependent match ergonomics under consideration for inclusion -in Rust. -For more information, see the corresponding typing rules for [Editions 2021 and earlier] and for -[Editions 2024 and later]. +in Rust, allowing `&` patterns in more places. For example: + +```rust,edition2024 +#![feature(ref_pat_eat_one_layer_2024)] +#![allow(incomplete_features)] +# +# // Tests type equality in a way that avoids coercing `&&T` or `&mut T` to `&T`. +# trait Eq {} +# impl Eq for T {} +# fn has_type(_: impl Eq) {} + +// `&` can match against a `ref` binding mode instead of a reference type: +let (x, &y) = &(0, 1); +has_type::<&u8>(x); +has_type::(y); + +// `&` can match against `&mut` references: +let &z = &mut 2; +has_type::(z); +``` + +For specifics, see the corresponding typing rules for [Editions 2021 and earlier] and for +[Editions 2024 and later]. For more information on binding modes, see [The Rust Reference]. For alternative experimental match ergonomics, see the feature [`ref_pat_eat_one_layer_2024_structural`](./ref-pat-eat-one-layer-2024-structural.md). [Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQABAAAAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false [Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAAABAQABAgIAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false +[The Rust Reference]: https://doc.rust-lang.org/reference/patterns.html#binding-modes From bf26f2442365bbdc6c0785d884a042a824e1d37f Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Thu, 20 Feb 2025 17:24:09 +0100 Subject: [PATCH 208/991] Clarify/update comments in `BufRead::read_line`'s default body with where to *actually* look for more details --- library/std/src/io/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 980ea1478e08..7f610bc88bfd 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2534,7 +2534,7 @@ pub trait BufRead: Read { fn read_line(&mut self, buf: &mut String) -> Result { // Note that we are not calling the `.read_until` method here, but // rather our hardcoded implementation. For more details as to why, see - // the comments in `read_to_end`. + // the comments in `default_read_to_string`. unsafe { append_to_string(buf, |b| read_until(self, b'\n', b)) } } From c2d75cff47e208280ce9c8d81331639dbb1ae086 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 21 Feb 2025 07:54:35 +1100 Subject: [PATCH 209/991] Move methods from Map to TyCtxt, part 3. Continuing the work from #137162. Every method gains a `hir_` prefix. --- clippy_lints/src/assigning_clones.rs | 2 +- clippy_lints/src/doc/missing_headers.rs | 3 +- clippy_lints/src/doc/mod.rs | 2 +- clippy_lints/src/escape.rs | 3 +- clippy_lints/src/exit.rs | 2 +- clippy_lints/src/indexing_slicing.rs | 6 +-- clippy_lints/src/large_stack_arrays.rs | 2 +- clippy_lints/src/loops/infinite_loop.rs | 2 +- clippy_lints/src/loops/manual_find.rs | 2 +- clippy_lints/src/loops/needless_range_loop.rs | 4 +- .../src/matches/redundant_pattern_match.rs | 2 +- clippy_lints/src/methods/is_empty.rs | 3 +- clippy_lints/src/methods/iter_nth_zero.rs | 2 +- .../src/methods/manual_c_str_literals.rs | 2 +- clippy_lints/src/methods/manual_inspect.rs | 2 +- clippy_lints/src/methods/mod.rs | 2 +- clippy_lints/src/methods/or_fun_call.rs | 2 +- clippy_lints/src/methods/str_splitn.rs | 6 +-- .../src/methods/unnecessary_to_owned.rs | 2 +- clippy_lints/src/min_ident_chars.rs | 6 +-- clippy_lints/src/missing_const_for_fn.rs | 2 +- .../src/missing_const_for_thread_local.rs | 2 +- clippy_lints/src/needless_borrowed_ref.rs | 3 +- clippy_lints/src/needless_late_init.rs | 2 +- clippy_lints/src/needless_pass_by_ref_mut.rs | 3 +- clippy_lints/src/new_without_default.rs | 2 +- clippy_lints/src/no_effect.rs | 2 +- clippy_lints/src/non_copy_const.rs | 2 +- clippy_lints/src/non_zero_suggestions.rs | 2 +- .../src/operators/assign_op_pattern.rs | 2 +- clippy_lints/src/operators/identity_op.rs | 4 +- clippy_lints/src/panic_unimplemented.rs | 4 +- clippy_lints/src/ptr.rs | 3 +- clippy_lints/src/redundant_locals.rs | 5 +- clippy_lints/src/returns.rs | 5 +- clippy_lints/src/self_named_constructors.rs | 2 +- clippy_lints/src/shadow.rs | 10 ++-- .../src/significant_drop_tightening.rs | 3 +- clippy_lints/src/suspicious_trait_impl.rs | 4 +- clippy_lints/src/transmute/eager_transmute.rs | 2 +- .../missing_transmute_annotations.rs | 2 +- clippy_lints/src/types/mod.rs | 5 +- clippy_lints/src/unconditional_recursion.rs | 6 +-- .../src/undocumented_unsafe_blocks.rs | 5 +- clippy_lints/src/unused_io_amount.rs | 2 +- clippy_lints/src/unused_peekable.rs | 2 +- clippy_lints/src/unused_self.rs | 2 +- clippy_lints/src/zero_sized_map_values.rs | 4 +- clippy_utils/src/higher.rs | 2 +- clippy_utils/src/lib.rs | 51 +++++++++---------- clippy_utils/src/macros.rs | 2 +- 51 files changed, 96 insertions(+), 108 deletions(-) diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs index c01155ca86e0..348495f97a27 100644 --- a/clippy_lints/src/assigning_clones.rs +++ b/clippy_lints/src/assigning_clones.rs @@ -107,7 +107,7 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones { && !cx.tcx.is_builtin_derived(resolved_impl) // Don't suggest calling a function we're implementing. && resolved_impl.as_local().is_none_or(|block_id| { - cx.tcx.hir().parent_owner_iter(e.hir_id).all(|(id, _)| id.def_id != block_id) + cx.tcx.hir_parent_owner_iter(e.hir_id).all(|(id, _)| id.def_id != block_id) }) && let resolved_assoc_items = cx.tcx.associated_items(resolved_impl) // Only suggest if `clone_from`/`clone_into` is explicitly implemented diff --git a/clippy_lints/src/doc/missing_headers.rs b/clippy_lints/src/doc/missing_headers.rs index d1ffbb6ffe25..e8638595c4b2 100644 --- a/clippy_lints/src/doc/missing_headers.rs +++ b/clippy_lints/src/doc/missing_headers.rs @@ -24,8 +24,7 @@ pub fn check( if !check_private_items && cx .tcx - .hir() - .parent_iter(owner_id.into()) + .hir_parent_iter(owner_id.into()) .any(|(id, _node)| is_doc_hidden(cx.tcx.hir().attrs(id))) { return; diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 93c2b7a2d182..713d62a8801d 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -1057,7 +1057,7 @@ impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> { "assert" | "assert_eq" | "assert_ne" ) { - self.is_const = self.cx.tcx.hir().is_inside_const_context(expr.hir_id); + self.is_const = self.cx.tcx.hir_is_inside_const_context(expr.hir_id); self.panic_span = Some(macro_call.span); } } diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index c55d4387d696..0c06c9117d73 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -80,8 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { let parent_id = cx .tcx - .hir() - .get_parent_item(cx.tcx.local_def_id_to_hir_id(fn_def_id)) + .hir_get_parent_item(cx.tcx.local_def_id_to_hir_id(fn_def_id)) .def_id; let mut trait_self_ty = None; diff --git a/clippy_lints/src/exit.rs b/clippy_lints/src/exit.rs index e6ddcd107d9d..cc8e4d7d9e28 100644 --- a/clippy_lints/src/exit.rs +++ b/clippy_lints/src/exit.rs @@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit { && let ExprKind::Path(ref path) = path_expr.kind && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id() && cx.tcx.is_diagnostic_item(sym::process_exit, def_id) - && let parent = cx.tcx.hir().get_parent_item(e.hir_id) + && let parent = cx.tcx.hir_get_parent_item(e.hir_id) && let OwnerNode::Item(Item{kind: ItemKind::Fn{ .. }, ..}) = cx.tcx.hir_owner_node(parent) // If the next item up is a function we check if it is an entry point // and only then emit a linter warning diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index f666ed0a440b..33431385c7de 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -112,7 +112,7 @@ impl IndexingSlicing { impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Index(array, index, _) = &expr.kind - && (!self.suppress_restriction_lint_in_const || !cx.tcx.hir().is_inside_const_context(expr.hir_id)) + && (!self.suppress_restriction_lint_in_const || !cx.tcx.hir_is_inside_const_context(expr.hir_id)) && let expr_ty = cx.typeck_results().expr_ty(array) && let mut deref = deref_chain(cx, expr_ty) && deref.any(|l| { @@ -181,7 +181,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { span_lint_and_then(cx, INDEXING_SLICING, expr.span, "slicing may panic", |diag| { diag.help(help_msg); - if cx.tcx.hir().is_inside_const_context(expr.hir_id) { + if cx.tcx.hir_is_inside_const_context(expr.hir_id) { diag.note(note); } }); @@ -223,7 +223,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { span_lint_and_then(cx, INDEXING_SLICING, expr.span, "indexing may panic", |diag| { diag.help("consider using `.get(n)` or `.get_mut(n)` instead"); - if cx.tcx.hir().is_inside_const_context(expr.hir_id) { + if cx.tcx.hir_is_inside_const_context(expr.hir_id) { diag.note(note); } }); diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index c68499ce9f78..620e27fa67c6 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let Some(element_count) = cst.try_to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) - && !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| { + && !cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, node)| { matches!( node, Node::Item(Item { diff --git a/clippy_lints/src/loops/infinite_loop.rs b/clippy_lints/src/loops/infinite_loop.rs index 4d206850c998..797ff1f39866 100644 --- a/clippy_lints/src/loops/infinite_loop.rs +++ b/clippy_lints/src/loops/infinite_loop.rs @@ -61,7 +61,7 @@ pub(super) fn check<'tcx>( } fn get_parent_fn_ret_ty<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option> { - for (_, parent_node) in cx.tcx.hir().parent_iter(expr.hir_id) { + for (_, parent_node) in cx.tcx.hir_parent_iter(expr.hir_id) { match parent_node { // Skip `Coroutine` closures, these are the body of `async fn`, not async closures. // This is because we still need to backtrack one parent node to get the `OpaqueDef` ty. diff --git a/clippy_lints/src/loops/manual_find.rs b/clippy_lints/src/loops/manual_find.rs index 1721f569541b..aa8a2934f89b 100644 --- a/clippy_lints/src/loops/manual_find.rs +++ b/clippy_lints/src/loops/manual_find.rs @@ -134,7 +134,7 @@ fn last_stmt_and_ret<'tcx>( } None } - let mut parent_iter = cx.tcx.hir().parent_iter(expr.hir_id); + let mut parent_iter = cx.tcx.hir_parent_iter(expr.hir_id); if let Some((node_hir, Node::Stmt(..))) = parent_iter.next() // This should be the loop // This should be the function body diff --git a/clippy_lints/src/loops/needless_range_loop.rs b/clippy_lints/src/loops/needless_range_loop.rs index e98c3c9698ba..0f62183eb33d 100644 --- a/clippy_lints/src/loops/needless_range_loop.rs +++ b/clippy_lints/src/loops/needless_range_loop.rs @@ -56,7 +56,7 @@ pub(super) fn check<'tcx>( // ensure that the indexed variable was declared before the loop, see #601 if let Some(indexed_extent) = indexed_extent { - let parent_def_id = cx.tcx.hir().get_parent_item(expr.hir_id); + let parent_def_id = cx.tcx.hir_get_parent_item(expr.hir_id); let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id); let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id).unwrap(); if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) { @@ -256,7 +256,7 @@ impl<'tcx> VarVisitor<'_, 'tcx> { let res = self.cx.qpath_res(seqpath, seqexpr.hir_id); match res { Res::Local(hir_id) => { - let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id); + let parent_def_id = self.cx.tcx.hir_get_parent_item(expr.hir_id); let extent = self .cx .tcx diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index 393399660131..722ea7042dd7 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -199,7 +199,7 @@ fn find_method_sugg_for_if_let<'tcx>( // type needs to be considered, not just the inner type of the branch being matched on. // Note the last expression in a block is dropped after all local bindings. let check_ty = if has_else - || (keyword == "if" && matches!(cx.tcx.hir().parent_iter(expr.hir_id).next(), Some((_, Node::Block(..))))) + || (keyword == "if" && matches!(cx.tcx.hir_parent_iter(expr.hir_id).next(), Some((_, Node::Block(..))))) { op_ty } else { diff --git a/clippy_lints/src/methods/is_empty.rs b/clippy_lints/src/methods/is_empty.rs index 92c81b3c49d8..1c64f78678ae 100644 --- a/clippy_lints/src/methods/is_empty.rs +++ b/clippy_lints/src/methods/is_empty.rs @@ -40,8 +40,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool { cx.tcx - .hir() - .parent_id_iter(id) + .hir_parent_id_iter(id) .any(|id| cx.tcx.hir().attrs(id).iter().any(|attr| attr.has_name(sym::cfg))) } diff --git a/clippy_lints/src/methods/iter_nth_zero.rs b/clippy_lints/src/methods/iter_nth_zero.rs index 9ff6eaa34871..4bdf589f4876 100644 --- a/clippy_lints/src/methods/iter_nth_zero.rs +++ b/clippy_lints/src/methods/iter_nth_zero.rs @@ -11,7 +11,7 @@ use rustc_span::sym; use super::ITER_NTH_ZERO; pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) { - if let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id)) + if let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir_get_parent_item(expr.hir_id)) && let def_id = item.owner_id.to_def_id() && is_trait_method(cx, expr, sym::Iterator) && let Some(Constant::Int(0)) = ConstEvalCtxt::new(cx).eval(arg) diff --git a/clippy_lints/src/methods/manual_c_str_literals.rs b/clippy_lints/src/methods/manual_c_str_literals.rs index 7d5ebdedd0c3..e1ebca0b09df 100644 --- a/clippy_lints/src/methods/manual_c_str_literals.rs +++ b/clippy_lints/src/methods/manual_c_str_literals.rs @@ -187,7 +187,7 @@ fn peel_ptr_cast<'tcx>(e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { /// ^ given this `x` expression, returns the `foo(...)` expression fn peel_ptr_cast_ancestors<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { let mut prev = e; - for (_, node) in cx.tcx.hir().parent_iter(e.hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(e.hir_id) { if let Node::Expr(e) = node && get_cast_target(e).is_some() { diff --git a/clippy_lints/src/methods/manual_inspect.rs b/clippy_lints/src/methods/manual_inspect.rs index de37df2394d3..09ccb386a20b 100644 --- a/clippy_lints/src/methods/manual_inspect.rs +++ b/clippy_lints/src/methods/manual_inspect.rs @@ -123,7 +123,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: }; let mut prev_expr = e; - for (_, parent) in cx.tcx.hir().parent_iter(e.hir_id) { + for (_, parent) in cx.tcx.hir_parent_iter(e.hir_id) { if let Node::Expr(e) = parent { match e.kind { ExprKind::Field(_, name) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index ccc5cd4fa417..b58e8ba32e78 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -4671,7 +4671,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { return; } let name = impl_item.ident.name.as_str(); - let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; + let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index f5f404070cab..69f933fee68f 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -92,7 +92,7 @@ pub(super) fn check<'tcx>( let in_sugg_method_implementation = { matches!( suggested_method_def_id.as_local(), - Some(local_def_id) if local_def_id == cx.tcx.hir().get_parent_item(receiver.hir_id).def_id + Some(local_def_id) if local_def_id == cx.tcx.hir_get_parent_item(receiver.hir_id).def_id ) }; if in_sugg_method_implementation { diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs index 8a99974394c3..8389c2e3f982 100644 --- a/clippy_lints/src/methods/str_splitn.rs +++ b/clippy_lints/src/methods/str_splitn.rs @@ -35,7 +35,7 @@ pub(super) fn check( }; let manual = count == 2 && msrv.meets(msrvs::STR_SPLIT_ONCE); - match parse_iter_usage(cx, expr.span.ctxt(), cx.tcx.hir().parent_iter(expr.hir_id)) { + match parse_iter_usage(cx, expr.span.ctxt(), cx.tcx.hir_parent_iter(expr.hir_id)) { Some(usage) if needless(usage.kind) => lint_needless(cx, method_name, expr, self_arg, pat_arg), Some(usage) if manual => check_manual_split_once(cx, method_name, expr, self_arg, pat_arg, &usage), None if manual => { @@ -127,7 +127,7 @@ fn check_manual_split_once_indirect( pat_arg: &Expr<'_>, ) -> Option<()> { let ctxt = expr.span.ctxt(); - let mut parents = cx.tcx.hir().parent_iter(expr.hir_id); + let mut parents = cx.tcx.hir_parent_iter(expr.hir_id); if let (_, Node::LetStmt(local)) = parents.next()? && let PatKind::Binding(BindingMode::MUT, iter_binding_id, _, None) = local.pat.kind && let (iter_stmt_id, Node::Stmt(_)) = parents.next()? @@ -220,7 +220,7 @@ fn indirect_usage<'tcx>( ControlFlow::Continue(Descend::from(path_to_binding.is_none())) }); - let mut parents = cx.tcx.hir().parent_iter(path_to_binding?.hir_id); + let mut parents = cx.tcx.hir_parent_iter(path_to_binding?.hir_id); let iter_usage = parse_iter_usage(cx, ctxt, &mut parents)?; let (parent_id, _) = parents.find(|(_, node)| { diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index e80d99dca56d..ea134c057053 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -494,7 +494,7 @@ fn get_input_traits_and_projections<'tcx>( #[expect(clippy::too_many_lines)] fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<'a>) -> bool { - for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(expr.hir_id) { match node { Node::Stmt(_) => return true, Node::Block(..) => {}, diff --git a/clippy_lints/src/min_ident_chars.rs b/clippy_lints/src/min_ident_chars.rs index 4119b1d1051c..e5801124db48 100644 --- a/clippy_lints/src/min_ident_chars.rs +++ b/clippy_lints/src/min_ident_chars.rs @@ -121,9 +121,9 @@ impl Visitor<'_> for IdentVisitor<'_, '_> { // Check whether the node is part of a `use` statement. We don't want to emit a warning if the user // has no control over the type. let usenode = opt_as_use_node(node).or_else(|| { - cx.tcx - .hir() - .parent_iter(hir_id) + cx + .tcx + .hir_parent_iter(hir_id) .find_map(|(_, node)| opt_as_use_node(node)) }); diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index ba4af134ccd0..8d751c2c0acb 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { // Const fns are not allowed as methods in a trait. { - let parent = cx.tcx.hir().get_parent_item(hir_id).def_id; + let parent = cx.tcx.hir_get_parent_item(hir_id).def_id; if parent != CRATE_DEF_ID { if let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent) { if let hir::ItemKind::Trait(..) = &item.kind { diff --git a/clippy_lints/src/missing_const_for_thread_local.rs b/clippy_lints/src/missing_const_for_thread_local.rs index e2ca4458edaa..d4181c677afd 100644 --- a/clippy_lints/src/missing_const_for_thread_local.rs +++ b/clippy_lints/src/missing_const_for_thread_local.rs @@ -81,7 +81,7 @@ fn is_unreachable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { | sym::core_panic_2015_macro | sym::std_panic_2015_macro | sym::core_panic_2021_macro - ) && !cx.tcx.hir().is_inside_const_context(expr.hir_id)) + ) && !cx.tcx.hir_is_inside_const_context(expr.hir_id)) || matches!( diag_name, sym::unimplemented_macro | sym::todo_macro | sym::unreachable_macro | sym::unreachable_2015_macro diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index 098098718af3..1b6896827fed 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -41,8 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef { && !ref_pat.span.from_expansion() && cx .tcx - .hir() - .parent_iter(ref_pat.hir_id) + .hir_parent_iter(ref_pat.hir_id) .map_while(|(_, parent)| if let Node::Pat(pat) = parent { Some(pat) } else { None }) // Do not lint patterns that are part of an OR `|` pattern, the binding mode must match in all arms .all(|pat| !matches!(pat.kind, PatKind::Or(_))) diff --git a/clippy_lints/src/needless_late_init.rs b/clippy_lints/src/needless_late_init.rs index 4e19a2f409dd..863a1f895c93 100644 --- a/clippy_lints/src/needless_late_init.rs +++ b/clippy_lints/src/needless_late_init.rs @@ -347,7 +347,7 @@ fn check<'tcx>( impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) { - let mut parents = cx.tcx.hir().parent_iter(local.hir_id); + let mut parents = cx.tcx.hir_parent_iter(local.hir_id); if let LetStmt { init: None, pat: diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 5e85d23718a9..36a0738cbc95 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -350,8 +350,7 @@ impl MutablyUsedVariablesCtxt<'_> { // The goal here is to find if the current scope is unsafe or not. It stops when it finds // a function or an unsafe block. fn is_in_unsafe_block(&self, item: HirId) -> bool { - let hir = self.tcx.hir(); - for (parent, node) in hir.parent_iter(item) { + for (parent, node) in self.tcx.hir_parent_iter(item) { if let Some(fn_sig) = self.tcx.hir_fn_sig_by_hir_id(parent) { return fn_sig.header.is_unsafe(); } else if let Node::Block(block) = node { diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index cf407e51f7af..f0ee613791fb 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -90,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { if sig.decl.inputs.is_empty() && name == sym::new && cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id) - && let self_def_id = cx.tcx.hir().get_parent_item(id.into()) + && let self_def_id = cx.tcx.hir_get_parent_item(id.into()) && let self_ty = cx.tcx.type_of(self_def_id).instantiate_identity() && self_ty == return_ty(cx, id) && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default) diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 4d3e6aa79d0a..7187a8f2c11a 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -141,7 +141,7 @@ impl NoEffect { stmt.span, "statement with no effect", |diag| { - for parent in cx.tcx.hir().parent_iter(stmt.hir_id) { + for parent in cx.tcx.hir_parent_iter(stmt.hir_id) { if let Node::Item(item) = parent.1 && let ItemKind::Fn { .. } = item.kind && let Node::Block(block) = cx.tcx.parent_hir_node(stmt.hir_id) diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index f965ab90da23..4007ca88a00e 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -344,7 +344,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { if let ImplItemKind::Const(_, body_id) = &impl_item.kind { - let item_def_id = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; + let item_def_id = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(item_def_id); match &item.kind { diff --git a/clippy_lints/src/non_zero_suggestions.rs b/clippy_lints/src/non_zero_suggestions.rs index f6ce1d1d5867..16c4391c0fbe 100644 --- a/clippy_lints/src/non_zero_suggestions.rs +++ b/clippy_lints/src/non_zero_suggestions.rs @@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for NonZeroSuggestions { check_non_zero_conversion(cx, rhs, Applicability::MachineApplicable); } else { // Check if the parent expression is a binary operation - let parent_is_binary = cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| { + let parent_is_binary = cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, node)| { matches!(node, rustc_hir::Node::Expr(parent_expr) if matches!(parent_expr.kind, ExprKind::Binary(..))) }); diff --git a/clippy_lints/src/operators/assign_op_pattern.rs b/clippy_lints/src/operators/assign_op_pattern.rs index 1315c3dfc127..5737a91031db 100644 --- a/clippy_lints/src/operators/assign_op_pattern.rs +++ b/clippy_lints/src/operators/assign_op_pattern.rs @@ -26,7 +26,7 @@ pub(super) fn check<'tcx>( let rty = cx.typeck_results().expr_ty(rhs); if let Some((_, lang_item)) = binop_traits(op.node) && let Some(trait_id) = cx.tcx.lang_items().get(lang_item) - && let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id).def_id + && let parent_fn = cx.tcx.hir_get_parent_item(e.hir_id).def_id && trait_ref_of_method(cx, parent_fn).is_none_or(|t| t.path.res.def_id() != trait_id) && implements_trait(cx, ty, trait_id, &[rty.into()]) { diff --git a/clippy_lints/src/operators/identity_op.rs b/clippy_lints/src/operators/identity_op.rs index 1c2d6e90fc95..035823228278 100644 --- a/clippy_lints/src/operators/identity_op.rs +++ b/clippy_lints/src/operators/identity_op.rs @@ -120,7 +120,7 @@ fn needs_parenthesis(cx: &LateContext<'_>, binary: &Expr<'_>, child: &Expr<'_>) // the parent HIR node is an expression, or if the parent HIR node // is a Block or Stmt, and the new left hand side would need // parenthesis be treated as a statement rather than an expression. - if let Some((_, parent)) = cx.tcx.hir().parent_iter(binary.hir_id).next() { + if let Some((_, parent)) = cx.tcx.hir_parent_iter(binary.hir_id).next() { match parent { Node::Expr(_) => return Parens::Needed, Node::Block(_) | Node::Stmt(_) => { @@ -142,7 +142,7 @@ fn needs_parenthesis(cx: &LateContext<'_>, binary: &Expr<'_>, child: &Expr<'_>) // This would mean that the rustfix suggestion will appear at the start of a line, which causes // these expressions to be interpreted as statements if they do not have parenthesis. let mut prev_id = binary.hir_id; - for (_, parent) in cx.tcx.hir().parent_iter(binary.hir_id) { + for (_, parent) in cx.tcx.hir_parent_iter(binary.hir_id) { if let Node::Expr(expr) = parent && let ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) | ExprKind::Unary(_, lhs) = expr.kind && lhs.hir_id == prev_id diff --git a/clippy_lints/src/panic_unimplemented.rs b/clippy_lints/src/panic_unimplemented.rs index fa5b02a5a41b..c9bdeed660e2 100644 --- a/clippy_lints/src/panic_unimplemented.rs +++ b/clippy_lints/src/panic_unimplemented.rs @@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let Some(macro_call) = root_macro_call_first_node(cx, expr) { if is_panic(cx, macro_call.def_id) { - if cx.tcx.hir().is_inside_const_context(expr.hir_id) + if cx.tcx.hir_is_inside_const_context(expr.hir_id) || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id) { return; @@ -139,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented { && let Res::Def(DefKind::Fn, def_id) = expr_path.res && match_def_path(cx, def_id, &paths::PANIC_ANY) { - if cx.tcx.hir().is_inside_const_context(expr.hir_id) + if cx.tcx.hir_is_inside_const_context(expr.hir_id) || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id) { return; diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 9b241edf4ccf..ef4948a05b7f 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -186,8 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { } fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { - let hir = cx.tcx.hir(); - let mut parents = hir.parent_iter(body.value.hir_id); + let mut parents = cx.tcx.hir_parent_iter(body.value.hir_id); let (item_id, sig, is_trait_item) = match parents.next() { Some((_, Node::Item(i))) => { if let ItemKind::Fn { sig, .. } = &i.kind { diff --git a/clippy_lints/src/redundant_locals.rs b/clippy_lints/src/redundant_locals.rs index e15e12629209..f3ccc9e38f4d 100644 --- a/clippy_lints/src/redundant_locals.rs +++ b/clippy_lints/src/redundant_locals.rs @@ -122,8 +122,7 @@ fn find_binding(pat: &Pat<'_>, name: Ident) -> Option { /// Check if a rebinding of a local changes the effect of assignments to the binding. fn affects_assignments(cx: &LateContext<'_>, mutability: Mutability, bind: HirId, rebind: HirId) -> bool { - let hir = cx.tcx.hir(); - // the binding is mutable and the rebinding is in a different scope than the original binding - mutability == Mutability::Mut && hir.get_enclosing_scope(bind) != hir.get_enclosing_scope(rebind) + mutability == Mutability::Mut + && cx.tcx.hir_get_enclosing_scope(bind) != cx.tcx.hir_get_enclosing_scope(rebind) } diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 9f0ea84246dd..152739c2973b 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -177,8 +177,7 @@ declare_lint_pass!(Return => [LET_AND_RETURN, NEEDLESS_RETURN, NEEDLESS_RETURN_W /// because of the never-ness of `return` expressions fn stmt_needs_never_type(cx: &LateContext<'_>, stmt_hir_id: HirId) -> bool { cx.tcx - .hir() - .parent_iter(stmt_hir_id) + .hir_parent_iter(stmt_hir_id) .find_map(|(_, node)| if let Node::Expr(expr) = node { Some(expr) } else { None }) .is_some_and(|e| { cx.typeck_results() @@ -203,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { && is_res_lang_ctor(cx, path_res(cx, maybe_constr), ResultErr) // Ensure this is not the final stmt, otherwise removing it would cause a compile error - && let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id)) + && let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir_get_parent_item(expr.hir_id)) && let ItemKind::Fn { body, .. } = item.kind && let block = cx.tcx.hir_body(body).value && let ExprKind::Block(block, _) = block.kind diff --git a/clippy_lints/src/self_named_constructors.rs b/clippy_lints/src/self_named_constructors.rs index 23b47606f8aa..fc02c3a51716 100644 --- a/clippy_lints/src/self_named_constructors.rs +++ b/clippy_lints/src/self_named_constructors.rs @@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { _ => return, } - let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; + let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let ret_ty = return_ty(cx, impl_item.owner_id); diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index a931e39bac9c..ee282ee1dfb7 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -224,9 +224,9 @@ fn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span) /// Returns true if the expression is a simple transformation of a local binding such as `&x` fn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_id: HirId) -> bool { - let hir = cx.tcx.hir(); - let is_direct_binding = hir - .parent_iter(pat.hir_id) + let is_direct_binding = cx + .tcx + .hir_parent_iter(pat.hir_id) .map_while(|(_id, node)| match node { Node::Pat(pat) => Some(pat), _ => None, @@ -259,14 +259,14 @@ fn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_ /// For closure arguments passed to a method call, returns the method call, and the `HirId` of the /// closure (which will later be skipped). This is for fn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<(&'tcx Expr<'tcx>, Option)> { - for (hir_id, node) in cx.tcx.hir().parent_iter(hir_id) { + for (hir_id, node) in cx.tcx.hir_parent_iter(hir_id) { let init = match node { Node::Arm(_) | Node::Pat(_) | Node::PatField(_) | Node::Param(_) => continue, Node::Expr(expr) => match expr.kind { ExprKind::Match(e, _, _) | ExprKind::Let(&LetExpr { init: e, .. }) => Some((e, None)), // If we're a closure argument, then a parent call is also an associated item. ExprKind::Closure(_) => { - if let Some((_, node)) = cx.tcx.hir().parent_iter(hir_id).next() { + if let Some((_, node)) = cx.tcx.hir_parent_iter(hir_id).next() { match node { Node::Expr(expr) => match expr.kind { ExprKind::MethodCall(_, _, _, _) | ExprKind::Call(_, _) => Some((expr, Some(hir_id))), diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs index 597bfddecbc5..e9db7c9d031a 100644 --- a/clippy_lints/src/significant_drop_tightening.rs +++ b/clippy_lints/src/significant_drop_tightening.rs @@ -232,8 +232,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx let block_is_ancestor = self .cx .tcx - .hir() - .parent_iter(self.ap.curr_block_hir_id) + .hir_parent_iter(self.ap.curr_block_hir_id) .any(|(id, _)| id == apa.first_block_hir_id); if last_stmt_is_not_dummy && last_stmt_is_not_curr && (block_equals_curr || block_is_ancestor) { apa.has_expensive_expr_after_last_attr = true; diff --git a/clippy_lints/src/suspicious_trait_impl.rs b/clippy_lints/src/suspicious_trait_impl.rs index 9326b2adaffb..fb426e91bf01 100644 --- a/clippy_lints/src/suspicious_trait_impl.rs +++ b/clippy_lints/src/suspicious_trait_impl.rs @@ -63,11 +63,11 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl { // Check for more than one binary operation in the implemented function // Linting when multiple operations are involved can result in false positives - && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id + && let parent_fn = cx.tcx.hir_get_parent_item(expr.hir_id).def_id && let hir::Node::ImplItem(impl_item) = cx.tcx.hir_node_by_def_id(parent_fn) && let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind && let body = cx.tcx.hir_body(body_id) - && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id + && let parent_fn = cx.tcx.hir_get_parent_item(expr.hir_id).def_id && let Some(trait_ref) = trait_ref_of_method(cx, parent_fn) && let trait_id = trait_ref.path.res.def_id() && ![binop_trait_id, op_assign_trait_id].contains(&trait_id) diff --git a/clippy_lints/src/transmute/eager_transmute.rs b/clippy_lints/src/transmute/eager_transmute.rs index 1209bd5b34f2..81c0a57083e8 100644 --- a/clippy_lints/src/transmute/eager_transmute.rs +++ b/clippy_lints/src/transmute/eager_transmute.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::Ty; use super::EAGER_TRANSMUTE; fn peel_parent_unsafe_blocks<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { - for (_, parent) in cx.tcx.hir().parent_iter(expr.hir_id) { + for (_, parent) in cx.tcx.hir_parent_iter(expr.hir_id) { match parent { Node::Block(_) => {}, Node::Expr(e) if let ExprKind::Block(..) = e.kind => {}, diff --git a/clippy_lints/src/transmute/missing_transmute_annotations.rs b/clippy_lints/src/transmute/missing_transmute_annotations.rs index 0b5d83ef58ca..96286fcf73d6 100644 --- a/clippy_lints/src/transmute/missing_transmute_annotations.rs +++ b/clippy_lints/src/transmute/missing_transmute_annotations.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::Ty; use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS; fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) -> Option> { - let mut parent_iter = cx.tcx.hir().parent_iter(expr_hir_id); + let mut parent_iter = cx.tcx.hir_parent_iter(expr_hir_id); if let Some((_, node)) = parent_iter.next() { match node { Node::LetStmt(local) => Some(*local), diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 579cbf447a2b..71e6e75c1bd3 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -375,8 +375,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { ) { let is_in_trait_impl = if let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id( cx.tcx - .hir() - .get_parent_item(cx.tcx.local_def_id_to_hir_id(def_id)) + .hir_get_parent_item(cx.tcx.local_def_id_to_hir_id(def_id)) .def_id, ) { matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) @@ -420,7 +419,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { ImplItemKind::Const(ty, _) => { let is_in_trait_impl = if let hir::Node::Item(item) = cx .tcx - .hir_node_by_def_id(cx.tcx.hir().get_parent_item(item.hir_id()).def_id) + .hir_node_by_def_id(cx.tcx.hir_get_parent_item(item.hir_id()).def_id) { matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) } else { diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs index 76a0b927df42..a443043bef90 100644 --- a/clippy_lints/src/unconditional_recursion.rs +++ b/clippy_lints/src/unconditional_recursion.rs @@ -111,7 +111,7 @@ fn get_impl_trait_def_id(cx: &LateContext<'_>, method_def_id: LocalDefId) -> Opt owner_id, .. }), - )) = cx.tcx.hir().parent_iter(hir_id).next() + )) = cx.tcx.hir_parent_iter(hir_id).next() // We exclude `impl` blocks generated from rustc's proc macros. && !cx.tcx.has_attr(*owner_id, sym::automatically_derived) // It is a implementation of a trait. @@ -216,7 +216,7 @@ fn check_to_string(cx: &LateContext<'_>, method_span: Span, method_def_id: Local owner_id, .. }), - )) = cx.tcx.hir().parent_iter(hir_id).next() + )) = cx.tcx.hir_parent_iter(hir_id).next() // We exclude `impl` blocks generated from rustc's proc macros. && !cx.tcx.has_attr(*owner_id, sym::automatically_derived) // It is a implementation of a trait. @@ -367,7 +367,7 @@ impl UnconditionalRecursion { kind: ItemKind::Impl(impl_), .. }), - )) = cx.tcx.hir().parent_iter(hir_id).next() + )) = cx.tcx.hir_parent_iter(hir_id).next() && let Some(implemented_ty_id) = get_hir_ty_def_id(cx.tcx, *impl_.self_ty) && { self.init_default_impl_for_type_if_needed(cx); diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index c8e3c46f2f6f..93abf95e3577 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -291,7 +291,7 @@ fn expr_has_unnecessary_safety_comment<'tcx>( expr: &'tcx hir::Expr<'tcx>, comment_pos: BytePos, ) -> Option { - if cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, ref node)| { + if cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, ref node)| { matches!( node, Node::Block(Block { @@ -604,10 +604,9 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span fn get_body_search_span(cx: &LateContext<'_>) -> Option { let body = cx.enclosing_body?; - let map = cx.tcx.hir(); let mut span = cx.tcx.hir_body(body).value.span; let mut maybe_global_var = false; - for (_, node) in map.parent_iter(body.hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(body.hir_id) { match node { Node::Expr(e) => span = e.span, Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::LetStmt(_) => (), diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index e65123b8a949..0687fc319af6 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -224,7 +224,7 @@ fn is_unreachable_or_panic(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { return false; }; if is_panic(cx, macro_call.def_id) { - return !cx.tcx.hir().is_inside_const_context(expr.hir_id); + return !cx.tcx.hir_is_inside_const_context(expr.hir_id); } matches!(cx.tcx.item_name(macro_call.def_id).as_str(), "unreachable") } diff --git a/clippy_lints/src/unused_peekable.rs b/clippy_lints/src/unused_peekable.rs index 0f9b05c84d4b..7487e273caa7 100644 --- a/clippy_lints/src/unused_peekable.rs +++ b/clippy_lints/src/unused_peekable.rs @@ -118,7 +118,7 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> { fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> ControlFlow<()> { if path_to_local_id(ex, self.expected_hir_id) { - for (_, node) in self.cx.tcx.hir().parent_iter(ex.hir_id) { + for (_, node) in self.cx.tcx.hir_parent_iter(ex.hir_id) { match node { Node::Expr(expr) => { match expr.kind { diff --git a/clippy_lints/src/unused_self.rs b/clippy_lints/src/unused_self.rs index d8305a628290..2c6c75693166 100644 --- a/clippy_lints/src/unused_self.rs +++ b/clippy_lints/src/unused_self.rs @@ -56,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { if impl_item.span.from_expansion() { return; } - let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; + let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let parent_item = cx.tcx.hir().expect_item(parent); let assoc_item = cx.tcx.associated_item(impl_item.owner_id); let contains_todo = |cx, body: &'_ Body<'_>| -> bool { diff --git a/clippy_lints/src/zero_sized_map_values.rs b/clippy_lints/src/zero_sized_map_values.rs index 1221abec1abf..4c9a7f0e16de 100644 --- a/clippy_lints/src/zero_sized_map_values.rs +++ b/clippy_lints/src/zero_sized_map_values.rs @@ -73,8 +73,8 @@ impl LateLintPass<'_> for ZeroSizedMapValues { } fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool { - let parent_id = cx.tcx.hir().get_parent_item(hir_id); - let second_parent_id = cx.tcx.hir().get_parent_item(parent_id.into()).def_id; + let parent_id = cx.tcx.hir_get_parent_item(hir_id); + let second_parent_id = cx.tcx.hir_get_parent_item(parent_id.into()).def_id; if let Node::Item(item) = cx.tcx.hir_node_by_def_id(second_parent_id) { if let ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = item.kind { return true; diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs index 6bb876322f24..c4d00002292c 100644 --- a/clippy_utils/src/higher.rs +++ b/clippy_utils/src/higher.rs @@ -117,7 +117,7 @@ impl<'hir> IfLet<'hir> { if_else, ) = expr.kind { - let mut iter = cx.tcx.hir().parent_iter(expr.hir_id); + let mut iter = cx.tcx.hir_parent_iter(expr.hir_id); if let Some((_, Node::Block(Block { stmts: [], .. }))) = iter.next() { if let Some(( _, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 15e395731ade..40ddd75b7fad 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -212,7 +212,7 @@ pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option< /// /// e.g. returns true for `x` in `fn f(x: usize) { .. }` and `let x = 1;` but false for `let x;` pub fn local_is_initialized(cx: &LateContext<'_>, local: HirId) -> bool { - for (_, node) in cx.tcx.hir().parent_iter(local) { + for (_, node) in cx.tcx.hir_parent_iter(local) { match node { Node::Pat(..) | Node::PatField(..) => {}, Node::LetStmt(let_stmt) => return let_stmt.init.is_some(), @@ -227,7 +227,7 @@ pub fn local_is_initialized(cx: &LateContext<'_>, local: HirId) -> bool { /// /// The current context is determined based on the current body which is set before calling a lint's /// entry point (any function on `LateLintPass`). If you need to check in a different context use -/// `tcx.hir().is_inside_const_context(_)`. +/// `tcx.hir_is_inside_const_context(_)`. /// /// Do not call this unless the `LateContext` has an enclosing body. For release build this case /// will safely return `false`, but debug builds will ICE. Note that `check_expr`, `check_block`, @@ -806,7 +806,7 @@ pub fn get_trait_def_id(tcx: TyCtxt<'_>, path: &[&str]) -> Option { pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, def_id: LocalDefId) -> Option<&'tcx TraitRef<'tcx>> { // Get the implemented trait for the current function let hir_id = cx.tcx.local_def_id_to_hir_id(def_id); - let parent_impl = cx.tcx.hir().get_parent_item(hir_id); + let parent_impl = cx.tcx.hir_get_parent_item(hir_id); if parent_impl != hir::CRATE_OWNER_ID && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_impl.def_id) && let ItemKind::Impl(impl_) = &item.kind @@ -1117,7 +1117,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind { let mut capture = CaptureKind::Value; let mut capture_expr_ty = e; - for (parent_id, parent) in cx.tcx.hir().parent_iter(e.hir_id) { + for (parent_id, parent) in cx.tcx.hir_parent_iter(e.hir_id) { if let [ Adjustment { kind: Adjust::Deref(_) | Adjust::Borrow(AutoBorrow::Ref(..)), @@ -1336,13 +1336,13 @@ pub fn is_entrypoint_fn(cx: &LateContext<'_>, def_id: DefId) -> bool { /// Returns `true` if the expression is in the program's `#[panic_handler]`. pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - let parent = cx.tcx.hir().get_parent_item(e.hir_id); + let parent = cx.tcx.hir_get_parent_item(e.hir_id); Some(parent.to_def_id()) == cx.tcx.lang_items().panic_impl() } /// Gets the name of the item the expression is in, if available. pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { - let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id).def_id; + let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id; match cx.tcx.hir_node_by_def_id(parent_id) { Node::Item(Item { ident, .. }) | Node::TraitItem(TraitItem { ident, .. }) @@ -1407,9 +1407,9 @@ pub fn get_parent_expr_for_hir<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> O /// Gets the enclosing block, if any. pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Block<'tcx>> { - let map = &cx.tcx.hir(); - let enclosing_node = map - .get_enclosing_scope(hir_id) + let enclosing_node = cx + .tcx + .hir_get_enclosing_scope(hir_id) .map(|enclosing_id| cx.tcx.hir_node(enclosing_id)); enclosing_node.and_then(|node| match node { Node::Block(block) => Some(block), @@ -1433,7 +1433,7 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>( cx: &LateContext<'tcx>, expr: &Expr<'_>, ) -> Option<&'tcx Expr<'tcx>> { - for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(expr.hir_id) { match node { Node::Expr(e) => match e.kind { ExprKind::Closure { .. } @@ -1453,7 +1453,7 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>( /// Gets the parent node if it's an impl block. pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> { - match tcx.hir().parent_iter(id).next() { + match tcx.hir_parent_iter(id).next() { Some(( _, Node::Item(Item { @@ -1531,7 +1531,7 @@ pub fn peel_blocks_with_stmt<'a>(mut expr: &'a Expr<'a>) -> &'a Expr<'a> { /// Checks if the given expression is the else clause of either an `if` or `if let` expression. pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { - let mut iter = tcx.hir().parent_iter(expr.hir_id); + let mut iter = tcx.hir_parent_iter(expr.hir_id); match iter.next() { Some(( _, @@ -1548,7 +1548,7 @@ pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { /// returns `true` for both the `init` and the `else` part pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { let mut child_id = expr.hir_id; - for (parent_id, node) in tcx.hir().parent_iter(child_id) { + for (parent_id, node) in tcx.hir_parent_iter(child_id) { if let Node::LetStmt(LetStmt { init: Some(init), els: Some(els), @@ -1568,7 +1568,7 @@ pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { /// Checks if the given expression is the else clause of a `let else` expression pub fn is_else_clause_in_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { let mut child_id = expr.hir_id; - for (parent_id, node) in tcx.hir().parent_iter(child_id) { + for (parent_id, node) in tcx.hir_parent_iter(child_id) { if let Node::LetStmt(LetStmt { els: Some(els), .. }) = node && els.hir_id == child_id { @@ -1961,7 +1961,7 @@ pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool return true; } prev_enclosing_node = Some(enclosing_node); - enclosing_node = map.get_parent_item(enclosing_node).into(); + enclosing_node = tcx.hir_get_parent_item(enclosing_node).into(); } false @@ -1970,8 +1970,8 @@ pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool /// Checks if the given HIR node is inside an `impl` block with the `automatically_derived` /// attribute. pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.hir() - .parent_owner_iter(id) + tcx + .hir_parent_owner_iter(id) .filter(|(_, node)| matches!(node, OwnerNode::Item(item) if matches!(item.kind, ItemKind::Impl(_)))) .any(|(id, _)| { has_attr( @@ -2202,7 +2202,7 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool /// Returns both the node and the `HirId` of the closest child node. pub fn get_expr_use_or_unification_node<'tcx>(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<(Node<'tcx>, HirId)> { let mut child_id = expr.hir_id; - let mut iter = tcx.hir().parent_iter(child_id); + let mut iter = tcx.hir_parent_iter(child_id); loop { match iter.next() { None => break None, @@ -2581,7 +2581,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool { with_test_item_names(tcx, tcx.parent_module(id), |names| { let node = tcx.hir_node(id); once((id, node)) - .chain(tcx.hir().parent_iter(id)) + .chain(tcx.hir_parent_iter(id)) // Since you can nest functions we need to collect all until we leave // function scope .any(|(_id, node)| { @@ -2617,8 +2617,8 @@ pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { /// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.hir() - .parent_id_iter(id) + tcx + .hir_parent_id_iter(id) .any(|parent_id| is_cfg_test(tcx, parent_id)) } @@ -2632,8 +2632,8 @@ pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { let hir = tcx.hir(); tcx.has_attr(def_id, sym::cfg) - || hir - .parent_iter(tcx.local_def_id_to_hir_id(def_id)) + || tcx + .hir_parent_iter(tcx.local_def_id_to_hir_id(def_id)) .flat_map(|(parent_id, _)| hir.attrs(parent_id)) .any(|attr| attr.has_name(sym::cfg)) } @@ -2653,8 +2653,7 @@ pub fn walk_to_expr_usage<'tcx, T>( e: &Expr<'tcx>, mut f: impl FnMut(HirId, Node<'tcx>, HirId) -> ControlFlow, ) -> Option, HirId)>> { - let map = cx.tcx.hir(); - let mut iter = map.parent_iter(e.hir_id); + let mut iter = cx.tcx.hir_parent_iter(e.hir_id); let mut child_id = e.hir_id; while let Some((parent_id, parent)) = iter.next() { @@ -2677,7 +2676,7 @@ pub fn walk_to_expr_usage<'tcx, T>( ExprKind::If(child, ..) | ExprKind::Match(child, ..) if child.hir_id != child_id => child_id = parent_id, ExprKind::Break(Destination { target_id: Ok(id), .. }, _) => { child_id = id; - iter = map.parent_iter(id); + iter = cx.tcx.hir_parent_iter(id); }, ExprKind::Block(..) | ExprKind::DropTemps(_) => child_id = parent_id, _ => return Some(ControlFlow::Continue((parent, child_id))), diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index 30fd48fc0605..9ce0fd8318f1 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -178,7 +178,7 @@ pub fn first_node_in_macro(cx: &LateContext<'_>, node: &impl HirNode) -> Option< // get the parent node, possibly skipping over a statement // if the parent is not found, it is sensible to return `Some(root)` let hir = cx.tcx.hir(); - let mut parent_iter = hir.parent_iter(node.hir_id()); + let mut parent_iter = cx.tcx.hir_parent_iter(node.hir_id()); let (parent_id, _) = match parent_iter.next() { None => return Some(ExpnId::root()), Some((_, Node::Stmt(_))) => match parent_iter.next() { From 373f809c1ddf0046300cad3e9161c17f13155675 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Thu, 20 Feb 2025 22:59:05 -0500 Subject: [PATCH 210/991] Add `todo!` & `unimplemented!` to format macros list For some reason, the `todo!` and `unimplemented!` macros were not included in the list of format-supporting macros list. Since they seem to behave exactly the same as all others like `write!` and `assert!`, adding them now. --- clippy_utils/src/macros.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index 30fd48fc0605..5a94dd06c454 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -30,6 +30,8 @@ const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[ sym::print_macro, sym::println_macro, sym::std_panic_macro, + sym::todo_macro, + sym::unimplemented_macro, sym::write_macro, sym::writeln_macro, ]; From 4ac7a5361be9739b729a0554a40013435b030dce Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 21 Feb 2025 09:42:12 +0100 Subject: [PATCH 211/991] Represent the capability instead of the lint name in msrv aliases `INTEGER_BITS` better represents the addition of the `BITS` value on the primitive integer types. --- clippy_lints/src/manual_bits.rs | 2 +- clippy_utils/src/msrvs.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/manual_bits.rs b/clippy_lints/src/manual_bits.rs index 17e25635ce10..4a34a334cf2b 100644 --- a/clippy_lints/src/manual_bits.rs +++ b/clippy_lints/src/manual_bits.rs @@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits { if let ExprKind::Binary(bin_op, left_expr, right_expr) = expr.kind && let BinOpKind::Mul = &bin_op.node && !expr.span.from_expansion() - && self.msrv.meets(msrvs::MANUAL_BITS) + && self.msrv.meets(msrvs::INTEGER_BITS) && let ctxt = expr.span.ctxt() && left_expr.span.ctxt() == ctxt && right_expr.span.ctxt() == ctxt diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 2e8bcfaa7af0..21e8076985e8 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -41,7 +41,7 @@ msrv_aliases! { 1,56,0 { CONST_FN_UNION } 1,55,0 { SEEK_REWIND } 1,54,0 { INTO_KEYS } - 1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR } + 1,53,0 { OR_PATTERNS, INTEGER_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR } 1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST } 1,51,0 { BORROW_AS_PTR, SEEK_FROM_CURRENT, UNSIGNED_ABS } 1,50,0 { BOOL_THEN, CLAMP, SLICE_FILL } From ad0810b73b0df9f727f2693391bdcb327dccf649 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 14 Feb 2025 16:09:10 +0000 Subject: [PATCH 212/991] Implement vpmaxq_u8 on aarch64 --- src/tools/miri/src/shims/aarch64.rs | 77 +++++++++++++++++++++++ src/tools/miri/src/shims/foreign_items.rs | 18 ++---- src/tools/miri/src/shims/mod.rs | 1 + 3 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 src/tools/miri/src/shims/aarch64.rs diff --git a/src/tools/miri/src/shims/aarch64.rs b/src/tools/miri/src/shims/aarch64.rs new file mode 100644 index 000000000000..4751064a1b92 --- /dev/null +++ b/src/tools/miri/src/shims/aarch64.rs @@ -0,0 +1,77 @@ +use rustc_middle::mir::BinOp; +use rustc_middle::ty::Ty; +use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; + +use crate::*; + +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { + fn emulate_aarch64_intrinsic( + &mut self, + link_name: Symbol, + abi: &FnAbi<'tcx, Ty<'tcx>>, + args: &[OpTy<'tcx>], + dest: &MPlaceTy<'tcx>, + ) -> InterpResult<'tcx, EmulateItemResult> { + let this = self.eval_context_mut(); + // Prefix should have already been checked. + let unprefixed_name = link_name.as_str().strip_prefix("llvm.aarch64.").unwrap(); + match unprefixed_name { + "isb" => { + let [arg] = this.check_shim(abi, Conv::C, link_name, args)?; + let arg = this.read_scalar(arg)?.to_i32()?; + match arg { + // SY ("full system scope") + 15 => { + this.yield_active_thread(); + } + _ => { + throw_unsup_format!("unsupported llvm.aarch64.isb argument {}", arg); + } + } + } + + // Used to implement the vpmaxq_u8 function. + // Folding maximum of adjacent pairs. + // https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_u8 + "neon.umaxp.v16i8" => { + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; + + let (left, left_len) = this.project_to_simd(left)?; + let (right, right_len) = this.project_to_simd(right)?; + let (dest, lane_count) = this.project_to_simd(dest)?; + assert_eq!(left_len, right_len); + assert_eq!(lane_count, left_len); + + for lane_idx in 0..lane_count { + let src = if lane_idx < (lane_count / 2) { &left } else { &right }; + #[allow(clippy::arithmetic_side_effects)] + let src_idx = lane_idx % (lane_count / 2); + + #[allow(clippy::arithmetic_side_effects)] + let lhs_lane = this.read_immediate(&this.project_index(src, src_idx * 2)?)?; + #[allow(clippy::arithmetic_side_effects)] + let rhs_lane = + this.read_immediate(&this.project_index(src, src_idx * 2 + 1)?)?; + + let res_lane = if this + .binary_op(BinOp::Gt, &lhs_lane, &rhs_lane)? + .to_scalar() + .to_bool()? + { + lhs_lane + } else { + rhs_lane + }; + + let dest = this.project_index(&dest, lane_idx)?; + this.write_immediate(*res_lane, &dest)?; + } + } + + _ => return interp_ok(EmulateItemResult::NotSupported), + } + interp_ok(EmulateItemResult::NeedsReturn) + } +} diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 97bfb04f1f47..011eeac87bc7 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -939,20 +939,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this, link_name, abi, args, dest, ); } - // FIXME: Move these to an `arm` submodule. - "llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => { - let [arg] = this.check_shim(abi, Conv::C, link_name, args)?; - let arg = this.read_scalar(arg)?.to_i32()?; - match arg { - // SY ("full system scope") - 15 => { - this.yield_active_thread(); - } - _ => { - throw_unsup_format!("unsupported llvm.aarch64.isb argument {}", arg); - } - } + name if name.starts_with("llvm.aarch64.") && this.tcx.sess.target.arch == "aarch64" => { + return shims::aarch64::EvalContextExt::emulate_aarch64_intrinsic( + this, link_name, abi, args, dest, + ); } + // FIXME: Move this to an `arm` submodule. "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => { let [arg] = this.check_shim(abi, Conv::C, link_name, args)?; let arg = this.read_scalar(arg)?.to_i32()?; diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs index 61681edcf762..b498551ace34 100644 --- a/src/tools/miri/src/shims/mod.rs +++ b/src/tools/miri/src/shims/mod.rs @@ -1,5 +1,6 @@ #![warn(clippy::arithmetic_side_effects)] +mod aarch64; mod alloc; mod backtrace; mod files; From f7ae9e11fc67f6bbbe06c095983c928225f39b88 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Feb 2025 12:19:21 +0100 Subject: [PATCH 213/991] adjust_abi: make fallback logic for ABIs a bit easier to read --- compiler/rustc_target/src/spec/mod.rs | 37 +++++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 65736770efb8..4c633bb9f519 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2862,20 +2862,35 @@ impl Target { // On Windows, `extern "system"` behaves like msvc's `__stdcall`. // `__stdcall` only applies on x86 and on non-variadic functions: // https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170 - System { unwind } if self.is_like_windows && self.arch == "x86" && !c_variadic => { - Stdcall { unwind } + System { unwind } => { + if self.is_like_windows && self.arch == "x86" && !c_variadic { + Stdcall { unwind } + } else { + C { unwind } + } + } + + EfiApi => { + if self.arch == "arm" { + Aapcs { unwind: false } + } else if self.arch == "x86_64" { + Win64 { unwind: false } + } else { + C { unwind: false } + } } - System { unwind } => C { unwind }, - EfiApi if self.arch == "arm" => Aapcs { unwind: false }, - EfiApi if self.arch == "x86_64" => Win64 { unwind: false }, - EfiApi => C { unwind: false }, // See commentary in `is_abi_supported`. - Stdcall { .. } | Thiscall { .. } if self.arch == "x86" => abi, - Stdcall { unwind } | Thiscall { unwind } => C { unwind }, - Fastcall { .. } if self.arch == "x86" => abi, - Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => abi, - Fastcall { unwind } | Vectorcall { unwind } => C { unwind }, + Stdcall { unwind } | Thiscall { unwind } | Fastcall { unwind } => { + if self.arch == "x86" { abi } else { C { unwind } } + } + Vectorcall { unwind } => { + if ["x86", "x86_64"].contains(&&*self.arch) { + abi + } else { + C { unwind } + } + } // The Windows x64 calling convention we use for `extern "Rust"` // From 123062bfd9ab2f017bbd18c93a325c8f707d3859 Mon Sep 17 00:00:00 2001 From: usamoi Date: Wed, 5 Feb 2025 20:09:50 +0800 Subject: [PATCH 214/991] pass optimization level to llvm-bitcode-linker --- compiler/rustc_codegen_ssa/src/back/linker.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 8900405c1b8f..818edaf66031 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1939,14 +1939,14 @@ impl<'a> Linker for LlbcLinker<'a> { } fn optimize(&mut self) { - match self.sess.opts.optimize { + self.link_arg(match self.sess.opts.optimize { OptLevel::No => "-O0", OptLevel::Less => "-O1", OptLevel::More => "-O2", OptLevel::Aggressive => "-O3", OptLevel::Size => "-Os", OptLevel::SizeMin => "-Oz", - }; + }); } fn full_relro(&mut self) {} From eb4720dc8e09476d99a846b5e9f78137038e62aa Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Feb 2025 12:46:19 +0000 Subject: [PATCH 215/991] Fix review comments --- src/tools/miri/src/shims/aarch64.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tools/miri/src/shims/aarch64.rs b/src/tools/miri/src/shims/aarch64.rs index 4751064a1b92..fc6e3b303d1c 100644 --- a/src/tools/miri/src/shims/aarch64.rs +++ b/src/tools/miri/src/shims/aarch64.rs @@ -46,15 +46,15 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { for lane_idx in 0..lane_count { let src = if lane_idx < (lane_count / 2) { &left } else { &right }; - #[allow(clippy::arithmetic_side_effects)] - let src_idx = lane_idx % (lane_count / 2); + let src_idx = lane_idx.strict_rem(lane_count / 2); - #[allow(clippy::arithmetic_side_effects)] - let lhs_lane = this.read_immediate(&this.project_index(src, src_idx * 2)?)?; - #[allow(clippy::arithmetic_side_effects)] - let rhs_lane = - this.read_immediate(&this.project_index(src, src_idx * 2 + 1)?)?; + let lhs_lane = + this.read_immediate(&this.project_index(src, src_idx.strict_mul(2))?)?; + let rhs_lane = this.read_immediate( + &this.project_index(src, src_idx.strict_mul(2).strict_add(1))?, + )?; + // Compute `if lhs > rhs { lhs } else { rhs }`, i.e., `max`. let res_lane = if this .binary_op(BinOp::Gt, &lhs_lane, &rhs_lane)? .to_scalar() From 629fa76c14c8022310a6e38887a35fd49599015f Mon Sep 17 00:00:00 2001 From: andylokandy Date: Fri, 21 Feb 2025 21:18:20 +0800 Subject: [PATCH 216/991] feat: update insta inline snapshot when clicks 'Update Test' runnable --- src/tools/rust-analyzer/crates/ide/src/lib.rs | 2 +- .../rust-analyzer/src/handlers/request.rs | 6 ++---- .../crates/rust-analyzer/src/lsp/to_proto.rs | 21 +++++++++---------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index 27a1a510b4fb..8ac1a96cc652 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -104,7 +104,7 @@ pub use crate::{ navigation_target::{NavigationTarget, TryToNav, UpmappingResult}, references::ReferenceSearchResult, rename::RenameError, - runnables::{Runnable, RunnableKind, TestId}, + runnables::{Runnable, RunnableKind, TestId, UpdateTest}, signature_help::SignatureHelp, static_index::{ StaticIndex, StaticIndexedFile, TokenId, TokenStaticData, VendoredLibrariesConfig, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 1b144d90732e..b91a5dbd4166 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -941,9 +941,7 @@ pub(crate) fn handle_runnables( let update_test = runnable.update_test; if let Some(mut runnable) = to_proto::runnable(&snap, runnable)? { - if let Some(runnable) = - to_proto::make_update_runnable(&runnable, &update_test.label(), &update_test.env()) - { + if let Some(runnable) = to_proto::make_update_runnable(&runnable, update_test) { res.push(runnable); } @@ -2158,7 +2156,7 @@ fn runnable_action_links( if hover_actions_config.update_test && client_commands_config.run_single { let label = update_test.label(); - if let Some(r) = to_proto::make_update_runnable(&r, &label, &update_test.env()) { + if let Some(r) = to_proto::make_update_runnable(&r, update_test) { let update_command = to_proto::command::run_single(&r, label.unwrap().as_str()); group.commands.push(to_command_link(update_command, r.label.clone())); } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index bff53cf98b7b..51ae85b1dbba 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -14,13 +14,13 @@ use ide::{ InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, LazyProperty, Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp, SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize, + UpdateTest, }; use ide_db::{assists, rust_doc::format_docs, FxHasher}; use itertools::Itertools; use paths::{Utf8Component, Utf8Prefix}; use semver::VersionReq; use serde_json::to_value; -use syntax::SmolStr; use vfs::AbsPath; use crate::{ @@ -1623,8 +1623,7 @@ pub(crate) fn code_lens( } if lens_config.update_test && client_commands_config.run_single { let label = update_test.label(); - let env = update_test.env(); - if let Some(r) = make_update_runnable(&r, &label, &env) { + if let Some(r) = make_update_runnable(&r, update_test) { let command = command::run_single(&r, label.unwrap().as_str()); acc.push(lsp_types::CodeLens { range: annotation_range, @@ -1871,22 +1870,22 @@ pub(crate) mod command { pub(crate) fn make_update_runnable( runnable: &lsp_ext::Runnable, - label: &Option, - env: &[(&str, &str)], + update_test: UpdateTest, ) -> Option { - if !matches!(runnable.args, lsp_ext::RunnableArgs::Cargo(_)) { - return None; - } - let label = label.as_ref()?; + let label = update_test.label()?; let mut runnable = runnable.clone(); runnable.label = format!("{} + {}", runnable.label, label); let lsp_ext::RunnableArgs::Cargo(r) = &mut runnable.args else { - unreachable!(); + return None; }; - r.environment.extend(env.iter().map(|(k, v)| (k.to_string(), v.to_string()))); + r.environment.extend(update_test.env().iter().map(|(k, v)| (k.to_string(), v.to_string()))); + + if update_test.insta { + r.cargo_args.insert(0, "insta".to_string()); + } Some(runnable) } From ec451661660193bba32765b7d08b1d3ba1d21383 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Feb 2025 13:30:17 +0000 Subject: [PATCH 217/991] Tell llvm-ar to not create a symbol table --- tests/run-make/staticlib-broken-bitcode/rmake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-make/staticlib-broken-bitcode/rmake.rs b/tests/run-make/staticlib-broken-bitcode/rmake.rs index f8c61d708191..17d17c1f0f5e 100644 --- a/tests/run-make/staticlib-broken-bitcode/rmake.rs +++ b/tests/run-make/staticlib-broken-bitcode/rmake.rs @@ -11,7 +11,7 @@ fn main() { rfs::write("archive/invalid_bitcode.o", &bitcode); llvm_ar() - .obj_to_thin_ar() + .arg("rcuS") // like obj_to_ar() except skips creating a symbol table .output_input( path("archive").join(static_lib_name("thin_archive")), "archive/invalid_bitcode.o", From 2b6ea13c53521231a98ec778526309dd6bb72f76 Mon Sep 17 00:00:00 2001 From: andylokandy Date: Fri, 21 Feb 2025 21:31:23 +0800 Subject: [PATCH 218/991] fix --- .../rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 51ae85b1dbba..446549c90700 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1884,7 +1884,7 @@ pub(crate) fn make_update_runnable( r.environment.extend(update_test.env().iter().map(|(k, v)| (k.to_string(), v.to_string()))); if update_test.insta { - r.cargo_args.insert(0, "insta".to_string()); + r.cargo_args.insert(0, "insta".to_owned()); } Some(runnable) From fc02cfd1c0237e0f927fb61aa6e5787ed1c15bc9 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Tue, 28 Jan 2025 15:17:44 +0100 Subject: [PATCH 219/991] Do not use CString in the examples of CStr. Fixes #83999. --- library/core/src/ffi/c_str.rs | 73 ++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 7180593edf0d..0e23fd5205bb 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -55,18 +55,15 @@ use crate::{fmt, ops, slice, str}; /// Passing a Rust-originating C string: /// /// ``` -/// use std::ffi::{CString, CStr}; +/// use std::ffi::CStr; /// use std::os::raw::c_char; /// /// fn work(data: &CStr) { -/// # /* Extern functions are awkward in doc comments - fake it instead -/// extern "C" { fn work_with(data: *const c_char); } -/// # */ unsafe extern "C" fn work_with(s: *const c_char) {} -/// +/// unsafe extern "C" fn work_with(s: *const c_char) {} /// unsafe { work_with(data.as_ptr()) } /// } /// -/// let s = CString::new("data data data data").expect("CString::new failed"); +/// let s = c"Hello world!"; /// work(&s); /// ``` /// @@ -384,13 +381,12 @@ impl CStr { /// # Examples /// /// ``` - /// use std::ffi::{CStr, CString}; + /// use std::ffi::CStr; /// - /// unsafe { - /// let cstring = CString::new("hello").expect("CString::new failed"); - /// let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul()); - /// assert_eq!(cstr, &*cstring); - /// } + /// let bytes = b"Hello world!\0"; + /// + /// let cstr = unsafe { CStr::from_bytes_with_nul_unchecked(bytes) }; + /// assert_eq!(cstr.to_bytes_with_nul(), bytes); /// ``` #[inline] #[must_use] @@ -449,38 +445,43 @@ impl CStr { /// behavior when `ptr` is used inside the `unsafe` block: /// /// ```no_run - /// # #![allow(unused_must_use)] /// # #![expect(dangling_pointers_from_temporaries)] - /// use std::ffi::CString; + /// use std::ffi::{CStr, CString}; /// - /// // Do not do this: - /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr(); - /// unsafe { - /// // `ptr` is dangling - /// *ptr; - /// } + /// // 💀 The meaning of this entire program is undefined, + /// // 💀 and nothing about its behavior is guaranteed, + /// // 💀 not even that its behavior resembles the code as written, + /// // 💀 just because it contains a single instance of undefined behavior! + /// + /// // 🚨 creates a dangling pointer to a temporary `CString` + /// // 🚨 that is deallocated at the end of the statement + /// let ptr = CString::new("Hi!".to_uppercase()).unwrap().as_ptr(); + /// + /// // without undefined behavior, you would expect that `ptr` equals: + /// dbg!(CStr::from_bytes_with_nul(b"HI!\0").unwrap()); + /// + /// // 🙏 Possibly the program behaved as expected so far, + /// // 🙏 and this just shows `ptr` is now garbage..., but + /// // 💀 this violates `CStr::from_ptr`'s safety contract + /// // 💀 leading to a dereference of a dangling pointer, + /// // 💀 which is immediate undefined behavior. + /// // 💀 *BOOM*, you're dead, you're entire program has no meaning. + /// dbg!(unsafe { CStr::from_ptr(ptr) }); /// ``` /// - /// This happens because the pointer returned by `as_ptr` does not carry any - /// lifetime information and the `CString` is deallocated immediately after - /// the `CString::new("Hello").expect("CString::new failed").as_ptr()` - /// expression is evaluated. + /// This happens because, the pointer returned by `as_ptr` does not carry any + /// lifetime information, and the `CString` is deallocated immediately after + /// the expression that it is part of has been evaluated. /// To fix the problem, bind the `CString` to a local variable: /// - /// ```no_run - /// # #![allow(unused_must_use)] - /// use std::ffi::CString; - /// - /// let hello = CString::new("Hello").expect("CString::new failed"); - /// let ptr = hello.as_ptr(); - /// unsafe { - /// // `ptr` is valid because `hello` is in scope - /// *ptr; - /// } /// ``` + /// use std::ffi::{CStr, CString}; /// - /// This way, the lifetime of the `CString` in `hello` encompasses - /// the lifetime of `ptr` and the `unsafe` block. + /// let c_str = CString::new("Hi!".to_uppercase()).unwrap(); + /// let ptr = c_str.as_ptr(); + /// + /// assert_eq!(unsafe { CStr::from_ptr(ptr) }, c"HI!"); + /// ``` #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] From d0dc36eccca3f058956702f2281110119bbbfd5c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Feb 2025 13:07:24 +0000 Subject: [PATCH 220/991] Add tests --- .../shims/aarch64/intrinsics-aarch64-neon.rs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs diff --git a/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs b/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs new file mode 100644 index 000000000000..84485dbad8c9 --- /dev/null +++ b/src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs @@ -0,0 +1,40 @@ +// We're testing aarch64 target specific features +//@only-target: aarch64 +//@compile-flags: -C target-feature=+neon + +use std::arch::aarch64::*; +use std::arch::is_aarch64_feature_detected; + +fn main() { + assert!(is_aarch64_feature_detected!("neon")); + + unsafe { + test_neon(); + } +} + +#[target_feature(enable = "neon")] +unsafe fn test_neon() { + // Adapted from library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs + unsafe fn test_vpmaxq_u8() { + let a = vld1q_u8([1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8].as_ptr()); + let b = vld1q_u8([0, 3, 2, 5, 4, 7, 6, 9, 0, 3, 2, 5, 4, 7, 6, 9].as_ptr()); + let e = [2, 4, 6, 8, 2, 4, 6, 8, 3, 5, 7, 9, 3, 5, 7, 9]; + let mut r = [0; 16]; + vst1q_u8(r.as_mut_ptr(), vpmaxq_u8(a, b)); + assert_eq!(r, e); + } + test_vpmaxq_u8(); + + unsafe fn test_vpmaxq_u8_is_unsigned() { + let a = vld1q_u8( + [255, 0, 253, 252, 251, 250, 249, 248, 255, 254, 253, 252, 251, 250, 249, 248].as_ptr(), + ); + let b = vld1q_u8([254, 3, 2, 5, 4, 7, 6, 9, 0, 3, 2, 5, 4, 7, 6, 9].as_ptr()); + let e = [255, 253, 251, 249, 255, 253, 251, 249, 254, 5, 7, 9, 3, 5, 7, 9]; + let mut r = [0; 16]; + vst1q_u8(r.as_mut_ptr(), vpmaxq_u8(a, b)); + assert_eq!(r, e); + } + test_vpmaxq_u8_is_unsigned(); +} From 6c6ffd27a2ddd928e144149fb66937f033bdd177 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Thu, 6 Feb 2025 23:42:03 +0900 Subject: [PATCH 221/991] extend `obfuscated_if_else` to support `then().unwrap_or_else()` and `then_some().unwrap_or_else()` --- clippy_lints/src/methods/mod.rs | 5 +- .../src/methods/obfuscated_if_else.rs | 18 +++++- tests/ui/obfuscated_if_else.fixed | 24 +++++++- tests/ui/obfuscated_if_else.rs | 24 +++++++- tests/ui/obfuscated_if_else.stderr | 60 ++++++++++++++----- 5 files changed, 111 insertions(+), 20 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 7f421d098270..f3c826e5c061 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -5398,7 +5398,7 @@ impl Methods { option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, &self.msrv); }, Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => { - obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method); + obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method, "unwrap_or"); }, _ => {}, } @@ -5417,6 +5417,9 @@ impl Methods { match method_call(recv) { Some(("map", recv, [map_arg], _, _)) if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {}, + Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => { + obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method, "unwrap_or_else"); + }, _ => { unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or"); }, diff --git a/clippy_lints/src/methods/obfuscated_if_else.rs b/clippy_lints/src/methods/obfuscated_if_else.rs index 3ef4906b3c9d..9a5ffdeaf4e8 100644 --- a/clippy_lints/src/methods/obfuscated_if_else.rs +++ b/clippy_lints/src/methods/obfuscated_if_else.rs @@ -16,6 +16,7 @@ pub(super) fn check<'tcx>( then_arg: &'tcx hir::Expr<'_>, unwrap_arg: &'tcx hir::Expr<'_>, then_method_name: &str, + unwrap_method_name: &str, ) { let recv_ty = cx.typeck_results().expr_ty(then_recv); @@ -32,14 +33,27 @@ pub(super) fn check<'tcx>( snippet_with_applicability(cx, body.value.span, "..", &mut applicability) }, "then_some" => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability), - _ => String::new().into(), + _ => return, + }; + + // FIXME: Add `unwrap_or_else` symbol + let els = match unwrap_method_name { + "unwrap_or" => snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability), + "unwrap_or_else" if let ExprKind::Closure(closure) = unwrap_arg.kind => { + let body = cx.tcx.hir_body(closure.body); + snippet_with_applicability(cx, body.value.span, "..", &mut applicability) + }, + "unwrap_or_else" if let ExprKind::Path(_) = unwrap_arg.kind => { + snippet_with_applicability(cx, unwrap_arg.span, "_", &mut applicability) + "()" + }, + _ => return, }; let sugg = format!( "if {} {{ {} }} else {{ {} }}", Sugg::hir_with_applicability(cx, then_recv, "..", &mut applicability), if_then, - snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability) + els ); // To be parsed as an expression, the `if { … } else { … }` as the left operand of a binary operator diff --git a/tests/ui/obfuscated_if_else.fixed b/tests/ui/obfuscated_if_else.fixed index b7a9cc836475..66f5070787b0 100644 --- a/tests/ui/obfuscated_if_else.fixed +++ b/tests/ui/obfuscated_if_else.fixed @@ -1,5 +1,10 @@ #![warn(clippy::obfuscated_if_else)] -#![allow(clippy::unnecessary_lazy_evaluations, clippy::unit_arg, clippy::unused_unit)] +#![allow( + clippy::unnecessary_lazy_evaluations, + clippy::unit_arg, + clippy::unused_unit, + clippy::unwrap_or_default +)] fn main() { if true { "a" } else { "b" }; @@ -24,6 +29,23 @@ fn main() { if true { () } else { a += 2 }; //~^ obfuscated_if_else + + let mut n = 1; + if true { n = 1 } else { n = 2 }; + //~^ obfuscated_if_else + if true { 1 } else { n * 2 }; + //~^ obfuscated_if_else + if true { n += 1 } else { () }; + //~^ obfuscated_if_else + + let _ = if true { 1 } else { n * 2 }; + //~^ obfuscated_if_else + + if true { 1 } else { Default::default() }; + //~^ obfuscated_if_else + + let partial = true.then_some(1); + partial.unwrap_or_else(|| n * 2); // not lint } fn issue11141() { diff --git a/tests/ui/obfuscated_if_else.rs b/tests/ui/obfuscated_if_else.rs index a6470fedd5c6..4efd740eb60b 100644 --- a/tests/ui/obfuscated_if_else.rs +++ b/tests/ui/obfuscated_if_else.rs @@ -1,5 +1,10 @@ #![warn(clippy::obfuscated_if_else)] -#![allow(clippy::unnecessary_lazy_evaluations, clippy::unit_arg, clippy::unused_unit)] +#![allow( + clippy::unnecessary_lazy_evaluations, + clippy::unit_arg, + clippy::unused_unit, + clippy::unwrap_or_default +)] fn main() { true.then_some("a").unwrap_or("b"); @@ -24,6 +29,23 @@ fn main() { true.then_some(()).unwrap_or(a += 2); //~^ obfuscated_if_else + + let mut n = 1; + true.then(|| n = 1).unwrap_or_else(|| n = 2); + //~^ obfuscated_if_else + true.then_some(1).unwrap_or_else(|| n * 2); + //~^ obfuscated_if_else + true.then_some(n += 1).unwrap_or_else(|| ()); + //~^ obfuscated_if_else + + let _ = true.then_some(1).unwrap_or_else(|| n * 2); + //~^ obfuscated_if_else + + true.then_some(1).unwrap_or_else(Default::default); + //~^ obfuscated_if_else + + let partial = true.then_some(1); + partial.unwrap_or_else(|| n * 2); // not lint } fn issue11141() { diff --git a/tests/ui/obfuscated_if_else.stderr b/tests/ui/obfuscated_if_else.stderr index 84caa848ece6..d676c2566957 100644 --- a/tests/ui/obfuscated_if_else.stderr +++ b/tests/ui/obfuscated_if_else.stderr @@ -1,5 +1,5 @@ error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:5:5 + --> tests/ui/obfuscated_if_else.rs:10:5 | LL | true.then_some("a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { "a" } else { "b" }` @@ -8,82 +8,112 @@ LL | true.then_some("a").unwrap_or("b"); = help: to override `-D warnings` add `#[allow(clippy::obfuscated_if_else)]` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:8:5 + --> tests/ui/obfuscated_if_else.rs:13:5 | LL | true.then(|| "a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:12:5 + --> tests/ui/obfuscated_if_else.rs:17:5 | LL | (a == 1).then_some("a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:15:5 + --> tests/ui/obfuscated_if_else.rs:20:5 | LL | (a == 1).then(|| "a").unwrap_or("b"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:22:5 + --> tests/ui/obfuscated_if_else.rs:27:5 | LL | true.then_some(a += 1).unwrap_or(()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { a += 1 } else { () }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:25:5 + --> tests/ui/obfuscated_if_else.rs:30:5 | LL | true.then_some(()).unwrap_or(a += 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { a += 2 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:31:13 + --> tests/ui/obfuscated_if_else.rs:34:5 + | +LL | true.then(|| n = 1).unwrap_or_else(|| n = 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { n = 1 } else { n = 2 }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:36:5 + | +LL | true.then_some(1).unwrap_or_else(|| n * 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { n * 2 }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:38:5 + | +LL | true.then_some(n += 1).unwrap_or_else(|| ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { n += 1 } else { () }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:41:13 + | +LL | let _ = true.then_some(1).unwrap_or_else(|| n * 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { n * 2 }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:44:5 + | +LL | true.then_some(1).unwrap_or_else(Default::default); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { Default::default() }` + +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:53:13 | LL | let _ = true.then_some(40).unwrap_or(17) | 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 40 } else { 17 })` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:35:13 + --> tests/ui/obfuscated_if_else.rs:57:13 | LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 30 } else { 17 })` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:35:48 + --> tests/ui/obfuscated_if_else.rs:57:48 | LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 2 } else { 3 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:35:81 + --> tests/ui/obfuscated_if_else.rs:57:81 | LL | let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 10 } else { 1 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:41:17 + --> tests/ui/obfuscated_if_else.rs:63:17 | LL | let _ = 2 | true.then_some(40).unwrap_or(17); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 40 } else { 17 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:45:13 + --> tests/ui/obfuscated_if_else.rs:67:13 | LL | let _ = true.then_some(42).unwrap_or(17) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 42 } else { 17 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:49:14 + --> tests/ui/obfuscated_if_else.rs:71:14 | LL | let _ = *true.then_some(&42).unwrap_or(&17); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` error: this method chain can be written more clearly with `if .. else ..` - --> tests/ui/obfuscated_if_else.rs:53:14 + --> tests/ui/obfuscated_if_else.rs:75:14 | LL | let _ = *true.then_some(&42).unwrap_or(&17) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` -error: aborting due to 14 previous errors +error: aborting due to 19 previous errors From 6366cca43958bedcfcc1b980061793e1f6664c43 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Sat, 18 Jan 2025 11:40:39 +0100 Subject: [PATCH 222/991] add `io_other_error` lint --- CHANGELOG.md | 1 + book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_dev/src/new_lint.rs | 5 +- clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/manual_div_ceil.rs | 2 +- clippy_lints/src/methods/io_other_error.rs | 37 +++++++++++++++ clippy_lints/src/methods/mod.rs | 25 ++++++++++ clippy_utils/src/msrvs.rs | 4 +- clippy_utils/src/paths.rs | 2 + tests/ui/format_args_unfixable.rs | 8 ++-- tests/ui/io_other_error.fixed | 55 ++++++++++++++++++++++ tests/ui/io_other_error.rs | 55 ++++++++++++++++++++++ tests/ui/io_other_error.stderr | 52 ++++++++++++++++++++ 14 files changed, 239 insertions(+), 10 deletions(-) create mode 100644 clippy_lints/src/methods/io_other_error.rs create mode 100644 tests/ui/io_other_error.fixed create mode 100644 tests/ui/io_other_error.rs create mode 100644 tests/ui/io_other_error.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 04a7eebb3592..be5e95e9744e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5726,6 +5726,7 @@ Released 2018-09-13 [`invalid_utf8_in_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_utf8_in_unchecked [`inverted_saturating_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#inverted_saturating_sub [`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters +[`io_other_error`]: https://rust-lang.github.io/rust-clippy/master/index.html#io_other_error [`is_digit_ascii_radix`]: https://rust-lang.github.io/rust-clippy/master/index.html#is_digit_ascii_radix [`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements [`items_after_test_module`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_test_module diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index fc3d005c0c94..74c2be3479ec 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -759,6 +759,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into) * [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none) * [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice) +* [`io_other_error`](https://rust-lang.github.io/rust-clippy/master/index.html#io_other_error) * [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map) * [`legacy_numeric_constants`](https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants) * [`lines_filter_map_ok`](https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 62f2f798a9cd..ff2a86182402 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -614,6 +614,7 @@ define_Conf! { from_over_into, if_then_some_else_none, index_refutable_slice, + io_other_error, iter_kv_map, legacy_numeric_constants, lines_filter_map_ok, diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index cc4b26867a20..cf6e44245660 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -1,11 +1,10 @@ use crate::utils::{clippy_project_root, clippy_version}; use indoc::{formatdoc, writedoc}; -use std::fmt; use std::fmt::Write as _; use std::fs::{self, OpenOptions}; use std::io::prelude::*; -use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; +use std::{fmt, io}; struct LintData<'a> { pass: &'a str, @@ -25,7 +24,7 @@ impl Context for io::Result { Ok(t) => Ok(t), Err(e) => { let message = format!("{}: {e}", text.as_ref()); - Err(io::Error::new(ErrorKind::Other, message)) + Err(io::Error::other(message)) }, } } diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 1cc1a81f8cee..9df9a62438ce 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -400,6 +400,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::methods::INEFFICIENT_TO_STRING_INFO, crate::methods::INSPECT_FOR_EACH_INFO, crate::methods::INTO_ITER_ON_REF_INFO, + crate::methods::IO_OTHER_ERROR_INFO, crate::methods::IS_DIGIT_ASCII_RADIX_INFO, crate::methods::ITERATOR_STEP_BY_ZERO_INFO, crate::methods::ITER_CLONED_COLLECT_INFO, diff --git a/clippy_lints/src/manual_div_ceil.rs b/clippy_lints/src/manual_div_ceil.rs index dd242c4168c6..04357cdd8f66 100644 --- a/clippy_lints/src/manual_div_ceil.rs +++ b/clippy_lints/src/manual_div_ceil.rs @@ -59,7 +59,7 @@ impl_lint_pass!(ManualDivCeil => [MANUAL_DIV_CEIL]); impl<'tcx> LateLintPass<'tcx> for ManualDivCeil { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { - if !self.msrv.meets(msrvs::DIV_CEIL) { + if !self.msrv.meets(msrvs::MANUAL_DIV_CEIL) { return; } diff --git a/clippy_lints/src/methods/io_other_error.rs b/clippy_lints/src/methods/io_other_error.rs new file mode 100644 index 000000000000..e0ce013ca7b7 --- /dev/null +++ b/clippy_lints/src/methods/io_other_error.rs @@ -0,0 +1,37 @@ +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{IO_ERROR_OTHER, Msrv}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, QPath}; +use rustc_lint::LateContext; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, path: &Expr<'_>, args: &[Expr<'_>], msrv: &Msrv) { + if let [error_kind, error] = args + && !expr.span.from_expansion() + && !error_kind.span.from_expansion() + && clippy_utils::is_expr_path_def_path(cx, path, &clippy_utils::paths::IO_ERROR_NEW) + && clippy_utils::is_expr_path_def_path( + cx, + clippy_utils::expr_or_init(cx, error_kind), + &clippy_utils::paths::IO_ERRORKIND_OTHER, + ) + && let ExprKind::Path(QPath::TypeRelative(_, new_segment)) = path.kind + && msrv.meets(IO_ERROR_OTHER) + { + span_lint_and_then( + cx, + super::IO_OTHER_ERROR, + expr.span, + "this can be `std::io::Error::other(_)`", + |diag| { + diag.multipart_suggestion_verbose( + "use `std::io::Error::other`", + vec![ + (new_segment.ident.span, "other".to_owned()), + (error_kind.span.until(error.span), String::new()), + ], + Applicability::MachineApplicable, + ); + }, + ); + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 7f421d098270..291ddc1ce171 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -36,6 +36,7 @@ mod implicit_clone; mod inefficient_to_string; mod inspect_for_each; mod into_iter_on_ref; +mod io_other_error; mod is_digit_ascii_radix; mod is_empty; mod iter_cloned_collect; @@ -4461,6 +4462,28 @@ declare_clippy_lint! { "unnecessary `iter().any()` on slices that can be replaced with `contains()`" } +declare_clippy_lint! { + /// This lint warns on calling `io::Error::new(..)` with a kind of + /// `io::ErrorKind::Other`. + /// + /// ### Why is this bad? + /// Since Rust 1.74, there's the `io::Error::other(_)` shortcut. + /// + /// ### Example + /// ```no_run + /// use std::io; + /// let _ = io::Error::new(io::ErrorKind::Other, "bad".to_string()); + /// ``` + /// Use instead: + /// ```no_run + /// let _ = std::io::Error::other("bad".to_string()); + /// ``` + #[clippy::version = "1.86.0"] + pub IO_OTHER_ERROR, + style, + "calling `std::io::Error::new(std::io::ErrorKind::Other, _)`" +} + #[expect(clippy::struct_excessive_bools)] pub struct Methods { avoid_breaking_exported_api: bool, @@ -4637,6 +4660,7 @@ impl_lint_pass!(Methods => [ RETURN_AND_THEN, UNBUFFERED_BYTES, MANUAL_CONTAINS, + IO_OTHER_ERROR, ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -4666,6 +4690,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { unnecessary_fallible_conversions::check_function(cx, expr, func); manual_c_str_literals::check(cx, expr, func, args, &self.msrv); useless_nonzero_new_unchecked::check(cx, expr, func, args, &self.msrv); + io_other_error::check(cx, expr, func, args, &self.msrv); }, ExprKind::MethodCall(method_call, receiver, args, _) => { let method_span = method_call.ident.span; diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 7b3aedb80f90..8c9832af0a19 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -27,8 +27,8 @@ msrv_aliases! { 1,77,0 { C_STR_LITERALS } 1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT } 1,75,0 { OPTION_AS_SLICE } - 1,74,0 { REPR_RUST } - 1,73,0 { DIV_CEIL } + 1,74,0 { REPR_RUST, IO_ERROR_OTHER } + 1,73,0 { MANUAL_DIV_CEIL } 1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE } 1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN } 1,68,0 { PATH_MAIN_SEPARATOR_STR } diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 2250d991bd8e..452bb4ce4c77 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -29,6 +29,8 @@ pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"] // Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items. pub const CHAR_IS_ASCII: [&str; 5] = ["core", "char", "methods", "", "is_ascii"]; +pub const IO_ERROR_NEW: [&str; 5] = ["std", "io", "error", "Error", "new"]; +pub const IO_ERRORKIND_OTHER: [&str; 5] = ["std", "io", "error", "ErrorKind", "Other"]; // Paths in clippy itself pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"]; diff --git a/tests/ui/format_args_unfixable.rs b/tests/ui/format_args_unfixable.rs index 08cd7dbe54f7..9e1d6a649c35 100644 --- a/tests/ui/format_args_unfixable.rs +++ b/tests/ui/format_args_unfixable.rs @@ -2,7 +2,7 @@ #![allow(unused)] #![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::uninlined_format_args)] -use std::io::{Error, ErrorKind, Write, stdout}; +use std::io::{Error, Write, stdout}; use std::ops::Deref; use std::panic::Location; @@ -20,7 +20,7 @@ macro_rules! my_other_macro { } fn main() { - let error = Error::new(ErrorKind::Other, "bad thing"); + let error = Error::other("bad thing"); let x = 'x'; println!("error: {}", format!("something failed at {}", Location::caller())); @@ -115,7 +115,7 @@ macro_rules! my_println2_args { } fn test2() { - let error = Error::new(ErrorKind::Other, "bad thing"); + let error = Error::other("bad thing"); // None of these should be linted without the config change my_println2!(true, "error: {}", format!("something failed at {}", Location::caller())); @@ -145,7 +145,7 @@ macro_rules! usr_println { } fn user_format() { - let error = Error::new(ErrorKind::Other, "bad thing"); + let error = Error::other("bad thing"); let x = 'x'; usr_println!(true, "error: {}", format!("boom at {}", Location::caller())); diff --git a/tests/ui/io_other_error.fixed b/tests/ui/io_other_error.fixed new file mode 100644 index 000000000000..0054c56fb628 --- /dev/null +++ b/tests/ui/io_other_error.fixed @@ -0,0 +1,55 @@ +#![warn(clippy::io_other_error)] +use std::fmt; + +#[derive(Debug)] +struct E; + +impl std::error::Error for E {} +impl fmt::Display for E { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("E") + } +} + +macro_rules! o { + {} => { std::io::ErrorKind::Other }; +} + +macro_rules! e { + { $kind:expr } => { std::io::Error::new($kind, E) }; +} + +fn main() { + let _err = std::io::Error::other(E); + //~^ ERROR: this can be `std::io::Error::other(_)` + let other = std::io::ErrorKind::Other; + let _err = std::io::Error::other(E); + //~^ ERROR: this can be `std::io::Error::other(_)` + + // not other + let _err = std::io::Error::new(std::io::ErrorKind::TimedOut, E); + + // from expansion + let _err = e!(other); + let _err = std::io::Error::new(o!(), E); + let _err = e!(o!()); + + paths::short(); + under_msrv(); +} + +mod paths { + use std::io::{self, Error, ErrorKind}; + + pub fn short() { + let _err = Error::other(super::E); + //~^ ERROR: this can be `std::io::Error::other(_)` + let _err = io::Error::other(super::E); + //~^ ERROR: this can be `std::io::Error::other(_)` + } +} + +#[clippy::msrv = "1.73"] +fn under_msrv() { + let _err = std::io::Error::new(std::io::ErrorKind::Other, E); +} diff --git a/tests/ui/io_other_error.rs b/tests/ui/io_other_error.rs new file mode 100644 index 000000000000..8529fb9a77f9 --- /dev/null +++ b/tests/ui/io_other_error.rs @@ -0,0 +1,55 @@ +#![warn(clippy::io_other_error)] +use std::fmt; + +#[derive(Debug)] +struct E; + +impl std::error::Error for E {} +impl fmt::Display for E { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("E") + } +} + +macro_rules! o { + {} => { std::io::ErrorKind::Other }; +} + +macro_rules! e { + { $kind:expr } => { std::io::Error::new($kind, E) }; +} + +fn main() { + let _err = std::io::Error::new(std::io::ErrorKind::Other, E); + //~^ ERROR: this can be `std::io::Error::other(_)` + let other = std::io::ErrorKind::Other; + let _err = std::io::Error::new(other, E); + //~^ ERROR: this can be `std::io::Error::other(_)` + + // not other + let _err = std::io::Error::new(std::io::ErrorKind::TimedOut, E); + + // from expansion + let _err = e!(other); + let _err = std::io::Error::new(o!(), E); + let _err = e!(o!()); + + paths::short(); + under_msrv(); +} + +mod paths { + use std::io::{self, Error, ErrorKind}; + + pub fn short() { + let _err = Error::new(ErrorKind::Other, super::E); + //~^ ERROR: this can be `std::io::Error::other(_)` + let _err = io::Error::new(io::ErrorKind::Other, super::E); + //~^ ERROR: this can be `std::io::Error::other(_)` + } +} + +#[clippy::msrv = "1.73"] +fn under_msrv() { + let _err = std::io::Error::new(std::io::ErrorKind::Other, E); +} diff --git a/tests/ui/io_other_error.stderr b/tests/ui/io_other_error.stderr new file mode 100644 index 000000000000..e79e05ecd406 --- /dev/null +++ b/tests/ui/io_other_error.stderr @@ -0,0 +1,52 @@ +error: this can be `std::io::Error::other(_)` + --> tests/ui/io_other_error.rs:23:16 + | +LL | let _err = std::io::Error::new(std::io::ErrorKind::Other, E); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::io-other-error` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::io_other_error)]` +help: use `std::io::Error::other` + | +LL - let _err = std::io::Error::new(std::io::ErrorKind::Other, E); +LL + let _err = std::io::Error::other(E); + | + +error: this can be `std::io::Error::other(_)` + --> tests/ui/io_other_error.rs:26:16 + | +LL | let _err = std::io::Error::new(other, E); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `std::io::Error::other` + | +LL - let _err = std::io::Error::new(other, E); +LL + let _err = std::io::Error::other(E); + | + +error: this can be `std::io::Error::other(_)` + --> tests/ui/io_other_error.rs:45:20 + | +LL | let _err = Error::new(ErrorKind::Other, super::E); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `std::io::Error::other` + | +LL - let _err = Error::new(ErrorKind::Other, super::E); +LL + let _err = Error::other(super::E); + | + +error: this can be `std::io::Error::other(_)` + --> tests/ui/io_other_error.rs:47:20 + | +LL | let _err = io::Error::new(io::ErrorKind::Other, super::E); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `std::io::Error::other` + | +LL - let _err = io::Error::new(io::ErrorKind::Other, super::E); +LL + let _err = io::Error::other(super::E); + | + +error: aborting due to 4 previous errors + From 9323ba54d3b35aeaf55a9596a29682c7173cf4d2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Feb 2025 03:04:13 +0000 Subject: [PATCH 223/991] Remove MaybeForgetReturn suggestion --- compiler/rustc_errors/src/lib.rs | 1 - .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 5 -- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 60 +------------------ .../src/error_reporting/traits/ambiguity.rs | 8 +-- ...suggest-add-return-to-coerce-ret-ty.stderr | 8 --- .../return/tail-expr-as-potential-return.rs | 1 - .../tail-expr-as-potential-return.stderr | 4 -- 7 files changed, 4 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6fce1fade266..9df306bb6354 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -599,7 +599,6 @@ pub enum StashKey { MaybeFruTypo, CallAssocMethod, AssociatedTypeSuggestion, - MaybeForgetReturn, /// Query cycle detected, stashing in favor of a better error. Cycle, UndeterminedMacroResolution, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2d7d80e39bc3..5bd190cda950 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -666,12 +666,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !errors.is_empty() { self.adjust_fulfillment_errors_for_expr_obligation(&mut errors); - let errors_causecode = errors - .iter() - .map(|e| (e.obligation.cause.span, e.root_obligation.cause.code().clone())) - .collect::>(); self.err_ctxt().report_fulfillment_errors(errors); - self.collect_unused_stmts_for_coerce_return_ty(errors_causecode); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index cf61659479b1..f1b60fabfefd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -3,9 +3,7 @@ use std::{fmt, iter, mem}; use itertools::Itertools; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::codes::*; -use rustc_errors::{ - Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, a_or_an, listify, pluralize, -}; +use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, a_or_an, listify, pluralize}; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; @@ -2167,62 +2165,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(super) fn collect_unused_stmts_for_coerce_return_ty( - &self, - errors_causecode: Vec<(Span, ObligationCauseCode<'tcx>)>, - ) { - for (span, code) in errors_causecode { - self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| { - if let Some(fn_sig) = self.body_fn_sig() - && let ObligationCauseCode::WhereClauseInExpr(_, _, binding_hir_id, ..) = code - && !fn_sig.output().is_unit() - { - let mut block_num = 0; - let mut found_semi = false; - for (hir_id, node) in self.tcx.hir_parent_iter(binding_hir_id) { - // Don't proceed into parent bodies - if hir_id.owner != binding_hir_id.owner { - break; - } - match node { - hir::Node::Stmt(stmt) => { - if let hir::StmtKind::Semi(expr) = stmt.kind { - let expr_ty = self.typeck_results.borrow().expr_ty(expr); - let return_ty = fn_sig.output(); - if !matches!(expr.kind, hir::ExprKind::Ret(..)) - && self.may_coerce(expr_ty, return_ty) - { - found_semi = true; - } - } - } - hir::Node::Block(_block) => { - if found_semi { - block_num += 1; - } - } - hir::Node::Item(item) => { - if let hir::ItemKind::Fn { .. } = item.kind { - break; - } - } - _ => {} - } - } - if block_num > 1 && found_semi { - err.span_suggestion_verbose( - // use the span of the *whole* expr - self.tcx.hir().span(binding_hir_id).shrink_to_lo(), - "you might have meant to return this to infer its type parameters", - "return ", - Applicability::MaybeIncorrect, - ); - } - } - }); - } - } - /// Given a vector of fulfillment errors, try to adjust the spans of the /// errors to more accurately point at the cause of the failure. /// diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index f15f1b78b528..d673e5672a00 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -1,8 +1,6 @@ use std::ops::ControlFlow; -use rustc_errors::{ - Applicability, Diag, E0283, E0284, E0790, MultiSpan, StashKey, struct_span_code_err, -}; +use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::LangItem; use rustc_hir::def::{DefKind, Res}; @@ -197,7 +195,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // be ignoring the fact that we don't KNOW the type works // out. Though even that would probably be harmless, given that // we're only talking about builtin traits, which are known to be - // inhabited. We used to check for `self.tcx.sess.has_errors()` to + // inhabited. We used to check for `self.tainted_by_errors()` to // avoid inundating the user with unnecessary errors, but we now // check upstream for type errors and don't add the obligations to // begin with in those cases. @@ -211,7 +209,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { TypeAnnotationNeeded::E0282, false, ); - return err.stash(span, StashKey::MaybeForgetReturn).unwrap(); + return err.emit(); } Some(e) => return e, } diff --git a/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr index 1fea73529a8a..c61ca699b0d3 100644 --- a/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr +++ b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr @@ -8,10 +8,6 @@ help: consider specifying the generic arguments | LL | Err::(MyError); | ++++++++++++++ -help: you might have meant to return this to infer its type parameters - | -LL | return Err(MyError); - | ++++++ error[E0282]: type annotations needed --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:14:9 @@ -23,10 +19,6 @@ help: consider specifying the generic arguments | LL | Ok::<(), E>(()); | +++++++++ -help: you might have meant to return this to infer its type parameters - | -LL | return Ok(()); - | ++++++ error[E0308]: mismatched types --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:21:20 diff --git a/tests/ui/return/tail-expr-as-potential-return.rs b/tests/ui/return/tail-expr-as-potential-return.rs index 11ecddb049b5..2e638f1897c2 100644 --- a/tests/ui/return/tail-expr-as-potential-return.rs +++ b/tests/ui/return/tail-expr-as-potential-return.rs @@ -60,7 +60,6 @@ fn method() -> Option { Receiver.generic(); //~^ ERROR type annotations needed //~| HELP consider specifying the generic argument - //~| HELP you might have meant to return this to infer its type parameters } None diff --git a/tests/ui/return/tail-expr-as-potential-return.stderr b/tests/ui/return/tail-expr-as-potential-return.stderr index 756de2b5a166..8105b2df3fea 100644 --- a/tests/ui/return/tail-expr-as-potential-return.stderr +++ b/tests/ui/return/tail-expr-as-potential-return.stderr @@ -57,10 +57,6 @@ help: consider specifying the generic argument | LL | Receiver.generic::(); | +++++ -help: you might have meant to return this to infer its type parameters - | -LL | return Receiver.generic(); - | ++++++ error: aborting due to 4 previous errors From e5dbcc2c16bd73f2b6bb81c452af66289c2a3902 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 17 Feb 2025 05:33:06 +0000 Subject: [PATCH 224/991] Make asm a named field --- clippy_lints/src/arbitrary_source_item_ordering.rs | 4 ++-- clippy_lints/src/missing_doc.rs | 2 +- clippy_lints/src/missing_inline.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/arbitrary_source_item_ordering.rs b/clippy_lints/src/arbitrary_source_item_ordering.rs index aff40fa846be..c0ae4960e10d 100644 --- a/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -362,7 +362,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { } } else if let ItemKind::ForeignMod { .. } = item.kind { continue; - } else if let ItemKind::GlobalAsm(_) = item.kind { + } else if let ItemKind::GlobalAsm { .. } = item.kind { continue; } else if let ItemKind::Use(path, use_kind) = item.kind { if path.segments.is_empty() { @@ -467,7 +467,7 @@ fn convert_module_item_kind(value: &ItemKind<'_>) -> SourceItemOrderingModuleIte ItemKind::Macro(..) => Macro, ItemKind::Mod(..) => Mod, ItemKind::ForeignMod { .. } => ForeignMod, - ItemKind::GlobalAsm(..) => GlobalAsm, + ItemKind::GlobalAsm { .. } => GlobalAsm, ItemKind::TyAlias(..) => TyAlias, ItemKind::Enum(..) => Enum, ItemKind::Struct(..) => Struct, diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 06e92985e664..47a9e17b3cfe 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -217,7 +217,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { | hir::ItemKind::Union(..) => {}, hir::ItemKind::ExternCrate(..) | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::GlobalAsm { .. } | hir::ItemKind::Impl { .. } | hir::ItemKind::Use(..) => note_prev_span_then_ret!(self.prev_span, it.span), } diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index fdc0930e957a..3cf1a80607e8 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::TraitAlias(..) - | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::GlobalAsm { .. } | hir::ItemKind::TyAlias(..) | hir::ItemKind::Union(..) | hir::ItemKind::ExternCrate(..) From ba8079d0dbb1c5237e04c207ac06640ae189a960 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 17 Feb 2025 16:09:46 +0000 Subject: [PATCH 225/991] Make a fake body to store typeck results for global_asm --- clippy_lints/src/operators/numeric_arithmetic.rs | 2 +- clippy_utils/src/hir_utils.rs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/operators/numeric_arithmetic.rs b/clippy_lints/src/operators/numeric_arithmetic.rs index cda99a362dca..c261fd9bd9cb 100644 --- a/clippy_lints/src/operators/numeric_arithmetic.rs +++ b/clippy_lints/src/operators/numeric_arithmetic.rs @@ -82,7 +82,7 @@ impl Context { } self.const_span = Some(body_span); }, - hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => (), + hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::GlobalAsm => (), } } diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 9ee30094d608..0ac675345ae0 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -968,7 +968,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(out_expr); } }, - InlineAsmOperand::Const { anon_const } | InlineAsmOperand::SymFn { anon_const } => { + InlineAsmOperand::SymFn { expr } => { + self.hash_expr(expr); + } + InlineAsmOperand::Const { anon_const } => { self.hash_body(anon_const.body); }, InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path), From 2ad3520d514d41eeb892652ea8da95323e1242ed Mon Sep 17 00:00:00 2001 From: yanglsh Date: Sat, 22 Feb 2025 19:04:25 +0800 Subject: [PATCH 226/991] fix: `too_long_first_doc_paragraph` suggests wrongly when first line too long --- clippy_lints/src/doc/too_long_first_doc_paragraph.rs | 4 ++++ tests/ui/too_long_first_doc_paragraph.rs | 7 +++++++ tests/ui/too_long_first_doc_paragraph.stderr | 11 ++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/clippy_lints/src/doc/too_long_first_doc_paragraph.rs index 1f89cab91480..8f9a54d50f88 100644 --- a/clippy_lints/src/doc/too_long_first_doc_paragraph.rs +++ b/clippy_lints/src/doc/too_long_first_doc_paragraph.rs @@ -51,7 +51,11 @@ pub(super) fn check( // We make this suggestion only if the first doc line ends with a punctuation // because it might just need to add an empty line with `///`. should_suggest_empty_doc = doc.ends_with('.') || doc.ends_with('!') || doc.ends_with('?'); + } else if spans.len() == 2 { + // We make this suggestion only if the second doc line is not empty. + should_suggest_empty_doc &= !doc.is_empty(); } + let len = doc.chars().count(); if len >= first_paragraph_len { break; diff --git a/tests/ui/too_long_first_doc_paragraph.rs b/tests/ui/too_long_first_doc_paragraph.rs index 2321e228866c..49420841c88c 100644 --- a/tests/ui/too_long_first_doc_paragraph.rs +++ b/tests/ui/too_long_first_doc_paragraph.rs @@ -61,6 +61,13 @@ pub union Union2 { /// gravida non lacinia at, rhoncus eu lacus. fn f() {} +#[rustfmt::skip] +/// Some function. This doc-string paragraph is too long. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. +//~^ too_long_first_doc_paragraph +/// +/// Here's a second paragraph. It would be preferable to put the details here. +pub fn issue_14274() {} + fn main() { // test code goes here } diff --git a/tests/ui/too_long_first_doc_paragraph.stderr b/tests/ui/too_long_first_doc_paragraph.stderr index 2d4abaa9d63c..287a2c1c3e44 100644 --- a/tests/ui/too_long_first_doc_paragraph.stderr +++ b/tests/ui/too_long_first_doc_paragraph.stderr @@ -39,5 +39,14 @@ LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris a LL | | /// gravida non lacinia at, rhoncus eu lacus. | |_^ -error: aborting due to 3 previous errors +error: first doc comment paragraph is too long + --> tests/ui/too_long_first_doc_paragraph.rs:65:1 + | +LL | / /// Some function. This doc-string paragraph is too long. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lore... +LL | | +LL | | /// +LL | | /// Here's a second paragraph. It would be preferable to put the details here. + | |_^ + +error: aborting due to 4 previous errors From a0c69fd320adc3dc74c6cc94199f87fe8509bcc0 Mon Sep 17 00:00:00 2001 From: Shirayama Kazatsuyu Date: Sat, 22 Feb 2025 22:26:19 +0900 Subject: [PATCH 227/991] Allow "package/feature" format feature flag --- .../rust-analyzer/crates/project-model/src/cargo_workspace.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index b5f4e43a115d..40ab8c53faeb 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -594,7 +594,9 @@ impl CargoWorkspace { .filter_map(|package| { let package = &self[package]; if package.is_member { - Some(package.features.keys().cloned()) + Some(package.features.keys().cloned().chain( + package.features.keys().map(|key| format!("{}/{key}", package.name)), + )) } else { None } From ef337a6599145766fc73b2896c6ff3e0fef65b0b Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 9 Feb 2025 06:08:59 +0000 Subject: [PATCH 228/991] Make `ptr_cast_add_auto_to_object` lint into hard error In Rust 1.81, we added a FCW lint (including linting in dependencies) against pointer casts that add an auto trait to dyn bounds. This was part of work making casts of pointers involving trait objects stricter which was needed to restabilize trait upcasting. We considered just making this a hard error at the time, but opted against it due to breakage found by crater. This breakage was mostly due to the `anymap` crate which has been a persistent problem for us. It's now a year later, and the fact that this is not yet a hard error is giving us pause about stabilizing arbitrary self types and `derive(CoercePointee)`. So let's now make a hard error of this. --- .../src/error_codes/E0804.md | 41 ++++++++++++++ compiler/rustc_error_codes/src/lib.rs | 1 + compiler/rustc_hir_typeck/messages.ftl | 9 ++-- compiler/rustc_hir_typeck/src/cast.rs | 26 ++++----- compiler/rustc_hir_typeck/src/errors.rs | 9 +++- compiler/rustc_lint/src/lib.rs | 5 ++ compiler/rustc_lint_defs/src/builtin.rs | 53 ------------------- tests/ui/cast/ptr-to-trait-obj-add-auto.rs | 14 ++--- .../ui/cast/ptr-to-trait-obj-add-auto.stderr | 44 ++++----------- tests/ui/lint/removed-lints/README.md | 4 ++ .../ptr_cast_add_auto_to_object.rs | 5 ++ .../ptr_cast_add_auto_to_object.stderr | 10 ++++ 12 files changed, 109 insertions(+), 112 deletions(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0804.md create mode 100644 tests/ui/lint/removed-lints/README.md create mode 100644 tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs create mode 100644 tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0804.md b/compiler/rustc_error_codes/src/error_codes/E0804.md new file mode 100644 index 000000000000..9a6937c0b52e --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0804.md @@ -0,0 +1,41 @@ +An auto trait cannot be added to the bounds of a `dyn Trait` type via +a pointer cast. + +Erroneous code example: + +```rust,edition2021,compile_fail,E0804 +let ptr: *const dyn core::any::Any = &(); +_ = ptr as *const (dyn core::any::Any + Send); +``` + +Adding an auto trait can make the vtable invalid, potentially causing +UB in safe code afterwards. For example: + +```rust,edition2021,no_run +use core::{mem::transmute, ptr::NonNull}; + +trait Trait { + fn f(&self) + where + Self: Send; +} + +impl Trait for NonNull<()> { + fn f(&self) { + unreachable!() + } +} + +fn main() { + let unsend: &dyn Trait = &NonNull::dangling(); + let bad: &(dyn Trait + Send) = unsafe { transmute(unsend) }; + // This crashes, since the vtable for `NonNull as dyn Trait` does + // not have an entry for `Trait::f`. + bad.f(); +} +``` + +To fix this error, you can use `transmute` rather than pointer casts, +but you must ensure that the vtable is valid for the pointer's type +before calling a method on the trait object or allowing other code to +do so. diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 098ca42be2b4..d53d5678832b 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -547,6 +547,7 @@ E0800: 0800, E0801: 0801, E0802: 0802, E0803: 0803, +E0804: 0804, ); ) } diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index a994b31aeb43..c9dea60ba9fe 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -154,10 +154,13 @@ hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function .suggestion = cast the value to `{$cast_ty}` .teach_help = certain types, like `{$ty}`, must be casted before passing them to a variadic function, because of arcane ABI rules dictated by the C standard -hir_typeck_ptr_cast_add_auto_to_object = adding {$traits_len -> - [1] an auto trait {$traits} +hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len -> + [1] auto trait {$traits} *[other] auto traits {$traits} -} to a trait object in a pointer cast may cause UB later on +} to dyn bound via pointer cast + .note = this could allow UB elsewhere + .help = use `transmute` if you're sure this is sound + .label = unsupported cast hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index f5f6ada12c3c..02a44d58a406 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -936,23 +936,19 @@ impl<'a, 'tcx> CastCheck<'tcx> { .collect::>(); if !added.is_empty() { - tcx.emit_node_span_lint( - lint::builtin::PTR_CAST_ADD_AUTO_TO_OBJECT, - self.expr.hir_id, - self.span, - errors::PtrCastAddAutoToObject { - traits_len: added.len(), - traits: { - let mut traits: Vec<_> = added - .into_iter() - .map(|trait_did| tcx.def_path_str(trait_did)) - .collect(); + tcx.dcx().emit_err(errors::PtrCastAddAutoToObject { + span: self.span, + traits_len: added.len(), + traits: { + let mut traits: Vec<_> = added + .into_iter() + .map(|trait_did| tcx.def_path_str(trait_did)) + .collect(); - traits.sort(); - traits.into() - }, + traits.sort(); + traits.into() }, - ) + }); } Ok(CastKind::PtrPtrCast) diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 1bf8aa4f78d4..f2ca7d222038 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -373,9 +373,14 @@ pub(crate) struct LossyProvenanceInt2Ptr<'tcx> { pub sugg: LossyProvenanceInt2PtrSuggestion, } -#[derive(LintDiagnostic)] -#[diag(hir_typeck_ptr_cast_add_auto_to_object)] +#[derive(Diagnostic)] +#[diag(hir_typeck_ptr_cast_add_auto_to_object, code = E0804)] +#[note] +#[help] pub(crate) struct PtrCastAddAutoToObject { + #[primary_span] + #[label] + pub span: Span, pub traits_len: usize, pub traits: DiagSymbolList, } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c8de5e877531..1dc487d3511c 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -601,6 +601,11 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, \ see for more information", ); + store.register_removed( + "ptr_cast_add_auto_to_object", + "converted into hard error, see issue #127323 \ + for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 10bf4ec77ed9..42e288976f9e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -80,7 +80,6 @@ declare_lint_pass! { PRIVATE_BOUNDS, PRIVATE_INTERFACES, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, - PTR_CAST_ADD_AUTO_TO_OBJECT, PTR_TO_INTEGER_TRANSMUTE_IN_CONSTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, @@ -4827,58 +4826,6 @@ declare_lint! { }; } -declare_lint! { - /// The `ptr_cast_add_auto_to_object` lint detects casts of raw pointers to trait - /// objects, which add auto traits. - /// - /// ### Example - /// - /// ```rust,edition2021,compile_fail - /// let ptr: *const dyn core::any::Any = &(); - /// _ = ptr as *const dyn core::any::Any + Send; - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Adding an auto trait can make the vtable invalid, potentially causing - /// UB in safe code afterwards. For example: - /// - /// ```ignore (causes a warning) - /// #![feature(arbitrary_self_types)] - /// - /// trait Trait { - /// fn f(self: *const Self) - /// where - /// Self: Send; - /// } - /// - /// impl Trait for *const () { - /// fn f(self: *const Self) { - /// unreachable!() - /// } - /// } - /// - /// fn main() { - /// let unsend: *const () = &(); - /// let unsend: *const dyn Trait = &unsend; - /// let send_bad: *const (dyn Trait + Send) = unsend as _; - /// send_bad.f(); // this crashes, since vtable for `*const ()` does not have an entry for `f` - /// } - /// ``` - /// - /// Generally you must ensure that vtable is right for the pointer's type, - /// before passing the pointer to safe code. - pub PTR_CAST_ADD_AUTO_TO_OBJECT, - Warn, - "detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #127323 ", - }; -} - declare_lint! { /// The `out_of_scope_macro_calls` lint detects `macro_rules` called when they are not in scope, /// above their definition, which may happen in key-value attributes. diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs index 46e72ea08779..3a1e667d03a4 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs @@ -1,18 +1,20 @@ -//@ check-pass - trait Trait<'a> {} fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) { x as _ - //~^ warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on - //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~^ ERROR cannot add auto trait `Send` to dyn bound via pointer cast + //~| NOTE unsupported cast + //~| NOTE this could allow UB elsewhere + //~| HELP use `transmute` if you're sure this is sound } // (to test diagnostic list formatting) fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) { x as _ - //~^ warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on - //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~^ ERROR cannot add auto traits `Send`, `Sync`, and `Unpin` to dyn bound via pointer cast + //~| NOTE unsupported cast + //~| NOTE this could allow UB elsewhere + //~| HELP use `transmute` if you're sure this is sound } fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr index e5ef8bf76b44..b64ca9b32bf5 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr @@ -1,43 +1,21 @@ -warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on - --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5 +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-add-auto.rs:4:5 | LL | x as _ - | ^^^^^^ + | ^^^^^^ unsupported cast | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #127323 - = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound -warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on +error[E0804]: cannot add auto traits `Send`, `Sync`, and `Unpin` to dyn bound via pointer cast --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 | LL | x as _ - | ^^^^^^ + | ^^^^^^ unsupported cast | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #127323 + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound -warning: 2 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on - --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5 - | -LL | x as _ - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #127323 - = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default - -Future breakage diagnostic: -warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on - --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 - | -LL | x as _ - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #127323 - = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0804`. diff --git a/tests/ui/lint/removed-lints/README.md b/tests/ui/lint/removed-lints/README.md new file mode 100644 index 000000000000..abe7ee04115c --- /dev/null +++ b/tests/ui/lint/removed-lints/README.md @@ -0,0 +1,4 @@ +# Removed lints + +This directory contains tests to confirm that lints that have been +removed do not cause errors and produce the appropriate warnings. diff --git a/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs new file mode 100644 index 000000000000..7fb635487ff2 --- /dev/null +++ b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs @@ -0,0 +1,5 @@ +//@ check-pass + +#![deny(ptr_cast_add_auto_to_object)] +//~^ WARN lint `ptr_cast_add_auto_to_object` has been removed +fn main() {} diff --git a/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr new file mode 100644 index 000000000000..36b5e847d807 --- /dev/null +++ b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr @@ -0,0 +1,10 @@ +warning: lint `ptr_cast_add_auto_to_object` has been removed: converted into hard error, see issue #127323 for more information + --> $DIR/ptr_cast_add_auto_to_object.rs:3:9 + | +LL | #![deny(ptr_cast_add_auto_to_object)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(renamed_and_removed_lints)]` on by default + +warning: 1 warning emitted + From 479116e6910e3b3329adcdebfdca2707f10e5880 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sun, 23 Feb 2025 04:34:02 +0000 Subject: [PATCH 229/991] return `impl fmt::Display` in more places instead of writing to strings --- src/librustdoc/html/format.rs | 16 +- src/librustdoc/html/render/context.rs | 5 +- src/librustdoc/html/render/mod.rs | 1474 ++++----- src/librustdoc/html/render/print_item.rs | 3311 ++++++++++---------- src/librustdoc/html/render/write_shared.rs | 36 +- 5 files changed, 2522 insertions(+), 2320 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 91b4b3ba1eba..522ef1af376c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -30,7 +30,7 @@ use super::url_parts_builder::{UrlPartsBuilder, estimate_item_path_byte_length}; use crate::clean::types::ExternalLocation; use crate::clean::utils::find_nearest_parent_module; use crate::clean::{self, ExternalCrate, PrimitiveType}; -use crate::display::Joined as _; +use crate::display::{Joined as _, MaybeDisplay as _}; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::html::escape::{Escape, EscapeBodyText}; @@ -178,12 +178,12 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( cx: &'a Context<'tcx>, indent: usize, ending: Ending, -) -> impl Display + 'a + Captures<'tcx> { - fmt::from_fn(move |f| { - if gens.where_predicates.is_empty() { - return Ok(()); - } +) -> Option> { + if gens.where_predicates.is_empty() { + return None; + } + Some(fmt::from_fn(move |f| { let where_preds = fmt::from_fn(|f| { gens.where_predicates .iter() @@ -246,7 +246,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( } }; write!(f, "{clause}") - }) + })) } impl clean::Lifetime { @@ -1179,7 +1179,7 @@ impl clean::Impl { self.print_type(&self.for_, f, use_absolute, cx)?; } - print_where_clause(&self.generics, cx, 0, Ending::Newline).fmt(f) + print_where_clause(&self.generics, cx, 0, Ending::Newline).maybe_display().fmt(f) }) } fn print_type<'a, 'tcx: 'a>( diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 146bdd340697..5f69e79f3ab1 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -237,8 +237,7 @@ impl<'tcx> Context<'tcx> { }; if !render_redirect_pages { - let mut page_buffer = String::new(); - print_item(self, it, &mut page_buffer); + let content = print_item(self, it); let page = layout::Page { css_class: tyname_s, root_path: &self.root_path(), @@ -254,7 +253,7 @@ impl<'tcx> Context<'tcx> { BufDisplay(|buf: &mut String| { print_sidebar(self, it, buf); }), - page_buffer, + content, &self.shared.style_files, ) } else { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 204631063a23..bd4af359404a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -38,7 +38,7 @@ mod type_layout; mod write_shared; use std::collections::VecDeque; -use std::fmt::{self, Write}; +use std::fmt::{self, Display as _, Write}; use std::iter::Peekable; use std::path::PathBuf; use std::{fs, str}; @@ -774,9 +774,7 @@ pub(crate) fn render_impls( let did = i.trait_did().unwrap(); let provided_trait_methods = i.inner_impl().provided_trait_methods(cx.tcx()); let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_trait_methods); - let mut buffer = String::new(); - render_impl( - &mut buffer, + let imp = render_impl( cx, i, containing_item, @@ -791,7 +789,7 @@ pub(crate) fn render_impls( toggle_open_by_default, }, ); - buffer + imp.to_string() }) .collect::>(); rendered_impls.sort(); @@ -879,20 +877,19 @@ enum AssocConstValue<'a> { None, } -fn assoc_const( - w: &mut String, - it: &clean::Item, - generics: &clean::Generics, - ty: &clean::Type, - value: AssocConstValue<'_>, - link: AssocItemLink<'_>, +fn assoc_const<'a, 'tcx>( + it: &'a clean::Item, + generics: &'a clean::Generics, + ty: &'a clean::Type, + value: AssocConstValue<'a>, + link: AssocItemLink<'a>, indent: usize, - cx: &Context<'_>, -) { + cx: &'a Context<'tcx>, +) -> impl fmt::Display + 'a + Captures<'tcx> { let tcx = cx.tcx(); - write_str( - w, - format_args!( + fmt::from_fn(move |w| { + write!( + w, "{indent}{vis}const {name}{generics}: {ty}", indent = " ".repeat(indent), vis = visibility_print_with_space(it, cx), @@ -900,67 +897,65 @@ fn assoc_const( name = it.name.as_ref().unwrap(), generics = generics.print(cx), ty = ty.print(cx), - ), - ); - if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value { - // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the - // hood which adds noisy underscores and a type suffix to number literals. - // This hurts readability in this context especially when more complex expressions - // are involved and it doesn't add much of value. - // Find a way to print constants here without all that jazz. - let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx)); - if match value { - AssocConstValue::TraitDefault(_) => true, // always show - AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show - AssocConstValue::None => unreachable!(), - } { - write_str(w, format_args!(" = {}", Escape(&repr))); + )?; + if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value { + // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the + // hood which adds noisy underscores and a type suffix to number literals. + // This hurts readability in this context especially when more complex expressions + // are involved and it doesn't add much of value. + // Find a way to print constants here without all that jazz. + let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx)); + if match value { + AssocConstValue::TraitDefault(_) => true, // always show + AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show + AssocConstValue::None => unreachable!(), + } { + write!(w, " = {}", Escape(&repr))?; + } } - } - write_str(w, format_args!("{}", print_where_clause(generics, cx, indent, Ending::NoNewline))); + write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline).maybe_display()) + }) } -fn assoc_type( - w: &mut String, - it: &clean::Item, - generics: &clean::Generics, - bounds: &[clean::GenericBound], - default: Option<&clean::Type>, - link: AssocItemLink<'_>, +fn assoc_type<'a, 'tcx>( + it: &'a clean::Item, + generics: &'a clean::Generics, + bounds: &'a [clean::GenericBound], + default: Option<&'a clean::Type>, + link: AssocItemLink<'a>, indent: usize, - cx: &Context<'_>, -) { - write_str( - w, - format_args!( + cx: &'a Context<'tcx>, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + write!( + w, "{indent}{vis}type {name}{generics}", indent = " ".repeat(indent), vis = visibility_print_with_space(it, cx), href = assoc_href_attr(it, link, cx).maybe_display(), name = it.name.as_ref().unwrap(), generics = generics.print(cx), - ), - ); - if !bounds.is_empty() { - write_str(w, format_args!(": {}", print_generic_bounds(bounds, cx))); - } - // Render the default before the where-clause which aligns with the new recommended style. See #89122. - if let Some(default) = default { - write_str(w, format_args!(" = {}", default.print(cx))); - } - write_str(w, format_args!("{}", print_where_clause(generics, cx, indent, Ending::NoNewline))); + )?; + if !bounds.is_empty() { + write!(w, ": {}", print_generic_bounds(bounds, cx))?; + } + // Render the default before the where-clause which aligns with the new recommended style. See #89122. + if let Some(default) = default { + write!(w, " = {}", default.print(cx))?; + } + write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline).maybe_display()) + }) } -fn assoc_method( - w: &mut String, - meth: &clean::Item, - g: &clean::Generics, - d: &clean::FnDecl, - link: AssocItemLink<'_>, +fn assoc_method<'a, 'tcx>( + meth: &'a clean::Item, + g: &'a clean::Generics, + d: &'a clean::FnDecl, + link: AssocItemLink<'a>, parent: ItemType, - cx: &Context<'_>, + cx: &'a Context<'tcx>, render_mode: RenderMode, -) { +) -> impl fmt::Display + 'a + Captures<'tcx> { let tcx = cx.tcx(); let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item"); let name = meth.name.as_ref().unwrap(); @@ -976,61 +971,53 @@ fn assoc_method( ), RenderMode::ForDeref { .. } => "", }; - let asyncness = header.asyncness.print_with_space(); - let safety = header.safety.print_with_space(); - let abi = print_abi_with_space(header.abi).to_string(); - let href = assoc_href_attr(meth, link, cx).maybe_display(); - // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`. - let generics_len = format!("{:#}", g.print(cx)).len(); - let mut header_len = "fn ".len() - + vis.len() - + defaultness.len() - + constness.len() - + asyncness.len() - + safety.len() - + abi.len() - + name.as_str().len() - + generics_len; + fmt::from_fn(move |w| { + let asyncness = header.asyncness.print_with_space(); + let safety = header.safety.print_with_space(); + let abi = print_abi_with_space(header.abi).to_string(); + let href = assoc_href_attr(meth, link, cx).maybe_display(); - let notable_traits = notable_traits_button(&d.output, cx).maybe_display(); + // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`. + let generics_len = format!("{:#}", g.print(cx)).len(); + let mut header_len = "fn ".len() + + vis.len() + + defaultness.len() + + constness.len() + + asyncness.len() + + safety.len() + + abi.len() + + name.as_str().len() + + generics_len; - let (indent, indent_str, end_newline) = if parent == ItemType::Trait { - header_len += 4; - let indent_str = " "; - write_str(w, format_args!("{}", render_attributes_in_pre(meth, indent_str, cx))); - (4, indent_str, Ending::NoNewline) - } else { - render_attributes_in_code(w, meth, cx); - (0, "", Ending::Newline) - }; - w.reserve(header_len + "{".len() + "".len()); - write_str( - w, - format_args!( + let notable_traits = notable_traits_button(&d.output, cx).maybe_display(); + + let (indent, indent_str, end_newline) = if parent == ItemType::Trait { + header_len += 4; + let indent_str = " "; + write!(w, "{}", render_attributes_in_pre(meth, indent_str, cx))?; + (4, indent_str, Ending::NoNewline) + } else { + render_attributes_in_code(w, meth, cx); + (0, "", Ending::Newline) + }; + write!( + w, "{indent}{vis}{defaultness}{constness}{asyncness}{safety}{abi}fn \ - {name}{generics}{decl}{notable_traits}{where_clause}", + {name}{generics}{decl}{notable_traits}{where_clause}", indent = indent_str, - vis = vis, - defaultness = defaultness, - constness = constness, - asyncness = asyncness, - safety = safety, - abi = abi, - href = href, - name = name, generics = g.print(cx), decl = d.full_print(header_len, indent, cx), - where_clause = print_where_clause(g, cx, indent, end_newline), - ), - ); + where_clause = print_where_clause(g, cx, indent, end_newline).maybe_display(), + ) + }) } /// Writes a span containing the versions at which an item became stable and/or const-stable. For /// example, if the item became stable at 1.0.0, and const-stable at 1.45.0, this function would /// write a span containing "1.0.0 (const: 1.45.0)". /// -/// Returns `true` if a stability annotation was rendered. +/// Returns `None` if there is no stability annotation to be rendered. /// /// Stability and const-stability are considered separately. If the item is unstable, no version /// will be written. If the item is const-unstable, "const: unstable" will be appended to the @@ -1041,11 +1028,10 @@ fn assoc_method( /// will include the const-stable version, but no stable version will be emitted, as a natural /// consequence of the above rules. fn render_stability_since_raw_with_extra( - w: &mut String, stable_version: Option, const_stability: Option, extra_class: &str, -) -> bool { +) -> Option { let mut title = String::new(); let mut stability = String::new(); @@ -1095,14 +1081,9 @@ fn render_stability_since_raw_with_extra( } } - if !stability.is_empty() { - write_str( - w, - format_args!(r#"{stability}"#), - ); - } - - !stability.is_empty() + (!stability.is_empty()).then_some(fmt::from_fn(move |w| { + write!(w, r#"{stability}"#) + })) } fn since_to_string(since: &StableSince) -> Option { @@ -1115,31 +1096,25 @@ fn since_to_string(since: &StableSince) -> Option { #[inline] fn render_stability_since_raw( - w: &mut String, ver: Option, const_stability: Option, -) -> bool { - render_stability_since_raw_with_extra(w, ver, const_stability, "") +) -> Option { + render_stability_since_raw_with_extra(ver, const_stability, "") } -fn render_assoc_item( - w: &mut String, - item: &clean::Item, - link: AssocItemLink<'_>, +fn render_assoc_item<'a, 'tcx>( + item: &'a clean::Item, + link: AssocItemLink<'a>, parent: ItemType, - cx: &Context<'_>, + cx: &'a Context<'tcx>, render_mode: RenderMode, -) { - match &item.kind { - clean::StrippedItem(..) => {} - clean::RequiredMethodItem(m) => { - assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode) - } - clean::MethodItem(m, _) => { - assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode) +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |f| match &item.kind { + clean::StrippedItem(..) => Ok(()), + clean::RequiredMethodItem(m) | clean::MethodItem(m, _) => { + assoc_method(item, &m.generics, &m.decl, link, parent, cx, render_mode).fmt(f) } clean::RequiredAssocConstItem(generics, ty) => assoc_const( - w, item, generics, ty, @@ -1147,9 +1122,9 @@ fn render_assoc_item( link, if parent == ItemType::Trait { 4 } else { 0 }, cx, - ), + ) + .fmt(f), clean::ProvidedAssocConstItem(ci) => assoc_const( - w, item, &ci.generics, &ci.type_, @@ -1157,9 +1132,9 @@ fn render_assoc_item( link, if parent == ItemType::Trait { 4 } else { 0 }, cx, - ), + ) + .fmt(f), clean::ImplAssocConstItem(ci) => assoc_const( - w, item, &ci.generics, &ci.type_, @@ -1167,9 +1142,9 @@ fn render_assoc_item( link, if parent == ItemType::Trait { 4 } else { 0 }, cx, - ), + ) + .fmt(f), clean::RequiredAssocTypeItem(ref generics, ref bounds) => assoc_type( - w, item, generics, bounds, @@ -1177,9 +1152,9 @@ fn render_assoc_item( link, if parent == ItemType::Trait { 4 } else { 0 }, cx, - ), + ) + .fmt(f), clean::AssocTypeItem(ref ty, ref bounds) => assoc_type( - w, item, &ty.generics, bounds, @@ -1187,9 +1162,10 @@ fn render_assoc_item( link, if parent == ItemType::Trait { 4 } else { 0 }, cx, - ), + ) + .fmt(f), _ => panic!("render_assoc_item called on non-associated-item"), - } + }) } // When an attribute is rendered inside a `

\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html index 485d44f97e16..e1d51dc0b71e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html @@ -45,20 +45,20 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
#[allow(dead_code)]
-#[rustfmt::skip]
+
#[allow(dead_code)]
+#[rustfmt::skip]
 #[proc_macros::identity]
-#[derive(Default)]
+#[derive(Default)]
 /// This is a doc comment
 // This is a normal comment
 /// This is a doc comment
-#[derive(Copy)]
+#[derive(Copy)]
 // This is another normal comment
 /// This is another doc comment
 // This is another normal comment
-#[derive(Copy, Unresolved)]
+#[derive(Copy, Unresolved)]
 // The reason for these being here is to test AttrIds
-enum Foo {
-    #[default]
-    Bar
-}
\ No newline at end of file +enum Foo { + #[default] + Bar +}
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html index c6eab90e42b0..af29af3f03ca 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html @@ -53,9 +53,9 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd }; } fn main() { - foo!(Foo); + foo!(Foo); mod module { - foo!(Bar); + foo!(Bar); fn func(_: y::Bar) { mod inner { struct Innerest<const C: usize> { field: [(); {C}] } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html index 96cdb532dd54..6d8f6b3c6e32 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html @@ -57,7 +57,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd const { const || {} } - id!( + id!( CONST_ITEM; CONST_PARAM; const { @@ -65,7 +65,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd }; &raw const (); const - ); + ); ().assoc_const_method(); } trait ConstTrait { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index 5b5c51a3631b..263e4545fb5a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html @@ -105,7 +105,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd /// let foo = Foo::new(); /// /// // calls bar on foo - /// assert!(foo.bar()); + /// assert!(foo.bar()); /// /// let bar = foo.bar || Foo::bar; /// @@ -157,7 +157,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd /// ``` /// macro_rules! noop { ($expr:expr) => { $expr }} -/// noop!(1); +/// noop!(1); /// ``` macro_rules! noop { ($expr:expr) => { @@ -177,7 +177,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd /// #[cfg_attr(feature = "alloc", doc = "```rust")] #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] -/// let _ = example(&alloc::vec![1, 2, 3]); +/// let _ = example(&alloc::vec![1, 2, 3]); /// ``` pub fn mix_and_match() {} diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index b5e950ffc23c..eb532a5639d4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html @@ -78,7 +78,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd use self::FooCopy::{self as BarCopy}; -#[derive(Copy)] +#[derive(Copy)] struct FooCopy { x: u32, } @@ -170,7 +170,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd impl<T> Option<T> { fn and<U>(self, other: Option<U>) -> Option<(T, U)> { match other { - None => unimplemented!(), + None => unimplemented!(), Nope => Nope, } } @@ -184,7 +184,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd async fn async_main() { let f1 = learn_and_sing(); let f2 = dance(); - futures::join!(f1, f2); + futures::join!(f1, f2); } fn use_foo_items() { @@ -196,7 +196,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let control_flow = foo::identity(foo::ControlFlow::Continue); if control_flow.should_die() { - foo::die!(); + foo::die!(); } } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html index 5fbed35192bb..1f9422161de4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html @@ -51,7 +51,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd fixture(r#" trait Foo { fn foo() { - println!("2 + 2 = {}", 4); + println!("2 + 2 = {}", 4); } }"# ); diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html index 06817af1b1f2..a846addba3f2 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html @@ -46,8 +46,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
fn main() {
-    template!(template);
+    template!(template);
 }
 
 #[proc_macros::issue_18089]
-fn template() {}
\ No newline at end of file +fn template() {} \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html index 2d3407dbcda0..4d4d03dba31c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html @@ -59,16 +59,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); -void!('static 'self 'unsafe) \ No newline at end of file +void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!('static 'self 'unsafe) \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html index f8eb5d068a81..a199a7ccb47e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html @@ -59,16 +59,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); -void!('static 'self 'unsafe) \ No newline at end of file +void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!('static 'self 'unsafe) \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html index f8eb5d068a81..a199a7ccb47e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html @@ -59,16 +59,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); -void!('static 'self 'unsafe) \ No newline at end of file +void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!('static 'self 'unsafe) \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html index fca840170696..58a95f199d0b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html @@ -59,16 +59,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); -void!('static 'self 'unsafe) \ No newline at end of file +void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!('static 'self 'unsafe) \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html index f640a5e6ca7f..f224435e9618 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html @@ -47,21 +47,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
use proc_macros::{mirror, identity, DeriveIdentity};
 
-mirror! {
+mirror! {
     {
         ,i32 :x pub
         ,i32 :y pub
     } Foo struct
-}
+}
 macro_rules! def_fn {
     ($($tt:tt)*) => {$($tt)*}
 }
 
-def_fn! {
+def_fn! {
     fn bar() -> u32 {
         100
     }
-}
+}
 
 macro_rules! dont_color_me_braces {
     () => {0}
@@ -100,16 +100,16 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     };
 }
 
-include!(concat!("foo/", "foo.rs"));
+include!(concat!("foo/", "foo.rs"));
 
 struct S<T>(T);
 fn main() {
     struct TestLocal;
     // regression test, TestLocal here used to not resolve
-    let _: S<id![TestLocal]>;
+    let _: S<id![TestLocal]>;
 
-    format_args!("Hello, {}!", (92,).0);
-    dont_color_me_braces!();
-    noop!(noop!(1));
+    format_args!("Hello, {}!", (92,).0);
+    dont_color_me_braces!();
+    noop!(noop!(1));
 }
 
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index 1794d7dbfe29..539c74f6b57e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html @@ -99,86 +99,86 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let a = b'\xFF'; - println!("Hello {{Hello}}"); + println!("Hello {{Hello}}"); // from https://doc.rust-lang.org/std/fmt/index.html - println!("Hello"); // => "Hello" - println!("Hello, {}!", "world"); // => "Hello, world!" - println!("The number is {}", 1); // => "The number is 1" - println!("{:?}", (3, 4)); // => "(3, 4)" - println!("{value}", value=4); // => "4" - println!("{} {}", 1, 2); // => "1 2" - println!("{:04}", 42); // => "0042" with leading zerosV - println!("{1} {} {0} {}", 1, 2); // => "2 1 1 2" - println!("{argument}", argument = "test"); // => "test" - println!("{name} {}", 1, name = 2); // => "2 1" - println!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" - println!("{{{}}}", 2); // => "{2}" - println!("Hello {:5}!", "x"); - println!("Hello {:1$}!", "x", 5); - println!("Hello {1:0$}!", 5, "x"); - println!("Hello {:width$}!", "x", width = 5); - println!("Hello {:<5}!", "x"); - println!("Hello {:-<5}!", "x"); - println!("Hello {:^5}!", "x"); - println!("Hello {:>5}!", "x"); - println!("Hello {:+}!", 5); - println!("{:#x}!", 27); - println!("Hello {:05}!", 5); - println!("Hello {:05}!", -5); - println!("{:#010x}!", 27); - println!("Hello {0} is {1:.5}", "x", 0.01); - println!("Hello {1} is {2:.0$}", 5, "x", 0.01); - println!("Hello {0} is {2:.1$}", "x", 5, 0.01); - println!("Hello {} is {:.*}", "x", 5, 0.01); - println!("Hello {} is {2:.*}", "x", 5, 0.01); - println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); - println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); - println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); - println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); + println!("Hello"); // => "Hello" + println!("Hello, {}!", "world"); // => "Hello, world!" + println!("The number is {}", 1); // => "The number is 1" + println!("{:?}", (3, 4)); // => "(3, 4)" + println!("{value}", value=4); // => "4" + println!("{} {}", 1, 2); // => "1 2" + println!("{:04}", 42); // => "0042" with leading zerosV + println!("{1} {} {0} {}", 1, 2); // => "2 1 1 2" + println!("{argument}", argument = "test"); // => "test" + println!("{name} {}", 1, name = 2); // => "2 1" + println!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" + println!("{{{}}}", 2); // => "{2}" + println!("Hello {:5}!", "x"); + println!("Hello {:1$}!", "x", 5); + println!("Hello {1:0$}!", 5, "x"); + println!("Hello {:width$}!", "x", width = 5); + println!("Hello {:<5}!", "x"); + println!("Hello {:-<5}!", "x"); + println!("Hello {:^5}!", "x"); + println!("Hello {:>5}!", "x"); + println!("Hello {:+}!", 5); + println!("{:#x}!", 27); + println!("Hello {:05}!", 5); + println!("Hello {:05}!", -5); + println!("{:#010x}!", 27); + println!("Hello {0} is {1:.5}", "x", 0.01); + println!("Hello {1} is {2:.0$}", 5, "x", 0.01); + println!("Hello {0} is {2:.1$}", "x", 5, 0.01); + println!("Hello {} is {:.*}", "x", 5, 0.01); + println!("Hello {} is {2:.*}", "x", 5, 0.01); + println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); + println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); + println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); + println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); let _ = "{}" let _ = "{{}}"; - println!("Hello {{}}"); - println!("{{ Hello"); - println!("Hello }}"); - println!("{{Hello}}"); - println!("{{ Hello }}"); - println!("{{Hello }}"); - println!("{{ Hello}}"); + println!("Hello {{}}"); + println!("{{ Hello"); + println!("Hello }}"); + println!("{{Hello}}"); + println!("{{ Hello }}"); + println!("{{Hello }}"); + println!("{{ Hello}}"); - println!(r"Hello, {}!", "world"); + println!(r"Hello, {}!", "world"); // escape sequences - println!("Hello\nWorld"); - println!("\u{48}\x65\x6C\x6C\x6F World"); + println!("Hello\nWorld"); + println!("\u{48}\x65\x6C\x6C\x6F World"); let _ = "\x28\x28\x00\x63\xFF\u{FF}\n"; // invalid non-UTF8 escape sequences let _ = b"\x28\x28\x00\x63\xFF\u{FF}\n"; // valid bytes, invalid unicodes let _ = c"\u{FF}\xFF"; // valid bytes, valid unicodes let backslash = r"\\"; - println!("{\x41}", A = 92); - println!("{ничоси}", ничоси = 92); + println!("{\x41}", A = 92); + println!("{ничоси}", ничоси = 92); - println!("{:x?} {} ", thingy, n2); - panic!("{}", 0); - panic!("more {}", 1); - assert!(true, "{}", 1); - assert!(true, "{} asdasd", 1); - toho!("{}fmt", 0); + println!("{:x?} {} ", thingy, n2); + panic!("{}", 0); + panic!("more {}", 1); + assert!(true, "{}", 1); + assert!(true, "{} asdasd", 1); + toho!("{}fmt", 0); let i: u64 = 3; let o: u64; - core::arch::asm!( + core::arch::asm!( "mov {0}, {1}", "add {0}, 5", out(reg) o, in(reg) i, - ); + ); const CONSTANT: () = (): let mut m = (); - format_args!(concat!("{}"), "{}"); - format_args!("{} {} {} {} {} {} {backslash} {CONSTANT} {m}", backslash, format_args!("{}", 0), foo, "bar", toho!(), backslash); - reuse_twice!("{backslash}"); + format_args!(concat!("{}"), "{}"); + format_args!("{} {} {} {} {} {} {backslash} {CONSTANT} {m}", backslash, format_args!("{}", 0), foo, "bar", toho!(), backslash); + reuse_twice!("{backslash}"); } \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html index d9beac308982..9a46d9f4025d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html @@ -92,13 +92,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let x = &5 as *const _ as *const usize; let u = Union { b: 0 }; - id! { + id! { unsafe { unsafe_deref!() } - }; + }; unsafe { - unsafe_deref!(); - id! { unsafe_deref!() }; + unsafe_deref!(); + id! { unsafe_deref!() }; // unsafe fn and method calls unsafe_fn(); From 497f14013c31211f4d5d4f7c61813babad94679e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 1 Mar 2025 17:44:12 +0100 Subject: [PATCH 509/991] Cleanup string handling in syntax highlighting --- .../crates/ide/src/syntax_highlighting.rs | 58 +++++++------------ .../ide/src/syntax_highlighting/highlight.rs | 2 +- .../parser/src/syntax_kind/generated.rs | 19 +----- .../rust-analyzer/crates/syntax/rust.ungram | 6 +- 4 files changed, 27 insertions(+), 58 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index 1ce42205d5aa..519133e3ad18 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -14,7 +14,7 @@ mod tests; use std::ops::ControlFlow; -use hir::{InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics}; +use hir::{HirFileIdExt, InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics}; use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind}; use span::EditionedFileId; use syntax::{ @@ -371,8 +371,7 @@ fn traverse( InFile::new(file_id.into(), element) }; - // string highlight injections, note this does not use the descended element as proc-macros - // can rewrite string literals which invalidates our indices + // string highlight injections if let (Some(original_token), Some(descended_token)) = (original_token, descended_element.value.as_token()) { @@ -390,6 +389,7 @@ fn traverse( } } + let edition = descended_element.file_id.edition(sema.db); let element = match descended_element.value { NodeOrToken::Node(name_like) => { let hl = highlight::name_like( @@ -398,7 +398,7 @@ fn traverse( &mut bindings_shadow_count, config.syntactic_name_ref_highlighting, name_like, - file_id.edition(), + edition, ); if hl.is_some() && !in_macro { // skip highlighting the contained token of our name-like node @@ -408,7 +408,7 @@ fn traverse( hl } NodeOrToken::Token(token) => { - highlight::token(sema, token, file_id.edition(), tt_level > 0).zip(Some(None)) + highlight::token(sema, token, edition, tt_level > 0).zip(Some(None)) } }; if let Some((mut highlight, binding_hash)) = element { @@ -448,10 +448,11 @@ fn string_injections( token: SyntaxToken, descended_token: &SyntaxToken, ) -> ControlFlow<()> { - if ast::String::can_cast(token.kind()) && ast::String::can_cast(descended_token.kind()) { - let string = ast::String::cast(token); - let string_to_highlight = ast::String::cast(descended_token.clone()); - if let Some((string, descended_string)) = string.zip(string_to_highlight) { + if !matches!(token.kind(), STRING | BYTE_STRING | BYTE | CHAR | C_STRING) { + return ControlFlow::Continue(()); + } + if let Some(string) = ast::String::cast(token.clone()) { + if let Some(descended_string) = ast::String::cast(descended_token.clone()) { if string.is_raw() && inject::ra_fixture(hl, sema, config, &string, &descended_string).is_some() { @@ -463,32 +464,17 @@ fn string_injections( highlight_escape_string(hl, &string); } } - } else if ast::ByteString::can_cast(token.kind()) - && ast::ByteString::can_cast(descended_token.kind()) - { - if let Some(byte_string) = ast::ByteString::cast(token) { - if !byte_string.is_raw() { - highlight_escape_string(hl, &byte_string); - } + } else if let Some(byte_string) = ast::ByteString::cast(token.clone()) { + if !byte_string.is_raw() { + highlight_escape_string(hl, &byte_string); } - } else if ast::CString::can_cast(token.kind()) && ast::CString::can_cast(descended_token.kind()) - { - if let Some(c_string) = ast::CString::cast(token) { - if !c_string.is_raw() { - highlight_escape_string(hl, &c_string); - } + } else if let Some(c_string) = ast::CString::cast(token.clone()) { + if !c_string.is_raw() { + highlight_escape_string(hl, &c_string); } - } else if ast::Char::can_cast(token.kind()) && ast::Char::can_cast(descended_token.kind()) { - let Some(char) = ast::Char::cast(token) else { - return ControlFlow::Break(()); - }; - + } else if let Some(char) = ast::Char::cast(token.clone()) { highlight_escape_char(hl, &char) - } else if ast::Byte::can_cast(token.kind()) && ast::Byte::can_cast(descended_token.kind()) { - let Some(byte) = ast::Byte::cast(token) else { - return ControlFlow::Break(()); - }; - + } else if let Some(byte) = ast::Byte::cast(token) { highlight_escape_byte(hl, &byte) } ControlFlow::Continue(()) @@ -536,10 +522,10 @@ fn descend_token( token.map(|token| match token.parent().and_then(ast::NameLike::cast) { // Remap the token into the wrapping single token nodes Some(parent) => match (token.kind(), parent.syntax().kind()) { - (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent), - (T![self] | T![super] | T![crate] | T![Self], NAME_REF) => NodeOrToken::Node(parent), - (INT_NUMBER, NAME_REF) => NodeOrToken::Node(parent), - (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent), + (T![ident] | T![self], NAME) + | (T![ident] | T![self] | T![super] | T![crate] | T![Self], NAME_REF) + | (INT_NUMBER, NAME_REF) + | (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent), _ => NodeOrToken::Token(token), }, None => NodeOrToken::Token(token), diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index 316fa5b6e9e5..127861a04bd8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs @@ -89,7 +89,7 @@ pub(super) fn name_like( Some(IdentClass::NameRefClass(NameRefClass::Definition(def, _))) => { highlight_def(sema, krate, def, edition) } - // FIXME: Fallback for 'static and '_, as we do not resolve these yet + // FIXME: Fallback for '_, as we do not resolve these yet _ => SymbolKind::LifetimeParam.into(), }, }; diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index 79900425a17c..e56e09eeb66b 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -147,9 +147,6 @@ pub enum SyntaxKind { C_STRING, FLOAT_NUMBER, INT_NUMBER, - RAW_BYTE_STRING, - RAW_C_STRING, - RAW_STRING, STRING, COMMENT, ERROR, @@ -343,9 +340,6 @@ impl SyntaxKind { | C_STRING | FLOAT_NUMBER | INT_NUMBER - | RAW_BYTE_STRING - | RAW_C_STRING - | RAW_STRING | STRING | ABI | ADT @@ -898,18 +892,7 @@ impl SyntaxKind { ) } pub fn is_literal(self) -> bool { - matches!( - self, - BYTE | BYTE_STRING - | CHAR - | C_STRING - | FLOAT_NUMBER - | INT_NUMBER - | RAW_BYTE_STRING - | RAW_C_STRING - | RAW_STRING - | STRING - ) + matches!(self, BYTE | BYTE_STRING | CHAR | C_STRING | FLOAT_NUMBER | INT_NUMBER | STRING) } pub fn from_keyword(ident: &str, edition: Edition) -> Option { let kw = match ident { diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index bbb8413cbc08..88d7beb897e0 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -438,9 +438,9 @@ MacroExpr = Literal = Attr* value:( '@int_number' | '@float_number' - | '@string' | '@raw_string' - | '@byte_string' | '@raw_byte_string' - | '@c_string' | '@raw_c_string' + | '@string' + | '@byte_string' + | '@c_string' | '@char' | '@byte' | 'true' | 'false' ) From 28a5eeb157329fd45c31d7c5567bc48ecfdd4aa9 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 1 Mar 2025 17:49:51 +0100 Subject: [PATCH 510/991] Fix `test_keyword_highlighting` test --- .../test_data/highlight_keywords_2015.html | 14 +++--- .../test_data/highlight_keywords_2018.html | 14 +++--- .../test_data/highlight_keywords_2021.html | 14 +++--- .../test_data/highlight_keywords_2024.html | 14 +++--- .../test_data/highlight_keywords_macros.html | 50 +++++++++++++++++++ .../ide/src/syntax_highlighting/tests.rs | 27 +++++++++- .../crates/test-utils/src/fixture.rs | 12 ++--- 7 files changed, 107 insertions(+), 38 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html index 4d4d03dba31c..c3377614d729 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html @@ -54,21 +54,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!(abstract become box do final macro override priv typeof unsized virtual yield); void!('static 'self 'unsafe) \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html index a199a7ccb47e..9b22500396bd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html @@ -54,21 +54,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!(abstract become box do final macro override priv typeof unsized virtual yield); void!('static 'self 'unsafe) \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html index a199a7ccb47e..9b22500396bd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html @@ -54,21 +54,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!(abstract become box do final macro override priv typeof unsized virtual yield); void!('static 'self 'unsafe) \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html index 58a95f199d0b..ac8353120e87 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html @@ -54,21 +54,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!(abstract become box do final macro override priv typeof unsized virtual yield); void!('static 'self 'unsafe) \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html new file mode 100644 index 000000000000..694e54d2fa8c --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html @@ -0,0 +1,50 @@ + + +
lib2015::void_2015!(try async await gen);
+lib2024::void_2024!(try async await gen);
+
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index 3775265f234d..e48ca86c46b5 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -386,7 +386,7 @@ mod __ { } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; @@ -411,6 +411,31 @@ void!('static 'self 'unsafe) } } +#[test] +fn test_keyword_macro_edition_highlighting() { + check_highlighting( + r#" +//- /main.rs crate:main edition:2018 deps:lib2015,lib2024 +lib2015::void_2015!(try async await gen); +lib2024::void_2024!(try async await gen); +//- /lib2015.rs crate:lib2015 edition:2015 +#[macro_export] +macro_rules! void_2015 { + ($($tt:tt)*) => {discard!($($tt:tt)*)} +} + +//- /lib2024.rs crate:lib2024 edition:2024 +#[macro_export] +macro_rules! void_2024 { + ($($tt:tt)*) => {discard!($($tt:tt)*)} +} + +"#, + expect_file![format!("./test_data/highlight_keywords_macros.html")], + false, + ); +} + #[test] fn test_string_highlighting() { // The format string detection is based on macro-expansion, diff --git a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs index daeb56c5835c..7240069753e8 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs @@ -218,16 +218,11 @@ impl FixtureWithProjectMeta { ); } - if line.starts_with("//-") { + if let Some(line) = line.strip_prefix("//-") { let meta = Self::parse_meta_line(line); res.push(meta); } else { - if line.starts_with("// ") - && line.contains(':') - && !line.contains("::") - && !line.contains('.') - && line.chars().all(|it| !it.is_uppercase()) - { + if matches!(line.strip_prefix("// "), Some(l) if l.trim().starts_with('/')) { panic!("looks like invalid metadata line: {line:?}"); } @@ -242,8 +237,7 @@ impl FixtureWithProjectMeta { //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo fn parse_meta_line(meta: &str) -> Fixture { - assert!(meta.starts_with("//-")); - let meta = meta["//-".len()..].trim(); + let meta = meta.trim(); let mut components = meta.split_ascii_whitespace(); let path = components.next().expect("fixture meta must start with a path").to_owned(); From 629baf217c77ca9f27f70e273f9840043eae6872 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 Feb 2025 11:53:16 +0100 Subject: [PATCH 511/991] Remove syntax editing from parenthesis computation --- .../src/handlers/apply_demorgan.rs | 65 +++++++------------ .../src/handlers/inline_local_variable.rs | 20 +----- .../src/handlers/remove_parentheses.rs | 2 +- .../src/handlers/unqualify_method_call.rs | 22 +------ .../crates/ide/src/inlay_hints/adjustment.rs | 11 ++-- .../crates/syntax/src/ast/prec.rs | 17 ++++- 6 files changed, 50 insertions(+), 87 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs index 83c049d4613b..77562c588e23 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -6,9 +6,16 @@ use ide_db::{ syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, }; use syntax::{ - ast::{self, syntax_factory::SyntaxFactory, AstNode, Expr::BinExpr, HasArgList}, + ast::{ + self, + prec::{precedence, ExprPrecedence}, + syntax_factory::SyntaxFactory, + AstNode, + Expr::BinExpr, + HasArgList, + }, syntax_editor::{Position, SyntaxEditor}, - SyntaxKind, SyntaxNode, T, + SyntaxKind, T, }; use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists}; @@ -52,9 +59,9 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti } let op = bin_expr.op_kind()?; - let inv_token = match op { - ast::BinaryOp::LogicOp(ast::LogicOp::And) => SyntaxKind::PIPE2, - ast::BinaryOp::LogicOp(ast::LogicOp::Or) => SyntaxKind::AMP2, + let (inv_token, prec) = match op { + ast::BinaryOp::LogicOp(ast::LogicOp::And) => (SyntaxKind::PIPE2, ExprPrecedence::LOr), + ast::BinaryOp::LogicOp(ast::LogicOp::Or) => (SyntaxKind::AMP2, ExprPrecedence::LAnd), _ => return None, }; @@ -65,33 +72,33 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti editor.replace(demorganed.op_token()?, make.token(inv_token)); let mut exprs = VecDeque::from([ - (bin_expr.lhs()?, demorganed.lhs()?), - (bin_expr.rhs()?, demorganed.rhs()?), + (bin_expr.lhs()?, demorganed.lhs()?, prec), + (bin_expr.rhs()?, demorganed.rhs()?, prec), ]); - while let Some((expr, dm)) = exprs.pop_front() { + while let Some((expr, demorganed, prec)) = exprs.pop_front() { if let BinExpr(bin_expr) = &expr { - if let BinExpr(cbin_expr) = &dm { + if let BinExpr(cbin_expr) = &demorganed { if op == bin_expr.op_kind()? { editor.replace(cbin_expr.op_token()?, make.token(inv_token)); - exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?)); - exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?)); + exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?, prec)); + exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?, prec)); } else { let mut inv = invert_boolean_expression(&make, expr); - if needs_parens_in_place_of(&inv, &dm.syntax().parent()?, &dm) { + if precedence(&inv).needs_parentheses_in(prec) { inv = make.expr_paren(inv).into(); } - editor.replace(dm.syntax(), inv.syntax()); + editor.replace(demorganed.syntax(), inv.syntax()); } } else { return None; } } else { - let mut inv = invert_boolean_expression(&make, dm.clone()); - if needs_parens_in_place_of(&inv, &dm.syntax().parent()?, &dm) { + let mut inv = invert_boolean_expression(&make, demorganed.clone()); + if precedence(&inv).needs_parentheses_in(prec) { inv = make.expr_paren(inv).into(); } - editor.replace(dm.syntax(), inv.syntax()); + editor.replace(demorganed.syntax(), inv.syntax()); } } @@ -121,7 +128,7 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti let parent = neg_expr.syntax().parent(); editor = builder.make_editor(neg_expr.syntax()); - if parent.is_some_and(|parent| demorganed.needs_parens_in(parent)) { + if parent.is_some_and(|parent| demorganed.needs_parens_in(&parent)) { cov_mark::hit!(demorgan_keep_parens_for_op_precedence2); editor.replace(neg_expr.syntax(), make.expr_paren(demorganed).syntax()); } else { @@ -271,30 +278,6 @@ fn add_bang_paren(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr { make.expr_prefix(T![!], make.expr_paren(expr).into()).into() } -fn needs_parens_in_place_of( - this: &ast::Expr, - parent: &SyntaxNode, - in_place_of: &ast::Expr, -) -> bool { - assert_eq!(Some(parent), in_place_of.syntax().parent().as_ref()); - - let child_idx = parent - .children() - .enumerate() - .find_map(|(i, it)| if &it == in_place_of.syntax() { Some(i) } else { None }) - .unwrap(); - let parent = parent.clone_subtree(); - let subtree_place = parent.children().nth(child_idx).unwrap(); - - let mut editor = SyntaxEditor::new(parent); - editor.replace(subtree_place, this.syntax()); - let edit = editor.finish(); - - let replaced = edit.new_root().children().nth(child_idx).unwrap(); - let replaced = ast::Expr::cast(replaced).unwrap(); - replaced.needs_parens_in(edit.new_root().clone()) -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs index 5d4fbfc10ab0..cc7bea5152b6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs @@ -5,11 +5,7 @@ use ide_db::{ EditionedFileId, RootDatabase, }; use syntax::{ - ast::{ - self, - prec::{precedence, ExprPrecedence}, - AstNode, AstToken, HasName, - }, + ast::{self, AstNode, AstToken, HasName}, SyntaxElement, TextRange, }; @@ -77,22 +73,12 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) } let usage_node = name_ref.syntax().ancestors().find(|it| ast::PathExpr::can_cast(it.kind())); - let usage_parent_option = - usage_node.and_then(|it| it.parent()).and_then(ast::Expr::cast); + let usage_parent_option = usage_node.and_then(|it| it.parent()); let usage_parent = match usage_parent_option { Some(u) => u, None => return Some((range, name_ref, false)), }; - let initializer = precedence(&initializer_expr); - let parent = precedence(&usage_parent); - Some(( - range, - name_ref, - parent != ExprPrecedence::Unambiguous - && initializer < parent - // initializer == ExprPrecedence::Prefix -> parent != ExprPrecedence::Jump - && (initializer != ExprPrecedence::Prefix || parent != ExprPrecedence::Jump), - )) + Some((range, name_ref, initializer_expr.needs_parens_in(&usage_parent))) }) .collect::>>()?; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs index 143d5e542428..e7beb23bf8e7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs @@ -34,7 +34,7 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) -> let expr = parens.expr()?; let parent = parens.syntax().parent()?; - if expr.needs_parens_in(parent) { + if expr.needs_parens_in(&parent) { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs index 0876246e90b1..baf4ddae2fbc 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs @@ -1,6 +1,6 @@ use ide_db::imports::insert_use::ImportScope; use syntax::{ - ast::{self, make, AstNode, HasArgList}, + ast::{self, prec::ExprPrecedence, AstNode, HasArgList}, TextRange, }; @@ -55,7 +55,7 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) TextRange::new(path.syntax().text_range().start(), l_paren.text_range().end()); // Parens around `expr` if needed - let parens = needs_parens_as_receiver(&first_arg).then(|| { + let parens = first_arg.precedence().needs_parentheses_in(ExprPrecedence::Postfix).then(|| { let range = first_arg.syntax().text_range(); (range.start(), range.end()) }); @@ -124,24 +124,6 @@ fn add_import( } } -fn needs_parens_as_receiver(expr: &ast::Expr) -> bool { - // Make `(expr).dummy()` - let dummy_call = make::expr_method_call( - make::expr_paren(expr.clone()), - make::name_ref("dummy"), - make::arg_list([]), - ); - - // Get the `expr` clone with the right parent back - // (unreachable!s are fine since we've just constructed the expression) - let ast::Expr::MethodCallExpr(call) = &dummy_call else { unreachable!() }; - let Some(receiver) = call.receiver() else { unreachable!() }; - let ast::Expr::ParenExpr(parens) = receiver else { unreachable!() }; - let Some(expr) = parens.expr() else { unreachable!() }; - - expr.needs_parens_in(dummy_call.syntax().clone()) -} - #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs index 6b2e41f42b6b..8522ef0a6d5f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs @@ -258,15 +258,12 @@ fn mode_and_needs_parens_for_adjustment_hints( fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, bool) { let prec = expr.precedence(); if postfix { - // postfix ops have higher precedence than any other operator, so we need to wrap - // any inner expression that is below - let needs_inner_parens = prec < ExprPrecedence::Postfix; + let needs_inner_parens = prec.needs_parentheses_in(ExprPrecedence::Postfix); // given we are the higher precedence, no parent expression will have stronger requirements let needs_outer_parens = false; (needs_outer_parens, needs_inner_parens) } else { - // We need to wrap all binary like things, thats everything below prefix except for jumps - let needs_inner_parens = prec < ExprPrecedence::Prefix && prec != ExprPrecedence::Jump; + let needs_inner_parens = prec.needs_parentheses_in(ExprPrecedence::Prefix); let parent = expr .syntax() .parent() @@ -278,8 +275,8 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, // if we have no parent, we don't need outer parens to disambiguate // otherwise anything with higher precedence than what we insert needs to wrap us - let needs_outer_parens = - parent.is_some_and(|parent_prec| parent_prec > ExprPrecedence::Prefix); + let needs_outer_parens = parent + .is_some_and(|parent_prec| ExprPrecedence::Prefix.needs_parentheses_in(parent_prec)); (needs_outer_parens, needs_inner_parens) } } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs index 2a47b3bea5b6..0c4da7629926 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs @@ -41,6 +41,21 @@ pub enum ExprPrecedence { Unambiguous, } +impl ExprPrecedence { + pub fn needs_parentheses_in(self, other: ExprPrecedence) -> bool { + match other { + ExprPrecedence::Unambiguous => false, + // postfix ops have higher precedence than any other operator, so we need to wrap + // any inner expression that is below + ExprPrecedence::Postfix => self < ExprPrecedence::Postfix, + // We need to wrap all binary like things, thats everything below prefix except for + // jumps (as those are prefix operations as well) + ExprPrecedence::Prefix => ExprPrecedence::Jump < self && self < ExprPrecedence::Prefix, + parent => self <= parent, + } + } +} + #[derive(PartialEq, Debug)] pub enum Fixity { /// The operator is left-associative @@ -137,7 +152,7 @@ impl Expr { // - https://github.com/rust-lang/rust/blob/b6852428a8ea9728369b64b9964cad8e258403d3/compiler/rustc_ast/src/util/parser.rs#L296 /// Returns `true` if `self` would need to be wrapped in parentheses given that its parent is `parent`. - pub fn needs_parens_in(&self, parent: SyntaxNode) -> bool { + pub fn needs_parens_in(&self, parent: &SyntaxNode) -> bool { match_ast! { match parent { ast::Expr(e) => self.needs_parens_in_expr(&e), From 6f7fd11474615975fe3f57cfdd9d639892e54e8d Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 2 Mar 2025 03:03:52 +0900 Subject: [PATCH 512/991] rustc_target: Add msync target feature and enable it on powerpcspe targets --- .../src/spec/targets/powerpc_unknown_linux_gnuspe.rs | 2 +- .../src/spec/targets/powerpc_unknown_linux_muslspe.rs | 1 + compiler/rustc_target/src/target_features.rs | 1 + tests/ui/check-cfg/target_feature.stderr | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs index 03bae9b59777..3c1d18e07771 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: "spe".into(), endian: Endian::Big, - features: "+secure-plt".into(), + features: "+secure-plt,+msync".into(), mcount: "_mcount".into(), ..base }, diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs index df4fd75b0bde..30d0d9cb60a7 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs @@ -26,6 +26,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: "spe".into(), endian: Endian::Big, + features: "+msync".into(), mcount: "_mcount".into(), ..base }, diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 65a85151befa..d05466bb4843 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -461,6 +461,7 @@ const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start ("altivec", Unstable(sym::powerpc_target_feature), &[]), + ("msync", Unstable(sym::powerpc_target_feature), &[]), ("partword-atomics", Unstable(sym::powerpc_target_feature), &[]), ("power10-vector", Unstable(sym::powerpc_target_feature), &["power9-vector"]), ("power8-altivec", Unstable(sym::powerpc_target_feature), &["altivec"]), diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 8675f7a61c79..5b82d3f539fe 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -151,6 +151,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `mp` `mp1e2` `msa` +`msync` `mte` `multivalue` `mutable-globals` From 6f505ba76724f00694ffc568ddc3032e147591b2 Mon Sep 17 00:00:00 2001 From: Michael Toner <22949655+mtoner23@users.noreply.github.com> Date: Sat, 1 Mar 2025 12:05:51 -0600 Subject: [PATCH 513/991] ensure we always print all --print options in help --- compiler/rustc_session/src/config.rs | 64 ++++++++++--------- tests/run-make/rustc-help/help-v.stdout | 2 +- tests/run-make/rustc-help/help.stdout | 2 +- .../print-without-arg.stderr | 2 +- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7586c5766b58..2f67660a46be 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -42,6 +42,32 @@ mod cfg; mod native_libs; pub mod sigpipe; +pub const PRINT_KINDS: &[(&str, PrintKind)] = &[ + // tidy-alphabetical-start + ("all-target-specs-json", PrintKind::AllTargetSpecs), + ("calling-conventions", PrintKind::CallingConventions), + ("cfg", PrintKind::Cfg), + ("check-cfg", PrintKind::CheckCfg), + ("code-models", PrintKind::CodeModels), + ("crate-name", PrintKind::CrateName), + ("deployment-target", PrintKind::DeploymentTarget), + ("file-names", PrintKind::FileNames), + ("host-tuple", PrintKind::HostTuple), + ("link-args", PrintKind::LinkArgs), + ("native-static-libs", PrintKind::NativeStaticLibs), + ("relocation-models", PrintKind::RelocationModels), + ("split-debuginfo", PrintKind::SplitDebuginfo), + ("stack-protector-strategies", PrintKind::StackProtectorStrategies), + ("sysroot", PrintKind::Sysroot), + ("target-cpus", PrintKind::TargetCPUs), + ("target-features", PrintKind::TargetFeatures), + ("target-libdir", PrintKind::TargetLibdir), + ("target-list", PrintKind::TargetList), + ("target-spec-json", PrintKind::TargetSpec), + ("tls-models", PrintKind::TlsModels), + // tidy-alphabetical-end +]; + /// The different settings that the `-C strip` flag can have. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum Strip { @@ -1508,6 +1534,13 @@ The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE ) }); +static PRINT_KINDS_STRING: LazyLock = LazyLock::new(|| { + format!( + "[{}]", + PRINT_KINDS.iter().map(|(name, _)| format!("{name}")).collect::>().join("|") + ) +}); + /// Returns all rustc command line options, including metadata for /// each option, such as whether the option is stable. pub fn rustc_optgroups() -> Vec { @@ -1568,10 +1601,7 @@ pub fn rustc_optgroups() -> Vec { "", "print", "Compiler information to print on stdout", - "[crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|\ - target-list|target-cpus|target-features|relocation-models|code-models|\ - tls-models|target-spec-json|all-target-specs-json|native-static-libs|\ - stack-protector-strategies|link-args|deployment-target]", + &PRINT_KINDS_STRING, ), opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""), opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""), @@ -1999,32 +2029,6 @@ fn collect_print_requests( cg.target_feature = String::new(); } - const PRINT_KINDS: &[(&str, PrintKind)] = &[ - // tidy-alphabetical-start - ("all-target-specs-json", PrintKind::AllTargetSpecs), - ("calling-conventions", PrintKind::CallingConventions), - ("cfg", PrintKind::Cfg), - ("check-cfg", PrintKind::CheckCfg), - ("code-models", PrintKind::CodeModels), - ("crate-name", PrintKind::CrateName), - ("deployment-target", PrintKind::DeploymentTarget), - ("file-names", PrintKind::FileNames), - ("host-tuple", PrintKind::HostTuple), - ("link-args", PrintKind::LinkArgs), - ("native-static-libs", PrintKind::NativeStaticLibs), - ("relocation-models", PrintKind::RelocationModels), - ("split-debuginfo", PrintKind::SplitDebuginfo), - ("stack-protector-strategies", PrintKind::StackProtectorStrategies), - ("sysroot", PrintKind::Sysroot), - ("target-cpus", PrintKind::TargetCPUs), - ("target-features", PrintKind::TargetFeatures), - ("target-libdir", PrintKind::TargetLibdir), - ("target-list", PrintKind::TargetList), - ("target-spec-json", PrintKind::TargetSpec), - ("tls-models", PrintKind::TlsModels), - // tidy-alphabetical-end - ]; - // We disallow reusing the same path in multiple prints, such as `--print // cfg=output.txt --print link-args=output.txt`, because outputs are printed // by disparate pieces of the compiler, and keeping track of which files diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout index 382b1c96682c..c8ea09ee2c8a 100644 --- a/tests/run-make/rustc-help/help-v.stdout +++ b/tests/run-make/rustc-help/help-v.stdout @@ -29,7 +29,7 @@ Options: --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir] Comma separated list of types of output for the compiler to emit - --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target] + --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models] Compiler information to print on stdout -g Equivalent to -C debuginfo=2 -O Equivalent to -C opt-level=3 diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout index 08bb7f85098d..434e71e901e4 100644 --- a/tests/run-make/rustc-help/help.stdout +++ b/tests/run-make/rustc-help/help.stdout @@ -29,7 +29,7 @@ Options: --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir] Comma separated list of types of output for the compiler to emit - --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target] + --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models] Compiler information to print on stdout -g Equivalent to -C debuginfo=2 -O Equivalent to -C opt-level=3 diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/invalid-compile-flags/print-without-arg.stderr index a18d2779cade..05d42247d419 100644 --- a/tests/ui/invalid-compile-flags/print-without-arg.stderr +++ b/tests/ui/invalid-compile-flags/print-without-arg.stderr @@ -1,5 +1,5 @@ error: Argument to option 'print' missing Usage: - --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target] + --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models] Compiler information to print on stdout From adff091b3e144c294981e62ba3f5cb2e16995a10 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 25 Feb 2025 20:11:05 +0000 Subject: [PATCH 514/991] Check dyn flavor before registering upcast goal on wide pointer cast in MIR typeck --- compiler/rustc_borrowck/src/type_check/mod.rs | 4 ++-- .../traits/trait-upcasting/dyn-to-dyn-star.rs | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/trait-upcasting/dyn-to-dyn-star.rs diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6d05696e146f..480d90932b99 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2120,8 +2120,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // // Note that other checks (such as denying `dyn Send` -> `dyn // Debug`) are in `rustc_hir_typeck`. - if let ty::Dynamic(src_tty, _src_lt, _) = *src_tail.kind() - && let ty::Dynamic(dst_tty, dst_lt, _) = *dst_tail.kind() + if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) = *src_tail.kind() + && let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) = *dst_tail.kind() && src_tty.principal().is_some() && dst_tty.principal().is_some() { diff --git a/tests/ui/traits/trait-upcasting/dyn-to-dyn-star.rs b/tests/ui/traits/trait-upcasting/dyn-to-dyn-star.rs new file mode 100644 index 000000000000..5936c93efad3 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/dyn-to-dyn-star.rs @@ -0,0 +1,19 @@ +// While somewhat nonsensical, this is a cast from a wide pointer to a thin pointer. +// Thus, we don't need to check an unsize goal here; there isn't any vtable casting +// happening at all. + +// Regression test for . + +//@ check-pass + +#![allow(incomplete_features)] +#![feature(dyn_star)] + +trait Foo {} +trait Bar {} + +fn cast(x: *const dyn Foo) { + x as *const dyn* Bar; +} + +fn main() {} From 86aae8e2d626258104cae2725bcdd1a92e572daf Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sun, 23 Feb 2025 16:16:10 +0530 Subject: [PATCH 515/991] uefi: Add Service Binding Protocol abstraction - Some UEFI protocols such as TCP4, TCP6, UDP4, UDP6, etc are managed by service binding protocol. - A new instance of such protocols is created and destroyed using the corresponding service binding protocol. - This PR adds abstractions to make using such protocols simpler using Rust Drop trait. - The reason to add these abstractions in a seperate PR from TCP4 Protocol is to make review easier. [EFI_SERVICE_BINDING_PROTCOL](https://uefi.org/specs/UEFI/2.11/11_Protocols_UEFI_Driver_Model.html#efi-service-binding-protocol) Signed-off-by: Ayush Singh --- library/std/src/sys/pal/uefi/helpers.rs | 61 ++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index ec2da4e4ee7a..55f050989636 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -10,7 +10,7 @@ //! - More information about protocols can be found [here](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/3_foundation/36_protocols_and_handles) use r_efi::efi::{self, Guid}; -use r_efi::protocols::{device_path, device_path_to_text, shell}; +use r_efi::protocols::{device_path, device_path_to_text, service_binding, shell}; use crate::ffi::{OsStr, OsString}; use crate::io::{self, const_error}; @@ -500,3 +500,62 @@ pub(crate) fn get_device_path_from_map(map: &Path) -> io::Result, + child_handle: NonNull, +} + +impl ServiceProtocol { + #[expect(dead_code)] + pub(crate) fn open(service_guid: r_efi::efi::Guid) -> io::Result { + let handles = locate_handles(service_guid)?; + + for handle in handles { + if let Ok(protocol) = open_protocol::(handle, service_guid) { + let Ok(child_handle) = Self::create_child(protocol) else { + continue; + }; + + return Ok(Self { service_guid, handle, child_handle }); + } + } + + Err(io::const_error!(io::ErrorKind::NotFound, "no service binding protocol found")) + } + + #[expect(dead_code)] + pub(crate) fn child_handle(&self) -> NonNull { + self.child_handle + } + + fn create_child( + sbp: NonNull, + ) -> io::Result> { + let mut child_handle: r_efi::efi::Handle = crate::ptr::null_mut(); + // SAFETY: A new handle is allocated if a pointer to NULL is passed. + let r = unsafe { ((*sbp.as_ptr()).create_child)(sbp.as_ptr(), &mut child_handle) }; + + if r.is_error() { + Err(crate::io::Error::from_raw_os_error(r.as_usize())) + } else { + NonNull::new(child_handle) + .ok_or(const_error!(io::ErrorKind::Other, "null child handle")) + } + } +} + +impl Drop for ServiceProtocol { + fn drop(&mut self) { + if let Ok(sbp) = open_protocol::(self.handle, self.service_guid) + { + // SAFETY: Child handle must be allocated by the current service binding protocol. + let _ = unsafe { + ((*sbp.as_ptr()).destroy_child)(sbp.as_ptr(), self.child_handle.as_ptr()) + }; + } + } +} From 8b4007a91db75b320ec20a14263d0292f02a0626 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 25 Feb 2025 19:08:03 +0000 Subject: [PATCH 516/991] Update `compiler-builtins` to 0.1.150 Includes a change to make a subset of math symbols available on all platforms [1], and disables `f16` on aarch64 without neon [2]. [1]: https://github.com/rust-lang/compiler-builtins/pull/763 [2]: https://github.com/rust-lang/compiler-builtins/pull/775 --- ...029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch | 4 ++-- library/Cargo.lock | 4 ++-- library/alloc/Cargo.toml | 2 +- library/std/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch index bedc6ca11b3f..d8db7d63f2dd 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644 [dependencies] core = { path = "../core", public = true } --compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std', 'no-f16-f128'] } +-compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std', 'no-f16-f128'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/library/Cargo.lock b/library/Cargo.lock index de9685742f59..37b10649ced4 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.148" +version = "0.1.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26137996631d90d2727b905b480fdcf8c4479fdbce7afd7f8e3796d689b33cc2" +checksum = "5c42734e0ccf0d9f953165770593a75306f0b24dda1aa03f115c70748726dbca" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 9e80f3579e80..9cf9e98e89ee 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" [dependencies] core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.9.0", default-features = false, features = ["alloc"] } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f4d4894c1bbd..8e4dd0f2bf48 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.148" } +compiler_builtins = { version = "=0.1.150" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', From 649c0ff9b0bdce2652b2db0a95fac95aafa28992 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 2 Mar 2025 05:44:32 +0900 Subject: [PATCH 517/991] Add minimal platform support documentation for powerpc-unknown-linux-gnuspe --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 4 ++-- .../powerpc-unknown-linux-gnuspe.md | 20 +++++++++++++++++++ .../powerpc-unknown-linux-muslspe.md | 4 +++- 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/doc/rustc/src/platform-support/powerpc-unknown-linux-gnuspe.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 6c7cdec34802..e2d41a48102b 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -68,6 +68,7 @@ - [mipsisa\*r6\*-unknown-linux-gnu\*](platform-support/mips-release-6.md) - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md) - [powerpc-unknown-openbsd](platform-support/powerpc-unknown-openbsd.md) + - [powerpc-unknown-linux-gnuspe](platform-support/powerpc-unknown-linux-gnuspe.md) - [powerpc-unknown-linux-muslspe](platform-support/powerpc-unknown-linux-muslspe.md) - [powerpc64-ibm-aix](platform-support/aix.md) - [powerpc64le-unknown-linux-musl](platform-support/powerpc64le-unknown-linux-musl.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c4e5c1aac2f5..9000ec51f215 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -348,9 +348,9 @@ target | std | host | notes [`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ✓ | ✓ | 64-bit MIPS Release 6 Little Endian `msp430-none-elf` | * | | 16-bit MSP430 microcontrollers [`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD -`powerpc-unknown-linux-gnuspe` | ✓ | | PowerPC SPE Linux +[`powerpc-unknown-linux-gnuspe`](platform-support/powerpc-unknown-linux-gnuspe.md) | ✓ | | PowerPC SPE Linux `powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.3 -[`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? | | PowerPC SPE Linux +[`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? | | PowerPC SPE Linux with musl 1.2.3 [`powerpc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD 32-bit powerpc systems [`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * | | [`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | diff --git a/src/doc/rustc/src/platform-support/powerpc-unknown-linux-gnuspe.md b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-gnuspe.md new file mode 100644 index 000000000000..a9983a141115 --- /dev/null +++ b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-gnuspe.md @@ -0,0 +1,20 @@ +# powerpc-unknown-linux-gnuspe + +**Tier: 3** + +`powerpc-unknown-linux-gnuspe` is a target for Linux on 32-bit PowerPC +processors that implement the Signal Processing Engine (SPE), such as e500, and +uses a different ABI than standard `powerpc-unknown-linux-gnu`. +When building for other 32-bit PowerPC processors, use +`powerpc-unknown-linux-gnu` instead. + +See also [Debian Wiki](https://wiki.debian.org/PowerPCSPEPort) for details on +this platform, and [ABI reference](https://web.archive.org/web/20120608163804/https://www.power.org/resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Unified.pdf) +for details on SPE ABI. + +Note that support for PowerPC SPE by GCC was [removed in GCC 9](https://gcc.gnu.org/gcc-8/changes.html), +so recent GCC cannot be used as linker/compiler for this target. + +## Target maintainers + +There are currently no formally documented target maintainers. diff --git a/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md index 4c416b519299..6b62e9ddba10 100644 --- a/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md +++ b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md @@ -2,9 +2,11 @@ **Tier: 3** -This target is very similar to already existing ones like `powerpc_unknown_linux_musl` and `powerpc_unknown_linux_gnuspe`. +This target is very similar to already existing ones like `powerpc-unknown-linux-musl` and `powerpc-unknown-linux-gnuspe`. This one has PowerPC SPE support for musl. Unfortunately, the last supported gcc version with PowerPC SPE is 8.4.0. +See also [platform support documentation of `powerpc-unknown-linux-gnuspe`](powerpc-unknown-linux-gnuspe.md) for information about PowerPC SPE. + ## Target maintainers - [@BKPepe](https://github.com/BKPepe) From 0034d6c928803076225867c6fea19a3e2c8e9f26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 24 Feb 2025 09:52:53 +0100 Subject: [PATCH 518/991] Compile run-make recipes using the stage0 compiler --- src/bootstrap/src/core/build_steps/test.rs | 5 + src/tools/compiletest/src/common.rs | 3 + src/tools/compiletest/src/lib.rs | 7 ++ src/tools/compiletest/src/runtest/run_make.rs | 119 ++++++------------ .../src/external_deps/rustc.rs | 8 +- .../src/external_deps/rustdoc.rs | 24 +--- src/tools/run-make-support/src/lib.rs | 2 +- src/tools/run-make-support/src/run.rs | 19 +-- src/tools/run-make-support/src/util.rs | 6 +- .../run-make/rustdoc-default-output/rmake.rs | 4 +- .../version-verbose-commit-hash/rmake.rs | 4 +- 11 files changed, 78 insertions(+), 123 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 79be42cdd2f2..99ab876ccfa5 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1679,6 +1679,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the }; cmd.arg("--cargo-path").arg(cargo_path); + + // We need to pass the compiler that was used to compile run-make-support, + // because we have to use the same compiler to compile rmake.rs recipes. + let stage0_rustc_path = builder.compiler(0, compiler.host); + cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path)); } // Avoid depending on rustdoc when we don't need it. diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index b302c6a49f58..978836cb6636 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -190,6 +190,9 @@ pub struct Config { /// The cargo executable. pub cargo_path: Option, + /// Rustc executable used to compile run-make recipes. + pub stage0_rustc_path: Option, + /// The rustdoc executable. pub rustdoc_path: Option, diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 9dff7047bc4a..e93f32c86bc4 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -54,6 +54,12 @@ pub fn parse_config(args: Vec) -> Config { .reqopt("", "run-lib-path", "path to target shared libraries", "PATH") .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH") .optopt("", "cargo-path", "path to cargo to use for compiling", "PATH") + .optopt( + "", + "stage0-rustc-path", + "path to rustc to use for compiling run-make recipes", + "PATH", + ) .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH") .optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH") .reqopt("", "python", "path to python to use for doc tests", "PATH") @@ -320,6 +326,7 @@ pub fn parse_config(args: Vec) -> Config { run_lib_path: make_absolute(opt_path(matches, "run-lib-path")), rustc_path: opt_path(matches, "rustc-path"), cargo_path: matches.opt_str("cargo-path").map(PathBuf::from), + stage0_rustc_path: matches.opt_str("stage0-rustc-path").map(PathBuf::from), rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from), coverage_dump_path: matches.opt_str("coverage-dump-path").map(PathBuf::from), python: matches.opt_str("python").unwrap(), diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 9bb3993223e2..07f4d7c49426 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -173,7 +173,8 @@ impl TestCx<'_> { fn run_rmake_v2_test(&self) { // For `run-make` V2, we need to perform 2 steps to build and run a `run-make` V2 recipe // (`rmake.rs`) to run the actual tests. The support library is already built as a tool rust - // library and is available under `build/$TARGET/stageN-tools-bin/librun_make_support.rlib`. + // library and is available under + // `build/$HOST/stage0-bootstrap-tools/$TARGET/release/librun_make_support.rlib`. // // 1. We need to build the recipe `rmake.rs` as a binary and link in the `run_make_support` // library. @@ -224,25 +225,21 @@ impl TestCx<'_> { // // ``` // build// - // ├── stageN-tools-bin/ - // │ └── librun_make_support.rlib // <- support rlib itself - // ├── stageN-tools/ - // │ ├── release/deps/ // <- deps of deps - // │ └── /release/deps/ // <- deps + // ├── stage0-bootstrap-tools/ + // │ ├── /release/librun_make_support.rlib // <- support rlib itself + // │ ├── /release/deps/ // <- deps + // │ └── release/deps/ // <- deps of deps // ``` // // FIXME(jieyouxu): there almost certainly is a better way to do this (specifically how the - // support lib and its deps are organized, can't we copy them to the tools-bin dir as - // well?), but this seems to work for now. + // support lib and its deps are organized), but this seems to work for now. - let stage_number = self.config.stage; + let tools_bin = host_build_root.join("stage0-bootstrap-tools"); + let support_host_path = tools_bin.join(&self.config.host).join("release"); + let support_lib_path = support_host_path.join("librun_make_support.rlib"); - let stage_tools_bin = host_build_root.join(format!("stage{stage_number}-tools-bin")); - let support_lib_path = stage_tools_bin.join("librun_make_support.rlib"); - - let stage_tools = host_build_root.join(format!("stage{stage_number}-tools")); - let support_lib_deps = stage_tools.join(&self.config.host).join("release").join("deps"); - let support_lib_deps_deps = stage_tools.join("release").join("deps"); + let support_lib_deps = support_host_path.join("deps"); + let support_lib_deps_deps = tools_bin.join("release").join("deps"); // To compile the recipe with rustc, we need to provide suitable dynamic library search // paths to rustc. This includes both: @@ -253,12 +250,6 @@ impl TestCx<'_> { let base_dylib_search_paths = Vec::from_iter(env::split_paths(&env::var(dylib_env_var()).unwrap())); - let host_dylib_search_paths = { - let mut paths = vec![self.config.compile_lib_path.clone()]; - paths.extend(base_dylib_search_paths.iter().cloned()); - paths - }; - // Calculate the paths of the recipe binary. As previously discussed, this is placed at // `/` with `bin_name` being `rmake` or `rmake.exe` depending on // platform. @@ -268,7 +259,15 @@ impl TestCx<'_> { p }; - let mut rustc = Command::new(&self.config.rustc_path); + // run-make-support and run-make tests are compiled using the stage0 compiler + // If the stage is 0, then the compiler that we test (either bootstrap or an explicitly + // set compiler) is the one that actually compiled run-make-support. + let stage0_rustc = self + .config + .stage0_rustc_path + .as_ref() + .expect("stage0 rustc is required to run run-make tests"); + let mut rustc = Command::new(&stage0_rustc); rustc .arg("-o") .arg(&recipe_bin) @@ -282,35 +281,12 @@ impl TestCx<'_> { .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy())) .arg("--edition=2021") .arg(&self.testpaths.file.join("rmake.rs")) - .arg("-Cprefer-dynamic") - // Provide necessary library search paths for rustc. - .env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap()); + .arg("-Cprefer-dynamic"); // In test code we want to be very pedantic about values being silently discarded that are // annotated with `#[must_use]`. rustc.arg("-Dunused_must_use"); - // > `cg_clif` uses `COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0` for running the rustc - // > test suite. With the introduction of rmake.rs this broke. `librun_make_support.rlib` is - // > compiled using the bootstrap rustc wrapper which sets `--sysroot - // > build/aarch64-unknown-linux-gnu/stage0-sysroot`, but then compiletest will compile - // > `rmake.rs` using the sysroot of the bootstrap compiler causing it to not find the - // > `libstd.rlib` against which `librun_make_support.rlib` is compiled. - // - // The gist here is that we have to pass the proper stage0 sysroot if we want - // - // ``` - // $ COMPILETEST_FORCE_STAGE0=1 ./x test run-make --stage 0 - // ``` - // - // to work correctly. - // - // See for more background. - let stage0_sysroot = host_build_root.join("stage0-sysroot"); - if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() { - rustc.arg("--sysroot").arg(&stage0_sysroot); - } - // Now run rustc to build the recipe. let res = self.run_command_to_procres(&mut rustc); if !res.status.success() { @@ -320,35 +296,24 @@ impl TestCx<'_> { // To actually run the recipe, we have to provide the recipe with a bunch of information // provided through env vars. - // Compute stage-specific standard library paths. - let stage_std_path = host_build_root.join(format!("stage{stage_number}")).join("lib"); - // Compute dynamic library search paths for recipes. + // These dylib directories are needed to **execute the recipe**. let recipe_dylib_search_paths = { let mut paths = base_dylib_search_paths.clone(); - - // For stage 0, we need to explicitly include the stage0-sysroot libstd dylib. - // See . - if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() { - paths.push( - stage0_sysroot.join("lib").join("rustlib").join(&self.config.host).join("lib"), - ); - } - - paths.push(support_lib_path.parent().unwrap().to_path_buf()); - paths.push(stage_std_path.join("rustlib").join(&self.config.host).join("lib")); + paths.push( + stage0_rustc + .parent() + .unwrap() + .parent() + .unwrap() + .join("lib") + .join("rustlib") + .join(&self.config.host) + .join("lib"), + ); paths }; - // Compute runtime library search paths for recipes. This is target-specific. - let target_runtime_dylib_search_paths = { - let mut paths = vec![rmake_out_dir.clone()]; - paths.extend(base_dylib_search_paths.iter().cloned()); - paths - }; - - // FIXME(jieyouxu): please rename `TARGET_RPATH_ENV`, `HOST_RPATH_DIR` and - // `TARGET_RPATH_DIR`, it is **extremely** confusing! let mut cmd = Command::new(&recipe_bin); cmd.current_dir(&rmake_out_dir) .stdout(Stdio::piped()) @@ -357,9 +322,14 @@ impl TestCx<'_> { // example, this could be `LD_LIBRARY_PATH` on some linux distros but `PATH` on Windows. .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) // Provide the dylib search paths. + // This is required to run the **recipe** itself. .env(dylib_env_var(), &env::join_paths(recipe_dylib_search_paths).unwrap()) - // Provide runtime dylib search paths. - .env("TARGET_RPATH_ENV", &env::join_paths(target_runtime_dylib_search_paths).unwrap()) + // Provide the directory to libraries that are needed to run the *compiler* invoked + // by the recipe. + .env("HOST_RUSTC_DYLIB_PATH", &self.config.compile_lib_path) + // Provide the directory to libraries that might be needed to run binaries created + // by a compiler invoked by the recipe. + .env("TARGET_EXE_DYLIB_PATH", &self.config.run_lib_path) // Provide the target. .env("TARGET", &self.config.target) // Some tests unfortunately still need Python, so provide path to a Python interpreter. @@ -370,13 +340,6 @@ impl TestCx<'_> { .env("BUILD_ROOT", &host_build_root) // Provide path to stage-corresponding rustc. .env("RUSTC", &self.config.rustc_path) - // Provide the directory to libraries that are needed to run the *compiler*. This is not - // to be confused with `TARGET_RPATH_ENV` or `TARGET_RPATH_DIR`. This is needed if the - // recipe wants to invoke rustc. - .env("HOST_RPATH_DIR", &self.config.compile_lib_path) - // Provide the directory to libraries that might be needed to run compiled binaries - // (further compiled by the recipe!). - .env("TARGET_RPATH_DIR", &self.config.run_lib_path) // Provide which LLVM components are available (e.g. which LLVM components are provided // through a specific CI runner). .env("LLVM_COMPONENTS", &self.config.llvm_components); diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index 710ba025830a..cb2bd83815a3 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -5,7 +5,7 @@ use std::str::FromStr as _; use crate::command::Command; use crate::env::env_var; use crate::path_helpers::cwd; -use crate::util::set_host_rpath; +use crate::util::set_host_compiler_dylib_path; use crate::{is_aix, is_darwin, is_msvc, is_windows, uname}; /// Construct a new `rustc` invocation. This will automatically set the library @@ -15,8 +15,8 @@ pub fn rustc() -> Rustc { Rustc::new() } -/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_rpath`] -/// still presets the environment variable `HOST_RPATH_DIR` by default. +/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_compiler_dylib_path`] +/// still presets the environment variable `HOST_RUSTC_DYLIB_PATH` by default. #[track_caller] pub fn bare_rustc() -> Rustc { Rustc::bare() @@ -44,7 +44,7 @@ pub fn rustc_path() -> String { #[track_caller] fn setup_common() -> Command { let mut cmd = Command::new(rustc_path()); - set_host_rpath(&mut cmd); + set_host_compiler_dylib_path(&mut cmd); cmd } diff --git a/src/tools/run-make-support/src/external_deps/rustdoc.rs b/src/tools/run-make-support/src/external_deps/rustdoc.rs index 3c0e9c82f0bb..61351ace12c9 100644 --- a/src/tools/run-make-support/src/external_deps/rustdoc.rs +++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs @@ -2,16 +2,10 @@ use std::ffi::OsStr; use std::path::Path; use crate::command::Command; -use crate::env::{env_var, env_var_os}; -use crate::util::set_host_rpath; +use crate::env::env_var; +use crate::util::set_host_compiler_dylib_path; -/// Construct a plain `rustdoc` invocation with no flags set. -#[track_caller] -pub fn bare_rustdoc() -> Rustdoc { - Rustdoc::bare() -} - -/// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. +/// Construct a new `rustdoc` invocation. #[track_caller] pub fn rustdoc() -> Rustdoc { Rustdoc::new() @@ -29,23 +23,15 @@ crate::macros::impl_common_helpers!(Rustdoc); fn setup_common() -> Command { let rustdoc = env_var("RUSTDOC"); let mut cmd = Command::new(rustdoc); - set_host_rpath(&mut cmd); + set_host_compiler_dylib_path(&mut cmd); cmd } impl Rustdoc { /// Construct a bare `rustdoc` invocation. #[track_caller] - pub fn bare() -> Self { - let cmd = setup_common(); - Self { cmd } - } - - /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. - #[track_caller] pub fn new() -> Self { - let mut cmd = setup_common(); - cmd.arg("-L").arg(env_var_os("TARGET_RPATH_DIR")); + let cmd = setup_common(); Self { cmd } } diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 7e63ab3159ac..d40ec9c4116e 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -67,7 +67,7 @@ pub use llvm::{ }; pub use python::python_command; pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc}; -pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; +pub use rustdoc::{rustdoc, Rustdoc}; /// [`diff`][mod@diff] is implemented in terms of the [similar] library. /// diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs index 3eeba6fd5263..7812863ccc2c 100644 --- a/src/tools/run-make-support/src/run.rs +++ b/src/tools/run-make-support/src/run.rs @@ -1,10 +1,10 @@ use std::ffi::OsStr; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::{env, panic}; use crate::command::{Command, CompletedProcess}; -use crate::util::{handle_failed_output, set_host_rpath}; -use crate::{cwd, env_var, is_windows}; +use crate::util::handle_failed_output; +use crate::{cwd, env_var}; #[track_caller] fn run_common(name: &str, args: Option<&[&str]>) -> Command { @@ -18,10 +18,11 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command { cmd.arg(arg); } } + cmd.env(&ld_lib_path_envvar, { let mut paths = vec![]; paths.push(cwd()); - for p in env::split_paths(&env_var("TARGET_RPATH_ENV")) { + for p in env::split_paths(&env_var("TARGET_EXE_DYLIB_PATH")) { paths.push(p.to_path_buf()); } for p in env::split_paths(&env_var(&ld_lib_path_envvar)) { @@ -31,15 +32,6 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command { }); cmd.env("LC_ALL", "C"); // force english locale - if is_windows() { - let mut paths = vec![]; - for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) { - paths.push(p.to_path_buf()); - } - paths.push(Path::new(&env_var("TARGET_RPATH_DIR")).to_path_buf()); - cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); - } - cmd } @@ -84,7 +76,6 @@ pub fn run_fail(name: &str) -> CompletedProcess { #[track_caller] pub fn cmd>(program: S) -> Command { let mut command = Command::new(program); - set_host_rpath(&mut command); command.env("LC_ALL", "C"); // force english locale command } diff --git a/src/tools/run-make-support/src/util.rs b/src/tools/run-make-support/src/util.rs index 703e3ad1c6cd..af01758447b9 100644 --- a/src/tools/run-make-support/src/util.rs +++ b/src/tools/run-make-support/src/util.rs @@ -24,13 +24,13 @@ pub(crate) fn handle_failed_output( std::process::exit(1) } -/// Set the runtime library path as needed for running the host rustc/rustdoc/etc. -pub(crate) fn set_host_rpath(cmd: &mut Command) { +/// Set the runtime library paths as needed for running the host compilers (rustc/rustdoc/etc). +pub(crate) fn set_host_compiler_dylib_path(cmd: &mut Command) { let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR"); cmd.env(&ld_lib_path_envvar, { let mut paths = vec![]; paths.push(cwd()); - paths.push(PathBuf::from(env_var("HOST_RPATH_DIR"))); + paths.push(PathBuf::from(env_var("HOST_RUSTC_DYLIB_PATH"))); for p in std::env::split_paths(&env_var(&ld_lib_path_envvar)) { paths.push(p.to_path_buf()); } diff --git a/tests/run-make/rustdoc-default-output/rmake.rs b/tests/run-make/rustdoc-default-output/rmake.rs index 06720445a35c..5f9c501e5286 100644 --- a/tests/run-make/rustdoc-default-output/rmake.rs +++ b/tests/run-make/rustdoc-default-output/rmake.rs @@ -3,10 +3,10 @@ // ensures the output of rustdoc's help menu is as expected. // See https://github.com/rust-lang/rust/issues/88756 -use run_make_support::{bare_rustdoc, diff}; +use run_make_support::{diff, rustdoc}; fn main() { - let out = bare_rustdoc().run().stdout_utf8(); + let out = rustdoc().run().stdout_utf8(); diff() .expected_file("output-default.stdout") .actual_text("actual", out) diff --git a/tests/run-make/version-verbose-commit-hash/rmake.rs b/tests/run-make/version-verbose-commit-hash/rmake.rs index 733c0e2cdb14..ae8dda38ab41 100644 --- a/tests/run-make/version-verbose-commit-hash/rmake.rs +++ b/tests/run-make/version-verbose-commit-hash/rmake.rs @@ -5,13 +5,13 @@ //@ needs-git-hash -use run_make_support::{bare_rustc, bare_rustdoc, regex}; +use run_make_support::{bare_rustc, regex, rustdoc}; fn main() { let out_rustc = bare_rustc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase(); let out_rustdoc = - bare_rustdoc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase(); + rustdoc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase(); let re = regex::Regex::new(r#"commit-hash: [0-9a-f]{40}\ncommit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}"#) .unwrap(); From 9d6ca5f286dac25ac168aa77709f5a0cbd40d30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 25 Feb 2025 11:10:59 +0100 Subject: [PATCH 519/991] Ignore a-b-a-linker-guard during cross-compilation --- tests/run-make/a-b-a-linker-guard/rmake.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/run-make/a-b-a-linker-guard/rmake.rs b/tests/run-make/a-b-a-linker-guard/rmake.rs index ee6d655bc760..4428685a6cf1 100644 --- a/tests/run-make/a-b-a-linker-guard/rmake.rs +++ b/tests/run-make/a-b-a-linker-guard/rmake.rs @@ -1,7 +1,8 @@ -// ignore-tidy-linelength +// Test that if we build `b` against a version of `a` that has +// one set of types, it will not run with a dylib that has a different set of types. -// Test that if we build `b` against a version of `a` that has one set of types, it will not run -// with a dylib that has a different set of types. +//@ ignore-cross-compile +// Reason: the compiled binary is executed use run_make_support::{run, run_fail, rustc}; From 3998690a68d0346bc31870595e7ca6cf8540a989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:15:04 +0800 Subject: [PATCH 520/991] compiletest: remove legacy `Makefile`-based `run-make` support --- src/tools/compiletest/src/header.rs | 16 +- src/tools/compiletest/src/header/tests.rs | 9 - src/tools/compiletest/src/lib.rs | 43 ++--- src/tools/compiletest/src/runtest/run_make.rs | 164 ------------------ 4 files changed, 18 insertions(+), 214 deletions(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 53ee901b8bc4..7675e13990d6 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -709,11 +709,11 @@ impl TestProps { /// returns a struct containing various parts of the directive. fn line_directive<'line>( line_number: usize, - comment: &str, original_line: &'line str, ) -> Option> { // Ignore lines that don't start with the comment prefix. - let after_comment = original_line.trim_start().strip_prefix(comment)?.trim_start(); + let after_comment = + original_line.trim_start().strip_prefix(COMPILETEST_DIRECTIVE_PREFIX)?.trim_start(); let revision; let raw_directive; @@ -722,7 +722,7 @@ fn line_directive<'line>( // A comment like `//@[foo]` only applies to revision `foo`. let Some((line_revision, after_close_bracket)) = after_open_bracket.split_once(']') else { panic!( - "malformed condition directive: expected `{comment}[foo]`, found `{original_line}`" + "malformed condition directive: expected `{COMPILETEST_DIRECTIVE_PREFIX}[foo]`, found `{original_line}`" ) }; @@ -836,6 +836,8 @@ pub(crate) fn check_directive<'a>( CheckDirectiveResult { is_known_directive: is_known(&directive_name), trailing_directive } } +const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@"; + fn iter_header( mode: Mode, _suite: &str, @@ -849,8 +851,7 @@ fn iter_header( } // Coverage tests in coverage-run mode always have these extra directives, without needing to - // specify them manually in every test file. (Some of the comments below have been copied over - // from the old `tests/run-make/coverage-reports/Makefile`, which no longer exists.) + // specify them manually in every test file. // // FIXME(jieyouxu): I feel like there's a better way to do this, leaving for later. if mode == Mode::CoverageRun { @@ -867,9 +868,6 @@ fn iter_header( } } - // NOTE(jieyouxu): once we get rid of `Makefile`s we can unconditionally check for `//@`. - let comment = if testfile.extension().is_some_and(|e| e == "rs") { "//@" } else { "#" }; - let mut rdr = BufReader::with_capacity(1024, rdr); let mut ln = String::new(); let mut line_number = 0; @@ -882,7 +880,7 @@ fn iter_header( } let ln = ln.trim(); - let Some(directive_line) = line_directive(line_number, comment, ln) else { + let Some(directive_line) = line_directive(line_number, ln) else { continue; }; diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index d7079fdeee6c..007318be7cc3 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -239,11 +239,6 @@ fn check_ignore(config: &Config, contents: &str) -> bool { d.ignore } -fn parse_makefile(config: &Config, contents: &str) -> EarlyProps { - let bytes = contents.as_bytes(); - EarlyProps::from_reader(config, Path::new("Makefile"), bytes) -} - #[test] fn should_fail() { let config: Config = cfg().build(); @@ -261,10 +256,6 @@ fn revisions() { let config: Config = cfg().build(); assert_eq!(parse_rs(&config, "//@ revisions: a b c").revisions, vec!["a", "b", "c"],); - assert_eq!( - parse_makefile(&config, "# revisions: hello there").revisions, - vec!["hello", "there"], - ); } #[test] diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 9dff7047bc4a..30b8e269e625 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -21,7 +21,7 @@ pub mod util; use core::panic; use std::collections::HashSet; -use std::ffi::{OsStr, OsString}; +use std::ffi::OsString; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -268,12 +268,8 @@ pub fn parse_config(args: Vec) -> Config { let path = Path::new(f); let mut iter = path.iter().skip(1); - // We skip the test folder and check if the user passed `rmake.rs` or `Makefile`. - if iter - .next() - .is_some_and(|s| s == OsStr::new("rmake.rs") || s == OsStr::new("Makefile")) - && iter.next().is_none() - { + // We skip the test folder and check if the user passed `rmake.rs`. + if iter.next().is_some_and(|s| s == "rmake.rs") && iter.next().is_none() { path.parent().unwrap().to_str().unwrap().to_string() } else { f.to_string() @@ -776,16 +772,9 @@ fn collect_tests_from_dir( return Ok(()); } - // For run-make tests, a "test file" is actually a directory that contains - // an `rmake.rs` or `Makefile`" + // For run-make tests, a "test file" is actually a directory that contains an `rmake.rs`. if cx.config.mode == Mode::RunMake { - if dir.join("Makefile").exists() && dir.join("rmake.rs").exists() { - return Err(io::Error::other( - "run-make tests cannot have both `Makefile` and `rmake.rs`", - )); - } - - if dir.join("Makefile").exists() || dir.join("rmake.rs").exists() { + if dir.join("rmake.rs").exists() { let paths = TestPaths { file: dir.to_path_buf(), relative_dir: relative_dir_path.parent().unwrap().to_path_buf(), @@ -854,24 +843,14 @@ pub fn is_test(file_name: &OsString) -> bool { !invalid_prefixes.iter().any(|p| file_name.starts_with(p)) } -/// For a single test file, creates one or more test structures (one per revision) -/// that can be handed over to libtest to run, possibly in parallel. +/// For a single test file, creates one or more test structures (one per revision) that can be +/// handed over to libtest to run, possibly in parallel. fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &TestPaths) { - // For run-make tests, each "test file" is actually a _directory_ containing - // an `rmake.rs` or `Makefile`. But for the purposes of directive parsing, - // we want to look at that recipe file, not the directory itself. + // For run-make tests, each "test file" is actually a _directory_ containing an `rmake.rs`. But + // for the purposes of directive parsing, we want to look at that recipe file, not the directory + // itself. let test_path = if cx.config.mode == Mode::RunMake { - if testpaths.file.join("rmake.rs").exists() && testpaths.file.join("Makefile").exists() { - panic!("run-make tests cannot have both `rmake.rs` and `Makefile`"); - } - - if testpaths.file.join("rmake.rs").exists() { - // Parse directives in rmake.rs. - testpaths.file.join("rmake.rs") - } else { - // Parse directives in the Makefile. - testpaths.file.join("Makefile") - } + testpaths.file.join("rmake.rs") } else { PathBuf::from(&testpaths.file) }; diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 9bb3993223e2..b237fac38f6b 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -9,168 +9,6 @@ use crate::util::{copy_dir_all, dylib_env_var}; impl TestCx<'_> { pub(super) fn run_rmake_test(&self) { - let test_dir = &self.testpaths.file; - if test_dir.join("rmake.rs").exists() { - self.run_rmake_v2_test(); - } else if test_dir.join("Makefile").exists() { - self.run_rmake_legacy_test(); - } else { - self.fatal("failed to find either `rmake.rs` or `Makefile`") - } - } - - fn run_rmake_legacy_test(&self) { - let cwd = env::current_dir().unwrap(); - - // FIXME(Zalathar): This should probably be `output_base_dir` to avoid - // an unnecessary extra subdirectory, but since legacy Makefile tests - // are hopefully going away, it seems safer to leave this perilous code - // as-is until it can all be deleted. - let tmpdir = cwd.join(self.output_base_name()); - ignore_not_found(|| recursive_remove(&tmpdir)).unwrap(); - - fs::create_dir_all(&tmpdir).unwrap(); - - let host = &self.config.host; - let make = if host.contains("dragonfly") - || host.contains("freebsd") - || host.contains("netbsd") - || host.contains("openbsd") - || host.contains("aix") - { - "gmake" - } else { - "make" - }; - - let mut cmd = Command::new(make); - cmd.current_dir(&self.testpaths.file) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .env("TARGET", &self.config.target) - .env("PYTHON", &self.config.python) - .env("S", &self.config.src_root) - .env("RUST_BUILD_STAGE", &self.config.stage_id) - .env("RUSTC", cwd.join(&self.config.rustc_path)) - .env("TMPDIR", &tmpdir) - .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) - .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) - .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path)) - .env("LLVM_COMPONENTS", &self.config.llvm_components) - // We for sure don't want these tests to run in parallel, so make - // sure they don't have access to these vars if we run via `make` - // at the top level - .env_remove("MAKEFLAGS") - .env_remove("MFLAGS") - .env_remove("CARGO_MAKEFLAGS"); - - if let Some(ref cargo) = self.config.cargo_path { - cmd.env("CARGO", cwd.join(cargo)); - } - - if let Some(ref rustdoc) = self.config.rustdoc_path { - cmd.env("RUSTDOC", cwd.join(rustdoc)); - } - - if let Some(ref node) = self.config.nodejs { - cmd.env("NODE", node); - } - - if let Some(ref linker) = self.config.target_linker { - cmd.env("RUSTC_LINKER", linker); - } - - if let Some(ref clang) = self.config.run_clang_based_tests_with { - cmd.env("CLANG", clang); - } - - if let Some(ref filecheck) = self.config.llvm_filecheck { - cmd.env("LLVM_FILECHECK", filecheck); - } - - if let Some(ref llvm_bin_dir) = self.config.llvm_bin_dir { - cmd.env("LLVM_BIN_DIR", llvm_bin_dir); - } - - if let Some(ref remote_test_client) = self.config.remote_test_client { - cmd.env("REMOTE_TEST_CLIENT", remote_test_client); - } - - // We don't want RUSTFLAGS set from the outside to interfere with - // compiler flags set in the test cases: - cmd.env_remove("RUSTFLAGS"); - - // Use dynamic musl for tests because static doesn't allow creating dylibs - if self.config.host.contains("musl") { - cmd.env("RUSTFLAGS", "-Ctarget-feature=-crt-static").env("IS_MUSL_HOST", "1"); - } - - if self.config.bless { - cmd.env("RUSTC_BLESS_TEST", "--bless"); - // Assume this option is active if the environment variable is "defined", with _any_ value. - // As an example, a `Makefile` can use this option by: - // - // ifdef RUSTC_BLESS_TEST - // cp "$(TMPDIR)"/actual_something.ext expected_something.ext - // else - // $(DIFF) expected_something.ext "$(TMPDIR)"/actual_something.ext - // endif - } - - if self.config.target.contains("msvc") && !self.config.cc.is_empty() { - // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe` - // and that `lib.exe` lives next to it. - let lib = Path::new(&self.config.cc).parent().unwrap().join("lib.exe"); - - // MSYS doesn't like passing flags of the form `/foo` as it thinks it's - // a path and instead passes `C:\msys64\foo`, so convert all - // `/`-arguments to MSVC here to `-` arguments. - let cflags = self - .config - .cflags - .split(' ') - .map(|s| s.replace("/", "-")) - .collect::>() - .join(" "); - let cxxflags = self - .config - .cxxflags - .split(' ') - .map(|s| s.replace("/", "-")) - .collect::>() - .join(" "); - - cmd.env("IS_MSVC", "1") - .env("IS_WINDOWS", "1") - .env("MSVC_LIB", format!("'{}' -nologo", lib.display())) - .env("MSVC_LIB_PATH", format!("{}", lib.display())) - .env("CC", format!("'{}' {}", self.config.cc, cflags)) - .env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags)); - } else { - cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags)) - .env("CXX", format!("{} {}", self.config.cxx, self.config.cxxflags)) - .env("AR", &self.config.ar); - - if self.config.target.contains("windows") { - cmd.env("IS_WINDOWS", "1"); - } - } - - let (output, truncated) = - self.read2_abbreviated(cmd.spawn().expect("failed to spawn `make`")); - if !output.status.success() { - let res = ProcRes { - status: output.status, - stdout: String::from_utf8_lossy(&output.stdout).into_owned(), - stderr: String::from_utf8_lossy(&output.stderr).into_owned(), - truncated, - cmdline: format!("{:?}", cmd), - }; - self.fatal_proc_rec("make failed", &res); - } - } - - fn run_rmake_v2_test(&self) { // For `run-make` V2, we need to perform 2 steps to build and run a `run-make` V2 recipe // (`rmake.rs`) to run the actual tests. The support library is already built as a tool rust // library and is available under `build/$TARGET/stageN-tools-bin/librun_make_support.rlib`. @@ -191,8 +29,6 @@ impl TestCx<'_> { // recipes to `remove_dir_all($TMPDIR)` without running into issues related trying to remove // a currently running executable because the recipe executable is not under the // `rmake_out/` directory. - // - // This setup intentionally diverges from legacy Makefile run-make tests. let base_dir = self.output_base_dir(); ignore_not_found(|| recursive_remove(&base_dir)).unwrap(); From 413b824e5b41180b1503a081daf8f23927678add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:43:20 +0800 Subject: [PATCH 521/991] run-make: remove `tools.mk` It has served us well, but it's time to retire the `Makefile` support file since this is no longer needed. --- tests/run-make/tools.mk | 209 ---------------------------------------- 1 file changed, 209 deletions(-) delete mode 100644 tests/run-make/tools.mk diff --git a/tests/run-make/tools.mk b/tests/run-make/tools.mk deleted file mode 100644 index b1e872a202af..000000000000 --- a/tests/run-make/tools.mk +++ /dev/null @@ -1,209 +0,0 @@ -# These deliberately use `=` and not `:=` so that client makefiles can -# augment HOST_RPATH_DIR / TARGET_RPATH_DIR. -HOST_RPATH_ENV = \ - $(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(HOST_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))" -TARGET_RPATH_ENV = \ - $(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(TARGET_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))" - -RUSTC_ORIGINAL := $(RUSTC) -BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)' -BARE_RUSTDOC := $(HOST_RPATH_ENV) '$(RUSTDOC)' -RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS) -Ainternal_features -RUSTDOC := $(BARE_RUSTDOC) -L $(TARGET_RPATH_DIR) -ifdef RUSTC_LINKER -RUSTC := $(RUSTC) -Clinker='$(RUSTC_LINKER)' -RUSTDOC := $(RUSTDOC) -Clinker='$(RUSTC_LINKER)' -endif -#CC := $(CC) -L $(TMPDIR) -HTMLDOCCK := '$(PYTHON)' '$(S)/src/etc/htmldocck.py' -CGREP := "$(S)/src/etc/cat-and-grep.sh" - -# diff with common flags for multi-platform diffs against text output -DIFF := diff -u --strip-trailing-cr - -# With RUSTC_TEST_OP you can elegantly support blessing of run-make tests. Do -# like this in a Makefile recipe: -# -# "$(TMPDIR)"/your-test > "$(TMPDIR)"/your-test.run.stdout -# $(RUSTC_TEST_OP) "$(TMPDIR)"/your-test.run.stdout your-test.run.stdout -# -# When running the test normally with -# -# ./x test tests/run-make/your-test -# -# the actual output will be diffed against the expected output. When running in -# bless-mode with -# -# ./x test --bless tests/run-make/your-test -# -# the actual output will be blessed as the expected output. -ifdef RUSTC_BLESS_TEST - RUSTC_TEST_OP = cp -else - RUSTC_TEST_OP = $(DIFF) -endif - -# Some of the Rust CI platforms use `/bin/dash` to run `shell` script in -# Makefiles. Other platforms, including many developer platforms, default to -# `/bin/bash`. (In many cases, `make` is actually using `/bin/sh`, but `sh` -# is configured to execute one or the other shell binary). `dash` features -# support only a small subset of `bash` features, so `dash` can be thought of as -# the lowest common denominator, and tests should be validated against `dash` -# whenever possible. Most developer platforms include `/bin/dash`, but to ensure -# tests still work when `/bin/dash`, if not available, this `SHELL` override is -# conditional: -ifndef IS_WINDOWS # dash interprets backslashes in executable paths incorrectly -ifneq (,$(wildcard /bin/dash)) -SHELL := /bin/dash -endif -endif - -# This is the name of the binary we will generate and run; use this -# e.g. for `$(CC) -o $(RUN_BINFILE)`. -RUN_BINFILE = $(TMPDIR)/$(1) - -# Invoke the generated binary on the remote machine if compiletest was -# configured to use a remote test device, otherwise run it on the current host. -ifdef REMOTE_TEST_CLIENT -# FIXME: if a test requires additional files, this will need to be changed to -# also push them (by changing the 0 to the number of additional files, and -# providing the path of the additional files as the last arguments). -EXECUTE = $(REMOTE_TEST_CLIENT) run 0 $(RUN_BINFILE) -else -EXECUTE = $(RUN_BINFILE) -endif - -# RUN and FAIL are basic way we will invoke the generated binary. On -# non-windows platforms, they set the LD_LIBRARY_PATH environment -# variable before running the binary. - -RLIB_GLOB = lib$(1)*.rlib -BIN = $(1) - -UNAME = $(shell uname) - -ifeq ($(UNAME),Darwin) -RUN = $(TARGET_RPATH_ENV) $(EXECUTE) -FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0 -DYLIB_GLOB = lib$(1)*.dylib -DYLIB = $(TMPDIR)/lib$(1).dylib -STATICLIB = $(TMPDIR)/lib$(1).a -STATICLIB_GLOB = lib$(1)*.a -else -ifdef IS_WINDOWS -RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) -FAIL = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) && exit 1 || exit 0 -DYLIB_GLOB = $(1)*.dll -DYLIB = $(TMPDIR)/$(1).dll -ifdef IS_MSVC -STATICLIB = $(TMPDIR)/$(1).lib -STATICLIB_GLOB = $(1)*.lib -else -IMPLIB = $(TMPDIR)/lib$(1).dll.a -STATICLIB = $(TMPDIR)/lib$(1).a -STATICLIB_GLOB = lib$(1)*.a -endif -BIN = $(1).exe -LLVM_FILECHECK := $(shell cygpath -u "$(LLVM_FILECHECK)") -else -RUN = $(TARGET_RPATH_ENV) $(EXECUTE) -FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0 -DYLIB_GLOB = lib$(1)*.so -DYLIB = $(TMPDIR)/lib$(1).so -STATICLIB = $(TMPDIR)/lib$(1).a -STATICLIB_GLOB = lib$(1)*.a -endif -endif - -ifdef IS_MSVC -COMPILE_OBJ = $(CC) -c -Fo:`cygpath -w $(1)` $(2) -COMPILE_OBJ_CXX = $(CXX) -EHs -c -Fo:`cygpath -w $(1)` $(2) -NATIVE_STATICLIB_FILE = $(1).lib -NATIVE_STATICLIB = $(TMPDIR)/$(call NATIVE_STATICLIB_FILE,$(1)) -OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \ - -Fo:`cygpath -w $(TMPDIR)/$(1).obj` -else -COMPILE_OBJ = $(CC) -v -c -o $(1) $(2) -COMPILE_OBJ_CXX = $(CXX) -c -o $(1) $(2) -NATIVE_STATICLIB_FILE = lib$(1).a -NATIVE_STATICLIB = $(call STATICLIB,$(1)) -OUT_EXE=-o $(TMPDIR)/$(1) -endif - - -# Extra flags needed to compile a working executable with the standard library -ifdef IS_WINDOWS -ifdef IS_MSVC - EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib -else - EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization - EXTRACXXFLAGS := -lstdc++ - # So this is a bit hacky: we can't use the DLL version of libstdc++ because - # it pulls in the DLL version of libgcc, which means that we end up with 2 - # instances of the DW2 unwinding implementation. This is a problem on - # i686-pc-windows-gnu because each module (DLL/EXE) needs to register its - # unwind information with the unwinding implementation, and libstdc++'s - # __cxa_throw won't see the unwinding info we registered with our statically - # linked libgcc. - # - # Now, simply statically linking libstdc++ would fix this problem, except - # that it is compiled with the expectation that pthreads is dynamically - # linked as a DLL and will fail to link with a statically linked libpthread. - # - # So we end up with the following hack: we link use static:-bundle to only - # link the parts of libstdc++ that we actually use, which doesn't include - # the dependency on the pthreads DLL. - EXTRARSCXXFLAGS := -l static:-bundle=stdc++ -endif -else -ifeq ($(UNAME),Darwin) - EXTRACFLAGS := -lresolv - EXTRACXXFLAGS := -lc++ - EXTRARSCXXFLAGS := -lc++ -else -ifeq ($(UNAME),FreeBSD) - EXTRACFLAGS := -lm -lpthread -lgcc_s -else -ifeq ($(UNAME),SunOS) - EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv -else -ifeq ($(UNAME),OpenBSD) - EXTRACFLAGS := -lm -lpthread -lc++abi - RUSTC := $(RUSTC) -C linker="$(word 1,$(CC:ccache=))" -else - EXTRACFLAGS := -lm -lrt -ldl -lpthread - EXTRACXXFLAGS := -lstdc++ - EXTRARSCXXFLAGS := -lstdc++ -endif -endif -endif -endif -endif - -REMOVE_DYLIBS = rm $(TMPDIR)/$(call DYLIB_GLOB,$(1)) -REMOVE_RLIBS = rm $(TMPDIR)/$(call RLIB_GLOB,$(1)) - -%.a: %.o - $(AR) crus $@ $< -ifdef IS_MSVC -%.lib: lib%.o - $(MSVC_LIB) -out:`cygpath -w $@` $< -else -%.lib: lib%.o - $(AR) crus $@ $< -endif -%.dylib: %.o - $(CC) -dynamiclib -Wl,-dylib -o $@ $< -%.so: %.o - $(CC) -o $@ $< -shared - -ifdef IS_MSVC -%.dll: lib%.o - $(CC) $< -link -dll -out:`cygpath -w $@` -else -%.dll: lib%.o - $(CC) -o $@ $< -shared -Wl,--out-implib=$@.a -endif - -$(TMPDIR)/lib%.o: %.c - $(call COMPILE_OBJ,$@,$<) From 596c14ade49d94bd1cfaa26aa34f7ef016f632d6 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sat, 1 Mar 2025 14:38:07 -0700 Subject: [PATCH 522/991] fix `RangeBounds::is_empty` documentation One-sided ranges are never empty --- library/core/src/ops/range.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index e0c442e52921..1935268cda89 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -827,7 +827,7 @@ pub trait RangeBounds { } /// Returns `true` if the range contains no items. - /// One-sided ranges (`RangeFrom`, etc) always return `true`. + /// One-sided ranges (`RangeFrom`, etc) always return `false`. /// /// # Examples /// From 9b17c98d766f98766494230e65a5ab39c8656d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:35:25 +0800 Subject: [PATCH 523/991] run-make: update test suite README --- tests/run-make/README.md | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/tests/run-make/README.md b/tests/run-make/README.md index 403599034738..5cdd2fdc523c 100644 --- a/tests/run-make/README.md +++ b/tests/run-make/README.md @@ -1,32 +1,17 @@ # The `run-make` test suite -The `run-make` test suite contains tests which are the most flexible out of all -the [rust-lang/rust](https://github.com/rust-lang/rust) test suites. `run-make` -tests can basically contain arbitrary code, and are supported by the -[`run_make_support`] library. +The `run-make` test suite contains tests which are the most flexible out of all the [rust-lang/rust](https://github.com/rust-lang/rust) test suites. `run-make` tests can basically contain arbitrary code, and are supported by the [`run_make_support`] library. ## Infrastructure -There are two kinds of run-make tests: +A `run-make` test is a test recipe source file `rmake.rs` accompanied by its parent directory (e.g. `tests/run-make/foo/rmake.rs` is the `foo` `run-make` test). -1. The new `rmake.rs` version: this allows run-make tests to be written in Rust - (with `rmake.rs` as the main test file). -2. The legacy `Makefile` version: this is what run-make tests were written with - before support for `rmake.rs` was introduced. +The implementation for collecting and building the `rmake.rs` recipes are in [`src/tools/compiletest/src/runtest.rs`](../../src/tools/compiletest/src/runtest.rs), in `run_rmake_test`. -The implementation for collecting and building the `rmake.rs` recipes (or -`Makefile`s) are in -[`src/tools/compiletest/src/runtest.rs`](../../src/tools/compiletest/src/runtest.rs), -in `run_rmake_v2_test` and `run_rmake_legacy_test`. - -### Rust-based `run-make` tests: `rmake.rs` - -The setup for the `rmake.rs` version is a 3-stage process: +The setup for the `rmake.rs` can be summarized as a 3-stage process: 1. First, we build the [`run_make_support`] library in bootstrap as a tool lib. -2. Then, we compile the `rmake.rs` "recipe" linking the support library and its - dependencies in, and provide a bunch of env vars. We setup a directory - structure within `build//test/run-make/` +2. Then, we compile the `rmake.rs` "recipe" linking the support library and its dependencies in, and provide a bunch of env vars. We setup a directory structure within `build//test/run-make/` ``` / @@ -34,15 +19,8 @@ The setup for the `rmake.rs` version is a 3-stage process: rmake_out/ # sources from test sources copied over ``` - and copy non-`rmake.rs` input support files over to `rmake_out/`. The - support library is made available as an [*extern prelude*][extern_prelude]. -3. Finally, we run the recipe binary and set `rmake_out/` as the working - directory. + and copy non-`rmake.rs` input support files over to `rmake_out/`. The support library is made available as an [*extern prelude*][extern_prelude]. +3. Finally, we run the recipe binary and set `rmake_out/` as the working directory. [`run_make_support`]: ../../src/tools/run-make-support [extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude - -### Formatting - -Note that files under `tests/` are not formatted by `./x fmt`, -use `rustfmt tests/path/to/file.rs` to format a specific file if desired. From ed168e7b2bd98b7f044938ab88b791cdee73d85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sun, 2 Mar 2025 05:21:23 +0800 Subject: [PATCH 524/991] run-make-support: remove outdated comments --- .../run-make-support/src/artifact_names.rs | 17 ------ .../src/external_deps/c_cxx_compiler/cc.rs | 11 ---- .../external_deps/c_cxx_compiler/extras.rs | 55 ------------------- .../src/external_deps/rustc.rs | 25 --------- 4 files changed, 108 deletions(-) diff --git a/src/tools/run-make-support/src/artifact_names.rs b/src/tools/run-make-support/src/artifact_names.rs index 0d7b5cb98388..8968f831542e 100644 --- a/src/tools/run-make-support/src/artifact_names.rs +++ b/src/tools/run-make-support/src/artifact_names.rs @@ -8,23 +8,6 @@ use crate::targets::is_msvc; /// Construct the static library name based on the target. #[must_use] pub fn static_lib_name(name: &str) -> String { - // See tools.mk (irrelevant lines omitted): - // - // ```makefile - // ifeq ($(UNAME),Darwin) - // STATICLIB = $(TMPDIR)/lib$(1).a - // else - // ifdef IS_WINDOWS - // ifdef IS_MSVC - // STATICLIB = $(TMPDIR)/$(1).lib - // else - // STATICLIB = $(TMPDIR)/lib$(1).a - // endif - // else - // STATICLIB = $(TMPDIR)/lib$(1).a - // endif - // endif - // ``` assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace"); if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") } diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs index becb91ae989c..0e6d6ea6075d 100644 --- a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs +++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs @@ -80,17 +80,6 @@ impl Cc { /// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler. pub fn out_exe(&mut self, name: &str) -> &mut Self { - // Ref: tools.mk (irrelevant lines omitted): - // - // ```makefile - // ifdef IS_MSVC - // OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \ - // -Fo:`cygpath -w $(TMPDIR)/$(1).obj` - // else - // OUT_EXE=-o $(TMPDIR)/$(1) - // endif - // ``` - let mut path = std::path::PathBuf::from(name); if is_msvc() { diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs index 49210d75e063..ca6ab3275c4d 100644 --- a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs +++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs @@ -2,36 +2,6 @@ use crate::{is_msvc, is_windows, uname}; /// `EXTRACFLAGS` pub fn extra_c_flags() -> Vec<&'static str> { - // Adapted from tools.mk (trimmed): - // - // ```makefile - // ifdef IS_WINDOWS - // ifdef IS_MSVC - // EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib - // else - // EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization - // endif - // else - // ifeq ($(UNAME),Darwin) - // EXTRACFLAGS := -lresolv - // else - // ifeq ($(UNAME),FreeBSD) - // EXTRACFLAGS := -lm -lpthread -lgcc_s - // else - // ifeq ($(UNAME),SunOS) - // EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv - // else - // ifeq ($(UNAME),OpenBSD) - // EXTRACFLAGS := -lm -lpthread -lc++abi - // else - // EXTRACFLAGS := -lm -lrt -ldl -lpthread - // endif - // endif - // endif - // endif - // endif - // ``` - if is_windows() { if is_msvc() { vec![ @@ -60,31 +30,6 @@ pub fn extra_c_flags() -> Vec<&'static str> { /// `EXTRACXXFLAGS` pub fn extra_cxx_flags() -> Vec<&'static str> { - // Adapted from tools.mk (trimmed): - // - // ```makefile - // ifdef IS_WINDOWS - // ifdef IS_MSVC - // else - // EXTRACXXFLAGS := -lstdc++ - // endif - // else - // ifeq ($(UNAME),Darwin) - // EXTRACXXFLAGS := -lc++ - // else - // ifeq ($(UNAME),FreeBSD) - // else - // ifeq ($(UNAME),SunOS) - // else - // ifeq ($(UNAME),OpenBSD) - // else - // EXTRACXXFLAGS := -lstdc++ - // endif - // endif - // endif - // endif - // endif - // ``` if is_windows() { if is_msvc() { vec![] } else { vec!["-lstdc++"] } } else { diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index 710ba025830a..07db42027f0a 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -365,31 +365,6 @@ impl Rustc { /// `EXTRARSCXXFLAGS` pub fn extra_rs_cxx_flags(&mut self) -> &mut Self { - // Adapted from tools.mk (trimmed): - // - // ```makefile - // ifdef IS_WINDOWS - // ifdef IS_MSVC - // else - // EXTRARSCXXFLAGS := -lstatic:-bundle=stdc++ - // endif - // else - // ifeq ($(UNAME),Darwin) - // EXTRARSCXXFLAGS := -lc++ - // else - // ifeq ($(UNAME),FreeBSD) - // else - // ifeq ($(UNAME),SunOS) - // else - // ifeq ($(UNAME),OpenBSD) - // else - // EXTRARSCXXFLAGS := -lstdc++ - // endif - // endif - // endif - // endif - // endif - // ``` if is_windows() { // So this is a bit hacky: we can't use the DLL version of libstdc++ because // it pulls in the DLL version of libgcc, which means that we end up with 2 From efec638308362313fe8c7541cb8f10e6b9a7fe4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:48:48 +0800 Subject: [PATCH 525/991] tidy: remove legacy `Makefile` checks --- .../tidy/src/allowed_run_make_makefiles.txt | 0 src/tools/tidy/src/lib.rs | 1 - src/tools/tidy/src/main.rs | 2 - src/tools/tidy/src/run_make_tests.rs | 104 ------------------ 4 files changed, 107 deletions(-) delete mode 100644 src/tools/tidy/src/allowed_run_make_makefiles.txt delete mode 100644 src/tools/tidy/src/run_make_tests.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 1e7eb82b83e9..9f6d563166e2 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -79,7 +79,6 @@ pub(crate) mod iter_header; pub mod known_bug; pub mod mir_opt_tests; pub mod pal; -pub mod run_make_tests; pub mod rustdoc_css_themes; pub mod rustdoc_gui_tests; pub mod rustdoc_templates; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 13a558fea48e..1d8514ef4c9c 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -103,8 +103,6 @@ fn main() { check!(tests_revision_unpaired_stdout_stderr, &tests_path); check!(debug_artifacts, &tests_path); check!(ui_tests, &root_path, bless); - // FIXME(jieyouxu): remove this check once all run-make tests are ported over to rmake.rs. - check!(run_make_tests, &tests_path, &src_path, bless); check!(mir_opt_tests, &tests_path, bless); check!(rustdoc_gui_tests, &tests_path); check!(rustdoc_css_themes, &librustdoc_path); diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs deleted file mode 100644 index 8d1767878378..000000000000 --- a/src/tools/tidy/src/run_make_tests.rs +++ /dev/null @@ -1,104 +0,0 @@ -//! Tidy check to ensure that no new Makefiles are added under `tests/run-make/`. - -use std::collections::BTreeSet; -use std::fs::File; -use std::io::Write; -use std::path::{Path, PathBuf}; - -pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { - let mut is_sorted = true; - - let allowed_makefiles = { - let mut total_lines = 0; - let mut prev_line = ""; - let allowed_makefiles: BTreeSet<&str> = include_str!("allowed_run_make_makefiles.txt") - .lines() - .map(|line| { - total_lines += 1; - - if prev_line > line { - is_sorted = false; - } - - prev_line = line; - - line - }) - .collect(); - - if !is_sorted && !bless { - tidy_error!( - bad, - "`src/tools/tidy/src/allowed_run_make_makefiles.txt` is not in order, likely \ - because you modified it manually, please only update it with command \ - `x test tidy --bless`" - ); - } - if allowed_makefiles.len() != total_lines { - tidy_error!( - bad, - "`src/tools/tidy/src/allowed_run_make_makefiles.txt` contains duplicate entries, \ - likely because you modified it manually, please only update it with command \ - `x test tidy --bless`" - ); - } - - allowed_makefiles - }; - - let mut remaining_makefiles = allowed_makefiles.clone(); - - crate::walk::walk_no_read( - &[tests_path.join("run-make").as_ref()], - |_, _| false, - &mut |entry| { - if entry.file_type().map_or(true, |t| t.is_dir()) { - return; - } - - if entry.file_name().to_str().map_or(true, |f| f != "Makefile") { - return; - } - - let makefile_path = entry.path().strip_prefix(&tests_path).unwrap(); - let makefile_path = makefile_path.to_str().unwrap().replace('\\', "/"); - - if !remaining_makefiles.remove(makefile_path.as_str()) { - tidy_error!( - bad, - "found run-make Makefile not permitted in \ - `src/tools/tidy/src/allowed_run_make_makefiles.txt`, please write new run-make \ - tests with `rmake.rs` instead: {}", - entry.path().display() - ); - } - }, - ); - - // If there are any expected Makefiles remaining, they were moved or deleted. - // Our data must remain up to date, so they must be removed from - // `src/tools/tidy/src/allowed_run_make_makefiles.txt`. - // This can be done automatically on --bless, or else a tidy error will be issued. - if bless && (!remaining_makefiles.is_empty() || !is_sorted) { - let tidy_src = src_path.join("tools").join("tidy").join("src"); - let org_file_path = tidy_src.join("allowed_run_make_makefiles.txt"); - let temp_file_path = tidy_src.join("blessed_allowed_run_make_makefiles.txt"); - let mut temp_file = t!(File::create_new(&temp_file_path)); - for file in allowed_makefiles.difference(&remaining_makefiles) { - t!(writeln!(temp_file, "{file}")); - } - t!(std::fs::rename(&temp_file_path, &org_file_path)); - } else { - for file in remaining_makefiles { - let mut p = PathBuf::from(tests_path); - p.push(file); - tidy_error!( - bad, - "Makefile `{}` no longer exists and should be removed from the exclusions in \ - `src/tools/tidy/src/allowed_run_make_makefiles.txt`, you can run `x test tidy --bless` to update \ - the allow list", - p.display() - ); - } - } -} From b0d6a8426caf94ed0f822208a55270776149a576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:40:57 +0800 Subject: [PATCH 526/991] rustc-dev-guide: remove mentions of legacy `Makefile` run-make infra And remove outdated requirements to run `run-make` tests on Windows. --- .../rustc-dev-guide/src/tests/compiletest.md | 30 +------------------ .../rustc-dev-guide/src/tests/directives.md | 7 +---- src/doc/rustc-dev-guide/src/tests/running.md | 25 ---------------- 3 files changed, 2 insertions(+), 60 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index 459c082906eb..2905e470fabd 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -74,8 +74,7 @@ The following test suites are available, with links for more information: ### General purpose test suite -[`run-make`](#run-make-tests) are general purpose tests using Rust programs (or -Makefiles (legacy)). +[`run-make`](#run-make-tests) are general purpose tests using Rust programs. ### Rustdoc test suites @@ -396,14 +395,6 @@ your test, causing separate files to be generated for 32bit and 64bit systems. ### `run-make` tests -> **Note on phasing out `Makefile`s** -> -> We are planning to migrate all existing Makefile-based `run-make` tests -> to Rust programs. You should not be adding new Makefile-based `run-make` -> tests. -> -> See . - The tests in [`tests/run-make`] are general-purpose tests using Rust *recipes*, which are small programs (`rmake.rs`) allowing arbitrary Rust code such as `rustc` invocations, and is supported by a [`run_make_support`] library. Using @@ -424,11 +415,6 @@ Compiletest directives like `//@ only-` or `//@ ignore-` are supported in `rmake.rs`, like in UI tests. However, revisions or building auxiliary via directives are not currently supported. -Two `run-make` tests are ported over to Rust recipes as examples: - -- -- - #### Quickly check if `rmake.rs` tests can be compiled You can quickly check if `rmake.rs` tests can be compiled without having to @@ -481,20 +467,6 @@ Then add a corresponding entry to `"rust-analyzer.linkedProjects"` ], ``` -#### Using Makefiles (legacy) - -
-You should avoid writing new Makefile-based `run-make` tests. -
- -Each test should be in a separate directory with a `Makefile` indicating the -commands to run. - -There is a [`tools.mk`] Makefile which you can include which provides a bunch of -utilities to make it easier to run commands and compare outputs. Take a look at -some of the other tests for some examples on how to get started. - -[`tools.mk`]: https://github.com/rust-lang/rust/blob/master/tests/run-make/tools.mk [`tests/run-make`]: https://github.com/rust-lang/rust/tree/master/tests/run-make [`run_make_support`]: https://github.com/rust-lang/rust/tree/master/src/tools/run-make-support diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 00bb2bc4dbb1..c72c7d7d87eb 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -6,10 +6,7 @@ FIXME(jieyouxu) completely revise this chapter. --> -Directives are special comments that tell compiletest how to build and interpret -a test. They must appear before the Rust source in the test. They may also -appear in `rmake.rs` or legacy Makefiles for [run-make -tests](compiletest.md#run-make-tests). +Directives are special comments that tell compiletest how to build and interpret a test. They must appear before the Rust source in the test. They may also appear in `rmake.rs` [run-make tests](compiletest.md#run-make-tests). They are normally put after the short comment that explains the point of this test. Compiletest test suites use `//@` to signal that a comment is a directive. @@ -221,8 +218,6 @@ The following directives will check LLVM support: [`aarch64-gnu-debug`]), which only runs a subset of `run-make` tests. Other tests with this directive will not run at all, which is usually not what you want. - - Notably, the [`aarch64-gnu-debug`] CI job *currently* only runs `run-make` - tests which additionally contain `clang` in their test name. See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for ignoring debuggers. diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md index 6ce65092389b..9ddf0afee0c7 100644 --- a/src/doc/rustc-dev-guide/src/tests/running.md +++ b/src/doc/rustc-dev-guide/src/tests/running.md @@ -238,30 +238,6 @@ This is much faster, but doesn't always work. For example, some tests include directives that specify specific compiler flags, or which rely on other crates, and they may not run the same without those options. -## Running `run-make` tests - -### Windows - -Running the `run-make` test suite on Windows is a currently bit more involved. -There are numerous prerequisites and environmental requirements: - -- Install msys2: -- Specify `MSYS2_PATH_TYPE=inherit` in `msys2.ini` in the msys2 installation directory, run the - following with `MSYS2 MSYS`: - - `pacman -Syuu` - - `pacman -S make` - - `pacman -S diffutils` - - `pacman -S binutils` - - `./x test run-make` (`./x test tests/run-make` doesn't work) - -There is [on-going work][port-run-make] to not rely on `Makefile`s in the -run-make test suite. Once this work is completed, you can run the entire -`run-make` test suite on native Windows inside `cmd` or `PowerShell` without -needing to install and use MSYS2. As of Oct 2024, it is -already possible to run the vast majority of the `run-make` test suite outside -of MSYS2, but there will be failures for the tests that still use `Makefile`s -due to not finding `make`. - ## Running tests on a remote machine Tests may be run on a remote machine (e.g. to test builds for a different @@ -406,4 +382,3 @@ If you encounter bugs or problems, don't hesitate to open issues on the repository](https://github.com/rust-lang/rustc_codegen_gcc/). [`tests/ui`]: https://github.com/rust-lang/rust/tree/master/tests/ui -[port-run-make]: https://github.com/rust-lang/rust/issues/121876 From 95b030f671bdc9652626a7a8490f42027973dfac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:52:30 +0800 Subject: [PATCH 527/991] triagebot: stop backlinking to the test porting tracking issue No longer needed. --- triagebot.toml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index f9eb09ff3438..31683bc67e8d 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -834,13 +834,7 @@ message = "Some changes occurred in GUI tests." cc = ["@GuillaumeGomez"] [mentions."tests/run-make/"] -message = """ -This PR modifies `tests/run-make/`. If this PR is trying to port a Makefile -run-make test to use rmake.rs, please update the -[run-make port tracking issue](https://github.com/rust-lang/rust/issues/121876) -so we can track our progress. You can either modify the tracking issue -directly, or you can comment on the tracking issue and link this PR. -""" +message = "This PR modifies `run-make` tests." cc = ["@jieyouxu"] [mentions."src/rustdoc-json-types"] From c51b229140c885cac757a405a328a07e90d5bca9 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 1 Mar 2025 23:05:19 +0000 Subject: [PATCH 528/991] Disable `f16` on Aarch64 without `neon` LLVM has crashes at some `half` operations when built with assertions enabled if fp-armv8 is not available [1]. Things seem to usually work, but we are reaching LLVM undefined behavior so this needs to be disabled. [1]: https://github.com/llvm/llvm-project/issues/129394 --- library/std/build.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/std/build.rs b/library/std/build.rs index 723d1eb02e07..9df35ce3cc85 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -12,6 +12,11 @@ fn main() { .expect("CARGO_CFG_TARGET_POINTER_WIDTH was not set") .parse() .unwrap(); + let target_features: Vec<_> = env::var("CARGO_CFG_TARGET_FEATURE") + .unwrap_or_default() + .split(",") + .map(ToOwned::to_owned) + .collect(); let is_miri = env::var_os("CARGO_CFG_MIRI").is_some(); println!("cargo:rustc-check-cfg=cfg(netbsd10)"); @@ -101,6 +106,8 @@ fn main() { ("s390x", _) => false, // Unsupported ("arm64ec", _) => false, + // LLVM crash + ("aarch64", _) if !target_features.iter().any(|f| f == "neon") => false, // MinGW ABI bugs ("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false, // Infinite recursion From 60798272d6aa5e9bd45341c637ce55338e349496 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 2 Mar 2025 14:27:53 +1100 Subject: [PATCH 529/991] Adjust triagebot.toml entries for `rustc_mir_build/src/builder/` --- triagebot.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index f9eb09ff3438..7aafe85d9f94 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -771,7 +771,7 @@ cc = ["@fmease"] message = "Some changes occurred in diagnostic error codes" cc = ["@GuillaumeGomez"] -[mentions."compiler/rustc_mir_build/src/build/matches"] +[mentions."compiler/rustc_mir_build/src/builder/matches"] message = "Some changes occurred in match lowering" cc = ["@Nadrieril"] @@ -1031,7 +1031,7 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] message = "Some changes occurred in coverage instrumentation." cc = ["@Zalathar"] -[mentions."compiler/rustc_mir_build/src/build/coverageinfo.rs"] +[mentions."compiler/rustc_mir_build/src/builder/coverageinfo.rs"] message = "Some changes occurred in coverage instrumentation." cc = ["@Zalathar"] @@ -1260,7 +1260,7 @@ project-exploit-mitigations = [ "/compiler/rustc_middle/src/ty" = ["compiler", "types"] "/compiler/rustc_const_eval/src/interpret" = ["compiler", "mir"] "/compiler/rustc_const_eval/src/transform" = ["compiler", "mir-opt"] -"/compiler/rustc_mir_build/src/build" = ["compiler", "mir"] +"/compiler/rustc_mir_build/src/builder" = ["compiler", "mir"] "/compiler/rustc_mir_transform" = ["compiler", "mir", "mir-opt"] "/compiler/rustc_smir" = ["project-stable-mir"] "/compiler/rustc_parse" = ["compiler", "parser"] From 7603e0104a0003a232645fb6c50d63652cbe5b59 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 31 Dec 2024 21:39:13 +0000 Subject: [PATCH 530/991] Simplify parallelization in test-float-parse Currently, test case generators are launched in parallel and their test cases also run in parallel, all within the same pool. I originally implemented this with the assumption that there would be an advantage in parallelizing the generators themselves, but this turns out to not really have any benefit. Simplify things by running generators in series while keeping their test cases parallelized. This makes the code easier to follow, and there is no longer a need for MPSC or multiprogress bars. Additionally, the UI output can be made cleaner. --- .../test-float-parse/src/gen/exhaustive.rs | 3 +- src/etc/test-float-parse/src/gen/fuzz.rs | 1 - src/etc/test-float-parse/src/gen/sparse.rs | 1 - src/etc/test-float-parse/src/lib.rs | 221 +++++------------- src/etc/test-float-parse/src/traits.rs | 2 +- src/etc/test-float-parse/src/ui.rs | 128 ++++++---- src/etc/test-float-parse/src/validate.rs | 46 +++- 7 files changed, 175 insertions(+), 227 deletions(-) diff --git a/src/etc/test-float-parse/src/gen/exhaustive.rs b/src/etc/test-float-parse/src/gen/exhaustive.rs index 5d4b6df8e59b..01458fb0b608 100644 --- a/src/etc/test-float-parse/src/gen/exhaustive.rs +++ b/src/etc/test-float-parse/src/gen/exhaustive.rs @@ -13,13 +13,12 @@ impl Generator for Exhaustive where RangeInclusive: Iterator, { - const NAME: &'static str = "exhaustive"; const SHORT_NAME: &'static str = "exhaustive"; type WriteCtx = F; fn total_tests() -> u64 { - F::Int::MAX.try_into().unwrap_or(u64::MAX) + 1u64.checked_shl(F::Int::BITS).expect("More than u64::MAX tests") } fn new() -> Self { diff --git a/src/etc/test-float-parse/src/gen/fuzz.rs b/src/etc/test-float-parse/src/gen/fuzz.rs index 0c63e8aae26e..7fc999d16711 100644 --- a/src/etc/test-float-parse/src/gen/fuzz.rs +++ b/src/etc/test-float-parse/src/gen/fuzz.rs @@ -49,7 +49,6 @@ impl Generator for Fuzz where Standard: Distribution<::Int>, { - const NAME: &'static str = "fuzz"; const SHORT_NAME: &'static str = "fuzz"; type WriteCtx = F; diff --git a/src/etc/test-float-parse/src/gen/sparse.rs b/src/etc/test-float-parse/src/gen/sparse.rs index 389b71056a3e..72b65d4ce7f1 100644 --- a/src/etc/test-float-parse/src/gen/sparse.rs +++ b/src/etc/test-float-parse/src/gen/sparse.rs @@ -35,7 +35,6 @@ impl Generator for FewOnesInt where >::Error: std::fmt::Debug, { - const NAME: &'static str = "few ones int"; const SHORT_NAME: &'static str = "few ones int"; type WriteCtx = F::Int; diff --git a/src/etc/test-float-parse/src/lib.rs b/src/etc/test-float-parse/src/lib.rs index 3c71b0dc32e7..def66398d9fd 100644 --- a/src/etc/test-float-parse/src/lib.rs +++ b/src/etc/test-float-parse/src/lib.rs @@ -2,19 +2,19 @@ mod traits; mod ui; mod validate; -use std::any::{TypeId, type_name}; +use std::any::type_name; use std::cmp::min; use std::ops::RangeInclusive; use std::process::ExitCode; +use std::sync::OnceLock; use std::sync::atomic::{AtomicU64, Ordering}; -use std::sync::{OnceLock, mpsc}; use std::{fmt, time}; -use indicatif::{MultiProgress, ProgressBar}; use rand::distributions::{Distribution, Standard}; use rayon::prelude::*; use time::{Duration, Instant}; use traits::{Float, Generator, Int}; +use validate::CheckError; /// Test generators. mod gen { @@ -43,7 +43,7 @@ const HUGE_TEST_CUTOFF: u64 = 5_000_000; /// Seed for tests that use a deterministic RNG. const SEED: [u8; 32] = *b"3.141592653589793238462643383279"; -/// Global configuration +/// Global configuration. #[derive(Debug)] pub struct Config { pub timeout: Duration, @@ -104,9 +104,9 @@ pub fn run(cfg: Config, include: &[String], exclude: &[String]) -> ExitCode { println!("Skipping test '{exc}'"); } - println!("launching"); + println!("Launching all"); let elapsed = launch_tests(&mut tests, &cfg); - ui::finish(&tests, elapsed, &cfg) + ui::finish_all(&tests, elapsed, &cfg) } /// Enumerate tests to run but don't actually run them. @@ -160,18 +160,18 @@ where #[derive(Debug)] pub struct TestInfo { pub name: String, - /// Tests are identified by the type ID of `(F, G)` (tuple of the float and generator type). - /// This gives an easy way to associate messages with tests. - id: TypeId, float_name: &'static str, + float_bits: u32, gen_name: &'static str, /// Name for display in the progress bar. short_name: String, + /// Pad the short name to a common width for progress bar use. + short_name_padded: String, total_tests: u64, /// Function to launch this test. - launch: fn(&mpsc::Sender, &TestInfo, &Config), + launch: fn(&TestInfo, &Config), /// Progress bar to be updated. - pb: Option, + progress: Option, /// Once completed, this will be set. completed: OnceLock, } @@ -187,14 +187,18 @@ impl TestInfo { let f_name = type_name::(); let gen_name = G::NAME; let gen_short_name = G::SHORT_NAME; + let name = format!("{f_name} {gen_name}"); + let short_name = format!("{f_name} {gen_short_name}"); + let short_name_padded = format!("{short_name:18}"); let info = TestInfo { - id: TypeId::of::<(F, G)>(), float_name: f_name, + float_bits: F::BITS, gen_name, - pb: None, - name: format!("{f_name} {gen_name}"), - short_name: format!("{f_name} {gen_short_name}"), + progress: None, + name, + short_name_padded, + short_name, launch: test_runner::, total_tests: G::total_tests(), completed: OnceLock::new(), @@ -202,104 +206,16 @@ impl TestInfo { v.push(info); } - /// Pad the short name to a common width for progress bar use. - fn short_name_padded(&self) -> String { - format!("{:18}", self.short_name) - } - - /// Create a progress bar for this test within a multiprogress bar. - fn register_pb(&mut self, mp: &MultiProgress, drop_bars: &mut Vec) { - self.pb = Some(ui::create_pb(mp, self.total_tests, &self.short_name_padded(), drop_bars)); - } - - /// When the test is finished, update progress bar messages and finalize. - fn finalize_pb(&self, c: &Completed) { - let pb = self.pb.as_ref().unwrap(); - ui::finalize_pb(pb, &self.short_name_padded(), c); - } - /// True if this should be run after all others. fn is_huge_test(&self) -> bool { self.total_tests >= HUGE_TEST_CUTOFF } -} -/// A message sent from test runner threads to the UI/log thread. -#[derive(Clone, Debug)] -struct Msg { - id: TypeId, - update: Update, -} - -impl Msg { - /// Wrap an `Update` into a message for the specified type. We use the `TypeId` of `(F, G)` to - /// identify which test a message in the channel came from. - fn new>(u: Update) -> Self { - Self { id: TypeId::of::<(F, G)>(), update: u } + /// When the test is finished, update progress bar messages and finalize. + fn complete(&self, c: Completed) { + self.progress.as_ref().unwrap().complete(&c, 0); + self.completed.set(c).unwrap(); } - - /// Get the matching test from a list. Panics if not found. - fn find_test<'a>(&self, tests: &'a [TestInfo]) -> &'a TestInfo { - tests.iter().find(|t| t.id == self.id).unwrap() - } - - /// Update UI as needed for a single message received from the test runners. - fn handle(self, tests: &[TestInfo], mp: &MultiProgress) { - let test = self.find_test(tests); - let pb = test.pb.as_ref().unwrap(); - - match self.update { - Update::Started => { - mp.println(format!("Testing '{}'", test.name)).unwrap(); - } - Update::Progress { executed, failures } => { - pb.set_message(format! {"{failures}"}); - pb.set_position(executed); - } - Update::Failure { fail, input, float_res } => { - mp.println(format!( - "Failure in '{}': {fail}. parsing '{input}'. Parsed as: {float_res}", - test.name - )) - .unwrap(); - } - Update::Completed(c) => { - test.finalize_pb(&c); - - let prefix = match c.result { - Ok(FinishedAll) => "Completed tests for", - Err(EarlyExit::Timeout) => "Timed out", - Err(EarlyExit::MaxFailures) => "Max failures reached for", - }; - - mp.println(format!( - "{prefix} generator '{}' in {:?}. {} tests run, {} failures", - test.name, c.elapsed, c.executed, c.failures - )) - .unwrap(); - test.completed.set(c).unwrap(); - } - }; - } -} - -/// Status sent with a message. -#[derive(Clone, Debug)] -enum Update { - /// Starting a new test runner. - Started, - /// Completed a out of b tests. - Progress { executed: u64, failures: u64 }, - /// Received a failed test. - Failure { - fail: CheckFailure, - /// String for which parsing was attempted. - input: Box, - /// The parsed & decomposed `FloatRes`, already stringified so we don't need generics here. - float_res: Box, - }, - /// Exited with an unexpected condition. - Completed(Completed), } /// Result of an input did not parsing successfully. @@ -329,6 +245,10 @@ enum CheckFailure { /// two representable values. incorrect_midpoint_rounding: bool, }, + /// String did not parse successfully. + ParsingFailed(Box), + /// A panic was caught. + Panic(Box), } impl fmt::Display for CheckFailure { @@ -363,6 +283,8 @@ impl fmt::Display for CheckFailure { } Ok(()) } + CheckFailure::ParsingFailed(e) => write!(f, "parsing failed: {e}"), + CheckFailure::Panic(e) => write!(f, "function panicked: {e}"), } } } @@ -398,55 +320,21 @@ enum EarlyExit { /// This launches a main thread that receives messages and handlees UI updates, and uses the /// rest of the thread pool to execute the tests. fn launch_tests(tests: &mut [TestInfo], cfg: &Config) -> Duration { - // Run shorter tests first - tests.sort_unstable_by_key(|test| test.total_tests); + // Run shorter tests and smaller float types first. + tests.sort_unstable_by_key(|test| (test.total_tests, test.float_bits)); for test in tests.iter() { println!("Launching test '{}'", test.name); } - // Configure progress bars let mut all_progress_bars = Vec::new(); - let mp = MultiProgress::new(); - mp.set_move_cursor(true); - for test in tests.iter_mut() { - test.register_pb(&mp, &mut all_progress_bars); - } - - ui::set_panic_hook(all_progress_bars); - - let (tx, rx) = mpsc::channel::(); let start = Instant::now(); - rayon::scope(|scope| { - // Thread that updates the UI - scope.spawn(|_scope| { - let rx = rx; // move rx - - loop { - if tests.iter().all(|t| t.completed.get().is_some()) { - break; - } - - let msg = rx.recv().unwrap(); - msg.handle(tests, &mp); - } - - // All tests completed; finish things up - drop(mp); - assert_eq!(rx.try_recv().unwrap_err(), mpsc::TryRecvError::Empty); - }); - - // Don't let the thread pool be starved by huge tests. Run faster tests first in parallel, - // then parallelize only within the rest of the tests. - let (huge_tests, normal_tests): (Vec<_>, Vec<_>) = - tests.iter().partition(|t| t.is_huge_test()); - - // Run the actual tests - normal_tests.par_iter().for_each(|test| ((test.launch)(&tx, test, cfg))); - - huge_tests.par_iter().for_each(|test| ((test.launch)(&tx, test, cfg))); - }); + for test in tests.iter_mut() { + test.progress = Some(ui::Progress::new(test, &mut all_progress_bars)); + ui::set_panic_hook(&all_progress_bars); + ((test.launch)(test, cfg)); + } start.elapsed() } @@ -454,15 +342,12 @@ fn launch_tests(tests: &mut [TestInfo], cfg: &Config) -> Duration { /// Test runer for a single generator. /// /// This calls the generator's iterator multiple times (in parallel) and validates each output. -fn test_runner>(tx: &mpsc::Sender, _info: &TestInfo, cfg: &Config) { - tx.send(Msg::new::(Update::Started)).unwrap(); - - let total = G::total_tests(); +fn test_runner>(test: &TestInfo, cfg: &Config) { let gen = G::new(); let executed = AtomicU64::new(0); let failures = AtomicU64::new(0); - let checks_per_update = min(total, 1000); + let checks_per_update = min(test.total_tests, 1000); let started = Instant::now(); // Function to execute for a single test iteration. @@ -474,7 +359,12 @@ fn test_runner>(tx: &mpsc::Sender, _info: &TestIn match validate::validate::(buf) { Ok(()) => (), Err(e) => { - tx.send(Msg::new::(e)).unwrap(); + let CheckError { fail, input, float_res } = e; + test.progress.as_ref().unwrap().println(&format!( + "Failure in '{}': {fail}. parsing '{input}'. Parsed as: {float_res}", + test.name + )); + let f = failures.fetch_add(1, Ordering::Relaxed); // End early if the limit is exceeded. if f >= cfg.max_failures { @@ -486,9 +376,7 @@ fn test_runner>(tx: &mpsc::Sender, _info: &TestIn // Send periodic updates if executed % checks_per_update == 0 { let failures = failures.load(Ordering::Relaxed); - - tx.send(Msg::new::(Update::Progress { executed, failures })).unwrap(); - + test.progress.as_ref().unwrap().update(executed, failures); if started.elapsed() > cfg.timeout { return Err(EarlyExit::Timeout); } @@ -499,15 +387,19 @@ fn test_runner>(tx: &mpsc::Sender, _info: &TestIn // Run the test iterations in parallel. Each thread gets a string buffer to write // its check values to. - let res = gen.par_bridge().try_for_each_init(|| String::with_capacity(100), check_one); + let res = gen.par_bridge().try_for_each_init(String::new, check_one); let elapsed = started.elapsed(); let executed = executed.into_inner(); let failures = failures.into_inner(); // Warn about bad estimates if relevant. - let warning = if executed != total && res.is_ok() { - let msg = format!("executed tests != estimated ({executed} != {total}) for {}", G::NAME); + let warning = if executed != test.total_tests && res.is_ok() { + let msg = format!( + "executed tests != estimated ({executed} != {}) for {}", + test.total_tests, + G::NAME + ); Some(msg.into()) } else { @@ -515,12 +407,5 @@ fn test_runner>(tx: &mpsc::Sender, _info: &TestIn }; let result = res.map(|()| FinishedAll); - tx.send(Msg::new::(Update::Completed(Completed { - executed, - failures, - result, - warning, - elapsed, - }))) - .unwrap(); + test.complete(Completed { executed, failures, result, warning, elapsed }); } diff --git a/src/etc/test-float-parse/src/traits.rs b/src/etc/test-float-parse/src/traits.rs index f5333d63b369..c8407ba7cc50 100644 --- a/src/etc/test-float-parse/src/traits.rs +++ b/src/etc/test-float-parse/src/traits.rs @@ -177,7 +177,7 @@ impl_float!(f32, u32, 32; f64, u64, 64); /// allocations (which otherwise turn out to be a pretty expensive part of these tests). pub trait Generator: Iterator + Send + 'static { /// Full display and filtering name - const NAME: &'static str; + const NAME: &'static str = Self::SHORT_NAME; /// Name for display with the progress bar const SHORT_NAME: &'static str; diff --git a/src/etc/test-float-parse/src/ui.rs b/src/etc/test-float-parse/src/ui.rs index f333bd4a55dc..1ee57723e6a6 100644 --- a/src/etc/test-float-parse/src/ui.rs +++ b/src/etc/test-float-parse/src/ui.rs @@ -1,67 +1,92 @@ //! Progress bars and such. +use std::any::type_name; +use std::fmt; use std::io::{self, Write}; use std::process::ExitCode; use std::time::Duration; -use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; +use indicatif::{ProgressBar, ProgressStyle}; use crate::{Completed, Config, EarlyExit, FinishedAll, TestInfo}; /// Templates for progress bars. -const PB_TEMPLATE: &str = "[{elapsed:3} {percent:3}%] {bar:20.cyan/blue} NAME ({pos}/{len}, {msg} f, {per_sec}, eta {eta})"; -const PB_TEMPLATE_FINAL: &str = - "[{elapsed:3} {percent:3}%] NAME ({pos}/{len}, {msg:.COLOR}, {per_sec}, {elapsed_precise})"; +const PB_TEMPLATE: &str = "[{elapsed:3} {percent:3}%] {bar:20.cyan/blue} NAME \ + {human_pos:>8}/{human_len:8} {msg} f {per_sec:14} eta {eta:8}"; +const PB_TEMPLATE_FINAL: &str = "[{elapsed:3} {percent:3}%] {bar:20.cyan/blue} NAME \ + {human_pos:>8}/{human_len:8} {msg:.COLOR} {per_sec:18} {elapsed_precise}"; -/// Create a new progress bar within a multiprogress bar. -pub fn create_pb( - mp: &MultiProgress, - total_tests: u64, - short_name_padded: &str, - all_bars: &mut Vec, -) -> ProgressBar { - let pb = mp.add(ProgressBar::new(total_tests)); - let pb_style = ProgressStyle::with_template(&PB_TEMPLATE.replace("NAME", short_name_padded)) - .unwrap() - .progress_chars("##-"); - - pb.set_style(pb_style.clone()); - pb.set_message("0"); - all_bars.push(pb.clone()); - pb +/// Thin abstraction over our usage of a `ProgressBar`. +#[derive(Debug)] +pub struct Progress { + pb: ProgressBar, + make_final_style: NoDebug ProgressStyle + Sync>>, } -/// Removes the status bar and replace it with a message. -pub fn finalize_pb(pb: &ProgressBar, short_name_padded: &str, c: &Completed) { - let f = c.failures; +impl Progress { + /// Create a new progress bar within a multiprogress bar. + pub fn new(test: &TestInfo, all_bars: &mut Vec) -> Self { + let initial_template = PB_TEMPLATE.replace("NAME", &test.short_name_padded); + let final_template = PB_TEMPLATE_FINAL.replace("NAME", &test.short_name_padded); + let initial_style = + ProgressStyle::with_template(&initial_template).unwrap().progress_chars("##-"); + let make_final_style = move |color| { + ProgressStyle::with_template(&final_template.replace("COLOR", color)) + .unwrap() + .progress_chars("##-") + }; - // Use a tuple so we can use colors - let (color, msg, finish_pb): (&str, String, fn(&ProgressBar, String)) = match &c.result { - Ok(FinishedAll) if f > 0 => { - ("red", format!("{f} f (finished with errors)",), ProgressBar::finish_with_message) - } - Ok(FinishedAll) => { - ("green", format!("{f} f (finished successfully)",), ProgressBar::finish_with_message) - } - Err(EarlyExit::Timeout) => { - ("red", format!("{f} f (timed out)"), ProgressBar::abandon_with_message) - } - Err(EarlyExit::MaxFailures) => { - ("red", format!("{f} f (failure limit)"), ProgressBar::abandon_with_message) - } - }; + let pb = ProgressBar::new(test.total_tests); + pb.set_style(initial_style); + pb.set_length(test.total_tests); + pb.set_message("0"); + all_bars.push(pb.clone()); - let pb_style = ProgressStyle::with_template( - &PB_TEMPLATE_FINAL.replace("NAME", short_name_padded).replace("COLOR", color), - ) - .unwrap(); + Progress { pb, make_final_style: NoDebug(Box::new(make_final_style)) } + } - pb.set_style(pb_style); - finish_pb(pb, msg); + /// Completed a out of b tests. + pub fn update(&self, completed: u64, failures: u64) { + // Infrequently update the progress bar. + if completed % 5_000 == 0 || failures > 0 { + self.pb.set_position(completed); + } + + if failures > 0 { + self.pb.set_message(format! {"{failures}"}); + } + } + + /// Finalize the progress bar. + pub fn complete(&self, c: &Completed, real_total: u64) { + let f = c.failures; + let (color, msg, finish_fn): (&str, String, fn(&ProgressBar)) = match &c.result { + Ok(FinishedAll) if f > 0 => { + ("red", format!("{f} f (completed with errors)",), ProgressBar::finish) + } + Ok(FinishedAll) => { + ("green", format!("{f} f (completed successfully)",), ProgressBar::finish) + } + Err(EarlyExit::Timeout) => ("red", format!("{f} f (timed out)"), ProgressBar::abandon), + Err(EarlyExit::MaxFailures) => { + ("red", format!("{f} f (failure limit)"), ProgressBar::abandon) + } + }; + + self.pb.set_position(real_total); + self.pb.set_style(self.make_final_style.0(color)); + self.pb.set_message(msg); + finish_fn(&self.pb); + } + + /// Print a message to stdout above the current progress bar. + pub fn println(&self, msg: &str) { + self.pb.suspend(|| println!("{msg}")); + } } /// Print final messages after all tests are complete. -pub fn finish(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> ExitCode { +pub fn finish_all(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> ExitCode { println!("\n\nResults:"); let mut failed_generators = 0; @@ -118,8 +143,9 @@ pub fn finish(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> Exit /// indicatif likes to eat panic messages. This workaround isn't ideal, but it improves things. /// . -pub fn set_panic_hook(drop_bars: Vec) { +pub fn set_panic_hook(drop_bars: &[ProgressBar]) { let hook = std::panic::take_hook(); + let drop_bars = drop_bars.to_owned(); std::panic::set_hook(Box::new(move |info| { for bar in &drop_bars { bar.abandon(); @@ -130,3 +156,13 @@ pub fn set_panic_hook(drop_bars: Vec) { hook(info); })); } + +/// Allow non-Debug items in a `derive(Debug)` struct`. +#[derive(Clone)] +struct NoDebug(T); + +impl fmt::Debug for NoDebug { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(type_name::()) + } +} diff --git a/src/etc/test-float-parse/src/validate.rs b/src/etc/test-float-parse/src/validate.rs index 1eb3699cfb9f..40dda274e3b8 100644 --- a/src/etc/test-float-parse/src/validate.rs +++ b/src/etc/test-float-parse/src/validate.rs @@ -1,6 +1,6 @@ //! Everything related to verifying that parsed outputs are correct. -use std::any::type_name; +use std::any::{Any, type_name}; use std::collections::BTreeMap; use std::ops::RangeInclusive; use std::str::FromStr; @@ -9,7 +9,7 @@ use std::sync::LazyLock; use num::bigint::ToBigInt; use num::{BigInt, BigRational, FromPrimitive, Signed, ToPrimitive}; -use crate::{CheckFailure, Float, Int, Update}; +use crate::{CheckFailure, Float, Int}; /// Powers of two that we store for constants. Account for binary128 which has a 15-bit exponent. const POWERS_OF_TWO_RANGE: RangeInclusive = (-(2 << 15))..=(2 << 15); @@ -89,10 +89,16 @@ impl Constants { } /// Validate that a string parses correctly -pub fn validate(input: &str) -> Result<(), Update> { - let parsed: F = input - .parse() - .unwrap_or_else(|e| panic!("parsing failed for {}: {e}. Input: {input}", type_name::())); +pub fn validate(input: &str) -> Result<(), CheckError> { + // Catch panics in case debug assertions within `std` fail. + let parsed = std::panic::catch_unwind(|| { + input.parse::().map_err(|e| CheckError { + fail: CheckFailure::ParsingFailed(e.to_string().into()), + input: input.into(), + float_res: "none".into(), + }) + }) + .map_err(|e| convert_panic_error(&e, input))??; // Parsed float, decoded into significand and exponent let decoded = decode(parsed); @@ -104,6 +110,21 @@ pub fn validate(input: &str) -> Result<(), Update> { decoded.check(rational, input) } +/// Turn panics into concrete error types. +fn convert_panic_error(e: &dyn Any, input: &str) -> CheckError { + let msg = e + .downcast_ref::() + .map(|s| s.as_str()) + .or_else(|| e.downcast_ref::<&str>().copied()) + .unwrap_or("(no contents)"); + + CheckError { + fail: CheckFailure::Panic(msg.into()), + input: input.into(), + float_res: "none".into(), + } +} + /// The result of parsing a string to a float type. #[derive(Clone, Copy, Debug, PartialEq)] pub enum FloatRes { @@ -118,10 +139,19 @@ pub enum FloatRes { }, } +#[derive(Clone, Debug)] +pub struct CheckError { + pub fail: CheckFailure, + /// String for which parsing was attempted. + pub input: Box, + /// The parsed & decomposed `FloatRes`, already stringified so we don't need generics here. + pub float_res: Box, +} + impl FloatRes { /// Given a known exact rational, check that this representation is accurate within the /// limits of the float representation. If not, construct a failure `Update` to send. - fn check(self, expected: Rational, input: &str) -> Result<(), Update> { + fn check(self, expected: Rational, input: &str) -> Result<(), CheckError> { let consts = F::constants(); // let bool_helper = |cond: bool, err| cond.then_some(()).ok_or(err); @@ -173,7 +203,7 @@ impl FloatRes { (Rational::Finite(r), FloatRes::Real { sig, exp }) => Self::validate_real(r, sig, exp), }; - res.map_err(|fail| Update::Failure { + res.map_err(|fail| CheckError { fail, input: input.into(), float_res: format!("{self:?}").into(), From 1b85befbd9ffd44b8effc9607baec40a483c7d28 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 2 Mar 2025 08:03:01 +0100 Subject: [PATCH 531/991] Add flip or-pattern assist --- .../crates/ide-assists/src/assist_context.rs | 20 ++++- .../ide-assists/src/handlers/flip_comma.rs | 49 +++++------- .../src/handlers/flip_or_pattern.rs | 80 +++++++++++++++++++ .../src/handlers/flip_trait_bound.rs | 9 +-- .../crates/ide-assists/src/lib.rs | 2 + .../crates/ide-assists/src/tests/generated.rs | 17 ++++ .../docs/book/src/assists_generated.md | 24 +++++- 7 files changed, 159 insertions(+), 42 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs index 64e77b2d6982..b1189f0d0b06 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs @@ -52,6 +52,10 @@ pub(crate) struct AssistContext<'a> { frange: FileRange, trimmed_range: TextRange, source_file: SourceFile, + // We cache this here to speed up things slightly + token_at_offset: TokenAtOffset, + // We cache this here to speed up things slightly + covering_element: SyntaxElement, } impl<'a> AssistContext<'a> { @@ -78,8 +82,18 @@ impl<'a> AssistContext<'a> { // Selection solely consists of whitespace so just fall back to the original _ => frange.range, }; + let token_at_offset = source_file.syntax().token_at_offset(frange.range.start()); + let covering_element = source_file.syntax().covering_element(trimmed_range); - AssistContext { config, sema, frange, source_file, trimmed_range } + AssistContext { + config, + sema, + frange, + source_file, + trimmed_range, + token_at_offset, + covering_element, + } } pub(crate) fn db(&self) -> &RootDatabase { @@ -114,7 +128,7 @@ impl<'a> AssistContext<'a> { } pub(crate) fn token_at_offset(&self) -> TokenAtOffset { - self.source_file.syntax().token_at_offset(self.offset()) + self.token_at_offset.clone() } pub(crate) fn find_token_syntax_at_offset(&self, kind: SyntaxKind) -> Option { self.token_at_offset().find(|it| it.kind() == kind) @@ -136,7 +150,7 @@ impl<'a> AssistContext<'a> { } /// Returns the element covered by the selection range, this excludes trailing whitespace in the selection. pub(crate) fn covering_element(&self) -> SyntaxElement { - self.source_file.syntax().covering_element(self.selection_trimmed()) + self.covering_element.clone() } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs index 95e035c05379..dd27269b001c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs @@ -1,8 +1,8 @@ use syntax::{ algo::non_trivia_sibling, ast::{self, syntax_factory::SyntaxFactory}, - syntax_editor::{Element, SyntaxMapping}, - AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxToken, T, + syntax_editor::SyntaxMapping, + AstNode, Direction, NodeOrToken, SyntaxKind, SyntaxToken, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -39,37 +39,24 @@ pub(crate) fn flip_comma(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( return None; } - let prev = match prev { - SyntaxElement::Node(node) => node.syntax_element(), - _ => prev, - }; - let next = match next { - SyntaxElement::Node(node) => node.syntax_element(), - _ => next, - }; + let target = comma.text_range(); + acc.add(AssistId("flip_comma", AssistKind::RefactorRewrite), "Flip comma", target, |builder| { + let parent = comma.parent().unwrap(); + let mut editor = builder.make_editor(&parent); - acc.add( - AssistId("flip_comma", AssistKind::RefactorRewrite), - "Flip comma", - comma.text_range(), - |builder| { - let parent = comma.parent().unwrap(); - let mut editor = builder.make_editor(&parent); + if let Some(parent) = ast::TokenTree::cast(parent) { + // An attribute. It often contains a path followed by a + // token tree (e.g. `align(2)`), so we have to be smarter. + let (new_tree, mapping) = flip_tree(parent.clone(), comma); + editor.replace(parent.syntax(), new_tree.syntax()); + editor.add_mappings(mapping); + } else { + editor.replace(prev.clone(), next.clone()); + editor.replace(next.clone(), prev.clone()); + } - if let Some(parent) = ast::TokenTree::cast(parent) { - // An attribute. It often contains a path followed by a - // token tree (e.g. `align(2)`), so we have to be smarter. - let (new_tree, mapping) = flip_tree(parent.clone(), comma); - editor.replace(parent.syntax(), new_tree.syntax()); - editor.add_mappings(mapping); - } else { - editor.replace(prev.clone(), next.clone()); - editor.replace(next.clone(), prev.clone()); - } - - builder.add_file_edits(ctx.file_id(), editor); - }, - ) + builder.add_file_edits(ctx.file_id(), editor); + }) } fn flip_tree(tree: ast::TokenTree, comma: SyntaxToken) -> (ast::TokenTree, SyntaxMapping) { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs new file mode 100644 index 000000000000..d9fa03e7191b --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs @@ -0,0 +1,80 @@ +use syntax::{ + algo::non_trivia_sibling, + ast::{self, AstNode}, + Direction, T, +}; + +use crate::{AssistContext, AssistId, AssistKind, Assists}; + +// Assist: flip_or_pattern +// +// Flips two patterns in an or-pattern. +// +// ``` +// fn foo() { +// let (a |$0 b) = 1; +// } +// ``` +// -> +// ``` +// fn foo() { +// let (b | a) = 1; +// } +// ``` +pub(crate) fn flip_or_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + // Only flip on the `|` token + let pipe = ctx.find_token_syntax_at_offset(T![|])?; + + let parent = ast::OrPat::cast(pipe.parent()?)?; + + let before = non_trivia_sibling(pipe.clone().into(), Direction::Prev)?.into_node()?; + let after = non_trivia_sibling(pipe.clone().into(), Direction::Next)?.into_node()?; + + let target = pipe.text_range(); + acc.add( + AssistId("flip_or_pattern", AssistKind::RefactorRewrite), + "Flip patterns", + target, + |builder| { + let mut editor = builder.make_editor(parent.syntax()); + editor.replace(before.clone(), after.clone()); + editor.replace(after, before); + builder.add_file_edits(ctx.file_id(), editor); + }, + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; + + #[test] + fn flip_or_pattern_assist_available() { + check_assist_target(flip_or_pattern, "fn main(a |$0 b: ()) {}", "|") + } + + #[test] + fn flip_or_pattern_not_applicable_for_leading_pipe() { + check_assist_not_applicable(flip_or_pattern, "fn main(|$0 b: ()) {}") + } + + #[test] + fn flip_or_pattern_works() { + check_assist( + flip_or_pattern, + "fn foo() { let (a | b |$0 c | d) = 1; }", + "fn foo() { let (a | c | b | d) = 1; }", + ) + } + + #[test] + fn flip_or_pattern_works_match_guard() { + check_assist( + flip_or_pattern, + "fn foo() { match() { a |$0 b if true => () }}", + "fn foo() { match() { b | a if true => () }}", + ) + } +} diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs index 298e5bd82c98..3528f5e81324 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs @@ -18,17 +18,14 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // fn foo() { } // ``` pub(crate) fn flip_trait_bound(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - // We want to replicate the behavior of `flip_binexpr` by only suggesting - // the assist when the cursor is on a `+` + // Only flip on the `+` token let plus = ctx.find_token_syntax_at_offset(T![+])?; // Make sure we're in a `TypeBoundList` let parent = ast::TypeBoundList::cast(plus.parent()?)?; - let (before, after) = ( - non_trivia_sibling(plus.clone().into(), Direction::Prev)?.into_node()?, - non_trivia_sibling(plus.clone().into(), Direction::Next)?.into_node()?, - ); + let before = non_trivia_sibling(plus.clone().into(), Direction::Prev)?.into_node()?; + let after = non_trivia_sibling(plus.clone().into(), Direction::Next)?.into_node()?; let target = plus.text_range(); acc.add( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index 179742f91b4d..448bcadb8ef2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -149,6 +149,7 @@ mod handlers { mod fix_visibility; mod flip_binexpr; mod flip_comma; + mod flip_or_pattern; mod flip_trait_bound; mod generate_constant; mod generate_default_from_enum_variant; @@ -279,6 +280,7 @@ mod handlers { fix_visibility::fix_visibility, flip_binexpr::flip_binexpr, flip_comma::flip_comma, + flip_or_pattern::flip_or_pattern, flip_trait_bound::flip_trait_bound, generate_constant::generate_constant, generate_default_from_enum_variant::generate_default_from_enum_variant, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 74ae126adae8..91c1a3e1bd79 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -1195,6 +1195,23 @@ fn main() { ) } +#[test] +fn doctest_flip_or_pattern() { + check_doc_test( + "flip_or_pattern", + r#####" +fn foo() { + let (a |$0 b) = 1; +} +"#####, + r#####" +fn foo() { + let (b | a) = 1; +} +"#####, + ) +} + #[test] fn doctest_flip_trait_bound() { check_doc_test( diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 2d233ca62ad6..8efc7cbabe9c 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -257,7 +257,7 @@ fn main() { ### `apply_demorgan` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L16) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L23) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws). This transforms expressions of the form `!l || !r` into `!(l && r)`. @@ -280,7 +280,7 @@ fn main() { ### `apply_demorgan_iterator` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L147) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L154) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to `Iterator::all` and `Iterator::any`. @@ -1345,6 +1345,26 @@ fn main() { ``` +### `flip_or_pattern` +**Source:** [flip_or_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_or_pattern.rs#L9) + +Flips two trait bounds. + +#### Before +```rust +fn foo() { + let (a |┃ b) = 1; +} +``` + +#### After +```rust +fn foo() { + let (b | a) = 1; +} +``` + + ### `flip_trait_bound` **Source:** [flip_trait_bound.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_trait_bound.rs#L9) From a0ed304c2101b4efdaf9982189e8d6ca73690712 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 9 Dec 2024 09:25:21 +0000 Subject: [PATCH 532/991] float: Update some constants to `pub(crate)` These constants can be useful outside of their current module. Make them `pub(crate)` to allow for this. --- library/core/src/num/f32.rs | 6 +++--- library/core/src/num/f64.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index a200fd531866..de1557ccc902 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -493,13 +493,13 @@ impl f32 { pub const NEG_INFINITY: f32 = -1.0_f32 / 0.0_f32; /// Sign bit - const SIGN_MASK: u32 = 0x8000_0000; + pub(crate) const SIGN_MASK: u32 = 0x8000_0000; /// Exponent mask - const EXP_MASK: u32 = 0x7f80_0000; + pub(crate) const EXP_MASK: u32 = 0x7f80_0000; /// Mantissa mask - const MAN_MASK: u32 = 0x007f_ffff; + pub(crate) const MAN_MASK: u32 = 0x007f_ffff; /// Minimum representable positive value (min subnormal) const TINY_BITS: u32 = 0x1; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index de63a462b61a..65b5f3b9af09 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -492,13 +492,13 @@ impl f64 { pub const NEG_INFINITY: f64 = -1.0_f64 / 0.0_f64; /// Sign bit - const SIGN_MASK: u64 = 0x8000_0000_0000_0000; + pub(crate) const SIGN_MASK: u64 = 0x8000_0000_0000_0000; /// Exponent mask - const EXP_MASK: u64 = 0x7ff0_0000_0000_0000; + pub(crate) const EXP_MASK: u64 = 0x7ff0_0000_0000_0000; /// Mantissa mask - const MAN_MASK: u64 = 0x000f_ffff_ffff_ffff; + pub(crate) const MAN_MASK: u64 = 0x000f_ffff_ffff_ffff; /// Minimum representable positive value (min subnormal) const TINY_BITS: u64 = 0x1; From 5a2da96a44abad6be752c7ee1cac173aa1ca2f7c Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 9 Dec 2024 09:25:22 +0000 Subject: [PATCH 533/991] dec2flt: Update documentation of existing methods Fix or elaborate existing float parsing documentation. This includes introducing a convention that should make naming more consistent. --- library/core/src/num/dec2flt/common.rs | 14 ++++++++------ library/core/src/num/dec2flt/decimal.rs | 22 +++++++++++++--------- library/core/src/num/dec2flt/mod.rs | 16 ++++++++++++++-- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/library/core/src/num/dec2flt/common.rs b/library/core/src/num/dec2flt/common.rs index 4dadf406ae8c..1646d3a95d3b 100644 --- a/library/core/src/num/dec2flt/common.rs +++ b/library/core/src/num/dec2flt/common.rs @@ -8,12 +8,12 @@ pub(crate) trait ByteSlice { /// Writes a 64-bit integer as 8 bytes in little-endian order. fn write_u64(&mut self, value: u64); - /// Calculate the offset of a slice from another. + /// Calculate the difference in length between two slices. fn offset_from(&self, other: &Self) -> isize; /// Iteratively parse and consume digits from bytes. - /// Returns the same bytes with consumed digits being - /// elided. + /// + /// Returns the same bytes with consumed digits being elided. Breaks on invalid digits. fn parse_digits(&self, func: impl FnMut(u8)) -> &Self; } @@ -39,11 +39,11 @@ impl ByteSlice for [u8] { fn parse_digits(&self, mut func: impl FnMut(u8)) -> &Self { let mut s = self; - while let Some((c, s_next)) = s.split_first() { + while let Some((c, rest)) = s.split_first() { let c = c.wrapping_sub(b'0'); if c < 10 { func(c); - s = s_next; + s = rest; } else { break; } @@ -53,7 +53,9 @@ impl ByteSlice for [u8] { } } -/// Determine if 8 bytes are all decimal digits. +/// Determine if all characters in an 8-byte byte string (represented as a `u64`) are all decimal +/// digits. +/// /// This does not care about the order in which the bytes were loaded. pub(crate) fn is_8digits(v: u64) -> bool { let a = v.wrapping_add(0x4646_4646_4646_4646); diff --git a/library/core/src/num/dec2flt/decimal.rs b/library/core/src/num/dec2flt/decimal.rs index b37724ba62d5..a84e11ec8e71 100644 --- a/library/core/src/num/dec2flt/decimal.rs +++ b/library/core/src/num/dec2flt/decimal.rs @@ -1,4 +1,4 @@ -//! Arbitrary-precision decimal class for fallback algorithms. +//! Arbitrary-precision decimal type used by fallback algorithms. //! //! This is only used if the fast-path (native floats) and //! the Eisel-Lemire algorithm are unable to unambiguously @@ -11,6 +11,7 @@ use crate::num::dec2flt::common::{ByteSlice, is_8digits}; +/// A decimal floating-point number. #[derive(Clone)] pub(super) struct Decimal { /// The number of significant digits in the decimal. @@ -30,18 +31,17 @@ impl Default for Decimal { } impl Decimal { - /// The maximum number of digits required to unambiguously round a float. + /// The maximum number of digits required to unambiguously round up to a 64-bit float. /// - /// For a double-precision IEEE 754 float, this required 767 digits, - /// so we store the max digits + 1. + /// For an IEEE 754 binary64 float, this required 767 digits. So we store the max digits + 1. /// /// We can exactly represent a float in radix `b` from radix 2 if /// `b` is divisible by 2. This function calculates the exact number of /// digits required to exactly represent that float. /// /// According to the "Handbook of Floating Point Arithmetic", - /// for IEEE754, with emin being the min exponent, p2 being the - /// precision, and b being the radix, the number of digits follows as: + /// for IEEE754, with `emin` being the min exponent, `p2` being the + /// precision, and `b` being the radix, the number of digits follows as: /// /// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋` /// @@ -56,11 +56,14 @@ impl Decimal { /// In Python: /// `-emin + p2 + math.floor((emin+ 1)*math.log(2, b)-math.log(1-2**(-p2), b))` pub(super) const MAX_DIGITS: usize = 768; - /// The max digits that can be exactly represented in a 64-bit integer. + /// The max decimal digits that can be exactly represented in a 64-bit integer. pub(super) const MAX_DIGITS_WITHOUT_OVERFLOW: usize = 19; pub(super) const DECIMAL_POINT_RANGE: i32 = 2047; - /// Append a digit to the buffer. + /// Append a digit to the buffer if it fits. + // FIXME(tgross35): it may be better for this to return an option + // FIXME(tgross35): incrementing the digit counter even if we don't push anything + // seems incorrect. pub(super) fn try_add_digit(&mut self, digit: u8) { if self.num_digits < Self::MAX_DIGITS { self.digits[self.num_digits] = digit; @@ -69,6 +72,7 @@ impl Decimal { } /// Trim trailing zeros from the buffer. + // FIXME(tgross35): this could be `.rev().position()` if perf is okay pub(super) fn trim(&mut self) { // All of the following calls to `Decimal::trim` can't panic because: // @@ -86,7 +90,7 @@ impl Decimal { pub(super) fn round(&self) -> u64 { if self.num_digits == 0 || self.decimal_point < 0 { return 0; - } else if self.decimal_point > 18 { + } else if self.decimal_point >= Self::MAX_DIGITS_WITHOUT_OVERFLOW as i32 { return 0xFFFF_FFFF_FFFF_FFFF_u64; } let dp = self.decimal_point as usize; diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 6dca74068453..91bfe1bef2e7 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -3,8 +3,8 @@ //! # Problem statement //! //! We are given a decimal string such as `12.34e56`. This string consists of integral (`12`), -//! fractional (`34`), and exponent (`56`) parts. All parts are optional and interpreted as zero -//! when missing. +//! fractional (`34`), and exponent (`56`) parts. All parts are optional and interpreted as a +//! default value (1 or 0) when missing. //! //! We seek the IEEE 754 floating point number that is closest to the exact value of the decimal //! string. It is well-known that many decimal strings do not have terminating representations in @@ -67,6 +67,18 @@ //! "such that the exponent +/- the number of decimal digits fits into a 64 bit integer". //! Larger exponents are accepted, but we don't do arithmetic with them, they are immediately //! turned into {positive,negative} {zero,infinity}. +//! +//! # Notation +//! +//! This module uses the same notation as the Lemire paper: +//! +//! - `m`: binary mantissa; always nonnegative +//! - `p`: binary exponent; a signed integer +//! - `w`: decimal significand; always nonnegative +//! - `q`: decimal exponent; a signed integer +//! +//! This gives `m * 2^p` for the binary floating-point number, with `w * 10^q` as the decimal +//! equivalent. #![doc(hidden)] #![unstable( From 49a2d4c757e27f915d15664ba92bbe0d3f590a8e Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 9 Dec 2024 09:25:22 +0000 Subject: [PATCH 534/991] dec2flt: Rename `Decimal` to `DecimalSeq` This module currently contains two decimal types, `Decimal` and `Number`. These names don't provide a whole lot of insight into what exactly they are, and `Number` is actually the one that is more like an expected `Decimal` type. In accordance with this, rename the existing `Decimal` to `DecimalSeq`. This highlights that it contains a sequence of decimal digits, rather than representing a base-10 floating point (decimal) number. Additionally, add some tests to validate internal behavior. --- .../dec2flt/{decimal.rs => decimal_seq.rs} | 51 ++++++++++++------- library/core/src/num/dec2flt/mod.rs | 2 +- library/core/src/num/dec2flt/slow.rs | 8 +-- .../tests/num/dec2flt/decimal_seq.rs | 30 +++++++++++ library/coretests/tests/num/dec2flt/mod.rs | 1 + 5 files changed, 70 insertions(+), 22 deletions(-) rename library/core/src/num/dec2flt/{decimal.rs => decimal_seq.rs} (94%) create mode 100644 library/coretests/tests/num/dec2flt/decimal_seq.rs diff --git a/library/core/src/num/dec2flt/decimal.rs b/library/core/src/num/dec2flt/decimal_seq.rs similarity index 94% rename from library/core/src/num/dec2flt/decimal.rs rename to library/core/src/num/dec2flt/decimal_seq.rs index a84e11ec8e71..de22280c001c 100644 --- a/library/core/src/num/dec2flt/decimal.rs +++ b/library/core/src/num/dec2flt/decimal_seq.rs @@ -11,9 +11,9 @@ use crate::num::dec2flt::common::{ByteSlice, is_8digits}; -/// A decimal floating-point number. -#[derive(Clone)] -pub(super) struct Decimal { +/// A decimal floating-point number, represented as a sequence of decimal digits. +#[derive(Clone, Debug, PartialEq)] +pub struct DecimalSeq { /// The number of significant digits in the decimal. pub num_digits: usize, /// The offset of the decimal point in the significant digits. @@ -24,13 +24,13 @@ pub(super) struct Decimal { pub digits: [u8; Self::MAX_DIGITS], } -impl Default for Decimal { +impl Default for DecimalSeq { fn default() -> Self { Self { num_digits: 0, decimal_point: 0, truncated: false, digits: [0; Self::MAX_DIGITS] } } } -impl Decimal { +impl DecimalSeq { /// The maximum number of digits required to unambiguously round up to a 64-bit float. /// /// For an IEEE 754 binary64 float, this required 767 digits. So we store the max digits + 1. @@ -55,7 +55,8 @@ impl Decimal { /// /// In Python: /// `-emin + p2 + math.floor((emin+ 1)*math.log(2, b)-math.log(1-2**(-p2), b))` - pub(super) const MAX_DIGITS: usize = 768; + pub const MAX_DIGITS: usize = 768; + /// The max decimal digits that can be exactly represented in a 64-bit integer. pub(super) const MAX_DIGITS_WITHOUT_OVERFLOW: usize = 19; pub(super) const DECIMAL_POINT_RANGE: i32 = 2047; @@ -73,12 +74,12 @@ impl Decimal { /// Trim trailing zeros from the buffer. // FIXME(tgross35): this could be `.rev().position()` if perf is okay - pub(super) fn trim(&mut self) { - // All of the following calls to `Decimal::trim` can't panic because: + pub fn trim(&mut self) { + // All of the following calls to `DecimalSeq::trim` can't panic because: // - // 1. `parse_decimal` sets `num_digits` to a max of `Decimal::MAX_DIGITS`. + // 1. `parse_decimal` sets `num_digits` to a max of `DecimalSeq::MAX_DIGITS`. // 2. `right_shift` sets `num_digits` to `write_index`, which is bounded by `num_digits`. - // 3. `left_shift` `num_digits` to a max of `Decimal::MAX_DIGITS`. + // 3. `left_shift` `num_digits` to a max of `DecimalSeq::MAX_DIGITS`. // // Trim is only called in `right_shift` and `left_shift`. debug_assert!(self.num_digits <= Self::MAX_DIGITS); @@ -93,21 +94,26 @@ impl Decimal { } else if self.decimal_point >= Self::MAX_DIGITS_WITHOUT_OVERFLOW as i32 { return 0xFFFF_FFFF_FFFF_FFFF_u64; } + let dp = self.decimal_point as usize; let mut n = 0_u64; + for i in 0..dp { n *= 10; if i < self.num_digits { n += self.digits[i] as u64; } } + let mut round_up = false; + if dp < self.num_digits { round_up = self.digits[dp] >= 5; if self.digits[dp] == 5 && dp + 1 == self.num_digits { round_up = self.truncated || ((dp != 0) && (1 & self.digits[dp - 1] != 0)) } } + if round_up { n += 1; } @@ -123,6 +129,7 @@ impl Decimal { let mut read_index = self.num_digits; let mut write_index = self.num_digits + num_new_digits; let mut n = 0_u64; + while read_index != 0 { read_index -= 1; write_index -= 1; @@ -136,6 +143,7 @@ impl Decimal { } n = quotient; } + while n > 0 { write_index -= 1; let quotient = n / 10; @@ -147,10 +155,13 @@ impl Decimal { } n = quotient; } + self.num_digits += num_new_digits; + if self.num_digits > Self::MAX_DIGITS { self.num_digits = Self::MAX_DIGITS; } + self.decimal_point += num_new_digits as i32; self.trim(); } @@ -206,8 +217,8 @@ impl Decimal { } /// Parse a big integer representation of the float as a decimal. -pub(super) fn parse_decimal(mut s: &[u8]) -> Decimal { - let mut d = Decimal::default(); +pub fn parse_decimal_seq(mut s: &[u8]) -> DecimalSeq { + let mut d = DecimalSeq::default(); let start = s; while let Some((&b'0', s_next)) = s.split_first() { @@ -225,7 +236,7 @@ pub(super) fn parse_decimal(mut s: &[u8]) -> Decimal { s = s_next; } } - while s.len() >= 8 && d.num_digits + 8 < Decimal::MAX_DIGITS { + while s.len() >= 8 && d.num_digits + 8 < DecimalSeq::MAX_DIGITS { let v = s.read_u64(); if !is_8digits(v) { break; @@ -237,6 +248,7 @@ pub(super) fn parse_decimal(mut s: &[u8]) -> Decimal { s = s.parse_digits(|digit| d.try_add_digit(digit)); d.decimal_point = s.len() as i32 - first.len() as i32; } + if d.num_digits != 0 { // Ignore the trailing zeros if there are any let mut n_trailing_zeros = 0; @@ -250,11 +262,12 @@ pub(super) fn parse_decimal(mut s: &[u8]) -> Decimal { d.decimal_point += n_trailing_zeros as i32; d.num_digits -= n_trailing_zeros; d.decimal_point += d.num_digits as i32; - if d.num_digits > Decimal::MAX_DIGITS { + if d.num_digits > DecimalSeq::MAX_DIGITS { d.truncated = true; - d.num_digits = Decimal::MAX_DIGITS; + d.num_digits = DecimalSeq::MAX_DIGITS; } } + if let Some((&ch, s_next)) = s.split_first() { if ch == b'e' || ch == b'E' { s = s_next; @@ -276,13 +289,15 @@ pub(super) fn parse_decimal(mut s: &[u8]) -> Decimal { d.decimal_point += if neg_exp { -exp_num } else { exp_num }; } } - for i in d.num_digits..Decimal::MAX_DIGITS_WITHOUT_OVERFLOW { + + for i in d.num_digits..DecimalSeq::MAX_DIGITS_WITHOUT_OVERFLOW { d.digits[i] = 0; } + d } -fn number_of_digits_decimal_left_shift(d: &Decimal, mut shift: usize) -> usize { +fn number_of_digits_decimal_left_shift(d: &DecimalSeq, mut shift: usize) -> usize { #[rustfmt::skip] const TABLE: [u16; 65] = [ 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, 0x181D, 0x2024, @@ -347,6 +362,7 @@ fn number_of_digits_decimal_left_shift(d: &Decimal, mut shift: usize) -> usize { let pow5_a = (0x7FF & x_a) as usize; let pow5_b = (0x7FF & x_b) as usize; let pow5 = &TABLE_POW5[pow5_a..]; + for (i, &p5) in pow5.iter().enumerate().take(pow5_b - pow5_a) { if i >= d.num_digits { return num_new_digits - 1; @@ -358,5 +374,6 @@ fn number_of_digits_decimal_left_shift(d: &Decimal, mut shift: usize) -> usize { return num_new_digits; } } + num_new_digits } diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 91bfe1bef2e7..471505d24940 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -97,7 +97,7 @@ use crate::fmt; use crate::str::FromStr; mod common; -mod decimal; +pub mod decimal_seq; mod fpu; mod slow; mod table; diff --git a/library/core/src/num/dec2flt/slow.rs b/library/core/src/num/dec2flt/slow.rs index 85d4b13284b7..e274e1aa0aa1 100644 --- a/library/core/src/num/dec2flt/slow.rs +++ b/library/core/src/num/dec2flt/slow.rs @@ -1,7 +1,7 @@ //! Slow, fallback algorithm for cases the Eisel-Lemire algorithm cannot round. use crate::num::dec2flt::common::BiasedFp; -use crate::num::dec2flt::decimal::{Decimal, parse_decimal}; +use crate::num::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq}; use crate::num::dec2flt::float::RawFloat; /// Parse the significant digits and biased, binary exponent of a float. @@ -36,7 +36,7 @@ pub(crate) fn parse_long_mantissa(s: &[u8]) -> BiasedFp { let fp_zero = BiasedFp::zero_pow2(0); let fp_inf = BiasedFp::zero_pow2(F::INFINITE_POWER); - let mut d = parse_decimal(s); + let mut d = parse_decimal_seq(s); // Short-circuit if the value can only be a literal 0 or infinity. if d.num_digits == 0 || d.decimal_point < -324 { @@ -50,7 +50,7 @@ pub(crate) fn parse_long_mantissa(s: &[u8]) -> BiasedFp { let n = d.decimal_point as usize; let shift = get_shift(n); d.right_shift(shift); - if d.decimal_point < -Decimal::DECIMAL_POINT_RANGE { + if d.decimal_point < -DecimalSeq::DECIMAL_POINT_RANGE { return fp_zero; } exp2 += shift as i32; @@ -67,7 +67,7 @@ pub(crate) fn parse_long_mantissa(s: &[u8]) -> BiasedFp { get_shift((-d.decimal_point) as _) }; d.left_shift(shift); - if d.decimal_point > Decimal::DECIMAL_POINT_RANGE { + if d.decimal_point > DecimalSeq::DECIMAL_POINT_RANGE { return fp_inf; } exp2 -= shift as i32; diff --git a/library/coretests/tests/num/dec2flt/decimal_seq.rs b/library/coretests/tests/num/dec2flt/decimal_seq.rs new file mode 100644 index 000000000000..f46ba7c465a6 --- /dev/null +++ b/library/coretests/tests/num/dec2flt/decimal_seq.rs @@ -0,0 +1,30 @@ +use core::num::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq}; + +#[test] +fn test_trim() { + let mut dec = DecimalSeq::default(); + let digits = [1, 2, 3, 4]; + + dec.digits[0..4].copy_from_slice(&digits); + dec.num_digits = 8; + dec.trim(); + + assert_eq!(dec.digits[0..4], digits); + assert_eq!(dec.num_digits, 4); +} + +#[test] +fn test_parse() { + let tests = [("1.234", [1, 2, 3, 4], 1)]; + + for (s, exp_digits, decimal_point) in tests { + let actual = parse_decimal_seq(s.as_bytes()); + let mut digits = [0; DecimalSeq::MAX_DIGITS]; + digits[..exp_digits.len()].copy_from_slice(&exp_digits); + + let expected = + DecimalSeq { num_digits: exp_digits.len(), decimal_point, truncated: false, digits }; + + assert_eq!(actual, expected); + } +} diff --git a/library/coretests/tests/num/dec2flt/mod.rs b/library/coretests/tests/num/dec2flt/mod.rs index 874e0ec7093c..51f3017ddc79 100644 --- a/library/coretests/tests/num/dec2flt/mod.rs +++ b/library/coretests/tests/num/dec2flt/mod.rs @@ -1,5 +1,6 @@ #![allow(overflowing_literals)] +mod decimal_seq; mod float; mod lemire; mod parse; From 626d2c5eed687e2c166d25f29cdfcaaba48f5f23 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 9 Dec 2024 09:25:22 +0000 Subject: [PATCH 535/991] dec2flt: Rename `Number` to `Decimal` The previous commit renamed `Decimal` to `DecimalSeq`. Now, rename the type that represents a decimal floating point number to be `Decimal`. Additionally, add some tests for internal behavior. --- .../src/num/dec2flt/{number.rs => decimal.rs} | 6 ++-- library/core/src/num/dec2flt/mod.rs | 2 +- library/core/src/num/dec2flt/parse.rs | 10 +++---- .../coretests/tests/num/dec2flt/decimal.rs | 28 +++++++++++++++++++ library/coretests/tests/num/dec2flt/mod.rs | 1 + library/coretests/tests/num/dec2flt/parse.rs | 26 ++++++++--------- 6 files changed, 51 insertions(+), 22 deletions(-) rename library/core/src/num/dec2flt/{number.rs => decimal.rs} (96%) create mode 100644 library/coretests/tests/num/dec2flt/decimal.rs diff --git a/library/core/src/num/dec2flt/number.rs b/library/core/src/num/dec2flt/decimal.rs similarity index 96% rename from library/core/src/num/dec2flt/number.rs rename to library/core/src/num/dec2flt/decimal.rs index 2538991564ae..1ba9150a0119 100644 --- a/library/core/src/num/dec2flt/number.rs +++ b/library/core/src/num/dec2flt/decimal.rs @@ -3,7 +3,6 @@ use crate::num::dec2flt::float::RawFloat; use crate::num::dec2flt::fpu::set_precision; -#[rustfmt::skip] const INT_POW10: [u64; 16] = [ 1, 10, @@ -23,15 +22,16 @@ const INT_POW10: [u64; 16] = [ 1000000000000000, ]; +/// A floating point number with up to 64 bits of mantissa and an `i64` exponent. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] -pub struct Number { +pub struct Decimal { pub exponent: i64, pub mantissa: u64, pub negative: bool, pub many_digits: bool, } -impl Number { +impl Decimal { /// Detect if the float can be accurately reconstructed from native floats. #[inline] fn is_fast_path(&self) -> bool { diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 471505d24940..a82c858df499 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -97,6 +97,7 @@ use crate::fmt; use crate::str::FromStr; mod common; +pub mod decimal; pub mod decimal_seq; mod fpu; mod slow; @@ -104,7 +105,6 @@ mod table; // float is used in flt2dec, and all are used in unit tests. pub mod float; pub mod lemire; -pub mod number; pub mod parse; macro_rules! from_str_float_impl { diff --git a/library/core/src/num/dec2flt/parse.rs b/library/core/src/num/dec2flt/parse.rs index 06ee8e95fbc4..e38fedc58bec 100644 --- a/library/core/src/num/dec2flt/parse.rs +++ b/library/core/src/num/dec2flt/parse.rs @@ -1,8 +1,8 @@ //! Functions to parse floating-point numbers. use crate::num::dec2flt::common::{ByteSlice, is_8digits}; +use crate::num::dec2flt::decimal::Decimal; use crate::num::dec2flt::float::RawFloat; -use crate::num::dec2flt::number::Number; const MIN_19DIGIT_INT: u64 = 100_0000_0000_0000_0000; @@ -100,7 +100,7 @@ fn parse_scientific(s_ref: &mut &[u8]) -> Option { /// /// This creates a representation of the float as the /// significant digits and the decimal exponent. -fn parse_partial_number(mut s: &[u8]) -> Option<(Number, usize)> { +fn parse_partial_number(mut s: &[u8]) -> Option<(Decimal, usize)> { debug_assert!(!s.is_empty()); // parse initial digits before dot @@ -146,7 +146,7 @@ fn parse_partial_number(mut s: &[u8]) -> Option<(Number, usize)> { // handle uncommon case with many digits if n_digits <= 19 { - return Some((Number { exponent, mantissa, negative: false, many_digits: false }, len)); + return Some((Decimal { exponent, mantissa, negative: false, many_digits: false }, len)); } n_digits -= 19; @@ -179,13 +179,13 @@ fn parse_partial_number(mut s: &[u8]) -> Option<(Number, usize)> { exponent += exp_number; } - Some((Number { exponent, mantissa, negative: false, many_digits }, len)) + Some((Decimal { exponent, mantissa, negative: false, many_digits }, len)) } /// Try to parse a non-special floating point number, /// as well as two slices with integer and fractional parts /// and the parsed exponent. -pub fn parse_number(s: &[u8]) -> Option { +pub fn parse_number(s: &[u8]) -> Option { if let Some((float, rest)) = parse_partial_number(s) { if rest == s.len() { return Some(float); diff --git a/library/coretests/tests/num/dec2flt/decimal.rs b/library/coretests/tests/num/dec2flt/decimal.rs new file mode 100644 index 000000000000..1fa06de692e0 --- /dev/null +++ b/library/coretests/tests/num/dec2flt/decimal.rs @@ -0,0 +1,28 @@ +use core::num::dec2flt::decimal::Decimal; + +type FPath = ((i64, u64, bool, bool), Option); + +const FPATHS_F32: &[FPath] = + &[((0, 0, false, false), Some(0.0)), ((0, 0, false, false), Some(0.0))]; +const FPATHS_F64: &[FPath] = + &[((0, 0, false, false), Some(0.0)), ((0, 0, false, false), Some(0.0))]; + +#[test] +fn check_fast_path_f32() { + for ((exponent, mantissa, negative, many_digits), expected) in FPATHS_F32.iter().copied() { + let dec = Decimal { exponent, mantissa, negative, many_digits }; + let actual = dec.try_fast_path::(); + + assert_eq!(actual, expected); + } +} + +#[test] +fn check_fast_path_f64() { + for ((exponent, mantissa, negative, many_digits), expected) in FPATHS_F64.iter().copied() { + let dec = Decimal { exponent, mantissa, negative, many_digits }; + let actual = dec.try_fast_path::(); + + assert_eq!(actual, expected); + } +} diff --git a/library/coretests/tests/num/dec2flt/mod.rs b/library/coretests/tests/num/dec2flt/mod.rs index 51f3017ddc79..a9025be5ca7f 100644 --- a/library/coretests/tests/num/dec2flt/mod.rs +++ b/library/coretests/tests/num/dec2flt/mod.rs @@ -1,5 +1,6 @@ #![allow(overflowing_literals)] +mod decimal; mod decimal_seq; mod float; mod lemire; diff --git a/library/coretests/tests/num/dec2flt/parse.rs b/library/coretests/tests/num/dec2flt/parse.rs index 4a5d24ba7d5f..ec705a61e13c 100644 --- a/library/coretests/tests/num/dec2flt/parse.rs +++ b/library/coretests/tests/num/dec2flt/parse.rs @@ -1,9 +1,9 @@ -use core::num::dec2flt::number::Number; +use core::num::dec2flt::decimal::Decimal; use core::num::dec2flt::parse::parse_number; use core::num::dec2flt::{dec2flt, pfe_invalid}; -fn new_number(e: i64, m: u64) -> Number { - Number { exponent: e, mantissa: m, negative: false, many_digits: false } +fn new_dec(e: i64, m: u64) -> Decimal { + Decimal { exponent: e, mantissa: m, negative: false, many_digits: false } } #[test] @@ -31,23 +31,23 @@ fn invalid_chars() { } } -fn parse_positive(s: &[u8]) -> Option { +fn parse_positive(s: &[u8]) -> Option { parse_number(s) } #[test] fn valid() { - assert_eq!(parse_positive(b"123.456e789"), Some(new_number(786, 123456))); - assert_eq!(parse_positive(b"123.456e+789"), Some(new_number(786, 123456))); - assert_eq!(parse_positive(b"123.456e-789"), Some(new_number(-792, 123456))); - assert_eq!(parse_positive(b".050"), Some(new_number(-3, 50))); - assert_eq!(parse_positive(b"999"), Some(new_number(0, 999))); - assert_eq!(parse_positive(b"1.e300"), Some(new_number(300, 1))); - assert_eq!(parse_positive(b".1e300"), Some(new_number(299, 1))); - assert_eq!(parse_positive(b"101e-33"), Some(new_number(-33, 101))); + assert_eq!(parse_positive(b"123.456e789"), Some(new_dec(786, 123456))); + assert_eq!(parse_positive(b"123.456e+789"), Some(new_dec(786, 123456))); + assert_eq!(parse_positive(b"123.456e-789"), Some(new_dec(-792, 123456))); + assert_eq!(parse_positive(b".050"), Some(new_dec(-3, 50))); + assert_eq!(parse_positive(b"999"), Some(new_dec(0, 999))); + assert_eq!(parse_positive(b"1.e300"), Some(new_dec(300, 1))); + assert_eq!(parse_positive(b".1e300"), Some(new_dec(299, 1))); + assert_eq!(parse_positive(b"101e-33"), Some(new_dec(-33, 101))); let zeros = "0".repeat(25); let s = format!("1.5e{zeros}"); - assert_eq!(parse_positive(s.as_bytes()), Some(new_number(-1, 15))); + assert_eq!(parse_positive(s.as_bytes()), Some(new_dec(-1, 15))); } macro_rules! assert_float_result_bits_eq { From 6c34daff57101922dc97e1860bf5940ea88d3906 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 9 Dec 2024 09:25:22 +0000 Subject: [PATCH 536/991] dec2flt: Rename fields to be consistent with documented notation --- library/core/src/num/dec2flt/common.rs | 13 +++++++------ library/core/src/num/dec2flt/lemire.rs | 4 ++-- library/core/src/num/dec2flt/mod.rs | 13 ++++++++----- library/core/src/num/dec2flt/slow.rs | 2 +- library/coretests/tests/num/dec2flt/float.rs | 8 ++++---- library/coretests/tests/num/dec2flt/lemire.rs | 4 ++-- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/library/core/src/num/dec2flt/common.rs b/library/core/src/num/dec2flt/common.rs index 1646d3a95d3b..a140a311c452 100644 --- a/library/core/src/num/dec2flt/common.rs +++ b/library/core/src/num/dec2flt/common.rs @@ -63,19 +63,20 @@ pub(crate) fn is_8digits(v: u64) -> bool { (a | b) & 0x8080_8080_8080_8080 == 0 } -/// A custom 64-bit floating point type, representing `f * 2^e`. -/// e is biased, so it be directly shifted into the exponent bits. +/// A custom 64-bit floating point type, representing `m * 2^p`. +/// p is biased, so it be directly shifted into the exponent bits. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct BiasedFp { /// The significant digits. - pub f: u64, + pub m: u64, /// The biased, binary exponent. - pub e: i32, + pub p_biased: i32, } impl BiasedFp { + /// Represent `0 ^ p` #[inline] - pub const fn zero_pow2(e: i32) -> Self { - Self { f: 0, e } + pub const fn zero_pow2(p_biased: i32) -> Self { + Self { m: 0, p_biased } } } diff --git a/library/core/src/num/dec2flt/lemire.rs b/library/core/src/num/dec2flt/lemire.rs index 01642e1b1112..0cc39cb9b623 100644 --- a/library/core/src/num/dec2flt/lemire.rs +++ b/library/core/src/num/dec2flt/lemire.rs @@ -73,7 +73,7 @@ pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { mantissa += mantissa & 1; mantissa >>= 1; power2 = (mantissa >= (1_u64 << F::MANTISSA_EXPLICIT_BITS)) as i32; - return BiasedFp { f: mantissa, e: power2 }; + return BiasedFp { m: mantissa, p_biased: power2 }; } // Need to handle rounding ties. Normally, we need to round up, // but if we fall right in between and we have an even basis, we @@ -111,7 +111,7 @@ pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { // Exponent is above largest normal value, must be infinite. return fp_inf; } - BiasedFp { f: mantissa, e: power2 } + BiasedFp { m: mantissa, p_biased: power2 } } /// Calculate a base 2 exponent from a decimal exponent. diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index a82c858df499..9d1989c4b817 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -233,8 +233,8 @@ pub fn pfe_invalid() -> ParseFloatError { /// Converts a `BiasedFp` to the closest machine float type. fn biased_fp_to_float(x: BiasedFp) -> T { - let mut word = x.f; - word |= (x.e as u64) << T::MANTISSA_EXPLICIT_BITS; + let mut word = x.m; + word |= (x.p_biased as u64) << T::MANTISSA_EXPLICIT_BITS; T::from_u64_bits(word) } @@ -272,12 +272,15 @@ pub fn dec2flt(s: &str) -> Result { // redundantly using the Eisel-Lemire algorithm if it was unable to // correctly round on the first pass. let mut fp = compute_float::(num.exponent, num.mantissa); - if num.many_digits && fp.e >= 0 && fp != compute_float::(num.exponent, num.mantissa + 1) { - fp.e = -1; + if num.many_digits + && fp.p_biased >= 0 + && fp != compute_float::(num.exponent, num.mantissa + 1) + { + fp.p_biased = -1; } // Unable to correctly round the float using the Eisel-Lemire algorithm. // Fallback to a slower, but always correct algorithm. - if fp.e < 0 { + if fp.p_biased < 0 { fp = parse_long_mantissa::(s); } diff --git a/library/core/src/num/dec2flt/slow.rs b/library/core/src/num/dec2flt/slow.rs index e274e1aa0aa1..e0c4ae117da0 100644 --- a/library/core/src/num/dec2flt/slow.rs +++ b/library/core/src/num/dec2flt/slow.rs @@ -105,5 +105,5 @@ pub(crate) fn parse_long_mantissa(s: &[u8]) -> BiasedFp { } // Zero out all the bits above the explicit mantissa bits. mantissa &= (1_u64 << F::MANTISSA_EXPLICIT_BITS) - 1; - BiasedFp { f: mantissa, e: power2 } + BiasedFp { m: mantissa, p_biased: power2 } } diff --git a/library/coretests/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs index 7a9587a18d03..40f0776e0214 100644 --- a/library/coretests/tests/num/dec2flt/float.rs +++ b/library/coretests/tests/num/dec2flt/float.rs @@ -12,8 +12,8 @@ fn test_f32_integer_decode() { // Ignore the "sign" (quiet / signalling flag) of NAN. // It can vary between runtime operations and LLVM folding. - let (nan_m, nan_e, _nan_s) = f32::NAN.integer_decode(); - assert_eq!((nan_m, nan_e), (12582912, 105)); + let (nan_m, nan_p, _nan_s) = f32::NAN.integer_decode(); + assert_eq!((nan_m, nan_p), (12582912, 105)); } #[test] @@ -28,6 +28,6 @@ fn test_f64_integer_decode() { // Ignore the "sign" (quiet / signalling flag) of NAN. // It can vary between runtime operations and LLVM folding. - let (nan_m, nan_e, _nan_s) = f64::NAN.integer_decode(); - assert_eq!((nan_m, nan_e), (6755399441055744, 972)); + let (nan_m, nan_p, _nan_s) = f64::NAN.integer_decode(); + assert_eq!((nan_m, nan_p), (6755399441055744, 972)); } diff --git a/library/coretests/tests/num/dec2flt/lemire.rs b/library/coretests/tests/num/dec2flt/lemire.rs index f71bbb7c7a31..9f228a25e46b 100644 --- a/library/coretests/tests/num/dec2flt/lemire.rs +++ b/library/coretests/tests/num/dec2flt/lemire.rs @@ -2,12 +2,12 @@ use core::num::dec2flt::lemire::compute_float; fn compute_float32(q: i64, w: u64) -> (i32, u64) { let fp = compute_float::(q, w); - (fp.e, fp.f) + (fp.p_biased, fp.m) } fn compute_float64(q: i64, w: u64) -> (i32, u64) { let fp = compute_float::(q, w); - (fp.e, fp.f) + (fp.p_biased, fp.m) } #[test] From 43c5e95af9ce0c4315ec44c00eeabe2de0a5c826 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 2 Mar 2025 09:09:12 +0100 Subject: [PATCH 537/991] Normalize some assist names --- ...t.rs => add_explicit_enum_discriminant.rs} | 23 ++- ...ool_to_enum.rs => convert_bool_to_enum.rs} | 96 +++++----- ...ttern_fields.rs => expand_rest_pattern.rs} | 46 +++-- ...c.rs => introduce_named_type_parameter.rs} | 36 ++-- .../crates/ide-assists/src/lib.rs | 60 +++--- .../crates/ide-assists/src/tests/generated.rs | 148 +++++++-------- .../docs/book/src/assists_generated.md | 178 +++++++++--------- 7 files changed, 299 insertions(+), 288 deletions(-) rename src/tools/rust-analyzer/crates/ide-assists/src/handlers/{explicit_enum_discriminant.rs => add_explicit_enum_discriminant.rs} (87%) rename src/tools/rust-analyzer/crates/ide-assists/src/handlers/{bool_to_enum.rs => convert_bool_to_enum.rs} (95%) rename src/tools/rust-analyzer/crates/ide-assists/src/handlers/{fill_record_pattern_fields.rs => expand_rest_pattern.rs} (84%) rename src/tools/rust-analyzer/crates/ide-assists/src/handlers/{introduce_named_generic.rs => introduce_named_type_parameter.rs} (84%) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/explicit_enum_discriminant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs similarity index 87% rename from src/tools/rust-analyzer/crates/ide-assists/src/handlers/explicit_enum_discriminant.rs rename to src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs index fafc3448a87c..1a5de9cb071b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/explicit_enum_discriminant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs @@ -8,7 +8,7 @@ use syntax::{ast, AstNode}; use crate::{AssistContext, Assists}; -// Assist: explicit_enum_discriminant +// Assist: add_explicit_enum_discriminant // // Adds explicit discriminant to all enum variants. // @@ -29,7 +29,10 @@ use crate::{AssistContext, Assists}; // Quux = 43, // } // ``` -pub(crate) fn explicit_enum_discriminant(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { +pub(crate) fn add_explicit_enum_discriminant( + acc: &mut Assists, + ctx: &AssistContext<'_>, +) -> Option<()> { let enum_node = ctx.find_node_at_offset::()?; let enum_def = ctx.sema.to_def(&enum_node)?; @@ -50,7 +53,7 @@ pub(crate) fn explicit_enum_discriminant(acc: &mut Assists, ctx: &AssistContext< } acc.add( - AssistId("explicit_enum_discriminant", AssistKind::RefactorRewrite), + AssistId("add_explicit_enum_discriminant", AssistKind::RefactorRewrite), "Add explicit enum discriminants", enum_node.syntax().text_range(), |builder| { @@ -88,12 +91,12 @@ fn add_variant_discriminant( mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; - use super::explicit_enum_discriminant; + use super::add_explicit_enum_discriminant; #[test] fn non_primitive_repr_non_data_bearing_add_discriminant() { check_assist( - explicit_enum_discriminant, + add_explicit_enum_discriminant, r#" enum TheEnum$0 { Foo, @@ -120,7 +123,7 @@ enum TheEnum { #[test] fn primitive_repr_data_bearing_add_discriminant() { check_assist( - explicit_enum_discriminant, + add_explicit_enum_discriminant, r#" #[repr(u8)] $0enum TheEnum { @@ -145,7 +148,7 @@ enum TheEnum { #[test] fn non_primitive_repr_data_bearing_not_applicable() { check_assist_not_applicable( - explicit_enum_discriminant, + add_explicit_enum_discriminant, r#" enum TheEnum$0 { Foo, @@ -159,7 +162,7 @@ enum TheEnum$0 { #[test] fn primitive_repr_non_data_bearing_add_discriminant() { check_assist( - explicit_enum_discriminant, + add_explicit_enum_discriminant, r#" #[repr(i64)] enum TheEnum { @@ -184,7 +187,7 @@ enum TheEnum { #[test] fn discriminants_already_explicit_not_applicable() { check_assist_not_applicable( - explicit_enum_discriminant, + add_explicit_enum_discriminant, r#" enum TheEnum$0 { Foo = 0, @@ -197,7 +200,7 @@ enum TheEnum$0 { #[test] fn empty_enum_not_applicable() { check_assist_not_applicable( - explicit_enum_discriminant, + add_explicit_enum_discriminant, r#" enum TheEnum$0 {} "#, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs similarity index 95% rename from src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs rename to src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs index cbd39796241b..7716e99e604b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs @@ -26,7 +26,7 @@ use crate::{ utils, }; -// Assist: bool_to_enum +// Assist: convert_bool_to_enum // // This converts boolean local variables, fields, constants, and statics into a new // enum with two variants `Bool::True` and `Bool::False`, as well as replacing @@ -55,14 +55,14 @@ use crate::{ // } // } // ``` -pub(crate) fn bool_to_enum(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { +pub(crate) fn convert_bool_to_enum(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let BoolNodeData { target_node, name, ty_annotation, initializer, definition } = find_bool_node(ctx)?; let target_module = ctx.sema.scope(&target_node)?.module().nearest_non_block_module(ctx.db()); let target = name.syntax().text_range(); acc.add( - AssistId("bool_to_enum", AssistKind::RefactorRewrite), + AssistId("convert_bool_to_enum", AssistKind::RefactorRewrite), "Convert boolean to enum", target, |edit| { @@ -549,7 +549,7 @@ mod tests { #[test] fn parameter_with_first_param_usage() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn function($0foo: bool, bar: bool) { if foo { @@ -573,7 +573,7 @@ fn function(foo: Bool, bar: bool) { #[test] fn no_duplicate_enums() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" #[derive(PartialEq, Eq)] enum Bool { True, False } @@ -600,7 +600,7 @@ fn function(foo: bool, bar: Bool) { #[test] fn parameter_with_last_param_usage() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn function(foo: bool, $0bar: bool) { if bar { @@ -624,7 +624,7 @@ fn function(foo: bool, bar: Bool) { #[test] fn parameter_with_middle_param_usage() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn function(foo: bool, $0bar: bool, baz: bool) { if bar { @@ -648,7 +648,7 @@ fn function(foo: bool, bar: Bool, baz: bool) { #[test] fn parameter_with_closure_usage() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let foo = |$0bar: bool| bar; @@ -668,7 +668,7 @@ fn main() { #[test] fn local_variable_with_usage() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let $0foo = true; @@ -697,7 +697,7 @@ fn main() { fn local_variable_with_usage_negated() { cov_mark::check!(replaces_negation); check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let $0foo = true; @@ -726,7 +726,7 @@ fn main() { fn local_variable_with_type_annotation() { cov_mark::check!(replaces_ty_annotation); check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let $0foo: bool = false; @@ -746,7 +746,7 @@ fn main() { #[test] fn local_variable_with_non_literal_initializer() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let $0foo = 1 == 2; @@ -766,7 +766,7 @@ fn main() { #[test] fn local_variable_binexpr_usage() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let $0foo = false; @@ -796,7 +796,7 @@ fn main() { #[test] fn local_variable_unop_usage() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let $0foo = true; @@ -825,7 +825,7 @@ fn main() { fn local_variable_assigned_later() { cov_mark::check!(replaces_assignment); check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let $0foo: bool; @@ -847,7 +847,7 @@ fn main() { #[test] fn local_variable_does_not_apply_recursively() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let $0foo = true; @@ -878,7 +878,7 @@ fn main() { fn local_variable_nested_in_negation() { cov_mark::check!(dont_overwrite_expression_inside_negation); check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { if !"foo".chars().any(|c| { @@ -909,7 +909,7 @@ fn main() { fn local_variable_non_bool() { cov_mark::check!(not_applicable_non_bool_local); check_assist_not_applicable( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let $0foo = 1; @@ -921,7 +921,7 @@ fn main() { #[test] fn local_variable_cursor_not_on_ident() { check_assist_not_applicable( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let foo = $0true; @@ -933,7 +933,7 @@ fn main() { #[test] fn local_variable_non_ident_pat() { check_assist_not_applicable( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { let ($0foo, bar) = (true, false); @@ -945,7 +945,7 @@ fn main() { #[test] fn local_var_init_struct_usage() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" struct Foo { foo: bool, @@ -975,7 +975,7 @@ fn main() { #[test] fn local_var_init_struct_usage_in_macro() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" struct Struct { boolean: bool, @@ -1018,7 +1018,7 @@ fn new() -> Struct { fn field_struct_basic() { cov_mark::check!(replaces_record_expr); check_assist( - bool_to_enum, + convert_bool_to_enum, r#" struct Foo { $0bar: bool, @@ -1057,7 +1057,7 @@ fn main() { fn field_enum_basic() { cov_mark::check!(replaces_record_pat); check_assist( - bool_to_enum, + convert_bool_to_enum, r#" enum Foo { Foo, @@ -1100,7 +1100,7 @@ fn main() { fn field_enum_cross_file() { // FIXME: The import is missing check_assist( - bool_to_enum, + convert_bool_to_enum, r#" //- /foo.rs pub enum Foo { @@ -1151,7 +1151,7 @@ fn main() { fn field_enum_shorthand() { cov_mark::check!(replaces_record_pat_shorthand); check_assist( - bool_to_enum, + convert_bool_to_enum, r#" enum Foo { Foo, @@ -1200,7 +1200,7 @@ fn main() { fn field_enum_replaces_literal_patterns() { cov_mark::check!(replaces_literal_pat); check_assist( - bool_to_enum, + convert_bool_to_enum, r#" enum Foo { Foo, @@ -1238,7 +1238,7 @@ fn main() { #[test] fn field_enum_keeps_wildcard_patterns() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" enum Foo { Foo, @@ -1276,7 +1276,7 @@ fn main() { #[test] fn field_union_basic() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" union Foo { $0foo: bool, @@ -1314,7 +1314,7 @@ fn main() { #[test] fn field_negated() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" struct Foo { $0bar: bool, @@ -1350,7 +1350,7 @@ fn main() { #[test] fn field_in_mod_properly_indented() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" mod foo { struct Bar { @@ -1386,7 +1386,7 @@ mod foo { #[test] fn field_multiple_initializations() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" struct Foo { $0bar: bool, @@ -1427,7 +1427,7 @@ fn main() { fn field_assigned_to_another() { cov_mark::check!(dont_assign_incorrect_ref); check_assist( - bool_to_enum, + convert_bool_to_enum, r#" struct Foo { $0foo: bool, @@ -1469,7 +1469,7 @@ fn main() { #[test] fn field_initialized_with_other() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" struct Foo { $0foo: bool, @@ -1507,7 +1507,7 @@ fn main() { #[test] fn field_method_chain_usage() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" struct Foo { $0bool: bool, @@ -1539,7 +1539,7 @@ fn main() { #[test] fn field_in_macro() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" struct Struct { $0boolean: bool, @@ -1580,7 +1580,7 @@ fn new() -> Struct { fn field_non_bool() { cov_mark::check!(not_applicable_non_bool_field); check_assist_not_applicable( - bool_to_enum, + convert_bool_to_enum, r#" struct Foo { $0bar: usize, @@ -1596,7 +1596,7 @@ fn main() { #[test] fn const_basic() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" const $0FOO: bool = false; @@ -1624,7 +1624,7 @@ fn main() { #[test] fn const_in_module() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { if foo::FOO { @@ -1658,7 +1658,7 @@ mod foo { #[test] fn const_in_module_with_import() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" fn main() { use foo::FOO; @@ -1696,7 +1696,7 @@ mod foo { #[test] fn const_cross_file() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" //- /main.rs mod foo; @@ -1734,7 +1734,7 @@ pub const FOO: Bool = Bool::True; #[test] fn const_cross_file_and_module() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" //- /main.rs mod foo; @@ -1780,7 +1780,7 @@ pub mod bar { #[test] fn const_in_impl_cross_file() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" //- /main.rs mod foo; @@ -1824,7 +1824,7 @@ fn foo() -> bool { #[test] fn const_in_trait() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" trait Foo { const $0BOOL: bool; @@ -1865,7 +1865,7 @@ fn main() { fn const_non_bool() { cov_mark::check!(not_applicable_non_bool_const); check_assist_not_applicable( - bool_to_enum, + convert_bool_to_enum, r#" const $0FOO: &str = "foo"; @@ -1879,7 +1879,7 @@ fn main() { #[test] fn static_basic() { check_assist( - bool_to_enum, + convert_bool_to_enum, r#" static mut $0BOOL: bool = true; @@ -1910,7 +1910,7 @@ fn main() { fn static_non_bool() { cov_mark::check!(not_applicable_non_bool_static); check_assist_not_applicable( - bool_to_enum, + convert_bool_to_enum, r#" static mut $0FOO: usize = 0; @@ -1925,6 +1925,6 @@ fn main() { #[test] fn not_applicable_to_other_names() { - check_assist_not_applicable(bool_to_enum, "fn $0main() {}") + check_assist_not_applicable(convert_bool_to_enum, "fn $0main() {}") } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs similarity index 84% rename from src/tools/rust-analyzer/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs rename to src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs index ee321864805e..315d7e727b41 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs @@ -1,11 +1,11 @@ use syntax::{ ast::{self, make}, - AstNode, ToSmolStr, + match_ast, AstNode, ToSmolStr, }; use crate::{AssistContext, AssistId, Assists}; -// Assist: fill_record_pattern_fields +// Assist: expand_rest_pattern // // Fills fields by replacing rest pattern in record patterns. // @@ -24,14 +24,20 @@ use crate::{AssistContext, AssistId, Assists}; // let Bar { y, z } = bar; // } // ``` -pub(crate) fn fill_record_pattern_fields(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let record_pat = ctx.find_node_at_offset::()?; +pub(crate) fn expand_rest_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + let rest_pat = ctx.find_node_at_offset::()?; + let parent = rest_pat.syntax().parent()?; + let record_pat = match_ast! { + match parent { + ast::RecordPatFieldList(it) => ast::RecordPat::cast(it.syntax().parent()?)?, + // ast::TupleStructPat(it) => (), + // ast::TuplePat(it) => (), + // ast::SlicePat(it) => (), + _ => return None, + } + }; let ellipsis = record_pat.record_pat_field_list().and_then(|r| r.rest_pat())?; - if !ellipsis.syntax().text_range().contains_inclusive(ctx.offset()) { - return None; - } - let target_range = ellipsis.syntax().text_range(); let missing_fields = ctx.sema.record_pattern_missing_fields(&record_pat); @@ -58,7 +64,7 @@ pub(crate) fn fill_record_pattern_fields(acc: &mut Assists, ctx: &AssistContext< } acc.add( - AssistId("fill_record_pattern_fields", crate::AssistKind::RefactorRewrite), + AssistId("expand_rest_pattern", crate::AssistKind::RefactorRewrite), "Fill structure fields", target_range, move |builder| builder.replace_ast(old_field_list, new_field_list), @@ -73,7 +79,7 @@ mod tests { #[test] fn fill_fields_enum_with_only_ellipsis() { check_assist( - fill_record_pattern_fields, + expand_rest_pattern, r#" enum Foo { A(X), @@ -106,7 +112,7 @@ fn bar(foo: Foo) { #[test] fn fill_fields_enum_with_fields() { check_assist( - fill_record_pattern_fields, + expand_rest_pattern, r#" enum Foo { A(X), @@ -139,7 +145,7 @@ fn bar(foo: Foo) { #[test] fn fill_fields_struct_with_only_ellipsis() { check_assist( - fill_record_pattern_fields, + expand_rest_pattern, r#" struct Bar { y: Y, @@ -166,7 +172,7 @@ fn foo(bar: Bar) { #[test] fn fill_fields_struct_with_fields() { check_assist( - fill_record_pattern_fields, + expand_rest_pattern, r#" struct Bar { y: Y, @@ -193,7 +199,7 @@ fn foo(bar: Bar) { #[test] fn fill_fields_struct_generated_by_macro() { check_assist( - fill_record_pattern_fields, + expand_rest_pattern, r#" macro_rules! position { ($t: ty) => { @@ -226,7 +232,7 @@ fn macro_call(pos: Pos) { #[test] fn fill_fields_enum_generated_by_macro() { check_assist( - fill_record_pattern_fields, + expand_rest_pattern, r#" macro_rules! enum_gen { ($t: ty) => { @@ -271,7 +277,7 @@ fn macro_call(foo: Foo) { #[test] fn not_applicable_when_not_in_ellipsis() { check_assist_not_applicable( - fill_record_pattern_fields, + expand_rest_pattern, r#" enum Foo { A(X), @@ -287,7 +293,7 @@ fn bar(foo: Foo) { "#, ); check_assist_not_applicable( - fill_record_pattern_fields, + expand_rest_pattern, r#" enum Foo { A(X), @@ -303,7 +309,7 @@ fn bar(foo: Foo) { "#, ); check_assist_not_applicable( - fill_record_pattern_fields, + expand_rest_pattern, r#" enum Foo { A(X), @@ -325,7 +331,7 @@ fn bar(foo: Foo) { // This is still possible even though it's meaningless cov_mark::check!(no_missing_fields); check_assist_not_applicable( - fill_record_pattern_fields, + expand_rest_pattern, r#" enum Foo { A(X), @@ -341,7 +347,7 @@ fn bar(foo: Foo) { "#, ); check_assist_not_applicable( - fill_record_pattern_fields, + expand_rest_pattern, r#" struct Bar { y: Y, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_generic.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs similarity index 84% rename from src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_generic.rs rename to src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs index 8c276415bb1f..994e4a0eddaf 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_generic.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs @@ -4,7 +4,7 @@ use syntax::ast::{self, syntax_factory::SyntaxFactory, AstNode, HasGenericParams use crate::{AssistContext, AssistId, AssistKind, Assists}; -// Assist: introduce_named_generic +// Assist: introduce_named_type_parameter // // Replaces `impl Trait` function argument with the named generic. // @@ -15,18 +15,20 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // ``` // fn foo<$0B: Bar>(bar: B) {} // ``` -pub(crate) fn introduce_named_generic(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { +pub(crate) fn introduce_named_type_parameter( + acc: &mut Assists, + ctx: &AssistContext<'_>, +) -> Option<()> { let impl_trait_type = ctx.find_node_at_offset::()?; let param = impl_trait_type.syntax().ancestors().find_map(ast::Param::cast)?; - let fn_ = param.syntax().ancestors().find_map(ast::Fn::cast)?; - + let fn_ = param.syntax().ancestors().nth(2).and_then(ast::Fn::cast)?; let type_bound_list = impl_trait_type.type_bound_list()?; let make = SyntaxFactory::new(); let target = fn_.syntax().text_range(); acc.add( - AssistId("introduce_named_generic", AssistKind::RefactorRewrite), - "Replace impl trait with generic", + AssistId("introduce_named_type_parameter", AssistKind::RefactorRewrite), + "Replace impl trait with type parameter", target, |builder| { let mut editor = builder.make_editor(fn_.syntax()); @@ -71,7 +73,7 @@ mod tests { #[test] fn introduce_named_generic_params() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#"fn foo(bar: $0impl Bar) {}"#, r#"fn foo(bar: B) {}"#, ); @@ -80,7 +82,7 @@ mod tests { #[test] fn replace_impl_trait_without_generic_params() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#"fn foo(bar: $0impl Bar) {}"#, r#"fn foo<$0B: Bar>(bar: B) {}"#, ); @@ -89,7 +91,7 @@ mod tests { #[test] fn replace_two_impl_trait_with_generic_params() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#"fn foo(foo: impl Foo, bar: $0impl Bar) {}"#, r#"fn foo(foo: impl Foo, bar: B) {}"#, ); @@ -98,7 +100,7 @@ mod tests { #[test] fn replace_impl_trait_with_empty_generic_params() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#"fn foo<>(bar: $0impl Bar) {}"#, r#"fn foo<$0B: Bar>(bar: B) {}"#, ); @@ -107,7 +109,7 @@ mod tests { #[test] fn replace_impl_trait_with_empty_multiline_generic_params() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#" fn foo< >(bar: $0impl Bar) {} @@ -122,7 +124,7 @@ fn foo<$0B: Bar #[test] fn replace_impl_trait_with_exist_generic_letter() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#"fn foo(bar: $0impl Bar) {}"#, r#"fn foo(bar: B1) {}"#, ); @@ -131,7 +133,7 @@ fn foo<$0B: Bar #[test] fn replace_impl_trait_with_more_exist_generic_letter() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#"fn foo(bar: $0impl Bar) {}"#, r#"fn foo(bar: B4) {}"#, ); @@ -140,7 +142,7 @@ fn foo<$0B: Bar #[test] fn replace_impl_trait_with_multiline_generic_params() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#" fn foo< G: Foo, @@ -161,7 +163,7 @@ fn foo< #[test] fn replace_impl_trait_multiple() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#"fn foo(bar: $0impl Foo + Bar) {}"#, r#"fn foo<$0F: Foo + Bar>(bar: F) {}"#, ); @@ -170,7 +172,7 @@ fn foo< #[test] fn replace_impl_with_mut() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#"fn f(iter: &mut $0impl Iterator) {}"#, r#"fn f<$0I: Iterator>(iter: &mut I) {}"#, ); @@ -179,7 +181,7 @@ fn foo< #[test] fn replace_impl_inside() { check_assist( - introduce_named_generic, + introduce_named_type_parameter, r#"fn f(x: &mut Vec<$0impl Iterator>) {}"#, r#"fn f<$0I: Iterator>(x: &mut Vec) {}"#, ); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index 179742f91b4d..11d48430a0ad 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -105,6 +105,7 @@ mod handlers { pub(crate) type Handler = fn(&mut Assists, &AssistContext<'_>) -> Option<()>; mod add_braces; + mod add_explicit_enum_discriminant; mod add_explicit_type; mod add_label_to_loop; mod add_lifetime_to_type; @@ -115,9 +116,9 @@ mod handlers { mod apply_demorgan; mod auto_import; mod bind_unused_param; - mod bool_to_enum; mod change_visibility; mod convert_bool_then; + mod convert_bool_to_enum; mod convert_closure_to_fn; mod convert_comment_block; mod convert_comment_from_or_to_doc; @@ -138,14 +139,13 @@ mod handlers { mod destructure_tuple_binding; mod desugar_doc_comment; mod expand_glob_import; - mod explicit_enum_discriminant; + mod expand_rest_pattern; mod extract_expressions_from_format_string; mod extract_function; mod extract_module; mod extract_struct_from_enum_variant; mod extract_type_alias; mod extract_variable; - mod fill_record_pattern_fields; mod fix_visibility; mod flip_binexpr; mod flip_comma; @@ -176,8 +176,8 @@ mod handlers { mod inline_macro; mod inline_type_alias; mod into_to_qualified_from; - mod introduce_named_generic; mod introduce_named_lifetime; + mod introduce_named_type_parameter; mod invert_if; mod merge_imports; mod merge_match_arms; @@ -233,49 +233,47 @@ mod handlers { &[ // These are alphabetic for the foolish consistency add_braces::add_braces, + add_explicit_enum_discriminant::add_explicit_enum_discriminant, add_explicit_type::add_explicit_type, add_label_to_loop::add_label_to_loop, - add_missing_match_arms::add_missing_match_arms, add_lifetime_to_type::add_lifetime_to_type, + add_missing_match_arms::add_missing_match_arms, add_return_type::add_return_type, add_turbo_fish::add_turbo_fish, - apply_demorgan::apply_demorgan, apply_demorgan::apply_demorgan_iterator, + apply_demorgan::apply_demorgan, auto_import::auto_import, bind_unused_param::bind_unused_param, - bool_to_enum::bool_to_enum, change_visibility::change_visibility, convert_bool_then::convert_bool_then_to_if, convert_bool_then::convert_if_to_bool_then, - toggle_async_sugar::desugar_async_into_impl_future, - toggle_async_sugar::sugar_impl_future_into_async, + convert_bool_to_enum::convert_bool_to_enum, + convert_closure_to_fn::convert_closure_to_fn, convert_comment_block::convert_comment_block, convert_comment_from_or_to_doc::convert_comment_from_or_to_doc, - convert_closure_to_fn::convert_closure_to_fn, convert_from_to_tryfrom::convert_from_to_tryfrom, convert_integer_literal::convert_integer_literal, convert_into_to_from::convert_into_to_from, - convert_iter_for_each_to_for::convert_iter_for_each_to_for, convert_iter_for_each_to_for::convert_for_loop_with_for_each, + convert_iter_for_each_to_for::convert_iter_for_each_to_for, convert_let_else_to_match::convert_let_else_to_match, convert_match_to_let_else::convert_match_to_let_else, - convert_tuple_return_type_to_struct::convert_tuple_return_type_to_struct, convert_named_struct_to_tuple_struct::convert_named_struct_to_tuple_struct, convert_nested_function_to_closure::convert_nested_function_to_closure, convert_to_guarded_return::convert_to_guarded_return, + convert_tuple_return_type_to_struct::convert_tuple_return_type_to_struct, convert_tuple_struct_to_named_struct::convert_tuple_struct_to_named_struct, convert_two_arm_bool_match_to_matches_macro::convert_two_arm_bool_match_to_matches_macro, convert_while_to_loop::convert_while_to_loop, - desugar_doc_comment::desugar_doc_comment, - destructure_tuple_binding::destructure_tuple_binding, destructure_struct_binding::destructure_struct_binding, + destructure_tuple_binding::destructure_tuple_binding, + desugar_doc_comment::desugar_doc_comment, expand_glob_import::expand_glob_import, expand_glob_import::expand_glob_reexport, - explicit_enum_discriminant::explicit_enum_discriminant, + expand_rest_pattern::expand_rest_pattern, extract_expressions_from_format_string::extract_expressions_from_format_string, extract_struct_from_enum_variant::extract_struct_from_enum_variant, extract_type_alias::extract_type_alias, - fill_record_pattern_fields::fill_record_pattern_fields, fix_visibility::fix_visibility, flip_binexpr::flip_binexpr, flip_comma::flip_comma, @@ -285,8 +283,8 @@ mod handlers { generate_default_from_new::generate_default_from_new, generate_delegate_trait::generate_delegate_trait, generate_derive::generate_derive, - generate_documentation_template::generate_documentation_template, generate_documentation_template::generate_doc_example, + generate_documentation_template::generate_documentation_template, generate_enum_is_method::generate_enum_is_method, generate_enum_projection_method::generate_enum_as_method, generate_enum_projection_method::generate_enum_try_into_method, @@ -296,8 +294,8 @@ mod handlers { generate_function::generate_function, generate_impl::generate_impl, generate_impl::generate_trait_impl, - generate_mut_trait_impl::generate_mut_trait_impl, generate_is_empty_from_len::generate_is_empty_from_len, + generate_mut_trait_impl::generate_mut_trait_impl, generate_new::generate_new, generate_trait_from_impl::generate_trait_from_impl, inline_call::inline_call, @@ -305,39 +303,41 @@ mod handlers { inline_const_as_literal::inline_const_as_literal, inline_local_variable::inline_local_variable, inline_macro::inline_macro, - inline_type_alias::inline_type_alias, inline_type_alias::inline_type_alias_uses, + inline_type_alias::inline_type_alias, into_to_qualified_from::into_to_qualified_from, - introduce_named_generic::introduce_named_generic, introduce_named_lifetime::introduce_named_lifetime, + introduce_named_type_parameter::introduce_named_type_parameter, invert_if::invert_if, merge_imports::merge_imports, merge_match_arms::merge_match_arms, merge_nested_if::merge_nested_if, move_bounds::move_bounds_to_where_clause, move_const_to_impl::move_const_to_impl, + move_from_mod_rs::move_from_mod_rs, move_guard::move_arm_cond_to_match_guard, move_guard::move_guard_to_arm_body, move_module_to_file::move_module_to_file, move_to_mod_rs::move_to_mod_rs, - move_from_mod_rs::move_from_mod_rs, normalize_import::normalize_import, number_representation::reformat_number_literal, - pull_assignment_up::pull_assignment_up, promote_local_to_const::promote_local_to_const, - qualify_path::qualify_path, + pull_assignment_up::pull_assignment_up, qualify_method_call::qualify_method_call, + qualify_path::qualify_path, raw_string::add_hash, raw_string::make_usual_string, raw_string::remove_hash, remove_dbg::remove_dbg, remove_mut::remove_mut, + remove_parentheses::remove_parentheses, remove_unused_imports::remove_unused_imports, remove_unused_param::remove_unused_param, - remove_parentheses::remove_parentheses, reorder_fields::reorder_fields, reorder_impl_items::reorder_impl_items, - replace_try_expr_with_match::replace_try_expr_with_match, + replace_arith_op::replace_arith_with_checked, + replace_arith_op::replace_arith_with_saturating, + replace_arith_op::replace_arith_with_wrapping, replace_derive_with_manual_impl::replace_derive_with_manual_impl, replace_if_let_with_match::replace_if_let_with_match, replace_if_let_with_match::replace_match_with_if_let, @@ -346,23 +346,23 @@ mod handlers { replace_method_eager_lazy::replace_with_eager_method, replace_method_eager_lazy::replace_with_lazy_method, replace_named_generic_with_impl::replace_named_generic_with_impl, - replace_turbofish_with_explicit_type::replace_turbofish_with_explicit_type, replace_qualified_name_with_use::replace_qualified_name_with_use, - replace_arith_op::replace_arith_with_wrapping, - replace_arith_op::replace_arith_with_checked, - replace_arith_op::replace_arith_with_saturating, + replace_try_expr_with_match::replace_try_expr_with_match, + replace_turbofish_with_explicit_type::replace_turbofish_with_explicit_type, sort_items::sort_items, split_import::split_import, term_search::term_search, + toggle_async_sugar::desugar_async_into_impl_future, + toggle_async_sugar::sugar_impl_future_into_async, toggle_ignore::toggle_ignore, toggle_macro_delimiter::toggle_macro_delimiter, unmerge_match_arm::unmerge_match_arm, unmerge_use::unmerge_use, unnecessary_async::unnecessary_async, + unqualify_method_call::unqualify_method_call, unwrap_block::unwrap_block, unwrap_return_type::unwrap_return_type, unwrap_tuple::unwrap_tuple, - unqualify_method_call::unqualify_method_call, wrap_return_type::wrap_return_type, wrap_unwrap_cfg_attr::wrap_unwrap_cfg_attr, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 74ae126adae8..dd994ef4a640 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -27,6 +27,29 @@ fn foo(n: i32) -> i32 { ) } +#[test] +fn doctest_add_explicit_enum_discriminant() { + check_doc_test( + "add_explicit_enum_discriminant", + r#####" +enum TheEnum$0 { + Foo, + Bar, + Baz = 42, + Quux, +} +"#####, + r#####" +enum TheEnum { + Foo = 0, + Bar = 1, + Baz = 42, + Quux = 43, +} +"#####, + ) +} + #[test] fn doctest_add_explicit_type() { check_doc_test( @@ -304,34 +327,6 @@ fn some_function(x: i32) { ) } -#[test] -fn doctest_bool_to_enum() { - check_doc_test( - "bool_to_enum", - r#####" -fn main() { - let $0bool = true; - - if bool { - println!("foo"); - } -} -"#####, - r#####" -#[derive(PartialEq, Eq)] -enum Bool { True, False } - -fn main() { - let bool = Bool::True; - - if bool == Bool::True { - println!("foo"); - } -} -"#####, - ) -} - #[test] fn doctest_change_visibility() { check_doc_test( @@ -382,6 +377,34 @@ fn main() { ) } +#[test] +fn doctest_convert_bool_to_enum() { + check_doc_test( + "convert_bool_to_enum", + r#####" +fn main() { + let $0bool = true; + + if bool { + println!("foo"); + } +} +"#####, + r#####" +#[derive(PartialEq, Eq)] +enum Bool { True, False } + +fn main() { + let bool = Bool::True; + + if bool == Bool::True { + println!("foo"); + } +} +"#####, + ) +} + #[test] fn doctest_convert_closure_to_fn() { check_doc_test( @@ -933,23 +956,21 @@ pub use foo::{Bar, Baz}; } #[test] -fn doctest_explicit_enum_discriminant() { +fn doctest_expand_rest_pattern() { check_doc_test( - "explicit_enum_discriminant", + "expand_rest_pattern", r#####" -enum TheEnum$0 { - Foo, - Bar, - Baz = 42, - Quux, +struct Bar { y: Y, z: Z } + +fn foo(bar: Bar) { + let Bar { ..$0 } = bar; } "#####, r#####" -enum TheEnum { - Foo = 0, - Bar = 1, - Baz = 42, - Quux = 43, +struct Bar { y: Y, z: Z } + +fn foo(bar: Bar) { + let Bar { y, z } = bar; } "#####, ) @@ -1117,27 +1138,6 @@ fn main() { ) } -#[test] -fn doctest_fill_record_pattern_fields() { - check_doc_test( - "fill_record_pattern_fields", - r#####" -struct Bar { y: Y, z: Z } - -fn foo(bar: Bar) { - let Bar { ..$0 } = bar; -} -"#####, - r#####" -struct Bar { y: Y, z: Z } - -fn foo(bar: Bar) { - let Bar { y, z } = bar; -} -"#####, - ) -} - #[test] fn doctest_fix_visibility() { check_doc_test( @@ -2176,19 +2176,6 @@ fn main() -> () { ) } -#[test] -fn doctest_introduce_named_generic() { - check_doc_test( - "introduce_named_generic", - r#####" -fn foo(bar: $0impl Bar) {} -"#####, - r#####" -fn foo<$0B: Bar>(bar: B) {} -"#####, - ) -} - #[test] fn doctest_introduce_named_lifetime() { check_doc_test( @@ -2214,6 +2201,19 @@ impl<'a> Cursor<'a> { ) } +#[test] +fn doctest_introduce_named_type_parameter() { + check_doc_test( + "introduce_named_type_parameter", + r#####" +fn foo(bar: $0impl Bar) {} +"#####, + r#####" +fn foo<$0B: Bar>(bar: B) {} +"#####, + ) +} + #[test] fn doctest_invert_if() { check_doc_test( diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 2d233ca62ad6..743e5c5e10d4 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -28,6 +28,32 @@ fn foo(n: i32) -> i32 { ``` +### `add_explicit_enum_discriminant` +**Source:** [add_explicit_enum_discriminant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_explicit_enum_discriminant.rs#L11) + +Adds explicit discriminant to all enum variants. + +#### Before +```rust +enum TheEnum┃ { + Foo, + Bar, + Baz = 42, + Quux, +} +``` + +#### After +```rust +enum TheEnum { + Foo = 0, + Bar = 1, + Baz = 42, + Quux = 43, +} +``` + + ### `add_explicit_type` **Source:** [add_explicit_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_explicit_type.rs#L7) @@ -257,7 +283,7 @@ fn main() { ### `apply_demorgan` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L16) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L23) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws). This transforms expressions of the form `!l || !r` into `!(l && r)`. @@ -280,7 +306,7 @@ fn main() { ### `apply_demorgan_iterator` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L147) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L154) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to `Iterator::all` and `Iterator::any`. @@ -350,40 +376,6 @@ fn some_function(x: i32) { ``` -### `bool_to_enum` -**Source:** [bool_to_enum.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/bool_to_enum.rs#L29) - -This converts boolean local variables, fields, constants, and statics into a new -enum with two variants `Bool::True` and `Bool::False`, as well as replacing -all assignments with the variants and replacing all usages with `== Bool::True` or -`== Bool::False`. - -#### Before -```rust -fn main() { - let ┃bool = true; - - if bool { - println!("foo"); - } -} -``` - -#### After -```rust -#[derive(PartialEq, Eq)] -enum Bool { True, False } - -fn main() { - let bool = Bool::True; - - if bool == Bool::True { - println!("foo"); - } -} -``` - - ### `change_visibility` **Source:** [change_visibility.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/change_visibility.rs#L13) @@ -442,6 +434,40 @@ fn main() { ``` +### `convert_bool_to_enum` +**Source:** [convert_bool_to_enum.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_to_enum.rs#L29) + +This converts boolean local variables, fields, constants, and statics into a new +enum with two variants `Bool::True` and `Bool::False`, as well as replacing +all assignments with the variants and replacing all usages with `== Bool::True` or +`== Bool::False`. + +#### Before +```rust +fn main() { + let ┃bool = true; + + if bool { + println!("foo"); + } +} +``` + +#### After +```rust +#[derive(PartialEq, Eq)] +enum Bool { True, False } + +fn main() { + let bool = Bool::True; + + if bool == Bool::True { + println!("foo"); + } +} +``` + + ### `convert_closure_to_fn` **Source:** [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L25) @@ -1043,28 +1069,26 @@ pub use foo::{Bar, Baz}; ``` -### `explicit_enum_discriminant` -**Source:** [explicit_enum_discriminant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/explicit_enum_discriminant.rs#L11) +### `expand_rest_pattern` +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L8) -Adds explicit discriminant to all enum variants. +Fills fields by replacing rest pattern in record patterns. #### Before ```rust -enum TheEnum┃ { - Foo, - Bar, - Baz = 42, - Quux, +struct Bar { y: Y, z: Z } + +fn foo(bar: Bar) { + let Bar { ..┃ } = bar; } ``` #### After ```rust -enum TheEnum { - Foo = 0, - Bar = 1, - Baz = 42, - Quux = 43, +struct Bar { y: Y, z: Z } + +fn foo(bar: Bar) { + let Bar { y, z } = bar; } ``` @@ -1255,30 +1279,6 @@ fn main() { ``` -### `fill_record_pattern_fields` -**Source:** [fill_record_pattern_fields.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs#L8) - -Fills fields by replacing rest pattern in record patterns. - -#### Before -```rust -struct Bar { y: Y, z: Z } - -fn foo(bar: Bar) { - let Bar { ..┃ } = bar; -} -``` - -#### After -```rust -struct Bar { y: Y, z: Z } - -fn foo(bar: Bar) { - let Bar { y, z } = bar; -} -``` - - ### `fix_visibility` **Source:** [fix_visibility.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/fix_visibility.rs#L14) @@ -2403,22 +2403,6 @@ fn main() -> () { ``` -### `introduce_named_generic` -**Source:** [introduce_named_generic.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/introduce_named_generic.rs#L7) - -Replaces `impl Trait` function argument with the named generic. - -#### Before -```rust -fn foo(bar: ┃impl Bar) {} -``` - -#### After -```rust -fn foo<┃B: Bar>(bar: B) {} -``` - - ### `introduce_named_lifetime` **Source:** [introduce_named_lifetime.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/introduce_named_lifetime.rs#L13) @@ -2447,6 +2431,22 @@ impl<'a> Cursor<'a> { ``` +### `introduce_named_type_parameter` +**Source:** [introduce_named_type_parameter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs#L7) + +Replaces `impl Trait` function argument with the named generic. + +#### Before +```rust +fn foo(bar: ┃impl Bar) {} +``` + +#### After +```rust +fn foo<┃B: Bar>(bar: B) {} +``` + + ### `invert_if` **Source:** [invert_if.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/invert_if.rs#L13) From ef028d79d6d4d54576c88dbd1f9de7f4824c0289 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 2 Mar 2025 08:27:40 +0000 Subject: [PATCH 538/991] do not build additional stage on compiler paths When calling `x build compiler (or rustc) --stage N` bootstrap builds stage N+1 compiler, which is clearly not what we requested. This doesn't happen when running `x build --stage N` without explicitly targeting the compiler. The changes applied fix this issue. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 6 ++++-- src/bootstrap/src/core/builder/tests.rs | 4 +--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 9d3d07c83d25..163b59b10dee 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -993,7 +993,9 @@ impl Step for Rustc { fn make_run(run: RunConfig<'_>) { let crates = run.cargo_crates_in_set(); run.builder.ensure(Rustc { - compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()), + compiler: run + .builder + .compiler(run.builder.top_stage.saturating_sub(1), run.build_triple()), target: run.target, crates, }); @@ -1902,7 +1904,7 @@ impl Step for Assemble { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Assemble { - target_compiler: run.builder.compiler(run.builder.top_stage + 1, run.target), + target_compiler: run.builder.compiler(run.builder.top_stage, run.target), }); } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 0eaa89792bd9..9adc27645f1f 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -664,15 +664,13 @@ mod dist { std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2), ] ); - assert_eq!(builder.cache.all::().len(), 5); + assert_eq!(builder.cache.all::().len(), 4); assert_eq!( first(builder.cache.all::()), &[ rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), - rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2), rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), - rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2), ] ); } From 4d0a1af920c088f4a56def2c2c4d97cb7c60f1ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 2 Mar 2025 09:59:28 +0100 Subject: [PATCH 539/991] edit mailmap --- .mailmap | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.mailmap b/.mailmap index eb6a9fcabca9..a791daa681d4 100644 --- a/.mailmap +++ b/.mailmap @@ -292,6 +292,9 @@ James Hinshelwood James Miller James Perry James Sanderson +Jana Dönszelmann +Jana Dönszelmann +Jana Dönszelmann Jan-Erik Rediger Jaro Fietz Jason Fager From 298fb8af65cdbecd81ed4a51d3602641caaad909 Mon Sep 17 00:00:00 2001 From: NotLebedev Date: Sat, 1 Mar 2025 09:57:04 +0300 Subject: [PATCH 540/991] Add name and trimmed_name methods to DefId --- compiler/stable_mir/src/crate_def.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/compiler/stable_mir/src/crate_def.rs b/compiler/stable_mir/src/crate_def.rs index 8c6fd99f98a1..469e8a7cf899 100644 --- a/compiler/stable_mir/src/crate_def.rs +++ b/compiler/stable_mir/src/crate_def.rs @@ -10,6 +10,27 @@ use crate::{Crate, Symbol, with}; #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] pub struct DefId(pub(crate) usize); +impl DefId { + /// Return fully qualified name of this definition + pub fn name(&self) -> Symbol { + with(|cx| cx.def_name(*self, false)) + } + + /// Return a trimmed name of this definition. + /// + /// This can be used to print more user friendly diagnostic messages. + /// + /// If a symbol name can only be imported from one place for a type, and as + /// long as it was not glob-imported anywhere in the current crate, we trim its + /// path and print only the name. + /// + /// For example, this function may shorten `std::vec::Vec` to just `Vec`, + /// as long as there is no other `Vec` importable anywhere. + pub fn trimmed_name(&self) -> Symbol { + with(|cx| cx.def_name(*self, true)) + } +} + /// A trait for retrieving information about a particular definition. /// /// Implementors must provide the implementation of `def_id` which will be used to retrieve From 141d2f3f025c649e92e71dc1f22198cb265c435a Mon Sep 17 00:00:00 2001 From: NotLebedev Date: Sat, 1 Mar 2025 10:57:17 +0300 Subject: [PATCH 541/991] Replace usages of `Context.def_name` Use `DefId.name` and `DefId.trimmed_name` instead --- compiler/stable_mir/src/crate_def.rs | 6 ++---- compiler/stable_mir/src/lib.rs | 5 +---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/compiler/stable_mir/src/crate_def.rs b/compiler/stable_mir/src/crate_def.rs index 469e8a7cf899..d36426d5a990 100644 --- a/compiler/stable_mir/src/crate_def.rs +++ b/compiler/stable_mir/src/crate_def.rs @@ -41,8 +41,7 @@ pub trait CrateDef { /// Return the fully qualified name of the current definition. fn name(&self) -> Symbol { - let def_id = self.def_id(); - with(|cx| cx.def_name(def_id, false)) + self.def_id().name() } /// Return a trimmed name of this definition. @@ -56,8 +55,7 @@ pub trait CrateDef { /// For example, this function may shorten `std::vec::Vec` to just `Vec`, /// as long as there is no other `Vec` importable anywhere. fn trimmed_name(&self) -> Symbol { - let def_id = self.def_id(); - with(|cx| cx.def_name(def_id, true)) + self.def_id().trimmed_name() } /// Return information about the crate where this definition is declared. diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 0b4cebadad1d..8df36e23c4a2 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -48,10 +48,7 @@ pub type CrateNum = usize; impl Debug for DefId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("DefId") - .field("id", &self.0) - .field("name", &with(|cx| cx.def_name(*self, false))) - .finish() + f.debug_struct("DefId").field("id", &self.0).field("name", &self.name()).finish() } } From 19a909ae0e9f923db2da0fc10264a75b7aa5ad99 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 9 Dec 2024 09:25:22 +0000 Subject: [PATCH 542/991] dec2flt: Refactor float traits A lot of the magic constants can be turned into expressions. This reduces some code duplication. Additionally, add traits to make these operations fully generic. This will make it easier to support `f16` and `f128`. --- library/core/src/num/dec2flt/float.rs | 270 ++++++++++++------ library/core/src/num/dec2flt/lemire.rs | 18 +- library/core/src/num/dec2flt/mod.rs | 6 +- library/core/src/num/dec2flt/slow.rs | 18 +- library/coretests/tests/num/dec2flt/float.rs | 40 +++ library/coretests/tests/num/dec2flt/lemire.rs | 6 + library/coretests/tests/num/dec2flt/parse.rs | 15 + src/etc/test-float-parse/src/traits.rs | 6 +- 8 files changed, 266 insertions(+), 113 deletions(-) diff --git a/library/core/src/num/dec2flt/float.rs b/library/core/src/num/dec2flt/float.rs index da57aa9a546a..b8a28a675691 100644 --- a/library/core/src/num/dec2flt/float.rs +++ b/library/core/src/num/dec2flt/float.rs @@ -1,14 +1,57 @@ //! Helper trait for generic float types. +use core::f64; + use crate::fmt::{Debug, LowerExp}; use crate::num::FpCategory; -use crate::ops::{Add, Div, Mul, Neg}; +use crate::ops::{self, Add, Div, Mul, Neg}; -/// A helper trait to avoid duplicating basically all the conversion code for `f32` and `f64`. +/// Lossy `as` casting between two types. +pub trait CastInto: Copy { + fn cast(self) -> T; +} + +/// Collection of traits that allow us to be generic over integer size. +pub trait Integer: + Sized + + Clone + + Copy + + Debug + + ops::Shr + + ops::Shl + + ops::BitAnd + + ops::BitOr + + PartialEq + + CastInto +{ + const ZERO: Self; + const ONE: Self; +} + +macro_rules! int { + ($($ty:ty),+) => { + $( + impl CastInto for $ty { + fn cast(self) -> i16 { + self as i16 + } + } + + impl Integer for $ty { + const ZERO: Self = 0; + const ONE: Self = 1; + } + )+ + } +} + +int!(u32, u64); + +/// A helper trait to avoid duplicating basically all the conversion code for IEEE floats. /// /// See the parent module's doc comment for why this is necessary. /// -/// Should **never ever** be implemented for other types or be used outside the dec2flt module. +/// Should **never ever** be implemented for other types or be used outside the `dec2flt` module. #[doc(hidden)] pub trait RawFloat: Sized @@ -24,62 +67,107 @@ pub trait RawFloat: + Copy + Debug { + /// The unsigned integer with the same size as the float + type Int: Integer + Into; + + /* general constants */ + const INFINITY: Self; const NEG_INFINITY: Self; const NAN: Self; const NEG_NAN: Self; - /// The number of bits in the significand, *excluding* the hidden bit. - const MANTISSA_EXPLICIT_BITS: usize; + /// Bit width of the float + const BITS: u32; - // Round-to-even only happens for negative values of q - // when q ≥ −4 in the 64-bit case and when q ≥ −17 in - // the 32-bitcase. - // - // When q ≥ 0,we have that 5^q ≤ 2m+1. In the 64-bit case,we - // have 5^q ≤ 2m+1 ≤ 2^54 or q ≤ 23. In the 32-bit case,we have - // 5^q ≤ 2m+1 ≤ 2^25 or q ≤ 10. - // - // When q < 0, we have w ≥ (2m+1)×5^−q. We must have that w < 2^64 - // so (2m+1)×5^−q < 2^64. We have that 2m+1 > 2^53 (64-bit case) - // or 2m+1 > 2^24 (32-bit case). Hence,we must have 2^53×5^−q < 2^64 - // (64-bit) and 2^24×5^−q < 2^64 (32-bit). Hence we have 5^−q < 2^11 - // or q ≥ −4 (64-bit case) and 5^−q < 2^40 or q ≥ −17 (32-bitcase). - // - // Thus we have that we only need to round ties to even when - // we have that q ∈ [−4,23](in the 64-bit case) or q∈[−17,10] - // (in the 32-bit case). In both cases,the power of five(5^|q|) - // fits in a 64-bit word. + /// The number of bits in the significand, *including* the hidden bit. + const SIG_TOTAL_BITS: u32; + + const EXP_MASK: Self::Int; + const SIG_MASK: Self::Int; + + /// The number of bits in the significand, *excluding* the hidden bit. + const SIG_BITS: u32 = Self::SIG_TOTAL_BITS - 1; + + /// Number of bits in the exponent. + const EXP_BITS: u32 = Self::BITS - Self::SIG_BITS - 1; + + /// The saturated (maximum bitpattern) value of the exponent, i.e. the infinite + /// representation. + /// + /// This shifted fully right, use `EXP_MASK` for the shifted value. + const EXP_SAT: u32 = (1 << Self::EXP_BITS) - 1; + + /// Signed version of `EXP_SAT` since we convert a lot. + const INFINITE_POWER: i32 = Self::EXP_SAT as i32; + + /// The exponent bias value. This is also the maximum value of the exponent. + const EXP_BIAS: u32 = Self::EXP_SAT >> 1; + + /// Minimum exponent value of normal values. + const EXP_MIN: i32 = -(Self::EXP_BIAS as i32 - 1); + + /// Round-to-even only happens for negative values of q + /// when q ≥ −4 in the 64-bit case and when q ≥ −17 in + /// the 32-bitcase. + /// + /// When q ≥ 0,we have that 5^q ≤ 2m+1. In the 64-bit case,we + /// have 5^q ≤ 2m+1 ≤ 2^54 or q ≤ 23. In the 32-bit case,we have + /// 5^q ≤ 2m+1 ≤ 2^25 or q ≤ 10. + /// + /// When q < 0, we have w ≥ (2m+1)×5^−q. We must have that w < 2^64 + /// so (2m+1)×5^−q < 2^64. We have that 2m+1 > 2^53 (64-bit case) + /// or 2m+1 > 2^24 (32-bit case). Hence,we must have 2^53×5^−q < 2^64 + /// (64-bit) and 2^24×5^−q < 2^64 (32-bit). Hence we have 5^−q < 2^11 + /// or q ≥ −4 (64-bit case) and 5^−q < 2^40 or q ≥ −17 (32-bitcase). + /// + /// Thus we have that we only need to round ties to even when + /// we have that q ∈ [−4,23](in the 64-bit case) or q∈[−17,10] + /// (in the 32-bit case). In both cases,the power of five(5^|q|) + /// fits in a 64-bit word. const MIN_EXPONENT_ROUND_TO_EVEN: i32; const MAX_EXPONENT_ROUND_TO_EVEN: i32; - // Minimum exponent that for a fast path case, or `-⌊(MANTISSA_EXPLICIT_BITS+1)/log2(5)⌋` - const MIN_EXPONENT_FAST_PATH: i64; + /* limits related to Fast pathing */ - // Maximum exponent that for a fast path case, or `⌊(MANTISSA_EXPLICIT_BITS+1)/log2(5)⌋` - const MAX_EXPONENT_FAST_PATH: i64; + /// Largest decimal exponent for a non-infinite value. + /// + /// This is the max exponent in binary converted to the max exponent in decimal. Allows fast + /// pathing anything larger than `10^LARGEST_POWER_OF_TEN`, which will round to infinity. + const LARGEST_POWER_OF_TEN: i32 = { + let largest_pow2 = Self::EXP_BIAS + 1; + pow2_to_pow10(largest_pow2 as i64) as i32 + }; - // Maximum exponent that can be represented for a disguised-fast path case. - // This is `MAX_EXPONENT_FAST_PATH + ⌊(MANTISSA_EXPLICIT_BITS+1)/log2(10)⌋` - const MAX_EXPONENT_DISGUISED_FAST_PATH: i64; - - // Minimum exponent value `-(1 << (EXP_BITS - 1)) + 1`. - const MINIMUM_EXPONENT: i32; - - // Largest exponent value `(1 << EXP_BITS) - 1`. - const INFINITE_POWER: i32; - - // Index (in bits) of the sign. - const SIGN_INDEX: usize; - - // Smallest decimal exponent for a non-zero value. + /// Smallest decimal exponent for a non-zero value. This allows for fast pathing anything + /// smaller than `10^SMALLEST_POWER_OF_TEN`, which will round to zero. + /// + /// The smallest power of ten is represented by `⌊log10(2^-n / (2^64 - 1))⌋`, where `n` is + /// the smallest power of two. The `2^64 - 1)` denomenator comes from the number of values + /// that are representable by the intermediate storage format. I don't actually know _why_ + /// the storage format is relevant here. + /// + /// The values may be calculated using the formula. Unfortunately we cannot calculate them at + /// compile time since intermediates exceed the range of an `f64`. const SMALLEST_POWER_OF_TEN: i32; - // Largest decimal exponent for a non-infinite value. - const LARGEST_POWER_OF_TEN: i32; + /// Maximum exponent for a fast path case, or `⌊(SIG_BITS+1)/log2(5)⌋` + // assuming FLT_EVAL_METHOD = 0 + const MAX_EXPONENT_FAST_PATH: i64 = { + let log2_5 = f64::consts::LOG2_10 - 1.0; + (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64 + }; - // Maximum mantissa for the fast-path (`1 << 53` for f64). - const MAX_MANTISSA_FAST_PATH: u64 = 2_u64 << Self::MANTISSA_EXPLICIT_BITS; + /// Minimum exponent for a fast path case, or `-⌊(SIG_BITS+1)/log2(5)⌋` + const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH; + + /// Maximum exponent that can be represented for a disguised-fast path case. + /// This is `MAX_EXPONENT_FAST_PATH + ⌊(SIG_BITS+1)/log2(10)⌋` + const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = + Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64; + + /// Maximum mantissa for the fast-path (`1 << 53` for f64). + const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS; /// Converts integer into float through an as cast. /// This is only called in the fast-path algorithm, and therefore @@ -96,27 +184,51 @@ pub trait RawFloat: /// Returns the category that this number falls into. fn classify(self) -> FpCategory; + /// Transmute to the integer representation + fn to_bits(self) -> Self::Int; + /// Returns the mantissa, exponent and sign as integers. - fn integer_decode(self) -> (u64, i16, i8); + /// + /// That is, this returns `(m, p, s)` such that `s * m * 2^p` represents the original float. + /// For 0, the exponent will be `-(EXP_BIAS + SIG_BITS`, which is the + /// minimum subnormal power. + fn integer_decode(self) -> (u64, i16, i8) { + let bits = self.to_bits(); + let sign: i8 = if bits >> (Self::BITS - 1) == Self::Int::ZERO { 1 } else { -1 }; + let mut exponent: i16 = ((bits & Self::EXP_MASK) >> Self::SIG_BITS).cast(); + let mantissa = if exponent == 0 { + (bits & Self::SIG_MASK) << 1 + } else { + (bits & Self::SIG_MASK) | (Self::Int::ONE << Self::SIG_BITS) + }; + // Exponent bias + mantissa shift + exponent -= (Self::EXP_BIAS + Self::SIG_BITS) as i16; + (mantissa.into(), exponent, sign) + } +} + +/// Solve for `b` in `10^b = 2^a` +const fn pow2_to_pow10(a: i64) -> i64 { + let res = (a as f64) / f64::consts::LOG2_10; + res as i64 } impl RawFloat for f32 { + type Int = u32; + const INFINITY: Self = f32::INFINITY; const NEG_INFINITY: Self = f32::NEG_INFINITY; const NAN: Self = f32::NAN; const NEG_NAN: Self = -f32::NAN; - const MANTISSA_EXPLICIT_BITS: usize = 23; + const BITS: u32 = 32; + const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS; + const EXP_MASK: Self::Int = Self::EXP_MASK; + const SIG_MASK: Self::Int = Self::MAN_MASK; + const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -17; const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10; - const MIN_EXPONENT_FAST_PATH: i64 = -10; // assuming FLT_EVAL_METHOD = 0 - const MAX_EXPONENT_FAST_PATH: i64 = 10; - const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = 17; - const MINIMUM_EXPONENT: i32 = -127; - const INFINITE_POWER: i32 = 0xFF; - const SIGN_INDEX: usize = 31; const SMALLEST_POWER_OF_TEN: i32 = -65; - const LARGEST_POWER_OF_TEN: i32 = 38; #[inline] fn from_u64(v: u64) -> Self { @@ -136,16 +248,8 @@ impl RawFloat for f32 { TABLE[exponent & 15] } - /// Returns the mantissa, exponent and sign as integers. - fn integer_decode(self) -> (u64, i16, i8) { - let bits = self.to_bits(); - let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 }; - let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; - let mantissa = - if exponent == 0 { (bits & 0x7fffff) << 1 } else { (bits & 0x7fffff) | 0x800000 }; - // Exponent bias + mantissa shift - exponent -= 127 + 23; - (mantissa as u64, exponent, sign) + fn to_bits(self) -> Self::Int { + self.to_bits() } fn classify(self) -> FpCategory { @@ -154,22 +258,21 @@ impl RawFloat for f32 { } impl RawFloat for f64 { - const INFINITY: Self = f64::INFINITY; - const NEG_INFINITY: Self = f64::NEG_INFINITY; - const NAN: Self = f64::NAN; - const NEG_NAN: Self = -f64::NAN; + type Int = u64; + + const INFINITY: Self = Self::INFINITY; + const NEG_INFINITY: Self = Self::NEG_INFINITY; + const NAN: Self = Self::NAN; + const NEG_NAN: Self = -Self::NAN; + + const BITS: u32 = 64; + const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS; + const EXP_MASK: Self::Int = Self::EXP_MASK; + const SIG_MASK: Self::Int = Self::MAN_MASK; - const MANTISSA_EXPLICIT_BITS: usize = 52; const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -4; const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23; - const MIN_EXPONENT_FAST_PATH: i64 = -22; // assuming FLT_EVAL_METHOD = 0 - const MAX_EXPONENT_FAST_PATH: i64 = 22; - const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = 37; - const MINIMUM_EXPONENT: i32 = -1023; - const INFINITE_POWER: i32 = 0x7FF; - const SIGN_INDEX: usize = 63; const SMALLEST_POWER_OF_TEN: i32 = -342; - const LARGEST_POWER_OF_TEN: i32 = 308; #[inline] fn from_u64(v: u64) -> Self { @@ -190,19 +293,8 @@ impl RawFloat for f64 { TABLE[exponent & 31] } - /// Returns the mantissa, exponent and sign as integers. - fn integer_decode(self) -> (u64, i16, i8) { - let bits = self.to_bits(); - let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; - let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; - let mantissa = if exponent == 0 { - (bits & 0xfffffffffffff) << 1 - } else { - (bits & 0xfffffffffffff) | 0x10000000000000 - }; - // Exponent bias + mantissa shift - exponent -= 1023 + 52; - (mantissa, exponent, sign) + fn to_bits(self) -> Self::Int { + self.to_bits() } fn classify(self) -> FpCategory { diff --git a/library/core/src/num/dec2flt/lemire.rs b/library/core/src/num/dec2flt/lemire.rs index 0cc39cb9b623..f84929a03c17 100644 --- a/library/core/src/num/dec2flt/lemire.rs +++ b/library/core/src/num/dec2flt/lemire.rs @@ -38,7 +38,7 @@ pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { // Normalize our significant digits, so the most-significant bit is set. let lz = w.leading_zeros(); w <<= lz; - let (lo, hi) = compute_product_approx(q, w, F::MANTISSA_EXPLICIT_BITS + 3); + let (lo, hi) = compute_product_approx(q, w, F::SIG_BITS as usize + 3); if lo == 0xFFFF_FFFF_FFFF_FFFF { // If we have failed to approximate w x 5^-q with our 128-bit value. // Since the addition of 1 could lead to an overflow which could then @@ -61,8 +61,8 @@ pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { } } let upperbit = (hi >> 63) as i32; - let mut mantissa = hi >> (upperbit + 64 - F::MANTISSA_EXPLICIT_BITS as i32 - 3); - let mut power2 = power(q as i32) + upperbit - lz as i32 - F::MINIMUM_EXPONENT; + let mut mantissa = hi >> (upperbit + 64 - F::SIG_BITS as i32 - 3); + let mut power2 = power(q as i32) + upperbit - lz as i32 - F::EXP_MIN + 1; if power2 <= 0 { if -power2 + 1 >= 64 { // Have more than 64 bits below the minimum exponent, must be 0. @@ -72,7 +72,7 @@ pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { mantissa >>= -power2 + 1; mantissa += mantissa & 1; mantissa >>= 1; - power2 = (mantissa >= (1_u64 << F::MANTISSA_EXPLICIT_BITS)) as i32; + power2 = (mantissa >= (1_u64 << F::SIG_BITS)) as i32; return BiasedFp { m: mantissa, p_biased: power2 }; } // Need to handle rounding ties. Normally, we need to round up, @@ -89,8 +89,8 @@ pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { if lo <= 1 && q >= F::MIN_EXPONENT_ROUND_TO_EVEN as i64 && q <= F::MAX_EXPONENT_ROUND_TO_EVEN as i64 - && mantissa & 3 == 1 - && (mantissa << (upperbit + 64 - F::MANTISSA_EXPLICIT_BITS as i32 - 3)) == hi + && mantissa & 0b11 == 0b01 + && (mantissa << (upperbit + 64 - F::SIG_BITS as i32 - 3)) == hi { // Zero the lowest bit, so we don't round up. mantissa &= !1_u64; @@ -98,15 +98,15 @@ pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { // Round-to-even, then shift the significant digits into place. mantissa += mantissa & 1; mantissa >>= 1; - if mantissa >= (2_u64 << F::MANTISSA_EXPLICIT_BITS) { + if mantissa >= (2_u64 << F::SIG_BITS) { // Rounding up overflowed, so the carry bit is set. Set the // mantissa to 1 (only the implicit, hidden bit is set) and // increase the exponent. - mantissa = 1_u64 << F::MANTISSA_EXPLICIT_BITS; + mantissa = 1_u64 << F::SIG_BITS; power2 += 1; } // Zero out the hidden bit. - mantissa &= !(1_u64 << F::MANTISSA_EXPLICIT_BITS); + mantissa &= !(1_u64 << F::SIG_BITS); if power2 >= F::INFINITE_POWER { // Exponent is above largest normal value, must be infinite. return fp_inf; diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 9d1989c4b817..d1a0e1db3131 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -232,10 +232,10 @@ pub fn pfe_invalid() -> ParseFloatError { } /// Converts a `BiasedFp` to the closest machine float type. -fn biased_fp_to_float(x: BiasedFp) -> T { +fn biased_fp_to_float(x: BiasedFp) -> F { let mut word = x.m; - word |= (x.p_biased as u64) << T::MANTISSA_EXPLICIT_BITS; - T::from_u64_bits(word) + word |= (x.p_biased as u64) << F::SIG_BITS; + F::from_u64_bits(word) } /// Converts a decimal string into a floating point number. diff --git a/library/core/src/num/dec2flt/slow.rs b/library/core/src/num/dec2flt/slow.rs index e0c4ae117da0..3baed4265239 100644 --- a/library/core/src/num/dec2flt/slow.rs +++ b/library/core/src/num/dec2flt/slow.rs @@ -74,36 +74,36 @@ pub(crate) fn parse_long_mantissa(s: &[u8]) -> BiasedFp { } // We are now in the range [1/2 ... 1] but the binary format uses [1 ... 2]. exp2 -= 1; - while (F::MINIMUM_EXPONENT + 1) > exp2 { - let mut n = ((F::MINIMUM_EXPONENT + 1) - exp2) as usize; + while F::EXP_MIN > exp2 { + let mut n = (F::EXP_MIN - exp2) as usize; if n > MAX_SHIFT { n = MAX_SHIFT; } d.right_shift(n); exp2 += n as i32; } - if (exp2 - F::MINIMUM_EXPONENT) >= F::INFINITE_POWER { + if (exp2 - F::EXP_MIN + 1) >= F::INFINITE_POWER { return fp_inf; } // Shift the decimal to the hidden bit, and then round the value // to get the high mantissa+1 bits. - d.left_shift(F::MANTISSA_EXPLICIT_BITS + 1); + d.left_shift(F::SIG_BITS as usize + 1); let mut mantissa = d.round(); - if mantissa >= (1_u64 << (F::MANTISSA_EXPLICIT_BITS + 1)) { + if mantissa >= (1_u64 << (F::SIG_BITS + 1)) { // Rounding up overflowed to the carry bit, need to // shift back to the hidden bit. d.right_shift(1); exp2 += 1; mantissa = d.round(); - if (exp2 - F::MINIMUM_EXPONENT) >= F::INFINITE_POWER { + if (exp2 - F::EXP_MIN + 1) >= F::INFINITE_POWER { return fp_inf; } } - let mut power2 = exp2 - F::MINIMUM_EXPONENT; - if mantissa < (1_u64 << F::MANTISSA_EXPLICIT_BITS) { + let mut power2 = exp2 - F::EXP_MIN + 1; + if mantissa < (1_u64 << F::SIG_BITS) { power2 -= 1; } // Zero out all the bits above the explicit mantissa bits. - mantissa &= (1_u64 << F::MANTISSA_EXPLICIT_BITS) - 1; + mantissa &= (1_u64 << F::SIG_BITS) - 1; BiasedFp { m: mantissa, p_biased: power2 } } diff --git a/library/coretests/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs index 40f0776e0214..b5afd3e3b243 100644 --- a/library/coretests/tests/num/dec2flt/float.rs +++ b/library/coretests/tests/num/dec2flt/float.rs @@ -31,3 +31,43 @@ fn test_f64_integer_decode() { let (nan_m, nan_p, _nan_s) = f64::NAN.integer_decode(); assert_eq!((nan_m, nan_p), (6755399441055744, 972)); } + +/* Sanity checks of computed magic numbers */ + +#[test] +fn test_f32_consts() { + assert_eq!(::INFINITY, f32::INFINITY); + assert_eq!(::NEG_INFINITY, -f32::INFINITY); + assert_eq!(::NAN.to_bits(), f32::NAN.to_bits()); + assert_eq!(::NEG_NAN.to_bits(), (-f32::NAN).to_bits()); + assert_eq!(::SIG_BITS, 23); + assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -17); + assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 10); + assert_eq!(::MIN_EXPONENT_FAST_PATH, -10); + assert_eq!(::MAX_EXPONENT_FAST_PATH, 10); + assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 17); + assert_eq!(::EXP_MIN, -126); + assert_eq!(::EXP_SAT, 0xff); + assert_eq!(::SMALLEST_POWER_OF_TEN, -65); + assert_eq!(::LARGEST_POWER_OF_TEN, 38); + assert_eq!(::MAX_MANTISSA_FAST_PATH, 16777216); +} + +#[test] +fn test_f64_consts() { + assert_eq!(::INFINITY, f64::INFINITY); + assert_eq!(::NEG_INFINITY, -f64::INFINITY); + assert_eq!(::NAN.to_bits(), f64::NAN.to_bits()); + assert_eq!(::NEG_NAN.to_bits(), (-f64::NAN).to_bits()); + assert_eq!(::SIG_BITS, 52); + assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -4); + assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 23); + assert_eq!(::MIN_EXPONENT_FAST_PATH, -22); + assert_eq!(::MAX_EXPONENT_FAST_PATH, 22); + assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 37); + assert_eq!(::EXP_MIN, -1022); + assert_eq!(::EXP_SAT, 0x7ff); + assert_eq!(::SMALLEST_POWER_OF_TEN, -342); + assert_eq!(::LARGEST_POWER_OF_TEN, 308); + assert_eq!(::MAX_MANTISSA_FAST_PATH, 9007199254740992); +} diff --git a/library/coretests/tests/num/dec2flt/lemire.rs b/library/coretests/tests/num/dec2flt/lemire.rs index 9f228a25e46b..0db80fbd5250 100644 --- a/library/coretests/tests/num/dec2flt/lemire.rs +++ b/library/coretests/tests/num/dec2flt/lemire.rs @@ -1,3 +1,4 @@ +use core::num::dec2flt::float::RawFloat; use core::num::dec2flt::lemire::compute_float; fn compute_float32(q: i64, w: u64) -> (i32, u64) { @@ -27,6 +28,11 @@ fn compute_float_f32_rounding() { // Let's check the lines to see if anything is different in table... assert_eq!(compute_float32(-10, 167772190000000000), (151, 2)); assert_eq!(compute_float32(-10, 167772200000000000), (151, 2)); + + // Check the rounding point between infinity and the next representable number down + assert_eq!(compute_float32(38, 3), (f32::INFINITE_POWER - 1, 6402534)); + assert_eq!(compute_float32(38, 4), (f32::INFINITE_POWER, 0)); // infinity + assert_eq!(compute_float32(20, 3402823470000000000), (f32::INFINITE_POWER - 1, 8388607)); } #[test] diff --git a/library/coretests/tests/num/dec2flt/parse.rs b/library/coretests/tests/num/dec2flt/parse.rs index ec705a61e13c..59be3915052d 100644 --- a/library/coretests/tests/num/dec2flt/parse.rs +++ b/library/coretests/tests/num/dec2flt/parse.rs @@ -57,6 +57,21 @@ macro_rules! assert_float_result_bits_eq { }}; } +#[test] +fn regression() { + // These showed up in fuzz tests when the minimum exponent was incorrect. + assert_float_result_bits_eq!( + 0x0, + f64, + "3313756768023998018398807867233977556112078681253148176737587500333136120852692315608454494981109839693784033457129423181787087843504060087613228932431e-475" + ); + assert_float_result_bits_eq!( + 0x0, + f64, + "5298127456259331337220.92759278003098321644501973966679724599271041396379712108366679824365568578569680024083293475291869842408884554511641179110778276695274832779269225510492006696321279587846006535230380114430977056662212751544508159333199129106162019382177820713609e-346" + ); +} + #[test] fn issue31109() { // Regression test for #31109. diff --git a/src/etc/test-float-parse/src/traits.rs b/src/etc/test-float-parse/src/traits.rs index f5333d63b369..f7f5f5dd35b7 100644 --- a/src/etc/test-float-parse/src/traits.rs +++ b/src/etc/test-float-parse/src/traits.rs @@ -147,12 +147,12 @@ pub trait Float: } macro_rules! impl_float { - ($($fty:ty, $ity:ty, $bits:literal);+) => { + ($($fty:ty, $ity:ty);+) => { $( impl Float for $fty { type Int = $ity; type SInt = ::Signed; - const BITS: u32 = $bits; + const BITS: u32 = <$ity>::BITS; const MAN_BITS: u32 = Self::MANTISSA_DIGITS - 1; const MAN_MASK: Self::Int = (Self::Int::ONE << Self::MAN_BITS) - Self::Int::ONE; const SIGN_MASK: Self::Int = Self::Int::ONE << (Self::BITS-1); @@ -168,7 +168,7 @@ macro_rules! impl_float { } } -impl_float!(f32, u32, 32; f64, u64, 64); +impl_float!(f32, u32; f64, u64); /// A test generator. Should provide an iterator that produces unique patterns to parse. /// From 37e223ccaa1d0036540e6e3de5d4ed4b721afd60 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 9 Dec 2024 09:25:22 +0000 Subject: [PATCH 543/991] dec2flt: Refactor the fast path This is just a bit of code cleanup to make use of returning early. --- library/core/src/num/dec2flt/decimal.rs | 51 ++++++++++++------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/library/core/src/num/dec2flt/decimal.rs b/library/core/src/num/dec2flt/decimal.rs index 1ba9150a0119..db7176c12431 100644 --- a/library/core/src/num/dec2flt/decimal.rs +++ b/library/core/src/num/dec2flt/decimal.rs @@ -34,14 +34,15 @@ pub struct Decimal { impl Decimal { /// Detect if the float can be accurately reconstructed from native floats. #[inline] - fn is_fast_path(&self) -> bool { + fn can_use_fast_path(&self) -> bool { F::MIN_EXPONENT_FAST_PATH <= self.exponent && self.exponent <= F::MAX_EXPONENT_DISGUISED_FAST_PATH && self.mantissa <= F::MAX_MANTISSA_FAST_PATH && !self.many_digits } - /// The fast path algorithm using machine-sized integers and floats. + /// Try turning the decimal into an exact float representation, using machine-sized integers + /// and floats. /// /// This is extracted into a separate function so that it can be attempted before constructing /// a Decimal. This only works if both the mantissa and the exponent @@ -59,30 +60,28 @@ impl Decimal { // require setting it by changing the global state (like the control word of the x87 FPU). let _cw = set_precision::(); - if self.is_fast_path::() { - let mut value = if self.exponent <= F::MAX_EXPONENT_FAST_PATH { - // normal fast path - let value = F::from_u64(self.mantissa); - if self.exponent < 0 { - value / F::pow10_fast_path((-self.exponent) as _) - } else { - value * F::pow10_fast_path(self.exponent as _) - } - } else { - // disguised fast path - let shift = self.exponent - F::MAX_EXPONENT_FAST_PATH; - let mantissa = self.mantissa.checked_mul(INT_POW10[shift as usize])?; - if mantissa > F::MAX_MANTISSA_FAST_PATH { - return None; - } - F::from_u64(mantissa) * F::pow10_fast_path(F::MAX_EXPONENT_FAST_PATH as _) - }; - if self.negative { - value = -value; - } - Some(value) - } else { - None + if !self.can_use_fast_path::() { + return None; } + + let value = if self.exponent <= F::MAX_EXPONENT_FAST_PATH { + // normal fast path + let value = F::from_u64(self.mantissa); + if self.exponent < 0 { + value / F::pow10_fast_path((-self.exponent) as _) + } else { + value * F::pow10_fast_path(self.exponent as _) + } + } else { + // disguised fast path + let shift = self.exponent - F::MAX_EXPONENT_FAST_PATH; + let mantissa = self.mantissa.checked_mul(INT_POW10[shift as usize])?; + if mantissa > F::MAX_MANTISSA_FAST_PATH { + return None; + } + F::from_u64(mantissa) * F::pow10_fast_path(F::MAX_EXPONENT_FAST_PATH as _) + }; + + if self.negative { Some(-value) } else { Some(value) } } } From a3378f59388ced7f6011e508bb7dff5f90362e00 Mon Sep 17 00:00:00 2001 From: NotLebedev Date: Sun, 2 Mar 2025 13:02:20 +0300 Subject: [PATCH 544/991] Remove duplication in `name`/`trimmed_anem` docs Reference `DefId` in `CrateDef` docs to avoid duplicating long description of `trimmed_name` --- compiler/stable_mir/src/crate_def.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/compiler/stable_mir/src/crate_def.rs b/compiler/stable_mir/src/crate_def.rs index d36426d5a990..2577c281ca4f 100644 --- a/compiler/stable_mir/src/crate_def.rs +++ b/compiler/stable_mir/src/crate_def.rs @@ -40,20 +40,15 @@ pub trait CrateDef { fn def_id(&self) -> DefId; /// Return the fully qualified name of the current definition. + /// + /// See [`DefId::name`] for more details fn name(&self) -> Symbol { self.def_id().name() } /// Return a trimmed name of this definition. /// - /// This can be used to print more user friendly diagnostic messages. - /// - /// If a symbol name can only be imported from one place for a type, and as - /// long as it was not glob-imported anywhere in the current crate, we trim its - /// path and print only the name. - /// - /// For example, this function may shorten `std::vec::Vec` to just `Vec`, - /// as long as there is no other `Vec` importable anywhere. + /// See [`DefId::trimmed_name`] for more details fn trimmed_name(&self) -> Symbol { self.def_id().trimmed_name() } From cfb475c1d2ca0bf2c717c3750cb01c7435f01d71 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 2 Mar 2025 09:22:35 +0000 Subject: [PATCH 545/991] extend scope of build_all test Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder/tests.rs | 45 ++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 9adc27645f1f..1f27002f81ca 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -653,6 +653,20 @@ mod dist { &["compiler/rustc".into(), "library".into()], ); + assert_eq!(builder.config.stage, 2); + + // `compile::Rustc` includes one-stage-off compiler information as the target compiler + // artifacts get copied from there to the target stage sysroot. + // For example, `stage2/bin/rustc` gets copied from the `stage1-rustc` build directory. + assert_eq!( + first(builder.cache.all::()), + &[ + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), + ] + ); + assert_eq!( first(builder.cache.all::()), &[ @@ -664,13 +678,34 @@ mod dist { std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2), ] ); - assert_eq!(builder.cache.all::().len(), 4); + assert_eq!( - first(builder.cache.all::()), + first(builder.cache.all::()), &[ - rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), - rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), - rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), + compile::Assemble { + target_compiler: Compiler { + host: TargetSelection::from_user(TEST_TRIPLE_1), + stage: 0 + } + }, + compile::Assemble { + target_compiler: Compiler { + host: TargetSelection::from_user(TEST_TRIPLE_1), + stage: 1 + } + }, + compile::Assemble { + target_compiler: Compiler { + host: TargetSelection::from_user(TEST_TRIPLE_1), + stage: 2 + } + }, + compile::Assemble { + target_compiler: Compiler { + host: TargetSelection::from_user(TEST_TRIPLE_2), + stage: 2 + } + }, ] ); } From cbe32a76476c5fffa65783c82cf04072ac5886a6 Mon Sep 17 00:00:00 2001 From: Moulins Date: Sat, 1 Mar 2025 12:40:06 +0100 Subject: [PATCH 546/991] Remove layouting dead code for non-array SIMD types. These aren't supported anymore, and are already rejected in type checking. --- compiler/rustc_ty_utils/messages.ftl | 2 - compiler/rustc_ty_utils/src/errors.rs | 6 -- compiler/rustc_ty_utils/src/layout.rs | 89 ++++--------------- .../rust-analyzer/crates/hir-ty/src/layout.rs | 47 +++------- 4 files changed, 30 insertions(+), 114 deletions(-) diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl index ae795ef2214b..de2c3b63997e 100644 --- a/compiler/rustc_ty_utils/messages.ftl +++ b/compiler/rustc_ty_utils/messages.ftl @@ -42,8 +42,6 @@ ty_utils_logical_op_not_supported = unsupported operation in generic constants, ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants -ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with more than one array field - ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index 5497d7d0bd2a..8877bb45ceb2 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -82,12 +82,6 @@ pub(crate) struct ZeroLengthSimdType<'tcx> { pub ty: Ty<'tcx>, } -#[derive(Diagnostic)] -#[diag(ty_utils_multiple_array_fields_simd_type)] -pub(crate) struct MultipleArrayFieldsSimdType<'tcx> { - pub ty: Ty<'tcx>, -} - #[derive(Diagnostic)] #[diag(ty_utils_oversized_simd_type)] pub(crate) struct OversizedSimdType<'tcx> { diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 1a82d1713075..852d3fc58d87 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -28,9 +28,7 @@ use rustc_span::{Symbol, sym}; use tracing::{debug, instrument, trace}; use {rustc_abi as abi, rustc_hir as hir}; -use crate::errors::{ - MultipleArrayFieldsSimdType, NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType, -}; +use crate::errors::{NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType}; mod invariant; @@ -450,71 +448,26 @@ fn layout_of_uncached<'tcx>( // SIMD vector types. ty::Adt(def, args) if def.repr().simd() => { - if !def.is_struct() { - // Should have yielded E0517 by now. - let guar = tcx - .dcx() - .delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct"); - return Err(error(cx, LayoutError::ReferencesError(guar))); - } - - let fields = &def.non_enum_variant().fields; - - // Supported SIMD vectors are homogeneous ADTs with at least one field: + // Supported SIMD vectors are ADTs with a single array field: // - // * #[repr(simd)] struct S(T, T, T, T); - // * #[repr(simd)] struct S { x: T, y: T, z: T, w: T } // * #[repr(simd)] struct S([T; 4]) // // where T is a primitive scalar (integer/float/pointer). - - // SIMD vectors with zero fields are not supported. - // (should be caught by typeck) - if fields.is_empty() { - tcx.dcx().emit_fatal(ZeroLengthSimdType { ty }) - } - - // Type of the first ADT field: - let f0_ty = fields[FieldIdx::ZERO].ty(tcx, args); - - // Heterogeneous SIMD vectors are not supported: - // (should be caught by typeck) - for fi in fields { - if fi.ty(tcx, args) != f0_ty { - let guar = tcx.dcx().delayed_bug( - "#[repr(simd)] was applied to an ADT with heterogeneous field type", - ); - return Err(error(cx, LayoutError::ReferencesError(guar))); - } - } - - // The element type and number of elements of the SIMD vector - // are obtained from: - // - // * the element type and length of the single array field, if - // the first field is of array type, or - // - // * the homogeneous field type and the number of fields. - let (e_ty, e_len, is_array) = if let ty::Array(e_ty, _) = f0_ty.kind() { - // First ADT field is an array: - - // SIMD vectors with multiple array fields are not supported: - // Can't be caught by typeck with a generic simd type. - if def.non_enum_variant().fields.len() != 1 { - tcx.dcx().emit_fatal(MultipleArrayFieldsSimdType { ty }); - } - - // Extract the number of elements from the layout of the array field: - let FieldsShape::Array { count, .. } = cx.layout_of(f0_ty)?.layout.fields() else { - return Err(error(cx, LayoutError::Unknown(ty))); - }; - - (*e_ty, *count, true) - } else { - // First ADT field is not an array: - (f0_ty, def.non_enum_variant().fields.len() as _, false) + let Some(ty::Array(e_ty, e_len)) = def + .is_struct() + .then(|| &def.variant(FIRST_VARIANT).fields) + .filter(|fields| fields.len() == 1) + .map(|fields| *fields[FieldIdx::ZERO].ty(tcx, args).kind()) + else { + // Invalid SIMD types should have been caught by typeck by now. + let guar = tcx.dcx().delayed_bug("#[repr(simd)] was applied to an invalid ADT"); + return Err(error(cx, LayoutError::ReferencesError(guar))); }; + let e_len = extract_const_value(cx, ty, e_len)? + .try_to_target_usize(tcx) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; + // SIMD vectors of zero length are not supported. // Additionally, lengths are capped at 2^16 as a fixed maximum backends must // support. @@ -559,16 +512,12 @@ fn layout_of_uncached<'tcx>( }; let size = size.align_to(align.abi); - // Compute the placement of the vector fields: - let fields = if is_array { - FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() } - } else { - FieldsShape::Array { stride: e_ly.size, count: e_len } - }; - tcx.mk_layout(LayoutData { variants: Variants::Single { index: FIRST_VARIANT }, - fields, + fields: FieldsShape::Arbitrary { + offsets: [Size::ZERO].into(), + memory_index: [0].into(), + }, backend_repr: abi, largest_niche: e_ly.largest_niche, uninhabited: false, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index a4e49e0aa10a..7af31dabe45b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -133,40 +133,22 @@ fn layout_of_simd_ty( env: Arc, dl: &TargetDataLayout, ) -> Result, LayoutError> { - let fields = db.field_types(id.into()); - - // Supported SIMD vectors are homogeneous ADTs with at least one field: + // Supported SIMD vectors are homogeneous ADTs with exactly one array field: // - // * #[repr(simd)] struct S(T, T, T, T); - // * #[repr(simd)] struct S { it: T, y: T, z: T, w: T } // * #[repr(simd)] struct S([T; 4]) // // where T is a primitive scalar (integer/float/pointer). - - let f0_ty = match fields.iter().next() { - Some(it) => it.1.clone().substitute(Interner, subst), - None => return Err(LayoutError::InvalidSimdType), + let fields = db.field_types(id.into()); + let mut fields = fields.iter(); + let Some(TyKind::Array(e_ty, e_len)) = fields + .next() + .filter(|_| fields.next().is_none()) + .map(|f| f.1.clone().substitute(Interner, subst).kind(Interner).clone()) + else { + return Err(LayoutError::InvalidSimdType); }; - // The element type and number of elements of the SIMD vector - // are obtained from: - // - // * the element type and length of the single array field, if - // the first field is of array type, or - // - // * the homogeneous field type and the number of fields. - let (e_ty, e_len, is_array) = if let TyKind::Array(e_ty, _) = f0_ty.kind(Interner) { - // Extract the number of elements from the layout of the array field: - let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields - else { - return Err(LayoutError::Unknown); - }; - - (e_ty.clone(), count, true) - } else { - // First ADT field is not an array: - (f0_ty, fields.iter().count() as u64, false) - }; + let e_len = try_const_usize(db, &e_len).ok_or(LayoutError::HasErrorConst)? as u64; // Compute the ABI of the element type: let e_ly = db.layout_of_ty(e_ty, env)?; @@ -182,16 +164,9 @@ fn layout_of_simd_ty( let align = dl.llvmlike_vector_align(size); let size = size.align_to(align.abi); - // Compute the placement of the vector fields: - let fields = if is_array { - FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() } - } else { - FieldsShape::Array { stride: e_ly.size, count: e_len } - }; - Ok(Arc::new(Layout { variants: Variants::Single { index: struct_variant_idx() }, - fields, + fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }, backend_repr: BackendRepr::SimdVector { element: e_abi, count: e_len }, largest_niche: e_ly.largest_niche, uninhabited: false, From 6c1e5b4edba347920c44e94b80d07d298c9104a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Sun, 2 Mar 2025 16:05:13 +0200 Subject: [PATCH 547/991] Fix transparent diagnostics --- src/tools/rust-analyzer/editors/code/src/diagnostics.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/src/diagnostics.ts b/src/tools/rust-analyzer/editors/code/src/diagnostics.ts index 73621dda9ccb..cd0e43b21203 100644 --- a/src/tools/rust-analyzer/editors/code/src/diagnostics.ts +++ b/src/tools/rust-analyzer/editors/code/src/diagnostics.ts @@ -207,11 +207,6 @@ export class AnsiDecorationProvider implements vscode.Disposable { } } - const themeColor = AnsiDecorationProvider._anserToThemeColor[color]; - if (themeColor) { - return new ThemeColor("terminal." + themeColor); - } - - return undefined; + return AnsiDecorationProvider._anserToThemeColor[color]; } } From 2f9e5586a07f8cfa3e533668d0bf7885178659ed Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 2 Mar 2025 19:41:39 +0530 Subject: [PATCH 548/991] add diagnostic for dangling dyn --- .../crates/syntax/src/validation.rs | 24 ++++++++++++------ .../parser/validation/0224_dangling_dyn.rast | 25 +++++++++++++++++++ .../parser/validation/0224_dangling_dyn.rs | 1 + 3 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast create mode 100644 src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs diff --git a/src/tools/rust-analyzer/crates/syntax/src/validation.rs b/src/tools/rust-analyzer/crates/syntax/src/validation.rs index 13d352d3c691..2dc86411e427 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/validation.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/validation.rs @@ -340,17 +340,25 @@ fn validate_trait_object_fn_ptr_ret_ty(ty: ast::FnPtrType, errors: &mut Vec Option { let tbl = ty.type_bound_list()?; + let bounds_count = tbl.bounds().count(); - if tbl.bounds().count() > 1 { - let dyn_token = ty.dyn_token()?; - let potential_parenthesis = - algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?; - let kind = potential_parenthesis.kind(); - if !matches!(kind, T!['('] | T![<] | T![=]) { - return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range())); + match bounds_count { + 0 => Some(SyntaxError::new( + "At least one trait is required for an object type", + ty.syntax().text_range(), + )), + _ if bounds_count > 1 => { + let dyn_token = ty.dyn_token()?; + let preceding_token = + algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?; + + if !matches!(preceding_token.kind(), T!['('] | T![<] | T![=]) { + return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range())); + } + None } + _ => None, } - None } fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec) { diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast new file mode 100644 index 000000000000..b31af5fbc6a5 --- /dev/null +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast @@ -0,0 +1,25 @@ +SOURCE_FILE@0..16 + FN@0..16 + FN_KW@0..2 "fn" + WHITESPACE@2..3 " " + NAME@3..4 + IDENT@3..4 "f" + PARAM_LIST@4..13 + L_PAREN@4..5 "(" + PARAM@5..12 + WILDCARD_PAT@5..6 + UNDERSCORE@5..6 "_" + COLON@6..7 ":" + WHITESPACE@7..8 " " + REF_TYPE@8..12 + AMP@8..9 "&" + DYN_TRAIT_TYPE@9..12 + DYN_KW@9..12 "dyn" + TYPE_BOUND_LIST@12..12 + R_PAREN@12..13 ")" + WHITESPACE@13..14 " " + BLOCK_EXPR@14..16 + STMT_LIST@14..16 + L_CURLY@14..15 "{" + R_CURLY@15..16 "}" +error 9..12: At least one trait is required for an object type diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs new file mode 100644 index 000000000000..2fdbb42846b6 --- /dev/null +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs @@ -0,0 +1 @@ +fn f(_: &dyn) {} \ No newline at end of file From 1840f57dde794e984e3adabba7763ce2bcb10741 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 2 Mar 2025 19:42:42 +0530 Subject: [PATCH 549/991] add diagnostic for dangling impl --- .../crates/syntax/src/validation.rs | 17 ++++++++++--- .../parser/validation/dangling_impl.rast | 25 +++++++++++++++++++ .../parser/validation/dangling_impl.rs | 1 + 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rast create mode 100644 src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rs diff --git a/src/tools/rust-analyzer/crates/syntax/src/validation.rs b/src/tools/rust-analyzer/crates/syntax/src/validation.rs index 2dc86411e427..0377e7c0e63e 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/validation.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/validation.rs @@ -315,10 +315,21 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec) { - if let Some(ast::Type::DynTraitType(ty)) = ty.ty() { - if let Some(err) = validate_trait_object_ty(ty) { - errors.push(err); + match ty.ty() { + Some(ast::Type::DynTraitType(ty)) => { + if let Some(err) = validate_trait_object_ty(ty) { + errors.push(err); + } } + Some(ast::Type::ImplTraitType(ty)) => { + if ty.type_bound_list().map_or(0, |tbl| tbl.bounds().count()) == 0 { + errors.push(SyntaxError::new( + "At least one trait must be specified", + ty.syntax().text_range(), + )); + } + } + _ => {} } } diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rast b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rast new file mode 100644 index 000000000000..dbe6535ac665 --- /dev/null +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rast @@ -0,0 +1,25 @@ +SOURCE_FILE@0..17 + FN@0..17 + FN_KW@0..2 "fn" + WHITESPACE@2..3 " " + NAME@3..4 + IDENT@3..4 "f" + PARAM_LIST@4..14 + L_PAREN@4..5 "(" + PARAM@5..13 + WILDCARD_PAT@5..6 + UNDERSCORE@5..6 "_" + COLON@6..7 ":" + WHITESPACE@7..8 " " + REF_TYPE@8..13 + AMP@8..9 "&" + IMPL_TRAIT_TYPE@9..13 + IMPL_KW@9..13 "impl" + TYPE_BOUND_LIST@13..13 + R_PAREN@13..14 ")" + WHITESPACE@14..15 " " + BLOCK_EXPR@15..17 + STMT_LIST@15..17 + L_CURLY@15..16 "{" + R_CURLY@16..17 "}" +error 9..13: At least one trait must be specified diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rs b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rs new file mode 100644 index 000000000000..0b440b4c5af4 --- /dev/null +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rs @@ -0,0 +1 @@ +fn f(_: &impl) {} \ No newline at end of file From 1c00d8ffd63837626fe77ff2b6b92bc0c94ae2ca Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 2 Mar 2025 09:19:25 -0500 Subject: [PATCH 550/991] Add `identifier` to pull diagnostic LSP capabilities This field in the server capabilities instructs the client to maintain the diagnostics received from a `textDocument/diagnostic` pull request as a separate set from other diagnostics: namely those sent with classic "push" diagnostics, `textDocument/publishDiagnostic`. rust-analyzer emits "native" diagnostics (computed by rust-analyzer itself) in pull diagnostics and separately emits cargo-based diagnostics with push, so push and pull diagnostics should be different sets. Setting this field instructs the client to avoid clearing push diagnostics when new pull diagnostics arrive and vice versa. --- .../rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs index b1136dbbdac3..9c6b69d73129 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs @@ -165,7 +165,7 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { })), diagnostic_provider: Some(lsp_types::DiagnosticServerCapabilities::Options( lsp_types::DiagnosticOptions { - identifier: None, + identifier: Some("rust-analyzer".to_owned()), inter_file_dependencies: true, // FIXME workspace_diagnostics: false, From 6867806f67ad6a8343014f8c1ca6867b72a92b1c Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Wed, 22 Jan 2025 20:16:34 +0100 Subject: [PATCH 551/991] Document workings of successors more clearly This is an attempt to fix #135087 together with https://github.com/rust-lang/rust/pull/135886, but I am not sure if I've succeeded in adding much clarity here, so don't be shy with your comments. --- library/core/src/iter/sources/successors.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/library/core/src/iter/sources/successors.rs b/library/core/src/iter/sources/successors.rs index e14c9235e556..5466131903f8 100644 --- a/library/core/src/iter/sources/successors.rs +++ b/library/core/src/iter/sources/successors.rs @@ -1,11 +1,16 @@ use crate::fmt; use crate::iter::FusedIterator; -/// Creates a new iterator where each successive item is computed based on the preceding one. +/// Creates an iterator which, starting from an initial item, +/// computes each successive item from the preceding one. /// -/// The iterator starts with the given first item (if any) -/// and calls the given `FnMut(&T) -> Option` closure to compute each item’s successor. -/// The iterator will yield the `T`s returned from the closure. +/// This iterator stores an optional item (`Option`) and a successor closure (`impl FnMut(&T) -> Option`). +/// Its `next` method returns the stored optional item and +/// if it is `Some(val)` calls the stored closure on `&val` to compute and store its successor. +/// The iterator will apply the closure successively to the stored option's value until the option is `None`. +/// This also means that once the stored option is `None` it will remain `None`, +/// as the closure will not be called again, so the created iterator is a [`FusedIterator`]. +/// The iterator's items will be the initial item and all of its successors as calculated by the successor closure. /// /// ``` /// use std::iter::successors; @@ -24,7 +29,8 @@ where Successors { next: first, succ } } -/// A new iterator where each successive item is computed based on the preceding one. +/// An iterator which, starting from an initial item, +/// computes each successive item from the preceding one. /// /// This `struct` is created by the [`iter::successors()`] function. /// See its documentation for more. From a59a8f9e7579b4346eb6b00c3809d04986dcfcee Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 2 Mar 2025 18:41:28 +0000 Subject: [PATCH 552/991] Revert "Auto merge of #135335 - oli-obk:push-zxwssomxxtnq, r=saethlin" This reverts commit a7a6c64a657f68113301c2ffe0745b49a16442d1, reversing changes made to ebbe63891f1fae21734cb97f2f863b08b1d44bf8. --- compiler/rustc_codegen_gcc/src/common.rs | 5 -- compiler/rustc_codegen_llvm/src/common.rs | 4 -- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 - compiler/rustc_codegen_ssa/src/mir/operand.rs | 59 +++++++------------ compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 26 +------- .../rustc_codegen_ssa/src/traits/consts.rs | 1 - .../src/mir/interpret/allocation.rs | 2 +- tests/codegen/slice-init.rs | 55 +---------------- 8 files changed, 28 insertions(+), 125 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 20a3482aaa27..2052a6aa2159 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -64,11 +64,6 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) } } - fn is_undef(&self, _val: RValue<'gcc>) -> bool { - // FIXME: actually check for undef - false - } - fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> { let local = self.current_func.borrow().expect("func").new_local(None, typ, "undefined"); if typ.is_struct().is_some() { diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 0621b893e755..c9851ef84314 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -127,10 +127,6 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { unsafe { llvm::LLVMGetUndef(t) } } - fn is_undef(&self, v: &'ll Value) -> bool { - unsafe { llvm::LLVMIsUndef(v) == True } - } - fn const_poison(&self, t: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMGetPoison(t) } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 2dc14e4613d2..e3d0b928c978 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1046,7 +1046,6 @@ unsafe extern "C" { pub(crate) fn LLVMMetadataTypeInContext(C: &Context) -> &Type; // Operations on all values - pub(crate) fn LLVMIsUndef(Val: &Value) -> Bool; pub(crate) fn LLVMTypeOf(Val: &Value) -> &Type; pub(crate) fn LLVMGetValueName2(Val: &Value, Length: *mut size_t) -> *const c_char; pub(crate) fn LLVMSetValueName2(Val: &Value, Name: *const c_char, NameLen: size_t); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 461cf1b8acda..c2f66c98c690 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -203,30 +203,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let alloc_align = alloc.inner().align; assert!(alloc_align >= layout.align.abi); - // Returns `None` when the value is partially undefined or any byte of it has provenance. - // Otherwise returns the value or (if the entire value is undef) returns an undef. let read_scalar = |start, size, s: abi::Scalar, ty| { - let range = alloc_range(start, size); match alloc.0.read_scalar( bx, - range, + alloc_range(start, size), /*read_provenance*/ matches!(s.primitive(), abi::Primitive::Pointer(_)), ) { - Ok(val) => Some(bx.scalar_to_backend(val, s, ty)), - Err(_) => { - // We may have failed due to partial provenance or unexpected provenance, - // continue down the normal code path if so. - if alloc.0.provenance().range_empty(range, &bx.tcx()) - // Since `read_scalar` failed, but there were no relocations involved, the - // bytes must be partially or fully uninitialized. Thus we can now unwrap the - // information about the range of uninit bytes and check if it's the full range. - && alloc.0.init_mask().is_range_initialized(range).unwrap_err() == range - { - Some(bx.const_undef(ty)) - } else { - None - } - } + Ok(val) => bx.scalar_to_backend(val, s, ty), + Err(_) => bx.const_poison(ty), } }; @@ -237,14 +221,16 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { // check that walks over the type of `mplace` to make sure it is truly correct to treat this // like a `Scalar` (or `ScalarPair`). match layout.backend_repr { - BackendRepr::Scalar(s) => { + BackendRepr::Scalar(s @ abi::Scalar::Initialized { .. }) => { let size = s.size(bx); assert_eq!(size, layout.size, "abi::Scalar size does not match layout size"); - if let Some(val) = read_scalar(offset, size, s, bx.immediate_backend_type(layout)) { - return OperandRef { val: OperandValue::Immediate(val), layout }; - } + let val = read_scalar(offset, size, s, bx.immediate_backend_type(layout)); + OperandRef { val: OperandValue::Immediate(val), layout } } - BackendRepr::ScalarPair(a, b) => { + BackendRepr::ScalarPair( + a @ abi::Scalar::Initialized { .. }, + b @ abi::Scalar::Initialized { .. }, + ) => { let (a_size, b_size) = (a.size(bx), b.size(bx)); let b_offset = (offset + a_size).align_to(b.align(bx).abi); assert!(b_offset.bytes() > 0); @@ -260,21 +246,20 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { b, bx.scalar_pair_element_backend_type(layout, 1, true), ); - if let (Some(a_val), Some(b_val)) = (a_val, b_val) { - return OperandRef { val: OperandValue::Pair(a_val, b_val), layout }; - } + OperandRef { val: OperandValue::Pair(a_val, b_val), layout } } - _ if layout.is_zst() => return OperandRef::zero_sized(layout), - _ => {} - } - // Neither a scalar nor scalar pair. Load from a place - // FIXME: should we cache `const_data_from_alloc` to avoid repeating this for the - // same `ConstAllocation`? - let init = bx.const_data_from_alloc(alloc); - let base_addr = bx.static_addr_of(init, alloc_align, None); + _ if layout.is_zst() => OperandRef::zero_sized(layout), + _ => { + // Neither a scalar nor scalar pair. Load from a place + // FIXME: should we cache `const_data_from_alloc` to avoid repeating this for the + // same `ConstAllocation`? + let init = bx.const_data_from_alloc(alloc); + let base_addr = bx.static_addr_of(init, alloc_align, None); - let llval = bx.const_ptr_byte_offset(base_addr, offset); - bx.load_operand(PlaceRef::new_sized(llval, layout)) + let llval = bx.const_ptr_byte_offset(base_addr, offset); + bx.load_operand(PlaceRef::new_sized(llval, layout)) + } + } } /// Asserts that this operand refers to a scalar and returns diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index d24e48b37a46..44208f6019ec 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_middle::{bug, mir, span_bug}; use rustc_session::config::OptLevel; use rustc_span::{DUMMY_SP, Span}; -use tracing::{debug, instrument, trace}; +use tracing::{debug, instrument}; use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; @@ -93,8 +93,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } - // If `v` is an integer constant whose value is just a single byte repeated N times, - // emit a `memset` filling the entire `dest` with that byte. let try_init_all_same = |bx: &mut Bx, v| { let start = dest.val.llval; let size = bx.const_usize(dest.layout.size.bytes()); @@ -119,33 +117,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { false }; - trace!(?cg_elem.val); match cg_elem.val { OperandValue::Immediate(v) => { if try_init_all_same(bx, v) { return; } } - OperandValue::Pair(a, b) => { - let a_is_undef = bx.cx().is_undef(a); - match (a_is_undef, bx.cx().is_undef(b)) { - // Can happen for uninit unions - (true, true) => { - // FIXME: can we produce better output here? - } - (false, true) | (true, false) => { - let val = if a_is_undef { b } else { a }; - if try_init_all_same(bx, val) { - return; - } - } - (false, false) => { - // FIXME: if both are the same value, use try_init_all_same - } - } - } - OperandValue::ZeroSized => unreachable!("checked above"), - OperandValue::Ref(..) => {} + _ => (), } let count = self diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index 5cfb56ebacee..dc6b68ceff7d 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -9,7 +9,6 @@ pub trait ConstCodegenMethods<'tcx>: BackendTypes { /// Generate an uninitialized value (matching uninitialized memory in MIR). /// Whether memory is initialized or not is tracked byte-for-byte. fn const_undef(&self, t: Self::Type) -> Self::Value; - fn is_undef(&self, v: Self::Value) -> bool; /// Generate a fake value. Poison always affects the entire value, even if just a single byte is /// poison. This can only be used in codepaths that are already UB, i.e., UB-free Rust code /// (including code that e.g. copies uninit memory with `MaybeUninit`) can never encounter a diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 95bc9b71fe0a..697a0e6592df 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -222,7 +222,7 @@ impl AllocError { } /// The information that makes up a memory access: offset and size. -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone)] pub struct AllocRange { pub start: Size, pub size: Size, diff --git a/tests/codegen/slice-init.rs b/tests/codegen/slice-init.rs index b36a5b5de3d4..1c2dd3e88755 100644 --- a/tests/codegen/slice-init.rs +++ b/tests/codegen/slice-init.rs @@ -2,8 +2,6 @@ #![crate_type = "lib"] -use std::mem::MaybeUninit; - // CHECK-LABEL: @zero_sized_elem #[no_mangle] pub fn zero_sized_elem() { @@ -78,64 +76,17 @@ pub fn u16_init_one_bytes() -> [u16; N] { [const { u16::from_be_bytes([1, 1]) }; N] } +// FIXME: undef bytes can just be initialized with the same value as the +// defined bytes, if the defines bytes are all the same. // CHECK-LABEL: @option_none_init #[no_mangle] pub fn option_none_init() -> [Option; N] { - // CHECK-NOT: select - // CHECK-NOT: br - // CHECK-NOT: switch - // CHECK-NOT: icmp - // CHECK: call void @llvm.memset.p0 - [const { None }; N] -} - -// If there is partial provenance or some bytes are initialized and some are not, -// we can't really do better than initialize bytes or groups of bytes together. -// CHECK-LABEL: @option_maybe_uninit_init -#[no_mangle] -pub fn option_maybe_uninit_init() -> [MaybeUninit; N] { // CHECK-NOT: select // CHECK: br label %repeat_loop_header{{.*}} // CHECK-NOT: switch // CHECK: icmp // CHECK-NOT: call void @llvm.memset.p0 - [const { - let mut val: MaybeUninit = MaybeUninit::uninit(); - let ptr = val.as_mut_ptr() as *mut u8; - unsafe { - ptr.write(0); - } - val - }; N] -} - -#[repr(packed)] -struct Packed { - start: u8, - ptr: &'static (), - rest: u16, - rest2: u8, -} - -// If there is partial provenance or some bytes are initialized and some are not, -// we can't really do better than initialize bytes or groups of bytes together. -// CHECK-LABEL: @option_maybe_uninit_provenance -#[no_mangle] -pub fn option_maybe_uninit_provenance() -> [MaybeUninit; N] { - // CHECK-NOT: select - // CHECK: br label %repeat_loop_header{{.*}} - // CHECK-NOT: switch - // CHECK: icmp - // CHECK-NOT: call void @llvm.memset.p0 - [const { - let mut val: MaybeUninit = MaybeUninit::uninit(); - unsafe { - let ptr = &raw mut (*val.as_mut_ptr()).ptr; - static HAS_ADDR: () = (); - ptr.write_unaligned(&HAS_ADDR); - } - val - }; N] + [None; N] } // Use an opaque function to prevent rustc from removing useless drops. From 5f575bc4bca3f18e4798110b05e059a840c0fd49 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 2 Mar 2025 18:52:33 +0000 Subject: [PATCH 553/991] Add a test --- tests/codegen/slice-init.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/codegen/slice-init.rs b/tests/codegen/slice-init.rs index 1c2dd3e88755..950e0b0c10db 100644 --- a/tests/codegen/slice-init.rs +++ b/tests/codegen/slice-init.rs @@ -89,6 +89,20 @@ pub fn option_none_init() -> [Option; N] { [None; N] } +use std::mem::MaybeUninit; + +// FIXME: This could be optimized into a memset. +// Regression test for . +#[no_mangle] +pub fn half_uninit() -> [(u128, MaybeUninit); N] { + // CHECK-NOT: select + // CHECK: br label %repeat_loop_header{{.*}} + // CHECK-NOT: switch + // CHECK: icmp + // CHECK-NOT: call void @llvm.memset.p0 + [const { (0, MaybeUninit::uninit()) }; N] +} + // Use an opaque function to prevent rustc from removing useless drops. #[inline(never)] pub fn opaque(_: impl Sized) {} From 2a1e2e9632af4098aea3136fc80e165284deb927 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Dec 2024 07:28:16 +1100 Subject: [PATCH 554/991] Replace `ast::TokenKind::BinOp{,Eq}` and remove `BinOpToken`. `BinOpToken` is badly named, because it only covers the assignable binary ops and excludes comparisons and `&&`/`||`. Its use in `ast::TokenKind` does allow a small amount of code sharing, but it's a clumsy factoring. This commit removes `ast::TokenKind::BinOp{,Eq}`, replacing each one with 10 individual variants. This makes `ast::TokenKind` more similar to `rustc_lexer::TokenKind`, which has individual variants for all operators. Although the number of lines of code increases, the number of chars decreases due to the frequent use of shorter names like `token::Plus` instead of `token::BinOp(BinOpToken::Plus)`. --- compiler/rustc_ast/src/token.rs | 290 ++++++++++-------- compiler/rustc_ast/src/util/parser.rs | 42 +-- compiler/rustc_ast_pretty/src/pprust/state.rs | 41 +-- compiler/rustc_expand/src/mbe/macro_rules.rs | 10 +- compiler/rustc_expand/src/mbe/quoted.rs | 4 +- .../rustc_expand/src/proc_macro_server.rs | 67 ++-- compiler/rustc_parse/src/lexer/mod.rs | 16 +- .../rustc_parse/src/lexer/unicode_chars.rs | 10 +- .../rustc_parse/src/parser/diagnostics.rs | 19 +- compiler/rustc_parse/src/parser/expr.rs | 36 +-- compiler/rustc_parse/src/parser/item.rs | 12 +- compiler/rustc_parse/src/parser/mod.rs | 8 +- compiler/rustc_parse/src/parser/pat.rs | 12 +- compiler/rustc_parse/src/parser/path.rs | 5 +- compiler/rustc_parse/src/parser/stmt.rs | 13 +- compiler/rustc_parse/src/parser/token_type.rs | 17 +- compiler/rustc_parse/src/parser/ty.rs | 18 +- src/librustdoc/clean/render_macro_matchers.rs | 11 +- src/tools/rustfmt/src/macros.rs | 30 +- 19 files changed, 352 insertions(+), 309 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 6cd0e15c557f..9304636eda6c 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -2,7 +2,6 @@ use std::borrow::Cow; use std::fmt; use std::sync::Arc; -pub use BinOpToken::*; pub use LitKind::*; pub use Nonterminal::*; pub use NtExprKind::*; @@ -26,21 +25,6 @@ pub enum CommentKind { Block, } -#[derive(Clone, PartialEq, Encodable, Decodable, Hash, Debug, Copy)] -#[derive(HashStable_Generic)] -pub enum BinOpToken { - Plus, - Minus, - Star, - Slash, - Percent, - Caret, - And, - Or, - Shl, - Shr, -} - // This type must not implement `Hash` due to the unusual `PartialEq` impl below. #[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)] pub enum InvisibleOrigin { @@ -379,8 +363,46 @@ pub enum TokenKind { Not, /// `~` Tilde, - BinOp(BinOpToken), - BinOpEq(BinOpToken), + // `+` + Plus, + // `-` + Minus, + // `*` + Star, + // `/` + Slash, + // `%` + Percent, + // `^` + Caret, + // `&` + And, + // `|` + Or, + // `<<` + Shl, + // `>>` + Shr, + // `+=` + PlusEq, + // `-=` + MinusEq, + // `*=` + StarEq, + // `/=` + SlashEq, + // `%=` + PercentEq, + // `^=` + CaretEq, + // `&=` + AndEq, + // `|=` + OrEq, + // `<<=` + ShlEq, + // `>>=` + ShrEq, /* Structural symbols */ /// `@` @@ -502,29 +524,29 @@ impl TokenKind { (EqEq, 1) => (Eq, Eq), (Ne, 1) => (Not, Eq), (Ge, 1) => (Gt, Eq), - (AndAnd, 1) => (BinOp(And), BinOp(And)), - (OrOr, 1) => (BinOp(Or), BinOp(Or)), - (BinOp(Shl), 1) => (Lt, Lt), - (BinOp(Shr), 1) => (Gt, Gt), - (BinOpEq(Plus), 1) => (BinOp(Plus), Eq), - (BinOpEq(Minus), 1) => (BinOp(Minus), Eq), - (BinOpEq(Star), 1) => (BinOp(Star), Eq), - (BinOpEq(Slash), 1) => (BinOp(Slash), Eq), - (BinOpEq(Percent), 1) => (BinOp(Percent), Eq), - (BinOpEq(Caret), 1) => (BinOp(Caret), Eq), - (BinOpEq(And), 1) => (BinOp(And), Eq), - (BinOpEq(Or), 1) => (BinOp(Or), Eq), - (BinOpEq(Shl), 1) => (Lt, Le), // `<` + `<=` - (BinOpEq(Shl), 2) => (BinOp(Shl), Eq), // `<<` + `=` - (BinOpEq(Shr), 1) => (Gt, Ge), // `>` + `>=` - (BinOpEq(Shr), 2) => (BinOp(Shr), Eq), // `>>` + `=` + (AndAnd, 1) => (And, And), + (OrOr, 1) => (Or, Or), + (Shl, 1) => (Lt, Lt), + (Shr, 1) => (Gt, Gt), + (PlusEq, 1) => (Plus, Eq), + (MinusEq, 1) => (Minus, Eq), + (StarEq, 1) => (Star, Eq), + (SlashEq, 1) => (Slash, Eq), + (PercentEq, 1) => (Percent, Eq), + (CaretEq, 1) => (Caret, Eq), + (AndEq, 1) => (And, Eq), + (OrEq, 1) => (Or, Eq), + (ShlEq, 1) => (Lt, Le), // `<` + `<=` + (ShlEq, 2) => (Shl, Eq), // `<<` + `=` + (ShrEq, 1) => (Gt, Ge), // `>` + `>=` + (ShrEq, 2) => (Shr, Eq), // `>>` + `=` (DotDot, 1) => (Dot, Dot), (DotDotDot, 1) => (Dot, DotDot), // `.` + `..` (DotDotDot, 2) => (DotDot, Dot), // `..` + `.` (DotDotEq, 2) => (DotDot, Eq), (PathSep, 1) => (Colon, Colon), - (RArrow, 1) => (BinOp(Minus), Gt), - (LArrow, 1) => (Lt, BinOp(Minus)), + (RArrow, 1) => (Minus, Gt), + (LArrow, 1) => (Lt, Minus), (FatArrow, 1) => (Eq, Gt), _ => return None, }) @@ -543,7 +565,7 @@ impl TokenKind { } pub fn should_end_const_arg(&self) -> bool { - matches!(self, Gt | Ge | BinOp(Shr) | BinOpEq(Shr)) + matches!(self, Gt | Ge | Shr | ShrEq) } } @@ -582,11 +604,11 @@ impl Token { pub fn is_punct(&self) -> bool { match self.kind { - Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | BinOp(_) - | BinOpEq(_) | At | Dot | DotDot | DotDotDot | DotDotEq | Comma | Semi | Colon - | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => { - true - } + Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | Plus | Minus + | Star | Slash | Percent | Caret | And | Or | Shl | Shr | PlusEq | MinusEq | StarEq + | SlashEq | PercentEq | CaretEq | AndEq | OrEq | ShlEq | ShrEq | At | Dot | DotDot + | DotDotDot | DotDotEq | Comma | Semi | Colon | PathSep | RArrow | LArrow + | FatArrow | Pound | Dollar | Question | SingleQuote => true, OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..) | NtIdent(..) | Lifetime(..) | NtLifetime(..) | Interpolated(..) | Eof => false, @@ -594,7 +616,7 @@ impl Token { } pub fn is_like_plus(&self) -> bool { - matches!(self.kind, BinOp(Plus) | BinOpEq(Plus)) + matches!(self.kind, Plus | PlusEq) } /// Returns `true` if the token can appear at the start of an expression. @@ -609,14 +631,14 @@ impl Token { OpenDelim(Parenthesis | Brace | Bracket) | // tuple, array or block Literal(..) | // literal Not | // operator not - BinOp(Minus) | // unary minus - BinOp(Star) | // dereference - BinOp(Or) | OrOr | // closure - BinOp(And) | // reference + Minus | // unary minus + Star | // dereference + Or | OrOr | // closure + And | // reference AndAnd | // double reference // DotDotDot is no longer supported, but we need some way to display the error DotDot | DotDotDot | DotDotEq | // range notation - Lt | BinOp(Shl) | // associated path + Lt | Shl | // associated path PathSep | // global path Lifetime(..) | // labeled loop Pound => true, // expression attributes @@ -645,17 +667,16 @@ impl Token { Ident(..) | NtIdent(..) | OpenDelim(Delimiter::Parenthesis) | // tuple pattern OpenDelim(Delimiter::Bracket) | // slice pattern - BinOp(And) | // reference - BinOp(Minus) | // negative literal - AndAnd | // double reference - Literal(_) | // literal - DotDot | // range pattern (future compat) - DotDotDot | // range pattern (future compat) - PathSep | // path - Lt | // path (UFCS constant) - BinOp(Shl) => true, // path (double UFCS) - // leading vert `|` or-pattern - BinOp(Or) => matches!(pat_kind, PatWithOr), + And | // reference + Minus | // negative literal + AndAnd | // double reference + Literal(_) | // literal + DotDot | // range pattern (future compat) + DotDotDot | // range pattern (future compat) + PathSep | // path + Lt | // path (UFCS constant) + Shl => true, // path (double UFCS) + Or => matches!(pat_kind, PatWithOr), // leading vert `|` or-pattern Interpolated(nt) => matches!(&**nt, | NtExpr(..) @@ -676,18 +697,18 @@ impl Token { /// Returns `true` if the token can appear at the start of a type. pub fn can_begin_type(&self) -> bool { match self.uninterpolate().kind { - Ident(name, is_raw) => + Ident(name, is_raw) => ident_can_begin_type(name, self.span, is_raw), // type name or keyword OpenDelim(Delimiter::Parenthesis) | // tuple OpenDelim(Delimiter::Bracket) | // array - Not | // never - BinOp(Star) | // raw pointer - BinOp(And) | // reference - AndAnd | // double reference - Question | // maybe bound in trait object - Lifetime(..) | // lifetime bound in trait object - Lt | BinOp(Shl) | // associated path - PathSep => true, // global path + Not | // never + Star | // raw pointer + And | // reference + AndAnd | // double reference + Question | // maybe bound in trait object + Lifetime(..) | // lifetime bound in trait object + Lt | Shl | // associated path + PathSep => true, // global path OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( MetaVarKind::Ty { .. } | MetaVarKind::Path @@ -701,7 +722,7 @@ impl Token { /// Returns `true` if the token can appear at the start of a const param. pub fn can_begin_const_arg(&self) -> bool { match self.kind { - OpenDelim(Delimiter::Brace) | Literal(..) | BinOp(Minus) => true, + OpenDelim(Delimiter::Brace) | Literal(..) | Minus => true, Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true, Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)), OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( @@ -750,7 +771,7 @@ impl Token { /// Keep this in sync with and `Lit::from_token`, excluding unary negation. pub fn can_begin_literal_maybe_minus(&self) -> bool { match self.uninterpolate().kind { - Literal(..) | BinOp(Minus) => true, + Literal(..) | Minus => true, Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true, Interpolated(ref nt) => match &**nt { NtLiteral(_) => true, @@ -875,7 +896,7 @@ impl Token { } pub fn is_qpath_start(&self) -> bool { - self == &Lt || self == &BinOp(Shl) + self == &Lt || self == &Shl } pub fn is_path_start(&self) -> bool { @@ -967,59 +988,82 @@ impl Token { } pub fn glue(&self, joint: &Token) -> Option { - let kind = match self.kind { - Eq => match joint.kind { - Eq => EqEq, - Gt => FatArrow, - _ => return None, - }, - Lt => match joint.kind { - Eq => Le, - Lt => BinOp(Shl), - Le => BinOpEq(Shl), - BinOp(Minus) => LArrow, - _ => return None, - }, - Gt => match joint.kind { - Eq => Ge, - Gt => BinOp(Shr), - Ge => BinOpEq(Shr), - _ => return None, - }, - Not => match joint.kind { - Eq => Ne, - _ => return None, - }, - BinOp(op) => match joint.kind { - Eq => BinOpEq(op), - BinOp(And) if op == And => AndAnd, - BinOp(Or) if op == Or => OrOr, - Gt if op == Minus => RArrow, - _ => return None, - }, - Dot => match joint.kind { - Dot => DotDot, - DotDot => DotDotDot, - _ => return None, - }, - DotDot => match joint.kind { - Dot => DotDotDot, - Eq => DotDotEq, - _ => return None, - }, - Colon => match joint.kind { - Colon => PathSep, - _ => return None, - }, - SingleQuote => match joint.kind { - Ident(name, is_raw) => Lifetime(Symbol::intern(&format!("'{name}")), is_raw), - _ => return None, - }, + let kind = match (&self.kind, &joint.kind) { + (Eq, Eq) => EqEq, + (Eq, Gt) => FatArrow, + (Eq, _) => return None, - Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot - | DotDotEq | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar - | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | NtIdent(..) - | Lifetime(..) | NtLifetime(..) | Interpolated(..) | DocComment(..) | Eof => { + (Lt, Eq) => Le, + (Lt, Lt) => Shl, + (Lt, Le) => ShlEq, + (Lt, Minus) => LArrow, + (Lt, _) => return None, + + (Gt, Eq) => Ge, + (Gt, Gt) => Shr, + (Gt, Ge) => ShrEq, + (Gt, _) => return None, + + (Not, Eq) => Ne, + (Not, _) => return None, + + (Plus, Eq) => PlusEq, + (Plus, _) => return None, + + (Minus, Eq) => MinusEq, + (Minus, Gt) => RArrow, + (Minus, _) => return None, + + (Star, Eq) => StarEq, + (Star, _) => return None, + + (Slash, Eq) => SlashEq, + (Slash, _) => return None, + + (Percent, Eq) => PercentEq, + (Percent, _) => return None, + + (Caret, Eq) => CaretEq, + (Caret, _) => return None, + + (And, Eq) => AndEq, + (And, And) => AndAnd, + (And, _) => return None, + + (Or, Eq) => OrEq, + (Or, Or) => OrOr, + (Or, _) => return None, + + (Shl, Eq) => ShlEq, + (Shl, _) => return None, + + (Shr, Eq) => ShrEq, + (Shr, _) => return None, + + (Dot, Dot) => DotDot, + (Dot, DotDot) => DotDotDot, + (Dot, _) => return None, + + (DotDot, Dot) => DotDotDot, + (DotDot, Eq) => DotDotEq, + (DotDot, _) => return None, + + (Colon, Colon) => PathSep, + (Colon, _) => return None, + + (SingleQuote, Ident(name, is_raw)) => { + Lifetime(Symbol::intern(&format!("'{name}")), *is_raw) + } + (SingleQuote, _) => return None, + + ( + Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | PlusEq | MinusEq | StarEq | SlashEq + | PercentEq | CaretEq | AndEq | OrEq | ShlEq | ShrEq | At | DotDotDot | DotDotEq + | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question + | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | NtIdent(..) + | Lifetime(..) | NtLifetime(..) | Interpolated(..) | DocComment(..) | Eof, + _, + ) => { return None; } }; diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 69454967eed6..98b1fc52ed74 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -1,7 +1,7 @@ use rustc_span::kw; use crate::ast::{self, BinOpKind, RangeLimits}; -use crate::token::{self, BinOpToken, Token}; +use crate::token::{self, Token}; /// Associative operator. #[derive(Copy, Clone, PartialEq, Debug)] @@ -34,26 +34,26 @@ impl AssocOp { use AssocOp::*; match t.kind { token::Eq => Some(Assign), - token::BinOp(BinOpToken::Plus) => Some(Binary(BinOpKind::Add)), - token::BinOp(BinOpToken::Minus) => Some(Binary(BinOpKind::Sub)), - token::BinOp(BinOpToken::Star) => Some(Binary(BinOpKind::Mul)), - token::BinOp(BinOpToken::Slash) => Some(Binary(BinOpKind::Div)), - token::BinOp(BinOpToken::Percent) => Some(Binary(BinOpKind::Rem)), - token::BinOp(BinOpToken::Caret) => Some(Binary(BinOpKind::BitXor)), - token::BinOp(BinOpToken::And) => Some(Binary(BinOpKind::BitAnd)), - token::BinOp(BinOpToken::Or) => Some(Binary(BinOpKind::BitOr)), - token::BinOp(BinOpToken::Shl) => Some(Binary(BinOpKind::Shl)), - token::BinOp(BinOpToken::Shr) => Some(Binary(BinOpKind::Shr)), - token::BinOpEq(BinOpToken::Plus) => Some(AssignOp(BinOpKind::Add)), - token::BinOpEq(BinOpToken::Minus) => Some(AssignOp(BinOpKind::Sub)), - token::BinOpEq(BinOpToken::Star) => Some(AssignOp(BinOpKind::Mul)), - token::BinOpEq(BinOpToken::Slash) => Some(AssignOp(BinOpKind::Div)), - token::BinOpEq(BinOpToken::Percent) => Some(AssignOp(BinOpKind::Rem)), - token::BinOpEq(BinOpToken::Caret) => Some(AssignOp(BinOpKind::BitXor)), - token::BinOpEq(BinOpToken::And) => Some(AssignOp(BinOpKind::BitAnd)), - token::BinOpEq(BinOpToken::Or) => Some(AssignOp(BinOpKind::BitOr)), - token::BinOpEq(BinOpToken::Shl) => Some(AssignOp(BinOpKind::Shl)), - token::BinOpEq(BinOpToken::Shr) => Some(AssignOp(BinOpKind::Shr)), + token::Plus => Some(Binary(BinOpKind::Add)), + token::Minus => Some(Binary(BinOpKind::Sub)), + token::Star => Some(Binary(BinOpKind::Mul)), + token::Slash => Some(Binary(BinOpKind::Div)), + token::Percent => Some(Binary(BinOpKind::Rem)), + token::Caret => Some(Binary(BinOpKind::BitXor)), + token::And => Some(Binary(BinOpKind::BitAnd)), + token::Or => Some(Binary(BinOpKind::BitOr)), + token::Shl => Some(Binary(BinOpKind::Shl)), + token::Shr => Some(Binary(BinOpKind::Shr)), + token::PlusEq => Some(AssignOp(BinOpKind::Add)), + token::MinusEq => Some(AssignOp(BinOpKind::Sub)), + token::StarEq => Some(AssignOp(BinOpKind::Mul)), + token::SlashEq => Some(AssignOp(BinOpKind::Div)), + token::PercentEq => Some(AssignOp(BinOpKind::Rem)), + token::CaretEq => Some(AssignOp(BinOpKind::BitXor)), + token::AndEq => Some(AssignOp(BinOpKind::BitAnd)), + token::OrEq => Some(AssignOp(BinOpKind::BitOr)), + token::ShlEq => Some(AssignOp(BinOpKind::Shl)), + token::ShrEq => Some(AssignOp(BinOpKind::Shr)), token::Lt => Some(Binary(BinOpKind::Lt)), token::Le => Some(Binary(BinOpKind::Le)), token::Ge => Some(Binary(BinOpKind::Ge)), diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 44e956dc37f3..9d922b61567e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -11,9 +11,7 @@ use std::sync::Arc; use rustc_ast::attr::AttrIdGenerator; use rustc_ast::ptr::P; -use rustc_ast::token::{ - self, BinOpToken, CommentKind, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind, -}; +use rustc_ast::token::{self, CommentKind, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{Comment, CommentStyle}; @@ -344,21 +342,6 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool { } } -fn binop_to_string(op: BinOpToken) -> &'static str { - match op { - token::Plus => "+", - token::Minus => "-", - token::Star => "*", - token::Slash => "/", - token::Percent => "%", - token::Caret => "^", - token::And => "&", - token::Or => "|", - token::Shl => "<<", - token::Shr => ">>", - } -} - pub fn doc_comment_to_string( comment_kind: CommentKind, attr_style: ast::AttrStyle, @@ -917,8 +900,26 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere token::Tilde => "~".into(), token::OrOr => "||".into(), token::AndAnd => "&&".into(), - token::BinOp(op) => binop_to_string(op).into(), - token::BinOpEq(op) => format!("{}=", binop_to_string(op)).into(), + token::Plus => "+".into(), + token::Minus => "-".into(), + token::Star => "*".into(), + token::Slash => "/".into(), + token::Percent => "%".into(), + token::Caret => "^".into(), + token::And => "&".into(), + token::Or => "|".into(), + token::Shl => "<<".into(), + token::Shr => ">>".into(), + token::PlusEq => "+=".into(), + token::MinusEq => "-=".into(), + token::StarEq => "*=".into(), + token::SlashEq => "/=".into(), + token::PercentEq => "%=".into(), + token::CaretEq => "^=".into(), + token::AndEq => "&=".into(), + token::OrEq => "|=".into(), + token::ShlEq => "<<=".into(), + token::ShrEq => ">>=".into(), /* Structural symbols */ token::At => "@".into(), diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index cc7e3e651050..db45739e2dde 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -1135,7 +1135,7 @@ fn check_matcher_core<'tt>( && matches!(kind, NonterminalKind::Pat(PatParam { inferred: true })) && matches!( next_token, - TokenTree::Token(token) if *token == BinOp(token::BinOpToken::Or) + TokenTree::Token(token) if *token == token::Or ) { // It is suggestion to use pat_param, for example: $x:pat -> $x:pat_param. @@ -1177,7 +1177,7 @@ fn check_matcher_core<'tt>( if kind == NonterminalKind::Pat(PatWithOr) && sess.psess.edition.at_least_rust_2021() - && next_token.is_token(&BinOp(token::BinOpToken::Or)) + && next_token.is_token(&token::Or) { let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl( span, @@ -1296,7 +1296,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"]; match tok { TokenTree::Token(token) => match token.kind { - FatArrow | Comma | Eq | BinOp(token::Or) => IsInFollow::Yes, + FatArrow | Comma | Eq | Or => IsInFollow::Yes, Ident(name, IdentIsRaw::No) if name == kw::If || name == kw::In => { IsInFollow::Yes } @@ -1332,9 +1332,9 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { | Colon | Eq | Gt - | BinOp(token::Shr) + | Shr | Semi - | BinOp(token::Or) => IsInFollow::Yes, + | Or => IsInFollow::Yes, Ident(name, IdentIsRaw::No) if name == kw::As || name == kw::Where => { IsInFollow::Yes } diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index b9a061579079..8cb001391c52 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -302,8 +302,8 @@ fn parse_tree<'a>( /// `None`. fn kleene_op(token: &Token) -> Option { match token.kind { - token::BinOp(token::Star) => Some(KleeneOp::ZeroOrMore), - token::BinOp(token::Plus) => Some(KleeneOp::OneOrMore), + token::Star => Some(KleeneOp::ZeroOrMore), + token::Plus => Some(KleeneOp::OneOrMore), token::Question => Some(KleeneOp::ZeroOrOne), _ => None, } diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 5581a6e65089..a8a323c7a8de 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -182,26 +182,26 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec op("||"), Not => op("!"), Tilde => op("~"), - BinOp(Plus) => op("+"), - BinOp(Minus) => op("-"), - BinOp(Star) => op("*"), - BinOp(Slash) => op("/"), - BinOp(Percent) => op("%"), - BinOp(Caret) => op("^"), - BinOp(And) => op("&"), - BinOp(Or) => op("|"), - BinOp(Shl) => op("<<"), - BinOp(Shr) => op(">>"), - BinOpEq(Plus) => op("+="), - BinOpEq(Minus) => op("-="), - BinOpEq(Star) => op("*="), - BinOpEq(Slash) => op("/="), - BinOpEq(Percent) => op("%="), - BinOpEq(Caret) => op("^="), - BinOpEq(And) => op("&="), - BinOpEq(Or) => op("|="), - BinOpEq(Shl) => op("<<="), - BinOpEq(Shr) => op(">>="), + Plus => op("+"), + Minus => op("-"), + Star => op("*"), + Slash => op("/"), + Percent => op("%"), + Caret => op("^"), + And => op("&"), + Or => op("|"), + Shl => op("<<"), + Shr => op(">>"), + PlusEq => op("+="), + MinusEq => op("-="), + StarEq => op("*="), + SlashEq => op("/="), + PercentEq => op("%="), + CaretEq => op("^="), + AndEq => op("&="), + OrEq => op("|="), + ShlEq => op("<<="), + ShrEq => op(">>="), At => op("@"), Dot => op("."), DotDot => op(".."), @@ -324,14 +324,14 @@ impl ToInternal> b'>' => Gt, b'!' => Not, b'~' => Tilde, - b'+' => BinOp(Plus), - b'-' => BinOp(Minus), - b'*' => BinOp(Star), - b'/' => BinOp(Slash), - b'%' => BinOp(Percent), - b'^' => BinOp(Caret), - b'&' => BinOp(And), - b'|' => BinOp(Or), + b'+' => Plus, + b'-' => Minus, + b'*' => Star, + b'/' => Slash, + b'%' => Percent, + b'^' => Caret, + b'&' => And, + b'|' => Or, b'@' => At, b'.' => Dot, b',' => Comma, @@ -372,10 +372,9 @@ impl ToInternal> suffix, span, }) if symbol.as_str().starts_with('-') => { - let minus = BinOp(BinOpToken::Minus); let symbol = Symbol::intern(&symbol.as_str()[1..]); let integer = TokenKind::lit(token::Integer, symbol, suffix); - let a = tokenstream::TokenTree::token_joint_hidden(minus, span); + let a = tokenstream::TokenTree::token_joint_hidden(Minus, span); let b = tokenstream::TokenTree::token_alone(integer, span); smallvec![a, b] } @@ -385,10 +384,9 @@ impl ToInternal> suffix, span, }) if symbol.as_str().starts_with('-') => { - let minus = BinOp(BinOpToken::Minus); let symbol = Symbol::intern(&symbol.as_str()[1..]); let float = TokenKind::lit(token::Float, symbol, suffix); - let a = tokenstream::TokenTree::token_joint_hidden(minus, span); + let a = tokenstream::TokenTree::token_joint_hidden(Minus, span); let b = tokenstream::TokenTree::token_alone(float, span); smallvec![a, b] } @@ -599,10 +597,7 @@ impl server::TokenStream for Rustc<'_, '_> { Ok(Self::TokenStream::from_iter([ // FIXME: The span of the `-` token is lost when // parsing, so we cannot faithfully recover it here. - tokenstream::TokenTree::token_joint_hidden( - token::BinOp(token::Minus), - e.span, - ), + tokenstream::TokenTree::token_joint_hidden(token::Minus, e.span), tokenstream::TokenTree::token_alone(token::Literal(*token_lit), e.span), ])) } diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 792e2cc26ef1..94604043bac6 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -387,14 +387,14 @@ impl<'psess, 'src> Lexer<'psess, 'src> { rustc_lexer::TokenKind::Bang => token::Not, rustc_lexer::TokenKind::Lt => token::Lt, rustc_lexer::TokenKind::Gt => token::Gt, - rustc_lexer::TokenKind::Minus => token::BinOp(token::Minus), - rustc_lexer::TokenKind::And => token::BinOp(token::And), - rustc_lexer::TokenKind::Or => token::BinOp(token::Or), - rustc_lexer::TokenKind::Plus => token::BinOp(token::Plus), - rustc_lexer::TokenKind::Star => token::BinOp(token::Star), - rustc_lexer::TokenKind::Slash => token::BinOp(token::Slash), - rustc_lexer::TokenKind::Caret => token::BinOp(token::Caret), - rustc_lexer::TokenKind::Percent => token::BinOp(token::Percent), + rustc_lexer::TokenKind::Minus => token::Minus, + rustc_lexer::TokenKind::And => token::And, + rustc_lexer::TokenKind::Or => token::Or, + rustc_lexer::TokenKind::Plus => token::Plus, + rustc_lexer::TokenKind::Star => token::Star, + rustc_lexer::TokenKind::Slash => token::Slash, + rustc_lexer::TokenKind::Caret => token::Caret, + rustc_lexer::TokenKind::Percent => token::Percent, rustc_lexer::TokenKind::Unknown | rustc_lexer::TokenKind::InvalidIdent => { // Don't emit diagnostics for sequences of the same invalid token diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index 648a352efd9b..e0d9f0faaf7d 100644 --- a/compiler/rustc_parse/src/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -308,7 +308,7 @@ pub(super) static UNICODE_ARRAY: &[(char, &str, &str)] = &[ const ASCII_ARRAY: &[(&str, &str, Option)] = &[ (" ", "Space", None), ("_", "Underscore", Some(token::Ident(kw::Underscore, token::IdentIsRaw::No))), - ("-", "Minus/Hyphen", Some(token::BinOp(token::Minus))), + ("-", "Minus/Hyphen", Some(token::Minus)), (",", "Comma", Some(token::Comma)), (";", "Semicolon", Some(token::Semi)), (":", "Colon", Some(token::Colon)), @@ -321,11 +321,11 @@ const ASCII_ARRAY: &[(&str, &str, Option)] = &[ ("]", "Right Square Bracket", Some(token::CloseDelim(Delimiter::Bracket))), ("{", "Left Curly Brace", Some(token::OpenDelim(Delimiter::Brace))), ("}", "Right Curly Brace", Some(token::CloseDelim(Delimiter::Brace))), - ("*", "Asterisk", Some(token::BinOp(token::Star))), - ("/", "Slash", Some(token::BinOp(token::Slash))), + ("*", "Asterisk", Some(token::Star)), + ("/", "Slash", Some(token::Slash)), ("\\", "Backslash", None), - ("&", "Ampersand", Some(token::BinOp(token::And))), - ("+", "Plus Sign", Some(token::BinOp(token::Plus))), + ("&", "Ampersand", Some(token::And)), + ("+", "Plus Sign", Some(token::Plus)), ("<", "Less-Than Sign", Some(token::Lt)), ("=", "Equals Sign", Some(token::Eq)), ("==", "Double Equals Sign", Some(token::EqEq)), diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 02bcb1fbf702..660425086b4f 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1167,7 +1167,7 @@ impl<'a> Parser<'a> { let mut number_of_gt = 0; while self.look_ahead(position, |t| { trace!("check_trailing_angle_brackets: t={:?}", t); - if *t == token::BinOp(token::BinOpToken::Shr) { + if *t == token::Shr { number_of_shr += 1; true } else if *t == token::Gt { @@ -1222,7 +1222,7 @@ impl<'a> Parser<'a> { let span = lo.to(self.prev_token.span); // Detect trailing `>` like in `x.collect::Vec<_>>()`. let mut trailing_span = self.prev_token.span.shrink_to_hi(); - while self.token == token::BinOp(token::Shr) || self.token == token::Gt { + while self.token == token::Shr || self.token == token::Gt { trailing_span = trailing_span.to(self.token.span); self.bump(); } @@ -1468,8 +1468,7 @@ impl<'a> Parser<'a> { let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); // So far we have parsed `foo Parser<'a> { || self.token == TokenKind::Dot; // This will be true when a trait object type `Foo +` or a path which was a `const fn` with // type params has been parsed. - let was_op = - matches!(self.prev_token.kind, token::BinOp(token::Plus | token::Shr) | token::Gt); + let was_op = matches!(self.prev_token.kind, token::Plus | token::Shr | token::Gt); if !is_op_or_dot && !was_op { // We perform these checks and early return to avoid taking a snapshot unnecessarily. return Err(err); @@ -2992,8 +2990,7 @@ impl<'a> Parser<'a> { pub(super) fn recover_vcs_conflict_marker(&mut self) { // <<<<<<< - let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) - else { + let Some(start) = self.conflict_marker(&TokenKind::Shl, &TokenKind::Lt) else { return; }; let mut spans = Vec::with_capacity(3); @@ -3008,15 +3005,13 @@ impl<'a> Parser<'a> { if self.token == TokenKind::Eof { break; } - if let Some(span) = self.conflict_marker(&TokenKind::OrOr, &TokenKind::BinOp(token::Or)) - { + if let Some(span) = self.conflict_marker(&TokenKind::OrOr, &TokenKind::Or) { middlediff3 = Some(span); } if let Some(span) = self.conflict_marker(&TokenKind::EqEq, &TokenKind::Eq) { middle = Some(span); } - if let Some(span) = self.conflict_marker(&TokenKind::BinOp(token::Shr), &TokenKind::Gt) - { + if let Some(span) = self.conflict_marker(&TokenKind::Shr, &TokenKind::Gt) { spans.push(span); end = Some(span); break; diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index ef29ac2719d9..a991ad14bc8d 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -239,8 +239,8 @@ impl<'a> Parser<'a> { self.bump(); } - if self.prev_token == token::BinOp(token::Plus) - && self.token == token::BinOp(token::Plus) + if self.prev_token == token::Plus + && self.token == token::Plus && self.prev_token.span.between(self.token.span).is_empty() { let op_span = self.prev_token.span.to(self.token.span); @@ -250,8 +250,8 @@ impl<'a> Parser<'a> { continue; } - if self.prev_token == token::BinOp(token::Minus) - && self.token == token::BinOp(token::Minus) + if self.prev_token == token::Minus + && self.token == token::Minus && self.prev_token.span.between(self.token.span).is_empty() && !self.look_ahead(1, |tok| tok.can_begin_expr()) { @@ -509,19 +509,19 @@ impl<'a> Parser<'a> { // `~expr` token::Tilde => make_it!(this, attrs, |this, _| this.recover_tilde_expr(lo)), // `-expr` - token::BinOp(token::Minus) => { + token::Minus => { make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Neg)) } // `*expr` - token::BinOp(token::Star) => { + token::Star => { make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Deref)) } // `&expr` and `&&expr` - token::BinOp(token::And) | token::AndAnd => { + token::And | token::AndAnd => { make_it!(this, attrs, |this, _| this.parse_expr_borrow(lo)) } // `+lit` - token::BinOp(token::Plus) if this.look_ahead(1, |tok| tok.is_numeric_lit()) => { + token::Plus if this.look_ahead(1, |tok| tok.is_numeric_lit()) => { let mut err = errors::LeadingPlusNotSupported { span: lo, remove_plus: None, @@ -541,9 +541,7 @@ impl<'a> Parser<'a> { this.parse_expr_prefix(attrs) } // Recover from `++x`: - token::BinOp(token::Plus) - if this.look_ahead(1, |t| *t == token::BinOp(token::Plus)) => - { + token::Plus if this.look_ahead(1, |t| *t == token::Plus) => { let starts_stmt = this.prev_token == token::Semi || this.prev_token == token::CloseDelim(Delimiter::Brace); let pre_span = this.token.span.to(this.look_ahead(1, |t| t.span)); @@ -723,14 +721,12 @@ impl<'a> Parser<'a> { suggestion, }) } - token::BinOp(token::Shl) => { - self.dcx().emit_err(errors::ShiftInterpretedAsGeneric { - shift: self.token.span, - r#type: path, - args: args_span, - suggestion, - }) - } + token::Shl => self.dcx().emit_err(errors::ShiftInterpretedAsGeneric { + shift: self.token.span, + r#type: path, + args: args_span, + suggestion, + }), _ => { // We can end up here even without `<` being the next token, for // example because `parse_ty_no_plus` returns `Err` on keywords, @@ -2595,7 +2591,7 @@ impl<'a> Parser<'a> { missing_let: None, comparison: None, }; - if self.prev_token == token::BinOp(token::Or) { + if self.prev_token == token::Or { // This was part of a closure, the that part of the parser recover. return Err(self.dcx().create_err(err)); } else { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 5765a5b5315b..2c8fe7a63a9d 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1293,7 +1293,7 @@ impl<'a> Parser<'a> { if token.is_keyword(kw::Move) { return true; } - matches!(token.kind, token::BinOp(token::Or) | token::OrOr) + matches!(token.kind, token::Or | token::OrOr) }) } else { // `$qual static` @@ -1814,7 +1814,7 @@ impl<'a> Parser<'a> { let attrs = p.parse_outer_attributes()?; p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| { let mut snapshot = None; - if p.is_vcs_conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { + if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) { // Account for `<<<<<<<` diff markers. We can't proactively error here because // that can be a valid type start, so we snapshot and reparse only we've // encountered another parse error. @@ -3011,7 +3011,7 @@ impl<'a> Parser<'a> { // else is parsed as a normal function parameter list, so some lookahead is required. let eself_lo = self.token.span; let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind { - token::BinOp(token::And) => { + token::And => { let eself = if is_isolated_self(self, 1) { // `&self` self.bump(); @@ -3041,12 +3041,12 @@ impl<'a> Parser<'a> { (eself, self_ident, hi) } // `*self` - token::BinOp(token::Star) if is_isolated_self(self, 1) => { + token::Star if is_isolated_self(self, 1) => { self.bump(); recover_self_ptr(self)? } // `*mut self` and `*const self` - token::BinOp(token::Star) + token::Star if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) => { self.bump(); @@ -3077,7 +3077,7 @@ impl<'a> Parser<'a> { } _ => 0, }, - token::BinOp(token::And) | token::AndAnd => 1, + token::And | token::AndAnd => 1, _ if self.token.is_keyword(kw::Mut) => 1, _ => 0, }; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 00282ef86799..7dabc28c6454 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -813,9 +813,9 @@ impl<'a> Parser<'a> { self.is_keyword_ahead(0, &[kw::Const]) && self.look_ahead(1, |t| match &t.kind { // async closures do not work with const closures, so we do not parse that here. - token::Ident(kw::Move | kw::Static, IdentIsRaw::No) - | token::OrOr - | token::BinOp(token::Or) => true, + token::Ident(kw::Move | kw::Static, IdentIsRaw::No) | token::OrOr | token::Or => { + true + } _ => false, }) } @@ -1651,7 +1651,7 @@ impl<'a> Parser<'a> { /// `::{` or `::*` fn is_import_coupler(&mut self) -> bool { self.check_path_sep_and_look_ahead(|t| { - matches!(t.kind, token::OpenDelim(Delimiter::Brace) | token::BinOp(token::Star)) + matches!(t.kind, token::OpenDelim(Delimiter::Brace) | token::Star) }) } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 40f2e228b24e..04cdf8e55654 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -3,7 +3,7 @@ use std::ops::Bound; use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::token::NtPatKind::*; -use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, MetaVarKind, Token}; +use rustc_ast::token::{self, Delimiter, IdentIsRaw, MetaVarKind, Token}; use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{ @@ -358,7 +358,7 @@ impl<'a> Parser<'a> { ) }); match (is_end_ahead, &self.token.kind) { - (true, token::BinOp(token::Or) | token::OrOr) => { + (true, token::Or | token::OrOr) => { // A `|` or possibly `||` token shouldn't be here. Ban it. self.dcx().emit_err(TrailingVertNotAllowed { span: self.token.span, @@ -432,7 +432,11 @@ impl<'a> Parser<'a> { // `[` is included for indexing operations, // `[]` is excluded as `a[]` isn't an expression and should be recovered as `a, []` (cf. `tests/ui/parser/pat-lt-bracket-7.rs`), // `as` is included for type casts - let has_trailing_operator = matches!(self.token.kind, token::BinOp(op) if op != BinOpToken::Or) + let has_trailing_operator = matches!( + self.token.kind, + token::Plus | token::Minus | token::Star | token::Slash | token::Percent + | token::Caret | token::And | token::Shl | token::Shr // excludes `Or` + ) || self.token == token::Question || (self.token == token::OpenDelim(Delimiter::Bracket) && self.look_ahead(1, |t| *t != token::CloseDelim(Delimiter::Bracket))) // excludes `[]` @@ -1255,7 +1259,7 @@ impl<'a> Parser<'a> { || self.look_ahead(dist, |t| { t.is_path_start() // e.g. `MY_CONST`; || *t == token::Dot // e.g. `.5` for recovery; - || matches!(t.kind, token::Literal(..) | token::BinOp(token::Minus)) + || matches!(t.kind, token::Literal(..) | token::Minus) || t.is_bool_lit() || t.is_whole_expr() || t.is_lifetime() // recover `'a` instead of `'a'` diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 8091dfa2a4a4..9c6830c36727 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -305,10 +305,7 @@ impl<'a> Parser<'a> { let is_args_start = |token: &Token| { matches!( token.kind, - token::Lt - | token::BinOp(token::Shl) - | token::OpenDelim(Delimiter::Parenthesis) - | token::LArrow + token::Lt | token::Shl | token::OpenDelim(Delimiter::Parenthesis) | token::LArrow ) }; let check_args_start = |this: &mut Self| { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index a2699b077fcf..5e4034e0f4bf 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -442,7 +442,16 @@ impl<'a> Parser<'a> { /// Parses the RHS of a local variable declaration (e.g., `= 14;`). fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option>> { let eq_consumed = match self.token.kind { - token::BinOpEq(..) => { + token::PlusEq + | token::MinusEq + | token::StarEq + | token::SlashEq + | token::PercentEq + | token::CaretEq + | token::AndEq + | token::OrEq + | token::ShlEq + | token::ShrEq => { // Recover `let x = 1` as `let x = 1` We must not use `+ BytePos(1)` here // because `` can be a multi-byte lookalike that was recovered, e.g. `➖=` (the // `➖` is a U+2796 Heavy Minus Sign Unicode Character) that was recovered as a @@ -688,7 +697,7 @@ impl<'a> Parser<'a> { if self.token == token::Eof { break; } - if self.is_vcs_conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { + if self.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) { // Account for `<<<<<<<` diff markers. We can't proactively error here because // that can be a valid path start, so we snapshot and reparse only we've // encountered another parse error. diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs index 40631d9154d3..061b5dfba481 100644 --- a/compiler/rustc_parse/src/parser/token_type.rs +++ b/compiler/rustc_parse/src/parser/token_type.rs @@ -445,12 +445,6 @@ macro_rules! exp { token_type: $crate::parser::token_type::TokenType::$tok } }; - (@binop, $op:ident) => { - $crate::parser::token_type::ExpTokenPair { - tok: &rustc_ast::token::BinOp(rustc_ast::token::BinOpToken::$op), - token_type: $crate::parser::token_type::TokenType::$op, - } - }; (@open, $delim:ident, $token_type:ident) => { $crate::parser::token_type::ExpTokenPair { tok: &rustc_ast::token::OpenDelim(rustc_ast::token::Delimiter::$delim), @@ -487,6 +481,11 @@ macro_rules! exp { (OrOr) => { exp!(@tok, OrOr) }; (Not) => { exp!(@tok, Not) }; (Tilde) => { exp!(@tok, Tilde) }; + (Plus) => { exp!(@tok, Plus) }; + (Minus) => { exp!(@tok, Minus) }; + (Star) => { exp!(@tok, Star) }; + (And) => { exp!(@tok, And) }; + (Or) => { exp!(@tok, Or) }; (At) => { exp!(@tok, At) }; (Dot) => { exp!(@tok, Dot) }; (DotDot) => { exp!(@tok, DotDot) }; @@ -502,12 +501,6 @@ macro_rules! exp { (Question) => { exp!(@tok, Question) }; (Eof) => { exp!(@tok, Eof) }; - (Plus) => { exp!(@binop, Plus) }; - (Minus) => { exp!(@binop, Minus) }; - (Star) => { exp!(@binop, Star) }; - (And) => { exp!(@binop, And) }; - (Or) => { exp!(@binop, Or) }; - (OpenParen) => { exp!(@open, Parenthesis, OpenParen) }; (OpenBrace) => { exp!(@open, Brace, OpenBrace) }; (OpenBracket) => { exp!(@open, Bracket, OpenBracket) }; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 18af0a1c79aa..02f24b65688a 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -1,5 +1,5 @@ use rustc_ast::ptr::P; -use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, MetaVarKind, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, IdentIsRaw, MetaVarKind, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy, @@ -86,7 +86,7 @@ enum AllowCVariadic { /// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes /// that `IDENT` is not the ident of a fn trait. fn can_continue_type_after_non_fn_ident(t: &Token) -> bool { - t == &token::PathSep || t == &token::Lt || t == &token::BinOp(token::Shl) + t == &token::PathSep || t == &token::Lt || t == &token::Shl } fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool { @@ -399,7 +399,7 @@ impl<'a> Parser<'a> { let mut trailing_plus = false; let (ts, trailing) = self.parse_paren_comma_seq(|p| { let ty = p.parse_ty()?; - trailing_plus = p.prev_token == TokenKind::BinOp(token::Plus); + trailing_plus = p.prev_token == TokenKind::Plus; Ok(ty) })?; @@ -735,7 +735,7 @@ impl<'a> Parser<'a> { // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds()?; - *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::BinOp(token::Plus); + *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus; Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)) } @@ -747,11 +747,7 @@ impl<'a> Parser<'a> { self.expect_lt()?; let (args, _, _) = self.parse_seq_to_before_tokens( &[exp!(Gt)], - &[ - &TokenKind::Ge, - &TokenKind::BinOp(BinOpToken::Shr), - &TokenKind::BinOpEq(BinOpToken::Shr), - ], + &[&TokenKind::Ge, &TokenKind::Shr, &TokenKind::Shr], SeqSep::trailing_allowed(exp!(Comma)), |self_| { if self_.check_keyword(exp!(SelfUpper)) { @@ -781,7 +777,7 @@ impl<'a> Parser<'a> { self.check_keyword(exp!(Dyn)) && (self.token.uninterpolated_span().at_least_rust_2018() || self.look_ahead(1, |t| { - (can_begin_dyn_bound_in_edition_2015(t) || *t == TokenKind::BinOp(token::Star)) + (can_begin_dyn_bound_in_edition_2015(t) || *t == TokenKind::Star) && !can_continue_type_after_non_fn_ident(t) })) } @@ -803,7 +799,7 @@ impl<'a> Parser<'a> { // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds()?; - *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::BinOp(token::Plus); + *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus; Ok(TyKind::TraitObject(bounds, syntax)) } diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index 3cc5f8d615a4..b6b349173585 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -1,4 +1,4 @@ -use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw}; +use rustc_ast::token::{self, Delimiter, IdentIsRaw}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast_pretty::pprust::PrintState; use rustc_ast_pretty::pprust::state::State as Printer; @@ -137,14 +137,9 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) { (Dollar, token::Ident(..)) => (false, DollarIdent), (DollarIdent, token::Colon) => (false, DollarIdentColon), (DollarIdentColon, token::Ident(..)) => (false, Other), - ( - DollarParen, - token::BinOp(BinOpToken::Plus | BinOpToken::Star) | token::Question, - ) => (false, Other), + (DollarParen, token::Plus | token::Star | token::Question) => (false, Other), (DollarParen, _) => (false, DollarParenSep), - (DollarParenSep, token::BinOp(BinOpToken::Plus | BinOpToken::Star)) => { - (false, Other) - } + (DollarParenSep, token::Plus | token::Star) => (false, Other), (Pound, token::Not) => (false, PoundBang), (_, token::Ident(symbol, IdentIsRaw::No)) if !usually_needs_space_between_keyword_and_open_delim(*symbol, tt.span) => diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index ea8ca38cb772..7775db2db6bb 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -12,7 +12,7 @@ use std::collections::HashMap; use std::panic::{AssertUnwindSafe, catch_unwind}; -use rustc_ast::token::{BinOpToken, Delimiter, Token, TokenKind}; +use rustc_ast::token::{Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenStreamIter, TokenTree}; use rustc_ast::{ast, ptr}; use rustc_ast_pretty::pprust; @@ -841,7 +841,7 @@ impl MacroArgParser { match tok { TokenTree::Token( Token { - kind: TokenKind::BinOp(BinOpToken::Plus), + kind: TokenKind::Plus, .. }, _, @@ -855,7 +855,7 @@ impl MacroArgParser { ) | TokenTree::Token( Token { - kind: TokenKind::BinOp(BinOpToken::Star), + kind: TokenKind::Star, .. }, _, @@ -1090,12 +1090,30 @@ fn force_space_before(tok: &TokenKind) -> bool { | TokenKind::OrOr | TokenKind::Not | TokenKind::Tilde - | TokenKind::BinOpEq(_) + | TokenKind::PlusEq + | TokenKind::MinusEq + | TokenKind::StarEq + | TokenKind::SlashEq + | TokenKind::PercentEq + | TokenKind::CaretEq + | TokenKind::AndEq + | TokenKind::OrEq + | TokenKind::ShlEq + | TokenKind::ShrEq | TokenKind::At | TokenKind::RArrow | TokenKind::LArrow | TokenKind::FatArrow - | TokenKind::BinOp(_) + | TokenKind::Plus + | TokenKind::Minus + | TokenKind::Star + | TokenKind::Slash + | TokenKind::Percent + | TokenKind::Caret + | TokenKind::And + | TokenKind::Or + | TokenKind::Shl + | TokenKind::Shr | TokenKind::Pound | TokenKind::Dollar => true, _ => false, @@ -1114,7 +1132,7 @@ fn next_space(tok: &TokenKind) -> SpaceState { match tok { TokenKind::Not - | TokenKind::BinOp(BinOpToken::And) + | TokenKind::And | TokenKind::Tilde | TokenKind::At | TokenKind::Comma From 53167c0b7f8112a492b9442058a034605a120c9e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Dec 2024 14:04:25 +1100 Subject: [PATCH 555/991] Rename `ast::TokenKind::Not` as `ast::TokenKind::Bang`. For consistency with `rustc_lexer::TokenKind::Bang`, and because other `ast::TokenKind` variants generally have syntactic names instead of semantic names (e.g. `Star` and `DotDot` instead of `Mul` and `Range`). --- compiler/rustc_ast/src/token.rs | 14 +++++++------- compiler/rustc_ast/src/tokenstream.rs | 2 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 4 ++-- compiler/rustc_expand/src/config.rs | 2 +- compiler/rustc_expand/src/mbe/macro_check.rs | 2 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 2 +- compiler/rustc_expand/src/proc_macro_server.rs | 4 ++-- compiler/rustc_parse/src/lexer/mod.rs | 2 +- compiler/rustc_parse/src/lexer/unicode_chars.rs | 2 +- compiler/rustc_parse/src/parser/attr.rs | 4 ++-- compiler/rustc_parse/src/parser/diagnostics.rs | 6 +++--- compiler/rustc_parse/src/parser/expr.rs | 4 ++-- compiler/rustc_parse/src/parser/item.rs | 16 ++++++++-------- compiler/rustc_parse/src/parser/pat.rs | 6 +++--- compiler/rustc_parse/src/parser/stmt.rs | 2 +- compiler/rustc_parse/src/parser/tests.rs | 2 +- compiler/rustc_parse/src/parser/token_type.rs | 8 ++++---- compiler/rustc_parse/src/parser/ty.rs | 8 ++++---- src/librustdoc/clean/render_macro_matchers.rs | 2 +- src/tools/rustfmt/src/macros.rs | 4 ++-- 20 files changed, 48 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 9304636eda6c..ff1edad725a4 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -360,7 +360,7 @@ pub enum TokenKind { /// `||` OrOr, /// `!` - Not, + Bang, /// `~` Tilde, // `+` @@ -522,7 +522,7 @@ impl TokenKind { Some(match (self, n) { (Le, 1) => (Lt, Eq), (EqEq, 1) => (Eq, Eq), - (Ne, 1) => (Not, Eq), + (Ne, 1) => (Bang, Eq), (Ge, 1) => (Gt, Eq), (AndAnd, 1) => (And, And), (OrOr, 1) => (Or, Or), @@ -604,7 +604,7 @@ impl Token { pub fn is_punct(&self) -> bool { match self.kind { - Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | Plus | Minus + Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Bang | Tilde | Plus | Minus | Star | Slash | Percent | Caret | And | Or | Shl | Shr | PlusEq | MinusEq | StarEq | SlashEq | PercentEq | CaretEq | AndEq | OrEq | ShlEq | ShrEq | At | Dot | DotDot | DotDotDot | DotDotEq | Comma | Semi | Colon | PathSep | RArrow | LArrow @@ -630,7 +630,7 @@ impl Token { ident_can_begin_expr(name, self.span, is_raw), // value name or keyword OpenDelim(Parenthesis | Brace | Bracket) | // tuple, array or block Literal(..) | // literal - Not | // operator not + Bang | // operator not Minus | // unary minus Star | // dereference Or | OrOr | // closure @@ -701,7 +701,7 @@ impl Token { ident_can_begin_type(name, self.span, is_raw), // type name or keyword OpenDelim(Delimiter::Parenthesis) | // tuple OpenDelim(Delimiter::Bracket) | // array - Not | // never + Bang | // never Star | // raw pointer And | // reference AndAnd | // double reference @@ -1004,8 +1004,8 @@ impl Token { (Gt, Ge) => ShrEq, (Gt, _) => return None, - (Not, Eq) => Ne, - (Not, _) => return None, + (Bang, Eq) => Ne, + (Bang, _) => return None, (Plus, Eq) => PlusEq, (Plus, _) => return None, diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 49ae8cc78fc5..b9b20cf93768 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -651,7 +651,7 @@ impl TokenStream { if attr_style == AttrStyle::Inner { vec![ TokenTree::token_joint(token::Pound, span), - TokenTree::token_joint_hidden(token::Not, span), + TokenTree::token_joint_hidden(token::Bang, span), body, ] } else { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 9d922b61567e..d747237f76db 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -317,7 +317,7 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool { (tt1, Tok(Token { kind: Comma | Semi | Dot, .. }, _)) if !is_punct(tt1) => false, // IDENT + `!`: `println!()`, but `if !x { ... }` needs a space after the `if` - (Tok(Token { kind: Ident(sym, is_raw), span }, _), Tok(Token { kind: Not, .. }, _)) + (Tok(Token { kind: Ident(sym, is_raw), span }, _), Tok(Token { kind: Bang, .. }, _)) if !Ident::new(*sym, *span).is_reserved() || matches!(is_raw, IdentIsRaw::Yes) => { false @@ -896,7 +896,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere token::Ne => "!=".into(), token::Ge => ">=".into(), token::Gt => ">".into(), - token::Not => "!".into(), + token::Bang => "!".into(), token::Tilde => "~".into(), token::OrOr => "||".into(), token::AndAnd => "&&".into(), diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 83255b820178..5570c0c38e83 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -328,7 +328,7 @@ impl<'a> StripUnconfigured<'a> { // For inner attributes, we do the same thing for the `!` in `#![attr]`. let mut trees = if cfg_attr.style == AttrStyle::Inner { - let Some(TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _)) = + let Some(TokenTree::Token(bang_token @ Token { kind: TokenKind::Bang, .. }, _)) = orig_trees.next() else { panic!("Bad tokens for attribute {cfg_attr:?}"); diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs index 729dec2bfbdb..1a2db233b7a6 100644 --- a/compiler/rustc_expand/src/mbe/macro_check.rs +++ b/compiler/rustc_expand/src/mbe/macro_check.rs @@ -432,7 +432,7 @@ fn check_nested_occurrences( } ( NestedMacroState::MacroRules, - &TokenTree::Token(Token { kind: TokenKind::Not, .. }), + &TokenTree::Token(Token { kind: TokenKind::Bang, .. }), ) => { state = NestedMacroState::MacroRulesNot; } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index db45739e2dde..5577c8902dae 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -690,7 +690,7 @@ fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool { && let TokenKind::Ident(ident, _) = ident.kind && ident == sym::compile_error && let mbe::TokenTree::Token(bang) = bang - && let TokenKind::Not = bang.kind + && let TokenKind::Bang = bang.kind && let mbe::TokenTree::Delimited(.., del) = args && !del.delim.skip() { diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index a8a323c7a8de..007241437ecc 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -180,7 +180,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec op(">"), AndAnd => op("&&"), OrOr => op("||"), - Not => op("!"), + Bang => op("!"), Tilde => op("~"), Plus => op("+"), Minus => op("-"), @@ -322,7 +322,7 @@ impl ToInternal> b'=' => Eq, b'<' => Lt, b'>' => Gt, - b'!' => Not, + b'!' => Bang, b'~' => Tilde, b'+' => Plus, b'-' => Minus, diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 94604043bac6..1d17290e1c70 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -384,7 +384,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { rustc_lexer::TokenKind::Colon => token::Colon, rustc_lexer::TokenKind::Dollar => token::Dollar, rustc_lexer::TokenKind::Eq => token::Eq, - rustc_lexer::TokenKind::Bang => token::Not, + rustc_lexer::TokenKind::Bang => token::Bang, rustc_lexer::TokenKind::Lt => token::Lt, rustc_lexer::TokenKind::Gt => token::Gt, rustc_lexer::TokenKind::Minus => token::Minus, diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index e0d9f0faaf7d..ff03b42484b4 100644 --- a/compiler/rustc_parse/src/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -312,7 +312,7 @@ const ASCII_ARRAY: &[(&str, &str, Option)] = &[ (",", "Comma", Some(token::Comma)), (";", "Semicolon", Some(token::Semi)), (":", "Colon", Some(token::Colon)), - ("!", "Exclamation Mark", Some(token::Not)), + ("!", "Exclamation Mark", Some(token::Bang)), ("?", "Question Mark", Some(token::Question)), (".", "Period", Some(token::Dot)), ("(", "Left Parenthesis", Some(token::OpenDelim(Delimiter::Parenthesis))), diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 98fdd35190d8..066b570c23f9 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -130,7 +130,7 @@ impl<'a> Parser<'a> { assert!(this.eat(exp!(Pound)), "parse_attribute called in non-attribute position"); let style = - if this.eat(exp!(Not)) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer }; + if this.eat(exp!(Bang)) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer }; this.expect(exp!(OpenBracket))?; let item = this.parse_attr_item(ForceCollect::No)?; @@ -312,7 +312,7 @@ impl<'a> Parser<'a> { loop { let start_pos = self.num_bump_calls; // Only try to parse if it is an inner attribute (has `!`). - let attr = if self.check(exp!(Pound)) && self.look_ahead(1, |t| t == &token::Not) { + let attr = if self.check(exp!(Pound)) && self.look_ahead(1, |t| t == &token::Bang) { Some(self.parse_attribute(InnerAttrPolicy::Permitted)?) } else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind { if attr_style == ast::AttrStyle::Inner { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 660425086b4f..94db43bb59f8 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1961,7 +1961,7 @@ impl<'a> Parser<'a> { &mut self, await_sp: Span, ) -> PResult<'a, P> { - let (hi, expr, is_question) = if self.token == token::Not { + let (hi, expr, is_question) = if self.token == token::Bang { // Handle `await!()`. self.recover_await_macro()? } else { @@ -1973,7 +1973,7 @@ impl<'a> Parser<'a> { } fn recover_await_macro(&mut self) -> PResult<'a, (Span, P, bool)> { - self.expect(exp!(Not))?; + self.expect(exp!(Bang))?; self.expect(exp!(OpenParen))?; let expr = self.parse_expr()?; self.expect(exp!(CloseParen))?; @@ -2033,7 +2033,7 @@ impl<'a> Parser<'a> { pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P> { let is_try = self.token.is_keyword(kw::Try); - let is_questionmark = self.look_ahead(1, |t| t == &token::Not); //check for ! + let is_questionmark = self.look_ahead(1, |t| t == &token::Bang); //check for ! let is_open = self.look_ahead(2, |t| t == &token::OpenDelim(Delimiter::Parenthesis)); //check for ( if is_try && is_questionmark && is_open { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a991ad14bc8d..23b366dc2c9a 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -505,7 +505,7 @@ impl<'a> Parser<'a> { // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr() match this.token.uninterpolate().kind { // `!expr` - token::Not => make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Not)), + token::Bang => make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Not)), // `~expr` token::Tilde => make_it!(this, attrs, |this, _| this.recover_tilde_expr(lo)), // `-expr` @@ -1570,7 +1570,7 @@ impl<'a> Parser<'a> { }; // `!`, as an operator, is prefix, so we know this isn't that. - let (span, kind) = if self.eat(exp!(Not)) { + let (span, kind) = if self.eat(exp!(Bang)) { // MACRO INVOCATION expression if qself.is_some() { self.dcx().emit_err(errors::MacroInvocationWithQualifiedPath(path.span)); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2c8fe7a63a9d..3f642a7ac1fd 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -382,7 +382,7 @@ impl<'a> Parser<'a> { /// Are we sure this could not possibly be a macro invocation? fn isnt_macro_invocation(&mut self) -> bool { - self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::PathSep) + self.check_ident() && self.look_ahead(1, |t| *t != token::Bang && *t != token::PathSep) } /// Recover on encountering a struct, enum, or method definition where the user @@ -480,7 +480,7 @@ impl<'a> Parser<'a> { /// Parses an item macro, e.g., `item!();`. fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> { let path = self.parse_path(PathStyle::Mod)?; // `foo::bar` - self.expect(exp!(Not))?; // `!` + self.expect(exp!(Bang))?; // `!` match self.parse_delim_args() { // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`. Ok(args) => { @@ -540,7 +540,7 @@ impl<'a> Parser<'a> { fn parse_polarity(&mut self) -> ast::ImplPolarity { // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type. - if self.check(exp!(Not)) && self.look_ahead(1, |t| t.can_begin_type()) { + if self.check(exp!(Bang)) && self.look_ahead(1, |t| t.can_begin_type()) { self.bump(); // `!` ast::ImplPolarity::Negative(self.prev_token.span) } else { @@ -1579,7 +1579,7 @@ impl<'a> Parser<'a> { } let ident = this.parse_field_ident("enum", vlo)?; - if this.token == token::Not { + if this.token == token::Bang { if let Err(err) = this.unexpected() { err.with_note(fluent::parse_macro_expands_to_enum_variant).emit(); } @@ -2034,7 +2034,7 @@ impl<'a> Parser<'a> { attrs: AttrVec, ) -> PResult<'a, FieldDef> { let name = self.parse_field_ident(adt_ty, lo)?; - if self.token == token::Not { + if self.token == token::Bang { if let Err(mut err) = self.unexpected() { // Encounter the macro invocation err.subdiagnostic(MacroExpandsToAdtField { adt_ty }); @@ -2184,7 +2184,7 @@ impl<'a> Parser<'a> { if self.check_keyword(exp!(MacroRules)) { let macro_rules_span = self.token.span; - if self.look_ahead(1, |t| *t == token::Not) && self.look_ahead(2, |t| t.is_ident()) { + if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) { return IsMacroRulesItem::Yes { has_bang: true }; } else if self.look_ahead(1, |t| (t.is_ident())) { // macro_rules foo @@ -2209,11 +2209,11 @@ impl<'a> Parser<'a> { self.expect_keyword(exp!(MacroRules))?; // `macro_rules` if has_bang { - self.expect(exp!(Not))?; // `!` + self.expect(exp!(Bang))?; // `!` } let ident = self.parse_ident()?; - if self.eat(exp!(Not)) { + if self.eat(exp!(Bang)) { // Handle macro_rules! foo! let span = self.prev_token.span; self.dcx().emit_err(errors::MacroNameRemoveBang { span }); diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 04cdf8e55654..ec14c5718da5 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -767,7 +767,7 @@ impl<'a> Parser<'a> { self.recover_dotdotdot_rest_pat(lo) } else if let Some(form) = self.parse_range_end() { self.parse_pat_range_to(form)? // `..=X`, `...X`, or `..X`. - } else if self.eat(exp!(Not)) { + } else if self.eat(exp!(Bang)) { // Parse `!` self.psess.gated_spans.gate(sym::never_patterns, self.prev_token.span); PatKind::Never @@ -823,7 +823,7 @@ impl<'a> Parser<'a> { }; let span = lo.to(self.prev_token.span); - if qself.is_none() && self.check(exp!(Not)) { + if qself.is_none() && self.check(exp!(Bang)) { self.parse_pat_mac_invoc(path)? } else if let Some(form) = self.parse_range_end() { let begin = self.mk_expr(span, ExprKind::Path(qself, path)); @@ -1335,7 +1335,7 @@ impl<'a> Parser<'a> { | token::OpenDelim(Delimiter::Brace) // A struct pattern. | token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern. | token::PathSep // A tuple / struct variant pattern. - | token::Not)) // A macro expanding to a pattern. + | token::Bang)) // A macro expanding to a pattern. } /// Parses `ident` or `ident @ pat`. diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 5e4034e0f4bf..3a9dc5ce7985 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -176,7 +176,7 @@ impl<'a> Parser<'a> { let stmt = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { let path = this.parse_path(PathStyle::Expr)?; - if this.eat(exp!(Not)) { + if this.eat(exp!(Bang)) { let stmt_mac = this.parse_stmt_mac(lo, attrs, path)?; return Ok(( stmt_mac, diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 8b8c81a77a01..471966d086d5 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -2291,7 +2291,7 @@ fn string_to_tts_macro() { Token { kind: token::Ident(name_macro_rules, IdentIsRaw::No), .. }, _, ), - TokenTree::Token(Token { kind: token::Not, .. }, _), + TokenTree::Token(Token { kind: token::Bang, .. }, _), TokenTree::Token(Token { kind: token::Ident(name_zip, IdentIsRaw::No), .. }, _), TokenTree::Delimited(.., macro_delim, macro_tts), ] if name_macro_rules == &kw::MacroRules && name_zip.as_str() == "zip" => { diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs index 061b5dfba481..110546d0ba66 100644 --- a/compiler/rustc_parse/src/parser/token_type.rs +++ b/compiler/rustc_parse/src/parser/token_type.rs @@ -25,7 +25,7 @@ pub enum TokenType { Gt, AndAnd, OrOr, - Not, + Bang, Tilde, // BinOps @@ -172,7 +172,7 @@ impl TokenType { Gt, AndAnd, OrOr, - Not, + Bang, Tilde, Plus, @@ -366,7 +366,7 @@ impl TokenType { TokenType::Gt => "`>`", TokenType::AndAnd => "`&&`", TokenType::OrOr => "`||`", - TokenType::Not => "`!`", + TokenType::Bang => "`!`", TokenType::Tilde => "`~`", TokenType::Plus => "`+`", @@ -479,7 +479,7 @@ macro_rules! exp { (Gt) => { exp!(@tok, Gt) }; (AndAnd) => { exp!(@tok, AndAnd) }; (OrOr) => { exp!(@tok, OrOr) }; - (Not) => { exp!(@tok, Not) }; + (Bang) => { exp!(@tok, Bang) }; (Tilde) => { exp!(@tok, Tilde) }; (Plus) => { exp!(@tok, Plus) }; (Minus) => { exp!(@tok, Minus) }; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 02f24b65688a..b45ebae079cb 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -260,7 +260,7 @@ impl<'a> Parser<'a> { let mut impl_dyn_multi = false; let kind = if self.check(exp!(OpenParen)) { self.parse_ty_tuple_or_parens(lo, allow_plus)? - } else if self.eat(exp!(Not)) { + } else if self.eat(exp!(Bang)) { // Never type `!` TyKind::Never } else if self.eat(exp!(Star)) { @@ -817,7 +817,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, TyKind> { // Simple path let path = self.parse_path_inner(PathStyle::Type, ty_generics)?; - if self.eat(exp!(Not)) { + if self.eat(exp!(Bang)) { // Macro invocation in type position Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? }))) } else if allow_plus == AllowPlus::Yes && self.check_plus() { @@ -870,7 +870,7 @@ impl<'a> Parser<'a> { fn can_begin_bound(&mut self) -> bool { self.check_path() || self.check_lifetime() - || self.check(exp!(Not)) + || self.check(exp!(Bang)) || self.check(exp!(Question)) || self.check(exp!(Tilde)) || self.check_keyword(exp!(For)) @@ -1021,7 +1021,7 @@ impl<'a> Parser<'a> { let polarity = if self.eat(exp!(Question)) { BoundPolarity::Maybe(self.prev_token.span) - } else if self.eat(exp!(Not)) { + } else if self.eat(exp!(Bang)) { self.psess.gated_spans.gate(sym::negative_bounds, self.prev_token.span); BoundPolarity::Negative(self.prev_token.span) } else { diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index b6b349173585..88db853d7c38 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -140,7 +140,7 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) { (DollarParen, token::Plus | token::Star | token::Question) => (false, Other), (DollarParen, _) => (false, DollarParenSep), (DollarParenSep, token::Plus | token::Star) => (false, Other), - (Pound, token::Not) => (false, PoundBang), + (Pound, token::Bang) => (false, PoundBang), (_, token::Ident(symbol, IdentIsRaw::No)) if !usually_needs_space_between_keyword_and_open_delim(*symbol, tt.span) => { diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index 7775db2db6bb..664c90b991a9 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -1088,7 +1088,7 @@ fn force_space_before(tok: &TokenKind) -> bool { | TokenKind::Gt | TokenKind::AndAnd | TokenKind::OrOr - | TokenKind::Not + | TokenKind::Bang | TokenKind::Tilde | TokenKind::PlusEq | TokenKind::MinusEq @@ -1131,7 +1131,7 @@ fn next_space(tok: &TokenKind) -> SpaceState { debug!("next_space: {:?}", tok); match tok { - TokenKind::Not + TokenKind::Bang | TokenKind::And | TokenKind::Tilde | TokenKind::At From 6b29bb6680e0df3bbcd8e9defdf0ad142e80cdf0 Mon Sep 17 00:00:00 2001 From: Sa4dUs Date: Sun, 2 Mar 2025 23:38:55 +0100 Subject: [PATCH 556/991] Prevent ICE in autodiff validation by emitting user-friendly errors --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 673740b4aab9..c8f13dc0bae6 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -930,13 +930,19 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option { } } + // Validate input and return activities + let mut msg = "".to_string(); for &input in &arg_activities { if !valid_input_activity(mode, input) { - span_bug!(attr.span(), "Invalid input activity {} for {} mode", input, mode); + msg = format!("Invalid input activity {} for {} mode", input, mode); } } if !valid_ret_activity(mode, ret_activity) { - span_bug!(attr.span(), "Invalid return activity {} for {} mode", ret_activity, mode); + msg = format!("Invalid return activity {} for {} mode", ret_activity, mode); + } + if msg != "".to_string() { + tcx.dcx().struct_span_err(attr.span(), msg).with_note("invalid activity").emit(); + return Some(AutoDiffAttrs::error()); } Some(AutoDiffAttrs { mode, ret_activity, input_activity: arg_activities }) From 83fa2faf239b4bcde67eda7adf0a1a10dfca620d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 1 Mar 2025 19:28:04 +0000 Subject: [PATCH 557/991] Fix pretty printing of unsafe binders --- compiler/rustc_middle/src/ty/print/pretty.rs | 115 ++++++++++++------ compiler/rustc_symbol_mangling/src/v0.rs | 7 +- .../src/error_reporting/infer/mod.rs | 6 +- tests/ui/unsafe-binders/type-mismatch.rs | 9 ++ tests/ui/unsafe-binders/type-mismatch.stderr | 34 ++++++ 5 files changed, 130 insertions(+), 41 deletions(-) create mode 100644 tests/ui/unsafe-binders/type-mismatch.rs create mode 100644 tests/ui/unsafe-binders/type-mismatch.stderr diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c77b37a302bc..f1e82e8816cf 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -133,6 +133,20 @@ pub macro with_no_queries($e:expr) {{ )) }} +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum WrapBinderMode { + ForAll, + Unsafe, +} +impl WrapBinderMode { + pub fn start_str(self) -> &'static str { + match self { + WrapBinderMode::ForAll => "for<", + WrapBinderMode::Unsafe => "unsafe<", + } + } +} + /// The "region highlights" are used to control region printing during /// specific error messages. When a "region highlight" is enabled, it /// gives an alternate way to print specific regions. For now, we @@ -219,7 +233,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { self.print_def_path(def_id, args) } - fn in_binder(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError> + fn in_binder( + &mut self, + value: &ty::Binder<'tcx, T>, + _mode: WrapBinderMode, + ) -> Result<(), PrintError> where T: Print<'tcx, Self> + TypeFoldable>, { @@ -229,6 +247,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { fn wrap_binder Result<(), fmt::Error>>( &mut self, value: &ty::Binder<'tcx, T>, + _mode: WrapBinderMode, f: F, ) -> Result<(), PrintError> where @@ -703,8 +722,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } ty::FnPtr(ref sig_tys, hdr) => p!(print(sig_tys.with(hdr))), ty::UnsafeBinder(ref bound_ty) => { - // FIXME(unsafe_binders): Make this print `unsafe<>` rather than `for<>`. - self.wrap_binder(bound_ty, |ty, cx| cx.pretty_print_type(*ty))?; + self.wrap_binder(bound_ty, WrapBinderMode::Unsafe, |ty, cx| { + cx.pretty_print_type(*ty) + })?; } ty::Infer(infer_ty) => { if self.should_print_verbose() { @@ -1067,29 +1087,33 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { }; if let Some(return_ty) = entry.return_ty { - self.wrap_binder(&bound_args_and_self_ty, |(args, _), cx| { - define_scoped_cx!(cx); - p!(write("{}", tcx.item_name(trait_def_id))); - p!("("); + self.wrap_binder( + &bound_args_and_self_ty, + WrapBinderMode::ForAll, + |(args, _), cx| { + define_scoped_cx!(cx); + p!(write("{}", tcx.item_name(trait_def_id))); + p!("("); - for (idx, ty) in args.iter().enumerate() { - if idx > 0 { - p!(", "); + for (idx, ty) in args.iter().enumerate() { + if idx > 0 { + p!(", "); + } + p!(print(ty)); } - p!(print(ty)); - } - p!(")"); - if let Some(ty) = return_ty.skip_binder().as_type() { - if !ty.is_unit() { - p!(" -> ", print(return_ty)); + p!(")"); + if let Some(ty) = return_ty.skip_binder().as_type() { + if !ty.is_unit() { + p!(" -> ", print(return_ty)); + } } - } - p!(write("{}", if paren_needed { ")" } else { "" })); + p!(write("{}", if paren_needed { ")" } else { "" })); - first = false; - Ok(()) - })?; + first = false; + Ok(()) + }, + )?; } else { // Otherwise, render this like a regular trait. traits.insert( @@ -1110,7 +1134,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { for (trait_pred, assoc_items) in traits { write!(self, "{}", if first { "" } else { " + " })?; - self.wrap_binder(&trait_pred, |trait_pred, cx| { + self.wrap_binder(&trait_pred, WrapBinderMode::ForAll, |trait_pred, cx| { define_scoped_cx!(cx); if trait_pred.polarity == ty::PredicatePolarity::Negative { @@ -1302,7 +1326,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut first = true; if let Some(bound_principal) = predicates.principal() { - self.wrap_binder(&bound_principal, |principal, cx| { + self.wrap_binder(&bound_principal, WrapBinderMode::ForAll, |principal, cx| { define_scoped_cx!(cx); p!(print_def_path(principal.def_id, &[])); @@ -1927,7 +1951,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn); write!(self, "impl ")?; - self.wrap_binder(&sig, |sig, cx| { + self.wrap_binder(&sig, WrapBinderMode::ForAll, |sig, cx| { define_scoped_cx!(cx); p!(write("{kind}(")); @@ -2367,22 +2391,27 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { Ok(()) } - fn in_binder(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError> + fn in_binder( + &mut self, + value: &ty::Binder<'tcx, T>, + mode: WrapBinderMode, + ) -> Result<(), PrintError> where T: Print<'tcx, Self> + TypeFoldable>, { - self.pretty_in_binder(value) + self.pretty_in_binder(value, mode) } fn wrap_binder Result<(), PrintError>>( &mut self, value: &ty::Binder<'tcx, T>, + mode: WrapBinderMode, f: C, ) -> Result<(), PrintError> where T: TypeFoldable>, { - self.pretty_wrap_binder(value, f) + self.pretty_wrap_binder(value, mode, f) } fn typed_value( @@ -2632,6 +2661,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { pub fn name_all_regions( &mut self, value: &ty::Binder<'tcx, T>, + mode: WrapBinderMode, ) -> Result<(T, UnordMap>), fmt::Error> where T: TypeFoldable>, @@ -2705,9 +2735,13 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { // anyways. let (new_value, map) = if self.should_print_verbose() { for var in value.bound_vars().iter() { - start_or_continue(self, "for<", ", "); + start_or_continue(self, mode.start_str(), ", "); write!(self, "{var:?}")?; } + // Unconditionally render `unsafe<>`. + if value.bound_vars().is_empty() && mode == WrapBinderMode::Unsafe { + start_or_continue(self, mode.start_str(), ""); + } start_or_continue(self, "", "> "); (value.clone().skip_binder(), UnordMap::default()) } else { @@ -2772,8 +2806,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { } }; - if !trim_path { - start_or_continue(self, "for<", ", "); + // Unconditionally render `unsafe<>`. + if !trim_path || mode == WrapBinderMode::Unsafe { + start_or_continue(self, mode.start_str(), ", "); do_continue(self, name); } ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion { var: br.var, kind }) @@ -2786,9 +2821,12 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { }; let new_value = value.clone().skip_binder().fold_with(&mut folder); let region_map = folder.region_map; - if !trim_path { - start_or_continue(self, "", "> "); + + if mode == WrapBinderMode::Unsafe && region_map.is_empty() { + start_or_continue(self, mode.start_str(), ""); } + start_or_continue(self, "", "> "); + (new_value, region_map) }; @@ -2797,12 +2835,16 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { Ok((new_value, map)) } - pub fn pretty_in_binder(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), fmt::Error> + pub fn pretty_in_binder( + &mut self, + value: &ty::Binder<'tcx, T>, + mode: WrapBinderMode, + ) -> Result<(), fmt::Error> where T: Print<'tcx, Self> + TypeFoldable>, { let old_region_index = self.region_index; - let (new_value, _) = self.name_all_regions(value)?; + let (new_value, _) = self.name_all_regions(value, mode)?; new_value.print(self)?; self.region_index = old_region_index; self.binder_depth -= 1; @@ -2812,13 +2854,14 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { pub fn pretty_wrap_binder Result<(), fmt::Error>>( &mut self, value: &ty::Binder<'tcx, T>, + mode: WrapBinderMode, f: C, ) -> Result<(), fmt::Error> where T: TypeFoldable>, { let old_region_index = self.region_index; - let (new_value, _) = self.name_all_regions(value)?; + let (new_value, _) = self.name_all_regions(value, mode)?; f(&new_value, self)?; self.region_index = old_region_index; self.binder_depth -= 1; @@ -2877,7 +2920,7 @@ where T: Print<'tcx, P> + TypeFoldable>, { fn print(&self, cx: &mut P) -> Result<(), PrintError> { - cx.in_binder(self) + cx.in_binder(self, WrapBinderMode::ForAll) } } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 4fafd1ac3509..5f56e3d21455 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -12,7 +12,7 @@ use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_middle::bug; use rustc_middle::ty::layout::IntegerExt; -use rustc_middle::ty::print::{Print, PrintError, Printer}; +use rustc_middle::ty::print::{Print, PrintError, Printer, WrapBinderMode}; use rustc_middle::ty::{ self, FloatTy, GenericArg, GenericArgKind, Instance, IntTy, ReifyReason, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, UintTy, @@ -172,6 +172,7 @@ impl<'tcx> SymbolMangler<'tcx> { fn in_binder( &mut self, value: &ty::Binder<'tcx, T>, + _mode: WrapBinderMode, print_value: impl FnOnce(&mut Self, &T) -> Result<(), PrintError>, ) -> Result<(), PrintError> where @@ -471,7 +472,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ty::FnPtr(sig_tys, hdr) => { let sig = sig_tys.with(hdr); self.push("F"); - self.in_binder(&sig, |cx, sig| { + self.in_binder(&sig, WrapBinderMode::ForAll, |cx, sig| { if sig.safety.is_unsafe() { cx.push("U"); } @@ -554,7 +555,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { // [ [{}]] [{}] // Since any predicates after the first one shouldn't change the binders, // just put them all in the binders of the first. - self.in_binder(&predicates[0], |cx, _| { + self.in_binder(&predicates[0], WrapBinderMode::ForAll, |cx, _| { for predicate in predicates.iter() { // It would be nice to be able to validate bound vars here, but // projections can actually include bound vars from super traits diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 847bd06bb017..42d37418fb84 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -65,7 +65,9 @@ use rustc_middle::bug; use rustc_middle::dep_graph::DepContext; use rustc_middle::traits::PatternOriginExpr; use rustc_middle::ty::error::{ExpectedFound, TypeError, TypeErrorToStringExt}; -use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, with_forced_trimmed_paths}; +use rustc_middle::ty::print::{ + PrintError, PrintTraitRefExt as _, WrapBinderMode, with_forced_trimmed_paths, +}; use rustc_middle::ty::{ self, List, ParamEnv, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, @@ -835,7 +837,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let get_lifetimes = |sig| { use rustc_hir::def::Namespace; let (sig, reg) = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS) - .name_all_regions(sig) + .name_all_regions(sig, WrapBinderMode::ForAll) .unwrap(); let lts: Vec = reg.into_items().map(|(_, kind)| kind.to_string()).into_sorted_stable_ord(); diff --git a/tests/ui/unsafe-binders/type-mismatch.rs b/tests/ui/unsafe-binders/type-mismatch.rs new file mode 100644 index 000000000000..9ac4e817c28b --- /dev/null +++ b/tests/ui/unsafe-binders/type-mismatch.rs @@ -0,0 +1,9 @@ +#![feature(unsafe_binders)] +//~^ WARN the feature `unsafe_binders` is incomplete + +fn main() { + let x: unsafe<> i32 = 0; + //~^ ERROR mismatched types + let x: unsafe<'a> &'a i32 = &0; + //~^ ERROR mismatched types +} diff --git a/tests/ui/unsafe-binders/type-mismatch.stderr b/tests/ui/unsafe-binders/type-mismatch.stderr new file mode 100644 index 000000000000..e694b5d464d8 --- /dev/null +++ b/tests/ui/unsafe-binders/type-mismatch.stderr @@ -0,0 +1,34 @@ +warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/type-mismatch.rs:1:12 + | +LL | #![feature(unsafe_binders)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #130516 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:5:27 + | +LL | let x: unsafe<> i32 = 0; + | ------------ ^ expected `unsafe<> i32`, found integer + | | + | expected due to this + | + = note: expected unsafe binder `unsafe<> i32` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:7:33 + | +LL | let x: unsafe<'a> &'a i32 = &0; + | ------------------ ^^ expected `unsafe<'a> &i32`, found `&{integer}` + | | + | expected due to this + | + = note: expected unsafe binder `unsafe<'a> &'a i32` + found reference `&{integer}` + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. From a05a8c80f39033bbc99299a987bf55c85bb574a0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Mar 2025 01:34:06 +0000 Subject: [PATCH 558/991] Rename a bit --- compiler/rustc_middle/src/ty/print/pretty.rs | 21 ++++++-------------- compiler/rustc_symbol_mangling/src/v0.rs | 9 ++++----- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f1e82e8816cf..34d85534d0ae 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -233,11 +233,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { self.print_def_path(def_id, args) } - fn in_binder( - &mut self, - value: &ty::Binder<'tcx, T>, - _mode: WrapBinderMode, - ) -> Result<(), PrintError> + fn print_in_binder(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError> where T: Print<'tcx, Self> + TypeFoldable>, { @@ -2391,15 +2387,11 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { Ok(()) } - fn in_binder( - &mut self, - value: &ty::Binder<'tcx, T>, - mode: WrapBinderMode, - ) -> Result<(), PrintError> + fn print_in_binder(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError> where T: Print<'tcx, Self> + TypeFoldable>, { - self.pretty_in_binder(value, mode) + self.pretty_print_in_binder(value) } fn wrap_binder Result<(), PrintError>>( @@ -2835,16 +2827,15 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { Ok((new_value, map)) } - pub fn pretty_in_binder( + pub fn pretty_print_in_binder( &mut self, value: &ty::Binder<'tcx, T>, - mode: WrapBinderMode, ) -> Result<(), fmt::Error> where T: Print<'tcx, Self> + TypeFoldable>, { let old_region_index = self.region_index; - let (new_value, _) = self.name_all_regions(value, mode)?; + let (new_value, _) = self.name_all_regions(value, WrapBinderMode::ForAll)?; new_value.print(self)?; self.region_index = old_region_index; self.binder_depth -= 1; @@ -2920,7 +2911,7 @@ where T: Print<'tcx, P> + TypeFoldable>, { fn print(&self, cx: &mut P) -> Result<(), PrintError> { - cx.in_binder(self, WrapBinderMode::ForAll) + cx.print_in_binder(self) } } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 5f56e3d21455..a11f6f0df1c5 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -12,7 +12,7 @@ use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_middle::bug; use rustc_middle::ty::layout::IntegerExt; -use rustc_middle::ty::print::{Print, PrintError, Printer, WrapBinderMode}; +use rustc_middle::ty::print::{Print, PrintError, Printer}; use rustc_middle::ty::{ self, FloatTy, GenericArg, GenericArgKind, Instance, IntTy, ReifyReason, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, UintTy, @@ -169,10 +169,9 @@ impl<'tcx> SymbolMangler<'tcx> { Ok(()) } - fn in_binder( + fn wrap_binder( &mut self, value: &ty::Binder<'tcx, T>, - _mode: WrapBinderMode, print_value: impl FnOnce(&mut Self, &T) -> Result<(), PrintError>, ) -> Result<(), PrintError> where @@ -472,7 +471,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ty::FnPtr(sig_tys, hdr) => { let sig = sig_tys.with(hdr); self.push("F"); - self.in_binder(&sig, WrapBinderMode::ForAll, |cx, sig| { + self.wrap_binder(&sig, |cx, sig| { if sig.safety.is_unsafe() { cx.push("U"); } @@ -555,7 +554,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { // [ [{}]] [{}] // Since any predicates after the first one shouldn't change the binders, // just put them all in the binders of the first. - self.in_binder(&predicates[0], WrapBinderMode::ForAll, |cx, _| { + self.wrap_binder(&predicates[0], |cx, _| { for predicate in predicates.iter() { // It would be nice to be able to validate bound vars here, but // projections can actually include bound vars from super traits From e213f4beeabbb2604565a8e9324f66c5c72780c6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Mar 2025 04:09:43 +0000 Subject: [PATCH 559/991] Improve error message for AsyncFn trait failure for RPIT --- .../traits/fulfillment_errors.rs | 115 ++++++++++-------- .../src/error_reporting/traits/suggestions.rs | 5 +- .../src/traits/select/confirmation.rs | 4 +- .../async-closures/kind-due-to-rpit.rs | 14 +++ .../async-closures/kind-due-to-rpit.stderr | 17 +++ 5 files changed, 101 insertions(+), 54 deletions(-) create mode 100644 tests/ui/async-await/async-closures/kind-due-to-rpit.rs create mode 100644 tests/ui/async-await/async-closures/kind-due-to-rpit.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d270b4cf96ba..389e8e7994dc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -829,7 +829,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let ty::Closure(closure_def_id, _) | ty::CoroutineClosure(closure_def_id, _) = *typeck_results.node_type(arg_hir_id).kind() { - // Otherwise, extract the closure kind from the obligation. + // Otherwise, extract the closure kind from the obligation, + // but only if we actually have an argument to deduce the + // closure type from... let mut err = self.report_closure_error( &obligation, closure_def_id, @@ -844,63 +846,72 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let self_ty = trait_pred.self_ty().skip_binder(); - if let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) { - let (closure_def_id, found_args, by_ref_captures) = match *self_ty.kind() { - ty::Closure(def_id, args) => { - (def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), None) - } - ty::CoroutineClosure(def_id, args) => ( - def_id, - args.as_coroutine_closure() - .coroutine_closure_sig() - .map_bound(|sig| sig.tupled_inputs_ty), - Some(args.as_coroutine_closure().coroutine_captures_by_ref_ty()), - ), - _ => return None, + let (expected_kind, trait_prefix) = + if let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) { + (expected_kind, "") + } else if let Some(expected_kind) = + self.tcx.async_fn_trait_kind_from_def_id(trait_pred.def_id()) + { + (expected_kind, "Async") + } else { + return None; }; - let expected_args = - trait_pred.map_bound(|trait_pred| trait_pred.trait_ref.args.type_at(1)); - - // Verify that the arguments are compatible. If the signature is - // mismatched, then we have a totally different error to report. - if self.enter_forall(found_args, |found_args| { - self.enter_forall(expected_args, |expected_args| { - !self.can_eq(obligation.param_env, expected_args, found_args) - }) - }) { - return None; + let (closure_def_id, found_args, by_ref_captures) = match *self_ty.kind() { + ty::Closure(def_id, args) => { + (def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), None) } + ty::CoroutineClosure(def_id, args) => ( + def_id, + args.as_coroutine_closure() + .coroutine_closure_sig() + .map_bound(|sig| sig.tupled_inputs_ty), + Some(args.as_coroutine_closure().coroutine_captures_by_ref_ty()), + ), + _ => return None, + }; - if let Some(found_kind) = self.closure_kind(self_ty) - && !found_kind.extends(expected_kind) - { - let mut err = self.report_closure_error( - &obligation, - closure_def_id, - found_kind, - expected_kind, - "", - ); - self.note_obligation_cause(&mut err, &obligation); - return Some(err.emit()); - } + let expected_args = trait_pred.map_bound(|trait_pred| trait_pred.trait_ref.args.type_at(1)); - // If the closure has captures, then perhaps the reason that the trait - // is unimplemented is because async closures don't implement `Fn`/`FnMut` - // if they have captures. - if let Some(by_ref_captures) = by_ref_captures - && let ty::FnPtr(sig_tys, _) = by_ref_captures.kind() - && !sig_tys.skip_binder().output().is_unit() - { - let mut err = self.dcx().create_err(AsyncClosureNotFn { - span: self.tcx.def_span(closure_def_id), - kind: expected_kind.as_str(), - }); - self.note_obligation_cause(&mut err, &obligation); - return Some(err.emit()); - } + // Verify that the arguments are compatible. If the signature is + // mismatched, then we have a totally different error to report. + if self.enter_forall(found_args, |found_args| { + self.enter_forall(expected_args, |expected_args| { + !self.can_eq(obligation.param_env, expected_args, found_args) + }) + }) { + return None; } + + if let Some(found_kind) = self.closure_kind(self_ty) + && !found_kind.extends(expected_kind) + { + let mut err = self.report_closure_error( + &obligation, + closure_def_id, + found_kind, + expected_kind, + trait_prefix, + ); + self.note_obligation_cause(&mut err, &obligation); + return Some(err.emit()); + } + + // If the closure has captures, then perhaps the reason that the trait + // is unimplemented is because async closures don't implement `Fn`/`FnMut` + // if they have captures. + if let Some(by_ref_captures) = by_ref_captures + && let ty::FnPtr(sig_tys, _) = by_ref_captures.kind() + && !sig_tys.skip_binder().output().is_unit() + { + let mut err = self.dcx().create_err(AsyncClosureNotFn { + span: self.tcx.def_span(closure_def_id), + kind: expected_kind.as_str(), + }); + self.note_obligation_cause(&mut err, &obligation); + return Some(err.emit()); + } + None } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index b85c18c53121..bbf46fff71b8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3191,7 +3191,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { false }; - if !is_upvar_tys_infer_tuple { + let is_builtin_async_fn_trait = + tcx.async_fn_trait_kind_from_def_id(data.parent_trait_pred.def_id()).is_some(); + + if !is_upvar_tys_infer_tuple && !is_builtin_async_fn_trait { let ty_str = tcx.short_string(ty, err.long_ty_path()); let msg = format!("required because it appears within the type `{ty_str}`"); match ty.kind() { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a58317dd56d2..4ed27e406d20 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -984,8 +984,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Err(SelectionError::Unimplemented); } } else { - nested.push(obligation.with( + nested.push(Obligation::new( self.tcx(), + obligation.derived_cause(ObligationCauseCode::BuiltinDerived), + obligation.param_env, ty::TraitRef::new( self.tcx(), self.tcx().require_lang_item( diff --git a/tests/ui/async-await/async-closures/kind-due-to-rpit.rs b/tests/ui/async-await/async-closures/kind-due-to-rpit.rs new file mode 100644 index 000000000000..ad19d93b93a3 --- /dev/null +++ b/tests/ui/async-await/async-closures/kind-due-to-rpit.rs @@ -0,0 +1,14 @@ +//@ edition: 2024 + +// Make sure the error message is understandable when an `AsyncFn` goal is not satisfied +// (due to closure kind), and that goal originates from an RPIT. + +fn repro(foo: impl Into) -> impl AsyncFn() { + let inner_fn = async move || { + //~^ ERROR expected a closure that implements the `AsyncFn` trait + let _ = foo.into(); + }; + inner_fn +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/kind-due-to-rpit.stderr b/tests/ui/async-await/async-closures/kind-due-to-rpit.stderr new file mode 100644 index 000000000000..982cc50e14f9 --- /dev/null +++ b/tests/ui/async-await/async-closures/kind-due-to-rpit.stderr @@ -0,0 +1,17 @@ +error[E0525]: expected a closure that implements the `AsyncFn` trait, but this closure only implements `AsyncFnOnce` + --> $DIR/kind-due-to-rpit.rs:7:20 + | +LL | fn repro(foo: impl Into) -> impl AsyncFn() { + | -------------- the requirement to implement `AsyncFn` derives from here +LL | let inner_fn = async move || { + | ^^^^^^^^^^^^^ this closure implements `AsyncFnOnce`, not `AsyncFn` +LL | +LL | let _ = foo.into(); + | --- closure is `AsyncFnOnce` because it moves the variable `foo` out of its environment +LL | }; +LL | inner_fn + | -------- return type was inferred to be `{async closure@$DIR/kind-due-to-rpit.rs:7:20: 7:33}` here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0525`. From 0ad48b47e65b414c5a47c0955e0ec582c01a61ad Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Mar 2025 05:14:52 +0000 Subject: [PATCH 560/991] Do not recover missing lifetime with random in-scope lifetime --- .../rustc_resolve/src/late/diagnostics.rs | 6 --- tests/ui/async-await/issues/issue-63388-2.rs | 1 - .../async-await/issues/issue-63388-2.stderr | 14 +------ .../in-trait/opaque-and-lifetime-mismatch.rs | 2 - .../opaque-and-lifetime-mismatch.stderr | 42 ++++--------------- .../opaque-used-in-extraneous-argument.stderr | 2 +- .../precise-capturing/bad-lifetimes.rs | 1 - .../precise-capturing/bad-lifetimes.stderr | 12 ++---- tests/ui/issues/issue-13497.rs | 1 - tests/ui/issues/issue-13497.stderr | 14 +------ tests/ui/lifetimes/issue-26638.rs | 1 - tests/ui/lifetimes/issue-26638.stderr | 17 ++------ .../do-not-ice-on-invalid-lifetime.rs | 2 +- .../do-not-ice-on-invalid-lifetime.stderr | 13 +----- .../impl-trait-missing-lifetime-gated.rs | 2 - .../impl-trait-missing-lifetime-gated.stderr | 40 ++++++------------ .../impl-trait-missing-lifetime.rs | 2 - .../impl-trait-missing-lifetime.stderr | 18 +------- tests/ui/suggestions/missing-lt-for-hrtb.rs | 2 - .../ui/suggestions/missing-lt-for-hrtb.stderr | 24 +---------- 20 files changed, 36 insertions(+), 180 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0e14e7671b17..42be92c0f8fe 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3515,12 +3515,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } } - - // Record as using the suggested resolution. - let (_, (_, res)) = in_scope_lifetimes[0]; - for < in &lifetime_refs { - self.r.lifetimes_res_map.insert(lt.id, res); - } } _ => { let lifetime_spans: Vec<_> = diff --git a/tests/ui/async-await/issues/issue-63388-2.rs b/tests/ui/async-await/issues/issue-63388-2.rs index 8bb5cfa4a594..d9dc602bd1c6 100644 --- a/tests/ui/async-await/issues/issue-63388-2.rs +++ b/tests/ui/async-await/issues/issue-63388-2.rs @@ -12,7 +12,6 @@ impl Xyz { ) -> &dyn Foo //~ ERROR missing lifetime specifier { foo - //~^ ERROR explicit lifetime required in the type of `foo` [E0621] } } diff --git a/tests/ui/async-await/issues/issue-63388-2.stderr b/tests/ui/async-await/issues/issue-63388-2.stderr index 7e3c0a1227de..45843bc72cd8 100644 --- a/tests/ui/async-await/issues/issue-63388-2.stderr +++ b/tests/ui/async-await/issues/issue-63388-2.stderr @@ -12,16 +12,6 @@ help: consider using the `'a` lifetime LL | ) -> &'a dyn Foo | ++ -error[E0621]: explicit lifetime required in the type of `foo` - --> $DIR/issue-63388-2.rs:14:9 - | -LL | foo: &dyn Foo, bar: &'a dyn Foo - | -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)` -... -LL | foo - | ^^^ lifetime `'a` required +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0106, E0621. -For more information about an error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs index 21e2fda1c3af..b9b551c1b23d 100644 --- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs +++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs @@ -8,8 +8,6 @@ trait Foo { impl Foo for () { fn bar() -> i32 { - //~^ ERROR method `bar` has an incompatible type for trait - //~| ERROR method `bar` has an incompatible return type for trait 0 } } diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr index d575fedbb58d..24896151bedb 100644 --- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr @@ -11,7 +11,7 @@ LL | fn bar() -> Wrapper<'static, impl Sized>; | ++++++++ error[E0106]: missing lifetime specifier - --> $DIR/opaque-and-lifetime-mismatch.rs:18:24 + --> $DIR/opaque-and-lifetime-mismatch.rs:16:24 | LL | fn foo() -> Wrapper; | ^ expected named lifetime parameter @@ -23,7 +23,7 @@ LL | fn foo() -> Wrapper<'static, impl Sized>; | ++++++++ error[E0106]: missing lifetime specifier - --> $DIR/opaque-and-lifetime-mismatch.rs:24:24 + --> $DIR/opaque-and-lifetime-mismatch.rs:22:24 | LL | fn foo() -> Wrapper { | ^ expected named lifetime parameter @@ -49,7 +49,7 @@ LL | struct Wrapper<'rom>(&'rom ()); | ^^^^^^^ error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/opaque-and-lifetime-mismatch.rs:18:17 + --> $DIR/opaque-and-lifetime-mismatch.rs:16:17 | LL | fn foo() -> Wrapper; | ^^^^^^^ ---------- help: remove the unnecessary generic argument @@ -62,36 +62,8 @@ note: struct defined here, with 0 generic parameters LL | struct Wrapper<'rom>(&'rom ()); | ^^^^^^^ -error[E0053]: method `bar` has an incompatible return type for trait - --> $DIR/opaque-and-lifetime-mismatch.rs:10:17 - | -LL | fn bar() -> i32 { - | ^^^ - | | - | expected `Wrapper<'static>`, found `i32` - | return type in trait - -error[E0053]: method `bar` has an incompatible type for trait - --> $DIR/opaque-and-lifetime-mismatch.rs:10:17 - | -LL | fn bar() -> i32 { - | ^^^ expected `Wrapper<'static>`, found `i32` - | -note: type in trait - --> $DIR/opaque-and-lifetime-mismatch.rs:4:17 - | -LL | fn bar() -> Wrapper; - | ^^^^^^^^^^^^^^^^^^^ - = note: expected signature `fn() -> Wrapper<'static>` - found signature `fn() -> i32` -help: change the output type to match the trait - | -LL - fn bar() -> i32 { -LL + fn bar() -> Wrapper<'static> { - | - error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/opaque-and-lifetime-mismatch.rs:24:17 + --> $DIR/opaque-and-lifetime-mismatch.rs:22:17 | LL | fn foo() -> Wrapper { | ^^^^^^^ ---------- help: remove the unnecessary generic argument @@ -104,7 +76,7 @@ note: struct defined here, with 0 generic parameters LL | struct Wrapper<'rom>(&'rom ()); | ^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0053, E0106, E0107. -For more information about an error, try `rustc --explain E0053`. +Some errors have detailed explanations: E0106, E0107. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr index 4198095db65f..73e7890f91fd 100644 --- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr +++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr @@ -75,7 +75,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/opaque-used-in-extraneous-argument.rs:20:5 | LL | open_parent(&old_path) - | ^^^^^^^^^^^ --------- unexpected argument of type `&impl Fn<{type error}> + FnOnce<{type error}, Output = {type error}> + 'static` + | ^^^^^^^^^^^ --------- unexpected argument of type `&impl Fn<{type error}> + FnOnce<{type error}, Output = {type error}> + '_` | note: function defined here --> $DIR/opaque-used-in-extraneous-argument.rs:12:4 diff --git a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs index 161fe23c8999..8e30973cd3a1 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs +++ b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs @@ -1,6 +1,5 @@ fn no_elided_lt() -> impl Sized + use<'_> {} //~^ ERROR missing lifetime specifier -//~| ERROR expected lifetime parameter in `use<...>` precise captures list, found `'_` fn static_lt() -> impl Sized + use<'static> {} //~^ ERROR expected lifetime parameter in `use<...>` precise captures list, found `'static` diff --git a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr index c8dac3a69cd9..98f629f52cf3 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr +++ b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr @@ -12,26 +12,20 @@ LL + fn no_elided_lt() -> impl Sized + use<'static> {} | error[E0261]: use of undeclared lifetime name `'missing` - --> $DIR/bad-lifetimes.rs:8:37 + --> $DIR/bad-lifetimes.rs:7:37 | LL | fn missing_lt() -> impl Sized + use<'missing> {} | - ^^^^^^^^ undeclared lifetime | | | help: consider introducing lifetime `'missing` here: `<'missing>` -error: expected lifetime parameter in `use<...>` precise captures list, found `'_` - --> $DIR/bad-lifetimes.rs:1:39 - | -LL | fn no_elided_lt() -> impl Sized + use<'_> {} - | ^^ - error: expected lifetime parameter in `use<...>` precise captures list, found `'static` - --> $DIR/bad-lifetimes.rs:5:36 + --> $DIR/bad-lifetimes.rs:4:36 | LL | fn static_lt() -> impl Sized + use<'static> {} | ^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0106, E0261. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/issues/issue-13497.rs b/tests/ui/issues/issue-13497.rs index 7f786a54b9f7..4b2795aa841e 100644 --- a/tests/ui/issues/issue-13497.rs +++ b/tests/ui/issues/issue-13497.rs @@ -3,7 +3,6 @@ fn read_lines_borrowed1() -> Vec< > { let rawLines: Vec = vec!["foo ".to_string(), " bar".to_string()]; rawLines.iter().map(|l| l.trim()).collect() - //~^ ERROR: cannot return value referencing } fn main() {} diff --git a/tests/ui/issues/issue-13497.stderr b/tests/ui/issues/issue-13497.stderr index 8016b55d6aad..ee111f1d262e 100644 --- a/tests/ui/issues/issue-13497.stderr +++ b/tests/ui/issues/issue-13497.stderr @@ -15,16 +15,6 @@ LL - &str LL + String | -error[E0515]: cannot return value referencing local variable `rawLines` - --> $DIR/issue-13497.rs:5:5 - | -LL | rawLines.iter().map(|l| l.trim()).collect() - | --------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | returns a value referencing data owned by the current function - | `rawLines` is borrowed here +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0106, E0515. -For more information about an error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/lifetimes/issue-26638.rs b/tests/ui/lifetimes/issue-26638.rs index 11c730165f22..e73cf21bd6cf 100644 --- a/tests/ui/lifetimes/issue-26638.rs +++ b/tests/ui/lifetimes/issue-26638.rs @@ -3,7 +3,6 @@ fn parse_type(iter: Box+'static>) -> &str { iter.next() fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } //~^ ERROR missing lifetime specifier [E0106] -//~| ERROR mismatched types //~| ERROR function takes 1 argument but 0 arguments were supplied fn parse_type_3() -> &str { unimplemented!() } diff --git a/tests/ui/lifetimes/issue-26638.stderr b/tests/ui/lifetimes/issue-26638.stderr index bdf911367653..74a1676f6848 100644 --- a/tests/ui/lifetimes/issue-26638.stderr +++ b/tests/ui/lifetimes/issue-26638.stderr @@ -32,7 +32,7 @@ LL + fn parse_type_2(iter: fn(&u8)->&u8) -> String { iter() } | error[E0106]: missing lifetime specifier - --> $DIR/issue-26638.rs:9:22 + --> $DIR/issue-26638.rs:8:22 | LL | fn parse_type_3() -> &str { unimplemented!() } | ^ expected named lifetime parameter @@ -59,18 +59,7 @@ help: provide the argument LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter(/* &u8 */) } | +++++++++ -error[E0308]: mismatched types - --> $DIR/issue-26638.rs:4:47 - | -LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } - | ---- ^^^^^^ expected `&str`, found `&u8` - | | - | expected `&'static str` because of return type - | - = note: expected reference `&'static str` - found reference `&u8` +error: aborting due to 4 previous errors -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0061, E0106, E0308. +Some errors have detailed explanations: E0061, E0106. For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs index 71d90ddd935f..ba99b03539cf 100644 --- a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs +++ b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs @@ -1,5 +1,5 @@ #![feature(default_field_values)] -struct A<'a> { //~ ERROR lifetime parameter `'a` is never used +struct A<'a> { x: Vec
= Vec::new(), //~ ERROR missing lifetime specifier } diff --git a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr index 20b9afe80cdc..7100efc695ce 100644 --- a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr +++ b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr @@ -9,15 +9,6 @@ help: consider using the `'a` lifetime LL | x: Vec> = Vec::new(), | ++++ -error[E0392]: lifetime parameter `'a` is never used - --> $DIR/do-not-ice-on-invalid-lifetime.rs:2:10 - | -LL | struct A<'a> { - | ^^ unused lifetime parameter - | - = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0106, E0392. -For more information about an error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs index daec66709b65..443a7e3835e3 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs +++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs @@ -18,7 +18,6 @@ mod elided { // But that lifetime does not participate in resolution. async fn i(mut x: impl Iterator) -> Option<&()> { x.next() } //~^ ERROR missing lifetime specifier - //~| ERROR lifetime may not live long enough } mod underscore { @@ -37,7 +36,6 @@ mod underscore { // But that lifetime does not participate in resolution. async fn i(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } //~^ ERROR missing lifetime specifier - //~| ERROR lifetime may not live long enough } mod alone_in_path { diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr index 204209179adf..24013c85c875 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr +++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr @@ -41,7 +41,7 @@ LL + async fn i(mut x: impl Iterator) -> Option<()> { x.next() } | error[E0106]: missing lifetime specifier - --> $DIR/impl-trait-missing-lifetime-gated.rs:28:58 + --> $DIR/impl-trait-missing-lifetime-gated.rs:27:58 | LL | fn g(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } | ^^ expected named lifetime parameter @@ -64,7 +64,7 @@ LL + fn g(mut x: impl Iterator) -> Option<()> { x.next() } | error[E0106]: missing lifetime specifier - --> $DIR/impl-trait-missing-lifetime-gated.rs:38:64 + --> $DIR/impl-trait-missing-lifetime-gated.rs:37:64 | LL | async fn i(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } | ^^ expected named lifetime parameter @@ -87,7 +87,7 @@ LL + async fn i(mut x: impl Iterator) -> Option<()> { x.next( | error[E0106]: missing lifetime specifier - --> $DIR/impl-trait-missing-lifetime-gated.rs:49:37 + --> $DIR/impl-trait-missing-lifetime-gated.rs:47:37 | LL | fn g(mut x: impl Foo) -> Option<&()> { x.next() } | ^ expected named lifetime parameter @@ -108,7 +108,7 @@ LL + fn g(mut x: impl Foo) -> Option<()> { x.next() } | error[E0106]: missing lifetime specifier - --> $DIR/impl-trait-missing-lifetime-gated.rs:60:41 + --> $DIR/impl-trait-missing-lifetime-gated.rs:58:41 | LL | fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() } | ^ expected named lifetime parameter @@ -129,7 +129,7 @@ LL + fn g(mut x: impl Foo<()>) -> Option<()> { x.next() } | warning: elided lifetime has a name - --> $DIR/impl-trait-missing-lifetime-gated.rs:66:57 + --> $DIR/impl-trait-missing-lifetime-gated.rs:64:57 | LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) { | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` @@ -162,16 +162,8 @@ help: consider introducing a named lifetime parameter LL | fn g<'a>(mut x: impl Iterator) -> Option<&()> { x.next() } | ++++ ++ -error: lifetime may not live long enough - --> $DIR/impl-trait-missing-lifetime-gated.rs:19:67 - | -LL | async fn i(mut x: impl Iterator) -> Option<&()> { x.next() } - | ----------------------------------------------------------- ^^^^^^^^ returning this value requires that `'1` must outlive `'static` - | | - | return type `impl Future>` contains a lifetime `'1` - error[E0658]: anonymous lifetimes in `impl Trait` are unstable - --> $DIR/impl-trait-missing-lifetime-gated.rs:25:35 + --> $DIR/impl-trait-missing-lifetime-gated.rs:24:35 | LL | fn f(_: impl Iterator) {} | ^^ expected named lifetime parameter @@ -185,7 +177,7 @@ LL + fn f<'a>(_: impl Iterator) {} | error[E0658]: anonymous lifetimes in `impl Trait` are unstable - --> $DIR/impl-trait-missing-lifetime-gated.rs:28:39 + --> $DIR/impl-trait-missing-lifetime-gated.rs:27:39 | LL | fn g(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } | ^^ expected named lifetime parameter @@ -198,16 +190,8 @@ LL - fn g(mut x: impl Iterator) -> Option<&'_ ()> { x.next() LL + fn g<'a>(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } | -error: lifetime may not live long enough - --> $DIR/impl-trait-missing-lifetime-gated.rs:38:73 - | -LL | async fn i(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } - | ----------------------------------------------------------------- ^^^^^^^^ returning this value requires that `'1` must outlive `'static` - | | - | return type `impl Future>` contains a lifetime `'1` - error[E0658]: anonymous lifetimes in `impl Trait` are unstable - --> $DIR/impl-trait-missing-lifetime-gated.rs:46:18 + --> $DIR/impl-trait-missing-lifetime-gated.rs:44:18 | LL | fn f(_: impl Foo) {} | ^^^ expected named lifetime parameter @@ -220,7 +204,7 @@ LL | fn f<'a>(_: impl Foo<'a>) {} | ++++ ++++ error[E0658]: anonymous lifetimes in `impl Trait` are unstable - --> $DIR/impl-trait-missing-lifetime-gated.rs:49:22 + --> $DIR/impl-trait-missing-lifetime-gated.rs:47:22 | LL | fn g(mut x: impl Foo) -> Option<&()> { x.next() } | ^^^ expected named lifetime parameter @@ -233,7 +217,7 @@ LL | fn g<'a>(mut x: impl Foo<'a>) -> Option<&()> { x.next() } | ++++ ++++ error[E0658]: anonymous lifetimes in `impl Trait` are unstable - --> $DIR/impl-trait-missing-lifetime-gated.rs:57:22 + --> $DIR/impl-trait-missing-lifetime-gated.rs:55:22 | LL | fn f(_: impl Foo<()>) {} | ^ expected named lifetime parameter @@ -246,7 +230,7 @@ LL | fn f<'a>(_: impl Foo<'a, ()>) {} | ++++ +++ error[E0658]: anonymous lifetimes in `impl Trait` are unstable - --> $DIR/impl-trait-missing-lifetime-gated.rs:60:26 + --> $DIR/impl-trait-missing-lifetime-gated.rs:58:26 | LL | fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() } | ^ expected named lifetime parameter @@ -258,7 +242,7 @@ help: consider introducing a named lifetime parameter LL | fn g<'a>(mut x: impl Foo<'a, ()>) -> Option<&()> { x.next() } | ++++ +++ -error: aborting due to 16 previous errors; 1 warning emitted +error: aborting due to 14 previous errors; 1 warning emitted Some errors have detailed explanations: E0106, E0658. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime.rs b/tests/ui/suggestions/impl-trait-missing-lifetime.rs index 12dc0e8216b7..27f03431d098 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime.rs +++ b/tests/ui/suggestions/impl-trait-missing-lifetime.rs @@ -8,7 +8,6 @@ fn f(_: impl Iterator) {} // But that lifetime does not participate in resolution. fn g(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } //~^ ERROR missing lifetime specifier -//~| ERROR lifetime may not live long enough // This is understood as `fn foo<'_1>(_: impl Iterator) {}`. async fn h(_: impl Iterator) {} @@ -16,6 +15,5 @@ async fn h(_: impl Iterator) {} // But that lifetime does not participate in resolution. async fn i(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } //~^ ERROR missing lifetime specifier -//~| ERROR lifetime may not live long enough fn main() {} diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr index dfbc883680b2..c09c575c147f 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr +++ b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr @@ -22,7 +22,7 @@ LL + fn g(mut x: impl Iterator) -> Option<()> { x.next() } | error[E0106]: missing lifetime specifier - --> $DIR/impl-trait-missing-lifetime.rs:17:60 + --> $DIR/impl-trait-missing-lifetime.rs:16:60 | LL | async fn i(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } | ^^ expected named lifetime parameter @@ -44,20 +44,6 @@ LL - async fn i(mut x: impl Iterator) -> Option<&'_ ()> { x.next( LL + async fn i(mut x: impl Iterator) -> Option<()> { x.next() } | -error: lifetime may not live long enough - --> $DIR/impl-trait-missing-lifetime.rs:17:69 - | -LL | async fn i(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } - | ----------------------------------------------------------------- ^^^^^^^^ returning this value requires that `'1` must outlive `'static` - | | - | return type `impl Future>` contains a lifetime `'1` - -error: lifetime may not live long enough - --> $DIR/impl-trait-missing-lifetime.rs:9:63 - | -LL | fn g(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } - | ----- has type `x` ^^^^^^^^ returning this value requires that `'1` must outlive `'static` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/suggestions/missing-lt-for-hrtb.rs b/tests/ui/suggestions/missing-lt-for-hrtb.rs index a48c5665d67a..04ea3d831c93 100644 --- a/tests/ui/suggestions/missing-lt-for-hrtb.rs +++ b/tests/ui/suggestions/missing-lt-for-hrtb.rs @@ -8,8 +8,6 @@ fn main() { let x = S(&|x| { println!("hi"); x - //~^ ERROR lifetime may not live long enough - //~| ERROR lifetime may not live long enough }); x.0(&X(&())); } diff --git a/tests/ui/suggestions/missing-lt-for-hrtb.stderr b/tests/ui/suggestions/missing-lt-for-hrtb.stderr index e8c536ac47d5..fa515644431a 100644 --- a/tests/ui/suggestions/missing-lt-for-hrtb.stderr +++ b/tests/ui/suggestions/missing-lt-for-hrtb.stderr @@ -31,28 +31,6 @@ help: consider using one of the available lifetimes here LL | struct V<'a>(&'a dyn for<'b> Fn(&X) -> &'lifetime X<'lifetime>); | +++++++++ +++++++++++ -error: lifetime may not live long enough - --> $DIR/missing-lt-for-hrtb.rs:10:9 - | -LL | let x = S(&|x| { - | -- return type of closure is &'2 X<'_> - | | - | has type `&'1 X<'_>` -LL | println!("hi"); -LL | x - | ^ returning this value requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/missing-lt-for-hrtb.rs:10:9 - | -LL | let x = S(&|x| { - | -- return type of closure is &X<'4> - | | - | has type `&X<'3>` -LL | println!("hi"); -LL | x - | ^ returning this value requires that `'3` must outlive `'4` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0106`. From 969868ba30b41af0cece305cd68d133369b492a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 3 Mar 2025 08:38:14 +0200 Subject: [PATCH 561/991] Preparing for merge from rust-lang/rust --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 6cd39fabeeee..e24e08d0687d 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -e0be1a02626abef2878cb7f4aaef7ae409477112 +daf59857d6d2b87af4b846316bf1561a6083ed51 From 24c480e350a1307e3b8a4b53a5bdf708b94905d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 3 Mar 2025 08:43:57 +0200 Subject: [PATCH 562/991] Bump rustc crates --- src/tools/rust-analyzer/Cargo.lock | 28 ++++++++++++++-------------- src/tools/rust-analyzer/Cargo.toml | 12 ++++++------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 57aafcb1ec7b..c57953ba6547 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1504,9 +1504,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_abi" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3829c3355d1681ffeaf1450ec71edcdace6820fe2e86469d8fc1ad45e2c96460" +checksum = "4b42cccfff8091a4c3397736518774dbad619e82f8def6f70d8e46dbbe396007" dependencies = [ "bitflags 2.7.0", "ra-ap-rustc_hashes", @@ -1516,18 +1516,18 @@ dependencies = [ [[package]] name = "ra-ap-rustc_hashes" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bd4d6d4c434bec08e02370a4f64a4985312097215a62e82d0f757f3a98e502e" +checksum = "46d8bd34ed6552c8cac1764106ef5adbeef3e5c7700e0ceb4c83a47a631894fe" dependencies = [ "rustc-stable-hash", ] [[package]] name = "ra-ap-rustc_index" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad6fc4bd7522e31096e2de5b0351144fe0684b608791ee26c842bf2da1b19ae" +checksum = "93799e4dccbbd47f8b66bc0aa42effc1b7077aaee09d8a40b86b8d659b80c7b7" dependencies = [ "ra-ap-rustc_index_macros", "smallvec", @@ -1535,9 +1535,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index_macros" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfb234e1f84b92be45276c3025bee18789e9bc95bec8789bec961e78edb01c52" +checksum = "30baa5d00f94ba437a9dcaf7ae074ebe4f367bb05a4c2835e0aa2e7af3463aac" dependencies = [ "proc-macro2", "quote", @@ -1546,9 +1546,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_lexer" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3a40bd11dc43d1cb110e730b80620cf8102f4cca8920a02b65954da0ed931f" +checksum = "3004d1d1b50afe3e1f9cdd428a282da7ffbf5f26dd8bf04af0d651d44e4873d8" dependencies = [ "memchr", "unicode-properties", @@ -1557,9 +1557,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_parse_format" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5feb877478994cb4c0c0c7a5116a352eefc0634aefc8636feb00a893fa5b7135" +checksum = "cb57e5124a64aaaf92c06130fbc1b8e1d547b5a2a96081f1f848e31c211df5d2" dependencies = [ "ra-ap-rustc_index", "ra-ap-rustc_lexer", @@ -1567,9 +1567,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76774d35934d464c4115908cde16f76a4f7e540fe1eea6b79336c556e37bdd3" +checksum = "e427c3d30e4bdff28abd6b0ef3e6f4dfab44acd9468a4954eeff8717d8df8819" dependencies = [ "ra-ap-rustc_index", "rustc-hash 2.0.0", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 19ae35142fa2..1132acb64741 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -85,12 +85,12 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } edition = { path = "./crates/edition", version = "0.0.0" } -ra-ap-rustc_hashes = { version = "0.97", default-features = false } -ra-ap-rustc_lexer = { version = "0.97", default-features = false } -ra-ap-rustc_parse_format = { version = "0.97", default-features = false } -ra-ap-rustc_index = { version = "0.97", default-features = false } -ra-ap-rustc_abi = { version = "0.97", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.97", default-features = false } +ra-ap-rustc_hashes = { version = "0.98", default-features = false } +ra-ap-rustc_lexer = { version = "0.98", default-features = false } +ra-ap-rustc_parse_format = { version = "0.98", default-features = false } +ra-ap-rustc_index = { version = "0.98", default-features = false } +ra-ap-rustc_abi = { version = "0.98", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.98", default-features = false } # local crates that aren't published to crates.io. These should not have versions. From 5afd12239af03b4944429a2f5be10357f0044e89 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 2 Mar 2025 17:49:15 +1100 Subject: [PATCH 563/991] Remove leading underscores from parameter names in `Sharded` With the removal of `cfg(parallel_compiler)`, these parameters are never considered unused. --- compiler/rustc_data_structures/src/sharded.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index 5a53f8af5f8c..e6be9c256f01 100644 --- a/compiler/rustc_data_structures/src/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs @@ -43,10 +43,10 @@ impl Sharded { /// The shard is selected by hashing `val` with `FxHasher`. #[inline] - pub fn get_shard_by_value(&self, _val: &K) -> &Lock { + pub fn get_shard_by_value(&self, val: &K) -> &Lock { match self { Self::Single(single) => single, - Self::Shards(..) => self.get_shard_by_hash(make_hash(_val)), + Self::Shards(..) => self.get_shard_by_hash(make_hash(val)), } } @@ -56,12 +56,12 @@ impl Sharded { } #[inline] - pub fn get_shard_by_index(&self, _i: usize) -> &Lock { + pub fn get_shard_by_index(&self, i: usize) -> &Lock { match self { Self::Single(single) => single, Self::Shards(shards) => { // SAFETY: The index gets ANDed with the shard mask, ensuring it is always inbounds. - unsafe { &shards.get_unchecked(_i & (SHARDS - 1)).0 } + unsafe { &shards.get_unchecked(i & (SHARDS - 1)).0 } } } } @@ -69,7 +69,7 @@ impl Sharded { /// The shard is selected by hashing `val` with `FxHasher`. #[inline] #[track_caller] - pub fn lock_shard_by_value(&self, _val: &K) -> LockGuard<'_, T> { + pub fn lock_shard_by_value(&self, val: &K) -> LockGuard<'_, T> { match self { Self::Single(single) => { // Synchronization is disabled so use the `lock_assume_no_sync` method optimized @@ -79,7 +79,7 @@ impl Sharded { // `might_be_dyn_thread_safe` was also false. unsafe { single.lock_assume(Mode::NoSync) } } - Self::Shards(..) => self.lock_shard_by_hash(make_hash(_val)), + Self::Shards(..) => self.lock_shard_by_hash(make_hash(val)), } } @@ -91,7 +91,7 @@ impl Sharded { #[inline] #[track_caller] - pub fn lock_shard_by_index(&self, _i: usize) -> LockGuard<'_, T> { + pub fn lock_shard_by_index(&self, i: usize) -> LockGuard<'_, T> { match self { Self::Single(single) => { // Synchronization is disabled so use the `lock_assume_no_sync` method optimized @@ -109,7 +109,7 @@ impl Sharded { // always inbounds. // SAFETY (lock_assume_sync): We know `is_dyn_thread_safe` was true when creating // the lock thus `might_be_dyn_thread_safe` was also true. - unsafe { shards.get_unchecked(_i & (SHARDS - 1)).0.lock_assume(Mode::Sync) } + unsafe { shards.get_unchecked(i & (SHARDS - 1)).0.lock_assume(Mode::Sync) } } } } From 0aacfe9d91d5001872bb482ea6973827cad20220 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 3 Mar 2025 08:15:03 +0100 Subject: [PATCH 564/991] interpret/provenance_map: consistently use range_is_empty --- .../src/mir/interpret/allocation.rs | 2 +- .../interpret/allocation/provenance_map.rs | 42 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 95bc9b71fe0a..e940e2952204 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -470,7 +470,7 @@ impl Allocation // Find the provenance. let (offset, _prov) = self .provenance - .range_get_ptrs(range, cx) + .range_ptrs_get(range, cx) .first() .copied() .expect("there must be provenance somewhere here"); diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index 82fb5f33b4c8..c9525df1f794 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -67,7 +67,7 @@ impl ProvenanceMap { } impl ProvenanceMap { - fn adjusted_range(range: AllocRange, cx: &impl HasDataLayout) -> Range { + fn adjusted_range_ptrs(range: AllocRange, cx: &impl HasDataLayout) -> Range { // We have to go back `pointer_size - 1` bytes, as that one would still overlap with // the beginning of this range. let adjusted_start = Size::from_bytes( @@ -79,26 +79,21 @@ impl ProvenanceMap { /// Returns all ptr-sized provenance in the given range. /// If the range has length 0, returns provenance that crosses the edge between `start-1` and /// `start`. - pub(super) fn range_get_ptrs( + pub(super) fn range_ptrs_get( &self, range: AllocRange, cx: &impl HasDataLayout, ) -> &[(Size, Prov)] { - self.ptrs.range(Self::adjusted_range(range, cx)) + self.ptrs.range(Self::adjusted_range_ptrs(range, cx)) } - /// `pm.range_get_ptrs_is_empty(r, cx)` == `pm.range_get_ptrs(r, cx).is_empty()`, but is - /// faster. - pub(super) fn range_get_ptrs_is_empty( - &self, - range: AllocRange, - cx: &impl HasDataLayout, - ) -> bool { - self.ptrs.range_is_empty(Self::adjusted_range(range, cx)) + /// `pm.range_ptrs_is_empty(r, cx)` == `pm.range_ptrs_get(r, cx).is_empty()`, but is faster. + pub(super) fn range_ptrs_is_empty(&self, range: AllocRange, cx: &impl HasDataLayout) -> bool { + self.ptrs.range_is_empty(Self::adjusted_range_ptrs(range, cx)) } /// Returns all byte-wise provenance in the given range. - fn range_get_bytes(&self, range: AllocRange) -> &[(Size, Prov)] { + fn range_bytes_get(&self, range: AllocRange) -> &[(Size, Prov)] { if let Some(bytes) = self.bytes.as_ref() { bytes.range(range.start..range.end()) } else { @@ -106,9 +101,14 @@ impl ProvenanceMap { } } + /// Same as `range_bytes_get(range).is_empty()`, but faster. + fn range_bytes_is_empty(&self, range: AllocRange) -> bool { + self.bytes.as_ref().is_none_or(|bytes| bytes.range_is_empty(range.start..range.end())) + } + /// Get the provenance of a single byte. pub fn get(&self, offset: Size, cx: &impl HasDataLayout) -> Option { - let prov = self.range_get_ptrs(alloc_range(offset, Size::from_bytes(1)), cx); + let prov = self.range_ptrs_get(alloc_range(offset, Size::from_bytes(1)), cx); debug_assert!(prov.len() <= 1); if let Some(entry) = prov.first() { // If it overlaps with this byte, it is on this byte. @@ -132,7 +132,7 @@ impl ProvenanceMap { /// limit access to provenance outside of the `Allocation` abstraction. /// pub fn range_empty(&self, range: AllocRange, cx: &impl HasDataLayout) -> bool { - self.range_get_ptrs_is_empty(range, cx) && self.range_get_bytes(range).is_empty() + self.range_ptrs_is_empty(range, cx) && self.range_bytes_is_empty(range) } /// Yields all the provenances stored in this map. @@ -164,14 +164,14 @@ impl ProvenanceMap { // provenance that overlaps with the given range. let (first, last) = { // Find all provenance overlapping the given range. - if self.range_get_ptrs_is_empty(range, cx) { + if self.range_ptrs_is_empty(range, cx) { // No provenance in this range, we are done. This is the common case. return Ok(()); } // This redoes some of the work of `range_get_ptrs_is_empty`, but this path is much // colder than the early return above, so it's worth it. - let provenance = self.range_get_ptrs(range, cx); + let provenance = self.range_ptrs_get(range, cx); ( provenance.first().unwrap().0, provenance.last().unwrap().0 + cx.data_layout().pointer_size, @@ -284,8 +284,8 @@ impl ProvenanceMap { // This includes the existing bytewise provenance in the range, and ptr provenance // that overlaps with the begin/end of the range. let mut dest_bytes_box = None; - let begin_overlap = self.range_get_ptrs(alloc_range(src.start, Size::ZERO), cx).first(); - let end_overlap = self.range_get_ptrs(alloc_range(src.end(), Size::ZERO), cx).first(); + let begin_overlap = self.range_ptrs_get(alloc_range(src.start, Size::ZERO), cx).first(); + let end_overlap = self.range_ptrs_get(alloc_range(src.end(), Size::ZERO), cx).first(); if !Prov::OFFSET_IS_ADDR { // There can't be any bytewise provenance, and we cannot split up the begin/end overlap. if let Some(entry) = begin_overlap { @@ -308,10 +308,10 @@ impl ProvenanceMap { } else { trace!("no start overlapping entry"); } + // Then the main part, bytewise provenance from `self.bytes`. - if let Some(all_bytes) = self.bytes.as_ref() { - bytes.extend(all_bytes.range(src.start..src.end())); - } + bytes.extend(self.range_bytes_get(src)); + // And finally possibly parts of a pointer at the end. if let Some(entry) = end_overlap { trace!("end overlapping entry: {entry:?}"); From e403654c8b49f7bf62e551c2dc5aaaca9ba71d76 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 2 Mar 2025 23:47:24 -0800 Subject: [PATCH 565/991] Simplify `::size_hint` The current version is wrong (cc 137919); let's see if we can get away with a loose but trivially-correct one. --- compiler/rustc_middle/src/mir/traversal.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 5950ac295af1..5fb3c648d5a2 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -108,7 +108,6 @@ pub struct Postorder<'a, 'tcx> { basic_blocks: &'a IndexSlice>, visited: DenseBitSet, visit_stack: Vec<(BasicBlock, Successors<'a>)>, - root_is_start_block: bool, /// A non-empty `extra` allows for a precise calculation of the successors. extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>, } @@ -123,7 +122,6 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { basic_blocks, visited: DenseBitSet::new_empty(basic_blocks.len()), visit_stack: Vec::new(), - root_is_start_block: root == START_BLOCK, extra, }; @@ -211,16 +209,13 @@ impl<'tcx> Iterator for Postorder<'_, 'tcx> { } fn size_hint(&self) -> (usize, Option) { - // All the blocks, minus the number of blocks we've visited. - let upper = self.basic_blocks.len() - self.visited.count(); - - let lower = if self.root_is_start_block { - // We will visit all remaining blocks exactly once. - upper - } else { - self.visit_stack.len() - }; + // These bounds are not at all tight, but that's fine. + // It's not worth a popcnt loop in `DenseBitSet` to improve the upper, + // and in mono-reachable we can't be precise anyway. + // Leaning on amortized growth is fine. + let lower = self.visit_stack.len(); + let upper = self.basic_blocks.len(); (lower, Some(upper)) } } From 9b78d48c112092ea0db5276d9ad6f447f0e1e30e Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Mon, 20 Jan 2025 11:30:13 +0100 Subject: [PATCH 566/991] After introducing the warning in 1.83, now also warn in deps This was left to only warn in the current crate to give users a chance to update their code. Now for 1.86 we also warn users depending on those crates. --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 97850a2afc11..3d63ea820530 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3782,7 +3782,7 @@ declare_lint! { Warn, "use of unsupported calling convention for function pointer", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, reference: "issue #130260 ", }; } From 2bf5cc93e6421fdc5cfd83912d152b6712aadb56 Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Mon, 20 Jan 2025 17:27:34 +0100 Subject: [PATCH 567/991] Bless UI tests --- tests/ui/abi/unsupported.aarch64.stderr | 110 ++++++++++++++++++ tests/ui/abi/unsupported.arm.stderr | 99 ++++++++++++++++ tests/ui/abi/unsupported.i686.stderr | 77 ++++++++++++ tests/ui/abi/unsupported.riscv32.stderr | 99 ++++++++++++++++ tests/ui/abi/unsupported.riscv64.stderr | 99 ++++++++++++++++ tests/ui/abi/unsupported.x64.stderr | 99 ++++++++++++++++ tests/ui/c-variadic/variadic-ffi-2.rs | 1 + tests/ui/c-variadic/variadic-ffi-2.stderr | 12 +- .../cmse-nonsecure-call/gate_test.stderr | 10 ++ .../feature-gate-abi_gpu_kernel.stderr | 11 ++ 10 files changed, 616 insertions(+), 1 deletion(-) diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 01f071f1f310..224d0e649017 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -206,3 +206,113 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} error: aborting due to 19 previous errors; 10 warnings emitted For more information about this error, try `rustc --explain E0570`. +Future incompatibility report: Future breakage diagnostic: +warning: the calling convention "ptx-kernel" is not supported on this target + --> $DIR/unsupported.rs:36:15 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "aapcs" is not supported on this target + --> $DIR/unsupported.rs:52:17 + | +LL | fn aapcs_ptr(f: extern "aapcs" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "msp430-interrupt" is not supported on this target + --> $DIR/unsupported.rs:74:18 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "avr-interrupt" is not supported on this target + --> $DIR/unsupported.rs:84:15 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "riscv-interrupt-m" is not supported on this target + --> $DIR/unsupported.rs:97:17 + | +LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "x86-interrupt" is not supported on this target + --> $DIR/unsupported.rs:119:15 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "thiscall" is not supported on this target + --> $DIR/unsupported.rs:142:20 + | +LL | fn thiscall_ptr(f: extern "thiscall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "stdcall" is not supported on this target + --> $DIR/unsupported.rs:168:19 + | +LL | fn stdcall_ptr(f: extern "stdcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target + --> $DIR/unsupported.rs:188:21 + | +LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target + --> $DIR/unsupported.rs:196:22 + | +LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index dfb4b573349b..c813b48ce3ab 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -185,3 +185,102 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} error: aborting due to 17 previous errors; 9 warnings emitted For more information about this error, try `rustc --explain E0570`. +Future incompatibility report: Future breakage diagnostic: +warning: the calling convention "ptx-kernel" is not supported on this target + --> $DIR/unsupported.rs:36:15 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "msp430-interrupt" is not supported on this target + --> $DIR/unsupported.rs:74:18 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "avr-interrupt" is not supported on this target + --> $DIR/unsupported.rs:84:15 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "riscv-interrupt-m" is not supported on this target + --> $DIR/unsupported.rs:97:17 + | +LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "x86-interrupt" is not supported on this target + --> $DIR/unsupported.rs:119:15 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "thiscall" is not supported on this target + --> $DIR/unsupported.rs:142:20 + | +LL | fn thiscall_ptr(f: extern "thiscall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "stdcall" is not supported on this target + --> $DIR/unsupported.rs:168:19 + | +LL | fn stdcall_ptr(f: extern "stdcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target + --> $DIR/unsupported.rs:188:21 + | +LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target + --> $DIR/unsupported.rs:196:22 + | +LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index d7b76a4730b2..edc3d6489348 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -143,3 +143,80 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} error: aborting due to 13 previous errors; 7 warnings emitted For more information about this error, try `rustc --explain E0570`. +Future incompatibility report: Future breakage diagnostic: +warning: the calling convention "ptx-kernel" is not supported on this target + --> $DIR/unsupported.rs:36:15 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "aapcs" is not supported on this target + --> $DIR/unsupported.rs:52:17 + | +LL | fn aapcs_ptr(f: extern "aapcs" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "msp430-interrupt" is not supported on this target + --> $DIR/unsupported.rs:74:18 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "avr-interrupt" is not supported on this target + --> $DIR/unsupported.rs:84:15 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "riscv-interrupt-m" is not supported on this target + --> $DIR/unsupported.rs:97:17 + | +LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target + --> $DIR/unsupported.rs:188:21 + | +LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target + --> $DIR/unsupported.rs:196:22 + | +LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index eef2ead4f0f3..2b9e491ef2ea 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -185,3 +185,102 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} error: aborting due to 17 previous errors; 9 warnings emitted For more information about this error, try `rustc --explain E0570`. +Future incompatibility report: Future breakage diagnostic: +warning: the calling convention "ptx-kernel" is not supported on this target + --> $DIR/unsupported.rs:36:15 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "aapcs" is not supported on this target + --> $DIR/unsupported.rs:52:17 + | +LL | fn aapcs_ptr(f: extern "aapcs" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "msp430-interrupt" is not supported on this target + --> $DIR/unsupported.rs:74:18 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "avr-interrupt" is not supported on this target + --> $DIR/unsupported.rs:84:15 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "x86-interrupt" is not supported on this target + --> $DIR/unsupported.rs:119:15 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "thiscall" is not supported on this target + --> $DIR/unsupported.rs:142:20 + | +LL | fn thiscall_ptr(f: extern "thiscall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "stdcall" is not supported on this target + --> $DIR/unsupported.rs:168:19 + | +LL | fn stdcall_ptr(f: extern "stdcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target + --> $DIR/unsupported.rs:188:21 + | +LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target + --> $DIR/unsupported.rs:196:22 + | +LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index eef2ead4f0f3..2b9e491ef2ea 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -185,3 +185,102 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} error: aborting due to 17 previous errors; 9 warnings emitted For more information about this error, try `rustc --explain E0570`. +Future incompatibility report: Future breakage diagnostic: +warning: the calling convention "ptx-kernel" is not supported on this target + --> $DIR/unsupported.rs:36:15 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "aapcs" is not supported on this target + --> $DIR/unsupported.rs:52:17 + | +LL | fn aapcs_ptr(f: extern "aapcs" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "msp430-interrupt" is not supported on this target + --> $DIR/unsupported.rs:74:18 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "avr-interrupt" is not supported on this target + --> $DIR/unsupported.rs:84:15 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "x86-interrupt" is not supported on this target + --> $DIR/unsupported.rs:119:15 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "thiscall" is not supported on this target + --> $DIR/unsupported.rs:142:20 + | +LL | fn thiscall_ptr(f: extern "thiscall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "stdcall" is not supported on this target + --> $DIR/unsupported.rs:168:19 + | +LL | fn stdcall_ptr(f: extern "stdcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target + --> $DIR/unsupported.rs:188:21 + | +LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target + --> $DIR/unsupported.rs:196:22 + | +LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 80613d83e588..3146ccb80b1b 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -185,3 +185,102 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} error: aborting due to 17 previous errors; 9 warnings emitted For more information about this error, try `rustc --explain E0570`. +Future incompatibility report: Future breakage diagnostic: +warning: the calling convention "ptx-kernel" is not supported on this target + --> $DIR/unsupported.rs:36:15 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "aapcs" is not supported on this target + --> $DIR/unsupported.rs:52:17 + | +LL | fn aapcs_ptr(f: extern "aapcs" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "msp430-interrupt" is not supported on this target + --> $DIR/unsupported.rs:74:18 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "avr-interrupt" is not supported on this target + --> $DIR/unsupported.rs:84:15 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "riscv-interrupt-m" is not supported on this target + --> $DIR/unsupported.rs:97:17 + | +LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "thiscall" is not supported on this target + --> $DIR/unsupported.rs:142:20 + | +LL | fn thiscall_ptr(f: extern "thiscall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "stdcall" is not supported on this target + --> $DIR/unsupported.rs:168:19 + | +LL | fn stdcall_ptr(f: extern "stdcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target + --> $DIR/unsupported.rs:188:21 + | +LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target + --> $DIR/unsupported.rs:196:22 + | +LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + diff --git a/tests/ui/c-variadic/variadic-ffi-2.rs b/tests/ui/c-variadic/variadic-ffi-2.rs index 99f83f22d17c..7b46f579240a 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.rs +++ b/tests/ui/c-variadic/variadic-ffi-2.rs @@ -1,4 +1,5 @@ //@ ignore-arm stdcall isn't supported +//@ ignore-x86 stdcall isn't supported #![feature(extended_varargs_abi_support)] #[allow(unsupported_fn_ptr_calling_conventions)] diff --git a/tests/ui/c-variadic/variadic-ffi-2.stderr b/tests/ui/c-variadic/variadic-ffi-2.stderr index e52de93a9264..56cc49362196 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.stderr +++ b/tests/ui/c-variadic/variadic-ffi-2.stderr @@ -1,5 +1,5 @@ error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` - --> $DIR/variadic-ffi-2.rs:5:11 + --> $DIR/variadic-ffi-2.rs:6:11 | LL | fn baz(f: extern "stdcall" fn(usize, ...)) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention @@ -7,3 +7,13 @@ LL | fn baz(f: extern "stdcall" fn(usize, ...)) { error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0045`. +Future incompatibility report: Future breakage diagnostic: +warning: the calling convention "stdcall" is not supported on this target + --> $DIR/variadic-ffi-2.rs:6:11 + | +LL | fn baz(f: extern "stdcall" fn(usize, ...)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.stderr index 63260b5c78fd..beb0ab70cc7e 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.stderr @@ -11,3 +11,13 @@ LL | core::mem::transmute:: $DIR/gate_test.rs:5:39 + | +LL | core::mem::transmute:: i32>( + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + diff --git a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr index d8dbd94696eb..0e51484846c2 100644 --- a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr +++ b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr @@ -112,3 +112,14 @@ error: aborting due to 12 previous errors; 1 warning emitted Some errors have detailed explanations: E0570, E0658. For more information about an error, try `rustc --explain E0570`. +Future incompatibility report: Future breakage diagnostic: +warning: the calling convention "gpu-kernel" is not supported on this target + --> $DIR/feature-gate-abi_gpu_kernel.rs:39:11 + | +LL | type A1 = extern "gpu-kernel" fn(_: ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + From 310f837fd56d52d20bdcd00b7f89967455570fc0 Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Tue, 18 Feb 2025 15:00:26 +0100 Subject: [PATCH 568/991] Change variadic-ffi-2 to use a platform independant ABI Otherwise this test will include a future incompatibility warning on some targets but not others. --- tests/ui/c-variadic/variadic-ffi-2.rs | 5 +---- tests/ui/c-variadic/variadic-ffi-2.stderr | 16 +++------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/tests/ui/c-variadic/variadic-ffi-2.rs b/tests/ui/c-variadic/variadic-ffi-2.rs index 7b46f579240a..da7bb76fc14b 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.rs +++ b/tests/ui/c-variadic/variadic-ffi-2.rs @@ -1,9 +1,6 @@ -//@ ignore-arm stdcall isn't supported -//@ ignore-x86 stdcall isn't supported #![feature(extended_varargs_abi_support)] -#[allow(unsupported_fn_ptr_calling_conventions)] -fn baz(f: extern "stdcall" fn(usize, ...)) { +fn baz(f: extern "Rust" fn(usize, ...)) { //~^ ERROR: C-variadic function must have a compatible calling convention, // like C, cdecl, system, aapcs, win64, sysv64 or efiapi f(22, 44); diff --git a/tests/ui/c-variadic/variadic-ffi-2.stderr b/tests/ui/c-variadic/variadic-ffi-2.stderr index 56cc49362196..9f8dcefdb033 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.stderr +++ b/tests/ui/c-variadic/variadic-ffi-2.stderr @@ -1,19 +1,9 @@ error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` - --> $DIR/variadic-ffi-2.rs:6:11 + --> $DIR/variadic-ffi-2.rs:3:11 | -LL | fn baz(f: extern "stdcall" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention +LL | fn baz(f: extern "Rust" fn(usize, ...)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0045`. -Future incompatibility report: Future breakage diagnostic: -warning: the calling convention "stdcall" is not supported on this target - --> $DIR/variadic-ffi-2.rs:6:11 - | -LL | fn baz(f: extern "stdcall" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - From 6657aa99dd689b95a74b41deace90009e0927ac5 Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Mon, 3 Mar 2025 09:03:04 +0100 Subject: [PATCH 569/991] Bless UI tests --- tests/ui/abi/unsupported.aarch64.stderr | 20 +++++++++---------- tests/ui/abi/unsupported.arm.stderr | 18 ++++++++--------- tests/ui/abi/unsupported.i686.stderr | 14 ++++++------- tests/ui/abi/unsupported.riscv32.stderr | 18 ++++++++--------- tests/ui/abi/unsupported.riscv64.stderr | 18 ++++++++--------- tests/ui/abi/unsupported.x64.stderr | 18 ++++++++--------- .../feature-gate-abi_gpu_kernel.stderr | 2 +- 7 files changed, 54 insertions(+), 54 deletions(-) diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 224d0e649017..c11cc4e2d52e 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -208,7 +208,7 @@ error: aborting due to 19 previous errors; 10 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -230,7 +230,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +241,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -252,7 +252,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:97:17 + --> $DIR/unsupported.rs:96:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:119:15 + --> $DIR/unsupported.rs:118:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -274,7 +274,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -285,7 +285,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -296,7 +296,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -307,7 +307,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index c813b48ce3ab..b2f24381336a 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -187,7 +187,7 @@ error: aborting due to 17 previous errors; 9 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +198,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:97:17 + --> $DIR/unsupported.rs:96:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:119:15 + --> $DIR/unsupported.rs:118:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +242,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -264,7 +264,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,7 +275,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index edc3d6489348..94bd9b8af90d 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -145,7 +145,7 @@ error: aborting due to 13 previous errors; 7 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -178,7 +178,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:97:17 + --> $DIR/unsupported.rs:96:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -200,7 +200,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +211,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index 2b9e491ef2ea..c6ff47283c6e 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -187,7 +187,7 @@ error: aborting due to 17 previous errors; 9 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +198,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:119:15 + --> $DIR/unsupported.rs:118:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +242,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -264,7 +264,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,7 +275,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index 2b9e491ef2ea..c6ff47283c6e 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -187,7 +187,7 @@ error: aborting due to 17 previous errors; 9 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +198,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:119:15 + --> $DIR/unsupported.rs:118:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +242,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -264,7 +264,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,7 +275,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 3146ccb80b1b..0a9f9a69123c 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -187,7 +187,7 @@ error: aborting due to 17 previous errors; 9 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +198,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:97:17 + --> $DIR/unsupported.rs:96:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +242,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -264,7 +264,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,7 +275,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr index 0e51484846c2..aa9c67f0151f 100644 --- a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr +++ b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr @@ -114,7 +114,7 @@ Some errors have detailed explanations: E0570, E0658. For more information about an error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "gpu-kernel" is not supported on this target - --> $DIR/feature-gate-abi_gpu_kernel.rs:39:11 + --> $DIR/feature-gate-abi_gpu_kernel.rs:37:11 | LL | type A1 = extern "gpu-kernel" fn(_: ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 7c62a4766f65a6875e396be6a50295472f48cfc3 Mon Sep 17 00:00:00 2001 From: Speedy_Lex Date: Mon, 3 Mar 2025 09:51:51 +0100 Subject: [PATCH 570/991] fix order on shl impl this doesn't fix any bugs, it just looks more consistent with the other impl's --- library/core/src/ops/bit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index 6984100e498e..deb54c8ba348 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -493,7 +493,7 @@ macro_rules! shl_impl_all { )*) } -shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 } +shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// The right shift operator `>>`. Note that because this trait is implemented /// for all integer types with multiple right-hand-side types, Rust's type From 32c5449d4523452f2a1d11f57f04997d4fb36592 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 3 Mar 2025 20:17:26 +1100 Subject: [PATCH 571/991] Remove some unnecessary aliases from `rustc_data_structures::sync` With the removal of `cfg(parallel_compiler)`, these are always shared references and `std::sync::OnceLock`. --- compiler/rustc_data_structures/src/sync.rs | 10 ------ compiler/rustc_interface/src/passes.rs | 4 +-- compiler/rustc_metadata/src/rmeta/decoder.rs | 4 +-- compiler/rustc_middle/src/mir/basic_blocks.rs | 3 +- compiler/rustc_monomorphize/src/collector.rs | 34 ++++++++----------- .../rustc_query_system/src/query/caches.rs | 2 +- src/doc/rustc-dev-guide/src/parallel-rustc.md | 2 -- src/tools/clippy/clippy_utils/src/macros.rs | 3 +- 8 files changed, 23 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 37b54fe38ff7..524f6b67d025 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -18,21 +18,16 @@ //! //! | Type | Serial version | Parallel version | //! | ----------------------- | ------------------- | ------------------------------- | -//! | `LRef<'a, T>` [^2] | `&'a mut T` | `&'a T` | -//! | | | | //! | `Lock` | `RefCell` | `RefCell` or | //! | | | `parking_lot::Mutex` | //! | `RwLock` | `RefCell` | `parking_lot::RwLock` | //! | `MTLock` [^1] | `T` | `Lock` | -//! | `MTLockRef<'a, T>` [^2] | `&'a mut MTLock` | `&'a MTLock` | //! | | | | //! | `ParallelIterator` | `Iterator` | `rayon::iter::ParallelIterator` | //! //! [^1]: `MTLock` is similar to `Lock`, but the serial version avoids the cost //! of a `RefCell`. This is appropriate when interior mutability is not //! required. -//! -//! [^2]: `MTRef`, `MTLockRef` are type aliases. use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; @@ -97,7 +92,6 @@ mod mode { // FIXME(parallel_compiler): Get rid of these aliases across the compiler. -pub use std::sync::OnceLock; // Use portable AtomicU64 for targets without native 64-bit atomics #[cfg(target_has_atomic = "64")] pub use std::sync::atomic::AtomicU64; @@ -110,8 +104,6 @@ pub use parking_lot::{ #[cfg(not(target_has_atomic = "64"))] pub use portable_atomic::AtomicU64; -pub type LRef<'a, T> = &'a T; - #[derive(Debug, Default)] pub struct MTLock(Lock); @@ -148,8 +140,6 @@ use parking_lot::RwLock as InnerRwLock; /// It is only useful when you are running in a single thread const ERROR_CHECKING: bool = false; -pub type MTLockRef<'a, T> = LRef<'a, MTLock>; - #[derive(Default)] #[repr(align(64))] pub struct CacheAligned(pub T); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 553215ca0af0..e47385d08994 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -2,14 +2,14 @@ use std::any::Any; use std::ffi::OsString; use std::io::{self, BufWriter, Write}; use std::path::{Path, PathBuf}; -use std::sync::{Arc, LazyLock}; +use std::sync::{Arc, LazyLock, OnceLock}; use std::{env, fs, iter}; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::parallel; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, OnceLock, WorkerLocal}; +use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal}; use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_feature::Features; use rustc_fs_util::try_canonicalize; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index e8d9d17872f7..6ffbebfffd5a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -2,7 +2,7 @@ use std::iter::TrustedLen; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, OnceLock}; use std::{io, iter, mem}; pub(super) use cstore_impl::provide; @@ -11,7 +11,7 @@ use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::owned_slice::OwnedSlice; -use rustc_data_structures::sync::{Lock, OnceLock}; +use rustc_data_structures::sync::Lock; use rustc_data_structures::unhash::UnhashMap; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro}; diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index 171542d1279c..d0dbf64dc595 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -1,8 +1,9 @@ +use std::sync::OnceLock; + use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph; use rustc_data_structures::graph::dominators::{Dominators, dominators}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::OnceLock; use rustc_index::{IndexSlice, IndexVec}; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 08df0dedc6b0..67fca1d7c294 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -209,7 +209,7 @@ use std::path::PathBuf; use rustc_attr_parsing::InlineAttr; use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::sync::{LRef, MTLock, par_for_each_in}; +use rustc_data_structures::sync::{MTLock, par_for_each_in}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -357,7 +357,7 @@ impl<'tcx> Extend>> for MonoItems<'tcx> { fn collect_items_rec<'tcx>( tcx: TyCtxt<'tcx>, starting_item: Spanned>, - state: LRef<'_, SharedState<'tcx>>, + state: &SharedState<'tcx>, recursion_depths: &mut DefIdMap, recursion_limit: Limit, mode: CollectionMode, @@ -1671,30 +1671,26 @@ pub(crate) fn collect_crate_mono_items<'tcx>( debug!("building mono item graph, beginning at roots"); - let mut state = SharedState { + let state = SharedState { visited: MTLock::new(UnordSet::default()), mentioned: MTLock::new(UnordSet::default()), usage_map: MTLock::new(UsageMap::new()), }; let recursion_limit = tcx.recursion_limit(); - { - let state: LRef<'_, _> = &mut state; - - tcx.sess.time("monomorphization_collector_graph_walk", || { - par_for_each_in(roots, |root| { - let mut recursion_depths = DefIdMap::default(); - collect_items_rec( - tcx, - dummy_spanned(root), - state, - &mut recursion_depths, - recursion_limit, - CollectionMode::UsedItems, - ); - }); + tcx.sess.time("monomorphization_collector_graph_walk", || { + par_for_each_in(roots, |root| { + let mut recursion_depths = DefIdMap::default(); + collect_items_rec( + tcx, + dummy_spanned(root), + &state, + &mut recursion_depths, + recursion_limit, + CollectionMode::UsedItems, + ); }); - } + }); // The set of MonoItems was created in an inherently indeterministic order because // of parallelism. We sort it here to ensure that the output is deterministic. diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index e11123dff26a..3b47e7eba0ff 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -1,9 +1,9 @@ use std::fmt::Debug; use std::hash::Hash; +use std::sync::OnceLock; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sharded::{self, Sharded}; -use rustc_data_structures::sync::OnceLock; pub use rustc_data_structures::vec_cache::VecCache; use rustc_hir::def_id::LOCAL_CRATE; use rustc_index::Idx; diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md index c5b70706a818..690fb19c9f52 100644 --- a/src/doc/rustc-dev-guide/src/parallel-rustc.md +++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md @@ -46,10 +46,8 @@ are implemented differently depending on whether `parallel-compiler` is true. | data structure | parallel | non-parallel | | -------------------------------- | --------------------------------------------------- | ------------ | -| OnceCell | std::sync::OnceLock | std::cell::OnceCell | | Lock\ | (parking_lot::Mutex\) | (std::cell::RefCell) | | RwLock\ | (parking_lot::RwLock\) | (std::cell::RefCell) | -| MTRef<'a, T> | &'a T | &'a mut T | | MTLock\ | (Lock\) | (T) | | ReadGuard | parking_lot::RwLockReadGuard | std::cell::Ref | | MappedReadGuard | parking_lot::MappedRwLockReadGuard | std::cell::Ref | diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs index 3ce2cdfebe96..1a457bc7f214 100644 --- a/src/tools/clippy/clippy_utils/src/macros.rs +++ b/src/tools/clippy/clippy_utils/src/macros.rs @@ -1,6 +1,6 @@ #![allow(clippy::similar_names)] // `expr` and `expn` -use std::sync::Arc; +use std::sync::{Arc, OnceLock}; use crate::get_unique_attr; use crate::visitors::{Descend, for_each_expr_without_closures}; @@ -8,7 +8,6 @@ use crate::visitors::{Descend, for_each_expr_without_closures}; use arrayvec::ArrayVec; use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::OnceLock; use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath}; use rustc_lint::{LateContext, LintContext}; use rustc_span::def_id::DefId; From cfa27fbeef0698c85772b7d089615f2633c2eade Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 3 Mar 2025 14:06:53 +1100 Subject: [PATCH 572/991] Tidy imports in `rustc_data_structures::sync` --- compiler/rustc_data_structures/src/sync.rs | 63 +++++++++++----------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 524f6b67d025..a1cc75c49850 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -32,23 +32,40 @@ use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; +pub use parking_lot::{ + MappedRwLockReadGuard as MappedReadGuard, MappedRwLockWriteGuard as MappedWriteGuard, + RwLockReadGuard as ReadGuard, RwLockWriteGuard as WriteGuard, +}; + +pub use self::atomic::AtomicU64; +pub use self::freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard}; +#[doc(no_inline)] +pub use self::lock::{Lock, LockGuard, Mode}; +pub use self::mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode}; +pub use self::parallel::{ + join, par_for_each_in, par_map, parallel_guard, scope, try_par_for_each_in, +}; +pub use self::vec::{AppendOnlyIndexVec, AppendOnlyVec}; +pub use self::worker_local::{Registry, WorkerLocal}; pub use crate::marker::*; -mod lock; -#[doc(no_inline)] -pub use lock::{Lock, LockGuard, Mode}; - -mod worker_local; -pub use worker_local::{Registry, WorkerLocal}; - -mod parallel; -pub use parallel::{join, par_for_each_in, par_map, parallel_guard, scope, try_par_for_each_in}; -pub use vec::{AppendOnlyIndexVec, AppendOnlyVec}; - -mod vec; - mod freeze; -pub use freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard}; +mod lock; +mod parallel; +mod vec; +mod worker_local; + +/// Keep the conditional imports together in a submodule, so that import-sorting +/// doesn't split them up. +mod atomic { + // Most hosts can just use a regular AtomicU64. + #[cfg(target_has_atomic = "64")] + pub use std::sync::atomic::AtomicU64; + + // Some 32-bit hosts don't have AtomicU64, so use a fallback. + #[cfg(not(target_has_atomic = "64"))] + pub use portable_atomic::AtomicU64; +} mod mode { use std::sync::atomic::{AtomicU8, Ordering}; @@ -92,18 +109,6 @@ mod mode { // FIXME(parallel_compiler): Get rid of these aliases across the compiler. -// Use portable AtomicU64 for targets without native 64-bit atomics -#[cfg(target_has_atomic = "64")] -pub use std::sync::atomic::AtomicU64; - -pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode}; -pub use parking_lot::{ - MappedRwLockReadGuard as MappedReadGuard, MappedRwLockWriteGuard as MappedWriteGuard, - RwLockReadGuard as ReadGuard, RwLockWriteGuard as WriteGuard, -}; -#[cfg(not(target_has_atomic = "64"))] -pub use portable_atomic::AtomicU64; - #[derive(Debug, Default)] pub struct MTLock(Lock); @@ -134,8 +139,6 @@ impl MTLock { } } -use parking_lot::RwLock as InnerRwLock; - /// This makes locks panic if they are already held. /// It is only useful when you are running in a single thread const ERROR_CHECKING: bool = false; @@ -157,12 +160,12 @@ impl HashMapExt for HashMap } #[derive(Debug, Default)] -pub struct RwLock(InnerRwLock); +pub struct RwLock(parking_lot::RwLock); impl RwLock { #[inline(always)] pub fn new(inner: T) -> Self { - RwLock(InnerRwLock::new(inner)) + RwLock(parking_lot::RwLock::new(inner)) } #[inline(always)] From c2a630eaa591907315fb8a1f55ec5b9e9b4b2d18 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 3 Mar 2025 15:58:33 +0530 Subject: [PATCH 573/991] Add dangling impl - Adds dangling impl diagnostics - Rename validation test from dangling_impl to dangling_iml_ref --- .../crates/syntax/src/validation.rs | 27 ++++++++--------- .../parser/validation/dangling_impl.rast | 30 +++++++++---------- .../parser/validation/dangling_impl.rs | 2 +- .../validation/dangling_impl_reference.rast | 25 ++++++++++++++++ .../validation/dangling_impl_reference.rs | 1 + 5 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl_reference.rast create mode 100644 src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl_reference.rs diff --git a/src/tools/rust-analyzer/crates/syntax/src/validation.rs b/src/tools/rust-analyzer/crates/syntax/src/validation.rs index 0377e7c0e63e..85eefac734b2 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/validation.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/validation.rs @@ -37,6 +37,7 @@ pub(crate) fn validate(root: &SyntaxNode, errors: &mut Vec) { ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, errors), ast::MacroRules(it) => validate_macro_rules(it, errors), ast::LetExpr(it) => validate_let_expr(it, errors), + ast::ImplTraitType(it) => validate_impl_object_ty(it, errors), _ => (), } } @@ -315,21 +316,10 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec) { - match ty.ty() { - Some(ast::Type::DynTraitType(ty)) => { - if let Some(err) = validate_trait_object_ty(ty) { - errors.push(err); - } + if let Some(ast::Type::DynTraitType(ty)) = ty.ty() { + if let Some(err) = validate_trait_object_ty(ty) { + errors.push(err); } - Some(ast::Type::ImplTraitType(ty)) => { - if ty.type_bound_list().map_or(0, |tbl| tbl.bounds().count()) == 0 { - errors.push(SyntaxError::new( - "At least one trait must be specified", - ty.syntax().text_range(), - )); - } - } - _ => {} } } @@ -372,6 +362,15 @@ fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option { } } +fn validate_impl_object_ty(ty: ast::ImplTraitType, errors: &mut Vec) { + if ty.type_bound_list().map_or(0, |tbl| tbl.bounds().count()) == 0 { + errors.push(SyntaxError::new( + "At least one trait must be specified", + ty.syntax().text_range(), + )); + } +} + fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec) { if let Some(vis) = mac.visibility() { errors.push(SyntaxError::new( diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rast b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rast index dbe6535ac665..2db07ae12a98 100644 --- a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rast +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rast @@ -1,25 +1,23 @@ -SOURCE_FILE@0..17 - FN@0..17 +SOURCE_FILE@0..16 + FN@0..16 FN_KW@0..2 "fn" WHITESPACE@2..3 " " NAME@3..4 IDENT@3..4 "f" - PARAM_LIST@4..14 + PARAM_LIST@4..13 L_PAREN@4..5 "(" - PARAM@5..13 + PARAM@5..12 WILDCARD_PAT@5..6 UNDERSCORE@5..6 "_" COLON@6..7 ":" WHITESPACE@7..8 " " - REF_TYPE@8..13 - AMP@8..9 "&" - IMPL_TRAIT_TYPE@9..13 - IMPL_KW@9..13 "impl" - TYPE_BOUND_LIST@13..13 - R_PAREN@13..14 ")" - WHITESPACE@14..15 " " - BLOCK_EXPR@15..17 - STMT_LIST@15..17 - L_CURLY@15..16 "{" - R_CURLY@16..17 "}" -error 9..13: At least one trait must be specified + IMPL_TRAIT_TYPE@8..12 + IMPL_KW@8..12 "impl" + TYPE_BOUND_LIST@12..12 + R_PAREN@12..13 ")" + WHITESPACE@13..14 " " + BLOCK_EXPR@14..16 + STMT_LIST@14..16 + L_CURLY@14..15 "{" + R_CURLY@15..16 "}" +error 8..12: At least one trait must be specified diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rs b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rs index 0b440b4c5af4..61706d9e4129 100644 --- a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rs +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl.rs @@ -1 +1 @@ -fn f(_: &impl) {} \ No newline at end of file +fn f(_: impl) {} \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl_reference.rast b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl_reference.rast new file mode 100644 index 000000000000..dbe6535ac665 --- /dev/null +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl_reference.rast @@ -0,0 +1,25 @@ +SOURCE_FILE@0..17 + FN@0..17 + FN_KW@0..2 "fn" + WHITESPACE@2..3 " " + NAME@3..4 + IDENT@3..4 "f" + PARAM_LIST@4..14 + L_PAREN@4..5 "(" + PARAM@5..13 + WILDCARD_PAT@5..6 + UNDERSCORE@5..6 "_" + COLON@6..7 ":" + WHITESPACE@7..8 " " + REF_TYPE@8..13 + AMP@8..9 "&" + IMPL_TRAIT_TYPE@9..13 + IMPL_KW@9..13 "impl" + TYPE_BOUND_LIST@13..13 + R_PAREN@13..14 ")" + WHITESPACE@14..15 " " + BLOCK_EXPR@15..17 + STMT_LIST@15..17 + L_CURLY@15..16 "{" + R_CURLY@16..17 "}" +error 9..13: At least one trait must be specified diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl_reference.rs b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl_reference.rs new file mode 100644 index 000000000000..0b440b4c5af4 --- /dev/null +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/dangling_impl_reference.rs @@ -0,0 +1 @@ +fn f(_: &impl) {} \ No newline at end of file From c315ad914fa2755ee8444a12d5ecfa599065b5bd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 2 Mar 2025 09:49:52 +0100 Subject: [PATCH 574/991] Support tuple struct patterns for expand_rest_pattern assist --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 2 + .../src/handlers/expand_rest_pattern.rs | 187 ++++++++++++++++-- .../crates/ide-assists/src/tests/generated.rs | 25 ++- .../docs/book/src/assists_generated.md | 28 ++- 4 files changed, 217 insertions(+), 25 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 55448d4ae868..7549d54a544e 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -296,6 +296,7 @@ pub enum ModuleDef { Function(Function), Adt(Adt), // Can't be directly declared, but can be imported. + // FIXME: Rename to `EnumVariant` Variant(Variant), Const(Const), Static(Static), @@ -1564,6 +1565,7 @@ impl From<&Variant> for DefWithBodyId { } } +// FIXME: Rename to `EnumVariant` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Variant { pub(crate) id: EnumVariantId, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs index 315d7e727b41..c79a982c38d0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs @@ -1,3 +1,5 @@ +use hir::{PathResolution, StructKind}; +use ide_db::syntax_helpers::suggest_name::NameGenerator; use syntax::{ ast::{self, make}, match_ast, AstNode, ToSmolStr, @@ -5,7 +7,23 @@ use syntax::{ use crate::{AssistContext, AssistId, Assists}; -// Assist: expand_rest_pattern +pub(crate) fn expand_rest_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + let rest_pat = ctx.find_node_at_offset::()?; + let parent = rest_pat.syntax().parent()?; + match_ast! { + match parent { + ast::RecordPatFieldList(it) => expand_record_rest_pattern(acc, ctx, it.syntax().parent().and_then(ast::RecordPat::cast)?, rest_pat), + ast::TupleStructPat(it) => expand_tuple_struct_rest_pattern(acc, ctx, it, rest_pat), + // FIXME + // ast::TuplePat(it) => (), + // FIXME + // ast::SlicePat(it) => (), + _ => return None, + } + } +} + +// Assist: expand_record_rest_pattern // // Fills fields by replacing rest pattern in record patterns. // @@ -24,22 +42,12 @@ use crate::{AssistContext, AssistId, Assists}; // let Bar { y, z } = bar; // } // ``` -pub(crate) fn expand_rest_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let rest_pat = ctx.find_node_at_offset::()?; - let parent = rest_pat.syntax().parent()?; - let record_pat = match_ast! { - match parent { - ast::RecordPatFieldList(it) => ast::RecordPat::cast(it.syntax().parent()?)?, - // ast::TupleStructPat(it) => (), - // ast::TuplePat(it) => (), - // ast::SlicePat(it) => (), - _ => return None, - } - }; - - let ellipsis = record_pat.record_pat_field_list().and_then(|r| r.rest_pat())?; - let target_range = ellipsis.syntax().text_range(); - +fn expand_record_rest_pattern( + acc: &mut Assists, + ctx: &AssistContext<'_>, + record_pat: ast::RecordPat, + rest_pat: ast::RestPat, +) -> Option<()> { let missing_fields = ctx.sema.record_pattern_missing_fields(&record_pat); if missing_fields.is_empty() { @@ -48,6 +56,11 @@ pub(crate) fn expand_rest_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> } let old_field_list = record_pat.record_pat_field_list()?; + let old_range = ctx.sema.original_range_opt(old_field_list.syntax())?; + if old_range.file_id != ctx.file_id() { + return None; + } + let new_field_list = make::record_pat_field_list(old_field_list.fields(), None).clone_for_update(); for (f, _) in missing_fields.iter() { @@ -58,16 +71,93 @@ pub(crate) fn expand_rest_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> new_field_list.add_field(field.clone_for_update()); } - let old_range = ctx.sema.original_range_opt(old_field_list.syntax())?; + let target_range = rest_pat.syntax().text_range(); + acc.add( + AssistId("expand_record_rest_pattern", crate::AssistKind::RefactorRewrite), + "Fill struct fields", + target_range, + move |builder| builder.replace_ast(old_field_list, new_field_list), + ) +} +// Assist: expand_tuple_struct_rest_pattern +// +// Fills fields by replacing rest pattern in tuple struct patterns. +// +// ``` +// struct Bar(Y, Z); +// +// fn foo(bar: Bar) { +// let Bar(..$0) = bar; +// } +// ``` +// -> +// ``` +// struct Bar(Y, Z); +// +// fn foo(bar: Bar) { +// let Bar(_0, _1) = bar; +// } +// ``` +fn expand_tuple_struct_rest_pattern( + acc: &mut Assists, + ctx: &AssistContext<'_>, + pat: ast::TupleStructPat, + rest_pat: ast::RestPat, +) -> Option<()> { + let path = pat.path()?; + let fields = match ctx.sema.type_of_pat(&pat.clone().into())?.original.as_adt()? { + hir::Adt::Struct(s) if s.kind(ctx.sema.db) == StructKind::Tuple => s.fields(ctx.sema.db), + hir::Adt::Enum(_) => match ctx.sema.resolve_path(&path)? { + PathResolution::Def(hir::ModuleDef::Variant(v)) + if v.kind(ctx.sema.db) == StructKind::Tuple => + { + v.fields(ctx.sema.db) + } + _ => return None, + }, + _ => return None, + }; + + let rest_pat = rest_pat.into(); + let mut pats = pat.fields(); + let prefix_count = pats.by_ref().position(|p| p == rest_pat)?; + let suffix_count = pats.count(); + + if fields.len().saturating_sub(prefix_count).saturating_sub(suffix_count) == 0 { + cov_mark::hit!(no_missing_fields_tuple_struct); + return None; + } + + let old_range = ctx.sema.original_range_opt(pat.syntax())?; if old_range.file_id != ctx.file_id() { return None; } + let mut name_gen = NameGenerator::new_from_scope_locals(ctx.sema.scope(pat.syntax())); + let new_pat = make::tuple_struct_pat( + path, + pat.fields() + .take(prefix_count) + .chain(fields[prefix_count..fields.len() - suffix_count].iter().map(|f| { + make::ident_pat( + false, + false, + match name_gen.for_type(&f.ty(ctx.sema.db), ctx.sema.db, ctx.edition()) { + Some(name) => make::name(&name), + None => make::name(&format!("_{}", f.index())), + }, + ) + .into() + })) + .chain(pat.fields().skip(prefix_count + 1)), + ); + + let target_range = rest_pat.syntax().text_range(); acc.add( - AssistId("expand_rest_pattern", crate::AssistKind::RefactorRewrite), - "Fill structure fields", + AssistId("expand_tuple_struct_rest_pattern", crate::AssistKind::RefactorRewrite), + "Fill tuple struct fields", target_range, - move |builder| builder.replace_ast(old_field_list, new_field_list), + move |builder| builder.replace_ast(pat, new_pat), ) } @@ -165,6 +255,27 @@ struct Bar { fn foo(bar: Bar) { let Bar { y, z } = bar; } +"#, + ); + check_assist( + expand_rest_pattern, + r#" +struct Y; +struct Z; +struct Bar(Y, Z) + +fn foo(bar: Bar) { + let Bar(..$0) = bar; +} +"#, + r#" +struct Y; +struct Z; +struct Bar(Y, Z) + +fn foo(bar: Bar) { + let Bar(y, z) = bar; +} "#, ) } @@ -192,6 +303,29 @@ struct Bar { fn foo(bar: Bar) { let Bar { y, z } = bar; } +"#, + ); + check_assist( + expand_rest_pattern, + r#" +struct X; +struct Y; +struct Z; +struct Bar(X, Y, Z) + +fn foo(bar: Bar) { + let Bar(x, ..$0, z) = bar; +} +"#, + r#" +struct X; +struct Y; +struct Z; +struct Bar(X, Y, Z) + +fn foo(bar: Bar) { + let Bar(x, y, z) = bar; +} "#, ) } @@ -330,6 +464,7 @@ fn bar(foo: Foo) { fn not_applicable_when_no_missing_fields() { // This is still possible even though it's meaningless cov_mark::check!(no_missing_fields); + cov_mark::check!(no_missing_fields_tuple_struct); check_assist_not_applicable( expand_rest_pattern, r#" @@ -357,6 +492,16 @@ struct Bar { fn foo(bar: Bar) { let Bar { y, z, ..$0 } = bar; } +"#, + ); + check_assist_not_applicable( + expand_rest_pattern, + r#" +struct Bar(Y, Z) + +fn foo(bar: Bar) { + let Bar(y, ..$0, z) = bar; +} "#, ); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index dd994ef4a640..46688a22f333 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -956,9 +956,9 @@ pub use foo::{Bar, Baz}; } #[test] -fn doctest_expand_rest_pattern() { +fn doctest_expand_record_rest_pattern() { check_doc_test( - "expand_rest_pattern", + "expand_record_rest_pattern", r#####" struct Bar { y: Y, z: Z } @@ -976,6 +976,27 @@ fn foo(bar: Bar) { ) } +#[test] +fn doctest_expand_tuple_struct_rest_pattern() { + check_doc_test( + "expand_tuple_struct_rest_pattern", + r#####" +struct Bar(Y, Z); + +fn foo(bar: Bar) { + let Bar(..$0) = bar; +} +"#####, + r#####" +struct Bar(Y, Z); + +fn foo(bar: Bar) { + let Bar(_0, _1) = bar; +} +"#####, + ) +} + #[test] fn doctest_extract_constant() { check_doc_test( diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 743e5c5e10d4..b815cad0a230 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -1069,8 +1069,8 @@ pub use foo::{Bar, Baz}; ``` -### `expand_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L8) +### `expand_record_rest_pattern` +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L24) Fills fields by replacing rest pattern in record patterns. @@ -1093,6 +1093,30 @@ fn foo(bar: Bar) { ``` +### `expand_tuple_struct_rest_pattern` +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L80) + +Fills fields by replacing rest pattern in tuple struct patterns. + +#### Before +```rust +struct Bar(Y, Z); + +fn foo(bar: Bar) { + let Bar(..┃) = bar; +} +``` + +#### After +```rust +struct Bar(Y, Z); + +fn foo(bar: Bar) { + let Bar(_0, _1) = bar; +} +``` + + ### `extract_constant` **Source:** [extract_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_variable.rs#L35) From cc39e5f2665d4288cef57c00efe5623ce3859820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 20 Mar 2024 18:54:01 +0100 Subject: [PATCH 575/991] Apply dllimport in ThinLTO --- compiler/rustc_codegen_llvm/src/consts.rs | 11 +++++------ .../issues/auxiliary/static_dllimport_aux.rs | 13 ------------- .../issue-81408-dllimport-thinlto-windows.rs | 15 --------------- 3 files changed, 5 insertions(+), 34 deletions(-) delete mode 100644 tests/codegen/issues/auxiliary/static_dllimport_aux.rs delete mode 100644 tests/codegen/issues/issue-81408-dllimport-thinlto-windows.rs diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 330e8a8f4069..31b73ca0f842 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -16,7 +16,6 @@ use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::Instance; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::{bug, span_bug}; -use rustc_session::config::Lto; use tracing::{debug, instrument, trace}; use crate::common::{AsCCharPtr, CodegenCx}; @@ -344,11 +343,11 @@ impl<'ll> CodegenCx<'ll, '_> { // Local definitions can never be imported, so we must not apply // the DLLImport annotation. && !dso_local - // ThinLTO can't handle this workaround in all cases, so we don't - // emit the attrs. Instead we make them unnecessary by disallowing - // dynamic linking when linker plugin based LTO is enabled. - && !self.tcx.sess.opts.cg.linker_plugin_lto.enabled() - && self.tcx.sess.lto() != Lto::Thin; + // Linker plugin ThinLTO doesn't create the self-dllimport Rust uses for rlibs + // as the code generation happens out of process. Instead we assume static linkage + // and disallow dynamic linking when linker plugin based LTO is enabled. + // Regular in-process ThinLTO doesn't need this workaround. + && !self.tcx.sess.opts.cg.linker_plugin_lto.enabled(); // If this assertion triggers, there's something wrong with commandline // argument validation. diff --git a/tests/codegen/issues/auxiliary/static_dllimport_aux.rs b/tests/codegen/issues/auxiliary/static_dllimport_aux.rs deleted file mode 100644 index afb0dc42f443..000000000000 --- a/tests/codegen/issues/auxiliary/static_dllimport_aux.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::sync::atomic::{AtomicPtr, Ordering}; - -#[inline(always)] -pub fn memrchr() { - fn detect() {} - - static CROSS_CRATE_STATIC_ITEM: AtomicPtr<()> = AtomicPtr::new(detect as *mut ()); - - unsafe { - let fun = CROSS_CRATE_STATIC_ITEM.load(Ordering::SeqCst); - std::mem::transmute::<*mut (), fn()>(fun)() - } -} diff --git a/tests/codegen/issues/issue-81408-dllimport-thinlto-windows.rs b/tests/codegen/issues/issue-81408-dllimport-thinlto-windows.rs deleted file mode 100644 index 4023412f23cf..000000000000 --- a/tests/codegen/issues/issue-81408-dllimport-thinlto-windows.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ compile-flags: -Copt-level=3 -C lto=thin -C prefer-dynamic=no -//@ only-windows -//@ aux-build:static_dllimport_aux.rs - -// Test that on Windows, when performing ThinLTO, we do not mark cross-crate static items with -// dllimport because lld does not fix the symbol names for us. - -extern crate static_dllimport_aux; - -// CHECK-LABEL: @{{.+}}CROSS_CRATE_STATIC_ITEM{{.+}} = -// CHECK-SAME: external local_unnamed_addr global %"{{.+}}AtomicPtr - -pub fn main() { - static_dllimport_aux::memrchr(); -} From de07b171effdd344c51907998236dd6aafaa5b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 3 Mar 2025 16:03:06 +0200 Subject: [PATCH 576/991] Bump minimum supported toolchain to 1.82 --- src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index a0d6a0d6da6f..b9e38f2e6917 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -12,7 +12,7 @@ /// Any toolchain less than this version will likely not work with rust-analyzer built from this revision. pub const MINIMUM_SUPPORTED_TOOLCHAIN_VERSION: semver::Version = semver::Version { major: 1, - minor: 78, + minor: 82, patch: 0, pre: semver::Prerelease::EMPTY, build: semver::BuildMetadata::EMPTY, From 530bedc1d087b0df94367db56904b3da1dac5a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 3 Mar 2025 16:09:57 +0100 Subject: [PATCH 577/991] Skip Rust for Linux in CI temporarily --- src/ci/github-actions/jobs.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index bbcc01a0c299..1504e5c60ce7 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -271,8 +271,9 @@ auto: # Tests integration with Rust for Linux. # Builds stage 1 compiler and tries to compile a few RfL examples with it. - - name: x86_64-rust-for-linux - <<: *job-linux-4c + # FIXME: fix rustup 1.28 issue + # - name: x86_64-rust-for-linux + # <<: *job-linux-4c - name: x86_64-gnu <<: *job-linux-4c From 93b8279f4fca7631ca8585ebcc9ed6b31ec57173 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 3 Mar 2025 07:15:34 -0800 Subject: [PATCH 578/991] Fix docker run-local docs --- src/ci/docker/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index a1a3a1c37ced..20b6f7d10ef5 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -11,12 +11,12 @@ the [`jobs.yml`](../github-actions/jobs.yml) file. To run a specific CI job locally, you can use the `citool` Rust crate: ``` -cargo --manifest-path src/ci/citool/Cargo.toml run run-local +cargo run --manifest-path src/ci/citool/Cargo.toml run-local ``` For example, to run the `x86_64-gnu-llvm-18-1` job: ``` -cargo --manifest-path src/ci/citool/Cargo.toml run run-local x86_64-gnu-llvm-18-1 +cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-llvm-18-1 ``` The job will output artifacts in an `obj/` dir at the root of a repository. Note From 7e0a2fcb1b4c8026948212140d7d58b8ed87fa38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 11 Feb 2025 20:21:02 +0800 Subject: [PATCH 579/991] compiletest: change `TEST_BUILD_DIR` to maximally normalize This is to make test stderr insensitive to compare-mode / debugger that changes the test build dir output name. Previously, this normalized paths up to test-suite-specific build root, e.g. `/path/to/build/test/ui/`. Now, this normalizes up to test-specific build root, e.g. `/path/to/build/test/ui/subdir/$name.$revision.$mode.$debugger/`. --- src/tools/compiletest/src/runtest.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index f36d43b211ff..6e250ca12c93 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2412,8 +2412,9 @@ impl<'test> TestCx<'test> { let rust_src_dir = rust_src_dir.read_link().unwrap_or(rust_src_dir.to_path_buf()); normalize_path(&rust_src_dir.join("library"), "$SRC_DIR_REAL"); - // eg. /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui - normalize_path(&self.config.build_test_suite_root, "$TEST_BUILD_DIR"); + // eg. + // /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui//$name.$revision.$mode/ + normalize_path(&self.output_base_dir(), "$TEST_BUILD_DIR"); // eg. /home/user/rust/build normalize_path(&self.config.build_root, "$BUILD_DIR"); @@ -2434,6 +2435,18 @@ impl<'test> TestCx<'test> { .into_owned(); normalized = Self::normalize_platform_differences(&normalized); + + // Normalize long type name hash. + normalized = + static_regex!(r"\$TEST_BUILD_DIR/(?P[^\.]+).long-type-(?P\d+).txt") + .replace_all(&normalized, |caps: &Captures<'_>| { + format!( + "$TEST_BUILD_DIR/{filename}.long-type-$LONG_TYPE_HASH.txt", + filename = &caps["filename"] + ) + }) + .into_owned(); + normalized = normalized.replace("\t", "\\t"); // makes tabs visible // Remove test annotations like `//~ ERROR text` from the output, From 83429144fc43960368a25f0190d333f927805952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 11 Feb 2025 20:38:58 +0800 Subject: [PATCH 580/991] tests: remove explicit long type filename hash normalization from some ui tests --- tests/ui/diagnostic-width/E0271.ascii.stderr | 6 +++--- tests/ui/diagnostic-width/E0271.rs | 1 - tests/ui/diagnostic-width/E0271.unicode.stderr | 6 +++--- tests/ui/diagnostic-width/binop.rs | 2 -- tests/ui/diagnostic-width/binop.stderr | 8 ++++---- .../diagnostic-width/long-E0308.ascii.stderr | 16 ++++++++-------- tests/ui/diagnostic-width/long-E0308.rs | 3 --- .../diagnostic-width/long-E0308.unicode.stderr | 16 ++++++++-------- tests/ui/diagnostic-width/long-E0529.rs | 3 +-- tests/ui/diagnostic-width/long-E0529.stderr | 4 ++-- tests/ui/diagnostic-width/long-E0609.rs | 3 +-- tests/ui/diagnostic-width/long-E0609.stderr | 4 ++-- tests/ui/diagnostic-width/long-E0614.rs | 3 +-- tests/ui/diagnostic-width/long-E0614.stderr | 4 ++-- tests/ui/diagnostic-width/long-E0618.rs | 3 +-- tests/ui/diagnostic-width/long-E0618.stderr | 4 ++-- tests/ui/diagnostic-width/long-e0277.rs | 2 -- tests/ui/diagnostic-width/long-e0277.stderr | 8 ++++---- .../ui/diagnostic-width/non-copy-type-moved.rs | 2 -- .../non-copy-type-moved.stderr | 4 ++-- .../secondary-label-with-long-type.rs | 2 -- .../secondary-label-with-long-type.stderr | 4 ++-- tests/ui/error-codes/E0275.rs | 1 - tests/ui/error-codes/E0275.stderr | 4 ++-- .../trait-bounds/hang-on-deeply-nested-dyn.rs | 2 -- .../hang-on-deeply-nested-dyn.stderr | 2 +- .../trait-bounds/hrtb-doesnt-borrow-self-1.rs | 2 -- .../hrtb-doesnt-borrow-self-1.stderr | 14 +++++++------- .../trait-bounds/hrtb-doesnt-borrow-self-2.rs | 2 -- .../hrtb-doesnt-borrow-self-2.stderr | 14 +++++++------- ...ite-instantiation-struct-tail-ice-114484.rs | 3 --- ...instantiation-struct-tail-ice-114484.stderr | 10 +++++----- tests/ui/infinite/infinite-instantiation.rs | 2 -- .../ui/infinite/infinite-instantiation.stderr | 6 +++--- tests/ui/issues/issue-20413.rs | 1 - tests/ui/issues/issue-20413.stderr | 18 +++++++++--------- .../issue-37311.rs | 2 -- .../issue-37311.stderr | 6 +++--- tests/ui/issues/issue-67552.rs | 2 -- tests/ui/issues/issue-67552.stderr | 6 +++--- tests/ui/issues/issue-8727.rs | 2 -- tests/ui/issues/issue-8727.stderr | 8 ++++---- tests/ui/methods/inherent-bound-in-probe.rs | 2 -- .../ui/methods/inherent-bound-in-probe.stderr | 8 ++++---- tests/ui/recursion/issue-23122-2.rs | 1 - tests/ui/recursion/issue-23122-2.stderr | 4 ++-- tests/ui/recursion/issue-83150.rs | 3 +-- tests/ui/recursion/issue-83150.stderr | 8 ++++---- tests/ui/recursion/recursion.rs | 2 -- tests/ui/recursion/recursion.stderr | 6 +++--- tests/ui/regions/issue-102374.rs | 1 - tests/ui/regions/issue-102374.stderr | 2 +- tests/ui/traits/on_unimplemented_long_types.rs | 2 -- .../traits/on_unimplemented_long_types.stderr | 4 ++-- tests/ui/type_length_limit.rs | 3 --- tests/ui/type_length_limit.stderr | 4 ++-- 56 files changed, 109 insertions(+), 156 deletions(-) diff --git a/tests/ui/diagnostic-width/E0271.ascii.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr index 9a9c12a938f6..ad5f53e44bea 100644 --- a/tests/ui/diagnostic-width/E0271.ascii.stderr +++ b/tests/ui/diagnostic-width/E0271.ascii.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving ` as Future>::Error == Foo` - --> $DIR/E0271.rs:20:5 + --> $DIR/E0271.rs:19:5 | LL | / Box::new( LL | | Ok::<_, ()>( @@ -10,12 +10,12 @@ LL | | ) | |_____^ type mismatch resolving ` as Future>::Error == Foo` | note: expected this to be `Foo` - --> $DIR/E0271.rs:10:18 + --> $DIR/E0271.rs:9:18 | LL | type Error = E; | ^ = note: required for the cast from `Box>` to `Box<...>` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/E0271.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs index 061877210414..522bfb5b93fe 100644 --- a/tests/ui/diagnostic-width/E0271.rs +++ b/tests/ui/diagnostic-width/E0271.rs @@ -1,7 +1,6 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=40 -Zwrite-long-types-to-disk=yes //@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 -Zwrite-long-types-to-disk=yes -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" trait Future { type Error; } diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr index 9c3deae66608..91adf8341016 100644 --- a/tests/ui/diagnostic-width/E0271.unicode.stderr +++ b/tests/ui/diagnostic-width/E0271.unicode.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving ` as Future>::Error == Foo` - ╭▸ $DIR/E0271.rs:20:5 + ╭▸ $DIR/E0271.rs:19:5 │ LL │ ┏ Box::new( LL │ ┃ Ok::<_, ()>( @@ -10,12 +10,12 @@ LL │ ┃ ) │ ┗━━━━━┛ type mismatch resolving ` as Future>::Error == Foo` ╰╴ note: expected this to be `Foo` - ╭▸ $DIR/E0271.rs:10:18 + ╭▸ $DIR/E0271.rs:9:18 │ LL │ type Error = E; │ ━ ├ note: required for the cast from `Box>` to `Box<...>` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/E0271.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/binop.rs b/tests/ui/diagnostic-width/binop.rs index 60ba40b8047f..9e4e837f3869 100644 --- a/tests/ui/diagnostic-width/binop.rs +++ b/tests/ui/diagnostic-width/binop.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/binop.stderr b/tests/ui/diagnostic-width/binop.stderr index fd69129c33e4..92723df5a9b3 100644 --- a/tests/ui/diagnostic-width/binop.stderr +++ b/tests/ui/diagnostic-width/binop.stderr @@ -1,21 +1,21 @@ error[E0369]: cannot add `(..., ..., ..., ...)` to `(..., ..., ..., ...)` - --> $DIR/binop.rs:10:7 + --> $DIR/binop.rs:8:7 | LL | x + x; | - ^ - (..., ..., ..., ...) | | | (..., ..., ..., ...) | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/binop.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error[E0600]: cannot apply unary operator `!` to type `(..., ..., ..., ...)` - --> $DIR/binop.rs:14:5 + --> $DIR/binop.rs:12:5 | LL | !x; | ^^ cannot apply unary operator `!` | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/binop.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 2 previous errors diff --git a/tests/ui/diagnostic-width/long-E0308.ascii.stderr b/tests/ui/diagnostic-width/long-E0308.ascii.stderr index 83da55861887..d1fdd6c44335 100644 --- a/tests/ui/diagnostic-width/long-E0308.ascii.stderr +++ b/tests/ui/diagnostic-width/long-E0308.ascii.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/long-E0308.rs:48:9 + --> $DIR/long-E0308.rs:45:9 | LL | let x: Atype< | _____________- @@ -20,11 +20,11 @@ LL | | )))))))))))))))))))))))))))))); | = note: expected struct `Atype, i32>` found enum `Result, _>` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - --> $DIR/long-E0308.rs:61:26 + --> $DIR/long-E0308.rs:58:26 | LL | ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O... | __________________________^ @@ -36,11 +36,11 @@ LL | | )))))))))))))))))))))))); | = note: expected enum `Option, _>>` found enum `Result, _>` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - --> $DIR/long-E0308.rs:92:9 + --> $DIR/long-E0308.rs:89:9 | LL | let x: Atype< | ____________- @@ -56,11 +56,11 @@ LL | | > = (); | = note: expected struct `Atype, i32>` found unit type `()` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - --> $DIR/long-E0308.rs:95:17 + --> $DIR/long-E0308.rs:92:17 | LL | let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O... | ____________--___^ @@ -74,7 +74,7 @@ LL | | )))))))))))))))))))))))); | = note: expected unit type `()` found enum `Result, _>` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 4 previous errors diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs index 26383d9418dd..94e525e387ef 100644 --- a/tests/ui/diagnostic-width/long-E0308.rs +++ b/tests/ui/diagnostic-width/long-E0308.rs @@ -2,9 +2,6 @@ //@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes //@[unicode] compile-flags: -Zunstable-options --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" - mod a { // Force the "short path for unique types" machinery to trip up pub struct Atype; diff --git a/tests/ui/diagnostic-width/long-E0308.unicode.stderr b/tests/ui/diagnostic-width/long-E0308.unicode.stderr index 54abf576dbd0..69e5ca100671 100644 --- a/tests/ui/diagnostic-width/long-E0308.unicode.stderr +++ b/tests/ui/diagnostic-width/long-E0308.unicode.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:48:9 + ╭▸ $DIR/long-E0308.rs:45:9 │ LL │ let x: Atype< │ ┌─────────────┘ @@ -20,11 +20,11 @@ LL │ ┃ )))))))))))))))))))))))))))))); │ ├ note: expected struct `Atype, i32>` │ found enum `Result, _>` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:61:26 + ╭▸ $DIR/long-E0308.rs:58:26 │ LL │ ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(… │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┛ @@ -36,11 +36,11 @@ LL │ ┃ )))))))))))))))))))))))); │ ├ note: expected enum `Option, _>>` │ found enum `Result, _>` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:92:9 + ╭▸ $DIR/long-E0308.rs:89:9 │ LL │ let x: Atype< │ ┌────────────┘ @@ -56,11 +56,11 @@ LL │ │ > = (); │ ├ note: expected struct `Atype, i32>` │ found unit type `()` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:95:17 + ╭▸ $DIR/long-E0308.rs:92:17 │ LL │ let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(… │ ┏━━━━━━━━━━━━┬─━━━┛ @@ -74,7 +74,7 @@ LL │ ┃ )))))))))))))))))))))))); │ ├ note: expected unit type `()` │ found enum `Result, _>` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error: aborting due to 4 previous errors diff --git a/tests/ui/diagnostic-width/long-E0529.rs b/tests/ui/diagnostic-width/long-E0529.rs index 3ebc4f5f8c82..759a902da7e6 100644 --- a/tests/ui/diagnostic-width/long-E0529.rs +++ b/tests/ui/diagnostic-width/long-E0529.rs @@ -1,6 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-E0529.stderr b/tests/ui/diagnostic-width/long-E0529.stderr index da03e5fab2ca..bf3144cc9b67 100644 --- a/tests/ui/diagnostic-width/long-E0529.stderr +++ b/tests/ui/diagnostic-width/long-E0529.stderr @@ -1,10 +1,10 @@ error[E0529]: expected an array or slice, found `(..., ..., ..., ...)` - --> $DIR/long-E0529.rs:10:9 + --> $DIR/long-E0529.rs:9:9 | LL | let [] = x; | ^^ pattern cannot match with input type `(..., ..., ..., ...)` | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0529.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-E0609.rs b/tests/ui/diagnostic-width/long-E0609.rs index 39442bdeae03..a26d16ad12e7 100644 --- a/tests/ui/diagnostic-width/long-E0609.rs +++ b/tests/ui/diagnostic-width/long-E0609.rs @@ -1,6 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-E0609.stderr b/tests/ui/diagnostic-width/long-E0609.stderr index 6815caa6b6ba..36ef85457468 100644 --- a/tests/ui/diagnostic-width/long-E0609.stderr +++ b/tests/ui/diagnostic-width/long-E0609.stderr @@ -1,10 +1,10 @@ error[E0609]: no field `field` on type `(..., ..., ..., ...)` - --> $DIR/long-E0609.rs:10:7 + --> $DIR/long-E0609.rs:9:7 | LL | x.field; | ^^^^^ unknown field | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0609.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-E0614.rs b/tests/ui/diagnostic-width/long-E0614.rs index 0b78444a00d2..5e8b3324dd17 100644 --- a/tests/ui/diagnostic-width/long-E0614.rs +++ b/tests/ui/diagnostic-width/long-E0614.rs @@ -1,6 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-E0614.stderr b/tests/ui/diagnostic-width/long-E0614.stderr index 1c16ff617faa..18da20da9453 100644 --- a/tests/ui/diagnostic-width/long-E0614.stderr +++ b/tests/ui/diagnostic-width/long-E0614.stderr @@ -1,10 +1,10 @@ error[E0614]: type `(..., ..., ..., ...)` cannot be dereferenced - --> $DIR/long-E0614.rs:10:5 + --> $DIR/long-E0614.rs:9:5 | LL | *x; | ^^ can't be dereferenced | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0614.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-E0618.rs b/tests/ui/diagnostic-width/long-E0618.rs index f8626ab9455e..b499bedc394a 100644 --- a/tests/ui/diagnostic-width/long-E0618.rs +++ b/tests/ui/diagnostic-width/long-E0618.rs @@ -1,6 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-E0618.stderr b/tests/ui/diagnostic-width/long-E0618.stderr index f0838cbddcc6..05bf999c1422 100644 --- a/tests/ui/diagnostic-width/long-E0618.stderr +++ b/tests/ui/diagnostic-width/long-E0618.stderr @@ -1,5 +1,5 @@ error[E0618]: expected function, found `(..., ..., ..., ...)` - --> $DIR/long-E0618.rs:10:5 + --> $DIR/long-E0618.rs:9:5 | LL | fn foo(x: D) { | - `x` has type `(..., ..., ..., ...)` @@ -8,7 +8,7 @@ LL | x(); | | | call expression requires function | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0618.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-e0277.rs b/tests/ui/diagnostic-width/long-e0277.rs index 9b3bd8bb7289..369fd8daea78 100644 --- a/tests/ui/diagnostic-width/long-e0277.rs +++ b/tests/ui/diagnostic-width/long-e0277.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-e0277.stderr b/tests/ui/diagnostic-width/long-e0277.stderr index a57270df7e25..ff8971511653 100644 --- a/tests/ui/diagnostic-width/long-e0277.stderr +++ b/tests/ui/diagnostic-width/long-e0277.stderr @@ -1,21 +1,21 @@ error[E0277]: the trait bound `(..., ..., ..., ...): Trait` is not satisfied - --> $DIR/long-e0277.rs:14:21 + --> $DIR/long-e0277.rs:12:21 | LL | require_trait::(); | ^ unsatisfied trait bound | = help: the trait `Trait` is not implemented for `(..., ..., ..., ...)` help: this trait has no implementations, consider adding one - --> $DIR/long-e0277.rs:9:1 + --> $DIR/long-e0277.rs:7:1 | LL | trait Trait {} | ^^^^^^^^^^^ note: required by a bound in `require_trait` - --> $DIR/long-e0277.rs:11:21 + --> $DIR/long-e0277.rs:9:21 | LL | fn require_trait() {} | ^^^^^ required by this bound in `require_trait` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-e0277.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.rs b/tests/ui/diagnostic-width/non-copy-type-moved.rs index a220c62775eb..845457f7e30f 100644 --- a/tests/ui/diagnostic-width/non-copy-type-moved.rs +++ b/tests/ui/diagnostic-width/non-copy-type-moved.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" type A = (String, String, String, String); type B = (A, A, A, A); diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.stderr b/tests/ui/diagnostic-width/non-copy-type-moved.stderr index 254542c7b390..16c01c858b7d 100644 --- a/tests/ui/diagnostic-width/non-copy-type-moved.stderr +++ b/tests/ui/diagnostic-width/non-copy-type-moved.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/non-copy-type-moved.rs:16:14 + --> $DIR/non-copy-type-moved.rs:14:14 | LL | fn foo(x: D) { | - move occurs because `x` has type `(..., ..., ..., ...)`, which does not implement the `Copy` trait @@ -8,7 +8,7 @@ LL | let _a = x; LL | let _b = x; | ^ value used here after move | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/non-copy-type-moved.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console help: consider cloning the value if the performance cost is acceptable | diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs index c8845af31835..13fe967ba5f8 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=100 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" type A = (i32, i32, i32, i32); type B = (A, A, A, A); diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr index a95e17091489..a99657ca113f 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/secondary-label-with-long-type.rs:11:9 + --> $DIR/secondary-label-with-long-type.rs:9:9 | LL | let () = x; | ^^ - this expression has type `((..., ..., ..., ...), ..., ..., ...)` @@ -8,7 +8,7 @@ LL | let () = x; | = note: expected tuple `((..., ..., ..., ...), ..., ..., ...)` found unit type `()` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/secondary-label-with-long-type.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0275.rs b/tests/ui/error-codes/E0275.rs index df7b606155eb..28a9676f03e3 100644 --- a/tests/ui/error-codes/E0275.rs +++ b/tests/ui/error-codes/E0275.rs @@ -1,4 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Foo {} struct Bar(T); diff --git a/tests/ui/error-codes/E0275.stderr b/tests/ui/error-codes/E0275.stderr index b50754083406..3b31c87320ae 100644 --- a/tests/ui/error-codes/E0275.stderr +++ b/tests/ui/error-codes/E0275.stderr @@ -1,12 +1,12 @@ error[E0275]: overflow evaluating the requirement `Bar>>>>>>: Foo` - --> $DIR/E0275.rs:6:33 + --> $DIR/E0275.rs:5:33 | LL | impl Foo for T where Bar: Foo {} | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`) note: required for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo` - --> $DIR/E0275.rs:6:9 + --> $DIR/E0275.rs:5:9 | LL | impl Foo for T where Bar: Foo {} | ^^^ ^ --- unsatisfied trait bound introduced here diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs index 7b6ba9f7f169..e22a49d03993 100644 --- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs +++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs @@ -1,5 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" - fn id( f: &dyn Fn(u32), ) -> &dyn Fn( diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr index be2eca3e61ad..00a5948bdd47 100644 --- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/hang-on-deeply-nested-dyn.rs:12:5 + --> $DIR/hang-on-deeply-nested-dyn.rs:10:5 | LL | ) -> &dyn Fn( | ______- diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs index f880749ec835..ff6f4861e144 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs @@ -1,5 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" - // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream` // should act as assertion that item does not borrow from its stream; // but an earlier buggy rustc allowed `.map(|x: &_| x)` which does diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr index ae364de8cc06..240e1c3dde1a 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr @@ -1,5 +1,5 @@ -error[E0599]: the method `filterx` exists for struct `Map`, but its trait bounds were not satisfied - --> $DIR/hrtb-doesnt-borrow-self-1.rs:116:22 +error[E0599]: the method `filterx` exists for struct `Map`, but its trait bounds were not satisfied + --> $DIR/hrtb-doesnt-borrow-self-1.rs:114:22 | LL | pub struct Map { | -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt` @@ -8,16 +8,16 @@ LL | let filter = map.filterx(|x: &_| true); | ^^^^^^^ method cannot be called due to unsatisfied trait bounds | note: the following trait bounds were not satisfied: - `&'a mut &Map: Stream` - `&'a mut &mut Map: Stream` - `&'a mut Map: Stream` - --> $DIR/hrtb-doesnt-borrow-self-1.rs:98:50 + `&'a mut &Map: Stream` + `&'a mut &mut Map: Stream` + `&'a mut Map: Stream` + --> $DIR/hrtb-doesnt-borrow-self-1.rs:96:50 | LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} | --------- - ^^^^^^ unsatisfied trait bound introduced here = help: items from traits can only be used if the trait is implemented and in scope note: `StreamExt` defines an item `filterx`, perhaps you need to implement it - --> $DIR/hrtb-doesnt-borrow-self-1.rs:66:1 + --> $DIR/hrtb-doesnt-borrow-self-1.rs:64:1 | LL | pub trait StreamExt | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs index ff4c0cf24d69..d8a1f3fa69e4 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs @@ -1,5 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" - // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream &u64 {identity::}>, {closure@hrtb-doesnt-borrow-self-2.rs:111:30}>`, but its trait bounds were not satisfied - --> $DIR/hrtb-doesnt-borrow-self-2.rs:112:24 +error[E0599]: the method `countx` exists for struct `Filter &u64 {identity::}>, {closure@hrtb-doesnt-borrow-self-2.rs:109:30}>`, but its trait bounds were not satisfied + --> $DIR/hrtb-doesnt-borrow-self-2.rs:110:24 | LL | pub struct Filter { | ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt` @@ -8,16 +8,16 @@ LL | let count = filter.countx(); | ^^^^^^ method cannot be called due to unsatisfied trait bounds | note: the following trait bounds were not satisfied: - `&'a mut &Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream` - `&'a mut &mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream` - `&'a mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream` - --> $DIR/hrtb-doesnt-borrow-self-2.rs:98:50 + `&'a mut &Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream` + `&'a mut &mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream` + `&'a mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream` + --> $DIR/hrtb-doesnt-borrow-self-2.rs:96:50 | LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} | --------- - ^^^^^^ unsatisfied trait bound introduced here = help: items from traits can only be used if the trait is implemented and in scope note: `StreamExt` defines an item `countx`, perhaps you need to implement it - --> $DIR/hrtb-doesnt-borrow-self-2.rs:66:1 + --> $DIR/hrtb-doesnt-borrow-self-2.rs:64:1 | LL | pub trait StreamExt | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs index 62fc079d9d97..e28b8f373dab 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs @@ -3,9 +3,6 @@ //@ error-pattern: reached the recursion limit while instantiating //@ error-pattern: reached the recursion limit finding the struct tail -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" - // Regression test for #114484: This used to ICE during monomorphization, because we treated // ` as Pointee>::Metadata` as a rigid projection after reaching the recursion // limit when finding the struct tail. diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr index b67e000bf74a..475e26fd0f06 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr @@ -18,7 +18,7 @@ error: reached the recursion limit finding the struct tail for `[u8; 256]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ error: reached the recursion limit finding the struct tail for `SomeData<256>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ error: reached the recursion limit finding the struct tail for `VirtualWrapper, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -76,11 +76,11 @@ LL | unsafe { virtualize_my_trait(L, self) } error: reached the recursion limit while instantiating `, 1>, 1>, 1>, 1> as MyTrait>::virtualize` | note: ` as MyTrait>::virtualize` defined here - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:28:5 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:5 | LL | fn virtualize(&self) -> &dyn MyTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/infinite-instantiation-struct-tail-ice-114484.long-type.txt' error: aborting due to 13 previous errors diff --git a/tests/ui/infinite/infinite-instantiation.rs b/tests/ui/infinite/infinite-instantiation.rs index d5cb8e79592f..7898cc1ffc10 100644 --- a/tests/ui/infinite/infinite-instantiation.rs +++ b/tests/ui/infinite/infinite-instantiation.rs @@ -1,6 +1,4 @@ //@ build-fail -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" trait ToOpt: Sized { fn to_option(&self) -> Option; diff --git a/tests/ui/infinite/infinite-instantiation.stderr b/tests/ui/infinite/infinite-instantiation.stderr index 71c745cf5eb8..d7a4a49961a6 100644 --- a/tests/ui/infinite/infinite-instantiation.stderr +++ b/tests/ui/infinite/infinite-instantiation.stderr @@ -1,15 +1,15 @@ error: reached the recursion limit while instantiating `function::>>>>>` - --> $DIR/infinite-instantiation.rs:23:9 + --> $DIR/infinite-instantiation.rs:21:9 | LL | function(counter - 1, t.to_option()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `function` defined here - --> $DIR/infinite-instantiation.rs:21:1 + --> $DIR/infinite-instantiation.rs:19:1 | LL | fn function(counter: usize, t: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/infinite-instantiation.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-20413.rs b/tests/ui/issues/issue-20413.rs index 7766f3755993..138a235e675e 100644 --- a/tests/ui/issues/issue-20413.rs +++ b/tests/ui/issues/issue-20413.rs @@ -1,4 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Foo { fn answer(self); } diff --git a/tests/ui/issues/issue-20413.stderr b/tests/ui/issues/issue-20413.stderr index 5d442eb98985..42f3cd2d0627 100644 --- a/tests/ui/issues/issue-20413.stderr +++ b/tests/ui/issues/issue-20413.stderr @@ -1,5 +1,5 @@ error[E0392]: type parameter `T` is never used - --> $DIR/issue-20413.rs:6:15 + --> $DIR/issue-20413.rs:5:15 | LL | struct NoData; | ^ unused type parameter @@ -8,14 +8,14 @@ LL | struct NoData; = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error[E0275]: overflow evaluating the requirement `NoData>>>>>>: Foo` - --> $DIR/issue-20413.rs:9:36 + --> $DIR/issue-20413.rs:8:36 | LL | impl Foo for T where NoData: Foo { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) note: required for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo` - --> $DIR/issue-20413.rs:9:9 + --> $DIR/issue-20413.rs:8:9 | LL | impl Foo for T where NoData: Foo { | ^^^ ^ --- unsatisfied trait bound introduced here @@ -23,19 +23,19 @@ LL | impl Foo for T where NoData: Foo { = note: required for `NoData` to implement `Foo` error[E0275]: overflow evaluating the requirement `AlmostNoData>>>>>>: Bar` - --> $DIR/issue-20413.rs:28:42 + --> $DIR/issue-20413.rs:27:42 | LL | impl Bar for T where EvenLessData: Baz { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) note: required for `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz` - --> $DIR/issue-20413.rs:35:9 + --> $DIR/issue-20413.rs:34:9 | LL | impl Baz for T where AlmostNoData: Bar { | ^^^ ^ --- unsatisfied trait bound introduced here note: required for `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar` - --> $DIR/issue-20413.rs:28:9 + --> $DIR/issue-20413.rs:27:9 | LL | impl Bar for T where EvenLessData: Baz { | ^^^ ^ --- unsatisfied trait bound introduced here @@ -43,19 +43,19 @@ LL | impl Bar for T where EvenLessData: Baz { = note: required for `EvenLessData` to implement `Baz` error[E0275]: overflow evaluating the requirement `EvenLessData>>>>>>: Baz` - --> $DIR/issue-20413.rs:35:42 + --> $DIR/issue-20413.rs:34:42 | LL | impl Baz for T where AlmostNoData: Bar { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) note: required for `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar` - --> $DIR/issue-20413.rs:28:9 + --> $DIR/issue-20413.rs:27:9 | LL | impl Bar for T where EvenLessData: Baz { | ^^^ ^ --- unsatisfied trait bound introduced here note: required for `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz` - --> $DIR/issue-20413.rs:35:9 + --> $DIR/issue-20413.rs:34:9 | LL | impl Baz for T where AlmostNoData: Bar { | ^^^ ^ --- unsatisfied trait bound introduced here diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs index ebaf244ac9c2..05adde452044 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs @@ -1,6 +1,4 @@ //@ build-fail -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" trait Mirror { type Image; diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr index fbbf80021bee..945fa605e140 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr @@ -1,15 +1,15 @@ error: reached the recursion limit while instantiating `<(&(&(..., ...), ...), ...) as Foo>::recurse` - --> $DIR/issue-37311.rs:18:9 + --> $DIR/issue-37311.rs:16:9 | LL | (self, self).recurse(); | ^^^^^^^^^^^^^^^^^^^^^^ | note: `::recurse` defined here - --> $DIR/issue-37311.rs:17:5 + --> $DIR/issue-37311.rs:15:5 | LL | fn recurse(&self) { | ^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/issue-37311.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs index 8c7e95bd2e3e..53f0e931d60b 100644 --- a/tests/ui/issues/issue-67552.rs +++ b/tests/ui/issues/issue-67552.rs @@ -1,7 +1,5 @@ //@ build-fail //@ compile-flags: -Copt-level=0 -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" fn main() { rec(Empty); diff --git a/tests/ui/issues/issue-67552.stderr b/tests/ui/issues/issue-67552.stderr index f94cd78c8701..def0a29f3e51 100644 --- a/tests/ui/issues/issue-67552.stderr +++ b/tests/ui/issues/issue-67552.stderr @@ -1,17 +1,17 @@ error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>` - --> $DIR/issue-67552.rs:30:9 + --> $DIR/issue-67552.rs:28:9 | LL | rec(identity(&mut it)) | ^^^^^^^^^^^^^^^^^^^^^^ | note: `rec` defined here - --> $DIR/issue-67552.rs:23:1 + --> $DIR/issue-67552.rs:21:1 | LL | / fn rec(mut it: T) LL | | where LL | | T: Iterator, | |________________^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/issue-67552.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-8727.rs b/tests/ui/issues/issue-8727.rs index 7767729109ea..1883287f1407 100644 --- a/tests/ui/issues/issue-8727.rs +++ b/tests/ui/issues/issue-8727.rs @@ -2,8 +2,6 @@ // recursions. //@ build-fail -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" fn generic() { //~ WARN function cannot return without recursing generic::>(); diff --git a/tests/ui/issues/issue-8727.stderr b/tests/ui/issues/issue-8727.stderr index 22286eb8d7be..04158962a010 100644 --- a/tests/ui/issues/issue-8727.stderr +++ b/tests/ui/issues/issue-8727.stderr @@ -1,5 +1,5 @@ warning: function cannot return without recursing - --> $DIR/issue-8727.rs:8:1 + --> $DIR/issue-8727.rs:6:1 | LL | fn generic() { | ^^^^^^^^^^^^^^^ cannot return without recursing @@ -10,17 +10,17 @@ LL | generic::>(); = note: `#[warn(unconditional_recursion)]` on by default error: reached the recursion limit while instantiating `generic::>>>>>` - --> $DIR/issue-8727.rs:9:5 + --> $DIR/issue-8727.rs:7:5 | LL | generic::>(); | ^^^^^^^^^^^^^^^^^^^^^^ | note: `generic` defined here - --> $DIR/issue-8727.rs:8:1 + --> $DIR/issue-8727.rs:6:1 | LL | fn generic() { | ^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/issue-8727.long-type.txt' error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/methods/inherent-bound-in-probe.rs b/tests/ui/methods/inherent-bound-in-probe.rs index 9b9eb91559b3..4add93e808d2 100644 --- a/tests/ui/methods/inherent-bound-in-probe.rs +++ b/tests/ui/methods/inherent-bound-in-probe.rs @@ -1,5 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" - // Fixes #110131 // // The issue is that we were constructing an `ImplDerived` cause code for the diff --git a/tests/ui/methods/inherent-bound-in-probe.stderr b/tests/ui/methods/inherent-bound-in-probe.stderr index 433ef02a2aa4..77aed390c9ac 100644 --- a/tests/ui/methods/inherent-bound-in-probe.stderr +++ b/tests/ui/methods/inherent-bound-in-probe.stderr @@ -1,5 +1,5 @@ error[E0277]: `Helper<'a, T>` is not an iterator - --> $DIR/inherent-bound-in-probe.rs:40:21 + --> $DIR/inherent-bound-in-probe.rs:38:21 | LL | type IntoIter = Helper<'a, T>; | ^^^^^^^^^^^^^ `Helper<'a, T>` is not an iterator @@ -9,14 +9,14 @@ note: required by a bound in `std::iter::IntoIterator::IntoIter` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL error[E0275]: overflow evaluating the requirement `&_: IntoIterator` - --> $DIR/inherent-bound-in-probe.rs:44:9 + --> $DIR/inherent-bound-in-probe.rs:42:9 | LL | Helper::new(&self.0) | ^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_bound_in_probe`) note: required for `&BitReaderWrapper<_>` to implement `IntoIterator` - --> $DIR/inherent-bound-in-probe.rs:34:13 + --> $DIR/inherent-bound-in-probe.rs:32:13 | LL | impl<'a, T> IntoIterator for &'a BitReaderWrapper | ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | &'a T: IntoIterator, = note: 126 redundant requirements hidden = note: required for `&BitReaderWrapper>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `IntoIterator` note: required by a bound in `Helper` - --> $DIR/inherent-bound-in-probe.rs:18:12 + --> $DIR/inherent-bound-in-probe.rs:16:12 | LL | struct Helper<'a, T> | ------ required by a bound in this struct diff --git a/tests/ui/recursion/issue-23122-2.rs b/tests/ui/recursion/issue-23122-2.rs index 3e14fa92dd0f..95e1f60d8b02 100644 --- a/tests/ui/recursion/issue-23122-2.rs +++ b/tests/ui/recursion/issue-23122-2.rs @@ -1,4 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Next { type Next: Next; } diff --git a/tests/ui/recursion/issue-23122-2.stderr b/tests/ui/recursion/issue-23122-2.stderr index 10463ab2c33f..c5774cc18882 100644 --- a/tests/ui/recursion/issue-23122-2.stderr +++ b/tests/ui/recursion/issue-23122-2.stderr @@ -1,12 +1,12 @@ error[E0275]: overflow evaluating the requirement `<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized` - --> $DIR/issue-23122-2.rs:11:17 + --> $DIR/issue-23122-2.rs:10:17 | LL | type Next = as Next>::Next; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`) note: required for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` - --> $DIR/issue-23122-2.rs:10:15 + --> $DIR/issue-23122-2.rs:9:15 | LL | impl Next for GetNext { | - ^^^^ ^^^^^^^^^^ diff --git a/tests/ui/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs index ea1bef4fce39..b720c168187b 100644 --- a/tests/ui/recursion/issue-83150.rs +++ b/tests/ui/recursion/issue-83150.rs @@ -1,7 +1,6 @@ -//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>: Iterator` +//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` //@ build-fail //@ compile-flags: -Copt-level=0 -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" fn main() { let mut iter = 0u8..1; diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr index 92a39a44e4fa..600922f1e57a 100644 --- a/tests/ui/recursion/issue-83150.stderr +++ b/tests/ui/recursion/issue-83150.stderr @@ -1,5 +1,5 @@ warning: function cannot return without recursing - --> $DIR/issue-83150.rs:11:1 + --> $DIR/issue-83150.rs:10:1 | LL | fn func>(iter: &mut T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -10,12 +10,12 @@ LL | func(&mut iter.map(|x| x + 1)) = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>: Iterator` +error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) - = note: required for `&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>` to implement `Iterator` + = note: required for `&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator` = note: 65 redundant requirements hidden - = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>` to implement `Iterator` + = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator` error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/recursion/recursion.rs b/tests/ui/recursion/recursion.rs index ce56fe974b7c..5cd4012a9d2d 100644 --- a/tests/ui/recursion/recursion.rs +++ b/tests/ui/recursion/recursion.rs @@ -1,7 +1,5 @@ //@ build-fail //@ compile-flags:-C overflow-checks=off -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" enum Nil {NilValue} struct Cons {head:isize, tail:T} diff --git a/tests/ui/recursion/recursion.stderr b/tests/ui/recursion/recursion.stderr index cb9f67ba7418..f959805defc6 100644 --- a/tests/ui/recursion/recursion.stderr +++ b/tests/ui/recursion/recursion.stderr @@ -1,15 +1,15 @@ error: reached the recursion limit while instantiating `test::>>>>>` - --> $DIR/recursion.rs:19:11 + --> $DIR/recursion.rs:17:11 | LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `test` defined here - --> $DIR/recursion.rs:17:1 + --> $DIR/recursion.rs:15:1 | LL | fn test (n:isize, i:isize, first:T, second:T) ->isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/recursion.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/regions/issue-102374.rs b/tests/ui/regions/issue-102374.rs index d640c29b2f4c..e0a1164211a2 100644 --- a/tests/ui/regions/issue-102374.rs +++ b/tests/ui/regions/issue-102374.rs @@ -1,4 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" use std::cell::Cell; #[rustfmt::skip] diff --git a/tests/ui/regions/issue-102374.stderr b/tests/ui/regions/issue-102374.stderr index e07dca0c7ee2..5416125d1c7b 100644 --- a/tests/ui/regions/issue-102374.stderr +++ b/tests/ui/regions/issue-102374.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-102374.rs:17:5 + --> $DIR/issue-102374.rs:16:5 | LL | ) -> i32 { | --- expected `i32` because of return type diff --git a/tests/ui/traits/on_unimplemented_long_types.rs b/tests/ui/traits/on_unimplemented_long_types.rs index c652b71e51ac..d6c3e8ef75fa 100644 --- a/tests/ui/traits/on_unimplemented_long_types.rs +++ b/tests/ui/traits/on_unimplemented_long_types.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=60 -Z write-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" pub fn foo() -> impl std::fmt::Display { //~^ ERROR doesn't implement `std::fmt::Display` diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr index 2705d7c501ec..1628466e0818 100644 --- a/tests/ui/traits/on_unimplemented_long_types.stderr +++ b/tests/ui/traits/on_unimplemented_long_types.stderr @@ -1,5 +1,5 @@ error[E0277]: `Option>>` doesn't implement `std::fmt::Display` - --> $DIR/on_unimplemented_long_types.rs:5:17 + --> $DIR/on_unimplemented_long_types.rs:3:17 | LL | pub fn foo() -> impl std::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^^ `Option>>` cannot be formatted with the default formatter @@ -15,7 +15,7 @@ LL | | ))))))))))) | = help: the trait `std::fmt::Display` is not implemented for `Option>>` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/on_unimplemented_long_types.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/type_length_limit.rs b/tests/ui/type_length_limit.rs index b629455aced7..87f5ffd76d7a 100644 --- a/tests/ui/type_length_limit.rs +++ b/tests/ui/type_length_limit.rs @@ -2,9 +2,6 @@ //@ compile-flags: -Copt-level=0 -Zenforce-type-length-limit //~^^ ERROR reached the type-length limit -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" - // Test that the type length limit can be changed. // The exact type depends on optimizations, so disable them. diff --git a/tests/ui/type_length_limit.stderr b/tests/ui/type_length_limit.stderr index d913b661c6f0..198d133c08c8 100644 --- a/tests/ui/type_length_limit.stderr +++ b/tests/ui/type_length_limit.stderr @@ -1,11 +1,11 @@ error: reached the type-length limit while instantiating `std::mem::drop::>` - --> $DIR/type_length_limit.rs:35:5 + --> $DIR/type_length_limit.rs:32:5 | LL | drop::>(None); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.long-type.txt' error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` | From 12cd0f11f0ff3408781f673fd903859ac412c71c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 11 Feb 2025 20:59:35 +0800 Subject: [PATCH 581/991] tests: rebless some tests as a side-effect of `TEST_BUILD_DIR` changes --- tests/ui/crate-loading/crateresolve1.stderr | 6 +++--- tests/ui/crate-loading/crateresolve2.stderr | 6 +++--- tests/ui/error-codes/E0462.stderr | 2 +- tests/ui/error-codes/E0464.stderr | 6 +++--- tests/ui/error-codes/E0523.stderr | 6 +++--- tests/ui/json/json-multiple.stderr | 2 +- tests/ui/json/json-options.stderr | 2 +- tests/ui/rmeta/emit-artifact-notifications.stderr | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/ui/crate-loading/crateresolve1.stderr b/tests/ui/crate-loading/crateresolve1.stderr index 47131a96bf43..b17330fb9d94 100644 --- a/tests/ui/crate-loading/crateresolve1.stderr +++ b/tests/ui/crate-loading/crateresolve1.stderr @@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found LL | extern crate crateresolve1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: candidate #1: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-1.somelib - = note: candidate #2: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-2.somelib - = note: candidate #3: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-3.somelib + = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib + = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib + = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib error: aborting due to 1 previous error diff --git a/tests/ui/crate-loading/crateresolve2.stderr b/tests/ui/crate-loading/crateresolve2.stderr index 3dc89dabde6d..0c488f3fd070 100644 --- a/tests/ui/crate-loading/crateresolve2.stderr +++ b/tests/ui/crate-loading/crateresolve2.stderr @@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rmeta` dependency `crateresolve2` found LL | extern crate crateresolve2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: candidate #1: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-1.rmeta - = note: candidate #2: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-2.rmeta - = note: candidate #3: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-3.rmeta + = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve2-1.rmeta + = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve2-2.rmeta + = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve2-3.rmeta error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0462.stderr b/tests/ui/error-codes/E0462.stderr index 18f20d79385e..be32001fad46 100644 --- a/tests/ui/error-codes/E0462.stderr +++ b/tests/ui/error-codes/E0462.stderr @@ -5,7 +5,7 @@ LL | extern crate found_staticlib; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the following crate versions were found: - crate `found_staticlib`: $TEST_BUILD_DIR/error-codes/E0462/auxiliary/libfound_staticlib.somelib + crate `found_staticlib`: $TEST_BUILD_DIR/auxiliary/libfound_staticlib.somelib = help: please recompile that crate using --crate-type lib error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0464.stderr b/tests/ui/error-codes/E0464.stderr index edb0b1cf41e1..ec18978a59ac 100644 --- a/tests/ui/error-codes/E0464.stderr +++ b/tests/ui/error-codes/E0464.stderr @@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found LL | extern crate crateresolve1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: candidate #1: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-1.somelib - = note: candidate #2: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-2.somelib - = note: candidate #3: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-3.somelib + = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib + = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib + = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0523.stderr b/tests/ui/error-codes/E0523.stderr index c6e65b55e2b3..f4072d691044 100644 --- a/tests/ui/error-codes/E0523.stderr +++ b/tests/ui/error-codes/E0523.stderr @@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found LL | extern crate crateresolve1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: candidate #1: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-1.somelib - = note: candidate #2: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-2.somelib - = note: candidate #3: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-3.somelib + = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib + = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib + = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib error: aborting due to 1 previous error diff --git a/tests/ui/json/json-multiple.stderr b/tests/ui/json/json-multiple.stderr index 7689fb94a6c8..e285817cffb9 100644 --- a/tests/ui/json/json-multiple.stderr +++ b/tests/ui/json/json-multiple.stderr @@ -1 +1 @@ -{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-multiple/libjson_multiple.rlib","emit":"link"} +{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/libjson_multiple.rlib","emit":"link"} diff --git a/tests/ui/json/json-options.stderr b/tests/ui/json/json-options.stderr index 668fc18097f0..fff4ec9a6df1 100644 --- a/tests/ui/json/json-options.stderr +++ b/tests/ui/json/json-options.stderr @@ -1 +1 @@ -{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-options/libjson_options.rlib","emit":"link"} +{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/libjson_options.rlib","emit":"link"} diff --git a/tests/ui/rmeta/emit-artifact-notifications.stderr b/tests/ui/rmeta/emit-artifact-notifications.stderr index 4f68a2d74ed3..c002be7bcff0 100644 --- a/tests/ui/rmeta/emit-artifact-notifications.stderr +++ b/tests/ui/rmeta/emit-artifact-notifications.stderr @@ -1 +1 @@ -{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/rmeta/emit-artifact-notifications/libemit_artifact_notifications.rmeta","emit":"metadata"} +{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/libemit_artifact_notifications.rmeta","emit":"metadata"} From 4f2a3dc196ff80f0fb535636296c4be5489ecd8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:43:19 +0800 Subject: [PATCH 582/991] tests: manually rebless `tests/ui-fulldeps/codegen-backend/hotplug.rs` --- tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout | 4 ++-- tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout b/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout index 4d58fd503d0a..5cf39ca3165d 100644 --- a/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout +++ b/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout @@ -1,4 +1,4 @@ -$TEST_BUILD_DIR/codegen-backend/hotplug.bindep/libhotplug.rlib: $DIR/hotplug.rs $TEST_BUILD_DIR/codegen-backend/hotplug.bindep/auxiliary/libthe_backend.so +$TEST_BUILD_DIR/libhotplug.rlib: $DIR/hotplug.rs $TEST_BUILD_DIR/auxiliary/libthe_backend.so $DIR/hotplug.rs: -$TEST_BUILD_DIR/codegen-backend/hotplug.bindep/auxiliary/libthe_backend.so: +$TEST_BUILD_DIR/auxiliary/libthe_backend.so: diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout b/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout index 48b7534d8faf..717439f14e1d 100644 --- a/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout +++ b/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout @@ -1,3 +1,3 @@ -$TEST_BUILD_DIR/codegen-backend/hotplug.dep/libhotplug.rlib: $DIR/hotplug.rs +$TEST_BUILD_DIR/libhotplug.rlib: $DIR/hotplug.rs $DIR/hotplug.rs: From 133705c402941c0825fe658a932289847478cf9f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 27 Feb 2025 20:54:26 +0800 Subject: [PATCH 583/991] [rustdoc] hide item that is not marked as doc(inline) and whose src is doc(hidden) Signed-off-by: xizheyin --- src/librustdoc/passes/strip_hidden.rs | 22 +++++++++++++++++-- tests/rustdoc/doc-hidden-reexports-109449.rs | 18 +++++++-------- tests/rustdoc/doc-hidden-source.rs | 16 ++++++++++++++ tests/rustdoc/inline_cross/inline_hidden.rs | 4 ++-- tests/rustdoc/reexport-attr-merge.rs | 4 ++-- .../reexport-doc-hidden-inside-private.rs | 4 ++-- tests/rustdoc/reexport-doc-hidden.rs | 4 ++-- tests/rustdoc/reexport-hidden-macro.rs | 2 +- tests/rustdoc/reexport-of-doc-hidden.rs | 12 +++++----- 9 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 tests/rustdoc/doc-hidden-source.rs diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index a71bb62e56c7..bcdca862862d 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -7,9 +7,8 @@ use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; use tracing::debug; -use crate::clean; use crate::clean::utils::inherits_doc_hidden; -use crate::clean::{Item, ItemIdSet}; +use crate::clean::{self, Item, ItemIdSet, reexport_chain}; use crate::core::DocContext; use crate::fold::{DocFolder, strip_item}; use crate::passes::{ImplStripper, Pass}; @@ -89,6 +88,25 @@ impl Stripper<'_, '_> { impl DocFolder for Stripper<'_, '_> { fn fold_item(&mut self, i: Item) -> Option { let has_doc_hidden = i.is_doc_hidden(); + + if let clean::ImportItem(clean::Import { source, .. }) = &i.kind + && let Some(source_did) = source.did + && let Some(import_def_id) = i.def_id().and_then(|def_id| def_id.as_local()) + { + let reexports = reexport_chain(self.tcx, import_def_id, source_did); + + // Check if any reexport in the chain has a hidden source + let has_hidden_source = reexports + .iter() + .filter_map(|reexport| reexport.id()) + .any(|reexport_did| self.tcx.is_doc_hidden(reexport_did)) + || self.tcx.is_doc_hidden(source_did); + + if has_hidden_source { + return None; + } + } + let is_impl_or_exported_macro = match i.kind { clean::ImplItem(..) => true, // If the macro has the `#[macro_export]` attribute, it means it's accessible at the diff --git a/tests/rustdoc/doc-hidden-reexports-109449.rs b/tests/rustdoc/doc-hidden-reexports-109449.rs index 8f195544120a..78b9214300a9 100644 --- a/tests/rustdoc/doc-hidden-reexports-109449.rs +++ b/tests/rustdoc/doc-hidden-reexports-109449.rs @@ -26,21 +26,21 @@ pub mod single_reexport { //@ has 'foo/single_reexport/index.html' // First we check that we have 4 type aliases. - //@ count - '//*[@id="main-content"]/*[@class="item-table reexports"]//code' 4 + //@ count - '//*[@id="main-content"]/*[@class="item-table reexports"]//code' 0 // Then we check that we have the correct link for each re-export. //@ !has - '//*[@href="struct.Foo.html"]' 'Foo' - //@ has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;' + //@ !has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;' pub use crate::private_module::Public as Foo; //@ !has - '//*[@href="type.Foo2.html"]' 'Foo2' - //@ has - '//*[@id="reexport.Foo2"]/code' 'pub use crate::private_module::Bar as Foo2;' + //@ !has - '//*[@id="reexport.Foo2"]/code' 'pub use crate::private_module::Bar as Foo2;' pub use crate::private_module::Bar as Foo2; //@ !has - '//*[@href="type.Yo.html"]' 'Yo' - //@ has - '//*[@id="reexport.Yo"]/code' 'pub use crate::Bar3 as Yo;' + //@ !has - '//*[@id="reexport.Yo"]/code' 'pub use crate::Bar3 as Yo;' pub use crate::Bar3 as Yo; //@ !has - '//*[@href="struct.Yo2.html"]' 'Yo2' - //@ has - '//*[@id="reexport.Yo2"]/code' 'pub use crate::FooFoo as Yo2;' + //@ !has - '//*[@id="reexport.Yo2"]/code' 'pub use crate::FooFoo as Yo2;' pub use crate::FooFoo as Yo2; // Checking that each file is also created as expected. @@ -70,19 +70,19 @@ pub mod single_reexport_no_inline { //@ has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports' // Now we check that we don't have links to the items, just `pub use`. - //@ has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;' + //@ !has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;' //@ !has - '//*[@id="main-content"]//a' 'XFoo' #[doc(no_inline)] pub use crate::private_module::Public as XFoo; - //@ has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Bar as Foo2;' + //@ !has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Bar as Foo2;' //@ !has - '//*[@id="main-content"]//a' 'Foo2' #[doc(no_inline)] pub use crate::private_module::Bar as Foo2; - //@ has - '//*[@id="main-content"]//*' 'pub use crate::Bar3 as Yo;' + //@ !has - '//*[@id="main-content"]//*' 'pub use crate::Bar3 as Yo;' //@ !has - '//*[@id="main-content"]//a' 'Yo' #[doc(no_inline)] pub use crate::Bar3 as Yo; - //@ has - '//*[@id="main-content"]//*' 'pub use crate::FooFoo as Yo2;' + //@ !has - '//*[@id="main-content"]//*' 'pub use crate::FooFoo as Yo2;' //@ !has - '//*[@id="main-content"]//a' 'Yo2' #[doc(no_inline)] pub use crate::FooFoo as Yo2; diff --git a/tests/rustdoc/doc-hidden-source.rs b/tests/rustdoc/doc-hidden-source.rs new file mode 100644 index 000000000000..b6bc622dd584 --- /dev/null +++ b/tests/rustdoc/doc-hidden-source.rs @@ -0,0 +1,16 @@ +// Test for . + +#![crate_name = "foo"] + +//@ has 'foo/index.html' +//@ !has - '//*[@id="main-content"]//*[@class="struct"]' 'Bar' +#[doc(hidden)] +pub struct Bar; + +//@ !has - '//*' 'pub use crate::Bar as A;' +pub use crate::Bar as A; +//@ !has - '//*' 'pub use crate::A as B;' +pub use crate::A as B; +//@ has - '//dt/a[@class="struct"]' 'C' +#[doc(inline)] +pub use crate::Bar as C; diff --git a/tests/rustdoc/inline_cross/inline_hidden.rs b/tests/rustdoc/inline_cross/inline_hidden.rs index 49ca2db6a224..f6727de2cc67 100644 --- a/tests/rustdoc/inline_cross/inline_hidden.rs +++ b/tests/rustdoc/inline_cross/inline_hidden.rs @@ -6,7 +6,7 @@ extern crate rustdoc_hidden; //@ has inline_hidden/index.html // Ensures this item is not inlined. -//@ has - '//*[@id="reexport.Foo"]/code' 'pub use rustdoc_hidden::Foo;' +//@ !has - '//*[@id="reexport.Foo"]/code' 'pub use rustdoc_hidden::Foo;' #[doc(no_inline)] pub use rustdoc_hidden::Foo; @@ -16,7 +16,7 @@ pub use rustdoc_hidden::Foo; pub use rustdoc_hidden::Foo as Inlined; // Even with this import, we should not see `Foo`. -//@ count - '//dt' 4 +//@ count - '//dt' 3 //@ has - '//dt/a[@class="struct"]' 'Bar' //@ has - '//dt/a[@class="fn"]' 'foo' pub use rustdoc_hidden::*; diff --git a/tests/rustdoc/reexport-attr-merge.rs b/tests/rustdoc/reexport-attr-merge.rs index e4a406c3845a..aef302eb0b29 100644 --- a/tests/rustdoc/reexport-attr-merge.rs +++ b/tests/rustdoc/reexport-attr-merge.rs @@ -18,7 +18,7 @@ pub use Foo1 as Foo2; // First we ensure that only the reexport `Bar2` and the inlined struct `Bar` // are inlined. -//@ count - '//a[@class="struct"]' 2 +//@ count - '//a[@class="struct"]' 1 // Then we check that `cfg` is displayed for base item, but not for intermediate re-exports. //@ has - '//*[@class="stab portability"]' 'foo' //@ !has - '//*[@class="stab portability"]' 'bar' @@ -29,5 +29,5 @@ pub use Foo2 as Bar; // This one should appear but `Bar2` won't be linked because there is no // `#[doc(inline)]`. -//@ has - '//*[@id="reexport.Bar2"]' 'pub use Foo2 as Bar2;' +//@ !has - '//*[@id="reexport.Bar2"]' 'pub use Foo2 as Bar2;' pub use Foo2 as Bar2; diff --git a/tests/rustdoc/reexport-doc-hidden-inside-private.rs b/tests/rustdoc/reexport-doc-hidden-inside-private.rs index 8e194ef74fb8..bae2aa78ec7a 100644 --- a/tests/rustdoc/reexport-doc-hidden-inside-private.rs +++ b/tests/rustdoc/reexport-doc-hidden-inside-private.rs @@ -9,8 +9,8 @@ mod private_module { } //@ has 'foo/index.html' -//@ has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;' +//@ !has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;' pub use crate::private_module::Public as Foo; // Glob re-exports with no visible items should not be displayed. -//@ count - '//*[@class="item-table reexports"]/dt' 1 +//@ count - '//*[@class="item-table reexports"]/dt' 0 pub use crate::private_module::*; diff --git a/tests/rustdoc/reexport-doc-hidden.rs b/tests/rustdoc/reexport-doc-hidden.rs index b912362f2987..1468e9ad957f 100644 --- a/tests/rustdoc/reexport-doc-hidden.rs +++ b/tests/rustdoc/reexport-doc-hidden.rs @@ -8,7 +8,7 @@ pub type Type = u32; //@ has 'foo/index.html' -//@ has - '//*[@id="reexport.Type2"]/code' 'pub use crate::Type as Type2;' +//@ !has - '//*[@id="reexport.Type2"]/code' 'pub use crate::Type as Type2;' pub use crate::Type as Type2; //@ count - '//*[@id="reexport.Type3"]' 0 @@ -21,5 +21,5 @@ macro_rules! foo { () => {}; } -//@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' +//@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' pub use crate::foo as Macro; diff --git a/tests/rustdoc/reexport-hidden-macro.rs b/tests/rustdoc/reexport-hidden-macro.rs index 9b83bca3906d..7345149c6452 100644 --- a/tests/rustdoc/reexport-hidden-macro.rs +++ b/tests/rustdoc/reexport-hidden-macro.rs @@ -5,7 +5,7 @@ //@ has 'foo/index.html' //@ has - '//*[@id="main-content"]//a[@href="macro.Macro2.html"]' 'Macro2' -//@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' +//@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' //@ has 'foo/macro.Macro2.html' //@ has - '//*[@class="docblock"]' 'Displayed' diff --git a/tests/rustdoc/reexport-of-doc-hidden.rs b/tests/rustdoc/reexport-of-doc-hidden.rs index 21511bc2aea9..e901d0ff8a2b 100644 --- a/tests/rustdoc/reexport-of-doc-hidden.rs +++ b/tests/rustdoc/reexport-of-doc-hidden.rs @@ -12,13 +12,13 @@ macro_rules! foo { } //@ has 'foo/index.html' -//@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' +//@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' pub use crate::foo as Macro; -//@ has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;' +//@ !has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;' pub use crate::foo as Macro2; -//@ has - '//*[@id="reexport.Boo"]/code' 'pub use crate::Bar as Boo;' +//@ !has - '//*[@id="reexport.Boo"]/code' 'pub use crate::Bar as Boo;' pub use crate::Bar as Boo; -//@ has - '//*[@id="reexport.Boo2"]/code' 'pub use crate::Bar as Boo2;' +//@ !has - '//*[@id="reexport.Boo2"]/code' 'pub use crate::Bar as Boo2;' pub use crate::Bar as Boo2; pub fn fofo() {} @@ -30,9 +30,9 @@ pub use crate::fofo as f2; pub mod sub { //@ has 'foo/sub/index.html' - //@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' + //@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' pub use crate::foo as Macro; - //@ has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;' + //@ !has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;' pub use crate::foo as Macro2; //@ has - '//*[@id="reexport.f1"]/code' 'pub use crate::fofo as f1;' From a23566a57e4d53a35827becc2f65ce27951276c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 28 Feb 2025 21:39:25 +0000 Subject: [PATCH 584/991] Provide more context on resolve error caused from incorrect RTN When encountering a resolve E0575 error for an associated method (when a type was expected), see if it could have been an intended return type notation bound. ``` error[E0575]: expected associated type, found associated function `Trait::method` --> $DIR/bad-inputs-and-output.rs:31:36 | LL | fn foo_qualified() where ::method(i32): Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type | help: you might have meant to use the return type notation syntax | LL - fn foo_qualified() where ::method(i32): Send {} LL + fn foo_qualified() where T::method(..): Send {} | ``` --- compiler/rustc_ast_lowering/src/lib.rs | 1 - compiler/rustc_ast_lowering/src/path.rs | 1 - compiler/rustc_resolve/src/late.rs | 18 +++++++-- .../rustc_resolve/src/late/diagnostics.rs | 39 +++++++++++++++++- .../bad-inputs-and-output.fixed | 40 +++++++++++++++++++ .../bad-inputs-and-output.rs | 3 +- .../bad-inputs-and-output.stderr | 38 +++++++++++++----- 7 files changed, 123 insertions(+), 17 deletions(-) create mode 100644 tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 13edcc10c9e2..2e175405da21 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -926,7 +926,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if let Some(first_char) = constraint.ident.as_str().chars().next() && first_char.is_ascii_lowercase() { - tracing::info!(?data, ?data.inputs); let err = match (&data.inputs[..], &data.output) { ([_, ..], FnRetTy::Default(_)) => { errors::BadReturnTypeNotation::Inputs { span: data.inputs_span } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 6b6244b05aa9..d00c797755f3 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -268,7 +268,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } GenericArgs::Parenthesized(data) => match generic_args_mode { GenericArgsMode::ReturnTypeNotation => { - tracing::info!(?data, ?data.inputs); let err = match (&data.inputs[..], &data.output) { ([_, ..], FnRetTy::Default(_)) => { BadReturnTypeNotation::Inputs { span: data.inputs_span } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f119ed55e7d1..50bc2feb477d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -623,7 +623,7 @@ pub(crate) struct UnnecessaryQualification<'ra> { pub removal_span: Span, } -#[derive(Default)] +#[derive(Default, Debug)] struct DiagMetadata<'ast> { /// The current trait's associated items' ident, used for diagnostic suggestions. current_trait_assoc_items: Option<&'ast [P]>, @@ -3146,6 +3146,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { PathSource::Trait(AliasPossibility::No), Finalize::new(trait_ref.ref_id, trait_ref.path.span), RecordPartialRes::Yes, + None, ); self.diag_metadata.currently_processing_impl_trait = None; if let Some(def_id) = res.expect_full_res().opt_def_id() { @@ -4072,6 +4073,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { source, Finalize::new(id, path.span), RecordPartialRes::Yes, + None, ); } @@ -4083,14 +4085,21 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { source: PathSource<'ast>, finalize: Finalize, record_partial_res: RecordPartialRes, + parent_qself: Option<&QSelf>, ) -> PartialRes { let ns = source.namespace(); let Finalize { node_id, path_span, .. } = finalize; let report_errors = |this: &mut Self, res: Option| { if this.should_report_errs() { - let (err, candidates) = - this.smart_resolve_report_errors(path, None, path_span, source, res); + let (err, candidates) = this.smart_resolve_report_errors( + path, + None, + path_span, + source, + res, + parent_qself, + ); let def_id = this.parent_scope.module.nearest_parent_mod(); let instead = res.is_some(); @@ -4159,6 +4168,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { path_span, PathSource::Type, None, + parent_qself, ); // There are two different error messages user might receive at @@ -4436,6 +4446,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { PathSource::Trait(AliasPossibility::No), Finalize::new(finalize.node_id, qself.path_span), RecordPartialRes::No, + Some(&qself), ); if trait_res.expect_full_res() == Res::Err { @@ -4460,6 +4471,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { PathSource::TraitItem(ns), Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span), RecordPartialRes::No, + Some(&qself), ); // The remaining segments (the `C` in our example) will diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0e14e7671b17..035f9abda86e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -35,7 +35,7 @@ use super::NoConstantGenericsReason; use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion}; use crate::late::{ AliasPossibility, LateResolutionVisitor, LifetimeBinderKind, LifetimeRes, LifetimeRibKind, - LifetimeUseSet, RibKind, + LifetimeUseSet, QSelf, RibKind, }; use crate::ty::fast_reject::SimplifiedType; use crate::{ @@ -421,6 +421,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { span: Span, source: PathSource<'_>, res: Option, + qself: Option<&QSelf>, ) -> (Diag<'tcx>, Vec) { debug!(?res, ?source); let base_error = self.make_base_error(path, span, source, res); @@ -453,6 +454,15 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { self.suggest_self_or_self_ref(&mut err, path, span); self.detect_assoc_type_constraint_meant_as_path(&mut err, &base_error); + self.detect_rtn_with_fully_qualified_path( + &mut err, + path, + following_seg, + span, + source, + res, + qself, + ); if self.suggest_self_ty(&mut err, source, path, span) || self.suggest_self_value(&mut err, source, path, span) { @@ -501,6 +511,33 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { (err, candidates) } + fn detect_rtn_with_fully_qualified_path( + &self, + err: &mut Diag<'_>, + path: &[Segment], + following_seg: Option<&Segment>, + span: Span, + source: PathSource<'_>, + res: Option, + qself: Option<&QSelf>, + ) { + if let Some(Res::Def(DefKind::AssocFn, _)) = res + && let PathSource::TraitItem(TypeNS) = source + && let None = following_seg + && let Some(qself) = qself + && let TyKind::Path(None, ty_path) = &qself.ty.kind + && ty_path.segments.len() == 1 + && self.diag_metadata.current_where_predicate.is_some() + { + err.span_suggestion_verbose( + span, + "you might have meant to use the return type notation syntax", + format!("{}::{}(..)", ty_path.segments[0].ident, path[path.len() - 1].ident), + Applicability::MaybeIncorrect, + ); + } + } + fn detect_assoc_type_constraint_meant_as_path( &self, err: &mut Diag<'_>, diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed new file mode 100644 index 000000000000..7af986267aa6 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed @@ -0,0 +1,40 @@ +//@ edition: 2021 +//@ run-rustfix +#![feature(return_type_notation)] +#![allow(dead_code)] + +trait Trait { + async fn method() {} +} + +fn foo>() {} +//~^ ERROR argument types not allowed with return type notation + +fn bar>() {} +//~^ ERROR return type not allowed with return type notation + +fn baz>() {} +//~^ ERROR return type notation arguments must be elided with `..` + +fn foo_path() where T::method(..): Send {} +//~^ ERROR argument types not allowed with return type notation + +fn bar_path() where T::method(..): Send {} +//~^ ERROR return type not allowed with return type notation + +fn bay_path() where T::method(..): Send {} +//~^ ERROR return type not allowed with return type notation + +fn baz_path() where T::method(..): Send {} +//~^ ERROR return type notation arguments must be elided with `..` + +fn foo_qualified() where T::method(..): Send {} +//~^ ERROR expected associated type + +fn bar_qualified() where T::method(..): Send {} +//~^ ERROR expected associated type + +fn baz_qualified() where T::method(..): Send {} +//~^ ERROR expected associated type + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs index 90fd2c2b4f32..983836e6433f 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -1,6 +1,7 @@ //@ edition: 2021 - +//@ run-rustfix #![feature(return_type_notation)] +#![allow(dead_code)] trait Trait { async fn method() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr index bd02b7d6534a..e1245a04c7f7 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -1,5 +1,5 @@ error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:24:45 + --> $DIR/bad-inputs-and-output.rs:25:45 | LL | fn bay_path() where T::method(..) -> (): Send {} | ^^^^^ @@ -11,25 +11,43 @@ LL + fn bay_path() where T::method(..): Send {} | error[E0575]: expected associated type, found associated function `Trait::method` - --> $DIR/bad-inputs-and-output.rs:30:36 + --> $DIR/bad-inputs-and-output.rs:31:36 | LL | fn foo_qualified() where ::method(i32): Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type + | +help: you might have meant to use the return type notation syntax + | +LL - fn foo_qualified() where ::method(i32): Send {} +LL + fn foo_qualified() where T::method(..): Send {} + | error[E0575]: expected associated type, found associated function `Trait::method` - --> $DIR/bad-inputs-and-output.rs:33:36 + --> $DIR/bad-inputs-and-output.rs:34:36 | LL | fn bar_qualified() where ::method() -> (): Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type + | +help: you might have meant to use the return type notation syntax + | +LL - fn bar_qualified() where ::method() -> (): Send {} +LL + fn bar_qualified() where T::method(..): Send {} + | error[E0575]: expected associated type, found associated function `Trait::method` - --> $DIR/bad-inputs-and-output.rs:36:36 + --> $DIR/bad-inputs-and-output.rs:37:36 | LL | fn baz_qualified() where ::method(): Send {} | ^^^^^^^^^^^^^^^^^^^^^^ not a associated type + | +help: you might have meant to use the return type notation syntax + | +LL - fn baz_qualified() where ::method(): Send {} +LL + fn baz_qualified() where T::method(..): Send {} + | error: argument types not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:9:23 + --> $DIR/bad-inputs-and-output.rs:10:23 | LL | fn foo>() {} | ^^^^^ @@ -41,7 +59,7 @@ LL + fn foo>() {} | error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:12:25 + --> $DIR/bad-inputs-and-output.rs:13:25 | LL | fn bar (): Send>>() {} | ^^^^^^ @@ -53,7 +71,7 @@ LL + fn bar>() {} | error: return type notation arguments must be elided with `..` - --> $DIR/bad-inputs-and-output.rs:15:23 + --> $DIR/bad-inputs-and-output.rs:16:23 | LL | fn baz>() {} | ^^ @@ -64,7 +82,7 @@ LL | fn baz>() {} | ++ error: argument types not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:18:40 + --> $DIR/bad-inputs-and-output.rs:19:40 | LL | fn foo_path() where T::method(i32): Send {} | ^^^^^ @@ -76,7 +94,7 @@ LL + fn foo_path() where T::method(..): Send {} | error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:21:42 + --> $DIR/bad-inputs-and-output.rs:22:42 | LL | fn bar_path() where T::method() -> (): Send {} | ^^^^^^ @@ -88,7 +106,7 @@ LL + fn bar_path() where T::method(..): Send {} | error: return type notation arguments must be elided with `..` - --> $DIR/bad-inputs-and-output.rs:27:40 + --> $DIR/bad-inputs-and-output.rs:28:40 | LL | fn baz_path() where T::method(): Send {} | ^^ From dfed028e788702a313ad49754e5d7ec64ffa61cf Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Mon, 3 Mar 2025 19:59:12 +0100 Subject: [PATCH 585/991] Always allow rustdoc-json tests to contain long lines The rustdoc-json test syntax often requires very long lines, so the checks for long lines aren't really useful. --- src/tools/tidy/src/style.rs | 21 +++++++++++++++---- .../rustdoc-json/enums/discriminant/limits.rs | 1 - .../discriminant/num_underscore_and_suffix.rs | 2 -- .../only_some_have_discriminant.rs | 2 -- .../rustdoc-json/enums/discriminant/struct.rs | 2 -- .../rustdoc-json/enums/discriminant/tuple.rs | 2 -- tests/rustdoc-json/enums/kind.rs | 2 -- tests/rustdoc-json/fn_pointer/abi.rs | 2 -- tests/rustdoc-json/fn_pointer/generics.rs | 2 -- tests/rustdoc-json/fn_pointer/qualifiers.rs | 2 -- tests/rustdoc-json/fns/abi.rs | 2 -- tests/rustdoc-json/fns/async_return.rs | 1 - tests/rustdoc-json/fns/generic_args.rs | 2 -- tests/rustdoc-json/fns/generic_returns.rs | 2 -- tests/rustdoc-json/fns/generics.rs | 2 -- .../generic-associated-types/gats.rs | 2 -- .../rustdoc-json/impl-trait-in-assoc-type.rs | 1 - tests/rustdoc-json/lifetime/longest.rs | 2 -- tests/rustdoc-json/lifetime/outlives.rs | 2 -- .../lifetime/outlives_in_param.rs | 2 -- .../lifetime/outlives_in_where.rs | 2 -- tests/rustdoc-json/methods/abi.rs | 2 -- tests/rustdoc-json/non_lifetime_binders.rs | 2 -- tests/rustdoc-json/path_name.rs | 1 - .../reexport/doc_inline_external_crate.rs | 1 - .../reexport/export_extern_crate_as_self.rs | 2 -- .../reexport/private_twice_one_inline.rs | 1 - .../reexport/private_two_names.rs | 2 -- .../same_type_reexported_more_than_once.rs | 2 -- tests/rustdoc-json/return_private.rs | 1 - tests/rustdoc-json/statics/extern.rs | 1 - tests/rustdoc-json/structs/with_primitives.rs | 2 -- tests/rustdoc-json/trait_alias.rs | 1 - .../rustdoc-json/traits/private_supertrait.rs | 2 -- tests/rustdoc-json/traits/self.rs | 2 -- tests/rustdoc-json/traits/supertrait.rs | 2 -- tests/rustdoc-json/traits/trait_alias.rs | 1 - tests/rustdoc-json/type/dyn.rs | 1 - tests/rustdoc-json/type/fn_lifetime.rs | 2 -- tests/rustdoc-json/type/generic_default.rs | 2 -- tests/rustdoc-json/type/hrtb.rs | 2 -- .../type/inherent_associated_type.rs | 1 - .../type/inherent_associated_type_bound.rs | 1 - .../inherent_associated_type_projections.rs | 1 - 44 files changed, 17 insertions(+), 76 deletions(-) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 21b513629ed8..205d6720718a 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -72,12 +72,14 @@ const ANNOTATIONS_TO_IGNORE: &[&str] = &[ "//@ normalize-stderr", ]; +const LINELENGTH_CHECK: &str = "linelength"; + // If you edit this, also edit where it gets used in `check` (calling `contains_ignore_directives`) const CONFIGURABLE_CHECKS: [&str; 11] = [ "cr", "undocumented-unsafe", "tab", - "linelength", + LINELENGTH_CHECK, "filelength", "end-whitespace", "trailing-newlines", @@ -250,14 +252,24 @@ enum Directive { // Use a fixed size array in the return type to catch mistakes with changing `CONFIGURABLE_CHECKS` // without changing the code in `check` easier. fn contains_ignore_directives( + path_str: &str, can_contain: bool, contents: &str, checks: [&str; N], ) -> [Directive; N] { - if !can_contain { + // The rustdoc-json test syntax often requires very long lines, so the checks + // for long lines aren't really useful. + let always_ignore_linelength = path_str.contains("rustdoc-json"); + + if !can_contain && !always_ignore_linelength { return [Directive::Deny; N]; } + checks.map(|check| { + if check == LINELENGTH_CHECK && always_ignore_linelength { + return Directive::Ignore(false); + } + // Update `can_contain` when changing this if contents.contains(&format!("// ignore-tidy-{check}")) || contents.contains(&format!("# ignore-tidy-{check}")) @@ -367,6 +379,7 @@ pub fn check(path: &Path, bad: &mut bool) { walk(path, skip, &mut |entry, contents| { let file = entry.path(); + let path_str = file.to_string_lossy(); let filename = file.file_name().unwrap().to_string_lossy(); let is_css_file = filename.ends_with(".css"); @@ -422,7 +435,7 @@ pub fn check(path: &Path, bad: &mut bool) { mut skip_copyright, mut skip_dbg, mut skip_odd_backticks, - ] = contains_ignore_directives(can_contain, &contents, CONFIGURABLE_CHECKS); + ] = contains_ignore_directives(&path_str, can_contain, &contents, CONFIGURABLE_CHECKS); let mut leading_new_lines = false; let mut trailing_new_lines = 0; let mut lines = 0; @@ -502,7 +515,7 @@ pub fn check(path: &Path, bad: &mut bool) { let contains_potential_directive = possible_line_start && (line.contains("-tidy") || line.contains("tidy-")); let has_recognized_ignore_directive = - contains_ignore_directives(can_contain, line, CONFIGURABLE_CHECKS) + contains_ignore_directives(&path_str, can_contain, line, CONFIGURABLE_CHECKS) .into_iter() .any(|directive| matches!(directive, Directive::Ignore(_))); let has_alphabetical_directive = line.contains("tidy-alphabetical-start") diff --git a/tests/rustdoc-json/enums/discriminant/limits.rs b/tests/rustdoc-json/enums/discriminant/limits.rs index a023c9fbf6ef..7508490d6661 100644 --- a/tests/rustdoc-json/enums/discriminant/limits.rs +++ b/tests/rustdoc-json/enums/discriminant/limits.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![feature(repr128)] #![allow(incomplete_features)] diff --git a/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs b/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs index f16a74d638b5..6f66495bed25 100644 --- a/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs +++ b/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #[repr(u32)] pub enum Foo { //@ is "$.index[*][?(@.name=='Basic')].inner.variant.discriminant.value" '"0"' diff --git a/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs b/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs index 522545d34d02..8e7985f07f41 100644 --- a/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs +++ b/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - pub enum Foo { //@ is "$.index[*][?(@.name=='Has')].inner.variant.discriminant" '{"expr":"0", "value":"0"}' Has = 0, diff --git a/tests/rustdoc-json/enums/discriminant/struct.rs b/tests/rustdoc-json/enums/discriminant/struct.rs index 24d5f5b08c20..82437f5ef03b 100644 --- a/tests/rustdoc-json/enums/discriminant/struct.rs +++ b/tests/rustdoc-json/enums/discriminant/struct.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #[repr(i32)] //@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(SignedInt(I32))])\")]\n"]' pub enum Foo { diff --git a/tests/rustdoc-json/enums/discriminant/tuple.rs b/tests/rustdoc-json/enums/discriminant/tuple.rs index a50ae8b9189f..25bba07e8f79 100644 --- a/tests/rustdoc-json/enums/discriminant/tuple.rs +++ b/tests/rustdoc-json/enums/discriminant/tuple.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #[repr(u32)] //@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(UnsignedInt(U32))])\")]\n"]' pub enum Foo { diff --git a/tests/rustdoc-json/enums/kind.rs b/tests/rustdoc-json/enums/kind.rs index 2e0fb3101a31..517a53828b78 100644 --- a/tests/rustdoc-json/enums/kind.rs +++ b/tests/rustdoc-json/enums/kind.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - pub enum Foo { //@ set Unit = "$.index[*][?(@.name=='Unit')].id" //@ is "$.index[*][?(@.name=='Unit')].inner.variant.kind" '"plain"' diff --git a/tests/rustdoc-json/fn_pointer/abi.rs b/tests/rustdoc-json/fn_pointer/abi.rs index 03fbb3b795d0..13a967bd35e2 100644 --- a/tests/rustdoc-json/fn_pointer/abi.rs +++ b/tests/rustdoc-json/fn_pointer/abi.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![feature(abi_vectorcall)] //@ is "$.index[*][?(@.name=='AbiRust')].inner.type_alias.type.function_pointer.header.abi" \"Rust\" diff --git a/tests/rustdoc-json/fn_pointer/generics.rs b/tests/rustdoc-json/fn_pointer/generics.rs index 7d64e490a222..c974b472297c 100644 --- a/tests/rustdoc-json/fn_pointer/generics.rs +++ b/tests/rustdoc-json/fn_pointer/generics.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[*]" 1 //@ is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[0][0]" '"val"' //@ is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[0][1].borrowed_ref.lifetime" \"\'c\" diff --git a/tests/rustdoc-json/fn_pointer/qualifiers.rs b/tests/rustdoc-json/fn_pointer/qualifiers.rs index 6f03cf58522e..398e31f72db0 100644 --- a/tests/rustdoc-json/fn_pointer/qualifiers.rs +++ b/tests/rustdoc-json/fn_pointer/qualifiers.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_unsafe" false //@ is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_const" false //@ is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_async" false diff --git a/tests/rustdoc-json/fns/abi.rs b/tests/rustdoc-json/fns/abi.rs index 2f6413cee6f6..68957f799521 100644 --- a/tests/rustdoc-json/fns/abi.rs +++ b/tests/rustdoc-json/fns/abi.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![feature(abi_vectorcall)] //@ is "$.index[*][?(@.name=='abi_rust')].inner.function.header.abi" \"Rust\" diff --git a/tests/rustdoc-json/fns/async_return.rs b/tests/rustdoc-json/fns/async_return.rs index ff88fa99c61b..ddfd4ccf90d0 100644 --- a/tests/rustdoc-json/fns/async_return.rs +++ b/tests/rustdoc-json/fns/async_return.rs @@ -1,5 +1,4 @@ //@ edition:2021 -// ignore-tidy-linelength // Regression test for diff --git a/tests/rustdoc-json/fns/generic_args.rs b/tests/rustdoc-json/fns/generic_args.rs index b5412446ab42..6a7124976f8b 100644 --- a/tests/rustdoc-json/fns/generic_args.rs +++ b/tests/rustdoc-json/fns/generic_args.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ set foo = "$.index[*][?(@.name=='Foo')].id" pub trait Foo {} diff --git a/tests/rustdoc-json/fns/generic_returns.rs b/tests/rustdoc-json/fns/generic_returns.rs index 2f23801fc3f8..90e17525c446 100644 --- a/tests/rustdoc-json/fns/generic_returns.rs +++ b/tests/rustdoc-json/fns/generic_returns.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ count "$.index[*][?(@.name=='generic_returns')].inner.module.items[*]" 2 //@ set foo = "$.index[*][?(@.name=='Foo')].id" diff --git a/tests/rustdoc-json/fns/generics.rs b/tests/rustdoc-json/fns/generics.rs index f2064fd1e93d..b953094b5de6 100644 --- a/tests/rustdoc-json/fns/generics.rs +++ b/tests/rustdoc-json/fns/generics.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ set wham_id = "$.index[*][?(@.name=='Wham')].id" pub trait Wham {} diff --git a/tests/rustdoc-json/generic-associated-types/gats.rs b/tests/rustdoc-json/generic-associated-types/gats.rs index fdf605e92871..d1172b35fda4 100644 --- a/tests/rustdoc-json/generic-associated-types/gats.rs +++ b/tests/rustdoc-json/generic-associated-types/gats.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - pub trait Display {} pub trait LendingIterator { diff --git a/tests/rustdoc-json/impl-trait-in-assoc-type.rs b/tests/rustdoc-json/impl-trait-in-assoc-type.rs index 14ea29507692..fc12fc87e8da 100644 --- a/tests/rustdoc-json/impl-trait-in-assoc-type.rs +++ b/tests/rustdoc-json/impl-trait-in-assoc-type.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![feature(impl_trait_in_assoc_type)] pub struct AlwaysTrue; diff --git a/tests/rustdoc-json/lifetime/longest.rs b/tests/rustdoc-json/lifetime/longest.rs index 8ac60be0fefd..2d4e098d696b 100644 --- a/tests/rustdoc-json/lifetime/longest.rs +++ b/tests/rustdoc-json/lifetime/longest.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].name" \"\'a\" //@ is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].kind" '{"lifetime": {"outlives": []}}' //@ is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].kind" '{"lifetime": {"outlives": []}}' diff --git a/tests/rustdoc-json/lifetime/outlives.rs b/tests/rustdoc-json/lifetime/outlives.rs index 99d14296f999..257e43985ac3 100644 --- a/tests/rustdoc-json/lifetime/outlives.rs +++ b/tests/rustdoc-json/lifetime/outlives.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ count "$.index[*][?(@.name=='foo')].inner.function.generics.params[*]" 3 //@ is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates" [] //@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[0].name" \"\'a\" diff --git a/tests/rustdoc-json/lifetime/outlives_in_param.rs b/tests/rustdoc-json/lifetime/outlives_in_param.rs index 3eee6d9ea46f..55ff52505415 100644 --- a/tests/rustdoc-json/lifetime/outlives_in_param.rs +++ b/tests/rustdoc-json/lifetime/outlives_in_param.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ count '$.index[*][?(@.name=="outlives")].inner.function.generics.params[*]' 2 //@ is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].name' \"\'a\" //@ is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].kind.lifetime.outlives' [] diff --git a/tests/rustdoc-json/lifetime/outlives_in_where.rs b/tests/rustdoc-json/lifetime/outlives_in_where.rs index a8f88be01daa..5158ff118a07 100644 --- a/tests/rustdoc-json/lifetime/outlives_in_where.rs +++ b/tests/rustdoc-json/lifetime/outlives_in_where.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ is '$.index[*][?(@.name=="on_lifetimes")].inner.function.generics.where_predicates' '[{"lifetime_predicate": {"lifetime": "'\''all", "outlives": ["'\''a", "'\''b", "'\''c"]}}]' pub fn on_lifetimes<'a, 'b, 'c, 'all>() where diff --git a/tests/rustdoc-json/methods/abi.rs b/tests/rustdoc-json/methods/abi.rs index 6d33dfca373c..dac02a6ce3ca 100644 --- a/tests/rustdoc-json/methods/abi.rs +++ b/tests/rustdoc-json/methods/abi.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![feature(abi_vectorcall)] //@ has "$.index[*][?(@.name=='Foo')]" diff --git a/tests/rustdoc-json/non_lifetime_binders.rs b/tests/rustdoc-json/non_lifetime_binders.rs index 8443141fecd5..7c518a8f5a7b 100644 --- a/tests/rustdoc-json/non_lifetime_binders.rs +++ b/tests/rustdoc-json/non_lifetime_binders.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![feature(non_lifetime_binders)] #![allow(incomplete_features)] diff --git a/tests/rustdoc-json/path_name.rs b/tests/rustdoc-json/path_name.rs index 67843dfc8ff3..a1b3ae294fa9 100644 --- a/tests/rustdoc-json/path_name.rs +++ b/tests/rustdoc-json/path_name.rs @@ -3,7 +3,6 @@ // See https://github.com/rust-lang/rust/issues/135600 // and https://github.com/rust-lang/rust/pull/134880#issuecomment-2596386111 // -// ignore-tidy-linelength //@ aux-build: defines_and_reexports.rs extern crate defines_and_reexports; diff --git a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs index 512c741798b9..4debd395496b 100644 --- a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs +++ b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs @@ -1,6 +1,5 @@ // Regression Test for https://github.com/rust-lang/rust/issues/110138 //@ aux-build: enum_with_discriminant.rs -// ignore-tidy-linelength #[doc(inline)] pub extern crate enum_with_discriminant; diff --git a/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs b/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs index 6e9b50448169..4efacd283ef7 100644 --- a/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs +++ b/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs @@ -2,7 +2,5 @@ #![crate_name = "export_extern_crate_as_self"] -// ignore-tidy-linelength - //@ is "$.index[*][?(@.inner.module)].name" \"export_extern_crate_as_self\" pub extern crate self as export_extern_crate_as_self; // Must be the same name as the crate already has diff --git a/tests/rustdoc-json/reexport/private_twice_one_inline.rs b/tests/rustdoc-json/reexport/private_twice_one_inline.rs index 87b97e65c0ac..fdf8cda103bf 100644 --- a/tests/rustdoc-json/reexport/private_twice_one_inline.rs +++ b/tests/rustdoc-json/reexport/private_twice_one_inline.rs @@ -1,5 +1,4 @@ //@ aux-build:pub-struct.rs -// ignore-tidy-linelength // Test for the ICE in https://github.com/rust-lang/rust/issues/83057 // An external type re-exported with different attributes shouldn't cause an error diff --git a/tests/rustdoc-json/reexport/private_two_names.rs b/tests/rustdoc-json/reexport/private_two_names.rs index 1ed54f15fdc3..049100d7f497 100644 --- a/tests/rustdoc-json/reexport/private_two_names.rs +++ b/tests/rustdoc-json/reexport/private_two_names.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Test for the ICE in https://github.com/rust-lang/rust/issues/83720 // A pub-in-private type re-exported under two different names shouldn't cause an error diff --git a/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs b/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs index 27e2827d08dd..f313171afa59 100644 --- a/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs +++ b/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Regression test for . #![no_std] diff --git a/tests/rustdoc-json/return_private.rs b/tests/rustdoc-json/return_private.rs index bfcbed890400..214fda14acad 100644 --- a/tests/rustdoc-json/return_private.rs +++ b/tests/rustdoc-json/return_private.rs @@ -1,5 +1,4 @@ // Regression test for . -// ignore-tidy-linelength mod secret { //@ set struct_secret = "$.index[*][?(@.name == 'Secret' && @.inner.struct)].id" diff --git a/tests/rustdoc-json/statics/extern.rs b/tests/rustdoc-json/statics/extern.rs index d38fdf1cd1cd..9e0265da8e2e 100644 --- a/tests/rustdoc-json/statics/extern.rs +++ b/tests/rustdoc-json/statics/extern.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength //@ edition: 2021 extern "C" { diff --git a/tests/rustdoc-json/structs/with_primitives.rs b/tests/rustdoc-json/structs/with_primitives.rs index 7202ab9af9c2..fe99292456d6 100644 --- a/tests/rustdoc-json/structs/with_primitives.rs +++ b/tests/rustdoc-json/structs/with_primitives.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ is "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\" //@ has "$.index[*][?(@.name=='WithPrimitives')].inner.struct" //@ is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.generics.params[0].name" \"\'a\" diff --git a/tests/rustdoc-json/trait_alias.rs b/tests/rustdoc-json/trait_alias.rs index 3ae5fad8accd..d9ef256b106f 100644 --- a/tests/rustdoc-json/trait_alias.rs +++ b/tests/rustdoc-json/trait_alias.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![feature(trait_alias)] //@ set StrLike = "$.index[*][?(@.name=='StrLike')].id" diff --git a/tests/rustdoc-json/traits/private_supertrait.rs b/tests/rustdoc-json/traits/private_supertrait.rs index d31b6ca4ad86..ce0642278e08 100644 --- a/tests/rustdoc-json/traits/private_supertrait.rs +++ b/tests/rustdoc-json/traits/private_supertrait.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ !has "$.index[*][?(@.name == 'sealed')]" mod sealed { //@ set sealed_id = "$.index[*][?(@.name=='Sealed')].id" diff --git a/tests/rustdoc-json/traits/self.rs b/tests/rustdoc-json/traits/self.rs index 060bc37f2d5e..efd9efd556fa 100644 --- a/tests/rustdoc-json/traits/self.rs +++ b/tests/rustdoc-json/traits/self.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - pub struct Foo; // Check that Self is represented uniformly between inherent impls, trait impls, diff --git a/tests/rustdoc-json/traits/supertrait.rs b/tests/rustdoc-json/traits/supertrait.rs index e8fe82ab9cd4..4b6199d4b26f 100644 --- a/tests/rustdoc-json/traits/supertrait.rs +++ b/tests/rustdoc-json/traits/supertrait.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ set loud_id = "$.index[*][?(@.name=='Loud')].id" pub trait Loud {} diff --git a/tests/rustdoc-json/traits/trait_alias.rs b/tests/rustdoc-json/traits/trait_alias.rs index 17c83ddc353c..137b8947e239 100644 --- a/tests/rustdoc-json/traits/trait_alias.rs +++ b/tests/rustdoc-json/traits/trait_alias.rs @@ -1,5 +1,4 @@ // Regression test for -// ignore-tidy-linelength #![feature(trait_alias)] diff --git a/tests/rustdoc-json/type/dyn.rs b/tests/rustdoc-json/type/dyn.rs index f990a2cb53a7..d8686d4e2fb1 100644 --- a/tests/rustdoc-json/type/dyn.rs +++ b/tests/rustdoc-json/type/dyn.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength use std::fmt::Debug; //@ count "$.index[*][?(@.name=='dyn')].inner.module.items[*]" 3 diff --git a/tests/rustdoc-json/type/fn_lifetime.rs b/tests/rustdoc-json/type/fn_lifetime.rs index 7fa12dad54e9..aaa716bf11fd 100644 --- a/tests/rustdoc-json/type/fn_lifetime.rs +++ b/tests/rustdoc-json/type/fn_lifetime.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ has "$.index[*][?(@.name=='GenericFn')].inner.type_alias" //@ ismany "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.params[*].name" \"\'a\" diff --git a/tests/rustdoc-json/type/generic_default.rs b/tests/rustdoc-json/type/generic_default.rs index 7eaa299af5c7..2d2ce9cd1033 100644 --- a/tests/rustdoc-json/type/generic_default.rs +++ b/tests/rustdoc-json/type/generic_default.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ set result = "$.index[*][?(@.name=='Result')].id" pub enum Result { Ok(T), diff --git a/tests/rustdoc-json/type/hrtb.rs b/tests/rustdoc-json/type/hrtb.rs index e71d9fc1e1e9..08b35b90a2b1 100644 --- a/tests/rustdoc-json/type/hrtb.rs +++ b/tests/rustdoc-json/type/hrtb.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - //@ is "$.index[*][?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.type" '{"generic": "F"}' //@ is "$.index[*][?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' pub fn genfn(f: F) diff --git a/tests/rustdoc-json/type/inherent_associated_type.rs b/tests/rustdoc-json/type/inherent_associated_type.rs index b8ce11fc6e19..e26f8f7c651b 100644 --- a/tests/rustdoc-json/type/inherent_associated_type.rs +++ b/tests/rustdoc-json/type/inherent_associated_type.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![feature(inherent_associated_types)] #![allow(incomplete_features)] diff --git a/tests/rustdoc-json/type/inherent_associated_type_bound.rs b/tests/rustdoc-json/type/inherent_associated_type_bound.rs index cb008291b722..22c9c9c1149a 100644 --- a/tests/rustdoc-json/type/inherent_associated_type_bound.rs +++ b/tests/rustdoc-json/type/inherent_associated_type_bound.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![feature(inherent_associated_types)] #![allow(incomplete_features)] diff --git a/tests/rustdoc-json/type/inherent_associated_type_projections.rs b/tests/rustdoc-json/type/inherent_associated_type_projections.rs index e73e86d5817f..501694dce8b6 100644 --- a/tests/rustdoc-json/type/inherent_associated_type_projections.rs +++ b/tests/rustdoc-json/type/inherent_associated_type_projections.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![feature(inherent_associated_types)] #![allow(incomplete_features)] From b5562c04e73590c8eefa67400aba022ff7b61f25 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Mon, 3 Mar 2025 20:14:16 +0100 Subject: [PATCH 586/991] Remove i586-pc-windows-msvc See MCP 840. I left a specialized error message that should help users that hit this in the wild (for example, because they use it in their CI). --- compiler/rustc_target/src/spec/mod.rs | 11 +++++++++-- .../src/spec/targets/i586_pc_windows_msvc.rs | 9 --------- src/ci/github-actions/jobs.yml | 2 +- src/doc/rustc/src/platform-support.md | 1 - src/tools/build-manifest/src/main.rs | 1 - .../stack-protector/stack-protector-target-support.rs | 6 +----- tests/assembly/targets/targets-pe.rs | 3 --- 7 files changed, 11 insertions(+), 22 deletions(-) delete mode 100644 compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index cc8162a2f27e..1edc66bb9f96 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1915,7 +1915,6 @@ supported_targets! { ("i686-pc-windows-msvc", i686_pc_windows_msvc), ("i686-uwp-windows-msvc", i686_uwp_windows_msvc), ("i686-win7-windows-msvc", i686_win7_windows_msvc), - ("i586-pc-windows-msvc", i586_pc_windows_msvc), ("thumbv7a-pc-windows-msvc", thumbv7a_pc_windows_msvc), ("thumbv7a-uwp-windows-msvc", thumbv7a_uwp_windows_msvc), @@ -3503,7 +3502,15 @@ impl Target { return load_file(&p); } - Err(format!("Could not find specification for target {target_tuple:?}")) + // Leave in a specialized error message for the removed target. + // FIXME: If you see this and it's been a few months after this has been released, + // you can probably remove it. + if target_tuple == "i586-pc-windows-msvc" { + Err("the `i586-pc-windows-msvc` target has been removed. Use the `i686-pc-windows-msvc` target instead.\n\ + Windows 10 (the minimum required OS version) requires a CPU baseline of at least i686 so you can safely switch".into()) + } else { + Err(format!("Could not find specification for target {target_tuple:?}")) + } } TargetTuple::TargetJson { ref contents, .. } => { let obj = serde_json::from_str(contents).map_err(|e| e.to_string())?; diff --git a/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs deleted file mode 100644 index 394e6f9e6bf6..000000000000 --- a/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs +++ /dev/null @@ -1,9 +0,0 @@ -use crate::spec::Target; - -pub(crate) fn target() -> Target { - let mut base = super::i686_pc_windows_msvc::target(); - base.rustc_abi = None; // overwrite the SSE2 ABI set by the base target - base.cpu = "pentium".into(); - base.llvm_target = "i586-pc-windows-msvc".into(); - base -} diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index bbcc01a0c299..aff374654dc7 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -591,7 +591,7 @@ auto: RUST_CONFIGURE_ARGS: >- --build=i686-pc-windows-msvc --host=i686-pc-windows-msvc - --target=i686-pc-windows-msvc,i586-pc-windows-msvc + --target=i686-pc-windows-msvc --enable-full-tools --enable-profiler SCRIPT: python x.py dist bootstrap --include-default-paths diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c4e5c1aac2f5..487fb94c229e 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -162,7 +162,6 @@ target | std | notes [`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat -`i586-pc-windows-msvc` | * | 32-bit Windows (original Pentium) [^x86_32-floats-x87] `i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2, glibc 2.17, original Pentium) [^x86_32-floats-x87] `i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.3, original Pentium) [^x86_32-floats-x87] [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([Pentium 4 plus various extensions](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI] diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index cd5ca74f8ade..dfc8f3bc7e0d 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -97,7 +97,6 @@ static TARGETS: &[&str] = &[ "bpfeb-unknown-none", "bpfel-unknown-none", "i386-apple-ios", - "i586-pc-windows-msvc", "i586-unknown-linux-gnu", "i586-unknown-linux-musl", "i586-unknown-redox", diff --git a/tests/assembly/stack-protector/stack-protector-target-support.rs b/tests/assembly/stack-protector/stack-protector-target-support.rs index e9ba0f9ba899..a937256a60f8 100644 --- a/tests/assembly/stack-protector/stack-protector-target-support.rs +++ b/tests/assembly/stack-protector/stack-protector-target-support.rs @@ -3,7 +3,7 @@ // //@ add-core-stubs //@ revisions: r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 -//@ revisions: r24 r25 r26 r27 r28 r29 r30 r31 r32 r33 r35 r36 r37 r38 r39 r40 r41 r42 r43 r44 +//@ revisions: r24 r25 r26 r27 r28 r29 r30 r31 r32 r33 r36 r37 r38 r39 r40 r41 r42 r43 r44 //@ revisions: r45 r46 r47 r48 r49 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63 r64 r65 //@ revisions: r66 r67 r68 r69 r70 r71 r72 r73 r74 r75 r76 r77 r78 r79 r80 r81 r82 r83 r84 r85 //@ assembly-output: emit-asm @@ -73,9 +73,6 @@ //@ [r32] needs-llvm-components: arm //@ [r33] compile-flags: --target armv7-unknown-linux-musleabihf //@ [r33] needs-llvm-components: arm - -//@ [r35] compile-flags: --target i586-pc-windows-msvc -//@ [r35] needs-llvm-components: x86 //@ [r36] compile-flags: --target i586-unknown-linux-gnu //@ [r36] needs-llvm-components: x86 //@ [r37] compile-flags: --target i586-unknown-linux-musl @@ -195,7 +192,6 @@ pub fn foo() { // r3: calll @__security_check_cookie // r7: callq __security_check_cookie // r13: bl __security_check_cookie - // r35: calll @__security_check_cookie // cuda doesn't support stack-smash protection // r49-NOT: __security_check_cookie diff --git a/tests/assembly/targets/targets-pe.rs b/tests/assembly/targets/targets-pe.rs index f895b79ba507..de29b9af5020 100644 --- a/tests/assembly/targets/targets-pe.rs +++ b/tests/assembly/targets/targets-pe.rs @@ -25,9 +25,6 @@ //@ revisions: bpfel_unknown_none //@ [bpfel_unknown_none] compile-flags: --target bpfel-unknown-none //@ [bpfel_unknown_none] needs-llvm-components: bpf -//@ revisions: i586_pc_windows_msvc -//@ [i586_pc_windows_msvc] compile-flags: --target i586-pc-windows-msvc -//@ [i586_pc_windows_msvc] needs-llvm-components: x86 //@ revisions: i686_pc_windows_gnu //@ [i686_pc_windows_gnu] compile-flags: --target i686-pc-windows-gnu //@ [i686_pc_windows_gnu] needs-llvm-components: x86 From f0de899001d9c8fe7735eef061bdc024436f9b6f Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Mon, 3 Mar 2025 19:28:57 +0000 Subject: [PATCH 587/991] triagebot.toml: Don't label `test/rustdoc-json` as A-rustdoc-search This happened because `test/rustdoc-js` is a prefix of `test/rustdoc-json`, and triagebot works on prefixes. Maybe this should be fixed in triagebot, but this works now. --- triagebot.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index ed352984fb12..cab4e232dc04 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -207,7 +207,7 @@ trigger_files = [ "tests/rustdoc", "tests/rustdoc-ui", "tests/rustdoc-gui", - "tests/rustdoc-js", + "tests/rustdoc-js/", "tests/rustdoc-js-std", "tests/rustdoc-json", @@ -1307,7 +1307,7 @@ project-exploit-mitigations = [ "/tests/rustdoc" = ["rustdoc"] "/tests/rustdoc-gui" = ["rustdoc"] "/tests/rustdoc-js-std" = ["rustdoc"] -"/tests/rustdoc-js" = ["rustdoc"] +"/tests/rustdoc-js/" = ["rustdoc"] "/tests/rustdoc-json" = ["@aDotInTheVoid"] "/tests/rustdoc-ui" = ["rustdoc"] "/tests/ui" = ["compiler"] From 53ee6968a3664c36fbc78530cb7795f2259e6a0c Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 4 Mar 2025 00:27:22 +0800 Subject: [PATCH 588/991] Update MSVC INSTALL.md instructions to recommend VS 2022 + recent Windows 10/11 SDK --- INSTALL.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 74fcc58348b4..a46d3d70093f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -210,9 +210,13 @@ itself back on after some time). ### MSVC -MSVC builds of Rust additionally require an installation of Visual Studio 2017 -(or later) so `rustc` can use its linker. The simplest way is to get -[Visual Studio], check the "C++ build tools" and "Windows 10 SDK" workload. +MSVC builds of Rust additionally requires an installation of: + +- Visual Studio 2022 (or later) build tools so `rustc` can use its linker. Older + Visual Studio versions such as 2019 *may* work but aren't actively tested. +- A recent Windows 10 or 11 SDK. + +The simplest way is to get [Visual Studio], check the "C++ build tools". [Visual Studio]: https://visualstudio.microsoft.com/downloads/ From e3117e6e1834838bce446517d7541dda395032d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 3 Mar 2025 19:49:35 +0100 Subject: [PATCH 589/991] Do not use rustup to build Rust for Linux --- src/ci/docker/scripts/rfl-build.sh | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index 573821c3e59c..ea8066d95e02 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -8,16 +8,10 @@ LINUX_VERSION=v6.14-rc3 ../x.py build --stage 2 library rustdoc clippy rustfmt ../x.py build --stage 0 cargo -# Install rustup so that we can use the built toolchain easily, and also -# install bindgen in an easy way. -curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs -sh rustup.sh -y --default-toolchain none +BUILD_DIR=$(realpath ./build/x86_64-unknown-linux-gnu) -source /cargo/env - -BUILD_DIR=$(realpath ./build) -rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage2 -rustup default local +# Provide path to rustc, rustdoc, clippy-driver and rustfmt to RfL +export PATH=${PATH}:${BUILD_DIR}/stage2/bin mkdir -p rfl cd rfl @@ -33,10 +27,14 @@ git -C linux fetch --depth 1 origin ${LINUX_VERSION} git -C linux checkout FETCH_HEAD # Install bindgen -"${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage0/bin/cargo install \ +"${BUILD_DIR}"/stage0/bin/cargo install \ --version $(linux/scripts/min-tool-version.sh bindgen) \ + --root ${BUILD_DIR}/bindgen \ bindgen-cli +# Provide path to bindgen to RfL +export PATH=${PATH}:${BUILD_DIR}/bindgen/bin + # Configure Rust for Linux cat < linux/kernel/configs/rfl-for-rust-ci.config # CONFIG_WERROR is not set From 4f4cbff170684515b47ce1d54ba36dd80ce9c511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 3 Mar 2025 20:55:48 +0100 Subject: [PATCH 590/991] Re-enable Rust for Linux CI job --- src/ci/github-actions/jobs.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 1504e5c60ce7..bbcc01a0c299 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -271,9 +271,8 @@ auto: # Tests integration with Rust for Linux. # Builds stage 1 compiler and tries to compile a few RfL examples with it. - # FIXME: fix rustup 1.28 issue - # - name: x86_64-rust-for-linux - # <<: *job-linux-4c + - name: x86_64-rust-for-linux + <<: *job-linux-4c - name: x86_64-gnu <<: *job-linux-4c From 2a4204bf6c7965778685cc1af4d32a3767d8fbe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Mar 2025 20:04:20 +0000 Subject: [PATCH 591/991] Use default field values in `markdown::parse::Context` --- compiler/rustc_errors/src/lib.rs | 1 + compiler/rustc_errors/src/markdown/parse.rs | 20 +++++++------------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index f2b133f56773..afced1d803f6 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -14,6 +14,7 @@ #![feature(associated_type_defaults)] #![feature(box_into_inner)] #![feature(box_patterns)] +#![feature(default_field_values)] #![feature(error_reporter)] #![feature(if_let_guard)] #![feature(let_chains)] diff --git a/compiler/rustc_errors/src/markdown/parse.rs b/compiler/rustc_errors/src/markdown/parse.rs index 7a991a2ace71..f02387d83359 100644 --- a/compiler/rustc_errors/src/markdown/parse.rs +++ b/compiler/rustc_errors/src/markdown/parse.rs @@ -40,11 +40,13 @@ type ParseResult<'a> = Option>; /// Parsing context #[derive(Clone, Copy, Debug, PartialEq)] +// The default values are the most common setting for non top-level parsing: not top block, not at +// line start (yes leading whitespace, not escaped). struct Context { /// If true, we are at a the topmost level (not recursing a nested tt) - top_block: bool, + top_block: bool = false, /// Previous character - prev: Prev, + prev: Prev = Prev::Whitespace, } /// Character class preceding this one @@ -57,14 +59,6 @@ enum Prev { Any, } -impl Default for Context { - /// Most common setting for non top-level parsing: not top block, not at - /// line start (yes leading whitespace, not escaped) - fn default() -> Self { - Self { top_block: false, prev: Prev::Whitespace } - } -} - /// Flags to simple parser function #[derive(Clone, Copy, Debug, PartialEq)] enum ParseOpt { @@ -248,7 +242,7 @@ fn parse_heading(buf: &[u8]) -> ParseResult<'_> { } let (txt, rest) = parse_to_newline(&buf[1..]); - let ctx = Context { top_block: false, prev: Prev::Whitespace }; + let ctx = Context { .. }; let stream = parse_recursive(txt, ctx); Some((MdTree::Heading(level.try_into().unwrap(), stream), rest)) @@ -257,7 +251,7 @@ fn parse_heading(buf: &[u8]) -> ParseResult<'_> { /// Bulleted list fn parse_unordered_li(buf: &[u8]) -> Parsed<'_> { let (txt, rest) = get_indented_section(&buf[2..]); - let ctx = Context { top_block: false, prev: Prev::Whitespace }; + let ctx = Context { .. }; let stream = parse_recursive(trim_ascii_start(txt), ctx); (MdTree::UnorderedListItem(stream), rest) } @@ -266,7 +260,7 @@ fn parse_unordered_li(buf: &[u8]) -> Parsed<'_> { fn parse_ordered_li(buf: &[u8]) -> Parsed<'_> { let (num, pos) = ord_list_start(buf).unwrap(); // success tested in caller let (txt, rest) = get_indented_section(&buf[pos..]); - let ctx = Context { top_block: false, prev: Prev::Whitespace }; + let ctx = Context { .. }; let stream = parse_recursive(trim_ascii_start(txt), ctx); (MdTree::OrderedListItem(num, stream), rest) } From aae7a3c4c2fbd0db49fac5618590df541943f140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Mar 2025 20:05:42 +0000 Subject: [PATCH 592/991] Use default field values for `config::NextSolverConfig` Use default field values to avoid manual `Default` impl. --- compiler/rustc_session/src/config.rs | 11 +++-------- compiler/rustc_session/src/lib.rs | 1 + 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7586c5766b58..1f63847b6fe7 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -872,18 +872,13 @@ pub enum PrintKind { DeploymentTarget, } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)] pub struct NextSolverConfig { /// Whether the new trait solver should be enabled in coherence. - pub coherence: bool, + pub coherence: bool = true, /// Whether the new trait solver should be enabled everywhere. /// This is only `true` if `coherence` is also enabled. - pub globally: bool, -} -impl Default for NextSolverConfig { - fn default() -> Self { - NextSolverConfig { coherence: true, globally: false } - } + pub globally: bool = false, } #[derive(Clone)] diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 112adde3740b..d432e84fdb22 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,5 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![feature(default_field_values)] #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(rustc_attrs)] From 0c4eaa5c985f69d3b6255a56799ee30d29e08d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Mar 2025 20:18:56 +0000 Subject: [PATCH 593/991] Use default field values for `ErrorOutputType` Remove manual `Default` impl from `config::ErrorOutputType`. --- compiler/rustc_session/src/config.rs | 45 +++++++++++++-------------- compiler/rustc_session/src/session.rs | 4 +-- src/librustdoc/core.rs | 2 +- src/librustdoc/doctest.rs | 2 +- 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 1f63847b6fe7..36adb113d053 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -655,10 +655,14 @@ impl OutputType { } /// The type of diagnostics output to generate. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] pub enum ErrorOutputType { /// Output meant for the consumption of humans. - HumanReadable(HumanReadableErrorType, ColorConfig), + #[default] + HumanReadable { + kind: HumanReadableErrorType = HumanReadableErrorType::Default, + color_config: ColorConfig = ColorConfig::Auto, + }, /// Output that's consumed by other tools such as `rustfix` or the `RLS`. Json { /// Render the JSON in a human readable way (with indents and newlines). @@ -670,12 +674,6 @@ pub enum ErrorOutputType { }, } -impl Default for ErrorOutputType { - fn default() -> Self { - Self::HumanReadable(HumanReadableErrorType::Default, ColorConfig::Auto) - } -} - #[derive(Clone, Hash, Debug)] pub enum ResolveDocLinks { /// Do not resolve doc links. @@ -1790,7 +1788,7 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json pub fn parse_error_format( early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches, - color: ColorConfig, + color_config: ColorConfig, json_color: ColorConfig, json_rendered: HumanReadableErrorType, ) -> ErrorOutputType { @@ -1800,27 +1798,26 @@ pub fn parse_error_format( // `opt_present` because the latter will panic. let error_format = if matches.opts_present(&["error-format".to_owned()]) { match matches.opt_str("error-format").as_deref() { - None | Some("human") => { - ErrorOutputType::HumanReadable(HumanReadableErrorType::Default, color) - } - Some("human-annotate-rs") => { - ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet, color) - } + None | Some("human") => ErrorOutputType::HumanReadable { color_config, .. }, + Some("human-annotate-rs") => ErrorOutputType::HumanReadable { + kind: HumanReadableErrorType::AnnotateSnippet, + color_config, + }, Some("json") => { ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color } } Some("pretty-json") => { ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color } } - Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short, color), - Some("human-unicode") => { - ErrorOutputType::HumanReadable(HumanReadableErrorType::Unicode, color) + Some("short") => { + ErrorOutputType::HumanReadable { kind: HumanReadableErrorType::Short, color_config } } + Some("human-unicode") => ErrorOutputType::HumanReadable { + kind: HumanReadableErrorType::Unicode, + color_config, + }, Some(arg) => { - early_dcx.set_error_format(ErrorOutputType::HumanReadable( - HumanReadableErrorType::Default, - color, - )); + early_dcx.set_error_format(ErrorOutputType::HumanReadable { color_config, .. }); early_dcx.early_fatal(format!( "argument for `--error-format` must be `human`, `human-annotate-rs`, \ `human-unicode`, `json`, `pretty-json` or `short` (instead was `{arg}`)" @@ -1828,7 +1825,7 @@ pub fn parse_error_format( } } } else { - ErrorOutputType::HumanReadable(HumanReadableErrorType::Default, color) + ErrorOutputType::HumanReadable { color_config, .. } }; match error_format { @@ -1883,7 +1880,7 @@ fn check_error_format_stability( } let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", - ErrorOutputType::HumanReadable(format, _) => match format { + ErrorOutputType::HumanReadable { kind, .. } => match kind { HumanReadableErrorType::AnnotateSnippet => "human-annotate-rs", HumanReadableErrorType::Unicode => "human-unicode", _ => return, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index ecdf76d22fb2..aa1e9762f397 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -913,7 +913,7 @@ fn default_emitter( let source_map = if sopts.unstable_opts.link_only { None } else { Some(source_map) }; match sopts.error_format { - config::ErrorOutputType::HumanReadable(kind, color_config) => { + config::ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); if let HumanReadableErrorType::AnnotateSnippet = kind { @@ -1430,7 +1430,7 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let fallback_bundle = fallback_fluent_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box = match output { - config::ErrorOutputType::HumanReadable(kind, color_config) => { + config::ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); Box::new( HumanEmitter::new(stderr_destination(color_config), fallback_bundle) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 757a2a6e0dd0..7221e2ce6b1d 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -153,7 +153,7 @@ pub(crate) fn new_dcx( false, ); let emitter: Box = match error_format { - ErrorOutputType::HumanReadable(kind, color_config) => { + ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); Box::new( HumanEmitter::new(stderr_destination(color_config), fallback_bundle) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 4a379b4235ff..3d6e0330fffa 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -580,7 +580,7 @@ fn run_test( path_for_rustdoc.to_str().expect("target path must be valid unicode") } }); - if let ErrorOutputType::HumanReadable(kind, color_config) = rustdoc_options.error_format { + if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { let short = kind.short(); let unicode = kind == HumanReadableErrorType::Unicode; From a89cddb2be47b52ec8373165e0d69448df80a23f Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Mon, 3 Mar 2025 22:58:03 +0200 Subject: [PATCH 594/991] Add ``dyn`` keyword --- compiler/rustc_error_codes/src/error_codes/E0373.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0373.md b/compiler/rustc_error_codes/src/error_codes/E0373.md index d4d26007aa50..b9db80725972 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0373.md +++ b/compiler/rustc_error_codes/src/error_codes/E0373.md @@ -3,7 +3,7 @@ A captured variable in a closure may not live long enough. Erroneous code example: ```compile_fail,E0373 -fn foo() -> Box u32> { +fn foo() -> Box u32> { let x = 0u32; Box::new(|y| x + y) } @@ -42,7 +42,7 @@ This approach moves (or copies, where possible) data into the closure, rather than taking references to it. For example: ``` -fn foo() -> Box u32> { +fn foo() -> Box u32> { let x = 0u32; Box::new(move |y| x + y) } From ddd04d03d1f271e31a54b777a54f8e2814ae365c Mon Sep 17 00:00:00 2001 From: Jane Losare-Lusby Date: Fri, 28 Feb 2025 13:04:23 -0800 Subject: [PATCH 595/991] Add timestamp to unstable feature usage metrics --- compiler/rustc_feature/src/unstable.rs | 16 +++++++++++++++- .../unstable-feature-usage-metrics/rmake.rs | 11 ++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 66c26a541f17..09de30a89d00 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -1,6 +1,7 @@ //! List of the unstable feature gates. use std::path::PathBuf; +use std::time::{SystemTime, UNIX_EPOCH}; use rustc_data_structures::fx::FxHashSet; use rustc_span::{Span, Symbol, sym}; @@ -681,11 +682,13 @@ impl Features { ) -> Result<(), Box> { #[derive(serde::Serialize)] struct LibFeature { + timestamp: u128, symbol: String, } #[derive(serde::Serialize)] struct LangFeature { + timestamp: u128, symbol: String, since: Option, } @@ -699,10 +702,20 @@ impl Features { let metrics_file = std::fs::File::create(metrics_path)?; let metrics_file = std::io::BufWriter::new(metrics_file); + let now = || { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("system time should always be greater than the unix epoch") + .as_nanos() + }; + let lib_features = self .enabled_lib_features .iter() - .map(|EnabledLibFeature { gate_name, .. }| LibFeature { symbol: gate_name.to_string() }) + .map(|EnabledLibFeature { gate_name, .. }| LibFeature { + symbol: gate_name.to_string(), + timestamp: now(), + }) .collect(); let lang_features = self @@ -711,6 +724,7 @@ impl Features { .map(|EnabledLangFeature { gate_name, stable_since, .. }| LangFeature { symbol: gate_name.to_string(), since: stable_since.map(|since| since.to_string()), + timestamp: now(), }) .collect(); diff --git a/tests/run-make/unstable-feature-usage-metrics/rmake.rs b/tests/run-make/unstable-feature-usage-metrics/rmake.rs index 1397548a6fce..2183e28e89ab 100644 --- a/tests/run-make/unstable-feature-usage-metrics/rmake.rs +++ b/tests/run-make/unstable-feature-usage-metrics/rmake.rs @@ -58,12 +58,17 @@ fn test_metrics_dump() { ); let message = rfs::read_to_string(json_path); - let parsed: serde_json::Value = + let mut parsed: serde_json::Value = serde_json::from_str(&message).expect("metrics should be dumped as json"); + // remove timestamps + assert!(parsed["lib_features"][0]["timestamp"].is_number()); + assert!(parsed["lang_features"][0]["timestamp"].is_number()); + parsed["lib_features"][0]["timestamp"] = serde_json::json!(null); + parsed["lang_features"][0]["timestamp"] = serde_json::json!(null); let expected = serde_json::json!( { - "lib_features":[{"symbol":"ascii_char"}], - "lang_features":[{"symbol":"box_patterns","since":null}] + "lib_features":[{"symbol":"ascii_char", "timestamp":null}], + "lang_features":[{"symbol":"box_patterns","since":null, "timestamp":null}] } ); From c566318a782030a33f370d7490d7bdac9d8bfca4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 18 Feb 2025 17:11:12 +0000 Subject: [PATCH 596/991] Tweak error code for sized checks of const/static --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 14 +++++++++++--- compiler/rustc_hir_typeck/src/expr.rs | 2 +- compiler/rustc_middle/src/traits/mod.rs | 2 +- .../src/error_reporting/traits/suggestions.rs | 4 ++-- tests/ui/consts/const-slice-array-deref.stderr | 1 + tests/ui/consts/const-unsized.stderr | 4 ++++ .../consts/const_refs_to_static-ice-121413.stderr | 1 + .../issue-36122-accessing-externed-dst.stderr | 1 + tests/ui/issues/issue-54410.stderr | 1 + tests/ui/static/issue-24446.stderr | 1 + tests/ui/statics/unsized_type2.stderr | 1 + .../ice-unsized-tuple-const-issue-121443.stderr | 1 + 12 files changed, 26 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index d72cf00293f0..8199585ee61c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1108,7 +1108,13 @@ fn check_associated_item( let ty = tcx.type_of(item.def_id).instantiate_identity(); let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); - check_sized_if_body(wfcx, item.def_id.expect_local(), ty, Some(span)); + check_sized_if_body( + wfcx, + item.def_id.expect_local(), + ty, + Some(span), + ObligationCauseCode::SizedConstOrStatic, + ); Ok(()) } ty::AssocKind::Fn => { @@ -1354,7 +1360,7 @@ fn check_item_type( traits::ObligationCause::new( ty_span, wfcx.body_def_id, - ObligationCauseCode::WellFormed(None), + ObligationCauseCode::SizedConstOrStatic, ), wfcx.param_env, item_ty, @@ -1698,6 +1704,7 @@ fn check_fn_or_method<'tcx>( hir::FnRetTy::Return(ty) => Some(ty.span), hir::FnRetTy::DefaultReturn(_) => None, }, + ObligationCauseCode::SizedReturnType, ); } @@ -1706,13 +1713,14 @@ fn check_sized_if_body<'tcx>( def_id: LocalDefId, ty: Ty<'tcx>, maybe_span: Option, + code: ObligationCauseCode<'tcx>, ) { let tcx = wfcx.tcx(); if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) { let span = maybe_span.unwrap_or(body.value.span); wfcx.register_bound( - ObligationCause::new(span, def_id, traits::ObligationCauseCode::SizedReturnType), + ObligationCause::new(span, def_id, code), wfcx.param_env, ty, tcx.require_lang_item(LangItem::Sized, Some(span)), diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index dec1779d92ca..cbe677171a0b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1806,7 +1806,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { crate::GatherLocalsVisitor::new(&fcx).visit_body(body); let ty = fcx.check_expr_with_expectation(body.value, expected); - fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::ConstSized); + fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::SizedConstOrStatic); fcx.write_ty(block.hir_id, ty); ty } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index d033ecc75dbe..b8698aa82335 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -266,7 +266,7 @@ pub enum ObligationCauseCode<'tcx> { }, /// Constant expressions must be sized. - ConstSized, + SizedConstOrStatic, /// `static` items must have `Sync` type. SharedStatic, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index b85c18c53121..d180c0be9d5a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3126,8 +3126,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } - ObligationCauseCode::ConstSized => { - err.note("constant expressions must have a statically known size"); + ObligationCauseCode::SizedConstOrStatic => { + err.note("statics and constants must have a statically known size"); } ObligationCauseCode::InlineAsmSized => { err.note("all inline asm arguments must have a statically known size"); diff --git a/tests/ui/consts/const-slice-array-deref.stderr b/tests/ui/consts/const-slice-array-deref.stderr index 346685380cc6..b1d069280885 100644 --- a/tests/ui/consts/const-slice-array-deref.stderr +++ b/tests/ui/consts/const-slice-array-deref.stderr @@ -5,6 +5,7 @@ LL | const ONE: [u16] = [1]; | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u16]` + = note: statics and constants must have a statically known size error[E0308]: mismatched types --> $DIR/const-slice-array-deref.rs:1:20 diff --git a/tests/ui/consts/const-unsized.stderr b/tests/ui/consts/const-unsized.stderr index 7931d7adafdb..8328e19aac22 100644 --- a/tests/ui/consts/const-unsized.stderr +++ b/tests/ui/consts/const-unsized.stderr @@ -5,6 +5,7 @@ LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync)); | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)` + = note: statics and constants must have a statically known size error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/const-unsized.rs:7:18 @@ -13,6 +14,7 @@ LL | const CONST_FOO: str = *"foo"; | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` + = note: statics and constants must have a statically known size error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time --> $DIR/const-unsized.rs:11:18 @@ -21,6 +23,7 @@ LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync)); | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)` + = note: statics and constants must have a statically known size error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/const-unsized.rs:15:20 @@ -29,6 +32,7 @@ LL | static STATIC_BAR: str = *"bar"; | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` + = note: statics and constants must have a statically known size error[E0507]: cannot move out of a shared reference --> $DIR/const-unsized.rs:3:35 diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.stderr b/tests/ui/consts/const_refs_to_static-ice-121413.stderr index 8665d9b68522..3980a7e9b93b 100644 --- a/tests/ui/consts/const_refs_to_static-ice-121413.stderr +++ b/tests/ui/consts/const_refs_to_static-ice-121413.stderr @@ -30,6 +30,7 @@ LL | static FOO: Sync = AtomicUsize::new(0); | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Sync + 'static)` + = note: statics and constants must have a statically known size error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr index 64178e6f8439..6f805aec1df0 100644 --- a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr +++ b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr @@ -5,6 +5,7 @@ LL | static symbol: [usize]; | ^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[usize]` + = note: statics and constants must have a statically known size error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/issue-36122-accessing-externed-dst.rs:5:20 diff --git a/tests/ui/issues/issue-54410.stderr b/tests/ui/issues/issue-54410.stderr index 97e5990750e3..2cd5a2a49ef5 100644 --- a/tests/ui/issues/issue-54410.stderr +++ b/tests/ui/issues/issue-54410.stderr @@ -5,6 +5,7 @@ LL | pub static mut symbol: [i8]; | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i8]` + = note: statics and constants must have a statically known size error: aborting due to 1 previous error diff --git a/tests/ui/static/issue-24446.stderr b/tests/ui/static/issue-24446.stderr index 033caf07d8e5..0e6e338c5efe 100644 --- a/tests/ui/static/issue-24446.stderr +++ b/tests/ui/static/issue-24446.stderr @@ -14,6 +14,7 @@ LL | static foo: dyn Fn() -> u32 = || -> u32 { | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)` + = note: statics and constants must have a statically known size error[E0308]: mismatched types --> $DIR/issue-24446.rs:2:35 diff --git a/tests/ui/statics/unsized_type2.stderr b/tests/ui/statics/unsized_type2.stderr index ffbbe218c87a..3f9b0879c166 100644 --- a/tests/ui/statics/unsized_type2.stderr +++ b/tests/ui/statics/unsized_type2.stderr @@ -10,6 +10,7 @@ note: required because it appears within the type `Foo` | LL | pub struct Foo { | ^^^ + = note: statics and constants must have a statically known size error[E0308]: mismatched types --> $DIR/unsized_type2.rs:14:45 diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr index 76e015a7238b..4609e02716fd 100644 --- a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr +++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr @@ -11,6 +11,7 @@ LL | const TEST: Fn = some_fn; | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)` + = note: statics and constants must have a statically known size error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time --> $DIR/ice-unsized-tuple-const-issue-121443.rs:11:14 From 9d3d5a7fbb9d28d91e2d19d2b0bf5bc5af5b038c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Feb 2025 02:21:58 +0000 Subject: [PATCH 597/991] Check signature WF when lowering MIR body --- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 18 ++++++++++++++++ tests/crashes/129095.rs | 5 ++++- tests/crashes/132960.rs | 2 +- tests/crashes/134654.rs | 3 +++ tests/crashes/135128.rs | 2 ++ tests/crashes/135570.rs | 3 +++ .../consts/dont-ctfe-unsized-initializer.rs | 7 +++++++ .../dont-ctfe-unsized-initializer.stderr | 21 +++++++++++++++++++ 9 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 tests/ui/consts/dont-ctfe-unsized-initializer.rs create mode 100644 tests/ui/consts/dont-ctfe-unsized-initializer.stderr diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 8199585ee61c..54aaf889b402 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -201,7 +201,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua hir::Node::ImplItem(item) => check_impl_item(tcx, item), hir::Node::ForeignItem(item) => check_foreign_item(tcx, item), hir::Node::OpaqueTy(_) => Ok(crate::check::check::check_item_type(tcx, def_id)), - _ => unreachable!(), + _ => unreachable!("{node:?}"), }; if let Some(generics) = node.generics() { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 04c9375b8317..5df12ac4d8bc 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -513,6 +513,24 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & body.tainted_by_errors = Some(error_reported); } + // Also taint the body if it's within a top-level item that is not well formed. + // + // We do this check here and not during `mir_promoted` because that may result + // in borrowck cycles if WF requires looking into an opaque hidden type. + let root = tcx.typeck_root_def_id(def.to_def_id()); + match tcx.def_kind(root) { + DefKind::Fn + | DefKind::AssocFn + | DefKind::Static { .. } + | DefKind::Const + | DefKind::AssocConst => { + if let Err(guar) = tcx.check_well_formed(root.expect_local()) { + body.tainted_by_errors = Some(guar); + } + } + _ => {} + } + run_analysis_to_runtime_passes(tcx, &mut body); tcx.alloc_steal_mir(body) diff --git a/tests/crashes/129095.rs b/tests/crashes/129095.rs index d82474e18e70..b1bb74708c2d 100644 --- a/tests/crashes/129095.rs +++ b/tests/crashes/129095.rs @@ -1,10 +1,13 @@ //@ known-bug: rust-lang/rust#129095 //@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir +#![feature(adt_const_params, unsized_const_params)] +#![allow(incomplete_features)] + pub fn function_with_bytes() -> &'static [u8] { BYTES } pub fn main() { - assert_eq!(function_with_bytes::(), &[0x41, 0x41, 0x41, 0x41]); + assert_eq!(function_with_bytes::(), &[0x41, 0x41, 0x41, 0x41]); } diff --git a/tests/crashes/132960.rs b/tests/crashes/132960.rs index 87d0ee7dedeb..c23a33934291 100644 --- a/tests/crashes/132960.rs +++ b/tests/crashes/132960.rs @@ -1,6 +1,6 @@ //@ known-bug: #132960 -#![feature(adt_const_params, const_ptr_read, generic_const_exprs)] +#![feature(adt_const_params, const_ptr_read, generic_const_exprs, unsized_const_params)] const fn concat_strs() -> &'static str where diff --git a/tests/crashes/134654.rs b/tests/crashes/134654.rs index 8a8d18359e96..f2323fe4ecdc 100644 --- a/tests/crashes/134654.rs +++ b/tests/crashes/134654.rs @@ -2,6 +2,9 @@ //@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir //@ only-x86_64 +#![feature(adt_const_params, unsized_const_params)] +#![allow(incomplete_features)] + fn function_with_bytes() -> &'static [u8] { BYTES diff --git a/tests/crashes/135128.rs b/tests/crashes/135128.rs index 2ce17df824a0..a8fd1ae1ff56 100644 --- a/tests/crashes/135128.rs +++ b/tests/crashes/135128.rs @@ -1,6 +1,8 @@ //@ known-bug: #135128 //@ compile-flags: -Copt-level=1 --edition=2021 +#![feature(trivial_bounds)] + async fn return_str() -> str where str: Sized, diff --git a/tests/crashes/135570.rs b/tests/crashes/135570.rs index a9eda97ef9de..7919ceb26d50 100644 --- a/tests/crashes/135570.rs +++ b/tests/crashes/135570.rs @@ -2,6 +2,9 @@ //@compile-flags: -Zvalidate-mir -Zmir-enable-passes=+Inline -Copt-level=0 -Zmir-enable-passes=+GVN //@ only-x86_64 +#![feature(adt_const_params, unsized_const_params)] +#![allow(incomplete_features)] + fn function_with_bytes( ) -> &'static [u8] { BYTES diff --git a/tests/ui/consts/dont-ctfe-unsized-initializer.rs b/tests/ui/consts/dont-ctfe-unsized-initializer.rs new file mode 100644 index 000000000000..cca38b760dcc --- /dev/null +++ b/tests/ui/consts/dont-ctfe-unsized-initializer.rs @@ -0,0 +1,7 @@ +static S: str = todo!(); +//~^ ERROR the size for values of type `str` cannot be known at compilation time + +const C: str = todo!(); +//~^ ERROR the size for values of type `str` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/consts/dont-ctfe-unsized-initializer.stderr b/tests/ui/consts/dont-ctfe-unsized-initializer.stderr new file mode 100644 index 000000000000..e69790fc1823 --- /dev/null +++ b/tests/ui/consts/dont-ctfe-unsized-initializer.stderr @@ -0,0 +1,21 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/dont-ctfe-unsized-initializer.rs:1:11 + | +LL | static S: str = todo!(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: statics and constants must have a statically known size + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/dont-ctfe-unsized-initializer.rs:4:10 + | +LL | const C: str = todo!(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: statics and constants must have a statically known size + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From 0baee2432a435fc587d458b7f7d0c19d7c239589 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 21 Feb 2025 19:22:08 +0000 Subject: [PATCH 598/991] Don't typeck during WF, instead check outside of WF in check_crate --- .../rustc_hir_analysis/src/check/check.rs | 7 +-- compiler/rustc_hir_analysis/src/check/mod.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 10 ++-- tests/rustdoc-ui/issues/issue-79494.rs | 2 +- tests/rustdoc-ui/issues/issue-79494.stderr | 6 +-- tests/rustdoc-ui/track-diagnostics.rs | 3 +- tests/rustdoc-ui/track-diagnostics.stderr | 4 +- .../unevaluated-const-ice-119731.stderr | 12 ++--- tests/ui/consts/issue-39974.stderr | 12 ++--- tests/ui/layout/issue-84108.stderr | 18 +++---- .../ui/type-alias-impl-trait/issue-53092-2.rs | 6 ++- .../issue-53092-2.stderr | 54 ++++++++++++++----- .../ui/wf/wf-normalization-sized.next.stderr | 20 +++---- 13 files changed, 90 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f2331f3fd8e1..f89f41aaf8af 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -745,14 +745,10 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { match tcx.def_kind(def_id) { DefKind::Static { .. } => { - tcx.ensure_ok().typeck(def_id); - maybe_check_static_with_link_section(tcx, def_id); check_static_inhabited(tcx, def_id); check_static_linkage(tcx, def_id); } - DefKind::Const => { - tcx.ensure_ok().typeck(def_id); - } + DefKind::Const => {} DefKind::Enum => { check_enum(tcx, def_id); } @@ -766,7 +762,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { ExternAbi::Rust, ) } - // Everything else is checked entirely within check_item_body } DefKind::Impl { of_trait } => { if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) { diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 1c5455710db8..89a759f7ddae 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -145,7 +145,7 @@ pub fn forbid_intrinsic_abi(tcx: TyCtxt<'_>, sp: Span, abi: ExternAbi) { } } -fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) { +pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) { // Only restricted on wasm target for now if !tcx.sess.target.is_like_wasm { return; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index cf18bab950ae..50b0e32b95eb 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -212,7 +212,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); match def_kind { - DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id), + DefKind::Static { .. } => { + tcx.ensure_ok().eval_static_initializer(item_def_id); + check::maybe_check_static_with_link_section(tcx, item_def_id); + } DefKind::Const if tcx.generics_of(item_def_id).is_empty() => { let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty()); let cid = GlobalId { instance, promoted: None }; @@ -223,12 +226,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) { } }); - // FIXME: Remove this when we implement creating `DefId`s - // for anon constants during their parents' typeck. - // Typeck all body owners in parallel will produce queries - // cycle errors because it may typeck on anon constants directly. tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); + // Skip `AnonConst`s because we feed their `type_of`. if !matches!(def_kind, DefKind::AnonConst) { tcx.ensure_ok().typeck(item_def_id); } diff --git a/tests/rustdoc-ui/issues/issue-79494.rs b/tests/rustdoc-ui/issues/issue-79494.rs index 7a1890c4429a..28ef82dac0f8 100644 --- a/tests/rustdoc-ui/issues/issue-79494.rs +++ b/tests/rustdoc-ui/issues/issue-79494.rs @@ -2,4 +2,4 @@ #![feature(const_transmute)] -const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; //~ ERROR cannot transmute between types of different sizes, or dependently-sized types +pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; //~ ERROR cannot transmute between types of different sizes, or dependently-sized types diff --git a/tests/rustdoc-ui/issues/issue-79494.stderr b/tests/rustdoc-ui/issues/issue-79494.stderr index abcd69d3aaef..20e568d8eaba 100644 --- a/tests/rustdoc-ui/issues/issue-79494.stderr +++ b/tests/rustdoc-ui/issues/issue-79494.stderr @@ -1,8 +1,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/issue-79494.rs:5:29 + --> $DIR/issue-79494.rs:5:33 | -LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; - | ^^^^^^^^^^^^^^^^^^^ +LL | pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; + | ^^^^^^^^^^^^^^^^^^^ | = note: source type: `usize` (64 bits) = note: target type: `&[u8]` (128 bits) diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs index 5c950a11082f..27781f47e0dd 100644 --- a/tests/rustdoc-ui/track-diagnostics.rs +++ b/tests/rustdoc-ui/track-diagnostics.rs @@ -7,4 +7,5 @@ struct A; struct B; -const S: A = B; + +pub const S: A = B; diff --git a/tests/rustdoc-ui/track-diagnostics.stderr b/tests/rustdoc-ui/track-diagnostics.stderr index 3d17570a7a2d..fb0d7b866449 100644 --- a/tests/rustdoc-ui/track-diagnostics.stderr +++ b/tests/rustdoc-ui/track-diagnostics.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types --> $DIR/track-diagnostics.rs:LL:CC | -LL | const S: A = B; - | ^ expected `A`, found `B` +LL | pub const S: A = B; + | ^ expected `A`, found `B` -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index 30a45ce377e7..b73611c79b29 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -54,12 +54,6 @@ warning: type `v17` should have an upper camel case name LL | pub struct v17 { | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `V17` -error[E0425]: cannot find function `v6` in this scope - --> $DIR/unevaluated-const-ice-119731.rs:13:35 - | -LL | const v0: [[usize; v4]; v4] = v6(v8); - | ^^ not found in this scope - error: `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter --> $DIR/unevaluated-const-ice-119731.rs:16:48 | @@ -72,6 +66,12 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more LL + #![feature(adt_const_params)] | +error[E0425]: cannot find function `v6` in this scope + --> $DIR/unevaluated-const-ice-119731.rs:13:35 + | +LL | const v0: [[usize; v4]; v4] = v6(v8); + | ^^ not found in this scope + error: maximum number of nodes exceeded in constant v20::v17::::{constant#0} --> $DIR/unevaluated-const-ice-119731.rs:28:37 | diff --git a/tests/ui/consts/issue-39974.stderr b/tests/ui/consts/issue-39974.stderr index a371ea5709e1..d03f709b0eaf 100644 --- a/tests/ui/consts/issue-39974.stderr +++ b/tests/ui/consts/issue-39974.stderr @@ -1,3 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/issue-39974.rs:5:19 + | +LL | f: [[f64; 2]; LENGTH], + | ^^^^^^ expected `usize`, found `f64` + error[E0308]: mismatched types --> $DIR/issue-39974.rs:1:21 | @@ -9,12 +15,6 @@ help: use a float literal LL | const LENGTH: f64 = 2.0; | ++ -error[E0308]: mismatched types - --> $DIR/issue-39974.rs:5:19 - | -LL | f: [[f64; 2]; LENGTH], - | ^^^^^^ expected `usize`, found `f64` - error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index 8ddce285e23f..e296abfc3b53 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -29,6 +29,15 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); = help: the trait `Sized` is not implemented for `[u8]` = note: only the last element of a tuple may have a dynamically sized type +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/issue-84108.rs:15:13 + | +LL | static BAZ: ([u8], usize) = ([], 0); + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/issue-84108.rs:9:12 | @@ -48,15 +57,6 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); = note: expected slice `[u8]` found array `[_; 0]` -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:15:13 - | -LL | static BAZ: ([u8], usize) = ([], 0); - | ^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` - = note: only the last element of a tuple may have a dynamically sized type - error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/issue-84108.rs:15:13 | diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.rs b/tests/ui/type-alias-impl-trait/issue-53092-2.rs index 2383008d042f..43df49adc423 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.rs @@ -2,10 +2,12 @@ #![allow(dead_code)] type Bug = impl Fn(T) -> U + Copy; +//~^ ERROR cycle detected const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; -//~^ ERROR cycle detected -//~| ERROR: non-defining opaque type use +//~^ ERROR item does not constrain `Bug::{opaque#0}`, but has it in its signature +//~| ERROR item does not constrain `Bug::{opaque#0}`, but has it in its signature +//~| ERROR non-defining opaque type use in defining scope fn make_bug>() -> Bug { |x| x.into() diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr index ac580866704d..678b0c84f78b 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -1,5 +1,5 @@ error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-53092-2.rs:6:18 + --> $DIR/issue-53092-2.rs:7:18 | LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; | ^^^^^^^^^^^ argument `u8` is not a generic parameter @@ -10,33 +10,59 @@ note: for this opaque type LL | type Bug = impl Fn(T) -> U + Copy; | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0391]: cycle detected when type-checking `CONST_BUG` - --> $DIR/issue-53092-2.rs:6:1 - | -LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: ...which requires computing layout of `Bug`... - = note: ...which requires normalizing `Bug`... -note: ...which requires computing type of `Bug::{opaque#0}`... +error[E0391]: cycle detected when computing type of `Bug::{opaque#0}` --> $DIR/issue-53092-2.rs:4:18 | LL | type Bug = impl Fn(T) -> U + Copy; | ^^^^^^^^^^^^^^^^^^^^^^ + | note: ...which requires computing type of opaque `Bug::{opaque#0}`... --> $DIR/issue-53092-2.rs:4:18 | LL | type Bug = impl Fn(T) -> U + Copy; | ^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires type-checking `CONST_BUG`, completing the cycle -note: cycle used when checking that `CONST_BUG` is well-formed - --> $DIR/issue-53092-2.rs:6:1 +note: ...which requires type-checking `CONST_BUG`... + --> $DIR/issue-53092-2.rs:7:1 | LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing layout of `Bug`... + = note: ...which requires normalizing `Bug`... + = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle +note: cycle used when checking that `Bug::{opaque#0}` is well-formed + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 2 previous errors +error: item does not constrain `Bug::{opaque#0}`, but has it in its signature + --> $DIR/issue-53092-2.rs:7:7 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `Bug::{opaque#0}`, but has it in its signature + --> $DIR/issue-53092-2.rs:7:61 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0391, E0792. For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/wf/wf-normalization-sized.next.stderr b/tests/ui/wf/wf-normalization-sized.next.stderr index 83b56bb6b19a..66c4f214415d 100644 --- a/tests/ui/wf/wf-normalization-sized.next.stderr +++ b/tests/ui/wf/wf-normalization-sized.next.stderr @@ -7,16 +7,6 @@ LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = (); = help: the trait `Sized` is not implemented for `[[[[[u8]]]]]` = note: slice and array elements must have `Sized` type -error[E0277]: the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time - --> $DIR/wf-normalization-sized.rs:19:11 - | -LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = (); - | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[[[[[u8]]]]]` - = note: slice and array elements must have `Sized` type - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/wf-normalization-sized.rs:22:11 | @@ -27,6 +17,16 @@ LL | const _: as WellUnformed>::RequestNormalize = (); note: required by an implicit `Sized` bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL +error[E0277]: the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time + --> $DIR/wf-normalization-sized.rs:19:11 + | +LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = (); + | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[[[[[u8]]]]]` + = note: slice and array elements must have `Sized` type + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/wf-normalization-sized.rs:22:11 | From e081b7b77e54a23ae11a95aaf2845446630cec42 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Mar 2025 03:16:53 +0000 Subject: [PATCH 599/991] Better reasons for inline failure --- compiler/rustc_mir_transform/src/inline.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 5981b5031c64..c043a9850dd8 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -606,14 +606,14 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( ty::EarlyBinder::bind(callee_body.clone()), ) else { debug!("failed to normalize callee body"); - return Err("implementation limitation"); + return Err("implementation limitation -- could not normalize callee body"); }; // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. if !validate_types(tcx, inliner.typing_env(), &callee_body, &caller_body).is_empty() { debug!("failed to validate callee body"); - return Err("implementation limitation"); + return Err("implementation limitation -- callee body failed validation"); } // Check call signature compatibility. @@ -622,8 +622,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( let output_type = callee_body.return_ty(); if !util::sub_types(tcx, inliner.typing_env(), output_type, destination_ty) { trace!(?output_type, ?destination_ty); - debug!("failed to normalize return type"); - return Err("implementation limitation"); + return Err("implementation limitation -- return type mismatch"); } if callsite.fn_sig.abi() == ExternAbi::RustCall { // FIXME: Don't inline user-written `extern "rust-call"` functions, @@ -653,7 +652,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) { trace!(?arg_ty, ?input_type); debug!("failed to normalize tuple argument type"); - return Err("implementation limitation"); + return Err("implementation limitation -- arg mismatch"); } } } else { @@ -663,7 +662,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) { trace!(?arg_ty, ?input_type); debug!("failed to normalize argument type"); - return Err("implementation limitation"); + return Err("implementation limitation -- arg mismatch"); } } } @@ -693,13 +692,13 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( // won't cause cycles on this. if !inliner.tcx().is_mir_available(callee_def_id) { debug!("item MIR unavailable"); - return Err("implementation limitation"); + return Err("implementation limitation -- MIR unavailable"); } } // These have no own callable MIR. InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => { debug!("instance without MIR (intrinsic / virtual)"); - return Err("implementation limitation"); + return Err("implementation limitation -- cannot inline intrinsic"); } // FIXME(#127030): `ConstParamHasTy` has bad interactions with @@ -709,7 +708,7 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( // substituted. InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => { debug!("still needs substitution"); - return Err("implementation limitation"); + return Err("implementation limitation -- HACK for dropping polymorphic type"); } // This cannot result in an immediate cycle since the callee MIR is a shim, which does From d33946c3ab1e818d07ec9ac8198fbe958f1985c6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Mar 2025 02:12:28 +0000 Subject: [PATCH 600/991] Inline FnOnce once again --- compiler/rustc_mir_transform/src/inline.rs | 23 +++---- ...ric_rust_call.call.Inline.panic-abort.diff | 29 ++++++-- ...ic_rust_call.call.Inline.panic-unwind.diff | 41 ++++++++--- .../inline/dont_ice_on_generic_rust_call.rs | 2 +- ...inline_box_fn.call.Inline.panic-abort.diff | 32 +++++++-- ...nline_box_fn.call.Inline.panic-unwind.diff | 47 ++++++++++--- tests/mir-opt/inline/inline_box_fn.rs | 2 +- .../inline_cycle.two.Inline.panic-abort.diff | 13 +++- .../inline_cycle.two.Inline.panic-unwind.diff | 13 +++- ...inline_diverging.h.Inline.panic-abort.diff | 24 +++---- ...nline_diverging.h.Inline.panic-unwind.diff | 40 +++-------- tests/mir-opt/inline/inline_diverging.rs | 3 +- .../issue_78442.bar.Inline.panic-abort.diff | 14 ++-- .../issue_78442.bar.Inline.panic-unwind.diff | 22 +++--- tests/mir-opt/inline/issue_78442.rs | 5 +- tests/mir-opt/inline_fn_call_for_fn_def.rs | 19 ++++++ ...inline_fn_call_for_fn_def.test.Inline.diff | 34 ++++++++++ ...it.PreCodegen.after.32bit.panic-abort.mir} | 0 ...t.PreCodegen.after.32bit.panic-unwind.mir} | 0 ...git.PreCodegen.after.64bit.panic-abort.mir | 68 +++++++++++++++++++ ...it.PreCodegen.after.64bit.panic-unwind.mir | 68 +++++++++++++++++++ tests/mir-opt/issues/issue_59352.rs | 2 + .../loops.mapped.PreCodegen.after.mir | 6 +- 23 files changed, 391 insertions(+), 116 deletions(-) create mode 100644 tests/mir-opt/inline_fn_call_for_fn_def.rs create mode 100644 tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff rename tests/mir-opt/issues/{issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir => issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir} (100%) rename tests/mir-opt/issues/{issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir => issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir} (100%) create mode 100644 tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir create mode 100644 tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index c043a9850dd8..0183ba19475c 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -625,13 +625,6 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( return Err("implementation limitation -- return type mismatch"); } if callsite.fn_sig.abi() == ExternAbi::RustCall { - // FIXME: Don't inline user-written `extern "rust-call"` functions, - // since this is generally perf-negative on rustc, and we hope that - // LLVM will inline these functions instead. - if callee_body.spread_arg.is_some() { - return Err("user-written rust-call functions"); - } - let (self_arg, arg_tuple) = match &args[..] { [arg_tuple] => (None, arg_tuple), [self_arg, arg_tuple] => (Some(self_arg), arg_tuple), @@ -641,18 +634,23 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( let self_arg_ty = self_arg.map(|self_arg| self_arg.node.ty(&caller_body.local_decls, tcx)); let arg_tuple_ty = arg_tuple.node.ty(&caller_body.local_decls, tcx); - let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else { - bug!("Closure arguments are not passed as a tuple"); + let arg_tys = if callee_body.spread_arg.is_some() { + std::slice::from_ref(&arg_tuple_ty) + } else { + let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else { + bug!("Closure arguments are not passed as a tuple"); + }; + arg_tuple_tys.as_slice() }; for (arg_ty, input) in - self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter()) + self_arg_ty.into_iter().chain(arg_tys.iter().copied()).zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) { trace!(?arg_ty, ?input_type); debug!("failed to normalize tuple argument type"); - return Err("implementation limitation -- arg mismatch"); + return Err("implementation limitation"); } } } else { @@ -1059,8 +1057,7 @@ fn make_call_args<'tcx, I: Inliner<'tcx>>( closure_ref_arg.chain(tuple_tmp_args).collect() } else { - // FIXME(edition_2024): switch back to a normal method call. - <_>::into_iter(args) + args.into_iter() .map(|a| create_temp_if_necessary(inliner, a.node, callsite, caller_body, return_block)) .collect() } diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff index 757617e59402..0615f8132af0 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff @@ -7,23 +7,42 @@ let mut _0: (); let mut _3: &mut std::boxed::Box>; let mut _4: I; ++ scope 1 (inlined > as FnMut>::call_mut) { ++ let mut _5: &mut dyn std::ops::FnMut; ++ let mut _6: std::boxed::Box>; ++ let mut _7: *const dyn std::ops::FnMut; ++ } bb0: { StorageLive(_3); _3 = &mut _1; StorageLive(_4); _4 = move _2; - _0 = > as FnMut>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable]; +- _0 = > as FnMut>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable]; ++ StorageLive(_6); ++ StorageLive(_7); ++ StorageLive(_5); ++ _6 = copy (*_3); ++ _7 = copy ((_6.0: std::ptr::Unique>).0: std::ptr::NonNull>) as *const dyn std::ops::FnMut (Transmute); ++ _5 = &mut (*_7); ++ _0 = as FnMut>::call_mut(move _5, move _4) -> [return: bb2, unwind unreachable]; } bb1: { - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb2, unwind unreachable]; +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb2, unwind unreachable]; ++ return; } bb2: { - return; +- return; ++ StorageDead(_5); ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_4); ++ StorageDead(_3); ++ drop(_1) -> [return: bb1, unwind unreachable]; } } diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff index b82961c2815d..21b20329d4fa 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff @@ -7,31 +7,54 @@ let mut _0: (); let mut _3: &mut std::boxed::Box>; let mut _4: I; ++ scope 1 (inlined > as FnMut>::call_mut) { ++ let mut _5: &mut dyn std::ops::FnMut; ++ let mut _6: std::boxed::Box>; ++ let mut _7: *const dyn std::ops::FnMut; ++ } bb0: { StorageLive(_3); _3 = &mut _1; StorageLive(_4); _4 = move _2; - _0 = > as FnMut>::call_mut(move _3, move _4) -> [return: bb1, unwind: bb3]; +- _0 = > as FnMut>::call_mut(move _3, move _4) -> [return: bb1, unwind: bb3]; ++ StorageLive(_6); ++ StorageLive(_7); ++ StorageLive(_5); ++ _6 = copy (*_3); ++ _7 = copy ((_6.0: std::ptr::Unique>).0: std::ptr::NonNull>) as *const dyn std::ops::FnMut (Transmute); ++ _5 = &mut (*_7); ++ _0 = as FnMut>::call_mut(move _5, move _4) -> [return: bb4, unwind: bb2]; } bb1: { - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb2, unwind: bb4]; +- StorageDead(_4); +- StorageDead(_3); +- drop(_1) -> [return: bb2, unwind: bb4]; ++ return; } - bb2: { - return; +- bb2: { +- return; ++ bb2 (cleanup): { ++ drop(_1) -> [return: bb3, unwind terminate(cleanup)]; } bb3 (cleanup): { - drop(_1) -> [return: bb4, unwind terminate(cleanup)]; +- drop(_1) -> [return: bb4, unwind terminate(cleanup)]; ++ resume; } - bb4 (cleanup): { - resume; +- bb4 (cleanup): { +- resume; ++ bb4: { ++ StorageDead(_5); ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_4); ++ StorageDead(_3); ++ drop(_1) -> [return: bb1, unwind: bb3]; } } diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs index abc0ef5c61d5..ac0c3ddac764 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs @@ -8,6 +8,6 @@ use std::marker::Tuple; // EMIT_MIR dont_ice_on_generic_rust_call.call.Inline.diff pub fn call(mut mock: Box>, input: I) { // CHECK-LABEL: fn call( - // CHECK-NOT: inlined + // CHECK: (inlined > as FnMut>::call_mut) mock.call_mut(input) } diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff index 4fa04b05e899..ecea7a97513d 100644 --- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff @@ -7,6 +7,11 @@ let _2: (); let mut _3: &std::boxed::Box; let mut _4: (i32,); ++ scope 1 (inlined as Fn<(i32,)>>::call) { ++ let mut _5: &dyn std::ops::Fn(i32); ++ let mut _6: std::boxed::Box; ++ let mut _7: *const dyn std::ops::Fn(i32); ++ } bb0: { StorageLive(_2); @@ -14,19 +19,34 @@ _3 = &_1; StorageLive(_4); _4 = (const 1_i32,); - _2 = as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable]; +- _2 = as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable]; ++ StorageLive(_6); ++ StorageLive(_7); ++ StorageLive(_5); ++ _6 = copy (*_3); ++ _7 = copy ((_6.0: std::ptr::Unique).0: std::ptr::NonNull) as *const dyn std::ops::Fn(i32) (Transmute); ++ _5 = &(*_7); ++ _2 = >::call(move _5, move _4) -> [return: bb2, unwind unreachable]; } bb1: { ++ return; ++ } ++ ++ bb2: { ++ StorageDead(_5); ++ StorageDead(_7); ++ StorageDead(_6); StorageDead(_4); StorageDead(_3); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb2, unwind unreachable]; - } - - bb2: { - return; +- drop(_1) -> [return: bb2, unwind unreachable]; +- } +- +- bb2: { +- return; ++ drop(_1) -> [return: bb1, unwind unreachable]; } } diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff index 47fd0ed07999..3a4a528e879f 100644 --- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff @@ -7,6 +7,11 @@ let _2: (); let mut _3: &std::boxed::Box; let mut _4: (i32,); ++ scope 1 (inlined as Fn<(i32,)>>::call) { ++ let mut _5: &dyn std::ops::Fn(i32); ++ let mut _6: std::boxed::Box; ++ let mut _7: *const dyn std::ops::Fn(i32); ++ } bb0: { StorageLive(_2); @@ -14,27 +19,47 @@ _3 = &_1; StorageLive(_4); _4 = (const 1_i32,); - _2 = as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind: bb3]; +- _2 = as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind: bb3]; ++ StorageLive(_6); ++ StorageLive(_7); ++ StorageLive(_5); ++ _6 = copy (*_3); ++ _7 = copy ((_6.0: std::ptr::Unique).0: std::ptr::NonNull) as *const dyn std::ops::Fn(i32) (Transmute); ++ _5 = &(*_7); ++ _2 = >::call(move _5, move _4) -> [return: bb4, unwind: bb2]; } bb1: { - StorageDead(_4); - StorageDead(_3); - StorageDead(_2); - _0 = const (); - drop(_1) -> [return: bb2, unwind: bb4]; +- StorageDead(_4); +- StorageDead(_3); +- StorageDead(_2); +- _0 = const (); +- drop(_1) -> [return: bb2, unwind: bb4]; ++ return; } - bb2: { - return; +- bb2: { +- return; ++ bb2 (cleanup): { ++ drop(_1) -> [return: bb3, unwind terminate(cleanup)]; } bb3 (cleanup): { - drop(_1) -> [return: bb4, unwind terminate(cleanup)]; +- drop(_1) -> [return: bb4, unwind terminate(cleanup)]; ++ resume; } - bb4 (cleanup): { - resume; +- bb4 (cleanup): { +- resume; ++ bb4: { ++ StorageDead(_5); ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_4); ++ StorageDead(_3); ++ StorageDead(_2); ++ _0 = const (); ++ drop(_1) -> [return: bb1, unwind: bb3]; } } diff --git a/tests/mir-opt/inline/inline_box_fn.rs b/tests/mir-opt/inline/inline_box_fn.rs index bb2da3ac5157..e9ab3bef01fb 100644 --- a/tests/mir-opt/inline/inline_box_fn.rs +++ b/tests/mir-opt/inline/inline_box_fn.rs @@ -5,6 +5,6 @@ // EMIT_MIR inline_box_fn.call.Inline.diff fn call(x: Box) { // CHECK-LABEL: fn call( - // CHECK-NOT: inlined + // CHECK: (inlined as Fn<(i32,)>>::call) x(1); } diff --git a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff index 8a6eec3352a3..c878b8b63241 100644 --- a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff @@ -5,9 +5,15 @@ let mut _0: (); let _1: (); + let mut _2: fn() {f}; ++ let mut _4: (); + scope 1 (inlined call::) { + debug f => _2; + let _3: (); ++ scope 2 (inlined >::call_once - shim(fn() {f})) { ++ scope 3 (inlined f) { ++ let _5: (); ++ } ++ } + } bb0: { @@ -16,10 +22,15 @@ + StorageLive(_2); + _2 = f; + StorageLive(_3); -+ _3 = >::call_once(move _2, const ()) -> [return: bb1, unwind unreachable]; ++ StorageLive(_4); ++ _4 = const (); ++ StorageLive(_5); ++ _5 = call::(f) -> [return: bb1, unwind unreachable]; } bb1: { ++ StorageDead(_5); ++ StorageDead(_4); + StorageDead(_3); + StorageDead(_2); StorageDead(_1); diff --git a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff index a24649c1ebd5..072b7ab3fa49 100644 --- a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff @@ -5,9 +5,15 @@ let mut _0: (); let _1: (); + let mut _2: fn() {f}; ++ let mut _4: (); + scope 1 (inlined call::) { + debug f => _2; + let _3: (); ++ scope 2 (inlined >::call_once - shim(fn() {f})) { ++ scope 3 (inlined f) { ++ let _5: (); ++ } ++ } + } bb0: { @@ -16,10 +22,15 @@ + StorageLive(_2); + _2 = f; + StorageLive(_3); -+ _3 = >::call_once(move _2, const ()) -> [return: bb1, unwind continue]; ++ StorageLive(_4); ++ _4 = const (); ++ StorageLive(_5); ++ _5 = call::(f) -> [return: bb1, unwind continue]; } bb1: { ++ StorageDead(_5); ++ StorageDead(_4); + StorageDead(_3); + StorageDead(_2); StorageDead(_1); diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff index 338dca85e5c9..75fc2ea16e3d 100644 --- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff @@ -5,6 +5,7 @@ let mut _0: (); let _1: (!, !); + let mut _2: fn() -> ! {sleep}; ++ let mut _7: (); + scope 1 (inlined call_twice:: ! {sleep}>) { + debug f => _2; + let mut _3: &fn() -> ! {sleep}; @@ -17,6 +18,10 @@ + debug b => _6; + } + } ++ scope 4 (inlined ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { ++ scope 5 (inlined sleep) { ++ } ++ } + } bb0: { @@ -28,24 +33,13 @@ + StorageLive(_6); + StorageLive(_3); + _3 = &_2; -+ _4 = ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind unreachable]; ++ StorageLive(_7); ++ _7 = const (); ++ goto -> bb1; + } + + bb1: { -+ StorageDead(_3); -+ StorageLive(_5); -+ _5 = &_2; -+ _6 = ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind unreachable]; -+ } -+ -+ bb2: { -+ StorageDead(_5); -+ _1 = (copy _4, copy _6); -+ drop(_2) -> [return: bb3, unwind unreachable]; -+ } -+ -+ bb3: { -+ unreachable; ++ goto -> bb1; } } diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff index a77cb913bfd0..407cb24df675 100644 --- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff @@ -5,6 +5,7 @@ let mut _0: (); let _1: (!, !); + let mut _2: fn() -> ! {sleep}; ++ let mut _8: (); + scope 1 (inlined call_twice:: ! {sleep}>) { + debug f => _2; + let mut _3: &fn() -> ! {sleep}; @@ -18,6 +19,10 @@ + debug b => _6; + } + } ++ scope 4 (inlined ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { ++ scope 5 (inlined sleep) { ++ } ++ } + } bb0: { @@ -29,40 +34,13 @@ + StorageLive(_4); + StorageLive(_3); + _3 = &_2; -+ _4 = ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind: bb5]; ++ StorageLive(_8); ++ _8 = const (); ++ goto -> bb1; + } + + bb1: { -+ StorageDead(_3); -+ StorageLive(_5); -+ _5 = &_2; -+ _6 = ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind: bb4]; -+ } -+ -+ bb2: { -+ StorageDead(_5); -+ StorageLive(_7); -+ _7 = move _4; -+ _1 = (move _7, copy _6); -+ StorageDead(_7); -+ StorageDead(_4); -+ drop(_2) -> [return: bb3, unwind continue]; -+ } -+ -+ bb3: { -+ unreachable; -+ } -+ -+ bb4 (cleanup): { -+ drop(_4) -> [return: bb5, unwind terminate(cleanup)]; -+ } -+ -+ bb5 (cleanup): { -+ drop(_2) -> [return: bb6, unwind terminate(cleanup)]; -+ } -+ -+ bb6 (cleanup): { -+ resume; ++ goto -> bb1; } } diff --git a/tests/mir-opt/inline/inline_diverging.rs b/tests/mir-opt/inline/inline_diverging.rs index e1cea3618f17..04ff943e7465 100644 --- a/tests/mir-opt/inline/inline_diverging.rs +++ b/tests/mir-opt/inline/inline_diverging.rs @@ -26,7 +26,8 @@ pub fn g(i: i32) -> u32 { pub fn h() { // CHECK-LABEL: fn h( // CHECK: (inlined call_twice:: ! {sleep}>) - // CHECK-NOT: inlined + // CHECK: (inlined ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) + // CHECK: (inlined sleep) call_twice(sleep); } diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff index b9f268df3515..14a0c639c3ab 100644 --- a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff @@ -9,6 +9,10 @@ let _4: fn() {foo}; let mut _5: (); + scope 1 (inlined hide_foo) { ++ } ++ scope 2 (inlined >::call - shim(fn() {foo})) { ++ scope 3 (inlined foo) { ++ } + } bb0: { @@ -23,22 +27,20 @@ StorageLive(_5); _5 = (); - _2 = >::call(move _3, move _5) -> [return: bb2, unwind unreachable]; -+ _2 = >::call(move _3, move _5) -> [return: bb1, unwind unreachable]; - } - +- } +- - bb2: { -+ bb1: { StorageDead(_5); StorageDead(_3); StorageDead(_4); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb3, unwind unreachable]; -+ drop(_1) -> [return: bb2, unwind unreachable]; ++ drop(_1) -> [return: bb1, unwind unreachable]; } - bb3: { -+ bb2: { ++ bb1: { return; } } diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff index 8495164df9c6..e0a273eb13f5 100644 --- a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff @@ -9,6 +9,10 @@ let _4: fn() {foo}; let mut _5: (); + scope 1 (inlined hide_foo) { ++ } ++ scope 2 (inlined >::call - shim(fn() {foo})) { ++ scope 3 (inlined foo) { ++ } + } bb0: { @@ -23,33 +27,29 @@ StorageLive(_5); _5 = (); - _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; -+ _2 = >::call(move _3, move _5) -> [return: bb1, unwind: bb3]; - } - +- } +- - bb2: { -+ bb1: { StorageDead(_5); StorageDead(_3); StorageDead(_4); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb3, unwind: bb5]; -+ drop(_1) -> [return: bb2, unwind: bb4]; ++ drop(_1) -> [return: bb1, unwind: bb2]; } - bb3: { -+ bb2: { ++ bb1: { return; } - bb4 (cleanup): { - drop(_1) -> [return: bb5, unwind terminate(cleanup)]; -+ bb3 (cleanup): { -+ drop(_1) -> [return: bb4, unwind terminate(cleanup)]; - } - +- } +- - bb5 (cleanup): { -+ bb4 (cleanup): { ++ bb2 (cleanup): { resume; } } diff --git a/tests/mir-opt/inline/issue_78442.rs b/tests/mir-opt/inline/issue_78442.rs index 4eb5c142034c..a142d4573774 100644 --- a/tests/mir-opt/inline/issue_78442.rs +++ b/tests/mir-opt/inline/issue_78442.rs @@ -9,10 +9,9 @@ pub fn bar
` tag, it is formatted using
 // a whitespace prefix and newline.
-fn render_attributes_in_pre<'a, 'tcx: 'a>(
-    it: &'a clean::Item,
-    prefix: &'a str,
-    cx: &'a Context<'tcx>,
-) -> impl fmt::Display + Captures<'a> + Captures<'tcx> {
+fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         for a in it.attributes(cx.tcx(), cx.cache(), false) {
             writeln!(f, "{prefix}{a}")?;
@@ -1206,12 +1201,12 @@ impl<'a> AssocItemLink<'a> {
     }
 }
 
-pub fn write_section_heading<'a>(
-    title: &'a str,
-    id: &'a str,
-    extra_class: Option<&'a str>,
-    extra: impl fmt::Display + 'a,
-) -> impl fmt::Display + 'a {
+pub fn write_section_heading(
+    title: &str,
+    id: &str,
+    extra_class: Option<&str>,
+    extra: impl fmt::Display,
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let (extra_class, whitespace) = match extra_class {
             Some(extra) => (extra, " "),
@@ -1227,7 +1222,7 @@ pub fn write_section_heading<'a>(
     })
 }
 
-fn write_impl_section_heading<'a>(title: &'a str, id: &'a str) -> impl fmt::Display + 'a {
+fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display {
     write_section_heading(title, id, None, "")
 }
 
@@ -1276,12 +1271,12 @@ pub(crate) fn render_all_impls(
     }
 }
 
-fn render_assoc_items<'a, 'cx: 'a>(
-    cx: &'a Context<'cx>,
-    containing_item: &'a clean::Item,
+fn render_assoc_items(
+    cx: &Context<'_>,
+    containing_item: &clean::Item,
     it: DefId,
-    what: AssocItemRender<'a>,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+    what: AssocItemRender<'_>,
+) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         let mut derefs = DefIdSet::default();
         derefs.insert(it);
@@ -1466,10 +1461,10 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
     }
 }
 
-pub(crate) fn notable_traits_button<'a, 'tcx>(
-    ty: &'a clean::Type,
-    cx: &'a Context<'tcx>,
-) -> Option> {
+pub(crate) fn notable_traits_button(
+    ty: &clean::Type,
+    cx: &Context<'_>,
+) -> Option {
     let mut has_notable_trait = false;
 
     if ty.is_unit() {
@@ -1623,16 +1618,16 @@ struct ImplRenderingParameters {
     toggle_open_by_default: bool,
 }
 
-fn render_impl<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    i: &'a Impl,
-    parent: &'a clean::Item,
-    link: AssocItemLink<'a>,
+fn render_impl(
+    cx: &Context<'_>,
+    i: &Impl,
+    parent: &clean::Item,
+    link: AssocItemLink<'_>,
     render_mode: RenderMode,
     use_absolute: Option,
-    aliases: &'a [String],
+    aliases: &[String],
     rendering_params: ImplRenderingParameters,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let cache = &cx.shared.cache;
         let traits = &cache.traits;
@@ -1780,7 +1775,7 @@ fn render_impl<'a, 'tcx>(
                         );
                     }
                 }
-                clean::RequiredAssocConstItem(ref generics, ref ty) => {
+                clean::RequiredAssocConstItem(generics, ty) => {
                     let source_id = format!("{item_type}.{name}");
                     let id = cx.derive_id(&source_id);
                     write_str(
@@ -1847,7 +1842,7 @@ fn render_impl<'a, 'tcx>(
                         ),
                     );
                 }
-                clean::RequiredAssocTypeItem(ref generics, ref bounds) => {
+                clean::RequiredAssocTypeItem(generics, bounds) => {
                     let source_id = format!("{item_type}.{name}");
                     let id = cx.derive_id(&source_id);
                     write_str(
@@ -2135,11 +2130,11 @@ fn render_impl<'a, 'tcx>(
 
 // Render the items that appear on the right side of methods, impls, and
 // associated types. For example "1.0.0 (const: 1.39.0) · source".
-fn render_rightside<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    item: &'a clean::Item,
+fn render_rightside(
+    cx: &Context<'_>,
+    item: &clean::Item,
     render_mode: RenderMode,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     let tcx = cx.tcx();
 
     fmt::from_fn(move |w| {
@@ -2174,17 +2169,17 @@ fn render_rightside<'a, 'tcx>(
     })
 }
 
-pub(crate) fn render_impl_summary<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    i: &'a Impl,
-    parent: &'a clean::Item,
+pub(crate) fn render_impl_summary(
+    cx: &Context<'_>,
+    i: &Impl,
+    parent: &clean::Item,
     show_def_docs: bool,
     use_absolute: Option,
     // This argument is used to reference same type with different paths to avoid duplication
     // in documentation pages for trait with automatic implementations like "Send" and "Sync".
-    aliases: &'a [String],
-    doc: Option<&'a str>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+    aliases: &[String],
+    doc: Option<&str>,
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let inner_impl = i.inner_impl();
         let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id));
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index b647b2aad75a..c599a84ee44e 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -4,7 +4,6 @@ use std::fmt::{Display, Write as _};
 
 use rinja::Template;
 use rustc_abi::VariantIdx;
-use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
@@ -92,44 +91,32 @@ macro_rules! item_template {
 macro_rules! item_template_methods {
     () => {};
     (document $($rest:tt)*) => {
-        fn document<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let (item, cx) = self.item_and_cx();
-                let v = document(cx, item, None, HeadingOffset::H2);
-                write!(f, "{v}")
-            })
+        fn document(&self) -> impl fmt::Display {
+            let (item, cx) = self.item_and_cx();
+            document(cx, item, None, HeadingOffset::H2)
         }
         item_template_methods!($($rest)*);
     };
     (document_type_layout $($rest:tt)*) => {
-        fn document_type_layout<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let (item, cx) = self.item_and_cx();
-                let def_id = item.item_id.expect_def_id();
-                let v = document_type_layout(cx, def_id);
-                write!(f, "{v}")
-            })
+        fn document_type_layout(&self) -> impl fmt::Display {
+            let (item, cx) = self.item_and_cx();
+            let def_id = item.item_id.expect_def_id();
+            document_type_layout(cx, def_id)
         }
         item_template_methods!($($rest)*);
     };
     (render_attributes_in_pre $($rest:tt)*) => {
-        fn render_attributes_in_pre<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let (item, cx) = self.item_and_cx();
-                let v = render_attributes_in_pre(item, "", cx);
-                write!(f, "{v}")
-            })
+        fn render_attributes_in_pre(&self) -> impl fmt::Display {
+            let (item, cx) = self.item_and_cx();
+            render_attributes_in_pre(item, "", cx)
         }
         item_template_methods!($($rest)*);
     };
     (render_assoc_items $($rest:tt)*) => {
-        fn render_assoc_items<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let (item, cx) = self.item_and_cx();
-                let def_id = item.item_id.expect_def_id();
-                let v = render_assoc_items(cx, item, def_id, AssocItemRender::All);
-                write!(f, "{v}")
-            })
+        fn render_assoc_items(&self) -> impl fmt::Display {
+            let (item, cx) = self.item_and_cx();
+            let def_id = item.item_id.expect_def_id();
+            render_assoc_items(cx, item, def_id, AssocItemRender::All)
         }
         item_template_methods!($($rest)*);
     };
@@ -162,10 +149,7 @@ struct ItemVars<'a> {
     src_href: Option<&'a str>,
 }
 
-pub(super) fn print_item<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    item: &'a clean::Item,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item) -> impl fmt::Display {
     debug_assert!(!item.is_stripped());
 
     fmt::from_fn(|buf| {
@@ -241,30 +225,30 @@ pub(super) fn print_item<'a, 'tcx>(
         item_vars.render_into(buf).unwrap();
 
         match &item.kind {
-            clean::ModuleItem(ref m) => {
+            clean::ModuleItem(m) => {
                 write!(buf, "{}", item_module(cx, item, &m.items))
             }
-            clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f, _) => {
+            clean::FunctionItem(f) | clean::ForeignFunctionItem(f, _) => {
                 write!(buf, "{}", item_function(cx, item, f))
             }
-            clean::TraitItem(ref t) => write!(buf, "{}", item_trait(cx, item, t)),
-            clean::StructItem(ref s) => {
+            clean::TraitItem(t) => write!(buf, "{}", item_trait(cx, item, t)),
+            clean::StructItem(s) => {
                 write!(buf, "{}", item_struct(cx, item, s))
             }
-            clean::UnionItem(ref s) => write!(buf, "{}", item_union(cx, item, s)),
-            clean::EnumItem(ref e) => write!(buf, "{}", item_enum(cx, item, e)),
-            clean::TypeAliasItem(ref t) => {
+            clean::UnionItem(s) => write!(buf, "{}", item_union(cx, item, s)),
+            clean::EnumItem(e) => write!(buf, "{}", item_enum(cx, item, e)),
+            clean::TypeAliasItem(t) => {
                 write!(buf, "{}", item_type_alias(cx, item, t))
             }
-            clean::MacroItem(ref m) => write!(buf, "{}", item_macro(cx, item, m)),
-            clean::ProcMacroItem(ref m) => {
+            clean::MacroItem(m) => write!(buf, "{}", item_macro(cx, item, m)),
+            clean::ProcMacroItem(m) => {
                 write!(buf, "{}", item_proc_macro(cx, item, m))
             }
             clean::PrimitiveItem(_) => write!(buf, "{}", item_primitive(cx, item)),
-            clean::StaticItem(ref i) => {
+            clean::StaticItem(i) => {
                 write!(buf, "{}", item_static(cx, item, i, None))
             }
-            clean::ForeignStaticItem(ref i, safety) => {
+            clean::ForeignStaticItem(i, safety) => {
                 write!(buf, "{}", item_static(cx, item, i, Some(*safety)))
             }
             clean::ConstantItem(ci) => {
@@ -274,7 +258,7 @@ pub(super) fn print_item<'a, 'tcx>(
                 write!(buf, "{}", item_foreign_type(cx, item))
             }
             clean::KeywordItem => write!(buf, "{}", item_keyword(cx, item)),
-            clean::TraitAliasItem(ref ta) => {
+            clean::TraitAliasItem(ta) => {
                 write!(buf, "{}", item_trait_alias(cx, item, ta))
             }
             _ => {
@@ -321,11 +305,7 @@ trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + Display {
     fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>);
 }
 
-fn item_module<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    item: &'a clean::Item,
-    items: &'a [clean::Item],
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> impl fmt::Display {
     fmt::from_fn(|w| {
         write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?;
 
@@ -541,14 +521,14 @@ fn item_module<'a, 'tcx>(
 
 /// Render the stability, deprecation and portability tags that are displayed in the item's summary
 /// at the module level.
-fn extra_info_tags<'a, 'tcx: 'a>(
-    tcx: TyCtxt<'tcx>,
-    item: &'a clean::Item,
-    parent: &'a clean::Item,
+fn extra_info_tags(
+    tcx: TyCtxt<'_>,
+    item: &clean::Item,
+    parent: &clean::Item,
     import_def_id: Option,
-) -> impl Display + 'a + Captures<'tcx> {
+) -> impl Display {
     fmt::from_fn(move |f| {
-        fn tag_html<'a>(class: &'a str, title: &'a str, contents: &'a str) -> impl Display + 'a {
+        fn tag_html(class: &str, title: &str, contents: &str) -> impl Display {
             fmt::from_fn(move |f| {
                 write!(
                     f,
@@ -597,11 +577,7 @@ fn extra_info_tags<'a, 'tcx: 'a>(
     })
 }
 
-fn item_function<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    f: &'a clean::Function,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> impl fmt::Display {
     fmt::from_fn(|w| {
         let tcx = cx.tcx();
         let header = it.fn_header(tcx).expect("printing a function which isn't a function");
@@ -657,11 +633,7 @@ fn item_function<'a, 'tcx>(
     })
 }
 
-fn item_trait<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    t: &'a clean::Trait,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt::Display {
     fmt::from_fn(|w| {
         let tcx = cx.tcx();
         let bounds = bounds(&t.bounds, false, cx);
@@ -831,11 +803,7 @@ fn item_trait<'a, 'tcx>(
         // Trait documentation
         write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
 
-        fn trait_item<'a, 'tcx>(
-            cx: &'a Context<'tcx>,
-            m: &'a clean::Item,
-            t: &'a clean::Item,
-        ) -> impl fmt::Display + 'a + Captures<'tcx> {
+        fn trait_item(cx: &Context<'_>, m: &clean::Item, t: &clean::Item) -> impl fmt::Display {
             fmt::from_fn(|w| {
                 let name = m.name.unwrap();
                 info!("Documenting {name} on {ty_name:?}", ty_name = t.name);
@@ -1021,7 +989,7 @@ fn item_trait<'a, 'tcx>(
                     extern_crates.insert(did.krate);
                 }
                 match implementor.inner_impl().for_.without_borrowed_ref() {
-                    clean::Type::Path { ref path } if !path.is_assoc_ty() => {
+                    clean::Type::Path { path } if !path.is_assoc_ty() => {
                         let did = path.def_id();
                         let &mut (prev_did, ref mut has_duplicates) =
                             implementor_dups.entry(path.last()).or_insert((did, false));
@@ -1254,11 +1222,11 @@ fn item_trait<'a, 'tcx>(
     })
 }
 
-fn item_trait_alias<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    t: &'a clean::TraitAlias,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_trait_alias(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    t: &clean::TraitAlias,
+) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             write!(
@@ -1285,11 +1253,7 @@ fn item_trait_alias<'a, 'tcx>(
     })
 }
 
-fn item_type_alias<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    t: &'a clean::TypeAlias,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             write!(
@@ -1499,11 +1463,7 @@ fn item_type_alias<'a, 'tcx>(
     })
 }
 
-fn item_union<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    s: &'a clean::Union,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt::Display {
     item_template!(
         #[template(path = "item_union.html")]
         struct ItemUnion<'a, 'cx> {
@@ -1515,35 +1475,20 @@ fn item_union<'a, 'tcx>(
     );
 
     impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
-        fn render_union<'b>(&'b self) -> impl Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let v = render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx);
-                write!(f, "{v}")
-            })
+        fn render_union(&self) -> impl Display {
+            render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx)
         }
 
-        fn document_field<'b>(
-            &'b self,
-            field: &'a clean::Item,
-        ) -> impl Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let v = document(self.cx, field, Some(self.it), HeadingOffset::H3);
-                write!(f, "{v}")
-            })
+        fn document_field(&self, field: &'a clean::Item) -> impl Display {
+            document(self.cx, field, Some(self.it), HeadingOffset::H3)
         }
 
         fn stability_field(&self, field: &clean::Item) -> Option {
             field.stability_class(self.cx.tcx())
         }
 
-        fn print_ty<'b>(
-            &'b self,
-            ty: &'a clean::Type,
-        ) -> impl Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let v = ty.print(self.cx);
-                write!(f, "{v}")
-            })
+        fn print_ty(&self, ty: &'a clean::Type) -> impl Display {
+            ty.print(self.cx)
         }
 
         fn fields_iter(
@@ -1566,10 +1511,7 @@ fn item_union<'a, 'tcx>(
     })
 }
 
-fn print_tuple_struct_fields<'a, 'cx: 'a>(
-    cx: &'a Context<'cx>,
-    s: &'a [clean::Item],
-) -> impl Display + 'a + Captures<'cx> {
+fn print_tuple_struct_fields(cx: &Context<'_>, s: &[clean::Item]) -> impl Display {
     fmt::from_fn(|f| {
         if !s.is_empty()
             && s.iter().all(|field| {
@@ -1591,11 +1533,7 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>(
     })
 }
 
-fn item_enum<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    e: &'a clean::Enum,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_enum(cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) -> impl fmt::Display {
     fmt::from_fn(|w| {
         let count_variants = e.variants().count();
         wrap_item(w, |w| {
@@ -1658,14 +1596,14 @@ fn should_show_enum_discriminant(
     repr.c() || repr.int.is_some()
 }
 
-fn display_c_like_variant<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    item: &'a clean::Item,
-    variant: &'a clean::Variant,
+fn display_c_like_variant(
+    cx: &Context<'_>,
+    item: &clean::Item,
+    variant: &clean::Variant,
     index: VariantIdx,
     should_show_enum_discriminant: bool,
     enum_def_id: DefId,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let name = item.name.unwrap();
         if let Some(ref value) = variant.discriminant {
@@ -1685,15 +1623,15 @@ fn display_c_like_variant<'a, 'tcx>(
     })
 }
 
-fn render_enum_fields<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    g: Option<&'a clean::Generics>,
-    variants: &'a IndexVec,
+fn render_enum_fields(
+    cx: &Context<'_>,
+    g: Option<&clean::Generics>,
+    variants: &IndexVec,
     count_variants: usize,
     has_stripped_entries: bool,
     is_non_exhaustive: bool,
     enum_def_id: DefId,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let should_show_enum_discriminant =
             should_show_enum_discriminant(cx, enum_def_id, variants);
@@ -1764,12 +1702,12 @@ fn render_enum_fields<'a, 'tcx>(
     })
 }
 
-fn item_variants<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    variants: &'a IndexVec,
+fn item_variants(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    variants: &IndexVec,
     enum_def_id: DefId,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let tcx = cx.tcx();
         write!(
@@ -1895,11 +1833,7 @@ fn item_variants<'a, 'tcx>(
     })
 }
 
-fn item_macro<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    t: &'a clean::Macro,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`.
@@ -1912,11 +1846,7 @@ fn item_macro<'a, 'tcx>(
     })
 }
 
-fn item_proc_macro<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    m: &'a clean::ProcMacro,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_proc_macro(cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             let name = it.name.expect("proc-macros always have names");
@@ -1947,10 +1877,7 @@ fn item_proc_macro<'a, 'tcx>(
     })
 }
 
-fn item_primitive<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_primitive(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
     fmt::from_fn(|w| {
         let def_id = it.item_id.expect_def_id();
         write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
@@ -1968,13 +1895,13 @@ fn item_primitive<'a, 'tcx>(
     })
 }
 
-fn item_constant<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    generics: &'a clean::Generics,
-    ty: &'a clean::Type,
-    c: &'a clean::ConstantKind,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_constant(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    generics: &clean::Generics,
+    ty: &clean::Type,
+    c: &clean::ConstantKind,
+) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             let tcx = cx.tcx();
@@ -2028,11 +1955,7 @@ fn item_constant<'a, 'tcx>(
     })
 }
 
-fn item_struct<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    s: &'a clean::Struct,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_struct(cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             render_attributes_in_code(w, it, cx);
@@ -2056,12 +1979,12 @@ fn item_struct<'a, 'tcx>(
     })
 }
 
-fn item_fields<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    fields: &'a [clean::Item],
+fn item_fields(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    fields: &[clean::Item],
     ctor_kind: Option,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let mut fields = fields
             .iter()
@@ -2111,12 +2034,12 @@ fn item_fields<'a, 'tcx>(
     })
 }
 
-fn item_static<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    s: &'a clean::Static,
+fn item_static(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    s: &clean::Static,
     safety: Option,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         wrap_item(w, |w| {
             render_attributes_in_code(w, it, cx);
@@ -2135,10 +2058,7 @@ fn item_static<'a, 'tcx>(
     })
 }
 
-fn item_foreign_type<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             w.write_str("extern {\n")?;
@@ -2155,10 +2075,7 @@ fn item_foreign_type<'a, 'tcx>(
     })
 }
 
-fn item_keyword<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_keyword(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
     document(cx, it, None, HeadingOffset::H2)
 }
 
@@ -2268,18 +2185,14 @@ pub(super) fn full_path(cx: &Context<'_>, item: &clean::Item) -> String {
     s
 }
 
-pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display + '_ {
+pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display {
     fmt::from_fn(move |f| match ty {
         ItemType::Module => write!(f, "{}index.html", ensure_trailing_slash(name)),
         _ => write!(f, "{ty}.{name}.html"),
     })
 }
 
-fn bounds<'a, 'tcx>(
-    bounds: &'a [clean::GenericBound],
-    trait_alias: bool,
-    cx: &'a Context<'tcx>,
-) -> impl Display + 'a + Captures<'tcx> {
+fn bounds(bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>) -> impl Display {
     (!bounds.is_empty())
         .then_some(fmt::from_fn(move |f| {
             let has_lots_of_bounds = bounds.len() > 2;
@@ -2329,13 +2242,13 @@ impl Ord for ImplString {
     }
 }
 
-fn render_implementor<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    implementor: &'a Impl,
-    trait_: &'a clean::Item,
-    implementor_dups: &'a FxHashMap,
-    aliases: &'a [String],
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn render_implementor(
+    cx: &Context<'_>,
+    implementor: &Impl,
+    trait_: &clean::Item,
+    implementor_dups: &FxHashMap,
+    aliases: &[String],
+) -> impl fmt::Display {
     // If there's already another implementor that has the same abridged name, use the
     // full path, for example in `std::iter::ExactSizeIterator`
     let use_absolute = match implementor.inner_impl().for_ {
@@ -2364,12 +2277,12 @@ fn render_implementor<'a, 'tcx>(
     )
 }
 
-fn render_union<'a, 'cx: 'a>(
-    it: &'a clean::Item,
-    g: Option<&'a clean::Generics>,
-    fields: &'a [clean::Item],
-    cx: &'a Context<'cx>,
-) -> impl Display + 'a + Captures<'cx> {
+fn render_union(
+    it: &clean::Item,
+    g: Option<&clean::Generics>,
+    fields: &[clean::Item],
+    cx: &Context<'_>,
+) -> impl Display {
     fmt::from_fn(move |mut f| {
         write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?;
 
@@ -2421,15 +2334,15 @@ fn render_union<'a, 'cx: 'a>(
     })
 }
 
-fn render_struct<'a, 'tcx>(
-    it: &'a clean::Item,
-    g: Option<&'a clean::Generics>,
+fn render_struct(
+    it: &clean::Item,
+    g: Option<&clean::Generics>,
     ty: Option,
-    fields: &'a [clean::Item],
-    tab: &'a str,
+    fields: &[clean::Item],
+    tab: &str,
     structhead: bool,
-    cx: &'a Context<'tcx>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+    cx: &Context<'_>,
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         write!(
             w,
@@ -2457,15 +2370,15 @@ fn render_struct<'a, 'tcx>(
     })
 }
 
-fn render_struct_fields<'a, 'tcx>(
-    g: Option<&'a clean::Generics>,
+fn render_struct_fields(
+    g: Option<&clean::Generics>,
     ty: Option,
-    fields: &'a [clean::Item],
-    tab: &'a str,
+    fields: &[clean::Item],
+    tab: &str,
     structhead: bool,
     has_stripped_entries: bool,
-    cx: &'a Context<'tcx>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+    cx: &Context<'_>,
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         match ty {
             None => {
@@ -2581,7 +2494,7 @@ fn document_non_exhaustive_header(item: &clean::Item) -> &str {
     if item.is_non_exhaustive() { " (Non-exhaustive)" } else { "" }
 }
 
-fn document_non_exhaustive(item: &clean::Item) -> impl Display + '_ {
+fn document_non_exhaustive(item: &clean::Item) -> impl Display {
     fmt::from_fn(|f| {
         if item.is_non_exhaustive() {
             write!(
diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs
index 0f01db5f6bcc..a1ee5c8c548b 100644
--- a/src/librustdoc/html/render/type_layout.rs
+++ b/src/librustdoc/html/render/type_layout.rs
@@ -2,7 +2,6 @@ use std::fmt;
 
 use rinja::Template;
 use rustc_abi::{Primitive, TagEncoding, Variants};
-use rustc_data_structures::captures::Captures;
 use rustc_hir::def_id::DefId;
 use rustc_middle::span_bug;
 use rustc_middle::ty::layout::LayoutError;
@@ -26,10 +25,7 @@ struct TypeLayoutSize {
     size: u64,
 }
 
-pub(crate) fn document_type_layout<'a, 'cx: 'a>(
-    cx: &'a Context<'cx>,
-    ty_def_id: DefId,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+pub(crate) fn document_type_layout(cx: &Context<'_>, ty_def_id: DefId) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         if !cx.shared.show_type_layout {
             return Ok(());
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 97e6d3146427..440d6331457b 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -58,7 +58,7 @@ fn filter_assoc_items_by_name_and_namespace(
     assoc_items_of: DefId,
     ident: Ident,
     ns: Namespace,
-) -> impl Iterator + '_ {
+) -> impl Iterator {
     tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| {
         item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of)
     })

From 84dd2a77769be235c19302d69b3bd1916718819e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= 
Date: Tue, 4 Mar 2025 12:24:09 +0100
Subject: [PATCH 618/991] Remove obsolete comment from DeduceReadOnly

The situation described in the comment does arise in practice now and
described panic is long gone.
---
 .../src/deduce_param_attrs.rs                 | 29 -------------------
 1 file changed, 29 deletions(-)

diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
index 049f13ce96d7..a0db8bdb7ed8 100644
--- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
+++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
@@ -80,35 +80,6 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
         // `f` passes. Note that function arguments are the only situation in which this problem can
         // arise: every other use of `move` in MIR doesn't actually write to the value it moves
         // from.
-        //
-        // Anyway, right now this situation doesn't actually arise in practice. Instead, the MIR for
-        // that function looks like this:
-        //
-        //      fn f(_1: BigStruct) -> () {
-        //          let mut _0: ();
-        //          let mut _2: BigStruct;
-        //          bb0: {
-        //              _2 = move _1;
-        //              _0 = g(move _2) -> bb1;
-        //          }
-        //          ...
-        //      }
-        //
-        // Because of that extra move that MIR construction inserts, `x` (i.e. `_1`) can *in
-        // practice* safely be marked `readonly`.
-        //
-        // To handle the possibility that other optimizations (for example, destination propagation)
-        // might someday generate MIR like the first example above, we panic upon seeing an argument
-        // to *our* function that is directly moved into *another* function as an argument. Having
-        // eliminated that problematic case, we can safely treat moves as copies in this analysis.
-        //
-        // In the future, if MIR optimizations cause arguments of a caller to be directly moved into
-        // the argument of a callee, we can just add that argument to `mutated_args` instead of
-        // panicking.
-        //
-        // Note that, because the problematic MIR is never actually generated, we can't add a test
-        // case for this.
-
         if let TerminatorKind::Call { ref args, .. } = terminator.kind {
             for arg in args {
                 if let Operand::Move(place) = arg.node {

From 6463590f0ce9ae9113bba171d8f9ea0d64c7e47a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= 
Date: Sat, 15 Feb 2025 14:25:43 +0100
Subject: [PATCH 619/991] Postprocess test suite metrics into GitHub summary

---
 .github/workflows/ci.yml     |  17 +++++
 src/ci/citool/Cargo.lock     |   9 +++
 src/ci/citool/Cargo.toml     |   2 +
 src/ci/citool/src/main.rs    |  15 ++++
 src/ci/citool/src/metrics.rs | 138 +++++++++++++++++++++++++++++++++++
 5 files changed, 181 insertions(+)
 create mode 100644 src/ci/citool/src/metrics.rs

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0cfbb4e77c46..a91598586b9f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -182,6 +182,13 @@ jobs:
       - name: show the current environment
         run: src/ci/scripts/dump-environment.sh
 
+      # Pre-build citool before the following step uninstalls rustup
+      # Build is into the build directory, to avoid modifying sources
+      - name: build citool
+        run: |
+          cd src/ci/citool
+          CARGO_TARGET_DIR=../../../build/citool cargo build
+
       - name: run the build
         # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
         run: src/ci/scripts/run-build-from-ci.sh 2>&1
@@ -218,6 +225,16 @@ jobs:
         # erroring about invalid credentials instead.
         if: github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1'
 
+      - name: postprocess metrics into the summary
+        run: |
+          if [ -f build/metrics.json ]; then
+            ./build/citool/debug/citool postprocess-metrics build/metrics.json ${GITHUB_STEP_SUMMARY}
+          elif [ -f obj/build/metrics.json ]; then
+            ./build/citool/debug/citool postprocess-metrics obj/build/metrics.json ${GITHUB_STEP_SUMMARY}
+          else
+            echo "No metrics.json found"
+          fi
+
       - name: upload job metrics to DataDog
         if: needs.calculate_matrix.outputs.run_type != 'pr'
         env:
diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock
index 39b6b44da643..e5be2d42472b 100644
--- a/src/ci/citool/Cargo.lock
+++ b/src/ci/citool/Cargo.lock
@@ -58,11 +58,20 @@ version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
 
+[[package]]
+name = "build_helper"
+version = "0.1.0"
+dependencies = [
+ "serde",
+ "serde_derive",
+]
+
 [[package]]
 name = "citool"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "build_helper",
  "clap",
  "insta",
  "serde",
diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml
index e77c67c71477..11172832cb81 100644
--- a/src/ci/citool/Cargo.toml
+++ b/src/ci/citool/Cargo.toml
@@ -10,6 +10,8 @@ serde = { version = "1", features = ["derive"] }
 serde_yaml = "0.9"
 serde_json = "1"
 
+build_helper = { path = "../../build_helper" }
+
 [dev-dependencies]
 insta = "1"
 
diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs
index ad9cc8b82a6f..cef92e998da1 100644
--- a/src/ci/citool/src/main.rs
+++ b/src/ci/citool/src/main.rs
@@ -1,3 +1,5 @@
+mod metrics;
+
 use std::collections::BTreeMap;
 use std::path::{Path, PathBuf};
 use std::process::Command;
@@ -6,6 +8,8 @@ use anyhow::Context;
 use clap::Parser;
 use serde_yaml::Value;
 
+use crate::metrics::postprocess_metrics;
+
 const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/..");
 const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker");
 const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml");
@@ -338,6 +342,14 @@ enum Args {
         #[clap(long = "type", default_value = "auto")]
         job_type: JobType,
     },
+    /// Postprocess the metrics.json file generated by bootstrap.
+    PostprocessMetrics {
+        /// Path to the metrics.json file
+        metrics_path: PathBuf,
+        /// Path to a file where the postprocessed metrics summary will be stored.
+        /// Usually, this will be GITHUB_STEP_SUMMARY on CI.
+        summary_path: PathBuf,
+    },
 }
 
 #[derive(clap::ValueEnum, Clone)]
@@ -369,6 +381,9 @@ fn main() -> anyhow::Result<()> {
         Args::RunJobLocally { job_type, name } => {
             run_workflow_locally(load_db(default_jobs_file)?, job_type, name)?
         }
+        Args::PostprocessMetrics { metrics_path, summary_path } => {
+            postprocess_metrics(&metrics_path, &summary_path)?;
+        }
     }
 
     Ok(())
diff --git a/src/ci/citool/src/metrics.rs b/src/ci/citool/src/metrics.rs
new file mode 100644
index 000000000000..9a1c7c4d910a
--- /dev/null
+++ b/src/ci/citool/src/metrics.rs
@@ -0,0 +1,138 @@
+use std::collections::BTreeMap;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+
+use anyhow::Context;
+use build_helper::metrics::{JsonNode, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata};
+
+pub fn postprocess_metrics(metrics_path: &Path, summary_path: &Path) -> anyhow::Result<()> {
+    let metrics = load_metrics(metrics_path)?;
+
+    let mut file = File::options()
+        .append(true)
+        .create(true)
+        .open(summary_path)
+        .with_context(|| format!("Cannot open summary file at {summary_path:?}"))?;
+
+    record_test_suites(&metrics, &mut file)?;
+
+    Ok(())
+}
+
+fn record_test_suites(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> {
+    let suites = get_test_suites(&metrics);
+
+    if !suites.is_empty() {
+        let aggregated = aggregate_test_suites(&suites);
+        let table = render_table(aggregated);
+        writeln!(file, "\n# Test results\n")?;
+        writeln!(file, "{table}")?;
+    } else {
+        eprintln!("No test suites found in metrics");
+    }
+
+    Ok(())
+}
+
+fn render_table(suites: BTreeMap) -> String {
+    use std::fmt::Write;
+
+    let mut table = "| Test suite | Passed ✅ | Ignored 🚫 | Failed  ❌ |\n".to_string();
+    writeln!(table, "|:------|------:|------:|------:|").unwrap();
+
+    fn write_row(
+        buffer: &mut String,
+        name: &str,
+        record: &TestSuiteRecord,
+        surround: &str,
+    ) -> std::fmt::Result {
+        let TestSuiteRecord { passed, ignored, failed } = record;
+        let total = (record.passed + record.ignored + record.failed) as f64;
+        let passed_pct = ((*passed as f64) / total) * 100.0;
+        let ignored_pct = ((*ignored as f64) / total) * 100.0;
+        let failed_pct = ((*failed as f64) / total) * 100.0;
+
+        write!(buffer, "| {surround}{name}{surround} |")?;
+        write!(buffer, " {surround}{passed} ({passed_pct:.0}%){surround} |")?;
+        write!(buffer, " {surround}{ignored} ({ignored_pct:.0}%){surround} |")?;
+        writeln!(buffer, " {surround}{failed} ({failed_pct:.0}%){surround} |")?;
+
+        Ok(())
+    }
+
+    let mut total = TestSuiteRecord::default();
+    for (name, record) in suites {
+        write_row(&mut table, &name, &record, "").unwrap();
+        total.passed += record.passed;
+        total.ignored += record.ignored;
+        total.failed += record.failed;
+    }
+    write_row(&mut table, "Total", &total, "**").unwrap();
+    table
+}
+
+#[derive(Default)]
+struct TestSuiteRecord {
+    passed: u64,
+    ignored: u64,
+    failed: u64,
+}
+
+fn aggregate_test_suites(suites: &[&TestSuite]) -> BTreeMap {
+    let mut records: BTreeMap = BTreeMap::new();
+    for suite in suites {
+        let name = match &suite.metadata {
+            TestSuiteMetadata::CargoPackage { crates, stage, .. } => {
+                format!("{} (stage {stage})", crates.join(", "))
+            }
+            TestSuiteMetadata::Compiletest { suite, stage, .. } => {
+                format!("{suite} (stage {stage})")
+            }
+        };
+        let record = records.entry(name).or_default();
+        for test in &suite.tests {
+            match test.outcome {
+                TestOutcome::Passed => {
+                    record.passed += 1;
+                }
+                TestOutcome::Failed => {
+                    record.failed += 1;
+                }
+                TestOutcome::Ignored { .. } => {
+                    record.ignored += 1;
+                }
+            }
+        }
+    }
+    records
+}
+
+fn get_test_suites(metrics: &JsonRoot) -> Vec<&TestSuite> {
+    fn visit_test_suites<'a>(nodes: &'a [JsonNode], suites: &mut Vec<&'a TestSuite>) {
+        for node in nodes {
+            match node {
+                JsonNode::RustbuildStep { children, .. } => {
+                    visit_test_suites(&children, suites);
+                }
+                JsonNode::TestSuite(suite) => {
+                    suites.push(&suite);
+                }
+            }
+        }
+    }
+
+    let mut suites = vec![];
+    for invocation in &metrics.invocations {
+        visit_test_suites(&invocation.children, &mut suites);
+    }
+    suites
+}
+
+fn load_metrics(path: &Path) -> anyhow::Result {
+    let metrics = std::fs::read_to_string(path)
+        .with_context(|| format!("Cannot read JSON metrics from {path:?}"))?;
+    let metrics: JsonRoot = serde_json::from_str(&metrics)
+        .with_context(|| format!("Cannot deserialize JSON metrics from {path:?}"))?;
+    Ok(metrics)
+}

From 2e5ab4e6a07a9ebdb6e593ca19112148250e6906 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= 
Date: Wed, 19 Feb 2025 16:06:47 +0100
Subject: [PATCH 620/991] Store bootstrap command-line into metrics

---
 src/bootstrap/src/utils/metrics.rs | 8 ++++++++
 src/build_helper/src/metrics.rs    | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/src/bootstrap/src/utils/metrics.rs b/src/bootstrap/src/utils/metrics.rs
index b51fd490535a..57766fd63fb1 100644
--- a/src/bootstrap/src/utils/metrics.rs
+++ b/src/bootstrap/src/utils/metrics.rs
@@ -200,6 +200,14 @@ impl BuildMetrics {
             }
         };
         invocations.push(JsonInvocation {
+            // The command-line invocation with which bootstrap was invoked.
+            // Skip the first argument, as it is a potentially long absolute
+            // path that is not interesting.
+            cmdline: std::env::args_os()
+                .skip(1)
+                .map(|arg| arg.to_string_lossy().to_string())
+                .collect::>()
+                .join(" "),
             start_time: state
                 .invocation_start
                 .duration_since(SystemTime::UNIX_EPOCH)
diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs
index 538c33e9b159..c9be63ed534b 100644
--- a/src/build_helper/src/metrics.rs
+++ b/src/build_helper/src/metrics.rs
@@ -12,6 +12,8 @@ pub struct JsonRoot {
 #[derive(Serialize, Deserialize)]
 #[serde(rename_all = "snake_case")]
 pub struct JsonInvocation {
+    // Remembers the command-line invocation with which bootstrap was invoked.
+    pub cmdline: String,
     // Unix timestamp in seconds
     //
     // This is necessary to easily correlate this invocation with logs or other data.

From ead58ea6f8bf860459fe5351a83717a8e591b0af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= 
Date: Tue, 4 Mar 2025 12:29:51 +0100
Subject: [PATCH 621/991] Move `BuildStep` and metric logging into
 `build_helper`

---
 src/build_helper/src/metrics.rs   | 80 +++++++++++++++++++++++++++++++
 src/tools/opt-dist/src/metrics.rs | 73 ++--------------------------
 2 files changed, 83 insertions(+), 70 deletions(-)

diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs
index c9be63ed534b..4b585c151824 100644
--- a/src/build_helper/src/metrics.rs
+++ b/src/build_helper/src/metrics.rs
@@ -1,3 +1,5 @@
+use std::time::Duration;
+
 use serde_derive::{Deserialize, Serialize};
 
 #[derive(Serialize, Deserialize)]
@@ -100,3 +102,81 @@ fn null_as_f64_nan<'de, D: serde::Deserializer<'de>>(d: D) -> Result::deserialize(d).map(|f| f.unwrap_or(f64::NAN))
 }
+
+/// Represents a single bootstrap step, with the accumulated duration of all its children.
+#[derive(Clone, Debug)]
+pub struct BuildStep {
+    pub r#type: String,
+    pub children: Vec,
+    pub duration: Duration,
+}
+
+impl BuildStep {
+    /// Create a `BuildStep` representing a single invocation of bootstrap.
+    /// The most important thing is that the build step aggregates the
+    /// durations of all children, so that it can be easily accessed.
+    pub fn from_invocation(invocation: &JsonInvocation) -> Self {
+        fn parse(node: &JsonNode) -> Option {
+            match node {
+                JsonNode::RustbuildStep {
+                    type_: kind,
+                    children,
+                    duration_excluding_children_sec,
+                    ..
+                } => {
+                    let children: Vec<_> = children.into_iter().filter_map(parse).collect();
+                    let children_duration = children.iter().map(|c| c.duration).sum::();
+                    Some(BuildStep {
+                        r#type: kind.to_string(),
+                        children,
+                        duration: children_duration
+                            + Duration::from_secs_f64(*duration_excluding_children_sec),
+                    })
+                }
+                JsonNode::TestSuite(_) => None,
+            }
+        }
+
+        let duration = Duration::from_secs_f64(invocation.duration_including_children_sec);
+        let children: Vec<_> = invocation.children.iter().filter_map(parse).collect();
+        Self { r#type: "total".to_string(), children, duration }
+    }
+
+    pub fn find_all_by_type(&self, r#type: &str) -> Vec<&Self> {
+        let mut result = Vec::new();
+        self.find_by_type(r#type, &mut result);
+        result
+    }
+
+    fn find_by_type<'a>(&'a self, r#type: &str, result: &mut Vec<&'a Self>) {
+        if self.r#type == r#type {
+            result.push(self);
+        }
+        for child in &self.children {
+            child.find_by_type(r#type, result);
+        }
+    }
+}
+
+/// Writes build steps into a nice indented table.
+pub fn format_build_steps(root: &BuildStep) -> String {
+    use std::fmt::Write;
+
+    let mut substeps: Vec<(u32, &BuildStep)> = Vec::new();
+
+    fn visit<'a>(step: &'a BuildStep, level: u32, substeps: &mut Vec<(u32, &'a BuildStep)>) {
+        substeps.push((level, step));
+        for child in &step.children {
+            visit(child, level + 1, substeps);
+        }
+    }
+
+    visit(root, 0, &mut substeps);
+
+    let mut output = String::new();
+    for (level, step) in substeps {
+        let label = format!("{}{}", ".".repeat(level as usize), step.r#type);
+        writeln!(output, "{label:<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap();
+    }
+    output
+}
diff --git a/src/tools/opt-dist/src/metrics.rs b/src/tools/opt-dist/src/metrics.rs
index 89c4cb12d4c3..0a745566eb51 100644
--- a/src/tools/opt-dist/src/metrics.rs
+++ b/src/tools/opt-dist/src/metrics.rs
@@ -1,33 +1,10 @@
 use std::time::Duration;
 
-use build_helper::metrics::{JsonNode, JsonRoot};
+use build_helper::metrics::{BuildStep, JsonRoot, format_build_steps};
 use camino::Utf8Path;
 
 use crate::timer::TimerSection;
 
-#[derive(Clone, Debug)]
-pub struct BuildStep {
-    r#type: String,
-    children: Vec,
-    duration: Duration,
-}
-
-impl BuildStep {
-    pub fn find_all_by_type(&self, r#type: &str) -> Vec<&BuildStep> {
-        let mut result = Vec::new();
-        self.find_by_type(r#type, &mut result);
-        result
-    }
-    fn find_by_type<'a>(&'a self, r#type: &str, result: &mut Vec<&'a BuildStep>) {
-        if self.r#type == r#type {
-            result.push(self);
-        }
-        for child in &self.children {
-            child.find_by_type(r#type, result);
-        }
-    }
-}
-
 /// Loads the metrics of the most recent bootstrap execution from a metrics.json file.
 pub fn load_metrics(path: &Utf8Path) -> anyhow::Result {
     let content = std::fs::read(path.as_std_path())?;
@@ -37,30 +14,7 @@ pub fn load_metrics(path: &Utf8Path) -> anyhow::Result {
         .pop()
         .ok_or_else(|| anyhow::anyhow!("No bootstrap invocation found in metrics file"))?;
 
-    fn parse(node: JsonNode) -> Option {
-        match node {
-            JsonNode::RustbuildStep {
-                type_: kind,
-                children,
-                duration_excluding_children_sec,
-                ..
-            } => {
-                let children: Vec<_> = children.into_iter().filter_map(parse).collect();
-                let children_duration = children.iter().map(|c| c.duration).sum::();
-                Some(BuildStep {
-                    r#type: kind.to_string(),
-                    children,
-                    duration: children_duration
-                        + Duration::from_secs_f64(duration_excluding_children_sec),
-                })
-            }
-            JsonNode::TestSuite(_) => None,
-        }
-    }
-
-    let duration = Duration::from_secs_f64(invocation.duration_including_children_sec);
-    let children: Vec<_> = invocation.children.into_iter().filter_map(parse).collect();
-    Ok(BuildStep { r#type: "root".to_string(), children, duration })
+    Ok(BuildStep::from_invocation(&invocation))
 }
 
 /// Logs the individual metrics in a table and add Rustc and LLVM durations to the passed
@@ -82,27 +36,6 @@ pub fn record_metrics(metrics: &BuildStep, timer: &mut TimerSection) {
         timer.add_duration("Rustc", rustc_duration);
     }
 
-    log_metrics(metrics);
-}
-
-fn log_metrics(metrics: &BuildStep) {
-    use std::fmt::Write;
-
-    let mut substeps: Vec<(u32, &BuildStep)> = Vec::new();
-
-    fn visit<'a>(step: &'a BuildStep, level: u32, substeps: &mut Vec<(u32, &'a BuildStep)>) {
-        substeps.push((level, step));
-        for child in &step.children {
-            visit(child, level + 1, substeps);
-        }
-    }
-
-    visit(metrics, 0, &mut substeps);
-
-    let mut output = String::new();
-    for (level, step) in substeps {
-        let label = format!("{}{}", ".".repeat(level as usize), step.r#type);
-        writeln!(output, "{label:<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap();
-    }
+    let output = format_build_steps(metrics);
     log::info!("Build step durations\n{output}");
 }

From 7b53ac7ee67fbd62cadd883c860a6df263b6a481 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= 
Date: Sun, 2 Mar 2025 18:23:11 +0100
Subject: [PATCH 622/991] Record bootstrap step durations into GitHub summary
 in citool

---
 src/build_helper/src/metrics.rs | 10 ++++++++--
 src/ci/citool/src/metrics.rs    | 30 ++++++++++++++++++++++++++++--
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs
index 4b585c151824..eb306550fc4a 100644
--- a/src/build_helper/src/metrics.rs
+++ b/src/build_helper/src/metrics.rs
@@ -175,8 +175,14 @@ pub fn format_build_steps(root: &BuildStep) -> String {
 
     let mut output = String::new();
     for (level, step) in substeps {
-        let label = format!("{}{}", ".".repeat(level as usize), step.r#type);
-        writeln!(output, "{label:<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap();
+        let label = format!(
+            "{}{}",
+            ".".repeat(level as usize),
+            // Bootstrap steps can be generic and thus contain angle brackets (<...>).
+            // However, Markdown interprets these as HTML, so we need to escap ethem.
+            step.r#type.replace('<', "<").replace('>', ">")
+        );
+        writeln!(output, "{label:.<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap();
     }
     output
 }
diff --git a/src/ci/citool/src/metrics.rs b/src/ci/citool/src/metrics.rs
index 9a1c7c4d910a..2386413ed6b1 100644
--- a/src/ci/citool/src/metrics.rs
+++ b/src/ci/citool/src/metrics.rs
@@ -4,7 +4,9 @@ use std::io::Write;
 use std::path::Path;
 
 use anyhow::Context;
-use build_helper::metrics::{JsonNode, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata};
+use build_helper::metrics::{
+    BuildStep, JsonNode, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, format_build_steps,
+};
 
 pub fn postprocess_metrics(metrics_path: &Path, summary_path: &Path) -> anyhow::Result<()> {
     let metrics = load_metrics(metrics_path)?;
@@ -15,7 +17,31 @@ pub fn postprocess_metrics(metrics_path: &Path, summary_path: &Path) -> anyhow::
         .open(summary_path)
         .with_context(|| format!("Cannot open summary file at {summary_path:?}"))?;
 
-    record_test_suites(&metrics, &mut file)?;
+    if !metrics.invocations.is_empty() {
+        writeln!(file, "# Bootstrap steps")?;
+        record_bootstrap_step_durations(&metrics, &mut file)?;
+        record_test_suites(&metrics, &mut file)?;
+    }
+
+    Ok(())
+}
+
+fn record_bootstrap_step_durations(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> {
+    for invocation in &metrics.invocations {
+        let step = BuildStep::from_invocation(invocation);
+        let table = format_build_steps(&step);
+        eprintln!("Step `{}`\n{table}\n", invocation.cmdline);
+        writeln!(
+            file,
+            r"
+{} +
{table}
+
+", + invocation.cmdline + )?; + } + eprintln!("Recorded {} bootstrap invocation(s)", metrics.invocations.len()); Ok(()) } From c6c4ea40dc645239ebcb0535be6b96a29983fd5b Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Tue, 4 Mar 2025 15:32:55 +0300 Subject: [PATCH 623/991] Revert "compiler/rustc_data_structures/src/sync/worker_local.rs: delete "unsafe impl Sync"" This reverts commit 02406903b0c26440428580a4bbaf30da973c5b23. --- .../rustc_data_structures/src/sync/worker_local.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs index 402ec9827bba..d75af0098504 100644 --- a/compiler/rustc_data_structures/src/sync/worker_local.rs +++ b/compiler/rustc_data_structures/src/sync/worker_local.rs @@ -106,6 +106,12 @@ pub struct WorkerLocal { registry: Registry, } +// This is safe because the `deref` call will return a reference to a `T` unique to each thread +// or it will panic for threads without an associated local. So there isn't a need for `T` to do +// it's own synchronization. The `verify` method on `RegistryId` has an issue where the id +// can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse. +unsafe impl Sync for WorkerLocal {} + impl WorkerLocal { /// Creates a new worker local where the `initial` closure computes the /// value this worker local should take for each thread in the registry. @@ -132,11 +138,6 @@ impl Deref for WorkerLocal { fn deref(&self) -> &T { // This is safe because `verify` will only return values less than // `self.registry.thread_limit` which is the size of the `self.locals` array. - - // The `deref` call will return a reference to a `T` unique to each thread - // or it will panic for threads without an associated local. So there isn't a need for `T` to do - // it's own synchronization. The `verify` method on `RegistryId` has an issue where the id - // can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse. unsafe { &self.locals.get_unchecked(self.registry.id().verify()).0 } } } From da3e73654f311869c052f218e37871a2f4381c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Fri, 28 Feb 2025 20:54:10 +0100 Subject: [PATCH 624/991] Clarify why InhabitedPredicate::instantiate_opt exists At first glance, the extra casework seems pointless and needlessly error-prone. Clarify that there is a reason for it being there. --- .../rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 505c7278176f..86ef07dff5f2 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -236,6 +236,11 @@ impl<'tcx> InhabitedPredicate<'tcx> { self.instantiate_opt(tcx, args).unwrap_or(self) } + /// Same as [`Self::instantiate`], but if there is no generics to + /// instantiate, returns `None`. This is useful because it lets us avoid + /// allocating a recursive copy of everything when the result is unchanged. + /// + /// Only used to implement `instantiate` itself. fn instantiate_opt(self, tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> Option { match self { Self::ConstIsZero(c) => { From a3d63fb0d488e4db52e0fe672f0cf2040840f2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Mon, 3 Mar 2025 23:52:22 +0100 Subject: [PATCH 625/991] InhabitedPredicate: avoid using a wildcard branch This is error-prone. Explicitly write down which cases don't need anything substituted. Turn the `OpaqueType` case, which currently seems to be unreachable, into a `bug!`. --- .../rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 86ef07dff5f2..953ad62be0a8 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -265,7 +265,10 @@ impl<'tcx> InhabitedPredicate<'tcx> { Some(InhabitedPredicate::True) => Some(InhabitedPredicate::True), Some(a) => Some(a.or(tcx, b.instantiate_opt(tcx, args).unwrap_or(b))), }, - _ => None, + Self::True | Self::False | Self::NotInModule(_) => None, + Self::OpaqueType(_) => { + bug!("unexpected OpaqueType in InhabitedPredicate"); + } } } } From 68df70d510e2ff8a303d7b3c9c8b0cb3bce579f4 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Tue, 4 Mar 2025 11:58:31 +0000 Subject: [PATCH 626/991] List the feature in removed.rs --- compiler/rustc_feature/src/removed.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index fc58b66ad35e..47e4f9a2fe88 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -244,6 +244,8 @@ declare_features! ( /// Allows unnamed fields of struct and union type (removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign")), (removed, unsafe_no_drop_flag, "1.0.0", None, None), + (removed, unsized_tuple_coercion, "CURRENT_RUSTC_VERSION", Some(42877), + Some("The feature restricts possible layouts for tuples, and this restriction is not worth it.")), /// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue. (removed, untagged_unions, "1.13.0", Some(55149), Some("unions with `Copy` and `ManuallyDrop` fields are stable; there is no intent to stabilize more")), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 14280b433ae8..501c9039f2de 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1,4 +1,5 @@ -//! An "interner" is a data structure that associates values with usize tags and allows bidirectional lookup; i.e., given a value, one can easily find the +//! An "interner" is a data structure that associates values with usize tags and +//! allows bidirectional lookup; i.e., given a value, one can easily find the //! type, and vice versa. use std::hash::{Hash, Hasher}; @@ -2164,6 +2165,7 @@ symbols! { unsized_const_params, unsized_fn_params, unsized_locals, + unsized_tuple_coercion, unstable, unstable_location_reason_default: "this crate is being loaded from the sysroot, an \ unstable location; did you mean to load this crate \ From 1a5a4537437285bbd0f7f4cc9525b312a44789b2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Mar 2025 15:14:59 +0100 Subject: [PATCH 627/991] atomic: clarify that failing conditional RMW operations are not 'writes' --- library/core/src/sync/atomic.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 73180bde54aa..d55fa347cc5b 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -44,8 +44,9 @@ //! The most important aspect of this model is that *data races* are undefined behavior. A data race //! is defined as conflicting non-synchronized accesses where at least one of the accesses is //! non-atomic. Here, accesses are *conflicting* if they affect overlapping regions of memory and at -//! least one of them is a write. They are *non-synchronized* if neither of them *happens-before* -//! the other, according to the happens-before order of the memory model. +//! least one of them is a write. (A `compare_exchange` or `compare_exchange_weak` that does not +//! succeed is not considered a write.) They are *non-synchronized* if neither of them +//! *happens-before* the other, according to the happens-before order of the memory model. //! //! The other possible cause of undefined behavior in the memory model are mixed-size accesses: Rust //! inherits the C++ limitation that non-synchronized conflicting atomic accesses may not partially From 2a7ad952a7a7120a76feadc72b24c40233aedf31 Mon Sep 17 00:00:00 2001 From: Henry Jiang Date: Mon, 3 Mar 2025 15:40:23 -0500 Subject: [PATCH 628/991] Fix test hangs on AIX --- library/std/src/net/test.rs | 11 +++++++++++ library/std/src/net/udp/tests.rs | 12 ++++++++---- tests/debuginfo/pretty-huge-vec.rs | 1 + tests/ui/consts/large_const_alloc.rs | 3 +++ tests/ui/consts/large_const_alloc.stderr | 4 ++-- .../promoted_running_out_of_memory_issue-130687.rs | 3 +++ ...romoted_running_out_of_memory_issue-130687.stderr | 2 +- 7 files changed, 29 insertions(+), 7 deletions(-) diff --git a/library/std/src/net/test.rs b/library/std/src/net/test.rs index a5c3983cd89e..df48b2f2420c 100644 --- a/library/std/src/net/test.rs +++ b/library/std/src/net/test.rs @@ -31,3 +31,14 @@ pub fn tsa(a: A) -> Result, String> { Err(e) => Err(e.to_string()), } } + +pub fn compare_ignore_zoneid(a: &SocketAddr, b: &SocketAddr) -> bool { + match (a, b) { + (SocketAddr::V6(a), SocketAddr::V6(b)) => { + a.ip().segments() == b.ip().segments() + && a.flowinfo() == b.flowinfo() + && a.port() == b.port() + } + _ => a == b, + } +} diff --git a/library/std/src/net/udp/tests.rs b/library/std/src/net/udp/tests.rs index 1c8c58d18795..91da3135f97c 100644 --- a/library/std/src/net/udp/tests.rs +++ b/library/std/src/net/udp/tests.rs @@ -1,4 +1,4 @@ -use crate::net::test::{next_test_ip4, next_test_ip6}; +use crate::net::test::{compare_ignore_zoneid, next_test_ip4, next_test_ip6}; use crate::net::*; use crate::sync::mpsc::channel; use crate::thread; @@ -46,7 +46,7 @@ fn socket_smoke_test_ip4() { let (nread, src) = t!(server.recv_from(&mut buf)); assert_eq!(nread, 1); assert_eq!(buf[0], 99); - assert_eq!(src, client_ip); + assert_eq!(compare_ignore_zoneid(&src, &client_ip), true); rx2.recv().unwrap(); }) } @@ -78,7 +78,9 @@ fn udp_clone_smoke() { let _t = thread::spawn(move || { let mut buf = [0, 0]; - assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1)); + let res = sock2.recv_from(&mut buf).unwrap(); + assert_eq!(res.0, 1); + assert_eq!(compare_ignore_zoneid(&res.1, &addr1), true); assert_eq!(buf[0], 1); t!(sock2.send_to(&[2], &addr1)); }); @@ -94,7 +96,9 @@ fn udp_clone_smoke() { }); tx1.send(()).unwrap(); let mut buf = [0, 0]; - assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2)); + let res = sock1.recv_from(&mut buf).unwrap(); + assert_eq!(res.0, 1); + assert_eq!(compare_ignore_zoneid(&res.1, &addr2), true); rx2.recv().unwrap(); }) } diff --git a/tests/debuginfo/pretty-huge-vec.rs b/tests/debuginfo/pretty-huge-vec.rs index 093fbc5b12d2..6938158e365e 100644 --- a/tests/debuginfo/pretty-huge-vec.rs +++ b/tests/debuginfo/pretty-huge-vec.rs @@ -1,5 +1,6 @@ //@ ignore-windows-gnu: #128981 //@ ignore-android: FIXME(#10381) +//@ ignore-aix: FIXME(#137965) //@ compile-flags:-g // === GDB TESTS =================================================================================== diff --git a/tests/ui/consts/large_const_alloc.rs b/tests/ui/consts/large_const_alloc.rs index 14edc1bb6961..3573a018630f 100644 --- a/tests/ui/consts/large_const_alloc.rs +++ b/tests/ui/consts/large_const_alloc.rs @@ -2,6 +2,9 @@ // on 32bit and 16bit platforms it is plausible that the maximum allocation size will succeed // FIXME (#135952) In some cases on AArch64 Linux the diagnostic does not trigger //@ ignore-aarch64-unknown-linux-gnu +// AIX will allow the allocation to go through, and get SIGKILL when zero initializing +// the overcommitted page. +//@ ignore-aix const FOO: () = { // 128 TiB, unlikely anyone has that much RAM diff --git a/tests/ui/consts/large_const_alloc.stderr b/tests/ui/consts/large_const_alloc.stderr index fa7d5977a956..f3f3de7af63a 100644 --- a/tests/ui/consts/large_const_alloc.stderr +++ b/tests/ui/consts/large_const_alloc.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/large_const_alloc.rs:8:13 + --> $DIR/large_const_alloc.rs:11:13 | LL | let x = [0_u8; (1 << 47) - 1]; | ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler error[E0080]: could not evaluate static initializer - --> $DIR/large_const_alloc.rs:13:13 + --> $DIR/large_const_alloc.rs:16:13 | LL | let x = [0_u8; (1 << 47) - 1]; | ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs index 53618e2e86ac..75765596fa17 100644 --- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs +++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs @@ -5,6 +5,9 @@ //@ only-64bit // FIXME (#135952) In some cases on AArch64 Linux the diagnostic does not trigger //@ ignore-aarch64-unknown-linux-gnu +// AIX will allow the allocation to go through, and get SIGKILL when zero initializing +// the overcommitted page. +//@ ignore-aix pub struct Data([u8; (1 << 47) - 1]); const _: &'static Data = &Data([0; (1 << 47) - 1]); diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr index aac805dbd8c7..02180c1e4c68 100644 --- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr +++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/promoted_running_out_of_memory_issue-130687.rs:10:32 + --> $DIR/promoted_running_out_of_memory_issue-130687.rs:13:32 | LL | const _: &'static Data = &Data([0; (1 << 47) - 1]); | ^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler From 177e7ff5484cb712c176604eb49fce1d2f56b474 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 6 Jan 2025 21:15:56 -0800 Subject: [PATCH 629/991] mgca: Lower all const paths as `ConstArgKind::Path` When `#![feature(min_generic_const_args)]` is enabled, we now lower all const paths in generic arg position to `hir::ConstArgKind::Path`. We then lower assoc const paths to `ty::ConstKind::Unevaluated` since we can no longer use the anon const expression lowering machinery. In the process of implementing this, I factored out `hir_ty_lowering` code that is now shared between lowering assoc types and assoc consts. This PR also introduces a `#[type_const]` attribute for trait assoc consts that are allowed as const args. However, we still need to implement code to check that assoc const definitions satisfy `#[type_const]` if present (basically is it a const path or a monomorphic anon const). --- compiler/rustc_ast/src/ast.rs | 48 ++- compiler/rustc_ast_lowering/src/lib.rs | 17 +- compiler/rustc_builtin_macros/src/format.rs | 3 +- compiler/rustc_feature/src/builtin_attrs.rs | 7 + compiler/rustc_hir_analysis/src/collect.rs | 28 +- .../src/hir_ty_lowering/bounds.rs | 4 +- .../src/hir_ty_lowering/errors.rs | 36 +- .../src/hir_ty_lowering/generics.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 327 ++++++++++++++---- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 12 +- compiler/rustc_middle/src/ty/assoc.rs | 20 +- compiler/rustc_passes/src/check_attr.rs | 21 ++ compiler/rustc_resolve/src/late.rs | 18 +- compiler/rustc_span/src/symbol.rs | 1 + .../traits/fulfillment_errors.rs | 4 +- .../src/traits/const_evaluatable.rs | 6 + .../src/traits/select/confirmation.rs | 2 +- .../issue-109299-1.stderr | 4 +- ...ffers-shadowing-trait-item.shadowed.stderr | 2 +- .../not-found-self-type-differs.stderr | 4 +- .../not-found-unsatisfied-bounds-0.stderr | 4 +- .../not-found-unsatisfied-bounds-1.stderr | 2 +- ...nsatisfied-bounds-in-multiple-impls.stderr | 2 +- .../mgca/ambiguous-assoc-const.rs | 15 + .../mgca/ambiguous-assoc-const.stderr | 15 + .../mgca/assoc-const-without-type_const.rs | 14 + .../assoc-const-without-type_const.stderr | 18 + tests/ui/const-generics/mgca/assoc-const.rs | 15 + .../mgca/bad-type_const-syntax.rs | 17 + .../mgca/bad-type_const-syntax.stderr | 35 ++ .../mgca/inherent-const-gating.rs | 13 + .../mgca/inherent-const-gating.stderr | 13 + .../feature-gate-min-generic-const-args.rs | 4 +- ...feature-gate-min-generic-const-args.stderr | 15 +- 35 files changed, 602 insertions(+), 148 deletions(-) create mode 100644 tests/ui/const-generics/mgca/ambiguous-assoc-const.rs create mode 100644 tests/ui/const-generics/mgca/ambiguous-assoc-const.stderr create mode 100644 tests/ui/const-generics/mgca/assoc-const-without-type_const.rs create mode 100644 tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr create mode 100644 tests/ui/const-generics/mgca/assoc-const.rs create mode 100644 tests/ui/const-generics/mgca/bad-type_const-syntax.rs create mode 100644 tests/ui/const-generics/mgca/bad-type_const-syntax.stderr create mode 100644 tests/ui/const-generics/mgca/inherent-const-gating.rs create mode 100644 tests/ui/const-generics/mgca/inherent-const-gating.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index a8d30949ea85..fb6b36e1a09d 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -124,10 +124,19 @@ impl Path { self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot) } - /// If this path is a single identifier with no arguments, does not ensure - /// that the path resolves to a const param, the caller should check this. - pub fn is_potential_trivial_const_arg(&self) -> bool { - matches!(self.segments[..], [PathSegment { args: None, .. }]) + /// Check if this path is potentially a trivial const arg, i.e., one that can _potentially_ + /// be represented without an anon const in the HIR. + /// + /// If `allow_mgca_arg` is true (as should be the case in most situations when + /// `#![feature(min_generic_const_args)]` is enabled), then this always returns true + /// because all paths are valid. + /// + /// Otherwise, it returns true iff the path has exactly one segment, and it has no generic args + /// (i.e., it is _potentially_ a const parameter). + #[tracing::instrument(level = "debug", ret)] + pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool { + allow_mgca_arg + || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none()) } } @@ -1208,22 +1217,31 @@ pub struct Expr { } impl Expr { - /// Could this expr be either `N`, or `{ N }`, where `N` is a const parameter. + /// Check if this expression is potentially a trivial const arg, i.e., one that can _potentially_ + /// be represented without an anon const in the HIR. /// - /// If this is not the case, name resolution does not resolve `N` when using - /// `min_const_generics` as more complex expressions are not supported. + /// This will unwrap at most one block level (curly braces). After that, if the expression + /// is a path, it mostly dispatches to [`Path::is_potential_trivial_const_arg`]. + /// See there for more info about `allow_mgca_arg`. /// - /// Does not ensure that the path resolves to a const param, the caller should check this. + /// The only additional thing to note is that when `allow_mgca_arg` is false, this function + /// will only allow paths with no qself, before dispatching to the `Path` function of + /// the same name. + /// + /// Does not ensure that the path resolves to a const param/item, the caller should check this. /// This also does not consider macros, so it's only correct after macro-expansion. - pub fn is_potential_trivial_const_arg(&self) -> bool { + pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool { let this = self.maybe_unwrap_block(); - - if let ExprKind::Path(None, path) = &this.kind - && path.is_potential_trivial_const_arg() - { - true + if allow_mgca_arg { + matches!(this.kind, ExprKind::Path(..)) } else { - false + if let ExprKind::Path(None, path) = &this.kind + && path.is_potential_trivial_const_arg(allow_mgca_arg) + { + true + } else { + false + } } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 13edcc10c9e2..c0188dde5651 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1094,7 +1094,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .and_then(|partial_res| partial_res.full_res()) { if !res.matches_ns(Namespace::TypeNS) - && path.is_potential_trivial_const_arg() + && path.is_potential_trivial_const_arg(false) { debug!( "lower_generic_arg: Lowering type argument as const argument: {:?}", @@ -2061,8 +2061,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> &'hir hir::ConstArg<'hir> { let tcx = self.tcx; - // FIXME(min_generic_const_args): we only allow one-segment const paths for now - let ct_kind = if path.is_potential_trivial_const_arg() + let ct_kind = if path + .is_potential_trivial_const_arg(tcx.features().min_generic_const_args()) && (tcx.features().min_generic_const_args() || matches!(res, Res::Def(DefKind::ConstParam, _))) { @@ -2072,7 +2072,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path, ParamMode::Optional, AllowReturnTypeNotation::No, - // FIXME(min_generic_const_args): update for `fn foo() -> Bar>` support + // FIXME(mgca): update for `fn foo() -> Bar>` support ImplTraitContext::Disallowed(ImplTraitPosition::Path), None, ); @@ -2136,19 +2136,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; let maybe_res = self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res()); - // FIXME(min_generic_const_args): we only allow one-segment const paths for now - if let ExprKind::Path(None, path) = &expr.kind - && path.is_potential_trivial_const_arg() + if let ExprKind::Path(qself, path) = &expr.kind + && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args()) && (tcx.features().min_generic_const_args() || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _)))) { let qpath = self.lower_qpath( expr.id, - &None, + qself, path, ParamMode::Optional, AllowReturnTypeNotation::No, - // FIXME(min_generic_const_args): update for `fn foo() -> Bar>` support + // FIXME(mgca): update for `fn foo() -> Bar>` support ImplTraitContext::Disallowed(ImplTraitPosition::Path), None, ); diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 90447da66807..6dbd8a7ac013 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -190,7 +190,8 @@ fn make_format_args( && let [stmt] = block.stmts.as_slice() && let StmtKind::Expr(expr) = &stmt.kind && let ExprKind::Path(None, path) = &expr.kind - && path.is_potential_trivial_const_arg() + && path.segments.len() == 1 + && path.segments[0].args.is_none() { err.multipart_suggestion( "quote your inlined format argument to use as string literal", diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 306535bf7642..40857e0066ee 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -576,6 +576,13 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::Yes, experimental!(patchable_function_entry) ), + // Probably temporary component of min_generic_const_args. + // `#[type_const] const ASSOC: usize;` + gated!( + type_const, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::Yes, min_generic_const_args, experimental!(type_const), + ), + // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 027aa5554a40..49523912b14d 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -45,6 +45,7 @@ use tracing::{debug, instrument}; use crate::check::intrinsic::intrinsic_operation_unsafety; use crate::errors; +use crate::hir_ty_lowering::errors::assoc_kind_str; use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason}; pub(crate) mod dump; @@ -443,13 +444,14 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name)) } - fn lower_assoc_ty( + fn lower_assoc_shared( &self, span: Span, item_def_id: DefId, - item_segment: &hir::PathSegment<'tcx>, + item_segment: &rustc_hir::PathSegment<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Ty<'tcx> { + kind: ty::AssocKind, + ) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> { if let Some(trait_ref) = poly_trait_ref.no_bound_vars() { let item_args = self.lowerer().lower_generic_args_of_assoc_item( span, @@ -457,7 +459,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { item_segment, trait_ref.args, ); - Ty::new_projection_from_args(self.tcx(), item_def_id, item_args) + Ok((item_def_id, item_args)) } else { // There are no late-bound regions; we can just ignore the binder. let (mut mpart_sugg, mut inferred_sugg) = (None, None); @@ -518,16 +520,14 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { } _ => {} } - Ty::new_error( - self.tcx(), - self.tcx().dcx().emit_err(errors::AssociatedItemTraitUninferredGenericParams { - span, - inferred_sugg, - bound, - mpart_sugg, - what: "type", - }), - ) + + Err(self.tcx().dcx().emit_err(errors::AssociatedItemTraitUninferredGenericParams { + span, + inferred_sugg, + bound, + mpart_sugg, + what: assoc_kind_str(kind), + })) } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index dd346ed1f97a..60af36da6e2f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -468,11 +468,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Good error for `where Trait::method(..): Send`. let Some(self_ty) = opt_self_ty else { - return self.error_missing_qpath_self_ty( + let guar = self.error_missing_qpath_self_ty( trait_def_id, hir_ty.span, item_segment, + ty::AssocKind::Type, ); + return Ty::new_error(tcx, guar); }; let self_ty = self.lower_ty(self_ty); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 922578792ba8..d51fd7f7e78a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -385,14 +385,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) } - pub(super) fn report_ambiguous_assoc_ty( + pub(super) fn report_ambiguous_assoc( &self, span: Span, types: &[String], traits: &[String], name: Symbol, + kind: ty::AssocKind, ) -> ErrorGuaranteed { - let mut err = struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type"); + let kind_str = assoc_kind_str(kind); + let mut err = + struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated {kind_str}"); if self .tcx() .resolutions(()) @@ -417,7 +420,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span, format!( "if there were a type named `Type` that implements a trait named \ - `Trait` with associated type `{name}`, you could use the \ + `Trait` with associated {kind_str} `{name}`, you could use the \ fully-qualified path", ), format!("::{name}"), @@ -440,7 +443,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span, format!( "if there were a type named `Example` that implemented one of the \ - traits with associated type `{name}`, you could use the \ + traits with associated {kind_str} `{name}`, you could use the \ fully-qualified path", ), traits.iter().map(|trait_str| format!("::{name}")), @@ -451,7 +454,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { err.span_suggestion_verbose( span, format!( - "if there were a trait named `Example` with associated type `{name}` \ + "if there were a trait named `Example` with associated {kind_str} `{name}` \ implemented for `{type_str}`, you could use the fully-qualified path", ), format!("<{type_str} as Example>::{name}"), @@ -462,7 +465,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { err.span_suggestions( span, format!( - "if there were a trait named `Example` with associated type `{name}` \ + "if there were a trait named `Example` with associated {kind_str} `{name}` \ implemented for one of the types, you could use the fully-qualified \ path", ), @@ -491,7 +494,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { err.emit() } - pub(crate) fn complain_about_ambiguous_inherent_assoc_ty( + pub(crate) fn complain_about_ambiguous_inherent_assoc( &self, name: Ident, candidates: Vec, @@ -552,13 +555,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } // FIXME(inherent_associated_types): Find similarly named associated types and suggest them. - pub(crate) fn complain_about_inherent_assoc_ty_not_found( + pub(crate) fn complain_about_inherent_assoc_not_found( &self, name: Ident, self_ty: Ty<'tcx>, candidates: Vec<(DefId, (DefId, DefId))>, fulfillment_errors: Vec>, span: Span, + kind: ty::AssocKind, ) -> ErrorGuaranteed { // FIXME(fmease): This was copied in parts from an old version of `rustc_hir_typeck::method::suggest`. // Either @@ -568,12 +572,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); + let kind_str = assoc_kind_str(kind); let adt_did = self_ty.ty_adt_def().map(|def| def.did()); let add_def_label = |err: &mut Diag<'_>| { if let Some(did) = adt_did { err.span_label( tcx.def_span(did), - format!("associated item `{name}` not found for this {}", tcx.def_descr(did)), + format!( + "associated {kind_str} `{name}` not found for this {}", + tcx.def_descr(did) + ), ); } }; @@ -600,11 +608,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.dcx(), name.span, E0220, - "associated type `{name}` not found for `{self_ty}` in the current scope" + "associated {kind_str} `{name}` not found for `{self_ty}` in the current scope" ); err.span_label(name.span, format!("associated item not found in `{self_ty}`")); err.note(format!( - "the associated type was found for\n{type_candidates}{additional_types}", + "the associated {kind_str} was found for\n{type_candidates}{additional_types}", )); add_def_label(&mut err); return err.emit(); @@ -685,7 +693,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut err = self.dcx().struct_span_err( name.span, - format!("the associated type `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied") + format!("the associated {kind_str} `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied") ); if !bounds.is_empty() { err.note(format!( @@ -695,7 +703,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } err.span_label( name.span, - format!("associated type cannot be referenced on `{self_ty}` due to unsatisfied trait bounds") + format!("associated {kind_str} cannot be referenced on `{self_ty}` due to unsatisfied trait bounds") ); for (span, mut bounds) in bound_spans { @@ -1614,7 +1622,7 @@ fn generics_args_err_extend<'a>( } } -pub(super) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str { +pub(crate) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str { match kind { ty::AssocKind::Fn => "function", ty::AssocKind::Const => "constant", diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index fa58f12c553c..60a60f6415a2 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -115,7 +115,7 @@ fn generic_arg_mismatch_err( body.value.kind && let Res::Def(DefKind::Fn { .. }, id) = path.res { - // FIXME(min_generic_const_args): this branch is dead once new const path lowering + // FIXME(mgca): this branch is dead once new const path lowering // (for single-segment paths) is no longer gated err.help(format!("`{}` is a function item, not a type", tcx.item_name(id))); err.help("function item types cannot be named directly"); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index a0f848f07c4b..d044688246f9 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -44,14 +44,16 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; +use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; -use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw}; +use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::wf::object_region_bounds; use rustc_trait_selection::traits::{self, ObligationCtxt}; use rustc_type_ir::Upcast; use tracing::{debug, instrument}; +use self::errors::assoc_kind_str; use crate::check::check_abi_fn_ptr; use crate::errors::{ AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, NoVariantNamed, @@ -152,7 +154,7 @@ pub trait HirTyLowerer<'tcx> { assoc_name: Ident, ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>; - /// Lower an associated type to a projection. + /// Lower an associated type/const (from a trait) to a projection. /// /// This method has to be defined by the concrete lowering context because /// dealing with higher-ranked trait references depends on its capabilities: @@ -164,13 +166,14 @@ pub trait HirTyLowerer<'tcx> { /// /// The canonical example of this is associated type `T::P` where `T` is a type /// param constrained by `T: for<'a> Trait<'a>` and where `Trait` defines `P`. - fn lower_assoc_ty( + fn lower_assoc_shared( &self, span: Span, item_def_id: DefId, item_segment: &hir::PathSegment<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Ty<'tcx>; + kind: ty::AssocKind, + ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>; fn lower_fn_sig( &self, @@ -245,6 +248,42 @@ pub enum FeedConstTy<'a, 'tcx> { No, } +#[derive(Debug, Clone, Copy)] +enum LowerAssocMode { + Type { permit_variants: bool }, + Const, +} + +impl LowerAssocMode { + fn kind(self) -> ty::AssocKind { + match self { + LowerAssocMode::Type { .. } => ty::AssocKind::Type, + LowerAssocMode::Const => ty::AssocKind::Const, + } + } + + fn def_kind(self) -> DefKind { + match self { + LowerAssocMode::Type { .. } => DefKind::AssocTy, + LowerAssocMode::Const => DefKind::AssocConst, + } + } + + fn permit_variants(self) -> bool { + match self { + LowerAssocMode::Type { permit_variants } => permit_variants, + // FIXME(mgca): Support paths like `Option::::None` or `Option::::Some` which resolve to const ctors/fn items respectively + LowerAssocMode::Const => false, + } + } +} + +#[derive(Debug, Clone, Copy)] +enum LoweredAssoc<'tcx> { + Term(DefId, GenericArgsRef<'tcx>), + Variant { adt: Ty<'tcx>, variant_did: DefId }, +} + /// New-typed boolean indicating whether explicit late-bound lifetimes /// are present in a set of generic arguments. /// @@ -630,7 +669,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { (args, arg_count) } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "debug", skip(self))] pub fn lower_generic_args_of_assoc_item( &self, span: Span, @@ -638,7 +677,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { item_segment: &hir::PathSegment<'tcx>, parent_args: GenericArgsRef<'tcx>, ) -> GenericArgsRef<'tcx> { - debug!(?span, ?item_def_id, ?item_segment); let (args, _) = self.lower_generic_args_of_path(span, item_def_id, parent_args, item_segment, None); if let Some(c) = item_segment.args().constraints.first() { @@ -1118,7 +1156,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // NOTE: When this function starts resolving `Trait::AssocTy` successfully // it should also start reporting the `BARE_TRAIT_OBJECTS` lint. #[instrument(level = "debug", skip_all, ret)] - pub fn lower_assoc_path( + pub fn lower_assoc_path_ty( &self, hir_ref_id: HirId, span: Span, @@ -1127,6 +1165,72 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_segment: &'tcx hir::PathSegment<'tcx>, permit_variants: bool, ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> { + let tcx = self.tcx(); + match self.lower_assoc_path_shared( + hir_ref_id, + span, + qself_ty, + qself, + assoc_segment, + LowerAssocMode::Type { permit_variants }, + )? { + LoweredAssoc::Term(def_id, args) => { + let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args); + let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty); + Ok((ty, tcx.def_kind(def_id), def_id)) + } + LoweredAssoc::Variant { adt, variant_did } => Ok((adt, DefKind::Variant, variant_did)), + } + } + + #[instrument(level = "debug", skip_all, ret)] + fn lower_assoc_path_const( + &self, + hir_ref_id: HirId, + span: Span, + qself_ty: Ty<'tcx>, + qself: &'tcx hir::Ty<'tcx>, + assoc_segment: &'tcx hir::PathSegment<'tcx>, + ) -> Result, ErrorGuaranteed> { + let tcx = self.tcx(); + let (def_id, args) = match self.lower_assoc_path_shared( + hir_ref_id, + span, + qself_ty, + qself, + assoc_segment, + LowerAssocMode::Const, + )? { + LoweredAssoc::Term(def_id, args) => { + if !tcx.associated_item(def_id).is_type_const_capable(tcx) { + let mut err = tcx.dcx().struct_span_err( + span, + "use of trait associated const without `#[type_const]`", + ); + err.note("the declaration in the trait must be marked with `#[type_const]`"); + return Err(err.emit()); + } + (def_id, args) + } + // FIXME(mgca): implement support for this once ready to support all adt ctor expressions, + // not just const ctors + LoweredAssoc::Variant { .. } => { + span_bug!(span, "unexpected variant res for type associated const path") + } + }; + Ok(Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args))) + } + + #[instrument(level = "debug", skip_all, ret)] + fn lower_assoc_path_shared( + &self, + hir_ref_id: HirId, + span: Span, + qself_ty: Ty<'tcx>, + qself: &'tcx hir::Ty<'tcx>, + assoc_segment: &'tcx hir::PathSegment<'tcx>, + mode: LowerAssocMode, + ) -> Result, ErrorGuaranteed> { debug!(%qself_ty, ?assoc_segment.ident); let tcx = self.tcx(); @@ -1141,13 +1245,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did())); if let Some(variant_def) = variant_def { - if permit_variants { + if mode.permit_variants() { tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None); let _ = self.prohibit_generic_args( slice::from_ref(assoc_segment).iter(), GenericsArgsErrExtend::EnumVariant { qself, assoc_segment, adt_def }, ); - return Ok((qself_ty, DefKind::Variant, variant_def.def_id)); + return Ok(LoweredAssoc::Variant { + adt: qself_ty, + variant_did: variant_def.def_id, + }); } else { variant_resolution = Some(variant_def.def_id); } @@ -1155,15 +1262,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } // FIXME(inherent_associated_types, #106719): Support self types other than ADTs. - if let Some((ty, did)) = self.probe_inherent_assoc_ty( - assoc_ident, + if let Some((did, args)) = self.probe_inherent_assoc_shared( assoc_segment, adt_def.did(), qself_ty, hir_ref_id, span, + mode.kind(), )? { - return Ok((ty, DefKind::AssocTy, did)); + return Ok(LoweredAssoc::Term(did, args)); } } @@ -1192,7 +1299,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) }, AssocItemQSelf::SelfTyAlias, - ty::AssocKind::Type, + mode.kind(), assoc_ident, span, None, @@ -1204,14 +1311,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) => self.probe_single_ty_param_bound_for_assoc_item( param_did.expect_local(), qself.span, - ty::AssocKind::Type, + mode.kind(), assoc_ident, span, )?, _ => { + let kind_str = assoc_kind_str(mode.kind()); let reported = if variant_resolution.is_some() { // Variant in type position - let msg = format!("expected type, found variant `{assoc_ident}`"); + let msg = format!("expected {kind_str}, found variant `{assoc_ident}`"); self.dcx().span_err(span, msg) } else if qself_ty.is_enum() { let mut err = self.dcx().create_err(NoVariantNamed { @@ -1310,11 +1418,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident); // Don't print `ty::Error` to the user. - self.report_ambiguous_assoc_ty( + self.report_ambiguous_assoc( span, &[qself_ty.to_string()], &traits, assoc_ident.name, + mode.kind(), ) }; return Err(reported); @@ -1322,10 +1431,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; let trait_did = bound.def_id(); - let assoc_ty = self - .probe_assoc_item(assoc_ident, ty::AssocKind::Type, hir_ref_id, span, trait_did) - .expect("failed to find associated type"); - let ty = self.lower_assoc_ty(span, assoc_ty.def_id, assoc_segment, bound); + let assoc_item = self + .probe_assoc_item(assoc_ident, mode.kind(), hir_ref_id, span, trait_did) + .expect("failed to find associated item"); + let (def_id, args) = + self.lower_assoc_shared(span, assoc_item.def_id, assoc_segment, bound, mode.kind())?; + let result = LoweredAssoc::Term(def_id, args); if let Some(variant_def_id) = variant_resolution { tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| { @@ -1341,7 +1452,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; could_refer_to(DefKind::Variant, variant_def_id, ""); - could_refer_to(DefKind::AssocTy, assoc_ty.def_id, " also"); + could_refer_to(mode.def_kind(), assoc_item.def_id, " also"); lint.span_suggestion( span, @@ -1351,36 +1462,51 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); }); } - Ok((ty, DefKind::AssocTy, assoc_ty.def_id)) + Ok(result) } - fn probe_inherent_assoc_ty( + fn probe_inherent_assoc_shared( &self, - name: Ident, segment: &hir::PathSegment<'tcx>, adt_did: DefId, self_ty: Ty<'tcx>, block: HirId, span: Span, - ) -> Result, DefId)>, ErrorGuaranteed> { + kind: ty::AssocKind, + ) -> Result)>, ErrorGuaranteed> { let tcx = self.tcx(); - // Don't attempt to look up inherent associated types when the feature is not enabled. - // Theoretically it'd be fine to do so since we feature-gate their definition site. - // However, due to current limitations of the implementation (caused by us performing - // selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle - // errors (#108491) which mask the feature-gate error, needlessly confusing users - // who use IATs by accident (#113265). if !tcx.features().inherent_associated_types() { - return Ok(None); + match kind { + // Don't attempt to look up inherent associated types when the feature is not enabled. + // Theoretically it'd be fine to do so since we feature-gate their definition site. + // However, due to current limitations of the implementation (caused by us performing + // selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle + // errors (#108491) which mask the feature-gate error, needlessly confusing users + // who use IATs by accident (#113265). + ty::AssocKind::Type => return Ok(None), + ty::AssocKind::Const => { + // We also gate the mgca codepath for type-level uses of inherent consts + // with the inherent_associated_types feature gate since it relies on the + // same machinery and has similar rough edges. + return Err(feature_err( + &tcx.sess, + sym::inherent_associated_types, + span, + "inherent associated types are unstable", + ) + .emit()); + } + ty::AssocKind::Fn => unreachable!(), + } } + let name = segment.ident; let candidates: Vec<_> = tcx .inherent_impls(adt_did) .iter() .filter_map(|&impl_| { - let (item, scope) = - self.probe_assoc_item_unchecked(name, ty::AssocKind::Type, block, impl_)?; + let (item, scope) = self.probe_assoc_item_unchecked(name, kind, block, impl_)?; Some((impl_, (item.def_id, scope))) }) .collect(); @@ -1395,13 +1521,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // In contexts that have no inference context, just make a new one. // We do need a local variable to store it, though. - let infcx_; let infcx = match self.infcx() { Some(infcx) => infcx, None => { assert!(!self_ty.has_infer()); - infcx_ = tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis()); - &infcx_ + &tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis()) } }; @@ -1420,8 +1544,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &mut universes, self_ty, |self_ty| { - self.select_inherent_assoc_type_candidates( - infcx, name, span, self_ty, param_env, candidates, + self.select_inherent_assoc_candidates( + infcx, name, span, self_ty, param_env, candidates, kind, ) }, )?; @@ -1438,13 +1562,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .chain(args.into_iter().skip(parent_args.len())), ); - let ty = - Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new_from_args(tcx, assoc_item, args)); - - Ok(Some((ty, assoc_item))) + Ok(Some((assoc_item, args))) } - fn select_inherent_assoc_type_candidates( + fn select_inherent_assoc_candidates( &self, infcx: &InferCtxt<'tcx>, name: Ident, @@ -1452,6 +1573,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty: Ty<'tcx>, param_env: ParamEnv<'tcx>, candidates: Vec<(DefId, (DefId, DefId))>, + kind: ty::AssocKind, ) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> { let tcx = self.tcx(); let mut fulfillment_errors = Vec::new(); @@ -1496,17 +1618,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .collect(); match &applicable_candidates[..] { - &[] => Err(self.complain_about_inherent_assoc_ty_not_found( + &[] => Err(self.complain_about_inherent_assoc_not_found( name, self_ty, candidates, fulfillment_errors, span, + kind, )), &[applicable_candidate] => Ok(applicable_candidate), - &[_, ..] => Err(self.complain_about_ambiguous_inherent_assoc_ty( + &[_, ..] => Err(self.complain_about_ambiguous_inherent_assoc( name, applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(), span, @@ -1638,7 +1761,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Lower a qualified path to a type. #[instrument(level = "debug", skip_all)] - fn lower_qpath( + fn lower_qpath_ty( &self, span: Span, opt_self_ty: Option>, @@ -1646,13 +1769,64 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_segment: &hir::PathSegment<'tcx>, item_segment: &hir::PathSegment<'tcx>, ) -> Ty<'tcx> { + match self.lower_qpath_shared( + span, + opt_self_ty, + item_def_id, + trait_segment, + item_segment, + ty::AssocKind::Type, + ) { + Ok((item_def_id, item_args)) => { + Ty::new_projection_from_args(self.tcx(), item_def_id, item_args) + } + Err(guar) => Ty::new_error(self.tcx(), guar), + } + } + + /// Lower a qualified path to a const. + #[instrument(level = "debug", skip_all)] + fn lower_qpath_const( + &self, + span: Span, + opt_self_ty: Option>, + item_def_id: DefId, + trait_segment: &hir::PathSegment<'tcx>, + item_segment: &hir::PathSegment<'tcx>, + ) -> Const<'tcx> { + match self.lower_qpath_shared( + span, + opt_self_ty, + item_def_id, + trait_segment, + item_segment, + ty::AssocKind::Const, + ) { + Ok((item_def_id, item_args)) => { + let uv = ty::UnevaluatedConst::new(item_def_id, item_args); + Const::new_unevaluated(self.tcx(), uv) + } + Err(guar) => Const::new_error(self.tcx(), guar), + } + } + + #[instrument(level = "debug", skip_all)] + fn lower_qpath_shared( + &self, + span: Span, + opt_self_ty: Option>, + item_def_id: DefId, + trait_segment: &hir::PathSegment<'tcx>, + item_segment: &hir::PathSegment<'tcx>, + kind: ty::AssocKind, + ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> { let tcx = self.tcx(); let trait_def_id = tcx.parent(item_def_id); debug!(?trait_def_id); let Some(self_ty) = opt_self_ty else { - return self.error_missing_qpath_self_ty(trait_def_id, span, item_segment); + return Err(self.error_missing_qpath_self_ty(trait_def_id, span, item_segment, kind)); }; debug!(?self_ty); @@ -1663,7 +1837,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let item_args = self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args); - Ty::new_projection_from_args(tcx, item_def_id, item_args) + Ok((item_def_id, item_args)) } fn error_missing_qpath_self_ty( @@ -1671,7 +1845,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_def_id: DefId, span: Span, item_segment: &hir::PathSegment<'tcx>, - ) -> Ty<'tcx> { + kind: ty::AssocKind, + ) -> ErrorGuaranteed { let tcx = self.tcx(); let path_str = tcx.def_path_str(trait_def_id); @@ -1707,9 +1882,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that // references the trait. Relevant for the first case in // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs` - let reported = - self.report_ambiguous_assoc_ty(span, &type_names, &[path_str], item_segment.ident.name); - Ty::new_error(tcx, reported) + self.report_ambiguous_assoc(span, &type_names, &[path_str], item_segment.ident.name, kind) } pub fn prohibit_generic_args<'a>( @@ -2013,7 +2186,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { path.segments[..path.segments.len() - 2].iter(), GenericsArgsErrExtend::None, ); - self.lower_qpath( + self.lower_qpath_ty( span, opt_self_ty, def_id, @@ -2167,11 +2340,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself)); self.lower_const_path_resolved(opt_self_ty, path, hir_id) } - hir::ConstArgKind::Path(qpath) => ty::Const::new_error_with_message( - tcx, - qpath.span(), - format!("Const::lower_const_arg: invalid qpath {qpath:?}"), - ), + hir::ConstArgKind::Path(hir::QPath::TypeRelative(qself, segment)) => { + debug!(?qself, ?segment); + let ty = self.lower_ty(qself); + self.lower_assoc_path_const(hir_id, const_arg.span(), ty, qself, segment) + .unwrap_or_else(|guar| Const::new_error(tcx, guar)) + } + hir::ConstArgKind::Path(qpath @ hir::QPath::LangItem(..)) => { + ty::Const::new_error_with_message( + tcx, + qpath.span(), + format!("Const::lower_const_arg: invalid qpath {qpath:?}"), + ) + } hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon), hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span), } @@ -2207,6 +2388,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args)) } + Res::Def(DefKind::AssocConst, did) => { + debug_assert!(path.segments.len() >= 2); + let _ = self.prohibit_generic_args( + path.segments[..path.segments.len() - 2].iter(), + GenericsArgsErrExtend::None, + ); + self.lower_qpath_const( + span, + opt_self_ty, + did, + &path.segments[path.segments.len() - 2], + path.segments.last().unwrap(), + ) + } Res::Def(DefKind::Static { .. }, _) => { span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported") } @@ -2223,7 +2418,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Exhaustive match to be clear about what exactly we're considering to be // an invalid Res for a const path. - Res::Def( + res @ (Res::Def( DefKind::Mod | DefKind::Enum | DefKind::Variant @@ -2237,7 +2432,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { | DefKind::Union | DefKind::Trait | DefKind::ForeignTy - | DefKind::AssocConst | DefKind::TyParam | DefKind::Macro(_) | DefKind::LifetimeParam @@ -2260,12 +2454,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { | Res::Local(_) | Res::ToolMod | Res::NonMacroAttr(_) - | Res::Err => Const::new_error_with_message(tcx, span, "invalid Res for const path"), + | Res::Err) => Const::new_error_with_message( + tcx, + span, + format!("invalid Res {res:?} for const path"), + ), } } - /// Literals and const generic parameters are eagerly converted to a constant, everything else - /// becomes `Unevaluated`. + /// Literals are eagerly converted to a constant, everything else becomes `Unevaluated`. #[instrument(skip(self), level = "debug")] fn lower_anon_const(&self, anon: &AnonConst) -> Const<'tcx> { let tcx = self.tcx(); @@ -2464,7 +2661,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => { debug!(?qself, ?segment); let ty = self.lower_ty(qself); - self.lower_assoc_path(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false) + self.lower_assoc_path_ty(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false) .map(|(ty, _, _)| ty) .unwrap_or_else(|guar| Ty::new_error(tcx, guar)) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index e60a4bb47b57..82e99ca7afa2 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2174,7 +2174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = self .lowerer() - .lower_assoc_path(hir_id, path_span, ty.raw, qself, segment, true); + .lower_assoc_path_ty(hir_id, path_span, ty.raw, qself, segment, true); let ty = result .map(|(ty, _, _)| ty) .unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar)); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 42236ac6d808..e14f1528d2c4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -17,7 +17,7 @@ use rustc_infer::infer; use rustc_infer::traits::Obligation; use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Session; -use rustc_span::{self, DUMMY_SP, Ident, Span, sym}; +use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym}; use rustc_trait_selection::error_reporting::TypeErrCtxt; use rustc_trait_selection::error_reporting::infer::sub_relations::SubRelations; use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt}; @@ -308,15 +308,17 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { )) } - fn lower_assoc_ty( + fn lower_assoc_shared( &self, span: Span, item_def_id: DefId, - item_segment: &hir::PathSegment<'tcx>, + item_segment: &rustc_hir::PathSegment<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Ty<'tcx> { + _kind: ty::AssocKind, + ) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> { let trait_ref = self.instantiate_binder_with_fresh_vars( span, + // FIXME(mgca): this should be assoc const if that is the `kind` infer::BoundRegionConversionTime::AssocTypeProjection(item_def_id), poly_trait_ref, ); @@ -328,7 +330,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { trait_ref.args, ); - Ty::new_projection_from_args(self.tcx(), item_def_id, item_args) + Ok((item_def_id, item_args)) } fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option> { diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 6309dd2e490f..ce4c08aa485e 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -3,7 +3,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::{Ident, Symbol}; +use rustc_span::{Ident, Symbol, sym}; use super::{TyCtxt, Visibility}; use crate::ty; @@ -108,6 +108,24 @@ impl AssocItem { pub fn is_impl_trait_in_trait(&self) -> bool { self.opt_rpitit_info.is_some() } + + /// Returns true if: + /// - This trait associated item has the `#[type_const]` attribute, + /// - If it is in a trait impl, the item from the original trait has this attribute, or + /// - It is an inherent assoc const. + pub fn is_type_const_capable(&self, tcx: TyCtxt<'_>) -> bool { + if self.kind != ty::AssocKind::Const { + return false; + } + + let def_id = match (self.container, self.trait_item_def_id) { + (AssocItemContainer::Trait, _) => self.def_id, + (AssocItemContainer::Impl, Some(trait_item_did)) => trait_item_did, + // Inherent impl but this attr is only applied to trait assoc items. + (AssocItemContainer::Impl, None) => return true, + }; + tcx.has_attr(def_id, sym::type_const) + } } #[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)] diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d6c0edf5ae7b..91916b8f5fcc 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -14,6 +14,7 @@ use rustc_attr_parsing::{AttributeKind, ReprAttr, find_attr}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; +use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ @@ -257,6 +258,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::coroutine, ..] => { self.check_coroutine(attr, target); } + [sym::type_const, ..] => { + self.check_type_const(hir_id,attr, target); + } [sym::linkage, ..] => self.check_linkage(attr, span, target), [sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent(attr.span(), span, attrs), [ @@ -2519,6 +2523,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } + fn check_type_const(&self, hir_id: HirId, attr: &Attribute, target: Target) { + let tcx = self.tcx; + if target == Target::AssocConst + && let parent = tcx.parent(hir_id.expect_owner().to_def_id()) + && self.tcx.def_kind(parent) == DefKind::Trait + { + return; + } else { + self.dcx() + .struct_span_err( + attr.span(), + "`#[type_const]` must only be applied to trait associated constants", + ) + .emit(); + } + } + fn check_linkage(&self, attr: &Attribute, span: Span, target: Target) { match target { Target::Fn diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f119ed55e7d1..1e86b9721d4a 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1202,7 +1202,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r if let TyKind::Path(None, ref path) = ty.kind // We cannot disambiguate multi-segment paths right now as that requires type // checking. - && path.is_potential_trivial_const_arg() + && path.is_potential_trivial_const_arg(false) { let mut check_ns = |ns| { self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns) @@ -4630,11 +4630,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { constant, anon_const_kind ); - self.resolve_anon_const_manual( - constant.value.is_potential_trivial_const_arg(), - anon_const_kind, - |this| this.resolve_expr(&constant.value, None), - ) + let is_trivial_const_arg = constant + .value + .is_potential_trivial_const_arg(self.r.tcx.features().min_generic_const_args()); + self.resolve_anon_const_manual(is_trivial_const_arg, anon_const_kind, |this| { + this.resolve_expr(&constant.value, None) + }) } /// There are a few places that we need to resolve an anon const but we did not parse an @@ -4794,8 +4795,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Constant arguments need to be treated as AnonConst since // that is how they will be later lowered to HIR. if const_args.contains(&idx) { + let is_trivial_const_arg = argument.is_potential_trivial_const_arg( + self.r.tcx.features().min_generic_const_args(), + ); self.resolve_anon_const_manual( - argument.is_potential_trivial_const_arg(), + is_trivial_const_arg, AnonConstKind::ConstArg(IsRepeatExpr::No), |this| this.resolve_expr(argument, None), ); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3524709eebc2..541678572274 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2083,6 +2083,7 @@ symbols! { type_ascribe, type_ascription, type_changing_struct_update, + type_const, type_id, type_ir_inherent, type_length_limit, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d270b4cf96ba..8c1df9b51139 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -3250,7 +3250,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation: &PredicateObligation<'tcx>, span: Span, ) -> Result, ErrorGuaranteed> { - if !self.tcx.features().generic_const_exprs() { + if !self.tcx.features().generic_const_exprs() + && !self.tcx.features().min_generic_const_args() + { let guar = self .dcx() .struct_span_err(span, "constant expression depends on a generic parameter") diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index bdee6ca2afe5..75f53b063d10 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -85,6 +85,12 @@ pub fn is_const_evaluatable<'tcx>( } _ => bug!("unexpected constkind in `is_const_evalautable: {unexpanded_ct:?}`"), } + } else if tcx.features().min_generic_const_args() { + // This is a sanity check to make sure that non-generics consts are checked to + // be evaluatable in case they aren't cchecked elsewhere. This will NOT error + // if the const uses generics, as desired. + crate::traits::evaluate_const(infcx, unexpanded_ct, param_env); + Ok(()) } else { let uv = match unexpanded_ct.kind() { ty::ConstKind::Unevaluated(uv) => uv, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a58317dd56d2..97db1ddf4ff3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -410,7 +410,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let predicate = obligation.predicate.skip_binder(); let mut assume = predicate.trait_ref.args.const_at(2); - // FIXME(min_generic_const_exprs): We should shallowly normalize this. + // FIXME(mgca): We should shallowly normalize this. if self.tcx().features().generic_const_exprs() { assume = crate::traits::evaluate_const(self.infcx, assume, obligation.param_env) } diff --git a/tests/ui/associated-inherent-types/issue-109299-1.stderr b/tests/ui/associated-inherent-types/issue-109299-1.stderr index 07a00b6b9a95..77a78da852f3 100644 --- a/tests/ui/associated-inherent-types/issue-109299-1.stderr +++ b/tests/ui/associated-inherent-types/issue-109299-1.stderr @@ -2,7 +2,7 @@ error[E0220]: associated type `Cursor` not found for `Lexer` in the current s --> $DIR/issue-109299-1.rs:10:40 | LL | struct Lexer(T); - | --------------- associated item `Cursor` not found for this struct + | --------------- associated type `Cursor` not found for this struct ... LL | type X = impl for Fn() -> Lexer::Cursor; | ^^^^^^ associated item not found in `Lexer` @@ -14,7 +14,7 @@ error[E0220]: associated type `Cursor` not found for `Lexer` in the current s --> $DIR/issue-109299-1.rs:10:40 | LL | struct Lexer(T); - | --------------- associated item `Cursor` not found for this struct + | --------------- associated type `Cursor` not found for this struct ... LL | type X = impl for Fn() -> Lexer::Cursor; | ^^^^^^ associated item not found in `Lexer` diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr index 9bd5a842fdc7..a247d6d5b45b 100644 --- a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr +++ b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr @@ -2,7 +2,7 @@ error[E0220]: associated type `Pr` not found for `S` in the current scope --> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23 | LL | struct S(T); - | ----------- associated item `Pr` not found for this struct + | ----------- associated type `Pr` not found for this struct ... LL | let _: S::::Pr = (); | ^^ associated item not found in `S` diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs.stderr index 1871407c64fe..6194c6ff4d70 100644 --- a/tests/ui/associated-inherent-types/not-found-self-type-differs.stderr +++ b/tests/ui/associated-inherent-types/not-found-self-type-differs.stderr @@ -2,7 +2,7 @@ error[E0220]: associated type `Proj` not found for `Family>` in the c --> $DIR/not-found-self-type-differs.rs:15:32 | LL | struct Family(T); - | ---------------- associated item `Proj` not found for this struct + | ---------------- associated type `Proj` not found for this struct ... LL | let _: Family>::Proj; | ^^^^ associated item not found in `Family>` @@ -15,7 +15,7 @@ error[E0220]: associated type `Proj` not found for `Family` in the curr --> $DIR/not-found-self-type-differs.rs:16:40 | LL | struct Family(T); - | ---------------- associated item `Proj` not found for this struct + | ---------------- associated type `Proj` not found for this struct ... LL | let _: Family::Proj = (); | ^^^^ associated item not found in `Family` diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr index 736579067615..dd51192e06ff 100644 --- a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr +++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr @@ -2,7 +2,7 @@ error: the associated type `Yield` exists for `Container<[u8]>`, but its trait b --> $DIR/not-found-unsatisfied-bounds-0.rs:19:29 | LL | struct Container(T); - | --------------------------- associated item `Yield` not found for this struct + | --------------------------- associated type `Yield` not found for this struct ... LL | let _: Container<[u8]>::Yield = 1; | ^^^^^ associated type cannot be referenced on `Container<[u8]>` due to unsatisfied trait bounds @@ -14,7 +14,7 @@ error: the associated type `Combination` exists for `Duple>`, bu --> $DIR/not-found-unsatisfied-bounds-0.rs:20:45 | LL | struct Duple(T, U); - | ------------------ associated item `Combination` not found for this struct + | ------------------ associated type `Combination` not found for this struct ... LL | let _: Duple>::Combination; | ^^^^^^^^^^^ associated type cannot be referenced on `Duple>` due to unsatisfied trait bounds diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr index 0d5f781dc633..c27e1f49faab 100644 --- a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr +++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr @@ -5,7 +5,7 @@ LL | let _: Container::Proj = String::new(); | ^^^^ associated type cannot be referenced on `Container` due to unsatisfied trait bounds ... LL | struct Container(T); - | ------------------- associated item `Proj` not found for this struct + | ------------------- associated type `Proj` not found for this struct | = note: the following trait bounds were not satisfied: `T: Clone` diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr index 1613af6b8b15..db6c71a626ff 100644 --- a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr +++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr @@ -2,7 +2,7 @@ error: the associated type `X` exists for `S`, but its --> $DIR/not-found-unsatisfied-bounds-in-multiple-impls.rs:19:43 | LL | struct S(A, B); - | -------------- associated item `X` not found for this struct + | -------------- associated type `X` not found for this struct LL | struct Featureless; | ------------------ doesn't satisfy `Featureless: One` or `Featureless: Two` ... diff --git a/tests/ui/const-generics/mgca/ambiguous-assoc-const.rs b/tests/ui/const-generics/mgca/ambiguous-assoc-const.rs new file mode 100644 index 000000000000..d7df9c22afd6 --- /dev/null +++ b/tests/ui/const-generics/mgca/ambiguous-assoc-const.rs @@ -0,0 +1,15 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Tr { + const N: usize; +} + +struct Blah; + +fn foo() -> Blah<{ Tr::N }> { + //~^ ERROR ambiguous associated constant + todo!() +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/ambiguous-assoc-const.stderr b/tests/ui/const-generics/mgca/ambiguous-assoc-const.stderr new file mode 100644 index 000000000000..11c63bdbcf4b --- /dev/null +++ b/tests/ui/const-generics/mgca/ambiguous-assoc-const.stderr @@ -0,0 +1,15 @@ +error[E0223]: ambiguous associated constant + --> $DIR/ambiguous-assoc-const.rs:10:20 + | +LL | fn foo() -> Blah<{ Tr::N }> { + | ^^^^^ + | +help: if there were a type named `Example` that implemented `Tr`, you could use the fully-qualified path + | +LL - fn foo() -> Blah<{ Tr::N }> { +LL + fn foo() -> Blah<{ ::N }> { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0223`. diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs b/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs new file mode 100644 index 000000000000..a11314c11aae --- /dev/null +++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs @@ -0,0 +1,14 @@ +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +pub trait Tr { + const SIZE: usize; +} + +fn mk_array(_x: T) -> [(); T::SIZE] { + //~^ ERROR type_const + [(); T::SIZE] + //~^ ERROR type_const +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr new file mode 100644 index 000000000000..7872e0967626 --- /dev/null +++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr @@ -0,0 +1,18 @@ +error: use of trait associated const without `#[type_const]` + --> $DIR/assoc-const-without-type_const.rs:8:35 + | +LL | fn mk_array(_x: T) -> [(); T::SIZE] { + | ^^^^^^^ + | + = note: the declaration in the trait must be marked with `#[type_const]` + +error: use of trait associated const without `#[type_const]` + --> $DIR/assoc-const-without-type_const.rs:10:10 + | +LL | [(); T::SIZE] + | ^^^^^^^ + | + = note: the declaration in the trait must be marked with `#[type_const]` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/assoc-const.rs b/tests/ui/const-generics/mgca/assoc-const.rs new file mode 100644 index 000000000000..fb5b4308a7f8 --- /dev/null +++ b/tests/ui/const-generics/mgca/assoc-const.rs @@ -0,0 +1,15 @@ +//@ check-pass + +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +pub trait Tr { + #[type_const] + const SIZE: usize; +} + +fn mk_array>(_x: T) -> [(); >::SIZE] { + [(); T::SIZE] +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.rs b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs new file mode 100644 index 000000000000..1e9673a56b56 --- /dev/null +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs @@ -0,0 +1,17 @@ +trait Tr { + #[type_const()] + //~^ ERROR malformed + //~| ERROR experimental + const N: usize; +} + +struct S; + +impl Tr for S { + #[type_const] + //~^ ERROR must only be applied to trait associated constants + //~| ERROR experimental + const N: usize = 0; +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr new file mode 100644 index 000000000000..579aff849d6e --- /dev/null +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr @@ -0,0 +1,35 @@ +error: malformed `type_const` attribute input + --> $DIR/bad-type_const-syntax.rs:2:5 + | +LL | #[type_const()] + | ^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` + +error[E0658]: the `#[type_const]` attribute is an experimental feature + --> $DIR/bad-type_const-syntax.rs:2:5 + | +LL | #[type_const()] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `#[type_const]` attribute is an experimental feature + --> $DIR/bad-type_const-syntax.rs:11:5 + | +LL | #[type_const] + | ^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: `#[type_const]` must only be applied to trait associated constants + --> $DIR/bad-type_const-syntax.rs:11:5 + | +LL | #[type_const] + | ^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/mgca/inherent-const-gating.rs b/tests/ui/const-generics/mgca/inherent-const-gating.rs new file mode 100644 index 000000000000..c39b8e6f7f64 --- /dev/null +++ b/tests/ui/const-generics/mgca/inherent-const-gating.rs @@ -0,0 +1,13 @@ +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +struct S; + +impl S { + const N: usize = 42; +} + +fn main() { + let _x: [(); S::N] = todo!(); + //~^ ERROR inherent associated types are unstable +} diff --git a/tests/ui/const-generics/mgca/inherent-const-gating.stderr b/tests/ui/const-generics/mgca/inherent-const-gating.stderr new file mode 100644 index 000000000000..71bb11ae700f --- /dev/null +++ b/tests/ui/const-generics/mgca/inherent-const-gating.stderr @@ -0,0 +1,13 @@ +error[E0658]: inherent associated types are unstable + --> $DIR/inherent-const-gating.rs:11:18 + | +LL | let _x: [(); S::N] = todo!(); + | ^^^^ + | + = note: see issue #8995 for more information + = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs b/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs index 171509876d18..1cf755b2c565 100644 --- a/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs +++ b/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs @@ -1,8 +1,10 @@ trait Trait { + #[type_const] + //~^ ERROR experimental const ASSOC: usize; } -// FIXME(min_generic_const_args): implement support for this, behind the feature gate +// FIXME(mgca): add suggestion for mgca to this error fn foo() -> [u8; ::ASSOC] { //~^ ERROR generic parameters may not be used in const operations loop {} diff --git a/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr index 04d96b4c11ee..af528a3c1b79 100644 --- a/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr +++ b/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/feature-gate-min-generic-const-args.rs:6:29 + --> $DIR/feature-gate-min-generic-const-args.rs:8:29 | LL | fn foo() -> [u8; ::ASSOC] { | ^ cannot perform const operation using `T` @@ -7,5 +7,16 @@ LL | fn foo() -> [u8; ::ASSOC] { = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error: aborting due to 1 previous error +error[E0658]: the `#[type_const]` attribute is an experimental feature + --> $DIR/feature-gate-min-generic-const-args.rs:2:5 + | +LL | #[type_const] + | ^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. From 7635f2bfc61b353b83c244cf758459486a2ea442 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 11:03:55 -0600 Subject: [PATCH 630/991] fix whitespace --- src/librustdoc/html/static/js/search.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 45077f7920ba..cc8c7a3e43a4 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1584,17 +1584,17 @@ class DocSearch { * This is effectively string interning, so that function matching can be * done more quickly. Two types with the same name but different item kinds * get the same ID. - * - * @template T extends string - * @overload + * + * @template T extends string + * @overload * @param {T} name * @param {boolean=} isAssocType - True if this is an assoc type * @returns {T extends "" ? null : number} - * - * @param {string} name + * + * @param {string} name * @param {boolean=} isAssocType * @returns {number | null} - * + * */ buildTypeMapIndex(name, isAssocType) { if (name === "" || name === null) { From c392cf7690e08a56ff1fcea67b81b89bbc976045 Mon Sep 17 00:00:00 2001 From: pcorwin Date: Sun, 9 Feb 2025 22:00:31 -0500 Subject: [PATCH 631/991] Added documentation for flushing --- library/std/src/io/stdio.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 318c35082216..90ed49ff663e 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -574,6 +574,11 @@ impl fmt::Debug for StdinLock<'_> { /// output stream. Access is also synchronized via a lock and explicit control /// over locking is available via the [`lock`] method. /// +/// By default, the handle is line-buffered when connected to a terminal, meaning +/// it flushes automatically when a newline (`\n`) is encountered. For immediate +/// output, you can manually call the [`flush`] method. When the handle goes out +/// of scope, the buffer is automatically flushed. +/// /// Created by the [`io::stdout`] method. /// /// ### Note: Windows Portability Considerations @@ -589,6 +594,7 @@ impl fmt::Debug for StdinLock<'_> { /// standard library or via raw Windows API calls, will fail. /// /// [`lock`]: Stdout::lock +/// [`flush`]: Write::flush /// [`io::stdout`]: stdout #[stable(feature = "rust1", since = "1.0.0")] pub struct Stdout { @@ -603,6 +609,11 @@ pub struct Stdout { /// This handle implements the [`Write`] trait, and is constructed via /// the [`Stdout::lock`] method. See its documentation for more. /// +/// By default, the handle is line-buffered when connected to a terminal, meaning +/// it flushes automatically when a newline (`\n`) is encountered. For immediate +/// output, you can manually call the [`flush`] method. When the handle goes out +/// of scope, the buffer is automatically flushed. +/// /// ### Note: Windows Portability Considerations /// /// When operating in a console, the Windows implementation of this stream does not support @@ -614,6 +625,8 @@ pub struct Stdout { /// the contained handle will be null. In such cases, the standard library's `Read` and /// `Write` will do nothing and silently succeed. All other I/O operations, via the /// standard library or via raw Windows API calls, will fail. +/// +/// [`flush`]: Write::flush #[must_use = "if unused stdout will immediately unlock"] #[stable(feature = "rust1", since = "1.0.0")] pub struct StdoutLock<'a> { @@ -628,6 +641,11 @@ static STDOUT: OnceLock>>> = OnceLoc /// is synchronized via a mutex. If you need more explicit control over /// locking, see the [`Stdout::lock`] method. /// +/// By default, the handle is line-buffered when connected to a terminal, meaning +/// it flushes automatically when a newline (`\n`) is encountered. For immediate +/// output, you can manually call the [`flush`] method. When the handle goes out +/// of scope, the buffer is automatically flushed. +/// /// ### Note: Windows Portability Considerations /// /// When operating in a console, the Windows implementation of this stream does not support @@ -668,6 +686,22 @@ static STDOUT: OnceLock>>> = OnceLoc /// Ok(()) /// } /// ``` +/// +/// Ensuring output is flushed immediately: +/// +/// ```no_run +/// use std::io::{self, Write}; +/// +/// fn main() -> io::Result<()> { +/// let mut stdout = io::stdout(); +/// stdout.write_all(b"hello, ")?; +/// stdout.flush()?; // Manual flush +/// stdout.write_all(b"world!\n")?; // Automatically flushed +/// Ok(()) +/// } +/// ``` +/// +/// [`flush`]: Write::flush #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "io_stdout")] From 3d62b279ddc2095b94aa5921540b27f3003365ff Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Feb 2025 01:28:32 +0000 Subject: [PATCH 632/991] Ensure that negative auto impls are always applicable --- compiler/rustc_data_structures/src/marker.rs | 10 +- .../check/{dropck.rs => always_applicable.rs} | 149 +++++++++++++----- compiler/rustc_hir_analysis/src/check/mod.rs | 6 +- .../rustc_hir_analysis/src/coherence/mod.rs | 26 +-- compiler/rustc_middle/src/traits/mod.rs | 4 +- .../src/error_reporting/traits/suggestions.rs | 2 +- library/core/src/convert/mod.rs | 1 - ...herence-conflicting-negative-trait-impl.rs | 8 +- ...nce-conflicting-negative-trait-impl.stderr | 31 +++- ...mpl-trait-for-marker-trait-negative.stderr | 20 +-- tests/ui/coherence/coherence-orphan.rs | 5 +- .../coherence-overlap-negative-impls.rs | 4 +- .../coherence-overlap-negative-impls.stderr | 16 ++ tests/ui/issues/issue-106755.rs | 5 +- tests/ui/issues/issue-106755.stderr | 31 +++- .../specialization/defaultimpl/validation.rs | 15 +- .../defaultimpl/validation.stderr | 28 ++-- .../specialization-overlap-negative.rs | 4 +- .../specialization-overlap-negative.stderr | 17 +- 19 files changed, 275 insertions(+), 107 deletions(-) rename compiler/rustc_hir_analysis/src/check/{dropck.rs => always_applicable.rs} (62%) create mode 100644 tests/ui/coherence/coherence-overlap-negative-impls.stderr diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 6ae97222f77f..4cacc269709a 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -1,3 +1,5 @@ +use std::alloc::Allocator; + #[rustc_on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \ Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`")] // This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()` @@ -28,8 +30,8 @@ impls_dyn_send_neg!( [*const T where T: ?Sized] [*mut T where T: ?Sized] [std::ptr::NonNull where T: ?Sized] - [std::rc::Rc where T: ?Sized] - [std::rc::Weak where T: ?Sized] + [std::rc::Rc where T: ?Sized, A: Allocator] + [std::rc::Weak where T: ?Sized, A: Allocator] [std::sync::MutexGuard<'_, T> where T: ?Sized] [std::sync::RwLockReadGuard<'_, T> where T: ?Sized] [std::sync::RwLockWriteGuard<'_, T> where T: ?Sized] @@ -96,8 +98,8 @@ impls_dyn_sync_neg!( [std::cell::RefCell where T: ?Sized] [std::cell::UnsafeCell where T: ?Sized] [std::ptr::NonNull where T: ?Sized] - [std::rc::Rc where T: ?Sized] - [std::rc::Weak where T: ?Sized] + [std::rc::Rc where T: ?Sized, A: Allocator] + [std::rc::Weak where T: ?Sized, A: Allocator] [std::cell::OnceCell where T] [std::sync::mpsc::Receiver where T] [std::sync::mpsc::Sender where T] diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs similarity index 62% rename from compiler/rustc_hir_analysis/src/check/dropck.rs rename to compiler/rustc_hir_analysis/src/check/always_applicable.rs index d7dfe482da44..64377ffa3476 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -1,8 +1,15 @@ +//! This module contains methods that assist in checking that impls are general +//! enough, i.e. that they always apply to every valid instantaiton of the ADT +//! they're implemented for. +//! +//! This is necessary for `Drop` and negative impls to be well-formed. + use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{ErrorGuaranteed, struct_span_code_err}; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; +use rustc_middle::span_bug; use rustc_middle::ty::util::CheckRegions; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypingMode}; use rustc_trait_selection::regions::InferCtxtRegionExt; @@ -27,11 +34,12 @@ use crate::hir::def_id::{DefId, LocalDefId}; /// 3. Any bounds on the generic parameters must be reflected in the /// struct/enum definition for the nominal type itself (i.e. /// cannot do `struct S; impl Drop for S { ... }`). -/// pub(crate) fn check_drop_impl( tcx: TyCtxt<'_>, drop_impl_did: DefId, ) -> Result<(), ErrorGuaranteed> { + let drop_impl_did = drop_impl_did.expect_local(); + match tcx.impl_polarity(drop_impl_did) { ty::ImplPolarity::Positive => {} ty::ImplPolarity::Negative => { @@ -45,55 +53,107 @@ pub(crate) fn check_drop_impl( })); } } - let dtor_self_type = tcx.type_of(drop_impl_did).instantiate_identity(); - match dtor_self_type.kind() { + + tcx.ensure_ok().orphan_check_impl(drop_impl_did)?; + + let dtor_impl_trait_ref = tcx.impl_trait_ref(drop_impl_did).unwrap().instantiate_identity(); + + match dtor_impl_trait_ref.self_ty().kind() { ty::Adt(adt_def, adt_to_impl_args) => { - ensure_drop_params_and_item_params_correspond( + ensure_impl_params_and_item_params_correspond( tcx, - drop_impl_did.expect_local(), + drop_impl_did, adt_def.did(), adt_to_impl_args, )?; - ensure_drop_predicates_are_implied_by_item_defn( + ensure_impl_predicates_are_implied_by_item_defn( tcx, - drop_impl_did.expect_local(), - adt_def.did().expect_local(), + drop_impl_did, + adt_def.did(), adt_to_impl_args, ) } _ => { - // Destructors only work on nominal types. This was - // already checked by coherence, but compilation may - // not have been terminated. - let span = tcx.def_span(drop_impl_did); - let reported = tcx.dcx().span_delayed_bug( - span, - format!("should have been rejected by coherence check: {dtor_self_type}"), - ); - Err(reported) + span_bug!(tcx.def_span(drop_impl_did), "incoherent impl of Drop"); } } } -fn ensure_drop_params_and_item_params_correspond<'tcx>( +pub(crate) fn check_negative_auto_trait_impl<'tcx>( tcx: TyCtxt<'tcx>, - drop_impl_did: LocalDefId, - self_type_did: DefId, + impl_def_id: LocalDefId, + impl_trait_ref: ty::TraitRef<'tcx>, + polarity: ty::ImplPolarity, +) -> Result<(), ErrorGuaranteed> { + let ty::ImplPolarity::Negative = polarity else { + return Ok(()); + }; + + if !tcx.trait_is_auto(impl_trait_ref.def_id) { + return Ok(()); + } + + if tcx.defaultness(impl_def_id).is_default() { + tcx.dcx().span_delayed_bug(tcx.def_span(impl_def_id), "default impl cannot be negative"); + } + + tcx.ensure_ok().orphan_check_impl(impl_def_id)?; + + match impl_trait_ref.self_ty().kind() { + ty::Adt(adt_def, adt_to_impl_args) => { + ensure_impl_params_and_item_params_correspond( + tcx, + impl_def_id, + adt_def.did(), + adt_to_impl_args, + )?; + + ensure_impl_predicates_are_implied_by_item_defn( + tcx, + impl_def_id, + adt_def.did(), + adt_to_impl_args, + ) + } + _ => { + if tcx.features().auto_traits() { + // NOTE: We ignore the applicability check for negative auto impls + // defined in libcore. In the (almost impossible) future where we + // stabilize auto impls, then the proper applicability check MUST + // be implemented here to handle non-ADT rigid types. + Ok(()) + } else { + span_bug!(tcx.def_span(impl_def_id), "incoherent impl of negative auto trait"); + } + } + } +} + +fn ensure_impl_params_and_item_params_correspond<'tcx>( + tcx: TyCtxt<'tcx>, + impl_def_id: LocalDefId, + adt_def_id: DefId, adt_to_impl_args: GenericArgsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyParam) else { return Ok(()); }; - let drop_impl_span = tcx.def_span(drop_impl_did); - let item_span = tcx.def_span(self_type_did); - let self_descr = tcx.def_descr(self_type_did); + let drop_impl_span = tcx.def_span(impl_def_id); + let item_span = tcx.def_span(adt_def_id); + let self_descr = tcx.def_descr(adt_def_id); + let polarity = match tcx.impl_polarity(impl_def_id) { + ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", + ty::ImplPolarity::Negative => "!", + }; + let trait_name = tcx + .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait")); let mut err = struct_span_code_err!( tcx.dcx(), drop_impl_span, E0366, - "`Drop` impls cannot be specialized" + "`{polarity}{trait_name}` impls cannot be specialized", ); match arg { ty::util::NotUniqueParam::DuplicateParam(arg) => { @@ -116,17 +176,22 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( /// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be /// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are /// implied by the ADT being well formed. -fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( +fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>( tcx: TyCtxt<'tcx>, - drop_impl_def_id: LocalDefId, - adt_def_id: LocalDefId, + impl_def_id: LocalDefId, + adt_def_id: DefId, adt_to_impl_args: GenericArgsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - let impl_span = tcx.def_span(drop_impl_def_id.to_def_id()); - + let impl_span = tcx.def_span(impl_def_id.to_def_id()); + let trait_name = tcx + .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait")); + let polarity = match tcx.impl_polarity(impl_def_id) { + ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", + ty::ImplPolarity::Negative => "!", + }; // Take the param-env of the adt and instantiate the args that show up in // the implementation's self type. This gives us the assumptions that the // self ty of the implementation is allowed to know just from it being a @@ -145,17 +210,21 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( let adt_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args); - let fresh_impl_args = infcx.fresh_args_for_item(impl_span, drop_impl_def_id.to_def_id()); + let fresh_impl_args = infcx.fresh_args_for_item(impl_span, impl_def_id.to_def_id()); let fresh_adt_ty = - tcx.impl_trait_ref(drop_impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty(); + tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty(); ocx.eq(&ObligationCause::dummy_with_span(impl_span), adt_env, fresh_adt_ty, impl_adt_ty) - .unwrap(); + .expect("equating fully generic trait ref should never fail"); - for (clause, span) in tcx.predicates_of(drop_impl_def_id).instantiate(tcx, fresh_impl_args) { - let normalize_cause = traits::ObligationCause::misc(span, adt_def_id); + for (clause, span) in tcx.predicates_of(impl_def_id).instantiate(tcx, fresh_impl_args) { + let normalize_cause = traits::ObligationCause::misc(span, impl_def_id); let pred = ocx.normalize(&normalize_cause, adt_env, clause); - let cause = traits::ObligationCause::new(span, adt_def_id, ObligationCauseCode::DropImpl); + let cause = traits::ObligationCause::new( + span, + impl_def_id, + ObligationCauseCode::AlwaysApplicableImpl, + ); ocx.register_obligation(traits::Obligation::new(tcx, cause, adt_env, pred)); } @@ -173,13 +242,13 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( let root_predicate = error.root_obligation.predicate; if root_predicates.insert(root_predicate) { let item_span = tcx.def_span(adt_def_id); - let self_descr = tcx.def_descr(adt_def_id.to_def_id()); + let self_descr = tcx.def_descr(adt_def_id); guar = Some( struct_span_code_err!( tcx.dcx(), error.root_obligation.cause.span, E0367, - "`Drop` impl requires `{root_predicate}` \ + "`{polarity}{trait_name}` impl requires `{root_predicate}` \ but the {self_descr} it is implemented for does not", ) .with_span_note(item_span, "the implementor must specify the same requirement") @@ -190,12 +259,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( return Err(guar.unwrap()); } - let errors = ocx.infcx.resolve_regions(adt_def_id, adt_env, []); + let errors = ocx.infcx.resolve_regions(impl_def_id, adt_env, []); if !errors.is_empty() { let mut guar = None; for error in errors { let item_span = tcx.def_span(adt_def_id); - let self_descr = tcx.def_descr(adt_def_id.to_def_id()); + let self_descr = tcx.def_descr(adt_def_id); let outlives = match error { RegionResolutionError::ConcreteFailure(_, a, b) => format!("{b}: {a}"), RegionResolutionError::GenericBoundFailure(_, generic, r) => { @@ -212,7 +281,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( tcx.dcx(), error.origin().span(), E0367, - "`Drop` impl requires `{outlives}` \ + "`{polarity}{trait_name}` impl requires `{outlives}` \ but the {self_descr} it is implemented for does not", ) .with_span_note(item_span, "the implementor must specify the same requirement") diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 1c5455710db8..d72d5b4fa19d 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -62,9 +62,9 @@ a type parameter). */ +pub mod always_applicable; mod check; mod compare_impl_item; -pub mod dropck; mod entry; pub mod intrinsic; pub mod intrinsicck; @@ -113,11 +113,11 @@ pub fn provide(providers: &mut Providers) { } fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - tcx.calculate_dtor(def_id.to_def_id(), dropck::check_drop_impl) + tcx.calculate_dtor(def_id.to_def_id(), always_applicable::check_drop_impl) } fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - tcx.calculate_async_dtor(def_id.to_def_id(), dropck::check_drop_impl) + tcx.calculate_async_dtor(def_id.to_def_id(), always_applicable::check_drop_impl) } /// Given a `DefId` for an opaque type in return position, find its parent item's return diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 0245d4c9fe4b..b5c6c2f38619 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -16,6 +16,7 @@ use rustc_span::{ErrorGuaranteed, sym}; use rustc_type_ir::elaborate; use tracing::debug; +use crate::check::always_applicable; use crate::errors; mod builtin; @@ -24,11 +25,12 @@ mod inherent_impls_overlap; mod orphan; mod unsafety; -fn check_impl( - tcx: TyCtxt<'_>, +fn check_impl<'tcx>( + tcx: TyCtxt<'tcx>, impl_def_id: LocalDefId, - trait_ref: ty::TraitRef<'_>, - trait_def: &ty::TraitDef, + trait_ref: ty::TraitRef<'tcx>, + trait_def: &'tcx ty::TraitDef, + polarity: ty::ImplPolarity, ) -> Result<(), ErrorGuaranteed> { debug!( "(checking implementation) adding impl for trait '{:?}', item '{}'", @@ -44,6 +46,12 @@ fn check_impl( enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id, trait_def) .and(enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id, trait_def)) + .and(always_applicable::check_negative_auto_trait_impl( + tcx, + impl_def_id, + trait_ref, + polarity, + )) } fn enforce_trait_manually_implementable( @@ -154,16 +162,16 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> let mut res = tcx.ensure_ok().specialization_graph_of(def_id); for &impl_def_id in impls { - let trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); - let trait_ref = trait_header.trait_ref.instantiate_identity(); + let impl_header = tcx.impl_trait_header(impl_def_id).unwrap(); + let trait_ref = impl_header.trait_ref.instantiate_identity(); let trait_def = tcx.trait_def(trait_ref.def_id); res = res - .and(check_impl(tcx, impl_def_id, trait_ref, trait_def)) + .and(check_impl(tcx, impl_def_id, trait_ref, trait_def, impl_header.polarity)) .and(check_object_overlap(tcx, impl_def_id, trait_ref)) - .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def)) + .and(unsafety::check_item(tcx, impl_def_id, impl_header, trait_def)) .and(tcx.ensure_ok().orphan_check_impl(impl_def_id)) - .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header)); + .and(builtin::check_trait(tcx, def_id, impl_def_id, impl_header)); } res diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index d033ecc75dbe..af38748d5b2a 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -397,9 +397,9 @@ pub enum ObligationCauseCode<'tcx> { RustCall, - /// Obligations to prove that a `std::ops::Drop` impl is not stronger than + /// Obligations to prove that a `Drop` or negative auto trait impl is not stronger than /// the ADT it's being implemented for. - DropImpl, + AlwaysApplicableImpl, /// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy` ConstParam(Ty<'tcx>), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index b85c18c53121..0178400414cb 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2695,7 +2695,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | ObligationCauseCode::LetElse | ObligationCauseCode::BinOp { .. } | ObligationCauseCode::AscribeUserTypeProvePredicate(..) - | ObligationCauseCode::DropImpl + | ObligationCauseCode::AlwaysApplicableImpl | ObligationCauseCode::ConstParam(_) | ObligationCauseCode::ReferenceOutlivesReferent(..) | ObligationCauseCode::ObjectTypeBound(..) => {} diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index e468f4f0f7e6..43fd54f881da 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -778,7 +778,6 @@ impl From for T { /// /// [#64715]: https://github.com/rust-lang/rust/issues/64715 #[stable(feature = "convert_infallible", since = "1.34.0")] -#[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead. #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl From for T` later; see rust-lang/rust#64715 for details"] impl From for T { diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs index 24b878927530..15ca0577e4ac 100644 --- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs +++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs @@ -8,10 +8,14 @@ struct TestType(::std::marker::PhantomData); unsafe impl Send for TestType {} -impl !Send for TestType {} //~ ERROR found both positive and negative implementation +impl !Send for TestType {} +//~^ ERROR found both positive and negative implementation +//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not -unsafe impl Send for TestType {} //~ ERROR conflicting implementations +unsafe impl Send for TestType {} +//~^ ERROR conflicting implementations impl !Send for TestType {} +//~^ ERROR `!Send` impls cannot be specialized fn main() {} diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr index 2463f38a9225..c6aed150201d 100644 --- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr +++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr @@ -8,7 +8,7 @@ LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>` - --> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1 + --> $DIR/coherence-conflicting-negative-trait-impl.rs:15:1 | LL | unsafe impl Send for TestType {} | ------------------------------------------------------ first implementation here @@ -16,7 +16,32 @@ LL | unsafe impl Send for TestType {} LL | unsafe impl Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` -error: aborting due to 2 previous errors +error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not + --> $DIR/coherence-conflicting-negative-trait-impl.rs:11:9 + | +LL | impl !Send for TestType {} + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ -Some errors have detailed explanations: E0119, E0751. +error[E0366]: `!Send` impls cannot be specialized + --> $DIR/coherence-conflicting-negative-trait-impl.rs:18:1 + | +LL | impl !Send for TestType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `i32` is not a generic parameter +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0119, E0366, E0367, E0751. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr index 77d1bdee5acf..bc81dd6f286d 100644 --- a/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr +++ b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr @@ -1,9 +1,3 @@ -error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` - --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1 - | -LL | impl !Marker1 for dyn Object + Marker2 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` - error[E0321]: traits with a default impl, like `Marker1`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)` --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1 | @@ -12,11 +6,11 @@ LL | impl !Marker1 for dyn Object + Marker2 {} | = note: a trait object implements `Marker1` if and only if `Marker1` is one of the trait object's trait bounds -error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` - --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1 +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1 | -LL | impl !Marker2 for dyn Object + Marker2 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` +LL | impl !Marker1 for dyn Object + Marker2 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)` --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1 @@ -26,6 +20,12 @@ LL | impl !Marker2 for dyn Object + Marker2 {} | = note: a trait object implements `Marker2` if and only if `Marker2` is one of the trait object's trait bounds +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1 + | +LL | impl !Marker2 for dyn Object + Marker2 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` + error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + 'static)` --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:26:1 | diff --git a/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs index aee6647a7881..665fa15c56e5 100644 --- a/tests/ui/coherence/coherence-orphan.rs +++ b/tests/ui/coherence/coherence-orphan.rs @@ -8,12 +8,13 @@ use lib::TheTrait; struct TheType; impl TheTrait for isize {} -//~^ ERROR E0117 +//~^ ERROR only traits defined in the current crate can be implemented for primitive types impl TheTrait for isize {} impl TheTrait for TheType {} -impl !Send for Vec {} //~ ERROR E0117 +impl !Send for Vec {} +//~^ ERROR only traits defined in the current crate can be implemented for types defined outside of the crate fn main() {} diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.rs b/tests/ui/coherence/coherence-overlap-negative-impls.rs index ffcd56817e5c..ba90a37cb2aa 100644 --- a/tests/ui/coherence/coherence-overlap-negative-impls.rs +++ b/tests/ui/coherence/coherence-overlap-negative-impls.rs @@ -1,6 +1,3 @@ -//@ check-pass -//@ known-bug: #74629 - // Should fail. The `0` and `1` impls overlap, violating coherence. Eg, with // `T = Test, F = ()`, all bounds are true, making both impls applicable. // `Test: Fold`, `Test: Fold<()>` are true because of `2`. @@ -39,6 +36,7 @@ mod private { pub auto trait NotNil {} impl !NotNil for Is {} + //~^ ERROR `!NotNil` impls cannot be specialized } fn main() {} diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.stderr b/tests/ui/coherence/coherence-overlap-negative-impls.stderr new file mode 100644 index 000000000000..fe22cf61b753 --- /dev/null +++ b/tests/ui/coherence/coherence-overlap-negative-impls.stderr @@ -0,0 +1,16 @@ +error[E0366]: `!NotNil` impls cannot be specialized + --> $DIR/coherence-overlap-negative-impls.rs:38:5 + | +LL | impl !NotNil for Is {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Nil` is not a generic parameter +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/coherence-overlap-negative-impls.rs:35:5 + | +LL | pub struct Is(T); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0366`. diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/issues/issue-106755.rs index 689b1d885ae6..d7e7122ebda1 100644 --- a/tests/ui/issues/issue-106755.rs +++ b/tests/ui/issues/issue-106755.rs @@ -10,10 +10,13 @@ struct TestType(::std::marker::PhantomData); unsafe impl Send for TestType {} -impl !Send for TestType {} //~ ERROR found both positive and negative implementation +impl !Send for TestType {} +//~^ ERROR found both positive and negative implementation +//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not unsafe impl Send for TestType {} //~ ERROR conflicting implementations impl !Send for TestType {} +//~^ ERROR `!Send` impls cannot be specialized fn main() {} diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/issues/issue-106755.stderr index 543970340620..da6b8c5c5632 100644 --- a/tests/ui/issues/issue-106755.stderr +++ b/tests/ui/issues/issue-106755.stderr @@ -8,7 +8,7 @@ LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>` - --> $DIR/issue-106755.rs:15:1 + --> $DIR/issue-106755.rs:17:1 | LL | unsafe impl Send for TestType {} | ------------------------------------------------------ first implementation here @@ -16,7 +16,32 @@ LL | unsafe impl Send for TestType {} LL | unsafe impl Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` -error: aborting due to 2 previous errors +error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not + --> $DIR/issue-106755.rs:13:9 + | +LL | impl !Send for TestType {} + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/issue-106755.rs:9:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ -Some errors have detailed explanations: E0119, E0751. +error[E0366]: `!Send` impls cannot be specialized + --> $DIR/issue-106755.rs:19:1 + | +LL | impl !Send for TestType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `i32` is not a generic parameter +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/issue-106755.rs:9:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0119, E0366, E0367, E0751. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/defaultimpl/validation.rs b/tests/ui/specialization/defaultimpl/validation.rs index 4049c4ea14c5..14771be8982d 100644 --- a/tests/ui/specialization/defaultimpl/validation.rs +++ b/tests/ui/specialization/defaultimpl/validation.rs @@ -6,12 +6,17 @@ struct Z; default impl S {} //~ ERROR inherent impls cannot be `default` -default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default -//~^ ERROR `S` cannot be sent between threads safely -default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default - //~^ ERROR negative impls cannot be default impls +default unsafe impl Send for S {} +//~^ ERROR impls of auto traits cannot be default + +default impl !Send for Z {} +//~^ ERROR impls of auto traits cannot be default +//~| ERROR negative impls cannot be default impls +//~| ERROR `!Send` impl requires `Z: Send` but the struct it is implemented for does not trait Tr {} -default impl !Tr for S {} //~ ERROR negative impls cannot be default impls + +default impl !Tr for S {} +//~^ ERROR negative impls cannot be default impls fn main() {} diff --git a/tests/ui/specialization/defaultimpl/validation.stderr b/tests/ui/specialization/defaultimpl/validation.stderr index f56f16162a27..d034386b842f 100644 --- a/tests/ui/specialization/defaultimpl/validation.stderr +++ b/tests/ui/specialization/defaultimpl/validation.stderr @@ -26,22 +26,20 @@ LL | default unsafe impl Send for S {} | | | default because of this -error[E0277]: `S` cannot be sent between threads safely - --> $DIR/validation.rs:9:1 +error[E0367]: `!Send` impl requires `Z: Send` but the struct it is implemented for does not + --> $DIR/validation.rs:12:1 | -LL | default unsafe impl Send for S {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `S` cannot be sent between threads safely +LL | default impl !Send for Z {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: the trait `Send` is not implemented for `S` - = help: the trait `Send` is implemented for `S` - = help: see issue #48214 -help: add `#![feature(trivial_bounds)]` to the crate attributes to enable - | -LL + #![feature(trivial_bounds)] +note: the implementor must specify the same requirement + --> $DIR/validation.rs:5:1 | +LL | struct Z; + | ^^^^^^^^ error: impls of auto traits cannot be default - --> $DIR/validation.rs:11:15 + --> $DIR/validation.rs:12:15 | LL | default impl !Send for Z {} | ------- ^^^^ auto trait @@ -49,18 +47,18 @@ LL | default impl !Send for Z {} | default because of this error[E0750]: negative impls cannot be default impls - --> $DIR/validation.rs:11:1 + --> $DIR/validation.rs:12:1 | LL | default impl !Send for Z {} | ^^^^^^^ ^ error[E0750]: negative impls cannot be default impls - --> $DIR/validation.rs:15:1 + --> $DIR/validation.rs:19:1 | LL | default impl !Tr for S {} | ^^^^^^^ ^ error: aborting due to 6 previous errors; 1 warning emitted -Some errors have detailed explanations: E0277, E0750. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0367, E0750. +For more information about an error, try `rustc --explain E0367`. diff --git a/tests/ui/specialization/specialization-overlap-negative.rs b/tests/ui/specialization/specialization-overlap-negative.rs index 550d37082953..244f21c7ba90 100644 --- a/tests/ui/specialization/specialization-overlap-negative.rs +++ b/tests/ui/specialization/specialization-overlap-negative.rs @@ -6,6 +6,8 @@ trait MyTrait {} struct TestType(::std::marker::PhantomData); unsafe impl Send for TestType {} -impl !Send for TestType {} //~ ERROR E0751 +impl !Send for TestType {} +//~^ ERROR found both positive and negative implementation of trait `Send` for type `TestType<_>` +//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not fn main() {} diff --git a/tests/ui/specialization/specialization-overlap-negative.stderr b/tests/ui/specialization/specialization-overlap-negative.stderr index a8e99953e2b6..4874e897726f 100644 --- a/tests/ui/specialization/specialization-overlap-negative.stderr +++ b/tests/ui/specialization/specialization-overlap-negative.stderr @@ -16,6 +16,19 @@ LL | unsafe impl Send for TestType {} LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here -error: aborting due to 1 previous error; 1 warning emitted +error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not + --> $DIR/specialization-overlap-negative.rs:9:9 + | +LL | impl !Send for TestType {} + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/specialization-overlap-negative.rs:6:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ -For more information about this error, try `rustc --explain E0751`. +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0367, E0751. +For more information about an error, try `rustc --explain E0367`. From 05a80608b36f71f49e6cc8d586f54c023264ac12 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Feb 2025 02:43:12 +0000 Subject: [PATCH 633/991] Make rustdoc tests use always applicable negative auto impls --- .../src/check/always_applicable.rs | 4 +- tests/rustdoc/impl-parts-crosscrate.rs | 2 +- tests/rustdoc/impl-parts.rs | 2 +- .../coherence-overlap-negative-impls.rs | 42 --------------- .../coherence-overlap-negative-impls.stderr | 16 ------ .../negated-auto-traits-validity-error.rs | 22 ++++++++ .../negated-auto-traits-validity-error.stderr | 54 +++++++++++++++++++ .../negated-auto-traits-validity.rs | 22 ++++++++ 8 files changed, 102 insertions(+), 62 deletions(-) delete mode 100644 tests/ui/coherence/coherence-overlap-negative-impls.rs delete mode 100644 tests/ui/coherence/coherence-overlap-negative-impls.stderr create mode 100644 tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs create mode 100644 tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr create mode 100644 tests/ui/traits/negative-impls/negated-auto-traits-validity.rs diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index 64377ffa3476..ba5b61d3fce0 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -140,7 +140,7 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>( return Ok(()); }; - let drop_impl_span = tcx.def_span(impl_def_id); + let impl_span = tcx.def_span(impl_def_id); let item_span = tcx.def_span(adt_def_id); let self_descr = tcx.def_descr(adt_def_id); let polarity = match tcx.impl_polarity(impl_def_id) { @@ -151,7 +151,7 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>( .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait")); let mut err = struct_span_code_err!( tcx.dcx(), - drop_impl_span, + impl_span, E0366, "`{polarity}{trait_name}` impls cannot be specialized", ); diff --git a/tests/rustdoc/impl-parts-crosscrate.rs b/tests/rustdoc/impl-parts-crosscrate.rs index 49752ab75d51..631c8bb3eb31 100644 --- a/tests/rustdoc/impl-parts-crosscrate.rs +++ b/tests/rustdoc/impl-parts-crosscrate.rs @@ -5,7 +5,7 @@ extern crate rustdoc_impl_parts_crosscrate; -pub struct Bar { t: T } +pub struct Bar { t: T } // The output file is html embedded in javascript, so the html tags // aren't stripped by the processing script and we can't check for the diff --git a/tests/rustdoc/impl-parts.rs b/tests/rustdoc/impl-parts.rs index 820f51008a40..4f281bfd63c8 100644 --- a/tests/rustdoc/impl-parts.rs +++ b/tests/rustdoc/impl-parts.rs @@ -3,7 +3,7 @@ pub auto trait AnAutoTrait {} -pub struct Foo { field: T } +pub struct Foo { field: T } //@ has impl_parts/struct.Foo.html '//*[@class="impl"]//h3[@class="code-header"]' \ // "impl !AnAutoTrait for Foowhere T: Sync + Clone," diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.rs b/tests/ui/coherence/coherence-overlap-negative-impls.rs deleted file mode 100644 index ba90a37cb2aa..000000000000 --- a/tests/ui/coherence/coherence-overlap-negative-impls.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Should fail. The `0` and `1` impls overlap, violating coherence. Eg, with -// `T = Test, F = ()`, all bounds are true, making both impls applicable. -// `Test: Fold`, `Test: Fold<()>` are true because of `2`. -// `Is: NotNil` is true because of `auto trait` and lack of negative impl. - -#![feature(negative_impls)] -#![feature(auto_traits)] - -struct Nil; -struct Cons(H); -struct Test; - -trait Fold {} - -impl Fold for Cons -// 0 -where - T: Fold, -{ -} - -impl Fold for Cons -// 1 -where - T: Fold, - private::Is: private::NotNil, -{ -} - -impl Fold for Test {} // 2 - -mod private { - use crate::Nil; - - pub struct Is(T); - pub auto trait NotNil {} - - impl !NotNil for Is {} - //~^ ERROR `!NotNil` impls cannot be specialized -} - -fn main() {} diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.stderr b/tests/ui/coherence/coherence-overlap-negative-impls.stderr deleted file mode 100644 index fe22cf61b753..000000000000 --- a/tests/ui/coherence/coherence-overlap-negative-impls.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0366]: `!NotNil` impls cannot be specialized - --> $DIR/coherence-overlap-negative-impls.rs:38:5 - | -LL | impl !NotNil for Is {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `Nil` is not a generic parameter -note: use the same sequence of generic lifetime, type and const parameters as the struct definition - --> $DIR/coherence-overlap-negative-impls.rs:35:5 - | -LL | pub struct Is(T); - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0366`. diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs new file mode 100644 index 000000000000..cd675a5efd16 --- /dev/null +++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs @@ -0,0 +1,22 @@ +#![feature(auto_traits, negative_impls)] + +auto trait Foo {} + +struct AdditionalLt<'a, T>(&'a (), T); +impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {} +//~^ ERROR `!Foo` impl requires `T: 'a` but the struct it is implemented for does not + +struct AdditionalBound(T); +trait Bound {} +impl !Foo for AdditionalBound {} +//~^ ERROR `!Foo` impl requires `T: Bound` but the struct it is implemented for does not + +struct TwoParam(T, U); +impl !Foo for TwoParam {} +//~^ ERROR `!Foo` impls cannot be specialized + +struct ConcreteParam(T); +impl !Foo for ConcreteParam {} +//~^ ERROR `!Foo` impls cannot be specialized + +fn main() {} diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr new file mode 100644 index 000000000000..ef783e901559 --- /dev/null +++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr @@ -0,0 +1,54 @@ +error[E0367]: `!Foo` impl requires `T: 'a` but the struct it is implemented for does not + --> $DIR/negated-auto-traits-validity-error.rs:6:13 + | +LL | impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {} + | ^^ + | +note: the implementor must specify the same requirement + --> $DIR/negated-auto-traits-validity-error.rs:5:1 + | +LL | struct AdditionalLt<'a, T>(&'a (), T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0367]: `!Foo` impl requires `T: Bound` but the struct it is implemented for does not + --> $DIR/negated-auto-traits-validity-error.rs:11:9 + | +LL | impl !Foo for AdditionalBound {} + | ^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/negated-auto-traits-validity-error.rs:9:1 + | +LL | struct AdditionalBound(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0366]: `!Foo` impls cannot be specialized + --> $DIR/negated-auto-traits-validity-error.rs:15:1 + | +LL | impl !Foo for TwoParam {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `T` is mentioned multiple times +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/negated-auto-traits-validity-error.rs:14:1 + | +LL | struct TwoParam(T, U); + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0366]: `!Foo` impls cannot be specialized + --> $DIR/negated-auto-traits-validity-error.rs:19:1 + | +LL | impl !Foo for ConcreteParam {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `i32` is not a generic parameter +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/negated-auto-traits-validity-error.rs:18:1 + | +LL | struct ConcreteParam(T); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0366, E0367. +For more information about an error, try `rustc --explain E0366`. diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs b/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs new file mode 100644 index 000000000000..76996b5593e6 --- /dev/null +++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs @@ -0,0 +1,22 @@ +//@ check-pass + +#![feature(auto_traits, negative_impls)] + +auto trait Foo {} +auto trait Bar {} + +struct NeedsOutlives<'a, T>(&'a T); + +impl<'a, T: 'a> !Foo for NeedsOutlives<'a, T> {} + +// Leaving out the lifetime bound +impl<'a, T> !Bar for NeedsOutlives<'a, T> {} + +struct NeedsSend(T); + +impl !Foo for NeedsSend {} + +// Leaving off the trait bound +impl !Bar for NeedsSend {} + +fn main() {} From d75995813112b0297ec727ab4de32c48adb7d695 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 4 Mar 2025 18:00:26 +0000 Subject: [PATCH 634/991] Only use implied bounds hack if bevy, and use deeply normalize in implied bounds hack --- .../rustc_hir_analysis/src/check/wfcheck.rs | 66 ++---- compiler/rustc_middle/src/query/keys.rs | 8 + compiler/rustc_middle/src/query/mod.rs | 13 +- compiler/rustc_trait_selection/src/regions.rs | 14 +- .../src/traits/outlives_bounds.rs | 18 +- .../query/type_op/implied_outlives_bounds.rs | 198 +++++------------- .../src/implied_outlives_bounds.rs | 28 +-- .../associated-inherent-types/issue-109789.rs | 1 + .../issue-109789.stderr | 10 +- .../issue-111404-1.rs | 1 + .../issue-111404-1.stderr | 10 +- tests/ui/implied-bounds/from-trait-impl.rs | 2 + .../ui/implied-bounds/from-trait-impl.stderr | 27 ++- .../normalization-nested.lifetime.stderr | 10 - .../ui/implied-bounds/normalization-nested.rs | 5 +- ...normalization-placeholder-leak.fail.stderr | 34 ++- .../normalization-placeholder-leak.rs | 4 + tests/ui/implied-bounds/sod_service_chain.rs | 8 + .../implied-bounds/sod_service_chain.stderr | 76 ++++++- 19 files changed, 264 insertions(+), 269 deletions(-) delete mode 100644 tests/ui/implied-bounds/normalization-nested.lifetime.stderr diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index d72cf00293f0..ec137bb1fcae 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -126,13 +126,14 @@ where let infcx_compat = infcx.fork(); - // We specifically want to call the non-compat version of `implied_bounds_tys`; we do this always. + // We specifically want to *disable* the implied bounds hack, first, + // so we can detect when failures are due to bevy's implied bounds. let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat( &infcx, body_def_id, param_env, assumed_wf_types.iter().copied(), - false, + true, ); lint_redundant_lifetimes(tcx, body_def_id, &outlives_env); @@ -142,53 +143,22 @@ where return Ok(()); } - let is_bevy = assumed_wf_types.visit_with(&mut ContainsBevyParamSet { tcx }).is_break(); - - // If we have set `no_implied_bounds_compat`, then do not attempt compatibility. - // We could also just always enter if `is_bevy`, and call `implied_bounds_tys`, - // but that does result in slightly more work when this option is set and - // just obscures what we mean here anyways. Let's just be explicit. - if is_bevy && !infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat { - let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat( - &infcx, - body_def_id, - param_env, - assumed_wf_types, - true, - ); - let errors_compat = infcx_compat.resolve_regions_with_outlives_env(&outlives_env); - if errors_compat.is_empty() { - Ok(()) - } else { - Err(infcx_compat.err_ctxt().report_region_errors(body_def_id, &errors_compat)) - } + let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat( + &infcx_compat, + body_def_id, + param_env, + assumed_wf_types, + // Don't *disable* the implied bounds hack; though this will only apply + // the implied bounds hack if this contains `bevy_ecs`'s `ParamSet` type. + false, + ); + let errors_compat = infcx_compat.resolve_regions_with_outlives_env(&outlives_env); + if errors_compat.is_empty() { + // FIXME: Once we fix bevy, this would be the place to insert a warning + // to upgrade bevy. + Ok(()) } else { - Err(infcx.err_ctxt().report_region_errors(body_def_id, &errors)) - } -} - -struct ContainsBevyParamSet<'tcx> { - tcx: TyCtxt<'tcx>, -} - -impl<'tcx> TypeVisitor> for ContainsBevyParamSet<'tcx> { - type Result = ControlFlow<()>; - - fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { - // We only care to match `ParamSet` or `&ParamSet`. - match t.kind() { - ty::Adt(def, _) => { - if self.tcx.item_name(def.did()) == sym::ParamSet - && self.tcx.crate_name(def.did().krate) == sym::bevy_ecs - { - return ControlFlow::Break(()); - } - } - ty::Ref(_, ty, _) => ty.visit_with(self)?, - _ => {} - } - - ControlFlow::Continue(()) + Err(infcx_compat.err_ctxt().report_region_errors(body_def_id, &errors_compat)) } } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 1489d57aba64..98314b5abfda 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -508,6 +508,14 @@ impl<'tcx, T: Clone> Key for CanonicalQueryInput<'tcx, T> { } } +impl<'tcx, T: Clone> Key for (CanonicalQueryInput<'tcx, T>, bool) { + type Cache = DefaultCache; + + fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} + impl Key for (Symbol, u32, u32) { type Cache = DefaultCache; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 1302027aabb3..4ad4427594cf 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2262,22 +2262,13 @@ rustc_queries! { desc { "normalizing `{}`", goal.value } } - query implied_outlives_bounds_compat( - goal: CanonicalImpliedOutlivesBoundsGoal<'tcx> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, - NoSolution, - > { - desc { "computing implied outlives bounds for `{}`", goal.canonical.value.value.ty } - } - query implied_outlives_bounds( - goal: CanonicalImpliedOutlivesBoundsGoal<'tcx> + key: (CanonicalImpliedOutlivesBoundsGoal<'tcx>, bool) ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { - desc { "computing implied outlives bounds v2 for `{}`", goal.canonical.value.value.ty } + desc { "computing implied outlives bounds for `{}` (hack disabled = {:?})", key.0.canonical.value.value.ty, key.1 } } /// Do not call this query directly: diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index 551717546187..068e90b00b8d 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -17,13 +17,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> { param_env: ty::ParamEnv<'tcx>, assumed_wf_tys: impl IntoIterator>, ) -> Self { - Self::new_with_implied_bounds_compat( - infcx, - body_id, - param_env, - assumed_wf_tys, - !infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat, - ) + Self::new_with_implied_bounds_compat(infcx, body_id, param_env, assumed_wf_tys, false) } fn new_with_implied_bounds_compat( @@ -31,7 +25,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> { body_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, assumed_wf_tys: impl IntoIterator>, - implied_bounds_compat: bool, + disable_implied_bounds_hack: bool, ) -> Self { let mut bounds = vec![]; @@ -59,11 +53,11 @@ impl<'tcx> OutlivesEnvironment<'tcx> { OutlivesEnvironment::from_normalized_bounds( param_env, bounds, - infcx.implied_bounds_tys_with_compat( + infcx.implied_bounds_tys( body_id, param_env, assumed_wf_tys, - implied_bounds_compat, + disable_implied_bounds_hack, ), ) } diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 189326958078..68983ef80fa4 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -36,7 +36,7 @@ fn implied_outlives_bounds<'a, 'tcx>( param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, ty: Ty<'tcx>, - compat: bool, + disable_implied_bounds_hack: bool, ) -> Vec> { let ty = infcx.resolve_vars_if_possible(ty); let ty = OpportunisticRegionResolver::new(infcx).fold_ty(ty); @@ -52,11 +52,8 @@ fn implied_outlives_bounds<'a, 'tcx>( let mut canonical_var_values = OriginalQueryValues::default(); let input = ImpliedOutlivesBounds { ty }; let canonical = infcx.canonicalize_query(param_env.and(input), &mut canonical_var_values); - let implied_bounds_result = if compat { - infcx.tcx.implied_outlives_bounds_compat(canonical) - } else { - infcx.tcx.implied_outlives_bounds(canonical) - }; + let implied_bounds_result = + infcx.tcx.implied_outlives_bounds((canonical, disable_implied_bounds_hack)); let Ok(canonical_result) = implied_bounds_result else { return vec![]; }; @@ -110,14 +107,15 @@ fn implied_outlives_bounds<'a, 'tcx>( impl<'tcx> InferCtxt<'tcx> { /// Do *NOT* call this directly. You probably want to construct a `OutlivesEnvironment` /// instead if you're interested in the implied bounds for a given signature. - fn implied_bounds_tys_with_compat>>( + fn implied_bounds_tys>>( &self, body_id: LocalDefId, param_env: ParamEnv<'tcx>, tys: Tys, - compat: bool, + disable_implied_bounds_hack: bool, ) -> impl Iterator> { - tys.into_iter() - .flat_map(move |ty| implied_outlives_bounds(self, param_env, body_id, ty, compat)) + tys.into_iter().flat_map(move |ty| { + implied_outlives_bounds(self, param_env, body_id, ty, disable_implied_bounds_hack) + }) } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index ec0b79033969..f98529860ff8 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -1,15 +1,16 @@ +use std::ops::ControlFlow; + +use rustc_infer::infer::RegionObligation; use rustc_infer::infer::canonical::CanonicalQueryInput; -use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::query::OutlivesBound; use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; use rustc_middle::infer::canonical::CanonicalQueryResponse; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt}; +use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitable, TypeVisitor}; use rustc_span::def_id::CRATE_DEF_ID; -use rustc_span::{DUMMY_SP, Span}; +use rustc_span::{DUMMY_SP, Span, sym}; use rustc_type_ir::outlives::{Component, push_outlives_components}; use smallvec::{SmallVec, smallvec}; -use tracing::debug; use crate::traits::query::NoSolution; use crate::traits::{ObligationCtxt, wf}; @@ -35,11 +36,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { tcx: TyCtxt<'tcx>, canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution> { - if tcx.sess.opts.unstable_opts.no_implied_bounds_compat { - tcx.implied_outlives_bounds(canonicalized) - } else { - tcx.implied_outlives_bounds_compat(canonicalized) - } + tcx.implied_outlives_bounds((canonicalized, false)) } fn perform_locally_with_next_solver( @@ -47,11 +44,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { key: ParamEnvAnd<'tcx, Self>, span: Span, ) -> Result { - if ocx.infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat { - compute_implied_outlives_bounds_inner(ocx, key.param_env, key.value.ty, span) - } else { - compute_implied_outlives_bounds_compat_inner(ocx, key.param_env, key.value.ty, span) - } + compute_implied_outlives_bounds_inner(ocx, key.param_env, key.value.ty, span, false) } } @@ -60,18 +53,15 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, span: Span, + disable_implied_bounds_hack: bool, ) -> Result>, NoSolution> { - let normalize_op = |ty| -> Result<_, NoSolution> { + let normalize_ty = |ty| -> Result<_, NoSolution> { // We must normalize the type so we can compute the right outlives components. // for example, if we have some constrained param type like `T: Trait`, // and we know that `&'a T::Out` is WF, then we want to imply `U: 'a`. let ty = ocx .deeply_normalize(&ObligationCause::dummy_with_span(span), param_env, ty) .map_err(|_| NoSolution)?; - if !ocx.select_all_or_error().is_empty() { - return Err(NoSolution); - } - let ty = OpportunisticRegionResolver::new(&ocx.infcx).fold_ty(ty); Ok(ty) }; @@ -81,7 +71,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( // guaranteed to be a subset of the original type, so we need to store the // WF args we've computed in a set. let mut checked_wf_args = rustc_data_structures::fx::FxHashSet::default(); - let mut wf_args = vec![ty.into(), normalize_op(ty)?.into()]; + let mut wf_args = vec![ty.into(), normalize_ty(ty)?.into()]; let mut outlives_bounds: Vec> = vec![]; @@ -96,8 +86,14 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( .into_iter() .flatten() { - assert!(!obligation.has_escaping_bound_vars()); - let Some(pred) = obligation.predicate.kind().no_bound_vars() else { + let pred = ocx + .deeply_normalize( + &ObligationCause::dummy_with_span(span), + param_env, + obligation.predicate, + ) + .map_err(|_| NoSolution)?; + let Some(pred) = pred.kind().no_bound_vars() else { continue; }; match pred { @@ -130,7 +126,6 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( ty_a, r_b, ))) => { - let ty_a = normalize_op(ty_a)?; let mut components = smallvec![]; push_outlives_components(ocx.infcx.tcx, ty_a, &mut components); outlives_bounds.extend(implied_bounds_from_components(r_b, components)) @@ -139,141 +134,48 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( } } + // If we detect `bevy_ecs::*::ParamSet` in the WF args list (and `disable_implied_bounds_hack` + // or `-Zno-implied-bounds-compat` are not set), then use the registered outlives obligations + // as implied bounds. + if !disable_implied_bounds_hack + && !ocx.infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat + && ty.visit_with(&mut ContainsBevyParamSet { tcx: ocx.infcx.tcx }).is_break() + { + for RegionObligation { sup_type, sub_region, .. } in + ocx.infcx.take_registered_region_obligations() + { + let mut components = smallvec![]; + push_outlives_components(ocx.infcx.tcx, sup_type, &mut components); + outlives_bounds.extend(implied_bounds_from_components(sub_region, components)); + } + } + Ok(outlives_bounds) } -pub fn compute_implied_outlives_bounds_compat_inner<'tcx>( - ocx: &ObligationCtxt<'_, 'tcx>, - param_env: ty::ParamEnv<'tcx>, - ty: Ty<'tcx>, - span: Span, -) -> Result>, NoSolution> { - let tcx = ocx.infcx.tcx; +struct ContainsBevyParamSet<'tcx> { + tcx: TyCtxt<'tcx>, +} - // Sometimes when we ask what it takes for T: WF, we get back that - // U: WF is required; in that case, we push U onto this stack and - // process it next. Because the resulting predicates aren't always - // guaranteed to be a subset of the original type, so we need to store the - // WF args we've computed in a set. - let mut checked_wf_args = rustc_data_structures::fx::FxHashSet::default(); - let mut wf_args = vec![ty.into()]; +impl<'tcx> TypeVisitor> for ContainsBevyParamSet<'tcx> { + type Result = ControlFlow<()>; - let mut outlives_bounds: Vec>> = vec![]; - - while let Some(arg) = wf_args.pop() { - if !checked_wf_args.insert(arg) { - continue; - } - - // Compute the obligations for `arg` to be well-formed. If `arg` is - // an unresolved inference variable, just instantiated an empty set - // -- because the return type here is going to be things we *add* - // to the environment, it's always ok for this set to be smaller - // than the ultimate set. (Note: normally there won't be - // unresolved inference variables here anyway, but there might be - // during typeck under some circumstances.) - // - // FIXME(@lcnr): It's not really "always fine", having fewer implied - // bounds can be backward incompatible, e.g. #101951 was caused by - // us not dealing with inference vars in `TypeOutlives` predicates. - let obligations = - wf::obligations(ocx.infcx, param_env, CRATE_DEF_ID, 0, arg, span).unwrap_or_default(); - - for obligation in obligations { - debug!(?obligation); - assert!(!obligation.has_escaping_bound_vars()); - - // While these predicates should all be implied by other parts of - // the program, they are still relevant as they may constrain - // inference variables, which is necessary to add the correct - // implied bounds in some cases, mostly when dealing with projections. - // - // Another important point here: we only register `Projection` - // predicates, since otherwise we might register outlives - // predicates containing inference variables, and we don't - // learn anything new from those. - if obligation.predicate.has_non_region_infer() { - match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) - | ty::PredicateKind::AliasRelate(..) => { - ocx.register_obligation(obligation.clone()); - } - _ => {} + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + // We only care to match `ParamSet` or `&ParamSet`. + match t.kind() { + ty::Adt(def, _) => { + if self.tcx.item_name(def.did()) == sym::ParamSet + && self.tcx.crate_name(def.did().krate) == sym::bevy_ecs + { + return ControlFlow::Break(()); } } - - let pred = match obligation.predicate.kind().no_bound_vars() { - None => continue, - Some(pred) => pred, - }; - match pred { - // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound - // if we ever support that - ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) - | ty::PredicateKind::Subtype(..) - | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) - | ty::PredicateKind::DynCompatible(..) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::Ambiguous - | ty::PredicateKind::NormalizesTo(..) - | ty::PredicateKind::AliasRelate(..) => {} - - // We need to search through *all* WellFormed predicates - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { - wf_args.push(arg); - } - - // We need to register region relationships - ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives( - ty::OutlivesPredicate(r_a, r_b), - )) => outlives_bounds.push(ty::OutlivesPredicate(r_a.into(), r_b)), - - ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate( - ty_a, - r_b, - ))) => outlives_bounds.push(ty::OutlivesPredicate(ty_a.into(), r_b)), - } + ty::Ref(_, ty, _) => ty.visit_with(self)?, + _ => {} } - } - // This call to `select_all_or_error` is necessary to constrain inference variables, which we - // use further down when computing the implied bounds. - match ocx.select_all_or_error().as_slice() { - [] => (), - _ => return Err(NoSolution), + ControlFlow::Continue(()) } - - // We lazily compute the outlives components as - // `select_all_or_error` constrains inference variables. - let mut implied_bounds = Vec::new(); - for ty::OutlivesPredicate(a, r_b) in outlives_bounds { - match a.unpack() { - ty::GenericArgKind::Lifetime(r_a) => { - implied_bounds.push(OutlivesBound::RegionSubRegion(r_b, r_a)) - } - ty::GenericArgKind::Type(ty_a) => { - let mut ty_a = ocx.infcx.resolve_vars_if_possible(ty_a); - // Need to manually normalize in the new solver as `wf::obligations` does not. - if ocx.infcx.next_trait_solver() { - ty_a = ocx - .deeply_normalize(&ObligationCause::dummy_with_span(span), param_env, ty_a) - .map_err(|_| NoSolution)?; - } - let mut components = smallvec![]; - push_outlives_components(tcx, ty_a, &mut components); - implied_bounds.extend(implied_bounds_from_components(r_b, components)) - } - ty::GenericArgKind::Const(_) => { - unreachable!("consts do not participate in outlives bounds") - } - } - } - - Ok(implied_bounds) } /// When we have an implied bound that `T: 'a`, we can further break diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 5f75e242a50f..6fb483e6dac9 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -10,38 +10,28 @@ use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_span::DUMMY_SP; use rustc_trait_selection::infer::InferCtxtBuilderExt; -use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::{ - compute_implied_outlives_bounds_compat_inner, compute_implied_outlives_bounds_inner, -}; +use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::compute_implied_outlives_bounds_inner; use rustc_trait_selection::traits::query::{CanonicalImpliedOutlivesBoundsGoal, NoSolution}; pub(crate) fn provide(p: &mut Providers) { - *p = Providers { implied_outlives_bounds_compat, ..*p }; *p = Providers { implied_outlives_bounds, ..*p }; } -fn implied_outlives_bounds_compat<'tcx>( - tcx: TyCtxt<'tcx>, - goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>, -) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, - NoSolution, -> { - tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { - let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts(); - compute_implied_outlives_bounds_compat_inner(ocx, param_env, ty, DUMMY_SP) - }) -} - fn implied_outlives_bounds<'tcx>( tcx: TyCtxt<'tcx>, - goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>, + (goal, disable_implied_bounds_hack): (CanonicalImpliedOutlivesBoundsGoal<'tcx>, bool), ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts(); - compute_implied_outlives_bounds_inner(ocx, param_env, ty, DUMMY_SP) + compute_implied_outlives_bounds_inner( + ocx, + param_env, + ty, + DUMMY_SP, + disable_implied_bounds_hack, + ) }) } diff --git a/tests/ui/associated-inherent-types/issue-109789.rs b/tests/ui/associated-inherent-types/issue-109789.rs index 46dd4590141d..e3c490b2dc84 100644 --- a/tests/ui/associated-inherent-types/issue-109789.rs +++ b/tests/ui/associated-inherent-types/issue-109789.rs @@ -20,5 +20,6 @@ fn bar(_: Foo fn(&'a ())>::Assoc) {} //~| ERROR mismatched types //~| ERROR higher-ranked subtype error //~| ERROR higher-ranked subtype error +//~| ERROR higher-ranked subtype error fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-109789.stderr b/tests/ui/associated-inherent-types/issue-109789.stderr index c6ea6c5541d2..db860a64826d 100644 --- a/tests/ui/associated-inherent-types/issue-109789.stderr +++ b/tests/ui/associated-inherent-types/issue-109789.stderr @@ -31,6 +31,14 @@ LL | fn bar(_: Foo fn(&'a ())>::Assoc) {} | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors +error: higher-ranked subtype error + --> $DIR/issue-109789.rs:18:1 + | +LL | fn bar(_: Foo fn(&'a ())>::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-inherent-types/issue-111404-1.rs b/tests/ui/associated-inherent-types/issue-111404-1.rs index 3255bf20ebd1..cad6d48b1c5a 100644 --- a/tests/ui/associated-inherent-types/issue-111404-1.rs +++ b/tests/ui/associated-inherent-types/issue-111404-1.rs @@ -12,5 +12,6 @@ fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {} //~| ERROR mismatched types [E0308] //~| ERROR higher-ranked subtype error //~| ERROR higher-ranked subtype error +//~| ERROR higher-ranked subtype error fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-111404-1.stderr b/tests/ui/associated-inherent-types/issue-111404-1.stderr index 5074c877a8ee..ce49126c316c 100644 --- a/tests/ui/associated-inherent-types/issue-111404-1.stderr +++ b/tests/ui/associated-inherent-types/issue-111404-1.stderr @@ -31,6 +31,14 @@ LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {} | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors +error: higher-ranked subtype error + --> $DIR/issue-111404-1.rs:10:1 + | +LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/implied-bounds/from-trait-impl.rs b/tests/ui/implied-bounds/from-trait-impl.rs index 6e126575aa9a..5822c5474bdc 100644 --- a/tests/ui/implied-bounds/from-trait-impl.rs +++ b/tests/ui/implied-bounds/from-trait-impl.rs @@ -12,6 +12,7 @@ where fn func1(foo: Foo<(&str,)>) { //~^ ERROR `&str` does not fulfill the required lifetime + //~| ERROR lifetime may not live long enough let _: &'static str = foo.0.0; } @@ -19,5 +20,6 @@ trait TestTrait {} impl TestTrait for [Foo<(X,)>; 1] {} //~^ ERROR `X` may not live long enough +//~| ERROR `X` may not live long enough fn main() {} diff --git a/tests/ui/implied-bounds/from-trait-impl.stderr b/tests/ui/implied-bounds/from-trait-impl.stderr index 4151d206ae25..5f189d3385ac 100644 --- a/tests/ui/implied-bounds/from-trait-impl.stderr +++ b/tests/ui/implied-bounds/from-trait-impl.stderr @@ -7,7 +7,21 @@ LL | fn func1(foo: Foo<(&str,)>) { = note: type must satisfy the static lifetime error[E0310]: the parameter type `X` may not live long enough - --> $DIR/from-trait-impl.rs:20:23 + --> $DIR/from-trait-impl.rs:21:1 + | +LL | impl TestTrait for [Foo<(X,)>; 1] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the parameter type `X` must be valid for the static lifetime... + | ...so that the type `X` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | impl TestTrait for [Foo<(X,)>; 1] {} + | +++++++++ + +error[E0310]: the parameter type `X` may not live long enough + --> $DIR/from-trait-impl.rs:21:23 | LL | impl TestTrait for [Foo<(X,)>; 1] {} | ^^^^^^^^^^^^^^ @@ -20,7 +34,16 @@ help: consider adding an explicit lifetime bound LL | impl TestTrait for [Foo<(X,)>; 1] {} | +++++++++ -error: aborting due to 2 previous errors +error: lifetime may not live long enough + --> $DIR/from-trait-impl.rs:13:1 + | +LL | fn func1(foo: Foo<(&str,)>) { + | ^^^^^^^^^^^^^^^^^^^-^^^^^^^ + | | | + | | let's call the lifetime of this reference `'1` + | requires that `'1` must outlive `'static` + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0310, E0477. For more information about an error, try `rustc --explain E0310`. diff --git a/tests/ui/implied-bounds/normalization-nested.lifetime.stderr b/tests/ui/implied-bounds/normalization-nested.lifetime.stderr deleted file mode 100644 index c43cc0999f1d..000000000000 --- a/tests/ui/implied-bounds/normalization-nested.lifetime.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/normalization-nested.rs:40:5 - | -LL | pub fn test_borrowck<'x>(_: Map>, s: &'x str) -> &'static str { - | -- lifetime `'x` defined here -LL | s - | ^ returning this value requires that `'x` must outlive `'static` - -error: aborting due to 1 previous error - diff --git a/tests/ui/implied-bounds/normalization-nested.rs b/tests/ui/implied-bounds/normalization-nested.rs index 4527e33a291b..9a0defd16675 100644 --- a/tests/ui/implied-bounds/normalization-nested.rs +++ b/tests/ui/implied-bounds/normalization-nested.rs @@ -3,9 +3,7 @@ // //@ revisions: param_ty lifetime param_ty_no_compat lifetime_no_compat -//@[param_ty] check-pass -//@[param_ty_no_compat] check-pass -//@[lifetime_no_compat] check-pass +//@ check-pass //@[param_ty_no_compat] compile-flags: -Zno-implied-bounds-compat //@[lifetime_no_compat] compile-flags: -Zno-implied-bounds-compat @@ -38,7 +36,6 @@ pub fn test_wfcheck<'x>(_: Map>) {} pub fn test_borrowck<'x>(_: Map>, s: &'x str) -> &'static str { s - //[lifetime]~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr b/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr index a591d0f5d4d0..8919919d04e5 100644 --- a/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr +++ b/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr @@ -1,3 +1,9 @@ +error[E0477]: the type `&'lt u8` does not fulfill the required lifetime + --> $DIR/normalization-placeholder-leak.rs:31:5 + | +LL | fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0477]: the type `&'lt u8` does not fulfill the required lifetime --> $DIR/normalization-placeholder-leak.rs:31:40 | @@ -5,11 +11,35 @@ LL | fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {} | ^^^^^^^^^^^^ error[E0477]: the type `::Ty2<'lt>` does not fulfill the required lifetime - --> $DIR/normalization-placeholder-leak.rs:36:44 + --> $DIR/normalization-placeholder-leak.rs:38:5 + | +LL | fn test_alias<'lt, T: AnotherTrait>(_: Foo>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0477]: the type `::Ty2<'lt>` does not fulfill the required lifetime + --> $DIR/normalization-placeholder-leak.rs:38:44 | LL | fn test_alias<'lt, T: AnotherTrait>(_: Foo>) {} | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: lifetime may not live long enough + --> $DIR/normalization-placeholder-leak.rs:31:5 + | +LL | fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {} + | ^^^^^^^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | lifetime `'lt` defined here + | requires that `'lt` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/normalization-placeholder-leak.rs:38:5 + | +LL | fn test_alias<'lt, T: AnotherTrait>(_: Foo>) {} + | ^^^^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | lifetime `'lt` defined here + | requires that `'lt` must outlive `'static` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0477`. diff --git a/tests/ui/implied-bounds/normalization-placeholder-leak.rs b/tests/ui/implied-bounds/normalization-placeholder-leak.rs index a9dfa69cfd6a..3a15897db821 100644 --- a/tests/ui/implied-bounds/normalization-placeholder-leak.rs +++ b/tests/ui/implied-bounds/normalization-placeholder-leak.rs @@ -30,11 +30,15 @@ mod fail { // don't use the bound to prove `'lt: 'static`. fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {} //[fail]~^ ERROR `&'lt u8` does not fulfill the required lifetime + //[fail]~| ERROR `&'lt u8` does not fulfill the required lifetime + //[fail]~| ERROR may not live long enough // implied bound: `T::Ty2<'lt>: placeholder('x)`. // don't use the bound to prove `T::Ty2<'lt>: 'static`. fn test_alias<'lt, T: AnotherTrait>(_: Foo>) {} //[fail]~^ ERROR `::Ty2<'lt>` does not fulfill the required lifetime + //[fail]~| ERROR `::Ty2<'lt>` does not fulfill the required lifetime + //[fail]~| ERROR may not live long enough } diff --git a/tests/ui/implied-bounds/sod_service_chain.rs b/tests/ui/implied-bounds/sod_service_chain.rs index 7443a29f30cb..032483e1be48 100644 --- a/tests/ui/implied-bounds/sod_service_chain.rs +++ b/tests/ui/implied-bounds/sod_service_chain.rs @@ -27,11 +27,19 @@ pub struct ServiceChainBuilder> { } impl> ServiceChainBuilder { pub fn next>( + //~^ the associated type + //~| the associated type + //~| the associated type + //~| the associated type + //~| the associated type + //~| the associated type + //~| may not live long enough self, ) -> ServiceChainBuilder, NS> { //~^ the associated type //~| the associated type //~| the associated type + //~| the associated type panic!(); } } diff --git a/tests/ui/implied-bounds/sod_service_chain.stderr b/tests/ui/implied-bounds/sod_service_chain.stderr index 1c0ef573e7d3..f5221fc11056 100644 --- a/tests/ui/implied-bounds/sod_service_chain.stderr +++ b/tests/ui/implied-bounds/sod_service_chain.stderr @@ -1,5 +1,39 @@ error[E0310]: the associated type `

::Error` may not live long enough - --> $DIR/sod_service_chain.rs:31:10 + --> $DIR/sod_service_chain.rs:29:5 + | +LL | / pub fn next>( +... | +LL | | self, +LL | | ) -> ServiceChainBuilder, NS> { + | | ^ + | | | + | |____________________________________________________the associated type `

::Error` must be valid for the static lifetime... + | ...so that the type `

::Error` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | ) -> ServiceChainBuilder, NS> where

::Error: 'static { + | ++++++++++++++++++++++++++++++++++++ + +error[E0310]: the associated type `::Error` may not live long enough + --> $DIR/sod_service_chain.rs:29:5 + | +LL | / pub fn next>( +... | +LL | | self, +LL | | ) -> ServiceChainBuilder, NS> { + | | ^ + | | | + | |____________________________________________________the associated type `::Error` must be valid for the static lifetime... + | ...so that the type `::Error` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | ) -> ServiceChainBuilder, NS> where ::Error: 'static { + | ++++++++++++++++++++++++++++++++++++ + +error[E0310]: the associated type `

::Error` may not live long enough + --> $DIR/sod_service_chain.rs:38:10 | LL | ) -> ServiceChainBuilder, NS> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +47,7 @@ LL | ) -> ServiceChainBuilder, NS> where

:: | ++++++++++++++++++++++++++++++++++++ error[E0310]: the associated type `::Error` may not live long enough - --> $DIR/sod_service_chain.rs:31:10 + --> $DIR/sod_service_chain.rs:38:10 | LL | ) -> ServiceChainBuilder, NS> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,6 +60,42 @@ help: consider adding an explicit lifetime bound LL | ) -> ServiceChainBuilder, NS> where ::Error: 'static { | ++++++++++++++++++++++++++++++++++++ -error: aborting due to 2 previous errors +error[E0310]: the associated type `

::Error` may not live long enough + --> $DIR/sod_service_chain.rs:29:5 + | +LL | / pub fn next>( +... | +LL | | self, +LL | | ) -> ServiceChainBuilder, NS> { + | | ^ + | | | + | |____________________________________________________the associated type `

::Error` must be valid for the static lifetime... + | ...so that the type `

::Error` will meet its required lifetime bounds + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider adding an explicit lifetime bound + | +LL | ) -> ServiceChainBuilder, NS> where

::Error: 'static { + | ++++++++++++++++++++++++++++++++++++ + +error[E0310]: the associated type `::Error` may not live long enough + --> $DIR/sod_service_chain.rs:29:5 + | +LL | / pub fn next>( +... | +LL | | self, +LL | | ) -> ServiceChainBuilder, NS> { + | | ^ + | | | + | |____________________________________________________the associated type `::Error` must be valid for the static lifetime... + | ...so that the type `::Error` will meet its required lifetime bounds + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider adding an explicit lifetime bound + | +LL | ) -> ServiceChainBuilder, NS> where ::Error: 'static { + | ++++++++++++++++++++++++++++++++++++ + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0310`. From 32ebe8ed04db275e68b4f1e08d7f6c8ddc806993 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 13:37:56 -0600 Subject: [PATCH 635/991] don't use double quotes --- src/librustdoc/html/static/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index cc8c7a3e43a4..5daaddd50fb6 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2319,7 +2319,7 @@ class DocSearch { * @param {rustdoc.ParserQueryElement} elem */ function convertTypeFilterOnElem(elem) { - if (typeof elem.typeFilter === 'string') { + if (typeof elem.typeFilter === "string") { let typeFilter = elem.typeFilter; if (typeFilter === "const") { typeFilter = "constant"; From d130e2545510a10373a147192d8c19cdd9bedc00 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 13:54:56 -0600 Subject: [PATCH 636/991] search.js: local variable `extra` is an array, annotate it as such. --- src/librustdoc/html/static/js/search.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 5daaddd50fb6..b4f3bcde4d4d 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2398,9 +2398,9 @@ class DocSearch { continue; } if (!foundStopChar) { - let extra = ""; + /** @type String[] */ + let extra = []; if (isLastElemGeneric(query.elems, parserState)) { - // @ts-expect-error extra = [" after ", ">"]; } else if (prevIs(parserState, "\"")) { throw ["Cannot have more than one element if you use quotes"]; From 78b92f08f9d72fd44e8d1a641c23a25a75f7f25d Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 13:58:35 -0600 Subject: [PATCH 637/991] search.js: second argument of convertNameToId is optional --- src/librustdoc/html/static/js/search.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index b4f3bcde4d4d..57e776deb5c5 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2538,7 +2538,7 @@ class DocSearch { * See `buildTypeMapIndex` for more information. * * @param {rustdoc.QueryElement} elem - * @param {boolean} isAssocType + * @param {boolean=} isAssocType */ const convertNameToId = (elem, isAssocType) => { const loweredName = elem.pathLast.toLowerCase(); @@ -2618,7 +2618,6 @@ class DocSearch { ]; } for (const elem2 of elem.generics) { - // @ts-expect-error convertNameToId(elem2); } elem.bindings = new Map(Array.from(elem.bindings.entries()) From 9581f1935bd7a8c66e17c6d65ee286f03ca2c60a Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 14:25:04 -0600 Subject: [PATCH 638/991] search.js: give pathSplitter a type signature --- src/librustdoc/html/static/js/search.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 57e776deb5c5..fb481638061d 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2740,7 +2740,11 @@ class DocSearch { return [displayPath, href, `${exactPath}::${name}`]; }; - // @ts-expect-error + /** + * + * @param {string} path + * @returns {string} + */ function pathSplitter(path) { const tmp = "" + path.replace(/::/g, "::"); if (tmp.endsWith("")) { From 4f6772d2ac31cdf5ca4fb0b3087a0d884a1f2c5c Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 14:28:45 -0600 Subject: [PATCH 639/991] give local mgens a type --- src/librustdoc/html/static/js/search.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index fb481638061d..335e35b211bf 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2834,7 +2834,7 @@ class DocSearch { } let fnInputs = null; let fnOutput = null; - // @ts-expect-error + /** @type {Map | null} */ let mgens = null; if (typeInfo !== "elems" && typeInfo !== "returned") { fnInputs = unifyFunctionTypes( @@ -3047,7 +3047,6 @@ class DocSearch { writeFn(nested, result); } return; - // @ts-expect-error } else if (mgens) { for (const [queryId, fnId] of mgens) { if (fnId === fnType.id) { From c05f6bf98d08cfb159051caaae850590758f6c15 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 14:31:35 -0600 Subject: [PATCH 640/991] search.js: give local `where` a type --- src/librustdoc/html/static/js/search.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 335e35b211bf..9d740cef3eb9 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -3062,7 +3062,7 @@ class DocSearch { name: fnParamNames[-1 - fnType.id], highlighted: !!fnType.highlighted, }, result); - // @ts-expect-error + /** @type{string[]} */ const where = []; onEachBtwn( fnType.generics, @@ -3072,7 +3072,6 @@ class DocSearch { () => pushText({ name: " + ", highlighted: false }, where), ); if (where.length > 0) { - // @ts-expect-error whereClause.set(fnParamNames[-1 - fnType.id], where); } } else { From 374de12dad8e42e1595f1af5f8e43b8b2b71c61c Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 15:19:20 -0600 Subject: [PATCH 641/991] search.js: give buildIndex a proper return type some of the fields of rustdoc.Row were confusing null and undefined. --- src/librustdoc/html/static/js/rustdoc.d.ts | 3 ++- src/librustdoc/html/static/js/search.js | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index bc4c9a12ac0a..060d82056587 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -182,10 +182,11 @@ declare namespace rustdoc { name: string, normalizedName: string, word: string, + paramNames: string[], parent: ({ty: number, name: string, path: string, exactPath: string}|null|undefined), path: string, ty: number, - type?: FunctionSearchType + type: FunctionSearchType | null, } /** diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 9d740cef3eb9..ccaa8237ff89 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1573,7 +1573,6 @@ class DocSearch { /** * @type {Array} */ - // @ts-expect-error this.searchIndex = this.buildIndex(rawSearchIndex); } @@ -1902,6 +1901,7 @@ class DocSearch { * Convert raw search index into in-memory search index. * * @param {Map} rawSearchIndex + * @returns {rustdoc.Row[]} */ buildIndex(rawSearchIndex) { /** @@ -2001,6 +2001,7 @@ class DocSearch { return cb; }; + /** @type {rustdoc.Row[]} */ const searchIndex = []; let currentIndex = 0; let id = 0; @@ -2225,6 +2226,7 @@ class DocSearch { // object defined above. const itemParentIdx = itemParentIdxDecoder.next(); normalizedName = word.indexOf("_") === -1 ? word : word.replace(/_/g, ""); + /** @type {rustdoc.Row} */ const row = { crate, ty: itemTypes.charCodeAt(i) - 65, // 65 = "A" From 5f390265409018a653ba6aef7ee7f2ce56afe972 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 15:26:46 -0600 Subject: [PATCH 642/991] search.js: allow empty result arrays --- src/librustdoc/html/static/js/search.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index ccaa8237ff89..8954cefa3163 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2759,9 +2759,9 @@ class DocSearch { * Add extra data to result objects, and filter items that have been * marked for removal. * - * @param {[rustdoc.ResultObject]} results + * @param {rustdoc.ResultObject[]} results * @param {"sig"|"elems"|"returned"|null} typeInfo - * @returns {[rustdoc.ResultObject]} + * @returns {rustdoc.ResultObject[]} */ const transformResults = (results, typeInfo) => { const duplicates = new Set(); @@ -3175,7 +3175,7 @@ class DocSearch { * @param {rustdoc.Results} results * @param {"sig"|"elems"|"returned"|null} typeInfo * @param {string} preferredCrate - * @returns {Promise<[rustdoc.ResultObject]>} + * @returns {Promise} */ const sortResults = async(results, typeInfo, preferredCrate) => { const userQuery = parsedQuery.userQuery; @@ -3331,7 +3331,6 @@ class DocSearch { return 0; }); - // @ts-expect-error return transformResults(result_list, typeInfo); }; From a9a52ddc04d45dcf06622f360ad9e784adfedc65 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 15:53:35 -0600 Subject: [PATCH 643/991] search.js: give RawSearchIndexCrate.a an index signature --- src/librustdoc/html/static/js/rustdoc.d.ts | 2 +- src/librustdoc/html/static/js/search.js | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 060d82056587..1554c045a327 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -397,7 +397,7 @@ declare namespace rustdoc { */ type RawSearchIndexCrate = { doc: string, - a: Object, + a: { [key: string]: number[] }, n: Array, t: string, D: string, diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 8954cefa3163..8deeff7f973c 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2269,16 +2269,14 @@ class DocSearch { continue; } - // @ts-expect-error + /** @type{number[]} */ let currentNameAliases; if (currentCrateAliases.has(alias_name)) { currentNameAliases = currentCrateAliases.get(alias_name); } else { currentNameAliases = []; - // @ts-expect-error currentCrateAliases.set(alias_name, currentNameAliases); } - // @ts-expect-error for (const local_alias of aliases[alias_name]) { currentNameAliases.push(local_alias + currentIndex); } From 892016766a70e929f9325f315d0a9fd953f54853 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 15:54:48 -0600 Subject: [PATCH 644/991] search.js: remove incorrect outdated comment --- src/librustdoc/html/static/js/search.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 8deeff7f973c..c275127997ab 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2102,8 +2102,6 @@ class DocSearch { // an array of [(Number) item type, // (String) name] const rawPaths = crateCorpus.p; - // an array of [(String) alias name - // [Number] index to items] const aliases = crateCorpus.a; // an array of [(Number) item index, // (String) comma-separated list of function generic param names] From 1df93fd6a7a164ebd8b7868d9382e3fb37f4642e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 25 Feb 2025 13:58:31 +1100 Subject: [PATCH 645/991] Avoid double interning of feature names. Also improve some comments. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 5cc4f4ab9e67..23e8a9865648 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -313,11 +313,11 @@ pub(crate) fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec Vec Some((true, Symbol::intern(&s[1..]))), @@ -398,13 +398,12 @@ pub(crate) fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec Date: Tue, 25 Feb 2025 14:13:16 +1100 Subject: [PATCH 646/991] Simplify `implied_target_features`. Currently its argument is an iterator, but in practice it's always a singleton. --- compiler/rustc_codegen_gcc/src/gcc_util.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm_util.rs | 6 +++--- compiler/rustc_codegen_ssa/src/target_features.rs | 2 +- compiler/rustc_target/src/target_features.rs | 12 +++++------- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 4e8c8aaaf5c8..6eae0c24f48a 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -48,7 +48,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec Vec Vec( - &self, - base_features: impl Iterator, - ) -> FxHashSet<&'a str> { + // Note: the returned set includes `base_feature`. + pub fn implied_target_features<'a>(&self, base_feature: &'a str) -> FxHashSet<&'a str> { let implied_features = self.rust_target_features().iter().map(|(f, _, i)| (f, i)).collect::>(); - // implied target features have their own implied target features, so we traverse the - // map until there are no more features to add + // Implied target features have their own implied target features, so we traverse the + // map until there are no more features to add. let mut features = FxHashSet::default(); - let mut new_features = base_features.collect::>(); + let mut new_features = vec![base_feature]; while let Some(new_feature) = new_features.pop() { if features.insert(new_feature) { if let Some(implied_features) = implied_features.get(&new_feature) { From 936a8232df56cf6fbf41beb3b2329a99498d2167 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 25 Feb 2025 15:25:54 +1100 Subject: [PATCH 647/991] Change signature of `target_features_cfg`. Currently it is called twice, once with `allow_unstable` set to true and once with it set to false. This results in some duplicated work. Most notably, for the LLVM backend, `LLVMRustHasFeature` is called twice for every feature, and it's moderately slow. For very short running compilations on platforms with many features (e.g. a `check` build of hello-world on x86) this is a significant fraction of runtime. This commit changes `target_features_cfg` so it is only called once, and it now returns a pair of feature sets. This halves the number of `LLVMRustHasFeature` calls. --- compiler/rustc_codegen_cranelift/src/lib.rs | 13 ++-- compiler/rustc_codegen_gcc/src/lib.rs | 68 ++++++++++--------- compiler/rustc_codegen_llvm/src/lib.rs | 4 +- compiler/rustc_codegen_llvm/src/llvm_util.rs | 54 ++++++++------- .../rustc_codegen_ssa/src/traits/backend.rs | 9 ++- compiler/rustc_interface/src/util.rs | 8 +-- 6 files changed, 85 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index a3f437448757..06939beb3742 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -176,13 +176,9 @@ impl CodegenBackend for CraneliftCodegenBackend { } } - fn target_features_cfg( - &self, - sess: &Session, - _allow_unstable: bool, - ) -> Vec { + fn target_features_cfg(&self, sess: &Session) -> (Vec, Vec) { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] - if sess.target.arch == "x86_64" && sess.target.os != "none" { + let target_features = if sess.target.arch == "x86_64" && sess.target.os != "none" { // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled vec![sym::fsxr, sym::sse, sym::sse2, Symbol::intern("x87")] } else if sess.target.arch == "aarch64" { @@ -196,7 +192,10 @@ impl CodegenBackend for CraneliftCodegenBackend { } } else { vec![] - } + }; + // FIXME do `unstable_target_features` properly + let unstable_target_features = target_features.clone(); + (target_features, unstable_target_features) } fn print_version(&self) { diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index f090597f9533..d478b2af46c2 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -259,8 +259,8 @@ impl CodegenBackend for GccCodegenBackend { .join(sess) } - fn target_features_cfg(&self, sess: &Session, allow_unstable: bool) -> Vec { - target_features_cfg(sess, allow_unstable, &self.target_info) + fn target_features_cfg(&self, sess: &Session) -> (Vec, Vec) { + target_features_cfg(sess, &self.target_info) } } @@ -486,35 +486,41 @@ fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { /// Returns the features that should be set in `cfg(target_feature)`. fn target_features_cfg( sess: &Session, - allow_unstable: bool, target_info: &LockedTargetInfo, -) -> Vec { +) -> (Vec, Vec) { // TODO(antoyo): use global_gcc_features. - sess.target - .rust_target_features() - .iter() - .filter_map(|&(feature, gate, _)| { - if allow_unstable - || (gate.in_cfg() && (sess.is_nightly_build() || gate.requires_nightly().is_none())) - { - Some(feature) - } else { - None - } - }) - .filter(|feature| { - // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. - if *feature == "neon" { - return false; - } - target_info.cpu_supports(feature) - /* - adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, - avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, - bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, - sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves - */ - }) - .map(Symbol::intern) - .collect() + let f = |allow_unstable| { + sess.target + .rust_target_features() + .iter() + .filter_map(|&(feature, gate, _)| { + if allow_unstable + || (gate.in_cfg() + && (sess.is_nightly_build() || gate.requires_nightly().is_none())) + { + Some(feature) + } else { + None + } + }) + .filter(|feature| { + // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. + if *feature == "neon" { + return false; + } + target_info.cpu_supports(feature) + /* + adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, + avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, + bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, + sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves + */ + }) + .map(Symbol::intern) + .collect() + }; + + let target_features = f(false); + let unstable_target_features = f(true); + (target_features, unstable_target_features) } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 8f72307eeba3..833c8441196a 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -338,8 +338,8 @@ impl CodegenBackend for LlvmCodegenBackend { llvm_util::print_version(); } - fn target_features_cfg(&self, sess: &Session, allow_unstable: bool) -> Vec { - target_features_cfg(sess, allow_unstable) + fn target_features_cfg(&self, sess: &Session) -> (Vec, Vec) { + target_features_cfg(sess) } fn codegen_crate<'tcx>( diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index f86ac13a87a3..ed861a69b71f 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -306,7 +306,7 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Vec { +pub(crate) fn target_features_cfg(sess: &Session) -> (Vec, Vec) { let mut features: FxHashSet = Default::default(); // Add base features for the target. @@ -331,6 +331,9 @@ pub(crate) fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec Vec Vec Vec { - vec![] + fn target_features_cfg(&self, _sess: &Session) -> (Vec, Vec) { + (vec![], vec![]) } fn print_passes(&self) {} diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index bc2aae7cd87e..5cccab893bb3 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -39,11 +39,11 @@ pub(crate) fn add_configuration( ) { let tf = sym::target_feature; - let unstable_target_features = codegen_backend.target_features_cfg(sess, true); - sess.unstable_target_features.extend(unstable_target_features.iter().cloned()); + let (target_features, unstable_target_features) = codegen_backend.target_features_cfg(sess); - let target_features = codegen_backend.target_features_cfg(sess, false); - sess.target_features.extend(target_features.iter().cloned()); + sess.unstable_target_features.extend(unstable_target_features.iter().copied()); + + sess.target_features.extend(target_features.iter().copied()); cfg.extend(target_features.into_iter().map(|feat| (tf, Some(feat)))); From 35b7994ea884aaa771b44fd89436f4feebf86c1b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 25 Feb 2025 16:27:09 +1100 Subject: [PATCH 648/991] Use `collect` to initialize `features`. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 53 +++++++++----------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index ed861a69b71f..a4ada290ae1f 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -307,8 +307,6 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option (Vec, Vec) { - let mut features: FxHashSet = Default::default(); - // Add base features for the target. // We do *not* add the -Ctarget-features there, and instead duplicate the logic for that below. // The reason is that if LLVM considers a feature implied but we do not, we don't want that to @@ -318,34 +316,33 @@ pub(crate) fn target_features_cfg(sess: &Session) -> (Vec, Vec) let target_machine = create_informational_target_machine(sess, true); // Compute which of the known target features are enabled in the 'base' target machine. We only // consider "supported" features; "forbidden" features are not reflected in `cfg` as of now. - features.extend( - sess.target - .rust_target_features() - .iter() - .filter(|(feature, _, _)| { - // skip checking special features, as LLVM may not understand them - if RUSTC_SPECIAL_FEATURES.contains(feature) { - return true; - } - // check that all features in a given smallvec are enabled - if let Some(feat) = to_llvm_features(sess, feature) { - for llvm_feature in feat { - let cstr = SmallCStr::new(llvm_feature); - // `LLVMRustHasFeature` is moderately expensive. On targets with many - // features (e.g. x86) these calls take a non-trivial fraction of runtime - // when compiling very small programs. - if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) } - { - return false; - } + let mut features: FxHashSet = sess + .target + .rust_target_features() + .iter() + .filter(|(feature, _, _)| { + // skip checking special features, as LLVM may not understand them + if RUSTC_SPECIAL_FEATURES.contains(feature) { + return true; + } + // check that all features in a given smallvec are enabled + if let Some(feat) = to_llvm_features(sess, feature) { + for llvm_feature in feat { + let cstr = SmallCStr::new(llvm_feature); + // `LLVMRustHasFeature` is moderately expensive. On targets with many + // features (e.g. x86) these calls take a non-trivial fraction of runtime + // when compiling very small programs. + if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) } { + return false; } - true - } else { - false } - }) - .map(|(feature, _, _)| Symbol::intern(feature)), - ); + true + } else { + false + } + }) + .map(|(feature, _, _)| Symbol::intern(feature)) + .collect(); // Add enabled and remove disabled features. for (enabled, feature) in From cee311454427bf5049f5493bb7c7d74df2abb369 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 25 Feb 2025 16:45:35 +1100 Subject: [PATCH 649/991] Remove out of date comment. No smallvecs here. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index a4ada290ae1f..4a166b0872df 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -325,7 +325,6 @@ pub(crate) fn target_features_cfg(sess: &Session) -> (Vec, Vec) if RUSTC_SPECIAL_FEATURES.contains(feature) { return true; } - // check that all features in a given smallvec are enabled if let Some(feat) = to_llvm_features(sess, feature) { for llvm_feature in feat { let cstr = SmallCStr::new(llvm_feature); From 4d75c4f8f3e2b186da379358b09f6c347657e1c2 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Tue, 4 Mar 2025 17:39:02 -0800 Subject: [PATCH 650/991] Make CrateItem::body() function return an option When we initially created `CrateItem`, it would only represent items that contain a body. That is no longer the case, for now, make this explicit by expanding the APIs to retrieve the item body. This is related to https://github.com/rust-lang/project-stable-mir/issues/34 --- compiler/stable_mir/src/lib.rs | 21 +++++++++++---- tests/ui-fulldeps/stable-mir/check_ty_fold.rs | 12 +++++---- tests/ui-fulldeps/stable-mir/crate-info.rs | 23 +++++++++------- tests/ui-fulldeps/stable-mir/projections.rs | 10 +++---- tests/ui-fulldeps/stable-mir/smir_internal.rs | 2 +- tests/ui-fulldeps/stable-mir/smir_serde.rs | 26 ++++++++----------- tests/ui-fulldeps/stable-mir/smir_visitor.rs | 12 ++++----- 7 files changed, 58 insertions(+), 48 deletions(-) diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 8df36e23c4a2..70d42dfbfcb9 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -129,13 +129,21 @@ crate_def_with_ty! { } impl CrateItem { - /// This will return the body of an item. - /// - /// This will panic if no body is available. - pub fn body(&self) -> mir::Body { + /// This will return the body of an item or panic if it's not available. + pub fn expect_body(&self) -> mir::Body { with(|cx| cx.mir_body(self.0)) } + /// Return the body of an item if available. + pub fn body(&self) -> Option { + with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0))) + } + + /// Check if a body is available for this item. + pub fn has_body(&self) -> bool { + with(|cx| cx.has_body(self.0)) + } + pub fn span(&self) -> Span { with(|cx| cx.span_of_an_item(self.0)) } @@ -156,8 +164,11 @@ impl CrateItem { with(|cx| cx.is_foreign_item(self.0)) } + /// Emit MIR for this item body. pub fn emit_mir(&self, w: &mut W) -> io::Result<()> { - self.body().dump(w, &self.name()) + self.body() + .ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))? + .dump(w, &self.name()) } } diff --git a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs index 9fa4929d68e2..9d71697178e5 100644 --- a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs +++ b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs @@ -18,9 +18,11 @@ extern crate rustc_interface; extern crate stable_mir; use rustc_smir::rustc_internal; -use stable_mir::ty::{RigidTy, TyKind, Ty, }; -use stable_mir::mir::{Body, MirVisitor, FieldIdx, Place, ProjectionElem, visit::{Location, - PlaceContext}}; +use stable_mir::mir::{ + Body, FieldIdx, MirVisitor, Place, ProjectionElem, + visit::{Location, PlaceContext}, +}; +use stable_mir::ty::{RigidTy, Ty, TyKind}; use std::io::Write; use std::ops::ControlFlow; @@ -29,8 +31,8 @@ const CRATE_NAME: &str = "input"; /// This function uses the Stable MIR APIs to get information about the test crate. fn test_stable_mir() -> ControlFlow<()> { let main_fn = stable_mir::entry_fn(); - let body = main_fn.unwrap().body(); - let mut visitor = PlaceVisitor{ body: &body, tested: false}; + let body = main_fn.unwrap().expect_body(); + let mut visitor = PlaceVisitor { body: &body, tested: false }; visitor.visit_body(&body); assert!(visitor.tested); ControlFlow::Continue(()) diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index 7f0e9b50335d..4d2d7e26276b 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -45,7 +45,7 @@ fn test_stable_mir() -> ControlFlow<()> { assert!(stable_mir::find_crates("std").len() == 1); let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap(); - let body = bar.body(); + let body = bar.expect_body(); assert_eq!(body.locals().len(), 2); assert_eq!(body.blocks.len(), 1); let block = &body.blocks[0]; @@ -60,7 +60,7 @@ fn test_stable_mir() -> ControlFlow<()> { } let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap(); - let body = foo_bar.body(); + let body = foo_bar.expect_body(); assert_eq!(body.locals().len(), 5); assert_eq!(body.blocks.len(), 4); let block = &body.blocks[0]; @@ -70,7 +70,7 @@ fn test_stable_mir() -> ControlFlow<()> { } let types = get_item(&items, (DefKind::Fn, "types")).unwrap(); - let body = types.body(); + let body = types.expect_body(); assert_eq!(body.locals().len(), 6); assert_matches!( body.locals()[0].ty.kind(), @@ -100,7 +100,7 @@ fn test_stable_mir() -> ControlFlow<()> { ); let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap(); - let body = drop.body(); + let body = drop.expect_body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; match &block.terminator.kind { @@ -109,7 +109,7 @@ fn test_stable_mir() -> ControlFlow<()> { } let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap(); - let body = assert.body(); + let body = assert.expect_body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; match &block.terminator.kind { @@ -123,7 +123,8 @@ fn test_stable_mir() -> ControlFlow<()> { match &block.terminator.kind { stable_mir::mir::TerminatorKind::Call { func, .. } => { let TyKind::RigidTy(ty) = func.ty(&body.locals()).unwrap().kind() else { - unreachable!() }; + unreachable!() + }; let RigidTy::FnDef(def, args) = ty else { unreachable!() }; let next_func = Instance::resolve(def, &args).unwrap(); match next_func.body().unwrap().locals()[1].ty.kind() { @@ -138,10 +139,10 @@ fn test_stable_mir() -> ControlFlow<()> { let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap(); // Ensure we don't panic trying to get the body of a constant. - foo_const.body(); + foo_const.expect_body(); let locals_fn = get_item(&items, (DefKind::Fn, "locals")).unwrap(); - let body = locals_fn.body(); + let body = locals_fn.expect_body(); assert_eq!(body.locals().len(), 4); assert_matches!( body.ret_local().ty.kind(), @@ -172,8 +173,10 @@ fn get_item<'a>( item: (DefKind, &str), ) -> Option<&'a stable_mir::CrateItem> { items.iter().find(|crate_item| { - matches!((item.0, crate_item.kind()), (DefKind::Fn, ItemKind::Fn) | (DefKind::Const, - ItemKind::Const)) && crate_item.name() == item.1 + matches!( + (item.0, crate_item.kind()), + (DefKind::Fn, ItemKind::Fn) | (DefKind::Const, ItemKind::Const) + ) && crate_item.name() == item.1 }) } diff --git a/tests/ui-fulldeps/stable-mir/projections.rs b/tests/ui-fulldeps/stable-mir/projections.rs index 3cc71247e674..6f82eba61fce 100644 --- a/tests/ui-fulldeps/stable-mir/projections.rs +++ b/tests/ui-fulldeps/stable-mir/projections.rs @@ -18,10 +18,10 @@ extern crate rustc_interface; extern crate stable_mir; use rustc_smir::rustc_internal; +use stable_mir::ItemKind; use stable_mir::crate_def::CrateDef; use stable_mir::mir::{ProjectionElem, Rvalue, StatementKind}; use stable_mir::ty::{RigidTy, TyKind, UintTy}; -use stable_mir::ItemKind; use std::assert_matches::assert_matches; use std::io::Write; use std::ops::ControlFlow; @@ -31,7 +31,7 @@ const CRATE_NAME: &str = "input"; /// Tests projections within Place objects fn test_place_projections() -> ControlFlow<()> { let items = stable_mir::all_local_items(); - let body = get_item(&items, (ItemKind::Fn, "projections")).unwrap().body(); + let body = get_item(&items, (ItemKind::Fn, "projections")).unwrap().expect_body(); assert_eq!(body.blocks.len(), 4); // The first statement assigns `&s.c` to a local. The projections include a deref for `s`, since // `s` is passed as a reference argument, and a field access for field `c`. @@ -53,7 +53,7 @@ fn test_place_projections() -> ControlFlow<()> { ); let ty = place.ty(body.locals()).unwrap(); assert_matches!(ty.kind().rigid(), Some(RigidTy::Ref(..))); - }, + } other => panic!( "Unable to match against expected rvalue projection. Expected the projection \ for `s.c`, which is a Deref and u8 Field. Got: {:?}", @@ -137,9 +137,7 @@ fn get_item<'a>( items: &'a stable_mir::CrateItems, item: (ItemKind, &str), ) -> Option<&'a stable_mir::CrateItem> { - items.iter().find(|crate_item| { - crate_item.kind() == item.0 && crate_item.name() == item.1 - }) + items.iter().find(|crate_item| crate_item.kind() == item.0 && crate_item.name() == item.1) } /// This test will generate and analyze a dummy crate using the stable mir. diff --git a/tests/ui-fulldeps/stable-mir/smir_internal.rs b/tests/ui-fulldeps/stable-mir/smir_internal.rs index 453e5372de4f..f9972dc27e3f 100644 --- a/tests/ui-fulldeps/stable-mir/smir_internal.rs +++ b/tests/ui-fulldeps/stable-mir/smir_internal.rs @@ -26,7 +26,7 @@ const CRATE_NAME: &str = "input"; fn test_translation(tcx: TyCtxt<'_>) -> ControlFlow<()> { let main_fn = stable_mir::entry_fn().unwrap(); - let body = main_fn.body(); + let body = main_fn.expect_body(); let orig_ty = body.locals()[0].ty; let rustc_ty = rustc_internal::internal(tcx, &orig_ty); assert!(rustc_ty.is_unit()); diff --git a/tests/ui-fulldeps/stable-mir/smir_serde.rs b/tests/ui-fulldeps/stable-mir/smir_serde.rs index 2c74276d550c..9b3638a9f2f4 100644 --- a/tests/ui-fulldeps/stable-mir/smir_serde.rs +++ b/tests/ui-fulldeps/stable-mir/smir_serde.rs @@ -14,33 +14,29 @@ extern crate rustc_smir; extern crate rustc_driver; extern crate rustc_interface; extern crate rustc_middle; -extern crate stable_mir; extern crate serde; extern crate serde_json; +extern crate stable_mir; use rustc_middle::ty::TyCtxt; use rustc_smir::rustc_internal; -use stable_mir::mir::Body; -use std::io::{Write, BufWriter}; -use std::ops::ControlFlow; use serde_json::to_string; - +use stable_mir::mir::Body; +use std::io::{BufWriter, Write}; +use std::ops::ControlFlow; const CRATE_NAME: &str = "input"; fn serialize_to_json(_tcx: TyCtxt<'_>) -> ControlFlow<()> { let path = "output.json"; - let mut writer = BufWriter::new(std::fs::File::create(path) - .expect("Failed to create path")); + let mut writer = BufWriter::new(std::fs::File::create(path).expect("Failed to create path")); let local_crate = stable_mir::local_crate(); - let items: Vec = stable_mir::all_local_items() - .iter() - .map(|item| { item.body() }) - .collect(); - let crate_data = ( local_crate.name, items ); - writer.write_all(to_string(&crate_data) - .expect("serde_json failed") - .as_bytes()).expect("JSON serialization failed"); + let items: Vec = + stable_mir::all_local_items().iter().map(|item| item.expect_body()).collect(); + let crate_data = (local_crate.name, items); + writer + .write_all(to_string(&crate_data).expect("serde_json failed").as_bytes()) + .expect("JSON serialization failed"); ControlFlow::Continue(()) } diff --git a/tests/ui-fulldeps/stable-mir/smir_visitor.rs b/tests/ui-fulldeps/stable-mir/smir_visitor.rs index 0a6415d490e4..cffb41742b4e 100644 --- a/tests/ui-fulldeps/stable-mir/smir_visitor.rs +++ b/tests/ui-fulldeps/stable-mir/smir_visitor.rs @@ -16,10 +16,10 @@ extern crate rustc_driver; extern crate rustc_interface; extern crate stable_mir; -use std::collections::HashSet; use rustc_smir::rustc_internal; -use stable_mir::*; use stable_mir::mir::MirVisitor; +use stable_mir::*; +use std::collections::HashSet; use std::io::Write; use std::ops::ControlFlow; @@ -27,7 +27,7 @@ const CRATE_NAME: &str = "input"; fn test_visitor() -> ControlFlow<()> { let main_fn = stable_mir::entry_fn(); - let main_body = main_fn.unwrap().body(); + let main_body = main_fn.unwrap().expect_body(); let main_visitor = TestVisitor::collect(&main_body); assert!(main_visitor.ret_val.is_some()); assert!(main_visitor.args.is_empty()); @@ -51,7 +51,7 @@ struct TestVisitor<'a> { pub tys: HashSet, pub ret_val: Option, pub args: Vec, - pub calls: Vec + pub calls: Vec, } impl<'a> TestVisitor<'a> { @@ -90,8 +90,8 @@ impl<'a> mir::MirVisitor for TestVisitor<'a> { fn visit_terminator(&mut self, term: &mir::Terminator, location: mir::visit::Location) { if let mir::TerminatorKind::Call { func, .. } = &term.kind { let ty::TyKind::RigidTy(ty) = func.ty(self.body.locals()).unwrap().kind() else { - unreachable! - () }; + unreachable!() + }; let ty::RigidTy::FnDef(def, args) = ty else { unreachable!() }; self.calls.push(mir::mono::Instance::resolve(def, &args).unwrap()); } From 55f8d3f628e674d6874c96c9da425db406f15d09 Mon Sep 17 00:00:00 2001 From: Predrag Gruevski Date: Tue, 4 Mar 2025 22:03:28 +0000 Subject: [PATCH 651/991] Pretty-print `#[deprecated]` attribute in HIR. --- compiler/rustc_hir_pretty/src/lib.rs | 74 ++++++++++++++++++++++++ tests/ui/unpretty/deprecated-attr.rs | 17 ++++++ tests/ui/unpretty/deprecated-attr.stdout | 21 +++++++ tests/ui/unpretty/diagnostic-attr.rs | 13 +++++ tests/ui/unpretty/diagnostic-attr.stdout | 16 +++++ 5 files changed, 141 insertions(+) create mode 100644 tests/ui/unpretty/deprecated-attr.rs create mode 100644 tests/ui/unpretty/deprecated-attr.stdout create mode 100644 tests/ui/unpretty/diagnostic-attr.rs create mode 100644 tests/ui/unpretty/diagnostic-attr.stdout diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 22edc18d71ca..1658c8dac676 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -117,6 +117,80 @@ impl<'a> State<'a> { )); self.hardbreak() } + hir::Attribute::Parsed(AttributeKind::Deprecation { deprecation, .. }) => { + self.word("#[deprecated"); + + // There are three possible forms here: + // 1. a form with explicit components like + // `#[deprecated(since = "1.2.3", note = "some note", suggestion = "something")]` + // where each component may be present or absent. + // 2. `#[deprecated = "message"]` + // 3. `#[deprecated]` + // + // Let's figure out which we need. + // If there's a `since` or `suggestion` value, we're definitely in form 1. + if matches!( + deprecation.since, + rustc_attr_parsing::DeprecatedSince::RustcVersion(..) + | rustc_attr_parsing::DeprecatedSince::Future + | rustc_attr_parsing::DeprecatedSince::NonStandard(..) + ) || deprecation.suggestion.is_some() + { + self.word("("); + let mut use_comma = false; + + match &deprecation.since { + rustc_attr_parsing::DeprecatedSince::RustcVersion(rustc_version) => { + self.word("since = \""); + self.word(format!( + "{}.{}.{}", + rustc_version.major, rustc_version.minor, rustc_version.patch + )); + self.word("\""); + use_comma = true; + } + rustc_attr_parsing::DeprecatedSince::Future => { + self.word("since = \"future\""); + use_comma = true; + } + rustc_attr_parsing::DeprecatedSince::NonStandard(symbol) => { + self.word("since = \""); + self.word(symbol.to_ident_string()); + self.word("\""); + use_comma = true; + } + _ => {} + } + + if let Some(note) = &deprecation.note { + if use_comma { + self.word(", "); + } + self.word("note = \""); + self.word(note.to_ident_string()); + self.word("\""); + use_comma = true; + } + + if let Some(suggestion) = &deprecation.suggestion { + if use_comma { + self.word(", "); + } + self.word("suggestion = \""); + self.word(suggestion.to_ident_string()); + self.word("\""); + } + } else if let Some(note) = &deprecation.note { + // We're in form 2: `#[deprecated = "message"]`. + self.word(" = \""); + self.word(note.to_ident_string()); + self.word("\""); + } else { + // We're in form 3: `#[deprecated]`. Nothing to do here. + } + + self.word("]"); + } hir::Attribute::Parsed(pa) => { self.word("#[attr=\""); pa.print_attribute(self); diff --git a/tests/ui/unpretty/deprecated-attr.rs b/tests/ui/unpretty/deprecated-attr.rs new file mode 100644 index 000000000000..dda362a595e2 --- /dev/null +++ b/tests/ui/unpretty/deprecated-attr.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +#[deprecated] +pub struct PlainDeprecated; + +#[deprecated = "here's why this is deprecated"] +pub struct DirectNote; + +#[deprecated(note = "here's why this is deprecated")] +pub struct ExplicitNote; + +#[deprecated(since = "1.2.3", note = "here's why this is deprecated")] +pub struct SinceAndNote; + +#[deprecated(note = "here's why this is deprecated", since = "1.2.3")] +pub struct FlippedOrder; diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout new file mode 100644 index 000000000000..60dbac1072b9 --- /dev/null +++ b/tests/ui/unpretty/deprecated-attr.stdout @@ -0,0 +1,21 @@ +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +#[deprecated] +struct PlainDeprecated; + +#[deprecated = "here's why this is deprecated"] +struct DirectNote; + +#[deprecated = "here's why this is deprecated"] +struct ExplicitNote; + +#[deprecated(since = "1.2.3", note = "here's why this is deprecated"] +struct SinceAndNote; + +#[deprecated(since = "1.2.3", note = "here's why this is deprecated"] +struct FlippedOrder; diff --git a/tests/ui/unpretty/diagnostic-attr.rs b/tests/ui/unpretty/diagnostic-attr.rs new file mode 100644 index 000000000000..27f5b693e691 --- /dev/null +++ b/tests/ui/unpretty/diagnostic-attr.rs @@ -0,0 +1,13 @@ +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +#[diagnostic::on_unimplemented( + message = "My Message for `ImportantTrait<{A}>` implemented for `{Self}`", + label = "My Label", + note = "Note 1", + note = "Note 2" +)] +pub trait ImportantTrait {} + +#[diagnostic::do_not_recommend] +impl ImportantTrait for T where T: Clone {} diff --git a/tests/ui/unpretty/diagnostic-attr.stdout b/tests/ui/unpretty/diagnostic-attr.stdout new file mode 100644 index 000000000000..e8696d04d38a --- /dev/null +++ b/tests/ui/unpretty/diagnostic-attr.stdout @@ -0,0 +1,16 @@ +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +#[diagnostic::on_unimplemented(message = +"My Message for `ImportantTrait<{A}>` implemented for `{Self}`", label = +"My Label", note = "Note 1", note = "Note 2")] +trait ImportantTrait { } + +#[diagnostic::do_not_recommend] +impl ImportantTrait for T where T: Clone + {#![diagnostic::do_not_recommend] +} From 1f32f7bd78e26d673162a168cac01943b544090d Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 4 Mar 2025 16:38:07 -0800 Subject: [PATCH 652/991] compiler: add `ExternAbi::is_rustic_abi` --- compiler/rustc_abi/src/extern_abi.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 543c2f8ab12c..4d70afd4e0bc 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -191,6 +191,17 @@ impl StableOrd for ExternAbi { } impl ExternAbi { + /// An ABI "like Rust" + /// + /// These ABIs are fully controlled by the Rust compiler, which means they + /// - support unwinding with `-Cpanic=unwind`, unlike `extern "C"` + /// - often diverge from the C ABI + /// - are subject to change between compiler versions + pub fn is_rustic_abi(self) -> bool { + use ExternAbi::*; + matches!(self, Rust | RustCall | RustIntrinsic | RustCold) + } + pub fn supports_varargs(self) -> bool { // * C and Cdecl obviously support varargs. // * C can be based on Aapcs, SysV64 or Win64, so they must support varargs. From 08b578330e4cad3319f2c0f9530591c3610120c2 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 4 Mar 2025 16:38:19 -0800 Subject: [PATCH 653/991] compiler: use `is_rustic_abi` in mir_transform no functional changes. --- compiler/rustc_mir_transform/src/ffi_unwind_calls.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 7b3553e7afd0..abbff1c48dd9 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -53,11 +53,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { // Rust calls cannot themselves create foreign unwinds. // We assume this is true for intrinsics as well. - if let ExternAbi::RustIntrinsic - | ExternAbi::Rust - | ExternAbi::RustCall - | ExternAbi::RustCold = sig.abi() - { + if sig.abi().is_rustic_abi() { continue; }; From 5abf36b486a426c20c71dccc9252aab6c724a0cd Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 4 Mar 2025 16:38:34 -0800 Subject: [PATCH 654/991] compiler: use `is_rustic_abi` in ImproperCTypesVisitor no functional changes --- compiler/rustc_lint/src/types.rs | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index cb83d405cc3e..d2b08eab4791 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1,7 +1,7 @@ use std::iter; use std::ops::ControlFlow; -use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, VariantIdx, Variants, WrappingRange}; +use rustc_abi::{BackendRepr, TagEncoding, VariantIdx, Variants, WrappingRange}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::DiagMessage; use rustc_hir::intravisit::VisitorExt; @@ -1349,7 +1349,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::FnPtr(sig_tys, hdr) => { let sig = sig_tys.with(hdr); - if self.is_internal_abi(sig.abi()) { + if sig.abi().is_rustic_abi() { return FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_fnptr_reason, @@ -1552,13 +1552,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { self.check_type_for_ffi_and_report_errors(span, ty, true, false); } - fn is_internal_abi(&self, abi: ExternAbi) -> bool { - matches!( - abi, - ExternAbi::Rust | ExternAbi::RustCall | ExternAbi::RustCold | ExternAbi::RustIntrinsic - ) - } - /// Find any fn-ptr types with external ABIs in `ty`. /// /// For example, `Option` returns `extern "C" fn()` @@ -1567,17 +1560,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { hir_ty: &hir::Ty<'tcx>, ty: Ty<'tcx>, ) -> Vec<(Ty<'tcx>, Span)> { - struct FnPtrFinder<'a, 'b, 'tcx> { - visitor: &'a ImproperCTypesVisitor<'b, 'tcx>, + struct FnPtrFinder<'tcx> { spans: Vec, tys: Vec>, } - impl<'a, 'b, 'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'a, 'b, 'tcx> { + impl<'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'tcx> { fn visit_ty(&mut self, ty: &'_ hir::Ty<'_, AmbigArg>) { debug!(?ty); if let hir::TyKind::BareFn(hir::BareFnTy { abi, .. }) = ty.kind - && !self.visitor.is_internal_abi(*abi) + && !abi.is_rustic_abi() { self.spans.push(ty.span); } @@ -1586,12 +1578,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } } - impl<'a, 'b, 'tcx> ty::visit::TypeVisitor> for FnPtrFinder<'a, 'b, 'tcx> { + impl<'tcx> ty::visit::TypeVisitor> for FnPtrFinder<'tcx> { type Result = (); fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { if let ty::FnPtr(_, hdr) = ty.kind() - && !self.visitor.is_internal_abi(hdr.abi) + && !hdr.abi.is_rustic_abi() { self.tys.push(ty); } @@ -1600,7 +1592,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } } - let mut visitor = FnPtrFinder { visitor: self, spans: Vec::new(), tys: Vec::new() }; + let mut visitor = FnPtrFinder { spans: Vec::new(), tys: Vec::new() }; ty.visit_with(&mut visitor); visitor.visit_ty_unambig(hir_ty); @@ -1615,13 +1607,13 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations { match it.kind { hir::ForeignItemKind::Fn(sig, _, _) => { - if vis.is_internal_abi(abi) { + if abi.is_rustic_abi() { vis.check_fn(it.owner_id.def_id, sig.decl) } else { vis.check_foreign_fn(it.owner_id.def_id, sig.decl); } } - hir::ForeignItemKind::Static(ty, _, _) if !vis.is_internal_abi(abi) => { + hir::ForeignItemKind::Static(ty, _, _) if !abi.is_rustic_abi() => { vis.check_foreign_static(it.owner_id, ty.span); } hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (), @@ -1775,7 +1767,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { }; let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition }; - if vis.is_internal_abi(abi) { + if abi.is_rustic_abi() { vis.check_fn(id, decl); } else { vis.check_foreign_fn(id, decl); From e81fbe30e6bfbfb62f599b03baf0f34bab447bef Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 4 Mar 2025 16:48:13 -0800 Subject: [PATCH 655/991] compiler: use `is_rustic_abi` in abi_check warns on fewer ABIs now --- compiler/rustc_monomorphize/src/mono_checks/abi_check.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index 9f26da7d5c64..06d6c3ab8050 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -1,6 +1,6 @@ //! This module ensures that if a function's ABI requires a particular target feature, //! that target feature is enabled both on the callee and all callers. -use rustc_abi::{BackendRepr, ExternAbi, RegKind}; +use rustc_abi::{BackendRepr, RegKind}; use rustc_hir::CRATE_HIR_ID; use rustc_middle::mir::{self, traversal}; use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt}; @@ -115,8 +115,8 @@ fn check_call_site_abi<'tcx>( span: Span, caller: InstanceKind<'tcx>, ) { - if callee.fn_sig(tcx).abi() == ExternAbi::Rust { - // "Rust" ABI never passes arguments in vector registers. + if callee.fn_sig(tcx).abi().is_rustic_abi() { + // we directly handle the soundness of Rust ABIs return; } let typing_env = ty::TypingEnv::fully_monomorphized(); From cc1e4ede9388d87750c3751f41e8c6c4f6cae995 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 5 Mar 2025 11:24:58 +0800 Subject: [PATCH 656/991] resume one waiter at a call --- compiler/rustc_query_system/src/query/job.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index a8c2aa98cd08..37b305d0a8b5 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -477,8 +477,8 @@ fn remove_cycle( /// Detects query cycles by using depth first search over all active query jobs. /// If a query cycle is found it will break the cycle by finding an edge which /// uses a query latch and then resuming that waiter. -/// There may be multiple cycles involved in a deadlock, so this searches -/// all active queries for cycles before finally resuming all the waiters at once. +/// There may be multiple cycles involved in a deadlock, but we only search +/// one cycle at a call and resume one waiter at once. See `FIXME` below. pub fn break_query_cycles(query_map: QueryMap, registry: &rayon_core::Registry) { let mut wakelist = Vec::new(); let mut jobs: Vec = query_map.keys().cloned().collect(); @@ -488,6 +488,19 @@ pub fn break_query_cycles(query_map: QueryMap, registry: &rayon_core::Registry) while jobs.len() > 0 { if remove_cycle(&query_map, &mut jobs, &mut wakelist) { found_cycle = true; + + // FIXME(#137731): Resume all the waiters at once may cause deadlocks, + // so we resume one waiter at a call for now. It's still unclear whether + // it's due to possible issues in rustc-rayon or instead in the handling + // of query cycles. + // This seem to only appear when multiple query cycles errors + // are involved, so this reduction in parallelism, while suboptimal, is not + // universal and only the deadlock handler will encounter these cases. + // The workaround shows loss of potential gains, but there still are big + // improvements in the common case, and no regressions compared to the + // single-threaded case. More investigation is still needed, and once fixed, + // we can wake up all the waiters up. + break; } } From 8a689878ced1b3c0834ea32265c7d1cd43750db4 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 4 Mar 2025 16:50:16 -0800 Subject: [PATCH 657/991] compiler: use `is_rustic_abi` in ty_utils expands some conditionals to include different "rustic" ABIs, so that we actually handle passing args through all "rustic" ABIs --- compiler/rustc_ty_utils/src/abi.rs | 7 ++----- tests/crashes/132981.rs | 11 ----------- tests/ui/abi/rust-cold-works-with-rustic-args.rs | 6 ++++++ 3 files changed, 8 insertions(+), 16 deletions(-) delete mode 100644 tests/crashes/132981.rs create mode 100644 tests/ui/abi/rust-cold-works-with-rustic-args.rs diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index e317768ff602..a726ebae6fe1 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -436,10 +436,7 @@ fn fn_abi_sanity_check<'tcx>( ) { let tcx = cx.tcx(); - if spec_abi == ExternAbi::Rust - || spec_abi == ExternAbi::RustCall - || spec_abi == ExternAbi::RustCold - { + if spec_abi.is_rustic_abi() { if arg.layout.is_zst() { // Casting closures to function pointers depends on ZST closure types being // omitted entirely in the calling convention. @@ -687,7 +684,7 @@ fn fn_abi_adjust_for_abi<'tcx>( let tcx = cx.tcx(); - if abi == ExternAbi::Rust || abi == ExternAbi::RustCall || abi == ExternAbi::RustIntrinsic { + if abi.is_rustic_abi() { fn_abi.adjust_for_rust_abi(cx, abi); // Look up the deduced parameter attributes for this function, if we have its def ID and diff --git a/tests/crashes/132981.rs b/tests/crashes/132981.rs deleted file mode 100644 index 916c15592404..000000000000 --- a/tests/crashes/132981.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #132981 -//@compile-flags: -Clink-dead-code=true --crate-type lib -//@ only-x86_64 -//@ ignore-windows -// The set of targets this crashes on is really fiddly, because it is deep in our ABI logic. It -// crashes on x86_64-unknown-linux-gnu, and i686-pc-windows-msvc, but not on -// x86_64-pc-windows-msvc. If you are trying to fix this crash, don't pay too much attention to the -// directives. - -#![feature(rust_cold_cc)] -pub extern "rust-cold" fn foo(_: [usize; 3]) {} diff --git a/tests/ui/abi/rust-cold-works-with-rustic-args.rs b/tests/ui/abi/rust-cold-works-with-rustic-args.rs new file mode 100644 index 000000000000..570273646996 --- /dev/null +++ b/tests/ui/abi/rust-cold-works-with-rustic-args.rs @@ -0,0 +1,6 @@ +//@build-pass +//@compile-flags: -Clink-dead-code=true --crate-type lib +// We used to not handle all "rustic" ABIs in a (relatively) uniform way, +// so we failed to fix up arguments for actually passing through the ABI... +#![feature(rust_cold_cc)] +pub extern "rust-cold" fn foo(_: [usize; 3]) {} From e07d9a8200bc37e3cd816386d35931f9f02e9464 Mon Sep 17 00:00:00 2001 From: Predrag Gruevski Date: Wed, 5 Mar 2025 04:46:14 +0000 Subject: [PATCH 658/991] rustdoc: Add attribute-related tests for rustdoc JSON. --- tests/rustdoc-json/attrs/export_name_2021.rs | 6 ++++++ tests/rustdoc-json/attrs/export_name_2024.rs | 9 +++++++++ tests/rustdoc-json/attrs/must_use.rs | 9 +++++++++ tests/rustdoc-json/attrs/no_mangle_2021.rs | 6 ++++++ tests/rustdoc-json/attrs/no_mangle_2024.rs | 9 +++++++++ tests/rustdoc-json/attrs/non_exhaustive.rs | 19 +++++++++++++++++++ 6 files changed, 58 insertions(+) create mode 100644 tests/rustdoc-json/attrs/export_name_2021.rs create mode 100644 tests/rustdoc-json/attrs/export_name_2024.rs create mode 100644 tests/rustdoc-json/attrs/must_use.rs create mode 100644 tests/rustdoc-json/attrs/no_mangle_2021.rs create mode 100644 tests/rustdoc-json/attrs/no_mangle_2024.rs create mode 100644 tests/rustdoc-json/attrs/non_exhaustive.rs diff --git a/tests/rustdoc-json/attrs/export_name_2021.rs b/tests/rustdoc-json/attrs/export_name_2021.rs new file mode 100644 index 000000000000..badf124bdde3 --- /dev/null +++ b/tests/rustdoc-json/attrs/export_name_2021.rs @@ -0,0 +1,6 @@ +//@ edition: 2021 +#![no_std] + +//@ is "$.index[*][?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' +#[export_name = "altered"] +pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/export_name_2024.rs b/tests/rustdoc-json/attrs/export_name_2024.rs new file mode 100644 index 000000000000..c5bb9dcc8f68 --- /dev/null +++ b/tests/rustdoc-json/attrs/export_name_2024.rs @@ -0,0 +1,9 @@ +//@ edition: 2024 +#![no_std] + +// The representation of `#[unsafe(export_name = ..)]` in rustdoc in edition 2024 +// is still `#[export_name = ..]` without the `unsafe` attribute wrapper. + +//@ is "$.index[*][?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' +#[unsafe(export_name = "altered")] +pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/must_use.rs b/tests/rustdoc-json/attrs/must_use.rs new file mode 100644 index 000000000000..dca73abc76a1 --- /dev/null +++ b/tests/rustdoc-json/attrs/must_use.rs @@ -0,0 +1,9 @@ +#![no_std] + +//@ is "$.index[*][?(@.name=='example')].attrs" '["#[must_use]"]' +#[must_use] +pub fn example() -> impl Iterator {} + +//@ is "$.index[*][?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]"]' +#[must_use = "does nothing if you do not use it"] +pub fn explicit_message() -> impl Iterator {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2021.rs b/tests/rustdoc-json/attrs/no_mangle_2021.rs new file mode 100644 index 000000000000..258542086ec3 --- /dev/null +++ b/tests/rustdoc-json/attrs/no_mangle_2021.rs @@ -0,0 +1,6 @@ +//@ edition: 2021 +#![no_std] + +//@ is "$.index[*][?(@.name=='example')].attrs" '["#[no_mangle]"]' +#[no_mangle] +pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2024.rs b/tests/rustdoc-json/attrs/no_mangle_2024.rs new file mode 100644 index 000000000000..4c01082d045e --- /dev/null +++ b/tests/rustdoc-json/attrs/no_mangle_2024.rs @@ -0,0 +1,9 @@ +//@ edition: 2024 +#![no_std] + +// The representation of `#[unsafe(no_mangle)]` in rustdoc in edition 2024 +// is still `#[no_mangle]` without the `unsafe` attribute wrapper. + +//@ is "$.index[*][?(@.name=='example')].attrs" '["#[no_mangle]"]' +#[unsafe(no_mangle)] +pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/non_exhaustive.rs b/tests/rustdoc-json/attrs/non_exhaustive.rs new file mode 100644 index 000000000000..5d738fc0560d --- /dev/null +++ b/tests/rustdoc-json/attrs/non_exhaustive.rs @@ -0,0 +1,19 @@ +#![no_std] + +//@ is "$.index[*][?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]"]' +#[non_exhaustive] +pub enum MyEnum { + First, +} + +pub enum NonExhaustiveVariant { + //@ is "$.index[*][?(@.name=='Variant')].attrs" '["#[non_exhaustive]"]' + #[non_exhaustive] + Variant(i64), +} + +//@ is "$.index[*][?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]"]' +#[non_exhaustive] +pub struct MyStruct { + pub x: i64, +} From 31e612bd7b6adf411c1a470d961657d0d4654e54 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 27 Feb 2025 15:19:44 +0300 Subject: [PATCH 659/991] move `rust.description` to `build.description` Signed-off-by: onur-ozkan --- config.example.toml | 22 +++++++++++----------- src/bootstrap/src/core/config/config.rs | 13 +++++++++++-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/config.example.toml b/config.example.toml index 2e26c024865d..ac5e491b4b52 100644 --- a/config.example.toml +++ b/config.example.toml @@ -189,6 +189,17 @@ # The default stage to use for the `bench` subcommand #bench-stage = 2 +# A descriptive string to be appended to version output (e.g., `rustc --version`), +# which is also used in places like debuginfo `DW_AT_producer`. This may be useful for +# supplementary build information, like distro-specific package versions. +# +# The Rust compiler will differentiate between versions of itself, including +# based on this string, which means that if you wish to be compatible with +# upstream Rust you need to set this to "". However, note that if you set this to "" but +# are not actually compatible -- for example if you've backported patches that change +# behavior -- this may lead to miscompilations or other bugs. +#description = "" + # Build triple for the pre-compiled snapshot compiler. If `rustc` is set, this must match its host # triple (see `rustc --version --verbose`; cross-compiling the rust build system itself is NOT # supported). If `rustc` is unset, this must be a platform with pre-compiled host tools @@ -615,17 +626,6 @@ # If using tarball sources, default value is "auto-detect", otherwise, it's "dev". #channel = if "is a tarball source" { "auto-detect" } else { "dev" } -# A descriptive string to be appended to `rustc --version` output, which is -# also used in places like debuginfo `DW_AT_producer`. This may be useful for -# supplementary build information, like distro-specific package versions. -# -# The Rust compiler will differentiate between versions of itself, including -# based on this string, which means that if you wish to be compatible with -# upstream Rust you need to set this to "". However, note that if you are not -# actually compatible -- for example if you've backported patches that change -# behavior -- this may lead to miscompilations or other bugs. -#description = "" - # The root location of the musl installation directory. The library directory # will also need to contain libunwind.a for an unwinding implementation. Note # that this option only makes sense for musl targets that produce statically diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index d0e0ed50ad89..ac24da9f86b2 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -894,6 +894,7 @@ define_config! { #[derive(Default)] struct Build { build: Option = "build", + description: Option = "description", host: Option> = "host", target: Option> = "target", build_dir: Option = "build-dir", @@ -1176,6 +1177,7 @@ define_config! { incremental: Option = "incremental", default_linker: Option = "default-linker", channel: Option = "channel", + // FIXME: Remove this field at Q2 2025, it has been replaced by build.description description: Option = "description", musl_root: Option = "musl-root", rpath: Option = "rpath", @@ -1583,6 +1585,7 @@ impl Config { config.change_id = toml.change_id.inner; let Build { + mut description, build, host, target, @@ -1831,7 +1834,7 @@ impl Config { randomize_layout, default_linker, channel: _, // already handled above - description, + description: rust_description, musl_root, rpath, verbose_tests, @@ -1924,7 +1927,12 @@ impl Config { set(&mut config.jemalloc, jemalloc); set(&mut config.test_compare_mode, test_compare_mode); set(&mut config.backtrace, backtrace); - config.description = description; + if rust_description.is_some() { + eprintln!( + "Warning: rust.description is deprecated. Use build.description instead." + ); + } + description = description.or(rust_description); set(&mut config.rust_dist_src, dist_src); set(&mut config.verbose_tests, verbose_tests); // in the case "false" is set explicitly, do not overwrite the command line args @@ -1990,6 +1998,7 @@ impl Config { } config.reproducible_artifacts = flags.reproducible_artifact; + config.description = description; // We need to override `rust.channel` if it's manually specified when using the CI rustc. // This is because if the compiler uses a different channel than the one specified in config.toml, From 92956e8cd652fb4c0669f600f334fe19b48c0526 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 27 Feb 2025 15:25:11 +0300 Subject: [PATCH 660/991] add change-entry Signed-off-by: onur-ozkan --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 5f49c50c5ad3..425ffdccad57 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -365,4 +365,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "`rust.channel` now supports \"auto-detect\" to load the channel from `src/ci/channel`", }, + ChangeInfo { + change_id: 137723, + severity: ChangeSeverity::Info, + summary: "The rust.description option has moved to build.description and rust.description is now deprecated.", + }, ]; From 853e34dbe1a8aa3f88f8d6b2644b164d95b5e987 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 27 Feb 2025 15:25:18 +0300 Subject: [PATCH 661/991] pass `CFG_VER_DESCRIPTION` to tool builds Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/tool.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 39acb646dff4..44d04a54bcc8 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -234,23 +234,32 @@ pub fn prepare_tool_cargo( cargo.env("CFG_VERSION", builder.rust_version()); cargo.env("CFG_RELEASE_NUM", &builder.version); cargo.env("DOC_RUST_LANG_ORG_CHANNEL", builder.doc_rust_lang_org_channel()); + if let Some(ref ver_date) = builder.rust_info().commit_date() { cargo.env("CFG_VER_DATE", ver_date); } + if let Some(ref ver_hash) = builder.rust_info().sha() { cargo.env("CFG_VER_HASH", ver_hash); } + if let Some(description) = &builder.config.description { + cargo.env("CFG_VER_DESCRIPTION", description); + } + let info = GitInfo::new(builder.config.omit_git_hash, &dir); if let Some(sha) = info.sha() { cargo.env("CFG_COMMIT_HASH", sha); } + if let Some(sha_short) = info.sha_short() { cargo.env("CFG_SHORT_COMMIT_HASH", sha_short); } + if let Some(date) = info.commit_date() { cargo.env("CFG_COMMIT_DATE", date); } + if !features.is_empty() { cargo.arg("--features").arg(features.join(", ")); } From 9646c2f642be66123fe32d2c64c1efc47a585522 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 27 Feb 2025 22:00:09 +0300 Subject: [PATCH 662/991] replace `rust.description` with `build.description` Signed-off-by: onur-ozkan --- src/bootstrap/configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index e3f58d97cbc4..c3b256464396 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -292,7 +292,7 @@ v( v("release-channel", "rust.channel", "the name of the release channel to build") v( "release-description", - "rust.description", + "build.description", "optional descriptive string for version output", ) v("dist-compression-formats", None, "List of compression formats to use") From b9d157c67a681e90968192cf52632028194d1231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Wed, 5 Mar 2025 07:52:23 +0200 Subject: [PATCH 663/991] Twiddle with the rustup invocation on CI --- src/tools/rust-analyzer/.github/workflows/ci.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index bc770dbe71e4..1b011c90d031 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -67,8 +67,7 @@ jobs: rustup component add --toolchain ${{ env.RUST_CHANNEL }} rust-src # We always use a nightly rustfmt, regardless of channel, because we need # --file-lines. - rustup toolchain add nightly --profile minimal - rustup component add --toolchain nightly rustfmt + rustup toolchain install nightly --profile minimal --component rustfmt # https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/rust.json - name: Install Rust Problem Matcher if: matrix.os == 'ubuntu-latest' From 7923031e7ef449aa0b1ed5ed2af9e83fc434ceda Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Wed, 5 Mar 2025 01:35:02 -0500 Subject: [PATCH 664/991] Update `compiler-builtins` to 0.1.151 This enables `f16` builtins for loongarch [1] and adds support for Cygwin [2]. [1]: https://github.com/rust-lang/compiler-builtins/pull/770 [2]: https://github.com/rust-lang/compiler-builtins/pull/774 --- ...029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch | 4 ++-- library/Cargo.lock | 4 ++-- library/alloc/Cargo.toml | 2 +- library/std/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch index d8db7d63f2dd..c2027863b00b 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644 [dependencies] core = { path = "../core", public = true } --compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std', 'no-f16-f128'] } +-compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std', 'no-f16-f128'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/library/Cargo.lock b/library/Cargo.lock index 37b10649ced4..74d9f00df21b 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.150" +version = "0.1.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c42734e0ccf0d9f953165770593a75306f0b24dda1aa03f115c70748726dbca" +checksum = "abc30f1766d387c35f2405e586d3e7a88230dc728ff78cd1d0bc59ae0b63154b" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 9cf9e98e89ee..4cb835012568 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" [dependencies] core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.9.0", default-features = false, features = ["alloc"] } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 8e4dd0f2bf48..288732ac1467 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.150" } +compiler_builtins = { version = "=0.1.151" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', From e0b75776c3265fdb9dead021e565c2fda906ed88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 26 Feb 2025 15:45:36 +0000 Subject: [PATCH 665/991] linux x64: default to `-znostart-stop-gc` This will help stabilization of lld. --- compiler/rustc_codegen_ssa/src/back/link.rs | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index a170b2e3b6a5..3407117a06e3 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -3382,6 +3382,35 @@ fn add_lld_args( // this, `wasm-component-ld`, which is overridden if this option is passed. if !sess.target.is_like_wasm { cmd.cc_arg("-fuse-ld=lld"); + + // On ELF platforms like at least x64 linux, GNU ld and LLD have opposite defaults on some + // section garbage-collection features. For example, the somewhat popular `linkme` crate and + // its dependents rely in practice on this difference: when using lld, they need `-z + // nostart-stop-gc` to prevent encapsulation symbols and sections from being + // garbage-collected. + // + // More information about all this can be found in: + // - https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order + // - https://lld.llvm.org/ELF/start-stop-gc + // + // So when using lld, we restore, for now, the traditional behavior to help migration, but + // will remove it in the future. + // Since this only disables an optimization, it shouldn't create issues, but is in theory + // slightly suboptimal. However, it: + // - doesn't have any visible impact on our benchmarks + // - reduces the need to disable lld for the crates that depend on this + // + // Note that lld can detect some cases where this difference is relied on, and emits a + // dedicated error to add this link arg. We could make use of this error to emit an FCW. As + // of writing this, we don't do it, because lld is already enabled by default on nightly + // without this mitigation: no working project would see the FCW, so we do this to help + // stabilization. + // + // FIXME: emit an FCW if linking fails due its absence, and then remove this link-arg in the + // future. + if sess.target.llvm_target == "x86_64-unknown-linux-gnu" { + cmd.link_arg("-znostart-stop-gc"); + } } if !flavor.is_gnu() { From d7ed32b0c079719b611d78bbd16f6dc695d831d4 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 5 Mar 2025 16:03:56 +0800 Subject: [PATCH 666/991] Suggest struct or union to add generic that impls trait Signed-off-by: xizheyin --- .../src/hir_ty_lowering/lint.rs | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index f5e075367f33..3611db7c68f1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -84,9 +84,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { rustc_errors::struct_span_code_err!(self.dcx(), self_ty.span, E0782, "{}", msg); if self_ty.span.can_be_used_for_suggestions() && !self.maybe_suggest_impl_trait(self_ty, &mut diag) + && !self.maybe_suggest_dyn_trait(self_ty, label, sugg, &mut diag) { - // FIXME: Only emit this suggestion if the trait is dyn-compatible. - diag.multipart_suggestion_verbose(label, sugg, Applicability::MachineApplicable); + self.maybe_suggest_add_generic_impl_trait(self_ty, &mut diag); } // Check if the impl trait that we are considering is an impl of a local trait. self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag); @@ -123,6 +123,33 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + fn maybe_suggest_add_generic_impl_trait( + &self, + self_ty: &hir::Ty<'_>, + diag: &mut Diag<'_>, + ) -> bool { + let tcx = self.tcx(); + let msg = "you might be missing a type parameter"; + let mut sugg = vec![]; + + let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; + let parent_item = tcx.hir_node_by_def_id(parent_id).expect_item(); + match parent_item.kind { + hir::ItemKind::Struct(_, generics) | hir::ItemKind::Enum(_, generics) => { + sugg.push(( + generics.where_clause_span, + format!( + "", + self.tcx().sess.source_map().span_to_snippet(self_ty.span).unwrap() + ), + )); + sugg.push((self_ty.span, "T".to_string())); + } + _ => {} + } + diag.multipart_suggestion_verbose(msg, sugg, Applicability::MachineApplicable); + true + } /// Make sure that we are in the condition to suggest the blanket implementation. fn maybe_suggest_blanket_trait_impl( &self, @@ -171,6 +198,38 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + fn maybe_suggest_dyn_trait( + &self, + self_ty: &hir::Ty<'_>, + label: &str, + sugg: Vec<(Span, String)>, + diag: &mut Diag<'_>, + ) -> bool { + let tcx = self.tcx(); + let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; + let parent_item = tcx.hir_node_by_def_id(parent_id).expect_item(); + + // If the parent item is an enum, don't suggest the dyn trait. + if let hir::ItemKind::Enum(..) = parent_item.kind { + return false; + } + + // If the parent item is a struct, check if self_ty is the last field. + if let hir::ItemKind::Struct(variant_data, _) = parent_item.kind { + if variant_data.fields().last().unwrap().ty.span != self_ty.span { + return false; + } + } + + // FIXME: Only emit this suggestion if the trait is dyn-compatible. + diag.multipart_suggestion_verbose( + label.to_string(), + sugg, + Applicability::MachineApplicable, + ); + true + } + fn add_generic_param_suggestion( &self, generics: &hir::Generics<'_>, From 0ffef9b5d158ce1954ce7b715e675d50b863bc05 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Wed, 5 Mar 2025 00:21:02 -0800 Subject: [PATCH 667/991] minicore: Add size_of to prelude and add rust_2024 prelude --- .../crates/ide-completion/src/tests/expression.rs | 1 + src/tools/rust-analyzer/crates/test-utils/src/minicore.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs index 375575128377..68218ae03fd3 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs @@ -1920,6 +1920,7 @@ fn bar() { md rust_2015 (use core::prelude::rust_2015) md rust_2018 (use core::prelude::rust_2018) md rust_2021 (use core::prelude::rust_2021) + md rust_2024 (use core::prelude::rust_2024) tt Clone tt Copy tt IntoIterator diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index 202afebde70f..d01db2d04cb7 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs @@ -1874,6 +1874,7 @@ pub mod prelude { marker::Sized, // :sized marker::Sync, // :sync mem::drop, // :drop + mem::size_of, // :size_of ops::Drop, // :drop ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}, // :async_fn ops::{Fn, FnMut, FnOnce}, // :fn @@ -1895,6 +1896,10 @@ pub mod prelude { pub mod rust_2021 { pub use super::v1::*; } + + pub mod rust_2024 { + pub use super::v1::*; + } } #[prelude_import] From 653801b854841fadbbf3bba83779a8ba82a2de8c Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Tue, 4 Mar 2025 20:28:38 -0800 Subject: [PATCH 668/991] Use size_of from the prelude instead of imported Use `std::mem::{size_of, size_of_val, align_of, align_of_val}` from the prelude instead of importing or qualifying them. These functions were added to all preludes in Rust 1.80. --- .../crates/hir-def/src/hir/type_ref.rs | 2 +- .../crates/hir-ty/src/consteval/tests.rs | 3 +- .../crates/hir-ty/src/display.rs | 2 +- .../crates/hir-ty/src/mir/eval.rs | 4 +-- .../crates/hir-ty/src/mir/lower.rs | 2 +- .../crates/ide-db/src/generated/lints.rs | 4 +-- .../crates/ide-db/src/symbol_index.rs | 3 +- .../rust-analyzer/crates/ide/src/status.rs | 3 +- .../rust-analyzer/crates/intern/src/symbol.rs | 31 +++++++------------ .../crates/profile/src/memory_usage.rs | 2 +- .../crates/test-utils/src/minicore.rs | 2 +- 11 files changed, 24 insertions(+), 34 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs index 6d4d519cd2b7..6de4026dff75 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs @@ -260,7 +260,7 @@ pub enum TypeBound { } #[cfg(target_pointer_width = "64")] -const _: [(); 24] = [(); ::std::mem::size_of::()]; +const _: [(); 24] = [(); size_of::()]; #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum UseArgRef { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index 2d7d4cacd2c5..249170c4f3ee 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -2713,12 +2713,11 @@ fn const_trait_assoc() { r#" //- minicore: size_of, fn //- /a/lib.rs crate:a - use core::mem::size_of; pub struct S(T); impl S { pub const X: usize = { let k: T; - let f = || core::mem::size_of::(); + let f = || size_of::(); f() }; } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 49f061813d10..6ee4780d206f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -4,7 +4,7 @@ use std::{ fmt::{self, Debug}, - mem::{self, size_of}, + mem, }; use base_db::CrateId; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 6b20522cf34c..d0f9f4519caa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -302,7 +302,7 @@ impl Address { } } - fn to_bytes(&self) -> [u8; mem::size_of::()] { + fn to_bytes(&self) -> [u8; size_of::()] { usize::to_le_bytes(self.to_usize()) } @@ -589,7 +589,7 @@ pub fn interpret_mir( let ty = body.locals[return_slot()].ty.clone(); let mut evaluator = Evaluator::new(db, body.owner, assert_placeholder_ty_is_unused, trait_env)?; let it: Result = (|| { - if evaluator.ptr_size() != std::mem::size_of::() { + if evaluator.ptr_size() != size_of::() { not_supported!("targets with different pointer size from host"); } let interval = evaluator.interpret_mir(body.clone(), None.into_iter())?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index f88696692e6a..2fe4ce8319e2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -1394,7 +1394,7 @@ impl<'ctx> MirLowerCtx<'ctx> { .layout_of_ty(ty.clone(), self.db.trait_environment_for_body(self.owner)) .map(|it| it.size.bytes_usize()) }; - const USIZE_SIZE: usize = mem::size_of::(); + const USIZE_SIZE: usize = size_of::(); let bytes: Box<[_]> = match l { hir_def::hir::Literal::String(b) => { let b = b.as_str(); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index ed9d6c67501e..333dbe33059c 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs @@ -15086,7 +15086,7 @@ cannot be represented as the underlying type without loss."##, }, Lint { label: "clippy::manual_bits", - description: r##"Checks for usage of `std::mem::size_of::() * 8` when + description: r##"Checks for usage of `size_of::() * 8` when `T::BITS` is available."##, default_severity: Severity::Allow, warn_since: None, @@ -17428,7 +17428,7 @@ count of elements of type `T`"##, }, Lint { label: "clippy::size_of_ref", - description: r##"Checks for calls to `std::mem::size_of_val()` where the argument is + description: r##"Checks for calls to `size_of_val()` where the argument is a reference to a reference."##, default_severity: Severity::Allow, warn_since: None, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index bb4c289c9084..2737436993de 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -24,7 +24,6 @@ use std::{ cmp::Ordering, fmt, hash::{Hash, Hasher}, - mem, ops::ControlFlow, }; @@ -299,7 +298,7 @@ impl SymbolIndex { } pub fn memory_size(&self) -> usize { - self.map.as_fst().size() + self.symbols.len() * mem::size_of::() + self.map.as_fst().size() + self.symbols.len() * size_of::() } fn range_to_map_value(start: usize, end: usize) -> u64 { diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs index f8ecaa8fdf25..a44be67668ce 100644 --- a/src/tools/rust-analyzer/crates/ide/src/status.rs +++ b/src/tools/rust-analyzer/crates/ide/src/status.rs @@ -268,8 +268,7 @@ struct AttrsStats { impl fmt::Display for AttrsStats { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let size = - self.entries * std::mem::size_of::() + self.total * std::mem::size_of::(); + let size = self.entries * size_of::() + self.total * size_of::(); let size = Bytes::new(size as _); write!( fmt, diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index b3bf285edfb1..0fa6701ca3fa 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -18,20 +18,17 @@ use triomphe::Arc; pub mod symbols; // some asserts for layout compatibility -const _: () = assert!(std::mem::size_of::>() == std::mem::size_of::<&str>()); -const _: () = assert!(std::mem::align_of::>() == std::mem::align_of::<&str>()); +const _: () = assert!(size_of::>() == size_of::<&str>()); +const _: () = assert!(align_of::>() == align_of::<&str>()); -const _: () = assert!(std::mem::size_of::>>() == std::mem::size_of::<&&str>()); -const _: () = assert!(std::mem::align_of::>>() == std::mem::align_of::<&&str>()); +const _: () = assert!(size_of::>>() == size_of::<&&str>()); +const _: () = assert!(align_of::>>() == align_of::<&&str>()); -const _: () = - assert!(std::mem::size_of::<*const *const str>() == std::mem::size_of::()); -const _: () = - assert!(std::mem::align_of::<*const *const str>() == std::mem::align_of::()); +const _: () = assert!(size_of::<*const *const str>() == size_of::()); +const _: () = assert!(align_of::<*const *const str>() == align_of::()); -const _: () = assert!(std::mem::size_of::>>() == std::mem::size_of::()); -const _: () = - assert!(std::mem::align_of::>>() == std::mem::align_of::()); +const _: () = assert!(size_of::>>() == size_of::()); +const _: () = assert!(align_of::>>() == align_of::()); /// A pointer that points to a pointer to a `str`, it may be backed as a `&'static &'static str` or /// `Arc>` but its size is that of a thin pointer. The active variant is encoded as a tag @@ -49,9 +46,7 @@ impl TaggedArcPtr { const BOOL_BITS: usize = true as usize; const fn non_arc(r: &'static &'static str) -> Self { - assert!( - mem::align_of::<&'static &'static str>().trailing_zeros() as usize > Self::BOOL_BITS - ); + assert!(align_of::<&'static &'static str>().trailing_zeros() as usize > Self::BOOL_BITS); // SAFETY: The pointer is non-null as it is derived from a reference // Ideally we would call out to `pack_arc` but for a `false` tag, unfortunately the // packing stuff requires reading out the pointer to an integer which is not supported @@ -64,9 +59,7 @@ impl TaggedArcPtr { } fn arc(arc: Arc>) -> Self { - assert!( - mem::align_of::<&'static &'static str>().trailing_zeros() as usize > Self::BOOL_BITS - ); + assert!(align_of::<&'static &'static str>().trailing_zeros() as usize > Self::BOOL_BITS); Self { packed: Self::pack_arc( // Safety: `Arc::into_raw` always returns a non null pointer @@ -131,8 +124,8 @@ impl fmt::Debug for Symbol { } } -const _: () = assert!(std::mem::size_of::() == std::mem::size_of::>()); -const _: () = assert!(std::mem::align_of::() == std::mem::align_of::>()); +const _: () = assert!(size_of::() == size_of::>()); +const _: () = assert!(align_of::() == align_of::>()); static MAP: OnceLock>> = OnceLock::new(); diff --git a/src/tools/rust-analyzer/crates/profile/src/memory_usage.rs b/src/tools/rust-analyzer/crates/profile/src/memory_usage.rs index 006748ddb08e..f5b8eca060f9 100644 --- a/src/tools/rust-analyzer/crates/profile/src/memory_usage.rs +++ b/src/tools/rust-analyzer/crates/profile/src/memory_usage.rs @@ -38,7 +38,7 @@ impl MemoryUsage { // approximate that by using the Commit Charge value. use windows_sys::Win32::System::{Threading::*, ProcessStatus::*}; - use std::mem::{MaybeUninit, size_of}; + use std::mem::MaybeUninit; let proc = unsafe { GetCurrentProcess() }; let mut mem_counters = MaybeUninit::uninit(); diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index d01db2d04cb7..bf53e58d70ce 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs @@ -1825,7 +1825,7 @@ macro_rules! impl_int { ($($t:ty)*) => { $( impl $t { - pub const fn from_ne_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub const fn from_ne_bytes(bytes: [u8; size_of::()]) -> Self { unsafe { mem::transmute(bytes) } } } From 056ec72efe71f328c40fcce63f070b3b84fbdde1 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 5 Mar 2025 12:05:19 +0300 Subject: [PATCH 669/991] trim channel value in `get_closest_merge_commit` Signed-off-by: onur-ozkan --- src/build_helper/src/git.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 3ef9c7ac35e9..9f778a2fd774 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -129,7 +129,7 @@ pub fn get_closest_merge_commit( git.current_dir(git_dir); } - let channel = include_str!("../../ci/channel"); + let channel = include_str!("../../ci/channel").trim(); let merge_base = { if CiEnv::is_ci() && From 01795b14f07910223e12240128510f48ff110629 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 27 Feb 2025 11:57:05 +0100 Subject: [PATCH 670/991] change definitely non-productive cycles to error --- .../src/solve/eval_ctxt/mod.rs | 51 +++++- .../src/solve/inspect/build.rs | 2 +- .../rustc_next_trait_solver/src/solve/mod.rs | 4 +- .../src/solve/project_goals.rs | 3 +- .../src/solve/search_graph.rs | 12 +- .../src/solve/fulfill/derive_errors.rs | 2 +- .../rustc_type_ir/src/search_graph/mod.rs | 162 ++++++++++++------ compiler/rustc_type_ir/src/solve/mod.rs | 19 +- tests/ui/associated-type-bounds/hrtb.rs | 3 + .../supertrait-defines-ty.rs | 3 + .../inherent-impls-overflow.next.stderr | 7 +- .../inherent-impls-overflow.rs | 2 +- .../trait_ref_is_knowable-norm-overflow.rs | 8 +- ...trait_ref_is_knowable-norm-overflow.stderr | 16 +- .../cyclic-normalization-to-error-nalgebra.rs | 21 +++ .../recursive-self-normalization-2.rs | 7 +- .../recursive-self-normalization-2.stderr | 56 +----- .../overflow/recursive-self-normalization.rs | 7 +- .../recursive-self-normalization.stderr | 56 +----- 19 files changed, 235 insertions(+), 206 deletions(-) create mode 100644 tests/ui/traits/next-solver/cycles/cyclic-normalization-to-error-nalgebra.rs diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index b0bbec489471..e48ee71c858c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -271,12 +271,39 @@ where /// and will need to clearly document it in the rustc-dev-guide before /// stabilization. pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind { - match (self.current_goal_kind, source) { - (_, GoalSource::NormalizeGoal(step_kind)) => step_kind, - (CurrentGoalKind::CoinductiveTrait, GoalSource::ImplWhereBound) => { - PathKind::Coinductive + match source { + // We treat these goals as unknown for now. It is likely that most miscellaneous + // nested goals will be converted to an inductive variant in the future. + // + // Having unknown cycles is always the safer option, as changing that to either + // succeed or hard error is backwards compatible. If we incorrectly treat a cycle + // as inductive even though it should not be, it may be unsound during coherence and + // fixing it may cause inference breakage or introduce ambiguity. + GoalSource::Misc => PathKind::Unknown, + GoalSource::NormalizeGoal(path_kind) => path_kind, + GoalSource::ImplWhereBound => { + // We currently only consider a cycle coinductive if it steps + // into a where-clause of a coinductive trait. + // + // We probably want to make all traits coinductive in the future, + // so we treat cycles involving their where-clauses as ambiguous. + if let CurrentGoalKind::CoinductiveTrait = self.current_goal_kind { + PathKind::Coinductive + } else { + PathKind::Unknown + } } - _ => PathKind::Inductive, + // Relating types is always unproductive. If we were to map proof trees to + // corecursive functions as explained in #136824, relating types never + // introduces a constructor which could cause the recursion to be guarded. + GoalSource::TypeRelating => PathKind::Inductive, + // Instantiating a higher ranked goal can never cause the recursion to be + // guarded and is therefore unproductive. + GoalSource::InstantiateHigherRanked => PathKind::Inductive, + // These goal sources are likely unproductive and can be changed to + // `PathKind::Inductive`. Keeping them as unknown until we're confident + // about this and have an example where it is necessary. + GoalSource::AliasBoundConstCondition | GoalSource::AliasWellFormed => PathKind::Unknown, } } @@ -606,7 +633,7 @@ where let (NestedNormalizationGoals(nested_goals), _, certainty) = self.evaluate_goal_raw( GoalEvaluationKind::Nested, - GoalSource::Misc, + GoalSource::TypeRelating, unconstrained_goal, )?; // Add the nested goals from normalization to our own nested goals. @@ -683,7 +710,7 @@ where pub(super) fn add_normalizes_to_goal(&mut self, mut goal: Goal>) { goal.predicate = goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new( self, - GoalSource::Misc, + GoalSource::TypeRelating, goal.param_env, )); self.inspect.add_normalizes_to_goal(self.delegate, self.max_input_universe, goal); @@ -939,7 +966,15 @@ where rhs: T, ) -> Result<(), NoSolution> { let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?; - self.add_goals(GoalSource::Misc, goals); + if cfg!(debug_assertions) { + for g in goals.iter() { + match g.predicate.kind().skip_binder() { + ty::PredicateKind::Subtype { .. } | ty::PredicateKind::AliasRelate(..) => {} + p => unreachable!("unexpected nested goal in `relate`: {p:?}"), + } + } + } + self.add_goals(GoalSource::TypeRelating, goals); Ok(()) } diff --git a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs index 1607fbb1b6a7..6a8e0790f7cb 100644 --- a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs +++ b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs @@ -421,7 +421,7 @@ impl, I: Interner> ProofTreeBuilder { self.add_goal( delegate, max_input_universe, - GoalSource::Misc, + GoalSource::TypeRelating, goal.with(delegate.cx(), goal.predicate), ); } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 1fa35b60304c..199f0c7512e1 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -313,7 +313,9 @@ where ty::AliasRelationDirection::Equate, ), ); - self.add_goal(GoalSource::Misc, alias_relate_goal); + // We normalize the self type to be able to relate it with + // types from candidates. + self.add_goal(GoalSource::TypeRelating, alias_relate_goal); self.try_evaluate_added_goals()?; Ok(self.resolve_vars_if_possible(normalized_term)) } else { diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals.rs index d94528800717..944d5f0e042d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals.rs @@ -24,7 +24,8 @@ where ty::AliasRelationDirection::Equate, ), ); - self.add_goal(GoalSource::Misc, goal); + // A projection goal holds if the alias is equal to the expected term. + self.add_goal(GoalSource::TypeRelating, goal); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index 67eb442d2cce..aa1206cd6b73 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use rustc_type_ir::Interner; use rustc_type_ir::search_graph::{self, PathKind}; -use rustc_type_ir::solve::{CanonicalInput, Certainty, QueryResult}; +use rustc_type_ir::solve::{CanonicalInput, Certainty, NoSolution, QueryResult}; use super::inspect::ProofTreeBuilder; use super::{FIXPOINT_STEP_LIMIT, has_no_inference_or_external_constraints}; @@ -47,7 +47,8 @@ where ) -> QueryResult { match kind { PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes), - PathKind::Inductive => response_no_constraints(cx, input, Certainty::overflow(false)), + PathKind::Unknown => response_no_constraints(cx, input, Certainty::overflow(false)), + PathKind::Inductive => Err(NoSolution), } } @@ -57,12 +58,7 @@ where input: CanonicalInput, result: QueryResult, ) -> bool { - match kind { - PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes) == result, - PathKind::Inductive => { - response_no_constraints(cx, input, Certainty::overflow(false)) == result - } - } + Self::initial_provisional_result(cx, kind, input) == result } fn on_stack_overflow( diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 4f177df89e23..352ac7c1a4e6 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -440,7 +440,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { match (child_mode, nested_goal.source()) { ( ChildMode::Trait(_) | ChildMode::Host(_), - GoalSource::Misc | GoalSource::NormalizeGoal(_), + GoalSource::Misc | GoalSource::TypeRelating | GoalSource::NormalizeGoal(_), ) => { continue; } diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 18e84db5d686..1950fab35be3 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -13,6 +13,7 @@ /// behavior as long as the resulting behavior is still correct. use std::cmp::Ordering; use std::collections::BTreeMap; +use std::collections::hash_map::Entry; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; @@ -20,7 +21,7 @@ use std::marker::PhantomData; use derive_where::derive_where; use rustc_index::{Idx, IndexVec}; #[cfg(feature = "nightly")] -use rustc_macros::HashStable_NoContext; +use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use tracing::debug; use crate::data_structures::HashMap; @@ -111,21 +112,32 @@ pub trait Delegate { /// In the initial iteration of a cycle, we do not yet have a provisional /// result. In the case we return an initial provisional result depending /// on the kind of cycle. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub enum PathKind { - Coinductive, + /// A path consisting of only inductive/unproductive steps. Inductive, + /// A path which is not be coinductive right now but we may want + /// to change of them to be so in the future. We return an ambiguous + /// result in this case to prevent people from relying on this. + Unknown, + /// A path with at least one coinductive step. Such cycles hold. + Coinductive, } + impl PathKind { /// Returns the path kind when merging `self` with `rest`. /// /// Given an inductive path `self` and a coinductive path `rest`, /// the path `self -> rest` would be coinductive. + /// + /// This operation represents an ordering and would be equivalent + /// to `max(self, rest)`. fn extend(self, rest: PathKind) -> PathKind { - match self { - PathKind::Coinductive => PathKind::Coinductive, - PathKind::Inductive => rest, + match (self, rest) { + (PathKind::Coinductive, _) | (_, PathKind::Coinductive) => PathKind::Coinductive, + (PathKind::Unknown, _) | (_, PathKind::Unknown) => PathKind::Unknown, + (PathKind::Inductive, PathKind::Inductive) => PathKind::Inductive, } } } @@ -159,9 +171,6 @@ impl UsageKind { } } } - fn and_merge(&mut self, other: impl Into) { - *self = self.merge(other); - } } /// For each goal we track whether the paths from this goal @@ -297,7 +306,7 @@ impl CycleHeads { let path_from_entry = match step_kind { PathKind::Coinductive => AllPathsToHeadCoinductive::Yes, - PathKind::Inductive => path_from_entry, + PathKind::Unknown | PathKind::Inductive => path_from_entry, }; self.insert(head, path_from_entry); @@ -305,6 +314,63 @@ impl CycleHeads { } } +bitflags::bitflags! { + /// Tracks how nested goals have been accessed. This is necessary to disable + /// global cache entries if computing them would otherwise result in a cycle or + /// access a provisional cache entry. + #[derive(Debug, Clone, Copy)] + pub struct PathsToNested: u8 { + /// The initial value when adding a goal to its own nested goals. + const EMPTY = 1 << 0; + const INDUCTIVE = 1 << 1; + const UNKNOWN = 1 << 2; + const COINDUCTIVE = 1 << 3; + } +} +impl From for PathsToNested { + fn from(path: PathKind) -> PathsToNested { + match path { + PathKind::Inductive => PathsToNested::INDUCTIVE, + PathKind::Unknown => PathsToNested::UNKNOWN, + PathKind::Coinductive => PathsToNested::COINDUCTIVE, + } + } +} +impl PathsToNested { + /// The implementation of this function is kind of ugly. We check whether + /// there currently exist 'weaker' paths in the set, if so we upgrade these + /// paths to at least `path`. + #[must_use] + fn extend_with(mut self, path: PathKind) -> Self { + match path { + PathKind::Inductive => { + if self.intersects(PathsToNested::EMPTY) { + self.remove(PathsToNested::EMPTY); + self.insert(PathsToNested::INDUCTIVE); + } + } + PathKind::Unknown => { + if self.intersects(PathsToNested::EMPTY | PathsToNested::INDUCTIVE) { + self.remove(PathsToNested::EMPTY | PathsToNested::INDUCTIVE); + self.insert(PathsToNested::UNKNOWN); + } + } + PathKind::Coinductive => { + if self.intersects( + PathsToNested::EMPTY | PathsToNested::INDUCTIVE | PathsToNested::UNKNOWN, + ) { + self.remove( + PathsToNested::EMPTY | PathsToNested::INDUCTIVE | PathsToNested::UNKNOWN, + ); + self.insert(PathsToNested::COINDUCTIVE); + } + } + } + + self + } +} + /// The nested goals of each stack entry and the path from the /// stack entry to that nested goal. /// @@ -322,15 +388,18 @@ impl CycleHeads { /// results from a the cycle BAB depending on the cycle root. #[derive_where(Debug, Default, Clone; X: Cx)] struct NestedGoals { - nested_goals: HashMap, + nested_goals: HashMap, } impl NestedGoals { fn is_empty(&self) -> bool { self.nested_goals.is_empty() } - fn insert(&mut self, input: X::Input, path_from_entry: UsageKind) { - self.nested_goals.entry(input).or_insert(path_from_entry).and_merge(path_from_entry); + fn insert(&mut self, input: X::Input, paths_to_nested: PathsToNested) { + match self.nested_goals.entry(input) { + Entry::Occupied(mut entry) => *entry.get_mut() |= paths_to_nested, + Entry::Vacant(entry) => drop(entry.insert(paths_to_nested)), + } } /// Adds the nested goals of a nested goal, given that the path `step_kind` from this goal @@ -341,18 +410,15 @@ impl NestedGoals { /// the same as for the child. fn extend_from_child(&mut self, step_kind: PathKind, nested_goals: &NestedGoals) { #[allow(rustc::potential_query_instability)] - for (input, path_from_entry) in nested_goals.iter() { - let path_from_entry = match step_kind { - PathKind::Coinductive => UsageKind::Single(PathKind::Coinductive), - PathKind::Inductive => path_from_entry, - }; - self.insert(input, path_from_entry); + for (input, paths_to_nested) in nested_goals.iter() { + let paths_to_nested = paths_to_nested.extend_with(step_kind); + self.insert(input, paths_to_nested); } } #[cfg_attr(feature = "nightly", rustc_lint_query_instability)] #[allow(rustc::potential_query_instability)] - fn iter(&self) -> impl Iterator { + fn iter(&self) -> impl Iterator + '_ { self.nested_goals.iter().map(|(i, p)| (*i, *p)) } @@ -490,7 +556,7 @@ impl, X: Cx> SearchGraph { // goals as this change may cause them to now depend on additional // goals, resulting in new cycles. See the dev-guide for examples. if parent_depends_on_cycle { - parent.nested_goals.insert(parent.input, UsageKind::Single(PathKind::Inductive)) + parent.nested_goals.insert(parent.input, PathsToNested::EMPTY); } } } @@ -666,7 +732,7 @@ impl, X: Cx> SearchGraph { // // We must therefore not use the global cache entry for `B` in that case. // See tests/ui/traits/next-solver/cycles/hidden-by-overflow.rs - last.nested_goals.insert(last.input, UsageKind::Single(PathKind::Inductive)); + last.nested_goals.insert(last.input, PathsToNested::EMPTY); } debug!("encountered stack overflow"); @@ -749,16 +815,11 @@ impl, X: Cx> SearchGraph { // We now care about the path from the next highest cycle head to the // provisional cache entry. - match path_from_head { - PathKind::Coinductive => {} - PathKind::Inductive => { - *path_from_head = Self::cycle_path_kind( - &self.stack, - stack_entry.step_kind_from_parent, - head, - ) - } - } + *path_from_head = path_from_head.extend(Self::cycle_path_kind( + &self.stack, + stack_entry.step_kind_from_parent, + head, + )); // Mutate the result of the provisional cache entry in case we did // not reach a fixpoint. *result = mutate_result(input, *result); @@ -858,7 +919,7 @@ impl, X: Cx> SearchGraph { for &ProvisionalCacheEntry { encountered_overflow, ref heads, - path_from_head, + path_from_head: head_to_provisional, result: _, } in entries.iter() { @@ -870,24 +931,19 @@ impl, X: Cx> SearchGraph { // A provisional cache entry only applies if the path from its highest head // matches the path when encountering the goal. + // + // We check if any of the paths taken while computing the global goal + // would end up with an applicable provisional cache entry. let head = heads.highest_cycle_head(); - let full_path = match Self::cycle_path_kind(stack, step_kind_from_parent, head) { - PathKind::Coinductive => UsageKind::Single(PathKind::Coinductive), - PathKind::Inductive => path_from_global_entry, - }; - - match (full_path, path_from_head) { - (UsageKind::Mixed, _) - | (UsageKind::Single(PathKind::Coinductive), PathKind::Coinductive) - | (UsageKind::Single(PathKind::Inductive), PathKind::Inductive) => { - debug!( - ?full_path, - ?path_from_head, - "cache entry not applicable due to matching paths" - ); - return false; - } - _ => debug!(?full_path, ?path_from_head, "paths don't match"), + let head_to_curr = Self::cycle_path_kind(stack, step_kind_from_parent, head); + let full_paths = path_from_global_entry.extend_with(head_to_curr); + if full_paths.contains(head_to_provisional.into()) { + debug!( + ?full_paths, + ?head_to_provisional, + "cache entry not applicable due to matching paths" + ); + return false; } } } @@ -986,8 +1042,8 @@ impl, X: Cx> SearchGraph { let last = &mut self.stack[last_index]; last.reached_depth = last.reached_depth.max(next_index); - last.nested_goals.insert(input, UsageKind::Single(step_kind_from_parent)); - last.nested_goals.insert(last.input, UsageKind::Single(PathKind::Inductive)); + last.nested_goals.insert(input, step_kind_from_parent.into()); + last.nested_goals.insert(last.input, PathsToNested::EMPTY); if last_index != head { last.heads.insert(head, step_kind_from_parent); } diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index b93668b5111b..8848640510c7 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -58,20 +58,24 @@ impl Goal { /// Why a specific goal has to be proven. /// /// This is necessary as we treat nested goals different depending on -/// their source. This is currently mostly used by proof tree visitors -/// but will be used by cycle handling in the future. +/// their source. This is used to decide whether a cycle is coinductive. +/// See the documentation of `EvalCtxt::step_kind_for_source` for more details +/// about this. +/// +/// It is also used by proof tree visitors, e.g. for diagnostics purposes. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub enum GoalSource { Misc, - /// We're proving a where-bound of an impl. + /// A nested goal required to prove that types are equal/subtypes. + /// This is always an unproductive step. /// - /// FIXME(-Znext-solver=coinductive): Explain how and why this - /// changes whether cycles are coinductive. + /// This is also used for all `NormalizesTo` goals as we they are used + /// to relate types in `AliasRelate`. + TypeRelating, + /// We're proving a where-bound of an impl. ImplWhereBound, /// Const conditions that need to hold for `~const` alias bounds to hold. - /// - /// FIXME(-Znext-solver=coinductive): Are these even coinductive? AliasBoundConstCondition, /// Instantiating a higher-ranked goal and re-proving it. InstantiateHigherRanked, @@ -79,7 +83,6 @@ pub enum GoalSource { /// This is used in two places: projecting to an opaque whose hidden type /// is already registered in the opaque type storage, and for rigid projections. AliasWellFormed, - /// In case normalizing aliases in nested goals cycles, eagerly normalizing these /// aliases in the context of the parent may incorrectly change the cycle kind. /// Normalizing aliases in goals therefore tracks the original path kind for this diff --git a/tests/ui/associated-type-bounds/hrtb.rs b/tests/ui/associated-type-bounds/hrtb.rs index 1bf574f2e651..8ff7faec3a0f 100644 --- a/tests/ui/associated-type-bounds/hrtb.rs +++ b/tests/ui/associated-type-bounds/hrtb.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) trait A<'a> {} trait B<'b> {} diff --git a/tests/ui/associated-type-bounds/supertrait-defines-ty.rs b/tests/ui/associated-type-bounds/supertrait-defines-ty.rs index ed1c1fa6f039..1c09ff3d3fb8 100644 --- a/tests/ui/associated-type-bounds/supertrait-defines-ty.rs +++ b/tests/ui/associated-type-bounds/supertrait-defines-ty.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) // Make sure that we don't look into associated type bounds when looking for // supertraits that define an associated type. Fixes #76593. diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr index 192b5eebdaac..4f1d339bc999 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr @@ -1,8 +1,8 @@ -error[E0275]: overflow evaluating the requirement `Loop == _` +error[E0271]: type mismatch resolving `Loop normalizes-to _` --> $DIR/inherent-impls-overflow.rs:10:6 | LL | impl Loop {} - | ^^^^ + | ^^^^ types differ error: type parameter `T` is only used recursively --> $DIR/inherent-impls-overflow.rs:14:24 @@ -36,4 +36,5 @@ LL | impl Poly0<()> {} error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0275`. +Some errors have detailed explanations: E0271, E0275. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs index 1397695a3fe4..0d5ec7d15307 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs @@ -9,7 +9,7 @@ type Loop = Loop; //[current]~ ERROR overflow normalizing the type alias `Loop` impl Loop {} //[current]~^ ERROR overflow normalizing the type alias `Loop` -//[next]~^^ ERROR overflow evaluating the requirement `Loop == _` +//[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _` type Poly0 = Poly1<(T,)>; //[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>` diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs index 3238f0283628..28fd66cd1694 100644 --- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs @@ -6,9 +6,11 @@ trait Overflow { type Assoc; } -impl Overflow for T { - type Assoc = ::Assoc; - //~^ ERROR: overflow +impl Overflow for T +where + (T,): Overflow +{ + type Assoc = <(T,) as Overflow>::Assoc; } diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr index 294fa0d7613c..34a45e936306 100644 --- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr @@ -1,19 +1,15 @@ -error[E0275]: overflow evaluating the requirement `::Assoc == _` - --> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18 - | -LL | type Assoc = ::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^ - error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/trait_ref_is_knowable-norm-overflow.rs:18:1 + --> $DIR/trait_ref_is_knowable-norm-overflow.rs:20:1 | LL | impl Trait for T {} | ------------------------- first implementation here LL | struct LocalTy; LL | impl Trait for ::Assoc {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + | + = note: overflow evaluating the requirement `_ == ::Assoc` + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`) -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0119, E0275. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/next-solver/cycles/cyclic-normalization-to-error-nalgebra.rs b/tests/ui/traits/next-solver/cycles/cyclic-normalization-to-error-nalgebra.rs new file mode 100644 index 000000000000..ec478aa02b77 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/cyclic-normalization-to-error-nalgebra.rs @@ -0,0 +1,21 @@ +// Regression test for trait-system-refactor-initiative#114. +// +// We previously treated the cycle when trying to use the +// `>::Output: DimMin` where-bound when +// normalizing `>::Output` as ambiguous, causing +// this to error. + +//@ check-pass +//@ compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver + +pub trait DimMin { + type Output; +} +pub fn repro, C>() +where + >::Output: DimMin>::Output>, +{ +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs index 0f01a453b332..94a9484ecdcf 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs @@ -13,12 +13,7 @@ fn needs_bar() {} fn test::Assoc2> + Foo2::Assoc1>>() { needs_bar::(); - //~^ ERROR overflow evaluating the requirement `::Assoc1 == _` - //~| ERROR overflow evaluating the requirement `::Assoc1 == _` - //~| ERROR overflow evaluating the requirement `::Assoc1 == _` - //~| ERROR overflow evaluating the requirement `::Assoc1 == _` - //~| ERROR overflow evaluating the requirement `::Assoc1: Sized` - //~| ERROR overflow evaluating the requirement `::Assoc1: Bar` + //~^ ERROR the trait bound `::Assoc1: Bar` is not satisfied } fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr index 2b0e57966fe7..6f5111a6193c 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr @@ -1,59 +1,19 @@ -error[E0275]: overflow evaluating the requirement `::Assoc1 == _` +error[E0277]: the trait bound `::Assoc1: Bar` is not satisfied --> $DIR/recursive-self-normalization-2.rs:15:17 | LL | needs_bar::(); - | ^^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `::Assoc1: Bar` - --> $DIR/recursive-self-normalization-2.rs:15:17 - | -LL | needs_bar::(); - | ^^^^^^^^^ + | ^^^^^^^^^ the trait `Bar` is not implemented for `::Assoc1` | note: required by a bound in `needs_bar` --> $DIR/recursive-self-normalization-2.rs:12:17 | LL | fn needs_bar() {} | ^^^ required by this bound in `needs_bar` +help: consider further restricting the associated type + | +LL | fn test::Assoc2> + Foo2::Assoc1>>() where ::Assoc1: Bar { + | ++++++++++++++++++++++++++++++ -error[E0275]: overflow evaluating the requirement `::Assoc1: Sized` - --> $DIR/recursive-self-normalization-2.rs:15:17 - | -LL | needs_bar::(); - | ^^^^^^^^^ - | -note: required by an implicit `Sized` bound in `needs_bar` - --> $DIR/recursive-self-normalization-2.rs:12:14 - | -LL | fn needs_bar() {} - | ^ required by the implicit `Sized` requirement on this type parameter in `needs_bar` -help: consider relaxing the implicit `Sized` restriction - | -LL | fn needs_bar() {} - | ++++++++ +error: aborting due to 1 previous error -error[E0275]: overflow evaluating the requirement `::Assoc1 == _` - --> $DIR/recursive-self-normalization-2.rs:15:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `::Assoc1 == _` - --> $DIR/recursive-self-normalization-2.rs:15:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0275]: overflow evaluating the requirement `::Assoc1 == _` - --> $DIR/recursive-self-normalization-2.rs:15:17 - | -LL | needs_bar::(); - | ^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs index f435b48737e2..f441ac499f99 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs @@ -9,12 +9,7 @@ fn needs_bar() {} fn test::Assoc>>() { needs_bar::(); - //~^ ERROR overflow evaluating the requirement `::Assoc == _` - //~| ERROR overflow evaluating the requirement `::Assoc == _` - //~| ERROR overflow evaluating the requirement `::Assoc == _` - //~| ERROR overflow evaluating the requirement `::Assoc == _` - //~| ERROR overflow evaluating the requirement `::Assoc: Sized` - //~| ERROR overflow evaluating the requirement `::Assoc: Bar` + //~^ ERROR the trait bound `::Assoc: Bar` is not satisfied } fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr index af8504dcaeee..c55182346874 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr @@ -1,59 +1,19 @@ -error[E0275]: overflow evaluating the requirement `::Assoc == _` +error[E0277]: the trait bound `::Assoc: Bar` is not satisfied --> $DIR/recursive-self-normalization.rs:11:17 | LL | needs_bar::(); - | ^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `::Assoc: Bar` - --> $DIR/recursive-self-normalization.rs:11:17 - | -LL | needs_bar::(); - | ^^^^^^^^ + | ^^^^^^^^ the trait `Bar` is not implemented for `::Assoc` | note: required by a bound in `needs_bar` --> $DIR/recursive-self-normalization.rs:8:17 | LL | fn needs_bar() {} | ^^^ required by this bound in `needs_bar` +help: consider further restricting the associated type + | +LL | fn test::Assoc>>() where ::Assoc: Bar { + | ++++++++++++++++++++++++++++ -error[E0275]: overflow evaluating the requirement `::Assoc: Sized` - --> $DIR/recursive-self-normalization.rs:11:17 - | -LL | needs_bar::(); - | ^^^^^^^^ - | -note: required by an implicit `Sized` bound in `needs_bar` - --> $DIR/recursive-self-normalization.rs:8:14 - | -LL | fn needs_bar() {} - | ^ required by the implicit `Sized` requirement on this type parameter in `needs_bar` -help: consider relaxing the implicit `Sized` restriction - | -LL | fn needs_bar() {} - | ++++++++ +error: aborting due to 1 previous error -error[E0275]: overflow evaluating the requirement `::Assoc == _` - --> $DIR/recursive-self-normalization.rs:11:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `::Assoc == _` - --> $DIR/recursive-self-normalization.rs:11:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0275]: overflow evaluating the requirement `::Assoc == _` - --> $DIR/recursive-self-normalization.rs:11:17 - | -LL | needs_bar::(); - | ^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. From 18809a2b123752d904a9487117665115b404a513 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 28 Feb 2025 13:11:25 +0100 Subject: [PATCH 671/991] keep inductive cycles as ambig in coherence --- .../src/solve/search_graph.rs | 20 ++++++++++++++++-- .../rustc_type_ir/src/search_graph/mod.rs | 5 ++++- .../cycles/unproductive-in-coherence.rs | 21 +++++++++++++++++++ .../cycles/unproductive-in-coherence.stderr | 11 ++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs create mode 100644 tests/ui/traits/next-solver/cycles/unproductive-in-coherence.stderr diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index aa1206cd6b73..eba496fa2265 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -1,9 +1,9 @@ use std::convert::Infallible; use std::marker::PhantomData; -use rustc_type_ir::Interner; use rustc_type_ir::search_graph::{self, PathKind}; use rustc_type_ir::solve::{CanonicalInput, Certainty, NoSolution, QueryResult}; +use rustc_type_ir::{Interner, TypingMode}; use super::inspect::ProofTreeBuilder; use super::{FIXPOINT_STEP_LIMIT, has_no_inference_or_external_constraints}; @@ -48,7 +48,23 @@ where match kind { PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes), PathKind::Unknown => response_no_constraints(cx, input, Certainty::overflow(false)), - PathKind::Inductive => Err(NoSolution), + // Even though we know these cycles to be unproductive, we still return + // overflow during coherence. This is both as we are not 100% confident in + // the implementation yet and any incorrect errors would be unsound there. + // The affected cases are also fairly artificial and not necessarily desirable + // so keeping this as ambiguity is fine for now. + // + // See `tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs` for an + // example where this would matter. We likely should change these cycles to `NoSolution` + // even in coherence once this is a bit more settled. + PathKind::Inductive => match input.typing_mode { + TypingMode::Coherence => { + response_no_constraints(cx, input, Certainty::overflow(false)) + } + TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => Err(NoSolution), + }, } } diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 1950fab35be3..9ae839280577 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -115,7 +115,10 @@ pub trait Delegate { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub enum PathKind { - /// A path consisting of only inductive/unproductive steps. + /// A path consisting of only inductive/unproductive steps. Their initial + /// provisional result is `Err(NoSolution)`. We currently treat them as + /// `PathKind::Unknown` during coherence until we're fully confident in + /// our approach. Inductive, /// A path which is not be coinductive right now but we may want /// to change of them to be so in the future. We return an ambiguous diff --git a/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs b/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs new file mode 100644 index 000000000000..46dd6adf6622 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs @@ -0,0 +1,21 @@ +// If we treat known inductive cycles as errors, this test compiles +// as normalizing `Overflow::Assoc` fails. +// +// As coherence already uses the new solver on stable, this change +// would require an FCP. + +trait Trait { + type Assoc; +} + +struct Overflow; +impl Trait for Overflow { + type Assoc = ::Assoc; +} + +trait Overlap {} +impl Overlap, U> for T {} +impl Overlap for Overflow {} +//~^ ERROR conflicting implementations of trait `Overlap<::Assoc, _>` for type `Overflow` + +fn main() {} diff --git a/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.stderr b/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.stderr new file mode 100644 index 000000000000..6605a28d5477 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.stderr @@ -0,0 +1,11 @@ +error[E0119]: conflicting implementations of trait `Overlap<::Assoc, _>` for type `Overflow` + --> $DIR/unproductive-in-coherence.rs:18:1 + | +LL | impl Overlap, U> for T {} + | ----------------------------------------------------- first implementation here +LL | impl Overlap for Overflow {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Overflow` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. From 5421fba7469f0669dc61a822deaf34c9b404816a Mon Sep 17 00:00:00 2001 From: Tongjun Gao Date: Wed, 5 Mar 2025 17:26:30 +0800 Subject: [PATCH 672/991] add test cases for 'letm' keyword completion --- .../crates/ide-completion/src/tests/expression.rs | 14 ++++++++++++++ .../crates/ide-completion/src/tests/item.rs | 1 + .../crates/ide-completion/src/tests/special.rs | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs index 375575128377..e91c399f0bb0 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs @@ -170,6 +170,7 @@ impl Unit { kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -247,6 +248,7 @@ fn complete_in_block() { kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -297,6 +299,7 @@ fn complete_after_if_expr() { kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -370,6 +373,7 @@ fn completes_in_loop_ctx() { kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -942,6 +946,7 @@ fn foo() { if foo {} $0 } kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -983,6 +988,7 @@ fn foo() { if foo {} el$0 } kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1072,6 +1078,7 @@ fn foo() { if foo {} $0 let x = 92; } kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1113,6 +1120,7 @@ fn foo() { if foo {} el$0 let x = 92; } kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1154,6 +1162,7 @@ fn foo() { if foo {} el$0 { let x = 92; } } kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1205,6 +1214,7 @@ pub struct UnstableThisShouldNotBeListed; kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1258,6 +1268,7 @@ pub struct UnstableButWeAreOnNightlyAnyway; kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1495,6 +1506,7 @@ fn main() { kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1944,6 +1956,7 @@ fn bar() { kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -2015,6 +2028,7 @@ fn foo() { kw if let kw impl kw let + kw letm kw loop kw match kw mod diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/item.rs index bea6d60769cc..be2c37d10162 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/item.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/item.rs @@ -285,6 +285,7 @@ fn bar() { kw if let kw impl kw let + kw letm kw loop kw match kw mod diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs index 2b05184bdbeb..005263d100a5 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs @@ -1009,6 +1009,7 @@ fn here_we_go() { kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1059,6 +1060,7 @@ fn here_we_go() { kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1182,6 +1184,7 @@ fn bar() { qu$0 } kw if let kw impl kw let + kw letm kw loop kw match kw mod @@ -1437,6 +1440,7 @@ fn foo() { kw if let kw impl kw let + kw letm kw loop kw match kw mod From 8edf528eb458631041b75eb1a6de709ba1f509ec Mon Sep 17 00:00:00 2001 From: klensy Date: Sun, 2 Mar 2025 12:58:07 +0300 Subject: [PATCH 673/991] tidy: add check to verify paths in triagebot.toml --- Cargo.lock | 1 + src/tools/tidy/Cargo.toml | 1 + src/tools/tidy/src/lib.rs | 1 + src/tools/tidy/src/main.rs | 2 + src/tools/tidy/src/triagebot.rs | 93 +++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 src/tools/tidy/src/triagebot.rs diff --git a/Cargo.lock b/Cargo.lock index 72f2d4f6cd39..3d49eb4e5f98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5260,6 +5260,7 @@ dependencies = [ "serde", "similar", "termcolor", + "toml 0.7.8", "walkdir", ] diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 9a4d0891b4ae..dfdbc0878f26 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -17,6 +17,7 @@ termcolor = "1.1.3" rustc-hash = "2.0.0" fluent-syntax = "0.11.1" similar = "2.5.0" +toml = "0.7.8" [features] build-metrics = ["dep:serde"] diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 1e7eb82b83e9..0b88b668cc13 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -88,6 +88,7 @@ pub mod target_policy; pub mod target_specific_tests; pub mod tests_placement; pub mod tests_revision_unpaired_stdout_stderr; +pub mod triagebot; pub mod ui_tests; pub mod unit_tests; pub mod unknown_revision; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 13a558fea48e..7bfce2858851 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -146,6 +146,8 @@ fn main() { check!(x_version, &root_path, &cargo); + check!(triagebot, &root_path); + let collected = { drain_handles(&mut handles); diff --git a/src/tools/tidy/src/triagebot.rs b/src/tools/tidy/src/triagebot.rs new file mode 100644 index 000000000000..7131c16ec302 --- /dev/null +++ b/src/tools/tidy/src/triagebot.rs @@ -0,0 +1,93 @@ +//! Tidy check to ensure paths mentioned in triagebot.toml exist in the project. + +use std::path::Path; + +use toml::Value; + +pub fn check(path: &Path, bad: &mut bool) { + let triagebot_path = path.join("triagebot.toml"); + if !triagebot_path.exists() { + tidy_error!(bad, "triagebot.toml file not found"); + return; + } + + let contents = std::fs::read_to_string(&triagebot_path).unwrap(); + let config: Value = toml::from_str(&contents).unwrap(); + + // Check [mentions."*"] sections, i.e. [mentions."compiler/rustc_const_eval/src/"] + if let Some(Value::Table(mentions)) = config.get("mentions") { + for path_str in mentions.keys() { + // Remove quotes from the path + let clean_path = path_str.trim_matches('"'); + let full_path = path.join(clean_path); + + if !full_path.exists() { + tidy_error!( + bad, + "triagebot.toml [mentions.*] contains path '{}' which doesn't exist", + clean_path + ); + } + } + } else { + tidy_error!( + bad, + "triagebot.toml missing [mentions.*] section, this wrong for rust-lang/rust repo." + ); + } + + // Check [assign.owners] sections, i.e. + // [assign.owners] + // "/.github/workflows" = ["infra-ci"] + if let Some(Value::Table(assign)) = config.get("assign") { + if let Some(Value::Table(owners)) = assign.get("owners") { + for path_str in owners.keys() { + // Remove quotes and leading slash from the path + let clean_path = path_str.trim_matches('"').trim_start_matches('/'); + let full_path = path.join(clean_path); + + if !full_path.exists() { + tidy_error!( + bad, + "triagebot.toml [assign.owners] contains path '{}' which doesn't exist", + clean_path + ); + } + } + } else { + tidy_error!( + bad, + "triagebot.toml missing [assign.owners] section, this wrong for rust-lang/rust repo." + ); + } + } + + // Verify that trigger_files in [autolabel."*"] exist in the project, i.e. + // [autolabel."A-rustdoc-search"] + // trigger_files = [ + // "src/librustdoc/html/static/js/search.js", + // "tests/rustdoc-js", + // "tests/rustdoc-js-std", + // ] + if let Some(Value::Table(autolabels)) = config.get("autolabel") { + for (label, content) in autolabels { + if let Some(trigger_files) = content.get("trigger_files").and_then(|v| v.as_array()) { + for file in trigger_files { + if let Some(file_str) = file.as_str() { + let full_path = path.join(file_str); + + // Handle both file and directory paths + if !full_path.exists() { + tidy_error!( + bad, + "triagebot.toml [autolabel.{}] contains trigger_files path '{}' which doesn't exist", + label, + file_str + ); + } + } + } + } + } + } +} From aa72de9330d7803374d4200833c39ec5daea1012 Mon Sep 17 00:00:00 2001 From: klensy Date: Sun, 2 Mar 2025 13:05:19 +0300 Subject: [PATCH 674/991] fix triagebot.toml --- triagebot.toml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index ed352984fb12..f136bfb7211c 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -252,7 +252,6 @@ trigger_files = [ "compiler/rustc_passes/src/check_attr.rs", "compiler/rustc_attr_parsing", "compiler/rustc_attr_data_structures", - "compiler/rustc_attr_validation", ] [autolabel."T-rustdoc-frontend"] @@ -316,7 +315,6 @@ trigger_files = [ "library/panic_unwind", "library/std", "library/stdarch", - "library/term", "library/test", ] exclude_labels = [ @@ -331,7 +329,7 @@ trigger_files = [ [autolabel."O-apple"] trigger_files = [ "library/std/src/os/darwin", - "library/std/src/sys/pal/unix/thread_parking/darwin.rs", + "library/std/src/sys/sync/thread_parking/darwin.rs", "compiler/rustc_target/src/spec/base/apple", ] @@ -408,7 +406,8 @@ trigger_files = [ [autolabel."O-wasm"] trigger_files = [ "library/std/src/sys/pal/wasm", - "library/std/src/os/wasm" + "library/std/src/os/wasi", + "library/std/src/os/wasip2" ] [autolabel."O-windows"] @@ -499,7 +498,6 @@ trigger_files = [ "CONTRIBUTING.md", "INSTALL.md", "REUSE.toml", - ".reuse", ".mailmap", ".git-blame-ignore-revs", ".editorconfig" @@ -524,7 +522,6 @@ exclude_labels = [ [autolabel."WG-trait-system-refactor"] trigger_files = [ - "compiler/rustc_middle/src/traits/solve", "compiler/rustc_next_trait_solver", "compiler/rustc_trait_selection/src/solve", "compiler/rustc_type_ir/src/solve", @@ -791,7 +788,7 @@ cc = ["@Nadrieril"] message = "Some changes occurred in cfg and check-cfg configuration" cc = ["@Urgau"] -[mentions."compiler/rustc_lint/src/context/diagnostics/check_cfg.rs"] +[mentions."compiler/rustc_lint/src/early/diagnostics/check_cfg.rs"] message = "Some changes occurred in check-cfg diagnostics" cc = ["@Urgau"] @@ -963,7 +960,7 @@ If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/util [mentions."src/bootstrap/src/core/build_steps/llvm.rs"] message = "This PR changes how LLVM is built. Consider updating src/bootstrap/download-ci-llvm-stamp." -[mentions."test/crashes"] +[mentions."tests/crashes"] message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the corresponding `ui` subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge." [mentions."tests/rustdoc-json"] @@ -1077,8 +1074,6 @@ cc = ["@jdonszelmann"] cc = ["@jdonszelmann"] [mentions."compiler/rustc_attr_data_structures"] cc = ["@jdonszelmann"] -[mentions."compiler/rustc_attr_validation"] -cc = ["@jdonszelmann"] [assign] warn_non_default_branch.enable = true @@ -1263,7 +1258,6 @@ project-exploit-mitigations = [ "/compiler/rustc_middle/src/traits" = ["compiler", "types"] "/compiler/rustc_middle/src/ty" = ["compiler", "types"] "/compiler/rustc_const_eval/src/interpret" = ["compiler", "mir"] -"/compiler/rustc_const_eval/src/transform" = ["compiler", "mir-opt"] "/compiler/rustc_mir_build/src/builder" = ["compiler", "mir"] "/compiler/rustc_mir_transform" = ["compiler", "mir", "mir-opt"] "/compiler/rustc_smir" = ["project-stable-mir"] From 049f4dbd2b990f46772d07f07d54c7ea6ccca7fd Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 5 Mar 2025 10:40:11 +0100 Subject: [PATCH 675/991] Add warning and debug information when `cargo metadata` fails The errors are silently dropped elsewhere, which make it really hard to debug issues due to dependency download failures. --- .../crates/project-model/src/cargo_workspace.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 40ab8c53faeb..e7c3bcb5418d 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -288,7 +288,22 @@ impl CargoWorkspace { locked: bool, progress: &dyn Fn(String), ) -> anyhow::Result<(cargo_metadata::Metadata, Option)> { - Self::fetch_metadata_(cargo_toml, current_dir, config, sysroot, locked, false, progress) + let res = Self::fetch_metadata_( + cargo_toml, + current_dir, + config, + sysroot, + locked, + false, + progress, + ); + if let Ok((_, Some(ref e))) = res { + tracing::warn!( + "`cargo metadata` failed on `{cargo_toml}`, but retry with `--no-deps` succeeded" + ); + tracing::debug!("{e:?}"); + } + res } fn fetch_metadata_( From b885407c0ce3cfdc7bc91c108b41e2026b51de5a Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 5 Mar 2025 09:26:04 +0300 Subject: [PATCH 676/991] add new field `forced_compiler` to `Compiler` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/dist.rs | 3 +- src/bootstrap/src/core/builder/mod.rs | 9 +- src/bootstrap/src/core/builder/tests.rs | 128 ++++++++++----------- src/bootstrap/src/lib.rs | 32 +++++- 4 files changed, 97 insertions(+), 75 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 26b3e0b701c4..692ff31c5c79 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2112,8 +2112,7 @@ pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, ), )] pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) { - let dst_libdir = - sysroot.join(builder.sysroot_libdir_relative(Compiler { stage: 1, host: target })); + let dst_libdir = sysroot.join(builder.sysroot_libdir_relative(Compiler::new(1, target))); // We do not need to copy LLVM files into the sysroot if it is not // dynamically linked; it is already included into librustc_llvm // statically. diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index c8e2856bdc87..819c58d98198 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1234,7 +1234,7 @@ impl<'a> Builder<'a> { ), )] pub fn compiler(&self, stage: u32, host: TargetSelection) -> Compiler { - self.ensure(compile::Assemble { target_compiler: Compiler { stage, host } }) + self.ensure(compile::Assemble { target_compiler: Compiler::new(stage, host) }) } /// Similar to `compiler`, except handles the full-bootstrap option to @@ -1272,7 +1272,7 @@ impl<'a> Builder<'a> { target: TargetSelection, ) -> Compiler { #![allow(clippy::let_and_return)] - let resolved_compiler = if self.build.force_use_stage2(stage) { + let mut resolved_compiler = if self.build.force_use_stage2(stage) { trace!(target: "COMPILER_FOR", ?stage, "force_use_stage2"); self.compiler(2, self.config.build) } else if self.build.force_use_stage1(stage, target) { @@ -1282,6 +1282,11 @@ impl<'a> Builder<'a> { trace!(target: "COMPILER_FOR", ?stage, ?host, "no force, fallback to `compiler()`"); self.compiler(stage, host) }; + + if stage != resolved_compiler.stage { + resolved_compiler.forced_compiler(true); + } + trace!(target: "COMPILER_FOR", ?resolved_compiler); resolved_compiler } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 1f27002f81ca..6e050bffc479 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -71,7 +71,7 @@ fn check_cli(paths: [&str; N]) { macro_rules! std { ($host:ident => $target:ident, stage = $stage:literal) => { compile::Std::new( - Compiler { host: TargetSelection::from_user($host), stage: $stage }, + Compiler::new($stage, TargetSelection::from_user($host)), TargetSelection::from_user($target), ) }; @@ -84,7 +84,7 @@ macro_rules! doc_std { macro_rules! rustc { ($host:ident => $target:ident, stage = $stage:literal) => { compile::Rustc::new( - Compiler { host: TargetSelection::from_user($host), stage: $stage }, + Compiler::new($stage, TargetSelection::from_user($host)), TargetSelection::from_user($target), ) }; @@ -296,7 +296,7 @@ mod defaults { first(cache.all::()), // Recall that rustdoc stages are off-by-one // - this is the compiler it's _linked_ to, not built with. - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }], + &[tool::Rustdoc { compiler: Compiler::new(1, a) }], ); assert_eq!( first(cache.all::()), @@ -319,7 +319,7 @@ mod defaults { first(cache.all::()), // This is the beta rustdoc. // Add an assert here to make sure this is the only rustdoc built. - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } }], + &[tool::Rustdoc { compiler: Compiler::new(0, a) }], ); assert!(cache.all::().is_empty()); } @@ -352,16 +352,16 @@ mod defaults { assert_eq!( first(cache.all::()), &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: b, stage: 1 } }, + compile::Assemble { target_compiler: Compiler::new(0, a) }, + compile::Assemble { target_compiler: Compiler::new(1, a) }, + compile::Assemble { target_compiler: Compiler::new(1, b) }, ] ); assert_eq!( first(cache.all::()), &[ - tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }, - tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } }, + tool::Rustdoc { compiler: Compiler::new(1, a) }, + tool::Rustdoc { compiler: Compiler::new(1, b) }, ], ); assert_eq!( @@ -386,14 +386,14 @@ mod defaults { assert_eq!(first(cache.all::()), &[doc::ErrorIndex { target: a },]); assert_eq!( first(cache.all::()), - &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 0 } }] + &[tool::ErrorIndex { compiler: Compiler::new(0, a) }] ); // docs should be built with the beta compiler, not with the stage0 artifacts. // recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to, // not the one it was built by. assert_eq!( first(cache.all::()), - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },] + &[tool::Rustdoc { compiler: Compiler::new(0, a) },] ); } } @@ -418,17 +418,17 @@ mod dist { assert_eq!(first(cache.all::()), &[dist::Mingw { host: a },]); assert_eq!( first(cache.all::()), - &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] + &[dist::Rustc { compiler: Compiler::new(2, a) },] ); assert_eq!( first(cache.all::()), - &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },] + &[dist::Std { compiler: Compiler::new(1, a), target: a },] ); assert_eq!(first(cache.all::()), &[dist::Src]); // Make sure rustdoc is only built once. assert_eq!( first(cache.all::()), - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] + &[tool::Rustdoc { compiler: Compiler::new(2, a) },] ); } @@ -450,13 +450,13 @@ mod dist { ); assert_eq!( first(cache.all::()), - &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] + &[dist::Rustc { compiler: Compiler::new(2, a) },] ); assert_eq!( first(cache.all::()), &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + dist::Std { compiler: Compiler::new(1, a), target: a }, + dist::Std { compiler: Compiler::new(2, a), target: b }, ] ); assert_eq!(first(cache.all::()), &[dist::Src]); @@ -483,15 +483,15 @@ mod dist { assert_eq!( first(cache.all::()), &[ - dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, - dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, + dist::Rustc { compiler: Compiler::new(2, a) }, + dist::Rustc { compiler: Compiler::new(2, b) }, ] ); assert_eq!( first(cache.all::()), &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + dist::Std { compiler: Compiler::new(1, a), target: a }, + dist::Std { compiler: Compiler::new(1, a), target: b }, ] ); assert_eq!( @@ -519,7 +519,7 @@ mod dist { assert_eq!( first(cache.all::()), - &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },] + &[dist::Rustc { compiler: Compiler::new(2, b) },] ); assert_eq!( first(cache.all::()), @@ -556,16 +556,16 @@ mod dist { assert_eq!( first(cache.all::()), &[ - dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, - dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, + dist::Rustc { compiler: Compiler::new(2, a) }, + dist::Rustc { compiler: Compiler::new(2, b) }, ] ); assert_eq!( first(cache.all::()), &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + dist::Std { compiler: Compiler::new(1, a), target: a }, + dist::Std { compiler: Compiler::new(1, a), target: b }, + dist::Std { compiler: Compiler::new(2, a), target: c }, ] ); assert_eq!(first(cache.all::()), &[dist::Src]); @@ -583,7 +583,7 @@ mod dist { assert_eq!(first(cache.all::()), &[dist::Mingw { host: c },]); assert_eq!( first(cache.all::()), - &[dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },] + &[dist::Std { compiler: Compiler::new(2, a), target: c },] ); } @@ -608,15 +608,15 @@ mod dist { assert_eq!( first(cache.all::()), &[ - dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, - dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, + dist::Rustc { compiler: Compiler::new(2, a) }, + dist::Rustc { compiler: Compiler::new(2, b) }, ] ); assert_eq!( first(cache.all::()), &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + dist::Std { compiler: Compiler::new(1, a), target: a }, + dist::Std { compiler: Compiler::new(1, a), target: b }, ] ); assert_eq!(first(cache.all::()), &[dist::Src]); @@ -633,10 +633,10 @@ mod dist { assert_eq!( first(cache.all::()), &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, - compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, + compile::Assemble { target_compiler: Compiler::new(0, a) }, + compile::Assemble { target_compiler: Compiler::new(1, a) }, + compile::Assemble { target_compiler: Compiler::new(2, a) }, + compile::Assemble { target_compiler: Compiler::new(2, b) }, ] ); } @@ -683,28 +683,16 @@ mod dist { first(builder.cache.all::()), &[ compile::Assemble { - target_compiler: Compiler { - host: TargetSelection::from_user(TEST_TRIPLE_1), - stage: 0 - } + target_compiler: Compiler::new(0, TargetSelection::from_user(TEST_TRIPLE_1),) }, compile::Assemble { - target_compiler: Compiler { - host: TargetSelection::from_user(TEST_TRIPLE_1), - stage: 1 - } + target_compiler: Compiler::new(1, TargetSelection::from_user(TEST_TRIPLE_1),) }, compile::Assemble { - target_compiler: Compiler { - host: TargetSelection::from_user(TEST_TRIPLE_1), - stage: 2 - } + target_compiler: Compiler::new(2, TargetSelection::from_user(TEST_TRIPLE_1),) }, compile::Assemble { - target_compiler: Compiler { - host: TargetSelection::from_user(TEST_TRIPLE_2), - stage: 2 - } + target_compiler: Compiler::new(2, TargetSelection::from_user(TEST_TRIPLE_2),) }, ] ); @@ -747,9 +735,9 @@ mod dist { assert_eq!( first(builder.cache.all::()), &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, + compile::Assemble { target_compiler: Compiler::new(0, a) }, + compile::Assemble { target_compiler: Compiler::new(1, a) }, + compile::Assemble { target_compiler: Compiler::new(2, a) }, ] ); assert_eq!( @@ -798,7 +786,7 @@ mod dist { assert_eq!( first(builder.cache.all::()), &[test::Crate { - compiler: Compiler { host, stage: 0 }, + compiler: Compiler::new(0, host), target: host, mode: crate::Mode::Std, crates: vec!["std".to_owned()], @@ -824,13 +812,13 @@ mod dist { ); assert_eq!( first(builder.cache.all::()), - &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] + &[tool::ErrorIndex { compiler: Compiler::new(1, a) }] ); // This is actually stage 1, but Rustdoc::run swaps out the compiler with // stage minus 1 if --stage is not 0. Very confusing! assert_eq!( first(builder.cache.all::()), - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] + &[tool::Rustdoc { compiler: Compiler::new(2, a) },] ); } @@ -870,7 +858,7 @@ mod dist { ); assert_eq!( first(builder.cache.all::()), - &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] + &[tool::ErrorIndex { compiler: Compiler::new(1, a) }] ); // Unfortunately rustdoc is built twice. Once from stage1 for compiletest // (and other things), and once from stage0 for std crates. Ideally it @@ -886,9 +874,9 @@ mod dist { assert_eq!( first(builder.cache.all::()), &[ - tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } }, - tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }, - tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } }, + tool::Rustdoc { compiler: Compiler::new(0, a) }, + tool::Rustdoc { compiler: Compiler::new(1, a) }, + tool::Rustdoc { compiler: Compiler::new(2, a) }, ] ); } @@ -904,7 +892,7 @@ mod sysroot_target_dirs { let build = Build::new(configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); let builder = Builder::new(&build); let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1); - let compiler = Compiler { stage: 1, host: target_triple_1 }; + let compiler = Compiler::new(1, target_triple_1); let target_triple_2 = TargetSelection::from_user(TEST_TRIPLE_2); let actual = builder.sysroot_target_libdir(compiler, target_triple_2); @@ -924,7 +912,7 @@ mod sysroot_target_dirs { let build = Build::new(configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); let builder = Builder::new(&build); let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1); - let compiler = Compiler { stage: 1, host: target_triple_1 }; + let compiler = Compiler::new(1, target_triple_1); let target_triple_2 = TargetSelection::from_user(TEST_TRIPLE_2); let actual = builder.sysroot_target_bindir(compiler, target_triple_2); @@ -1128,13 +1116,13 @@ fn test_get_tool_rustc_compiler() { let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1); - let compiler = Compiler { stage: 2, host: target_triple_1 }; - let expected = Compiler { stage: 1, host: target_triple_1 }; + let compiler = Compiler::new(2, target_triple_1); + let expected = Compiler::new(1, target_triple_1); let actual = tool::get_tool_rustc_compiler(&builder, compiler); assert_eq!(expected, actual); - let compiler = Compiler { stage: 1, host: target_triple_1 }; - let expected = Compiler { stage: 0, host: target_triple_1 }; + let compiler = Compiler::new(1, target_triple_1); + let expected = Compiler::new(0, target_triple_1); let actual = tool::get_tool_rustc_compiler(&builder, compiler); assert_eq!(expected, actual); @@ -1143,8 +1131,8 @@ fn test_get_tool_rustc_compiler() { let build = Build::new(config); let builder = Builder::new(&build); - let compiler = Compiler { stage: 1, host: target_triple_1 }; - let expected = Compiler { stage: 1, host: target_triple_1 }; + let compiler = Compiler::new(1, target_triple_1); + let expected = Compiler::new(1, target_triple_1); let actual = tool::get_tool_rustc_compiler(&builder, compiler); assert_eq!(expected, actual); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 351e67f6702d..b09ed3a3c7e9 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -92,10 +92,27 @@ const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ /// Each compiler has a `stage` that it is associated with and a `host` that /// corresponds to the platform the compiler runs on. This structure is used as /// a parameter to many methods below. -#[derive(Eq, PartialOrd, Ord, PartialEq, Clone, Copy, Hash, Debug)] +#[derive(Eq, PartialOrd, Ord, Clone, Copy, Debug)] pub struct Compiler { stage: u32, host: TargetSelection, + /// Indicates whether `compiler_for` was used to force a specific compiler stage. + /// This field is ignored in `Hash` and `PartialEq` implementations as only the `stage` + /// and `host` fields are relevant for those. + forced_compiler: bool, +} + +impl std::hash::Hash for Compiler { + fn hash(&self, state: &mut H) { + self.stage.hash(state); + self.host.hash(state); + } +} + +impl PartialEq for Compiler { + fn eq(&self, other: &Self) -> bool { + self.stage == other.stage && self.host == other.host + } } #[derive(PartialEq, Eq, Copy, Clone, Debug)] @@ -1964,6 +1981,14 @@ fn chmod(path: &Path, perms: u32) { fn chmod(_path: &Path, _perms: u32) {} impl Compiler { + pub fn new(stage: u32, host: TargetSelection) -> Self { + Self { stage, host, forced_compiler: false } + } + + pub fn forced_compiler(&mut self, forced_compiler: bool) { + self.forced_compiler = forced_compiler; + } + pub fn with_stage(mut self, stage: u32) -> Compiler { self.stage = stage; self @@ -1973,6 +1998,11 @@ impl Compiler { pub fn is_snapshot(&self, build: &Build) -> bool { self.stage == 0 && self.host == build.build } + + /// Indicates whether `compiler_for` was used to force a specific compiler stage. + pub fn is_forced_compiler(&self) -> bool { + self.forced_compiler + } } fn envify(s: &str) -> String { From 9e4b3d6bc4dc9c3d5bbf65511212791fa32666ac Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 5 Mar 2025 09:26:25 +0300 Subject: [PATCH 677/991] handle forced compiler in `get_tool_rustc_compiler` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/tool.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 39acb646dff4..e86bf02e9c3d 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -299,6 +299,8 @@ pub(crate) fn get_tool_rustc_compiler( if builder.download_rustc() && target_compiler.stage == 1 { // We already have the stage 1 compiler, we don't need to cut the stage. builder.compiler(target_compiler.stage, builder.config.build) + } else if target_compiler.is_forced_compiler() { + target_compiler } else { // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise // we'd have stageN/bin/rustc and stageN/bin/$rustc_tool be effectively different stage From 0acc0c874b0400636c36248b6057f01eaa7ca3cd Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 5 Mar 2025 09:26:58 +0300 Subject: [PATCH 678/991] Revert "avoid `compiler_for` for dist tools and force the current compiler" This reverts commit 50f84129e66de867a735ee836339e8ed9dd7425e. --- src/bootstrap/src/core/build_steps/dist.rs | 56 ++++++++++++++++++---- src/bootstrap/src/core/builder/tests.rs | 2 +- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 692ff31c5c79..735cae7b47b0 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -421,7 +421,11 @@ impl Step for Rustc { if let Some(ra_proc_macro_srv) = builder.ensure_if_default( tool::RustAnalyzerProcMacroSrv { - compiler: builder.compiler(compiler.stage, builder.config.build), + compiler: builder.compiler_for( + compiler.stage, + builder.config.build, + compiler.host, + ), target: compiler.host, }, builder.kind, @@ -771,7 +775,11 @@ impl Step for Analysis { // Find the actual compiler (handling the full bootstrap option) which // produced the save-analysis data because that data isn't copied // through the sysroot uplifting. - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), target: run.target, }); } @@ -1116,7 +1124,11 @@ impl Step for Cargo { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Cargo { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), target: run.target, }); } @@ -1161,7 +1173,11 @@ impl Step for Rls { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Rls { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), target: run.target, }); } @@ -1199,7 +1215,11 @@ impl Step for RustAnalyzer { fn make_run(run: RunConfig<'_>) { run.builder.ensure(RustAnalyzer { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), target: run.target, }); } @@ -1237,7 +1257,11 @@ impl Step for Clippy { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Clippy { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), target: run.target, }); } @@ -1280,7 +1304,11 @@ impl Step for Miri { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Miri { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), target: run.target, }); } @@ -1414,7 +1442,11 @@ impl Step for Rustfmt { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Rustfmt { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), target: run.target, }); } @@ -1464,7 +1496,7 @@ impl Step for Extended { fn run(self, builder: &Builder<'_>) { let target = self.target; let stage = self.stage; - let compiler = builder.compiler(self.stage, self.host); + let compiler = builder.compiler_for(self.stage, self.host, self.target); builder.info(&format!("Dist extended stage{} ({})", compiler.stage, target)); @@ -2227,7 +2259,11 @@ impl Step for LlvmBitcodeLinker { fn make_run(run: RunConfig<'_>) { run.builder.ensure(LlvmBitcodeLinker { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), target: run.target, }); } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 6e050bffc479..ec926daa9228 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -525,7 +525,7 @@ mod dist { first(cache.all::()), &[ rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), - rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0), rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), ] ); From 36efaf8437fd3926868293c87fa6cffc6f309bb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 5 Mar 2025 10:54:11 +0100 Subject: [PATCH 679/991] normalize away `-Wlinker-messages` wrappers from `rust-lld` rmake test --- tests/run-make/rust-lld/rmake.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index e5ae94353884..35f716c24c71 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -60,7 +60,8 @@ fn main() { } fn find_lld_version_in_logs(stderr: String) -> bool { - let lld_version_re = - Regex::new(r"^warning: linker std(out|err): LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + // Strip the `-Wlinker-messages` wrappers prefixing the linker output. + let stderr = Regex::new(r"warning: linker std(out|err):").unwrap().replace_all(&stderr, ""); + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } From 26e42de17c57e79a176da5782d6d92e6ae17a410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 13 Feb 2025 17:02:38 +0100 Subject: [PATCH 680/991] Make citool compilation faster --- .github/workflows/ci.yml | 6 +++--- src/ci/citool/Cargo.toml | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a91598586b9f..be4919ce1a3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,8 +58,8 @@ jobs: COMMIT_MESSAGE: ${{ github.event.head_commit.message }} run: | cd src/ci/citool - cargo test - cargo run calculate-job-matrix >> $GITHUB_OUTPUT + CARGO_INCREMENTAL=0 cargo test + CARGO_INCREMENTAL=0 cargo run calculate-job-matrix >> $GITHUB_OUTPUT id: jobs job: name: ${{ matrix.full_name }} @@ -187,7 +187,7 @@ jobs: - name: build citool run: | cd src/ci/citool - CARGO_TARGET_DIR=../../../build/citool cargo build + CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=../../../build/citool cargo build - name: run the build # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index 11172832cb81..3b3252683096 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -19,3 +19,7 @@ insta = "1" # If this is omitted, cargo will look for a workspace elsewhere. # We want to avoid this, since citool is independent of the other crates. [workspace] + +# Make compilation faster +[profile.dev] +debug = 0 From 6130b3da18530c0b735d9dd631df1ddb66319430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 13 Feb 2025 17:23:44 +0100 Subject: [PATCH 681/991] Upload Datadog average CPU usage metric in citool --- .github/workflows/ci.yml | 8 +- src/ci/citool/Cargo.lock | 680 ++++++++++++++++++++++++++++++++- src/ci/citool/Cargo.toml | 2 + src/ci/citool/src/cpu_usage.rs | 22 ++ src/ci/citool/src/datadog.rs | 43 +++ src/ci/citool/src/main.rs | 41 +- src/ci/citool/src/utils.rs | 12 + 7 files changed, 787 insertions(+), 21 deletions(-) create mode 100644 src/ci/citool/src/cpu_usage.rs create mode 100644 src/ci/citool/src/datadog.rs create mode 100644 src/ci/citool/src/utils.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be4919ce1a3f..f166e0c0b416 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -183,7 +183,7 @@ jobs: run: src/ci/scripts/dump-environment.sh # Pre-build citool before the following step uninstalls rustup - # Build is into the build directory, to avoid modifying sources + # Build it into the build directory, to avoid modifying sources - name: build citool run: | cd src/ci/citool @@ -238,13 +238,9 @@ jobs: - name: upload job metrics to DataDog if: needs.calculate_matrix.outputs.run_type != 'pr' env: - DATADOG_SITE: datadoghq.com DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }} DD_GITHUB_JOB_NAME: ${{ matrix.full_name }} - run: | - cd src/ci - npm ci - python3 scripts/upload-build-metrics.py ../../build/cpu-usage.csv + run: ./build/citool/debug/citool upload-build-metrics build/cpu-usage.csv # This job isused to tell bors the final status of the build, as there is no practical way to detect # when a workflow is successful listening to webhooks only in our current bors implementation (homu). diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index e5be2d42472b..46343a7b86e8 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "anstream" version = "0.6.18" @@ -38,7 +44,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -49,7 +55,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", "once_cell", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -58,6 +64,12 @@ version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "build_helper" version = "0.1.0" @@ -66,6 +78,27 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "bytes" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" + +[[package]] +name = "cc" +version = "1.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "citool" version = "0.1.0" @@ -73,10 +106,12 @@ dependencies = [ "anyhow", "build_helper", "clap", + "csv", "insta", "serde", "serde_json", "serde_yaml", + "ureq", ] [[package]] @@ -134,7 +169,95 @@ dependencies = [ "encode_unicode", "libc", "once_cell", - "windows-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" +dependencies = [ + "cookie", + "document-features", + "idna", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "csv" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" +dependencies = [ + "memchr", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", ] [[package]] @@ -149,6 +272,42 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "flate2" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "hashbrown" version = "0.15.2" @@ -161,6 +320,162 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "indexmap" version = "2.7.1" @@ -208,18 +523,57 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "litemap" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "log" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "once_cell" version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project" version = "1.1.9" @@ -240,6 +594,12 @@ dependencies = [ "syn", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro2" version = "1.0.93" @@ -258,6 +618,61 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "ring" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.23.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "ryu" version = "1.0.19" @@ -309,18 +724,42 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "similar" version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +[[package]] +name = "smallvec" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.98" @@ -332,6 +771,58 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb041120f25f8fbe8fd2dbe4671c7c2ed74d83be2e7a77529bf7e0790ae3f472" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef" + +[[package]] +name = "time-macros" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "unicode-ident" version = "1.0.16" @@ -344,12 +835,110 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "3.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06f78313c985f2fba11100dd06d60dd402d0cabb458af4d94791b8e09c025323" +dependencies = [ + "base64", + "cookie_store", + "flate2", + "log", + "percent-encoding", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "serde", + "serde_json", + "ureq-proto", + "utf-8", + "webpki-roots", +] + +[[package]] +name = "ureq-proto" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64adb55464bad1ab1aa9229133d0d59d2f679180f4d15f0d9debe616f541f25e" +dependencies = [ + "base64", + "http", + "httparse", + "log", +] + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "webpki-roots" +version = "0.26.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -422,3 +1011,88 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index 3b3252683096..c486f2977a1c 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -6,9 +6,11 @@ edition = "2021" [dependencies] anyhow = "1" clap = { version = "4.5", features = ["derive"] } +csv = "1" serde = { version = "1", features = ["derive"] } serde_yaml = "0.9" serde_json = "1" +ureq = { version = "3", features = ["json"] } build_helper = { path = "../../build_helper" } diff --git a/src/ci/citool/src/cpu_usage.rs b/src/ci/citool/src/cpu_usage.rs new file mode 100644 index 000000000000..4c9e37bf6db7 --- /dev/null +++ b/src/ci/citool/src/cpu_usage.rs @@ -0,0 +1,22 @@ +use std::path::Path; + +/// Loads CPU usage records from a CSV generated by the `src/ci/scripts/collect-cpu-stats.sh` +/// script. +pub fn load_cpu_usage(path: &Path) -> anyhow::Result> { + let reader = csv::ReaderBuilder::new().flexible(true).from_path(path)?; + + let mut entries = vec![]; + for row in reader.into_records() { + let row = row?; + let cols = row.into_iter().collect::>(); + + // The log might contain incomplete rows or some Python exception + if cols.len() == 2 { + if let Ok(idle) = cols[1].parse::() { + entries.push(100.0 - idle); + } + } + } + + Ok(entries) +} diff --git a/src/ci/citool/src/datadog.rs b/src/ci/citool/src/datadog.rs new file mode 100644 index 000000000000..837257420d6a --- /dev/null +++ b/src/ci/citool/src/datadog.rs @@ -0,0 +1,43 @@ +use anyhow::Context; + +use crate::utils::load_env_var; + +/// Uploads a custom CI pipeline metric to Datadog. +/// Expects to be executed from within the context of a GitHub Actions job. +pub fn upload_datadog_metric(name: &str, value: f64) -> anyhow::Result<()> { + let datadog_api_key = load_env_var("DATADOG_API_KEY")?; + let github_server_url = load_env_var("GITHUB_SERVER_URL")?; + let github_repository = load_env_var("GITHUB_REPOSITORY")?; + let github_run_id = load_env_var("GITHUB_RUN_ID")?; + let github_run_attempt = load_env_var("GITHUB_RUN_ATTEMPT")?; + let github_job = load_env_var("GITHUB_JOB")?; + let dd_github_job_name = load_env_var("DD_GITHUB_JOB_NAME")?; + + // This API endpoint is not documented in Datadog's API reference currently. + // It was reverse-engineered from the `datadog-ci measure` npm command. + ureq::post("https://api.datadoghq.com/api/v2/ci/pipeline/metrics") + .header("DD-API-KEY", datadog_api_key) + .send_json(serde_json::json!({ + "data": { + "attributes": { + "ci_env": { + "GITHUB_SERVER_URL": github_server_url, + "GITHUB_REPOSITORY": github_repository, + "GITHUB_RUN_ID": github_run_id, + "GITHUB_RUN_ATTEMPT": github_run_attempt, + "GITHUB_JOB": github_job, + "DD_GITHUB_JOB_NAME": dd_github_job_name + }, + // Job level + "ci_level": 1, + "metrics": { + name: value + }, + "provider": "github" + }, + "type": "ci_custom_metric" + } + })) + .context("cannot send metric to DataDog")?; + Ok(()) +} diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index cef92e998da1..a1e5658be364 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -1,4 +1,7 @@ +mod cpu_usage; +mod datadog; mod metrics; +mod utils; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; @@ -8,7 +11,10 @@ use anyhow::Context; use clap::Parser; use serde_yaml::Value; +use crate::cpu_usage::load_cpu_usage; +use crate::datadog::upload_datadog_metric; use crate::metrics::postprocess_metrics; +use crate::utils::load_env_var; const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker"); @@ -75,7 +81,7 @@ impl JobDatabase { } fn load_job_db(path: &Path) -> anyhow::Result { - let db = read_to_string(path)?; + let db = utils::read_to_string(path)?; let mut db: Value = serde_yaml::from_str(&db)?; // We need to expand merge keys (<<), because serde_yaml can't deal with them @@ -148,10 +154,6 @@ impl GitHubContext { } } -fn load_env_var(name: &str) -> anyhow::Result { - std::env::var(name).with_context(|| format!("Cannot find variable {name}")) -} - fn load_github_ctx() -> anyhow::Result { let event_name = load_env_var("GITHUB_EVENT_NAME")?; let commit_message = @@ -325,6 +327,18 @@ fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> any if !result.success() { Err(anyhow::anyhow!("Job failed")) } else { Ok(()) } } +fn upload_ci_metrics(cpu_usage_csv: &Path) -> anyhow::Result<()> { + let usage = load_cpu_usage(cpu_usage_csv).context("Cannot load CPU usage from input CSV")?; + eprintln!("CPU usage\n{usage:?}"); + + let avg = if !usage.is_empty() { usage.iter().sum::() / usage.len() as f64 } else { 0.0 }; + eprintln!("CPU usage average: {avg}"); + + upload_datadog_metric("avg-cpu-usage", avg).context("Cannot upload Datadog metric")?; + + Ok(()) +} + #[derive(clap::Parser)] enum Args { /// Calculate a list of jobs that should be executed on CI. @@ -350,6 +364,11 @@ enum Args { /// Usually, this will be GITHUB_STEP_SUMMARY on CI. summary_path: PathBuf, }, + /// Upload CI metrics to Datadog. + UploadBuildMetrics { + /// Path to a CSV containing the CI job CPU usage. + cpu_usage_csv: PathBuf, + }, } #[derive(clap::ValueEnum, Clone)] @@ -370,7 +389,7 @@ fn main() -> anyhow::Result<()> { let jobs_path = jobs_file.as_deref().unwrap_or(default_jobs_file); let gh_ctx = load_github_ctx() .context("Cannot load environment variables from GitHub Actions")?; - let channel = read_to_string(Path::new(CI_DIRECTORY).join("channel")) + let channel = utils::read_to_string(Path::new(CI_DIRECTORY).join("channel")) .context("Cannot read channel file")? .trim() .to_string(); @@ -379,7 +398,10 @@ fn main() -> anyhow::Result<()> { .context("Failed to calculate job matrix")?; } Args::RunJobLocally { job_type, name } => { - run_workflow_locally(load_db(default_jobs_file)?, job_type, name)? + run_workflow_locally(load_db(default_jobs_file)?, job_type, name)?; + } + Args::UploadBuildMetrics { cpu_usage_csv } => { + upload_ci_metrics(&cpu_usage_csv)?; } Args::PostprocessMetrics { metrics_path, summary_path } => { postprocess_metrics(&metrics_path, &summary_path)?; @@ -388,8 +410,3 @@ fn main() -> anyhow::Result<()> { Ok(()) } - -fn read_to_string>(path: P) -> anyhow::Result { - let error = format!("Cannot read file {:?}", path.as_ref()); - std::fs::read_to_string(path).context(error) -} diff --git a/src/ci/citool/src/utils.rs b/src/ci/citool/src/utils.rs new file mode 100644 index 000000000000..eb268ca397c7 --- /dev/null +++ b/src/ci/citool/src/utils.rs @@ -0,0 +1,12 @@ +use std::path::Path; + +use anyhow::Context; + +pub fn load_env_var(name: &str) -> anyhow::Result { + std::env::var(name).with_context(|| format!("Cannot find environment variable `{name}`")) +} + +pub fn read_to_string>(path: P) -> anyhow::Result { + let error = format!("Cannot read file {:?}", path.as_ref()); + std::fs::read_to_string(path).context(error) +} From 6166f3d2122c7dda2ffaf0935b843da7fa40c511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 13 Feb 2025 17:24:21 +0100 Subject: [PATCH 682/991] Remove Python metric upload script and package.json --- src/ci/package-lock.json | 5004 ------------------------ src/ci/package.json | 5 - src/ci/scripts/upload-build-metrics.py | 86 - 3 files changed, 5095 deletions(-) delete mode 100644 src/ci/package-lock.json delete mode 100644 src/ci/package.json delete mode 100644 src/ci/scripts/upload-build-metrics.py diff --git a/src/ci/package-lock.json b/src/ci/package-lock.json deleted file mode 100644 index 6bbdc6adcfd3..000000000000 --- a/src/ci/package-lock.json +++ /dev/null @@ -1,5004 +0,0 @@ -{ - "name": "ci", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@datadog/datadog-ci": "^2.45.1" - } - }, - "node_modules/@aws-crypto/crc32": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", - "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-js": "^5.2.0", - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.703.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.703.0.tgz", - "integrity": "sha512-KkLMwrNhkLZr3OCRWakJY16OF8pUZCoexxZkWzHfR/Pw3WBcDtBMEiEO13P6oHlGAn1VvIDxxMBSxeg/89xyJA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.699.0", - "@aws-sdk/client-sts": "3.699.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/credential-provider-node": "3.699.0", - "@aws-sdk/middleware-host-header": "3.696.0", - "@aws-sdk/middleware-logger": "3.696.0", - "@aws-sdk/middleware-recursion-detection": "3.696.0", - "@aws-sdk/middleware-user-agent": "3.696.0", - "@aws-sdk/region-config-resolver": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@aws-sdk/util-endpoints": "3.696.0", - "@aws-sdk/util-user-agent-browser": "3.696.0", - "@aws-sdk/util-user-agent-node": "3.696.0", - "@smithy/config-resolver": "^3.0.12", - "@smithy/core": "^2.5.3", - "@smithy/eventstream-serde-browser": "^3.0.13", - "@smithy/eventstream-serde-config-resolver": "^3.0.10", - "@smithy/eventstream-serde-node": "^3.0.12", - "@smithy/fetch-http-handler": "^4.1.1", - "@smithy/hash-node": "^3.0.10", - "@smithy/invalid-dependency": "^3.0.10", - "@smithy/middleware-content-length": "^3.0.12", - "@smithy/middleware-endpoint": "^3.2.3", - "@smithy/middleware-retry": "^3.0.27", - "@smithy/middleware-serde": "^3.0.10", - "@smithy/middleware-stack": "^3.0.10", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/node-http-handler": "^3.3.1", - "@smithy/protocol-http": "^4.1.7", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/url-parser": "^3.0.10", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.27", - "@smithy/util-defaults-mode-node": "^3.0.27", - "@smithy/util-endpoints": "^2.1.6", - "@smithy/util-middleware": "^3.0.10", - "@smithy/util-retry": "^3.0.10", - "@smithy/util-utf8": "^3.0.0", - "@types/uuid": "^9.0.1", - "tslib": "^2.6.2", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-cloudwatch-logs/node_modules/@smithy/util-retry": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.699.0.tgz", - "integrity": "sha512-9tFt+we6AIvj/f1+nrLHuCWcQmyfux5gcBSOy9d9+zIG56YxGEX7S9TaZnybogpVV8A0BYWml36WvIHS9QjIpA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.699.0", - "@aws-sdk/client-sts": "3.699.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/credential-provider-node": "3.699.0", - "@aws-sdk/middleware-host-header": "3.696.0", - "@aws-sdk/middleware-logger": "3.696.0", - "@aws-sdk/middleware-recursion-detection": "3.696.0", - "@aws-sdk/middleware-user-agent": "3.696.0", - "@aws-sdk/region-config-resolver": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@aws-sdk/util-endpoints": "3.696.0", - "@aws-sdk/util-user-agent-browser": "3.696.0", - "@aws-sdk/util-user-agent-node": "3.696.0", - "@smithy/config-resolver": "^3.0.12", - "@smithy/core": "^2.5.3", - "@smithy/fetch-http-handler": "^4.1.1", - "@smithy/hash-node": "^3.0.10", - "@smithy/invalid-dependency": "^3.0.10", - "@smithy/middleware-content-length": "^3.0.12", - "@smithy/middleware-endpoint": "^3.2.3", - "@smithy/middleware-retry": "^3.0.27", - "@smithy/middleware-serde": "^3.0.10", - "@smithy/middleware-stack": "^3.0.10", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/node-http-handler": "^3.3.1", - "@smithy/protocol-http": "^4.1.7", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/url-parser": "^3.0.10", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.27", - "@smithy/util-defaults-mode-node": "^3.0.27", - "@smithy/util-endpoints": "^2.1.6", - "@smithy/util-middleware": "^3.0.10", - "@smithy/util-retry": "^3.0.10", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-cognito-identity/node_modules/@smithy/util-retry": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-iam": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-iam/-/client-iam-3.699.0.tgz", - "integrity": "sha512-JBVcmkGaV7tW/mEntqt6KdkhsyYU2oIMUbkNHJextKqu6odSkuB1mN70TgctwFP8x2LDgFzvT6WcWVCKc/g3Ng==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.699.0", - "@aws-sdk/client-sts": "3.699.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/credential-provider-node": "3.699.0", - "@aws-sdk/middleware-host-header": "3.696.0", - "@aws-sdk/middleware-logger": "3.696.0", - "@aws-sdk/middleware-recursion-detection": "3.696.0", - "@aws-sdk/middleware-user-agent": "3.696.0", - "@aws-sdk/region-config-resolver": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@aws-sdk/util-endpoints": "3.696.0", - "@aws-sdk/util-user-agent-browser": "3.696.0", - "@aws-sdk/util-user-agent-node": "3.696.0", - "@smithy/config-resolver": "^3.0.12", - "@smithy/core": "^2.5.3", - "@smithy/fetch-http-handler": "^4.1.1", - "@smithy/hash-node": "^3.0.10", - "@smithy/invalid-dependency": "^3.0.10", - "@smithy/middleware-content-length": "^3.0.12", - "@smithy/middleware-endpoint": "^3.2.3", - "@smithy/middleware-retry": "^3.0.27", - "@smithy/middleware-serde": "^3.0.10", - "@smithy/middleware-stack": "^3.0.10", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/node-http-handler": "^3.3.1", - "@smithy/protocol-http": "^4.1.7", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/url-parser": "^3.0.10", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.27", - "@smithy/util-defaults-mode-node": "^3.0.27", - "@smithy/util-endpoints": "^2.1.6", - "@smithy/util-middleware": "^3.0.10", - "@smithy/util-retry": "^3.0.10", - "@smithy/util-utf8": "^3.0.0", - "@smithy/util-waiter": "^3.1.9", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-iam/node_modules/@smithy/util-retry": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-lambda": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.699.0.tgz", - "integrity": "sha512-K9TGvQB8hkjwNhfWSfYllUpttqxTcd78ShSRCIhlcwzzsmQphET10xEb0Tm1k8sqriSQ+CiVOFSkX78gqoHzBg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.699.0", - "@aws-sdk/client-sts": "3.699.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/credential-provider-node": "3.699.0", - "@aws-sdk/middleware-host-header": "3.696.0", - "@aws-sdk/middleware-logger": "3.696.0", - "@aws-sdk/middleware-recursion-detection": "3.696.0", - "@aws-sdk/middleware-user-agent": "3.696.0", - "@aws-sdk/region-config-resolver": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@aws-sdk/util-endpoints": "3.696.0", - "@aws-sdk/util-user-agent-browser": "3.696.0", - "@aws-sdk/util-user-agent-node": "3.696.0", - "@smithy/config-resolver": "^3.0.12", - "@smithy/core": "^2.5.3", - "@smithy/eventstream-serde-browser": "^3.0.13", - "@smithy/eventstream-serde-config-resolver": "^3.0.10", - "@smithy/eventstream-serde-node": "^3.0.12", - "@smithy/fetch-http-handler": "^4.1.1", - "@smithy/hash-node": "^3.0.10", - "@smithy/invalid-dependency": "^3.0.10", - "@smithy/middleware-content-length": "^3.0.12", - "@smithy/middleware-endpoint": "^3.2.3", - "@smithy/middleware-retry": "^3.0.27", - "@smithy/middleware-serde": "^3.0.10", - "@smithy/middleware-stack": "^3.0.10", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/node-http-handler": "^3.3.1", - "@smithy/protocol-http": "^4.1.7", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/url-parser": "^3.0.10", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.27", - "@smithy/util-defaults-mode-node": "^3.0.27", - "@smithy/util-endpoints": "^2.1.6", - "@smithy/util-middleware": "^3.0.10", - "@smithy/util-retry": "^3.0.10", - "@smithy/util-stream": "^3.3.1", - "@smithy/util-utf8": "^3.0.0", - "@smithy/util-waiter": "^3.1.9", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/util-retry": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sfn": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sfn/-/client-sfn-3.699.0.tgz", - "integrity": "sha512-66/+rOMVvjKRhKDDsrxtfRzXXsAfVu/RbhxPYepcVhO+0/ii6DL2uQCeNhMN3+MPg+HWX695H5RyBVJ6QGli8w==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.699.0", - "@aws-sdk/client-sts": "3.699.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/credential-provider-node": "3.699.0", - "@aws-sdk/middleware-host-header": "3.696.0", - "@aws-sdk/middleware-logger": "3.696.0", - "@aws-sdk/middleware-recursion-detection": "3.696.0", - "@aws-sdk/middleware-user-agent": "3.696.0", - "@aws-sdk/region-config-resolver": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@aws-sdk/util-endpoints": "3.696.0", - "@aws-sdk/util-user-agent-browser": "3.696.0", - "@aws-sdk/util-user-agent-node": "3.696.0", - "@smithy/config-resolver": "^3.0.12", - "@smithy/core": "^2.5.3", - "@smithy/fetch-http-handler": "^4.1.1", - "@smithy/hash-node": "^3.0.10", - "@smithy/invalid-dependency": "^3.0.10", - "@smithy/middleware-content-length": "^3.0.12", - "@smithy/middleware-endpoint": "^3.2.3", - "@smithy/middleware-retry": "^3.0.27", - "@smithy/middleware-serde": "^3.0.10", - "@smithy/middleware-stack": "^3.0.10", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/node-http-handler": "^3.3.1", - "@smithy/protocol-http": "^4.1.7", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/url-parser": "^3.0.10", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.27", - "@smithy/util-defaults-mode-node": "^3.0.27", - "@smithy/util-endpoints": "^2.1.6", - "@smithy/util-middleware": "^3.0.10", - "@smithy/util-retry": "^3.0.10", - "@smithy/util-utf8": "^3.0.0", - "@types/uuid": "^9.0.1", - "tslib": "^2.6.2", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sfn/node_modules/@smithy/util-retry": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz", - "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/middleware-host-header": "3.696.0", - "@aws-sdk/middleware-logger": "3.696.0", - "@aws-sdk/middleware-recursion-detection": "3.696.0", - "@aws-sdk/middleware-user-agent": "3.696.0", - "@aws-sdk/region-config-resolver": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@aws-sdk/util-endpoints": "3.696.0", - "@aws-sdk/util-user-agent-browser": "3.696.0", - "@aws-sdk/util-user-agent-node": "3.696.0", - "@smithy/config-resolver": "^3.0.12", - "@smithy/core": "^2.5.3", - "@smithy/fetch-http-handler": "^4.1.1", - "@smithy/hash-node": "^3.0.10", - "@smithy/invalid-dependency": "^3.0.10", - "@smithy/middleware-content-length": "^3.0.12", - "@smithy/middleware-endpoint": "^3.2.3", - "@smithy/middleware-retry": "^3.0.27", - "@smithy/middleware-serde": "^3.0.10", - "@smithy/middleware-stack": "^3.0.10", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/node-http-handler": "^3.3.1", - "@smithy/protocol-http": "^4.1.7", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/url-parser": "^3.0.10", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.27", - "@smithy/util-defaults-mode-node": "^3.0.27", - "@smithy/util-endpoints": "^2.1.6", - "@smithy/util-middleware": "^3.0.10", - "@smithy/util-retry": "^3.0.10", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.699.0.tgz", - "integrity": "sha512-u8a1GorY5D1l+4FQAf4XBUC1T10/t7neuwT21r0ymrtMFSK2a9QqVHKMoLkvavAwyhJnARSBM9/UQC797PFOFw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/credential-provider-node": "3.699.0", - "@aws-sdk/middleware-host-header": "3.696.0", - "@aws-sdk/middleware-logger": "3.696.0", - "@aws-sdk/middleware-recursion-detection": "3.696.0", - "@aws-sdk/middleware-user-agent": "3.696.0", - "@aws-sdk/region-config-resolver": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@aws-sdk/util-endpoints": "3.696.0", - "@aws-sdk/util-user-agent-browser": "3.696.0", - "@aws-sdk/util-user-agent-node": "3.696.0", - "@smithy/config-resolver": "^3.0.12", - "@smithy/core": "^2.5.3", - "@smithy/fetch-http-handler": "^4.1.1", - "@smithy/hash-node": "^3.0.10", - "@smithy/invalid-dependency": "^3.0.10", - "@smithy/middleware-content-length": "^3.0.12", - "@smithy/middleware-endpoint": "^3.2.3", - "@smithy/middleware-retry": "^3.0.27", - "@smithy/middleware-serde": "^3.0.10", - "@smithy/middleware-stack": "^3.0.10", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/node-http-handler": "^3.3.1", - "@smithy/protocol-http": "^4.1.7", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/url-parser": "^3.0.10", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.27", - "@smithy/util-defaults-mode-node": "^3.0.27", - "@smithy/util-endpoints": "^2.1.6", - "@smithy/util-middleware": "^3.0.10", - "@smithy/util-retry": "^3.0.10", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.699.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/util-retry": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso/node_modules/@smithy/util-retry": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sts": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.699.0.tgz", - "integrity": "sha512-++lsn4x2YXsZPIzFVwv3fSUVM55ZT0WRFmPeNilYIhZClxHLmVAWKH4I55cY9ry60/aTKYjzOXkWwyBKGsGvQg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.699.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/credential-provider-node": "3.699.0", - "@aws-sdk/middleware-host-header": "3.696.0", - "@aws-sdk/middleware-logger": "3.696.0", - "@aws-sdk/middleware-recursion-detection": "3.696.0", - "@aws-sdk/middleware-user-agent": "3.696.0", - "@aws-sdk/region-config-resolver": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@aws-sdk/util-endpoints": "3.696.0", - "@aws-sdk/util-user-agent-browser": "3.696.0", - "@aws-sdk/util-user-agent-node": "3.696.0", - "@smithy/config-resolver": "^3.0.12", - "@smithy/core": "^2.5.3", - "@smithy/fetch-http-handler": "^4.1.1", - "@smithy/hash-node": "^3.0.10", - "@smithy/invalid-dependency": "^3.0.10", - "@smithy/middleware-content-length": "^3.0.12", - "@smithy/middleware-endpoint": "^3.2.3", - "@smithy/middleware-retry": "^3.0.27", - "@smithy/middleware-serde": "^3.0.10", - "@smithy/middleware-stack": "^3.0.10", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/node-http-handler": "^3.3.1", - "@smithy/protocol-http": "^4.1.7", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/url-parser": "^3.0.10", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.27", - "@smithy/util-defaults-mode-node": "^3.0.27", - "@smithy/util-endpoints": "^2.1.6", - "@smithy/util-middleware": "^3.0.10", - "@smithy/util-retry": "^3.0.10", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sts/node_modules/@smithy/util-retry": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/core": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz", - "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.696.0", - "@smithy/core": "^2.5.3", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/property-provider": "^3.1.9", - "@smithy/protocol-http": "^4.1.7", - "@smithy/signature-v4": "^4.2.2", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/util-middleware": "^3.0.10", - "fast-xml-parser": "4.4.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/core/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/core/node_modules/fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - ], - "license": "MIT", - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.699.0.tgz", - "integrity": "sha512-iuaTnudaBfEET+o444sDwf71Awe6UiZfH+ipUPmswAi2jZDwdFF1nxMKDEKL8/LV5WpXsdKSfwgS0RQeupURew==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.699.0", - "@aws-sdk/types": "3.696.0", - "@smithy/property-provider": "^3.1.9", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-cognito-identity/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz", - "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@smithy/property-provider": "^3.1.9", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-env/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz", - "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@smithy/fetch-http-handler": "^4.1.1", - "@smithy/node-http-handler": "^3.3.1", - "@smithy/property-provider": "^3.1.9", - "@smithy/protocol-http": "^4.1.7", - "@smithy/smithy-client": "^3.4.4", - "@smithy/types": "^3.7.1", - "@smithy/util-stream": "^3.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.699.0.tgz", - "integrity": "sha512-dXmCqjJnKmG37Q+nLjPVu22mNkrGHY8hYoOt3Jo9R2zr5MYV7s/NHsCHr+7E+BZ+tfZYLRPeB1wkpTeHiEcdRw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.696.0", - "@aws-sdk/credential-provider-env": "3.696.0", - "@aws-sdk/credential-provider-http": "3.696.0", - "@aws-sdk/credential-provider-process": "3.696.0", - "@aws-sdk/credential-provider-sso": "3.699.0", - "@aws-sdk/credential-provider-web-identity": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@smithy/credential-provider-imds": "^3.2.6", - "@smithy/property-provider": "^3.1.9", - "@smithy/shared-ini-file-loader": "^3.1.10", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.699.0" - } - }, - "node_modules/@aws-sdk/credential-provider-ini/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.699.0.tgz", - "integrity": "sha512-MmEmNDo1bBtTgRmdNfdQksXu4uXe66s0p1hi1YPrn1h59Q605eq/xiWbGL6/3KdkViH6eGUuABeV2ODld86ylg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.696.0", - "@aws-sdk/credential-provider-http": "3.696.0", - "@aws-sdk/credential-provider-ini": "3.699.0", - "@aws-sdk/credential-provider-process": "3.696.0", - "@aws-sdk/credential-provider-sso": "3.699.0", - "@aws-sdk/credential-provider-web-identity": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@smithy/credential-provider-imds": "^3.2.6", - "@smithy/property-provider": "^3.1.9", - "@smithy/shared-ini-file-loader": "^3.1.10", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-node/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz", - "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@smithy/property-provider": "^3.1.9", - "@smithy/shared-ini-file-loader": "^3.1.10", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-process/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.699.0.tgz", - "integrity": "sha512-Ekp2cZG4pl9D8+uKWm4qO1xcm8/MeiI8f+dnlZm8aQzizeC+aXYy9GyoclSf6daK8KfRPiRfM7ZHBBL5dAfdMA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/client-sso": "3.696.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/token-providers": "3.699.0", - "@aws-sdk/types": "3.696.0", - "@smithy/property-provider": "^3.1.9", - "@smithy/shared-ini-file-loader": "^3.1.10", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz", - "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@smithy/property-provider": "^3.1.9", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.696.0" - } - }, - "node_modules/@aws-sdk/credential-provider-web-identity/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-providers": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.699.0.tgz", - "integrity": "sha512-jBjOntl9zN9Nvb0jmbMGRbiTzemDz64ij7W6BDavxBJRZpRoNeN0QCz6RolkCyXnyUJjo5mF2unY2wnv00A+LQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.699.0", - "@aws-sdk/client-sso": "3.696.0", - "@aws-sdk/client-sts": "3.699.0", - "@aws-sdk/core": "3.696.0", - "@aws-sdk/credential-provider-cognito-identity": "3.699.0", - "@aws-sdk/credential-provider-env": "3.696.0", - "@aws-sdk/credential-provider-http": "3.696.0", - "@aws-sdk/credential-provider-ini": "3.699.0", - "@aws-sdk/credential-provider-node": "3.699.0", - "@aws-sdk/credential-provider-process": "3.696.0", - "@aws-sdk/credential-provider-sso": "3.699.0", - "@aws-sdk/credential-provider-web-identity": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@smithy/credential-provider-imds": "^3.2.6", - "@smithy/property-provider": "^3.1.9", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-providers/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz", - "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.696.0", - "@smithy/protocol-http": "^4.1.7", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-logger": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz", - "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.696.0", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz", - "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.696.0", - "@smithy/protocol-http": "^4.1.7", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz", - "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@aws-sdk/util-endpoints": "3.696.0", - "@smithy/core": "^2.5.3", - "@smithy/protocol-http": "^4.1.7", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz", - "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.696.0", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/types": "^3.7.1", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.10", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/token-providers": { - "version": "3.699.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.699.0.tgz", - "integrity": "sha512-kuiEW9DWs7fNos/SM+y58HCPhcIzm1nEZLhe2/7/6+TvAYLuEWURYsbK48gzsxXlaJ2k/jGY3nIsA7RptbMOwA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.696.0", - "@smithy/property-provider": "^3.1.9", - "@smithy/shared-ini-file-loader": "^3.1.10", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sso-oidc": "^3.699.0" - } - }, - "node_modules/@aws-sdk/token-providers/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/types": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz", - "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-endpoints": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz", - "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.696.0", - "@smithy/types": "^3.7.1", - "@smithy/util-endpoints": "^2.1.6", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz", - "integrity": "sha512-ttrag6haJLWABhLqtg1Uf+4LgHWIMOVSYL+VYZmAp2v4PUGOwWmWQH0Zk8RM7YuQcLfH/EoR72/Yxz6A4FKcuw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz", - "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.696.0", - "@smithy/types": "^3.7.1", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.696.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz", - "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/middleware-user-agent": "3.696.0", - "@aws-sdk/types": "3.696.0", - "@smithy/node-config-provider": "^3.1.11", - "@smithy/types": "^3.7.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } - } - }, - "node_modules/@datadog/datadog-ci": { - "version": "2.45.1", - "resolved": "https://registry.npmjs.org/@datadog/datadog-ci/-/datadog-ci-2.45.1.tgz", - "integrity": "sha512-na4c4UuhT2jGFTOh+/uUVGR0CVj7c2B6Q7pRp9AMxb6NF2o3McjnSFJzmVc7YFdZwr+eHXeKXKf6bEYw/PjNWw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.624.0", - "@aws-sdk/client-iam": "^3.624.0", - "@aws-sdk/client-lambda": "^3.624.0", - "@aws-sdk/client-sfn": "^3.624.0", - "@aws-sdk/core": "^3.624.0", - "@aws-sdk/credential-provider-ini": "^3.624.0", - "@aws-sdk/credential-providers": "^3.624.0", - "@google-cloud/logging": "^11.1.0", - "@google-cloud/run": "^1.4.0", - "@smithy/property-provider": "^2.0.12", - "@smithy/util-retry": "^2.0.4", - "@types/datadog-metrics": "0.6.1", - "ajv": "^8.12.0", - "ajv-formats": "^2.1.1", - "async-retry": "1.3.1", - "axios": "^1.7.4", - "chalk": "3.0.0", - "clipanion": "^3.2.1", - "datadog-metrics": "0.9.3", - "deep-extend": "0.6.0", - "deep-object-diff": "^1.1.9", - "fast-levenshtein": "^3.0.0", - "fast-xml-parser": "^4.4.1", - "form-data": "4.0.0", - "fuzzy": "^0.1.3", - "glob": "^7.1.4", - "google-auth-library": "^9.12.0", - "inquirer": "^8.2.5", - "inquirer-checkbox-plus-prompt": "^1.4.2", - "js-yaml": "3.13.1", - "jszip": "^3.10.1", - "ora": "5.4.1", - "proxy-agent": "^6.4.0", - "rimraf": "^3.0.2", - "semver": "^7.5.3", - "simple-git": "3.16.0", - "ssh2": "^1.15.0", - "ssh2-streams": "0.4.10", - "sshpk": "1.16.1", - "terminal-link": "2.1.1", - "tiny-async-pool": "^2.1.0", - "typanion": "^3.14.0", - "uuid": "^9.0.0", - "ws": "^7.5.10", - "xml2js": "0.5.0", - "yamux-js": "0.1.2" - }, - "bin": { - "datadog-ci": "dist/cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@google-cloud/common": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-5.0.2.tgz", - "integrity": "sha512-V7bmBKYQyu0eVG2BFejuUjlBt+zrya6vtsKdY+JxMM/dNntPF41vZ9+LhOshEUH01zOHEqBSvI7Dad7ZS6aUeA==", - "license": "Apache-2.0", - "dependencies": { - "@google-cloud/projectify": "^4.0.0", - "@google-cloud/promisify": "^4.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "extend": "^3.0.2", - "google-auth-library": "^9.0.0", - "html-entities": "^2.5.2", - "retry-request": "^7.0.0", - "teeny-request": "^9.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/logging": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@google-cloud/logging/-/logging-11.2.0.tgz", - "integrity": "sha512-Ma94jvuoMpbgNniwtelOt8w82hxK62FuOXZonEv0Hyk3B+/YVuLG/SWNyY9yMso/RXnPEc1fP2qo9kDrjf/b2w==", - "license": "Apache-2.0", - "dependencies": { - "@google-cloud/common": "^5.0.0", - "@google-cloud/paginator": "^5.0.0", - "@google-cloud/projectify": "^4.0.0", - "@google-cloud/promisify": "^4.0.0", - "@opentelemetry/api": "^1.7.0", - "arrify": "^2.0.1", - "dot-prop": "^6.0.0", - "eventid": "^2.0.0", - "extend": "^3.0.2", - "gcp-metadata": "^6.0.0", - "google-auth-library": "^9.0.0", - "google-gax": "^4.0.3", - "on-finished": "^2.3.0", - "pumpify": "^2.0.1", - "stream-events": "^1.0.5", - "uuid": "^9.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/paginator": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", - "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", - "license": "Apache-2.0", - "dependencies": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/projectify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", - "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", - "license": "Apache-2.0", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/promisify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", - "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - } - }, - "node_modules/@google-cloud/run": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@google-cloud/run/-/run-1.5.0.tgz", - "integrity": "sha512-Ct0ZIuicd2O6fJHv7Lbwl4CcCWKK7NjACvUc4pOJVbKo75B5proOa7/9TrXVpI6oWu1n7EFx1s8xsavYHLxRAg==", - "license": "Apache-2.0", - "dependencies": { - "google-gax": "^4.0.3" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.12.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.4.tgz", - "integrity": "sha512-NBhrxEWnFh0FxeA0d//YP95lRFsSx2TNLEUQg4/W+5f/BMxcCjgOOIT24iD+ZB/tZw057j44DaIxja7w4XMrhg==", - "license": "Apache-2.0", - "dependencies": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.1" - } - }, - "node_modules/@kwsites/file-exists/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@kwsites/file-exists/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "license": "MIT" - }, - "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "license": "Apache-2.0", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause" - }, - "node_modules/@smithy/abort-controller": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.9.tgz", - "integrity": "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/config-resolver": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.13.tgz", - "integrity": "sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^3.1.12", - "@smithy/types": "^3.7.2", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.11", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/core": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.5.tgz", - "integrity": "sha512-G8G/sDDhXA7o0bOvkc7bgai6POuSld/+XhNnWAbpQTpLv2OZPvyqQ58tLPPlz0bSNsXktldDDREIv1LczFeNEw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/middleware-serde": "^3.0.11", - "@smithy/protocol-http": "^4.1.8", - "@smithy/types": "^3.7.2", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-middleware": "^3.0.11", - "@smithy/util-stream": "^3.3.2", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.8.tgz", - "integrity": "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^3.1.12", - "@smithy/property-provider": "^3.1.11", - "@smithy/types": "^3.7.2", - "@smithy/url-parser": "^3.0.11", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-codec": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.10.tgz", - "integrity": "sha512-323B8YckSbUH0nMIpXn7HZsAVKHYHFUODa8gG9cHo0ySvA1fr5iWaNT+iIL0UCqUzG6QPHA3BSsBtRQou4mMqQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^3.7.2", - "@smithy/util-hex-encoding": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/eventstream-serde-browser": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.14.tgz", - "integrity": "sha512-kbrt0vjOIihW3V7Cqj1SXQvAI5BR8SnyQYsandva0AOR307cXAc+IhPngxIPslxTLfxwDpNu0HzCAq6g42kCPg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.13", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.11.tgz", - "integrity": "sha512-P2pnEp4n75O+QHjyO7cbw/vsw5l93K/8EWyjNCAAybYwUmj3M+hjSQZ9P5TVdUgEG08ueMAP5R4FkuSkElZ5tQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-node": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.13.tgz", - "integrity": "sha512-zqy/9iwbj8Wysmvi7Lq7XFLeDgjRpTbCfwBhJa8WbrylTAHiAu6oQTwdY7iu2lxigbc9YYr9vPv5SzYny5tCXQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.13", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-universal": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.13.tgz", - "integrity": "sha512-L1Ib66+gg9uTnqp/18Gz4MDpJPKRE44geOjOQ2SVc0eiaO5l255ADziATZgjQjqumC7yPtp1XnjHlF1srcwjKw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/eventstream-codec": "^3.1.10", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/fetch-http-handler": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.2.tgz", - "integrity": "sha512-R7rU7Ae3ItU4rC0c5mB2sP5mJNbCfoDc8I5XlYjIZnquyUwec7fEo78F6DA3SmgJgkU1qTMcZJuGblxZsl10ZA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/protocol-http": "^4.1.8", - "@smithy/querystring-builder": "^3.0.11", - "@smithy/types": "^3.7.2", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/hash-node": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.11.tgz", - "integrity": "sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/invalid-dependency": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.11.tgz", - "integrity": "sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/is-array-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", - "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-content-length": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.13.tgz", - "integrity": "sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/protocol-http": "^4.1.8", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-endpoint": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.5.tgz", - "integrity": "sha512-VhJNs/s/lyx4weiZdXSloBgoLoS8osV0dKIain8nGmx7of3QFKu5BSdEuk1z/U8x9iwes1i+XCiNusEvuK1ijg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^2.5.5", - "@smithy/middleware-serde": "^3.0.11", - "@smithy/node-config-provider": "^3.1.12", - "@smithy/shared-ini-file-loader": "^3.1.12", - "@smithy/types": "^3.7.2", - "@smithy/url-parser": "^3.0.11", - "@smithy/util-middleware": "^3.0.11", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-retry": { - "version": "3.0.29", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.29.tgz", - "integrity": "sha512-/FfI/N2tIVCG9escHYLLABJlNHbO1gWFSdMlvbPOTV+Y+Aa8Q1FuS7Yaghb8NUfFmGYjkbeIu3bnbta6KbarsA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^3.1.12", - "@smithy/protocol-http": "^4.1.8", - "@smithy/service-error-classification": "^3.0.11", - "@smithy/smithy-client": "^3.4.6", - "@smithy/types": "^3.7.2", - "@smithy/util-middleware": "^3.0.11", - "@smithy/util-retry": "^3.0.11", - "tslib": "^2.6.2", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-retry/node_modules/@smithy/util-retry": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-serde": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.11.tgz", - "integrity": "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-stack": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.11.tgz", - "integrity": "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-config-provider": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.12.tgz", - "integrity": "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/property-provider": "^3.1.11", - "@smithy/shared-ini-file-loader": "^3.1.12", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-config-provider/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-http-handler": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.2.tgz", - "integrity": "sha512-t4ng1DAd527vlxvOfKFYEe6/QFBcsj7WpNlWTyjorwXXcKw3XlltBGbyHfSJ24QT84nF+agDha9tNYpzmSRZPA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/abort-controller": "^3.1.9", - "@smithy/protocol-http": "^4.1.8", - "@smithy/querystring-builder": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/property-provider": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.2.0.tgz", - "integrity": "sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/property-provider/node_modules/@smithy/types": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", - "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/protocol-http": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-builder": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.11.tgz", - "integrity": "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-parser": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.11.tgz", - "integrity": "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/service-error-classification": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz", - "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz", - "integrity": "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/signature-v4": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.4.tgz", - "integrity": "sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.8", - "@smithy/types": "^3.7.2", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.11", - "@smithy/util-uri-escape": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/smithy-client": { - "version": "3.4.6", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.6.tgz", - "integrity": "sha512-j/WYdfzdx4asqb0YZch1rb6Y5OQcuTdXY7xnEMtc05diB5jfLQQtys9J/2lzmGKri9m9mUBrcnNTv3jbXvtk7A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^2.5.5", - "@smithy/middleware-endpoint": "^3.2.5", - "@smithy/middleware-stack": "^3.0.11", - "@smithy/protocol-http": "^4.1.8", - "@smithy/types": "^3.7.2", - "@smithy/util-stream": "^3.3.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", - "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/url-parser": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.11.tgz", - "integrity": "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/querystring-parser": "^3.0.11", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-body-length-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", - "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/util-body-length-node": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", - "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-buffer-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", - "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-config-provider": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", - "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.29", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.29.tgz", - "integrity": "sha512-7k0kOfDjnSM44GG74UnjEixtHmtF/do6pCNEvp1DQlFjktEz8pv06p9RSjxp2J3Lv6I3+Ba9FLfurpFeBv+Pvw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/property-provider": "^3.1.11", - "@smithy/smithy-client": "^3.4.6", - "@smithy/types": "^3.7.2", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-browser/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.29", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.29.tgz", - "integrity": "sha512-lu8jaXAt1TIVkTAKMuGdZwWQ1L03iV/n8WPbY5hdjcNqLg2ysp5DqiINmtuLL8EgzDv1TXvKDaBAN+9bGH4sEQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/config-resolver": "^3.0.13", - "@smithy/credential-provider-imds": "^3.2.8", - "@smithy/node-config-provider": "^3.1.12", - "@smithy/property-provider": "^3.1.11", - "@smithy/smithy-client": "^3.4.6", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-node/node_modules/@smithy/property-provider": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", - "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-endpoints": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.7.tgz", - "integrity": "sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^3.1.12", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-hex-encoding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", - "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-middleware": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.11.tgz", - "integrity": "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-retry": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.2.0.tgz", - "integrity": "sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^2.1.5", - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@smithy/util-retry/node_modules/@smithy/service-error-classification": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.1.5.tgz", - "integrity": "sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^2.12.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-retry/node_modules/@smithy/types": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", - "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-stream": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.2.tgz", - "integrity": "sha512-sInAqdiVeisUGYAv/FrXpmJ0b4WTFmciTRqzhb7wVuem9BHvhIG7tpiYHLDWrl2stOokNZpTTGqz3mzB2qFwXg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/fetch-http-handler": "^4.1.2", - "@smithy/node-http-handler": "^3.3.2", - "@smithy/types": "^3.7.2", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", - "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-waiter": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.2.0.tgz", - "integrity": "sha512-PpjSboaDUE6yl+1qlg3Si57++e84oXdWGbuFUSAciXsVfEZJJJupR2Nb0QuXHiunt2vGR+1PTizOMvnUPaG2Qg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/abort-controller": "^3.1.9", - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "license": "MIT" - }, - "node_modules/@types/caseless": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", - "license": "MIT" - }, - "node_modules/@types/datadog-metrics": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@types/datadog-metrics/-/datadog-metrics-0.6.1.tgz", - "integrity": "sha512-p6zVpfmNcXwtcXjgpz7do/fKyfndGhU5sGJVtb5Gn5PvLDiQUAgD0mI/itf/99sBi9DRxeyhFQ9dQF6OxxQNbA==", - "license": "MIT" - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", - "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.20.0" - } - }, - "node_modules/@types/request": { - "version": "2.48.12", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", - "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", - "license": "MIT", - "dependencies": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, - "node_modules/@types/request/node_modules/form-data": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz", - "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "license": "MIT" - }, - "node_modules/@types/uuid": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", - "license": "MIT" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/async-retry": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", - "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", - "license": "MIT", - "dependencies": { - "retry": "0.12.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" - }, - "node_modules/buildcheck": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz", - "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==", - "optional": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "license": "MIT" - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "license": "ISC", - "engines": { - "node": ">= 10" - } - }, - "node_modules/clipanion": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-3.2.1.tgz", - "integrity": "sha512-dYFdjLb7y1ajfxQopN05mylEpK9ZX0sO1/RfMXdfmwjlIsPkbh4p7A682x++zFPLDCo1x3p82dtljHf5cW2LKA==", - "license": "MIT", - "workspaces": [ - "website" - ], - "dependencies": { - "typanion": "^3.8.0" - }, - "peerDependencies": { - "typanion": "*" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, - "node_modules/cpu-features": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", - "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "buildcheck": "~0.0.6", - "nan": "^2.19.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/datadog-metrics": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/datadog-metrics/-/datadog-metrics-0.9.3.tgz", - "integrity": "sha512-BVsBX2t+4yA3tHs7DnB5H01cHVNiGJ/bHA8y6JppJDyXG7s2DLm6JaozPGpgsgVGd42Is1CHRG/yMDQpt877Xg==", - "license": "MIT", - "dependencies": { - "debug": "3.1.0", - "dogapi": "2.8.4" - } - }, - "node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-object-diff": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.9.tgz", - "integrity": "sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==", - "license": "MIT" - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "license": "MIT", - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dogapi": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/dogapi/-/dogapi-2.8.4.tgz", - "integrity": "sha512-065fsvu5dB0o4+ENtLjZILvXMClDNH/yA9H6L8nsdcNiz9l0Hzpn7aQaCOPYXxqyzq4CRPOdwkFXUjDOXfRGbg==", - "license": "MIT", - "dependencies": { - "extend": "^3.0.2", - "json-bigint": "^1.0.0", - "lodash": "^4.17.21", - "minimist": "^1.2.5", - "rc": "^1.2.8" - }, - "bin": { - "dogapi": "bin/dogapi" - } - }, - "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/duplexify": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.2" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "license": "MIT", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ecc-jsbn/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "license": "MIT" - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/eventid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/eventid/-/eventid-2.0.1.tgz", - "integrity": "sha512-sPNTqiMokAvV048P2c9+foqVJzk49o6d4e0D/sq5jog3pw+4kBgyR0gaM1FM7Mx6Kzd9dztesh9oYz1LWWOpzw==", - "license": "Apache-2.0", - "dependencies": { - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eventid/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "license": "MIT", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", - "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", - "license": "MIT", - "dependencies": { - "fastest-levenshtein": "^1.0.7" - } - }, - "node_modules/fast-uri": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", - "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", - "license": "BSD-3-Clause" - }, - "node_modules/fast-xml-parser": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", - "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - ], - "license": "MIT", - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/fuzzy": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/fuzzy/-/fuzzy-0.1.3.tgz", - "integrity": "sha512-/gZffu4ykarLrCiP3Ygsa86UAo1E5vEVlvTrpkKywXSbP9Xhln3oSp9QSV57gEq3JFFpGJ4GZ+5zdEp3FcUh4w==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/gaxios": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", - "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", - "license": "Apache-2.0", - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.9", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", - "license": "Apache-2.0", - "dependencies": { - "gaxios": "^6.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-uri": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", - "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", - "license": "MIT", - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/get-uri/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/get-uri/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/google-auth-library": { - "version": "9.15.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz", - "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==", - "license": "Apache-2.0", - "dependencies": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/google-gax": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz", - "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==", - "license": "Apache-2.0", - "dependencies": { - "@grpc/grpc-js": "^1.10.9", - "@grpc/proto-loader": "^0.7.13", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "google-auth-library": "^9.3.0", - "node-fetch": "^2.7.0", - "object-hash": "^3.0.0", - "proto3-json-serializer": "^2.0.2", - "protobufjs": "^7.3.2", - "retry-request": "^7.0.0", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/gtoken": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "license": "MIT", - "dependencies": { - "gaxios": "^6.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/http-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "license": "MIT" - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/inquirer": { - "version": "8.2.6", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", - "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^6.0.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/inquirer-checkbox-plus-prompt": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/inquirer-checkbox-plus-prompt/-/inquirer-checkbox-plus-prompt-1.4.2.tgz", - "integrity": "sha512-W8/NL9x5A81Oq9ZfbYW5c1LuwtAhc/oB/u9YZZejna0pqrajj27XhnUHygJV0Vn5TvcDy1VJcD2Ld9kTk40dvg==", - "license": "MIT", - "dependencies": { - "chalk": "4.1.2", - "cli-cursor": "^3.1.0", - "figures": "^3.0.0", - "lodash": "^4.17.5", - "rxjs": "^6.6.7" - }, - "peerDependencies": { - "inquirer": "< 9.x" - } - }, - "node_modules/inquirer-checkbox-plus-prompt/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer-checkbox-plus-prompt/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/inquirer-checkbox-plus-prompt/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "license": "0BSD" - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/ip-address/node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause" - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "license": "MIT" - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "license": "MIT", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "license": "(MIT OR GPL-3.0-or-later)", - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, - "node_modules/jszip/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/jszip/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/jszip/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "license": "MIT", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "license": "MIT", - "dependencies": { - "immediate": "~3.0.5" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "license": "Apache-2.0" - }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "license": "ISC" - }, - "node_modules/nan": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", - "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", - "license": "MIT", - "optional": true - }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "license": "MIT", - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pac-proxy-agent": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz", - "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==", - "license": "MIT", - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.6", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-proxy-agent/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/pac-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "license": "MIT", - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "license": "(MIT AND Zlib)" - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT" - }, - "node_modules/proto3-json-serializer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", - "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", - "license": "Apache-2.0", - "dependencies": { - "protobufjs": "^7.2.5" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/protobufjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", - "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/proxy-agent": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", - "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.6", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.1.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-agent/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", - "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", - "license": "MIT", - "dependencies": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/retry-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", - "license": "MIT", - "dependencies": { - "@types/request": "^2.48.8", - "extend": "^3.0.2", - "teeny-request": "^9.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "license": "ISC" - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "license": "MIT" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, - "node_modules/simple-git": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.16.0.tgz", - "integrity": "sha512-zuWYsOLEhbJRWVxpjdiXl6eyAyGo/KzVW+KFhhw9MqEEJttcq+32jTWSGyxTdf9e/YCohxRE+9xpWFj9FdiJNw==", - "license": "MIT", - "dependencies": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.4" - }, - "funding": { - "type": "github", - "url": "https://github.com/steveukx/git-js?sponsor=1" - } - }, - "node_modules/simple-git/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/simple-git/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/socks-proxy-agent/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socks-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/ssh2": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz", - "integrity": "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==", - "hasInstallScript": true, - "dependencies": { - "asn1": "^0.2.6", - "bcrypt-pbkdf": "^1.0.2" - }, - "engines": { - "node": ">=10.16.0" - }, - "optionalDependencies": { - "cpu-features": "~0.0.10", - "nan": "^2.20.0" - } - }, - "node_modules/ssh2-streams": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.10.tgz", - "integrity": "sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==", - "dependencies": { - "asn1": "~0.2.0", - "bcrypt-pbkdf": "^1.0.2", - "streamsearch": "~0.1.2" - }, - "engines": { - "node": ">=5.2.0" - } - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "license": "MIT" - }, - "node_modules/stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "license": "MIT", - "dependencies": { - "stubs": "^3.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "license": "MIT" - }, - "node_modules/streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", - "license": "MIT" - }, - "node_modules/stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", - "license": "MIT" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/teeny-request": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", - "license": "Apache-2.0", - "dependencies": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.9", - "stream-events": "^1.0.5", - "uuid": "^9.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/teeny-request/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/teeny-request/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/teeny-request/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "license": "MIT", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/teeny-request/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/teeny-request/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "license": "MIT" - }, - "node_modules/tiny-async-pool": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-2.1.0.tgz", - "integrity": "sha512-ltAHPh/9k0STRQqaoUX52NH4ZQYAJz24ZAEwf1Zm+HYg3l9OXTWeqWKyYsHu40wF/F0rxd2N2bk5sLvX2qlSvg==", - "license": "MIT" - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "license": "Unlicense" - }, - "node_modules/typanion": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz", - "integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==", - "license": "MIT", - "workspaces": [ - "website" - ] - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "license": "MIT" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "license": "MIT", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yamux-js": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yamux-js/-/yamux-js-0.1.2.tgz", - "integrity": "sha512-bhsPlPZ9xB4Dawyf6nkS58u4F3IvGCaybkEKGnneUeepcI7MPoG3Tt6SaKCU5x/kP2/2w20Qm/GqbpwAM16vYw==", - "license": "MIT" - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - } - } -} diff --git a/src/ci/package.json b/src/ci/package.json deleted file mode 100644 index 91f21e5531e7..000000000000 --- a/src/ci/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "@datadog/datadog-ci": "^2.45.1" - } -} diff --git a/src/ci/scripts/upload-build-metrics.py b/src/ci/scripts/upload-build-metrics.py deleted file mode 100644 index 915ba9539846..000000000000 --- a/src/ci/scripts/upload-build-metrics.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -This script postprocesses data gathered during a CI run, computes certain metrics -from them, and uploads these metrics to DataDog. - -This script is expected to be executed from within a GitHub Actions job. - -It expects the following environment variables: -- DATADOG_SITE: path to the DataDog API endpoint -- DATADOG_API_KEY: DataDog API token -- DD_GITHUB_JOB_NAME: Name of the current GitHub Actions job - -It expects the presence of a binary called `datadog-ci` inside `node_modules`. -It can be installed with `npm ci` at `src/ci`. - -Usage: -```bash -$ python3 upload-build-metrics.py -``` - -`path-to-CPU-usage-CSV` is a path to a CSV generated by the `src/ci/cpu-usage-over-time.py` script. -""" - -import argparse -import csv -import os -import subprocess -import sys -from pathlib import Path -from typing import List - - -def load_cpu_usage(path: Path) -> List[float]: - usage = [] - with open(path) as f: - reader = csv.reader(f, delimiter=",") - for row in reader: - # The log might contain incomplete rows or some Python exception - if len(row) == 2: - try: - idle = float(row[1]) - usage.append(100.0 - idle) - except ValueError: - pass - return usage - - -def upload_datadog_measure(name: str, value: float): - """ - Uploads a single numeric metric for the current GitHub Actions job to DataDog. - """ - print(f"Metric {name}: {value:.4f}") - - cmd = "npx" - if os.getenv("GITHUB_ACTIONS") is not None and sys.platform.lower().startswith( - "win" - ): - # Due to weird interaction of MSYS2 and Python, we need to use an absolute path, - # and also specify the ".cmd" at the end. See https://github.com/rust-lang/rust/pull/125771. - cmd = "C:\\Program Files\\nodejs\\npx.cmd" - - subprocess.run( - [ - cmd, - "datadog-ci", - "measure", - "--level", - "job", - "--measures", - f"{name}:{value}", - ], - check=False, - ) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(prog="DataDog metric uploader") - parser.add_argument("cpu-usage-history-csv") - args = parser.parse_args() - - build_usage_csv = vars(args)["cpu-usage-history-csv"] - usage_timeseries = load_cpu_usage(Path(build_usage_csv)) - if len(usage_timeseries) > 0: - avg_cpu_usage = sum(usage_timeseries) / len(usage_timeseries) - else: - avg_cpu_usage = 0 - upload_datadog_measure("avg-cpu-usage", avg_cpu_usage) From 6c2c5dcb6e8f912af1c903d4ea632a9acef97268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 5 Mar 2025 12:13:18 +0100 Subject: [PATCH 683/991] Apply review remarks --- src/ci/citool/src/cpu_usage.rs | 2 ++ src/ci/citool/src/utils.rs | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ci/citool/src/cpu_usage.rs b/src/ci/citool/src/cpu_usage.rs index 4c9e37bf6db7..fa9a1203f419 100644 --- a/src/ci/citool/src/cpu_usage.rs +++ b/src/ci/citool/src/cpu_usage.rs @@ -14,6 +14,8 @@ pub fn load_cpu_usage(path: &Path) -> anyhow::Result> { if cols.len() == 2 { if let Ok(idle) = cols[1].parse::() { entries.push(100.0 - idle); + } else { + eprintln!("Warning: cannot parse CPU CSV entry {}", cols[1]); } } } diff --git a/src/ci/citool/src/utils.rs b/src/ci/citool/src/utils.rs index eb268ca397c7..9cc220987bdf 100644 --- a/src/ci/citool/src/utils.rs +++ b/src/ci/citool/src/utils.rs @@ -7,6 +7,5 @@ pub fn load_env_var(name: &str) -> anyhow::Result { } pub fn read_to_string>(path: P) -> anyhow::Result { - let error = format!("Cannot read file {:?}", path.as_ref()); - std::fs::read_to_string(path).context(error) + std::fs::read_to_string(&path).with_context(|| format!("Cannot read file {:?}", path.as_ref())) } From 3dbf3dc1e187d1c0654870597f85fdff4f5a640f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 5 Mar 2025 12:27:10 +0100 Subject: [PATCH 684/991] Increase the max. custom try jobs requested to `20` --- src/ci/citool/src/main.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index cef92e998da1..6a5643ab37a2 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -180,6 +180,10 @@ fn yaml_map_to_json(map: &BTreeMap) -> BTreeMap (db.pr_jobs.clone(), "PR", &db.envs.pr_env), RunType::TryJob { custom_jobs } => { let jobs = if let Some(custom_jobs) = custom_jobs { - if custom_jobs.len() > 10 { + if custom_jobs.len() > MAX_TRY_JOBS_COUNT { return Err(anyhow::anyhow!( - "It is only possible to schedule up to 10 custom jobs, received {} custom jobs", + "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs", custom_jobs.len() )); } From 64dd484f487ef9befb0b82980ad534d650318b53 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 5 Mar 2025 14:28:05 +0300 Subject: [PATCH 685/991] bless bootstrap tests Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder/tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index ec926daa9228..63a1bbc24f16 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -525,7 +525,6 @@ mod dist { first(cache.all::()), &[ rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), - rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0), rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), ] ); From 52525bc913c8acce5033250deb3a70ad5107e95c Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 5 Mar 2025 12:49:42 +0100 Subject: [PATCH 686/991] Improve tracing log format in cargo_workspace.rs --- .../rust-analyzer/crates/project-model/src/cargo_workspace.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index e7c3bcb5418d..68a9fba09c72 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -299,7 +299,9 @@ impl CargoWorkspace { ); if let Ok((_, Some(ref e))) = res { tracing::warn!( - "`cargo metadata` failed on `{cargo_toml}`, but retry with `--no-deps` succeeded" + %cargo_toml, + %e, + "`cargo metadata` failed, but retry with `--no-deps` succeeded" ); tracing::debug!("{e:?}"); } From 87815f7c0bb0735ad5eb375a52e0b72709709466 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 3 Mar 2025 14:45:20 +0100 Subject: [PATCH 687/991] Use HIR unsafety information for unsafe syntax highlightng --- .../crates/hir-ty/src/diagnostics.rs | 5 +- .../hir-ty/src/diagnostics/unsafe_check.rs | 42 +- .../rust-analyzer/crates/hir/src/semantics.rs | 113 ++---- .../crates/hir/src/source_analyzer.rs | 4 +- .../src/handlers/extract_function.rs | 5 +- .../ide-db/src/syntax_helpers/node_ext.rs | 22 +- .../crates/ide/src/syntax_highlighting.rs | 136 ++++--- .../ide/src/syntax_highlighting/format.rs | 2 +- .../ide/src/syntax_highlighting/highlight.rs | 361 +++++++++++------- .../ide/src/syntax_highlighting/html.rs | 7 +- .../test_data/highlight_asm.html | 33 +- .../test_data/highlight_assoc_functions.html | 7 +- .../test_data/highlight_attributes.html | 7 +- .../test_data/highlight_block_mod_items.html | 9 +- .../test_data/highlight_const.html | 21 +- .../test_data/highlight_crate_root.html | 7 +- .../test_data/highlight_default_library.html | 7 +- .../test_data/highlight_doctest.html | 9 +- .../test_data/highlight_extern_crate.html | 7 +- .../test_data/highlight_general.html | 9 +- .../test_data/highlight_injection.html | 7 +- .../test_data/highlight_issue_18089.html | 7 +- .../test_data/highlight_keywords_2015.html | 7 +- .../test_data/highlight_keywords_2018.html | 7 +- .../test_data/highlight_keywords_2021.html | 7 +- .../test_data/highlight_keywords_2024.html | 7 +- .../test_data/highlight_keywords_macros.html | 7 +- .../test_data/highlight_lifetimes.html | 7 +- .../test_data/highlight_macros.html | 7 +- .../highlight_module_docs_inline.html | 7 +- .../highlight_module_docs_outline.html | 7 +- .../test_data/highlight_operators.html | 7 +- .../test_data/highlight_rainbow.html | 7 +- .../test_data/highlight_strings.html | 11 +- .../test_data/highlight_unsafe.html | 93 +++-- .../ide/src/syntax_highlighting/tests.rs | 76 ++-- .../docs/book/src/assists_generated.md | 6 +- 37 files changed, 550 insertions(+), 540 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics.rs index 30c02a2936dd..845d33333536 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics.rs @@ -9,5 +9,8 @@ pub use crate::diagnostics::{ expr::{ record_literal_missing_fields, record_pattern_missing_fields, BodyValidationDiagnostic, }, - unsafe_check::{missing_unsafe, unsafe_expressions, InsideUnsafeBlock, UnsafetyReason}, + unsafe_check::{ + missing_unsafe, unsafe_operations, unsafe_operations_for_body, InsideUnsafeBlock, + UnsafetyReason, + }, }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs index ac849b0762d7..d2b908839c42 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -95,7 +95,26 @@ enum UnsafeDiagnostic { DeprecatedSafe2024 { node: ExprId, inside_unsafe_block: InsideUnsafeBlock }, } -pub fn unsafe_expressions( +pub fn unsafe_operations_for_body( + db: &dyn HirDatabase, + infer: &InferenceResult, + def: DefWithBodyId, + body: &Body, + callback: &mut dyn FnMut(ExprOrPatId), +) { + let mut visitor_callback = |diag| { + if let UnsafeDiagnostic::UnsafeOperation { node, .. } = diag { + callback(node); + } + }; + let mut visitor = UnsafeVisitor::new(db, infer, body, def, &mut visitor_callback); + visitor.walk_expr(body.body_expr); + for ¶m in &body.params { + visitor.walk_pat(param); + } +} + +pub fn unsafe_operations( db: &dyn HirDatabase, infer: &InferenceResult, def: DefWithBodyId, @@ -281,13 +300,6 @@ impl<'a> UnsafeVisitor<'a> { self.on_unsafe_op(current.into(), UnsafetyReason::RawPtrDeref); } } - Expr::Unsafe { .. } => { - let old_inside_unsafe_block = - mem::replace(&mut self.inside_unsafe_block, InsideUnsafeBlock::Yes); - self.body.walk_child_exprs_without_pats(current, |child| self.walk_expr(child)); - self.inside_unsafe_block = old_inside_unsafe_block; - return; - } &Expr::Assignment { target, value: _ } => { let old_inside_assignment = mem::replace(&mut self.inside_assignment, true); self.walk_pats_top(std::iter::once(target), current); @@ -306,6 +318,20 @@ impl<'a> UnsafeVisitor<'a> { } } } + Expr::Unsafe { statements, .. } => { + let old_inside_unsafe_block = + mem::replace(&mut self.inside_unsafe_block, InsideUnsafeBlock::Yes); + self.walk_pats_top( + statements.iter().filter_map(|statement| match statement { + &Statement::Let { pat, .. } => Some(pat), + _ => None, + }), + current, + ); + self.body.walk_child_exprs_without_pats(current, |child| self.walk_expr(child)); + self.inside_unsafe_block = old_inside_unsafe_block; + return; + } Expr::Block { statements, .. } | Expr::Async { statements, .. } => { self.walk_pats_top( statements.iter().filter_map(|statement| match statement { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index bb67fa63a1d1..1b8531209c1b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -12,6 +12,7 @@ use std::{ use either::Either; use hir_def::{ + expr_store::ExprOrPatSource, hir::{Expr, ExprOrPatId}, lower::LowerCtx, nameres::{MacroSubNs, ModuleOrigin}, @@ -30,6 +31,7 @@ use hir_expand::{ name::AsName, ExpandResult, FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, }; +use hir_ty::diagnostics::unsafe_operations_for_body; use intern::{sym, Symbol}; use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; @@ -48,8 +50,8 @@ use crate::{ db::HirDatabase, semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{name_hygiene, resolve_hir_path, SourceAnalyzer}, - Access, Adjust, Adjustment, Adt, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const, - ConstParam, Crate, DeriveHelper, Enum, Field, Function, GenericSubstitution, HasSource, + Adjust, Adjustment, Adt, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const, ConstParam, + Crate, DefWithBody, DeriveHelper, Enum, Field, Function, GenericSubstitution, HasSource, HirFileId, Impl, InFile, InlineAsmOperand, ItemInNs, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, OverloadedDeref, Path, ScopeDef, Static, Struct, ToolModule, Trait, TraitAlias, TupleField, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, @@ -1555,6 +1557,19 @@ impl<'db> SemanticsImpl<'db> { .matched_arm } + pub fn get_unsafe_ops(&self, def: DefWithBody) -> FxHashSet { + let def = DefWithBodyId::from(def); + let (body, source_map) = self.db.body_with_source_map(def); + let infer = self.db.infer(def); + let mut res = FxHashSet::default(); + unsafe_operations_for_body(self.db, &infer, def, &body, &mut |node| { + if let Ok(node) = source_map.expr_or_pat_syntax(node) { + res.insert(node); + } + }); + res + } + pub fn is_unsafe_macro_call(&self, macro_call: &ast::MacroCall) -> bool { let Some(mac) = self.resolve_macro_call(macro_call) else { return false }; if mac.is_asm_or_global_asm(self.db) { @@ -1682,6 +1697,15 @@ impl<'db> SemanticsImpl<'db> { Some(res) } + pub fn body_for(&self, node: InFile<&SyntaxNode>) -> Option { + let container = self.with_ctx(|ctx| ctx.find_container(node))?; + + match container { + ChildContainer::DefWithBodyId(def) => Some(def.into()), + _ => None, + } + } + /// Returns none if the file of the node is not part of a crate. fn analyze(&self, node: &SyntaxNode) -> Option { let node = self.find_file(node); @@ -1783,91 +1807,6 @@ impl<'db> SemanticsImpl<'db> { InFile::new(file_id, node) } - pub fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool { - method_call_expr - .receiver() - .and_then(|expr| { - let field_expr = match expr { - ast::Expr::FieldExpr(field_expr) => field_expr, - _ => return None, - }; - let ty = self.type_of_expr(&field_expr.expr()?)?.original; - if !ty.is_packed(self.db) { - return None; - } - - let func = self.resolve_method_call(method_call_expr)?; - let res = match func.self_param(self.db)?.access(self.db) { - Access::Shared | Access::Exclusive => true, - Access::Owned => false, - }; - Some(res) - }) - .unwrap_or(false) - } - - pub fn is_unsafe_ref_expr(&self, ref_expr: &ast::RefExpr) -> bool { - ref_expr - .expr() - .and_then(|expr| { - let field_expr = match expr { - ast::Expr::FieldExpr(field_expr) => field_expr, - _ => return None, - }; - let expr = field_expr.expr()?; - self.type_of_expr(&expr) - }) - // Binding a reference to a packed type is possibly unsafe. - .map(|ty| ty.original.is_packed(self.db)) - .unwrap_or(false) - - // FIXME This needs layout computation to be correct. It will highlight - // more than it should with the current implementation. - } - - pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool { - if ident_pat.ref_token().is_none() { - return false; - } - - ident_pat - .syntax() - .parent() - .and_then(|parent| { - // `IdentPat` can live under `RecordPat` directly under `RecordPatField` or - // `RecordPatFieldList`. `RecordPatField` also lives under `RecordPatFieldList`, - // so this tries to lookup the `IdentPat` anywhere along that structure to the - // `RecordPat` so we can get the containing type. - let record_pat = ast::RecordPatField::cast(parent.clone()) - .and_then(|record_pat| record_pat.syntax().parent()) - .or_else(|| Some(parent.clone())) - .and_then(|parent| { - ast::RecordPatFieldList::cast(parent)? - .syntax() - .parent() - .and_then(ast::RecordPat::cast) - }); - - // If this doesn't match a `RecordPat`, fallback to a `LetStmt` to see if - // this is initialized from a `FieldExpr`. - if let Some(record_pat) = record_pat { - self.type_of_pat(&ast::Pat::RecordPat(record_pat)) - } else if let Some(let_stmt) = ast::LetStmt::cast(parent) { - let field_expr = match let_stmt.initializer()? { - ast::Expr::FieldExpr(field_expr) => field_expr, - _ => return None, - }; - - self.type_of_expr(&field_expr.expr()?) - } else { - None - } - }) - // Binding a reference to a packed type is possibly unsafe. - .map(|ty| ty.original.is_packed(self.db)) - .unwrap_or(false) - } - /// Returns `true` if the `node` is inside an `unsafe` context. pub fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool { let Some(enclosing_item) = diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 9019863f7fde..d1245f5f7d68 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -35,7 +35,7 @@ use hir_expand::{ }; use hir_ty::{ diagnostics::{ - record_literal_missing_fields, record_pattern_missing_fields, unsafe_expressions, + record_literal_missing_fields, record_pattern_missing_fields, unsafe_operations, InsideUnsafeBlock, }, from_assoc_type_id, @@ -1160,7 +1160,7 @@ impl SourceAnalyzer { if let Some(expanded_expr) = sm.macro_expansion_expr(macro_expr) { let mut is_unsafe = false; let mut walk_expr = |expr_id| { - unsafe_expressions(db, infer, *def, body, expr_id, &mut |inside_unsafe_block| { + unsafe_operations(db, infer, *def, body, expr_id, &mut |inside_unsafe_block| { is_unsafe |= inside_unsafe_block == InsideUnsafeBlock::No }) }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 751e4a5a5719..330587e0dbfb 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -750,7 +750,10 @@ impl FunctionBody { ast::Stmt::Item(_) => (), ast::Stmt::LetStmt(stmt) => { if let Some(pat) = stmt.pat() { - walk_pat(&pat, cb); + walk_pat(&pat, &mut |pat| { + cb(pat); + std::ops::ControlFlow::<(), ()>::Continue(()) + }); } if let Some(expr) = stmt.initializer() { walk_patterns_in_expr(&expr, cb); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs index 74c0b8e2baac..0b2e8aa6836f 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs @@ -1,4 +1,6 @@ //! Various helper functions to work with SyntaxNodes. +use std::ops::ControlFlow; + use itertools::Itertools; use parser::T; use span::Edition; @@ -119,7 +121,10 @@ pub fn walk_patterns_in_expr(start: &ast::Expr, cb: &mut dyn FnMut(ast::Pat)) { match ast::Stmt::cast(node.clone()) { Some(ast::Stmt::LetStmt(l)) => { if let Some(pat) = l.pat() { - walk_pat(&pat, cb); + walk_pat(&pat, &mut |pat| { + cb(pat); + ControlFlow::<(), ()>::Continue(()) + }); } if let Some(expr) = l.initializer() { walk_patterns_in_expr(&expr, cb); @@ -154,7 +159,10 @@ pub fn walk_patterns_in_expr(start: &ast::Expr, cb: &mut dyn FnMut(ast::Pat)) { } } else if let Some(pat) = ast::Pat::cast(node) { preorder.skip_subtree(); - walk_pat(&pat, cb); + walk_pat(&pat, &mut |pat| { + cb(pat); + ControlFlow::<(), ()>::Continue(()) + }); } } } @@ -162,7 +170,10 @@ pub fn walk_patterns_in_expr(start: &ast::Expr, cb: &mut dyn FnMut(ast::Pat)) { } /// Preorder walk all the pattern's sub patterns. -pub fn walk_pat(pat: &ast::Pat, cb: &mut dyn FnMut(ast::Pat)) { +pub fn walk_pat( + pat: &ast::Pat, + cb: &mut dyn FnMut(ast::Pat) -> ControlFlow, +) -> ControlFlow { let mut preorder = pat.syntax().preorder(); while let Some(event) = preorder.next() { let node = match event { @@ -173,10 +184,10 @@ pub fn walk_pat(pat: &ast::Pat, cb: &mut dyn FnMut(ast::Pat)) { match ast::Pat::cast(node) { Some(pat @ ast::Pat::ConstBlockPat(_)) => { preorder.skip_subtree(); - cb(pat); + cb(pat)?; } Some(pat) => { - cb(pat); + cb(pat)?; } // skip const args None if ast::GenericArg::can_cast(kind) => { @@ -185,6 +196,7 @@ pub fn walk_pat(pat: &ast::Pat, cb: &mut dyn FnMut(ast::Pat)) { None => (), } } + ControlFlow::Continue(()) } /// Preorder walk all the type's sub types. diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index 519133e3ad18..62dc92feb1d6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -14,8 +14,11 @@ mod tests; use std::ops::ControlFlow; -use hir::{HirFileIdExt, InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics}; -use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind}; +use either::Either; +use hir::{ + DefWithBody, HirFileIdExt, InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics, +}; +use ide_db::{FxHashMap, FxHashSet, Ranker, RootDatabase, SymbolKind}; use span::EditionedFileId; use syntax::{ ast::{self, IsString}, @@ -232,7 +235,6 @@ fn traverse( range_to_highlight: TextRange, ) { let is_unlinked = sema.file_to_module_def(file_id).is_none(); - let mut bindings_shadow_count: FxHashMap = FxHashMap::default(); enum AttrOrDerive { Attr(ast::Item), @@ -247,13 +249,22 @@ fn traverse( } } + let empty = FxHashSet::default(); + + // FIXME: accommodate range highlighting let mut tt_level = 0; + // FIXME: accommodate range highlighting let mut attr_or_derive_item = None; // FIXME: these are not perfectly accurate, we determine them by the real file's syntax tree // an attribute nested in a macro call will not emit `inside_attribute` let mut inside_attribute = false; + // FIXME: accommodate range highlighting + let mut body_stack: Vec> = vec![]; + let mut per_body_cache: FxHashMap, FxHashMap)> = + FxHashMap::default(); + // Walk all nodes, keeping track of whether we are inside a macro or not. // If in macro, expand it first and highlight the expanded code. let mut preorder = root.preorder_with_tokens(); @@ -282,48 +293,68 @@ fn traverse( Leave(NodeOrToken::Node(node)) if ast::Attr::can_cast(node.kind()) => { inside_attribute = false } - Enter(NodeOrToken::Node(node)) => { - if let Some(item) = ast::Item::cast(node.clone()) { + if let Some(item) = >::cast(node.clone()) { match item { - ast::Item::Fn(_) | ast::Item::Const(_) | ast::Item::Static(_) => { - bindings_shadow_count.clear() - } - _ => (), - } - - if attr_or_derive_item.is_none() { - if sema.is_attr_macro_call(InFile::new(file_id.into(), &item)) { - attr_or_derive_item = Some(AttrOrDerive::Attr(item)); - } else { - let adt = match item { - ast::Item::Enum(it) => Some(ast::Adt::Enum(it)), - ast::Item::Struct(it) => Some(ast::Adt::Struct(it)), - ast::Item::Union(it) => Some(ast::Adt::Union(it)), - _ => None, - }; - match adt { - Some(adt) - if sema - .is_derive_annotated(InFile::new(file_id.into(), &adt)) => - { - attr_or_derive_item = - Some(AttrOrDerive::Derive(ast::Item::from(adt))); + Either::Left(item) => { + match &item { + ast::Item::Fn(it) => { + body_stack.push(sema.to_def(it).map(Into::into)) + } + ast::Item::Const(it) => { + body_stack.push(sema.to_def(it).map(Into::into)) + } + ast::Item::Static(it) => { + body_stack.push(sema.to_def(it).map(Into::into)) } _ => (), } + + if attr_or_derive_item.is_none() { + if sema.is_attr_macro_call(InFile::new(file_id.into(), &item)) { + attr_or_derive_item = Some(AttrOrDerive::Attr(item)); + } else { + let adt = match item { + ast::Item::Enum(it) => Some(ast::Adt::Enum(it)), + ast::Item::Struct(it) => Some(ast::Adt::Struct(it)), + ast::Item::Union(it) => Some(ast::Adt::Union(it)), + _ => None, + }; + match adt { + Some(adt) + if sema.is_derive_annotated(InFile::new( + file_id.into(), + &adt, + )) => + { + attr_or_derive_item = + Some(AttrOrDerive::Derive(ast::Item::from(adt))); + } + _ => (), + } + } + } } + Either::Right(it) => body_stack.push(sema.to_def(&it).map(Into::into)), } } } - Leave(NodeOrToken::Node(node)) if ast::Item::can_cast(node.kind()) => { + Leave(NodeOrToken::Node(node)) + if >::can_cast(node.kind()) => + { match ast::Item::cast(node.clone()) { - Some(item) - if attr_or_derive_item.as_ref().is_some_and(|it| *it.item() == item) => - { - attr_or_derive_item = None; + Some(item) => { + if attr_or_derive_item.as_ref().is_some_and(|it| *it.item() == item) { + attr_or_derive_item = None; + } + if matches!( + item, + ast::Item::Fn(_) | ast::Item::Const(_) | ast::Item::Static(_) + ) { + body_stack.pop(); + } } - _ => (), + None => _ = body_stack.pop(), } } _ => (), @@ -361,16 +392,22 @@ fn traverse( None => false, }; - let descended_element = if in_macro { + let (descended_element, current_body) = match element { // Attempt to descend tokens into macro-calls. - match element { - NodeOrToken::Token(token) => descend_token(sema, InRealFile::new(file_id, token)), - n => InFile::new(file_id.into(), n), + NodeOrToken::Token(token) if in_macro => { + let descended = descend_token(sema, InRealFile::new(file_id, token)); + let body = match &descended.value { + NodeOrToken::Node(n) => { + sema.body_for(InFile::new(descended.file_id, n.syntax())) + } + NodeOrToken::Token(t) => { + t.parent().and_then(|it| sema.body_for(InFile::new(descended.file_id, &it))) + } + }; + (descended, body) } - } else { - InFile::new(file_id.into(), element) + n => (InFile::new(file_id.into(), n), body_stack.last().copied().flatten()), }; - // string highlight injections if let (Some(original_token), Some(descended_token)) = (original_token, descended_element.value.as_token()) @@ -390,12 +427,24 @@ fn traverse( } let edition = descended_element.file_id.edition(sema.db); + let (unsafe_ops, bindings_shadow_count) = match current_body { + Some(current_body) => { + let (ops, bindings) = per_body_cache + .entry(current_body) + .or_insert_with(|| (sema.get_unsafe_ops(current_body), Default::default())); + (&*ops, Some(bindings)) + } + None => (&empty, None), + }; + let is_unsafe_node = + |node| unsafe_ops.contains(&InFile::new(descended_element.file_id, node)); let element = match descended_element.value { NodeOrToken::Node(name_like) => { let hl = highlight::name_like( sema, krate, - &mut bindings_shadow_count, + bindings_shadow_count, + &is_unsafe_node, config.syntactic_name_ref_highlighting, name_like, edition, @@ -408,7 +457,8 @@ fn traverse( hl } NodeOrToken::Token(token) => { - highlight::token(sema, token, edition, tt_level > 0).zip(Some(None)) + highlight::token(sema, token, edition, &is_unsafe_node, tt_level > 0) + .zip(Some(None)) } }; if let Some((mut highlight, binding_hash)) = element { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs index c63043621c27..cc02aff2acf8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs @@ -41,7 +41,7 @@ pub(super) fn highlight_format_string( if let Some(res) = res { stack.add(HlRange { range, - highlight: highlight_def(sema, krate, Definition::from(res), edition), + highlight: highlight_def(sema, krate, Definition::from(res), edition, true), binding_hash: None, }) } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index 127861a04bd8..282fbb4433b2 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs @@ -1,17 +1,20 @@ //! Computes color for a single element. +use std::ops::ControlFlow; + use either::Either; use hir::{AsAssocItem, HasVisibility, MacroFileIdExt, Semantics}; use ide_db::{ defs::{Definition, IdentClass, NameClass, NameRefClass}, + syntax_helpers::node_ext::walk_pat, FxHashMap, RootDatabase, SymbolKind, }; use span::Edition; use stdx::hash_once; use syntax::{ - ast, match_ast, AstNode, AstToken, NodeOrToken, + ast, match_ast, AstNode, AstPtr, AstToken, NodeOrToken, SyntaxKind::{self, *}, - SyntaxNode, SyntaxToken, T, + SyntaxNode, SyntaxNodePtr, SyntaxToken, T, }; use crate::{ @@ -23,6 +26,7 @@ pub(super) fn token( sema: &Semantics<'_, RootDatabase>, token: SyntaxToken, edition: Edition, + is_unsafe_node: &impl Fn(AstPtr>) -> bool, in_tt: bool, ) -> Option { if let Some(comment) = ast::Comment::cast(token.clone()) { @@ -33,11 +37,8 @@ pub(super) fn token( }); } - let highlight: Highlight = match token.kind() { + let h = match token.kind() { STRING | BYTE_STRING | C_STRING => HlTag::StringLiteral.into(), - INT_NUMBER if token.parent_ancestors().nth(1).map(|it| it.kind()) == Some(FIELD_EXPR) => { - SymbolKind::Field.into() - } INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(), BYTE => HlTag::ByteLiteral.into(), CHAR => HlTag::CharLiteral.into(), @@ -46,24 +47,25 @@ pub(super) fn token( // that were not mapped down into macro invocations HlTag::None.into() } - p if p.is_punct() => punctuation(sema, token, p), + p if p.is_punct() => punctuation(sema, token, p, is_unsafe_node), k if k.is_keyword(edition) => { if in_tt && token.prev_token().is_some_and(|t| t.kind() == T![$]) { // we are likely within a macro definition where our keyword is a fragment name HlTag::None.into() } else { - keyword(sema, token, k)? + keyword(token, k) } } _ => return None, }; - Some(highlight) + Some(h) } pub(super) fn name_like( sema: &Semantics<'_, RootDatabase>, krate: hir::Crate, - bindings_shadow_count: &mut FxHashMap, + bindings_shadow_count: Option<&mut FxHashMap>, + is_unsafe_node: &impl Fn(AstPtr>) -> bool, syntactic_name_ref_highlighting: bool, name_like: ast::NameLike, edition: Edition, @@ -75,19 +77,26 @@ pub(super) fn name_like( krate, bindings_shadow_count, &mut binding_hash, + is_unsafe_node, syntactic_name_ref_highlighting, name_ref, edition, ), - ast::NameLike::Name(name) => { - highlight_name(sema, bindings_shadow_count, &mut binding_hash, krate, name, edition) - } + ast::NameLike::Name(name) => highlight_name( + sema, + bindings_shadow_count, + &mut binding_hash, + is_unsafe_node, + krate, + name, + edition, + ), ast::NameLike::Lifetime(lifetime) => match IdentClass::classify_lifetime(sema, &lifetime) { Some(IdentClass::NameClass(NameClass::Definition(def))) => { - highlight_def(sema, krate, def, edition) | HlMod::Definition + highlight_def(sema, krate, def, edition, false) | HlMod::Definition } Some(IdentClass::NameRefClass(NameRefClass::Definition(def, _))) => { - highlight_def(sema, krate, def, edition) + highlight_def(sema, krate, def, edition, true) } // FIXME: Fallback for '_, as we do not resolve these yet _ => SymbolKind::LifetimeParam.into(), @@ -100,44 +109,49 @@ fn punctuation( sema: &Semantics<'_, RootDatabase>, token: SyntaxToken, kind: SyntaxKind, + is_unsafe_node: &impl Fn(AstPtr>) -> bool, ) -> Highlight { - let parent = token.parent(); - let parent_kind = parent.as_ref().map_or(EOF, SyntaxNode::kind); - match (kind, parent_kind) { + let operator_parent = token.parent(); + let parent_kind = operator_parent.as_ref().map_or(EOF, SyntaxNode::kind); + let h = match (kind, parent_kind) { (T![?], TRY_EXPR) => HlTag::Operator(HlOperator::Other) | HlMod::ControlFlow, (T![&], BIN_EXPR) => HlOperator::Bitwise.into(), - (T![&], REF_EXPR) => { + (T![&], REF_EXPR | REF_PAT) => HlTag::Operator(HlOperator::Other).into(), + (T![..] | T![..=], _) => match token.parent().and_then(ast::Pat::cast) { + Some(pat) if is_unsafe_node(AstPtr::new(&pat).wrap_right()) => { + Highlight::from(HlOperator::Other) | HlMod::Unsafe + } + _ => HlOperator::Other.into(), + }, + (T![::] | T![->] | T![=>] | T![=] | T![@] | T![.], _) => HlOperator::Other.into(), + (T![!], MACRO_CALL) => { + if operator_parent + .and_then(ast::MacroCall::cast) + .is_some_and(|macro_call| sema.is_unsafe_macro_call(¯o_call)) + { + Highlight::from(HlPunct::MacroBang) | HlMod::Unsafe + } else { + HlPunct::MacroBang.into() + } + } + (T![!], MACRO_RULES) => HlPunct::MacroBang.into(), + (T![!], NEVER_TYPE) => HlTag::BuiltinType.into(), + (T![!], PREFIX_EXPR) => HlOperator::Logical.into(), + (T![*], PTR_TYPE) => HlTag::Keyword.into(), + (T![*], PREFIX_EXPR) => { let h = HlTag::Operator(HlOperator::Other).into(); - let is_unsafe = parent - .and_then(ast::RefExpr::cast) - .map(|ref_expr| sema.is_unsafe_ref_expr(&ref_expr)); - if let Some(true) = is_unsafe { + let ptr = operator_parent + .as_ref() + .and_then(|it| AstPtr::try_from_raw(SyntaxNodePtr::new(it))); + if ptr.is_some_and(is_unsafe_node) { h | HlMod::Unsafe } else { h } } - (T![::] | T![->] | T![=>] | T![..] | T![..=] | T![=] | T![@] | T![.], _) => { - HlOperator::Other.into() - } - (T![!], MACRO_CALL | MACRO_RULES) => HlPunct::MacroBang.into(), - (T![!], NEVER_TYPE) => HlTag::BuiltinType.into(), - (T![!], PREFIX_EXPR) => HlOperator::Logical.into(), - (T![*], PTR_TYPE) => HlTag::Keyword.into(), - (T![*], PREFIX_EXPR) => { - let is_raw_ptr = (|| { - let prefix_expr = parent.and_then(ast::PrefixExpr::cast)?; - let expr = prefix_expr.expr()?; - sema.type_of_expr(&expr)?.original.is_raw_ptr().then_some(()) - })(); - if let Some(()) = is_raw_ptr { - HlTag::Operator(HlOperator::Other) | HlMod::Unsafe - } else { - HlOperator::Other.into() - } - } (T![-], PREFIX_EXPR) => { - let prefix_expr = parent.and_then(ast::PrefixExpr::cast).and_then(|e| e.expr()); + let prefix_expr = + operator_parent.and_then(ast::PrefixExpr::cast).and_then(|e| e.expr()); match prefix_expr { Some(ast::Expr::Literal(_)) => HlTag::NumericLiteral, _ => HlTag::Operator(HlOperator::Other), @@ -157,36 +171,90 @@ fn punctuation( HlOperator::Comparison.into() } (_, ATTR) => HlTag::AttributeBracket.into(), + (T![>], _) + if operator_parent + .as_ref() + .and_then(SyntaxNode::parent) + .is_some_and(|it| it.kind() == MACRO_RULES) => + { + HlOperator::Other.into() + } (kind, _) => match kind { - T!['['] | T![']'] => HlPunct::Bracket, - T!['{'] | T!['}'] => HlPunct::Brace, - T!['('] | T![')'] => HlPunct::Parenthesis, - T![>] - if parent + T!['['] | T![']'] => { + let is_unsafe_macro = operator_parent .as_ref() - .and_then(SyntaxNode::parent) - .is_some_and(|it| it.kind() == MACRO_RULES) => - { - return HlOperator::Other.into() + .and_then(|it| ast::TokenTree::cast(it.clone())?.syntax().parent()) + .and_then(ast::MacroCall::cast) + .is_some_and(|macro_call| sema.is_unsafe_macro_call(¯o_call)); + let is_unsafe = is_unsafe_macro + || operator_parent + .as_ref() + .and_then(|it| AstPtr::try_from_raw(SyntaxNodePtr::new(it))) + .is_some_and(is_unsafe_node); + if is_unsafe { + return Highlight::from(HlPunct::Bracket) | HlMod::Unsafe; + } else { + HlPunct::Bracket + } + } + T!['{'] | T!['}'] => { + let is_unsafe_macro = operator_parent + .as_ref() + .and_then(|it| ast::TokenTree::cast(it.clone())?.syntax().parent()) + .and_then(ast::MacroCall::cast) + .is_some_and(|macro_call| sema.is_unsafe_macro_call(¯o_call)); + let is_unsafe = is_unsafe_macro + || operator_parent + .as_ref() + .and_then(|it| AstPtr::try_from_raw(SyntaxNodePtr::new(it))) + .is_some_and(is_unsafe_node); + if is_unsafe { + return Highlight::from(HlPunct::Brace) | HlMod::Unsafe; + } else { + HlPunct::Brace + } + } + T!['('] | T![')'] => { + let is_unsafe_macro = operator_parent + .as_ref() + .and_then(|it| ast::TokenTree::cast(it.clone())?.syntax().parent()) + .and_then(ast::MacroCall::cast) + .is_some_and(|macro_call| sema.is_unsafe_macro_call(¯o_call)); + let is_unsafe = is_unsafe_macro + || operator_parent + .and_then(|it| { + if ast::ArgList::can_cast(it.kind()) { + it.parent() + } else { + Some(it) + } + }) + .and_then(|it| AstPtr::try_from_raw(SyntaxNodePtr::new(&it))) + .is_some_and(is_unsafe_node); + + if is_unsafe { + return Highlight::from(HlPunct::Parenthesis) | HlMod::Unsafe; + } else { + HlPunct::Parenthesis + } } T![<] | T![>] => HlPunct::Angle, - T![,] => HlPunct::Comma, + // Early return as otherwise we'd highlight these in + // asm expressions + T![,] => return HlPunct::Comma.into(), T![:] => HlPunct::Colon, T![;] => HlPunct::Semi, T![.] => HlPunct::Dot, _ => HlPunct::Other, } .into(), - } + }; + h } -fn keyword( - sema: &Semantics<'_, RootDatabase>, - token: SyntaxToken, - kind: SyntaxKind, -) -> Option { +fn keyword(token: SyntaxToken, kind: SyntaxKind) -> Highlight { let h = Highlight::new(HlTag::Keyword); - let h = match kind { + match kind { T![await] => h | HlMod::Async | HlMod::ControlFlow, T![async] => h | HlMod::Async, T![break] @@ -202,53 +270,33 @@ fn keyword( T![do] | T![yeet] if parent_matches::(&token) => h | HlMod::ControlFlow, T![for] if parent_matches::(&token) => h | HlMod::ControlFlow, T![unsafe] => h | HlMod::Unsafe, - T![const] - if token.parent().is_some_and(|it| { - matches!( - it.kind(), - SyntaxKind::CONST - | SyntaxKind::FN - | SyntaxKind::IMPL - | SyntaxKind::BLOCK_EXPR - | SyntaxKind::CLOSURE_EXPR - | SyntaxKind::FN_PTR_TYPE - | SyntaxKind::TYPE_BOUND - | SyntaxKind::CONST_BLOCK_PAT - ) - }) => - { - h | HlMod::Const - } + T![const] => h | HlMod::Const, T![true] | T![false] => HlTag::BoolLiteral.into(), // crate is handled just as a token if it's in an `extern crate` T![crate] if parent_matches::(&token) => h, - T![ref] => match token.parent().and_then(ast::IdentPat::cast) { - Some(ident) if sema.is_unsafe_ident_pat(&ident) => h | HlMod::Unsafe, - _ => h, - }, _ => h, - }; - Some(h) + } } fn highlight_name_ref( sema: &Semantics<'_, RootDatabase>, krate: hir::Crate, - bindings_shadow_count: &mut FxHashMap, + bindings_shadow_count: Option<&mut FxHashMap>, binding_hash: &mut Option, + is_unsafe_node: &impl Fn(AstPtr>) -> bool, syntactic_name_ref_highlighting: bool, name_ref: ast::NameRef, edition: Edition, ) -> Highlight { let db = sema.db; - if let Some(res) = highlight_method_call_by_name_ref(sema, krate, &name_ref, edition) { + if let Some(res) = highlight_method_call_by_name_ref(sema, krate, &name_ref, is_unsafe_node) { return res; } let name_class = match NameRefClass::classify(sema, &name_ref) { Some(name_kind) => name_kind, None if syntactic_name_ref_highlighting => { - return highlight_name_ref_by_syntax(name_ref, sema, krate, edition) + return highlight_name_ref_by_syntax(name_ref, sema, krate, is_unsafe_node) } // FIXME: This is required for helper attributes used by proc-macros, as those do not map down // to anything when used. @@ -267,17 +315,20 @@ fn highlight_name_ref( let mut h = match name_class { NameRefClass::Definition(def, _) => { if let Definition::Local(local) = &def { - let name = local.name(db); - let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); - *binding_hash = Some(calc_binding_hash(&name, *shadow_count)) + if let Some(bindings_shadow_count) = bindings_shadow_count { + let name = local.name(sema.db); + let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); + *binding_hash = Some(calc_binding_hash(&name, *shadow_count)) + } }; - let mut h = highlight_def(sema, krate, def, edition); + let mut h = highlight_def(sema, krate, def, edition, true); match def { Definition::Local(local) if is_consumed_lvalue(name_ref.syntax(), &local, db) => { h |= HlMod::Consuming; } + // highlight unsafe traits as unsafe only in their implementations Definition::Trait(trait_) if trait_.is_unsafe(db) => { if ast::Impl::for_trait_name_ref(&name_ref) .is_some_and(|impl_| impl_.unsafe_token().is_some()) @@ -285,23 +336,66 @@ fn highlight_name_ref( h |= HlMod::Unsafe; } } - Definition::Field(field) => { - if let Some(parent) = name_ref.syntax().parent() { - if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) { - if let hir::VariantDef::Union(_) = field.parent_def(db) { - h |= HlMod::Unsafe; - } - } + Definition::Function(_) => { + let is_unsafe = name_ref + .syntax() + .parent() + .and_then(|it| ast::PathSegment::cast(it)?.parent_path().syntax().parent()) + .and_then(ast::PathExpr::cast) + .and_then(|it| it.syntax().parent()) + .and_then(ast::CallExpr::cast) + .is_some_and(|it| { + is_unsafe_node(AstPtr::new(&ast::Expr::CallExpr(it)).wrap_left()) + }); + if is_unsafe { + h |= HlMod::Unsafe; } } Definition::Macro(_) => { - if let Some(macro_call) = - ide_db::syntax_helpers::node_ext::full_path_of_name_ref(&name_ref) - .and_then(|it| it.syntax().parent().and_then(ast::MacroCall::cast)) - { - if sema.is_unsafe_macro_call(¯o_call) { - h |= HlMod::Unsafe; - } + let is_unsafe = name_ref + .syntax() + .parent() + .and_then(|it| ast::PathSegment::cast(it)?.parent_path().syntax().parent()) + .and_then(ast::MacroCall::cast) + .is_some_and(|macro_call| sema.is_unsafe_macro_call(¯o_call)); + if is_unsafe { + h |= HlMod::Unsafe; + } + } + Definition::Field(_) => { + let is_unsafe = name_ref + .syntax() + .parent() + .and_then(|it| { + match_ast! { match it { + ast::FieldExpr(expr) => Some(is_unsafe_node(AstPtr::new(&Either::Left(expr.into())))), + ast::RecordPatField(pat) => { + walk_pat(&pat.pat()?, &mut |pat| { + if is_unsafe_node(AstPtr::new(&Either::Right(pat))) { + ControlFlow::Break(true) + } + else {ControlFlow::Continue(())} + }).break_value() + }, + _ => None, + }} + }) + .unwrap_or(false); + if is_unsafe { + h |= HlMod::Unsafe; + } + } + Definition::Static(_) => { + let is_unsafe = name_ref + .syntax() + .parent() + .and_then(|it| ast::PathSegment::cast(it)?.parent_path().syntax().parent()) + .and_then(ast::PathExpr::cast) + .is_some_and(|it| { + is_unsafe_node(AstPtr::new(&ast::Expr::PathExpr(it)).wrap_left()) + }); + if is_unsafe { + h |= HlMod::Unsafe; } } _ => (), @@ -310,7 +404,7 @@ fn highlight_name_ref( h } NameRefClass::FieldShorthand { field_ref, .. } => { - highlight_def(sema, krate, field_ref.into(), edition) + highlight_def(sema, krate, field_ref.into(), edition, true) } NameRefClass::ExternCrateShorthand { decl, krate: resolved_krate } => { let mut h = HlTag::Symbol(SymbolKind::Module).into(); @@ -342,22 +436,25 @@ fn highlight_name_ref( fn highlight_name( sema: &Semantics<'_, RootDatabase>, - bindings_shadow_count: &mut FxHashMap, + bindings_shadow_count: Option<&mut FxHashMap>, binding_hash: &mut Option, + is_unsafe_node: &impl Fn(AstPtr>) -> bool, krate: hir::Crate, name: ast::Name, edition: Edition, ) -> Highlight { let name_kind = NameClass::classify(sema, &name); if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind { - let name = local.name(sema.db); - let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); - *shadow_count += 1; - *binding_hash = Some(calc_binding_hash(&name, *shadow_count)) + if let Some(bindings_shadow_count) = bindings_shadow_count { + let name = local.name(sema.db); + let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); + *shadow_count += 1; + *binding_hash = Some(calc_binding_hash(&name, *shadow_count)) + } }; match name_kind { Some(NameClass::Definition(def)) => { - let mut h = highlight_def(sema, krate, def, edition) | HlMod::Definition; + let mut h = highlight_def(sema, krate, def, edition, false) | HlMod::Definition; if let Definition::Trait(trait_) = &def { if trait_.is_unsafe(sema.db) { h |= HlMod::Unsafe; @@ -365,10 +462,14 @@ fn highlight_name( } h } - Some(NameClass::ConstReference(def)) => highlight_def(sema, krate, def, edition), - Some(NameClass::PatFieldShorthand { field_ref, .. }) => { + Some(NameClass::ConstReference(def)) => highlight_def(sema, krate, def, edition, true), + Some(NameClass::PatFieldShorthand { .. }) => { let mut h = HlTag::Symbol(SymbolKind::Field).into(); - if let hir::VariantDef::Union(_) = field_ref.parent_def(sema.db) { + let is_unsafe = + name.syntax().parent().and_then(ast::IdentPat::cast).is_some_and(|it| { + is_unsafe_node(AstPtr::new(&ast::Pat::IdentPat(it)).wrap_right()) + }); + if is_unsafe { h |= HlMod::Unsafe; } h @@ -386,6 +487,7 @@ pub(super) fn highlight_def( krate: hir::Crate, def: Definition, edition: Edition, + is_ref: bool, ) -> Highlight { let db = sema.db; let mut h = match def { @@ -439,7 +541,7 @@ pub(super) fn highlight_def( // We probably should consider checking the current function, but I found no easy way to do // that (also I'm worried about perf). There's also an instance below. // FIXME: This should be the edition of the call. - if func.is_unsafe_to_call(db, None, edition) { + if !is_ref && func.is_unsafe_to_call(db, None, edition) { h |= HlMod::Unsafe; } if func.is_async(db) { @@ -509,7 +611,9 @@ pub(super) fn highlight_def( if s.is_mut(db) { h |= HlMod::Mutable; - h |= HlMod::Unsafe; + if !is_ref { + h |= HlMod::Unsafe; + } } h @@ -587,23 +691,24 @@ fn highlight_method_call_by_name_ref( sema: &Semantics<'_, RootDatabase>, krate: hir::Crate, name_ref: &ast::NameRef, - edition: Edition, + is_unsafe_node: &impl Fn(AstPtr>) -> bool, ) -> Option { let mc = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; - highlight_method_call(sema, krate, &mc, edition) + highlight_method_call(sema, krate, &mc, is_unsafe_node) } fn highlight_method_call( sema: &Semantics<'_, RootDatabase>, krate: hir::Crate, method_call: &ast::MethodCallExpr, - edition: Edition, + is_unsafe_node: &impl Fn(AstPtr>) -> bool, ) -> Option { let func = sema.resolve_method_call(method_call)?; let mut h = SymbolKind::Method.into(); - if func.is_unsafe_to_call(sema.db, None, edition) || sema.is_unsafe_method_call(method_call) { + let is_unsafe = is_unsafe_node(AstPtr::new(method_call).upcast::().wrap_left()); + if is_unsafe { h |= HlMod::Unsafe; } if func.is_async(sema.db) { @@ -695,7 +800,7 @@ fn highlight_name_ref_by_syntax( name: ast::NameRef, sema: &Semantics<'_, RootDatabase>, krate: hir::Crate, - edition: Edition, + is_unsafe_node: &impl Fn(AstPtr>) -> bool, ) -> Highlight { let default = HlTag::UnresolvedReference; @@ -707,19 +812,13 @@ fn highlight_name_ref_by_syntax( match parent.kind() { EXTERN_CRATE => HlTag::Symbol(SymbolKind::Module) | HlMod::CrateRoot, METHOD_CALL_EXPR => ast::MethodCallExpr::cast(parent) - .and_then(|it| highlight_method_call(sema, krate, &it, edition)) + .and_then(|it| highlight_method_call(sema, krate, &it, is_unsafe_node)) .unwrap_or_else(|| SymbolKind::Method.into()), FIELD_EXPR => { let h = HlTag::Symbol(SymbolKind::Field); - let is_union = ast::FieldExpr::cast(parent) - .and_then(|field_expr| sema.resolve_field(&field_expr)) - .is_some_and(|field| match field { - Either::Left(field) => { - matches!(field.parent_def(sema.db), hir::VariantDef::Union(_)) - } - Either::Right(_) => false, - }); - if is_union { + let is_unsafe = ast::Expr::cast(parent) + .is_some_and(|it| is_unsafe_node(AstPtr::new(&it).wrap_left())); + if is_unsafe { h | HlMod::Unsafe } else { h.into() diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs index 47ad54759a87..07d40bafeba1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs @@ -88,12 +88,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -115,6 +109,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html index 2bc22f960bd5..c8ffa9e85583 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } @@ -49,26 +44,26 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd unsafe { let foo = 1; let mut o = 0; - core::arch::asm!( + core::arch::asm!( "%input = OpLoad _ {0}", concat!("%result = ", "bar", " _ %input"), "OpStore {1} %result", in(reg) &foo, in(reg) &mut o, - ); + ); let thread_id: usize; - core::arch::asm!(" + core::arch::asm!(" mov {0}, gs:[0x30] mov {0}, [{0}+0x48] - ", out(reg) thread_id, options(pure, readonly, nostack)); + ", out(reg) thread_id, options(pure, readonly, nostack)); static UNMAP_BASE: usize; const MEM_RELEASE: usize; static VirtualFree: usize; const OffPtr: usize; const OffFn: usize; - core::arch::asm!(" + core::arch::asm!(" push {free_type} push {free_size} push {base} @@ -82,26 +77,26 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd jmp {virtual_free} ", - off_ptr = const OffPtr, - off_fn = const OffFn, + off_ptr = const OffPtr, + off_fn = const OffFn, - free_size = const 0, - free_type = const MEM_RELEASE, + free_size = const 0, + free_type = const MEM_RELEASE, virtual_free = sym VirtualFree, base = sym UNMAP_BASE, options(noreturn), - ); + ); } } // taken from https://github.com/rust-embedded/cortex-m/blob/47921b51f8b960344fcfa1255a50a0d19efcde6d/cortex-m/src/asm.rs#L254-L274 #[inline] -pub unsafe fn bootstrap(msp: *const u32, rv: *const u32) -> ! { +pub unsafe fn bootstrap(msp: *const u32, rv: *const u32) -> ! { // Ensure thumb mode is set. let rv = (rv as u32) | 1; let msp = msp as u32; - core::arch::asm!( + core::arch::asm!( "mrs {tmp}, CONTROL", "bics {tmp}, {spsel}", "msr CONTROL, {tmp}", @@ -115,5 +110,5 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd msp = in(reg) msp, rv = in(reg) rv, options(noreturn, nomem, nostack), - ); + ); }

\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html index 9c7f03fc1587..faace6eaff86 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html index e1d51dc0b71e..d59f4caa97f6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html index af29af3f03ca..3beda396da80 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } @@ -58,7 +53,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd foo!(Bar); fn func(_: y::Bar) { mod inner { - struct Innerest<const C: usize> { field: [(); {C}] } + struct Innerest<const C: usize> { field: [(); {C}] } } } } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html index 6d8f6b3c6e32..9c7324eafa3a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } @@ -50,21 +45,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd $($tt)* }; } -const CONST_ITEM: *const () = &raw const (); -const fn const_fn<const CONST_PARAM: ()>(const {}: const fn()) where (): const ConstTrait { +const CONST_ITEM: *const () = &raw const (); +const fn const_fn<const CONST_PARAM: ()>(const {}: const fn()) where (): const ConstTrait { CONST_ITEM; CONST_PARAM; const { - const || {} + const || {} } id!( CONST_ITEM; CONST_PARAM; const { - const || {} + const || {} }; - &raw const (); - const + &raw const (); + const ); ().assoc_const_method(); } @@ -80,6 +75,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd macro_rules! unsafe_deref { () => { - *(&() as *const ()) + *(&() as *const ()) }; } \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html index 63e1560b9210..4613c65ee614 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html index dfad3a6605ce..b1b2c659a22f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index 263e4545fb5a..c8c8c5dba4c4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } @@ -129,7 +124,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd /// /// ``` /// // functions - /// fn foo<T, const X: usize>(arg: i32) { + /// fn foo<T, const X: usize>(arg: i32) { /// let x: T = X; /// } /// ``` diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html index fe5f5ab6a9a2..5399f83085ed 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index eb532a5639d4..00925bd81ed8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } @@ -109,7 +104,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd loop {} } -fn const_param<const FOO: usize>() -> usize { +fn const_param<const FOO: usize>() -> usize { const_param::<{ FOO }>(); FOO } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html index 1f9422161de4..3b468ab6dba6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html index a846addba3f2..5ef64465c983 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html index c3377614d729..0407e6896e97 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html index 9b22500396bd..f39d033c76f7 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html index 9b22500396bd..f39d033c76f7 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html index ac8353120e87..721185a1a847 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html index 694e54d2fa8c..b2c82051eb16 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html index 8428b8158003..618ea2171b52 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html index f224435e9618..c3145941c3e3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_inline.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_inline.html index 947d1bf1e357..9996a871580f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_inline.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_inline.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_outline.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_outline.html index 0fe2b6f274d0..dc9e1de4a420 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_outline.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_outline.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_operators.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_operators.html index c60b6ab27bba..9c42401ed077 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_operators.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_operators.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html index a4449b5d8d8e..7f6b4c2c880e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index 539c74f6b57e..f7d798208037 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } @@ -169,12 +164,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd toho!("{}fmt", 0); let i: u64 = 3; let o: u64; - core::arch::asm!( + core::arch::asm!( "mov {0}, {1}", "add {0}, 5", out(reg) o, in(reg) i, - ); + ); const CONSTANT: () = (): let mut m = (); diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html index 9a46d9f4025d..44905831e36a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html @@ -14,12 +14,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .string_literal { color: #CC9393; } .field { color: #94BFF3; } .function { color: #93E0E3; } -.function.unsafe { color: #BC8383; } -.trait.unsafe { color: #BC8383; } -.operator.unsafe { color: #BC8383; } -.mutable.unsafe { color: #BC8383; text-decoration: underline; } -.keyword.unsafe { color: #BC8383; font-weight: bold; } -.macro.unsafe { color: #BC8383; } .parameter { color: #94BFF3; } .text { color: #DCDCCC; } .type { color: #7CB8BB; } @@ -41,6 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; } .reference { font-style: italic; font-weight: bold; } .const { font-weight: bolder; } +.unsafe { color: #BC8383; } .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } @@ -52,78 +47,82 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } macro_rules! unsafe_deref { () => { - *(&() as *const ()) + *(&() as *const ()) }; } -static mut MUT_GLOBAL: Struct = Struct { field: 0 }; -static GLOBAL: Struct = Struct { field: 0 }; -unsafe fn unsafe_fn() {} union Union { - a: u32, - b: f32, + field: u32, } struct Struct { field: i32 } + +static mut MUT_GLOBAL: Struct = Struct { field: 0 }; +unsafe fn unsafe_fn() {} + impl Struct { unsafe fn unsafe_method(&self) {} } -#[repr(packed)] -struct Packed { - a: u16, -} - unsafe trait UnsafeTrait {} -unsafe impl UnsafeTrait for Packed {} +unsafe impl UnsafeTrait for Union {} impl !UnsafeTrait for () {} fn unsafe_trait_bound<T: UnsafeTrait>(_: T) {} -trait DoTheAutoref { - fn calls_autoref(&self); -} - -impl DoTheAutoref for u16 { - fn calls_autoref(&self) {} +extern { + static EXTERN_STATIC: (); } fn main() { - let x = &5 as *const _ as *const usize; - let u = Union { b: 0 }; + let x: *const usize; + let u: Union; + // id should be safe here, but unsafe_deref should not id! { - unsafe { unsafe_deref!() } + unsafe { unsafe_deref!() } }; unsafe { - unsafe_deref!(); - id! { unsafe_deref!() }; + // unsafe macro calls + unsafe_deref!(); + id! { unsafe_deref!() }; // unsafe fn and method calls - unsafe_fn(); - let b = u.b; - match u { - Union { b: 0 } => (), - Union { a } => (), - } - Struct { field: 0 }.unsafe_method(); + unsafe_fn(); + self::unsafe_fn(); + (unsafe_fn as unsafe fn())(); + Struct { field: 0 }.unsafe_method(); + + u.field; + &u.field; + &raw const u.field; + // this should be safe! + let Union { field: _ }; + // but not these + let Union { field }; + let Union { field: true }; + let Union { field: field }; + let Union { field: ref field }; + let Union { field: (ref field | 0) }; // unsafe deref - *x; + *&raw const*&*x; // unsafe access to a static mut MUT_GLOBAL.field; - GLOBAL.field; + &MUT_GLOBAL.field; + &raw const MUT_GLOBAL.field; + MUT_GLOBAL; + &MUT_GLOBAL; + &raw const MUT_GLOBAL; + EXTERN_STATIC; + &EXTERN_STATIC; + &raw const EXTERN_STATIC; - // unsafe ref of packed fields - let packed = Packed { a: 0 }; - let a = &packed.a; - let ref a = packed.a; - let Packed { ref a } = packed; - let Packed { a: ref _a } = packed; - - // unsafe auto ref of packed field - packed.a.calls_autoref(); + core::arch::asm!( + "push {base}", + base = const 0 + ); } } \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index e48ca86c46b5..504a1c970efb 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -589,7 +589,7 @@ fn main() { fn test_unsafe_highlighting() { check_highlighting( r#" -//- minicore: sized +//- minicore: sized, asm macro_rules! id { ($($tt:tt)*) => { $($tt)* @@ -600,76 +600,80 @@ macro_rules! unsafe_deref { *(&() as *const ()) }; } -static mut MUT_GLOBAL: Struct = Struct { field: 0 }; -static GLOBAL: Struct = Struct { field: 0 }; -unsafe fn unsafe_fn() {} union Union { - a: u32, - b: f32, + field: u32, } struct Struct { field: i32 } + +static mut MUT_GLOBAL: Struct = Struct { field: 0 }; +unsafe fn unsafe_fn() {} + impl Struct { unsafe fn unsafe_method(&self) {} } -#[repr(packed)] -struct Packed { - a: u16, -} - unsafe trait UnsafeTrait {} -unsafe impl UnsafeTrait for Packed {} +unsafe impl UnsafeTrait for Union {} impl !UnsafeTrait for () {} fn unsafe_trait_bound(_: T) {} -trait DoTheAutoref { - fn calls_autoref(&self); -} - -impl DoTheAutoref for u16 { - fn calls_autoref(&self) {} +extern { + static EXTERN_STATIC: (); } fn main() { - let x = &5 as *const _ as *const usize; - let u = Union { b: 0 }; + let x: *const usize; + let u: Union; + // id should be safe here, but unsafe_deref should not id! { unsafe { unsafe_deref!() } }; unsafe { + // unsafe macro calls unsafe_deref!(); id! { unsafe_deref!() }; // unsafe fn and method calls unsafe_fn(); - let b = u.b; - match u { - Union { b: 0 } => (), - Union { a } => (), - } + self::unsafe_fn(); + (unsafe_fn as unsafe fn())(); Struct { field: 0 }.unsafe_method(); + u.field; + &u.field; + &raw const u.field; + // this should be safe! + let Union { field: _ }; + // but not these + let Union { field }; + let Union { field: true }; + let Union { field: field }; + let Union { field: ref field }; + let Union { field: (ref field | 0) }; + // unsafe deref - *x; + *&raw const*&*x; // unsafe access to a static mut MUT_GLOBAL.field; - GLOBAL.field; + &MUT_GLOBAL.field; + &raw const MUT_GLOBAL.field; + MUT_GLOBAL; + &MUT_GLOBAL; + &raw const MUT_GLOBAL; + EXTERN_STATIC; + &EXTERN_STATIC; + &raw const EXTERN_STATIC; - // unsafe ref of packed fields - let packed = Packed { a: 0 }; - let a = &packed.a; - let ref a = packed.a; - let Packed { ref a } = packed; - let Packed { a: ref _a } = packed; - - // unsafe auto ref of packed field - packed.a.calls_autoref(); + core::arch::asm!( + "push {base}", + base$0 = const 0 + ); } } "#, diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index c2063df50689..1be0dda76cdd 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -443,7 +443,7 @@ fn main() { ### `convert_closure_to_fn` -**Source:** [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L27) +**Source:** [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L25) This converts a closure to a freestanding function, changing all captures to parameters. @@ -1348,7 +1348,7 @@ fn main() { ### `flip_or_pattern` **Source:** [flip_or_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_or_pattern.rs#L9) -Flips two trait bounds. +Flips two patterns in an or-pattern. #### Before ```rust @@ -2278,7 +2278,7 @@ fn bar() { ### `inline_local_variable` -**Source:** [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L21) +**Source:** [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L17) Inlines a local variable. From 7a31456c1ce6e9bbf878faf225422bd31ad09e9b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Mar 2025 23:25:59 +1100 Subject: [PATCH 688/991] Make `field_match_pairs` push its output nodes to a vector --- .../src/builder/matches/match_pair.rs | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 10b43390eb28..cdac35ea0c74 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -9,24 +9,21 @@ use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder}; use crate::builder::matches::{FlatPat, MatchPairTree, TestCase}; impl<'a, 'tcx> Builder<'a, 'tcx> { - /// Builds and returns [`MatchPairTree`] subtrees, one for each pattern in + /// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in /// `subpatterns`, representing the fields of a [`PatKind::Variant`] or /// [`PatKind::Leaf`]. /// /// Used internally by [`MatchPairTree::for_pattern`]. fn field_match_pairs( &mut self, + match_pairs: &mut Vec>, place: PlaceBuilder<'tcx>, subpatterns: &[FieldPat<'tcx>], - ) -> Vec> { - subpatterns - .iter() - .map(|fieldpat| { - let place = - place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty)); - MatchPairTree::for_pattern(place, &fieldpat.pattern, self) - }) - .collect() + ) { + for fieldpat in subpatterns { + let place = place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty)); + match_pairs.push(MatchPairTree::for_pattern(place, &fieldpat.pattern, self)); + } } /// Builds [`MatchPairTree`] subtrees for the prefix/middle/suffix parts of an @@ -215,7 +212,7 @@ impl<'tcx> MatchPairTree<'tcx> { PatKind::Variant { adt_def, variant_index, args, ref subpatterns } => { let downcast_place = place_builder.downcast(adt_def, variant_index); // `(x as Variant)` - subpairs = cx.field_match_pairs(downcast_place, subpatterns); + cx.field_match_pairs(&mut subpairs, downcast_place, subpatterns); let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { i == variant_index @@ -233,7 +230,7 @@ impl<'tcx> MatchPairTree<'tcx> { } PatKind::Leaf { ref subpatterns } => { - subpairs = cx.field_match_pairs(place_builder, subpatterns); + cx.field_match_pairs(&mut subpairs, place_builder, subpatterns); default_irrefutable() } From 281455add74530e23af760d60f6665a6901afc8b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Mar 2025 23:25:59 +1100 Subject: [PATCH 689/991] Make `MatchPairTree::for_pattern` push its output node to a vector --- .../src/builder/matches/match_pair.rs | 39 ++++++++++--------- .../src/builder/matches/mod.rs | 3 +- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index cdac35ea0c74..7252dadc3202 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -22,7 +22,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { for fieldpat in subpatterns { let place = place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty)); - match_pairs.push(MatchPairTree::for_pattern(place, &fieldpat.pattern, self)); + MatchPairTree::for_pattern(place, &fieldpat.pattern, self, match_pairs); } } @@ -53,11 +53,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ((prefix.len() + suffix.len()).try_into().unwrap(), false) }; - match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| { + for (idx, subpattern) in prefix.iter().enumerate() { let elem = ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false }; - MatchPairTree::for_pattern(place.clone_project(elem), subpattern, self) - })); + let place = place.clone_project(elem); + MatchPairTree::for_pattern(place, subpattern, self, match_pairs); + } if let Some(subslice_pat) = opt_slice { let suffix_len = suffix.len() as u64; @@ -66,10 +67,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { to: if exact_size { min_length - suffix_len } else { suffix_len }, from_end: !exact_size, }); - match_pairs.push(MatchPairTree::for_pattern(subslice, subslice_pat, self)); + MatchPairTree::for_pattern(subslice, subslice_pat, self, match_pairs); } - match_pairs.extend(suffix.iter().rev().enumerate().map(|(idx, subpattern)| { + for (idx, subpattern) in suffix.iter().rev().enumerate() { let end_offset = (idx + 1) as u64; let elem = ProjectionElem::ConstantIndex { offset: if exact_size { min_length - end_offset } else { end_offset }, @@ -77,8 +78,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { from_end: !exact_size, }; let place = place.clone_project(elem); - MatchPairTree::for_pattern(place, subpattern, self) - })); + MatchPairTree::for_pattern(place, subpattern, self, match_pairs); + } } } @@ -89,7 +90,8 @@ impl<'tcx> MatchPairTree<'tcx> { mut place_builder: PlaceBuilder<'tcx>, pattern: &Pat<'tcx>, cx: &mut Builder<'_, 'tcx>, - ) -> MatchPairTree<'tcx> { + match_pairs: &mut Vec, // Newly-created nodes are added to this vector + ) { // Force the place type to the pattern's type. // FIXME(oli-obk): can we use this to simplify slice/array pattern hacks? if let Some(resolved) = place_builder.resolve_upvar(cx) { @@ -142,7 +144,7 @@ impl<'tcx> MatchPairTree<'tcx> { variance, }); - subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx)); + MatchPairTree::for_pattern(place_builder, subpattern, cx, &mut subpairs); TestCase::Irrefutable { ascription, binding: None } } @@ -156,13 +158,13 @@ impl<'tcx> MatchPairTree<'tcx> { if let Some(subpattern) = subpattern.as_ref() { // this is the `x @ P` case; have to keep matching against `P` now - subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx)); + MatchPairTree::for_pattern(place_builder, subpattern, cx, &mut subpairs); } TestCase::Irrefutable { ascription: None, binding } } PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => { - subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx)); + MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs); default_irrefutable() } PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => { @@ -189,7 +191,7 @@ impl<'tcx> MatchPairTree<'tcx> { super::Ascription { annotation, source, variance: ty::Contravariant } }); - subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx)); + MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs); TestCase::Irrefutable { ascription, binding: None } } @@ -235,7 +237,7 @@ impl<'tcx> MatchPairTree<'tcx> { } PatKind::Deref { ref subpattern } => { - subpairs.push(MatchPairTree::for_pattern(place_builder.deref(), subpattern, cx)); + MatchPairTree::for_pattern(place_builder.deref(), subpattern, cx, &mut subpairs); default_irrefutable() } @@ -246,23 +248,24 @@ impl<'tcx> MatchPairTree<'tcx> { Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, subpattern.ty, mutability), pattern.span, ); - subpairs.push(MatchPairTree::for_pattern( + MatchPairTree::for_pattern( PlaceBuilder::from(temp).deref(), subpattern, cx, - )); + &mut subpairs, + ); TestCase::Deref { temp, mutability } } PatKind::Never => TestCase::Never, }; - MatchPairTree { + match_pairs.push(MatchPairTree { place, test_case, subpairs, pattern_ty: pattern.ty, pattern_span: pattern.span, - } + }); } } diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index d05d5b151ff4..e41001193d54 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1009,7 +1009,8 @@ impl<'tcx> FlatPat<'tcx> { /// for the given pattern. fn new(place: PlaceBuilder<'tcx>, pattern: &Pat<'tcx>, cx: &mut Builder<'_, 'tcx>) -> Self { // First, recursively build a tree of match pairs for the given pattern. - let mut match_pairs = vec![MatchPairTree::for_pattern(place, pattern, cx)]; + let mut match_pairs = vec![]; + MatchPairTree::for_pattern(place, pattern, cx, &mut match_pairs); let mut extra_data = PatternExtraData { span: pattern.span, bindings: Vec::new(), From ef442738386e8daf318f177bd6a551529e99b0da Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Mar 2025 23:25:59 +1100 Subject: [PATCH 690/991] Populate pattern bindings/ascriptions while building `MatchPairTree` --- .../src/builder/matches/match_pair.rs | 130 +++++++++++++----- .../src/builder/matches/mod.rs | 8 +- .../src/builder/matches/simplify.rs | 8 +- 3 files changed, 100 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 7252dadc3202..89d8189cee03 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -6,7 +6,7 @@ use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use crate::builder::Builder; use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder}; -use crate::builder::matches::{FlatPat, MatchPairTree, TestCase}; +use crate::builder::matches::{FlatPat, MatchPairTree, PatternExtraData, TestCase}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in @@ -17,12 +17,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn field_match_pairs( &mut self, match_pairs: &mut Vec>, + extra_data: &mut PatternExtraData<'tcx>, place: PlaceBuilder<'tcx>, subpatterns: &[FieldPat<'tcx>], ) { for fieldpat in subpatterns { let place = place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty)); - MatchPairTree::for_pattern(place, &fieldpat.pattern, self, match_pairs); + MatchPairTree::for_pattern(place, &fieldpat.pattern, self, match_pairs, extra_data); } } @@ -33,6 +34,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn prefix_slice_suffix( &mut self, match_pairs: &mut Vec>, + extra_data: &mut PatternExtraData<'tcx>, place: &PlaceBuilder<'tcx>, prefix: &[Pat<'tcx>], opt_slice: &Option>>, @@ -57,7 +59,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let elem = ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false }; let place = place.clone_project(elem); - MatchPairTree::for_pattern(place, subpattern, self, match_pairs); + MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data) } if let Some(subslice_pat) = opt_slice { @@ -67,7 +69,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { to: if exact_size { min_length - suffix_len } else { suffix_len }, from_end: !exact_size, }); - MatchPairTree::for_pattern(subslice, subslice_pat, self, match_pairs); + MatchPairTree::for_pattern(subslice, subslice_pat, self, match_pairs, extra_data); } for (idx, subpattern) in suffix.iter().rev().enumerate() { @@ -78,7 +80,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { from_end: !exact_size, }; let place = place.clone_project(elem); - MatchPairTree::for_pattern(place, subpattern, self, match_pairs); + MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data) } } } @@ -86,11 +88,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { impl<'tcx> MatchPairTree<'tcx> { /// Recursively builds a match pair tree for the given pattern and its /// subpatterns. - pub(in crate::builder) fn for_pattern( + pub(super) fn for_pattern( mut place_builder: PlaceBuilder<'tcx>, pattern: &Pat<'tcx>, cx: &mut Builder<'_, 'tcx>, match_pairs: &mut Vec, // Newly-created nodes are added to this vector + extra_data: &mut PatternExtraData<'tcx>, // Bindings/ascriptions are added here ) { // Force the place type to the pattern's type. // FIXME(oli-obk): can we use this to simplify slice/array pattern hacks? @@ -113,7 +116,7 @@ impl<'tcx> MatchPairTree<'tcx> { } let place = place_builder.try_to_place(cx); - let default_irrefutable = || TestCase::Irrefutable { binding: None, ascription: None }; + let default_irrefutable = || TestCase::Irrefutable {}; let mut subpairs = Vec::new(); let test_case = match pattern.kind { PatKind::Wild | PatKind::Error(_) => default_irrefutable(), @@ -137,39 +140,77 @@ impl<'tcx> MatchPairTree<'tcx> { ref subpattern, .. } => { - // Apply the type ascription to the value at `match_pair.place` - let ascription = place.map(|source| super::Ascription { - annotation: annotation.clone(), - source, - variance, - }); + MatchPairTree::for_pattern( + place_builder, + subpattern, + cx, + &mut subpairs, + extra_data, + ); - MatchPairTree::for_pattern(place_builder, subpattern, cx, &mut subpairs); - TestCase::Irrefutable { ascription, binding: None } + // Apply the type ascription to the value at `match_pair.place` + if let Some(source) = place { + let annotation = annotation.clone(); + extra_data.ascriptions.push(super::Ascription { source, annotation, variance }); + } + + default_irrefutable() } PatKind::Binding { mode, var, ref subpattern, .. } => { - let binding = place.map(|source| super::Binding { - span: pattern.span, - source, - var_id: var, - binding_mode: mode, - }); + // In order to please the borrow checker, when lowering a pattern + // like `x @ subpat` we must establish any bindings in `subpat` + // before establishing the binding for `x`. + // + // For example (from #69971): + // + // ```ignore (illustrative) + // struct NonCopyStruct { + // copy_field: u32, + // } + // + // fn foo1(x: NonCopyStruct) { + // let y @ NonCopyStruct { copy_field: z } = x; + // // the above should turn into + // let z = x.copy_field; + // let y = x; + // } + // ``` + // First, recurse into the subpattern, if any. if let Some(subpattern) = subpattern.as_ref() { // this is the `x @ P` case; have to keep matching against `P` now - MatchPairTree::for_pattern(place_builder, subpattern, cx, &mut subpairs); + MatchPairTree::for_pattern( + place_builder, + subpattern, + cx, + &mut subpairs, + extra_data, + ); } - TestCase::Irrefutable { ascription: None, binding } + + // Then push this binding, after any bindings in the subpattern. + if let Some(source) = place { + extra_data.bindings.push(super::Binding { + span: pattern.span, + source, + var_id: var, + binding_mode: mode, + }); + } + + default_irrefutable() } PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => { - MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs); + MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data); default_irrefutable() } PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => { + MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data); + // Apply a type ascription for the inline constant to the value at `match_pair.place` - let ascription = place.map(|source| { + if let Some(source) = place { let span = pattern.span; let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id()); let args = ty::InlineConstArgs::new( @@ -188,19 +229,33 @@ impl<'tcx> MatchPairTree<'tcx> { span, user_ty: Box::new(user_ty), }; - super::Ascription { annotation, source, variance: ty::Contravariant } - }); + let variance = ty::Contravariant; + extra_data.ascriptions.push(super::Ascription { annotation, source, variance }); + } - MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs); - TestCase::Irrefutable { ascription, binding: None } + default_irrefutable() } PatKind::Array { ref prefix, ref slice, ref suffix } => { - cx.prefix_slice_suffix(&mut subpairs, &place_builder, prefix, slice, suffix); + cx.prefix_slice_suffix( + &mut subpairs, + extra_data, + &place_builder, + prefix, + slice, + suffix, + ); default_irrefutable() } PatKind::Slice { ref prefix, ref slice, ref suffix } => { - cx.prefix_slice_suffix(&mut subpairs, &place_builder, prefix, slice, suffix); + cx.prefix_slice_suffix( + &mut subpairs, + extra_data, + &place_builder, + prefix, + slice, + suffix, + ); if prefix.is_empty() && slice.is_some() && suffix.is_empty() { default_irrefutable() @@ -214,7 +269,7 @@ impl<'tcx> MatchPairTree<'tcx> { PatKind::Variant { adt_def, variant_index, args, ref subpatterns } => { let downcast_place = place_builder.downcast(adt_def, variant_index); // `(x as Variant)` - cx.field_match_pairs(&mut subpairs, downcast_place, subpatterns); + cx.field_match_pairs(&mut subpairs, extra_data, downcast_place, subpatterns); let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { i == variant_index @@ -232,12 +287,18 @@ impl<'tcx> MatchPairTree<'tcx> { } PatKind::Leaf { ref subpatterns } => { - cx.field_match_pairs(&mut subpairs, place_builder, subpatterns); + cx.field_match_pairs(&mut subpairs, extra_data, place_builder, subpatterns); default_irrefutable() } PatKind::Deref { ref subpattern } => { - MatchPairTree::for_pattern(place_builder.deref(), subpattern, cx, &mut subpairs); + MatchPairTree::for_pattern( + place_builder.deref(), + subpattern, + cx, + &mut subpairs, + extra_data, + ); default_irrefutable() } @@ -253,6 +314,7 @@ impl<'tcx> MatchPairTree<'tcx> { subpattern, cx, &mut subpairs, + extra_data, ); TestCase::Deref { temp, mutability } } diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index e41001193d54..8c8f4c3c92c0 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1008,17 +1008,15 @@ impl<'tcx> FlatPat<'tcx> { /// Creates a `FlatPat` containing a simplified [`MatchPairTree`] list/forest /// for the given pattern. fn new(place: PlaceBuilder<'tcx>, pattern: &Pat<'tcx>, cx: &mut Builder<'_, 'tcx>) -> Self { - // First, recursively build a tree of match pairs for the given pattern. + // Recursively build a tree of match pairs for the given pattern. let mut match_pairs = vec![]; - MatchPairTree::for_pattern(place, pattern, cx, &mut match_pairs); let mut extra_data = PatternExtraData { span: pattern.span, bindings: Vec::new(), ascriptions: Vec::new(), is_never: pattern.is_never_pattern(), }; - // Recursively remove irrefutable match pairs, while recording their - // bindings/ascriptions, and sort or-patterns after other match pairs. + MatchPairTree::for_pattern(place, pattern, cx, &mut match_pairs, &mut extra_data); cx.simplify_match_pairs(&mut match_pairs, &mut extra_data); Self { match_pairs, extra_data } @@ -1238,7 +1236,7 @@ struct Ascription<'tcx> { /// - See [`Builder::expand_and_match_or_candidates`]. #[derive(Debug, Clone)] enum TestCase<'tcx> { - Irrefutable { binding: Option>, ascription: Option> }, + Irrefutable {}, Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx }, Constant { value: mir::Const<'tcx> }, Range(Arc>), diff --git a/compiler/rustc_mir_build/src/builder/matches/simplify.rs b/compiler/rustc_mir_build/src/builder/matches/simplify.rs index 15c860151dc9..f4bcf62a4b1f 100644 --- a/compiler/rustc_mir_build/src/builder/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/builder/matches/simplify.rs @@ -47,13 +47,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // match lowering forces us to lower bindings inside or-patterns last. for mut match_pair in mem::take(match_pairs) { self.simplify_match_pairs(&mut match_pair.subpairs, extra_data); - if let TestCase::Irrefutable { binding, ascription } = match_pair.test_case { - if let Some(binding) = binding { - extra_data.bindings.push(binding); - } - if let Some(ascription) = ascription { - extra_data.ascriptions.push(ascription); - } + if let TestCase::Irrefutable {} = match_pair.test_case { // Simplifiable pattern; we replace it with its already simplified subpairs. match_pairs.append(&mut match_pair.subpairs); } else { From 854feae88773da49f2b1a900f46668938cf52b85 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Mar 2025 23:25:59 +1100 Subject: [PATCH 691/991] Remove `TestCase::Irrefutable` --- .../src/builder/matches/match_pair.rs | 64 ++++++++++--------- .../src/builder/matches/mod.rs | 17 +---- .../src/builder/matches/simplify.rs | 9 +-- .../src/builder/matches/test.rs | 6 -- 4 files changed, 38 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 89d8189cee03..55487f48509f 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -116,24 +116,23 @@ impl<'tcx> MatchPairTree<'tcx> { } let place = place_builder.try_to_place(cx); - let default_irrefutable = || TestCase::Irrefutable {}; let mut subpairs = Vec::new(); let test_case = match pattern.kind { - PatKind::Wild | PatKind::Error(_) => default_irrefutable(), + PatKind::Wild | PatKind::Error(_) => None, - PatKind::Or { ref pats } => TestCase::Or { + PatKind::Or { ref pats } => Some(TestCase::Or { pats: pats.iter().map(|pat| FlatPat::new(place_builder.clone(), pat, cx)).collect(), - }, + }), PatKind::Range(ref range) => { if range.is_full_range(cx.tcx) == Some(true) { - default_irrefutable() + None } else { - TestCase::Range(Arc::clone(range)) + Some(TestCase::Range(Arc::clone(range))) } } - PatKind::Constant { value } => TestCase::Constant { value }, + PatKind::Constant { value } => Some(TestCase::Constant { value }), PatKind::AscribeUserType { ascription: Ascription { ref annotation, variance }, @@ -154,7 +153,7 @@ impl<'tcx> MatchPairTree<'tcx> { extra_data.ascriptions.push(super::Ascription { source, annotation, variance }); } - default_irrefutable() + None } PatKind::Binding { mode, var, ref subpattern, .. } => { @@ -199,12 +198,12 @@ impl<'tcx> MatchPairTree<'tcx> { }); } - default_irrefutable() + None } PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => { MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data); - default_irrefutable() + None } PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => { MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data); @@ -233,7 +232,7 @@ impl<'tcx> MatchPairTree<'tcx> { extra_data.ascriptions.push(super::Ascription { annotation, source, variance }); } - default_irrefutable() + None } PatKind::Array { ref prefix, ref slice, ref suffix } => { @@ -245,7 +244,7 @@ impl<'tcx> MatchPairTree<'tcx> { slice, suffix, ); - default_irrefutable() + None } PatKind::Slice { ref prefix, ref slice, ref suffix } => { cx.prefix_slice_suffix( @@ -258,12 +257,12 @@ impl<'tcx> MatchPairTree<'tcx> { ); if prefix.is_empty() && slice.is_some() && suffix.is_empty() { - default_irrefutable() + None } else { - TestCase::Slice { + Some(TestCase::Slice { len: prefix.len() + suffix.len(), variable_length: slice.is_some(), - } + }) } } @@ -279,16 +278,12 @@ impl<'tcx> MatchPairTree<'tcx> { .apply_ignore_module(cx.tcx, cx.infcx.typing_env(cx.param_env)) }) && (adt_def.did().is_local() || !adt_def.is_variant_list_non_exhaustive()); - if irrefutable { - default_irrefutable() - } else { - TestCase::Variant { adt_def, variant_index } - } + if irrefutable { None } else { Some(TestCase::Variant { adt_def, variant_index }) } } PatKind::Leaf { ref subpatterns } => { cx.field_match_pairs(&mut subpairs, extra_data, place_builder, subpatterns); - default_irrefutable() + None } PatKind::Deref { ref subpattern } => { @@ -299,7 +294,7 @@ impl<'tcx> MatchPairTree<'tcx> { &mut subpairs, extra_data, ); - default_irrefutable() + None } PatKind::DerefPattern { ref subpattern, mutability } => { @@ -316,18 +311,25 @@ impl<'tcx> MatchPairTree<'tcx> { &mut subpairs, extra_data, ); - TestCase::Deref { temp, mutability } + Some(TestCase::Deref { temp, mutability }) } - PatKind::Never => TestCase::Never, + PatKind::Never => Some(TestCase::Never), }; - match_pairs.push(MatchPairTree { - place, - test_case, - subpairs, - pattern_ty: pattern.ty, - pattern_span: pattern.span, - }); + if let Some(test_case) = test_case { + // This pattern is refutable, so push a new match-pair node. + match_pairs.push(MatchPairTree { + place, + test_case, + subpairs, + pattern_ty: pattern.ty, + pattern_span: pattern.span, + }) + } else { + // This pattern is irrefutable, so it doesn't need its own match-pair node. + // Just push its refutable subpatterns instead, if any. + match_pairs.extend(subpairs); + } } } diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 8c8f4c3c92c0..bb93482c0b6c 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1054,7 +1054,6 @@ struct Candidate<'tcx> { /// (see [`Builder::test_remaining_match_pairs_after_or`]). /// /// Invariants: - /// - All [`TestCase::Irrefutable`] patterns have been removed by simplification. /// - All or-patterns ([`TestCase::Or`]) have been sorted to the end. match_pairs: Vec>, @@ -1226,17 +1225,11 @@ struct Ascription<'tcx> { /// - [`Builder::pick_test_for_match_pair`] (to choose a test) /// - [`Builder::sort_candidate`] (to see how the test interacts with a match pair) /// -/// Two variants are unlike the others and deserve special mention: -/// -/// - [`Self::Irrefutable`] is only used temporarily when building a [`MatchPairTree`]. -/// They are then flattened away by [`Builder::simplify_match_pairs`], with any -/// bindings/ascriptions incorporated into the enclosing [`FlatPat`]. -/// - [`Self::Or`] are not tested directly like the other variants. Instead they -/// participate in or-pattern expansion, where they are transformed into subcandidates. -/// - See [`Builder::expand_and_match_or_candidates`]. +/// Note that or-patterns are not tested directly like the other variants. +/// Instead they participate in or-pattern expansion, where they are transformed into +/// subcandidates. See [`Builder::expand_and_match_or_candidates`]. #[derive(Debug, Clone)] enum TestCase<'tcx> { - Irrefutable {}, Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx }, Constant { value: mir::Const<'tcx> }, Range(Arc>), @@ -1269,10 +1262,6 @@ pub(crate) struct MatchPairTree<'tcx> { place: Option>, /// ... must pass this test... - /// - /// --- - /// Invariant: after creation and simplification in [`FlatPat::new`], - /// this must not be [`TestCase::Irrefutable`]. test_case: TestCase<'tcx>, /// ... and these subpairs must match. diff --git a/compiler/rustc_mir_build/src/builder/matches/simplify.rs b/compiler/rustc_mir_build/src/builder/matches/simplify.rs index f4bcf62a4b1f..5965b35b70c0 100644 --- a/compiler/rustc_mir_build/src/builder/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/builder/matches/simplify.rs @@ -47,13 +47,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // match lowering forces us to lower bindings inside or-patterns last. for mut match_pair in mem::take(match_pairs) { self.simplify_match_pairs(&mut match_pair.subpairs, extra_data); - if let TestCase::Irrefutable {} = match_pair.test_case { - // Simplifiable pattern; we replace it with its already simplified subpairs. - match_pairs.append(&mut match_pair.subpairs); - } else { - // Unsimplifiable pattern; we keep it. - match_pairs.push(match_pair); - } + // Unsimplifiable pattern; we keep it. + match_pairs.push(match_pair); } // Move or-patterns to the end, because they can result in us diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index a7a028bff97f..fe5ec32422cf 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -55,12 +55,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Or-patterns are not tested directly; instead they are expanded into subcandidates, // which are then distinguished by testing whatever non-or patterns they contain. TestCase::Or { .. } => bug!("or-patterns should have already been handled"), - - TestCase::Irrefutable { .. } => span_bug!( - match_pair.pattern_span, - "simplifiable pattern found: {:?}", - match_pair.pattern_span - ), }; Test { span: match_pair.pattern_span, kind } From e05df1cb5d13200314e95dde3e0f497d6c5a38aa Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Mar 2025 23:26:00 +1100 Subject: [PATCH 692/991] Remove the separate simplify step for match-pair trees What remained of this simplification process has been integrated into construction of the match-pair trees. --- .../src/builder/matches/mod.rs | 23 +++---- .../src/builder/matches/simplify.rs | 60 ------------------- .../src/builder/matches/test.rs | 2 +- 3 files changed, 14 insertions(+), 71 deletions(-) delete mode 100644 compiler/rustc_mir_build/src/builder/matches/simplify.rs diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index bb93482c0b6c..5d97bf13f869 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -26,7 +26,6 @@ use crate::builder::{ // helper functions, broken out by category: mod match_pair; -mod simplify; mod test; mod util; @@ -987,18 +986,16 @@ impl<'tcx> PatternExtraData<'tcx> { } /// A pattern in a form suitable for lowering the match tree, with all irrefutable -/// patterns simplified away, and or-patterns sorted to the end. +/// patterns simplified away. /// -/// Here, "flat" indicates that the pattern's match pairs have been recursively -/// simplified by [`Builder::simplify_match_pairs`]. They are not necessarily -/// flat in an absolute sense. +/// Here, "flat" indicates that irrefutable nodes in the pattern tree have been +/// recursively replaced with their refutable subpatterns. They are not +/// necessarily flat in an absolute sense. /// /// Will typically be incorporated into a [`Candidate`]. #[derive(Debug, Clone)] struct FlatPat<'tcx> { /// To match the pattern, all of these must be satisfied... - // Invariant: all the match pairs are recursively simplified. - // Invariant: or-patterns must be sorted to the end. match_pairs: Vec>, extra_data: PatternExtraData<'tcx>, @@ -1017,7 +1014,6 @@ impl<'tcx> FlatPat<'tcx> { is_never: pattern.is_never_pattern(), }; MatchPairTree::for_pattern(place, pattern, cx, &mut match_pairs, &mut extra_data); - cx.simplify_match_pairs(&mut match_pairs, &mut extra_data); Self { match_pairs, extra_data } } @@ -1124,7 +1120,7 @@ impl<'tcx> Candidate<'tcx> { /// Incorporates an already-simplified [`FlatPat`] into a new candidate. fn from_flat_pat(flat_pat: FlatPat<'tcx>, has_guard: bool) -> Self { - Candidate { + let mut this = Candidate { match_pairs: flat_pat.match_pairs, extra_data: flat_pat.extra_data, has_guard, @@ -1133,7 +1129,14 @@ impl<'tcx> Candidate<'tcx> { otherwise_block: None, pre_binding_block: None, false_edge_start_block: None, - } + }; + this.sort_match_pairs(); + this + } + + /// Restores the invariant that or-patterns must be sorted to the end. + fn sort_match_pairs(&mut self) { + self.match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. })); } /// Returns whether the first match pair of this candidate is an or-pattern. diff --git a/compiler/rustc_mir_build/src/builder/matches/simplify.rs b/compiler/rustc_mir_build/src/builder/matches/simplify.rs deleted file mode 100644 index 5965b35b70c0..000000000000 --- a/compiler/rustc_mir_build/src/builder/matches/simplify.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! Simplifying Candidates -//! -//! *Simplifying* a match pair `place @ pattern` means breaking it down -//! into bindings or other, simpler match pairs. For example: -//! -//! - `place @ (P1, P2)` can be simplified to `[place.0 @ P1, place.1 @ P2]` -//! - `place @ x` can be simplified to `[]` by binding `x` to `place` -//! -//! The `simplify_match_pairs` routine just repeatedly applies these -//! sort of simplifications until there is nothing left to -//! simplify. Match pairs cannot be simplified if they require some -//! sort of test: for example, testing which variant an enum is, or -//! testing a value against a constant. - -use std::mem; - -use tracing::{debug, instrument}; - -use crate::builder::Builder; -use crate::builder::matches::{MatchPairTree, PatternExtraData, TestCase}; - -impl<'a, 'tcx> Builder<'a, 'tcx> { - /// Simplify a list of match pairs so they all require a test. Stores relevant bindings and - /// ascriptions in `extra_data`. - #[instrument(skip(self), level = "debug")] - pub(super) fn simplify_match_pairs( - &mut self, - match_pairs: &mut Vec>, - extra_data: &mut PatternExtraData<'tcx>, - ) { - // In order to please the borrow checker, in a pattern like `x @ pat` we must lower the - // bindings in `pat` before `x`. E.g. (#69971): - // - // struct NonCopyStruct { - // copy_field: u32, - // } - // - // fn foo1(x: NonCopyStruct) { - // let y @ NonCopyStruct { copy_field: z } = x; - // // the above should turn into - // let z = x.copy_field; - // let y = x; - // } - // - // We therefore lower bindings from left-to-right, except we lower the `x` in `x @ pat` - // after any bindings in `pat`. This doesn't work for or-patterns: the current structure of - // match lowering forces us to lower bindings inside or-patterns last. - for mut match_pair in mem::take(match_pairs) { - self.simplify_match_pairs(&mut match_pair.subpairs, extra_data); - // Unsimplifiable pattern; we keep it. - match_pairs.push(match_pair); - } - - // Move or-patterns to the end, because they can result in us - // creating additional candidates, so we want to test them as - // late as possible. - match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. })); - debug!(simplified = ?match_pairs, "simplify_match_pairs"); - } -} diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index fe5ec32422cf..f92036a83e1e 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -763,7 +763,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let match_pair = candidate.match_pairs.remove(match_pair_index); candidate.match_pairs.extend(match_pair.subpairs); // Move or-patterns to the end. - candidate.match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. })); + candidate.sort_match_pairs(); } ret From e3e74bc89a958e36c658fa809d98b4dd66d53cf8 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Mar 2025 23:26:00 +1100 Subject: [PATCH 693/991] Make `MatchPairTree::place` non-optional As the invariant indicated, this place could only be none for `TestCase::Irrefutable` nodes, which no longer exist. --- .../src/builder/matches/match_pair.rs | 3 ++- compiler/rustc_mir_build/src/builder/matches/mod.rs | 12 ++---------- compiler/rustc_mir_build/src/builder/matches/test.rs | 9 +++------ compiler/rustc_mir_build/src/builder/matches/util.rs | 8 ++------ 4 files changed, 9 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 55487f48509f..c6f3e22e95f6 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -115,6 +115,7 @@ impl<'tcx> MatchPairTree<'tcx> { place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty)); } + // Place can be none if the pattern refers to a non-captured place in a closure. let place = place_builder.try_to_place(cx); let mut subpairs = Vec::new(); let test_case = match pattern.kind { @@ -320,7 +321,7 @@ impl<'tcx> MatchPairTree<'tcx> { if let Some(test_case) = test_case { // This pattern is refutable, so push a new match-pair node. match_pairs.push(MatchPairTree { - place, + place: place.expect("refutable patterns should always have a place to inspect"), test_case, subpairs, pattern_ty: pattern.ty, diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 5d97bf13f869..b05052a3455e 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1256,13 +1256,7 @@ impl<'tcx> TestCase<'tcx> { #[derive(Debug, Clone)] pub(crate) struct MatchPairTree<'tcx> { /// This place... - /// - /// --- - /// This can be `None` if it referred to a non-captured place in a closure. - /// - /// Invariant: Can only be `None` when `test_case` is `Irrefutable`. - /// Therefore this must be `Some(_)` after simplification. - place: Option>, + place: Place<'tcx>, /// ... must pass this test... test_case: TestCase<'tcx>, @@ -2082,11 +2076,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Extract the match-pair from the highest priority candidate let match_pair = &candidates[0].match_pairs[0]; let test = self.pick_test_for_match_pair(match_pair); - // Unwrap is ok after simplification. - let match_place = match_pair.place.unwrap(); debug!(?test, ?match_pair); - (match_place, test) + (match_pair.place, test) } /// Given a test, we partition the input candidates into several buckets. diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index f92036a83e1e..e5d61bc9e556 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -540,11 +540,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // than one, but it'd be very unusual to have two sides that // both require tests; you'd expect one side to be simplified // away.) - let (match_pair_index, match_pair) = candidate - .match_pairs - .iter() - .enumerate() - .find(|&(_, mp)| mp.place == Some(test_place))?; + let (match_pair_index, match_pair) = + candidate.match_pairs.iter().enumerate().find(|&(_, mp)| mp.place == test_place)?; // If true, the match pair is completely entailed by its corresponding test // branch, so it can be removed. If false, the match pair is _compatible_ @@ -587,7 +584,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate .match_pairs .iter() - .any(|mp| mp.place == Some(test_place) && is_covering_range(&mp.test_case)) + .any(|mp| mp.place == test_place && is_covering_range(&mp.test_case)) }; if sorted_candidates .get(&TestBranch::Failure) diff --git a/compiler/rustc_mir_build/src/builder/matches/util.rs b/compiler/rustc_mir_build/src/builder/matches/util.rs index 589e350a03fc..ed3b652e4ef5 100644 --- a/compiler/rustc_mir_build/src/builder/matches/util.rs +++ b/compiler/rustc_mir_build/src/builder/matches/util.rs @@ -173,14 +173,10 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { // } // ``` // Hence we fake borrow using a deep borrow. - if let Some(place) = match_pair.place { - self.fake_borrow(place, FakeBorrowKind::Deep); - } + self.fake_borrow(match_pair.place, FakeBorrowKind::Deep); } else { // Insert a Shallow borrow of any place that is switched on. - if let Some(place) = match_pair.place { - self.fake_borrow(place, FakeBorrowKind::Shallow); - } + self.fake_borrow(match_pair.place, FakeBorrowKind::Shallow); for subpair in &match_pair.subpairs { self.visit_match_pair(subpair); From 8641805dfeb035f66a8c04f57893864deeaaef03 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 5 Mar 2025 14:42:43 +0100 Subject: [PATCH 694/991] Fix syntax highlightingg punct filtering ignoring mods --- .../rust-analyzer/crates/ide/src/syntax_highlighting.rs | 2 +- .../src/syntax_highlighting/test_data/highlight_unsafe.html | 3 +-- .../crates/ide/src/syntax_highlighting/tests.rs | 5 ++--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index 62dc92feb1d6..83082496d5b6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -593,7 +593,7 @@ fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool *tag = HlTag::Punctuation(HlPunct::Other); } } - HlTag::Punctuation(_) if !config.punctuation => return false, + HlTag::Punctuation(_) if !config.punctuation && highlight.mods.is_empty() => return false, tag @ HlTag::Punctuation(_) if !config.specialize_punctuation => { *tag = HlTag::Punctuation(HlPunct::Other); } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html index 44905831e36a..828b8f762c58 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html @@ -101,10 +101,9 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let Union { field: _ }; // but not these let Union { field }; - let Union { field: true }; let Union { field: field }; let Union { field: ref field }; - let Union { field: (ref field | 0) }; + let Union { field: (_ | ref field) }; // unsafe deref *&raw const*&*x; diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index 504a1c970efb..8f69bb823000 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -651,10 +651,9 @@ fn main() { let Union { field: _ }; // but not these let Union { field }; - let Union { field: true }; let Union { field: field }; let Union { field: ref field }; - let Union { field: (ref field | 0) }; + let Union { field: (_ | ref field) }; // unsafe deref *&raw const*&*x; @@ -672,7 +671,7 @@ fn main() { core::arch::asm!( "push {base}", - base$0 = const 0 + base = const 0 ); } } From 9c75ed2fa29bd24c0bc29729de69d78fb7f66708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Mar 2025 22:18:53 +0800 Subject: [PATCH 695/991] triagebot: add `compiler_leads` ad-hoc group Intended for e.g. rolling reviewers for adding new targets. --- triagebot.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index cab4e232dc04..eceb35b36749 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1096,6 +1096,10 @@ title = "[stable" branch = "stable" [assign.adhoc_groups] +compiler_leads = [ + "@davidtwco", + "@wesleywiser", +] compiler = [ "@BoxyUwU", "@cjgillot", From cb7d687e96151adc81c55fc48734497a2b48e79c Mon Sep 17 00:00:00 2001 From: Frank King Date: Sun, 19 Jan 2025 23:30:58 +0800 Subject: [PATCH 696/991] Implement `&pin const self` and `&pin mut self` sugars --- compiler/rustc_ast/src/ast.rs | 21 ++++- compiler/rustc_ast_pretty/src/pprust/state.rs | 7 ++ compiler/rustc_parse/src/parser/item.rs | 45 ++++++++++ src/tools/rustfmt/src/items.rs | 27 ++++++ src/tools/rustfmt/tests/source/pin_sugar.rs | 10 +++ src/tools/rustfmt/tests/target/pin_sugar.rs | 9 ++ tests/pretty/pin-ergonomics.rs | 24 +++++ .../async-await/pin-ergonomics/sugar-self.rs | 46 ++++++++++ .../feature-gate-pin_ergonomics.rs | 40 ++++++++- .../feature-gate-pin_ergonomics.stderr | 88 +++++++++++++++++-- 10 files changed, 304 insertions(+), 13 deletions(-) create mode 100644 tests/pretty/pin-ergonomics.rs create mode 100644 tests/ui/async-await/pin-ergonomics/sugar-self.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fb6b36e1a09d..11fc409cf433 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2641,6 +2641,8 @@ pub enum SelfKind { Value(Mutability), /// `&'lt self`, `&'lt mut self` Region(Option, Mutability), + /// `&'lt pin const self`, `&'lt pin mut self` + Pinned(Option, Mutability), /// `self: TYPE`, `mut self: TYPE` Explicit(P, Mutability), } @@ -2650,6 +2652,8 @@ impl SelfKind { match self { SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(), SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()), + SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()), + SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()), SelfKind::Value(_) | SelfKind::Explicit(_, _) => { unreachable!("if we had an explicit self, we wouldn't be here") } @@ -2666,11 +2670,13 @@ impl Param { if ident.name == kw::SelfLower { return match self.ty.kind { TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), - TyKind::Ref(lt, MutTy { ref ty, mutbl }) - | TyKind::PinnedRef(lt, MutTy { ref ty, mutbl }) + TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => { + Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) + } + TyKind::PinnedRef(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => { - Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) + Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl))) } _ => Some(respan( self.pat.span.to(self.ty.span), @@ -2712,6 +2718,15 @@ impl Param { tokens: None, }), ), + SelfKind::Pinned(lt, mutbl) => ( + mutbl, + P(Ty { + id: DUMMY_NODE_ID, + kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }), + span, + tokens: None, + }), + ), }; Param { attrs, diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index d747237f76db..01fc272a4589 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1783,6 +1783,13 @@ impl<'a> State<'a> { self.print_mutability(*m, false); self.word("self") } + SelfKind::Pinned(lt, m) => { + self.word("&"); + self.print_opt_lifetime(lt); + self.word("pin "); + self.print_mutability(*m, true); + self.word("self") + } SelfKind::Explicit(typ, m) => { self.print_mutability(*m, false); self.word("self"); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 3f642a7ac1fd..68a16a1c66bb 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2959,9 +2959,20 @@ impl<'a> Parser<'a> { this.is_keyword_ahead(n, &[kw::SelfLower]) && this.look_ahead(n + 1, |t| t != &token::PathSep) }; + // Is `pin const self` `n` tokens ahead? + let is_isolated_pin_const_self = |this: &Self, n| { + this.look_ahead(n, |token| token.is_ident_named(sym::pin)) + && this.is_keyword_ahead(n + 1, &[kw::Const]) + && is_isolated_self(this, n + 2) + }; // Is `mut self` `n` tokens ahead? let is_isolated_mut_self = |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1); + // Is `pin mut self` `n` tokens ahead? + let is_isolated_pin_mut_self = |this: &Self, n| { + this.look_ahead(n, |token| token.is_ident_named(sym::pin)) + && is_isolated_mut_self(this, n + 1) + }; // Parse `self` or `self: TYPE`. We already know the current token is `self`. let parse_self_possibly_typed = |this: &mut Self, m| { let eself_ident = expect_self_ident(this); @@ -3021,6 +3032,20 @@ impl<'a> Parser<'a> { self.bump(); self.bump(); SelfKind::Region(None, Mutability::Mut) + } else if is_isolated_pin_const_self(self, 1) { + // `&pin const self` + self.bump(); // & + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); // pin + self.bump(); // const + SelfKind::Pinned(None, Mutability::Not) + } else if is_isolated_pin_mut_self(self, 1) { + // `&pin mut self` + self.bump(); // & + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); // pin + self.bump(); // mut + SelfKind::Pinned(None, Mutability::Mut) } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) { // `&'lt self` self.bump(); @@ -3032,6 +3057,26 @@ impl<'a> Parser<'a> { let lt = self.expect_lifetime(); self.bump(); SelfKind::Region(Some(lt), Mutability::Mut) + } else if self.look_ahead(1, |t| t.is_lifetime()) + && is_isolated_pin_const_self(self, 2) + { + // `&'lt pin const self` + self.bump(); // & + let lt = self.expect_lifetime(); + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); // pin + self.bump(); // const + SelfKind::Pinned(Some(lt), Mutability::Not) + } else if self.look_ahead(1, |t| t.is_lifetime()) + && is_isolated_pin_mut_self(self, 2) + { + // `&'lt pin mut self` + self.bump(); // & + let lt = self.expect_lifetime(); + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); // pin + self.bump(); // mut + SelfKind::Pinned(Some(lt), Mutability::Mut) } else { // `¬_self` return Ok(None); diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 457d0afe3b5b..e9e7c4ed8f9c 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -2395,6 +2395,33 @@ fn rewrite_explicit_self( )?), } } + ast::SelfKind::Pinned(lt, m) => { + let mut_str = m.ptr_str(); + match lt { + Some(ref l) => { + let lifetime_str = l.rewrite_result( + context, + Shape::legacy(context.config.max_width(), Indent::empty()), + )?; + Ok(combine_strs_with_missing_comments( + context, + param_attrs, + &format!("&{lifetime_str} pin {mut_str} self"), + span, + shape, + !has_multiple_attr_lines, + )?) + } + None => Ok(combine_strs_with_missing_comments( + context, + param_attrs, + &format!("&pin {mut_str} self"), + span, + shape, + !has_multiple_attr_lines, + )?), + } + } ast::SelfKind::Explicit(ref ty, mutability) => { let type_str = ty.rewrite_result( context, diff --git a/src/tools/rustfmt/tests/source/pin_sugar.rs b/src/tools/rustfmt/tests/source/pin_sugar.rs index 0eb3c0770c48..370dfbc196ae 100644 --- a/src/tools/rustfmt/tests/source/pin_sugar.rs +++ b/src/tools/rustfmt/tests/source/pin_sugar.rs @@ -8,3 +8,13 @@ fn g<'a>(x: & 'a pin const i32) {} fn h<'a>(x: & 'a pin mut i32) {} fn i(x: &pin mut i32) {} + +struct Foo; + +impl Foo { + fn f(&pin const self) {} + fn g<'a>(& 'a pin const self) {} + fn h<'a>(& 'a pin +mut self) {} + fn i(&pin mut self) {} +} diff --git a/src/tools/rustfmt/tests/target/pin_sugar.rs b/src/tools/rustfmt/tests/target/pin_sugar.rs index c9fa883e238f..7d04efb1b326 100644 --- a/src/tools/rustfmt/tests/target/pin_sugar.rs +++ b/src/tools/rustfmt/tests/target/pin_sugar.rs @@ -7,3 +7,12 @@ fn f(x: &pin const i32) {} fn g<'a>(x: &'a pin const i32) {} fn h<'a>(x: &'a pin mut i32) {} fn i(x: &pin mut i32) {} + +struct Foo; + +impl Foo { + fn f(&pin const self) {} + fn g<'a>(&'a pin const self) {} + fn h<'a>(&'a pin mut self) {} + fn i(&pin mut self) {} +} diff --git a/tests/pretty/pin-ergonomics.rs b/tests/pretty/pin-ergonomics.rs new file mode 100644 index 000000000000..47ffc97b1183 --- /dev/null +++ b/tests/pretty/pin-ergonomics.rs @@ -0,0 +1,24 @@ +//@ pp-exact + +#![feature(pin_ergonomics)] +#![allow(dead_code, incomplete_features)] + +struct Foo; + +impl Foo { + fn baz(&pin mut self) {} + + fn baz_const(&pin const self) {} + + fn baz_lt<'a>(&'a pin mut self) {} + + fn baz_const_lt(&'_ pin const self) {} +} + +fn foo(_: &pin mut Foo) {} +fn foo_lt<'a>(_: &'a pin mut Foo) {} + +fn foo_const(_: &pin const Foo) {} +fn foo_const_lt(_: &'_ pin const Foo) {} + +fn main() {} diff --git a/tests/ui/async-await/pin-ergonomics/sugar-self.rs b/tests/ui/async-await/pin-ergonomics/sugar-self.rs new file mode 100644 index 000000000000..3d71b54b1aec --- /dev/null +++ b/tests/ui/async-await/pin-ergonomics/sugar-self.rs @@ -0,0 +1,46 @@ +//@ check-pass + +#![feature(pin_ergonomics)] +#![allow(dead_code, incomplete_features)] + +// Makes sure we can handle `&pin mut self` and `&pin const self` as sugar for +// `self: Pin<&mut Self>` and `self: Pin<&Self>`. + +use std::pin::Pin; + +struct Foo; + +impl Foo { + fn baz(&pin mut self) {} + + fn baz_const(&pin const self) {} + + fn baz_lt<'a>(&'a pin mut self) {} + + fn baz_const_lt(&'_ pin const self) {} +} + +fn foo(_: &pin mut Foo) {} + +fn foo_const(_: &pin const Foo) {} + +fn bar(x: &pin mut Foo) { + // For the calls below to work we need to automatically reborrow, + // as if the user had written `foo(x.as_mut())`. + foo(x); + foo(x); + + Foo::baz(x); + Foo::baz(x); + + // make sure we can reborrow &mut as &. + foo_const(x); + Foo::baz_const(x); + + let x: &pin const _ = Pin::new(&Foo); + + foo_const(x); // make sure reborrowing from & to & works. + foo_const(x); +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs index 4624faf1e53c..663a83a665c4 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs @@ -7,9 +7,13 @@ struct Foo; impl Foo { fn foo(self: Pin<&mut Self>) { } + fn foo_sugar(&pin mut self) {} //~ ERROR pinned reference syntax is experimental + fn foo_sugar_const(&pin const self) {} //~ ERROR pinned reference syntax is experimental } -fn foo(x: Pin<&mut Foo>) { +fn foo(mut x: Pin<&mut Foo>) { + Foo::foo_sugar(x.as_mut()); + Foo::foo_sugar_const(x.as_ref()); let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental } @@ -27,4 +31,38 @@ fn baz(mut x: Pin<&mut Foo>) { fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental +#[cfg(any())] +mod not_compiled { + use std::pin::Pin; + + struct Foo; + + impl Foo { + fn foo(self: Pin<&mut Self>) { + } + fn foo_sugar(&pin mut self) {} //~ ERROR pinned reference syntax is experimental + fn foo_sugar_const(&pin const self) {} //~ ERROR pinned reference syntax is experimental + } + + fn foo(mut x: Pin<&mut Foo>) { + Foo::foo_sugar(x.as_mut()); + Foo::foo_sugar_const(x.as_ref()); + let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental + } + + fn foo_sugar(_: &pin mut Foo) {} //~ ERROR pinned reference syntax is experimental + + fn bar(x: Pin<&mut Foo>) { + foo(x); + foo(x); + } + + fn baz(mut x: Pin<&mut Foo>) { + x.foo(); + x.foo(); + } + + fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental +} + fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr index dd93a7be1ada..8ed7543d86e3 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr @@ -1,5 +1,25 @@ error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:13:14 + --> $DIR/feature-gate-pin_ergonomics.rs:10:19 + | +LL | fn foo_sugar(&pin mut self) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:11:25 + | +LL | fn foo_sugar_const(&pin const self) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:17:14 | LL | let _y: &pin mut Foo = x; | ^^^ @@ -9,7 +29,7 @@ LL | let _y: &pin mut Foo = x; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:16:18 + --> $DIR/feature-gate-pin_ergonomics.rs:20:18 | LL | fn foo_sugar(_: &pin mut Foo) {} | ^^^ @@ -19,7 +39,7 @@ LL | fn foo_sugar(_: &pin mut Foo) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:28:18 + --> $DIR/feature-gate-pin_ergonomics.rs:32:18 | LL | fn baz_sugar(_: &pin const Foo) {} | ^^^ @@ -28,8 +48,58 @@ LL | fn baz_sugar(_: &pin const Foo) {} = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:43:23 + | +LL | fn foo_sugar(&pin mut self) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:44:29 + | +LL | fn foo_sugar_const(&pin const self) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:50:18 + | +LL | let _y: &pin mut Foo = x; + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:53:22 + | +LL | fn foo_sugar(_: &pin mut Foo) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:65:22 + | +LL | fn baz_sugar(_: &pin const Foo) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0382]: use of moved value: `x` - --> $DIR/feature-gate-pin_ergonomics.rs:20:9 + --> $DIR/feature-gate-pin_ergonomics.rs:24:9 | LL | fn bar(x: Pin<&mut Foo>) { | - move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait @@ -39,15 +109,15 @@ LL | foo(x); | ^ value used here after move | note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary - --> $DIR/feature-gate-pin_ergonomics.rs:12:11 + --> $DIR/feature-gate-pin_ergonomics.rs:14:15 | -LL | fn foo(x: Pin<&mut Foo>) { - | --- ^^^^^^^^^^^^^ this parameter takes ownership of the value +LL | fn foo(mut x: Pin<&mut Foo>) { + | --- ^^^^^^^^^^^^^ this parameter takes ownership of the value | | | in this function error[E0382]: use of moved value: `x` - --> $DIR/feature-gate-pin_ergonomics.rs:25:5 + --> $DIR/feature-gate-pin_ergonomics.rs:29:5 | LL | fn baz(mut x: Pin<&mut Foo>) { | ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait @@ -66,7 +136,7 @@ help: consider reborrowing the `Pin` instead of moving it LL | x.as_mut().foo(); | +++++++++ -error: aborting due to 5 previous errors +error: aborting due to 12 previous errors Some errors have detailed explanations: E0382, E0658. For more information about an error, try `rustc --explain E0382`. From 52cd8746bab900aa38210d24c62352170b9f51f8 Mon Sep 17 00:00:00 2001 From: Frank King Date: Wed, 5 Mar 2025 22:13:22 +0800 Subject: [PATCH 697/991] Simplify `parse_self_param` --- compiler/rustc_parse/src/parser/item.rs | 69 +++++++++---------------- 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 68a16a1c66bb..c3b1956ad2e8 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2954,6 +2954,8 @@ impl<'a> Parser<'a> { } _ => unreachable!(), }; + // is lifetime `n` tokens ahead? + let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime()); // Is `self` `n` tokens ahead? let is_isolated_self = |this: &Self, n| { this.is_keyword_ahead(n, &[kw::SelfLower]) @@ -3023,60 +3025,35 @@ impl<'a> Parser<'a> { let eself_lo = self.token.span; let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind { token::And => { - let eself = if is_isolated_self(self, 1) { - // `&self` - self.bump(); - SelfKind::Region(None, Mutability::Not) - } else if is_isolated_mut_self(self, 1) { - // `&mut self` - self.bump(); - self.bump(); - SelfKind::Region(None, Mutability::Mut) - } else if is_isolated_pin_const_self(self, 1) { - // `&pin const self` + let has_lifetime = is_lifetime(self, 1); + let skip_lifetime_count = has_lifetime as usize; + let eself = if is_isolated_self(self, skip_lifetime_count + 1) { + // `&{'lt} self` self.bump(); // & + let lifetime = has_lifetime.then(|| self.expect_lifetime()); + SelfKind::Region(lifetime, Mutability::Not) + } else if is_isolated_mut_self(self, skip_lifetime_count + 1) { + // `&{'lt} mut self` + self.bump(); // & + let lifetime = has_lifetime.then(|| self.expect_lifetime()); + self.bump(); // mut + SelfKind::Region(lifetime, Mutability::Mut) + } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) { + // `&{'lt} pin const self` + self.bump(); // & + let lifetime = has_lifetime.then(|| self.expect_lifetime()); self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); self.bump(); // pin self.bump(); // const - SelfKind::Pinned(None, Mutability::Not) - } else if is_isolated_pin_mut_self(self, 1) { - // `&pin mut self` + SelfKind::Pinned(lifetime, Mutability::Not) + } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) { + // `&{'lt} pin mut self` self.bump(); // & + let lifetime = has_lifetime.then(|| self.expect_lifetime()); self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); self.bump(); // pin self.bump(); // mut - SelfKind::Pinned(None, Mutability::Mut) - } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) { - // `&'lt self` - self.bump(); - let lt = self.expect_lifetime(); - SelfKind::Region(Some(lt), Mutability::Not) - } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) { - // `&'lt mut self` - self.bump(); - let lt = self.expect_lifetime(); - self.bump(); - SelfKind::Region(Some(lt), Mutability::Mut) - } else if self.look_ahead(1, |t| t.is_lifetime()) - && is_isolated_pin_const_self(self, 2) - { - // `&'lt pin const self` - self.bump(); // & - let lt = self.expect_lifetime(); - self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); - self.bump(); // pin - self.bump(); // const - SelfKind::Pinned(Some(lt), Mutability::Not) - } else if self.look_ahead(1, |t| t.is_lifetime()) - && is_isolated_pin_mut_self(self, 2) - { - // `&'lt pin mut self` - self.bump(); // & - let lt = self.expect_lifetime(); - self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); - self.bump(); // pin - self.bump(); // mut - SelfKind::Pinned(Some(lt), Mutability::Mut) + SelfKind::Pinned(lifetime, Mutability::Mut) } else { // `¬_self` return Ok(None); From 50d0f992acf3e7b4f0801a6a749e379a616a71d8 Mon Sep 17 00:00:00 2001 From: Frank King Date: Wed, 5 Mar 2025 22:35:50 +0800 Subject: [PATCH 698/991] Simplify `rewrite_explicit_self` --- src/tools/rustfmt/src/items.rs | 98 +++++++++++----------------------- 1 file changed, 31 insertions(+), 67 deletions(-) diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index e9e7c4ed8f9c..3fb3284e3d7f 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -2359,6 +2359,21 @@ impl Rewrite for ast::Param { } } +fn rewrite_opt_lifetime( + context: &RewriteContext<'_>, + lifetime: Option, +) -> RewriteResult { + let Some(l) = lifetime else { + return Ok(String::new()); + }; + let mut result = l.rewrite_result( + context, + Shape::legacy(context.config.max_width(), Indent::empty()), + )?; + result.push(' '); + Ok(result) +} + fn rewrite_explicit_self( context: &RewriteContext<'_>, explicit_self: &ast::ExplicitSelf, @@ -2367,85 +2382,34 @@ fn rewrite_explicit_self( shape: Shape, has_multiple_attr_lines: bool, ) -> RewriteResult { - match explicit_self.node { + let self_str = match explicit_self.node { ast::SelfKind::Region(lt, m) => { let mut_str = format_mutability(m); - match lt { - Some(ref l) => { - let lifetime_str = l.rewrite_result( - context, - Shape::legacy(context.config.max_width(), Indent::empty()), - )?; - Ok(combine_strs_with_missing_comments( - context, - param_attrs, - &format!("&{lifetime_str} {mut_str}self"), - span, - shape, - !has_multiple_attr_lines, - )?) - } - None => Ok(combine_strs_with_missing_comments( - context, - param_attrs, - &format!("&{mut_str}self"), - span, - shape, - !has_multiple_attr_lines, - )?), - } + let lifetime_str = rewrite_opt_lifetime(context, lt)?; + format!("&{lifetime_str}{mut_str}self") } ast::SelfKind::Pinned(lt, m) => { let mut_str = m.ptr_str(); - match lt { - Some(ref l) => { - let lifetime_str = l.rewrite_result( - context, - Shape::legacy(context.config.max_width(), Indent::empty()), - )?; - Ok(combine_strs_with_missing_comments( - context, - param_attrs, - &format!("&{lifetime_str} pin {mut_str} self"), - span, - shape, - !has_multiple_attr_lines, - )?) - } - None => Ok(combine_strs_with_missing_comments( - context, - param_attrs, - &format!("&pin {mut_str} self"), - span, - shape, - !has_multiple_attr_lines, - )?), - } + let lifetime_str = rewrite_opt_lifetime(context, lt)?; + format!("&{lifetime_str}pin {mut_str} self") } ast::SelfKind::Explicit(ref ty, mutability) => { let type_str = ty.rewrite_result( context, Shape::legacy(context.config.max_width(), Indent::empty()), )?; - - Ok(combine_strs_with_missing_comments( - context, - param_attrs, - &format!("{}self: {}", format_mutability(mutability), type_str), - span, - shape, - !has_multiple_attr_lines, - )?) + format!("{}self: {}", format_mutability(mutability), type_str) } - ast::SelfKind::Value(mutability) => Ok(combine_strs_with_missing_comments( - context, - param_attrs, - &format!("{}self", format_mutability(mutability)), - span, - shape, - !has_multiple_attr_lines, - )?), - } + ast::SelfKind::Value(mutability) => format!("{}self", format_mutability(mutability)), + }; + Ok(combine_strs_with_missing_comments( + context, + param_attrs, + &self_str, + span, + shape, + !has_multiple_attr_lines, + )?) } pub(crate) fn span_lo_for_param(param: &ast::Param) -> BytePos { From 8391c08b0329cf965ba9dae04d04dc1e46d1803e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 5 Mar 2025 15:23:45 +0100 Subject: [PATCH 699/991] Revert #138019 after further discussion about adding this exception in hir-pretty --- compiler/rustc_hir_pretty/src/lib.rs | 74 ------------------------ tests/ui/unpretty/deprecated-attr.rs | 2 + tests/ui/unpretty/deprecated-attr.stdout | 17 ++++-- 3 files changed, 14 insertions(+), 79 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 1658c8dac676..22edc18d71ca 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -117,80 +117,6 @@ impl<'a> State<'a> { )); self.hardbreak() } - hir::Attribute::Parsed(AttributeKind::Deprecation { deprecation, .. }) => { - self.word("#[deprecated"); - - // There are three possible forms here: - // 1. a form with explicit components like - // `#[deprecated(since = "1.2.3", note = "some note", suggestion = "something")]` - // where each component may be present or absent. - // 2. `#[deprecated = "message"]` - // 3. `#[deprecated]` - // - // Let's figure out which we need. - // If there's a `since` or `suggestion` value, we're definitely in form 1. - if matches!( - deprecation.since, - rustc_attr_parsing::DeprecatedSince::RustcVersion(..) - | rustc_attr_parsing::DeprecatedSince::Future - | rustc_attr_parsing::DeprecatedSince::NonStandard(..) - ) || deprecation.suggestion.is_some() - { - self.word("("); - let mut use_comma = false; - - match &deprecation.since { - rustc_attr_parsing::DeprecatedSince::RustcVersion(rustc_version) => { - self.word("since = \""); - self.word(format!( - "{}.{}.{}", - rustc_version.major, rustc_version.minor, rustc_version.patch - )); - self.word("\""); - use_comma = true; - } - rustc_attr_parsing::DeprecatedSince::Future => { - self.word("since = \"future\""); - use_comma = true; - } - rustc_attr_parsing::DeprecatedSince::NonStandard(symbol) => { - self.word("since = \""); - self.word(symbol.to_ident_string()); - self.word("\""); - use_comma = true; - } - _ => {} - } - - if let Some(note) = &deprecation.note { - if use_comma { - self.word(", "); - } - self.word("note = \""); - self.word(note.to_ident_string()); - self.word("\""); - use_comma = true; - } - - if let Some(suggestion) = &deprecation.suggestion { - if use_comma { - self.word(", "); - } - self.word("suggestion = \""); - self.word(suggestion.to_ident_string()); - self.word("\""); - } - } else if let Some(note) = &deprecation.note { - // We're in form 2: `#[deprecated = "message"]`. - self.word(" = \""); - self.word(note.to_ident_string()); - self.word("\""); - } else { - // We're in form 3: `#[deprecated]`. Nothing to do here. - } - - self.word("]"); - } hir::Attribute::Parsed(pa) => { self.word("#[attr=\""); pa.print_attribute(self); diff --git a/tests/ui/unpretty/deprecated-attr.rs b/tests/ui/unpretty/deprecated-attr.rs index dda362a595e2..24a32d8a9acf 100644 --- a/tests/ui/unpretty/deprecated-attr.rs +++ b/tests/ui/unpretty/deprecated-attr.rs @@ -1,6 +1,8 @@ //@ compile-flags: -Zunpretty=hir //@ check-pass +// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is +// slightly broken. #[deprecated] pub struct PlainDeprecated; diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout index 60dbac1072b9..675351351a0c 100644 --- a/tests/ui/unpretty/deprecated-attr.stdout +++ b/tests/ui/unpretty/deprecated-attr.stdout @@ -5,17 +5,24 @@ extern crate std; //@ compile-flags: -Zunpretty=hir //@ check-pass -#[deprecated] +// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is +// slightly broken. +#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote: +suggestion: }span: }")] struct PlainDeprecated; -#[deprecated = "here's why this is deprecated"] +#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote: +here's why this is deprecatedsuggestion: }span: }")] struct DirectNote; -#[deprecated = "here's why this is deprecated"] +#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote: +here's why this is deprecatedsuggestion: }span: }")] struct ExplicitNote; -#[deprecated(since = "1.2.3", note = "here's why this is deprecated"] +#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note: +here's why this is deprecatedsuggestion: }span: }")] struct SinceAndNote; -#[deprecated(since = "1.2.3", note = "here's why this is deprecated"] +#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note: +here's why this is deprecatedsuggestion: }span: }")] struct FlippedOrder; From 376955ef2559101820272233ac1035b7d74659ce Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Wed, 5 Mar 2025 16:34:09 +0100 Subject: [PATCH 700/991] feat: Remove - from xtensa targets cpu names Co-authored-by: MabezDev --- compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs | 2 +- .../rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs | 2 +- compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs | 2 +- .../rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs index dd98f34d3239..cffdaa907273 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { vendor: "espressif".into(), executables: true, - cpu: "esp32-s2".into(), + cpu: "esp32s2".into(), linker: Some("xtensa-esp32s2-elf-gcc".into()), // See https://github.com/espressif/rust-esp32-example/issues/3#issuecomment-861054477 diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs index 29bcf12cbaf6..7bf5834ab0aa 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { vendor: "espressif".into(), - cpu: "esp32-s2".into(), + cpu: "esp32s2".into(), linker: Some("xtensa-esp32s2-elf-gcc".into()), max_atomic_width: Some(32), features: "+forced-atomics".into(), diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs index dd6e7b6c3e8c..2e4afc005414 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { vendor: "espressif".into(), executables: true, - cpu: "esp32-s3".into(), + cpu: "esp32s3".into(), linker: Some("xtensa-esp32s3-elf-gcc".into()), // The esp32s3 only supports native 32bit atomics. diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs index ddc909f387e9..d506888d8ee0 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { vendor: "espressif".into(), - cpu: "esp32-s3".into(), + cpu: "esp32s3".into(), linker: Some("xtensa-esp32s3-elf-gcc".into()), max_atomic_width: Some(32), atomic_cas: true, From c85d3f6e874acd35647617161fd2ae950b94dedd Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Tue, 4 Mar 2025 20:28:38 -0800 Subject: [PATCH 701/991] bootstrap and compiletest: Use size_of_val from the prelude instead of imported Use `std::mem::size_of_val` from the prelude instead of importing or qualifying it. This function was added to all preludes in Rust 1.80. --- src/bootstrap/src/bin/rustc.rs | 2 +- src/bootstrap/src/utils/job.rs | 4 ++-- src/tools/compiletest/src/raise_fd_limit.rs | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 610450675928..d8cae02456c0 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -349,7 +349,7 @@ fn format_rusage_data(child: Child) -> Option { let mut kernel_filetime = Default::default(); let mut kernel_time = Default::default(); let mut memory_counters = PROCESS_MEMORY_COUNTERS::default(); - let memory_counters_size = std::mem::size_of_val(&memory_counters); + let memory_counters_size = size_of_val(&memory_counters); unsafe { GetProcessTimes( diff --git a/src/bootstrap/src/utils/job.rs b/src/bootstrap/src/utils/job.rs index 10efed130d62..a60e889fd576 100644 --- a/src/bootstrap/src/utils/job.rs +++ b/src/bootstrap/src/utils/job.rs @@ -42,7 +42,7 @@ pub unsafe fn setup(build: &mut crate::Build) { #[cfg(windows)] mod for_windows { use std::ffi::c_void; - use std::{io, mem}; + use std::io; use windows::Win32::Foundation::CloseHandle; use windows::Win32::System::Diagnostics::Debug::{ @@ -82,7 +82,7 @@ mod for_windows { job, JobObjectExtendedLimitInformation, &info as *const _ as *const c_void, - mem::size_of_val(&info) as u32, + size_of_val(&info) as u32, ); assert!(r.is_ok(), "{}", io::Error::last_os_error()); diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs index 4445ecb7ce85..7b12ba946b9e 100644 --- a/src/tools/compiletest/src/raise_fd_limit.rs +++ b/src/tools/compiletest/src/raise_fd_limit.rs @@ -7,7 +7,6 @@ #[cfg(target_vendor = "apple")] #[allow(non_camel_case_types)] pub unsafe fn raise_fd_limit() { - use std::mem::size_of_val; use std::ptr::null_mut; use std::{cmp, io}; From bee6cdd962bc9517282e044617d6e42a657620a7 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Wed, 5 Mar 2025 23:38:29 +0100 Subject: [PATCH 702/991] fix: Make RustAnalyzer:Run available in manifest file --- .../rust-analyzer/editors/code/src/ctx.ts | 6 ++++++ .../rust-analyzer/editors/code/src/run.ts | 19 +++++++++++++------ .../rust-analyzer/editors/code/src/util.ts | 4 ++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts index ac73f2ae6bf1..37a2ee236915 100644 --- a/src/tools/rust-analyzer/editors/code/src/ctx.ts +++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts @@ -5,6 +5,7 @@ import * as ra from "./lsp_ext"; import { Config, prepareVSCodeConfig } from "./config"; import { createClient } from "./client"; import { + isCargoTomlEditor, isDocumentInWorkspace, isRustDocument, isRustEditor, @@ -429,6 +430,11 @@ export class Ctx implements RustAnalyzerExtensionApi { return editor && isRustEditor(editor) ? editor : undefined; } + get activeCargoTomlEditor(): RustEditor | undefined { + const editor = vscode.window.activeTextEditor; + return editor && isCargoTomlEditor(editor) ? editor : undefined; + } + get extensionPath(): string { return this.extCtx.extensionPath; } diff --git a/src/tools/rust-analyzer/editors/code/src/run.ts b/src/tools/rust-analyzer/editors/code/src/run.ts index f71ab7ffbd81..40027cc7c857 100644 --- a/src/tools/rust-analyzer/editors/code/src/run.ts +++ b/src/tools/rust-analyzer/editors/code/src/run.ts @@ -7,7 +7,7 @@ import type { CtxInit } from "./ctx"; import { makeDebugConfig } from "./debug"; import type { Config } from "./config"; import type { LanguageClient } from "vscode-languageclient/node"; -import { unwrapUndefinable, type RustEditor } from "./util"; +import { log, unwrapUndefinable, type RustEditor } from "./util"; const quickPickButtons = [ { iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configuration." }, @@ -19,7 +19,7 @@ export async function selectRunnable( debuggeeOnly = false, showButtons: boolean = true, ): Promise { - const editor = ctx.activeRustEditor; + const editor = ctx.activeRustEditor ?? ctx.activeCargoTomlEditor; if (!editor) return; // show a placeholder while we get the runnables from the server @@ -175,10 +175,17 @@ async function getRunnables( uri: editor.document.uri.toString(), }; - const runnables = await client.sendRequest(ra.runnables, { - textDocument, - position: client.code2ProtocolConverter.asPosition(editor.selection.active), - }); + const runnables = await client + .sendRequest(ra.runnables, { + textDocument, + position: client.code2ProtocolConverter.asPosition(editor.selection.active), + }) + .catch((err) => { + // If this command is run for a virtual manifest at the workspace root, then this request + // will fail as we do not watch this file. + log.error(`${err}`); + return []; + }); const items: RunnableQuickPick[] = []; if (prevRunnable) { items.push(prevRunnable); diff --git a/src/tools/rust-analyzer/editors/code/src/util.ts b/src/tools/rust-analyzer/editors/code/src/util.ts index 2f7702baebb6..93c7bf8d73e7 100644 --- a/src/tools/rust-analyzer/editors/code/src/util.ts +++ b/src/tools/rust-analyzer/editors/code/src/util.ts @@ -90,6 +90,10 @@ export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor { return isRustDocument(editor.document); } +export function isCargoTomlEditor(editor: vscode.TextEditor): editor is RustEditor { + return isCargoTomlDocument(editor.document); +} + export function isDocumentInWorkspace(document: RustDocument): boolean { const workspaceFolders = vscode.workspace.workspaceFolders; if (!workspaceFolders) { From 181ef540cfa6f7819c999ba2c9c5036f86fff238 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Mar 2025 23:06:54 +0000 Subject: [PATCH 703/991] Use final path segment for diagnostic --- compiler/rustc_hir_typeck/src/demand.rs | 2 +- tests/ui/typeck/issue-84768.stderr | 2 +- tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 85131f6195f8..aa917ee07ff5 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1265,7 +1265,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { CallableKind::Function }; - maybe_emit_help(def_id, path.segments[0].ident, args, callable_kind); + maybe_emit_help(def_id, path.segments.last().unwrap().ident, args, callable_kind); } hir::ExprKind::MethodCall(method, _receiver, args, _span) => { let Some(def_id) = diff --git a/tests/ui/typeck/issue-84768.stderr b/tests/ui/typeck/issue-84768.stderr index 72784ba59c9b..8a2200cbf684 100644 --- a/tests/ui/typeck/issue-84768.stderr +++ b/tests/ui/typeck/issue-84768.stderr @@ -20,7 +20,7 @@ help: the return type of this call is `{integer}` due to the type of the argumen LL | ::call_once(f, 1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^ | | - | this argument influences the return type of `FnOnce` + | this argument influences the return type of `call_once` note: method defined here --> $SRC_DIR/core/src/ops/function.rs:LL:COL diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr index 050718348839..edee7c4f5a15 100644 --- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -25,7 +25,7 @@ help: the return type of this call is `u32` due to the type of the argument pass LL | >::add(1u32, 2); | ^^^^^^^^^^^^^^^^^^^^^^^----^^^^ | | - | this argument influences the return type of `Add` + | this argument influences the return type of `add` note: method defined here --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the type of the numeric literal from `u32` to `i32` @@ -48,7 +48,7 @@ help: the return type of this call is `u32` due to the type of the argument pass LL | >::add(1, 2u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^----^ | | - | this argument influences the return type of `Add` + | this argument influences the return type of `add` note: method defined here --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the type of the numeric literal from `u32` to `i32` From 9d8ce729011a8b8c735e3b3cfea66db1bc0fb303 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Fri, 21 Feb 2025 00:07:46 -0800 Subject: [PATCH 704/991] compiler: factor Windows x86-32 ABI impl into its own file While it shares more than zero code with the SysV x86-32 ABI impl, there is no particular reason to organize wildly different ABIs using if-else in the same function. --- compiler/rustc_target/src/callconv/mod.rs | 7 +- compiler/rustc_target/src/callconv/x86.rs | 24 +----- .../rustc_target/src/callconv/x86_win32.rs | 81 +++++++++++++++++++ 3 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 compiler/rustc_target/src/callconv/x86_win32.rs diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 1c044fe98b3e..8fe19358954e 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -31,6 +31,7 @@ mod sparc64; mod wasm; mod x86; mod x86_64; +mod x86_win32; mod x86_win64; mod xtensa; @@ -649,7 +650,11 @@ impl<'a, Ty> FnAbi<'a, Ty> { }; let reg_struct_return = cx.x86_abi_opt().reg_struct_return; let opts = x86::X86Options { flavor, regparm, reg_struct_return }; - x86::compute_abi_info(cx, self, opts); + if spec.is_like_msvc { + x86_win32::compute_abi_info(cx, self, opts); + } else { + x86::compute_abi_info(cx, self, opts); + } } "x86_64" => match abi { ExternAbi::SysV64 { .. } => x86_64::compute_abi_info(cx, self), diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 7e5aab0201b6..828725e94692 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -36,7 +36,7 @@ where if t.abi_return_struct_as_int || opts.reg_struct_return { // According to Clang, everyone but MSVC returns single-element // float aggregates directly in a floating-point register. - if !t.is_like_msvc && fn_abi.ret.layout.is_single_fp_element(cx) { + if fn_abi.ret.layout.is_single_fp_element(cx) { match fn_abi.ret.layout.size.bytes() { 4 => fn_abi.ret.cast_to(Reg::f32()), 8 => fn_abi.ret.cast_to(Reg::f64()), @@ -64,31 +64,11 @@ where continue; } - // FIXME: MSVC 2015+ will pass the first 3 vector arguments in [XYZ]MM0-2 - // See https://reviews.llvm.org/D72114 for Clang behavior - let t = cx.target_spec(); let align_4 = Align::from_bytes(4).unwrap(); let align_16 = Align::from_bytes(16).unwrap(); - if t.is_like_msvc - && arg.layout.is_adt() - && let Some(max_repr_align) = arg.layout.max_repr_align - && max_repr_align > align_4 - { - // MSVC has special rules for overaligned arguments: https://reviews.llvm.org/D72114. - // Summarized here: - // - Arguments with _requested_ alignment > 4 are passed indirectly. - // - For backwards compatibility, arguments with natural alignment > 4 are still passed - // on stack (via `byval`). For example, this includes `double`, `int64_t`, - // and structs containing them, provided they lack an explicit alignment attribute. - assert!( - arg.layout.align.abi >= max_repr_align, - "abi alignment {:?} less than requested alignment {max_repr_align:?}", - arg.layout.align.abi, - ); - arg.make_indirect(); - } else if arg.layout.is_aggregate() { + if arg.layout.is_aggregate() { // We need to compute the alignment of the `byval` argument. The rules can be found in // `X86_32ABIInfo::getTypeStackAlignInBytes` in Clang's `TargetInfo.cpp`. Summarized // here, they are: diff --git a/compiler/rustc_target/src/callconv/x86_win32.rs b/compiler/rustc_target/src/callconv/x86_win32.rs new file mode 100644 index 000000000000..554a7368848b --- /dev/null +++ b/compiler/rustc_target/src/callconv/x86_win32.rs @@ -0,0 +1,81 @@ +use rustc_abi::{Align, HasDataLayout, Reg, TyAbiInterface}; + +use crate::callconv::FnAbi; +use crate::spec::HasTargetSpec; + +pub(crate) fn compute_abi_info<'a, Ty, C>( + cx: &C, + fn_abi: &mut FnAbi<'a, Ty>, + opts: super::x86::X86Options, +) where + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, +{ + if !fn_abi.ret.is_ignore() { + if fn_abi.ret.layout.is_aggregate() && fn_abi.ret.layout.is_sized() { + // Returning a structure. Most often, this will use + // a hidden first argument. On some platforms, though, + // small structs are returned as integers. + // + // Some links: + // https://www.angelcode.com/dev/callconv/callconv.html + // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp + let t = cx.target_spec(); + // MSVC does not special-case 1-element float aggregates, unlike others. + // GCC used to apply the SysV rule here, breaking windows-gnu's ABI, but was fixed: + // - reported in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82028 + // - fixed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85667 + if t.abi_return_struct_as_int || opts.reg_struct_return { + match fn_abi.ret.layout.size.bytes() { + 1 => fn_abi.ret.cast_to(Reg::i8()), + 2 => fn_abi.ret.cast_to(Reg::i16()), + 4 => fn_abi.ret.cast_to(Reg::i32()), + 8 => fn_abi.ret.cast_to(Reg::i64()), + _ => fn_abi.ret.make_indirect(), + } + } else { + fn_abi.ret.make_indirect(); + } + } else { + fn_abi.ret.extend_integer_width_to(32); + } + } + + for arg in fn_abi.args.iter_mut() { + if arg.is_ignore() || !arg.layout.is_sized() { + continue; + } + + // FIXME: MSVC 2015+ will pass the first 3 vector arguments in [XYZ]MM0-2 + // See https://reviews.llvm.org/D72114 for Clang behavior + + let align_4 = Align::from_bytes(4).unwrap(); + + if arg.layout.is_adt() + && let Some(max_repr_align) = arg.layout.max_repr_align + && max_repr_align > align_4 + { + // MSVC has special rules for overaligned arguments: https://reviews.llvm.org/D72114. + // Summarized here: + // - Arguments with _requested_ alignment > 4 are passed indirectly. + // - For backwards compatibility, arguments with natural alignment > 4 are still passed + // on stack (via `byval`). For example, this includes `double`, `int64_t`, + // and structs containing them, provided they lack an explicit alignment attribute. + assert!( + arg.layout.align.abi >= max_repr_align, + "abi alignment {:?} less than requested alignment {max_repr_align:?}", + arg.layout.align.abi, + ); + arg.make_indirect(); + } else if arg.layout.is_aggregate() { + // Alignment of the `byval` argument. + // The rules can be found in `X86_32ABIInfo::getTypeStackAlignInBytes` in Clang's `TargetInfo.cpp`. + let byval_align = align_4; + arg.pass_by_stack_offset(Some(byval_align)); + } else { + arg.extend_integer_width_to(32); + } + } + + super::x86::fill_inregs(cx, fn_abi, opts, false); +} From 508b803c44e4df10fe189e8d1ae3a551ade9b2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 5 Mar 2025 23:36:47 +0100 Subject: [PATCH 705/991] Remove start block special case Edges to the start block are invalid. The special case is unnecessary. --- compiler/rustc_mir_transform/src/add_call_guards.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index 55694cacd92e..f9e757dda431 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -34,7 +34,6 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let mut pred_count: IndexVec<_, _> = body.basic_blocks.predecessors().iter().map(|ps| ps.len()).collect(); - pred_count[START_BLOCK] += 1; // We need a place to store the new blocks generated let mut new_blocks = Vec::new(); From 5bae3adde9410c4f0f7363ec44b183a255463a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 5 Mar 2025 23:41:44 +0100 Subject: [PATCH 706/991] Calculate predecessor count directly Avoid allocating a vector of small vectors merely to determine how many predecessors each basic block has. Additionally use u8 and saturating operations. The pass only needs to distinguish between [0..1] and [2..]. --- compiler/rustc_mir_transform/src/add_call_guards.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index f9e757dda431..60e6342d4ecf 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -32,8 +32,12 @@ pub(super) use self::AddCallGuards::*; impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mut pred_count: IndexVec<_, _> = - body.basic_blocks.predecessors().iter().map(|ps| ps.len()).collect(); + let mut pred_count = IndexVec::from_elem(0u8, &body.basic_blocks); + for (_, data) in body.basic_blocks.iter_enumerated() { + for succ in data.terminator().successors() { + pred_count[succ] = pred_count[succ].saturating_add(1); + } + } // We need a place to store the new blocks generated let mut new_blocks = Vec::new(); From 571f95fb94fa51a8003de8a610ac0eba5e02b1a3 Mon Sep 17 00:00:00 2001 From: moxian Date: Wed, 5 Mar 2025 16:24:07 -0800 Subject: [PATCH 707/991] Remember silenced bootstrap changelog warnings even in --dry-run --- src/bootstrap/src/bin/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 38b380e3db82..07118164a706 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -187,7 +187,8 @@ fn check_version(config: &Config) -> Option { "update `config.toml` to use `change-id = {latest_change_id}` instead" )); - if io::stdout().is_terminal() && !config.dry_run() { + if io::stdout().is_terminal() { + t!(std::fs::create_dir_all(warned_id_path.parent().unwrap())); t!(fs::write(warned_id_path, latest_change_id.to_string())); } } else { From d95d2784da05988bf09bcbf83c460e34030b9362 Mon Sep 17 00:00:00 2001 From: Tongjun Gao Date: Thu, 6 Mar 2025 10:14:39 +0800 Subject: [PATCH 708/991] Adjust relevance scoring threshold to consistent with existing implementations --- src/tools/rust-analyzer/crates/ide-completion/src/item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs index b3dd8a8d06eb..ea52d69c7952 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs @@ -350,7 +350,7 @@ impl CompletionRelevance { /// some threshold such that we think it is especially likely /// to be relevant. pub fn is_relevant(&self) -> bool { - self.score() > 0 + self.score() > (!0 / 2) } } From 1b21952f0279bf39d0f7188638f1a33dc16e5143 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 2 Mar 2025 13:59:00 -0800 Subject: [PATCH 709/991] Also add a MIR pre-codegen test for the derived `PartialOrd::le` --- .../derived_ord.demo_le.PreCodegen.after.mir | 91 +++++++++++++++++++ tests/mir-opt/pre-codegen/derived_ord.rs | 7 ++ 2 files changed, 98 insertions(+) create mode 100644 tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir diff --git a/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir new file mode 100644 index 000000000000..8f47336e2a00 --- /dev/null +++ b/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir @@ -0,0 +1,91 @@ +// MIR for `demo_le` after PreCodegen + +fn demo_le(_1: &MultiField, _2: &MultiField) -> bool { + debug a => _1; + debug b => _2; + let mut _0: bool; + scope 1 (inlined ::le) { + let mut _11: std::option::Option; + scope 2 (inlined Option::::is_some_and:: bool {std::cmp::Ordering::is_le}>) { + let _12: std::cmp::Ordering; + scope 3 { + scope 4 (inlined bool {std::cmp::Ordering::is_le} as FnOnce<(std::cmp::Ordering,)>>::call_once - shim(fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le})) { + scope 5 (inlined std::cmp::Ordering::is_le) { + let mut _13: i8; + let mut _14: bool; + } + } + } + } + scope 6 (inlined ::partial_cmp) { + let mut _6: std::option::Option; + let mut _7: i8; + scope 7 { + } + scope 8 (inlined std::cmp::impls::::partial_cmp) { + let mut _3: char; + let mut _4: char; + let mut _5: std::cmp::Ordering; + } + scope 9 (inlined std::cmp::impls::::partial_cmp) { + let mut _8: i16; + let mut _9: i16; + let mut _10: std::cmp::Ordering; + } + } + } + + bb0: { + StorageLive(_12); + StorageLive(_11); + StorageLive(_5); + StorageLive(_7); + StorageLive(_3); + _3 = copy ((*_1).0: char); + StorageLive(_4); + _4 = copy ((*_2).0: char); + _5 = Cmp(move _3, move _4); + StorageDead(_4); + StorageDead(_3); + _6 = Option::::Some(copy _5); + _7 = discriminant(_5); + switchInt(move _7) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_10); + StorageLive(_8); + _8 = copy ((*_1).1: i16); + StorageLive(_9); + _9 = copy ((*_2).1: i16); + _10 = Cmp(move _8, move _9); + StorageDead(_9); + StorageDead(_8); + _11 = Option::::Some(move _10); + StorageDead(_10); + StorageDead(_7); + StorageDead(_5); + goto -> bb3; + } + + bb2: { + _11 = copy _6; + StorageDead(_7); + StorageDead(_5); + goto -> bb3; + } + + bb3: { + _12 = move ((_11 as Some).0: std::cmp::Ordering); + StorageLive(_13); + StorageLive(_14); + _13 = discriminant(_12); + _14 = Eq(copy _13, const 1_i8); + _0 = Not(move _14); + StorageDead(_14); + StorageDead(_13); + StorageDead(_11); + StorageDead(_12); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/derived_ord.rs b/tests/mir-opt/pre-codegen/derived_ord.rs index bad751edf841..fdfa409d5f27 100644 --- a/tests/mir-opt/pre-codegen/derived_ord.rs +++ b/tests/mir-opt/pre-codegen/derived_ord.rs @@ -6,4 +6,11 @@ #[derive(PartialOrd, PartialEq)] pub struct MultiField(char, i16); +// Because this isn't derived by the impl, it's not on the `{impl#0}-partial_cmp`, +// and thus we need to call it to see what the inlined generic one produces. +pub fn demo_le(a: &MultiField, b: &MultiField) -> bool { + *a <= *b +} + // EMIT_MIR derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir +// EMIT_MIR derived_ord.demo_le.PreCodegen.after.mir From eae5ed609d8afe6c8cd7a231a1bbbb12aba331dd Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 2 Mar 2025 14:30:32 -0800 Subject: [PATCH 710/991] Make `is_le` and friends work like clang's --- library/core/src/cmp.rs | 22 ++++++++++++++----- .../derived_ord.demo_le.PreCodegen.after.mir | 16 ++++++-------- tests/mir-opt/pre-codegen/derived_ord.rs | 19 +++++++++++++++- ....{impl#0}-partial_cmp.PreCodegen.after.mir | 4 ++-- 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index c8ced78c4d79..b29251b4b436 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -397,6 +397,12 @@ pub enum Ordering { } impl Ordering { + #[inline] + const fn as_raw(self) -> i8 { + // FIXME(const-hack): just use `PartialOrd` against `Equal` once that's const + crate::intrinsics::discriminant_value(&self) + } + /// Returns `true` if the ordering is the `Equal` variant. /// /// # Examples @@ -413,7 +419,11 @@ impl Ordering { #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")] #[stable(feature = "ordering_helpers", since = "1.53.0")] pub const fn is_eq(self) -> bool { - matches!(self, Equal) + // All the `is_*` methods are implemented as comparisons against zero + // to follow how clang's libcxx implements their equivalents in + // + + self.as_raw() == 0 } /// Returns `true` if the ordering is not the `Equal` variant. @@ -432,7 +442,7 @@ impl Ordering { #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")] #[stable(feature = "ordering_helpers", since = "1.53.0")] pub const fn is_ne(self) -> bool { - !matches!(self, Equal) + self.as_raw() != 0 } /// Returns `true` if the ordering is the `Less` variant. @@ -451,7 +461,7 @@ impl Ordering { #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")] #[stable(feature = "ordering_helpers", since = "1.53.0")] pub const fn is_lt(self) -> bool { - matches!(self, Less) + self.as_raw() < 0 } /// Returns `true` if the ordering is the `Greater` variant. @@ -470,7 +480,7 @@ impl Ordering { #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")] #[stable(feature = "ordering_helpers", since = "1.53.0")] pub const fn is_gt(self) -> bool { - matches!(self, Greater) + self.as_raw() > 0 } /// Returns `true` if the ordering is either the `Less` or `Equal` variant. @@ -489,7 +499,7 @@ impl Ordering { #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")] #[stable(feature = "ordering_helpers", since = "1.53.0")] pub const fn is_le(self) -> bool { - !matches!(self, Greater) + self.as_raw() <= 0 } /// Returns `true` if the ordering is either the `Greater` or `Equal` variant. @@ -508,7 +518,7 @@ impl Ordering { #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")] #[stable(feature = "ordering_helpers", since = "1.53.0")] pub const fn is_ge(self) -> bool { - !matches!(self, Less) + self.as_raw() >= 0 } /// Reverses the `Ordering`. diff --git a/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir index 8f47336e2a00..49314a64c3fc 100644 --- a/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir @@ -12,22 +12,23 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool { scope 4 (inlined bool {std::cmp::Ordering::is_le} as FnOnce<(std::cmp::Ordering,)>>::call_once - shim(fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le})) { scope 5 (inlined std::cmp::Ordering::is_le) { let mut _13: i8; - let mut _14: bool; + scope 6 (inlined std::cmp::Ordering::as_raw) { + } } } } } - scope 6 (inlined ::partial_cmp) { + scope 7 (inlined ::partial_cmp) { let mut _6: std::option::Option; let mut _7: i8; - scope 7 { + scope 8 { } - scope 8 (inlined std::cmp::impls::::partial_cmp) { + scope 9 (inlined std::cmp::impls::::partial_cmp) { let mut _3: char; let mut _4: char; let mut _5: std::cmp::Ordering; } - scope 9 (inlined std::cmp::impls::::partial_cmp) { + scope 10 (inlined std::cmp::impls::::partial_cmp) { let mut _8: i16; let mut _9: i16; let mut _10: std::cmp::Ordering; @@ -78,11 +79,8 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool { bb3: { _12 = move ((_11 as Some).0: std::cmp::Ordering); StorageLive(_13); - StorageLive(_14); _13 = discriminant(_12); - _14 = Eq(copy _13, const 1_i8); - _0 = Not(move _14); - StorageDead(_14); + _0 = Le(move _13, const 0_i8); StorageDead(_13); StorageDead(_11); StorageDead(_12); diff --git a/tests/mir-opt/pre-codegen/derived_ord.rs b/tests/mir-opt/pre-codegen/derived_ord.rs index fdfa409d5f27..73ae923a6cb9 100644 --- a/tests/mir-opt/pre-codegen/derived_ord.rs +++ b/tests/mir-opt/pre-codegen/derived_ord.rs @@ -1,4 +1,3 @@ -// skip-filecheck //@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0 #![crate_type = "lib"] @@ -9,6 +8,24 @@ pub struct MultiField(char, i16); // Because this isn't derived by the impl, it's not on the `{impl#0}-partial_cmp`, // and thus we need to call it to see what the inlined generic one produces. pub fn demo_le(a: &MultiField, b: &MultiField) -> bool { + // CHECK-LABEL: fn demo_le + // CHECK: inlined ::le + // CHECK: inlined{{.+}}is_some_and + // CHECK: inlined ::partial_cmp + + // CHECK: [[A0:_[0-9]+]] = copy ((*_1).0: char); + // CHECK: [[B0:_[0-9]+]] = copy ((*_2).0: char); + // CHECK: Cmp(move [[A0]], move [[B0]]); + + // CHECK: [[D0:_[0-9]+]] = discriminant({{.+}}); + // CHECK: switchInt(move [[D0]]) -> [0: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}]; + + // CHECK: [[A1:_[0-9]+]] = copy ((*_1).1: i16); + // CHECK: [[B1:_[0-9]+]] = copy ((*_2).1: i16); + // CHECK: Cmp(move [[A1]], move [[B1]]); + + // CHECK: [[D1:_[0-9]+]] = discriminant({{.+}}); + // CHECK: _0 = Le(move [[D1]], const 0_i8); *a <= *b } diff --git a/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir index 5f4ec1de2701..de25eebee77f 100644 --- a/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir @@ -1,6 +1,6 @@ -// MIR for `::partial_cmp` after PreCodegen +// MIR for `::partial_cmp` after PreCodegen -fn ::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option { +fn ::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option { debug self => _1; debug other => _2; let mut _0: std::option::Option; From fde37335aab7df1f9fcdfb0f5079ba76e56d7fe1 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Thu, 6 Mar 2025 07:59:11 +0000 Subject: [PATCH 711/991] `librustdoc`: flatten nested ifs --- src/librustdoc/clean/inline.rs | 10 +- src/librustdoc/clean/mod.rs | 112 ++++++++---------- src/librustdoc/clean/types.rs | 34 +++--- src/librustdoc/config.rs | 16 +-- src/librustdoc/doctest/rust.rs | 5 +- src/librustdoc/formats/cache.rs | 4 +- src/librustdoc/html/highlight.rs | 85 +++++++------ src/librustdoc/html/markdown.rs | 15 ++- src/librustdoc/html/render/span_map.rs | 22 ++-- .../passes/collect_intra_doc_links.rs | 57 +++++---- src/librustdoc/passes/collect_trait_impls.rs | 33 +++--- src/librustdoc/passes/lint/html_tags.rs | 6 +- .../passes/lint/unportable_markdown.rs | 16 +-- src/librustdoc/visit_lib.rs | 8 +- 14 files changed, 203 insertions(+), 220 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index e10a74221ae2..8c6ea00d4890 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -563,11 +563,13 @@ pub(crate) fn build_impl( // Return if the trait itself or any types of the generic parameters are doc(hidden). let mut stack: Vec<&Type> = vec![&for_]; - if let Some(did) = trait_.as_ref().map(|t| t.def_id()) { - if !document_hidden && tcx.is_doc_hidden(did) { - return; - } + if let Some(did) = trait_.as_ref().map(|t| t.def_id()) + && !document_hidden + && tcx.is_doc_hidden(did) + { + return; } + if let Some(generics) = trait_.as_ref().and_then(|t| t.generics()) { stack.extend(generics); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bb12e4a706e7..fd528786d03a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -828,30 +828,26 @@ fn clean_ty_generics<'tcx>( .iter() .flat_map(|(pred, _)| { let mut projection = None; - let param_idx = (|| { + let param_idx = { let bound_p = pred.kind(); match bound_p.skip_binder() { - ty::ClauseKind::Trait(pred) => { - if let ty::Param(param) = pred.self_ty().kind() { - return Some(param.index); - } + ty::ClauseKind::Trait(pred) if let ty::Param(param) = pred.self_ty().kind() => { + Some(param.index) } - ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => { - if let ty::Param(param) = ty.kind() { - return Some(param.index); - } + ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) + if let ty::Param(param) = ty.kind() => + { + Some(param.index) } - ty::ClauseKind::Projection(p) => { - if let ty::Param(param) = p.projection_term.self_ty().kind() { - projection = Some(bound_p.rebind(p)); - return Some(param.index); - } + ty::ClauseKind::Projection(p) + if let ty::Param(param) = p.projection_term.self_ty().kind() => + { + projection = Some(bound_p.rebind(p)); + Some(param.index) } - _ => (), + _ => None, } - - None - })(); + }; if let Some(param_idx) = param_idx && let Some(bounds) = impl_trait.get_mut(¶m_idx) @@ -1378,12 +1374,12 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder(); if self_arg_ty == self_ty { item.decl.inputs.values[0].type_ = SelfTy; - } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() { - if ty == self_ty { - match item.decl.inputs.values[0].type_ { - BorrowedRef { ref mut type_, .. } => **type_ = SelfTy, - _ => unreachable!(), - } + } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() + && ty == self_ty + { + match item.decl.inputs.values[0].type_ { + BorrowedRef { ref mut type_, .. } => **type_ = SelfTy, + _ => unreachable!(), } } } @@ -2331,25 +2327,22 @@ fn clean_middle_opaque_bounds<'tcx>( let bindings: ThinVec<_> = bounds .iter() .filter_map(|(bound, _)| { - if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() { - if proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() { - Some(AssocItemConstraint { - assoc: projection_to_path_segment( - // FIXME: This needs to be made resilient for `AliasTerm`s that - // are associated consts. - bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)), - cx, - ), - kind: AssocItemConstraintKind::Equality { - term: clean_middle_term(bound.kind().rebind(proj.term), cx), - }, - }) - } else { - None - } - } else { - None + if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() + && proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() + { + return Some(AssocItemConstraint { + assoc: projection_to_path_segment( + // FIXME: This needs to be made resilient for `AliasTerm`s that + // are associated consts. + bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)), + cx, + ), + kind: AssocItemConstraintKind::Equality { + term: clean_middle_term(bound.kind().rebind(proj.term), cx), + }, + }); } + None }) .collect(); @@ -2743,23 +2736,20 @@ fn add_without_unwanted_attributes<'hir>( } let mut attr = attr.clone(); match attr { - hir::Attribute::Unparsed(ref mut normal) => { - if let [ident] = &*normal.path.segments { - let ident = ident.name; - if ident == sym::doc { - filter_doc_attr(&mut normal.args, is_inline); - attrs.push((Cow::Owned(attr), import_parent)); - } else if is_inline || ident != sym::cfg { - // If it's not a `cfg()` attribute, we keep it. - attrs.push((Cow::Owned(attr), import_parent)); - } - } - } - hir::Attribute::Parsed(..) => { - if is_inline { + hir::Attribute::Unparsed(ref mut normal) if let [ident] = &*normal.path.segments => { + let ident = ident.name; + if ident == sym::doc { + filter_doc_attr(&mut normal.args, is_inline); + attrs.push((Cow::Owned(attr), import_parent)); + } else if is_inline || ident != sym::cfg { + // If it's not a `cfg()` attribute, we keep it. attrs.push((Cow::Owned(attr), import_parent)); } } + hir::Attribute::Parsed(..) if is_inline => { + attrs.push((Cow::Owned(attr), import_parent)); + } + _ => {} } } } @@ -2961,16 +2951,16 @@ fn clean_extern_crate<'tcx>( && !cx.is_json_output(); let krate_owner_def_id = krate.owner_id.def_id; - if please_inline { - if let Some(items) = inline::try_inline( + if please_inline + && let Some(items) = inline::try_inline( cx, Res::Def(DefKind::Mod, crate_def_id), name, Some((attrs, Some(krate_owner_def_id))), &mut Default::default(), - ) { - return items; - } + ) + { + return items; } vec![Item::from_def_id_and_parts( diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5906a720e0fd..0d33c234f934 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -208,11 +208,11 @@ impl ExternalCrate { .get_attrs(def_id, sym::doc) .flat_map(|attr| attr.meta_item_list().unwrap_or_default()); for meta in meta_items { - if meta.has_name(sym::keyword) { - if let Some(v) = meta.value_str() { - keyword = Some(v); - break; - } + if meta.has_name(sym::keyword) + && let Some(v) = meta.value_str() + { + keyword = Some(v); + break; } } return keyword.map(|p| (def_id, p)); @@ -1071,16 +1071,14 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator // treat #[target_feature(enable = "feat")] attributes as if they were // #[doc(cfg(target_feature = "feat"))] attributes as well for attr in hir_attr_lists(attrs, sym::target_feature) { - if attr.has_name(sym::enable) { - if attr.value_str().is_some() { - // Clone `enable = "feat"`, change to `target_feature = "feat"`. - // Unwrap is safe because `value_str` succeeded above. - let mut meta = attr.meta_item().unwrap().clone(); - meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature)); + if attr.has_name(sym::enable) && attr.value_str().is_some() { + // Clone `enable = "feat"`, change to `target_feature = "feat"`. + // Unwrap is safe because `value_str` succeeded above. + let mut meta = attr.meta_item().unwrap().clone(); + meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature)); - if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) { - cfg &= feat_cfg; - } + if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) { + cfg &= feat_cfg; } } } @@ -1160,10 +1158,10 @@ impl Attributes { continue; } - if let Some(items) = attr.meta_item_list() { - if items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) { - return true; - } + if let Some(items) = attr.meta_item_list() + && items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) + { + return true; } } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e67fe6c88ea4..9cf471733f94 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -645,10 +645,10 @@ impl Options { let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s)); - if let Some(ref p) = extension_css { - if !p.is_file() { - dcx.fatal("option --extend-css argument must be a file"); - } + if let Some(ref p) = extension_css + && !p.is_file() + { + dcx.fatal("option --extend-css argument must be a file"); } let mut themes = Vec::new(); @@ -720,10 +720,10 @@ impl Options { } let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s)); - if let Some(ref index_page) = index_page { - if !index_page.is_file() { - dcx.fatal("option `--index-page` argument must be a file"); - } + if let Some(ref index_page) = index_page + && !index_page.is_file() + { + dcx.fatal("option `--index-page` argument must be a file"); } let target = parse_target_triple(early_dcx, matches); diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 3ac7abd0aa5d..907e2a3eb2fc 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -98,10 +98,9 @@ impl HirCollector<'_> { let ast_attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); if let Some(ref cfg) = extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default()) + && !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features())) { - if !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features())) { - return; - } + return; } let has_name = !name.is_empty(); diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 4760e579199a..2648641e53e7 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -419,7 +419,9 @@ impl DocFolder for CacheBuilder<'_, '_> { } } - if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) { + if let Some(trait_) = &i.trait_ + && let Some(generics) = trait_.generics() + { for bound in generics { dids.extend(bound.def_id(self.cache)); } diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index ed4b97d36252..b7a782e25f54 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -1102,53 +1102,52 @@ fn string_without_closing_tag( }); } - if let Some(href_context) = href_context { - if let Some(href) = - href_context.context.shared.span_correspondence_map.get(&def_span).and_then(|href| { - let context = href_context.context; - // FIXME: later on, it'd be nice to provide two links (if possible) for all items: - // one to the documentation page and one to the source definition. - // FIXME: currently, external items only generate a link to their documentation, - // a link to their definition can be generated using this: - // https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338 - match href { - LinkFromSrc::Local(span) => { - context.href_from_span_relative(*span, &href_context.current_href) - } - LinkFromSrc::External(def_id) => { - format::href_with_root_path(*def_id, context, Some(href_context.root_path)) - .ok() - .map(|(url, _, _)| url) - } - LinkFromSrc::Primitive(prim) => format::href_with_root_path( - PrimitiveType::primitive_locations(context.tcx())[prim], - context, - Some(href_context.root_path), - ) - .ok() - .map(|(url, _, _)| url), - LinkFromSrc::Doc(def_id) => { - format::href_with_root_path(*def_id, context, Some(href_context.root_path)) - .ok() - .map(|(doc_link, _, _)| doc_link) - } + if let Some(href_context) = href_context + && let Some(href) = href_context.context.shared.span_correspondence_map.get(&def_span) + && let Some(href) = { + let context = href_context.context; + // FIXME: later on, it'd be nice to provide two links (if possible) for all items: + // one to the documentation page and one to the source definition. + // FIXME: currently, external items only generate a link to their documentation, + // a link to their definition can be generated using this: + // https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338 + match href { + LinkFromSrc::Local(span) => { + context.href_from_span_relative(*span, &href_context.current_href) } - }) - { - if !open_tag { - // We're already inside an element which has the same klass, no need to give it - // again. - write!(out, "{text_s}").unwrap(); - } else { - let klass_s = klass.as_html(); - if klass_s.is_empty() { - write!(out, "{text_s}").unwrap(); - } else { - write!(out, "{text_s}").unwrap(); + LinkFromSrc::External(def_id) => { + format::href_with_root_path(*def_id, context, Some(href_context.root_path)) + .ok() + .map(|(url, _, _)| url) + } + LinkFromSrc::Primitive(prim) => format::href_with_root_path( + PrimitiveType::primitive_locations(context.tcx())[prim], + context, + Some(href_context.root_path), + ) + .ok() + .map(|(url, _, _)| url), + LinkFromSrc::Doc(def_id) => { + format::href_with_root_path(*def_id, context, Some(href_context.root_path)) + .ok() + .map(|(doc_link, _, _)| doc_link) } } - return Some(""); } + { + if !open_tag { + // We're already inside an element which has the same klass, no need to give it + // again. + write!(out, "{text_s}").unwrap(); + } else { + let klass_s = klass.as_html(); + if klass_s.is_empty() { + write!(out, "{text_s}").unwrap(); + } else { + write!(out, "{text_s}").unwrap(); + } + } + return Some(""); } if !open_tag { write!(out, "{}", text_s).unwrap(); diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index d9e49577d392..083b2c17a1d3 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1308,18 +1308,17 @@ impl LangString { seen_other_tags = true; data.unknown.push(x.to_owned()); } - LangStringToken::KeyValueAttribute(key, value) => { - if key == "class" { - data.added_classes.push(value.to_owned()); - } else if let Some(extra) = extra { - extra.error_invalid_codeblock_attr(format!( - "unsupported attribute `{key}`" - )); - } + LangStringToken::KeyValueAttribute("class", value) => { + data.added_classes.push(value.to_owned()); + } + LangStringToken::KeyValueAttribute(key, ..) if let Some(extra) = extra => { + extra + .error_invalid_codeblock_attr(format!("unsupported attribute `{key}`")); } LangStringToken::ClassAttribute(class) => { data.added_classes.push(class.to_owned()); } + _ => {} } } }; diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index ce9c42c01cc7..82385c1c4db5 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -95,10 +95,8 @@ impl SpanMapVisitor<'_> { .unwrap_or(path.span); self.matches.insert(span, link); } - Res::Local(_) => { - if let Some(span) = self.tcx.hir().res_span(path.res) { - self.matches.insert(path.span, LinkFromSrc::Local(clean::Span::new(span))); - } + Res::Local(_) if let Some(span) = self.tcx.hir().res_span(path.res) => { + self.matches.insert(path.span, LinkFromSrc::Local(clean::Span::new(span))); } Res::PrimTy(p) => { // FIXME: Doesn't handle "path-like" primitives like arrays or tuples. @@ -111,15 +109,15 @@ impl SpanMapVisitor<'_> { /// Used to generate links on items' definition to go to their documentation page. pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) { - if let Node::Item(item) = self.tcx.hir_node(hir_id) { - if let Some(span) = self.tcx.def_ident_span(item.owner_id) { - let cspan = clean::Span::new(span); - // If the span isn't from the current crate, we ignore it. - if cspan.inner().is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE { - return; - } - self.matches.insert(span, LinkFromSrc::Doc(item.owner_id.to_def_id())); + if let Node::Item(item) = self.tcx.hir_node(hir_id) + && let Some(span) = self.tcx.def_ident_span(item.owner_id) + { + let cspan = clean::Span::new(span); + // If the span isn't from the current crate, we ignore it. + if cspan.inner().is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE { + return; } + self.matches.insert(span, LinkFromSrc::Doc(item.owner_id.to_def_id())); } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 440d6331457b..4ffce85851cb 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1334,14 +1334,12 @@ impl LinkCollector<'_, '_> { } // item can be non-local e.g. when using `#[rustc_doc_primitive = "pointer"]` - if let Some((src_id, dst_id)) = id.as_local().and_then(|dst_id| { - diag_info.item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id)) - }) { - if self.cx.tcx.effective_visibilities(()).is_exported(src_id) - && !self.cx.tcx.effective_visibilities(()).is_exported(dst_id) - { - privacy_error(self.cx, diag_info, path_str); - } + if let Some(dst_id) = id.as_local() + && let Some(src_id) = diag_info.item.item_id.expect_def_id().as_local() + && self.cx.tcx.effective_visibilities(()).is_exported(src_id) + && !self.cx.tcx.effective_visibilities(()).is_exported(dst_id) + { + privacy_error(self.cx, diag_info, path_str); } Some(()) @@ -1405,10 +1403,10 @@ impl LinkCollector<'_, '_> { // which we want in some cases but not in others. cache_errors: bool, ) -> Option)>> { - if let Some(res) = self.visited_links.get(&key) { - if res.is_some() || cache_errors { - return res.clone().map(|r| vec![r]); - } + if let Some(res) = self.visited_links.get(&key) + && (res.is_some() || cache_errors) + { + return res.clone().map(|r| vec![r]); } let mut candidates = self.resolve_with_disambiguator(&key, diag.clone()); @@ -1432,10 +1430,10 @@ impl LinkCollector<'_, '_> { // and after removing duplicated kinds, only one remains, the `ambiguity_error` function // won't emit an error. So at this point, we can just take the first candidate as it was // the first retrieved and use it to generate the link. - if let [candidate, _candidate2, ..] = *candidates { - if !ambiguity_error(self.cx, &diag, &key.path_str, &candidates, false) { - candidates = vec![candidate]; - } + if let [candidate, _candidate2, ..] = *candidates + && !ambiguity_error(self.cx, &diag, &key.path_str, &candidates, false) + { + candidates = vec![candidate]; } let mut out = Vec::with_capacity(candidates.len()); @@ -1480,17 +1478,16 @@ impl LinkCollector<'_, '_> { // See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach. let mut err = ResolutionFailure::NotResolved(err); for other_ns in [TypeNS, ValueNS, MacroNS] { - if other_ns != expected_ns { - if let Ok(&[res, ..]) = self + if other_ns != expected_ns + && let Ok(&[res, ..]) = self .resolve(path_str, other_ns, None, item_id, module_id) .as_deref() - { - err = ResolutionFailure::WrongNamespace { - res: full_res(self.cx.tcx, res), - expected_ns, - }; - break; - } + { + err = ResolutionFailure::WrongNamespace { + res: full_res(self.cx.tcx, res), + expected_ns, + }; + break; } } resolution_failure(self, diag, path_str, disambiguator, smallvec![err]); @@ -1674,11 +1671,11 @@ impl Disambiguator { Ok(Some((d, &rest[1..], &rest[1..]))) } else { for (suffix, kind) in suffixes { - if let Some(path_str) = link.strip_suffix(suffix) { - // Avoid turning `!` or `()` into an empty string - if !path_str.is_empty() { - return Ok(Some((Kind(kind), path_str, link))); - } + // Avoid turning `!` or `()` into an empty string + if let Some(path_str) = link.strip_suffix(suffix) + && !path_str.is_empty() + { + return Ok(Some((Kind(kind), path_str, link))); } } Ok(None) diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 87f85c573152..f4e4cd924f7f 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -177,23 +177,22 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> } else if let Some(did) = target.def_id(&cx.cache) { cleaner.items.insert(did.into()); } - if let Some(for_did) = for_.def_id(&cx.cache) { - if type_did_to_deref_target.insert(for_did, target).is_none() { - // Since only the `DefId` portion of the `Type` instances is known to be same for both the - // `Deref` target type and the impl for type positions, this map of types is keyed by - // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. - if cleaner.keep_impl_with_def_id(for_did.into()) { - let mut targets = DefIdSet::default(); - targets.insert(for_did); - add_deref_target( - cx, - &type_did_to_deref_target, - &mut cleaner, - &mut targets, - for_did, - ); - } - } + if let Some(for_did) = for_.def_id(&cx.cache) + && type_did_to_deref_target.insert(for_did, target).is_none() + // Since only the `DefId` portion of the `Type` instances is known to be same for both the + // `Deref` target type and the impl for type positions, this map of types is keyed by + // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. + && cleaner.keep_impl_with_def_id(for_did.into()) + { + let mut targets = DefIdSet::default(); + targets.insert(for_did); + add_deref_target( + cx, + &type_did_to_deref_target, + &mut cleaner, + &mut targets, + for_did, + ); } } } diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index 3fb154dc5154..b9739726c956 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -28,9 +28,9 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & // We don't try to detect stuff `` because that's not valid HTML, // and we don't try to detect stuff `` because that's not valid Rust. let mut generics_end = range.end; - if let Some(Some(mut generics_start)) = (is_open_tag - && dox[..generics_end].ends_with('>')) - .then(|| extract_path_backwards(dox, range.start)) + if is_open_tag + && dox[..generics_end].ends_with('>') + && let Some(mut generics_start) = extract_path_backwards(dox, range.start) { while generics_start != 0 && generics_end < dox.len() diff --git a/src/librustdoc/passes/lint/unportable_markdown.rs b/src/librustdoc/passes/lint/unportable_markdown.rs index a3c3134f4c2c..95646413a2d2 100644 --- a/src/librustdoc/passes/lint/unportable_markdown.rs +++ b/src/librustdoc/passes/lint/unportable_markdown.rs @@ -73,15 +73,15 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & } let parser_old = cmarko::Parser::new_ext(dox, main_body_opts_old()).into_offset_iter(); for (event, span) in parser_old { - if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event { - if !dox[span.clone()].starts_with("> ") { - spaceless_block_quotes.remove(&span.start); - } + if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event + && !dox[span.clone()].starts_with("> ") + { + spaceless_block_quotes.remove(&span.start); } - if let cmarko::Event::FootnoteReference(_) = event { - if !found_footnote_references.contains(&(span.start + 1)) { - missing_footnote_references.insert(span.start + 1, span); - } + if let cmarko::Event::FootnoteReference(_) = event + && !found_footnote_references.contains(&(span.start + 1)) + { + missing_footnote_references.insert(span.start + 1, span); } } } diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index 3e66ed9f56da..369fc52860ee 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -57,10 +57,10 @@ impl LibEmbargoVisitor<'_, '_> { } for item in self.tcx.module_children(def_id).iter() { - if let Some(def_id) = item.res.opt_def_id() { - if item.vis.is_public() { - self.visit_item(def_id); - } + if let Some(def_id) = item.res.opt_def_id() + && item.vis.is_public() + { + self.visit_item(def_id); } } } From 7e199b10c9efc765024d5bad1f964ddaf6b9a131 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 6 Mar 2025 16:23:23 +0800 Subject: [PATCH 712/991] Add ui test: suggest-struct-or-union-add-generic-impl-trait.rs Signed-off-by: xizheyin --- ...-struct-or-union-add-generic-impl-trait.rs | 30 +++++++++++ ...uct-or-union-add-generic-impl-trait.stderr | 51 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs create mode 100644 tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr diff --git a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs b/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs new file mode 100644 index 000000000000..9963b5be4f2b --- /dev/null +++ b/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs @@ -0,0 +1,30 @@ +//@ edition:2021 +trait Trait {} + +struct Foo1 { + a: Trait, + //~^ ERROR expected a type, found a trait + b: u32, +} + +struct Foo2 { + a: i32, + b: Trait, + //~^ ERROR expected a type, found a trait +} + + +enum Enum1 { + A(Trait), + //~^ ERROR expected a type, found a trait + B(u32), +} + +enum Enum2 { + A(u32), + B(Trait), + //~^ ERROR expected a type, found a trait +} + + +fn main() {} diff --git a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr b/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr new file mode 100644 index 000000000000..433196919caf --- /dev/null +++ b/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr @@ -0,0 +1,51 @@ +error[E0782]: expected a type, found a trait + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:5:8 + | +LL | a: Trait, + | ^^^^^ + | +help: you might be missing a type parameter + | +LL ~ struct Foo1 { +LL ~ a: T, + | + +error[E0782]: expected a type, found a trait + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:12:8 + | +LL | b: Trait, + | ^^^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | b: dyn Trait, + | +++ + +error[E0782]: expected a type, found a trait + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:18:7 + | +LL | A(Trait), + | ^^^^^ + | +help: you might be missing a type parameter + | +LL ~ enum Enum1 { +LL ~ A(T), + | + +error[E0782]: expected a type, found a trait + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:25:7 + | +LL | B(Trait), + | ^^^^^ + | +help: you might be missing a type parameter + | +LL ~ enum Enum2 { +LL | A(u32), +LL ~ B(T), + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0782`. From e13af7abca71ec6aac4c2115c9563663b83c88cf Mon Sep 17 00:00:00 2001 From: moxian Date: Thu, 6 Mar 2025 01:07:02 -0800 Subject: [PATCH 713/991] Don't even bother checking changelog in --dry-run mode --- src/bootstrap/src/bin/main.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 07118164a706..6f6aaa878ef6 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -70,11 +70,12 @@ fn main() { } // check_version warnings are not printed during setup, or during CI - let changelog_suggestion = if matches!(config.cmd, Subcommand::Setup { .. }) || CiEnv::is_ci() { - None - } else { - check_version(&config) - }; + let changelog_suggestion = + if matches!(config.cmd, Subcommand::Setup { .. }) || CiEnv::is_ci() || config.dry_run() { + None + } else { + check_version(&config) + }; // NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the // changelog warning, not the `x.py setup` message. @@ -188,7 +189,6 @@ fn check_version(config: &Config) -> Option { )); if io::stdout().is_terminal() { - t!(std::fs::create_dir_all(warned_id_path.parent().unwrap())); t!(fs::write(warned_id_path, latest_change_id.to_string())); } } else { From ca64815c702162c7c36f165f07462ce32b14d68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 6 Mar 2025 09:16:24 +0000 Subject: [PATCH 714/991] Revert "rustc_middle: parallel: TyCtxt: remove "unsafe impl DynSend/DynSync"" This reverts commit 8eba29ac1015e989e6ba96ff17a75d548afde7ff. --- compiler/rustc_middle/src/ty/context.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d0aa2b8cbdad..2d2bbd22b984 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1327,6 +1327,9 @@ pub struct TyCtxt<'tcx> { gcx: &'tcx GlobalCtxt<'tcx>, } +// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. +unsafe impl DynSend for TyCtxt<'_> {} +unsafe impl DynSync for TyCtxt<'_> {} fn _assert_tcx_fields() { sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>(); sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>(); From 4f2b108816e782f68d5964bec74448c04bd36ac5 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Feb 2025 10:37:49 +0000 Subject: [PATCH 715/991] Prefer a two value enum over bool --- compiler/rustc_hir/src/hir.rs | 2 +- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 5 ----- compiler/rustc_lint/src/types.rs | 11 ++++------- compiler/rustc_middle/src/ty/pattern.rs | 8 +++----- compiler/rustc_middle/src/ty/structural_impls.rs | 1 + compiler/rustc_smir/src/rustc_internal/internal.rs | 3 ++- compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 5 ++++- compiler/rustc_ty_utils/src/layout.rs | 5 +++-- 9 files changed, 19 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 399f1f4b2373..3b506039025a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1600,7 +1600,7 @@ pub struct PatField<'hir> { pub span: Span, } -#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic, Hash, Eq, Encodable, Decodable)] pub enum RangeEnd { Included, Excluded, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index d044688246f9..fe446492acab 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2708,11 +2708,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)); let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)); - let include_end = match include_end { - hir::RangeEnd::Included => true, - hir::RangeEnd::Excluded => false, - }; - let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end }); Ty::new_pat(tcx, ty, pat) } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index d2b08eab4791..8304d533c269 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -5,7 +5,7 @@ use rustc_abi::{BackendRepr, TagEncoding, VariantIdx, Variants, WrappingRange}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::DiagMessage; use rustc_hir::intravisit::VisitorExt; -use rustc_hir::{AmbigArg, Expr, ExprKind, HirId, LangItem}; +use rustc_hir::{AmbigArg, Expr, ExprKind, HirId, LangItem, RangeEnd}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton}; use rustc_middle::ty::{ @@ -893,12 +893,9 @@ fn ty_is_known_nonnull<'tcx>( let end = end.try_to_value()?.try_to_bits(tcx, typing_env)?; - if include_end { - // This also works for negative numbers, as we just need - // to ensure we aren't wrapping over zero. - start > 0 && end >= start - } else { - start > 0 && end > start + match include_end { + RangeEnd::Included => start > 0 && end >= start, + RangeEnd::Excluded => start > 0 && end > start, } } _ => false, diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index e604aedd05e3..48ae5b1e657d 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -1,6 +1,7 @@ use std::fmt; use rustc_data_structures::intern::Interned; +use rustc_hir::RangeEnd; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use crate::ty; @@ -30,10 +31,7 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> { if let Some(start) = start { write!(f, "{start}")?; } - write!(f, "..")?; - if include_end { - write!(f, "=")?; - } + write!(f, "{include_end}")?; if let Some(end) = end { write!(f, "{end}")?; } @@ -46,5 +44,5 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> { #[derive(Clone, PartialEq, Eq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] pub enum PatternKind<'tcx> { - Range { start: Option>, end: Option>, include_end: bool }, + Range { start: Option>, end: Option>, include_end: RangeEnd }, } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index db9e9fbc643b..6c62c04f42e4 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -284,6 +284,7 @@ TrivialTypeTraversalImpls! { rustc_hir::def_id::LocalDefId, rustc_hir::HirId, rustc_hir::MatchSource, + rustc_hir::RangeEnd, rustc_span::Ident, rustc_span::Span, rustc_span::Symbol, diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index 50cf605ba2a8..093ce5f56488 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -5,6 +5,7 @@ // Prefer importing stable_mir over internal rustc constructs to make this file more readable. +use rustc_hir::RangeEnd; use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt}; use rustc_span::Symbol; use stable_mir::abi::Layout; @@ -91,7 +92,7 @@ impl RustcInternal for Pattern { Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range { start: start.as_ref().map(|c| c.internal(tables, tcx)), end: end.as_ref().map(|c| c.internal(tables, tcx)), - include_end: *include_end, + include_end: if *include_end { RangeEnd::Included } else { RangeEnd::Excluded }, }, }) } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index a0faf20c79a6..9c06d08d61b5 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -408,7 +408,7 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { ty::PatternKind::Range { start, end, include_end } => stable_mir::ty::Pattern::Range { start: start.stable(tables), end: end.stable(tables), - include_end, + include_end: matches!(include_end, rustc_hir::RangeEnd::Included), }, } } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index a11f6f0df1c5..79ab51ec9b33 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -417,7 +417,10 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { let consts = [ start.unwrap_or(self.tcx.consts.unit), end.unwrap_or(self.tcx.consts.unit), - ty::Const::from_bool(self.tcx, include_end), + ty::Const::from_bool( + self.tcx, + matches!(include_end, rustc_hir::RangeEnd::Included), + ), ]; // HACK: Represent as tuple until we have something better. // HACK: constants are used in arrays, even if the types don't match. diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 852d3fc58d87..2ba3fb22e6cf 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -218,8 +218,9 @@ fn layout_of_uncached<'tcx>( let mut end = extract_const_value(cx, ty, end)? .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; - if !include_end { - end = end.wrapping_sub(1); + match include_end { + rustc_hir::RangeEnd::Included => {} + rustc_hir::RangeEnd::Excluded => end = end.wrapping_sub(1), } scalar.valid_range_mut().end = end; } From 0e7b2835735fc7fee08505fa6c14670bc7ee7601 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 5 Feb 2025 15:22:10 +0000 Subject: [PATCH 716/991] Avoid having to handle an `Option` in the type system --- .../src/hir_ty_lowering/mod.rs | 89 ++++++++++++++++--- .../src/variance/constraints.rs | 8 +- compiler/rustc_lint/src/types.rs | 22 ++--- compiler/rustc_middle/src/ty/flags.rs | 8 +- compiler/rustc_middle/src/ty/pattern.rs | 11 +-- compiler/rustc_middle/src/ty/relate.rs | 23 +++-- compiler/rustc_middle/src/ty/walk.rs | 4 +- .../rustc_smir/src/rustc_internal/internal.rs | 4 +- .../rustc_smir/src/rustc_smir/convert/ty.rs | 5 +- compiler/rustc_symbol_mangling/src/v0.rs | 4 +- .../rustc_trait_selection/src/traits/wf.rs | 8 +- compiler/rustc_ty_utils/src/layout.rs | 25 +++--- .../pattern_types.main.PreCodegen.after.mir | 4 +- tests/mir-opt/pattern_types.rs | 4 +- tests/ui/lint/clashing-extern-fn.stderr | 4 +- tests/ui/type/pattern_types/nested.stderr | 18 ++-- .../type/pattern_types/range_patterns.stderr | 4 +- .../range_patterns_trait_impls2.stderr | 2 +- .../range_patterns_unusable.stderr | 2 +- .../range_patterns_unusable_math.rs | 2 +- .../range_patterns_unusable_math.stderr | 4 +- 21 files changed, 146 insertions(+), 109 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index fe446492acab..21581d304d9a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -21,8 +21,9 @@ pub mod generics; mod lint; use std::assert_matches::assert_matches; -use std::slice; +use std::{char, slice}; +use rustc_abi::Size; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; @@ -31,7 +32,7 @@ use rustc_errors::{ }; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId}; +use rustc_hir::{self as hir, AnonConst, ConstArg, GenericArg, GenericArgs, HirId}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; @@ -2693,20 +2694,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ty = self.lower_ty(ty); let pat_ty = match pat.kind { hir::TyPatKind::Range(start, end, include_end) => { - let ty = match ty.kind() { - ty::Int(_) | ty::Uint(_) | ty::Char => ty, - _ => Ty::new_error( - tcx, - self.dcx().emit_err(InvalidBaseType { + let (ty, start, end) = match ty.kind() { + ty::Int(_) | ty::Uint(_) | ty::Char => { + let (start, end) = self.lower_ty_pat_range(ty, start, end); + (ty, start, end) + } + _ => { + let guar = self.dcx().emit_err(InvalidBaseType { ty, pat: "range", ty_span, pat_span: pat.span, - }), - ), + }); + let errc = ty::Const::new_error(tcx, guar); + (Ty::new_error(tcx, guar), errc, errc) + } }; - let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)); - let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)); let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end }); Ty::new_pat(tcx, ty, pat) @@ -2723,6 +2726,70 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { result_ty } + fn lower_ty_pat_range( + &self, + base: Ty<'tcx>, + start: Option<&ConstArg<'tcx>>, + end: Option<&ConstArg<'tcx>>, + ) -> (ty::Const<'tcx>, ty::Const<'tcx>) { + let tcx = self.tcx(); + let size = match base.kind() { + ty::Int(i) => { + i.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits)) + } + ty::Uint(ui) => { + ui.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits)) + } + ty::Char => Size::from_bytes(4), + _ => unreachable!(), + }; + let start = + start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else(|| { + match base.kind() { + ty::Char | ty::Uint(_) => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int(ty::ScalarInt::null(size)), + base, + ), + ty::Int(_) => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int( + ty::ScalarInt::truncate_from_int(size.signed_int_min(), size).0, + ), + base, + ), + _ => unreachable!(), + } + }); + let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else( + || match base.kind() { + ty::Char => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int( + ty::ScalarInt::truncate_from_uint(char::MAX, size).0, + ), + base, + ), + ty::Uint(_) => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int( + ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size).0, + ), + base, + ), + ty::Int(_) => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int( + ty::ScalarInt::truncate_from_int(size.signed_int_max(), size).0, + ), + base, + ), + _ => unreachable!(), + }, + ); + (start, end) + } + /// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR. #[instrument(level = "debug", skip(self), ret)] fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index e954d2b9ea48..4b336769cfb8 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -253,12 +253,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::Pat(typ, pat) => { match *pat { ty::PatternKind::Range { start, end, include_end: _ } => { - if let Some(start) = start { - self.add_constraints_from_const(current, start, variance); - } - if let Some(end) = end { - self.add_constraints_from_const(current, end, variance); - } + self.add_constraints_from_const(current, start, variance); + self.add_constraints_from_const(current, end, variance); } } self.add_constraints_from_ty(current, typ, variance); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 8304d533c269..d873d9fca649 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -883,22 +883,14 @@ fn ty_is_known_nonnull<'tcx>( try { match **pat { ty::PatternKind::Range { start, end, include_end } => { - match (start, end) { - (Some(start), None) => { - start.try_to_value()?.try_to_bits(tcx, typing_env)? > 0 - } - (Some(start), Some(end)) => { - let start = - start.try_to_value()?.try_to_bits(tcx, typing_env)?; - let end = - end.try_to_value()?.try_to_bits(tcx, typing_env)?; + let start = start.try_to_value()?.try_to_bits(tcx, typing_env)?; + let end = end.try_to_value()?.try_to_bits(tcx, typing_env)?; - match include_end { - RangeEnd::Included => start > 0 && end >= start, - RangeEnd::Excluded => start > 0 && end > start, - } - } - _ => false, + match include_end { + // This also works for negative numbers, as we just need + // to ensure we aren't wrapping over zero. + RangeEnd::Included => start > 0 && end >= start, + RangeEnd::Excluded => start > 0 && end > start, } } } diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index ec0498b168c0..c08d78e25b8d 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -221,12 +221,8 @@ impl FlagComputation { self.add_ty(ty); match *pat { ty::PatternKind::Range { start, end, include_end: _ } => { - if let Some(start) = start { - self.add_const(start) - } - if let Some(end) = end { - self.add_const(end) - } + self.add_const(start); + self.add_const(end); } } } diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index 48ae5b1e657d..a1dfd2e8d34f 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -28,14 +28,7 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { PatternKind::Range { start, end, include_end } => { - if let Some(start) = start { - write!(f, "{start}")?; - } - write!(f, "{include_end}")?; - if let Some(end) = end { - write!(f, "{end}")?; - } - Ok(()) + write!(f, "{start}{include_end}{end}") } } } @@ -44,5 +37,5 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> { #[derive(Clone, PartialEq, Eq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] pub enum PatternKind<'tcx> { - Range { start: Option>, end: Option>, include_end: RangeEnd }, + Range { start: ty::Const<'tcx>, end: ty::Const<'tcx>, include_end: RangeEnd }, } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 839c1c346a47..6d5cc42065f2 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -54,19 +54,18 @@ impl<'tcx> Relate> for ty::Pattern<'tcx> { &ty::PatternKind::Range { start: start_a, end: end_a, include_end: inc_a }, &ty::PatternKind::Range { start: start_b, end: end_b, include_end: inc_b }, ) => { - // FIXME(pattern_types): make equal patterns equal (`0..=` is the same as `..=`). - let mut relate_opt_const = |a, b| match (a, b) { - (None, None) => Ok(None), - (Some(a), Some(b)) => relation.relate(a, b).map(Some), - // FIXME(pattern_types): report a better error - _ => Err(TypeError::Mismatch), - }; - let start = relate_opt_const(start_a, start_b)?; - let end = relate_opt_const(end_a, end_b)?; - if inc_a != inc_b { - todo!() + let start = relation.relate(start_a, start_b)?; + // FIXME(pattern_types): make equal patterns equal (`0..5` is the same as `0..=6`). + let end = relation.relate(end_a, end_b)?; + if inc_a == inc_b { + Ok(relation.cx().mk_pat(ty::PatternKind::Range { + start, + end, + include_end: inc_a, + })) + } else { + Err(TypeError::Mismatch) } - Ok(relation.cx().mk_pat(ty::PatternKind::Range { start, end, include_end: inc_a })) } } } diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 3e8a3d1a2892..b31b7cac41ef 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -138,8 +138,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) ty::Pat(ty, pat) => { match *pat { ty::PatternKind::Range { start, end, include_end: _ } => { - stack.extend(end.map(Into::into)); - stack.extend(start.map(Into::into)); + stack.push(end.into()); + stack.push(start.into()); } } stack.push(ty.into()); diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index 093ce5f56488..a8c4cd660fd9 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -90,8 +90,8 @@ impl RustcInternal for Pattern { fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { tcx.mk_pat(match self { Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range { - start: start.as_ref().map(|c| c.internal(tables, tcx)), - end: end.as_ref().map(|c| c.internal(tables, tcx)), + start: start.as_ref().unwrap().internal(tables, tcx), + end: end.as_ref().unwrap().internal(tables, tcx), include_end: if *include_end { RangeEnd::Included } else { RangeEnd::Excluded }, }, }) diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 9c06d08d61b5..f6a6a3c1737f 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -406,8 +406,9 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { match **self { ty::PatternKind::Range { start, end, include_end } => stable_mir::ty::Pattern::Range { - start: start.stable(tables), - end: end.stable(tables), + // FIXME(SMIR): update data structures to not have an Option here anymore + start: Some(start.stable(tables)), + end: Some(end.stable(tables)), include_end: matches!(include_end, rustc_hir::RangeEnd::Included), }, } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 79ab51ec9b33..bb21d84b09dc 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -415,8 +415,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ty::Pat(ty, pat) => match *pat { ty::PatternKind::Range { start, end, include_end } => { let consts = [ - start.unwrap_or(self.tcx.consts.unit), - end.unwrap_or(self.tcx.consts.unit), + start, + end, ty::Const::from_bool( self.tcx, matches!(include_end, rustc_hir::RangeEnd::Included), diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 18906a6a8ce0..0fece96a3eb4 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -738,12 +738,8 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { } } }; - if let Some(start) = start { - check(start) - } - if let Some(end) = end { - check(end) - } + check(start); + check(end); } } } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 2ba3fb22e6cf..e5f4a8b87bb0 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -209,21 +209,18 @@ fn layout_of_uncached<'tcx>( if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) = &mut layout.backend_repr { - if let Some(start) = start { - scalar.valid_range_mut().start = extract_const_value(cx, ty, start)? - .try_to_bits(tcx, cx.typing_env) - .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; - } - if let Some(end) = end { - let mut end = extract_const_value(cx, ty, end)? - .try_to_bits(tcx, cx.typing_env) - .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; - match include_end { - rustc_hir::RangeEnd::Included => {} - rustc_hir::RangeEnd::Excluded => end = end.wrapping_sub(1), - } - scalar.valid_range_mut().end = end; + scalar.valid_range_mut().start = extract_const_value(cx, ty, start)? + .try_to_bits(tcx, cx.typing_env) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; + + let mut end = extract_const_value(cx, ty, end)? + .try_to_bits(tcx, cx.typing_env) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; + match include_end { + rustc_hir::RangeEnd::Included => {} + rustc_hir::RangeEnd::Excluded => end = end.wrapping_sub(1), } + scalar.valid_range_mut().end = end; let niche = Niche { offset: Size::ZERO, diff --git a/tests/mir-opt/pattern_types.main.PreCodegen.after.mir b/tests/mir-opt/pattern_types.main.PreCodegen.after.mir index 5ff90de96150..8214ff61d75e 100644 --- a/tests/mir-opt/pattern_types.main.PreCodegen.after.mir +++ b/tests/mir-opt/pattern_types.main.PreCodegen.after.mir @@ -3,9 +3,9 @@ fn main() -> () { let mut _0: (); scope 1 { - debug x => const 2_u32 is 1..=; + debug x => const 2_u32 is 1..=u32::MAX; scope 2 { - debug y => const {transmute(0x00000000): (u32) is 1..=}; + debug y => const {transmute(0x00000000): (u32) is 1..=u32::MAX}; } } diff --git a/tests/mir-opt/pattern_types.rs b/tests/mir-opt/pattern_types.rs index 0369ccf9a9d5..6d5391993452 100644 --- a/tests/mir-opt/pattern_types.rs +++ b/tests/mir-opt/pattern_types.rs @@ -5,8 +5,8 @@ use std::pat::pattern_type; // EMIT_MIR pattern_types.main.PreCodegen.after.mir fn main() { - // CHECK: debug x => const 2_u32 is 1..= + // CHECK: debug x => const 2_u32 is 1..=u32::MAX let x: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(2) }; - // CHECK: debug y => const {transmute(0x00000000): (u32) is 1..=} + // CHECK: debug y => const {transmute(0x00000000): (u32) is 1..=u32::MAX} let y: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) }; } diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr index 118b18b224c0..85ca701a3b64 100644 --- a/tests/ui/lint/clashing-extern-fn.stderr +++ b/tests/ui/lint/clashing-extern-fn.stderr @@ -17,7 +17,7 @@ LL | fn hidden_niche_unsafe_cell() -> Option`, which is not FFI-safe +warning: `extern` block uses type `Option<(usize) is 0..=usize::MAX>`, which is not FFI-safe --> $DIR/clashing-extern-fn.rs:502:54 | LL | fn pt_non_zero_usize_opt_full_range() -> Option; @@ -276,7 +276,7 @@ LL | fn pt_non_null_ptr() -> pattern_type!(usize is 1..); LL | fn pt_non_null_ptr() -> *const (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | - = note: expected `unsafe extern "C" fn() -> (usize) is 1..=` + = note: expected `unsafe extern "C" fn() -> (usize) is 1..=usize::MAX` found `unsafe extern "C" fn() -> *const ()` warning: 24 warnings emitted diff --git a/tests/ui/type/pattern_types/nested.stderr b/tests/ui/type/pattern_types/nested.stderr index b753b0a9c9ba..a606fd013c5e 100644 --- a/tests/ui/type/pattern_types/nested.stderr +++ b/tests/ui/type/pattern_types/nested.stderr @@ -1,4 +1,4 @@ -error: `(u32) is 1..=` is not a valid base type for range patterns +error: `(u32) is 1..=u32::MAX` is not a valid base type for range patterns --> $DIR/nested.rs:10:34 | LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); @@ -10,7 +10,7 @@ note: range patterns only support integers LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); | ^^^ -error: `(i32) is 1..=` is not a valid base type for range patterns +error: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns --> $DIR/nested.rs:15:35 | LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); @@ -22,7 +22,7 @@ note: range patterns only support integers LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); | ^^^^^ -error: `(i32) is 1..=` is not a valid base type for range patterns +error: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns --> $DIR/nested.rs:19:35 | LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); @@ -62,27 +62,27 @@ error[E0308]: mismatched types --> $DIR/nested.rs:10:63 | LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); - | ^ expected `(u32) is 1..=`, found integer + | ^ expected `(u32) is 1..=u32::MAX`, found integer | - = note: expected pattern type `(u32) is 1..=` + = note: expected pattern type `(u32) is 1..=u32::MAX` found type `{integer}` error[E0308]: mismatched types --> $DIR/nested.rs:15:67 | LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); - | ^^ expected `(i32) is 1..=`, found integer + | ^^ expected `(i32) is 1..=i32::MAX`, found integer | - = note: expected pattern type `(i32) is 1..=` + = note: expected pattern type `(i32) is 1..=i32::MAX` found type `{integer}` error[E0308]: mismatched types --> $DIR/nested.rs:19:66 | LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); - | ^ expected `(i32) is 1..=`, found integer + | ^ expected `(i32) is 1..=i32::MAX`, found integer | - = note: expected pattern type `(i32) is 1..=` + = note: expected pattern type `(i32) is 1..=i32::MAX` found type `{integer}` error[E0308]: mismatched types diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 690592ba0b8d..43ae7e870f00 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -44,7 +44,7 @@ error: layout_of(NonZero) = Layout { LL | type X = std::num::NonZeroU32; | ^^^^^^ -error: layout_of((u32) is 1..=) = Layout { +error: layout_of((u32) is 1..=u32::MAX) = Layout { size: Size(4 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), @@ -83,7 +83,7 @@ error: layout_of((u32) is 1..=) = Layout { LL | type Y = pattern_type!(u32 is 1..); | ^^^^^^ -error: layout_of(Option<(u32) is 1..=>) = Layout { +error: layout_of(Option<(u32) is 1..=u32::MAX>) = Layout { size: Size(4 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), diff --git a/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr b/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr index d5c539b6c52e..565d8f18cdbb 100644 --- a/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr +++ b/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Eq for Y {} | ^^^^^^^^^^^^- | | - | `(u32) is 1..=` is not defined in the current crate + | `(u32) is 1..=u32::MAX` is not defined in the current crate | = note: impl doesn't have any local type before any uncovered type parameters = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules diff --git a/tests/ui/type/pattern_types/range_patterns_unusable.stderr b/tests/ui/type/pattern_types/range_patterns_unusable.stderr index 8377d417452b..a9558852eb29 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable.stderr +++ b/tests/ui/type/pattern_types/range_patterns_unusable.stderr @@ -4,7 +4,7 @@ error[E0512]: cannot transmute between types of different sizes, or dependently- LL | let _: Option = unsafe { std::mem::transmute(z) }; | ^^^^^^^^^^^^^^^^^^^ | - = note: source type: `Option<(u32) is 1..=>` (32 bits) + = note: source type: `Option<(u32) is 1..=u32::MAX>` (32 bits) = note: target type: `Option` (64 bits) error: aborting due to 1 previous error diff --git a/tests/ui/type/pattern_types/range_patterns_unusable_math.rs b/tests/ui/type/pattern_types/range_patterns_unusable_math.rs index ece4009e1e7d..54ad6096c577 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable_math.rs +++ b/tests/ui/type/pattern_types/range_patterns_unusable_math.rs @@ -11,5 +11,5 @@ type Z = Option; fn main() { let x: Y = unsafe { std::mem::transmute(42_u32) }; - let x = x + 1_u32; //~ ERROR cannot add `u32` to `(u32) is 1..=` + let x = x + 1_u32; //~ ERROR cannot add `u32` to `(u32) is 1..=u32::MAX` } diff --git a/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr b/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr index 373615e3714e..68ddd63cd530 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr +++ b/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr @@ -1,10 +1,10 @@ -error[E0369]: cannot add `u32` to `(u32) is 1..=` +error[E0369]: cannot add `u32` to `(u32) is 1..=u32::MAX` --> $DIR/range_patterns_unusable_math.rs:14:15 | LL | let x = x + 1_u32; | - ^ ----- u32 | | - | (u32) is 1..= + | (u32) is 1..=u32::MAX error: aborting due to 1 previous error From ad45962939cd901fbb3c6e47d9ad8310eea52536 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 6 Mar 2025 11:04:35 +0100 Subject: [PATCH 717/991] `apply_closure_requirement` use `LocalDefId` --- .../rustc_borrowck/src/type_check/constraint_conversion.rs | 6 +++--- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 3b48ca305c45..8dff40ba6ac3 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -1,4 +1,4 @@ -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; @@ -88,7 +88,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { pub(crate) fn apply_closure_requirements( &mut self, closure_requirements: &ClosureRegionRequirements<'tcx>, - closure_def_id: DefId, + closure_def_id: LocalDefId, closure_args: ty::GenericArgsRef<'tcx>, ) { // Extract the values of the free regions in `closure_args` @@ -98,7 +98,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { self.tcx, closure_args, closure_requirements.num_external_vids, - closure_def_id.expect_local(), + closure_def_id, ); debug!(?closure_mapping); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6d05696e146f..8edd3912366e 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2582,7 +2582,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Boring, // same as above. self.constraints, ) - .apply_closure_requirements(closure_requirements, def_id.to_def_id(), args); + .apply_closure_requirements(closure_requirements, def_id, args); } // Now equate closure args to regions inherited from `typeck_root_def_id`. Fixes #98589. From e8f7a382be12a812b7d73f58967f740a0cf9d9af Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 5 Feb 2025 15:22:10 +0000 Subject: [PATCH 718/991] Remove the `Option` part of range ends in the HIR --- compiler/rustc_ast_lowering/src/lib.rs | 4 +- compiler/rustc_ast_lowering/src/pat.rs | 122 +++++++++- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir/src/intravisit.rs | 6 +- compiler/rustc_hir/src/lang_items.rs | 3 + compiler/rustc_hir_analysis/messages.ftl | 3 - compiler/rustc_hir_analysis/src/errors.rs | 2 - .../src/errors/pattern_types.rs | 14 -- .../src/hir_ty_lowering/mod.rs | 90 +------ .../src/variance/constraints.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 15 +- compiler/rustc_lint/src/types.rs | 13 +- compiler/rustc_middle/src/ty/flags.rs | 2 +- compiler/rustc_middle/src/ty/pattern.rs | 7 +- compiler/rustc_middle/src/ty/relate.rs | 15 +- compiler/rustc_middle/src/ty/walk.rs | 2 +- .../rustc_smir/src/rustc_internal/internal.rs | 4 +- .../rustc_smir/src/rustc_smir/convert/ty.rs | 4 +- compiler/rustc_span/src/hygiene.rs | 3 + compiler/rustc_span/src/symbol.rs | 4 + compiler/rustc_symbol_mangling/src/v0.rs | 11 +- .../rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_ty_utils/src/layout.rs | 9 +- library/core/src/pat.rs | 62 +++++ .../clippy/clippy_utils/src/hir_utils.rs | 11 +- tests/ui/lint/clashing-extern-fn.stderr | 2 +- tests/ui/type/pattern_types/nested.rs | 2 + tests/ui/type/pattern_types/nested.stderr | 220 ++++++++++++------ .../range_patterns_trait_impls2.stderr | 2 +- tests/ui/type/pattern_types/reverse_range.rs | 13 +- .../type/pattern_types/reverse_range.stderr | 16 +- tests/ui/type/pattern_types/validity.rs | 2 +- 32 files changed, 400 insertions(+), 269 deletions(-) delete mode 100644 compiler/rustc_hir_analysis/src/errors/pattern_types.rs diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c0188dde5651..ee131bb51f64 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -136,6 +136,7 @@ struct LoweringContext<'a, 'hir> { allow_try_trait: Arc<[Symbol]>, allow_gen_future: Arc<[Symbol]>, + allow_pattern_type: Arc<[Symbol]>, allow_async_iterator: Arc<[Symbol]>, allow_for_await: Arc<[Symbol]>, allow_async_fn_traits: Arc<[Symbol]>, @@ -176,6 +177,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { impl_trait_defs: Vec::new(), impl_trait_bounds: Vec::new(), allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(), + allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(), allow_gen_future: if tcx.features().async_fn_track_caller() { [sym::gen_future, sym::closure_track_caller].into() } else { @@ -1365,7 +1367,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } TyKind::Pat(ty, pat) => { - hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat)) + hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span)) } TyKind::MacCall(_) => { span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now") diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 2dcfe7c745da..728981dea5f8 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -3,11 +3,11 @@ use std::sync::Arc; use rustc_ast::ptr::P; use rustc_ast::*; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_hir as hir; -use rustc_hir::def::Res; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{self as hir, LangItem}; use rustc_middle::span_bug; use rustc_span::source_map::{Spanned, respan}; -use rustc_span::{Ident, Span}; +use rustc_span::{DesugaringKind, Ident, Span, kw}; use super::errors::{ ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding, @@ -430,22 +430,124 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind }) } - pub(crate) fn lower_ty_pat(&mut self, pattern: &TyPat) -> &'hir hir::TyPat<'hir> { - self.arena.alloc(self.lower_ty_pat_mut(pattern)) + pub(crate) fn lower_ty_pat( + &mut self, + pattern: &TyPat, + base_type: Span, + ) -> &'hir hir::TyPat<'hir> { + self.arena.alloc(self.lower_ty_pat_mut(pattern, base_type)) } - fn lower_ty_pat_mut(&mut self, pattern: &TyPat) -> hir::TyPat<'hir> { + fn lower_ty_pat_mut(&mut self, pattern: &TyPat, base_type: Span) -> hir::TyPat<'hir> { // loop here to avoid recursion let pat_hir_id = self.lower_node_id(pattern.id); let node = match &pattern.kind { - TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range( - e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)), - e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)), - self.lower_range_end(end, e2.is_some()), + TyPatKind::Range(e1, e2, Spanned { node: end, span }) => hir::TyPatKind::Range( + e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)).unwrap_or_else(|| { + self.lower_ty_pat_range_end( + hir::LangItem::RangeMin, + span.shrink_to_lo(), + base_type, + ) + }), + e2.as_deref() + .map(|e| match end { + RangeEnd::Included(..) => self.lower_anon_const_to_const_arg(e), + RangeEnd::Excluded => self.lower_excluded_range_end(e), + }) + .unwrap_or_else(|| { + self.lower_ty_pat_range_end( + hir::LangItem::RangeMax, + span.shrink_to_hi(), + base_type, + ) + }), ), TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar), }; hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) } } + + /// Lowers the range end of an exclusive range (`2..5`) to an inclusive range 2..=(5 - 1). + /// This way the type system doesn't have to handle the distinction between inclusive/exclusive ranges. + fn lower_excluded_range_end(&mut self, e: &AnonConst) -> &'hir hir::ConstArg<'hir> { + let span = self.lower_span(e.value.span); + let unstable_span = self.mark_span_with_reason( + DesugaringKind::PatTyRange, + span, + Some(Arc::clone(&self.allow_pattern_type)), + ); + let anon_const = self.with_new_scopes(span, |this| { + let def_id = this.local_def_id(e.id); + let hir_id = this.lower_node_id(e.id); + let body = this.lower_body(|this| { + // Need to use a custom function as we can't just subtract `1` from a `char`. + let kind = hir::ExprKind::Path(this.make_lang_item_qpath( + hir::LangItem::RangeSub, + unstable_span, + None, + )); + let fn_def = this.arena.alloc(hir::Expr { hir_id: this.next_id(), kind, span }); + let args = this.arena.alloc([this.lower_expr_mut(&e.value)]); + ( + &[], + hir::Expr { + hir_id: this.next_id(), + kind: hir::ExprKind::Call(fn_def, args), + span, + }, + ) + }); + hir::AnonConst { def_id, hir_id, body, span } + }); + self.arena.alloc(hir::ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Anon(self.arena.alloc(anon_const)), + }) + } + + /// When a range has no end specified (`1..` or `1..=`) or no start specified (`..5` or `..=5`), + /// we instead use a constant of the MAX/MIN of the type. + /// This way the type system does not have to handle the lack of a start/end. + fn lower_ty_pat_range_end( + &mut self, + lang_item: LangItem, + span: Span, + base_type: Span, + ) -> &'hir hir::ConstArg<'hir> { + let parent_def_id = self.current_hir_id_owner.def_id; + let node_id = self.next_node_id(); + + // Add a definition for the in-band const def. + // We're generating a range end that didn't exist in the AST, + // so the def collector didn't create the def ahead of time. That's why we have to do + // it here. + let def_id = self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span); + let hir_id = self.lower_node_id(node_id); + + let unstable_span = self.mark_span_with_reason( + DesugaringKind::PatTyRange, + self.lower_span(span), + Some(Arc::clone(&self.allow_pattern_type)), + ); + let span = self.lower_span(base_type); + + let path_expr = hir::Expr { + hir_id: self.next_id(), + kind: hir::ExprKind::Path(self.make_lang_item_qpath(lang_item, unstable_span, None)), + span, + }; + + let ct = self.with_new_scopes(span, |this| { + self.arena.alloc(hir::AnonConst { + def_id, + hir_id, + body: this.lower_body(|_this| (&[], path_expr)), + span, + }) + }); + let hir_id = self.next_id(); + self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id }) + } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 3b506039025a..df305e6e769d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1668,7 +1668,7 @@ pub enum PatExprKind<'hir> { #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TyPatKind<'hir> { /// A range pattern (e.g., `1..=2` or `1..2`). - Range(Option<&'hir ConstArg<'hir>>, Option<&'hir ConstArg<'hir>>, RangeEnd), + Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>), /// A placeholder for a pattern that wasn't well formed in some way. Err(ErrorGuaranteed), diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index e349e23f7dcf..41eb5b45bd1e 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -708,9 +708,9 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Res pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) -> V::Result { try_visit!(visitor.visit_id(pattern.hir_id)); match pattern.kind { - TyPatKind::Range(lower_bound, upper_bound, _) => { - visit_opt!(visitor, visit_const_arg_unambig, lower_bound); - visit_opt!(visitor, visit_const_arg_unambig, upper_bound); + TyPatKind::Range(lower_bound, upper_bound) => { + try_visit!(visitor.visit_const_arg_unambig(lower_bound)); + try_visit!(visitor.visit_const_arg_unambig(upper_bound)); } TyPatKind::Err(_) => (), } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index f5626937ec45..c3b14a4e06c7 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -418,6 +418,9 @@ language_item_table! { Range, sym::Range, range_struct, Target::Struct, GenericRequirement::None; RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct, GenericRequirement::None; RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None; + RangeMax, sym::RangeMax, range_max, Target::AssocConst, GenericRequirement::Exact(0); + RangeMin, sym::RangeMin, range_min, Target::AssocConst, GenericRequirement::Exact(0); + RangeSub, sym::RangeSub, range_sub, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0); // `new_range` types that are `Copy + IntoIterator` RangeFromCopy, sym::RangeFromCopy, range_from_copy_struct, Target::Struct, GenericRequirement::None; diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 3f75cce00922..d16aba197fe5 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -244,9 +244,6 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a .help = consider moving this inherent impl into the crate defining the type if possible .span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items -hir_analysis_invalid_base_type = `{$ty}` is not a valid base type for range patterns - .note = range patterns only support integers - hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}` .note = type of `self` must not be a method generic parameter type diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 852533ff5c95..f3e1e89812ca 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -11,8 +11,6 @@ use rustc_middle::ty::Ty; use rustc_span::{Ident, Span, Symbol}; use crate::fluent_generated as fluent; -mod pattern_types; -pub(crate) use pattern_types::*; pub(crate) mod wrong_number_of_generic_args; mod precise_captures; diff --git a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs deleted file mode 100644 index ec7b3aaa1c14..000000000000 --- a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs +++ /dev/null @@ -1,14 +0,0 @@ -use rustc_macros::Diagnostic; -use rustc_middle::ty::Ty; -use rustc_span::Span; - -#[derive(Diagnostic)] -#[diag(hir_analysis_invalid_base_type)] -pub(crate) struct InvalidBaseType<'tcx> { - pub ty: Ty<'tcx>, - #[primary_span] - pub ty_span: Span, - pub pat: &'static str, - #[note] - pub pat_span: Span, -} diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 21581d304d9a..dd6c40bfbb8d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -21,9 +21,8 @@ pub mod generics; mod lint; use std::assert_matches::assert_matches; -use std::{char, slice}; +use std::slice; -use rustc_abi::Size; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; @@ -32,7 +31,7 @@ use rustc_errors::{ }; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, AnonConst, ConstArg, GenericArg, GenericArgs, HirId}; +use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; @@ -56,9 +55,7 @@ use tracing::{debug, instrument}; use self::errors::assoc_kind_str; use crate::check::check_abi_fn_ptr; -use crate::errors::{ - AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, NoVariantNamed, -}; +use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, NoVariantNamed}; use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint}; use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args}; use crate::middle::resolve_bound_vars as rbv; @@ -2693,25 +2690,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ty_span = ty.span; let ty = self.lower_ty(ty); let pat_ty = match pat.kind { - hir::TyPatKind::Range(start, end, include_end) => { + hir::TyPatKind::Range(start, end) => { let (ty, start, end) = match ty.kind() { + // Keep this list of types in sync with the list of types that + // the `RangePattern` trait is implemented for. ty::Int(_) | ty::Uint(_) | ty::Char => { - let (start, end) = self.lower_ty_pat_range(ty, start, end); + let start = self.lower_const_arg(start, FeedConstTy::No); + let end = self.lower_const_arg(end, FeedConstTy::No); (ty, start, end) } _ => { - let guar = self.dcx().emit_err(InvalidBaseType { - ty, - pat: "range", + let guar = self.dcx().span_delayed_bug( ty_span, - pat_span: pat.span, - }); + "invalid base type for range pattern", + ); let errc = ty::Const::new_error(tcx, guar); (Ty::new_error(tcx, guar), errc, errc) } }; - let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end }); + let pat = tcx.mk_pat(ty::PatternKind::Range { start, end }); Ty::new_pat(tcx, ty, pat) } hir::TyPatKind::Err(e) => Ty::new_error(tcx, e), @@ -2726,70 +2724,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { result_ty } - fn lower_ty_pat_range( - &self, - base: Ty<'tcx>, - start: Option<&ConstArg<'tcx>>, - end: Option<&ConstArg<'tcx>>, - ) -> (ty::Const<'tcx>, ty::Const<'tcx>) { - let tcx = self.tcx(); - let size = match base.kind() { - ty::Int(i) => { - i.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits)) - } - ty::Uint(ui) => { - ui.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits)) - } - ty::Char => Size::from_bytes(4), - _ => unreachable!(), - }; - let start = - start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else(|| { - match base.kind() { - ty::Char | ty::Uint(_) => ty::Const::new_value( - tcx, - ty::ValTree::from_scalar_int(ty::ScalarInt::null(size)), - base, - ), - ty::Int(_) => ty::Const::new_value( - tcx, - ty::ValTree::from_scalar_int( - ty::ScalarInt::truncate_from_int(size.signed_int_min(), size).0, - ), - base, - ), - _ => unreachable!(), - } - }); - let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else( - || match base.kind() { - ty::Char => ty::Const::new_value( - tcx, - ty::ValTree::from_scalar_int( - ty::ScalarInt::truncate_from_uint(char::MAX, size).0, - ), - base, - ), - ty::Uint(_) => ty::Const::new_value( - tcx, - ty::ValTree::from_scalar_int( - ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size).0, - ), - base, - ), - ty::Int(_) => ty::Const::new_value( - tcx, - ty::ValTree::from_scalar_int( - ty::ScalarInt::truncate_from_int(size.signed_int_max(), size).0, - ), - base, - ), - _ => unreachable!(), - }, - ); - (start, end) - } - /// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR. #[instrument(level = "debug", skip(self), ret)] fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 4b336769cfb8..8475903c68fd 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -252,7 +252,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::Pat(typ, pat) => { match *pat { - ty::PatternKind::Range { start, end, include_end: _ } => { + ty::PatternKind::Range { start, end } => { self.add_constraints_from_const(current, start, variance); self.add_constraints_from_const(current, end, variance); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 1658c8dac676..147b42c04908 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1943,17 +1943,10 @@ impl<'a> State<'a> { // Pat isn't normalized, but the beauty of it // is that it doesn't matter match pat.kind { - TyPatKind::Range(begin, end, end_kind) => { - if let Some(expr) = begin { - self.print_const_arg(expr); - } - match end_kind { - RangeEnd::Included => self.word("..."), - RangeEnd::Excluded => self.word(".."), - } - if let Some(expr) = end { - self.print_const_arg(expr); - } + TyPatKind::Range(begin, end) => { + self.print_const_arg(begin); + self.word("..="); + self.print_const_arg(end); } TyPatKind::Err(_) => { self.popen(); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index d873d9fca649..fcadbfc3c4a7 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -5,7 +5,7 @@ use rustc_abi::{BackendRepr, TagEncoding, VariantIdx, Variants, WrappingRange}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::DiagMessage; use rustc_hir::intravisit::VisitorExt; -use rustc_hir::{AmbigArg, Expr, ExprKind, HirId, LangItem, RangeEnd}; +use rustc_hir::{AmbigArg, Expr, ExprKind, HirId, LangItem}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton}; use rustc_middle::ty::{ @@ -882,16 +882,13 @@ fn ty_is_known_nonnull<'tcx>( || Option::unwrap_or_default( try { match **pat { - ty::PatternKind::Range { start, end, include_end } => { + ty::PatternKind::Range { start, end } => { let start = start.try_to_value()?.try_to_bits(tcx, typing_env)?; let end = end.try_to_value()?.try_to_bits(tcx, typing_env)?; - match include_end { - // This also works for negative numbers, as we just need - // to ensure we aren't wrapping over zero. - RangeEnd::Included => start > 0 && end >= start, - RangeEnd::Excluded => start > 0 && end > start, - } + // This also works for negative numbers, as we just need + // to ensure we aren't wrapping over zero. + start > 0 && end >= start } } }, diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index c08d78e25b8d..0b8f0e8cd41d 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -220,7 +220,7 @@ impl FlagComputation { &ty::Pat(ty, pat) => { self.add_ty(ty); match *pat { - ty::PatternKind::Range { start, end, include_end: _ } => { + ty::PatternKind::Range { start, end } => { self.add_const(start); self.add_const(end); } diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index a1dfd2e8d34f..89dadb36ad64 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -1,7 +1,6 @@ use std::fmt; use rustc_data_structures::intern::Interned; -use rustc_hir::RangeEnd; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use crate::ty; @@ -27,8 +26,8 @@ impl<'tcx> fmt::Debug for Pattern<'tcx> { impl<'tcx> fmt::Debug for PatternKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - PatternKind::Range { start, end, include_end } => { - write!(f, "{start}{include_end}{end}") + PatternKind::Range { start, end } => { + write!(f, "{start}..={end}") } } } @@ -37,5 +36,5 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> { #[derive(Clone, PartialEq, Eq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] pub enum PatternKind<'tcx> { - Range { start: ty::Const<'tcx>, end: ty::Const<'tcx>, include_end: RangeEnd }, + Range { start: ty::Const<'tcx>, end: ty::Const<'tcx> }, } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 6d5cc42065f2..b1dfcb80bde5 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -51,21 +51,12 @@ impl<'tcx> Relate> for ty::Pattern<'tcx> { ) -> RelateResult<'tcx, Self> { match (&*a, &*b) { ( - &ty::PatternKind::Range { start: start_a, end: end_a, include_end: inc_a }, - &ty::PatternKind::Range { start: start_b, end: end_b, include_end: inc_b }, + &ty::PatternKind::Range { start: start_a, end: end_a }, + &ty::PatternKind::Range { start: start_b, end: end_b }, ) => { let start = relation.relate(start_a, start_b)?; - // FIXME(pattern_types): make equal patterns equal (`0..5` is the same as `0..=6`). let end = relation.relate(end_a, end_b)?; - if inc_a == inc_b { - Ok(relation.cx().mk_pat(ty::PatternKind::Range { - start, - end, - include_end: inc_a, - })) - } else { - Err(TypeError::Mismatch) - } + Ok(relation.cx().mk_pat(ty::PatternKind::Range { start, end })) } } } diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index b31b7cac41ef..a23316ae6fc8 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -137,7 +137,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) ty::Pat(ty, pat) => { match *pat { - ty::PatternKind::Range { start, end, include_end: _ } => { + ty::PatternKind::Range { start, end } => { stack.push(end.into()); stack.push(start.into()); } diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index a8c4cd660fd9..bb2b2dea2f37 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -5,7 +5,6 @@ // Prefer importing stable_mir over internal rustc constructs to make this file more readable. -use rustc_hir::RangeEnd; use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt}; use rustc_span::Symbol; use stable_mir::abi::Layout; @@ -89,10 +88,9 @@ impl RustcInternal for Pattern { type T<'tcx> = rustc_ty::Pattern<'tcx>; fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { tcx.mk_pat(match self { - Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range { + Pattern::Range { start, end, include_end: _ } => rustc_ty::PatternKind::Range { start: start.as_ref().unwrap().internal(tables, tcx), end: end.as_ref().unwrap().internal(tables, tcx), - include_end: if *include_end { RangeEnd::Included } else { RangeEnd::Excluded }, }, }) } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index f6a6a3c1737f..aa0eac628dd0 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -405,11 +405,11 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { match **self { - ty::PatternKind::Range { start, end, include_end } => stable_mir::ty::Pattern::Range { + ty::PatternKind::Range { start, end } => stable_mir::ty::Pattern::Range { // FIXME(SMIR): update data structures to not have an Option here anymore start: Some(start.stable(tables)), end: Some(end.stable(tables)), - include_end: matches!(include_end, rustc_hir::RangeEnd::Included), + include_end: true, }, } } diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 84e89ff4b7da..64982b858c64 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1173,6 +1173,8 @@ pub enum DesugaringKind { BoundModifier, /// Calls to contract checks (`#[requires]` to precond, `#[ensures]` to postcond) Contract, + /// A pattern type range start/end + PatTyRange, } impl DesugaringKind { @@ -1190,6 +1192,7 @@ impl DesugaringKind { DesugaringKind::WhileLoop => "`while` loop", DesugaringKind::BoundModifier => "trait bound modifier", DesugaringKind::Contract => "contract check", + DesugaringKind::PatTyRange => "pattern type", } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 522bccb1acb0..573c65a772cb 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -308,6 +308,9 @@ symbols! { RangeFull, RangeInclusive, RangeInclusiveCopy, + RangeMax, + RangeMin, + RangeSub, RangeTo, RangeToInclusive, Rc, @@ -1522,6 +1525,7 @@ symbols! { pattern_complexity_limit, pattern_parentheses, pattern_type, + pattern_type_range_trait, pattern_types, permissions_from_mode, phantom_data, diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index bb21d84b09dc..bc3923e4b4d6 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -413,15 +413,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { } ty::Pat(ty, pat) => match *pat { - ty::PatternKind::Range { start, end, include_end } => { - let consts = [ - start, - end, - ty::Const::from_bool( - self.tcx, - matches!(include_end, rustc_hir::RangeEnd::Included), - ), - ]; + ty::PatternKind::Range { start, end } => { + let consts = [start, end]; // HACK: Represent as tuple until we have something better. // HACK: constants are used in arrays, even if the types don't match. self.push("T"); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 0fece96a3eb4..54b6c22b2d82 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -708,7 +708,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { ty::Pat(subty, pat) => { self.require_sized(subty, ObligationCauseCode::Misc); match *pat { - ty::PatternKind::Range { start, end, include_end: _ } => { + ty::PatternKind::Range { start, end } => { let mut check = |c| { let cause = self.cause(ObligationCauseCode::Misc); self.out.push(traits::Obligation::with_depth( diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index e5f4a8b87bb0..a53f0538c581 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -205,7 +205,7 @@ fn layout_of_uncached<'tcx>( let layout = cx.layout_of(ty)?.layout; let mut layout = LayoutData::clone(&layout.0); match *pat { - ty::PatternKind::Range { start, end, include_end } => { + ty::PatternKind::Range { start, end } => { if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) = &mut layout.backend_repr { @@ -213,14 +213,9 @@ fn layout_of_uncached<'tcx>( .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; - let mut end = extract_const_value(cx, ty, end)? + scalar.valid_range_mut().end = extract_const_value(cx, ty, end)? .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; - match include_end { - rustc_hir::RangeEnd::Included => {} - rustc_hir::RangeEnd::Excluded => end = end.wrapping_sub(1), - } - scalar.valid_range_mut().end = end; let niche = Niche { offset: Size::ZERO, diff --git a/library/core/src/pat.rs b/library/core/src/pat.rs index 752e79c2dace..f8826096df3e 100644 --- a/library/core/src/pat.rs +++ b/library/core/src/pat.rs @@ -12,3 +12,65 @@ macro_rules! pattern_type { /* compiler built-in */ }; } + +/// A trait implemented for integer types and `char`. +/// Useful in the future for generic pattern types, but +/// used right now to simplify ast lowering of pattern type ranges. +#[unstable(feature = "pattern_type_range_trait", issue = "123646")] +#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")] +#[const_trait] +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a valid base type for range patterns", + label = "only integer types and `char` are supported" +)] +pub trait RangePattern { + /// Trait version of the inherent `MIN` assoc const. + #[cfg_attr(not(bootstrap), lang = "RangeMin")] + const MIN: Self; + + /// Trait version of the inherent `MIN` assoc const. + #[cfg_attr(not(bootstrap), lang = "RangeMax")] + const MAX: Self; + + /// A compile-time helper to subtract 1 for exclusive ranges. + #[cfg_attr(not(bootstrap), lang = "RangeSub")] + #[track_caller] + fn sub_one(self) -> Self; +} + +macro_rules! impl_range_pat { + ($($ty:ty,)*) => { + $( + #[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")] + impl const RangePattern for $ty { + const MIN: $ty = <$ty>::MIN; + const MAX: $ty = <$ty>::MAX; + fn sub_one(self) -> Self { + match self.checked_sub(1) { + Some(val) => val, + None => panic!("exclusive range end at minimum value of type") + } + } + } + )* + } +} + +impl_range_pat! { + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize, +} + +#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")] +impl const RangePattern for char { + const MIN: Self = char::MIN; + + const MAX: Self = char::MAX; + + fn sub_one(self) -> Self { + match char::from_u32(self as u32 - 1) { + None => panic!("exclusive range to start of valid chars"), + Some(val) => val, + } + } +} diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 4bd86a253351..c47c08285c2e 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -1108,14 +1108,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { pub fn hash_ty_pat(&mut self, pat: &TyPat<'_>) { std::mem::discriminant(&pat.kind).hash(&mut self.s); match pat.kind { - TyPatKind::Range(s, e, i) => { - if let Some(s) = s { - self.hash_const_arg(s); - } - if let Some(e) = e { - self.hash_const_arg(e); - } - std::mem::discriminant(&i).hash(&mut self.s); + TyPatKind::Range(s, e) => { + self.hash_const_arg(s); + self.hash_const_arg(e); }, TyPatKind::Err(_) => {}, } diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr index 85ca701a3b64..4e9f6ea3f78c 100644 --- a/tests/ui/lint/clashing-extern-fn.stderr +++ b/tests/ui/lint/clashing-extern-fn.stderr @@ -276,7 +276,7 @@ LL | fn pt_non_null_ptr() -> pattern_type!(usize is 1..); LL | fn pt_non_null_ptr() -> *const (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | - = note: expected `unsafe extern "C" fn() -> (usize) is 1..=usize::MAX` + = note: expected `unsafe extern "C" fn() -> (usize) is 1..=` found `unsafe extern "C" fn() -> *const ()` warning: 24 warnings emitted diff --git a/tests/ui/type/pattern_types/nested.rs b/tests/ui/type/pattern_types/nested.rs index 9ca9c7923ded..0d8cd22190e5 100644 --- a/tests/ui/type/pattern_types/nested.rs +++ b/tests/ui/type/pattern_types/nested.rs @@ -18,10 +18,12 @@ const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); //~^ ERROR: not a valid base type for range patterns +//~| ERROR: not a valid base type for range patterns //~| ERROR: mismatched types const BAD_NESTING4: pattern_type!(() is ..0) = todo!(); //~^ ERROR: not a valid base type for range patterns +//~| ERROR: not a valid base type for range patterns //~| ERROR: mismatched types const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!(); diff --git a/tests/ui/type/pattern_types/nested.stderr b/tests/ui/type/pattern_types/nested.stderr index a606fd013c5e..04aacabc136e 100644 --- a/tests/ui/type/pattern_types/nested.stderr +++ b/tests/ui/type/pattern_types/nested.stderr @@ -1,63 +1,3 @@ -error: `(u32) is 1..=u32::MAX` is not a valid base type for range patterns - --> $DIR/nested.rs:10:34 - | -LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: range patterns only support integers - --> $DIR/nested.rs:10:63 - | -LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); - | ^^^ - -error: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns - --> $DIR/nested.rs:15:35 - | -LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: range patterns only support integers - --> $DIR/nested.rs:15:64 - | -LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); - | ^^^^^ - -error: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns - --> $DIR/nested.rs:19:35 - | -LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: range patterns only support integers - --> $DIR/nested.rs:19:64 - | -LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); - | ^^^ - -error: `()` is not a valid base type for range patterns - --> $DIR/nested.rs:23:35 - | -LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!(); - | ^^ - | -note: range patterns only support integers - --> $DIR/nested.rs:23:41 - | -LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!(); - | ^^^ - -error: `f32` is not a valid base type for range patterns - --> $DIR/nested.rs:27:35 - | -LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!(); - | ^^^ - | -note: range patterns only support integers - --> $DIR/nested.rs:27:42 - | -LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!(); - | ^^^^^^^^^^ - error[E0308]: mismatched types --> $DIR/nested.rs:10:63 | @@ -67,6 +7,42 @@ LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!( = note: expected pattern type `(u32) is 1..=u32::MAX` found type `{integer}` +error[E0277]: `(u32) is 1..=u32::MAX` is not a valid base type for range patterns + --> $DIR/nested.rs:10:34 + | +LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported + | + = help: the trait `core::pat::RangePattern` is not implemented for `(u32) is 1..=u32::MAX` + = help: the following other types implement trait `core::pat::RangePattern`: + char + i128 + i16 + i32 + i64 + i8 + isize + u128 + and 5 others + +error[E0277]: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns + --> $DIR/nested.rs:15:35 + | +LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported + | + = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..=i32::MAX` + = help: the following other types implement trait `core::pat::RangePattern`: + char + i128 + i16 + i32 + i64 + i8 + isize + u128 + and 5 others + error[E0308]: mismatched types --> $DIR/nested.rs:15:67 | @@ -76,21 +52,133 @@ LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = tod = note: expected pattern type `(i32) is 1..=i32::MAX` found type `{integer}` +error[E0277]: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns + --> $DIR/nested.rs:19:35 + | +LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported + | + = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..=i32::MAX` + = help: the following other types implement trait `core::pat::RangePattern`: + char + i128 + i16 + i32 + i64 + i8 + isize + u128 + and 5 others + error[E0308]: mismatched types --> $DIR/nested.rs:19:66 | LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); - | ^ expected `(i32) is 1..=i32::MAX`, found integer + | ^ + | | + | expected `(i32) is 1..=i32::MAX`, found integer + | arguments to this function are incorrect | = note: expected pattern type `(i32) is 1..=i32::MAX` found type `{integer}` +help: the return type of this call is `{integer}` due to the type of the argument passed + --> $DIR/nested.rs:19:66 + | +LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); + | ^ this argument influences the return type of `RangeSub` +note: method defined here + --> $SRC_DIR/core/src/pat.rs:LL:COL -error[E0308]: mismatched types - --> $DIR/nested.rs:23:43 +error[E0277]: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns + --> $DIR/nested.rs:19:66 + | +LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); + | ^ only integer types and `char` are supported + | + = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..=i32::MAX` + = help: the following other types implement trait `core::pat::RangePattern`: + char + i128 + i16 + i32 + i64 + i8 + isize + u128 + and 5 others + +error[E0277]: `()` is not a valid base type for range patterns + --> $DIR/nested.rs:24:35 | LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!(); - | ^ expected `()`, found integer + | ^^ only integer types and `char` are supported + | + = help: the trait `core::pat::RangePattern` is not implemented for `()` + = help: the following other types implement trait `core::pat::RangePattern`: + char + i128 + i16 + i32 + i64 + i8 + isize + u128 + and 5 others -error: aborting due to 9 previous errors +error[E0308]: mismatched types + --> $DIR/nested.rs:24:43 + | +LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!(); + | ^ + | | + | expected `()`, found integer + | arguments to this function are incorrect + | +help: the return type of this call is `{integer}` due to the type of the argument passed + --> $DIR/nested.rs:24:43 + | +LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!(); + | ^ this argument influences the return type of `RangeSub` +note: method defined here + --> $SRC_DIR/core/src/pat.rs:LL:COL -For more information about this error, try `rustc --explain E0308`. +error[E0277]: `()` is not a valid base type for range patterns + --> $DIR/nested.rs:24:43 + | +LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!(); + | ^ only integer types and `char` are supported + | + = help: the trait `core::pat::RangePattern` is not implemented for `()` + = help: the following other types implement trait `core::pat::RangePattern`: + char + i128 + i16 + i32 + i64 + i8 + isize + u128 + and 5 others + +error[E0277]: `f32` is not a valid base type for range patterns + --> $DIR/nested.rs:29:49 + | +LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!(); + | ^^^ only integer types and `char` are supported + | + = help: the trait `core::pat::RangePattern` is not implemented for `f32` + = help: the following other types implement trait `core::pat::RangePattern`: + i128 + i16 + i32 + i64 + i8 + isize + u128 + u16 + and 4 others + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr b/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr index 565d8f18cdbb..d5c539b6c52e 100644 --- a/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr +++ b/tests/ui/type/pattern_types/range_patterns_trait_impls2.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl Eq for Y {} | ^^^^^^^^^^^^- | | - | `(u32) is 1..=u32::MAX` is not defined in the current crate + | `(u32) is 1..=` is not defined in the current crate | = note: impl doesn't have any local type before any uncovered type parameters = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules diff --git a/tests/ui/type/pattern_types/reverse_range.rs b/tests/ui/type/pattern_types/reverse_range.rs index 6a245615f1ac..e698e9dd541d 100644 --- a/tests/ui/type/pattern_types/reverse_range.rs +++ b/tests/ui/type/pattern_types/reverse_range.rs @@ -1,14 +1,11 @@ //! Check that the range start must be smaller than the range end -//@ known-bug: unknown -//@ failure-status: 101 -//@ normalize-stderr: "note: .*\n\n" -> "" -//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@ rustc-env:RUST_BACKTRACE=0 - -#![feature(pattern_types)] +#![feature(pattern_types, const_trait_impl, pattern_type_range_trait)] #![feature(pattern_type_macro)] use std::pat::pattern_type; const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) }; +//~^ NOTE: exclusive range end at minimum value of type +//~| ERROR: evaluation of constant value failed + +fn main() {} diff --git a/tests/ui/type/pattern_types/reverse_range.stderr b/tests/ui/type/pattern_types/reverse_range.stderr index b714ca7d9ab9..90f8ef3261a0 100644 --- a/tests/ui/type/pattern_types/reverse_range.stderr +++ b/tests/ui/type/pattern_types/reverse_range.stderr @@ -1,17 +1,9 @@ -error[E0601]: `main` function not found in crate `reverse_range` - --> $DIR/reverse_range.rs:14:78 +error[E0080]: evaluation of constant value failed + --> $DIR/reverse_range.rs:7:36 | LL | const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) }; - | ^ consider adding a `main` function to `$DIR/reverse_range.rs` + | ^ evaluation panicked: exclusive range end at minimum value of type - -assertion failed: end <= max_value -error: the compiler unexpectedly panicked. this is a bug. - -query stack during panic: -#0 [eval_to_allocation_raw] const-evaluating + checking `NONE` -#1 [eval_to_const_value_raw] simplifying constant for the type system `NONE` -... and 1 other queries... use `env RUST_BACKTRACE=1` to see the full query stack error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/type/pattern_types/validity.rs b/tests/ui/type/pattern_types/validity.rs index 77a4e72f6755..5a6a688e1b30 100644 --- a/tests/ui/type/pattern_types/validity.rs +++ b/tests/ui/type/pattern_types/validity.rs @@ -1,6 +1,6 @@ //! Check that pattern types have their validity checked -#![feature(pattern_types)] +#![feature(pattern_types, const_trait_impl, pattern_type_range_trait)] #![feature(pattern_type_macro)] use std::pat::pattern_type; From a2c1211b6de0c1a93c3ff1f97c49acc237f620a6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 5 Feb 2025 16:21:54 +0000 Subject: [PATCH 719/991] Hide the end of ranges in pretty printing if it's also the maximum of the type --- compiler/rustc_middle/src/ty/pattern.rs | 24 +++++++++++++++- tests/codegen/pattern_type_symbols.rs | 4 +-- .../pattern_types.main.PreCodegen.after.mir | 4 +-- tests/mir-opt/pattern_types.rs | 4 +-- tests/ui/lint/clashing-extern-fn.stderr | 2 +- tests/ui/type/pattern_types/nested.stderr | 28 +++++++++---------- .../type/pattern_types/range_patterns.stderr | 4 +-- .../range_patterns_unusable.stderr | 2 +- .../range_patterns_unusable_math.rs | 2 +- .../range_patterns_unusable_math.stderr | 4 +-- 10 files changed, 50 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index 89dadb36ad64..4cad1ab20991 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -27,7 +27,29 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { PatternKind::Range { start, end } => { - write!(f, "{start}..={end}") + write!(f, "{start}")?; + + if let Some(c) = end.try_to_value() { + let end = c.valtree.unwrap_leaf(); + let size = end.size(); + let max = match c.ty.kind() { + ty::Int(_) => { + Some(ty::ScalarInt::truncate_from_int(size.signed_int_max(), size)) + } + ty::Uint(_) => { + Some(ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size)) + } + ty::Char => Some(ty::ScalarInt::truncate_from_uint(char::MAX, size)), + _ => None, + }; + if let Some((max, _)) = max + && end == max + { + return write!(f, ".."); + } + } + + write!(f, "..={end}") } } } diff --git a/tests/codegen/pattern_type_symbols.rs b/tests/codegen/pattern_type_symbols.rs index b504a3508f94..e86a9ef27de1 100644 --- a/tests/codegen/pattern_type_symbols.rs +++ b/tests/codegen/pattern_type_symbols.rs @@ -16,7 +16,7 @@ pub fn bar() { // CHECK: call pattern_type_symbols::foo:: // CHECK: call void @_RINvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_20pattern_type_symbols3foomEB2_ foo::(); - // CHECK: call pattern_type_symbols::foo::<(u32, [(); 0], [(); 999999999], [(); true])> - // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_Aub1_EEB2_ + // CHECK: call pattern_type_symbols::foo::<(u32, [(); 0], [(); 999999999])> + // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_EEB2_ foo::(); } diff --git a/tests/mir-opt/pattern_types.main.PreCodegen.after.mir b/tests/mir-opt/pattern_types.main.PreCodegen.after.mir index 8214ff61d75e..cc01f51973c8 100644 --- a/tests/mir-opt/pattern_types.main.PreCodegen.after.mir +++ b/tests/mir-opt/pattern_types.main.PreCodegen.after.mir @@ -3,9 +3,9 @@ fn main() -> () { let mut _0: (); scope 1 { - debug x => const 2_u32 is 1..=u32::MAX; + debug x => const 2_u32 is 1..; scope 2 { - debug y => const {transmute(0x00000000): (u32) is 1..=u32::MAX}; + debug y => const {transmute(0x00000000): (u32) is 1..}; } } diff --git a/tests/mir-opt/pattern_types.rs b/tests/mir-opt/pattern_types.rs index 6d5391993452..d5847b95f732 100644 --- a/tests/mir-opt/pattern_types.rs +++ b/tests/mir-opt/pattern_types.rs @@ -5,8 +5,8 @@ use std::pat::pattern_type; // EMIT_MIR pattern_types.main.PreCodegen.after.mir fn main() { - // CHECK: debug x => const 2_u32 is 1..=u32::MAX + // CHECK: debug x => const 2_u32 is 1.. let x: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(2) }; - // CHECK: debug y => const {transmute(0x00000000): (u32) is 1..=u32::MAX} + // CHECK: debug y => const {transmute(0x00000000): (u32) is 1..} let y: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) }; } diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr index 4e9f6ea3f78c..0c27547a6ed8 100644 --- a/tests/ui/lint/clashing-extern-fn.stderr +++ b/tests/ui/lint/clashing-extern-fn.stderr @@ -17,7 +17,7 @@ LL | fn hidden_niche_unsafe_cell() -> Option`, which is not FFI-safe +warning: `extern` block uses type `Option<(usize) is 0..>`, which is not FFI-safe --> $DIR/clashing-extern-fn.rs:502:54 | LL | fn pt_non_zero_usize_opt_full_range() -> Option; diff --git a/tests/ui/type/pattern_types/nested.stderr b/tests/ui/type/pattern_types/nested.stderr index 04aacabc136e..f79d12bc3f37 100644 --- a/tests/ui/type/pattern_types/nested.stderr +++ b/tests/ui/type/pattern_types/nested.stderr @@ -2,18 +2,18 @@ error[E0308]: mismatched types --> $DIR/nested.rs:10:63 | LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); - | ^ expected `(u32) is 1..=u32::MAX`, found integer + | ^ expected `(u32) is 1..`, found integer | - = note: expected pattern type `(u32) is 1..=u32::MAX` + = note: expected pattern type `(u32) is 1..` found type `{integer}` -error[E0277]: `(u32) is 1..=u32::MAX` is not a valid base type for range patterns +error[E0277]: `(u32) is 1..` is not a valid base type for range patterns --> $DIR/nested.rs:10:34 | LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `(u32) is 1..=u32::MAX` + = help: the trait `core::pat::RangePattern` is not implemented for `(u32) is 1..` = help: the following other types implement trait `core::pat::RangePattern`: char i128 @@ -25,13 +25,13 @@ LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!( u128 and 5 others -error[E0277]: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns +error[E0277]: `(i32) is 1..` is not a valid base type for range patterns --> $DIR/nested.rs:15:35 | LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..=i32::MAX` + = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..` = help: the following other types implement trait `core::pat::RangePattern`: char i128 @@ -47,18 +47,18 @@ error[E0308]: mismatched types --> $DIR/nested.rs:15:67 | LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); - | ^^ expected `(i32) is 1..=i32::MAX`, found integer + | ^^ expected `(i32) is 1..`, found integer | - = note: expected pattern type `(i32) is 1..=i32::MAX` + = note: expected pattern type `(i32) is 1..` found type `{integer}` -error[E0277]: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns +error[E0277]: `(i32) is 1..` is not a valid base type for range patterns --> $DIR/nested.rs:19:35 | LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..=i32::MAX` + = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..` = help: the following other types implement trait `core::pat::RangePattern`: char i128 @@ -76,10 +76,10 @@ error[E0308]: mismatched types LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); | ^ | | - | expected `(i32) is 1..=i32::MAX`, found integer + | expected `(i32) is 1..`, found integer | arguments to this function are incorrect | - = note: expected pattern type `(i32) is 1..=i32::MAX` + = note: expected pattern type `(i32) is 1..` found type `{integer}` help: the return type of this call is `{integer}` due to the type of the argument passed --> $DIR/nested.rs:19:66 @@ -89,13 +89,13 @@ LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo! note: method defined here --> $SRC_DIR/core/src/pat.rs:LL:COL -error[E0277]: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns +error[E0277]: `(i32) is 1..` is not a valid base type for range patterns --> $DIR/nested.rs:19:66 | LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); | ^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..=i32::MAX` + = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..` = help: the following other types implement trait `core::pat::RangePattern`: char i128 diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 43ae7e870f00..512181c22d53 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -44,7 +44,7 @@ error: layout_of(NonZero) = Layout { LL | type X = std::num::NonZeroU32; | ^^^^^^ -error: layout_of((u32) is 1..=u32::MAX) = Layout { +error: layout_of((u32) is 1..) = Layout { size: Size(4 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), @@ -83,7 +83,7 @@ error: layout_of((u32) is 1..=u32::MAX) = Layout { LL | type Y = pattern_type!(u32 is 1..); | ^^^^^^ -error: layout_of(Option<(u32) is 1..=u32::MAX>) = Layout { +error: layout_of(Option<(u32) is 1..>) = Layout { size: Size(4 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), diff --git a/tests/ui/type/pattern_types/range_patterns_unusable.stderr b/tests/ui/type/pattern_types/range_patterns_unusable.stderr index a9558852eb29..7daa41d70817 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable.stderr +++ b/tests/ui/type/pattern_types/range_patterns_unusable.stderr @@ -4,7 +4,7 @@ error[E0512]: cannot transmute between types of different sizes, or dependently- LL | let _: Option = unsafe { std::mem::transmute(z) }; | ^^^^^^^^^^^^^^^^^^^ | - = note: source type: `Option<(u32) is 1..=u32::MAX>` (32 bits) + = note: source type: `Option<(u32) is 1..>` (32 bits) = note: target type: `Option` (64 bits) error: aborting due to 1 previous error diff --git a/tests/ui/type/pattern_types/range_patterns_unusable_math.rs b/tests/ui/type/pattern_types/range_patterns_unusable_math.rs index 54ad6096c577..6125063699be 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable_math.rs +++ b/tests/ui/type/pattern_types/range_patterns_unusable_math.rs @@ -11,5 +11,5 @@ type Z = Option; fn main() { let x: Y = unsafe { std::mem::transmute(42_u32) }; - let x = x + 1_u32; //~ ERROR cannot add `u32` to `(u32) is 1..=u32::MAX` + let x = x + 1_u32; //~ ERROR cannot add `u32` to `(u32) is 1..` } diff --git a/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr b/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr index 68ddd63cd530..a64f1db31766 100644 --- a/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr +++ b/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr @@ -1,10 +1,10 @@ -error[E0369]: cannot add `u32` to `(u32) is 1..=u32::MAX` +error[E0369]: cannot add `u32` to `(u32) is 1..` --> $DIR/range_patterns_unusable_math.rs:14:15 | LL | let x = x + 1_u32; | - ^ ----- u32 | | - | (u32) is 1..=u32::MAX + | (u32) is 1.. error: aborting due to 1 previous error From 7d6bbe2df788d9c23aef1384bc1c8b240253ae7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 6 Mar 2025 09:21:37 +0000 Subject: [PATCH 720/991] expand comments of `TyCtxt` impl of `DynSync`/`DynSend` so that it doesn't get removed again --- compiler/rustc_middle/src/ty/context.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 2d2bbd22b984..4013f7b2c854 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1327,7 +1327,9 @@ pub struct TyCtxt<'tcx> { gcx: &'tcx GlobalCtxt<'tcx>, } -// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. +// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. Its +// field are asserted to implement these traits below, so this is trivially safe, and it greatly +// speeds-up compilation of this crate and its dependents. unsafe impl DynSend for TyCtxt<'_> {} unsafe impl DynSync for TyCtxt<'_> {} fn _assert_tcx_fields() { From 71d688bb721037b9623ccb645e4f0557fb427fb3 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 6 Mar 2025 12:52:34 +0100 Subject: [PATCH 721/991] `TypeVerifier` do not walk into required consts --- compiler/rustc_borrowck/src/type_check/mod.rs | 35 ++++++++++++------- tests/ui/error-codes/E0582.stderr | 2 +- .../trait-bounds/hrtb-just-for-static.stderr | 2 +- tests/ui/nll/issue-97997.rs | 1 - tests/ui/nll/issue-97997.stderr | 12 +------ .../implied_lifetime_wf_check3.stderr | 2 +- .../implied_lifetime_wf_check4_static.stderr | 2 +- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 8edd3912366e..746457d76e08 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -328,9 +328,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } + #[instrument(level = "debug", skip(self))] fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) { - debug!(?constant, ?location, "visit_const_operand"); - self.super_const_operand(constant, location); let ty = constant.const_.ty(); @@ -339,14 +338,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { self.typeck.constraints.liveness_constraints.add_location(live_region_vid, location); }); - // HACK(compiler-errors): Constants that are gathered into Body.required_consts - // have their locations erased... - let locations = if location != Location::START { - location.to_locations() - } else { - Locations::All(constant.span) - }; - + let locations = location.to_locations(); if let Some(annotation_index) = constant.user_ty { if let Err(terr) = self.typeck.relate_type_and_user_type( constant.const_.ty(), @@ -491,9 +483,28 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } + #[instrument(level = "debug", skip(self))] fn visit_body(&mut self, body: &Body<'tcx>) { - // The types of local_decls are checked above which is called in super_body. - self.super_body(body); + // We intentionally do not recursive into `body.required_consts` or + // `body.mentioned_items` here as the MIR at this phase should still + // refer to all items and we don't want to check them multiple times. + + for (local, local_decl) in body.local_decls.iter_enumerated() { + self.visit_local_decl(local, local_decl); + } + + for (block, block_data) in body.basic_blocks.iter_enumerated() { + let mut location = Location { block, statement_index: 0 }; + for stmt in &block_data.statements { + if !stmt.source_info.span.is_dummy() { + self.last_span = stmt.source_info.span; + } + self.visit_statement(stmt, location); + location.statement_index += 1; + } + + self.visit_terminator(block_data.terminator(), location); + } } } diff --git a/tests/ui/error-codes/E0582.stderr b/tests/ui/error-codes/E0582.stderr index 64b527cdcc2a..ac97a6ff00a8 100644 --- a/tests/ui/error-codes/E0582.stderr +++ b/tests/ui/error-codes/E0582.stderr @@ -14,7 +14,7 @@ error[E0308]: mismatched types --> $DIR/E0582.rs:22:5 | LL | bar(mk_unexpected_char_err) - | ^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | = note: expected enum `Option<&_>` found enum `Option<&'a _>` diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr index 31e11e128351..1c077a9b906c 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr @@ -2,7 +2,7 @@ error: implementation of `Foo` is not general enough --> $DIR/hrtb-just-for-static.rs:24:5 | LL | want_hrtb::() - | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough | = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`... = note: ...but it actually implements `Foo<&'static isize>` diff --git a/tests/ui/nll/issue-97997.rs b/tests/ui/nll/issue-97997.rs index c64e720b12f7..8e0fbe89ac23 100644 --- a/tests/ui/nll/issue-97997.rs +++ b/tests/ui/nll/issue-97997.rs @@ -12,5 +12,4 @@ fn main() { ::ASSOC; //~^ ERROR implementation of `Foo` is not general enough - //~| ERROR implementation of `Foo` is not general enough } diff --git a/tests/ui/nll/issue-97997.stderr b/tests/ui/nll/issue-97997.stderr index 89eaf77adf06..ff08daaeaac0 100644 --- a/tests/ui/nll/issue-97997.stderr +++ b/tests/ui/nll/issue-97997.stderr @@ -7,15 +7,5 @@ LL | ::ASSOC; = note: `Foo` would have to be implemented for the type `for<'a> fn(&'a u8)` = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0` -error: implementation of `Foo` is not general enough - --> $DIR/issue-97997.rs:13:5 - | -LL | ::ASSOC; - | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `Foo` would have to be implemented for the type `for<'a> fn(&'a u8)` - = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr index b7c9c131c7d1..c9af4bda572a 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr @@ -28,7 +28,7 @@ error[E0310]: the parameter type `A` may not live long enough --> $DIR/implied_lifetime_wf_check3.rs:52:5 | LL | test_type_param::assert_static::() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | the parameter type `A` must be valid for the static lifetime... | ...so that the type `A` will meet its required lifetime bounds diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr index f23b978d0b64..060d68eb632b 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr @@ -21,7 +21,7 @@ error[E0310]: the parameter type `A` may not live long enough --> $DIR/implied_lifetime_wf_check4_static.rs:17:5 | LL | assert_static::() - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ | | | the parameter type `A` must be valid for the static lifetime... | ...so that the type `A` will meet its required lifetime bounds From d4c0c945773973ec6d10cb87d9a2396768f6e075 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Thu, 6 Mar 2025 07:32:52 -0500 Subject: [PATCH 722/991] Stabilize `const_copy_from_slice` feature Stabilizes `copy_from_slice` method on `[T]` --- library/core/src/slice/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f991cc4ae2db..4055038b958d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3732,8 +3732,7 @@ impl [T] { #[doc(alias = "memcpy")] #[inline] #[stable(feature = "copy_from_slice", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_copy_from_slice", issue = "131415")] - #[rustc_const_stable_indirect] + #[rustc_const_stable(feature = "const_copy_from_slice", since = "CURRENT_RUSTC_VERSION")] #[track_caller] pub const fn copy_from_slice(&mut self, src: &[T]) where From 66a1164eeb6095c80cdb440a6194e8b86e7c8630 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Thu, 6 Mar 2025 13:36:20 +0100 Subject: [PATCH 723/991] Change `%e` to `?e` to include detailed error message --- .../rust-analyzer/crates/project-model/src/cargo_workspace.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 68a9fba09c72..014028a0b63e 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -300,10 +300,9 @@ impl CargoWorkspace { if let Ok((_, Some(ref e))) = res { tracing::warn!( %cargo_toml, - %e, + ?e, "`cargo metadata` failed, but retry with `--no-deps` succeeded" ); - tracing::debug!("{e:?}"); } res } From 1fac14de23b72b3d1d09a07dda52cc276d97f0ef Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 6 Mar 2025 14:46:10 +0100 Subject: [PATCH 724/991] fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rémy Rakic --- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 746457d76e08..50e66e58d85d 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -485,7 +485,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_body(&mut self, body: &Body<'tcx>) { - // We intentionally do not recursive into `body.required_consts` or + // We intentionally do not recurse into `body.required_consts` or // `body.mentioned_items` here as the MIR at this phase should still // refer to all items and we don't want to check them multiple times. From c5b7a9c4b5b06cab36b0e3914854d6ee4a600d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 4 Mar 2025 20:30:42 +0100 Subject: [PATCH 725/991] Factor out edge breaking code --- .../src/add_call_guards.rs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index 55694cacd92e..c64bb30fa215 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -40,6 +40,16 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { let mut new_blocks = Vec::new(); let cur_len = body.basic_blocks.len(); + let mut new_block = |source_info: SourceInfo, is_cleanup: bool, target: BasicBlock| { + let block = BasicBlockData { + statements: vec![], + is_cleanup, + terminator: Some(Terminator { source_info, kind: TerminatorKind::Goto { target } }), + }; + let idx = cur_len + new_blocks.len(); + new_blocks.push(block); + BasicBlock::new(idx) + }; for block in body.basic_blocks_mut() { match block.terminator { @@ -53,19 +63,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { ) || self == &AllCallEdges) => { // It's a critical edge, break it - let call_guard = BasicBlockData { - statements: vec![], - is_cleanup: block.is_cleanup, - terminator: Some(Terminator { - source_info, - kind: TerminatorKind::Goto { target: *destination }, - }), - }; - - // Get the index it will be when inserted into the MIR - let idx = cur_len + new_blocks.len(); - new_blocks.push(call_guard); - *destination = BasicBlock::new(idx); + *destination = new_block(source_info, block.is_cleanup, *destination); } _ => {} } From 662d73514af6ed897ac048c12a546afbaf045381 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 6 Mar 2025 06:57:00 -0800 Subject: [PATCH 726/991] Git ignore citool's target directory Whenever running citool, it leaves behind a target directory. Ignore this like we do for other tools. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2184e04f16b2..b8cb31e81908 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ no_llvm_build /target /library/target /src/bootstrap/target +/src/ci/citool/target /src/tools/x/target # Created by `x vendor` /vendor From 6b14125102ccdbcd62099a096e686dbd2f625ff1 Mon Sep 17 00:00:00 2001 From: Redddy <78539407+reddevilmidzy@users.noreply.github.com> Date: Fri, 7 Mar 2025 00:55:24 +0900 Subject: [PATCH 727/991] Fix broken link to Miri intrinsics in documentation Replaced the outdated link to https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics with the correct link https://github.com/rust-lang/miri/tree/master/src/intrinsics in the library/core/src/intrinsics/mod.rs file. --- library/core/src/intrinsics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 38a60338e74e..c5603298a70e 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -10,7 +10,7 @@ //! //! In order to make an intrinsic usable at compile-time, it needs to be declared in the "new" //! style, i.e. as a `#[rustc_intrinsic]` function, not inside an `extern` block. Then copy the -//! implementation from to +//! implementation from to //! //! and make the intrinsic declaration a `const fn`. //! From ccfbfe22922946249088bc9d574f7dc22c8f6c90 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Thu, 6 Mar 2025 16:06:41 +0000 Subject: [PATCH 728/991] `x clippy src/librustdoc --fix` --- src/librustdoc/clean/mod.rs | 5 ++--- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/clean/utils.rs | 4 ++-- src/librustdoc/display.rs | 2 +- src/librustdoc/doctest/extracted.rs | 4 ++-- src/librustdoc/html/format.rs | 10 ++++------ src/librustdoc/html/highlight.rs | 6 +++--- src/librustdoc/html/markdown.rs | 2 +- src/librustdoc/html/render/print_item.rs | 6 ++---- src/librustdoc/html/render/search_index/encode.rs | 4 ++-- src/librustdoc/passes/collect_intra_doc_links.rs | 2 +- src/librustdoc/passes/propagate_stability.rs | 6 +++--- 12 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bb12e4a706e7..b45c43e6979f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2539,7 +2539,7 @@ fn clean_generic_args<'tcx>( ) -> GenericArgs { // FIXME(return_type_notation): Fix RTN parens rendering if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() { - let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect::>().into(); + let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect::>(); let output = match output.kind { hir::TyKind::Tup(&[]) => None, _ => Some(Box::new(clean_ty(output, cx))), @@ -2560,8 +2560,7 @@ fn clean_generic_args<'tcx>( } hir::GenericArg::Infer(_inf) => GenericArg::Infer, }) - .collect::>() - .into(); + .collect::>(); let constraints = generic_args .constraints .iter() diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5906a720e0fd..8d03fce423bc 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2419,7 +2419,7 @@ impl ConstantKind { ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { rendered_const(tcx, tcx.hir_body(body), tcx.hir_body_owner_def_id(body)) } - ConstantKind::Infer { .. } => "_".to_string(), + ConstantKind::Infer => "_".to_string(), } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index a284de5229a2..cf649bdb11f0 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -223,7 +223,7 @@ fn clean_middle_generic_args_with_constraints<'tcx>( let args = clean_middle_generic_args(cx, args.map_bound(|args| &args[..]), has_self, did); - GenericArgs::AngleBracketed { args: args.into(), constraints } + GenericArgs::AngleBracketed { args: args, constraints } } pub(super) fn clean_middle_path<'tcx>( @@ -524,7 +524,7 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId { | AssocConst | Variant | Fn - | TyAlias { .. } + | TyAlias | Enum | Trait | Struct diff --git a/src/librustdoc/display.rs b/src/librustdoc/display.rs index ee8dde013ee9..aa0fad265208 100644 --- a/src/librustdoc/display.rs +++ b/src/librustdoc/display.rs @@ -22,7 +22,7 @@ where let mut iter = self.into_iter(); let Some(first) = iter.next() else { return Ok(()) }; first.fmt(f)?; - while let Some(item) = iter.next() { + for item in iter { f.write_str(sep)?; item.fmt(f)?; } diff --git a/src/librustdoc/doctest/extracted.rs b/src/librustdoc/doctest/extracted.rs index 03c8814a4c96..ce362eabfc4c 100644 --- a/src/librustdoc/doctest/extracted.rs +++ b/src/librustdoc/doctest/extracted.rs @@ -33,7 +33,7 @@ impl ExtractedDocTests { opts: &super::GlobalTestOptions, options: &RustdocOptions, ) { - let edition = scraped_test.edition(&options); + let edition = scraped_test.edition(options); let ScrapedDocTest { filename, line, langstr, text, name } = scraped_test; @@ -48,7 +48,7 @@ impl ExtractedDocTests { let (full_test_code, size) = doctest.generate_unique_doctest( &text, langstr.test_harness, - &opts, + opts, Some(&opts.crate_name), ); self.doctests.push(ExtractedDocTest { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index ea740508c583..6731837d7184 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -625,8 +625,7 @@ pub(crate) fn href_relative_parts<'fqp>( let dissimilar_part_count = relative_to_fqp.len() - i; let fqp_module = &fqp[i..fqp.len()]; return Box::new( - iter::repeat(sym::dotdot) - .take(dissimilar_part_count) + std::iter::repeat_n(sym::dotdot, dissimilar_part_count) .chain(fqp_module.iter().copied()), ); } @@ -639,7 +638,7 @@ pub(crate) fn href_relative_parts<'fqp>( Ordering::Greater => { // e.g. linking to std::sync from std::sync::atomic let dissimilar_part_count = relative_to_fqp.len() - fqp.len(); - Box::new(iter::repeat(sym::dotdot).take(dissimilar_part_count)) + Box::new(std::iter::repeat_n(sym::dotdot, dissimilar_part_count)) } Ordering::Equal => { // linking to the same module @@ -770,10 +769,9 @@ fn primitive_link_fragment( ExternalLocation::Local => { let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()); Some(if cx.current.first() == Some(&cname_sym) { - iter::repeat(sym::dotdot).take(cx.current.len() - 1).collect() + std::iter::repeat_n(sym::dotdot, cx.current.len() - 1).collect() } else { - iter::repeat(sym::dotdot) - .take(cx.current.len()) + std::iter::repeat_n(sym::dotdot, cx.current.len()) .chain(iter::once(cname_sym)) .collect() }) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index ed4b97d36252..8c17b84a42f4 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -100,7 +100,7 @@ fn write_header( } if let Some(extra) = extra_content { - out.push_str(&extra); + out.push_str(extra); } if class.is_empty() { write_str( @@ -233,7 +233,7 @@ impl TokenHandler<'_, '_, F> { #[inline] fn write_line_number(&mut self, line: u32, extra: &'static str) { - (self.write_line_number)(&mut self.out, line, extra); + (self.write_line_number)(self.out, line, extra); } } @@ -610,7 +610,7 @@ impl Decorations { let (mut starts, mut ends): (Vec<_>, Vec<_>) = info .0 .iter() - .flat_map(|(&kind, ranges)| ranges.into_iter().map(move |&(lo, hi)| ((lo, kind), hi))) + .flat_map(|(&kind, ranges)| ranges.iter().map(move |&(lo, hi)| ((lo, kind), hi))) .unzip(); // Sort the sequences in document order. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index d9e49577d392..8c49bf49a4e5 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1792,7 +1792,7 @@ pub(crate) fn markdown_links<'md, R>( } } } else if !c.is_ascii_whitespace() { - while let Some((j, c)) = iter.next() { + for (j, c) in iter.by_ref() { if c.is_ascii_whitespace() { return MarkdownLinkRange::Destination(i + span.start..j + span.start); } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index c599a84ee44e..48bbba607b2d 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1192,8 +1192,7 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: // to already be in the HTML, and will be ignored. // // [JSONP]: https://en.wikipedia.org/wiki/JSONP - let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..") - .take(cx.current.len()) + let mut js_src_path: UrlPartsBuilder = std::iter::repeat_n("..", cx.current.len()) .chain(std::iter::once("trait.impl")) .collect(); if let Some(did) = it.item_id.as_def_id() @@ -1446,8 +1445,7 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> && let get_local = { || cache.paths.get(&self_did).map(|(p, _)| p) } && let Some(self_fqp) = cache.exact_paths.get(&self_did).or_else(get_local) { - let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..") - .take(cx.current.len()) + let mut js_src_path: UrlPartsBuilder = std::iter::repeat_n("..", cx.current.len()) .chain(std::iter::once("type.impl")) .collect(); js_src_path.extend(target_fqp[..target_fqp.len() - 1].iter().copied()); diff --git a/src/librustdoc/html/render/search_index/encode.rs b/src/librustdoc/html/render/search_index/encode.rs index 8816ea650593..de2f54558ff8 100644 --- a/src/librustdoc/html/render/search_index/encode.rs +++ b/src/librustdoc/html/render/search_index/encode.rs @@ -182,9 +182,9 @@ pub(crate) fn write_bitmap_to_bytes( out.write_all(&[b])?; } if size < NO_OFFSET_THRESHOLD { - 4 + 4 * size + ((size + 7) / 8) + 4 + 4 * size + size.div_ceil(8) } else { - 4 + 8 * size + ((size + 7) / 8) + 4 + 8 * size + size.div_ceil(8) } } else { out.write_all(&u32::to_le_bytes(SERIAL_COOKIE_NO_RUNCONTAINER))?; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 440d6331457b..de4ae6f59158 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -2060,7 +2060,7 @@ fn resolution_failure( return; } Trait - | TyAlias { .. } + | TyAlias | ForeignTy | OpaqueTy | TraitAlias diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index 8cf39afd55c5..fdab2b087799 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -39,15 +39,15 @@ impl DocFolder for StabilityPropagator<'_, '_> { let item_stability = self.cx.tcx.lookup_stability(def_id); let inline_stability = item.inline_stmt_id.and_then(|did| self.cx.tcx.lookup_stability(did)); - let is_glob_export = item.inline_stmt_id.and_then(|id| { + let is_glob_export = item.inline_stmt_id.map(|id| { let hir_id = self.cx.tcx.local_def_id_to_hir_id(id); - Some(matches!( + matches!( self.cx.tcx.hir_node(hir_id), rustc_hir::Node::Item(rustc_hir::Item { kind: rustc_hir::ItemKind::Use(_, rustc_hir::UseKind::Glob), .. }) - )) + ) }); let own_stability = if let Some(item_stab) = item_stability && let StabilityLevel::Stable { since: _, allowed_through_unstable_modules } = From 329b8a312dc5fbe8a310a30b8ce452c7609e202c Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sat, 1 Mar 2025 21:50:43 +0000 Subject: [PATCH 729/991] Implement `Ord` by-hand instead of `PartialOrd` for `Link` --- src/librustdoc/html/render/sidebar.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 64dbaf9083e7..3130815af0bd 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -79,7 +79,7 @@ impl<'a> LinkBlock<'a> { } /// A link to an item. Content should not be escaped. -#[derive(Ord, PartialEq, Eq, Hash, Clone)] +#[derive(PartialEq, Eq, Hash, Clone)] pub(crate) struct Link<'a> { /// The content for the anchor tag and title attr name: Cow<'a, str>, @@ -91,13 +91,13 @@ pub(crate) struct Link<'a> { children: Vec>, } -impl PartialOrd for Link<'_> { - fn partial_cmp(&self, other: &Link<'_>) -> Option { +impl Ord for Link<'_> { + fn cmp(&self, other: &Self) -> Ordering { match compare_names(&self.name, &other.name) { - Ordering::Equal => (), - result => return Some(result), + Ordering::Equal => {} + result => return result, } - (&self.name_html, &self.href, &self.children).partial_cmp(&( + (&self.name_html, &self.href, &self.children).cmp(&( &other.name_html, &other.href, &other.children, @@ -105,6 +105,12 @@ impl PartialOrd for Link<'_> { } } +impl PartialOrd for Link<'_> { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + impl<'a> Link<'a> { pub fn new(href: impl Into>, name: impl Into>) -> Self { Self { href: href.into(), name: name.into(), children: vec![], name_html: None } From 5d259224bd69425b44b4c83adc310cbf72b15855 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sat, 1 Mar 2025 19:12:21 +0000 Subject: [PATCH 730/991] Manual, post-`clippy --fix` cleanups --- src/librustdoc/clean/mod.rs | 4 ++-- src/librustdoc/clean/utils.rs | 4 ++-- src/librustdoc/html/format.rs | 10 +++++----- src/librustdoc/html/highlight.rs | 2 +- src/librustdoc/html/render/print_item.rs | 16 +++++++--------- src/librustdoc/html/render/search_index.rs | 5 +---- 6 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b45c43e6979f..67bc5cefd58a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2539,7 +2539,7 @@ fn clean_generic_args<'tcx>( ) -> GenericArgs { // FIXME(return_type_notation): Fix RTN parens rendering if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() { - let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect::>(); + let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect(); let output = match output.kind { hir::TyKind::Tup(&[]) => None, _ => Some(Box::new(clean_ty(output, cx))), @@ -2560,7 +2560,7 @@ fn clean_generic_args<'tcx>( } hir::GenericArg::Infer(_inf) => GenericArg::Infer, }) - .collect::>(); + .collect(); let constraints = generic_args .constraints .iter() diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index cf649bdb11f0..f81db58950cb 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -223,7 +223,7 @@ fn clean_middle_generic_args_with_constraints<'tcx>( let args = clean_middle_generic_args(cx, args.map_bound(|args| &args[..]), has_self, did); - GenericArgs::AngleBracketed { args: args, constraints } + GenericArgs::AngleBracketed { args, constraints } } pub(super) fn clean_middle_path<'tcx>( @@ -394,7 +394,7 @@ pub(crate) fn print_evaluated_const( fn format_integer_with_underscore_sep(num: &str) -> String { let num_chars: Vec<_> = num.chars().collect(); let mut num_start_index = if num_chars.first() == Some(&'-') { 1 } else { 0 }; - let chunk_size = match num[num_start_index..].as_bytes() { + let chunk_size = match &num.as_bytes()[num_start_index..] { [b'0', b'b' | b'x', ..] => { num_start_index += 2; 4 diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6731837d7184..8b8439a25352 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -623,9 +623,9 @@ pub(crate) fn href_relative_parts<'fqp>( // e.g. linking to std::iter from std::vec (`dissimilar_part_count` will be 1) if f != r { let dissimilar_part_count = relative_to_fqp.len() - i; - let fqp_module = &fqp[i..fqp.len()]; + let fqp_module = &fqp[i..]; return Box::new( - std::iter::repeat_n(sym::dotdot, dissimilar_part_count) + iter::repeat_n(sym::dotdot, dissimilar_part_count) .chain(fqp_module.iter().copied()), ); } @@ -638,7 +638,7 @@ pub(crate) fn href_relative_parts<'fqp>( Ordering::Greater => { // e.g. linking to std::sync from std::sync::atomic let dissimilar_part_count = relative_to_fqp.len() - fqp.len(); - Box::new(std::iter::repeat_n(sym::dotdot, dissimilar_part_count)) + Box::new(iter::repeat_n(sym::dotdot, dissimilar_part_count)) } Ordering::Equal => { // linking to the same module @@ -769,9 +769,9 @@ fn primitive_link_fragment( ExternalLocation::Local => { let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()); Some(if cx.current.first() == Some(&cname_sym) { - std::iter::repeat_n(sym::dotdot, cx.current.len() - 1).collect() + iter::repeat_n(sym::dotdot, cx.current.len() - 1).collect() } else { - std::iter::repeat_n(sym::dotdot, cx.current.len()) + iter::repeat_n(sym::dotdot, cx.current.len()) .chain(iter::once(cname_sym)) .collect() }) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 8c17b84a42f4..760a6d0c1a09 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -131,7 +131,7 @@ fn write_header( /// * If the other `Class` is unclassified and only contains white characters (backline, /// whitespace, etc), it can be merged. /// * `Class::Ident` is considered the same as unclassified (because it doesn't have an associated -/// CSS class). +/// CSS class). fn can_merge(class1: Option, class2: Option, text: &str) -> bool { match (class1, class2) { (Some(c1), Some(c2)) => c1.is_equal_to(c2), diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 48bbba607b2d..3c5c2ce19767 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; -use std::fmt; -use std::fmt::{Display, Write as _}; +use std::fmt::{self, Display, Write as _}; +use std::iter; use rinja::Template; use rustc_abi::VariantIdx; @@ -1192,9 +1192,8 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: // to already be in the HTML, and will be ignored. // // [JSONP]: https://en.wikipedia.org/wiki/JSONP - let mut js_src_path: UrlPartsBuilder = std::iter::repeat_n("..", cx.current.len()) - .chain(std::iter::once("trait.impl")) - .collect(); + let mut js_src_path: UrlPartsBuilder = + iter::repeat_n("..", cx.current.len()).chain(iter::once("trait.impl")).collect(); if let Some(did) = it.item_id.as_def_id() && let get_extern = { || cx.shared.cache.external_paths.get(&did).map(|s| &s.0) } && let Some(fqp) = cx.shared.cache.exact_paths.get(&did).or_else(get_extern) @@ -1445,9 +1444,8 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> && let get_local = { || cache.paths.get(&self_did).map(|(p, _)| p) } && let Some(self_fqp) = cache.exact_paths.get(&self_did).or_else(get_local) { - let mut js_src_path: UrlPartsBuilder = std::iter::repeat_n("..", cx.current.len()) - .chain(std::iter::once("type.impl")) - .collect(); + let mut js_src_path: UrlPartsBuilder = + iter::repeat_n("..", cx.current.len()).chain(iter::once("type.impl")).collect(); js_src_path.extend(target_fqp[..target_fqp.len() - 1].iter().copied()); js_src_path.push_fmt(format_args!("{target_type}.{}.js", target_fqp.last().unwrap())); let self_path = fmt::from_fn(|f| self_fqp.iter().joined("::", f)); @@ -1491,7 +1489,7 @@ fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt: fn fields_iter( &self, - ) -> std::iter::Peekable> { + ) -> iter::Peekable> { self.s .fields .iter() diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 95f617c98390..b39701fae1d6 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -842,10 +842,7 @@ pub(crate) fn get_function_type_for_search( } clean::ConstantItem(ref c) => make_nullary_fn(&c.type_), clean::StaticItem(ref s) => make_nullary_fn(&s.type_), - clean::StructFieldItem(ref t) => { - let Some(parent) = parent else { - return None; - }; + clean::StructFieldItem(ref t) if let Some(parent) = parent => { let mut rgen: FxIndexMap)> = Default::default(); let output = get_index_type(t, vec![], &mut rgen); From c867b8f11dbf0be397ba9b5c898fde95f8d5ea6c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 23 Feb 2025 22:54:36 +0000 Subject: [PATCH 731/991] Construct MIR error body for global_asm correctly --- compiler/rustc_mir_build/src/builder/mod.rs | 3 ++- tests/ui/asm/global-asm-with-error.rs | 11 +++++++++++ tests/ui/asm/global-asm-with-error.stderr | 9 +++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/ui/asm/global-asm-with-error.rs create mode 100644 tests/ui/asm/global-asm-with-error.stderr diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 949559549345..dc869b885a03 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -612,7 +612,8 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - | DefKind::AssocConst | DefKind::AnonConst | DefKind::InlineConst - | DefKind::Static { .. } => (vec![], tcx.type_of(def_id).instantiate_identity(), None), + | DefKind::Static { .. } + | DefKind::GlobalAsm => (vec![], tcx.type_of(def_id).instantiate_identity(), None), DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => { let sig = tcx.liberate_late_bound_regions( def_id.to_def_id(), diff --git a/tests/ui/asm/global-asm-with-error.rs b/tests/ui/asm/global-asm-with-error.rs new file mode 100644 index 000000000000..c2253e3cb874 --- /dev/null +++ b/tests/ui/asm/global-asm-with-error.rs @@ -0,0 +1,11 @@ +// Ensure that we don't ICE when constructing the fake MIR body for a global +// asm when the body has errors. See #137470. + +//@ needs-asm-support + +use std::arch::global_asm; + +global_asm!("/* {} */", sym a); +//~^ ERROR cannot find value `a` in this scope + +fn main() {} diff --git a/tests/ui/asm/global-asm-with-error.stderr b/tests/ui/asm/global-asm-with-error.stderr new file mode 100644 index 000000000000..6c07a9f020da --- /dev/null +++ b/tests/ui/asm/global-asm-with-error.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `a` in this scope + --> $DIR/global-asm-with-error.rs:6:29 + | +LL | global_asm!("/* {} */", sym a); + | ^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. From ef031c854da6432c86ac14c438ab96c7e349d85f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 23 Feb 2025 23:01:04 +0000 Subject: [PATCH 732/991] Exclude global_asm from mir_keys --- compiler/rustc_mir_transform/src/lib.rs | 4 +++ .../asm/global-asm-isnt-really-a-mir-body.rs | 26 +++++++++++++++++++ tests/ui/asm/global-asm-with-error.stderr | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/ui/asm/global-asm-isnt-really-a-mir-body.rs diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 5df12ac4d8bc..8aa14d15644b 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -316,6 +316,10 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { // All body-owners have MIR associated with them. let mut set: FxIndexSet<_> = tcx.hir_body_owners().collect(); + // Remove the fake bodies for `global_asm!`, since they're not useful + // to be emitted (`--emit=mir`) or encoded (in metadata). + set.retain(|&def_id| !matches!(tcx.def_kind(def_id), DefKind::GlobalAsm)); + // Coroutine-closures (e.g. async closures) have an additional by-move MIR // body that isn't in the HIR. for body_owner in tcx.hir_body_owners() { diff --git a/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs new file mode 100644 index 000000000000..b7636d116ec6 --- /dev/null +++ b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs @@ -0,0 +1,26 @@ +//@ revisions: emit_mir instrument cfi + +// Make sure we don't try to emit MIR for it. +//@[emit_mir] compile-flags: --emit=mir + +// Make sure we don't try to instrument it. +//@[instrument] compile-flags: -Cinstrument-coverage -Zno-profiler-runtime +//@[instrument] only-linux + +// Make sure we don't try to CFI encode it. +//@[cfi] compile-flags: -Zsanitizer=cfi -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Clink-dead-code=true +//@[cfi] needs-sanitizer-cfi +//@[cfi] no-prefer-dynamic +// FIXME(#122848) Remove only-linux once OSX CFI binaries work +//@[cfi] only-linux + +//@ build-pass +//@ needs-asm-support + +use std::arch::global_asm; + +fn foo() {} + +global_asm!("/* {} */", sym foo); + +fn main() {} diff --git a/tests/ui/asm/global-asm-with-error.stderr b/tests/ui/asm/global-asm-with-error.stderr index 6c07a9f020da..3b76bfd19485 100644 --- a/tests/ui/asm/global-asm-with-error.stderr +++ b/tests/ui/asm/global-asm-with-error.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `a` in this scope - --> $DIR/global-asm-with-error.rs:6:29 + --> $DIR/global-asm-with-error.rs:8:29 | LL | global_asm!("/* {} */", sym a); | ^ not found in this scope From feae27945bbffacf553e92421a7efd2a159b7262 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 6 Mar 2025 10:09:19 -0800 Subject: [PATCH 733/991] [llvm/PassWrapper] use `size_t` when building arg strings --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 6e607baebb5c..bc3d4d6f83ad 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -484,7 +484,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( if (ArgsCstrBuff != nullptr) { #if LLVM_VERSION_GE(20, 0) - int buffer_offset = 0; + size_t buffer_offset = 0; assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0'); auto Arg0 = std::string(ArgsCstrBuff); buffer_offset = Arg0.size() + 1; @@ -502,7 +502,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.MCOptions.Argv0 = Arg0; Options.MCOptions.CommandlineArgs = CommandlineArgs; #else - int buffer_offset = 0; + size_t buffer_offset = 0; assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0'); const size_t arg0_len = std::strlen(ArgsCstrBuff); @@ -511,13 +511,13 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( arg0[arg0_len] = '\0'; buffer_offset += arg0_len + 1; - const int num_cmd_arg_strings = std::count( + const size_t num_cmd_arg_strings = std::count( &ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0'); std::string *cmd_arg_strings = new std::string[num_cmd_arg_strings]; - for (int i = 0; i < num_cmd_arg_strings; ++i) { + for (size_t i = 0; i < num_cmd_arg_strings; ++i) { assert(buffer_offset < ArgsCstrBuffLen); - const int len = std::strlen(ArgsCstrBuff + buffer_offset); + const size_t len = std::strlen(ArgsCstrBuff + buffer_offset); cmd_arg_strings[i] = std::string(&ArgsCstrBuff[buffer_offset], len); buffer_offset += len + 1; } From ac40ea7129447abbd004859957bf00a374e8a739 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 6 Mar 2025 17:32:32 +0000 Subject: [PATCH 734/991] Suggest typo fix for static lifetime --- .../rustc_resolve/src/late/diagnostics.rs | 48 ++++++++++++------- tests/ui/lifetimes/static-typos.rs | 7 +++ tests/ui/lifetimes/static-typos.stderr | 26 ++++++++++ 3 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 tests/ui/lifetimes/static-typos.rs create mode 100644 tests/ui/lifetimes/static-typos.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 42be92c0f8fe..30fb17fa6a16 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -24,7 +24,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_hir::{MissingLifetimeKind, PrimTy}; use rustc_middle::ty; use rustc_session::{Session, lint}; -use rustc_span::edit_distance::find_best_match_for_name; +use rustc_span::edit_distance::{edit_distance, find_best_match_for_name}; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; @@ -2874,23 +2874,35 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ) .with_span_label(lifetime_ref.ident.span, "undeclared lifetime") }; - self.suggest_introducing_lifetime( - &mut err, - Some(lifetime_ref.ident.name.as_str()), - |err, _, span, message, suggestion, span_suggs| { - err.multipart_suggestion_with_style( - message, - std::iter::once((span, suggestion)).chain(span_suggs.clone()).collect(), - Applicability::MaybeIncorrect, - if span_suggs.is_empty() { - SuggestionStyle::ShowCode - } else { - SuggestionStyle::ShowAlways - }, - ); - true - }, - ); + + // Check if this is a typo of `'static`. + if edit_distance(lifetime_ref.ident.name.as_str(), "'static", 2).is_some() { + err.span_suggestion_verbose( + lifetime_ref.ident.span, + "you may have misspelled the `'static` lifetime", + "'static", + Applicability::MachineApplicable, + ); + } else { + self.suggest_introducing_lifetime( + &mut err, + Some(lifetime_ref.ident.name.as_str()), + |err, _, span, message, suggestion, span_suggs| { + err.multipart_suggestion_with_style( + message, + std::iter::once((span, suggestion)).chain(span_suggs.clone()).collect(), + Applicability::MaybeIncorrect, + if span_suggs.is_empty() { + SuggestionStyle::ShowCode + } else { + SuggestionStyle::ShowAlways + }, + ); + true + }, + ); + } + err.emit(); } diff --git a/tests/ui/lifetimes/static-typos.rs b/tests/ui/lifetimes/static-typos.rs new file mode 100644 index 000000000000..941d1b376bce --- /dev/null +++ b/tests/ui/lifetimes/static-typos.rs @@ -0,0 +1,7 @@ +fn stati() {} +//~^ ERROR use of undeclared lifetime name `'stati` + +fn statoc() {} +//~^ ERROR use of undeclared lifetime name `'statoc` + +fn main() {} diff --git a/tests/ui/lifetimes/static-typos.stderr b/tests/ui/lifetimes/static-typos.stderr new file mode 100644 index 000000000000..a817fa89c7e5 --- /dev/null +++ b/tests/ui/lifetimes/static-typos.stderr @@ -0,0 +1,26 @@ +error[E0261]: use of undeclared lifetime name `'stati` + --> $DIR/static-typos.rs:1:13 + | +LL | fn stati() {} + | ^^^^^^ undeclared lifetime + | +help: you may have misspelled the `'static` lifetime + | +LL | fn stati() {} + | + + +error[E0261]: use of undeclared lifetime name `'statoc` + --> $DIR/static-typos.rs:4:14 + | +LL | fn statoc() {} + | ^^^^^^^ undeclared lifetime + | +help: you may have misspelled the `'static` lifetime + | +LL - fn statoc() {} +LL + fn statoc() {} + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. From 5143638e5150b51038009f95d64e541dc6ecac5f Mon Sep 17 00:00:00 2001 From: waffle Date: Thu, 6 Mar 2025 17:16:00 +0100 Subject: [PATCH 735/991] Mention me (WaffleLapkin) when changes to `rustc_codegen_ssa` occur --- triagebot.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index ff789e6e3626..3ae93e31814c 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -701,6 +701,9 @@ cc = ["@davidtwco", "@wesleywiser"] [mentions."compiler/rustc_codegen_cranelift"] cc = ["@bjorn3"] +[mentions."compiler/rustc_codegen_ssa"] +cc = ["@WaffleLapkin"] + [mentions."compiler/rustc_codegen_gcc"] cc = ["@antoyo", "@GuillaumeGomez"] From 860637abc36c5ab3cdc1cf6a5b4130a2d8fecd03 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 27 Feb 2025 11:21:01 +0200 Subject: [PATCH 736/991] Normalize projections in evaluated const display and layout calculation --- .../crates/hir-ty/src/display.rs | 2 ++ .../rust-analyzer/crates/hir-ty/src/layout.rs | 3 ++ .../crates/ide/src/hover/tests.rs | 34 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 6ee4780d206f..b3613b372bfd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -45,6 +45,7 @@ use crate::{ db::{HirDatabase, InternedClosure}, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, generics::generics, + infer::normalize, layout::Layout, lt_from_placeholder_idx, mapping::from_chalk, @@ -657,6 +658,7 @@ fn render_const_scalar( // infrastructure and have it here as a field on `f`. let trait_env = TraitEnvironment::empty(*f.db.crate_graph().crates_in_topological_order().last().unwrap()); + let ty = normalize(f.db, trait_env.clone(), ty.clone()); match ty.kind(Interner) { TyKind::Scalar(s) => match s { Scalar::Bool => write!(f, "{}", b[0] != 0), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index a4e49e0aa10a..6b5c712159a5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -435,6 +435,9 @@ pub fn layout_of_ty_query( TyKind::Error => return Err(LayoutError::HasErrorType), TyKind::AssociatedType(id, subst) => { // Try again with `TyKind::Alias` to normalize the associated type. + // Usually we should not try to normalize `TyKind::AssociatedType`, but layout calculation is used + // in monomorphized MIR where this is okay. If outside monomorphization, this will lead to cycle, + // which we will recover from with an error. let ty = TyKind::Alias(chalk_ir::AliasTy::Projection(ProjectionTy { associated_ty_id: *id, substitution: subst.clone(), diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 7c720d97cb6d..964b1d7eb7dc 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -10947,3 +10947,37 @@ pub struct ManuallyDrop$0 { "#]], ); } + +#[test] +fn projection_const() { + check( + r#" +pub trait PublicFlags { + type Internal; +} + +pub struct NoteDialects(::Internal); + +impl NoteDialects { + pub const CLAP$0: Self = Self(InternalBitFlags); +} + +pub struct InternalBitFlags; + +impl PublicFlags for NoteDialects { + type Internal = InternalBitFlags; +} + "#, + expect![[r#" + *CLAP* + + ```rust + ra_test_fixture::NoteDialects + ``` + + ```rust + pub const CLAP: Self = NoteDialects(InternalBitFlags) + ``` + "#]], + ); +} From fcb34b17e22268636a7b227ce78237b158737d39 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 27 Feb 2025 14:19:54 +0200 Subject: [PATCH 737/991] Pass the target crate in `HirFormatter` This is required to format evaluated consts, because we need trait env, and it needs the crate (currently it uses the last crate in topological order, which is wrong, the next commit will fix that). --- .../crates/hir-ty/src/consteval.rs | 17 ++- .../crates/hir-ty/src/consteval/tests.rs | 18 ++- .../crates/hir-ty/src/diagnostics/expr.rs | 15 +- .../crates/hir-ty/src/display.rs | 136 +++++++++++------- .../rust-analyzer/crates/hir-ty/src/lib.rs | 10 +- .../rust-analyzer/crates/hir-ty/src/mir.rs | 4 +- .../crates/hir-ty/src/mir/borrowck.rs | 6 +- .../crates/hir-ty/src/mir/eval.rs | 27 ++-- .../crates/hir-ty/src/mir/eval/shim.rs | 4 +- .../crates/hir-ty/src/mir/eval/tests.rs | 5 +- .../crates/hir-ty/src/mir/lower.rs | 55 ++++--- .../hir-ty/src/mir/lower/pattern_matching.rs | 7 +- .../crates/hir-ty/src/mir/pretty.rs | 63 +++++--- .../rust-analyzer/crates/hir-ty/src/tests.rs | 47 +++--- .../hir-ty/src/tests/closure_captures.rs | 8 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 71 ++++++--- .../rust-analyzer/crates/hir/src/semantics.rs | 8 ++ .../rust-analyzer/crates/hir/src/symbols.rs | 14 +- .../crates/hir/src/term_search/expr.rs | 50 +++++-- .../src/handlers/generate_function.rs | 11 +- .../src/handlers/generate_getter_or_setter.rs | 2 +- .../src/handlers/inline_const_as_literal.rs | 2 +- .../ide-assists/src/handlers/term_search.rs | 9 +- .../crates/ide-assists/src/utils.rs | 44 ++++-- .../crates/ide-completion/src/context.rs | 7 +- .../ide-completion/src/context/tests.rs | 2 +- .../crates/ide-completion/src/render.rs | 13 +- .../ide-completion/src/render/const_.rs | 2 +- .../ide-completion/src/render/function.rs | 32 ++--- .../ide-completion/src/render/literal.rs | 4 +- .../ide-completion/src/render/macro_.rs | 2 +- .../ide-completion/src/render/type_alias.rs | 2 +- .../src/render/union_literal.rs | 2 +- .../ide-completion/src/render/variant.rs | 22 +-- .../rust-analyzer/crates/ide-db/src/defs.rs | 93 +++++++----- .../crates/ide-db/src/path_transform.rs | 4 +- .../src/handlers/expected_function.rs | 2 +- .../src/handlers/invalid_cast.rs | 2 +- .../src/handlers/moved_out_of_ref.rs | 2 +- .../trait_impl_redundant_assoc_item.rs | 4 +- .../src/handlers/type_mismatch.rs | 8 +- .../src/handlers/typed_hole.rs | 4 +- .../src/handlers/unresolved_field.rs | 2 +- .../src/handlers/unresolved_method.rs | 4 +- .../crates/ide-diagnostics/src/lib.rs | 19 ++- .../crates/ide-ssr/src/matching.rs | 20 +-- .../rust-analyzer/crates/ide/src/hover.rs | 54 +++++-- .../crates/ide/src/hover/render.rs | 124 ++++++++++------ .../crates/ide/src/inlay_hints.rs | 28 ++-- .../crates/ide/src/inlay_hints/adjustment.rs | 10 +- .../crates/ide/src/inlay_hints/bind_pat.rs | 7 +- .../crates/ide/src/inlay_hints/chaining.rs | 6 +- .../ide/src/inlay_hints/closing_brace.rs | 7 +- .../crates/ide/src/inlay_hints/closure_ret.rs | 6 +- .../rust-analyzer/crates/ide/src/interpret.rs | 15 +- .../rust-analyzer/crates/ide/src/moniker.rs | 14 +- .../crates/ide/src/navigation_target.rs | 61 +++++--- .../rust-analyzer/crates/ide/src/runnables.rs | 14 +- .../crates/ide/src/signature_help.rs | 55 ++++--- .../crates/ide/src/static_index.rs | 12 +- .../crates/ide/src/view_memory_layout.rs | 20 ++- .../rust-analyzer/src/cli/analysis_stats.rs | 41 +++--- 62 files changed, 842 insertions(+), 517 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index 7839589994b2..fb604569f439 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -15,9 +15,10 @@ use stdx::never; use triomphe::Arc; use crate::{ - db::HirDatabase, generics::Generics, infer::InferenceContext, lower::ParamLoweringMode, - mir::monomorphize_mir_body_bad, to_placeholder_idx, Const, ConstData, ConstScalar, ConstValue, - GenericArg, Interner, MemoryMap, Substitution, TraitEnvironment, Ty, TyBuilder, + db::HirDatabase, display::DisplayTarget, generics::Generics, infer::InferenceContext, + lower::ParamLoweringMode, mir::monomorphize_mir_body_bad, to_placeholder_idx, Const, ConstData, + ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution, TraitEnvironment, Ty, + TyBuilder, }; use super::mir::{interpret_mir, lower_to_mir, pad16, MirEvalError, MirLowerError}; @@ -62,11 +63,15 @@ impl ConstEvalError { f: &mut String, db: &dyn HirDatabase, span_formatter: impl Fn(span::FileId, span::TextRange) -> String, - edition: span::Edition, + display_target: DisplayTarget, ) -> std::result::Result<(), std::fmt::Error> { match self { - ConstEvalError::MirLowerError(e) => e.pretty_print(f, db, span_formatter, edition), - ConstEvalError::MirEvalError(e) => e.pretty_print(f, db, span_formatter, edition), + ConstEvalError::MirLowerError(e) => { + e.pretty_print(f, db, span_formatter, display_target) + } + ConstEvalError::MirEvalError(e) => { + e.pretty_print(f, db, span_formatter, display_target) + } } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index 249170c4f3ee..26a3b7022976 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -10,8 +10,8 @@ use test_fixture::WithFixture; use test_utils::skip_slow_tests; use crate::{ - consteval::try_const_usize, db::HirDatabase, mir::pad16, test_db::TestDB, Const, ConstScalar, - Interner, MemoryMap, + consteval::try_const_usize, db::HirDatabase, display::DisplayTarget, mir::pad16, + test_db::TestDB, Const, ConstScalar, Interner, MemoryMap, }; use super::{ @@ -101,11 +101,17 @@ fn check_answer( fn pretty_print_err(e: ConstEvalError, db: TestDB) -> String { let mut err = String::new(); let span_formatter = |file, range| format!("{file:?} {range:?}"); - let edition = - db.crate_graph()[*db.crate_graph().crates_in_topological_order().last().unwrap()].edition; + let display_target = DisplayTarget::from_crate( + &db, + *db.crate_graph().crates_in_topological_order().last().unwrap(), + ); match e { - ConstEvalError::MirLowerError(e) => e.pretty_print(&mut err, &db, span_formatter, edition), - ConstEvalError::MirEvalError(e) => e.pretty_print(&mut err, &db, span_formatter, edition), + ConstEvalError::MirLowerError(e) => { + e.pretty_print(&mut err, &db, span_formatter, display_target) + } + ConstEvalError::MirEvalError(e) => { + e.pretty_print(&mut err, &db, span_formatter, display_target) + } } .unwrap(); err diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 59aaf85164a0..cc6f4d9e52eb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -16,7 +16,6 @@ use intern::sym; use itertools::Itertools; use rustc_hash::FxHashSet; use rustc_pattern_analysis::constructor::Constructor; -use span::Edition; use syntax::{ ast::{self, UnaryOp}, AstNode, @@ -31,7 +30,7 @@ use crate::{ self, pat_analysis::{self, DeconstructedPat, MatchCheckCtx, WitnessPat}, }, - display::HirDisplay, + display::{DisplayTarget, HirDisplay}, Adjust, InferenceResult, Interner, Ty, TyExt, TyKind, }; @@ -633,24 +632,24 @@ fn missing_match_arms<'p>( arms_is_empty: bool, krate: CrateId, ) -> String { - struct DisplayWitness<'a, 'p>(&'a WitnessPat<'p>, &'a MatchCheckCtx<'p>, Edition); + struct DisplayWitness<'a, 'p>(&'a WitnessPat<'p>, &'a MatchCheckCtx<'p>, DisplayTarget); impl fmt::Display for DisplayWitness<'_, '_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let DisplayWitness(witness, cx, edition) = *self; + let DisplayWitness(witness, cx, display_target) = *self; let pat = cx.hoist_witness_pat(witness); - write!(f, "{}", pat.display(cx.db, edition)) + write!(f, "{}", pat.display(cx.db, display_target)) } } - let edition = cx.db.crate_graph()[krate].edition; let non_empty_enum = match scrut_ty.as_adt() { Some((AdtId::EnumId(e), _)) => !cx.db.enum_data(e).variants.is_empty(), _ => false, }; + let display_target = DisplayTarget::from_crate(cx.db, krate); if arms_is_empty && !non_empty_enum { - format!("type `{}` is non-empty", scrut_ty.display(cx.db, edition)) + format!("type `{}` is non-empty", scrut_ty.display(cx.db, display_target)) } else { - let pat_display = |witness| DisplayWitness(witness, cx, edition); + let pat_display = |witness| DisplayWitness(witness, cx, display_target); const LIMIT: usize = 3; match &*witnesses { [witness] => format!("`{}` not covered", pat_display(witness)), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index b3613b372bfd..41152d90220e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -88,6 +88,7 @@ pub struct HirFormatter<'a> { show_container_bounds: bool, omit_verbose_types: bool, closure_style: ClosureStyle, + display_kind: DisplayKind, display_target: DisplayTarget, bounds_formatting_ctx: BoundsFormattingCtx, } @@ -165,6 +166,7 @@ pub trait HirDisplay { limited_size: Option, omit_verbose_types: bool, display_target: DisplayTarget, + display_kind: DisplayKind, closure_style: ClosureStyle, show_container_bounds: bool, ) -> HirDisplayWrapper<'a, Self> @@ -172,7 +174,7 @@ pub trait HirDisplay { Self: Sized, { assert!( - !matches!(display_target, DisplayTarget::SourceCode { .. }), + !matches!(display_kind, DisplayKind::SourceCode { .. }), "HirDisplayWrapper cannot fail with DisplaySourceCodeError, use HirDisplay::hir_fmt directly instead" ); HirDisplayWrapper { @@ -182,6 +184,7 @@ pub trait HirDisplay { limited_size, omit_verbose_types, display_target, + display_kind, closure_style, show_container_bounds, } @@ -192,7 +195,7 @@ pub trait HirDisplay { fn display<'a>( &'a self, db: &'a dyn HirDatabase, - edition: Edition, + display_target: DisplayTarget, ) -> HirDisplayWrapper<'a, Self> where Self: Sized, @@ -204,7 +207,8 @@ pub trait HirDisplay { limited_size: None, omit_verbose_types: false, closure_style: ClosureStyle::ImplFn, - display_target: DisplayTarget::Diagnostics { edition }, + display_target, + display_kind: DisplayKind::Diagnostics, show_container_bounds: false, } } @@ -215,7 +219,7 @@ pub trait HirDisplay { &'a self, db: &'a dyn HirDatabase, max_size: Option, - edition: Edition, + display_target: DisplayTarget, ) -> HirDisplayWrapper<'a, Self> where Self: Sized, @@ -227,7 +231,8 @@ pub trait HirDisplay { limited_size: None, omit_verbose_types: true, closure_style: ClosureStyle::ImplFn, - display_target: DisplayTarget::Diagnostics { edition }, + display_target, + display_kind: DisplayKind::Diagnostics, show_container_bounds: false, } } @@ -238,7 +243,7 @@ pub trait HirDisplay { &'a self, db: &'a dyn HirDatabase, limited_size: Option, - edition: Edition, + display_target: DisplayTarget, ) -> HirDisplayWrapper<'a, Self> where Self: Sized, @@ -250,7 +255,8 @@ pub trait HirDisplay { limited_size, omit_verbose_types: true, closure_style: ClosureStyle::ImplFn, - display_target: DisplayTarget::Diagnostics { edition }, + display_target, + display_kind: DisplayKind::Diagnostics, show_container_bounds: false, } } @@ -273,7 +279,8 @@ pub trait HirDisplay { entity_limit: None, omit_verbose_types: false, closure_style: ClosureStyle::ImplFn, - display_target: DisplayTarget::SourceCode { module_id, allow_opaque }, + display_target: DisplayTarget::from_crate(db, module_id.krate()), + display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque }, show_container_bounds: false, bounds_formatting_ctx: Default::default(), }) { @@ -285,29 +292,10 @@ pub trait HirDisplay { } /// Returns a String representation of `self` for test purposes - fn display_test<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self> - where - Self: Sized, - { - HirDisplayWrapper { - db, - t: self, - max_size: None, - limited_size: None, - omit_verbose_types: false, - closure_style: ClosureStyle::ImplFn, - display_target: DisplayTarget::Test, - show_container_bounds: false, - } - } - - /// Returns a String representation of `self` that shows the constraint from - /// the container for functions - fn display_with_container_bounds<'a>( + fn display_test<'a>( &'a self, db: &'a dyn HirDatabase, - show_container_bounds: bool, - edition: Edition, + display_target: DisplayTarget, ) -> HirDisplayWrapper<'a, Self> where Self: Sized, @@ -319,21 +307,44 @@ pub trait HirDisplay { limited_size: None, omit_verbose_types: false, closure_style: ClosureStyle::ImplFn, - display_target: DisplayTarget::Diagnostics { edition }, + display_target, + display_kind: DisplayKind::Test, + show_container_bounds: false, + } + } + + /// Returns a String representation of `self` that shows the constraint from + /// the container for functions + fn display_with_container_bounds<'a>( + &'a self, + db: &'a dyn HirDatabase, + show_container_bounds: bool, + display_target: DisplayTarget, + ) -> HirDisplayWrapper<'a, Self> + where + Self: Sized, + { + HirDisplayWrapper { + db, + t: self, + max_size: None, + limited_size: None, + omit_verbose_types: false, + closure_style: ClosureStyle::ImplFn, + display_target, + display_kind: DisplayKind::Diagnostics, show_container_bounds, } } } impl HirFormatter<'_> { + pub fn krate(&self) -> CrateId { + self.display_target.krate + } + pub fn edition(&self) -> Edition { - match self.display_target { - DisplayTarget::Diagnostics { edition } => edition, - DisplayTarget::SourceCode { module_id, .. } => { - self.db.crate_graph()[module_id.krate()].edition - } - DisplayTarget::Test => Edition::CURRENT, - } + self.display_target.edition } pub fn write_joined( @@ -395,20 +406,33 @@ impl HirFormatter<'_> { } } +#[derive(Debug, Clone, Copy)] +pub struct DisplayTarget { + krate: CrateId, + pub edition: Edition, +} + +impl DisplayTarget { + pub fn from_crate(db: &dyn HirDatabase, krate: CrateId) -> Self { + let edition = db.crate_graph()[krate].edition; + Self { krate, edition } + } +} + #[derive(Clone, Copy)] -pub enum DisplayTarget { +pub enum DisplayKind { /// Display types for inlays, doc popups, autocompletion, etc... /// Showing `{unknown}` or not qualifying paths is fine here. /// There's no reason for this to fail. - Diagnostics { edition: Edition }, + Diagnostics, /// Display types for inserting them in source files. /// The generated code should compile, so paths need to be qualified. - SourceCode { module_id: ModuleId, allow_opaque: bool }, + SourceCode { target_module_id: ModuleId, allow_opaque: bool }, /// Only for test purpose to keep real types Test, } -impl DisplayTarget { +impl DisplayKind { fn is_source_code(self) -> bool { matches!(self, Self::SourceCode { .. }) } @@ -451,6 +475,7 @@ pub struct HirDisplayWrapper<'a, T> { limited_size: Option, omit_verbose_types: bool, closure_style: ClosureStyle, + display_kind: DisplayKind, display_target: DisplayTarget, show_container_bounds: bool, } @@ -480,6 +505,7 @@ impl HirDisplayWrapper<'_, T> { max_size: self.max_size, entity_limit: self.limited_size, omit_verbose_types: self.omit_verbose_types, + display_kind: self.display_kind, display_target: self.display_target, closure_style: self.closure_style, show_container_bounds: self.show_container_bounds, @@ -534,7 +560,7 @@ impl HirDisplay for ProjectionTy { // if we are projection on a type parameter, check if the projection target has bounds // itself, if so, we render them directly as `impl Bound` instead of the less useful // `::Assoc` - if !f.display_target.is_source_code() { + if !f.display_kind.is_source_code() { if let TyKind::Placeholder(idx) = self_ty.kind(Interner) { if !f.bounds_formatting_ctx.contains(self) { let db = f.db; @@ -1111,7 +1137,7 @@ impl HirDisplay for Ty { let def = from_chalk(db, *def); let sig = db.callable_item_signature(def).substitute(Interner, parameters); - if f.display_target.is_source_code() { + if f.display_kind.is_source_code() { // `FnDef` is anonymous and there's no surface syntax for it. Show it as a // function pointer type. return sig.hir_fmt(f); @@ -1200,8 +1226,8 @@ impl HirDisplay for Ty { } TyKind::Adt(AdtId(def_id), parameters) => { f.start_location_link((*def_id).into()); - match f.display_target { - DisplayTarget::Diagnostics { .. } | DisplayTarget::Test => { + match f.display_kind { + DisplayKind::Diagnostics { .. } | DisplayKind::Test { .. } => { let name = match *def_id { hir_def::AdtId::StructId(it) => db.struct_data(it).name.clone(), hir_def::AdtId::UnionId(it) => db.union_data(it).name.clone(), @@ -1209,7 +1235,7 @@ impl HirDisplay for Ty { }; write!(f, "{}", name.display(f.db.upcast(), f.edition()))?; } - DisplayTarget::SourceCode { module_id, allow_opaque: _ } => { + DisplayKind::SourceCode { target_module_id: module_id, allow_opaque: _ } => { if let Some(path) = find_path::find_path( db.upcast(), ItemInNs::Types((*def_id).into()), @@ -1248,7 +1274,7 @@ impl HirDisplay for Ty { let type_alias_data = db.type_alias_data(type_alias); // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) - if f.display_target.is_test() { + if f.display_kind.is_test() { f.start_location_link(trait_.into()); write!(f, "{}", trait_data.name.display(f.db.upcast(), f.edition()))?; f.end_location_link(); @@ -1277,7 +1303,7 @@ impl HirDisplay for Ty { f.end_location_link(); } TyKind::OpaqueType(opaque_ty_id, parameters) => { - if !f.display_target.allows_opaque() { + if !f.display_kind.allows_opaque() { return Err(HirDisplayError::DisplaySourceCodeError( DisplaySourceCodeError::OpaqueType, )); @@ -1346,8 +1372,8 @@ impl HirDisplay for Ty { } } TyKind::Closure(id, substs) => { - if f.display_target.is_source_code() { - if !f.display_target.allows_opaque() { + if f.display_kind.is_source_code() { + if !f.display_kind.allows_opaque() { return Err(HirDisplayError::DisplaySourceCodeError( DisplaySourceCodeError::OpaqueType, )); @@ -1467,7 +1493,7 @@ impl HirDisplay for Ty { } TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { - if !f.display_target.allows_opaque() { + if !f.display_kind.allows_opaque() { return Err(HirDisplayError::DisplaySourceCodeError( DisplaySourceCodeError::OpaqueType, )); @@ -1510,7 +1536,7 @@ impl HirDisplay for Ty { }; } TyKind::Error => { - if f.display_target.is_source_code() { + if f.display_kind.is_source_code() { f.write_char('_')?; } else { write!(f, "{{unknown}}")?; @@ -1518,7 +1544,7 @@ impl HirDisplay for Ty { } TyKind::InferenceVar(..) => write!(f, "_")?, TyKind::Coroutine(_, subst) => { - if f.display_target.is_source_code() { + if f.display_kind.is_source_code() { return Err(HirDisplayError::DisplaySourceCodeError( DisplaySourceCodeError::Coroutine, )); @@ -1575,7 +1601,7 @@ fn generic_args_sans_defaults<'ga>( generic_def: Option, parameters: &'ga [GenericArg], ) -> &'ga [GenericArg] { - if f.display_target.is_source_code() || f.omit_verbose_types() { + if f.display_kind.is_source_code() || f.omit_verbose_types() { match generic_def .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) .filter(|it| !it.is_empty()) @@ -1960,7 +1986,7 @@ impl HirDisplay for LifetimeData { write!(f, "{}", param_data.name.display(f.db.upcast(), f.edition()))?; Ok(()) } - _ if f.display_target.is_source_code() => write!(f, "'_"), + _ if f.display_kind.is_source_code() => write!(f, "'_"), LifetimeData::BoundVar(idx) => idx.hir_fmt(f), LifetimeData::InferenceVar(_) => write!(f, "_"), LifetimeData::Static => write!(f, "'static"), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 707c43777267..2f9245a33261 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -76,13 +76,15 @@ use intern::{sym, Symbol}; use la_arena::{Arena, Idx}; use mir::{MirEvalError, VTableMap}; use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet}; -use span::Edition; use syntax::ast::{make, ConstArg}; use traits::FnTrait; use triomphe::Arc; use crate::{ - consteval::unknown_const, db::HirDatabase, display::HirDisplay, generics::Generics, + consteval::unknown_const, + db::HirDatabase, + display::{DisplayTarget, HirDisplay}, + generics::Generics, infer::unify::InferenceTable, }; @@ -1044,7 +1046,7 @@ where pub fn known_const_to_ast( konst: &Const, db: &dyn HirDatabase, - edition: Edition, + display_target: DisplayTarget, ) -> Option { if let ConstValue::Concrete(c) = &konst.interned().value { match c.interned { @@ -1055,7 +1057,7 @@ pub fn known_const_to_ast( _ => (), } } - Some(make::expr_const_value(konst.display(db, edition).to_string().as_str())) + Some(make::expr_const_value(konst.display(db, display_target).to_string().as_str())) } #[derive(Debug, Copy, Clone)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs index 41304bbd8a91..56c431ef8dab 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs @@ -5,7 +5,7 @@ use std::{collections::hash_map::Entry, fmt::Display, iter}; use crate::{ consteval::usize_const, db::HirDatabase, - display::HirDisplay, + display::{DisplayTarget, HirDisplay}, infer::{normalize, PointerCast}, lang_items::is_box, mapping::ToChalk, @@ -168,7 +168,7 @@ impl ProjectionElem { _ => { never!( "Overloaded deref on type {} is not a projection", - base.display(db, db.crate_graph()[krate].edition) + base.display(db, DisplayTarget::from_crate(db, krate)) ); TyKind::Error.intern(Interner) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index 9c86d3b59f6d..fbcca388e781 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs @@ -13,6 +13,7 @@ use triomphe::Arc; use crate::{ db::{HirDatabase, InternedClosure}, + display::DisplayTarget, mir::Operand, utils::ClosureSubst, ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags, @@ -422,7 +423,10 @@ fn ever_initialized_map( let Some(terminator) = &block.terminator else { never!( "Terminator should be none only in construction.\nThe body:\n{}", - body.pretty_print(db) + body.pretty_print( + db, + DisplayTarget::from_crate(db, body.owner.krate(db.upcast())) + ) ); return; }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index d0f9f4519caa..74a34e298171 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -24,7 +24,7 @@ use rustc_apfloat::{ Float, }; use rustc_hash::{FxHashMap, FxHashSet}; -use span::{Edition, FileId}; +use span::FileId; use stdx::never; use syntax::{SyntaxNodePtr, TextRange}; use triomphe::Arc; @@ -32,7 +32,7 @@ use triomphe::Arc; use crate::{ consteval::{intern_const_scalar, try_const_usize, ConstEvalError}, db::{HirDatabase, InternedClosure}, - display::{ClosureStyle, HirDisplay}, + display::{ClosureStyle, DisplayTarget, HirDisplay}, infer::PointerCast, layout::{Layout, LayoutError, RustcEnumVariantIdx}, mapping::from_chalk, @@ -359,7 +359,7 @@ impl MirEvalError { f: &mut String, db: &dyn HirDatabase, span_formatter: impl Fn(FileId, TextRange) -> String, - edition: Edition, + display_target: DisplayTarget, ) -> std::result::Result<(), std::fmt::Error> { writeln!(f, "Mir eval error:")?; let mut err = self; @@ -372,7 +372,7 @@ impl MirEvalError { writeln!( f, "In function {} ({:?})", - function_name.name.display(db.upcast(), edition), + function_name.name.display(db.upcast(), display_target.edition), func )?; } @@ -417,7 +417,7 @@ impl MirEvalError { write!( f, "Layout for type `{}` is not available due {err:?}", - ty.display(db, edition).with_closure_style(ClosureStyle::ClosureWithId) + ty.display(db, display_target).with_closure_style(ClosureStyle::ClosureWithId) )?; } MirEvalError::MirLowerError(func, err) => { @@ -428,12 +428,15 @@ impl MirEvalError { let substs = generics.placeholder_subst(db); db.impl_self_ty(impl_id) .substitute(Interner, &substs) - .display(db, edition) + .display(db, display_target) .to_string() }), - ItemContainerId::TraitId(it) => { - Some(db.trait_data(it).name.display(db.upcast(), edition).to_string()) - } + ItemContainerId::TraitId(it) => Some( + db.trait_data(it) + .name + .display(db.upcast(), display_target.edition) + .to_string(), + ), _ => None, }; writeln!( @@ -441,17 +444,17 @@ impl MirEvalError { "MIR lowering for function `{}{}{}` ({:?}) failed due:", self_.as_deref().unwrap_or_default(), if self_.is_some() { "::" } else { "" }, - function_name.name.display(db.upcast(), edition), + function_name.name.display(db.upcast(), display_target.edition), func )?; - err.pretty_print(f, db, span_formatter, edition)?; + err.pretty_print(f, db, span_formatter, display_target)?; } MirEvalError::ConstEvalError(name, err) => { MirLowerError::ConstEvalError((**name).into(), err.clone()).pretty_print( f, db, span_formatter, - edition, + display_target, )?; } MirEvalError::UndefinedBehavior(_) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index 7d3376f56be1..f61ecabb7e41 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -14,6 +14,7 @@ use intern::{sym, Symbol}; use stdx::never; use crate::{ + display::DisplayTarget, error_lifetime, mir::eval::{ pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay, @@ -835,8 +836,7 @@ impl Evaluator<'_> { // render full paths. Err(_) => { let krate = locals.body.owner.krate(self.db.upcast()); - let edition = self.db.crate_graph()[krate].edition; - ty.display(self.db, edition).to_string() + ty.display(self.db, DisplayTarget::from_crate(self.db, krate)).to_string() } }; let len = ty_name.len(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs index 2b5486fc5fa0..084c391d26cb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs @@ -3,6 +3,7 @@ use span::{Edition, EditionedFileId}; use syntax::{TextRange, TextSize}; use test_fixture::WithFixture; +use crate::display::DisplayTarget; use crate::{db::HirDatabase, mir::MirLowerError, test_db::TestDB, Interner, Substitution}; use super::{interpret_mir, MirEvalError}; @@ -67,7 +68,9 @@ fn check_pass_and_stdio( let span_formatter = |file, range: TextRange| { format!("{:?} {:?}..{:?}", file, line_index(range.start()), line_index(range.end())) }; - e.pretty_print(&mut err, &db, span_formatter, Edition::CURRENT).unwrap(); + let krate = db.module_for_file(file_id).krate(); + e.pretty_print(&mut err, &db, span_formatter, DisplayTarget::from_crate(&db, krate)) + .unwrap(); panic!("Error in interpreting: {err}"); } Ok((stdout, stderr)) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 2fe4ce8319e2..520717e79952 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -2,7 +2,7 @@ use std::{fmt::Write, iter, mem}; -use base_db::ra_salsa::Cycle; +use base_db::{ra_salsa::Cycle, CrateId}; use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind}; use hir_def::{ data::adt::{StructKind, VariantData}, @@ -29,7 +29,7 @@ use triomphe::Arc; use crate::{ consteval::ConstEvalError, db::{HirDatabase, InternedClosure}, - display::{hir_display_with_types_map, HirDisplay}, + display::{hir_display_with_types_map, DisplayTarget, HirDisplay}, error_lifetime, generics::generics, infer::{cast::CastTy, unify::InferenceTable, CaptureKind, CapturedItem, TypeMismatch}, @@ -160,17 +160,17 @@ impl MirLowerError { f: &mut String, db: &dyn HirDatabase, span_formatter: impl Fn(FileId, TextRange) -> String, - edition: Edition, + display_target: DisplayTarget, ) -> std::result::Result<(), std::fmt::Error> { match self { MirLowerError::ConstEvalError(name, e) => { writeln!(f, "In evaluating constant {name}")?; match &**e { ConstEvalError::MirLowerError(e) => { - e.pretty_print(f, db, span_formatter, edition)? + e.pretty_print(f, db, span_formatter, display_target)? } ConstEvalError::MirEvalError(e) => { - e.pretty_print(f, db, span_formatter, edition)? + e.pretty_print(f, db, span_formatter, display_target)? } } } @@ -179,15 +179,15 @@ impl MirLowerError { writeln!( f, "Missing function definition for {}", - body.pretty_print_expr(db.upcast(), *owner, *it, edition) + body.pretty_print_expr(db.upcast(), *owner, *it, display_target.edition) )?; } MirLowerError::HasErrors => writeln!(f, "Type inference result contains errors")?, MirLowerError::TypeMismatch(e) => writeln!( f, "Type mismatch: Expected {}, found {}", - e.expected.display(db, edition), - e.actual.display(db, edition), + e.expected.display(db, display_target), + e.actual.display(db, display_target), )?, MirLowerError::GenericArgNotProvided(id, subst) => { let parent = id.parent; @@ -195,11 +195,14 @@ impl MirLowerError { writeln!( f, "Generic arg not provided for {}", - param.name().unwrap_or(&Name::missing()).display(db.upcast(), edition) + param + .name() + .unwrap_or(&Name::missing()) + .display(db.upcast(), display_target.edition) )?; writeln!(f, "Provided args: [")?; for g in subst.iter(Interner) { - write!(f, " {},", g.display(db, edition))?; + write!(f, " {},", g.display(db, display_target))?; } writeln!(f, "]")?; } @@ -251,11 +254,11 @@ impl MirLowerError { fn unresolved_path( db: &dyn HirDatabase, p: &Path, - edition: Edition, + display_target: DisplayTarget, types_map: &TypesMap, ) -> Self { Self::UnresolvedName( - hir_display_with_types_map(p, types_map).display(db, edition).to_string(), + hir_display_with_types_map(p, types_map).display(db, display_target).to_string(), ) } } @@ -462,7 +465,7 @@ impl<'ctx> MirLowerCtx<'ctx> { MirLowerError::unresolved_path( self.db, p, - self.edition(), + DisplayTarget::from_crate(self.db, self.krate()), &self.body.types, ) })?; @@ -838,7 +841,7 @@ impl<'ctx> MirLowerCtx<'ctx> { self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path { Some(p) => MirLowerError::UnresolvedName( hir_display_with_types_map(&**p, &self.body.types) - .display(self.db, self.edition()) + .display(self.db, self.display_target()) .to_string(), ), None => MirLowerError::RecordLiteralWithoutPath, @@ -1362,9 +1365,16 @@ impl<'ctx> MirLowerCtx<'ctx> { match &self.body.exprs[*loc] { Expr::Literal(l) => self.lower_literal_to_operand(ty, l), Expr::Path(c) => { - let edition = self.edition(); - let unresolved_name = - || MirLowerError::unresolved_path(self.db, c, edition, &self.body.types); + let owner = self.owner; + let db = self.db; + let unresolved_name = || { + MirLowerError::unresolved_path( + self.db, + c, + DisplayTarget::from_crate(db, owner.krate(db.upcast())), + &self.body.types, + ) + }; let pr = self .resolver .resolve_path_in_value_ns(self.db.upcast(), c, HygieneId::ROOT) @@ -1910,8 +1920,15 @@ impl<'ctx> MirLowerCtx<'ctx> { } fn edition(&self) -> Edition { - let krate = self.owner.krate(self.db.upcast()); - self.db.crate_graph()[krate].edition + self.db.crate_graph()[self.krate()].edition + } + + fn krate(&self) -> CrateId { + self.owner.krate(self.db.upcast()) + } + + fn display_target(&self) -> DisplayTarget { + DisplayTarget::from_crate(self.db, self.krate()) } fn drop_until_scope( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs index 289175feefb1..783f92b2043f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -350,7 +350,12 @@ impl MirLowerCtx<'_> { )?, None => { let unresolved_name = || { - MirLowerError::unresolved_path(self.db, p, self.edition(), &self.body.types) + MirLowerError::unresolved_path( + self.db, + p, + self.display_target(), + &self.body.types, + ) }; let hygiene = self.body.pat_path_hygiene(pattern); let pr = self diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs index 2a26101ac439..7d7d4106cb95 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs @@ -9,11 +9,10 @@ use either::Either; use hir_def::{expr_store::Body, hir::BindingId}; use hir_expand::{name::Name, Lookup}; use la_arena::ArenaMap; -use span::Edition; use crate::{ db::HirDatabase, - display::{ClosureStyle, HirDisplay}, + display::{ClosureStyle, DisplayTarget, HirDisplay}, mir::{PlaceElem, ProjectionElem, StatementKind, TerminatorKind}, ClosureId, }; @@ -39,17 +38,21 @@ macro_rules! wln { } impl MirBody { - pub fn pretty_print(&self, db: &dyn HirDatabase) -> String { + pub fn pretty_print(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String { let hir_body = db.body(self.owner); - let mut ctx = MirPrettyCtx::new(self, &hir_body, db); + let mut ctx = MirPrettyCtx::new(self, &hir_body, db, display_target); ctx.for_body(|this| match ctx.body.owner { hir_def::DefWithBodyId::FunctionId(id) => { let data = db.function_data(id); - w!(this, "fn {}() ", data.name.display(db.upcast(), Edition::LATEST)); + w!(this, "fn {}() ", data.name.display(db.upcast(), this.display_target.edition)); } hir_def::DefWithBodyId::StaticId(id) => { let data = db.static_data(id); - w!(this, "static {}: _ = ", data.name.display(db.upcast(), Edition::LATEST)); + w!( + this, + "static {}: _ = ", + data.name.display(db.upcast(), this.display_target.edition) + ); } hir_def::DefWithBodyId::ConstId(id) => { let data = db.const_data(id); @@ -59,7 +62,7 @@ impl MirBody { data.name .as_ref() .unwrap_or(&Name::missing()) - .display(db.upcast(), Edition::LATEST) + .display(db.upcast(), this.display_target.edition) ); } hir_def::DefWithBodyId::VariantId(id) => { @@ -70,10 +73,10 @@ impl MirBody { "enum {}::{} = ", enum_loc.id.item_tree(db.upcast())[enum_loc.id.value] .name - .display(db.upcast(), Edition::LATEST), + .display(db.upcast(), this.display_target.edition), loc.id.item_tree(db.upcast())[loc.id.value] .name - .display(db.upcast(), Edition::LATEST), + .display(db.upcast(), this.display_target.edition), ) } hir_def::DefWithBodyId::InTypeConstId(id) => { @@ -85,14 +88,14 @@ impl MirBody { // String with lines is rendered poorly in `dbg` macros, which I use very much, so this // function exists to solve that. - pub fn dbg(&self, db: &dyn HirDatabase) -> impl Debug { + pub fn dbg(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> impl Debug { struct StringDbg(String); impl Debug for StringDbg { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&self.0) } } - StringDbg(self.pretty_print(db)) + StringDbg(self.pretty_print(db, display_target)) } } @@ -103,6 +106,7 @@ struct MirPrettyCtx<'a> { result: String, indent: String, local_to_binding: ArenaMap, + display_target: DisplayTarget, } impl Write for MirPrettyCtx<'_> { @@ -182,7 +186,12 @@ impl<'a> MirPrettyCtx<'a> { wln!(self, "}}"); } - fn new(body: &'a MirBody, hir_body: &'a Body, db: &'a dyn HirDatabase) -> Self { + fn new( + body: &'a MirBody, + hir_body: &'a Body, + db: &'a dyn HirDatabase, + display_target: DisplayTarget, + ) -> Self { let local_to_binding = body.local_to_binding_map(); MirPrettyCtx { body, @@ -191,6 +200,7 @@ impl<'a> MirPrettyCtx<'a> { indent: String::new(), local_to_binding, hir_body, + display_target, } } @@ -208,7 +218,7 @@ impl<'a> MirPrettyCtx<'a> { wln!( self, "let {}: {};", - self.local_name(id).display_test(self.db), + self.local_name(id).display_test(self.db, self.display_target), self.hir_display(&local.ty) ); } @@ -242,14 +252,14 @@ impl<'a> MirPrettyCtx<'a> { wln!( this, "StorageDead({})", - this.local_name(*p).display_test(self.db) + this.local_name(*p).display_test(this.db, this.display_target) ); } StatementKind::StorageLive(p) => { wln!( this, "StorageLive({})", - this.local_name(*p).display_test(self.db) + this.local_name(*p).display_test(this.db, this.display_target) ); } StatementKind::Deinit(p) => { @@ -313,7 +323,7 @@ impl<'a> MirPrettyCtx<'a> { fn f(this: &mut MirPrettyCtx<'_>, local: LocalId, projections: &[PlaceElem]) { let Some((last, head)) = projections.split_last() else { // no projection - w!(this, "{}", this.local_name(local).display_test(this.db)); + w!(this, "{}", this.local_name(local).display_test(this.db, this.display_target)); return; }; match last { @@ -333,13 +343,17 @@ impl<'a> MirPrettyCtx<'a> { w!( this, " as {}).{}", - variant_name.display(this.db.upcast(), Edition::LATEST), - name.display(this.db.upcast(), Edition::LATEST) + variant_name.display(this.db.upcast(), this.display_target.edition), + name.display(this.db.upcast(), this.display_target.edition) ); } hir_def::VariantId::StructId(_) | hir_def::VariantId::UnionId(_) => { f(this, local, head); - w!(this, ".{}", name.display(this.db.upcast(), Edition::LATEST)); + w!( + this, + ".{}", + name.display(this.db.upcast(), this.display_target.edition) + ); } } } @@ -353,7 +367,11 @@ impl<'a> MirPrettyCtx<'a> { } ProjectionElem::Index(l) => { f(this, local, head); - w!(this, "[{}]", this.local_name(*l).display_test(this.db)); + w!( + this, + "[{}]", + this.local_name(*l).display_test(this.db, this.display_target) + ); } it => { f(this, local, head); @@ -403,7 +421,7 @@ impl<'a> MirPrettyCtx<'a> { Rvalue::Repeat(op, len) => { w!(self, "["); self.operand(op); - w!(self, "; {}]", len.display_test(self.db)); + w!(self, "; {}]", len.display_test(self.db, self.display_target)); } Rvalue::Aggregate(AggregateKind::Adt(_, _), it) => { w!(self, "Adt("); @@ -478,6 +496,7 @@ impl<'a> MirPrettyCtx<'a> { } fn hir_display(&self, ty: &'a T) -> impl Display + 'a { - ty.display_test(self.db).with_closure_style(ClosureStyle::ClosureWithSubst) + ty.display_test(self.db, self.display_target) + .with_closure_style(ClosureStyle::ClosureWithSubst) } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index f5a4d4ff35c3..81e38be2285a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -15,7 +15,7 @@ mod type_alias_impl_traits; use std::env; use std::sync::LazyLock; -use base_db::SourceDatabaseFileInputExt as _; +use base_db::{CrateId, SourceDatabaseFileInputExt as _}; use expect_test::Expect; use hir_def::{ db::DefDatabase, @@ -41,7 +41,7 @@ use triomphe::Arc; use crate::{ db::HirDatabase, - display::HirDisplay, + display::{DisplayTarget, HirDisplay}, infer::{Adjustment, TypeMismatch}, test_db::TestDB, InferenceResult, Ty, @@ -124,7 +124,7 @@ fn check_impl( } assert!(had_annotations || allow_none, "no `//^` annotations found"); - let mut defs: Vec = Vec::new(); + let mut defs: Vec<(DefWithBodyId, CrateId)> = Vec::new(); for file_id in files { let module = db.module_for_file_opt(file_id); let module = match module { @@ -133,16 +133,17 @@ fn check_impl( }; let def_map = module.def_map(&db); visit_module(&db, &def_map, module.local_id, &mut |it| { - defs.push(match it { + let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), ModuleDefId::ConstId(it) => it.into(), ModuleDefId::StaticId(it) => it.into(), _ => return, - }) + }; + defs.push((def, module.krate())) }); } - defs.sort_by_key(|def| match def { + defs.sort_by_key(|(def, _)| match def { DefWithBodyId::FunctionId(it) => { let loc = it.lookup(&db); loc.source(&db).value.syntax().text_range().start() @@ -162,7 +163,8 @@ fn check_impl( DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(), }); let mut unexpected_type_mismatches = String::new(); - for def in defs { + for (def, krate) in defs { + let display_target = DisplayTarget::from_crate(&db, krate); let (body, body_source_map) = db.body_with_source_map(def); let inference_result = db.infer(def); @@ -179,7 +181,7 @@ fn check_impl( let actual = if display_source { ty.display_source_code(&db, def.module(&db), true).unwrap() } else { - ty.display_test(&db).to_string() + ty.display_test(&db, display_target).to_string() }; assert_eq!(actual, expected, "type annotation differs at {:#?}", range.range); } @@ -195,7 +197,7 @@ fn check_impl( let actual = if display_source { ty.display_source_code(&db, def.module(&db), true).unwrap() } else { - ty.display_test(&db).to_string() + ty.display_test(&db, display_target).to_string() }; assert_eq!(actual, expected, "type annotation differs at {:#?}", range.range); } @@ -224,8 +226,8 @@ fn check_impl( let range = node.as_ref().original_file_range_rooted(&db); let actual = format!( "expected {}, got {}", - mismatch.expected.display_test(&db), - mismatch.actual.display_test(&db) + mismatch.expected.display_test(&db, display_target), + mismatch.actual.display_test(&db, display_target) ); match mismatches.remove(&range) { Some(annotation) => assert_eq!(actual, annotation), @@ -299,7 +301,9 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let mut infer_def = |inference_result: Arc, body: Arc, - body_source_map: Arc| { + body_source_map: Arc, + krate: CrateId| { + let display_target = DisplayTarget::from_crate(&db, krate); let mut types: Vec<(InFile, &Ty)> = Vec::new(); let mut mismatches: Vec<(InFile, &TypeMismatch)> = Vec::new(); @@ -361,7 +365,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { macro_prefix, range, ellipsize(text, 15), - ty.display_test(&db) + ty.display_test(&db, display_target) ); } if include_mismatches { @@ -377,8 +381,8 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { "{}{:?}: expected {}, got {}\n", macro_prefix, range, - mismatch.expected.display_test(&db), - mismatch.actual.display_test(&db), + mismatch.expected.display_test(&db, display_target), + mismatch.actual.display_test(&db, display_target), ); } } @@ -387,17 +391,18 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let module = db.module_for_file(file_id); let def_map = module.def_map(&db); - let mut defs: Vec = Vec::new(); + let mut defs: Vec<(DefWithBodyId, CrateId)> = Vec::new(); visit_module(&db, &def_map, module.local_id, &mut |it| { - defs.push(match it { + let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), ModuleDefId::ConstId(it) => it.into(), ModuleDefId::StaticId(it) => it.into(), _ => return, - }) + }; + defs.push((def, module.krate())) }); - defs.sort_by_key(|def| match def { + defs.sort_by_key(|(def, _)| match def { DefWithBodyId::FunctionId(it) => { let loc = it.lookup(&db); loc.source(&db).value.syntax().text_range().start() @@ -416,10 +421,10 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { } DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(), }); - for def in defs { + for (def, krate) in defs { let (body, source_map) = db.body_with_source_map(def); let infer = db.infer(def); - infer_def(infer, body, source_map); + infer_def(infer, body, source_map, krate); } buf.truncate(buf.trim_end().len()); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs index 34d299edd1bd..6f7bfc4ea7a0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs @@ -8,7 +8,7 @@ use syntax::{AstNode, AstPtr}; use test_fixture::WithFixture; use crate::db::{HirDatabase, InternedClosureId}; -use crate::display::HirDisplay; +use crate::display::{DisplayTarget, HirDisplay}; use crate::mir::MirSpan; use crate::test_db::TestDB; @@ -66,7 +66,11 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec .join(", "), }; let place = capture.display_place(closure.0, db); - let capture_ty = capture.ty.skip_binders().display_test(db).to_string(); + let capture_ty = capture + .ty + .skip_binders() + .display_test(db, DisplayTarget::from_crate(db, module.krate())) + .to_string(); let spans = capture .spans() .iter() diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 7549d54a544e..a59f90b17501 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -39,7 +39,7 @@ use std::{ }; use arrayvec::ArrayVec; -use base_db::{CrateDisplayName, CrateId, CrateOrigin}; +use base_db::{CrateDisplayName, CrateId, CrateOrigin, LangCrateOrigin}; use either::Either; use hir_def::{ data::{adt::VariantData, TraitFlags}, @@ -147,7 +147,7 @@ pub use { hir_ty::{ consteval::ConstEvalError, diagnostics::UnsafetyReason, - display::{ClosureStyle, HirDisplay, HirDisplayError, HirWrite}, + display::{ClosureStyle, DisplayTarget, HirDisplay, HirDisplayError, HirWrite}, dyn_compatibility::{DynCompatibilityViolation, MethodViolationCode}, layout::LayoutError, method_resolution::TyFingerprint, @@ -282,6 +282,21 @@ impl Crate { let data = &db.crate_graph()[self.id]; data.potential_cfg_options.clone().unwrap_or_else(|| data.cfg_options.clone()) } + + pub fn to_display_target(self, db: &dyn HirDatabase) -> DisplayTarget { + DisplayTarget::from_crate(db, self.id) + } + + fn core(db: &dyn HirDatabase) -> Option { + let crate_graph = db.crate_graph(); + let result = crate_graph + .iter() + .find(|&krate| { + matches!(crate_graph[krate].origin, CrateOrigin::Lang(LangCrateOrigin::Core)) + }) + .map(Crate::from); + result + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -470,6 +485,17 @@ impl ModuleDef { } } +impl HasCrate for ModuleDef { + fn krate(&self, db: &dyn HirDatabase) -> Crate { + match self.module(db) { + Some(module) => module.krate(), + None => Crate::core(db).unwrap_or_else(|| { + (*db.crate_graph().crates_in_topological_order().last().unwrap()).into() + }), + } + } +} + impl HasVisibility for ModuleDef { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { match *self { @@ -1865,7 +1891,7 @@ impl DefWithBody { pub fn debug_mir(self, db: &dyn HirDatabase) -> String { let body = db.mir_body(self.id()); match body { - Ok(body) => body.pretty_print(db), + Ok(body) => body.pretty_print(db, self.module(db).krate().to_display_target(db)), Err(e) => format!("error:\n{e:?}"), } } @@ -2451,8 +2477,6 @@ impl Function { db: &dyn HirDatabase, span_formatter: impl Fn(FileId, TextRange) -> String, ) -> Result { - let krate = HasModule::krate(&self.id, db.upcast()); - let edition = db.crate_graph()[krate].edition; let body = db.monomorphized_mir_body( self.id.into(), Substitution::empty(Interner), @@ -2463,7 +2487,12 @@ impl Function { Ok(_) => "pass".to_owned(), Err(e) => { let mut r = String::new(); - _ = e.pretty_print(&mut r, db, &span_formatter, edition); + _ = e.pretty_print( + &mut r, + db, + &span_formatter, + self.krate(db).to_display_target(db), + ); r } }; @@ -2727,8 +2756,8 @@ pub struct EvaluatedConst { } impl EvaluatedConst { - pub fn render(&self, db: &dyn HirDatabase, edition: Edition) -> String { - format!("{}", self.const_.display(db, edition)) + pub fn render(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String { + format!("{}", self.const_.display(db, display_target)) } pub fn render_debug(&self, db: &dyn HirDatabase) -> Result { @@ -4197,9 +4226,13 @@ impl ConstParam { Type::new(db, self.id.parent(), db.const_param_ty(self.id)) } - pub fn default(self, db: &dyn HirDatabase, edition: Edition) -> Option { + pub fn default( + self, + db: &dyn HirDatabase, + display_target: DisplayTarget, + ) -> Option { let arg = generic_arg_from_param(db, self.id.into())?; - known_const_to_ast(arg.constant(Interner)?, db, edition) + known_const_to_ast(arg.constant(Interner)?, db, display_target) } } @@ -4507,18 +4540,18 @@ impl Closure { TyKind::Closure(self.id, self.subst).intern(Interner) } - pub fn display_with_id(&self, db: &dyn HirDatabase, edition: Edition) -> String { + pub fn display_with_id(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String { self.clone() .as_ty() - .display(db, edition) + .display(db, display_target) .with_closure_style(ClosureStyle::ClosureWithId) .to_string() } - pub fn display_with_impl(&self, db: &dyn HirDatabase, edition: Edition) -> String { + pub fn display_with_impl(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String { self.clone() .as_ty() - .display(db, edition) + .display(db, display_target) .with_closure_style(ClosureStyle::ImplFn) .to_string() } @@ -5323,7 +5356,7 @@ impl Type { pub fn type_and_const_arguments<'a>( &'a self, db: &'a dyn HirDatabase, - edition: Edition, + display_target: DisplayTarget, ) -> impl Iterator + 'a { self.ty .strip_references() @@ -5333,10 +5366,10 @@ impl Type { .filter_map(move |arg| { // arg can be either a `Ty` or `constant` if let Some(ty) = arg.ty(Interner) { - Some(format_smolstr!("{}", ty.display(db, edition))) + Some(format_smolstr!("{}", ty.display(db, display_target))) } else { arg.constant(Interner) - .map(|const_| format_smolstr!("{}", const_.display(db, edition))) + .map(|const_| format_smolstr!("{}", const_.display(db, display_target))) } }) } @@ -5345,7 +5378,7 @@ impl Type { pub fn generic_parameters<'a>( &'a self, db: &'a dyn HirDatabase, - edition: Edition, + display_target: DisplayTarget, ) -> impl Iterator + 'a { // iterate the lifetime self.as_adt() @@ -5355,7 +5388,7 @@ impl Type { }) .into_iter() // add the type and const parameters - .chain(self.type_and_const_arguments(db, edition)) + .chain(self.type_and_const_arguments(db, display_target)) } pub fn iterate_method_candidates_with_traits( diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 1b8531209c1b..034e727d31bc 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -313,6 +313,14 @@ impl<'db> SemanticsImpl<'db> { tree } + /// If not crate is found for the file, returns the last crate in topological order. + pub fn first_crate_or_default(&self, file: FileId) -> Crate { + match self.file_to_module_defs(file).next() { + Some(module) => module.krate(), + None => (*self.db.crate_graph().crates_in_topological_order().last().unwrap()).into(), + } + } + pub fn attach_first_edition(&self, file: FileId) -> Option { Some(EditionedFileId::new( file, diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 2ebd88edae2d..81eb6a70ad73 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -13,11 +13,10 @@ use hir_def::{ use hir_expand::{name::Name, HirFileId}; use hir_ty::{ db::HirDatabase, - display::{hir_display_with_types_map, HirDisplay}, + display::{hir_display_with_types_map, DisplayTarget, HirDisplay}, }; use intern::Symbol; use rustc_hash::FxHashMap; -use span::Edition; use syntax::{ast::HasName, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, ToSmolStr}; use crate::{Module, ModuleDef, Semantics}; @@ -66,7 +65,7 @@ pub struct SymbolCollector<'a> { symbols: FxIndexSet, work: Vec, current_container_name: Option, - edition: Edition, + display_target: DisplayTarget, } /// Given a [`ModuleId`] and a [`HirDatabase`], use the DefMap for the module's crate to collect @@ -78,7 +77,10 @@ impl<'a> SymbolCollector<'a> { symbols: Default::default(), work: Default::default(), current_container_name: None, - edition: Edition::Edition2015, + display_target: DisplayTarget::from_crate( + db, + *db.crate_graph().crates_in_topological_order().last().unwrap(), + ), } } @@ -91,7 +93,7 @@ impl<'a> SymbolCollector<'a> { pub fn collect(&mut self, module: Module) { let _p = tracing::info_span!("SymbolCollector::collect", ?module).entered(); tracing::info!(?module, "SymbolCollector::collect",); - self.edition = module.krate().edition(self.db); + self.display_target = module.krate().to_display_target(self.db); // The initial work is the root module we're collecting, additional work will // be populated as we traverse the module's definitions. @@ -307,7 +309,7 @@ impl<'a> SymbolCollector<'a> { let impl_data = self.db.impl_data(impl_id); let impl_name = Some( hir_display_with_types_map(impl_data.self_ty, &impl_data.types_map) - .display(self.db, self.edition) + .display(self.db, self.display_target) .to_smolstr(), ); self.with_container_name(impl_name, |s| { diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs index d2070f0e18b4..0d672dc332f3 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs @@ -4,7 +4,7 @@ use hir_def::ImportPathConfig; use hir_expand::mod_path::ModPath; use hir_ty::{ db::HirDatabase, - display::{DisplaySourceCodeError, HirDisplay}, + display::{DisplaySourceCodeError, DisplayTarget, HirDisplay}, }; use itertools::Itertools; use span::Edition; @@ -99,14 +99,16 @@ impl Expr { sema_scope: &SemanticsScope<'_>, many_formatter: &mut dyn FnMut(&Type) -> String, cfg: ImportPathConfig, - edition: Edition, + display_target: DisplayTarget, ) -> Result { let db = sema_scope.db; + let edition = display_target.edition; let mod_item_path_str = |s, def| mod_item_path_str(s, def, cfg, edition); match self { Expr::Const(it) => match it.as_assoc_item(db).map(|it| it.container(db)) { Some(container) => { - let container_name = container_name(container, sema_scope, cfg, edition)?; + let container_name = + container_name(container, sema_scope, cfg, edition, display_target)?; let const_name = it .name(db) .map(|c| c.display(db.upcast(), edition).to_string()) @@ -122,14 +124,15 @@ impl Expr { Expr::Function { func, params, .. } => { let args = params .iter() - .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg, edition)) + .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg, display_target)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); match func.as_assoc_item(db).map(|it| it.container(db)) { Some(container) => { - let container_name = container_name(container, sema_scope, cfg, edition)?; + let container_name = + container_name(container, sema_scope, cfg, edition, display_target)?; let fn_name = func.name(db).display(db.upcast(), edition).to_string(); Ok(format!("{container_name}::{fn_name}({args})")) } @@ -147,10 +150,10 @@ impl Expr { let func_name = func.name(db).display(db.upcast(), edition).to_string(); let self_param = func.self_param(db).unwrap(); let target_str = - target.gen_source_code(sema_scope, many_formatter, cfg, edition)?; + target.gen_source_code(sema_scope, many_formatter, cfg, display_target)?; let args = params .iter() - .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg, edition)) + .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg, display_target)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -180,7 +183,9 @@ impl Expr { StructKind::Tuple => { let args = params .iter() - .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg, edition)) + .map(|f| { + f.gen_source_code(sema_scope, many_formatter, cfg, display_target) + }) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -195,7 +200,12 @@ impl Expr { let tmp = format!( "{}: {}", f.name(db).display(db.upcast(), edition), - a.gen_source_code(sema_scope, many_formatter, cfg, edition)? + a.gen_source_code( + sema_scope, + many_formatter, + cfg, + display_target + )? ); Ok(tmp) }) @@ -215,7 +225,9 @@ impl Expr { StructKind::Tuple => { let args = params .iter() - .map(|a| a.gen_source_code(sema_scope, many_formatter, cfg, edition)) + .map(|a| { + a.gen_source_code(sema_scope, many_formatter, cfg, display_target) + }) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -230,7 +242,12 @@ impl Expr { let tmp = format!( "{}: {}", f.name(db).display(db.upcast(), edition), - a.gen_source_code(sema_scope, many_formatter, cfg, edition)? + a.gen_source_code( + sema_scope, + many_formatter, + cfg, + display_target + )? ); Ok(tmp) }) @@ -248,7 +265,7 @@ impl Expr { Expr::Tuple { params, .. } => { let args = params .iter() - .map(|a| a.gen_source_code(sema_scope, many_formatter, cfg, edition)) + .map(|a| a.gen_source_code(sema_scope, many_formatter, cfg, display_target)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -260,7 +277,8 @@ impl Expr { return Ok(many_formatter(&expr.ty(db))); } - let strukt = expr.gen_source_code(sema_scope, many_formatter, cfg, edition)?; + let strukt = + expr.gen_source_code(sema_scope, many_formatter, cfg, display_target)?; let field = field.name(db).display(db.upcast(), edition).to_string(); Ok(format!("{strukt}.{field}")) } @@ -269,7 +287,8 @@ impl Expr { return Ok(many_formatter(&expr.ty(db))); } - let inner = expr.gen_source_code(sema_scope, many_formatter, cfg, edition)?; + let inner = + expr.gen_source_code(sema_scope, many_formatter, cfg, display_target)?; Ok(format!("&{inner}")) } Expr::Many(ty) => Ok(many_formatter(ty)), @@ -358,6 +377,7 @@ fn container_name( sema_scope: &SemanticsScope<'_>, cfg: ImportPathConfig, edition: Edition, + display_target: DisplayTarget, ) -> Result { let container_name = match container { crate::AssocItemContainer::Trait(trait_) => { @@ -368,7 +388,7 @@ fn container_name( // Should it be guaranteed that `mod_item_path` always exists? match self_ty.as_adt().and_then(|adt| mod_item_path(sema_scope, &adt.into(), cfg)) { Some(path) => path.display(sema_scope.db.upcast(), edition).to_string(), - None => self_ty.display(sema_scope.db, edition).to_string(), + None => self_ty.display(sema_scope.db, display_target).to_string(), } } }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index 91e248a1de51..7af2a2e1e6a3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -724,9 +724,9 @@ fn fn_generic_params( filter_unnecessary_bounds(&mut generic_params, &mut where_preds, necessary_params); filter_bounds_in_scope(&mut generic_params, &mut where_preds, ctx, target); - let generic_params: Vec<_> = + let generic_params: Vec = generic_params.into_iter().map(|it| it.node.clone_for_update()).collect(); - let where_preds: Vec<_> = + let where_preds: Vec = where_preds.into_iter().map(|it| it.node.clone_for_update()).collect(); // 4. Rewrite paths @@ -1116,9 +1116,12 @@ fn fn_arg_type( if ty.is_reference() || ty.is_mutable_reference() { let famous_defs = &FamousDefs(&ctx.sema, ctx.sema.scope(fn_arg.syntax())?.krate()); - let target_edition = target_module.krate().edition(ctx.db()); convert_reference_type(ty.strip_references(), ctx.db(), famous_defs) - .map(|conversion| conversion.convert_type(ctx.db(), target_edition).to_string()) + .map(|conversion| { + conversion + .convert_type(ctx.db(), target_module.krate().to_display_target(ctx.db())) + .to_string() + }) .or_else(|| ty.display_source_code(ctx.db(), target_module.into(), true).ok()) } else { ty.display_source_code(ctx.db(), target_module.into(), true).ok() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs index ac58af625252..1b16ba5fc8ff 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs @@ -233,7 +233,7 @@ fn generate_getter_from_info( .map(|conversion| { cov_mark::hit!(convert_reference_type); ( - conversion.convert_type(ctx.db(), krate.edition(ctx.db())), + conversion.convert_type(ctx.db(), krate.to_display_target(ctx.db())), conversion.getter(record_field_info.field_name.to_string()), ) }) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs index 139078eee7c4..ca5882d0313a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs @@ -42,7 +42,7 @@ pub(crate) fn inline_const_as_literal(acc: &mut Assists, ctx: &AssistContext<'_> let value = konst .eval(ctx.sema.db) .ok()? - .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)); + .render(ctx.sema.db, konst.krate(ctx.sema.db).to_display_target(ctx.sema.db)); let id = AssistId("inline_const_as_literal", AssistKind::RefactorInline); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs index 66671c934c4b..e10897b3bef7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs @@ -52,8 +52,13 @@ pub(crate) fn term_search(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< let paths = paths .into_iter() .filter_map(|path| { - path.gen_source_code(&scope, &mut formatter, ctx.config.import_path_config(), edition) - .ok() + path.gen_source_code( + &scope, + &mut formatter, + ctx.config.import_path_config(), + scope.krate().to_display_target(ctx.db()), + ) + .ok() }) .unique(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 39686f065a9c..a6fa1706710d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -3,7 +3,8 @@ pub(crate) use gen_trait_fn_body::gen_trait_fn_body; use hir::{ db::{ExpandDatabase, HirDatabase}, - HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution, Semantics, + DisplayTarget, HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution, + Semantics, }; use ide_db::{ famous_defs::FamousDefs, @@ -21,7 +22,7 @@ use syntax::{ syntax_factory::SyntaxFactory, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, }, - ted, AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile, + ted, AstNode, AstToken, Direction, NodeOrToken, SourceFile, SyntaxKind::*, SyntaxNode, SyntaxToken, TextRange, TextSize, WalkEvent, T, }; @@ -793,31 +794,50 @@ enum ReferenceConversionType { } impl ReferenceConversion { - pub(crate) fn convert_type(&self, db: &dyn HirDatabase, edition: Edition) -> ast::Type { + pub(crate) fn convert_type( + &self, + db: &dyn HirDatabase, + display_target: DisplayTarget, + ) -> ast::Type { let ty = match self.conversion { - ReferenceConversionType::Copy => self.ty.display(db, edition).to_string(), + ReferenceConversionType::Copy => self.ty.display(db, display_target).to_string(), ReferenceConversionType::AsRefStr => "&str".to_owned(), ReferenceConversionType::AsRefSlice => { - let type_argument_name = - self.ty.type_arguments().next().unwrap().display(db, edition).to_string(); + let type_argument_name = self + .ty + .type_arguments() + .next() + .unwrap() + .display(db, display_target) + .to_string(); format!("&[{type_argument_name}]") } ReferenceConversionType::Dereferenced => { - let type_argument_name = - self.ty.type_arguments().next().unwrap().display(db, edition).to_string(); + let type_argument_name = self + .ty + .type_arguments() + .next() + .unwrap() + .display(db, display_target) + .to_string(); format!("&{type_argument_name}") } ReferenceConversionType::Option => { - let type_argument_name = - self.ty.type_arguments().next().unwrap().display(db, edition).to_string(); + let type_argument_name = self + .ty + .type_arguments() + .next() + .unwrap() + .display(db, display_target) + .to_string(); format!("Option<&{type_argument_name}>") } ReferenceConversionType::Result => { let mut type_arguments = self.ty.type_arguments(); let first_type_argument_name = - type_arguments.next().unwrap().display(db, edition).to_string(); + type_arguments.next().unwrap().display(db, display_target).to_string(); let second_type_argument_name = - type_arguments.next().unwrap().display(db, edition).to_string(); + type_arguments.next().unwrap().display(db, display_target).to_string(); format!("Result<&{first_type_argument_name}, &{second_type_argument_name}>") } }; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index 919b30f7f971..e686a2930946 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -7,8 +7,8 @@ mod tests; use std::{iter, ops::ControlFlow}; use hir::{ - HasAttrs, Local, ModPath, ModuleDef, ModuleSource, Name, PathResolution, ScopeDef, Semantics, - SemanticsScope, Symbol, Type, TypeInfo, + DisplayTarget, HasAttrs, Local, ModPath, ModuleDef, ModuleSource, Name, PathResolution, + ScopeDef, Semantics, SemanticsScope, Symbol, Type, TypeInfo, }; use ide_db::{ base_db::SourceDatabase, famous_defs::FamousDefs, helpers::is_editable_crate, FilePosition, @@ -440,6 +440,7 @@ pub(crate) struct CompletionContext<'a> { pub(crate) token: SyntaxToken, /// The crate of the current file. pub(crate) krate: hir::Crate, + pub(crate) display_target: DisplayTarget, /// The module of the `scope`. pub(crate) module: hir::Module, /// The function where we're completing, if inside a function. @@ -867,6 +868,7 @@ impl<'a> CompletionContext<'a> { CompleteSemicolon::DoNotComplete }; + let display_target = krate.to_display_target(db); let ctx = CompletionContext { sema, scope, @@ -888,6 +890,7 @@ impl<'a> CompletionContext<'a> { exclude_flyimport, exclude_traits, complete_semicolon, + display_target, }; Some((ctx, analysis)) } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs index fc2bfc01e62a..a03f632cdfdf 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs @@ -13,7 +13,7 @@ fn check_expected_type_and_name(#[rust_analyzer::rust_fixture] ra_fixture: &str, let ty = completion_context .expected_type - .map(|t| t.display_test(&db).to_string()) + .map(|t| t.display_test(&db, completion_context.krate.to_display_target(&db)).to_string()) .unwrap_or("?".to_owned()); let name = diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 4f6c4cb66393..b32a589a1b26 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -144,7 +144,7 @@ pub(crate) fn render_field( is_skipping_completion: receiver.is_some(), ..CompletionRelevance::default() }); - item.detail(ty.display(db, ctx.completion.edition).to_string()) + item.detail(ty.display(db, ctx.completion.display_target).to_string()) .set_documentation(field.docs(db)) .set_deprecated(is_deprecated) .lookup_by(name); @@ -212,7 +212,7 @@ pub(crate) fn render_tuple_field( field_with_receiver(receiver.as_deref(), &field.to_string()), ctx.completion.edition, ); - item.detail(ty.display(ctx.db(), ctx.completion.edition).to_string()) + item.detail(ty.display(ctx.db(), ctx.completion.display_target).to_string()) .lookup_by(field.to_string()); item.set_relevance(CompletionRelevance { is_skipping_completion: receiver.is_some(), @@ -303,7 +303,8 @@ pub(crate) fn render_expr( let cfg = ctx.config.import_path_config(ctx.is_nightly); - let label = expr.gen_source_code(&ctx.scope, &mut label_formatter, cfg, ctx.edition).ok()?; + let label = + expr.gen_source_code(&ctx.scope, &mut label_formatter, cfg, ctx.display_target).ok()?; let source_range = match ctx.original_token.parent() { Some(node) => match node.ancestors().find_map(ast::Path::cast) { @@ -318,7 +319,7 @@ pub(crate) fn render_expr( let snippet = format!( "{}$0", - expr.gen_source_code(&ctx.scope, &mut snippet_formatter, cfg, ctx.edition).ok()? + expr.gen_source_code(&ctx.scope, &mut snippet_formatter, cfg, ctx.display_target).ok()? ); let edit = TextEdit::replace(source_range, snippet); item.snippet_edit(ctx.config.snippet_cap?, edit); @@ -398,6 +399,8 @@ fn render_resolution_path( let _p = tracing::info_span!("render_resolution_path").entered(); use hir::ModuleDef::*; + let krate = ctx.completion.display_target; + match resolution { ScopeDef::ModuleDef(Macro(mac)) => { let ctx = ctx.import_to_add(import_to_add); @@ -459,7 +462,7 @@ fn render_resolution_path( let mut set_item_relevance = |ty: Type| { if !ty.is_unknown() { - item.detail(ty.display(db, completion.edition).to_string()); + item.detail(ty.display(db, krate).to_string()); } item.set_relevance(CompletionRelevance { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs index e357ab24d22d..f11b3023679a 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs @@ -16,7 +16,7 @@ fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option let name = const_.name(db)?; let (name, escaped_name) = (name.as_str().to_smolstr(), name.display(db, ctx.completion.edition).to_smolstr()); - let detail = const_.display(db, ctx.completion.edition).to_string(); + let detail = const_.display(db, ctx.completion.display_target).to_string(); let mut item = CompletionItem::new(SymbolKind::Const, ctx.source_range(), name, ctx.completion.edition); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs index fd90613964af..4693bdc047f9 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs @@ -4,7 +4,7 @@ use hir::{db::HirDatabase, AsAssocItem, HirDisplay}; use ide_db::{SnippetCap, SymbolKind}; use itertools::Itertools; use stdx::{format_to, to_lower_snake_case}; -use syntax::{format_smolstr, AstNode, Edition, SmolStr, ToSmolStr}; +use syntax::{format_smolstr, AstNode, SmolStr, ToSmolStr}; use crate::{ context::{ @@ -142,9 +142,9 @@ fn render( } let detail = if ctx.completion.config.full_function_signatures { - detail_full(db, func, ctx.completion.edition) + detail_full(ctx.completion, func) } else { - detail(ctx.completion, func, ctx.completion.edition) + detail(ctx.completion, func) }; item.set_documentation(ctx.docs(func)) .set_deprecated(ctx.is_deprecated(func) || ctx.is_deprecated_assoc_item(func)) @@ -251,7 +251,7 @@ pub(super) fn add_call_parens<'b>( format!( "{}(${{1:{}}}{}{})$0", escaped_name, - self_param.display(ctx.db, ctx.edition), + self_param.display(ctx.db, ctx.display_target), if params.is_empty() { "" } else { ", " }, function_params_snippet ) @@ -307,7 +307,7 @@ fn ref_of_param(ctx: &CompletionContext<'_>, arg: &str, ty: &hir::Type) -> &'sta "" } -fn detail(ctx: &CompletionContext<'_>, func: hir::Function, edition: Edition) -> String { +fn detail(ctx: &CompletionContext<'_>, func: hir::Function) -> String { let mut ret_ty = func.ret_type(ctx.db); let mut detail = String::new(); @@ -324,15 +324,15 @@ fn detail(ctx: &CompletionContext<'_>, func: hir::Function, edition: Edition) -> format_to!(detail, "unsafe "); } - format_to!(detail, "fn({})", params_display(ctx.db, func, edition)); + format_to!(detail, "fn({})", params_display(ctx, func)); if !ret_ty.is_unit() { - format_to!(detail, " -> {}", ret_ty.display(ctx.db, edition)); + format_to!(detail, " -> {}", ret_ty.display(ctx.db, ctx.display_target)); } detail } -fn detail_full(db: &dyn HirDatabase, func: hir::Function, edition: Edition) -> String { - let signature = format!("{}", func.display(db, edition)); +fn detail_full(ctx: &CompletionContext<'_>, func: hir::Function) -> String { + let signature = format!("{}", func.display(ctx.db, ctx.display_target)); let mut detail = String::with_capacity(signature.len()); for segment in signature.split_whitespace() { @@ -346,24 +346,24 @@ fn detail_full(db: &dyn HirDatabase, func: hir::Function, edition: Edition) -> S detail } -fn params_display(db: &dyn HirDatabase, func: hir::Function, edition: Edition) -> String { - if let Some(self_param) = func.self_param(db) { - let assoc_fn_params = func.assoc_fn_params(db); +fn params_display(ctx: &CompletionContext<'_>, func: hir::Function) -> String { + if let Some(self_param) = func.self_param(ctx.db) { + let assoc_fn_params = func.assoc_fn_params(ctx.db); let params = assoc_fn_params .iter() .skip(1) // skip the self param because we are manually handling that - .map(|p| p.ty().display(db, edition)); + .map(|p| p.ty().display(ctx.db, ctx.display_target)); format!( "{}{}", - self_param.display(db, edition), + self_param.display(ctx.db, ctx.display_target), params.format_with("", |display, f| { f(&", ")?; f(&display) }) ) } else { - let assoc_fn_params = func.assoc_fn_params(db); - assoc_fn_params.iter().map(|p| p.ty().display(db, edition)).join(", ") + let assoc_fn_params = func.assoc_fn_params(ctx.db); + assoc_fn_params.iter().map(|p| p.ty().display(ctx.db, ctx.display_target)).join(", ") } } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs index aab54ca5e014..3429ae1f46d4 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs @@ -82,10 +82,10 @@ fn render( let mut rendered = match kind { StructKind::Tuple if should_add_parens => { - render_tuple_lit(db, snippet_cap, &fields, &escaped_qualified_name, completion.edition) + render_tuple_lit(completion, snippet_cap, &fields, &escaped_qualified_name) } StructKind::Record if should_add_parens => { - render_record_lit(db, snippet_cap, &fields, &escaped_qualified_name, completion.edition) + render_record_lit(completion, snippet_cap, &fields, &escaped_qualified_name) } _ => RenderedLiteral { literal: escaped_qualified_name.clone(), diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs index e265e92f9794..8b2476d153f1 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs @@ -62,7 +62,7 @@ fn render( completion.edition, ); item.set_deprecated(ctx.is_deprecated(macro_)) - .detail(macro_.display(completion.db, completion.edition).to_string()) + .detail(macro_.display(completion.db, completion.display_target).to_string()) .set_documentation(docs) .set_relevance(ctx.completion_relevance()); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs index 1b952f31360c..d57feee4fa65 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs @@ -38,7 +38,7 @@ fn render( } else { (name.as_str().to_smolstr(), name.display_no_db(ctx.completion.edition).to_smolstr()) }; - let detail = type_alias.display(db, ctx.completion.edition).to_string(); + let detail = type_alias.display(db, ctx.completion.display_target).to_string(); let mut item = CompletionItem::new( SymbolKind::TypeAlias, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs index 742036265211..09154e81c030 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs @@ -88,7 +88,7 @@ pub(crate) fn render_union_literal( f(&format_args!( "{}: {}", field.name(ctx.db()).display(ctx.db(), ctx.completion.edition), - field.ty(ctx.db()).display(ctx.db(), ctx.completion.edition) + field.ty(ctx.db()).display(ctx.db(), ctx.completion.display_target) )) }), if fields_omitted { ", .." } else { "" } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs index d8516ea10786..83718e57229a 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs @@ -1,10 +1,10 @@ //! Code common to structs, unions, and enum variants. use crate::context::CompletionContext; -use hir::{db::HirDatabase, sym, HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind}; +use hir::{sym, HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind}; use ide_db::SnippetCap; use itertools::Itertools; -use syntax::{Edition, SmolStr}; +use syntax::SmolStr; /// A rendered struct, union, or enum variant, split into fields for actual /// auto-completion (`literal`, using `field: ()`) and display in the @@ -17,11 +17,10 @@ pub(crate) struct RenderedLiteral { /// Render a record type (or sub-type) to a `RenderedCompound`. Use `None` for /// the `name` argument for an anonymous type. pub(crate) fn render_record_lit( - db: &dyn HirDatabase, + ctx: &CompletionContext<'_>, snippet_cap: Option, fields: &[hir::Field], path: &str, - edition: Edition, ) -> RenderedLiteral { if snippet_cap.is_none() { return RenderedLiteral { literal: path.to_owned(), detail: path.to_owned() }; @@ -30,19 +29,19 @@ pub(crate) fn render_record_lit( if snippet_cap.is_some() { f(&format_args!( "{}: ${{{}:()}}", - field.name(db).display(db.upcast(), edition), + field.name(ctx.db).display(ctx.db, ctx.edition), idx + 1 )) } else { - f(&format_args!("{}: ()", field.name(db).display(db.upcast(), edition))) + f(&format_args!("{}: ()", field.name(ctx.db).display(ctx.db, ctx.edition))) } }); let types = fields.iter().format_with(", ", |field, f| { f(&format_args!( "{}: {}", - field.name(db).display(db.upcast(), edition), - field.ty(db).display(db, edition) + field.name(ctx.db).display(ctx.db, ctx.edition), + field.ty(ctx.db).display(ctx.db, ctx.display_target) )) }); @@ -55,11 +54,10 @@ pub(crate) fn render_record_lit( /// Render a tuple type (or sub-type) to a `RenderedCompound`. Use `None` for /// the `name` argument for an anonymous type. pub(crate) fn render_tuple_lit( - db: &dyn HirDatabase, + ctx: &CompletionContext<'_>, snippet_cap: Option, fields: &[hir::Field], path: &str, - edition: Edition, ) -> RenderedLiteral { if snippet_cap.is_none() { return RenderedLiteral { literal: path.to_owned(), detail: path.to_owned() }; @@ -72,7 +70,9 @@ pub(crate) fn render_tuple_lit( } }); - let types = fields.iter().format_with(", ", |field, f| f(&field.ty(db).display(db, edition))); + let types = fields + .iter() + .format_with(", ", |field, f| f(&field.ty(ctx.db).display(ctx.db, ctx.display_target))); RenderedLiteral { literal: format!("{path}({completions})"), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs index 6f71c3d9bd7e..502314ed1e0e 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs @@ -12,11 +12,11 @@ use arrayvec::ArrayVec; use either::Either; use hir::{ Adt, AsAssocItem, AsExternAssocItem, AssocItem, AttributeTemplate, BuiltinAttr, BuiltinType, - Const, Crate, DefWithBody, DeriveHelper, DocLinkDef, ExternAssocItem, ExternCrateDecl, Field, - Function, GenericDef, GenericParam, GenericSubstitution, HasContainer, HasVisibility, - HirDisplay, Impl, InlineAsmOperand, ItemContainer, Label, Local, Macro, Module, ModuleDef, - Name, PathResolution, Semantics, Static, StaticLifetime, Struct, ToolModule, Trait, TraitAlias, - TupleField, TypeAlias, Variant, VariantDef, Visibility, + Const, Crate, DefWithBody, DeriveHelper, DisplayTarget, DocLinkDef, ExternAssocItem, + ExternCrateDecl, Field, Function, GenericDef, GenericParam, GenericSubstitution, HasContainer, + HasVisibility, HirDisplay, Impl, InlineAsmOperand, ItemContainer, Label, Local, Macro, Module, + ModuleDef, Name, PathResolution, Semantics, Static, StaticLifetime, Struct, ToolModule, Trait, + TraitAlias, TupleField, TypeAlias, Variant, VariantDef, Visibility, }; use span::Edition; use stdx::{format_to, impl_from}; @@ -207,7 +207,7 @@ impl Definition { &self, db: &RootDatabase, famous_defs: Option<&FamousDefs<'_, '_>>, - edition: Edition, + display_target: DisplayTarget, ) -> Option { let docs = match self { Definition::Macro(it) => it.docs(db), @@ -228,7 +228,7 @@ impl Definition { let docs = adt.docs(db)?; let docs = format!( "*This is the documentation for* `{}`\n\n{}", - adt.display(db, edition), + adt.display(db, display_target), docs.as_str() ); Some(Documentation::new(docs)) @@ -237,8 +237,9 @@ impl Definition { Definition::BuiltinType(it) => { famous_defs.and_then(|fd| { // std exposes prim_{} modules with docstrings on the root to document the builtins - let primitive_mod = format!("prim_{}", it.name().display(fd.0.db, edition)); - let doc_owner = find_std_module(fd, &primitive_mod, edition)?; + let primitive_mod = + format!("prim_{}", it.name().display(fd.0.db, display_target.edition)); + let doc_owner = find_std_module(fd, &primitive_mod, display_target.edition)?; doc_owner.docs(fd.0.db) }) } @@ -256,16 +257,21 @@ impl Definition { let AttributeTemplate { word, list, name_value_str } = it.template(db)?; let mut docs = "Valid forms are:".to_owned(); if word { - format_to!(docs, "\n - #\\[{}]", name.display(db, edition)); + format_to!(docs, "\n - #\\[{}]", name.display(db, display_target.edition)); } if let Some(list) = list { - format_to!(docs, "\n - #\\[{}({})]", name.display(db, edition), list); + format_to!( + docs, + "\n - #\\[{}({})]", + name.display(db, display_target.edition), + list + ); } if let Some(name_value_str) = name_value_str { format_to!( docs, "\n - #\\[{} = {}]", - name.display(db, edition), + name.display(db, display_target.edition), name_value_str ); } @@ -288,49 +294,60 @@ impl Definition { }) } - pub fn label(&self, db: &RootDatabase, edition: Edition) -> String { + pub fn label(&self, db: &RootDatabase, display_target: DisplayTarget) -> String { match *self { - Definition::Macro(it) => it.display(db, edition).to_string(), - Definition::Field(it) => it.display(db, edition).to_string(), - Definition::TupleField(it) => it.display(db, edition).to_string(), - Definition::Module(it) => it.display(db, edition).to_string(), - Definition::Crate(it) => it.display(db, edition).to_string(), - Definition::Function(it) => it.display(db, edition).to_string(), - Definition::Adt(it) => it.display(db, edition).to_string(), - Definition::Variant(it) => it.display(db, edition).to_string(), - Definition::Const(it) => it.display(db, edition).to_string(), - Definition::Static(it) => it.display(db, edition).to_string(), - Definition::Trait(it) => it.display(db, edition).to_string(), - Definition::TraitAlias(it) => it.display(db, edition).to_string(), - Definition::TypeAlias(it) => it.display(db, edition).to_string(), - Definition::BuiltinType(it) => it.name().display(db, edition).to_string(), - Definition::BuiltinLifetime(it) => it.name().display(db, edition).to_string(), + Definition::Macro(it) => it.display(db, display_target).to_string(), + Definition::Field(it) => it.display(db, display_target).to_string(), + Definition::TupleField(it) => it.display(db, display_target).to_string(), + Definition::Module(it) => it.display(db, display_target).to_string(), + Definition::Crate(it) => it.display(db, display_target).to_string(), + Definition::Function(it) => it.display(db, display_target).to_string(), + Definition::Adt(it) => it.display(db, display_target).to_string(), + Definition::Variant(it) => it.display(db, display_target).to_string(), + Definition::Const(it) => it.display(db, display_target).to_string(), + Definition::Static(it) => it.display(db, display_target).to_string(), + Definition::Trait(it) => it.display(db, display_target).to_string(), + Definition::TraitAlias(it) => it.display(db, display_target).to_string(), + Definition::TypeAlias(it) => it.display(db, display_target).to_string(), + Definition::BuiltinType(it) => { + it.name().display(db, display_target.edition).to_string() + } + Definition::BuiltinLifetime(it) => { + it.name().display(db, display_target.edition).to_string() + } Definition::Local(it) => { let ty = it.ty(db); - let ty_display = ty.display_truncated(db, None, edition); + let ty_display = ty.display_truncated(db, None, display_target); let is_mut = if it.is_mut(db) { "mut " } else { "" }; if it.is_self(db) { format!("{is_mut}self: {ty_display}") } else { let name = it.name(db); let let_kw = if it.is_param(db) { "" } else { "let " }; - format!("{let_kw}{is_mut}{}: {ty_display}", name.display(db, edition)) + format!( + "{let_kw}{is_mut}{}: {ty_display}", + name.display(db, display_target.edition) + ) } } Definition::SelfType(impl_def) => { let self_ty = &impl_def.self_ty(db); match self_ty.as_adt() { - Some(it) => it.display(db, edition).to_string(), - None => self_ty.display(db, edition).to_string(), + Some(it) => it.display(db, display_target).to_string(), + None => self_ty.display(db, display_target).to_string(), } } - Definition::GenericParam(it) => it.display(db, edition).to_string(), - Definition::Label(it) => it.name(db).display(db, edition).to_string(), - Definition::ExternCrateDecl(it) => it.display(db, edition).to_string(), - Definition::BuiltinAttr(it) => format!("#[{}]", it.name(db).display(db, edition)), - Definition::ToolModule(it) => it.name(db).display(db, edition).to_string(), + Definition::GenericParam(it) => it.display(db, display_target).to_string(), + Definition::Label(it) => it.name(db).display(db, display_target.edition).to_string(), + Definition::ExternCrateDecl(it) => it.display(db, display_target).to_string(), + Definition::BuiltinAttr(it) => { + format!("#[{}]", it.name(db).display(db, display_target.edition)) + } + Definition::ToolModule(it) => { + it.name(db).display(db, display_target.edition).to_string() + } Definition::DeriveHelper(it) => { - format!("derive_helper {}", it.name(db).display(db, edition)) + format!("derive_helper {}", it.name(db).display(db, display_target.edition)) } // FIXME Definition::InlineAsmRegOrRegClass(_) => "inline_asm_reg_or_reg_class".to_owned(), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index 126b30470b7e..a348a4ef7d3f 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -192,7 +192,9 @@ impl<'a> PathTransform<'a> { } } (Either::Left(k), None) => { - if let Some(default) = k.default(db, target_edition) { + if let Some(default) = + k.default(db, target_module.krate().to_display_target(db)) + { if let Some(default) = default.expr() { const_substs.insert(k, default.syntax().clone_for_update()); defaulted_params.push(Either::Right(k)); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs index e3a1e12e0296..af25c2b2e332 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs @@ -12,7 +12,7 @@ pub(crate) fn expected_function( Diagnostic::new_with_syntax_node_ptr( ctx, DiagnosticCode::RustcHardError("E0618"), - format!("expected function, found {}", d.found.display(ctx.sema.db, ctx.edition)), + format!("expected function, found {}", d.found.display(ctx.sema.db, ctx.display_target)), d.call.map(|it| it.into()), ) .experimental() diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs index 5730508436d2..82cd1f2fde6d 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs @@ -8,7 +8,7 @@ macro_rules! format_ty { $fmt, $( $arg - .display($ctx.sema.db, $ctx.edition) + .display($ctx.sema.db, $ctx.display_target) .with_closure_style(ClosureStyle::ClosureWithId) ),* ) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs index a9ff06fb0ab1..7d0f10983d73 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs @@ -8,7 +8,7 @@ pub(crate) fn moved_out_of_ref(ctx: &DiagnosticsContext<'_>, d: &hir::MovedOutOf Diagnostic::new_with_syntax_node_ptr( ctx, DiagnosticCode::RustcHardError("E0507"), - format!("cannot move `{}` out of reference", d.ty.display(ctx.sema.db, ctx.edition)), + format!("cannot move `{}` out of reference", d.ty.display(ctx.sema.db, ctx.display_target)), d.span, ) .experimental() // spans are broken, and I'm not sure how precise we can detect copy types diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs index 1363a8ff0ddb..3db2e013a397 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs @@ -30,7 +30,7 @@ pub(crate) fn trait_impl_redundant_assoc_item( ( format!("`fn {redundant_assoc_item_name}`"), function.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range), - format!("\n {};", function.display(db, ctx.edition)), + format!("\n {};", function.display(db, ctx.display_target)), ) } hir::AssocItem::Const(id) => { @@ -38,7 +38,7 @@ pub(crate) fn trait_impl_redundant_assoc_item( ( format!("`const {redundant_assoc_item_name}`"), constant.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range), - format!("\n {};", constant.display(db, ctx.edition)), + format!("\n {};", constant.display(db, ctx.display_target)), ) } hir::AssocItem::TypeAlias(id) => { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs index 7cf8282d0529..c726a3bcd3ca 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -45,10 +45,10 @@ pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) format!( "expected {}, found {}", d.expected - .display(ctx.sema.db, ctx.edition) + .display(ctx.sema.db, ctx.display_target) .with_closure_style(ClosureStyle::ClosureWithId), d.actual - .display(ctx.sema.db, ctx.edition) + .display(ctx.sema.db, ctx.display_target) .with_closure_style(ClosureStyle::ClosureWithId), ), display_range, @@ -306,8 +306,8 @@ fn str_ref_to_owned( expr_ptr: &InFile>, acc: &mut Vec, ) -> Option<()> { - let expected = d.expected.display(ctx.sema.db, ctx.edition); - let actual = d.actual.display(ctx.sema.db, ctx.edition); + let expected = d.expected.display(ctx.sema.db, ctx.display_target); + let actual = d.actual.display(ctx.sema.db, ctx.display_target); // FIXME do this properly if expected.to_string() != "String" || actual.to_string() != "&str" { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs index b023a95fb355..c25318eda485 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs @@ -27,7 +27,7 @@ pub(crate) fn typed_hole(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Di format!( "invalid `_` expression, expected type `{}`", d.expected - .display(ctx.sema.db, ctx.edition) + .display(ctx.sema.db, ctx.display_target) .with_closure_style(ClosureStyle::ClosureWithId), ), fixes(ctx, d), @@ -72,7 +72,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option prefer_absolute: ctx.config.prefer_absolute, allow_unstable: ctx.is_nightly, }, - ctx.edition, + ctx.display_target, ) .ok() }) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs index dfb03eee732a..6ab713a5896c 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -38,7 +38,7 @@ pub(crate) fn unresolved_field( format!( "no field `{}` on type `{}`{method_suffix}", d.name.display(ctx.sema.db, ctx.edition), - d.receiver.display(ctx.sema.db, ctx.edition) + d.receiver.display(ctx.sema.db, ctx.display_target) ), adjusted_display_range(ctx, d.expr, &|expr| { Some( diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs index e4de107249bd..35e7521af706 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs @@ -31,7 +31,7 @@ pub(crate) fn unresolved_method( format!( "no method `{}` on type `{}`{suffix}", d.name.display(ctx.sema.db, ctx.edition), - d.receiver.display(ctx.sema.db, ctx.edition) + d.receiver.display(ctx.sema.db, ctx.display_target) ), adjusted_display_range(ctx, d.expr, &|expr| { Some( @@ -152,7 +152,7 @@ fn assoc_func_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall) - receiver_type.as_adt()?.name(db).display_no_db(ctx.edition).to_smolstr(); let generic_parameters: Vec = - receiver_type.generic_parameters(db, ctx.edition).collect(); + receiver_type.generic_parameters(db, ctx.display_target).collect(); // if receiver should be pass as first arg in the assoc func, // we could omit generic parameters cause compiler can deduce it automatically if !need_to_take_receiver_as_first_arg && !generic_parameters.is_empty() { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index 0a55b6e9bee8..e15d34957891 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -81,7 +81,10 @@ mod tests; use std::{collections::hash_map, iter, sync::LazyLock}; use either::Either; -use hir::{db::ExpandDatabase, diagnostics::AnyDiagnostic, Crate, HirFileId, InFile, Semantics}; +use hir::{ + db::ExpandDatabase, diagnostics::AnyDiagnostic, Crate, DisplayTarget, HirFileId, InFile, + Semantics, +}; use ide_db::{ assists::{Assist, AssistId, AssistKind, AssistResolveStrategy}, base_db::{ReleaseChannel, SourceDatabase}, @@ -277,6 +280,7 @@ struct DiagnosticsContext<'a> { sema: Semantics<'a, RootDatabase>, resolve: &'a AssistResolveStrategy, edition: Edition, + display_target: DisplayTarget, is_nightly: bool, } @@ -374,7 +378,18 @@ pub fn semantic_diagnostics( module.and_then(|m| db.toolchain_channel(m.krate().into())), Some(ReleaseChannel::Nightly) | None ); - let ctx = DiagnosticsContext { config, sema, resolve, edition: file_id.edition(), is_nightly }; + let krate = module.map(|module| module.krate()).unwrap_or_else(|| { + (*db.crate_graph().crates_in_topological_order().last().unwrap()).into() + }); + let display_target = krate.to_display_target(db); + let ctx = DiagnosticsContext { + config, + sema, + resolve, + edition: file_id.edition(), + is_nightly, + display_target, + }; let mut diags = Vec::new(); match module { diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs index 4bead14e31d4..e219ba4bf639 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs @@ -7,8 +7,7 @@ use crate::{ SsrMatches, }; use hir::{FileRange, ImportPathConfig, Semantics}; -use ide_db::FxHashMap; -use parser::Edition; +use ide_db::{base_db::SourceDatabase, FxHashMap}; use std::{cell::Cell, iter::Peekable}; use syntax::{ ast::{self, AstNode, AstToken, HasGenericArgs}, @@ -627,22 +626,23 @@ impl<'db, 'sema> Matcher<'db, 'sema> { match_error!("Failed to get receiver type for `{}`", expr.syntax().text()) })? .original; - let edition = self - .sema - .scope(expr.syntax()) - .map(|it| it.krate().edition(self.sema.db)) - .unwrap_or(Edition::CURRENT); - // Temporary needed to make the borrow checker happy. + let krate = self.sema.scope(expr.syntax()).map(|it| it.krate()).unwrap_or_else(|| { + hir::Crate::from( + *self.sema.db.crate_graph().crates_in_topological_order().last().unwrap(), + ) + }); let res = code_type .autoderef(self.sema.db) .enumerate() .find(|(_, deref_code_type)| pattern_type == deref_code_type) .map(|(count, _)| count) .ok_or_else(|| { + let display_target = krate.to_display_target(self.sema.db); + // Temporary needed to make the borrow checker happy. match_error!( "Pattern type `{}` didn't match code type `{}`", - pattern_type.display(self.sema.db, edition), - code_type.display(self.sema.db, edition) + pattern_type.display(self.sema.db, display_target), + code_type.display(self.sema.db, display_target) ) }); res diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index 9a3e77f3a932..b00de6ba4083 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -7,7 +7,8 @@ use std::{iter, ops::Not}; use either::Either; use hir::{ - db::DefDatabase, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics, + db::DefDatabase, DisplayTarget, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, + Semantics, }; use ide_db::{ defs::{Definition, IdentClass, NameRefClass, OperatorClass}, @@ -129,10 +130,18 @@ pub(crate) fn hover( let file = sema.parse_guess_edition(file_id).syntax().clone(); let edition = sema.attach_first_edition(file_id).map(|it| it.edition()).unwrap_or(Edition::CURRENT); + let display_target = sema.first_crate_or_default(file_id).to_display_target(db); let mut res = if range.is_empty() { - hover_offset(sema, FilePosition { file_id, offset: range.start() }, file, config, edition) + hover_offset( + sema, + FilePosition { file_id, offset: range.start() }, + file, + config, + edition, + display_target, + ) } else { - hover_ranged(sema, frange, file, config, edition) + hover_ranged(sema, frange, file, config, edition, display_target) }?; if let HoverDocFormat::PlainText = config.format { @@ -148,6 +157,7 @@ fn hover_offset( file: SyntaxNode, config: &HoverConfig, edition: Edition, + display_target: DisplayTarget, ) -> Option> { let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind { IDENT @@ -169,8 +179,18 @@ fn hover_offset( if let Some(doc_comment) = token_as_doc_comment(&original_token) { cov_mark::hit!(no_highlight_on_comment_hover); return doc_comment.get_definition_with_descend_at(sema, offset, |def, node, range| { - let res = - hover_for_definition(sema, file_id, def, None, &node, None, false, config, edition); + let res = hover_for_definition( + sema, + file_id, + def, + None, + &node, + None, + false, + config, + edition, + display_target, + ); Some(RangeInfo::new(range, res)) }); } @@ -188,6 +208,7 @@ fn hover_offset( false, config, edition, + display_target, ); return Some(RangeInfo::new(range, res)); } @@ -277,6 +298,7 @@ fn hover_offset( hovered_definition, config, edition, + display_target, ) }) .collect::>(), @@ -286,12 +308,12 @@ fn hover_offset( res.extend(definitions); continue; } - let keywords = || render::keyword(sema, config, &token, edition); + let keywords = || render::keyword(sema, config, &token, edition, display_target); let underscore = || { if !is_same_kind { return None; } - render::underscore(sema, config, &token, edition) + render::underscore(sema, config, &token, edition, display_target) }; let rest_pat = || { if !is_same_kind || token.kind() != DOT2 { @@ -305,7 +327,7 @@ fn hover_offset( let record_pat = record_pat_field_list.syntax().parent().and_then(ast::RecordPat::cast)?; - Some(render::struct_rest_pat(sema, config, &record_pat, edition)) + Some(render::struct_rest_pat(sema, config, &record_pat, edition, display_target)) }; let call = || { if !is_same_kind || token.kind() != T!['('] && token.kind() != T![')'] { @@ -319,17 +341,17 @@ fn hover_offset( _ => return None, } }; - render::type_info_of(sema, config, &Either::Left(call_expr), edition) + render::type_info_of(sema, config, &Either::Left(call_expr), edition, display_target) }; let closure = || { if !is_same_kind || token.kind() != T![|] { return None; } let c = token.parent().and_then(|x| x.parent()).and_then(ast::ClosureExpr::cast)?; - render::closure_expr(sema, config, c, edition) + render::closure_expr(sema, config, c, edition, display_target) }; let literal = || { - render::literal(sema, original_token.clone(), edition) + render::literal(sema, original_token.clone(), display_target) .map(|markup| HoverResult { markup, actions: vec![] }) }; if let Some(result) = keywords() @@ -362,6 +384,7 @@ fn hover_ranged( file: SyntaxNode, config: &HoverConfig, edition: Edition, + display_target: DisplayTarget, ) -> Option> { // FIXME: make this work in attributes let expr_or_pat = file @@ -371,16 +394,17 @@ fn hover_ranged( .find_map(Either::::cast)?; let res = match &expr_or_pat { Either::Left(ast::Expr::TryExpr(try_expr)) => { - render::try_expr(sema, config, try_expr, edition) + render::try_expr(sema, config, try_expr, edition, display_target) } Either::Left(ast::Expr::PrefixExpr(prefix_expr)) if prefix_expr.op_kind() == Some(ast::UnaryOp::Deref) => { - render::deref_expr(sema, config, prefix_expr, edition) + render::deref_expr(sema, config, prefix_expr, edition, display_target) } _ => None, }; - let res = res.or_else(|| render::type_info_of(sema, config, &expr_or_pat, edition)); + let res = + res.or_else(|| render::type_info_of(sema, config, &expr_or_pat, edition, display_target)); res.map(|it| { let range = match expr_or_pat { Either::Left(it) => it.syntax().text_range(), @@ -401,6 +425,7 @@ pub(crate) fn hover_for_definition( hovered_definition: bool, config: &HoverConfig, edition: Edition, + display_target: DisplayTarget, ) -> HoverResult { let famous_defs = match &def { Definition::BuiltinType(_) => sema.scope(scope_node).map(|it| FamousDefs(sema, it.krate())), @@ -435,6 +460,7 @@ pub(crate) fn hover_for_definition( subst_types.as_ref(), config, edition, + display_target, ); HoverResult { markup: render::process_markup(sema.db, def, &markup, config), diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index c5a83e58cea1..31ef89a07cde 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -3,7 +3,7 @@ use std::{env, mem, ops::Not}; use either::Either; use hir::{ - db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind, DropGlue, + db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind, DisplayTarget, DropGlue, DynCompatibilityViolation, HasCrate, HasSource, HirDisplay, Layout, LayoutError, MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef, }; @@ -38,12 +38,13 @@ pub(super) fn type_info_of( _config: &HoverConfig, expr_or_pat: &Either, edition: Edition, + display_target: DisplayTarget, ) -> Option { let ty_info = match expr_or_pat { Either::Left(expr) => sema.type_of_expr(expr)?, Either::Right(pat) => sema.type_of_pat(pat)?, }; - type_info(sema, _config, ty_info, edition) + type_info(sema, _config, ty_info, edition, display_target) } pub(super) fn closure_expr( @@ -51,9 +52,10 @@ pub(super) fn closure_expr( config: &HoverConfig, c: ast::ClosureExpr, edition: Edition, + display_target: DisplayTarget, ) -> Option { let TypeInfo { original, .. } = sema.type_of_expr(&c.into())?; - closure_ty(sema, config, &TypeInfo { original, adjusted: None }, edition) + closure_ty(sema, config, &TypeInfo { original, adjusted: None }, edition, display_target) } pub(super) fn try_expr( @@ -61,6 +63,7 @@ pub(super) fn try_expr( _config: &HoverConfig, try_expr: &ast::TryExpr, edition: Edition, + display_target: DisplayTarget, ) -> Option { let inner_ty = sema.type_of_expr(&try_expr.expr()?)?.original; let mut ancestors = try_expr.syntax().ancestors(); @@ -127,8 +130,8 @@ pub(super) fn try_expr( res.actions.push(actions); } - let inner_ty = inner_ty.display(sema.db, edition).to_string(); - let body_ty = body_ty.display(sema.db, edition).to_string(); + let inner_ty = inner_ty.display(sema.db, display_target).to_string(); + let body_ty = body_ty.display(sema.db, display_target).to_string(); let ty_len_max = inner_ty.len().max(body_ty.len()); let l = "Propagated as: ".len() - " Type: ".len(); @@ -153,6 +156,7 @@ pub(super) fn deref_expr( _config: &HoverConfig, deref_expr: &ast::PrefixExpr, edition: Edition, + display_target: DisplayTarget, ) -> Option { let inner_ty = sema.type_of_expr(&deref_expr.expr()?)?.original; let TypeInfo { original, adjusted } = @@ -170,9 +174,9 @@ pub(super) fn deref_expr( res.markup = if let Some(adjusted_ty) = adjusted { walk_and_push_ty(sema.db, &adjusted_ty, &mut push_new_def); - let original = original.display(sema.db, edition).to_string(); - let adjusted = adjusted_ty.display(sema.db, edition).to_string(); - let inner = inner_ty.display(sema.db, edition).to_string(); + let original = original.display(sema.db, display_target).to_string(); + let adjusted = adjusted_ty.display(sema.db, display_target).to_string(); + let inner = inner_ty.display(sema.db, display_target).to_string(); let type_len = "To type: ".len(); let coerced_len = "Coerced to: ".len(); let deref_len = "Dereferenced from: ".len(); @@ -190,8 +194,8 @@ pub(super) fn deref_expr( ) .into() } else { - let original = original.display(sema.db, edition).to_string(); - let inner = inner_ty.display(sema.db, edition).to_string(); + let original = original.display(sema.db, display_target).to_string(); + let inner = inner_ty.display(sema.db, display_target).to_string(); let type_len = "To type: ".len(); let deref_len = "Dereferenced from: ".len(); let max_len = (original.len() + type_len).max(inner.len() + deref_len); @@ -216,6 +220,7 @@ pub(super) fn underscore( config: &HoverConfig, token: &SyntaxToken, edition: Edition, + display_target: DisplayTarget, ) -> Option { if token.kind() != T![_] { return None; @@ -224,8 +229,8 @@ pub(super) fn underscore( let _it = match_ast! { match parent { ast::InferType(it) => it, - ast::UnderscoreExpr(it) => return type_info_of(sema, config, &Either::Left(ast::Expr::UnderscoreExpr(it)),edition), - ast::WildcardPat(it) => return type_info_of(sema, config, &Either::Right(ast::Pat::WildcardPat(it)),edition), + ast::UnderscoreExpr(it) => return type_info_of(sema, config, &Either::Left(ast::Expr::UnderscoreExpr(it)),edition, display_target), + ast::WildcardPat(it) => return type_info_of(sema, config, &Either::Right(ast::Pat::WildcardPat(it)),edition, display_target), _ => return None, } }; @@ -259,6 +264,7 @@ pub(super) fn keyword( config: &HoverConfig, token: &SyntaxToken, edition: Edition, + display_target: DisplayTarget, ) -> Option { if !token.kind().is_keyword(edition) || !config.documentation || !config.keywords { return None; @@ -267,7 +273,7 @@ pub(super) fn keyword( let famous_defs = FamousDefs(sema, sema.scope(&parent)?.krate()); let KeywordHint { description, keyword_mod, actions } = - keyword_hints(sema, token, parent, edition); + keyword_hints(sema, token, parent, edition, display_target); let doc_owner = find_std_module(&famous_defs, &keyword_mod, edition)?; let docs = doc_owner.docs(sema.db)?; @@ -288,6 +294,7 @@ pub(super) fn struct_rest_pat( _config: &HoverConfig, pattern: &ast::RecordPat, edition: Edition, + display_target: DisplayTarget, ) -> HoverResult { let missing_fields = sema.record_pattern_missing_fields(pattern); @@ -309,7 +316,7 @@ pub(super) fn struct_rest_pat( res.markup = { let mut s = String::from(".., "); for (f, _) in &missing_fields { - s += f.display(sema.db, edition).to_string().as_ref(); + s += f.display(sema.db, display_target).to_string().as_ref(); s += ", "; } // get rid of trailing comma @@ -479,41 +486,44 @@ pub(super) fn definition( subst_types: Option<&Vec<(Symbol, Type)>>, config: &HoverConfig, edition: Edition, + display_target: DisplayTarget, ) -> Markup { let mod_path = definition_path(db, &def, edition); let label = match def { - Definition::Trait(trait_) => { - trait_.display_limited(db, config.max_trait_assoc_items_count, edition).to_string() - } + Definition::Trait(trait_) => trait_ + .display_limited(db, config.max_trait_assoc_items_count, display_target) + .to_string(), Definition::Adt(adt @ (Adt::Struct(_) | Adt::Union(_))) => { - adt.display_limited(db, config.max_fields_count, edition).to_string() + adt.display_limited(db, config.max_fields_count, display_target).to_string() } Definition::Variant(variant) => { - variant.display_limited(db, config.max_fields_count, edition).to_string() + variant.display_limited(db, config.max_fields_count, display_target).to_string() } Definition::Adt(adt @ Adt::Enum(_)) => { - adt.display_limited(db, config.max_enum_variants_count, edition).to_string() + adt.display_limited(db, config.max_enum_variants_count, display_target).to_string() } Definition::SelfType(impl_def) => { let self_ty = &impl_def.self_ty(db); match self_ty.as_adt() { - Some(adt) => adt.display_limited(db, config.max_fields_count, edition).to_string(), - None => self_ty.display(db, edition).to_string(), + Some(adt) => { + adt.display_limited(db, config.max_fields_count, display_target).to_string() + } + None => self_ty.display(db, display_target).to_string(), } } Definition::Macro(it) => { - let mut label = it.display(db, edition).to_string(); + let mut label = it.display(db, display_target).to_string(); if let Some(macro_arm) = macro_arm { format_to!(label, " // matched arm #{}", macro_arm); } label } Definition::Function(fn_) => { - fn_.display_with_container_bounds(db, true, edition).to_string() + fn_.display_with_container_bounds(db, true, display_target).to_string() } - _ => def.label(db, edition), + _ => def.label(db, display_target), }; - let docs = def.docs(db, famous_defs, edition); + let docs = def.docs(db, famous_defs, display_target); let value = || match def { Definition::Variant(it) => { if !it.parent_enum(db).is_data_carrying(db) { @@ -525,7 +535,10 @@ pub(super) fn definition( let res = it.value(db).map(|it| format!("{it:?}")); if env::var_os("RA_DEV").is_some() { let res = res.as_deref().unwrap_or(""); - Some(format!("{res} ({})", render_const_eval_error(db, err, edition))) + Some(format!( + "{res} ({})", + render_const_eval_error(db, err, display_target) + )) } else { res } @@ -541,9 +554,12 @@ pub(super) fn definition( Ok(it) => match it.render_debug(db) { Ok(it) => it, Err(err) => { - let it = it.render(db, edition); + let it = it.render(db, display_target); if env::var_os("RA_DEV").is_some() { - format!("{it}\n{}", render_const_eval_error(db, err.into(), edition)) + format!( + "{it}\n{}", + render_const_eval_error(db, err.into(), display_target) + ) } else { it } @@ -557,7 +573,7 @@ pub(super) fn definition( body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into()); } if env::var_os("RA_DEV").is_some() { - format!("{body}\n{}", render_const_eval_error(db, err, edition)) + format!("{body}\n{}", render_const_eval_error(db, err, display_target)) } else { body.to_string() } @@ -570,9 +586,12 @@ pub(super) fn definition( Ok(it) => match it.render_debug(db) { Ok(it) => it, Err(err) => { - let it = it.render(db, edition); + let it = it.render(db, display_target); if env::var_os("RA_DEV").is_some() { - format!("{it}\n{}", render_const_eval_error(db, err.into(), edition)) + format!( + "{it}\n{}", + render_const_eval_error(db, err.into(), display_target) + ) } else { it } @@ -586,7 +605,7 @@ pub(super) fn definition( body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into()); } if env::var_os("RA_DEV").is_some() { - format!("{body}\n{}", render_const_eval_error(db, err, edition)) + format!("{body}\n{}", render_const_eval_error(db, err, display_target)) } else { body.to_string() } @@ -728,7 +747,9 @@ pub(super) fn definition( let mut extra = String::new(); if hovered_definition { - if let Some(notable_traits) = render_notable_trait(db, notable_traits, edition) { + if let Some(notable_traits) = + render_notable_trait(db, notable_traits, edition, display_target) + { extra.push_str("\n___\n"); extra.push_str(¬able_traits); } @@ -772,7 +793,7 @@ pub(super) fn definition( .format_with(", ", |(name, ty), fmt| { fmt(&format_args!( "`{name}` = `{}`", - ty.display_truncated(db, limit, edition) + ty.display_truncated(db, limit, display_target) )) }) .to_string() @@ -799,7 +820,7 @@ struct DropInfo { pub(super) fn literal( sema: &Semantics<'_, RootDatabase>, token: SyntaxToken, - edition: Edition, + display_target: DisplayTarget, ) -> Option { let lit = token.parent().and_then(ast::Literal::cast)?; let ty = if let Some(p) = lit.syntax().parent().and_then(ast::Pat::cast) { @@ -847,7 +868,7 @@ pub(super) fn literal( _ => return None } }; - let ty = ty.display(sema.db, edition); + let ty = ty.display(sema.db, display_target); let mut s = format!("```rust\n{ty}\n```\n___\n\n"); match value { @@ -879,6 +900,7 @@ fn render_notable_trait( db: &RootDatabase, notable_traits: &[(Trait, Vec<(Option, Name)>)], edition: Edition, + display_target: DisplayTarget, ) -> Option { let mut desc = String::new(); let mut needs_impl_header = true; @@ -898,7 +920,7 @@ fn render_notable_trait( f(&name.display(db, edition))?; f(&" = ")?; match ty { - Some(ty) => f(&ty.display(db, edition)), + Some(ty) => f(&ty.display(db, display_target)), None => f(&"?"), } }) @@ -914,8 +936,9 @@ fn type_info( config: &HoverConfig, ty: TypeInfo, edition: Edition, + display_target: DisplayTarget, ) -> Option { - if let Some(res) = closure_ty(sema, config, &ty, edition) { + if let Some(res) = closure_ty(sema, config, &ty, edition, display_target) { return Some(res); }; let db = sema.db; @@ -951,7 +974,7 @@ fn type_info( f(&name.display(db, edition))?; f(&" = ")?; match ty { - Some(ty) => f(&ty.display(db, edition)), + Some(ty) => f(&ty.display(db, display_target)), None => f(&"?"), } }) @@ -965,8 +988,8 @@ fn type_info( desc }; - let original = original.display(db, edition).to_string(); - let adjusted = adjusted_ty.display(db, edition).to_string(); + let original = original.display(db, display_target).to_string(); + let adjusted = adjusted_ty.display(db, display_target).to_string(); let static_text_diff_len = "Coerced to: ".len() - "Type: ".len(); format!( "```text\nType: {:>apad$}\nCoerced to: {:>opad$}\n{notable}```\n", @@ -977,8 +1000,10 @@ fn type_info( ) .into() } else { - let mut desc = format!("```rust\n{}\n```", original.display(db, edition)); - if let Some(extra) = render_notable_trait(db, ¬able_traits(db, &original), edition) { + let mut desc = format!("```rust\n{}\n```", original.display(db, display_target)); + if let Some(extra) = + render_notable_trait(db, ¬able_traits(db, &original), edition, display_target) + { desc.push_str("\n___\n"); desc.push_str(&extra); }; @@ -995,6 +1020,7 @@ fn closure_ty( config: &HoverConfig, TypeInfo { original, adjusted }: &TypeInfo, edition: Edition, + display_target: DisplayTarget, ) -> Option { let c = original.as_closure()?; let mut captures_rendered = c.captured_items(sema.db) @@ -1027,12 +1053,14 @@ fn closure_ty( walk_and_push_ty(sema.db, adjusted_ty, &mut push_new_def); format!( "\nCoerced to: {}", - adjusted_ty.display(sema.db, edition).with_closure_style(hir::ClosureStyle::ImplFn) + adjusted_ty + .display(sema.db, display_target) + .with_closure_style(hir::ClosureStyle::ImplFn) ) } else { String::new() }; - let mut markup = format!("```rust\n{}\n```", c.display_with_impl(sema.db, edition)); + let mut markup = format!("```rust\n{}\n```", c.display_with_impl(sema.db, display_target)); if let Some(trait_) = c.fn_trait(sema.db).get_id(sema.db, original.krate(sema.db).into()) { push_new_def(hir::Trait::from(trait_).into()) @@ -1213,6 +1241,7 @@ fn keyword_hints( token: &SyntaxToken, parent: syntax::SyntaxNode, edition: Edition, + display_target: DisplayTarget, ) -> KeywordHint { match token.kind() { T![await] | T![loop] | T![match] | T![unsafe] | T![as] | T![try] | T![if] | T![else] => { @@ -1230,7 +1259,8 @@ fn keyword_hints( walk_and_push_ty(sema.db, &ty.original, &mut push_new_def); let ty = ty.adjusted(); - let description = format!("{}: {}", token.text(), ty.display(sema.db, edition)); + let description = + format!("{}: {}", token.text(), ty.display(sema.db, display_target)); KeywordHint { description, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index 63039b1cd34e..6babdff52a2b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -5,14 +5,14 @@ use std::{ use either::Either; use hir::{ - sym, ClosureStyle, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef, - ModuleDefId, Semantics, + sym, ClosureStyle, DisplayTarget, HasVisibility, HirDisplay, HirDisplayError, HirWrite, + ModuleDef, ModuleDefId, Semantics, }; use ide_db::{famous_defs::FamousDefs, FileRange, RootDatabase}; use ide_db::{text_edit::TextEdit, FxHashSet}; use itertools::Itertools; use smallvec::{smallvec, SmallVec}; -use span::{Edition, EditionedFileId}; +use span::EditionedFileId; use stdx::never; use syntax::{ ast::{self, AstNode, HasGenericParams}, @@ -207,7 +207,8 @@ fn hints( file_id: EditionedFileId, node: SyntaxNode, ) { - closing_brace::hints(hints, sema, config, file_id, node.clone()); + let display_target = sema.first_crate_or_default(file_id.file_id()).to_display_target(sema.db); + closing_brace::hints(hints, sema, config, file_id, display_target, node.clone()); if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) { generic_param::hints(hints, famous_defs, config, any_has_generic_args); } @@ -215,8 +216,8 @@ fn hints( match_ast! { match node { ast::Expr(expr) => { - chaining::hints(hints, famous_defs, config, file_id, &expr); - adjustment::hints(hints, famous_defs, config, file_id, &expr); + chaining::hints(hints, famous_defs, config, display_target, &expr); + adjustment::hints(hints, famous_defs, config, display_target, &expr); match expr { ast::Expr::CallExpr(it) => param_name::hints(hints, famous_defs, config, file_id, ast::Expr::from(it)), ast::Expr::MethodCallExpr(it) => { @@ -224,7 +225,7 @@ fn hints( } ast::Expr::ClosureExpr(it) => { closure_captures::hints(hints, famous_defs, config, file_id, it.clone()); - closure_ret::hints(hints, famous_defs, config, file_id, it) + closure_ret::hints(hints, famous_defs, config, display_target, it) }, ast::Expr::RangeExpr(it) => range_exclusive::hints(hints, famous_defs, config, file_id, it), _ => Some(()), @@ -234,7 +235,7 @@ fn hints( binding_mode::hints(hints, famous_defs, config, file_id, &it); match it { ast::Pat::IdentPat(it) => { - bind_pat::hints(hints, famous_defs, config, file_id, &it); + bind_pat::hints(hints, famous_defs, config, display_target, &it); } ast::Pat::RangePat(it) => { range_exclusive::hints(hints, famous_defs, config, file_id, it); @@ -704,7 +705,7 @@ fn label_of_ty( famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, ty: &hir::Type, - edition: Edition, + display_target: DisplayTarget, ) -> Option { fn rec( sema: &Semantics<'_, RootDatabase>, @@ -713,7 +714,7 @@ fn label_of_ty( ty: &hir::Type, label_builder: &mut InlayHintLabelBuilder<'_>, config: &InlayHintsConfig, - edition: Edition, + display_target: DisplayTarget, ) -> Result<(), HirDisplayError> { let iter_item_type = hint_iterator(sema, famous_defs, ty); match iter_item_type { @@ -744,12 +745,12 @@ fn label_of_ty( label_builder.write_str(LABEL_ITEM)?; label_builder.end_location_link(); label_builder.write_str(LABEL_MIDDLE2)?; - rec(sema, famous_defs, max_length, &ty, label_builder, config, edition)?; + rec(sema, famous_defs, max_length, &ty, label_builder, config, display_target)?; label_builder.write_str(LABEL_END)?; Ok(()) } None => ty - .display_truncated(sema.db, max_length, edition) + .display_truncated(sema.db, max_length, display_target) .with_closure_style(config.closure_style) .write_to(label_builder), } @@ -762,7 +763,8 @@ fn label_of_ty( result: InlayHintLabel::default(), resolve: config.fields_to_resolve.resolve_label_location, }; - let _ = rec(sema, famous_defs, config.max_length, ty, &mut label_builder, config, edition); + let _ = + rec(sema, famous_defs, config.max_length, ty, &mut label_builder, config, display_target); let r = label_builder.finish(); Some(r) } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs index 8522ef0a6d5f..91b818729523 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs @@ -7,12 +7,12 @@ use std::ops::Not; use either::Either; use hir::{ - Adjust, Adjustment, AutoBorrow, HirDisplay, Mutability, OverloadedDeref, PointerCast, Safety, + Adjust, Adjustment, AutoBorrow, DisplayTarget, HirDisplay, Mutability, OverloadedDeref, + PointerCast, Safety, }; use ide_db::famous_defs::FamousDefs; use ide_db::text_edit::TextEditBuilder; -use span::EditionedFileId; use syntax::ast::{self, prec::ExprPrecedence, AstNode}; use crate::{ @@ -24,7 +24,7 @@ pub(super) fn hints( acc: &mut Vec, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: EditionedFileId, + display_target: DisplayTarget, expr: &ast::Expr, ) -> Option<()> { if config.adjustment_hints_hide_outside_unsafe && !sema.is_inside_unsafe(expr) { @@ -163,8 +163,8 @@ pub(super) fn hints( tooltip: Some(config.lazy_tooltip(|| { InlayTooltip::Markdown(format!( "`{}` → `{}` ({coercion} coercion)", - source.display(sema.db, file_id.edition()), - target.display(sema.db, file_id.edition()), + source.display(sema.db, display_target), + target.display(sema.db, display_target), )) })), }; diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index c2986a9aa662..4379153acaa1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -3,11 +3,10 @@ //! fn f(a: i32, b: i32) -> i32 { a + b } //! let _x /* i32 */= f(4, 4); //! ``` -use hir::Semantics; +use hir::{DisplayTarget, Semantics}; use ide_db::{famous_defs::FamousDefs, RootDatabase}; use itertools::Itertools; -use span::EditionedFileId; use syntax::{ ast::{self, AstNode, HasGenericArgs, HasName}, match_ast, @@ -22,7 +21,7 @@ pub(super) fn hints( acc: &mut Vec, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: EditionedFileId, + display_target: DisplayTarget, pat: &ast::IdentPat, ) -> Option<()> { if !config.type_hints { @@ -70,7 +69,7 @@ pub(super) fn hints( return None; } - let mut label = label_of_ty(famous_defs, config, &ty, file_id.edition())?; + let mut label = label_of_ty(famous_defs, config, &ty, display_target)?; if config.hide_named_constructor_hints && is_named_constructor(sema, pat, &label.to_string()).is_some() diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs index 8471547727fe..604719bc366f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs @@ -1,6 +1,6 @@ //! Implementation of "chaining" inlay hints. +use hir::DisplayTarget; use ide_db::famous_defs::FamousDefs; -use span::EditionedFileId; use syntax::{ ast::{self, AstNode}, Direction, NodeOrToken, SyntaxKind, T, @@ -14,7 +14,7 @@ pub(super) fn hints( acc: &mut Vec, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: EditionedFileId, + display_target: DisplayTarget, expr: &ast::Expr, ) -> Option<()> { if !config.chaining_hints { @@ -58,7 +58,7 @@ pub(super) fn hints( } } } - let label = label_of_ty(famous_defs, config, &ty, file_id.edition())?; + let label = label_of_ty(famous_defs, config, &ty, display_target)?; acc.push(InlayHint { range: expr.syntax().text_range(), kind: InlayKind::Chaining, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs index 3767d34e2c7a..bec6d38ee9ca 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs @@ -3,7 +3,7 @@ //! fn g() { //! } /* fn g */ //! ``` -use hir::{HirDisplay, Semantics}; +use hir::{DisplayTarget, HirDisplay, Semantics}; use ide_db::{FileRange, RootDatabase}; use span::EditionedFileId; use syntax::{ @@ -21,6 +21,7 @@ pub(super) fn hints( sema: &Semantics<'_, RootDatabase>, config: &InlayHintsConfig, file_id: EditionedFileId, + display_target: DisplayTarget, original_node: SyntaxNode, ) -> Option<()> { let min_lines = config.closing_brace_hints_min_lines?; @@ -43,9 +44,9 @@ pub(super) fn hints( Some(tr) => format!( "impl {} for {}", tr.name(sema.db).display(sema.db, file_id.edition()), - ty.display_truncated(sema.db, config.max_length, file_id.edition(), + ty.display_truncated(sema.db, config.max_length, display_target, )), - None => format!("impl {}", ty.display_truncated(sema.db, config.max_length, file_id.edition())), + None => format!("impl {}", ty.display_truncated(sema.db, config.max_length, display_target)), }; (hint_text, None) }, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs index 7858b1d90a38..61c9c25fe739 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs @@ -1,8 +1,8 @@ //! Implementation of "closure return type" inlay hints. //! //! Tests live in [`bind_pat`][super::bind_pat] module. +use hir::DisplayTarget; use ide_db::famous_defs::FamousDefs; -use span::EditionedFileId; use syntax::ast::{self, AstNode}; use crate::{ @@ -14,7 +14,7 @@ pub(super) fn hints( acc: &mut Vec, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: EditionedFileId, + display_target: DisplayTarget, closure: ast::ClosureExpr, ) -> Option<()> { if config.closure_return_type_hints == ClosureReturnTypeHints::Never { @@ -43,7 +43,7 @@ pub(super) fn hints( return None; } - let mut label = label_of_ty(famous_defs, config, &ty, file_id.edition())?; + let mut label = label_of_ty(famous_defs, config, &ty, display_target)?; if arrow.is_none() { label.prepend_str(" -> "); diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs index ae11072e34b7..74dad488b4d3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/interpret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs @@ -1,6 +1,5 @@ -use hir::{ConstEvalError, DefWithBody, Semantics}; +use hir::{ConstEvalError, DefWithBody, DisplayTarget, Semantics}; use ide_db::{base_db::SourceRootDatabase, FilePosition, LineIndexDatabase, RootDatabase}; -use span::Edition; use std::time::{Duration, Instant}; use stdx::format_to; use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange}; @@ -46,15 +45,15 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura None => format!("file://{path} range {text_range:?}"), } }; - let edition = def.module(db).krate().edition(db); + let display_target = def.module(db).krate().to_display_target(db); let start_time = Instant::now(); let res = match def { DefWithBody::Function(it) => it.eval(db, span_formatter), - DefWithBody::Static(it) => it.eval(db).map(|it| it.render(db, edition)), - DefWithBody::Const(it) => it.eval(db).map(|it| it.render(db, edition)), + DefWithBody::Static(it) => it.eval(db).map(|it| it.render(db, display_target)), + DefWithBody::Const(it) => it.eval(db).map(|it| it.render(db, display_target)), _ => unreachable!(), }; - let res = res.unwrap_or_else(|e| render_const_eval_error(db, e, edition)); + let res = res.unwrap_or_else(|e| render_const_eval_error(db, e, display_target)); let duration = Instant::now() - start_time; Some((duration, res)) } @@ -62,7 +61,7 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura pub(crate) fn render_const_eval_error( db: &RootDatabase, e: ConstEvalError, - edition: Edition, + display_target: DisplayTarget, ) -> String { let span_formatter = |file_id, text_range: TextRange| { let path = &db @@ -76,6 +75,6 @@ pub(crate) fn render_const_eval_error( } }; let mut r = String::new(); - _ = e.pretty_print(&mut r, db, span_formatter, edition); + _ = e.pretty_print(&mut r, db, span_formatter, display_target); r } diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs index 25d12a4c0b4f..5754b4fa82f4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs +++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs @@ -11,7 +11,6 @@ use ide_db::{ FilePosition, RootDatabase, }; use itertools::Itertools; -use span::Edition; use syntax::{AstNode, SyntaxKind::*, T}; use crate::{doc_links::token_as_doc_comment, parent_module::crates_for, RangeInfo}; @@ -305,13 +304,13 @@ fn def_to_non_local_moniker( if let Some(trait_ref) = impl_.trait_ref(db) { // Trait impls use the trait type for the 2nd parameter. reverse_description.push(MonikerDescriptor { - name: display(db, edition, module, trait_ref), + name: display(db, module, trait_ref), desc: MonikerDescriptorKind::TypeParameter, }); } // Both inherent and trait impls use the self type for the first parameter. reverse_description.push(MonikerDescriptor { - name: display(db, edition, module, impl_.self_ty(db)), + name: display(db, module, impl_.self_ty(db)), desc: MonikerDescriptorKind::TypeParameter, }); reverse_description.push(MonikerDescriptor { @@ -390,17 +389,12 @@ fn def_to_non_local_moniker( }) } -fn display( - db: &RootDatabase, - edition: Edition, - module: hir::Module, - it: T, -) -> String { +fn display(db: &RootDatabase, module: hir::Module, it: T) -> String { match it.display_source_code(db, module.into(), true) { Ok(result) => result, // Fallback on display variant that always succeeds Err(_) => { - let fallback_result = it.display(db, edition).to_string(); + let fallback_result = it.display(db, module.krate().to_display_target(db)).to_string(); tracing::error!( display = %fallback_result, "`display_source_code` failed; falling back to using display" ); diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index d9f80cb53dd6..d67aaac06fb9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -6,7 +6,7 @@ use arrayvec::ArrayVec; use either::Either; use hir::{ db::ExpandDatabase, symbols::FileSymbol, AssocItem, FieldSource, HasContainer, HasCrate, - HasSource, HirDisplay, HirFileId, HirFileIdExt, InFile, LocalSource, ModuleSource, + HasSource, HirDisplay, HirFileId, InFile, LocalSource, ModuleSource, }; use ide_db::{ defs::Definition, @@ -116,7 +116,9 @@ impl NavigationTarget { SymbolKind::Module, ); res.docs = module.docs(db); - res.description = Some(module.display(db, edition).to_string()); + res.description = Some( + module.display(db, module.krate().to_display_target(db)).to_string(), + ); res }, ) @@ -183,6 +185,7 @@ impl TryToNav for FileSymbol { fn try_to_nav(&self, db: &RootDatabase) -> Option> { let edition = self.def.module(db).map(|it| it.krate().edition(db)).unwrap_or(Edition::CURRENT); + let display_target = self.def.krate(db).to_display_target(db); Some( orig_range_with_focus_r( db, @@ -203,16 +206,34 @@ impl TryToNav for FileSymbol { focus_range, container_name: self.container_name.clone(), description: match self.def { - hir::ModuleDef::Module(it) => Some(it.display(db, edition).to_string()), - hir::ModuleDef::Function(it) => Some(it.display(db, edition).to_string()), - hir::ModuleDef::Adt(it) => Some(it.display(db, edition).to_string()), - hir::ModuleDef::Variant(it) => Some(it.display(db, edition).to_string()), - hir::ModuleDef::Const(it) => Some(it.display(db, edition).to_string()), - hir::ModuleDef::Static(it) => Some(it.display(db, edition).to_string()), - hir::ModuleDef::Trait(it) => Some(it.display(db, edition).to_string()), - hir::ModuleDef::TraitAlias(it) => Some(it.display(db, edition).to_string()), - hir::ModuleDef::TypeAlias(it) => Some(it.display(db, edition).to_string()), - hir::ModuleDef::Macro(it) => Some(it.display(db, edition).to_string()), + hir::ModuleDef::Module(it) => { + Some(it.display(db, display_target).to_string()) + } + hir::ModuleDef::Function(it) => { + Some(it.display(db, display_target).to_string()) + } + hir::ModuleDef::Adt(it) => Some(it.display(db, display_target).to_string()), + hir::ModuleDef::Variant(it) => { + Some(it.display(db, display_target).to_string()) + } + hir::ModuleDef::Const(it) => { + Some(it.display(db, display_target).to_string()) + } + hir::ModuleDef::Static(it) => { + Some(it.display(db, display_target).to_string()) + } + hir::ModuleDef::Trait(it) => { + Some(it.display(db, display_target).to_string()) + } + hir::ModuleDef::TraitAlias(it) => { + Some(it.display(db, display_target).to_string()) + } + hir::ModuleDef::TypeAlias(it) => { + Some(it.display(db, display_target).to_string()) + } + hir::ModuleDef::Macro(it) => { + Some(it.display(db, display_target).to_string()) + } hir::ModuleDef::BuiltinType(_) => None, }, docs: None, @@ -353,12 +374,11 @@ impl ToNavFromAst for hir::TraitAlias { impl TryToNav for D where - D: HasSource + ToNavFromAst + Copy + HasDocs + HirDisplay, + D: HasSource + ToNavFromAst + Copy + HasDocs + HirDisplay + HasCrate, D::Ast: ast::HasName, { fn try_to_nav(&self, db: &RootDatabase) -> Option> { let src = self.source(db)?; - let edition = src.file_id.original_file(db).edition(); Some( NavigationTarget::from_named( db, @@ -367,7 +387,8 @@ where ) .map(|mut res| { res.docs = self.docs(db); - res.description = Some(self.display(db, edition).to_string()); + res.description = + Some(self.display(db, self.krate(db).to_display_target(db)).to_string()); res.container_name = self.container_name(db); res }), @@ -439,7 +460,8 @@ impl TryToNav for hir::ExternCrateDecl { let focus = value .rename() .map_or_else(|| value.name_ref().map(Either::Left), |it| it.name().map(Either::Right)); - let edition = self.module(db).krate().edition(db); + let krate = self.module(db).krate(); + let edition = krate.edition(db); Some(orig_range_with_focus(db, file_id, value.syntax(), focus).map( |(FileRange { file_id, range: full_range }, focus_range)| { @@ -455,7 +477,7 @@ impl TryToNav for hir::ExternCrateDecl { ); res.docs = self.docs(db); - res.description = Some(self.display(db, edition).to_string()); + res.description = Some(self.display(db, krate.to_display_target(db)).to_string()); res.container_name = container_name(db, *self, edition); res }, @@ -466,14 +488,15 @@ impl TryToNav for hir::ExternCrateDecl { impl TryToNav for hir::Field { fn try_to_nav(&self, db: &RootDatabase) -> Option> { let src = self.source(db)?; - let edition = self.parent_def(db).module(db).krate().edition(db); + let krate = self.parent_def(db).module(db).krate(); let field_source = match &src.value { FieldSource::Named(it) => { NavigationTarget::from_named(db, src.with_value(it), SymbolKind::Field).map( |mut res| { res.docs = self.docs(db); - res.description = Some(self.display(db, edition).to_string()); + res.description = + Some(self.display(db, krate.to_display_target(db)).to_string()); res }, ) diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index 509ae3204c36..b8deed01fb7f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -9,6 +9,7 @@ use hir::{ }; use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn}; use ide_db::{ + base_db::SourceDatabase, defs::Definition, documentation::docs_from_attrs, helpers::visit_file_defs, @@ -399,7 +400,8 @@ pub(crate) fn runnable_impl( sema: &Semantics<'_, RootDatabase>, def: &hir::Impl, ) -> Option { - let edition = def.module(sema.db).krate().edition(sema.db); + let display_target = def.module(sema.db).krate().to_display_target(sema.db); + let edition = display_target.edition; let attrs = def.attrs(sema.db); if !has_runnable_doc_test(&attrs) { return None; @@ -408,7 +410,7 @@ pub(crate) fn runnable_impl( let nav = def.try_to_nav(sema.db)?.call_site(); let ty = def.self_ty(sema.db); let adt_name = ty.as_adt()?.name(sema.db); - let mut ty_args = ty.generic_parameters(sema.db, edition).peekable(); + let mut ty_args = ty.generic_parameters(sema.db, display_target).peekable(); let params = if ty_args.peek().is_some() { format!("<{}>", ty_args.format_with(",", |ty, cb| cb(&ty))) } else { @@ -494,7 +496,11 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option { Definition::SelfType(it) => it.attrs(db), _ => return None, }; - let edition = def.krate(db).map(|it| it.edition(db)).unwrap_or(Edition::CURRENT); + let krate = def.krate(db); + let edition = krate.map(|it| it.edition(db)).unwrap_or(Edition::CURRENT); + let display_target = krate + .unwrap_or_else(|| (*db.crate_graph().crates_in_topological_order().last().unwrap()).into()) + .to_display_target(db); if !has_runnable_doc_test(&attrs) { return None; } @@ -509,7 +515,7 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option { if let Some(ty) = assoc_item.implementing_ty(db) { if let Some(adt) = ty.as_adt() { let name = adt.name(db); - let mut ty_args = ty.generic_parameters(db, edition).peekable(); + let mut ty_args = ty.generic_parameters(db, display_target).peekable(); format_to!(path, "{}", name.display(db, edition)); if ty_args.peek().is_some() { format_to!(path, "<{}>", ty_args.format_with(",", |ty, cb| cb(&ty))); diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index f99721160041..b5468a5aee9f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -4,7 +4,9 @@ use std::collections::BTreeSet; use either::Either; -use hir::{AssocItem, GenericParam, HirDisplay, ModuleDef, PathResolution, Semantics, Trait}; +use hir::{ + AssocItem, DisplayTarget, GenericParam, HirDisplay, ModuleDef, PathResolution, Semantics, Trait, +}; use ide_db::{ active_parameter::{callable_for_node, generic_def_for_node}, documentation::{Documentation, HasDocs}, @@ -82,6 +84,7 @@ pub(crate) fn signature_help( let token = sema.descend_into_macros_single_exact(token); let edition = sema.attach_first_edition(file_id).map(|it| it.edition()).unwrap_or(Edition::CURRENT); + let display_target = sema.first_crate_or_default(file_id).to_display_target(db); for node in token.parent_ancestors() { match_ast! { @@ -91,49 +94,49 @@ pub(crate) fn signature_help( if cursor_outside { continue; } - return signature_help_for_call(&sema, arg_list, token, edition); + return signature_help_for_call(&sema, arg_list, token, edition, display_target); }, ast::GenericArgList(garg_list) => { let cursor_outside = garg_list.r_angle_token().as_ref() == Some(&token); if cursor_outside { continue; } - return signature_help_for_generics(&sema, garg_list, token, edition); + return signature_help_for_generics(&sema, garg_list, token, edition, display_target); }, ast::RecordExpr(record) => { let cursor_outside = record.record_expr_field_list().and_then(|list| list.r_curly_token()).as_ref() == Some(&token); if cursor_outside { continue; } - return signature_help_for_record_lit(&sema, record, token, edition); + return signature_help_for_record_lit(&sema, record, token, edition, display_target); }, ast::RecordPat(record) => { let cursor_outside = record.record_pat_field_list().and_then(|list| list.r_curly_token()).as_ref() == Some(&token); if cursor_outside { continue; } - return signature_help_for_record_pat(&sema, record, token, edition); + return signature_help_for_record_pat(&sema, record, token, edition, display_target); }, ast::TupleStructPat(tuple_pat) => { let cursor_outside = tuple_pat.r_paren_token().as_ref() == Some(&token); if cursor_outside { continue; } - return signature_help_for_tuple_struct_pat(&sema, tuple_pat, token, edition); + return signature_help_for_tuple_struct_pat(&sema, tuple_pat, token, edition, display_target); }, ast::TuplePat(tuple_pat) => { let cursor_outside = tuple_pat.r_paren_token().as_ref() == Some(&token); if cursor_outside { continue; } - return signature_help_for_tuple_pat(&sema, tuple_pat, token, edition); + return signature_help_for_tuple_pat(&sema, tuple_pat, token, display_target); }, ast::TupleExpr(tuple_expr) => { let cursor_outside = tuple_expr.r_paren_token().as_ref() == Some(&token); if cursor_outside { continue; } - return signature_help_for_tuple_expr(&sema, tuple_expr, token, edition); + return signature_help_for_tuple_expr(&sema, tuple_expr, token, display_target); }, _ => (), } @@ -158,6 +161,7 @@ fn signature_help_for_call( arg_list: ast::ArgList, token: SyntaxToken, edition: Edition, + display_target: DisplayTarget, ) -> Option { // Find the calling expression and its NameRef let mut nodes = arg_list.syntax().ancestors().skip(1); @@ -221,7 +225,7 @@ fn signature_help_for_call( res.signature.push('('); { if let Some((self_param, _)) = callable.receiver_param(db) { - format_to!(res.signature, "{}", self_param.display(db, edition)) + format_to!(res.signature, "{}", self_param.display(db, display_target)) } let mut buf = String::new(); for (idx, p) in callable.params().into_iter().enumerate() { @@ -242,9 +246,9 @@ fn signature_help_for_call( // (see FIXME in tests::impl_trait) and falling back on any unknowns. match (p.ty().contains_unknown(), fn_params.as_deref()) { (true, Some(fn_params)) => { - format_to!(buf, "{}", fn_params[idx].ty().display(db, edition)) + format_to!(buf, "{}", fn_params[idx].ty().display(db, display_target)) } - _ => format_to!(buf, "{}", p.ty().display(db, edition)), + _ => format_to!(buf, "{}", p.ty().display(db, display_target)), } res.push_call_param(&buf); } @@ -253,7 +257,7 @@ fn signature_help_for_call( let mut render = |ret_type: hir::Type| { if !ret_type.is_unit() { - format_to!(res.signature, " -> {}", ret_type.display(db, edition)); + format_to!(res.signature, " -> {}", ret_type.display(db, display_target)); } }; match callable.kind() { @@ -274,6 +278,7 @@ fn signature_help_for_generics( arg_list: ast::GenericArgList, token: SyntaxToken, edition: Edition, + display_target: DisplayTarget, ) -> Option { let (generics_def, mut active_parameter, first_arg_is_non_lifetime, variant) = generic_def_for_node(sema, &arg_list, &token)?; @@ -345,7 +350,7 @@ fn signature_help_for_generics( } buf.clear(); - format_to!(buf, "{}", param.display(db, edition)); + format_to!(buf, "{}", param.display(db, display_target)); res.push_generic_param(&buf); } if let hir::GenericDef::Trait(tr) = generics_def { @@ -400,6 +405,7 @@ fn signature_help_for_record_lit( record: ast::RecordExpr, token: SyntaxToken, edition: Edition, + display_target: DisplayTarget, ) -> Option { signature_help_for_record_( sema, @@ -412,6 +418,7 @@ fn signature_help_for_record_lit( .map(|(field, _, ty)| (field, ty)), token, edition, + display_target, ) } @@ -420,6 +427,7 @@ fn signature_help_for_record_pat( record: ast::RecordPat, token: SyntaxToken, edition: Edition, + display_target: DisplayTarget, ) -> Option { signature_help_for_record_( sema, @@ -431,6 +439,7 @@ fn signature_help_for_record_pat( .filter_map(|field| sema.resolve_record_pat_field(&field)), token, edition, + display_target, ) } @@ -439,6 +448,7 @@ fn signature_help_for_tuple_struct_pat( pat: ast::TupleStructPat, token: SyntaxToken, edition: Edition, + display_target: DisplayTarget, ) -> Option { let path = pat.path()?; let path_res = sema.resolve_path(&path)?; @@ -484,7 +494,7 @@ fn signature_help_for_tuple_struct_pat( token, pat.fields(), fields.into_iter().map(|it| it.ty(db)), - edition, + display_target, )) } @@ -492,7 +502,7 @@ fn signature_help_for_tuple_pat( sema: &Semantics<'_, RootDatabase>, pat: ast::TuplePat, token: SyntaxToken, - edition: Edition, + display_target: DisplayTarget, ) -> Option { let db = sema.db; let field_pats = pat.fields(); @@ -512,7 +522,7 @@ fn signature_help_for_tuple_pat( token, field_pats, fields.into_iter(), - edition, + display_target, )) } @@ -520,7 +530,7 @@ fn signature_help_for_tuple_expr( sema: &Semantics<'_, RootDatabase>, expr: ast::TupleExpr, token: SyntaxToken, - edition: Edition, + display_target: DisplayTarget, ) -> Option { let active_parameter = Some( expr.syntax() @@ -542,7 +552,7 @@ fn signature_help_for_tuple_expr( let fields = expr.original.tuple_fields(db); let mut buf = String::new(); for ty in fields { - format_to!(buf, "{}", ty.display_truncated(db, Some(20), edition)); + format_to!(buf, "{}", ty.display_truncated(db, Some(20), display_target)); res.push_call_param(&buf); buf.clear(); } @@ -557,6 +567,7 @@ fn signature_help_for_record_( fields2: impl Iterator, token: SyntaxToken, edition: Edition, + display_target: DisplayTarget, ) -> Option { let active_parameter = field_list_children .filter_map(NodeOrToken::into_token) @@ -617,7 +628,7 @@ fn signature_help_for_record_( buf, "{}: {}", name.display(db, edition), - ty.display_truncated(db, Some(20), edition) + ty.display_truncated(db, Some(20), display_target) ); res.push_record_field(&buf); buf.clear(); @@ -632,7 +643,7 @@ fn signature_help_for_record_( buf, "{}: {}", name.display(db, edition), - field.ty(db).display_truncated(db, Some(20), edition) + field.ty(db).display_truncated(db, Some(20), display_target) ); res.push_record_field(&buf); buf.clear(); @@ -648,7 +659,7 @@ fn signature_help_for_tuple_pat_ish( token: SyntaxToken, mut field_pats: AstChildren, fields: impl ExactSizeIterator, - edition: Edition, + display_target: DisplayTarget, ) -> SignatureHelp { let rest_pat = field_pats.find(|it| matches!(it, ast::Pat::RestPat(_))); let is_left_of_rest_pat = @@ -675,7 +686,7 @@ fn signature_help_for_tuple_pat_ish( let mut buf = String::new(); for ty in fields { - format_to!(buf, "{}", ty.display_truncated(db, Some(20), edition)); + format_to!(buf, "{}", ty.display_truncated(db, Some(20), display_target)); res.push_call_param(&buf); buf.clear(); } diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 41957bad7e07..332aecf1e3cc 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -3,7 +3,7 @@ use hir::{db::HirDatabase, Crate, HirFileIdExt, Module, Semantics}; use ide_db::{ - base_db::{SourceRootDatabase, VfsPath}, + base_db::{SourceDatabase, SourceRootDatabase, VfsPath}, defs::Definition, documentation::Documentation, famous_defs::FamousDefs, @@ -118,7 +118,11 @@ fn documentation_for_definition( def.docs( sema.db, famous_defs.as_ref(), - def.krate(sema.db).map(|it| it.edition(sema.db)).unwrap_or(Edition::CURRENT), + def.krate(sema.db) + .unwrap_or_else(|| { + (*sema.db.crate_graph().crates_in_topological_order().last().unwrap()).into() + }) + .to_display_target(sema.db), ) } @@ -173,6 +177,7 @@ impl StaticIndex<'_> { let root = sema.parse_guess_edition(file_id).syntax().clone(); let edition = sema.attach_first_edition(file_id).map(|it| it.edition()).unwrap_or(Edition::CURRENT); + let display_target = sema.first_crate_or_default(file_id).to_display_target(self.db); let tokens = root.descendants_with_tokens().filter_map(|it| match it { syntax::NodeOrToken::Node(_) => None, syntax::NodeOrToken::Token(it) => Some(it), @@ -213,6 +218,7 @@ impl StaticIndex<'_> { false, &hover_config, edition, + display_target, )), definition: def.try_to_nav(self.db).map(UpmappingResult::call_site).map(|it| { FileRange { file_id: it.file_id, range: it.focus_or_full_range() } @@ -222,7 +228,7 @@ impl StaticIndex<'_> { display_name: def .name(self.db) .map(|name| name.display(self.db, edition).to_string()), - signature: Some(def.label(self.db, edition)), + signature: Some(def.label(self.db, display_target)), kind: def_to_kind(self.db, def), }); self.def_map.insert(def, it); diff --git a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs index edb83bc4eac4..34bca7bce12c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs @@ -1,12 +1,11 @@ use std::fmt; -use hir::{Field, HirDisplay, Layout, Semantics, Type}; +use hir::{DisplayTarget, Field, HirDisplay, Layout, Semantics, Type}; use ide_db::{ defs::Definition, helpers::{get_definition, pick_best_token}, RootDatabase, }; -use span::Edition; use syntax::{AstNode, SyntaxKind}; use crate::FilePosition; @@ -84,10 +83,7 @@ pub(crate) fn view_memory_layout( ) -> Option { let sema = Semantics::new(db); let file = sema.parse_guess_edition(position.file_id); - let edition = sema - .attach_first_edition(position.file_id) - .map(|it| it.edition()) - .unwrap_or(Edition::CURRENT); + let display_target = sema.first_crate_or_default(position.file_id).to_display_target(db); let token = pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind { SyntaxKind::IDENT => 3, @@ -114,7 +110,7 @@ pub(crate) fn view_memory_layout( ty: &Type, layout: &Layout, parent_idx: usize, - edition: Edition, + display_target: DisplayTarget, ) { let mut fields = ty .fields(db) @@ -145,7 +141,7 @@ pub(crate) fn view_memory_layout( if let Ok(child_layout) = child_ty.layout(db) { nodes.push(MemoryLayoutNode { item_name: field.name(db), - typename: child_ty.display(db, edition).to_string(), + typename: child_ty.display(db, display_target).to_string(), size: child_layout.size(), alignment: child_layout.align(), offset: match *field { @@ -161,7 +157,7 @@ pub(crate) fn view_memory_layout( item_name: field.name(db) + format!("(no layout data: {:?})", child_ty.layout(db).unwrap_err()) .as_ref(), - typename: child_ty.display(db, edition).to_string(), + typename: child_ty.display(db, display_target).to_string(), size: 0, offset: 0, alignment: 0, @@ -174,7 +170,7 @@ pub(crate) fn view_memory_layout( for (i, (_, child_ty)) in fields.iter().enumerate() { if let Ok(child_layout) = child_ty.layout(db) { - read_layout(nodes, db, child_ty, &child_layout, children_start + i, edition); + read_layout(nodes, db, child_ty, &child_layout, children_start + i, display_target); } } } @@ -192,7 +188,7 @@ pub(crate) fn view_memory_layout( def => def.name(db).map(|n| n.as_str().to_owned()).unwrap_or("[ROOT]".to_owned()), }; - let typename = ty.display(db, edition).to_string(); + let typename = ty.display(db, display_target).to_string(); let mut nodes = vec![MemoryLayoutNode { item_name, @@ -204,7 +200,7 @@ pub(crate) fn view_memory_layout( children_start: -1, children_len: 0, }]; - read_layout(&mut nodes, db, &ty, &layout, 0, edition); + read_layout(&mut nodes, db, &ty, &layout, 0, display_target); RecursiveMemoryLayout { nodes } }) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index b9e4457fc98d..dee76ee15c3d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -390,6 +390,8 @@ impl flags::AnalysisStats { for &file_id in &file_ids { let sema = hir::Semantics::new(db); + let display_target = + sema.first_crate_or_default(file_id.file_id()).to_display_target(db); let parse = sema.parse_guess_edition(file_id.into()); let file_txt = db.file_text(file_id.into()); @@ -467,7 +469,7 @@ impl flags::AnalysisStats { prefer_absolute: false, allow_unstable: true, }, - Edition::LATEST, + display_target, ) .unwrap(); syntax_hit_found |= trim(&original_text) == trim(&generated); @@ -641,6 +643,7 @@ impl flags::AnalysisStats { for &body_id in bodies { let name = body_id.name(db).unwrap_or_else(Name::missing); let module = body_id.module(db); + let display_target = module.krate().to_display_target(db); let full_name = move || { module .krate() @@ -739,12 +742,12 @@ impl flags::AnalysisStats { start.col, end.line + 1, end.col, - ty.display(db, Edition::LATEST) + ty.display(db, display_target) )); } else { bar.println(format!( "unknown location: {}", - ty.display(db, Edition::LATEST) + ty.display(db, display_target) )); } } @@ -752,7 +755,7 @@ impl flags::AnalysisStats { println!( r#"{},type,"{}""#, location_csv_expr(db, vfs, &sm(), expr_id), - ty.display(db, Edition::LATEST) + ty.display(db, display_target) ); } if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { @@ -767,15 +770,15 @@ impl flags::AnalysisStats { start.col, end.line + 1, end.col, - mismatch.expected.display(db, Edition::LATEST), - mismatch.actual.display(db, Edition::LATEST) + mismatch.expected.display(db, display_target), + mismatch.actual.display(db, display_target) )); } else { bar.println(format!( "{}: Expected {}, got {}", name.display(db, Edition::LATEST), - mismatch.expected.display(db, Edition::LATEST), - mismatch.actual.display(db, Edition::LATEST) + mismatch.expected.display(db, display_target), + mismatch.actual.display(db, display_target) )); } } @@ -783,8 +786,8 @@ impl flags::AnalysisStats { println!( r#"{},mismatch,"{}","{}""#, location_csv_expr(db, vfs, &sm(), expr_id), - mismatch.expected.display(db, Edition::LATEST), - mismatch.actual.display(db, Edition::LATEST) + mismatch.expected.display(db, display_target), + mismatch.actual.display(db, display_target) ); } } @@ -843,12 +846,12 @@ impl flags::AnalysisStats { start.col, end.line + 1, end.col, - ty.display(db, Edition::LATEST) + ty.display(db, display_target) )); } else { bar.println(format!( "unknown location: {}", - ty.display(db, Edition::LATEST) + ty.display(db, display_target) )); } } @@ -856,7 +859,7 @@ impl flags::AnalysisStats { println!( r#"{},type,"{}""#, location_csv_pat(db, vfs, &sm(), pat_id), - ty.display(db, Edition::LATEST) + ty.display(db, display_target) ); } if let Some(mismatch) = inference_result.type_mismatch_for_pat(pat_id) { @@ -870,15 +873,15 @@ impl flags::AnalysisStats { start.col, end.line + 1, end.col, - mismatch.expected.display(db, Edition::LATEST), - mismatch.actual.display(db, Edition::LATEST) + mismatch.expected.display(db, display_target), + mismatch.actual.display(db, display_target) )); } else { bar.println(format!( "{}: Expected {}, got {}", name.display(db, Edition::LATEST), - mismatch.expected.display(db, Edition::LATEST), - mismatch.actual.display(db, Edition::LATEST) + mismatch.expected.display(db, display_target), + mismatch.actual.display(db, display_target) )); } } @@ -886,8 +889,8 @@ impl flags::AnalysisStats { println!( r#"{},mismatch,"{}","{}""#, location_csv_pat(db, vfs, &sm(), pat_id), - mismatch.expected.display(db, Edition::LATEST), - mismatch.actual.display(db, Edition::LATEST) + mismatch.expected.display(db, display_target), + mismatch.actual.display(db, display_target) ); } } From 92de0ffd5cf7a9cf35618a0f66c20b55918c69d6 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 27 Feb 2025 14:30:10 +0200 Subject: [PATCH 738/991] Use correct crate for trait env in `render_const_scalar()` --- src/tools/rust-analyzer/crates/hir-ty/src/display.rs | 5 +---- src/tools/rust-analyzer/crates/ide/src/hover/tests.rs | 7 ++++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 41152d90220e..95ce36390d33 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -680,10 +680,7 @@ fn render_const_scalar( memory_map: &MemoryMap, ty: &Ty, ) -> Result<(), HirDisplayError> { - // FIXME: We need to get krate from the final callers of the hir display - // infrastructure and have it here as a field on `f`. - let trait_env = - TraitEnvironment::empty(*f.db.crate_graph().crates_in_topological_order().last().unwrap()); + let trait_env = TraitEnvironment::empty(f.krate()); let ty = normalize(f.db, trait_env.clone(), ty.clone()); match ty.kind(Interner) { TyKind::Scalar(s) => match s { diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 964b1d7eb7dc..6b470d921f7a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -10950,8 +10950,12 @@ pub struct ManuallyDrop$0 { #[test] fn projection_const() { + // This uses two crates, which have *no* relation between them, to test another thing: + // `render_const_scalar()` used to just use the last crate for the trait env, which will + // fail in this scenario. check( r#" +//- /foo.rs crate:foo pub trait PublicFlags { type Internal; } @@ -10967,12 +10971,13 @@ pub struct InternalBitFlags; impl PublicFlags for NoteDialects { type Internal = InternalBitFlags; } +//- /bar.rs crate:bar "#, expect![[r#" *CLAP* ```rust - ra_test_fixture::NoteDialects + foo::NoteDialects ``` ```rust From 5c1733e4f4d51d7887a117a06ac4c465d55c3b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 5 Mar 2025 13:14:08 +0100 Subject: [PATCH 739/991] Break critical edges in inline asm before code generation An inline asm terminator defines outputs along its target edges -- a fallthrough target and labeled targets. Code generation implements this by inserting code directly into the target blocks. This approach works only if the target blocks don't have other predecessors. Establish required invariant by extending existing code that breaks critical edges before code generation. --- .../src/add_call_guards.rs | 26 +++++++++++++ tests/codegen/asm/critical.rs | 37 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 tests/codegen/asm/critical.rs diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index c64bb30fa215..ce7d7a435c84 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -65,6 +65,32 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { // It's a critical edge, break it *destination = new_block(source_info, block.is_cleanup, *destination); } + Some(Terminator { + kind: + TerminatorKind::InlineAsm { + asm_macro: InlineAsmMacro::Asm, + ref mut targets, + ref operands, + unwind, + .. + }, + source_info, + }) if self == &CriticalCallEdges => { + let has_outputs = operands.iter().any(|op| { + matches!(op, InlineAsmOperand::InOut { .. } | InlineAsmOperand::Out { .. }) + }); + let has_labels = + operands.iter().any(|op| matches!(op, InlineAsmOperand::Label { .. })); + let invoke = + matches!(unwind, UnwindAction::Cleanup(_) | UnwindAction::Terminate(_)); + if has_outputs && (has_labels || invoke) { + for target in targets.iter_mut() { + if pred_count[*target] > 1 { + *target = new_block(source_info, block.is_cleanup, *target); + } + } + } + } _ => {} } } diff --git a/tests/codegen/asm/critical.rs b/tests/codegen/asm/critical.rs new file mode 100644 index 000000000000..8c039900cab3 --- /dev/null +++ b/tests/codegen/asm/critical.rs @@ -0,0 +1,37 @@ +//@ only-x86_64 +//@ compile-flags: -C no-prepopulate-passes +#![feature(asm_goto)] +#![feature(asm_goto_with_outputs)] +#![crate_type = "lib"] +use std::arch::asm; + +// Regression test for #137867. Check that critical edges have been split before code generation, +// and so all stores to the asm output occur on disjoint paths without any of them jumping to +// another callbr label. +// +// CHECK-LABEL: @f( +// CHECK: [[OUT:%.*]] = callbr i32 asm +// CHECK-NEXT: to label %[[BB0:.*]] [label %[[BB1:.*]], label %[[BB2:.*]]], +// CHECK: [[BB1]]: +// CHECK-NEXT: store i32 [[OUT]], ptr %a +// CHECK-NEXT: br label %[[BBR:.*]] +// CHECK: [[BB2]]: +// CHECK-NEXT: store i32 [[OUT]], ptr %a +// CHECK-NEXT: br label %[[BBR]] +// CHECK: [[BB0]]: +// CHECK-NEXT: store i32 [[OUT]], ptr %a +// CHECK-NEXT: br label %[[BBR]] +// CHECK: [[BBR]]: +// CHECK-NEXT: [[RET:%.*]] = load i32, ptr %a +// CHECK-NEXT: ret i32 [[RET]] +#[unsafe(no_mangle)] +pub unsafe fn f(mut a: u32) -> u32 { + asm!( + "jmp {} + jmp {}", + label {}, + label {}, + inout("eax") a, + ); + a +} From 02d7fc167fea5013e2300b1c5a3ca75f7a048664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 6 Mar 2025 00:00:00 +0000 Subject: [PATCH 740/991] Factor out check whether an unwind action generates invoke --- .../rustc_mir_transform/src/add_call_guards.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index ce7d7a435c84..bc335cee1479 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -57,10 +57,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { kind: TerminatorKind::Call { target: Some(ref mut destination), unwind, .. }, source_info, }) if pred_count[*destination] > 1 - && (matches!( - unwind, - UnwindAction::Cleanup(_) | UnwindAction::Terminate(_) - ) || self == &AllCallEdges) => + && (generates_invoke(unwind) || self == &AllCallEdges) => { // It's a critical edge, break it *destination = new_block(source_info, block.is_cleanup, *destination); @@ -81,9 +78,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { }); let has_labels = operands.iter().any(|op| matches!(op, InlineAsmOperand::Label { .. })); - let invoke = - matches!(unwind, UnwindAction::Cleanup(_) | UnwindAction::Terminate(_)); - if has_outputs && (has_labels || invoke) { + if has_outputs && (has_labels || generates_invoke(unwind)) { for target in targets.iter_mut() { if pred_count[*target] > 1 { *target = new_block(source_info, block.is_cleanup, *target); @@ -104,3 +99,11 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { true } } + +/// Returns true if this unwind action is code generated as an invoke as opposed to a call. +fn generates_invoke(unwind: UnwindAction) -> bool { + match unwind { + UnwindAction::Continue | UnwindAction::Unreachable => false, + UnwindAction::Cleanup(_) | UnwindAction::Terminate(_) => true, + } +} From 0bd3229ef2714487b2b697334499f3e85ea9b611 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 2 Feb 2025 01:49:04 +0200 Subject: [PATCH 741/991] Warn the user when a rename will change the meaning of the program Specifically, when a rename of a local will change some code that refers it to refer another local, or some code that refer another local to refer to it. We do it by introducing a dummy edit with an annotation. I'm not a fond of this approach, but I don't think LSP has a better way. --- .../rust-analyzer/crates/hir-def/src/path.rs | 16 +- .../crates/hir-def/src/resolver.rs | 166 +++++++++++++++--- .../rust-analyzer/crates/hir/src/semantics.rs | 95 +++++++++- .../crates/ide-assists/src/tests.rs | 30 ++++ .../crates/ide-completion/src/render.rs | 2 + .../rust-analyzer/crates/ide-db/src/rename.rs | 36 +++- .../crates/ide-db/src/source_change.rs | 45 +++-- .../crates/ide-db/src/text_edit.rs | 15 +- .../rust-analyzer/crates/ide/src/rename.rs | 81 +++++++++ src/tools/rust-analyzer/crates/ide/src/ssr.rs | 7 + .../rust-analyzer/src/handlers/request.rs | 21 ++- .../crates/rust-analyzer/src/lsp/to_proto.rs | 54 +++++- 12 files changed, 509 insertions(+), 59 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path.rs b/src/tools/rust-analyzer/crates/hir-def/src/path.rs index e6c2504d07a5..713e7389736a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path.rs @@ -57,7 +57,7 @@ pub enum Path { /// or type anchor, it is `Path::Normal` with the generics filled with `None` even if there are none (practically /// this is not a problem since many more paths have generics than a type anchor). BarePath(Interned), - /// `Path::Normal` may have empty generics and type anchor (but generic args will be filled with `None`). + /// `Path::Normal` will always have either generics or type anchor. Normal(NormalPath), /// A link to a lang item. It is used in desugaring of things like `it?`. We can show these /// links via a normal path since they might be private and not accessible in the usage place. @@ -208,11 +208,15 @@ impl Path { mod_path.segments()[..mod_path.segments().len() - 1].iter().cloned(), )); let qualifier_generic_args = &generic_args[..generic_args.len() - 1]; - Some(Path::Normal(NormalPath::new( - type_anchor, - qualifier_mod_path, - qualifier_generic_args.iter().cloned(), - ))) + if type_anchor.is_none() && qualifier_generic_args.iter().all(|it| it.is_none()) { + Some(Path::BarePath(qualifier_mod_path)) + } else { + Some(Path::Normal(NormalPath::new( + type_anchor, + qualifier_mod_path, + qualifier_generic_args.iter().cloned(), + ))) + } } Path::LangItem(..) => None, } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index e5774b48044f..a2e6e4cc0436 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -3,10 +3,11 @@ use std::{fmt, iter, mem}; use base_db::CrateId; use hir_expand::{name::Name, MacroDefId}; -use intern::sym; +use intern::{sym, Symbol}; use itertools::Itertools as _; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; +use span::SyntaxContextId; use triomphe::Arc; use crate::{ @@ -343,15 +344,7 @@ impl Resolver { } if n_segments <= 1 { - let mut hygiene_info = if !hygiene_id.is_root() { - let ctx = hygiene_id.lookup(db); - ctx.outer_expn.map(|expansion| { - let expansion = db.lookup_intern_macro_call(expansion); - (ctx.parent, expansion.def) - }) - } else { - None - }; + let mut hygiene_info = hygiene_info(db, hygiene_id); for scope in self.scopes() { match scope { Scope::ExprScope(scope) => { @@ -371,19 +364,7 @@ impl Resolver { } } Scope::MacroDefScope(macro_id) => { - if let Some((parent_ctx, label_macro_id)) = hygiene_info { - if label_macro_id == **macro_id { - // A macro is allowed to refer to variables from before its declaration. - // Therefore, if we got to the rib of its declaration, give up its hygiene - // and use its parent expansion. - let parent_ctx = db.lookup_intern_syntax_context(parent_ctx); - hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent); - hygiene_info = parent_ctx.outer_expn.map(|expansion| { - let expansion = db.lookup_intern_macro_call(expansion); - (parent_ctx.parent, expansion.def) - }); - } - } + handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id) } Scope::GenericParams { params, def } => { if let Some(id) = params.find_const_by_name(first_name, *def) { @@ -730,6 +711,107 @@ impl Resolver { }) } + /// Checks if we rename `renamed` (currently named `current_name`) to `new_name`, will the meaning of this reference + /// (that contains `current_name` path) change from `renamed` to some another variable (returned as `Some`). + pub fn rename_will_conflict_with_another_variable( + &self, + db: &dyn DefDatabase, + current_name: &Name, + current_name_as_path: &ModPath, + mut hygiene_id: HygieneId, + new_name: &Symbol, + to_be_renamed: BindingId, + ) -> Option { + let mut hygiene_info = hygiene_info(db, hygiene_id); + let mut will_be_resolved_to = None; + for scope in self.scopes() { + match scope { + Scope::ExprScope(scope) => { + for entry in scope.expr_scopes.entries(scope.scope_id) { + if entry.hygiene() == hygiene_id { + if entry.binding() == to_be_renamed { + // This currently resolves to our renamed variable, now `will_be_resolved_to` + // contains `Some` if the meaning will change or `None` if not. + return will_be_resolved_to; + } else if entry.name().symbol() == new_name { + will_be_resolved_to = Some(entry.binding()); + } + } + } + } + Scope::MacroDefScope(macro_id) => { + handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id) + } + Scope::GenericParams { params, def } => { + if params.find_const_by_name(current_name, *def).is_some() { + // It does not resolve to our renamed variable. + return None; + } + } + Scope::AdtScope(_) | Scope::ImplDefScope(_) => continue, + Scope::BlockScope(m) => { + if m.resolve_path_in_value_ns(db, current_name_as_path).is_some() { + // It does not resolve to our renamed variable. + return None; + } + } + } + } + // It does not resolve to our renamed variable. + None + } + + /// Checks if we rename `renamed` to `name`, will the meaning of this reference (that contains `name` path) change + /// from some other variable (returned as `Some`) to `renamed`. + pub fn rename_will_conflict_with_renamed( + &self, + db: &dyn DefDatabase, + name: &Name, + name_as_path: &ModPath, + mut hygiene_id: HygieneId, + to_be_renamed: BindingId, + ) -> Option { + let mut hygiene_info = hygiene_info(db, hygiene_id); + let mut will_resolve_to_renamed = false; + for scope in self.scopes() { + match scope { + Scope::ExprScope(scope) => { + for entry in scope.expr_scopes.entries(scope.scope_id) { + if entry.binding() == to_be_renamed { + will_resolve_to_renamed = true; + } else if entry.hygiene() == hygiene_id && entry.name() == name { + if will_resolve_to_renamed { + // This will resolve to the renamed variable before it resolves to the original variable. + return Some(entry.binding()); + } else { + // This will resolve to the original variable. + return None; + } + } + } + } + Scope::MacroDefScope(macro_id) => { + handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id) + } + Scope::GenericParams { params, def } => { + if params.find_const_by_name(name, *def).is_some() { + // Here and below, it might actually resolve to our renamed variable - in which case it'll + // hide the generic parameter or some other thing (not a variable). We don't check for that + // because due to naming conventions, it is rare that variable will shadow a non-variable. + return None; + } + } + Scope::AdtScope(_) | Scope::ImplDefScope(_) => continue, + Scope::BlockScope(m) => { + if m.resolve_path_in_value_ns(db, name_as_path).is_some() { + return None; + } + } + } + } + None + } + /// `expr_id` is required to be an expression id that comes after the top level expression scope in the given resolver #[must_use] pub fn update_to_inner_scope( @@ -795,6 +877,44 @@ impl Resolver { } } +#[inline] +fn handle_macro_def_scope( + db: &dyn DefDatabase, + hygiene_id: &mut HygieneId, + hygiene_info: &mut Option<(SyntaxContextId, MacroDefId)>, + macro_id: &MacroDefId, +) { + if let Some((parent_ctx, label_macro_id)) = hygiene_info { + if label_macro_id == macro_id { + // A macro is allowed to refer to variables from before its declaration. + // Therefore, if we got to the rib of its declaration, give up its hygiene + // and use its parent expansion. + let parent_ctx = db.lookup_intern_syntax_context(*parent_ctx); + *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent); + *hygiene_info = parent_ctx.outer_expn.map(|expansion| { + let expansion = db.lookup_intern_macro_call(expansion); + (parent_ctx.parent, expansion.def) + }); + } + } +} + +#[inline] +fn hygiene_info( + db: &dyn DefDatabase, + hygiene_id: HygieneId, +) -> Option<(SyntaxContextId, MacroDefId)> { + if !hygiene_id.is_root() { + let ctx = hygiene_id.lookup(db); + ctx.outer_expn.map(|expansion| { + let expansion = db.lookup_intern_macro_call(expansion); + (ctx.parent, expansion.def) + }) + } else { + None + } +} + pub struct UpdateGuard(usize); impl Resolver { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 1b8531209c1b..b0c2feaac1d1 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -12,8 +12,8 @@ use std::{ use either::Either; use hir_def::{ - expr_store::ExprOrPatSource, - hir::{Expr, ExprOrPatId}, + expr_store::{Body, ExprOrPatSource}, + hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, lower::LowerCtx, nameres::{MacroSubNs, ModuleOrigin}, path::ModPath, @@ -629,6 +629,31 @@ impl<'db> SemanticsImpl<'db> { ) } + /// Checks if renaming `renamed` to `new_name` may introduce conflicts with other locals, + /// and returns the conflicting locals. + pub fn rename_conflicts(&self, to_be_renamed: &Local, new_name: &str) -> Vec { + let body = self.db.body(to_be_renamed.parent); + let resolver = to_be_renamed.parent.resolver(self.db.upcast()); + let starting_expr = + body.binding_owners.get(&to_be_renamed.binding_id).copied().unwrap_or(body.body_expr); + let mut visitor = RenameConflictsVisitor { + body: &body, + conflicts: FxHashSet::default(), + db: self.db, + new_name: Symbol::intern(new_name), + old_name: to_be_renamed.name(self.db).symbol().clone(), + owner: to_be_renamed.parent, + to_be_renamed: to_be_renamed.binding_id, + resolver, + }; + visitor.rename_conflicts(starting_expr); + visitor + .conflicts + .into_iter() + .map(|binding_id| Local { parent: to_be_renamed.parent, binding_id }) + .collect() + } + /// Retrieves all the formatting parts of the format_args! (or `asm!`) template string. pub fn as_format_args_parts( &self, @@ -2094,3 +2119,69 @@ impl ops::Deref for VisibleTraits { &self.0 } } + +struct RenameConflictsVisitor<'a> { + db: &'a dyn HirDatabase, + owner: DefWithBodyId, + resolver: Resolver, + body: &'a Body, + to_be_renamed: BindingId, + new_name: Symbol, + old_name: Symbol, + conflicts: FxHashSet, +} + +impl RenameConflictsVisitor<'_> { + fn resolve_path(&mut self, node: ExprOrPatId, path: &Path) { + if let Path::BarePath(path) = path { + if let Some(name) = path.as_ident() { + if *name.symbol() == self.new_name { + if let Some(conflicting) = self.resolver.rename_will_conflict_with_renamed( + self.db.upcast(), + name, + path, + self.body.expr_or_pat_path_hygiene(node), + self.to_be_renamed, + ) { + self.conflicts.insert(conflicting); + } + } else if *name.symbol() == self.old_name { + if let Some(conflicting) = + self.resolver.rename_will_conflict_with_another_variable( + self.db.upcast(), + name, + path, + self.body.expr_or_pat_path_hygiene(node), + &self.new_name, + self.to_be_renamed, + ) + { + self.conflicts.insert(conflicting); + } + } + } + } + } + + fn rename_conflicts(&mut self, expr: ExprId) { + match &self.body[expr] { + Expr::Path(path) => { + let guard = self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr); + self.resolve_path(expr.into(), path); + self.resolver.reset_to_guard(guard); + } + &Expr::Assignment { target, .. } => { + let guard = self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr); + self.body.walk_pats(target, &mut |pat| { + if let Pat::Path(path) = &self.body[pat] { + self.resolve_path(pat.into(), path); + } + }); + self.resolver.reset_to_guard(guard); + } + _ => {} + } + + self.body.walk_child_exprs(expr, |expr| self.rename_conflicts(expr)); + } +} diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index 11aeb21c77e5..7d7012c46222 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -710,18 +710,22 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "let", delete: 45..47, + annotation: None, }, Indel { insert: "var_name", delete: 48..60, + annotation: None, }, Indel { insert: "=", delete: 61..81, + annotation: None, }, Indel { insert: "5;\n if let 2..6 = var_name {\n true\n } else {\n false\n }", delete: 82..108, + annotation: None, }, ], }, @@ -739,6 +743,8 @@ pub fn test_some_range(a: int) -> bool { }, file_system_edits: [], is_snippet: true, + annotations: {}, + next_annotation_id: 0, }, ), command: Some( @@ -839,18 +845,22 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "let", delete: 45..47, + annotation: None, }, Indel { insert: "var_name", delete: 48..60, + annotation: None, }, Indel { insert: "=", delete: 61..81, + annotation: None, }, Indel { insert: "5;\n if let 2..6 = var_name {\n true\n } else {\n false\n }", delete: 82..108, + annotation: None, }, ], }, @@ -868,6 +878,8 @@ pub fn test_some_range(a: int) -> bool { }, file_system_edits: [], is_snippet: true, + annotations: {}, + next_annotation_id: 0, }, ), command: Some( @@ -902,22 +914,27 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "const", delete: 45..47, + annotation: None, }, Indel { insert: "VAR_NAME:", delete: 48..60, + annotation: None, }, Indel { insert: "i32", delete: 61..81, + annotation: None, }, Indel { insert: "=", delete: 82..86, + annotation: None, }, Indel { insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", delete: 87..108, + annotation: None, }, ], }, @@ -935,6 +952,8 @@ pub fn test_some_range(a: int) -> bool { }, file_system_edits: [], is_snippet: true, + annotations: {}, + next_annotation_id: 0, }, ), command: Some( @@ -969,22 +988,27 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "static", delete: 45..47, + annotation: None, }, Indel { insert: "VAR_NAME:", delete: 48..60, + annotation: None, }, Indel { insert: "i32", delete: 61..81, + annotation: None, }, Indel { insert: "=", delete: 82..86, + annotation: None, }, Indel { insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", delete: 87..108, + annotation: None, }, ], }, @@ -1002,6 +1026,8 @@ pub fn test_some_range(a: int) -> bool { }, file_system_edits: [], is_snippet: true, + annotations: {}, + next_annotation_id: 0, }, ), command: Some( @@ -1036,10 +1062,12 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "fun_name()", delete: 59..60, + annotation: None, }, Indel { insert: "\n\nfn fun_name() -> i32 {\n 5\n}", delete: 110..110, + annotation: None, }, ], }, @@ -1057,6 +1085,8 @@ pub fn test_some_range(a: int) -> bool { }, file_system_edits: [], is_snippet: true, + annotations: {}, + next_annotation_id: 0, }, ), command: None, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 4f6c4cb66393..af644d0fda78 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -2686,10 +2686,12 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 } Indel { insert: "(", delete: 107..107, + annotation: None, }, Indel { insert: "qux)()", delete: 109..110, + annotation: None, }, ], }, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index 59914bedde43..1633065f6521 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -22,7 +22,10 @@ //! Our current behavior is ¯\_(ツ)_/¯. use std::fmt; -use crate::text_edit::{TextEdit, TextEditBuilder}; +use crate::{ + source_change::ChangeAnnotation, + text_edit::{TextEdit, TextEditBuilder}, +}; use base_db::AnchoredPathBuf; use either::Either; use hir::{FieldSource, FileRange, HirFileIdExt, InFile, ModuleSource, Semantics}; @@ -365,10 +368,12 @@ fn rename_reference( })); let mut insert_def_edit = |def| { - let (file_id, edit) = source_edit_from_def(sema, def, new_name)?; + let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?; source_change.insert_source_edit(file_id, edit); Ok(()) }; + // This needs to come after the references edits, because we change the annotation of existing edits + // if a conflict is detected. insert_def_edit(def)?; Ok(source_change) } @@ -537,6 +542,7 @@ fn source_edit_from_def( sema: &Semantics<'_, RootDatabase>, def: Definition, new_name: &str, + source_change: &mut SourceChange, ) -> Result<(FileId, TextEdit)> { let new_name_edition_aware = |new_name: &str, file_id: EditionedFileId| { if is_raw_identifier(new_name, file_id.edition()) { @@ -548,6 +554,23 @@ fn source_edit_from_def( let mut edit = TextEdit::builder(); if let Definition::Local(local) = def { let mut file_id = None; + + let conflict_annotation = if !sema.rename_conflicts(&local, new_name).is_empty() { + Some( + source_change.insert_annotation(ChangeAnnotation { + label: "This rename will change the program's meaning".to_owned(), + needs_confirmation: true, + description: Some( + "Some variable(s) will shadow the renamed variable \ + or be shadowed by it if the rename is performed" + .to_owned(), + ), + }), + ) + } else { + None + }; + for source in local.sources(sema.db) { let source = match source.source.clone().original_ast_node_rooted(sema.db) { Some(source) => source, @@ -611,8 +634,15 @@ fn source_edit_from_def( } } } + let mut edit = edit.finish(); + + for (edit, _) in source_change.source_file_edits.values_mut() { + edit.set_annotation(conflict_annotation); + } + edit.set_annotation(conflict_annotation); + let Some(file_id) = file_id else { bail!("No file available to rename") }; - return Ok((EditionedFileId::file_id(file_id), edit.finish())); + return Ok((EditionedFileId::file_id(file_id), edit)); } let FileRange { file_id, range } = def .range_for_rename(sema) diff --git a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs index 34642d7eaf9d..b4d0b0dc9f0a 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs @@ -3,7 +3,7 @@ //! //! It can be viewed as a dual for `Change`. -use std::{collections::hash_map::Entry, iter, mem}; +use std::{collections::hash_map::Entry, fmt, iter, mem}; use crate::text_edit::{TextEdit, TextEditBuilder}; use crate::{assists::Command, syntax_helpers::tree_diff::diff, SnippetCap}; @@ -18,23 +18,33 @@ use syntax::{ AstNode, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize, }; +/// An annotation ID associated with an indel, to describe changes. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct ChangeAnnotationId(u32); + +impl fmt::Display for ChangeAnnotationId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } +} + +#[derive(Debug, Clone)] +pub struct ChangeAnnotation { + pub label: String, + pub needs_confirmation: bool, + pub description: Option, +} + #[derive(Default, Debug, Clone)] pub struct SourceChange { pub source_file_edits: IntMap)>, pub file_system_edits: Vec, pub is_snippet: bool, + pub annotations: FxHashMap, + next_annotation_id: u32, } impl SourceChange { - /// Creates a new SourceChange with the given label - /// from the edits. - pub fn from_edits( - source_file_edits: IntMap)>, - file_system_edits: Vec, - ) -> Self { - SourceChange { source_file_edits, file_system_edits, is_snippet: false } - } - pub fn from_text_edit(file_id: impl Into, edit: TextEdit) -> Self { SourceChange { source_file_edits: iter::once((file_id.into(), (edit, None))).collect(), @@ -42,6 +52,13 @@ impl SourceChange { } } + pub fn insert_annotation(&mut self, annotation: ChangeAnnotation) -> ChangeAnnotationId { + let id = ChangeAnnotationId(self.next_annotation_id); + self.next_annotation_id += 1; + self.annotations.insert(id, annotation); + id + } + /// Inserts a [`TextEdit`] for the given [`FileId`]. This properly handles merging existing /// edits for a file if some already exist. pub fn insert_source_edit(&mut self, file_id: impl Into, edit: TextEdit) { @@ -120,7 +137,12 @@ impl From> for SourceChange { fn from(source_file_edits: IntMap) -> SourceChange { let source_file_edits = source_file_edits.into_iter().map(|(file_id, edit)| (file_id, (edit, None))).collect(); - SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false } + SourceChange { + source_file_edits, + file_system_edits: Vec::new(), + is_snippet: false, + ..SourceChange::default() + } } } @@ -482,6 +504,7 @@ impl From for SourceChange { source_file_edits: Default::default(), file_system_edits: vec![edit], is_snippet: false, + ..SourceChange::default() } } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/text_edit.rs b/src/tools/rust-analyzer/crates/ide-db/src/text_edit.rs index 0c675f0619f2..b59010f2f8c8 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/text_edit.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/text_edit.rs @@ -8,6 +8,8 @@ use itertools::Itertools; pub use span::{TextRange, TextSize}; use std::cmp::max; +use crate::source_change::ChangeAnnotationId; + /// `InsertDelete` -- a single "atomic" change to text /// /// Must not overlap with other `InDel`s @@ -16,6 +18,7 @@ pub struct Indel { pub insert: String, /// Refers to offsets in the original text pub delete: TextRange, + pub annotation: Option, } #[derive(Default, Debug, Clone)] @@ -37,7 +40,7 @@ impl Indel { Indel::replace(range, String::new()) } pub fn replace(range: TextRange, replace_with: String) -> Indel { - Indel { delete: range, insert: replace_with } + Indel { delete: range, insert: replace_with, annotation: None } } pub fn apply(&self, text: &mut String) { @@ -138,6 +141,14 @@ impl TextEdit { } Some(res) } + + pub fn set_annotation(&mut self, annotation: Option) { + if annotation.is_some() { + for indel in &mut self.indels { + indel.annotation = annotation; + } + } + } } impl IntoIterator for TextEdit { @@ -180,7 +191,7 @@ impl TextEditBuilder { pub fn invalidates_offset(&self, offset: TextSize) -> bool { self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset)) } - fn indel(&mut self, indel: Indel) { + pub fn indel(&mut self, indel: Indel) { self.indels.push(indel); if self.indels.len() <= 16 { assert_disjoint_or_equal(&mut self.indels); diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index 3e8295e3f08e..d0e1c2097a7a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -446,6 +446,7 @@ mod tests { use expect_test::{expect, Expect}; use ide_db::source_change::SourceChange; use ide_db::text_edit::TextEdit; + use itertools::Itertools; use stdx::trim_indent; use test_utils::assert_eq_text; @@ -496,6 +497,31 @@ mod tests { }; } + #[track_caller] + fn check_conflicts(new_name: &str, #[rust_analyzer::rust_fixture] ra_fixture: &str) { + let (analysis, position, conflicts) = fixture::annotations(ra_fixture); + let source_change = analysis.rename(position, new_name).unwrap().unwrap(); + let expected_conflicts = conflicts + .into_iter() + .map(|(file_range, _)| (file_range.file_id, file_range.range)) + .sorted_unstable_by_key(|(file_id, range)| (*file_id, range.start())) + .collect_vec(); + let found_conflicts = source_change + .source_file_edits + .iter() + .flat_map(|(file_id, (edit, _))| { + edit.into_iter() + .filter(|edit| edit.annotation.is_some()) + .map(move |edit| (*file_id, edit.delete)) + }) + .sorted_unstable_by_key(|(file_id, range)| (*file_id, range.start())) + .collect_vec(); + assert_eq!( + expected_conflicts, found_conflicts, + "rename conflicts mismatch: {source_change:#?}" + ); + } + fn check_expect( new_name: &str, #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -547,6 +573,37 @@ mod tests { ) } + #[test] + fn rename_will_shadow() { + check_conflicts( + "new_name", + r#" +fn foo() { + let mut new_name = 123; + let old_name$0 = 456; + // ^^^^^^^^ + new_name = 789 + new_name; +} + "#, + ); + } + + #[test] + fn rename_will_be_shadowed() { + check_conflicts( + "new_name", + r#" +fn foo() { + let mut old_name$0 = 456; + // ^^^^^^^^ + let new_name = 123; + old_name = 789 + old_name; + // ^^^^^^^^ ^^^^^^^^ +} + "#, + ); + } + #[test] fn test_prepare_rename_namelikes() { check_prepare(r"fn name$0<'lifetime>() {}", expect![[r#"3..7: name"#]]); @@ -1024,6 +1081,7 @@ mod foo$0; Indel { insert: "foo2", delete: 4..7, + annotation: None, }, ], ), @@ -1071,6 +1129,7 @@ use crate::foo$0::FooContent; Indel { insert: "quux", delete: 8..11, + annotation: None, }, ], ), @@ -1082,6 +1141,7 @@ use crate::foo$0::FooContent; Indel { insert: "quux", delete: 11..14, + annotation: None, }, ], ), @@ -1123,6 +1183,7 @@ mod fo$0o; Indel { insert: "foo2", delete: 4..7, + annotation: None, }, ], ), @@ -1171,6 +1232,7 @@ mod outer { mod fo$0o; } Indel { insert: "bar", delete: 16..19, + annotation: None, }, ], ), @@ -1242,6 +1304,7 @@ pub mod foo$0; Indel { insert: "foo2", delete: 27..30, + annotation: None, }, ], ), @@ -1253,6 +1316,7 @@ pub mod foo$0; Indel { insert: "foo2", delete: 8..11, + annotation: None, }, ], ), @@ -1308,6 +1372,7 @@ mod quux; Indel { insert: "foo2", delete: 4..7, + annotation: None, }, ], ), @@ -1441,10 +1506,12 @@ pub fn baz() {} Indel { insert: "r#fn", delete: 4..7, + annotation: None, }, Indel { insert: "r#fn", delete: 22..25, + annotation: None, }, ], ), @@ -1509,10 +1576,12 @@ pub fn baz() {} Indel { insert: "foo", delete: 4..8, + annotation: None, }, Indel { insert: "foo", delete: 23..27, + annotation: None, }, ], ), @@ -1574,6 +1643,7 @@ fn bar() { Indel { insert: "dyn", delete: 7..10, + annotation: None, }, ], ), @@ -1585,6 +1655,7 @@ fn bar() { Indel { insert: "r#dyn", delete: 18..21, + annotation: None, }, ], ), @@ -1614,6 +1685,7 @@ fn bar() { Indel { insert: "r#dyn", delete: 7..10, + annotation: None, }, ], ), @@ -1625,6 +1697,7 @@ fn bar() { Indel { insert: "dyn", delete: 18..21, + annotation: None, }, ], ), @@ -1654,6 +1727,7 @@ fn bar() { Indel { insert: "r#dyn", delete: 7..10, + annotation: None, }, ], ), @@ -1665,6 +1739,7 @@ fn bar() { Indel { insert: "dyn", delete: 18..21, + annotation: None, }, ], ), @@ -1701,10 +1776,12 @@ fn bar() { Indel { insert: "abc", delete: 7..10, + annotation: None, }, Indel { insert: "abc", delete: 32..35, + annotation: None, }, ], ), @@ -1716,6 +1793,7 @@ fn bar() { Indel { insert: "abc", delete: 18..23, + annotation: None, }, ], ), @@ -1749,10 +1827,12 @@ fn bar() { Indel { insert: "abc", delete: 7..12, + annotation: None, }, Indel { insert: "abc", delete: 34..39, + annotation: None, }, ], ), @@ -1764,6 +1844,7 @@ fn bar() { Indel { insert: "abc", delete: 18..21, + annotation: None, }, ], ), diff --git a/src/tools/rust-analyzer/crates/ide/src/ssr.rs b/src/tools/rust-analyzer/crates/ide/src/ssr.rs index 77a011cac198..90e350949b81 100644 --- a/src/tools/rust-analyzer/crates/ide/src/ssr.rs +++ b/src/tools/rust-analyzer/crates/ide/src/ssr.rs @@ -139,6 +139,7 @@ mod tests { Indel { insert: "3", delete: 33..34, + annotation: None, }, ], }, @@ -147,6 +148,8 @@ mod tests { }, file_system_edits: [], is_snippet: false, + annotations: {}, + next_annotation_id: 0, }, ), command: None, @@ -179,6 +182,7 @@ mod tests { Indel { insert: "3", delete: 33..34, + annotation: None, }, ], }, @@ -192,6 +196,7 @@ mod tests { Indel { insert: "3", delete: 11..12, + annotation: None, }, ], }, @@ -200,6 +205,8 @@ mod tests { }, file_system_edits: [], is_snippet: false, + annotations: {}, + next_annotation_id: 0, }, ), command: None, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 4ab96e9e2d58..68b2d6b69628 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -427,7 +427,12 @@ pub(crate) fn handle_on_enter( Some(it) => it, }; let line_index = snap.file_line_index(position.file_id)?; - let edit = to_proto::snippet_text_edit_vec(&line_index, true, edit); + let edit = to_proto::snippet_text_edit_vec( + &line_index, + true, + edit, + snap.config.change_annotation_support(), + ); Ok(Some(edit)) } @@ -464,7 +469,12 @@ pub(crate) fn handle_on_type_formatting( let (_, (text_edit, snippet_edit)) = edit.source_file_edits.into_iter().next().unwrap(); stdx::always!(snippet_edit.is_none(), "on type formatting shouldn't use structured snippets"); - let change = to_proto::snippet_text_edit_vec(&line_index, edit.is_snippet, text_edit); + let change = to_proto::snippet_text_edit_vec( + &line_index, + edit.is_snippet, + text_edit, + snap.config.change_annotation_support(), + ); Ok(Some(change)) } @@ -2025,7 +2035,12 @@ pub(crate) fn handle_move_item( match snap.analysis.move_item(range, direction)? { Some(text_edit) => { let line_index = snap.file_line_index(file_id)?; - Ok(to_proto::snippet_text_edit_vec(&line_index, true, text_edit)) + Ok(to_proto::snippet_text_edit_vec( + &line_index, + true, + text_edit, + snap.config.change_annotation_support(), + )) } None => Ok(vec![]), } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 3c206f47db5e..6db7bcb11102 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -200,7 +200,10 @@ pub(crate) fn snippet_text_edit( line_index: &LineIndex, is_snippet: bool, indel: Indel, + client_supports_annotations: bool, ) -> lsp_ext::SnippetTextEdit { + let annotation_id = + indel.annotation.filter(|_| client_supports_annotations).map(|it| it.to_string()); let text_edit = text_edit(line_index, indel); let insert_text_format = if is_snippet { Some(lsp_types::InsertTextFormat::SNIPPET) } else { None }; @@ -208,7 +211,7 @@ pub(crate) fn snippet_text_edit( range: text_edit.range, new_text: text_edit.new_text, insert_text_format, - annotation_id: None, + annotation_id, } } @@ -223,10 +226,13 @@ pub(crate) fn snippet_text_edit_vec( line_index: &LineIndex, is_snippet: bool, text_edit: TextEdit, + clients_support_annotations: bool, ) -> Vec { text_edit .into_iter() - .map(|indel| self::snippet_text_edit(line_index, is_snippet, indel)) + .map(|indel| { + self::snippet_text_edit(line_index, is_snippet, indel, clients_support_annotations) + }) .collect() } @@ -1072,6 +1078,7 @@ fn merge_text_and_snippet_edits( line_index: &LineIndex, edit: TextEdit, snippet_edit: SnippetEdit, + client_supports_annotations: bool, ) -> Vec { let mut edits: Vec = vec![]; let mut snippets = snippet_edit.into_edit_ranges().into_iter().peekable(); @@ -1120,7 +1127,12 @@ fn merge_text_and_snippet_edits( edits.push(snippet_text_edit( line_index, true, - Indel { insert: format!("${snippet_index}"), delete: snippet_range }, + Indel { + insert: format!("${snippet_index}"), + delete: snippet_range, + annotation: None, + }, + client_supports_annotations, )) } @@ -1178,12 +1190,22 @@ fn merge_text_and_snippet_edits( edits.push(snippet_text_edit( line_index, true, - Indel { insert: new_text, delete: current_indel.delete }, + Indel { + insert: new_text, + delete: current_indel.delete, + annotation: current_indel.annotation, + }, + client_supports_annotations, )) } else { // snippet edit was beyond the current one // since it wasn't consumed, it's available for the next pass - edits.push(snippet_text_edit(line_index, false, current_indel)); + edits.push(snippet_text_edit( + line_index, + false, + current_indel, + client_supports_annotations, + )); } // update the final source -> initial source mapping offset @@ -1208,7 +1230,8 @@ fn merge_text_and_snippet_edits( snippet_text_edit( line_index, true, - Indel { insert: format!("${snippet_index}"), delete: snippet_range }, + Indel { insert: format!("${snippet_index}"), delete: snippet_range, annotation: None }, + client_supports_annotations, ) })); @@ -1224,10 +1247,13 @@ pub(crate) fn snippet_text_document_edit( ) -> Cancellable { let text_document = optional_versioned_text_document_identifier(snap, file_id); let line_index = snap.file_line_index(file_id)?; + let client_supports_annotations = snap.config.change_annotation_support(); let mut edits = if let Some(snippet_edit) = snippet_edit { - merge_text_and_snippet_edits(&line_index, edit, snippet_edit) + merge_text_and_snippet_edits(&line_index, edit, snippet_edit, client_supports_annotations) } else { - edit.into_iter().map(|it| snippet_text_edit(&line_index, is_snippet, it)).collect() + edit.into_iter() + .map(|it| snippet_text_edit(&line_index, is_snippet, it, client_supports_annotations)) + .collect() }; if snap.analysis.is_library_file(file_id)? && snap.config.change_annotation_support() { @@ -1348,6 +1374,16 @@ pub(crate) fn snippet_workspace_edit( )), }, )) + .chain(source_change.annotations.into_iter().map(|(id, annotation)| { + ( + id.to_string(), + lsp_types::ChangeAnnotation { + label: annotation.label, + description: annotation.description, + needs_confirmation: Some(annotation.needs_confirmation), + }, + ) + })) .collect(), ) } @@ -2023,7 +2059,7 @@ fn bar(_: usize) {} encoding: PositionEncoding::Utf8, }; - let res = merge_text_and_snippet_edits(&line_index, edit, snippets); + let res = merge_text_and_snippet_edits(&line_index, edit, snippets, true); // Ensure that none of the ranges overlap { From a78d1b092c9cea14137744f188ef00c1416d6f75 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 10 Feb 2025 10:41:19 -0800 Subject: [PATCH 742/991] Update stdarch --- .../rustc_span/src/analyze_source_file.rs | 8 +++---- library/core/Cargo.toml | 2 ++ library/core/src/lib.rs | 3 +++ library/stdarch | 2 +- .../rust-analyzer/lib/line-index/src/lib.rs | 24 ++++++++++++------- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs index 141d261b5f01..6384fa06c21b 100644 --- a/compiler/rustc_span/src/analyze_source_file.rs +++ b/compiler/rustc_span/src/analyze_source_file.rs @@ -83,17 +83,17 @@ cfg_match! { // For character in the chunk, see if its byte value is < 0, which // indicates that it's part of a UTF-8 char. - let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) }; + let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)); // Create a bit mask from the comparison results. - let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) }; + let multibyte_mask = _mm_movemask_epi8(multibyte_test); // If the bit mask is all zero, we only have ASCII chars here: if multibyte_mask == 0 { assert!(intra_chunk_offset == 0); // Check for newlines in the chunk - let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) }; - let mut newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) }; + let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)); + let mut newlines_mask = _mm_movemask_epi8(newlines_test); let output_offset = RelativeBytePos::from_usize(chunk_index * CHUNK_SIZE + 1); diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 1538ecc6b929..edde8153aa1d 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -32,6 +32,8 @@ check-cfg = [ 'cfg(bootstrap)', 'cfg(no_fp_fmt_parse)', 'cfg(stdarch_intel_sde)', + # #[cfg(bootstrap)] + 'cfg(target_feature, values("vector-enhancements-1"))', # core use #[path] imports to portable-simd `core_simd` crate # and to stdarch `core_arch` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index db68f472c42f..987fa93d5987 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -202,14 +202,17 @@ // // Target features: // tidy-alphabetical-start +#![feature(aarch64_unstable_target_feature)] #![feature(arm_target_feature)] #![feature(avx512_target_feature)] #![feature(hexagon_target_feature)] +#![feature(keylocker_x86)] #![feature(loongarch_target_feature)] #![feature(mips_target_feature)] #![feature(powerpc_target_feature)] #![feature(riscv_target_feature)] #![feature(rtm_target_feature)] +#![feature(s390x_target_feature)] #![feature(sha512_sm_x86)] #![feature(sse4a_target_feature)] #![feature(tbm_target_feature)] diff --git a/library/stdarch b/library/stdarch index 684de0d6fef7..9426bb56586c 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit 684de0d6fef708cae08214fef9643dd9ec7296e1 +Subproject commit 9426bb56586c6ae4095a2dcbd66c570253e6fb32 diff --git a/src/tools/rust-analyzer/lib/line-index/src/lib.rs b/src/tools/rust-analyzer/lib/line-index/src/lib.rs index bc87ada3eb55..905da330e64b 100644 --- a/src/tools/rust-analyzer/lib/line-index/src/lib.rs +++ b/src/tools/rust-analyzer/lib/line-index/src/lib.rs @@ -257,6 +257,8 @@ fn analyze_source_file_dispatch( /// SSE2 intrinsics to quickly find all newlines. #[target_feature(enable = "sse2")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +// This can be removed once 1.87 is stable due to some intrinsics switching to safe. +#[allow(unsafe_op_in_unsafe_fn)] unsafe fn analyze_source_file_sse2( src: &str, lines: &mut Vec, @@ -287,17 +289,17 @@ unsafe fn analyze_source_file_sse2( // For character in the chunk, see if its byte value is < 0, which // indicates that it's part of a UTF-8 char. - let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) }; + let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)); // Create a bit mask from the comparison results. - let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) }; + let multibyte_mask = _mm_movemask_epi8(multibyte_test); // If the bit mask is all zero, we only have ASCII chars here: if multibyte_mask == 0 { assert!(intra_chunk_offset == 0); // Check for newlines in the chunk - let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) }; - let newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) }; + let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)); + let newlines_mask = _mm_movemask_epi8(newlines_test); if newlines_mask != 0 { // All control characters are newlines, record them @@ -354,15 +356,19 @@ unsafe fn analyze_source_file_sse2( // The mask is a 64-bit integer, where each 4-bit corresponds to a u8 in the // input vector. The least significant 4 bits correspond to the first byte in // the vector. +// This can be removed once 1.87 is stable due to some intrinsics switching to safe. +#[allow(unsafe_op_in_unsafe_fn)] unsafe fn move_mask(v: std::arch::aarch64::uint8x16_t) -> u64 { use std::arch::aarch64::*; - let nibble_mask = unsafe { vshrn_n_u16(vreinterpretq_u16_u8(v), 4) }; - unsafe { vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0) } + let nibble_mask = vshrn_n_u16(vreinterpretq_u16_u8(v), 4); + vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0) } #[target_feature(enable = "neon")] #[cfg(all(target_arch = "aarch64", target_endian = "little"))] +// This can be removed once 1.87 is stable due to some intrinsics switching to safe. +#[allow(unsafe_op_in_unsafe_fn)] unsafe fn analyze_source_file_neon( src: &str, lines: &mut Vec, @@ -376,7 +382,7 @@ unsafe fn analyze_source_file_neon( let chunk_count = src.len() / CHUNK_SIZE; - let newline = unsafe { vdupq_n_s8(b'\n' as i8) }; + let newline = vdupq_n_s8(b'\n' as i8); // This variable keeps track of where we should start decoding a // chunk. If a multi-byte character spans across chunk boundaries, @@ -390,7 +396,7 @@ unsafe fn analyze_source_file_neon( // For character in the chunk, see if its byte value is < 0, which // indicates that it's part of a UTF-8 char. - let multibyte_test = unsafe { vcltzq_s8(chunk) }; + let multibyte_test = vcltzq_s8(chunk); // Create a bit mask from the comparison results. let multibyte_mask = unsafe { move_mask(multibyte_test) }; @@ -399,7 +405,7 @@ unsafe fn analyze_source_file_neon( assert!(intra_chunk_offset == 0); // Check for newlines in the chunk - let newlines_test = unsafe { vceqq_s8(chunk, newline) }; + let newlines_test = vceqq_s8(chunk, newline); let mut newlines_mask = unsafe { move_mask(newlines_test) }; // If the bit mask is not all zero, there are newlines in this chunk. From 432e1c3eeaa94310f474e314d7750b6df6236fba Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 5 Mar 2025 17:09:08 -0800 Subject: [PATCH 743/991] Add the yield_expr feature --- compiler/rustc_ast_lowering/src/expr.rs | 35 +++++++--------- compiler/rustc_feature/src/unstable.rs | 1 + tests/ui/coroutine/gen_block.e2024.stderr | 22 +--------- tests/ui/coroutine/gen_block.none.stderr | 4 +- tests/ui/coroutine/gen_block.rs | 4 +- .../feature-gate-coroutines.e2024.stderr | 4 +- .../feature-gate-coroutines.none.stderr | 4 +- .../feature-gates/feature-gate-yield-expr.rs | 9 ++++ .../feature-gate-yield-expr.stderr | 41 +++++++++++++++++++ 9 files changed, 74 insertions(+), 50 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-yield-expr.rs create mode 100644 tests/ui/feature-gates/feature-gate-yield-expr.stderr diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 9c3db7abc1cc..c70fcdc84a38 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1690,6 +1690,19 @@ impl<'hir> LoweringContext<'_, 'hir> { let yielded = opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span)); + if !self.tcx.features().yield_expr() + && !self.tcx.features().coroutines() + && !self.tcx.features().gen_blocks() + { + rustc_session::parse::feature_err( + &self.tcx.sess, + sym::yield_expr, + span, + fluent_generated::ast_lowering_yield, + ) + .emit(); + } + let is_async_gen = match self.coroutine_kind { Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => false, Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true, @@ -1714,28 +1727,8 @@ impl<'hir> LoweringContext<'_, 'hir> { None, ); } - Some(hir::CoroutineKind::Coroutine(_)) => { - if !self.tcx.features().coroutines() { - rustc_session::parse::feature_err( - &self.tcx.sess, - sym::coroutines, - span, - fluent_generated::ast_lowering_yield, - ) - .emit(); - } - false - } + Some(hir::CoroutineKind::Coroutine(_)) => false, None => { - if !self.tcx.features().coroutines() { - rustc_session::parse::feature_err( - &self.tcx.sess, - sym::coroutines, - span, - fluent_generated::ast_lowering_yield, - ) - .emit(); - } let suggestion = self.current_item.map(|s| s.shrink_to_lo()); self.dcx().emit_err(YieldInClosure { span, suggestion }); self.coroutine_kind = Some(hir::CoroutineKind::Coroutine(Movability::Movable)); diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index b39ad8875a47..f084cf18ec69 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -669,6 +669,7 @@ declare_features! ( (unstable, xop_target_feature, "1.81.0", Some(127208)), /// Allows `do yeet` expressions (unstable, yeet_expr, "1.62.0", Some(96373)), + (unstable, yield_expr, "CURRENT_RUSTC_VERSION", Some(43122)), // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! diff --git a/tests/ui/coroutine/gen_block.e2024.stderr b/tests/ui/coroutine/gen_block.e2024.stderr index 0491bdbc2e17..347f111e79fd 100644 --- a/tests/ui/coroutine/gen_block.e2024.stderr +++ b/tests/ui/coroutine/gen_block.e2024.stderr @@ -18,16 +18,6 @@ LL | let _ = #[coroutine] || {}; = help: add `#![feature(coroutines)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: yield syntax is experimental - --> $DIR/gen_block.rs:16:16 - | -LL | let _ = || yield true; - | ^^^^^^^^^^ - | - = note: see issue #43122 for more information - = help: add `#![feature(coroutines)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks --> $DIR/gen_block.rs:16:16 | @@ -39,23 +29,13 @@ help: use `#[coroutine]` to make this closure a coroutine LL | let _ = #[coroutine] || yield true; | ++++++++++++ -error[E0658]: yield syntax is experimental - --> $DIR/gen_block.rs:20:29 - | -LL | let _ = #[coroutine] || yield true; - | ^^^^^^^^^^ - | - = note: see issue #43122 for more information - = help: add `#![feature(coroutines)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - error[E0282]: type annotations needed --> $DIR/gen_block.rs:7:13 | LL | let x = gen {}; | ^^^^^^ cannot infer type -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0282, E0658. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/coroutine/gen_block.none.stderr b/tests/ui/coroutine/gen_block.none.stderr index 43437793005a..ed744f2957ac 100644 --- a/tests/ui/coroutine/gen_block.none.stderr +++ b/tests/ui/coroutine/gen_block.none.stderr @@ -71,7 +71,7 @@ LL | let _ = || yield true; | ^^^^^^^^^^ | = note: see issue #43122 for more information - = help: add `#![feature(coroutines)]` to the crate attributes to enable + = help: add `#![feature(yield_expr)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks @@ -92,7 +92,7 @@ LL | let _ = #[coroutine] || yield true; | ^^^^^^^^^^ | = note: see issue #43122 for more information - = help: add `#![feature(coroutines)]` to the crate attributes to enable + = help: add `#![feature(yield_expr)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 11 previous errors diff --git a/tests/ui/coroutine/gen_block.rs b/tests/ui/coroutine/gen_block.rs index 4494d654eeb6..e3734dd4cdf0 100644 --- a/tests/ui/coroutine/gen_block.rs +++ b/tests/ui/coroutine/gen_block.rs @@ -14,12 +14,12 @@ fn main() { //[none]~^ ERROR: cannot find let _ = || yield true; //[none]~ ERROR yield syntax is experimental - //~^ ERROR yield syntax is experimental + //[none]~^ ERROR yield syntax is experimental //~^^ ERROR `yield` can only be used in let _ = #[coroutine] || yield true; //[none]~ ERROR yield syntax is experimental //~^ ERROR `#[coroutine]` attribute is an experimental feature - //~^^ ERROR yield syntax is experimental + //[none]~^^ ERROR yield syntax is experimental let _ = #[coroutine] || {}; //~^ ERROR `#[coroutine]` attribute is an experimental feature diff --git a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr index 032d7adf77ab..381e7a210be0 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr +++ b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr @@ -45,7 +45,7 @@ LL | yield true; | ^^^^^^^^^^ | = note: see issue #43122 for more information - = help: add `#![feature(coroutines)]` to the crate attributes to enable + = help: add `#![feature(yield_expr)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks @@ -66,7 +66,7 @@ LL | let _ = || yield true; | ^^^^^^^^^^ | = note: see issue #43122 for more information - = help: add `#![feature(coroutines)]` to the crate attributes to enable + = help: add `#![feature(yield_expr)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks diff --git a/tests/ui/feature-gates/feature-gate-coroutines.none.stderr b/tests/ui/feature-gates/feature-gate-coroutines.none.stderr index 032d7adf77ab..381e7a210be0 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.none.stderr +++ b/tests/ui/feature-gates/feature-gate-coroutines.none.stderr @@ -45,7 +45,7 @@ LL | yield true; | ^^^^^^^^^^ | = note: see issue #43122 for more information - = help: add `#![feature(coroutines)]` to the crate attributes to enable + = help: add `#![feature(yield_expr)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks @@ -66,7 +66,7 @@ LL | let _ = || yield true; | ^^^^^^^^^^ | = note: see issue #43122 for more information - = help: add `#![feature(coroutines)]` to the crate attributes to enable + = help: add `#![feature(yield_expr)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks diff --git a/tests/ui/feature-gates/feature-gate-yield-expr.rs b/tests/ui/feature-gates/feature-gate-yield-expr.rs new file mode 100644 index 000000000000..382bf89069e7 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-yield-expr.rs @@ -0,0 +1,9 @@ +//@ edition: 2024 +#![feature(stmt_expr_attributes)] + +fn main() { + yield (); //~ ERROR yield syntax is experimental + //~^ ERROR yield syntax is experimental + //~^^ ERROR `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + //~^^^ ERROR yield expression outside of coroutine literal +} diff --git a/tests/ui/feature-gates/feature-gate-yield-expr.stderr b/tests/ui/feature-gates/feature-gate-yield-expr.stderr new file mode 100644 index 000000000000..ad8a15a0f365 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-yield-expr.stderr @@ -0,0 +1,41 @@ +error[E0658]: yield syntax is experimental + --> $DIR/feature-gate-yield-expr.rs:5:5 + | +LL | yield (); + | ^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: yield syntax is experimental + --> $DIR/feature-gate-yield-expr.rs:5:5 + | +LL | yield (); + | ^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(yield_expr)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/feature-gate-yield-expr.rs:5:5 + | +LL | yield (); + | ^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | #[coroutine] fn main() { + | ++++++++++++ + +error[E0627]: yield expression outside of coroutine literal + --> $DIR/feature-gate-yield-expr.rs:5:5 + | +LL | yield (); + | ^^^^^^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0627, E0658. +For more information about an error, try `rustc --explain E0627`. From 5339d4ef5b3e15a92594dd397c38db036566f54f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 6 Mar 2025 19:56:21 +0000 Subject: [PATCH 744/991] Fix target-feature inline test to be less flaky --- tests/codegen/target-feature-inline-closure.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/codegen/target-feature-inline-closure.rs b/tests/codegen/target-feature-inline-closure.rs index 73bdbc0e1a84..5d54444f994a 100644 --- a/tests/codegen/target-feature-inline-closure.rs +++ b/tests/codegen/target-feature-inline-closure.rs @@ -12,7 +12,7 @@ use std::arch::x86_64::*; #[cfg(target_arch = "x86_64")] #[target_feature(enable = "avx")] fn with_avx(x: __m256) -> __m256 { - // CHECK: fadd + // CHECK: fadd <8 x float> let add = { #[inline(always)] |x, y| unsafe { _mm256_add_ps(x, y) } @@ -24,14 +24,10 @@ fn with_avx(x: __m256) -> __m256 { #[no_mangle] #[cfg(target_arch = "x86_64")] unsafe fn without_avx(x: __m256) -> __m256 { - // CHECK-NOT: fadd + // CHECK-NOT: fadd <8 x float> let add = { #[inline(always)] |x, y| unsafe { _mm256_add_ps(x, y) } }; add(x, x) } - -// Don't allow the above CHECK-NOT to accidentally match a commit hash in the -// compiler version. -// CHECK-LABEL: rustc version From 0cf8dbc96c7c3c454779fe59e8e7019a3e37d5b6 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 29 Oct 2024 17:11:57 -0300 Subject: [PATCH 745/991] Add ergonomic_clones feature flag --- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + .../feature-gate-ergonomic-clones.rs | 20 ++++++++++++++ .../feature-gate-ergonomic-clones.stderr | 26 +++++++++++++++++++ 5 files changed, 50 insertions(+) create mode 100644 tests/ui/feature-gates/feature-gate-ergonomic-clones.rs create mode 100644 tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index de11fe770c5b..0e798169af83 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -489,6 +489,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(dyn_star, "`dyn*` trait objects are experimental"); gate_all!(const_closures, "const closures are experimental"); gate_all!(builtin_syntax, "`builtin #` syntax is unstable"); + gate_all!(ergonomic_clones, "`.use` calls are experimental"); gate_all!(explicit_tail_calls, "`become` expression is experimental"); gate_all!(generic_const_items, "generic const items are experimental"); gate_all!(guard_patterns, "guard patterns are experimental", "consider using match arm guards"); diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 841d30841856..ccfdd93e9939 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -473,6 +473,8 @@ declare_features! ( (unstable, doc_masked, "1.21.0", Some(44027)), /// Allows `dyn* Trait` objects. (incomplete, dyn_star, "1.65.0", Some(102425)), + /// Allows the .use postfix syntax `x.use` and use closures `use |x| { ... }` + (unstable, ergonomic_clones, "CURRENT_RUSTC_VERSION", Some(132290)), /// Allows exhaustive pattern matching on types that contain uninhabited types. (unstable, exhaustive_patterns, "1.13.0", Some(51085)), /// Allows explicit tail calls via `become` expression. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 522bccb1acb0..3357e085a7d2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -859,6 +859,7 @@ symbols! { eprint_macro, eprintln_macro, eq, + ergonomic_clones, ermsb_target_feature, exact_div, except, diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs new file mode 100644 index 000000000000..37c2dc132e83 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs @@ -0,0 +1,20 @@ +fn ergonomic_clone(x: i32) -> i32 { + x.use + //~^ ERROR expected identifier, found keyword `use` + //~| ERROR `i32` is a primitive type and therefore doesn't have fields [E0610] +} + +fn ergonomic_closure_clone() { + let s1 = String::from("hi!"); + + let s2 = use || { + //~^ ERROR expected expression, found keyword `use` + s1 + }; + + let s3 = use || { + s1 + }; +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr new file mode 100644 index 000000000000..9edefb775b49 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr @@ -0,0 +1,26 @@ +error: expected identifier, found keyword `use` + --> $DIR/feature-gate-ergonomic-clones.rs:2:7 + | +LL | x.use + | ^^^ expected identifier, found keyword + | +help: escape `use` to use it as an identifier + | +LL | x.r#use + | ++ + +error: expected expression, found keyword `use` + --> $DIR/feature-gate-ergonomic-clones.rs:10:14 + | +LL | let s2 = use || { + | ^^^ expected expression + +error[E0610]: `i32` is a primitive type and therefore doesn't have fields + --> $DIR/feature-gate-ergonomic-clones.rs:2:7 + | +LL | x.use + | ^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0610`. From 05c516446a0f6105ce695da00d5cf5a0eb54e808 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 2 Oct 2024 16:35:37 -0300 Subject: [PATCH 746/991] Implement .use keyword as an alias of clone --- compiler/rustc_ast/src/ast.rs | 3 ++ compiler/rustc_ast/src/mut_visit.rs | 4 ++ compiler/rustc_ast/src/util/classify.rs | 2 + compiler/rustc_ast/src/visit.rs | 1 + compiler/rustc_ast_lowering/src/expr.rs | 5 ++ .../rustc_ast_pretty/src/pprust/state/expr.rs | 8 +++ .../src/assert/context.rs | 1 + compiler/rustc_hir/src/hir.rs | 8 ++- compiler/rustc_hir/src/intravisit.rs | 3 ++ compiler/rustc_hir_pretty/src/lib.rs | 4 ++ compiler/rustc_hir_typeck/src/expr.rs | 11 +++++ .../rustc_hir_typeck/src/expr_use_visitor.rs | 5 ++ compiler/rustc_lint/src/dangling.rs | 5 +- compiler/rustc_middle/src/thir.rs | 8 +++ compiler/rustc_middle/src/thir/visit.rs | 3 ++ .../src/builder/expr/as_place.rs | 1 + .../src/builder/expr/as_rvalue.rs | 8 +++ .../src/builder/expr/category.rs | 1 + .../rustc_mir_build/src/builder/expr/into.rs | 36 +++++++++++++- .../rustc_mir_build/src/check_unsafety.rs | 1 + compiler/rustc_mir_build/src/thir/cx/expr.rs | 4 ++ .../src/thir/pattern/check_match.rs | 1 + compiler/rustc_mir_build/src/thir/print.rs | 7 +++ compiler/rustc_parse/messages.ftl | 3 ++ compiler/rustc_parse/src/errors.rs | 13 +++++ .../rustc_parse/src/parser/diagnostics.rs | 21 ++++++-- compiler/rustc_parse/src/parser/expr.rs | 15 ++++++ compiler/rustc_passes/src/input_stats.rs | 3 +- compiler/rustc_passes/src/liveness.rs | 7 +++ compiler/rustc_passes/src/naked_functions.rs | 1 + compiler/rustc_ty_utils/messages.ftl | 2 + compiler/rustc_ty_utils/src/consts.rs | 5 +- compiler/rustc_ty_utils/src/errors.rs | 2 + tests/ui/ergonomic-clones/dotuse.rs | 14 ++++++ .../feature-gate-ergonomic-clones.rs | 6 +-- .../feature-gate-ergonomic-clones.stderr | 49 ++++++++++++++----- 36 files changed, 247 insertions(+), 24 deletions(-) create mode 100644 tests/ui/ergonomic-clones/dotuse.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fb6b36e1a09d..3987aea6066d 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1399,6 +1399,7 @@ impl Expr { // Never need parens ExprKind::Array(_) | ExprKind::Await(..) + | ExprKind::Use(..) | ExprKind::Block(..) | ExprKind::Call(..) | ExprKind::ConstBlock(_) @@ -1588,6 +1589,8 @@ pub enum ExprKind { Gen(CaptureBy, P, GenBlockKind, Span), /// An await expression (`my_future.await`). Span is of await keyword. Await(P, Span), + /// A use expression (`x.use`). Span is of use keyword. + Use(P, Span), /// A try block (`try { ... }`). TryBlock(P), diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index f14646b5a99a..5841805abd7c 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1745,6 +1745,10 @@ pub fn walk_expr(vis: &mut T, Expr { kind, id, span, attrs, token vis.visit_expr(expr); vis.visit_span(await_kw_span); } + ExprKind::Use(expr, use_kw_span) => { + vis.visit_expr(expr); + vis.visit_span(use_kw_span); + } ExprKind::Assign(el, er, span) => { vis.visit_expr(el); vis.visit_expr(er); diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 64f2a98b8a6f..e43d78f6e721 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -108,6 +108,7 @@ pub fn leading_labeled_expr(mut expr: &ast::Expr) -> bool { Assign(e, _, _) | AssignOp(_, e, _) | Await(e, _) + | Use(e, _) | Binary(_, e, _) | Call(e, _) | Cast(e, _) @@ -224,6 +225,7 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option> { | Lit(_) | Type(_, _) | Await(_, _) + | Use(_, _) | Field(_, _) | Index(_, _, _) | Underscore diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 37139e664f3d..43ffbe9b071d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1211,6 +1211,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V } ExprKind::Gen(_capt, body, _kind, _decl_span) => try_visit!(visitor.visit_block(body)), ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)), + ExprKind::Use(expr, _span) => try_visit!(visitor.visit_expr(expr)), ExprKind::Assign(lhs, rhs, _span) => { try_visit!(visitor.visit_expr(lhs)); try_visit!(visitor.visit_expr(rhs)); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 9c3db7abc1cc..871c69c9eb13 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -207,6 +207,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }, ), ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr), + ExprKind::Use(expr, use_kw_span) => self.lower_expr_use(*use_kw_span, expr), ExprKind::Closure(box Closure { binder, capture_clause, @@ -1067,6 +1068,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } + fn lower_expr_use(&mut self, use_kw_span: Span, expr: &Expr) -> hir::ExprKind<'hir> { + hir::ExprKind::Use(self.lower_expr(expr), use_kw_span) + } + fn lower_expr_closure( &mut self, binder: &ClosureBinder, diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 496323a35b8d..9d11115ecbf5 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -574,6 +574,14 @@ impl<'a> State<'a> { ); self.word(".await"); } + ast::ExprKind::Use(expr, _) => { + self.print_expr_cond_paren( + expr, + expr.precedence() < ExprPrecedence::Unambiguous, + fixup, + ); + self.word(".use"); + } ast::ExprKind::Assign(lhs, rhs, _) => { self.print_expr_cond_paren( lhs, diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index bb9dc651cec2..a949ab94f3ad 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -297,6 +297,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::AssignOp(_, _, _) | ExprKind::Gen(_, _, _, _) | ExprKind::Await(_, _) + | ExprKind::Use(_, _) | ExprKind::Block(_, _) | ExprKind::Break(_, _) | ExprKind::Closure(_) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 399f1f4b2373..7b927316f3b8 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2166,6 +2166,7 @@ impl Expr<'_> { | ExprKind::Tup(_) | ExprKind::Type(..) | ExprKind::UnsafeBinderCast(..) + | ExprKind::Use(..) | ExprKind::Err(_) => ExprPrecedence::Unambiguous, ExprKind::DropTemps(expr, ..) => expr.precedence(), @@ -2212,6 +2213,7 @@ impl Expr<'_> { ExprKind::Path(QPath::TypeRelative(..)) | ExprKind::Call(..) | ExprKind::MethodCall(..) + | ExprKind::Use(..) | ExprKind::Struct(..) | ExprKind::Tup(..) | ExprKind::If(..) @@ -2285,7 +2287,9 @@ impl Expr<'_> { pub fn can_have_side_effects(&self) -> bool { match self.peel_drop_temps().kind { - ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) => false, + ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) | ExprKind::Use(..) => { + false + } ExprKind::Type(base, _) | ExprKind::Unary(_, base) | ExprKind::Field(base, _) @@ -2547,6 +2551,8 @@ pub enum ExprKind<'hir> { /// /// [`type_dependent_def_id`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.type_dependent_def_id MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span), + /// An use expression (e.g., `var.use`). + Use(&'hir Expr<'hir>, Span), /// A tuple (e.g., `(a, b, c, d)`). Tup(&'hir [Expr<'hir>]), /// A binary operation (e.g., `a + b`, `a * b`). diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index e349e23f7dcf..6b34c2ac2ef4 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -821,6 +821,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) try_visit!(visitor.visit_expr(receiver)); walk_list!(visitor, visit_expr, arguments); } + ExprKind::Use(expr, _) => { + try_visit!(visitor.visit_expr(expr)); + } ExprKind::Binary(_, ref left_expression, ref right_expression) => { try_visit!(visitor.visit_expr(left_expression)); try_visit!(visitor.visit_expr(right_expression)); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 1658c8dac676..5f632bdc517d 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1544,6 +1544,10 @@ impl<'a> State<'a> { hir::ExprKind::MethodCall(segment, receiver, args, _) => { self.print_expr_method_call(segment, receiver, args); } + hir::ExprKind::Use(expr, _) => { + self.print_expr(expr); + self.word(".use"); + } hir::ExprKind::Binary(op, lhs, rhs) => { self.print_expr_binary(op, lhs, rhs); } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index dec1779d92ca..360d9a6cecd0 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -362,6 +362,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Any expression child of these expressions constitute reads. ExprKind::Array(_) | ExprKind::Call(_, _) + | ExprKind::Use(_, _) | ExprKind::MethodCall(_, _, _, _) | ExprKind::Tup(_) | ExprKind::Binary(_, _, _) @@ -552,6 +553,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Closure(closure) => self.check_expr_closure(closure, expr.span, expected), ExprKind::Block(body, _) => self.check_expr_block(body, expected), ExprKind::Call(callee, args) => self.check_expr_call(expr, callee, args, expected), + ExprKind::Use(used_expr, _) => self.check_expr_use(used_expr, expected), ExprKind::MethodCall(segment, receiver, args, _) => { self.check_expr_method_call(expr, segment, receiver, args, expected) } @@ -1616,6 +1618,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } + /// Checks use `x.use`. + fn check_expr_use( + &self, + used_expr: &'tcx hir::Expr<'tcx>, + expected: Expectation<'tcx>, + ) -> Ty<'tcx> { + self.check_expr_with_expectation(used_expr, expected) + } + fn check_expr_cast( &self, e: &'tcx hir::Expr<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index c0617119d67c..bd9173e6163f 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -366,6 +366,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.consume_exprs(args)?; } + hir::ExprKind::Use(expr, _) => { + self.consume_expr(expr)?; + } + hir::ExprKind::MethodCall(.., receiver, args, _) => { // callee.m(args) self.consume_expr(receiver)?; @@ -1386,6 +1390,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx hir::ExprKind::AddrOf(..) | hir::ExprKind::Call(..) + | hir::ExprKind::Use(..) | hir::ExprKind::Assign(..) | hir::ExprKind::AssignOp(..) | hir::ExprKind::Closure { .. } diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index fd6b3e90adab..91c7922638de 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -159,7 +159,10 @@ fn is_temporary_rvalue(expr: &Expr<'_>) -> bool { ExprKind::Path(..) => false, // Calls return rvalues. - ExprKind::Call(..) | ExprKind::MethodCall(..) | ExprKind::Binary(..) => true, + ExprKind::Call(..) + | ExprKind::MethodCall(..) + | ExprKind::Use(..) + | ExprKind::Binary(..) => true, // Inner blocks are rvalues. ExprKind::If(..) | ExprKind::Loop(..) | ExprKind::Match(..) | ExprKind::Block(..) => true, diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index e5592de81cd7..c9e7331660ff 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -312,6 +312,14 @@ pub enum ExprKind<'tcx> { /// (e.g. `foo(a, b)` in `x.foo(a, b)`). fn_span: Span, }, + /// A use expression `x.use`. + ByUse { + /// The expression on which use is applied. + expr: ExprId, + /// The span of use, without the dot and receiver + /// (e.g. `use` in `x.use`). + span: Span, + }, /// A *non-overloaded* dereference. Deref { arg: ExprId, diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index a9df4d1625be..d208692f4e71 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -59,6 +59,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( visitor.visit_expr(&visitor.thir()[arg]); } } + ByUse { expr, span: _ } => { + visitor.visit_expr(&visitor.thir()[expr]); + } Deref { arg } => visitor.visit_expr(&visitor.thir()[arg]), Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => { visitor.visit_expr(&visitor.thir()[lhs]); diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs index 581f45db6c48..50ca924baf9c 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs @@ -582,6 +582,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::Yield { .. } | ExprKind::ThreadLocalRef(_) | ExprKind::Call { .. } + | ExprKind::ByUse { .. } | ExprKind::WrapUnsafeBinder { .. } => { // these are not places, so we need to make a temporary. debug_assert!(!matches!(Category::of(&expr.kind), Some(Category::Place))); diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index 2c9a1de7f997..97d34b85f50d 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -572,6 +572,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); block.and(Rvalue::Use(operand)) } + + ExprKind::ByUse { expr, span: _ } => { + let operand = unpack!( + block = + this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::No) + ); + block.and(Rvalue::Use(operand)) + } } } diff --git a/compiler/rustc_mir_build/src/builder/expr/category.rs b/compiler/rustc_mir_build/src/builder/expr/category.rs index ca55d36bfc65..34524aed4067 100644 --- a/compiler/rustc_mir_build/src/builder/expr/category.rs +++ b/compiler/rustc_mir_build/src/builder/expr/category.rs @@ -56,6 +56,7 @@ impl Category { | ExprKind::RawBorrow { .. } | ExprKind::Yield { .. } | ExprKind::Call { .. } + | ExprKind::ByUse { .. } | ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::Into)), ExprKind::Array { .. } diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index 72443e2f60dd..d89f3773e4ab 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -4,10 +4,12 @@ use rustc_ast::{AsmMacro, InlineAsmOptions}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; +use rustc_hir::lang_items::LangItem; use rustc_middle::mir::*; use rustc_middle::span_bug; use rustc_middle::thir::*; -use rustc_middle::ty::CanonicalUserTypeAnnotation; +use rustc_middle::ty::{CanonicalUserTypeAnnotation, Ty}; +use rustc_span::DUMMY_SP; use rustc_span::source_map::Spanned; use tracing::{debug, instrument}; @@ -289,6 +291,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.diverge_from(block); success.unit() } + ExprKind::ByUse { expr, span } => { + let place = unpack!(block = this.as_place(block, expr)); + let ty = place.ty(&this.local_decls, this.tcx).ty; + + // Convert `expr.use` to a call like `Clone::clone(&expr)` + let success = this.cfg.start_new_block(); + let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None); + let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0]; + let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span); + let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty); + let ref_place = this.temp(ref_ty, span); + this.cfg.push_assign( + block, + source_info, + ref_place, + Rvalue::Ref(this.tcx.lifetimes.re_erased, BorrowKind::Shared, place), + ); + this.cfg.terminate( + block, + source_info, + TerminatorKind::Call { + func, + args: [Spanned { node: Operand::Move(ref_place), span: DUMMY_SP }].into(), + destination, + target: Some(success), + unwind: UnwindAction::Unreachable, + call_source: CallSource::Misc, + fn_span: expr_span, + }, + ); + success.unit() + } ExprKind::Use { source } => this.expr_into_dest(destination, block, source), ExprKind::Borrow { arg, borrow_kind } => { // We don't do this in `as_rvalue` because we use `as_place` diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index c2eafd0a74e6..d78c874c7660 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -451,6 +451,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { | ExprKind::Tuple { .. } | ExprKind::Unary { .. } | ExprKind::Call { .. } + | ExprKind::ByUse { .. } | ExprKind::Assign { .. } | ExprKind::AssignOp { .. } | ExprKind::Break { .. } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 7139516702e9..40e84be72b10 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -464,6 +464,10 @@ impl<'tcx> ThirBuildCx<'tcx> { } } + hir::ExprKind::Use(expr, span) => { + ExprKind::ByUse { expr: self.mirror_expr(expr), span } + } + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, arg) => { ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg: self.mirror_expr(arg) } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 954d0cf97abe..dadd1e854611 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -345,6 +345,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { | Borrow { .. } | Box { .. } | Call { .. } + | ByUse { .. } | Closure { .. } | ConstBlock { .. } | ConstParam { .. } diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index cd56d93afcf7..16cef0ec3acb 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -246,6 +246,13 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, "}", depth_lvl); } + ByUse { expr, span } => { + print_indented!(self, "ByUse {", depth_lvl); + print_indented!(self, "expr:", depth_lvl + 1); + self.print_expr(*expr, depth_lvl + 2); + print_indented!(self, format!("span: {:?}", span), depth_lvl + 1); + print_indented!(self, "}", depth_lvl); + } Deref { arg } => { print_indented!(self, "Deref {", depth_lvl); self.print_expr(*arg, depth_lvl + 1); diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 1d5b59421706..0289fa5f4933 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -348,6 +348,9 @@ parse_incorrect_use_of_await = incorrect use of `await` parse_incorrect_use_of_await_postfix_suggestion = `await` is a postfix operation +parse_incorrect_use_of_use = incorrect use of `use` + .parentheses_suggestion = `use` is not a method call, try removing the parentheses + parse_incorrect_visibility_restriction = incorrect visibility restriction .help = some possible visibility restrictions are: `pub(crate)`: visible only on the current crate diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 8d2fd595942c..d89bb1451b63 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -106,6 +106,19 @@ pub(crate) struct IncorrectUseOfAwait { pub span: Span, } +#[derive(Diagnostic)] +#[diag(parse_incorrect_use_of_use)] +pub(crate) struct IncorrectUseOfUse { + #[primary_span] + #[suggestion( + parse_parentheses_suggestion, + style = "verbose", + code = "", + applicability = "machine-applicable" + )] + pub span: Span, +} + #[derive(Subdiagnostic)] #[multipart_suggestion( parse_incorrect_use_of_await_postfix_suggestion, diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 94db43bb59f8..dd511fcd8c04 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -38,8 +38,8 @@ use crate::errors::{ DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg, HelpIdentifierStartsWithNumber, HelpUseLatestEdition, InInTypo, IncorrectAwait, - IncorrectSemicolon, IncorrectUseOfAwait, PatternMethodParamWithoutBody, QuestionMarkInType, - QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath, + IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, PatternMethodParamWithoutBody, + QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, StructLiteralNeedingParensSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration, @@ -1991,7 +1991,7 @@ impl<'a> Parser<'a> { self.parse_expr() } .map_err(|mut err| { - err.span_label(await_sp, "while parsing this incorrect await expression"); + err.span_label(await_sp, format!("while parsing this incorrect await expression")); err })?; Ok((expr.span, expr, is_question)) @@ -2030,6 +2030,21 @@ impl<'a> Parser<'a> { self.dcx().emit_err(IncorrectUseOfAwait { span }); } } + /// + /// If encountering `x.use()`, consumes and emits an error. + pub(super) fn recover_from_use(&mut self) { + if self.token == token::OpenDelim(Delimiter::Parenthesis) + && self.look_ahead(1, |t| t == &token::CloseDelim(Delimiter::Parenthesis)) + { + // var.use() + let lo = self.token.span; + self.bump(); // ( + let span = lo.to(self.token.span); + self.bump(); // ) + + self.dcx().emit_err(IncorrectUseOfUse { span }); + } + } pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P> { let is_try = self.token.is_keyword(kw::Try); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0a08c6faeb48..c00f7f2d8de0 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -778,6 +778,7 @@ impl<'a> Parser<'a> { ExprKind::MethodCall(_) => "a method call", ExprKind::Call(_, _) => "a function call", ExprKind::Await(_, _) => "`.await`", + ExprKind::Use(_, _) => "`.use`", ExprKind::Match(_, _, MatchKind::Postfix) => "a postfix match", ExprKind::Err(_) => return Ok(with_postfix), _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"), @@ -1296,6 +1297,12 @@ impl<'a> Parser<'a> { return Ok(self.mk_await_expr(self_arg, lo)); } + if self.eat_keyword(exp!(Use)) { + let use_span = self.prev_token.span; + self.psess.gated_spans.gate(sym::ergonomic_clones, use_span); + return Ok(self.mk_use_expr(self_arg, lo)); + } + // Post-fix match if self.eat_keyword(exp!(Match)) { let match_span = self.prev_token.span; @@ -3818,6 +3825,13 @@ impl<'a> Parser<'a> { await_expr } + fn mk_use_expr(&mut self, self_arg: P, lo: Span) -> P { + let span = lo.to(self.prev_token.span); + let use_expr = self.mk_expr(span, ExprKind::Use(self_arg, self.prev_token.span)); + self.recover_from_use(); + use_expr + } + pub(crate) fn mk_expr_with_attrs(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P { P(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None }) } @@ -3966,6 +3980,7 @@ impl MutVisitor for CondChecker<'_> { } ExprKind::Unary(_, _) | ExprKind::Await(_, _) + | ExprKind::Use(_, _) | ExprKind::AssignOp(_, _, _) | ExprKind::Range(_, _, _) | ExprKind::Try(_) diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 92ea49f18e5d..e610b404d016 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -328,6 +328,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { Array, Call, MethodCall, + Use, Tup, Binary, Unary, @@ -626,7 +627,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { (self, e, e.kind, None, ast, Expr, ExprKind), [ Array, ConstBlock, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, Let, - If, While, ForLoop, Loop, Match, Closure, Block, Await, TryBlock, Assign, + If, While, ForLoop, Loop, Match, Closure, Block, Await, Use, TryBlock, Assign, AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret, InlineAsm, FormatArgs, OffsetOf, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, Become, IncludedBytes, Gen, UnsafeBinderCast, Err, Dummy diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 24dc018c6612..84fb169c5f75 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -426,6 +426,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { | hir::ExprKind::Array(..) | hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) + | hir::ExprKind::Use(..) | hir::ExprKind::Tup(..) | hir::ExprKind::Binary(..) | hir::ExprKind::AddrOf(..) @@ -1031,6 +1032,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(receiver, succ) } + hir::ExprKind::Use(expr, _) => { + let succ = self.check_is_ty_uninhabited(expr, succ); + self.propagate_through_expr(expr, succ) + } + hir::ExprKind::Tup(exprs) => self.propagate_through_exprs(exprs, succ), hir::ExprKind::Binary(op, ref l, ref r) if op.node.is_lazy() => { @@ -1418,6 +1424,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) { // no correctness conditions related to liveness hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) + | hir::ExprKind::Use(..) | hir::ExprKind::Match(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Index(..) diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index cb17b0f6cf52..d35aedf9a564 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -182,6 +182,7 @@ impl CheckInlineAssembly { | ExprKind::Array(..) | ExprKind::Call(..) | ExprKind::MethodCall(..) + | ExprKind::Use(..) | ExprKind::Tup(..) | ExprKind::Binary(..) | ExprKind::Unary(..) diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl index de2c3b63997e..8bc7bf10865f 100644 --- a/compiler/rustc_ty_utils/messages.ftl +++ b/compiler/rustc_ty_utils/messages.ftl @@ -14,6 +14,8 @@ ty_utils_borrow_not_supported = borrowing is not supported in generic constants ty_utils_box_not_supported = allocations are not allowed in generic constants +ty_utils_by_use_not_supported = .use is not allowed in generic constants + ty_utils_closure_and_return_not_supported = closures and function keywords are not supported in generic constants ty_utils_const_block_not_supported = const blocks are not supported in generic constants diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index ece796b3c71c..b275cd382ab8 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -230,7 +230,9 @@ fn recurse_build<'tcx>( error(GenericConstantTooComplexSub::LoopNotSupported(node.span))? } ExprKind::Box { .. } => error(GenericConstantTooComplexSub::BoxNotSupported(node.span))?, - + ExprKind::ByUse { .. } => { + error(GenericConstantTooComplexSub::ByUseNotSupported(node.span))? + } ExprKind::Unary { .. } => unreachable!(), // we handle valid unary/binary ops above ExprKind::Binary { .. } => { @@ -317,6 +319,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> { | thir::ExprKind::Box { .. } | thir::ExprKind::If { .. } | thir::ExprKind::Call { .. } + | thir::ExprKind::ByUse { .. } | thir::ExprKind::Deref { .. } | thir::ExprKind::Binary { .. } | thir::ExprKind::LogicalOp { .. } diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index 8877bb45ceb2..0298e7e0e951 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -55,6 +55,8 @@ pub(crate) enum GenericConstantTooComplexSub { BoxNotSupported(#[primary_span] Span), #[label(ty_utils_binary_not_supported)] BinaryNotSupported(#[primary_span] Span), + #[label(ty_utils_by_use_not_supported)] + ByUseNotSupported(#[primary_span] Span), #[label(ty_utils_logical_op_not_supported)] LogicalOpNotSupported(#[primary_span] Span), #[label(ty_utils_assign_not_supported)] diff --git a/tests/ui/ergonomic-clones/dotuse.rs b/tests/ui/ergonomic-clones/dotuse.rs new file mode 100644 index 000000000000..928c27296b16 --- /dev/null +++ b/tests/ui/ergonomic-clones/dotuse.rs @@ -0,0 +1,14 @@ +//@ check-pass + +#![feature(ergonomic_clones)] + +fn basic_test(x: i32) -> i32 { + x.use.use.abs() +} + +fn do_not_move_test(x: String) -> String { + let s = x.use; + x +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs index 37c2dc132e83..be65afd85d92 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs @@ -1,18 +1,18 @@ fn ergonomic_clone(x: i32) -> i32 { x.use - //~^ ERROR expected identifier, found keyword `use` - //~| ERROR `i32` is a primitive type and therefore doesn't have fields [E0610] + //~^ ERROR `.use` calls are experimental [E0658] } fn ergonomic_closure_clone() { let s1 = String::from("hi!"); let s2 = use || { - //~^ ERROR expected expression, found keyword `use` + //~^ ERROR incorrect use of `use` s1 }; let s3 = use || { + //~^ ERROR incorrect use of `use` s1 }; } diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr index 9edefb775b49..61583239815c 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr @@ -1,26 +1,49 @@ -error: expected identifier, found keyword `use` - --> $DIR/feature-gate-ergonomic-clones.rs:2:7 +error: incorrect use of `use` + --> $DIR/feature-gate-ergonomic-clones.rs:9:14 | -LL | x.use - | ^^^ expected identifier, found keyword +LL | let s2 = use || { + | ______________^ +LL | | +LL | | s1 +LL | | }; + | |_____^ | -help: escape `use` to use it as an identifier +help: `use` is a postfix operation + | +LL ~ let s2 = || { +LL | +LL | s1 +LL ~ }.use; | -LL | x.r#use - | ++ -error: expected expression, found keyword `use` - --> $DIR/feature-gate-ergonomic-clones.rs:10:14 +error: incorrect use of `use` + --> $DIR/feature-gate-ergonomic-clones.rs:14:14 + | +LL | let s3 = use || { + | ______________^ +LL | | +LL | | s1 +LL | | }; + | |_____^ + | +help: `use` is a postfix operation + | +LL ~ let s3 = || { +LL | +LL | s1 +LL ~ }.use; | -LL | let s2 = use || { - | ^^^ expected expression -error[E0610]: `i32` is a primitive type and therefore doesn't have fields +error[E0658]: `.use` calls are experimental --> $DIR/feature-gate-ergonomic-clones.rs:2:7 | LL | x.use | ^^^ + | + = note: see issue #132290 for more information + = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0610`. +For more information about this error, try `rustc --explain E0658`. From 81a926cc2ae22bed26c57a7ef481099916fc1cc8 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 1 Nov 2024 18:37:32 -0300 Subject: [PATCH 747/991] Use closure parse code --- compiler/rustc_ast/src/ast.rs | 5 ++ compiler/rustc_ast/src/mut_visit.rs | 3 + .../rustc_ast_pretty/src/pprust/state/expr.rs | 1 + .../rustc_borrowck/src/borrowck_errors.rs | 1 + compiler/rustc_hir_pretty/src/lib.rs | 1 + compiler/rustc_hir_typeck/src/upvar.rs | 14 ++-- compiler/rustc_parse/messages.ftl | 3 + compiler/rustc_parse/src/errors.rs | 8 ++ compiler/rustc_parse/src/parser/expr.rs | 15 +++- compiler/rustc_parse/src/parser/item.rs | 2 +- .../edition-keywords-2018-2015-parsing.stderr | 8 +- .../edition-keywords-2018-2018-parsing.stderr | 16 ++-- tests/ui/ergonomic-clones/closure.rs | 23 +++++ .../feature-gate-ergonomic-clones.rs | 5 +- .../feature-gate-ergonomic-clones.stderr | 84 ++++++++++--------- tests/ui/parser/block-no-opening-brace.rs | 2 +- tests/ui/parser/block-no-opening-brace.stderr | 4 +- .../misspelled-keywords/async-move.stderr | 4 +- .../recover/recover-quantified-closure.rs | 2 +- .../recover/recover-quantified-closure.stderr | 4 +- 20 files changed, 137 insertions(+), 68 deletions(-) create mode 100644 tests/ui/ergonomic-clones/closure.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 3987aea6066d..66a8d1ce86ae 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1762,6 +1762,11 @@ pub enum CaptureBy { }, /// `move` keyword was not specified. Ref, + /// `use |x| y + x`. + Use { + /// The span of the `use` keyword. + use_kw: Span, + }, } /// Closure lifetime binder, `for<'a, 'b>` in `for<'a, 'b> |_: &'a (), _: &'b ()|`. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 5841805abd7c..ee894db7b966 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1899,6 +1899,9 @@ fn walk_capture_by(vis: &mut T, capture_by: &mut CaptureBy) { CaptureBy::Value { move_kw } => { vis.visit_span(move_kw); } + CaptureBy::Use { use_kw } => { + vis.visit_span(use_kw); + } } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 9d11115ecbf5..e3c41f117abb 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -893,6 +893,7 @@ impl<'a> State<'a> { fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy) { match capture_clause { ast::CaptureBy::Value { .. } => self.word_space("move"), + ast::CaptureBy::Use { .. } => self.word_space("use"), ast::CaptureBy::Ref => {} } } diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 30e94b0bec70..c9be5575da5c 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -403,6 +403,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { .expect_closure(); let span = match capture_clause { rustc_hir::CaptureBy::Value { move_kw } => move_kw.shrink_to_lo(), + rustc_hir::CaptureBy::Use { use_kw } => use_kw.shrink_to_lo(), rustc_hir::CaptureBy::Ref => fn_decl_span.shrink_to_lo(), }; diag.span_suggestion_verbose( diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 5f632bdc517d..b04d3256f7be 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2305,6 +2305,7 @@ impl<'a> State<'a> { fn print_capture_clause(&mut self, capture_clause: hir::CaptureBy) { match capture_clause { hir::CaptureBy::Value { .. } => self.word_space("move"), + hir::CaptureBy::Use { .. } => self.word_space("use"), hir::CaptureBy::Ref => {} } } diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 9a0b22470585..4c2a0e1a26b1 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -670,7 +670,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { origin = updated.1; let (place, capture_kind) = match capture_clause { - hir::CaptureBy::Value { .. } => adjust_for_move_closure(place, capture_kind), + hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } => { + adjust_for_move_closure(place, capture_kind) + } hir::CaptureBy::Ref => adjust_for_non_move_closure(place, capture_kind), }; @@ -1165,7 +1167,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = match closure_clause { hir::CaptureBy::Value { .. } => ty, // For move closure the capture kind should be by value - hir::CaptureBy::Ref => { + hir::CaptureBy::Ref | hir::CaptureBy::Use { .. } => { // For non move closure the capture kind is the max capture kind of all captures // according to the ordering ImmBorrow < UniqueImmBorrow < MutBorrow < ByValue let mut max_capture_info = root_var_min_capture_list.first().unwrap().info; @@ -1292,7 +1294,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .insert(UpvarMigrationInfo::CapturingNothing { use_span: upvar.span }); return Some(diagnostics_info); } - hir::CaptureBy::Ref => {} + hir::CaptureBy::Ref | hir::CaptureBy::Use { .. } => {} } return None; @@ -1689,10 +1691,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // If the data will be moved out of this place, then the place will be truncated // at the first Deref in `adjust_for_move_closure` and then moved into the closure. - hir::CaptureBy::Value { .. } if !place.deref_tys().any(Ty::is_ref) => { + hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } + if !place.deref_tys().any(Ty::is_ref) => + { ty::UpvarCapture::ByValue } - hir::CaptureBy::Value { .. } | hir::CaptureBy::Ref => { + hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } | hir::CaptureBy::Ref => { ty::UpvarCapture::ByRef(BorrowKind::Immutable) } } diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 0289fa5f4933..a1d7d321d8aa 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -26,6 +26,9 @@ parse_async_move_block_in_2015 = `async move` blocks are only allowed in Rust 20 parse_async_move_order_incorrect = the order of `move` and `async` is incorrect .suggestion = try switching the order +parse_async_use_order_incorrect = the order of `use` and `async` is incorrect + .suggestion = try switching the order + parse_at_dot_dot_in_struct_pattern = `@ ..` is not supported in struct patterns .suggestion = bind to each field separately or, if you don't need them, just remove `{$ident} @` diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index d89bb1451b63..f75fc8f98305 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1512,6 +1512,14 @@ pub(crate) struct AsyncMoveOrderIncorrect { pub span: Span, } +#[derive(Diagnostic)] +#[diag(parse_async_use_order_incorrect)] +pub(crate) struct AsyncUseOrderIncorrect { + #[primary_span] + #[suggestion(style = "verbose", code = "async use", applicability = "maybe-incorrect")] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(parse_double_colon_in_bound)] pub(crate) struct DoubleColonInBound { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c00f7f2d8de0..b37dd64fbed6 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1404,6 +1404,7 @@ impl<'a> Parser<'a> { } else if this.check_path() { this.parse_expr_path_start() } else if this.check_keyword(exp!(Move)) + || this.check_keyword(exp!(Use)) || this.check_keyword(exp!(Static)) || this.check_const_closure() { @@ -2395,7 +2396,7 @@ impl<'a> Parser<'a> { Ok(closure) } - /// Parses an optional `move` prefix to a closure-like construct. + /// Parses an optional `move` or `use` prefix to a closure-like construct. fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> { if self.eat_keyword(exp!(Move)) { let move_kw_span = self.prev_token.span; @@ -2408,6 +2409,16 @@ impl<'a> Parser<'a> { } else { Ok(CaptureBy::Value { move_kw: move_kw_span }) } + } else if self.eat_keyword(exp!(Use)) { + let use_kw_span = self.prev_token.span; + self.psess.gated_spans.gate(sym::ergonomic_clones, use_kw_span); + // Check for `use async` and recover + if self.check_keyword(exp!(Async)) { + let use_async_span = self.token.span.with_lo(self.prev_token.span.data().lo); + Err(self.dcx().create_err(errors::AsyncUseOrderIncorrect { span: use_async_span })) + } else { + Ok(CaptureBy::Use { use_kw: use_kw_span }) + } } else { Ok(CaptureBy::Ref) } @@ -3422,7 +3433,7 @@ impl<'a> Parser<'a> { self.is_keyword_ahead(lookahead, &[kw]) && (( // `async move {` - self.is_keyword_ahead(lookahead + 1, &[kw::Move]) + self.is_keyword_ahead(lookahead + 1, &[kw::Move, kw::Use]) && self.look_ahead(lookahead + 2, |t| { *t == token::OpenDelim(Delimiter::Brace) || t.is_whole_block() }) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 3f642a7ac1fd..7b511f503dde 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1290,7 +1290,7 @@ impl<'a> Parser<'a> { if self.check_keyword(exp!(Static)) { // Check if this could be a closure. !self.look_ahead(1, |token| { - if token.is_keyword(kw::Move) { + if token.is_keyword(kw::Move) || token.is_keyword(kw::Use) { return true; } matches!(token.kind, token::Or | token::OrOr) diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr index 905e1249d972..152a6f3a41e6 100644 --- a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -44,22 +44,22 @@ note: while trying to match `r#async` LL | (r#async) => (1) | ^^^^^^^ -error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` +error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||` --> $DIR/auxiliary/edition-kw-macro-2015.rs:27:23 | LL | ($i: ident) => ($i) - | ^ expected one of `move`, `|`, or `||` + | ^ expected one of `move`, `use`, `|`, or `||` | ::: $DIR/edition-keywords-2018-2015-parsing.rs:22:8 | LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved | -------------------- in this macro invocation -error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` +error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||` --> $DIR/edition-keywords-2018-2015-parsing.rs:24:24 | LL | if passes_tt!(async) == 1 {} - | ^ expected one of `move`, `|`, or `||` + | ^ expected one of `move`, `use`, `|`, or `||` error[E0308]: mismatched types --> $DIR/edition-keywords-2018-2015-parsing.rs:29:33 diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr index af5cc515bb22..53f1b827f9c6 100644 --- a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -44,34 +44,34 @@ note: while trying to match `r#async` LL | (r#async) => (1) | ^^^^^^^ -error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` +error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||` --> $DIR/auxiliary/edition-kw-macro-2018.rs:27:23 | LL | ($i: ident) => ($i) - | ^ expected one of `move`, `|`, or `||` + | ^ expected one of `move`, `use`, `|`, or `||` | ::: $DIR/edition-keywords-2018-2018-parsing.rs:29:8 | LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved | -------------------- in this macro invocation -error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` +error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||` --> $DIR/edition-keywords-2018-2018-parsing.rs:31:24 | LL | if passes_tt!(async) == 1 {} - | ^ expected one of `move`, `|`, or `||` + | ^ expected one of `move`, `use`, `|`, or `||` -error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` +error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||` --> $DIR/edition-keywords-2018-2018-parsing.rs:14:23 | LL | ($i: ident) => ($i) - | ^ expected one of `move`, `|`, or `||` + | ^ expected one of `move`, `use`, `|`, or `||` -error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` +error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||` --> $DIR/edition-keywords-2018-2018-parsing.rs:35:30 | LL | if local_passes_tt!(async) == 1 {} - | ^ expected one of `move`, `|`, or `||` + | ^ expected one of `move`, `use`, `|`, or `||` error[E0308]: mismatched types --> $DIR/edition-keywords-2018-2018-parsing.rs:40:33 diff --git a/tests/ui/ergonomic-clones/closure.rs b/tests/ui/ergonomic-clones/closure.rs new file mode 100644 index 000000000000..ea5c06457f53 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure.rs @@ -0,0 +1,23 @@ +//@ check-pass +//@ edition:2018 + +#![feature(ergonomic_clones)] + +fn ergonomic_clone_closure() -> i32 { + let cl = use || { + 1 + }; + cl() +} + +fn ergonomic_clone_async_closures() -> String { + let s = String::from("hi"); + + async use { + 22 + }; + + s +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs index be65afd85d92..f00f15174b25 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs @@ -7,12 +7,13 @@ fn ergonomic_closure_clone() { let s1 = String::from("hi!"); let s2 = use || { - //~^ ERROR incorrect use of `use` + //~^ ERROR `.use` calls are experimental [E0658] s1 }; let s3 = use || { - //~^ ERROR incorrect use of `use` + //~^ ERROR `.use` calls are experimental [E0658] + //~| ERROR use of moved value: `s1` [E0382] s1 }; } diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr index 61583239815c..c83b4400d3c2 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr @@ -1,39 +1,3 @@ -error: incorrect use of `use` - --> $DIR/feature-gate-ergonomic-clones.rs:9:14 - | -LL | let s2 = use || { - | ______________^ -LL | | -LL | | s1 -LL | | }; - | |_____^ - | -help: `use` is a postfix operation - | -LL ~ let s2 = || { -LL | -LL | s1 -LL ~ }.use; - | - -error: incorrect use of `use` - --> $DIR/feature-gate-ergonomic-clones.rs:14:14 - | -LL | let s3 = use || { - | ______________^ -LL | | -LL | | s1 -LL | | }; - | |_____^ - | -help: `use` is a postfix operation - | -LL ~ let s3 = || { -LL | -LL | s1 -LL ~ }.use; - | - error[E0658]: `.use` calls are experimental --> $DIR/feature-gate-ergonomic-clones.rs:2:7 | @@ -44,6 +8,50 @@ LL | x.use = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 3 previous errors +error[E0658]: `.use` calls are experimental + --> $DIR/feature-gate-ergonomic-clones.rs:9:14 + | +LL | let s2 = use || { + | ^^^ + | + = note: see issue #132290 for more information + = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -For more information about this error, try `rustc --explain E0658`. +error[E0658]: `.use` calls are experimental + --> $DIR/feature-gate-ergonomic-clones.rs:14:14 + | +LL | let s3 = use || { + | ^^^ + | + = note: see issue #132290 for more information + = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0382]: use of moved value: `s1` + --> $DIR/feature-gate-ergonomic-clones.rs:14:14 + | +LL | let s1 = String::from("hi!"); + | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait +LL | +LL | let s2 = use || { + | ------ value moved into closure here +LL | +LL | s1 + | -- variable moved due to use in closure +... +LL | let s3 = use || { + | ^^^^^^ value used here after move +... +LL | s1 + | -- use occurs due to use in closure + | +help: consider cloning the value if the performance cost is acceptable + | +LL | s1.clone() + | ++++++++ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0382, E0658. +For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/parser/block-no-opening-brace.rs b/tests/ui/parser/block-no-opening-brace.rs index 2fde37ce6ace..b08c830bfc76 100644 --- a/tests/ui/parser/block-no-opening-brace.rs +++ b/tests/ui/parser/block-no-opening-brace.rs @@ -30,7 +30,7 @@ fn in_try() { // FIXME(#80931) fn in_async() { async - let x = 0; //~ ERROR expected one of `move`, `|`, or `||`, found keyword `let` + let x = 0; //~ ERROR expected one of `move`, `use`, `|`, or `||`, found keyword `let` } // FIXME(#78168) diff --git a/tests/ui/parser/block-no-opening-brace.stderr b/tests/ui/parser/block-no-opening-brace.stderr index b65de4eac3f8..f51ee92626f5 100644 --- a/tests/ui/parser/block-no-opening-brace.stderr +++ b/tests/ui/parser/block-no-opening-brace.stderr @@ -43,11 +43,11 @@ error: expected expression, found reserved keyword `try` LL | try | ^^^ expected expression -error: expected one of `move`, `|`, or `||`, found keyword `let` +error: expected one of `move`, `use`, `|`, or `||`, found keyword `let` --> $DIR/block-no-opening-brace.rs:33:9 | LL | async - | - expected one of `move`, `|`, or `||` + | - expected one of `move`, `use`, `|`, or `||` LL | let x = 0; | ^^^ unexpected token diff --git a/tests/ui/parser/misspelled-keywords/async-move.stderr b/tests/ui/parser/misspelled-keywords/async-move.stderr index a002d54dc911..2507326fb285 100644 --- a/tests/ui/parser/misspelled-keywords/async-move.stderr +++ b/tests/ui/parser/misspelled-keywords/async-move.stderr @@ -1,8 +1,8 @@ -error: expected one of `move`, `|`, or `||`, found `Move` +error: expected one of `move`, `use`, `|`, or `||`, found `Move` --> $DIR/async-move.rs:4:11 | LL | async Move {} - | ^^^^ expected one of `move`, `|`, or `||` + | ^^^^ expected one of `move`, `use`, `|`, or `||` | help: write keyword `move` in lowercase | diff --git a/tests/ui/parser/recover/recover-quantified-closure.rs b/tests/ui/parser/recover/recover-quantified-closure.rs index 10af39b70074..1f5004ad0998 100644 --- a/tests/ui/parser/recover/recover-quantified-closure.rs +++ b/tests/ui/parser/recover/recover-quantified-closure.rs @@ -7,6 +7,6 @@ fn main() { enum Foo { Bar } fn foo(x: impl Iterator) { for ::Bar in x {} - //~^ ERROR expected one of `move`, `static`, `|` + //~^ ERROR expected one of `move`, `static`, `use`, `|` //~^^ ERROR `for<...>` binders for closures are experimental } diff --git a/tests/ui/parser/recover/recover-quantified-closure.stderr b/tests/ui/parser/recover/recover-quantified-closure.stderr index 6e03bbb58695..48dea071ae64 100644 --- a/tests/ui/parser/recover/recover-quantified-closure.stderr +++ b/tests/ui/parser/recover/recover-quantified-closure.stderr @@ -1,8 +1,8 @@ -error: expected one of `move`, `static`, `|`, or `||`, found `::` +error: expected one of `move`, `static`, `use`, `|`, or `||`, found `::` --> $DIR/recover-quantified-closure.rs:9:14 | LL | for ::Bar in x {} - | ^^ expected one of `move`, `static`, `|`, or `||` + | ^^ expected one of `move`, `static`, `use`, `|`, or `||` error[E0658]: `for<...>` binders for closures are experimental --> $DIR/recover-quantified-closure.rs:2:5 From 57cb498989ac29fbe9938ed2f4a31a3eab6850dc Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 17 Dec 2024 12:27:02 -0300 Subject: [PATCH 748/991] Generate the right MIR for by use closures --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 2 +- compiler/rustc_hir_typeck/src/upvar.rs | 38 ++++++++++++++----- compiler/rustc_middle/src/ty/closure.rs | 7 +++- compiler/rustc_mir_build/src/builder/mod.rs | 4 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 13 ++++++- .../src/coroutine/by_move_body.rs | 2 +- compiler/rustc_passes/src/liveness.rs | 4 +- tests/ui/ergonomic-clones/closure.rs | 13 ++++++- .../feature-gate-ergonomic-clones.rs | 1 - .../feature-gate-ergonomic-clones.stderr | 28 +------------- 10 files changed, 65 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index bd9173e6163f..7e037d56ffea 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1086,7 +1086,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ); match capture_info.capture_kind { - ty::UpvarCapture::ByValue => { + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => { self.consume_or_copy(&place_with_id, place_with_id.hir_id); } ty::UpvarCapture::ByRef(upvar_borrow) => { diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 4c2a0e1a26b1..3c5fcdd005ed 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -670,9 +670,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { origin = updated.1; let (place, capture_kind) = match capture_clause { - hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } => { - adjust_for_move_closure(place, capture_kind) - } + hir::CaptureBy::Value { .. } => adjust_for_move_closure(place, capture_kind), + hir::CaptureBy::Use { .. } => adjust_for_use_closure(place, capture_kind), hir::CaptureBy::Ref => adjust_for_non_move_closure(place, capture_kind), }; @@ -1307,7 +1306,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for captured_place in root_var_min_capture_list.iter() { match captured_place.info.capture_kind { // Only care about captures that are moved into the closure - ty::UpvarCapture::ByValue => { + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => { projections_list.push(captured_place.place.projections.as_slice()); diagnostics_info.insert(UpvarMigrationInfo::CapturingPrecise { source_expr: captured_place.info.path_expr_id, @@ -1931,7 +1930,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>( region: ty::Region<'tcx>, ) -> Ty<'tcx> { match capture_kind { - ty::UpvarCapture::ByValue => ty, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => ty, ty::UpvarCapture::ByRef(kind) => Ty::new_ref(tcx, region, ty, kind.to_mutbl_lossy()), } } @@ -2168,6 +2167,20 @@ fn adjust_for_move_closure( (place, ty::UpvarCapture::ByValue) } +/// Truncate deref of any reference. +fn adjust_for_use_closure( + mut place: Place<'_>, + mut kind: ty::UpvarCapture, +) -> (Place<'_>, ty::UpvarCapture) { + let first_deref = place.projections.iter().position(|proj| proj.kind == ProjectionKind::Deref); + + if let Some(idx) = first_deref { + truncate_place_to_len_and_update_capture_kind(&mut place, &mut kind, idx); + } + + (place, ty::UpvarCapture::ByUse) +} + /// Adjust closure capture just that if taking ownership of data, only move data /// from enclosing stack frame. fn adjust_for_non_move_closure( @@ -2178,7 +2191,7 @@ fn adjust_for_non_move_closure( place.projections.iter().position(|proj| proj.kind == ProjectionKind::Deref); match kind { - ty::UpvarCapture::ByValue => { + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => { if let Some(idx) = contains_deref { truncate_place_to_len_and_update_capture_kind(&mut place, &mut kind, idx); } @@ -2223,6 +2236,7 @@ fn construct_capture_kind_reason_string<'tcx>( let capture_kind_str = match capture_info.capture_kind { ty::UpvarCapture::ByValue => "ByValue".into(), + ty::UpvarCapture::ByUse => "ByUse".into(), ty::UpvarCapture::ByRef(kind) => format!("{kind:?}"), }; @@ -2244,6 +2258,7 @@ fn construct_capture_info_string<'tcx>( let capture_kind_str = match capture_info.capture_kind { ty::UpvarCapture::ByValue => "ByValue".into(), + ty::UpvarCapture::ByUse => "ByUse".into(), ty::UpvarCapture::ByRef(kind) => format!("{kind:?}"), }; format!("{place_str} -> {capture_kind_str}") @@ -2339,8 +2354,11 @@ fn determine_capture_info( // expressions. let eq_capture_kind = match (capture_info_a.capture_kind, capture_info_b.capture_kind) { (ty::UpvarCapture::ByValue, ty::UpvarCapture::ByValue) => true, + (ty::UpvarCapture::ByUse, ty::UpvarCapture::ByUse) => true, (ty::UpvarCapture::ByRef(ref_a), ty::UpvarCapture::ByRef(ref_b)) => ref_a == ref_b, - (ty::UpvarCapture::ByValue, _) | (ty::UpvarCapture::ByRef(_), _) => false, + (ty::UpvarCapture::ByValue, _) + | (ty::UpvarCapture::ByUse, _) + | (ty::UpvarCapture::ByRef(_), _) => false, }; if eq_capture_kind { @@ -2350,8 +2368,10 @@ fn determine_capture_info( } } else { // We select the CaptureKind which ranks higher based the following priority order: - // ByValue > MutBorrow > UniqueImmBorrow > ImmBorrow + // (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow match (capture_info_a.capture_kind, capture_info_b.capture_kind) { + (ty::UpvarCapture::ByUse, _) => capture_info_a, + (_, ty::UpvarCapture::ByUse) => capture_info_b, (ty::UpvarCapture::ByValue, _) => capture_info_a, (_, ty::UpvarCapture::ByValue) => capture_info_b, (ty::UpvarCapture::ByRef(ref_a), ty::UpvarCapture::ByRef(ref_b)) => { @@ -2405,7 +2425,7 @@ fn truncate_place_to_len_and_update_capture_kind<'tcx>( } ty::UpvarCapture::ByRef(..) => {} - ty::UpvarCapture::ByValue => {} + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => {} } place.projections.truncate(len); diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 3605f2402e7f..5d9b1ddfa38e 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -51,6 +51,9 @@ pub enum UpvarCapture { /// depending on inference. ByValue, + /// Upvar is captured by use. This is true when the closure is labeled `use`. + ByUse, + /// Upvar is captured by reference. ByRef(BorrowKind), } @@ -178,7 +181,7 @@ impl<'tcx> CapturedPlace<'tcx> { pub fn is_by_ref(&self) -> bool { match self.info.capture_kind { - ty::UpvarCapture::ByValue => false, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => false, ty::UpvarCapture::ByRef(..) => true, } } @@ -214,7 +217,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn closure_captures(self, def_id: LocalDefId) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] { if !self.is_closure_like(def_id.to_def_id()) { return &[]; - }; + } self.closure_typeinfo(def_id).captures } } diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 949559549345..ff2b59ee07d2 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -37,7 +37,7 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( .map(|captured_place| { let name = captured_place.to_symbol(); match captured_place.info.capture_kind { - ty::UpvarCapture::ByValue => name, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => name, ty::UpvarCapture::ByRef(..) => Symbol::intern(&format!("_ref__{name}")), } }) @@ -871,7 +871,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut projs = closure_env_projs.clone(); projs.push(ProjectionElem::Field(FieldIdx::new(i), ty)); match capture { - ty::UpvarCapture::ByValue => {} + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => {} ty::UpvarCapture::ByRef(..) => { projs.push(ProjectionElem::Deref); } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 40e84be72b10..e46e8c9871a5 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -652,7 +652,7 @@ impl<'tcx> ThirBuildCx<'tcx> { } }, - hir::ExprKind::Closure { .. } => { + hir::ExprKind::Closure(hir::Closure { .. }) => { let closure_ty = self.typeck_results.expr_ty(expr); let (def_id, args, movability) = match *closure_ty.kind() { ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args), None), @@ -1252,6 +1252,17 @@ impl<'tcx> ThirBuildCx<'tcx> { match upvar_capture { ty::UpvarCapture::ByValue => captured_place_expr, + ty::UpvarCapture::ByUse => { + let span = captured_place_expr.span; + let expr_id = self.thir.exprs.push(captured_place_expr); + + Expr { + temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible }, + ty: upvar_ty, + span: closure_expr.span, + kind: ExprKind::ByUse { expr: expr_id, span }, + } + } ty::UpvarCapture::ByRef(upvar_borrow) => { let borrow_kind = match upvar_borrow { ty::BorrowKind::Immutable => BorrowKind::Shared, diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 0f5fcb0d8eb9..c79ea14d6f64 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -170,7 +170,7 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( // this when building the field projection in the MIR body later on. let mut parent_capture_ty = parent_capture.place.ty(); parent_capture_ty = match parent_capture.info.capture_kind { - ty::UpvarCapture::ByValue => parent_capture_ty, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => parent_capture_ty, ty::UpvarCapture::ByRef(kind) => Ty::new_ref( tcx, tcx.lifetimes.re_erased, diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 84fb169c5f75..822804893fe2 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -706,7 +706,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ); self.acc(self.exit_ln, var, ACC_READ | ACC_USE); } - ty::UpvarCapture::ByValue => {} + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => {} } } } @@ -1500,7 +1500,7 @@ impl<'tcx> Liveness<'_, 'tcx> { for (&var_hir_id, min_capture_list) in closure_min_captures { for captured_place in min_capture_list { match captured_place.info.capture_kind { - ty::UpvarCapture::ByValue => {} + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => {} ty::UpvarCapture::ByRef(..) => continue, }; let span = captured_place.get_capture_kind_span(self.ir.tcx); diff --git a/tests/ui/ergonomic-clones/closure.rs b/tests/ui/ergonomic-clones/closure.rs index ea5c06457f53..340b9ece50e6 100644 --- a/tests/ui/ergonomic-clones/closure.rs +++ b/tests/ui/ergonomic-clones/closure.rs @@ -3,18 +3,27 @@ #![feature(ergonomic_clones)] -fn ergonomic_clone_closure() -> i32 { +fn ergonomic_clone_closure_no_captures() -> i32 { let cl = use || { 1 }; cl() } +fn ergonomic_clone_closure_with_captures() -> String { + let s = String::from("hi"); + + let cl = use || { + s + }; + cl() +} + fn ergonomic_clone_async_closures() -> String { let s = String::from("hi"); async use { - 22 + s }; s diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs index f00f15174b25..0ffc3925005e 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs @@ -13,7 +13,6 @@ fn ergonomic_closure_clone() { let s3 = use || { //~^ ERROR `.use` calls are experimental [E0658] - //~| ERROR use of moved value: `s1` [E0382] s1 }; } diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr index c83b4400d3c2..366151c91a63 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr @@ -28,30 +28,6 @@ LL | let s3 = use || { = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0382]: use of moved value: `s1` - --> $DIR/feature-gate-ergonomic-clones.rs:14:14 - | -LL | let s1 = String::from("hi!"); - | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait -LL | -LL | let s2 = use || { - | ------ value moved into closure here -LL | -LL | s1 - | -- variable moved due to use in closure -... -LL | let s3 = use || { - | ^^^^^^ value used here after move -... -LL | s1 - | -- use occurs due to use in closure - | -help: consider cloning the value if the performance cost is acceptable - | -LL | s1.clone() - | ++++++++ +error: aborting due to 3 previous errors -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0382, E0658. -For more information about an error, try `rustc --explain E0382`. +For more information about this error, try `rustc --explain E0658`. From dcdfd551f05073ececfa437be002ce7804b31c91 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 11 Dec 2024 18:00:56 -0300 Subject: [PATCH 749/991] Add UseCloned trait related code --- compiler/rustc_hir/src/lang_items.rs | 1 + .../rustc_mir_build/src/builder/expr/into.rs | 72 ++++++++++++------- compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_trait_selection/src/infer.rs | 10 +++ library/alloc/src/lib.rs | 1 + library/alloc/src/rc.rs | 7 ++ library/alloc/src/sync.rs | 7 ++ library/core/src/clone.rs | 34 +++++++++ library/core/src/num/bignum.rs | 2 + library/core/src/num/nonzero.rs | 4 ++ library/core/src/option.rs | 3 + library/core/src/result.rs | 8 +++ tests/ui/ergonomic-clones/closure.rs | 30 ++++++-- tests/ui/ergonomic-clones/dotuse.rs | 9 ++- .../feature-gate-ergonomic-clones.rs | 21 ++++-- .../feature-gate-ergonomic-clones.stderr | 32 +++++++-- 16 files changed, 198 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index f5626937ec45..2c73ea6a11a7 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -171,6 +171,7 @@ language_item_table! { Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0); Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None; CloneFn, sym::clone_fn, clone_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; + UseCloned, sym::use_cloned, use_cloned_trait, Target::Trait, GenericRequirement::None; Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0); DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None; /// The associated item of the `DiscriminantKind` trait. diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index d89f3773e4ab..333e69475c50 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -11,6 +11,7 @@ use rustc_middle::thir::*; use rustc_middle::ty::{CanonicalUserTypeAnnotation, Ty}; use rustc_span::DUMMY_SP; use rustc_span::source_map::Spanned; +use rustc_trait_selection::infer::InferCtxtExt; use tracing::{debug, instrument}; use crate::builder::expr::category::{Category, RvalueFunc}; @@ -295,33 +296,52 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let place = unpack!(block = this.as_place(block, expr)); let ty = place.ty(&this.local_decls, this.tcx).ty; - // Convert `expr.use` to a call like `Clone::clone(&expr)` - let success = this.cfg.start_new_block(); - let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None); - let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0]; - let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span); - let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty); - let ref_place = this.temp(ref_ty, span); - this.cfg.push_assign( - block, - source_info, - ref_place, - Rvalue::Ref(this.tcx.lifetimes.re_erased, BorrowKind::Shared, place), - ); - this.cfg.terminate( - block, - source_info, - TerminatorKind::Call { - func, - args: [Spanned { node: Operand::Move(ref_place), span: DUMMY_SP }].into(), + if this.tcx.type_is_copy_modulo_regions(this.infcx.typing_env(this.param_env), ty) { + this.cfg.push_assign( + block, + source_info, destination, - target: Some(success), - unwind: UnwindAction::Unreachable, - call_source: CallSource::Misc, - fn_span: expr_span, - }, - ); - success.unit() + Rvalue::Use(Operand::Copy(place)), + ); + block.unit() + } else if this.infcx.type_is_use_cloned_modulo_regions(this.param_env, ty) { + // Convert `expr.use` to a call like `Clone::clone(&expr)` + let success = this.cfg.start_new_block(); + let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None); + let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0]; + let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span); + let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty); + let ref_place = this.temp(ref_ty, span); + this.cfg.push_assign( + block, + source_info, + ref_place, + Rvalue::Ref(this.tcx.lifetimes.re_erased, BorrowKind::Shared, place), + ); + this.cfg.terminate( + block, + source_info, + TerminatorKind::Call { + func, + args: [Spanned { node: Operand::Move(ref_place), span: DUMMY_SP }] + .into(), + destination, + target: Some(success), + unwind: UnwindAction::Unreachable, + call_source: CallSource::Misc, + fn_span: expr_span, + }, + ); + success.unit() + } else { + this.cfg.push_assign( + block, + source_info, + destination, + Rvalue::Use(Operand::Move(place)), + ); + block.unit() + } } ExprKind::Use { source } => this.expr_into_dest(destination, block, source), ExprKind::Borrow { arg, borrow_kind } => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3357e085a7d2..a8c38d8244de 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2182,6 +2182,7 @@ symbols! { unwrap, unwrap_binder, unwrap_or, + use_cloned, use_extern_macros, use_nested_groups, used, diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index f373706b2960..5cf0600ade8b 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -53,6 +53,16 @@ impl<'tcx> InferCtxt<'tcx> { traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id) } + fn type_is_use_cloned_modulo_regions( + &self, + param_env: ty::ParamEnv<'tcx>, + ty: Ty<'tcx>, + ) -> bool { + let ty = self.resolve_vars_if_possible(ty); + let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, None); + traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, use_cloned_def_id) + } + fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index cb93100f56cf..aac0eefc5196 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -113,6 +113,7 @@ #![feature(deprecated_suggestion)] #![feature(deref_pure_trait)] #![feature(dispatch_from_dyn)] +#![feature(ergonomic_clones)] #![feature(error_generic_member_access)] #![feature(exact_size_is_empty)] #![feature(extend_one)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 09206c2f8b29..5847bd8f2813 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -245,6 +245,7 @@ use core::any::Any; use core::cell::Cell; #[cfg(not(no_global_oom_handling))] use core::clone::CloneToUninit; +use core::clone::UseCloned; use core::cmp::Ordering; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; @@ -2333,6 +2334,9 @@ impl Clone for Rc { } } +#[unstable(feature = "ergonomic_clones", issue = "132290")] +impl UseCloned for Rc {} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Default for Rc { @@ -3496,6 +3500,9 @@ impl Clone for Weak { } } +#[unstable(feature = "ergonomic_clones", issue = "132290")] +impl UseCloned for Weak {} + #[stable(feature = "rc_weak", since = "1.4.0")] impl fmt::Debug for Weak { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index dba1449347ac..ddd0677ee350 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -11,6 +11,7 @@ use core::any::Any; #[cfg(not(no_global_oom_handling))] use core::clone::CloneToUninit; +use core::clone::UseCloned; use core::cmp::Ordering; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; @@ -2197,6 +2198,9 @@ impl Clone for Arc { } } +#[unstable(feature = "ergonomic_clones", issue = "132290")] +impl UseCloned for Arc {} + #[stable(feature = "rust1", since = "1.0.0")] impl Deref for Arc { type Target = T; @@ -3158,6 +3162,9 @@ impl Clone for Weak { } } +#[unstable(feature = "ergonomic_clones", issue = "132290")] +impl UseCloned for Weak {} + #[stable(feature = "downgraded_weak", since = "1.10.0")] impl Default for Weak { /// Constructs a new `Weak`, without allocating memory. diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 00300328b64c..249ca6c091fd 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -184,6 +184,40 @@ pub macro Clone($item:item) { /* compiler built-in */ } +/// Trait for objects whose [`Clone`] impl is lightweight (e.g. reference-counted) +/// +/// Cloning an object implementing this trait should in general: +/// - be O(1) (constant) time regardless of the amount of data managed by the object, +/// - not require a memory allocation, +/// - not require copying more than roughly 64 bytes (a typical cache line size), +/// - not block the current thread, +/// - not have any semantic side effects (e.g. allocating a file descriptor), and +/// - not have overhead larger than a couple of atomic operations. +/// +/// The `UseCloned` trait does not provide a method; instead, it indicates that +/// `Clone::clone` is lightweight, and allows the use of the `.use` syntax. +#[unstable(feature = "ergonomic_clones", issue = "132290")] +#[cfg_attr(not(bootstrap), lang = "use_cloned")] +pub trait UseCloned: Clone { + // Empty. +} + +macro_rules! impl_use_cloned { + ($($t:ty)*) => { + $( + #[unstable(feature = "ergonomic_clones", issue = "132290")] + impl UseCloned for $t {} + )* + } +} + +impl_use_cloned! { + usize u8 u16 u32 u64 u128 + isize i8 i16 i32 i64 i128 + f16 f32 f64 f128 + bool char +} + // FIXME(aburka): these structs are used solely by #[derive] to // assert that every component of a type implements Clone or Copy. // diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs index 2a47c89e2aee..9de6b349d946 100644 --- a/library/core/src/num/bignum.rs +++ b/library/core/src/num/bignum.rs @@ -405,6 +405,8 @@ macro_rules! define_bignum { } } + impl crate::clone::UseCloned for $name {} + impl crate::fmt::Debug for $name { fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result { let sz = if self.size < 1 { 1 } else { self.size }; diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index a967b72c4fa9..5b997d44278c 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1,6 +1,7 @@ //! Definitions of integer that is known not to equal zero. use super::{IntErrorKind, ParseIntError}; +use crate::clone::UseCloned; use crate::cmp::Ordering; use crate::hash::{Hash, Hasher}; use crate::marker::{Freeze, StructuralPartialEq}; @@ -183,6 +184,9 @@ where } } +#[unstable(feature = "ergonomic_clones", issue = "132290")] +impl UseCloned for NonZero where T: ZeroablePrimitive {} + #[stable(feature = "nonzero", since = "1.28.0")] impl Copy for NonZero where T: ZeroablePrimitive {} diff --git a/library/core/src/option.rs b/library/core/src/option.rs index a9f06b92ad5d..f668c6f06724 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2050,6 +2050,9 @@ where } } +#[unstable(feature = "ergonomic_clones", issue = "132290")] +impl crate::clone::UseCloned for Option where T: crate::clone::UseCloned {} + #[stable(feature = "rust1", since = "1.0.0")] impl Default for Option { /// Returns [`None`][Option::None]. diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 92b5cba15316..ee98a47523fe 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1744,6 +1744,14 @@ where } } +#[unstable(feature = "ergonomic_clones", issue = "132290")] +impl crate::clone::UseCloned for Result +where + T: crate::clone::UseCloned, + E: crate::clone::UseCloned, +{ +} + #[stable(feature = "rust1", since = "1.0.0")] impl IntoIterator for Result { type Item = T; diff --git a/tests/ui/ergonomic-clones/closure.rs b/tests/ui/ergonomic-clones/closure.rs index 340b9ece50e6..19ef6f4e13db 100644 --- a/tests/ui/ergonomic-clones/closure.rs +++ b/tests/ui/ergonomic-clones/closure.rs @@ -3,6 +3,9 @@ #![feature(ergonomic_clones)] +use std::clone::UseCloned; +use std::future::Future; + fn ergonomic_clone_closure_no_captures() -> i32 { let cl = use || { 1 @@ -10,7 +13,7 @@ fn ergonomic_clone_closure_no_captures() -> i32 { cl() } -fn ergonomic_clone_closure_with_captures() -> String { +fn ergonomic_clone_closure_move() -> String { let s = String::from("hi"); let cl = use || { @@ -19,14 +22,31 @@ fn ergonomic_clone_closure_with_captures() -> String { cl() } -fn ergonomic_clone_async_closures() -> String { +#[derive(Clone)] +struct Foo; + +impl UseCloned for Foo {} + +fn ergonomic_clone_closure_use_cloned() -> Foo { + let f = Foo; + + let f1 = use || { + f + }; + + let f2 = use || { + f + }; + + f +} + +fn ergonomic_clone_async_closures() -> impl Future { let s = String::from("hi"); async use { s - }; - - s + } } fn main() {} diff --git a/tests/ui/ergonomic-clones/dotuse.rs b/tests/ui/ergonomic-clones/dotuse.rs index 928c27296b16..4bab400fef28 100644 --- a/tests/ui/ergonomic-clones/dotuse.rs +++ b/tests/ui/ergonomic-clones/dotuse.rs @@ -2,11 +2,18 @@ #![feature(ergonomic_clones)] +use std::clone::UseCloned; + fn basic_test(x: i32) -> i32 { x.use.use.abs() } -fn do_not_move_test(x: String) -> String { +#[derive(Clone)] +struct Foo; + +impl UseCloned for Foo {} + +fn do_not_move_test(x: Foo) -> Foo { let s = x.use; x } diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs index 0ffc3925005e..8ae78e27d0ef 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs @@ -1,19 +1,28 @@ +use std::clone::UseCloned; +//~^ ERROR use of unstable library feature `ergonomic_clones` [E0658] + fn ergonomic_clone(x: i32) -> i32 { x.use //~^ ERROR `.use` calls are experimental [E0658] } -fn ergonomic_closure_clone() { - let s1 = String::from("hi!"); +#[derive(Clone)] +struct Foo; - let s2 = use || { +impl UseCloned for Foo {} +//~^ ERROR use of unstable library feature `ergonomic_clones` [E0658] + +fn ergonomic_closure_clone() { + let f1 = Foo; + + let f2 = use || { //~^ ERROR `.use` calls are experimental [E0658] - s1 + f1 }; - let s3 = use || { + let f3 = use || { //~^ ERROR `.use` calls are experimental [E0658] - s1 + f1 }; } diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr index 366151c91a63..68d64715620f 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr @@ -1,5 +1,5 @@ error[E0658]: `.use` calls are experimental - --> $DIR/feature-gate-ergonomic-clones.rs:2:7 + --> $DIR/feature-gate-ergonomic-clones.rs:5:7 | LL | x.use | ^^^ @@ -9,9 +9,9 @@ LL | x.use = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `.use` calls are experimental - --> $DIR/feature-gate-ergonomic-clones.rs:9:14 + --> $DIR/feature-gate-ergonomic-clones.rs:18:14 | -LL | let s2 = use || { +LL | let f2 = use || { | ^^^ | = note: see issue #132290 for more information @@ -19,15 +19,35 @@ LL | let s2 = use || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `.use` calls are experimental - --> $DIR/feature-gate-ergonomic-clones.rs:14:14 + --> $DIR/feature-gate-ergonomic-clones.rs:23:14 | -LL | let s3 = use || { +LL | let f3 = use || { | ^^^ | = note: see issue #132290 for more information = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 3 previous errors +error[E0658]: use of unstable library feature `ergonomic_clones` + --> $DIR/feature-gate-ergonomic-clones.rs:1:5 + | +LL | use std::clone::UseCloned; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132290 for more information + = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `ergonomic_clones` + --> $DIR/feature-gate-ergonomic-clones.rs:12:6 + | +LL | impl UseCloned for Foo {} + | ^^^^^^^^^ + | + = note: see issue #132290 for more information + = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0658`. From 60b64701041a87e81fa56d4cab312d353dfd977b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 26 Dec 2024 18:15:50 -0300 Subject: [PATCH 750/991] Fix clippy --- src/tools/clippy/clippy_lints/src/escape.rs | 2 ++ .../clippy/clippy_lints/src/loops/mut_range_bound.rs | 2 ++ src/tools/clippy/clippy_lints/src/loops/never_loop.rs | 1 + .../clippy/clippy_lints/src/matches/manual_utils.rs | 2 +- .../clippy_lints/src/methods/iter_overeager_cloned.rs | 2 ++ .../clippy/clippy_lints/src/needless_pass_by_ref_mut.rs | 2 ++ .../clippy/clippy_lints/src/needless_pass_by_value.rs | 2 ++ .../clippy_lints/src/operators/assign_op_pattern.rs | 2 ++ src/tools/clippy/clippy_lints/src/option_if_let_else.rs | 2 +- src/tools/clippy/clippy_lints/src/unwrap.rs | 2 ++ src/tools/clippy/clippy_lints/src/utils/author.rs | 6 ++++++ src/tools/clippy/clippy_utils/src/eager_or_lazy.rs | 1 + src/tools/clippy/clippy_utils/src/hir_utils.rs | 5 +++++ src/tools/clippy/clippy_utils/src/lib.rs | 9 ++++++--- src/tools/clippy/clippy_utils/src/sugg.rs | 4 ++++ src/tools/clippy/clippy_utils/src/usage.rs | 2 ++ src/tools/clippy/clippy_utils/src/visitors.rs | 3 +++ 17 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 8d1e893cb1af..33ba401d60c2 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -150,6 +150,8 @@ impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> { } } + fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) { if cmt.place.projections.is_empty() { if let PlaceBase::Local(lid) = cmt.place.base { diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index 39e5e140b7a4..fb5d49a10047 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -79,6 +79,8 @@ struct MutatePairDelegate<'a, 'tcx> { impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) { if bk == ty::BorrowKind::Mutable { if let PlaceBase::Local(id) = cmt.place.base { diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs index b679fdfadc3a..dd7a6f77acff 100644 --- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs @@ -160,6 +160,7 @@ fn never_loop_expr<'tcx>( | ExprKind::UnsafeBinderCast(_, e, _) => never_loop_expr(cx, e, local_labels, main_loop_id), ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, local_labels, main_loop_id), ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, es.iter(), local_labels, main_loop_id), + ExprKind::Use(expr, _) => never_loop_expr(cx, expr, local_labels, main_loop_id), ExprKind::MethodCall(_, receiver, es, _) => { never_loop_expr_all(cx, once(receiver).chain(es.iter()), local_labels, main_loop_id) }, diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs index 09440c396ee1..d0905733ab50 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs @@ -99,7 +99,7 @@ where }); if let ExprKind::Path(QPath::Resolved(None, Path { res: Res::Local(l), .. })) = e.kind { match captures.get(l) { - Some(CaptureKind::Value | CaptureKind::Ref(Mutability::Mut)) => return None, + Some(CaptureKind::Value | CaptureKind::Use | CaptureKind::Ref(Mutability::Mut)) => return None, Some(CaptureKind::Ref(Mutability::Not)) if binding_ref_mutability == Mutability::Mut => { return None; }, diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs index a80977459f21..f51bdc78f8a5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -147,6 +147,8 @@ impl<'tcx> Delegate<'tcx> for MoveDelegate { } } + fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn borrow(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId, _: BorrowKind) {} fn mutate(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index d5c5679c990d..dc10de24bc8c 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -396,6 +396,8 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> { } } + fn use_cloned(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {} + #[allow(clippy::if_same_then_else)] fn borrow(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, id: HirId, borrow: ty::BorrowKind) { self.prev_bind = None; diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 380cc380ad0f..dc85176ebb9e 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -326,6 +326,8 @@ impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt { self.move_common(cmt); } + fn use_cloned(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {} + fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {} fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {} diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 5737a91031db..03b907ebdf4d 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -112,6 +112,7 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { } fn consume(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn use_cloned(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: HirId) {} fn copy(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} @@ -137,6 +138,7 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { } fn consume(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn use_cloned(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: HirId) {} fn copy(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} diff --git a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs index de9f055863cb..75b18bc651e2 100644 --- a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs +++ b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs @@ -177,7 +177,7 @@ fn try_get_option_occurrence<'tcx>( .then_some(()) .and_then(|()| none_captures.get(local_id)) }) { - Some(CaptureKind::Value | CaptureKind::Ref(Mutability::Mut)) => return None, + Some(CaptureKind::Value | CaptureKind::Use | CaptureKind::Ref(Mutability::Mut)) => return None, Some(CaptureKind::Ref(Mutability::Not)) if as_mut => return None, Some(CaptureKind::Ref(Mutability::Not)) | None => (), } diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 76b9bbbd32fd..6f6683eb9712 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -230,6 +230,8 @@ impl<'tcx> Delegate<'tcx> for MutationVisitor<'tcx> { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {} } diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 5fc166438e84..9d8c161873c0 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -426,6 +426,11 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("Tup({elements})"); self.slice(elements, |e| self.expr(e)); }, + ExprKind::Use(expr, _) => { + bind!(self, expr); + kind!("Use({expr})"); + self.expr(expr); + }, ExprKind::Binary(op, left, right) => { bind!(self, op, left, right); kind!("Binary({op}, {left}, {right})"); @@ -488,6 +493,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }) => { let capture_clause = match capture_clause { CaptureBy::Value { .. } => "Value { .. }", + CaptureBy::Use { .. } => "Use { .. }", CaptureBy::Ref => "Ref", }; diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index aaea8d71efbe..4543a20cc2cd 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -291,6 +291,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS ExprKind::ConstBlock(_) | ExprKind::Array(_) | ExprKind::Tup(_) + | ExprKind::Use(..) | ExprKind::Lit(_) | ExprKind::Cast(..) | ExprKind::Type(..) diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 4bd86a253351..dd0ac224e456 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -393,6 +393,7 @@ impl HirEqInterExpr<'_, '_, '_> { && over(lf, rf, |l, r| self.eq_expr_field(l, r)) }, (&ExprKind::Tup(l_tup), &ExprKind::Tup(r_tup)) => self.eq_exprs(l_tup, r_tup), + (&ExprKind::Use(l_expr, _), &ExprKind::Use(r_expr, _)) => self.eq_expr(l_expr, r_expr), (&ExprKind::Type(le, lt), &ExprKind::Type(re, rt)) => self.eq_expr(le, re) && self.eq_ty(lt, rt), (&ExprKind::Unary(l_op, le), &ExprKind::Unary(r_op, re)) => l_op == r_op && self.eq_expr(le, re), (&ExprKind::Yield(le, _), &ExprKind::Yield(re, _)) => return self.eq_expr(le, re), @@ -425,6 +426,7 @@ impl HirEqInterExpr<'_, '_, '_> { | &ExprKind::Ret(..) | &ExprKind::Struct(..) | &ExprKind::Tup(..) + | &ExprKind::Use(..) | &ExprKind::Type(..) | &ExprKind::Unary(..) | &ExprKind::Yield(..) @@ -1053,6 +1055,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { ExprKind::Tup(tup) => { self.hash_exprs(tup); }, + ExprKind::Use(expr, _) => { + self.hash_expr(expr); + }, ExprKind::Unary(lop, le) => { std::mem::discriminant(&lop).hash(&mut self.s); self.hash_expr(le); diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index d850cc410008..723ae9b01a80 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1129,6 +1129,7 @@ pub fn can_move_expr_to_closure_no_visit<'tcx>( #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum CaptureKind { Value, + Use, Ref(Mutability), } impl CaptureKind { @@ -1141,6 +1142,7 @@ impl std::ops::BitOr for CaptureKind { fn bitor(self, rhs: Self) -> Self::Output { match (self, rhs) { (CaptureKind::Value, _) | (_, CaptureKind::Value) => CaptureKind::Value, + (CaptureKind::Use, _) | (_, CaptureKind::Use) => CaptureKind::Use, (CaptureKind::Ref(Mutability::Mut), CaptureKind::Ref(_)) | (CaptureKind::Ref(_), CaptureKind::Ref(Mutability::Mut)) => CaptureKind::Ref(Mutability::Mut), (CaptureKind::Ref(Mutability::Not), CaptureKind::Ref(Mutability::Not)) => CaptureKind::Ref(Mutability::Not), @@ -1220,7 +1222,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind { }, ExprKind::Let(let_expr) => { let mutability = match pat_capture_kind(cx, let_expr.pat) { - CaptureKind::Value => Mutability::Not, + CaptureKind::Value | CaptureKind::Use => Mutability::Not, CaptureKind::Ref(m) => m, }; return CaptureKind::Ref(mutability); @@ -1229,7 +1231,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind { let mut mutability = Mutability::Not; for capture in arms.iter().map(|arm| pat_capture_kind(cx, arm.pat)) { match capture { - CaptureKind::Value => break, + CaptureKind::Value | CaptureKind::Use => break, CaptureKind::Ref(Mutability::Mut) => mutability = Mutability::Mut, CaptureKind::Ref(Mutability::Not) => (), } @@ -1239,7 +1241,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind { _ => break, }, Node::LetStmt(l) => match pat_capture_kind(cx, l.pat) { - CaptureKind::Value => break, + CaptureKind::Value | CaptureKind::Use => break, capture @ CaptureKind::Ref(_) => return capture, }, _ => break, @@ -1294,6 +1296,7 @@ pub fn can_move_expr_to_closure<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<' if !self.locals.contains(&local_id) { let capture = match capture.info.capture_kind { UpvarCapture::ByValue => CaptureKind::Value, + UpvarCapture::ByUse => CaptureKind::Use, UpvarCapture::ByRef(kind) => match kind { BorrowKind::Immutable => CaptureKind::Ref(Mutability::Not), BorrowKind::UniqueImmutable | BorrowKind::Mutable => { diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 4a9ab17d4a60..24b4f0d9e6d8 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -147,6 +147,7 @@ impl<'a> Sugg<'a> { | ExprKind::Become(..) | ExprKind::Struct(..) | ExprKind::Tup(..) + | ExprKind::Use(..) | ExprKind::Err(_) | ExprKind::UnsafeBinderCast(..) => Sugg::NonParen(get_snippet(expr.span)), ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet), @@ -217,6 +218,7 @@ impl<'a> Sugg<'a> { | ast::ExprKind::Try(..) | ast::ExprKind::TryBlock(..) | ast::ExprKind::Tup(..) + | ast::ExprKind::Use(..) | ast::ExprKind::Array(..) | ast::ExprKind::While(..) | ast::ExprKind::Await(..) @@ -835,6 +837,8 @@ impl<'tcx> DerefDelegate<'_, 'tcx> { impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) { if let PlaceBase::Local(id) = cmt.place.base { let map = self.cx.tcx.hir(); diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs index 3bf518f7fe70..a079fd940c00 100644 --- a/src/tools/clippy/clippy_utils/src/usage.rs +++ b/src/tools/clippy/clippy_utils/src/usage.rs @@ -66,6 +66,8 @@ impl MutVarsDelegate { impl<'tcx> Delegate<'tcx> for MutVarsDelegate { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind) { if bk == ty::BorrowKind::Mutable { self.update(cmt); diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 2ac0efd7e392..63dd00f2de0f 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -648,6 +648,9 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( helper(typeck, true, arg, f)?; } }, + ExprKind::Use(expr, _) => { + helper(typeck, true, expr, f)?; + }, ExprKind::Index(borrowed, consumed, _) | ExprKind::Assign(borrowed, consumed, _) | ExprKind::AssignOp(_, borrowed, consumed) => { From 8c456cbf5fe7c1d9e574a50dead0f26e890fe07c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 27 Dec 2024 01:43:49 -0300 Subject: [PATCH 751/991] Fix rustfmt --- src/tools/rustfmt/src/expr.rs | 4 ++++ src/tools/rustfmt/src/utils.rs | 1 + 2 files changed, 5 insertions(+) diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index 16b7e7aa709d..eff2d2e3ff4a 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -137,6 +137,10 @@ pub(crate) fn format_expr( ast::ExprKind::Tup(ref items) => { rewrite_tuple(context, items.iter(), expr.span, shape, items.len() == 1) } + ast::ExprKind::Use(_, _) => { + // FIXME: properly implement this + Ok(context.snippet(expr.span()).to_owned()) + } ast::ExprKind::Let(ref pat, ref expr, _span, _) => rewrite_let(context, shape, pat, expr), ast::ExprKind::If(..) | ast::ExprKind::ForLoop { .. } diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index ba4a4c045f1c..fe716c186389 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -513,6 +513,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Become(..) | ast::ExprKind::Yeet(..) | ast::ExprKind::Tup(..) + | ast::ExprKind::Use(..) | ast::ExprKind::Type(..) | ast::ExprKind::Yield(None) | ast::ExprKind::Underscore => false, From 4cbca777ea94b2d7b5e59d1511fad858326e3e4b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 27 Dec 2024 12:39:48 -0300 Subject: [PATCH 752/991] Separate closures, async and dotuse tests in directories --- tests/ui/ergonomic-clones/async/basic.rs | 16 ++++++++++++++++ .../{closure.rs => closure/basic.rs} | 9 --------- .../{dotuse.rs => dotuse/basic.rs} | 0 3 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 tests/ui/ergonomic-clones/async/basic.rs rename tests/ui/ergonomic-clones/{closure.rs => closure/basic.rs} (78%) rename tests/ui/ergonomic-clones/{dotuse.rs => dotuse/basic.rs} (100%) diff --git a/tests/ui/ergonomic-clones/async/basic.rs b/tests/ui/ergonomic-clones/async/basic.rs new file mode 100644 index 000000000000..46d12afe0d15 --- /dev/null +++ b/tests/ui/ergonomic-clones/async/basic.rs @@ -0,0 +1,16 @@ +//@ check-pass +//@ edition:2018 + +#![feature(ergonomic_clones)] + +use std::future::Future; + +fn ergonomic_clone_async_closures() -> impl Future { + let s = String::from("hi"); + + async use { + s + } +} + +fn main() {} diff --git a/tests/ui/ergonomic-clones/closure.rs b/tests/ui/ergonomic-clones/closure/basic.rs similarity index 78% rename from tests/ui/ergonomic-clones/closure.rs rename to tests/ui/ergonomic-clones/closure/basic.rs index 19ef6f4e13db..71fc32ccb1fb 100644 --- a/tests/ui/ergonomic-clones/closure.rs +++ b/tests/ui/ergonomic-clones/closure/basic.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ edition:2018 #![feature(ergonomic_clones)] @@ -41,12 +40,4 @@ fn ergonomic_clone_closure_use_cloned() -> Foo { f } -fn ergonomic_clone_async_closures() -> impl Future { - let s = String::from("hi"); - - async use { - s - } -} - fn main() {} diff --git a/tests/ui/ergonomic-clones/dotuse.rs b/tests/ui/ergonomic-clones/dotuse/basic.rs similarity index 100% rename from tests/ui/ergonomic-clones/dotuse.rs rename to tests/ui/ergonomic-clones/dotuse/basic.rs From 38b4746d824294d05d87a6e461113a99ac052c34 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 10 Feb 2025 18:09:31 -0300 Subject: [PATCH 753/991] Support nested use closures --- compiler/rustc_parse/src/parser/item.rs | 4 +++- tests/ui/ergonomic-clones/closure/nested.rs | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/ui/ergonomic-clones/closure/nested.rs diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 7b511f503dde..961e81989d6a 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -209,7 +209,9 @@ impl<'a> Parser<'a> { let check_pub = def == &Defaultness::Final; let mut def_ = || mem::replace(def, Defaultness::Final); - let info = if self.eat_keyword_case(exp!(Use), case) { + let info = if !self.look_ahead(1, |t| [token::OrOr, token::Or].contains(&t.kind)) + && self.eat_keyword_case(exp!(Use), case) + { self.parse_use_item()? } else if self.check_fn_front_matter(check_pub, case) { // FUNCTION ITEM diff --git a/tests/ui/ergonomic-clones/closure/nested.rs b/tests/ui/ergonomic-clones/closure/nested.rs new file mode 100644 index 000000000000..5876396f087f --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/nested.rs @@ -0,0 +1,20 @@ +//@ run-pass + +#![feature(ergonomic_clones)] + +use std::clone::UseCloned; + +#[derive(Clone)] +struct Foo; + +impl UseCloned for Foo {} + +fn work(_: Box) {} +fn foo(_: F) {} + +pub fn main() { + let a = Box::new(Foo); + foo(use || { foo(use || { work(a) }) }); + let x = use || { use || { Foo } }; + let _y = x(); +} From 7c17bf8e824aefcc4272168f1cbda21c1683dcbe Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 10 Feb 2025 18:17:39 -0300 Subject: [PATCH 754/991] Add tests --- tests/ui/ergonomic-clones/async/local-type.rs | 9 ++++ .../ergonomic-clones/async/local-type.stderr | 15 ++++++ tests/ui/ergonomic-clones/closure/basic.rs | 14 +++++ tests/ui/ergonomic-clones/closure/fn-once.rs | 13 +++++ .../ergonomic-clones/closure/fn-once.stderr | 16 ++++++ .../ui/ergonomic-clones/closure/local-type.rs | 8 +++ .../closure/local-type.stderr | 15 ++++++ .../closure/once-move-out-on-heap.rs | 18 +++++++ tests/ui/ergonomic-clones/closure/parse.rs | 23 ++++++++ .../ui/ergonomic-clones/closure/parse.stderr | 34 ++++++++++++ .../ergonomic-clones/closure/print-verbose.rs | 27 ++++++++++ .../closure/print-verbose.stderr | 20 +++++++ tests/ui/ergonomic-clones/closure/print.rs | 25 +++++++++ .../ui/ergonomic-clones/closure/print.stderr | 20 +++++++ .../ergonomic-clones/closure/with-binders.rs | 9 ++++ tests/ui/ergonomic-clones/dotuse/parse.rs | 38 +++++++++++++ tests/ui/ergonomic-clones/dotuse/parse.stderr | 53 +++++++++++++++++++ 17 files changed, 357 insertions(+) create mode 100644 tests/ui/ergonomic-clones/async/local-type.rs create mode 100644 tests/ui/ergonomic-clones/async/local-type.stderr create mode 100644 tests/ui/ergonomic-clones/closure/fn-once.rs create mode 100644 tests/ui/ergonomic-clones/closure/fn-once.stderr create mode 100644 tests/ui/ergonomic-clones/closure/local-type.rs create mode 100644 tests/ui/ergonomic-clones/closure/local-type.stderr create mode 100644 tests/ui/ergonomic-clones/closure/once-move-out-on-heap.rs create mode 100644 tests/ui/ergonomic-clones/closure/parse.rs create mode 100644 tests/ui/ergonomic-clones/closure/parse.stderr create mode 100644 tests/ui/ergonomic-clones/closure/print-verbose.rs create mode 100644 tests/ui/ergonomic-clones/closure/print-verbose.stderr create mode 100644 tests/ui/ergonomic-clones/closure/print.rs create mode 100644 tests/ui/ergonomic-clones/closure/print.stderr create mode 100644 tests/ui/ergonomic-clones/closure/with-binders.rs create mode 100644 tests/ui/ergonomic-clones/dotuse/parse.rs create mode 100644 tests/ui/ergonomic-clones/dotuse/parse.stderr diff --git a/tests/ui/ergonomic-clones/async/local-type.rs b/tests/ui/ergonomic-clones/async/local-type.rs new file mode 100644 index 000000000000..54808ef494ec --- /dev/null +++ b/tests/ui/ergonomic-clones/async/local-type.rs @@ -0,0 +1,9 @@ +// Check that using the parameter name in its type does not ICE. +//@ edition:2018 + +#![feature(ergonomic_clones)] + +fn main() { + let _ = async use |x: x| x; //~ ERROR expected type + let _ = async use |x: bool| -> x { x }; //~ ERROR expected type +} diff --git a/tests/ui/ergonomic-clones/async/local-type.stderr b/tests/ui/ergonomic-clones/async/local-type.stderr new file mode 100644 index 000000000000..35f6d7fa3ad1 --- /dev/null +++ b/tests/ui/ergonomic-clones/async/local-type.stderr @@ -0,0 +1,15 @@ +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type.rs:7:27 + | +LL | let _ = async use |x: x| x; + | ^ not a type + +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type.rs:8:36 + | +LL | let _ = async use |x: bool| -> x { x }; + | ^ not a type + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/ergonomic-clones/closure/basic.rs b/tests/ui/ergonomic-clones/closure/basic.rs index 71fc32ccb1fb..aba8ebd53e4a 100644 --- a/tests/ui/ergonomic-clones/closure/basic.rs +++ b/tests/ui/ergonomic-clones/closure/basic.rs @@ -40,4 +40,18 @@ fn ergonomic_clone_closure_use_cloned() -> Foo { f } +fn ergonomic_clone_closure_copy() -> i32 { + let i = 1; + + let i1 = use || { + i + }; + + let i2 = use || { + i + }; + + i +} + fn main() {} diff --git a/tests/ui/ergonomic-clones/closure/fn-once.rs b/tests/ui/ergonomic-clones/closure/fn-once.rs new file mode 100644 index 000000000000..51049fe57c71 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/fn-once.rs @@ -0,0 +1,13 @@ +#![feature(ergonomic_clones)] + +fn get_closure() -> Box Vec> { + let vec = vec![1u8, 2u8]; + + let closure = use || { //~ ERROR expected a closure + vec + }; + + Box::new(closure) +} + +fn main() {} diff --git a/tests/ui/ergonomic-clones/closure/fn-once.stderr b/tests/ui/ergonomic-clones/closure/fn-once.stderr new file mode 100644 index 000000000000..20dd70e625d8 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/fn-once.stderr @@ -0,0 +1,16 @@ +error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` + --> $DIR/fn-once.rs:6:19 + | +LL | let closure = use || { + | ^^^^^^ this closure implements `FnOnce`, not `Fn` +LL | vec + | --- closure is `FnOnce` because it moves the variable `vec` out of its environment +... +LL | Box::new(closure) + | ----------------- the requirement to implement `Fn` derives from here + | + = note: required for the cast from `Box<{closure@$DIR/fn-once.rs:6:19: 6:25}>` to `Box<(dyn Fn() -> Vec + 'static)>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0525`. diff --git a/tests/ui/ergonomic-clones/closure/local-type.rs b/tests/ui/ergonomic-clones/closure/local-type.rs new file mode 100644 index 000000000000..291faebd7657 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/local-type.rs @@ -0,0 +1,8 @@ +// Check that using the parameter name in its type does not ICE. + +#![feature(ergonomic_clones)] + +fn main() { + let _ = use |x: x| x; //~ ERROR expected type + let _ = use |x: bool| -> x { x }; //~ ERROR expected type +} diff --git a/tests/ui/ergonomic-clones/closure/local-type.stderr b/tests/ui/ergonomic-clones/closure/local-type.stderr new file mode 100644 index 000000000000..8a9d20890374 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/local-type.stderr @@ -0,0 +1,15 @@ +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type.rs:6:21 + | +LL | let _ = use |x: x| x; + | ^ not a type + +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type.rs:7:30 + | +LL | let _ = use |x: bool| -> x { x }; + | ^ not a type + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/ergonomic-clones/closure/once-move-out-on-heap.rs b/tests/ui/ergonomic-clones/closure/once-move-out-on-heap.rs new file mode 100644 index 000000000000..50240114aa91 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/once-move-out-on-heap.rs @@ -0,0 +1,18 @@ +//@ run-pass +// Testing guarantees provided by once functions. + +#![feature(ergonomic_clones)] + +use std::sync::Arc; + +fn foo(blk: F) { + blk(); +} + +pub fn main() { + let x = Arc::new(true); + foo(use || { + assert!(*x); + drop(x); + }); +} diff --git a/tests/ui/ergonomic-clones/closure/parse.rs b/tests/ui/ergonomic-clones/closure/parse.rs new file mode 100644 index 000000000000..d4523de57ffa --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/parse.rs @@ -0,0 +1,23 @@ +#![feature(ergonomic_clones)] + +fn parse1() { + || use { + //~^ ERROR expected one of `async`, `|`, or `||`, found `{` + }; +} + +fn parse2() { + move use || { + //~^ ERROR expected one of `async`, `|`, or `||`, found keyword `use` + }; +} + +fn parse3() { + use move || { + //~^ ERROR expected identifier, found keyword `move` + //~| ERROR expected one of `::`, `;`, or `as`, found `||` + // FIXME ideally we should error like in the previous example + }; +} + +fn main() {} diff --git a/tests/ui/ergonomic-clones/closure/parse.stderr b/tests/ui/ergonomic-clones/closure/parse.stderr new file mode 100644 index 000000000000..ac86a0419298 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/parse.stderr @@ -0,0 +1,34 @@ +error: expected one of `async`, `|`, or `||`, found `{` + --> $DIR/parse.rs:4:12 + | +LL | || use { + | -- ^ expected one of `async`, `|`, or `||` + | | + | while parsing the body of this closure + | +help: you might have meant to open the body of the closure, instead of enclosing the closure in a block + | +LL ~ fn parse1() +LL ~ || { use { + | + +error: expected one of `async`, `|`, or `||`, found keyword `use` + --> $DIR/parse.rs:10:10 + | +LL | move use || { + | ^^^ expected one of `async`, `|`, or `||` + +error: expected identifier, found keyword `move` + --> $DIR/parse.rs:16:9 + | +LL | use move || { + | ^^^^ expected identifier, found keyword + +error: expected one of `::`, `;`, or `as`, found `||` + --> $DIR/parse.rs:16:14 + | +LL | use move || { + | ^^ expected one of `::`, `;`, or `as` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/ergonomic-clones/closure/print-verbose.rs b/tests/ui/ergonomic-clones/closure/print-verbose.rs new file mode 100644 index 000000000000..b4fc51f91743 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/print-verbose.rs @@ -0,0 +1,27 @@ +//@ compile-flags: -Zverbose-internals + +#![feature(ergonomic_clones)] + +fn to_fn_once(f: F) -> F { + f +} + +fn f(y: T) { + struct Foo { + x: U, + }; + + let foo = Foo { x: "x" }; + + let c = to_fn_once(use || { + println!("{} {}", foo.x, y); + }); + + c(); + c(); + //~^ ERROR use of moved value +} + +fn main() { + f("S"); +} diff --git a/tests/ui/ergonomic-clones/closure/print-verbose.stderr b/tests/ui/ergonomic-clones/closure/print-verbose.stderr new file mode 100644 index 000000000000..a9d4dd32a201 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/print-verbose.stderr @@ -0,0 +1,20 @@ +error[E0382]: use of moved value: `c` + --> $DIR/print-verbose.rs:21:5 + | +LL | let c = to_fn_once(use || { + | - move occurs because `c` has type `{f::{closure#0} closure_kind_ty=i32 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=(Foo<&'?9 str>, T)}`, which does not implement the `Copy` trait +... +LL | c(); + | --- `c` moved due to this call +LL | c(); + | ^ value used here after move + | +note: this value implements `FnOnce`, which causes it to be moved when called + --> $DIR/print-verbose.rs:20:5 + | +LL | c(); + | ^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/ergonomic-clones/closure/print.rs b/tests/ui/ergonomic-clones/closure/print.rs new file mode 100644 index 000000000000..c3f03d2b2e11 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/print.rs @@ -0,0 +1,25 @@ +#![feature(ergonomic_clones)] + +fn to_fn_once(f: F) -> F { + f +} + +fn f(y: T) { + struct Foo { + x: U, + }; + + let foo = Foo { x: "x" }; + + let c = to_fn_once(use || { + println!("{} {}", foo.x, y); + }); + + c(); + c(); + //~^ ERROR use of moved value +} + +fn main() { + f("S"); +} diff --git a/tests/ui/ergonomic-clones/closure/print.stderr b/tests/ui/ergonomic-clones/closure/print.stderr new file mode 100644 index 000000000000..796ae46317ca --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/print.stderr @@ -0,0 +1,20 @@ +error[E0382]: use of moved value: `c` + --> $DIR/print.rs:19:5 + | +LL | let c = to_fn_once(use || { + | - move occurs because `c` has type `{closure@$DIR/print.rs:14:24: 14:30}`, which does not implement the `Copy` trait +... +LL | c(); + | --- `c` moved due to this call +LL | c(); + | ^ value used here after move + | +note: this value implements `FnOnce`, which causes it to be moved when called + --> $DIR/print.rs:18:5 + | +LL | c(); + | ^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/ergonomic-clones/closure/with-binders.rs b/tests/ui/ergonomic-clones/closure/with-binders.rs new file mode 100644 index 000000000000..952f6e48d44e --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/with-binders.rs @@ -0,0 +1,9 @@ +//@ edition:2021 +//@ check-pass + +#![feature(closure_lifetime_binder)] +#![feature(ergonomic_clones)] + +fn main() { + for<'a> use || -> () {}; +} diff --git a/tests/ui/ergonomic-clones/dotuse/parse.rs b/tests/ui/ergonomic-clones/dotuse/parse.rs new file mode 100644 index 000000000000..579d2dd774c8 --- /dev/null +++ b/tests/ui/ergonomic-clones/dotuse/parse.rs @@ -0,0 +1,38 @@ +#![feature(ergonomic_clones)] + +fn parse1() { + 1.use!; + //~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `!` + } + +fn parse2() { + 1.use!(2); + //~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `!` + } + +fn parse3() { + 1.use 2; + //~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `2` + } + +fn parse4() { + 1.use? 2; + //~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `2` + } + +fn parse5() { + 1.use(); + //~^ ERROR: incorrect use of `use` +} + +fn parse6() { + 1.use(2); + //~^ ERROR: expected function, found `{integer}` [E0618] +} + +fn parse7() { + 1.use { 2 }; + //~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` +} + +fn main() {} diff --git a/tests/ui/ergonomic-clones/dotuse/parse.stderr b/tests/ui/ergonomic-clones/dotuse/parse.stderr new file mode 100644 index 000000000000..b2240a12c4d2 --- /dev/null +++ b/tests/ui/ergonomic-clones/dotuse/parse.stderr @@ -0,0 +1,53 @@ +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `!` + --> $DIR/parse.rs:4:10 + | +LL | 1.use!; + | ^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `!` + --> $DIR/parse.rs:9:10 + | +LL | 1.use!(2); + | ^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `2` + --> $DIR/parse.rs:14:11 + | +LL | 1.use 2; + | ^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `2` + --> $DIR/parse.rs:19:12 + | +LL | 1.use? 2; + | ^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: incorrect use of `use` + --> $DIR/parse.rs:24:10 + | +LL | 1.use(); + | ^^ + | +help: `use` is not a method call, remove the parentheses + | +LL - 1.use(); +LL + 1.use; + | + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` + --> $DIR/parse.rs:34:11 + | +LL | 1.use { 2 }; + | ^ expected one of `.`, `;`, `?`, `}`, or an operator + +error[E0618]: expected function, found `{integer}` + --> $DIR/parse.rs:29:5 + | +LL | 1.use(2); + | ^^^^^--- + | | + | call expression requires function + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0618`. From 292aa8704957f0c0a94cc0cb01c74267d2bdfe27 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 11 Feb 2025 11:13:33 -0300 Subject: [PATCH 755/991] Fix use closure parsing error message --- compiler/rustc_parse/src/parser/item.rs | 19 ++++++++++++++++--- tests/ui/ergonomic-clones/closure/parse.rs | 4 +--- .../ui/ergonomic-clones/closure/parse.stderr | 12 +++--------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 961e81989d6a..678376aee4f8 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -209,9 +209,7 @@ impl<'a> Parser<'a> { let check_pub = def == &Defaultness::Final; let mut def_ = || mem::replace(def, Defaultness::Final); - let info = if !self.look_ahead(1, |t| [token::OrOr, token::Or].contains(&t.kind)) - && self.eat_keyword_case(exp!(Use), case) - { + let info = if !self.is_use_closure() && self.eat_keyword_case(exp!(Use), case) { self.parse_use_item()? } else if self.check_fn_front_matter(check_pub, case) { // FUNCTION ITEM @@ -1279,6 +1277,21 @@ impl<'a> Parser<'a> { None } + fn is_use_closure(&self) -> bool { + if self.token.is_keyword(kw::Use) { + // Check if this could be a closure. + self.look_ahead(1, |token| { + // Move or Async here would be an error but still we're parsing a closure + let dist = + if token.is_keyword(kw::Move) || token.is_keyword(kw::Async) { 2 } else { 1 }; + + self.look_ahead(dist, |token| matches!(token.kind, token::Or | token::OrOr)) + }) + } else { + false + } + } + fn is_unsafe_foreign_mod(&self) -> bool { self.token.is_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Extern]) diff --git a/tests/ui/ergonomic-clones/closure/parse.rs b/tests/ui/ergonomic-clones/closure/parse.rs index d4523de57ffa..23fce20e370f 100644 --- a/tests/ui/ergonomic-clones/closure/parse.rs +++ b/tests/ui/ergonomic-clones/closure/parse.rs @@ -14,9 +14,7 @@ fn parse2() { fn parse3() { use move || { - //~^ ERROR expected identifier, found keyword `move` - //~| ERROR expected one of `::`, `;`, or `as`, found `||` - // FIXME ideally we should error like in the previous example + //~^ ERROR expected one of `async`, `|`, or `||`, found keyword `move` }; } diff --git a/tests/ui/ergonomic-clones/closure/parse.stderr b/tests/ui/ergonomic-clones/closure/parse.stderr index ac86a0419298..c45c46eefa5c 100644 --- a/tests/ui/ergonomic-clones/closure/parse.stderr +++ b/tests/ui/ergonomic-clones/closure/parse.stderr @@ -18,17 +18,11 @@ error: expected one of `async`, `|`, or `||`, found keyword `use` LL | move use || { | ^^^ expected one of `async`, `|`, or `||` -error: expected identifier, found keyword `move` +error: expected one of `async`, `|`, or `||`, found keyword `move` --> $DIR/parse.rs:16:9 | LL | use move || { - | ^^^^ expected identifier, found keyword + | ^^^^ expected one of `async`, `|`, or `||` -error: expected one of `::`, `;`, or `as`, found `||` - --> $DIR/parse.rs:16:14 - | -LL | use move || { - | ^^ expected one of `::`, `;`, or `as` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors From 6eb6ff62f78560720f6902421dcd482cb70482ed Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 14 Feb 2025 18:35:43 -0300 Subject: [PATCH 756/991] Allow to mutate use captures --- compiler/rustc_borrowck/src/lib.rs | 20 ++++++++++++------- tests/ui/ergonomic-clones/closure/mutation.rs | 11 ++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 tests/ui/ergonomic-clones/closure/mutation.rs diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 68e0ab0933e6..64a533e05ffd 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1490,14 +1490,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { let stmt = &bbd.statements[loc.statement_index]; debug!("temporary assigned in: stmt={:?}", stmt); - if let StatementKind::Assign(box (_, Rvalue::Ref(_, _, source))) = stmt.kind - { - propagate_closure_used_mut_place(self, source); - } else { - bug!( - "closures should only capture user variables \ + match stmt.kind { + StatementKind::Assign(box ( + _, + Rvalue::Ref(_, _, source) + | Rvalue::Use(Operand::Copy(source) | Operand::Move(source)), + )) => { + propagate_closure_used_mut_place(self, source); + } + _ => { + bug!( + "closures should only capture user variables \ or references to user variables" - ); + ); + } } } _ => propagate_closure_used_mut_place(self, place), diff --git a/tests/ui/ergonomic-clones/closure/mutation.rs b/tests/ui/ergonomic-clones/closure/mutation.rs new file mode 100644 index 000000000000..2e2f0dddf80a --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/mutation.rs @@ -0,0 +1,11 @@ +//@ check-pass + +#![feature(ergonomic_clones)] + +fn main() { + let mut my_var = false; + let mut callback = use || { + my_var = true; + }; + callback(); +} From aa58439f87f58aa9c7b1ccfb5d52ae5d3d0f1106 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 14 Feb 2025 18:42:06 -0300 Subject: [PATCH 757/991] Fail gracefully if mutating on a use closure and the closure it not declared mut --- .../src/diagnostics/mutability_errors.rs | 2 +- tests/ui/ergonomic-clones/closure/mutation2.rs | 10 ++++++++++ .../ergonomic-clones/closure/mutation2.stderr | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/ui/ergonomic-clones/closure/mutation2.rs create mode 100644 tests/ui/ergonomic-clones/closure/mutation2.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index be4a7736b1c2..145137f92369 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -823,7 +823,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) => { capture_reason = format!("mutable borrow of `{upvar}`"); } - ty::UpvarCapture::ByValue => { + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => { capture_reason = format!("possible mutation of `{upvar}`"); } _ => bug!("upvar `{upvar}` borrowed, but not mutably"), diff --git a/tests/ui/ergonomic-clones/closure/mutation2.rs b/tests/ui/ergonomic-clones/closure/mutation2.rs new file mode 100644 index 000000000000..8a43f9232bf4 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/mutation2.rs @@ -0,0 +1,10 @@ +#![feature(ergonomic_clones)] + +fn main() { + let mut my_var = false; + let callback = use || { + my_var = true; + }; + callback(); + //~^ ERROR cannot borrow `callback` as mutable, as it is not declared as mutable [E0596] +} diff --git a/tests/ui/ergonomic-clones/closure/mutation2.stderr b/tests/ui/ergonomic-clones/closure/mutation2.stderr new file mode 100644 index 000000000000..3ee8f80ce223 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/mutation2.stderr @@ -0,0 +1,17 @@ +error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable + --> $DIR/mutation2.rs:8:5 + | +LL | my_var = true; + | ------ calling `callback` requires mutable binding due to possible mutation of `my_var` +LL | }; +LL | callback(); + | ^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut callback = use || { + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`. From 18d689c085ed7e560cb3c3ce8c9d5fb91a90e73c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 14 Feb 2025 15:51:01 -0300 Subject: [PATCH 758/991] Add more tests --- .../ergonomic-clones/closure/expect-region.rs | 25 +++++++++++++++++++ .../closure/expect-region.stderr | 22 ++++++++++++++++ .../closure/immutable-outer-variable.fixed | 15 +++++++++++ .../closure/immutable-outer-variable.rs | 15 +++++++++++ .../closure/immutable-outer-variable.stderr | 14 +++++++++++ 5 files changed, 91 insertions(+) create mode 100644 tests/ui/ergonomic-clones/closure/expect-region.rs create mode 100644 tests/ui/ergonomic-clones/closure/expect-region.stderr create mode 100644 tests/ui/ergonomic-clones/closure/immutable-outer-variable.fixed create mode 100644 tests/ui/ergonomic-clones/closure/immutable-outer-variable.rs create mode 100644 tests/ui/ergonomic-clones/closure/immutable-outer-variable.stderr diff --git a/tests/ui/ergonomic-clones/closure/expect-region.rs b/tests/ui/ergonomic-clones/closure/expect-region.rs new file mode 100644 index 000000000000..cbb13e56a18a --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/expect-region.rs @@ -0,0 +1,25 @@ +#![feature(ergonomic_clones)] +#![allow(warnings)] + +fn closure_expecting_bound(_: F) +where + F: FnOnce(&u32), +{ +} + +fn expect_bound_supply_named<'x>() { + let mut f: Option<&u32> = None; + + // Here we give a type annotation that `x` should be free. We get + // an error because of that. + closure_expecting_bound(use |x: &'x u32| { + //~^ ERROR lifetime may not live long enough + //~| ERROR lifetime may not live long enough + + // Borrowck doesn't get a chance to run, but if it did it should error + // here. + f = Some(x); + }); +} + +fn main() {} diff --git a/tests/ui/ergonomic-clones/closure/expect-region.stderr b/tests/ui/ergonomic-clones/closure/expect-region.stderr new file mode 100644 index 000000000000..4df1df1378b8 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/expect-region.stderr @@ -0,0 +1,22 @@ +error: lifetime may not live long enough + --> $DIR/expect-region.rs:15:34 + | +LL | fn expect_bound_supply_named<'x>() { + | -- lifetime `'x` defined here +... +LL | closure_expecting_bound(use |x: &'x u32| { + | ^ - let's call the lifetime of this reference `'1` + | | + | requires that `'1` must outlive `'x` + +error: lifetime may not live long enough + --> $DIR/expect-region.rs:15:34 + | +LL | fn expect_bound_supply_named<'x>() { + | -- lifetime `'x` defined here +... +LL | closure_expecting_bound(use |x: &'x u32| { + | ^ requires that `'x` must outlive `'static` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/ergonomic-clones/closure/immutable-outer-variable.fixed b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.fixed new file mode 100644 index 000000000000..510230ffb33e --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.fixed @@ -0,0 +1,15 @@ +//@ run-rustfix + +// Point at the captured immutable outer variable + +#![feature(ergonomic_clones)] + +fn foo(mut f: Box) { + f(); +} + +fn main() { + let mut y = true; + foo(Box::new(use || y = !y) as Box<_>); + //~^ ERROR cannot assign to `y`, as it is not declared as mutable +} diff --git a/tests/ui/ergonomic-clones/closure/immutable-outer-variable.rs b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.rs new file mode 100644 index 000000000000..8b2b72e11594 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.rs @@ -0,0 +1,15 @@ +//@ run-rustfix + +// Point at the captured immutable outer variable + +#![feature(ergonomic_clones)] + +fn foo(mut f: Box) { + f(); +} + +fn main() { + let y = true; + foo(Box::new(use || y = !y) as Box<_>); + //~^ ERROR cannot assign to `y`, as it is not declared as mutable +} diff --git a/tests/ui/ergonomic-clones/closure/immutable-outer-variable.stderr b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.stderr new file mode 100644 index 000000000000..70478c416657 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.stderr @@ -0,0 +1,14 @@ +error[E0594]: cannot assign to `y`, as it is not declared as mutable + --> $DIR/immutable-outer-variable.rs:13:25 + | +LL | foo(Box::new(use || y = !y) as Box<_>); + | ^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut y = true; + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0594`. From edcbc9b535f4321befc5b9552d633ff7d297bada Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 20 Feb 2025 13:06:38 -0300 Subject: [PATCH 759/991] Add a code example as comment in init_capture_kind_for_place --- compiler/rustc_hir_typeck/src/upvar.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 3c5fcdd005ed..43e3ebde67c8 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1690,6 +1690,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // If the data will be moved out of this place, then the place will be truncated // at the first Deref in `adjust_for_move_closure` and then moved into the closure. + // + // For example: + // + // struct Buffer<'a> { + // x: &'a String, + // y: Vec, + // } + // + // fn get<'a>(b: Buffer<'a>) -> impl Sized + 'a { + // let c = move || b.x; + // drop(b); + // c + // } + // + // Even though the closure is declared as move, when we are capturing borrowed data (in + // this case, *b.x) we prefer to capture by reference. + // Otherwise you'd get an error in 2021 immediately because you'd be trying to take + // ownership of the (borrowed) String or else you'd take ownership of b, as in 2018 and + // before, which is also an error. hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } if !place.deref_tys().any(Ty::is_ref) => { From b43b700250066fdd34673ee13e1a51824b18218e Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 20 Feb 2025 14:34:49 -0300 Subject: [PATCH 760/991] Account for UseCloned on expr_use_visitor --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 48 ++++++++++++++++++- compiler/rustc_hir_typeck/src/upvar.rs | 15 ++++++ compiler/rustc_lint/src/context.rs | 4 ++ compiler/rustc_middle/src/query/mod.rs | 5 ++ compiler/rustc_middle/src/ty/util.rs | 12 +++++ compiler/rustc_ty_utils/src/common_traits.rs | 16 ++++++- 6 files changed, 98 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 7e037d56ffea..4b6174769ea6 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -47,6 +47,21 @@ pub trait Delegate<'tcx> { /// the id of the binding in the pattern `pat`. fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId); + /// The value found at `place` is used, depending + /// on `mode`. Where `diag_expr_id` is the id used for diagnostics for `place`. + /// + /// Use of a `Copy` type in a ByUse context is considered a use + /// by `ImmBorrow` and `borrow` is called instead. This is because + /// a shared borrow is the "minimum access" that would be needed + /// to perform a copy. + /// + /// + /// The parameter `diag_expr_id` indicates the HIR id that ought to be used for + /// diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic + /// id will be the id of the expression `expr` but the place itself will have + /// the id of the binding in the pattern `pat`. + fn use_cloned(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId); + /// The value found at `place` is being borrowed with kind `bk`. /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). fn borrow( @@ -91,6 +106,10 @@ impl<'tcx, D: Delegate<'tcx>> Delegate<'tcx> for &mut D { (**self).consume(place_with_id, diag_expr_id) } + fn use_cloned(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + (**self).use_cloned(place_with_id, diag_expr_id) + } + fn borrow( &mut self, place_with_id: &PlaceWithHirId<'tcx>, @@ -143,6 +162,8 @@ pub trait TypeInformationCtxt<'tcx> { fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool; + fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool; + fn body_owner_def_id(&self) -> LocalDefId; fn tcx(&self) -> TyCtxt<'tcx>; @@ -184,6 +205,10 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { self.infcx.type_is_copy_modulo_regions(self.param_env, ty) } + fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool { + self.infcx.type_is_use_cloned_modulo_regions(self.param_env, ty) + } + fn body_owner_def_id(&self) -> LocalDefId { self.body_id } @@ -230,6 +255,10 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { self.0.type_is_copy_modulo_regions(ty) } + fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool { + self.0.type_is_use_cloned_modulo_regions(ty) + } + fn body_owner_def_id(&self) -> LocalDefId { self.1 } @@ -313,6 +342,23 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx Ok(()) } + pub fn consume_or_clone_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { + debug!("consume_or_clone_expr(expr={:?})", expr); + + let place_with_id = self.cat_expr(expr)?; + + if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) { + self.delegate.borrow_mut().copy(&place_with_id, place_with_id.hir_id); + } else if self.cx.type_is_use_cloned_modulo_regions(place_with_id.place.ty()) { + self.delegate.borrow_mut().use_cloned(&place_with_id, place_with_id.hir_id); + } else { + self.delegate.borrow_mut().consume(&place_with_id, place_with_id.hir_id); + } + + self.walk_expr(expr)?; + Ok(()) + } + fn mutate_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { let place_with_id = self.cat_expr(expr)?; self.delegate.borrow_mut().mutate(&place_with_id, place_with_id.hir_id); @@ -367,7 +413,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } hir::ExprKind::Use(expr, _) => { - self.consume_expr(expr)?; + self.consume_or_clone_expr(expr)?; } hir::ExprKind::MethodCall(.., receiver, args, _) => { diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 43e3ebde67c8..40a935afbac2 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -2045,6 +2045,21 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { )); } + #[instrument(skip(self), level = "debug")] + fn use_cloned(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return }; + assert_eq!(self.closure_def_id, upvar_id.closure_expr_id); + + self.capture_information.push(( + place_with_id.place.clone(), + ty::CaptureInfo { + capture_kind_expr_id: Some(diag_expr_id), + path_expr_id: Some(diag_expr_id), + capture_kind: ty::UpvarCapture::ByUse, + }, + )); + } + #[instrument(skip(self), level = "debug")] fn borrow( &mut self, diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 74663e6b4bbe..cd4106ebf83a 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -683,6 +683,10 @@ impl<'tcx> LateContext<'tcx> { self.tcx.type_is_copy_modulo_regions(self.typing_env(), ty) } + pub fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool { + self.tcx.type_is_use_cloned_modulo_regions(self.typing_env(), ty) + } + /// Gets the type-checking results for the current body, /// or `None` if outside a body. pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 1302027aabb3..cf623459898a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1533,6 +1533,11 @@ rustc_queries! { query is_copy_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Copy`", env.value } } + /// Trait selection queries. These are best used by invoking `ty.is_use_cloned_modulo_regions()`, + /// `ty.is_use_cloned()`, etc, since that will prune the environment where possible. + query is_use_cloned_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` is `UseCloned`", env.value } + } /// Query backing `Ty::is_sized`. query is_sized_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Sized`", env.value } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 237aa66f486f..0c68913904fc 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -192,6 +192,18 @@ impl<'tcx> TyCtxt<'tcx> { ty.is_trivially_pure_clone_copy() || self.is_copy_raw(typing_env.as_query_input(ty)) } + /// Checks whether `ty: UseCloned` holds while ignoring region constraints. + /// + /// This function should not be used if there is an `InferCtxt` available. + /// Use `InferCtxt::type_is_copy_modulo_regions` instead. + pub fn type_is_use_cloned_modulo_regions( + self, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, + ) -> bool { + ty.is_trivially_pure_clone_copy() || self.is_use_cloned_raw(typing_env.as_query_input(ty)) + } + /// Returns the deeply last field of nested structures, or the same type if /// not a structure at all. Corresponds to the only possible unsized field, /// and its type can be used to determine unsizing strategy. diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs index 2157ab3c4022..20646cf9a826 100644 --- a/compiler/rustc_ty_utils/src/common_traits.rs +++ b/compiler/rustc_ty_utils/src/common_traits.rs @@ -10,6 +10,13 @@ fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::PseudoCanonicalInput<'tcx, Ty is_item_raw(tcx, query, LangItem::Copy) } +fn is_use_cloned_raw<'tcx>( + tcx: TyCtxt<'tcx>, + query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>, +) -> bool { + is_item_raw(tcx, query, LangItem::UseCloned) +} + fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { is_item_raw(tcx, query, LangItem::Sized) } @@ -33,5 +40,12 @@ fn is_item_raw<'tcx>( } pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { is_copy_raw, is_sized_raw, is_freeze_raw, is_unpin_raw, ..*providers }; + *providers = Providers { + is_copy_raw, + is_use_cloned_raw, + is_sized_raw, + is_freeze_raw, + is_unpin_raw, + ..*providers + }; } From 2f48fcec63245de13d3017c392ee792ea7f44007 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 21 Feb 2025 17:08:46 -0300 Subject: [PATCH 761/991] Change feature flag error to be ergonomic clones are experimental --- compiler/rustc_ast_passes/src/feature_gate.rs | 2 +- tests/ui/ergonomic-clones/dotuse/parse.stderr | 2 +- tests/ui/feature-gates/feature-gate-ergonomic-clones.rs | 6 +++--- tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 0e798169af83..31ff102c127a 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -489,7 +489,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(dyn_star, "`dyn*` trait objects are experimental"); gate_all!(const_closures, "const closures are experimental"); gate_all!(builtin_syntax, "`builtin #` syntax is unstable"); - gate_all!(ergonomic_clones, "`.use` calls are experimental"); + gate_all!(ergonomic_clones, "ergonomic clones are experimental"); gate_all!(explicit_tail_calls, "`become` expression is experimental"); gate_all!(generic_const_items, "generic const items are experimental"); gate_all!(guard_patterns, "guard patterns are experimental", "consider using match arm guards"); diff --git a/tests/ui/ergonomic-clones/dotuse/parse.stderr b/tests/ui/ergonomic-clones/dotuse/parse.stderr index b2240a12c4d2..65bc5137af80 100644 --- a/tests/ui/ergonomic-clones/dotuse/parse.stderr +++ b/tests/ui/ergonomic-clones/dotuse/parse.stderr @@ -28,7 +28,7 @@ error: incorrect use of `use` LL | 1.use(); | ^^ | -help: `use` is not a method call, remove the parentheses +help: `use` is not a method call, try removing the parentheses | LL - 1.use(); LL + 1.use; diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs index 8ae78e27d0ef..fb2b853893ec 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs @@ -3,7 +3,7 @@ use std::clone::UseCloned; fn ergonomic_clone(x: i32) -> i32 { x.use - //~^ ERROR `.use` calls are experimental [E0658] + //~^ ERROR ergonomic clones are experimental [E0658] } #[derive(Clone)] @@ -16,12 +16,12 @@ fn ergonomic_closure_clone() { let f1 = Foo; let f2 = use || { - //~^ ERROR `.use` calls are experimental [E0658] + //~^ ERROR ergonomic clones are experimental [E0658] f1 }; let f3 = use || { - //~^ ERROR `.use` calls are experimental [E0658] + //~^ ERROR ergonomic clones are experimental [E0658] f1 }; } diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr index 68d64715620f..af1b2022ccff 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr @@ -1,4 +1,4 @@ -error[E0658]: `.use` calls are experimental +error[E0658]: ergonomic clones are experimental --> $DIR/feature-gate-ergonomic-clones.rs:5:7 | LL | x.use @@ -8,7 +8,7 @@ LL | x.use = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: `.use` calls are experimental +error[E0658]: ergonomic clones are experimental --> $DIR/feature-gate-ergonomic-clones.rs:18:14 | LL | let f2 = use || { @@ -18,7 +18,7 @@ LL | let f2 = use || { = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: `.use` calls are experimental +error[E0658]: ergonomic clones are experimental --> $DIR/feature-gate-ergonomic-clones.rs:23:14 | LL | let f3 = use || { From 4e6407ab947314480f3b978a20f9b0685ad59f78 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 21 Feb 2025 17:24:46 -0300 Subject: [PATCH 762/991] Give a better error message on async use in edition 2015 --- compiler/rustc_parse/messages.ftl | 2 ++ compiler/rustc_parse/src/errors.rs | 7 ++++++ .../rustc_parse/src/parser/diagnostics.rs | 23 ++++++++++++------- .../ui/ergonomic-clones/async/edition-2015.rs | 6 +++++ .../async/edition-2015.stderr | 8 +++++++ 5 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 tests/ui/ergonomic-clones/async/edition-2015.rs create mode 100644 tests/ui/ergonomic-clones/async/edition-2015.stderr diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index a1d7d321d8aa..6d4308cda1a6 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -26,6 +26,8 @@ parse_async_move_block_in_2015 = `async move` blocks are only allowed in Rust 20 parse_async_move_order_incorrect = the order of `move` and `async` is incorrect .suggestion = try switching the order +parse_async_use_block_in_2015 = `async use` blocks are only allowed in Rust 2018 or later + parse_async_use_order_incorrect = the order of `use` and `async` is incorrect .suggestion = try switching the order diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index f75fc8f98305..e090d9cf7600 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1688,6 +1688,13 @@ pub(crate) struct AsyncMoveBlockIn2015 { pub span: Span, } +#[derive(Diagnostic)] +#[diag(parse_async_use_block_in_2015)] +pub(crate) struct AsyncUseBlockIn2015 { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(parse_async_bound_modifier_in_2015)] pub(crate) struct AsyncBoundModifierIn2015 { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index dd511fcd8c04..bb227a58cf19 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -31,11 +31,11 @@ use super::{ SeqSep, TokenType, }; use crate::errors::{ - AddParen, AmbiguousPlus, AsyncMoveBlockIn2015, AttributeOnParamType, AwaitSuggestion, - BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi, ComparisonOperatorsCannotBeChained, - ComparisonOperatorsCannotBeChainedSugg, ConstGenericWithoutBraces, - ConstGenericWithoutBracesSugg, DocCommentDoesNotDocumentAnything, DocCommentOnParamType, - DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, + AddParen, AmbiguousPlus, AsyncMoveBlockIn2015, AsyncUseBlockIn2015, AttributeOnParamType, + AwaitSuggestion, BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi, + ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg, + ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, DocCommentDoesNotDocumentAnything, + DocCommentOnParamType, DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg, HelpIdentifierStartsWithNumber, HelpUseLatestEdition, InInTypo, IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, PatternMethodParamWithoutBody, @@ -572,10 +572,17 @@ impl<'a> Parser<'a> { return Err(self.dcx().create_err(UseEqInstead { span: self.token.span })); } - if self.token.is_keyword(kw::Move) && self.prev_token.is_keyword(kw::Async) { - // The 2015 edition is in use because parsing of `async move` has failed. + if (self.token.is_keyword(kw::Move) || self.token.is_keyword(kw::Use)) + && self.prev_token.is_keyword(kw::Async) + { + // The 2015 edition is in use because parsing of `async move` or `async use` has failed. let span = self.prev_token.span.to(self.token.span); - return Err(self.dcx().create_err(AsyncMoveBlockIn2015 { span })); + if self.token.is_keyword(kw::Move) { + return Err(self.dcx().create_err(AsyncMoveBlockIn2015 { span })); + } else { + // kw::Use + return Err(self.dcx().create_err(AsyncUseBlockIn2015 { span })); + } } let expect = tokens_to_string(&expected); diff --git a/tests/ui/ergonomic-clones/async/edition-2015.rs b/tests/ui/ergonomic-clones/async/edition-2015.rs new file mode 100644 index 000000000000..64f62ea099ea --- /dev/null +++ b/tests/ui/ergonomic-clones/async/edition-2015.rs @@ -0,0 +1,6 @@ +#![feature(ergonomic_clones)] + +fn main() { + async use {}; + //~^ ERROR `async use` blocks are only allowed in Rust 2018 or later +} diff --git a/tests/ui/ergonomic-clones/async/edition-2015.stderr b/tests/ui/ergonomic-clones/async/edition-2015.stderr new file mode 100644 index 000000000000..e65e8d77910a --- /dev/null +++ b/tests/ui/ergonomic-clones/async/edition-2015.stderr @@ -0,0 +1,8 @@ +error: `async use` blocks are only allowed in Rust 2018 or later + --> $DIR/edition-2015.rs:4:5 + | +LL | async use {}; + | ^^^^^^^^^ + +error: aborting due to 1 previous error + From 65d65e5e7eac02bfbb9f4053b7ec0db8f4c0f183 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 21 Feb 2025 17:38:30 -0300 Subject: [PATCH 763/991] Parse and allow const use closures --- compiler/rustc_parse/src/parser/mod.rs | 6 +++--- tests/ui/ergonomic-clones/closure/const-closure.rs | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 tests/ui/ergonomic-clones/closure/const-closure.rs diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 7dabc28c6454..4ec8d9e5e49e 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -813,9 +813,9 @@ impl<'a> Parser<'a> { self.is_keyword_ahead(0, &[kw::Const]) && self.look_ahead(1, |t| match &t.kind { // async closures do not work with const closures, so we do not parse that here. - token::Ident(kw::Move | kw::Static, IdentIsRaw::No) | token::OrOr | token::Or => { - true - } + token::Ident(kw::Move | kw::Use | kw::Static, IdentIsRaw::No) + | token::OrOr + | token::Or => true, _ => false, }) } diff --git a/tests/ui/ergonomic-clones/closure/const-closure.rs b/tests/ui/ergonomic-clones/closure/const-closure.rs new file mode 100644 index 000000000000..6b4de824df9e --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/const-closure.rs @@ -0,0 +1,11 @@ +//@ check-pass + +#![feature(const_closures)] +#![feature(ergonomic_clones)] +#![allow(incomplete_features)] + +const fn foo() { + let cl = const use || {}; +} + +fn main() {} From 1702c000562b914e926e4b586f1fb4a6945ab345 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 21 Feb 2025 18:27:58 -0300 Subject: [PATCH 764/991] Make captures in ByUse context be always ty::UpvarCapture::ByUse --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 27 ++++++++++++------- compiler/rustc_hir_typeck/src/upvar.rs | 23 +++++++++++----- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 4b6174769ea6..e7e648dc26b0 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -324,6 +324,18 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } + pub fn consume_clone_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + debug!("delegate_consume_or_clone(place_with_id={:?})", place_with_id); + + if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) { + self.delegate.borrow_mut().copy(place_with_id, diag_expr_id); + } else if self.cx.type_is_use_cloned_modulo_regions(place_with_id.place.ty()) { + self.delegate.borrow_mut().use_cloned(place_with_id, diag_expr_id); + } else { + self.delegate.borrow_mut().consume(place_with_id, diag_expr_id); + } + } + fn consume_exprs(&self, exprs: &[hir::Expr<'_>]) -> Result<(), Cx::Error> { for expr in exprs { self.consume_expr(expr)?; @@ -346,15 +358,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx debug!("consume_or_clone_expr(expr={:?})", expr); let place_with_id = self.cat_expr(expr)?; - - if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) { - self.delegate.borrow_mut().copy(&place_with_id, place_with_id.hir_id); - } else if self.cx.type_is_use_cloned_modulo_regions(place_with_id.place.ty()) { - self.delegate.borrow_mut().use_cloned(&place_with_id, place_with_id.hir_id); - } else { - self.delegate.borrow_mut().consume(&place_with_id, place_with_id.hir_id); - } - + self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id); self.walk_expr(expr)?; Ok(()) } @@ -1132,9 +1136,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ); match capture_info.capture_kind { - ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => { + ty::UpvarCapture::ByValue => { self.consume_or_copy(&place_with_id, place_with_id.hir_id); } + ty::UpvarCapture::ByUse => { + self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id); + } ty::UpvarCapture::ByRef(upvar_borrow) => { self.delegate.borrow_mut().borrow( &place_with_id, diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 40a935afbac2..f570d0d8a0d3 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1709,11 +1709,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Otherwise you'd get an error in 2021 immediately because you'd be trying to take // ownership of the (borrowed) String or else you'd take ownership of b, as in 2018 and // before, which is also an error. - hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } - if !place.deref_tys().any(Ty::is_ref) => - { + hir::CaptureBy::Value { .. } if !place.deref_tys().any(Ty::is_ref) => { ty::UpvarCapture::ByValue } + hir::CaptureBy::Use { .. } if !place.deref_tys().any(Ty::is_ref) => { + ty::UpvarCapture::ByUse + } hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } | hir::CaptureBy::Ref => { ty::UpvarCapture::ByRef(BorrowKind::Immutable) } @@ -2404,10 +2405,18 @@ fn determine_capture_info( // We select the CaptureKind which ranks higher based the following priority order: // (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow match (capture_info_a.capture_kind, capture_info_b.capture_kind) { - (ty::UpvarCapture::ByUse, _) => capture_info_a, - (_, ty::UpvarCapture::ByUse) => capture_info_b, - (ty::UpvarCapture::ByValue, _) => capture_info_a, - (_, ty::UpvarCapture::ByValue) => capture_info_b, + (ty::UpvarCapture::ByUse, ty::UpvarCapture::ByValue) + | (ty::UpvarCapture::ByValue, ty::UpvarCapture::ByUse) => { + bug!("Same capture can't be ByUse and ByValue at the same time") + } + (ty::UpvarCapture::ByValue, ty::UpvarCapture::ByValue) + | (ty::UpvarCapture::ByUse, ty::UpvarCapture::ByUse) + | (ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse, ty::UpvarCapture::ByRef(_)) => { + capture_info_a + } + (ty::UpvarCapture::ByRef(_), ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse) => { + capture_info_b + } (ty::UpvarCapture::ByRef(ref_a), ty::UpvarCapture::ByRef(ref_b)) => { match (ref_a, ref_b) { // Take LHS: From a68db7e3a844839028c90dbb2ab0a56ddc63c718 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 24 Feb 2025 16:00:56 -0300 Subject: [PATCH 765/991] Add examples in stdlib demonstrating the use syntax --- library/core/src/clone.rs | 19 +++++++++++++++++++ library/std/src/keyword_docs.rs | 9 +++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 249ca6c091fd..4e18ab1c7cf5 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -196,6 +196,25 @@ pub macro Clone($item:item) { /// /// The `UseCloned` trait does not provide a method; instead, it indicates that /// `Clone::clone` is lightweight, and allows the use of the `.use` syntax. +/// +/// ## .use postfix syntax +/// +/// Values can be `.use`d by adding `.use` postfix to the value you want to use. +/// +/// ```ignore (this won't work until we land use) +/// fn foo(f: Foo) { +/// // if `Foo` implements `Copy` f would be copied into x. +/// // if `Foo` implements `UseCloned` f would be cloned into x. +/// // otherwise f would be moved into x. +/// let x = f.use; +/// // ... +/// } +/// ``` +/// +/// ## use closures +/// +/// Use closures allow captured values to be automatically used. +/// This is similar to have a closure that you would call `.use` over each captured value. #[unstable(feature = "ergonomic_clones", issue = "132290")] #[cfg_attr(not(bootstrap), lang = "use_cloned")] pub trait UseCloned: Clone { diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index bdd330611de3..5ac3dbc3e985 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -2121,8 +2121,8 @@ mod unsafe_keyword {} #[doc(keyword = "use")] // -/// Import or rename items from other crates or modules, or specify precise capturing -/// with `use<..>`. +/// Import or rename items from other crates or modules, use values under ergonomic clones +/// semantic, or specify precise capturing with `use<..>`. /// /// ## Importing items /// @@ -2205,6 +2205,11 @@ mod unsafe_keyword {} /// /// For more details about precise capturing, see the [Reference][ref-impl-trait]. /// +/// ## Ergonomic clones +/// +/// Use a values, copying its content if the value implements `Copy`, cloning the contents if the +/// value implements `UseCloned` or moving it otherwise. +/// /// [`crate`]: keyword.crate.html /// [`self`]: keyword.self.html /// [`super`]: keyword.super.html From 42b8b13b22465ec0d8629e8706510deac296ace4 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 6 Mar 2025 16:57:51 -0300 Subject: [PATCH 766/991] Add some code comments --- compiler/rustc_ast/src/ast.rs | 6 +++++- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 66a8d1ce86ae..21695339f06b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1760,9 +1760,13 @@ pub enum CaptureBy { /// The span of the `move` keyword. move_kw: Span, }, - /// `move` keyword was not specified. + /// `move` or `use` keywords were not specified. Ref, /// `use |x| y + x`. + /// + /// Note that if you have a regular closure like `|| x.use`, this will *not* result + /// in a `Use` capture. Instead, the `ExprUseVisitor` will look at the type + /// of `x` and treat `x.use` as either a copy/clone/move as appropriate. Use { /// The span of the `use` keyword. use_kw: Span, diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index e7e648dc26b0..9ff7eeb23688 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -327,6 +327,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx pub fn consume_clone_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { debug!("delegate_consume_or_clone(place_with_id={:?})", place_with_id); + // `x.use` will do one of the following + // * if it implements `Copy`, it will be a copy + // * if it implements `UseCloned`, it will be a call to `clone` + // * otherwise, it is a move + // + // we do a conservative approximation of this, treating it as a move unless we know that it implements copy or `UseCloned` if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) { self.delegate.borrow_mut().copy(place_with_id, diag_expr_id); } else if self.cx.type_is_use_cloned_modulo_regions(place_with_id.place.ty()) { From 5a6d00c05def397a11bd195b1352c5ad4c6a5695 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 6 Mar 2025 17:41:27 -0300 Subject: [PATCH 767/991] Add allow(incomplete_features) to alloc --- library/alloc/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index aac0eefc5196..265b68d3b0eb 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -56,6 +56,7 @@ //! [`Rc`]: rc //! [`RefCell`]: core::cell +#![allow(incomplete_features)] #![allow(unused_attributes)] #![stable(feature = "alloc", since = "1.36.0")] #![doc( From d7104dc3f5c64406432b65ba2823f7c7d337c5c3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 6 Mar 2025 18:06:48 -0300 Subject: [PATCH 768/991] Make feature flag incomplete --- compiler/rustc_feature/src/unstable.rs | 2 +- tests/ui/ergonomic-clones/async/basic.rs | 1 + tests/ui/ergonomic-clones/async/edition-2015.rs | 1 + .../ui/ergonomic-clones/async/edition-2015.stderr | 2 +- tests/ui/ergonomic-clones/async/local-type.rs | 1 + tests/ui/ergonomic-clones/async/local-type.stderr | 4 ++-- tests/ui/ergonomic-clones/closure/basic.rs | 1 + tests/ui/ergonomic-clones/closure/fn-once.rs | 1 + tests/ui/ergonomic-clones/closure/fn-once.stderr | 4 ++-- .../closure/immutable-outer-variable.fixed | 1 + .../closure/immutable-outer-variable.rs | 1 + .../closure/immutable-outer-variable.stderr | 2 +- tests/ui/ergonomic-clones/closure/local-type.rs | 1 + .../ui/ergonomic-clones/closure/local-type.stderr | 4 ++-- tests/ui/ergonomic-clones/closure/mutation.rs | 1 + tests/ui/ergonomic-clones/closure/mutation2.rs | 1 + tests/ui/ergonomic-clones/closure/mutation2.stderr | 2 +- tests/ui/ergonomic-clones/closure/nested.rs | 1 + .../closure/once-move-out-on-heap.rs | 1 + tests/ui/ergonomic-clones/closure/parse.rs | 1 + tests/ui/ergonomic-clones/closure/parse.stderr | 6 +++--- tests/ui/ergonomic-clones/closure/print-verbose.rs | 1 + .../ergonomic-clones/closure/print-verbose.stderr | 4 ++-- tests/ui/ergonomic-clones/closure/print.rs | 1 + tests/ui/ergonomic-clones/closure/print.stderr | 6 +++--- tests/ui/ergonomic-clones/closure/with-binders.rs | 1 + tests/ui/ergonomic-clones/dotuse/basic.rs | 1 + tests/ui/ergonomic-clones/dotuse/parse.rs | 1 + tests/ui/ergonomic-clones/dotuse/parse.stderr | 14 +++++++------- 29 files changed, 43 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index ccfdd93e9939..48c608f8f171 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -474,7 +474,7 @@ declare_features! ( /// Allows `dyn* Trait` objects. (incomplete, dyn_star, "1.65.0", Some(102425)), /// Allows the .use postfix syntax `x.use` and use closures `use |x| { ... }` - (unstable, ergonomic_clones, "CURRENT_RUSTC_VERSION", Some(132290)), + (incomplete, ergonomic_clones, "CURRENT_RUSTC_VERSION", Some(132290)), /// Allows exhaustive pattern matching on types that contain uninhabited types. (unstable, exhaustive_patterns, "1.13.0", Some(51085)), /// Allows explicit tail calls via `become` expression. diff --git a/tests/ui/ergonomic-clones/async/basic.rs b/tests/ui/ergonomic-clones/async/basic.rs index 46d12afe0d15..ad2bfd97cd1b 100644 --- a/tests/ui/ergonomic-clones/async/basic.rs +++ b/tests/ui/ergonomic-clones/async/basic.rs @@ -2,6 +2,7 @@ //@ edition:2018 #![feature(ergonomic_clones)] +#![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/ergonomic-clones/async/edition-2015.rs b/tests/ui/ergonomic-clones/async/edition-2015.rs index 64f62ea099ea..d3b2071b9f91 100644 --- a/tests/ui/ergonomic-clones/async/edition-2015.rs +++ b/tests/ui/ergonomic-clones/async/edition-2015.rs @@ -1,4 +1,5 @@ #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn main() { async use {}; diff --git a/tests/ui/ergonomic-clones/async/edition-2015.stderr b/tests/ui/ergonomic-clones/async/edition-2015.stderr index e65e8d77910a..b218e6b242e1 100644 --- a/tests/ui/ergonomic-clones/async/edition-2015.stderr +++ b/tests/ui/ergonomic-clones/async/edition-2015.stderr @@ -1,5 +1,5 @@ error: `async use` blocks are only allowed in Rust 2018 or later - --> $DIR/edition-2015.rs:4:5 + --> $DIR/edition-2015.rs:5:5 | LL | async use {}; | ^^^^^^^^^ diff --git a/tests/ui/ergonomic-clones/async/local-type.rs b/tests/ui/ergonomic-clones/async/local-type.rs index 54808ef494ec..e891686b550a 100644 --- a/tests/ui/ergonomic-clones/async/local-type.rs +++ b/tests/ui/ergonomic-clones/async/local-type.rs @@ -2,6 +2,7 @@ //@ edition:2018 #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn main() { let _ = async use |x: x| x; //~ ERROR expected type diff --git a/tests/ui/ergonomic-clones/async/local-type.stderr b/tests/ui/ergonomic-clones/async/local-type.stderr index 35f6d7fa3ad1..fd832fbc8d29 100644 --- a/tests/ui/ergonomic-clones/async/local-type.stderr +++ b/tests/ui/ergonomic-clones/async/local-type.stderr @@ -1,11 +1,11 @@ error[E0573]: expected type, found local variable `x` - --> $DIR/local-type.rs:7:27 + --> $DIR/local-type.rs:8:27 | LL | let _ = async use |x: x| x; | ^ not a type error[E0573]: expected type, found local variable `x` - --> $DIR/local-type.rs:8:36 + --> $DIR/local-type.rs:9:36 | LL | let _ = async use |x: bool| -> x { x }; | ^ not a type diff --git a/tests/ui/ergonomic-clones/closure/basic.rs b/tests/ui/ergonomic-clones/closure/basic.rs index aba8ebd53e4a..01d3b08ffa27 100644 --- a/tests/ui/ergonomic-clones/closure/basic.rs +++ b/tests/ui/ergonomic-clones/closure/basic.rs @@ -1,6 +1,7 @@ //@ check-pass #![feature(ergonomic_clones)] +#![allow(incomplete_features)] use std::clone::UseCloned; use std::future::Future; diff --git a/tests/ui/ergonomic-clones/closure/fn-once.rs b/tests/ui/ergonomic-clones/closure/fn-once.rs index 51049fe57c71..24060f3ed3b8 100644 --- a/tests/ui/ergonomic-clones/closure/fn-once.rs +++ b/tests/ui/ergonomic-clones/closure/fn-once.rs @@ -1,4 +1,5 @@ #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn get_closure() -> Box Vec> { let vec = vec![1u8, 2u8]; diff --git a/tests/ui/ergonomic-clones/closure/fn-once.stderr b/tests/ui/ergonomic-clones/closure/fn-once.stderr index 20dd70e625d8..40f1200695cc 100644 --- a/tests/ui/ergonomic-clones/closure/fn-once.stderr +++ b/tests/ui/ergonomic-clones/closure/fn-once.stderr @@ -1,5 +1,5 @@ error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` - --> $DIR/fn-once.rs:6:19 + --> $DIR/fn-once.rs:7:19 | LL | let closure = use || { | ^^^^^^ this closure implements `FnOnce`, not `Fn` @@ -9,7 +9,7 @@ LL | vec LL | Box::new(closure) | ----------------- the requirement to implement `Fn` derives from here | - = note: required for the cast from `Box<{closure@$DIR/fn-once.rs:6:19: 6:25}>` to `Box<(dyn Fn() -> Vec + 'static)>` + = note: required for the cast from `Box<{closure@$DIR/fn-once.rs:7:19: 7:25}>` to `Box<(dyn Fn() -> Vec + 'static)>` error: aborting due to 1 previous error diff --git a/tests/ui/ergonomic-clones/closure/immutable-outer-variable.fixed b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.fixed index 510230ffb33e..1e5706324527 100644 --- a/tests/ui/ergonomic-clones/closure/immutable-outer-variable.fixed +++ b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.fixed @@ -3,6 +3,7 @@ // Point at the captured immutable outer variable #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn foo(mut f: Box) { f(); diff --git a/tests/ui/ergonomic-clones/closure/immutable-outer-variable.rs b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.rs index 8b2b72e11594..59aa61f581d9 100644 --- a/tests/ui/ergonomic-clones/closure/immutable-outer-variable.rs +++ b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.rs @@ -3,6 +3,7 @@ // Point at the captured immutable outer variable #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn foo(mut f: Box) { f(); diff --git a/tests/ui/ergonomic-clones/closure/immutable-outer-variable.stderr b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.stderr index 70478c416657..f7c742d33fda 100644 --- a/tests/ui/ergonomic-clones/closure/immutable-outer-variable.stderr +++ b/tests/ui/ergonomic-clones/closure/immutable-outer-variable.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `y`, as it is not declared as mutable - --> $DIR/immutable-outer-variable.rs:13:25 + --> $DIR/immutable-outer-variable.rs:14:25 | LL | foo(Box::new(use || y = !y) as Box<_>); | ^^^^^^ cannot assign diff --git a/tests/ui/ergonomic-clones/closure/local-type.rs b/tests/ui/ergonomic-clones/closure/local-type.rs index 291faebd7657..b2f99efa1e66 100644 --- a/tests/ui/ergonomic-clones/closure/local-type.rs +++ b/tests/ui/ergonomic-clones/closure/local-type.rs @@ -1,6 +1,7 @@ // Check that using the parameter name in its type does not ICE. #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn main() { let _ = use |x: x| x; //~ ERROR expected type diff --git a/tests/ui/ergonomic-clones/closure/local-type.stderr b/tests/ui/ergonomic-clones/closure/local-type.stderr index 8a9d20890374..5a42ae63afaf 100644 --- a/tests/ui/ergonomic-clones/closure/local-type.stderr +++ b/tests/ui/ergonomic-clones/closure/local-type.stderr @@ -1,11 +1,11 @@ error[E0573]: expected type, found local variable `x` - --> $DIR/local-type.rs:6:21 + --> $DIR/local-type.rs:7:21 | LL | let _ = use |x: x| x; | ^ not a type error[E0573]: expected type, found local variable `x` - --> $DIR/local-type.rs:7:30 + --> $DIR/local-type.rs:8:30 | LL | let _ = use |x: bool| -> x { x }; | ^ not a type diff --git a/tests/ui/ergonomic-clones/closure/mutation.rs b/tests/ui/ergonomic-clones/closure/mutation.rs index 2e2f0dddf80a..ef05fffd4799 100644 --- a/tests/ui/ergonomic-clones/closure/mutation.rs +++ b/tests/ui/ergonomic-clones/closure/mutation.rs @@ -1,6 +1,7 @@ //@ check-pass #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn main() { let mut my_var = false; diff --git a/tests/ui/ergonomic-clones/closure/mutation2.rs b/tests/ui/ergonomic-clones/closure/mutation2.rs index 8a43f9232bf4..1cb5b8a7ec3f 100644 --- a/tests/ui/ergonomic-clones/closure/mutation2.rs +++ b/tests/ui/ergonomic-clones/closure/mutation2.rs @@ -1,4 +1,5 @@ #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn main() { let mut my_var = false; diff --git a/tests/ui/ergonomic-clones/closure/mutation2.stderr b/tests/ui/ergonomic-clones/closure/mutation2.stderr index 3ee8f80ce223..3ff33cf70174 100644 --- a/tests/ui/ergonomic-clones/closure/mutation2.stderr +++ b/tests/ui/ergonomic-clones/closure/mutation2.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable - --> $DIR/mutation2.rs:8:5 + --> $DIR/mutation2.rs:9:5 | LL | my_var = true; | ------ calling `callback` requires mutable binding due to possible mutation of `my_var` diff --git a/tests/ui/ergonomic-clones/closure/nested.rs b/tests/ui/ergonomic-clones/closure/nested.rs index 5876396f087f..fc364fb594b2 100644 --- a/tests/ui/ergonomic-clones/closure/nested.rs +++ b/tests/ui/ergonomic-clones/closure/nested.rs @@ -1,6 +1,7 @@ //@ run-pass #![feature(ergonomic_clones)] +#![allow(incomplete_features)] use std::clone::UseCloned; diff --git a/tests/ui/ergonomic-clones/closure/once-move-out-on-heap.rs b/tests/ui/ergonomic-clones/closure/once-move-out-on-heap.rs index 50240114aa91..a8267ac5359f 100644 --- a/tests/ui/ergonomic-clones/closure/once-move-out-on-heap.rs +++ b/tests/ui/ergonomic-clones/closure/once-move-out-on-heap.rs @@ -2,6 +2,7 @@ // Testing guarantees provided by once functions. #![feature(ergonomic_clones)] +#![allow(incomplete_features)] use std::sync::Arc; diff --git a/tests/ui/ergonomic-clones/closure/parse.rs b/tests/ui/ergonomic-clones/closure/parse.rs index 23fce20e370f..0b3bfae0608a 100644 --- a/tests/ui/ergonomic-clones/closure/parse.rs +++ b/tests/ui/ergonomic-clones/closure/parse.rs @@ -1,4 +1,5 @@ #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn parse1() { || use { diff --git a/tests/ui/ergonomic-clones/closure/parse.stderr b/tests/ui/ergonomic-clones/closure/parse.stderr index c45c46eefa5c..c37cb71394be 100644 --- a/tests/ui/ergonomic-clones/closure/parse.stderr +++ b/tests/ui/ergonomic-clones/closure/parse.stderr @@ -1,5 +1,5 @@ error: expected one of `async`, `|`, or `||`, found `{` - --> $DIR/parse.rs:4:12 + --> $DIR/parse.rs:5:12 | LL | || use { | -- ^ expected one of `async`, `|`, or `||` @@ -13,13 +13,13 @@ LL ~ || { use { | error: expected one of `async`, `|`, or `||`, found keyword `use` - --> $DIR/parse.rs:10:10 + --> $DIR/parse.rs:11:10 | LL | move use || { | ^^^ expected one of `async`, `|`, or `||` error: expected one of `async`, `|`, or `||`, found keyword `move` - --> $DIR/parse.rs:16:9 + --> $DIR/parse.rs:17:9 | LL | use move || { | ^^^^ expected one of `async`, `|`, or `||` diff --git a/tests/ui/ergonomic-clones/closure/print-verbose.rs b/tests/ui/ergonomic-clones/closure/print-verbose.rs index b4fc51f91743..e80d0d4b649a 100644 --- a/tests/ui/ergonomic-clones/closure/print-verbose.rs +++ b/tests/ui/ergonomic-clones/closure/print-verbose.rs @@ -1,6 +1,7 @@ //@ compile-flags: -Zverbose-internals #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn to_fn_once(f: F) -> F { f diff --git a/tests/ui/ergonomic-clones/closure/print-verbose.stderr b/tests/ui/ergonomic-clones/closure/print-verbose.stderr index a9d4dd32a201..283405c79d61 100644 --- a/tests/ui/ergonomic-clones/closure/print-verbose.stderr +++ b/tests/ui/ergonomic-clones/closure/print-verbose.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `c` - --> $DIR/print-verbose.rs:21:5 + --> $DIR/print-verbose.rs:22:5 | LL | let c = to_fn_once(use || { | - move occurs because `c` has type `{f::{closure#0} closure_kind_ty=i32 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=(Foo<&'?9 str>, T)}`, which does not implement the `Copy` trait @@ -10,7 +10,7 @@ LL | c(); | ^ value used here after move | note: this value implements `FnOnce`, which causes it to be moved when called - --> $DIR/print-verbose.rs:20:5 + --> $DIR/print-verbose.rs:21:5 | LL | c(); | ^ diff --git a/tests/ui/ergonomic-clones/closure/print.rs b/tests/ui/ergonomic-clones/closure/print.rs index c3f03d2b2e11..c24a4cc5094b 100644 --- a/tests/ui/ergonomic-clones/closure/print.rs +++ b/tests/ui/ergonomic-clones/closure/print.rs @@ -1,4 +1,5 @@ #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn to_fn_once(f: F) -> F { f diff --git a/tests/ui/ergonomic-clones/closure/print.stderr b/tests/ui/ergonomic-clones/closure/print.stderr index 796ae46317ca..5f48059ebff2 100644 --- a/tests/ui/ergonomic-clones/closure/print.stderr +++ b/tests/ui/ergonomic-clones/closure/print.stderr @@ -1,8 +1,8 @@ error[E0382]: use of moved value: `c` - --> $DIR/print.rs:19:5 + --> $DIR/print.rs:20:5 | LL | let c = to_fn_once(use || { - | - move occurs because `c` has type `{closure@$DIR/print.rs:14:24: 14:30}`, which does not implement the `Copy` trait + | - move occurs because `c` has type `{closure@$DIR/print.rs:15:24: 15:30}`, which does not implement the `Copy` trait ... LL | c(); | --- `c` moved due to this call @@ -10,7 +10,7 @@ LL | c(); | ^ value used here after move | note: this value implements `FnOnce`, which causes it to be moved when called - --> $DIR/print.rs:18:5 + --> $DIR/print.rs:19:5 | LL | c(); | ^ diff --git a/tests/ui/ergonomic-clones/closure/with-binders.rs b/tests/ui/ergonomic-clones/closure/with-binders.rs index 952f6e48d44e..4260c252d9dd 100644 --- a/tests/ui/ergonomic-clones/closure/with-binders.rs +++ b/tests/ui/ergonomic-clones/closure/with-binders.rs @@ -3,6 +3,7 @@ #![feature(closure_lifetime_binder)] #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn main() { for<'a> use || -> () {}; diff --git a/tests/ui/ergonomic-clones/dotuse/basic.rs b/tests/ui/ergonomic-clones/dotuse/basic.rs index 4bab400fef28..8f962f079df7 100644 --- a/tests/ui/ergonomic-clones/dotuse/basic.rs +++ b/tests/ui/ergonomic-clones/dotuse/basic.rs @@ -1,6 +1,7 @@ //@ check-pass #![feature(ergonomic_clones)] +#![allow(incomplete_features)] use std::clone::UseCloned; diff --git a/tests/ui/ergonomic-clones/dotuse/parse.rs b/tests/ui/ergonomic-clones/dotuse/parse.rs index 579d2dd774c8..37ef5c37029c 100644 --- a/tests/ui/ergonomic-clones/dotuse/parse.rs +++ b/tests/ui/ergonomic-clones/dotuse/parse.rs @@ -1,4 +1,5 @@ #![feature(ergonomic_clones)] +#![allow(incomplete_features)] fn parse1() { 1.use!; diff --git a/tests/ui/ergonomic-clones/dotuse/parse.stderr b/tests/ui/ergonomic-clones/dotuse/parse.stderr index 65bc5137af80..4b7a92534eda 100644 --- a/tests/ui/ergonomic-clones/dotuse/parse.stderr +++ b/tests/ui/ergonomic-clones/dotuse/parse.stderr @@ -1,29 +1,29 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `!` - --> $DIR/parse.rs:4:10 + --> $DIR/parse.rs:5:10 | LL | 1.use!; | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: expected one of `.`, `;`, `?`, `}`, or an operator, found `!` - --> $DIR/parse.rs:9:10 + --> $DIR/parse.rs:10:10 | LL | 1.use!(2); | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: expected one of `.`, `;`, `?`, `}`, or an operator, found `2` - --> $DIR/parse.rs:14:11 + --> $DIR/parse.rs:15:11 | LL | 1.use 2; | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: expected one of `.`, `;`, `?`, `}`, or an operator, found `2` - --> $DIR/parse.rs:19:12 + --> $DIR/parse.rs:20:12 | LL | 1.use? 2; | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: incorrect use of `use` - --> $DIR/parse.rs:24:10 + --> $DIR/parse.rs:25:10 | LL | 1.use(); | ^^ @@ -35,13 +35,13 @@ LL + 1.use; | error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` - --> $DIR/parse.rs:34:11 + --> $DIR/parse.rs:35:11 | LL | 1.use { 2 }; | ^ expected one of `.`, `;`, `?`, `}`, or an operator error[E0618]: expected function, found `{integer}` - --> $DIR/parse.rs:29:5 + --> $DIR/parse.rs:30:5 | LL | 1.use(2); | ^^^^^--- From 98dc15fb0f93ced1e52491b9007c27a637d37636 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 6 Mar 2025 22:28:48 +0100 Subject: [PATCH 769/991] stabilize const_char_classify --- library/core/src/char/methods.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 85cc315626d4..bb71af339b81 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -337,7 +337,7 @@ impl char { /// '1'.is_digit(1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_char_classify", issue = "132241")] + #[rustc_const_stable(feature = "const_char_classify", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn is_digit(self, radix: u32) -> bool { self.to_digit(radix).is_some() @@ -886,7 +886,7 @@ impl char { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_char_classify", issue = "132241")] + #[rustc_const_stable(feature = "const_char_classify", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn is_whitespace(self) -> bool { match self { From 8f8c7fcb8bb5106bed941632847830667ad37840 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 6 Mar 2025 22:29:07 +0100 Subject: [PATCH 770/991] stabilize const_sockaddr_setters --- library/core/src/net/socket_addr.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/core/src/net/socket_addr.rs b/library/core/src/net/socket_addr.rs index 9204797e6e15..57f47e66e81e 100644 --- a/library/core/src/net/socket_addr.rs +++ b/library/core/src/net/socket_addr.rs @@ -200,7 +200,7 @@ impl SocketAddr { /// ``` #[inline] #[stable(feature = "sockaddr_setters", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")] + #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")] pub const fn set_ip(&mut self, new_ip: IpAddr) { // `match (*self, new_ip)` would have us mutate a copy of self only to throw it away. match (self, new_ip) { @@ -244,7 +244,7 @@ impl SocketAddr { /// ``` #[inline] #[stable(feature = "sockaddr_setters", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")] + #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")] pub const fn set_port(&mut self, new_port: u16) { match *self { SocketAddr::V4(ref mut a) => a.set_port(new_port), @@ -350,7 +350,7 @@ impl SocketAddrV4 { /// ``` #[inline] #[stable(feature = "sockaddr_setters", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")] + #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")] pub const fn set_ip(&mut self, new_ip: Ipv4Addr) { self.ip = new_ip; } @@ -386,7 +386,7 @@ impl SocketAddrV4 { /// ``` #[inline] #[stable(feature = "sockaddr_setters", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")] + #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")] pub const fn set_port(&mut self, new_port: u16) { self.port = new_port; } @@ -448,7 +448,7 @@ impl SocketAddrV6 { /// ``` #[inline] #[stable(feature = "sockaddr_setters", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")] + #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")] pub const fn set_ip(&mut self, new_ip: Ipv6Addr) { self.ip = new_ip; } @@ -484,7 +484,7 @@ impl SocketAddrV6 { /// ``` #[inline] #[stable(feature = "sockaddr_setters", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")] + #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")] pub const fn set_port(&mut self, new_port: u16) { self.port = new_port; } @@ -532,7 +532,7 @@ impl SocketAddrV6 { /// ``` #[inline] #[stable(feature = "sockaddr_setters", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")] + #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")] pub const fn set_flowinfo(&mut self, new_flowinfo: u32) { self.flowinfo = new_flowinfo; } @@ -575,7 +575,7 @@ impl SocketAddrV6 { /// ``` #[inline] #[stable(feature = "sockaddr_setters", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")] + #[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")] pub const fn set_scope_id(&mut self, new_scope_id: u32) { self.scope_id = new_scope_id; } From 2458ccd1f997cf9fd3451a8aaa18b333d4833d33 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Sat, 1 Mar 2025 15:23:36 -0800 Subject: [PATCH 771/991] Simplify printf and shell format suggestions --- compiler/rustc_builtin_macros/src/format.rs | 4 +--- .../rustc_builtin_macros/src/format_foreign.rs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 6dbd8a7ac013..12654001a1e2 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -711,11 +711,9 @@ fn report_missing_placeholders( }; let pos = sub.position(); - let sub = String::from(sub.as_str()); - if explained.contains(&sub) { + if !explained.insert(sub.to_string()) { continue; } - explained.insert(sub); if !found_foreign { found_foreign = true; diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs index 866ec72f1164..13d5b42942ac 100644 --- a/compiler/rustc_builtin_macros/src/format_foreign.rs +++ b/compiler/rustc_builtin_macros/src/format_foreign.rs @@ -12,14 +12,16 @@ pub(crate) mod printf { Escape((usize, usize)), } - impl<'a> Substitution<'a> { - pub(crate) fn as_str(&self) -> &str { + impl ToString for Substitution<'_> { + fn to_string(&self) -> String { match self { - Substitution::Format(fmt) => fmt.span, - Substitution::Escape(_) => "%%", + Substitution::Format(fmt) => fmt.span.into(), + Substitution::Escape(_) => "%%".into(), } } + } + impl Substitution<'_> { pub(crate) fn position(&self) -> InnerSpan { match self { Substitution::Format(fmt) => fmt.position, @@ -627,15 +629,17 @@ pub(crate) mod shell { Escape((usize, usize)), } - impl Substitution<'_> { - pub(crate) fn as_str(&self) -> String { + impl ToString for Substitution<'_> { + fn to_string(&self) -> String { match self { Substitution::Ordinal(n, _) => format!("${n}"), Substitution::Name(n, _) => format!("${n}"), Substitution::Escape(_) => "$$".into(), } } + } + impl Substitution<'_> { pub(crate) fn position(&self) -> InnerSpan { let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self; InnerSpan::new(pos.0, pos.1) From b58fc9c2bc92d453d8d89269bbd2b93c6a2e8f69 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 7 Mar 2025 00:16:54 +0200 Subject: [PATCH 772/991] Mark `rust-analyzer.showSyntaxTree` config option as requiring server restart We register the provider when we start the server. It confused me why I set the option and it didn't work, so probably better to have it hint people. --- src/tools/rust-analyzer/editors/code/src/config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rust-analyzer/editors/code/src/config.ts b/src/tools/rust-analyzer/editors/code/src/config.ts index 2ae329134520..896b3c10cbf5 100644 --- a/src/tools/rust-analyzer/editors/code/src/config.ts +++ b/src/tools/rust-analyzer/editors/code/src/config.ts @@ -27,6 +27,7 @@ export class Config { "server", "files", "cfg", + "showSyntaxTree", ].map((opt) => `${this.rootSection}.${opt}`); private readonly requiresWindowReloadOpts = ["testExplorer"].map( From 4e4bed8684a7144c82ea95aa013e7911dd9fe20d Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Thu, 6 Mar 2025 16:24:40 -0800 Subject: [PATCH 773/991] setTargetTriple now accepts Triple rather than string --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index aea2a8dd0978..6d01095cccad 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -153,7 +153,11 @@ extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) { extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *Triple) { +#if LLVM_VERSION_GE(21, 0) + unwrap(M)->setTargetTriple(llvm::Triple(Triple::normalize(Triple))); +#else unwrap(M)->setTargetTriple(Triple::normalize(Triple)); +#endif } extern "C" void LLVMRustPrintPassTimings(RustStringRef OutBuf) { From d2bde63b7ade858b7fa819aa042f6b2e196863ff Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 6 Mar 2025 22:36:07 -0300 Subject: [PATCH 774/991] Add slight variation to feature-gate ergonomic clones test --- .../feature-gate-ergonomic-clones.rs | 3 +++ .../feature-gate-ergonomic-clones.stderr | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs index fb2b853893ec..c2e44064cfad 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.rs @@ -9,6 +9,9 @@ fn ergonomic_clone(x: i32) -> i32 { #[derive(Clone)] struct Foo; +fn foo() {} +//~^ ERROR use of unstable library feature `ergonomic_clones` [E0658] + impl UseCloned for Foo {} //~^ ERROR use of unstable library feature `ergonomic_clones` [E0658] diff --git a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr index af1b2022ccff..cf92f2f28df8 100644 --- a/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr +++ b/tests/ui/feature-gates/feature-gate-ergonomic-clones.stderr @@ -9,7 +9,7 @@ LL | x.use = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: ergonomic clones are experimental - --> $DIR/feature-gate-ergonomic-clones.rs:18:14 + --> $DIR/feature-gate-ergonomic-clones.rs:21:14 | LL | let f2 = use || { | ^^^ @@ -19,7 +19,7 @@ LL | let f2 = use || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: ergonomic clones are experimental - --> $DIR/feature-gate-ergonomic-clones.rs:23:14 + --> $DIR/feature-gate-ergonomic-clones.rs:26:14 | LL | let f3 = use || { | ^^^ @@ -39,7 +39,17 @@ LL | use std::clone::UseCloned; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `ergonomic_clones` - --> $DIR/feature-gate-ergonomic-clones.rs:12:6 + --> $DIR/feature-gate-ergonomic-clones.rs:12:11 + | +LL | fn foo() {} + | ^^^^^^^^^ + | + = note: see issue #132290 for more information + = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `ergonomic_clones` + --> $DIR/feature-gate-ergonomic-clones.rs:15:6 | LL | impl UseCloned for Foo {} | ^^^^^^^^^ @@ -48,6 +58,6 @@ LL | impl UseCloned for Foo {} = help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0658`. From 69aafd21f5abeb202a377f6b632b3204a2a76b9c Mon Sep 17 00:00:00 2001 From: tcpdumppy <847462026@qq.com> Date: Fri, 7 Mar 2025 10:50:31 +0800 Subject: [PATCH 775/991] tests: fix some typos in comment Signed-off-by: tcpdumppy <847462026@qq.com> --- tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.rs | 4 ++-- tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.rs | 2 +- tests/ui/lint/dead-code/allow-or-expect-dead_code-114557.rs | 2 +- tests/ui/lint/unused/must-use-ops.rs | 2 +- tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.rs b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.rs index 20999df9844e..db23dcd5e5eb 100644 --- a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.rs +++ b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.rs @@ -1,10 +1,10 @@ //@ check-pass -// this test checks that the `dead_code` lint is *NOT* being emited +// this test checks that the `dead_code` lint is *NOT* being emitted // for `foo` as `foo` is being used by `main`, and so the `#[expect]` // is unfulfilled // -// it also checks that the `dead_code` lint is also *NOT* emited +// it also checks that the `dead_code` lint is also *NOT* emitted // for `bar` as it's suppresed by the `#[expect]` on `bar` #![warn(dead_code)] // to override compiletest diff --git a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.rs b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.rs index 08103b233872..c4476e43e1ff 100644 --- a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.rs +++ b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.rs @@ -1,7 +1,7 @@ //@ check-pass // this test makes sure that the `unfulfilled_lint_expectations` lint -// is being emited for `foo` as foo is not dead code, it's pub +// is being emitted for `foo` as foo is not dead code, it's pub #![warn(dead_code)] // to override compiletest diff --git a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557.rs b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557.rs index f2625f0781f6..ea2e81261d10 100644 --- a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557.rs +++ b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557.rs @@ -2,7 +2,7 @@ //@ revisions: allow expect // this test checks that no matter if we put #[allow(dead_code)] -// or #[expect(dead_code)], no warning is being emited +// or #[expect(dead_code)], no warning is being emitted #![warn(dead_code)] // to override compiletest diff --git a/tests/ui/lint/unused/must-use-ops.rs b/tests/ui/lint/unused/must-use-ops.rs index f61cf0fcfcb4..5085dbb58c19 100644 --- a/tests/ui/lint/unused/must-use-ops.rs +++ b/tests/ui/lint/unused/must-use-ops.rs @@ -6,7 +6,7 @@ #![feature(never_type)] fn deref_never(x: &!) { - // Don't lint for uninhabited typess + // Don't lint for uninhabited types *x; } diff --git a/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs b/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs index d7ade7f0e96c..009cc66f3f74 100644 --- a/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs +++ b/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs @@ -5,7 +5,7 @@ #![deny(exported_private_dependencies)] // Ensure the libbar.rlib is loaded first. If the command line parameter `--extern foo` does not -// exist, previus version would fail to compile +// exist, previous version would fail to compile #![crate_type = "rlib"] extern crate bar; extern crate foo; From 141719f68a3084f3b96f644c34734af077b9d197 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Apr 2024 14:53:52 +1000 Subject: [PATCH 776/991] Remove `NtItem` and `NtStmt`. This involves replacing `nt_pretty_printing_compatibility_hack` with `stream_pretty_printing_compatibility_hack`. The handling of statements in `transcribe` is slightly different to other nonterminal kinds, due to the lack of `from_ast` implementation for empty statements. Notable test changes: - `tests/ui/proc-macro/expand-to-derive.rs`: the diff looks large but the only difference is the insertion of a single invisible-delimited group around a metavar. --- compiler/rustc_ast/src/ast_traits.rs | 4 - compiler/rustc_ast/src/mut_visit.rs | 12 --- compiler/rustc_ast/src/token.rs | 9 +- compiler/rustc_ast/src/tokenstream.rs | 8 +- compiler/rustc_builtin_macros/src/cfg_eval.rs | 5 +- compiler/rustc_expand/src/base.rs | 49 +++++++---- compiler/rustc_expand/src/mbe/transcribe.rs | 14 ++- compiler/rustc_expand/src/proc_macro.rs | 2 +- .../rustc_expand/src/proc_macro_server.rs | 31 ++++--- compiler/rustc_parse/src/parser/expr.rs | 3 +- compiler/rustc_parse/src/parser/item.rs | 13 +-- compiler/rustc_parse/src/parser/mod.rs | 12 ++- .../rustc_parse/src/parser/nonterminal.rs | 12 ++- compiler/rustc_parse/src/parser/stmt.rs | 60 +++++++++---- tests/ui/macros/macro-stmt-2.rs | 11 +++ tests/ui/macros/nonterminal-matching.rs | 4 +- tests/ui/macros/nonterminal-matching.stderr | 6 +- tests/ui/proc-macro/expand-to-derive.stdout | 88 ++++++++++--------- 18 files changed, 198 insertions(+), 145 deletions(-) create mode 100644 tests/ui/macros/macro-stmt-2.rs diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index a37c0f92b127..849cc650e9d6 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -209,16 +209,12 @@ impl HasTokens for Attribute { impl HasTokens for Nonterminal { fn tokens(&self) -> Option<&LazyAttrTokenStream> { match self { - Nonterminal::NtItem(item) => item.tokens(), - Nonterminal::NtStmt(stmt) => stmt.tokens(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(), Nonterminal::NtBlock(block) => block.tokens(), } } fn tokens_mut(&mut self) -> Option<&mut Option> { match self { - Nonterminal::NtItem(item) => item.tokens_mut(), - Nonterminal::NtStmt(stmt) => stmt.tokens_mut(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(), Nonterminal::NtBlock(block) => block.tokens_mut(), } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index f14646b5a99a..8a64ce4654dc 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -895,19 +895,7 @@ pub fn visit_token(vis: &mut T, t: &mut Token) { // multiple items there.... fn visit_nonterminal(vis: &mut T, nt: &mut token::Nonterminal) { match nt { - token::NtItem(item) => visit_clobber(item, |item| { - // This is probably okay, because the only visitors likely to - // peek inside interpolated nodes will be renamings/markings, - // which map single items to single items. - vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item") - }), token::NtBlock(block) => vis.visit_block(block), - token::NtStmt(stmt) => visit_clobber(stmt, |stmt| { - // See reasoning above. - stmt.map(|stmt| { - vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item") - }) - }), token::NtExpr(expr) => vis.visit_expr(expr), token::NtLiteral(expr) => vis.visit_expr(expr), } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index ff1edad725a4..f7cd63aaaf82 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -870,6 +870,7 @@ impl Token { /// Is this a pre-parsed expression dropped into the token stream /// (which happens while parsing the result of macro expansion)? pub fn is_whole_expr(&self) -> bool { + #[allow(irrefutable_let_patterns)] // FIXME: temporary if let Interpolated(nt) = &self.kind && let NtExpr(_) | NtLiteral(_) | NtBlock(_) = &**nt { @@ -1103,9 +1104,7 @@ pub enum NtExprKind { #[derive(Clone, Encodable, Decodable)] /// For interpolation during macro expansion. pub enum Nonterminal { - NtItem(P), NtBlock(P), - NtStmt(P), NtExpr(P), NtLiteral(P), } @@ -1196,18 +1195,14 @@ impl fmt::Display for NonterminalKind { impl Nonterminal { pub fn use_span(&self) -> Span { match self { - NtItem(item) => item.span, NtBlock(block) => block.span, - NtStmt(stmt) => stmt.span, NtExpr(expr) | NtLiteral(expr) => expr.span, } } pub fn descr(&self) -> &'static str { match self { - NtItem(..) => "item", NtBlock(..) => "block", - NtStmt(..) => "statement", NtExpr(..) => "expression", NtLiteral(..) => "literal", } @@ -1227,9 +1222,7 @@ impl PartialEq for Nonterminal { impl fmt::Debug for Nonterminal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - NtItem(..) => f.pad("NtItem(..)"), NtBlock(..) => f.pad("NtBlock(..)"), - NtStmt(..) => f.pad("NtStmt(..)"), NtExpr(..) => f.pad("NtExpr(..)"), NtLiteral(..) => f.pad("NtLiteral(..)"), } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index b9b20cf93768..bdd244be6d1c 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -23,7 +23,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Encodable}; use rustc_span::{DUMMY_SP, Span, SpanDecoder, SpanEncoder, Symbol, sym}; -use crate::ast::{AttrStyle, StmtKind}; +use crate::ast::AttrStyle; use crate::ast_traits::{HasAttrs, HasTokens}; use crate::token::{self, Delimiter, InvisibleOrigin, Nonterminal, Token, TokenKind}; use crate::{AttrVec, Attribute}; @@ -461,13 +461,7 @@ impl TokenStream { pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream { match nt { - Nonterminal::NtItem(item) => TokenStream::from_ast(item), Nonterminal::NtBlock(block) => TokenStream::from_ast(block), - Nonterminal::NtStmt(stmt) if let StmtKind::Empty = stmt.kind => { - // FIXME: Properly collect tokens for empty statements. - TokenStream::token_alone(token::Semi, stmt.span) - } - Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr), } } diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 53c61831b422..5788966b6e7b 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -140,8 +140,9 @@ impl CfgEval<'_> { Annotatable::ForeignItem(self.flat_map_foreign_item(item).pop().unwrap()) } Annotatable::Stmt(_) => { - let stmt = - parser.parse_stmt_without_recovery(false, ForceCollect::Yes)?.unwrap(); + let stmt = parser + .parse_stmt_without_recovery(false, ForceCollect::Yes, false)? + .unwrap(); Annotatable::Stmt(P(self.flat_map_stmt(stmt).pop().unwrap())) } Annotatable::Expr(_) => { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 86b12f6be4e6..895efe05e117 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use rustc_ast::attr::{AttributeExt, MarkedAttrs}; use rustc_ast::ptr::P; -use rustc_ast::token::Nonterminal; +use rustc_ast::token::MetaVarKind; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind}; @@ -19,7 +19,7 @@ use rustc_feature::Features; use rustc_hir as hir; use rustc_lint_defs::{BufferedEarlyLint, RegisteredTools}; use rustc_parse::MACRO_ARGUMENTS; -use rustc_parse::parser::Parser; +use rustc_parse::parser::{ForceCollect, Parser}; use rustc_session::config::CollapseMacroDebuginfo; use rustc_session::parse::ParseSess; use rustc_session::{Limit, Session}; @@ -1405,13 +1405,13 @@ pub fn parse_macro_name_and_helper_attrs( /// If this item looks like a specific enums from `rental`, emit a fatal error. /// See #73345 and #83125 for more details. /// FIXME(#73933): Remove this eventually. -fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) { +fn pretty_printing_compatibility_hack(item: &Item, psess: &ParseSess) { let name = item.ident.name; if name == sym::ProceduralMasqueradeDummyType && let ast::ItemKind::Enum(enum_def, _) = &item.kind && let [variant] = &*enum_def.variants && variant.ident.name == sym::Input - && let FileName::Real(real) = sess.source_map().span_to_filename(item.ident.span) + && let FileName::Real(real) = psess.source_map().span_to_filename(item.ident.span) && let Some(c) = real .local_path() .unwrap_or(Path::new("")) @@ -1429,7 +1429,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) { }; if crate_matches { - sess.dcx().emit_fatal(errors::ProcMacroBackCompat { + psess.dcx().emit_fatal(errors::ProcMacroBackCompat { crate_name: "rental".to_string(), fixed_version: "0.5.6".to_string(), }); @@ -1437,7 +1437,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) { } } -pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &Session) { +pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, psess: &ParseSess) { let item = match ann { Annotatable::Item(item) => item, Annotatable::Stmt(stmt) => match &stmt.kind { @@ -1446,17 +1446,36 @@ pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &S }, _ => return, }; - pretty_printing_compatibility_hack(item, sess) + pretty_printing_compatibility_hack(item, psess) } -pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &Session) { - let item = match nt { - Nonterminal::NtItem(item) => item, - Nonterminal::NtStmt(stmt) => match &stmt.kind { - ast::StmtKind::Item(item) => item, - _ => return, - }, +pub(crate) fn stream_pretty_printing_compatibility_hack( + kind: MetaVarKind, + stream: &TokenStream, + psess: &ParseSess, +) { + let item = match kind { + MetaVarKind::Item => { + let mut parser = Parser::new(psess, stream.clone(), None); + // No need to collect tokens for this simple check. + parser + .parse_item(ForceCollect::No) + .expect("failed to reparse item") + .expect("an actual item") + } + MetaVarKind::Stmt => { + let mut parser = Parser::new(psess, stream.clone(), None); + // No need to collect tokens for this simple check. + let stmt = parser + .parse_stmt(ForceCollect::No) + .expect("failed to reparse") + .expect("an actual stmt"); + match &stmt.kind { + ast::StmtKind::Item(item) => item.clone(), + _ => return, + } + } _ => return, }; - pretty_printing_compatibility_hack(item, sess) + pretty_printing_compatibility_hack(&item, psess) } diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 70107c80147f..cffa4af6ac3d 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -7,7 +7,7 @@ use rustc_ast::token::{ TokenKind, }; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; -use rustc_ast::{ExprKind, TyKind}; +use rustc_ast::{ExprKind, StmtKind, TyKind}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize}; use rustc_parse::lexer::nfc_normalize; @@ -323,6 +323,18 @@ pub(super) fn transcribe<'a>( let kind = token::NtLifetime(*ident, *is_raw); TokenTree::token_alone(kind, sp) } + MatchedSingle(ParseNtResult::Item(item)) => { + mk_delimited(item.span, MetaVarKind::Item, TokenStream::from_ast(item)) + } + MatchedSingle(ParseNtResult::Stmt(stmt)) => { + let stream = if let StmtKind::Empty = stmt.kind { + // FIXME: Properly collect tokens for empty statements. + TokenStream::token_alone(token::Semi, stmt.span) + } else { + TokenStream::from_ast(stmt) + }; + mk_delimited(stmt.span, MetaVarKind::Stmt, stream) + } MatchedSingle(ParseNtResult::Pat(pat, pat_kind)) => mk_delimited( pat.span, MetaVarKind::Pat(*pat_kind), diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index a6cdeaee176f..d5af9849e759 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -122,7 +122,7 @@ impl MultiItemModifier for DeriveProcMacro { // We had a lint for a long time, but now we just emit a hard error. // Eventually we might remove the special case hard error check // altogether. See #73345. - crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess); + crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess.psess); let input = item.to_tokens(); let stream = { let _timer = diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 007241437ecc..7e5e02fd41b2 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -115,11 +115,25 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { - let delimiter = pm::Delimiter::from_internal(delim); + tokenstream::TokenTree::Delimited(span, _, delim, stream) => { + // We used to have an alternative behaviour for crates that + // needed it: a hack used to pass AST fragments to + // attribute and derive macros as a single nonterminal + // token instead of a token stream. Such token needs to be + // "unwrapped" and not represented as a delimited group. We + // had a lint for a long time, but now we just emit a hard + // error. Eventually we might remove the special case hard + // error check altogether. See #73345. + if let Delimiter::Invisible(InvisibleOrigin::MetaVar(kind)) = delim { + crate::base::stream_pretty_printing_compatibility_hack( + kind, + &stream, + rustc.psess(), + ); + } trees.push(TokenTree::Group(Group { - delimiter, - stream: Some(tts), + delimiter: pm::Delimiter::from_internal(delim), + stream: Some(stream), span: DelimSpan { open: span.open, close: span.close, @@ -279,15 +293,6 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { let stream = TokenStream::from_nonterminal_ast(&nt); - // We used to have an alternative behaviour for crates that - // needed it: a hack used to pass AST fragments to - // attribute and derive macros as a single nonterminal - // token instead of a token stream. Such token needs to be - // "unwrapped" and not represented as a delimited group. We - // had a lint for a long time, but now we just emit a hard - // error. Eventually we might remove the special case hard - // error check altogether. See #73345. - crate::base::nt_pretty_printing_compatibility_hack(&nt, rustc.ecx.sess); trees.push(TokenTree::Group(Group { delimiter: pm::Delimiter::None, stream: Some(stream), diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0a08c6faeb48..cab0c7df3e08 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1357,7 +1357,6 @@ impl<'a> Parser<'a> { self.bump(); return Ok(self.mk_expr(self.prev_token.span, ExprKind::Block(block, None))); } - _ => {} }; } else if let Some(path) = self.eat_metavar_seq(MetaVarKind::Path, |this| { this.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type)) @@ -3046,7 +3045,7 @@ impl<'a> Parser<'a> { } self.restore_snapshot(pre_pat_snapshot); - match self.parse_stmt_without_recovery(true, ForceCollect::No) { + match self.parse_stmt_without_recovery(true, ForceCollect::No, false) { // Consume statements for as long as possible. Ok(Some(stmt)) => { stmts.push(stmt); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index c3b1956ad2e8..5d537a0e144f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -21,10 +21,10 @@ use super::diagnostics::{ConsumeClosingDelim, dummy_arg}; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{ AttrWrapper, ExpKeywordPair, ExpTokenPair, FollowedByType, ForceCollect, Parser, PathStyle, - Trailing, UsePreAttrPos, + Recovered, Trailing, UsePreAttrPos, }; use crate::errors::{self, MacroExpandsToAdtField}; -use crate::{exp, fluent_generated as fluent, maybe_whole}; +use crate::{exp, fluent_generated as fluent}; impl<'a> Parser<'a> { /// Parses a source module as a crate. This is the main entry point for the parser. @@ -142,10 +142,13 @@ impl<'a> Parser<'a> { fn_parse_mode: FnParseMode, force_collect: ForceCollect, ) -> PResult<'a, Option> { - maybe_whole!(self, NtItem, |item| { + if let Some(item) = + self.eat_metavar_seq(MetaVarKind::Item, |this| this.parse_item(ForceCollect::Yes)) + { + let mut item = item.expect("an actual item"); attrs.prepend_to_nt_inner(&mut item.attrs); - Some(item.into_inner()) - }); + return Ok(Some(item.into_inner())); + } self.collect_tokens(None, attrs, force_collect, |this, mut attrs| { let lo = this.token.span; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 7dabc28c6454..0bb6e2ab1265 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1076,10 +1076,12 @@ impl<'a> Parser<'a> { let initial_semicolon = self.token.span; while self.eat(exp!(Semi)) { - let _ = self.parse_stmt_without_recovery(false, ForceCollect::No).unwrap_or_else(|e| { - e.cancel(); - None - }); + let _ = self + .parse_stmt_without_recovery(false, ForceCollect::No, false) + .unwrap_or_else(|e| { + e.cancel(); + None + }); } expect_err @@ -1746,6 +1748,8 @@ pub enum ParseNtResult { Tt(TokenTree), Ident(Ident, IdentIsRaw), Lifetime(Ident, IdentIsRaw), + Item(P), + Stmt(P), Pat(P, NtPatKind), Ty(P), Meta(P), diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index d537bc17ce37..1123755ce003 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -48,12 +48,11 @@ impl<'a> Parser<'a> { /// Old variant of `may_be_ident`. Being phased out. fn nt_may_be_ident(nt: &Nonterminal) -> bool { match nt { - NtStmt(_) - | NtExpr(_) + NtExpr(_) | NtLiteral(_) // `true`, `false` => true, - NtItem(_) | NtBlock(_) => false, + NtBlock(_) => false, } } @@ -96,8 +95,7 @@ impl<'a> Parser<'a> { token::OpenDelim(Delimiter::Brace) => true, token::NtLifetime(..) => true, token::Interpolated(nt) => match &**nt { - NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, - NtItem(_) => false, + NtBlock(_) | NtExpr(_) | NtLiteral(_) => true, }, token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k { MetaVarKind::Block @@ -147,7 +145,7 @@ impl<'a> Parser<'a> { // Note that TT is treated differently to all the others. NonterminalKind::TT => return Ok(ParseNtResult::Tt(self.parse_token_tree())), NonterminalKind::Item => match self.parse_item(ForceCollect::Yes)? { - Some(item) => NtItem(item), + Some(item) => return Ok(ParseNtResult::Item(item)), None => { return Err(self .dcx() @@ -160,7 +158,7 @@ impl<'a> Parser<'a> { NtBlock(self.collect_tokens_no_attrs(|this| this.parse_block())?) } NonterminalKind::Stmt => match self.parse_stmt(ForceCollect::Yes)? { - Some(s) => NtStmt(P(s)), + Some(stmt) => return Ok(ParseNtResult::Stmt(P(stmt))), None => { return Err(self .dcx() diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 3a9dc5ce7985..0896bd88b4cd 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -5,7 +5,7 @@ use std::ops::Bound; use ast::Label; use rustc_ast as ast; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Delimiter, TokenKind}; +use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind}; use rustc_ast::util::classify::{self, TrailingBrace}; use rustc_ast::{ AttrStyle, AttrVec, Block, BlockCheckMode, DUMMY_NODE_ID, Expr, ExprKind, HasAttrs, Local, @@ -33,8 +33,8 @@ impl<'a> Parser<'a> { /// If `force_collect` is [`ForceCollect::Yes`], forces collection of tokens regardless of /// whether or not we have attributes. // Public for rustfmt usage. - pub(super) fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option> { - Ok(self.parse_stmt_without_recovery(false, force_collect).unwrap_or_else(|e| { + pub fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option> { + Ok(self.parse_stmt_without_recovery(false, force_collect, false).unwrap_or_else(|e| { e.emit(); self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore); None @@ -42,23 +42,27 @@ impl<'a> Parser<'a> { } /// If `force_collect` is [`ForceCollect::Yes`], forces collection of tokens regardless of - /// whether or not we have attributes. - // Public for `cfg_eval` macro expansion. + /// whether or not we have attributes. If `force_full_expr` is true, parses the stmt without + /// using `Restriction::STMT_EXPR`. Public for `cfg_eval` macro expansion. pub fn parse_stmt_without_recovery( &mut self, capture_semi: bool, force_collect: ForceCollect, + force_full_expr: bool, ) -> PResult<'a, Option> { let pre_attr_pos = self.collect_pos(); let attrs = self.parse_outer_attributes()?; let lo = self.token.span; - maybe_whole!(self, NtStmt, |stmt| { + if let Some(stmt) = self.eat_metavar_seq(MetaVarKind::Stmt, |this| { + this.parse_stmt_without_recovery(false, ForceCollect::Yes, false) + }) { + let mut stmt = stmt.expect("an actual statement"); stmt.visit_attrs(|stmt_attrs| { attrs.prepend_to_nt_inner(stmt_attrs); }); - Some(stmt.into_inner()) - }); + return Ok(Some(stmt)); + } if self.token.is_keyword(kw::Mut) && self.is_keyword_ahead(1, &[kw::Let]) { self.bump(); @@ -147,12 +151,14 @@ impl<'a> Parser<'a> { } else if self.token != token::CloseDelim(Delimiter::Brace) { // Remainder are line-expr stmts. This is similar to the `parse_stmt_path_start` case // above. + let restrictions = + if force_full_expr { Restrictions::empty() } else { Restrictions::STMT_EXPR }; let e = self.collect_tokens( Some(pre_attr_pos), AttrWrapper::empty(), force_collect, |this, _empty_attrs| { - let (expr, _) = this.parse_expr_res(Restrictions::STMT_EXPR, attrs)?; + let (expr, _) = this.parse_expr_res(restrictions, attrs)?; Ok((expr, Trailing::No, UsePreAttrPos::Yes)) }, )?; @@ -229,11 +235,15 @@ impl<'a> Parser<'a> { let mac = P(MacCall { path, args }); let kind = if (style == MacStmtStyle::Braces - && self.token != token::Dot - && self.token != token::Question) - || self.token == token::Semi - || self.token == token::Eof - { + && !matches!(self.token.kind, token::Dot | token::Question)) + || matches!( + self.token.kind, + token::Semi + | token::Eof + | token::CloseDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( + MetaVarKind::Stmt + ))) + ) { StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None })) } else { // Since none of the above applied, this is an expression statement macro. @@ -501,7 +511,7 @@ impl<'a> Parser<'a> { // bar; // // which is valid in other languages, but not Rust. - match self.parse_stmt_without_recovery(false, ForceCollect::No) { + match self.parse_stmt_without_recovery(false, ForceCollect::No, false) { // If the next token is an open brace, e.g., we have: // // if expr other_expr { @@ -810,10 +820,24 @@ impl<'a> Parser<'a> { &mut self, recover: AttemptLocalParseRecovery, ) -> PResult<'a, Option> { - // Skip looking for a trailing semicolon when we have an interpolated statement. - maybe_whole!(self, NtStmt, |stmt| Some(stmt.into_inner())); + // Skip looking for a trailing semicolon when we have a metavar seq. + if let Some(stmt) = self.eat_metavar_seq(MetaVarKind::Stmt, |this| { + // Why pass `true` for `force_full_expr`? Statement expressions are less expressive + // than "full" expressions, due to the `STMT_EXPR` restriction, and sometimes need + // parentheses. E.g. the "full" expression `match paren_around_match {} | true` when + // used in statement context must be written `(match paren_around_match {} | true)`. + // However, if the expression we are parsing in this statement context was pasted by a + // declarative macro, it may have come from a "full" expression context, and lack + // these parentheses. So we lift the `STMT_EXPR` restriction to ensure the statement + // will reparse successfully. + this.parse_stmt_without_recovery(false, ForceCollect::No, true) + }) { + let stmt = stmt.expect("an actual statement"); + return Ok(Some(stmt)); + } - let Some(mut stmt) = self.parse_stmt_without_recovery(true, ForceCollect::No)? else { + let Some(mut stmt) = self.parse_stmt_without_recovery(true, ForceCollect::No, false)? + else { return Ok(None); }; diff --git a/tests/ui/macros/macro-stmt-2.rs b/tests/ui/macros/macro-stmt-2.rs new file mode 100644 index 000000000000..663d8ddc4843 --- /dev/null +++ b/tests/ui/macros/macro-stmt-2.rs @@ -0,0 +1,11 @@ +//@ check-pass +// +// This shows a tricky case for #124141, where `declare!(_x)` was incorrectly +// being categorised as a `StmtKind::Expr` instead of a `StmtKind::MacCall` in +// `parse_stmt_mac`. + +macro_rules! as_stmt { ($s:stmt) => { $s }; } + +macro_rules! declare { ($name:ident) => { let $name = 0u32; }; } + +fn main() { as_stmt!(declare!(_x)); } diff --git a/tests/ui/macros/nonterminal-matching.rs b/tests/ui/macros/nonterminal-matching.rs index ca95e8fac050..b0a7f3e4650f 100644 --- a/tests/ui/macros/nonterminal-matching.rs +++ b/tests/ui/macros/nonterminal-matching.rs @@ -16,7 +16,7 @@ macro complex_nonterminal($nt_item: item) { struct S; } - n!(a $nt_item b); //~ ERROR no rules expected item `enum E {}` + n!(a $nt_item b); //~ ERROR no rules expected `item` metavariable } simple_nonterminal!(a, 'a, (x, y, z)); // OK @@ -32,7 +32,7 @@ macro_rules! foo { (expr $x:expr) => { bar!(expr $x); }; //~ ERROR: no rules expected expression `3` (literal $x:literal) => { bar!(literal $x); }; //~ ERROR: no rules expected literal `4` (path $x:path) => { bar!(path $x); }; //~ ERROR: no rules expected `path` metavariable - (stmt $x:stmt) => { bar!(stmt $x); }; //~ ERROR: no rules expected statement `let abc = 0` + (stmt $x:stmt) => { bar!(stmt $x); }; //~ ERROR: no rules expected `stmt` metavariable } macro_rules! bar { diff --git a/tests/ui/macros/nonterminal-matching.stderr b/tests/ui/macros/nonterminal-matching.stderr index ba2b3e213ad0..2d9252fbfc1f 100644 --- a/tests/ui/macros/nonterminal-matching.stderr +++ b/tests/ui/macros/nonterminal-matching.stderr @@ -1,4 +1,4 @@ -error: no rules expected item `enum E {}` +error: no rules expected `item` metavariable --> $DIR/nonterminal-matching.rs:19:10 | LL | macro n(a $nt_item b) { @@ -10,7 +10,7 @@ LL | n!(a $nt_item b); LL | complex_nonterminal!(enum E {}); | ------------------------------- in this macro invocation | -note: while trying to match item `enum E {}` +note: while trying to match `item` metavariable --> $DIR/nonterminal-matching.rs:15:15 | LL | macro n(a $nt_item b) { @@ -89,7 +89,7 @@ LL | (path a::b::c) => {}; = help: try using `:tt` instead in the macro definition = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) -error: no rules expected statement `let abc = 0` +error: no rules expected `stmt` metavariable --> $DIR/nonterminal-matching.rs:35:35 | LL | (stmt $x:stmt) => { bar!(stmt $x); }; diff --git a/tests/ui/proc-macro/expand-to-derive.stdout b/tests/ui/proc-macro/expand-to-derive.stdout index 81fc52ea22d7..3a16f23ecf23 100644 --- a/tests/ui/proc-macro/expand-to-derive.stdout +++ b/tests/ui/proc-macro/expand-to-derive.stdout @@ -44,52 +44,58 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Group { delimiter: Brace, stream: TokenStream [ - Punct { - ch: '#', - spacing: Alone, - span: $DIR/expand-to-derive.rs:27:5: 27:6 (#0), - }, Group { - delimiter: Bracket, + delimiter: None, stream: TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/expand-to-derive.rs:27:5: 27:6 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "rustc_dummy", + span: $DIR/expand-to-derive.rs:27:28: 27:39 (#0), + }, + ], + span: $DIR/expand-to-derive.rs:27:6: 27:41 (#0), + }, Ident { - ident: "rustc_dummy", - span: $DIR/expand-to-derive.rs:27:28: 27:39 (#0), + ident: "struct", + span: $DIR/expand-to-derive.rs:28:5: 28:11 (#0), + }, + Ident { + ident: "Inner", + span: $DIR/expand-to-derive.rs:28:12: 28:17 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Ident { + ident: "other_inner_field", + span: $DIR/expand-to-derive.rs:30:9: 30:26 (#0), + }, + Punct { + ch: ':', + spacing: Alone, + span: $DIR/expand-to-derive.rs:30:26: 30:27 (#0), + }, + Ident { + ident: "u8", + span: $DIR/expand-to-derive.rs:30:28: 30:30 (#0), + }, + Punct { + ch: ',', + spacing: Alone, + span: $DIR/expand-to-derive.rs:30:30: 30:31 (#0), + }, + ], + span: $DIR/expand-to-derive.rs:28:18: 31:6 (#0), }, ], - span: $DIR/expand-to-derive.rs:27:6: 27:41 (#0), - }, - Ident { - ident: "struct", - span: $DIR/expand-to-derive.rs:28:5: 28:11 (#0), - }, - Ident { - ident: "Inner", - span: $DIR/expand-to-derive.rs:28:12: 28:17 (#0), - }, - Group { - delimiter: Brace, - stream: TokenStream [ - Ident { - ident: "other_inner_field", - span: $DIR/expand-to-derive.rs:30:9: 30:26 (#0), - }, - Punct { - ch: ':', - spacing: Alone, - span: $DIR/expand-to-derive.rs:30:26: 30:27 (#0), - }, - Ident { - ident: "u8", - span: $DIR/expand-to-derive.rs:30:28: 30:30 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/expand-to-derive.rs:30:30: 30:31 (#0), - }, - ], - span: $DIR/expand-to-derive.rs:28:18: 31:6 (#0), + span: $DIR/expand-to-derive.rs:19:17: 19:22 (#3), }, Literal { kind: Integer, From 293fe0a9667b442b2a4adf94bbf68bf60391441c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 6 Mar 2025 10:03:56 +1100 Subject: [PATCH 777/991] Increase recursion_limit in numerous crates. This is temporarily needed for `x doc compiler` to work. They can be removed once the `Nonterminal` is removed (#124141). --- compiler/rustc_ast/src/lib.rs | 1 + compiler/rustc_ast_lowering/src/lib.rs | 1 + compiler/rustc_attr_parsing/src/lib.rs | 1 + compiler/rustc_borrowck/src/lib.rs | 1 + compiler/rustc_builtin_macros/src/lib.rs | 1 + compiler/rustc_codegen_ssa/src/lib.rs | 1 + compiler/rustc_const_eval/src/lib.rs | 1 + compiler/rustc_driver/src/lib.rs | 1 + compiler/rustc_driver_impl/src/lib.rs | 1 + compiler/rustc_hir/src/lib.rs | 1 + compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_hir_typeck/src/lib.rs | 1 + compiler/rustc_incremental/src/lib.rs | 1 + compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_metadata/src/lib.rs | 1 + compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_mir_build/src/lib.rs | 1 + compiler/rustc_mir_dataflow/src/lib.rs | 1 + compiler/rustc_mir_transform/src/lib.rs | 1 + compiler/rustc_monomorphize/src/lib.rs | 1 + compiler/rustc_parse/src/lib.rs | 1 + compiler/rustc_passes/src/lib.rs | 1 + compiler/rustc_privacy/src/lib.rs | 1 + compiler/rustc_query_impl/src/lib.rs | 1 + compiler/rustc_sanitizers/src/lib.rs | 1 + compiler/rustc_smir/src/lib.rs | 1 + compiler/rustc_symbol_mangling/src/lib.rs | 1 + compiler/rustc_transmute/src/lib.rs | 1 + compiler/rustc_ty_utils/src/lib.rs | 1 + 29 files changed, 29 insertions(+) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 6372c66050e7..d4a221c65d1b 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -6,6 +6,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(deny(warnings))) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index f58320680284..7cdc3afaca74 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -32,6 +32,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 9841166b37db..ee43f1b82aa0 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -77,6 +77,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 68e0ab0933e6..b42f45dc76c9 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,6 +2,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index ca16583a45de..c1ca813bb0d5 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -5,6 +5,7 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 4e758bfdec39..4573d3352cde 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -2,6 +2,7 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index ed5489652fba..67e1150ddecd 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,6 +1,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index a03834c519d5..381309f83b2c 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -3,6 +3,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(rust_logo)] #![feature(rustdoc_internals)] // tidy-alphabetical-end diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index a2ddff7183e6..725f7c474913 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -7,6 +7,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(decl_macro)] diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 270d4fbec30f..adbc32a76cd5 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -4,6 +4,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(closure_track_caller)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 50b0e32b95eb..99eee3fa1ee7 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -59,6 +59,7 @@ This API is completely unstable and subject to change. #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 8b9c2b4a6ca0..f2e8379b1ce7 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -1,6 +1,7 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(array_windows)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 563ed7614c60..05bdc5dedcfd 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -2,6 +2,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![deny(missing_docs)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7018774e5c6b..82cf08559f62 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -21,6 +21,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(array_windows)] diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index ebcc0efd5a67..8eb90d7bdae8 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -1,5 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(coroutines)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 48ea7df5c23f..3a73196cb6f9 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -29,6 +29,7 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index fa5db32d9134..98d128a714f8 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -3,6 +3,7 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index a8a56baa1ffc..73a5c7745d7d 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -1,4 +1,5 @@ // tidy-alphabetical-start +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 5df12ac4d8bc..31f78bcf40a6 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,4 +1,5 @@ // tidy-alphabetical-start +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(array_windows)] #![feature(assert_matches)] #![feature(box_patterns)] diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 714b64b3a231..0eb52c0927ca 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -1,4 +1,5 @@ // tidy-alphabetical-start +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(array_windows)] #![feature(file_buffered)] #![feature(if_let_guard)] diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 1a104ff5e337..b7cc365dbfd6 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -4,6 +4,7 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(array_windows)] #![feature(assert_matches)] #![feature(box_patterns)] diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 1aa077ad2bb5..334ed6be2882 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -6,6 +6,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(let_chains)] diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5271d03a6f61..3d7315c1a25c 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1,5 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(associated_type_defaults)] diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 73c205fdb17d..036d5ae3bb3a 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -3,6 +3,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(unused_parens)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(min_specialization)] diff --git a/compiler/rustc_sanitizers/src/lib.rs b/compiler/rustc_sanitizers/src/lib.rs index 55be931bcd6d..57a4ec05c0fd 100644 --- a/compiler/rustc_sanitizers/src/lib.rs +++ b/compiler/rustc_sanitizers/src/lib.rs @@ -4,6 +4,7 @@ //! compiler. // tidy-alphabetical-start +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(let_chains)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 2215e2f01ade..079a9e554eb9 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -9,6 +9,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::usage_of_ty_tykind)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 4312c82815c1..195cf75cc5d2 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -89,6 +89,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(let_chains)] diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 81a11f7cfb26..41e089daf46b 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,4 +1,5 @@ // tidy-alphabetical-start +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(never_type)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 8be1611bb9ac..fa2f55aa37ec 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -6,6 +6,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] From 3378ee1a4f2ddfc4b740b70d286fc32d81aca005 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 24 Sep 2024 15:24:26 +1000 Subject: [PATCH 778/991] More denesting of invisibly-delimited groups. This time when converting them to proc-macro `Group` form. --- .../rustc_expand/src/proc_macro_server.rs | 20 ++++++++++++++++++- tests/ui/proc-macro/nodelim-groups.rs | 13 ++++++++++++ tests/ui/proc-macro/nodelim-groups.stdout | 15 ++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 7e5e02fd41b2..e0269eb69034 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -115,7 +115,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { + tokenstream::TokenTree::Delimited(span, _, mut delim, mut stream) => { // We used to have an alternative behaviour for crates that // needed it: a hack used to pass AST fragments to // attribute and derive macros as a single nonterminal @@ -131,6 +131,24 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { print_bang_consume!($e) }; } +macro_rules! m4 { ($e:expr) => { m5!($e); } } +macro_rules! m3 { ($e:expr) => { m4!($e); } } +macro_rules! m2 { ($e:expr) => { m3!($e); } } +macro_rules! m1 { ($e:expr) => { m2!($e); } } + +fn f() { + m1!(123); } diff --git a/tests/ui/proc-macro/nodelim-groups.stdout b/tests/ui/proc-macro/nodelim-groups.stdout index cdf851b535aa..61001035c26c 100644 --- a/tests/ui/proc-macro/nodelim-groups.stdout +++ b/tests/ui/proc-macro/nodelim-groups.stdout @@ -165,3 +165,18 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ span: $DIR/nodelim-groups.rs:16:52: 16:59 (#8), }, ] +PRINT-BANG INPUT (DISPLAY): 123 +PRINT-BANG INPUT (DEBUG): TokenStream [ + Group { + delimiter: None, + stream: TokenStream [ + Literal { + kind: Integer, + symbol: "123", + suffix: None, + span: $DIR/nodelim-groups.rs:34:9: 34:12 (#0), + }, + ], + span: $DIR/nodelim-groups.rs:27:54: 27:56 (#16), + }, +] From 988eb1997014987caad878699ee1e7c000214508 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Tue, 4 Mar 2025 20:28:38 -0800 Subject: [PATCH 779/991] library: Use size_of from the prelude instead of imported Use `std::mem::{size_of, size_of_val, align_of, align_of_val}` from the prelude instead of importing or qualifying them. These functions were added to all preludes in Rust 1.80. --- library/alloc/benches/slice.rs | 14 +++--- library/alloc/benches/vec.rs | 8 ++-- library/alloc/src/boxed/convert.rs | 28 ++++------- library/alloc/src/boxed/thin.rs | 22 ++++----- .../alloc/src/collections/btree/node/tests.rs | 8 ++-- library/alloc/src/raw_vec.rs | 4 +- library/alloc/src/raw_vec/tests.rs | 3 +- library/alloc/src/slice.rs | 4 +- library/alloc/src/string.rs | 6 +-- library/alloc/src/sync.rs | 4 +- library/alloc/src/vec/in_place_collect.rs | 24 +++++----- library/alloc/src/vec/mod.rs | 10 ++-- library/alloc/tests/arc.rs | 5 +- library/alloc/tests/rc.rs | 5 +- library/alloc/tests/slice.rs | 4 +- .../tests/sort/known_good_stable_sort.rs | 6 +-- library/alloc/tests/thin_box.rs | 3 +- library/alloc/tests/vec.rs | 6 +-- library/core/src/alloc/layout.rs | 4 +- library/core/src/char/convert.rs | 16 ++----- library/core/src/clone.rs | 4 +- library/core/src/hash/mod.rs | 4 +- library/core/src/hash/sip.rs | 6 +-- library/core/src/intrinsics/mod.rs | 8 ++-- library/core/src/iter/adapters/map_windows.rs | 4 +- library/core/src/marker.rs | 5 +- library/core/src/mem/maybe_uninit.rs | 4 +- library/core/src/mem/mod.rs | 48 ++++++++----------- library/core/src/mem/transmutability.rs | 6 +-- library/core/src/num/bignum.rs | 3 +- library/core/src/num/dec2flt/fpu.rs | 1 - library/core/src/num/int_macros.rs | 18 +++---- library/core/src/num/mod.rs | 6 +-- library/core/src/num/nonzero.rs | 5 +- library/core/src/num/uint_macros.rs | 20 ++++---- library/core/src/primitive_docs.rs | 28 +++++------ library/core/src/ptr/alignment.rs | 8 ++-- library/core/src/ptr/const_ptr.rs | 22 ++++----- library/core/src/ptr/metadata.rs | 2 +- library/core/src/ptr/mod.rs | 30 +++++------- library/core/src/ptr/mut_ptr.rs | 22 ++++----- library/core/src/ptr/non_null.rs | 18 ++++--- library/core/src/slice/cmp.rs | 6 +-- library/core/src/slice/memchr.rs | 5 +- library/core/src/slice/mod.rs | 26 +++++----- library/core/src/slice/raw.rs | 8 ++-- library/core/src/slice/rotate.rs | 6 +-- .../core/src/slice/sort/shared/smallsort.rs | 16 +++---- library/core/src/slice/sort/stable/mod.rs | 6 +-- .../core/src/slice/sort/stable/quicksort.rs | 4 +- .../core/src/slice/sort/unstable/quicksort.rs | 8 ++-- library/core/src/str/count.rs | 2 +- library/core/src/str/validations.rs | 3 +- library/core/src/sync/atomic.rs | 4 +- library/coretests/benches/ascii/is_ascii.rs | 6 +-- library/coretests/benches/iter.rs | 5 +- library/coretests/tests/alloc.rs | 1 - library/coretests/tests/atomic.rs | 2 - library/coretests/tests/hash/sip.rs | 4 +- library/coretests/tests/nonzero.rs | 1 - library/coretests/tests/ptr.rs | 18 +++---- library/coretests/tests/slice.rs | 4 +- library/panic_unwind/src/emcc.rs | 4 +- library/panic_unwind/src/seh.rs | 4 +- .../proc_macro/src/bridge/selfless_reify.rs | 2 +- library/std/src/fs/tests.rs | 2 +- library/std/src/io/error/tests.rs | 1 - library/std/src/os/fd/tests.rs | 1 - library/std/src/os/unix/io/tests.rs | 1 - library/std/src/os/unix/net/addr.rs | 2 +- library/std/src/os/unix/net/listener.rs | 2 +- library/std/src/os/unix/net/ucred.rs | 14 +++--- library/std/src/os/wasi/io/tests.rs | 1 - library/std/src/os/windows/io/tests.rs | 1 - library/std/src/os/windows/process.rs | 8 +--- library/std/src/os/xous/ffi.rs | 8 ++-- library/std/src/os/xous/services/log.rs | 4 +- library/std/src/sys/alloc/unix.rs | 2 +- library/std/src/sys/alloc/windows/tests.rs | 5 +- library/std/src/sys/io/is_terminal/windows.rs | 1 - library/std/src/sys/net/connection/socket.rs | 16 +++---- .../src/sys/net/connection/socket/hermit.rs | 2 +- .../src/sys/net/connection/socket/solid.rs | 2 +- .../std/src/sys/net/connection/socket/unix.rs | 2 +- .../src/sys/net/connection/socket/wasip2.rs | 2 +- .../src/sys/net/connection/socket/windows.rs | 10 ++-- .../std/src/sys/net/connection/xous/udp.rs | 2 +- library/std/src/sys/pal/itron/thread.rs | 2 +- .../src/sys/pal/sgx/abi/usercalls/alloc.rs | 42 ++++++++-------- library/std/src/sys/pal/uefi/args.rs | 1 - library/std/src/sys/pal/uefi/helpers.rs | 2 +- library/std/src/sys/pal/uefi/process.rs | 2 +- library/std/src/sys/pal/uefi/tests.rs | 2 +- library/std/src/sys/pal/unix/fs.rs | 4 +- library/std/src/sys/pal/unix/futex.rs | 2 +- .../sys/pal/unix/process/process_common.rs | 5 +- .../sys/pal/unix/process/process_fuchsia.rs | 4 +- .../src/sys/pal/unix/process/process_unix.rs | 8 ++-- .../std/src/sys/pal/unix/stack_overflow.rs | 2 +- library/std/src/sys/pal/unix/thread.rs | 6 +-- library/std/src/sys/pal/unix/weak.rs | 2 +- library/std/src/sys/pal/wasi/fd.rs | 8 ++-- library/std/src/sys/pal/wasi/fs.rs | 2 +- library/std/src/sys/pal/wasi/thread.rs | 7 ++- library/std/src/sys/pal/windows/api.rs | 4 +- library/std/src/sys/pal/windows/c.rs | 6 +-- library/std/src/sys/pal/windows/fs.rs | 27 +++++------ library/std/src/sys/pal/windows/futex.rs | 4 +- library/std/src/sys/pal/windows/pipe.rs | 2 +- library/std/src/sys/pal/windows/process.rs | 8 ++-- library/std/src/sys/pal/windows/stdio.rs | 2 +- library/std/src/sys/pal/xous/stdio.rs | 2 +- library/std/src/sys/pal/zkvm/mod.rs | 2 +- library/std/src/sys/personality/dwarf/eh.rs | 5 +- library/std/src/sys/personality/dwarf/mod.rs | 4 +- library/std/src/sys/thread_local/key/xous.rs | 11 ++--- library/std/src/thread/tests.rs | 4 +- library/unwind/src/unwinding.rs | 6 +-- 118 files changed, 392 insertions(+), 486 deletions(-) diff --git a/library/alloc/benches/slice.rs b/library/alloc/benches/slice.rs index c6b46e6a2a18..27b0e6fac0ad 100644 --- a/library/alloc/benches/slice.rs +++ b/library/alloc/benches/slice.rs @@ -1,4 +1,4 @@ -use std::{mem, ptr}; +use std::ptr; use rand::Rng; use rand::distr::{Alphanumeric, SampleString, StandardUniform}; @@ -234,7 +234,7 @@ macro_rules! sort { fn $name(b: &mut Bencher) { let v = $gen($len); b.iter(|| v.clone().$f()); - b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64; + b.bytes = $len * size_of_val(&$gen(1)[0]) as u64; } }; } @@ -246,7 +246,7 @@ macro_rules! sort_strings { let v = $gen($len); let v = v.iter().map(|s| &**s).collect::>(); b.iter(|| v.clone().$f()); - b.bytes = $len * mem::size_of::<&str>() as u64; + b.bytes = $len * size_of::<&str>() as u64; } }; } @@ -268,7 +268,7 @@ macro_rules! sort_expensive { }); black_box(count); }); - b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64; + b.bytes = $len * size_of_val(&$gen(1)[0]) as u64; } }; } @@ -279,7 +279,7 @@ macro_rules! sort_lexicographic { fn $name(b: &mut Bencher) { let v = $gen($len); b.iter(|| v.clone().$f(|x| x.to_string())); - b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64; + b.bytes = $len * size_of_val(&$gen(1)[0]) as u64; } }; } @@ -322,7 +322,7 @@ macro_rules! reverse { fn $name(b: &mut Bencher) { // odd length and offset by 1 to be as unaligned as possible let n = 0xFFFFF; - let mut v: Vec<_> = (0..1 + (n / mem::size_of::<$ty>() as u64)).map($f).collect(); + let mut v: Vec<_> = (0..1 + (n / size_of::<$ty>() as u64)).map($f).collect(); b.iter(|| black_box(&mut v[1..]).reverse()); b.bytes = n; } @@ -346,7 +346,7 @@ macro_rules! rotate { ($name:ident, $gen:expr, $len:expr, $mid:expr) => { #[bench] fn $name(b: &mut Bencher) { - let size = mem::size_of_val(&$gen(1)[0]); + let size = size_of_val(&$gen(1)[0]); let mut v = $gen($len * 8 / size); b.iter(|| black_box(&mut v).rotate_left(($mid * 8 + size - 1) / size)); b.bytes = (v.len() * size) as u64; diff --git a/library/alloc/benches/vec.rs b/library/alloc/benches/vec.rs index a725ad6894b9..1dab71fa1f4f 100644 --- a/library/alloc/benches/vec.rs +++ b/library/alloc/benches/vec.rs @@ -669,7 +669,7 @@ fn random_sorted_fill(mut seed: u32, buf: &mut [u32]) { // This algorithm was used for Vecs prior to Rust 1.52. fn bench_dedup_slice_truncate(b: &mut Bencher, sz: usize) { let mut template = vec![0u32; sz]; - b.bytes = std::mem::size_of_val(template.as_slice()) as u64; + b.bytes = size_of_val(template.as_slice()) as u64; random_sorted_fill(0x43, &mut template); let mut vec = template.clone(); @@ -691,7 +691,7 @@ fn bench_dedup_slice_truncate(b: &mut Bencher, sz: usize) { // Measures performance of Vec::dedup on random data. fn bench_vec_dedup_random(b: &mut Bencher, sz: usize) { let mut template = vec![0u32; sz]; - b.bytes = std::mem::size_of_val(template.as_slice()) as u64; + b.bytes = size_of_val(template.as_slice()) as u64; random_sorted_fill(0x43, &mut template); let mut vec = template.clone(); @@ -708,7 +708,7 @@ fn bench_vec_dedup_random(b: &mut Bencher, sz: usize) { // Measures performance of Vec::dedup when there is no items removed fn bench_vec_dedup_none(b: &mut Bencher, sz: usize) { let mut template = vec![0u32; sz]; - b.bytes = std::mem::size_of_val(template.as_slice()) as u64; + b.bytes = size_of_val(template.as_slice()) as u64; template.chunks_exact_mut(2).for_each(|w| { w[0] = black_box(0); w[1] = black_box(5); @@ -729,7 +729,7 @@ fn bench_vec_dedup_none(b: &mut Bencher, sz: usize) { // Measures performance of Vec::dedup when there is all items removed fn bench_vec_dedup_all(b: &mut Bencher, sz: usize) { let mut template = vec![0u32; sz]; - b.bytes = std::mem::size_of_val(template.as_slice()) as u64; + b.bytes = size_of_val(template.as_slice()) as u64; template.iter_mut().for_each(|w| { *w = black_box(0); }); diff --git a/library/alloc/src/boxed/convert.rs b/library/alloc/src/boxed/convert.rs index 255cefb1e78f..806265802023 100644 --- a/library/alloc/src/boxed/convert.rs +++ b/library/alloc/src/boxed/convert.rs @@ -529,7 +529,6 @@ impl<'a, E: Error + 'a> From for Box { /// ``` /// use std::error::Error; /// use std::fmt; - /// use std::mem; /// /// #[derive(Debug)] /// struct AnError; @@ -543,9 +542,9 @@ impl<'a, E: Error + 'a> From for Box { /// impl Error for AnError {} /// /// let an_error = AnError; - /// assert!(0 == mem::size_of_val(&an_error)); + /// assert!(0 == size_of_val(&an_error)); /// let a_boxed_error = Box::::from(an_error); - /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// assert!(size_of::>() == size_of_val(&a_boxed_error)) /// ``` fn from(err: E) -> Box { Box::new(err) @@ -563,7 +562,6 @@ impl<'a, E: Error + Send + Sync + 'a> From for Box From for Box::from(an_error); /// assert!( - /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// size_of::>() == size_of_val(&a_boxed_error)) /// ``` fn from(err: E) -> Box { Box::new(err) @@ -600,12 +598,11 @@ impl<'a> From for Box { /// /// ``` /// use std::error::Error; - /// use std::mem; /// /// let a_string_error = "a string error".to_string(); /// let a_boxed_error = Box::::from(a_string_error); /// assert!( - /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// size_of::>() == size_of_val(&a_boxed_error)) /// ``` #[inline] fn from(err: String) -> Box { @@ -644,11 +641,10 @@ impl<'a> From for Box { /// /// ``` /// use std::error::Error; - /// use std::mem; /// /// let a_string_error = "a string error".to_string(); /// let a_boxed_error = Box::::from(a_string_error); - /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// assert!(size_of::>() == size_of_val(&a_boxed_error)) /// ``` fn from(str_err: String) -> Box { let err1: Box = From::from(str_err); @@ -668,12 +664,11 @@ impl<'a> From<&str> for Box { /// /// ``` /// use std::error::Error; - /// use std::mem; /// /// let a_str_error = "a str error"; /// let a_boxed_error = Box::::from(a_str_error); /// assert!( - /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// size_of::>() == size_of_val(&a_boxed_error)) /// ``` #[inline] fn from(err: &str) -> Box { @@ -692,11 +687,10 @@ impl<'a> From<&str> for Box { /// /// ``` /// use std::error::Error; - /// use std::mem; /// /// let a_str_error = "a str error"; /// let a_boxed_error = Box::::from(a_str_error); - /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// assert!(size_of::>() == size_of_val(&a_boxed_error)) /// ``` fn from(err: &str) -> Box { From::from(String::from(err)) @@ -712,13 +706,12 @@ impl<'a, 'b> From> for Box { /// /// ``` /// use std::error::Error; - /// use std::mem; /// use std::borrow::Cow; /// /// let a_cow_str_error = Cow::from("a str error"); /// let a_boxed_error = Box::::from(a_cow_str_error); /// assert!( - /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// size_of::>() == size_of_val(&a_boxed_error)) /// ``` fn from(err: Cow<'b, str>) -> Box { From::from(String::from(err)) @@ -734,12 +727,11 @@ impl<'a, 'b> From> for Box { /// /// ``` /// use std::error::Error; - /// use std::mem; /// use std::borrow::Cow; /// /// let a_cow_str_error = Cow::from("a str error"); /// let a_boxed_error = Box::::from(a_cow_str_error); - /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// assert!(size_of::>() == size_of_val(&a_boxed_error)) /// ``` fn from(err: Cow<'b, str>) -> Box { From::from(String::from(err)) diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index 78e5aec09b18..21425b9846e4 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -9,9 +9,8 @@ use core::intrinsics::const_allocate; use core::marker::PhantomData; #[cfg(not(no_global_oom_handling))] use core::marker::Unsize; -use core::mem; #[cfg(not(no_global_oom_handling))] -use core::mem::SizedTypeProperties; +use core::mem::{self, SizedTypeProperties}; use core::ops::{Deref, DerefMut}; use core::ptr::{self, NonNull, Pointee}; @@ -30,7 +29,6 @@ use crate::alloc::{self, Layout, LayoutError}; /// let five = ThinBox::new(5); /// let thin_slice = ThinBox::<[i32]>::new_unsize([1, 2, 3, 4]); /// -/// use std::mem::{size_of, size_of_val}; /// let size_of_ptr = size_of::<*const ()>(); /// assert_eq!(size_of_ptr, size_of_val(&five)); /// assert_eq!(size_of_ptr, size_of_val(&thin_slice)); @@ -114,7 +112,7 @@ impl ThinBox { where T: Unsize, { - if mem::size_of::() == 0 { + if size_of::() == 0 { let ptr = WithOpaqueHeader::new_unsize_zst::(value); ThinBox { ptr, _marker: PhantomData } } else { @@ -283,9 +281,7 @@ impl WithHeader { let ptr = if layout.size() == 0 { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. - debug_assert!( - value_offset == 0 && mem::size_of::() == 0 && mem::size_of::() == 0 - ); + debug_assert!(value_offset == 0 && size_of::() == 0 && size_of::() == 0); layout.dangling() } else { let ptr = alloc::alloc(layout); @@ -315,7 +311,7 @@ impl WithHeader { Dyn: Pointee + ?Sized, T: Unsize, { - assert!(mem::size_of::() == 0); + assert!(size_of::() == 0); const fn max(a: usize, b: usize) -> usize { if a > b { a } else { b } @@ -329,18 +325,16 @@ impl WithHeader { // FIXME: just call `WithHeader::alloc_layout` with size reset to 0. // Currently that's blocked on `Layout::extend` not being `const fn`. - let alloc_align = - max(mem::align_of::(), mem::align_of::<::Metadata>()); + let alloc_align = max(align_of::(), align_of::<::Metadata>()); - let alloc_size = - max(mem::align_of::(), mem::size_of::<::Metadata>()); + let alloc_size = max(align_of::(), size_of::<::Metadata>()); unsafe { // SAFETY: align is power of two because it is the maximum of two alignments. let alloc: *mut u8 = const_allocate(alloc_size, alloc_align); let metadata_offset = - alloc_size.checked_sub(mem::size_of::<::Metadata>()).unwrap(); + alloc_size.checked_sub(size_of::<::Metadata>()).unwrap(); // SAFETY: adding offset within the allocation. let metadata_ptr: *mut ::Metadata = alloc.add(metadata_offset).cast(); @@ -421,7 +415,7 @@ impl WithHeader { } const fn header_size() -> usize { - mem::size_of::() + size_of::() } fn alloc_layout(value_layout: Layout) -> Result<(Layout, usize), LayoutError> { diff --git a/library/alloc/src/collections/btree/node/tests.rs b/library/alloc/src/collections/btree/node/tests.rs index ecd009f11c71..7d1a2ea48094 100644 --- a/library/alloc/src/collections/btree/node/tests.rs +++ b/library/alloc/src/collections/btree/node/tests.rs @@ -92,8 +92,8 @@ fn test_partial_eq() { #[cfg(target_arch = "x86_64")] #[cfg_attr(any(miri, randomized_layouts), ignore)] // We'd like to run Miri with layout randomization fn test_sizes() { - assert_eq!(core::mem::size_of::>(), 16); - assert_eq!(core::mem::size_of::>(), 16 + CAPACITY * 2 * 8); - assert_eq!(core::mem::size_of::>(), 16 + (CAPACITY + 1) * 8); - assert_eq!(core::mem::size_of::>(), 16 + (CAPACITY * 3 + 1) * 8); + assert_eq!(size_of::>(), 16); + assert_eq!(size_of::>(), 16 + CAPACITY * 2 * 8); + assert_eq!(size_of::>(), 16 + (CAPACITY + 1) * 8); + assert_eq!(size_of::>(), 16 + (CAPACITY * 3 + 1) * 8); } diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index b80d1fc78894..70f32fbaab42 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -480,7 +480,7 @@ impl RawVecInner { // Allocators currently return a `NonNull<[u8]>` whose length // matches the size requested. If that ever changes, the capacity - // here should change to `ptr.len() / mem::size_of::()`. + // here should change to `ptr.len() / size_of::()`. Ok(Self { ptr: Unique::from(ptr.cast()), cap: unsafe { Cap::new_unchecked(capacity) }, @@ -627,7 +627,7 @@ impl RawVecInner { unsafe fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) { // Allocators currently return a `NonNull<[u8]>` whose length matches // the size requested. If that ever changes, the capacity here should - // change to `ptr.len() / mem::size_of::()`. + // change to `ptr.len() / size_of::()`. self.ptr = Unique::from(ptr.cast()); self.cap = unsafe { Cap::new_unchecked(cap) }; } diff --git a/library/alloc/src/raw_vec/tests.rs b/library/alloc/src/raw_vec/tests.rs index d78ded104fb0..700fa922739d 100644 --- a/library/alloc/src/raw_vec/tests.rs +++ b/library/alloc/src/raw_vec/tests.rs @@ -1,4 +1,3 @@ -use core::mem::size_of; use std::cell::Cell; use super::*; @@ -93,7 +92,7 @@ fn zst_sanity(v: &RawVec) { fn zst() { let cap_err = Err(crate::collections::TryReserveErrorKind::CapacityOverflow.into()); - assert_eq!(std::mem::size_of::(), 0); + assert_eq!(size_of::(), 0); // All these different ways of creating the RawVec produce the same thing. diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index dcd95ddf00ff..8baf96850626 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -16,7 +16,7 @@ use core::borrow::{Borrow, BorrowMut}; #[cfg(not(no_global_oom_handling))] use core::cmp::Ordering::{self, Less}; #[cfg(not(no_global_oom_handling))] -use core::mem::{self, MaybeUninit}; +use core::mem::MaybeUninit; #[cfg(not(no_global_oom_handling))] use core::ptr; #[unstable(feature = "array_chunks", issue = "74985")] @@ -446,7 +446,7 @@ impl [T] { // Avoids binary-size usage in cases where the alignment doesn't work out to make this // beneficial or on 32-bit platforms. let is_using_u32_as_idx_type_helpful = - const { mem::size_of::<(K, u32)>() < mem::size_of::<(K, usize)>() }; + const { size_of::<(K, u32)>() < size_of::<(K, usize)>() }; // It's possible to instantiate this for u8 and u16 but, doing so is very wasteful in terms // of compile-times and binary-size, the peak saved heap memory for u16 is (u8 + u16) -> 4 diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index f10ef1fca137..679c8eb12b4e 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -119,8 +119,6 @@ use crate::vec::{self, Vec}; /// the same `char`s: /// /// ``` -/// use std::mem; -/// /// // `s` is ASCII which represents each `char` as one byte /// let s = "hello"; /// assert_eq!(s.len(), 5); @@ -128,7 +126,7 @@ use crate::vec::{self, Vec}; /// // A `char` array with the same contents would be longer because /// // every `char` is four bytes /// let s = ['h', 'e', 'l', 'l', 'o']; -/// let size: usize = s.into_iter().map(|c| mem::size_of_val(&c)).sum(); +/// let size: usize = s.into_iter().map(|c| size_of_val(&c)).sum(); /// assert_eq!(size, 20); /// /// // However, for non-ASCII strings, the difference will be smaller @@ -137,7 +135,7 @@ use crate::vec::{self, Vec}; /// assert_eq!(s.len(), 20); /// /// let s = ['💖', '💖', '💖', '💖', '💖']; -/// let size: usize = s.into_iter().map(|c| mem::size_of_val(&c)).sum(); +/// let size: usize = s.into_iter().map(|c| size_of_val(&c)).sum(); /// assert_eq!(size, 20); /// ``` /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index dba1449347ac..1956dda53881 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2274,7 +2274,7 @@ impl Arc { #[inline] #[stable(feature = "arc_unique", since = "1.4.0")] pub fn make_mut(this: &mut Self) -> &mut T { - let size_of_val = mem::size_of_val::(&**this); + let size_of_val = size_of_val::(&**this); // Note that we hold both a strong reference and a weak reference. // Thus, releasing our strong reference only will not, by itself, cause @@ -3544,7 +3544,7 @@ impl Default for Arc<[T]> { /// This may or may not share an allocation with other Arcs. #[inline] fn default() -> Self { - if mem::align_of::() <= MAX_STATIC_INNER_SLICE_ALIGNMENT { + if align_of::() <= MAX_STATIC_INNER_SLICE_ALIGNMENT { // We take a reference to the whole struct instead of the ArcInner<[u8; 1]> inside it so // we don't shrink the range of bytes the ptr is allowed to access under Stacked Borrows. // (Miri complains on 32-bit targets with Arc<[Align16]> otherwise.) diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index dffd85f13aa5..b98a118048f2 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -171,7 +171,7 @@ const fn in_place_collectible( ) -> bool { // Require matching alignments because an alignment-changing realloc is inefficient on many // system allocators and better implementations would require the unstable Allocator trait. - if const { SRC::IS_ZST || DEST::IS_ZST || mem::align_of::() != mem::align_of::() } { + if const { SRC::IS_ZST || DEST::IS_ZST || align_of::() != align_of::() } { return false; } @@ -181,7 +181,7 @@ const fn in_place_collectible( // e.g. // - 1 x [u8; 4] -> 4x u8, via flatten // - 4 x u8 -> 1x [u8; 4], via array_chunks - mem::size_of::() * step_merge.get() >= mem::size_of::() * step_expand.get() + size_of::() * step_merge.get() >= size_of::() * step_expand.get() } // Fall back to other from_iter impls if an overflow occurred in the step merge/expansion // tracking. @@ -190,7 +190,7 @@ const fn in_place_collectible( } const fn needs_realloc(src_cap: usize, dst_cap: usize) -> bool { - if const { mem::align_of::() != mem::align_of::() } { + if const { align_of::() != align_of::() } { // FIXME(const-hack): use unreachable! once that works in const panic!("in_place_collectible() prevents this"); } @@ -199,8 +199,8 @@ const fn needs_realloc(src_cap: usize, dst_cap: usize) -> bool { // the caller will have calculated a `dst_cap` that is an integer multiple of // `src_cap` without remainder. if const { - let src_sz = mem::size_of::(); - let dest_sz = mem::size_of::(); + let src_sz = size_of::(); + let dest_sz = size_of::(); dest_sz != 0 && src_sz % dest_sz == 0 } { return false; @@ -208,7 +208,7 @@ const fn needs_realloc(src_cap: usize, dst_cap: usize) -> bool { // type layouts don't guarantee a fit, so do a runtime check to see if // the allocations happen to match - src_cap > 0 && src_cap * mem::size_of::() != dst_cap * mem::size_of::() + src_cap > 0 && src_cap * size_of::() != dst_cap * size_of::() } /// This provides a shorthand for the source type since local type aliases aren't a thing. @@ -262,7 +262,7 @@ where inner.buf.cast::(), inner.end as *const T, // SAFETY: the multiplication can not overflow, since `inner.cap * size_of::()` is the size of the allocation. - inner.cap.unchecked_mul(mem::size_of::()) / mem::size_of::(), + inner.cap.unchecked_mul(size_of::()) / size_of::(), ) }; @@ -310,14 +310,14 @@ where debug_assert_ne!(dst_cap, 0); unsafe { // The old allocation exists, therefore it must have a valid layout. - let src_align = mem::align_of::(); - let src_size = mem::size_of::().unchecked_mul(src_cap); + let src_align = align_of::(); + let src_size = size_of::().unchecked_mul(src_cap); let old_layout = Layout::from_size_align_unchecked(src_size, src_align); // The allocation must be equal or smaller for in-place iteration to be possible // therefore the new layout must be ≤ the old one and therefore valid. - let dst_align = mem::align_of::(); - let dst_size = mem::size_of::().unchecked_mul(dst_cap); + let dst_align = align_of::(); + let dst_size = size_of::().unchecked_mul(dst_cap); let new_layout = Layout::from_size_align_unchecked(dst_size, dst_align); let result = alloc.shrink(dst_buf.cast(), old_layout, new_layout); @@ -325,7 +325,7 @@ where dst_buf = reallocated.cast::(); } } else { - debug_assert_eq!(src_cap * mem::size_of::(), dst_cap * mem::size_of::()); + debug_assert_eq!(src_cap * size_of::(), dst_cap * size_of::()); } mem::forget(dst_guard); diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 701144cc3af2..49878f2b6fa5 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -293,7 +293,7 @@ mod spec_extend; /// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized /// types inside a `Vec`, it will not allocate space for them. *Note that in this case /// the `Vec` might not report a [`capacity`] of 0*. `Vec` will allocate if and only -/// if [mem::size_of::\]\() * [capacity]\() > 0. In general, `Vec`'s allocation +/// if [size_of::\]\() * [capacity]\() > 0. In general, `Vec`'s allocation /// details are very subtle --- if you intend to allocate memory using a `Vec` /// and use it for something else (either to pass to unsafe code, or to build your /// own memory-backed collection), be sure to deallocate this memory by using @@ -393,7 +393,7 @@ mod spec_extend; /// [capacity]: Vec::capacity /// [`capacity`]: Vec::capacity /// [`Vec::capacity`]: Vec::capacity -/// [mem::size_of::\]: core::mem::size_of +/// [size_of::\]: size_of /// [len]: Vec::len /// [`len`]: Vec::len /// [`push`]: Vec::push @@ -1573,7 +1573,7 @@ impl Vec { pub const fn as_slice(&self) -> &[T] { // SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size // `len` containing properly-initialized `T`s. Data must not be mutated for the returned - // lifetime. Further, `len * mem::size_of::` <= `ISIZE::MAX`, and allocation does not + // lifetime. Further, `len * size_of::` <= `isize::MAX`, and allocation does not // "wrap" through overflowing memory addresses. // // * Vec API guarantees that self.buf: @@ -1605,7 +1605,7 @@ impl Vec { pub const fn as_mut_slice(&mut self) -> &mut [T] { // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of // size `len` containing properly-initialized `T`s. Data must not be accessed through any - // other pointer for the returned lifetime. Further, `len * mem::size_of::` <= + // other pointer for the returned lifetime. Further, `len * size_of::` <= // `ISIZE::MAX` and allocation does not "wrap" through overflowing memory addresses. // // * Vec API guarantees that self.buf: @@ -2693,7 +2693,7 @@ impl Vec { let len = self.len; // SAFETY: The maximum capacity of `Vec` is `isize::MAX` bytes, so the maximum value can - // be returned is `usize::checked_div(mem::size_of::()).unwrap_or(usize::MAX)`, which + // be returned is `usize::checked_div(size_of::()).unwrap_or(usize::MAX)`, which // matches the definition of `T::MAX_SLICE_LEN`. unsafe { intrinsics::assume(len <= T::MAX_SLICE_LEN) }; diff --git a/library/alloc/tests/arc.rs b/library/alloc/tests/arc.rs index a259c0131ecd..0baa50f439b3 100644 --- a/library/alloc/tests/arc.rs +++ b/library/alloc/tests/arc.rs @@ -1,7 +1,6 @@ use std::any::Any; use std::cell::{Cell, RefCell}; use std::iter::TrustedLen; -use std::mem; use std::sync::{Arc, Weak}; #[test] @@ -129,7 +128,7 @@ fn shared_from_iter_trustedlen_normal() { let vec = iter.clone().collect::>(); let rc = iter.collect::>(); assert_eq!(&*vec, &*rc); - assert_eq!(mem::size_of::>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc)); + assert_eq!(size_of::>() * SHARED_ITER_MAX as usize, size_of_val(&*rc)); // Clone a bit and let these get dropped. { @@ -145,7 +144,7 @@ fn shared_from_iter_trustedlen_normal() { let vec = iter.clone().collect::>(); let rc = iter.collect::>(); assert_eq!(&*vec, &*rc); - assert_eq!(0, mem::size_of_val(&*rc)); + assert_eq!(0, size_of_val(&*rc)); { let _rc_2 = rc.clone(); let _rc_3 = rc.clone(); diff --git a/library/alloc/tests/rc.rs b/library/alloc/tests/rc.rs index 451765d72428..9d82a7621a21 100644 --- a/library/alloc/tests/rc.rs +++ b/library/alloc/tests/rc.rs @@ -1,7 +1,6 @@ use std::any::Any; use std::cell::{Cell, RefCell}; use std::iter::TrustedLen; -use std::mem; use std::rc::{Rc, Weak}; #[test] @@ -125,7 +124,7 @@ fn shared_from_iter_trustedlen_normal() { let vec = iter.clone().collect::>(); let rc = iter.collect::>(); assert_eq!(&*vec, &*rc); - assert_eq!(mem::size_of::>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc)); + assert_eq!(size_of::>() * SHARED_ITER_MAX as usize, size_of_val(&*rc)); // Clone a bit and let these get dropped. { @@ -141,7 +140,7 @@ fn shared_from_iter_trustedlen_normal() { let vec = iter.clone().collect::>(); let rc = iter.collect::>(); assert_eq!(&*vec, &*rc); - assert_eq!(0, mem::size_of_val(&*rc)); + assert_eq!(0, size_of_val(&*rc)); { let _rc_2 = rc.clone(); let _rc_3 = rc.clone(); diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs index f990a41b679f..2516563187f2 100644 --- a/library/alloc/tests/slice.rs +++ b/library/alloc/tests/slice.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering::{Equal, Greater, Less}; use std::convert::identity; use std::rc::Rc; -use std::{fmt, mem, panic}; +use std::{fmt, panic}; fn square(n: usize) -> usize { n * n @@ -73,7 +73,7 @@ fn test_len_divzero() { let v0: &[Z] = &[]; let v1: &[Z] = &[[]]; let v2: &[Z] = &[[], []]; - assert_eq!(mem::size_of::(), 0); + assert_eq!(size_of::(), 0); assert_eq!(v0.len(), 0); assert_eq!(v1.len(), 1); assert_eq!(v2.len(), 2); diff --git a/library/alloc/tests/sort/known_good_stable_sort.rs b/library/alloc/tests/sort/known_good_stable_sort.rs index f8615435fc2a..2df891462538 100644 --- a/library/alloc/tests/sort/known_good_stable_sort.rs +++ b/library/alloc/tests/sort/known_good_stable_sort.rs @@ -5,7 +5,7 @@ // Based on https://github.com/voultapher/tiny-sort-rs. use alloc::alloc::{Layout, alloc, dealloc}; -use std::{mem, ptr}; +use std::ptr; /// Sort `v` preserving initial order of equal elements. /// @@ -26,7 +26,7 @@ pub fn sort(v: &mut [T]) { #[inline(always)] fn stable_sort bool>(v: &mut [T], mut is_less: F) { - if mem::size_of::() == 0 { + if size_of::() == 0 { return; } @@ -166,7 +166,7 @@ struct BufGuard { impl BufGuard { // SAFETY: The caller has to ensure that len is not 0 and that T is not a ZST. unsafe fn new(len: usize) -> Self { - debug_assert!(len > 0 && mem::size_of::() > 0); + debug_assert!(len > 0 && size_of::() > 0); // SAFETY: See function safety description. let layout = unsafe { unwrap_unchecked(Layout::array::(len).ok()) }; diff --git a/library/alloc/tests/thin_box.rs b/library/alloc/tests/thin_box.rs index e008b0cc3571..4c46b6141279 100644 --- a/library/alloc/tests/thin_box.rs +++ b/library/alloc/tests/thin_box.rs @@ -1,5 +1,4 @@ use core::fmt::Debug; -use core::mem::size_of; use std::boxed::ThinBox; #[test] @@ -52,7 +51,7 @@ fn verify_aligned(ptr: *const T) { ptr.is_aligned() && !ptr.is_null(), "misaligned ThinBox data; valid pointers to `{ty}` should be aligned to {align}: {ptr:p}", ty = core::any::type_name::(), - align = core::mem::align_of::(), + align = align_of::(), ); } diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index fe1db56414e0..f430d979fa84 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -11,14 +11,14 @@ use std::borrow::Cow; use std::cell::Cell; use std::collections::TryReserveErrorKind::*; use std::fmt::Debug; +use std::hint; use std::iter::InPlaceIterable; -use std::mem::{size_of, swap}; +use std::mem::swap; use std::ops::Bound::*; use std::panic::{AssertUnwindSafe, catch_unwind}; use std::rc::Rc; use std::sync::atomic::{AtomicU32, Ordering}; use std::vec::{Drain, IntoIter}; -use std::{hint, mem}; struct DropCounter<'a> { count: &'a mut u32, @@ -1134,7 +1134,7 @@ fn test_into_iter_zst() { impl Drop for AlignedZstWithDrop { fn drop(&mut self) { let addr = self as *mut _ as usize; - assert!(hint::black_box(addr) % mem::align_of::() == 0); + assert!(hint::black_box(addr) % align_of::() == 0); } } diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 17f4d68867e1..1595a3af883d 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -17,7 +17,7 @@ use crate::{assert_unsafe_precondition, fmt, mem}; // * https://github.com/rust-lang/rust/pull/72189 // * https://github.com/rust-lang/rust/pull/79827 const fn size_align() -> (usize, usize) { - (mem::size_of::(), mem::align_of::()) + (size_of::(), align_of::()) } /// Layout of a block of memory. @@ -182,7 +182,7 @@ impl Layout { #[must_use] #[inline] pub const fn for_value(t: &T) -> Self { - let (size, align) = (mem::size_of_val(t), mem::align_of_val(t)); + let (size, align) = (size_of_val(t), align_of_val(t)); // SAFETY: see rationale in `new` for why this is using the unsafe variant unsafe { Layout::from_size_align_unchecked(size, align) } } diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 73ab4f1e52ad..ac808038f890 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -40,11 +40,9 @@ impl From for u32 { /// # Examples /// /// ``` - /// use std::mem; - /// /// let c = 'c'; /// let u = u32::from(c); - /// assert!(4 == mem::size_of_val(&u)) + /// assert!(4 == size_of_val(&u)) /// ``` #[inline] fn from(c: char) -> Self { @@ -59,11 +57,9 @@ impl From for u64 { /// # Examples /// /// ``` - /// use std::mem; - /// /// let c = '👤'; /// let u = u64::from(c); - /// assert!(8 == mem::size_of_val(&u)) + /// assert!(8 == size_of_val(&u)) /// ``` #[inline] fn from(c: char) -> Self { @@ -80,11 +76,9 @@ impl From for u128 { /// # Examples /// /// ``` - /// use std::mem; - /// /// let c = '⚙'; /// let u = u128::from(c); - /// assert!(16 == mem::size_of_val(&u)) + /// assert!(16 == size_of_val(&u)) /// ``` #[inline] fn from(c: char) -> Self { @@ -167,11 +161,9 @@ impl From for char { /// # Examples /// /// ``` - /// use std::mem; - /// /// let u = 32 as u8; /// let c = char::from(u); - /// assert!(4 == mem::size_of_val(&c)) + /// assert!(4 == size_of_val(&c)) /// ``` #[inline] fn from(i: u8) -> Self { diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 00300328b64c..9d64348289cf 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -244,8 +244,8 @@ pub unsafe trait CloneToUninit { /// /// Behavior is undefined if any of the following conditions are violated: /// - /// * `dst` must be [valid] for writes for `std::mem::size_of_val(self)` bytes. - /// * `dst` must be properly aligned to `std::mem::align_of_val(self)`. + /// * `dst` must be [valid] for writes for `size_of_val(self)` bytes. + /// * `dst` must be properly aligned to `align_of_val(self)`. /// /// [valid]: crate::ptr#safety /// [pointer metadata]: crate::ptr::metadata() diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 7a6630c82d0d..f7b874b26bb7 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -801,7 +801,7 @@ impl Eq for BuildHasherDefault {} mod impls { use super::*; - use crate::{mem, slice}; + use crate::slice; macro_rules! impl_write { ($(($ty:ident, $meth:ident),)*) => {$( @@ -814,7 +814,7 @@ mod impls { #[inline] fn hash_slice(data: &[$ty], state: &mut H) { - let newlen = mem::size_of_val(data); + let newlen = size_of_val(data); let ptr = data.as_ptr() as *const u8; // SAFETY: `ptr` is valid and aligned, as this macro is only used // for numeric primitives which have no padding. The new slice only diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs index 6ea3241c5935..780e522c48eb 100644 --- a/library/core/src/hash/sip.rs +++ b/library/core/src/hash/sip.rs @@ -3,7 +3,7 @@ #![allow(deprecated)] // the types in this module are deprecated use crate::marker::PhantomData; -use crate::{cmp, mem, ptr}; +use crate::{cmp, ptr}; /// An implementation of SipHash 1-3. /// @@ -99,12 +99,12 @@ macro_rules! compress { /// `$i..$i+size_of::<$int_ty>()`, so that must be in-bounds. macro_rules! load_int_le { ($buf:expr, $i:expr, $int_ty:ident) => {{ - debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len()); + debug_assert!($i + size_of::<$int_ty>() <= $buf.len()); let mut data = 0 as $int_ty; ptr::copy_nonoverlapping( $buf.as_ptr().add($i), &mut data as *mut _ as *mut u8, - mem::size_of::<$int_ty>(), + size_of::<$int_ty>(), ); data.to_le() }}; diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 38a60338e74e..b405e1d413ae 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3340,7 +3340,7 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize; /// More specifically, this is the offset in bytes between successive /// items of the same type, including alignment padding. /// -/// The stabilized version of this intrinsic is [`core::mem::size_of`]. +/// The stabilized version of this intrinsic is [`size_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] @@ -3354,7 +3354,7 @@ pub const fn size_of() -> usize; /// Therefore, implementations must not require the user to uphold /// any safety invariants. /// -/// The stabilized version of this intrinsic is [`core::mem::align_of`]. +/// The stabilized version of this intrinsic is [`align_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] @@ -3386,7 +3386,7 @@ pub const fn variant_count() -> usize; /// The size of the referenced value in bytes. /// -/// The stabilized version of this intrinsic is [`crate::mem::size_of_val`]. +/// The stabilized version of this intrinsic is [`size_of_val`]. /// /// # Safety /// @@ -3399,7 +3399,7 @@ pub const unsafe fn size_of_val(_ptr: *const T) -> usize; /// The required alignment of the referenced value. /// -/// The stabilized version of this intrinsic is [`core::mem::align_of_val`]. +/// The stabilized version of this intrinsic is [`align_of_val`]. /// /// # Safety /// diff --git a/library/core/src/iter/adapters/map_windows.rs b/library/core/src/iter/adapters/map_windows.rs index cb13023c85c4..a9c07fee2a91 100644 --- a/library/core/src/iter/adapters/map_windows.rs +++ b/library/core/src/iter/adapters/map_windows.rs @@ -1,5 +1,5 @@ use crate::iter::FusedIterator; -use crate::mem::{self, MaybeUninit}; +use crate::mem::MaybeUninit; use crate::{fmt, ptr}; /// An iterator over the mapped windows of another iterator. @@ -50,7 +50,7 @@ impl MapWindows { assert!(N != 0, "array in `Iterator::map_windows` must contain more than 0 elements"); // Only ZST arrays' length can be so large. - if mem::size_of::() == 0 { + if size_of::() == 0 { assert!( N.checked_mul(2).is_some(), "array size of `Iterator::map_windows` is too large" diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b0571bf7247a..b6fd823f77ea 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -405,7 +405,7 @@ marker_impls! { /// /// [`Vec`]: ../../std/vec/struct.Vec.html /// [`String`]: ../../std/string/struct.String.html -/// [`size_of::`]: crate::mem::size_of +/// [`size_of::`]: size_of /// [impls]: #implementors #[stable(feature = "rust1", since = "1.0.0")] #[lang = "copy"] @@ -731,7 +731,6 @@ impl !Sync for *mut T {} /// # } /// # fn convert_params(_: ParamType) -> usize { 42 } /// use std::marker::PhantomData; -/// use std::mem; /// /// struct ExternalResource { /// resource_handle: *mut (), @@ -740,7 +739,7 @@ impl !Sync for *mut T {} /// /// impl ExternalResource { /// fn new() -> Self { -/// let size_of_res = mem::size_of::(); +/// let size_of_res = size_of::(); /// Self { /// resource_handle: foreign_lib::new(size_of_res), /// resource_type: PhantomData, diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 067371c1b58a..ce84f105e5c5 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -203,7 +203,7 @@ use crate::{fmt, intrinsics, ptr, slice}; /// `MaybeUninit` is guaranteed to have the same size, alignment, and ABI as `T`: /// /// ```rust -/// use std::mem::{MaybeUninit, size_of, align_of}; +/// use std::mem::MaybeUninit; /// assert_eq!(size_of::>(), size_of::()); /// assert_eq!(align_of::>(), align_of::()); /// ``` @@ -215,7 +215,7 @@ use crate::{fmt, intrinsics, ptr, slice}; /// optimizations, potentially resulting in a larger size: /// /// ```rust -/// # use std::mem::{MaybeUninit, size_of}; +/// # use std::mem::MaybeUninit; /// assert_eq!(size_of::>(), 1); /// assert_eq!(size_of::>>(), 2); /// ``` diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index b9bb6d6a13f7..caab7a6ddb52 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -226,31 +226,27 @@ pub fn forget_unsized(t: T) { /// # Examples /// /// ``` -/// use std::mem; -/// /// // Some primitives -/// assert_eq!(4, mem::size_of::()); -/// assert_eq!(8, mem::size_of::()); -/// assert_eq!(0, mem::size_of::<()>()); +/// assert_eq!(4, size_of::()); +/// assert_eq!(8, size_of::()); +/// assert_eq!(0, size_of::<()>()); /// /// // Some arrays -/// assert_eq!(8, mem::size_of::<[i32; 2]>()); -/// assert_eq!(12, mem::size_of::<[i32; 3]>()); -/// assert_eq!(0, mem::size_of::<[i32; 0]>()); +/// assert_eq!(8, size_of::<[i32; 2]>()); +/// assert_eq!(12, size_of::<[i32; 3]>()); +/// assert_eq!(0, size_of::<[i32; 0]>()); /// /// /// // Pointer size equality -/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<*const i32>()); -/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::>()); -/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::>()); -/// assert_eq!(mem::size_of::>(), mem::size_of::>>()); +/// assert_eq!(size_of::<&i32>(), size_of::<*const i32>()); +/// assert_eq!(size_of::<&i32>(), size_of::>()); +/// assert_eq!(size_of::<&i32>(), size_of::>()); +/// assert_eq!(size_of::>(), size_of::>>()); /// ``` /// /// Using `#[repr(C)]`. /// /// ``` -/// use std::mem; -/// /// #[repr(C)] /// struct FieldStruct { /// first: u8, @@ -265,13 +261,13 @@ pub fn forget_unsized(t: T) { /// // The size of the third field is 1, so add 1 to the size. Size is 5. /// // Finally, the alignment of the struct is 2 (because the largest alignment amongst its /// // fields is 2), so add 1 to the size for padding. Size is 6. -/// assert_eq!(6, mem::size_of::()); +/// assert_eq!(6, size_of::()); /// /// #[repr(C)] /// struct TupleStruct(u8, u16, u8); /// /// // Tuple structs follow the same rules. -/// assert_eq!(6, mem::size_of::()); +/// assert_eq!(6, size_of::()); /// /// // Note that reordering the fields can lower the size. We can remove both padding bytes /// // by putting `third` before `second`. @@ -282,7 +278,7 @@ pub fn forget_unsized(t: T) { /// second: u16 /// } /// -/// assert_eq!(4, mem::size_of::()); +/// assert_eq!(4, size_of::()); /// /// // Union size is the size of the largest field. /// #[repr(C)] @@ -291,7 +287,7 @@ pub fn forget_unsized(t: T) { /// larger: u16 /// } /// -/// assert_eq!(2, mem::size_of::()); +/// assert_eq!(2, size_of::()); /// ``` /// /// [alignment]: align_of @@ -320,13 +316,11 @@ pub const fn size_of() -> usize { /// # Examples /// /// ``` -/// use std::mem; -/// -/// assert_eq!(4, mem::size_of_val(&5i32)); +/// assert_eq!(4, size_of_val(&5i32)); /// /// let x: [u8; 13] = [0; 13]; /// let y: &[u8] = &x; -/// assert_eq!(13, mem::size_of_val(y)); +/// assert_eq!(13, size_of_val(y)); /// ``` /// /// [`size_of::()`]: size_of @@ -381,7 +375,7 @@ pub const fn size_of_val(val: &T) -> usize { /// #![feature(layout_for_ptr)] /// use std::mem; /// -/// assert_eq!(4, mem::size_of_val(&5i32)); +/// assert_eq!(4, size_of_val(&5i32)); /// /// let x: [u8; 13] = [0; 13]; /// let y: &[u8] = &x; @@ -454,9 +448,7 @@ pub fn min_align_of_val(val: &T) -> usize { /// # Examples /// /// ``` -/// use std::mem; -/// -/// assert_eq!(4, mem::align_of::()); +/// assert_eq!(4, align_of::()); /// ``` #[inline(always)] #[must_use] @@ -477,9 +469,7 @@ pub const fn align_of() -> usize { /// # Examples /// /// ``` -/// use std::mem; -/// -/// assert_eq!(4, mem::align_of_val(&5i32)); +/// assert_eq!(4, align_of_val(&5i32)); /// ``` #[inline] #[must_use] diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs index 7b920d7a777c..782b826448a3 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/core/src/mem/transmutability.rs @@ -153,7 +153,7 @@ pub struct Assume { /// /// ```compile_fail,E0277 /// #![feature(transmutability)] - /// use core::mem::{align_of, TransmuteFrom}; + /// use core::mem::TransmuteFrom; /// /// assert_eq!(align_of::<[u8; 2]>(), 1); /// assert_eq!(align_of::(), 2); @@ -172,7 +172,7 @@ pub struct Assume { /// /// ```rust /// #![feature(pointer_is_aligned_to, transmutability)] - /// use core::mem::{align_of, Assume, TransmuteFrom}; + /// use core::mem::{Assume, TransmuteFrom}; /// /// let src: &[u8; 2] = &[0xFF, 0xFF]; /// @@ -337,7 +337,7 @@ impl Assume { /// transmutability, /// )] /// #![allow(incomplete_features)] - /// use core::mem::{align_of, Assume, TransmuteFrom}; + /// use core::mem::{Assume, TransmuteFrom}; /// /// /// Attempts to transmute `src` to `&Dst`. /// /// diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs index 2a47c89e2aee..40e6eaf075ed 100644 --- a/library/core/src/num/bignum.rs +++ b/library/core/src/num/bignum.rs @@ -253,12 +253,11 @@ macro_rules! define_bignum { /// Multiplies itself by `5^e` and returns its own mutable reference. pub fn mul_pow5(&mut self, mut e: usize) -> &mut $name { - use crate::mem; use crate::num::bignum::SMALL_POW5; // There are exactly n trailing zeros on 2^n, and the only relevant digit sizes // are consecutive powers of two, so this is well suited index for the table. - let table_index = mem::size_of::<$ty>().trailing_zeros() as usize; + let table_index = size_of::<$ty>().trailing_zeros() as usize; let (small_power, small_e) = SMALL_POW5[table_index]; let small_power = small_power as $ty; diff --git a/library/core/src/num/dec2flt/fpu.rs b/library/core/src/num/dec2flt/fpu.rs index daeee1755b0b..8aad087ec1bc 100644 --- a/library/core/src/num/dec2flt/fpu.rs +++ b/library/core/src/num/dec2flt/fpu.rs @@ -22,7 +22,6 @@ pub(super) use fpu_precision::set_precision; #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))] mod fpu_precision { use core::arch::asm; - use core::mem::size_of; /// A structure used to preserve the original value of the FPU control word, so that it can be /// restored when the structure is dropped. diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 7d99aaa17314..a72ca4bcb059 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -3627,7 +3627,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_be_bytes(self) -> [u8; mem::size_of::()] { + pub const fn to_be_bytes(self) -> [u8; size_of::()] { self.to_be().to_ne_bytes() } @@ -3647,7 +3647,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_le_bytes(self) -> [u8; mem::size_of::()] { + pub const fn to_le_bytes(self) -> [u8; size_of::()] { self.to_le().to_ne_bytes() } @@ -3683,7 +3683,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_ne_bytes(self) -> [u8; mem::size_of::()] { + pub const fn to_ne_bytes(self) -> [u8; size_of::()] { // SAFETY: integers are plain old datatypes so we can always transmute them to // arrays of bytes unsafe { mem::transmute(self) } @@ -3705,7 +3705,7 @@ macro_rules! int_impl { /// /// ``` #[doc = concat!("fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")] - #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")] + #[doc = concat!(" let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")] /// *input = rest; #[doc = concat!(" ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())")] /// } @@ -3714,7 +3714,7 @@ macro_rules! int_impl { #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[must_use] #[inline] - pub const fn from_be_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub const fn from_be_bytes(bytes: [u8; size_of::()]) -> Self { Self::from_be(Self::from_ne_bytes(bytes)) } @@ -3734,7 +3734,7 @@ macro_rules! int_impl { /// /// ``` #[doc = concat!("fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")] - #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")] + #[doc = concat!(" let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")] /// *input = rest; #[doc = concat!(" ", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())")] /// } @@ -3743,7 +3743,7 @@ macro_rules! int_impl { #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[must_use] #[inline] - pub const fn from_le_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub const fn from_le_bytes(bytes: [u8; size_of::()]) -> Self { Self::from_le(Self::from_ne_bytes(bytes)) } @@ -3774,7 +3774,7 @@ macro_rules! int_impl { /// /// ``` #[doc = concat!("fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")] - #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")] + #[doc = concat!(" let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")] /// *input = rest; #[doc = concat!(" ", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())")] /// } @@ -3785,7 +3785,7 @@ macro_rules! int_impl { // SAFETY: const sound because integers are plain old datatypes so we can always // transmute to them #[inline] - pub const fn from_ne_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub const fn from_ne_bytes(bytes: [u8; size_of::()]) -> Self { // SAFETY: integers are plain old datatypes so we can always transmute to them unsafe { mem::transmute(bytes) } } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 80a38a6013dd..151e128cd78a 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1241,7 +1241,7 @@ impl usize { /// Returns an `usize` where every byte is equal to `x`. #[inline] pub(crate) const fn repeat_u8(x: u8) -> usize { - usize::from_ne_bytes([x; mem::size_of::()]) + usize::from_ne_bytes([x; size_of::()]) } /// Returns an `usize` where every byte pair is equal to `x`. @@ -1249,7 +1249,7 @@ impl usize { pub(crate) const fn repeat_u16(x: u16) -> usize { let mut r = 0usize; let mut i = 0; - while i < mem::size_of::() { + while i < size_of::() { // Use `wrapping_shl` to make it work on targets with 16-bit `usize` r = r.wrapping_shl(16) | (x as usize); i += 2; @@ -1330,7 +1330,7 @@ pub enum FpCategory { #[inline(always)] #[unstable(issue = "none", feature = "std_internals")] pub const fn can_not_overflow(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool { - radix <= 16 && digits.len() <= mem::size_of::() * 2 - is_signed_ty as usize + radix <= 16 && digits.len() <= size_of::() * 2 - is_signed_ty as usize } #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index a967b72c4fa9..6c9b366d9030 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -86,7 +86,7 @@ impl_zeroable_primitive!( /// For example, `Option>` is the same size as `u32`: /// /// ``` -/// use core::{mem::size_of, num::NonZero}; +/// use core::{num::NonZero}; /// /// assert_eq!(size_of::>>(), size_of::()); /// ``` @@ -102,7 +102,6 @@ impl_zeroable_primitive!( /// `Option>` are guaranteed to have the same size and alignment: /// /// ``` -/// # use std::mem::{size_of, align_of}; /// use std::num::NonZero; /// /// assert_eq!(size_of::>(), size_of::>>()); @@ -500,7 +499,6 @@ macro_rules! nonzero_integer { #[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")] /// /// ```rust - /// use std::mem::size_of; #[doc = concat!("assert_eq!(size_of::>(), size_of::<", stringify!($Int), ">());")] /// ``` /// @@ -516,7 +514,6 @@ macro_rules! nonzero_integer { /// are guaranteed to have the same size and alignment: /// /// ``` - /// # use std::mem::{size_of, align_of}; #[doc = concat!("use std::num::", stringify!($Ty), ";")] /// #[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::>());")] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 405c71121caa..d8709d51cccb 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2586,7 +2586,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline] pub const fn abs_diff(self, other: Self) -> Self { - if mem::size_of::() == 1 { + if size_of::() == 1 { // Trick LLVM into generating the psadbw instruction when SSE2 // is available and this function is autovectorized for u8's. (self as i32).wrapping_sub(other as i32).abs() as Self @@ -3465,7 +3465,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_be_bytes(self) -> [u8; mem::size_of::()] { + pub const fn to_be_bytes(self) -> [u8; size_of::()] { self.to_be().to_ne_bytes() } @@ -3485,7 +3485,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_le_bytes(self) -> [u8; mem::size_of::()] { + pub const fn to_le_bytes(self) -> [u8; size_of::()] { self.to_le().to_ne_bytes() } @@ -3521,7 +3521,7 @@ macro_rules! uint_impl { // SAFETY: const sound because integers are plain old datatypes so we can always // transmute them to arrays of bytes #[inline] - pub const fn to_ne_bytes(self) -> [u8; mem::size_of::()] { + pub const fn to_ne_bytes(self) -> [u8; size_of::()] { // SAFETY: integers are plain old datatypes so we can always transmute them to // arrays of bytes unsafe { mem::transmute(self) } @@ -3543,7 +3543,7 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")] - #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")] + #[doc = concat!(" let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")] /// *input = rest; #[doc = concat!(" ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())")] /// } @@ -3552,7 +3552,7 @@ macro_rules! uint_impl { #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[must_use] #[inline] - pub const fn from_be_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub const fn from_be_bytes(bytes: [u8; size_of::()]) -> Self { Self::from_be(Self::from_ne_bytes(bytes)) } @@ -3572,7 +3572,7 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")] - #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")] + #[doc = concat!(" let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")] /// *input = rest; #[doc = concat!(" ", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())")] /// } @@ -3581,7 +3581,7 @@ macro_rules! uint_impl { #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[must_use] #[inline] - pub const fn from_le_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub const fn from_le_bytes(bytes: [u8; size_of::()]) -> Self { Self::from_le(Self::from_ne_bytes(bytes)) } @@ -3612,7 +3612,7 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")] - #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")] + #[doc = concat!(" let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")] /// *input = rest; #[doc = concat!(" ", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())")] /// } @@ -3623,7 +3623,7 @@ macro_rules! uint_impl { // SAFETY: const sound because integers are plain old datatypes so we can always // transmute to them #[inline] - pub const fn from_ne_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub const fn from_ne_bytes(bytes: [u8; size_of::()]) -> Self { // SAFETY: integers are plain old datatypes so we can always transmute to them unsafe { mem::transmute(bytes) } } diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index bbf5939fe1b0..89c856fe1074 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -398,12 +398,12 @@ mod prim_never {} /// let v = vec!['h', 'e', 'l', 'l', 'o']; /// /// // five elements times four bytes for each element -/// assert_eq!(20, v.len() * std::mem::size_of::()); +/// assert_eq!(20, v.len() * size_of::()); /// /// let s = String::from("hello"); /// /// // five elements times one byte per element -/// assert_eq!(5, s.len() * std::mem::size_of::()); +/// assert_eq!(5, s.len() * size_of::()); /// ``` /// /// [`String`]: ../std/string/struct.String.html @@ -443,8 +443,8 @@ mod prim_never {} /// let s = String::from("love: ❤️"); /// let v: Vec = s.chars().collect(); /// -/// assert_eq!(12, std::mem::size_of_val(&s[..])); -/// assert_eq!(32, std::mem::size_of_val(&v[..])); +/// assert_eq!(12, size_of_val(&s[..])); +/// assert_eq!(32, size_of_val(&v[..])); /// ``` #[stable(feature = "rust1", since = "1.0.0")] mod prim_char {} @@ -594,10 +594,8 @@ impl () {} /// #[allow(unused_extern_crates)] /// extern crate libc; /// -/// use std::mem; -/// /// unsafe { -/// let my_num: *mut i32 = libc::malloc(mem::size_of::()) as *mut i32; +/// let my_num: *mut i32 = libc::malloc(size_of::()) as *mut i32; /// if my_num.is_null() { /// panic!("failed to allocate memory"); /// } @@ -893,11 +891,11 @@ mod prim_array {} /// /// ``` /// # use std::rc::Rc; -/// let pointer_size = std::mem::size_of::<&u8>(); -/// assert_eq!(2 * pointer_size, std::mem::size_of::<&[u8]>()); -/// assert_eq!(2 * pointer_size, std::mem::size_of::<*const [u8]>()); -/// assert_eq!(2 * pointer_size, std::mem::size_of::>()); -/// assert_eq!(2 * pointer_size, std::mem::size_of::>()); +/// let pointer_size = size_of::<&u8>(); +/// assert_eq!(2 * pointer_size, size_of::<&[u8]>()); +/// assert_eq!(2 * pointer_size, size_of::<*const [u8]>()); +/// assert_eq!(2 * pointer_size, size_of::>()); +/// assert_eq!(2 * pointer_size, size_of::>()); /// ``` /// /// ## Trait Implementations @@ -1692,15 +1690,13 @@ mod prim_ref {} /// This zero-sized type *coerces* to a regular function pointer. For example: /// /// ```rust -/// use std::mem; -/// /// fn bar(x: i32) {} /// /// let not_bar_ptr = bar; // `not_bar_ptr` is zero-sized, uniquely identifying `bar` -/// assert_eq!(mem::size_of_val(¬_bar_ptr), 0); +/// assert_eq!(size_of_val(¬_bar_ptr), 0); /// /// let bar_ptr: fn(i32) = not_bar_ptr; // force coercion to function pointer -/// assert_eq!(mem::size_of_val(&bar_ptr), mem::size_of::()); +/// assert_eq!(size_of_val(&bar_ptr), size_of::()); /// /// let footgun = &bar; // this is a shared reference to the zero-sized type identifying `bar` /// ``` diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 2da94e72566e..19311e39b454 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -13,8 +13,8 @@ use crate::{cmp, fmt, hash, mem, num}; pub struct Alignment(AlignmentEnum); // Alignment is `repr(usize)`, but via extra steps. -const _: () = assert!(mem::size_of::() == mem::size_of::()); -const _: () = assert!(mem::align_of::() == mem::align_of::()); +const _: () = assert!(size_of::() == size_of::()); +const _: () = assert!(align_of::() == align_of::()); fn _alignment_can_be_structurally_matched(a: Alignment) -> bool { matches!(a, Alignment::MIN) @@ -38,14 +38,14 @@ impl Alignment { /// Returns the alignment for a type. /// - /// This provides the same numerical value as [`mem::align_of`], + /// This provides the same numerical value as [`align_of`], /// but in an `Alignment` instead of a `usize`. #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] #[must_use] pub const fn of() -> Self { // This can't actually panic since type alignment is always a power of two. - const { Alignment::new(mem::align_of::()).unwrap() } + const { Alignment::new(align_of::()).unwrap() } } /// Creates an `Alignment` from a `usize`, or returns `None` if it's diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 8db620596dde..43306cfa674b 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1,7 +1,7 @@ use super::*; use crate::cmp::Ordering::{Equal, Greater, Less}; use crate::intrinsics::const_eval_select; -use crate::mem::SizedTypeProperties; +use crate::mem::{self, SizedTypeProperties}; use crate::slice::{self, SliceIndex}; impl *const T { @@ -595,9 +595,9 @@ impl *const T { } /// Calculates the distance between two pointers within the same allocation. The returned value is in - /// units of T: the distance in bytes divided by `mem::size_of::()`. + /// units of T: the distance in bytes divided by `size_of::()`. /// - /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, + /// This is equivalent to `(self as isize - origin as isize) / (size_of::() as isize)`, /// except that it has a lot more opportunities for UB, in exchange for the compiler /// better understanding what you are doing. /// @@ -633,7 +633,7 @@ impl *const T { /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - - /// origin as isize) / mem::size_of::()`. + /// origin as isize) / size_of::()`. // FIXME: recommend `addr()` instead of `as usize` once that is stable. /// /// [`add`]: #method.add @@ -683,7 +683,7 @@ impl *const T { where T: Sized, { - let pointee_size = mem::size_of::(); + let pointee_size = size_of::(); assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); // SAFETY: the caller must uphold the safety contract for `ptr_offset_from`. unsafe { intrinsics::ptr_offset_from(self, origin) } @@ -709,7 +709,7 @@ impl *const T { /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in - /// units of T: the distance in bytes is divided by `mem::size_of::()`. + /// units of T: the distance in bytes is divided by `size_of::()`. /// /// This computes the same value that [`offset_from`](#method.offset_from) /// would compute, but with the added precondition that the offset is @@ -793,7 +793,7 @@ impl *const T { ) => runtime_ptr_ge(this, origin) ); - let pointee_size = mem::size_of::(); + let pointee_size = size_of::(); assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); // SAFETY: the caller must uphold the safety contract for `ptr_offset_from_unsigned`. unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } @@ -1375,8 +1375,6 @@ impl *const T { /// Accessing adjacent `u8` as `u16` /// /// ``` - /// use std::mem::align_of; - /// /// # unsafe { /// let x = [5_u8, 6, 7, 8, 9]; /// let ptr = x.as_ptr(); @@ -1436,7 +1434,7 @@ impl *const T { where T: Sized, { - self.is_aligned_to(mem::align_of::()) + self.is_aligned_to(align_of::()) } /// Returns whether the pointer is aligned to `align`. @@ -1595,7 +1593,7 @@ impl *const [T] { /// When calling this method, you have to ensure that *either* the pointer is null *or* /// all of the following is true: /// - /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::()` many bytes, + /// * The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// /// * The entire memory range of this slice must be contained within a single [allocated object]! @@ -1607,7 +1605,7 @@ impl *const [T] { /// them from other data. You can obtain a pointer that is usable as `data` /// for zero-length slices using [`NonNull::dangling()`]. /// - /// * The total size `ptr.len() * mem::size_of::()` of the slice must be no larger than `isize::MAX`. + /// * The total size `ptr.len() * size_of::()` of the slice must be no larger than `isize::MAX`. /// See the safety documentation of [`pointer::offset`]. /// /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 9eee29d485f4..487075063895 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -74,7 +74,7 @@ pub trait Pointee { /// #![feature(ptr_metadata)] /// /// fn this_never_panics() { -/// assert_eq!(std::mem::size_of::<&T>(), std::mem::size_of::()) +/// assert_eq!(size_of::<&T>(), size_of::()) /// } /// ``` #[unstable(feature = "ptr_metadata", issue = "81513")] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index eb99be817a2c..ea53da78d3bd 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -48,7 +48,7 @@ //! //! Valid raw pointers as defined above are not necessarily properly aligned (where //! "proper" alignment is defined by the pointee type, i.e., `*const T` must be -//! aligned to `mem::align_of::()`). However, most functions require their +//! aligned to `align_of::()`). However, most functions require their //! arguments to be properly aligned, and will explicitly state //! this requirement in their documentation. Notable exceptions to this are //! [`read_unaligned`] and [`write_unaligned`]. @@ -297,7 +297,7 @@ //! //! // Our value, which must have enough alignment to have spare least-significant-bits. //! let my_precious_data: u32 = 17; -//! assert!(core::mem::align_of::() > 1); +//! assert!(align_of::() > 1); //! //! // Create a tagged pointer //! let ptr = &my_precious_data as *const u32; @@ -1098,12 +1098,12 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { } else { macro_rules! attempt_swap_as_chunks { ($ChunkTy:ty) => { - if mem::align_of::() >= mem::align_of::<$ChunkTy>() - && mem::size_of::() % mem::size_of::<$ChunkTy>() == 0 + if align_of::() >= align_of::<$ChunkTy>() + && size_of::() % size_of::<$ChunkTy>() == 0 { let x: *mut $ChunkTy = x.cast(); let y: *mut $ChunkTy = y.cast(); - let count = count * (mem::size_of::() / mem::size_of::<$ChunkTy>()); + let count = count * (size_of::() / size_of::<$ChunkTy>()); // SAFETY: these are the same bytes that the caller promised were // ok, just typed as `MaybeUninit`s instead of as `T`s. // The `if` condition above ensures that we're not violating @@ -1117,9 +1117,9 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { // Split up the slice into small power-of-two-sized chunks that LLVM is able // to vectorize (unless it's a special type with more-than-pointer alignment, // because we don't want to pessimize things like slices of SIMD vectors.) - if mem::align_of::() <= mem::size_of::() - && (!mem::size_of::().is_power_of_two() - || mem::size_of::() > mem::size_of::() * 2) + if align_of::() <= size_of::() + && (!size_of::().is_power_of_two() + || size_of::() > size_of::() * 2) { attempt_swap_as_chunks!(usize); attempt_swap_as_chunks!(u8); @@ -1443,10 +1443,8 @@ pub const unsafe fn read(src: *const T) -> T { /// Read a `usize` value from a byte buffer: /// /// ``` -/// use std::mem; -/// /// fn read_usize(x: &[u8]) -> usize { -/// assert!(x.len() >= mem::size_of::()); +/// assert!(x.len() >= size_of::()); /// /// let ptr = x.as_ptr() as *const usize; /// @@ -1467,7 +1465,7 @@ pub const unsafe fn read_unaligned(src: *const T) -> T { // Also, since we just wrote a valid value into `tmp`, it is guaranteed // to be properly initialized. unsafe { - copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::()); + copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, size_of::()); tmp.assume_init() } } @@ -1647,10 +1645,8 @@ pub const unsafe fn write(dst: *mut T, src: T) { /// Write a `usize` value to a byte buffer: /// /// ``` -/// use std::mem; -/// /// fn write_usize(x: &mut [u8], val: usize) { -/// assert!(x.len() >= mem::size_of::()); +/// assert!(x.len() >= size_of::()); /// /// let ptr = x.as_mut_ptr() as *mut usize; /// @@ -1667,7 +1663,7 @@ pub const unsafe fn write_unaligned(dst: *mut T, src: T) { // `dst` cannot overlap `src` because the caller has mutable access // to `dst` while `src` is owned by this function. unsafe { - copy_nonoverlapping((&raw const src) as *const u8, dst as *mut u8, mem::size_of::()); + copy_nonoverlapping((&raw const src) as *const u8, dst as *mut u8, size_of::()); // We are calling the intrinsic directly to avoid function calls in the generated code. intrinsics::forget(src); } @@ -1911,7 +1907,7 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { inverse & m_minus_one } - let stride = mem::size_of::(); + let stride = size_of::(); let addr: usize = p.addr(); diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 5a64f12ca99f..26aaac476027 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1,7 +1,7 @@ use super::*; use crate::cmp::Ordering::{Equal, Greater, Less}; use crate::intrinsics::const_eval_select; -use crate::mem::SizedTypeProperties; +use crate::mem::{self, SizedTypeProperties}; use crate::slice::{self, SliceIndex}; impl *mut T { @@ -769,9 +769,9 @@ impl *mut T { } /// Calculates the distance between two pointers within the same allocation. The returned value is in - /// units of T: the distance in bytes divided by `mem::size_of::()`. + /// units of T: the distance in bytes divided by `size_of::()`. /// - /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, + /// This is equivalent to `(self as isize - origin as isize) / (size_of::() as isize)`, /// except that it has a lot more opportunities for UB, in exchange for the compiler /// better understanding what you are doing. /// @@ -807,7 +807,7 @@ impl *mut T { /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - - /// origin as isize) / mem::size_of::()`. + /// origin as isize) / size_of::()`. // FIXME: recommend `addr()` instead of `as usize` once that is stable. /// /// [`add`]: #method.add @@ -881,7 +881,7 @@ impl *mut T { /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in - /// units of T: the distance in bytes is divided by `mem::size_of::()`. + /// units of T: the distance in bytes is divided by `size_of::()`. /// /// This computes the same value that [`offset_from`](#method.offset_from) /// would compute, but with the added precondition that the offset is @@ -1623,8 +1623,6 @@ impl *mut T { /// Accessing adjacent `u8` as `u16` /// /// ``` - /// use std::mem::align_of; - /// /// # unsafe { /// let mut x = [5_u8, 6, 7, 8, 9]; /// let ptr = x.as_mut_ptr(); @@ -1689,7 +1687,7 @@ impl *mut T { where T: Sized, { - self.is_aligned_to(mem::align_of::()) + self.is_aligned_to(align_of::()) } /// Returns whether the pointer is aligned to `align`. @@ -1950,7 +1948,7 @@ impl *mut [T] { /// When calling this method, you have to ensure that *either* the pointer is null *or* /// all of the following is true: /// - /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::()` many bytes, + /// * The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// /// * The entire memory range of this slice must be contained within a single [allocated object]! @@ -1962,7 +1960,7 @@ impl *mut [T] { /// them from other data. You can obtain a pointer that is usable as `data` /// for zero-length slices using [`NonNull::dangling()`]. /// - /// * The total size `ptr.len() * mem::size_of::()` of the slice must be no larger than `isize::MAX`. + /// * The total size `ptr.len() * size_of::()` of the slice must be no larger than `isize::MAX`. /// See the safety documentation of [`pointer::offset`]. /// /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is @@ -2008,7 +2006,7 @@ impl *mut [T] { /// When calling this method, you have to ensure that *either* the pointer is null *or* /// all of the following is true: /// - /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::()` + /// * The pointer must be [valid] for reads and writes for `ptr.len() * size_of::()` /// many bytes, and it must be properly aligned. This means in particular: /// /// * The entire memory range of this slice must be contained within a single [allocated object]! @@ -2020,7 +2018,7 @@ impl *mut [T] { /// them from other data. You can obtain a pointer that is usable as `data` /// for zero-length slices using [`NonNull::dangling()`]. /// - /// * The total size `ptr.len() * mem::size_of::()` of the slice must be no larger than `isize::MAX`. + /// * The total size `ptr.len() * size_of::()` of the slice must be no larger than `isize::MAX`. /// See the safety documentation of [`pointer::offset`]. /// /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 7abd3ddaa9ef..7c567d522c55 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -49,7 +49,6 @@ use crate::{fmt, hash, intrinsics, mem, ptr}; /// are guaranteed to have the same size and alignment: /// /// ``` -/// # use std::mem::{size_of, align_of}; /// use std::ptr::NonNull; /// /// assert_eq!(size_of::>(), size_of::>>()); @@ -724,9 +723,9 @@ impl NonNull { } /// Calculates the distance between two pointers within the same allocation. The returned value is in - /// units of T: the distance in bytes divided by `mem::size_of::()`. + /// units of T: the distance in bytes divided by `size_of::()`. /// - /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, + /// This is equivalent to `(self as isize - origin as isize) / (size_of::() as isize)`, /// except that it has a lot more opportunities for UB, in exchange for the compiler /// better understanding what you are doing. /// @@ -762,7 +761,7 @@ impl NonNull { /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - - /// origin as isize) / mem::size_of::()`. + /// origin as isize) / size_of::()`. // FIXME: recommend `addr()` instead of `as usize` once that is stable. /// /// [`add`]: #method.add @@ -842,7 +841,7 @@ impl NonNull { /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in - /// units of T: the distance in bytes is divided by `mem::size_of::()`. + /// units of T: the distance in bytes is divided by `size_of::()`. /// /// This computes the same value that [`offset_from`](#method.offset_from) /// would compute, but with the added precondition that the offset is @@ -1223,7 +1222,6 @@ impl NonNull { /// Accessing adjacent `u8` as `u16` /// /// ``` - /// use std::mem::align_of; /// use std::ptr::NonNull; /// /// # unsafe { @@ -1443,7 +1441,7 @@ impl NonNull<[T]> { /// /// When calling this method, you have to ensure that all of the following is true: /// - /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::()` many bytes, + /// * The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// /// * The entire memory range of this slice must be contained within a single allocated object! @@ -1455,7 +1453,7 @@ impl NonNull<[T]> { /// them from other data. You can obtain a pointer that is usable as `data` /// for zero-length slices using [`NonNull::dangling()`]. /// - /// * The total size `ptr.len() * mem::size_of::()` of the slice must be no larger than `isize::MAX`. + /// * The total size `ptr.len() * size_of::()` of the slice must be no larger than `isize::MAX`. /// See the safety documentation of [`pointer::offset`]. /// /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is @@ -1488,7 +1486,7 @@ impl NonNull<[T]> { /// /// When calling this method, you have to ensure that all of the following is true: /// - /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::()` + /// * The pointer must be [valid] for reads and writes for `ptr.len() * size_of::()` /// many bytes, and it must be properly aligned. This means in particular: /// /// * The entire memory range of this slice must be contained within a single allocated object! @@ -1500,7 +1498,7 @@ impl NonNull<[T]> { /// them from other data. You can obtain a pointer that is usable as `data` /// for zero-length slices using [`NonNull::dangling()`]. /// - /// * The total size `ptr.len() * mem::size_of::()` of the slice must be no larger than `isize::MAX`. + /// * The total size `ptr.len() * size_of::()` of the slice must be no larger than `isize::MAX`. /// See the safety documentation of [`pointer::offset`]. /// /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 9cb00644e644..804bdfcbb4fc 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -1,10 +1,10 @@ //! Comparison traits for `[T]`. use super::{from_raw_parts, memchr}; +use crate::ascii; use crate::cmp::{self, BytewiseEq, Ordering}; use crate::intrinsics::compare_bytes; use crate::num::NonZero; -use crate::{ascii, mem}; #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq<[U]> for [T] @@ -87,7 +87,7 @@ where // SAFETY: `self` and `other` are references and are thus guaranteed to be valid. // The two slices have been checked to have the same size above. unsafe { - let size = mem::size_of_val(self); + let size = size_of_val(self); compare_bytes(self.as_ptr() as *const u8, other.as_ptr() as *const u8, size) == 0 } } @@ -266,7 +266,7 @@ macro_rules! impl_slice_contains { fn slice_contains(&self, arr: &[$t]) -> bool { // Make our LANE_COUNT 4x the normal lane count (aiming for 128 bit vectors). // The compiler will nicely unroll it. - const LANE_COUNT: usize = 4 * (128 / (mem::size_of::<$t>() * 8)); + const LANE_COUNT: usize = 4 * (128 / (size_of::<$t>() * 8)); // SIMD let mut chunks = arr.chunks_exact(LANE_COUNT); for chunk in &mut chunks { diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 98db7aaf5332..1e1053583a61 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -2,11 +2,10 @@ // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch use crate::intrinsics::const_eval_select; -use crate::mem; const LO_USIZE: usize = usize::repeat_u8(0x01); const HI_USIZE: usize = usize::repeat_u8(0x80); -const USIZE_BYTES: usize = mem::size_of::(); +const USIZE_BYTES: usize = size_of::(); /// Returns `true` if `x` contains any zero byte. /// @@ -138,7 +137,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { // offset is always aligned, so just testing `>` is sufficient and avoids possible // overflow. let repeated_x = usize::repeat_u8(x); - let chunk_bytes = mem::size_of::(); + let chunk_bytes = size_of::(); while offset > min_aligned_offset { // SAFETY: offset starts at len - suffix.len(), as long as it is greater than diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 7a2764206e8d..c79ae2c1915d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3894,9 +3894,9 @@ impl [T] { // Explicitly wrap the function call in a const block so it gets // constant-evaluated even in debug mode. - let gcd: usize = const { gcd(mem::size_of::(), mem::size_of::()) }; - let ts: usize = mem::size_of::() / gcd; - let us: usize = mem::size_of::() / gcd; + let gcd: usize = const { gcd(size_of::(), size_of::()) }; + let ts: usize = size_of::() / gcd; + let us: usize = size_of::() / gcd; // Armed with this knowledge, we can find how many `U`s we can fit! let us_len = self.len() / ts * us; @@ -3946,7 +3946,7 @@ impl [T] { // ptr.align_offset. let ptr = self.as_ptr(); // SAFETY: See the `align_to_mut` method for the detailed safety comment. - let offset = unsafe { crate::ptr::align_offset(ptr, mem::align_of::()) }; + let offset = unsafe { crate::ptr::align_offset(ptr, align_of::()) }; if offset > self.len() { (self, &[], &[]) } else { @@ -3956,7 +3956,7 @@ impl [T] { #[cfg(miri)] crate::intrinsics::miri_promise_symbolic_alignment( rest.as_ptr().cast(), - mem::align_of::(), + align_of::(), ); // SAFETY: now `rest` is definitely aligned, so `from_raw_parts` below is okay, // since the caller guarantees that we can transmute `T` to `U` safely. @@ -4017,7 +4017,7 @@ impl [T] { // valid pointer `ptr` (it comes from a reference to `self`) and with // a size that is a power of two (since it comes from the alignment for U), // satisfying its safety constraints. - let offset = unsafe { crate::ptr::align_offset(ptr, mem::align_of::()) }; + let offset = unsafe { crate::ptr::align_offset(ptr, align_of::()) }; if offset > self.len() { (self, &mut [], &mut []) } else { @@ -4029,7 +4029,7 @@ impl [T] { #[cfg(miri)] crate::intrinsics::miri_promise_symbolic_alignment( mut_ptr.cast() as *const (), - mem::align_of::(), + align_of::(), ); // We can't use `rest` again after this, that would invalidate its alias `mut_ptr`! // SAFETY: see comments for `align_to`. @@ -4100,7 +4100,7 @@ impl [T] { // These are expected to always match, as vector types are laid out like // arrays per , but we // might as well double-check since it'll optimize away anyhow. - assert_eq!(mem::size_of::>(), mem::size_of::<[T; LANES]>()); + assert_eq!(size_of::>(), size_of::<[T; LANES]>()); // SAFETY: The simd types have the same layout as arrays, just with // potentially-higher alignment, so the de-facto transmutes are sound. @@ -4136,7 +4136,7 @@ impl [T] { // These are expected to always match, as vector types are laid out like // arrays per , but we // might as well double-check since it'll optimize away anyhow. - assert_eq!(mem::size_of::>(), mem::size_of::<[T; LANES]>()); + assert_eq!(size_of::>(), size_of::<[T; LANES]>()); // SAFETY: The simd types have the same layout as arrays, just with // potentially-higher alignment, so the de-facto transmutes are sound. @@ -4721,11 +4721,11 @@ impl [T] { let byte_offset = elem_start.wrapping_sub(self_start); - if byte_offset % mem::size_of::() != 0 { + if byte_offset % size_of::() != 0 { return None; } - let offset = byte_offset / mem::size_of::(); + let offset = byte_offset / size_of::(); if offset < self.len() { Some(offset) } else { None } } @@ -4775,11 +4775,11 @@ impl [T] { let byte_start = subslice_start.wrapping_sub(self_start); - if byte_start % core::mem::size_of::() != 0 { + if byte_start % size_of::() != 0 { return None; } - let start = byte_start / core::mem::size_of::(); + let start = byte_start / size_of::(); let end = start.wrapping_add(subslice.len()); if start <= self.len() && end <= self.len() { Some(start..end) } else { None } diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index e24b52cff82e..3582c7e8b3f3 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -11,7 +11,7 @@ use crate::{array, ptr, ub_checks}; /// /// Behavior is undefined if any of the following conditions are violated: /// -/// * `data` must be non-null, [valid] for reads for `len * mem::size_of::()` many bytes, +/// * `data` must be non-null, [valid] for reads for `len * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// /// * The entire memory range of this slice must be contained within a single allocated object! @@ -28,7 +28,7 @@ use crate::{array, ptr, ub_checks}; /// * The memory referenced by the returned slice must not be mutated for the duration /// of lifetime `'a`, except inside an `UnsafeCell`. /// -/// * The total size `len * mem::size_of::()` of the slice must be no larger than `isize::MAX`, +/// * The total size `len * size_of::()` of the slice must be no larger than `isize::MAX`, /// and adding that size to `data` must not "wrap around" the address space. /// See the safety documentation of [`pointer::offset`]. /// @@ -146,7 +146,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] /// /// Behavior is undefined if any of the following conditions are violated: /// -/// * `data` must be non-null, [valid] for both reads and writes for `len * mem::size_of::()` many bytes, +/// * `data` must be non-null, [valid] for both reads and writes for `len * size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// /// * The entire memory range of this slice must be contained within a single allocated object! @@ -163,7 +163,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] /// (not derived from the return value) for the duration of lifetime `'a`. /// Both read and write accesses are forbidden. /// -/// * The total size `len * mem::size_of::()` of the slice must be no larger than `isize::MAX`, +/// * The total size `len * size_of::()` of the slice must be no larger than `isize::MAX`, /// and adding that size to `data` must not "wrap around" the address space. /// See the safety documentation of [`pointer::offset`]. /// diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs index 5d5ee4c7b624..80178f297eaa 100644 --- a/library/core/src/slice/rotate.rs +++ b/library/core/src/slice/rotate.rs @@ -1,4 +1,4 @@ -use crate::mem::{self, MaybeUninit, SizedTypeProperties}; +use crate::mem::{MaybeUninit, SizedTypeProperties}; use crate::{cmp, ptr}; type BufType = [usize; 32]; @@ -21,12 +21,12 @@ pub(super) unsafe fn ptr_rotate(left: usize, mid: *mut T, right: usize) { } // `T` is not a zero-sized type, so it's okay to divide by its size. if !cfg!(feature = "optimize_for_size") - && cmp::min(left, right) <= mem::size_of::() / mem::size_of::() + && cmp::min(left, right) <= size_of::() / size_of::() { // SAFETY: guaranteed by the caller unsafe { ptr_rotate_memmove(left, mid, right) }; } else if !cfg!(feature = "optimize_for_size") - && ((left + right < 24) || (mem::size_of::() > mem::size_of::<[usize; 4]>())) + && ((left + right < 24) || (size_of::() > size_of::<[usize; 4]>())) { // SAFETY: guaranteed by the caller unsafe { ptr_rotate_gcd(left, mid, right) } diff --git a/library/core/src/slice/sort/shared/smallsort.rs b/library/core/src/slice/sort/shared/smallsort.rs index f6dcf42ba603..95f196a40d01 100644 --- a/library/core/src/slice/sort/shared/smallsort.rs +++ b/library/core/src/slice/sort/shared/smallsort.rs @@ -113,7 +113,7 @@ pub(crate) trait UnstableSmallSortFreezeTypeImpl: Sized + FreezeMarker { impl UnstableSmallSortFreezeTypeImpl for T { #[inline(always)] default fn small_sort_threshold() -> usize { - if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { + if (size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { SMALL_SORT_GENERAL_THRESHOLD } else { SMALL_SORT_FALLBACK_THRESHOLD @@ -125,7 +125,7 @@ impl UnstableSmallSortFreezeTypeImpl for T { where F: FnMut(&T, &T) -> bool, { - if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { + if (size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { small_sort_general(v, is_less); } else { small_sort_fallback(v, is_less); @@ -143,10 +143,10 @@ impl UnstableSmallSortFreezeTypeImpl for T { #[inline(always)] fn small_sort_threshold() -> usize { if has_efficient_in_place_swap::() - && (mem::size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE + && (size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { SMALL_SORT_NETWORK_THRESHOLD - } else if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { + } else if (size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { SMALL_SORT_GENERAL_THRESHOLD } else { SMALL_SORT_FALLBACK_THRESHOLD @@ -159,10 +159,10 @@ impl UnstableSmallSortFreezeTypeImpl for T { F: FnMut(&T, &T) -> bool, { if has_efficient_in_place_swap::() - && (mem::size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE + && (size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { small_sort_network(v, is_less); - } else if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { + } else if (size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { small_sort_general(v, is_less); } else { small_sort_fallback(v, is_less); @@ -238,7 +238,7 @@ fn small_sort_general_with_scratch bool>( unsafe { let scratch_base = scratch.as_mut_ptr() as *mut T; - let presorted_len = if const { mem::size_of::() <= 16 } && len >= 16 { + let presorted_len = if const { size_of::() <= 16 } && len >= 16 { // SAFETY: scratch_base is valid and has enough space. sort8_stable(v_base, scratch_base, scratch_base.add(len), is_less); sort8_stable( @@ -863,5 +863,5 @@ fn panic_on_ord_violation() -> ! { #[must_use] pub(crate) const fn has_efficient_in_place_swap() -> bool { // Heuristic that holds true on all tested 64-bit capable architectures. - mem::size_of::() <= 8 // mem::size_of::() + size_of::() <= 8 // size_of::() } diff --git a/library/core/src/slice/sort/stable/mod.rs b/library/core/src/slice/sort/stable/mod.rs index 3ff2e71fd05b..090367cdabad 100644 --- a/library/core/src/slice/sort/stable/mod.rs +++ b/library/core/src/slice/sort/stable/mod.rs @@ -3,7 +3,7 @@ #[cfg(not(any(feature = "optimize_for_size", target_pointer_width = "16")))] use crate::cmp; use crate::intrinsics; -use crate::mem::{self, MaybeUninit, SizedTypeProperties}; +use crate::mem::{MaybeUninit, SizedTypeProperties}; #[cfg(not(any(feature = "optimize_for_size", target_pointer_width = "16")))] use crate::slice::sort::shared::smallsort::{ SMALL_SORT_GENERAL_SCRATCH_LEN, StableSmallSortTypeImpl, insertion_sort_shift_left, @@ -107,7 +107,7 @@ fn driftsort_main bool, BufT: BufGuard>(v: &mut [T], i // If min_good_run_len is ever modified, this code must be updated to allocate // the correct scratch size for it. const MAX_FULL_ALLOC_BYTES: usize = 8_000_000; // 8MB - let max_full_alloc = MAX_FULL_ALLOC_BYTES / mem::size_of::(); + let max_full_alloc = MAX_FULL_ALLOC_BYTES / size_of::(); let len = v.len(); let alloc_len = cmp::max( cmp::max(len - len / 2, cmp::min(len, max_full_alloc)), @@ -155,7 +155,7 @@ impl AlignedStorage { } fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit] { - let len = N / mem::size_of::(); + let len = N / size_of::(); // SAFETY: `_align` ensures we are correctly aligned. unsafe { core::slice::from_raw_parts_mut(self.storage.as_mut_ptr().cast(), len) } diff --git a/library/core/src/slice/sort/stable/quicksort.rs b/library/core/src/slice/sort/stable/quicksort.rs index 630c6ff90770..3c9688790c40 100644 --- a/library/core/src/slice/sort/stable/quicksort.rs +++ b/library/core/src/slice/sort/stable/quicksort.rs @@ -1,6 +1,6 @@ //! This module contains a stable quicksort and partition implementation. -use crate::mem::{self, ManuallyDrop, MaybeUninit}; +use crate::mem::{ManuallyDrop, MaybeUninit}; use crate::slice::sort::shared::FreezeMarker; use crate::slice::sort::shared::pivot::choose_pivot; use crate::slice::sort::shared::smallsort::StableSmallSortTypeImpl; @@ -126,7 +126,7 @@ fn stable_partition bool>( // this gave significant performance boosts in benchmarks. Unrolling // through for _ in 0..UNROLL_LEN { .. } instead of manually improves // compile times but has a ~10-20% performance penalty on opt-level=s. - if const { mem::size_of::() <= 16 } { + if const { size_of::() <= 16 } { const UNROLL_LEN: usize = 4; let unroll_end = v_base.add(loop_end_pos.saturating_sub(UNROLL_LEN - 1)); while state.scan < unroll_end { diff --git a/library/core/src/slice/sort/unstable/quicksort.rs b/library/core/src/slice/sort/unstable/quicksort.rs index bb9f90fc881a..68a161187169 100644 --- a/library/core/src/slice/sort/unstable/quicksort.rs +++ b/library/core/src/slice/sort/unstable/quicksort.rs @@ -1,6 +1,8 @@ //! This module contains an unstable quicksort and two partition implementations. -use crate::mem::{self, ManuallyDrop}; +#[cfg(not(feature = "optimize_for_size"))] +use crate::mem; +use crate::mem::ManuallyDrop; #[cfg(not(feature = "optimize_for_size"))] use crate::slice::sort::shared::pivot::choose_pivot; #[cfg(not(feature = "optimize_for_size"))] @@ -137,7 +139,7 @@ where const fn inst_partition bool>() -> fn(&mut [T], &T, &mut F) -> usize { const MAX_BRANCHLESS_PARTITION_SIZE: usize = 96; - if mem::size_of::() <= MAX_BRANCHLESS_PARTITION_SIZE { + if size_of::() <= MAX_BRANCHLESS_PARTITION_SIZE { // Specialize for types that are relatively cheap to copy, where branchless optimizations // have large leverage e.g. `u64` and `String`. cfg_if! { @@ -304,7 +306,7 @@ where // Manual unrolling that works well on x86, Arm and with opt-level=s without murdering // compile-times. Leaving this to the compiler yields ok to bad results. - let unroll_len = const { if mem::size_of::() <= 16 { 2 } else { 1 } }; + let unroll_len = const { if size_of::() <= 16 { 2 } else { 1 } }; let unroll_end = v_base.add(len - (unroll_len - 1)); while state.right < unroll_end { diff --git a/library/core/src/str/count.rs b/library/core/src/str/count.rs index b5d7aaf05d4b..452403b23dee 100644 --- a/library/core/src/str/count.rs +++ b/library/core/src/str/count.rs @@ -20,7 +20,7 @@ use core::intrinsics::unlikely; -const USIZE_SIZE: usize = core::mem::size_of::(); +const USIZE_SIZE: usize = size_of::(); const UNROLL_INNER: usize = 4; #[inline] diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs index 0f724dd96132..8174e4ff97df 100644 --- a/library/core/src/str/validations.rs +++ b/library/core/src/str/validations.rs @@ -2,7 +2,6 @@ use super::Utf8Error; use crate::intrinsics::const_eval_select; -use crate::mem; /// Returns the initial codepoint accumulator for the first byte. /// The first byte is special, only want bottom 5 bits for width 2, 4 bits @@ -128,7 +127,7 @@ pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { let mut index = 0; let len = v.len(); - const USIZE_BYTES: usize = mem::size_of::(); + const USIZE_BYTES: usize = size_of::(); let ascii_block_size = 2 * USIZE_BYTES; let blocks_end = if len >= ascii_block_size { len - ascii_block_size + 1 } else { 0 }; diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 73180bde54aa..bac92ef94e71 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -2033,7 +2033,7 @@ impl AtomicPtr { #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T { - self.fetch_byte_add(val.wrapping_mul(core::mem::size_of::()), order) + self.fetch_byte_add(val.wrapping_mul(size_of::()), order) } /// Offsets the pointer's address by subtracting `val` (in units of `T`), @@ -2078,7 +2078,7 @@ impl AtomicPtr { #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T { - self.fetch_byte_sub(val.wrapping_mul(core::mem::size_of::()), order) + self.fetch_byte_sub(val.wrapping_mul(size_of::()), order) } /// Offsets the pointer's address by adding `val` *bytes*, returning the diff --git a/library/coretests/benches/ascii/is_ascii.rs b/library/coretests/benches/ascii/is_ascii.rs index ced7084fb0e4..a6c718409ee8 100644 --- a/library/coretests/benches/ascii/is_ascii.rs +++ b/library/coretests/benches/ascii/is_ascii.rs @@ -95,7 +95,7 @@ benches! { // These are separate since it's easier to debug errors if they don't go through // macro expansion first. fn is_ascii_align_to(bytes: &[u8]) -> bool { - if bytes.len() < core::mem::size_of::() { + if bytes.len() < size_of::() { return bytes.iter().all(|b| b.is_ascii()); } // SAFETY: transmuting a sequence of `u8` to `usize` is always fine @@ -106,7 +106,7 @@ fn is_ascii_align_to(bytes: &[u8]) -> bool { } fn is_ascii_align_to_unrolled(bytes: &[u8]) -> bool { - if bytes.len() < core::mem::size_of::() { + if bytes.len() < size_of::() { return bytes.iter().all(|b| b.is_ascii()); } // SAFETY: transmuting a sequence of `u8` to `[usize; 2]` is always fine @@ -118,6 +118,6 @@ fn is_ascii_align_to_unrolled(bytes: &[u8]) -> bool { #[inline] fn contains_nonascii(v: usize) -> bool { - const NONASCII_MASK: usize = usize::from_ne_bytes([0x80; core::mem::size_of::()]); + const NONASCII_MASK: usize = usize::from_ne_bytes([0x80; size_of::()]); (NONASCII_MASK & v) != 0 } diff --git a/library/coretests/benches/iter.rs b/library/coretests/benches/iter.rs index e14f26b72903..e49d152eb539 100644 --- a/library/coretests/benches/iter.rs +++ b/library/coretests/benches/iter.rs @@ -1,6 +1,5 @@ use core::borrow::Borrow; use core::iter::*; -use core::mem; use core::num::Wrapping; use core::ops::Range; @@ -477,7 +476,7 @@ fn bench_next_chunk_copied(b: &mut Bencher) { let mut iter = black_box(&v).iter().copied(); let mut acc = Wrapping(0); // This uses a while-let loop to side-step the TRA specialization in ArrayChunks - while let Ok(chunk) = iter.next_chunk::<{ mem::size_of::() }>() { + while let Ok(chunk) = iter.next_chunk::<{ size_of::() }>() { let d = u64::from_ne_bytes(chunk); acc += Wrapping(d.rotate_left(7).wrapping_add(1)); } @@ -496,7 +495,7 @@ fn bench_next_chunk_trusted_random_access(b: &mut Bencher) { .iter() // this shows that we're not relying on the slice::Iter specialization in Copied .map(|b| *b.borrow()) - .array_chunks::<{ mem::size_of::() }>() + .array_chunks::<{ size_of::() }>() .map(|ary| { let d = u64::from_ne_bytes(ary); Wrapping(d.rotate_left(7).wrapping_add(1)) diff --git a/library/coretests/tests/alloc.rs b/library/coretests/tests/alloc.rs index b88f1821cd77..72fdf82c1f8c 100644 --- a/library/coretests/tests/alloc.rs +++ b/library/coretests/tests/alloc.rs @@ -1,5 +1,4 @@ use core::alloc::Layout; -use core::mem::size_of; use core::ptr::{self, NonNull}; #[test] diff --git a/library/coretests/tests/atomic.rs b/library/coretests/tests/atomic.rs index 0ffba538b207..e0c0fe4790c0 100644 --- a/library/coretests/tests/atomic.rs +++ b/library/coretests/tests/atomic.rs @@ -250,8 +250,6 @@ fn atomic_access_bool() { #[test] fn atomic_alignment() { - use std::mem::{align_of, size_of}; - #[cfg(target_has_atomic = "8")] assert_eq!(align_of::(), size_of::()); #[cfg(target_has_atomic = "ptr")] diff --git a/library/coretests/tests/hash/sip.rs b/library/coretests/tests/hash/sip.rs index f79954f916b7..6add1a33cb93 100644 --- a/library/coretests/tests/hash/sip.rs +++ b/library/coretests/tests/hash/sip.rs @@ -1,7 +1,7 @@ #![allow(deprecated)] use core::hash::{Hash, Hasher, SipHasher, SipHasher13}; -use core::{mem, slice}; +use core::slice; // Hash just the bytes of the slice, without length prefix struct Bytes<'a>(&'a [u8]); @@ -314,7 +314,7 @@ fn test_write_short_works() { h1.write_u8(0x01u8); let mut h2 = SipHasher::new(); h2.write(unsafe { - slice::from_raw_parts(&test_usize as *const _ as *const u8, mem::size_of::()) + slice::from_raw_parts(&test_usize as *const _ as *const u8, size_of::()) }); h2.write(b"bytes"); h2.write(b"string"); diff --git a/library/coretests/tests/nonzero.rs b/library/coretests/tests/nonzero.rs index bdc5701d9fd2..00232c9b7061 100644 --- a/library/coretests/tests/nonzero.rs +++ b/library/coretests/tests/nonzero.rs @@ -1,6 +1,5 @@ use core::num::{IntErrorKind, NonZero}; use core::option::Option::None; -use std::mem::size_of; #[test] fn test_create_nonzero_instance() { diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs index 0c9f9b338b0c..370349c879e0 100644 --- a/library/coretests/tests/ptr.rs +++ b/library/coretests/tests/ptr.rs @@ -1,6 +1,6 @@ use core::cell::RefCell; use core::marker::Freeze; -use core::mem::{self, MaybeUninit}; +use core::mem::MaybeUninit; use core::num::NonZero; use core::ptr; use core::ptr::*; @@ -388,7 +388,7 @@ fn align_offset_various_strides() { let mut expected = usize::MAX; // Naive but definitely correct way to find the *first* aligned element of stride::. for el in 0..align { - if (numptr + el * ::std::mem::size_of::()) % align == 0 { + if (numptr + el * size_of::()) % align == 0 { expected = el; break; } @@ -398,7 +398,7 @@ fn align_offset_various_strides() { eprintln!( "aligning {:p} (with stride of {}) to {}, expected {}, got {}", ptr, - ::std::mem::size_of::(), + size_of::(), align, expected, got @@ -613,9 +613,9 @@ fn dyn_metadata() { let meta = metadata(trait_object); assert_eq!(meta.size_of(), 64); - assert_eq!(meta.size_of(), std::mem::size_of::()); + assert_eq!(meta.size_of(), size_of::()); assert_eq!(meta.align_of(), 32); - assert_eq!(meta.align_of(), std::mem::align_of::()); + assert_eq!(meta.align_of(), align_of::()); assert_eq!(meta.layout(), std::alloc::Layout::new::()); assert!(format!("{meta:?}").starts_with("DynMetadata(0x")); @@ -789,7 +789,7 @@ fn nonnull_tagged_pointer_with_provenance() { impl TaggedPointer { /// The ABI-required minimum alignment of the `P` type. - pub const ALIGNMENT: usize = core::mem::align_of::(); + pub const ALIGNMENT: usize = align_of::(); /// A mask for data-carrying bits of the address. pub const DATA_MASK: usize = !Self::ADDRESS_MASK; /// Number of available bits of storage in the address. @@ -873,7 +873,7 @@ fn test_const_copy_ptr() { ptr::copy( &ptr1 as *const _ as *const MaybeUninit, &mut ptr2 as *mut _ as *mut MaybeUninit, - mem::size_of::<&i32>(), + size_of::<&i32>(), ); } @@ -891,7 +891,7 @@ fn test_const_copy_ptr() { ptr::copy_nonoverlapping( &ptr1 as *const _ as *const MaybeUninit, &mut ptr2 as *mut _ as *mut MaybeUninit, - mem::size_of::<&i32>(), + size_of::<&i32>(), ); } @@ -936,7 +936,7 @@ fn test_const_swap_ptr() { let mut s2 = A(S { ptr: &666, f1: 0, f2: [0; 3] }); // Swap ptr1 and ptr2, as an array. - type T = [u8; mem::size_of::()]; + type T = [u8; size_of::()]; unsafe { ptr::swap(ptr::from_mut(&mut s1).cast::(), ptr::from_mut(&mut s2).cast::()); } diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs index 1c5c8a9ebf25..4fd072137089 100644 --- a/library/coretests/tests/slice.rs +++ b/library/coretests/tests/slice.rs @@ -2058,15 +2058,13 @@ fn test_align_to_non_trivial() { #[test] fn test_align_to_empty_mid() { - use core::mem; - // Make sure that we do not create empty unaligned slices for the mid part, even when the // overall slice is too short to contain an aligned address. let bytes = [1, 2, 3, 4, 5, 6, 7]; type Chunk = u32; for offset in 0..4 { let (_, mid, _) = unsafe { bytes[offset..offset + 1].align_to::() }; - assert_eq!(mid.as_ptr() as usize % mem::align_of::(), 0); + assert_eq!(mid.as_ptr() as usize % align_of::(), 0); } } diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs index 1569c26c9de4..bad795a019c9 100644 --- a/library/panic_unwind/src/emcc.rs +++ b/library/panic_unwind/src/emcc.rs @@ -9,7 +9,7 @@ use alloc::boxed::Box; use core::any::Any; use core::sync::atomic::{AtomicBool, Ordering}; -use core::{intrinsics, mem, ptr}; +use core::{intrinsics, ptr}; use unwind as uw; @@ -97,7 +97,7 @@ pub(crate) unsafe fn cleanup(ptr: *mut u8) -> Box { pub(crate) unsafe fn panic(data: Box) -> u32 { unsafe { - let exception = __cxa_allocate_exception(mem::size_of::()) as *mut Exception; + let exception = __cxa_allocate_exception(size_of::()) as *mut Exception; if exception.is_null() { return uw::_URC_FATAL_PHASE1_ERROR as u32; } diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 3a95b940221c..3794b56c0898 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -49,7 +49,7 @@ use alloc::boxed::Box; use core::any::Any; use core::ffi::{c_int, c_uint, c_void}; -use core::mem::{self, ManuallyDrop}; +use core::mem::ManuallyDrop; // NOTE(nbdd0121): The `canary` field is part of stable ABI. #[repr(C)] @@ -225,7 +225,7 @@ static mut CATCHABLE_TYPE: _CatchableType = _CatchableType { properties: 0, pType: ptr_t::null(), thisDisplacement: _PMD { mdisp: 0, pdisp: -1, vdisp: 0 }, - sizeOrOffset: mem::size_of::() as c_int, + sizeOrOffset: size_of::() as c_int, copyFunction: ptr_t::null(), }; diff --git a/library/proc_macro/src/bridge/selfless_reify.rs b/library/proc_macro/src/bridge/selfless_reify.rs index 312a79152e23..b06434a5ffee 100644 --- a/library/proc_macro/src/bridge/selfless_reify.rs +++ b/library/proc_macro/src/bridge/selfless_reify.rs @@ -50,7 +50,7 @@ macro_rules! define_reify_functions { >(f: F) -> $(extern $abi)? fn($($arg_ty),*) -> $ret_ty { // FIXME(eddyb) describe the `F` type (e.g. via `type_name::`) once panic // formatting becomes possible in `const fn`. - assert!(mem::size_of::() == 0, "selfless_reify: closure must be zero-sized"); + assert!(size_of::() == 0, "selfless_reify: closure must be zero-sized"); $(extern $abi)? fn wrapper< $($($param,)*)? diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 38dcd816d267..6dd18e4f4c83 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1878,7 +1878,7 @@ fn windows_unix_socket_exists() { let bytes = socket_path.as_os_str().as_encoded_bytes(); let bytes = core::slice::from_raw_parts(bytes.as_ptr().cast::(), bytes.len()); addr.sun_path[..bytes.len()].copy_from_slice(bytes); - let len = mem::size_of_val(&addr) as i32; + let len = size_of_val(&addr) as i32; let result = c::bind(socket, (&raw const addr).cast::(), len); c::closesocket(socket); assert_eq!(result, 0); diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs index edac6563478c..3e4029768eb8 100644 --- a/library/std/src/io/error/tests.rs +++ b/library/std/src/io/error/tests.rs @@ -1,6 +1,5 @@ use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error}; use crate::assert_matches::assert_matches; -use crate::mem::size_of; use crate::sys::decode_error_kind; use crate::sys::os::error_string; use crate::{error, fmt}; diff --git a/library/std/src/os/fd/tests.rs b/library/std/src/os/fd/tests.rs index b39863644f11..7e9cf038e9a7 100644 --- a/library/std/src/os/fd/tests.rs +++ b/library/std/src/os/fd/tests.rs @@ -36,7 +36,6 @@ fn test_fd() { #[cfg(any(unix, target_os = "wasi"))] #[test] fn test_niche_optimizations() { - use crate::mem::size_of; #[cfg(unix)] use crate::os::unix::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; #[cfg(target_os = "wasi")] diff --git a/library/std/src/os/unix/io/tests.rs b/library/std/src/os/unix/io/tests.rs index 84d2a7a1a91b..fc147730578a 100644 --- a/library/std/src/os/unix/io/tests.rs +++ b/library/std/src/os/unix/io/tests.rs @@ -1,4 +1,3 @@ -use crate::mem::size_of; use crate::os::unix::io::RawFd; #[test] diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 56789f235fda..cb1246db3109 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -94,7 +94,7 @@ impl SocketAddr { { unsafe { let mut addr: libc::sockaddr_un = mem::zeroed(); - let mut len = mem::size_of::() as libc::socklen_t; + let mut len = size_of::() as libc::socklen_t; cvt(f((&raw mut addr) as *mut _, &mut len))?; SocketAddr::from_parts(addr, len) } diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs index be236317d047..27428c9eb285 100644 --- a/library/std/src/os/unix/net/listener.rs +++ b/library/std/src/os/unix/net/listener.rs @@ -177,7 +177,7 @@ impl UnixListener { #[stable(feature = "unix_socket", since = "1.10.0")] pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() }; - let mut len = mem::size_of_val(&storage) as libc::socklen_t; + let mut len = size_of_val(&storage) as libc::socklen_t; let sock = self.0.accept((&raw mut storage) as *mut _, &mut len)?; let addr = SocketAddr::from_parts(storage, len)?; Ok((UnixStream(sock), addr)) diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs index e1014a4f296d..2dd7d409e48c 100644 --- a/library/std/src/os/unix/net/ucred.rs +++ b/library/std/src/os/unix/net/ucred.rs @@ -41,15 +41,15 @@ mod impl_linux { use libc::{SO_PEERCRED, SOL_SOCKET, c_void, getsockopt, socklen_t, ucred}; use super::UCred; + use crate::io; use crate::os::unix::io::AsRawFd; use crate::os::unix::net::UnixStream; - use crate::{io, mem}; pub fn peer_cred(socket: &UnixStream) -> io::Result { - let ucred_size = mem::size_of::(); + let ucred_size = size_of::(); // Trivial sanity checks. - assert!(mem::size_of::() <= mem::size_of::()); + assert!(size_of::() <= size_of::()); assert!(ucred_size <= u32::MAX as usize); let mut ucred_size = ucred_size as socklen_t; @@ -64,7 +64,7 @@ mod impl_linux { &mut ucred_size, ); - if ret == 0 && ucred_size as usize == mem::size_of::() { + if ret == 0 && ucred_size as usize == size_of::() { Ok(UCred { uid: ucred.uid, gid: ucred.gid, pid: Some(ucred.pid) }) } else { Err(io::Error::last_os_error()) @@ -101,9 +101,9 @@ mod impl_apple { use libc::{LOCAL_PEERPID, SOL_LOCAL, c_void, getpeereid, getsockopt, pid_t, socklen_t}; use super::UCred; + use crate::io; use crate::os::unix::io::AsRawFd; use crate::os::unix::net::UnixStream; - use crate::{io, mem}; pub fn peer_cred(socket: &UnixStream) -> io::Result { let mut cred = UCred { uid: 1, gid: 1, pid: None }; @@ -115,7 +115,7 @@ mod impl_apple { } let mut pid: pid_t = 1; - let mut pid_size = mem::size_of::() as socklen_t; + let mut pid_size = size_of::() as socklen_t; let ret = getsockopt( socket.as_raw_fd(), @@ -125,7 +125,7 @@ mod impl_apple { &mut pid_size, ); - if ret == 0 && pid_size as usize == mem::size_of::() { + if ret == 0 && pid_size as usize == size_of::() { cred.pid = Some(pid); Ok(cred) } else { diff --git a/library/std/src/os/wasi/io/tests.rs b/library/std/src/os/wasi/io/tests.rs index 418274752b0a..c5c6a19a6c88 100644 --- a/library/std/src/os/wasi/io/tests.rs +++ b/library/std/src/os/wasi/io/tests.rs @@ -1,4 +1,3 @@ -use crate::mem::size_of; use crate::os::wasi::io::RawFd; #[test] diff --git a/library/std/src/os/windows/io/tests.rs b/library/std/src/os/windows/io/tests.rs index 41734e52e8cc..029b6f5cd3d9 100644 --- a/library/std/src/os/windows/io/tests.rs +++ b/library/std/src/os/windows/io/tests.rs @@ -1,6 +1,5 @@ #[test] fn test_niche_optimizations_socket() { - use crate::mem::size_of; use crate::os::windows::io::{ BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket, }; diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 201274cf03ae..fa65a7c51bfa 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -500,11 +500,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> { /// [1]: pub fn attribute(self, attribute: usize, value: &'a T) -> Self { unsafe { - self.raw_attribute( - attribute, - ptr::addr_of!(*value).cast::(), - crate::mem::size_of::(), - ) + self.raw_attribute(attribute, ptr::addr_of!(*value).cast::(), size_of::()) } } @@ -574,7 +570,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> { /// .raw_attribute( /// PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, /// h_pc as *const c_void, - /// std::mem::size_of::(), + /// size_of::(), /// ) /// .finish()? /// }; diff --git a/library/std/src/os/xous/ffi.rs b/library/std/src/os/xous/ffi.rs index 1db314e9ddad..9394f0a0496b 100644 --- a/library/std/src/os/xous/ffi.rs +++ b/library/std/src/os/xous/ffi.rs @@ -368,7 +368,7 @@ pub(crate) unsafe fn map_memory( let mut a0 = Syscall::MapMemory as usize; let mut a1 = phys.map(|p| p.as_ptr() as usize).unwrap_or_default(); let mut a2 = virt.map(|p| p.as_ptr() as usize).unwrap_or_default(); - let a3 = count * core::mem::size_of::(); + let a3 = count * size_of::(); let a4 = flags.bits(); let a5 = 0; let a6 = 0; @@ -392,7 +392,7 @@ pub(crate) unsafe fn map_memory( if result == SyscallResult::MemoryRange as usize { let start = core::ptr::with_exposed_provenance_mut::(a1); - let len = a2 / core::mem::size_of::(); + let len = a2 / size_of::(); let end = unsafe { start.add(len) }; Ok(unsafe { core::slice::from_raw_parts_mut(start, len) }) } else if result == SyscallResult::Error as usize { @@ -409,7 +409,7 @@ pub(crate) unsafe fn map_memory( pub(crate) unsafe fn unmap_memory(range: *mut [T]) -> Result<(), Error> { let mut a0 = Syscall::UnmapMemory as usize; let mut a1 = range.as_mut_ptr() as usize; - let a2 = range.len() * core::mem::size_of::(); + let a2 = range.len() * size_of::(); let a3 = 0; let a4 = 0; let a5 = 0; @@ -455,7 +455,7 @@ pub(crate) unsafe fn update_memory_flags( ) -> Result<(), Error> { let mut a0 = Syscall::UpdateMemoryFlags as usize; let mut a1 = range.as_mut_ptr() as usize; - let a2 = range.len() * core::mem::size_of::(); + let a2 = range.len() * size_of::(); let a3 = new_flags.bits(); let a4 = 0; // Process ID is currently None let a5 = 0; diff --git a/library/std/src/os/xous/services/log.rs b/library/std/src/os/xous/services/log.rs index 1661011ca64b..095d4f4a3e7a 100644 --- a/library/std/src/os/xous/services/log.rs +++ b/library/std/src/os/xous/services/log.rs @@ -7,8 +7,8 @@ use crate::os::xous::ffi::Connection; /// `group_or_null([1,2,3,4,5,6,7,8], 1)` on a 32-bit system will return a /// `usize` with 5678 packed into it. fn group_or_null(data: &[u8], offset: usize) -> usize { - let start = offset * core::mem::size_of::(); - let mut out_array = [0u8; core::mem::size_of::()]; + let start = offset * size_of::(); + let mut out_array = [0u8; size_of::()]; if start < data.len() { for (dest, src) in out_array.iter_mut().zip(&data[start..]) { *dest = *src; diff --git a/library/std/src/sys/alloc/unix.rs b/library/std/src/sys/alloc/unix.rs index 1af9d7662901..a7ac4117ec90 100644 --- a/library/std/src/sys/alloc/unix.rs +++ b/library/std/src/sys/alloc/unix.rs @@ -81,7 +81,7 @@ cfg_if::cfg_if! { // while others require the alignment to be at least the pointer size (Illumos, macOS). // posix_memalign only has one, clear requirement: that the alignment be a multiple of // `sizeof(void*)`. Since these are all powers of 2, we can just use max. - let align = layout.align().max(crate::mem::size_of::()); + let align = layout.align().max(size_of::()); let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) }; if ret != 0 { ptr::null_mut() } else { out as *mut u8 } } diff --git a/library/std/src/sys/alloc/windows/tests.rs b/library/std/src/sys/alloc/windows/tests.rs index 674a3e1d92d1..1d5614528b12 100644 --- a/library/std/src/sys/alloc/windows/tests.rs +++ b/library/std/src/sys/alloc/windows/tests.rs @@ -1,9 +1,8 @@ use super::{Header, MIN_ALIGN}; -use crate::mem; #[test] fn alloc_header() { // Header must fit in the padding before an aligned pointer - assert!(mem::size_of::
() <= MIN_ALIGN); - assert!(mem::align_of::
() <= MIN_ALIGN); + assert!(size_of::
() <= MIN_ALIGN); + assert!(align_of::
() <= MIN_ALIGN); } diff --git a/library/std/src/sys/io/is_terminal/windows.rs b/library/std/src/sys/io/is_terminal/windows.rs index 3ec18fb47b9d..b0c718d71f9f 100644 --- a/library/std/src/sys/io/is_terminal/windows.rs +++ b/library/std/src/sys/io/is_terminal/windows.rs @@ -1,5 +1,4 @@ use crate::ffi::c_void; -use crate::mem::size_of; use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle}; use crate::sys::c; diff --git a/library/std/src/sys/net/connection/socket.rs b/library/std/src/sys/net/connection/socket.rs index ddd74b426158..e154cf039cad 100644 --- a/library/std/src/sys/net/connection/socket.rs +++ b/library/std/src/sys/net/connection/socket.rs @@ -154,11 +154,11 @@ fn socket_addr_to_c(addr: &SocketAddr) -> (SocketAddrCRepr, c::socklen_t) { match addr { SocketAddr::V4(a) => { let sockaddr = SocketAddrCRepr { v4: socket_addr_v4_to_c(a) }; - (sockaddr, mem::size_of::() as c::socklen_t) + (sockaddr, size_of::() as c::socklen_t) } SocketAddr::V6(a) => { let sockaddr = SocketAddrCRepr { v6: socket_addr_v6_to_c(a) }; - (sockaddr, mem::size_of::() as c::socklen_t) + (sockaddr, size_of::() as c::socklen_t) } } } @@ -169,13 +169,13 @@ unsafe fn socket_addr_from_c( ) -> io::Result { match (*storage).ss_family as c_int { c::AF_INET => { - assert!(len >= mem::size_of::()); + assert!(len >= size_of::()); Ok(SocketAddr::V4(socket_addr_v4_from_c(unsafe { *(storage as *const _ as *const c::sockaddr_in) }))) } c::AF_INET6 => { - assert!(len >= mem::size_of::()); + assert!(len >= size_of::()); Ok(SocketAddr::V6(socket_addr_v6_from_c(unsafe { *(storage as *const _ as *const c::sockaddr_in6) }))) @@ -200,7 +200,7 @@ pub fn setsockopt( level, option_name, (&raw const option_value) as *const _, - mem::size_of::() as c::socklen_t, + size_of::() as c::socklen_t, ))?; Ok(()) } @@ -209,7 +209,7 @@ pub fn setsockopt( pub fn getsockopt(sock: &Socket, level: c_int, option_name: c_int) -> io::Result { unsafe { let mut option_value: T = mem::zeroed(); - let mut option_len = mem::size_of::() as c::socklen_t; + let mut option_len = size_of::() as c::socklen_t; cvt(c::getsockopt( sock.as_raw(), level, @@ -227,7 +227,7 @@ where { unsafe { let mut storage: c::sockaddr_storage = mem::zeroed(); - let mut len = mem::size_of_val(&storage) as c::socklen_t; + let mut len = size_of_val(&storage) as c::socklen_t; cvt(f((&raw mut storage) as *mut _, &mut len))?; socket_addr_from_c(&storage, len as usize) } @@ -561,7 +561,7 @@ impl TcpListener { // so we don't need to zero it here. // reference: https://linux.die.net/man/2/accept4 let mut storage: mem::MaybeUninit = mem::MaybeUninit::uninit(); - let mut len = mem::size_of_val(&storage) as c::socklen_t; + let mut len = size_of_val(&storage) as c::socklen_t; let sock = self.inner.accept(storage.as_mut_ptr() as *mut _, &mut len)?; let addr = unsafe { socket_addr_from_c(storage.as_ptr(), len as usize)? }; Ok((TcpStream { inner: sock }, addr)) diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs index e393342ced9d..f49821657d94 100644 --- a/library/std/src/sys/net/connection/socket/hermit.rs +++ b/library/std/src/sys/net/connection/socket/hermit.rs @@ -183,7 +183,7 @@ impl Socket { fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> { let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t; + let mut addrlen = size_of_val(&storage) as netc::socklen_t; let n = cvt(unsafe { netc::recvfrom( diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs index 906bef267b6f..94bb605c1007 100644 --- a/library/std/src/sys/net/connection/socket/solid.rs +++ b/library/std/src/sys/net/connection/socket/solid.rs @@ -244,7 +244,7 @@ impl Socket { flags: c_int, ) -> io::Result<(usize, SocketAddr)> { let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t; + let mut addrlen = size_of_val(&storage) as netc::socklen_t; let n = cvt(unsafe { netc::recvfrom( diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index 29fb47ddca3b..e633cf772c52 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -326,7 +326,7 @@ impl Socket { // so we don't need to zero it here. // reference: https://linux.die.net/man/2/recvfrom let mut storage: mem::MaybeUninit = mem::MaybeUninit::uninit(); - let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t; + let mut addrlen = size_of_val(&storage) as libc::socklen_t; let n = cvt(unsafe { libc::recvfrom( diff --git a/library/std/src/sys/net/connection/socket/wasip2.rs b/library/std/src/sys/net/connection/socket/wasip2.rs index c5034e73dd70..73c258318720 100644 --- a/library/std/src/sys/net/connection/socket/wasip2.rs +++ b/library/std/src/sys/net/connection/socket/wasip2.rs @@ -211,7 +211,7 @@ impl Socket { flags: c_int, ) -> io::Result<(usize, SocketAddr)> { let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t; + let mut addrlen = size_of_val(&storage) as netc::socklen_t; let n = cvt(unsafe { netc::recvfrom( diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index 428f142dabe2..ce975bb2289c 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs @@ -381,7 +381,7 @@ impl Socket { flags: c_int, ) -> io::Result<(usize, SocketAddr)> { let mut storage = unsafe { mem::zeroed::() }; - let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t; + let mut addrlen = size_of_val(&storage) as netc::socklen_t; let length = cmp::min(buf.len(), ::MAX as usize) as wrlen_t; // On unix when a socket is shut down all further reads return 0, so we @@ -514,13 +514,13 @@ impl Socket { // This is used by sys_common code to abstract over Windows and Unix. pub fn as_raw(&self) -> c::SOCKET { - debug_assert_eq!(mem::size_of::(), mem::size_of::()); - debug_assert_eq!(mem::align_of::(), mem::align_of::()); + debug_assert_eq!(size_of::(), size_of::()); + debug_assert_eq!(align_of::(), align_of::()); self.as_inner().as_raw_socket() as c::SOCKET } pub unsafe fn from_raw(raw: c::SOCKET) -> Self { - debug_assert_eq!(mem::size_of::(), mem::size_of::()); - debug_assert_eq!(mem::align_of::(), mem::align_of::()); + debug_assert_eq!(size_of::(), size_of::()); + debug_assert_eq!(align_of::(), align_of::()); unsafe { Self::from_raw_socket(raw as RawSocket) } } } diff --git a/library/std/src/sys/net/connection/xous/udp.rs b/library/std/src/sys/net/connection/xous/udp.rs index f35970bc3215..c112c04ce94b 100644 --- a/library/std/src/sys/net/connection/xous/udp.rs +++ b/library/std/src/sys/net/connection/xous/udp.rs @@ -244,7 +244,7 @@ impl UdpSocket { // let buf = unsafe { // xous::MemoryRange::new( // &mut tx_req as *mut SendData as usize, - // core::mem::size_of::(), + // size_of::(), // ) // .unwrap() // }; diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs index 04095e1a7cf9..d1481f827e1e 100644 --- a/library/std/src/sys/pal/itron/thread.rs +++ b/library/std/src/sys/pal/itron/thread.rs @@ -80,7 +80,7 @@ const LIFECYCLE_EXITED_OR_FINISHED_OR_JOIN_FINALIZE: usize = usize::MAX; // there's no single value for `JOINING` // 64KiB for 32-bit ISAs, 128KiB for 64-bit ISAs. -pub const DEFAULT_MIN_STACK_SIZE: usize = 0x4000 * crate::mem::size_of::(); +pub const DEFAULT_MIN_STACK_SIZE: usize = 0x4000 * size_of::(); impl Thread { /// # Safety diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index 5069ab82ccc9..301e3299c057 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs @@ -63,7 +63,7 @@ unsafe impl UserSafeSized for [T; 2] {} /// A type that can be represented in memory as one or more `UserSafeSized`s. #[unstable(feature = "sgx_platform", issue = "56975")] pub unsafe trait UserSafe { - /// Equivalent to `mem::align_of::`. + /// Equivalent to `align_of::`. fn align_of() -> usize; /// Constructs a pointer to `Self` given a memory range in user space. @@ -120,7 +120,7 @@ pub unsafe trait UserSafe { let is_aligned = |p: *const u8| -> bool { p.is_aligned_to(Self::align_of()) }; assert!(is_aligned(ptr as *const u8)); - assert!(is_user_range(ptr as _, mem::size_of_val(unsafe { &*ptr }))); + assert!(is_user_range(ptr as _, size_of_val(unsafe { &*ptr }))); assert!(!ptr.is_null()); } } @@ -128,11 +128,11 @@ pub unsafe trait UserSafe { #[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl UserSafe for T { fn align_of() -> usize { - mem::align_of::() + align_of::() } unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self { - assert_eq!(size, mem::size_of::()); + assert_eq!(size, size_of::()); ptr as _ } } @@ -140,7 +140,7 @@ unsafe impl UserSafe for T { #[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl UserSafe for [T] { fn align_of() -> usize { - mem::align_of::() + align_of::() } /// # Safety @@ -155,7 +155,7 @@ unsafe impl UserSafe for [T] { /// /// * the element size is not a factor of the size unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self { - let elem_size = mem::size_of::(); + let elem_size = size_of::(); assert_eq!(size % elem_size, 0); let len = size / elem_size; // SAFETY: The caller must uphold the safety contract for `from_raw_sized_unchecked` @@ -239,7 +239,7 @@ where /// Copies `val` into freshly allocated space in user memory. pub fn new_from_enclave(val: &T) -> Self { unsafe { - let mut user = Self::new_uninit_bytes(mem::size_of_val(val)); + let mut user = Self::new_uninit_bytes(size_of_val(val)); user.copy_from_enclave(val); user } @@ -277,7 +277,7 @@ where { /// Allocates space for `T` in user memory. pub fn uninitialized() -> Self { - Self::new_uninit_bytes(mem::size_of::()) + Self::new_uninit_bytes(size_of::()) } } @@ -288,7 +288,7 @@ where { /// Allocates space for a `[T]` of `n` elements in user memory. pub fn uninitialized(n: usize) -> Self { - Self::new_uninit_bytes(n * mem::size_of::()) + Self::new_uninit_bytes(n * size_of::()) } /// Creates an owned `User<[T]>` from a raw thin pointer and a slice length. @@ -306,9 +306,7 @@ where /// * The pointed-to range does not fit in the address space /// * The pointed-to range is not in user memory pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self { - User(unsafe { - NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::())) - }) + User(unsafe { NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * size_of::())) }) } } @@ -326,7 +324,7 @@ where // `<*const u8>::align_offset` aren't _guaranteed_ to compute the largest // possible middle region, and as such can't be used. fn u64_align_to_guaranteed(ptr: *const u8, mut len: usize) -> (usize, usize, usize) { - const QWORD_SIZE: usize = mem::size_of::(); + const QWORD_SIZE: usize = size_of::(); let offset = ptr as usize % QWORD_SIZE; @@ -532,11 +530,11 @@ where /// the source. This can happen for dynamically-sized types such as slices. pub fn copy_from_enclave(&mut self, val: &T) { unsafe { - assert_eq!(mem::size_of_val(val), mem::size_of_val(&*self.0.get())); + assert_eq!(size_of_val(val), size_of_val(&*self.0.get())); copy_to_userspace( val as *const T as *const u8, self.0.get() as *mut T as *mut u8, - mem::size_of_val(val), + size_of_val(val), ); } } @@ -548,11 +546,11 @@ where /// the source. This can happen for dynamically-sized types such as slices. pub fn copy_to_enclave(&self, dest: &mut T) { unsafe { - assert_eq!(mem::size_of_val(dest), mem::size_of_val(&*self.0.get())); + assert_eq!(size_of_val(dest), size_of_val(&*self.0.get())); copy_from_userspace( self.0.get() as *const T as *const u8, dest as *mut T as *mut u8, - mem::size_of_val(dest), + size_of_val(dest), ); } } @@ -577,7 +575,7 @@ where pub fn to_enclave(&self) -> T { unsafe { let mut data = mem::MaybeUninit::uninit(); - copy_from_userspace(self.0.get() as _, data.as_mut_ptr() as _, mem::size_of::()); + copy_from_userspace(self.0.get() as _, data.as_mut_ptr() as _, size_of::()); data.assume_init() } } @@ -602,9 +600,7 @@ where /// * The pointed-to range is not in user memory pub unsafe fn from_raw_parts<'a>(ptr: *const T, len: usize) -> &'a Self { // SAFETY: The caller must uphold the safety contract for `from_raw_parts`. - unsafe { - &*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::()).as_ptr() as *const Self) - } + unsafe { &*(<[T]>::from_raw_sized(ptr as _, len * size_of::()).as_ptr() as *const Self) } } /// Creates a `&mut UserRef<[T]>` from a raw thin pointer and a slice length. @@ -624,7 +620,7 @@ where pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut T, len: usize) -> &'a mut Self { // SAFETY: The caller must uphold the safety contract for `from_raw_parts_mut`. unsafe { - &mut *(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::()).as_ptr() as *mut Self) + &mut *(<[T]>::from_raw_sized(ptr as _, len * size_of::()).as_ptr() as *mut Self) } } @@ -744,7 +740,7 @@ where fn drop(&mut self) { unsafe { let ptr = (*self.0.as_ptr()).0.get(); - super::free(ptr as _, mem::size_of_val(&mut *ptr), T::align_of()); + super::free(ptr as _, size_of_val(&mut *ptr), T::align_of()); } } } diff --git a/library/std/src/sys/pal/uefi/args.rs b/library/std/src/sys/pal/uefi/args.rs index bdf6f5a0c1c3..0c29caf2db67 100644 --- a/library/std/src/sys/pal/uefi/args.rs +++ b/library/std/src/sys/pal/uefi/args.rs @@ -4,7 +4,6 @@ use super::helpers; use crate::env::current_exe; use crate::ffi::OsString; use crate::iter::Iterator; -use crate::mem::size_of; use crate::{fmt, vec}; pub struct Args { diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index cb6aacd0063d..ca28239ef14f 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -15,7 +15,7 @@ use r_efi::protocols::{device_path, device_path_to_text, shell}; use crate::ffi::{OsStr, OsString}; use crate::io::{self, const_error}; use crate::marker::PhantomData; -use crate::mem::{MaybeUninit, size_of}; +use crate::mem::MaybeUninit; use crate::os::uefi::env::boot_services; use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; use crate::os::uefi::{self}; diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs index a47c8dbcaaaf..5b9e119edd1c 100644 --- a/library/std/src/sys/pal/uefi/process.rs +++ b/library/std/src/sys/pal/uefi/process.rs @@ -490,7 +490,7 @@ mod uefi_command_internal { helpers::open_protocol(self.handle, loaded_image::PROTOCOL_GUID).unwrap(); let len = args.len(); - let args_size: u32 = (len * crate::mem::size_of::()).try_into().unwrap(); + let args_size: u32 = (len * size_of::()).try_into().unwrap(); let ptr = Box::into_raw(args).as_mut_ptr(); unsafe { diff --git a/library/std/src/sys/pal/uefi/tests.rs b/library/std/src/sys/pal/uefi/tests.rs index 5eb36da922b5..38658cc4e9ac 100644 --- a/library/std/src/sys/pal/uefi/tests.rs +++ b/library/std/src/sys/pal/uefi/tests.rs @@ -16,7 +16,7 @@ fn align() { if *j <= 8 { assert_eq!(align_size(i, *j), i); } else { - assert!(align_size(i, *j) > i + std::mem::size_of::<*mut ()>()); + assert!(align_size(i, *j) > i + size_of::<*mut ()>()); } } } diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 3df460e38b72..20ba915af136 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -1505,7 +1505,7 @@ impl File { self.as_raw_fd(), (&raw const attrlist).cast::().cast_mut(), buf.as_ptr().cast::().cast_mut(), - num_times * mem::size_of::(), + num_times * size_of::(), 0 ) })?; Ok(()) @@ -1660,7 +1660,7 @@ impl fmt::Debug for File { fn get_path(fd: c_int) -> Option { let info = Box::::new_zeroed(); let mut info = unsafe { info.assume_init() }; - info.kf_structsize = mem::size_of::() as libc::c_int; + info.kf_structsize = size_of::() as libc::c_int; let n = unsafe { libc::fcntl(fd, libc::F_KINFO, &mut *info) }; if n == -1 { return None; diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs index d4551dd6a38b..87ba13ca9321 100644 --- a/library/std/src/sys/pal/unix/futex.rs +++ b/library/std/src/sys/pal/unix/futex.rs @@ -58,7 +58,7 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option) - _clockid: libc::CLOCK_MONOTONIC as u32, }); let umtx_timeout_ptr = umtx_timeout.as_ref().map_or(null(), |t| t as *const _); - let umtx_timeout_size = umtx_timeout.as_ref().map_or(0, |t| crate::mem::size_of_val(t)); + let umtx_timeout_size = umtx_timeout.as_ref().map_or(0, |t| size_of_val(t)); libc::_umtx_op( futex as *const AtomicU32 as *mut _, libc::UMTX_OP_WAIT_UINT_PRIVATE, diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/pal/unix/process/process_common.rs index 342818ac9118..0ea9db211b31 100644 --- a/library/std/src/sys/pal/unix/process/process_common.rs +++ b/library/std/src/sys/pal/unix/process/process_common.rs @@ -43,10 +43,7 @@ cfg_if::cfg_if! { #[allow(dead_code)] pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int { - use crate::{ - mem::{align_of, size_of}, - slice, - }; + use crate::slice; use libc::{c_ulong, sigset_t}; // The implementations from bionic (android libc) type pun `sigset_t` as an diff --git a/library/std/src/sys/pal/unix/process/process_fuchsia.rs b/library/std/src/sys/pal/unix/process/process_fuchsia.rs index 4ddc96356b99..05c9ace470e3 100644 --- a/library/std/src/sys/pal/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/pal/unix/process/process_fuchsia.rs @@ -179,7 +179,7 @@ impl Process { self.handle.raw(), ZX_INFO_PROCESS, (&raw mut proc_info) as *mut libc::c_void, - mem::size_of::(), + size_of::(), &mut actual, &mut avail, ))?; @@ -216,7 +216,7 @@ impl Process { self.handle.raw(), ZX_INFO_PROCESS, (&raw mut proc_info) as *mut libc::c_void, - mem::size_of::(), + size_of::(), &mut actual, &mut avail, ))?; diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 1f3abd4cc128..00d4d46dba59 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -799,7 +799,7 @@ impl Command { let fds: [c_int; 1] = [pidfd as RawFd]; - const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>(); + const SCM_MSG_LEN: usize = size_of::<[c_int; 1]>(); #[repr(C)] union Cmsg { @@ -818,7 +818,7 @@ impl Command { // only attach cmsg if we successfully acquired the pidfd if pidfd >= 0 { - msg.msg_controllen = mem::size_of_val(&cmsg.buf) as _; + msg.msg_controllen = size_of_val(&cmsg.buf) as _; msg.msg_control = (&raw mut cmsg.buf) as *mut _; let hdr = CMSG_FIRSTHDR((&raw mut msg) as *mut _); @@ -850,7 +850,7 @@ impl Command { use crate::sys::cvt_r; unsafe { - const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>(); + const SCM_MSG_LEN: usize = size_of::<[c_int; 1]>(); #[repr(C)] union Cmsg { @@ -865,7 +865,7 @@ impl Command { msg.msg_iov = (&raw mut iov) as *mut _; msg.msg_iovlen = 1; - msg.msg_controllen = mem::size_of::() as _; + msg.msg_controllen = size_of::() as _; msg.msg_control = (&raw mut cmsg) as *mut _; match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, libc::MSG_CMSG_CLOEXEC)) { diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index 43ece63457fe..0ecccdc8812d 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -426,7 +426,7 @@ mod imp { use crate::sys::weak::dlsym; dlsym!(fn sysctlbyname(*const libc::c_char, *mut libc::c_void, *mut libc::size_t, *const libc::c_void, libc::size_t) -> libc::c_int); let mut guard: usize = 0; - let mut size = mem::size_of_val(&guard); + let mut size = size_of_val(&guard); let oid = c"security.bsd.stack_guard_page"; match sysctlbyname.get() { Some(fcn) if unsafe { diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 3dedc8d1257c..11f6998cac11 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -372,7 +372,7 @@ pub fn available_parallelism() -> io::Result> { quota = cgroups::quota().max(1); let mut set: libc::cpu_set_t = unsafe { mem::zeroed() }; unsafe { - if libc::sched_getaffinity(0, mem::size_of::(), &mut set) == 0 { + if libc::sched_getaffinity(0, size_of::(), &mut set) == 0 { let count = libc::CPU_COUNT(&set) as usize; let count = count.min(quota); @@ -412,7 +412,7 @@ pub fn available_parallelism() -> io::Result> { libc::CPU_LEVEL_WHICH, libc::CPU_WHICH_PID, -1, - mem::size_of::(), + size_of::(), &mut set, ) == 0 { let count = libc::CPU_COUNT(&set) as usize; @@ -447,7 +447,7 @@ pub fn available_parallelism() -> io::Result> { } let mut cpus: libc::c_uint = 0; - let mut cpus_size = crate::mem::size_of_val(&cpus); + let mut cpus_size = size_of_val(&cpus); unsafe { cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint; diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs index 5a37598f4382..7ec4787f1eab 100644 --- a/library/std/src/sys/pal/unix/weak.rs +++ b/library/std/src/sys/pal/unix/weak.rs @@ -123,7 +123,7 @@ impl DlsymWeak { // Cold because it should only happen during first-time initialization. #[cold] unsafe fn initialize(&self) -> Option { - assert_eq!(mem::size_of::(), mem::size_of::<*mut libc::c_void>()); + assert_eq!(size_of::(), size_of::<*mut libc::c_void>()); let val = fetch(self.name); // This synchronizes with the acquire fence in `get`. diff --git a/library/std/src/sys/pal/wasi/fd.rs b/library/std/src/sys/pal/wasi/fd.rs index 19b60157e2e0..4b3dd1ce49ef 100644 --- a/library/std/src/sys/pal/wasi/fd.rs +++ b/library/std/src/sys/pal/wasi/fd.rs @@ -14,8 +14,8 @@ pub struct WasiFd { } fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] { - assert_eq!(mem::size_of::>(), mem::size_of::()); - assert_eq!(mem::align_of::>(), mem::align_of::()); + assert_eq!(size_of::>(), size_of::()); + assert_eq!(align_of::>(), align_of::()); // SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout. // We decorate our `IoSliceMut` with `repr(transparent)` (see `io.rs`), and // `crate::io::IoSliceMut` is a `repr(transparent)` wrapper around our type, so this is @@ -24,8 +24,8 @@ fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] { } fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] { - assert_eq!(mem::size_of::>(), mem::size_of::()); - assert_eq!(mem::align_of::>(), mem::align_of::()); + assert_eq!(size_of::>(), size_of::()); + assert_eq!(align_of::>(), align_of::()); // SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout. // We decorate our `IoSlice` with `repr(transparent)` (see `io.rs`), and // `crate::io::IoSlice` is a `repr(transparent)` wrapper around our type, so this is diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs index 39978346d738..6d7d125fc4d4 100644 --- a/library/std/src/sys/pal/wasi/fs.rs +++ b/library/std/src/sys/pal/wasi/fs.rs @@ -209,7 +209,7 @@ impl Iterator for ReadDir { } ReadDirState::ProcessEntry { buf, next_read_offset, offset } => { let contents = &buf[*offset..]; - const DIRENT_SIZE: usize = crate::mem::size_of::(); + const DIRENT_SIZE: usize = size_of::(); if contents.len() >= DIRENT_SIZE { let (dirent, data) = contents.split_at(DIRENT_SIZE); let dirent = diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index 0ae023694106..c85b03d4a891 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -13,16 +13,15 @@ cfg_if::cfg_if! { // Add a few symbols not in upstream `libc` just yet. mod libc { pub use crate::ffi; - pub use crate::mem; pub use libc::*; // defined in wasi-libc // https://github.com/WebAssembly/wasi-libc/blob/a6f871343313220b76009827ed0153586361c0d5/libc-top-half/musl/include/alltypes.h.in#L108 #[repr(C)] union pthread_attr_union { - __i: [ffi::c_int; if mem::size_of::() == 8 { 14 } else { 9 }], - __vi: [ffi::c_int; if mem::size_of::() == 8 { 14 } else { 9 }], - __s: [ffi::c_ulong; if mem::size_of::() == 8 { 7 } else { 9 }], + __i: [ffi::c_int; if size_of::() == 8 { 14 } else { 9 }], + __vi: [ffi::c_int; if size_of::() == 8 { 14 } else { 9 }], + __s: [ffi::c_ulong; if size_of::() == 8 { 7 } else { 9 }], } #[repr(C)] diff --git a/library/std/src/sys/pal/windows/api.rs b/library/std/src/sys/pal/windows/api.rs index ebe207fde935..6b5f9aeace28 100644 --- a/library/std/src/sys/pal/windows/api.rs +++ b/library/std/src/sys/pal/windows/api.rs @@ -137,7 +137,7 @@ pub const fn to_utf16(s: &str) -> [u16; UTF16_LEN] { /// use frequent `as` casts. This is risky because they are too powerful. /// For example, the following will compile today: /// -/// `std::mem::size_of:: as u32` +/// `size_of:: as u32` /// /// Note that `size_of` is never actually called, instead a function pointer is /// converted to a `u32`. Clippy would warn about this but, alas, it's not run @@ -147,7 +147,7 @@ const fn win32_size_of() -> u32 { // Uses a trait to workaround restriction on using generic types in inner items. trait Win32SizeOf: Sized { const WIN32_SIZE_OF: u32 = { - let size = core::mem::size_of::(); + let size = size_of::(); assert!(size <= u32::MAX as usize); size as u32 }; diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 4fbdc839939c..40b2bed73c0d 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -6,7 +6,7 @@ #![allow(clippy::style)] use core::ffi::{CStr, c_uint, c_ulong, c_ushort, c_void}; -use core::{mem, ptr}; +use core::ptr; mod windows_sys; pub use windows_sys::*; @@ -39,7 +39,7 @@ pub fn nt_success(status: NTSTATUS) -> bool { impl UNICODE_STRING { pub fn from_ref(slice: &[u16]) -> Self { - let len = mem::size_of_val(slice); + let len = size_of_val(slice); Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ } } } @@ -47,7 +47,7 @@ impl UNICODE_STRING { impl Default for OBJECT_ATTRIBUTES { fn default() -> Self { Self { - Length: mem::size_of::() as _, + Length: size_of::() as _, RootDirectory: ptr::null_mut(), ObjectName: ptr::null_mut(), Attributes: 0, diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 623a7d89ba5a..17dc3e5c257d 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -477,7 +477,7 @@ impl File { self.handle.as_raw_handle(), c::FileAttributeTagInfo, (&raw mut attr_tag).cast(), - mem::size_of::().try_into().unwrap(), + size_of::().try_into().unwrap(), ))?; if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { reparse_tag = attr_tag.ReparseTag; @@ -504,7 +504,7 @@ impl File { pub fn file_attr(&self) -> io::Result { unsafe { let mut info: c::FILE_BASIC_INFO = mem::zeroed(); - let size = mem::size_of_val(&info); + let size = size_of_val(&info); cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileBasicInfo, @@ -536,7 +536,7 @@ impl File { file_index: None, }; let mut info: c::FILE_STANDARD_INFO = mem::zeroed(); - let size = mem::size_of_val(&info); + let size = size_of_val(&info); cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileStandardInfo, @@ -551,7 +551,7 @@ impl File { self.handle.as_raw_handle(), c::FileAttributeTagInfo, (&raw mut attr_tag).cast(), - mem::size_of::().try_into().unwrap(), + size_of::().try_into().unwrap(), ))?; if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { attr.reparse_tag = attr_tag.ReparseTag; @@ -649,7 +649,7 @@ impl File { ptr::null_mut(), ) })?; - const _: () = assert!(core::mem::align_of::() <= 8); + const _: () = assert!(align_of::() <= 8); Ok((bytes, space.0.as_mut_ptr().cast::())) } } @@ -753,7 +753,7 @@ impl File { fn basic_info(&self) -> io::Result { unsafe { let mut info: c::FILE_BASIC_INFO = mem::zeroed(); - let size = mem::size_of_val(&info); + let size = size_of_val(&info); cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileBasicInfo, @@ -886,7 +886,6 @@ impl<'a> DirBuffIter<'a> { impl<'a> Iterator for DirBuffIter<'a> { type Item = (Cow<'a, [u16]>, bool); fn next(&mut self) -> Option { - use crate::mem::size_of; let buffer = &self.buffer?[self.cursor..]; // Get the name and next entry from the buffer. @@ -1249,8 +1248,8 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { // Therefore we need to make sure to not allocate less than // size_of::() bytes, which would be the case with // 0 or 1 character paths + a null byte. - let struct_size = mem::size_of::() - .max(mem::offset_of!(c::FILE_RENAME_INFO, FileName) + new.len() * mem::size_of::()); + let struct_size = size_of::() + .max(mem::offset_of!(c::FILE_RENAME_INFO, FileName) + new.len() * size_of::()); let struct_size: u32 = struct_size.try_into().unwrap(); @@ -1282,7 +1281,7 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { handle.as_raw_handle(), c::FileAttributeTagInfo, file_attribute_tag_info.as_mut_ptr().cast(), - mem::size_of::().try_into().unwrap(), + size_of::().try_into().unwrap(), )) }; @@ -1321,11 +1320,9 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { } .unwrap_or_else(|| create_file(0, 0))?; - let layout = core::alloc::Layout::from_size_align( - struct_size as _, - mem::align_of::(), - ) - .unwrap(); + let layout = + core::alloc::Layout::from_size_align(struct_size as _, align_of::()) + .unwrap(); let file_rename_info = unsafe { alloc(layout) } as *mut c::FILE_RENAME_INFO; diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs index 38afb8c043b3..aebf638239ca 100644 --- a/library/std/src/sys/pal/windows/futex.rs +++ b/library/std/src/sys/pal/windows/futex.rs @@ -1,10 +1,10 @@ use core::ffi::c_void; +use core::ptr; use core::sync::atomic::{ AtomicBool, AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, AtomicU32, AtomicU64, AtomicUsize, }; use core::time::Duration; -use core::{mem, ptr}; use super::api::{self, WinError}; use crate::sys::{c, dur2timeout}; @@ -61,7 +61,7 @@ pub fn wait_on_address( ) -> bool { unsafe { let addr = ptr::from_ref(address).cast::(); - let size = mem::size_of::(); + let size = size_of::(); let compare_addr = (&raw const compare).cast::(); let timeout = timeout.map(dur2timeout).unwrap_or(c::INFINITE); c::WaitOnAddress(addr, compare_addr, size, timeout) == c::TRUE diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index a8f6617c9dc8..8521cf4162f5 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -151,7 +151,7 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res opts.write(ours_readable); opts.read(!ours_readable); opts.share_mode(0); - let size = mem::size_of::(); + let size = size_of::(); let mut sa = c::SECURITY_ATTRIBUTES { nLength: size as u32, lpSecurityDescriptor: ptr::null_mut(), diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs index 6eff471f3867..c57ff355d124 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/pal/windows/process.rs @@ -24,7 +24,7 @@ use crate::sys::pipe::{self, AnonPipe}; use crate::sys::{cvt, path, stdio}; use crate::sys_common::IntoInner; use crate::sys_common::process::{CommandEnv, CommandEnvs}; -use crate::{cmp, env, fmt, mem, ptr}; +use crate::{cmp, env, fmt, ptr}; //////////////////////////////////////////////////////////////////////////////// // Command @@ -355,7 +355,7 @@ impl Command { let mut si_ex; if let Some(proc_thread_attribute_list) = proc_thread_attribute_list { - si.cb = mem::size_of::() as u32; + si.cb = size_of::() as u32; flags |= c::EXTENDED_STARTUPINFO_PRESENT; si_ex = c::STARTUPINFOEXW { @@ -367,7 +367,7 @@ impl Command { }; si_ptr = (&raw mut si_ex) as _; } else { - si.cb = mem::size_of::() as u32; + si.cb = size_of::() as u32; si_ptr = (&raw mut si) as _; } @@ -599,7 +599,7 @@ impl Stdio { // permissions as well as the ability to be inherited to child // processes (as this is about to be inherited). Stdio::Null => { - let size = mem::size_of::(); + let size = size_of::(); let mut sa = c::SECURITY_ATTRIBUTES { nLength: size as u32, lpSecurityDescriptor: ptr::null_mut(), diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index 1b245991aa79..58d3406e1382 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -359,7 +359,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit]) -> io::Result() as u32, + nLength: size_of::() as u32, nInitialChars: 0, dwCtrlWakeupMask: CTRL_Z_MASK, dwControlKeyState: 0, diff --git a/library/std/src/sys/pal/xous/stdio.rs b/library/std/src/sys/pal/xous/stdio.rs index dfd47a1775ae..717361452213 100644 --- a/library/std/src/sys/pal/xous/stdio.rs +++ b/library/std/src/sys/pal/xous/stdio.rs @@ -87,7 +87,7 @@ pub struct PanicWriter { impl io::Write for PanicWriter { fn write(&mut self, s: &[u8]) -> core::result::Result { - for c in s.chunks(core::mem::size_of::() * 4) { + for c in s.chunks(size_of::() * 4) { // Text is grouped into 4x `usize` words. The id is 1100 plus // the number of characters in this message. // Ignore errors since we're already panicking. diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 054c867f90d8..8d8fe321f661 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -8,7 +8,7 @@ //! will likely change over time. #![forbid(unsafe_op_in_unsafe_fn)] -const WORD_SIZE: usize = core::mem::size_of::(); +const WORD_SIZE: usize = size_of::(); pub mod abi; #[path = "../zkvm/args.rs"] diff --git a/library/std/src/sys/personality/dwarf/eh.rs b/library/std/src/sys/personality/dwarf/eh.rs index 778d8686f023..ef5112ad74f1 100644 --- a/library/std/src/sys/personality/dwarf/eh.rs +++ b/library/std/src/sys/personality/dwarf/eh.rs @@ -12,7 +12,7 @@ #![allow(non_upper_case_globals)] #![allow(unused)] -use core::{mem, ptr}; +use core::ptr; use super::DwarfReader; @@ -245,8 +245,7 @@ unsafe fn read_encoded_pointer( DW_EH_PE_datarel => (*context.get_data_start)(), // aligned means the value is aligned to the size of a pointer DW_EH_PE_aligned => { - reader.ptr = - reader.ptr.with_addr(round_up(reader.ptr.addr(), mem::size_of::<*const u8>())?); + reader.ptr = reader.ptr.with_addr(round_up(reader.ptr.addr(), size_of::<*const u8>())?); core::ptr::null() } _ => return Err(()), diff --git a/library/std/src/sys/personality/dwarf/mod.rs b/library/std/src/sys/personality/dwarf/mod.rs index 5c52d96c4cad..2bc91951b49f 100644 --- a/library/std/src/sys/personality/dwarf/mod.rs +++ b/library/std/src/sys/personality/dwarf/mod.rs @@ -12,8 +12,6 @@ mod tests; pub mod eh; -use core::mem; - pub struct DwarfReader { pub ptr: *const u8, } @@ -29,7 +27,7 @@ impl DwarfReader { pub unsafe fn read(&mut self) -> T { unsafe { let result = self.ptr.cast::().read_unaligned(); - self.ptr = self.ptr.byte_add(mem::size_of::()); + self.ptr = self.ptr.byte_add(size_of::()); result } } diff --git a/library/std/src/sys/thread_local/key/xous.rs b/library/std/src/sys/thread_local/key/xous.rs index 55ac5b20e1ab..48dfe17ab326 100644 --- a/library/std/src/sys/thread_local/key/xous.rs +++ b/library/std/src/sys/thread_local/key/xous.rs @@ -85,7 +85,7 @@ fn tls_table() -> &'static mut [*mut u8] { if !tp.is_null() { return unsafe { - core::slice::from_raw_parts_mut(tp, TLS_MEMORY_SIZE / core::mem::size_of::<*mut u8>()) + core::slice::from_raw_parts_mut(tp, TLS_MEMORY_SIZE / size_of::<*mut u8>()) }; } // If the TP register is `0`, then this thread hasn't initialized @@ -94,7 +94,7 @@ fn tls_table() -> &'static mut [*mut u8] { map_memory( None, None, - TLS_MEMORY_SIZE / core::mem::size_of::<*mut u8>(), + TLS_MEMORY_SIZE / size_of::<*mut u8>(), MemoryFlags::R | MemoryFlags::W, ) .expect("Unable to allocate memory for thread local storage") @@ -177,11 +177,8 @@ pub unsafe fn destroy_tls() { // Finally, free the TLS array unsafe { - unmap_memory(core::slice::from_raw_parts_mut( - tp, - TLS_MEMORY_SIZE / core::mem::size_of::(), - )) - .unwrap() + unmap_memory(core::slice::from_raw_parts_mut(tp, TLS_MEMORY_SIZE / size_of::())) + .unwrap() }; } diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index ff45e82bd9c7..06c347af1819 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -1,12 +1,12 @@ use super::Builder; use crate::any::Any; use crate::panic::panic_any; +use crate::result; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sync::mpsc::{Sender, channel}; use crate::sync::{Arc, Barrier}; use crate::thread::{self, Scope, ThreadId}; use crate::time::{Duration, Instant}; -use crate::{mem, result}; // !!! These tests are dangerous. If something is buggy, they will hang, !!! // !!! instead of exiting cleanly. This might wedge the buildbots. !!! @@ -327,7 +327,7 @@ fn sleep_ms_smoke() { #[test] fn test_size_of_option_thread_id() { - assert_eq!(mem::size_of::>(), mem::size_of::()); + assert_eq!(size_of::>(), size_of::()); } #[test] diff --git a/library/unwind/src/unwinding.rs b/library/unwind/src/unwinding.rs index 1b94005ab6cd..fa8a8c385839 100644 --- a/library/unwind/src/unwinding.rs +++ b/library/unwind/src/unwinding.rs @@ -39,9 +39,9 @@ pub type _Unwind_Exception_Class = u64; pub type _Unwind_Word = *const u8; pub type _Unwind_Ptr = *const u8; -pub const unwinder_private_data_size: usize = core::mem::size_of::() - - core::mem::size_of::<_Unwind_Exception_Class>() - - core::mem::size_of::<_Unwind_Exception_Cleanup_Fn>(); +pub const unwinder_private_data_size: usize = size_of::() + - size_of::<_Unwind_Exception_Class>() + - size_of::<_Unwind_Exception_Cleanup_Fn>(); pub type _Unwind_Exception_Cleanup_Fn = Option; From 5dfa2f5fd0d2e1cdf650679d709ae71bbad7d87a Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Tue, 4 Mar 2025 21:40:04 -0800 Subject: [PATCH 780/991] Use turbofish for size_of and align_of in docs --- library/core/src/ptr/const_ptr.rs | 4 ++-- library/core/src/ptr/mut_ptr.rs | 8 ++++---- library/core/src/ptr/non_null.rs | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 43306cfa674b..9a4f916803e8 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1313,7 +1313,7 @@ impl *const T { unsafe { read_unaligned(self) } } - /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// Copies `count * size_of::()` bytes from `self` to `dest`. The source /// and destination may overlap. /// /// NOTE: this has the *same* argument order as [`ptr::copy`]. @@ -1333,7 +1333,7 @@ impl *const T { unsafe { copy(self, dest, count) } } - /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// Copies `count * size_of::()` bytes from `self` to `dest`. The source /// and destination may *not* overlap. /// /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`]. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 26aaac476027..b960a3d86bef 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1397,7 +1397,7 @@ impl *mut T { unsafe { read_unaligned(self) } } - /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// Copies `count * size_of::()` bytes from `self` to `dest`. The source /// and destination may overlap. /// /// NOTE: this has the *same* argument order as [`ptr::copy`]. @@ -1417,7 +1417,7 @@ impl *mut T { unsafe { copy(self, dest, count) } } - /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// Copies `count * size_of::()` bytes from `self` to `dest`. The source /// and destination may *not* overlap. /// /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`]. @@ -1437,7 +1437,7 @@ impl *mut T { unsafe { copy_nonoverlapping(self, dest, count) } } - /// Copies `count * size_of` bytes from `src` to `self`. The source + /// Copies `count * size_of::()` bytes from `src` to `self`. The source /// and destination may overlap. /// /// NOTE: this has the *opposite* argument order of [`ptr::copy`]. @@ -1457,7 +1457,7 @@ impl *mut T { unsafe { copy(src, self, count) } } - /// Copies `count * size_of` bytes from `src` to `self`. The source + /// Copies `count * size_of::()` bytes from `src` to `self`. The source /// and destination may *not* overlap. /// /// NOTE: this has the *opposite* argument order of [`ptr::copy_nonoverlapping`]. diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 7c567d522c55..c769ba673c61 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -988,7 +988,7 @@ impl NonNull { unsafe { ptr::read_unaligned(self.as_ptr()) } } - /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// Copies `count * size_of::()` bytes from `self` to `dest`. The source /// and destination may overlap. /// /// NOTE: this has the *same* argument order as [`ptr::copy`]. @@ -1008,7 +1008,7 @@ impl NonNull { unsafe { ptr::copy(self.as_ptr(), dest.as_ptr(), count) } } - /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// Copies `count * size_of::()` bytes from `self` to `dest`. The source /// and destination may *not* overlap. /// /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`]. @@ -1028,7 +1028,7 @@ impl NonNull { unsafe { ptr::copy_nonoverlapping(self.as_ptr(), dest.as_ptr(), count) } } - /// Copies `count * size_of` bytes from `src` to `self`. The source + /// Copies `count * size_of::()` bytes from `src` to `self`. The source /// and destination may overlap. /// /// NOTE: this has the *opposite* argument order of [`ptr::copy`]. @@ -1048,7 +1048,7 @@ impl NonNull { unsafe { ptr::copy(src.as_ptr(), self.as_ptr(), count) } } - /// Copies `count * size_of` bytes from `src` to `self`. The source + /// Copies `count * size_of::()` bytes from `src` to `self`. The source /// and destination may *not* overlap. /// /// NOTE: this has the *opposite* argument order of [`ptr::copy_nonoverlapping`]. From f68fd669f3d7a0847b5c2f3b789b6c95db0acdc1 Mon Sep 17 00:00:00 2001 From: Tongjun Gao Date: Fri, 7 Mar 2025 13:24:14 +0800 Subject: [PATCH 781/991] Fix logical error in relevance scoring implementation --- src/tools/rust-analyzer/crates/ide-completion/src/item.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs index ea52d69c7952..294fbde1b6d5 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs @@ -252,14 +252,14 @@ impl CompletionRelevance { /// Provides a relevance score. Higher values are more relevant. /// /// The absolute value of the relevance score is not meaningful, for - /// example a value of 0 doesn't mean "not relevant", rather + /// example a value of (!(0 as u32) / 2) doesn't mean "not relevant", rather /// it means "least relevant". The score value should only be used /// for relative ordering. /// /// See is_relevant if you need to make some judgement about score /// in an absolute sense. pub fn score(self) -> u32 { - let mut score = !0 / 2; + let mut score = !(0 as u32) / 2; let CompletionRelevance { exact_name_match, type_match, @@ -350,7 +350,7 @@ impl CompletionRelevance { /// some threshold such that we think it is especially likely /// to be relevant. pub fn is_relevant(&self) -> bool { - self.score() > (!0 / 2) + self.score() > !(0 as u32) / 2 } } From d9432acfe12dfb44a88d186875cc105b1b93301f Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 23 Feb 2025 14:23:25 -0800 Subject: [PATCH 782/991] Use `trunc nuw`+`br` for 0/1 branches even in optimized builds Rather than needing to use `switch` for them to include the `unreachable` arm --- compiler/rustc_codegen_ssa/src/mir/block.rs | 34 +++++++++++++ tests/codegen/enum/enum-two-variants-match.rs | 51 +++++++++++++++++++ tests/codegen/intrinsics/cold_path2.rs | 3 +- tests/codegen/issues/issue-101082.rs | 1 + .../issue-122600-ptr-discriminant-update.rs | 29 +++++++++-- tests/codegen/try_question_mark_nop.rs | 8 +-- 6 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 tests/codegen/enum/enum-two-variants-match.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e2a9b540d306..6d1930a402d3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -3,6 +3,7 @@ use std::cmp; use rustc_abi::{BackendRepr, ExternAbi, HasDataLayout, Reg, WrappingRange}; use rustc_ast as ast; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_data_structures::packed::Pu128; use rustc_hir::lang_items::LangItem; use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; @@ -406,6 +407,39 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let cmp = bx.icmp(IntPredicate::IntEQ, discr_value, llval); bx.cond_br_with_expect(cmp, lltarget, llotherwise, expect); } + } else if target_iter.len() == 2 + && self.mir[targets.otherwise()].is_empty_unreachable() + && targets.all_values().contains(&Pu128(0)) + && targets.all_values().contains(&Pu128(1)) + { + // This is the really common case for `bool`, `Option`, etc. + // By using `trunc nuw` we communicate that other values are + // impossible without needing `switch` or `assume`s. + let true_bb = targets.target_for_value(1); + let false_bb = targets.target_for_value(0); + let true_ll = helper.llbb_with_cleanup(self, true_bb); + let false_ll = helper.llbb_with_cleanup(self, false_bb); + + let expected_cond_value = if self.cx.sess().opts.optimize == OptLevel::No { + None + } else { + match (self.cold_blocks[true_bb], self.cold_blocks[false_bb]) { + // Same coldness, no expectation + (true, true) | (false, false) => None, + // Different coldness, expect the non-cold one + (true, false) => Some(false), + (false, true) => Some(true), + } + }; + + let bool_ty = bx.tcx().types.bool; + let cond = if switch_ty == bool_ty { + discr_value + } else { + let bool_llty = bx.immediate_backend_type(bx.layout_of(bool_ty)); + bx.unchecked_utrunc(discr_value, bool_llty) + }; + bx.cond_br_with_expect(cond, true_ll, false_ll, expected_cond_value); } else if self.cx.sess().opts.optimize == OptLevel::No && target_iter.len() == 2 && self.mir[targets.otherwise()].is_empty_unreachable() diff --git a/tests/codegen/enum/enum-two-variants-match.rs b/tests/codegen/enum/enum-two-variants-match.rs new file mode 100644 index 000000000000..e5978bfc7615 --- /dev/null +++ b/tests/codegen/enum/enum-two-variants-match.rs @@ -0,0 +1,51 @@ +//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes +//@ min-llvm-version: 19 (for trunc nuw) +//@ only-x86_64 (because these discriminants are isize) + +#![crate_type = "lib"] + +// CHECK-LABEL: @option_match +#[no_mangle] +pub fn option_match(x: Option) -> u16 { + // CHECK: %x = alloca [8 x i8] + // CHECK: store i32 %0, ptr %x + // CHECK: %[[TAG:.+]] = load i32, ptr %x + // CHECK-SAME: !range ![[ZERO_ONE_32:[0-9]+]] + // CHECK: %[[DISCR:.+]] = zext i32 %[[TAG]] to i64 + // CHECK: %[[COND:.+]] = trunc nuw i64 %[[DISCR]] to i1 + // CHECK: br i1 %[[COND]], label %[[TRUE:[a-z0-9]+]], label %[[FALSE:[a-z0-9]+]] + + // CHECK: [[TRUE]]: + // CHECK: store i16 13 + + // CHECK: [[FALSE]]: + // CHECK: store i16 42 + match x { + Some(_) => 13, + None => 42, + } +} + +// CHECK-LABEL: @result_match +#[no_mangle] +pub fn result_match(x: Result) -> u16 { + // CHECK: %x = alloca [16 x i8] + // CHECK: store i64 %0, ptr %x + // CHECK: %[[DISCR:.+]] = load i64, ptr %x + // CHECK-SAME: !range ![[ZERO_ONE_64:[0-9]+]] + // CHECK: %[[COND:.+]] = trunc nuw i64 %[[DISCR]] to i1 + // CHECK: br i1 %[[COND]], label %[[TRUE:[a-z0-9]+]], label %[[FALSE:[a-z0-9]+]] + + // CHECK: [[TRUE]]: + // CHECK: store i16 13 + + // CHECK: [[FALSE]]: + // CHECK: store i16 42 + match x { + Err(_) => 13, + Ok(_) => 42, + } +} + +// CHECK: ![[ZERO_ONE_32]] = !{i32 0, i32 2} +// CHECK: ![[ZERO_ONE_64]] = !{i64 0, i64 2} diff --git a/tests/codegen/intrinsics/cold_path2.rs b/tests/codegen/intrinsics/cold_path2.rs index 1e7e0478f4fd..54ee473e620b 100644 --- a/tests/codegen/intrinsics/cold_path2.rs +++ b/tests/codegen/intrinsics/cold_path2.rs @@ -26,7 +26,8 @@ pub fn test(x: Option) { } // CHECK-LABEL: @test( - // CHECK: br i1 %1, label %bb2, label %bb1, !prof ![[NUM:[0-9]+]] + // CHECK: %[[IS_NONE:.+]] = icmp eq i8 %0, 2 + // CHECK: br i1 %[[IS_NONE]], label %bb2, label %bb1, !prof ![[NUM:[0-9]+]] // CHECK: bb1: // CHECK: path_a // CHECK: bb2: diff --git a/tests/codegen/issues/issue-101082.rs b/tests/codegen/issues/issue-101082.rs index 048b69d207b6..7fb850ca2532 100644 --- a/tests/codegen/issues/issue-101082.rs +++ b/tests/codegen/issues/issue-101082.rs @@ -1,5 +1,6 @@ //@ compile-flags: -Copt-level=3 //@ revisions: host x86-64-v3 +//@ min-llvm-version: 20 // This particular CPU regressed in #131563 //@[x86-64-v3] only-x86_64 diff --git a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs index fdb8f06df800..fbea4ee8979f 100644 --- a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs +++ b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs @@ -3,6 +3,11 @@ #![crate_type = "lib"] +// The bug here was that it was loading and storing the whole value. +// It's ok for it to load the discriminant, +// to preserve the UB from `unreachable_unchecked`, +// but it better only store the constant discriminant of `B`. + pub enum State { A([u8; 753]), B([u8; 753]), @@ -11,9 +16,27 @@ pub enum State { // CHECK-LABEL: @update #[no_mangle] pub unsafe fn update(s: *mut State) { - // CHECK-NEXT: start: - // CHECK-NEXT: store i8 - // CHECK-NEXT: ret + // CHECK-NOT: alloca + + // CHECK-NOT: load + // CHECK-NOT: store + // CHECK-NOT: memcpy + // CHECK-NOT: 75{{3|4}} + + // CHECK: %[[TAG:.+]] = load i8, ptr %s, align 1 + // CHECK-NEXT: trunc nuw i8 %[[TAG]] to i1 + + // CHECK-NOT: load + // CHECK-NOT: store + // CHECK-NOT: memcpy + // CHECK-NOT: 75{{3|4}} + + // CHECK: store i8 1, ptr %s, align 1 + + // CHECK-NOT: load + // CHECK-NOT: store + // CHECK-NOT: memcpy + // CHECK-NOT: 75{{3|4}} let State::A(v) = s.read() else { std::hint::unreachable_unchecked() }; s.write(State::B(v)); } diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs index 751d7ca93116..ca15e5101734 100644 --- a/tests/codegen/try_question_mark_nop.rs +++ b/tests/codegen/try_question_mark_nop.rs @@ -16,8 +16,8 @@ use std::ptr::NonNull; #[no_mangle] pub fn option_nop_match_32(x: Option) -> Option { // CHECK: start: - // TWENTY-NEXT: %trunc = trunc nuw i32 %0 to i1 - // TWENTY-NEXT: %.2 = select i1 %trunc, i32 %1, i32 undef + // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1 + // TWENTY-NEXT: %.2 = select i1 %[[IS_SOME]], i32 %1, i32 undef // CHECK-NEXT: [[REG1:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0 // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1 // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %.2, 1 @@ -32,8 +32,8 @@ pub fn option_nop_match_32(x: Option) -> Option { #[no_mangle] pub fn option_nop_traits_32(x: Option) -> Option { // CHECK: start: - // TWENTY-NEXT: %trunc = trunc nuw i32 %0 to i1 - // TWENTY-NEXT: %.1 = select i1 %trunc, i32 %1, i32 undef + // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1 + // TWENTY-NEXT: %.1 = select i1 %[[IS_SOME]], i32 %1, i32 undef // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: ret { i32, i32 } From 422705573c28708c6f4befeacaec442f6140be5c Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 7 Mar 2025 09:41:29 +0300 Subject: [PATCH 783/991] use target compiler on llvm-bitcode-linker The build compiler is already resolved inside the `ToolBuild` step, so we should pass only the target compilers for `Mode::ToolRustc` tools. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 782195007374..26c5c2bf411b 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1991,12 +1991,12 @@ impl Step for Assemble { } } - let maybe_install_llvm_bitcode_linker = |compiler| { + let maybe_install_llvm_bitcode_linker = || { if builder.config.llvm_bitcode_linker_enabled { trace!("llvm-bitcode-linker enabled, installing"); let llvm_bitcode_linker = builder.ensure(crate::core::build_steps::tool::LlvmBitcodeLinker { - compiler, + compiler: target_compiler, target: target_compiler.host, extra_features: vec![], }); @@ -2020,7 +2020,7 @@ impl Step for Assemble { builder.info(&format!("Creating a sysroot for stage{stage} compiler (use `rustup toolchain link 'name' build/host/stage{stage}`)", stage=target_compiler.stage)); } - maybe_install_llvm_bitcode_linker(target_compiler); + maybe_install_llvm_bitcode_linker(); return target_compiler; } @@ -2203,7 +2203,7 @@ impl Step for Assemble { ); } - maybe_install_llvm_bitcode_linker(build_compiler); + maybe_install_llvm_bitcode_linker(); // Ensure that `libLLVM.so` ends up in the newly build compiler directory, // so that it can be found when the newly built `rustc` is run. From 16878eb02a27e5d8a4520851d88c33bd34170695 Mon Sep 17 00:00:00 2001 From: Tongjun Gao Date: Fri, 7 Mar 2025 14:44:57 +0800 Subject: [PATCH 784/991] Refactor relevance scoring to use a named constant BASE_SCORE Replace magic number with a named constant for improved readability and maintainability of the scoring logic --- src/tools/rust-analyzer/crates/ide-completion/src/item.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs index 294fbde1b6d5..8d6dc4c80130 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs @@ -252,14 +252,16 @@ impl CompletionRelevance { /// Provides a relevance score. Higher values are more relevant. /// /// The absolute value of the relevance score is not meaningful, for - /// example a value of (!(0 as u32) / 2) doesn't mean "not relevant", rather + /// example a value of BASE_SCORE doesn't mean "not relevant", rather /// it means "least relevant". The score value should only be used /// for relative ordering. /// /// See is_relevant if you need to make some judgement about score /// in an absolute sense. + const BASE_SCORE: u32 = u32::MAX / 2; + pub fn score(self) -> u32 { - let mut score = !(0 as u32) / 2; + let mut score = Self::BASE_SCORE; let CompletionRelevance { exact_name_match, type_match, @@ -350,7 +352,7 @@ impl CompletionRelevance { /// some threshold such that we think it is especially likely /// to be relevant. pub fn is_relevant(&self) -> bool { - self.score() > !(0 as u32) / 2 + self.score() > Self::BASE_SCORE } } From c8d9d5a930cbe7a357cfa4ecc23d9a871b8fefee Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 7 Mar 2025 07:38:10 +0100 Subject: [PATCH 785/991] Move project MSRV back to 1.78 --- .../crates/project-model/src/project_json.rs | 2 +- .../crates/project-model/src/sysroot.rs | 137 +++++ .../crates/project-model/src/workspace.rs | 56 ++ .../output/rust_project_cfg_groups.txt | 501 +++++++++++++++++- ...rust_project_hello_world_project_model.txt | 454 +++++++++++++++- .../crates/rust-analyzer/src/lib.rs | 2 +- 6 files changed, 1145 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index 0282a714645b..b2df8e4703ab 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -86,7 +86,7 @@ impl ProjectJson { /// * `manifest` - The path to the `rust-project.json`. /// * `base` - The path to the workspace root (i.e. the folder containing `rust-project.json`) /// * `data` - The parsed contents of `rust-project.json`, or project json that's passed via - /// configuration. + /// configuration. pub fn new( manifest: Option, base: &AbsPath, diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs index 1e3c5a94786f..13812e96fe7a 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs @@ -30,6 +30,7 @@ pub struct Sysroot { pub enum RustLibSrcWorkspace { Workspace(CargoWorkspace), Json(ProjectJson), + Stitched(stitched::Stitched), Empty, } @@ -60,6 +61,7 @@ impl Sysroot { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().next().is_none(), RustLibSrcWorkspace::Json(project_json) => project_json.n_crates() == 0, + RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.is_empty(), RustLibSrcWorkspace::Empty => true, } } @@ -72,6 +74,7 @@ impl Sysroot { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().count(), RustLibSrcWorkspace::Json(project_json) => project_json.n_crates(), + RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.len(), RustLibSrcWorkspace::Empty => 0, } } @@ -197,6 +200,51 @@ impl Sysroot { return Some(loaded); } } + tracing::debug!("Stitching sysroot library: {src_root}"); + + let mut stitched = stitched::Stitched { crates: Default::default() }; + + for path in stitched::SYSROOT_CRATES.trim().lines() { + let name = path.split('/').next_back().unwrap(); + let root = [format!("{path}/src/lib.rs"), format!("lib{path}/lib.rs")] + .into_iter() + .map(|it| src_root.join(it)) + .filter_map(|it| ManifestPath::try_from(it).ok()) + .find(|it| fs::metadata(it).is_ok()); + + if let Some(root) = root { + stitched.crates.alloc(stitched::RustLibSrcCrateData { + name: name.into(), + root, + deps: Vec::new(), + }); + } + } + + if let Some(std) = stitched.by_name("std") { + for dep in stitched::STD_DEPS.trim().lines() { + if let Some(dep) = stitched.by_name(dep) { + stitched.crates[std].deps.push(dep) + } + } + } + + if let Some(alloc) = stitched.by_name("alloc") { + for dep in stitched::ALLOC_DEPS.trim().lines() { + if let Some(dep) = stitched.by_name(dep) { + stitched.crates[alloc].deps.push(dep) + } + } + } + + if let Some(proc_macro) = stitched.by_name("proc_macro") { + for dep in stitched::PROC_MACRO_DEPS.trim().lines() { + if let Some(dep) = stitched.by_name(dep) { + stitched.crates[proc_macro].deps.push(dep) + } + } + } + return Some(RustLibSrcWorkspace::Stitched(stitched)); } else if let RustSourceWorkspaceConfig::Json(project_json) = sysroot_source_config { return Some(RustLibSrcWorkspace::Json(project_json.clone())); } @@ -216,6 +264,7 @@ impl Sysroot { .crates() .filter_map(|(_, krate)| krate.display_name.clone()) .any(|name| name.canonical_name().as_str() == "core"), + RustLibSrcWorkspace::Stitched(stitched) => stitched.by_name("core").is_some(), RustLibSrcWorkspace::Empty => true, }; if !has_core { @@ -391,3 +440,91 @@ fn get_rust_lib_src(sysroot_path: &AbsPath) -> Option { None } } + +// FIXME: Remove this, that will bump our project MSRV to 1.82 +pub(crate) mod stitched { + use std::ops; + + use base_db::CrateName; + use la_arena::{Arena, Idx}; + + use crate::ManifestPath; + + #[derive(Debug, Clone, Eq, PartialEq)] + pub struct Stitched { + pub(super) crates: Arena, + } + + impl ops::Index for Stitched { + type Output = RustLibSrcCrateData; + fn index(&self, index: RustLibSrcCrate) -> &RustLibSrcCrateData { + &self.crates[index] + } + } + + impl Stitched { + pub(crate) fn public_deps( + &self, + ) -> impl Iterator + '_ { + // core is added as a dependency before std in order to + // mimic rustcs dependency order + [("core", true), ("alloc", false), ("std", true), ("test", false)] + .into_iter() + .filter_map(move |(name, prelude)| { + Some((CrateName::new(name).unwrap(), self.by_name(name)?, prelude)) + }) + } + + pub(crate) fn proc_macro(&self) -> Option { + self.by_name("proc_macro") + } + + pub(crate) fn crates(&self) -> impl ExactSizeIterator + '_ { + self.crates.iter().map(|(id, _data)| id) + } + + pub(super) fn by_name(&self, name: &str) -> Option { + let (id, _data) = self.crates.iter().find(|(_id, data)| data.name == name)?; + Some(id) + } + } + + pub(crate) type RustLibSrcCrate = Idx; + + #[derive(Debug, Clone, Eq, PartialEq)] + pub(crate) struct RustLibSrcCrateData { + pub(crate) name: String, + pub(crate) root: ManifestPath, + pub(crate) deps: Vec, + } + + pub(super) const SYSROOT_CRATES: &str = " +alloc +backtrace +core +panic_abort +panic_unwind +proc_macro +profiler_builtins +std +stdarch/crates/std_detect +test +unwind"; + + pub(super) const ALLOC_DEPS: &str = "core"; + + pub(super) const STD_DEPS: &str = " +alloc +panic_unwind +panic_abort +core +profiler_builtins +unwind +std_detect +test"; + + // core is required for our builtin derives to work in the proc_macro lib currently + pub(super) const PROC_MACRO_DEPS: &str = " +std +core"; +} diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 89818be8d470..62c13c7d9ec8 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -692,6 +692,7 @@ impl ProjectWorkspace { exclude: krate.exclude.clone(), }) .collect(), + RustLibSrcWorkspace::Stitched(_) => vec![], RustLibSrcWorkspace::Empty => vec![], }; @@ -1630,7 +1631,62 @@ fn sysroot_to_crate_graph( extend_crate_graph_with_sysroot(crate_graph, cg, pm) } + RustLibSrcWorkspace::Stitched(stitched) => { + let cfg_options = Arc::new({ + let mut cfg_options = CfgOptions::default(); + cfg_options.extend(rustc_cfg); + cfg_options.insert_atom(sym::debug_assertions.clone()); + cfg_options.insert_atom(sym::miri.clone()); + cfg_options + }); + let sysroot_crates: FxHashMap = + stitched + .crates() + .filter_map(|krate| { + let file_id = load(&stitched[krate].root)?; + let display_name = + CrateDisplayName::from_canonical_name(&stitched[krate].name); + let crate_id = crate_graph.add_crate_root( + file_id, + Edition::CURRENT_FIXME, + Some(display_name), + None, + cfg_options.clone(), + None, + Env::default(), + CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)), + false, + None, + ); + Some((krate, crate_id)) + }) + .collect(); + + for from in stitched.crates() { + for &to in stitched[from].deps.iter() { + let name = CrateName::new(&stitched[to].name).unwrap(); + if let (Some(&from), Some(&to)) = + (sysroot_crates.get(&from), sysroot_crates.get(&to)) + { + add_dep(crate_graph, from, name, to); + } + } + } + + let public_deps = SysrootPublicDeps { + deps: stitched + .public_deps() + .filter_map(|(name, idx, prelude)| { + Some((name, *sysroot_crates.get(&idx)?, prelude)) + }) + .collect::>(), + }; + + let libproc_macro = + stitched.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); + (public_deps, libproc_macro) + } RustLibSrcWorkspace::Empty => (SysrootPublicDeps { deps: vec![] }, None), } } diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt index 28ca4eb53487..9b4be19c41c8 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt @@ -3,6 +3,417 @@ root_file_id: FileId( 1, ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "alloc", + ), + canonical_name: "alloc", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + Alloc, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 1: CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "core", + ), + canonical_name: "core", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Core, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 2: CrateData { + root_file_id: FileId( + 3, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "panic_abort", + ), + canonical_name: "panic_abort", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 3: CrateData { + root_file_id: FileId( + 4, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "panic_unwind", + ), + canonical_name: "panic_unwind", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 4: CrateData { + root_file_id: FileId( + 5, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "proc_macro", + ), + canonical_name: "proc_macro", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [ + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + ProcMacro, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 5: CrateData { + root_file_id: FileId( + 6, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "profiler_builtins", + ), + canonical_name: "profiler_builtins", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 6: CrateData { + root_file_id: FileId( + 7, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "std", + ), + canonical_name: "std", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(3), + name: CrateName( + "panic_unwind", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(2), + name: CrateName( + "panic_abort", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(5), + name: CrateName( + "profiler_builtins", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(9), + name: CrateName( + "unwind", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(7), + name: CrateName( + "std_detect", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + Std, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 7: CrateData { + root_file_id: FileId( + 8, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "std_detect", + ), + canonical_name: "std_detect", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 8: CrateData { + root_file_id: FileId( + 9, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "test", + ), + canonical_name: "test", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Test, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 9: CrateData { + root_file_id: FileId( + 10, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "unwind", + ), + canonical_name: "unwind", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 10: CrateData { + root_file_id: FileId( + 11, + ), edition: Edition2018, version: None, display_name: Some( @@ -27,7 +438,48 @@ env: Env { entries: {}, }, - dependencies: [], + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "proc_macro", + ), + prelude: false, + sysroot: true, + }, + ], origin: Local { repo: None, name: Some( @@ -37,9 +489,9 @@ is_proc_macro: false, proc_macro_cwd: None, }, - 1: CrateData { + 11: CrateData { root_file_id: FileId( - 1, + 11, ), edition: Edition2018, version: None, @@ -65,7 +517,48 @@ env: Env { entries: {}, }, - dependencies: [], + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "proc_macro", + ), + prelude: false, + sysroot: true, + }, + ], origin: Local { repo: None, name: Some( diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt index dde8d3023dc2..4c8e66e8e968 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt @@ -3,6 +3,417 @@ root_file_id: FileId( 1, ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "alloc", + ), + canonical_name: "alloc", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + Alloc, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 1: CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "core", + ), + canonical_name: "core", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Core, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 2: CrateData { + root_file_id: FileId( + 3, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "panic_abort", + ), + canonical_name: "panic_abort", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 3: CrateData { + root_file_id: FileId( + 4, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "panic_unwind", + ), + canonical_name: "panic_unwind", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 4: CrateData { + root_file_id: FileId( + 5, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "proc_macro", + ), + canonical_name: "proc_macro", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [ + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + ProcMacro, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 5: CrateData { + root_file_id: FileId( + 6, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "profiler_builtins", + ), + canonical_name: "profiler_builtins", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 6: CrateData { + root_file_id: FileId( + 7, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "std", + ), + canonical_name: "std", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [ + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(3), + name: CrateName( + "panic_unwind", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(2), + name: CrateName( + "panic_abort", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(5), + name: CrateName( + "profiler_builtins", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(9), + name: CrateName( + "unwind", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(7), + name: CrateName( + "std_detect", + ), + prelude: true, + sysroot: false, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: true, + sysroot: false, + }, + ], + origin: Lang( + Std, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 7: CrateData { + root_file_id: FileId( + 8, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "std_detect", + ), + canonical_name: "std_detect", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 8: CrateData { + root_file_id: FileId( + 9, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "test", + ), + canonical_name: "test", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Test, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 9: CrateData { + root_file_id: FileId( + 10, + ), + edition: Edition2021, + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "unwind", + ), + canonical_name: "unwind", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "miri", + "true", + ], + ), + potential_cfg_options: None, + env: Env { + entries: {}, + }, + dependencies: [], + origin: Lang( + Other, + ), + is_proc_macro: false, + proc_macro_cwd: None, + }, + 10: CrateData { + root_file_id: FileId( + 11, + ), edition: Edition2018, version: None, display_name: Some( @@ -24,7 +435,48 @@ env: Env { entries: {}, }, - dependencies: [], + dependencies: [ + Dependency { + crate_id: Idx::(1), + name: CrateName( + "core", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(0), + name: CrateName( + "alloc", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(6), + name: CrateName( + "std", + ), + prelude: true, + sysroot: true, + }, + Dependency { + crate_id: Idx::(8), + name: CrateName( + "test", + ), + prelude: false, + sysroot: true, + }, + Dependency { + crate_id: Idx::(4), + name: CrateName( + "proc_macro", + ), + prelude: false, + sysroot: true, + }, + ], origin: Local { repo: None, name: Some( diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index b9e38f2e6917..a0d6a0d6da6f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -12,7 +12,7 @@ /// Any toolchain less than this version will likely not work with rust-analyzer built from this revision. pub const MINIMUM_SUPPORTED_TOOLCHAIN_VERSION: semver::Version = semver::Version { major: 1, - minor: 82, + minor: 78, patch: 0, pre: semver::Prerelease::EMPTY, build: semver::BuildMetadata::EMPTY, From 5c6a1247fb7075682798f5b0d68823759fca571b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 7 Mar 2025 07:49:36 +0100 Subject: [PATCH 786/991] Pop up a notification for the MSRV project loading warning --- .../crates/rust-analyzer/src/global_state.rs | 19 ++++++++++++++ .../crates/rust-analyzer/src/reload.rs | 26 +++++++------------ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 70105cda006b..54670b675984 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -637,6 +637,25 @@ impl GlobalState { } }); } + + pub(crate) fn check_workspaces_msrv(&self) -> impl Iterator + '_ { + self.workspaces.iter().filter_map(|ws| { + if let Some(toolchain) = &ws.toolchain { + if *toolchain < crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION { + return Some(format!( + "Workspace `{}` is using an outdated toolchain version `{}` but \ + rust-analyzer only supports `{}` and higher.\n\ + Consider using the rust-analyzer rustup component for your toolchain or + upgrade your toolchain to a supported version.\n\n", + ws.manifest_or_root(), + toolchain, + crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION, + )); + } + } + None + }) + } } impl Drop for GlobalState { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 733a7c359b8e..dffaa88240b1 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -178,26 +178,15 @@ impl GlobalState { } if !self.workspaces.is_empty() { + self.check_workspaces_msrv().for_each(|e| { + status.health |= lsp_ext::Health::Warning; + format_to!(message, "{e}"); + }); + let proc_macro_clients = self.proc_macro_clients.iter().map(Some).chain(iter::repeat_with(|| None)); for (ws, proc_macro_client) in self.workspaces.iter().zip(proc_macro_clients) { - if let Some(toolchain) = &ws.toolchain { - if *toolchain < crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION { - status.health |= lsp_ext::Health::Warning; - format_to!( - message, - "Workspace `{}` is using an outdated toolchain version `{}` but \ - rust-analyzer only supports `{}` and higher.\n\ - Consider using the rust-analyzer rustup component for your toolchain or - upgrade your toolchain to a supported version.\n\n", - ws.manifest_or_root(), - toolchain, - crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION, - ); - } - } - if let ProjectWorkspaceKind::Cargo { error: Some(error), .. } | ProjectWorkspaceKind::DetachedFile { cargo: Some((_, _, Some(error))), .. @@ -529,6 +518,11 @@ impl GlobalState { // we don't care about build-script results, they are stale. // FIXME: can we abort the build scripts here if they are already running? self.workspaces = Arc::new(workspaces); + self.check_workspaces_msrv().for_each(|message| { + self.send_notification::( + lsp_types::ShowMessageParams { typ: lsp_types::MessageType::WARNING, message }, + ); + }); if self.config.run_build_scripts(None) { self.build_deps_changed = false; From 8814679a5410b8d9ce8385094ec8ec888395b1a5 Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Thu, 6 Mar 2025 22:52:20 -0800 Subject: [PATCH 787/991] rename Triple to Target --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 6d01095cccad..53df59930f4f 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -152,11 +152,11 @@ extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) { } extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M, - const char *Triple) { + const char *Target) { #if LLVM_VERSION_GE(21, 0) - unwrap(M)->setTargetTriple(llvm::Triple(Triple::normalize(Triple))); + unwrap(M)->setTargetTriple(Triple(Triple::normalize(Target))); #else - unwrap(M)->setTargetTriple(Triple::normalize(Triple)); + unwrap(M)->setTargetTriple(Triple::normalize(Target)); #endif } From 872ac73f59465ccaf63f74fd12785c583d3aa0a6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 7 Mar 2025 17:02:33 +1100 Subject: [PATCH 788/991] Move `visit_id` calls. In `walk_item`, we call `visit_id` on every item kind. For most of them we do it directly in `walk_item`. But for `ItemKind::Mod`, `ItemKind::Enum`, and `ItemKind::Use` we instead do it in the `walk_*` function called (via the `visit_*` function) from `walk_item`. I can see no reason for this inconsistency, so this commit makes those three cases like all the other cases, moving the `visit_id` calls into `walk_item`. This also avoids the need for a few `HirId` arguments. --- compiler/rustc_hir/src/intravisit.rs | 25 +++++++++--------------- compiler/rustc_lint/src/late.rs | 2 +- compiler/rustc_middle/src/hir/map.rs | 2 +- compiler/rustc_passes/src/input_stats.rs | 4 ++-- src/librustdoc/html/render/span_map.rs | 2 +- 5 files changed, 14 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 41eb5b45bd1e..0aa07d96b3de 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -316,8 +316,8 @@ pub trait Visitor<'v>: Sized { fn visit_ident(&mut self, ident: Ident) -> Self::Result { walk_ident(self, ident) } - fn visit_mod(&mut self, m: &'v Mod<'v>, _s: Span, n: HirId) -> Self::Result { - walk_mod(self, m, n) + fn visit_mod(&mut self, m: &'v Mod<'v>, _s: Span, _n: HirId) -> Self::Result { + walk_mod(self, m) } fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) -> Self::Result { walk_foreign_item(self, i) @@ -464,8 +464,8 @@ pub trait Visitor<'v>: Sized { fn visit_field_def(&mut self, s: &'v FieldDef<'v>) -> Self::Result { walk_field_def(self, s) } - fn visit_enum_def(&mut self, enum_definition: &'v EnumDef<'v>, item_id: HirId) -> Self::Result { - walk_enum_def(self, enum_definition, item_id) + fn visit_enum_def(&mut self, enum_definition: &'v EnumDef<'v>) -> Self::Result { + walk_enum_def(self, enum_definition) } fn visit_variant(&mut self, v: &'v Variant<'v>) -> Self::Result { walk_variant(self, v) @@ -539,6 +539,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: visit_opt!(visitor, visit_name, orig_name); } ItemKind::Use(ref path, _) => { + try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_use(path, item.hir_id())); } ItemKind::Static(ref typ, _, body) => { @@ -566,7 +567,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_id(item.hir_id())); } ItemKind::Mod(ref module) => { - // `visit_mod()` takes care of visiting the `Item`'s `HirId`. + try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_mod(module, item.span, item.hir_id())); } ItemKind::ForeignMod { abi: _, items } => { @@ -587,9 +588,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_generics(generics)); } ItemKind::Enum(ref enum_definition, ref generics) => { + try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_generics(generics)); - // `visit_enum_def()` takes care of visiting the `Item`'s `HirId`. - try_visit!(visitor.visit_enum_def(enum_definition, item.hir_id())); + try_visit!(visitor.visit_enum_def(enum_definition)); } ItemKind::Impl(Impl { constness: _, @@ -638,12 +639,7 @@ pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) -> V::Resul visitor.visit_name(ident.name) } -pub fn walk_mod<'v, V: Visitor<'v>>( - visitor: &mut V, - module: &'v Mod<'v>, - mod_hir_id: HirId, -) -> V::Result { - try_visit!(visitor.visit_id(mod_hir_id)); +pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>) -> V::Result { walk_list!(visitor, visit_nested_item, module.item_ids.iter().copied()); V::Result::output() } @@ -1145,7 +1141,6 @@ pub fn walk_use<'v, V: Visitor<'v>>( path: &'v UsePath<'v>, hir_id: HirId, ) -> V::Result { - try_visit!(visitor.visit_id(hir_id)); let UsePath { segments, ref res, span } = *path; for &res in res { try_visit!(visitor.visit_path(&Path { segments, res, span }, hir_id)); @@ -1326,9 +1321,7 @@ pub fn walk_field_def<'v, V: Visitor<'v>>( pub fn walk_enum_def<'v, V: Visitor<'v>>( visitor: &mut V, enum_definition: &'v EnumDef<'v>, - item_id: HirId, ) -> V::Result { - try_visit!(visitor.visit_id(item_id)); walk_list!(visitor, visit_variant, enum_definition.variants); V::Result::output() } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index d22515d62d60..23d6efa05083 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -74,7 +74,7 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { fn process_mod(&mut self, m: &'tcx hir::Mod<'tcx>, n: HirId) { lint_callback!(self, check_mod, m, n); - hir_visit::walk_mod(self, m, n); + hir_visit::walk_mod(self, m); } } diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index fad8c7dcbcbc..c85af81ee25b 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1356,7 +1356,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { self.submodules.push(item.owner_id); // A module collector does not recurse inside nested modules. if self.crate_collector { - intravisit::walk_mod(self, module, item.hir_id()); + intravisit::walk_mod(self, module); } } else { intravisit::walk_item(self, item) diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 92ea49f18e5d..8ff11197e09d 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -255,9 +255,9 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_body(self, b); } - fn visit_mod(&mut self, m: &'v hir::Mod<'v>, _s: Span, n: HirId) { + fn visit_mod(&mut self, m: &'v hir::Mod<'v>, _s: Span, _n: HirId) { self.record("Mod", None, m); - hir_visit::walk_mod(self, m, n) + hir_visit::walk_mod(self, m) } fn visit_foreign_item(&mut self, i: &'v hir::ForeignItem<'v>) { diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index ce9c42c01cc7..bd8427261800 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -253,7 +253,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { // If it's a "mod foo {}", we want to look to its documentation page. self.extract_info_from_hir_id(id); } - intravisit::walk_mod(self, m, id); + intravisit::walk_mod(self, m); } fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) { From 8a981241fe86dfac2e8212638c87bbaf1ae53264 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 7 Mar 2025 17:37:23 +1100 Subject: [PATCH 789/991] Factor out repeated `visit_id` calls. Every `ItemKind` now has one. --- compiler/rustc_hir/src/intravisit.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 0aa07d96b3de..be9f490edcce 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -532,29 +532,25 @@ pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) -> } pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::Result { + try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_ident(item.ident)); match item.kind { ItemKind::ExternCrate(orig_name) => { - try_visit!(visitor.visit_id(item.hir_id())); visit_opt!(visitor, visit_name, orig_name); } ItemKind::Use(ref path, _) => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_use(path, item.hir_id())); } ItemKind::Static(ref typ, _, body) => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_ty_unambig(typ)); try_visit!(visitor.visit_nested_body(body)); } ItemKind::Const(ref typ, ref generics, body) => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_ty_unambig(typ)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_nested_body(body)); } ItemKind::Fn { sig, generics, body: body_id, .. } => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_fn( FnKind::ItemFn(item.ident, generics, sig.header), sig.decl, @@ -563,19 +559,14 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: item.owner_id.def_id, )); } - ItemKind::Macro(..) => { - try_visit!(visitor.visit_id(item.hir_id())); - } + ItemKind::Macro(..) => {} ItemKind::Mod(ref module) => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_mod(module, item.span, item.hir_id())); } ItemKind::ForeignMod { abi: _, items } => { - try_visit!(visitor.visit_id(item.hir_id())); walk_list!(visitor, visit_foreign_item_ref, items); } ItemKind::GlobalAsm { asm: _, fake_body } => { - try_visit!(visitor.visit_id(item.hir_id())); // Visit the fake body, which contains the asm statement. // Therefore we should not visit the asm statement again // outside of the body, or some visitors won't have their @@ -583,12 +574,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_nested_body(fake_body)); } ItemKind::TyAlias(ref ty, ref generics) => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_ty_unambig(ty)); try_visit!(visitor.visit_generics(generics)); } ItemKind::Enum(ref enum_definition, ref generics) => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_enum_def(enum_definition)); } @@ -603,7 +592,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: self_ty, items, }) => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_generics(generics)); visit_opt!(visitor, visit_trait_ref, of_trait); try_visit!(visitor.visit_ty_unambig(self_ty)); @@ -612,17 +600,14 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: ItemKind::Struct(ref struct_definition, ref generics) | ItemKind::Union(ref struct_definition, ref generics) => { try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_variant_data(struct_definition)); } ItemKind::Trait(.., ref generics, bounds, trait_item_refs) => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_trait_item_ref, trait_item_refs); } ItemKind::TraitAlias(ref generics, bounds) => { - try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds); } From d5da6b71fa7f29946a41d624e038c1c0eed8a4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 4 Mar 2025 18:26:11 +0100 Subject: [PATCH 790/991] Add post-merge analysis CI workflow --- .github/workflows/post-merge.yml | 36 +++++ src/build_helper/src/metrics.rs | 2 +- src/ci/citool/src/main.rs | 12 ++ src/ci/citool/src/merge_report.rs | 257 ++++++++++++++++++++++++++++++ src/ci/citool/src/metrics.rs | 22 +-- 5 files changed, 319 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/post-merge.yml create mode 100644 src/ci/citool/src/merge_report.rs diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml new file mode 100644 index 000000000000..d3f42c5a9052 --- /dev/null +++ b/.github/workflows/post-merge.yml @@ -0,0 +1,36 @@ +# Workflow that runs after a merge to master, analyses changes in test executions +# and posts the result to the merged PR. + +name: Post merge analysis + +on: + push: + branches: + - master + +jobs: + analysis: + runs-on: ubuntu-24.04 + if: github.repository == 'rust-lang/rust' + permissions: + pull-requests: write + steps: + - uses: actions/checkout@v4 + - name: Perform analysis and send PR + run: | + # Get closest bors merge commit + PARENT_COMMIT=`git rev-list --author='bors ' -n1 --first-parent HEAD^1` + + # Find PR for the current commit + HEAD_PR=`gh pr list --search "${{ github.sha }}" --state merged --json number --jq '.[0].number'` + + echo "Parent: ${PARENT_COMMIT}" + echo "HEAD: ${{ github.sha }} (#${HEAD_PR})" + + cd src/ci/citool + + echo "Post-merge analysis result" > output.log + cargo run --release post-merge-analysis ${PARENT_COMMIT} ${{ github.sha }} >> output.log + cat output.log + + gh pr comment ${HEAD_PR} -F output.log diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs index eb306550fc4a..b6daac32a441 100644 --- a/src/build_helper/src/metrics.rs +++ b/src/build_helper/src/metrics.rs @@ -74,7 +74,7 @@ pub struct Test { pub outcome: TestOutcome, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] #[serde(tag = "outcome", rename_all = "snake_case")] pub enum TestOutcome { Passed, diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 16edd6818864..52e7638d98bd 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -1,5 +1,6 @@ mod cpu_usage; mod datadog; +mod merge_report; mod metrics; mod utils; @@ -13,6 +14,7 @@ use serde_yaml::Value; use crate::cpu_usage::load_cpu_usage; use crate::datadog::upload_datadog_metric; +use crate::merge_report::post_merge_report; use crate::metrics::postprocess_metrics; use crate::utils::load_env_var; @@ -373,6 +375,13 @@ enum Args { /// Path to a CSV containing the CI job CPU usage. cpu_usage_csv: PathBuf, }, + /// Generate a report of test execution changes between two rustc commits. + PostMergeReport { + /// Parent commit to use as a base of the comparison. + parent: String, + /// Current commit that will be compared to `parent`. + current: String, + }, } #[derive(clap::ValueEnum, Clone)] @@ -410,6 +419,9 @@ fn main() -> anyhow::Result<()> { Args::PostprocessMetrics { metrics_path, summary_path } => { postprocess_metrics(&metrics_path, &summary_path)?; } + Args::PostMergeReport { current: commit, parent } => { + post_merge_report(load_db(default_jobs_file)?, parent, commit)?; + } } Ok(()) diff --git a/src/ci/citool/src/merge_report.rs b/src/ci/citool/src/merge_report.rs new file mode 100644 index 000000000000..5dd662280f0f --- /dev/null +++ b/src/ci/citool/src/merge_report.rs @@ -0,0 +1,257 @@ +use std::cmp::Reverse; +use std::collections::HashMap; + +use anyhow::Context; +use build_helper::metrics::{JsonRoot, TestOutcome}; + +use crate::JobDatabase; +use crate::metrics::get_test_suites; + +type Sha = String; +type JobName = String; + +/// Computes a post merge CI analysis report between the `parent` and `current` commits. +pub fn post_merge_report(job_db: JobDatabase, parent: Sha, current: Sha) -> anyhow::Result<()> { + let jobs = download_all_metrics(&job_db, &parent, ¤t)?; + let diffs = aggregate_test_diffs(&jobs)?; + report_test_changes(diffs); + + Ok(()) +} + +struct JobMetrics { + parent: Option, + current: JsonRoot, +} + +/// Download before/after metrics for all auto jobs in the job database. +fn download_all_metrics( + job_db: &JobDatabase, + parent: &str, + current: &str, +) -> anyhow::Result> { + let mut jobs = HashMap::default(); + + for job in &job_db.auto_jobs { + eprintln!("Downloading metrics of job {}", job.name); + let metrics_parent = match download_job_metrics(&job.name, parent) { + Ok(metrics) => Some(metrics), + Err(error) => { + eprintln!( + r#"Did not find metrics for job `{}` at `{}`: {error:?}. +Maybe it was newly added?"#, + job.name, parent + ); + None + } + }; + let metrics_current = download_job_metrics(&job.name, current)?; + jobs.insert( + job.name.clone(), + JobMetrics { parent: metrics_parent, current: metrics_current }, + ); + } + Ok(jobs) +} + +fn download_job_metrics(job_name: &str, sha: &str) -> anyhow::Result { + let url = get_metrics_url(job_name, sha); + let mut response = ureq::get(&url).call()?; + if !response.status().is_success() { + return Err(anyhow::anyhow!( + "Cannot fetch metrics from {url}: {}\n{}", + response.status(), + response.body_mut().read_to_string()? + )); + } + let data: JsonRoot = response + .body_mut() + .read_json() + .with_context(|| anyhow::anyhow!("cannot deserialize metrics from {url}"))?; + Ok(data) +} + +fn get_metrics_url(job_name: &str, sha: &str) -> String { + let suffix = if job_name.ends_with("-alt") { "-alt" } else { "" }; + format!("https://ci-artifacts.rust-lang.org/rustc-builds{suffix}/{sha}/metrics-{job_name}.json") +} + +fn aggregate_test_diffs( + jobs: &HashMap, +) -> anyhow::Result> { + let mut job_diffs = vec![]; + + // Aggregate test suites + for (name, metrics) in jobs { + if let Some(parent) = &metrics.parent { + let tests_parent = aggregate_tests(parent); + let tests_current = aggregate_tests(&metrics.current); + let test_diffs = calculate_test_diffs(tests_parent, tests_current); + if !test_diffs.is_empty() { + job_diffs.push((name.clone(), test_diffs)); + } + } + } + + // Aggregate jobs with the same diff, as often the same diff will appear in many jobs + let job_diffs: HashMap, Vec> = + job_diffs.into_iter().fold(HashMap::new(), |mut acc, (job, diffs)| { + acc.entry(diffs).or_default().push(job); + acc + }); + + Ok(job_diffs + .into_iter() + .map(|(test_diffs, jobs)| AggregatedTestDiffs { jobs, test_diffs }) + .collect()) +} + +fn calculate_test_diffs( + reference: TestSuiteData, + current: TestSuiteData, +) -> Vec<(Test, TestOutcomeDiff)> { + let mut diffs = vec![]; + for (test, outcome) in ¤t.tests { + match reference.tests.get(test) { + Some(before) => { + if before != outcome { + diffs.push(( + test.clone(), + TestOutcomeDiff::ChangeOutcome { + before: before.clone(), + after: outcome.clone(), + }, + )); + } + } + None => diffs.push((test.clone(), TestOutcomeDiff::Added(outcome.clone()))), + } + } + for (test, outcome) in &reference.tests { + if !current.tests.contains_key(test) { + diffs.push((test.clone(), TestOutcomeDiff::Missing { before: outcome.clone() })); + } + } + + diffs +} + +/// Represents a difference in the outcome of tests between a base and a current commit. +#[derive(Debug)] +struct AggregatedTestDiffs { + /// All jobs that had the exact same test diffs. + jobs: Vec, + test_diffs: Vec<(Test, TestOutcomeDiff)>, +} + +#[derive(Eq, PartialEq, Hash, Debug)] +enum TestOutcomeDiff { + ChangeOutcome { before: TestOutcome, after: TestOutcome }, + Missing { before: TestOutcome }, + Added(TestOutcome), +} + +/// Aggregates test suite executions from all bootstrap invocations in a given CI job. +#[derive(Default)] +struct TestSuiteData { + tests: HashMap, +} + +#[derive(Hash, PartialEq, Eq, Debug, Clone)] +struct Test { + name: String, +} + +/// Extracts all tests from the passed metrics and map them to their outcomes. +fn aggregate_tests(metrics: &JsonRoot) -> TestSuiteData { + let mut tests = HashMap::new(); + let test_suites = get_test_suites(&metrics); + for suite in test_suites { + for test in &suite.tests { + let test_entry = Test { name: normalize_test_name(&test.name) }; + tests.insert(test_entry, test.outcome.clone()); + } + } + TestSuiteData { tests } +} + +/// Normalizes Windows-style path delimiters to Unix-style paths. +fn normalize_test_name(name: &str) -> String { + name.replace('\\', "/") +} + +/// Prints test changes in Markdown format to stdout. +fn report_test_changes(mut diffs: Vec) { + println!("## Test differences"); + if diffs.is_empty() { + println!("No test diffs found"); + return; + } + + // Sort diffs in decreasing order by diff count + diffs.sort_by_key(|entry| Reverse(entry.test_diffs.len())); + + fn format_outcome(outcome: &TestOutcome) -> String { + match outcome { + TestOutcome::Passed => "pass".to_string(), + TestOutcome::Failed => "fail".to_string(), + TestOutcome::Ignored { ignore_reason } => { + let reason = match ignore_reason { + Some(reason) => format!(" ({reason})"), + None => String::new(), + }; + format!("ignore{reason}") + } + } + } + + fn format_diff(diff: &TestOutcomeDiff) -> String { + match diff { + TestOutcomeDiff::ChangeOutcome { before, after } => { + format!("{} -> {}", format_outcome(before), format_outcome(after)) + } + TestOutcomeDiff::Missing { before } => { + format!("{} -> [missing]", format_outcome(before)) + } + TestOutcomeDiff::Added(outcome) => { + format!("[missing] -> {}", format_outcome(outcome)) + } + } + } + + let max_diff_count = 10; + let max_job_count = 5; + let max_test_count = 10; + + for diff in diffs.iter().take(max_diff_count) { + let mut jobs = diff.jobs.clone(); + jobs.sort(); + + let jobs = jobs.iter().take(max_job_count).map(|j| format!("`{j}`")).collect::>(); + + let extra_jobs = diff.jobs.len().saturating_sub(max_job_count); + let suffix = if extra_jobs > 0 { + format!(" (and {extra_jobs} {})", pluralize("other", extra_jobs)) + } else { + String::new() + }; + println!("- {}{suffix}", jobs.join(",")); + + let extra_tests = diff.test_diffs.len().saturating_sub(max_test_count); + for (test, outcome_diff) in diff.test_diffs.iter().take(max_test_count) { + println!(" - {}: {}", test.name, format_diff(&outcome_diff)); + } + if extra_tests > 0 { + println!(" - (and {extra_tests} additional {})", pluralize("tests", extra_tests)); + } + } + + let extra_diffs = diffs.len().saturating_sub(max_diff_count); + if extra_diffs > 0 { + println!("\n(and {extra_diffs} additional {})", pluralize("diff", extra_diffs)); + } +} + +fn pluralize(text: &str, count: usize) -> String { + if count == 1 { text.to_string() } else { format!("{text}s") } +} diff --git a/src/ci/citool/src/metrics.rs b/src/ci/citool/src/metrics.rs index 2386413ed6b1..8548602b31cb 100644 --- a/src/ci/citool/src/metrics.rs +++ b/src/ci/citool/src/metrics.rs @@ -105,17 +105,21 @@ struct TestSuiteRecord { failed: u64, } +fn test_metadata_name(metadata: &TestSuiteMetadata) -> String { + match metadata { + TestSuiteMetadata::CargoPackage { crates, stage, .. } => { + format!("{} (stage {stage})", crates.join(", ")) + } + TestSuiteMetadata::Compiletest { suite, stage, .. } => { + format!("{suite} (stage {stage})") + } + } +} + fn aggregate_test_suites(suites: &[&TestSuite]) -> BTreeMap { let mut records: BTreeMap = BTreeMap::new(); for suite in suites { - let name = match &suite.metadata { - TestSuiteMetadata::CargoPackage { crates, stage, .. } => { - format!("{} (stage {stage})", crates.join(", ")) - } - TestSuiteMetadata::Compiletest { suite, stage, .. } => { - format!("{suite} (stage {stage})") - } - }; + let name = test_metadata_name(&suite.metadata); let record = records.entry(name).or_default(); for test in &suite.tests { match test.outcome { @@ -134,7 +138,7 @@ fn aggregate_test_suites(suites: &[&TestSuite]) -> BTreeMap Vec<&TestSuite> { +pub fn get_test_suites(metrics: &JsonRoot) -> Vec<&TestSuite> { fn visit_test_suites<'a>(nodes: &'a [JsonNode], suites: &mut Vec<&'a TestSuite>) { for node in nodes { match node { From e7bea57ce42f6882c8721ca59d0a96e13e1cbbe3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 4 Mar 2025 15:04:38 +1100 Subject: [PATCH 791/991] Fix a typo in the crashtest output. --- src/tools/compiletest/src/runtest/crashes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/runtest/crashes.rs b/src/tools/compiletest/src/runtest/crashes.rs index 885ed3b08fac..da1e74b4a56b 100644 --- a/src/tools/compiletest/src/runtest/crashes.rs +++ b/src/tools/compiletest/src/runtest/crashes.rs @@ -15,7 +15,7 @@ impl TestCx<'_> { // if a test does not crash, consider it an error if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) { self.fatal(&format!( - "crashtest no longer crashes/triggers ICE, horray! Please give it a meaningful \ + "crashtest no longer crashes/triggers ICE, hooray! Please give it a meaningful \ name, add a doc-comment to the start of the test explaining why it exists and \ move it to tests/ui or wherever you see fit. Adding 'Fixes #' to your PR \ description ensures that the corresponding ticket is auto-closed upon merge. \ From 79439323843d4131a3685e704d14086d17ce79a1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 4 Mar 2025 13:54:15 +1100 Subject: [PATCH 792/991] Pass `Option` to `def_path_data`/`create_def` methods. It's clearer than using `kw::Empty` to mean `None`. --- compiler/rustc_ast_lowering/src/expr.rs | 4 +- compiler/rustc_ast_lowering/src/lib.rs | 7 ++- compiler/rustc_ast_lowering/src/pat.rs | 4 +- .../rustc_const_eval/src/interpret/intern.rs | 2 +- compiler/rustc_hir/src/def.rs | 12 +++-- .../src/collect/resolve_bound_vars.rs | 3 +- compiler/rustc_middle/src/ty/context.rs | 4 +- .../src/coroutine/by_move_body.rs | 3 +- compiler/rustc_resolve/src/def_collector.rs | 52 ++++++++----------- compiler/rustc_resolve/src/lib.rs | 2 +- compiler/rustc_ty_utils/src/assoc.rs | 7 ++- 11 files changed, 47 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index c70fcdc84a38..de6c29d65d6c 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -13,7 +13,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::TyCtxt; use rustc_session::errors::report_lit_error; use rustc_span::source_map::{Spanned, respan}; -use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; +use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; use visit::{Visitor, walk_expr}; @@ -483,7 +483,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if legacy_args_idx.contains(&idx) { let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); - self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span); + self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, f.span); let mut visitor = WillCreateDefIdsVisitor {}; let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) { AstP(Expr { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index f58320680284..1c4edd8348f4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -494,7 +494,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, parent: LocalDefId, node_id: ast::NodeId, - name: Symbol, + name: Option, def_kind: DefKind, span: Span, ) -> LocalDefId { @@ -774,7 +774,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let _def_id = self.create_def( self.current_hir_id_owner.def_id, param, - kw::UnderscoreLifetime, + Some(kw::UnderscoreLifetime), DefKind::LifetimeParam, ident.span, ); @@ -2089,8 +2089,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // We're lowering a const argument that was originally thought to be a type argument, // so the def collector didn't create the def ahead of time. That's why we have to do // it here. - let def_id = - self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span); + let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span); let hir_id = self.lower_node_id(node_id); let path_expr = Expr { diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 728981dea5f8..07cc64a1358e 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::{self as hir, LangItem}; use rustc_middle::span_bug; use rustc_span::source_map::{Spanned, respan}; -use rustc_span::{DesugaringKind, Ident, Span, kw}; +use rustc_span::{DesugaringKind, Ident, Span}; use super::errors::{ ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding, @@ -523,7 +523,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // We're generating a range end that didn't exist in the AST, // so the def collector didn't create the def ahead of time. That's why we have to do // it here. - let def_id = self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span); + let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span); let hir_id = self.lower_node_id(node_id); let unstable_span = self.mark_span_with_reason( diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 43631330f89b..e4b2fe5d153e 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -104,7 +104,7 @@ fn intern_as_new_static<'tcx>( ) { let feed = tcx.create_def( static_id, - sym::nested, + Some(sym::nested), DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true }, ); tcx.set_nested_alloc_id_static(alloc_id, feed.def_id()); diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 7e3a8561da08..3a3b04689f7a 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -253,7 +253,9 @@ impl DefKind { } } - pub fn def_path_data(self, name: Symbol) -> DefPathData { + // Some `DefKind`s require a name, some don't. Panics if one is needed but + // not provided. + pub fn def_path_data(self, name: Option) -> DefPathData { match self { DefKind::Mod | DefKind::Struct @@ -266,7 +268,7 @@ impl DefKind { | DefKind::TraitAlias | DefKind::AssocTy | DefKind::TyParam - | DefKind::ExternCrate => DefPathData::TypeNs(name), + | DefKind::ExternCrate => DefPathData::TypeNs(name.unwrap()), // It's not exactly an anon const, but wrt DefPathData, there // is no difference. DefKind::Static { nested: true, .. } => DefPathData::AnonConst, @@ -276,9 +278,9 @@ impl DefKind { | DefKind::Static { .. } | DefKind::AssocFn | DefKind::AssocConst - | DefKind::Field => DefPathData::ValueNs(name), - DefKind::Macro(..) => DefPathData::MacroNs(name), - DefKind::LifetimeParam => DefPathData::LifetimeNs(name), + | DefKind::Field => DefPathData::ValueNs(name.unwrap()), + DefKind::Macro(..) => DefPathData::MacroNs(name.unwrap()), + DefKind::LifetimeParam => DefPathData::LifetimeNs(name.unwrap()), DefKind::Ctor(..) => DefPathData::Ctor, DefKind::Use => DefPathData::Use, DefKind::ForeignMod => DefPathData::ForeignMod, diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 6b61d317d3f5..883a1acdb309 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1462,7 +1462,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { for &(opaque_def_id, captures) in opaque_capture_scopes.iter().rev() { let mut captures = captures.borrow_mut(); let remapped = *captures.entry(lifetime).or_insert_with(|| { - let feed = self.tcx.create_def(opaque_def_id, ident.name, DefKind::LifetimeParam); + let feed = + self.tcx.create_def(opaque_def_id, Some(ident.name), DefKind::LifetimeParam); feed.def_span(ident.span); feed.def_ident_span(Some(ident.span)); feed.def_id() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4013f7b2c854..edba2a2530f6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1890,7 +1890,7 @@ impl<'tcx> TyCtxtAt<'tcx> { pub fn create_def( self, parent: LocalDefId, - name: Symbol, + name: Option, def_kind: DefKind, ) -> TyCtxtFeed<'tcx, LocalDefId> { let feed = self.tcx.create_def(parent, name, def_kind); @@ -1905,7 +1905,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn create_def( self, parent: LocalDefId, - name: Symbol, + name: Option, def_kind: DefKind, ) -> TyCtxtFeed<'tcx, LocalDefId> { let data = def_kind.def_path_data(name); diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 0f5fcb0d8eb9..206052e2cef5 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -78,7 +78,6 @@ use rustc_middle::hir::place::{Projection, ProjectionKind}; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::{self, dump_mir}; use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, TypeVisitableExt}; -use rustc_span::kw; pub(crate) fn coroutine_by_move_body_def_id<'tcx>( tcx: TyCtxt<'tcx>, @@ -214,7 +213,7 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body); // This will always be `{closure#1}`, since the original coroutine is `{closure#0}`. - let body_def = tcx.create_def(parent_def_id, kw::Empty, DefKind::SyntheticCoroutineBody); + let body_def = tcx.create_def(parent_def_id, None, DefKind::SyntheticCoroutineBody); by_move_body.source = mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id())); dump_mir(tcx, false, "built", &"after", &by_move_body, |_, _| Ok(())); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 95d637b6b22b..33f529851ae4 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind}; use rustc_hir::def_id::LocalDefId; use rustc_span::hygiene::LocalExpnId; -use rustc_span::{Span, Symbol, kw, sym}; +use rustc_span::{Span, Symbol, sym}; use tracing::debug; use crate::{ImplTraitContext, InvocationParent, Resolver}; @@ -38,7 +38,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { fn create_def( &mut self, node_id: NodeId, - name: Symbol, + name: Option, def_kind: DefKind, span: Span, ) -> LocalDefId { @@ -89,7 +89,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { self.visit_macro_invoc(field.id); } else { let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name); - let def = self.create_def(field.id, name, DefKind::Field, field.span); + let def = self.create_def(field.id, Some(name), DefKind::Field, field.span); self.with_parent(def, |this| visit::walk_field_def(this, field)); } } @@ -161,7 +161,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { return self.visit_macro_invoc(i.id); } }; - let def_id = self.create_def(i.id, i.ident.name, def_kind, i.span); + let def_id = self.create_def(i.id, Some(i.ident.name), def_kind, i.span); if let Some(macro_data) = opt_macro_data { self.resolver.macro_map.insert(def_id.to_def_id(), macro_data); @@ -175,7 +175,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(struct_def) { this.create_def( ctor_node_id, - kw::Empty, + None, DefKind::Ctor(CtorOf::Struct, ctor_kind), i.span, ); @@ -211,20 +211,15 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } let (return_id, return_span) = coroutine_kind.return_id(); - let return_def = - self.create_def(return_id, kw::Empty, DefKind::OpaqueTy, return_span); + let return_def = self.create_def(return_id, None, DefKind::OpaqueTy, return_span); self.with_parent(return_def, |this| this.visit_fn_ret_ty(output)); // If this async fn has no body (i.e. it's an async fn signature in a trait) // then the closure_def will never be used, and we should avoid generating a // def-id for it. if let Some(body) = body { - let closure_def = self.create_def( - coroutine_kind.closure_id(), - kw::Empty, - DefKind::Closure, - span, - ); + let closure_def = + self.create_def(coroutine_kind.closure_id(), None, DefKind::Closure, span); self.with_parent(closure_def, |this| this.visit_block(body)); } } @@ -235,7 +230,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // Async closures desugar to closures inside of closures, so // we must create two defs. let coroutine_def = - self.create_def(coroutine_kind.closure_id(), kw::Empty, DefKind::Closure, span); + self.create_def(coroutine_kind.closure_id(), None, DefKind::Closure, span); self.with_parent(coroutine_def, |this| this.visit_expr(body)); } _ => visit::walk_fn(self, fn_kind), @@ -243,7 +238,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) { - self.create_def(id, kw::Empty, DefKind::Use, use_tree.span); + self.create_def(id, None, DefKind::Use, use_tree.span); visit::walk_use_tree(self, use_tree, id); } @@ -262,7 +257,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id), }; - let def = self.create_def(fi.id, fi.ident.name, def_kind, fi.span); + let def = self.create_def(fi.id, Some(fi.ident.name), def_kind, fi.span); self.with_parent(def, |this| visit::walk_item(this, fi)); } @@ -271,12 +266,12 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { if v.is_placeholder { return self.visit_macro_invoc(v.id); } - let def = self.create_def(v.id, v.ident.name, DefKind::Variant, v.span); + let def = self.create_def(v.id, Some(v.ident.name), DefKind::Variant, v.span); self.with_parent(def, |this| { if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&v.data) { this.create_def( ctor_node_id, - kw::Empty, + None, DefKind::Ctor(CtorOf::Variant, ctor_kind), v.span, ); @@ -312,7 +307,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { GenericParamKind::Type { .. } => DefKind::TyParam, GenericParamKind::Const { .. } => DefKind::ConstParam, }; - self.create_def(param.id, param.ident.name, def_kind, param.ident.span); + self.create_def(param.id, Some(param.ident.name), def_kind, param.ident.span); // impl-Trait can happen inside generic parameters, like // ``` @@ -335,7 +330,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } }; - let def = self.create_def(i.id, i.ident.name, def_kind, i.span); + let def = self.create_def(i.id, Some(i.ident.name), def_kind, i.span); self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); } @@ -347,8 +342,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } fn visit_anon_const(&mut self, constant: &'a AnonConst) { - let parent = - self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span); + let parent = self.create_def(constant.id, None, DefKind::AnonConst, constant.value.span); self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); } @@ -356,18 +350,14 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { let parent_def = match expr.kind { ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id), ExprKind::Closure(..) | ExprKind::Gen(..) => { - self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span) + self.create_def(expr.id, None, DefKind::Closure, expr.span) } ExprKind::ConstBlock(ref constant) => { for attr in &expr.attrs { visit::walk_attribute(self, attr); } - let def = self.create_def( - constant.id, - kw::Empty, - DefKind::InlineConst, - constant.value.span, - ); + let def = + self.create_def(constant.id, None, DefKind::InlineConst, constant.value.span); self.with_parent(def, |this| visit::walk_anon_const(this, constant)); return; } @@ -391,7 +381,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { ImplTraitContext::Existential => DefKind::OpaqueTy, ImplTraitContext::InBinding => return visit::walk_ty(self, ty), }; - let id = self.create_def(*id, name, kind, ty.span); + let id = self.create_def(*id, Some(name), kind, ty.span); match self.impl_trait_context { // Do not nest APIT, as we desugar them as `impl_trait: bounds`, // so the `impl_trait` node is not a parent to `bounds`. @@ -495,7 +485,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { InlineAsmOperand::Const { anon_const } => { let def = self.create_def( anon_const.id, - kw::Empty, + None, DefKind::InlineConst, anon_const.value.span, ); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 4c5d4041022a..ccdca8552320 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1340,7 +1340,7 @@ impl<'tcx> Resolver<'_, 'tcx> { &mut self, parent: LocalDefId, node_id: ast::NodeId, - name: Symbol, + name: Option, def_kind: DefKind, expn_id: ExpnId, span: Span, diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index c8034f4e7b9f..318f9be30619 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -252,7 +252,8 @@ fn associated_type_for_impl_trait_in_trait( assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait); let span = tcx.def_span(opaque_ty_def_id); - let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy); + // FIXME: `kw::Empty` gets special treatment by `DefPathData`'s methods. + let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, Some(kw::Empty), DefKind::AssocTy); let local_def_id = trait_assoc_ty.def_id(); let def_id = local_def_id.to_def_id(); @@ -304,7 +305,9 @@ fn associated_type_for_impl_trait_in_impl( hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id), hir::FnRetTy::Return(ty) => ty.span, }; - let impl_assoc_ty = tcx.at(span).create_def(impl_local_def_id, kw::Empty, DefKind::AssocTy); + // FIXME: `kw::Empty` gets special treatment by `DefPathData`'s methods. + let impl_assoc_ty = + tcx.at(span).create_def(impl_local_def_id, Some(kw::Empty), DefKind::AssocTy); let local_def_id = impl_assoc_ty.def_id(); let def_id = local_def_id.to_def_id(); From af92a33deef026844c4594cc5eb7484527403425 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 4 Mar 2025 14:34:18 +1100 Subject: [PATCH 793/991] Make synthetic RPITIT assoc ty name handling more rigorous. Currently it relies on special treatment of `kw::Empty`, which is really easy to get wrong. This commit makes the special case clearer in the type system by using `Option`. It's a bit clumsy, but the synthetic name handling itself is a bit clumsy; better to make it explicit than sneak it in. Fixes #133426. --- compiler/rustc_hir/src/def.rs | 10 ++++-- compiler/rustc_hir/src/definitions.rs | 22 +++++++------ compiler/rustc_middle/src/ty/print/pretty.rs | 4 +-- .../src/ty/significant_drop_order.rs | 6 ++-- compiler/rustc_ty_utils/src/assoc.rs | 9 +++--- src/tools/clippy/clippy_utils/src/lib.rs | 6 ++-- tests/crashes/133426.rs | 12 ------- .../no-name-for-DefPath-issue-133426.rs | 20 ++++++++++++ .../no-name-for-DefPath-issue-133426.stderr | 31 +++++++++++++++++++ 9 files changed, 84 insertions(+), 36 deletions(-) delete mode 100644 tests/crashes/133426.rs create mode 100644 tests/ui/lowering/no-name-for-DefPath-issue-133426.rs create mode 100644 tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 3a3b04689f7a..ea2581787e47 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -254,7 +254,7 @@ impl DefKind { } // Some `DefKind`s require a name, some don't. Panics if one is needed but - // not provided. + // not provided. (`AssocTy` is an exception, see below.) pub fn def_path_data(self, name: Option) -> DefPathData { match self { DefKind::Mod @@ -266,9 +266,13 @@ impl DefKind { | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias - | DefKind::AssocTy | DefKind::TyParam - | DefKind::ExternCrate => DefPathData::TypeNs(name.unwrap()), + | DefKind::ExternCrate => DefPathData::TypeNs(Some(name.unwrap())), + + // An associated type names will be missing for an RPITIT. It will + // later be given a name with `synthetic` in it, if necessary. + DefKind::AssocTy => DefPathData::TypeNs(name), + // It's not exactly an anon const, but wrt DefPathData, there // is no difference. DefKind::Static { nested: true, .. } => DefPathData::AnonConst, diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index c4c309e77e19..61f5efd9978c 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -271,8 +271,9 @@ pub enum DefPathData { Use, /// A global asm item. GlobalAsm, - /// Something in the type namespace. - TypeNs(Symbol), + /// Something in the type namespace. Will be empty for RPITIT associated + /// types, which are given a synthetic name later, if necessary. + TypeNs(Option), /// Something in the value namespace. ValueNs(Symbol), /// Something in the macro namespace. @@ -410,8 +411,9 @@ impl DefPathData { pub fn get_opt_name(&self) -> Option { use self::DefPathData::*; match *self { - TypeNs(name) if name == kw::Empty => None, - TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), + TypeNs(name) => name, + + ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), Impl | ForeignMod | CrateRoot | Use | GlobalAsm | Closure | Ctor | AnonConst | OpaqueTy => None, @@ -421,12 +423,14 @@ impl DefPathData { pub fn name(&self) -> DefPathDataName { use self::DefPathData::*; match *self { - TypeNs(name) if name == kw::Empty => { - DefPathDataName::Anon { namespace: sym::synthetic } - } - TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => { - DefPathDataName::Named(name) + TypeNs(name) => { + if let Some(name) = name { + DefPathDataName::Named(name) + } else { + DefPathDataName::Anon { namespace: sym::synthetic } + } } + ValueNs(name) | MacroNs(name) | LifetimeNs(name) => DefPathDataName::Named(name), // Note that this does not show up in user print-outs. CrateRoot => DefPathDataName::Anon { namespace: kw::Crate }, Impl => DefPathDataName::Anon { namespace: kw::Impl }, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 34d85534d0ae..2a3a7705b7b6 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -569,7 +569,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { // the children of the visible parent (as was done when computing // `visible_parent_map`), looking for the specific child we currently have and then // have access to the re-exported name. - DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => { + DefPathData::TypeNs(Some(ref mut name)) if Some(visible_parent) != actual_parent => { // Item might be re-exported several times, but filter for the one // that's public and whose identifier isn't `_`. let reexport = self @@ -590,7 +590,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } // Re-exported `extern crate` (#43189). DefPathData::CrateRoot => { - data = DefPathData::TypeNs(self.tcx().crate_name(def_id.krate)); + data = DefPathData::TypeNs(Some(self.tcx().crate_name(def_id.krate))); } _ => {} } diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs index 7f0d82d89fed..2d9e0331451f 100644 --- a/compiler/rustc_middle/src/ty/significant_drop_order.rs +++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs @@ -23,9 +23,11 @@ fn true_significant_drop_ty<'tcx>( match key.disambiguated_data.data { rustc_hir::definitions::DefPathData::CrateRoot => { - name_rev.push(tcx.crate_name(did.krate)) + name_rev.push(tcx.crate_name(did.krate)); + } + rustc_hir::definitions::DefPathData::TypeNs(symbol) => { + name_rev.push(symbol.unwrap()); } - rustc_hir::definitions::DefPathData::TypeNs(symbol) => name_rev.push(symbol), _ => return None, } if let Some(parent) = key.parent { diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 318f9be30619..c84055f5b84f 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -252,8 +252,8 @@ fn associated_type_for_impl_trait_in_trait( assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait); let span = tcx.def_span(opaque_ty_def_id); - // FIXME: `kw::Empty` gets special treatment by `DefPathData`'s methods. - let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, Some(kw::Empty), DefKind::AssocTy); + // No name because this is a synthetic associated type. + let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, None, DefKind::AssocTy); let local_def_id = trait_assoc_ty.def_id(); let def_id = local_def_id.to_def_id(); @@ -305,9 +305,8 @@ fn associated_type_for_impl_trait_in_impl( hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id), hir::FnRetTy::Return(ty) => ty.span, }; - // FIXME: `kw::Empty` gets special treatment by `DefPathData`'s methods. - let impl_assoc_ty = - tcx.at(span).create_def(impl_local_def_id, Some(kw::Empty), DefKind::AssocTy); + // No name because this is a synthetic associated type. + let impl_assoc_ty = tcx.at(span).create_def(impl_local_def_id, None, DefKind::AssocTy); let local_def_id = impl_assoc_ty.def_id(); let def_id = local_def_id.to_def_id(); diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index d850cc410008..ef706cd076f0 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -3489,7 +3489,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St // a::b::c ::d::sym refers to // e::f::sym:: :: // result should be super::super::super::super::e::f - if let DefPathData::TypeNs(s) = l { + if let DefPathData::TypeNs(Some(s)) = l { path.push(s.to_string()); } if let DefPathData::TypeNs(_) = r { @@ -3500,7 +3500,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St // a::b::sym:: :: refers to // c::d::e ::f::sym // when looking at `f` - Left(DefPathData::TypeNs(sym)) => path.push(sym.to_string()), + Left(DefPathData::TypeNs(Some(sym))) => path.push(sym.to_string()), // consider: // a::b::c ::d::sym refers to // e::f::sym:: :: @@ -3514,7 +3514,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St // `super` chain would be too long, just use the absolute path instead once(String::from("crate")) .chain(to.data.iter().filter_map(|el| { - if let DefPathData::TypeNs(sym) = el.data { + if let DefPathData::TypeNs(Some(sym)) = el.data { Some(sym.to_string()) } else { None diff --git a/tests/crashes/133426.rs b/tests/crashes/133426.rs deleted file mode 100644 index 307a94c0f6ca..000000000000 --- a/tests/crashes/133426.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #133426 - -fn a( - _: impl Iterator< - Item = [(); { - match *todo!() { ! }; - }], - >, -) { -} - -fn b(_: impl Iterator) {} diff --git a/tests/ui/lowering/no-name-for-DefPath-issue-133426.rs b/tests/ui/lowering/no-name-for-DefPath-issue-133426.rs new file mode 100644 index 000000000000..fc3b51b40a54 --- /dev/null +++ b/tests/ui/lowering/no-name-for-DefPath-issue-133426.rs @@ -0,0 +1,20 @@ +//! Test for the crash in #133426, caused by an empty symbol being used for a +//! type name. + +#![allow(incomplete_features)] +#![feature(never_patterns)] + +fn a( + _: impl Iterator< + Item = [(); { + match *todo!() { ! }; //~ ERROR type `!` cannot be dereferenced + }], + >, +) { +} + +fn b(_: impl Iterator) {} +//~^ ERROR associated const equality is incomplete +//~| ERROR expected type, found constant + +fn main() {} diff --git a/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr b/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr new file mode 100644 index 000000000000..555d8eec6bab --- /dev/null +++ b/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr @@ -0,0 +1,31 @@ +error[E0658]: associated const equality is incomplete + --> $DIR/no-name-for-DefPath-issue-133426.rs:16:23 + | +LL | fn b(_: impl Iterator) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #92827 for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0614]: type `!` cannot be dereferenced + --> $DIR/no-name-for-DefPath-issue-133426.rs:10:19 + | +LL | match *todo!() { ! }; + | ^^^^^^^^ can't be dereferenced + +error: expected type, found constant + --> $DIR/no-name-for-DefPath-issue-133426.rs:16:30 + | +LL | fn b(_: impl Iterator) {} + | ---- ^^^^^^^^^^^^^^^^^ unexpected constant + | | + | expected a type because of this associated type + | +note: the associated type is defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0614, E0658. +For more information about an error, try `rustc --explain E0614`. From ec3cde249f5b5a8406dcdf6b8abc702e86e6e56b Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 7 Mar 2025 19:05:03 +0800 Subject: [PATCH 794/991] Apply `--cfg windows_raw_dylib` for bootstrap tools too This is already applied for rustc/std tools. This is needed to make `windows` crates avoid trying to depend on a generated `windows.0.xx.0.lib`. --- src/bootstrap/src/core/builder/cargo.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index d1d52d82eaa0..12dd40d14e9b 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -597,7 +597,7 @@ impl Builder<'_> { // sysroot. Passing this cfg enables raw-dylib support instead, which makes the native // library unnecessary. This can be removed when windows-rs enables raw-dylib // unconditionally. - if let Mode::Rustc | Mode::ToolRustc = mode { + if let Mode::Rustc | Mode::ToolRustc | Mode::ToolBootstrap = mode { rustflags.arg("--cfg=windows_raw_dylib"); } From bd884d8043b9ebd4e2bbae0e31bc4780d2e26c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:10:49 +0800 Subject: [PATCH 795/991] Prevent `rmake.rs` from using any nightly/unstable features --- src/tools/compiletest/src/runtest/run_make.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 8900752bd4be..073116933bdb 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -105,6 +105,11 @@ impl TestCx<'_> { .expect("stage0 rustc is required to run run-make tests"); let mut rustc = Command::new(&stage0_rustc); rustc + // `rmake.rs` **must** be buildable by a stable compiler, it may not use *any* unstable + // library or compiler features. Here, we force the stage 0 rustc to consider itself as + // a stable-channel compiler via `RUSTC_BOOTSTRAP=-1` to prevent *any* unstable + // library/compiler usages, even if stage 0 rustc is *actually* a nightly rustc. + .env("RUSTC_BOOTSTRAP", "-1") .arg("-o") .arg(&recipe_bin) // Specify library search paths for `run_make_support`. From da57f1418f0e302e43c757c7f93cad688a895e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 24 Feb 2025 19:17:40 +0800 Subject: [PATCH 796/991] Fix `issue-107495-archive-permissions` to not rely on `rustc_private` --- tests/run-make/issue-107495-archive-permissions/rmake.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/run-make/issue-107495-archive-permissions/rmake.rs b/tests/run-make/issue-107495-archive-permissions/rmake.rs index f210b7c737b4..5d7c8a49bcc9 100644 --- a/tests/run-make/issue-107495-archive-permissions/rmake.rs +++ b/tests/run-make/issue-107495-archive-permissions/rmake.rs @@ -1,7 +1,5 @@ -#![feature(rustc_private)] - #[cfg(unix)] -extern crate libc; +use run_make_support::libc; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; From 9befcfd0f4671675341e770c5bb3bf696c7aa670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 24 Feb 2025 19:37:10 +0800 Subject: [PATCH 797/991] Fix `cross-lang-lto` to not use `path_file_prefix` --- tests/run-make/cross-lang-lto/rmake.rs | 15 ++++++++++----- .../issue-107495-archive-permissions/rmake.rs | 5 ++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/run-make/cross-lang-lto/rmake.rs b/tests/run-make/cross-lang-lto/rmake.rs index dc376b561e43..50d37460d8db 100644 --- a/tests/run-make/cross-lang-lto/rmake.rs +++ b/tests/run-make/cross-lang-lto/rmake.rs @@ -3,8 +3,6 @@ // -Clinker-plugin-lto. // See https://github.com/rust-lang/rust/pull/50000 -#![feature(path_file_prefix)] - use std::path::PathBuf; use run_make_support::{ @@ -92,10 +90,17 @@ fn check_bitcode(instructions: LibBuild) { llvm_ar().extract().arg(&instructions.output).run(); } - for object in shallow_find_files(cwd(), |path| { - has_prefix(path, instructions.output.file_prefix().unwrap().to_str().unwrap()) + let objects = shallow_find_files(cwd(), |path| { + let mut output_path = instructions.output.clone(); + output_path.set_extension(""); + has_prefix(path, output_path.file_name().unwrap().to_str().unwrap()) && has_extension(path, "o") - }) { + }); + assert!(!objects.is_empty()); + println!("objects: {:#?}", objects); + + for object in objects { + println!("reading bitcode: {}", object.display()); // All generated object files should be LLVM bitcode files - this will fail otherwise. llvm_bcanalyzer().input(object).run(); } diff --git a/tests/run-make/issue-107495-archive-permissions/rmake.rs b/tests/run-make/issue-107495-archive-permissions/rmake.rs index 5d7c8a49bcc9..228cfb0864e7 100644 --- a/tests/run-make/issue-107495-archive-permissions/rmake.rs +++ b/tests/run-make/issue-107495-archive-permissions/rmake.rs @@ -1,10 +1,9 @@ -#[cfg(unix)] -use run_make_support::libc; - #[cfg(unix)] use std::os::unix::fs::PermissionsExt; use std::path::Path; +#[cfg(unix)] +use run_make_support::libc; use run_make_support::{aux_build, rfs}; fn main() { From d47e5a371bb3a4353587e95bf4ee271a273d1326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:01:49 +0800 Subject: [PATCH 798/991] Temporarily depend on `os_pipe` in `run-make-support` and re-export it For `broken-pipe-no-ice` until std `anonymous_pipe` stabilizes. --- Cargo.lock | 11 +++++++++++ src/tools/run-make-support/Cargo.toml | 4 ++++ src/tools/run-make-support/src/lib.rs | 2 ++ 3 files changed, 17 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 72f2d4f6cd39..5886b96b7281 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2526,6 +2526,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "os_pipe" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "overload" version = "0.1.1" @@ -3050,6 +3060,7 @@ dependencies = [ "gimli 0.31.1", "libc", "object 0.36.7", + "os_pipe", "regex", "serde_json", "similar", diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index 15ed03ad5c23..f9beffec7508 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -14,5 +14,9 @@ build_helper = { path = "../../build_helper" } serde_json = "1.0" libc = "0.2" +# FIXME(#137532): replace `os_pipe` with `anonymous_pipe` once it stabilizes and +# reaches beta. +os_pipe = "1.2.1" + [lib] crate-type = ["lib", "dylib"] diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index d40ec9c4116e..c846a2d53e5f 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -40,6 +40,8 @@ pub use bstr; pub use gimli; pub use libc; pub use object; +// FIXME(#137532): replace with std `anonymous_pipe` once it stabilizes and reaches beta. +pub use os_pipe; pub use regex; pub use serde_json; pub use similar; From 224f287f3226a89eff12ff3cbf0ca4e64c96d351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:02:44 +0800 Subject: [PATCH 799/991] Fix `broken-pipe-no-ice` to not depend on unstable `anonymous_pipe` feature --- tests/run-make/broken-pipe-no-ice/rmake.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/run-make/broken-pipe-no-ice/rmake.rs b/tests/run-make/broken-pipe-no-ice/rmake.rs index 54d13b62f4a0..3e54b576fd42 100644 --- a/tests/run-make/broken-pipe-no-ice/rmake.rs +++ b/tests/run-make/broken-pipe-no-ice/rmake.rs @@ -11,12 +11,12 @@ // Internal Compiler Error strangely, but it doesn't even go through normal diagnostic infra. Very // strange. -#![feature(anonymous_pipe)] - use std::io::Read; use std::process::{Command, Stdio}; -use run_make_support::env_var; +// FIXME(#137532): replace `os_pipe` dependency with std `anonymous_pipe` once that stabilizes and +// reaches beta. +use run_make_support::{env_var, os_pipe}; #[derive(Debug, PartialEq)] enum Binary { @@ -25,7 +25,7 @@ enum Binary { } fn check_broken_pipe_handled_gracefully(bin: Binary, mut cmd: Command) { - let (reader, writer) = std::io::pipe().unwrap(); + let (reader, writer) = os_pipe::pipe().unwrap(); drop(reader); // close read-end cmd.stdout(writer).stderr(Stdio::piped()); From c9c572cd927b223d22280ca606086d64d20b733b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:14:25 +0800 Subject: [PATCH 800/991] Document that `rmake.rs`/`run-make-support` may not use unstable features --- src/doc/rustc-dev-guide/src/tests/compiletest.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index 2905e470fabd..a6996e398221 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -415,6 +415,10 @@ Compiletest directives like `//@ only-` or `//@ ignore-` are supported in `rmake.rs`, like in UI tests. However, revisions or building auxiliary via directives are not currently supported. +`rmake.rs` and `run-make-support` may *not* use any nightly/unstable features, +as they must be compilable by a stage 0 rustc that may be a beta or even stable +rustc. + #### Quickly check if `rmake.rs` tests can be compiled You can quickly check if `rmake.rs` tests can be compiled without having to From bdf602a594dd009a694d000d6d910685af1ae330 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 7 Mar 2025 16:07:35 +0100 Subject: [PATCH 801/991] Log build script error output in `load_cargo::load_workspace_at` --- src/tools/rust-analyzer/crates/load-cargo/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 76f1a7f48b6b..72ca85c6a2fd 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -45,10 +45,18 @@ pub fn load_workspace_at( ) -> anyhow::Result<(RootDatabase, vfs::Vfs, Option)> { let root = AbsPathBuf::assert_utf8(std::env::current_dir()?.join(root)); let root = ProjectManifest::discover_single(&root)?; + let manifest_path = root.manifest_path().clone(); let mut workspace = ProjectWorkspace::load(root, cargo_config, progress)?; if load_config.load_out_dirs_from_check { let build_scripts = workspace.run_build_scripts(cargo_config, progress)?; + if let Some(error) = build_scripts.error() { + tracing::debug!( + "Errors occurred while running build scripts for {}: {}", + manifest_path, + error + ); + } workspace.set_build_scripts(build_scripts) } From 4203e9c56d8aa6cdfe5f5a60bd510917b84188c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 12 Feb 2025 15:04:26 +0100 Subject: [PATCH 802/991] depend more on attr_data_structures and move find_attr! there --- Cargo.lock | 6 ++- .../rustc_attr_data_structures/src/lib.rs | 44 +++++++++++++++++++ compiler/rustc_attr_parsing/Cargo.toml | 1 + compiler/rustc_attr_parsing/src/lib.rs | 44 ------------------- compiler/rustc_hir_pretty/Cargo.toml | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_middle/Cargo.toml | 3 +- .../src/middle/codegen_fn_attrs.rs | 2 +- compiler/rustc_middle/src/middle/stability.rs | 2 +- compiler/rustc_middle/src/mir/mono.rs | 2 +- compiler/rustc_middle/src/query/erase.rs | 14 +++--- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 7 +-- compiler/rustc_middle/src/ty/parameterized.rs | 8 ++-- 15 files changed, 73 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72f2d4f6cd39..d1bdbb4cf563 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3286,6 +3286,7 @@ dependencies = [ "rustc_hir", "rustc_lexer", "rustc_macros", + "rustc_middle", "rustc_serialize", "rustc_session", "rustc_span", @@ -3741,7 +3742,7 @@ dependencies = [ "rustc_abi", "rustc_ast", "rustc_ast_pretty", - "rustc_attr_parsing", + "rustc_attr_data_structures", "rustc_hir", "rustc_span", ] @@ -4009,7 +4010,8 @@ dependencies = [ "rustc_apfloat", "rustc_arena", "rustc_ast", - "rustc_attr_parsing", + "rustc_ast_ir", + "rustc_attr_data_structures", "rustc_data_structures", "rustc_error_messages", "rustc_errors", diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index e4bb459e6df5..f4986d1d1872 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -149,3 +149,47 @@ print_tup!(A B C D E F G H); print_skip!(Span, ()); print_disp!(Symbol, u16, bool, NonZero); print_debug!(UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency); + +/// Finds attributes in sequences of attributes by pattern matching. +/// +/// A little like `matches` but for attributes. +/// +/// ```rust,ignore (illustrative) +/// // finds the repr attribute +/// if let Some(r) = find_attr!(attrs, AttributeKind::Repr(r) => r) { +/// +/// } +/// +/// // checks if one has matched +/// if find_attr!(attrs, AttributeKind::Repr(_)) { +/// +/// } +/// ``` +/// +/// Often this requires you to first end up with a list of attributes. +/// A common way to get those is through `tcx.get_all_attrs(did)` +#[macro_export] +macro_rules! find_attr { + ($attributes_list: expr, $pattern: pat $(if $guard: expr)?) => {{ + $crate::find_attr!($attributes_list, $pattern $(if $guard)? => ()).is_some() + }}; + + ($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{ + fn check_attribute_iterator<'a>(_: &'_ impl IntoIterator) {} + check_attribute_iterator(&$attributes_list); + + let find_attribute = |iter| { + for i in $attributes_list { + match i { + rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => { + return Some($e); + } + _ => {} + } + } + + None + }; + find_attribute($attributes_list) + }}; +} diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml index c335eeb5f712..6b4ce957630f 100644 --- a/compiler/rustc_attr_parsing/Cargo.toml +++ b/compiler/rustc_attr_parsing/Cargo.toml @@ -16,6 +16,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } +rustc_middle = { path = "../rustc_middle" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 9841166b37db..386f2c98447b 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -95,47 +95,3 @@ pub use context::{AttributeParser, OmitDoc}; pub use rustc_attr_data_structures::*; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - -/// Finds attributes in sequences of attributes by pattern matching. -/// -/// A little like `matches` but for attributes. -/// -/// ```rust,ignore (illustrative) -/// // finds the repr attribute -/// if let Some(r) = find_attr!(attrs, AttributeKind::Repr(r) => r) { -/// -/// } -/// -/// // checks if one has matched -/// if find_attr!(attrs, AttributeKind::Repr(_)) { -/// -/// } -/// ``` -/// -/// Often this requires you to first end up with a list of attributes. -/// A common way to get those is through `tcx.get_all_attrs(did)` -#[macro_export] -macro_rules! find_attr { - ($attributes_list: expr, $pattern: pat $(if $guard: expr)?) => {{ - $crate::find_attr!($attributes_list, $pattern $(if $guard)? => ()).is_some() - }}; - - ($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{ - fn check_attribute_iterator<'a>(_: &'_ impl IntoIterator) {} - check_attribute_iterator(&$attributes_list); - - let find_attribute = |iter| { - for i in $attributes_list { - match i { - rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => { - return Some($e); - } - _ => {} - } - } - - None - }; - find_attribute($attributes_list) - }}; -} diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml index 86989d1e55b4..91da8cb3fc5f 100644 --- a/compiler/rustc_hir_pretty/Cargo.toml +++ b/compiler/rustc_hir_pretty/Cargo.toml @@ -8,7 +8,7 @@ edition = "2024" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr_parsing = { path = "../rustc_attr_parsing" } +rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } rustc_hir = { path = "../rustc_hir" } rustc_span = { path = "../rustc_span" } # tidy-alphabetical-end diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 1f6fb3a329a5..d453301310e2 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -16,7 +16,7 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; use rustc_ast_pretty::pprust::state::MacHeader; use rustc_ast_pretty::pprust::{Comments, PrintState}; -use rustc_attr_parsing::{AttributeKind, PrintAttribute}; +use rustc_attr_data_structures::{AttributeKind, PrintAttribute}; use rustc_hir::{ BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind, HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index aebd2181f31e..43c1af642dd5 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -14,7 +14,8 @@ rustc_abi = { path = "../rustc_abi" } rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } -rustc_attr_parsing = { path = "../rustc_attr_parsing" } +rustc_ast_ir = { path = "../rustc_ast_ir" } +rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 311bc60c3cd3..a94ead161c37 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -1,6 +1,6 @@ use rustc_abi::Align; use rustc_ast::expand::autodiff_attrs::AutoDiffAttrs; -use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_attr_data_structures::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 2260cad41b97..ec128c8c4786 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -4,7 +4,7 @@ use std::num::NonZero; use rustc_ast::NodeId; -use rustc_attr_parsing::{ +use rustc_attr_data_structures::{ self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability, }; use rustc_data_structures::unord::UnordMap; diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 58d5c94d0332..897119c07122 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -2,7 +2,7 @@ use std::fmt; use std::hash::Hash; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; -use rustc_attr_parsing::InlineAttr; +use rustc_attr_data_structures::InlineAttr; use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexMap; diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index cbd60920bc57..2abb2d2d8e5d 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -231,9 +231,9 @@ trivial! { bool, Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>, Option, - Option, - Option, - Option, + Option, + Option, + Option, Option, Option, Option, @@ -256,10 +256,10 @@ trivial! { Result, rustc_abi::ReprOptions, rustc_ast::expand::allocator::AllocatorKind, - rustc_attr_parsing::ConstStability, - rustc_attr_parsing::DefaultBodyStability, - rustc_attr_parsing::Deprecation, - rustc_attr_parsing::Stability, + rustc_attr_data_structures::ConstStability, + rustc_attr_data_structures::DefaultBodyStability, + rustc_attr_data_structures::Deprecation, + rustc_attr_data_structures::Stability, rustc_data_structures::svh::Svh, rustc_errors::ErrorGuaranteed, rustc_hir::Constness, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 4ad4427594cf..6b70ecc028e2 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -41,7 +41,7 @@ use rustc_span::def_id::LOCAL_CRATE; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_target::spec::PanicStrategy; -use {rustc_abi as abi, rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir}; +use {rustc_abi as abi, rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir}; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 98ca71b86be0..b99148f33684 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -203,7 +203,7 @@ impl<'tcx> Instance<'tcx> { if !tcx.sess.opts.share_generics() // However, if the def_id is marked inline(never), then it's fine to just reuse the // upstream monomorphization. - && tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr_parsing::InlineAttr::Never + && tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr_data_structures::InlineAttr::Never { return None; } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 527509af05fc..dd916a5962bf 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -27,7 +27,8 @@ pub use intrinsic::IntrinsicDef; use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx}; use rustc_ast::expand::StrippedCfgItem; use rustc_ast::node_id::NodeMap; -use rustc_attr_parsing::AttributeKind; +pub use rustc_ast_ir::{Movability, Mutability, try_visit}; +use rustc_attr_data_structures::AttributeKind; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -51,7 +52,7 @@ pub use rustc_type_ir::relate::VarianceDiagInfo; pub use rustc_type_ir::*; use tracing::{debug, instrument}; pub use vtable::*; -use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir}; +use {rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir}; pub use self::closure::{ BorrowKind, CAPTURE_STRUCT_LOCAL, CaptureInfo, CapturedPlace, ClosureTypeInfo, @@ -1757,7 +1758,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Gets all attributes. /// - /// To see if an item has a specific attribute, you should use [`rustc_attr_parsing::find_attr!`] so you can use matching. + /// To see if an item has a specific attribute, you should use [`rustc_attr_data_structures::find_attr!`] so you can use matching. pub fn get_all_attrs( self, did: impl Into, diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 8eaf0a58f708..71fc38cb7edb 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -80,10 +80,10 @@ trivially_parameterized_over_tcx! { rustc_ast::Attribute, rustc_ast::DelimArgs, rustc_ast::expand::StrippedCfgItem, - rustc_attr_parsing::ConstStability, - rustc_attr_parsing::DefaultBodyStability, - rustc_attr_parsing::Deprecation, - rustc_attr_parsing::Stability, + rustc_attr_data_structures::ConstStability, + rustc_attr_data_structures::DefaultBodyStability, + rustc_attr_data_structures::Deprecation, + rustc_attr_data_structures::Stability, rustc_hir::Constness, rustc_hir::Defaultness, rustc_hir::Safety, From bbc80a819b542d751450bd82208438de5754ee47 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Mar 2025 17:09:36 +0000 Subject: [PATCH 803/991] Delay bug for negative auto trait rather than ICEing --- .../src/check/always_applicable.rs | 5 +++- tests/ui/auto-traits/ungated-impl.rs | 7 ++++++ tests/ui/auto-traits/ungated-impl.stderr | 23 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tests/ui/auto-traits/ungated-impl.rs create mode 100644 tests/ui/auto-traits/ungated-impl.stderr diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index ba5b61d3fce0..8a841a115567 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -124,7 +124,10 @@ pub(crate) fn check_negative_auto_trait_impl<'tcx>( // be implemented here to handle non-ADT rigid types. Ok(()) } else { - span_bug!(tcx.def_span(impl_def_id), "incoherent impl of negative auto trait"); + Err(tcx.dcx().span_delayed_bug( + tcx.def_span(impl_def_id), + "incoherent impl of negative auto trait", + )) } } } diff --git a/tests/ui/auto-traits/ungated-impl.rs b/tests/ui/auto-traits/ungated-impl.rs new file mode 100644 index 000000000000..d46b4b01af9c --- /dev/null +++ b/tests/ui/auto-traits/ungated-impl.rs @@ -0,0 +1,7 @@ +auto trait MyTrait {} +//~^ ERROR auto traits are experimental and possibly buggy + +impl !MyTrait for *mut T {} +//~^ ERROR negative trait bounds are not fully implemented + +fn main() {} diff --git a/tests/ui/auto-traits/ungated-impl.stderr b/tests/ui/auto-traits/ungated-impl.stderr new file mode 100644 index 000000000000..9d10d46a9028 --- /dev/null +++ b/tests/ui/auto-traits/ungated-impl.stderr @@ -0,0 +1,23 @@ +error[E0658]: auto traits are experimental and possibly buggy + --> $DIR/ungated-impl.rs:1:1 + | +LL | auto trait MyTrait {} + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #13231 for more information + = help: add `#![feature(auto_traits)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: negative trait bounds are not fully implemented; use marker types for now + --> $DIR/ungated-impl.rs:4:9 + | +LL | impl !MyTrait for *mut T {} + | ^^^^^^^^ + | + = note: see issue #68318 for more information + = help: add `#![feature(negative_impls)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. From 607987e3e24560312eb258d0217e5e00b31bec71 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 7 Mar 2025 15:44:15 +0100 Subject: [PATCH 804/991] Support rmeta inputs for --crate-type=bin --emit=obj This already works for --emit=metadata, but is possible anytime we're not linking. Tests: `rmeta_bin` checks we're not changing --emit=link (already passes) `rmeta_bin-pass` tests the new behavior for --emit=obj (would fail today) and also --emit=metadata which isn't changing --- compiler/rustc_metadata/src/dependency_format.rs | 2 +- tests/ui/rmeta/rmeta_bin-pass.rs | 14 ++++++++++++++ tests/ui/rmeta/rmeta_bin.rs | 14 ++++++++++++++ tests/ui/rmeta/rmeta_bin.stderr | 4 ++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/ui/rmeta/rmeta_bin-pass.rs create mode 100644 tests/ui/rmeta/rmeta_bin.rs create mode 100644 tests/ui/rmeta/rmeta_bin.stderr diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 582c2215d92e..be31aa629c86 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -84,7 +84,7 @@ pub(crate) fn calculate(tcx: TyCtxt<'_>) -> Dependencies { fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { let sess = &tcx.sess; - if !sess.opts.output_types.should_codegen() { + if !sess.opts.output_types.should_link() { return IndexVec::new(); } diff --git a/tests/ui/rmeta/rmeta_bin-pass.rs b/tests/ui/rmeta/rmeta_bin-pass.rs new file mode 100644 index 000000000000..7de4f3ba9613 --- /dev/null +++ b/tests/ui/rmeta/rmeta_bin-pass.rs @@ -0,0 +1,14 @@ +//@ compile-flags: --emit=obj,metadata --crate-type=bin +//@ aux-build:rmeta-meta.rs +//@ no-prefer-dynamic +//@ build-pass + +// Check that building a metadata bin crate works with a dependent, metadata +// crate if linking is not requested. + +extern crate rmeta_meta; +use rmeta_meta::Foo; + +pub fn main() { + let _ = Foo { field: 42 }; +} diff --git a/tests/ui/rmeta/rmeta_bin.rs b/tests/ui/rmeta/rmeta_bin.rs new file mode 100644 index 000000000000..c7d2050cd59f --- /dev/null +++ b/tests/ui/rmeta/rmeta_bin.rs @@ -0,0 +1,14 @@ +//@ build-fail +//@ compile-flags: --crate-type=bin +//@ aux-build:rmeta-meta.rs +//@ no-prefer-dynamic +//@ error-pattern: crate `rmeta_meta` required to be available in rlib format, but was not found + +// Check that building a bin crate fails if a dependent crate is metadata-only. + +extern crate rmeta_meta; +use rmeta_meta::Foo; + +fn main() { + let _ = Foo { field: 42 }; +} diff --git a/tests/ui/rmeta/rmeta_bin.stderr b/tests/ui/rmeta/rmeta_bin.stderr new file mode 100644 index 000000000000..830169e032a1 --- /dev/null +++ b/tests/ui/rmeta/rmeta_bin.stderr @@ -0,0 +1,4 @@ +error: crate `rmeta_meta` required to be available in rlib format, but was not found in this form + +error: aborting due to 1 previous error + From 0dfe2ae3fb72c50ea369286131c73daede13d7e5 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 24 Feb 2025 03:48:12 +0000 Subject: [PATCH 805/991] Windows: Use MoveFileEx by default in `fs:rename` --- library/std/src/sys/pal/windows/fs.rs | 177 ++++++++------------------ 1 file changed, 55 insertions(+), 122 deletions(-) diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 17dc3e5c257d..34108e44d58b 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1,10 +1,10 @@ use super::api::{self, WinError, set_file_information_by_handle}; use super::{IoResult, to_u16s}; -use crate::alloc::{alloc, handle_alloc_error}; +use crate::alloc::{Layout, alloc, dealloc, handle_alloc_error}; use crate::borrow::Cow; use crate::ffi::{OsStr, OsString, c_void}; use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; -use crate::mem::{self, MaybeUninit}; +use crate::mem::{self, MaybeUninit, offset_of}; use crate::os::windows::io::{AsHandle, BorrowedHandle}; use crate::os::windows::prelude::*; use crate::path::{Path, PathBuf}; @@ -1241,139 +1241,72 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { let old = maybe_verbatim(old)?; let new = maybe_verbatim(new)?; - let new_len_without_nul_in_bytes = (new.len() - 1).try_into().unwrap(); + if unsafe { c::MoveFileExW(old.as_ptr(), new.as_ptr(), c::MOVEFILE_REPLACE_EXISTING) } == 0 { + let err = api::get_last_error(); + // if `MoveFileExW` fails with ERROR_ACCESS_DENIED then try to move + // the file while ignoring the readonly attribute. + // This is accomplished by calling `SetFileInformationByHandle` with `FileRenameInfoEx`. + if err == WinError::ACCESS_DENIED { + let mut opts = OpenOptions::new(); + opts.access_mode(c::DELETE); + opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT | c::FILE_FLAG_BACKUP_SEMANTICS); + let Ok(f) = File::open_native(&old, &opts) else { return Err(err).io_result() }; - // The last field of FILE_RENAME_INFO, the file name, is unsized, - // and FILE_RENAME_INFO has two padding bytes. - // Therefore we need to make sure to not allocate less than - // size_of::() bytes, which would be the case with - // 0 or 1 character paths + a null byte. - let struct_size = size_of::() - .max(mem::offset_of!(c::FILE_RENAME_INFO, FileName) + new.len() * size_of::()); + // Calculate the layout of the `FILE_RENAME_INFO` we pass to `SetFileInformation` + // This is a dynamically sized struct so we need to get the position of the last field to calculate the actual size. + let Ok(new_len_without_nul_in_bytes): Result = ((new.len() - 1) * 2).try_into() + else { + return Err(err).io_result(); + }; + let offset: u32 = offset_of!(c::FILE_RENAME_INFO, FileName).try_into().unwrap(); + let struct_size = offset + new_len_without_nul_in_bytes + 2; + let layout = + Layout::from_size_align(struct_size as usize, align_of::()) + .unwrap(); - let struct_size: u32 = struct_size.try_into().unwrap(); + // SAFETY: We allocate enough memory for a full FILE_RENAME_INFO struct and a filename. + let file_rename_info; + unsafe { + file_rename_info = alloc(layout).cast::(); + if file_rename_info.is_null() { + handle_alloc_error(layout); + } - let create_file = |extra_access, extra_flags| { - let handle = unsafe { - HandleOrInvalid::from_raw_handle(c::CreateFileW( - old.as_ptr(), - c::SYNCHRONIZE | c::DELETE | extra_access, - c::FILE_SHARE_READ | c::FILE_SHARE_WRITE | c::FILE_SHARE_DELETE, - ptr::null(), - c::OPEN_EXISTING, - c::FILE_ATTRIBUTE_NORMAL | c::FILE_FLAG_BACKUP_SEMANTICS | extra_flags, - ptr::null_mut(), - )) - }; + (&raw mut (*file_rename_info).Anonymous).write(c::FILE_RENAME_INFO_0 { + Flags: c::FILE_RENAME_FLAG_REPLACE_IF_EXISTS + | c::FILE_RENAME_FLAG_POSIX_SEMANTICS, + }); - OwnedHandle::try_from(handle).map_err(|_| io::Error::last_os_error()) - }; + (&raw mut (*file_rename_info).RootDirectory).write(ptr::null_mut()); + // Don't include the NULL in the size + (&raw mut (*file_rename_info).FileNameLength).write(new_len_without_nul_in_bytes); - // The following code replicates `MoveFileEx`'s behavior as reverse-engineered from its disassembly. - // If `old` refers to a mount point, we move it instead of the target. - let handle = match create_file(c::FILE_READ_ATTRIBUTES, c::FILE_FLAG_OPEN_REPARSE_POINT) { - Ok(handle) => { - let mut file_attribute_tag_info: MaybeUninit = - MaybeUninit::uninit(); + new.as_ptr().copy_to_nonoverlapping( + (&raw mut (*file_rename_info).FileName).cast::(), + new.len(), + ); + } let result = unsafe { - cvt(c::GetFileInformationByHandleEx( - handle.as_raw_handle(), - c::FileAttributeTagInfo, - file_attribute_tag_info.as_mut_ptr().cast(), - size_of::().try_into().unwrap(), - )) - }; - - if let Err(err) = result { - if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _) - || err.raw_os_error() == Some(c::ERROR_INVALID_FUNCTION as _) - { - // `GetFileInformationByHandleEx` documents that not all underlying drivers support all file information classes. - // Since we know we passed the correct arguments, this means the underlying driver didn't understand our request; - // `MoveFileEx` proceeds by reopening the file without inhibiting reparse point behavior. - None - } else { - Some(Err(err)) - } - } else { - // SAFETY: The struct has been initialized by GetFileInformationByHandleEx - let file_attribute_tag_info = unsafe { file_attribute_tag_info.assume_init() }; - let file_type = FileType::new( - file_attribute_tag_info.FileAttributes, - file_attribute_tag_info.ReparseTag, - ); - - if file_type.is_symlink() { - // The file is a mount point, junction point or symlink so - // don't reopen the file so that the link gets renamed. - Some(Ok(handle)) - } else { - // Otherwise reopen the file without inhibiting reparse point behavior. - None - } - } - } - // The underlying driver may not support `FILE_FLAG_OPEN_REPARSE_POINT`: Retry without it. - Err(err) if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _) => None, - Err(err) => Some(Err(err)), - } - .unwrap_or_else(|| create_file(0, 0))?; - - let layout = - core::alloc::Layout::from_size_align(struct_size as _, align_of::()) - .unwrap(); - - let file_rename_info = unsafe { alloc(layout) } as *mut c::FILE_RENAME_INFO; - - if file_rename_info.is_null() { - handle_alloc_error(layout); - } - - // SAFETY: file_rename_info is a non-null pointer pointing to memory allocated by the global allocator. - let mut file_rename_info = unsafe { Box::from_raw(file_rename_info) }; - - // SAFETY: We have allocated enough memory for a full FILE_RENAME_INFO struct and a filename. - unsafe { - (&raw mut (*file_rename_info).Anonymous).write(c::FILE_RENAME_INFO_0 { - Flags: c::FILE_RENAME_FLAG_REPLACE_IF_EXISTS | c::FILE_RENAME_FLAG_POSIX_SEMANTICS, - }); - - (&raw mut (*file_rename_info).RootDirectory).write(ptr::null_mut()); - (&raw mut (*file_rename_info).FileNameLength).write(new_len_without_nul_in_bytes); - - new.as_ptr() - .copy_to_nonoverlapping((&raw mut (*file_rename_info).FileName) as *mut u16, new.len()); - } - - // We don't use `set_file_information_by_handle` here as `FILE_RENAME_INFO` is used for both `FileRenameInfo` and `FileRenameInfoEx`. - let result = unsafe { - cvt(c::SetFileInformationByHandle( - handle.as_raw_handle(), - c::FileRenameInfoEx, - (&raw const *file_rename_info).cast::(), - struct_size, - )) - }; - - if let Err(err) = result { - if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _) { - // FileRenameInfoEx and FILE_RENAME_FLAG_POSIX_SEMANTICS were added in Windows 10 1607; retry with FileRenameInfo. - file_rename_info.Anonymous.ReplaceIfExists = true; - - cvt(unsafe { c::SetFileInformationByHandle( - handle.as_raw_handle(), - c::FileRenameInfo, - (&raw const *file_rename_info).cast::(), + f.as_raw_handle(), + c::FileRenameInfoEx, + file_rename_info.cast::(), struct_size, ) - })?; + }; + unsafe { dealloc(file_rename_info.cast::(), layout) }; + if result == 0 { + if api::get_last_error() == WinError::DIR_NOT_EMPTY { + return Err(WinError::DIR_NOT_EMPTY).io_result(); + } else { + return Err(err).io_result(); + } + } } else { - return Err(err); + return Err(err).io_result(); } } - Ok(()) } From 3cb53df1feaba73b84344c8c0e3dc4120ad8c95b Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 6 Mar 2025 14:18:18 +0000 Subject: [PATCH 806/991] Return OutOfMemoryError and update docs --- library/std/src/fs.rs | 2 +- library/std/src/sys/pal/windows/fs.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 4314c8a0b182..46b5860123fc 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2446,7 +2446,7 @@ pub fn symlink_metadata>(path: P) -> io::Result { /// # Platform-specific behavior /// /// This function currently corresponds to the `rename` function on Unix -/// and the `SetFileInformationByHandle` function on Windows. +/// and the `MoveFileExW` or `SetFileInformationByHandle` function on Windows. /// /// Because of this, the behavior when both `from` and `to` exist differs. On /// Unix, if `from` is a directory, `to` must also be an (empty) directory. If diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 34108e44d58b..8fce0496d80c 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1,6 +1,6 @@ use super::api::{self, WinError, set_file_information_by_handle}; use super::{IoResult, to_u16s}; -use crate::alloc::{Layout, alloc, dealloc, handle_alloc_error}; +use crate::alloc::{Layout, alloc, dealloc}; use crate::borrow::Cow; use crate::ffi::{OsStr, OsString, c_void}; use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; @@ -1269,7 +1269,7 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { unsafe { file_rename_info = alloc(layout).cast::(); if file_rename_info.is_null() { - handle_alloc_error(layout); + return Err(io::ErrorKind::OutOfMemory.into()); } (&raw mut (*file_rename_info).Anonymous).write(c::FILE_RENAME_INFO_0 { From d975bd3a67e4f18c02f57d8d66a9d32daa295a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 27 Feb 2025 21:09:45 +0000 Subject: [PATCH 807/991] Remove highlighting of spans on `-Zteach` `-Zteach` is perma-unstable, barely used, the highlighting logic buggy and the flag being passed around is tech-debt. We should likely remove `-Zteach` in its entirely. --- compiler/rustc_errors/src/emitter.rs | 11 ----------- compiler/rustc_session/src/session.rs | 1 - src/librustdoc/core.rs | 1 - 3 files changed, 13 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index f7f842393084..18846a6dbe10 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -616,7 +616,6 @@ pub struct HumanEmitter { #[setters(skip)] fallback_bundle: LazyFallbackBundle, short_message: bool, - teach: bool, ui_testing: bool, ignored_directories_in_source_blocks: Vec, diagnostic_width: Option, @@ -642,7 +641,6 @@ impl HumanEmitter { fluent_bundle: None, fallback_bundle, short_message: false, - teach: false, ui_testing: false, ignored_directories_in_source_blocks: Vec::new(), diagnostic_width: None, @@ -1044,15 +1042,6 @@ impl HumanEmitter { underline.style, ); } - _ if self.teach => { - buffer.set_style_range( - line_offset, - (code_offset + annotation.start_col.display).saturating_sub(left), - (code_offset + annotation.end_col.display).saturating_sub(left), - underline.style, - annotation.is_primary, - ); - } _ => {} } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index aa1e9762f397..bcd9a73d9d30 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -930,7 +930,6 @@ fn default_emitter( .fluent_bundle(bundle) .sm(source_map) .short_message(short) - .teach(sopts.unstable_opts.teach) .diagnostic_width(sopts.diagnostic_width) .macro_backtrace(macro_backtrace) .track_diagnostics(track_diagnostics) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index f95ae380fa8d..719f1f978fec 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -160,7 +160,6 @@ pub(crate) fn new_dcx( HumanEmitter::new(stderr_destination(color_config), fallback_bundle) .sm(source_map.map(|sm| sm as _)) .short_message(short) - .teach(unstable_opts.teach) .diagnostic_width(diagnostic_width) .track_diagnostics(unstable_opts.track_diagnostics) .theme(if let HumanReadableErrorType::Unicode = kind { From 72326bfe4033fe51c5cb0f31614bbf6e66ec77f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 27 Feb 2025 21:11:22 +0000 Subject: [PATCH 808/991] On long spans, trim the middle of them to make them fit in the terminal width When encountering a single line span that is wider than the terminal, we keep context at the start and end of the span but otherwise remove the code from the middle. This is somewhat independent from whether the left and right margins of the output have been trimmed as well. ``` error[E0308]: mismatched types --> $DIR/long-span.rs:6:15 | LL | ... = [0, 0, 0, 0, ..., 0, 0]; | ^^^^^^^^^^^^^...^^^^^^^ expected `u8`, found `[{integer}; 1681]` ``` Address part of #137680 (missing handling of the long suggestion). Fix #125581. --- compiler/rustc_errors/src/emitter.rs | 27 +++++++++++++++++++ compiler/rustc_errors/src/styled_buffer.rs | 10 +++++++ .../ui/diagnostic-width/long-span.long.stderr | 9 +++++++ .../diagnostic-width/long-span.longest.stderr | 9 +++++++ tests/ui/diagnostic-width/long-span.rs | 9 +++++++ .../diagnostic-width/long-span.short.stderr | 9 +++++++ .../long-span.shortest.stderr | 9 +++++++ tests/ui/parser/raw/too-many-hash.stderr | 4 +-- .../rust-2024/reserved-guarded-strings.stderr | 4 +-- 9 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 tests/ui/diagnostic-width/long-span.long.stderr create mode 100644 tests/ui/diagnostic-width/long-span.longest.stderr create mode 100644 tests/ui/diagnostic-width/long-span.rs create mode 100644 tests/ui/diagnostic-width/long-span.short.stderr create mode 100644 tests/ui/diagnostic-width/long-span.shortest.stderr diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 18846a6dbe10..9277bae94ecd 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1238,6 +1238,33 @@ impl HumanEmitter { ); } } + + // We look for individual *long* spans, and we trim the *middle*, so that we render + // LL | ...= [0, 0, 0, ..., 0, 0]; + // | ^^^^^^^^^^...^^^^^^^ expected `&[u8]`, found `[{integer}; 1680]` + for &(pos, annotation) in &annotations_position { + let AnnotationType::Singleline = annotation.annotation_type else { continue }; + let width = annotation.end_col.display - annotation.start_col.display; + if pos == 0 && width > margin.column_width && width > 10 { + // If the terminal is *too* small, we keep at least a tiny bit of the span for + // display. + let pad = max(margin.column_width / 2, 5); + // Code line + buffer.replace( + line_offset, + annotation.start_col.file + pad, + annotation.end_col.file - pad, + self.margin(), + ); + // Underline line + buffer.replace( + line_offset + 1, + annotation.start_col.file + pad, + annotation.end_col.file - pad, + self.margin(), + ); + } + } annotations_position .iter() .filter_map(|&(_, annotation)| match annotation.annotation_type { diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index 5ca9e9b18f34..b0f4ec84a899 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -89,6 +89,16 @@ impl StyledBuffer { } } + pub(crate) fn replace(&mut self, line: usize, start: usize, end: usize, string: &str) { + if start == end { + return; + } + let _ = self.lines[line].drain(start..(end - string.chars().count())); + for (i, c) in string.chars().enumerate() { + self.lines[line][start + i] = StyledChar::new(c, Style::LineNumber); + } + } + /// For given `line` inserts `string` with `style` before old content of that line, /// adding lines if needed pub(crate) fn prepend(&mut self, line: usize, string: &str, style: Style) { diff --git a/tests/ui/diagnostic-width/long-span.long.stderr b/tests/ui/diagnostic-width/long-span.long.stderr new file mode 100644 index 000000000000..81edde85b33a --- /dev/null +++ b/tests/ui/diagnostic-width/long-span.long.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + ╭▸ $DIR/long-span.rs:7:15 + │ +LL │ …u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]… + ╰╴ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━…━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ expected `u8`, found `[{integer}; 1680]` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/diagnostic-width/long-span.longest.stderr b/tests/ui/diagnostic-width/long-span.longest.stderr new file mode 100644 index 000000000000..77aafc5f4267 --- /dev/null +++ b/tests/ui/diagnostic-width/long-span.longest.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/long-span.rs:7:15 + | +LL | ... = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `[{integer}; 1680]` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/diagnostic-width/long-span.rs b/tests/ui/diagnostic-width/long-span.rs new file mode 100644 index 000000000000..2feacdd96047 --- /dev/null +++ b/tests/ui/diagnostic-width/long-span.rs @@ -0,0 +1,9 @@ +//@ revisions: shortest short long longest +//@[shortest] compile-flags: --diagnostic-width=4 +//@[short] compile-flags: --diagnostic-width=12 -Zunstable-options --json=diagnostic-unicode +//@[long] compile-flags: --diagnostic-width=80 -Zunstable-options --json=diagnostic-unicode +//@[longest] compile-flags: --diagnostic-width=120 +// ignore-tidy-linelength +const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; +//~^ ERROR E0308 +fn main() {} diff --git a/tests/ui/diagnostic-width/long-span.short.stderr b/tests/ui/diagnostic-width/long-span.short.stderr new file mode 100644 index 000000000000..8e62acc936ce --- /dev/null +++ b/tests/ui/diagnostic-width/long-span.short.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + ╭▸ $DIR/long-span.rs:7:15 + │ +LL │ …u8 = [0, 0, 0…0]… + ╰╴ ━━━━━━━━…━━ expected `u8`, found `[{integer}; 1680]` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/diagnostic-width/long-span.shortest.stderr b/tests/ui/diagnostic-width/long-span.shortest.stderr new file mode 100644 index 000000000000..d9cec96ad8fd --- /dev/null +++ b/tests/ui/diagnostic-width/long-span.shortest.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/long-span.rs:7:15 + | +LL | ... = [0, 0, 0...... + | ^^^^^^^^...^^ expected `u8`, found `[{integer}; 1680]` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/raw/too-many-hash.stderr b/tests/ui/parser/raw/too-many-hash.stderr index 1c46b5385cd9..61fcbcee1595 100644 --- a/tests/ui/parser/raw/too-many-hash.stderr +++ b/tests/ui/parser/raw/too-many-hash.stderr @@ -1,8 +1,8 @@ error: too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found 256 --> $DIR/too-many-hash.rs:4:19 | -LL | ... = r################################################################################################################################################################################################################################################################"very raw"##############################################################################################################################################################################################################################################################... - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... = r############################################################################...#############################################################... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rust-2024/reserved-guarded-strings.stderr b/tests/ui/rust-2024/reserved-guarded-strings.stderr index 0f3b06147c4f..5c0f50645467 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings.stderr +++ b/tests/ui/rust-2024/reserved-guarded-strings.stderr @@ -241,8 +241,8 @@ LL | demo2!(#"foo"## #); error: invalid string literal --> $DIR/reserved-guarded-strings.rs:71:12 | -LL | ...n!(####################################################################################################################################################################################################################################################################"foo... - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ...n!(######################################################################...#################################################################"foo... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: unprefixed guarded string literals are reserved for future use since Rust 2024 help: consider inserting whitespace here From f1c751bc1a08e3439a9d0c482cbb0ea0fc8f644f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 27 Feb 2025 21:12:58 +0000 Subject: [PATCH 809/991] Refactor `emitter` to better account for unicode chars when trimming Change the way that underline positions are calculated by delaying using the "visual" column position until the last possible moment, instead using the "file"/byte position in the file, and then calculating visual positioning as late as possible. This should make the underlines more resilient to non-1-width unicode chars. Unfortunately, as part of this change (which fixes some visual bugs) comes with the loss of some eager tab codepoint handling, but the output remains legible despite some minor regression on the "margin trimming" logic. --- compiler/rustc_errors/src/emitter.rs | 177 +++---- tests/ui/codemap_tests/tab_2.stderr | 2 +- .../ui/diagnostic-width/long-span.long.stderr | 2 +- .../diagnostic-width/long-span.longest.stderr | 2 +- .../diagnostic-width/long-span.short.stderr | 2 +- .../long-span.shortest.stderr | 2 +- ...width-unicode-multiline-label.ascii.stderr | 59 ++- .../non-1-width-unicode-multiline-label.rs | 6 + ...dth-unicode-multiline-label.unicode.stderr | 59 ++- .../non-whitespace-trimming-unicode.stderr | 8 +- .../ui/diagnostic-width/tabs-trimming.stderr | 20 +- .../multiline-removal-suggestion.svg | 436 +++++++++--------- tests/ui/issues/issue-44078.stderr | 2 +- .../lexer/unterminated-nested-comment.stderr | 2 +- tests/ui/macros/not-utf8.stderr | 2 +- tests/ui/macros/same-sequence-span.stderr | 2 +- tests/ui/parser/byte-string-literals.stderr | 2 +- tests/ui/parser/raw/too-many-hash.stderr | 2 +- tests/ui/parser/unbalanced-doublequote.stderr | 2 +- .../rust-2024/reserved-guarded-strings.stderr | 2 +- 20 files changed, 462 insertions(+), 329 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 9277bae94ecd..9a3c96776b97 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -113,24 +113,11 @@ impl Margin { self.computed_left > 0 } - fn was_cut_right(&self, line_len: usize) -> bool { - let right = - if self.computed_right == self.span_right || self.computed_right == self.label_right { - // FIXME: This comment refers to the only callsite of this method. - // Rephrase it or refactor it, so it can stand on its own. - // Account for the "..." padding given above. Otherwise we end up with code lines - // that do fit but end in "..." as if they were trimmed. - // FIXME: Don't hard-code this offset. Is this meant to represent - // `2 * str_width(self.margin())`? - self.computed_right - 6 - } else { - self.computed_right - }; - right < line_len && self.computed_left + self.column_width < line_len - } - fn compute(&mut self, max_line_len: usize) { // When there's a lot of whitespace (>20), we want to trim it as it is useless. + // FIXME: this doesn't account for '\t', but to do so correctly we need to perform that + // calculation later, right before printing in order to be accurate with both unicode + // handling and trimming of long lines. self.computed_left = if self.whitespace_left > 20 { self.whitespace_left - 16 // We want some padding. } else { @@ -668,43 +655,43 @@ impl HumanEmitter { width_offset: usize, code_offset: usize, margin: Margin, - ) { - // Tabs are assumed to have been replaced by spaces in calling code. - debug_assert!(!source_string.contains('\t')); + ) -> usize { let line_len = source_string.len(); // Create the source line we will highlight. let left = margin.left(line_len); let right = margin.right(line_len); // FIXME: The following code looks fishy. See #132860. // On long lines, we strip the source line, accounting for unicode. - let mut taken = 0; let code: String = source_string .chars() - .skip(left) - .take_while(|ch| { - // Make sure that the trimming on the right will fall within the terminal width. - let next = char_width(*ch); - if taken + next > right - left { - return false; - } - taken += next; - true - }) + .enumerate() + .skip_while(|(i, _)| *i < left) + .take_while(|(i, _)| *i < right) + .map(|(_, c)| c) .collect(); + let code = normalize_whitespace(&code); + let was_cut_right = + source_string.chars().enumerate().skip_while(|(i, _)| *i < right).next().is_some(); buffer.puts(line_offset, code_offset, &code, Style::Quotation); let placeholder = self.margin(); if margin.was_cut_left() { // We have stripped some code/whitespace from the beginning, make it clear. buffer.puts(line_offset, code_offset, placeholder, Style::LineNumber); } - if margin.was_cut_right(line_len) { + if was_cut_right { let padding = str_width(placeholder); // We have stripped some code after the rightmost span end, make it clear we did so. - buffer.puts(line_offset, code_offset + taken - padding, placeholder, Style::LineNumber); + buffer.puts( + line_offset, + code_offset + str_width(&code) - padding, + placeholder, + Style::LineNumber, + ); } buffer.puts(line_offset, 0, &self.maybe_anonymized(line_index), Style::LineNumber); self.draw_col_separator_no_space(buffer, line_offset, width_offset - 2); + left } #[instrument(level = "trace", skip(self), ret)] @@ -736,22 +723,16 @@ impl HumanEmitter { return Vec::new(); } - let source_string = match file.get_line(line.line_index - 1) { - Some(s) => normalize_whitespace(&s), - None => return Vec::new(), + let Some(source_string) = file.get_line(line.line_index - 1) else { + return Vec::new(); }; trace!(?source_string); let line_offset = buffer.num_lines(); - // Left trim - let left = margin.left(source_string.len()); - + // Left trim. // FIXME: This looks fishy. See #132860. - // Account for unicode characters of width !=0 that were removed. - let left = source_string.chars().take(left).map(|ch| char_width(ch)).sum(); - - self.draw_line( + let left = self.draw_line( buffer, &source_string, line.line_index, @@ -1033,12 +1014,18 @@ impl HumanEmitter { let pos = pos + 1; match annotation.annotation_type { AnnotationType::MultilineStart(depth) | AnnotationType::MultilineEnd(depth) => { + let pre: usize = source_string + .chars() + .take(annotation.start_col.file) + .skip(left) + .map(|c| char_width(c)) + .sum(); self.draw_range( buffer, underline.multiline_horizontal, line_offset + pos, width_offset + depth, - (code_offset + annotation.start_col.display).saturating_sub(left), + code_offset + pre, underline.style, ); } @@ -1061,11 +1048,18 @@ impl HumanEmitter { let underline = self.underline(annotation.is_primary); let pos = pos + 1; + let code_offset = code_offset + + source_string + .chars() + .take(annotation.start_col.file) + .skip(left) + .map(|c| char_width(c)) + .sum::(); if pos > 1 && (annotation.has_label() || annotation.takes_space()) { for p in line_offset + 1..=line_offset + pos { buffer.putc( p, - (code_offset + annotation.start_col.display).saturating_sub(left), + code_offset, match annotation.annotation_type { AnnotationType::MultilineLine(_) => underline.multiline_vertical, _ => underline.vertical_text_line, @@ -1076,7 +1070,7 @@ impl HumanEmitter { if let AnnotationType::MultilineStart(_) = annotation.annotation_type { buffer.putc( line_offset + pos, - (code_offset + annotation.start_col.display).saturating_sub(left), + code_offset, underline.bottom_right, underline.style, ); @@ -1086,7 +1080,7 @@ impl HumanEmitter { { buffer.putc( line_offset + pos, - (code_offset + annotation.start_col.display).saturating_sub(left), + code_offset, underline.multiline_bottom_right_with_text, underline.style, ); @@ -1144,13 +1138,30 @@ impl HumanEmitter { let style = if annotation.is_primary { Style::LabelPrimary } else { Style::LabelSecondary }; let (pos, col) = if pos == 0 { - if annotation.end_col.display == 0 { - (pos + 1, (annotation.end_col.display + 2).saturating_sub(left)) + let pre: usize = source_string + .chars() + .take(annotation.end_col.file) + .skip(left) + .map(|c| char_width(c)) + .sum(); + if annotation.end_col.file == 0 { + (pos + 1, (pre + 2)) } else { - (pos + 1, (annotation.end_col.display + 1).saturating_sub(left)) + let pad = if annotation.end_col.file - annotation.start_col.file == 0 { + 2 + } else { + 1 + }; + (pos + 1, (pre + pad)) } } else { - (pos + 2, annotation.start_col.display.saturating_sub(left)) + let pre: usize = source_string + .chars() + .take(annotation.start_col.file) + .skip(left) + .map(|c| char_width(c)) + .sum(); + (pos + 2, pre) }; if let Some(ref label) = annotation.label { buffer.puts(line_offset + pos, code_offset + col, label, style); @@ -1183,14 +1194,35 @@ impl HumanEmitter { // | _^ test for &(pos, annotation) in &annotations_position { let uline = self.underline(annotation.is_primary); - for p in annotation.start_col.display..annotation.end_col.display { + let width = annotation.end_col.file - annotation.start_col.file; + let previous: String = + source_string.chars().take(annotation.start_col.file).skip(left).collect(); + let underlined: String = + source_string.chars().skip(annotation.start_col.file).take(width).collect(); + debug!(?previous, ?underlined); + let code_offset = code_offset + + source_string + .chars() + .take(annotation.start_col.file) + .skip(left) + .map(|c| char_width(c)) + .sum::(); + let ann_width: usize = source_string + .chars() + .skip(annotation.start_col.file) + .take(width) + .map(|c| char_width(c)) + .sum(); + let ann_width = if ann_width == 0 + && matches!(annotation.annotation_type, AnnotationType::Singleline) + { + 1 + } else { + ann_width + }; + for p in 0..ann_width { // The default span label underline. - buffer.putc( - line_offset + 1, - (code_offset + p).saturating_sub(left), - uline.underline, - uline.style, - ); + buffer.putc(line_offset + 1, code_offset + p, uline.underline, uline.style); } if pos == 0 @@ -1202,7 +1234,7 @@ impl HumanEmitter { // The beginning of a multiline span with its leftward moving line on the same line. buffer.putc( line_offset + 1, - (code_offset + annotation.start_col.display).saturating_sub(left), + code_offset, match annotation.annotation_type { AnnotationType::MultilineStart(_) => uline.top_right_flat, AnnotationType::MultilineEnd(_) => uline.multiline_end_same_line, @@ -1220,7 +1252,7 @@ impl HumanEmitter { // so we start going down first. buffer.putc( line_offset + 1, - (code_offset + annotation.start_col.display).saturating_sub(left), + code_offset, match annotation.annotation_type { AnnotationType::MultilineStart(_) => uline.multiline_start_down, AnnotationType::MultilineEnd(_) => uline.multiline_end_up, @@ -1230,12 +1262,7 @@ impl HumanEmitter { ); } else if pos != 0 && annotation.has_label() { // The beginning of a span label with an actual label, we'll point down. - buffer.putc( - line_offset + 1, - (code_offset + annotation.start_col.display).saturating_sub(left), - uline.label_start, - uline.style, - ); + buffer.putc(line_offset + 1, code_offset, uline.label_start, uline.style); } } @@ -1718,17 +1745,11 @@ impl HumanEmitter { // non-rustc_lexer::is_whitespace() chars are reported as an // error (ex. no-break-spaces \u{a0}), and thus can't be considered // for removal during error reporting. + // FIXME: doesn't account for '\t' properly. let leading_whitespace = source_string .chars() .take_while(|c| rustc_lexer::is_whitespace(*c)) - .map(|c| { - match c { - // Tabs are displayed as 4 spaces - '\t' => 4, - _ => 1, - } - }) - .sum(); + .count(); if source_string.chars().any(|c| !rustc_lexer::is_whitespace(c)) { whitespace_margin = min(whitespace_margin, leading_whitespace); } @@ -1742,8 +1763,8 @@ impl HumanEmitter { let mut span_left_margin = usize::MAX; for line in &annotated_file.lines { for ann in &line.annotations { - span_left_margin = min(span_left_margin, ann.start_col.display); - span_left_margin = min(span_left_margin, ann.end_col.display); + span_left_margin = min(span_left_margin, ann.start_col.file); + span_left_margin = min(span_left_margin, ann.end_col.file); } } if span_left_margin == usize::MAX { @@ -1763,12 +1784,12 @@ impl HumanEmitter { .map_or(0, |s| s.len()), ); for ann in &line.annotations { - span_right_margin = max(span_right_margin, ann.start_col.display); - span_right_margin = max(span_right_margin, ann.end_col.display); + span_right_margin = max(span_right_margin, ann.start_col.file); + span_right_margin = max(span_right_margin, ann.end_col.file); // FIXME: account for labels not in the same line let label_right = ann.label.as_ref().map_or(0, |l| l.len() + 1); label_right_margin = - max(label_right_margin, ann.end_col.display + label_right); + max(label_right_margin, ann.end_col.file + label_right); } } diff --git a/tests/ui/codemap_tests/tab_2.stderr b/tests/ui/codemap_tests/tab_2.stderr index b22c7b426651..4f9a937155dd 100644 --- a/tests/ui/codemap_tests/tab_2.stderr +++ b/tests/ui/codemap_tests/tab_2.stderr @@ -4,7 +4,7 @@ error[E0765]: unterminated double quote string LL | """; | ___________________^ LL | | } - | |_^ + | |__^ error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-span.long.stderr b/tests/ui/diagnostic-width/long-span.long.stderr index 81edde85b33a..e39f4000d3cd 100644 --- a/tests/ui/diagnostic-width/long-span.long.stderr +++ b/tests/ui/diagnostic-width/long-span.long.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types ╭▸ $DIR/long-span.rs:7:15 │ -LL │ …u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]… +LL │ …u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; ╰╴ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━…━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ expected `u8`, found `[{integer}; 1680]` error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-span.longest.stderr b/tests/ui/diagnostic-width/long-span.longest.stderr index 77aafc5f4267..8e2bad93692d 100644 --- a/tests/ui/diagnostic-width/long-span.longest.stderr +++ b/tests/ui/diagnostic-width/long-span.longest.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/long-span.rs:7:15 | -LL | ... = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... +LL | ... = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `[{integer}; 1680]` error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-span.short.stderr b/tests/ui/diagnostic-width/long-span.short.stderr index 8e62acc936ce..73ee895a89b6 100644 --- a/tests/ui/diagnostic-width/long-span.short.stderr +++ b/tests/ui/diagnostic-width/long-span.short.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types ╭▸ $DIR/long-span.rs:7:15 │ -LL │ …u8 = [0, 0, 0…0]… +LL │ …u8 = [0, 0, 0…0]; ╰╴ ━━━━━━━━…━━ expected `u8`, found `[{integer}; 1680]` error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-span.shortest.stderr b/tests/ui/diagnostic-width/long-span.shortest.stderr index d9cec96ad8fd..2b485e755413 100644 --- a/tests/ui/diagnostic-width/long-span.shortest.stderr +++ b/tests/ui/diagnostic-width/long-span.shortest.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/long-span.rs:7:15 | -LL | ... = [0, 0, 0...... +LL | ... = [0, 0, 0...0]; | ^^^^^^^^...^^ expected `u8`, found `[{integer}; 1680]` error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr index 4d8afb6f3ad9..60ce0d9a1483 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr @@ -1,11 +1,41 @@ error[E0369]: cannot add `&str` to `&str` - --> $DIR/non-1-width-unicode-multiline-label.rs:7:260 + --> $DIR/non-1-width-unicode-multiline-label.rs:7:237 | -LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇...࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; - | -------------- ^ -------------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str +LL | ...👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str + | + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun.to_owned() + " really fun!"; + | +++++++++++ + +error[E0369]: cannot add `&str` to `&str` + --> $DIR/non-1-width-unicode-multiline-label.rs:9:384 + | +LL | ...👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str + | + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun.to_owned() + " really fun!"; + | +++++++++++ + +error[E0369]: cannot add `&str` to `&str` + --> $DIR/non-1-width-unicode-multiline-label.rs:11:260 + | +LL | ...࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str | = note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -13,6 +43,21 @@ help: create an owned `String` from a string reference LL | let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!"; | +++++++++++ -error: aborting due to 1 previous error +error[E0369]: cannot add `&str` to `&str` + --> $DIR/non-1-width-unicode-multiline-label.rs:13:219 + | +LL | ...xxxxxxxxxxxxxxxxxxxx"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str + | + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _ = "xxxxxxx👨👩👧👦xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx👨xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; let _a = unicode_is_fun.to_owned() + " really fun!"; + | +++++++++++ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs index e630db8ba42a..6b9b27f6297f 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs @@ -4,6 +4,12 @@ fn main() { let unicode_is_fun = "؁‱ஹ௸௵꧄.ဪ꧅⸻𒈙𒐫﷽𒌄𒈟𒍼𒁎𒀱𒌧𒅃 𒈓𒍙𒊎𒄡𒅌𒁏𒀰𒐪𒐩𒈙𒐫𪚥"; + let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + //[ascii]~^ ERROR cannot add `&str` to `&str` + let _ = "👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦"; let _a = unicode_is_fun + " really fun!"; + //[ascii]~^ ERROR cannot add `&str` to `&str` let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; //[ascii]~^ ERROR cannot add `&str` to `&str` + let _ = "xxxxxxx👨‍👩‍👧‍👦xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx👨xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; let _a = unicode_is_fun + " really fun!"; + //[ascii]~^ ERROR cannot add `&str` to `&str` } diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr index ed8ce770bb7e..15b5dd9d7e2d 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr @@ -1,11 +1,41 @@ error[E0369]: cannot add `&str` to `&str` - ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:7:260 + ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:7:237 │ -LL │ …ཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉…࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; - │ ┬───────────── ┯ ────────────── &str - │ │ │ - │ │ `+` cannot be used to concatenate two `&str` strings - │ &str +LL │ …👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str + │ + ╰ note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + ╭╴ +LL │ let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun.to_owned() + " really fun!"; + ╰╴ +++++++++++ + +error[E0369]: cannot add `&str` to `&str` + ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:9:384 + │ +LL │ …👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str + │ + ╰ note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + ╭╴ +LL │ let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun.to_owned() + " really fun!"; + ╰╴ +++++++++++ + +error[E0369]: cannot add `&str` to `&str` + ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:11:260 + │ +LL │ …࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str │ ╰ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -13,6 +43,21 @@ help: create an owned `String` from a string reference LL │ let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!"; ╰╴ +++++++++++ -error: aborting due to 1 previous error +error[E0369]: cannot add `&str` to `&str` + ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:13:219 + │ +LL │ …xxxxxxxxxxxxxxxxxxxxxx"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str + │ + ╰ note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + ╭╴ +LL │ let _ = "xxxxxxx👨👩👧👦xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx👨xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; let _a = unicode_is_fun.to_owned() + " really fun!"; + ╰╴ +++++++++++ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr b/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr index da3d8d318922..5408825d8cd6 100644 --- a/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr +++ b/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr @@ -1,10 +1,10 @@ error[E0308]: mismatched types --> $DIR/non-whitespace-trimming-unicode.rs:4:415 | -LL | ...♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄... - | -- ^^ expected `()`, found integer - | | - | expected due to this +LL | ...♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼... + | -- ^^ expected `()`, found integer + | | + | expected due to this error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/tabs-trimming.stderr b/tests/ui/diagnostic-width/tabs-trimming.stderr index 85103fbf6f59..a896345bd702 100644 --- a/tests/ui/diagnostic-width/tabs-trimming.stderr +++ b/tests/ui/diagnostic-width/tabs-trimming.stderr @@ -1,20 +1,20 @@ error[E0408]: variable `v` is not bound in all patterns --> $DIR/tabs-trimming.rs:9:16 | -LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... - | - ^ ^ pattern doesn't bind `v` - | | | - | | pattern doesn't bind `v` - | variable not in all patterns +LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... + | - ^ ^ pattern doesn't bind `v` + | | | + | | pattern doesn't bind `v` + | variable not in all patterns error[E0381]: used binding `v` is possibly-uninitialized --> $DIR/tabs-trimming.rs:9:67 | -LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... - | - ^ `v` used here but it is possibly-uninitialized - | | - | binding initialized here in some conditions - | binding declared here but left uninitialized +LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... + | - ^ `v` used here but it is possibly-uninitialized + | | + | binding initialized here in some conditions + | binding declared here but left uninitialized | = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.svg b/tests/ui/error-emitter/multiline-removal-suggestion.svg index 95c7740f6995..0820baaff09e 100644 --- a/tests/ui/error-emitter/multiline-removal-suggestion.svg +++ b/tests/ui/error-emitter/multiline-removal-suggestion.svg @@ -1,4 +1,4 @@ - + AsVecIntoIter for IntoIter { type Item = I; diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs index 020cf4d73651..1414f797e8a4 100644 --- a/library/alloc/src/collections/mod.rs +++ b/library/alloc/src/collections/mod.rs @@ -24,41 +24,54 @@ pub mod btree_map { pub mod btree_set { //! An ordered set based on a B-Tree. #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(test))] pub use super::btree::set::*; } +#[cfg(not(test))] use core::fmt::Display; #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] +#[cfg(not(test))] pub use binary_heap::BinaryHeap; #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] +#[cfg(not(test))] pub use btree_map::BTreeMap; #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] +#[cfg(not(test))] pub use btree_set::BTreeSet; #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] +#[cfg(not(test))] pub use linked_list::LinkedList; #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] +#[cfg(not(test))] pub use vec_deque::VecDeque; +#[cfg(not(test))] use crate::alloc::{Layout, LayoutError}; /// The error type for `try_reserve` methods. #[derive(Clone, PartialEq, Eq, Debug)] #[stable(feature = "try_reserve", since = "1.57.0")] +#[cfg(not(test))] pub struct TryReserveError { kind: TryReserveErrorKind, } +#[cfg(test)] +pub use realalloc::collections::TryReserveError; + +#[cfg(not(test))] impl TryReserveError { /// Details about the allocation that caused the error #[inline] @@ -80,6 +93,7 @@ impl TryReserveError { reason = "Uncertain how much info should be exposed", issue = "48043" )] +#[cfg(not(test))] pub enum TryReserveErrorKind { /// Error due to the computed capacity exceeding the collection's maximum /// (usually `isize::MAX` bytes). @@ -103,11 +117,15 @@ pub enum TryReserveErrorKind { }, } +#[cfg(test)] +pub use realalloc::collections::TryReserveErrorKind; + #[unstable( feature = "try_reserve_kind", reason = "Uncertain how much info should be exposed", issue = "48043" )] +#[cfg(not(test))] impl From for TryReserveError { #[inline] fn from(kind: TryReserveErrorKind) -> Self { @@ -116,6 +134,7 @@ impl From for TryReserveError { } #[unstable(feature = "try_reserve_kind", reason = "new API", issue = "48043")] +#[cfg(not(test))] impl From for TryReserveErrorKind { /// Always evaluates to [`TryReserveErrorKind::CapacityOverflow`]. #[inline] @@ -125,6 +144,7 @@ impl From for TryReserveErrorKind { } #[stable(feature = "try_reserve", since = "1.57.0")] +#[cfg(not(test))] impl Display for TryReserveError { fn fmt( &self, @@ -152,4 +172,5 @@ trait SpecExtend { } #[stable(feature = "try_reserve", since = "1.57.0")] +#[cfg(not(test))] impl core::error::Error for TryReserveError {} diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 299c8b8679e3..f8844e2d3a5c 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -645,6 +645,7 @@ impl VecDeque { /// initialized rather than only supporting `0..len`. Requires that /// `initialized.start` ≤ `initialized.end` ≤ `capacity`. #[inline] + #[cfg(not(test))] pub(crate) unsafe fn from_contiguous_raw_parts_in( ptr: *mut T, initialized: Range, diff --git a/library/alloc/src/collections/vec_deque/spec_extend.rs b/library/alloc/src/collections/vec_deque/spec_extend.rs index d246385ca841..7c7072c4c3a1 100644 --- a/library/alloc/src/collections/vec_deque/spec_extend.rs +++ b/library/alloc/src/collections/vec_deque/spec_extend.rs @@ -3,6 +3,7 @@ use core::slice; use super::VecDeque; use crate::alloc::Allocator; +#[cfg(not(test))] use crate::vec; // Specialization trait used for VecDeque::extend @@ -78,6 +79,7 @@ where } } +#[cfg(not(test))] impl SpecExtend> for VecDeque { #[track_caller] fn spec_extend(&mut self, mut iterator: vec::IntoIter) { diff --git a/library/alloc/src/collections/vec_deque/spec_from_iter.rs b/library/alloc/src/collections/vec_deque/spec_from_iter.rs index 1efe84d6d7d7..c80a30c2103d 100644 --- a/library/alloc/src/collections/vec_deque/spec_from_iter.rs +++ b/library/alloc/src/collections/vec_deque/spec_from_iter.rs @@ -19,6 +19,7 @@ where } } +#[cfg(not(test))] impl SpecFromIter> for VecDeque { #[inline] fn spec_from_iter(iterator: crate::vec::IntoIter) -> Self { diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index fd93045a5ac4..f6743c657109 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -10,7 +10,6 @@ use core::{fmt, mem, ops, ptr, slice}; use crate::borrow::{Cow, ToOwned}; use crate::boxed::Box; use crate::rc::Rc; -use crate::slice::hack::into_vec; use crate::string::String; #[cfg(target_has_atomic = "ptr")] use crate::sync::Arc; @@ -103,7 +102,7 @@ use crate::vec::Vec; /// of `CString` instances can lead to invalid memory accesses, memory leaks, /// and other memory errors. #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] -#[cfg_attr(not(test), rustc_diagnostic_item = "cstring_type")] +#[rustc_diagnostic_item = "cstring_type"] #[stable(feature = "alloc_c_string", since = "1.64.0")] pub struct CString { // Invariant 1: the slice ends with a zero byte and has a length of at least one. @@ -491,7 +490,7 @@ impl CString { #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "cstring_into", since = "1.7.0")] pub fn into_bytes(self) -> Vec { - let mut vec = into_vec(self.into_inner()); + let mut vec = self.into_inner().into_vec(); let _nul = vec.pop(); debug_assert_eq!(_nul, Some(0u8)); vec @@ -512,7 +511,7 @@ impl CString { #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "cstring_into", since = "1.7.0")] pub fn into_bytes_with_nul(self) -> Vec { - into_vec(self.into_inner()) + self.into_inner().into_vec() } /// Returns the contents of this `CString` as a slice of bytes. @@ -573,7 +572,7 @@ impl CString { #[inline] #[must_use] #[stable(feature = "as_c_str", since = "1.20.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "cstring_as_c_str")] + #[rustc_diagnostic_item = "cstring_as_c_str"] pub fn as_c_str(&self) -> &CStr { &*self } @@ -755,7 +754,6 @@ impl<'a> From> for CString { } } -#[cfg(not(test))] #[stable(feature = "box_from_c_str", since = "1.17.0")] impl From<&CStr> for Box { /// Converts a `&CStr` into a `Box`, @@ -766,7 +764,6 @@ impl From<&CStr> for Box { } } -#[cfg(not(test))] #[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut CStr> for Box { /// Converts a `&mut CStr` into a `Box`, @@ -845,7 +842,6 @@ impl TryFrom for String { } } -#[cfg(not(test))] #[stable(feature = "more_box_slice_clone", since = "1.29.0")] impl Clone for Box { #[inline] @@ -971,7 +967,6 @@ impl Default for Rc { } } -#[cfg(not(test))] #[stable(feature = "default_box_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { @@ -1080,7 +1075,7 @@ impl ToOwned for CStr { } fn clone_into(&self, target: &mut CString) { - let mut b = into_vec(mem::take(&mut target.inner)); + let mut b = mem::take(&mut target.inner).into_vec(); self.to_bytes_with_nul().clone_into(&mut b); target.inner = b.into_boxed_slice(); } @@ -1113,7 +1108,6 @@ impl AsRef for CString { } } -#[cfg(not(test))] impl CStr { /// Converts a `CStr` into a [Cow]<[str]>. /// diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index cb93100f56cf..84bbc5a29739 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -92,7 +92,6 @@ // // Library features: // tidy-alphabetical-start -#![cfg_attr(test, feature(str_as_str))] #![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_chunks)] @@ -159,13 +158,11 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(not(test), feature(coroutine_trait))] -#![cfg_attr(test, feature(panic_update_hook))] -#![cfg_attr(test, feature(test))] #![feature(allocator_internals)] #![feature(allow_internal_unstable)] #![feature(cfg_sanitize)] #![feature(const_precise_live_drops)] +#![feature(coroutine_trait)] #![feature(decl_macro)] #![feature(dropck_eyepatch)] #![feature(fundamental)] @@ -198,15 +195,6 @@ // from other crates, but since this can only appear for lang items, it doesn't seem worth fixing. #![feature(intra_doc_pointers)] -// Allow testing this library -#[cfg(test)] -#[macro_use] -extern crate std; -#[cfg(test)] -extern crate test; -#[cfg(test)] -mod testing; - // Module with internal macros used by other modules (needs to be included before other modules). #[macro_use] mod macros; @@ -214,7 +202,6 @@ mod macros; mod raw_vec; // Heaps provided for low-level allocation strategies - pub mod alloc; // Primitive types using the heaps above @@ -222,13 +209,8 @@ pub mod alloc; // Need to conditionally define the mod from `boxed.rs` to avoid // duplicating the lang-items when building in test cfg; but also need // to allow code to have `use boxed::Box;` declarations. -#[cfg(not(test))] -pub mod boxed; -#[cfg(test)] -mod boxed { - pub(crate) use std::boxed::Box; -} pub mod borrow; +pub mod boxed; #[unstable(feature = "bstr", issue = "134915")] pub mod bstr; pub mod collections; @@ -252,20 +234,3 @@ pub mod __export { pub use core::format_args; pub use core::hint::must_use; } - -#[cfg(test)] -#[allow(dead_code)] // Not used in all configurations -pub(crate) mod test_helpers { - /// Copied from `std::test_helpers::test_rng`, since these tests rely on the - /// seed not being the same for every RNG invocation too. - pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { - use std::hash::{BuildHasher, Hash, Hasher}; - let mut hasher = std::hash::RandomState::new().build_hasher(); - std::panic::Location::caller().hash(&mut hasher); - let hc64 = hasher.finish(); - let seed_vec = - hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>(); - let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); - rand::SeedableRng::from_seed(seed) - } -} diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs index c000fd6f4efa..214192b8c9a9 100644 --- a/library/alloc/src/macros.rs +++ b/library/alloc/src/macros.rs @@ -34,7 +34,7 @@ /// be mindful of side effects. /// /// [`Vec`]: crate::vec::Vec -#[cfg(all(not(no_global_oom_handling), not(test)))] +#[cfg(not(no_global_oom_handling))] #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "vec_macro"] @@ -55,25 +55,6 @@ macro_rules! vec { ); } -// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is -// required for this macro definition, is not available. Instead use the -// `slice::into_vec` function which is only available with cfg(test) -// NB see the slice::hack module in slice.rs for more information -#[cfg(all(not(no_global_oom_handling), test))] -#[allow(unused_macro_rules)] -macro_rules! vec { - () => ( - $crate::vec::Vec::new() - ); - ($elem:expr; $n:expr) => ( - $crate::vec::from_elem($elem, $n) - ); - ($($x:expr),*) => ( - $crate::slice::into_vec($crate::boxed::Box::new([$($x),*])) - ); - ($($x:expr,)*) => (vec![$($x),*]) -} - /// Creates a `String` using interpolation of runtime expressions. /// /// The first argument `format!` receives is a format string. This must be a string @@ -120,7 +101,7 @@ macro_rules! vec { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(hint_must_use, liballoc_internals)] -#[cfg_attr(not(test), rustc_diagnostic_item = "format_macro")] +#[rustc_diagnostic_item = "format_macro"] macro_rules! format { ($($arg:tt)*) => { $crate::__export::must_use({ diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index 70f32fbaab42..f1f5ffefb9b7 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -1,4 +1,5 @@ #![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")] +#![cfg_attr(test, allow(dead_code))] use core::marker::PhantomData; use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties}; diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 2a4d4f264444..fe0b25f31b92 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -262,14 +262,11 @@ use core::ptr::{self, NonNull, drop_in_place}; #[cfg(not(no_global_oom_handling))] use core::slice::from_raw_parts_mut; use core::{borrow, fmt, hint}; -#[cfg(test)] -use std::boxed::Box; #[cfg(not(no_global_oom_handling))] use crate::alloc::handle_alloc_error; use crate::alloc::{AllocError, Allocator, Global, Layout}; use crate::borrow::{Cow, ToOwned}; -#[cfg(not(test))] use crate::boxed::Box; #[cfg(not(no_global_oom_handling))] use crate::string::String; @@ -306,7 +303,7 @@ fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout { /// /// [get_mut]: Rc::get_mut #[doc(search_unbox)] -#[cfg_attr(not(test), rustc_diagnostic_item = "Rc")] +#[rustc_diagnostic_item = "Rc"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] pub struct Rc< @@ -2981,7 +2978,7 @@ impl> ToRcSlice for I { /// /// [`upgrade`]: Weak::upgrade #[stable(feature = "rc_weak", since = "1.4.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "RcWeak")] +#[rustc_diagnostic_item = "RcWeak"] pub struct Weak< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 8baf96850626..7c5d22e1ee9b 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -8,9 +8,6 @@ //! A few functions are provided to create a slice from a value reference //! or from a raw pointer. #![stable(feature = "rust1", since = "1.0.0")] -// Many of the usings in this module are only used in the test configuration. -// It's cleaner to just turn off the unused_imports warning than to fix them. -#![cfg_attr(test, allow(unused_imports, dead_code))] use core::borrow::{Borrow, BorrowMut}; #[cfg(not(no_global_oom_handling))] @@ -63,16 +60,6 @@ pub use core::slice::{range, try_range}; //////////////////////////////////////////////////////////////////////////////// // Basic slice extension methods //////////////////////////////////////////////////////////////////////////////// - -// HACK(japaric) needed for the implementation of `vec!` macro during testing -// N.B., see the `hack` module in this file for more details. -#[cfg(test)] -pub use hack::into_vec; -// HACK(japaric) needed for the implementation of `Vec::clone` during testing -// N.B., see the `hack` module in this file for more details. -#[cfg(test)] -pub use hack::to_vec; - use crate::alloc::Allocator; #[cfg(not(no_global_oom_handling))] use crate::alloc::Global; @@ -81,98 +68,6 @@ use crate::borrow::ToOwned; use crate::boxed::Box; use crate::vec::Vec; -// HACK(japaric): With cfg(test) `impl [T]` is not available, these three -// functions are actually methods that are in `impl [T]` but not in -// `core::slice::SliceExt` - we need to supply these functions for the -// `test_permutations` test -#[allow(unreachable_pub)] // cfg(test) pub above -pub(crate) mod hack { - use core::alloc::Allocator; - - use crate::boxed::Box; - use crate::vec::Vec; - - // We shouldn't add inline attribute to this since this is used in - // `vec!` macro mostly and causes perf regression. See #71204 for - // discussion and perf results. - #[allow(missing_docs)] - pub fn into_vec(b: Box<[T], A>) -> Vec { - unsafe { - let len = b.len(); - let (b, alloc) = Box::into_raw_with_allocator(b); - Vec::from_raw_parts_in(b as *mut T, len, len, alloc) - } - } - - #[cfg(not(no_global_oom_handling))] - #[allow(missing_docs)] - #[inline] - pub fn to_vec(s: &[T], alloc: A) -> Vec { - T::to_vec(s, alloc) - } - - #[cfg(not(no_global_oom_handling))] - pub trait ConvertVec { - fn to_vec(s: &[Self], alloc: A) -> Vec - where - Self: Sized; - } - - #[cfg(not(no_global_oom_handling))] - impl ConvertVec for T { - #[inline] - default fn to_vec(s: &[Self], alloc: A) -> Vec { - struct DropGuard<'a, T, A: Allocator> { - vec: &'a mut Vec, - num_init: usize, - } - impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> { - #[inline] - fn drop(&mut self) { - // SAFETY: - // items were marked initialized in the loop below - unsafe { - self.vec.set_len(self.num_init); - } - } - } - let mut vec = Vec::with_capacity_in(s.len(), alloc); - let mut guard = DropGuard { vec: &mut vec, num_init: 0 }; - let slots = guard.vec.spare_capacity_mut(); - // .take(slots.len()) is necessary for LLVM to remove bounds checks - // and has better codegen than zip. - for (i, b) in s.iter().enumerate().take(slots.len()) { - guard.num_init = i; - slots[i].write(b.clone()); - } - core::mem::forget(guard); - // SAFETY: - // the vec was allocated and initialized above to at least this length. - unsafe { - vec.set_len(s.len()); - } - vec - } - } - - #[cfg(not(no_global_oom_handling))] - impl ConvertVec for T { - #[inline] - fn to_vec(s: &[Self], alloc: A) -> Vec { - let mut v = Vec::with_capacity_in(s.len(), alloc); - // SAFETY: - // allocated above with the capacity of `s`, and initialize to `s.len()` in - // ptr::copy_to_non_overlapping below. - unsafe { - s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len()); - v.set_len(s.len()); - } - v - } - } -} - -#[cfg(not(test))] impl [T] { /// Sorts the slice, preserving initial order of equal elements. /// @@ -501,8 +396,64 @@ impl [T] { where T: Clone, { - // N.B., see the `hack` module in this file for more details. - hack::to_vec(self, alloc) + return T::to_vec(self, alloc); + + trait ConvertVec { + fn to_vec(s: &[Self], alloc: A) -> Vec + where + Self: Sized; + } + + impl ConvertVec for T { + #[inline] + default fn to_vec(s: &[Self], alloc: A) -> Vec { + struct DropGuard<'a, T, A: Allocator> { + vec: &'a mut Vec, + num_init: usize, + } + impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> { + #[inline] + fn drop(&mut self) { + // SAFETY: + // items were marked initialized in the loop below + unsafe { + self.vec.set_len(self.num_init); + } + } + } + let mut vec = Vec::with_capacity_in(s.len(), alloc); + let mut guard = DropGuard { vec: &mut vec, num_init: 0 }; + let slots = guard.vec.spare_capacity_mut(); + // .take(slots.len()) is necessary for LLVM to remove bounds checks + // and has better codegen than zip. + for (i, b) in s.iter().enumerate().take(slots.len()) { + guard.num_init = i; + slots[i].write(b.clone()); + } + core::mem::forget(guard); + // SAFETY: + // the vec was allocated and initialized above to at least this length. + unsafe { + vec.set_len(s.len()); + } + vec + } + } + + impl ConvertVec for T { + #[inline] + fn to_vec(s: &[Self], alloc: A) -> Vec { + let mut v = Vec::with_capacity_in(s.len(), alloc); + // SAFETY: + // allocated above with the capacity of `s`, and initialize to `s.len()` in + // ptr::copy_to_non_overlapping below. + unsafe { + s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len()); + v.set_len(s.len()); + } + v + } + } } /// Converts `self` into a vector without clones or allocation. @@ -522,10 +473,13 @@ impl [T] { #[rustc_allow_incoherent_impl] #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[cfg_attr(not(test), rustc_diagnostic_item = "slice_into_vec")] + #[rustc_diagnostic_item = "slice_into_vec"] pub fn into_vec(self: Box) -> Vec { - // N.B., see the `hack` module in this file for more details. - hack::into_vec(self) + unsafe { + let len = self.len(); + let (b, alloc) = Box::into_raw_with_allocator(self); + Vec::from_raw_parts_in(b as *mut T, len, len, alloc) + } } /// Creates a vector by copying a slice `n` times. @@ -666,7 +620,6 @@ impl [T] { } } -#[cfg(not(test))] impl [u8] { /// Returns a vector containing a copy of this slice where each byte /// is mapped to its ASCII upper case equivalent. @@ -883,16 +836,11 @@ impl SpecCloneIntoVec for [T] { #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for [T] { type Owned = Vec; - #[cfg(not(test))] + fn to_owned(&self) -> Vec { self.to_vec() } - #[cfg(test)] - fn to_owned(&self) -> Vec { - hack::to_vec(self, Global) - } - fn clone_into(&self, target: &mut Vec) { SpecCloneIntoVec::clone_into(self, target); } diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 6fee8d3fe334..0664f2c3cf2c 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -219,7 +219,6 @@ impl ToOwned for str { } /// Methods for string slices. -#[cfg(not(test))] impl str { /// Converts a `Box` into a `Box<[u8]>` without copying or allocating. /// @@ -631,7 +630,6 @@ pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box { #[unstable(feature = "str_internals", issue = "none")] #[doc(hidden)] #[inline] -#[cfg(not(test))] #[cfg(not(no_global_oom_handling))] pub fn convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> (String, &str) { // Process the input in chunks of 16 bytes to enable auto-vectorization. @@ -704,7 +702,6 @@ pub fn convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> (String, &str) { } } #[inline] -#[cfg(not(test))] #[cfg(not(no_global_oom_handling))] #[allow(dead_code)] /// Faster implementation of string replacement for ASCII to ASCII cases. diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 2c0347865498..2ba797ab2add 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -356,7 +356,7 @@ use crate::vec::{self, Vec}; /// [`as_str()`]: String::as_str #[derive(PartialEq, PartialOrd, Eq, Ord)] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), lang = "String")] +#[lang = "String"] pub struct String { vec: Vec, } @@ -438,7 +438,7 @@ impl String { /// ``` #[inline] #[rustc_const_stable(feature = "const_string_new", since = "1.39.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "string_new")] + #[rustc_diagnostic_item = "string_new"] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] pub const fn new() -> String { @@ -501,17 +501,6 @@ impl String { Ok(String { vec: Vec::try_with_capacity(capacity)? }) } - // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is - // required for this method definition, is not available. Since we don't - // require this method for testing purposes, I'll just stub it - // NB see the slice::hack module in slice.rs for more information - #[inline] - #[cfg(test)] - #[allow(missing_docs)] - pub fn from_str(_: &str) -> String { - panic!("not available with cfg(test)"); - } - /// Converts a vector of bytes to a `String`. /// /// A string ([`String`]) is made of bytes ([`u8`]), and a vector of bytes @@ -570,7 +559,7 @@ impl String { /// [`into_bytes`]: String::into_bytes #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "string_from_utf8")] + #[rustc_diagnostic_item = "string_from_utf8"] pub fn from_utf8(vec: Vec) -> Result { match str::from_utf8(&vec) { Ok(..) => Ok(String { vec }), @@ -1071,7 +1060,7 @@ impl String { #[inline] #[must_use] #[stable(feature = "string_as_str", since = "1.7.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "string_as_str")] + #[rustc_diagnostic_item = "string_as_str"] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] pub const fn as_str(&self) -> &str { // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error @@ -1094,7 +1083,7 @@ impl String { #[inline] #[must_use] #[stable(feature = "string_as_str", since = "1.7.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "string_as_mut_str")] + #[rustc_diagnostic_item = "string_as_mut_str"] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] pub const fn as_mut_str(&mut self) -> &mut str { // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error @@ -1117,7 +1106,7 @@ impl String { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_confusables("append", "push")] - #[cfg_attr(not(test), rustc_diagnostic_item = "string_push_str")] + #[rustc_diagnostic_item = "string_push_str"] pub fn push_str(&mut self, string: &str) { self.vec.extend_from_slice(string.as_bytes()) } @@ -1755,7 +1744,7 @@ impl String { #[cfg(not(no_global_oom_handling))] #[inline] #[stable(feature = "insert_str", since = "1.16.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "string_insert_str")] + #[rustc_diagnostic_item = "string_insert_str"] pub fn insert_str(&mut self, idx: usize, string: &str) { assert!(self.is_char_boundary(idx)); @@ -2724,7 +2713,7 @@ impl FromStr for String { /// implementation for free. /// /// [`Display`]: fmt::Display -#[cfg_attr(not(test), rustc_diagnostic_item = "ToString")] +#[rustc_diagnostic_item = "ToString"] #[stable(feature = "rust1", since = "1.0.0")] pub trait ToString { /// Converts the given value to a `String`. @@ -2739,7 +2728,7 @@ pub trait ToString { /// ``` #[rustc_conversion_suggestion] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "to_string_method")] + #[rustc_diagnostic_item = "to_string_method"] fn to_string(&self) -> String; } @@ -2979,7 +2968,6 @@ impl From<&String> for String { } // note: test pulls in std, which causes errors here -#[cfg(not(test))] #[stable(feature = "string_from_box", since = "1.18.0")] impl From> for String { /// Converts the given boxed `str` slice to a [`String`]. diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 1956dda53881..faee15ab0c66 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -234,7 +234,7 @@ macro_rules! acquire { /// /// [rc_examples]: crate::rc#examples #[doc(search_unbox)] -#[cfg_attr(not(test), rustc_diagnostic_item = "Arc")] +#[rustc_diagnostic_item = "Arc"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] pub struct Arc< @@ -311,7 +311,7 @@ impl Arc { /// /// [`upgrade`]: Weak::upgrade #[stable(feature = "arc_weak", since = "1.4.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "ArcWeak")] +#[rustc_diagnostic_item = "ArcWeak"] pub struct Weak< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 52597e41c1cf..3eee988b6c9d 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -472,14 +472,9 @@ where #[cfg(not(no_global_oom_handling))] #[stable(feature = "vec_into_iter_clone", since = "1.8.0")] impl Clone for IntoIter { - #[cfg(not(test))] fn clone(&self) -> Self { self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter() } - #[cfg(test)] - fn clone(&self) -> Self { - crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter() - } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 49878f2b6fa5..ce6685405981 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -404,7 +404,7 @@ mod spec_extend; /// [owned slice]: Box /// [`into_boxed_slice`]: Vec::into_boxed_slice #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Vec")] +#[rustc_diagnostic_item = "Vec"] #[rustc_insignificant_dtor] pub struct Vec { buf: RawVec, @@ -428,7 +428,7 @@ impl Vec { /// ``` #[inline] #[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "vec_new")] + #[rustc_diagnostic_item = "vec_new"] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] pub const fn new() -> Self { @@ -489,7 +489,7 @@ impl Vec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] - #[cfg_attr(not(test), rustc_diagnostic_item = "vec_with_capacity")] + #[rustc_diagnostic_item = "vec_with_capacity"] #[track_caller] pub fn with_capacity(capacity: usize) -> Self { Self::with_capacity_in(capacity, Global) @@ -1279,7 +1279,7 @@ impl Vec { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] #[track_caller] - #[cfg_attr(not(test), rustc_diagnostic_item = "vec_reserve")] + #[rustc_diagnostic_item = "vec_reserve"] pub fn reserve(&mut self, additional: usize) { self.buf.reserve(self.len, additional); } @@ -1568,7 +1568,7 @@ impl Vec { /// ``` #[inline] #[stable(feature = "vec_as_slice", since = "1.7.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_slice")] + #[rustc_diagnostic_item = "vec_as_slice"] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] pub const fn as_slice(&self) -> &[T] { // SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size @@ -1600,7 +1600,7 @@ impl Vec { /// ``` #[inline] #[stable(feature = "vec_as_slice", since = "1.7.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_mut_slice")] + #[rustc_diagnostic_item = "vec_as_mut_slice"] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] pub const fn as_mut_slice(&mut self) -> &mut [T] { // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of @@ -2511,7 +2511,7 @@ impl Vec { /// Takes *O*(1) time. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "vec_pop")] + #[rustc_diagnostic_item = "vec_pop"] pub fn pop(&mut self) -> Option { if self.len == 0 { None @@ -2712,7 +2712,7 @@ impl Vec { /// assert!(!v.is_empty()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "vec_is_empty")] + #[rustc_diagnostic_item = "vec_is_empty"] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] pub const fn is_empty(&self) -> bool { self.len() == 0 @@ -3193,7 +3193,7 @@ impl Vec { #[doc(hidden)] #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "vec_from_elem")] +#[rustc_diagnostic_item = "vec_from_elem"] #[track_caller] pub fn from_elem(elem: T, n: usize) -> Vec { ::from_elem(elem, n, Global) @@ -3293,23 +3293,12 @@ unsafe impl ops::DerefPure for Vec {} #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Vec { - #[cfg(not(test))] #[track_caller] fn clone(&self) -> Self { let alloc = self.allocator().clone(); <[T]>::to_vec_in(&**self, alloc) } - // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is - // required for this method definition, is not available. Instead use the - // `slice::to_vec` function which is only available with cfg(test) - // NB see the slice::hack module in slice.rs for more information - #[cfg(test)] - fn clone(&self) -> Self { - let alloc = self.allocator().clone(); - crate::slice::to_vec(&**self, alloc) - } - /// Overwrites the contents of `self` with a clone of the contents of `source`. /// /// This method is preferred over simply assigning `source.clone()` to `self`, @@ -3854,15 +3843,10 @@ impl From<&[T]> for Vec { /// ``` /// assert_eq!(Vec::from(&[1, 2, 3][..]), vec![1, 2, 3]); /// ``` - #[cfg(not(test))] #[track_caller] fn from(s: &[T]) -> Vec { s.to_vec() } - #[cfg(test)] - fn from(s: &[T]) -> Vec { - crate::slice::to_vec(s, Global) - } } #[cfg(not(no_global_oom_handling))] @@ -3875,15 +3859,10 @@ impl From<&mut [T]> for Vec { /// ``` /// assert_eq!(Vec::from(&mut [1, 2, 3][..]), vec![1, 2, 3]); /// ``` - #[cfg(not(test))] #[track_caller] fn from(s: &mut [T]) -> Vec { s.to_vec() } - #[cfg(test)] - fn from(s: &mut [T]) -> Vec { - crate::slice::to_vec(s, Global) - } } #[cfg(not(no_global_oom_handling))] @@ -3928,16 +3907,10 @@ impl From<[T; N]> for Vec { /// ``` /// assert_eq!(Vec::from([1, 2, 3]), vec![1, 2, 3]); /// ``` - #[cfg(not(test))] #[track_caller] fn from(s: [T; N]) -> Vec { <[T]>::into_vec(Box::new(s)) } - - #[cfg(test)] - fn from(s: [T; N]) -> Vec { - crate::slice::into_vec(Box::new(s)) - } } #[stable(feature = "vec_from_cow_slice", since = "1.14.0")] @@ -3966,7 +3939,6 @@ where } // note: test pulls in std, which causes errors here -#[cfg(not(test))] #[stable(feature = "vec_from_box", since = "1.18.0")] impl From> for Vec { /// Converts a boxed slice into a vector by transferring ownership of @@ -3985,7 +3957,6 @@ impl From> for Vec { // note: test pulls in std, which causes errors here #[cfg(not(no_global_oom_handling))] -#[cfg(not(test))] #[stable(feature = "box_from_vec", since = "1.20.0")] impl From> for Box<[T], A> { /// Converts a vector into a boxed slice. diff --git a/library/alloctests/Cargo.toml b/library/alloctests/Cargo.toml index f1a783b1e224..306375f5f01c 100644 --- a/library/alloctests/Cargo.toml +++ b/library/alloctests/Cargo.toml @@ -10,8 +10,9 @@ edition = "2021" [lib] path = "lib.rs" -test = false -bench = false +test = true +bench = true +doc = false [dev-dependencies] rand = { version = "0.9.0", default-features = false, features = ["alloc"] } diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index b49208cd4eb3..0b5aa2c575d9 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -1 +1,90 @@ -// Intentionally left empty. +#![cfg(test)] +#![allow(unused_attributes)] +#![unstable(feature = "alloctests", issue = "none")] +#![no_std] +// Lints: +#![deny(unsafe_op_in_unsafe_fn)] +#![warn(deprecated_in_future)] +#![warn(missing_debug_implementations)] +#![allow(explicit_outlives_requirements)] +#![allow(internal_features)] +#![allow(rustdoc::redundant_explicit_links)] +#![warn(rustdoc::unescaped_backticks)] +#![deny(ffi_unwind_calls)] +// +// Library features: +// tidy-alphabetical-start +#![feature(alloc_layout_extra)] +#![feature(allocator_api)] +#![feature(array_into_iter_constructors)] +#![feature(assert_matches)] +#![feature(core_intrinsics)] +#![feature(exact_size_is_empty)] +#![feature(extend_one)] +#![feature(extend_one_unchecked)] +#![feature(hasher_prefixfree_extras)] +#![feature(inplace_iteration)] +#![feature(iter_advance_by)] +#![feature(iter_next_chunk)] +#![feature(maybe_uninit_slice)] +#![feature(maybe_uninit_uninit_array_transpose)] +#![feature(ptr_internals)] +#![feature(sized_type_properties)] +#![feature(slice_iter_mut_as_mut_slice)] +#![feature(slice_ptr_get)] +#![feature(slice_range)] +#![feature(std_internals)] +#![feature(temporary_niche_types)] +#![feature(trusted_fused)] +#![feature(trusted_len)] +#![feature(trusted_random_access)] +#![feature(try_reserve_kind)] +#![feature(try_trait_v2)] +// tidy-alphabetical-end +// +// Language features: +// tidy-alphabetical-start +#![feature(cfg_sanitize)] +#![feature(dropck_eyepatch)] +#![feature(lang_items)] +#![feature(min_specialization)] +#![feature(negative_impls)] +#![feature(never_type)] +#![feature(optimize_attribute)] +#![feature(rustc_allow_const_fn_unstable)] +#![feature(rustc_attrs)] +#![feature(staged_api)] +#![feature(test)] +#![rustc_preserve_ub_checks] +// tidy-alphabetical-end + +// Allow testing this library +extern crate alloc as realalloc; +#[macro_use] +extern crate std; +#[cfg(test)] +extern crate test; +mod testing; +use realalloc::*; + +#[path = "../alloc/src/collections/mod.rs"] +mod collections; + +#[path = "../alloc/src/raw_vec/mod.rs"] +mod raw_vec; + +#[allow(dead_code)] // Not used in all configurations +pub(crate) mod test_helpers { + /// Copied from `std::test_helpers::test_rng`, since these tests rely on the + /// seed not being the same for every RNG invocation too. + pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { + use std::hash::{BuildHasher, Hash, Hasher}; + let mut hasher = std::hash::RandomState::new().build_hasher(); + std::panic::Location::caller().hash(&mut hasher); + let hc64 = hasher.finish(); + let seed_vec = + hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>(); + let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); + rand::SeedableRng::from_seed(seed) + } +} diff --git a/library/alloc/src/testing/crash_test.rs b/library/alloctests/testing/crash_test.rs similarity index 100% rename from library/alloc/src/testing/crash_test.rs rename to library/alloctests/testing/crash_test.rs diff --git a/library/alloc/src/testing/mod.rs b/library/alloctests/testing/mod.rs similarity index 100% rename from library/alloc/src/testing/mod.rs rename to library/alloctests/testing/mod.rs diff --git a/library/alloc/src/testing/ord_chaos.rs b/library/alloctests/testing/ord_chaos.rs similarity index 100% rename from library/alloc/src/testing/ord_chaos.rs rename to library/alloctests/testing/ord_chaos.rs diff --git a/library/alloc/src/testing/rng.rs b/library/alloctests/testing/rng.rs similarity index 100% rename from library/alloc/src/testing/rng.rs rename to library/alloctests/testing/rng.rs From 22d0440993d6eab6e9faf35f729e2d52ba6d72a6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 13 Feb 2025 15:38:07 +0000 Subject: [PATCH 818/991] Add comments --- library/alloc/src/collections/mod.rs | 3 +++ library/alloc/src/raw_vec/mod.rs | 3 +++ library/alloctests/lib.rs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs index 1414f797e8a4..fac4d1a65abc 100644 --- a/library/alloc/src/collections/mod.rs +++ b/library/alloc/src/collections/mod.rs @@ -1,5 +1,8 @@ //! Collection types. +// Note: This module is also included in the alloctests crate using #[path] to +// run the tests. See the comment there for an explanation why this is the case. + #![stable(feature = "rust1", since = "1.0.0")] #[cfg(not(no_global_oom_handling))] diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index f1f5ffefb9b7..99ebc5c4bfca 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -1,6 +1,9 @@ #![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")] #![cfg_attr(test, allow(dead_code))] +// Note: This module is also included in the alloctests crate using #[path] to +// run the tests. See the comment there for an explanation why this is the case. + use core::marker::PhantomData; use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties}; use core::ptr::{self, NonNull, Unique}; diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index 0b5aa2c575d9..6ce8a6d9ca17 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -67,6 +67,9 @@ extern crate test; mod testing; use realalloc::*; +// We are directly including collections and raw_vec here as both use non-public +// methods and fields in tests and as such need to have the types to test in the +// same crate as the tests themself. #[path = "../alloc/src/collections/mod.rs"] mod collections; From e98837f558db4d92429ef10576afcd5198cbb3fb Mon Sep 17 00:00:00 2001 From: Prajwal S N Date: Sat, 8 Mar 2025 01:25:27 +0530 Subject: [PATCH 819/991] fix(hir): `VariantDef` is `impl HasSource` A new syntax node `ast::VariantDef` has been introduced to map between the HIR node and the AST. The files have been updated with `cargo test -p xtask`. Signed-off-by: Prajwal S N --- .../crates/hir/src/has_source.rs | 12 ++++- .../parser/src/syntax_kind/generated.rs | 2 + .../rust-analyzer/crates/syntax/rust.ungram | 5 ++ .../crates/syntax/src/ast/generated/nodes.rs | 50 +++++++++++++++++++ .../docs/book/src/assists_generated.md | 4 +- 5 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/has_source.rs b/src/tools/rust-analyzer/crates/hir/src/has_source.rs index a34b4980832c..372c72529344 100644 --- a/src/tools/rust-analyzer/crates/hir/src/has_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/has_source.rs @@ -15,7 +15,7 @@ use tt::TextRange; use crate::{ db::HirDatabase, Adt, Callee, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl, InlineAsmOperand, Label, LifetimeParam, LocalSource, Macro, Module, Param, SelfParam, Static, - Struct, Trait, TraitAlias, TypeAlias, TypeOrConstParam, Union, Variant, + Struct, Trait, TraitAlias, TypeAlias, TypeOrConstParam, Union, Variant, VariantDef, }; pub trait HasSource { @@ -110,6 +110,16 @@ impl HasSource for Adt { } } } +impl HasSource for VariantDef { + type Ast = ast::VariantDef; + fn source(self, db: &dyn HirDatabase) -> Option> { + match self { + VariantDef::Struct(s) => Some(s.source(db)?.map(ast::VariantDef::Struct)), + VariantDef::Union(u) => Some(u.source(db)?.map(ast::VariantDef::Union)), + VariantDef::Variant(v) => Some(v.source(db)?.map(ast::VariantDef::Variant)), + } + } +} impl HasSource for Struct { type Ast = ast::Struct; fn source(self, db: &dyn HirDatabase) -> Option> { diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index e56e09eeb66b..1ff0bbea8b1d 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -315,6 +315,7 @@ pub enum SyntaxKind { USE_TREE, USE_TREE_LIST, VARIANT, + VARIANT_DEF, VARIANT_LIST, VISIBILITY, WHERE_CLAUSE, @@ -501,6 +502,7 @@ impl SyntaxKind { | USE_TREE | USE_TREE_LIST | VARIANT + | VARIANT_DEF | VARIANT_LIST | VISIBILITY | WHERE_CLAUSE diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 88d7beb897e0..70a91af6c479 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -279,6 +279,11 @@ Adt = | Struct | Union +VariantDef = + Struct +| Union +| Variant + Const = Attr* Visibility? 'default'? diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index 58c76a456ab1..ebee5e9af2c4 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -2446,6 +2446,17 @@ pub enum UseBoundGenericArg { NameRef(NameRef), } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum VariantDef { + Struct(Struct), + Union(Union), + Variant(Variant), +} +impl ast::HasAttrs for VariantDef {} +impl ast::HasDocComments for VariantDef {} +impl ast::HasName for VariantDef {} +impl ast::HasVisibility for VariantDef {} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct AnyHasArgList { pub(crate) syntax: SyntaxNode, @@ -6738,6 +6749,40 @@ impl AstNode for UseBoundGenericArg { } } } +impl From for VariantDef { + #[inline] + fn from(node: Struct) -> VariantDef { VariantDef::Struct(node) } +} +impl From for VariantDef { + #[inline] + fn from(node: Union) -> VariantDef { VariantDef::Union(node) } +} +impl From for VariantDef { + #[inline] + fn from(node: Variant) -> VariantDef { VariantDef::Variant(node) } +} +impl AstNode for VariantDef { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, STRUCT | UNION | VARIANT) } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + STRUCT => VariantDef::Struct(Struct { syntax }), + UNION => VariantDef::Union(Union { syntax }), + VARIANT => VariantDef::Variant(Variant { syntax }), + _ => return None, + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + VariantDef::Struct(it) => &it.syntax, + VariantDef::Union(it) => &it.syntax, + VariantDef::Variant(it) => &it.syntax, + } + } +} impl AnyHasArgList { #[inline] pub fn new(node: T) -> AnyHasArgList { @@ -7753,6 +7798,11 @@ impl std::fmt::Display for UseBoundGenericArg { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for VariantDef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for Abi { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 918ae4a57944..a1433952e0ba 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -1070,7 +1070,7 @@ pub use foo::{Bar, Baz}; ### `expand_record_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L24) +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L26) Fills fields by replacing rest pattern in record patterns. @@ -1094,7 +1094,7 @@ fn foo(bar: Bar) { ### `expand_tuple_struct_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L80) +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L82) Fills fields by replacing rest pattern in tuple struct patterns. From b6f1ce8071c70e0afd3bad39ee10404bfbf32f5c Mon Sep 17 00:00:00 2001 From: Prajwal S N Date: Sat, 8 Mar 2025 01:44:27 +0530 Subject: [PATCH 820/991] fix: do not apply editorconfig to git commit msg The `max_line_length` property was set to 100 for all filetypes, which led to git commit messages being wrapped at 100 characters instead of the usual 75. This introduces an exception for the special file used by git to write commit messages. Signed-off-by: Prajwal S N --- src/tools/rust-analyzer/.editorconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/rust-analyzer/.editorconfig b/src/tools/rust-analyzer/.editorconfig index 6bb743a6736e..2d28ebd4766a 100644 --- a/src/tools/rust-analyzer/.editorconfig +++ b/src/tools/rust-analyzer/.editorconfig @@ -15,3 +15,6 @@ indent_size = 2 [*.{yml,yaml}] indent_size = 2 + +[COMMIT_EDITMSG] +max_line_length = unset From 06eecca264f4f793b5ad94af318f5688b739a168 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Fri, 7 Mar 2025 12:36:33 -0800 Subject: [PATCH 821/991] Allow anyone to relabel CI-spurious-* --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 7114c7ab27bc..305b99ad5ecd 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -18,6 +18,7 @@ allow-unauthenticated = [ "WG-*", "-Z*", "beta-nominated", + "CI-spurious-*", "const-hack", "llvm-*", "needs-fcp", From e0c2636df57e65fc7aa0ff940210e0af03b9bba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 7 Mar 2025 21:48:54 +0100 Subject: [PATCH 822/991] remove clones --- compiler/rustc_builtin_macros/src/autodiff.rs | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 6d9c35756574..7b5c4a159b0c 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -286,7 +286,7 @@ mod llvm_enzyme { let orig_annotatable: Annotatable = match item { Annotatable::Item(ref mut iitem) => { if !iitem.attrs.iter().any(|a| a.id == attr.id) { - iitem.attrs.push(attr.clone()); + iitem.attrs.push(attr); } if !iitem.attrs.iter().any(|a| a.id == inline_never.id) { iitem.attrs.push(inline_never.clone()); @@ -295,7 +295,7 @@ mod llvm_enzyme { } Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => { if !assoc_item.attrs.iter().any(|a| a.id == attr.id) { - assoc_item.attrs.push(attr.clone()); + assoc_item.attrs.push(attr); } if !assoc_item.attrs.iter().any(|a| a.id == inline_never.id) { assoc_item.attrs.push(inline_never.clone()); @@ -322,7 +322,7 @@ mod llvm_enzyme { let d_annotatable = if is_impl { let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(asdf); let d_fn = P(ast::AssocItem { - attrs: thin_vec![d_attr.clone(), inline_never], + attrs: thin_vec![d_attr, inline_never], id: ast::DUMMY_NODE_ID, span, vis, @@ -332,12 +332,8 @@ mod llvm_enzyme { }); Annotatable::AssocItem(d_fn, Impl) } else { - let mut d_fn = ecx.item( - span, - d_ident, - thin_vec![d_attr.clone(), inline_never], - ItemKind::Fn(asdf), - ); + let mut d_fn = + ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf)); d_fn.vis = vis; Annotatable::Item(d_fn) }; @@ -446,7 +442,7 @@ mod llvm_enzyme { if primal_ret && n_active == 0 && x.mode.is_rev() { // We only have the primal ret. - body.stmts.push(ecx.stmt_expr(black_box_primal_call.clone())); + body.stmts.push(ecx.stmt_expr(black_box_primal_call)); return body; } @@ -471,7 +467,7 @@ mod llvm_enzyme { if primal_ret { // We have both primal ret and active floats. // primal ret is first, by construction. - exprs.push(primal_call.clone()); + exprs.push(primal_call); } // Now construct default placeholder for each active float. @@ -538,16 +534,11 @@ mod llvm_enzyme { return body; } [arg] => { - ret = ecx.expr_call( - new_decl_span, - blackbox_call_expr.clone(), - thin_vec![arg.clone()], - ); + ret = ecx.expr_call(new_decl_span, blackbox_call_expr, thin_vec![arg.clone()]); } args => { let ret_tuple: P = ecx.expr_tuple(span, args.into()); - ret = - ecx.expr_call(new_decl_span, blackbox_call_expr.clone(), thin_vec![ret_tuple]); + ret = ecx.expr_call(new_decl_span, blackbox_call_expr, thin_vec![ret_tuple]); } } assert!(has_ret(&d_sig.decl.output)); @@ -567,7 +558,7 @@ mod llvm_enzyme { let args: ThinVec<_> = idents[1..].iter().map(|arg| ecx.expr_path(ecx.path_ident(span, *arg))).collect(); let self_expr = ecx.expr_self(span); - ecx.expr_method_call(span, self_expr, primal, args.clone()) + ecx.expr_method_call(span, self_expr, primal, args) } else { let args: ThinVec<_> = idents.iter().map(|arg| ecx.expr_path(ecx.path_ident(span, *arg))).collect(); From 17dd2b179c4fab87975bb1c23ea2b869ca516ea5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Mar 2025 22:00:36 +0100 Subject: [PATCH 823/991] Mention `env` and `option_env` macros in `std::env::var` docs --- library/std/src/env.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/env.rs b/library/std/src/env.rs index e62aeb2ede0a..6961fa8ea947 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -202,6 +202,9 @@ impl fmt::Debug for VarsOs { /// Returns [`VarError::NotUnicode`] if the variable's value is not valid /// Unicode. If this is not desired, consider using [`var_os`]. /// +/// Use [`env!`] or [`option_env!`] instead if you want to check environment +/// variables at compile time. +/// /// # Examples /// /// ``` From 38fad984c616cf4d10f653fa50c85cdc01083373 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Tue, 4 Mar 2025 20:28:38 -0800 Subject: [PATCH 824/991] compiler: Use size_of from the prelude instead of imported Use `std::mem::{size_of, size_of_val, align_of, align_of_val}` from the prelude instead of importing or qualifying them. These functions were added to all preludes in Rust 1.80. --- compiler/rustc_arena/src/lib.rs | 26 +++++++++---------- compiler/rustc_codegen_gcc/src/builder.rs | 6 +---- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- compiler/rustc_data_structures/src/aligned.rs | 8 +++--- .../rustc_data_structures/src/profiling.rs | 6 ++--- compiler/rustc_data_structures/src/sharded.rs | 4 +-- compiler/rustc_errors/src/diagnostic.rs | 2 +- compiler/rustc_hir/src/def.rs | 4 +-- .../src/persist/file_format.rs | 2 +- compiler/rustc_index/src/bit_set.rs | 6 +++-- compiler/rustc_index/src/vec/tests.rs | 2 -- compiler/rustc_lint_defs/src/builtin.rs | 2 +- .../src/mir/interpret/allocation/init_mask.rs | 4 +-- .../rustc_middle/src/mir/interpret/mod.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 4 +-- compiler/rustc_middle/src/query/erase.rs | 2 +- compiler/rustc_middle/src/query/plumbing.rs | 4 +-- compiler/rustc_middle/src/ty/consts/int.rs | 4 +-- compiler/rustc_middle/src/ty/generic_args.rs | 7 +++-- compiler/rustc_middle/src/ty/list.rs | 4 +-- compiler/rustc_middle/src/ty/mod.rs | 6 ++--- compiler/rustc_parse/src/parser/token_type.rs | 2 +- compiler/rustc_passes/src/input_stats.rs | 4 +-- .../rustc_passes/src/liveness/rwu_table.rs | 2 +- .../src/dep_graph/serialized.rs | 11 ++++---- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_serialize/src/leb128.rs | 2 +- compiler/rustc_session/src/filesearch.rs | 2 +- .../src/traits/const_evaluatable.rs | 2 +- compiler/stable_mir/src/mir/alloc.rs | 4 +-- 30 files changed, 64 insertions(+), 74 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index b21ccba93bb4..3b44e9963581 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -93,7 +93,7 @@ impl ArenaChunk { #[inline] fn end(&mut self) -> *mut T { unsafe { - if mem::size_of::() == 0 { + if size_of::() == 0 { // A pointer as large as possible for zero-sized elements. ptr::without_provenance_mut(!0) } else { @@ -151,7 +151,7 @@ impl TypedArena { } unsafe { - if mem::size_of::() == 0 { + if size_of::() == 0 { self.ptr.set(self.ptr.get().wrapping_byte_add(1)); let ptr = ptr::NonNull::::dangling().as_ptr(); // Don't drop the object. This `write` is equivalent to `forget`. @@ -173,13 +173,13 @@ impl TypedArena { // FIXME: this should *likely* use `offset_from`, but more // investigation is needed (including running tests in miri). let available_bytes = self.end.get().addr() - self.ptr.get().addr(); - let additional_bytes = additional.checked_mul(mem::size_of::()).unwrap(); + let additional_bytes = additional.checked_mul(size_of::()).unwrap(); available_bytes >= additional_bytes } #[inline] fn alloc_raw_slice(&self, len: usize) -> *mut T { - assert!(mem::size_of::() != 0); + assert!(size_of::() != 0); assert!(len != 0); // Ensure the current chunk can fit `len` objects. @@ -213,7 +213,7 @@ impl TypedArena { // So we collect all the elements beforehand, which takes care of reentrancy and panic // safety. This function is much less hot than `DroplessArena::alloc_from_iter`, so it // doesn't need to be hyper-optimized. - assert!(mem::size_of::() != 0); + assert!(size_of::() != 0); let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect(); if vec.is_empty() { @@ -236,7 +236,7 @@ impl TypedArena { unsafe { // We need the element size to convert chunk sizes (ranging from // PAGE to HUGE_PAGE bytes) to element counts. - let elem_size = cmp::max(1, mem::size_of::()); + let elem_size = cmp::max(1, size_of::()); let mut chunks = self.chunks.borrow_mut(); let mut new_cap; if let Some(last_chunk) = chunks.last_mut() { @@ -246,7 +246,7 @@ impl TypedArena { // FIXME: this should *likely* use `offset_from`, but more // investigation is needed (including running tests in miri). let used_bytes = self.ptr.get().addr() - last_chunk.start().addr(); - last_chunk.entries = used_bytes / mem::size_of::(); + last_chunk.entries = used_bytes / size_of::(); } // If the previous chunk's len is less than HUGE_PAGE @@ -276,7 +276,7 @@ impl TypedArena { let end = self.ptr.get().addr(); // We then calculate the number of elements to be dropped in the last chunk, // which is the filled area's length. - let diff = if mem::size_of::() == 0 { + let diff = if size_of::() == 0 { // `T` is ZST. It can't have a drop flag, so the value here doesn't matter. We get // the number of zero-sized values in the last and only chunk, just out of caution. // Recall that `end` was incremented for each allocated value. @@ -284,7 +284,7 @@ impl TypedArena { } else { // FIXME: this should *likely* use `offset_from`, but more // investigation is needed (including running tests in miri). - (end - start) / mem::size_of::() + (end - start) / size_of::() }; // Pass that to the `destroy` method. unsafe { @@ -329,7 +329,7 @@ fn align_up(val: usize, align: usize) -> usize { // Pointer alignment is common in compiler types, so keep `DroplessArena` aligned to them // to optimize away alignment code. -const DROPLESS_ALIGNMENT: usize = mem::align_of::(); +const DROPLESS_ALIGNMENT: usize = align_of::(); /// An arena that can hold objects of multiple different types that impl `Copy` /// and/or satisfy `!mem::needs_drop`. @@ -447,7 +447,7 @@ impl DroplessArena { #[inline] pub fn alloc(&self, object: T) -> &mut T { assert!(!mem::needs_drop::()); - assert!(mem::size_of::() != 0); + assert!(size_of::() != 0); let mem = self.alloc_raw(Layout::new::()) as *mut T; @@ -471,7 +471,7 @@ impl DroplessArena { T: Copy, { assert!(!mem::needs_drop::()); - assert!(mem::size_of::() != 0); + assert!(size_of::() != 0); assert!(!slice.is_empty()); let mem = self.alloc_raw(Layout::for_value::<[T]>(slice)) as *mut T; @@ -546,7 +546,7 @@ impl DroplessArena { // Warning: this function is reentrant: `iter` could hold a reference to `&self` and // allocate additional elements while we're iterating. let iter = iter.into_iter(); - assert!(mem::size_of::() != 0); + assert!(size_of::() != 0); assert!(!mem::needs_drop::()); let size_hint = iter.size_hint(); diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index c8b7616e6450..6573b5b165e6 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -2439,9 +2439,5 @@ fn get_maybe_pointer_size(value: RValue<'_>) -> u32 { #[cfg(not(feature = "master"))] fn get_maybe_pointer_size(value: RValue<'_>) -> u32 { let type_ = value.get_type(); - if type_.get_pointee().is_some() { - std::mem::size_of::<*const ()>() as _ - } else { - type_.get_size() - } + if type_.get_pointee().is_some() { size_of::<*const ()>() as _ } else { type_.get_size() } } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index a170b2e3b6a5..d2d29ef2ee5a 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1177,7 +1177,7 @@ mod win { let mut cp: u32 = 0; // We're using the `LOCALE_RETURN_NUMBER` flag to return a u32. // But the API requires us to pass the data as though it's a [u16] string. - let len = std::mem::size_of::() / std::mem::size_of::(); + let len = size_of::() / size_of::(); let data = std::slice::from_raw_parts_mut(&mut cp as *mut u32 as *mut u16, len); let len_written = GetLocaleInfoEx( LOCALE_NAME_SYSTEM_DEFAULT, diff --git a/compiler/rustc_data_structures/src/aligned.rs b/compiler/rustc_data_structures/src/aligned.rs index 0e5ecfd9bff6..a636d09fcae2 100644 --- a/compiler/rustc_data_structures/src/aligned.rs +++ b/compiler/rustc_data_structures/src/aligned.rs @@ -2,10 +2,8 @@ use std::ptr::Alignment; /// Returns the ABI-required minimum alignment of a type in bytes. /// -/// This is equivalent to [`mem::align_of`], but also works for some unsized +/// This is equivalent to [`align_of`], but also works for some unsized /// types (e.g. slices or rustc's `List`s). -/// -/// [`mem::align_of`]: std::mem::align_of pub const fn align_of() -> Alignment { T::ALIGN } @@ -15,10 +13,10 @@ pub const fn align_of() -> Alignment { /// # Safety /// /// `Self::ALIGN` must be equal to the alignment of `Self`. For sized types it -/// is [`mem::align_of()`], for unsized types it depends on the type, for +/// is [`align_of::()`], for unsized types it depends on the type, for /// example `[T]` has alignment of `T`. /// -/// [`mem::align_of()`]: std::mem::align_of +/// [`align_of::()`]: align_of pub unsafe trait Aligned { /// Alignment of `Self`. const ALIGN: Alignment; diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 39db551adfb8..60f007083baf 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -863,15 +863,13 @@ fn get_thread_id() -> u32 { cfg_match! { windows => { pub fn get_resident_set_size() -> Option { - use std::mem; - use windows::{ Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}, Win32::System::Threading::GetCurrentProcess, }; let mut pmc = PROCESS_MEMORY_COUNTERS::default(); - let pmc_size = mem::size_of_val(&pmc); + let pmc_size = size_of_val(&pmc); unsafe { K32GetProcessMemoryInfo( GetCurrentProcess(), @@ -889,7 +887,7 @@ cfg_match! { pub fn get_resident_set_size() -> Option { use libc::{c_int, c_void, getpid, proc_pidinfo, proc_taskinfo, PROC_PIDTASKINFO}; use std::mem; - const PROC_TASKINFO_SIZE: c_int = mem::size_of::() as c_int; + const PROC_TASKINFO_SIZE: c_int = size_of::() as c_int; unsafe { let mut info: proc_taskinfo = mem::zeroed(); diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index e6be9c256f01..3016348f2246 100644 --- a/compiler/rustc_data_structures/src/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs @@ -1,7 +1,7 @@ use std::borrow::Borrow; use std::collections::hash_map::RawEntryMut; use std::hash::{Hash, Hasher}; -use std::{iter, mem}; +use std::iter; use either::Either; @@ -221,7 +221,7 @@ pub fn make_hash(val: &K) -> u64 { /// consistently for each `Sharded` instance. #[inline] fn get_shard_hash(hash: u64) -> usize { - let hash_len = mem::size_of::(); + let hash_len = size_of::(); // Ignore the top 7 bits as hashbrown uses these and get the next SHARD_BITS highest bits. // hashbrown also uses the lowest bits, so we can't use those (hash >> (hash_len * 8 - 7 - SHARD_BITS)) as usize diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 7fffeaddb866..9f4d2ea5c1ad 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -490,7 +490,7 @@ pub struct Diag<'a, G: EmissionGuarantee = ErrorGuaranteed> { // would be bad. impl !Clone for Diag<'_, G> {} -rustc_data_structures::static_assert_size!(Diag<'_, ()>, 3 * std::mem::size_of::()); +rustc_data_structures::static_assert_size!(Diag<'_, ()>, 3 * size_of::()); impl Deref for Diag<'_, G> { type Target = DiagInner; diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 7e3a8561da08..03aaf30ff5fc 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -429,7 +429,7 @@ pub enum Res { /// mention any generic parameters to allow the following with `min_const_generics`: /// ``` /// # struct Foo; - /// impl Foo { fn test() -> [u8; std::mem::size_of::()] { todo!() } } + /// impl Foo { fn test() -> [u8; size_of::()] { todo!() } } /// /// struct Bar([u8; baz::()]); /// const fn baz() -> usize { 10 } @@ -439,7 +439,7 @@ pub enum Res { /// compat lint: /// ``` /// fn foo() { - /// let _bar = [1_u8; std::mem::size_of::<*mut T>()]; + /// let _bar = [1_u8; size_of::<*mut T>()]; /// } /// ``` // FIXME(generic_const_exprs): Remove this bodge once that feature is stable. diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs index 4c664ea6ba0f..9cec2702a417 100644 --- a/compiler/rustc_incremental/src/persist/file_format.rs +++ b/compiler/rustc_incremental/src/persist/file_format.rs @@ -123,7 +123,7 @@ pub(crate) fn read_file( // Check HEADER_FORMAT_VERSION { - debug_assert!(::std::mem::size_of_val(&HEADER_FORMAT_VERSION) == 2); + debug_assert!(size_of_val(&HEADER_FORMAT_VERSION) == 2); let mut header_format_version = [0u8; 2]; file.read_exact(&mut header_format_version)?; let header_format_version = diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 6dc044a6d380..598409c9051d 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1,7 +1,9 @@ use std::marker::PhantomData; +#[cfg(not(feature = "nightly"))] +use std::mem; use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Bound, Not, Range, RangeBounds, Shl}; use std::rc::Rc; -use std::{fmt, iter, mem, slice}; +use std::{fmt, iter, slice}; use Chunk::*; #[cfg(feature = "nightly")] @@ -14,7 +16,7 @@ use crate::{Idx, IndexVec}; mod tests; type Word = u64; -const WORD_BYTES: usize = mem::size_of::(); +const WORD_BYTES: usize = size_of::(); const WORD_BITS: usize = WORD_BYTES * 8; // The choice of chunk size has some trade-offs. diff --git a/compiler/rustc_index/src/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs index 381d79c24fcb..5b0ca4b2b924 100644 --- a/compiler/rustc_index/src/vec/tests.rs +++ b/compiler/rustc_index/src/vec/tests.rs @@ -9,8 +9,6 @@ crate::newtype_index! { #[test] fn index_size_is_optimized() { - use std::mem::size_of; - assert_eq!(size_of::(), 4); // Uses 0xFFFF_FFFB assert_eq!(size_of::>(), 4); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 3d63ea820530..7138948c32c4 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2711,7 +2711,7 @@ declare_lint! { /// /// ```rust /// const fn foo() -> usize { - /// if std::mem::size_of::<*mut T>() < 8 { // size of *mut T does not depend on T + /// if size_of::<*mut T>() < 8 { // size of *mut T does not depend on T /// 4 /// } else { /// 8 diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs index cc6389e2989e..fea5038e6dd9 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs @@ -223,8 +223,8 @@ impl Decodable for InitMaskMaterialized { // large. impl hash::Hash for InitMaskMaterialized { fn hash(&self, state: &mut H) { - const MAX_BLOCKS_TO_HASH: usize = super::MAX_BYTES_TO_HASH / std::mem::size_of::(); - const MAX_BLOCKS_LEN: usize = super::MAX_HASHED_BUFFER_LEN / std::mem::size_of::(); + const MAX_BLOCKS_TO_HASH: usize = super::MAX_BYTES_TO_HASH / size_of::(); + const MAX_BLOCKS_LEN: usize = super::MAX_HASHED_BUFFER_LEN / size_of::(); // Partially hash the `blocks` buffer when it is large. To limit collisions with common // prefixes and suffixes, we hash the length and some slices of the buffer. diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index c48cfffa05cc..2675b7e0fc51 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -573,7 +573,7 @@ pub fn write_target_uint( #[inline] pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result { // This u128 holds an "any-size uint" (since smaller uints can fits in it) - let mut buf = [0u8; std::mem::size_of::()]; + let mut buf = [0u8; size_of::()]; // So we do not read exactly 16 bytes into the u128, just the "payload". let uint = match endianness { Endian::Little => { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index ea0bb5feb122..83857ab6c5ca 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -332,13 +332,13 @@ pub struct Body<'tcx> { /// /// ```rust /// fn test() { - /// let _ = [0; std::mem::size_of::<*mut T>()]; + /// let _ = [0; size_of::<*mut T>()]; /// } /// ``` /// /// **WARNING**: Do not change this flags after the MIR was originally created, even if an optimization /// removed the last mention of all generic params. We do not want to rely on optimizations and - /// potentially allow things like `[u8; std::mem::size_of::() * 0]` due to this. + /// potentially allow things like `[u8; size_of::() * 0]` due to this. pub is_polymorphic: bool, /// The phase at which this MIR should be "injected" into the compilation process. diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index cbd60920bc57..7e1209a2a7f8 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -27,7 +27,7 @@ pub type Erase = Erased; pub fn erase(src: T) -> Erase { // Ensure the sizes match const { - if std::mem::size_of::() != std::mem::size_of::() { + if size_of::() != size_of::() { panic!("size of T must match erased type T::Result") } }; diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 66a9e5fed4c3..d78a589f2034 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -370,7 +370,7 @@ macro_rules! define_callbacks { // Increase this limit if necessary, but do try to keep the size low if possible #[cfg(target_pointer_width = "64")] const _: () = { - if mem::size_of::>() > 88 { + if size_of::>() > 88 { panic!("{}", concat!( "the query `", stringify!($name), @@ -386,7 +386,7 @@ macro_rules! define_callbacks { #[cfg(target_pointer_width = "64")] #[cfg(not(feature = "rustc_randomized_layouts"))] const _: () = { - if mem::size_of::>() > 64 { + if size_of::>() > 64 { panic!("{}", concat!( "the query `", stringify!($name), diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 7c9280fae16d..9f5e31d894cb 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -408,7 +408,7 @@ macro_rules! from_x_for_scalar_int { fn from(u: $ty) -> Self { Self { data: u128::from(u), - size: NonZero::new(std::mem::size_of::<$ty>() as u8).unwrap(), + size: NonZero::new(size_of::<$ty>() as u8).unwrap(), } } } @@ -424,7 +424,7 @@ macro_rules! from_scalar_int_for_x { fn from(int: ScalarInt) -> Self { // The `unwrap` cannot fail because to_bits (if it succeeds) // is guaranteed to return a value that fits into the size. - int.to_bits(Size::from_bytes(std::mem::size_of::<$ty>())) + int.to_bits(Size::from_bytes(size_of::<$ty>())) .try_into().unwrap() } } diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 27576a2ec4a2..f24910477dc0 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -2,7 +2,6 @@ use core::intrinsics; use std::marker::PhantomData; -use std::mem; use std::num::NonZero; use std::ptr::NonNull; @@ -176,17 +175,17 @@ impl<'tcx> GenericArgKind<'tcx> { let (tag, ptr) = match self { GenericArgKind::Lifetime(lt) => { // Ensure we can use the tag bits. - assert_eq!(mem::align_of_val(&*lt.0.0) & TAG_MASK, 0); + assert_eq!(align_of_val(&*lt.0.0) & TAG_MASK, 0); (REGION_TAG, NonNull::from(lt.0.0).cast()) } GenericArgKind::Type(ty) => { // Ensure we can use the tag bits. - assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0); + assert_eq!(align_of_val(&*ty.0.0) & TAG_MASK, 0); (TYPE_TAG, NonNull::from(ty.0.0).cast()) } GenericArgKind::Const(ct) => { // Ensure we can use the tag bits. - assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0); + assert_eq!(align_of_val(&*ct.0.0) & TAG_MASK, 0); (CONST_TAG, NonNull::from(ct.0.0).cast()) } }; diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 6718493f6b32..0fd370a56195 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -93,7 +93,7 @@ impl RawList { T: Copy, { assert!(!mem::needs_drop::()); - assert!(mem::size_of::() != 0); + assert!(size_of::() != 0); assert!(!slice.is_empty()); let (layout, _offset) = @@ -155,7 +155,7 @@ macro_rules! impl_list_empty { static EMPTY: ListSkeleton<$header_ty, MaxAlign> = ListSkeleton { header: $header_init, len: 0, data: [] }; - assert!(mem::align_of::() <= mem::align_of::()); + assert!(align_of::() <= align_of::()); // SAFETY: `EMPTY` is sufficiently aligned to be an empty list for all // types with `align_of(T) <= align_of(MaxAlign)`, which we checked above. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 527509af05fc..247eb7763d3b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -17,7 +17,7 @@ use std::hash::{Hash, Hasher}; use std::marker::PhantomData; use std::num::NonZero; use std::ptr::NonNull; -use std::{fmt, mem, str}; +use std::{fmt, str}; pub use adt::*; pub use assoc::*; @@ -637,12 +637,12 @@ impl<'tcx> TermKind<'tcx> { let (tag, ptr) = match self { TermKind::Ty(ty) => { // Ensure we can use the tag bits. - assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0); + assert_eq!(align_of_val(&*ty.0.0) & TAG_MASK, 0); (TYPE_TAG, NonNull::from(ty.0.0).cast()) } TermKind::Const(ct) => { // Ensure we can use the tag bits. - assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0); + assert_eq!(align_of_val(&*ct.0.0) & TAG_MASK, 0); (CONST_TAG, NonNull::from(ct.0.0).cast()) } }; diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs index 110546d0ba66..886438fd583a 100644 --- a/compiler/rustc_parse/src/parser/token_type.rs +++ b/compiler/rustc_parse/src/parser/token_type.rs @@ -619,7 +619,7 @@ impl Iterator for TokenTypeSetIter { type Item = TokenType; fn next(&mut self) -> Option { - let num_bits: u32 = (std::mem::size_of_val(&self.0.0) * 8) as u32; + let num_bits: u32 = (size_of_val(&self.0.0) * 8) as u32; assert_eq!(num_bits, 128); let z = self.0.0.trailing_zeros(); if z == num_bits { diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 92ea49f18e5d..71fd8ad7d17a 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -107,12 +107,12 @@ impl<'k> StatCollector<'k> { let node = self.nodes.entry(label1).or_insert(Node::new()); node.stats.count += 1; - node.stats.size = std::mem::size_of_val(val); + node.stats.size = size_of_val(val); if let Some(label2) = label2 { let subnode = node.subnodes.entry(label2).or_insert(NodeStats::new()); subnode.count += 1; - subnode.size = std::mem::size_of_val(val); + subnode.size = size_of_val(val); } } diff --git a/compiler/rustc_passes/src/liveness/rwu_table.rs b/compiler/rustc_passes/src/liveness/rwu_table.rs index 6e2f976e5b08..4c1f6ea141e6 100644 --- a/compiler/rustc_passes/src/liveness/rwu_table.rs +++ b/compiler/rustc_passes/src/liveness/rwu_table.rs @@ -39,7 +39,7 @@ impl RWUTable { /// Size of packed RWU in bits. const RWU_BITS: usize = 4; /// Size of a word in bits. - const WORD_BITS: usize = std::mem::size_of::() * 8; + const WORD_BITS: usize = size_of::() * 8; /// Number of packed RWUs that fit into a single word. const WORD_RWU_COUNT: usize = Self::WORD_BITS / Self::RWU_BITS; diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index bc78878a84a2..2c6fd7d494f0 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -63,7 +63,7 @@ rustc_index::newtype_index! { pub struct SerializedDepNodeIndex {} } -const DEP_NODE_SIZE: usize = std::mem::size_of::(); +const DEP_NODE_SIZE: usize = size_of::(); /// Amount of padding we need to add to the edge list data so that we can retrieve every /// SerializedDepNodeIndex with a fixed-size read then mask. const DEP_NODE_PAD: usize = DEP_NODE_SIZE - 1; @@ -175,7 +175,7 @@ impl EdgeHeader { #[inline] fn mask(bits: usize) -> usize { - usize::MAX >> ((std::mem::size_of::() * 8) - bits) + usize::MAX >> ((size_of::() * 8) - bits) } impl SerializedDepGraph { @@ -208,9 +208,8 @@ impl SerializedDepGraph { // for a node with length 64, which means the spilled 1-byte leb128 length is 1 byte of at // least (34 byte header + 1 byte len + 64 bytes edge data), which is ~1%. A 2-byte leb128 // length is about the same fractional overhead and it amortizes for yet greater lengths. - let mut edge_list_data = Vec::with_capacity( - graph_bytes - node_count * std::mem::size_of::>(), - ); + let mut edge_list_data = + Vec::with_capacity(graph_bytes - node_count * size_of::>()); for _index in 0..node_count { // Decode the header for this edge; the header packs together as many of the fixed-size @@ -300,7 +299,7 @@ struct Unpacked { // M..M+N bytes per index // M+N..16 kind impl SerializedNodeHeader { - const TOTAL_BITS: usize = std::mem::size_of::() * 8; + const TOTAL_BITS: usize = size_of::() * 8; const LEN_BITS: usize = Self::TOTAL_BITS - Self::KIND_BITS - Self::WIDTH_BITS; const WIDTH_BITS: usize = DEP_NODE_WIDTH_BITS; const KIND_BITS: usize = Self::TOTAL_BITS - D::DEP_KIND_MAX.leading_zeros() as usize; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 1e86b9721d4a..2f200be64d5d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2994,7 +2994,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } // HACK(min_const_generics, generic_const_exprs): We - // want to keep allowing `[0; std::mem::size_of::<*mut T>()]` + // want to keep allowing `[0; size_of::<*mut T>()]` // with a future compat lint for now. We do this by adding an // additional special case for repeat expressions. // diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs index aa7c28584666..4a4758056973 100644 --- a/compiler/rustc_serialize/src/leb128.rs +++ b/compiler/rustc_serialize/src/leb128.rs @@ -7,7 +7,7 @@ use crate::serialize::Decoder; /// Returns the length of the longest LEB128 encoding for `T`, assuming `T` is an integer type pub const fn max_leb128_len() -> usize { // The longest LEB128 encoding for an integer uses 7 bits per byte. - (std::mem::size_of::() * 8 + 6) / 7 + (size_of::() * 8 + 6) / 7 } /// Returns the length of the longest LEB128 encoding of all supported integer types. diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index ec83761da4a9..cc2decc2fe4b 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -92,7 +92,7 @@ fn current_dll_path() -> Result { if libc::loadquery( libc::L_GETINFO, buffer.as_mut_ptr() as *mut u8, - (std::mem::size_of::() * buffer.len()) as u32, + (size_of::() * buffer.len()) as u32, ) >= 0 { break; diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 75f53b063d10..39333082acdf 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -2,7 +2,7 @@ //! //! For concrete constants, this is fairly simple as we can just try and evaluate it. //! -//! When dealing with polymorphic constants, for example `std::mem::size_of::() - 1`, +//! When dealing with polymorphic constants, for example `size_of::() - 1`, //! this is not as easy. //! //! In this case we try to build an abstract representation of this constant using diff --git a/compiler/stable_mir/src/mir/alloc.rs b/compiler/stable_mir/src/mir/alloc.rs index 7e0c4a479b8e..023807b76aec 100644 --- a/compiler/stable_mir/src/mir/alloc.rs +++ b/compiler/stable_mir/src/mir/alloc.rs @@ -58,7 +58,7 @@ impl IndexedVal for AllocId { /// Utility function used to read an allocation data into a unassigned integer. pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result { - let mut buf = [0u8; std::mem::size_of::()]; + let mut buf = [0u8; size_of::()]; match MachineInfo::target_endianness() { Endian::Little => { bytes.read_exact(&mut buf[..bytes.len()])?; @@ -73,7 +73,7 @@ pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result { /// Utility function used to read an allocation data into an assigned integer. pub(crate) fn read_target_int(mut bytes: &[u8]) -> Result { - let mut buf = [0u8; std::mem::size_of::()]; + let mut buf = [0u8; size_of::()]; match MachineInfo::target_endianness() { Endian::Little => { bytes.read_exact(&mut buf[..bytes.len()])?; From 8af0aa25c30f16a6e5641b13208dd5defcaaeb93 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 6 Mar 2025 14:43:11 +1100 Subject: [PATCH 825/991] Remove `[lints.rust]` section from `rustc_type_ir`. It was added in #129523 to enable building on stable when there were `cfg(bootstrap)` occurrences in the crate. But those are gone now, so the section can be removed. --- compiler/rustc_type_ir/Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 7b2593b96e37..4adf71579266 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -33,6 +33,3 @@ nightly = [ "rustc_index/nightly", "rustc_ast_ir/nightly", ] - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } From a8eeb4b53b9ea3b8e67e5c6526fe04ba8e93431f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 8 Mar 2025 08:38:49 +1100 Subject: [PATCH 826/991] Remove `[lints.rust]` section from `rustc_builtin_macros`. `llvm_enzyme` is now in the extra `check-cfg` list in bootstrap, so it doesn't need to be handled explicitly here. --- compiler/rustc_builtin_macros/Cargo.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index b5f4f2efd1f5..1289d21308b7 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -3,10 +3,6 @@ name = "rustc_builtin_macros" version = "0.0.0" edition = "2024" - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(llvm_enzyme)'] } - [lib] doctest = false From beba32cebb4fb2ef8f02c4fc898a9d31f1b03c61 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 6 Mar 2025 11:53:30 +1100 Subject: [PATCH 827/991] Specify rust lints for `compiler/` crates via Cargo. By naming them in `[workspace.lints.rust]` in the top-level `Cargo.toml`, and then making all `compiler/` crates inherit them with `[lints] workspace = true`. (I omitted `rustc_codegen_{cranelift,gcc}`, because they're a bit different.) The advantages of this over the current approach: - It uses a standard Cargo feature, rather than special handling in bootstrap. So, easier to understand, and less likely to get accidentally broken in the future. - It works for proc macro crates. It's a shame it doesn't work for rustc-specific lints, as the comments explain. --- Cargo.toml | 13 +++++++++++++ compiler/rustc/Cargo.toml | 3 +++ compiler/rustc_abi/Cargo.toml | 3 +++ compiler/rustc_arena/Cargo.toml | 3 +++ compiler/rustc_ast/Cargo.toml | 3 +++ compiler/rustc_ast_ir/Cargo.toml | 3 +++ compiler/rustc_ast_lowering/Cargo.toml | 3 +++ compiler/rustc_ast_passes/Cargo.toml | 3 +++ compiler/rustc_ast_pretty/Cargo.toml | 3 +++ compiler/rustc_attr_data_structures/Cargo.toml | 3 +++ compiler/rustc_attr_parsing/Cargo.toml | 3 +++ compiler/rustc_baked_icu_data/Cargo.toml | 3 +++ compiler/rustc_borrowck/Cargo.toml | 3 +++ compiler/rustc_builtin_macros/Cargo.toml | 3 +++ compiler/rustc_codegen_llvm/Cargo.toml | 3 +++ compiler/rustc_codegen_ssa/Cargo.toml | 3 +++ compiler/rustc_const_eval/Cargo.toml | 3 +++ compiler/rustc_data_structures/Cargo.toml | 3 +++ compiler/rustc_driver/Cargo.toml | 3 +++ compiler/rustc_driver_impl/Cargo.toml | 3 +++ compiler/rustc_error_codes/Cargo.toml | 3 +++ compiler/rustc_error_messages/Cargo.toml | 3 +++ compiler/rustc_errors/Cargo.toml | 3 +++ compiler/rustc_expand/Cargo.toml | 3 +++ compiler/rustc_feature/Cargo.toml | 3 +++ compiler/rustc_fluent_macro/Cargo.toml | 3 +++ compiler/rustc_fs_util/Cargo.toml | 3 +++ compiler/rustc_graphviz/Cargo.toml | 3 +++ compiler/rustc_hashes/Cargo.toml | 3 +++ compiler/rustc_hir/Cargo.toml | 3 +++ compiler/rustc_hir_analysis/Cargo.toml | 3 +++ compiler/rustc_hir_pretty/Cargo.toml | 3 +++ compiler/rustc_hir_typeck/Cargo.toml | 3 +++ compiler/rustc_incremental/Cargo.toml | 3 +++ compiler/rustc_index/Cargo.toml | 3 +++ compiler/rustc_index_macros/Cargo.toml | 3 +++ compiler/rustc_infer/Cargo.toml | 3 +++ compiler/rustc_interface/Cargo.toml | 3 +++ compiler/rustc_lexer/Cargo.toml | 3 +++ compiler/rustc_lint/Cargo.toml | 3 +++ compiler/rustc_lint_defs/Cargo.toml | 3 +++ compiler/rustc_llvm/Cargo.toml | 3 +++ compiler/rustc_log/Cargo.toml | 3 +++ compiler/rustc_macros/Cargo.toml | 3 +++ compiler/rustc_metadata/Cargo.toml | 3 +++ compiler/rustc_middle/Cargo.toml | 3 +++ compiler/rustc_mir_build/Cargo.toml | 3 +++ compiler/rustc_mir_dataflow/Cargo.toml | 3 +++ compiler/rustc_mir_transform/Cargo.toml | 3 +++ compiler/rustc_monomorphize/Cargo.toml | 3 +++ compiler/rustc_next_trait_solver/Cargo.toml | 3 +++ compiler/rustc_parse/Cargo.toml | 2 ++ compiler/rustc_parse_format/Cargo.toml | 3 +++ compiler/rustc_passes/Cargo.toml | 3 +++ compiler/rustc_pattern_analysis/Cargo.toml | 3 +++ compiler/rustc_privacy/Cargo.toml | 3 +++ compiler/rustc_query_impl/Cargo.toml | 3 +++ compiler/rustc_query_system/Cargo.toml | 3 +++ compiler/rustc_resolve/Cargo.toml | 3 +++ compiler/rustc_sanitizers/Cargo.toml | 3 +++ compiler/rustc_serialize/Cargo.toml | 3 +++ compiler/rustc_session/Cargo.toml | 3 +++ compiler/rustc_smir/Cargo.toml | 3 +++ compiler/rustc_span/Cargo.toml | 3 +++ compiler/rustc_symbol_mangling/Cargo.toml | 3 +++ compiler/rustc_target/Cargo.toml | 3 +++ compiler/rustc_trait_selection/Cargo.toml | 3 +++ compiler/rustc_traits/Cargo.toml | 3 +++ compiler/rustc_transmute/Cargo.toml | 3 +++ compiler/rustc_ty_utils/Cargo.toml | 3 +++ compiler/rustc_type_ir/Cargo.toml | 3 +++ compiler/rustc_type_ir_macros/Cargo.toml | 3 +++ compiler/stable_mir/Cargo.toml | 3 +++ src/bootstrap/src/core/builder/cargo.rs | 13 +++++++++---- 74 files changed, 237 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 20a43aaaeeb3..4e952ccfc73d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,19 @@ exclude = [ "src/tools/x", ] +# These lints are applied to many crates in the workspace. In practice, this is +# all crates under `compiler/`. +# +# NOTE: rustc-specific lints (e.g. `rustc::internal`) aren't supported by +# Cargo. (Support for them is possibly blocked by #44690 (attributes for +# tools).) Those lints are instead specified for `compiler/` crates in +# `src/bootstrap/src/core/builder/cargo.rs`. +[workspace.lints.rust] +# FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all of the +# individual lints are satisfied. +keyword_idents_2024 = "warn" +unsafe_op_in_unsafe_fn = "warn" + [profile.release.package.rustc-rayon-core] # The rustc fork of Rayon has deadlock detection code which intermittently # causes overflows in the CI (see https://github.com/rust-lang/rust/issues/90227) diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index f4caa3ef769d..7af0b34d2daf 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -32,3 +32,6 @@ llvm = ['rustc_driver_impl/llvm'] max_level_info = ['rustc_driver_impl/max_level_info'] rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts'] # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 86dc84e2016d..4713b3474bdb 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -31,3 +31,6 @@ nightly = [ ] randomize = ["dep:rand", "dep:rand_xoshiro", "nightly"] # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_arena/Cargo.toml b/compiler/rustc_arena/Cargo.toml index bbcd8ea6d389..1a600f0ee3f8 100644 --- a/compiler/rustc_arena/Cargo.toml +++ b/compiler/rustc_arena/Cargo.toml @@ -7,3 +7,6 @@ edition = "2024" # tidy-alphabetical-start smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 902287d03280..259b51689e42 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -18,3 +18,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_ast_ir/Cargo.toml b/compiler/rustc_ast_ir/Cargo.toml index f54e9687d8c7..668c45438d6d 100644 --- a/compiler/rustc_ast_ir/Cargo.toml +++ b/compiler/rustc_ast_ir/Cargo.toml @@ -19,3 +19,6 @@ nightly = [ "dep:rustc_macros", "dep:rustc_span", ] + +[lints] +workspace = true diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 2ec4f4b05551..358963c79975 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -28,3 +28,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index c738cb2aa2fd..5966308a2626 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -20,3 +20,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index 2634dd1fdf93..b120bdc2f05e 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -12,3 +12,6 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_attr_data_structures/Cargo.toml b/compiler/rustc_attr_data_structures/Cargo.toml index b18923c337ff..8fbc21f3ba28 100644 --- a/compiler/rustc_attr_data_structures/Cargo.toml +++ b/compiler/rustc_attr_data_structures/Cargo.toml @@ -14,3 +14,6 @@ rustc_serialize = {path = "../rustc_serialize"} rustc_span = {path = "../rustc_span"} thin-vec = "0.2.12" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml index c335eeb5f712..39f4010f3038 100644 --- a/compiler/rustc_attr_parsing/Cargo.toml +++ b/compiler/rustc_attr_parsing/Cargo.toml @@ -21,3 +21,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml index cb0e145386b8..1480b59f1e02 100644 --- a/compiler/rustc_baked_icu_data/Cargo.toml +++ b/compiler/rustc_baked_icu_data/Cargo.toml @@ -11,3 +11,6 @@ icu_locid_transform = "1.3.2" icu_provider = { version = "1.2", features = ["sync"] } zerovec = "0.10.0" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml index 9e7d55180a23..15338eeb37a8 100644 --- a/compiler/rustc_borrowck/Cargo.toml +++ b/compiler/rustc_borrowck/Cargo.toml @@ -27,3 +27,6 @@ rustc_traits = { path = "../rustc_traits" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 1289d21308b7..da3572eebeea 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -30,3 +30,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index d3ce7c5a1130..1741c3bacc77 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -43,3 +43,6 @@ serde_json = "1" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 1346efcb87c2..c00be0e99263 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -63,3 +63,6 @@ features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", [target.'cfg(windows)'.dependencies.windows] version = "0.59.0" features = ["Win32_Globalization"] + +[lints] +workspace = true diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index a0cc2c65e6e0..d76238a3992f 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -26,3 +26,6 @@ rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_type_ir = { path = "../rustc_type_ir" } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index bdf5494f2107..b364ab0dde4f 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -54,3 +54,6 @@ memmap2 = "0.2.1" [target.'cfg(not(target_has_atomic = "64"))'.dependencies] portable-atomic = "1.5.1" + +[lints] +workspace = true diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index e3ee83512952..d27895a5e7a2 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -10,3 +10,6 @@ crate-type = ["dylib"] # tidy-alphabetical-start rustc_driver_impl = { path = "../rustc_driver_impl" } # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 8593d1faba26..4469fa4e1f3a 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -79,3 +79,6 @@ rustc_randomized_layouts = [ 'rustc_middle/rustc_randomized_layouts' ] # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_error_codes/Cargo.toml b/compiler/rustc_error_codes/Cargo.toml index 55b4e8990512..d89e4526016c 100644 --- a/compiler/rustc_error_codes/Cargo.toml +++ b/compiler/rustc_error_codes/Cargo.toml @@ -6,3 +6,6 @@ edition = "2024" [dependencies] # tidy-alphabetical-start # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml index 578af7fc51d4..e9047ba16e50 100644 --- a/compiler/rustc_error_messages/Cargo.toml +++ b/compiler/rustc_error_messages/Cargo.toml @@ -19,3 +19,6 @@ rustc_span = { path = "../rustc_span" } tracing = "0.1" unic-langid = { version = "0.9.0", features = ["macros"] } # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index b11793c190a1..fc39a726093a 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -39,3 +39,6 @@ features = [ "Win32_Security", "Win32_System_Threading", ] + +[lints] +workspace = true diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index 0ba139ea5cc5..f051ea0c2ac1 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -29,3 +29,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_feature/Cargo.toml b/compiler/rustc_feature/Cargo.toml index a5ae06473cbe..1aaace75404b 100644 --- a/compiler/rustc_feature/Cargo.toml +++ b/compiler/rustc_feature/Cargo.toml @@ -10,3 +10,6 @@ rustc_span = { path = "../rustc_span" } serde = { version = "1.0.125", features = [ "derive" ] } serde_json = "1.0.59" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_fluent_macro/Cargo.toml b/compiler/rustc_fluent_macro/Cargo.toml index ce76b2745eaa..695e8b3fd5db 100644 --- a/compiler/rustc_fluent_macro/Cargo.toml +++ b/compiler/rustc_fluent_macro/Cargo.toml @@ -16,3 +16,6 @@ quote = "1" syn = { version = "2", features = ["full"] } unic-langid = { version = "0.9.0", features = ["macros"] } # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_fs_util/Cargo.toml b/compiler/rustc_fs_util/Cargo.toml index baca3bc7d49e..3518209ea5b7 100644 --- a/compiler/rustc_fs_util/Cargo.toml +++ b/compiler/rustc_fs_util/Cargo.toml @@ -6,3 +6,6 @@ edition = "2024" [dependencies] # tidy-alphabetical-start # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_graphviz/Cargo.toml b/compiler/rustc_graphviz/Cargo.toml index d84943760bae..2672a624eabe 100644 --- a/compiler/rustc_graphviz/Cargo.toml +++ b/compiler/rustc_graphviz/Cargo.toml @@ -6,3 +6,6 @@ edition = "2024" [dependencies] # tidy-alphabetical-start # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_hashes/Cargo.toml b/compiler/rustc_hashes/Cargo.toml index c7a273cff88c..ff46696c4c06 100644 --- a/compiler/rustc_hashes/Cargo.toml +++ b/compiler/rustc_hashes/Cargo.toml @@ -7,3 +7,6 @@ edition = "2024" # tidy-alphabetical-start rustc-stable-hash = { version = "0.1.0" } # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 7ca8539845a0..e45c49cd7dbf 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -21,3 +21,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index 55a816a855af..99ced5ff0a91 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -32,3 +32,6 @@ rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml index 86989d1e55b4..ec95438b4212 100644 --- a/compiler/rustc_hir_pretty/Cargo.toml +++ b/compiler/rustc_hir_pretty/Cargo.toml @@ -12,3 +12,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_hir = { path = "../rustc_hir" } rustc_span = { path = "../rustc_span" } # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index f1afb7b712d5..1d6486fb7dc0 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -27,3 +27,6 @@ rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index 4939bfb3a1cd..754881309bf5 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -22,3 +22,6 @@ rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml index 3d83a3c98daf..ee6fe11f9a5b 100644 --- a/compiler/rustc_index/Cargo.toml +++ b/compiler/rustc_index/Cargo.toml @@ -21,3 +21,6 @@ nightly = [ ] rustc_randomized_layouts = [] # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml index 891e7ded6199..de100bd0e2c1 100644 --- a/compiler/rustc_index_macros/Cargo.toml +++ b/compiler/rustc_index_macros/Cargo.toml @@ -13,3 +13,6 @@ quote = "1" [features] nightly = [] + +[lints] +workspace = true diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 08c036148849..242886a92482 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -21,3 +21,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 9c9660cf5046..add8c0e20e63 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -56,3 +56,6 @@ tracing = "0.1" # tidy-alphabetical-start llvm = ['dep:rustc_codegen_llvm'] # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml index 448a50faf458..b9b16eebc548 100644 --- a/compiler/rustc_lexer/Cargo.toml +++ b/compiler/rustc_lexer/Cargo.toml @@ -24,3 +24,6 @@ features = ["emoji"] [dev-dependencies] expect-test = "1.4.0" + +[lints] +workspace = true diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index d6014f5006ad..f6c10aa97441 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -28,3 +28,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" unicode-security = "0.1.0" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_lint_defs/Cargo.toml b/compiler/rustc_lint_defs/Cargo.toml index 9ab350daf69d..f9b45a00ec10 100644 --- a/compiler/rustc_lint_defs/Cargo.toml +++ b/compiler/rustc_lint_defs/Cargo.toml @@ -15,3 +15,6 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } serde = { version = "1.0.125", features = ["derive"] } # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 061562b2ec5e..dcfaf9a0282e 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -14,3 +14,6 @@ libc = "0.2.73" # pinned `cc` in `rustc_codegen_ssa` if you update `cc` here. cc = "=1.2.16" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml index 30f6e9ba8053..665ebd52f474 100644 --- a/compiler/rustc_log/Cargo.toml +++ b/compiler/rustc_log/Cargo.toml @@ -20,3 +20,6 @@ rustc_span = { path = "../rustc_span" } # tidy-alphabetical-start max_level_info = ['tracing/max_level_info'] # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml index f9d3b7583590..b937f75e892a 100644 --- a/compiler/rustc_macros/Cargo.toml +++ b/compiler/rustc_macros/Cargo.toml @@ -13,3 +13,6 @@ quote = "1" syn = { version = "2.0.9", features = ["full"] } synstructure = "0.13.0" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index a8821640f048..5fa3047d14e0 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -31,3 +31,6 @@ rustc_type_ir = { path = "../rustc_type_ir" } tempfile = "3.2" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index aebd2181f31e..63b648b770d5 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -42,3 +42,6 @@ tracing = "0.1" # tidy-alphabetical-start rustc_randomized_layouts = [] # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index d70d70a31a4a..a29c01162664 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -28,3 +28,6 @@ rustc_span = { path = "../rustc_span" } rustc_trait_selection = { path = "../rustc_trait_selection" } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index 293bcbef21b8..a171f9641bb6 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml @@ -21,3 +21,6 @@ rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index fb8d0ac5e74a..4dc91723f03f 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -30,3 +30,6 @@ rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 36b76d261de6..51be8e55fa71 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -22,3 +22,6 @@ serde = "1" serde_json = "1" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index 63aa60f2f26b..e119d23d41a1 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -24,3 +24,6 @@ nightly = [ "rustc_index/nightly", "rustc_type_ir/nightly", ] + +[lints] +workspace = true diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index c9dcab0c871d..b78ac197dbba 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -26,3 +26,5 @@ unicode-width = "0.2.0" [dev-dependencies] termcolor = "1.2" +[lints] +workspace = true diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml index a39cca716d23..a720903097ae 100644 --- a/compiler/rustc_parse_format/Cargo.toml +++ b/compiler/rustc_parse_format/Cargo.toml @@ -8,3 +8,6 @@ edition = "2024" rustc_index = { path = "../rustc_index", default-features = false } rustc_lexer = { path = "../rustc_lexer" } # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index ba81ef3103bd..4cd7fde60348 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -26,3 +26,6 @@ rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml index 40d549630aca..0624fe96cd91 100644 --- a/compiler/rustc_pattern_analysis/Cargo.toml +++ b/compiler/rustc_pattern_analysis/Cargo.toml @@ -43,3 +43,6 @@ rustc = [ "smallvec/may_dangle", "rustc_index/nightly", ] + +[lints] +workspace = true diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index 242c67d732af..dc00ea8af43a 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -18,3 +18,6 @@ rustc_span = { path = "../rustc_span" } rustc_ty_utils = { path = "../rustc_ty_utils" } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index c85156e059e5..42f784481515 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -20,3 +20,6 @@ rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 3e8ccb51021e..c34d1170f0e1 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -25,3 +25,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index f4771f1af2cf..8958a3ac3048 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -28,3 +28,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_sanitizers/Cargo.toml b/compiler/rustc_sanitizers/Cargo.toml index 900cd4243b13..e18ed121ca50 100644 --- a/compiler/rustc_sanitizers/Cargo.toml +++ b/compiler/rustc_sanitizers/Cargo.toml @@ -15,3 +15,6 @@ rustc_middle = { path = "../rustc_middle" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } + +[lints] +workspace = true diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 948242352e7a..10bfe14abde0 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -16,3 +16,6 @@ thin-vec = "0.2.12" rustc_macros = { path = "../rustc_macros" } tempfile = "3.2" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index a087725d34dd..4b2b41ba845a 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -37,3 +37,6 @@ features = [ "Win32_Foundation", "Win32_System_LibraryLoader", ] + +[lints] +workspace = true diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index a11df9a9c9bc..d14bff73b8b4 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -18,3 +18,6 @@ scoped-tls = "1.0" stable_mir = {path = "../stable_mir" } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index 43a2d692577e..a6f86151b812 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -22,3 +22,6 @@ sha2 = "0.10.1" tracing = "0.1" unicode-width = "0.2.0" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index 90ddf4c8a040..89fe7ef2e408 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -19,3 +19,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml index 189b19b02861..6a0268cdee76 100644 --- a/compiler/rustc_target/Cargo.toml +++ b/compiler/rustc_target/Cargo.toml @@ -22,3 +22,6 @@ default-features = false features = ["elf", "macho"] version = "0.36.2" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 1c61e23362a8..5def437bd807 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -26,3 +26,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2" tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index 04aef4e7b9e0..49bcaae85714 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -13,3 +13,6 @@ rustc_span = { path = "../rustc_span" } rustc_trait_selection = { path = "../rustc_trait_selection" } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index f0c783b30020..ae1beb107288 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -25,3 +25,6 @@ rustc = [ # tidy-alphabetical-start itertools = "0.12" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 4c7a57f2931b..61acc12d0eb9 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -23,3 +23,6 @@ rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_type_ir = { path = "../rustc_type_ir" } tracing = "0.1" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 4adf71579266..0381797d7e92 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -33,3 +33,6 @@ nightly = [ "rustc_index/nightly", "rustc_ast_ir/nightly", ] + +[lints] +workspace = true diff --git a/compiler/rustc_type_ir_macros/Cargo.toml b/compiler/rustc_type_ir_macros/Cargo.toml index 15a555750992..a3fa46238558 100644 --- a/compiler/rustc_type_ir_macros/Cargo.toml +++ b/compiler/rustc_type_ir_macros/Cargo.toml @@ -13,3 +13,6 @@ quote = "1" syn = { version = "2.0.9", features = ["full"] } synstructure = "0.13.0" # tidy-alphabetical-end + +[lints] +workspace = true diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml index d691a0e4f22f..358a39154024 100644 --- a/compiler/stable_mir/Cargo.toml +++ b/compiler/stable_mir/Cargo.toml @@ -6,3 +6,6 @@ edition = "2024" [dependencies] scoped-tls = "1.0" serde = { version = "1.0.125", features = [ "derive" ] } + +[lints] +workspace = true diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index d1d52d82eaa0..181540074363 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -1072,12 +1072,17 @@ impl Builder<'_> { } if mode == Mode::Rustc { + // NOTE: rustc-specific lints are specified here. Normal rust lints + // are specified in the `[workspace.lints.rust]` section in the + // top-level `Cargo.toml`. If/when tool lints are supported by + // Cargo, these lints can be move to a `[workspace.lints.rustc]` + // section in the top-level `Cargo.toml`. + // + // NOTE: these flags are added to RUSTFLAGS, which is ignored when + // compiling proc macro crates such as `rustc_macros`, + // unfortunately. rustflags.arg("-Wrustc::internal"); rustflags.arg("-Drustc::symbol_intern_string_literal"); - // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all - // of the individual lints are satisfied. - rustflags.arg("-Wkeyword_idents_2024"); - rustflags.arg("-Wunsafe_op_in_unsafe_fn"); } if self.config.rust_frame_pointers { From 9212e31c92aba29fac1c1e05a258abe36dd0afee Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 6 Mar 2025 14:25:44 +1100 Subject: [PATCH 828/991] Add `unreachable_pub` to the default lints for `compiler/` crates. And fix the new errors in the handful of crates that didn't have a `#![warn(unreachable_pub)]`. --- Cargo.toml | 1 + compiler/rustc_baked_icu_data/src/lib.rs | 2 +- compiler/rustc_data_structures/src/graph/tests.rs | 4 ++-- .../src/obligation_forest/mod.rs | 2 +- compiler/rustc_data_structures/src/sync.rs | 2 +- .../rustc_data_structures/src/sync/parallel.rs | 2 +- .../rustc_data_structures/src/tagged_ptr/tests.rs | 2 +- compiler/rustc_index_macros/src/newtype.rs | 2 +- .../rustc_pattern_analysis/tests/common/mod.rs | 14 +++++++------- 9 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4e952ccfc73d..e2d032e08066 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,6 +74,7 @@ exclude = [ # FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all of the # individual lints are satisfied. keyword_idents_2024 = "warn" +unreachable_pub = "warn" unsafe_op_in_unsafe_fn = "warn" [profile.release.package.rustc-rayon-core] diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs index f86a9db61c60..df9bee0ebf51 100644 --- a/compiler/rustc_baked_icu_data/src/lib.rs +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -23,9 +23,9 @@ // tidy-alphabetical-start #![allow(elided_lifetimes_in_paths)] #![allow(internal_features)] +#![allow(unreachable_pub)] // because this crate is mostly generated code #![doc(rust_logo)] #![feature(rustdoc_internals)] -// #![warn(unreachable_pub)] // don't use because this crate is mostly generated code // tidy-alphabetical-end mod data { diff --git a/compiler/rustc_data_structures/src/graph/tests.rs b/compiler/rustc_data_structures/src/graph/tests.rs index b69b9dbc4a8e..e48b9686c260 100644 --- a/compiler/rustc_data_structures/src/graph/tests.rs +++ b/compiler/rustc_data_structures/src/graph/tests.rs @@ -3,7 +3,7 @@ use std::cmp::max; use super::*; use crate::fx::FxHashMap; -pub struct TestGraph { +pub(super) struct TestGraph { num_nodes: usize, start_node: usize, successors: FxHashMap>, @@ -11,7 +11,7 @@ pub struct TestGraph { } impl TestGraph { - pub fn new(start_node: usize, edges: &[(usize, usize)]) -> Self { + pub(super) fn new(start_node: usize, edges: &[(usize, usize)]) -> Self { let mut graph = TestGraph { num_nodes: start_node + 1, start_node, diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index 78d69a66edc8..8d19fc5f9ccf 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -313,7 +313,7 @@ pub struct Error { mod helper { use super::*; - pub type ObligationTreeIdGenerator = impl Iterator; + pub(super) type ObligationTreeIdGenerator = impl Iterator; impl ObligationForest { pub fn new() -> ObligationForest { ObligationForest { diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index a1cc75c49850..616a18a72ab7 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -88,7 +88,7 @@ mod mode { // Whether thread safety might be enabled. #[inline] - pub fn might_be_dyn_thread_safe() -> bool { + pub(super) fn might_be_dyn_thread_safe() -> bool { DYN_THREAD_SAFE_MODE.load(Ordering::Relaxed) != DYN_NOT_THREAD_SAFE } diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index 1ba631b86237..8ef8a3f35856 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs @@ -46,7 +46,7 @@ pub fn parallel_guard(f: impl FnOnce(&ParallelGuard) -> R) -> R { ret } -pub fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) +fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) where A: FnOnce() -> RA, B: FnOnce() -> RB, diff --git a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs index 9c1e4cefa692..85b21a7c8ecd 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs @@ -7,7 +7,7 @@ use crate::stable_hasher::{HashStable, StableHasher}; /// A tag type used in [`TaggedRef`] tests. #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Tag2 { +enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs index 67ec77611339..f0b58eabbff9 100644 --- a/compiler/rustc_index_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs @@ -305,7 +305,7 @@ impl Parse for Newtype { } } -pub fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub(crate) fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as Newtype); input.0.into() } diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs index 365bc2d863f4..8980b644f59b 100644 --- a/compiler/rustc_pattern_analysis/tests/common/mod.rs +++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs @@ -5,7 +5,7 @@ use rustc_pattern_analysis::usefulness::{PlaceValidity, UsefulnessReport}; use rustc_pattern_analysis::{MatchArm, PatCx, PrivateUninhabitedField}; /// Sets up `tracing` for easier debugging. Tries to look like the `rustc` setup. -pub fn init_tracing() { +fn init_tracing() { use tracing_subscriber::Layer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; @@ -24,7 +24,7 @@ pub fn init_tracing() { /// A simple set of types. #[allow(dead_code)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum Ty { +pub(super) enum Ty { /// Booleans Bool, /// 8-bit unsigned integers @@ -41,7 +41,7 @@ pub enum Ty { /// The important logic. impl Ty { - pub fn sub_tys(&self, ctor: &Constructor) -> Vec { + pub(super) fn sub_tys(&self, ctor: &Constructor) -> Vec { use Constructor::*; match (ctor, *self) { (Struct, Ty::Tuple(tys)) => tys.iter().copied().collect(), @@ -63,7 +63,7 @@ impl Ty { } } - pub fn ctor_set(&self) -> ConstructorSet { + fn ctor_set(&self) -> ConstructorSet { match *self { Ty::Bool => ConstructorSet::Bool, Ty::U8 => ConstructorSet::Integers { @@ -104,7 +104,7 @@ impl Ty { } } - pub fn write_variant_name( + fn write_variant_name( &self, f: &mut std::fmt::Formatter<'_>, ctor: &Constructor, @@ -120,7 +120,7 @@ impl Ty { } /// Compute usefulness in our simple context (and set up tracing for easier debugging). -pub fn compute_match_usefulness<'p>( +pub(super) fn compute_match_usefulness<'p>( arms: &[MatchArm<'p, Cx>], ty: Ty, scrut_validity: PlaceValidity, @@ -137,7 +137,7 @@ pub fn compute_match_usefulness<'p>( } #[derive(Debug)] -pub struct Cx; +pub(super) struct Cx; /// The context for pattern analysis. Forwards anything interesting to `Ty` methods. impl PatCx for Cx { From 8a3e03392ef12508a3ce50875594ddedd1164ed7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 6 Mar 2025 14:37:13 +1100 Subject: [PATCH 829/991] Remove `#![warn(unreachable_pub)]` from all `compiler/` crates. (Except for `rustc_codegen_cranelift`.) It's no longer necessary now that `unreachable_pub` is in the workspace lints. --- compiler/rustc_abi/src/lib.rs | 1 - compiler/rustc_arena/src/lib.rs | 1 - compiler/rustc_ast/src/lib.rs | 1 - compiler/rustc_ast_ir/src/lib.rs | 1 - compiler/rustc_ast_lowering/src/lib.rs | 1 - compiler/rustc_ast_passes/src/lib.rs | 1 - compiler/rustc_ast_pretty/src/lib.rs | 1 - compiler/rustc_attr_data_structures/src/lib.rs | 1 - compiler/rustc_attr_parsing/src/lib.rs | 1 - compiler/rustc_borrowck/src/lib.rs | 1 - compiler/rustc_builtin_macros/src/lib.rs | 1 - compiler/rustc_codegen_llvm/src/lib.rs | 1 - compiler/rustc_codegen_ssa/src/lib.rs | 1 - compiler/rustc_const_eval/src/lib.rs | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_error_codes/src/lib.rs | 1 - compiler/rustc_error_messages/src/lib.rs | 1 - compiler/rustc_errors/src/lib.rs | 1 - compiler/rustc_expand/src/lib.rs | 1 - compiler/rustc_feature/src/lib.rs | 1 - compiler/rustc_fluent_macro/src/lib.rs | 1 - compiler/rustc_graphviz/src/lib.rs | 1 - compiler/rustc_hir/src/lib.rs | 1 - compiler/rustc_hir_analysis/src/lib.rs | 1 - compiler/rustc_hir_pretty/src/lib.rs | 1 - compiler/rustc_hir_typeck/src/lib.rs | 1 - compiler/rustc_incremental/src/lib.rs | 1 - compiler/rustc_index/src/lib.rs | 1 - compiler/rustc_infer/src/lib.rs | 1 - compiler/rustc_interface/src/lib.rs | 1 - compiler/rustc_lexer/src/lib.rs | 1 - compiler/rustc_lint/src/lib.rs | 1 - compiler/rustc_lint_defs/src/lib.rs | 4 ---- compiler/rustc_llvm/src/lib.rs | 1 - compiler/rustc_macros/src/lib.rs | 1 - compiler/rustc_metadata/src/lib.rs | 1 - compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_mir_build/src/lib.rs | 1 - compiler/rustc_mir_dataflow/src/lib.rs | 1 - compiler/rustc_mir_transform/src/lib.rs | 1 - compiler/rustc_monomorphize/src/lib.rs | 1 - compiler/rustc_next_trait_solver/src/lib.rs | 1 - compiler/rustc_parse/src/lib.rs | 1 - compiler/rustc_parse_format/src/lib.rs | 1 - compiler/rustc_passes/src/lib.rs | 1 - compiler/rustc_pattern_analysis/src/lib.rs | 1 - compiler/rustc_privacy/src/lib.rs | 1 - compiler/rustc_query_impl/src/lib.rs | 1 - compiler/rustc_query_system/src/lib.rs | 1 - compiler/rustc_resolve/src/lib.rs | 1 - compiler/rustc_sanitizers/src/lib.rs | 1 - compiler/rustc_serialize/src/lib.rs | 1 - compiler/rustc_session/src/lib.rs | 1 - compiler/rustc_smir/src/lib.rs | 1 - compiler/rustc_span/src/lib.rs | 1 - compiler/rustc_symbol_mangling/src/lib.rs | 1 - compiler/rustc_target/src/lib.rs | 1 - compiler/rustc_trait_selection/src/lib.rs | 1 - compiler/rustc_traits/src/lib.rs | 1 - compiler/rustc_transmute/src/lib.rs | 1 - compiler/rustc_ty_utils/src/lib.rs | 1 - compiler/rustc_type_ir/src/lib.rs | 1 - 62 files changed, 65 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index a59dc870aa33..06131474d78f 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -5,7 +5,6 @@ #![cfg_attr(feature = "nightly", feature(rustc_attrs))] #![cfg_attr(feature = "nightly", feature(rustdoc_internals))] #![cfg_attr(feature = "nightly", feature(step_trait))] -#![warn(unreachable_pub)] // tidy-alphabetical-end /*! ABI handling for rustc diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index b21ccba93bb4..d72f6a9c924e 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -23,7 +23,6 @@ #![feature(maybe_uninit_slice)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::alloc::Layout; diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 6372c66050e7..294c6c9ba7a5 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -19,7 +19,6 @@ #![feature(never_type)] #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod util { diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index 9884e191ea7b..6d05cd18cec1 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -9,7 +9,6 @@ #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(never_type))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] -#![warn(unreachable_pub)] // tidy-alphabetical-end #[cfg(feature = "nightly")] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index f58320680284..6a90b9d1da41 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -38,7 +38,6 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::sync::Arc; diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index b4ed70d83e57..093199cf3421 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -10,7 +10,6 @@ #![feature(iter_is_partitioned)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod ast_validation; diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 602ab69ee5b5..84d9ce278a21 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -3,7 +3,6 @@ #![doc(rust_logo)] #![feature(box_patterns)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod helpers; diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index e4bb459e6df5..d90be4bd5fe8 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -3,7 +3,6 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod attributes; diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 9841166b37db..aab6fdc8cf30 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -80,7 +80,6 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end #[macro_use] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 68e0ab0933e6..780dc0d81e45 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -13,7 +13,6 @@ #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index ca16583a45de..c23ce1e5e4a2 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -18,7 +18,6 @@ #![feature(rustdoc_internals)] #![feature(string_from_utf8_lossy_owned)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 8f72307eeba3..d51532b3898b 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -19,7 +19,6 @@ #![feature(rustdoc_internals)] #![feature(slice_as_array)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::any::Any; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 4e758bfdec39..8ad040324147 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -14,7 +14,6 @@ #![feature(rustdoc_internals)] #![feature(trait_alias)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end //! This crate contains codegen code that is used by all codegen backends (LLVM and others). diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index ed5489652fba..da52d60ae59f 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -16,7 +16,6 @@ #![feature(unqualified_local_imports)] #![feature(yeet_expr)] #![warn(unqualified_local_imports)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod check_consts; diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index a2ddff7183e6..6e4020c6eca1 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -16,7 +16,6 @@ #![feature(result_flattening)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cmp::max; diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index d53d5678832b..dfeef5a957d6 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -6,7 +6,6 @@ #![deny(rustdoc::invalid_codeblock_attributes)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // This higher-order macro defines the error codes that are in use. It is used diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index ba1c3e185c2d..a6fbbb29ccd3 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -4,7 +4,6 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(type_alias_impl_trait)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index f69e756a3e1b..d535f02a9e14 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -24,7 +24,6 @@ #![feature(trait_alias)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_errors; diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 777044e3f33b..4222c9fe9061 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -13,7 +13,6 @@ #![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro as pm; diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 0b034a2ae107..25764755a8fc 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -15,7 +15,6 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod accepted; diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index 3ad51fa1e64d..c6e0484b9210 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -7,7 +7,6 @@ #![feature(proc_macro_span)] #![feature(rustdoc_internals)] #![feature(track_path)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index b5774f64b66b..c8f8fd5be023 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -277,7 +277,6 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 270d4fbec30f..84d369f1eddb 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -13,7 +13,6 @@ #![feature(never_type)] #![feature(rustc_attrs)] #![feature(variant_count)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_hir; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 50b0e32b95eb..26a20690a95c 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -73,7 +73,6 @@ This API is completely unstable and subject to change. #![feature(slice_partition_dedup)] #![feature(try_blocks)] #![feature(unwrap_infallible)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // These are used by Clippy. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 147b42c04908..3cbf230e2cf6 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -3,7 +3,6 @@ // tidy-alphabetical-start #![recursion_limit = "256"] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::Cell; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 8b9c2b4a6ca0..263fb84206e0 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -8,7 +8,6 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod _match; diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 563ed7614c60..299ee4876389 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -7,7 +7,6 @@ #![doc(rust_logo)] #![feature(file_buffered)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod assert_dep_graph; diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 3441a5f65c78..cc680838e7e7 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -4,7 +4,6 @@ #![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))] #![cfg_attr(feature = "nightly", feature(new_range_api))] #![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod bit_set; diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index a04b2bb2b08b..ece18f4ea64e 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -24,7 +24,6 @@ #![feature(let_chains)] #![feature(rustdoc_internals)] #![recursion_limit = "512"] // For rustdoc -#![warn(unreachable_pub)] // tidy-alphabetical-end mod errors; diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 54cd341698f0..67e0be93523d 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -4,7 +4,6 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod callbacks; diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index bf18845a0830..61638e45253f 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -23,7 +23,6 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod cursor; diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7018774e5c6b..35867d8c9efe 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -32,7 +32,6 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod async_closures; diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index e564235c41a5..46b4b1d43838 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -1,7 +1,3 @@ -// tidy-alphabetical-start -#![warn(unreachable_pub)] -// tidy-alphabetical-end - use rustc_abi::ExternAbi; use rustc_ast::AttrId; use rustc_ast::attr::AttributeExt; diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index eda9b2b1fc09..68058250a267 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -4,7 +4,6 @@ #![doc(rust_logo)] #![feature(extern_types)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::RefCell; diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 34fc0f00320c..44ba064dd824 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -6,7 +6,6 @@ #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] #![feature(proc_macro_tracked_env)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index ebcc0efd5a67..8898c5824fa2 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -15,7 +15,6 @@ #![feature(proc_macro_internals)] #![feature(rustdoc_internals)] #![feature(trusted_len)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 48ea7df5c23f..8fe2cc7101ba 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -61,7 +61,6 @@ #![feature(try_trait_v2_yeet)] #![feature(type_alias_impl_trait)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end #[cfg(test)] diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index fa5db32d9134..8e96d46dac27 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -8,7 +8,6 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // The `builder` module used to be named `build`, but that was causing GitHub's diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index a8a56baa1ffc..a0efc623b8e7 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -7,7 +7,6 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::ty; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 5df12ac4d8bc..30f2e6a86411 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -12,7 +12,6 @@ #![feature(never_type)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use hir::ConstContext; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 714b64b3a231..8f6914f3d724 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -4,7 +4,6 @@ #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(let_chains)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_hir::lang_items::LangItem; diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index d67ae2550d96..f6963a790675 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -6,7 +6,6 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_type_ir_inherent)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod canonicalizer; diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 1a104ff5e337..2edc8c83017d 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -12,7 +12,6 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(string_from_utf8_lossy_owned)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 3b985621b577..287bd8678da2 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -13,7 +13,6 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))) )] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub use Alignment::*; diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 1aa077ad2bb5..93ff0f66d695 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -12,7 +12,6 @@ #![feature(map_try_insert)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index a3400ebb7993..eeea724a29b4 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -6,7 +6,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(feature = "rustc", feature(let_chains))] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod constructor; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5271d03a6f61..5e3e8d69b603 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -6,7 +6,6 @@ #![feature(let_chains)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod errors; diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 73c205fdb17d..40da46a027df 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -8,7 +8,6 @@ #![feature(min_specialization)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_data_structures::stable_hasher::HashStable; diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index ee984095ad84..a546362414cf 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -6,7 +6,6 @@ #![feature(hash_raw_entry)] #![feature(let_chains)] #![feature(min_specialization)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod cache; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 4c5d4041022a..40e44f3ec737 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -20,7 +20,6 @@ #![feature(let_chains)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::{Cell, RefCell}; diff --git a/compiler/rustc_sanitizers/src/lib.rs b/compiler/rustc_sanitizers/src/lib.rs index 55be931bcd6d..e4792563e71e 100644 --- a/compiler/rustc_sanitizers/src/lib.rs +++ b/compiler/rustc_sanitizers/src/lib.rs @@ -5,7 +5,6 @@ // tidy-alphabetical-start #![feature(let_chains)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod cfi; diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 9e9b78cfdd57..13c1a273eb81 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -14,7 +14,6 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub use self::serialize::{Decodable, Decoder, Encodable, Encoder}; diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 112adde3740b..43657eaa8c4d 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -6,7 +6,6 @@ // To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums // with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers"). #![recursion_limit = "256"] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod errors; diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 2215e2f01ade..9f8888753061 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -15,7 +15,6 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod rustc_internal; diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 798e186a94b1..f19d4d9f3624 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -32,7 +32,6 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(slice_as_chunks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // The code produced by the `Encodable`/`Decodable` derive macros refer to diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 4312c82815c1..269401ef3a2d 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -93,7 +93,6 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_hir::def::DefKind; diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 7ebe96960ed0..a8d7da5692de 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -16,7 +16,6 @@ #![feature(let_chains)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index b235d0da83cc..b18fb0fb8fd3 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -31,7 +31,6 @@ #![feature(unwrap_infallible)] #![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc -#![warn(unreachable_pub)] // For rustdoc // tidy-alphabetical-end pub mod error_reporting; diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index d2f979bd6d9d..697c83918031 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -2,7 +2,6 @@ // tidy-alphabetical-start #![recursion_limit = "256"] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod codegen; diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 81a11f7cfb26..00928137d297 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![feature(never_type)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set}; diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 8be1611bb9ac..35cc6f398565 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -16,7 +16,6 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 15ef4e7d6c1d..e2dfd9173fab 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -6,7 +6,6 @@ feature(associated_type_defaults, never_type, rustc_attrs, negative_impls) )] #![cfg_attr(feature = "nightly", allow(internal_features))] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_type_ir; From f0dec714f3b6b6feaa5a0f40685e1e520636dff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 19 Feb 2025 16:47:28 +0000 Subject: [PATCH 830/991] Make some invalid codegen attr errors structured/translatable --- compiler/rustc_codegen_ssa/messages.ftl | 28 +++++ .../rustc_codegen_ssa/src/codegen_attrs.rs | 112 +++++------------- compiler/rustc_codegen_ssa/src/errors.rs | 104 ++++++++++++++++ .../patchable-function-entry-attribute.stderr | 2 +- 4 files changed, 161 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index f15d6fba5066..95912b016007 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -18,6 +18,8 @@ codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing codegen_ssa_autodiff_without_lto = using the autodiff feature requires using fat-lto +codegen_ssa_bare_instruction_set = `#[instruction_set]` requires an argument + codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty codegen_ssa_cgu_not_recorded = @@ -52,6 +54,10 @@ codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$err codegen_ssa_error_writing_def_file = Error writing .DEF file: {$error} +codegen_ssa_expected_name_value_pair = expected name value pair + +codegen_ssa_expected_one_argument = expected one argument + codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified @@ -88,9 +94,17 @@ codegen_ssa_incorrect_cgu_reuse_type = codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. +codegen_ssa_invalid_argument = invalid argument + .help = valid inline arguments are `always` and `never` + +codegen_ssa_invalid_instruction_set = invalid instruction set specified + codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]` .note = the attribute requires exactly one argument +codegen_ssa_invalid_literal_value = invalid literal value + .label = value must be an integer between `0` and `255` + codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}` codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}` @@ -217,6 +231,8 @@ codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions +codegen_ssa_multiple_instruction_set = cannot specify more than one instruction set + codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times .help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point @@ -229,6 +245,11 @@ codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error} codegen_ssa_no_saved_object_file = cached cgu {$cgu_name} should have an object file, but doesn't +codegen_ssa_null_on_export = `export_name` may not contain null characters + +codegen_ssa_out_of_range_integer = integer value out of range + .label = value must be between `0` and `255` + codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status} .note = {$output} @@ -236,6 +257,8 @@ codegen_ssa_read_file = failed to read file: {$message} codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer +codegen_ssa_requires_rust_abi = `#[track_caller]` requires Rust ABI + codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib at `{$path}`: {$error} codegen_ssa_rlib_incompatible_dependency_formats = `{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`) @@ -356,6 +379,9 @@ codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error} codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visualizer file `{$path}`: {$error} +codegen_ssa_unexpected_parameter_name = unexpected parameter name + .label = expected `{$prefix_nops}` or `{$entry_nops}` + codegen_ssa_unknown_archive_kind = Don't know how to build archive of type: {$kind} @@ -367,6 +393,8 @@ codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}` +codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]` + codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 673740b4aab9..90c53c347689 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -8,8 +8,6 @@ use rustc_ast::{MetaItem, MetaItemInner, attr}; use rustc_attr_parsing::ReprAttr::ReprAlign; use rustc_attr_parsing::{AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::codes::*; -use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS; @@ -236,13 +234,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { && let Some(fn_sig) = fn_sig() && fn_sig.skip_binder().abi() != ExternAbi::Rust { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0737, - "`#[track_caller]` requires Rust ABI" - ) - .emit(); + tcx.dcx().emit_err(errors::RequiresRustAbi { span: attr.span() }); } if is_closure && !tcx.features().closure_track_caller() @@ -263,13 +255,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if s.as_str().contains('\0') { // `#[export_name = ...]` will be converted to a null-terminated string, // so it may not contain any null characters. - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0648, - "`export_name` may not contain null characters" - ) - .emit(); + tcx.dcx().emit_err(errors::NullOnExport { span: attr.span() }); } codegen_fn_attrs.export_name = Some(s); mixed_export_name_no_mangle_lint_state.track_export_name(attr.span()); @@ -394,47 +380,28 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { [sym::arm, sym::a32 | sym::t32] if !tcx.sess.target.has_thumb_interworking => { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0779, - "target does not support `#[instruction_set]`" - ) - .emit(); + tcx.dcx().emit_err(errors::UnsuportedInstructionSet { + span: attr.span(), + }); None } [sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32), [sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32), _ => { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0779, - "invalid instruction set specified", - ) - .emit(); + tcx.dcx().emit_err(errors::InvalidInstructionSet { + span: attr.span(), + }); None } } } [] => { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0778, - "`#[instruction_set]` requires an argument" - ) - .emit(); + tcx.dcx().emit_err(errors::BareInstructionSet { span: attr.span() }); None } _ => { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0779, - "cannot specify more than one instruction set" - ) - .emit(); + tcx.dcx() + .emit_err(errors::MultipleInstructionSet { span: attr.span() }); None } }) @@ -445,58 +412,38 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { let mut entry = None; for item in l { let Some(meta_item) = item.meta_item() else { - tcx.dcx().span_err(item.span(), "expected name value pair"); + tcx.dcx().emit_err(errors::ExpectedNameValuePair { span: item.span() }); continue; }; let Some(name_value_lit) = meta_item.name_value_literal() else { - tcx.dcx().span_err(item.span(), "expected name value pair"); + tcx.dcx().emit_err(errors::ExpectedNameValuePair { span: item.span() }); continue; }; - fn emit_error_with_label( - tcx: TyCtxt<'_>, - span: Span, - error: impl Into, - label: impl Into, - ) { - let mut err: rustc_errors::Diag<'_, _> = - tcx.dcx().struct_span_err(span, error); - err.span_label(span, label); - err.emit(); - } - let attrib_to_write = match meta_item.name_or_empty() { sym::prefix_nops => &mut prefix, sym::entry_nops => &mut entry, _ => { - emit_error_with_label( - tcx, - item.span(), - "unexpected parameter name", - format!("expected {} or {}", sym::prefix_nops, sym::entry_nops), - ); + tcx.dcx().emit_err(errors::UnexpectedParameterName { + span: item.span(), + prefix_nops: sym::prefix_nops, + entry_nops: sym::entry_nops, + }); continue; } }; let rustc_ast::LitKind::Int(val, _) = name_value_lit.kind else { - emit_error_with_label( - tcx, - name_value_lit.span, - "invalid literal value", - "value must be an integer between `0` and `255`", - ); + tcx.dcx().emit_err(errors::InvalidLiteralValue { + span: name_value_lit.span, + }); continue; }; let Ok(val) = val.get().try_into() else { - emit_error_with_label( - tcx, - name_value_lit.span, - "integer value out of range", - "value must be between `0` and `255`", - ); + tcx.dcx() + .emit_err(errors::OutOfRangeInteger { span: name_value_lit.span }); continue; }; @@ -533,7 +480,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { inline_span = Some(attr.span()); let [item] = &items[..] else { - struct_span_code_err!(tcx.dcx(), attr.span(), E0534, "expected one argument").emit(); + tcx.dcx().emit_err(errors::ExpectedOneArgument { span: attr.span() }); return InlineAttr::None; }; @@ -542,9 +489,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } else if item.has_name(sym::never) { InlineAttr::Never } else { - struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") - .with_help("valid inline arguments are `always` and `never`") - .emit(); + tcx.dcx().emit_err(errors::InvalidArgument { span: items[0].span() }); InlineAttr::None } @@ -575,9 +520,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if !attr.has_name(sym::optimize) { return ia; } - let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit(); if attr.is_word() { - err(attr.span(), "expected one argument"); + tcx.dcx().emit_err(errors::ExpectedOneArgumentOptimize { span: attr.span() }); return ia; } let Some(ref items) = attr.meta_item_list() else { @@ -586,7 +530,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { inline_span = Some(attr.span()); let [item] = &items[..] else { - err(attr.span(), "expected one argument"); + tcx.dcx().emit_err(errors::ExpectedOneArgumentOptimize { span: attr.span() }); return OptimizeAttr::Default; }; if item.has_name(sym::size) { @@ -596,7 +540,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } else if item.has_name(sym::none) { OptimizeAttr::DoNotOptimize } else { - err(item.span(), "invalid argument"); + tcx.dcx().emit_err(errors::InvalidArgumentOptimize { span: item.span() }); OptimizeAttr::Default } }); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index ccf6d12977f6..394c80fcfbdc 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -135,6 +135,110 @@ pub(crate) struct NoSavedObjectFile<'a> { pub cgu_name: &'a str, } +#[derive(Diagnostic)] +#[diag(codegen_ssa_requires_rust_abi, code = E0737)] +pub(crate) struct RequiresRustAbi { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_null_on_export, code = E0648)] +pub(crate) struct NullOnExport { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unsupported_instruction_set, code = E0779)] +pub(crate) struct UnsuportedInstructionSet { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_invalid_instruction_set, code = E0779)] +pub(crate) struct InvalidInstructionSet { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_bare_instruction_set, code = E0778)] +pub(crate) struct BareInstructionSet { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_multiple_instruction_set, code = E0779)] +pub(crate) struct MultipleInstructionSet { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_expected_name_value_pair)] +pub(crate) struct ExpectedNameValuePair { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unexpected_parameter_name)] +pub(crate) struct UnexpectedParameterName { + #[primary_span] + #[label] + pub span: Span, + pub prefix_nops: Symbol, + pub entry_nops: Symbol, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_invalid_literal_value)] +pub(crate) struct InvalidLiteralValue { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_out_of_range_integer)] +pub(crate) struct OutOfRangeInteger { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_expected_one_argument, code = E0534)] +pub(crate) struct ExpectedOneArgument { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_expected_one_argument, code = E0722)] +pub(crate) struct ExpectedOneArgumentOptimize { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_invalid_argument, code = E0535)] +#[help] +pub(crate) struct InvalidArgument { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_invalid_argument, code = E0722)] +pub(crate) struct InvalidArgumentOptimize { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(codegen_ssa_copy_path_buf)] pub(crate) struct CopyPathBuf { diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr index d9710c6e6a2f..9357a86c4153 100644 --- a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr +++ b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr @@ -20,7 +20,7 @@ error: unexpected parameter name --> $DIR/patchable-function-entry-attribute.rs:13:46 | LL | #[patchable_function_entry(prefix_nops = 10, something = 0)] - | ^^^^^^^^^^^^^ expected prefix_nops or entry_nops + | ^^^^^^^^^^^^^ expected `prefix_nops` or `entry_nops` error: must specify at least one parameter --> $DIR/patchable-function-entry-attribute.rs:16:1 From 9dfccc5e640511a93a4e2661c5c328c76b678784 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 7 Mar 2025 21:45:43 -0500 Subject: [PATCH 831/991] Update cargo --- src/tools/cargo | 2 +- src/tools/tidy/src/deps.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/cargo b/src/tools/cargo index 2622e844bc1e..ab1463d63252 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 2622e844bc1e2e6123e54e94e4706f7b6195ce3d +Subproject commit ab1463d632528e39daf35f263e10c14cbe590ce8 diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 51e58b4e4fcf..f0e0c317e7bd 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -123,7 +123,6 @@ const EXCEPTIONS_CARGO: ExceptionList = &[ ("arrayref", "BSD-2-Clause"), ("bitmaps", "MPL-2.0+"), ("blake3", "CC0-1.0 OR Apache-2.0 OR Apache-2.0 WITH LLVM-exception"), - ("bytesize", "Apache-2.0"), ("ciborium", "Apache-2.0"), ("ciborium-io", "Apache-2.0"), ("ciborium-ll", "Apache-2.0"), From 8042e0029103573fc8e4013bc7dd2fe66699bad2 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 8 Mar 2025 08:14:47 +0300 Subject: [PATCH 832/991] handle precompiled compiler more properly Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 10 ++++---- src/bootstrap/src/core/build_steps/tool.rs | 24 ++++++++++--------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 26c5c2bf411b..319a2233b1c7 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1991,12 +1991,12 @@ impl Step for Assemble { } } - let maybe_install_llvm_bitcode_linker = || { + let maybe_install_llvm_bitcode_linker = |compiler| { if builder.config.llvm_bitcode_linker_enabled { trace!("llvm-bitcode-linker enabled, installing"); let llvm_bitcode_linker = builder.ensure(crate::core::build_steps::tool::LlvmBitcodeLinker { - compiler: target_compiler, + compiler, target: target_compiler.host, extra_features: vec![], }); @@ -2020,7 +2020,9 @@ impl Step for Assemble { builder.info(&format!("Creating a sysroot for stage{stage} compiler (use `rustup toolchain link 'name' build/host/stage{stage}`)", stage=target_compiler.stage)); } - maybe_install_llvm_bitcode_linker(); + let mut precompiled_compiler = target_compiler; + precompiled_compiler.forced_compiler(true); + maybe_install_llvm_bitcode_linker(precompiled_compiler); return target_compiler; } @@ -2203,7 +2205,7 @@ impl Step for Assemble { ); } - maybe_install_llvm_bitcode_linker(); + maybe_install_llvm_bitcode_linker(target_compiler); // Ensure that `libLLVM.so` ends up in the newly build compiler directory, // so that it can be found when the newly built `rustc` is run. diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 65633c9ea7c2..704feac54dec 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -319,18 +319,20 @@ pub(crate) fn get_tool_rustc_compiler( builder: &Builder<'_>, target_compiler: Compiler, ) -> Compiler { - if builder.download_rustc() && target_compiler.stage == 1 { - // We already have the stage 1 compiler, we don't need to cut the stage. - builder.compiler(target_compiler.stage, builder.config.build) - } else if target_compiler.is_forced_compiler() { - target_compiler - } else { - // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise - // we'd have stageN/bin/rustc and stageN/bin/$rustc_tool be effectively different stage - // compilers, which isn't what we want. Rustc tools should be linked in the same way as the - // compiler it's paired with, so it must be built with the previous stage compiler. - builder.compiler(target_compiler.stage.saturating_sub(1), builder.config.build) + if target_compiler.is_forced_compiler() { + return target_compiler; } + + if builder.download_rustc() && target_compiler.stage > 0 { + // We already have the stage N compiler, we don't need to cut the stage. + return builder.compiler(target_compiler.stage, builder.config.build); + } + + // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise + // we'd have stageN/bin/rustc and stageN/bin/$rustc_tool be effectively different stage + // compilers, which isn't what we want. Rustc tools should be linked in the same way as the + // compiler it's paired with, so it must be built with the previous stage compiler. + builder.compiler(target_compiler.stage.saturating_sub(1), builder.config.build) } /// Links a built tool binary with the given `name` from the build directory to the From dd8d1b4afac8c24a086054f78708f49ff0174c8a Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 8 Mar 2025 08:39:41 +0300 Subject: [PATCH 833/991] update doc-comment for `forced_compiler` Signed-off-by: onur-ozkan --- src/bootstrap/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 788c8bbdc840..994ccabf0eb3 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -96,7 +96,7 @@ const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ pub struct Compiler { stage: u32, host: TargetSelection, - /// Indicates whether `compiler_for` was used to force a specific compiler stage. + /// Indicates whether the compiler was forced to use a specific stage. /// This field is ignored in `Hash` and `PartialEq` implementations as only the `stage` /// and `host` fields are relevant for those. forced_compiler: bool, @@ -1998,7 +1998,7 @@ impl Compiler { self.stage == 0 && self.host == build.build } - /// Indicates whether `compiler_for` was used to force a specific compiler stage. + /// Indicates whether the compiler was forced to use a specific stage. pub fn is_forced_compiler(&self) -> bool { self.forced_compiler } From f83af2aa6b395c2e6c5639e8536f08f24d3f2128 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 8 Mar 2025 18:11:47 +1100 Subject: [PATCH 834/991] bootstrap: Fix stack printing when a step cycle is detected --- src/bootstrap/src/core/build_steps/run.rs | 25 +++++++++++++++++ src/bootstrap/src/core/builder/mod.rs | 18 +++++++++++- src/bootstrap/src/core/builder/tests.rs | 34 ++++++++++++++++++++++- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index fea8232296ec..1ef86e674f09 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -367,3 +367,28 @@ impl Step for FeaturesStatusDump { cmd.run(builder); } } + +/// Dummy step that can be used to deliberately trigger bootstrap's step cycle +/// detector, for automated and manual testing. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct CyclicStep { + n: u32, +} + +impl Step for CyclicStep { + type Output = (); + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("cyclic-step") + } + + fn make_run(run: RunConfig<'_>) { + // Start with n=2, so that we build up a few stack entries before panicking. + run.builder.ensure(CyclicStep { n: 2 }) + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + // When n=0, the step will try to ensure itself, causing a step cycle. + builder.ensure(CyclicStep { n: self.n.saturating_sub(1) }) + } +} diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 801894e9ff1b..2c4b3a5928b6 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -50,7 +50,7 @@ pub struct Builder<'a> { /// A stack of [`Step`]s to run before we can run this builder. The output /// of steps is cached in [`Self::cache`]. - stack: RefCell>>, + stack: RefCell>>, /// The total amount of time we spent running [`Step`]s in [`Self::stack`]. time_spent_on_dependencies: Cell, @@ -69,6 +69,21 @@ impl Deref for Builder<'_> { } } +/// This trait is similar to `Any`, except that it also exposes the underlying +/// type's [`Debug`] implementation. +/// +/// (Trying to debug-print `dyn Any` results in the unhelpful `"Any { .. }"`.) +trait AnyDebug: Any + Debug {} +impl AnyDebug for T {} +impl dyn AnyDebug { + /// Equivalent to `::downcast_ref`. + fn downcast_ref(&self) -> Option<&T> { + (self as &dyn Any).downcast_ref() + } + + // Feel free to add other `dyn Any` methods as necessary. +} + pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash { /// Result type of `Step::run`. type Output: Clone; @@ -1101,6 +1116,7 @@ impl<'a> Builder<'a> { run::GenerateCompletions, run::UnicodeTableGenerator, run::FeaturesStatusDump, + run::CyclicStep, ), Kind::Setup => { describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 63a1bbc24f16..e8820e3a8288 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1,4 +1,4 @@ -use std::thread; +use std::{panic, thread}; use llvm::prebuilt_llvm_config; @@ -1135,3 +1135,35 @@ fn test_get_tool_rustc_compiler() { let actual = tool::get_tool_rustc_compiler(&builder, compiler); assert_eq!(expected, actual); } + +/// When bootstrap detects a step dependency cycle (which is a bug), its panic +/// message should show the actual steps on the stack, not just several copies +/// of `Any { .. }`. +#[test] +fn step_cycle_debug() { + let cmd = ["run", "cyclic-step"].map(str::to_owned); + let config = configure_with_args(&cmd, &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]); + + let err = panic::catch_unwind(|| run_build(&config.paths.clone(), config)).unwrap_err(); + let err = err.downcast_ref::().unwrap().as_str(); + + assert!(!err.contains("Any")); + assert!(err.contains("CyclicStep { n: 1 }")); +} + +/// The `AnyDebug` trait should delegate to the underlying type's `Debug`, and +/// should also allow downcasting as expected. +#[test] +fn any_debug() { + #[derive(Debug, PartialEq, Eq)] + struct MyStruct { + x: u32, + } + + let x: &dyn AnyDebug = &MyStruct { x: 7 }; + + // Debug-formatting should delegate to the underlying type. + assert_eq!(format!("{x:?}"), format!("{:?}", MyStruct { x: 7 })); + // Downcasting to the underlying type should succeed. + assert_eq!(x.downcast_ref::(), Some(&MyStruct { x: 7 })); +} From 99171735753883fb8dfde343e9c0e8f0e509bbef Mon Sep 17 00:00:00 2001 From: Moulins Date: Fri, 28 Feb 2025 04:57:17 +0100 Subject: [PATCH 835/991] Remove most manual LayoutData creations and move them to `rustc_abi` ...either as: - methods on LayoutCalculator, for faillible operations; - constructors on LayoutData, for infaillible ones. --- compiler/rustc_abi/src/layout.rs | 75 +++------ compiler/rustc_abi/src/layout/simple.rs | 148 ++++++++++++++++++ compiler/rustc_abi/src/lib.rs | 42 ----- compiler/rustc_middle/src/ty/layout.rs | 40 ++--- compiler/rustc_ty_utils/src/layout.rs | 92 +++-------- .../rust-analyzer/crates/hir-ty/src/layout.rs | 98 +++--------- 6 files changed, 228 insertions(+), 267 deletions(-) create mode 100644 compiler/rustc_abi/src/layout/simple.rs diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index d3ae6a29f10f..42ecbce8117c 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -12,6 +12,8 @@ use crate::{ Variants, WrappingRange, }; +mod simple; + #[cfg(feature = "nightly")] mod ty; @@ -102,41 +104,27 @@ impl LayoutCalculator { Self { cx } } - pub fn scalar_pair( + pub fn array_like( &self, - a: Scalar, - b: Scalar, - ) -> LayoutData { - let dl = self.cx.data_layout(); - let b_align = b.align(dl); - let align = a.align(dl).max(b_align).max(dl.aggregate_align); - let b_offset = a.size(dl).align_to(b_align.abi); - let size = (b_offset + b.size(dl)).align_to(align.abi); + element: &LayoutData, + count_if_sized: Option, // None for slices + ) -> LayoutCalculatorResult { + let count = count_if_sized.unwrap_or(0); + let size = + element.size.checked_mul(count, &self.cx).ok_or(LayoutCalculatorError::SizeOverflow)?; - // HACK(nox): We iter on `b` and then `a` because `max_by_key` - // returns the last maximum. - let largest_niche = Niche::from_scalar(dl, b_offset, b) - .into_iter() - .chain(Niche::from_scalar(dl, Size::ZERO, a)) - .max_by_key(|niche| niche.available(dl)); - - let combined_seed = a.size(&self.cx).bytes().wrapping_add(b.size(&self.cx).bytes()); - - LayoutData { + Ok(LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Arbitrary { - offsets: [Size::ZERO, b_offset].into(), - memory_index: [0, 1].into(), - }, - backend_repr: BackendRepr::ScalarPair(a, b), - largest_niche, - uninhabited: false, - align, + fields: FieldsShape::Array { stride: element.size, count }, + backend_repr: BackendRepr::Memory { sized: count_if_sized.is_some() }, + largest_niche: element.largest_niche.filter(|_| count != 0), + uninhabited: element.uninhabited && count != 0, + align: element.align, size, max_repr_align: None, - unadjusted_abi_align: align.abi, - randomization_seed: Hash64::new(combined_seed), - } + unadjusted_abi_align: element.align.abi, + randomization_seed: element.randomization_seed.wrapping_add(Hash64::new(count)), + }) } pub fn univariant< @@ -214,25 +202,6 @@ impl LayoutCalculator { layout } - pub fn layout_of_never_type( - &self, - ) -> LayoutData { - let dl = self.cx.data_layout(); - // This is also used for uninhabited enums, so we use `Variants::Empty`. - LayoutData { - variants: Variants::Empty, - fields: FieldsShape::Primitive, - backend_repr: BackendRepr::Memory { sized: true }, - largest_niche: None, - uninhabited: true, - align: dl.i8_align, - size: Size::ZERO, - max_repr_align: None, - unadjusted_abi_align: dl.i8_align.abi, - randomization_seed: Hash64::ZERO, - } - } - pub fn layout_of_struct_or_enum< 'a, FieldIdx: Idx, @@ -260,7 +229,7 @@ impl LayoutCalculator { Some(present_first) => present_first, // Uninhabited because it has no variants, or only absent ones. None if is_enum => { - return Ok(self.layout_of_never_type()); + return Ok(LayoutData::never_type(&self.cx)); } // If it's a struct, still compute a layout so that we can still compute the // field offsets. @@ -949,7 +918,8 @@ impl LayoutCalculator { // Common prim might be uninit. Scalar::Union { value: prim } }; - let pair = self.scalar_pair::(tag, prim_scalar); + let pair = + LayoutData::::scalar_pair(&self.cx, tag, prim_scalar); let pair_offsets = match pair.fields { FieldsShape::Arbitrary { ref offsets, ref memory_index } => { assert_eq!(memory_index.raw, [0, 1]); @@ -1341,7 +1311,8 @@ impl LayoutCalculator { } else { ((j, b), (i, a)) }; - let pair = self.scalar_pair::(a, b); + let pair = + LayoutData::::scalar_pair(&self.cx, a, b); let pair_offsets = match pair.fields { FieldsShape::Arbitrary { ref offsets, ref memory_index } => { assert_eq!(memory_index.raw, [0, 1]); diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs new file mode 100644 index 000000000000..0d0706defc2e --- /dev/null +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -0,0 +1,148 @@ +use std::num::NonZero; + +use rustc_hashes::Hash64; +use rustc_index::{Idx, IndexVec}; + +use crate::{ + BackendRepr, FieldsShape, HasDataLayout, LayoutData, Niche, Primitive, Scalar, Size, Variants, +}; + +/// "Simple" layout constructors that cannot fail. +impl LayoutData { + pub fn unit(cx: &C, sized: bool) -> Self { + let dl = cx.data_layout(); + LayoutData { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Arbitrary { + offsets: IndexVec::new(), + memory_index: IndexVec::new(), + }, + backend_repr: BackendRepr::Memory { sized }, + largest_niche: None, + uninhabited: false, + align: dl.i8_align, + size: Size::ZERO, + max_repr_align: None, + unadjusted_abi_align: dl.i8_align.abi, + randomization_seed: Hash64::new(0), + } + } + + pub fn never_type(cx: &C) -> Self { + let dl = cx.data_layout(); + // This is also used for uninhabited enums, so we use `Variants::Empty`. + LayoutData { + variants: Variants::Empty, + fields: FieldsShape::Primitive, + backend_repr: BackendRepr::Memory { sized: true }, + largest_niche: None, + uninhabited: true, + align: dl.i8_align, + size: Size::ZERO, + max_repr_align: None, + unadjusted_abi_align: dl.i8_align.abi, + randomization_seed: Hash64::ZERO, + } + } + + pub fn scalar(cx: &C, scalar: Scalar) -> Self { + let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar); + let size = scalar.size(cx); + let align = scalar.align(cx); + + let range = scalar.valid_range(cx); + + // All primitive types for which we don't have subtype coercions should get a distinct seed, + // so that types wrapping them can use randomization to arrive at distinct layouts. + // + // Some type information is already lost at this point, so as an approximation we derive + // the seed from what remains. For example on 64-bit targets usize and u64 can no longer + // be distinguished. + let randomization_seed = size + .bytes() + .wrapping_add( + match scalar.primitive() { + Primitive::Int(_, true) => 1, + Primitive::Int(_, false) => 2, + Primitive::Float(_) => 3, + Primitive::Pointer(_) => 4, + } << 32, + ) + // distinguishes references from pointers + .wrapping_add((range.start as u64).rotate_right(16)) + // distinguishes char from u32 and bool from u8 + .wrapping_add((range.end as u64).rotate_right(16)); + + LayoutData { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Primitive, + backend_repr: BackendRepr::Scalar(scalar), + largest_niche, + uninhabited: false, + size, + align, + max_repr_align: None, + unadjusted_abi_align: align.abi, + randomization_seed: Hash64::new(randomization_seed), + } + } + + pub fn scalar_pair(cx: &C, a: Scalar, b: Scalar) -> Self { + let dl = cx.data_layout(); + let b_align = b.align(dl); + let align = a.align(dl).max(b_align).max(dl.aggregate_align); + let b_offset = a.size(dl).align_to(b_align.abi); + let size = (b_offset + b.size(dl)).align_to(align.abi); + + // HACK(nox): We iter on `b` and then `a` because `max_by_key` + // returns the last maximum. + let largest_niche = Niche::from_scalar(dl, b_offset, b) + .into_iter() + .chain(Niche::from_scalar(dl, Size::ZERO, a)) + .max_by_key(|niche| niche.available(dl)); + + let combined_seed = a.size(dl).bytes().wrapping_add(b.size(dl).bytes()); + + LayoutData { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Arbitrary { + offsets: [Size::ZERO, b_offset].into(), + memory_index: [0, 1].into(), + }, + backend_repr: BackendRepr::ScalarPair(a, b), + largest_niche, + uninhabited: false, + align, + size, + max_repr_align: None, + unadjusted_abi_align: align.abi, + randomization_seed: Hash64::new(combined_seed), + } + } + + /// Returns a dummy layout for an uninhabited variant. + /// + /// Uninhabited variants get pruned as part of the layout calculation, + /// so this can be used after the fact to reconstitute a layout. + pub fn uninhabited_variant(cx: &C, index: VariantIdx, fields: usize) -> Self { + let dl = cx.data_layout(); + LayoutData { + variants: Variants::Single { index }, + fields: match NonZero::new(fields) { + Some(fields) => FieldsShape::Union(fields), + None => FieldsShape::Arbitrary { + offsets: IndexVec::new(), + memory_index: IndexVec::new(), + }, + }, + backend_repr: BackendRepr::Memory { sized: true }, + largest_niche: None, + uninhabited: true, + align: dl.i8_align, + size: Size::ZERO, + max_repr_align: None, + unadjusted_abi_align: dl.i8_align.abi, + randomization_seed: Hash64::ZERO, + } + } +} diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index a59dc870aa33..db9a26c3ef7f 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1744,48 +1744,6 @@ impl LayoutData { pub fn is_uninhabited(&self) -> bool { self.uninhabited } - - pub fn scalar(cx: &C, scalar: Scalar) -> Self { - let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar); - let size = scalar.size(cx); - let align = scalar.align(cx); - - let range = scalar.valid_range(cx); - - // All primitive types for which we don't have subtype coercions should get a distinct seed, - // so that types wrapping them can use randomization to arrive at distinct layouts. - // - // Some type information is already lost at this point, so as an approximation we derive - // the seed from what remains. For example on 64-bit targets usize and u64 can no longer - // be distinguished. - let randomization_seed = size - .bytes() - .wrapping_add( - match scalar.primitive() { - Primitive::Int(_, true) => 1, - Primitive::Int(_, false) => 2, - Primitive::Float(_) => 3, - Primitive::Pointer(_) => 4, - } << 32, - ) - // distinguishes references from pointers - .wrapping_add((range.start as u64).rotate_right(16)) - // distinguishes char from u32 and bool from u8 - .wrapping_add((range.end as u64).rotate_right(16)); - - LayoutData { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Primitive, - backend_repr: BackendRepr::Scalar(scalar), - largest_niche, - uninhabited: false, - size, - align, - max_repr_align: None, - unadjusted_abi_align: align.abi, - randomization_seed: Hash64::new(randomization_seed), - } - } } impl fmt::Debug for LayoutData diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 272bb0cc915f..d32c524a427c 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1,20 +1,17 @@ -use std::num::NonZero; use std::ops::Bound; use std::{cmp, fmt}; use rustc_abi::{ - AddressSpace, Align, BackendRepr, ExternAbi, FieldIdx, FieldsShape, HasDataLayout, LayoutData, - PointeeInfo, PointerKind, Primitive, ReprOptions, Scalar, Size, TagEncoding, TargetDataLayout, + AddressSpace, Align, ExternAbi, FieldIdx, FieldsShape, HasDataLayout, LayoutData, PointeeInfo, + PointerKind, Primitive, ReprOptions, Scalar, Size, TagEncoding, TargetDataLayout, TyAbiInterface, VariantIdx, Variants, }; use rustc_error_messages::DiagMessage; use rustc_errors::{ Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, }; -use rustc_hashes::Hash64; use rustc_hir::LangItem; use rustc_hir::def_id::DefId; -use rustc_index::IndexVec; use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension}; use rustc_session::config::OptLevel; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; @@ -762,11 +759,9 @@ where variant_index: VariantIdx, ) -> TyAndLayout<'tcx> { let layout = match this.variants { - Variants::Single { index } - // If all variants but one are uninhabited, the variant layout is the enum layout. - if index == variant_index => - { - this.layout + // If all variants but one are uninhabited, the variant layout is the enum layout. + Variants::Single { index } if index == variant_index => { + return this; } Variants::Single { .. } | Variants::Empty => { @@ -783,29 +778,18 @@ where } let fields = match this.ty.kind() { - ty::Adt(def, _) if def.variants().is_empty() => - bug!("for_variant called on zero-variant enum {}", this.ty), + ty::Adt(def, _) if def.variants().is_empty() => { + bug!("for_variant called on zero-variant enum {}", this.ty) + } ty::Adt(def, _) => def.variant(variant_index).fields.len(), _ => bug!("`ty_and_layout_for_variant` on unexpected type {}", this.ty), }; - tcx.mk_layout(LayoutData { - variants: Variants::Single { index: variant_index }, - fields: match NonZero::new(fields) { - Some(fields) => FieldsShape::Union(fields), - None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() }, - }, - backend_repr: BackendRepr::Memory { sized: true }, - largest_niche: None, - uninhabited: true, - align: tcx.data_layout.i8_align, - size: Size::ZERO, - max_repr_align: None, - unadjusted_abi_align: tcx.data_layout.i8_align.abi, - randomization_seed: Hash64::ZERO, - }) + tcx.mk_layout(LayoutData::uninhabited_variant(cx, variant_index, fields)) } - Variants::Multiple { ref variants, .. } => cx.tcx().mk_layout(variants[variant_index].clone()), + Variants::Multiple { ref variants, .. } => { + cx.tcx().mk_layout(variants[variant_index].clone()) + } }; assert_eq!(*layout.variants(), Variants::Single { index: variant_index }); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index a53f0538c581..45c2639280f3 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -188,6 +188,10 @@ fn layout_of_uncached<'tcx>( let tcx = cx.tcx(); let dl = cx.data_layout(); + let map_layout = |result: Result<_, _>| match result { + Ok(layout) => Ok(tcx.mk_layout(layout)), + Err(err) => Err(map_error(cx, ty, err)), + }; let scalar_unit = |value: Primitive| { let size = value.size(dl); assert!(size.bits() <= 128); @@ -258,7 +262,7 @@ fn layout_of_uncached<'tcx>( } // The never type. - ty::Never => tcx.mk_layout(cx.calc.layout_of_never_type()), + ty::Never => tcx.mk_layout(LayoutData::never_type(cx)), // Potentially-wide pointers. ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => { @@ -329,7 +333,7 @@ fn layout_of_uncached<'tcx>( }; // Effectively a (ptr, meta) tuple. - tcx.mk_layout(cx.calc.scalar_pair(data_ptr, metadata)) + tcx.mk_layout(LayoutData::scalar_pair(cx, data_ptr, metadata)) } ty::Dynamic(_, _, ty::DynStar) => { @@ -337,7 +341,7 @@ fn layout_of_uncached<'tcx>( data.valid_range_mut().start = 0; let mut vtable = scalar_unit(Pointer(AddressSpace::DATA)); vtable.valid_range_mut().start = 1; - tcx.mk_layout(cx.calc.scalar_pair(data, vtable)) + tcx.mk_layout(LayoutData::scalar_pair(cx, data, vtable)) } // Arrays and slices. @@ -347,71 +351,29 @@ fn layout_of_uncached<'tcx>( .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; let element = cx.layout_of(element)?; - let size = element - .size - .checked_mul(count, dl) - .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?; - - let abi = BackendRepr::Memory { sized: true }; - - let largest_niche = if count != 0 { element.largest_niche } else { None }; - let uninhabited = if count != 0 { element.uninhabited } else { false }; - - tcx.mk_layout(LayoutData { - variants: Variants::Single { index: FIRST_VARIANT }, - fields: FieldsShape::Array { stride: element.size, count }, - backend_repr: abi, - largest_niche, - uninhabited, - align: element.align, - size, - max_repr_align: None, - unadjusted_abi_align: element.align.abi, - randomization_seed: element.randomization_seed.wrapping_add(Hash64::new(count)), - }) + map_layout(cx.calc.array_like(&element, Some(count)))? } ty::Slice(element) => { let element = cx.layout_of(element)?; - tcx.mk_layout(LayoutData { - variants: Variants::Single { index: FIRST_VARIANT }, - fields: FieldsShape::Array { stride: element.size, count: 0 }, - backend_repr: BackendRepr::Memory { sized: false }, - largest_niche: None, - uninhabited: false, - align: element.align, - size: Size::ZERO, - max_repr_align: None, - unadjusted_abi_align: element.align.abi, - // adding a randomly chosen value to distinguish slices - randomization_seed: element - .randomization_seed - .wrapping_add(Hash64::new(0x2dcba99c39784102)), - }) + map_layout(cx.calc.array_like(&element, None).map(|mut layout| { + // a randomly chosen value to distinguish slices + layout.randomization_seed = Hash64::new(0x2dcba99c39784102); + layout + }))? + } + ty::Str => { + let element = scalar(Int(I8, false)); + map_layout(cx.calc.array_like(&element, None).map(|mut layout| { + // another random value + layout.randomization_seed = Hash64::new(0xc1325f37d127be22); + layout + }))? } - ty::Str => tcx.mk_layout(LayoutData { - variants: Variants::Single { index: FIRST_VARIANT }, - fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, - backend_repr: BackendRepr::Memory { sized: false }, - largest_niche: None, - uninhabited: false, - align: dl.i8_align, - size: Size::ZERO, - max_repr_align: None, - unadjusted_abi_align: dl.i8_align.abi, - // another random value - randomization_seed: Hash64::new(0xc1325f37d127be22), - }), // Odd unit types. - ty::FnDef(..) => univariant(IndexSlice::empty(), StructKind::AlwaysSized)?, - ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => { - let mut unit = - univariant_uninterned(cx, ty, IndexSlice::empty(), StructKind::AlwaysSized)?; - match unit.backend_repr { - BackendRepr::Memory { ref mut sized } => *sized = false, - _ => bug!(), - } - tcx.mk_layout(unit) + ty::FnDef(..) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => { + let sized = matches!(ty.kind(), ty::FnDef(..)); + tcx.mk_layout(LayoutData::unit(cx, sized)) } ty::Coroutine(def_id, args) => coroutine_layout(cx, ty, def_id, args)?, @@ -545,11 +507,7 @@ fn layout_of_uncached<'tcx>( return Err(error(cx, LayoutError::ReferencesError(guar))); } - return Ok(tcx.mk_layout( - cx.calc - .layout_of_union(&def.repr(), &variants) - .map_err(|err| map_error(cx, ty, err))?, - )); + return map_layout(cx.calc.layout_of_union(&def.repr(), &variants)); } let get_discriminant_type = diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 7af31dabe45b..05f38cd09e22 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -15,7 +15,7 @@ use hir_def::{ use la_arena::{Idx, RawIdx}; use rustc_abi::AddressSpace; use rustc_hashes::Hash64; -use rustc_index::{IndexSlice, IndexVec}; +use rustc_index::IndexVec; use triomphe::Arc; @@ -190,7 +190,8 @@ pub fn layout_of_ty_query( let dl = &*target; let cx = LayoutCx::new(dl); let ty = normalize(db, trait_env.clone(), ty); - let result = match ty.kind(Interner) { + let kind = ty.kind(Interner); + let result = match kind { TyKind::Adt(AdtId(def), subst) => { if let hir_def::AdtId::StructId(s) = def { let data = db.struct_data(*s); @@ -216,7 +217,7 @@ pub fn layout_of_ty_query( valid_range: WrappingRange { start: 0, end: 0x10FFFF }, }, ), - chalk_ir::Scalar::Int(i) => scalar( + chalk_ir::Scalar::Int(i) => Layout::scalar(dl, scalar_unit( dl, Primitive::Int( match i { @@ -229,8 +230,8 @@ pub fn layout_of_ty_query( }, true, ), - ), - chalk_ir::Scalar::Uint(i) => scalar( + )), + chalk_ir::Scalar::Uint(i) => Layout::scalar(dl, scalar_unit( dl, Primitive::Int( match i { @@ -243,8 +244,8 @@ pub fn layout_of_ty_query( }, false, ), - ), - chalk_ir::Scalar::Float(f) => scalar( + )), + chalk_ir::Scalar::Float(f) => Layout::scalar(dl, scalar_unit( dl, Primitive::Float(match f { FloatTy::F16 => Float::F16, @@ -252,7 +253,7 @@ pub fn layout_of_ty_query( FloatTy::F64 => Float::F64, FloatTy::F128 => Float::F128, }), - ), + )), }, TyKind::Tuple(len, tys) => { let kind = if *len == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; @@ -268,56 +269,16 @@ pub fn layout_of_ty_query( TyKind::Array(element, count) => { let count = try_const_usize(db, count).ok_or(LayoutError::HasErrorConst)? as u64; let element = db.layout_of_ty(element.clone(), trait_env)?; - let size = element - .size - .checked_mul(count, dl) - .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?; - - let backend_repr = BackendRepr::Memory { sized: true }; - - let largest_niche = if count != 0 { element.largest_niche } else { None }; - let uninhabited = if count != 0 { element.uninhabited } else { false }; - - Layout { - variants: Variants::Single { index: struct_variant_idx() }, - fields: FieldsShape::Array { stride: element.size, count }, - backend_repr, - largest_niche, - uninhabited, - align: element.align, - size, - max_repr_align: None, - unadjusted_abi_align: element.align.abi, - randomization_seed: Hash64::ZERO, - } + cx.calc.array_like::<_, _, ()>(&element, Some(count))? } TyKind::Slice(element) => { let element = db.layout_of_ty(element.clone(), trait_env)?; - Layout { - variants: Variants::Single { index: struct_variant_idx() }, - fields: FieldsShape::Array { stride: element.size, count: 0 }, - backend_repr: BackendRepr::Memory { sized: false }, - largest_niche: None, - uninhabited: false, - align: element.align, - size: Size::ZERO, - max_repr_align: None, - unadjusted_abi_align: element.align.abi, - randomization_seed: Hash64::ZERO, - } + cx.calc.array_like::<_, _, ()>(&element, None)? + } + TyKind::Str => { + let element = scalar_unit(dl, Primitive::Int(Integer::I8, false)); + cx.calc.array_like::<_, _, ()>(&Layout::scalar(dl, element), None)? } - TyKind::Str => Layout { - variants: Variants::Single { index: struct_variant_idx() }, - fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, - backend_repr: BackendRepr::Memory { sized: false }, - largest_niche: None, - uninhabited: false, - align: dl.i8_align, - size: Size::ZERO, - max_repr_align: None, - unadjusted_abi_align: dl.i8_align.abi, - randomization_seed: Hash64::ZERO, - }, // Potentially-wide pointers. TyKind::Ref(_, _, pointee) | TyKind::Raw(_, pointee) => { let mut data_ptr = scalar_unit(dl, Primitive::Pointer(AddressSpace::DATA)); @@ -355,17 +316,12 @@ pub fn layout_of_ty_query( }; // Effectively a (ptr, meta) tuple. - cx.calc.scalar_pair(data_ptr, metadata) + LayoutData::scalar_pair(dl, data_ptr, metadata) } - TyKind::FnDef(_, _) => layout_of_unit(&cx)?, - TyKind::Never => cx.calc.layout_of_never_type(), - TyKind::Dyn(_) | TyKind::Foreign(_) => { - let mut unit = layout_of_unit(&cx)?; - match &mut unit.backend_repr { - BackendRepr::Memory { sized } => *sized = false, - _ => return Err(LayoutError::Unknown), - } - unit + TyKind::Never => LayoutData::never_type(dl), + TyKind::FnDef(..) | TyKind::Dyn(_) | TyKind::Foreign(_) => { + let sized = matches!(kind, TyKind::FnDef(..)); + LayoutData::unit(dl, sized) } TyKind::Function(_) => { let mut ptr = scalar_unit(dl, Primitive::Pointer(dl.instruction_address_space)); @@ -434,16 +390,6 @@ pub fn layout_of_ty_recover( Err(LayoutError::RecursiveTypeWithoutIndirection) } -fn layout_of_unit(cx: &LayoutCx<'_>) -> Result { - cx.calc - .univariant::( - IndexSlice::empty(), - &ReprOptions::default(), - StructKind::AlwaysSized, - ) - .map_err(Into::into) -} - fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty { match pointee.kind(Interner) { TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), subst) => { @@ -474,9 +420,5 @@ fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar { Scalar::Initialized { value, valid_range: WrappingRange::full(value.size(dl)) } } -fn scalar(dl: &TargetDataLayout, value: Primitive) -> Layout { - Layout::scalar(dl, scalar_unit(dl, value)) -} - #[cfg(test)] mod tests; From e69491ac6021572d4ac9cde1c14a04673b4ec859 Mon Sep 17 00:00:00 2001 From: Moulins Date: Fri, 7 Mar 2025 21:17:16 +0100 Subject: [PATCH 836/991] Move SIMD layout logic to `rustc_abi` --- compiler/rustc_abi/src/layout.rs | 97 ++++++++++++++++++++++---- compiler/rustc_abi/src/layout/ty.rs | 6 ++ compiler/rustc_abi/src/lib.rs | 7 ++ compiler/rustc_middle/src/ty/layout.rs | 7 +- compiler/rustc_ty_utils/src/layout.rs | 79 +++++---------------- 5 files changed, 117 insertions(+), 79 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 42ecbce8117c..d0d7cc68a77a 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -62,17 +62,28 @@ pub enum LayoutCalculatorError { /// The fields or variants have irreconcilable reprs ReprConflict, + + /// The length of an SIMD type is zero + ZeroLengthSimdType, + + /// The length of an SIMD type exceeds the maximum number of lanes + OversizedSimdType { max_lanes: u64 }, + + /// An element type of an SIMD type isn't a primitive + NonPrimitiveSimdType(F), } impl LayoutCalculatorError { pub fn without_payload(&self) -> LayoutCalculatorError<()> { - match self { - LayoutCalculatorError::UnexpectedUnsized(_) => { - LayoutCalculatorError::UnexpectedUnsized(()) - } - LayoutCalculatorError::SizeOverflow => LayoutCalculatorError::SizeOverflow, - LayoutCalculatorError::EmptyUnion => LayoutCalculatorError::EmptyUnion, - LayoutCalculatorError::ReprConflict => LayoutCalculatorError::ReprConflict, + use LayoutCalculatorError::*; + match *self { + UnexpectedUnsized(_) => UnexpectedUnsized(()), + SizeOverflow => SizeOverflow, + EmptyUnion => EmptyUnion, + ReprConflict => ReprConflict, + ZeroLengthSimdType => ZeroLengthSimdType, + OversizedSimdType { max_lanes } => OversizedSimdType { max_lanes }, + NonPrimitiveSimdType(_) => NonPrimitiveSimdType(()), } } @@ -80,13 +91,15 @@ impl LayoutCalculatorError { /// /// Intended for use by rust-analyzer, as neither it nor `rustc_abi` depend on fluent infra. pub fn fallback_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use LayoutCalculatorError::*; f.write_str(match self { - LayoutCalculatorError::UnexpectedUnsized(_) => { - "an unsized type was found where a sized type was expected" + UnexpectedUnsized(_) => "an unsized type was found where a sized type was expected", + SizeOverflow => "size overflow", + EmptyUnion => "type is a union with no fields", + ReprConflict => "type has an invalid repr", + ZeroLengthSimdType | OversizedSimdType { .. } | NonPrimitiveSimdType(_) => { + "invalid simd type definition" } - LayoutCalculatorError::SizeOverflow => "size overflow", - LayoutCalculatorError::EmptyUnion => "type is a union with no fields", - LayoutCalculatorError::ReprConflict => "type has an invalid repr", }) } } @@ -127,6 +140,66 @@ impl LayoutCalculator { }) } + pub fn simd_type< + FieldIdx: Idx, + VariantIdx: Idx, + F: AsRef> + fmt::Debug, + >( + &self, + element: F, + count: u64, + repr_packed: bool, + ) -> LayoutCalculatorResult { + let elt = element.as_ref(); + if count == 0 { + return Err(LayoutCalculatorError::ZeroLengthSimdType); + } else if count > crate::MAX_SIMD_LANES { + return Err(LayoutCalculatorError::OversizedSimdType { + max_lanes: crate::MAX_SIMD_LANES, + }); + } + + let BackendRepr::Scalar(e_repr) = elt.backend_repr else { + return Err(LayoutCalculatorError::NonPrimitiveSimdType(element)); + }; + + // Compute the size and alignment of the vector + let dl = self.cx.data_layout(); + let size = + elt.size.checked_mul(count, dl).ok_or_else(|| LayoutCalculatorError::SizeOverflow)?; + let (repr, align) = if repr_packed && !count.is_power_of_two() { + // Non-power-of-two vectors have padding up to the next power-of-two. + // If we're a packed repr, remove the padding while keeping the alignment as close + // to a vector as possible. + ( + BackendRepr::Memory { sized: true }, + AbiAndPrefAlign { + abi: Align::max_aligned_factor(size), + pref: dl.llvmlike_vector_align(size).pref, + }, + ) + } else { + (BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size)) + }; + let size = size.align_to(align.abi); + + Ok(LayoutData { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Arbitrary { + offsets: [Size::ZERO].into(), + memory_index: [0].into(), + }, + backend_repr: repr, + largest_niche: elt.largest_niche, + uninhabited: false, + size, + align, + max_repr_align: None, + unadjusted_abi_align: elt.align.abi, + randomization_seed: elt.randomization_seed.wrapping_add(Hash64::new(count)), + }) + } + pub fn univariant< 'a, FieldIdx: Idx, diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 03f3f043c218..4f43c0e6f8e9 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -150,6 +150,12 @@ impl<'a, Ty> Deref for TyAndLayout<'a, Ty> { } } +impl<'a, Ty> AsRef> for TyAndLayout<'a, Ty> { + fn as_ref(&self) -> &LayoutData { + &*self.layout.0.0 + } +} + /// Trait that needs to be implemented by the higher-level type representation /// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality. pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug { diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index db9a26c3ef7f..1b7375820093 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -205,6 +205,13 @@ impl ReprOptions { } } +/// The maximum supported number of lanes in a SIMD vector. +/// +/// This value is selected based on backend support: +/// * LLVM does not appear to have a vector width limit. +/// * Cranelift stores the base-2 log of the lane count in a 4 bit integer. +pub const MAX_SIMD_LANES: u64 = 1 << 0xF; + /// Parsed [Data layout](https://llvm.org/docs/LangRef.html#data-layout) /// for a target, which contains everything needed to compute layouts. #[derive(Debug, PartialEq, Eq)] diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index d32c524a427c..ebb6a8c08a54 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -182,12 +182,7 @@ pub const WIDE_PTR_ADDR: usize = 0; /// - For a slice, this is the length. pub const WIDE_PTR_EXTRA: usize = 1; -/// The maximum supported number of lanes in a SIMD vector. -/// -/// This value is selected based on backend support: -/// * LLVM does not appear to have a vector width limit. -/// * Cranelift stores the base-2 log of the lane count in a 4 bit integer. -pub const MAX_SIMD_LANES: u64 = 1 << 0xF; +pub const MAX_SIMD_LANES: u64 = rustc_abi::MAX_SIMD_LANES; /// Used in `check_validity_requirement` to indicate the kind of initialization /// that is checked to be valid diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 45c2639280f3..fe30b3e10931 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -5,9 +5,9 @@ use hir::def_id::DefId; use rustc_abi::Integer::{I8, I32}; use rustc_abi::Primitive::{self, Float, Int, Pointer}; use rustc_abi::{ - AbiAndPrefAlign, AddressSpace, Align, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, - HasDataLayout, Layout, LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, - StructKind, TagEncoding, VariantIdx, Variants, WrappingRange, + AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Layout, + LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding, + VariantIdx, Variants, WrappingRange, }; use rustc_hashes::Hash64; use rustc_index::bit_set::DenseBitSet; @@ -16,7 +16,7 @@ use rustc_middle::bug; use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal}; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ - FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, MAX_SIMD_LANES, TyAndLayout, + FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ @@ -124,6 +124,19 @@ fn map_error<'tcx>( .delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}")); LayoutError::ReferencesError(guar) } + LayoutCalculatorError::ZeroLengthSimdType => { + // Can't be caught in typeck if the array length is generic. + cx.tcx().dcx().emit_fatal(ZeroLengthSimdType { ty }) + } + LayoutCalculatorError::OversizedSimdType { max_lanes } => { + // Can't be caught in typeck if the array length is generic. + cx.tcx().dcx().emit_fatal(OversizedSimdType { ty, max_lanes }) + } + LayoutCalculatorError::NonPrimitiveSimdType(field) => { + // This error isn't caught in typeck, e.g., if + // the element type of the vector is generic. + cx.tcx().dcx().emit_fatal(NonPrimitiveSimdType { ty, e_ty: field.ty }) + } }; error(cx, err) } @@ -423,65 +436,9 @@ fn layout_of_uncached<'tcx>( .try_to_target_usize(tcx) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; - // SIMD vectors of zero length are not supported. - // Additionally, lengths are capped at 2^16 as a fixed maximum backends must - // support. - // - // Can't be caught in typeck if the array length is generic. - if e_len == 0 { - tcx.dcx().emit_fatal(ZeroLengthSimdType { ty }); - } else if e_len > MAX_SIMD_LANES { - tcx.dcx().emit_fatal(OversizedSimdType { ty, max_lanes: MAX_SIMD_LANES }); - } - - // Compute the ABI of the element type: let e_ly = cx.layout_of(e_ty)?; - let BackendRepr::Scalar(e_abi) = e_ly.backend_repr else { - // This error isn't caught in typeck, e.g., if - // the element type of the vector is generic. - tcx.dcx().emit_fatal(NonPrimitiveSimdType { ty, e_ty }); - }; - // Compute the size and alignment of the vector: - let size = e_ly - .size - .checked_mul(e_len, dl) - .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?; - - let (abi, align) = if def.repr().packed() && !e_len.is_power_of_two() { - // Non-power-of-two vectors have padding up to the next power-of-two. - // If we're a packed repr, remove the padding while keeping the alignment as close - // to a vector as possible. - ( - BackendRepr::Memory { sized: true }, - AbiAndPrefAlign { - abi: Align::max_aligned_factor(size), - pref: dl.llvmlike_vector_align(size).pref, - }, - ) - } else { - ( - BackendRepr::SimdVector { element: e_abi, count: e_len }, - dl.llvmlike_vector_align(size), - ) - }; - let size = size.align_to(align.abi); - - tcx.mk_layout(LayoutData { - variants: Variants::Single { index: FIRST_VARIANT }, - fields: FieldsShape::Arbitrary { - offsets: [Size::ZERO].into(), - memory_index: [0].into(), - }, - backend_repr: abi, - largest_niche: e_ly.largest_niche, - uninhabited: false, - size, - align, - max_repr_align: None, - unadjusted_abi_align: align.abi, - randomization_seed: e_ly.randomization_seed.wrapping_add(Hash64::new(e_len)), - }) + map_layout(cx.calc.simd_type(e_ly, e_len, def.repr().packed()))? } // ADTs. From f79f3d31a3cbf87e50531851f5079e7fcba7ce81 Mon Sep 17 00:00:00 2001 From: Moulins Date: Fri, 7 Mar 2025 21:18:18 +0100 Subject: [PATCH 837/991] Use `rustc_abi` code for SIMD layout in rust-analyzer --- .../rust-analyzer/crates/hir-ty/src/layout.rs | 37 +++---------------- .../crates/hir-ty/src/layout/adt.rs | 6 +-- .../rust-analyzer/crates/hir-ty/src/lib.rs | 3 -- 3 files changed, 7 insertions(+), 39 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 05f38cd09e22..2ac1792ba868 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -6,15 +6,14 @@ use base_db::ra_salsa::Cycle; use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy}; use hir_def::{ layout::{ - BackendRepr, FieldsShape, Float, Integer, LayoutCalculator, LayoutCalculatorError, - LayoutData, Primitive, ReprOptions, Scalar, Size, StructKind, TargetDataLayout, + Float, Integer, LayoutCalculator, LayoutCalculatorError, + LayoutData, Primitive, ReprOptions, Scalar, StructKind, TargetDataLayout, WrappingRange, }, LocalFieldId, StructId, }; use la_arena::{Idx, RawIdx}; use rustc_abi::AddressSpace; -use rustc_hashes::Hash64; use rustc_index::IndexVec; use triomphe::Arc; @@ -23,7 +22,6 @@ use crate::{ consteval::try_const_usize, db::{HirDatabase, InternedClosure}, infer::normalize, - layout::adt::struct_variant_idx, utils::ClosureSubst, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, }; @@ -125,10 +123,10 @@ impl<'a> LayoutCx<'a> { } } -// FIXME: move this to the `rustc_abi`. fn layout_of_simd_ty( db: &dyn HirDatabase, id: StructId, + repr_packed: bool, subst: &Substitution, env: Arc, dl: &TargetDataLayout, @@ -149,33 +147,10 @@ fn layout_of_simd_ty( }; let e_len = try_const_usize(db, &e_len).ok_or(LayoutError::HasErrorConst)? as u64; - - // Compute the ABI of the element type: let e_ly = db.layout_of_ty(e_ty, env)?; - let BackendRepr::Scalar(e_abi) = e_ly.backend_repr else { - return Err(LayoutError::Unknown); - }; - // Compute the size and alignment of the vector: - let size = e_ly - .size - .checked_mul(e_len, dl) - .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?; - let align = dl.llvmlike_vector_align(size); - let size = size.align_to(align.abi); - - Ok(Arc::new(Layout { - variants: Variants::Single { index: struct_variant_idx() }, - fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }, - backend_repr: BackendRepr::SimdVector { element: e_abi, count: e_len }, - largest_niche: e_ly.largest_niche, - uninhabited: false, - size, - align, - max_repr_align: None, - unadjusted_abi_align: align.abi, - randomization_seed: Hash64::ZERO, - })) + let cx = LayoutCx::new(dl); + Ok(Arc::new(cx.calc.simd_type(e_ly, e_len, repr_packed)?)) } pub fn layout_of_ty_query( @@ -197,7 +172,7 @@ pub fn layout_of_ty_query( let data = db.struct_data(*s); let repr = data.repr.unwrap_or_default(); if repr.simd() { - return layout_of_simd_ty(db, *s, subst, trait_env, &target); + return layout_of_simd_ty(db, *s, repr.packed(), subst, trait_env, &target); } }; return db.layout_of_adt(*def, subst.clone(), trait_env); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs index 0ba765bd75ef..eb4729fab842 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs @@ -16,16 +16,12 @@ use triomphe::Arc; use crate::{ db::HirDatabase, lang_items::is_unsafe_cell, - layout::{field_ty, Layout, LayoutError, RustcEnumVariantIdx}, + layout::{field_ty, Layout, LayoutError}, Substitution, TraitEnvironment, }; use super::LayoutCx; -pub(crate) fn struct_variant_idx() -> RustcEnumVariantIdx { - RustcEnumVariantIdx(0) -} - pub fn layout_of_adt_query( db: &dyn HirDatabase, def: AdtId, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 707c43777267..e0dcc01821ec 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -12,9 +12,6 @@ extern crate ra_ap_rustc_index as rustc_index; #[cfg(feature = "in-rust-tree")] extern crate rustc_abi; -#[cfg(feature = "in-rust-tree")] -extern crate rustc_hashes; - #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_abi as rustc_abi; From b8a217081d0d7aef0c89c9dacc21c020faa0949b Mon Sep 17 00:00:00 2001 From: Moulins Date: Fri, 7 Mar 2025 22:09:56 +0100 Subject: [PATCH 838/991] Refactor coroutine layout logic to precompute all sublayouts Also properly attaches spans on layouts of non-promoted coroutine locals, which slightly improves the error messages for some coroutine tests. --- compiler/rustc_ty_utils/src/layout.rs | 235 +++++++++--------- .../indirect-recursion-issue-112047.stderr | 3 + tests/ui/layout/post-mono-layout-cycle-2.rs | 2 +- .../ui/layout/post-mono-layout-cycle-2.stderr | 6 - 4 files changed, 122 insertions(+), 124 deletions(-) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index fe30b3e10931..efca395fe4ae 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -5,23 +5,21 @@ use hir::def_id::DefId; use rustc_abi::Integer::{I8, I32}; use rustc_abi::Primitive::{self, Float, Int, Pointer}; use rustc_abi::{ - AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Layout, - LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding, - VariantIdx, Variants, WrappingRange, + AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Integer, + Layout, LayoutCalculator, LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, + StructKind, TagEncoding, VariantIdx, Variants, WrappingRange, }; use rustc_hashes::Hash64; -use rustc_index::bit_set::DenseBitSet; -use rustc_index::{IndexSlice, IndexVec}; +use rustc_index::bit_set::{BitMatrix, DenseBitSet}; +use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_middle::bug; -use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal}; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, AdtDef, CoroutineArgsExt, EarlyBinder, GenericArgsRef, PseudoCanonicalInput, Ty, TyCtxt, - TypeVisitableExt, + self, AdtDef, CoroutineArgsExt, EarlyBinder, PseudoCanonicalInput, Ty, TyCtxt, TypeVisitableExt, }; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_span::{Symbol, sym}; @@ -141,16 +139,6 @@ fn map_error<'tcx>( error(cx, err) } -fn univariant_uninterned<'tcx>( - cx: &LayoutCx<'tcx>, - ty: Ty<'tcx>, - fields: &IndexSlice>, - kind: StructKind, -) -> Result, &'tcx LayoutError<'tcx>> { - let repr = ReprOptions::default(); - cx.calc.univariant(fields, &repr, kind).map_err(|err| map_error(cx, ty, err)) -} - fn extract_const_value<'tcx>( cx: &LayoutCx<'tcx>, ty: Ty<'tcx>, @@ -212,8 +200,10 @@ fn layout_of_uncached<'tcx>( }; let scalar = |value: Primitive| tcx.mk_layout(LayoutData::scalar(cx, scalar_unit(value))); - let univariant = |fields: &IndexSlice>, kind| { - Ok(tcx.mk_layout(univariant_uninterned(cx, ty, fields, kind)?)) + let univariant = |tys: &[Ty<'tcx>], kind| { + let fields = tys.iter().map(|ty| cx.layout_of(*ty)).try_collect::>()?; + let repr = ReprOptions::default(); + map_layout(cx.calc.univariant(&fields, &repr, kind)) }; debug_assert!(!ty.has_non_region_infer()); @@ -389,29 +379,61 @@ fn layout_of_uncached<'tcx>( tcx.mk_layout(LayoutData::unit(cx, sized)) } - ty::Coroutine(def_id, args) => coroutine_layout(cx, ty, def_id, args)?, + ty::Coroutine(def_id, args) => { + use rustc_middle::ty::layout::PrimitiveExt as _; - ty::Closure(_, args) => { - let tys = args.as_closure().upvar_tys(); - univariant( - &tys.iter().map(|ty| cx.layout_of(ty)).try_collect::>()?, - StructKind::AlwaysSized, - )? + let Some(info) = tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty()) else { + return Err(error(cx, LayoutError::Unknown(ty))); + }; + + let local_layouts = info + .field_tys + .iter() + .map(|local| { + let field_ty = EarlyBinder::bind(local.ty); + let uninit_ty = Ty::new_maybe_uninit(tcx, field_ty.instantiate(tcx, args)); + cx.spanned_layout_of(uninit_ty, local.source_info.span) + }) + .try_collect::>()?; + + let prefix_layouts = args + .as_coroutine() + .prefix_tys() + .iter() + .map(|ty| cx.layout_of(ty)) + .try_collect::>()?; + + let layout = coroutine_layout( + &cx.calc, + &local_layouts, + prefix_layouts, + &info.variant_fields, + &info.storage_conflicts, + |tag| TyAndLayout { + ty: tag.primitive().to_ty(tcx), + layout: tcx.mk_layout(LayoutData::scalar(cx, tag)), + }, + ) + .map(|mut layout| { + // this is similar to how ReprOptions populates its field_shuffle_seed + layout.randomization_seed = tcx.def_path_hash(def_id).0.to_smaller_hash(); + debug!("coroutine layout ({:?}): {:#?}", ty, layout); + layout + }); + map_layout(layout)? } + ty::Closure(_, args) => univariant(args.as_closure().upvar_tys(), StructKind::AlwaysSized)?, + ty::CoroutineClosure(_, args) => { - let tys = args.as_coroutine_closure().upvar_tys(); - univariant( - &tys.iter().map(|ty| cx.layout_of(ty)).try_collect::>()?, - StructKind::AlwaysSized, - )? + univariant(args.as_coroutine_closure().upvar_tys(), StructKind::AlwaysSized)? } ty::Tuple(tys) => { let kind = if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; - univariant(&tys.iter().map(|k| cx.layout_of(k)).try_collect::>()?, kind)? + univariant(tys, kind)? } // SIMD vector types. @@ -594,7 +616,7 @@ fn layout_of_uncached<'tcx>( /// Overlap eligibility and variant assignment for each CoroutineSavedLocal. #[derive(Clone, Debug, PartialEq)] -enum SavedLocalEligibility { +enum SavedLocalEligibility { Unassigned, Assigned(VariantIdx), Ineligible(Option), @@ -620,21 +642,22 @@ enum SavedLocalEligibility { // of any variant. /// Compute the eligibility and assignment of each local. -fn coroutine_saved_local_eligibility( - info: &CoroutineLayout<'_>, -) -> (DenseBitSet, IndexVec) { +fn coroutine_saved_local_eligibility( + nb_locals: usize, + variant_fields: &IndexSlice>, + storage_conflicts: &BitMatrix, +) -> (DenseBitSet, IndexVec>) { use SavedLocalEligibility::*; - let mut assignments: IndexVec = - IndexVec::from_elem(Unassigned, &info.field_tys); + let mut assignments: IndexVec = IndexVec::from_elem_n(Unassigned, nb_locals); // The saved locals not eligible for overlap. These will get // "promoted" to the prefix of our coroutine. - let mut ineligible_locals = DenseBitSet::new_empty(info.field_tys.len()); + let mut ineligible_locals = DenseBitSet::new_empty(nb_locals); // Figure out which of our saved locals are fields in only // one variant. The rest are deemed ineligible for overlap. - for (variant_index, fields) in info.variant_fields.iter_enumerated() { + for (variant_index, fields) in variant_fields.iter_enumerated() { for local in fields { match assignments[*local] { Unassigned => { @@ -657,13 +680,13 @@ fn coroutine_saved_local_eligibility( // Next, check every pair of eligible locals to see if they // conflict. - for local_a in info.storage_conflicts.rows() { - let conflicts_a = info.storage_conflicts.count(local_a); + for local_a in storage_conflicts.rows() { + let conflicts_a = storage_conflicts.count(local_a); if ineligible_locals.contains(local_a) { continue; } - for local_b in info.storage_conflicts.iter(local_a) { + for local_b in storage_conflicts.iter(local_a) { // local_a and local_b are storage live at the same time, therefore they // cannot overlap in the coroutine layout. The only way to guarantee // this is if they are in the same variant, or one is ineligible @@ -675,7 +698,7 @@ fn coroutine_saved_local_eligibility( // If they conflict, we will choose one to make ineligible. // This is not always optimal; it's just a greedy heuristic that // seems to produce good results most of the time. - let conflicts_b = info.storage_conflicts.count(local_b); + let conflicts_b = storage_conflicts.count(local_b); let (remove, other) = if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) }; ineligible_locals.insert(remove); @@ -690,7 +713,7 @@ fn coroutine_saved_local_eligibility( // lay them out with the other locals in the prefix and eliminate // unnecessary padding bytes. { - let mut used_variants = DenseBitSet::new_empty(info.variant_fields.len()); + let mut used_variants = DenseBitSet::new_empty(variant_fields.len()); for assignment in &assignments { if let Assigned(idx) = assignment { used_variants.insert(*idx); @@ -707,7 +730,7 @@ fn coroutine_saved_local_eligibility( // Write down the order of our locals that will be promoted to the prefix. { for (idx, local) in ineligible_locals.iter().enumerate() { - assignments[local] = Ineligible(Some(FieldIdx::from_usize(idx))); + assignments[local] = Ineligible(Some(FieldIdx::new(idx))); } } debug!("coroutine saved local assignments: {:?}", assignments); @@ -716,52 +739,43 @@ fn coroutine_saved_local_eligibility( } /// Compute the full coroutine layout. -fn coroutine_layout<'tcx>( - cx: &LayoutCx<'tcx>, - ty: Ty<'tcx>, - def_id: hir::def_id::DefId, - args: GenericArgsRef<'tcx>, -) -> Result, &'tcx LayoutError<'tcx>> { +fn coroutine_layout< + 'a, + F: core::ops::Deref> + core::fmt::Debug + Copy, + VariantIdx: Idx, + FieldIdx: Idx, + LocalIdx: Idx, +>( + calc: &LayoutCalculator, + local_layouts: &IndexSlice, + mut prefix_layouts: IndexVec, + variant_fields: &IndexSlice>, + storage_conflicts: &BitMatrix, + tag_to_layout: impl Fn(Scalar) -> F, +) -> Result, LayoutCalculatorError> { use SavedLocalEligibility::*; - let tcx = cx.tcx(); - let instantiate_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).instantiate(tcx, args); - let Some(info) = tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty()) else { - return Err(error(cx, LayoutError::Unknown(ty))); - }; - let (ineligible_locals, assignments) = coroutine_saved_local_eligibility(info); + let (ineligible_locals, assignments) = + coroutine_saved_local_eligibility(local_layouts.len(), variant_fields, storage_conflicts); // Build a prefix layout, including "promoting" all ineligible // locals as part of the prefix. We compute the layout of all of // these fields at once to get optimal packing. - let tag_index = args.as_coroutine().prefix_tys().len(); + let tag_index = prefix_layouts.len(); - // `info.variant_fields` already accounts for the reserved variants, so no need to add them. - let max_discr = (info.variant_fields.len() - 1) as u128; - let discr_int = abi::Integer::fit_unsigned(max_discr); + // `variant_fields` already accounts for the reserved variants, so no need to add them. + let max_discr = (variant_fields.len() - 1) as u128; + let discr_int = Integer::fit_unsigned(max_discr); let tag = Scalar::Initialized { value: Primitive::Int(discr_int, /* signed = */ false), valid_range: WrappingRange { start: 0, end: max_discr }, }; - let tag_layout = TyAndLayout { - ty: discr_int.to_ty(tcx, /* signed = */ false), - layout: tcx.mk_layout(LayoutData::scalar(cx, tag)), - }; - let promoted_layouts = ineligible_locals.iter().map(|local| { - let field_ty = instantiate_field(info.field_tys[local].ty); - let uninit_ty = Ty::new_maybe_uninit(tcx, field_ty); - cx.spanned_layout_of(uninit_ty, info.field_tys[local].source_info.span) - }); - let prefix_layouts = args - .as_coroutine() - .prefix_tys() - .iter() - .map(|ty| cx.layout_of(ty)) - .chain(iter::once(Ok(tag_layout))) - .chain(promoted_layouts) - .try_collect::>()?; - let prefix = univariant_uninterned(cx, ty, &prefix_layouts, StructKind::AlwaysSized)?; + let promoted_layouts = ineligible_locals.iter().map(|local| local_layouts[local]); + prefix_layouts.push(tag_to_layout(tag)); + prefix_layouts.extend(promoted_layouts); + let prefix = + calc.univariant(&prefix_layouts, &ReprOptions::default(), StructKind::AlwaysSized)?; let (prefix_size, prefix_align) = (prefix.size, prefix.align); @@ -776,8 +790,8 @@ fn coroutine_layout<'tcx>( // "a" (`0..b_start`) and "b" (`b_start..`) correspond to // "outer" and "promoted" fields respectively. - let b_start = FieldIdx::from_usize(tag_index + 1); - let offsets_b = IndexVec::from_raw(offsets.raw.split_off(b_start.as_usize())); + let b_start = FieldIdx::new(tag_index + 1); + let offsets_b = IndexVec::from_raw(offsets.raw.split_off(b_start.index())); let offsets_a = offsets; // Disentangle the "a" and "b" components of `inverse_memory_index` @@ -785,9 +799,9 @@ fn coroutine_layout<'tcx>( // FIXME(eddyb) build a better abstraction for permutations, if possible. let inverse_memory_index_b: IndexVec = inverse_memory_index .iter() - .filter_map(|&i| i.as_u32().checked_sub(b_start.as_u32()).map(FieldIdx::from_u32)) + .filter_map(|&i| i.index().checked_sub(b_start.index()).map(FieldIdx::new)) .collect(); - inverse_memory_index.raw.retain(|&i| i < b_start); + inverse_memory_index.raw.retain(|&i| i.index() < b_start.index()); let inverse_memory_index_a = inverse_memory_index; // Since `inverse_memory_index_{a,b}` each only refer to their @@ -799,39 +813,34 @@ fn coroutine_layout<'tcx>( FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a }; (outer_fields, offsets_b, memory_index_b) } - _ => bug!(), + _ => unreachable!(), }; let mut size = prefix.size; let mut align = prefix.align; - let variants = info - .variant_fields + let variants = variant_fields .iter_enumerated() .map(|(index, variant_fields)| { // Only include overlap-eligible fields when we compute our variant layout. let variant_only_tys = variant_fields .iter() .filter(|local| match assignments[**local] { - Unassigned => bug!(), + Unassigned => unreachable!(), Assigned(v) if v == index => true, - Assigned(_) => bug!("assignment does not match variant"), + Assigned(_) => unreachable!("assignment does not match variant"), Ineligible(_) => false, }) - .map(|local| { - let field_ty = instantiate_field(info.field_tys[*local].ty); - Ty::new_maybe_uninit(tcx, field_ty) - }); + .map(|local| local_layouts[*local]); - let mut variant = univariant_uninterned( - cx, - ty, - &variant_only_tys.map(|ty| cx.layout_of(ty)).try_collect::>()?, + let mut variant = calc.univariant( + &variant_only_tys.collect::>(), + &ReprOptions::default(), StructKind::Prefixed(prefix_size, prefix_align.abi), )?; variant.variants = Variants::Single { index }; let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else { - bug!(); + unreachable!(); }; // Now, stitch the promoted and variant-only fields back together in @@ -841,21 +850,18 @@ fn coroutine_layout<'tcx>( // `promoted_memory_index` (as we'd end up with gaps). // So instead, we build an "inverse memory_index", as if all of the // promoted fields were being used, but leave the elements not in the - // subset as `INVALID_FIELD_IDX`, which we can filter out later to + // subset as `invalid_field_idx`, which we can filter out later to // obtain a valid (bijective) mapping. - const INVALID_FIELD_IDX: FieldIdx = FieldIdx::MAX; - debug_assert!(variant_fields.next_index() <= INVALID_FIELD_IDX); + let invalid_field_idx = promoted_memory_index.len() + memory_index.len(); + let mut combined_inverse_memory_index = + IndexVec::from_elem_n(FieldIdx::new(invalid_field_idx), invalid_field_idx); - let mut combined_inverse_memory_index = IndexVec::from_elem_n( - INVALID_FIELD_IDX, - promoted_memory_index.len() + memory_index.len(), - ); let mut offsets_and_memory_index = iter::zip(offsets, memory_index); let combined_offsets = variant_fields .iter_enumerated() .map(|(i, local)| { let (offset, memory_index) = match assignments[*local] { - Unassigned => bug!(), + Unassigned => unreachable!(), Assigned(_) => { let (offset, memory_index) = offsets_and_memory_index.next().unwrap(); (offset, promoted_memory_index.len() as u32 + memory_index) @@ -872,7 +878,7 @@ fn coroutine_layout<'tcx>( // Remove the unused slots and invert the mapping to obtain the // combined `memory_index` (also see previous comment). - combined_inverse_memory_index.raw.retain(|&i| i != INVALID_FIELD_IDX); + combined_inverse_memory_index.raw.retain(|&i| i.index() != invalid_field_idx); let combined_memory_index = combined_inverse_memory_index.invert_bijective_mapping(); variant.fields = FieldsShape::Arbitrary { @@ -884,17 +890,14 @@ fn coroutine_layout<'tcx>( align = align.max(variant.align); Ok(variant) }) - .try_collect::>()?; + .collect::, _>>()?; size = size.align_to(align.abi); let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited()); let abi = BackendRepr::Memory { sized: true }; - // this is similar to how ReprOptions populates its field_shuffle_seed - let def_hash = tcx.def_path_hash(def_id).0.to_smaller_hash(); - - let layout = tcx.mk_layout(LayoutData { + Ok(LayoutData { variants: Variants::Multiple { tag, tag_encoding: TagEncoding::Direct, @@ -915,10 +918,8 @@ fn coroutine_layout<'tcx>( align, max_repr_align: None, unadjusted_abi_align: align.abi, - randomization_seed: def_hash, - }); - debug!("coroutine layout ({:?}): {:#?}", ty, layout); - Ok(layout) + randomization_seed: Default::default(), + }) } fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx>, layout: TyAndLayout<'tcx>) { diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr index 4ca6ef898198..aa22a453744c 100644 --- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr @@ -3,6 +3,9 @@ error[E0733]: recursion in an async fn requires boxing | LL | async fn second(self) { | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | self.first().await.second().await; + | --------------------------------- recursive call here | = note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future diff --git a/tests/ui/layout/post-mono-layout-cycle-2.rs b/tests/ui/layout/post-mono-layout-cycle-2.rs index 2daac12d7ac9..c8a4a222cc68 100644 --- a/tests/ui/layout/post-mono-layout-cycle-2.rs +++ b/tests/ui/layout/post-mono-layout-cycle-2.rs @@ -1,4 +1,4 @@ -//@ build-fail +//@ check-fail //@ edition: 2021 use std::future::Future; diff --git a/tests/ui/layout/post-mono-layout-cycle-2.stderr b/tests/ui/layout/post-mono-layout-cycle-2.stderr index d8c51deffe3b..f04e01071d7a 100644 --- a/tests/ui/layout/post-mono-layout-cycle-2.stderr +++ b/tests/ui/layout/post-mono-layout-cycle-2.stderr @@ -12,12 +12,6 @@ LL | Blah::iter(self, iterator).await | = note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future -note: the above error was encountered while instantiating `fn Wrap::<()>::ice` - --> $DIR/post-mono-layout-cycle-2.rs:54:9 - | -LL | t.ice(); - | ^^^^^^^ - error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0733`. From 871be8f54ace198c42780b366d1817ffc77e9fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 8 Mar 2025 12:46:24 +0100 Subject: [PATCH 839/991] Add missing `GH_TOKEN` environment variable It is needed for using the `gh` CLI commands. --- .github/workflows/post-merge.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index d3f42c5a9052..919e1bb33206 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -17,14 +17,15 @@ jobs: steps: - uses: actions/checkout@v4 - name: Perform analysis and send PR + env: + GH_TOKEN: ${{ github.token }} run: | # Get closest bors merge commit PARENT_COMMIT=`git rev-list --author='bors ' -n1 --first-parent HEAD^1` + echo "Parent: ${PARENT_COMMIT}" # Find PR for the current commit HEAD_PR=`gh pr list --search "${{ github.sha }}" --state merged --json number --jq '.[0].number'` - - echo "Parent: ${PARENT_COMMIT}" echo "HEAD: ${{ github.sha }} (#${HEAD_PR})" cd src/ci/citool From ff674232d198b196c8fa9d2092b8165b4bcce6b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 8 Mar 2025 12:46:33 +0100 Subject: [PATCH 840/991] Fix checkout in post-merge workflow --- .github/workflows/post-merge.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 919e1bb33206..2bc06d83c5b7 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -16,6 +16,11 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v4 + with: + # Make sure that we have enough commits to find the parent merge commit. + # Since all merges should be through merge commits, fetching two commits + # should be enough to get the parent bors merge commit. + fetch-depth: 2 - name: Perform analysis and send PR env: GH_TOKEN: ${{ github.token }} From b2de19e8acb938eb1c6c4e59f8a06655b299f6f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 25 Feb 2025 13:43:25 +0100 Subject: [PATCH 841/991] Update bootstrap to edition 2024 --- src/bootstrap/Cargo.toml | 2 +- src/bootstrap/src/bin/sccache-plus-cl.rs | 9 +++- src/bootstrap/src/core/build_steps/format.rs | 2 +- src/bootstrap/src/utils/cc_detect/tests.rs | 56 +++++++++++++------- src/bootstrap/src/utils/helpers.rs | 2 +- src/bootstrap/src/utils/job.rs | 4 +- 6 files changed, 51 insertions(+), 24 deletions(-) diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 2c1d85b01e6a..2ea2596088fd 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "bootstrap" version = "0.0.0" -edition = "2021" +edition = "2024" build = "build.rs" default-run = "bootstrap" diff --git a/src/bootstrap/src/bin/sccache-plus-cl.rs b/src/bootstrap/src/bin/sccache-plus-cl.rs index 6e87d4222e86..c161d69d5f73 100644 --- a/src/bootstrap/src/bin/sccache-plus-cl.rs +++ b/src/bootstrap/src/bin/sccache-plus-cl.rs @@ -4,8 +4,13 @@ use std::process::{self, Command}; fn main() { let target = env::var("SCCACHE_TARGET").unwrap(); // Locate the actual compiler that we're invoking - env::set_var("CC", env::var_os("SCCACHE_CC").unwrap()); - env::set_var("CXX", env::var_os("SCCACHE_CXX").unwrap()); + + // SAFETY: we're in main, there are no other threads + unsafe { + env::set_var("CC", env::var_os("SCCACHE_CC").unwrap()); + env::set_var("CXX", env::var_os("SCCACHE_CXX").unwrap()); + } + let mut cfg = cc::Build::new(); cfg.cargo_metadata(false) .out_dir("/") diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index c7eafadee2df..9817e47baa10 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -27,7 +27,7 @@ fn rustfmt( rustfmt: &Path, paths: &[PathBuf], check: bool, -) -> impl FnMut(bool) -> RustfmtStatus { +) -> impl FnMut(bool) -> RustfmtStatus + use<> { let mut cmd = Command::new(rustfmt); // Avoid the submodule config paths from coming into play. We only allow a single global config // for the workspace for now. diff --git a/src/bootstrap/src/utils/cc_detect/tests.rs b/src/bootstrap/src/utils/cc_detect/tests.rs index 006dfe7e5d7b..c97529cbe9eb 100644 --- a/src/bootstrap/src/utils/cc_detect/tests.rs +++ b/src/bootstrap/src/utils/cc_detect/tests.rs @@ -9,20 +9,24 @@ use crate::{Build, Config, Flags}; fn test_cc2ar_env_specific() { let triple = "x86_64-unknown-linux-gnu"; let key = "AR_x86_64_unknown_linux_gnu"; - env::set_var(key, "custom-ar"); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::set_var(key, "custom-ar") }; let target = TargetSelection::from_user(triple); let cc = Path::new("/usr/bin/clang"); let default_ar = PathBuf::from("default-ar"); let result = cc2ar(cc, target, default_ar); - env::remove_var(key); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var(key) }; assert_eq!(result, Some(PathBuf::from("custom-ar"))); } #[test] fn test_cc2ar_musl() { let triple = "x86_64-unknown-linux-musl"; - env::remove_var("AR_x86_64_unknown_linux_musl"); - env::remove_var("AR"); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR_x86_64_unknown_linux_musl") }; + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR") }; let target = TargetSelection::from_user(triple); let cc = Path::new("/usr/bin/clang"); let default_ar = PathBuf::from("default-ar"); @@ -33,8 +37,10 @@ fn test_cc2ar_musl() { #[test] fn test_cc2ar_openbsd() { let triple = "x86_64-unknown-openbsd"; - env::remove_var("AR_x86_64_unknown_openbsd"); - env::remove_var("AR"); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR_x86_64_unknown_openbsd") }; + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR") }; let target = TargetSelection::from_user(triple); let cc = Path::new("/usr/bin/cc"); let default_ar = PathBuf::from("default-ar"); @@ -45,8 +51,10 @@ fn test_cc2ar_openbsd() { #[test] fn test_cc2ar_vxworks() { let triple = "armv7-wrs-vxworks"; - env::remove_var("AR_armv7_wrs_vxworks"); - env::remove_var("AR"); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR_armv7_wrs_vxworks") }; + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR") }; let target = TargetSelection::from_user(triple); let cc = Path::new("/usr/bin/clang"); let default_ar = PathBuf::from("default-ar"); @@ -57,8 +65,10 @@ fn test_cc2ar_vxworks() { #[test] fn test_cc2ar_nto_i586() { let triple = "i586-unknown-nto-something"; - env::remove_var("AR_i586_unknown_nto_something"); - env::remove_var("AR"); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR_i586_unknown_nto_something") }; + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR") }; let target = TargetSelection::from_user(triple); let cc = Path::new("/usr/bin/clang"); let default_ar = PathBuf::from("default-ar"); @@ -69,8 +79,10 @@ fn test_cc2ar_nto_i586() { #[test] fn test_cc2ar_nto_aarch64() { let triple = "aarch64-unknown-nto-something"; - env::remove_var("AR_aarch64_unknown_nto_something"); - env::remove_var("AR"); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR_aarch64_unknown_nto_something") }; + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR") }; let target = TargetSelection::from_user(triple); let cc = Path::new("/usr/bin/clang"); let default_ar = PathBuf::from("default-ar"); @@ -81,8 +93,10 @@ fn test_cc2ar_nto_aarch64() { #[test] fn test_cc2ar_nto_x86_64() { let triple = "x86_64-unknown-nto-something"; - env::remove_var("AR_x86_64_unknown_nto_something"); - env::remove_var("AR"); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR_x86_64_unknown_nto_something") }; + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR") }; let target = TargetSelection::from_user(triple); let cc = Path::new("/usr/bin/clang"); let default_ar = PathBuf::from("default-ar"); @@ -94,8 +108,10 @@ fn test_cc2ar_nto_x86_64() { #[should_panic(expected = "Unknown architecture, cannot determine archiver for Neutrino QNX")] fn test_cc2ar_nto_unknown() { let triple = "powerpc-unknown-nto-something"; - env::remove_var("AR_powerpc_unknown_nto_something"); - env::remove_var("AR"); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR_powerpc_unknown_nto_something") }; + // SAFETY: bootstrap tests run on a single thread + unsafe { env::remove_var("AR") }; let target = TargetSelection::from_user(triple); let cc = Path::new("/usr/bin/clang"); let default_ar = PathBuf::from("default-ar"); @@ -177,7 +193,8 @@ fn test_default_compiler_wasi() { let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) }); let target = TargetSelection::from_user("wasm32-wasi"); let wasi_sdk = PathBuf::from("/wasi-sdk"); - env::set_var("WASI_SDK_PATH", &wasi_sdk); + // SAFETY: bootstrap tests run on a single thread + unsafe { env::set_var("WASI_SDK_PATH", &wasi_sdk) }; let mut cfg = cc::Build::new(); if let Some(result) = default_compiler(&mut cfg, Language::C, target.clone(), &build) { let expected = { @@ -190,7 +207,10 @@ fn test_default_compiler_wasi() { "default_compiler should return a compiler path for wasi target when WASI_SDK_PATH is set" ); } - env::remove_var("WASI_SDK_PATH"); + // SAFETY: bootstrap tests run on a single thread + unsafe { + env::remove_var("WASI_SDK_PATH"); + } } #[test] diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 7ad308cd0672..89d93a29acbc 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -286,7 +286,7 @@ pub fn output(cmd: &mut Command) -> String { /// to finish and then return its output. This allows the spawned process /// to do work without immediately blocking bootstrap. #[track_caller] -pub fn start_process(cmd: &mut Command) -> impl FnOnce() -> String { +pub fn start_process(cmd: &mut Command) -> impl FnOnce() -> String + use<> { let child = match cmd.stderr(Stdio::inherit()).stdout(Stdio::piped()).spawn() { Ok(child) => child, Err(e) => fail(&format!("failed to execute command: {cmd:?}\nERROR: {e}")), diff --git a/src/bootstrap/src/utils/job.rs b/src/bootstrap/src/utils/job.rs index a60e889fd576..99fc3e2dc7b5 100644 --- a/src/bootstrap/src/utils/job.rs +++ b/src/bootstrap/src/utils/job.rs @@ -7,7 +7,9 @@ pub unsafe fn setup(_build: &mut crate::Build) {} #[cfg(all(unix, not(target_os = "haiku")))] pub unsafe fn setup(build: &mut crate::Build) { if build.config.low_priority { - libc::setpriority(libc::PRIO_PGRP as _, 0, 10); + unsafe { + libc::setpriority(libc::PRIO_PGRP as _, 0, 10); + } } } From e88f892ecafcf9e0815552d219fe98c8f7084f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A8Florian?= <¨flodiebold@gmail.com¨> Date: Fri, 28 Feb 2025 17:32:21 +0100 Subject: [PATCH 842/991] Fix syntax fixup producing invalid punctuation Fixes #19206. Fixes #18244. --- .../mbe/tt_conversion.rs | 8 +-- .../crates/hir-expand/src/fixup.rs | 68 +++++++----------- .../rust-analyzer/crates/mbe/src/tests.rs | 17 +++++ .../crates/syntax-bridge/src/lib.rs | 70 ++++++++++++++----- src/tools/rust-analyzer/crates/tt/src/lib.rs | 30 ++------ 5 files changed, 105 insertions(+), 88 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs index c365a603d2af..138db1b498bb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs @@ -93,15 +93,15 @@ fn broken_parenthesis_sequence() { macro_rules! m1 { ($x:ident) => { ($x } } macro_rules! m2 { ($x:ident) => {} } -m1!(); -m2!(x +fn f1() { m1!(x); } +fn f2() { m2!(x } "#, expect![[r#" macro_rules! m1 { ($x:ident) => { ($x } } macro_rules! m2 { ($x:ident) => {} } -/* error: macro definition has parse errors */ -/* error: expected ident */ +fn f1() { (x); } +fn f2() { /* error: expected ident */ } "#]], ) } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs index eb430177390f..28894537d48f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs @@ -148,7 +148,6 @@ pub(crate) fn fixup_syntax( } if it.then_branch().is_none() { append.insert(node.clone().into(), vec![ - // FIXME: THis should be a subtree no? Leaf::Punct(Punct { char: '{', spacing: Spacing::Alone, @@ -179,7 +178,6 @@ pub(crate) fn fixup_syntax( } if it.loop_body().is_none() { append.insert(node.clone().into(), vec![ - // FIXME: THis should be a subtree no? Leaf::Punct(Punct { char: '{', spacing: Spacing::Alone, @@ -196,7 +194,6 @@ pub(crate) fn fixup_syntax( ast::LoopExpr(it) => { if it.loop_body().is_none() { append.insert(node.clone().into(), vec![ - // FIXME: THis should be a subtree no? Leaf::Punct(Punct { char: '{', spacing: Spacing::Alone, @@ -228,7 +225,6 @@ pub(crate) fn fixup_syntax( if it.match_arm_list().is_none() { // No match arms append.insert(node.clone().into(), vec![ - // FIXME: THis should be a subtree no? Leaf::Punct(Punct { char: '{', spacing: Spacing::Alone, @@ -269,7 +265,6 @@ pub(crate) fn fixup_syntax( if it.loop_body().is_none() { append.insert(node.clone().into(), vec![ - // FIXME: THis should be a subtree no? Leaf::Punct(Punct { char: '{', spacing: Spacing::Alone, @@ -309,28 +304,6 @@ pub(crate) fn fixup_syntax( } } }, - ast::ArgList(it) => { - if it.r_paren_token().is_none() { - append.insert(node.into(), vec![ - Leaf::Punct(Punct { - span: fake_span(node_range), - char: ')', - spacing: Spacing::Alone - }) - ]); - } - }, - ast::ArgList(it) => { - if it.r_paren_token().is_none() { - append.insert(node.into(), vec![ - Leaf::Punct(Punct { - span: fake_span(node_range), - char: ')', - spacing: Spacing::Alone - }) - ]); - } - }, ast::ClosureExpr(it) => { if it.body().is_none() { append.insert(node.into(), vec![ @@ -476,12 +449,12 @@ fn reverse_fixups_(tt: &mut TopSubtree, undo_info: &[TopSubtree]) { } } tt::TokenTree::Subtree(tt) => { + // fixup should only create matching delimiters, but proc macros + // could just copy the span to one of the delimiters. We don't want + // to leak the dummy ID, so we remove both. if tt.delimiter.close.anchor.ast_id == FIXUP_DUMMY_AST_ID || tt.delimiter.open.anchor.ast_id == FIXUP_DUMMY_AST_ID { - // Even though fixup never creates subtrees with fixup spans, the old proc-macro server - // might copy them if the proc-macro asks for it, so we need to filter those out - // here as well. return TransformTtAction::remove(); } TransformTtAction::Keep @@ -571,6 +544,17 @@ mod tests { parse.syntax_node() ); + // the fixed-up tree should not contain braces as punct + // FIXME: should probably instead check that it's a valid punctuation character + for x in tt.token_trees().flat_tokens() { + match x { + ::tt::TokenTree::Leaf(::tt::Leaf::Punct(punct)) => { + assert!(!matches!(punct.char, '{' | '}' | '(' | ')' | '[' | ']')) + } + _ => (), + } + } + reverse_fixups(&mut tt, &fixups.undo_info); // the fixed-up + reversed version should be equivalent to the original input @@ -596,7 +580,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {for _ in __ra_fixup { }} +fn foo () {for _ in __ra_fixup {}} "#]], ) } @@ -624,7 +608,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {for bar in qux { }} +fn foo () {for bar in qux {}} "#]], ) } @@ -655,7 +639,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {match __ra_fixup { }} +fn foo () {match __ra_fixup {}} "#]], ) } @@ -687,7 +671,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {match __ra_fixup { }} +fn foo () {match __ra_fixup {}} "#]], ) } @@ -802,7 +786,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {if a { }} +fn foo () {if a {}} "#]], ) } @@ -816,7 +800,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {if __ra_fixup { }} +fn foo () {if __ra_fixup {}} "#]], ) } @@ -830,7 +814,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {if __ra_fixup {} { }} +fn foo () {if __ra_fixup {} {}} "#]], ) } @@ -844,7 +828,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {while __ra_fixup { }} +fn foo () {while __ra_fixup {}} "#]], ) } @@ -858,7 +842,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {while foo { }} +fn foo () {while foo {}} "#]], ) } @@ -885,7 +869,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {loop { }} +fn foo () {loop {}} "#]], ) } @@ -941,7 +925,7 @@ fn foo() { } "#, expect![[r#" -fn foo () { foo ( a ) } +fn foo () {foo (a)} "#]], ); check( @@ -951,7 +935,7 @@ fn foo() { } "#, expect![[r#" -fn foo () { bar . foo ( a ) } +fn foo () {bar . foo (a)} "#]], ); } diff --git a/src/tools/rust-analyzer/crates/mbe/src/tests.rs b/src/tools/rust-analyzer/crates/mbe/src/tests.rs index fb68d35a4c84..4a73b6fa05a8 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/tests.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/tests.rs @@ -99,6 +99,23 @@ fn check( ); } +#[test] +fn unbalanced_brace() { + check( + Edition::CURRENT, + Edition::CURRENT, + r#" +() => { { } +"#, + r#""#, + expect![[r#" + SUBTREE $$ 1:0@0..0#2 1:0@0..0#2 + SUBTREE {} 0:0@9..10#2 0:0@11..12#2 + + {}"#]], + ); +} + #[test] fn token_mapping_smoke_test() { check( diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs index 19801c49e434..a59a3270c9d9 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs @@ -12,7 +12,7 @@ use syntax::{ SyntaxKind::{self, *}, SyntaxNode, SyntaxToken, SyntaxTreeBuilder, TextRange, TextSize, WalkEvent, T, }; -use tt::{buffer::Cursor, token_to_literal}; +use tt::{buffer::Cursor, token_to_literal, Punct}; pub mod prettify_macro_expansion; mod to_parser_input; @@ -217,8 +217,39 @@ where tt::TopSubtreeBuilder::new(tt::Delimiter::invisible_spanned(conv.call_site())); while let Some((token, abs_range)) = conv.bump() { - let delimiter = builder.expected_delimiter().map(|it| it.kind); let tt = match token.as_leaf() { + // These delimiters are not actually valid punctuation, but we produce them in syntax fixup. + // So we need to handle them specially here. + Some(&tt::Leaf::Punct(Punct { + char: char @ ('(' | ')' | '{' | '}' | '[' | ']'), + span, + spacing: _, + })) => { + let found_expected_delimiter = + builder.expected_delimiters().enumerate().find(|(_, delim)| match delim.kind { + tt::DelimiterKind::Parenthesis => char == ')', + tt::DelimiterKind::Brace => char == '}', + tt::DelimiterKind::Bracket => char == ']', + tt::DelimiterKind::Invisible => false, + }); + if let Some((idx, _)) = found_expected_delimiter { + for _ in 0..=idx { + builder.close(span); + } + continue; + } + + let delim = match char { + '(' => tt::DelimiterKind::Parenthesis, + '{' => tt::DelimiterKind::Brace, + '[' => tt::DelimiterKind::Bracket, + _ => panic!("unmatched closing delimiter from syntax fixup"), + }; + + // Start a new subtree + builder.open(delim, span); + continue; + } Some(leaf) => leaf.clone(), None => match token.kind(conv) { // Desugar doc comments into doc attributes @@ -228,17 +259,24 @@ where continue; } kind if kind.is_punct() && kind != UNDERSCORE => { - let expected = match delimiter { - Some(tt::DelimiterKind::Parenthesis) => Some(T![')']), - Some(tt::DelimiterKind::Brace) => Some(T!['}']), - Some(tt::DelimiterKind::Bracket) => Some(T![']']), - Some(tt::DelimiterKind::Invisible) | None => None, - }; + let found_expected_delimiter = + builder.expected_delimiters().enumerate().find(|(_, delim)| { + match delim.kind { + tt::DelimiterKind::Parenthesis => kind == T![')'], + tt::DelimiterKind::Brace => kind == T!['}'], + tt::DelimiterKind::Bracket => kind == T![']'], + tt::DelimiterKind::Invisible => false, + } + }); // Current token is a closing delimiter that we expect, fix up the closing span - // and end the subtree here - if matches!(expected, Some(expected) if expected == kind) { - builder.close(conv.span_for(abs_range)); + // and end the subtree here. + // We also close any open inner subtrees that might be missing their delimiter. + if let Some((idx, _)) = found_expected_delimiter { + for _ in 0..=idx { + // FIXME: record an error somewhere if we're closing more than one tree here? + builder.close(conv.span_for(abs_range)); + } continue; } @@ -262,6 +300,7 @@ where let Some(char) = token.to_char(conv) else { panic!("Token from lexer must be single char: token = {token:#?}") }; + // FIXME: this might still be an unmatched closing delimiter? Maybe we should assert here tt::Leaf::from(tt::Punct { char, spacing, span: conv.span_for(abs_range) }) } kind => { @@ -317,11 +356,10 @@ where builder.push(tt); } - // If we get here, we've consumed all input tokens. - // We might have more than one subtree in the stack, if the delimiters are improperly balanced. - // Merge them so we're left with one. - builder.flatten_unclosed_subtrees(); - + while builder.expected_delimiters().next().is_some() { + // FIXME: record an error somewhere? + builder.close(conv.call_site()); + } builder.build_skip_top_subtree() } diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 7705ba876e1a..1cfead54f192 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -243,8 +243,8 @@ impl TopSubtreeBuilder { self.token_trees.extend(tt.0.iter().cloned()); } - pub fn expected_delimiter(&self) -> Option<&Delimiter> { - self.unclosed_subtree_indices.last().map(|&subtree_idx| { + pub fn expected_delimiters(&self) -> impl Iterator> { + self.unclosed_subtree_indices.iter().rev().map(|&subtree_idx| { let TokenTree::Subtree(subtree) = &self.token_trees[subtree_idx] else { unreachable!("unclosed token tree is always a subtree") }; @@ -252,28 +252,6 @@ impl TopSubtreeBuilder { }) } - /// Converts unclosed subtree to a punct of their open delimiter. - // FIXME: This is incorrect to do, delimiters can never be puncts. See #18244. - pub fn flatten_unclosed_subtrees(&mut self) { - for &subtree_idx in &self.unclosed_subtree_indices { - let TokenTree::Subtree(subtree) = &self.token_trees[subtree_idx] else { - unreachable!("unclosed token tree is always a subtree") - }; - let char = match subtree.delimiter.kind { - DelimiterKind::Parenthesis => '(', - DelimiterKind::Brace => '{', - DelimiterKind::Bracket => '[', - DelimiterKind::Invisible => '$', - }; - self.token_trees[subtree_idx] = TokenTree::Leaf(Leaf::Punct(Punct { - char, - spacing: Spacing::Alone, - span: subtree.delimiter.open, - })); - } - self.unclosed_subtree_indices.clear(); - } - /// Builds, and remove the top subtree if it has only one subtree child. pub fn build_skip_top_subtree(mut self) -> TopSubtree { let top_tts = TokenTreesView::new(&self.token_trees[1..]); @@ -731,9 +709,9 @@ fn print_debug_subtree( }; write!(f, "{align}SUBTREE {delim} ",)?; - fmt::Debug::fmt(&open, f)?; + write!(f, "{:#?}", open)?; write!(f, " ")?; - fmt::Debug::fmt(&close, f)?; + write!(f, "{:#?}", close)?; for child in iter { writeln!(f)?; print_debug_token(f, level + 1, child)?; From fee83ba8527d595c155a05bf557cc00f743ade6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A8Florian?= <¨flodiebold@gmail.com¨> Date: Fri, 28 Feb 2025 18:03:53 +0100 Subject: [PATCH 843/991] Generated doc update --- src/tools/rust-analyzer/docs/book/src/assists_generated.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 918ae4a57944..a1433952e0ba 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -1070,7 +1070,7 @@ pub use foo::{Bar, Baz}; ### `expand_record_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L24) +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L26) Fills fields by replacing rest pattern in record patterns. @@ -1094,7 +1094,7 @@ fn foo(bar: Bar) { ### `expand_tuple_struct_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L80) +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L82) Fills fields by replacing rest pattern in tuple struct patterns. From 028aaa12b6936362f78fe553e820471c36a5a0f5 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 8 Mar 2025 15:28:26 +0300 Subject: [PATCH 844/991] skip `compile::Std` and `compile::Rustc` on `forced_compiler` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/tool.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 704feac54dec..96f2274a9d76 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -121,10 +121,18 @@ impl Step for ToolBuild { match self.mode { Mode::ToolRustc => { - builder.ensure(compile::Std::new(self.compiler, self.compiler.host)); - builder.ensure(compile::Rustc::new(self.compiler, target)); + // If compiler was forced, its artifacts should be prepared earlier. + if !self.compiler.is_forced_compiler() { + builder.ensure(compile::Std::new(self.compiler, self.compiler.host)); + builder.ensure(compile::Rustc::new(self.compiler, target)); + } + } + Mode::ToolStd => { + // If compiler was forced, its artifacts should be prepared earlier. + if !self.compiler.is_forced_compiler() { + builder.ensure(compile::Std::new(self.compiler, target)) + } } - Mode::ToolStd => builder.ensure(compile::Std::new(self.compiler, target)), Mode::ToolBootstrap => {} // uses downloaded stage0 compiler libs _ => panic!("unexpected Mode for tool build"), } From 5712d2e956e592bc4184e9c28cda9cfb5975a3db Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 16 Jan 2025 16:12:27 +0100 Subject: [PATCH 845/991] add a test for pointer casts involving un/re/wrapping trait objects the errors should not be there, this is a bug/missing feature. --- .../ui/cast/ptr-to-trait-obj-wrap-add-auto.rs | 40 +++++ .../ptr-to-trait-obj-wrap-add-auto.stderr | 113 ++++++++++++++ .../ptr-to-trait-obj-wrap-different-args.rs | 38 +++++ ...tr-to-trait-obj-wrap-different-args.stderr | 82 +++++++++++ ...ptr-to-trait-obj-wrap-different-regions.rs | 41 ++++++ ...to-trait-obj-wrap-different-regions.stderr | 139 ++++++++++++++++++ tests/ui/cast/ptr-to-trait-obj-wrap.rs | 36 +++++ tests/ui/cast/ptr-to-trait-obj-wrap.stderr | 57 +++++++ 8 files changed, 546 insertions(+) create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap.stderr diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs new file mode 100644 index 000000000000..2e5a9d0d3b58 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs @@ -0,0 +1,40 @@ +// Combination of `ptr-to-trait-obj-wrap.rs` and `ptr-to-trait-obj-add-auto.rs`. +// +// Checks that you *can't* add auto traits to trait object in pointer casts involving wrapping said +// traits structures. + +trait A {} + +struct W(T); +struct X(T); + +fn unwrap(a: *const W) -> *const (dyn A + Send) { + a as _ + //~^ error + //~| error + //~| error +} + +fn unwrap_nested(a: *const W>) -> *const W { + a as _ + //~^ error + //~| error + //~| error +} + +fn rewrap(a: *const W) -> *const X { + a as _ + //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast +} + +fn rewrap_nested(a: *const W>) -> *const W> { + a as _ + //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast +} + +fn wrap(a: *const dyn A) -> *const W { + a as _ + //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr new file mode 100644 index 000000000000..00a27156f077 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr @@ -0,0 +1,113 @@ +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:6:1 + | +LL | trait A {} + | ^^^^^^^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A + Send` + +error[E0277]: `(dyn A + 'static)` cannot be sent between threads safely + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 + | +LL | a as _ + | ^ `(dyn A + 'static)` cannot be sent between threads safely + | + = help: within `W<(dyn A + 'static)>`, the trait `Send` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A + Send` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A + Send` + +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:19:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:6:1 + | +LL | trait A {} + | ^^^^^^^ + = note: required for the cast from `*const W>` to `*const W` + +error[E0277]: `(dyn A + 'static)` cannot be sent between threads safely + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:19:5 + | +LL | a as _ + | ^ `(dyn A + 'static)` cannot be sent between threads safely + | + = help: within `W<(dyn A + 'static)>`, the trait `Send` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W>` to `*const W` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:19:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W>` to `*const W` + +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:26:5 + | +LL | a as _ + | ^^^^^^ unsupported cast + | + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound + +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:31:5 + | +LL | a as _ + | ^^^^^^ unsupported cast + | + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound + +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:36:5 + | +LL | a as _ + | ^^^^^^ unsupported cast + | + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0277, E0804. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs new file mode 100644 index 000000000000..55dc0aa184da --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs @@ -0,0 +1,38 @@ +// Combination of `ptr-to-trait-obj-different-args.rs` and `ptr-to-trait-obj-wrap.rs`. +// +// Checks that you *can't* change type arguments of trait objects in pointer casts involving +// wrapping said traits structures. + +trait A {} + +struct W(T); +struct X(T); + +fn unwrap(a: *const W>) -> *const dyn A { + a as _ + //~^ error + //~| error +} + +fn unwrap_nested(a: *const W>>) -> *const W> { + a as _ + //~^ error + //~| error +} + +fn rewrap(a: *const W>) -> *const X> { + a as _ + //~^ error: casting `*const W<(dyn A + 'static)>` as `*const X>` is invalid +} + +fn rewrap_nested(a: *const W>>) -> *const W>> { + a as _ + //~^ error: casting `*const W + 'static)>>` as `*const W>>` is invalid +} + +fn wrap(a: *const dyn A) -> *const W> { + a as _ + //~^ error: casting `*const (dyn A + 'static)` as `*const W>` is invalid +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr new file mode 100644 index 000000000000..59543229de7f --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr @@ -0,0 +1,82 @@ +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:12:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:6:1 + | +LL | trait A {} + | ^^^^^^^^^^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:12:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` + +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:18:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:6:1 + | +LL | trait A {} + | ^^^^^^^^^^ + = note: required for the cast from `*const W + 'static)>>` to `*const W>` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:18:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W + 'static)>>` to `*const W>` + +error[E0606]: casting `*const W<(dyn A + 'static)>` as `*const X>` is invalid + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:24:5 + | +LL | a as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error[E0606]: casting `*const W + 'static)>>` as `*const W>>` is invalid + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:29:5 + | +LL | a as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error[E0606]: casting `*const (dyn A + 'static)` as `*const W>` is invalid + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:34:5 + | +LL | a as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0277, E0606. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs new file mode 100644 index 000000000000..b0941277d01d --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs @@ -0,0 +1,41 @@ +// Combination of `ptr-to-trait-obj-different-regions-misc.rs` and `ptr-to-trait-obj-wrap.rs`. +// +// Checks that you *can't* change lifetime arguments of trait objects in pointer casts involving +// wrapping said traits structures. + +trait A<'a> {} + +struct W(T); +struct X(T); + +fn unwrap<'a, 'b>(a: *const W>) -> *const dyn A<'b> { + a as _ + //~^ error + //~| error +} + +fn unwrap_nested<'a, 'b>(a: *const W>>) -> *const W> { + a as _ + //~^ error + //~| error +} + +fn rewrap<'a, 'b>(a: *const W>) -> *const X> { + a as _ + //~^ error: lifetime may not live long enough + //~| error: lifetime may not live long enough +} + +fn rewrap_nested<'a, 'b>(a: *const W>>) -> *const W>> { + a as _ + //~^ error: lifetime may not live long enough + //~| error: lifetime may not live long enough +} + +fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W> { + a as _ + //~^ error: lifetime may not live long enough + //~| error: lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr new file mode 100644 index 000000000000..3d5fafea2eef --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr @@ -0,0 +1,139 @@ +error[E0277]: the trait bound `W<(dyn A<'a> + 'static)>: A<'b>` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5 + | +LL | a as _ + | ^ the trait `A<'b>` is not implemented for `W<(dyn A<'a> + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:6:1 + | +LL | trait A<'a> {} + | ^^^^^^^^^^^ + = note: required for the cast from `*const W<(dyn A<'a> + 'static)>` to `*const dyn A<'b>` + +error[E0277]: the size for values of type `(dyn A<'a> + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A<'a> + 'static)>`, the trait `Sized` is not implemented for `(dyn A<'a> + 'static)` +note: required because it appears within the type `W<(dyn A<'a> + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A<'a> + 'static)>` to `*const dyn A<'b>` + +error[E0277]: the trait bound `W<(dyn A<'a> + 'static)>: A<'b>` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5 + | +LL | a as _ + | ^ the trait `A<'b>` is not implemented for `W<(dyn A<'a> + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:6:1 + | +LL | trait A<'a> {} + | ^^^^^^^^^^^ + = note: required for the cast from `*const W + 'static)>>` to `*const W>` + +error[E0277]: the size for values of type `(dyn A<'a> + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A<'a> + 'static)>`, the trait `Sized` is not implemented for `(dyn A<'a> + 'static)` +note: required because it appears within the type `W<(dyn A<'a> + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:8:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W + 'static)>>` to `*const W>` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:24:5 + | +LL | fn rewrap<'a, 'b>(a: *const W>) -> *const X> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:24:5 + | +LL | fn rewrap<'a, 'b>(a: *const W>) -> *const X> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + +help: `'b` and `'a` must be the same: replace one with the other + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:30:5 + | +LL | fn rewrap_nested<'a, 'b>(a: *const W>>) -> *const W>> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:30:5 + | +LL | fn rewrap_nested<'a, 'b>(a: *const W>>) -> *const W>> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + +help: `'b` and `'a` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:36:5 + | +LL | fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:36:5 + | +LL | fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | a as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + +help: `'b` and `'a` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap.rs b/tests/ui/cast/ptr-to-trait-obj-wrap.rs new file mode 100644 index 000000000000..f45cedcab728 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap.rs @@ -0,0 +1,36 @@ +// Checks that various casts of pointers to trait objects wrapped in structures +// work. Note that the metadata doesn't change when a DST is wrapped in a +// structure, so these casts *are* fine. +// +// `unwrap` and `unwrap_nested` currently don't work due to a compiler limitation. + +trait A {} + +struct W(T); +struct X(T); + +fn unwrap(a: *const W) -> *const dyn A { + a as _ + //~^ error + //~| error +} + +fn unwrap_nested(a: *const W>) -> *const W { + a as _ + //~^ error + //~| error +} + +fn rewrap(a: *const W) -> *const X { + a as _ +} + +fn rewrap_nested(a: *const W>) -> *const W> { + a as _ +} + +fn wrap(a: *const dyn A) -> *const W { + a as _ +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap.stderr new file mode 100644 index 000000000000..3003363c04ab --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap.stderr @@ -0,0 +1,57 @@ +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap.rs:13:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap.rs:7:1 + | +LL | trait A {} + | ^^^^^^^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap.rs:13:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap.rs:9:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` + +error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied + --> $DIR/ptr-to-trait-obj-wrap.rs:19:5 + | +LL | a as _ + | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | +help: this trait has no implementations, consider adding one + --> $DIR/ptr-to-trait-obj-wrap.rs:7:1 + | +LL | trait A {} + | ^^^^^^^ + = note: required for the cast from `*const W>` to `*const W` + +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/ptr-to-trait-obj-wrap.rs:19:5 + | +LL | a as _ + | ^ doesn't have a size known at compile-time + | + = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` +note: required because it appears within the type `W<(dyn A + 'static)>` + --> $DIR/ptr-to-trait-obj-wrap.rs:9:8 + | +LL | struct W(T); + | ^ + = note: required for the cast from `*const W>` to `*const W` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. From b62d58f5415032291863d6b20654e86fcb7c4aea Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 16 Jan 2025 14:24:35 +0100 Subject: [PATCH 846/991] check that `UnsizeCoerce` may hold before trying unsizing coercion this prevents us from trying unsizing coercion in cases like `*const W` -> `*const dyn T`, where it would later cause a compilation error since `W: Sized` and `W: T` do not hold. --- compiler/rustc_hir_typeck/src/coercion.rs | 68 ++++++++++++++++++++--- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 67419fdf1c3e..d7b5c1ed5e15 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -41,8 +41,8 @@ use rustc_abi::ExternAbi; use rustc_attr_parsing::InlineAttr; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, struct_span_code_err}; -use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{self as hir, LangItem}; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::infer::relate::RelateResult; use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; @@ -56,7 +56,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::visit::TypeVisitableExt; -use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, AliasTy, GenericArgsRef, Ty, TyCtxt}; use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span}; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -593,6 +593,63 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Create an obligation for `Source: CoerceUnsized`. let cause = self.cause(self.cause.span, ObligationCauseCode::Coercion { source, target }); + let root_obligation = Obligation::new( + self.tcx, + cause.clone(), + self.fcx.param_env, + ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target]), + ); + + // If the root `Source: CoerceUnsized` obligation can't possibly hold, + // we don't have to assume that this is unsizing coercion (it will always lead to an error) + // + // However, we don't want to bail early all the time, since the unholdable obligations + // may be interesting for diagnostics (such as trying to coerce `&T` to `&dyn Id`), + // so we only bail if there (likely) is another way to convert the types. + if !self.infcx.predicate_may_hold(&root_obligation) { + if let Some(dyn_metadata_adt_def_id) = self.tcx.lang_items().get(LangItem::DynMetadata) + && let Some(metadata_type_def_id) = self.tcx.lang_items().get(LangItem::Metadata) + { + self.probe(|_| { + let ocx = ObligationCtxt::new(&self.infcx); + + // returns `true` if `::Metadata` is `DynMetadata<_>` + let has_dyn_trait_metadata = |ty| { + let metadata_ty: Result<_, _> = ocx.structurally_normalize_ty( + &ObligationCause::dummy(), + self.fcx.param_env, + Ty::new_alias( + self.tcx, + ty::AliasTyKind::Projection, + AliasTy::new(self.tcx, metadata_type_def_id, [ty]), + ), + ); + + metadata_ty.is_ok_and(|metadata_ty| { + metadata_ty + .ty_adt_def() + .is_some_and(|d| d.did() == dyn_metadata_adt_def_id) + }) + }; + + // If both types are raw pointers to a (wrapper over a) trait object, + // this might be a cast like `*const W -> *const dyn Trait`. + // So it's better to bail and try that. (even if the cast is not possible, for + // example due to vtables not matching, cast diagnostic will likely still be better) + // + // N.B. use `target`, not `coerce_target` (the latter is a var) + if let &ty::RawPtr(source_pointee, _) = coerce_source.kind() + && let &ty::RawPtr(target_pointee, _) = target.kind() + && has_dyn_trait_metadata(source_pointee) + && has_dyn_trait_metadata(target_pointee) + { + return Err(TypeError::Mismatch); + } + + Ok(()) + })?; + } + } // Use a FIFO queue for this custom fulfillment procedure. // @@ -601,12 +658,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // and almost never more than 3. By using a SmallVec we avoid an // allocation, at the (very small) cost of (occasionally) having to // shift subsequent elements down when removing the front element. - let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![Obligation::new( - self.tcx, - cause, - self.fcx.param_env, - ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target]) - )]; + let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![root_obligation]; // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where From 80157a560f3b139e0209d358ef275a84bccd99ed Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Fri, 17 Jan 2025 14:57:22 +0100 Subject: [PATCH 847/991] bless tests yay, I fixed the bug/missing feature :') --- .../ui/cast/ptr-to-trait-obj-wrap-add-auto.rs | 8 +- .../ptr-to-trait-obj-wrap-add-auto.stderr | 111 ++++-------------- .../ptr-to-trait-obj-wrap-different-args.rs | 6 +- ...tr-to-trait-obj-wrap-different-args.stderr | 63 ++-------- ...to-trait-obj-wrap-different-regions.stderr | 69 +++++------ tests/ui/cast/ptr-to-trait-obj-wrap.rs | 5 +- tests/ui/cast/ptr-to-trait-obj-wrap.stderr | 57 --------- 7 files changed, 75 insertions(+), 244 deletions(-) delete mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap.stderr diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs index 2e5a9d0d3b58..cfc0a97989dc 100644 --- a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs @@ -10,16 +10,12 @@ struct X(T); fn unwrap(a: *const W) -> *const (dyn A + Send) { a as _ - //~^ error - //~| error - //~| error + //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast } fn unwrap_nested(a: *const W>) -> *const W { a as _ - //~^ error - //~| error - //~| error + //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast } fn rewrap(a: *const W) -> *const X { diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr index 00a27156f077..42cdbc34ee82 100644 --- a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr @@ -1,87 +1,5 @@ -error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 - | -LL | a as _ - | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` - | -help: this trait has no implementations, consider adding one - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:6:1 - | -LL | trait A {} - | ^^^^^^^ - = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A + Send` - -error[E0277]: `(dyn A + 'static)` cannot be sent between threads safely - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 - | -LL | a as _ - | ^ `(dyn A + 'static)` cannot be sent between threads safely - | - = help: within `W<(dyn A + 'static)>`, the trait `Send` is not implemented for `(dyn A + 'static)` -note: required because it appears within the type `W<(dyn A + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 - | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A + Send` - -error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 - | -LL | a as _ - | ^ doesn't have a size known at compile-time - | - = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` -note: required because it appears within the type `W<(dyn A + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 - | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A + Send` - -error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:19:5 - | -LL | a as _ - | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` - | -help: this trait has no implementations, consider adding one - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:6:1 - | -LL | trait A {} - | ^^^^^^^ - = note: required for the cast from `*const W>` to `*const W` - -error[E0277]: `(dyn A + 'static)` cannot be sent between threads safely - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:19:5 - | -LL | a as _ - | ^ `(dyn A + 'static)` cannot be sent between threads safely - | - = help: within `W<(dyn A + 'static)>`, the trait `Send` is not implemented for `(dyn A + 'static)` -note: required because it appears within the type `W<(dyn A + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 - | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W>` to `*const W` - -error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:19:5 - | -LL | a as _ - | ^ doesn't have a size known at compile-time - | - = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` -note: required because it appears within the type `W<(dyn A + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:8:8 - | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W>` to `*const W` - error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:26:5 + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5 | LL | a as _ | ^^^^^^ unsupported cast @@ -90,7 +8,7 @@ LL | a as _ = help: use `transmute` if you're sure this is sound error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:31:5 + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:17:5 | LL | a as _ | ^^^^^^ unsupported cast @@ -99,7 +17,7 @@ LL | a as _ = help: use `transmute` if you're sure this is sound error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast - --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:36:5 + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:22:5 | LL | a as _ | ^^^^^^ unsupported cast @@ -107,7 +25,24 @@ LL | a as _ = note: this could allow UB elsewhere = help: use `transmute` if you're sure this is sound -error: aborting due to 9 previous errors +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:27:5 + | +LL | a as _ + | ^^^^^^ unsupported cast + | + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound -Some errors have detailed explanations: E0277, E0804. -For more information about an error, try `rustc --explain E0277`. +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:32:5 + | +LL | a as _ + | ^^^^^^ unsupported cast + | + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0804`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs index 55dc0aa184da..ebe7a06a7a15 100644 --- a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs @@ -10,14 +10,12 @@ struct X(T); fn unwrap(a: *const W>) -> *const dyn A { a as _ - //~^ error - //~| error + //~^ error casting `*const W<(dyn A + 'static)>` as `*const dyn A` is invalid } fn unwrap_nested(a: *const W>>) -> *const W> { a as _ - //~^ error - //~| error + //~^ error casting `*const W + 'static)>>` as `*const W>` is invalid } fn rewrap(a: *const W>) -> *const X> { diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr index 59543229de7f..4f85b208d05a 100644 --- a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr @@ -1,59 +1,21 @@ -error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied +error[E0606]: casting `*const W<(dyn A + 'static)>` as `*const dyn A` is invalid --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:12:5 | LL | a as _ - | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` + | ^^^^^^ | -help: this trait has no implementations, consider adding one - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:6:1 - | -LL | trait A {} - | ^^^^^^^^^^ - = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` + = note: the trait objects may have different vtables -error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:12:5 +error[E0606]: casting `*const W + 'static)>>` as `*const W>` is invalid + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:17:5 | LL | a as _ - | ^ doesn't have a size known at compile-time + | ^^^^^^ | - = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` -note: required because it appears within the type `W<(dyn A + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:8:8 - | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` - -error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:18:5 - | -LL | a as _ - | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` - | -help: this trait has no implementations, consider adding one - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:6:1 - | -LL | trait A {} - | ^^^^^^^^^^ - = note: required for the cast from `*const W + 'static)>>` to `*const W>` - -error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:18:5 - | -LL | a as _ - | ^ doesn't have a size known at compile-time - | - = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` -note: required because it appears within the type `W<(dyn A + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:8:8 - | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W + 'static)>>` to `*const W>` + = note: the trait objects may have different vtables error[E0606]: casting `*const W<(dyn A + 'static)>` as `*const X>` is invalid - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:24:5 + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:22:5 | LL | a as _ | ^^^^^^ @@ -61,7 +23,7 @@ LL | a as _ = note: the trait objects may have different vtables error[E0606]: casting `*const W + 'static)>>` as `*const W>>` is invalid - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:29:5 + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:27:5 | LL | a as _ | ^^^^^^ @@ -69,14 +31,13 @@ LL | a as _ = note: the trait objects may have different vtables error[E0606]: casting `*const (dyn A + 'static)` as `*const W>` is invalid - --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:34:5 + --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:32:5 | LL | a as _ | ^^^^^^ | = note: the trait objects may have different vtables -error: aborting due to 7 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0606. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0606`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr index 3d5fafea2eef..17a0ca3c34fc 100644 --- a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr @@ -1,56 +1,56 @@ -error[E0277]: the trait bound `W<(dyn A<'a> + 'static)>: A<'b>` is not satisfied +error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5 | +LL | fn unwrap<'a, 'b>(a: *const W>) -> *const dyn A<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here LL | a as _ - | ^ the trait `A<'b>` is not implemented for `W<(dyn A<'a> + 'static)>` + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | -help: this trait has no implementations, consider adding one - --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:6:1 - | -LL | trait A<'a> {} - | ^^^^^^^^^^^ - = note: required for the cast from `*const W<(dyn A<'a> + 'static)>` to `*const dyn A<'b>` + = help: consider adding the following bound: `'b: 'a` -error[E0277]: the size for values of type `(dyn A<'a> + 'static)` cannot be known at compilation time +error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5 | +LL | fn unwrap<'a, 'b>(a: *const W>) -> *const dyn A<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here LL | a as _ - | ^ doesn't have a size known at compile-time + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | - = help: within `W<(dyn A<'a> + 'static)>`, the trait `Sized` is not implemented for `(dyn A<'a> + 'static)` -note: required because it appears within the type `W<(dyn A<'a> + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:8:8 - | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W<(dyn A<'a> + 'static)>` to `*const dyn A<'b>` + = help: consider adding the following bound: `'a: 'b` -error[E0277]: the trait bound `W<(dyn A<'a> + 'static)>: A<'b>` is not satisfied +help: `'b` and `'a` must be the same: replace one with the other + +error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5 | +LL | fn unwrap_nested<'a, 'b>(a: *const W>>) -> *const W> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here LL | a as _ - | ^ the trait `A<'b>` is not implemented for `W<(dyn A<'a> + 'static)>` + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | -help: this trait has no implementations, consider adding one - --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:6:1 - | -LL | trait A<'a> {} - | ^^^^^^^^^^^ - = note: required for the cast from `*const W + 'static)>>` to `*const W>` + = help: consider adding the following bound: `'b: 'a` -error[E0277]: the size for values of type `(dyn A<'a> + 'static)` cannot be known at compilation time +error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5 | +LL | fn unwrap_nested<'a, 'b>(a: *const W>>) -> *const W> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here LL | a as _ - | ^ doesn't have a size known at compile-time + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | - = help: within `W<(dyn A<'a> + 'static)>`, the trait `Sized` is not implemented for `(dyn A<'a> + 'static)` -note: required because it appears within the type `W<(dyn A<'a> + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:8:8 + = help: consider adding the following bound: `'a: 'b` + +help: `'b` and `'a` must be the same: replace one with the other | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W + 'static)>>` to `*const W>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:24:5 @@ -77,6 +77,8 @@ LL | a as _ = help: consider adding the following bound: `'a: 'b` help: `'b` and `'a` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:30:5 @@ -136,4 +138,3 @@ help: `'b` and `'a` must be the same: replace one with the other error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap.rs b/tests/ui/cast/ptr-to-trait-obj-wrap.rs index f45cedcab728..6f9f6bddb996 100644 --- a/tests/ui/cast/ptr-to-trait-obj-wrap.rs +++ b/tests/ui/cast/ptr-to-trait-obj-wrap.rs @@ -3,6 +3,7 @@ // structure, so these casts *are* fine. // // `unwrap` and `unwrap_nested` currently don't work due to a compiler limitation. +//@ check-pass trait A {} @@ -11,14 +12,10 @@ struct X(T); fn unwrap(a: *const W) -> *const dyn A { a as _ - //~^ error - //~| error } fn unwrap_nested(a: *const W>) -> *const W { a as _ - //~^ error - //~| error } fn rewrap(a: *const W) -> *const X { diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap.stderr deleted file mode 100644 index 3003363c04ab..000000000000 --- a/tests/ui/cast/ptr-to-trait-obj-wrap.stderr +++ /dev/null @@ -1,57 +0,0 @@ -error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied - --> $DIR/ptr-to-trait-obj-wrap.rs:13:5 - | -LL | a as _ - | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` - | -help: this trait has no implementations, consider adding one - --> $DIR/ptr-to-trait-obj-wrap.rs:7:1 - | -LL | trait A {} - | ^^^^^^^ - = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` - -error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time - --> $DIR/ptr-to-trait-obj-wrap.rs:13:5 - | -LL | a as _ - | ^ doesn't have a size known at compile-time - | - = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` -note: required because it appears within the type `W<(dyn A + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap.rs:9:8 - | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W<(dyn A + 'static)>` to `*const dyn A` - -error[E0277]: the trait bound `W<(dyn A + 'static)>: A` is not satisfied - --> $DIR/ptr-to-trait-obj-wrap.rs:19:5 - | -LL | a as _ - | ^ the trait `A` is not implemented for `W<(dyn A + 'static)>` - | -help: this trait has no implementations, consider adding one - --> $DIR/ptr-to-trait-obj-wrap.rs:7:1 - | -LL | trait A {} - | ^^^^^^^ - = note: required for the cast from `*const W>` to `*const W` - -error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time - --> $DIR/ptr-to-trait-obj-wrap.rs:19:5 - | -LL | a as _ - | ^ doesn't have a size known at compile-time - | - = help: within `W<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` -note: required because it appears within the type `W<(dyn A + 'static)>` - --> $DIR/ptr-to-trait-obj-wrap.rs:9:8 - | -LL | struct W(T); - | ^ - = note: required for the cast from `*const W>` to `*const W` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0277`. From 8d37f38873fb374371bcd582f9ab29f223ce5d5a Mon Sep 17 00:00:00 2001 From: Tobias Decking Date: Sat, 8 Mar 2025 14:40:56 +0100 Subject: [PATCH 848/991] Use `disjoint_bitor` inside `borrowing_sub` --- library/core/src/num/uint_macros.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index d8709d51cccb..586892758398 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2533,15 +2533,20 @@ macro_rules! uint_impl { #[doc = concat!("assert_eq!((diff1, diff0), (3, ", stringify!($SelfT), "::MAX));")] /// ``` #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) { // note: longer-term this should be done via an intrinsic, but this has been shown // to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic - let (a, b) = self.overflowing_sub(rhs); - let (c, d) = a.overflowing_sub(borrow as $SelfT); - (c, b | d) + let (a, c1) = self.overflowing_sub(rhs); + let (b, c2) = a.overflowing_sub(borrow as $SelfT); + // SAFETY: Only one of `c1` and `c2` can be set. + // For c1 to be set we need to have underflowed, but if we did then + // `a` is nonzero, which means that `c2` cannot possibly + // underflow because it's subtracting at most `1` (since it came from `bool`) + (b, unsafe { intrinsics::disjoint_bitor(c1, c2) }) } /// Calculates `self` - `rhs` with a signed `rhs` From 08530d3e99dd84eb0a32a00168a11cab44d70118 Mon Sep 17 00:00:00 2001 From: Moulins Date: Fri, 7 Mar 2025 22:13:22 +0100 Subject: [PATCH 849/991] Move coroutine layout logic to `rustc_abi` --- compiler/rustc_abi/src/layout.rs | 30 ++ compiler/rustc_abi/src/layout/coroutine.rs | 320 ++++++++++++++++++ compiler/rustc_ty_utils/src/layout.rs | 357 ++------------------- 3 files changed, 373 insertions(+), 334 deletions(-) create mode 100644 compiler/rustc_abi/src/layout/coroutine.rs diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index d0d7cc68a77a..7bffeaf4cc9e 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -4,6 +4,7 @@ use std::{cmp, iter}; use rustc_hashes::Hash64; use rustc_index::Idx; +use rustc_index::bit_set::BitMatrix; use tracing::debug; use crate::{ @@ -12,6 +13,7 @@ use crate::{ Variants, WrappingRange, }; +mod coroutine; mod simple; #[cfg(feature = "nightly")] @@ -200,6 +202,34 @@ impl LayoutCalculator { }) } + /// Compute the layout for a coroutine. + /// + /// This uses dedicated code instead of [`Self::layout_of_struct_or_enum`], as coroutine + /// fields may be shared between multiple variants (see the [`coroutine`] module for details). + pub fn coroutine< + 'a, + F: Deref> + fmt::Debug + Copy, + VariantIdx: Idx, + FieldIdx: Idx, + LocalIdx: Idx, + >( + &self, + local_layouts: &IndexSlice, + prefix_layouts: IndexVec, + variant_fields: &IndexSlice>, + storage_conflicts: &BitMatrix, + tag_to_layout: impl Fn(Scalar) -> F, + ) -> LayoutCalculatorResult { + coroutine::layout( + self, + local_layouts, + prefix_layouts, + variant_fields, + storage_conflicts, + tag_to_layout, + ) + } + pub fn univariant< 'a, FieldIdx: Idx, diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs new file mode 100644 index 000000000000..27e704d538c8 --- /dev/null +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -0,0 +1,320 @@ +//! Coroutine layout logic. +//! +//! When laying out coroutines, we divide our saved local fields into two +//! categories: overlap-eligible and overlap-ineligible. +//! +//! Those fields which are ineligible for overlap go in a "prefix" at the +//! beginning of the layout, and always have space reserved for them. +//! +//! Overlap-eligible fields are only assigned to one variant, so we lay +//! those fields out for each variant and put them right after the +//! prefix. +//! +//! Finally, in the layout details, we point to the fields from the +//! variants they are assigned to. It is possible for some fields to be +//! included in multiple variants. No field ever "moves around" in the +//! layout; its offset is always the same. +//! +//! Also included in the layout are the upvars and the discriminant. +//! These are included as fields on the "outer" layout; they are not part +//! of any variant. + +use std::iter; + +use rustc_index::bit_set::{BitMatrix, DenseBitSet}; +use rustc_index::{Idx, IndexSlice, IndexVec}; +use tracing::{debug, trace}; + +use crate::{ + BackendRepr, FieldsShape, HasDataLayout, Integer, LayoutData, Primitive, ReprOptions, Scalar, + StructKind, TagEncoding, Variants, WrappingRange, +}; + +/// Overlap eligibility and variant assignment for each CoroutineSavedLocal. +#[derive(Clone, Debug, PartialEq)] +enum SavedLocalEligibility { + Unassigned, + Assigned(VariantIdx), + Ineligible(Option), +} + +/// Compute the eligibility and assignment of each local. +fn coroutine_saved_local_eligibility( + nb_locals: usize, + variant_fields: &IndexSlice>, + storage_conflicts: &BitMatrix, +) -> (DenseBitSet, IndexVec>) { + use SavedLocalEligibility::*; + + let mut assignments: IndexVec = IndexVec::from_elem_n(Unassigned, nb_locals); + + // The saved locals not eligible for overlap. These will get + // "promoted" to the prefix of our coroutine. + let mut ineligible_locals = DenseBitSet::new_empty(nb_locals); + + // Figure out which of our saved locals are fields in only + // one variant. The rest are deemed ineligible for overlap. + for (variant_index, fields) in variant_fields.iter_enumerated() { + for local in fields { + match assignments[*local] { + Unassigned => { + assignments[*local] = Assigned(variant_index); + } + Assigned(idx) => { + // We've already seen this local at another suspension + // point, so it is no longer a candidate. + trace!( + "removing local {:?} in >1 variant ({:?}, {:?})", + local, variant_index, idx + ); + ineligible_locals.insert(*local); + assignments[*local] = Ineligible(None); + } + Ineligible(_) => {} + } + } + } + + // Next, check every pair of eligible locals to see if they + // conflict. + for local_a in storage_conflicts.rows() { + let conflicts_a = storage_conflicts.count(local_a); + if ineligible_locals.contains(local_a) { + continue; + } + + for local_b in storage_conflicts.iter(local_a) { + // local_a and local_b are storage live at the same time, therefore they + // cannot overlap in the coroutine layout. The only way to guarantee + // this is if they are in the same variant, or one is ineligible + // (which means it is stored in every variant). + if ineligible_locals.contains(local_b) || assignments[local_a] == assignments[local_b] { + continue; + } + + // If they conflict, we will choose one to make ineligible. + // This is not always optimal; it's just a greedy heuristic that + // seems to produce good results most of the time. + let conflicts_b = storage_conflicts.count(local_b); + let (remove, other) = + if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) }; + ineligible_locals.insert(remove); + assignments[remove] = Ineligible(None); + trace!("removing local {:?} due to conflict with {:?}", remove, other); + } + } + + // Count the number of variants in use. If only one of them, then it is + // impossible to overlap any locals in our layout. In this case it's + // always better to make the remaining locals ineligible, so we can + // lay them out with the other locals in the prefix and eliminate + // unnecessary padding bytes. + { + let mut used_variants = DenseBitSet::new_empty(variant_fields.len()); + for assignment in &assignments { + if let Assigned(idx) = assignment { + used_variants.insert(*idx); + } + } + if used_variants.count() < 2 { + for assignment in assignments.iter_mut() { + *assignment = Ineligible(None); + } + ineligible_locals.insert_all(); + } + } + + // Write down the order of our locals that will be promoted to the prefix. + { + for (idx, local) in ineligible_locals.iter().enumerate() { + assignments[local] = Ineligible(Some(FieldIdx::new(idx))); + } + } + debug!("coroutine saved local assignments: {:?}", assignments); + + (ineligible_locals, assignments) +} + +/// Compute the full coroutine layout. +pub(super) fn layout< + 'a, + F: core::ops::Deref> + core::fmt::Debug + Copy, + VariantIdx: Idx, + FieldIdx: Idx, + LocalIdx: Idx, +>( + calc: &super::LayoutCalculator, + local_layouts: &IndexSlice, + mut prefix_layouts: IndexVec, + variant_fields: &IndexSlice>, + storage_conflicts: &BitMatrix, + tag_to_layout: impl Fn(Scalar) -> F, +) -> super::LayoutCalculatorResult { + use SavedLocalEligibility::*; + + let (ineligible_locals, assignments) = + coroutine_saved_local_eligibility(local_layouts.len(), variant_fields, storage_conflicts); + + // Build a prefix layout, including "promoting" all ineligible + // locals as part of the prefix. We compute the layout of all of + // these fields at once to get optimal packing. + let tag_index = prefix_layouts.len(); + + // `variant_fields` already accounts for the reserved variants, so no need to add them. + let max_discr = (variant_fields.len() - 1) as u128; + let discr_int = Integer::fit_unsigned(max_discr); + let tag = Scalar::Initialized { + value: Primitive::Int(discr_int, /* signed = */ false), + valid_range: WrappingRange { start: 0, end: max_discr }, + }; + + let promoted_layouts = ineligible_locals.iter().map(|local| local_layouts[local]); + prefix_layouts.push(tag_to_layout(tag)); + prefix_layouts.extend(promoted_layouts); + let prefix = + calc.univariant(&prefix_layouts, &ReprOptions::default(), StructKind::AlwaysSized)?; + + let (prefix_size, prefix_align) = (prefix.size, prefix.align); + + // Split the prefix layout into the "outer" fields (upvars and + // discriminant) and the "promoted" fields. Promoted fields will + // get included in each variant that requested them in + // CoroutineLayout. + debug!("prefix = {:#?}", prefix); + let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields { + FieldsShape::Arbitrary { mut offsets, memory_index } => { + let mut inverse_memory_index = memory_index.invert_bijective_mapping(); + + // "a" (`0..b_start`) and "b" (`b_start..`) correspond to + // "outer" and "promoted" fields respectively. + let b_start = FieldIdx::new(tag_index + 1); + let offsets_b = IndexVec::from_raw(offsets.raw.split_off(b_start.index())); + let offsets_a = offsets; + + // Disentangle the "a" and "b" components of `inverse_memory_index` + // by preserving the order but keeping only one disjoint "half" each. + // FIXME(eddyb) build a better abstraction for permutations, if possible. + let inverse_memory_index_b: IndexVec = inverse_memory_index + .iter() + .filter_map(|&i| i.index().checked_sub(b_start.index()).map(FieldIdx::new)) + .collect(); + inverse_memory_index.raw.retain(|&i| i.index() < b_start.index()); + let inverse_memory_index_a = inverse_memory_index; + + // Since `inverse_memory_index_{a,b}` each only refer to their + // respective fields, they can be safely inverted + let memory_index_a = inverse_memory_index_a.invert_bijective_mapping(); + let memory_index_b = inverse_memory_index_b.invert_bijective_mapping(); + + let outer_fields = + FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a }; + (outer_fields, offsets_b, memory_index_b) + } + _ => unreachable!(), + }; + + let mut size = prefix.size; + let mut align = prefix.align; + let variants = variant_fields + .iter_enumerated() + .map(|(index, variant_fields)| { + // Only include overlap-eligible fields when we compute our variant layout. + let variant_only_tys = variant_fields + .iter() + .filter(|local| match assignments[**local] { + Unassigned => unreachable!(), + Assigned(v) if v == index => true, + Assigned(_) => unreachable!("assignment does not match variant"), + Ineligible(_) => false, + }) + .map(|local| local_layouts[*local]); + + let mut variant = calc.univariant( + &variant_only_tys.collect::>(), + &ReprOptions::default(), + StructKind::Prefixed(prefix_size, prefix_align.abi), + )?; + variant.variants = Variants::Single { index }; + + let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else { + unreachable!(); + }; + + // Now, stitch the promoted and variant-only fields back together in + // the order they are mentioned by our CoroutineLayout. + // Because we only use some subset (that can differ between variants) + // of the promoted fields, we can't just pick those elements of the + // `promoted_memory_index` (as we'd end up with gaps). + // So instead, we build an "inverse memory_index", as if all of the + // promoted fields were being used, but leave the elements not in the + // subset as `invalid_field_idx`, which we can filter out later to + // obtain a valid (bijective) mapping. + let invalid_field_idx = promoted_memory_index.len() + memory_index.len(); + let mut combined_inverse_memory_index = + IndexVec::from_elem_n(FieldIdx::new(invalid_field_idx), invalid_field_idx); + + let mut offsets_and_memory_index = iter::zip(offsets, memory_index); + let combined_offsets = variant_fields + .iter_enumerated() + .map(|(i, local)| { + let (offset, memory_index) = match assignments[*local] { + Unassigned => unreachable!(), + Assigned(_) => { + let (offset, memory_index) = offsets_and_memory_index.next().unwrap(); + (offset, promoted_memory_index.len() as u32 + memory_index) + } + Ineligible(field_idx) => { + let field_idx = field_idx.unwrap(); + (promoted_offsets[field_idx], promoted_memory_index[field_idx]) + } + }; + combined_inverse_memory_index[memory_index] = i; + offset + }) + .collect(); + + // Remove the unused slots and invert the mapping to obtain the + // combined `memory_index` (also see previous comment). + combined_inverse_memory_index.raw.retain(|&i| i.index() != invalid_field_idx); + let combined_memory_index = combined_inverse_memory_index.invert_bijective_mapping(); + + variant.fields = FieldsShape::Arbitrary { + offsets: combined_offsets, + memory_index: combined_memory_index, + }; + + size = size.max(variant.size); + align = align.max(variant.align); + Ok(variant) + }) + .collect::, _>>()?; + + size = size.align_to(align.abi); + + let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited()); + let abi = BackendRepr::Memory { sized: true }; + + Ok(LayoutData { + variants: Variants::Multiple { + tag, + tag_encoding: TagEncoding::Direct, + tag_field: tag_index, + variants, + }, + fields: outer_fields, + backend_repr: abi, + // Suppress niches inside coroutines. If the niche is inside a field that is aliased (due to + // self-referentiality), getting the discriminant can cause aliasing violations. + // `UnsafeCell` blocks niches for the same reason, but we don't yet have `UnsafePinned` that + // would do the same for us here. + // See , . + // FIXME: Remove when is implemented and aliased coroutine fields are wrapped in `UnsafePinned`. + largest_niche: None, + uninhabited, + size, + align, + max_repr_align: None, + unadjusted_abi_align: align.abi, + randomization_seed: Default::default(), + }) +} diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index efca395fe4ae..5a4bb2c95da6 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -1,17 +1,13 @@ -use std::fmt::Debug; -use std::iter; - use hir::def_id::DefId; use rustc_abi::Integer::{I8, I32}; use rustc_abi::Primitive::{self, Float, Int, Pointer}; use rustc_abi::{ - AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Integer, - Layout, LayoutCalculator, LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, - StructKind, TagEncoding, VariantIdx, Variants, WrappingRange, + AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Layout, + LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding, + VariantIdx, Variants, WrappingRange, }; use rustc_hashes::Hash64; -use rustc_index::bit_set::{BitMatrix, DenseBitSet}; -use rustc_index::{Idx, IndexSlice, IndexVec}; +use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ @@ -23,7 +19,7 @@ use rustc_middle::ty::{ }; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_span::{Symbol, sym}; -use tracing::{debug, instrument, trace}; +use tracing::{debug, instrument}; use {rustc_abi as abi, rustc_hir as hir}; use crate::errors::{NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType}; @@ -403,23 +399,24 @@ fn layout_of_uncached<'tcx>( .map(|ty| cx.layout_of(ty)) .try_collect::>()?; - let layout = coroutine_layout( - &cx.calc, - &local_layouts, - prefix_layouts, - &info.variant_fields, - &info.storage_conflicts, - |tag| TyAndLayout { - ty: tag.primitive().to_ty(tcx), - layout: tcx.mk_layout(LayoutData::scalar(cx, tag)), - }, - ) - .map(|mut layout| { - // this is similar to how ReprOptions populates its field_shuffle_seed - layout.randomization_seed = tcx.def_path_hash(def_id).0.to_smaller_hash(); - debug!("coroutine layout ({:?}): {:#?}", ty, layout); - layout - }); + let layout = cx + .calc + .coroutine( + &local_layouts, + prefix_layouts, + &info.variant_fields, + &info.storage_conflicts, + |tag| TyAndLayout { + ty: tag.primitive().to_ty(tcx), + layout: tcx.mk_layout(LayoutData::scalar(cx, tag)), + }, + ) + .map(|mut layout| { + // this is similar to how ReprOptions populates its field_shuffle_seed + layout.randomization_seed = tcx.def_path_hash(def_id).0.to_smaller_hash(); + debug!("coroutine layout ({:?}): {:#?}", ty, layout); + layout + }); map_layout(layout)? } @@ -614,314 +611,6 @@ fn layout_of_uncached<'tcx>( }) } -/// Overlap eligibility and variant assignment for each CoroutineSavedLocal. -#[derive(Clone, Debug, PartialEq)] -enum SavedLocalEligibility { - Unassigned, - Assigned(VariantIdx), - Ineligible(Option), -} - -// When laying out coroutines, we divide our saved local fields into two -// categories: overlap-eligible and overlap-ineligible. -// -// Those fields which are ineligible for overlap go in a "prefix" at the -// beginning of the layout, and always have space reserved for them. -// -// Overlap-eligible fields are only assigned to one variant, so we lay -// those fields out for each variant and put them right after the -// prefix. -// -// Finally, in the layout details, we point to the fields from the -// variants they are assigned to. It is possible for some fields to be -// included in multiple variants. No field ever "moves around" in the -// layout; its offset is always the same. -// -// Also included in the layout are the upvars and the discriminant. -// These are included as fields on the "outer" layout; they are not part -// of any variant. - -/// Compute the eligibility and assignment of each local. -fn coroutine_saved_local_eligibility( - nb_locals: usize, - variant_fields: &IndexSlice>, - storage_conflicts: &BitMatrix, -) -> (DenseBitSet, IndexVec>) { - use SavedLocalEligibility::*; - - let mut assignments: IndexVec = IndexVec::from_elem_n(Unassigned, nb_locals); - - // The saved locals not eligible for overlap. These will get - // "promoted" to the prefix of our coroutine. - let mut ineligible_locals = DenseBitSet::new_empty(nb_locals); - - // Figure out which of our saved locals are fields in only - // one variant. The rest are deemed ineligible for overlap. - for (variant_index, fields) in variant_fields.iter_enumerated() { - for local in fields { - match assignments[*local] { - Unassigned => { - assignments[*local] = Assigned(variant_index); - } - Assigned(idx) => { - // We've already seen this local at another suspension - // point, so it is no longer a candidate. - trace!( - "removing local {:?} in >1 variant ({:?}, {:?})", - local, variant_index, idx - ); - ineligible_locals.insert(*local); - assignments[*local] = Ineligible(None); - } - Ineligible(_) => {} - } - } - } - - // Next, check every pair of eligible locals to see if they - // conflict. - for local_a in storage_conflicts.rows() { - let conflicts_a = storage_conflicts.count(local_a); - if ineligible_locals.contains(local_a) { - continue; - } - - for local_b in storage_conflicts.iter(local_a) { - // local_a and local_b are storage live at the same time, therefore they - // cannot overlap in the coroutine layout. The only way to guarantee - // this is if they are in the same variant, or one is ineligible - // (which means it is stored in every variant). - if ineligible_locals.contains(local_b) || assignments[local_a] == assignments[local_b] { - continue; - } - - // If they conflict, we will choose one to make ineligible. - // This is not always optimal; it's just a greedy heuristic that - // seems to produce good results most of the time. - let conflicts_b = storage_conflicts.count(local_b); - let (remove, other) = - if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) }; - ineligible_locals.insert(remove); - assignments[remove] = Ineligible(None); - trace!("removing local {:?} due to conflict with {:?}", remove, other); - } - } - - // Count the number of variants in use. If only one of them, then it is - // impossible to overlap any locals in our layout. In this case it's - // always better to make the remaining locals ineligible, so we can - // lay them out with the other locals in the prefix and eliminate - // unnecessary padding bytes. - { - let mut used_variants = DenseBitSet::new_empty(variant_fields.len()); - for assignment in &assignments { - if let Assigned(idx) = assignment { - used_variants.insert(*idx); - } - } - if used_variants.count() < 2 { - for assignment in assignments.iter_mut() { - *assignment = Ineligible(None); - } - ineligible_locals.insert_all(); - } - } - - // Write down the order of our locals that will be promoted to the prefix. - { - for (idx, local) in ineligible_locals.iter().enumerate() { - assignments[local] = Ineligible(Some(FieldIdx::new(idx))); - } - } - debug!("coroutine saved local assignments: {:?}", assignments); - - (ineligible_locals, assignments) -} - -/// Compute the full coroutine layout. -fn coroutine_layout< - 'a, - F: core::ops::Deref> + core::fmt::Debug + Copy, - VariantIdx: Idx, - FieldIdx: Idx, - LocalIdx: Idx, ->( - calc: &LayoutCalculator, - local_layouts: &IndexSlice, - mut prefix_layouts: IndexVec, - variant_fields: &IndexSlice>, - storage_conflicts: &BitMatrix, - tag_to_layout: impl Fn(Scalar) -> F, -) -> Result, LayoutCalculatorError> { - use SavedLocalEligibility::*; - - let (ineligible_locals, assignments) = - coroutine_saved_local_eligibility(local_layouts.len(), variant_fields, storage_conflicts); - - // Build a prefix layout, including "promoting" all ineligible - // locals as part of the prefix. We compute the layout of all of - // these fields at once to get optimal packing. - let tag_index = prefix_layouts.len(); - - // `variant_fields` already accounts for the reserved variants, so no need to add them. - let max_discr = (variant_fields.len() - 1) as u128; - let discr_int = Integer::fit_unsigned(max_discr); - let tag = Scalar::Initialized { - value: Primitive::Int(discr_int, /* signed = */ false), - valid_range: WrappingRange { start: 0, end: max_discr }, - }; - - let promoted_layouts = ineligible_locals.iter().map(|local| local_layouts[local]); - prefix_layouts.push(tag_to_layout(tag)); - prefix_layouts.extend(promoted_layouts); - let prefix = - calc.univariant(&prefix_layouts, &ReprOptions::default(), StructKind::AlwaysSized)?; - - let (prefix_size, prefix_align) = (prefix.size, prefix.align); - - // Split the prefix layout into the "outer" fields (upvars and - // discriminant) and the "promoted" fields. Promoted fields will - // get included in each variant that requested them in - // CoroutineLayout. - debug!("prefix = {:#?}", prefix); - let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields { - FieldsShape::Arbitrary { mut offsets, memory_index } => { - let mut inverse_memory_index = memory_index.invert_bijective_mapping(); - - // "a" (`0..b_start`) and "b" (`b_start..`) correspond to - // "outer" and "promoted" fields respectively. - let b_start = FieldIdx::new(tag_index + 1); - let offsets_b = IndexVec::from_raw(offsets.raw.split_off(b_start.index())); - let offsets_a = offsets; - - // Disentangle the "a" and "b" components of `inverse_memory_index` - // by preserving the order but keeping only one disjoint "half" each. - // FIXME(eddyb) build a better abstraction for permutations, if possible. - let inverse_memory_index_b: IndexVec = inverse_memory_index - .iter() - .filter_map(|&i| i.index().checked_sub(b_start.index()).map(FieldIdx::new)) - .collect(); - inverse_memory_index.raw.retain(|&i| i.index() < b_start.index()); - let inverse_memory_index_a = inverse_memory_index; - - // Since `inverse_memory_index_{a,b}` each only refer to their - // respective fields, they can be safely inverted - let memory_index_a = inverse_memory_index_a.invert_bijective_mapping(); - let memory_index_b = inverse_memory_index_b.invert_bijective_mapping(); - - let outer_fields = - FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a }; - (outer_fields, offsets_b, memory_index_b) - } - _ => unreachable!(), - }; - - let mut size = prefix.size; - let mut align = prefix.align; - let variants = variant_fields - .iter_enumerated() - .map(|(index, variant_fields)| { - // Only include overlap-eligible fields when we compute our variant layout. - let variant_only_tys = variant_fields - .iter() - .filter(|local| match assignments[**local] { - Unassigned => unreachable!(), - Assigned(v) if v == index => true, - Assigned(_) => unreachable!("assignment does not match variant"), - Ineligible(_) => false, - }) - .map(|local| local_layouts[*local]); - - let mut variant = calc.univariant( - &variant_only_tys.collect::>(), - &ReprOptions::default(), - StructKind::Prefixed(prefix_size, prefix_align.abi), - )?; - variant.variants = Variants::Single { index }; - - let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else { - unreachable!(); - }; - - // Now, stitch the promoted and variant-only fields back together in - // the order they are mentioned by our CoroutineLayout. - // Because we only use some subset (that can differ between variants) - // of the promoted fields, we can't just pick those elements of the - // `promoted_memory_index` (as we'd end up with gaps). - // So instead, we build an "inverse memory_index", as if all of the - // promoted fields were being used, but leave the elements not in the - // subset as `invalid_field_idx`, which we can filter out later to - // obtain a valid (bijective) mapping. - let invalid_field_idx = promoted_memory_index.len() + memory_index.len(); - let mut combined_inverse_memory_index = - IndexVec::from_elem_n(FieldIdx::new(invalid_field_idx), invalid_field_idx); - - let mut offsets_and_memory_index = iter::zip(offsets, memory_index); - let combined_offsets = variant_fields - .iter_enumerated() - .map(|(i, local)| { - let (offset, memory_index) = match assignments[*local] { - Unassigned => unreachable!(), - Assigned(_) => { - let (offset, memory_index) = offsets_and_memory_index.next().unwrap(); - (offset, promoted_memory_index.len() as u32 + memory_index) - } - Ineligible(field_idx) => { - let field_idx = field_idx.unwrap(); - (promoted_offsets[field_idx], promoted_memory_index[field_idx]) - } - }; - combined_inverse_memory_index[memory_index] = i; - offset - }) - .collect(); - - // Remove the unused slots and invert the mapping to obtain the - // combined `memory_index` (also see previous comment). - combined_inverse_memory_index.raw.retain(|&i| i.index() != invalid_field_idx); - let combined_memory_index = combined_inverse_memory_index.invert_bijective_mapping(); - - variant.fields = FieldsShape::Arbitrary { - offsets: combined_offsets, - memory_index: combined_memory_index, - }; - - size = size.max(variant.size); - align = align.max(variant.align); - Ok(variant) - }) - .collect::, _>>()?; - - size = size.align_to(align.abi); - - let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited()); - let abi = BackendRepr::Memory { sized: true }; - - Ok(LayoutData { - variants: Variants::Multiple { - tag, - tag_encoding: TagEncoding::Direct, - tag_field: tag_index, - variants, - }, - fields: outer_fields, - backend_repr: abi, - // Suppress niches inside coroutines. If the niche is inside a field that is aliased (due to - // self-referentiality), getting the discriminant can cause aliasing violations. - // `UnsafeCell` blocks niches for the same reason, but we don't yet have `UnsafePinned` that - // would do the same for us here. - // See , . - // FIXME: Remove when is implemented and aliased coroutine fields are wrapped in `UnsafePinned`. - largest_niche: None, - uninhabited, - size, - align, - max_repr_align: None, - unadjusted_abi_align: align.abi, - randomization_seed: Default::default(), - }) -} - fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx>, layout: TyAndLayout<'tcx>) { // Ignore layouts that are done with non-empty environments or // non-monomorphic layouts, as the user only wants to see the stuff From 2cff733dc5e9c2d390c887ca5aefdc96e6c656e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 8 Mar 2025 16:47:32 +0100 Subject: [PATCH 850/991] Reduce verbosity of GCC build log --- src/bootstrap/src/core/build_steps/gcc.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index e8b6a577cea5..70789fbbeeba 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -125,6 +125,7 @@ impl Step for Gcc { t!(stamp.remove()); let _time = helpers::timeit(builder); t!(fs::create_dir_all(&out_dir)); + t!(fs::create_dir_all(&install_dir)); let libgccjit_path = libgccjit_built_path(&install_dir); if builder.config.dry_run() { @@ -185,8 +186,16 @@ impl Step for Gcc { } configure_cmd.run(builder); - command("make").current_dir(&out_dir).arg(format!("-j{}", builder.jobs())).run(builder); - command("make").current_dir(&out_dir).arg("install").run(builder); + command("make") + .current_dir(&out_dir) + .arg("--silent") + .arg(format!("-j{}", builder.jobs())) + .run_capture_stdout(builder); + command("make") + .current_dir(&out_dir) + .arg("--silent") + .arg("install") + .run_capture_stdout(builder); let lib_alias = install_dir.join("lib/libgccjit.so.0"); if !lib_alias.exists() { From 9278a3ebd6117b29e5c982bc5bb80d31dd353a1a Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Sat, 8 Mar 2025 10:55:47 -0500 Subject: [PATCH 851/991] Don't link against advapi32, except on win7. --- library/windows_targets/src/lib.rs | 2 +- src/bootstrap/src/core/build_steps/dist.rs | 1 - .../src/external_deps/c_cxx_compiler/extras.rs | 16 +++++++--------- src/tools/run-make-support/src/lib.rs | 2 +- src/tools/run-make-support/src/targets.rs | 6 ++++++ 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs index e89bde8b1abf..939fab7d5fe6 100644 --- a/library/windows_targets/src/lib.rs +++ b/library/windows_targets/src/lib.rs @@ -34,7 +34,7 @@ pub macro link { } #[cfg(not(feature = "windows_raw_dylib"))] -#[link(name = "advapi32")] +#[cfg_attr(target_vendor = "win7", link(name = "advapi32"))] #[link(name = "ntdll")] #[link(name = "userenv")] #[link(name = "ws2_32")] diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 0296346009f4..63deaf7f5351 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -232,7 +232,6 @@ fn make_win_dist( "libpthread.a", //Windows import libs //This should contain only the set of libraries necessary to link the standard library. - "libadvapi32.a", "libbcrypt.a", "libcomctl32.a", "libcomdlg32.a", diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs index ca6ab3275c4d..c03176338736 100644 --- a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs +++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs @@ -1,17 +1,15 @@ -use crate::{is_msvc, is_windows, uname}; +use crate::{is_msvc, is_win7, is_windows, uname}; /// `EXTRACFLAGS` pub fn extra_c_flags() -> Vec<&'static str> { if is_windows() { if is_msvc() { - vec![ - "ws2_32.lib", - "userenv.lib", - "advapi32.lib", - "bcrypt.lib", - "ntdll.lib", - "synchronization.lib", - ] + let mut libs = + vec!["ws2_32.lib", "userenv.lib", "bcrypt.lib", "ntdll.lib", "synchronization.lib"]; + if is_win7() { + libs.push("advapi32.lib"); + } + libs } else { vec!["-lws2_32", "-luserenv", "-lbcrypt", "-lntdll", "-lsynchronization"] } diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index c846a2d53e5f..e0ad3ee9beda 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -84,7 +84,7 @@ pub use run::{cmd, run, run_fail, run_with_args}; /// Helpers for checking target information. pub use targets::{ - apple_os, is_aix, is_darwin, is_msvc, is_windows, is_windows_gnu, llvm_components_contain, + apple_os, is_aix, is_darwin, is_msvc, is_windows, is_windows_gnu, is_win7, llvm_components_contain, target, uname, }; diff --git a/src/tools/run-make-support/src/targets.rs b/src/tools/run-make-support/src/targets.rs index a16fca71d2ee..86edbdf750bb 100644 --- a/src/tools/run-make-support/src/targets.rs +++ b/src/tools/run-make-support/src/targets.rs @@ -28,6 +28,12 @@ pub fn is_windows_gnu() -> bool { target().ends_with("windows-gnu") } +/// Check if target is win7. +#[must_use] +pub fn is_win7() -> bool { + target().contains("win7") +} + /// Check if target uses macOS. #[must_use] pub fn is_darwin() -> bool { From 50ea503d9db368d3e1fff98ea8bad3a53b5b502d Mon Sep 17 00:00:00 2001 From: Martin Habovstiak Date: Thu, 20 Feb 2025 17:04:36 +0100 Subject: [PATCH 852/991] Stabilize `const_vec_string_slice` This feature was approved for stabilization in https://github.com/rust-lang/rust/issues/129041#issuecomment-2508940661 so this change stabilizes it. --- library/alloc/src/string.rs | 17 +++++++++-------- library/alloc/src/vec/mod.rs | 14 +++++++------- tests/ui/consts/issue-94675.rs | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 2ba797ab2add..9236f5cb8d1f 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1043,7 +1043,8 @@ impl String { #[inline] #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn into_bytes(self) -> Vec { self.vec } @@ -1061,7 +1062,7 @@ impl String { #[must_use] #[stable(feature = "string_as_str", since = "1.7.0")] #[rustc_diagnostic_item = "string_as_str"] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn as_str(&self) -> &str { // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error // at construction. @@ -1084,7 +1085,7 @@ impl String { #[must_use] #[stable(feature = "string_as_str", since = "1.7.0")] #[rustc_diagnostic_item = "string_as_mut_str"] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn as_mut_str(&mut self) -> &mut str { // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error // at construction. @@ -1158,7 +1159,7 @@ impl String { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn capacity(&self) -> usize { self.vec.capacity() } @@ -1424,7 +1425,7 @@ impl String { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn as_bytes(&self) -> &[u8] { self.vec.as_slice() } @@ -1778,7 +1779,7 @@ impl String { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn as_mut_vec(&mut self) -> &mut Vec { &mut self.vec } @@ -1800,7 +1801,7 @@ impl String { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] #[rustc_confusables("length", "size")] pub const fn len(&self) -> usize { self.vec.len() @@ -1820,7 +1821,7 @@ impl String { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn is_empty(&self) -> bool { self.len() == 0 } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index ce6685405981..da9a77154f9b 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1254,7 +1254,7 @@ impl Vec { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn capacity(&self) -> usize { self.buf.capacity() } @@ -1569,7 +1569,7 @@ impl Vec { #[inline] #[stable(feature = "vec_as_slice", since = "1.7.0")] #[rustc_diagnostic_item = "vec_as_slice"] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn as_slice(&self) -> &[T] { // SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size // `len` containing properly-initialized `T`s. Data must not be mutated for the returned @@ -1601,7 +1601,7 @@ impl Vec { #[inline] #[stable(feature = "vec_as_slice", since = "1.7.0")] #[rustc_diagnostic_item = "vec_as_mut_slice"] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn as_mut_slice(&mut self) -> &mut [T] { // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of // size `len` containing properly-initialized `T`s. Data must not be accessed through any @@ -1673,7 +1673,7 @@ impl Vec { /// [`as_ptr`]: Vec::as_ptr /// [`as_non_null`]: Vec::as_non_null #[stable(feature = "vec_as_ptr", since = "1.37.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] #[rustc_never_returns_null_ptr] #[rustc_as_ptr] #[inline] @@ -1736,7 +1736,7 @@ impl Vec { /// [`as_ptr`]: Vec::as_ptr /// [`as_non_null`]: Vec::as_non_null #[stable(feature = "vec_as_ptr", since = "1.37.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] #[rustc_never_returns_null_ptr] #[rustc_as_ptr] #[inline] @@ -2687,7 +2687,7 @@ impl Vec { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] #[rustc_confusables("length", "size")] pub const fn len(&self) -> usize { let len = self.len; @@ -2713,7 +2713,7 @@ impl Vec { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "vec_is_empty"] - #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] + #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn is_empty(&self) -> bool { self.len() == 0 } diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs index e1c6861c5103..87c8b04452ba 100644 --- a/tests/ui/consts/issue-94675.rs +++ b/tests/ui/consts/issue-94675.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl, const_vec_string_slice)] +#![feature(const_trait_impl)] struct Foo<'a> { bar: &'a mut Vec, From 31e22c60b34b4e262e327b8dc448281f0fea9e9d Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Sat, 8 Mar 2025 11:56:41 -0500 Subject: [PATCH 853/991] re-add gnu lib and tweak comment --- src/bootstrap/src/core/build_steps/dist.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 63deaf7f5351..ec0edeab9968 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -230,8 +230,11 @@ fn make_win_dist( "libiconv.a", "libmoldname.a", "libpthread.a", - //Windows import libs - //This should contain only the set of libraries necessary to link the standard library. + // Windows import libs + // This *should* contain only the set of libraries necessary to link the standard library, + // however we've had problems with people accidentally depending on extra libs being here, + // so we can't easily remove entries. + "libadvapi32.a", "libbcrypt.a", "libcomctl32.a", "libcomdlg32.a", From 7bf4e9977ebfd1de31b3daea3cec327f61ee1685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 3 Mar 2025 10:34:26 +0100 Subject: [PATCH 854/991] Add test for garbage collection of encapsulation symbols --- .../ui/linking/no-gc-encapsulation-symbols.rs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/ui/linking/no-gc-encapsulation-symbols.rs diff --git a/tests/ui/linking/no-gc-encapsulation-symbols.rs b/tests/ui/linking/no-gc-encapsulation-symbols.rs new file mode 100644 index 000000000000..36d69969199c --- /dev/null +++ b/tests/ui/linking/no-gc-encapsulation-symbols.rs @@ -0,0 +1,25 @@ +// This test checks that encapsulation symbols are not garbage collected by the linker. +// LLD will remove them by default, so this test checks that we pass `-znostart-stop-gc` to LLD +// to avoid that behavior. Without that flag, the test should fail. +// This test is inspired by the behavior of the linkme crate. +// +//@ build-pass +//@ only-x86_64-unknown-linux-gnu + +unsafe extern "Rust" { + // The __start_ section name is magical for the linker, + // It will put link sections named EXTERNFNS after it. + #[link_name = "__start_EXTERNFNS"] + static SECTION_START: fn(); +} + +#[used] +#[unsafe(link_section = "EXTERNFNS")] +static EXTERN_FN_LOCAL: fn() = extern_fn; + +fn extern_fn() {} + +fn main() { + // We need to reference the SECTION_START symbol to avoid it being garbage collected + let slice = unsafe { SECTION_START }; +} From 088b125853d35b23768cba8bf53b52a69d00fd03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 7 Mar 2025 23:17:25 +0100 Subject: [PATCH 855/991] crashes: couple more tests --- tests/crashes/136138.rs | 7 +++++++ tests/crashes/136175-2.rs | 13 +++++++++++++ tests/crashes/136175.rs | 13 +++++++++++++ tests/crashes/136188.rs | 9 +++++++++ tests/crashes/136286.rs | 7 +++++++ tests/crashes/136379.rs | 11 +++++++++++ tests/crashes/136381.rs | 18 ++++++++++++++++++ tests/crashes/136416.rs | 6 ++++++ tests/crashes/136442.rs | 9 +++++++++ tests/crashes/136661.rs | 25 +++++++++++++++++++++++++ tests/crashes/136666.rs | 36 ++++++++++++++++++++++++++++++++++++ tests/crashes/136678.rs | 18 ++++++++++++++++++ tests/crashes/136766.rs | 6 ++++++ tests/crashes/136859.rs | 27 +++++++++++++++++++++++++++ tests/crashes/136894.rs | 8 ++++++++ tests/crashes/137049.rs | 29 +++++++++++++++++++++++++++++ tests/crashes/137084.rs | 6 ++++++ tests/crashes/137187.rs | 9 +++++++++ tests/crashes/137188.rs | 6 ++++++ tests/crashes/137190-1.rs | 10 ++++++++++ tests/crashes/137190-2.rs | 18 ++++++++++++++++++ tests/crashes/137190-3.rs | 10 ++++++++++ tests/crashes/137260.rs | 11 +++++++++++ tests/crashes/137287.rs | 29 +++++++++++++++++++++++++++++ tests/crashes/137467-1.rs | 17 +++++++++++++++++ tests/crashes/137467-2.rs | 18 ++++++++++++++++++ tests/crashes/137467-3.rs | 8 ++++++++ tests/crashes/137468.rs | 16 ++++++++++++++++ tests/crashes/137514.rs | 9 +++++++++ tests/crashes/137580.rs | 4 ++++ tests/crashes/137582.rs | 16 ++++++++++++++++ tests/crashes/137706.rs | 7 +++++++ tests/crashes/137751.rs | 6 ++++++ tests/crashes/137813.rs | 18 ++++++++++++++++++ tests/crashes/137865.rs | 5 +++++ tests/crashes/137874.rs | 4 ++++ tests/crashes/137888.rs | 11 +++++++++++ tests/crashes/137895.rs | 6 ++++++ tests/crashes/137916.rs | 13 +++++++++++++ tests/crashes/138008.rs | 8 ++++++++ tests/crashes/138009.rs | 6 ++++++ tests/crashes/138048.rs | 8 ++++++++ tests/crashes/138088.rs | 5 +++++ tests/crashes/138089.rs | 13 +++++++++++++ tests/crashes/138131.rs | 12 ++++++++++++ tests/crashes/138132.rs | 10 ++++++++++ tests/crashes/138166.rs | 8 ++++++++ 47 files changed, 569 insertions(+) create mode 100644 tests/crashes/136138.rs create mode 100644 tests/crashes/136175-2.rs create mode 100644 tests/crashes/136175.rs create mode 100644 tests/crashes/136188.rs create mode 100644 tests/crashes/136286.rs create mode 100644 tests/crashes/136379.rs create mode 100644 tests/crashes/136381.rs create mode 100644 tests/crashes/136416.rs create mode 100644 tests/crashes/136442.rs create mode 100644 tests/crashes/136661.rs create mode 100644 tests/crashes/136666.rs create mode 100644 tests/crashes/136678.rs create mode 100644 tests/crashes/136766.rs create mode 100644 tests/crashes/136859.rs create mode 100644 tests/crashes/136894.rs create mode 100644 tests/crashes/137049.rs create mode 100644 tests/crashes/137084.rs create mode 100644 tests/crashes/137187.rs create mode 100644 tests/crashes/137188.rs create mode 100644 tests/crashes/137190-1.rs create mode 100644 tests/crashes/137190-2.rs create mode 100644 tests/crashes/137190-3.rs create mode 100644 tests/crashes/137260.rs create mode 100644 tests/crashes/137287.rs create mode 100644 tests/crashes/137467-1.rs create mode 100644 tests/crashes/137467-2.rs create mode 100644 tests/crashes/137467-3.rs create mode 100644 tests/crashes/137468.rs create mode 100644 tests/crashes/137514.rs create mode 100644 tests/crashes/137580.rs create mode 100644 tests/crashes/137582.rs create mode 100644 tests/crashes/137706.rs create mode 100644 tests/crashes/137751.rs create mode 100644 tests/crashes/137813.rs create mode 100644 tests/crashes/137865.rs create mode 100644 tests/crashes/137874.rs create mode 100644 tests/crashes/137888.rs create mode 100644 tests/crashes/137895.rs create mode 100644 tests/crashes/137916.rs create mode 100644 tests/crashes/138008.rs create mode 100644 tests/crashes/138009.rs create mode 100644 tests/crashes/138048.rs create mode 100644 tests/crashes/138088.rs create mode 100644 tests/crashes/138089.rs create mode 100644 tests/crashes/138131.rs create mode 100644 tests/crashes/138132.rs create mode 100644 tests/crashes/138166.rs diff --git a/tests/crashes/136138.rs b/tests/crashes/136138.rs new file mode 100644 index 000000000000..c3893dc9c8e6 --- /dev/null +++ b/tests/crashes/136138.rs @@ -0,0 +1,7 @@ +//@ known-bug: #136138 +#![feature(min_generic_const_args)] +struct U; +struct S() +where + S<{ U }>:; +fn main() {} diff --git a/tests/crashes/136175-2.rs b/tests/crashes/136175-2.rs new file mode 100644 index 000000000000..28f8ff7fd1cd --- /dev/null +++ b/tests/crashes/136175-2.rs @@ -0,0 +1,13 @@ +//@ known-bug: #136175 +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait Trait {} + +struct A(T) +where + [(); std::mem::offset_of!((T,), 0)]:; + +fn main() { + let x: A; +} diff --git a/tests/crashes/136175.rs b/tests/crashes/136175.rs new file mode 100644 index 000000000000..0b5f2fdaa922 --- /dev/null +++ b/tests/crashes/136175.rs @@ -0,0 +1,13 @@ +//@ known-bug: #136175 +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait Trait {} + +struct A(T) +where + [(); size_of::()]:; + +fn main() { + let x: A; +} diff --git a/tests/crashes/136188.rs b/tests/crashes/136188.rs new file mode 100644 index 000000000000..a701fc4c0b74 --- /dev/null +++ b/tests/crashes/136188.rs @@ -0,0 +1,9 @@ +//@ known-bug: #136188 +//@ compile-flags: --crate-type=lib -Znext-solver +#![feature(type_alias_impl_trait)] + +type Opaque = Box; + +fn define() -> Opaque { Box::new(()) } + +impl Copy for Opaque {} diff --git a/tests/crashes/136286.rs b/tests/crashes/136286.rs new file mode 100644 index 000000000000..f0ea14bd167c --- /dev/null +++ b/tests/crashes/136286.rs @@ -0,0 +1,7 @@ +//@ known-bug: #136286 +//@ compile-flags: --edition=2024 + +#![feature(async_fn_in_dyn_trait)] +trait A { + async fn b(self: A); +} diff --git a/tests/crashes/136379.rs b/tests/crashes/136379.rs new file mode 100644 index 000000000000..077b373e3b5d --- /dev/null +++ b/tests/crashes/136379.rs @@ -0,0 +1,11 @@ +//@ known-bug: #136379 +#![feature(min_generic_const_args)] +pub struct S(); + +impl S { + pub fn f() -> [u8; S] { + [] + } +} + +pub fn main() {} diff --git a/tests/crashes/136381.rs b/tests/crashes/136381.rs new file mode 100644 index 000000000000..13ccc14a2c5b --- /dev/null +++ b/tests/crashes/136381.rs @@ -0,0 +1,18 @@ +//@ known-bug: #136381 +//@ compile-flags: -Zvalidate-mir -Zmir-enable-passes=+GVN +#![feature(trait_upcasting)] + +trait A {} +trait B: A { + fn c(&self); +} +impl B for i32 { + fn c(self) { + todo!(); + } +} + +fn main() { + let baz: &dyn B = &1; + let bar: &dyn A = baz; +} diff --git a/tests/crashes/136416.rs b/tests/crashes/136416.rs new file mode 100644 index 000000000000..b233422af869 --- /dev/null +++ b/tests/crashes/136416.rs @@ -0,0 +1,6 @@ +//@ known-bug: #136416 +#![feature(generic_const_exprs)] +struct State where[(); S] :; + +struct Foo; +struct State2 where [(); S]:; diff --git a/tests/crashes/136442.rs b/tests/crashes/136442.rs new file mode 100644 index 000000000000..0436debd565b --- /dev/null +++ b/tests/crashes/136442.rs @@ -0,0 +1,9 @@ +//@ known-bug: #136442 +//@ compile-flags: -Copt-level=0 -Zmir-enable-passes=+Inline -Zmir-enable-passes=+JumpThreading --crate-type lib +pub fn problem_thingy(items: &mut impl Iterator) { + let mut peeker = items.peekable(); + match peeker.peek() { + Some(_) => (), + None => return (), + } +} diff --git a/tests/crashes/136661.rs b/tests/crashes/136661.rs new file mode 100644 index 000000000000..76161a566f4c --- /dev/null +++ b/tests/crashes/136661.rs @@ -0,0 +1,25 @@ +//@ known-bug: #136661 + +#![allow(unused)] + +trait Supertrait {} + +trait Other { + fn method(&self) {} +} + +impl WithAssoc for &'static () { + type As = (); +} + +trait WithAssoc { + type As; +} + +trait Trait: Supertrait { + fn method(&self) {} +} + +fn hrtb Trait<&'a ()>>() {} + +pub fn main() {} diff --git a/tests/crashes/136666.rs b/tests/crashes/136666.rs new file mode 100644 index 000000000000..5cfed65fdf91 --- /dev/null +++ b/tests/crashes/136666.rs @@ -0,0 +1,36 @@ +//@ known-bug: #136666 +// Needed so that rust can infer that the A in what() is &() +trait IsRef {} +struct Dummy; +impl<'a> IsRef<&'a ()> for Dummy {} + +trait WithLifetime { + type Output<'a>; +} +impl<'t> WithLifetime for &'t () { + type Output<'a> = &'a (); +} + +// Needed to prevent the two Foo impls from overlapping +struct Wrap(A); + +trait Unimplemented {} + +trait Foo {} +impl Foo for T where T: Unimplemented {} +impl Foo for Wrap +where + Dummy: IsRef, + for<'a> A: WithLifetime = A>, +{ +} + +fn what() +where + Wrap: Foo, +{ +} + +fn main() { + what(); +} diff --git a/tests/crashes/136678.rs b/tests/crashes/136678.rs new file mode 100644 index 000000000000..e7d7de23bfeb --- /dev/null +++ b/tests/crashes/136678.rs @@ -0,0 +1,18 @@ +//@ known-bug: #136678 +#![feature(inherent_associated_types)] +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +struct B; + +struct Test; + +impl Test { + type B = B<{ A }>; + + fn test(a: Self::B) -> Self::B { + a + } +} + +pub fn main() {} diff --git a/tests/crashes/136766.rs b/tests/crashes/136766.rs new file mode 100644 index 000000000000..01fa07a05ae3 --- /dev/null +++ b/tests/crashes/136766.rs @@ -0,0 +1,6 @@ +//@ known-bug: #136766 +#![feature(generic_const_exprs)] +trait A{} +impl A for () {} +fn c(E: [u8; D * D]) where() : A{} +fn main() { c } diff --git a/tests/crashes/136859.rs b/tests/crashes/136859.rs new file mode 100644 index 000000000000..2c926eea5e27 --- /dev/null +++ b/tests/crashes/136859.rs @@ -0,0 +1,27 @@ +//@ known-bug: #136859 +#![feature(generic_const_exprs)] + +trait If {} +impl If for () {} + +trait IsZero { + type Answer; +} + +struct True; +struct False; + +impl IsZero for () +where (): If<{N == 0}> { + type Msg = True; +} + +trait Foobar {} + +impl Foobar for () +where (): IsZero {} + +impl Foobar<{{ N }}> for () +where (): IsZero {} + +fn main() {} diff --git a/tests/crashes/136894.rs b/tests/crashes/136894.rs new file mode 100644 index 000000000000..26bbb78717e1 --- /dev/null +++ b/tests/crashes/136894.rs @@ -0,0 +1,8 @@ +//@ known-bug: #136894 +#![feature(generic_const_exprs)] +#![crate_type = "lib"] +#![allow(incomplete_features, dead_code)] + +struct X([(); f::()]) where [(); f::()]:; + +const fn f() -> usize { panic!() } diff --git a/tests/crashes/137049.rs b/tests/crashes/137049.rs new file mode 100644 index 000000000000..a7132e4fa17c --- /dev/null +++ b/tests/crashes/137049.rs @@ -0,0 +1,29 @@ +//@ known-bug: #137049 +//@ compile-flags: --crate-type=lib +#![feature(type_alias_impl_trait)] + +use std::marker::PhantomData; + +trait Project1 { + type Assoc1; +} + +impl Project1 for T { + type Assoc1 = (); +} + +trait Project2 { + type Assoc2; +} + +impl> Project2 for PhantomData { + type Assoc2 = (); +} + +type Alias = impl Project2; + +fn constrain() -> Alias { + PhantomData:: +} + +struct AdtConstructor( as Project2>::Assoc2); diff --git a/tests/crashes/137084.rs b/tests/crashes/137084.rs new file mode 100644 index 000000000000..0f248c212062 --- /dev/null +++ b/tests/crashes/137084.rs @@ -0,0 +1,6 @@ +//@ known-bug: #137084 +#![feature(min_generic_const_args)] +fn a() {} +fn d(e: &String) { + a:: +} diff --git a/tests/crashes/137187.rs b/tests/crashes/137187.rs new file mode 100644 index 000000000000..05cfb2b10e10 --- /dev/null +++ b/tests/crashes/137187.rs @@ -0,0 +1,9 @@ +//@ known-bug: #137187 +use std::ops::Add; +trait A where + *const Self: Add, +{ + const fn b(c: *const Self) -> <*const Self as Add>::Output { + c + c + } +} diff --git a/tests/crashes/137188.rs b/tests/crashes/137188.rs new file mode 100644 index 000000000000..fdd098d300f4 --- /dev/null +++ b/tests/crashes/137188.rs @@ -0,0 +1,6 @@ +//@ known-bug: #137188 +#![feature(min_generic_const_args)] +trait Trait {} +impl Trait for [(); N] {} +fn N() {} +pub fn main() {} diff --git a/tests/crashes/137190-1.rs b/tests/crashes/137190-1.rs new file mode 100644 index 000000000000..bdfe883b7120 --- /dev/null +++ b/tests/crashes/137190-1.rs @@ -0,0 +1,10 @@ +//@ known-bug: #137190 +//@ compile-flags: -Zmir-opt-level=2 -Zvalidate-mir +trait A { + fn b(&self); +} +trait C: A {} +impl C for () {} +fn main() { + (&() as &dyn C as &dyn A).b(); +} diff --git a/tests/crashes/137190-2.rs b/tests/crashes/137190-2.rs new file mode 100644 index 000000000000..0c68b5aa4a51 --- /dev/null +++ b/tests/crashes/137190-2.rs @@ -0,0 +1,18 @@ +//@ known-bug: #137190 +trait Supertrait { + fn method(&self) {} +} + +trait Trait

: Supertrait<()> {} + +impl

Trait

for () {} + +const fn upcast

(x: &dyn Trait

) -> &dyn Supertrait<()> { + x +} + +const fn foo() -> &'static dyn Supertrait<()> { + upcast::<()>(&()) +} + +const _: &'static dyn Supertrait<()> = foo(); diff --git a/tests/crashes/137190-3.rs b/tests/crashes/137190-3.rs new file mode 100644 index 000000000000..88ae88e11bcd --- /dev/null +++ b/tests/crashes/137190-3.rs @@ -0,0 +1,10 @@ +//@ known-bug: #137190 +trait Supertrait { + fn method(&self) {} +} + +trait Trait: Supertrait {} + +impl Trait for () {} + +const _: &dyn Supertrait = &() as &dyn Trait as &dyn Supertrait; diff --git a/tests/crashes/137260.rs b/tests/crashes/137260.rs new file mode 100644 index 000000000000..f1fa8a660dcd --- /dev/null +++ b/tests/crashes/137260.rs @@ -0,0 +1,11 @@ +//@ known-bug: #137260 +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait Iter {} + +fn needs_iter>() {} + +fn test() { + needs_iter::<1, dyn Iter<()>>(); +} diff --git a/tests/crashes/137287.rs b/tests/crashes/137287.rs new file mode 100644 index 000000000000..59fdf568d368 --- /dev/null +++ b/tests/crashes/137287.rs @@ -0,0 +1,29 @@ +//@ known-bug: #137287 + +mod defining_scope { + use super::*; + pub type Alias = impl Sized; + + pub fn cast(x: Container, T>) -> Container { + x + } +} + +struct Container, U> { + x: >::Assoc, +} + +trait Trait { + type Assoc; +} + +impl Trait for T { + type Assoc = Box; +} +impl Trait for defining_scope::Alias { + type Assoc = usize; +} + +fn main() { + let x: Box = defining_scope::cast::<()>(Container { x: 0 }).x; +} diff --git a/tests/crashes/137467-1.rs b/tests/crashes/137467-1.rs new file mode 100644 index 000000000000..1d62cba59a79 --- /dev/null +++ b/tests/crashes/137467-1.rs @@ -0,0 +1,17 @@ +//@ known-bug: #137467 +//@ compile-flags: --edition=2021 +enum Camera { + Normal { base_transform: i32 }, + Volume { transform: i32 }, +} + +fn draw_ui(camera: &mut Camera) { + || { + let (Camera::Normal { + base_transform: _transform, + } + | Camera::Volume { + transform: _transform, + }) = camera; + }; +} diff --git a/tests/crashes/137467-2.rs b/tests/crashes/137467-2.rs new file mode 100644 index 000000000000..151d6a0767f0 --- /dev/null +++ b/tests/crashes/137467-2.rs @@ -0,0 +1,18 @@ +//@ known-bug: #137467 +//@ compile-flags: --edition=2021 + +enum Camera { + Normal { base_transform: i32 }, + Volume { transform: i32 }, +} + +fn draw_ui(camera: &mut Camera) { + || { + let (Camera::Normal { + base_transform: _, + } + | Camera::Volume { + transform: _, + }) = camera; + }; +} diff --git a/tests/crashes/137467-3.rs b/tests/crashes/137467-3.rs new file mode 100644 index 000000000000..2140fe044a77 --- /dev/null +++ b/tests/crashes/137467-3.rs @@ -0,0 +1,8 @@ +//@ known-bug: #137467 +//@ compile-flags: --edition=2021 + +fn meow(x: (u32, u32, u32)) { + let f = || { + let ((0, a, _) | (_, _, a)) = x; + }; +} diff --git a/tests/crashes/137468.rs b/tests/crashes/137468.rs new file mode 100644 index 000000000000..cceb0502bd21 --- /dev/null +++ b/tests/crashes/137468.rs @@ -0,0 +1,16 @@ +//@ known-bug: #137468 +//@ compile-flags: -Copt-level=0 -Zmir-enable-passes=+GVN -Zvalidate-mir +trait Supertrait {} + +trait Identity { + type Selff; +} + +trait Trait

: Supertrait<()> + Supertrait<

::Selff> {} + +impl

Trait

for () {} + +fn main() { + let x: &dyn Trait<()> = &(); + let x: &dyn Supertrait<()> = x; +} diff --git a/tests/crashes/137514.rs b/tests/crashes/137514.rs new file mode 100644 index 000000000000..7ae5f29e36e6 --- /dev/null +++ b/tests/crashes/137514.rs @@ -0,0 +1,9 @@ +//@ known-bug: #137514 +//@ needs-rustc-debug-assertions +#![feature(generic_const_exprs)] + +trait Bar {} + +trait BB = Bar<{ 1i32 + 1 }>; + +fn foo(x: &dyn BB) {} diff --git a/tests/crashes/137580.rs b/tests/crashes/137580.rs new file mode 100644 index 000000000000..246c80ef5560 --- /dev/null +++ b/tests/crashes/137580.rs @@ -0,0 +1,4 @@ +//@ known-bug: #137580 +fn main() { + println!("%65536$", 1); +} diff --git a/tests/crashes/137582.rs b/tests/crashes/137582.rs new file mode 100644 index 000000000000..e21b6c9578b7 --- /dev/null +++ b/tests/crashes/137582.rs @@ -0,0 +1,16 @@ +//@ known-bug: #137582 +#![feature(adt_const_params)] + +mod lib { + pub type Matrix = [&'static u32]; + + const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; + + pub struct Walk { + _p: (), + } + + impl Walk {} +} + +fn main() {} diff --git a/tests/crashes/137706.rs b/tests/crashes/137706.rs new file mode 100644 index 000000000000..0b46f9c237aa --- /dev/null +++ b/tests/crashes/137706.rs @@ -0,0 +1,7 @@ +//@ known-bug: #137706 +//@ needs-rustc-debug-assertions +trait A { + fn b() -> impl IntoIterator; +} + +impl A<()> for dyn A {} diff --git a/tests/crashes/137751.rs b/tests/crashes/137751.rs new file mode 100644 index 000000000000..85ae3acd53d3 --- /dev/null +++ b/tests/crashes/137751.rs @@ -0,0 +1,6 @@ +//@ known-bug: #137751 +//@ compile-flags: --edition=2021 -Znext-solver=globally +async fn test() { + Box::pin(test()).await; +} +fn main() {} diff --git a/tests/crashes/137813.rs b/tests/crashes/137813.rs new file mode 100644 index 000000000000..5d205ee53312 --- /dev/null +++ b/tests/crashes/137813.rs @@ -0,0 +1,18 @@ +//@ known-bug: #137813 +trait AssocConst { + const A: u8; +} + +impl AssocConst for (T,) { + const A: u8 = 0; +} + +trait Trait {} + +impl Trait for () where (U,): AssocConst {} + +fn foo() +where + (): Trait, +{ +} diff --git a/tests/crashes/137865.rs b/tests/crashes/137865.rs new file mode 100644 index 000000000000..7ecd8c734d32 --- /dev/null +++ b/tests/crashes/137865.rs @@ -0,0 +1,5 @@ +//@ known-bug: #137865 +trait Foo { + type Assoc; + fn foo() -> Self::Assoc<3>; +} diff --git a/tests/crashes/137874.rs b/tests/crashes/137874.rs new file mode 100644 index 000000000000..447188090245 --- /dev/null +++ b/tests/crashes/137874.rs @@ -0,0 +1,4 @@ +//@ known-bug: #137874 +fn a() { + match b { deref !(0c) }; +} diff --git a/tests/crashes/137888.rs b/tests/crashes/137888.rs new file mode 100644 index 000000000000..6c13ae5fa916 --- /dev/null +++ b/tests/crashes/137888.rs @@ -0,0 +1,11 @@ +//@ known-bug: #137888 +#![feature(generic_const_exprs)] +macro_rules! empty { + () => (); +} +fn bar() -> [(); { + empty! {}; + N + }] { +} +fn main() {} diff --git a/tests/crashes/137895.rs b/tests/crashes/137895.rs new file mode 100644 index 000000000000..bb624d2e9fa1 --- /dev/null +++ b/tests/crashes/137895.rs @@ -0,0 +1,6 @@ +//@ known-bug: #137895 +trait A { + fn b() -> impl ?Sized + 'a; +} + +impl A for dyn A {} diff --git a/tests/crashes/137916.rs b/tests/crashes/137916.rs new file mode 100644 index 000000000000..3d6b0e0fbab4 --- /dev/null +++ b/tests/crashes/137916.rs @@ -0,0 +1,13 @@ +//@ known-bug: #137916 +//@ compile-flags: --edition=2021 +use std::ptr::null; + +async fn a() -> Box { + Box::new(async { + let non_send = null::<()>(); + &non_send; + async {}.await + }) +} + +fn main() {} diff --git a/tests/crashes/138008.rs b/tests/crashes/138008.rs new file mode 100644 index 000000000000..4645b8c9d562 --- /dev/null +++ b/tests/crashes/138008.rs @@ -0,0 +1,8 @@ +//@ known-bug: #138008 +//@compile-flags: --crate-type=lib -Copt-level=0 +#![feature(repr_simd)] +const C: usize = 16; + +#[repr(simd)] +pub struct Foo([u8; C]); +pub unsafe fn foo(a: Foo) {} diff --git a/tests/crashes/138009.rs b/tests/crashes/138009.rs new file mode 100644 index 000000000000..a1b890823e7d --- /dev/null +++ b/tests/crashes/138009.rs @@ -0,0 +1,6 @@ +//@ known-bug: #138009 +#![feature(min_generic_const_args)] +#[repr(simd)] +struct T([isize; N]); + +static X: T = T(); diff --git a/tests/crashes/138048.rs b/tests/crashes/138048.rs new file mode 100644 index 000000000000..fd59f46c752f --- /dev/null +++ b/tests/crashes/138048.rs @@ -0,0 +1,8 @@ +//@ known-bug: #138048 +struct Foo; + +impl<'b> Foo { + fn bar() { + let V; + } +} diff --git a/tests/crashes/138088.rs b/tests/crashes/138088.rs new file mode 100644 index 000000000000..25496d804fef --- /dev/null +++ b/tests/crashes/138088.rs @@ -0,0 +1,5 @@ +//@ known-bug: #138088 +#![feature(min_generic_const_args)] +trait Bar { + fn x(&self) -> [i32; Bar::x]; +} diff --git a/tests/crashes/138089.rs b/tests/crashes/138089.rs new file mode 100644 index 000000000000..acf27072bdd5 --- /dev/null +++ b/tests/crashes/138089.rs @@ -0,0 +1,13 @@ +//@ known-bug: #138089 +#![feature(generic_const_exprs)] +#![feature(min_generic_const_args)] +#![feature(inherent_associated_types)] +struct OnDiskDirEntry<'a> {} + +impl<'a> OnDiskDirEntry<'a> { + const LFN_FRAGMENT_LEN: i64 = 2; + + fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] { + loop {} + } +} diff --git a/tests/crashes/138131.rs b/tests/crashes/138131.rs new file mode 100644 index 000000000000..f400c02de8d6 --- /dev/null +++ b/tests/crashes/138131.rs @@ -0,0 +1,12 @@ +//@ known-bug: #138131 +#![feature(min_generic_const_args)] +#![feature(inherent_associated_types)] +struct Foo<'a> { + x: &'a (), +} + +impl<'a> Foo<'a> { + fn foo(_: [u8; Foo::X]) {} +} + +fn main() {} diff --git a/tests/crashes/138132.rs b/tests/crashes/138132.rs new file mode 100644 index 000000000000..3e31117c526a --- /dev/null +++ b/tests/crashes/138132.rs @@ -0,0 +1,10 @@ +//@ known-bug: #138132 +#![feature(min_generic_const_args)] +struct b(Box<[u8; c]>); +impl b { + fn d(self) { + self.0.e() + } +} +struct c<'a>(&'a u8); +fn main() {} diff --git a/tests/crashes/138166.rs b/tests/crashes/138166.rs new file mode 100644 index 000000000000..98003bd6dae7 --- /dev/null +++ b/tests/crashes/138166.rs @@ -0,0 +1,8 @@ +//@ known-bug: #138166 +#![feature(min_generic_const_args)] +#![feature(inherent_associated_types)] +struct a(Box<[u8; Box::b]>); +impl a { + fn c(self) { self.0.d() } +} +fn main() {} From bca0ab8d7a7b06406966c7a710e9f4ad61d064fb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 8 Mar 2025 19:44:43 +0000 Subject: [PATCH 856/991] Rework maybe_suggest_add_generic_impl_trait --- .../src/hir_ty_lowering/lint.rs | 95 ++++++++++++++----- .../ui/dyn-keyword/dyn-2021-edition-error.rs | 6 ++ .../dyn-keyword/dyn-2021-edition-error.stderr | 13 ++- ...-struct-or-union-add-generic-impl-trait.rs | 6 +- ...uct-or-union-add-generic-impl-trait.stderr | 17 +++- 5 files changed, 108 insertions(+), 29 deletions(-) rename tests/ui/{suggestions => dyn-keyword}/suggest-struct-or-union-add-generic-impl-trait.rs (71%) rename tests/ui/{suggestions => dyn-keyword}/suggest-struct-or-union-add-generic-impl-trait.stderr (69%) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 3611db7c68f1..43348791fa52 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -123,6 +123,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + /// For a struct or enum with an invalid bare trait object field, suggest turning + /// it into a generic type bound. fn maybe_suggest_add_generic_impl_trait( &self, self_ty: &hir::Ty<'_>, @@ -132,21 +134,38 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let msg = "you might be missing a type parameter"; let mut sugg = vec![]; - let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; - let parent_item = tcx.hir_node_by_def_id(parent_id).expect_item(); - match parent_item.kind { - hir::ItemKind::Struct(_, generics) | hir::ItemKind::Enum(_, generics) => { - sugg.push(( - generics.where_clause_span, - format!( - "", - self.tcx().sess.source_map().span_to_snippet(self_ty.span).unwrap() - ), - )); - sugg.push((self_ty.span, "T".to_string())); + let parent_hir_id = tcx.parent_hir_id(self_ty.hir_id); + let parent_item = tcx.hir_get_parent_item(self_ty.hir_id).def_id; + + let generics = match tcx.hir_node_by_def_id(parent_item) { + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Struct(variant, generics), .. + }) => { + if !variant.fields().iter().any(|field| field.hir_id == parent_hir_id) { + return false; + } + generics } - _ => {} - } + hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(def, generics), .. }) => { + if !def + .variants + .iter() + .flat_map(|variant| variant.data.fields().iter()) + .any(|field| field.hir_id == parent_hir_id) + { + return false; + } + generics + } + _ => return false, + }; + + // FIXME: `T` may already be taken. + sugg.push(( + generics.where_clause_span, + format!("", self.tcx().sess.source_map().span_to_snippet(self_ty.span).unwrap()), + )); + sugg.push((self_ty.span, "T".to_string())); diag.multipart_suggestion_verbose(msg, sugg, Applicability::MachineApplicable); true } @@ -198,6 +217,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + /// Try our best to approximate when adding `dyn` would be helpful for a bare + /// trait object. + /// + /// Right now, this is if the type is either directly nested in another ty, + /// or if it's in the tail field within a struct. This approximates what the + /// user would've gotten on edition 2015, except for the case where we have + /// an *obvious* knock-on `Sized` error. fn maybe_suggest_dyn_trait( &self, self_ty: &hir::Ty<'_>, @@ -206,19 +232,40 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { diag: &mut Diag<'_>, ) -> bool { let tcx = self.tcx(); - let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; - let parent_item = tcx.hir_node_by_def_id(parent_id).expect_item(); - // If the parent item is an enum, don't suggest the dyn trait. - if let hir::ItemKind::Enum(..) = parent_item.kind { - return false; - } + // Look at the direct HIR parent, since we care about the relationship between + // the type and the thing that directly encloses it. + match tcx.parent_hir_node(self_ty.hir_id) { + // These are all generally ok. Namely, when a trait object is nested + // into another expression or ty, it's either very certain that they + // missed the ty (e.g. `&Trait`) or it's not really possible to tell + // what their intention is, so let's not give confusing suggestions and + // just mention `dyn`. The user can make up their mind what to do here. + hir::Node::Ty(_) + | hir::Node::Expr(_) + | hir::Node::PatExpr(_) + | hir::Node::PathSegment(_) + | hir::Node::AssocItemConstraint(_) + | hir::Node::TraitRef(_) + | hir::Node::Item(_) + | hir::Node::WherePredicate(_) => {} - // If the parent item is a struct, check if self_ty is the last field. - if let hir::ItemKind::Struct(variant_data, _) = parent_item.kind { - if variant_data.fields().last().unwrap().ty.span != self_ty.span { - return false; + hir::Node::Field(field) => { + // Enums can't have unsized fields, fields can only have an unsized tail field. + if let hir::Node::Item(hir::Item { + kind: hir::ItemKind::Struct(variant, _), .. + }) = tcx.parent_hir_node(field.hir_id) + && variant + .fields() + .last() + .is_some_and(|tail_field| tail_field.hir_id == field.hir_id) + { + // Ok + } else { + return false; + } } + _ => return false, } // FIXME: Only emit this suggestion if the trait is dyn-compatible. diff --git a/tests/ui/dyn-keyword/dyn-2021-edition-error.rs b/tests/ui/dyn-keyword/dyn-2021-edition-error.rs index 5d607d82ea1a..cc23c2c5055d 100644 --- a/tests/ui/dyn-keyword/dyn-2021-edition-error.rs +++ b/tests/ui/dyn-keyword/dyn-2021-edition-error.rs @@ -7,6 +7,12 @@ fn function(x: &SomeTrait, y: Box) { //~^ ERROR expected a type, found a trait } +// Regression test for . +extern "C" { + fn foo() -> *const SomeTrait; + //~^ ERROR expected a type, found a trait +} + trait SomeTrait {} fn main() {} diff --git a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr index 8c4b809e76b0..b1d6385bde99 100644 --- a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr +++ b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr @@ -29,6 +29,17 @@ help: you can add the `dyn` keyword if you want a trait object LL | fn function(x: &SomeTrait, y: Box) { | +++ +error[E0782]: expected a type, found a trait + --> $DIR/dyn-2021-edition-error.rs:12:24 + | +LL | fn foo() -> *const SomeTrait; + | ^^^^^^^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | fn foo() -> *const dyn SomeTrait; + | +++ + error[E0782]: expected a type, found a trait --> $DIR/dyn-2021-edition-error.rs:6:14 | @@ -40,6 +51,6 @@ help: you can add the `dyn` keyword if you want a trait object LL | let _x: &dyn SomeTrait = todo!(); | +++ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0782`. diff --git a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs similarity index 71% rename from tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs rename to tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs index 9963b5be4f2b..dcbed027c748 100644 --- a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs +++ b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs @@ -13,7 +13,6 @@ struct Foo2 { //~^ ERROR expected a type, found a trait } - enum Enum1 { A(Trait), //~^ ERROR expected a type, found a trait @@ -26,5 +25,10 @@ enum Enum2 { //~^ ERROR expected a type, found a trait } +// Regression test for . +pub struct InWhereClause +where + Trait:, {} +//~^ ERROR expected a type, found a trait fn main() {} diff --git a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr similarity index 69% rename from tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr rename to tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr index 433196919caf..16e48ef3a129 100644 --- a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr +++ b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr @@ -22,7 +22,7 @@ LL | b: dyn Trait, | +++ error[E0782]: expected a type, found a trait - --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:18:7 + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:17:7 | LL | A(Trait), | ^^^^^ @@ -34,7 +34,7 @@ LL ~ A(T), | error[E0782]: expected a type, found a trait - --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:25:7 + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:24:7 | LL | B(Trait), | ^^^^^ @@ -46,6 +46,17 @@ LL | A(u32), LL ~ B(T), | -error: aborting due to 4 previous errors +error[E0782]: expected a type, found a trait + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:31:5 + | +LL | Trait:, {} + | ^^^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | dyn Trait:, {} + | +++ + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0782`. From ceb040135dedd7de4b3a77d25c5b4f485b6baf9d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 8 Mar 2025 20:20:15 +0000 Subject: [PATCH 857/991] Fix suggestion when there are generics, inline some things --- .../src/hir_ty_lowering/lint.rs | 46 ++++++++++++------- ...-struct-or-union-add-generic-impl-trait.rs | 7 +++ ...uct-or-union-add-generic-impl-trait.stderr | 14 +++++- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 43348791fa52..e78801dd6014 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -78,13 +78,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } if self_ty.span.edition().at_least_rust_2021() { - let msg = "expected a type, found a trait"; - let label = "you can add the `dyn` keyword if you want a trait object"; - let mut diag = - rustc_errors::struct_span_code_err!(self.dcx(), self_ty.span, E0782, "{}", msg); + let mut diag = rustc_errors::struct_span_code_err!( + self.dcx(), + self_ty.span, + E0782, + "{}", + "expected a type, found a trait" + ); if self_ty.span.can_be_used_for_suggestions() && !self.maybe_suggest_impl_trait(self_ty, &mut diag) - && !self.maybe_suggest_dyn_trait(self_ty, label, sugg, &mut diag) + && !self.maybe_suggest_dyn_trait(self_ty, sugg, &mut diag) { self.maybe_suggest_add_generic_impl_trait(self_ty, &mut diag); } @@ -131,8 +134,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { diag: &mut Diag<'_>, ) -> bool { let tcx = self.tcx(); - let msg = "you might be missing a type parameter"; - let mut sugg = vec![]; let parent_hir_id = tcx.parent_hir_id(self_ty.hir_id); let parent_item = tcx.hir_get_parent_item(self_ty.hir_id).def_id; @@ -160,13 +161,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { _ => return false, }; - // FIXME: `T` may already be taken. - sugg.push(( - generics.where_clause_span, - format!("", self.tcx().sess.source_map().span_to_snippet(self_ty.span).unwrap()), - )); - sugg.push((self_ty.span, "T".to_string())); - diag.multipart_suggestion_verbose(msg, sugg, Applicability::MachineApplicable); + let Ok(rendered_ty) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { + return false; + }; + + let param = "TUV" + .chars() + .map(|c| c.to_string()) + .chain((0..).map(|i| format!("P{i}"))) + .find(|s| !generics.params.iter().any(|param| param.name.ident().as_str() == s)) + .expect("we definitely can find at least one param name to generate"); + let mut sugg = vec![(self_ty.span, param.to_string())]; + if let Some(insertion_span) = generics.span_for_param_suggestion() { + sugg.push((insertion_span, format!(", {param}: {}", rendered_ty))); + } else { + sugg.push((generics.where_clause_span, format!("<{param}: {}>", rendered_ty))); + } + diag.multipart_suggestion_verbose( + "you might be missing a type parameter", + sugg, + Applicability::MachineApplicable, + ); true } /// Make sure that we are in the condition to suggest the blanket implementation. @@ -227,7 +242,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn maybe_suggest_dyn_trait( &self, self_ty: &hir::Ty<'_>, - label: &str, sugg: Vec<(Span, String)>, diag: &mut Diag<'_>, ) -> bool { @@ -270,7 +284,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME: Only emit this suggestion if the trait is dyn-compatible. diag.multipart_suggestion_verbose( - label.to_string(), + "you can add the `dyn` keyword if you want a trait object", sugg, Applicability::MachineApplicable, ); diff --git a/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs index dcbed027c748..4d573b90d606 100644 --- a/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs +++ b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs @@ -31,4 +31,11 @@ where Trait:, {} //~^ ERROR expected a type, found a trait +struct HasGenerics { + f: Trait, + //~^ ERROR expected a type, found a trait + t: T, +} + + fn main() {} diff --git a/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr index 16e48ef3a129..9584147bbc77 100644 --- a/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr +++ b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr @@ -46,6 +46,18 @@ LL | A(u32), LL ~ B(T), | +error[E0782]: expected a type, found a trait + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:35:8 + | +LL | f: Trait, + | ^^^^^ + | +help: you might be missing a type parameter + | +LL ~ struct HasGenerics { +LL ~ f: U, + | + error[E0782]: expected a type, found a trait --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:31:5 | @@ -57,6 +69,6 @@ help: you can add the `dyn` keyword if you want a trait object LL | dyn Trait:, {} | +++ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0782`. From 20ed8fb0db145a46e5a5f19e28cc1ba8b8daa6f7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 8 Mar 2025 22:45:16 +0200 Subject: [PATCH 858/991] Revert "Don't test new error messages with the stage 0 compiler" This reverts commit ae428141f7b99511e327ad28daf988978a376d86. --- tests/ui-fulldeps/hash-stable-is-unstable.rs | 1 - tests/ui-fulldeps/hash-stable-is-unstable.stderr | 10 +++++----- tests/ui-fulldeps/pathless-extern-unstable.rs | 1 - tests/ui-fulldeps/pathless-extern-unstable.stderr | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.rs b/tests/ui-fulldeps/hash-stable-is-unstable.rs index dc7786952873..a4b8533eb045 100644 --- a/tests/ui-fulldeps/hash-stable-is-unstable.rs +++ b/tests/ui-fulldeps/hash-stable-is-unstable.rs @@ -1,4 +1,3 @@ -//@ ignore-stage1 FIXME: this line can be removed once these new error messages are in stage 0 rustc //@ compile-flags: -Zdeduplicate-diagnostics=yes extern crate rustc_data_structures; //~^ use of unstable library feature `rustc_private` diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.stderr b/tests/ui-fulldeps/hash-stable-is-unstable.stderr index 8d8091758753..e7740d744b4f 100644 --- a/tests/ui-fulldeps/hash-stable-is-unstable.stderr +++ b/tests/ui-fulldeps/hash-stable-is-unstable.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:3:1 + --> $DIR/hash-stable-is-unstable.rs:2:1 | LL | extern crate rustc_data_structures; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | extern crate rustc_data_structures; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:7:1 + --> $DIR/hash-stable-is-unstable.rs:6:1 | LL | extern crate rustc_macros; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | extern crate rustc_macros; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:11:1 + --> $DIR/hash-stable-is-unstable.rs:10:1 | LL | extern crate rustc_query_system; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | extern crate rustc_query_system; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:16:5 + --> $DIR/hash-stable-is-unstable.rs:15:5 | LL | use rustc_macros::HashStable; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | use rustc_macros::HashStable; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:21:10 + --> $DIR/hash-stable-is-unstable.rs:20:10 | LL | #[derive(HashStable)] | ^^^^^^^^^^ diff --git a/tests/ui-fulldeps/pathless-extern-unstable.rs b/tests/ui-fulldeps/pathless-extern-unstable.rs index 27272135696a..b5ba4082e9df 100644 --- a/tests/ui-fulldeps/pathless-extern-unstable.rs +++ b/tests/ui-fulldeps/pathless-extern-unstable.rs @@ -1,4 +1,3 @@ -//@ ignore-stage1 FIXME: this line can be removed once these new error messages are in stage 0 rustc //@ edition:2018 //@ compile-flags:--extern rustc_middle diff --git a/tests/ui-fulldeps/pathless-extern-unstable.stderr b/tests/ui-fulldeps/pathless-extern-unstable.stderr index a78b69f4d20f..779c3773a9b9 100644 --- a/tests/ui-fulldeps/pathless-extern-unstable.stderr +++ b/tests/ui-fulldeps/pathless-extern-unstable.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/pathless-extern-unstable.rs:7:9 + --> $DIR/pathless-extern-unstable.rs:6:9 | LL | pub use rustc_middle; | ^^^^^^^^^^^^ From 9bdd92118c815965da45c44356cfccd0c76da6ab Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Wed, 26 Feb 2025 23:34:39 -0800 Subject: [PATCH 859/991] Erase non-pal sys platform paths --- src/tools/miri/tests/ui.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index 85ce38f57d63..c37cf15d40ab 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -270,13 +270,13 @@ regexes! { // erase thread caller ids r"call [0-9]+" => "call ID", // erase platform module paths - "sys::pal::[a-z]+::" => "sys::pal::PLATFORM::", + r"\bsys::([a-z_]+)::[a-z]+::" => "sys::$1::PLATFORM::", // Windows file paths r"\\" => "/", // erase Rust stdlib path "[^ \n`]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/", // erase platform file paths - "sys/pal/[a-z]+/" => "sys/pal/PLATFORM/", + r"\bsys/([a-z_]+)/[a-z]+\b" => "sys/$1/PLATFORM", // erase paths into the crate registry r"[^ ]*/\.?cargo/registry/.*/(.*\.rs)" => "CARGO_REGISTRY/.../$1", } From 685619e4c93e3b30da36b013ab62c4cf8931b432 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Tue, 25 Feb 2025 17:45:30 -0800 Subject: [PATCH 860/991] Move fs into sys --- .../{sys_common/fs.rs => sys/fs/common.rs} | 0 .../sys/{pal/hermit/fs.rs => fs/hermit.rs} | 12 ++++---- library/std/src/sys/fs/mod.rs | 28 +++++++++++++++++++ .../src/sys/{pal/solid/fs.rs => fs/solid.rs} | 6 ++-- .../src/sys/{pal/uefi/fs.rs => fs/uefi.rs} | 0 .../src/sys/{pal/unix/fs.rs => fs/unix.rs} | 14 ++++++---- .../src/sys/{pal/unix/fs => fs/unix}/tests.rs | 2 +- .../unsupported/fs.rs => fs/unsupported.rs} | 0 .../src/sys/{pal/wasi/fs.rs => fs/wasi.rs} | 6 ++-- .../sys/{pal/windows/fs.rs => fs/windows.rs} | 12 ++++---- .../fs => fs/windows}/remove_dir_all.rs | 2 +- library/std/src/sys/mod.rs | 1 + library/std/src/sys/pal/hermit/mod.rs | 1 - library/std/src/sys/pal/sgx/mod.rs | 2 -- library/std/src/sys/pal/solid/mod.rs | 1 - library/std/src/sys/pal/solid/time.rs | 2 +- library/std/src/sys/pal/teeos/mod.rs | 2 -- library/std/src/sys/pal/uefi/mod.rs | 1 - library/std/src/sys/pal/unix/mod.rs | 1 - library/std/src/sys/pal/unsupported/mod.rs | 1 - library/std/src/sys/pal/wasi/mod.rs | 1 - library/std/src/sys/pal/wasip2/mod.rs | 2 -- library/std/src/sys/pal/wasm/mod.rs | 2 -- library/std/src/sys/pal/windows/mod.rs | 3 +- library/std/src/sys/pal/xous/mod.rs | 2 -- library/std/src/sys/pal/zkvm/mod.rs | 2 -- library/std/src/sys_common/mod.rs | 1 - .../tests/fail/shims/fs/isolated_file.stderr | 18 ++++++------ 28 files changed, 70 insertions(+), 55 deletions(-) rename library/std/src/{sys_common/fs.rs => sys/fs/common.rs} (100%) rename library/std/src/sys/{pal/hermit/fs.rs => fs/hermit.rs} (99%) create mode 100644 library/std/src/sys/fs/mod.rs rename library/std/src/sys/{pal/solid/fs.rs => fs/solid.rs} (99%) rename library/std/src/sys/{pal/uefi/fs.rs => fs/uefi.rs} (100%) rename library/std/src/sys/{pal/unix/fs.rs => fs/unix.rs} (99%) rename library/std/src/sys/{pal/unix/fs => fs/unix}/tests.rs (98%) rename library/std/src/sys/{pal/unsupported/fs.rs => fs/unsupported.rs} (100%) rename library/std/src/sys/{pal/wasi/fs.rs => fs/wasi.rs} (99%) rename library/std/src/sys/{pal/windows/fs.rs => fs/windows.rs} (99%) rename library/std/src/sys/{pal/windows/fs => fs/windows}/remove_dir_all.rs (99%) diff --git a/library/std/src/sys_common/fs.rs b/library/std/src/sys/fs/common.rs similarity index 100% rename from library/std/src/sys_common/fs.rs rename to library/std/src/sys/fs/common.rs diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/fs/hermit.rs similarity index 99% rename from library/std/src/sys/pal/hermit/fs.rs rename to library/std/src/sys/fs/hermit.rs index d4bf84dc1854..e9339ff261c9 100644 --- a/library/std/src/sys/pal/hermit/fs.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -1,18 +1,18 @@ -use super::fd::FileDesc; -use super::hermit_abi::{ - self, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, - O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, dirent64, stat as stat_struct, -}; use crate::ffi::{CStr, OsStr, OsString, c_char}; use crate::io::{self, BorrowedCursor, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; use crate::os::hermit::ffi::OsStringExt; +use crate::os::hermit::hermit_abi::{ + self, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, + O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, dirent64, stat as stat_struct, +}; use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::path::{Path, PathBuf}; use crate::sync::Arc; use crate::sys::common::small_c_string::run_path_with_cstr; +pub use crate::sys::fs::common::{copy, exists}; +use crate::sys::pal::fd::FileDesc; use crate::sys::time::SystemTime; use crate::sys::{cvt, unsupported}; -pub use crate::sys_common::fs::{copy, exists}; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{fmt, mem}; diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs new file mode 100644 index 000000000000..c2e19eb393a1 --- /dev/null +++ b/library/std/src/sys/fs/mod.rs @@ -0,0 +1,28 @@ +#![deny(unsafe_op_in_unsafe_fn)] + +pub mod common; + +cfg_if::cfg_if! { + if #[cfg(target_family = "unix")] { + mod unix; + pub use unix::*; + } else if #[cfg(target_os = "windows")] { + mod windows; + pub use windows::*; + } else if #[cfg(target_os = "hermit")] { + mod hermit; + pub use hermit::*; + } else if #[cfg(target_os = "solid_asp3")] { + mod solid; + pub use solid::*; + } else if #[cfg(target_os = "uefi")] { + mod uefi; + pub use uefi::*; + } else if #[cfg(target_os = "wasi")] { + mod wasi; + pub use wasi::*; + } else { + mod unsupported; + pub use unsupported::*; + } +} diff --git a/library/std/src/sys/pal/solid/fs.rs b/library/std/src/sys/fs/solid.rs similarity index 99% rename from library/std/src/sys/pal/solid/fs.rs rename to library/std/src/sys/fs/solid.rs index 4e741943283d..39de933b7248 100644 --- a/library/std/src/sys/pal/solid/fs.rs +++ b/library/std/src/sys/fs/solid.rs @@ -1,4 +1,5 @@ -use super::{abi, error}; +#![allow(dead_code)] + use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; @@ -7,9 +8,10 @@ use crate::os::raw::{c_int, c_short}; use crate::os::solid::ffi::OsStrExt; use crate::path::{Path, PathBuf}; use crate::sync::Arc; +pub use crate::sys::fs::common::exists; +use crate::sys::pal::{abi, error}; use crate::sys::time::SystemTime; use crate::sys::unsupported; -pub use crate::sys_common::fs::exists; use crate::sys_common::ignore_notfound; type CIntNotMinusOne = core::num::niche_types::NotAllOnes; diff --git a/library/std/src/sys/pal/uefi/fs.rs b/library/std/src/sys/fs/uefi.rs similarity index 100% rename from library/std/src/sys/pal/uefi/fs.rs rename to library/std/src/sys/fs/uefi.rs diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/fs/unix.rs similarity index 99% rename from library/std/src/sys/pal/unix/fs.rs rename to library/std/src/sys/fs/unix.rs index 20ba915af136..914971934bfb 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1,3 +1,5 @@ +#![allow(nonstandard_style)] +#![allow(unsafe_op_in_unsafe_fn)] // miri has some special hacks here that make things unused. #![cfg_attr(miri, allow(unused))] @@ -79,13 +81,13 @@ use crate::path::{Path, PathBuf}; use crate::sync::Arc; use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::fd::FileDesc; +pub use crate::sys::fs::common::exists; use crate::sys::time::SystemTime; #[cfg(all(target_os = "linux", target_env = "gnu"))] use crate::sys::weak::syscall; #[cfg(target_os = "android")] use crate::sys::weak::weak; use crate::sys::{cvt, cvt_r}; -pub use crate::sys_common::fs::exists; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{mem, ptr}; @@ -699,6 +701,8 @@ impl Iterator for ReadDir { target_os = "hurd", ))] fn next(&mut self) -> Option> { + use crate::sys::os::{errno, set_errno}; + if self.end_of_stream { return None; } @@ -710,7 +714,7 @@ impl Iterator for ReadDir { // with unlimited or variable NAME_MAX. Many modern platforms guarantee // thread safety for readdir() as long an individual DIR* is not accessed // concurrently, which is sufficient for Rust. - super::os::set_errno(0); + set_errno(0); let entry_ptr: *const dirent64 = readdir64(self.inner.dirp.0); if entry_ptr.is_null() { // We either encountered an error, or reached the end. Either way, @@ -719,7 +723,7 @@ impl Iterator for ReadDir { // To distinguish between errors and end-of-directory, we had to clear // errno beforehand to check for an error now. - return match super::os::errno() { + return match errno() { 0 => None, e => Some(Err(Error::from_raw_os_error(e))), }; @@ -1932,7 +1936,7 @@ pub fn canonicalize(p: &Path) -> io::Result { fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::File; - use crate::sys_common::fs::NOT_FILE_ERROR; + use crate::sys::fs::common::NOT_FILE_ERROR; let reader = File::open(from)?; let metadata = reader.metadata()?; @@ -2151,7 +2155,7 @@ pub use remove_dir_impl::remove_dir_all; miri ))] mod remove_dir_impl { - pub use crate::sys_common::fs::remove_dir_all; + pub use crate::sys::fs::common::remove_dir_all; } // Modern implementation using openat(), unlinkat() and fdopendir() diff --git a/library/std/src/sys/pal/unix/fs/tests.rs b/library/std/src/sys/fs/unix/tests.rs similarity index 98% rename from library/std/src/sys/pal/unix/fs/tests.rs rename to library/std/src/sys/fs/unix/tests.rs index 71be3472148b..8875a318db7d 100644 --- a/library/std/src/sys/pal/unix/fs/tests.rs +++ b/library/std/src/sys/fs/unix/tests.rs @@ -1,4 +1,4 @@ -use crate::sys::pal::unix::fs::FilePermissions; +use crate::sys::fs::FilePermissions; #[test] fn test_debug_permissions() { diff --git a/library/std/src/sys/pal/unsupported/fs.rs b/library/std/src/sys/fs/unsupported.rs similarity index 100% rename from library/std/src/sys/pal/unsupported/fs.rs rename to library/std/src/sys/fs/unsupported.rs diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/fs/wasi.rs similarity index 99% rename from library/std/src/sys/pal/wasi/fs.rs rename to library/std/src/sys/fs/wasi.rs index 6d7d125fc4d4..773040571bc9 100644 --- a/library/std/src/sys/pal/wasi/fs.rs +++ b/library/std/src/sys/fs/wasi.rs @@ -1,6 +1,3 @@ -#![forbid(unsafe_op_in_unsafe_fn)] - -use super::fd::WasiFd; use crate::ffi::{CStr, OsStr, OsString}; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::mem::{self, ManuallyDrop}; @@ -10,9 +7,10 @@ use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd use crate::path::{Path, PathBuf}; use crate::sync::Arc; use crate::sys::common::small_c_string::run_path_with_cstr; +use crate::sys::fd::WasiFd; +pub use crate::sys::fs::common::exists; use crate::sys::time::SystemTime; use crate::sys::unsupported; -pub use crate::sys_common::fs::exists; use crate::sys_common::{AsInner, FromInner, IntoInner, ignore_notfound}; use crate::{fmt, iter, ptr}; diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/fs/windows.rs similarity index 99% rename from library/std/src/sys/pal/windows/fs.rs rename to library/std/src/sys/fs/windows.rs index 8fce0496d80c..362e64abf1ac 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/fs/windows.rs @@ -1,5 +1,5 @@ -use super::api::{self, WinError, set_file_information_by_handle}; -use super::{IoResult, to_u16s}; +#![allow(nonstandard_style)] + use crate::alloc::{Layout, alloc, dealloc}; use crate::borrow::Cow; use crate::ffi::{OsStr, OsString, c_void}; @@ -10,6 +10,8 @@ use crate::os::windows::prelude::*; use crate::path::{Path, PathBuf}; use crate::sync::Arc; use crate::sys::handle::Handle; +use crate::sys::pal::api::{self, WinError, set_file_information_by_handle}; +use crate::sys::pal::{IoResult, fill_utf16_buf, to_u16s, truncate_utf16_at_nul}; use crate::sys::path::maybe_verbatim; use crate::sys::time::SystemTime; use crate::sys::{Align8, c, cvt}; @@ -167,7 +169,7 @@ impl DirEntry { } pub fn file_name(&self) -> OsString { - let filename = super::truncate_utf16_at_nul(&self.data.cFileName); + let filename = truncate_utf16_at_nul(&self.data.cFileName); OsString::from_wide(filename) } @@ -695,7 +697,7 @@ impl File { // Turn `\??\` into `\\?\` (a verbatim path). subst[1] = b'\\' as u16; // Attempt to convert to a more user-friendly path. - let user = super::args::from_wide_to_user_path( + let user = crate::sys::args::from_wide_to_user_path( subst.iter().copied().chain([0]).collect(), )?; Ok(PathBuf::from(OsString::from_wide(user.strip_suffix(&[0]).unwrap_or(&user)))) @@ -1492,7 +1494,7 @@ pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { } fn get_path(f: &File) -> io::Result { - super::fill_utf16_buf( + fill_utf16_buf( |buf, sz| unsafe { c::GetFinalPathNameByHandleW(f.handle.as_raw_handle(), buf, sz, c::VOLUME_NAME_DOS) }, diff --git a/library/std/src/sys/pal/windows/fs/remove_dir_all.rs b/library/std/src/sys/fs/windows/remove_dir_all.rs similarity index 99% rename from library/std/src/sys/pal/windows/fs/remove_dir_all.rs rename to library/std/src/sys/fs/windows/remove_dir_all.rs index 9416049da78f..f51eced84164 100644 --- a/library/std/src/sys/pal/windows/fs/remove_dir_all.rs +++ b/library/std/src/sys/fs/windows/remove_dir_all.rs @@ -33,7 +33,7 @@ use core::sync::atomic::{AtomicU32, Ordering}; use super::{AsRawHandle, DirBuff, File, FromRawHandle}; use crate::sys::c; -use crate::sys::pal::windows::api::WinError; +use crate::sys::pal::api::WinError; use crate::thread; // The maximum number of times to spin when waiting for deletes to complete. diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 1032fcba5e2e..9f8c1e53131a 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -12,6 +12,7 @@ pub mod anonymous_pipe; pub mod backtrace; pub mod cmath; pub mod exit_guard; +pub mod fs; pub mod io; pub mod net; pub mod os_str; diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index 21cbac643bbe..5605c92db5ba 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -21,7 +21,6 @@ use crate::os::raw::c_char; pub mod args; pub mod env; pub mod fd; -pub mod fs; pub mod futex; pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 37ca6b08c950..16aa5ab116af 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -12,8 +12,6 @@ pub mod abi; pub mod args; pub mod env; pub mod fd; -#[path = "../unsupported/fs.rs"] -pub mod fs; mod libunwind_integration; pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index 06af7bfade05..2c3e50ed5948 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -22,7 +22,6 @@ pub mod env; // `error` is `pub(crate)` so that it can be accessed by `itron/error.rs` as // `crate::sys::error` pub(crate) mod error; -pub mod fs; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; diff --git a/library/std/src/sys/pal/solid/time.rs b/library/std/src/sys/pal/solid/time.rs index 3f9bbb0b63cd..c39d715c6a6f 100644 --- a/library/std/src/sys/pal/solid/time.rs +++ b/library/std/src/sys/pal/solid/time.rs @@ -35,7 +35,7 @@ impl SystemTime { SystemTime(t) } - pub(super) fn from_time_t(t: abi::time_t) -> Self { + pub fn from_time_t(t: abi::time_t) -> Self { Self(t) } diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 3632524157db..2aeaf20134ff 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -11,8 +11,6 @@ pub mod args; #[path = "../unsupported/env.rs"] pub mod env; //pub mod fd; -#[path = "../unsupported/fs.rs"] -pub mod fs; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index 6a03e240c6bd..3dc83f6f654b 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -15,7 +15,6 @@ pub mod args; pub mod env; -pub mod fs; pub mod helpers; pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index c0b56d8d2b28..0565e3ecfb93 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -9,7 +9,6 @@ pub mod weak; pub mod args; pub mod env; pub mod fd; -pub mod fs; pub mod futex; #[cfg(any(target_os = "linux", target_os = "android"))] pub mod kernel_copy; diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs index b1aaeb1b4c81..526e5008bd50 100644 --- a/library/std/src/sys/pal/unsupported/mod.rs +++ b/library/std/src/sys/pal/unsupported/mod.rs @@ -2,7 +2,6 @@ pub mod args; pub mod env; -pub mod fs; pub mod os; pub mod pipe; pub mod process; diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index f4588a60ea9a..a5ae1f513dcb 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -16,7 +16,6 @@ pub mod args; pub mod env; pub mod fd; -pub mod fs; #[allow(unused)] #[path = "../wasm/atomics/futex.rs"] pub mod futex; diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs index 72c9742b2e54..d4eb43696737 100644 --- a/library/std/src/sys/pal/wasip2/mod.rs +++ b/library/std/src/sys/pal/wasip2/mod.rs @@ -12,8 +12,6 @@ pub mod args; pub mod env; #[path = "../wasi/fd.rs"] pub mod fd; -#[path = "../wasi/fs.rs"] -pub mod fs; #[allow(unused)] #[path = "../wasm/atomics/futex.rs"] pub mod futex; diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs index 32d59c4d0f7c..cfadbdfe00cf 100644 --- a/library/std/src/sys/pal/wasm/mod.rs +++ b/library/std/src/sys/pal/wasm/mod.rs @@ -19,8 +19,6 @@ #[path = "../unsupported/args.rs"] pub mod args; pub mod env; -#[path = "../unsupported/fs.rs"] -pub mod fs; #[path = "../unsupported/os.rs"] pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 1eca346b76c2..bed79af395b6 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -17,7 +17,6 @@ pub mod api; pub mod args; pub mod c; pub mod env; -pub mod fs; #[cfg(not(target_vendor = "win7"))] pub mod futex; pub mod handle; @@ -37,7 +36,7 @@ cfg_if::cfg_if! { } /// Map a [`Result`] to [`io::Result`](crate::io::Result). -trait IoResult { +pub trait IoResult { fn io_result(self) -> crate::io::Result; } impl IoResult for Result { diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs index 1bd0e67f3716..3022d717b4a5 100644 --- a/library/std/src/sys/pal/xous/mod.rs +++ b/library/std/src/sys/pal/xous/mod.rs @@ -3,8 +3,6 @@ pub mod args; #[path = "../unsupported/env.rs"] pub mod env; -#[path = "../unsupported/fs.rs"] -pub mod fs; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 8d8fe321f661..ca5b479296de 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -14,8 +14,6 @@ pub mod abi; #[path = "../zkvm/args.rs"] pub mod args; pub mod env; -#[path = "../unsupported/fs.rs"] -pub mod fs; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 4dc67d26bd8f..2a5de7f66661 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -20,7 +20,6 @@ #[cfg(test)] mod tests; -pub mod fs; pub mod process; pub mod wstr; pub mod wtf8; diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr index e611d6e28f85..75167ab5b387 100644 --- a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr +++ b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr @@ -1,5 +1,5 @@ error: unsupported operation: `open` not available when isolation is enabled - --> RUSTLIB/std/src/sys/pal/PLATFORM/fs.rs:LL:CC + --> RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC | LL | let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode as c_int) })?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `open` not available when isolation is enabled @@ -7,14 +7,14 @@ LL | let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode a = help: set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation; = help: or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/pal/PLATFORM/fs.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::cvt_r::` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::fs::File::open_c` at RUSTLIB/std/src/sys/pal/PLATFORM/fs.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sys/pal/PLATFORM/fs.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_path_with_cstr::` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::fs::File::open` at RUSTLIB/std/src/sys/pal/PLATFORM/fs.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::cvt_r::` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC + = note: inside `std::sys::fs::PLATFORM::File::open_c` at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::small_c_string::run_path_with_cstr::` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + = note: inside `std::sys::fs::PLATFORM::File::open` at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC = note: inside `std::fs::OpenOptions::_open` at RUSTLIB/std/src/fs.rs:LL:CC = note: inside `std::fs::OpenOptions::open::<&std::path::Path>` at RUSTLIB/std/src/fs.rs:LL:CC = note: inside `std::fs::File::open::<&str>` at RUSTLIB/std/src/fs.rs:LL:CC From bb82831126fbddd7946fab1acdd694ce40c02c81 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Thu, 27 Feb 2025 03:42:57 +0900 Subject: [PATCH 861/991] Bump chalk for built-in supports of async closures --- src/tools/rust-analyzer/Cargo.lock | 16 ++++---- src/tools/rust-analyzer/Cargo.toml | 8 ++-- .../crates/hir-ty/src/chalk_db.rs | 8 ++++ .../crates/hir-ty/src/tests/simple.rs | 39 +++++++++++++++++++ .../docs/book/src/assists_generated.md | 4 +- 5 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index c57953ba6547..30853cb799e1 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -191,9 +191,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chalk-derive" -version = "0.99.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572583d9b97f9d277e5c7607f8239a30e2e04d3ed3b47c87d1cb2152ae724073" +checksum = "ab2d131019373f0d0d1f2af0abd4f719739f6583c1b33965112455f643a910af" dependencies = [ "proc-macro2", "quote", @@ -203,9 +203,9 @@ dependencies = [ [[package]] name = "chalk-ir" -version = "0.99.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e60e0ef9c81dce1336a9ed3c76f08775f5b623151d96d85ba45f7b10de76d1c7" +checksum = "4f114996bda14c0213f014a4ef31a7867dcf5f539a3900477fc6b20138e7a17b" dependencies = [ "bitflags 2.7.0", "chalk-derive", @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "chalk-recursive" -version = "0.99.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a06350d614e22b03a69b8105e3541614450a7ea48bc58ecc6c6bd92731a3995" +checksum = "551e956e031c09057c7b21f17d48d91de99c9b6b6e34bceaf5e7202d71021268" dependencies = [ "chalk-derive", "chalk-ir", @@ -226,9 +226,9 @@ dependencies = [ [[package]] name = "chalk-solve" -version = "0.99.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e428761e9b55bee516bfe2457caed8b6d1b86353f92ae825bbe438a36ce91e8" +checksum = "cd7ca50181156ce649efe8e5dd00580f573651554e4dcd11afa4e2ac93f53324" dependencies = [ "chalk-derive", "chalk-ir", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 1132acb64741..33a9a5695a06 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -105,10 +105,10 @@ arrayvec = "0.7.4" bitflags = "2.4.1" cargo_metadata = "0.18.1" camino = "1.1.6" -chalk-solve = { version = "0.99.0", default-features = false } -chalk-ir = "0.99.0" -chalk-recursive = { version = "0.99.0", default-features = false } -chalk-derive = "0.99.0" +chalk-solve = { version = "0.100.0", default-features = false } +chalk-ir = "0.100.0" +chalk-recursive = { version = "0.100.0", default-features = false } +chalk-derive = "0.100.0" crossbeam-channel = "0.5.8" dissimilar = "1.0.7" dot = "0.1.4" diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index c8ff6cba3dd1..67fb73696f76 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -708,6 +708,9 @@ fn well_known_trait_from_lang_item(item: LangItem) -> Option { LangItem::Fn => WellKnownTrait::Fn, LangItem::FnMut => WellKnownTrait::FnMut, LangItem::FnOnce => WellKnownTrait::FnOnce, + LangItem::AsyncFn => WellKnownTrait::AsyncFn, + LangItem::AsyncFnMut => WellKnownTrait::AsyncFnMut, + LangItem::AsyncFnOnce => WellKnownTrait::AsyncFnOnce, LangItem::Coroutine => WellKnownTrait::Coroutine, LangItem::Sized => WellKnownTrait::Sized, LangItem::Unpin => WellKnownTrait::Unpin, @@ -715,6 +718,7 @@ fn well_known_trait_from_lang_item(item: LangItem) -> Option { LangItem::Tuple => WellKnownTrait::Tuple, LangItem::PointeeTrait => WellKnownTrait::Pointee, LangItem::FnPtrTrait => WellKnownTrait::FnPtr, + LangItem::Future => WellKnownTrait::Future, _ => return None, }) } @@ -730,6 +734,9 @@ fn lang_item_from_well_known_trait(trait_: WellKnownTrait) -> LangItem { WellKnownTrait::Fn => LangItem::Fn, WellKnownTrait::FnMut => LangItem::FnMut, WellKnownTrait::FnOnce => LangItem::FnOnce, + WellKnownTrait::AsyncFn => LangItem::AsyncFn, + WellKnownTrait::AsyncFnMut => LangItem::AsyncFnMut, + WellKnownTrait::AsyncFnOnce => LangItem::AsyncFnOnce, WellKnownTrait::Coroutine => LangItem::Coroutine, WellKnownTrait::Sized => LangItem::Sized, WellKnownTrait::Tuple => LangItem::Tuple, @@ -737,6 +744,7 @@ fn lang_item_from_well_known_trait(trait_: WellKnownTrait) -> LangItem { WellKnownTrait::Unsize => LangItem::Unsize, WellKnownTrait::Pointee => LangItem::PointeeTrait, WellKnownTrait::FnPtr => LangItem::FnPtrTrait, + WellKnownTrait::Future => LangItem::Future, } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index 50a1ecd006d8..4c5cca21655d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs @@ -3861,3 +3861,42 @@ fn main() { "#]], ); } + +#[test] +fn regression_19196() { + check_infer( + r#" +//- minicore: async_fn +fn async_closure(f: F) {} +fn closure(f: F) {} + +fn main() { + async_closure(async |arg| { + arg; + }); + closure(|arg| { + arg; + }); +} +"#, + expect![[r#" + 38..39 'f': F + 44..46 '{}': () + 74..75 'f': F + 80..82 '{}': () + 94..191 '{ ... }); }': () + 100..113 'async_closure': fn async_closure impl Future>(impl AsyncFnOnce(i32) -> impl Future) + 100..147 'async_... })': () + 114..146 'async ... }': impl AsyncFnOnce(i32) -> impl Future + 121..124 'arg': i32 + 126..146 '{ ... }': () + 136..139 'arg': i32 + 153..160 'closure': fn closure(impl FnOnce(i32)) + 153..188 'closur... })': () + 161..187 '|arg| ... }': impl FnOnce(i32) + 162..165 'arg': i32 + 167..187 '{ ... }': () + 177..180 'arg': i32 + "#]], + ); +} diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 918ae4a57944..a1433952e0ba 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -1070,7 +1070,7 @@ pub use foo::{Bar, Baz}; ### `expand_record_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L24) +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L26) Fills fields by replacing rest pattern in record patterns. @@ -1094,7 +1094,7 @@ fn foo(bar: Bar) { ### `expand_tuple_struct_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L80) +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L82) Fills fields by replacing rest pattern in tuple struct patterns. From 86013e629b00aba50f80810ed46c187531a3fdf9 Mon Sep 17 00:00:00 2001 From: Mu001999 Date: Sun, 9 Mar 2025 10:51:50 +0800 Subject: [PATCH 862/991] continue to check attr if meet empty repr for adt --- compiler/rustc_passes/src/check_attr.rs | 2 +- tests/ui/repr/repr-empty-packed.rs | 9 +++++++++ tests/ui/repr/repr-empty-packed.stderr | 27 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/ui/repr/repr-empty-packed.rs create mode 100644 tests/ui/repr/repr-empty-packed.stderr diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 91916b8f5fcc..c6ae2c0fb9bf 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1998,7 +1998,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // catch `repr()` with no arguments, applied to an item (i.e. not `#![repr()]`) if item.is_some() { match target { - Target::Struct | Target::Union | Target::Enum => {} + Target::Struct | Target::Union | Target::Enum => continue, Target::Fn | Target::Method(_) => { feature_err( &self.tcx.sess, diff --git a/tests/ui/repr/repr-empty-packed.rs b/tests/ui/repr/repr-empty-packed.rs new file mode 100644 index 000000000000..6e390a12b15a --- /dev/null +++ b/tests/ui/repr/repr-empty-packed.rs @@ -0,0 +1,9 @@ +//@ compile-flags: --crate-type=lib +#![deny(unused_attributes)] + +#[repr()] //~ ERROR unused attribute +#[repr(packed)] //~ ERROR attribute should be applied to a struct or union +pub enum Foo { + Bar, + Baz(i32), +} diff --git a/tests/ui/repr/repr-empty-packed.stderr b/tests/ui/repr/repr-empty-packed.stderr new file mode 100644 index 000000000000..c824c2998b48 --- /dev/null +++ b/tests/ui/repr/repr-empty-packed.stderr @@ -0,0 +1,27 @@ +error: unused attribute + --> $DIR/repr-empty-packed.rs:4:1 + | +LL | #[repr()] + | ^^^^^^^^^ help: remove this attribute + | + = note: attribute `repr` with an empty list has no effect +note: the lint level is defined here + --> $DIR/repr-empty-packed.rs:2:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error[E0517]: attribute should be applied to a struct or union + --> $DIR/repr-empty-packed.rs:5:8 + | +LL | #[repr(packed)] + | ^^^^^^ +LL | / pub enum Foo { +LL | | Bar, +LL | | Baz(i32), +LL | | } + | |_- not a struct or union + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0517`. From 0e4f189e80d6b8ec14cff20fba329a4332ce71a9 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sun, 9 Mar 2025 15:51:37 +0900 Subject: [PATCH 863/991] internal: Migrate `inline_local_variable` to `SyntaxEditor` --- .../src/handlers/inline_local_variable.rs | 72 ++++++++++--------- .../src/ast/syntax_factory/constructors.rs | 21 ++++++ 2 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs index cc7bea5152b6..0aa9970a72ef 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs @@ -5,7 +5,7 @@ use ide_db::{ EditionedFileId, RootDatabase, }; use syntax::{ - ast::{self, AstNode, AstToken, HasName}, + ast::{self, syntax_factory::SyntaxFactory, AstNode, AstToken, HasName}, SyntaxElement, TextRange, }; @@ -43,22 +43,6 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) }?; let initializer_expr = let_stmt.initializer()?; - let delete_range = delete_let.then(|| { - if let Some(whitespace) = let_stmt - .syntax() - .next_sibling_or_token() - .and_then(SyntaxElement::into_token) - .and_then(ast::Whitespace::cast) - { - TextRange::new( - let_stmt.syntax().text_range().start(), - whitespace.syntax().text_range().end(), - ) - } else { - let_stmt.syntax().text_range() - } - }); - let wrap_in_parens = references .into_iter() .filter_map(|FileReference { range, name, .. }| match name { @@ -76,37 +60,55 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) let usage_parent_option = usage_node.and_then(|it| it.parent()); let usage_parent = match usage_parent_option { Some(u) => u, - None => return Some((range, name_ref, false)), + None => return Some((name_ref, false)), }; - Some((range, name_ref, initializer_expr.needs_parens_in(&usage_parent))) + Some((name_ref, initializer_expr.needs_parens_in(&usage_parent))) }) .collect::>>()?; - let init_str = initializer_expr.syntax().text().to_string(); - let init_in_paren = format!("({init_str})"); - let target = match target { - ast::NameOrNameRef::Name(it) => it.syntax().text_range(), - ast::NameOrNameRef::NameRef(it) => it.syntax().text_range(), + ast::NameOrNameRef::Name(it) => it.syntax().clone(), + ast::NameOrNameRef::NameRef(it) => it.syntax().clone(), }; acc.add( AssistId("inline_local_variable", AssistKind::RefactorInline), "Inline variable", - target, + target.text_range(), move |builder| { - if let Some(range) = delete_range { - builder.delete(range); - } - for (range, name, should_wrap) in wrap_in_parens { - let replacement = if should_wrap { &init_in_paren } else { &init_str }; - if ast::RecordExprField::for_field_name(&name).is_some() { - cov_mark::hit!(inline_field_shorthand); - builder.insert(range.end(), format!(": {replacement}")); - } else { - builder.replace(range, replacement.clone()) + let mut editor = builder.make_editor(&target); + if delete_let { + editor.delete(let_stmt.syntax()); + if let Some(whitespace) = let_stmt + .syntax() + .next_sibling_or_token() + .and_then(SyntaxElement::into_token) + .and_then(ast::Whitespace::cast) + { + editor.delete(whitespace.syntax()); } } + + let make = SyntaxFactory::new(); + + for (name, should_wrap) in wrap_in_parens { + let replacement = if should_wrap { + make.expr_paren(initializer_expr.clone()).into() + } else { + initializer_expr.clone() + }; + + if let Some(record_field) = ast::RecordExprField::for_field_name(&name) { + cov_mark::hit!(inline_field_shorthand); + let replacement = make.record_expr_field(name, Some(replacement)); + editor.replace(record_field.syntax(), replacement.syntax()); + } else { + editor.replace(name.syntax(), replacement.syntax()); + } + } + + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 85393ca5b4ce..44f13041c244 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -783,6 +783,27 @@ impl SyntaxFactory { ast } + pub fn record_expr_field( + &self, + name: ast::NameRef, + expr: Option, + ) -> ast::RecordExprField { + let ast = make::record_expr_field(name.clone(), expr.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + + builder.map_node(name.syntax().clone(), ast.name_ref().unwrap().syntax().clone()); + if let Some(expr) = expr { + builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); + } + + builder.finish(&mut mapping); + } + + ast + } + pub fn record_field_list( &self, fields: impl IntoIterator, From a2b9c8d35c69a37c9bdb14f733c0b53935eb8731 Mon Sep 17 00:00:00 2001 From: beetrees Date: Sun, 9 Mar 2025 07:56:41 +0000 Subject: [PATCH 864/991] Fix `repr128-dwarf` test --- tests/run-make/repr128-dwarf/rmake.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs index 15eb186717f6..8227c51516fa 100644 --- a/tests/run-make/repr128-dwarf/rmake.rs +++ b/tests/run-make/repr128-dwarf/rmake.rs @@ -87,14 +87,15 @@ fn main() { while let Some((_, entry)) = cursor.next_dfs().unwrap() { match entry.tag() { gimli::constants::DW_TAG_variant if !is_old_llvm => { - let value = match entry - .attr(gimli::constants::DW_AT_discr_value) - .unwrap() - .unwrap() - .value() - { + let Some(value) = entry.attr(gimli::constants::DW_AT_discr_value).unwrap() + else { + // `std` enums might have variants without `DW_AT_discr_value`. + continue; + }; + let value = match value.value() { AttributeValue::Block(value) => value.to_slice().unwrap().to_vec(), - value => panic!("unexpected DW_AT_discr_value of {value:?}"), + // `std` has non-repr128 enums which don't use `AttributeValue::Block`. + value => continue, }; // The `DW_TAG_member` that is a child of `DW_TAG_variant` will contain the // variant's name. From 965a0c016677dad9ee8141e7a446ce376b7177c1 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sun, 9 Mar 2025 18:42:46 +0900 Subject: [PATCH 865/991] fix: Prevent wrong invocations of `needs_parens_in` with non-ancestral "parent"s --- .../src/handlers/apply_demorgan.rs | 14 +++-- .../src/handlers/inline_local_variable.rs | 54 +++++++++++++++- .../crates/syntax/src/ast/prec.rs | 63 ++++++++++++++++--- .../docs/book/src/assists_generated.md | 6 +- 4 files changed, 120 insertions(+), 17 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs index 77562c588e23..67bf8eed23df 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -128,7 +128,9 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti let parent = neg_expr.syntax().parent(); editor = builder.make_editor(neg_expr.syntax()); - if parent.is_some_and(|parent| demorganed.needs_parens_in(&parent)) { + if parent.is_some_and(|parent| { + demorganed.needs_parens_in_place_of(&parent, neg_expr.syntax()) + }) { cov_mark::hit!(demorgan_keep_parens_for_op_precedence2); editor.replace(neg_expr.syntax(), make.expr_paren(demorganed).syntax()); } else { @@ -392,15 +394,19 @@ fn f() { !(S <= S || S < S) } #[test] fn demorgan_keep_pars_for_op_precedence3() { - check_assist(apply_demorgan, "fn f() { (a || !(b &&$0 c); }", "fn f() { (a || !b || !c; }"); + check_assist( + apply_demorgan, + "fn f() { (a || !(b &&$0 c); }", + "fn f() { (a || (!b || !c); }", + ); } #[test] - fn demorgan_removes_pars_in_eq_precedence() { + fn demorgan_keeps_pars_in_eq_precedence() { check_assist( apply_demorgan, "fn() { let x = a && !(!b |$0| !c); }", - "fn() { let x = a && b && c; }", + "fn() { let x = a && (b && c); }", ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs index 0aa9970a72ef..36eed290dc88 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs @@ -57,12 +57,14 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) } let usage_node = name_ref.syntax().ancestors().find(|it| ast::PathExpr::can_cast(it.kind())); - let usage_parent_option = usage_node.and_then(|it| it.parent()); + let usage_parent_option = usage_node.as_ref().and_then(|it| it.parent()); let usage_parent = match usage_parent_option { Some(u) => u, None => return Some((name_ref, false)), }; - Some((name_ref, initializer_expr.needs_parens_in(&usage_parent))) + let should_wrap = initializer_expr + .needs_parens_in_place_of(&usage_parent, usage_node.as_ref().unwrap()); + Some((name_ref, should_wrap)) }) .collect::>>()?; @@ -941,6 +943,54 @@ fn main() { fn main() { let _ = (|| 2)(); } +"#, + ); + } + + #[test] + fn test_wrap_in_parens() { + check_assist( + inline_local_variable, + r#" +fn main() { + let $0a = 123 < 456; + let b = !a; +} +"#, + r#" +fn main() { + let b = !(123 < 456); +} +"#, + ); + check_assist( + inline_local_variable, + r#" +trait Foo { + fn foo(&self); +} + +impl Foo for bool { + fn foo(&self) {} +} + +fn main() { + let $0a = 123 < 456; + let b = a.foo(); +} +"#, + r#" +trait Foo { + fn foo(&self); +} + +impl Foo for bool { + fn foo(&self) {} +} + +fn main() { + let b = (123 < 456).foo(); +} "#, ); } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs index 0c4da7629926..4f0e2cad1746 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs @@ -1,5 +1,7 @@ //! Precedence representation. +use stdx::always; + use crate::{ ast::{self, BinaryOp, Expr, HasArgList, RangeItem}, match_ast, AstNode, SyntaxNode, @@ -140,6 +142,22 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence { } } +fn check_ancestry(ancestor: &SyntaxNode, descendent: &SyntaxNode) -> bool { + let bail = || always!(false, "{} is not an ancestor of {}", ancestor, descendent); + + if !ancestor.text_range().contains_range(descendent.text_range()) { + return bail(); + } + + for anc in descendent.ancestors() { + if anc == *ancestor { + return true; + } + } + + bail() +} + impl Expr { pub fn precedence(&self) -> ExprPrecedence { precedence(self) @@ -153,9 +171,19 @@ impl Expr { /// Returns `true` if `self` would need to be wrapped in parentheses given that its parent is `parent`. pub fn needs_parens_in(&self, parent: &SyntaxNode) -> bool { + self.needs_parens_in_place_of(parent, self.syntax()) + } + + /// Returns `true` if `self` would need to be wrapped in parentheses if it replaces `place_of` + /// given that `place_of`'s parent is `parent`. + pub fn needs_parens_in_place_of(&self, parent: &SyntaxNode, place_of: &SyntaxNode) -> bool { + if !check_ancestry(parent, place_of) { + return false; + } + match_ast! { match parent { - ast::Expr(e) => self.needs_parens_in_expr(&e), + ast::Expr(e) => self.needs_parens_in_expr(&e, place_of), ast::Stmt(e) => self.needs_parens_in_stmt(Some(&e)), ast::StmtList(_) => self.needs_parens_in_stmt(None), ast::ArgList(_) => false, @@ -165,7 +193,7 @@ impl Expr { } } - fn needs_parens_in_expr(&self, parent: &Expr) -> bool { + fn needs_parens_in_expr(&self, parent: &Expr, place_of: &SyntaxNode) -> bool { // Parentheses are necessary when calling a function-like pointer that is a member of a struct or union // (e.g. `(a.f)()`). let is_parent_call_expr = matches!(parent, ast::Expr::CallExpr(_)); @@ -199,13 +227,17 @@ impl Expr { if self.is_paren_like() || parent.is_paren_like() - || self.is_prefix() && (parent.is_prefix() || !self.is_ordered_before(parent)) - || self.is_postfix() && (parent.is_postfix() || self.is_ordered_before(parent)) + || self.is_prefix() + && (parent.is_prefix() + || !self.is_ordered_before_parent_in_place_of(parent, place_of)) + || self.is_postfix() + && (parent.is_postfix() + || self.is_ordered_before_parent_in_place_of(parent, place_of)) { return false; } - let (left, right, inv) = match self.is_ordered_before(parent) { + let (left, right, inv) = match self.is_ordered_before_parent_in_place_of(parent, place_of) { true => (self, parent, false), false => (parent, self, true), }; @@ -413,13 +445,28 @@ impl Expr { } } - fn is_ordered_before(&self, other: &Expr) -> bool { + fn is_ordered_before_parent_in_place_of(&self, parent: &Expr, place_of: &SyntaxNode) -> bool { + use rowan::TextSize; use Expr::*; - return order(self) < order(other); + let self_range = self.syntax().text_range(); + let place_of_range = place_of.text_range(); + + let self_order_adjusted = order(self) - self_range.start() + place_of_range.start(); + + let parent_order = order(parent); + let parent_order_adjusted = if parent_order <= place_of_range.start() { + parent_order + } else if parent_order >= place_of_range.end() { + parent_order - place_of_range.len() + self_range.len() + } else { + return false; + }; + + return self_order_adjusted < parent_order_adjusted; /// Returns text range that can be used to compare two expression for order (which goes first). - fn order(this: &Expr) -> rowan::TextSize { + fn order(this: &Expr) -> TextSize { // For non-paren-like operators: get the operator itself let token = match this { RangeExpr(e) => e.op_token(), diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 918ae4a57944..9a8018517927 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -306,7 +306,7 @@ fn main() { ### `apply_demorgan_iterator` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L154) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L156) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to `Iterator::all` and `Iterator::any`. @@ -1070,7 +1070,7 @@ pub use foo::{Bar, Baz}; ### `expand_record_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L24) +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L26) Fills fields by replacing rest pattern in record patterns. @@ -1094,7 +1094,7 @@ fn foo(bar: Bar) { ### `expand_tuple_struct_rest_pattern` -**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L80) +**Source:** [expand_rest_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_rest_pattern.rs#L82) Fills fields by replacing rest pattern in tuple struct patterns. From 358355440598b138cb0af39977a90157507eb184 Mon Sep 17 00:00:00 2001 From: StevenMia Date: Sun, 9 Mar 2025 18:31:14 +0800 Subject: [PATCH 866/991] chore: Fix some comments Signed-off-by: StevenMia --- compiler/rustc_borrowck/src/type_check/liveness/trace.rs | 2 +- compiler/rustc_hir/src/intravisit.rs | 4 ++-- compiler/rustc_lint/src/default_could_be_derived.rs | 2 +- .../src/language-features/default-field-values.md | 2 +- tests/ui/check-cfg/allow-same-level.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index dc35d5eb89c9..32d398dc1605 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -610,7 +610,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { Err(ErrorGuaranteed { .. }) => { // We don't run dropck on HIR, and dropck looks inside fields of // types, so there's no guarantee that it succeeds. We also - // can't rely on the the `ErrorGuaranteed` from `fully_perform` here + // can't rely on the `ErrorGuaranteed` from `fully_perform` here // because it comes from delay_span_bug. // // Do this inside of a probe because we don't particularly care (or want) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 25d2a8253438..3ef645a5f617 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -363,7 +363,7 @@ pub trait Visitor<'v>: Sized { /// See the doc comments on [`Ty`] for an explanation of what it means for a type to be /// ambiguous. /// - /// The [`Visitor::visit_infer`] method should be overriden in order to handle infer vars. + /// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars. fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) -> Self::Result { walk_ty(self, t) } @@ -374,7 +374,7 @@ pub trait Visitor<'v>: Sized { /// See the doc comments on [`ConstArg`] for an explanation of what it means for a const to be /// ambiguous. /// - /// The [`Visitor::visit_infer`] method should be overriden in order to handle infer vars. + /// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars. fn visit_const_arg(&mut self, c: &'v ConstArg<'v, AmbigArg>) -> Self::Result { walk_ambig_const_arg(self, c) } diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs index 59e38a882dde..58efca5e994a 100644 --- a/compiler/rustc_lint/src/default_could_be_derived.rs +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { return; } - // At least one of the fields with a default value have been overriden in + // At least one of the fields with a default value have been overridden in // the `Default` implementation. We suggest removing it and relying on `..` // instead. let any_default_field_given = diff --git a/src/doc/unstable-book/src/language-features/default-field-values.md b/src/doc/unstable-book/src/language-features/default-field-values.md index 3143b2d7cae3..6da6c4e6c57e 100644 --- a/src/doc/unstable-book/src/language-features/default-field-values.md +++ b/src/doc/unstable-book/src/language-features/default-field-values.md @@ -67,7 +67,7 @@ have default field values. ## Lints When manually implementing the `Default` trait for a type that has default -field values, if any of these are overriden in the impl the +field values, if any of these are overridden in the impl the `default_overrides_default_fields` lint will trigger. This lint is in place to avoid surprising diverging behavior between `S { .. }` and `S::default()`, where using the same type in both ways could result in diff --git a/tests/ui/check-cfg/allow-same-level.rs b/tests/ui/check-cfg/allow-same-level.rs index 5eef50e08e21..8260b57bad4d 100644 --- a/tests/ui/check-cfg/allow-same-level.rs +++ b/tests/ui/check-cfg/allow-same-level.rs @@ -3,7 +3,7 @@ // // It should work, but due to interactions between how #[cfg]s are // expanded, the lint machinery and the check-cfg impl, we -// miss the #[allow], althrough we probably shoudln't. +// miss the #[allow], althrough we probably shouldn't. // // cf. https://github.com/rust-lang/rust/issues/124735 // From 506c304654156257498f9e1b3ff98600d8a3acf2 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 24 Jan 2025 12:53:39 +0100 Subject: [PATCH 867/991] Clarify iterator by_ref docs --- library/core/src/iter/traits/iterator.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 91c3a4b29b53..91e8c8d3a945 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1825,10 +1825,19 @@ pub trait Iterator { Inspect::new(self, f) } - /// Borrows an iterator, rather than consuming it. + /// Creates a "by reference" adapter for this instance of `Iterator`. /// - /// This is useful to allow applying iterator adapters while still - /// retaining ownership of the original iterator. + /// Consuming method calls (direct or indirect calls to `next`) + /// on the "by reference" adapter will consume the original iterator, + /// but ownership-taking methods (those with a `self` parameter) + /// only take ownership of the "by reference" iterator. + /// + /// This is useful for applying ownership-taking methods + /// (such as `take` in the example below) + /// without giving up ownership of the original iterator, + /// so you can use the original iterator afterwards. + /// + /// Uses [impl Iterator for &mut I { type Item = I::Item; ...}](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#impl-Iterator-for-%26mut+I). /// /// # Examples /// @@ -4019,6 +4028,9 @@ where } } +/// Implements `Iterator` for mutable references to iterators, such as those produced by [`Iterator::by_ref`]. +/// +/// This implementation passes all method calls on to the original iterator. #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for &mut I { type Item = I::Item; From e1912f8fa9b281a2d1ccd9f89082ecd724d7a4ba Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 9 Mar 2025 15:36:53 +0100 Subject: [PATCH 868/991] Rank ADT constructors as constructors for completion scoring --- .../crates/ide-completion/src/render.rs | 104 ++++++++++++++++-- .../ide-completion/src/render/literal.rs | 10 +- 2 files changed, 102 insertions(+), 12 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 4f6c4cb66393..a61389ac55ac 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -1151,6 +1151,24 @@ fn main() { Foo::Fo$0 } ), lookup: "Foo{}", detail: "Foo { x: i32, y: i32 }", + relevance: CompletionRelevance { + exact_name_match: false, + type_match: None, + is_local: false, + trait_: None, + is_name_already_imported: false, + requires_import: false, + is_private_editable: false, + postfix_match: None, + function: Some( + CompletionRelevanceFn { + has_params: true, + has_self_param: false, + return_type: DirectConstructor, + }, + ), + is_skipping_completion: false, + }, trigger_call_info: true, }, ] @@ -1183,6 +1201,24 @@ fn main() { Foo::Fo$0 } ), lookup: "Foo()", detail: "Foo(i32, i32)", + relevance: CompletionRelevance { + exact_name_match: false, + type_match: None, + is_local: false, + trait_: None, + is_name_already_imported: false, + requires_import: false, + is_private_editable: false, + postfix_match: None, + function: Some( + CompletionRelevanceFn { + has_params: true, + has_self_param: false, + return_type: DirectConstructor, + }, + ), + is_skipping_completion: false, + }, trigger_call_info: true, }, ] @@ -1261,6 +1297,24 @@ fn main() { Foo::Fo$0 } Variant, ), detail: "Foo", + relevance: CompletionRelevance { + exact_name_match: false, + type_match: None, + is_local: false, + trait_: None, + is_name_already_imported: false, + requires_import: false, + is_private_editable: false, + postfix_match: None, + function: Some( + CompletionRelevanceFn { + has_params: false, + has_self_param: false, + return_type: DirectConstructor, + }, + ), + is_skipping_completion: false, + }, trigger_call_info: true, }, ] @@ -1335,7 +1389,13 @@ fn main() { let _: m::Spam = S$0 } requires_import: false, is_private_editable: false, postfix_match: None, - function: None, + function: Some( + CompletionRelevanceFn { + has_params: true, + has_self_param: false, + return_type: DirectConstructor, + }, + ), is_skipping_completion: false, }, trigger_call_info: true, @@ -1365,7 +1425,13 @@ fn main() { let _: m::Spam = S$0 } requires_import: false, is_private_editable: false, postfix_match: None, - function: None, + function: Some( + CompletionRelevanceFn { + has_params: false, + has_self_param: false, + return_type: DirectConstructor, + }, + ), is_skipping_completion: false, }, trigger_call_info: true, @@ -1590,6 +1656,24 @@ use self::E::*; documentation: Documentation( "variant docs", ), + relevance: CompletionRelevance { + exact_name_match: false, + type_match: None, + is_local: false, + trait_: None, + is_name_already_imported: false, + requires_import: false, + is_private_editable: false, + postfix_match: None, + function: Some( + CompletionRelevanceFn { + has_params: false, + has_self_param: false, + return_type: DirectConstructor, + }, + ), + is_skipping_completion: false, + }, trigger_call_info: true, }, CompletionItem { @@ -2081,8 +2165,8 @@ fn main() { } "#, expect![[r#" - lc ssss S [type+local] st S S [type] + lc ssss S [type+local] st S S [type] ex ssss [type] ex S [type] @@ -2153,14 +2237,14 @@ fn main() { } "#, expect![[r#" + st S S [] + st &S [type] ex core::ops::Deref::deref(&t) [type_could_unify] lc m i32 [local] lc t T [local] lc &t [type+local] st S S [] st &S [type] - st S S [] - st &S [type] st T T [] st &T [type] fn foo(…) fn(&S) [] @@ -2202,14 +2286,14 @@ fn main() { } "#, expect![[r#" + st S S [] + st &mut S [type] ex core::ops::DerefMut::deref_mut(&mut t) [type_could_unify] lc m i32 [local] lc t T [local] lc &mut t [type+local] st S S [] st &mut S [type] - st S S [] - st &mut S [type] st T T [] st &mut T [type] fn foo(…) fn(&mut S) [] @@ -2306,9 +2390,9 @@ fn main() { } "#, expect![[r#" - ex core::ops::Deref::deref(&bar()) [type_could_unify] st S S [] st &S [type] + ex core::ops::Deref::deref(&bar()) [type_could_unify] st S S [] st &S [type] st T T [] @@ -2827,11 +2911,11 @@ fn foo() { } "#, expect![[r#" + ev Foo::B Foo::B [type_could_unify] + ev Foo::A(…) Foo::A(T) [type_could_unify] lc foo Foo [type+local] ex foo [type] ex Foo::B [type] - ev Foo::A(…) Foo::A(T) [type_could_unify] - ev Foo::B Foo::B [type_could_unify] en Foo Foo<{unknown}> [type_could_unify] fn foo() fn() [] fn bar() fn() -> Foo [] diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs index aab54ca5e014..9e2bb8db54ab 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs @@ -8,7 +8,7 @@ use ide_db::{ use crate::{ context::{CompletionContext, PathCompletionCtx, PathKind}, - item::{Builder, CompletionItem}, + item::{Builder, CompletionItem, CompletionRelevanceFn}, render::{ compute_type_match, variant::{ @@ -17,7 +17,7 @@ use crate::{ }, RenderContext, }, - CompletionItemKind, CompletionRelevance, + CompletionItemKind, CompletionRelevance, CompletionRelevanceReturnType, }; pub(crate) fn render_variant_lit( @@ -131,6 +131,12 @@ fn render( let ty = thing.ty(db); item.set_relevance(CompletionRelevance { type_match: compute_type_match(ctx.completion, &ty), + // function is a misnomer here, this is more about constructor information + function: Some(CompletionRelevanceFn { + has_params: !fields.is_empty(), + has_self_param: false, + return_type: CompletionRelevanceReturnType::DirectConstructor, + }), ..ctx.completion_relevance() }); From 33c6c3a1e99d7838ff44a275b6eabd32d6c5c52f Mon Sep 17 00:00:00 2001 From: bdbai Date: Sun, 9 Mar 2025 22:42:17 +0800 Subject: [PATCH 869/991] Lazy load NtOpenFile for UWP --- library/std/src/sys/pal/windows/c.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 40b2bed73c0d..004cbee52f62 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -237,6 +237,17 @@ compat_fn_with_fallback! { STATUS_NOT_IMPLEMENTED } #[cfg(target_vendor = "uwp")] + pub fn NtOpenFile( + filehandle: *mut HANDLE, + desiredaccess: u32, + objectattributes: *const OBJECT_ATTRIBUTES, + iostatusblock: *mut IO_STATUS_BLOCK, + shareaccess: u32, + openoptions: u32 + ) -> NTSTATUS { + STATUS_NOT_IMPLEMENTED + } + #[cfg(target_vendor = "uwp")] pub fn NtReadFile( filehandle: HANDLE, event: HANDLE, From 9067f7cad6b52a139af3f62c243a94adbf6be9f9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 9 Mar 2025 19:04:37 +0000 Subject: [PATCH 870/991] Explain weird quirk in user type annotation lowering --- compiler/rustc_mir_build/src/thir/cx/mod.rs | 2 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 2 +- compiler/rustc_mir_build/src/thir/util.rs | 22 ++++++++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 2e069cae4269..3d55c1401b63 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -207,7 +207,7 @@ impl<'tcx> ThirBuildCx<'tcx> { &self, hir_id: HirId, ) -> Option> { - crate::thir::util::user_args_applied_to_ty_of_hir_id(self.typeck_results, hir_id) + crate::thir::util::user_args_applied_to_ty_of_hir_id(self.tcx, self.typeck_results, hir_id) } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 8dc3f998e091..4bfeab44bf4b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -539,7 +539,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { &self, hir_id: hir::HirId, ) -> Option> { - crate::thir::util::user_args_applied_to_ty_of_hir_id(self.typeck_results, hir_id) + crate::thir::util::user_args_applied_to_ty_of_hir_id(self.tcx, self.typeck_results, hir_id) } /// Takes a HIR Path. If the path is a constant, evaluates it and feeds diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs index 60a47a94e3a1..457957f5fce9 100644 --- a/compiler/rustc_mir_build/src/thir/util.rs +++ b/compiler/rustc_mir_build/src/thir/util.rs @@ -1,12 +1,16 @@ +use std::assert_matches::assert_matches; + use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_middle::bug; -use rustc_middle::ty::{self, CanonicalUserType}; +use rustc_middle::ty::{self, CanonicalUserType, TyCtxt}; use tracing::debug; /// Looks up the type associated with this hir-id and applies the /// user-given generic parameters; the hir-id must map to a suitable /// type. pub(crate) fn user_args_applied_to_ty_of_hir_id<'tcx>( + tcx: TyCtxt<'tcx>, typeck_results: &ty::TypeckResults<'tcx>, hir_id: hir::HirId, ) -> Option> { @@ -16,7 +20,23 @@ pub(crate) fn user_args_applied_to_ty_of_hir_id<'tcx>( let ty = typeck_results.node_type(hir_id); match ty.kind() { ty::Adt(adt_def, ..) => { + // This "fixes" user type annotations for tupled ctor patterns for ADTs. + // That's because `type_of(ctor_did)` returns a FnDef, but we actually + // want to be annotating the type of the ADT itself. It's a bit goofy, + // but it's easier to adjust this here rather than in the path lowering + // code for patterns in HIR. if let ty::UserTypeKind::TypeOf(did, _) = &mut user_ty.value.kind { + // This is either already set up correctly (struct, union, enum, or variant), + // or needs adjusting (ctor). Make sure we don't start adjusting other + // user annotations like consts or fn calls. + assert_matches!( + tcx.def_kind(*did), + DefKind::Ctor(..) + | DefKind::Struct + | DefKind::Enum + | DefKind::Union + | DefKind::Variant + ); *did = adt_def.did(); } Some(user_ty) From 8ab05adc37667c3169fb120b3a9f53be9a909c3b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 9 Mar 2025 19:12:42 +0000 Subject: [PATCH 871/991] Do not write user type annotation for const param value path --- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 7 +++++++ tests/crashes/138048.rs | 8 -------- .../generic_const_parameter_types/bad-param-in-pat.rs | 10 ++++++++++ .../bad-param-in-pat.stderr | 11 +++++++++++ 4 files changed, 28 insertions(+), 8 deletions(-) delete mode 100644 tests/crashes/138048.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/bad-param-in-pat.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/bad-param-in-pat.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index c46a42c5de1e..36ad0ae1c301 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -220,6 +220,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { debug!("fcx {}", self.tag()); + // Don't write user type annotations for const param types, since we give them + // identity args just so that we can trivially substitute their `EarlyBinder`. + // We enforce that they match their type in MIR later on. + if matches!(self.tcx.def_kind(def_id), DefKind::ConstParam) { + return; + } + if Self::can_contain_user_lifetime_bounds((args, user_self_ty)) { let canonicalized = self.canonicalize_user_type_annotation(ty::UserType::new( ty::UserTypeKind::TypeOf(def_id, UserArgs { args, user_self_ty }), diff --git a/tests/crashes/138048.rs b/tests/crashes/138048.rs deleted file mode 100644 index fd59f46c752f..000000000000 --- a/tests/crashes/138048.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: #138048 -struct Foo; - -impl<'b> Foo { - fn bar() { - let V; - } -} diff --git a/tests/ui/const-generics/generic_const_parameter_types/bad-param-in-pat.rs b/tests/ui/const-generics/generic_const_parameter_types/bad-param-in-pat.rs new file mode 100644 index 000000000000..bc54aad59ba9 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/bad-param-in-pat.rs @@ -0,0 +1,10 @@ +struct Foo<'a>(&'a ()); + +// We need a lifetime in scope or else we do not write a user type annotation as a fast-path. +impl<'a> Foo<'a> { + fn bar() { + let V; + //~^ ERROR constant parameters cannot be referenced in patterns + } +} +fn main() {} diff --git a/tests/ui/const-generics/generic_const_parameter_types/bad-param-in-pat.stderr b/tests/ui/const-generics/generic_const_parameter_types/bad-param-in-pat.stderr new file mode 100644 index 000000000000..299ff4165e0d --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/bad-param-in-pat.stderr @@ -0,0 +1,11 @@ +error[E0158]: constant parameters cannot be referenced in patterns + --> $DIR/bad-param-in-pat.rs:6:13 + | +LL | fn bar() { + | ----------- constant defined here +LL | let V; + | ^ can't be used in patterns + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0158`. From ed6dfddfeb345e0fe94ef735a54d6290d278a6b8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 9 Mar 2025 18:23:17 +0000 Subject: [PATCH 872/991] Do not feed anon const a type that references generics that it does not have --- .../src/hir_ty_lowering/mod.rs | 25 +++++++++++++------ tests/crashes/137865.rs | 5 ---- .../references-parent-generics.feat.stderr | 25 +++++++++++++++++++ .../references-parent-generics.nofeat.stderr | 16 ++++++++++++ .../references-parent-generics.rs | 18 +++++++++++++ 5 files changed, 76 insertions(+), 13 deletions(-) delete mode 100644 tests/crashes/137865.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr create mode 100644 tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr create mode 100644 tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index dd6c40bfbb8d..5f91f1d7b3e1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2294,18 +2294,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { { let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args); - // We must error if the instantiated type has any inference variables as we will - // use this type to feed the `type_of` and query results must not contain inference - // variables otherwise we will ICE. - // + // FIXME(generic_const_parameter_types): Ideally we remove these errors below when + // we have the ability to intermix typeck of anon const const args with the parent + // bodies typeck. + // We also error if the type contains any regions as effectively any region will wind // up as a region variable in mir borrowck. It would also be somewhat concerning if // hir typeck was using equality but mir borrowck wound up using subtyping as that could // result in a non-infer in hir typeck but a region variable in borrowck. - // - // FIXME(generic_const_parameter_types): Ideally we remove these errors one day when - // we have the ability to intermix typeck of anon const const args with the parent - // bodies typeck. if tcx.features().generic_const_parameter_types() && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions()) { @@ -2316,6 +2312,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); return ty::Const::new_error(tcx, e); } + // We must error if the instantiated type has any inference variables as we will + // use this type to feed the `type_of` and query results must not contain inference + // variables otherwise we will ICE. if anon_const_type.has_non_region_infer() { let e = tcx.dcx().span_err( const_arg.span(), @@ -2324,6 +2323,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); return ty::Const::new_error(tcx, e); } + // We error when the type contains unsubstituted generics since we do not currently + // give the anon const any of the generics from the parent. + if anon_const_type.has_non_region_param() { + let e = tcx.dcx().span_err( + const_arg.span(), + "anonymous constants referencing generics are not yet supported", + ); + tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); + return ty::Const::new_error(tcx, e); + } tcx.feed_anon_const_type( anon.def_id, diff --git a/tests/crashes/137865.rs b/tests/crashes/137865.rs deleted file mode 100644 index 7ecd8c734d32..000000000000 --- a/tests/crashes/137865.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ known-bug: #137865 -trait Foo { - type Assoc; - fn foo() -> Self::Assoc<3>; -} diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr new file mode 100644 index 000000000000..29171c8006af --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr @@ -0,0 +1,25 @@ +warning: the feature `generic_const_parameter_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/references-parent-generics.rs:3:27 + | +LL | #![cfg_attr(feat, feature(generic_const_parameter_types))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #137626 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `Self` is forbidden as the type of a const generic parameter + --> $DIR/references-parent-generics.rs:7:25 + | +LL | type Assoc; + | ^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: anonymous constants referencing generics are not yet supported + --> $DIR/references-parent-generics.rs:14:21 + | +LL | let x: T::Assoc<3>; + | ^ + +error: aborting due to 2 previous errors; 1 warning emitted + diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr new file mode 100644 index 000000000000..64b413188144 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr @@ -0,0 +1,16 @@ +error: `Self` is forbidden as the type of a const generic parameter + --> $DIR/references-parent-generics.rs:7:25 + | +LL | type Assoc; + | ^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: anonymous constants referencing generics are not yet supported + --> $DIR/references-parent-generics.rs:14:21 + | +LL | let x: T::Assoc<3>; + | ^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs new file mode 100644 index 000000000000..21994eb83b42 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs @@ -0,0 +1,18 @@ +//@ revisions: feat nofeat + +#![cfg_attr(feat, feature(generic_const_parameter_types))] +//[feat]~^ WARN the feature `generic_const_parameter_types` is incomplete + +trait Foo { + type Assoc; + //~^ ERROR `Self` is forbidden as the type of a const generic parameter +} + +fn foo() { + // We used to end up feeding the type of this anon const to be `T`, but the anon const + // doesn't inherit the generics of `foo`, which led to index oob errors. + let x: T::Assoc<3>; + //~^ ERROR anonymous constants referencing generics are not yet supported +} + +fn main() {} From eecf17e803151666c43d55b427bb33dbc08585fe Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Sun, 9 Mar 2025 20:20:52 +0000 Subject: [PATCH 873/991] triagebot.toml: Don't label `test/rustdoc-json` as A-rustdoc-search (again) --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index e4231b2966ba..8db158b95edd 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -274,7 +274,7 @@ trigger_files = [ [autolabel."A-rustdoc-search"] trigger_files = [ "src/librustdoc/html/static/js/search.js", - "tests/rustdoc-js", + "tests/rustdoc-js/", "tests/rustdoc-js-std", ] From 32d0c4ed86c0e768b4b5cec20dabd3f9b39a692b Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Wed, 5 Mar 2025 14:42:32 -0800 Subject: [PATCH 874/991] Update hermit-abi to 0.5.0 --- library/Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index 405c69d95686..8f174f284724 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 0ec167c2d161..f7379c413f15 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -73,7 +73,7 @@ fortanix-sgx-abi = { version = "0.5.0", features = [ ], public = true } [target.'cfg(target_os = "hermit")'.dependencies] -hermit-abi = { version = "0.4.0", features = [ +hermit-abi = { version = "0.5.0", features = [ 'rustc-dep-of-std', ], public = true } From 1abaacd375bf74b3dc01fb578d8064771e327805 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Tue, 18 Feb 2025 16:30:42 -0800 Subject: [PATCH 875/991] Support File::seek for Hermit --- library/std/src/sys/fs/hermit.rs | 6 +++--- library/std/src/sys/pal/hermit/fd.rs | 21 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index e9339ff261c9..1191e335daad 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -417,12 +417,12 @@ impl File { Ok(()) } - pub fn seek(&self, _pos: SeekFrom) -> io::Result { - Err(Error::from_raw_os_error(22)) + pub fn seek(&self, pos: SeekFrom) -> io::Result { + self.0.seek(pos) } pub fn tell(&self) -> io::Result { - self.seek(SeekFrom::Current(0)) + self.0.tell() } pub fn duplicate(&self) -> io::Result { diff --git a/library/std/src/sys/pal/hermit/fd.rs b/library/std/src/sys/pal/hermit/fd.rs index 79fc13bd4a87..3d6b99cd77b5 100644 --- a/library/std/src/sys/pal/hermit/fd.rs +++ b/library/std/src/sys/pal/hermit/fd.rs @@ -2,8 +2,8 @@ use super::hermit_abi; use crate::cmp; -use crate::io::{self, IoSlice, IoSliceMut, Read}; -use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd, *}; +use crate::io::{self, IoSlice, IoSliceMut, Read, SeekFrom}; +use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::sys::{cvt, unsupported}; use crate::sys_common::{AsInner, FromInner, IntoInner}; @@ -66,9 +66,26 @@ impl FileDesc { true } + pub fn seek(&self, pos: SeekFrom) -> io::Result { + let (whence, pos) = match pos { + // Casting to `i64` is fine, too large values will end up as + // negative which will cause an error in `lseek`. + SeekFrom::Start(off) => (hermit_abi::SEEK_SET, off as i64), + SeekFrom::End(off) => (hermit_abi::SEEK_END, off), + SeekFrom::Current(off) => (hermit_abi::SEEK_CUR, off), + }; + let n = cvt(unsafe { hermit_abi::lseek(self.as_raw_fd(), pos as isize, whence) })?; + Ok(n as u64) + } + + pub fn tell(&self) -> io::Result { + self.seek(SeekFrom::Current(0)) + } + pub fn duplicate(&self) -> io::Result { self.duplicate_path(&[]) } + pub fn duplicate_path(&self, _path: &[u8]) -> io::Result { unsupported() } From c52e0596c5ef1d68bf0f283342fdb05db63248f9 Mon Sep 17 00:00:00 2001 From: joboet Date: Sun, 9 Feb 2025 18:42:07 +0100 Subject: [PATCH 876/991] std: move stdio to `sys` As per #117276, this moves the platform definitions of `Stdout` and friends into `sys`. This PR also unifies the UNIX and Hermit implementations and moves the `__rust_print_err` function needed by libunwind on SGX into the dedicated module for such helper functions. --- library/std/src/sys/mod.rs | 1 + library/std/src/sys/pal/hermit/mod.rs | 1 - library/std/src/sys/pal/hermit/stdio.rs | 97 ------------------- library/std/src/sys/pal/sgx/abi/mod.rs | 2 +- .../src/sys/pal/sgx/libunwind_integration.rs | 12 +++ library/std/src/sys/pal/sgx/mod.rs | 1 - library/std/src/sys/pal/solid/mod.rs | 1 - library/std/src/sys/pal/teeos/mod.rs | 1 - library/std/src/sys/pal/uefi/mod.rs | 1 - library/std/src/sys/pal/unix/mod.rs | 1 - library/std/src/sys/pal/unsupported/mod.rs | 1 - library/std/src/sys/pal/wasi/mod.rs | 1 - library/std/src/sys/pal/wasip2/mod.rs | 2 - library/std/src/sys/pal/wasm/mod.rs | 2 - library/std/src/sys/pal/windows/mod.rs | 1 - library/std/src/sys/pal/xous/mod.rs | 1 - library/std/src/sys/pal/zkvm/mod.rs | 1 - library/std/src/sys/stdio/mod.rs | 38 ++++++++ .../sys/{pal/sgx/stdio.rs => stdio/sgx.rs} | 20 +--- .../{pal/solid/stdio.rs => stdio/solid.rs} | 2 +- .../{pal/teeos/stdio.rs => stdio/teeos.rs} | 0 .../sys/{pal/uefi/stdio.rs => stdio/uefi.rs} | 0 .../sys/{pal/unix/stdio.rs => stdio/unix.rs} | 33 ++++--- .../stdio.rs => stdio/unsupported.rs} | 0 .../sys/{pal/wasi/stdio.rs => stdio/wasi.rs} | 2 +- .../windows/stdio.rs => stdio/windows.rs} | 2 +- .../windows/stdio => stdio/windows}/tests.rs | 0 .../sys/{pal/xous/stdio.rs => stdio/xous.rs} | 0 .../sys/{pal/zkvm/stdio.rs => stdio/zkvm.rs} | 3 +- 29 files changed, 77 insertions(+), 150 deletions(-) delete mode 100644 library/std/src/sys/pal/hermit/stdio.rs create mode 100644 library/std/src/sys/stdio/mod.rs rename library/std/src/sys/{pal/sgx/stdio.rs => stdio/sgx.rs} (71%) rename library/std/src/sys/{pal/solid/stdio.rs => stdio/solid.rs} (98%) rename library/std/src/sys/{pal/teeos/stdio.rs => stdio/teeos.rs} (100%) rename library/std/src/sys/{pal/uefi/stdio.rs => stdio/uefi.rs} (100%) rename library/std/src/sys/{pal/unix/stdio.rs => stdio/unix.rs} (59%) rename library/std/src/sys/{pal/unsupported/stdio.rs => stdio/unsupported.rs} (100%) rename library/std/src/sys/{pal/wasi/stdio.rs => stdio/wasi.rs} (98%) rename library/std/src/sys/{pal/windows/stdio.rs => stdio/windows.rs} (99%) rename library/std/src/sys/{pal/windows/stdio => stdio/windows}/tests.rs (100%) rename library/std/src/sys/{pal/xous/stdio.rs => stdio/xous.rs} (100%) rename library/std/src/sys/{pal/zkvm/stdio.rs => stdio/zkvm.rs} (97%) diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 9f8c1e53131a..09677b9d6428 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -18,6 +18,7 @@ pub mod net; pub mod os_str; pub mod path; pub mod random; +pub mod stdio; pub mod sync; pub mod thread_local; diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index 5605c92db5ba..608245bd430b 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -27,7 +27,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -pub mod stdio; pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/hermit/stdio.rs b/library/std/src/sys/pal/hermit/stdio.rs deleted file mode 100644 index 3ea00f5cc5ec..000000000000 --- a/library/std/src/sys/pal/hermit/stdio.rs +++ /dev/null @@ -1,97 +0,0 @@ -use super::hermit_abi; -use crate::io; -use crate::io::{IoSlice, IoSliceMut}; -use crate::mem::ManuallyDrop; -use crate::os::hermit::io::FromRawFd; -use crate::sys::fd::FileDesc; - -pub struct Stdin; -pub struct Stdout; -pub struct Stderr; - -impl Stdin { - pub const fn new() -> Stdin { - Stdin - } -} - -impl io::Read for Stdin { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read(buf) } - } - - fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - unsafe { - ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read_vectored(bufs) - } - } - - #[inline] - fn is_read_vectored(&self) -> bool { - true - } -} - -impl Stdout { - pub const fn new() -> Stdout { - Stdout - } -} - -impl io::Write for Stdout { - fn write(&mut self, buf: &[u8]) -> io::Result { - unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write(buf) } - } - - fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - unsafe { - ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write_vectored(bufs) - } - } - - #[inline] - fn is_write_vectored(&self) -> bool { - true - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl Stderr { - pub const fn new() -> Stderr { - Stderr - } -} - -impl io::Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result { - unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write(buf) } - } - - fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - unsafe { - ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write_vectored(bufs) - } - } - - #[inline] - fn is_write_vectored(&self) -> bool { - true - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -pub const STDIN_BUF_SIZE: usize = 128; - -pub fn is_ebadf(err: &io::Error) -> bool { - err.raw_os_error() == Some(hermit_abi::EBADF) -} - -pub fn panic_output() -> Option { - Some(Stderr::new()) -} diff --git a/library/std/src/sys/pal/sgx/abi/mod.rs b/library/std/src/sys/pal/sgx/abi/mod.rs index 90981bd6a6a0..2c805a4d0af0 100644 --- a/library/std/src/sys/pal/sgx/abi/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/mod.rs @@ -6,7 +6,7 @@ use core::sync::atomic::{AtomicUsize, Ordering}; use crate::io::Write; // runtime features -pub(super) mod panic; +pub mod panic; mod reloc; // library features diff --git a/library/std/src/sys/pal/sgx/libunwind_integration.rs b/library/std/src/sys/pal/sgx/libunwind_integration.rs index 6d0d78d1eb9b..b5419ad05dec 100644 --- a/library/std/src/sys/pal/sgx/libunwind_integration.rs +++ b/library/std/src/sys/pal/sgx/libunwind_integration.rs @@ -4,6 +4,7 @@ #![cfg(not(test))] use crate::sys::sync::RwLock; +use crate::{slice, str}; // Verify that the byte pattern libunwind uses to initialize an RwLock is // equivalent to the value of RwLock::new(). If the value changes, @@ -44,3 +45,14 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 { unsafe { (*p).write_unlock() }; return 0; } + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) { + if s < 0 { + return; + } + let buf = unsafe { slice::from_raw_parts(m as *const u8, s as _) }; + if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) { + eprint!("{s}"); + } +} diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 16aa5ab116af..bb419c2530ec 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -18,7 +18,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -pub mod stdio; pub mod thread; pub mod thread_parking; pub mod time; diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index 2c3e50ed5948..e4a61fdcfe3e 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -27,7 +27,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -pub mod stdio; pub use self::itron::{thread, thread_parking}; pub mod time; diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 2aeaf20134ff..41b251215928 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -16,7 +16,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -pub mod stdio; pub mod thread; #[allow(non_upper_case_globals)] #[path = "../unix/time.rs"] diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index 3dc83f6f654b..714dc392688f 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -20,7 +20,6 @@ pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; pub mod process; -pub mod stdio; pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 0565e3ecfb93..419abe732ac3 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -18,7 +18,6 @@ pub mod os; pub mod pipe; pub mod process; pub mod stack_overflow; -pub mod stdio; pub mod sync; pub mod thread; pub mod thread_parking; diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs index 526e5008bd50..bcea699f3b2a 100644 --- a/library/std/src/sys/pal/unsupported/mod.rs +++ b/library/std/src/sys/pal/unsupported/mod.rs @@ -5,7 +5,6 @@ pub mod env; pub mod os; pub mod pipe; pub mod process; -pub mod stdio; pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index a5ae1f513dcb..c89832857dd7 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -25,7 +25,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -pub mod stdio; pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs index d4eb43696737..3008ba887535 100644 --- a/library/std/src/sys/pal/wasip2/mod.rs +++ b/library/std/src/sys/pal/wasip2/mod.rs @@ -22,8 +22,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -#[path = "../wasi/stdio.rs"] -pub mod stdio; #[path = "../wasi/thread.rs"] pub mod thread; #[path = "../wasi/time.rs"] diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs index cfadbdfe00cf..175fe75357fb 100644 --- a/library/std/src/sys/pal/wasm/mod.rs +++ b/library/std/src/sys/pal/wasm/mod.rs @@ -25,8 +25,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -#[path = "../unsupported/stdio.rs"] -pub mod stdio; #[path = "../unsupported/time.rs"] pub mod time; diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index bed79af395b6..6eb68f3a3bc4 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -23,7 +23,6 @@ pub mod handle; pub mod os; pub mod pipe; pub mod process; -pub mod stdio; pub mod thread; pub mod time; cfg_if::cfg_if! { diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs index 3022d717b4a5..7d823012ad14 100644 --- a/library/std/src/sys/pal/xous/mod.rs +++ b/library/std/src/sys/pal/xous/mod.rs @@ -8,7 +8,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -pub mod stdio; pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index ca5b479296de..499e27872015 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -19,7 +19,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -pub mod stdio; #[path = "../unsupported/thread.rs"] pub mod thread; #[path = "../unsupported/time.rs"] diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs new file mode 100644 index 000000000000..2a9167bfe966 --- /dev/null +++ b/library/std/src/sys/stdio/mod.rs @@ -0,0 +1,38 @@ +#![forbid(unsafe_op_in_unsafe_fn)] + +cfg_if::cfg_if! { + if #[cfg(any( + target_family = "unix", + target_os = "hermit" + ))] { + mod unix; + pub use unix::*; + } else if #[cfg(target_os = "windows")] { + mod windows; + pub use windows::*; + } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + mod sgx; + pub use sgx::*; + } else if #[cfg(target_os = "solid_asp3")] { + mod solid; + pub use solid::*; + } else if #[cfg(target_os = "teeos")] { + mod teeos; + pub use teeos::*; + } else if #[cfg(target_os = "uefi")] { + mod uefi; + pub use uefi::*; + } else if #[cfg(target_os = "wasi")] { + mod wasi; + pub use wasi::*; + } else if #[cfg(target_os = "xous")] { + mod xous; + pub use xous::*; + } else if #[cfg(target_os = "zkvm")] { + mod zkvm; + pub use zkvm::*; + } else { + mod unsupported; + pub use unsupported::*; + } +} diff --git a/library/std/src/sys/pal/sgx/stdio.rs b/library/std/src/sys/stdio/sgx.rs similarity index 71% rename from library/std/src/sys/pal/sgx/stdio.rs rename to library/std/src/sys/stdio/sgx.rs index 726a93acae44..03d754cb2173 100644 --- a/library/std/src/sys/pal/sgx/stdio.rs +++ b/library/std/src/sys/stdio/sgx.rs @@ -1,10 +1,6 @@ use fortanix_sgx_abi as abi; use crate::io; -#[cfg(not(test))] -use crate::slice; -#[cfg(not(test))] -use crate::str; use crate::sys::fd::FileDesc; pub struct Stdin(()); @@ -70,19 +66,5 @@ pub fn is_ebadf(err: &io::Error) -> bool { } pub fn panic_output() -> Option { - super::abi::panic::SgxPanicOutput::new() -} - -// This function is needed by libunwind. The symbol is named in pre-link args -// for the target specification, so keep that in sync. -#[cfg(not(test))] -#[unsafe(no_mangle)] -pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) { - if s < 0 { - return; - } - let buf = unsafe { slice::from_raw_parts(m as *const u8, s as _) }; - if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) { - eprint!("{s}"); - } + crate::sys::pal::abi::panic::SgxPanicOutput::new() } diff --git a/library/std/src/sys/pal/solid/stdio.rs b/library/std/src/sys/stdio/solid.rs similarity index 98% rename from library/std/src/sys/pal/solid/stdio.rs rename to library/std/src/sys/stdio/solid.rs index 50f0176967b2..a2ff4bb212ff 100644 --- a/library/std/src/sys/pal/solid/stdio.rs +++ b/library/std/src/sys/stdio/solid.rs @@ -1,5 +1,5 @@ -use super::abi; use crate::io; +use crate::sys::pal::abi; pub struct Stdin; pub struct Stdout; diff --git a/library/std/src/sys/pal/teeos/stdio.rs b/library/std/src/sys/stdio/teeos.rs similarity index 100% rename from library/std/src/sys/pal/teeos/stdio.rs rename to library/std/src/sys/stdio/teeos.rs diff --git a/library/std/src/sys/pal/uefi/stdio.rs b/library/std/src/sys/stdio/uefi.rs similarity index 100% rename from library/std/src/sys/pal/uefi/stdio.rs rename to library/std/src/sys/stdio/uefi.rs diff --git a/library/std/src/sys/pal/unix/stdio.rs b/library/std/src/sys/stdio/unix.rs similarity index 59% rename from library/std/src/sys/pal/unix/stdio.rs rename to library/std/src/sys/stdio/unix.rs index 8c2f61a40de3..8d133857c596 100644 --- a/library/std/src/sys/pal/unix/stdio.rs +++ b/library/std/src/sys/stdio/unix.rs @@ -1,5 +1,15 @@ -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; +#[cfg(target_os = "hermit")] +use hermit_abi::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; +#[cfg(target_family = "unix")] +use libc::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; + +#[cfg(target_family = "unix")] +use crate::io::BorrowedCursor; +use crate::io::{self, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; +#[cfg(target_os = "hermit")] +use crate::os::hermit::io::FromRawFd; +#[cfg(target_family = "unix")] use crate::os::unix::io::FromRawFd; use crate::sys::fd::FileDesc; @@ -15,15 +25,16 @@ impl Stdin { impl io::Read for Stdin { fn read(&mut self, buf: &mut [u8]) -> io::Result { - unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read(buf) } + unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDIN_FILENO)).read(buf) } } + #[cfg(not(target_os = "hermit"))] fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { - unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read_buf(buf) } + unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDIN_FILENO)).read_buf(buf) } } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read_vectored(bufs) } + unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDIN_FILENO)).read_vectored(bufs) } } #[inline] @@ -40,13 +51,11 @@ impl Stdout { impl io::Write for Stdout { fn write(&mut self, buf: &[u8]) -> io::Result { - unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDOUT_FILENO)).write(buf) } + unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDOUT_FILENO)).write(buf) } } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - unsafe { - ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDOUT_FILENO)).write_vectored(bufs) - } + unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDOUT_FILENO)).write_vectored(bufs) } } #[inline] @@ -68,13 +77,11 @@ impl Stderr { impl io::Write for Stderr { fn write(&mut self, buf: &[u8]) -> io::Result { - unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDERR_FILENO)).write(buf) } + unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDERR_FILENO)).write(buf) } } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - unsafe { - ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDERR_FILENO)).write_vectored(bufs) - } + unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDERR_FILENO)).write_vectored(bufs) } } #[inline] @@ -89,7 +96,7 @@ impl io::Write for Stderr { } pub fn is_ebadf(err: &io::Error) -> bool { - err.raw_os_error() == Some(libc::EBADF as i32) + err.raw_os_error() == Some(EBADF as i32) } pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE; diff --git a/library/std/src/sys/pal/unsupported/stdio.rs b/library/std/src/sys/stdio/unsupported.rs similarity index 100% rename from library/std/src/sys/pal/unsupported/stdio.rs rename to library/std/src/sys/stdio/unsupported.rs diff --git a/library/std/src/sys/pal/wasi/stdio.rs b/library/std/src/sys/stdio/wasi.rs similarity index 98% rename from library/std/src/sys/pal/wasi/stdio.rs rename to library/std/src/sys/stdio/wasi.rs index fb21cb4d393d..8105b0cfa2f1 100644 --- a/library/std/src/sys/pal/wasi/stdio.rs +++ b/library/std/src/sys/stdio/wasi.rs @@ -1,10 +1,10 @@ #![forbid(unsafe_op_in_unsafe_fn)] -use super::fd::WasiFd; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; use crate::os::raw; use crate::os::wasi::io::{AsRawFd, FromRawFd}; +use crate::sys::pal::fd::WasiFd; pub struct Stdin; pub struct Stdout; diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/stdio/windows.rs similarity index 99% rename from library/std/src/sys/pal/windows/stdio.rs rename to library/std/src/sys/stdio/windows.rs index 58d3406e1382..9b27f76b9dd1 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/stdio/windows.rs @@ -3,10 +3,10 @@ use core::char::MAX_LEN_UTF8; use core::str::utf8_char_width; -use super::api::{self, WinError}; use crate::mem::MaybeUninit; use crate::os::windows::io::{FromRawHandle, IntoRawHandle}; use crate::sys::handle::Handle; +use crate::sys::pal::api::{self, WinError}; use crate::sys::{c, cvt}; use crate::{cmp, io, ptr, str}; diff --git a/library/std/src/sys/pal/windows/stdio/tests.rs b/library/std/src/sys/stdio/windows/tests.rs similarity index 100% rename from library/std/src/sys/pal/windows/stdio/tests.rs rename to library/std/src/sys/stdio/windows/tests.rs diff --git a/library/std/src/sys/pal/xous/stdio.rs b/library/std/src/sys/stdio/xous.rs similarity index 100% rename from library/std/src/sys/pal/xous/stdio.rs rename to library/std/src/sys/stdio/xous.rs diff --git a/library/std/src/sys/pal/zkvm/stdio.rs b/library/std/src/sys/stdio/zkvm.rs similarity index 97% rename from library/std/src/sys/pal/zkvm/stdio.rs rename to library/std/src/sys/stdio/zkvm.rs index 0bcb54744b0b..f31c6c26e87c 100644 --- a/library/std/src/sys/pal/zkvm/stdio.rs +++ b/library/std/src/sys/stdio/zkvm.rs @@ -1,6 +1,5 @@ -use super::abi; -use super::abi::fileno; use crate::io::{self, BorrowedCursor}; +use crate::sys::pal::abi::{self, fileno}; pub struct Stdin; pub struct Stdout; From 5d6eeea5f969a5a3478de3904e9e02df68ce8b89 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 2 Mar 2025 14:33:29 -0700 Subject: [PATCH 877/991] doctests: fix merging on stable Fixes #137898 The generated multi-test harness relies on nightly-only APIs, so the only way to run it on stable is to enable them. Since tests that use crate attrs don't be merged, there's no way to use nightly-only features on it anyway. --- src/librustdoc/doctest.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 3d6e0330fffa..4f3b233f86e8 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -550,7 +550,12 @@ fn run_test( } compiler.arg("--edition").arg(doctest.edition.to_string()); - if !doctest.is_multiple_tests { + if doctest.is_multiple_tests { + // The merged test harness uses the `test` crate, so we need to actually allow it. + // This will not expose nightly features on stable, because crate attrs disable + // merging, and `#![feature]` is required to be a crate attr. + compiler.env("RUSTC_BOOTSTRAP", "1"); + } else { // Setting these environment variables is unneeded if this is a merged doctest. compiler.env("UNSTABLE_RUSTDOC_TEST_PATH", &doctest.test_opts.path); compiler.env( From 9cf531d26f474917f21a750d8b5fb61bbbae8faa Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 2 Mar 2025 19:37:40 -0700 Subject: [PATCH 878/991] doctests: build test bundle and harness separately This prevents the included test case from getting at nightly-only features when run on stable. The harness builds with RUSTC_BOOTSTRAP, but the bundle doesn't. --- src/librustdoc/doctest.rs | 243 ++++++++++++------ src/librustdoc/doctest/runner.rs | 37 ++- tests/run-make/doctests-merge/rmake.rs | 1 - tests/rustdoc-ui/doctest/doctest-output.rs | 2 +- ...iled-doctest-test-crate.edition2015.stdout | 28 ++ ...iled-doctest-test-crate.edition2024.stdout | 25 ++ .../doctest/failed-doctest-test-crate.rs | 17 ++ 7 files changed, 255 insertions(+), 98 deletions(-) create mode 100644 tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout create mode 100644 tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout create mode 100644 tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 4f3b233f86e8..88af9a7388ce 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -96,7 +96,7 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> .map_err(|error| format!("failed to create args file: {error:?}"))?; // We now put the common arguments into the file we created. - let mut content = vec!["--crate-type=bin".to_string()]; + let mut content = vec![]; for cfg in &options.cfgs { content.push(format!("--cfg={cfg}")); @@ -513,12 +513,18 @@ pub(crate) struct RunnableDocTest { line: usize, edition: Edition, no_run: bool, - is_multiple_tests: bool, + merged_test_code: Option, } impl RunnableDocTest { - fn path_for_merged_doctest(&self) -> PathBuf { - self.test_opts.outdir.path().join(format!("doctest_{}.rs", self.edition)) + fn path_for_merged_doctest_bundle(&self) -> PathBuf { + self.test_opts.outdir.path().join(format!("doctest_bundle_{}.rs", self.edition)) + } + fn path_for_merged_doctest_runner(&self) -> PathBuf { + self.test_opts.outdir.path().join(format!("doctest_runner_{}.rs", self.edition)) + } + fn is_multiple_tests(&self) -> bool { + self.merged_test_code.is_some() } } @@ -537,96 +543,108 @@ fn run_test( let rust_out = add_exe_suffix("rust_out".to_owned(), &rustdoc_options.target); let output_file = doctest.test_opts.outdir.path().join(rust_out); + // Common arguments used for compiling the doctest runner. + // On merged doctests, the compiler is invoked twice: once for the test code itself, + // and once for the runner wrapper (which needs to use `#![feature]` on stable). + let mut compiler_args = vec![]; + + compiler_args.push(format!("@{}", doctest.global_opts.args_file.display())); + + if let Some(sysroot) = &rustdoc_options.maybe_sysroot { + compiler_args.push(format!("--sysroot={}", sysroot.display())); + } + + compiler_args.extend_from_slice(&["--edition".to_owned(), doctest.edition.to_string()]); + if langstr.test_harness { + compiler_args.push("--test".to_owned()); + } + if rustdoc_options.json_unused_externs.is_enabled() && !langstr.compile_fail { + compiler_args.push("--error-format=json".to_owned()); + compiler_args.extend_from_slice(&["--json".to_owned(), "unused-externs".to_owned()]); + compiler_args.extend_from_slice(&["-W".to_owned(), "unused_crate_dependencies".to_owned()]); + compiler_args.extend_from_slice(&["-Z".to_owned(), "unstable-options".to_owned()]); + } + + if doctest.no_run && !langstr.compile_fail && rustdoc_options.persist_doctests.is_none() { + // FIXME: why does this code check if it *shouldn't* persist doctests + // -- shouldn't it be the negation? + compiler_args.push("--emit=metadata".to_owned()); + } + compiler_args.extend_from_slice(&[ + "--target".to_owned(), + match &rustdoc_options.target { + TargetTuple::TargetTuple(s) => s.clone(), + TargetTuple::TargetJson { path_for_rustdoc, .. } => { + path_for_rustdoc.to_str().expect("target path must be valid unicode").to_owned() + } + }, + ]); + if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { + let short = kind.short(); + let unicode = kind == HumanReadableErrorType::Unicode; + + if short { + compiler_args.extend_from_slice(&["--error-format".to_owned(), "short".to_owned()]); + } + if unicode { + compiler_args + .extend_from_slice(&["--error-format".to_owned(), "human-unicode".to_owned()]); + } + + match color_config { + ColorConfig::Never => { + compiler_args.extend_from_slice(&["--color".to_owned(), "never".to_owned()]); + } + ColorConfig::Always => { + compiler_args.extend_from_slice(&["--color".to_owned(), "always".to_owned()]); + } + ColorConfig::Auto => { + compiler_args.extend_from_slice(&[ + "--color".to_owned(), + if supports_color { "always" } else { "never" }.to_owned(), + ]); + } + } + } + let rustc_binary = rustdoc_options .test_builder .as_deref() .unwrap_or_else(|| rustc_interface::util::rustc_path().expect("found rustc")); let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary); - compiler.arg(format!("@{}", doctest.global_opts.args_file.display())); + compiler.args(&compiler_args); - if let Some(sysroot) = &rustdoc_options.maybe_sysroot { - compiler.arg(format!("--sysroot={}", sysroot.display())); - } - - compiler.arg("--edition").arg(doctest.edition.to_string()); - if doctest.is_multiple_tests { - // The merged test harness uses the `test` crate, so we need to actually allow it. - // This will not expose nightly features on stable, because crate attrs disable - // merging, and `#![feature]` is required to be a crate attr. - compiler.env("RUSTC_BOOTSTRAP", "1"); + // If this is a merged doctest, we need to write it into a file instead of using stdin + // because if the size of the merged doctests is too big, it'll simply break stdin. + if doctest.is_multiple_tests() { + // It makes the compilation failure much faster if it is for a combined doctest. + compiler.arg("--error-format=short"); + let input_file = doctest.path_for_merged_doctest_bundle(); + if std::fs::write(&input_file, &doctest.full_test_code).is_err() { + // If we cannot write this file for any reason, we leave. All combined tests will be + // tested as standalone tests. + return Err(TestFailure::CompileError); + } + if !rustdoc_options.nocapture { + // If `nocapture` is disabled, then we don't display rustc's output when compiling + // the merged doctests. + compiler.stderr(Stdio::null()); + } + // bundled tests are an rlib, loaded by a separate runner executable + compiler + .arg("--crate-type=lib") + .arg("--out-dir") + .arg(doctest.test_opts.outdir.path()) + .arg(input_file); } else { + compiler.arg("--crate-type=bin").arg("-o").arg(&output_file); // Setting these environment variables is unneeded if this is a merged doctest. compiler.env("UNSTABLE_RUSTDOC_TEST_PATH", &doctest.test_opts.path); compiler.env( "UNSTABLE_RUSTDOC_TEST_LINE", format!("{}", doctest.line as isize - doctest.full_test_line_offset as isize), ); - } - compiler.arg("-o").arg(&output_file); - if langstr.test_harness { - compiler.arg("--test"); - } - if rustdoc_options.json_unused_externs.is_enabled() && !langstr.compile_fail { - compiler.arg("--error-format=json"); - compiler.arg("--json").arg("unused-externs"); - compiler.arg("-W").arg("unused_crate_dependencies"); - compiler.arg("-Z").arg("unstable-options"); - } - - if doctest.no_run && !langstr.compile_fail && rustdoc_options.persist_doctests.is_none() { - // FIXME: why does this code check if it *shouldn't* persist doctests - // -- shouldn't it be the negation? - compiler.arg("--emit=metadata"); - } - compiler.arg("--target").arg(match &rustdoc_options.target { - TargetTuple::TargetTuple(s) => s, - TargetTuple::TargetJson { path_for_rustdoc, .. } => { - path_for_rustdoc.to_str().expect("target path must be valid unicode") - } - }); - if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { - let short = kind.short(); - let unicode = kind == HumanReadableErrorType::Unicode; - - if short { - compiler.arg("--error-format").arg("short"); - } - if unicode { - compiler.arg("--error-format").arg("human-unicode"); - } - - match color_config { - ColorConfig::Never => { - compiler.arg("--color").arg("never"); - } - ColorConfig::Always => { - compiler.arg("--color").arg("always"); - } - ColorConfig::Auto => { - compiler.arg("--color").arg(if supports_color { "always" } else { "never" }); - } - } - } - - // If this is a merged doctest, we need to write it into a file instead of using stdin - // because if the size of the merged doctests is too big, it'll simply break stdin. - if doctest.is_multiple_tests { - // It makes the compilation failure much faster if it is for a combined doctest. - compiler.arg("--error-format=short"); - let input_file = doctest.path_for_merged_doctest(); - if std::fs::write(&input_file, &doctest.full_test_code).is_err() { - // If we cannot write this file for any reason, we leave. All combined tests will be - // tested as standalone tests. - return Err(TestFailure::CompileError); - } - compiler.arg(input_file); - if !rustdoc_options.nocapture { - // If `nocapture` is disabled, then we don't display rustc's output when compiling - // the merged doctests. - compiler.stderr(Stdio::null()); - } - } else { compiler.arg("-"); compiler.stdin(Stdio::piped()); compiler.stderr(Stdio::piped()); @@ -635,8 +653,65 @@ fn run_test( debug!("compiler invocation for doctest: {compiler:?}"); let mut child = compiler.spawn().expect("Failed to spawn rustc process"); - let output = if doctest.is_multiple_tests { + let output = if let Some(merged_test_code) = &doctest.merged_test_code { + // compile-fail tests never get merged, so this should always pass let status = child.wait().expect("Failed to wait"); + + // the actual test runner is a separate component, built with nightly-only features; + // build it now + let runner_input_file = doctest.path_for_merged_doctest_runner(); + + let mut runner_compiler = + wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary); + // the test runner does not contain any user-written code, so this doesn't allow + // the user to exploit nightly-only features on stable + runner_compiler.env("RUSTC_BOOTSTRAP", "1"); + runner_compiler.args(compiler_args); + runner_compiler.args(&["--crate-type=bin", "-o"]).arg(&output_file); + let mut extern_path = std::ffi::OsString::from(format!( + "--extern=doctest_bundle_{edition}=", + edition = doctest.edition + )); + for extern_str in &rustdoc_options.extern_strs { + if let Some((_cratename, path)) = extern_str.split_once('=') { + // Direct dependencies of the tests themselves are + // indirect dependencies of the test runner. + // They need to be in the library search path. + let dir = Path::new(path) + .parent() + .filter(|x| x.components().count() > 0) + .unwrap_or(Path::new(".")); + runner_compiler.arg("-L").arg(dir); + } + } + let output_bundle_file = doctest + .test_opts + .outdir + .path() + .join(format!("libdoctest_bundle_{edition}.rlib", edition = doctest.edition)); + extern_path.push(&output_bundle_file); + runner_compiler.arg(extern_path); + runner_compiler.arg(&runner_input_file); + if std::fs::write(&runner_input_file, &merged_test_code).is_err() { + // If we cannot write this file for any reason, we leave. All combined tests will be + // tested as standalone tests. + return Err(TestFailure::CompileError); + } + if !rustdoc_options.nocapture { + // If `nocapture` is disabled, then we don't display rustc's output when compiling + // the merged doctests. + runner_compiler.stderr(Stdio::null()); + } + runner_compiler.arg("--error-format=short"); + debug!("compiler invocation for doctest runner: {runner_compiler:?}"); + + let status = if !status.success() { + status + } else { + let mut child_runner = runner_compiler.spawn().expect("Failed to spawn rustc process"); + child_runner.wait().expect("Failed to wait") + }; + process::Output { status, stdout: Vec::new(), stderr: Vec::new() } } else { let stdin = child.stdin.as_mut().expect("Failed to open stdin"); @@ -713,7 +788,7 @@ fn run_test( cmd.arg(&output_file); } else { cmd = Command::new(&output_file); - if doctest.is_multiple_tests { + if doctest.is_multiple_tests() { cmd.env("RUSTDOC_DOCTEST_BIN_PATH", &output_file); } } @@ -721,7 +796,7 @@ fn run_test( cmd.current_dir(run_directory); } - let result = if doctest.is_multiple_tests || rustdoc_options.nocapture { + let result = if doctest.is_multiple_tests() || rustdoc_options.nocapture { cmd.status().map(|status| process::Output { status, stdout: Vec::new(), @@ -1008,7 +1083,7 @@ fn doctest_run_fn( line: scraped_test.line, edition: scraped_test.edition(&rustdoc_options), no_run: scraped_test.no_run(&rustdoc_options), - is_multiple_tests: false, + merged_test_code: None, }; let res = run_test(runnable_test, &rustdoc_options, doctest.supports_color, report_unused_externs); diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs index 234f40c6c1ab..58efa35711a0 100644 --- a/src/librustdoc/doctest/runner.rs +++ b/src/librustdoc/doctest/runner.rs @@ -14,6 +14,7 @@ pub(crate) struct DocTestRunner { crate_attrs: FxIndexSet, ids: String, output: String, + output_merged_tests: String, supports_color: bool, nb_tests: usize, } @@ -24,6 +25,7 @@ impl DocTestRunner { crate_attrs: FxIndexSet::default(), ids: String::new(), output: String::new(), + output_merged_tests: String::new(), supports_color: true, nb_tests: 0, } @@ -55,7 +57,8 @@ impl DocTestRunner { scraped_test, ignore, self.nb_tests, - &mut self.output + &mut self.output, + &mut self.output_merged_tests, ), )); self.supports_color &= doctest.supports_color; @@ -78,9 +81,11 @@ impl DocTestRunner { " .to_string(); + let mut code_prefix = String::new(); + for crate_attr in &self.crate_attrs { - code.push_str(crate_attr); - code.push('\n'); + code_prefix.push_str(crate_attr); + code_prefix.push('\n'); } if opts.attrs.is_empty() { @@ -88,15 +93,16 @@ impl DocTestRunner { // lints that are commonly triggered in doctests. The crate-level test attributes are // commonly used to make tests fail in case they trigger warnings, so having this there in // that case may cause some tests to pass when they shouldn't have. - code.push_str("#![allow(unused)]\n"); + code_prefix.push_str("#![allow(unused)]\n"); } // Next, any attributes that came from the crate root via #![doc(test(attr(...)))]. for attr in &opts.attrs { - code.push_str(&format!("#![{attr}]\n")); + code_prefix.push_str(&format!("#![{attr}]\n")); } code.push_str("extern crate test;\n"); + writeln!(code, "extern crate doctest_bundle_{edition} as doctest_bundle;").unwrap(); let test_args = test_args.iter().fold(String::new(), |mut x, arg| { write!(x, "{arg:?}.to_string(),").unwrap(); @@ -161,12 +167,12 @@ the same process\"); std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)) }}", nb_tests = self.nb_tests, - output = self.output, + output = self.output_merged_tests, ids = self.ids, ) .expect("failed to generate test code"); let runnable_test = RunnableDocTest { - full_test_code: code, + full_test_code: format!("{code_prefix}{code}", code = self.output), full_test_line_offset: 0, test_opts: test_options, global_opts: opts.clone(), @@ -174,7 +180,7 @@ std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), N line: 0, edition, no_run: false, - is_multiple_tests: true, + merged_test_code: Some(code), }; let ret = run_test(runnable_test, rustdoc_options, self.supports_color, |_: UnusedExterns| {}); @@ -189,14 +195,15 @@ fn generate_mergeable_doctest( ignore: bool, id: usize, output: &mut String, + output_merged_tests: &mut String, ) -> String { let test_id = format!("__doctest_{id}"); if ignore { // We generate nothing else. - writeln!(output, "mod {test_id} {{\n").unwrap(); + writeln!(output, "pub mod {test_id} {{}}\n").unwrap(); } else { - writeln!(output, "mod {test_id} {{\n{}{}", doctest.crates, doctest.maybe_crate_attrs) + writeln!(output, "pub mod {test_id} {{\n{}{}", doctest.crates, doctest.maybe_crate_attrs) .unwrap(); if doctest.has_main_fn { output.push_str(&doctest.everything_else); @@ -216,11 +223,17 @@ fn main() {returns_result} {{ ) .unwrap(); } + writeln!( + output, + "\npub fn __main_fn() -> impl std::process::Termination {{ main() }} \n}}\n" + ) + .unwrap(); } let not_running = ignore || scraped_test.langstr.no_run; writeln!( - output, + output_merged_tests, " +mod {test_id} {{ pub const TEST: test::TestDescAndFn = test::TestDescAndFn::new_doctest( {test_name:?}, {ignore}, {file:?}, {line}, {no_run}, {should_panic}, test::StaticTestFn( @@ -242,7 +255,7 @@ test::StaticTestFn( if let Some(bin_path) = crate::__doctest_mod::doctest_path() {{ test::assert_test_result(crate::__doctest_mod::doctest_runner(bin_path, {id})) }} else {{ - test::assert_test_result(self::main()) + test::assert_test_result(doctest_bundle::{test_id}::__main_fn()) }} ", ) diff --git a/tests/run-make/doctests-merge/rmake.rs b/tests/run-make/doctests-merge/rmake.rs index a25da7403e24..a88b050c50fa 100644 --- a/tests/run-make/doctests-merge/rmake.rs +++ b/tests/run-make/doctests-merge/rmake.rs @@ -8,7 +8,6 @@ fn test_and_compare(input_file: &str, stdout_file: &str, edition: &str, dep: &Pa let output = cmd .input(input_file) .arg("--test") - .arg("-Zunstable-options") .edition(edition) .arg("--test-args=--test-threads=1") .extern_("foo", dep.display().to_string()) diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs index fb4ab0680001..04bd1813b4c8 100644 --- a/tests/rustdoc-ui/doctest/doctest-output.rs +++ b/tests/rustdoc-ui/doctest/doctest-output.rs @@ -2,7 +2,7 @@ //@[edition2015]edition:2015 //@[edition2015]aux-build:extern_macros.rs //@[edition2015]compile-flags:--test --test-args=--test-threads=1 -//@[edition2024]edition:2015 +//@[edition2024]edition:2024 //@[edition2024]aux-build:extern_macros.rs //@[edition2024]compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" diff --git a/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout new file mode 100644 index 000000000000..ce767fb8443d --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout @@ -0,0 +1,28 @@ + +running 1 test +test $DIR/failed-doctest-test-crate.rs - m (line 14) ... FAILED + +failures: + +---- $DIR/failed-doctest-test-crate.rs - m (line 14) stdout ---- +error[E0432]: unresolved import `test` + --> $DIR/failed-doctest-test-crate.rs:15:5 + | +LL | use test::*; + | ^^^^ use of unresolved module or unlinked crate `test` + | +help: you might be missing a crate named `test`, add it to your project and import it in your code + | +LL + extern crate test; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0432`. +Couldn't compile the test. + +failures: + $DIR/failed-doctest-test-crate.rs - m (line 14) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout new file mode 100644 index 000000000000..80642e93bbde --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout @@ -0,0 +1,25 @@ + +running 1 test +test $DIR/failed-doctest-test-crate.rs - m (line 14) ... FAILED + +failures: + +---- $DIR/failed-doctest-test-crate.rs - m (line 14) stdout ---- +error[E0432]: unresolved import `test` + --> $DIR/failed-doctest-test-crate.rs:15:5 + | +LL | use test::*; + | ^^^^ use of unresolved module or unlinked crate `test` + | + = help: you might be missing a crate named `test` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0432`. +Couldn't compile the test. + +failures: + $DIR/failed-doctest-test-crate.rs - m (line 14) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs new file mode 100644 index 000000000000..6966d3df11ce --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs @@ -0,0 +1,17 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ revisions: edition2015 edition2024 +//@[edition2015]edition:2015 +//@[edition2024]edition:2024 +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +/// +/// +/// ```rust +/// use test::*; +/// ``` +pub mod m {} From 1c7aaf95e1bb77c99437fa260f84124ac30808f0 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 1 Feb 2025 19:35:47 +0000 Subject: [PATCH 879/991] Update rand to 0.9.0 --- Cargo.lock | 14 +++++++------- compiler/rustc_abi/Cargo.toml | 8 ++++---- compiler/rustc_incremental/Cargo.toml | 2 +- compiler/rustc_incremental/src/persist/fs.rs | 4 ++-- src/etc/test-float-parse/Cargo.toml | 4 ++-- src/etc/test-float-parse/src/gen/fuzz.rs | 8 ++++---- src/etc/test-float-parse/src/gen/many_digits.rs | 14 +++++++------- src/etc/test-float-parse/src/lib.rs | 4 ++-- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecd26d6199c9..ea93fbd01f06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2881,11 +2881,11 @@ dependencies = [ [[package]] name = "rand_xoshiro" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.9.0", ] [[package]] @@ -3155,7 +3155,7 @@ name = "rustc_abi" version = "0.0.0" dependencies = [ "bitflags", - "rand 0.8.5", + "rand 0.9.0", "rand_xoshiro", "rustc_data_structures", "rustc_hashes", @@ -3789,7 +3789,7 @@ dependencies = [ name = "rustc_incremental" version = "0.0.0" dependencies = [ - "rand 0.8.5", + "rand 0.9.0", "rustc_ast", "rustc_data_structures", "rustc_errors", @@ -5176,8 +5176,8 @@ version = "0.1.0" dependencies = [ "indicatif", "num", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.9.0", + "rand_chacha 0.9.0", "rayon", ] diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 4713b3474bdb..9cb6619adc95 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -6,13 +6,13 @@ edition = "2024" [dependencies] # tidy-alphabetical-start bitflags = "2.4.1" -rand = { version = "0.8.4", default-features = false, optional = true } -rand_xoshiro = { version = "0.6.0", optional = true } -rustc_data_structures = { path = "../rustc_data_structures", optional = true } +rand = { version = "0.9.0", default-features = false, optional = true } +rand_xoshiro = { version = "0.7.0", optional = true } +rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } -rustc_serialize = { path = "../rustc_serialize", optional = true } +rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index 754881309bf5..4e5061f4f69e 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -rand = "0.8.4" +rand = "0.9.0" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 19cca48af612..76a1ff3cf382 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -108,7 +108,7 @@ use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use rand::{RngCore, thread_rng}; +use rand::{RngCore, rng}; use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::svh::Svh; @@ -445,7 +445,7 @@ fn copy_files(sess: &Session, target_dir: &Path, source_dir: &Path) -> Result PathBuf { let timestamp = timestamp_to_string(SystemTime::now()); debug!("generate_session_dir_path: timestamp = {}", timestamp); - let random_number = thread_rng().next_u32(); + let random_number = rng().next_u32(); debug!("generate_session_dir_path: random_number = {}", random_number); // Chop the first 3 characters off the timestamp. Those 3 bytes will be zero for a while. diff --git a/src/etc/test-float-parse/Cargo.toml b/src/etc/test-float-parse/Cargo.toml index 56cb5cddeea5..bacb9e09f3f6 100644 --- a/src/etc/test-float-parse/Cargo.toml +++ b/src/etc/test-float-parse/Cargo.toml @@ -7,8 +7,8 @@ publish = false [dependencies] indicatif = { version = "0.17.8", default-features = false } num = "0.4.3" -rand = "0.8.5" -rand_chacha = "0.3" +rand = "0.9.0" +rand_chacha = "0.9.0" rayon = "1" [lib] diff --git a/src/etc/test-float-parse/src/gen/fuzz.rs b/src/etc/test-float-parse/src/gen/fuzz.rs index 7fc999d16711..1d6c5562a14c 100644 --- a/src/etc/test-float-parse/src/gen/fuzz.rs +++ b/src/etc/test-float-parse/src/gen/fuzz.rs @@ -6,7 +6,7 @@ use std::ops::Range; use std::sync::Mutex; use rand::Rng; -use rand::distributions::{Distribution, Standard}; +use rand::distr::{Distribution, StandardUniform}; use rand_chacha::ChaCha8Rng; use rand_chacha::rand_core::SeedableRng; @@ -47,7 +47,7 @@ impl Fuzz { impl Generator for Fuzz where - Standard: Distribution<::Int>, + StandardUniform: Distribution<::Int>, { const SHORT_NAME: &'static str = "fuzz"; @@ -74,13 +74,13 @@ where impl Iterator for Fuzz where - Standard: Distribution<::Int>, + StandardUniform: Distribution<::Int>, { type Item = >::WriteCtx; fn next(&mut self) -> Option { let _ = self.iter.next()?; - let i: F::Int = self.rng.gen(); + let i: F::Int = self.rng.random(); Some(F::from_bits(i)) } diff --git a/src/etc/test-float-parse/src/gen/many_digits.rs b/src/etc/test-float-parse/src/gen/many_digits.rs index aab8d5d704be..741e11437fe2 100644 --- a/src/etc/test-float-parse/src/gen/many_digits.rs +++ b/src/etc/test-float-parse/src/gen/many_digits.rs @@ -3,7 +3,7 @@ use std::fmt::Write; use std::marker::PhantomData; use std::ops::{Range, RangeInclusive}; -use rand::distributions::{Distribution, Uniform}; +use rand::distr::{Distribution, Uniform}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; @@ -40,7 +40,7 @@ impl Generator for RandDigits { fn new() -> Self { let rng = ChaCha8Rng::from_seed(SEED); - let range = Uniform::from(0..10); + let range = Uniform::try_from(0..10).unwrap(); Self { rng, iter: 0..ITERATIONS, uniform: range, marker: PhantomData } } @@ -55,11 +55,11 @@ impl Iterator for RandDigits { fn next(&mut self) -> Option { let _ = self.iter.next()?; - let num_digits = self.rng.gen_range(POSSIBLE_NUM_DIGITS); - let has_decimal = self.rng.gen_bool(0.2); - let has_exp = self.rng.gen_bool(0.2); + let num_digits = self.rng.random_range(POSSIBLE_NUM_DIGITS); + let has_decimal = self.rng.random_bool(0.2); + let has_exp = self.rng.random_bool(0.2); - let dec_pos = if has_decimal { Some(self.rng.gen_range(0..num_digits)) } else { None }; + let dec_pos = if has_decimal { Some(self.rng.random_range(0..num_digits)) } else { None }; let mut s = String::with_capacity(num_digits); @@ -75,7 +75,7 @@ impl Iterator for RandDigits { } if has_exp { - let exp = self.rng.gen_range(EXP_RANGE); + let exp = self.rng.random_range(EXP_RANGE); write!(s, "e{exp}").unwrap(); } diff --git a/src/etc/test-float-parse/src/lib.rs b/src/etc/test-float-parse/src/lib.rs index def66398d9fd..e2f84b085c6f 100644 --- a/src/etc/test-float-parse/src/lib.rs +++ b/src/etc/test-float-parse/src/lib.rs @@ -10,7 +10,7 @@ use std::sync::OnceLock; use std::sync::atomic::{AtomicU64, Ordering}; use std::{fmt, time}; -use rand::distributions::{Distribution, Standard}; +use rand::distr::{Distribution, StandardUniform}; use rayon::prelude::*; use time::{Duration, Instant}; use traits::{Float, Generator, Int}; @@ -132,7 +132,7 @@ fn register_float(tests: &mut Vec, cfg: &Config) where RangeInclusive: Iterator, >::Error: std::fmt::Debug, - Standard: Distribution<::Int>, + StandardUniform: Distribution<::Int>, { if F::BITS <= MAX_BITS_FOR_EXHAUUSTIVE { // Only run exhaustive tests if there is a chance of completion. From 9b71e86724923db15636fd8f0acc44f04be986ca Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 1 Feb 2025 19:50:04 +0000 Subject: [PATCH 880/991] Allow wit-bindgen-rt as compiler dependency --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 51e58b4e4fcf..b8d1d8103f23 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -446,6 +446,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", + "wit-bindgen-rt", // via wasi "writeable", "yoke", "yoke-derive", From aea9ddd745e6184dafeb0d0e3bab491910d0754b Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sun, 2 Mar 2025 14:10:32 +0000 Subject: [PATCH 881/991] Support locking versions in permitted rustc deps --- src/tools/tidy/src/deps.rs | 41 +++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index b8d1d8103f23..5434e708bb71 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -1,11 +1,12 @@ //! Checks the licenses of third-party dependencies. -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::fs::{File, read_dir}; use std::io::Write; use std::path::Path; use build_helper::ci::CiEnv; +use cargo_metadata::semver::Version; use cargo_metadata::{Metadata, Package, PackageId}; #[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"] @@ -446,7 +447,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", - "wit-bindgen-rt", // via wasi + "wit-bindgen-rt@0.33.0", // via wasi "writeable", "yoke", "yoke-derive", @@ -804,7 +805,17 @@ fn check_permitted_dependencies( // Check that the PERMITTED_DEPENDENCIES does not have unused entries. for permitted in permitted_dependencies { - if !deps.iter().any(|dep_id| &pkg_from_id(metadata, dep_id).name == permitted) { + fn compare(pkg: &Package, permitted: &str) -> bool { + if let Some((name, version)) = permitted.split_once("@") { + let Ok(version) = Version::parse(version) else { + return false; + }; + pkg.name == name && pkg.version == version + } else { + pkg.name == permitted + } + } + if !deps.iter().any(|dep_id| compare(pkg_from_id(metadata, dep_id), permitted)) { tidy_error!( bad, "could not find allowed package `{permitted}`\n\ @@ -815,14 +826,30 @@ fn check_permitted_dependencies( } // Get in a convenient form. - let permitted_dependencies: HashSet<_> = permitted_dependencies.iter().cloned().collect(); + let permitted_dependencies: HashMap<_, _> = permitted_dependencies + .iter() + .map(|s| { + if let Some((name, version)) = s.split_once('@') { + (name, Version::parse(version).ok()) + } else { + (*s, None) + } + }) + .collect(); for dep in deps { let dep = pkg_from_id(metadata, dep); // If this path is in-tree, we don't require it to be explicitly permitted. - if dep.source.is_some() && !permitted_dependencies.contains(dep.name.as_str()) { - tidy_error!(bad, "Dependency for {descr} not explicitly permitted: {}", dep.id); - has_permitted_dep_error = true; + if dep.source.is_some() { + let is_eq = if let Some(version) = permitted_dependencies.get(dep.name.as_str()) { + if let Some(version) = version { version == &dep.version } else { true } + } else { + false + }; + if !is_eq { + tidy_error!(bad, "Dependency for {descr} not explicitly permitted: {}", dep.id); + has_permitted_dep_error = true; + } } } From 6a38322d2608a480b38da6efd926627950bc0537 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Mar 2025 14:43:36 +0000 Subject: [PATCH 882/991] Rename print_something to should_render --- .../rustc_attr_data_structures/src/lib.rs | 40 +++++++++++-------- compiler/rustc_macros/src/print_attribute.rs | 10 ++--- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index be00d1c10e0c..16ff4183ef5f 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -34,13 +34,17 @@ pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStabl /// like [`Span`]s and empty tuples, are gracefully skipped so they don't clutter the /// representation much. pub trait PrintAttribute { - fn print_something(&self) -> bool; + /// Whether or not this will render as something meaningful, or if it's skipped + /// (which will force the containing struct to also skip printing a comma + /// and the field name). + fn should_render(&self) -> bool; + fn print_attribute(&self, p: &mut Printer); } impl PrintAttribute for &T { - fn print_something(&self) -> bool { - T::print_something(self) + fn should_render(&self) -> bool { + T::should_render(self) } fn print_attribute(&self, p: &mut Printer) { @@ -48,9 +52,10 @@ impl PrintAttribute for &T { } } impl PrintAttribute for Option { - fn print_something(&self) -> bool { - self.as_ref().is_some_and(|x| x.print_something()) + fn should_render(&self) -> bool { + self.as_ref().is_some_and(|x| x.should_render()) } + fn print_attribute(&self, p: &mut Printer) { if let Some(i) = self { T::print_attribute(i, p) @@ -58,9 +63,10 @@ impl PrintAttribute for Option { } } impl PrintAttribute for ThinVec { - fn print_something(&self) -> bool { - self.is_empty() || self[0].print_something() + fn should_render(&self) -> bool { + self.is_empty() || self[0].should_render() } + fn print_attribute(&self, p: &mut Printer) { let mut last_printed = false; p.word("["); @@ -69,7 +75,7 @@ impl PrintAttribute for ThinVec { p.word_space(","); } i.print_attribute(p); - last_printed = i.print_something(); + last_printed = i.should_render(); } p.word("]"); } @@ -77,7 +83,7 @@ impl PrintAttribute for ThinVec { macro_rules! print_skip { ($($t: ty),* $(,)?) => {$( impl PrintAttribute for $t { - fn print_something(&self) -> bool { false } + fn should_render(&self) -> bool { false } fn print_attribute(&self, _: &mut Printer) { } })* }; @@ -86,7 +92,7 @@ macro_rules! print_skip { macro_rules! print_disp { ($($t: ty),* $(,)?) => {$( impl PrintAttribute for $t { - fn print_something(&self) -> bool { true } + fn should_render(&self) -> bool { true } fn print_attribute(&self, p: &mut Printer) { p.word(format!("{}", self)); } @@ -96,7 +102,7 @@ macro_rules! print_disp { macro_rules! print_debug { ($($t: ty),* $(,)?) => {$( impl PrintAttribute for $t { - fn print_something(&self) -> bool { true } + fn should_render(&self) -> bool { true } fn print_attribute(&self, p: &mut Printer) { p.word(format!("{:?}", self)); } @@ -105,29 +111,29 @@ macro_rules! print_debug { } macro_rules! print_tup { - (num_print_something $($ts: ident)*) => { 0 $(+ $ts.print_something() as usize)* }; + (num_should_render $($ts: ident)*) => { 0 $(+ $ts.should_render() as usize)* }; () => {}; ($t: ident $($ts: ident)*) => { #[allow(non_snake_case, unused)] impl<$t: PrintAttribute, $($ts: PrintAttribute),*> PrintAttribute for ($t, $($ts),*) { - fn print_something(&self) -> bool { + fn should_render(&self) -> bool { let ($t, $($ts),*) = self; - print_tup!(num_print_something $t $($ts)*) != 0 + print_tup!(num_should_render $t $($ts)*) != 0 } fn print_attribute(&self, p: &mut Printer) { let ($t, $($ts),*) = self; - let parens = print_tup!(num_print_something $t $($ts)*) > 1; + let parens = print_tup!(num_should_render $t $($ts)*) > 1; if parens { p.word("("); } - let mut printed_anything = $t.print_something(); + let mut printed_anything = $t.should_render(); $t.print_attribute(p); $( - if printed_anything && $ts.print_something() { + if $ts.should_render() { p.word_space(","); printed_anything = true; } diff --git a/compiler/rustc_macros/src/print_attribute.rs b/compiler/rustc_macros/src/print_attribute.rs index 3c6e30b851bf..fe78fb15cb95 100644 --- a/compiler/rustc_macros/src/print_attribute.rs +++ b/compiler/rustc_macros/src/print_attribute.rs @@ -16,7 +16,7 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok let name = field.ident.as_ref().unwrap(); let string_name = name.to_string(); disps.push(quote! { - if __printed_anything && #name.print_something() { + if __printed_anything && #name.should_render() { __p.word_space(","); __printed_anything = true; } @@ -31,7 +31,7 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok quote! { {#(#field_names),*} }, quote! { __p.word(#string_name); - if true #(&& !#field_names.print_something())* { + if true #(&& !#field_names.should_render())* { return; } @@ -48,7 +48,7 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok for idx in 0..fields_unnamed.unnamed.len() { let name = format_ident!("f{idx}"); disps.push(quote! { - if __printed_anything && #name.print_something() { + if __printed_anything && #name.should_render() { __p.word_space(","); __printed_anything = true; } @@ -62,7 +62,7 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok quote! { __p.word(#string_name); - if true #(&& !#field_names.print_something())* { + if true #(&& !#field_names.should_render())* { return; } @@ -138,7 +138,7 @@ pub(crate) fn print_attribute(input: Structure<'_>) -> TokenStream { input.gen_impl(quote! { #[allow(unused)] gen impl PrintAttribute for @Self { - fn print_something(&self) -> bool { #printed } + fn should_render(&self) -> bool { #printed } fn print_attribute(&self, __p: &mut rustc_ast_pretty::pp::Printer) { #code } } }) From 279377f87aa1871e1011366b6cf997cfa24e3d65 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Mar 2025 15:20:16 +0000 Subject: [PATCH 883/991] Fix pretty printing of parsed attrs in hir_pretty --- .../rustc_attr_data_structures/src/lib.rs | 12 ++++++----- compiler/rustc_hir_pretty/src/lib.rs | 4 ++-- compiler/rustc_macros/src/print_attribute.rs | 21 ++++++++++++------- tests/pretty/hir-pretty-attr.pp | 2 +- .../rustdoc-json/enums/discriminant/struct.rs | 2 +- .../rustdoc-json/enums/discriminant/tuple.rs | 2 +- tests/ui/unpretty/deprecated-attr.rs | 2 -- tests/ui/unpretty/deprecated-attr.stdout | 21 ++++++++----------- 8 files changed, 34 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index 16ff4183ef5f..bbd3308809c3 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -125,7 +125,7 @@ macro_rules! print_tup { let ($t, $($ts),*) = self; let parens = print_tup!(num_should_render $t $($ts)*) > 1; if parens { - p.word("("); + p.popen(); } let mut printed_anything = $t.should_render(); @@ -134,14 +134,16 @@ macro_rules! print_tup { $( if $ts.should_render() { - p.word_space(","); + if printed_anything { + p.word_space(","); + } printed_anything = true; } $ts.print_attribute(p); )* if parens { - p.word(")"); + p.pclose(); } } } @@ -152,8 +154,8 @@ macro_rules! print_tup { print_tup!(A B C D E F G H); print_skip!(Span, ()); -print_disp!(Symbol, u16, bool, NonZero); -print_debug!(UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency); +print_disp!(u16, bool, NonZero); +print_debug!(Symbol, UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency); /// Finds attributes in sequences of attributes by pattern matching. /// diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 0e3721126fb3..2769b5343a05 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -117,9 +117,9 @@ impl<'a> State<'a> { self.hardbreak() } hir::Attribute::Parsed(pa) => { - self.word("#[attr=\""); + self.word("#[attr = "); pa.print_attribute(self); - self.word("\")]"); + self.word("]"); self.hardbreak() } } diff --git a/compiler/rustc_macros/src/print_attribute.rs b/compiler/rustc_macros/src/print_attribute.rs index fe78fb15cb95..42d94e72ee94 100644 --- a/compiler/rustc_macros/src/print_attribute.rs +++ b/compiler/rustc_macros/src/print_attribute.rs @@ -16,12 +16,14 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok let name = field.ident.as_ref().unwrap(); let string_name = name.to_string(); disps.push(quote! { - if __printed_anything && #name.should_render() { - __p.word_space(","); + if #name.should_render() { + if __printed_anything { + __p.word_space(","); + } + __p.word(#string_name); + __p.word_space(":"); __printed_anything = true; } - __p.word(#string_name); - __p.word_space(":"); #name.print_attribute(__p); }); field_names.push(name); @@ -35,6 +37,7 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok return; } + __p.nbsp(); __p.word("{"); #(#disps)* __p.word("}"); @@ -48,8 +51,10 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok for idx in 0..fields_unnamed.unnamed.len() { let name = format_ident!("f{idx}"); disps.push(quote! { - if __printed_anything && #name.should_render() { - __p.word_space(","); + if #name.should_render() { + if __printed_anything { + __p.word_space(","); + } __printed_anything = true; } #name.print_attribute(__p); @@ -66,9 +71,9 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok return; } - __p.word("("); + __p.popen(); #(#disps)* - __p.word(")"); + __p.pclose(); }, quote! { true }, ) diff --git a/tests/pretty/hir-pretty-attr.pp b/tests/pretty/hir-pretty-attr.pp index 586810b00466..d8cc8c424ca5 100644 --- a/tests/pretty/hir-pretty-attr.pp +++ b/tests/pretty/hir-pretty-attr.pp @@ -6,6 +6,6 @@ extern crate std; //@ pretty-mode:hir //@ pp-exact:hir-pretty-attr.pp -#[attr="Repr([ReprC, ReprPacked(Align(4 bytes)), ReprTransparent])")] +#[attr = Repr([ReprC, ReprPacked(Align(4 bytes)), ReprTransparent])] struct Example { } diff --git a/tests/rustdoc-json/enums/discriminant/struct.rs b/tests/rustdoc-json/enums/discriminant/struct.rs index 82437f5ef03b..f2bed77902b0 100644 --- a/tests/rustdoc-json/enums/discriminant/struct.rs +++ b/tests/rustdoc-json/enums/discriminant/struct.rs @@ -1,5 +1,5 @@ #[repr(i32)] -//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(SignedInt(I32))])\")]\n"]' +//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]' pub enum Foo { //@ is "$.index[*][?(@.name=='Struct')].inner.variant.discriminant" null //@ count "$.index[*][?(@.name=='Struct')].inner.variant.kind.struct.fields[*]" 0 diff --git a/tests/rustdoc-json/enums/discriminant/tuple.rs b/tests/rustdoc-json/enums/discriminant/tuple.rs index 25bba07e8f79..201c1cdc88e7 100644 --- a/tests/rustdoc-json/enums/discriminant/tuple.rs +++ b/tests/rustdoc-json/enums/discriminant/tuple.rs @@ -1,5 +1,5 @@ #[repr(u32)] -//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(UnsignedInt(U32))])\")]\n"]' +//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(U32))])]\n"]' pub enum Foo { //@ is "$.index[*][?(@.name=='Tuple')].inner.variant.discriminant" null //@ count "$.index[*][?(@.name=='Tuple')].inner.variant.kind.tuple[*]" 0 diff --git a/tests/ui/unpretty/deprecated-attr.rs b/tests/ui/unpretty/deprecated-attr.rs index 24a32d8a9acf..dda362a595e2 100644 --- a/tests/ui/unpretty/deprecated-attr.rs +++ b/tests/ui/unpretty/deprecated-attr.rs @@ -1,8 +1,6 @@ //@ compile-flags: -Zunpretty=hir //@ check-pass -// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is -// slightly broken. #[deprecated] pub struct PlainDeprecated; diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout index 675351351a0c..42de7b4533e5 100644 --- a/tests/ui/unpretty/deprecated-attr.stdout +++ b/tests/ui/unpretty/deprecated-attr.stdout @@ -5,24 +5,21 @@ extern crate std; //@ compile-flags: -Zunpretty=hir //@ check-pass -// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is -// slightly broken. -#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote: -suggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] struct PlainDeprecated; -#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote: -here's why this is deprecatedsuggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, note: +"here's why this is deprecated"}}] struct DirectNote; -#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote: -here's why this is deprecatedsuggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, note: +"here's why this is deprecated"}}] struct ExplicitNote; -#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note: -here's why this is deprecatedsuggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"), +note: "here's why this is deprecated"}}] struct SinceAndNote; -#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note: -here's why this is deprecatedsuggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"), +note: "here's why this is deprecated"}}] struct FlippedOrder; From f525b173edd08cf68f025a5b2db38b665887771d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 10 Mar 2025 02:31:16 +0000 Subject: [PATCH 884/991] Remove AdtFlags::IS_ANONYMOUS and Copy/Clone condition for anonymous ADT --- compiler/rustc_middle/src/ty/adt.rs | 8 -------- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_trait_selection/src/traits/select/mod.rs | 9 --------- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 3585f28b4a55..c1dc6a894cae 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -53,8 +53,6 @@ bitflags::bitflags! { const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 8; /// Indicates whether the type is `UnsafeCell`. const IS_UNSAFE_CELL = 1 << 9; - /// Indicates whether the type is anonymous. - const IS_ANONYMOUS = 1 << 10; } } rustc_data_structures::external_bitflags_debug! { AdtFlags } @@ -402,12 +400,6 @@ impl<'tcx> AdtDef<'tcx> { self.flags().contains(AdtFlags::IS_MANUALLY_DROP) } - /// Returns `true` if this is an anonymous adt - #[inline] - pub fn is_anonymous(self) -> bool { - self.flags().contains(AdtFlags::IS_ANONYMOUS) - } - /// Returns `true` if this type has a destructor. pub fn has_dtor(self, tcx: TyCtxt<'tcx>) -> bool { self.destructor(tcx).is_some() diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c5509c0a6087..97cfe5946af1 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1151,7 +1151,7 @@ pub struct VariantDef { /// `DefId` that identifies the variant's constructor. /// If this variant is a struct variant, then this is `None`. pub ctor: Option<(CtorKind, DefId)>, - /// Variant or struct name, maybe empty for anonymous adt (struct or union). + /// Variant or struct name. pub name: Symbol, /// Discriminant of this variant. pub discr: VariantDiscr, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0a54b8468fe3..e1adabbeaa66 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2231,15 +2231,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } - // `Copy` and `Clone` are automatically implemented for an anonymous adt - // if all of its fields are `Copy` and `Clone` - ty::Adt(adt, args) if adt.is_anonymous() => { - // (*) binder moved here - Where(obligation.predicate.rebind( - adt.non_enum_variant().fields.iter().map(|f| f.ty(self.tcx(), args)).collect(), - )) - } - ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => { // Fallback to whatever user-defined impls exist in this case. None From 1833737e165ffc78b9b6318ab5bea7478945cc7a Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sun, 9 Mar 2025 15:18:40 +0530 Subject: [PATCH 885/991] uefi: fs: Implement FilePermission - UEFI file permissions are indicated using a u64 bitfield used for readonly/filetype, etc. - Using normal bool with to and from attribute conversions to FilePermission from overriding some other bitfields. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 37 +++++++++++++++------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 45e93deffa3a..9b8fd5997893 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -6,6 +6,9 @@ use crate::path::{Path, PathBuf}; use crate::sys::time::SystemTime; use crate::sys::unsupported; +#[expect(dead_code)] +const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY; + pub struct File(!); pub struct FileAttr(!); @@ -20,7 +23,9 @@ pub struct OpenOptions {} #[derive(Copy, Clone, Debug, Default)] pub struct FileTimes {} -pub struct FilePermissions(!); +#[derive(Clone, PartialEq, Eq, Debug)] +// Bool indicates if file is readonly +pub struct FilePermissions(bool); pub struct FileType(!); @@ -64,28 +69,18 @@ impl FilePermissions { self.0 } - pub fn set_readonly(&mut self, _readonly: bool) { - self.0 + pub fn set_readonly(&mut self, readonly: bool) { + self.0 = readonly } -} -impl Clone for FilePermissions { - fn clone(&self) -> FilePermissions { - self.0 + #[expect(dead_code)] + const fn from_attr(attr: u64) -> Self { + Self(attr & r_efi::protocols::file::READ_ONLY != 0) } -} -impl PartialEq for FilePermissions { - fn eq(&self, _other: &FilePermissions) -> bool { - self.0 - } -} - -impl Eq for FilePermissions {} - -impl fmt::Debug for FilePermissions { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 + #[expect(dead_code)] + const fn to_attr(&self) -> u64 { + if self.0 { r_efi::protocols::file::READ_ONLY } else { 0 } } } @@ -303,8 +298,8 @@ pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> { unsupported() } -pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> { - match perm.0 {} +pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { + unsupported() } pub fn rmdir(_p: &Path) -> io::Result<()> { From c717cc7cd2e2ce9f3da069abd7781f366a87e64e Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sun, 9 Mar 2025 15:39:04 +0530 Subject: [PATCH 886/991] uefi: fs: Implement FileType - Similar to FilePermissions, using bool to represent the bitfield. - FileType cannot be changed, so no need to worry about converting back to attribute. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 40 +++++++++------------------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 9b8fd5997893..188f712fb844 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -1,6 +1,6 @@ use crate::ffi::OsString; use crate::fmt; -use crate::hash::{Hash, Hasher}; +use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; use crate::sys::time::SystemTime; @@ -27,7 +27,9 @@ pub struct FileTimes {} // Bool indicates if file is readonly pub struct FilePermissions(bool); -pub struct FileType(!); +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +// Bool indicates if directory +pub struct FileType(bool); #[derive(Debug)] pub struct DirBuilder {} @@ -95,39 +97,17 @@ impl FileType { } pub fn is_file(&self) -> bool { - self.0 + !self.is_dir() } + // Symlinks are not supported in UEFI pub fn is_symlink(&self) -> bool { - self.0 + false } -} -impl Clone for FileType { - fn clone(&self) -> FileType { - self.0 - } -} - -impl Copy for FileType {} - -impl PartialEq for FileType { - fn eq(&self, _other: &FileType) -> bool { - self.0 - } -} - -impl Eq for FileType {} - -impl Hash for FileType { - fn hash(&self, _h: &mut H) { - self.0 - } -} - -impl fmt::Debug for FileType { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 + #[expect(dead_code)] + const fn from_attr(attr: u64) -> Self { + Self(attr & r_efi::protocols::file::DIRECTORY != 0) } } From e0a9dd31c1998108184c59c3da8812b561017f85 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sun, 9 Mar 2025 15:50:54 +0530 Subject: [PATCH 887/991] uefi: fs: Partially implement FileAttr - Just the permission and file type. - FileTimes will need some new conversion functions and thus will come with a future PR. Trying to keep things simple here. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 188f712fb844..56aed7dfd8e8 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -11,7 +11,11 @@ const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY; pub struct File(!); -pub struct FileAttr(!); +#[derive(Clone)] +pub struct FileAttr { + attr: u64, + size: u64, +} pub struct ReadDir(!); @@ -36,33 +40,27 @@ pub struct DirBuilder {} impl FileAttr { pub fn size(&self) -> u64 { - self.0 + self.size } pub fn perm(&self) -> FilePermissions { - self.0 + FilePermissions::from_attr(self.attr) } pub fn file_type(&self) -> FileType { - self.0 + FileType::from_attr(self.attr) } pub fn modified(&self) -> io::Result { - self.0 + unsupported() } pub fn accessed(&self) -> io::Result { - self.0 + unsupported() } pub fn created(&self) -> io::Result { - self.0 - } -} - -impl Clone for FileAttr { - fn clone(&self) -> FileAttr { - self.0 + unsupported() } } @@ -75,7 +73,6 @@ impl FilePermissions { self.0 = readonly } - #[expect(dead_code)] const fn from_attr(attr: u64) -> Self { Self(attr & r_efi::protocols::file::READ_ONLY != 0) } @@ -105,7 +102,6 @@ impl FileType { false } - #[expect(dead_code)] const fn from_attr(attr: u64) -> Self { Self(attr & r_efi::protocols::file::DIRECTORY != 0) } From 295c70ef03d442c608d0dda0c14c06598c034411 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 9 Mar 2025 13:03:06 -0400 Subject: [PATCH 888/991] Fix O(tests) stack usage in edition 2024 mergeable doctests --- src/librustdoc/doctest/runner.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs index 234f40c6c1ab..5ff90efe77c2 100644 --- a/src/librustdoc/doctest/runner.rs +++ b/src/librustdoc/doctest/runner.rs @@ -45,11 +45,8 @@ impl DocTestRunner { self.crate_attrs.insert(line.to_string()); } } - if !self.ids.is_empty() { - self.ids.push(','); - } self.ids.push_str(&format!( - "{}::TEST", + "tests.push({}::TEST);\n", generate_mergeable_doctest( doctest, scraped_test, @@ -136,7 +133,11 @@ mod __doctest_mod {{ #[rustc_main] fn main() -> std::process::ExitCode {{ -const TESTS: [test::TestDescAndFn; {nb_tests}] = [{ids}]; +let tests = {{ + let mut tests = Vec::with_capacity({nb_tests}); + {ids} + tests +}}; let test_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION); let test_args = &[{test_args}]; const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\"; @@ -144,11 +145,11 @@ const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\"; if let Ok(binary) = std::env::var(ENV_BIN) {{ let _ = crate::__doctest_mod::BINARY_PATH.set(binary.into()); unsafe {{ std::env::remove_var(ENV_BIN); }} - return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)); + return std::process::Termination::report(test::test_main(test_args, tests, None)); }} else if let Ok(nb_test) = std::env::var(__doctest_mod::RUN_OPTION) {{ if let Ok(nb_test) = nb_test.parse::() {{ - if let Some(test) = TESTS.get(nb_test) {{ - if let test::StaticTestFn(f) = test.testfn {{ + if let Some(test) = tests.get(nb_test) {{ + if let test::StaticTestFn(f) = &test.testfn {{ return std::process::Termination::report(f()); }} }} @@ -158,7 +159,7 @@ if let Ok(binary) = std::env::var(ENV_BIN) {{ eprintln!(\"WARNING: No rustdoc doctest environment variable provided so doctests will be run in \ the same process\"); -std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)) +std::process::Termination::report(test::test_main(test_args, tests, None)) }}", nb_tests = self.nb_tests, output = self.output, From b827087a41869d4ad01398eefa7b491e2c68b1e9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 10 Mar 2025 08:33:53 +0100 Subject: [PATCH 889/991] add tracking issue for unqualified_local_imports --- compiler/rustc_feature/src/unstable.rs | 2 +- .../feature-gates/feature-gate-unqualified-local-imports.stderr | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 7741f6668c38..3c61bfd1c93f 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -240,7 +240,7 @@ declare_features! ( /// Added for testing unstable lints; perma-unstable. (internal, test_unstable_lint, "1.60.0", None), /// Helps with formatting for `group_imports = "StdExternalCrate"`. - (unstable, unqualified_local_imports, "1.83.0", None), + (unstable, unqualified_local_imports, "1.83.0", Some(138299)), /// Use for stable + negative coherence and strict coherence depending on trait's /// rustc_strict_coherence value. (unstable, with_negative_coherence, "1.60.0", None), diff --git a/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr b/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr index bc8edd847cc0..30e36acb871a 100644 --- a/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr +++ b/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr @@ -5,6 +5,7 @@ LL | #![allow(unqualified_local_imports)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `unqualified_local_imports` lint is unstable + = note: see issue #138299 for more information = help: add `#![feature(unqualified_local_imports)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `#[warn(unknown_lints)]` on by default From 7ee9ce8480305fdb5362145f80d5a4abfe087d78 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 10 Mar 2025 07:19:14 +0100 Subject: [PATCH 890/991] Fix `path` macro hygiene --- src/tools/rust-analyzer/crates/hir-expand/src/lib.rs | 2 ++ src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs | 4 ++-- src/tools/rust-analyzer/crates/hir/src/lib.rs | 1 + src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index 41603e3c92e3..c1d808cbf2c5 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -5,6 +5,8 @@ //! expansion. #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +pub use intern; + pub mod attrs; pub mod builtin; pub mod change; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index f0cf7ebf479f..75b586145405 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -388,7 +388,7 @@ macro_rules! __path { ($start:ident $(:: $seg:ident)*) => ({ $crate::__known_path!($start $(:: $seg)*); $crate::mod_path::ModPath::from_segments($crate::mod_path::PathKind::Abs, vec![ - $crate::name::Name::new_symbol_root(intern::sym::$start.clone()), $($crate::name::Name::new_symbol_root(intern::sym::$seg.clone()),)* + $crate::name::Name::new_symbol_root($crate::intern::sym::$start.clone()), $($crate::name::Name::new_symbol_root($crate::intern::sym::$seg.clone()),)* ]) }); } @@ -399,7 +399,7 @@ pub use crate::__path as path; macro_rules! __tool_path { ($start:ident $(:: $seg:ident)*) => ({ $crate::mod_path::ModPath::from_segments($crate::mod_path::PathKind::Plain, vec![ - $crate::name::Name::new_symbol_root(intern::sym::rust_analyzer.clone()), $crate::name::Name::new_symbol_root(intern::sym::$start.clone()), $($crate::name::Name::new_symbol_root(intern::sym::$seg.clone()),)* + $crate::name::Name::new_symbol_root($crate::intern::sym::rust_analyzer.clone()), $crate::name::Name::new_symbol_root($crate::intern::sym::$start.clone()), $($crate::name::Name::new_symbol_root($crate::intern::sym::$seg.clone()),)* ]) }); } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 7549d54a544e..cb667767d737 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -139,6 +139,7 @@ pub use { }, hygiene::{marks_rev, SyntaxContextExt}, inert_attr_macro::AttributeTemplate, + mod_path::tool_path, name::Name, prettify_macro_expansion, proc_macro::{ProcMacros, ProcMacrosBuilder}, diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index be0de6c93661..6b77c72cee89 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -185,6 +185,7 @@ define_symbols! { Clone, coerce_unsized, column, + completion, compile_error, concat_bytes, concat_idents, From fdee1c1455481516e61381dcd93a0adab2b64dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 10 Mar 2025 10:41:28 +0200 Subject: [PATCH 891/991] Preparing for merge from rust-lang/rust --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index e24e08d0687d..0db4be8ff639 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -daf59857d6d2b87af4b846316bf1561a6083ed51 +2c6a12ec44d0426c8939123c2f2cf27d2217de13 From 02bb2d4410d4db07c40bed308f8ba0d2af28d069 Mon Sep 17 00:00:00 2001 From: Bastian Kersting Date: Tue, 4 Mar 2025 14:31:03 +0000 Subject: [PATCH 892/991] Disable CFI for weakly linked syscalls Currently, when enabling CFI via -Zsanitizer=cfi and executing e.g. std::sys::random::getrandom, we can observe a CFI violation. This is the case for all consumers of the std::sys::pal::weak::weak macro, as it is defining weak functions which don't show up in LLVM IR metadata. CFI fails for all these functions. Similar to other such cases in https://github.com/rust-lang/rust/issues/115199, this change stops emitting the CFI typecheck for consumers of the macro via the \#[no_sanitize(cfi)] attribute. --- library/std/src/sys/fs/unix.rs | 12 ++++++++++++ library/std/src/sys/pal/unix/fd.rs | 1 + library/std/src/sys/pal/unix/process/process_unix.rs | 1 + library/std/src/sys/pal/unix/thread.rs | 1 + library/std/src/sys/pal/unix/time.rs | 9 +++++++++ library/std/src/sys/pal/unix/weak.rs | 3 +++ 6 files changed, 27 insertions(+) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 914971934bfb..d95735978c19 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1454,6 +1454,18 @@ impl File { Ok(()) } + #[cfg_attr( + any( + target_os = "android", + all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") + ) + ), + no_sanitize(cfi) + )] pub fn set_times(&self, times: FileTimes) -> io::Result<()> { #[cfg(not(any( target_os = "redox", diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs index 2fc33bdfefbf..6da329288f74 100644 --- a/library/std/src/sys/pal/unix/fd.rs +++ b/library/std/src/sys/pal/unix/fd.rs @@ -251,6 +251,7 @@ impl FileDesc { } #[cfg(all(target_os = "android", target_pointer_width = "32"))] + #[no_sanitize(cfi)] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize); diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 25d9e9353320..6d3680d231e6 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -434,6 +434,7 @@ impl Command { target_os = "nto", target_vendor = "apple", ))] + #[cfg_attr(target_os = "linux", no_sanitize(cfi))] fn posix_spawn( &mut self, stdio: &ChildPipes, diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 11f6998cac11..33db8e6939a4 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -188,6 +188,7 @@ impl Thread { } #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))] + #[no_sanitize(cfi)] pub fn set_name(name: &CStr) { weak! { fn pthread_setname_np( diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 0271626380c5..fc60c307f34e 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -96,6 +96,15 @@ impl Timespec { } } + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") + ), + no_sanitize(cfi) + )] pub fn now(clock: libc::clockid_t) -> Timespec { use crate::mem::MaybeUninit; use crate::sys::cvt; diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs index 7ec4787f1eab..9a718b71f469 100644 --- a/library/std/src/sys/pal/unix/weak.rs +++ b/library/std/src/sys/pal/unix/weak.rs @@ -144,6 +144,9 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void { #[cfg(not(any(target_os = "linux", target_os = "android")))] pub(crate) macro syscall { (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( + // FIXME: Rust currently omits weak function definitions + // and its metadata from LLVM IR. + #[no_sanitize(cfi)] unsafe fn $name($($arg_name: $t),*) -> $ret { weak! { fn $name($($t),*) -> $ret } From e5dc1e378619b11b296a953ca08abb2cdf38f9e0 Mon Sep 17 00:00:00 2001 From: Bastian Kersting Date: Mon, 10 Mar 2025 08:59:24 +0000 Subject: [PATCH 893/991] Add comments for #[no_sanitize(cfi)] in stdlib --- library/std/src/sys/fs/unix.rs | 2 ++ library/std/src/sys/pal/unix/fd.rs | 2 ++ library/std/src/sys/pal/unix/process/process_unix.rs | 2 ++ library/std/src/sys/pal/unix/thread.rs | 2 ++ library/std/src/sys/pal/unix/time.rs | 2 ++ library/std/src/sys/pal/unix/weak.rs | 2 +- 6 files changed, 11 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index d95735978c19..d944bc9c9a2a 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1454,6 +1454,8 @@ impl File { Ok(()) } + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[cfg_attr( any( target_os = "android", diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs index 6da329288f74..a08c7ccec2da 100644 --- a/library/std/src/sys/pal/unix/fd.rs +++ b/library/std/src/sys/pal/unix/fd.rs @@ -251,6 +251,8 @@ impl FileDesc { } #[cfg(all(target_os = "android", target_pointer_width = "32"))] + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[no_sanitize(cfi)] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize); diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 6d3680d231e6..be9a7e919905 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -434,6 +434,8 @@ impl Command { target_os = "nto", target_vendor = "apple", ))] + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[cfg_attr(target_os = "linux", no_sanitize(cfi))] fn posix_spawn( &mut self, diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 33db8e6939a4..abe8d3fbf681 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -188,6 +188,8 @@ impl Thread { } #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))] + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[no_sanitize(cfi)] pub fn set_name(name: &CStr) { weak! { diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index fc60c307f34e..c0a3044660b7 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -96,6 +96,8 @@ impl Timespec { } } + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[cfg_attr( all( target_os = "linux", diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs index 9a718b71f469..ce3f66a83748 100644 --- a/library/std/src/sys/pal/unix/weak.rs +++ b/library/std/src/sys/pal/unix/weak.rs @@ -144,7 +144,7 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void { #[cfg(not(any(target_os = "linux", target_os = "android")))] pub(crate) macro syscall { (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - // FIXME: Rust currently omits weak function definitions + // FIXME(#115199): Rust currently omits weak function definitions // and its metadata from LLVM IR. #[no_sanitize(cfi)] unsafe fn $name($($arg_name: $t),*) -> $ret { From 1483cb67d91f493c9e8599cc969a03ae1b846435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Mar 2025 10:07:03 +0100 Subject: [PATCH 894/991] Handle empty test suites in job summary report --- src/ci/citool/src/metrics.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ci/citool/src/metrics.rs b/src/ci/citool/src/metrics.rs index 8548602b31cb..83b3d5ceed05 100644 --- a/src/ci/citool/src/metrics.rs +++ b/src/ci/citool/src/metrics.rs @@ -67,6 +67,10 @@ fn render_table(suites: BTreeMap) -> String { let mut table = "| Test suite | Passed ✅ | Ignored 🚫 | Failed ❌ |\n".to_string(); writeln!(table, "|:------|------:|------:|------:|").unwrap(); + fn compute_pct(value: f64, total: f64) -> f64 { + if total == 0.0 { 0.0 } else { value / total } + } + fn write_row( buffer: &mut String, name: &str, @@ -75,9 +79,9 @@ fn render_table(suites: BTreeMap) -> String { ) -> std::fmt::Result { let TestSuiteRecord { passed, ignored, failed } = record; let total = (record.passed + record.ignored + record.failed) as f64; - let passed_pct = ((*passed as f64) / total) * 100.0; - let ignored_pct = ((*ignored as f64) / total) * 100.0; - let failed_pct = ((*failed as f64) / total) * 100.0; + let passed_pct = compute_pct(*passed as f64, total) * 100.0; + let ignored_pct = compute_pct(*ignored as f64, total) * 100.0; + let failed_pct = compute_pct(*failed as f64, total) * 100.0; write!(buffer, "| {surround}{name}{surround} |")?; write!(buffer, " {surround}{passed} ({passed_pct:.0}%){surround} |")?; From ee79f3e9dc6a7ebcb371ab6213f4b4a74b4a3d72 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 10 Mar 2025 09:39:02 +0100 Subject: [PATCH 895/991] Run proc-macro server tests are separate CI job Touch tt --- .../rust-analyzer/.github/workflows/ci.yaml | 70 ++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index 1b011c90d031..7a6b43a05315 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -35,19 +35,48 @@ jobs: typescript: - 'editors/code/**' proc_macros: + - 'crates/tt/**' - 'crates/proc-macro-api/**' - 'crates/proc-macro-srv/**' - 'crates/proc-macro-srv-cli/**' - rust: + proc-macro-srv: needs: changes + if: github.repository == 'rust-lang/rust-analyzer' && needs.changes.outputs.proc_macros == 'true' + name: proc-macro-srv + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Install Rust toolchain + run: | + rustup update --no-self-update nightly + rustup default nightly + rustup component add --toolchain nightly rust-src rustfmt + # https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/rust.json + - name: Install Rust Problem Matcher + if: matrix.os == 'ubuntu-latest' + run: echo "::add-matcher::.github/rust.json" + + - name: Cache Dependencies + uses: Swatinem/rust-cache@9bdad043e88c75890e36ad3bbc8d27f0090dd609 + + - name: Bump opt-level + if: matrix.os == 'ubuntu-latest' + run: sed -i '/\[profile.dev]/a opt-level=1' Cargo.toml + + - name: Test + run: cargo test --features sysroot-abi -p rust-analyzer -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api -- --quiet + + rust: if: github.repository == 'rust-lang/rust-analyzer' name: Rust runs-on: ${{ matrix.os }} env: CC: deny_c - RUST_CHANNEL: "${{ needs.changes.outputs.proc_macros == 'true' && 'nightly' || 'stable' }}" - USE_SYSROOT_ABI: "${{ needs.changes.outputs.proc_macros == 'true' && '--features sysroot-abi' || '' }}" strategy: fail-fast: false @@ -62,9 +91,9 @@ jobs: - name: Install Rust toolchain run: | - rustup update --no-self-update ${{ env.RUST_CHANNEL }} - rustup default ${{ env.RUST_CHANNEL }} - rustup component add --toolchain ${{ env.RUST_CHANNEL }} rust-src + rustup update --no-self-update stable + rustup default stable + rustup component add --toolchain stable rust-src # We always use a nightly rustfmt, regardless of channel, because we need # --file-lines. rustup toolchain install nightly --profile minimal --component rustfmt @@ -75,8 +104,6 @@ jobs: - name: Cache Dependencies uses: Swatinem/rust-cache@9bdad043e88c75890e36ad3bbc8d27f0090dd609 - with: - key: ${{ env.RUST_CHANNEL }} - name: Bump opt-level if: matrix.os == 'ubuntu-latest' @@ -86,16 +113,16 @@ jobs: run: cargo codegen --check - name: Compile (tests) - run: cargo test --no-run --locked ${{ env.USE_SYSROOT_ABI }} + run: cargo test --no-run --locked # It's faster to `test` before `build` ¯\_(ツ)_/¯ - name: Compile (rust-analyzer) if: matrix.os == 'ubuntu-latest' - run: cargo build --quiet ${{ env.USE_SYSROOT_ABI }} + run: cargo build --quiet - name: Test if: matrix.os == 'ubuntu-latest' || matrix.os == 'windows-latest' || github.event_name == 'push' - run: cargo test ${{ env.USE_SYSROOT_ABI }} -- --nocapture --quiet + run: cargo test -- --quiet - name: Switch to stable toolchain run: | @@ -156,7 +183,7 @@ jobs: typescript: needs: changes - if: github.repository == 'rust-lang/rust-analyzer' + if: github.repository == 'rust-lang/rust-analyzer' && needs.changes.outputs.typescript == 'true' name: TypeScript strategy: fail-fast: false @@ -168,21 +195,18 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - if: needs.changes.outputs.typescript == 'true' - name: Install Nodejs uses: actions/setup-node@v4 with: node-version: 22 - if: needs.changes.outputs.typescript == 'true' - name: Install xvfb - if: matrix.os == 'ubuntu-latest' && needs.changes.outputs.typescript == 'true' + if: matrix.os == 'ubuntu-latest' run: sudo apt-get install -y xvfb - run: npm ci working-directory: ./editors/code - if: needs.changes.outputs.typescript == 'true' # - run: npm audit || { sleep 10 && npm audit; } || { sleep 30 && npm audit; } # if: runner.os == 'Linux' @@ -191,27 +215,24 @@ jobs: # If this steps fails, your code's type integrity might be wrong at some places at TypeScript level. - run: npm run typecheck working-directory: ./editors/code - if: needs.changes.outputs.typescript == 'true' # You may fix the code automatically by running `npm run lint:fix` if this steps fails. - run: npm run lint working-directory: ./editors/code - if: needs.changes.outputs.typescript == 'true' # To fix this steps, please run `npm run format`. - run: npm run format:check working-directory: ./editors/code - if: needs.changes.outputs.typescript == 'true' - name: Run VS Code tests (Linux) - if: matrix.os == 'ubuntu-latest' && needs.changes.outputs.typescript == 'true' + if: matrix.os == 'ubuntu-latest' env: VSCODE_CLI: 1 run: xvfb-run npm test working-directory: ./editors/code - name: Run VS Code tests (Windows) - if: matrix.os == 'windows-latest' && needs.changes.outputs.typescript == 'true' + if: matrix.os == 'windows-latest' env: VSCODE_CLI: 1 run: npm test @@ -219,7 +240,6 @@ jobs: - run: npm run package --scripts-prepend-node-path working-directory: ./editors/code - if: needs.changes.outputs.typescript == 'true' typo-check: name: Typo Check @@ -241,7 +261,7 @@ jobs: run: typos conclusion: - needs: [rust, rust-cross, typescript, typo-check] + needs: [rust, rust-cross, typescript, typo-check, proc-macro-srv] # We need to ensure this job does *not* get skipped if its dependencies fail, # because a skipped job is considered a success by GitHub. So we have to # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run @@ -256,5 +276,5 @@ jobs: run: | # Print the dependent jobs to see them in the CI log jq -C <<< '${{ toJson(needs) }}' - # Check if all jobs that we depend on (in the needs array) were successful. - jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' + # Check if all jobs that we depend on (in the needs array) were successful (or have been skipped). + jq --exit-status 'all(.result == "success" or .result == "skipped")' <<< '${{ toJson(needs) }}' From 87d5bf2b9287287f59f015558e090fbe35d5292b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 10 Mar 2025 11:20:56 +0200 Subject: [PATCH 896/991] Bump rustc crates --- src/tools/rust-analyzer/Cargo.lock | 29 +++++++++---------- src/tools/rust-analyzer/Cargo.toml | 12 ++++---- .../rust-analyzer/crates/hir-ty/Cargo.toml | 1 - .../rust-analyzer/crates/hir-ty/src/lib.rs | 3 -- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index c57953ba6547..5ff46abcfe39 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -626,7 +626,6 @@ dependencies = [ "oorandom", "project-model", "ra-ap-rustc_abi", - "ra-ap-rustc_hashes", "ra-ap-rustc_index", "ra-ap-rustc_pattern_analysis", "rustc-hash 2.0.0", @@ -1504,9 +1503,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_abi" -version = "0.98.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b42cccfff8091a4c3397736518774dbad619e82f8def6f70d8e46dbbe396007" +checksum = "f1651b0f7e8c3eb7c27a88f39d277e69c32bfe58e3be174d286c1a24d6a7a4d8" dependencies = [ "bitflags 2.7.0", "ra-ap-rustc_hashes", @@ -1516,18 +1515,18 @@ dependencies = [ [[package]] name = "ra-ap-rustc_hashes" -version = "0.98.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46d8bd34ed6552c8cac1764106ef5adbeef3e5c7700e0ceb4c83a47a631894fe" +checksum = "2bcd85e93dc0ea850bcfe7957a115957df799ccbc9eea488bdee5ec6780d212b" dependencies = [ "rustc-stable-hash", ] [[package]] name = "ra-ap-rustc_index" -version = "0.98.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93799e4dccbbd47f8b66bc0aa42effc1b7077aaee09d8a40b86b8d659b80c7b7" +checksum = "62b295fc0640cd9fe0ecab872ee4a17a96f90a3998ec9f0c4765e9b8415c12cc" dependencies = [ "ra-ap-rustc_index_macros", "smallvec", @@ -1535,9 +1534,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index_macros" -version = "0.98.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30baa5d00f94ba437a9dcaf7ae074ebe4f367bb05a4c2835e0aa2e7af3463aac" +checksum = "c675f4257023aa933882906f13802cae287e88cc39ab13cbb96809083db0c801" dependencies = [ "proc-macro2", "quote", @@ -1546,9 +1545,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_lexer" -version = "0.98.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3004d1d1b50afe3e1f9cdd428a282da7ffbf5f26dd8bf04af0d651d44e4873d8" +checksum = "c8358702c2a510ea84ba5801ddc047d9ad9520902cfb0e6173277610cdce2c9c" dependencies = [ "memchr", "unicode-properties", @@ -1557,9 +1556,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_parse_format" -version = "0.98.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb57e5124a64aaaf92c06130fbc1b8e1d547b5a2a96081f1f848e31c211df5d2" +checksum = "b98f402011d46732c35c47bfd111dec0495747fef2ec900ddee7fe15d78449a7" dependencies = [ "ra-ap-rustc_index", "ra-ap-rustc_lexer", @@ -1567,9 +1566,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.98.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e427c3d30e4bdff28abd6b0ef3e6f4dfab44acd9468a4954eeff8717d8df8819" +checksum = "bef3ff73fa4653252ffe1d1e9177a446f49ef46d97140e4816b7ff2dad59ed53" dependencies = [ "ra-ap-rustc_index", "rustc-hash 2.0.0", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 1132acb64741..70b654433463 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -85,12 +85,12 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } edition = { path = "./crates/edition", version = "0.0.0" } -ra-ap-rustc_hashes = { version = "0.98", default-features = false } -ra-ap-rustc_lexer = { version = "0.98", default-features = false } -ra-ap-rustc_parse_format = { version = "0.98", default-features = false } -ra-ap-rustc_index = { version = "0.98", default-features = false } -ra-ap-rustc_abi = { version = "0.98", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.98", default-features = false } +ra-ap-rustc_hashes = { version = "0.100", default-features = false } +ra-ap-rustc_lexer = { version = "0.100", default-features = false } +ra-ap-rustc_parse_format = { version = "0.100", default-features = false } +ra-ap-rustc_index = { version = "0.100", default-features = false } +ra-ap-rustc_abi = { version = "0.100", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.100", default-features = false } # local crates that aren't published to crates.io. These should not have versions. diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml index 27849f3b449d..1d12bee646c4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml @@ -35,7 +35,6 @@ indexmap.workspace = true rustc_apfloat = "0.2.0" ra-ap-rustc_abi.workspace = true -ra-ap-rustc_hashes.workspace = true ra-ap-rustc_index.workspace = true ra-ap-rustc_pattern_analysis.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index e0dcc01821ec..f636de479c41 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -21,9 +21,6 @@ extern crate rustc_pattern_analysis; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis; -#[cfg(not(feature = "in-rust-tree"))] -extern crate ra_ap_rustc_hashes as rustc_hashes; - mod builder; mod chalk_db; mod chalk_ext; From c372c55f2b9fa1997619f7569e3a88b9d8a92024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 10 Mar 2025 11:21:03 +0200 Subject: [PATCH 897/991] Fix simd layout test --- src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index 4d3896660b47..8b74b7328bd8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs @@ -342,7 +342,7 @@ fn simd_types() { check_size_and_align( r#" #[repr(simd)] - struct SimdType(i64, i64); + struct SimdType([i64; 2]); struct Goal(SimdType); "#, "", From f38819ce17a5e2bfcaf58982956597214d5d034f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 30 Jan 2025 07:56:43 +0000 Subject: [PATCH 898/991] Add some layout tests for pattern type edge cases --- tests/ui/type/pattern_types/range_patterns.rs | 21 +- .../type/pattern_types/range_patterns.stderr | 210 +++++++++++++++++- 2 files changed, 229 insertions(+), 2 deletions(-) diff --git a/tests/ui/type/pattern_types/range_patterns.rs b/tests/ui/type/pattern_types/range_patterns.rs index 446a33195c8b..3aa8426178a1 100644 --- a/tests/ui/type/pattern_types/range_patterns.rs +++ b/tests/ui/type/pattern_types/range_patterns.rs @@ -1,4 +1,4 @@ -#![feature(pattern_types, rustc_attrs)] +#![feature(pattern_types, rustc_attrs, const_trait_impl, pattern_type_range_trait)] #![feature(pattern_type_macro)] #![allow(incomplete_features)] @@ -18,6 +18,25 @@ type A = Option; //~ ERROR layout_of #[rustc_layout(debug)] struct NonZeroU32New(pattern_type!(u32 is 1..)); //~ ERROR layout_of +#[rustc_layout(debug)] +type EMPTY = pattern_type!(u32 is 1..1); //~ ERROR layout_of + +#[rustc_layout(debug)] +type WRAP = pattern_type!(u32 is 1..0); //~ ERROR unknown layout +//~^ ERROR: evaluation of constant value failed + +#[rustc_layout(debug)] +type WRAP2 = pattern_type!(u32 is 5..2); //~ ERROR layout_of + +#[rustc_layout(debug)] +type SIGN = pattern_type!(i8 is -10..=10); //~ ERROR layout_of + +#[rustc_layout(debug)] +type MIN = pattern_type!(i8 is -128..=0); //~ ERROR layout_of + +#[rustc_layout(debug)] +type SignedWrap = pattern_type!(i8 is 120..=-120); //~ ERROR layout_of + fn main() { let x: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(42_u32) }; } diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index cb24a303404c..b6abcf462249 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -357,5 +357,213 @@ error: layout_of(NonZeroU32New) = Layout { LL | struct NonZeroU32New(pattern_type!(u32 is 1..)); | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: layout_of((u32) is 1..=0) = Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + backend_repr: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: (..=0) | (1..), + }, + ), + fields: Primitive, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: (..=0) | (1..), + }, + ), + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, + } + --> $DIR/range_patterns.rs:22:1 + | +LL | type EMPTY = pattern_type!(u32 is 1..1); + | ^^^^^^^^^^ +error[E0080]: evaluation of constant value failed + --> $DIR/range_patterns.rs:25:37 + | +LL | type WRAP = pattern_type!(u32 is 1..0); + | ^ evaluation panicked: exclusive range end at minimum value of type + +error: the type has an unknown layout + --> $DIR/range_patterns.rs:25:1 + | +LL | type WRAP = pattern_type!(u32 is 1..0); + | ^^^^^^^^^ + +error: layout_of((u32) is 5..=1) = Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + backend_repr: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: (..=1) | (5..), + }, + ), + fields: Primitive, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: (..=1) | (5..), + }, + ), + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, + } + --> $DIR/range_patterns.rs:29:1 + | +LL | type WRAP2 = pattern_type!(u32 is 5..2); + | ^^^^^^^^^^ + +error: layout_of((i8) is -10..=10) = Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + backend_repr: Scalar( + Initialized { + value: Int( + I8, + true, + ), + valid_range: (..=10) | (246..), + }, + ), + fields: Primitive, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + true, + ), + valid_range: (..=10) | (246..), + }, + ), + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + } + --> $DIR/range_patterns.rs:32:1 + | +LL | type SIGN = pattern_type!(i8 is -10..=10); + | ^^^^^^^^^ + +error: layout_of((i8) is i8::MIN..=0) = Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + backend_repr: Scalar( + Initialized { + value: Int( + I8, + true, + ), + valid_range: (..=0) | (128..), + }, + ), + fields: Primitive, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + true, + ), + valid_range: (..=0) | (128..), + }, + ), + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + } + --> $DIR/range_patterns.rs:35:1 + | +LL | type MIN = pattern_type!(i8 is -128..=0); + | ^^^^^^^^ + +error: layout_of((i8) is 120..=-120) = Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + backend_repr: Scalar( + Initialized { + value: Int( + I8, + true, + ), + valid_range: 120..=136, + }, + ), + fields: Primitive, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + true, + ), + valid_range: 120..=136, + }, + ), + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + } + --> $DIR/range_patterns.rs:38:1 + | +LL | type SignedWrap = pattern_type!(i8 is 120..=-120); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0080`. From 916f9552e975287d2bc9aed16d3a1c35b7c52695 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 30 Jan 2025 08:41:20 +0000 Subject: [PATCH 899/991] Reject wrapping ranges of pattern types --- compiler/rustc_ty_utils/src/layout.rs | 28 +++++ tests/ui/type/pattern_types/range_patterns.rs | 6 +- .../type/pattern_types/range_patterns.stderr | 113 ++---------------- 3 files changed, 41 insertions(+), 106 deletions(-) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 5a4bb2c95da6..7334beb52c9d 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -220,6 +220,34 @@ fn layout_of_uncached<'tcx>( .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; + // FIXME(pattern_types): create implied bounds from pattern types in signatures + // that require that the range end is >= the range start so that we can't hit + // this error anymore without first having hit a trait solver error. + // Very fuzzy on the details here, but pattern types are an internal impl detail, + // so we can just go with this for now + if scalar.is_signed() { + let range = scalar.valid_range_mut(); + let start = layout.size.sign_extend(range.start); + let end = layout.size.sign_extend(range.end); + if end < start { + let guar = tcx.dcx().err(format!( + "pattern type ranges cannot wrap: {start}..={end}" + )); + + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + } else { + let range = scalar.valid_range_mut(); + if range.end < range.start { + let guar = tcx.dcx().err(format!( + "pattern type ranges cannot wrap: {}..={}", + range.start, range.end + )); + + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + }; + let niche = Niche { offset: Size::ZERO, value: scalar.primitive(), diff --git a/tests/ui/type/pattern_types/range_patterns.rs b/tests/ui/type/pattern_types/range_patterns.rs index 3aa8426178a1..dda7eb0ae4ec 100644 --- a/tests/ui/type/pattern_types/range_patterns.rs +++ b/tests/ui/type/pattern_types/range_patterns.rs @@ -19,14 +19,14 @@ type A = Option; //~ ERROR layout_of struct NonZeroU32New(pattern_type!(u32 is 1..)); //~ ERROR layout_of #[rustc_layout(debug)] -type EMPTY = pattern_type!(u32 is 1..1); //~ ERROR layout_of +type EMPTY = pattern_type!(u32 is 1..1); //~ ERROR unknown layout #[rustc_layout(debug)] type WRAP = pattern_type!(u32 is 1..0); //~ ERROR unknown layout //~^ ERROR: evaluation of constant value failed #[rustc_layout(debug)] -type WRAP2 = pattern_type!(u32 is 5..2); //~ ERROR layout_of +type WRAP2 = pattern_type!(u32 is 5..2); //~ ERROR unknown layout #[rustc_layout(debug)] type SIGN = pattern_type!(i8 is -10..=10); //~ ERROR layout_of @@ -35,7 +35,7 @@ type SIGN = pattern_type!(i8 is -10..=10); //~ ERROR layout_of type MIN = pattern_type!(i8 is -128..=0); //~ ERROR layout_of #[rustc_layout(debug)] -type SignedWrap = pattern_type!(i8 is 120..=-120); //~ ERROR layout_of +type SignedWrap = pattern_type!(i8 is 120..=-120); //~ ERROR unknown layout fn main() { let x: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(42_u32) }; diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index b6abcf462249..a05995a33f9b 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -357,40 +357,9 @@ error: layout_of(NonZeroU32New) = Layout { LL | struct NonZeroU32New(pattern_type!(u32 is 1..)); | ^^^^^^^^^^^^^^^^^^^^ -error: layout_of((u32) is 1..=0) = Layout { - size: Size(4 bytes), - align: AbiAndPrefAlign { - abi: Align(4 bytes), - pref: $SOME_ALIGN, - }, - backend_repr: Scalar( - Initialized { - value: Int( - I32, - false, - ), - valid_range: (..=0) | (1..), - }, - ), - fields: Primitive, - largest_niche: Some( - Niche { - offset: Size(0 bytes), - value: Int( - I32, - false, - ), - valid_range: (..=0) | (1..), - }, - ), - uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, - } +error: pattern type ranges cannot wrap: 1..=0 + +error: the type has an unknown layout --> $DIR/range_patterns.rs:22:1 | LL | type EMPTY = pattern_type!(u32 is 1..1); @@ -408,40 +377,9 @@ error: the type has an unknown layout LL | type WRAP = pattern_type!(u32 is 1..0); | ^^^^^^^^^ -error: layout_of((u32) is 5..=1) = Layout { - size: Size(4 bytes), - align: AbiAndPrefAlign { - abi: Align(4 bytes), - pref: $SOME_ALIGN, - }, - backend_repr: Scalar( - Initialized { - value: Int( - I32, - false, - ), - valid_range: (..=1) | (5..), - }, - ), - fields: Primitive, - largest_niche: Some( - Niche { - offset: Size(0 bytes), - value: Int( - I32, - false, - ), - valid_range: (..=1) | (5..), - }, - ), - uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, - } +error: pattern type ranges cannot wrap: 5..=1 + +error: the type has an unknown layout --> $DIR/range_patterns.rs:29:1 | LL | type WRAP2 = pattern_type!(u32 is 5..2); @@ -525,45 +463,14 @@ error: layout_of((i8) is i8::MIN..=0) = Layout { LL | type MIN = pattern_type!(i8 is -128..=0); | ^^^^^^^^ -error: layout_of((i8) is 120..=-120) = Layout { - size: Size(1 bytes), - align: AbiAndPrefAlign { - abi: Align(1 bytes), - pref: $SOME_ALIGN, - }, - backend_repr: Scalar( - Initialized { - value: Int( - I8, - true, - ), - valid_range: 120..=136, - }, - ), - fields: Primitive, - largest_niche: Some( - Niche { - offset: Size(0 bytes), - value: Int( - I8, - true, - ), - valid_range: 120..=136, - }, - ), - uninhabited: false, - variants: Single { - index: 0, - }, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, - } +error: pattern type ranges cannot wrap: 120..=-120 + +error: the type has an unknown layout --> $DIR/range_patterns.rs:38:1 | LL | type SignedWrap = pattern_type!(i8 is 120..=-120); | ^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0080`. From 9d87d4e4f5b249312408058fdbb26d99693adf15 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 29 Jan 2025 16:37:58 +0000 Subject: [PATCH 900/991] Add tests for pattern type literals --- tests/ui/type/pattern_types/literals.rs | 143 ++++++++++ tests/ui/type/pattern_types/literals.stderr | 276 ++++++++++++++++++++ 2 files changed, 419 insertions(+) create mode 100644 tests/ui/type/pattern_types/literals.rs create mode 100644 tests/ui/type/pattern_types/literals.stderr diff --git a/tests/ui/type/pattern_types/literals.rs b/tests/ui/type/pattern_types/literals.rs new file mode 100644 index 000000000000..7ff3fdf09205 --- /dev/null +++ b/tests/ui/type/pattern_types/literals.rs @@ -0,0 +1,143 @@ +//! Check where literals can be used to initialize pattern types and where not. + +#![feature(pattern_types, const_trait_impl, pattern_type_range_trait)] +#![feature(pattern_type_macro)] + +use std::pat::pattern_type; + +fn out_of_range() -> pattern_type!(u32 is 1..) { + 0 + //~^ mismatched types +} + +fn at_range_start() -> pattern_type!(u32 is 1..) { + 1 + //~^ mismatched types +} + +fn in_range() -> pattern_type!(u32 is 1..) { + 2 + //~^ mismatched types +} + +fn negative_lit_on_unsigned_ty() -> pattern_type!(u32 is 1..) { + -3 + //~^ mismatched types +} + +fn negative_lit_in_range() -> pattern_type!(i8 is -5..5) { + -2 + //~^ mismatched types +} + +fn positive_lit_in_range_of_signed() -> pattern_type!(i8 is -5..5) { + 2 + //~^ mismatched types +} + +fn negative_lit_at_range_start() -> pattern_type!(i8 is -5..5) { + -5 + //~^ mismatched types +} + +fn positive_lit_at_range_end() -> pattern_type!(i8 is -5..5) { + 4 + //~^ mismatched types +} + +fn lit_one_beyond_range_end() -> pattern_type!(i8 is -5..5) { + 5 + //~^ mismatched types +} + +fn wrong_lit_kind() -> pattern_type!(u32 is 1..) { + '3' + //~^ mismatched types +} + +fn char_lit_in_range() -> pattern_type!(char is 'a'..'z') { + 'b' + //~^ mismatched types +} + +fn char_lit_out_of_range() -> pattern_type!(char is 'a'..'z') { + 'A' + //~^ mismatched types +} + +fn lit_at_unsigned_range_inclusive_end() -> pattern_type!(u32 is 0..=1) { + 1 + //~^ mismatched types +} + +fn single_element_range() -> pattern_type!(u32 is 0..=0) { + 0 + //~^ mismatched types +} + +fn lit_oob_single_element_range() -> pattern_type!(u32 is 0..=0) { + 1 + //~^ mismatched types +} + +fn lit_oob_single_element_range_exclusive() -> pattern_type!(u32 is 0..1) { + 1 + //~^ mismatched types +} + +fn single_element_range_exclusive() -> pattern_type!(u32 is 0..1) { + 0 + //~^ mismatched types +} + +fn empty_range_at_base_type_min() -> pattern_type!(u32 is 0..0) { + //~^ evaluation of constant value failed + 0 +} + +fn empty_range_at_base_type_min2() -> pattern_type!(u32 is 0..0) { + //~^ evaluation of constant value failed + 1 +} + +fn empty_range() -> pattern_type!(u32 is 1..1) { + 0 + //~^ mismatched types +} + +fn empty_range2() -> pattern_type!(u32 is 1..1) { + 1 + //~^ mismatched types +} + +fn wraparound_range_at_base_ty_end() -> pattern_type!(u32 is 1..0) { + //~^ evaluation of constant value failed + 1 +} + +fn wraparound_range_at_base_ty_end2() -> pattern_type!(u32 is 1..0) { + //~^ evaluation of constant value failed + 0 +} + +fn wraparound_range_at_base_ty_end3() -> pattern_type!(u32 is 1..0) { + //~^ evaluation of constant value failed + 2 +} + +fn wraparound_range() -> pattern_type!(u32 is 2..1) { + 1 + //~^ mismatched types +} + +fn lit_in_wraparound_range() -> pattern_type!(u32 is 2..1) { + 0 + //~^ mismatched types +} + +fn lit_at_wraparound_range_start() -> pattern_type!(u32 is 2..1) { + 2 + //~^ mismatched types +} + +fn main() {} diff --git a/tests/ui/type/pattern_types/literals.stderr b/tests/ui/type/pattern_types/literals.stderr new file mode 100644 index 000000000000..ae0987286203 --- /dev/null +++ b/tests/ui/type/pattern_types/literals.stderr @@ -0,0 +1,276 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/literals.rs:93:62 + | +LL | fn empty_range_at_base_type_min() -> pattern_type!(u32 is 0..0) { + | ^ evaluation panicked: exclusive range end at minimum value of type + +error[E0080]: evaluation of constant value failed + --> $DIR/literals.rs:98:63 + | +LL | fn empty_range_at_base_type_min2() -> pattern_type!(u32 is 0..0) { + | ^ evaluation panicked: exclusive range end at minimum value of type + +error[E0080]: evaluation of constant value failed + --> $DIR/literals.rs:113:65 + | +LL | fn wraparound_range_at_base_ty_end() -> pattern_type!(u32 is 1..0) { + | ^ evaluation panicked: exclusive range end at minimum value of type + +error[E0080]: evaluation of constant value failed + --> $DIR/literals.rs:118:66 + | +LL | fn wraparound_range_at_base_ty_end2() -> pattern_type!(u32 is 1..0) { + | ^ evaluation panicked: exclusive range end at minimum value of type + +error[E0080]: evaluation of constant value failed + --> $DIR/literals.rs:123:66 + | +LL | fn wraparound_range_at_base_ty_end3() -> pattern_type!(u32 is 1..0) { + | ^ evaluation panicked: exclusive range end at minimum value of type + +error[E0308]: mismatched types + --> $DIR/literals.rs:9:5 + | +LL | fn out_of_range() -> pattern_type!(u32 is 1..) { + | ------------------------- expected `(u32) is 1..` because of return type +LL | 0 + | ^ expected `(u32) is 1..`, found integer + | + = note: expected pattern type `(u32) is 1..` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:14:5 + | +LL | fn at_range_start() -> pattern_type!(u32 is 1..) { + | ------------------------- expected `(u32) is 1..` because of return type +LL | 1 + | ^ expected `(u32) is 1..`, found integer + | + = note: expected pattern type `(u32) is 1..` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:19:5 + | +LL | fn in_range() -> pattern_type!(u32 is 1..) { + | ------------------------- expected `(u32) is 1..` because of return type +LL | 2 + | ^ expected `(u32) is 1..`, found integer + | + = note: expected pattern type `(u32) is 1..` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:24:5 + | +LL | fn negative_lit_on_unsigned_ty() -> pattern_type!(u32 is 1..) { + | ------------------------- expected `(u32) is 1..` because of return type +LL | -3 + | ^^ expected `(u32) is 1..`, found integer + | + = note: expected pattern type `(u32) is 1..` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:29:5 + | +LL | fn negative_lit_in_range() -> pattern_type!(i8 is -5..5) { + | -------------------------- expected `(i8) is -5..=4` because of return type +LL | -2 + | ^^ expected `(i8) is -5..=4`, found integer + | + = note: expected pattern type `(i8) is -5..=4` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:34:5 + | +LL | fn positive_lit_in_range_of_signed() -> pattern_type!(i8 is -5..5) { + | -------------------------- expected `(i8) is -5..=4` because of return type +LL | 2 + | ^ expected `(i8) is -5..=4`, found integer + | + = note: expected pattern type `(i8) is -5..=4` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:39:5 + | +LL | fn negative_lit_at_range_start() -> pattern_type!(i8 is -5..5) { + | -------------------------- expected `(i8) is -5..=4` because of return type +LL | -5 + | ^^ expected `(i8) is -5..=4`, found integer + | + = note: expected pattern type `(i8) is -5..=4` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:44:5 + | +LL | fn positive_lit_at_range_end() -> pattern_type!(i8 is -5..5) { + | -------------------------- expected `(i8) is -5..=4` because of return type +LL | 4 + | ^ expected `(i8) is -5..=4`, found integer + | + = note: expected pattern type `(i8) is -5..=4` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:49:5 + | +LL | fn lit_one_beyond_range_end() -> pattern_type!(i8 is -5..5) { + | -------------------------- expected `(i8) is -5..=4` because of return type +LL | 5 + | ^ expected `(i8) is -5..=4`, found integer + | + = note: expected pattern type `(i8) is -5..=4` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:54:5 + | +LL | fn wrong_lit_kind() -> pattern_type!(u32 is 1..) { + | ------------------------- expected `(u32) is 1..` because of return type +LL | '3' + | ^^^ expected `(u32) is 1..`, found `char` + | + = note: expected pattern type `(u32) is 1..` + found type `char` + +error[E0308]: mismatched types + --> $DIR/literals.rs:59:5 + | +LL | fn char_lit_in_range() -> pattern_type!(char is 'a'..'z') { + | ------------------------------- expected `(char) is 'a'..='y'` because of return type +LL | 'b' + | ^^^ expected `(char) is 'a'..='y'`, found `char` + | + = note: expected pattern type `(char) is 'a'..='y'` + found type `char` + +error[E0308]: mismatched types + --> $DIR/literals.rs:64:5 + | +LL | fn char_lit_out_of_range() -> pattern_type!(char is 'a'..'z') { + | ------------------------------- expected `(char) is 'a'..='y'` because of return type +LL | 'A' + | ^^^ expected `(char) is 'a'..='y'`, found `char` + | + = note: expected pattern type `(char) is 'a'..='y'` + found type `char` + +error[E0308]: mismatched types + --> $DIR/literals.rs:69:5 + | +LL | fn lit_at_unsigned_range_inclusive_end() -> pattern_type!(u32 is 0..=1) { + | --------------------------- expected `(u32) is 0..=1` because of return type +LL | 1 + | ^ expected `(u32) is 0..=1`, found integer + | + = note: expected pattern type `(u32) is 0..=1` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:74:5 + | +LL | fn single_element_range() -> pattern_type!(u32 is 0..=0) { + | --------------------------- expected `(u32) is 0..=0` because of return type +LL | 0 + | ^ expected `(u32) is 0..=0`, found integer + | + = note: expected pattern type `(u32) is 0..=0` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:79:5 + | +LL | fn lit_oob_single_element_range() -> pattern_type!(u32 is 0..=0) { + | --------------------------- expected `(u32) is 0..=0` because of return type +LL | 1 + | ^ expected `(u32) is 0..=0`, found integer + | + = note: expected pattern type `(u32) is 0..=0` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:84:5 + | +LL | fn lit_oob_single_element_range_exclusive() -> pattern_type!(u32 is 0..1) { + | -------------------------- expected `(u32) is 0..=0` because of return type +LL | 1 + | ^ expected `(u32) is 0..=0`, found integer + | + = note: expected pattern type `(u32) is 0..=0` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:89:5 + | +LL | fn single_element_range_exclusive() -> pattern_type!(u32 is 0..1) { + | -------------------------- expected `(u32) is 0..=0` because of return type +LL | 0 + | ^ expected `(u32) is 0..=0`, found integer + | + = note: expected pattern type `(u32) is 0..=0` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:104:5 + | +LL | fn empty_range() -> pattern_type!(u32 is 1..1) { + | -------------------------- expected `(u32) is 1..=0` because of return type +LL | 0 + | ^ expected `(u32) is 1..=0`, found integer + | + = note: expected pattern type `(u32) is 1..=0` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:109:5 + | +LL | fn empty_range2() -> pattern_type!(u32 is 1..1) { + | -------------------------- expected `(u32) is 1..=0` because of return type +LL | 1 + | ^ expected `(u32) is 1..=0`, found integer + | + = note: expected pattern type `(u32) is 1..=0` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:129:5 + | +LL | fn wraparound_range() -> pattern_type!(u32 is 2..1) { + | -------------------------- expected `(u32) is 2..=0` because of return type +LL | 1 + | ^ expected `(u32) is 2..=0`, found integer + | + = note: expected pattern type `(u32) is 2..=0` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:134:5 + | +LL | fn lit_in_wraparound_range() -> pattern_type!(u32 is 2..1) { + | -------------------------- expected `(u32) is 2..=0` because of return type +LL | 0 + | ^ expected `(u32) is 2..=0`, found integer + | + = note: expected pattern type `(u32) is 2..=0` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/literals.rs:139:5 + | +LL | fn lit_at_wraparound_range_start() -> pattern_type!(u32 is 2..1) { + | -------------------------- expected `(u32) is 2..=0` because of return type +LL | 2 + | ^ expected `(u32) is 2..=0`, found integer + | + = note: expected pattern type `(u32) is 2..=0` + found type `{integer}` + +error: aborting due to 27 previous errors + +Some errors have detailed explanations: E0080, E0308. +For more information about an error, try `rustc --explain E0080`. From f87e58f1948c493aef6d645f339c2b9043e5ba59 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 29 Jan 2025 16:44:08 +0000 Subject: [PATCH 901/991] Allow int literals for pattern types with int base types --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 15 +- .../src/builder/expr/as_constant.rs | 7 +- tests/ui/type/pattern_types/literals.rs | 11 +- tests/ui/type/pattern_types/literals.stderr | 139 ++++-------------- tests/ui/type/pattern_types/nested.rs | 4 +- tests/ui/type/pattern_types/nested.stderr | 9 +- 6 files changed, 55 insertions(+), 130 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index db947b6744da..253ba74a1912 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1647,7 +1647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ast::LitKind::Char(_) => tcx.types.char, ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => Ty::new_int(tcx, ty::int_ty(t)), ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => Ty::new_uint(tcx, ty::uint_ty(t)), - ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => { + ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) => { let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() { ty::Int(_) | ty::Uint(_) => Some(ty), // These exist to direct casts like `0x61 as char` to use @@ -1656,6 +1656,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Char => Some(tcx.types.u8), ty::RawPtr(..) => Some(tcx.types.usize), ty::FnDef(..) | ty::FnPtr(..) => Some(tcx.types.usize), + &ty::Pat(base, _) if base.is_integral() => { + let layout = tcx + .layout_of(self.typing_env(self.param_env).as_query_input(ty)) + .ok()?; + assert!(!layout.uninhabited); + + match layout.backend_repr { + rustc_abi::BackendRepr::Scalar(scalar) => { + scalar.valid_range(&tcx).contains(u128::from(i.get())).then_some(ty) + } + _ => unreachable!(), + } + } _ => None, }); opt_ty.unwrap_or_else(|| self.next_int_var()) diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 84c9297e6589..f743ea60a456 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -117,7 +117,12 @@ fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx> ConstValue::Scalar(Scalar::from_uint(result, width)) }; - let value = match (lit, ty.kind()) { + let lit_ty = match *ty.kind() { + ty::Pat(base, _) => base, + _ => ty, + }; + + let value = match (lit, lit_ty.kind()) { (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { let s = s.as_str(); let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); diff --git a/tests/ui/type/pattern_types/literals.rs b/tests/ui/type/pattern_types/literals.rs index 7ff3fdf09205..97a918645f3e 100644 --- a/tests/ui/type/pattern_types/literals.rs +++ b/tests/ui/type/pattern_types/literals.rs @@ -12,27 +12,24 @@ fn out_of_range() -> pattern_type!(u32 is 1..) { fn at_range_start() -> pattern_type!(u32 is 1..) { 1 - //~^ mismatched types } fn in_range() -> pattern_type!(u32 is 1..) { 2 - //~^ mismatched types } fn negative_lit_on_unsigned_ty() -> pattern_type!(u32 is 1..) { -3 - //~^ mismatched types + //~^ ERROR: cannot apply unary operator `-` to type `(u32) is 1..` } fn negative_lit_in_range() -> pattern_type!(i8 is -5..5) { -2 - //~^ mismatched types + //~^ ERROR: cannot apply unary operator `-` to type `(i8) is -5..=4` } fn positive_lit_in_range_of_signed() -> pattern_type!(i8 is -5..5) { 2 - //~^ mismatched types } fn negative_lit_at_range_start() -> pattern_type!(i8 is -5..5) { @@ -42,7 +39,6 @@ fn negative_lit_at_range_start() -> pattern_type!(i8 is -5..5) { fn positive_lit_at_range_end() -> pattern_type!(i8 is -5..5) { 4 - //~^ mismatched types } fn lit_one_beyond_range_end() -> pattern_type!(i8 is -5..5) { @@ -67,12 +63,10 @@ fn char_lit_out_of_range() -> pattern_type!(char is 'a'..'z') { fn lit_at_unsigned_range_inclusive_end() -> pattern_type!(u32 is 0..=1) { 1 - //~^ mismatched types } fn single_element_range() -> pattern_type!(u32 is 0..=0) { 0 - //~^ mismatched types } fn lit_oob_single_element_range() -> pattern_type!(u32 is 0..=0) { @@ -87,7 +81,6 @@ fn lit_oob_single_element_range_exclusive() -> pattern_type!(u32 is 0..1) { fn single_element_range_exclusive() -> pattern_type!(u32 is 0..1) { 0 - //~^ mismatched types } fn empty_range_at_base_type_min() -> pattern_type!(u32 is 0..0) { diff --git a/tests/ui/type/pattern_types/literals.stderr b/tests/ui/type/pattern_types/literals.stderr index ae0987286203..5c926742f3cd 100644 --- a/tests/ui/type/pattern_types/literals.stderr +++ b/tests/ui/type/pattern_types/literals.stderr @@ -1,29 +1,29 @@ error[E0080]: evaluation of constant value failed - --> $DIR/literals.rs:93:62 + --> $DIR/literals.rs:86:62 | LL | fn empty_range_at_base_type_min() -> pattern_type!(u32 is 0..0) { | ^ evaluation panicked: exclusive range end at minimum value of type error[E0080]: evaluation of constant value failed - --> $DIR/literals.rs:98:63 + --> $DIR/literals.rs:91:63 | LL | fn empty_range_at_base_type_min2() -> pattern_type!(u32 is 0..0) { | ^ evaluation panicked: exclusive range end at minimum value of type error[E0080]: evaluation of constant value failed - --> $DIR/literals.rs:113:65 + --> $DIR/literals.rs:106:65 | LL | fn wraparound_range_at_base_ty_end() -> pattern_type!(u32 is 1..0) { | ^ evaluation panicked: exclusive range end at minimum value of type error[E0080]: evaluation of constant value failed - --> $DIR/literals.rs:118:66 + --> $DIR/literals.rs:111:66 | LL | fn wraparound_range_at_base_ty_end2() -> pattern_type!(u32 is 1..0) { | ^ evaluation panicked: exclusive range end at minimum value of type error[E0080]: evaluation of constant value failed - --> $DIR/literals.rs:123:66 + --> $DIR/literals.rs:116:66 | LL | fn wraparound_range_at_base_ty_end3() -> pattern_type!(u32 is 1..0) { | ^ evaluation panicked: exclusive range end at minimum value of type @@ -39,63 +39,20 @@ LL | 0 = note: expected pattern type `(u32) is 1..` found type `{integer}` -error[E0308]: mismatched types - --> $DIR/literals.rs:14:5 +error[E0600]: cannot apply unary operator `-` to type `(u32) is 1..` + --> $DIR/literals.rs:22:5 | -LL | fn at_range_start() -> pattern_type!(u32 is 1..) { - | ------------------------- expected `(u32) is 1..` because of return type -LL | 1 - | ^ expected `(u32) is 1..`, found integer - | - = note: expected pattern type `(u32) is 1..` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/literals.rs:19:5 - | -LL | fn in_range() -> pattern_type!(u32 is 1..) { - | ------------------------- expected `(u32) is 1..` because of return type -LL | 2 - | ^ expected `(u32) is 1..`, found integer - | - = note: expected pattern type `(u32) is 1..` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/literals.rs:24:5 - | -LL | fn negative_lit_on_unsigned_ty() -> pattern_type!(u32 is 1..) { - | ------------------------- expected `(u32) is 1..` because of return type LL | -3 - | ^^ expected `(u32) is 1..`, found integer - | - = note: expected pattern type `(u32) is 1..` - found type `{integer}` + | ^^ cannot apply unary operator `-` -error[E0308]: mismatched types - --> $DIR/literals.rs:29:5 +error[E0600]: cannot apply unary operator `-` to type `(i8) is -5..=4` + --> $DIR/literals.rs:27:5 | -LL | fn negative_lit_in_range() -> pattern_type!(i8 is -5..5) { - | -------------------------- expected `(i8) is -5..=4` because of return type LL | -2 - | ^^ expected `(i8) is -5..=4`, found integer - | - = note: expected pattern type `(i8) is -5..=4` - found type `{integer}` + | ^^ cannot apply unary operator `-` error[E0308]: mismatched types - --> $DIR/literals.rs:34:5 - | -LL | fn positive_lit_in_range_of_signed() -> pattern_type!(i8 is -5..5) { - | -------------------------- expected `(i8) is -5..=4` because of return type -LL | 2 - | ^ expected `(i8) is -5..=4`, found integer - | - = note: expected pattern type `(i8) is -5..=4` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/literals.rs:39:5 + --> $DIR/literals.rs:36:5 | LL | fn negative_lit_at_range_start() -> pattern_type!(i8 is -5..5) { | -------------------------- expected `(i8) is -5..=4` because of return type @@ -106,18 +63,7 @@ LL | -5 found type `{integer}` error[E0308]: mismatched types - --> $DIR/literals.rs:44:5 - | -LL | fn positive_lit_at_range_end() -> pattern_type!(i8 is -5..5) { - | -------------------------- expected `(i8) is -5..=4` because of return type -LL | 4 - | ^ expected `(i8) is -5..=4`, found integer - | - = note: expected pattern type `(i8) is -5..=4` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/literals.rs:49:5 + --> $DIR/literals.rs:45:5 | LL | fn lit_one_beyond_range_end() -> pattern_type!(i8 is -5..5) { | -------------------------- expected `(i8) is -5..=4` because of return type @@ -128,7 +74,7 @@ LL | 5 found type `{integer}` error[E0308]: mismatched types - --> $DIR/literals.rs:54:5 + --> $DIR/literals.rs:50:5 | LL | fn wrong_lit_kind() -> pattern_type!(u32 is 1..) { | ------------------------- expected `(u32) is 1..` because of return type @@ -139,7 +85,7 @@ LL | '3' found type `char` error[E0308]: mismatched types - --> $DIR/literals.rs:59:5 + --> $DIR/literals.rs:55:5 | LL | fn char_lit_in_range() -> pattern_type!(char is 'a'..'z') { | ------------------------------- expected `(char) is 'a'..='y'` because of return type @@ -150,7 +96,7 @@ LL | 'b' found type `char` error[E0308]: mismatched types - --> $DIR/literals.rs:64:5 + --> $DIR/literals.rs:60:5 | LL | fn char_lit_out_of_range() -> pattern_type!(char is 'a'..'z') { | ------------------------------- expected `(char) is 'a'..='y'` because of return type @@ -161,29 +107,7 @@ LL | 'A' found type `char` error[E0308]: mismatched types - --> $DIR/literals.rs:69:5 - | -LL | fn lit_at_unsigned_range_inclusive_end() -> pattern_type!(u32 is 0..=1) { - | --------------------------- expected `(u32) is 0..=1` because of return type -LL | 1 - | ^ expected `(u32) is 0..=1`, found integer - | - = note: expected pattern type `(u32) is 0..=1` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/literals.rs:74:5 - | -LL | fn single_element_range() -> pattern_type!(u32 is 0..=0) { - | --------------------------- expected `(u32) is 0..=0` because of return type -LL | 0 - | ^ expected `(u32) is 0..=0`, found integer - | - = note: expected pattern type `(u32) is 0..=0` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/literals.rs:79:5 + --> $DIR/literals.rs:73:5 | LL | fn lit_oob_single_element_range() -> pattern_type!(u32 is 0..=0) { | --------------------------- expected `(u32) is 0..=0` because of return type @@ -194,7 +118,7 @@ LL | 1 found type `{integer}` error[E0308]: mismatched types - --> $DIR/literals.rs:84:5 + --> $DIR/literals.rs:78:5 | LL | fn lit_oob_single_element_range_exclusive() -> pattern_type!(u32 is 0..1) { | -------------------------- expected `(u32) is 0..=0` because of return type @@ -204,19 +128,10 @@ LL | 1 = note: expected pattern type `(u32) is 0..=0` found type `{integer}` -error[E0308]: mismatched types - --> $DIR/literals.rs:89:5 - | -LL | fn single_element_range_exclusive() -> pattern_type!(u32 is 0..1) { - | -------------------------- expected `(u32) is 0..=0` because of return type -LL | 0 - | ^ expected `(u32) is 0..=0`, found integer - | - = note: expected pattern type `(u32) is 0..=0` - found type `{integer}` +error: pattern type ranges cannot wrap: 1..=0 error[E0308]: mismatched types - --> $DIR/literals.rs:104:5 + --> $DIR/literals.rs:97:5 | LL | fn empty_range() -> pattern_type!(u32 is 1..1) { | -------------------------- expected `(u32) is 1..=0` because of return type @@ -227,7 +142,7 @@ LL | 0 found type `{integer}` error[E0308]: mismatched types - --> $DIR/literals.rs:109:5 + --> $DIR/literals.rs:102:5 | LL | fn empty_range2() -> pattern_type!(u32 is 1..1) { | -------------------------- expected `(u32) is 1..=0` because of return type @@ -237,8 +152,10 @@ LL | 1 = note: expected pattern type `(u32) is 1..=0` found type `{integer}` +error: pattern type ranges cannot wrap: 2..=0 + error[E0308]: mismatched types - --> $DIR/literals.rs:129:5 + --> $DIR/literals.rs:122:5 | LL | fn wraparound_range() -> pattern_type!(u32 is 2..1) { | -------------------------- expected `(u32) is 2..=0` because of return type @@ -249,7 +166,7 @@ LL | 1 found type `{integer}` error[E0308]: mismatched types - --> $DIR/literals.rs:134:5 + --> $DIR/literals.rs:127:5 | LL | fn lit_in_wraparound_range() -> pattern_type!(u32 is 2..1) { | -------------------------- expected `(u32) is 2..=0` because of return type @@ -260,7 +177,7 @@ LL | 0 found type `{integer}` error[E0308]: mismatched types - --> $DIR/literals.rs:139:5 + --> $DIR/literals.rs:132:5 | LL | fn lit_at_wraparound_range_start() -> pattern_type!(u32 is 2..1) { | -------------------------- expected `(u32) is 2..=0` because of return type @@ -270,7 +187,7 @@ LL | 2 = note: expected pattern type `(u32) is 2..=0` found type `{integer}` -error: aborting due to 27 previous errors +error: aborting due to 22 previous errors -Some errors have detailed explanations: E0080, E0308. +Some errors have detailed explanations: E0080, E0308, E0600. For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/type/pattern_types/nested.rs b/tests/ui/type/pattern_types/nested.rs index 0d8cd22190e5..fd950d732914 100644 --- a/tests/ui/type/pattern_types/nested.rs +++ b/tests/ui/type/pattern_types/nested.rs @@ -1,6 +1,6 @@ //! Check that pattern types can only have specific base types -#![feature(pattern_types)] +#![feature(pattern_types, const_trait_impl, pattern_type_range_trait)] #![feature(pattern_type_macro)] use std::pat::pattern_type; @@ -14,7 +14,7 @@ const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); // We want to get the most narrowest version that a pattern could be const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); //~^ ERROR: not a valid base type for range patterns -//~| ERROR: mismatched types +//~| ERROR: cannot apply unary operator `-` to type `(i32) is 1..` const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); //~^ ERROR: not a valid base type for range patterns diff --git a/tests/ui/type/pattern_types/nested.stderr b/tests/ui/type/pattern_types/nested.stderr index f79d12bc3f37..bb206d9db3db 100644 --- a/tests/ui/type/pattern_types/nested.stderr +++ b/tests/ui/type/pattern_types/nested.stderr @@ -43,14 +43,11 @@ LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = tod u128 and 5 others -error[E0308]: mismatched types +error[E0600]: cannot apply unary operator `-` to type `(i32) is 1..` --> $DIR/nested.rs:15:67 | LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); - | ^^ expected `(i32) is 1..`, found integer - | - = note: expected pattern type `(i32) is 1..` - found type `{integer}` + | ^^ cannot apply unary operator `-` error[E0277]: `(i32) is 1..` is not a valid base type for range patterns --> $DIR/nested.rs:19:35 @@ -180,5 +177,5 @@ LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!(); error: aborting due to 11 previous errors -Some errors have detailed explanations: E0277, E0308. +Some errors have detailed explanations: E0277, E0308, E0600. For more information about an error, try `rustc --explain E0277`. From 1d983bf7941bb89985d53e741cabcf113912a40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 10 Mar 2025 11:37:21 +0200 Subject: [PATCH 902/991] Format code --- .../rust-analyzer/crates/hir-ty/src/layout.rs | 78 ++++++++++--------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 2ac1792ba868..ba36c279f7f0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -6,9 +6,8 @@ use base_db::ra_salsa::Cycle; use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy}; use hir_def::{ layout::{ - Float, Integer, LayoutCalculator, LayoutCalculatorError, - LayoutData, Primitive, ReprOptions, Scalar, StructKind, TargetDataLayout, - WrappingRange, + Float, Integer, LayoutCalculator, LayoutCalculatorError, LayoutData, Primitive, + ReprOptions, Scalar, StructKind, TargetDataLayout, WrappingRange, }, LocalFieldId, StructId, }; @@ -192,43 +191,52 @@ pub fn layout_of_ty_query( valid_range: WrappingRange { start: 0, end: 0x10FFFF }, }, ), - chalk_ir::Scalar::Int(i) => Layout::scalar(dl, scalar_unit( + chalk_ir::Scalar::Int(i) => Layout::scalar( dl, - Primitive::Int( - match i { - IntTy::Isize => dl.ptr_sized_integer(), - IntTy::I8 => Integer::I8, - IntTy::I16 => Integer::I16, - IntTy::I32 => Integer::I32, - IntTy::I64 => Integer::I64, - IntTy::I128 => Integer::I128, - }, - true, + scalar_unit( + dl, + Primitive::Int( + match i { + IntTy::Isize => dl.ptr_sized_integer(), + IntTy::I8 => Integer::I8, + IntTy::I16 => Integer::I16, + IntTy::I32 => Integer::I32, + IntTy::I64 => Integer::I64, + IntTy::I128 => Integer::I128, + }, + true, + ), ), - )), - chalk_ir::Scalar::Uint(i) => Layout::scalar(dl, scalar_unit( + ), + chalk_ir::Scalar::Uint(i) => Layout::scalar( dl, - Primitive::Int( - match i { - UintTy::Usize => dl.ptr_sized_integer(), - UintTy::U8 => Integer::I8, - UintTy::U16 => Integer::I16, - UintTy::U32 => Integer::I32, - UintTy::U64 => Integer::I64, - UintTy::U128 => Integer::I128, - }, - false, + scalar_unit( + dl, + Primitive::Int( + match i { + UintTy::Usize => dl.ptr_sized_integer(), + UintTy::U8 => Integer::I8, + UintTy::U16 => Integer::I16, + UintTy::U32 => Integer::I32, + UintTy::U64 => Integer::I64, + UintTy::U128 => Integer::I128, + }, + false, + ), ), - )), - chalk_ir::Scalar::Float(f) => Layout::scalar(dl, scalar_unit( + ), + chalk_ir::Scalar::Float(f) => Layout::scalar( dl, - Primitive::Float(match f { - FloatTy::F16 => Float::F16, - FloatTy::F32 => Float::F32, - FloatTy::F64 => Float::F64, - FloatTy::F128 => Float::F128, - }), - )), + scalar_unit( + dl, + Primitive::Float(match f { + FloatTy::F16 => Float::F16, + FloatTy::F32 => Float::F32, + FloatTy::F64 => Float::F64, + FloatTy::F128 => Float::F128, + }), + ), + ), }, TyKind::Tuple(len, tys) => { let kind = if *len == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; From 063ef18fdc10cb0eb49e1af855e1a8e807e73eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 10 Mar 2025 18:12:34 +0800 Subject: [PATCH 903/991] Revert "Use workspace lints for crates in `compiler/` #138084" Revert to buy time to consider options that avoids breaking downstream usages of cargo on distributed `rustc-src` artifacts, where such cargo invocations fail due to inability to inherit `lints` from workspace root manifest's `workspace.lints` (this is only valid for the source rust-lang/rust workspace, but not really the distributed `rustc-src` artifacts). This breakage was reported in . This reverts commit 48caf81484b50dca5a5cebb614899a3df81ca898, reversing changes made to c6662879b27f5161e95f39395e3c9513a7b97028. --- Cargo.toml | 14 -------------- compiler/rustc/Cargo.toml | 3 --- compiler/rustc_abi/Cargo.toml | 3 --- compiler/rustc_abi/src/lib.rs | 1 + compiler/rustc_arena/Cargo.toml | 3 --- compiler/rustc_arena/src/lib.rs | 1 + compiler/rustc_ast/Cargo.toml | 3 --- compiler/rustc_ast/src/lib.rs | 1 + compiler/rustc_ast_ir/Cargo.toml | 3 --- compiler/rustc_ast_ir/src/lib.rs | 1 + compiler/rustc_ast_lowering/Cargo.toml | 3 --- compiler/rustc_ast_lowering/src/lib.rs | 1 + compiler/rustc_ast_passes/Cargo.toml | 3 --- compiler/rustc_ast_passes/src/lib.rs | 1 + compiler/rustc_ast_pretty/Cargo.toml | 3 --- compiler/rustc_ast_pretty/src/lib.rs | 1 + compiler/rustc_attr_data_structures/Cargo.toml | 3 --- compiler/rustc_attr_data_structures/src/lib.rs | 1 + compiler/rustc_attr_parsing/Cargo.toml | 3 --- compiler/rustc_attr_parsing/src/lib.rs | 1 + compiler/rustc_baked_icu_data/Cargo.toml | 3 --- compiler/rustc_baked_icu_data/src/lib.rs | 2 +- compiler/rustc_borrowck/Cargo.toml | 3 --- compiler/rustc_borrowck/src/lib.rs | 1 + compiler/rustc_builtin_macros/Cargo.toml | 7 ++++--- compiler/rustc_builtin_macros/src/lib.rs | 1 + compiler/rustc_codegen_llvm/Cargo.toml | 3 --- compiler/rustc_codegen_llvm/src/lib.rs | 1 + compiler/rustc_codegen_ssa/Cargo.toml | 3 --- compiler/rustc_codegen_ssa/src/lib.rs | 1 + compiler/rustc_const_eval/Cargo.toml | 3 --- compiler/rustc_const_eval/src/lib.rs | 1 + compiler/rustc_data_structures/Cargo.toml | 3 --- compiler/rustc_data_structures/src/graph/tests.rs | 4 ++-- .../src/obligation_forest/mod.rs | 2 +- compiler/rustc_data_structures/src/sync.rs | 2 +- .../rustc_data_structures/src/sync/parallel.rs | 2 +- .../rustc_data_structures/src/tagged_ptr/tests.rs | 2 +- compiler/rustc_driver/Cargo.toml | 3 --- compiler/rustc_driver_impl/Cargo.toml | 3 --- compiler/rustc_driver_impl/src/lib.rs | 1 + compiler/rustc_error_codes/Cargo.toml | 3 --- compiler/rustc_error_codes/src/lib.rs | 1 + compiler/rustc_error_messages/Cargo.toml | 3 --- compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_errors/Cargo.toml | 3 --- compiler/rustc_errors/src/lib.rs | 1 + compiler/rustc_expand/Cargo.toml | 3 --- compiler/rustc_expand/src/lib.rs | 1 + compiler/rustc_feature/Cargo.toml | 3 --- compiler/rustc_feature/src/lib.rs | 1 + compiler/rustc_fluent_macro/Cargo.toml | 3 --- compiler/rustc_fluent_macro/src/lib.rs | 1 + compiler/rustc_fs_util/Cargo.toml | 3 --- compiler/rustc_graphviz/Cargo.toml | 3 --- compiler/rustc_graphviz/src/lib.rs | 1 + compiler/rustc_hashes/Cargo.toml | 3 --- compiler/rustc_hir/Cargo.toml | 3 --- compiler/rustc_hir/src/lib.rs | 1 + compiler/rustc_hir_analysis/Cargo.toml | 3 --- compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_hir_pretty/Cargo.toml | 3 --- compiler/rustc_hir_pretty/src/lib.rs | 1 + compiler/rustc_hir_typeck/Cargo.toml | 3 --- compiler/rustc_hir_typeck/src/lib.rs | 1 + compiler/rustc_incremental/Cargo.toml | 3 --- compiler/rustc_incremental/src/lib.rs | 1 + compiler/rustc_index/Cargo.toml | 3 --- compiler/rustc_index/src/lib.rs | 1 + compiler/rustc_index_macros/Cargo.toml | 3 --- compiler/rustc_index_macros/src/newtype.rs | 2 +- compiler/rustc_infer/Cargo.toml | 3 --- compiler/rustc_infer/src/lib.rs | 1 + compiler/rustc_interface/Cargo.toml | 3 --- compiler/rustc_interface/src/lib.rs | 1 + compiler/rustc_lexer/Cargo.toml | 3 --- compiler/rustc_lexer/src/lib.rs | 1 + compiler/rustc_lint/Cargo.toml | 3 --- compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_lint_defs/Cargo.toml | 3 --- compiler/rustc_lint_defs/src/lib.rs | 4 ++++ compiler/rustc_llvm/Cargo.toml | 3 --- compiler/rustc_llvm/src/lib.rs | 1 + compiler/rustc_log/Cargo.toml | 3 --- compiler/rustc_macros/Cargo.toml | 3 --- compiler/rustc_macros/src/lib.rs | 1 + compiler/rustc_metadata/Cargo.toml | 3 --- compiler/rustc_metadata/src/lib.rs | 1 + compiler/rustc_middle/Cargo.toml | 3 --- compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_mir_build/Cargo.toml | 3 --- compiler/rustc_mir_build/src/lib.rs | 1 + compiler/rustc_mir_dataflow/Cargo.toml | 3 --- compiler/rustc_mir_dataflow/src/lib.rs | 1 + compiler/rustc_mir_transform/Cargo.toml | 3 --- compiler/rustc_mir_transform/src/lib.rs | 1 + compiler/rustc_monomorphize/Cargo.toml | 3 --- compiler/rustc_monomorphize/src/lib.rs | 1 + compiler/rustc_next_trait_solver/Cargo.toml | 3 --- compiler/rustc_next_trait_solver/src/lib.rs | 1 + compiler/rustc_parse/Cargo.toml | 2 -- compiler/rustc_parse/src/lib.rs | 1 + compiler/rustc_parse_format/Cargo.toml | 3 --- compiler/rustc_parse_format/src/lib.rs | 1 + compiler/rustc_passes/Cargo.toml | 3 --- compiler/rustc_passes/src/lib.rs | 1 + compiler/rustc_pattern_analysis/Cargo.toml | 3 --- compiler/rustc_pattern_analysis/src/lib.rs | 1 + .../rustc_pattern_analysis/tests/common/mod.rs | 14 +++++++------- compiler/rustc_privacy/Cargo.toml | 3 --- compiler/rustc_privacy/src/lib.rs | 1 + compiler/rustc_query_impl/Cargo.toml | 3 --- compiler/rustc_query_impl/src/lib.rs | 1 + compiler/rustc_query_system/Cargo.toml | 3 --- compiler/rustc_query_system/src/lib.rs | 1 + compiler/rustc_resolve/Cargo.toml | 3 --- compiler/rustc_resolve/src/lib.rs | 1 + compiler/rustc_sanitizers/Cargo.toml | 3 --- compiler/rustc_sanitizers/src/lib.rs | 1 + compiler/rustc_serialize/Cargo.toml | 3 --- compiler/rustc_serialize/src/lib.rs | 1 + compiler/rustc_session/Cargo.toml | 3 --- compiler/rustc_session/src/lib.rs | 1 + compiler/rustc_smir/Cargo.toml | 3 --- compiler/rustc_smir/src/lib.rs | 1 + compiler/rustc_span/Cargo.toml | 3 --- compiler/rustc_span/src/lib.rs | 1 + compiler/rustc_symbol_mangling/Cargo.toml | 3 --- compiler/rustc_symbol_mangling/src/lib.rs | 1 + compiler/rustc_target/Cargo.toml | 3 --- compiler/rustc_target/src/lib.rs | 1 + compiler/rustc_trait_selection/Cargo.toml | 3 --- compiler/rustc_trait_selection/src/lib.rs | 1 + compiler/rustc_traits/Cargo.toml | 3 --- compiler/rustc_traits/src/lib.rs | 1 + compiler/rustc_transmute/Cargo.toml | 3 --- compiler/rustc_transmute/src/lib.rs | 1 + compiler/rustc_ty_utils/Cargo.toml | 3 --- compiler/rustc_ty_utils/src/lib.rs | 1 + compiler/rustc_type_ir/Cargo.toml | 4 ++-- compiler/rustc_type_ir/src/lib.rs | 1 + compiler/rustc_type_ir_macros/Cargo.toml | 3 --- compiler/stable_mir/Cargo.toml | 3 --- src/bootstrap/src/core/builder/cargo.rs | 13 ++++--------- 144 files changed, 90 insertions(+), 252 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e2d032e08066..20a43aaaeeb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,20 +63,6 @@ exclude = [ "src/tools/x", ] -# These lints are applied to many crates in the workspace. In practice, this is -# all crates under `compiler/`. -# -# NOTE: rustc-specific lints (e.g. `rustc::internal`) aren't supported by -# Cargo. (Support for them is possibly blocked by #44690 (attributes for -# tools).) Those lints are instead specified for `compiler/` crates in -# `src/bootstrap/src/core/builder/cargo.rs`. -[workspace.lints.rust] -# FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all of the -# individual lints are satisfied. -keyword_idents_2024 = "warn" -unreachable_pub = "warn" -unsafe_op_in_unsafe_fn = "warn" - [profile.release.package.rustc-rayon-core] # The rustc fork of Rayon has deadlock detection code which intermittently # causes overflows in the CI (see https://github.com/rust-lang/rust/issues/90227) diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 7af0b34d2daf..f4caa3ef769d 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -32,6 +32,3 @@ llvm = ['rustc_driver_impl/llvm'] max_level_info = ['rustc_driver_impl/max_level_info'] rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts'] # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 4713b3474bdb..86dc84e2016d 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -31,6 +31,3 @@ nightly = [ ] randomize = ["dep:rand", "dep:rand_xoshiro", "nightly"] # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 078b676e40eb..1b7375820093 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -5,6 +5,7 @@ #![cfg_attr(feature = "nightly", feature(rustc_attrs))] #![cfg_attr(feature = "nightly", feature(rustdoc_internals))] #![cfg_attr(feature = "nightly", feature(step_trait))] +#![warn(unreachable_pub)] // tidy-alphabetical-end /*! ABI handling for rustc diff --git a/compiler/rustc_arena/Cargo.toml b/compiler/rustc_arena/Cargo.toml index 1a600f0ee3f8..bbcd8ea6d389 100644 --- a/compiler/rustc_arena/Cargo.toml +++ b/compiler/rustc_arena/Cargo.toml @@ -7,6 +7,3 @@ edition = "2024" # tidy-alphabetical-start smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 6aaac072e4b2..3b44e9963581 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -23,6 +23,7 @@ #![feature(maybe_uninit_slice)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::alloc::Layout; diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 259b51689e42..902287d03280 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -18,6 +18,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 294c6c9ba7a5..6372c66050e7 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -19,6 +19,7 @@ #![feature(never_type)] #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod util { diff --git a/compiler/rustc_ast_ir/Cargo.toml b/compiler/rustc_ast_ir/Cargo.toml index 668c45438d6d..f54e9687d8c7 100644 --- a/compiler/rustc_ast_ir/Cargo.toml +++ b/compiler/rustc_ast_ir/Cargo.toml @@ -19,6 +19,3 @@ nightly = [ "dep:rustc_macros", "dep:rustc_span", ] - -[lints] -workspace = true diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index 6d05cd18cec1..9884e191ea7b 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -9,6 +9,7 @@ #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(never_type))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] +#![warn(unreachable_pub)] // tidy-alphabetical-end #[cfg(feature = "nightly")] diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 358963c79975..2ec4f4b05551 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -28,6 +28,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4cecc56909e5..1c4edd8348f4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -38,6 +38,7 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::sync::Arc; diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 5966308a2626..c738cb2aa2fd 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -20,6 +20,3 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 093199cf3421..b4ed70d83e57 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -10,6 +10,7 @@ #![feature(iter_is_partitioned)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod ast_validation; diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index b120bdc2f05e..2634dd1fdf93 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -12,6 +12,3 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 84d9ce278a21..602ab69ee5b5 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -3,6 +3,7 @@ #![doc(rust_logo)] #![feature(box_patterns)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod helpers; diff --git a/compiler/rustc_attr_data_structures/Cargo.toml b/compiler/rustc_attr_data_structures/Cargo.toml index 8fbc21f3ba28..b18923c337ff 100644 --- a/compiler/rustc_attr_data_structures/Cargo.toml +++ b/compiler/rustc_attr_data_structures/Cargo.toml @@ -14,6 +14,3 @@ rustc_serialize = {path = "../rustc_serialize"} rustc_span = {path = "../rustc_span"} thin-vec = "0.2.12" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index be00d1c10e0c..f4986d1d1872 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -3,6 +3,7 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod attributes; diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml index 24b552e2de4b..6b4ce957630f 100644 --- a/compiler/rustc_attr_parsing/Cargo.toml +++ b/compiler/rustc_attr_parsing/Cargo.toml @@ -22,6 +22,3 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 249e71ef70dc..386f2c98447b 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -80,6 +80,7 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end #[macro_use] diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml index 1480b59f1e02..cb0e145386b8 100644 --- a/compiler/rustc_baked_icu_data/Cargo.toml +++ b/compiler/rustc_baked_icu_data/Cargo.toml @@ -11,6 +11,3 @@ icu_locid_transform = "1.3.2" icu_provider = { version = "1.2", features = ["sync"] } zerovec = "0.10.0" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs index df9bee0ebf51..f86a9db61c60 100644 --- a/compiler/rustc_baked_icu_data/src/lib.rs +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -23,9 +23,9 @@ // tidy-alphabetical-start #![allow(elided_lifetimes_in_paths)] #![allow(internal_features)] -#![allow(unreachable_pub)] // because this crate is mostly generated code #![doc(rust_logo)] #![feature(rustdoc_internals)] +// #![warn(unreachable_pub)] // don't use because this crate is mostly generated code // tidy-alphabetical-end mod data { diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml index 15338eeb37a8..9e7d55180a23 100644 --- a/compiler/rustc_borrowck/Cargo.toml +++ b/compiler/rustc_borrowck/Cargo.toml @@ -27,6 +27,3 @@ rustc_traits = { path = "../rustc_traits" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4d3774682ce8..64a533e05ffd 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -13,6 +13,7 @@ #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index da3572eebeea..b5f4f2efd1f5 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -3,6 +3,10 @@ name = "rustc_builtin_macros" version = "0.0.0" edition = "2024" + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(llvm_enzyme)'] } + [lib] doctest = false @@ -30,6 +34,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index c23ce1e5e4a2..ca16583a45de 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -18,6 +18,7 @@ #![feature(rustdoc_internals)] #![feature(string_from_utf8_lossy_owned)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 1741c3bacc77..d3ce7c5a1130 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -43,6 +43,3 @@ serde_json = "1" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 2f3c8c75b0bf..e51d4852db28 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -19,6 +19,7 @@ #![feature(rustdoc_internals)] #![feature(slice_as_array)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::any::Any; diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index c00be0e99263..1346efcb87c2 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -63,6 +63,3 @@ features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", [target.'cfg(windows)'.dependencies.windows] version = "0.59.0" features = ["Win32_Globalization"] - -[lints] -workspace = true diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 8ad040324147..4e758bfdec39 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -14,6 +14,7 @@ #![feature(rustdoc_internals)] #![feature(trait_alias)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end //! This crate contains codegen code that is used by all codegen backends (LLVM and others). diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index d76238a3992f..a0cc2c65e6e0 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -26,6 +26,3 @@ rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_type_ir = { path = "../rustc_type_ir" } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index da52d60ae59f..ed5489652fba 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -16,6 +16,7 @@ #![feature(unqualified_local_imports)] #![feature(yeet_expr)] #![warn(unqualified_local_imports)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod check_consts; diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index b364ab0dde4f..bdf5494f2107 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -54,6 +54,3 @@ memmap2 = "0.2.1" [target.'cfg(not(target_has_atomic = "64"))'.dependencies] portable-atomic = "1.5.1" - -[lints] -workspace = true diff --git a/compiler/rustc_data_structures/src/graph/tests.rs b/compiler/rustc_data_structures/src/graph/tests.rs index e48b9686c260..b69b9dbc4a8e 100644 --- a/compiler/rustc_data_structures/src/graph/tests.rs +++ b/compiler/rustc_data_structures/src/graph/tests.rs @@ -3,7 +3,7 @@ use std::cmp::max; use super::*; use crate::fx::FxHashMap; -pub(super) struct TestGraph { +pub struct TestGraph { num_nodes: usize, start_node: usize, successors: FxHashMap>, @@ -11,7 +11,7 @@ pub(super) struct TestGraph { } impl TestGraph { - pub(super) fn new(start_node: usize, edges: &[(usize, usize)]) -> Self { + pub fn new(start_node: usize, edges: &[(usize, usize)]) -> Self { let mut graph = TestGraph { num_nodes: start_node + 1, start_node, diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index 8d19fc5f9ccf..78d69a66edc8 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -313,7 +313,7 @@ pub struct Error { mod helper { use super::*; - pub(super) type ObligationTreeIdGenerator = impl Iterator; + pub type ObligationTreeIdGenerator = impl Iterator; impl ObligationForest { pub fn new() -> ObligationForest { ObligationForest { diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 616a18a72ab7..a1cc75c49850 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -88,7 +88,7 @@ mod mode { // Whether thread safety might be enabled. #[inline] - pub(super) fn might_be_dyn_thread_safe() -> bool { + pub fn might_be_dyn_thread_safe() -> bool { DYN_THREAD_SAFE_MODE.load(Ordering::Relaxed) != DYN_NOT_THREAD_SAFE } diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index 8ef8a3f35856..1ba631b86237 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs @@ -46,7 +46,7 @@ pub fn parallel_guard(f: impl FnOnce(&ParallelGuard) -> R) -> R { ret } -fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) +pub fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) where A: FnOnce() -> RA, B: FnOnce() -> RB, diff --git a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs index 85b21a7c8ecd..9c1e4cefa692 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs @@ -7,7 +7,7 @@ use crate::stable_hasher::{HashStable, StableHasher}; /// A tag type used in [`TaggedRef`] tests. #[derive(Copy, Clone, Debug, PartialEq, Eq)] -enum Tag2 { +pub enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index d27895a5e7a2..e3ee83512952 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -10,6 +10,3 @@ crate-type = ["dylib"] # tidy-alphabetical-start rustc_driver_impl = { path = "../rustc_driver_impl" } # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 4469fa4e1f3a..8593d1faba26 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -79,6 +79,3 @@ rustc_randomized_layouts = [ 'rustc_middle/rustc_randomized_layouts' ] # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 6e4020c6eca1..a2ddff7183e6 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -16,6 +16,7 @@ #![feature(result_flattening)] #![feature(rustdoc_internals)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cmp::max; diff --git a/compiler/rustc_error_codes/Cargo.toml b/compiler/rustc_error_codes/Cargo.toml index d89e4526016c..55b4e8990512 100644 --- a/compiler/rustc_error_codes/Cargo.toml +++ b/compiler/rustc_error_codes/Cargo.toml @@ -6,6 +6,3 @@ edition = "2024" [dependencies] # tidy-alphabetical-start # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index dfeef5a957d6..d53d5678832b 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -6,6 +6,7 @@ #![deny(rustdoc::invalid_codeblock_attributes)] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end // This higher-order macro defines the error codes that are in use. It is used diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml index e9047ba16e50..578af7fc51d4 100644 --- a/compiler/rustc_error_messages/Cargo.toml +++ b/compiler/rustc_error_messages/Cargo.toml @@ -19,6 +19,3 @@ rustc_span = { path = "../rustc_span" } tracing = "0.1" unic-langid = { version = "0.9.0", features = ["macros"] } # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index a6fbbb29ccd3..ba1c3e185c2d 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -4,6 +4,7 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(type_alias_impl_trait)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index fc39a726093a..b11793c190a1 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -39,6 +39,3 @@ features = [ "Win32_Security", "Win32_System_Threading", ] - -[lints] -workspace = true diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 80e43ede4453..86959b28e538 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -25,6 +25,7 @@ #![feature(trait_alias)] #![feature(try_blocks)] #![feature(yeet_expr)] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_errors; diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index f051ea0c2ac1..0ba139ea5cc5 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -29,6 +29,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 4222c9fe9061..777044e3f33b 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -13,6 +13,7 @@ #![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro as pm; diff --git a/compiler/rustc_feature/Cargo.toml b/compiler/rustc_feature/Cargo.toml index 1aaace75404b..a5ae06473cbe 100644 --- a/compiler/rustc_feature/Cargo.toml +++ b/compiler/rustc_feature/Cargo.toml @@ -10,6 +10,3 @@ rustc_span = { path = "../rustc_span" } serde = { version = "1.0.125", features = [ "derive" ] } serde_json = "1.0.59" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 25764755a8fc..0b034a2ae107 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -15,6 +15,7 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod accepted; diff --git a/compiler/rustc_fluent_macro/Cargo.toml b/compiler/rustc_fluent_macro/Cargo.toml index 695e8b3fd5db..ce76b2745eaa 100644 --- a/compiler/rustc_fluent_macro/Cargo.toml +++ b/compiler/rustc_fluent_macro/Cargo.toml @@ -16,6 +16,3 @@ quote = "1" syn = { version = "2", features = ["full"] } unic-langid = { version = "0.9.0", features = ["macros"] } # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index c6e0484b9210..3ad51fa1e64d 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -7,6 +7,7 @@ #![feature(proc_macro_span)] #![feature(rustdoc_internals)] #![feature(track_path)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_fs_util/Cargo.toml b/compiler/rustc_fs_util/Cargo.toml index 3518209ea5b7..baca3bc7d49e 100644 --- a/compiler/rustc_fs_util/Cargo.toml +++ b/compiler/rustc_fs_util/Cargo.toml @@ -6,6 +6,3 @@ edition = "2024" [dependencies] # tidy-alphabetical-start # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_graphviz/Cargo.toml b/compiler/rustc_graphviz/Cargo.toml index 2672a624eabe..d84943760bae 100644 --- a/compiler/rustc_graphviz/Cargo.toml +++ b/compiler/rustc_graphviz/Cargo.toml @@ -6,6 +6,3 @@ edition = "2024" [dependencies] # tidy-alphabetical-start # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index c8f8fd5be023..b5774f64b66b 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -277,6 +277,7 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_hashes/Cargo.toml b/compiler/rustc_hashes/Cargo.toml index ff46696c4c06..c7a273cff88c 100644 --- a/compiler/rustc_hashes/Cargo.toml +++ b/compiler/rustc_hashes/Cargo.toml @@ -7,6 +7,3 @@ edition = "2024" # tidy-alphabetical-start rustc-stable-hash = { version = "0.1.0" } # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index e45c49cd7dbf..7ca8539845a0 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -21,6 +21,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 84d369f1eddb..270d4fbec30f 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -13,6 +13,7 @@ #![feature(never_type)] #![feature(rustc_attrs)] #![feature(variant_count)] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_hir; diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index 99ced5ff0a91..55a816a855af 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -32,6 +32,3 @@ rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 26a20690a95c..50b0e32b95eb 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -73,6 +73,7 @@ This API is completely unstable and subject to change. #![feature(slice_partition_dedup)] #![feature(try_blocks)] #![feature(unwrap_infallible)] +#![warn(unreachable_pub)] // tidy-alphabetical-end // These are used by Clippy. diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml index bc6431d02712..91da8cb3fc5f 100644 --- a/compiler/rustc_hir_pretty/Cargo.toml +++ b/compiler/rustc_hir_pretty/Cargo.toml @@ -12,6 +12,3 @@ rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } rustc_hir = { path = "../rustc_hir" } rustc_span = { path = "../rustc_span" } # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 0e3721126fb3..2572ff50eb74 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -3,6 +3,7 @@ // tidy-alphabetical-start #![recursion_limit = "256"] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::Cell; diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index 1d6486fb7dc0..f1afb7b712d5 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -27,6 +27,3 @@ rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 263fb84206e0..8b9c2b4a6ca0 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -8,6 +8,7 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod _match; diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index 754881309bf5..4939bfb3a1cd 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -22,6 +22,3 @@ rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 299ee4876389..563ed7614c60 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -7,6 +7,7 @@ #![doc(rust_logo)] #![feature(file_buffered)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod assert_dep_graph; diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml index ee6fe11f9a5b..3d83a3c98daf 100644 --- a/compiler/rustc_index/Cargo.toml +++ b/compiler/rustc_index/Cargo.toml @@ -21,6 +21,3 @@ nightly = [ ] rustc_randomized_layouts = [] # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index cc680838e7e7..3441a5f65c78 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -4,6 +4,7 @@ #![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))] #![cfg_attr(feature = "nightly", feature(new_range_api))] #![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod bit_set; diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml index de100bd0e2c1..891e7ded6199 100644 --- a/compiler/rustc_index_macros/Cargo.toml +++ b/compiler/rustc_index_macros/Cargo.toml @@ -13,6 +13,3 @@ quote = "1" [features] nightly = [] - -[lints] -workspace = true diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs index f0b58eabbff9..67ec77611339 100644 --- a/compiler/rustc_index_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs @@ -305,7 +305,7 @@ impl Parse for Newtype { } } -pub(crate) fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as Newtype); input.0.into() } diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 242886a92482..08c036148849 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -21,6 +21,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index ece18f4ea64e..a04b2bb2b08b 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -24,6 +24,7 @@ #![feature(let_chains)] #![feature(rustdoc_internals)] #![recursion_limit = "512"] // For rustdoc +#![warn(unreachable_pub)] // tidy-alphabetical-end mod errors; diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index add8c0e20e63..9c9660cf5046 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -56,6 +56,3 @@ tracing = "0.1" # tidy-alphabetical-start llvm = ['dep:rustc_codegen_llvm'] # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 67e0be93523d..54cd341698f0 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -4,6 +4,7 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod callbacks; diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml index b9b16eebc548..448a50faf458 100644 --- a/compiler/rustc_lexer/Cargo.toml +++ b/compiler/rustc_lexer/Cargo.toml @@ -24,6 +24,3 @@ features = ["emoji"] [dev-dependencies] expect-test = "1.4.0" - -[lints] -workspace = true diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index 61638e45253f..bf18845a0830 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -23,6 +23,7 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod cursor; diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index f6c10aa97441..d6014f5006ad 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -28,6 +28,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" unicode-security = "0.1.0" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 35867d8c9efe..7018774e5c6b 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -32,6 +32,7 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod async_closures; diff --git a/compiler/rustc_lint_defs/Cargo.toml b/compiler/rustc_lint_defs/Cargo.toml index f9b45a00ec10..9ab350daf69d 100644 --- a/compiler/rustc_lint_defs/Cargo.toml +++ b/compiler/rustc_lint_defs/Cargo.toml @@ -15,6 +15,3 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } serde = { version = "1.0.125", features = ["derive"] } # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 46b4b1d43838..e564235c41a5 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -1,3 +1,7 @@ +// tidy-alphabetical-start +#![warn(unreachable_pub)] +// tidy-alphabetical-end + use rustc_abi::ExternAbi; use rustc_ast::AttrId; use rustc_ast::attr::AttributeExt; diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index dcfaf9a0282e..061562b2ec5e 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -14,6 +14,3 @@ libc = "0.2.73" # pinned `cc` in `rustc_codegen_ssa` if you update `cc` here. cc = "=1.2.16" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index 68058250a267..eda9b2b1fc09 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -4,6 +4,7 @@ #![doc(rust_logo)] #![feature(extern_types)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::RefCell; diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml index 665ebd52f474..30f6e9ba8053 100644 --- a/compiler/rustc_log/Cargo.toml +++ b/compiler/rustc_log/Cargo.toml @@ -20,6 +20,3 @@ rustc_span = { path = "../rustc_span" } # tidy-alphabetical-start max_level_info = ['tracing/max_level_info'] # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml index b937f75e892a..f9d3b7583590 100644 --- a/compiler/rustc_macros/Cargo.toml +++ b/compiler/rustc_macros/Cargo.toml @@ -13,6 +13,3 @@ quote = "1" syn = { version = "2.0.9", features = ["full"] } synstructure = "0.13.0" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 44ba064dd824..34fc0f00320c 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -6,6 +6,7 @@ #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] #![feature(proc_macro_tracked_env)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 5fa3047d14e0..a8821640f048 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -31,6 +31,3 @@ rustc_type_ir = { path = "../rustc_type_ir" } tempfile = "3.2" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 8898c5824fa2..ebcc0efd5a67 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -15,6 +15,7 @@ #![feature(proc_macro_internals)] #![feature(rustdoc_internals)] #![feature(trusted_len)] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 3a6216e63a9a..43c1af642dd5 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -43,6 +43,3 @@ tracing = "0.1" # tidy-alphabetical-start rustc_randomized_layouts = [] # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 8fe2cc7101ba..48ea7df5c23f 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -61,6 +61,7 @@ #![feature(try_trait_v2_yeet)] #![feature(type_alias_impl_trait)] #![feature(yeet_expr)] +#![warn(unreachable_pub)] // tidy-alphabetical-end #[cfg(test)] diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index a29c01162664..d70d70a31a4a 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -28,6 +28,3 @@ rustc_span = { path = "../rustc_span" } rustc_trait_selection = { path = "../rustc_trait_selection" } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 8e96d46dac27..fa5db32d9134 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -8,6 +8,7 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end // The `builder` module used to be named `build`, but that was causing GitHub's diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index a171f9641bb6..293bcbef21b8 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml @@ -21,6 +21,3 @@ rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index a0efc623b8e7..a8a56baa1ffc 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -7,6 +7,7 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::ty; diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index 4dc91723f03f..fb8d0ac5e74a 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -30,6 +30,3 @@ rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 739cee5d7f4c..8aa14d15644b 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -12,6 +12,7 @@ #![feature(never_type)] #![feature(try_blocks)] #![feature(yeet_expr)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use hir::ConstContext; diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 51be8e55fa71..36b76d261de6 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -22,6 +22,3 @@ serde = "1" serde_json = "1" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 8f6914f3d724..714b64b3a231 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -4,6 +4,7 @@ #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(let_chains)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_hir::lang_items::LangItem; diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index e119d23d41a1..63aa60f2f26b 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -24,6 +24,3 @@ nightly = [ "rustc_index/nightly", "rustc_type_ir/nightly", ] - -[lints] -workspace = true diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index f6963a790675..d67ae2550d96 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -6,6 +6,7 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_type_ir_inherent)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod canonicalizer; diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index b78ac197dbba..c9dcab0c871d 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -26,5 +26,3 @@ unicode-width = "0.2.0" [dev-dependencies] termcolor = "1.2" -[lints] -workspace = true diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 2edc8c83017d..1a104ff5e337 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -12,6 +12,7 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(string_from_utf8_lossy_owned)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml index a720903097ae..a39cca716d23 100644 --- a/compiler/rustc_parse_format/Cargo.toml +++ b/compiler/rustc_parse_format/Cargo.toml @@ -8,6 +8,3 @@ edition = "2024" rustc_index = { path = "../rustc_index", default-features = false } rustc_lexer = { path = "../rustc_lexer" } # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 287bd8678da2..3b985621b577 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -13,6 +13,7 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))) )] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub use Alignment::*; diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index 4cd7fde60348..ba81ef3103bd 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -26,6 +26,3 @@ rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 93ff0f66d695..1aa077ad2bb5 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -12,6 +12,7 @@ #![feature(map_try_insert)] #![feature(rustdoc_internals)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml index 0624fe96cd91..40d549630aca 100644 --- a/compiler/rustc_pattern_analysis/Cargo.toml +++ b/compiler/rustc_pattern_analysis/Cargo.toml @@ -43,6 +43,3 @@ rustc = [ "smallvec/may_dangle", "rustc_index/nightly", ] - -[lints] -workspace = true diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index eeea724a29b4..a3400ebb7993 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -6,6 +6,7 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(feature = "rustc", feature(let_chains))] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod constructor; diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs index 8980b644f59b..365bc2d863f4 100644 --- a/compiler/rustc_pattern_analysis/tests/common/mod.rs +++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs @@ -5,7 +5,7 @@ use rustc_pattern_analysis::usefulness::{PlaceValidity, UsefulnessReport}; use rustc_pattern_analysis::{MatchArm, PatCx, PrivateUninhabitedField}; /// Sets up `tracing` for easier debugging. Tries to look like the `rustc` setup. -fn init_tracing() { +pub fn init_tracing() { use tracing_subscriber::Layer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; @@ -24,7 +24,7 @@ fn init_tracing() { /// A simple set of types. #[allow(dead_code)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub(super) enum Ty { +pub enum Ty { /// Booleans Bool, /// 8-bit unsigned integers @@ -41,7 +41,7 @@ pub(super) enum Ty { /// The important logic. impl Ty { - pub(super) fn sub_tys(&self, ctor: &Constructor) -> Vec { + pub fn sub_tys(&self, ctor: &Constructor) -> Vec { use Constructor::*; match (ctor, *self) { (Struct, Ty::Tuple(tys)) => tys.iter().copied().collect(), @@ -63,7 +63,7 @@ impl Ty { } } - fn ctor_set(&self) -> ConstructorSet { + pub fn ctor_set(&self) -> ConstructorSet { match *self { Ty::Bool => ConstructorSet::Bool, Ty::U8 => ConstructorSet::Integers { @@ -104,7 +104,7 @@ impl Ty { } } - fn write_variant_name( + pub fn write_variant_name( &self, f: &mut std::fmt::Formatter<'_>, ctor: &Constructor, @@ -120,7 +120,7 @@ impl Ty { } /// Compute usefulness in our simple context (and set up tracing for easier debugging). -pub(super) fn compute_match_usefulness<'p>( +pub fn compute_match_usefulness<'p>( arms: &[MatchArm<'p, Cx>], ty: Ty, scrut_validity: PlaceValidity, @@ -137,7 +137,7 @@ pub(super) fn compute_match_usefulness<'p>( } #[derive(Debug)] -pub(super) struct Cx; +pub struct Cx; /// The context for pattern analysis. Forwards anything interesting to `Ty` methods. impl PatCx for Cx { diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index dc00ea8af43a..242c67d732af 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -18,6 +18,3 @@ rustc_span = { path = "../rustc_span" } rustc_ty_utils = { path = "../rustc_ty_utils" } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5e3e8d69b603..5271d03a6f61 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -6,6 +6,7 @@ #![feature(let_chains)] #![feature(rustdoc_internals)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod errors; diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 42f784481515..c85156e059e5 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -20,6 +20,3 @@ rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 40da46a027df..73c205fdb17d 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -8,6 +8,7 @@ #![feature(min_specialization)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_data_structures::stable_hasher::HashStable; diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index c34d1170f0e1..3e8ccb51021e 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -25,6 +25,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index a546362414cf..ee984095ad84 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -6,6 +6,7 @@ #![feature(hash_raw_entry)] #![feature(let_chains)] #![feature(min_specialization)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod cache; diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 8958a3ac3048..f4771f1af2cf 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -28,6 +28,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f724ecf76b3c..ccdca8552320 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -20,6 +20,7 @@ #![feature(let_chains)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::{Cell, RefCell}; diff --git a/compiler/rustc_sanitizers/Cargo.toml b/compiler/rustc_sanitizers/Cargo.toml index e18ed121ca50..900cd4243b13 100644 --- a/compiler/rustc_sanitizers/Cargo.toml +++ b/compiler/rustc_sanitizers/Cargo.toml @@ -15,6 +15,3 @@ rustc_middle = { path = "../rustc_middle" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } - -[lints] -workspace = true diff --git a/compiler/rustc_sanitizers/src/lib.rs b/compiler/rustc_sanitizers/src/lib.rs index e4792563e71e..55be931bcd6d 100644 --- a/compiler/rustc_sanitizers/src/lib.rs +++ b/compiler/rustc_sanitizers/src/lib.rs @@ -5,6 +5,7 @@ // tidy-alphabetical-start #![feature(let_chains)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod cfi; diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 10bfe14abde0..948242352e7a 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -16,6 +16,3 @@ thin-vec = "0.2.12" rustc_macros = { path = "../rustc_macros" } tempfile = "3.2" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 13c1a273eb81..9e9b78cfdd57 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -14,6 +14,7 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub use self::serialize::{Decodable, Decoder, Encodable, Encoder}; diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 4b2b41ba845a..a087725d34dd 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -37,6 +37,3 @@ features = [ "Win32_Foundation", "Win32_System_LibraryLoader", ] - -[lints] -workspace = true diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 0e19b982a133..d432e84fdb22 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -7,6 +7,7 @@ // To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums // with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers"). #![recursion_limit = "256"] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod errors; diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index d14bff73b8b4..a11df9a9c9bc 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -18,6 +18,3 @@ scoped-tls = "1.0" stable_mir = {path = "../stable_mir" } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 9f8888753061..2215e2f01ade 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -15,6 +15,7 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod rustc_internal; diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index a6f86151b812..43a2d692577e 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -22,6 +22,3 @@ sha2 = "0.10.1" tracing = "0.1" unicode-width = "0.2.0" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index f19d4d9f3624..798e186a94b1 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -32,6 +32,7 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(slice_as_chunks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end // The code produced by the `Encodable`/`Decodable` derive macros refer to diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index 89fe7ef2e408..90ddf4c8a040 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -19,6 +19,3 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 269401ef3a2d..4312c82815c1 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -93,6 +93,7 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_hir::def::DefKind; diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml index 6a0268cdee76..189b19b02861 100644 --- a/compiler/rustc_target/Cargo.toml +++ b/compiler/rustc_target/Cargo.toml @@ -22,6 +22,3 @@ default-features = false features = ["elf", "macho"] version = "0.36.2" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index a8d7da5692de..7ebe96960ed0 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -16,6 +16,7 @@ #![feature(let_chains)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 5def437bd807..1c61e23362a8 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -26,6 +26,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2" tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index b18fb0fb8fd3..b235d0da83cc 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -31,6 +31,7 @@ #![feature(unwrap_infallible)] #![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc +#![warn(unreachable_pub)] // For rustdoc // tidy-alphabetical-end pub mod error_reporting; diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index 49bcaae85714..04aef4e7b9e0 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -13,6 +13,3 @@ rustc_span = { path = "../rustc_span" } rustc_trait_selection = { path = "../rustc_trait_selection" } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index 697c83918031..d2f979bd6d9d 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -2,6 +2,7 @@ // tidy-alphabetical-start #![recursion_limit = "256"] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod codegen; diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index ae1beb107288..f0c783b30020 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -25,6 +25,3 @@ rustc = [ # tidy-alphabetical-start itertools = "0.12" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 00928137d297..81a11f7cfb26 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,5 +1,6 @@ // tidy-alphabetical-start #![feature(never_type)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set}; diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 61acc12d0eb9..4c7a57f2931b 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -23,6 +23,3 @@ rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_type_ir = { path = "../rustc_type_ir" } tracing = "0.1" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 35cc6f398565..8be1611bb9ac 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -16,6 +16,7 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 0381797d7e92..7b2593b96e37 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -34,5 +34,5 @@ nightly = [ "rustc_ast_ir/nightly", ] -[lints] -workspace = true +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index e2dfd9173fab..15ef4e7d6c1d 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -6,6 +6,7 @@ feature(associated_type_defaults, never_type, rustc_attrs, negative_impls) )] #![cfg_attr(feature = "nightly", allow(internal_features))] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_type_ir; diff --git a/compiler/rustc_type_ir_macros/Cargo.toml b/compiler/rustc_type_ir_macros/Cargo.toml index a3fa46238558..15a555750992 100644 --- a/compiler/rustc_type_ir_macros/Cargo.toml +++ b/compiler/rustc_type_ir_macros/Cargo.toml @@ -13,6 +13,3 @@ quote = "1" syn = { version = "2.0.9", features = ["full"] } synstructure = "0.13.0" # tidy-alphabetical-end - -[lints] -workspace = true diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml index 358a39154024..d691a0e4f22f 100644 --- a/compiler/stable_mir/Cargo.toml +++ b/compiler/stable_mir/Cargo.toml @@ -6,6 +6,3 @@ edition = "2024" [dependencies] scoped-tls = "1.0" serde = { version = "1.0.125", features = [ "derive" ] } - -[lints] -workspace = true diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 2cbf82ccda36..12dd40d14e9b 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -1072,17 +1072,12 @@ impl Builder<'_> { } if mode == Mode::Rustc { - // NOTE: rustc-specific lints are specified here. Normal rust lints - // are specified in the `[workspace.lints.rust]` section in the - // top-level `Cargo.toml`. If/when tool lints are supported by - // Cargo, these lints can be move to a `[workspace.lints.rustc]` - // section in the top-level `Cargo.toml`. - // - // NOTE: these flags are added to RUSTFLAGS, which is ignored when - // compiling proc macro crates such as `rustc_macros`, - // unfortunately. rustflags.arg("-Wrustc::internal"); rustflags.arg("-Drustc::symbol_intern_string_literal"); + // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all + // of the individual lints are satisfied. + rustflags.arg("-Wkeyword_idents_2024"); + rustflags.arg("-Wunsafe_op_in_unsafe_fn"); } if self.config.rust_frame_pointers { From fb9ce0297682a0c54fe374800c2a41cc666d9580 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 12 Feb 2025 16:59:13 +0100 Subject: [PATCH 904/991] Limit formatting width and precision to 16 bits. --- compiler/rustc_ast/src/format.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 11 +++++ compiler/rustc_ast_lowering/src/format.rs | 2 +- compiler/rustc_parse_format/src/lib.rs | 18 ++++---- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/fmt/float.rs | 12 ++--- library/core/src/fmt/mod.rs | 51 ++++++++++++---------- library/core/src/fmt/rt.rs | 13 ++++-- library/core/src/time.rs | 3 +- library/coretests/tests/num/flt2dec/mod.rs | 2 +- 10 files changed, 69 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_ast/src/format.rs b/compiler/rustc_ast/src/format.rs index b93846c1fe6f..b611ddea1d9f 100644 --- a/compiler/rustc_ast/src/format.rs +++ b/compiler/rustc_ast/src/format.rs @@ -266,7 +266,7 @@ pub enum FormatAlignment { #[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)] pub enum FormatCount { /// `{:5}` or `{:.5}` - Literal(usize), + Literal(u16), /// `{:.*}`, `{:.5$}`, or `{:a$}`, etc. Argument(FormatArgPosition), } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index acf35b75e4df..0f175ea615f6 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -2152,6 +2152,17 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(sp, hir::ExprKind::Lit(lit)) } + pub(super) fn expr_u16(&mut self, sp: Span, value: u16) -> hir::Expr<'hir> { + let lit = self.arena.alloc(hir::Lit { + span: sp, + node: ast::LitKind::Int( + u128::from(value).into(), + ast::LitIntType::Unsigned(ast::UintTy::U16), + ), + }); + self.expr(sp, hir::ExprKind::Lit(lit)) + } + pub(super) fn expr_char(&mut self, sp: Span, value: char) -> hir::Expr<'hir> { let lit = self.arena.alloc(hir::Lit { span: sp, node: ast::LitKind::Char(value) }); self.expr(sp, hir::ExprKind::Lit(lit)) diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 07b94dbc2aeb..faa47274f96c 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -292,7 +292,7 @@ fn make_count<'hir>( hir::LangItem::FormatCount, sym::Is, )); - let value = ctx.arena.alloc_from_iter([ctx.expr_usize(sp, *n)]); + let value = ctx.arena.alloc_from_iter([ctx.expr_u16(sp, *n)]); ctx.expr_call_mut(sp, count_is, value) } Some(FormatCount::Argument(arg)) => { diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 287bd8678da2..5b8a2fe52d3f 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -189,7 +189,7 @@ pub enum DebugHex { #[derive(Copy, Clone, Debug, PartialEq)] pub enum Count<'a> { /// The count is specified explicitly. - CountIs(usize), + CountIs(u16), /// The count is specified by the argument with the given name. CountIsName(&'a str, InnerSpan), /// The count is specified by the argument at the given index. @@ -564,7 +564,7 @@ impl<'a> Parser<'a> { /// consuming a macro argument, `None` if it's the case. fn position(&mut self) -> Option> { if let Some(i) = self.integer() { - Some(ArgumentIs(i)) + Some(ArgumentIs(i.into())) } else { match self.cur.peek() { Some(&(lo, c)) if rustc_lexer::is_id_start(c) => { @@ -770,7 +770,7 @@ impl<'a> Parser<'a> { /// width. fn count(&mut self, start: usize) -> Count<'a> { if let Some(i) = self.integer() { - if self.consume('$') { CountIsParam(i) } else { CountIs(i) } + if self.consume('$') { CountIsParam(i.into()) } else { CountIs(i) } } else { let tmp = self.cur.clone(); let word = self.word(); @@ -821,15 +821,15 @@ impl<'a> Parser<'a> { word } - fn integer(&mut self) -> Option { - let mut cur: usize = 0; + fn integer(&mut self) -> Option { + let mut cur: u16 = 0; let mut found = false; let mut overflow = false; let start = self.current_pos(); while let Some(&(_, c)) = self.cur.peek() { if let Some(i) = c.to_digit(10) { let (tmp, mul_overflow) = cur.overflowing_mul(10); - let (tmp, add_overflow) = tmp.overflowing_add(i as usize); + let (tmp, add_overflow) = tmp.overflowing_add(i as u16); if mul_overflow || add_overflow { overflow = true; } @@ -846,11 +846,11 @@ impl<'a> Parser<'a> { let overflowed_int = &self.input[start..end]; self.err( format!( - "integer `{}` does not fit into the type `usize` whose range is `0..={}`", + "integer `{}` does not fit into the type `u16` whose range is `0..={}`", overflowed_int, - usize::MAX + u16::MAX ), - "integer out of range for `usize`", + "integer out of range for `u16`", self.span(start, end), ); } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9e7f5047eb30..8b701de34545 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1016,6 +1016,7 @@ symbols! { from_residual, from_size_align_unchecked, from_str_method, + from_u16, from_usize, from_yeet, fs_create_dir, diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index 3f10158193d7..4a43c12be9aa 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -29,7 +29,7 @@ fn float_to_decimal_common_exact( fmt: &mut Formatter<'_>, num: &T, sign: flt2dec::Sign, - precision: usize, + precision: u16, ) -> Result where T: flt2dec::DecodableFloat, @@ -40,7 +40,7 @@ where flt2dec::strategy::grisu::format_exact, *num, sign, - precision, + precision.into(), &mut buf, &mut parts, ); @@ -55,7 +55,7 @@ fn float_to_decimal_common_shortest( fmt: &mut Formatter<'_>, num: &T, sign: flt2dec::Sign, - precision: usize, + precision: u16, ) -> Result where T: flt2dec::DecodableFloat, @@ -68,7 +68,7 @@ where flt2dec::strategy::grisu::format_shortest, *num, sign, - precision, + precision.into(), &mut buf, &mut parts, ); @@ -101,7 +101,7 @@ fn float_to_exponential_common_exact( fmt: &mut Formatter<'_>, num: &T, sign: flt2dec::Sign, - precision: usize, + precision: u16, upper: bool, ) -> Result where @@ -113,7 +113,7 @@ where flt2dec::strategy::grisu::format_exact, *num, sign, - precision, + precision.into(), upper, &mut buf, &mut parts, diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 3f60bb067d6e..e0dc632df705 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -294,8 +294,8 @@ pub struct FormattingOptions { flags: u32, fill: char, align: Option, - width: Option, - precision: Option, + width: Option, + precision: Option, } impl FormattingOptions { @@ -389,7 +389,7 @@ impl FormattingOptions { /// the padding specified by [`FormattingOptions::fill`]/[`FormattingOptions::align`] /// will be used to take up the required space. #[unstable(feature = "formatting_options", issue = "118117")] - pub fn width(&mut self, width: Option) -> &mut Self { + pub fn width(&mut self, width: Option) -> &mut Self { self.width = width; self } @@ -403,7 +403,7 @@ impl FormattingOptions { /// - For floating-point types, this indicates how many digits after the /// decimal point should be printed. #[unstable(feature = "formatting_options", issue = "118117")] - pub fn precision(&mut self, precision: Option) -> &mut Self { + pub fn precision(&mut self, precision: Option) -> &mut Self { self.precision = precision; self } @@ -455,12 +455,12 @@ impl FormattingOptions { } /// Returns the current width. #[unstable(feature = "formatting_options", issue = "118117")] - pub const fn get_width(&self) -> Option { + pub const fn get_width(&self) -> Option { self.width } /// Returns the current precision. #[unstable(feature = "formatting_options", issue = "118117")] - pub const fn get_precision(&self) -> Option { + pub const fn get_precision(&self) -> Option { self.precision } /// Returns the current precision. @@ -1499,15 +1499,18 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argume unsafe { value.fmt(fmt) } } -unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option { +unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option { match *cnt { + #[cfg(bootstrap)] + rt::Count::Is(n) => Some(n as u16), + #[cfg(not(bootstrap))] rt::Count::Is(n) => Some(n), rt::Count::Implied => None, rt::Count::Param(i) => { debug_assert!(i < args.len()); // SAFETY: cnt and args come from the same Arguments, // which guarantees this index is always within bounds. - unsafe { args.get_unchecked(i).as_usize() } + unsafe { args.get_unchecked(i).as_u16() } } } } @@ -1516,11 +1519,11 @@ unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option #[must_use = "don't forget to write the post padding"] pub(crate) struct PostPadding { fill: char, - padding: usize, + padding: u16, } impl PostPadding { - fn new(fill: char, padding: usize) -> PostPadding { + fn new(fill: char, padding: u16) -> PostPadding { PostPadding { fill, padding } } @@ -1634,7 +1637,7 @@ impl<'a> Formatter<'a> { } // Check if we're over the minimum width, if so then we can also // just write the bytes. - Some(min) if width >= min => { + Some(min) if width >= usize::from(min) => { write_prefix(self, sign, prefix)?; self.buf.write_str(buf) } @@ -1645,7 +1648,7 @@ impl<'a> Formatter<'a> { let old_align = crate::mem::replace(&mut self.options.align, Some(Alignment::Right)); write_prefix(self, sign, prefix)?; - let post_padding = self.padding(min - width, Alignment::Right)?; + let post_padding = self.padding(min - width as u16, Alignment::Right)?; self.buf.write_str(buf)?; post_padding.write(self)?; self.options.fill = old_fill; @@ -1654,7 +1657,7 @@ impl<'a> Formatter<'a> { } // Otherwise, the sign and prefix goes after the padding Some(min) => { - let post_padding = self.padding(min - width, Alignment::Right)?; + let post_padding = self.padding(min - width as u16, Alignment::Right)?; write_prefix(self, sign, prefix)?; self.buf.write_str(buf)?; post_padding.write(self) @@ -1702,14 +1705,14 @@ impl<'a> Formatter<'a> { // string being formatted. let (s, char_count) = if let Some(max_char_count) = self.options.precision { let mut iter = s.char_indices(); - let remaining = match iter.advance_by(max_char_count) { + let remaining = match iter.advance_by(usize::from(max_char_count)) { Ok(()) => 0, Err(remaining) => remaining.get(), }; // SAFETY: The offset of `.char_indices()` is guaranteed to be // in-bounds and between character boundaries. let truncated = unsafe { s.get_unchecked(..iter.offset()) }; - (truncated, max_char_count - remaining) + (truncated, usize::from(max_char_count) - remaining) } else { // Use the optimized char counting algorithm for the full string. (s, s.chars().count()) @@ -1717,11 +1720,11 @@ impl<'a> Formatter<'a> { // The `width` field is more of a minimum width parameter at this point. if let Some(width) = self.options.width - && char_count < width + && char_count < usize::from(width) { // If we're under the minimum width, then fill up the minimum width // with the specified string + some alignment. - let post_padding = self.padding(width - char_count, Alignment::Left)?; + let post_padding = self.padding(width - char_count as u16, Alignment::Left)?; self.buf.write_str(s)?; post_padding.write(self) } else { @@ -1737,7 +1740,7 @@ impl<'a> Formatter<'a> { /// thing that is being padded. pub(crate) fn padding( &mut self, - padding: usize, + padding: u16, default: Alignment, ) -> result::Result { let align = self.align().unwrap_or(default); @@ -1777,19 +1780,19 @@ impl<'a> Formatter<'a> { // remove the sign from the formatted parts formatted.sign = ""; - width = width.saturating_sub(sign.len()); + width = width.saturating_sub(sign.len() as u16); self.options.fill = '0'; self.options.align = Some(Alignment::Right); } // remaining parts go through the ordinary padding process. let len = formatted.len(); - let ret = if width <= len { + let ret = if usize::from(width) <= len { // no padding // SAFETY: Per the precondition. unsafe { self.write_formatted_parts(&formatted) } } else { - let post_padding = self.padding(width - len, Alignment::Right)?; + let post_padding = self.padding(width - len as u16, Alignment::Right)?; // SAFETY: Per the precondition. unsafe { self.write_formatted_parts(&formatted)?; @@ -2021,7 +2024,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn width(&self) -> Option { - self.options.width + self.options.width.map(|x| x as usize) } /// Returns the optionally specified precision for numeric types. @@ -2052,7 +2055,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn precision(&self) -> Option { - self.options.precision + self.options.precision.map(|x| x as usize) } /// Determines if the `+` flag was specified. @@ -2792,7 +2795,7 @@ pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Resul f.options.flags |= 1 << (rt::Flag::SignAwareZeroPad as u32); if f.options.width.is_none() { - f.options.width = Some((usize::BITS / 4) as usize + 2); + f.options.width = Some((usize::BITS / 4) as u16 + 2); } } f.options.flags |= 1 << (rt::Flag::Alternate as u32); diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index 85d089a07908..cb908adc1cba 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -47,7 +47,11 @@ pub enum Alignment { #[derive(Copy, Clone)] pub enum Count { /// Specified with a literal number, stores the value + #[cfg(bootstrap)] Is(usize), + /// Specified with a literal number, stores the value + #[cfg(not(bootstrap))] + Is(u16), /// Specified using `$` and `*` syntaxes, stores the index into `args` Param(usize), /// Not specified @@ -74,7 +78,7 @@ enum ArgumentType<'a> { formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result, _lifetime: PhantomData<&'a ()>, }, - Count(usize), + Count(u16), } /// This struct represents a generic "argument" which is taken by format_args!(). @@ -151,7 +155,10 @@ impl Argument<'_> { } #[inline] pub const fn from_usize(x: &usize) -> Argument<'_> { - Argument { ty: ArgumentType::Count(*x) } + if *x > u16::MAX as usize { + panic!("Formatting argument out of range"); + }; + Argument { ty: ArgumentType::Count(*x as u16) } } /// Format this placeholder argument. @@ -181,7 +188,7 @@ impl Argument<'_> { } #[inline] - pub(super) const fn as_usize(&self) -> Option { + pub(super) const fn as_u16(&self) -> Option { match self.ty { ArgumentType::Count(count) => Some(count), ArgumentType::Placeholder { .. } => None, diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 8b211b442eab..37b5c1076fa2 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1377,7 +1377,8 @@ impl fmt::Debug for Duration { } else { // We need to add padding. Use the `Formatter::padding` helper function. let default_align = fmt::Alignment::Left; - let post_padding = f.padding(requested_w - actual_w, default_align)?; + let post_padding = + f.padding((requested_w - actual_w) as u16, default_align)?; emit_without_padding(f)?; post_padding.write(f) } diff --git a/library/coretests/tests/num/flt2dec/mod.rs b/library/coretests/tests/num/flt2dec/mod.rs index 6041923117c2..6e74cc91c5b2 100644 --- a/library/coretests/tests/num/flt2dec/mod.rs +++ b/library/coretests/tests/num/flt2dec/mod.rs @@ -577,7 +577,7 @@ where } // very large output - assert_eq!(to_string(f, 1.1, Minus, 80000), format!("1.1{:0>79999}", "")); + assert_eq!(to_string(f, 1.1, Minus, 50000), format!("1.1{:0>49999}", "")); } pub fn to_shortest_exp_str_test(mut f_: F) From 4374d5461e9a4041dcbd7413c79fced0bec333fc Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 12 Feb 2025 17:33:05 +0100 Subject: [PATCH 905/991] Update tests. --- library/coretests/tests/num/flt2dec/mod.rs | 28 +-- ...nential_common.GVN.32bit.panic-abort.diff} | 45 ++++- ...ential_common.GVN.32bit.panic-unwind.diff} | 45 ++++- ...onential_common.GVN.64bit.panic-abort.diff | 180 ++++++++++++++++++ ...nential_common.GVN.64bit.panic-unwind.diff | 180 ++++++++++++++++++ tests/mir-opt/funky_arms.rs | 1 + 6 files changed, 459 insertions(+), 20 deletions(-) rename tests/mir-opt/{funky_arms.float_to_exponential_common.GVN.panic-abort.diff => funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff} (73%) rename tests/mir-opt/{funky_arms.float_to_exponential_common.GVN.panic-unwind.diff => funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff} (73%) create mode 100644 tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff create mode 100644 tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff diff --git a/library/coretests/tests/num/flt2dec/mod.rs b/library/coretests/tests/num/flt2dec/mod.rs index 6e74cc91c5b2..c64bb0a30720 100644 --- a/library/coretests/tests/num/flt2dec/mod.rs +++ b/library/coretests/tests/num/flt2dec/mod.rs @@ -914,22 +914,22 @@ where ); // very large output - assert_eq!(to_string(f, 0.0, Minus, 80000, false), format!("0.{:0>79999}e0", "")); - assert_eq!(to_string(f, 1.0e1, Minus, 80000, false), format!("1.{:0>79999}e1", "")); - assert_eq!(to_string(f, 1.0e0, Minus, 80000, false), format!("1.{:0>79999}e0", "")); + assert_eq!(to_string(f, 0.0, Minus, 50000, false), format!("0.{:0>49999}e0", "")); + assert_eq!(to_string(f, 1.0e1, Minus, 50000, false), format!("1.{:0>49999}e1", "")); + assert_eq!(to_string(f, 1.0e0, Minus, 50000, false), format!("1.{:0>49999}e0", "")); assert_eq!( - to_string(f, 1.0e-1, Minus, 80000, false), + to_string(f, 1.0e-1, Minus, 50000, false), format!( - "1.000000000000000055511151231257827021181583404541015625{:0>79945}\ + "1.000000000000000055511151231257827021181583404541015625{:0>49945}\ e-1", "" ) ); assert_eq!( - to_string(f, 1.0e-20, Minus, 80000, false), + to_string(f, 1.0e-20, Minus, 50000, false), format!( "9.999999999999999451532714542095716517295037027873924471077157760\ - 66783064379706047475337982177734375{:0>79901}e-21", + 66783064379706047475337982177734375{:0>49901}e-21", "" ) ); @@ -1150,18 +1150,18 @@ where ); // very large output - assert_eq!(to_string(f, 0.0, Minus, 80000), format!("0.{:0>80000}", "")); - assert_eq!(to_string(f, 1.0e1, Minus, 80000), format!("10.{:0>80000}", "")); - assert_eq!(to_string(f, 1.0e0, Minus, 80000), format!("1.{:0>80000}", "")); + assert_eq!(to_string(f, 0.0, Minus, 50000), format!("0.{:0>50000}", "")); + assert_eq!(to_string(f, 1.0e1, Minus, 50000), format!("10.{:0>50000}", "")); + assert_eq!(to_string(f, 1.0e0, Minus, 50000), format!("1.{:0>50000}", "")); assert_eq!( - to_string(f, 1.0e-1, Minus, 80000), - format!("0.1000000000000000055511151231257827021181583404541015625{:0>79945}", "") + to_string(f, 1.0e-1, Minus, 50000), + format!("0.1000000000000000055511151231257827021181583404541015625{:0>49945}", "") ); assert_eq!( - to_string(f, 1.0e-20, Minus, 80000), + to_string(f, 1.0e-20, Minus, 50000), format!( "0.0000000000000000000099999999999999994515327145420957165172950370\ - 2787392447107715776066783064379706047475337982177734375{:0>79881}", + 2787392447107715776066783064379706047475337982177734375{:0>49881}", "" ) ); diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff similarity index 73% rename from tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-abort.diff rename to tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff index a1be927e1c04..45fc7365d8d6 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff @@ -29,6 +29,16 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { + let mut _22: std::option::Option; + scope 6 (inlined Option::::map::::precision::{closure#0}}>) { + let mut _23: isize; + let _24: u16; + let mut _25: usize; + scope 7 { + scope 8 (inlined Formatter::<'_>::precision::{closure#0}) { + } + } + } } } } @@ -65,9 +75,12 @@ bb3: { StorageLive(_6); - _6 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option); - _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb9]; + StorageLive(_24); + StorageLive(_22); + _22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option); + StorageLive(_23); + _23 = discriminant(_22); + switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10]; } bb4: { @@ -135,7 +148,33 @@ } bb9: { + StorageDead(_23); + StorageDead(_22); + StorageDead(_24); + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10]; + } + + bb10: { unreachable; } + + bb11: { + _6 = const Option::::None; + goto -> bb9; + } + + bb12: { + _24 = move ((_22 as Some).0: u16); + StorageLive(_25); + _25 = copy _24 as usize (IntToInt); + _6 = Option::::Some(move _25); + StorageDead(_25); + goto -> bb9; + } + } + + ALLOC0 (size: 8, align: 4) { + 00 00 00 00 __ __ __ __ │ ....░░░░ } diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff similarity index 73% rename from tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-unwind.diff rename to tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff index 87ab71feb2fa..578d2c2194b0 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff @@ -29,6 +29,16 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { + let mut _22: std::option::Option; + scope 6 (inlined Option::::map::::precision::{closure#0}}>) { + let mut _23: isize; + let _24: u16; + let mut _25: usize; + scope 7 { + scope 8 (inlined Formatter::<'_>::precision::{closure#0}) { + } + } + } } } } @@ -65,9 +75,12 @@ bb3: { StorageLive(_6); - _6 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option); - _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb9]; + StorageLive(_24); + StorageLive(_22); + _22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option); + StorageLive(_23); + _23 = discriminant(_22); + switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10]; } bb4: { @@ -135,7 +148,33 @@ } bb9: { + StorageDead(_23); + StorageDead(_22); + StorageDead(_24); + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10]; + } + + bb10: { unreachable; } + + bb11: { + _6 = const Option::::None; + goto -> bb9; + } + + bb12: { + _24 = move ((_22 as Some).0: u16); + StorageLive(_25); + _25 = copy _24 as usize (IntToInt); + _6 = Option::::Some(move _25); + StorageDead(_25); + goto -> bb9; + } + } + + ALLOC0 (size: 8, align: 4) { + 00 00 00 00 __ __ __ __ │ ....░░░░ } diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff new file mode 100644 index 000000000000..5f0f7d6cc74f --- /dev/null +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff @@ -0,0 +1,180 @@ +- // MIR for `float_to_exponential_common` before GVN ++ // MIR for `float_to_exponential_common` after GVN + + fn float_to_exponential_common(_1: &mut Formatter<'_>, _2: &T, _3: bool) -> Result<(), std::fmt::Error> { + debug fmt => _1; + debug num => _2; + debug upper => _3; + let mut _0: std::result::Result<(), std::fmt::Error>; + let _4: bool; + let mut _6: std::option::Option; + let mut _7: isize; + let mut _9: &mut std::fmt::Formatter<'_>; + let mut _10: &T; + let mut _11: core::num::flt2dec::Sign; + let mut _12: u32; + let mut _13: u32; + let mut _14: usize; + let mut _15: bool; + let mut _16: &mut std::fmt::Formatter<'_>; + let mut _17: &T; + let mut _18: core::num::flt2dec::Sign; + let mut _19: bool; + scope 1 { + debug force_sign => _4; + let _5: core::num::flt2dec::Sign; + scope 2 { + debug sign => _5; + scope 3 { + debug precision => _8; + let _8: usize; + scope 5 (inlined Formatter::<'_>::precision) { + let mut _22: std::option::Option; + scope 6 (inlined Option::::map::::precision::{closure#0}}>) { + let mut _23: isize; + let _24: u16; + let mut _25: usize; + scope 7 { + scope 8 (inlined Formatter::<'_>::precision::{closure#0}) { + } + } + } + } + } + } + } + scope 4 (inlined Formatter::<'_>::sign_plus) { + let mut _20: u32; + let mut _21: u32; + } + + bb0: { + StorageLive(_4); + StorageLive(_20); + StorageLive(_21); + _21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _20 = BitAnd(move _21, const 1_u32); + StorageDead(_21); + _4 = Ne(move _20, const 0_u32); + StorageDead(_20); + StorageLive(_5); + switchInt(copy _4) -> [0: bb2, otherwise: bb1]; + } + + bb1: { +- _5 = MinusPlus; ++ _5 = const MinusPlus; + goto -> bb3; + } + + bb2: { +- _5 = core::num::flt2dec::Sign::Minus; ++ _5 = const core::num::flt2dec::Sign::Minus; + goto -> bb3; + } + + bb3: { + StorageLive(_6); + StorageLive(_24); + StorageLive(_22); + _22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option); + StorageLive(_23); + _23 = discriminant(_22); + switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10]; + } + + bb4: { +- StorageLive(_8); ++ nop; + _8 = copy ((_6 as Some).0: usize); + StorageLive(_9); + _9 = copy _1; + StorageLive(_10); + _10 = copy _2; + StorageLive(_11); + _11 = copy _5; + StorageLive(_12); + StorageLive(_13); + StorageLive(_14); + _14 = copy _8; +- _13 = move _14 as u32 (IntToInt); ++ _13 = copy _8 as u32 (IntToInt); + StorageDead(_14); + _12 = Add(move _13, const 1_u32); + StorageDead(_13); + StorageLive(_15); + _15 = copy _3; +- _0 = float_to_exponential_common_exact::(move _9, move _10, move _11, move _12, move _15) -> [return: bb5, unwind unreachable]; ++ _0 = float_to_exponential_common_exact::(copy _1, copy _2, move _11, move _12, copy _3) -> [return: bb5, unwind unreachable]; + } + + bb5: { + StorageDead(_15); + StorageDead(_12); + StorageDead(_11); + StorageDead(_10); + StorageDead(_9); +- StorageDead(_8); ++ nop; + goto -> bb8; + } + + bb6: { + StorageLive(_16); + _16 = copy _1; + StorageLive(_17); + _17 = copy _2; + StorageLive(_18); + _18 = copy _5; + StorageLive(_19); + _19 = copy _3; +- _0 = float_to_exponential_common_shortest::(move _16, move _17, move _18, move _19) -> [return: bb7, unwind unreachable]; ++ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, move _18, copy _3) -> [return: bb7, unwind unreachable]; + } + + bb7: { + StorageDead(_19); + StorageDead(_18); + StorageDead(_17); + StorageDead(_16); + goto -> bb8; + } + + bb8: { + StorageDead(_5); + StorageDead(_4); + StorageDead(_6); + return; + } + + bb9: { + StorageDead(_23); + StorageDead(_22); + StorageDead(_24); + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10]; + } + + bb10: { + unreachable; + } + + bb11: { + _6 = const Option::::None; + goto -> bb9; + } + + bb12: { + _24 = move ((_22 as Some).0: u16); + StorageLive(_25); + _25 = copy _24 as usize (IntToInt); + _6 = Option::::Some(move _25); + StorageDead(_25); + goto -> bb9; + } + } + + ALLOC0 (size: 16, align: 8) { + 00 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░ + } + diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff new file mode 100644 index 000000000000..10cc46a8b828 --- /dev/null +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff @@ -0,0 +1,180 @@ +- // MIR for `float_to_exponential_common` before GVN ++ // MIR for `float_to_exponential_common` after GVN + + fn float_to_exponential_common(_1: &mut Formatter<'_>, _2: &T, _3: bool) -> Result<(), std::fmt::Error> { + debug fmt => _1; + debug num => _2; + debug upper => _3; + let mut _0: std::result::Result<(), std::fmt::Error>; + let _4: bool; + let mut _6: std::option::Option; + let mut _7: isize; + let mut _9: &mut std::fmt::Formatter<'_>; + let mut _10: &T; + let mut _11: core::num::flt2dec::Sign; + let mut _12: u32; + let mut _13: u32; + let mut _14: usize; + let mut _15: bool; + let mut _16: &mut std::fmt::Formatter<'_>; + let mut _17: &T; + let mut _18: core::num::flt2dec::Sign; + let mut _19: bool; + scope 1 { + debug force_sign => _4; + let _5: core::num::flt2dec::Sign; + scope 2 { + debug sign => _5; + scope 3 { + debug precision => _8; + let _8: usize; + scope 5 (inlined Formatter::<'_>::precision) { + let mut _22: std::option::Option; + scope 6 (inlined Option::::map::::precision::{closure#0}}>) { + let mut _23: isize; + let _24: u16; + let mut _25: usize; + scope 7 { + scope 8 (inlined Formatter::<'_>::precision::{closure#0}) { + } + } + } + } + } + } + } + scope 4 (inlined Formatter::<'_>::sign_plus) { + let mut _20: u32; + let mut _21: u32; + } + + bb0: { + StorageLive(_4); + StorageLive(_20); + StorageLive(_21); + _21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _20 = BitAnd(move _21, const 1_u32); + StorageDead(_21); + _4 = Ne(move _20, const 0_u32); + StorageDead(_20); + StorageLive(_5); + switchInt(copy _4) -> [0: bb2, otherwise: bb1]; + } + + bb1: { +- _5 = MinusPlus; ++ _5 = const MinusPlus; + goto -> bb3; + } + + bb2: { +- _5 = core::num::flt2dec::Sign::Minus; ++ _5 = const core::num::flt2dec::Sign::Minus; + goto -> bb3; + } + + bb3: { + StorageLive(_6); + StorageLive(_24); + StorageLive(_22); + _22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option); + StorageLive(_23); + _23 = discriminant(_22); + switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10]; + } + + bb4: { +- StorageLive(_8); ++ nop; + _8 = copy ((_6 as Some).0: usize); + StorageLive(_9); + _9 = copy _1; + StorageLive(_10); + _10 = copy _2; + StorageLive(_11); + _11 = copy _5; + StorageLive(_12); + StorageLive(_13); + StorageLive(_14); + _14 = copy _8; +- _13 = move _14 as u32 (IntToInt); ++ _13 = copy _8 as u32 (IntToInt); + StorageDead(_14); + _12 = Add(move _13, const 1_u32); + StorageDead(_13); + StorageLive(_15); + _15 = copy _3; +- _0 = float_to_exponential_common_exact::(move _9, move _10, move _11, move _12, move _15) -> [return: bb5, unwind continue]; ++ _0 = float_to_exponential_common_exact::(copy _1, copy _2, move _11, move _12, copy _3) -> [return: bb5, unwind continue]; + } + + bb5: { + StorageDead(_15); + StorageDead(_12); + StorageDead(_11); + StorageDead(_10); + StorageDead(_9); +- StorageDead(_8); ++ nop; + goto -> bb8; + } + + bb6: { + StorageLive(_16); + _16 = copy _1; + StorageLive(_17); + _17 = copy _2; + StorageLive(_18); + _18 = copy _5; + StorageLive(_19); + _19 = copy _3; +- _0 = float_to_exponential_common_shortest::(move _16, move _17, move _18, move _19) -> [return: bb7, unwind continue]; ++ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, move _18, copy _3) -> [return: bb7, unwind continue]; + } + + bb7: { + StorageDead(_19); + StorageDead(_18); + StorageDead(_17); + StorageDead(_16); + goto -> bb8; + } + + bb8: { + StorageDead(_5); + StorageDead(_4); + StorageDead(_6); + return; + } + + bb9: { + StorageDead(_23); + StorageDead(_22); + StorageDead(_24); + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10]; + } + + bb10: { + unreachable; + } + + bb11: { + _6 = const Option::::None; + goto -> bb9; + } + + bb12: { + _24 = move ((_22 as Some).0: u16); + StorageLive(_25); + _25 = copy _24 as usize (IntToInt); + _6 = Option::::Some(move _25); + StorageDead(_25); + goto -> bb9; + } + } + + ALLOC0 (size: 16, align: 8) { + 00 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░ + } + diff --git a/tests/mir-opt/funky_arms.rs b/tests/mir-opt/funky_arms.rs index fc3691049eb4..403a22ebed32 100644 --- a/tests/mir-opt/funky_arms.rs +++ b/tests/mir-opt/funky_arms.rs @@ -1,5 +1,6 @@ // skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY +// EMIT_MIR_FOR_EACH_BIT_WIDTH #![feature(flt2dec)] From ce512c2e4d0dc72f0b7cd17896c2c4e4ea8acfe5 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 12 Feb 2025 18:17:28 +0100 Subject: [PATCH 906/991] Fix rust-analyzer for 16-bit fmt width and precision. --- src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs index 28c824fd31d7..24badc52f25a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs @@ -137,7 +137,7 @@ pub enum FormatAlignment { #[derive(Clone, Debug, PartialEq, Eq)] pub enum FormatCount { /// `{:5}` or `{:.5}` - Literal(usize), + Literal(u16), /// `{:.*}`, `{:.5$}`, or `{:a$}`, etc. Argument(FormatArgPosition), } From 7677567e54285312c133b135821409f8cf3fa636 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 28 Feb 2025 12:49:20 +0100 Subject: [PATCH 907/991] Remove unnecessary semicolon. --- library/core/src/fmt/rt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index cb908adc1cba..a45875ba57c3 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -157,7 +157,7 @@ impl Argument<'_> { pub const fn from_usize(x: &usize) -> Argument<'_> { if *x > u16::MAX as usize { panic!("Formatting argument out of range"); - }; + } Argument { ty: ArgumentType::Count(*x as u16) } } From 2647cf17e75346ed50042a1ebe28aa3137a5544e Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 28 Feb 2025 12:49:28 +0100 Subject: [PATCH 908/991] Add #[track_caller] to from_usize. --- library/core/src/fmt/rt.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index a45875ba57c3..080fc6ddfc9b 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -154,6 +154,7 @@ impl Argument<'_> { Self::new(x, UpperExp::fmt) } #[inline] + #[track_caller] pub const fn from_usize(x: &usize) -> Argument<'_> { if *x > u16::MAX as usize { panic!("Formatting argument out of range"); From 53237c86564deb04def176251a58bd967f941ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 5 Mar 2025 11:00:56 +0100 Subject: [PATCH 909/991] Refactor GCC compilation --- src/bootstrap/src/core/build_steps/gcc.rs | 209 +++++++++++----------- 1 file changed, 108 insertions(+), 101 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 70789fbbeeba..1382d5b07f91 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -14,13 +14,68 @@ use std::sync::OnceLock; use build_helper::ci::CiEnv; -use crate::Kind; -use crate::core::builder::{Builder, Cargo, RunConfig, ShouldRun, Step}; +use crate::Config; +use crate::core::builder::{Builder, Cargo, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash}; use crate::utils::exec::command; use crate::utils::helpers::{self, t}; +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct Gcc { + pub target: TargetSelection, +} + +#[derive(Clone)] +pub struct GccOutput { + pub libgccjit: PathBuf, +} + +impl Step for Gcc { + type Output = GccOutput; + + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/gcc").alias("gcc") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Gcc { target: run.target }); + } + + /// Compile GCC (specifically `libgccjit`) for `target`. + fn run(self, builder: &Builder<'_>) -> Self::Output { + let target = self.target; + + // If GCC has already been built, we avoid building it again. + let metadata = match get_gcc_build_status(builder, target) { + GccBuildStatus::AlreadyBuilt(path) => return GccOutput { libgccjit: path }, + GccBuildStatus::ShouldBuild(m) => m, + }; + + let _guard = builder.msg_unstaged(Kind::Build, "GCC", target); + t!(metadata.stamp.remove()); + let _time = helpers::timeit(builder); + + let libgccjit_path = libgccjit_built_path(&metadata.install_dir); + if builder.config.dry_run() { + return GccOutput { libgccjit: libgccjit_path }; + } + + build_gcc(&metadata, builder, target); + + let lib_alias = metadata.install_dir.join("lib/libgccjit.so.0"); + if !lib_alias.exists() { + t!(builder.symlink_file(&libgccjit_path, lib_alias)); + } + + t!(metadata.stamp.write()); + + GccOutput { libgccjit: libgccjit_path } + } +} + pub struct Meta { stamp: BuildStamp, out_dir: PathBuf, @@ -38,7 +93,7 @@ pub enum GccBuildStatus { /// /// It's used to avoid busting caches during x.py check -- if we've already built /// GCC, it's fine for us to not try to avoid doing so. -pub fn prebuilt_gcc_config(builder: &Builder<'_>, target: TargetSelection) -> GccBuildStatus { +pub fn get_gcc_build_status(builder: &Builder<'_>, target: TargetSelection) -> GccBuildStatus { // Initialize the gcc submodule if not initialized already. builder.config.update_submodule("src/gcc"); @@ -87,104 +142,65 @@ fn libgccjit_built_path(install_dir: &Path) -> PathBuf { install_dir.join("lib/libgccjit.so") } -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct Gcc { - pub target: TargetSelection, -} +fn build_gcc(metadata: &Meta, builder: &Builder, target: TargetSelection) { + let Meta { stamp: _, out_dir, install_dir, root } = metadata; -#[derive(Clone)] -pub struct GccOutput { - pub libgccjit: PathBuf, -} + t!(fs::create_dir_all(out_dir)); + t!(fs::create_dir_all(install_dir)); -impl Step for Gcc { - type Output = GccOutput; - - const ONLY_HOSTS: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/gcc").alias("gcc") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Gcc { target: run.target }); - } - - /// Compile GCC (specifically `libgccjit`) for `target`. - fn run(self, builder: &Builder<'_>) -> Self::Output { - let target = self.target; - - // If GCC has already been built, we avoid building it again. - let Meta { stamp, out_dir, install_dir, root } = match prebuilt_gcc_config(builder, target) - { - GccBuildStatus::AlreadyBuilt(path) => return GccOutput { libgccjit: path }, - GccBuildStatus::ShouldBuild(m) => m, - }; - - let _guard = builder.msg_unstaged(Kind::Build, "GCC", target); - t!(stamp.remove()); - let _time = helpers::timeit(builder); - t!(fs::create_dir_all(&out_dir)); - t!(fs::create_dir_all(&install_dir)); - - let libgccjit_path = libgccjit_built_path(&install_dir); - if builder.config.dry_run() { - return GccOutput { libgccjit: libgccjit_path }; + // GCC creates files (e.g. symlinks to the downloaded dependencies) + // in the source directory, which does not work with our CI setup, where we mount + // source directories as read-only on Linux. + // Therefore, as a part of the build in CI, we first copy the whole source directory + // to the build directory, and perform the build from there. + let src_dir = if CiEnv::is_ci() { + let src_dir = builder.gcc_out(target).join("src"); + if src_dir.exists() { + builder.remove_dir(&src_dir); } + builder.create_dir(&src_dir); + builder.cp_link_r(root, &src_dir); + src_dir + } else { + root.clone() + }; - // GCC creates files (e.g. symlinks to the downloaded dependencies) - // in the source directory, which does not work with our CI setup, where we mount - // source directories as read-only on Linux. - // Therefore, as a part of the build in CI, we first copy the whole source directory - // to the build directory, and perform the build from there. - let src_dir = if CiEnv::is_ci() { - let src_dir = builder.gcc_out(target).join("src"); - if src_dir.exists() { - builder.remove_dir(&src_dir); - } - builder.create_dir(&src_dir); - builder.cp_link_r(&root, &src_dir); - src_dir - } else { - root - }; + command(src_dir.join("contrib/download_prerequisites")).current_dir(&src_dir).run(builder); + let mut configure_cmd = command(src_dir.join("configure")); + configure_cmd + .current_dir(out_dir) + // On CI, we compile GCC with Clang. + // The -Wno-everything flag is needed to make GCC compile with Clang 19. + // `-g -O2` are the default flags that are otherwise used by Make. + // FIXME(kobzol): change the flags once we have [gcc] configuration in config.toml. + .env("CXXFLAGS", "-Wno-everything -g -O2") + .env("CFLAGS", "-Wno-everything -g -O2") + .arg("--enable-host-shared") + .arg("--enable-languages=jit") + .arg("--enable-checking=release") + .arg("--disable-bootstrap") + .arg("--disable-multilib") + .arg(format!("--prefix={}", install_dir.display())); + let cc = builder.build.cc(target).display().to_string(); + let cc = builder + .build + .config + .ccache + .as_ref() + .map_or_else(|| cc.clone(), |ccache| format!("{ccache} {cc}")); + configure_cmd.env("CC", cc); - command(src_dir.join("contrib/download_prerequisites")).current_dir(&src_dir).run(builder); - let mut configure_cmd = command(src_dir.join("configure")); - configure_cmd - .current_dir(&out_dir) - // On CI, we compile GCC with Clang. - // The -Wno-everything flag is needed to make GCC compile with Clang 19. - // `-g -O2` are the default flags that are otherwise used by Make. - // FIXME(kobzol): change the flags once we have [gcc] configuration in config.toml. - .env("CXXFLAGS", "-Wno-everything -g -O2") - .env("CFLAGS", "-Wno-everything -g -O2") - .arg("--enable-host-shared") - .arg("--enable-languages=jit") - .arg("--enable-checking=release") - .arg("--disable-bootstrap") - .arg("--disable-multilib") - .arg(format!("--prefix={}", install_dir.display())); - let cc = builder.build.cc(target).display().to_string(); - let cc = builder + if let Ok(ref cxx) = builder.build.cxx(target) { + let cxx = cxx.display().to_string(); + let cxx = builder .build .config .ccache .as_ref() - .map_or_else(|| cc.clone(), |ccache| format!("{ccache} {cc}")); - configure_cmd.env("CC", cc); - - if let Ok(ref cxx) = builder.build.cxx(target) { - let cxx = cxx.display().to_string(); - let cxx = builder - .build - .config - .ccache - .as_ref() - .map_or_else(|| cxx.clone(), |ccache| format!("{ccache} {cxx}")); - configure_cmd.env("CXX", cxx); - } - configure_cmd.run(builder); + .map_or_else(|| cxx.clone(), |ccache| format!("{ccache} {cxx}")); + configure_cmd.env("CXX", cxx); + } + configure_cmd.run(builder); command("make") .current_dir(&out_dir) @@ -196,15 +212,6 @@ impl Step for Gcc { .arg("--silent") .arg("install") .run_capture_stdout(builder); - - let lib_alias = install_dir.join("lib/libgccjit.so.0"); - if !lib_alias.exists() { - t!(builder.symlink_file(&libgccjit_path, lib_alias)); - } - - t!(stamp.write()); - - GccOutput { libgccjit: libgccjit_path } } } From 009aba0aa3c3e97df5d27dbb722363888c972534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 5 Mar 2025 10:16:22 +0100 Subject: [PATCH 910/991] Add `gcc` bootstrap config section --- config.example.toml | 5 +++++ src/bootstrap/src/core/config/config.rs | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/config.example.toml b/config.example.toml index ac5e491b4b52..2dddb0099c13 100644 --- a/config.example.toml +++ b/config.example.toml @@ -163,6 +163,11 @@ # Custom CMake defines to set when building LLVM. #build-config = {} +# ============================================================================= +# Tweaking how GCC is compiled +# ============================================================================= +[gcc] + # ============================================================================= # General build configuration options # ============================================================================= diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index ac24da9f86b2..7fda61b70f9d 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -676,6 +676,7 @@ pub(crate) struct TomlConfig { build: Option, install: Option, llvm: Option, + gcc: Option, rust: Option, target: Option>, dist: Option, @@ -710,7 +711,7 @@ trait Merge { impl Merge for TomlConfig { fn merge( &mut self, - TomlConfig { build, install, llvm, rust, dist, target, profile, change_id }: Self, + TomlConfig { build, install, llvm, gcc, rust, dist, target, profile, change_id }: Self, replace: ReplaceOpt, ) { fn do_merge(x: &mut Option, y: Option, replace: ReplaceOpt) { @@ -729,6 +730,7 @@ impl Merge for TomlConfig { do_merge(&mut self.build, build, replace); do_merge(&mut self.install, install, replace); do_merge(&mut self.llvm, llvm, replace); + do_merge(&mut self.gcc, gcc, replace); do_merge(&mut self.rust, rust, replace); do_merge(&mut self.dist, dist, replace); @@ -995,6 +997,11 @@ define_config! { } } +define_config! { + /// TOML representation of how the GCC build is configured. + struct Gcc {} +} + define_config! { struct Dist { sign_folder: Option = "sign-folder", From c68a5ec6c36b9ea955968d8fcbf1c65c647a14c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 5 Mar 2025 11:26:16 +0100 Subject: [PATCH 911/991] Add `[gcc] download-ci-gcc` option --- config.example.toml | 5 +++++ src/bootstrap/src/core/config/config.rs | 28 ++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/config.example.toml b/config.example.toml index 2dddb0099c13..c3d2ad094ceb 100644 --- a/config.example.toml +++ b/config.example.toml @@ -167,6 +167,11 @@ # Tweaking how GCC is compiled # ============================================================================= [gcc] +# Download GCC from CI instead of building it locally. +# Note that this will attempt to download GCC even if there are local +# modifications to the `src/gcc` submodule. +# Currently, this is only supported for the `x86_64-unknown-linux-gnu` target. +# download-ci-gcc = false # ============================================================================= # General build configuration options diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 7fda61b70f9d..e73659773ab2 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -171,6 +171,17 @@ impl LldMode { } } +/// Determines how will GCC be provided. +#[derive(Default, Clone)] +pub enum GccCiMode { + /// Build GCC from the local `src/gcc` submodule. + #[default] + BuildLocally, + /// Try to download GCC from CI. + /// If it is not available on CI, it will be built locally instead. + DownloadFromCi, +} + /// Global configuration for the entire build and/or bootstrap. /// /// This structure is parsed from `config.toml`, and some of the fields are inferred from `git` or build-time parameters. @@ -283,6 +294,9 @@ pub struct Config { pub llvm_ldflags: Option, pub llvm_use_libcxx: bool, + // gcc codegen options + pub gcc_ci_mode: GccCiMode, + // rust codegen options pub rust_optimize: RustOptimize, pub rust_codegen_units: Option, @@ -999,7 +1013,9 @@ define_config! { define_config! { /// TOML representation of how the GCC build is configured. - struct Gcc {} + struct Gcc { + download_ci_gcc: Option = "download-ci-gcc", + } } define_config! { @@ -2143,6 +2159,16 @@ impl Config { config.llvm_from_ci = config.parse_download_ci_llvm(None, false); } + if let Some(gcc) = toml.gcc { + config.gcc_ci_mode = match gcc.download_ci_gcc { + Some(value) => match value { + true => GccCiMode::DownloadFromCi, + false => GccCiMode::BuildLocally, + }, + None => GccCiMode::default(), + }; + } + if let Some(t) = toml.target { for (triple, cfg) in t { let mut target = Target::from_triple(&triple); From 3de10b0756bc34a6bf98eb0be5c89b3806466bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 5 Mar 2025 10:35:16 +0100 Subject: [PATCH 912/991] Add `download-ci-gcc-stamp` file --- src/bootstrap/download-ci-gcc-stamp | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/bootstrap/download-ci-gcc-stamp diff --git a/src/bootstrap/download-ci-gcc-stamp b/src/bootstrap/download-ci-gcc-stamp new file mode 100644 index 000000000000..bbe26afc9526 --- /dev/null +++ b/src/bootstrap/download-ci-gcc-stamp @@ -0,0 +1,4 @@ +Change this file to make users of the `download-ci-gcc` configuration download +a new version of GCC from CI, even if the GCC submodule hasn’t changed. + +Last change is for: https://github.com/rust-lang/rust/pull/138051 From bc6302ca6d452e54365bf7a724bf96beffd7280e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 5 Mar 2025 11:38:05 +0100 Subject: [PATCH 913/991] Implement downloading GCC from CI --- src/bootstrap/src/core/build_steps/gcc.rs | 96 ++++++++++++++++++----- src/bootstrap/src/core/download.rs | 28 +++++++ 2 files changed, 104 insertions(+), 20 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 1382d5b07f91..7e1ec39659a3 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -13,10 +13,11 @@ use std::path::{Path, PathBuf}; use std::sync::OnceLock; use build_helper::ci::CiEnv; +use build_helper::git::get_closest_merge_commit; use crate::Config; use crate::core::builder::{Builder, Cargo, Kind, RunConfig, ShouldRun, Step}; -use crate::core::config::TargetSelection; +use crate::core::config::{GccCiMode, TargetSelection}; use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash}; use crate::utils::exec::command; use crate::utils::helpers::{self, t}; @@ -89,17 +90,39 @@ pub enum GccBuildStatus { ShouldBuild(Meta), } -/// This returns whether we've already previously built GCC. +/// Tries to download GCC from CI if it is enabled and GCC artifacts +/// are available for the given target. +/// Returns a path to the libgccjit.so file. +fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option { + // Try to download GCC from CI if configured and available + if !matches!(builder.config.gcc_ci_mode, GccCiMode::DownloadFromCi) { + return None; + } + if target != "x86_64-unknown-linux-gnu" { + eprintln!("GCC CI download is only available for the `x86_64-unknown-linux-gnu` target"); + return None; + } + let sha = + detect_gcc_sha(&builder.config, builder.config.rust_info.is_managed_git_subrepository()); + let root = ci_gcc_root(&builder.config); + let gcc_stamp = BuildStamp::new(&root).with_prefix("gcc").add_stamp(&sha); + if !gcc_stamp.is_up_to_date() && !builder.config.dry_run() { + builder.config.download_ci_gcc(&sha, &root); + t!(gcc_stamp.write()); + } + // FIXME: put libgccjit.so into a lib directory in dist::Gcc + Some(root.join("libgccjit.so")) +} + +/// This returns information about whether GCC should be built or if it's already built. +/// It transparently handles downloading GCC from CI if needed. /// /// It's used to avoid busting caches during x.py check -- if we've already built /// GCC, it's fine for us to not try to avoid doing so. pub fn get_gcc_build_status(builder: &Builder<'_>, target: TargetSelection) -> GccBuildStatus { - // Initialize the gcc submodule if not initialized already. - builder.config.update_submodule("src/gcc"); - - let root = builder.src.join("src/gcc"); - let out_dir = builder.gcc_out(target).join("build"); - let install_dir = builder.gcc_out(target).join("install"); + if let Some(path) = try_download_gcc(builder, target) { + return GccBuildStatus::AlreadyBuilt(path); + } static STAMP_HASH_MEMO: OnceLock = OnceLock::new(); let smart_stamp_hash = STAMP_HASH_MEMO.get_or_init(|| { @@ -110,6 +133,13 @@ pub fn get_gcc_build_status(builder: &Builder<'_>, target: TargetSelection) -> G ) }); + // Initialize the gcc submodule if not initialized already. + builder.config.update_submodule("src/gcc"); + + let root = builder.src.join("src/gcc"); + let out_dir = builder.gcc_out(target).join("build"); + let install_dir = builder.gcc_out(target).join("install"); + let stamp = BuildStamp::new(&out_dir).with_prefix("gcc").add_stamp(smart_stamp_hash); if stamp.is_up_to_date() { @@ -142,7 +172,7 @@ fn libgccjit_built_path(install_dir: &Path) -> PathBuf { install_dir.join("lib/libgccjit.so") } -fn build_gcc(metadata: &Meta, builder: &Builder, target: TargetSelection) { +fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) { let Meta { stamp: _, out_dir, install_dir, root } = metadata; t!(fs::create_dir_all(out_dir)); @@ -202,17 +232,12 @@ fn build_gcc(metadata: &Meta, builder: &Builder, target: TargetSelection) { } configure_cmd.run(builder); - command("make") - .current_dir(&out_dir) - .arg("--silent") - .arg(format!("-j{}", builder.jobs())) - .run_capture_stdout(builder); - command("make") - .current_dir(&out_dir) - .arg("--silent") - .arg("install") - .run_capture_stdout(builder); - } + command("make") + .current_dir(out_dir) + .arg("--silent") + .arg(format!("-j{}", builder.jobs())) + .run_capture_stdout(builder); + command("make").current_dir(out_dir).arg("--silent").arg("install").run_capture_stdout(builder); } /// Configures a Cargo invocation so that it can build the GCC codegen backend. @@ -220,3 +245,34 @@ pub fn add_cg_gcc_cargo_flags(cargo: &mut Cargo, gcc: &GccOutput) { // Add the path to libgccjit.so to the linker search paths. cargo.rustflag(&format!("-L{}", gcc.libgccjit.parent().unwrap().to_str().unwrap())); } + +/// The absolute path to the downloaded GCC artifacts. +fn ci_gcc_root(config: &Config) -> PathBuf { + config.out.join(config.build).join("ci-gcc") +} + +/// This retrieves the GCC sha we *want* to use, according to git history. +fn detect_gcc_sha(config: &Config, is_git: bool) -> String { + let gcc_sha = if is_git { + get_closest_merge_commit( + Some(&config.src), + &config.git_config(), + &[config.src.join("src/gcc"), config.src.join("src/bootstrap/download-ci-gcc-stamp")], + ) + .unwrap() + } else if let Some(info) = crate::utils::channel::read_commit_info_file(&config.src) { + info.sha.trim().to_owned() + } else { + "".to_owned() + }; + + if gcc_sha.is_empty() { + eprintln!("error: could not find commit hash for downloading GCC"); + eprintln!("HELP: maybe your repository history is too shallow?"); + eprintln!("HELP: consider disabling `download-ci-gcc`"); + eprintln!("HELP: or fetch enough history to include one upstream commit"); + panic!(); + } + + gcc_sha +} diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index c477bdb829a9..95feb41ffd0c 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -826,6 +826,34 @@ download-rustc = false let llvm_root = self.ci_llvm_root(); self.unpack(&tarball, &llvm_root, "rust-dev"); } + + pub fn download_ci_gcc(&self, gcc_sha: &str, root_dir: &Path) { + let cache_prefix = format!("gcc-{gcc_sha}"); + let cache_dst = + self.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| self.out.join("cache")); + + let gcc_cache = cache_dst.join(cache_prefix); + if !gcc_cache.exists() { + t!(fs::create_dir_all(&gcc_cache)); + } + let base = &self.stage0_metadata.config.artifacts_server; + let filename = format!("gcc-nightly-{}.tar.xz", self.build.triple); + let tarball = gcc_cache.join(&filename); + if !tarball.exists() { + let help_on_error = "ERROR: failed to download gcc from ci + + HELP: There could be two reasons behind this: + 1) The host triple is not supported for `download-ci-gcc`. + 2) Old builds get deleted after a certain time. + HELP: In either case, disable `download-ci-gcc` in your config.toml: + + [gcc] + download-ci-gcc = false + "; + self.download_file(&format!("{base}/{gcc_sha}/{filename}"), &tarball, help_on_error); + } + self.unpack(&tarball, root_dir, "gcc"); + } } fn path_is_dylib(path: &Path) -> bool { From 2b1b09ce0e0143ccf84f91b0691b52e2c8ecb6c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 5 Mar 2025 11:39:43 +0100 Subject: [PATCH 914/991] Add change tracker entry --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 425ffdccad57..ec27109c117a 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -370,4 +370,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "The rust.description option has moved to build.description and rust.description is now deprecated.", }, + ChangeInfo { + change_id: 138051, + severity: ChangeSeverity::Info, + summary: "There is now a new `gcc` config section that can be used to download GCC from CI using `gcc.download-ci-gcc = true`", + }, ]; From dcc2b307dc3b4807fb9a1fb2ef8c26396bb8649b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Mar 2025 11:29:04 +0100 Subject: [PATCH 915/991] Add triagebot entry for GCC modifications --- triagebot.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index e4231b2966ba..91d0edbe7628 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -958,6 +958,9 @@ If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/util [mentions."src/bootstrap/src/core/build_steps/llvm.rs"] message = "This PR changes how LLVM is built. Consider updating src/bootstrap/download-ci-llvm-stamp." +[mentions."src/bootstrap/src/core/build_steps/gcc.rs"] +message = "This PR changes how GCC is built. Consider updating src/bootstrap/download-ci-gcc-stamp." + [mentions."tests/crashes"] message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the corresponding `ui` subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge." From 7ca7675b7857c10851f0b2a18b44b52abaab607c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 27 Feb 2025 17:45:53 +0100 Subject: [PATCH 916/991] Make all keys explicit in citool Just to avoid surprises, the amount of used keys is not large. --- src/ci/citool/src/main.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 52e7638d98bd..346d7f7cf662 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -33,9 +33,12 @@ struct Job { /// Should the job be only executed on a specific channel? #[serde(default)] only_on_channel: Option, - /// Rest of attributes that will be passed through to GitHub actions - #[serde(flatten)] - extra_keys: BTreeMap, + /// Do not cancel the whole workflow if this job fails. + #[serde(default)] + continue_on_error: Option, + /// Free additional disk space in the job, by removing unused packages. + #[serde(default)] + free_disk: Option, } impl Job { @@ -105,8 +108,10 @@ struct GithubActionsJob { full_name: String, os: String, env: BTreeMap, - #[serde(flatten)] - extra_keys: BTreeMap, + #[serde(skip_serializing_if = "Option::is_none")] + continue_on_error: Option, + #[serde(skip_serializing_if = "Option::is_none")] + free_disk: Option, } /// Type of workflow that is being executed on CI @@ -240,7 +245,8 @@ fn calculate_jobs( full_name, os: job.os, env, - extra_keys: yaml_map_to_json(&job.extra_keys), + free_disk: job.free_disk, + continue_on_error: job.continue_on_error, } }) .collect(); From 0412507c52d074e20dc47501078d24c4ab51294f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Mar 2025 13:14:50 +0100 Subject: [PATCH 917/991] Move job handling to a separate module --- src/ci/citool/src/jobs.rs | 233 +++++++++++++++++++++++++++++ src/ci/citool/src/main.rs | 237 +----------------------------- src/ci/citool/src/merge_report.rs | 2 +- 3 files changed, 242 insertions(+), 230 deletions(-) create mode 100644 src/ci/citool/src/jobs.rs diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs new file mode 100644 index 000000000000..8103e9b93446 --- /dev/null +++ b/src/ci/citool/src/jobs.rs @@ -0,0 +1,233 @@ +use crate::{GitHubContext, utils}; +use serde_yaml::Value; +use std::collections::BTreeMap; +use std::path::Path; + +use serde_yaml::Value; + +use crate::GitHubContext; + +/// Representation of a job loaded from the `src/ci/github-actions/jobs.yml` file. +#[derive(serde::Deserialize, Debug, Clone)] +pub struct Job { + /// Name of the job, e.g. mingw-check + pub name: String, + /// GitHub runner on which the job should be executed + pub os: String, + pub env: BTreeMap, + /// Should the job be only executed on a specific channel? + #[serde(default)] + pub only_on_channel: Option, + /// Do not cancel the whole workflow if this job fails. + #[serde(default)] + pub continue_on_error: Option, + /// Free additional disk space in the job, by removing unused packages. + #[serde(default)] + pub free_disk: Option, +} + +impl Job { + /// By default, the Docker image of a job is based on its name. + /// However, it can be overridden by its IMAGE environment variable. + pub fn image(&self) -> String { + self.env + .get("IMAGE") + .map(|v| v.as_str().expect("IMAGE value should be a string").to_string()) + .unwrap_or_else(|| self.name.clone()) + } + + fn is_linux(&self) -> bool { + self.os.contains("ubuntu") + } +} + +#[derive(serde::Deserialize, Debug)] +struct JobEnvironments { + #[serde(rename = "pr")] + pr_env: BTreeMap, + #[serde(rename = "try")] + try_env: BTreeMap, + #[serde(rename = "auto")] + auto_env: BTreeMap, +} + +#[derive(serde::Deserialize, Debug)] +pub struct JobDatabase { + #[serde(rename = "pr")] + pub pr_jobs: Vec, + #[serde(rename = "try")] + pub try_jobs: Vec, + #[serde(rename = "auto")] + pub auto_jobs: Vec, + + /// Shared environments for the individual run types. + envs: JobEnvironments, +} + +impl JobDatabase { + fn find_auto_job_by_name(&self, name: &str) -> Option { + self.auto_jobs.iter().find(|j| j.name == name).cloned() + } +} + +pub fn load_job_db(path: &Path) -> anyhow::Result { + let db = utils::read_to_string(path)?; + let mut db: Value = serde_yaml::from_str(&db)?; + + // We need to expand merge keys (<<), because serde_yaml can't deal with them + // `apply_merge` only applies the merge once, so do it a few times to unwrap nested merges. + db.apply_merge()?; + db.apply_merge()?; + + let db: JobDatabase = serde_yaml::from_value(db)?; + Ok(db) +} + +/// Representation of a job outputted to a GitHub Actions workflow. +#[derive(serde::Serialize, Debug)] +struct GithubActionsJob { + /// The main identifier of the job, used by CI scripts to determine what should be executed. + name: String, + /// Helper label displayed in GitHub Actions interface, containing the job name and a run type + /// prefix (PR/try/auto). + full_name: String, + os: String, + env: BTreeMap, + #[serde(skip_serializing_if = "Option::is_none")] + continue_on_error: Option, + #[serde(skip_serializing_if = "Option::is_none")] + free_disk: Option, +} + +/// Skip CI jobs that are not supposed to be executed on the given `channel`. +fn skip_jobs(jobs: Vec, channel: &str) -> Vec { + jobs.into_iter() + .filter(|job| { + job.only_on_channel.is_none() || job.only_on_channel.as_deref() == Some(channel) + }) + .collect() +} + +/// Type of workflow that is being executed on CI +#[derive(Debug)] +pub enum RunType { + /// Workflows that run after a push to a PR branch + PullRequest, + /// Try run started with @bors try + TryJob { custom_jobs: Option> }, + /// Merge attempt workflow + AutoJob, +} + +/// Maximum number of custom try jobs that can be requested in a single +/// `@bors try` request. +const MAX_TRY_JOBS_COUNT: usize = 20; + +fn calculate_jobs( + run_type: &RunType, + db: &JobDatabase, + channel: &str, +) -> anyhow::Result> { + let (jobs, prefix, base_env) = match run_type { + RunType::PullRequest => (db.pr_jobs.clone(), "PR", &db.envs.pr_env), + RunType::TryJob { custom_jobs } => { + let jobs = if let Some(custom_jobs) = custom_jobs { + if custom_jobs.len() > MAX_TRY_JOBS_COUNT { + return Err(anyhow::anyhow!( + "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs", + custom_jobs.len() + )); + } + + let mut jobs = vec![]; + let mut unknown_jobs = vec![]; + for custom_job in custom_jobs { + if let Some(job) = db.find_auto_job_by_name(custom_job) { + jobs.push(job); + } else { + unknown_jobs.push(custom_job.clone()); + } + } + if !unknown_jobs.is_empty() { + return Err(anyhow::anyhow!( + "Custom job(s) `{}` not found in auto jobs", + unknown_jobs.join(", ") + )); + } + jobs + } else { + db.try_jobs.clone() + }; + (jobs, "try", &db.envs.try_env) + } + RunType::AutoJob => (db.auto_jobs.clone(), "auto", &db.envs.auto_env), + }; + let jobs = skip_jobs(jobs, channel); + let jobs = jobs + .into_iter() + .map(|job| { + let mut env: BTreeMap = crate::yaml_map_to_json(base_env); + env.extend(crate::yaml_map_to_json(&job.env)); + let full_name = format!("{prefix} - {}", job.name); + + GithubActionsJob { + name: job.name, + full_name, + os: job.os, + env, + continue_on_error: job.continue_on_error, + free_disk: job.free_disk, + } + }) + .collect(); + + Ok(jobs) +} + +pub fn calculate_job_matrix( + db: JobDatabase, + gh_ctx: GitHubContext, + channel: &str, +) -> anyhow::Result<()> { + let run_type = gh_ctx.get_run_type().ok_or_else(|| { + anyhow::anyhow!("Cannot determine the type of workflow that is being executed") + })?; + eprintln!("Run type: {run_type:?}"); + + let jobs = calculate_jobs(&run_type, &db, channel)?; + if jobs.is_empty() { + return Err(anyhow::anyhow!("Computed job list is empty")); + } + + let run_type = match run_type { + RunType::PullRequest => "pr", + RunType::TryJob { .. } => "try", + RunType::AutoJob => "auto", + }; + + eprintln!("Output"); + eprintln!("jobs={jobs:?}"); + eprintln!("run_type={run_type}"); + println!("jobs={}", serde_json::to_string(&jobs)?); + println!("run_type={run_type}"); + + Ok(()) +} + +pub fn find_linux_job<'a>(jobs: &'a [Job], name: &str) -> anyhow::Result<&'a Job> { + let Some(job) = jobs.iter().find(|j| j.name == name) else { + let available_jobs: Vec<&Job> = jobs.iter().filter(|j| j.is_linux()).collect(); + let mut available_jobs = + available_jobs.iter().map(|j| j.name.to_string()).collect::>(); + available_jobs.sort(); + return Err(anyhow::anyhow!( + "Job {name} not found. The following jobs are available:\n{}", + available_jobs.join(", ") + )); + }; + if !job.is_linux() { + return Err(anyhow::anyhow!("Only Linux jobs can be executed locally")); + } + + Ok(job) +} diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 346d7f7cf662..8765922d089a 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -1,5 +1,6 @@ mod cpu_usage; mod datadog; +mod jobs; mod merge_report; mod metrics; mod utils; @@ -10,10 +11,12 @@ use std::process::Command; use anyhow::Context; use clap::Parser; +use jobs::JobDatabase; use serde_yaml::Value; use crate::cpu_usage::load_cpu_usage; use crate::datadog::upload_datadog_metric; +use crate::jobs::RunType; use crate::merge_report::post_merge_report; use crate::metrics::postprocess_metrics; use crate::utils::load_env_var; @@ -22,109 +25,6 @@ const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker"); const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml"); -/// Representation of a job loaded from the `src/ci/github-actions/jobs.yml` file. -#[derive(serde::Deserialize, Debug, Clone)] -struct Job { - /// Name of the job, e.g. mingw-check - name: String, - /// GitHub runner on which the job should be executed - os: String, - env: BTreeMap, - /// Should the job be only executed on a specific channel? - #[serde(default)] - only_on_channel: Option, - /// Do not cancel the whole workflow if this job fails. - #[serde(default)] - continue_on_error: Option, - /// Free additional disk space in the job, by removing unused packages. - #[serde(default)] - free_disk: Option, -} - -impl Job { - fn is_linux(&self) -> bool { - self.os.contains("ubuntu") - } - - /// By default, the Docker image of a job is based on its name. - /// However, it can be overridden by its IMAGE environment variable. - fn image(&self) -> String { - self.env - .get("IMAGE") - .map(|v| v.as_str().expect("IMAGE value should be a string").to_string()) - .unwrap_or_else(|| self.name.clone()) - } -} - -#[derive(serde::Deserialize, Debug)] -struct JobEnvironments { - #[serde(rename = "pr")] - pr_env: BTreeMap, - #[serde(rename = "try")] - try_env: BTreeMap, - #[serde(rename = "auto")] - auto_env: BTreeMap, -} - -#[derive(serde::Deserialize, Debug)] -struct JobDatabase { - #[serde(rename = "pr")] - pr_jobs: Vec, - #[serde(rename = "try")] - try_jobs: Vec, - #[serde(rename = "auto")] - auto_jobs: Vec, - - /// Shared environments for the individual run types. - envs: JobEnvironments, -} - -impl JobDatabase { - fn find_auto_job_by_name(&self, name: &str) -> Option { - self.auto_jobs.iter().find(|j| j.name == name).cloned() - } -} - -fn load_job_db(path: &Path) -> anyhow::Result { - let db = utils::read_to_string(path)?; - let mut db: Value = serde_yaml::from_str(&db)?; - - // We need to expand merge keys (<<), because serde_yaml can't deal with them - // `apply_merge` only applies the merge once, so do it a few times to unwrap nested merges. - db.apply_merge()?; - db.apply_merge()?; - - let db: JobDatabase = serde_yaml::from_value(db)?; - Ok(db) -} - -/// Representation of a job outputted to a GitHub Actions workflow. -#[derive(serde::Serialize, Debug)] -struct GithubActionsJob { - /// The main identifier of the job, used by CI scripts to determine what should be executed. - name: String, - /// Helper label displayed in GitHub Actions interface, containing the job name and a run type - /// prefix (PR/try/auto). - full_name: String, - os: String, - env: BTreeMap, - #[serde(skip_serializing_if = "Option::is_none")] - continue_on_error: Option, - #[serde(skip_serializing_if = "Option::is_none")] - free_disk: Option, -} - -/// Type of workflow that is being executed on CI -#[derive(Debug)] -enum RunType { - /// Workflows that run after a push to a PR branch - PullRequest, - /// Try run started with @bors try - TryJob { custom_jobs: Option> }, - /// Merge attempt workflow - AutoJob, -} - struct GitHubContext { event_name: String, branch_ref: String, @@ -169,15 +69,6 @@ fn load_github_ctx() -> anyhow::Result { Ok(GitHubContext { event_name, branch_ref: load_env_var("GITHUB_REF")?, commit_message }) } -/// Skip CI jobs that are not supposed to be executed on the given `channel`. -fn skip_jobs(jobs: Vec, channel: &str) -> Vec { - jobs.into_iter() - .filter(|job| { - job.only_on_channel.is_none() || job.only_on_channel.as_deref() == Some(channel) - }) - .collect() -} - fn yaml_map_to_json(map: &BTreeMap) -> BTreeMap { map.into_iter() .map(|(key, value)| { @@ -189,125 +80,13 @@ fn yaml_map_to_json(map: &BTreeMap) -> BTreeMap anyhow::Result> { - let (jobs, prefix, base_env) = match run_type { - RunType::PullRequest => (db.pr_jobs.clone(), "PR", &db.envs.pr_env), - RunType::TryJob { custom_jobs } => { - let jobs = if let Some(custom_jobs) = custom_jobs { - if custom_jobs.len() > MAX_TRY_JOBS_COUNT { - return Err(anyhow::anyhow!( - "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs", - custom_jobs.len() - )); - } - - let mut jobs = vec![]; - let mut unknown_jobs = vec![]; - for custom_job in custom_jobs { - if let Some(job) = db.find_auto_job_by_name(custom_job) { - jobs.push(job); - } else { - unknown_jobs.push(custom_job.clone()); - } - } - if !unknown_jobs.is_empty() { - return Err(anyhow::anyhow!( - "Custom job(s) `{}` not found in auto jobs", - unknown_jobs.join(", ") - )); - } - jobs - } else { - db.try_jobs.clone() - }; - (jobs, "try", &db.envs.try_env) - } - RunType::AutoJob => (db.auto_jobs.clone(), "auto", &db.envs.auto_env), - }; - let jobs = skip_jobs(jobs, channel); - let jobs = jobs - .into_iter() - .map(|job| { - let mut env: BTreeMap = yaml_map_to_json(base_env); - env.extend(yaml_map_to_json(&job.env)); - let full_name = format!("{prefix} - {}", job.name); - - GithubActionsJob { - name: job.name, - full_name, - os: job.os, - env, - free_disk: job.free_disk, - continue_on_error: job.continue_on_error, - } - }) - .collect(); - - Ok(jobs) -} - -fn calculate_job_matrix( - db: JobDatabase, - gh_ctx: GitHubContext, - channel: &str, -) -> anyhow::Result<()> { - let run_type = gh_ctx.get_run_type().ok_or_else(|| { - anyhow::anyhow!("Cannot determine the type of workflow that is being executed") - })?; - eprintln!("Run type: {run_type:?}"); - - let jobs = calculate_jobs(&run_type, &db, channel)?; - if jobs.is_empty() { - return Err(anyhow::anyhow!("Computed job list is empty")); - } - - let run_type = match run_type { - RunType::PullRequest => "pr", - RunType::TryJob { .. } => "try", - RunType::AutoJob => "auto", - }; - - eprintln!("Output"); - eprintln!("jobs={jobs:?}"); - eprintln!("run_type={run_type}"); - println!("jobs={}", serde_json::to_string(&jobs)?); - println!("run_type={run_type}"); - - Ok(()) -} - -fn find_linux_job<'a>(jobs: &'a [Job], name: &str) -> anyhow::Result<&'a Job> { - let Some(job) = jobs.iter().find(|j| j.name == name) else { - let available_jobs: Vec<&Job> = jobs.iter().filter(|j| j.is_linux()).collect(); - let mut available_jobs = - available_jobs.iter().map(|j| j.name.to_string()).collect::>(); - available_jobs.sort(); - return Err(anyhow::anyhow!( - "Job {name} not found. The following jobs are available:\n{}", - available_jobs.join(", ") - )); - }; - if !job.is_linux() { - return Err(anyhow::anyhow!("Only Linux jobs can be executed locally")); - } - - Ok(job) -} - fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> anyhow::Result<()> { let jobs = match job_type { JobType::Auto => &db.auto_jobs, JobType::PR => &db.pr_jobs, }; - let job = find_linux_job(jobs, &name).with_context(|| format!("Cannot find job {name}"))?; + let job = + jobs::find_linux_job(jobs, &name).with_context(|| format!("Cannot find job {name}"))?; let mut custom_env: BTreeMap = BTreeMap::new(); // Replicate src/ci/scripts/setup-environment.sh @@ -391,7 +170,7 @@ enum Args { } #[derive(clap::ValueEnum, Clone)] -enum JobType { +pub enum JobType { /// Merge attempt ("auto") job Auto, /// Pull request job @@ -401,7 +180,7 @@ enum JobType { fn main() -> anyhow::Result<()> { let args = Args::parse(); let default_jobs_file = Path::new(JOBS_YML_PATH); - let load_db = |jobs_path| load_job_db(jobs_path).context("Cannot load jobs.yml"); + let load_db = |jobs_path| jobs::load_job_db(jobs_path).context("Cannot load jobs.yml"); match args { Args::CalculateJobMatrix { jobs_file } => { @@ -413,7 +192,7 @@ fn main() -> anyhow::Result<()> { .trim() .to_string(); - calculate_job_matrix(load_db(jobs_path)?, gh_ctx, &channel) + jobs::calculate_job_matrix(load_db(jobs_path)?, gh_ctx, &channel) .context("Failed to calculate job matrix")?; } Args::RunJobLocally { job_type, name } => { diff --git a/src/ci/citool/src/merge_report.rs b/src/ci/citool/src/merge_report.rs index 5dd662280f0f..17e42d49286f 100644 --- a/src/ci/citool/src/merge_report.rs +++ b/src/ci/citool/src/merge_report.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use anyhow::Context; use build_helper::metrics::{JsonRoot, TestOutcome}; -use crate::JobDatabase; +use crate::jobs::JobDatabase; use crate::metrics::get_test_suites; type Sha = String; From 2ce0205735afce776f402eb96f85759906959473 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 10 Mar 2025 13:57:23 +0100 Subject: [PATCH 918/991] Share implementation of expr_u{16,32,size}. --- compiler/rustc_ast_lowering/src/expr.rs | 29 +++++++------------------ 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 0f175ea615f6..5bb6704dde45 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -2130,37 +2130,24 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]))) } - pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> { + fn expr_uint(&mut self, sp: Span, ty: ast::UintTy, value: u128) -> hir::Expr<'hir> { let lit = self.arena.alloc(hir::Lit { span: sp, - node: ast::LitKind::Int( - (value as u128).into(), - ast::LitIntType::Unsigned(ast::UintTy::Usize), - ), + node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ty)), }); self.expr(sp, hir::ExprKind::Lit(lit)) } + pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> { + self.expr_uint(sp, ast::UintTy::Usize, value as u128) + } + pub(super) fn expr_u32(&mut self, sp: Span, value: u32) -> hir::Expr<'hir> { - let lit = self.arena.alloc(hir::Lit { - span: sp, - node: ast::LitKind::Int( - u128::from(value).into(), - ast::LitIntType::Unsigned(ast::UintTy::U32), - ), - }); - self.expr(sp, hir::ExprKind::Lit(lit)) + self.expr_uint(sp, ast::UintTy::U32, value as u128) } pub(super) fn expr_u16(&mut self, sp: Span, value: u16) -> hir::Expr<'hir> { - let lit = self.arena.alloc(hir::Lit { - span: sp, - node: ast::LitKind::Int( - u128::from(value).into(), - ast::LitIntType::Unsigned(ast::UintTy::U16), - ), - }); - self.expr(sp, hir::ExprKind::Lit(lit)) + self.expr_uint(sp, ast::UintTy::U16, value as u128) } pub(super) fn expr_char(&mut self, sp: Span, value: char) -> hir::Expr<'hir> { From 3326a9fd2733799deb74011ae9eda4c7d5c0b7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Mar 2025 13:32:58 +0100 Subject: [PATCH 919/991] Allow using glob aliases for custom try jobs --- src/ci/citool/Cargo.lock | 7 ++++ src/ci/citool/Cargo.toml | 1 + src/ci/citool/src/jobs.rs | 59 ++++++++++++++++-------------- src/ci/citool/src/jobs/tests.rs | 64 +++++++++++++++++++++++++++++++++ src/ci/citool/src/main.rs | 19 +++++----- 5 files changed, 116 insertions(+), 34 deletions(-) create mode 100644 src/ci/citool/src/jobs/tests.rs diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index 46343a7b86e8..c061ec6ebdce 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -107,6 +107,7 @@ dependencies = [ "build_helper", "clap", "csv", + "glob-match", "insta", "serde", "serde_json", @@ -308,6 +309,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "glob-match" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" + [[package]] name = "hashbrown" version = "0.15.2" diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index c486f2977a1c..dde09224afe8 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" anyhow = "1" clap = { version = "4.5", features = ["derive"] } csv = "1" +glob-match = "0.2" serde = { version = "1", features = ["derive"] } serde_yaml = "0.9" serde_json = "1" diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index 8103e9b93446..d161d17ebe64 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -1,7 +1,7 @@ -use crate::{GitHubContext, utils}; -use serde_yaml::Value; +#[cfg(test)] +mod tests; + use std::collections::BTreeMap; -use std::path::Path; use serde_yaml::Value; @@ -65,13 +65,19 @@ pub struct JobDatabase { } impl JobDatabase { - fn find_auto_job_by_name(&self, name: &str) -> Option { - self.auto_jobs.iter().find(|j| j.name == name).cloned() + /// Find `auto` jobs that correspond to the passed `pattern`. + /// Patterns are matched using the glob syntax. + /// For example `dist-*` matches all jobs starting with `dist-`. + fn find_auto_jobs_by_pattern(&self, pattern: &str) -> Vec { + self.auto_jobs + .iter() + .filter(|j| glob_match::glob_match(pattern, &j.name)) + .cloned() + .collect() } } -pub fn load_job_db(path: &Path) -> anyhow::Result { - let db = utils::read_to_string(path)?; +pub fn load_job_db(db: &str) -> anyhow::Result { let mut db: Value = serde_yaml::from_str(&db)?; // We need to expand merge keys (<<), because serde_yaml can't deal with them @@ -114,7 +120,7 @@ pub enum RunType { /// Workflows that run after a push to a PR branch PullRequest, /// Try run started with @bors try - TryJob { custom_jobs: Option> }, + TryJob { job_patterns: Option> }, /// Merge attempt workflow AutoJob, } @@ -130,28 +136,29 @@ fn calculate_jobs( ) -> anyhow::Result> { let (jobs, prefix, base_env) = match run_type { RunType::PullRequest => (db.pr_jobs.clone(), "PR", &db.envs.pr_env), - RunType::TryJob { custom_jobs } => { - let jobs = if let Some(custom_jobs) = custom_jobs { - if custom_jobs.len() > MAX_TRY_JOBS_COUNT { - return Err(anyhow::anyhow!( - "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs", - custom_jobs.len() - )); - } - - let mut jobs = vec![]; - let mut unknown_jobs = vec![]; - for custom_job in custom_jobs { - if let Some(job) = db.find_auto_job_by_name(custom_job) { - jobs.push(job); + RunType::TryJob { job_patterns } => { + let jobs = if let Some(patterns) = job_patterns { + let mut jobs: Vec = vec![]; + let mut unknown_patterns = vec![]; + for pattern in patterns { + let matched_jobs = db.find_auto_jobs_by_pattern(pattern); + if matched_jobs.is_empty() { + unknown_patterns.push(pattern.clone()); } else { - unknown_jobs.push(custom_job.clone()); + jobs.extend(matched_jobs); } } - if !unknown_jobs.is_empty() { + if !unknown_patterns.is_empty() { return Err(anyhow::anyhow!( - "Custom job(s) `{}` not found in auto jobs", - unknown_jobs.join(", ") + "Patterns `{}` did not match any auto jobs", + unknown_patterns.join(", ") + )); + } + if jobs.len() > MAX_TRY_JOBS_COUNT { + return Err(anyhow::anyhow!( + "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs expanded from {} pattern(s)", + jobs.len(), + patterns.len() )); } jobs diff --git a/src/ci/citool/src/jobs/tests.rs b/src/ci/citool/src/jobs/tests.rs new file mode 100644 index 000000000000..a489656fa5dc --- /dev/null +++ b/src/ci/citool/src/jobs/tests.rs @@ -0,0 +1,64 @@ +use crate::jobs::{JobDatabase, load_job_db}; + +#[test] +fn lookup_job_pattern() { + let db = load_job_db( + r#" +envs: + pr: + try: + auto: + +pr: +try: +auto: + - name: dist-a + os: ubuntu + env: {} + - name: dist-a-alt + os: ubuntu + env: {} + - name: dist-b + os: ubuntu + env: {} + - name: dist-b-alt + os: ubuntu + env: {} + - name: test-a + os: ubuntu + env: {} + - name: test-a-alt + os: ubuntu + env: {} + - name: test-i686 + os: ubuntu + env: {} + - name: dist-i686 + os: ubuntu + env: {} + - name: test-msvc-i686-1 + os: ubuntu + env: {} + - name: test-msvc-i686-2 + os: ubuntu + env: {} +"#, + ) + .unwrap(); + check_pattern(&db, "dist-*", &["dist-a", "dist-a-alt", "dist-b", "dist-b-alt", "dist-i686"]); + check_pattern(&db, "*-alt", &["dist-a-alt", "dist-b-alt", "test-a-alt"]); + check_pattern(&db, "dist*-alt", &["dist-a-alt", "dist-b-alt"]); + check_pattern( + &db, + "*i686*", + &["test-i686", "dist-i686", "test-msvc-i686-1", "test-msvc-i686-2"], + ); +} + +#[track_caller] +fn check_pattern(db: &JobDatabase, pattern: &str, expected: &[&str]) { + let jobs = + db.find_auto_jobs_by_pattern(pattern).into_iter().map(|j| j.name).collect::>(); + + assert_eq!(jobs, expected); +} diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 8765922d089a..2a4be061e4ec 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -35,21 +35,21 @@ impl GitHubContext { fn get_run_type(&self) -> Option { match (self.event_name.as_str(), self.branch_ref.as_str()) { ("pull_request", _) => Some(RunType::PullRequest), - ("push", "refs/heads/try-perf") => Some(RunType::TryJob { custom_jobs: None }), + ("push", "refs/heads/try-perf") => Some(RunType::TryJob { job_patterns: None }), ("push", "refs/heads/try" | "refs/heads/automation/bors/try") => { - let custom_jobs = self.get_custom_jobs(); - let custom_jobs = if !custom_jobs.is_empty() { Some(custom_jobs) } else { None }; - Some(RunType::TryJob { custom_jobs }) + let patterns = self.get_try_job_patterns(); + let patterns = if !patterns.is_empty() { Some(patterns) } else { None }; + Some(RunType::TryJob { job_patterns: patterns }) } ("push", "refs/heads/auto") => Some(RunType::AutoJob), _ => None, } } - /// Tries to parse names of specific CI jobs that should be executed in the form of - /// try-job: + /// Tries to parse patterns of CI jobs that should be executed in the form of + /// try-job: /// from the commit message of the passed GitHub context. - fn get_custom_jobs(&self) -> Vec { + fn get_try_job_patterns(&self) -> Vec { if let Some(ref msg) = self.commit_message { msg.lines() .filter_map(|line| line.trim().strip_prefix("try-job: ")) @@ -180,7 +180,10 @@ pub enum JobType { fn main() -> anyhow::Result<()> { let args = Args::parse(); let default_jobs_file = Path::new(JOBS_YML_PATH); - let load_db = |jobs_path| jobs::load_job_db(jobs_path).context("Cannot load jobs.yml"); + let load_db = |jobs_path| { + let db = utils::read_to_string(jobs_path)?; + Ok::<_, anyhow::Error>(jobs::load_job_db(&db).context("Cannot load jobs.yml")?) + }; match args { Args::CalculateJobMatrix { jobs_file } => { From 06d86cd60c59d4fb7b0df30248a0c50fbd96b14b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Mar 2025 13:35:50 +0100 Subject: [PATCH 920/991] Modify try-job documentation --- src/doc/rustc-dev-guide/src/tests/ci.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index ae6adb678af1..7fd4c1697224 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -134,15 +134,17 @@ There are several use-cases for try builds: the [dist-x86_64-linux] CI job. - Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it passes the test suite executed by that job. You can select which CI jobs will - be executed in the try build by adding up to 10 lines containing `try-job: - ` to the PR description. All such specified jobs will be executed + be executed in the try build by adding lines containing `try-job: + ` to the PR description. All such specified jobs will be executed in the try build once the `@bors try` command is used on the PR. If no try jobs are specified in this way, the jobs defined in the `try` section of - [`jobs.yml`] will be executed by default. + [`jobs.yml`] will be executed by default. Each pattern can either be an exact + name of a job or a glob pattern that matches multiple jobs, for example + `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. > **Using `try-job` PR description directives** > -> 1. Identify which set of try-jobs (max 10) you would like to exercise. You can +> 1. Identify which set of try-jobs you would like to exercise. You can > find the name of the CI jobs in [`jobs.yml`]. > > 2. Amend PR description to include (usually at the end of the PR description) @@ -153,9 +155,10 @@ There are several use-cases for try builds: > > try-job: x86_64-msvc > try-job: test-various +> try-job: *-alt > ``` > -> Each `try-job` directive must be on its own line. +> Each `try-job` pattern must be on its own line. > > 3. Run the prescribed try jobs with `@bors try`. As aforementioned, this > requires the user to either (1) have `try` permissions or (2) be delegated From dfef1a7b5ab07617d3c5a595f3764bdcc01ef23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Mar 2025 13:56:42 +0100 Subject: [PATCH 921/991] Handle backticks in try job patterns --- src/ci/citool/src/main.rs | 11 ++++++++-- src/doc/rustc-dev-guide/src/tests/ci.md | 27 +++++++++++++++---------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 2a4be061e4ec..cd690ebeb062 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -46,13 +46,20 @@ impl GitHubContext { } } - /// Tries to parse patterns of CI jobs that should be executed in the form of + /// Tries to parse patterns of CI jobs that should be executed + /// from the commit message of the passed GitHub context + /// + /// They can be specified in the form of /// try-job: - /// from the commit message of the passed GitHub context. + /// or + /// try-job: `` + /// (to avoid GitHub rendering the glob patterns as Markdown) fn get_try_job_patterns(&self) -> Vec { if let Some(ref msg) = self.commit_message { msg.lines() .filter_map(|line| line.trim().strip_prefix("try-job: ")) + // Strip backticks if present + .map(|l| l.trim_matches('`')) .map(|l| l.trim().to_string()) .collect() } else { diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 7fd4c1697224..0c0f750a45d7 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -133,29 +133,34 @@ There are several use-cases for try builds: Again, a working compiler build is needed for this, which can be produced by the [dist-x86_64-linux] CI job. - Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it - passes the test suite executed by that job. You can select which CI jobs will - be executed in the try build by adding lines containing `try-job: - ` to the PR description. All such specified jobs will be executed - in the try build once the `@bors try` command is used on the PR. If no try - jobs are specified in this way, the jobs defined in the `try` section of - [`jobs.yml`] will be executed by default. Each pattern can either be an exact - name of a job or a glob pattern that matches multiple jobs, for example - `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. + passes the test suite executed by that job. + +You can select which CI jobs will +be executed in the try build by adding lines containing `try-job: +` to the PR description. All such specified jobs will be executed +in the try build once the `@bors try` command is used on the PR. If no try +jobs are specified in this way, the jobs defined in the `try` section of +[`jobs.yml`] will be executed by default. + +Each pattern can either be an exact name of a job or a glob pattern that matches multiple jobs, +for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. When using +glob patterns, you might want to wrap them in backticks (`` ` ``) to avoid GitHub rendering +the pattern as Markdown. > **Using `try-job` PR description directives** > > 1. Identify which set of try-jobs you would like to exercise. You can > find the name of the CI jobs in [`jobs.yml`]. > -> 2. Amend PR description to include (usually at the end of the PR description) -> e.g. +> 2. Amend PR description to include a set of patterns (usually at the end +> of the PR description), for example: > > ```text > This PR fixes #123456. > > try-job: x86_64-msvc > try-job: test-various -> try-job: *-alt +> try-job: `*-alt` > ``` > > Each `try-job` pattern must be on its own line. From 16c08f61139df87e07bbb37a9c7bccc5e62d0490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Mar 2025 14:03:36 +0100 Subject: [PATCH 922/991] Ignore job duplicates --- src/ci/citool/src/jobs.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index d161d17ebe64..45a188fb234a 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -145,7 +145,11 @@ fn calculate_jobs( if matched_jobs.is_empty() { unknown_patterns.push(pattern.clone()); } else { - jobs.extend(matched_jobs); + for job in matched_jobs { + if !jobs.iter().any(|j| j.name == job.name) { + jobs.push(job); + } + } } } if !unknown_patterns.is_empty() { From dc576cb67fcf713de44482a1a5aa586dfeff628e Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 10 Mar 2025 17:36:49 +0800 Subject: [PATCH 923/991] Add remark for missing llvm-tools component re. rustc_private linker failures related to not finding LLVM libraries Signed-off-by: xizheyin --- .../src/language-features/rustc-private.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/doc/unstable-book/src/language-features/rustc-private.md b/src/doc/unstable-book/src/language-features/rustc-private.md index 3b83a3cf4df8..57ed857cdfe1 100644 --- a/src/doc/unstable-book/src/language-features/rustc-private.md +++ b/src/doc/unstable-book/src/language-features/rustc-private.md @@ -12,3 +12,33 @@ The presence of this feature changes the way the linkage format for dylibs is ca that is necessary for linking against dylibs that statically link `std` (such as `rustc_driver`). This makes this feature "viral" in linkage; its use in a given crate makes its use required in dependent crates which link to it (including integration tests, which are built as separate crates). + +## Common linker failures related to missing LLVM libraries + +### When using `rustc-private` with Official Toolchains + +When using the `rustc_private` feature with official toolchains distributed via rustup, you'll need to install: + +1. The `rustc-dev` component (provides compiler libraries) +2. The `llvm-tools` component (provides LLVM libraries needed for linking) + +You can install these components using `rustup`: + +```text +rustup component add rustc-dev llvm-tools +``` + +Without the `llvm-tools` component, you may encounter linking errors like: + +```text +error: linking with `cc` failed: exit status: 1 + | + = note: rust-lld: error: unable to find library -lLLVM-{version} +``` + +### When using `rustc-private` with Custom Toolchains + +For custom-built toolchains or environments not using rustup, different configuration may be required: + +- Ensure LLVM libraries are available in your library search paths +- You might need to configure library paths explicitly depending on your LLVM installation From 9213cb80c29941a7fb752413613c2c68f7e7d7b3 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 9 Mar 2025 16:47:38 +0100 Subject: [PATCH 924/991] fix ICE in pretty-printing `global_asm!` --- compiler/rustc_middle/src/mir/pretty.rs | 5 ++++- tests/mir-opt/global_asm.rs | 9 +++++++++ ...bal_asm.{global_asm#0}.SimplifyLocals-final.after.mir | 9 +++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/mir-opt/global_asm.rs create mode 100644 tests/mir-opt/global_asm.{global_asm#0}.SimplifyLocals-final.after.mir diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f880b1364c2c..05da8511361c 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -653,7 +653,10 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io: write!(w, "static mut ")? } (_, _) if is_function => write!(w, "fn ")?, - (DefKind::AnonConst | DefKind::InlineConst, _) => {} // things like anon const, not an item + // things like anon const, not an item + (DefKind::AnonConst | DefKind::InlineConst, _) => {} + // `global_asm!` have fake bodies, which we may dump after mir-build + (DefKind::GlobalAsm, _) => {} _ => bug!("Unexpected def kind {:?}", kind), } diff --git a/tests/mir-opt/global_asm.rs b/tests/mir-opt/global_asm.rs new file mode 100644 index 000000000000..22b782d365e9 --- /dev/null +++ b/tests/mir-opt/global_asm.rs @@ -0,0 +1,9 @@ +// skip-filecheck +//@ needs-asm-support + +// `global_asm!` gets a fake body, make sure it is handled correctly + +// EMIT_MIR global_asm.{global_asm#0}.SimplifyLocals-final.after.mir +core::arch::global_asm!("/* */"); + +fn main() {} diff --git a/tests/mir-opt/global_asm.{global_asm#0}.SimplifyLocals-final.after.mir b/tests/mir-opt/global_asm.{global_asm#0}.SimplifyLocals-final.after.mir new file mode 100644 index 000000000000..cec3c4a8261e --- /dev/null +++ b/tests/mir-opt/global_asm.{global_asm#0}.SimplifyLocals-final.after.mir @@ -0,0 +1,9 @@ +// MIR for `{global_asm#0}` after SimplifyLocals-final + +{global_asm#0}: ! = { + let mut _0: !; + + bb0: { + asm!("/* */", options()) -> unwind unreachable; + } +} From 61122d18298d1b82829a4717db896003b7d14c4d Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 10 Mar 2025 17:08:29 +0300 Subject: [PATCH 925/991] Delegation: fix ICE with invalid MethodCall generation --- compiler/rustc_ast_lowering/src/delegation.rs | 30 ++++++++++--------- compiler/rustc_ast_lowering/src/item.rs | 4 +-- tests/crashes/127916.rs | 16 ---------- tests/crashes/128119.rs | 15 ---------- tests/crashes/128190.rs | 7 ----- tests/ui/delegation/ice-isssue-128190.rs | 9 ++++++ tests/ui/delegation/ice-isssue-128190.stderr | 10 +++++++ 7 files changed, 37 insertions(+), 54 deletions(-) delete mode 100644 tests/crashes/127916.rs delete mode 100644 tests/crashes/128119.rs delete mode 100644 tests/crashes/128190.rs create mode 100644 tests/ui/delegation/ice-isssue-128190.rs create mode 100644 tests/ui/delegation/ice-isssue-128190.stderr diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index d8b7cb0c3225..571172be4ed1 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -60,25 +60,27 @@ pub(crate) struct DelegationResults<'hir> { } impl<'hir> LoweringContext<'_, 'hir> { - pub(crate) fn delegation_has_self(&self, item_id: NodeId, path_id: NodeId, span: Span) -> bool { + /// Defines whether the delegatee is an associated function whose first parameter is `self`. + pub(crate) fn delegatee_is_method(&self, item_id: NodeId, path_id: NodeId, span: Span) -> bool { let sig_id = self.get_delegation_sig_id(item_id, path_id, span); let Ok(sig_id) = sig_id else { return false; }; - self.has_self(sig_id, span) + self.is_method(sig_id, span) } - fn has_self(&self, def_id: DefId, span: Span) -> bool { - if let Some(local_sig_id) = def_id.as_local() { - // The value may be missing due to recursive delegation. - // Error will be emitted later during HIR ty lowering. - self.resolver.delegation_fn_sigs.get(&local_sig_id).is_some_and(|sig| sig.has_self) - } else { - match self.tcx.def_kind(def_id) { - DefKind::Fn => false, - DefKind::AssocFn => self.tcx.associated_item(def_id).fn_has_self_parameter, - _ => span_bug!(span, "unexpected DefKind for delegation item"), - } + fn is_method(&self, def_id: DefId, span: Span) -> bool { + match self.tcx.def_kind(def_id) { + DefKind::Fn => false, + DefKind::AssocFn => match def_id.as_local() { + Some(local_def_id) => self + .resolver + .delegation_fn_sigs + .get(&local_def_id) + .is_some_and(|sig| sig.has_self), + None => self.tcx.associated_item(def_id).fn_has_self_parameter, + }, + _ => span_bug!(span, "unexpected DefKind for delegation item"), } } @@ -324,7 +326,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let call = if self .get_resolution_id(delegation.id, span) - .and_then(|def_id| Ok(self.has_self(def_id, span))) + .and_then(|def_id| Ok(self.is_method(def_id, span))) .unwrap_or_default() && delegation.qself.is_none() && !has_generic_args diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 5e89321e6ecc..b01ca54fb6f4 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -871,7 +871,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } } AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn { - has_self: self.delegation_has_self(i.id, delegation.id, i.span), + has_self: self.delegatee_is_method(i.id, delegation.id, i.span), }, AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { panic!("macros should have been expanded by now") @@ -1000,7 +1000,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } } AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn { - has_self: self.delegation_has_self(i.id, delegation.id, i.span), + has_self: self.delegatee_is_method(i.id, delegation.id, i.span), }, AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { panic!("macros should have been expanded by now") diff --git a/tests/crashes/127916.rs b/tests/crashes/127916.rs deleted file mode 100644 index 295c88df8574..000000000000 --- a/tests/crashes/127916.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: #127916 - -trait Trait { - fn foo(&self) -> u32 { 0 } -} - -struct F; -struct S; - -mod to_reuse { - pub fn foo(&self) -> u32 {} -} - -impl Trait S { - reuse to_reuse::foo { self } -} diff --git a/tests/crashes/128119.rs b/tests/crashes/128119.rs deleted file mode 100644 index 7677b15a2f33..000000000000 --- a/tests/crashes/128119.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #128119 - -trait Trait { - reuse to_reuse::foo { self } -} - -struct S; - -mod to_reuse { - pub fn foo(&self) -> u32 {} -} - -impl Trait S { - reuse to_reuse::foo { self } -} diff --git a/tests/crashes/128190.rs b/tests/crashes/128190.rs deleted file mode 100644 index 0fa7027ae609..000000000000 --- a/tests/crashes/128190.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: rust-lang/rust#128190 - -fn a(&self) { - 15 -} - -reuse a as b { struct S; } diff --git a/tests/ui/delegation/ice-isssue-128190.rs b/tests/ui/delegation/ice-isssue-128190.rs new file mode 100644 index 000000000000..dab3bbee663c --- /dev/null +++ b/tests/ui/delegation/ice-isssue-128190.rs @@ -0,0 +1,9 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +fn a(&self) {} +//~^ ERROR `self` parameter is only allowed in associated functions + +reuse a as b; + +fn main() {} diff --git a/tests/ui/delegation/ice-isssue-128190.stderr b/tests/ui/delegation/ice-isssue-128190.stderr new file mode 100644 index 000000000000..18f676642c2b --- /dev/null +++ b/tests/ui/delegation/ice-isssue-128190.stderr @@ -0,0 +1,10 @@ +error: `self` parameter is only allowed in associated functions + --> $DIR/ice-isssue-128190.rs:4:6 + | +LL | fn a(&self) {} + | ^^^^^ not semantically valid as function parameter + | + = note: associated functions are those in `impl` or `trait` definitions + +error: aborting due to 1 previous error + From bc4f0bb486bcba6e6e40d0dd7c9df0f9e6aebca9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 6 Mar 2025 22:01:01 +0000 Subject: [PATCH 926/991] Pass InferCtxt to InlineAsmCtxt to properly taint on error Split up some of the tests bc tainting causes some errors to become suppressed --- .../src/check/intrinsicck.rs | 110 +++++++++--------- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 15 +-- tests/ui/asm/invalid-const-operand.rs | 8 +- tests/ui/asm/invalid-const-operand.stderr | 8 +- tests/ui/asm/tainting-on-error.rs | 13 +++ tests/ui/asm/tainting-on-error.stderr | 10 ++ tests/ui/asm/x86_64/type-check-2.rs | 8 +- tests/ui/asm/x86_64/type-check-2.stderr | 16 +-- 8 files changed, 109 insertions(+), 79 deletions(-) create mode 100644 tests/ui/asm/tainting-on-error.rs create mode 100644 tests/ui/asm/tainting-on-error.stderr diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 590ade516ec6..d63165f0f169 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -3,8 +3,11 @@ use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; +use rustc_infer::infer::InferCtxt; use rustc_middle::bug; -use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; +use rustc_middle::ty::{ + self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, TypeckResults, UintTy, +}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::{Symbol, sym}; @@ -14,12 +17,11 @@ use rustc_target::asm::{ use crate::errors::RegisterTypeUnstable; -pub struct InlineAsmCtxt<'a, 'tcx: 'a> { - tcx: TyCtxt<'tcx>, +pub struct InlineAsmCtxt<'a, 'tcx> { typing_env: ty::TypingEnv<'tcx>, target_features: &'tcx FxIndexSet, - expr_ty: Box) -> Ty<'tcx> + 'a>, - node_ty: Box Ty<'tcx> + 'a>, + infcx: &'a InferCtxt<'tcx>, + typeck_results: &'a TypeckResults<'tcx>, } enum NonAsmTypeReason<'tcx> { @@ -31,34 +33,38 @@ enum NonAsmTypeReason<'tcx> { impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { pub fn new( - tcx: TyCtxt<'tcx>, def_id: LocalDefId, + infcx: &'a InferCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, - expr_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a, - node_ty: impl Fn(hir::HirId) -> Ty<'tcx> + 'a, + typeck_results: &'a TypeckResults<'tcx>, ) -> Self { InlineAsmCtxt { - tcx, typing_env, - target_features: tcx.asm_target_features(def_id), - expr_ty: Box::new(expr_ty), - node_ty: Box::new(node_ty), + target_features: infcx.tcx.asm_target_features(def_id), + infcx, + typeck_results, } } - fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> { - (self.expr_ty)(expr) + fn tcx(&self) -> TyCtxt<'tcx> { + self.infcx.tcx } - fn node_ty(&self, hir_id: hir::HirId) -> Ty<'tcx> { - (self.node_ty)(hir_id) + fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> { + let ty = self.typeck_results.expr_ty_adjusted(expr); + let ty = self.infcx.resolve_vars_if_possible(ty); + if ty.has_non_region_infer() { + Ty::new_misc_error(self.tcx()) + } else { + self.tcx().erase_regions(ty) + } } // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()` fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool { // Type still may have region variables, but `Sized` does not depend // on those, so just erase them before querying. - if ty.is_sized(self.tcx, self.typing_env) { + if ty.is_sized(self.tcx(), self.typing_env) { return true; } if let ty::Foreign(..) = ty.kind() { @@ -68,7 +74,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } fn get_asm_ty(&self, ty: Ty<'tcx>) -> Result> { - let asm_ty_isize = match self.tcx.sess.target.pointer_width { + let asm_ty_isize = match self.tcx().sess.target.pointer_width { 16 => InlineAsmType::I16, 32 => InlineAsmType::I32, 64 => InlineAsmType::I64, @@ -97,12 +103,12 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Adt(adt, args) if adt.repr().simd() => { let fields = &adt.non_enum_variant().fields; let field = &fields[FieldIdx::ZERO]; - let elem_ty = field.ty(self.tcx, args); + let elem_ty = field.ty(self.tcx(), args); let (size, ty) = match elem_ty.kind() { ty::Array(ty, len) => { - let len = self.tcx.normalize_erasing_regions(self.typing_env, *len); - if let Some(len) = len.try_to_target_usize(self.tcx) { + let len = self.tcx().normalize_erasing_regions(self.typing_env, *len); + if let Some(len) = len.try_to_target_usize(self.tcx()) { (len, *ty) } else { return Err(NonAsmTypeReason::UnevaluatedSIMDArrayLength( @@ -122,7 +128,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { Ok(InlineAsmType::VecI128(size)) } ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => { - Ok(match self.tcx.sess.target.pointer_width { + Ok(match self.tcx().sess.target.pointer_width { 16 => InlineAsmType::VecI16(size), 32 => InlineAsmType::VecI32(size), 64 => InlineAsmType::VecI64(size), @@ -159,9 +165,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // `!` is allowed for input but not for output (issue #87802) ty::Never if is_input => return None, _ if ty.references_error() => return None, - ty::Adt(adt, args) if self.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => { + ty::Adt(adt, args) if self.tcx().is_lang_item(adt.did(), LangItem::MaybeUninit) => { let fields = &adt.non_enum_variant().fields; - let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args); + let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx(), args); // FIXME: Are we just trying to map to the `T` in `MaybeUninit`? // If so, just get it from the args. let ty::Adt(ty, args) = ty.kind() else { @@ -172,7 +178,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { "expected first field of `MaybeUninit` to be `ManuallyDrop`" ); let fields = &ty.non_enum_variant().fields; - let ty = fields[FieldIdx::ZERO].ty(self.tcx, args); + let ty = fields[FieldIdx::ZERO].ty(self.tcx(), args); self.get_asm_ty(ty) } _ => self.get_asm_ty(ty), @@ -183,9 +189,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { match reason { NonAsmTypeReason::UnevaluatedSIMDArrayLength(did, len) => { let msg = format!("cannot evaluate SIMD vector length `{len}`"); - self.tcx + self.infcx .dcx() - .struct_span_err(self.tcx.def_span(did), msg) + .struct_span_err(self.tcx().def_span(did), msg) .with_span_note( expr.span, "SIMD vector length needs to be known statically for use in `asm!`", @@ -194,7 +200,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } NonAsmTypeReason::Invalid(ty) => { let msg = format!("cannot use value of type `{ty}` for inline assembly"); - self.tcx.dcx().struct_span_err(expr.span, msg).with_note( + self.infcx.dcx().struct_span_err(expr.span, msg).with_note( "only integers, floats, SIMD vectors, pointers and function pointers \ can be used as arguments for inline assembly", ).emit(); @@ -203,7 +209,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let msg = format!( "cannot use value of unsized pointer type `{ty}` for inline assembly" ); - self.tcx + self.infcx .dcx() .struct_span_err(expr.span, msg) .with_note("only sized pointers can be used in inline assembly") @@ -213,8 +219,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let msg = format!( "cannot use SIMD vector with element type `{ty}` for inline assembly" ); - self.tcx.dcx() - .struct_span_err(self.tcx.def_span(did), msg).with_span_note( + self.infcx.dcx() + .struct_span_err(self.tcx().def_span(did), msg).with_span_note( expr.span, "only integers, floats, SIMD vectors, pointers and function pointers \ can be used as arguments for inline assembly", @@ -227,9 +233,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check that the type implements Copy. The only case where this can // possibly fail is for SIMD types which don't #[derive(Copy)]. - if !self.tcx.type_is_copy_modulo_regions(self.typing_env, ty) { + if !self.tcx().type_is_copy_modulo_regions(self.typing_env, ty) { let msg = "arguments for inline assembly must be copyable"; - self.tcx + self.infcx .dcx() .struct_span_err(expr.span, msg) .with_note(format!("`{ty}` does not implement the Copy trait")) @@ -249,7 +255,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if in_asm_ty != asm_ty { let msg = "incompatible types for asm inout argument"; let in_expr_ty = self.expr_ty(in_expr); - self.tcx + self.infcx .dcx() .struct_span_err(vec![in_expr.span, expr.span], msg) .with_span_label(in_expr.span, format!("type `{in_expr_ty}`")) @@ -268,21 +274,21 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check the type against the list of types supported by the selected // register class. - let asm_arch = self.tcx.sess.asm_arch.unwrap(); - let allow_experimental_reg = self.tcx.features().asm_experimental_reg(); + let asm_arch = self.tcx().sess.asm_arch.unwrap(); + let allow_experimental_reg = self.tcx().features().asm_experimental_reg(); let reg_class = reg.reg_class(); let supported_tys = reg_class.supported_types(asm_arch, allow_experimental_reg); let Some((_, feature)) = supported_tys.iter().find(|&&(t, _)| t == asm_ty) else { let mut err = if !allow_experimental_reg && reg_class.supported_types(asm_arch, true).iter().any(|&(t, _)| t == asm_ty) { - self.tcx.sess.create_feature_err( + self.tcx().sess.create_feature_err( RegisterTypeUnstable { span: expr.span, ty }, sym::asm_experimental_reg, ) } else { let msg = format!("type `{ty}` cannot be used with this register class"); - let mut err = self.tcx.dcx().struct_span_err(expr.span, msg); + let mut err = self.infcx.dcx().struct_span_err(expr.span, msg); let supported_tys: Vec<_> = supported_tys.iter().map(|(t, _)| t.to_string()).collect(); err.note(format!( @@ -312,7 +318,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Some(feature) = feature { if !self.target_features.contains(feature) { let msg = format!("`{feature}` target feature is not enabled"); - self.tcx + self.infcx .dcx() .struct_span_err(expr.span, msg) .with_note(format!( @@ -349,7 +355,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { result: default_result, size: default_size, } = reg_class.default_modifier(asm_arch).unwrap(); - self.tcx.node_span_lint( + self.tcx().node_span_lint( lint::builtin::ASM_SUB_REGISTER, expr.hir_id, spans, @@ -371,11 +377,11 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) { - let Some(asm_arch) = self.tcx.sess.asm_arch else { - self.tcx.dcx().delayed_bug("target architecture does not support asm"); + let Some(asm_arch) = self.tcx().sess.asm_arch else { + self.infcx.dcx().delayed_bug("target architecture does not support asm"); return; }; - let allow_experimental_reg = self.tcx.features().asm_experimental_reg(); + let allow_experimental_reg = self.tcx().features().asm_experimental_reg(); for (idx, &(op, op_sp)) in asm.operands.iter().enumerate() { // Validate register classes against currently enabled target // features. We check that at least one type is available for @@ -398,13 +404,13 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } if let Err(msg) = reg.validate( asm_arch, - self.tcx.sess.relocation_model(), + self.tcx().sess.relocation_model(), self.target_features, - &self.tcx.sess.target, + &self.tcx().sess.target, op.is_clobber(), ) { let msg = format!("cannot use register `{}`: {}", reg.name(), msg); - self.tcx.dcx().span_err(op_sp, msg); + self.infcx.dcx().span_err(op_sp, msg); continue; } } @@ -444,7 +450,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { reg_class.name(), feature ); - self.tcx.dcx().span_err(op_sp, msg); + self.infcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -458,7 +464,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { .intersperse(", ") .collect::(), ); - self.tcx.dcx().span_err(op_sp, msg); + self.infcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -493,16 +499,16 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } } hir::InlineAsmOperand::Const { anon_const } => { - let ty = self.node_ty(anon_const.hir_id); + let ty = self.expr_ty(self.tcx().hir_body(anon_const.body).value); match ty.kind() { ty::Error(_) => {} _ if ty.is_integral() => {} _ => { - self.tcx + self.infcx .dcx() .struct_span_err(op_sp, "invalid type for `const` operand") .with_span_label( - self.tcx.def_span(anon_const.def_id), + self.tcx().def_span(anon_const.def_id), format!("is {} `{}`", ty.kind().article(), ty), ) .with_help("`const` operands must be of an integer type") @@ -517,7 +523,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::FnDef(..) => {} ty::Error(_) => {} _ => { - self.tcx + self.infcx .dcx() .struct_span_err(op_sp, "invalid `sym` operand") .with_span_label( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index db947b6744da..ac911c202220 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -99,22 +99,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len()); for (asm, hir_id) in deferred_asm_checks.drain(..) { let enclosing_id = self.tcx.hir_enclosing_body_owner(hir_id); - let expr_ty = |expr: &hir::Expr<'tcx>| { - let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); - let ty = self.resolve_vars_if_possible(ty); - if ty.has_non_region_infer() { - Ty::new_misc_error(self.tcx) - } else { - self.tcx.erase_regions(ty) - } - }; - let node_ty = |hir_id: HirId| self.typeck_results.borrow().node_type(hir_id); InlineAsmCtxt::new( - self.tcx, enclosing_id, + &self.infcx, self.typing_env(self.param_env), - expr_ty, - node_ty, + &*self.typeck_results.borrow(), ) .check_asm(asm); } diff --git a/tests/ui/asm/invalid-const-operand.rs b/tests/ui/asm/invalid-const-operand.rs index a688f5042db5..bbf4001752a4 100644 --- a/tests/ui/asm/invalid-const-operand.rs +++ b/tests/ui/asm/invalid-const-operand.rs @@ -14,7 +14,7 @@ global_asm!("{}", const 0f32); global_asm!("{}", const 0 as *mut u8); //~^ ERROR invalid type for `const` operand -fn main() { +fn test1() { unsafe { // Const operands must be integers and must be constants. @@ -27,7 +27,11 @@ fn main() { //~^ ERROR invalid type for `const` operand asm!("{}", const &0); //~^ ERROR invalid type for `const` operand + } +} +fn test2() { + unsafe { // Constants must be... constant let x = 0; @@ -47,3 +51,5 @@ fn main() { //~^ ERROR attempt to use a non-constant value in a constant } } + +fn main() {} diff --git a/tests/ui/asm/invalid-const-operand.stderr b/tests/ui/asm/invalid-const-operand.stderr index 1cedabeef289..01aa843c6fb1 100644 --- a/tests/ui/asm/invalid-const-operand.stderr +++ b/tests/ui/asm/invalid-const-operand.stderr @@ -1,5 +1,5 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/invalid-const-operand.rs:40:26 + --> $DIR/invalid-const-operand.rs:44:26 | LL | asm!("{}", const x); | ^ non-constant value @@ -11,7 +11,7 @@ LL + const x: /* Type */ = 0; | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/invalid-const-operand.rs:43:36 + --> $DIR/invalid-const-operand.rs:47:36 | LL | asm!("{}", const const_foo(x)); | ^ non-constant value @@ -23,7 +23,7 @@ LL + const x: /* Type */ = 0; | error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/invalid-const-operand.rs:46:36 + --> $DIR/invalid-const-operand.rs:50:36 | LL | asm!("{}", const const_bar(x)); | ^ non-constant value @@ -80,7 +80,7 @@ error: invalid type for `const` operand LL | asm!("{}", const &0); | ^^^^^^-- | | - | is a `&{integer}` + | is a `&i32` | = help: `const` operands must be of an integer type diff --git a/tests/ui/asm/tainting-on-error.rs b/tests/ui/asm/tainting-on-error.rs new file mode 100644 index 000000000000..a8e9af911580 --- /dev/null +++ b/tests/ui/asm/tainting-on-error.rs @@ -0,0 +1,13 @@ +//@ needs-asm-support + +use std::arch::asm; + +fn main() { + unsafe { + asm!( + "/* {} */", + sym None::<()>, + //~^ ERROR invalid `sym` operand + ); + } +} diff --git a/tests/ui/asm/tainting-on-error.stderr b/tests/ui/asm/tainting-on-error.stderr new file mode 100644 index 000000000000..bd706d1f310b --- /dev/null +++ b/tests/ui/asm/tainting-on-error.stderr @@ -0,0 +1,10 @@ +error: invalid `sym` operand + --> $DIR/tainting-on-error.rs:9:13 + | +LL | sym None::<()>, + | ^^^^^^^^^^^^^^ is an `Option<()>` + | + = help: `sym` operands must refer to either a function or a static + +error: aborting due to 1 previous error + diff --git a/tests/ui/asm/x86_64/type-check-2.rs b/tests/ui/asm/x86_64/type-check-2.rs index 1650c595faeb..c63042298da3 100644 --- a/tests/ui/asm/x86_64/type-check-2.rs +++ b/tests/ui/asm/x86_64/type-check-2.rs @@ -7,7 +7,7 @@ use std::arch::{asm, global_asm}; #[repr(simd)] struct SimdNonCopy([f32; 4]); -fn main() { +fn test1() { unsafe { // Inputs must be initialized @@ -26,7 +26,11 @@ fn main() { asm!("{}", in(reg) v[0]); asm!("{}", out(reg) v[0]); asm!("{}", inout(reg) v[0]); + } +} +fn test2() { + unsafe { // Register operands must be Copy asm!("{}", in(xmm_reg) SimdNonCopy([0.0, 0.0, 0.0, 0.0])); @@ -68,3 +72,5 @@ fn main() { asm!("{}", in(reg) u); } } + +fn main() {} diff --git a/tests/ui/asm/x86_64/type-check-2.stderr b/tests/ui/asm/x86_64/type-check-2.stderr index 8b1bfa85fa2c..d5c5a3ff1f84 100644 --- a/tests/ui/asm/x86_64/type-check-2.stderr +++ b/tests/ui/asm/x86_64/type-check-2.stderr @@ -1,13 +1,13 @@ error: arguments for inline assembly must be copyable - --> $DIR/type-check-2.rs:32:32 + --> $DIR/type-check-2.rs:36:32 | LL | asm!("{}", in(xmm_reg) SimdNonCopy([0.0, 0.0, 0.0, 0.0])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `SimdNonCopy` does not implement the Copy trait -error: cannot use value of type `{closure@$DIR/type-check-2.rs:44:28: 44:36}` for inline assembly - --> $DIR/type-check-2.rs:44:28 +error: cannot use value of type `{closure@$DIR/type-check-2.rs:48:28: 48:36}` for inline assembly + --> $DIR/type-check-2.rs:48:28 | LL | asm!("{}", in(reg) |x: i32| x); | ^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | asm!("{}", in(reg) |x: i32| x); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `Vec` for inline assembly - --> $DIR/type-check-2.rs:46:28 + --> $DIR/type-check-2.rs:50:28 | LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ @@ -24,7 +24,7 @@ LL | asm!("{}", in(reg) vec![0]); = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly - --> $DIR/type-check-2.rs:48:28 + --> $DIR/type-check-2.rs:52:28 | LL | asm!("{}", in(reg) (1, 2, 3)); | ^^^^^^^^^ @@ -32,7 +32,7 @@ LL | asm!("{}", in(reg) (1, 2, 3)); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly - --> $DIR/type-check-2.rs:50:28 + --> $DIR/type-check-2.rs:54:28 | LL | asm!("{}", in(reg) [1, 2, 3]); | ^^^^^^^^^ @@ -40,7 +40,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `fn() {main}` for inline assembly - --> $DIR/type-check-2.rs:58:31 + --> $DIR/type-check-2.rs:62:31 | LL | asm!("{}", inout(reg) f); | ^ @@ -48,7 +48,7 @@ LL | asm!("{}", inout(reg) f); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `&mut i32` for inline assembly - --> $DIR/type-check-2.rs:61:31 + --> $DIR/type-check-2.rs:65:31 | LL | asm!("{}", inout(reg) r); | ^ From bf58a3521f8e5fb0fa693e77ce9ef7e5e3c4a915 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 9 Mar 2025 01:36:51 +0300 Subject: [PATCH 927/991] stabilize `ci_rustc_if_unchanged_logic` test for local environments Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder/tests.rs | 10 ++++++++-- src/bootstrap/src/core/config/config.rs | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 63a1bbc24f16..1f96ac729e2a 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -261,8 +261,14 @@ fn ci_rustc_if_unchanged_logic() { // Make sure "if-unchanged" logic doesn't try to use CI rustc while there are changes // in compiler and/or library. if config.download_rustc_commit.is_some() { - let has_changes = - config.last_modified_commit(&["compiler", "library"], "download-rustc", true).is_none(); + let mut paths = vec!["compiler"]; + + // Handle library tree the same way as in `Config::download_ci_rustc_commit`. + if build_helper::ci::CiEnv::is_ci() { + paths.push("library"); + } + + let has_changes = config.last_modified_commit(&paths, "download-rustc", true).is_none(); assert!( !has_changes, diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index ac24da9f86b2..09dc9dfbc04a 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2985,6 +2985,9 @@ impl Config { // these changes to speed up the build process for library developers. This provides consistent // functionality for library developers between `download-rustc=true` and `download-rustc="if-unchanged"` // options. + // + // If you update "library" logic here, update `builder::tests::ci_rustc_if_unchanged_logic` test + // logic accordingly. if !CiEnv::is_ci() { allowed_paths.push(":!library"); } From 5d4ff50f49220ebdf894421999ecee3deeaa7938 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 10 Mar 2025 18:01:15 +0100 Subject: [PATCH 928/991] Update books --- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/book b/src/doc/book index 4a01a9182496..81a976a237f8 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 4a01a9182496f807aaa5f72d93a25ce18bcbe105 +Subproject commit 81a976a237f84b8392c4ce1bd5fd076eb757a2eb diff --git a/src/doc/edition-guide b/src/doc/edition-guide index daa4b763cd84..1e27e5e6d513 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit daa4b763cd848f986813b5cf8069e1649f7147af +Subproject commit 1e27e5e6d5133ae4612f5cc195c15fc8d51b1c9c diff --git a/src/doc/nomicon b/src/doc/nomicon index 8f5c7322b65d..b4448fa406a6 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 8f5c7322b65d079aa5b242eb10d89a98e12471e1 +Subproject commit b4448fa406a6dccde62d1e2f34f70fc51814cdcc diff --git a/src/doc/reference b/src/doc/reference index 615b4cec60c2..dda31c85f2ef 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 615b4cec60c269cfc105d511c93287620032d5b0 +Subproject commit dda31c85f2ef2e5d2f0f2f643c9231690a30a626 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 66543bbc5b7d..6f69823c28ae 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 66543bbc5b7dbd4e679092c07ae06ba6c73fd912 +Subproject commit 6f69823c28ae8d929d6c815181c73d3e99ef16d3 From dcf6137b5cb16c5ed569fd0a17517cbaed48e604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 10 Mar 2025 19:03:51 +0100 Subject: [PATCH 929/991] use next_back() instead of last() on DoubleEndedIterator --- compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs | 2 +- compiler/rustc_parse/src/parser/diagnostics.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index ace5e34b3824..fa061c806180 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1520,7 +1520,7 @@ fn generics_args_err_extend<'a>( }) .collect(); if args.len() > 1 - && let Some(span) = args.into_iter().last() + && let Some(span) = args.into_iter().next_back() { err.note( "generic arguments are not allowed on both an enum and its variant's path \ diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index bb227a58cf19..716ababb0080 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2107,7 +2107,7 @@ impl<'a> Parser<'a> { ast::GenericBound::Trait(poly) => Some(poly), _ => None, }) - .last() + .next_back() { err.span_suggestion_verbose( poly.span.shrink_to_hi(), From e337d87e965d2562544a2d45f6eeef503c1271d5 Mon Sep 17 00:00:00 2001 From: David Tenty Date: Fri, 7 Mar 2025 00:43:04 -0500 Subject: [PATCH 930/991] Add powerpc64le maintainers --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 +- .../powerpc64le-unknown-linux-gnu.md | 47 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index b1d7e5421c1b..2f86021a4859 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -72,6 +72,7 @@ - [powerpc-unknown-linux-gnuspe](platform-support/powerpc-unknown-linux-gnuspe.md) - [powerpc-unknown-linux-muslspe](platform-support/powerpc-unknown-linux-muslspe.md) - [powerpc64-ibm-aix](platform-support/aix.md) + - [powerpc64le-unknown-linux-gnu](platform-support/powerpc64le-unknown-linux-gnu.md) - [powerpc64le-unknown-linux-musl](platform-support/powerpc64le-unknown-linux-musl.md) - [riscv32e\*-unknown-none-elf](platform-support/riscv32e-unknown-none-elf.md) - [riscv32i\*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 84440a5ab78b..bdecc23e1f39 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -96,7 +96,7 @@ target | notes [`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5) `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17) `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17) -`powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17) +[`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10, glibc 2.17) [`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19, musl 1.2.3) [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29) [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3) diff --git a/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md new file mode 100644 index 000000000000..6cb34b2a777a --- /dev/null +++ b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md @@ -0,0 +1,47 @@ +# `powerpc64le-unknown-linux-gnu` + +**Tier: 2** + +Target for 64-bit little endian PowerPC Linux programs + +## Target maintainers + +- David Tenty `daltenty@ibm.com`, https://github.com/daltenty +- Chris Cambly, `ccambly@ca.ibm.com`, https://github.com/gilamn5tr + +## Requirements + +Building the target itself requires a 64-bit little endian PowerPC compiler that is supported by `cc-rs`. + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["powerpc64le-unknown-linux-gnu"] +``` + +Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`: + +```toml +[target.powerpc64le-unknown-linux-gnu] +cc = "powerpc64le-linux-gnu-gcc" +cxx = "powerpc64le-linux-gnu-g++" +ar = "powerpc64le-linux-gnu-ar" +linker = "powerpc64le-linux-gnu-gcc" +``` + +## Building Rust programs + +This target is distributed through `rustup`, and requires no special +configuration. + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +This target can be tested as normal with `x.py` on a 64-bit little endian +PowerPC host or via QEMU emulation. From d75c9733f4ff9f6a45566952e8f330f6c50bcb80 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 12:02:17 -0500 Subject: [PATCH 931/991] main.js: insertAfter needs non-root referenceNode --- src/librustdoc/html/static/js/main.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index edfcc1291b97..cde3909603f5 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -121,12 +121,9 @@ function getNakedUrl() { * doesn't have a parent node. * * @param {HTMLElement} newNode - * @param {HTMLElement} referenceNode + * @param {HTMLElement & { parentNode: HTMLElement }} referenceNode */ function insertAfter(newNode, referenceNode) { - // You're not allowed to pass an element with no parent. - // I dunno how to make TS's typechecker see that. - // @ts-expect-error referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } From 93161f5c14dd4f85c174ab446542063a25f6b2da Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 13:01:07 -0500 Subject: [PATCH 932/991] main.js: don't set mouseMovedAfterSearch, as it is never read --- src/librustdoc/html/static/js/main.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index cde3909603f5..bcfc2c6fabd1 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -322,7 +322,6 @@ function preLoadCss(cssUrl) { search = window.searchState.outputElement(); } switchDisplayedElement(search); - // @ts-expect-error window.searchState.mouseMovedAfterSearch = false; document.title = window.searchState.title; }, From cf7f3cf42417e9898d067536445fdee62d3d6663 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 13:24:33 -0500 Subject: [PATCH 933/991] main.js: give type signatures to a few helper functions --- src/librustdoc/html/static/js/main.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index bcfc2c6fabd1..9e98131a0072 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -322,7 +322,6 @@ function preLoadCss(cssUrl) { search = window.searchState.outputElement(); } switchDisplayedElement(search); - window.searchState.mouseMovedAfterSearch = false; document.title = window.searchState.title; }, removeQueryParameters: () => { @@ -499,17 +498,22 @@ function preLoadCss(cssUrl) { handleHashes(ev); } - // @ts-expect-error + /** + * @param {HTMLElement|null} elem + */ function openParentDetails(elem) { while (elem) { if (elem.tagName === "DETAILS") { + // @ts-expect-error elem.open = true; } - elem = elem.parentNode; + elem = elem.parentElement; } } - // @ts-expect-error + /** + * @param {string} id + */ function expandSection(id) { openParentDetails(document.getElementById(id)); } From da5da99999a81dd1e80e269a30d0f490c02ce6ab Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 13:36:12 -0500 Subject: [PATCH 934/991] main.js: handleEscape and handleShortcut accept KeyboardEvent --- src/librustdoc/html/static/js/main.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 9e98131a0072..728f47dbc4cf 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -518,7 +518,9 @@ function preLoadCss(cssUrl) { openParentDetails(document.getElementById(id)); } - // @ts-expect-error + /** + * @param {KeyboardEvent} ev + */ function handleEscape(ev) { // @ts-expect-error searchState.clearInputTimeout(); @@ -530,7 +532,9 @@ function preLoadCss(cssUrl) { window.hideAllModals(true); // true = reset focus for tooltips } - // @ts-expect-error + /** + * @param {KeyboardEvent} ev + */ function handleShortcut(ev) { // Don't interfere with browser shortcuts const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; From 6622111906f5fd0b2820263a92d23df4aba831a8 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 13:42:56 -0500 Subject: [PATCH 935/991] main.js: always refer to searchState through window.searchState --- src/librustdoc/html/static/js/main.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 728f47dbc4cf..02e4839e8e68 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -522,13 +522,10 @@ function preLoadCss(cssUrl) { * @param {KeyboardEvent} ev */ function handleEscape(ev) { - // @ts-expect-error - searchState.clearInputTimeout(); - // @ts-expect-error - searchState.hideResults(); + window.searchState.clearInputTimeout(); + window.searchState.hideResults(); ev.preventDefault(); - // @ts-expect-error - searchState.defocus(); + window.searchState.defocus(); window.hideAllModals(true); // true = reset focus for tooltips } @@ -563,8 +560,7 @@ function preLoadCss(cssUrl) { case "S": case "/": ev.preventDefault(); - // @ts-expect-error - searchState.focus(); + window.searchState.focus(); break; case "+": @@ -1699,8 +1695,7 @@ function preLoadCss(cssUrl) { addSidebarCrates(); onHashChange(null); window.addEventListener("hashchange", onHashChange); - // @ts-expect-error - searchState.setup(); + window.searchState.setup(); }()); // Hide, show, and resize the sidebar From f5efd2aba3003aff5461ce6495558a7dad0a3923 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 13:46:35 -0500 Subject: [PATCH 936/991] main.js(isDisplayed): coerce truthy values to boolean --- src/librustdoc/html/static/js/main.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 02e4839e8e68..3fdff21e591b 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -302,11 +302,10 @@ function preLoadCss(cssUrl) { window.searchState.timeout = null; } }, - // @ts-expect-error isDisplayed: () => { const outputElement = window.searchState.outputElement(); - return outputElement && - outputElement.parentElement && + return !!outputElement && + !!outputElement.parentElement && outputElement.parentElement.id === ALTERNATIVE_DISPLAY_ID; }, // Sets the focus on the search bar at the top of the page From ab180c29e36504b4faed64dbffb29fbeca71e61c Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 13:54:02 -0500 Subject: [PATCH 937/991] main.js: handle document.activeElement being null this is technically possible if someone sticks rustdoc in an iframe, i think? --- src/librustdoc/html/static/js/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 3fdff21e591b..755b999e171e 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -538,8 +538,8 @@ function preLoadCss(cssUrl) { return; } - // @ts-expect-error - if (document.activeElement.tagName === "INPUT" && + if (document.activeElement && + document.activeElement.tagName === "INPUT" && // @ts-expect-error document.activeElement.type !== "checkbox" && // @ts-expect-error From 2e1c8f088aa9b422490449a92466b71c4f115819 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 14:06:13 -0500 Subject: [PATCH 938/991] rustdoc.d.ts: window.SIDEBAR_ITEMS may exist. --- src/librustdoc/html/static/js/main.js | 1 - src/librustdoc/html/static/js/rustdoc.d.ts | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 755b999e171e..b475e6418a74 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -585,7 +585,6 @@ function preLoadCss(cssUrl) { document.addEventListener("keydown", handleShortcut); function addSidebarItems() { - // @ts-expect-error if (!window.SIDEBAR_ITEMS) { return; } diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 1554c045a327..def0bd4f71ee 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -7,6 +7,8 @@ declare global { interface Window { /** Make the current theme easy to find */ currentTheme: HTMLLinkElement|null; + /** Generated in `render/context.rs` */ + SIDEBAR_ITEMS?: { [key: string]: string[] }; /** Used by the popover tooltip code. */ RUSTDOC_TOOLTIP_HOVER_MS: number; /** Used by the popover tooltip code. */ From 749b6bf79f0fb1cfa3d2ba12f3ae2f1cf0f374d0 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 14:29:08 -0500 Subject: [PATCH 939/991] rustdoc.d.ts: add window.{register_implementors,pending_implementors} --- src/librustdoc/html/static/js/main.js | 3 --- src/librustdoc/html/static/js/rustdoc.d.ts | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index b475e6418a74..26639a85601a 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -673,7 +673,6 @@ function preLoadCss(cssUrl) { } // - // @ts-expect-error window.register_implementors = imp => { const implementors = document.getElementById("implementors-list"); const synthetic_implementors = document.getElementById("synthetic-implementors-list"); @@ -765,9 +764,7 @@ function preLoadCss(cssUrl) { } } }; - // @ts-expect-error if (window.pending_implementors) { - // @ts-expect-error window.register_implementors(window.pending_implementors); } diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index def0bd4f71ee..4504642480b3 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -44,6 +44,15 @@ declare global { * Set up event listeners for a scraped source example. */ updateScrapedExample?: function(HTMLElement, HTMLElement), + /** + * register trait implementors, called by code generated in + * `write_shared.rs` + */ + register_implementors?: function(Implementors): void, + /** + * fallback in case `register_implementors` isn't defined yet. + */ + pending_implementors?: Implementors, } interface HTMLElement { /** Used by the popover tooltip code. */ @@ -415,4 +424,12 @@ declare namespace rustdoc { }; type VlqData = VlqData[] | number; + + /** + * Maps from crate names to trait implementation data. + * Provied by generated `trait.impl` files. + */ + type Implementors = { + [key: string]: Array<[string, number, Array]> + } } From 7421546f6b35393f0ba18988c2ee8a8e973b1e8b Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 14:40:38 -0500 Subject: [PATCH 940/991] main.js: typecheck things related to window.register_type_impls --- src/librustdoc/html/static/js/main.js | 8 ++------ src/librustdoc/html/static/js/rustdoc.d.ts | 10 ++++++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 26639a85601a..5b4453b55897 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -797,16 +797,14 @@ function preLoadCss(cssUrl) { * * - After processing all of the impls, it sorts the sidebar items by name. * - * @param {{[cratename: string]: Array>}} imp + * @param {rustdoc.TypeImpls} imp */ - // @ts-expect-error window.register_type_impls = imp => { // @ts-expect-error if (!imp || !imp[window.currentCrate]) { return; } - // @ts-expect-error - window.pending_type_impls = null; + window.pending_type_impls = undefined; const idMap = new Map(); let implementations = document.getElementById("implementations-list"); @@ -992,9 +990,7 @@ function preLoadCss(cssUrl) { list.replaceChildren(...newChildren); } }; - // @ts-expect-error if (window.pending_type_impls) { - // @ts-expect-error window.register_type_impls(window.pending_type_impls); } diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 4504642480b3..4b43c00730d4 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -48,11 +48,13 @@ declare global { * register trait implementors, called by code generated in * `write_shared.rs` */ - register_implementors?: function(Implementors): void, + register_implementors?: function(rustdoc.Implementors): void, /** * fallback in case `register_implementors` isn't defined yet. */ - pending_implementors?: Implementors, + pending_implementors?: rustdoc.Implementors, + register_type_impls?: function(rustdoc.TypeImpls): void, + pending_type_impls?: rustdoc.TypeImpls, } interface HTMLElement { /** Used by the popover tooltip code. */ @@ -432,4 +434,8 @@ declare namespace rustdoc { type Implementors = { [key: string]: Array<[string, number, Array]> } + + type TypeImpls = { + [cratename: string]: Array> + } } From 20bac26165a05bb5383621ad5f65b3ae9dfdb9b4 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 10 Mar 2025 16:38:11 -0500 Subject: [PATCH 941/991] main.js: remove searchState from globals. --- src/librustdoc/html/static/js/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 5b4453b55897..4150c5609a97 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1,5 +1,5 @@ // Local js definitions: -/* global addClass, getSettingValue, hasClass, searchState, updateLocalStorage */ +/* global addClass, getSettingValue, hasClass, updateLocalStorage */ /* global onEachLazy, removeClass, getVar */ "use strict"; From 3b0c2585c8daec44877a38fd83edaf1888afe7f9 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 26 Feb 2025 20:47:53 -0800 Subject: [PATCH 942/991] Convert `ShardedHashMap` to use `hashbrown::HashTable` The `hash_raw_entry` feature has finished fcp-close, so the compiler should stop using it to allow its removal. Several `Sharded` maps were using raw entries to avoid re-hashing between shard and map lookup, and we can do that with `hashbrown::HashTable` instead. --- Cargo.lock | 2 + compiler/rustc_data_structures/Cargo.toml | 5 + compiler/rustc_data_structures/src/lib.rs | 1 - compiler/rustc_data_structures/src/marker.rs | 2 + compiler/rustc_data_structures/src/sharded.rs | 95 +++++++++++++++---- .../rustc_middle/src/mir/interpret/mod.rs | 20 +--- compiler/rustc_middle/src/ty/context.rs | 4 +- .../rustc_query_system/src/dep_graph/graph.rs | 31 +++--- compiler/rustc_query_system/src/lib.rs | 1 - .../rustc_query_system/src/query/caches.rs | 14 +-- 10 files changed, 109 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecd26d6199c9..0ae5798d78a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1491,6 +1491,7 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ + "allocator-api2", "foldhash", "serde", ] @@ -3492,6 +3493,7 @@ dependencies = [ "either", "elsa", "ena", + "hashbrown 0.15.2", "indexmap", "jobserver", "libc", diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index bdf5494f2107..b9a5fc3a1fe9 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -29,6 +29,11 @@ thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end +[dependencies.hashbrown] +version = "0.15.2" +default-features = false +features = ["nightly"] # for may_dangle + [dependencies.parking_lot] version = "0.12" diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index a3b62b469196..865424fd6bbd 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -24,7 +24,6 @@ #![feature(dropck_eyepatch)] #![feature(extend_one)] #![feature(file_buffered)] -#![feature(hash_raw_entry)] #![feature(macro_metavar_expr)] #![feature(map_try_insert)] #![feature(min_specialization)] diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 4cacc269709a..64c64bfa3c29 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -76,6 +76,7 @@ impl_dyn_send!( [crate::sync::RwLock where T: DynSend] [crate::tagged_ptr::TaggedRef<'a, P, T> where 'a, P: Sync, T: Send + crate::tagged_ptr::Tag] [rustc_arena::TypedArena where T: DynSend] + [hashbrown::HashTable where T: DynSend] [indexmap::IndexSet where V: DynSend, S: DynSend] [indexmap::IndexMap where K: DynSend, V: DynSend, S: DynSend] [thin_vec::ThinVec where T: DynSend] @@ -153,6 +154,7 @@ impl_dyn_sync!( [crate::tagged_ptr::TaggedRef<'a, P, T> where 'a, P: Sync, T: Sync + crate::tagged_ptr::Tag] [parking_lot::lock_api::Mutex where R: DynSync, T: ?Sized + DynSend] [parking_lot::lock_api::RwLock where R: DynSync, T: ?Sized + DynSend + DynSync] + [hashbrown::HashTable where T: DynSync] [indexmap::IndexSet where V: DynSync, S: DynSync] [indexmap::IndexMap where K: DynSync, V: DynSync, S: DynSync] [smallvec::SmallVec where A: smallvec::Array + DynSync] diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index 3016348f2246..49cafcb17a03 100644 --- a/compiler/rustc_data_structures/src/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs @@ -1,11 +1,11 @@ use std::borrow::Borrow; -use std::collections::hash_map::RawEntryMut; use std::hash::{Hash, Hasher}; -use std::iter; +use std::{iter, mem}; use either::Either; +use hashbrown::hash_table::{Entry, HashTable}; -use crate::fx::{FxHashMap, FxHasher}; +use crate::fx::FxHasher; use crate::sync::{CacheAligned, Lock, LockGuard, Mode, is_dyn_thread_safe}; // 32 shards is sufficient to reduce contention on an 8-core Ryzen 7 1700, @@ -140,17 +140,67 @@ pub fn shards() -> usize { 1 } -pub type ShardedHashMap = Sharded>; +pub type ShardedHashMap = Sharded>; impl ShardedHashMap { pub fn with_capacity(cap: usize) -> Self { - Self::new(|| FxHashMap::with_capacity_and_hasher(cap, rustc_hash::FxBuildHasher::default())) + Self::new(|| HashTable::with_capacity(cap)) } pub fn len(&self) -> usize { self.lock_shards().map(|shard| shard.len()).sum() } } +impl ShardedHashMap { + #[inline] + pub fn get(&self, key: &Q) -> Option + where + K: Borrow, + Q: Hash + Eq, + V: Clone, + { + let hash = make_hash(key); + let shard = self.lock_shard_by_hash(hash); + let (_, value) = shard.find(hash, |(k, _)| k.borrow() == key)?; + Some(value.clone()) + } + + #[inline] + pub fn get_or_insert_with(&self, key: K, default: impl FnOnce() -> V) -> V + where + V: Copy, + { + let hash = make_hash(&key); + let mut shard = self.lock_shard_by_hash(hash); + + match table_entry(&mut shard, hash, &key) { + Entry::Occupied(e) => e.get().1, + Entry::Vacant(e) => { + let value = default(); + e.insert((key, value)); + value + } + } + } + + #[inline] + pub fn insert(&self, key: K, value: V) -> Option { + let hash = make_hash(&key); + let mut shard = self.lock_shard_by_hash(hash); + + match table_entry(&mut shard, hash, &key) { + Entry::Occupied(e) => { + let previous = mem::replace(&mut e.into_mut().1, value); + Some(previous) + } + Entry::Vacant(e) => { + e.insert((key, value)); + None + } + } + } +} + impl ShardedHashMap { #[inline] pub fn intern_ref(&self, value: &Q, make: impl FnOnce() -> K) -> K @@ -160,13 +210,12 @@ impl ShardedHashMap { { let hash = make_hash(value); let mut shard = self.lock_shard_by_hash(hash); - let entry = shard.raw_entry_mut().from_key_hashed_nocheck(hash, value); - match entry { - RawEntryMut::Occupied(e) => *e.key(), - RawEntryMut::Vacant(e) => { + match table_entry(&mut shard, hash, value) { + Entry::Occupied(e) => e.get().0, + Entry::Vacant(e) => { let v = make(); - e.insert_hashed_nocheck(hash, v, ()); + e.insert((v, ())); v } } @@ -180,13 +229,12 @@ impl ShardedHashMap { { let hash = make_hash(&value); let mut shard = self.lock_shard_by_hash(hash); - let entry = shard.raw_entry_mut().from_key_hashed_nocheck(hash, &value); - match entry { - RawEntryMut::Occupied(e) => *e.key(), - RawEntryMut::Vacant(e) => { + match table_entry(&mut shard, hash, &value) { + Entry::Occupied(e) => e.get().0, + Entry::Vacant(e) => { let v = make(value); - e.insert_hashed_nocheck(hash, v, ()); + e.insert((v, ())); v } } @@ -203,17 +251,30 @@ impl ShardedHashMap { let hash = make_hash(&value); let shard = self.lock_shard_by_hash(hash); let value = value.into_pointer(); - shard.raw_entry().from_hash(hash, |entry| entry.into_pointer() == value).is_some() + shard.find(hash, |(k, ())| k.into_pointer() == value).is_some() } } #[inline] -pub fn make_hash(val: &K) -> u64 { +fn make_hash(val: &K) -> u64 { let mut state = FxHasher::default(); val.hash(&mut state); state.finish() } +#[inline] +fn table_entry<'a, K, V, Q>( + table: &'a mut HashTable<(K, V)>, + hash: u64, + key: &Q, +) -> Entry<'a, (K, V)> +where + K: Hash + Borrow, + Q: ?Sized + Eq, +{ + table.entry(hash, move |(k, _)| k.borrow() == key, |(k, _)| make_hash(k)) +} + /// Get a shard with a pre-computed hash value. If `get_shard_by_value` is /// ever used in combination with `get_shard_by_hash` on a single `Sharded` /// instance, then `hash` must be computed with `FxHasher`. Otherwise, diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 2675b7e0fc51..effedf854e47 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -452,12 +452,7 @@ impl<'tcx> TyCtxt<'tcx> { } let id = self.alloc_map.reserve(); debug!("creating alloc {:?} with id {id:?}", alloc_salt.0); - let had_previous = self - .alloc_map - .to_alloc - .lock_shard_by_value(&id) - .insert(id, alloc_salt.0.clone()) - .is_some(); + let had_previous = self.alloc_map.to_alloc.insert(id, alloc_salt.0.clone()).is_some(); // We just reserved, so should always be unique. assert!(!had_previous); dedup.insert(alloc_salt, id); @@ -510,7 +505,7 @@ impl<'tcx> TyCtxt<'tcx> { /// local dangling pointers and allocations in constants/statics. #[inline] pub fn try_get_global_alloc(self, id: AllocId) -> Option> { - self.alloc_map.to_alloc.lock_shard_by_value(&id).get(&id).cloned() + self.alloc_map.to_alloc.get(&id) } #[inline] @@ -529,9 +524,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to /// call this function twice, even with the same `Allocation` will ICE the compiler. pub fn set_alloc_id_memory(self, id: AllocId, mem: ConstAllocation<'tcx>) { - if let Some(old) = - self.alloc_map.to_alloc.lock_shard_by_value(&id).insert(id, GlobalAlloc::Memory(mem)) - { + if let Some(old) = self.alloc_map.to_alloc.insert(id, GlobalAlloc::Memory(mem)) { bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}"); } } @@ -539,11 +532,8 @@ impl<'tcx> TyCtxt<'tcx> { /// Freezes an `AllocId` created with `reserve` by pointing it at a static item. Trying to /// call this function twice, even with the same `DefId` will ICE the compiler. pub fn set_nested_alloc_id_static(self, id: AllocId, def_id: LocalDefId) { - if let Some(old) = self - .alloc_map - .to_alloc - .lock_shard_by_value(&id) - .insert(id, GlobalAlloc::Static(def_id.to_def_id())) + if let Some(old) = + self.alloc_map.to_alloc.insert(id, GlobalAlloc::Static(def_id.to_def_id())) { bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}"); } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index edba2a2530f6..70bb902d1ae7 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2336,8 +2336,8 @@ macro_rules! sty_debug_print { $(let mut $variant = total;)* for shard in tcx.interners.type_.lock_shards() { - let types = shard.keys(); - for &InternedInSet(t) in types { + let types = shard.iter(); + for &(InternedInSet(t), ()) in types { let variant = match t.internee { ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Str | ty::Never => continue, diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 6ece01c211ba..3109d53cd2ca 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1,5 +1,4 @@ use std::assert_matches::assert_matches; -use std::collections::hash_map::Entry; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; @@ -9,7 +8,7 @@ use std::sync::atomic::{AtomicU32, Ordering}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::{QueryInvocationId, SelfProfilerRef}; -use rustc_data_structures::sharded::{self, Sharded}; +use rustc_data_structures::sharded::{self, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU64, Lock}; use rustc_data_structures::unord::UnordMap; @@ -619,7 +618,7 @@ impl DepGraphData { if let Some(prev_index) = self.previous.node_to_index_opt(dep_node) { self.current.prev_index_to_index.lock()[prev_index] } else { - self.current.new_node_to_index.lock_shard_by_value(dep_node).get(dep_node).copied() + self.current.new_node_to_index.get(dep_node) } } @@ -1048,7 +1047,7 @@ rustc_index::newtype_index! { /// first, and `data` second. pub(super) struct CurrentDepGraph { encoder: GraphEncoder, - new_node_to_index: Sharded>, + new_node_to_index: ShardedHashMap, prev_index_to_index: Lock>>, /// This is used to verify that fingerprints do not change between the creation of a node @@ -1117,12 +1116,9 @@ impl CurrentDepGraph { profiler, previous, ), - new_node_to_index: Sharded::new(|| { - FxHashMap::with_capacity_and_hasher( - new_node_count_estimate / sharded::shards(), - Default::default(), - ) - }), + new_node_to_index: ShardedHashMap::with_capacity( + new_node_count_estimate / sharded::shards(), + ), prev_index_to_index: Lock::new(IndexVec::from_elem_n(None, prev_graph_node_count)), anon_id_seed, #[cfg(debug_assertions)] @@ -1152,14 +1148,9 @@ impl CurrentDepGraph { edges: EdgesVec, current_fingerprint: Fingerprint, ) -> DepNodeIndex { - let dep_node_index = match self.new_node_to_index.lock_shard_by_value(&key).entry(key) { - Entry::Occupied(entry) => *entry.get(), - Entry::Vacant(entry) => { - let dep_node_index = self.encoder.send(key, current_fingerprint, edges); - entry.insert(dep_node_index); - dep_node_index - } - }; + let dep_node_index = self + .new_node_to_index + .get_or_insert_with(key, || self.encoder.send(key, current_fingerprint, edges)); #[cfg(debug_assertions)] self.record_edge(dep_node_index, key, current_fingerprint); @@ -1257,7 +1248,7 @@ impl CurrentDepGraph { ) { let node = &prev_graph.index_to_node(prev_index); debug_assert!( - !self.new_node_to_index.lock_shard_by_value(node).contains_key(node), + !self.new_node_to_index.get(node).is_some(), "node from previous graph present in new node collection" ); } @@ -1382,7 +1373,7 @@ fn panic_on_forbidden_read(data: &DepGraphData, dep_node_index: DepN if dep_node.is_none() { // Try to find it among the new nodes for shard in data.current.new_node_to_index.lock_shards() { - if let Some((node, _)) = shard.iter().find(|(_, index)| **index == dep_node_index) { + if let Some((node, _)) = shard.iter().find(|(_, index)| *index == dep_node_index) { dep_node = Some(*node); break; } diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index ee984095ad84..41ebf2d5ac76 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -3,7 +3,6 @@ #![feature(assert_matches)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] -#![feature(hash_raw_entry)] #![feature(let_chains)] #![feature(min_specialization)] #![warn(unreachable_pub)] diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 3b47e7eba0ff..30b5d7e59549 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -2,8 +2,7 @@ use std::fmt::Debug; use std::hash::Hash; use std::sync::OnceLock; -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sharded::{self, Sharded}; +use rustc_data_structures::sharded::ShardedHashMap; pub use rustc_data_structures::vec_cache::VecCache; use rustc_hir::def_id::LOCAL_CRATE; use rustc_index::Idx; @@ -36,7 +35,7 @@ pub trait QueryCache: Sized { /// In-memory cache for queries whose keys aren't suitable for any of the /// more specialized kinds of cache. Backed by a sharded hashmap. pub struct DefaultCache { - cache: Sharded>, + cache: ShardedHashMap, } impl Default for DefaultCache { @@ -55,19 +54,14 @@ where #[inline(always)] fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> { - let key_hash = sharded::make_hash(key); - let lock = self.cache.lock_shard_by_hash(key_hash); - let result = lock.raw_entry().from_key_hashed_nocheck(key_hash, key); - - if let Some((_, value)) = result { Some(*value) } else { None } + self.cache.get(key) } #[inline] fn complete(&self, key: K, value: V, index: DepNodeIndex) { - let mut lock = self.cache.lock_shard_by_value(&key); // We may be overwriting another value. This is all right, since the dep-graph // will check that the fingerprint matches. - lock.insert(key, (value, index)); + self.cache.insert(key, (value, index)); } fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { From 32afef411b159e8a85a4039089d9165de515a08d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Mar 2025 12:11:04 +1100 Subject: [PATCH 943/991] Remove unnecessary `[lints.rust]` sections. `bootstrap` and `llvm_enzyme` are now both in the extra `check-cfg` list in bootstrap, so they doesn't need to be handled explicitly in `Cargo.toml` files. --- compiler/rustc_builtin_macros/Cargo.toml | 4 ---- compiler/rustc_type_ir/Cargo.toml | 3 --- 2 files changed, 7 deletions(-) diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index b5f4f2efd1f5..1289d21308b7 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -3,10 +3,6 @@ name = "rustc_builtin_macros" version = "0.0.0" edition = "2024" - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(llvm_enzyme)'] } - [lib] doctest = false diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 7b2593b96e37..4adf71579266 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -33,6 +33,3 @@ nightly = [ "rustc_index/nightly", "rustc_ast_ir/nightly", ] - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } From 336a327f7c347ea96192633825892d6ae5e3e2ac Mon Sep 17 00:00:00 2001 From: Arjun Ramesh Date: Tue, 2 Jul 2024 18:19:42 -0400 Subject: [PATCH 944/991] Target definition for `wasm32-wali-linux-musl` to support the Wasm Linux Interface This commit does not patch libc, stdarch, or cc --- .../rustc_target/src/spec/base/linux_wasm.rs | 159 ++++++++++++++++++ compiler/rustc_target/src/spec/base/mod.rs | 1 + compiler/rustc_target/src/spec/mod.rs | 1 + .../spec/targets/wasm32_wali_linux_musl.rs | 29 ++++ library/core/src/ffi/primitives.rs | 5 +- library/unwind/src/libunwind.rs | 5 +- src/bootstrap/configure.py | 5 + src/bootstrap/src/core/build_steps/compile.rs | 48 ++++-- src/bootstrap/src/core/sanity.rs | 1 + src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 1 + .../src/platform-support/wasm32-wali-linux.md | 98 +++++++++++ tests/assembly/targets/targets-elf.rs | 3 + tests/run-make/musl-default-linking/rmake.rs | 15 +- 14 files changed, 352 insertions(+), 20 deletions(-) create mode 100644 compiler/rustc_target/src/spec/base/linux_wasm.rs create mode 100644 compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs create mode 100644 src/doc/rustc/src/platform-support/wasm32-wali-linux.md diff --git a/compiler/rustc_target/src/spec/base/linux_wasm.rs b/compiler/rustc_target/src/spec/base/linux_wasm.rs new file mode 100644 index 000000000000..a8c137c22a97 --- /dev/null +++ b/compiler/rustc_target/src/spec/base/linux_wasm.rs @@ -0,0 +1,159 @@ +//! This target is a confluence of Linux and Wasm models, inheriting most +//! aspects from their respective base targets + +use crate::spec::{ + Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel, + add_link_args, crt_objects, cvs, +}; + +pub(crate) fn opts() -> TargetOptions { + macro_rules! args { + ($prefix:literal) => { + &[ + // By default LLD only gives us one page of stack (64k) which is a + // little small. Default to a larger stack closer to other PC platforms + // (1MB) and users can always inject their own link-args to override this. + concat!($prefix, "-z"), + concat!($prefix, "stack-size=1048576"), + // By default LLD's memory layout is: + // + // 1. First, a blank page + // 2. Next, all static data + // 3. Finally, the main stack (which grows down) + // + // This has the unfortunate consequence that on stack overflows you + // corrupt static data and can cause some exceedingly weird bugs. To + // help detect this a little sooner we instead request that the stack is + // placed before static data. + // + // This means that we'll generate slightly larger binaries as references + // to static data will take more bytes in the ULEB128 encoding, but + // stack overflow will be guaranteed to trap as it underflows instead of + // corrupting static data. + concat!($prefix, "--stack-first"), + // FIXME we probably shouldn't pass this but instead pass an explicit list + // of symbols we'll allow to be undefined. We don't currently have a + // mechanism of knowing, however, which symbols are intended to be imported + // from the environment and which are intended to be imported from other + // objects linked elsewhere. This is a coarse approximation but is sure to + // hide some bugs and frustrate someone at some point, so we should ideally + // work towards a world where we can explicitly list symbols that are + // supposed to be imported and have all other symbols generate errors if + // they remain undefined. + concat!($prefix, "--allow-undefined"), + // LLD only implements C++-like demangling, which doesn't match our own + // mangling scheme. Tell LLD to not demangle anything and leave it up to + // us to demangle these symbols later. Currently rustc does not perform + // further demangling, but tools like twiggy and wasm-bindgen are intended + // to do so. + concat!($prefix, "--no-demangle"), + ] + }; + } + + let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!("")); + add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")); + + TargetOptions { + is_like_wasm: true, + families: cvs!["wasm", "unix"], + os: "linux".into(), + env: "musl".into(), + + // we allow dynamic linking, but only cdylibs. Basically we allow a + // final library artifact that exports some symbols (a wasm module) but + // we don't allow intermediate `dylib` crate types + dynamic_linking: true, + only_cdylib: true, + + // relatively self-explanatory! + exe_suffix: ".wasm".into(), + dll_prefix: "".into(), + dll_suffix: ".wasm".into(), + eh_frame_header: false, + + max_atomic_width: Some(64), + + // Unwinding doesn't work right now, so the whole target unconditionally + // defaults to panic=abort. Note that this is guaranteed to change in + // the future once unwinding is implemented. Don't rely on this as we're + // basically guaranteed to change it once WebAssembly supports + // exceptions. + panic_strategy: PanicStrategy::Abort, + + // Symbol visibility takes care of this for the WebAssembly. + // Additionally the only known linker, LLD, doesn't support the script + // arguments just yet + limit_rdylib_exports: false, + + // we use the LLD shipped with the Rust toolchain by default + linker: Some("rust-lld".into()), + linker_flavor: LinkerFlavor::WasmLld(Cc::No), + + pre_link_args, + + // FIXME: Figure out cases in which WASM needs to link with a native toolchain. + // + // rust-lang/rust#104137: cannot blindly remove this without putting in + // some other way to compensate for lack of `-nostartfiles` in linker + // invocation. + link_self_contained: LinkSelfContainedDefault::True, + pre_link_objects_self_contained: crt_objects::pre_wasi_self_contained(), + post_link_objects_self_contained: crt_objects::post_wasi_self_contained(), + + // This has no effect in LLVM 8 or prior, but in LLVM 9 and later when + // PIC code is implemented this has quite a drastic effect if it stays + // at the default, `pic`. In an effort to keep wasm binaries as minimal + // as possible we're defaulting to `static` for now, but the hope is + // that eventually we can ship a `pic`-compatible standard library which + // works with `static` as well (or works with some method of generating + // non-relative calls and such later on). + relocation_model: RelocModel::Static, + + // When the atomics feature is activated then these two keys matter, + // otherwise they're basically ignored by the standard library. In this + // mode, however, the `#[thread_local]` attribute works (i.e. + // `has_thread_local`) and we need to get it to work by specifying + // `local-exec` as that's all that's implemented in LLVM today for wasm. + has_thread_local: true, + tls_model: TlsModel::LocalExec, + + // Supporting Linux requires multithreading supported by Wasm's thread + // proposal + singlethread: false, + + // gdb scripts don't work on wasm blobs + emit_debug_gdb_scripts: false, + + // There's more discussion of this at + // https://bugs.llvm.org/show_bug.cgi?id=52442 but the general result is + // that this isn't useful for wasm and has tricky issues with + // representation, so this is disabled. + generate_arange_section: false, + + // Right now this is a bit of a workaround but we're currently saying that + // the target by default has a static crt which we're taking as a signal + // for "use the bundled crt". If that's turned off then the system's crt + // will be used, but this means that default usage of this target doesn't + // need an external compiler but it's still interoperable with an external + // compiler if configured correctly. + crt_static_default: true, + crt_static_respected: true, + + // Allow `+crt-static` to create a "cdylib" output which is just a wasm file + // without a main function. + crt_static_allows_dylibs: true, + + // Wasm start ignores arguments -- relies on API call from interface. + main_needs_argc_argv: false, + + // Wasm toolchains mangle the name of "main" to distinguish between different + // signatures. + entry_name: "__main_void".into(), + + // Wasm Feature flags for supporting Linux + features: "+atomics,+bulk-memory,+mutable-globals,+sign-ext".into(), + + ..Default::default() + } +} diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs index 6f88be5d37f1..e8fdc8717853 100644 --- a/compiler/rustc_target/src/spec/base/mod.rs +++ b/compiler/rustc_target/src/spec/base/mod.rs @@ -18,6 +18,7 @@ pub(crate) mod linux_gnu; pub(crate) mod linux_musl; pub(crate) mod linux_ohos; pub(crate) mod linux_uclibc; +pub(crate) mod linux_wasm; pub(crate) mod msvc; pub(crate) mod netbsd; pub(crate) mod nto_qnx; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 15936c731ea6..1887134c5757 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1924,6 +1924,7 @@ supported_targets! { ("wasm32-wasip1", wasm32_wasip1), ("wasm32-wasip2", wasm32_wasip2), ("wasm32-wasip1-threads", wasm32_wasip1_threads), + ("wasm32-wali-linux-musl", wasm32_wali_linux_musl), ("wasm64-unknown-unknown", wasm64_unknown_unknown), ("thumbv6m-none-eabi", thumbv6m_none_eabi), diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs b/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs new file mode 100644 index 000000000000..a0eb4a254fc0 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs @@ -0,0 +1,29 @@ +//! The `wasm32-wali-linux-musl` target is a wasm32 target compliant with the +//! [WebAssembly Linux Interface](https://github.com/arjunr2/WALI). + +use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base}; + +pub(crate) fn target() -> Target { + let mut options = base::linux_wasm::opts(); + + options + .add_pre_link_args(LinkerFlavor::WasmLld(Cc::No), &["--export-memory", "--shared-memory"]); + options.add_pre_link_args( + LinkerFlavor::WasmLld(Cc::Yes), + &["--target=wasm32-wasi-threads", "-Wl,--export-memory,", "-Wl,--shared-memory"], + ); + + Target { + llvm_target: "wasm32-wasi".into(), + metadata: TargetMetadata { + description: Some("WebAssembly Linux Interface with musl-libc".into()), + tier: Some(3), + host_tools: Some(false), + std: None, + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20".into(), + arch: "wasm32".into(), + options, + } +} diff --git a/library/core/src/ffi/primitives.rs b/library/core/src/ffi/primitives.rs index 6495e61b346f..0a70eb4da552 100644 --- a/library/core/src/ffi/primitives.rs +++ b/library/core/src/ffi/primitives.rs @@ -133,7 +133,10 @@ mod c_char_definition { mod c_long_definition { cfg_if! { - if #[cfg(all(target_pointer_width = "64", not(windows)))] { + if #[cfg(any( + all(target_pointer_width = "64", not(windows)), + // wasm32 Linux ABI uses 64-bit long + all(target_arch = "wasm32", target_os = "linux")))] { pub(super) type c_long = i64; pub(super) type c_ulong = u64; } else { diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 1a640bbde71d..ced8e82b8ebe 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -72,9 +72,12 @@ pub const unwinder_private_data_size: usize = 2; #[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))] pub const unwinder_private_data_size: usize = 2; -#[cfg(target_os = "emscripten")] +#[cfg(all(target_arch = "wasm32", target_os = "emscripten"))] pub const unwinder_private_data_size: usize = 20; +#[cfg(all(target_arch = "wasm32", target_os = "linux"))] +pub const unwinder_private_data_size: usize = 2; + #[cfg(all(target_arch = "hexagon", target_os = "linux"))] pub const unwinder_private_data_size: usize = 35; diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index c3b256464396..77151edd240b 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -269,6 +269,11 @@ v( "target.loongarch64-unknown-linux-musl.musl-root", "loongarch64-unknown-linux-musl install directory", ) +v( + "musl-root-wali-wasm32", + "target.wasm32-wali-linux-musl.musl-root", + "wasm32-wali-linux-musl install directory", +) v( "qemu-armhf-rootfs", "target.arm-unknown-linux-gnueabihf.qemu-rootfs", diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 319a2233b1c7..8cb3e3ed8729 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -390,24 +390,38 @@ fn copy_self_contained_objects( let srcdir = builder.musl_libdir(target).unwrap_or_else(|| { panic!("Target {:?} does not have a \"musl-libdir\" key", target.triple) }); - for &obj in &["libc.a", "crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] { - copy_and_stamp( - builder, - &libdir_self_contained, - &srcdir, - obj, - &mut target_deps, - DependencyType::TargetSelfContained, - ); + if !target.starts_with("wasm32") { + for &obj in &["libc.a", "crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] { + copy_and_stamp( + builder, + &libdir_self_contained, + &srcdir, + obj, + &mut target_deps, + DependencyType::TargetSelfContained, + ); + } + let crt_path = builder.ensure(llvm::CrtBeginEnd { target }); + for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { + let src = crt_path.join(obj); + let target = libdir_self_contained.join(obj); + builder.copy_link(&src, &target); + target_deps.push((target, DependencyType::TargetSelfContained)); + } + } else { + // For wasm32 targets, we need to copy the libc.a and crt1-command.o files from the + // musl-libdir, but we don't need the other files. + for &obj in &["libc.a", "crt1-command.o"] { + copy_and_stamp( + builder, + &libdir_self_contained, + &srcdir, + obj, + &mut target_deps, + DependencyType::TargetSelfContained, + ); + } } - let crt_path = builder.ensure(llvm::CrtBeginEnd { target }); - for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { - let src = crt_path.join(obj); - let target = libdir_self_contained.join(obj); - builder.copy_link(&src, &target); - target_deps.push((target, DependencyType::TargetSelfContained)); - } - if !target.starts_with("s390x") { let libunwind_path = copy_llvm_libunwind(builder, target, &libdir_self_contained); target_deps.push((libunwind_path, DependencyType::TargetSelfContained)); diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index fdac7f3cb179..583b8e1198ae 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -34,6 +34,7 @@ pub struct Finder { // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined + "wasm32-wali-linux-musl", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index b1d7e5421c1b..2595a1051429 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -97,6 +97,7 @@ - [wasm32-wasip1](platform-support/wasm32-wasip1.md) - [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md) - [wasm32-wasip2](platform-support/wasm32-wasip2.md) + - [wasm32-wali-linux-musl](platform-support/wasm32-wali-linux.md) - [wasm32-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md) - [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md) - [wasm32v1-none](platform-support/wasm32v1-none.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index f78ab151b9c2..5e5c3fe1b802 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -404,6 +404,7 @@ target | std | host | notes [`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX [`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly +[`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI) [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator [`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ? | | 64-bit x86 Cygwin | diff --git a/src/doc/rustc/src/platform-support/wasm32-wali-linux.md b/src/doc/rustc/src/platform-support/wasm32-wali-linux.md new file mode 100644 index 000000000000..0c46ea2c01da --- /dev/null +++ b/src/doc/rustc/src/platform-support/wasm32-wali-linux.md @@ -0,0 +1,98 @@ +# `wasm32-wali-linux-*` + +**Tier: 3** + +WebAssembly targets that use the [WebAssembly Linux Interface (WALI)](https://github.com/arjunr2/WALI) with 32-bit memory. The latest status of the WALI specification and support are documented within the repo. + +WALI offers seamless targetability of traditional Linux applications to Wasm by exposing Linux syscalls strategically into the sandbox. Numerous applications and build system work unmodified over WALI, including complex low-level system libraries -- a list of applications are included in the research paper linked in the main repo. + +From the wider Wasm ecosystem perspective, implementing WALI within engines allows layering of high-level security policies (e.g. WASI) above it, arming the latter's implementations with sandboxing and portability. + +## Target maintainers + +- Arjun Ramesh [@arjunr2](https://github.com/arjunr2) + +## Requirements + +### Compilation +This target is cross-compiled and requires an installation of the [WALI compiler/sysroot](https://github.com/arjunr2/WALI). This produces standard `wasm32` binaries with the WALI interface methods as module imports that need to be implemented by a supported engine (see the "Execution" section below). + +`wali` targets *minimally require* the following LLVM feature flags: + +* [Bulk memory] - `+bulk-memory` +* Mutable imported globals - `+mutable-globals` +* [Sign-extending operations] - `+sign-ext` +* [Threading/Atomics] - `+atomics` + +[Bulk memory]: https://github.com/WebAssembly/spec/blob/main/proposals/bulk-memory-operations/Overview.md +[Sign-extending operations]: https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md +[Threading/Atomics]: https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md + +> **Note**: Users can expect that new enabled-by-default Wasm features for LLVM are transitively incorporatable into this target -- see [wasm32-unknown-unknown](wasm32-unknown-unknown.md) for detailed information on WebAssembly features. + + +> **Note**: The WALI ABI is similar to default Clang wasm32 ABIs but *not identical*. The primary difference is 64-bit `long` types as opposed to 32-bit for wasm32. This is required to mantain minimum source code changes for 64-bit host platforms currently supported. This may change in the future as the spec evolves. + +### Execution +Running generated WALI binaries also requires a supported compliant engine implementation -- a working implementation in the [WebAssembly Micro-Runtime (WAMR)](https://github.com/arjunr2/WALI) is included in the repo. + +> **Note**: WALI is still somewhat experimental and bugs may exist in the Rust support, WALI toolchain, or the LLVM compiler. The former can be filed in Rust repos while the latter two in the WALI repo. + +## Building the target + +You can build Rust with support for the target by adding it to the `target` +list in `config.toml`, and pointing to the toolchain artifacts from the previous section ("Requirements->Compilation"). A sample `config.toml` for the `musl` environment will look like this, where `` is the absolute path to the root directory of the [WALI repo](https://github.com/arjunr2/WALI): + +```toml +[build] +target = ["wasm32-wali-linux-musl"] + +[target.wasm32-wali-linux-musl] +musl-root = "/wali-musl/sysroot" +llvm-config = "/llvm-project/build/bin/llvm-config" +cc = "/llvm-project/build/bin/clang-18" +cxx = "/llvm-project/build/bin/clang-18" +ar = "/llvm-project/build/bin/llvm-ar" +ranlib = "/llvm-project/build/bin/llvm-ranlib" +llvm-libunwind = "system" +crt-static = true +``` + +> The `llvm-config` settings are only temporary, and the changes will eventually be upstreamed into LLVM + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +Rust program builds can use this target normally. Currently, linking WALI programs may require pointing the `linker` to the llvm build in the [Cargo config](https://doc.rust-lang.org/cargo/reference/config.html) (until LLVM is upstreamed). A `config.toml` for Cargo will look like the following: + +```toml +[target.wasm32-wali-linux-musl] +linker = "/llvm-project/build/bin/lld" +``` + +Note that the following `cfg` directives are set for `wasm32-wali-linux-*`: + +* `cfg(target_arch = "wasm32")` +* `cfg(target_family = {"wasm", "unix"})` +* `cfg(target_r = "wasm")` +* `cfg(target_os = "linux")` +* `cfg(target_env = *)` + +### Restrictions + +Hardware or platform-specific support, besides `syscall` is mostly unsupported in WALI for ISA portability (these tend to be uncommon). + +## Testing + +Currently testing is not supported for `wali` targets and the Rust project doesn't run any tests for this target. + +However, standard ISA-agnostic tests for Linux should be thereotically reusable for WALI targets and minor changes. Testing integration will be continually incorporated as support evolves. + + +## Cross-compilation toolchains and C code + +Most fully featured C code is compilable with the WALI toolchain -- examples can be seen in the repo. diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index dc564c60f807..8f2fef0e9c91 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -559,6 +559,9 @@ //@ revisions: wasm32_wasip2 //@ [wasm32_wasip2] compile-flags: --target wasm32-wasip2 //@ [wasm32_wasip2] needs-llvm-components: webassembly +//@ revisions: wasm32_wali_linux_musl +//@ [wasm32_wali_linux_musl] compile-flags: --target wasm32-wali-linux-musl +//@ [wasm32_wali_linux_musl] needs-llvm-components: webassembly //@ revisions: wasm64_unknown_unknown //@ [wasm64_unknown_unknown] compile-flags: --target wasm64-unknown-unknown //@ [wasm64_unknown_unknown] needs-llvm-components: webassembly diff --git a/tests/run-make/musl-default-linking/rmake.rs b/tests/run-make/musl-default-linking/rmake.rs index d203595a4474..017444cfcddc 100644 --- a/tests/run-make/musl-default-linking/rmake.rs +++ b/tests/run-make/musl-default-linking/rmake.rs @@ -45,8 +45,21 @@ fn main() { let target_spec: serde_json::Value = serde_json::from_str(&target_spec_json).expect("failed to parse target-spec-json"); - let default = &target_spec["crt-static-default"]; + let target_families = &target_spec["target-family"]; + // WebAssembly doesn't support dynamic linking yet; all musl targets + // need to be statically linked. + if target_families + .as_array() + .expect("target-family wasn't an array") + .iter() + .filter_map(|x| x.as_str()) + .any(|family| family == "wasm") + { + continue; + } + + let default = &target_spec["crt-static-default"]; // If the value is `null`, then the default to dynamically link from // musl_base was not overridden. if default.is_null() { From c9c838795554901fa22ad14c2d34f270567aaa27 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Mar 2025 11:46:54 +1100 Subject: [PATCH 945/991] Use `RUSTC_LINT_FLAGS` more. For the `Mode::Rustc` lints as well. Because, unlike `RUSTC_FLAGS`, `RUSTC_LINT_FLAGS` is not ignored for proc macro crates. Fixes #138106. --- src/bootstrap/src/core/builder/cargo.rs | 37 +++++++++++++++---------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 12dd40d14e9b..1308a0694f7d 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -1045,8 +1045,11 @@ impl Builder<'_> { // so this line allows the use of custom libcs. cargo.env("LIBC_CHECK_CFG", "1"); + let mut lint_flags = Vec::new(); + + // Lints for all in-tree code: compiler, rustdoc, cranelift, gcc, + // clippy, rustfmt, rust-analyzer, etc. if source_type == SourceType::InTree { - let mut lint_flags = Vec::new(); // When extending this list, add the new lints to the RUSTFLAGS of the // build_bootstrap function of src/bootstrap/bootstrap.py as well as // some code doesn't go through this `rustc` wrapper. @@ -1058,28 +1061,32 @@ impl Builder<'_> { rustdocflags.arg("-Dwarnings"); } - // This does not use RUSTFLAGS due to caching issues with Cargo. - // Clippy is treated as an "in tree" tool, but shares the same - // cache as other "submodule" tools. With these options set in - // RUSTFLAGS, that causes *every* shared dependency to be rebuilt. - // By injecting this into the rustc wrapper, this circumvents - // Cargo's fingerprint detection. This is fine because lint flags - // are always ignored in dependencies. Eventually this should be - // fixed via better support from Cargo. - cargo.env("RUSTC_LINT_FLAGS", lint_flags.join(" ")); - rustdocflags.arg("-Wrustdoc::invalid_codeblock_attributes"); } + // Lints just for `compiler/` crates. if mode == Mode::Rustc { - rustflags.arg("-Wrustc::internal"); - rustflags.arg("-Drustc::symbol_intern_string_literal"); + lint_flags.push("-Wrustc::internal"); + lint_flags.push("-Drustc::symbol_intern_string_literal"); // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all // of the individual lints are satisfied. - rustflags.arg("-Wkeyword_idents_2024"); - rustflags.arg("-Wunsafe_op_in_unsafe_fn"); + lint_flags.push("-Wkeyword_idents_2024"); + lint_flags.push("-Wunsafe_op_in_unsafe_fn"); } + // This does not use RUSTFLAGS for two reasons. + // - Due to caching issues with Cargo. Clippy is treated as an "in + // tree" tool, but shares the same cache as other "submodule" tools. + // With these options set in RUSTFLAGS, that causes *every* shared + // dependency to be rebuilt. By injecting this into the rustc + // wrapper, this circumvents Cargo's fingerprint detection. This is + // fine because lint flags are always ignored in dependencies. + // Eventually this should be fixed via better support from Cargo. + // - RUSTFLAGS is ignored for proc macro crates that are being built on + // the host (because `--target` is given). But we want the lint flags + // to be applied to proc macro crates. + cargo.env("RUSTC_LINT_FLAGS", lint_flags.join(" ")); + if self.config.rust_frame_pointers { rustflags.arg("-Cforce-frame-pointers=true"); } From 55505ab1d3da2ad201303674cb6d3ebeb53e395d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Mar 2025 11:51:07 +1100 Subject: [PATCH 946/991] Add `unreachable_pub` to `RUSTC_LINT_FLAGS` for `compiler/` crates. And fix the new errors in the handful of crates that didn't have a `#![warn(unreachable_pub)]`. --- compiler/rustc_baked_icu_data/src/lib.rs | 1 + compiler/rustc_data_structures/src/graph/tests.rs | 4 ++-- .../src/obligation_forest/mod.rs | 2 +- compiler/rustc_data_structures/src/sync.rs | 2 +- .../rustc_data_structures/src/sync/parallel.rs | 2 +- .../rustc_data_structures/src/tagged_ptr/tests.rs | 2 +- compiler/rustc_index_macros/src/newtype.rs | 2 +- .../rustc_pattern_analysis/tests/common/mod.rs | 14 +++++++------- src/bootstrap/src/core/builder/cargo.rs | 1 + 9 files changed, 16 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs index f86a9db61c60..f3f6522f5758 100644 --- a/compiler/rustc_baked_icu_data/src/lib.rs +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -23,6 +23,7 @@ // tidy-alphabetical-start #![allow(elided_lifetimes_in_paths)] #![allow(internal_features)] +#![allow(unreachable_pub)] // because this crate is mostly generated code #![doc(rust_logo)] #![feature(rustdoc_internals)] // #![warn(unreachable_pub)] // don't use because this crate is mostly generated code diff --git a/compiler/rustc_data_structures/src/graph/tests.rs b/compiler/rustc_data_structures/src/graph/tests.rs index b69b9dbc4a8e..e48b9686c260 100644 --- a/compiler/rustc_data_structures/src/graph/tests.rs +++ b/compiler/rustc_data_structures/src/graph/tests.rs @@ -3,7 +3,7 @@ use std::cmp::max; use super::*; use crate::fx::FxHashMap; -pub struct TestGraph { +pub(super) struct TestGraph { num_nodes: usize, start_node: usize, successors: FxHashMap>, @@ -11,7 +11,7 @@ pub struct TestGraph { } impl TestGraph { - pub fn new(start_node: usize, edges: &[(usize, usize)]) -> Self { + pub(super) fn new(start_node: usize, edges: &[(usize, usize)]) -> Self { let mut graph = TestGraph { num_nodes: start_node + 1, start_node, diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index 78d69a66edc8..8d19fc5f9ccf 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -313,7 +313,7 @@ pub struct Error { mod helper { use super::*; - pub type ObligationTreeIdGenerator = impl Iterator; + pub(super) type ObligationTreeIdGenerator = impl Iterator; impl ObligationForest { pub fn new() -> ObligationForest { ObligationForest { diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index a1cc75c49850..616a18a72ab7 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -88,7 +88,7 @@ mod mode { // Whether thread safety might be enabled. #[inline] - pub fn might_be_dyn_thread_safe() -> bool { + pub(super) fn might_be_dyn_thread_safe() -> bool { DYN_THREAD_SAFE_MODE.load(Ordering::Relaxed) != DYN_NOT_THREAD_SAFE } diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index 1ba631b86237..8ef8a3f35856 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs @@ -46,7 +46,7 @@ pub fn parallel_guard(f: impl FnOnce(&ParallelGuard) -> R) -> R { ret } -pub fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) +fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) where A: FnOnce() -> RA, B: FnOnce() -> RB, diff --git a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs index 9c1e4cefa692..85b21a7c8ecd 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs @@ -7,7 +7,7 @@ use crate::stable_hasher::{HashStable, StableHasher}; /// A tag type used in [`TaggedRef`] tests. #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Tag2 { +enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs index 67ec77611339..f0b58eabbff9 100644 --- a/compiler/rustc_index_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs @@ -305,7 +305,7 @@ impl Parse for Newtype { } } -pub fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub(crate) fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as Newtype); input.0.into() } diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs index 365bc2d863f4..8980b644f59b 100644 --- a/compiler/rustc_pattern_analysis/tests/common/mod.rs +++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs @@ -5,7 +5,7 @@ use rustc_pattern_analysis::usefulness::{PlaceValidity, UsefulnessReport}; use rustc_pattern_analysis::{MatchArm, PatCx, PrivateUninhabitedField}; /// Sets up `tracing` for easier debugging. Tries to look like the `rustc` setup. -pub fn init_tracing() { +fn init_tracing() { use tracing_subscriber::Layer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; @@ -24,7 +24,7 @@ pub fn init_tracing() { /// A simple set of types. #[allow(dead_code)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum Ty { +pub(super) enum Ty { /// Booleans Bool, /// 8-bit unsigned integers @@ -41,7 +41,7 @@ pub enum Ty { /// The important logic. impl Ty { - pub fn sub_tys(&self, ctor: &Constructor) -> Vec { + pub(super) fn sub_tys(&self, ctor: &Constructor) -> Vec { use Constructor::*; match (ctor, *self) { (Struct, Ty::Tuple(tys)) => tys.iter().copied().collect(), @@ -63,7 +63,7 @@ impl Ty { } } - pub fn ctor_set(&self) -> ConstructorSet { + fn ctor_set(&self) -> ConstructorSet { match *self { Ty::Bool => ConstructorSet::Bool, Ty::U8 => ConstructorSet::Integers { @@ -104,7 +104,7 @@ impl Ty { } } - pub fn write_variant_name( + fn write_variant_name( &self, f: &mut std::fmt::Formatter<'_>, ctor: &Constructor, @@ -120,7 +120,7 @@ impl Ty { } /// Compute usefulness in our simple context (and set up tracing for easier debugging). -pub fn compute_match_usefulness<'p>( +pub(super) fn compute_match_usefulness<'p>( arms: &[MatchArm<'p, Cx>], ty: Ty, scrut_validity: PlaceValidity, @@ -137,7 +137,7 @@ pub fn compute_match_usefulness<'p>( } #[derive(Debug)] -pub struct Cx; +pub(super) struct Cx; /// The context for pattern analysis. Forwards anything interesting to `Ty` methods. impl PatCx for Cx { diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 1308a0694f7d..62d23c4ae6b2 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -1071,6 +1071,7 @@ impl Builder<'_> { // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all // of the individual lints are satisfied. lint_flags.push("-Wkeyword_idents_2024"); + lint_flags.push("-Wunreachable_pub"); lint_flags.push("-Wunsafe_op_in_unsafe_fn"); } From ff0a5fe975bdf94ea6a42c96c20a3891a91e503c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Mar 2025 12:55:32 +1100 Subject: [PATCH 947/991] Remove `#![warn(unreachable_pub)]` from all `compiler/` crates. It's no longer necessary now that `-Wunreachable_pub` is being passed. --- compiler/rustc_abi/src/lib.rs | 1 - compiler/rustc_arena/src/lib.rs | 1 - compiler/rustc_ast/src/lib.rs | 1 - compiler/rustc_ast_ir/src/lib.rs | 1 - compiler/rustc_ast_lowering/src/lib.rs | 1 - compiler/rustc_ast_passes/src/lib.rs | 1 - compiler/rustc_ast_pretty/src/lib.rs | 1 - compiler/rustc_attr_data_structures/src/lib.rs | 1 - compiler/rustc_attr_parsing/src/lib.rs | 1 - compiler/rustc_borrowck/src/lib.rs | 1 - compiler/rustc_builtin_macros/src/lib.rs | 1 - compiler/rustc_codegen_llvm/src/lib.rs | 1 - compiler/rustc_codegen_ssa/src/lib.rs | 1 - compiler/rustc_const_eval/src/lib.rs | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_error_codes/src/lib.rs | 1 - compiler/rustc_error_messages/src/lib.rs | 1 - compiler/rustc_errors/src/lib.rs | 1 - compiler/rustc_expand/src/lib.rs | 1 - compiler/rustc_feature/src/lib.rs | 1 - compiler/rustc_fluent_macro/src/lib.rs | 1 - compiler/rustc_graphviz/src/lib.rs | 1 - compiler/rustc_hir/src/lib.rs | 1 - compiler/rustc_hir_analysis/src/lib.rs | 1 - compiler/rustc_hir_pretty/src/lib.rs | 1 - compiler/rustc_hir_typeck/src/lib.rs | 1 - compiler/rustc_incremental/src/lib.rs | 1 - compiler/rustc_index/src/lib.rs | 1 - compiler/rustc_infer/src/lib.rs | 1 - compiler/rustc_interface/src/lib.rs | 1 - compiler/rustc_lexer/src/lib.rs | 1 - compiler/rustc_lint/src/lib.rs | 1 - compiler/rustc_lint_defs/src/lib.rs | 4 ---- compiler/rustc_llvm/src/lib.rs | 1 - compiler/rustc_macros/src/lib.rs | 1 - compiler/rustc_metadata/src/lib.rs | 1 - compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_mir_build/src/lib.rs | 1 - compiler/rustc_mir_dataflow/src/lib.rs | 1 - compiler/rustc_mir_transform/src/lib.rs | 1 - compiler/rustc_monomorphize/src/lib.rs | 1 - compiler/rustc_next_trait_solver/src/lib.rs | 1 - compiler/rustc_parse/src/lib.rs | 1 - compiler/rustc_parse_format/src/lib.rs | 1 - compiler/rustc_passes/src/lib.rs | 1 - compiler/rustc_pattern_analysis/src/lib.rs | 1 - compiler/rustc_privacy/src/lib.rs | 1 - compiler/rustc_query_impl/src/lib.rs | 1 - compiler/rustc_query_system/src/lib.rs | 1 - compiler/rustc_resolve/src/lib.rs | 1 - compiler/rustc_sanitizers/src/lib.rs | 1 - compiler/rustc_serialize/src/lib.rs | 1 - compiler/rustc_session/src/lib.rs | 1 - compiler/rustc_smir/src/lib.rs | 1 - compiler/rustc_span/src/lib.rs | 1 - compiler/rustc_symbol_mangling/src/lib.rs | 1 - compiler/rustc_target/src/lib.rs | 1 - compiler/rustc_trait_selection/src/lib.rs | 1 - compiler/rustc_traits/src/lib.rs | 1 - compiler/rustc_transmute/src/lib.rs | 1 - compiler/rustc_ty_utils/src/lib.rs | 1 - compiler/rustc_type_ir/src/lib.rs | 1 - 62 files changed, 65 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 1b7375820093..078b676e40eb 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -5,7 +5,6 @@ #![cfg_attr(feature = "nightly", feature(rustc_attrs))] #![cfg_attr(feature = "nightly", feature(rustdoc_internals))] #![cfg_attr(feature = "nightly", feature(step_trait))] -#![warn(unreachable_pub)] // tidy-alphabetical-end /*! ABI handling for rustc diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 3b44e9963581..6aaac072e4b2 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -23,7 +23,6 @@ #![feature(maybe_uninit_slice)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::alloc::Layout; diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 6372c66050e7..294c6c9ba7a5 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -19,7 +19,6 @@ #![feature(never_type)] #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod util { diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index 9884e191ea7b..6d05cd18cec1 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -9,7 +9,6 @@ #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(never_type))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] -#![warn(unreachable_pub)] // tidy-alphabetical-end #[cfg(feature = "nightly")] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1c4edd8348f4..4cecc56909e5 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -38,7 +38,6 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::sync::Arc; diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index b4ed70d83e57..093199cf3421 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -10,7 +10,6 @@ #![feature(iter_is_partitioned)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod ast_validation; diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 602ab69ee5b5..84d9ce278a21 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -3,7 +3,6 @@ #![doc(rust_logo)] #![feature(box_patterns)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod helpers; diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index f4986d1d1872..be00d1c10e0c 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -3,7 +3,6 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod attributes; diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 386f2c98447b..249e71ef70dc 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -80,7 +80,6 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end #[macro_use] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 64a533e05ffd..4d3774682ce8 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -13,7 +13,6 @@ #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index ca16583a45de..c23ce1e5e4a2 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -18,7 +18,6 @@ #![feature(rustdoc_internals)] #![feature(string_from_utf8_lossy_owned)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index e51d4852db28..2f3c8c75b0bf 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -19,7 +19,6 @@ #![feature(rustdoc_internals)] #![feature(slice_as_array)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::any::Any; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 4e758bfdec39..8ad040324147 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -14,7 +14,6 @@ #![feature(rustdoc_internals)] #![feature(trait_alias)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end //! This crate contains codegen code that is used by all codegen backends (LLVM and others). diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index ed5489652fba..da52d60ae59f 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -16,7 +16,6 @@ #![feature(unqualified_local_imports)] #![feature(yeet_expr)] #![warn(unqualified_local_imports)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod check_consts; diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index a2ddff7183e6..6e4020c6eca1 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -16,7 +16,6 @@ #![feature(result_flattening)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cmp::max; diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index d53d5678832b..dfeef5a957d6 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -6,7 +6,6 @@ #![deny(rustdoc::invalid_codeblock_attributes)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // This higher-order macro defines the error codes that are in use. It is used diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index ba1c3e185c2d..a6fbbb29ccd3 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -4,7 +4,6 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(type_alias_impl_trait)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 86959b28e538..80e43ede4453 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -25,7 +25,6 @@ #![feature(trait_alias)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_errors; diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 777044e3f33b..4222c9fe9061 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -13,7 +13,6 @@ #![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro as pm; diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 0b034a2ae107..25764755a8fc 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -15,7 +15,6 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod accepted; diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index 3ad51fa1e64d..c6e0484b9210 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -7,7 +7,6 @@ #![feature(proc_macro_span)] #![feature(rustdoc_internals)] #![feature(track_path)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index b5774f64b66b..c8f8fd5be023 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -277,7 +277,6 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 270d4fbec30f..84d369f1eddb 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -13,7 +13,6 @@ #![feature(never_type)] #![feature(rustc_attrs)] #![feature(variant_count)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_hir; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 50b0e32b95eb..26a20690a95c 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -73,7 +73,6 @@ This API is completely unstable and subject to change. #![feature(slice_partition_dedup)] #![feature(try_blocks)] #![feature(unwrap_infallible)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // These are used by Clippy. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2572ff50eb74..0e3721126fb3 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -3,7 +3,6 @@ // tidy-alphabetical-start #![recursion_limit = "256"] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::Cell; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 8b9c2b4a6ca0..263fb84206e0 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -8,7 +8,6 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod _match; diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 563ed7614c60..299ee4876389 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -7,7 +7,6 @@ #![doc(rust_logo)] #![feature(file_buffered)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod assert_dep_graph; diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 3441a5f65c78..cc680838e7e7 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -4,7 +4,6 @@ #![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))] #![cfg_attr(feature = "nightly", feature(new_range_api))] #![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod bit_set; diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index a04b2bb2b08b..ece18f4ea64e 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -24,7 +24,6 @@ #![feature(let_chains)] #![feature(rustdoc_internals)] #![recursion_limit = "512"] // For rustdoc -#![warn(unreachable_pub)] // tidy-alphabetical-end mod errors; diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 54cd341698f0..67e0be93523d 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -4,7 +4,6 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod callbacks; diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index bf18845a0830..61638e45253f 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -23,7 +23,6 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod cursor; diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7018774e5c6b..35867d8c9efe 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -32,7 +32,6 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod async_closures; diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index e564235c41a5..46b4b1d43838 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -1,7 +1,3 @@ -// tidy-alphabetical-start -#![warn(unreachable_pub)] -// tidy-alphabetical-end - use rustc_abi::ExternAbi; use rustc_ast::AttrId; use rustc_ast::attr::AttributeExt; diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index eda9b2b1fc09..68058250a267 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -4,7 +4,6 @@ #![doc(rust_logo)] #![feature(extern_types)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::RefCell; diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 34fc0f00320c..44ba064dd824 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -6,7 +6,6 @@ #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] #![feature(proc_macro_tracked_env)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index ebcc0efd5a67..8898c5824fa2 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -15,7 +15,6 @@ #![feature(proc_macro_internals)] #![feature(rustdoc_internals)] #![feature(trusted_len)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 48ea7df5c23f..8fe2cc7101ba 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -61,7 +61,6 @@ #![feature(try_trait_v2_yeet)] #![feature(type_alias_impl_trait)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end #[cfg(test)] diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index fa5db32d9134..8e96d46dac27 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -8,7 +8,6 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // The `builder` module used to be named `build`, but that was causing GitHub's diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index a8a56baa1ffc..a0efc623b8e7 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -7,7 +7,6 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::ty; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 8aa14d15644b..739cee5d7f4c 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -12,7 +12,6 @@ #![feature(never_type)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use hir::ConstContext; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 714b64b3a231..8f6914f3d724 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -4,7 +4,6 @@ #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(let_chains)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_hir::lang_items::LangItem; diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index d67ae2550d96..f6963a790675 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -6,7 +6,6 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_type_ir_inherent)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod canonicalizer; diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 1a104ff5e337..2edc8c83017d 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -12,7 +12,6 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(string_from_utf8_lossy_owned)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 3b985621b577..287bd8678da2 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -13,7 +13,6 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))) )] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub use Alignment::*; diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 1aa077ad2bb5..93ff0f66d695 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -12,7 +12,6 @@ #![feature(map_try_insert)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index a3400ebb7993..eeea724a29b4 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -6,7 +6,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(feature = "rustc", feature(let_chains))] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod constructor; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5271d03a6f61..5e3e8d69b603 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -6,7 +6,6 @@ #![feature(let_chains)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod errors; diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 73c205fdb17d..40da46a027df 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -8,7 +8,6 @@ #![feature(min_specialization)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_data_structures::stable_hasher::HashStable; diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index ee984095ad84..a546362414cf 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -6,7 +6,6 @@ #![feature(hash_raw_entry)] #![feature(let_chains)] #![feature(min_specialization)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod cache; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ccdca8552320..f724ecf76b3c 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -20,7 +20,6 @@ #![feature(let_chains)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::{Cell, RefCell}; diff --git a/compiler/rustc_sanitizers/src/lib.rs b/compiler/rustc_sanitizers/src/lib.rs index 55be931bcd6d..e4792563e71e 100644 --- a/compiler/rustc_sanitizers/src/lib.rs +++ b/compiler/rustc_sanitizers/src/lib.rs @@ -5,7 +5,6 @@ // tidy-alphabetical-start #![feature(let_chains)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod cfi; diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 9e9b78cfdd57..13c1a273eb81 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -14,7 +14,6 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub use self::serialize::{Decodable, Decoder, Encodable, Encoder}; diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index d432e84fdb22..0e19b982a133 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -7,7 +7,6 @@ // To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums // with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers"). #![recursion_limit = "256"] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod errors; diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 2215e2f01ade..9f8888753061 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -15,7 +15,6 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod rustc_internal; diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 798e186a94b1..f19d4d9f3624 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -32,7 +32,6 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(slice_as_chunks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // The code produced by the `Encodable`/`Decodable` derive macros refer to diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 4312c82815c1..269401ef3a2d 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -93,7 +93,6 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_hir::def::DefKind; diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 7ebe96960ed0..a8d7da5692de 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -16,7 +16,6 @@ #![feature(let_chains)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index b235d0da83cc..b18fb0fb8fd3 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -31,7 +31,6 @@ #![feature(unwrap_infallible)] #![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc -#![warn(unreachable_pub)] // For rustdoc // tidy-alphabetical-end pub mod error_reporting; diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index d2f979bd6d9d..697c83918031 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -2,7 +2,6 @@ // tidy-alphabetical-start #![recursion_limit = "256"] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod codegen; diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 81a11f7cfb26..00928137d297 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![feature(never_type)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set}; diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 8be1611bb9ac..35cc6f398565 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -16,7 +16,6 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 15ef4e7d6c1d..e2dfd9173fab 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -6,7 +6,6 @@ feature(associated_type_defaults, never_type, rustc_attrs, negative_impls) )] #![cfg_attr(feature = "nightly", allow(internal_features))] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_type_ir; From c00a5c08897b72e0aad2984101e1a2a938e6b365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:06:38 +0800 Subject: [PATCH 948/991] Fix post-merge workflow The command is called `post-merge-report` not `post-merge-analysis`. --- .github/workflows/post-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 2bc06d83c5b7..31e075f45d64 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -36,7 +36,7 @@ jobs: cd src/ci/citool echo "Post-merge analysis result" > output.log - cargo run --release post-merge-analysis ${PARENT_COMMIT} ${{ github.sha }} >> output.log + cargo run --release post-merge-report ${PARENT_COMMIT} ${{ github.sha }} >> output.log cat output.log gh pr comment ${HEAD_PR} -F output.log From 6e83ebe2558c5d3c95b52914033321f9e755d9d0 Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 9 Mar 2025 16:54:06 -0400 Subject: [PATCH 949/991] Document -Z crate-attr Co-authored-by: Vadim Petrochenkov --- .../src/compiler-flags/crate-attr.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/doc/unstable-book/src/compiler-flags/crate-attr.md diff --git a/src/doc/unstable-book/src/compiler-flags/crate-attr.md b/src/doc/unstable-book/src/compiler-flags/crate-attr.md new file mode 100644 index 000000000000..8c9c501a23e3 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/crate-attr.md @@ -0,0 +1,16 @@ +# `crate-attr` + +The tracking issue for this feature is: [#138287](https://github.com/rust-lang/rust/issues/138287). + +------------------------ + +The `-Z crate-attr` flag allows you to inject attributes into the crate root. +For example, `-Z crate-attr=crate_name="test"` acts as if `#![crate_name="test"]` were present before the first source line of the crate root. + +To inject multiple attributes, pass `-Z crate-attr` multiple times. + +Formally, the expansion behaves as follows: +1. The crate is parsed as if `-Z crate-attr` were not present. +2. The attributes in `-Z crate-attr` are parsed. +3. The attributes are injected at the top of the crate root. +4. Macro expansion is performed. From 512ebed59a37fc6bbb84195843878f279a3401ad Mon Sep 17 00:00:00 2001 From: jyn Date: Mon, 10 Mar 2025 23:25:22 -0400 Subject: [PATCH 950/991] add more -Z crate-attr tests --- .../basic.rs} | 0 tests/ui/attributes/z-crate-attr/cfg-false.rs | 7 +++++++ tests/ui/attributes/z-crate-attr/comments.rs | 5 +++++ .../ui/attributes/z-crate-attr/crate-name.rs | 6 ++++++ .../ui/attributes/z-crate-attr/crate-type.rs | 3 +++ tests/ui/attributes/z-crate-attr/garbage.rs | 4 ++++ .../ui/attributes/z-crate-attr/garbage.stderr | 20 +++++++++++++++++++ tests/ui/attributes/z-crate-attr/injection.rs | 3 +++ .../attributes/z-crate-attr/injection.stderr | 8 ++++++++ .../ui/attributes/z-crate-attr/inner-attr.rs | 4 ++++ .../attributes/z-crate-attr/inner-attr.stderr | 8 ++++++++ tests/ui/attributes/z-crate-attr/multiple.rs | 3 +++ .../attributes/z-crate-attr/multiple.stderr | 8 ++++++++ .../z-crate-attr/respect-existing-attrs.rs | 9 +++++++++ tests/ui/attributes/z-crate-attr/shebang.rs | 6 ++++++ .../z-crate-attr/unbalanced-paren.rs | 4 ++++ .../z-crate-attr/unbalanced-paren.stderr | 10 ++++++++++ 17 files changed, 108 insertions(+) rename tests/ui/attributes/{z-crate-attr.rs => z-crate-attr/basic.rs} (100%) create mode 100644 tests/ui/attributes/z-crate-attr/cfg-false.rs create mode 100644 tests/ui/attributes/z-crate-attr/comments.rs create mode 100644 tests/ui/attributes/z-crate-attr/crate-name.rs create mode 100644 tests/ui/attributes/z-crate-attr/crate-type.rs create mode 100644 tests/ui/attributes/z-crate-attr/garbage.rs create mode 100644 tests/ui/attributes/z-crate-attr/garbage.stderr create mode 100644 tests/ui/attributes/z-crate-attr/injection.rs create mode 100644 tests/ui/attributes/z-crate-attr/injection.stderr create mode 100644 tests/ui/attributes/z-crate-attr/inner-attr.rs create mode 100644 tests/ui/attributes/z-crate-attr/inner-attr.stderr create mode 100644 tests/ui/attributes/z-crate-attr/multiple.rs create mode 100644 tests/ui/attributes/z-crate-attr/multiple.stderr create mode 100644 tests/ui/attributes/z-crate-attr/respect-existing-attrs.rs create mode 100644 tests/ui/attributes/z-crate-attr/shebang.rs create mode 100644 tests/ui/attributes/z-crate-attr/unbalanced-paren.rs create mode 100644 tests/ui/attributes/z-crate-attr/unbalanced-paren.stderr diff --git a/tests/ui/attributes/z-crate-attr.rs b/tests/ui/attributes/z-crate-attr/basic.rs similarity index 100% rename from tests/ui/attributes/z-crate-attr.rs rename to tests/ui/attributes/z-crate-attr/basic.rs diff --git a/tests/ui/attributes/z-crate-attr/cfg-false.rs b/tests/ui/attributes/z-crate-attr/cfg-false.rs new file mode 100644 index 000000000000..db37cfdd0863 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/cfg-false.rs @@ -0,0 +1,7 @@ +// Ensure that `-Z crate-attr=cfg(FALSE)` can comment out the whole crate +//@ compile-flags: --crate-type=lib -Zcrate-attr=cfg(FALSE) +//@ check-pass + +// NOTE: duplicate items are load-bearing +fn foo() {} +fn foo() {} diff --git a/tests/ui/attributes/z-crate-attr/comments.rs b/tests/ui/attributes/z-crate-attr/comments.rs new file mode 100644 index 000000000000..c1ab041f3447 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/comments.rs @@ -0,0 +1,5 @@ +//@ check-pass +//@ compile-flags: -Zcrate-attr=/*hi-there*/feature(rustc_attrs) + +#[rustc_dummy] +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/crate-name.rs b/tests/ui/attributes/z-crate-attr/crate-name.rs new file mode 100644 index 000000000000..d49830390e2e --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/crate-name.rs @@ -0,0 +1,6 @@ +// Ensure that `crate_name` and `crate_type` can be set through `-Z crate-attr`. +//@ check-pass +//@ compile-flags: -Zcrate-attr=crate_name="override" +fn main() { + assert_eq!(module_path!(), "r#override"); +} diff --git a/tests/ui/attributes/z-crate-attr/crate-type.rs b/tests/ui/attributes/z-crate-attr/crate-type.rs new file mode 100644 index 000000000000..0e7411865af9 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/crate-type.rs @@ -0,0 +1,3 @@ +//@ check-pass +//@ compile-flags: -Zcrate-attr=crate_type="lib" +// notice the lack of `main` is load-bearing diff --git a/tests/ui/attributes/z-crate-attr/garbage.rs b/tests/ui/attributes/z-crate-attr/garbage.rs new file mode 100644 index 000000000000..ec81dd1bcaa0 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/garbage.rs @@ -0,0 +1,4 @@ +// Show diagnostics for invalid tokens +//@ compile-flags: -Zcrate-attr=`%~@$# +//@ error-pattern:unknown start of token +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/garbage.stderr b/tests/ui/attributes/z-crate-attr/garbage.stderr new file mode 100644 index 000000000000..082046e31f8c --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/garbage.stderr @@ -0,0 +1,20 @@ +error: unknown start of token: ` + --> :1:1 + | +LL | `%~@$# + | ^ + | +help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not + | +LL - `%~@$# +LL + '%~@$# + | + +error: expected identifier, found `%` + --> :1:2 + | +LL | `%~@$# + | ^ expected identifier + +error: aborting due to 2 previous errors + diff --git a/tests/ui/attributes/z-crate-attr/injection.rs b/tests/ui/attributes/z-crate-attr/injection.rs new file mode 100644 index 000000000000..0c5c81ca71a9 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/injection.rs @@ -0,0 +1,3 @@ +//@ compile-flags: '-Zcrate-attr=feature(yeet_expr)]fn main(){}#[inline' +//@ error-pattern:unexpected closing delimiter +fn foo() {} diff --git a/tests/ui/attributes/z-crate-attr/injection.stderr b/tests/ui/attributes/z-crate-attr/injection.stderr new file mode 100644 index 000000000000..6fec98baf8df --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/injection.stderr @@ -0,0 +1,8 @@ +error: unexpected closing delimiter: `]` + --> :1:19 + | +LL | feature(yeet_expr)]fn main(){}#[inline + | ^ unexpected closing delimiter + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/z-crate-attr/inner-attr.rs b/tests/ui/attributes/z-crate-attr/inner-attr.rs new file mode 100644 index 000000000000..522c906dcd81 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/inner-attr.rs @@ -0,0 +1,4 @@ +//@ compile-flags: -Zcrate-attr=#![feature(foo)] +//@ error-pattern:expected identifier + +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/inner-attr.stderr b/tests/ui/attributes/z-crate-attr/inner-attr.stderr new file mode 100644 index 000000000000..06a063d310b6 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/inner-attr.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `#` + --> :1:1 + | +LL | #![feature(foo)] + | ^ expected identifier + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/z-crate-attr/multiple.rs b/tests/ui/attributes/z-crate-attr/multiple.rs new file mode 100644 index 000000000000..ee13253f6255 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/multiple.rs @@ -0,0 +1,3 @@ +//@ compile-flags: -Zcrate-attr=feature(foo),feature(bar) +//@ error-pattern:invalid crate attr +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/multiple.stderr b/tests/ui/attributes/z-crate-attr/multiple.stderr new file mode 100644 index 000000000000..9f968a7e1346 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/multiple.stderr @@ -0,0 +1,8 @@ +error: invalid crate attribute + --> :1:1 + | +LL | feature(foo),feature(bar) + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/z-crate-attr/respect-existing-attrs.rs b/tests/ui/attributes/z-crate-attr/respect-existing-attrs.rs new file mode 100644 index 000000000000..71f2559998fb --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/respect-existing-attrs.rs @@ -0,0 +1,9 @@ +// Make sure that existing root attributes are still respected even when `-Zcrate-attr` is present. +//@ run-pass +//@ compile-flags: -Zcrate-attr=feature(rustc_attrs) +#![crate_name = "override"] + +#[rustc_dummy] +fn main() { + assert_eq!(module_path!(), "r#override"); +} diff --git a/tests/ui/attributes/z-crate-attr/shebang.rs b/tests/ui/attributes/z-crate-attr/shebang.rs new file mode 100644 index 000000000000..195393acaf5e --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/shebang.rs @@ -0,0 +1,6 @@ +#!/usr/bin/env -S cargo +nightly -Zscript +// Make sure that shebangs are still allowed even when `-Zcrate-attr` is present. +//@ check-pass +//@ compile-flags: -Zcrate-attr=feature(rustc_attrs) +#[rustc_dummy] +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/unbalanced-paren.rs b/tests/ui/attributes/z-crate-attr/unbalanced-paren.rs new file mode 100644 index 000000000000..fc1d7f39a597 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/unbalanced-paren.rs @@ -0,0 +1,4 @@ +// Show diagnostics for unbalanced parens. +//@ compile-flags: -Zcrate-attr=( +//@ error-pattern:unclosed delimiter +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/unbalanced-paren.stderr b/tests/ui/attributes/z-crate-attr/unbalanced-paren.stderr new file mode 100644 index 000000000000..47b1b764ba9a --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/unbalanced-paren.stderr @@ -0,0 +1,10 @@ +error: this file contains an unclosed delimiter + --> :1:2 + | +LL | ( + | -^ + | | + | unclosed delimiter + +error: aborting due to 1 previous error + From ed5877e0ada49a1f44f60f61c032520ec92b3607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Mar 2025 09:07:18 +0100 Subject: [PATCH 951/991] Add missing unsafe block --- src/bootstrap/src/utils/job.rs | 61 ++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/src/bootstrap/src/utils/job.rs b/src/bootstrap/src/utils/job.rs index 99fc3e2dc7b5..4949518de79b 100644 --- a/src/bootstrap/src/utils/job.rs +++ b/src/bootstrap/src/utils/job.rs @@ -61,38 +61,41 @@ mod for_windows { use crate::Build; pub unsafe fn setup(build: &mut Build) { - // Enable the Windows Error Reporting dialog which msys disables, - // so we can JIT debug rustc - let mode = SetErrorMode(THREAD_ERROR_MODE::default()); - let mode = THREAD_ERROR_MODE(mode); - SetErrorMode(mode & !SEM_NOGPFAULTERRORBOX); + // SAFETY: pretty much everything below is unsafe + unsafe { + // Enable the Windows Error Reporting dialog which msys disables, + // so we can JIT debug rustc + let mode = SetErrorMode(THREAD_ERROR_MODE::default()); + let mode = THREAD_ERROR_MODE(mode); + SetErrorMode(mode & !SEM_NOGPFAULTERRORBOX); - // Create a new job object for us to use - let job = CreateJobObjectW(None, PCWSTR::null()).unwrap(); + // Create a new job object for us to use + let job = CreateJobObjectW(None, PCWSTR::null()).unwrap(); - // Indicate that when all handles to the job object are gone that all - // process in the object should be killed. Note that this includes our - // entire process tree by default because we've added ourselves and our - // children will reside in the job by default. - let mut info = JOBOBJECT_EXTENDED_LIMIT_INFORMATION::default(); - info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; - if build.config.low_priority { - info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_PRIORITY_CLASS; - info.BasicLimitInformation.PriorityClass = BELOW_NORMAL_PRIORITY_CLASS.0; - } - let r = SetInformationJobObject( - job, - JobObjectExtendedLimitInformation, - &info as *const _ as *const c_void, - size_of_val(&info) as u32, - ); - assert!(r.is_ok(), "{}", io::Error::last_os_error()); + // Indicate that when all handles to the job object are gone that all + // process in the object should be killed. Note that this includes our + // entire process tree by default because we've added ourselves and our + // children will reside in the job by default. + let mut info = JOBOBJECT_EXTENDED_LIMIT_INFORMATION::default(); + info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + if build.config.low_priority { + info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_PRIORITY_CLASS; + info.BasicLimitInformation.PriorityClass = BELOW_NORMAL_PRIORITY_CLASS.0; + } + let r = SetInformationJobObject( + job, + JobObjectExtendedLimitInformation, + &info as *const _ as *const c_void, + size_of_val(&info) as u32, + ); + assert!(r.is_ok(), "{}", io::Error::last_os_error()); - // Assign our process to this job object. - let r = AssignProcessToJobObject(job, GetCurrentProcess()); - if r.is_err() { - CloseHandle(job).ok(); - return; + // Assign our process to this job object. + let r = AssignProcessToJobObject(job, GetCurrentProcess()); + if r.is_err() { + CloseHandle(job).ok(); + return; + } } // Note: we intentionally leak the job object handle. When our process exits From cf8e1f5e0faed0a8f50ccfecedb1e4fad8d79191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= <69964857+Sa4dUs@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:37:50 +0100 Subject: [PATCH 952/991] Fix ICE for invalid return activity and proper error handling --- compiler/rustc_builtin_macros/messages.ftl | 2 + compiler/rustc_builtin_macros/src/autodiff.rs | 15 +++++- compiler/rustc_builtin_macros/src/errors.rs | 9 ++++ .../rustc_codegen_ssa/src/codegen_attrs.rs | 19 +------ tests/ui/autodiff/autodiff_illegal.rs | 52 +++++++++++++------ tests/ui/autodiff/autodiff_illegal.stderr | 52 ++++++++++++++----- 6 files changed, 100 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 4cac7cb93f58..9dac7a8aaf42 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -75,8 +75,10 @@ builtin_macros_autodiff_mode = unknown Mode: `{$mode}`. Use `Forward` or `Revers builtin_macros_autodiff_mode_activity = {$act} can not be used in {$mode} Mode builtin_macros_autodiff_not_build = this rustc version does not support autodiff builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found} +builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode} Mode builtin_macros_autodiff_ty_activity = {$act} can not be used for this type + builtin_macros_autodiff_unknown_activity = did not recognize Activity: `{$act}` builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s .label = not applicable here diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 6d9c35756574..6707ab8edde9 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -8,7 +8,8 @@ mod llvm_enzyme { use std::string::String; use rustc_ast::expand::autodiff_attrs::{ - AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ty_for_activity, + AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, + valid_ty_for_activity, }; use rustc_ast::ptr::P; use rustc_ast::token::{Token, TokenKind}; @@ -632,10 +633,22 @@ mod llvm_enzyme { errors = true; } } + + if has_ret && !valid_ret_activity(x.mode, x.ret_activity) { + dcx.emit_err(errors::AutoDiffInvalidRetAct { + span, + mode: x.mode.to_string(), + act: x.ret_activity.to_string(), + }); + // We don't set `errors = true` to avoid annoying type errors relative + // to the expanded macro type signature + } + if errors { // This is not the right signature, but we can continue parsing. return (sig.clone(), new_inputs, idents, true); } + let unsafe_activities = x .input_activity .iter() diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index ab1e0d8ee896..30597944124c 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -185,6 +185,15 @@ mod autodiff { pub(crate) act: String, } + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_ret_activity)] + pub(crate) struct AutoDiffInvalidRetAct { + #[primary_span] + pub(crate) span: Span, + pub(crate) mode: String, + pub(crate) act: String, + } + #[derive(Diagnostic)] #[diag(builtin_macros_autodiff_mode)] pub(crate) struct AutoDiffInvalidMode { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index c8f13dc0bae6..a01f5d372a2d 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,9 +1,7 @@ use std::str::FromStr; use rustc_abi::ExternAbi; -use rustc_ast::expand::autodiff_attrs::{ - AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, -}; +use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{MetaItem, MetaItemInner, attr}; use rustc_attr_parsing::ReprAttr::ReprAlign; use rustc_attr_parsing::{AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr}; @@ -930,21 +928,6 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option { } } - // Validate input and return activities - let mut msg = "".to_string(); - for &input in &arg_activities { - if !valid_input_activity(mode, input) { - msg = format!("Invalid input activity {} for {} mode", input, mode); - } - } - if !valid_ret_activity(mode, ret_activity) { - msg = format!("Invalid return activity {} for {} mode", ret_activity, mode); - } - if msg != "".to_string() { - tcx.dcx().struct_span_err(attr.span(), msg).with_note("invalid activity").emit(); - return Some(AutoDiffAttrs::error()); - } - Some(AutoDiffAttrs { mode, ret_activity, input_activity: arg_activities }) } diff --git a/tests/ui/autodiff/autodiff_illegal.rs b/tests/ui/autodiff/autodiff_illegal.rs index c0548d2bbb8f..e810b9ba565b 100644 --- a/tests/ui/autodiff/autodiff_illegal.rs +++ b/tests/ui/autodiff/autodiff_illegal.rs @@ -12,41 +12,40 @@ use std::autodiff::autodiff; // We can't use Duplicated on scalars #[autodiff(df1, Reverse, Duplicated)] pub fn f1(x: f64) { -//~^ ERROR Duplicated can not be used for this type + //~^ ERROR Duplicated can not be used for this type unimplemented!() } // Too many activities #[autodiff(df3, Reverse, Duplicated, Const)] pub fn f3(x: f64) { -//~^^ ERROR expected 1 activities, but found 2 + //~^^ ERROR expected 1 activities, but found 2 unimplemented!() } // To few activities #[autodiff(df4, Reverse)] pub fn f4(x: f64) { -//~^^ ERROR expected 1 activities, but found 0 + //~^^ ERROR expected 1 activities, but found 0 unimplemented!() } // We can't use Dual in Reverse mode #[autodiff(df5, Reverse, Dual)] pub fn f5(x: f64) { -//~^^ ERROR Dual can not be used in Reverse Mode + //~^^ ERROR Dual can not be used in Reverse Mode unimplemented!() } // We can't use Duplicated in Forward mode #[autodiff(df6, Forward, Duplicated)] pub fn f6(x: f64) { -//~^^ ERROR Duplicated can not be used in Forward Mode -//~^^ ERROR Duplicated can not be used for this type + //~^^ ERROR Duplicated can not be used in Forward Mode + //~^^ ERROR Duplicated can not be used for this type unimplemented!() } fn dummy() { - #[autodiff(df7, Forward, Dual)] let mut x = 5; //~^ ERROR autodiff must be applied to function @@ -64,21 +63,21 @@ fn dummy() { // Malformed, where args? #[autodiff] pub fn f7(x: f64) { -//~^ ERROR autodiff must be applied to function + //~^ ERROR autodiff must be applied to function unimplemented!() } // Malformed, where args? #[autodiff()] pub fn f8(x: f64) { -//~^ ERROR autodiff requires at least a name and mode + //~^ ERROR autodiff requires at least a name and mode unimplemented!() } // Invalid attribute syntax #[autodiff = ""] pub fn f9(x: f64) { -//~^ ERROR autodiff must be applied to function + //~^ ERROR autodiff must be applied to function unimplemented!() } @@ -87,21 +86,21 @@ fn fn_exists() {} // We colide with an already existing function #[autodiff(fn_exists, Reverse, Active)] pub fn f10(x: f64) { -//~^^ ERROR the name `fn_exists` is defined multiple times [E0428] + //~^^ ERROR the name `fn_exists` is defined multiple times [E0428] unimplemented!() } // Malformed, missing a mode #[autodiff(df11)] pub fn f11() { -//~^ ERROR autodiff requires at least a name and mode + //~^ ERROR autodiff requires at least a name and mode unimplemented!() } // Invalid Mode #[autodiff(df12, Debug)] pub fn f12() { -//~^^ ERROR unknown Mode: `Debug`. Use `Forward` or `Reverse` + //~^^ ERROR unknown Mode: `Debug`. Use `Forward` or `Reverse` unimplemented!() } @@ -109,7 +108,7 @@ pub fn f12() { // or use two autodiff macros. #[autodiff(df13, Forward, Reverse)] pub fn f13() { -//~^^ ERROR did not recognize Activity: `Reverse` + //~^^ ERROR did not recognize Activity: `Reverse` unimplemented!() } @@ -130,7 +129,7 @@ type MyFloat = f32; // like THIR which has type information available. #[autodiff(df15, Reverse, Active, Active)] fn f15(x: MyFloat) -> f32 { -//~^^ ERROR failed to resolve: use of undeclared type `MyFloat` [E0433] + //~^^ ERROR failed to resolve: use of undeclared type `MyFloat` [E0433] unimplemented!() } @@ -141,7 +140,9 @@ fn f16(x: f32) -> MyFloat { } #[repr(transparent)] -struct F64Trans { inner: f64 } +struct F64Trans { + inner: f64, +} // We would like to support `#[repr(transparent)]` f32/f64 wrapper in return type in the future #[autodiff(df17, Reverse, Active, Active)] @@ -156,5 +157,24 @@ fn f18(x: F64Trans) -> f64 { unimplemented!() } +// Invalid return activity +#[autodiff(df19, Forward, Dual, Active)] +fn f19(x: f32) -> f32 { + //~^^ ERROR invalid return activity Active in Forward Mode + unimplemented!() +} + +#[autodiff(df20, Reverse, Active, Dual)] +fn f20(x: f32) -> f32 { + //~^^ ERROR invalid return activity Dual in Reverse Mode + unimplemented!() +} + +// Duplicated cannot be used as return activity +#[autodiff(df21, Reverse, Active, Duplicated)] +fn f21(x: f32) -> f32 { + //~^^ ERROR invalid return activity Duplicated in Reverse Mode + unimplemented!() +} fn main() {} diff --git a/tests/ui/autodiff/autodiff_illegal.stderr b/tests/ui/autodiff/autodiff_illegal.stderr index 3a7242b2f5d9..47d53492700b 100644 --- a/tests/ui/autodiff/autodiff_illegal.stderr +++ b/tests/ui/autodiff/autodiff_illegal.stderr @@ -1,5 +1,5 @@ error[E0658]: attributes on expressions are experimental - --> $DIR/autodiff_illegal.rs:54:5 + --> $DIR/autodiff_illegal.rs:53:5 | LL | #[autodiff(df7, Forward, Dual)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -53,25 +53,25 @@ LL | pub fn f6(x: f64) { | ^^^ error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:51:5 + --> $DIR/autodiff_illegal.rs:50:5 | LL | let mut x = 5; | ^^^^^^^^^^^^^^ error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:55:5 + --> $DIR/autodiff_illegal.rs:54:5 | LL | x = x + 3; | ^ error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:60:5 + --> $DIR/autodiff_illegal.rs:59:5 | LL | let add_one_v2 = |x: u32| -> u32 { x + 1 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:66:1 + --> $DIR/autodiff_illegal.rs:65:1 | LL | / pub fn f7(x: f64) { LL | | @@ -80,7 +80,7 @@ LL | | } | |_^ error: autodiff requires at least a name and mode - --> $DIR/autodiff_illegal.rs:73:1 + --> $DIR/autodiff_illegal.rs:72:1 | LL | / pub fn f8(x: f64) { LL | | @@ -89,7 +89,7 @@ LL | | } | |_^ error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:80:1 + --> $DIR/autodiff_illegal.rs:79:1 | LL | / pub fn f9(x: f64) { LL | | @@ -98,7 +98,7 @@ LL | | } | |_^ error[E0428]: the name `fn_exists` is defined multiple times - --> $DIR/autodiff_illegal.rs:88:1 + --> $DIR/autodiff_illegal.rs:87:1 | LL | fn fn_exists() {} | -------------- previous definition of the value `fn_exists` here @@ -110,7 +110,7 @@ LL | #[autodiff(fn_exists, Reverse, Active)] = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) error: autodiff requires at least a name and mode - --> $DIR/autodiff_illegal.rs:96:1 + --> $DIR/autodiff_illegal.rs:95:1 | LL | / pub fn f11() { LL | | @@ -119,19 +119,43 @@ LL | | } | |_^ error: unknown Mode: `Debug`. Use `Forward` or `Reverse` - --> $DIR/autodiff_illegal.rs:102:18 + --> $DIR/autodiff_illegal.rs:101:18 | LL | #[autodiff(df12, Debug)] | ^^^^^ error: did not recognize Activity: `Reverse` - --> $DIR/autodiff_illegal.rs:110:27 + --> $DIR/autodiff_illegal.rs:109:27 | LL | #[autodiff(df13, Forward, Reverse)] | ^^^^^^^ +error: invalid return activity Active in Forward Mode + --> $DIR/autodiff_illegal.rs:161:1 + | +LL | #[autodiff(df19, Forward, Dual, Active)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: invalid return activity Dual in Reverse Mode + --> $DIR/autodiff_illegal.rs:167:1 + | +LL | #[autodiff(df20, Reverse, Active, Dual)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: invalid return activity Duplicated in Reverse Mode + --> $DIR/autodiff_illegal.rs:174:1 + | +LL | #[autodiff(df21, Reverse, Active, Duplicated)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0433]: failed to resolve: use of undeclared type `MyFloat` - --> $DIR/autodiff_illegal.rs:131:1 + --> $DIR/autodiff_illegal.rs:130:1 | LL | #[autodiff(df15, Reverse, Active, Active)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `MyFloat` @@ -139,14 +163,14 @@ LL | #[autodiff(df15, Reverse, Active, Active)] = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0433]: failed to resolve: use of undeclared type `F64Trans` - --> $DIR/autodiff_illegal.rs:153:1 + --> $DIR/autodiff_illegal.rs:154:1 | LL | #[autodiff(df18, Reverse, Active, Active)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `F64Trans` | = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 19 previous errors +error: aborting due to 22 previous errors Some errors have detailed explanations: E0428, E0433, E0658. For more information about an error, try `rustc --explain E0428`. From 33f9a491eb97af0cc72df70fd10724eda2453d45 Mon Sep 17 00:00:00 2001 From: Sa4dUs Date: Mon, 10 Mar 2025 13:58:10 +0100 Subject: [PATCH 953/991] Combine autodiff errors together --- compiler/rustc_builtin_macros/messages.ftl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 9dac7a8aaf42..3f03834f8d78 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -77,9 +77,8 @@ builtin_macros_autodiff_not_build = this rustc version does not support autodiff builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found} builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode} Mode builtin_macros_autodiff_ty_activity = {$act} can not be used for this type - - builtin_macros_autodiff_unknown_activity = did not recognize Activity: `{$act}` + builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s .label = not applicable here .label2 = not a `struct`, `enum` or `union` From 8546e015b4a04e9c397478ae1e27a5370d2c638b Mon Sep 17 00:00:00 2001 From: Sa4dUs Date: Mon, 10 Mar 2025 16:05:27 +0100 Subject: [PATCH 954/991] Add individual activity span availability FIXME --- compiler/rustc_builtin_macros/src/autodiff.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 6707ab8edde9..cae806c6da77 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -586,6 +586,8 @@ mod llvm_enzyme { // // Error handling: If the user provides an invalid configuration (incorrect numbers, types, or // both), we emit an error and return the original signature. This allows us to continue parsing. + // FIXME(Sa4dUs): make individual activities' span available so errors + // can point to only the activity instead of the entire attribute fn gen_enzyme_decl( ecx: &ExtCtxt<'_>, sig: &ast::FnSig, From ff5a8ad2abb45955dbeda46273242d6f0186cf2c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 09:22:41 +0000 Subject: [PATCH 955/991] Explain the actual reason why stripping binders is fine --- .../rustc_monomorphize/src/partitioning/autodiff.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs index 0c855508434e..378b98c28077 100644 --- a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs +++ b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs @@ -12,15 +12,14 @@ fn adjust_activity_to_abi<'tcx>(tcx: TyCtxt<'tcx>, fn_ty: Ty<'tcx>, da: &mut Vec if !matches!(fn_ty.kind(), ty::FnDef(..)) { bug!("expected fn def for autodiff, got {:?}", fn_ty); } - let fnc_binder: ty::Binder<'_, ty::FnSig<'_>> = fn_ty.fn_sig(tcx); - // If rustc compiles the unmodified primal, we know that this copy of the function - // also has correct lifetimes. We know that Enzyme won't free the shadow too early - // (or actually at all), so let's strip lifetimes when computing the layout. - let x = tcx.instantiate_bound_regions_with_erased(fnc_binder); + // We don't actually pass the types back into the type system. + // All we do is decide how to handle the arguments. + let sig = fn_ty.fn_sig(tcx).skip_binder(); + let mut new_activities = vec![]; let mut new_positions = vec![]; - for (i, ty) in x.inputs().iter().enumerate() { + for (i, ty) in sig.inputs().iter().enumerate() { if let Some(inner_ty) = ty.builtin_deref(true) { if ty.is_fn_ptr() { // FIXME(ZuseZ4): add a nicer error, or just figure out how to support them, From 9882eca151a4c1c604597acd98072babb9e6ffcf Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Mar 2025 08:41:15 +0000 Subject: [PATCH 956/991] Remove some dead code --- compiler/rustc_monomorphize/src/partitioning/autodiff.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs index 378b98c28077..ebe0b258c1b6 100644 --- a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs +++ b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs @@ -21,11 +21,6 @@ fn adjust_activity_to_abi<'tcx>(tcx: TyCtxt<'tcx>, fn_ty: Ty<'tcx>, da: &mut Vec let mut new_positions = vec![]; for (i, ty) in sig.inputs().iter().enumerate() { if let Some(inner_ty) = ty.builtin_deref(true) { - if ty.is_fn_ptr() { - // FIXME(ZuseZ4): add a nicer error, or just figure out how to support them, - // since Enzyme itself can handle them. - tcx.dcx().err("function pointers are currently not supported in autodiff"); - } if inner_ty.is_slice() { // We know that the length will be passed as extra arg. if !da.is_empty() { From 7475a3416bb7580ad2327c2f3cd4fd7105848bab Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 9 Dec 2024 15:31:32 +0300 Subject: [PATCH 957/991] Stabilize `std::io::ErrorKind::InvalidFilename` --- library/std/src/io/error.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 5aa048c4cbc8..8472f9030500 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -373,8 +373,8 @@ pub enum ErrorKind { TooManyLinks, /// A filename was invalid. /// - /// This error can also cause if it exceeded the filename length limit. - #[unstable(feature = "io_error_more", issue = "86442")] + /// This error can also occur if a length limit for a name was exceeded. + #[stable(feature = "io_error_invalid_filename", since = "CURRENT_RUSTC_VERSION")] InvalidFilename, /// Program argument list too long. /// From cb4751d4b87e1c8ebdeb381abe3785486a59968e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 26 Jul 2024 10:04:02 +0000 Subject: [PATCH 958/991] Implement `#[define_opaque]` attribute for functions. --- Cargo.lock | 1 + compiler/rustc_ast/src/ast.rs | 3 +- compiler/rustc_ast/src/mut_visit.rs | 14 +- compiler/rustc_ast/src/visit.rs | 14 +- compiler/rustc_ast_lowering/src/item.rs | 51 ++++- compiler/rustc_ast_lowering/src/lib.rs | 9 +- .../rustc_ast_passes/src/ast_validation.rs | 5 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 11 +- .../rustc_ast_pretty/src/pprust/state/item.rs | 13 +- .../src/type_check/opaque_types.rs | 1 + .../src/alloc_error_handler.rs | 1 + compiler/rustc_builtin_macros/src/autodiff.rs | 1 + .../rustc_builtin_macros/src/define_opaque.rs | 54 +++++ .../src/deriving/generic/mod.rs | 1 + .../src/global_allocator.rs | 1 + compiler/rustc_builtin_macros/src/lib.rs | 2 + .../rustc_builtin_macros/src/test_harness.rs | 1 + .../example/issue-72793.rs | 30 ++- .../src/obligation_forest/mod.rs | 1 + .../src/error_codes/E0792.md | 4 + compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_hir/src/hir.rs | 9 +- compiler/rustc_hir/src/stable_hash_impls.rs | 2 +- compiler/rustc_hir_analysis/messages.ftl | 9 +- .../rustc_hir_analysis/src/check/check.rs | 20 +- .../src/collect/type_of/opaque.rs | 80 ++----- compiler/rustc_hir_analysis/src/errors.rs | 10 - .../src/opaque_hidden_inferred_bound.rs | 1 + compiler/rustc_middle/src/mir/terminator.rs | 3 + compiler/rustc_middle/src/query/erase.rs | 2 + compiler/rustc_parse/src/parser/item.rs | 9 +- compiler/rustc_resolve/src/late.rs | 67 ++++-- compiler/rustc_span/src/symbol.rs | 1 + .../error_reporting/infer/note_and_explain.rs | 27 ++- compiler/rustc_ty_utils/Cargo.toml | 1 + compiler/rustc_ty_utils/src/opaque_types.rs | 129 +++++------ library/core/src/macros/mod.rs | 15 ++ library/core/src/prelude/v1.rs | 8 + library/std/src/backtrace.rs | 1 + library/std/src/prelude/v1.rs | 9 + src/librustdoc/html/render/span_map.rs | 2 +- .../clippy/clippy_utils/src/ast_utils/mod.rs | 6 + .../clippy/tests/ui/crashes/ice-10972-tait.rs | 10 - .../tests/ui/implied_bounds_in_impls.fixed | 1 + .../tests/ui/implied_bounds_in_impls.rs | 1 + .../ui/missing_const_for_fn/cant_be_const.rs | 1 + .../tests/ui/new_ret_no_self_overflow.rs | 1 + .../tests/ui/new_ret_no_self_overflow.stderr | 2 +- src/tools/tidy/src/issues.txt | 1 - ...adata-id-itanium-cxx-abi-const-generics.rs | 24 +- ...e-metadata-id-itanium-cxx-abi-lifetimes.rs | 22 +- ...-type-metadata-id-itanium-cxx-abi-paths.rs | 94 ++++---- tests/crashes/120016.rs | 1 + tests/crashes/122904-2.rs | 2 + tests/crashes/122904.rs | 1 + tests/crashes/125185.rs | 14 +- tests/crashes/126680.rs | 22 +- tests/crashes/131298.rs | 12 - tests/crashes/131886.rs | 5 +- tests/crashes/135528.rs | 2 + tests/crashes/137049.rs | 1 + ...onstrain_opaque_types_during_projection.rs | 3 +- .../issue-109299-1.stderr | 2 +- .../dont-imply-atb-in-closure-inference.rs | 6 +- tests/ui/associated-type-bounds/duplicate.rs | 6 + .../associated-type-bounds/duplicate.stderr | 126 ++++++---- .../trait-alias-impl-trait.rs | 4 + tests/ui/async-await/async-fn/impl-trait.rs | 5 +- .../issues/issue-60655-latebound-regions.rs | 4 +- ...normalize-output-in-signature-deduction.rs | 1 + .../attributes/collapse-debuginfo-invalid.rs | 19 +- .../collapse-debuginfo-invalid.stderr | 6 +- .../overwrite-anon-late-param-regions.rs | 1 + .../overwrite-anon-late-param-regions.stderr | 4 +- tests/ui/coherence/coherence-with-closure.rs | 1 + .../coherence/coherence-with-closure.stderr | 2 +- .../ui/coherence/coherence-with-coroutine.rs | 1 + .../coherence-with-coroutine.stock.stderr | 2 +- tests/ui/coherence/issue-99663-2.rs | 1 + tests/ui/coherence/issue-99663.rs | 1 + .../occurs-check/opaques.current.stderr | 6 +- .../occurs-check/opaques.next.stderr | 12 +- tests/ui/coherence/occurs-check/opaques.rs | 17 +- .../orphan-check-opaque-types-not-covering.rs | 2 + ...han-check-opaque-types-not-covering.stderr | 4 +- .../generic_const_exprs/opaque_type.rs | 4 +- .../generic_const_exprs/opaque_type.stderr | 4 +- tests/ui/const-generics/opaque_types.rs | 3 +- tests/ui/const-generics/opaque_types.stderr | 116 +--------- tests/ui/const-generics/opaque_types2.rs | 13 +- tests/ui/const-generics/opaque_types2.stderr | 6 +- .../const-eval/ice-unhandled-type-122191.rs | 14 +- .../ice-unhandled-type-122191.stderr | 33 ++- .../const-promoted-opaque.atomic.stderr | 8 +- tests/ui/consts/const-promoted-opaque.rs | 34 +-- .../const-promoted-opaque.string.stderr | 6 +- .../consts/const-promoted-opaque.unit.stderr | 24 ++ .../collect-in-dead-fn-behind-opaque-type.rs | 1 + tests/ui/coroutine/layout-error.rs | 24 +- tests/ui/coroutine/layout-error.stderr | 6 +- .../metadata-sufficient-for-layout.rs | 1 + tests/ui/drop/drop_elaboration_with_errors.rs | 1 + .../drop/drop_elaboration_with_errors.stderr | 2 +- ...orted_main_const_fn_item_type_forbidden.rs | 6 +- ...d_main_const_fn_item_type_forbidden.stderr | 2 +- .../feature-gate-type_alias_impl_trait.rs | 9 +- tests/ui/fn/fn_def_opaque_coercion.rs | 5 + .../ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs | 3 + .../fn_def_opaque_coercion_to_fn_ptr.stderr | 4 +- .../generic-associated-types/issue-87258_b.rs | 1 + .../issue-87258_b.stderr | 2 +- .../generic-associated-types/issue-88287.rs | 1 + .../issue-88287.stderr | 2 +- .../issue-90014-tait.stderr | 15 +- .../issue-90014-tait2.rs | 1 + .../issue-90014-tait2.stderr | 2 +- ...e-method-resolution-opaque-type.old.stderr | 10 +- ...rm-before-method-resolution-opaque-type.rs | 1 + .../tait-hidden-erased-unsoundness-2.rs | 34 ++- .../tait-hidden-erased-unsoundness-2.stderr | 14 +- .../tait-hidden-erased-unsoundness.rs | 13 +- .../tait-hidden-erased-unsoundness.stderr | 15 +- .../ui/impl-trait/associated-type-undefine.rs | 1 + .../associated-type-undefine.stderr | 17 +- tests/ui/impl-trait/async_scope_creep.rs | 2 + tests/ui/impl-trait/auto-trait-coherence.rs | 1 + .../ui/impl-trait/auto-trait-coherence.stderr | 2 +- .../ui/impl-trait/bound-normalization-pass.rs | 1 + .../impl-trait/coherence-treats-tait-ambig.rs | 3 +- .../deduce-signature-from-supertrait.rs | 3 +- .../future-no-bound-vars-ice-112347.rs | 11 +- .../hidden-type-is-opaque-2.default.stderr | 2 +- .../hidden-type-is-opaque-2.next.stderr | 2 +- .../ui/impl-trait/hidden-type-is-opaque-2.rs | 1 + tests/ui/impl-trait/hidden-type-is-opaque.rs | 1 + ...bstituting-in-region-112823.current.stderr | 14 +- ...nsubstituting-in-region-112823.next.stderr | 18 +- ...-type-whensubstituting-in-region-112823.rs | 1 + .../in-assoc-type-unconstrained.stderr | 5 - tests/ui/impl-trait/in-assoc-type.stderr | 5 - tests/ui/impl-trait/issue-108591.rs | 1 + tests/ui/impl-trait/issue-108592.rs | 11 +- tests/ui/impl-trait/issue-99642-2.rs | 3 +- tests/ui/impl-trait/issues/issue-53457.rs | 1 + tests/ui/impl-trait/issues/issue-70877.rs | 38 +-- tests/ui/impl-trait/issues/issue-70877.stderr | 63 ++++- tests/ui/impl-trait/issues/issue-74282.rs | 3 +- tests/ui/impl-trait/issues/issue-74282.stderr | 10 +- tests/ui/impl-trait/issues/issue-77987.rs | 13 +- tests/ui/impl-trait/issues/issue-78722-2.rs | 1 + .../ui/impl-trait/issues/issue-78722-2.stderr | 8 +- tests/ui/impl-trait/issues/issue-78722.rs | 1 + tests/ui/impl-trait/issues/issue-78722.stderr | 6 +- tests/ui/impl-trait/issues/issue-86201.rs | 7 +- tests/ui/impl-trait/issues/issue-86800.rs | 24 +- tests/ui/impl-trait/issues/issue-86800.stderr | 40 ++-- tests/ui/impl-trait/issues/issue-89312.rs | 30 ++- .../issues/issue-99348-impl-compatibility.rs | 1 + .../multiple-lifetimes/error-handling-2.rs | 1 + .../error-handling-2.stderr | 4 +- .../multiple-lifetimes/error-handling.rs | 1 + .../multiple-lifetimes/error-handling.stderr | 2 +- ...nds-pick-original-type-alias-impl-trait.rs | 1 + tests/ui/impl-trait/negative-reasoning.rs | 1 + tests/ui/impl-trait/negative-reasoning.stderr | 2 +- .../ui/impl-trait/nested-return-type2-tait.rs | 4 +- .../nested-return-type2-tait.stderr | 2 +- .../impl-trait/nested-return-type2-tait2.rs | 4 +- .../impl-trait/nested-return-type2-tait3.rs | 4 +- .../ui/impl-trait/nested-return-type3-tait.rs | 4 +- .../nested-return-type3-tait.stderr | 2 +- .../impl-trait/nested-return-type3-tait2.rs | 4 +- .../impl-trait/nested-return-type3-tait3.rs | 4 +- .../impl-trait/normalize-tait-in-const.stderr | 32 ++- ...ias-impl-trait-declaration-too-subtle-2.rs | 10 +- ...alias-impl-trait-declaration-too-subtle.rs | 1 + ...s-impl-trait-declaration-too-subtle.stderr | 20 +- ...rsive-type-alias-impl-trait-declaration.rs | 1 + ...e-type-alias-impl-trait-declaration.stderr | 2 +- ...wo_tait_defining_each_other.current.stderr | 2 +- .../two_tait_defining_each_other.rs | 1 + ...o_tait_defining_each_other2.current.stderr | 10 +- .../two_tait_defining_each_other2.next.stderr | 2 +- .../two_tait_defining_each_other2.rs | 1 + ...o_tait_defining_each_other3.current.stderr | 2 +- .../two_tait_defining_each_other3.rs | 1 + .../type-alias-impl-trait-in-fn-body.rs | 1 + .../type-alias-impl-trait-in-fn-body.stderr | 6 +- tests/ui/impl-trait/where-allowed.rs | 1 + tests/ui/impl-trait/where-allowed.stderr | 58 +++-- tests/ui/implied-bounds/dyn-erasure-tait.rs | 1 + tests/ui/layout/debug.rs | 1 + tests/ui/layout/debug.stderr | 30 +-- .../ui/lazy-type-alias-impl-trait/branches.rs | 8 +- .../branches.stderr | 2 +- .../lazy-type-alias-impl-trait/branches2.rs | 13 +- .../lazy-type-alias-impl-trait/branches3.rs | 3 + .../branches3.stderr | 8 +- .../lazy-type-alias-impl-trait/recursion.rs | 5 +- .../lazy-type-alias-impl-trait/recursion2.rs | 3 +- .../lazy-type-alias-impl-trait/recursion3.rs | 5 +- .../recursion3.stderr | 4 +- .../lazy-type-alias-impl-trait/recursion4.rs | 1 + .../recursion4.stderr | 4 +- tests/ui/lint/issue-99387.rs | 1 + tests/ui/lint/issue-99387.stderr | 6 +- .../let_underscore/issue-119697-extra-let.rs | 2 +- .../issue-119697-extra-let.stderr | 4 +- tests/ui/lint/lint-ctypes-73249-2.rs | 1 + tests/ui/lint/lint-ctypes-73249-2.stderr | 2 +- tests/ui/lint/lint-ctypes-73249-3.rs | 1 + tests/ui/lint/lint-ctypes-73249-3.stderr | 2 +- tests/ui/lint/lint-ctypes-73249-5.rs | 1 + tests/ui/lint/lint-ctypes-73249-5.stderr | 2 +- tests/ui/lint/lint-ctypes-73251-1.rs | 1 + tests/ui/lint/lint-ctypes-73251-1.stderr | 2 +- tests/ui/lint/lint-ctypes-73251-2.rs | 2 + tests/ui/lint/lint-ctypes-73251-2.stderr | 2 +- tests/ui/lint/lint-ctypes-73251.rs | 1 + .../lint/opaque-ty-ffi-normalization-cycle.rs | 2 + .../opaque-ty-ffi-normalization-cycle.stderr | 2 +- tests/ui/lint/opaque-ty-ffi-unsafe.rs | 1 + tests/ui/lint/opaque-ty-ffi-unsafe.stderr | 2 +- tests/ui/methods/opaque_param_in_ufc.rs | 2 + tests/ui/mir/issue-75053.rs | 12 +- tests/ui/mir/issue-75053.stderr | 2 +- tests/ui/never_type/impl_trait_fallback2.rs | 2 + .../ui/never_type/impl_trait_fallback2.stderr | 2 +- tests/ui/never_type/impl_trait_fallback3.rs | 1 + .../ui/never_type/impl_trait_fallback3.stderr | 2 +- tests/ui/never_type/impl_trait_fallback4.rs | 1 + tests/ui/pattern/usefulness/impl-trait.rs | 6 + tests/ui/pattern/usefulness/impl-trait.stderr | 216 +++++++++--------- ...private-in-public-type-alias-impl-trait.rs | 1 + .../higher-ranked-regions-basic.rs | 13 +- .../higher-ranked-regions-basic.stderr | 53 ++--- .../higher-ranked-regions-gat.rs | 7 +- .../higher-ranked-regions-gat.stderr | 6 +- tests/ui/self/arbitrary-self-opaque.rs | 1 + tests/ui/self/arbitrary-self-opaque.stderr | 10 +- .../min_specialization/impl-on-opaque.rs | 1 + .../min_specialization/impl-on-opaque2.rs | 1 + tests/ui/traits/alias/issue-83613.rs | 1 + tests/ui/traits/alias/issue-83613.stderr | 2 +- .../alias-relate/tait-eq-proj-2.rs | 3 +- .../next-solver/alias-relate/tait-eq-proj.rs | 3 +- .../opaques/dont-remap-tait-substs.rs | 3 +- ...e_of-tait-in-defining-scope.is_send.stderr | 2 +- ..._of-tait-in-defining-scope.not_send.stderr | 2 +- .../dont-type_of-tait-in-defining-scope.rs | 4 +- .../no-define-in-wf-check.current.stderr | 14 +- .../opaques/no-define-in-wf-check.rs | 4 + .../traits/pointee-tail-is-generic-errors.rs | 1 + .../pointee-tail-is-generic-errors.stderr | 8 +- tests/ui/traits/pointee-tail-is-generic.rs | 11 +- .../type-checking-test-opaques.rs | 1 + .../trait-upcasting/upcast-defining-opaque.rs | 1 + .../coherence-bikeshed-intrinsic-from.stderr | 2 +- .../type-alias-impl-trait/argument-types.rs | 21 +- .../assoc-projection-ice.rs | 30 ++- .../associated-type-alias-impl-trait.rs | 2 + .../auto-trait-leakage.rs | 11 +- .../auto-trait-leakage2.rs | 17 +- .../auto-trait-leakage2.stderr | 18 +- .../auto-trait-leakage3.rs | 4 +- .../auto-trait-leakage3.stderr | 22 -- .../auxiliary/cross_crate_ice.rs | 1 + .../auxiliary/drop-shim-relates-opaque-aux.rs | 1 + .../bad-tait-no-substs.rs | 2 +- .../bad-tait-no-substs.stderr | 22 +- ...ariant-duplicate-lifetime-unconstrained.rs | 1 + .../bound-lifetime-through-dyn-trait.rs | 2 +- .../bound-lifetime-through-dyn-trait.stderr | 6 +- .../type-alias-impl-trait/bound_reduction.rs | 1 + .../type-alias-impl-trait/bound_reduction2.rs | 2 +- .../bound_reduction2.stderr | 14 +- .../bounds-are-checked-2.rs | 12 +- .../bounds-are-checked-2.stderr | 22 +- .../bounds-are-checked.rs | 1 + .../bounds-are-checked.stderr | 2 +- .../bounds-are-checked3.rs | 1 + tests/ui/type-alias-impl-trait/bounds.rs | 1 + .../closure-normalization-ice-109020.rs | 10 +- .../ui/type-alias-impl-trait/closure_args.rs | 24 +- .../ui/type-alias-impl-trait/closure_args2.rs | 36 ++- .../ui/type-alias-impl-trait/closure_infer.rs | 2 + .../closure_parent_substs.rs | 3 + .../closure_wf_outlives.rs | 4 + .../closure_wf_outlives.stderr | 16 +- .../closures_in_branches.rs | 3 +- .../closures_in_branches.stderr | 4 +- .../coherence.classic.stderr | 2 +- .../coherence.next.stderr | 2 +- tests/ui/type-alias-impl-trait/coherence.rs | 1 + .../coherence_cross_crate.rs | 1 + .../coherence_cross_crate.stderr | 2 +- .../coherence_different_hidden_ty.rs | 1 + .../coherence_generalization.rs | 1 + .../const_generic_type.infer.stderr | 6 +- .../const_generic_type.no_infer.stderr | 28 +-- .../const_generic_type.rs | 3 +- .../constrain_in_projection.current.stderr | 4 +- .../constrain_in_projection.rs | 3 +- .../constrain_in_projection2.current.stderr | 4 +- .../constrain_in_projection2.next.stderr | 2 +- .../constrain_in_projection2.rs | 3 +- .../type-alias-impl-trait/constrain_inputs.rs | 5 + .../constrain_inputs.stderr | 30 +-- .../constrain_inputs_unsound.rs | 5 +- .../constrain_inputs_unsound.stderr | 2 +- .../debug-ty-with-weak.rs | 10 +- .../declared_but_never_defined.stderr | 2 +- .../declared_but_not_defined_in_scope.stderr | 4 +- .../defined-by-user-annotation.rs | 3 + .../defined-in-closure-external-lifetime.rs | 2 + ...efined-in-closure-external-lifetime.stderr | 8 +- .../defining-use-submodule.rs | 11 + .../destructure_tait-ice-113594.rs | 1 + .../different_args_considered_equal.rs | 2 + .../different_args_considered_equal.stderr | 8 +- .../different_args_considered_equal2.rs | 1 + .../different_args_considered_equal2.stderr | 4 +- .../different_args_considered_equal3.rs | 10 +- .../different_args_considered_equal3.stderr | 2 +- .../different_defining_uses.rs | 2 + .../different_defining_uses.stderr | 4 +- .../different_defining_uses_never_type-2.rs | 1 + ...ifferent_defining_uses_never_type-2.stderr | 8 +- .../different_defining_uses_never_type-3.rs | 1 + ...ifferent_defining_uses_never_type-3.stderr | 4 +- .../different_defining_uses_never_type.rs | 3 + .../different_defining_uses_never_type.stderr | 4 +- .../different_defining_uses_never_type2.rs | 5 + .../different_defining_uses_never_type3.rs | 2 + ...different_defining_uses_never_type3.stderr | 4 +- .../different_lifetimes_defining_uses.rs | 2 + .../different_lifetimes_defining_uses.stderr | 4 +- .../drop-analysis-on-unconstrained-tait.rs | 36 +-- ...drop-analysis-on-unconstrained-tait.stderr | 8 +- ...ate-lifetimes-from-rpit-containing-tait.rs | 1 + .../equal-lifetime-params-not-ok.rs | 5 +- .../equal-lifetime-params-not-ok.stderr | 25 +- .../equal-lifetime-params-ok.rs | 2 + .../escaping-bound-var.rs | 1 + .../failed-to-normalize-ice-99945.rs | 2 + .../failed-to-normalize-ice-99945.stderr | 36 +-- tests/ui/type-alias-impl-trait/fallback.rs | 5 +- .../ui/type-alias-impl-trait/fallback.stderr | 2 +- tests/ui/type-alias-impl-trait/field-types.rs | 4 + tests/ui/type-alias-impl-trait/future.rs | 1 + tests/ui/type-alias-impl-trait/future.stderr | 4 +- .../generic-not-strictly-equal.basic.stderr | 2 +- ...t-strictly-equal.member_constraints.stderr | 4 +- .../generic-not-strictly-equal.rs | 1 + .../generic_different_defining_uses.rs | 2 + .../generic_different_defining_uses.stderr | 4 +- .../generic_duplicate_lifetime_param.rs | 2 +- .../generic_duplicate_lifetime_param.stderr | 14 +- .../generic_duplicate_param_use.rs | 6 +- .../generic_duplicate_param_use.stderr | 38 +-- .../generic_duplicate_param_use10.rs | 1 + .../generic_duplicate_param_use2.rs | 1 + .../generic_duplicate_param_use2.stderr | 4 +- .../generic_duplicate_param_use3.rs | 2 + .../generic_duplicate_param_use3.stderr | 4 +- .../generic_duplicate_param_use4.rs | 1 + .../generic_duplicate_param_use4.stderr | 4 +- .../generic_duplicate_param_use5.rs | 2 + .../generic_duplicate_param_use5.stderr | 4 +- .../generic_duplicate_param_use6.rs | 2 + .../generic_duplicate_param_use6.stderr | 4 +- .../generic_duplicate_param_use7.rs | 4 + .../generic_duplicate_param_use8.rs | 2 + .../generic_duplicate_param_use8.stderr | 4 +- .../generic_duplicate_param_use9.rs | 2 + .../generic_duplicate_param_use9.stderr | 4 +- .../generic_lifetime_param.rs | 1 + .../generic_nondefining_use.rs | 6 +- .../generic_nondefining_use.stderr | 38 +-- .../type-alias-impl-trait/generic_not_used.rs | 1 + .../generic_not_used.stderr | 2 +- .../generic_type_does_not_live_long_enough.rs | 1 + ...eric_type_does_not_live_long_enough.stderr | 2 +- .../generic_underconstrained.rs | 1 + .../generic_underconstrained.stderr | 4 +- .../generic_underconstrained2.rs | 2 + .../generic_underconstrained2.stderr | 12 +- ...n_behind_projection_behind_struct_field.rs | 1 + ...hind_projection_behind_struct_field.stderr | 19 +- .../hidden_behind_struct_field2.rs | 1 + .../hidden_behind_struct_field2.stderr | 19 +- .../hidden_behind_struct_field3.rs | 1 + .../hidden_behind_struct_field3.stderr | 17 +- .../hidden_type_mismatch.rs | 2 + .../hidden_type_mismatch.stderr | 10 +- .../higher_kinded_params.rs | 1 + .../higher_kinded_params2.rs | 3 +- .../higher_kinded_params2.stderr | 20 -- .../higher_kinded_params3.rs | 1 + .../higher_kinded_params3.stderr | 11 +- .../ui/type-alias-impl-trait/hkl_forbidden.rs | 5 + .../hkl_forbidden.stderr | 14 +- .../type-alias-impl-trait/hkl_forbidden2.rs | 1 + .../hkl_forbidden2.stderr | 2 +- .../type-alias-impl-trait/hkl_forbidden3.rs | 1 + .../hkl_forbidden3.stderr | 2 +- .../type-alias-impl-trait/hkl_forbidden4.rs | 1 + .../hkl_forbidden4.stderr | 58 ++--- ...e-failed-to-resolve-instance-for-110696.rs | 3 + ...iled-to-resolve-instance-for-110696.stderr | 10 +- ...mpl-trait-in-type-alias-with-bad-substs.rs | 1 + ...trait-in-type-alias-with-bad-substs.stderr | 10 +- .../impl_for_weak_alias.rs | 1 + .../impl_trait_for_generic_tait.rs | 1 + .../impl_trait_for_same_tait.rs | 2 + .../impl_trait_for_same_tait.stderr | 6 +- .../impl_trait_for_tait.rs | 1 + .../impl_trait_for_tait_bound.rs | 13 +- .../impl_trait_for_tait_bound.stderr | 6 +- .../impl_trait_for_tait_bound2.rs | 7 +- .../impl_trait_for_tait_bound2.stderr | 6 +- ...rait_in_trait_defined_outside_trait.stderr | 10 - .../type-alias-impl-trait/implied_bounds.rs | 9 +- .../implied_bounds.stderr | 2 +- .../type-alias-impl-trait/implied_bounds2.rs | 10 +- .../implied_bounds_from_types.rs | 9 +- .../implied_bounds_from_types.stderr | 2 +- .../implied_lifetime_wf_check.error.stderr | 2 +- .../implied_lifetime_wf_check.rs | 1 + .../implied_lifetime_wf_check3.rs | 13 +- .../implied_lifetime_wf_check3.stderr | 8 +- .../implied_lifetime_wf_check4_static.rs | 14 +- .../implied_lifetime_wf_check4_static.stderr | 24 +- .../imply_bounds_from_bounds.rs | 22 +- .../type-alias-impl-trait/in-where-clause.rs | 1 + .../in-where-clause.stderr | 6 +- .../incomplete-inference.rs | 2 + .../incomplete-inference.stderr | 2 +- .../type-alias-impl-trait/inference-cycle.rs | 32 +-- .../inference-cycle.stderr | 22 -- .../infinite-cycle-involving-weak.rs | 5 +- .../invalid_impl_trait_in_assoc_ty.rs | 1 + .../invalid_impl_trait_in_assoc_ty.stderr | 19 +- .../ui/type-alias-impl-trait/issue-101750.rs | 17 +- .../ui/type-alias-impl-trait/issue-104817.rs | 1 + .../issue-104817.stock.stderr | 2 +- .../ui/type-alias-impl-trait/issue-109054.rs | 2 + .../type-alias-impl-trait/issue-109054.stderr | 10 +- .../issue-52843-closure-constrain.rs | 13 -- .../issue-52843-closure-constrain.stderr | 14 -- tests/ui/type-alias-impl-trait/issue-52843.rs | 1 + .../type-alias-impl-trait/issue-52843.stderr | 4 +- .../ui/type-alias-impl-trait/issue-53092-2.rs | 9 +- .../issue-53092-2.stderr | 77 ++----- tests/ui/type-alias-impl-trait/issue-53092.rs | 11 +- .../type-alias-impl-trait/issue-53092.stderr | 16 +- tests/ui/type-alias-impl-trait/issue-53096.rs | 10 +- .../type-alias-impl-trait/issue-53096.stderr | 2 +- .../issue-53678-coroutine-and-const-fn.rs | 19 +- .../issue-55099-lifetime-inference.rs | 1 + tests/ui/type-alias-impl-trait/issue-57961.rs | 1 + .../issue-58662-coroutine-with-lifetime.rs | 2 + .../issue-58662-simplified.rs | 5 +- .../ui/type-alias-impl-trait/issue-58951-2.rs | 10 +- tests/ui/type-alias-impl-trait/issue-58951.rs | 11 +- tests/ui/type-alias-impl-trait/issue-60407.rs | 10 +- .../type-alias-impl-trait/issue-60407.stderr | 2 +- tests/ui/type-alias-impl-trait/issue-60564.rs | 2 +- .../type-alias-impl-trait/issue-60564.stderr | 14 +- .../issue-63263-closure-return.rs | 1 + tests/ui/type-alias-impl-trait/issue-63279.rs | 1 + .../type-alias-impl-trait/issue-63279.stderr | 12 +- tests/ui/type-alias-impl-trait/issue-63355.rs | 3 + .../type-alias-impl-trait/issue-63355.stderr | 10 +- .../issue-63677-type-alias-coherence.rs | 5 +- tests/ui/type-alias-impl-trait/issue-65384.rs | 3 +- ...sue-65679-inst-opaque-ty-from-val-twice.rs | 23 +- tests/ui/type-alias-impl-trait/issue-65918.rs | 12 +- .../issue-66580-closure-coherence.rs | 1 + .../issue-67844-nested-opaque.rs | 1 + .../issue-68368-non-defining-use-2.rs | 4 +- .../issue-68368-non-defining-use-2.stderr | 18 +- .../issue-68368-non-defining-use.rs | 2 +- .../issue-68368-non-defining-use.stderr | 18 +- ...ssue-69136-inner-lifetime-resolve-error.rs | 1 + .../issue-69136-inner-lifetime-resolve-ok.rs | 1 + tests/ui/type-alias-impl-trait/issue-69323.rs | 1 + tests/ui/type-alias-impl-trait/issue-70121.rs | 1 + .../type-alias-impl-trait/issue-70121.stderr | 6 +- tests/ui/type-alias-impl-trait/issue-72793.rs | 29 ++- tests/ui/type-alias-impl-trait/issue-74244.rs | 1 + tests/ui/type-alias-impl-trait/issue-74280.rs | 1 + .../type-alias-impl-trait/issue-74280.stderr | 2 +- .../issue-76202-trait-impl-for-tait.rs | 29 +-- tests/ui/type-alias-impl-trait/issue-77179.rs | 3 +- .../type-alias-impl-trait/issue-77179.stderr | 40 ++-- .../issue-84660-trait-impl-for-tait.rs | 1 + .../issue-84660-unsoundness.current.stderr | 10 +- .../issue-84660-unsoundness.next.stderr | 4 +- .../issue-84660-unsoundness.rs | 4 +- tests/ui/type-alias-impl-trait/issue-89686.rs | 1 + .../type-alias-impl-trait/issue-89686.stderr | 2 +- tests/ui/type-alias-impl-trait/issue-93411.rs | 1 + .../issue-96572-unconstrained.rs | 3 + .../itiat-forbid-nested-items.stderr | 5 - .../lazy_subtyping_of_opaques.rs | 1 + .../lazy_subtyping_of_opaques.stderr | 6 +- .../lifetime_mismatch.rs | 2 + .../lifetime_mismatch.stderr | 8 +- .../method_resolution.current.stderr | 2 +- .../method_resolution.next.stderr | 2 +- .../method_resolution.rs | 2 + .../method_resolution2.rs | 2 + .../method_resolution3.rs | 1 + .../method_resolution4.current.stderr | 4 +- .../method_resolution4.next.stderr | 4 +- .../method_resolution4.rs | 10 +- .../method_resolution5.rs | 8 +- ...on_trait_method_from_opaque.current.stderr | 8 +- ...ution_trait_method_from_opaque.next.stderr | 2 +- ...hod_resolution_trait_method_from_opaque.rs | 2 + .../missing_lifetime_bound.rs | 1 + .../missing_lifetime_bound.stderr | 6 +- .../multiple-def-uses-in-one-fn-infer.rs | 1 + .../multiple-def-uses-in-one-fn-infer.stderr | 2 +- .../multiple-def-uses-in-one-fn-lifetimes.rs | 1 + ...ltiple-def-uses-in-one-fn-lifetimes.stderr | 4 +- .../multiple-def-uses-in-one-fn-pass.rs | 2 + .../multiple-def-uses-in-one-fn.rs | 1 + .../multiple-def-uses-in-one-fn.stderr | 2 +- .../multiple-def-uses-in-one-fn2.rs | 1 + .../multiple-def-uses-in-one-fn2.stderr | 2 +- .../multiple-def-uses-in-one-fn3.rs | 2 + .../multiple-def-uses-in-one-fn3.stderr | 2 +- .../nested-impl-trait-in-tait.stderr | 4 +- .../nested-in-anon-const.stderr | 2 +- .../type-alias-impl-trait/nested-tait-hrtb.rs | 2 + .../nested-tait-hrtb.stderr | 7 +- .../nested-tait-inference.current.stderr | 2 +- .../nested-tait-inference.rs | 1 + .../nested-tait-inference2.current.stderr | 2 +- .../nested-tait-inference2.next.stderr | 2 +- .../nested-tait-inference2.rs | 1 + .../nested-tait-inference3.rs | 1 + .../nested-tait-inference3.stderr | 8 +- tests/ui/type-alias-impl-trait/nested.rs | 1 + tests/ui/type-alias-impl-trait/nested.stderr | 10 +- .../nested_inference_failure.rs | 1 + .../nested_type_alias_impl_trait.rs | 24 +- .../nested_type_alias_impl_trait.stderr | 36 +-- .../never_reveal_concrete_type.rs | 2 + .../no_inferrable_concrete_type.rs | 15 +- .../no_inferrable_concrete_type.stderr | 18 +- .../no_revealing_outside_defining_module.rs | 13 +- ...o_revealing_outside_defining_module.stderr | 26 +-- .../normalize-alias-type.rs | 15 +- .../normalize-hidden-types.current.stderr | 14 +- .../normalize-hidden-types.rs | 5 + .../not-matching-trait-refs-isnt-defining.rs | 1 + ...t-matching-trait-refs-isnt-defining.stderr | 17 +- .../not_a_defining_use.rs | 2 + .../not_a_defining_use.stderr | 4 +- .../type-alias-impl-trait/not_well_formed.rs | 1 + .../type-alias-impl-trait/obligation_ice.rs | 1 + .../outlives-bound-var.rs | 8 +- .../type-alias-impl-trait/param_mismatch.rs | 1 + .../param_mismatch.stderr | 2 +- .../type-alias-impl-trait/param_mismatch2.rs | 1 + .../param_mismatch2.stderr | 2 +- .../type-alias-impl-trait/param_mismatch3.rs | 2 + .../param_mismatch3.stderr | 4 +- .../type-alias-impl-trait/param_mismatch4.rs | 1 + .../param_mismatch4.stderr | 2 +- .../path_resolution_taint.rs | 16 ++ .../path_resolution_taint.stderr | 9 + tests/ui/type-alias-impl-trait/privacy.rs | 1 + tests/ui/type-alias-impl-trait/privacy.stderr | 2 +- .../recursive-fn-tait.rs | 2 + .../recursive-fn-tait.stderr | 6 +- .../recursive-tait-conflicting-defn-2.rs | 6 +- .../recursive-tait-conflicting-defn-2.stderr | 8 +- .../recursive-tait-conflicting-defn.rs | 29 ++- .../recursive-tait-conflicting-defn.stderr | 12 +- .../ui/type-alias-impl-trait/reveal_local.rs | 7 +- .../type-alias-impl-trait/reveal_local.stderr | 22 +- .../rpit_tait_equality_in_canonical_query.rs | 15 +- ...rpit_tait_equality_in_canonical_query_2.rs | 12 +- .../self-referential-2.current.stderr | 2 +- .../self-referential-2.rs | 1 + .../self-referential-3.rs | 1 + .../self-referential-3.stderr | 2 +- .../self-referential-4.rs | 3 + .../self-referential-4.stderr | 6 +- .../type-alias-impl-trait/self-referential.rs | 3 + .../self-referential.stderr | 6 +- .../type-alias-impl-trait/self_implication.rs | 9 +- .../static-const-types.rs | 13 -- .../structural-match-no-leak.rs | 16 +- .../structural-match-no-leak.stderr | 4 +- .../type-alias-impl-trait/structural-match.rs | 17 +- .../structural-match.stderr | 4 +- tests/ui/type-alias-impl-trait/taint.rs | 1 + tests/ui/type-alias-impl-trait/taint.stderr | 2 +- ...function-return-type-issue-101903-fixed.rs | 1 + .../tait-param-inference-issue-117310.rs | 2 + .../type-alias-impl-trait-assoc-dyn.rs | 1 + .../type-alias-impl-trait-assoc-impl-trait.rs | 2 + .../type-alias-impl-trait-const.rs | 12 +- .../type-alias-impl-trait-const.stderr | 57 +++++ .../type-alias-impl-trait-fns.rs | 4 +- .../type-alias-impl-trait-fns.stderr | 10 +- .../type-alias-impl-trait-sized.rs | 4 + .../type-alias-impl-trait-struct.rs | 1 + .../type-alias-impl-trait-tuple.rs | 15 +- ...alias-impl-trait-with-cycle-error-1.stderr | 11 +- ...alias-impl-trait-with-cycle-error-2.stderr | 11 +- ...alias-impl-trait-with-cycle-error-3.stderr | 11 +- .../type-alias-impl-trait-with-no-traits.rs | 1 + ...ype-alias-impl-trait-with-no-traits.stderr | 2 +- .../type-alias-impl-trait.rs | 20 +- .../type-alias-impl-trait2.rs | 135 +++++------ .../type-alias-nested-impl-trait.rs | 3 +- .../type_of_a_let.current.stderr | 4 +- .../ui/type-alias-impl-trait/type_of_a_let.rs | 2 + .../unbounded_opaque_type.rs | 9 +- .../unconstrained-due-to-bad-pattern.rs | 1 + .../unconstrained-due-to-bad-pattern.stderr | 2 +- .../unconstrained-impl-param.rs | 1 + .../unconstrained-impl-param.stderr | 2 +- .../ui/type-alias-impl-trait/under-binder.rs | 1 + .../type-alias-impl-trait/under-binder.stderr | 2 +- .../underconstrained_generic.rs | 5 +- .../underconstrained_generic.stderr | 4 +- .../underconstrained_lifetime.rs | 1 + .../underconstrained_lifetime.stderr | 2 +- .../underef-index-out-of-bounds-121472.rs | 1 + .../underef-index-out-of-bounds-121472.stderr | 14 +- .../type-alias-impl-trait/unnameable_type.rs | 1 + .../unnameable_type.stderr | 4 +- .../unused_generic_param.rs | 3 + tests/ui/type-alias-impl-trait/variance.rs | 1 + .../ui/type-alias-impl-trait/variance.stderr | 10 +- .../weird-return-types.rs | 3 +- .../wf-check-definition-site.rs | 6 +- .../type-alias-impl-trait/wf-check-fn-def.rs | 5 +- .../wf-check-fn-def.stderr | 6 +- .../type-alias-impl-trait/wf-check-fn-ptrs.rs | 5 +- tests/ui/type-alias-impl-trait/wf-nested.rs | 3 +- .../ui/type-alias-impl-trait/wf-nested.stderr | 2 +- .../wf_check_closures.rs | 3 +- .../wf_check_closures.stderr | 8 +- .../ui/typeck/typeck_type_placeholder_item.rs | 1 + .../typeck_type_placeholder_item.stderr | 42 ++-- 653 files changed, 2911 insertions(+), 2580 deletions(-) create mode 100644 compiler/rustc_builtin_macros/src/define_opaque.rs delete mode 100644 src/tools/clippy/tests/ui/crashes/ice-10972-tait.rs delete mode 100644 tests/crashes/131298.rs create mode 100644 tests/ui/consts/const-promoted-opaque.unit.stderr delete mode 100644 tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr delete mode 100644 tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr delete mode 100644 tests/ui/type-alias-impl-trait/inference-cycle.stderr delete mode 100644 tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs delete mode 100644 tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr create mode 100644 tests/ui/type-alias-impl-trait/path_resolution_taint.rs create mode 100644 tests/ui/type-alias-impl-trait/path_resolution_taint.stderr delete mode 100644 tests/ui/type-alias-impl-trait/static-const-types.rs create mode 100644 tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr diff --git a/Cargo.lock b/Cargo.lock index ecd26d6199c9..a6471b195b97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4529,6 +4529,7 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_abi", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 002435b2d032..1b831c454e6d 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3466,6 +3466,7 @@ pub struct Fn { pub generics: Generics, pub sig: FnSig, pub contract: Option>, + pub define_opaque: Option>, pub body: Option>, } @@ -3763,7 +3764,7 @@ mod size_asserts { static_assert_size!(Block, 32); static_assert_size!(Expr, 72); static_assert_size!(ExprKind, 40); - static_assert_size!(Fn, 168); + static_assert_size!(Fn, 176); static_assert_size!(ForeignItem, 88); static_assert_size!(ForeignItemKind, 16); static_assert_size!(GenericArg, 24); diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index ee894db7b966..e4396a50a15e 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -973,7 +973,14 @@ fn walk_fn(vis: &mut T, kind: FnKind<'_>) { _ctxt, _ident, _vis, - Fn { defaultness, generics, contract, body, sig: FnSig { header, decl, span } }, + Fn { + defaultness, + generics, + contract, + body, + sig: FnSig { header, decl, span }, + define_opaque, + }, ) => { // Identifier and visibility are visited as a part of the item. visit_defaultness(vis, defaultness); @@ -987,6 +994,11 @@ fn walk_fn(vis: &mut T, kind: FnKind<'_>) { vis.visit_block(body); } vis.visit_span(span); + + for (id, path) in define_opaque.iter_mut().flatten() { + vis.visit_id(id); + vis.visit_path(path) + } } FnKind::Closure(binder, coroutine_kind, decl, body) => { vis.visit_closure_binder(binder); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 43ffbe9b071d..cfcb0e23cb5e 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -892,7 +892,14 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu _ctxt, _ident, _vis, - Fn { defaultness: _, sig: FnSig { header, decl, span: _ }, generics, contract, body }, + Fn { + defaultness: _, + sig: FnSig { header, decl, span: _ }, + generics, + contract, + body, + define_opaque, + }, ) => { // Identifier and visibility are visited as a part of the item. try_visit!(visitor.visit_fn_header(header)); @@ -900,6 +907,9 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu try_visit!(visitor.visit_fn_decl(decl)); visit_opt!(visitor, visit_contract, contract); visit_opt!(visitor, visit_block, body); + for (id, path) in define_opaque.iter().flatten() { + try_visit!(visitor.visit_path(path, *id)) + } } FnKind::Closure(binder, coroutine_kind, decl, body) => { try_visit!(visitor.visit_closure_binder(binder)); @@ -1203,7 +1213,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id - )) + )); } ExprKind::Block(block, opt_label) => { visit_opt!(visitor, visit_label, opt_label); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 5e89321e6ecc..0aa42a0c4e75 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -3,10 +3,9 @@ use rustc_ast::ptr::P; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; use rustc_errors::ErrorGuaranteed; -use rustc_hir as hir; -use rustc_hir::PredicateOrigin; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; +use rustc_hir::{self as hir, HirId, PredicateOrigin}; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; @@ -209,6 +208,7 @@ impl<'hir> LoweringContext<'_, 'hir> { generics, body, contract, + define_opaque, .. }) => { self.with_new_scopes(*fn_sig_span, |this| { @@ -237,6 +237,7 @@ impl<'hir> LoweringContext<'_, 'hir> { header: this.lower_fn_header(*header, hir::Safety::Safe, attrs), span: this.lower_span(*fn_sig_span), }; + this.lower_define_opaque(hir_id, &define_opaque); hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() } }) } @@ -779,7 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); (generics, kind, expr.is_some()) } - AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => { + AssocItemKind::Fn(box Fn { sig, generics, body: None, define_opaque, .. }) => { // FIXME(contracts): Deny contract here since it won't apply to // any impl method or callees. let names = self.lower_fn_params_to_names(&sig.decl); @@ -791,9 +792,22 @@ impl<'hir> LoweringContext<'_, 'hir> { sig.header.coroutine_kind, attrs, ); + if define_opaque.is_some() { + self.dcx().span_err( + i.span, + "only trait methods with default bodies can define opaque types", + ); + } (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false) } - AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), contract, .. }) => { + AssocItemKind::Fn(box Fn { + sig, + generics, + body: Some(body), + contract, + define_opaque, + .. + }) => { let body_id = self.lower_maybe_coroutine_body( sig.span, i.span, @@ -812,6 +826,7 @@ impl<'hir> LoweringContext<'_, 'hir> { sig.header.coroutine_kind, attrs, ); + self.lower_define_opaque(hir_id, &define_opaque); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true) } AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => { @@ -911,7 +926,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ImplItemKind::Const(ty, body) }, ), - AssocItemKind::Fn(box Fn { sig, generics, body, contract, .. }) => { + AssocItemKind::Fn(box Fn { sig, generics, body, contract, define_opaque, .. }) => { let body_id = self.lower_maybe_coroutine_body( sig.span, i.span, @@ -930,6 +945,7 @@ impl<'hir> LoweringContext<'_, 'hir> { sig.header.coroutine_kind, attrs, ); + self.lower_define_opaque(hir_id, &define_opaque); (generics, hir::ImplItemKind::Fn(sig, body_id)) } @@ -1657,6 +1673,31 @@ impl<'hir> LoweringContext<'_, 'hir> { (lowered_generics, res) } + pub(super) fn lower_define_opaque( + &mut self, + hir_id: HirId, + define_opaque: &Option>, + ) { + assert_eq!(self.define_opaque, None); + assert!(hir_id.is_owner()); + let Some(define_opaque) = define_opaque.as_ref() else { + return; + }; + let define_opaque = define_opaque + .iter() + // TODO: error reporting for non-local items being mentioned and tests that go through these code paths + .map(|(id, _path)| { + self.resolver + .get_partial_res(*id) + .unwrap() + .expect_full_res() + .def_id() + .expect_local() + }); + let define_opaque = self.arena.alloc_from_iter(define_opaque); + self.define_opaque = Some(define_opaque); + } + pub(super) fn lower_generic_bound_predicate( &mut self, ident: Ident, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4cecc56909e5..e42a4b460fea 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -35,6 +35,7 @@ #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] +#![feature(exact_size_is_empty)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(rustdoc_internals)] @@ -97,6 +98,8 @@ struct LoweringContext<'a, 'hir> { /// Bodies inside the owner being lowered. bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>, + /// `#[define_opaque]` attributes + define_opaque: Option<&'hir [LocalDefId]>, /// Attributes inside the owner being lowered. attrs: SortedMap, /// Collect items that were created by lowering the current owner. @@ -154,6 +157,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // HirId handling. bodies: Vec::new(), + define_opaque: None, attrs: SortedMap::default(), children: Vec::default(), contract_ensures: None, @@ -546,6 +550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let current_attrs = std::mem::take(&mut self.attrs); let current_bodies = std::mem::take(&mut self.bodies); + let current_define_opaque = std::mem::take(&mut self.define_opaque); let current_ident_and_label_to_local_id = std::mem::take(&mut self.ident_and_label_to_local_id); @@ -579,6 +584,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.attrs = current_attrs; self.bodies = current_bodies; + self.define_opaque = current_define_opaque; self.ident_and_label_to_local_id = current_ident_and_label_to_local_id; #[cfg(debug_assertions)] @@ -598,6 +604,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> { let attrs = std::mem::take(&mut self.attrs); let mut bodies = std::mem::take(&mut self.bodies); + let define_opaque = std::mem::take(&mut self.define_opaque); let trait_map = std::mem::take(&mut self.trait_map); #[cfg(debug_assertions)] @@ -617,7 +624,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let num_nodes = self.item_local_id_counter.as_usize(); let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes); let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies }; - let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash }; + let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque }; self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map }) } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index f9f4035cb22f..232d60be4eb2 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -917,7 +917,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. } - ItemKind::Fn(func @ box Fn { defaultness, generics: _, sig, contract: _, body }) => { + ItemKind::Fn( + func + @ box Fn { defaultness, generics: _, sig, contract: _, body, define_opaque: _ }, + ) => { self.check_defaultness(item.span, *defaultness); let is_intrinsic = diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 01fc272a4589..a8eaff7346b7 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -24,7 +24,6 @@ use rustc_span::edition::Edition; use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::symbol::IdentPrinter; use rustc_span::{BytePos, CharPos, DUMMY_SP, FileName, Ident, Pos, Span, Symbol, kw, sym}; -use thin_vec::ThinVec; use crate::pp::Breaks::{Consistent, Inconsistent}; use crate::pp::{self, Breaks}; @@ -1978,15 +1977,7 @@ impl<'a> State<'a> { ) { self.ibox(INDENT_UNIT); self.print_formal_generic_params(generic_params); - let generics = ast::Generics { - params: ThinVec::new(), - where_clause: ast::WhereClause { - has_where_token: false, - predicates: ThinVec::new(), - span: DUMMY_SP, - }, - span: DUMMY_SP, - }; + let generics = ast::Generics::default(); let header = ast::FnHeader { safety, ext, ..ast::FnHeader::default() }; self.print_fn(decl, header, name, &generics); self.end(); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index ced0cbd2fef6..6236f8ecfb52 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -650,7 +650,16 @@ impl<'a> State<'a> { attrs: &[ast::Attribute], func: &ast::Fn, ) { - let ast::Fn { defaultness, generics, sig, contract, body } = func; + let ast::Fn { defaultness, generics, sig, contract, body, define_opaque } = func; + + if let Some(define_opaque) = define_opaque { + for (_, path) in define_opaque { + self.word("define opaques from "); + self.print_path(path, false, 0); + self.word(","); + } + } + if body.is_some() { self.head(""); } @@ -698,7 +707,7 @@ impl<'a> State<'a> { } self.print_generic_params(&generics.params); self.print_fn_params_and_ret(decl, false); - self.print_where_clause(&generics.where_clause) + self.print_where_clause(&generics.where_clause); } pub(crate) fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) { diff --git a/compiler/rustc_borrowck/src/type_check/opaque_types.rs b/compiler/rustc_borrowck/src/type_check/opaque_types.rs index 17482cc0cbd2..94b3d0c2bbf2 100644 --- a/compiler/rustc_borrowck/src/type_check/opaque_types.rs +++ b/compiler/rustc_borrowck/src/type_check/opaque_types.rs @@ -180,6 +180,7 @@ pub(super) fn take_opaques_and_register_member_constraints<'tcx>( /// // Equivalent to: /// # mod dummy { use super::*; /// type FooReturn<'a, T> = impl Foo<'a>; +/// #[define_opaque(FooReturn)] /// fn foo<'a, T>(x: &'a u32, y: T) -> FooReturn<'a, T> { /// (x, y) /// } diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 78bf2195975d..1c1b2c88f76e 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -88,6 +88,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span generics: Generics::default(), contract: None, body, + define_opaque: None, })); let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 7b5c4a159b0c..bb17efa02e0e 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -247,6 +247,7 @@ mod llvm_enzyme { generics: Generics::default(), contract: None, body: Some(d_body), + define_opaque: None, }); let mut rustc_ad_attr = P(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff))); diff --git a/compiler/rustc_builtin_macros/src/define_opaque.rs b/compiler/rustc_builtin_macros/src/define_opaque.rs new file mode 100644 index 000000000000..9777e772cf20 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/define_opaque.rs @@ -0,0 +1,54 @@ +use rustc_ast::{DUMMY_NODE_ID, ast}; +use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_span::Span; + +pub(crate) fn expand( + ecx: &mut ExtCtxt<'_>, + _expand_span: Span, + meta_item: &ast::MetaItem, + mut item: Annotatable, +) -> Vec { + let define_opaque = match &mut item { + Annotatable::Item(p) => match &mut p.kind { + ast::ItemKind::Fn(f) => Some(&mut f.define_opaque), + _ => None, + }, + Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind { + ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque), + _ => None, + }, + Annotatable::Stmt(s) => match &mut s.kind { + ast::StmtKind::Item(p) => match &mut p.kind { + ast::ItemKind::Fn(f) => Some(&mut f.define_opaque), + _ => None, + }, + _ => None, + }, + _ => None, + }; + + let Some(list) = meta_item.meta_item_list() else { + ecx.dcx().span_err(meta_item.span, "expected list of type aliases"); + return vec![item]; + }; + + if let Some(define_opaque) = define_opaque { + *define_opaque = Some( + list.iter() + .filter_map(|entry| match entry { + ast::MetaItemInner::MetaItem(meta_item) if meta_item.is_word() => { + Some((DUMMY_NODE_ID, meta_item.path.clone())) + } + _ => { + ecx.dcx().span_err(entry.span(), "expected path to type alias"); + None + } + }) + .collect(), + ); + } else { + ecx.dcx().span_err(meta_item.span, "only functions and methods can define opaque types"); + } + + vec![item] +} diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 5402b5a1ae9f..03ee59de70e1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -1040,6 +1040,7 @@ impl<'a> MethodDef<'a> { generics: fn_generics, contract: None, body: Some(body_block), + define_opaque: None, })), tokens: None, }) diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 8fdbbf8e704a..90d79235820f 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -83,6 +83,7 @@ impl AllocFnFactory<'_, '_> { generics: Generics::default(), contract: None, body, + define_opaque: None, })); let item = self.cx.item( self.span, diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index c23ce1e5e4a2..1defd3867a05 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -38,6 +38,7 @@ mod compile_error; mod concat; mod concat_bytes; mod concat_idents; +mod define_opaque; mod derive; mod deriving; mod edition_panic; @@ -113,6 +114,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { bench: test::expand_bench, cfg_accessible: cfg_accessible::Expander, cfg_eval: cfg_eval::expand, + define_opaque: define_opaque::expand, derive: derive::Expander { is_const: false }, derive_const: derive::Expander { is_const: true }, global_allocator: global_allocator::expand, diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 472e16e62d5b..768b459ec5e3 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -346,6 +346,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { generics: ast::Generics::default(), contract: None, body: Some(main_body), + define_opaque: None, })); // Honor the reexport_test_harness_main attribute diff --git a/compiler/rustc_codegen_cranelift/example/issue-72793.rs b/compiler/rustc_codegen_cranelift/example/issue-72793.rs index 2e08fbca8ef2..95d58b90e798 100644 --- a/compiler/rustc_codegen_cranelift/example/issue-72793.rs +++ b/compiler/rustc_codegen_cranelift/example/issue-72793.rs @@ -2,23 +2,21 @@ #![feature(type_alias_impl_trait)] -mod helper { - pub trait T { - type Item; - } - - pub type Alias<'a> = impl T; - - struct S; - impl<'a> T for &'a S { - type Item = &'a (); - } - - pub fn filter_positive<'a>() -> Alias<'a> { - &S - } +pub trait T { + type Item; +} + +pub type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S { + type Item = &'a (); +} + +#[define_opaque(Alias)] +pub fn filter_positive<'a>() -> Alias<'a> { + &S } -use helper::*; fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index 8d19fc5f9ccf..f63b201742d9 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -315,6 +315,7 @@ mod helper { use super::*; pub(super) type ObligationTreeIdGenerator = impl Iterator; impl ObligationForest { + #[cfg_attr(not(bootstrap), define_opaque(ObligationTreeIdGenerator))] pub fn new() -> ObligationForest { ObligationForest { nodes: vec![], diff --git a/compiler/rustc_error_codes/src/error_codes/E0792.md b/compiler/rustc_error_codes/src/error_codes/E0792.md index 5e3dcc4aa727..033e1c65192b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0792.md +++ b/compiler/rustc_error_codes/src/error_codes/E0792.md @@ -7,6 +7,7 @@ This means type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo() -> Foo { 5u32 } @@ -19,6 +20,7 @@ is not accepted. If it were accepted, one could create unsound situations like type Foo = impl Default; +#[define_opaque(Foo)] fn foo() -> Foo { 5u32 } @@ -36,6 +38,7 @@ Instead you need to make the function generic: type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo() -> Foo { 5u32 } @@ -56,6 +59,7 @@ use std::fmt::Debug; type Foo = impl Debug; +#[define_opaque(Foo)] fn foo() -> Foo { Vec::::new() } diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index a6fbbb29ccd3..066546ecf740 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -208,6 +208,7 @@ pub type LazyFallbackBundle = Arc Fluent /// Return the default `FluentBundle` with standard "en-US" diagnostic messages. #[instrument(level = "trace", skip(resources))] +#[cfg_attr(not(bootstrap), define_opaque(LazyFallbackBundle))] pub fn fallback_fluent_bundle( resources: Vec<&'static str>, with_directionality_markers: bool, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 928455ace856..1c54b99b12fc 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1307,13 +1307,18 @@ impl Attribute { #[derive(Debug)] pub struct AttributeMap<'tcx> { pub map: SortedMap, + /// Preprocessed `#[define_opaque]` attribute. + pub define_opaque: Option<&'tcx [LocalDefId]>, // Only present when the crate hash is needed. pub opt_hash: Option, } impl<'tcx> AttributeMap<'tcx> { - pub const EMPTY: &'static AttributeMap<'static> = - &AttributeMap { map: SortedMap::new(), opt_hash: Some(Fingerprint::ZERO) }; + pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap { + map: SortedMap::new(), + opt_hash: Some(Fingerprint::ZERO), + define_opaque: None, + }; #[inline] pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] { diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 2709a826549c..91ea88cae477 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -106,7 +106,7 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable for AttributeMap fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { // We ignore the `map` since it refers to information included in `opt_hash` which is // hashed in the collector and used for the crate hash. - let AttributeMap { opt_hash, map: _ } = *self; + let AttributeMap { opt_hash, define_opaque: _, map: _ } = *self; opt_hash.unwrap().hash_stable(hcx, hasher); } } diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 935f4de6c58c..194f2cd04e46 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -504,12 +504,9 @@ hir_analysis_supertrait_item_shadowee = item from `{$supertrait}` is shadowed by hir_analysis_supertrait_item_shadowing = trait item `{$item}` from `{$subtrait}` shadows identically named item from supertrait -hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature - .note = this item must mention the opaque type in its signature in order to be able to register hidden types - -hir_analysis_tait_forward_compat2 = item does not constrain `{$opaque_type}`, but has it in its signature - .note = consider moving the opaque type's declaration and defining uses into a separate module - .opaque = this opaque type is in the signature +hir_analysis_tait_forward_compat2 = item does not constrain `{$opaque_type}` + .note = consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` + .opaque = this opaque type is supposed to be constrained hir_analysis_target_feature_on_main = `main` function is not allowed to have `#[target_feature]` diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8f9997cb62ca..8dc5d3617504 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -392,6 +392,12 @@ fn best_definition_site_of_opaque<'tcx>( return ControlFlow::Continue(()); } + let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id); + // Don't try to check items that cannot possibly constrain the type. + if !opaque_types_defined_by.contains(&self.opaque_def_id) { + return ControlFlow::Continue(()); + } + if let Some(hidden_ty) = self.tcx.mir_borrowck(item_def_id).concrete_opaque_types.get(&self.opaque_def_id) { @@ -451,19 +457,7 @@ fn best_definition_site_of_opaque<'tcx>( None } hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { - let scope = tcx.hir_get_defining_scope(tcx.local_def_id_to_hir_id(opaque_def_id)); - let found = if scope == hir::CRATE_HIR_ID { - tcx.hir_walk_toplevel_module(&mut locator) - } else { - match tcx.hir_node(scope) { - Node::Item(it) => locator.visit_item(it), - Node::ImplItem(it) => locator.visit_impl_item(it), - Node::TraitItem(it) => locator.visit_trait_item(it), - Node::ForeignItem(it) => locator.visit_foreign_item(it), - other => bug!("{:?} is not a valid scope for an opaque type item", other), - } - }; - found.break_value() + tcx.hir_walk_toplevel_module(&mut locator).break_value() } } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 399c4fbe55a9..142078900f0e 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -1,14 +1,13 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def}; +use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def, intravisit}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::DUMMY_SP; use tracing::{debug, instrument, trace}; -use crate::errors::{TaitForwardCompat, TaitForwardCompat2, UnconstrainedOpaqueType}; +use crate::errors::{TaitForwardCompat2, UnconstrainedOpaqueType}; /// Checks "defining uses" of opaque `impl Trait` in associated types. /// These can only be defined by associated items of the same trait. @@ -82,38 +81,9 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( /// ``` #[instrument(skip(tcx), level = "debug")] pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { - let hir_id = tcx.local_def_id_to_hir_id(def_id); - let scope = tcx.hir_get_defining_scope(hir_id); let mut locator = TaitConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] }; - debug!(?scope); - - if scope == hir::CRATE_HIR_ID { - tcx.hir_walk_toplevel_module(&mut locator); - } else { - trace!("scope={:#?}", tcx.hir_node(scope)); - match tcx.hir_node(scope) { - // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods - // This allows our visitor to process the defining item itself, causing - // it to pick up any 'sibling' defining uses. - // - // For example, this code: - // ``` - // fn foo() { - // type Blah = impl Debug; - // let my_closure = || -> Blah { true }; - // } - // ``` - // - // requires us to explicitly process `foo()` in order - // to notice the defining usage of `Blah`. - Node::Item(it) => locator.visit_item(it), - Node::ImplItem(it) => locator.visit_impl_item(it), - Node::TraitItem(it) => locator.visit_trait_item(it), - Node::ForeignItem(it) => locator.visit_foreign_item(it), - other => bug!("{:?} is not a valid scope for an opaque type item", other), - } - } + tcx.hir_walk_toplevel_module(&mut locator); if let Some(hidden) = locator.found { // Only check against typeck if we didn't already error @@ -137,12 +107,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local let reported = tcx.dcx().emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), name: tcx.item_ident(parent_def_id.to_def_id()), - what: match tcx.hir_node(scope) { - _ if scope == hir::CRATE_HIR_ID => "module", - Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module", - Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl", - _ => "item", - }, + what: "crate", }); Ty::new_error(tcx, reported) } @@ -176,6 +141,13 @@ impl TaitConstraintLocator<'_> { return; } + let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id); + // Don't try to check items that cannot possibly constrain the type. + if !opaque_types_defined_by.contains(&self.def_id) { + debug!("no constraint: no opaque types defined"); + return; + } + // Function items with `_` in their return type already emit an error, skip any // "non-defining use" errors for them. // Note that we use `Node::fn_sig` instead of `Node::fn_decl` here, because the former @@ -215,8 +187,6 @@ impl TaitConstraintLocator<'_> { return; } - let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id); - let mut constrained = false; for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types { if opaque_type_key.def_id != self.def_id { @@ -224,20 +194,6 @@ impl TaitConstraintLocator<'_> { } constrained = true; - if !opaque_types_defined_by.contains(&self.def_id) { - let guar = self.tcx.dcx().emit_err(TaitForwardCompat { - span: hidden_type.span, - item_span: self - .tcx - .def_ident_span(item_def_id) - .unwrap_or_else(|| self.tcx.def_span(item_def_id)), - }); - // Avoid "opaque type not constrained" errors on the opaque itself. - self.found = Some(ty::OpaqueHiddenType { - span: DUMMY_SP, - ty: Ty::new_error(self.tcx, guar), - }); - } let concrete_type = self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params( opaque_type_key, @@ -309,19 +265,13 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> { } fn visit_item(&mut self, it: &'tcx Item<'tcx>) { trace!(?it.owner_id); - // The opaque type itself or its children are not within its reveal scope. - if it.owner_id.def_id != self.def_id { - self.check(it.owner_id.def_id); - intravisit::walk_item(self, it); - } + self.check(it.owner_id.def_id); + intravisit::walk_item(self, it); } fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) { trace!(?it.owner_id); - // The opaque type itself or its children are not within its reveal scope. - if it.owner_id.def_id != self.def_id { - self.check(it.owner_id.def_id); - intravisit::walk_impl_item(self, it); - } + self.check(it.owner_id.def_id); + intravisit::walk_impl_item(self, it); } fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) { trace!(?it.owner_id); diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 4c6c2504126a..f2560f22874b 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -424,16 +424,6 @@ pub(crate) struct UnconstrainedOpaqueType { pub what: &'static str, } -#[derive(Diagnostic)] -#[diag(hir_analysis_tait_forward_compat)] -#[note] -pub(crate) struct TaitForwardCompat { - #[primary_span] - pub span: Span, - #[note] - pub item_span: Span, -} - #[derive(Diagnostic)] #[diag(hir_analysis_tait_forward_compat2)] #[note] diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 7eaf83f5acf3..659f6d98f034 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -43,6 +43,7 @@ declare_lint! { /// /// type Tait = impl Sized; /// + /// #[define_opaque(Tait)] /// fn test() -> impl Trait { /// 42 /// } diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index bc77f22af67b..b2c51ad88645 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -454,6 +454,7 @@ mod helper { /// Like [`SwitchTargets::target_for_value`], but returning the same type as /// [`Terminator::successors`]. #[inline] + #[cfg_attr(not(bootstrap), define_opaque(Successors))] pub fn successors_for_value(&self, value: u128) -> Successors<'_> { let target = self.target_for_value(value); (&[]).into_iter().copied().chain(Some(target)) @@ -462,6 +463,7 @@ mod helper { impl<'tcx> TerminatorKind<'tcx> { #[inline] + #[cfg_attr(not(bootstrap), define_opaque(Successors))] pub fn successors(&self) -> Successors<'_> { use self::TerminatorKind::*; match *self { @@ -500,6 +502,7 @@ mod helper { } #[inline] + #[cfg_attr(not(bootstrap), define_opaque(SuccessorsMut))] pub fn successors_mut(&mut self) -> SuccessorsMut<'_> { use self::TerminatorKind::*; match *self { diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 907618e428f7..7bbaa0496d53 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -24,6 +24,7 @@ pub trait EraseType: Copy { pub type Erase = Erased; #[inline(always)] +#[cfg_attr(not(bootstrap), define_opaque(Erase))] pub fn erase(src: T) -> Erase { // Ensure the sizes match const { @@ -47,6 +48,7 @@ pub fn erase(src: T) -> Erase { /// Restores an erased value. #[inline(always)] +#[cfg_attr(not(bootstrap), define_opaque(Erase))] pub fn restore(value: Erase) -> T { let value: Erased<::Result> = value; // See comment in `erase` for why we use `transmute_unchecked`. diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 0b9350c71992..e309f144b4f4 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -217,7 +217,14 @@ impl<'a> Parser<'a> { self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?; ( ident, - ItemKind::Fn(Box::new(Fn { defaultness: def_(), sig, generics, contract, body })), + ItemKind::Fn(Box::new(Fn { + defaultness: def_(), + sig, + generics, + contract, + body, + define_opaque: None, + })), ) } else if self.eat_keyword(exp!(Extern)) { if self.eat_keyword(exp!(Crate)) { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 79479986d075..2c3e4bb505cc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -397,32 +397,37 @@ pub(crate) enum AliasPossibility { #[derive(Copy, Clone, Debug)] pub(crate) enum PathSource<'a> { - // Type paths `Path`. + /// Type paths `Path`. Type, - // Trait paths in bounds or impls. + /// Trait paths in bounds or impls. Trait(AliasPossibility), - // Expression paths `path`, with optional parent context. + /// Expression paths `path`, with optional parent context. Expr(Option<&'a Expr>), - // Paths in path patterns `Path`. + /// Paths in path patterns `Path`. Pat, - // Paths in struct expressions and patterns `Path { .. }`. + /// Paths in struct expressions and patterns `Path { .. }`. Struct, - // Paths in tuple struct patterns `Path(..)`. + /// Paths in tuple struct patterns `Path(..)`. TupleStruct(Span, &'a [Span]), - // `m::A::B` in `::B::C`. + /// `m::A::B` in `::B::C`. TraitItem(Namespace), - // Paths in delegation item + /// Paths in delegation item Delegation, /// An arg in a `use<'a, N>` precise-capturing bound. PreciseCapturingArg(Namespace), - // Paths that end with `(..)`, for return type notation. + /// Paths that end with `(..)`, for return type notation. ReturnTypeNotation, + /// Paths from `#[define_opaque]` attributes + DefineOpaques, } impl<'a> PathSource<'a> { fn namespace(self) -> Namespace { match self { - PathSource::Type | PathSource::Trait(_) | PathSource::Struct => TypeNS, + PathSource::Type + | PathSource::Trait(_) + | PathSource::Struct + | PathSource::DefineOpaques => TypeNS, PathSource::Expr(..) | PathSource::Pat | PathSource::TupleStruct(..) @@ -443,6 +448,7 @@ impl<'a> PathSource<'a> { | PathSource::ReturnTypeNotation => true, PathSource::Trait(_) | PathSource::TraitItem(..) + | PathSource::DefineOpaques | PathSource::Delegation | PathSource::PreciseCapturingArg(..) => false, } @@ -450,6 +456,7 @@ impl<'a> PathSource<'a> { fn descr_expected(self) -> &'static str { match &self { + PathSource::DefineOpaques => "type alias or associated type with opaqaue types", PathSource::Type => "type", PathSource::Trait(_) => "trait", PathSource::Pat => "unit struct, unit variant or constant", @@ -493,6 +500,19 @@ impl<'a> PathSource<'a> { pub(crate) fn is_expected(self, res: Res) -> bool { match self { + PathSource::DefineOpaques => { + matches!( + res, + Res::Def( + DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::TyAlias + | DefKind::AssocTy, + _ + ) | Res::SelfTyAlias { .. } + ) + } PathSource::Type => matches!( res, Res::Def( @@ -572,16 +592,16 @@ impl<'a> PathSource<'a> { match (self, has_unexpected_resolution) { (PathSource::Trait(_), true) => E0404, (PathSource::Trait(_), false) => E0405, - (PathSource::Type, true) => E0573, - (PathSource::Type, false) => E0412, + (PathSource::Type | PathSource::DefineOpaques, true) => E0573, + (PathSource::Type | PathSource::DefineOpaques, false) => E0412, (PathSource::Struct, true) => E0574, (PathSource::Struct, false) => E0422, (PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423, (PathSource::Expr(..), false) | (PathSource::Delegation, false) => E0425, (PathSource::Pat | PathSource::TupleStruct(..), true) => E0532, (PathSource::Pat | PathSource::TupleStruct(..), false) => E0531, - (PathSource::TraitItem(..), true) | (PathSource::ReturnTypeNotation, true) => E0575, - (PathSource::TraitItem(..), false) | (PathSource::ReturnTypeNotation, false) => E0576, + (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, true) => E0575, + (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, false) => E0576, (PathSource::PreciseCapturingArg(..), true) => E0799, (PathSource::PreciseCapturingArg(..), false) => E0800, } @@ -2006,6 +2026,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { | PathSource::Pat | PathSource::Struct | PathSource::TupleStruct(..) + | PathSource::DefineOpaques | PathSource::Delegation => true, }; if inferred { @@ -2619,7 +2640,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); } - ItemKind::Fn(box Fn { ref generics, .. }) => { + ItemKind::Fn(box Fn { ref generics, ref define_opaque, .. }) => { self.with_generic_param_rib( &generics.params, RibKind::Item(HasGenericParams::Yes(generics.span), def_kind), @@ -2630,6 +2651,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, |this| visit::walk_item(this, item), ); + + for (id, path) in define_opaque.iter().flatten() { + self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques); + } } ItemKind::Enum(_, ref generics) @@ -3100,8 +3125,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, ); } - AssocItemKind::Fn(box Fn { generics, .. }) => { + AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => { walk_assoc_item(self, generics, LifetimeBinderKind::Function, item); + + for (id, path) in define_opaque.iter().flatten() { + self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques); + } } AssocItemKind::Delegation(delegation) => { self.with_generic_param_rib( @@ -3311,7 +3340,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, ); } - AssocItemKind::Fn(box Fn { generics, .. }) => { + AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => { debug!("resolve_implementation AssocItemKind::Fn"); // We also need a new scope for the impl item type parameters. self.with_generic_param_rib( @@ -3338,6 +3367,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { visit::walk_assoc_item(this, item, AssocCtxt::Impl) }, ); + + for (id, path) in define_opaque.iter().flatten() { + self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques); + } } AssocItemKind::Type(box TyAlias { generics, .. }) => { self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty()); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9e7f5047eb30..4360109b6338 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -779,6 +779,7 @@ symbols! { default_method_body_is_const, default_type_parameter_fallback, default_type_params, + define_opaque, delayed_bug_from_inside_query, deny, deprecated, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 514615735a50..51b2a0b36bb9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -395,11 +395,28 @@ impl Trait for X { let sp = tcx .def_ident_span(body_owner_def_id) .unwrap_or_else(|| tcx.def_span(body_owner_def_id)); - diag.span_note( - sp, - "this item must have the opaque type in its signature in order to \ - be able to register hidden types", - ); + let mut alias_def_id = opaque_ty.def_id; + while let DefKind::OpaqueTy = tcx.def_kind(alias_def_id) { + alias_def_id = tcx.parent(alias_def_id); + } + let opaque_path = tcx.def_path_str(alias_def_id); + // FIXME(type_alias_impl_trait): make this a structured suggestion + match tcx.opaque_ty_origin(opaque_ty.def_id) { + rustc_hir::OpaqueTyOrigin::FnReturn { .. } => {} + rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {} + rustc_hir::OpaqueTyOrigin::TyAlias { + in_assoc_ty: false, .. + } => { + diag.span_note( + sp, + format!("this item must have a `#[define_opaque({opaque_path})]` \ + attribute to be able to define hidden types"), + ); + } + rustc_hir::OpaqueTyOrigin::TyAlias { + in_assoc_ty: true, .. + } => {} + } } // If two if arms can be coerced to a trait object, provide a structured // suggestion. diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 61acc12d0eb9..7213a150d2b7 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" # tidy-alphabetical-start itertools = "0.12" rustc_abi = { path = "../rustc_abi" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 98881905bcf8..2d590dfdd141 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -1,8 +1,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_hir::intravisit; use rustc_hir::intravisit::Visitor; -use rustc_hir::{CRATE_HIR_ID, intravisit}; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; @@ -30,14 +30,21 @@ enum CollectionMode { /// For impl trait in assoc types we only permit collecting them from /// associated types of the same impl block. ImplTraitInAssocTypes, - TypeAliasImplTraitTransition, + /// When collecting for an explicit `#[define_opaque]` attribute, find all TAITs + Taits, + /// The default case, only collect RPITs and AsyncFn return types, as these are + /// always defined by the current item. + RpitAndAsyncFnOnly, } impl<'tcx> OpaqueTypeCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self { - let mode = match tcx.def_kind(tcx.local_parent(item)) { - DefKind::Impl { of_trait: true } => CollectionMode::ImplTraitInAssocTypes, - _ => CollectionMode::TypeAliasImplTraitTransition, + let mode = match tcx.def_kind(item) { + DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy => { + CollectionMode::ImplTraitInAssocTypes + } + DefKind::TyAlias => CollectionMode::Taits, + _ => CollectionMode::RpitAndAsyncFnOnly, }; Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None, mode } } @@ -73,40 +80,6 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { } } - /// Returns `true` if `opaque_hir_id` is a sibling or a child of a sibling of `self.item`. - /// - /// Example: - /// ```ignore UNSOLVED (is this a bug?) - /// # #![feature(type_alias_impl_trait)] - /// pub mod foo { - /// pub mod bar { - /// pub trait Bar { /* ... */ } - /// pub type Baz = impl Bar; - /// - /// # impl Bar for () {} - /// fn f1() -> Baz { /* ... */ } - /// } - /// fn f2() -> bar::Baz { /* ... */ } - /// } - /// ``` - /// - /// and `opaque_def_id` is the `DefId` of the definition of the opaque type `Baz`. - /// For the above example, this function returns `true` for `f1` and `false` for `f2`. - #[instrument(level = "trace", skip(self), ret)] - fn check_tait_defining_scope(&self, opaque_def_id: LocalDefId) -> bool { - let mut hir_id = self.tcx.local_def_id_to_hir_id(self.item); - let opaque_hir_id = self.tcx.local_def_id_to_hir_id(opaque_def_id); - - // Named opaque types can be defined by any siblings or children of siblings. - let scope = self.tcx.hir_get_defining_scope(opaque_hir_id); - // We walk up the node tree until we hit the root or the scope of the opaque type. - while hir_id != scope && hir_id != CRATE_HIR_ID { - hir_id = self.tcx.hir_get_parent_item(hir_id).into(); - } - // Syntactically, we are allowed to define the concrete type if: - hir_id == scope - } - #[instrument(level = "trace", skip(self))] fn collect_taits_declared_in_body(&mut self) { let body = self.tcx.hir_body_owned_by(self.item).value; @@ -139,18 +112,31 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { } // TAITs outside their defining scopes are ignored. - let origin = self.tcx.local_opaque_ty_origin(alias_ty.def_id.expect_local()); - trace!(?origin); - match origin { + match self.tcx.local_opaque_ty_origin(alias_ty.def_id.expect_local()) { rustc_hir::OpaqueTyOrigin::FnReturn { .. } | rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {} - rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => { - if !in_assoc_ty && !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) { - return; + rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => match self.mode { + // If we are collecting opaques in an assoc method, we are only looking at assoc types + // mentioned in the assoc method and only at opaques defined in there. We do not + // want to collect TAITs + CollectionMode::ImplTraitInAssocTypes => { + if !in_assoc_ty { + return; + } } - } + // If we are collecting opaques referenced from a `define_opaque` attribute, we + // do not want to look at opaques defined in associated types. Those can only be + // defined by methods on the same impl. + CollectionMode::Taits => { + if in_assoc_ty { + return; + } + } + CollectionMode::RpitAndAsyncFnOnly => return, + }, } + trace!(?alias_ty, "adding"); self.opaques.push(alias_ty.def_id.expect_local()); let parent_count = self.tcx.generics_of(alias_ty.def_id).parent_count; @@ -192,6 +178,29 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { } } } + + /// Checks the `#[define_opaque]` attributes on items and collectes opaques to define + /// from the referenced types. + #[instrument(level = "trace", skip(self))] + fn collect_taits_from_defines_attr(&mut self) { + let hir_id = self.tcx.local_def_id_to_hir_id(self.item); + if !hir_id.is_owner() { + return; + } + let Some(defines) = self.tcx.hir_attrs(hir_id.owner).define_opaque else { + return; + }; + for &define in defines { + trace!(?define); + let mode = std::mem::replace(&mut self.mode, CollectionMode::Taits); + // TODO: check that opaque types were introduced and error otherwise (also add tests) + super::sig_types::walk_types(self.tcx, define, self); + self.mode = mode; + } + // Allow using `#[define_opaque]` on assoc methods and type aliases to override the default collection mode in + // case it was capturing too much. + self.mode = CollectionMode::RpitAndAsyncFnOnly; + } } impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> { @@ -210,6 +219,7 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { self.visit_opaque_ty(alias_ty); } // Skips type aliases, as they are meant to be transparent. + // FIXME(type_alias_impl_trait): can we require mentioning nested type aliases explicitly? ty::Alias(ty::Weak, alias_ty) if alias_ty.def_id.is_local() => { self.tcx .type_of(alias_ty.def_id) @@ -283,28 +293,6 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { self.visit_opaque_ty(alias_ty); } } - ty::Adt(def, _) if def.did().is_local() => { - if let CollectionMode::ImplTraitInAssocTypes = self.mode { - return; - } - if !self.seen.insert(def.did().expect_local()) { - return; - } - for variant in def.variants().iter() { - for field in variant.fields.iter() { - // Don't use the `ty::Adt` args, we either - // * found the opaque in the args - // * will find the opaque in the uninstantiated fields - // The only other situation that can occur is that after instantiating, - // some projection resolves to an opaque that we would have otherwise - // not found. While we could instantiate and walk those, that would mean we - // would have to walk all generic parameters of an Adt, which can quickly - // degenerate into looking at an exponential number of types. - let ty = self.tcx.type_of(field.did).instantiate_identity(); - self.visit_spanned(self.tcx.def_span(field.did), ty); - } - } - } _ => trace!(kind=?t.kind()), } } @@ -317,7 +305,9 @@ fn opaque_types_defined_by<'tcx>( let kind = tcx.def_kind(item); trace!(?kind); let mut collector = OpaqueTypeCollector::new(tcx, item); + collector.collect_taits_from_defines_attr(); super::sig_types::walk_types(tcx, item, &mut collector); + match kind { DefKind::AssocFn | DefKind::Fn @@ -350,8 +340,7 @@ fn opaque_types_defined_by<'tcx>( | DefKind::GlobalAsm | DefKind::Impl { .. } | DefKind::SyntheticCoroutineBody => {} - // Closures and coroutines are type checked with their parent, so we need to allow all - // opaques from the closure signature *and* from the parent body. + // Closures and coroutines are type checked with their parent DefKind::Closure | DefKind::InlineConst => { collector.opaques.extend(tcx.opaque_types_defined_by(tcx.local_parent(item))); } diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 16200184422b..a527a2ea5aad 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1743,6 +1743,21 @@ pub(crate) mod builtin { /* compiler built-in */ } + /// Provide a list of type aliases and other opaque-type-containing type definitions. + /// This list will be used in the body of the item it is applied to to define opaque + /// types' hidden types. + /// Can only be applied to things that have bodies. + #[unstable( + feature = "type_alias_impl_trait", + issue = "63063", + reason = "`type_alias_impl_trait` has open design concerns" + )] + #[rustc_builtin_macro] + #[cfg(not(bootstrap))] + pub macro define_opaque($($tt:tt)*) { + /* compiler built-in */ + } + /// Unstable placeholder for type ascription. #[allow_internal_unstable(builtin_syntax)] #[unstable( diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 50fd67e83955..c5975c030503 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -111,3 +111,11 @@ pub use crate::macros::builtin::type_ascribe; reason = "placeholder syntax for deref patterns" )] pub use crate::macros::builtin::deref; + +#[unstable( + feature = "type_alias_impl_trait", + issue = "63063", + reason = "`type_alias_impl_trait` has open design concerns" +)] +#[cfg(not(bootstrap))] +pub use crate::macros::builtin::define_opaque; diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs index fc333d7ff3f9..3e641ac5d904 100644 --- a/library/std/src/backtrace.rs +++ b/library/std/src/backtrace.rs @@ -432,6 +432,7 @@ mod helper { use super::*; pub(super) type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync + UnwindSafe; + #[cfg_attr(not(bootstrap), define_opaque(LazyResolve))] pub(super) fn lazy_resolve(mut capture: Capture) -> LazyResolve { move || { // Use the global backtrace lock to synchronize this as it's a diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 5b324b2e9167..4217f6586407 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -103,6 +103,15 @@ pub use core::prelude::v1::type_ascribe; )] pub use core::prelude::v1::deref; +// Do not `doc(no_inline)` either. +#[unstable( + feature = "type_alias_impl_trait", + issue = "63063", + reason = "`type_alias_impl_trait` has open design concerns" +)] +#[cfg(not(bootstrap))] +pub use core::prelude::v1::define_opaque; + // The file so far is equivalent to core/src/prelude/v1.rs. It is duplicated // rather than glob imported because we want docs to show these re-exports as // pointing to within `std`. diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 4610e092cdfa..3228f71df074 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -272,7 +272,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { fn visit_item(&mut self, item: &'tcx Item<'tcx>) { match item.kind { - ItemKind::Static(_, _, _) + ItemKind::Static(..) | ItemKind::Const(_, _, _) | ItemKind::Fn { .. } | ItemKind::Macro(_, _) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 4f024ecaf29e..707312a97f3b 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -364,6 +364,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { generics: lg, contract: lc, body: lb, + define_opaque: _, }), Fn(box ast::Fn { defaultness: rd, @@ -371,6 +372,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { generics: rg, contract: rc, body: rb, + define_opaque: _, }), ) => { eq_defaultness(*ld, *rd) @@ -502,6 +504,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { generics: lg, contract: lc, body: lb, + define_opaque: _, }), Fn(box ast::Fn { defaultness: rd, @@ -509,6 +512,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { generics: rg, contract: rc, body: rb, + define_opaque: _, }), ) => { eq_defaultness(*ld, *rd) @@ -567,6 +571,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { generics: lg, contract: lc, body: lb, + define_opaque: _, }), Fn(box ast::Fn { defaultness: rd, @@ -574,6 +579,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { generics: rg, contract: rc, body: rb, + define_opaque: _, }), ) => { eq_defaultness(*ld, *rd) diff --git a/src/tools/clippy/tests/ui/crashes/ice-10972-tait.rs b/src/tools/clippy/tests/ui/crashes/ice-10972-tait.rs deleted file mode 100644 index 11ddbfc3a04b..000000000000 --- a/src/tools/clippy/tests/ui/crashes/ice-10972-tait.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ check-pass -// ICE: #10972 -// asked to assemble constituent types of unexpected type: Binder(Foo, []) -#![feature(type_alias_impl_trait)] - -use std::fmt::Debug; -type Foo = impl Debug; -const FOO2: Foo = 22_u32; - -pub fn main() {} diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed index bac7af59491f..4fe3fa4eab51 100644 --- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed +++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed @@ -192,6 +192,7 @@ impl Atpit for () { type Tait = impl DerefMut; //~^ implied_bounds_in_impls +#[define_opaque(Tait)] fn define() -> Tait { &mut [] as &mut [()] } diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs index 2014cd46ada7..6cc824db1107 100644 --- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs +++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs @@ -192,6 +192,7 @@ impl Atpit for () { type Tait = impl Deref + DerefMut; //~^ implied_bounds_in_impls +#[define_opaque(Tait)] fn define() -> Tait { &mut [] as &mut [()] } diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs index aef5eb5b890a..bd6339b78700 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs @@ -207,6 +207,7 @@ mod msrv { mod with_ty_alias { type Foo = impl std::fmt::Debug; + #[define_opaque(Foo)] fn foo(_: Foo) { let _: Foo = 1; } diff --git a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs index 8a85c5662276..f317674bc1ae 100644 --- a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs +++ b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs @@ -17,6 +17,7 @@ mod issue10041 { struct Bomb2; impl Bomb2 { + #[define_opaque(X)] pub fn new() -> X { //~^ ERROR: overflow evaluating the requirement 0i32 diff --git a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr index 77c1b64ebc8e..8ecd0437e7db 100644 --- a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr +++ b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr @@ -1,5 +1,5 @@ error[E0275]: overflow evaluating the requirement `::Output == issue10041::X` - --> tests/ui/new_ret_no_self_overflow.rs:20:25 + --> tests/ui/new_ret_no_self_overflow.rs:21:25 | LL | pub fn new() -> X { | ^ diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 253e13375c73..2b9ae1954785 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -4058,7 +4058,6 @@ ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs ui/type-alias-impl-trait/issue-101750.rs ui/type-alias-impl-trait/issue-104817.rs ui/type-alias-impl-trait/issue-109054.rs -ui/type-alias-impl-trait/issue-52843-closure-constrain.rs ui/type-alias-impl-trait/issue-52843.rs ui/type-alias-impl-trait/issue-53092-2.rs ui/type-alias-impl-trait/issue-53092.rs diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs index 3edc68e13474..9048c6a1f183 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs @@ -9,18 +9,16 @@ extern crate core; -mod defining_module { - pub type Type1 = impl Send; +pub type Type1 = impl Send; - pub fn foo() - where - Type1: 'static, - { - pub struct Foo([T; N]); - let _: Type1 = Foo([0; 32]); - } +#[define_opaque(Type1)] +pub fn foo() +where + Type1: 'static, +{ + pub struct Foo([T; N]); + let _: Type1 = Foo([0; 32]); } -use defining_module::*; pub fn foo1(_: Type1) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} @@ -29,6 +27,6 @@ pub fn foo2(_: Type1, _: Type1) {} pub fn foo3(_: Type1, _: Type1, _: Type1) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EEE"} -// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_E"} -// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_S2_E"} +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EEE"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_E"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_S2_E"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs index 09cfd2e10d6e..36d2e8c9f25a 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs @@ -9,22 +9,18 @@ extern crate core; -mod defining_module { +pub type Type1 = impl Send; - pub type Type1 = impl Send; - - pub fn foo<'a>() - where - Type1: 'static, - { - pub struct Foo<'a>(&'a i32); - pub struct Bar<'a, 'b>(&'a i32, &'b Foo<'b>); - let _: Type1 = Bar; - } +#[define_opaque(Type1)] +pub fn foo<'a>() +where + Type1: 'static, +{ + pub struct Foo<'a>(&'a i32); + pub struct Bar<'a, 'b>(&'a i32, &'b Foo<'b>); + let _: Type1 = Bar; } -use defining_module::*; - pub fn foo1(_: Type1) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo2(_: Type1, _: Type1) {} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs index ffbfe021ba3e..a8ba8db1be3b 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs @@ -9,47 +9,41 @@ extern crate core; -mod defining_module { - pub type Type1 = impl Send; - pub type Type2 = impl Send; - pub type Type3 = impl Send; - pub type Type4 = impl Send; +pub type Type1 = impl Send; +pub type Type2 = impl Send; +pub type Type3 = impl Send; +pub type Type4 = impl Send; - pub fn foo() - where - Type1: 'static, - Type2: 'static, - Type4: 'static, - { - // Type in extern path - extern "C" { - fn bar(); - } - let _: Type1 = bar; - - // Type in closure path - || { - pub struct Foo; - let _: Type2 = Foo; - }; - - // Type in const path - const { - pub struct Foo; - fn bar() -> Type3 { - Foo - } - }; - - // Type in impl path - struct Foo; - impl Foo { - fn bar(&self) {} - } - let _: Type4 = ::bar; +#[define_opaque(Type1, Type2, Type4)] +pub fn foo() { + // Type in extern path + extern "C" { + fn bar(); } + let _: Type1 = bar; + + // Type in closure path + || { + pub struct Foo; + let _: Type2 = Foo; + }; + + // Type in const path + const { + pub struct Foo; + #[define_opaque(Type3)] + fn bar() -> Type3 { + Foo + } + }; + + // Type in impl path + struct Foo; + impl Foo { + fn bar(&self) {} + } + let _: Type4 = ::bar; } -use defining_module::*; // Force arguments to be passed by using a reference. Otherwise, they may end up PassMode::Ignore @@ -78,15 +72,15 @@ pub fn foo11(_: &Type4, _: &Type4) {} pub fn foo12(_: &Type4, _: &Type4, _: &Type4) {} // CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"} -// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"} -// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"} -// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"} -// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"} -// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"} -// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"} -// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"} -// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"} -// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"} -// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"} -// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"} +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"} +// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"} diff --git a/tests/crashes/120016.rs b/tests/crashes/120016.rs index 09175689256a..faba1af91b4b 100644 --- a/tests/crashes/120016.rs +++ b/tests/crashes/120016.rs @@ -6,6 +6,7 @@ struct Bug { V1: [(); { type F = impl std::future::Future; + #[define_opaque(F)] fn concrete_use() -> F { //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()` async {} diff --git a/tests/crashes/122904-2.rs b/tests/crashes/122904-2.rs index 85ed91c2fa48..db66b8625db0 100644 --- a/tests/crashes/122904-2.rs +++ b/tests/crashes/122904-2.rs @@ -6,10 +6,12 @@ type Alias<'a> = impl T; struct S; impl<'a> T for &'a S {} +#[define_opaque(Alias)] fn with_positive(fun: impl Fn(Alias<'_>)) { with_positive(|&n| ()); } +#[define_opaque(Alias)] fn main(Alias<'_>) { with_positive(|&a| ()); } diff --git a/tests/crashes/122904.rs b/tests/crashes/122904.rs index 8b8bb35d56c1..2068cd9d239d 100644 --- a/tests/crashes/122904.rs +++ b/tests/crashes/122904.rs @@ -6,6 +6,7 @@ type Alias<'a> = impl T; struct S; impl<'a> T for &'a S {} +#[define_opaque(Alias)] fn with_positive(fun: impl Fn(Alias<'_>)) { with_positive(|&n| ()); } diff --git a/tests/crashes/125185.rs b/tests/crashes/125185.rs index 8693d6c7662b..e77666ca73d3 100644 --- a/tests/crashes/125185.rs +++ b/tests/crashes/125185.rs @@ -1,16 +1,26 @@ //@ known-bug: rust-lang/rust#125185 //@ compile-flags: -Zvalidate-mir +#![feature(type_alias_impl_trait)] + type Foo = impl Send; struct A; -const VALUE: Foo = value(); +#[define_opaque(Foo)] +const fn foo() -> Foo { + value() +} -fn test(foo: Foo<'a>, f: impl for<'b> FnMut()) { +const VALUE: Foo = foo(); + +#[define_opaque(Foo)] +fn test(foo: Foo, f: impl for<'b> FnMut()) { match VALUE { 0 | 0 => {} _ => (), } } + +fn main() {} diff --git a/tests/crashes/126680.rs b/tests/crashes/126680.rs index b1566d5e6bee..dcb6ccad6b42 100644 --- a/tests/crashes/126680.rs +++ b/tests/crashes/126680.rs @@ -8,14 +8,18 @@ use std::path::Path; struct A { pub func: fn(check: Bar, b: Option<&Path>), } -const MY_A: A = A { - func: |check, b| { - if check { - () - } else if let Some(_) = b.and_then(|p| p.parent()) { - () - } - }, -}; + +#[define_opaque(Bar)] +fn foo() -> A { + A { + func: |check, b| { + if check { + () + } else if let Some(_) = b.and_then(|p| p.parent()) { + () + } + }, + } +} fn main() {} diff --git a/tests/crashes/131298.rs b/tests/crashes/131298.rs deleted file mode 100644 index 833f1b04ffab..000000000000 --- a/tests/crashes/131298.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #131298 - -fn dyn_hoops() -> *const dyn Iterator { - loop {} -} - -mod typeck { - type Opaque = impl Sized; - fn define() -> Opaque { - let _: Opaque = super::dyn_hoops::(); - } -} diff --git a/tests/crashes/131886.rs b/tests/crashes/131886.rs index 2c692dfb7771..16cb815f1c22 100644 --- a/tests/crashes/131886.rs +++ b/tests/crashes/131886.rs @@ -1,5 +1,5 @@ //@ known-bug: #131886 -//@ compile-flags: -Zvalidate-mir --crate-type=lib +//@ compile-flags: -Zvalidate-mir #![feature(type_alias_impl_trait)] type Tait = impl Sized; @@ -7,6 +7,9 @@ type Tait = impl Sized; trait Foo<'a>: Bar<'a, 'a, Tait> {} trait Bar<'a, 'b, T> {} +#[define_opaque(Tait)] fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) { let _ = x as &dyn Bar<'_, '_, ()>; } + +fn main() {} diff --git a/tests/crashes/135528.rs b/tests/crashes/135528.rs index a1418f40be6a..171550e209e5 100644 --- a/tests/crashes/135528.rs +++ b/tests/crashes/135528.rs @@ -7,10 +7,12 @@ fn set(x: &isize) -> isize { *x } +#[define_opaque(Tait)] fn d(x: Tait) { set(x); } +#[define_opaque(Tait)] fn other_define() -> Tait { () } diff --git a/tests/crashes/137049.rs b/tests/crashes/137049.rs index a7132e4fa17c..3dbbf2807332 100644 --- a/tests/crashes/137049.rs +++ b/tests/crashes/137049.rs @@ -22,6 +22,7 @@ impl> Project2 for PhantomData { type Alias = impl Project2; +#[define_opaque(Alias)] fn constrain() -> Alias { PhantomData:: } diff --git a/tests/ui/associated-inherent-types/constrain_opaque_types_during_projection.rs b/tests/ui/associated-inherent-types/constrain_opaque_types_during_projection.rs index 292733cd4923..929fa354cd09 100644 --- a/tests/ui/associated-inherent-types/constrain_opaque_types_during_projection.rs +++ b/tests/ui/associated-inherent-types/constrain_opaque_types_during_projection.rs @@ -11,7 +11,8 @@ impl Foo { type Tait = impl Sized; -fn bar(_: Tait) { +#[define_opaque(Tait)] +fn bar() { let x: Foo::Assoc = 42; } diff --git a/tests/ui/associated-inherent-types/issue-109299-1.stderr b/tests/ui/associated-inherent-types/issue-109299-1.stderr index 77a78da852f3..940ccd7e400b 100644 --- a/tests/ui/associated-inherent-types/issue-109299-1.stderr +++ b/tests/ui/associated-inherent-types/issue-109299-1.stderr @@ -29,7 +29,7 @@ error: unconstrained opaque type LL | type X = impl for Fn() -> Lexer::Cursor; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `X` must be used in combination with a concrete type within the same module + = note: `X` must be used in combination with a concrete type within the same crate error: aborting due to 3 previous errors diff --git a/tests/ui/associated-type-bounds/dont-imply-atb-in-closure-inference.rs b/tests/ui/associated-type-bounds/dont-imply-atb-in-closure-inference.rs index fecb3b153386..1cfbefb9daa6 100644 --- a/tests/ui/associated-type-bounds/dont-imply-atb-in-closure-inference.rs +++ b/tests/ui/associated-type-bounds/dont-imply-atb-in-closure-inference.rs @@ -11,10 +11,8 @@ impl IsPtr for T { type Tait = impl IsPtr + Fn(u32); -fn hello() -where - Tait:, -{ +#[define_opaque(Tait)] +fn hello() { let _: Tait = |x| {}; } diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs index 2b4a01376d77..e9d94787e982 100644 --- a/tests/ui/associated-type-bounds/duplicate.rs +++ b/tests/ui/associated-type-bounds/duplicate.rs @@ -179,19 +179,25 @@ where type ETAI1> = impl Copy; //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] +//~| ERROR unconstrained opaque type type ETAI2> = impl Copy; //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] +//~| ERROR unconstrained opaque type type ETAI3> = impl Copy; //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] +//~| ERROR unconstrained opaque type type ETAI4 = impl Iterator; //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] +//~| ERROR unconstrained opaque type type ETAI5 = impl Iterator; //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] +//~| ERROR unconstrained opaque type type ETAI6 = impl Iterator; //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] +//~| ERROR unconstrained opaque type trait TRI1> {} //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr index 0dabcbdce1bb..1ce212a9ff3e 100644 --- a/tests/ui/associated-type-bounds/duplicate.stderr +++ b/tests/ui/associated-type-bounds/duplicate.stderr @@ -325,7 +325,7 @@ LL | type ETAI1> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:182:36 + --> $DIR/duplicate.rs:183:36 | LL | type ETAI2> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -333,7 +333,7 @@ LL | type ETAI2> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:184:39 + --> $DIR/duplicate.rs:186:39 | LL | type ETAI3> = impl Copy; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -341,7 +341,7 @@ LL | type ETAI3> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:186:40 + --> $DIR/duplicate.rs:189:40 | LL | type ETAI4 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -349,7 +349,7 @@ LL | type ETAI4 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:186:40 + --> $DIR/duplicate.rs:189:40 | LL | type ETAI4 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -359,7 +359,7 @@ LL | type ETAI4 = impl Iterator; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:189:40 + --> $DIR/duplicate.rs:193:40 | LL | type ETAI5 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -367,7 +367,7 @@ LL | type ETAI5 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:189:40 + --> $DIR/duplicate.rs:193:40 | LL | type ETAI5 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -377,7 +377,7 @@ LL | type ETAI5 = impl Iterator; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:192:43 + --> $DIR/duplicate.rs:197:43 | LL | type ETAI6 = impl Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -385,7 +385,7 @@ LL | type ETAI6 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:192:43 + --> $DIR/duplicate.rs:197:43 | LL | type ETAI6 = impl Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -395,7 +395,7 @@ LL | type ETAI6 = impl Iterator; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:196:36 + --> $DIR/duplicate.rs:202:36 | LL | trait TRI1> {} | ---------- ^^^^^^^^^^ re-bound here @@ -403,7 +403,7 @@ LL | trait TRI1> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:198:36 + --> $DIR/duplicate.rs:204:36 | LL | trait TRI2> {} | ---------- ^^^^^^^^^^ re-bound here @@ -411,7 +411,7 @@ LL | trait TRI2> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:200:39 + --> $DIR/duplicate.rs:206:39 | LL | trait TRI3> {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -419,7 +419,7 @@ LL | trait TRI3> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:202:34 + --> $DIR/duplicate.rs:208:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -427,7 +427,7 @@ LL | trait TRS1: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:202:34 + --> $DIR/duplicate.rs:208:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -437,7 +437,7 @@ LL | trait TRS1: Iterator {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:202:34 + --> $DIR/duplicate.rs:208:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -447,7 +447,7 @@ LL | trait TRS1: Iterator {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:206:34 + --> $DIR/duplicate.rs:212:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -455,7 +455,7 @@ LL | trait TRS2: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:206:34 + --> $DIR/duplicate.rs:212:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -465,7 +465,7 @@ LL | trait TRS2: Iterator {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:206:34 + --> $DIR/duplicate.rs:212:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -475,7 +475,7 @@ LL | trait TRS2: Iterator {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:210:37 + --> $DIR/duplicate.rs:216:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -483,7 +483,7 @@ LL | trait TRS3: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:210:37 + --> $DIR/duplicate.rs:216:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -493,7 +493,7 @@ LL | trait TRS3: Iterator {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:210:37 + --> $DIR/duplicate.rs:216:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -503,7 +503,7 @@ LL | trait TRS3: Iterator {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:216:29 + --> $DIR/duplicate.rs:222:29 | LL | T: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -511,7 +511,7 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:222:29 + --> $DIR/duplicate.rs:228:29 | LL | T: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -519,7 +519,7 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:228:32 + --> $DIR/duplicate.rs:234:32 | LL | T: Iterator, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -527,7 +527,7 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:234:32 + --> $DIR/duplicate.rs:240:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -535,7 +535,7 @@ LL | Self: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:234:32 + --> $DIR/duplicate.rs:240:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -545,7 +545,7 @@ LL | Self: Iterator, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:234:32 + --> $DIR/duplicate.rs:240:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -555,7 +555,7 @@ LL | Self: Iterator, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:242:32 + --> $DIR/duplicate.rs:248:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -563,7 +563,7 @@ LL | Self: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:242:32 + --> $DIR/duplicate.rs:248:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -573,7 +573,7 @@ LL | Self: Iterator, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:242:32 + --> $DIR/duplicate.rs:248:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -583,7 +583,7 @@ LL | Self: Iterator, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:250:35 + --> $DIR/duplicate.rs:256:35 | LL | Self: Iterator, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -591,7 +591,7 @@ LL | Self: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:250:35 + --> $DIR/duplicate.rs:256:35 | LL | Self: Iterator, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -601,7 +601,7 @@ LL | Self: Iterator, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:250:35 + --> $DIR/duplicate.rs:256:35 | LL | Self: Iterator, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -611,7 +611,7 @@ LL | Self: Iterator, = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:257:34 + --> $DIR/duplicate.rs:263:34 | LL | type A: Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -619,7 +619,7 @@ LL | type A: Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:257:34 + --> $DIR/duplicate.rs:263:34 | LL | type A: Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -629,7 +629,7 @@ LL | type A: Iterator; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:262:34 + --> $DIR/duplicate.rs:268:34 | LL | type A: Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -637,7 +637,7 @@ LL | type A: Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:262:34 + --> $DIR/duplicate.rs:268:34 | LL | type A: Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -647,7 +647,7 @@ LL | type A: Iterator; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:267:37 + --> $DIR/duplicate.rs:273:37 | LL | type A: Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -655,7 +655,7 @@ LL | type A: Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:267:37 + --> $DIR/duplicate.rs:273:37 | LL | type A: Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -697,7 +697,55 @@ help: consider specifying the generic argument LL | iter::empty::() | +++++ -error: aborting due to 81 previous errors +error: unconstrained opaque type + --> $DIR/duplicate.rs:180:51 + | +LL | type ETAI1> = impl Copy; + | ^^^^^^^^^ + | + = note: `ETAI1` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate.rs:183:51 + | +LL | type ETAI2> = impl Copy; + | ^^^^^^^^^ + | + = note: `ETAI2` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate.rs:186:57 + | +LL | type ETAI3> = impl Copy; + | ^^^^^^^^^ + | + = note: `ETAI3` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate.rs:189:14 + | +LL | type ETAI4 = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `ETAI4` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate.rs:193:14 + | +LL | type ETAI5 = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `ETAI5` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate.rs:197:14 + | +LL | type ETAI6 = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `ETAI6` must be used in combination with a concrete type within the same crate + +error: aborting due to 87 previous errors Some errors have detailed explanations: E0282, E0719. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs index fb6a4fcbe976..540c083e309f 100644 --- a/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs +++ b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs @@ -31,6 +31,7 @@ impl Tr1 for S1 { } type Et1 = impl Tr1; +#[define_opaque(Et1)] fn def_et1() -> Et1 { S1 } @@ -39,6 +40,7 @@ pub fn use_et1() { } type Et2 = impl Tr1; +#[define_opaque(Et2)] fn def_et2() -> Et2 { S1 } @@ -47,6 +49,7 @@ pub fn use_et2() { } type Et3 = impl Tr1>>>; +#[define_opaque(Et3)] fn def_et3() -> Et3 { struct A; impl Tr1 for A { @@ -68,6 +71,7 @@ pub fn use_et3() { } type Et4 = impl Tr1 Tr2<'a>>; +#[define_opaque(Et4)] fn def_et4() -> Et4 { #[derive(Copy, Clone)] struct A; diff --git a/tests/ui/async-await/async-fn/impl-trait.rs b/tests/ui/async-await/async-fn/impl-trait.rs index f284de8981ad..89c41ceb2da5 100644 --- a/tests/ui/async-await/async-fn/impl-trait.rs +++ b/tests/ui/async-await/async-fn/impl-trait.rs @@ -4,11 +4,14 @@ #![feature(type_alias_impl_trait)] type Tait = impl AsyncFn(); +#[define_opaque(Tait)] fn tait() -> Tait { || async {} } -fn foo(x: impl AsyncFn()) -> impl AsyncFn() { x } +fn foo(x: impl AsyncFn()) -> impl AsyncFn() { + x +} fn param() {} diff --git a/tests/ui/async-await/issues/issue-60655-latebound-regions.rs b/tests/ui/async-await/issues/issue-60655-latebound-regions.rs index 4a8b5af5769b..f9eeb361b139 100644 --- a/tests/ui/async-await/issues/issue-60655-latebound-regions.rs +++ b/tests/ui/async-await/issues/issue-60655-latebound-regions.rs @@ -11,15 +11,17 @@ pub type Func = impl Sized; // Late bound region should be allowed to escape the function, since it's bound // in the type. +#[define_opaque(Func)] fn null_function_ptr() -> Func { None:: fn(&'a ())> } async fn async_nop(_: &u8) {} -pub type ServeFut = impl Future; +pub type ServeFut = impl Future; // Late bound regions occur in the coroutine witness type here. +#[define_opaque(ServeFut)] fn serve() -> ServeFut { async move { let x = 5; diff --git a/tests/ui/async-await/normalize-output-in-signature-deduction.rs b/tests/ui/async-await/normalize-output-in-signature-deduction.rs index 19d70c2c6eeb..e2238d85093d 100644 --- a/tests/ui/async-await/normalize-output-in-signature-deduction.rs +++ b/tests/ui/async-await/normalize-output-in-signature-deduction.rs @@ -13,6 +13,7 @@ pub trait Trait {} pub type TAIT = impl Trait; +#[define_opaque(TAIT)] async fn foo() -> TAIT { Foo } diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.rs b/tests/ui/attributes/collapse-debuginfo-invalid.rs index d6b3554a5a81..ccf11df2eb0d 100644 --- a/tests/ui/attributes/collapse-debuginfo-invalid.rs +++ b/tests/ui/attributes/collapse-debuginfo-invalid.rs @@ -24,15 +24,15 @@ const BAR: u32 = 3; //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions fn foo() { let _ = #[collapse_debuginfo(yes)] || { }; -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions let _ = 3; let _ = #[collapse_debuginfo(yes)] 3; -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions match (3, 4) { #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions _ => (), } } @@ -50,7 +50,7 @@ type Map = HashMap; //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions enum Foo { #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions Variant, } @@ -58,7 +58,7 @@ enum Foo { //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions struct Bar { #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions field: u32, } @@ -73,7 +73,7 @@ union Qux { //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions trait Foobar { #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions type Bar; } @@ -85,6 +85,7 @@ impl Foobar for Bar { type Bar = u32; } +#[define_opaque(AFoobar)] fn constraining() -> AFoobar { Bar { field: 3 } } @@ -93,11 +94,11 @@ fn constraining() -> AFoobar { //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions impl Bar { #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions const FOO: u32 = 3; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions fn bar(&self) {} } diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.stderr b/tests/ui/attributes/collapse-debuginfo-invalid.stderr index 70376f985cb1..081e4445a869 100644 --- a/tests/ui/attributes/collapse-debuginfo-invalid.stderr +++ b/tests/ui/attributes/collapse-debuginfo-invalid.stderr @@ -176,7 +176,7 @@ LL | type AFoobar = impl Foobar; | --------------------------- not a macro definition error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:92:1 + --> $DIR/collapse-debuginfo-invalid.rs:93:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -200,7 +200,7 @@ LL | type Bar; | --------- not a macro definition error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:95:5 + --> $DIR/collapse-debuginfo-invalid.rs:96:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | const FOO: u32 = 3; | ------------------- not a macro definition error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:99:5 + --> $DIR/collapse-debuginfo-invalid.rs:100:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/borrowck/overwrite-anon-late-param-regions.rs b/tests/ui/borrowck/overwrite-anon-late-param-regions.rs index 7b0f784068f6..8e0e005cd781 100644 --- a/tests/ui/borrowck/overwrite-anon-late-param-regions.rs +++ b/tests/ui/borrowck/overwrite-anon-late-param-regions.rs @@ -6,6 +6,7 @@ #![feature(type_alias_impl_trait)] type Opaque2<'a> = impl Sized + 'a; +#[define_opaque(Opaque2)] fn test2() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque2<'a>, Opaque2<'a>) { |x| x //~^ ERROR lifetime may not live long enough diff --git a/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr b/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr index c5b7284271e4..96b3ebf1eb49 100644 --- a/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr +++ b/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/overwrite-anon-late-param-regions.rs:10:9 + --> $DIR/overwrite-anon-late-param-regions.rs:11:9 | LL | |x| x | - ^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -8,7 +8,7 @@ LL | |x| x | has type `(&'2 str, &str)` error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/overwrite-anon-late-param-regions.rs:10:5 + --> $DIR/overwrite-anon-late-param-regions.rs:11:5 | LL | type Opaque2<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/coherence/coherence-with-closure.rs b/tests/ui/coherence/coherence-with-closure.rs index 5b6a62b24d4b..ac2c55843929 100644 --- a/tests/ui/coherence/coherence-with-closure.rs +++ b/tests/ui/coherence/coherence-with-closure.rs @@ -1,6 +1,7 @@ // Test that encountering closures during coherence does not cause issues. #![feature(type_alias_impl_trait)] type OpaqueClosure = impl Sized; +#[define_opaque(OpaqueClosure)] fn defining_use() -> OpaqueClosure { || () } diff --git a/tests/ui/coherence/coherence-with-closure.stderr b/tests/ui/coherence/coherence-with-closure.stderr index 501279ffe6a7..37f393ceeb70 100644 --- a/tests/ui/coherence/coherence-with-closure.stderr +++ b/tests/ui/coherence/coherence-with-closure.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper` - --> $DIR/coherence-with-closure.rs:11:1 + --> $DIR/coherence-with-closure.rs:12:1 | LL | impl Trait for Wrapper {} | ------------------------------------- first implementation here diff --git a/tests/ui/coherence/coherence-with-coroutine.rs b/tests/ui/coherence/coherence-with-coroutine.rs index 6b0617e950b7..0e65a6c1da03 100644 --- a/tests/ui/coherence/coherence-with-coroutine.rs +++ b/tests/ui/coherence/coherence-with-coroutine.rs @@ -7,6 +7,7 @@ //@ [specialized]check-pass type OpaqueCoroutine = impl Sized; +#[define_opaque(OpaqueCoroutine)] fn defining_use() -> OpaqueCoroutine { #[coroutine] || { diff --git a/tests/ui/coherence/coherence-with-coroutine.stock.stderr b/tests/ui/coherence/coherence-with-coroutine.stock.stderr index 5f58b3088f14..c7af384df6d3 100644 --- a/tests/ui/coherence/coherence-with-coroutine.stock.stderr +++ b/tests/ui/coherence/coherence-with-coroutine.stock.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper` - --> $DIR/coherence-with-coroutine.rs:22:1 + --> $DIR/coherence-with-coroutine.rs:23:1 | LL | impl Trait for Wrapper {} | --------------------------------------- first implementation here diff --git a/tests/ui/coherence/issue-99663-2.rs b/tests/ui/coherence/issue-99663-2.rs index 675e9fdfdba7..9827df1d5e70 100644 --- a/tests/ui/coherence/issue-99663-2.rs +++ b/tests/ui/coherence/issue-99663-2.rs @@ -8,6 +8,7 @@ struct Outer { type InnerSend = impl Send; +#[define_opaque(InnerSend)] fn constrain() -> InnerSend { () } diff --git a/tests/ui/coherence/issue-99663.rs b/tests/ui/coherence/issue-99663.rs index 00d15977d8f0..49156952990d 100644 --- a/tests/ui/coherence/issue-99663.rs +++ b/tests/ui/coherence/issue-99663.rs @@ -8,6 +8,7 @@ struct Send { type InnerSend = impl Sized; +#[define_opaque(InnerSend)] fn constrain() -> InnerSend { () } diff --git a/tests/ui/coherence/occurs-check/opaques.current.stderr b/tests/ui/coherence/occurs-check/opaques.current.stderr index f3fc22027c26..d3850df52182 100644 --- a/tests/ui/coherence/occurs-check/opaques.current.stderr +++ b/tests/ui/coherence/occurs-check/opaques.current.stderr @@ -1,11 +1,11 @@ error[E0119]: conflicting implementations of trait `Trait<_>` - --> $DIR/opaques.rs:28:1 + --> $DIR/opaques.rs:27:1 | LL | impl Trait for T { | ---------------------- first implementation here ... -LL | impl Trait for defining_scope::Alias { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation +LL | impl Trait for Alias { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error: aborting due to 1 previous error diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr index 04fd139f901b..508e6f402342 100644 --- a/tests/ui/coherence/occurs-check/opaques.next.stderr +++ b/tests/ui/coherence/occurs-check/opaques.next.stderr @@ -1,17 +1,17 @@ error[E0119]: conflicting implementations of trait `Trait<_>` - --> $DIR/opaques.rs:28:1 + --> $DIR/opaques.rs:27:1 | LL | impl Trait for T { | ---------------------- first implementation here ... -LL | impl Trait for defining_scope::Alias { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation +LL | impl Trait for Alias { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error[E0282]: type annotations needed - --> $DIR/opaques.rs:11:23 + --> $DIR/opaques.rs:11:19 | -LL | pub fn cast(x: Container, T>) -> Container { - | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type +LL | pub fn cast(x: Container, T>) -> Container { + | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type error: aborting due to 2 previous errors diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs index e197256c78c7..5ea654189a94 100644 --- a/tests/ui/coherence/occurs-check/opaques.rs +++ b/tests/ui/coherence/occurs-check/opaques.rs @@ -4,14 +4,13 @@ // A regression test for #105787 #![feature(type_alias_impl_trait)] -mod defining_scope { - use super::*; - pub type Alias = impl Sized; - pub fn cast(x: Container, T>) -> Container { - //[next]~^ ERROR type annotations needed - x - } +pub type Alias = impl Sized; + +#[define_opaque(Alias)] +pub fn cast(x: Container, T>) -> Container { + //[next]~^ ERROR type annotations needed + x } struct Container, U> { @@ -25,12 +24,12 @@ trait Trait { impl Trait for T { type Assoc = Box; } -impl Trait for defining_scope::Alias { +impl Trait for Alias { //~^ ERROR conflicting implementations of trait type Assoc = usize; } fn main() { - let x: Box = defining_scope::cast::<()>(Container { x: 0 }).x; + let x: Box = cast::<()>(Container { x: 0 }).x; println!("{}", *x); } diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs index 02e9eb65570c..ea91933e6949 100644 --- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs +++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs @@ -7,6 +7,7 @@ type Identity = impl Sized; +#[define_opaque(Identity)] fn define_identity(x: T) -> Identity { x } @@ -16,6 +17,7 @@ impl foreign::Trait0 for Identity {} type Opaque = impl Sized; +#[define_opaque(Opaque)] fn define_local() -> Opaque { Local } diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr index 57f5bbd22787..6203742b47c0 100644 --- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr +++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr @@ -1,5 +1,5 @@ error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - --> $DIR/orphan-check-opaque-types-not-covering.rs:14:6 + --> $DIR/orphan-check-opaque-types-not-covering.rs:15:6 | LL | impl foreign::Trait0 for Identity {} | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) @@ -8,7 +8,7 @@ LL | impl foreign::Trait0 for Identity {} = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - --> $DIR/orphan-check-opaque-types-not-covering.rs:23:6 + --> $DIR/orphan-check-opaque-types-not-covering.rs:25:6 | LL | impl foreign::Trait1 for Opaque {} | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs index 56b8acbf88cd..446112cc617d 100644 --- a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs @@ -3,14 +3,14 @@ type Foo = impl Sized; -fn with_bound() -> Foo +#[define_opaque(Foo)] +fn with_bound() where [u8; (N / 2) as usize]: Sized, { let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; //~^ ERROR mismatched types //~| ERROR non-primitive cast: `usize` as `Foo` - todo!() } fn main() { diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr index e9fb8c0f403a..9f48a8563c8a 100644 --- a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/opaque_type.rs:10:17 + --> $DIR/opaque_type.rs:11:17 | LL | type Foo = impl Sized; | ---------- the found opaque type @@ -11,7 +11,7 @@ LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; found opaque type `Foo` error[E0605]: non-primitive cast: `usize` as `Foo` - --> $DIR/opaque_type.rs:10:17 + --> $DIR/opaque_type.rs:11:17 | LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; | ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object diff --git a/tests/ui/const-generics/opaque_types.rs b/tests/ui/const-generics/opaque_types.rs index 2c7170c889fb..788d79519998 100644 --- a/tests/ui/const-generics/opaque_types.rs +++ b/tests/ui/const-generics/opaque_types.rs @@ -1,9 +1,8 @@ #![feature(type_alias_impl_trait)] type Foo = impl Sized; -//~^ ERROR: cycle -//~| ERROR: cycle +#[define_opaque(Foo)] fn foo() {} //~^ ERROR: `Foo` is forbidden as the type of a const generic parameter //~| ERROR: item does not constrain diff --git a/tests/ui/const-generics/opaque_types.stderr b/tests/ui/const-generics/opaque_types.stderr index a060488b3287..f67e1c8ce699 100644 --- a/tests/ui/const-generics/opaque_types.stderr +++ b/tests/ui/const-generics/opaque_types.stderr @@ -1,26 +1,26 @@ error: `Foo` is forbidden as the type of a const generic parameter - --> $DIR/opaque_types.rs:7:17 + --> $DIR/opaque_types.rs:6:17 | LL | fn foo() {} | ^^^ | = note: the only supported types are integers, `bool`, and `char` -error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/opaque_types.rs:7:4 +error: item does not constrain `Foo::{opaque#0}` + --> $DIR/opaque_types.rs:6:4 | LL | fn foo() {} | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/opaque_types.rs:3:12 | LL | type Foo = impl Sized; | ^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/opaque_types.rs:12:11 + --> $DIR/opaque_types.rs:11:11 | LL | type Foo = impl Sized; | ---------- the expected opaque type @@ -31,106 +31,6 @@ LL | foo::<42>(); = note: expected opaque type `Foo` found type `{integer}` -error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` - --> $DIR/opaque_types.rs:3:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - | -note: ...which requires computing type of opaque `Foo::{opaque#0}`... - --> $DIR/opaque_types.rs:3:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ -note: ...which requires type-checking `main`... - --> $DIR/opaque_types.rs:11:1 - | -LL | fn main() { - | ^^^^^^^^^ -note: ...which requires evaluating type-level constant... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ -note: ...which requires const-evaluating + checking `main::{constant#0}`... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ -note: ...which requires caching mir of `main::{constant#0}` for CTFE... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ -note: ...which requires elaborating drops for `main::{constant#0}`... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ - = note: ...which requires normalizing `Foo`... - = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle -note: cycle used when checking that `Foo::{opaque#0}` is well-formed - --> $DIR/opaque_types.rs:3:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information +error: aborting due to 3 previous errors -error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}` - --> $DIR/opaque_types.rs:3:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - | -note: ...which requires type-checking `main`... - --> $DIR/opaque_types.rs:11:1 - | -LL | fn main() { - | ^^^^^^^^^ -note: ...which requires evaluating type-level constant... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ -note: ...which requires const-evaluating + checking `main::{constant#0}`... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ -note: ...which requires caching mir of `main::{constant#0}` for CTFE... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ -note: ...which requires elaborating drops for `main::{constant#0}`... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ -note: ...which requires borrow-checking `main::{constant#0}`... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ -note: ...which requires promoting constants in MIR for `main::{constant#0}`... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ -note: ...which requires const checking `main::{constant#0}`... - --> $DIR/opaque_types.rs:12:11 - | -LL | foo::<42>(); - | ^^ - = note: ...which again requires computing type of opaque `Foo::{opaque#0}`, completing the cycle -note: cycle used when computing type of `Foo::{opaque#0}` - --> $DIR/opaque_types.rs:3:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0308, E0391. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/opaque_types2.rs b/tests/ui/const-generics/opaque_types2.rs index fd57438bb617..69f813cf84ae 100644 --- a/tests/ui/const-generics/opaque_types2.rs +++ b/tests/ui/const-generics/opaque_types2.rs @@ -4,13 +4,14 @@ type Foo = impl Sized; fn foo() {} -const C: Foo = 42; +#[define_opaque(Foo)] +const fn baz() -> Foo { + 42 +} -fn bar() -where - Foo:, -{ - foo::(); +#[define_opaque(Foo)] +fn bar() { + foo::<{ baz() }>(); //~^ ERROR: mismatched types } diff --git a/tests/ui/const-generics/opaque_types2.stderr b/tests/ui/const-generics/opaque_types2.stderr index 2fb1669b7bfa..98d96c3ccee3 100644 --- a/tests/ui/const-generics/opaque_types2.stderr +++ b/tests/ui/const-generics/opaque_types2.stderr @@ -1,11 +1,11 @@ error[E0308]: mismatched types - --> $DIR/opaque_types2.rs:13:11 + --> $DIR/opaque_types2.rs:14:13 | LL | type Foo = impl Sized; | ---------- the found opaque type ... -LL | foo::(); - | ^ expected `u32`, found opaque type +LL | foo::<{ baz() }>(); + | ^^^^^ expected `u32`, found opaque type | = note: expected type `u32` found opaque type `Foo` diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs index a92b99976e26..75bd6f7a123c 100644 --- a/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs +++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs @@ -3,14 +3,20 @@ type Foo = impl Send; struct A; -const VALUE: Foo = value(); -//~^ ERROR cannot find function `value` in this scope +#[define_opaque(Foo)] +//~^ ERROR unstable library feature +const fn foo() -> Foo { + value() + //~^ ERROR cannot find function `value` in this scope +} + +const VALUE: Foo = foo(); fn test() { match VALUE { 0 | 0 => {} -//~^ ERROR mismatched types -//~| ERROR mismatched types + //~^ ERROR mismatched types + //~| ERROR mismatched types _ => (), } } diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr index daf0ccaa776c..bcb6a80a8f2b 100644 --- a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr +++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr @@ -1,3 +1,13 @@ +error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns + --> $DIR/ice-unhandled-type-122191.rs:6:3 + | +LL | #[define_opaque(Foo)] + | ^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: `impl Trait` in type aliases is unstable --> $DIR/ice-unhandled-type-122191.rs:1:12 | @@ -9,13 +19,16 @@ LL | type Foo = impl Send; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0425]: cannot find function `value` in this scope - --> $DIR/ice-unhandled-type-122191.rs:6:20 + --> $DIR/ice-unhandled-type-122191.rs:9:5 | -LL | const VALUE: Foo = value(); - | ^^^^^ not found in this scope +LL | value() + | ^^^^^ help: a constant with a similar name exists: `VALUE` +... +LL | const VALUE: Foo = foo(); + | ------------------------- similarly named constant `VALUE` defined here error[E0308]: mismatched types - --> $DIR/ice-unhandled-type-122191.rs:11:9 + --> $DIR/ice-unhandled-type-122191.rs:17:9 | LL | type Foo = impl Send; | --------- the expected opaque type @@ -27,14 +40,14 @@ LL | 0 | 0 => {} | = note: expected opaque type `Foo` found type `{integer}` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/ice-unhandled-type-122191.rs:9:4 +note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types + --> $DIR/ice-unhandled-type-122191.rs:15:4 | LL | fn test() { | ^^^^ error[E0308]: mismatched types - --> $DIR/ice-unhandled-type-122191.rs:11:13 + --> $DIR/ice-unhandled-type-122191.rs:17:13 | LL | type Foo = impl Send; | --------- the expected opaque type @@ -46,13 +59,13 @@ LL | 0 | 0 => {} | = note: expected opaque type `Foo` found type `{integer}` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/ice-unhandled-type-122191.rs:9:4 +note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types + --> $DIR/ice-unhandled-type-122191.rs:15:4 | LL | fn test() { | ^^^^ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0308, E0425, E0658. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-promoted-opaque.atomic.stderr b/tests/ui/consts/const-promoted-opaque.atomic.stderr index b9d5cbf801a8..9c0c969d586c 100644 --- a/tests/ui/consts/const-promoted-opaque.atomic.stderr +++ b/tests/ui/consts/const-promoted-opaque.atomic.stderr @@ -1,5 +1,5 @@ -error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time - --> $DIR/const-promoted-opaque.rs:28:26 +error[E0493]: destructor of `Foo` cannot be evaluated at compile-time + --> $DIR/const-promoted-opaque.rs:32:26 | LL | let _: &'static _ = &FOO; | ^^^ the destructor for this type cannot be evaluated in constants @@ -8,13 +8,13 @@ LL | }; | - value is dropped here error[E0492]: constants cannot refer to interior mutable data - --> $DIR/const-promoted-opaque.rs:32:19 + --> $DIR/const-promoted-opaque.rs:36:19 | LL | const BAZ: &Foo = &FOO; | ^^^^ this borrow of an interior mutable value may end up in the final value error[E0716]: temporary value dropped while borrowed - --> $DIR/const-promoted-opaque.rs:36:26 + --> $DIR/const-promoted-opaque.rs:40:26 | LL | let _: &'static _ = &FOO; | ---------- ^^^ creates a temporary value which is freed while still in use diff --git a/tests/ui/consts/const-promoted-opaque.rs b/tests/ui/consts/const-promoted-opaque.rs index bb33e92778aa..188dacd10034 100644 --- a/tests/ui/consts/const-promoted-opaque.rs +++ b/tests/ui/consts/const-promoted-opaque.rs @@ -8,25 +8,29 @@ //! hidden type of the opaque type. Thus we ended up relying on the //! result of our analysis to compute the result of our analysis. -//@[unit] check-pass +pub type Foo = impl Sized; -mod helper { - pub type Foo = impl Sized; - - #[cfg(string)] - pub const FOO: Foo = String::new(); - - #[cfg(atomic)] - pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42); - - #[cfg(unit)] - pub const FOO: Foo = (); +#[cfg(string)] +#[define_opaque(Foo)] +const fn foo() -> Foo { + String::new() } -use helper::*; + +#[cfg(atomic)] +#[define_opaque(Foo)] +const fn foo() -> Foo { + std::sync::atomic::AtomicU8::new(42) +} + +#[cfg(unit)] +#[define_opaque(Foo)] +const fn foo() -> Foo {} + +const FOO: Foo = foo(); const BAR: () = { let _: &'static _ = &FOO; - //[string,atomic]~^ ERROR: destructor of `helper::Foo` cannot be evaluated at compile-time + //[string,atomic,unit]~^ ERROR: destructor of `Foo` cannot be evaluated at compile-time }; const BAZ: &Foo = &FOO; @@ -34,5 +38,5 @@ const BAZ: &Foo = &FOO; fn main() { let _: &'static _ = &FOO; - //[string,atomic]~^ ERROR: temporary value dropped while borrowed + //[string,atomic,unit]~^ ERROR: temporary value dropped while borrowed } diff --git a/tests/ui/consts/const-promoted-opaque.string.stderr b/tests/ui/consts/const-promoted-opaque.string.stderr index 33e5f426448c..847a466f21c5 100644 --- a/tests/ui/consts/const-promoted-opaque.string.stderr +++ b/tests/ui/consts/const-promoted-opaque.string.stderr @@ -1,5 +1,5 @@ -error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time - --> $DIR/const-promoted-opaque.rs:28:26 +error[E0493]: destructor of `Foo` cannot be evaluated at compile-time + --> $DIR/const-promoted-opaque.rs:32:26 | LL | let _: &'static _ = &FOO; | ^^^ the destructor for this type cannot be evaluated in constants @@ -8,7 +8,7 @@ LL | }; | - value is dropped here error[E0716]: temporary value dropped while borrowed - --> $DIR/const-promoted-opaque.rs:36:26 + --> $DIR/const-promoted-opaque.rs:40:26 | LL | let _: &'static _ = &FOO; | ---------- ^^^ creates a temporary value which is freed while still in use diff --git a/tests/ui/consts/const-promoted-opaque.unit.stderr b/tests/ui/consts/const-promoted-opaque.unit.stderr new file mode 100644 index 000000000000..847a466f21c5 --- /dev/null +++ b/tests/ui/consts/const-promoted-opaque.unit.stderr @@ -0,0 +1,24 @@ +error[E0493]: destructor of `Foo` cannot be evaluated at compile-time + --> $DIR/const-promoted-opaque.rs:32:26 + | +LL | let _: &'static _ = &FOO; + | ^^^ the destructor for this type cannot be evaluated in constants +LL | +LL | }; + | - value is dropped here + +error[E0716]: temporary value dropped while borrowed + --> $DIR/const-promoted-opaque.rs:40:26 + | +LL | let _: &'static _ = &FOO; + | ---------- ^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +LL | +LL | } + | - temporary value is freed at the end of this statement + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0493, E0716. +For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs index 795e021ceb08..f333f3462c75 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs @@ -20,6 +20,7 @@ mod m { } } + #[define_opaque(NotCalledFn)] fn mk_not_called() -> NotCalledFn { not_called:: } diff --git a/tests/ui/coroutine/layout-error.rs b/tests/ui/coroutine/layout-error.rs index 3e26cf17d29e..6cf32134025c 100644 --- a/tests/ui/coroutine/layout-error.rs +++ b/tests/ui/coroutine/layout-error.rs @@ -16,22 +16,20 @@ impl Task { } } -mod helper { - use super::*; - pub type F = impl Future; - fn foo() - where - F:, - { - async fn cb() { - let a = Foo; //~ ERROR cannot find value `Foo` in this scope - } - - Task::spawn(&POOL, || cb()); +pub type F = impl Future; +#[define_opaque(F)] +fn foo() +where + F:, +{ + async fn cb() { + let a = Foo; //~ ERROR cannot find value `Foo` in this scope } + + Task::spawn(&POOL, || cb()); } // Check that statics are inhabited computes they layout. -static POOL: Task = Task::new(); +static POOL: Task = Task::new(); fn main() {} diff --git a/tests/ui/coroutine/layout-error.stderr b/tests/ui/coroutine/layout-error.stderr index ceadb62c9998..91e352164357 100644 --- a/tests/ui/coroutine/layout-error.stderr +++ b/tests/ui/coroutine/layout-error.stderr @@ -1,8 +1,8 @@ error[E0425]: cannot find value `Foo` in this scope - --> $DIR/layout-error.rs:27:21 + --> $DIR/layout-error.rs:26:17 | -LL | let a = Foo; - | ^^^ not found in this scope +LL | let a = Foo; + | ^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/coroutine/metadata-sufficient-for-layout.rs b/tests/ui/coroutine/metadata-sufficient-for-layout.rs index 9c3a7e4378e3..b7d8575c7617 100644 --- a/tests/ui/coroutine/metadata-sufficient-for-layout.rs +++ b/tests/ui/coroutine/metadata-sufficient-for-layout.rs @@ -15,6 +15,7 @@ mod helper { use std::ops::Coroutine; pub type F = impl Coroutine<(), Yield = (), Return = ()>; + #[define_opaque(F)] fn f() -> F { metadata_sufficient_for_layout::g() } diff --git a/tests/ui/drop/drop_elaboration_with_errors.rs b/tests/ui/drop/drop_elaboration_with_errors.rs index 35d05e6cf64a..6b686e49d45f 100644 --- a/tests/ui/drop/drop_elaboration_with_errors.rs +++ b/tests/ui/drop/drop_elaboration_with_errors.rs @@ -10,6 +10,7 @@ struct Foo { type Tait = impl Sized; +#[define_opaque(Tait)] fn ice_cold(beverage: Tait) { let Foo { field } = beverage; _ = field; diff --git a/tests/ui/drop/drop_elaboration_with_errors.stderr b/tests/ui/drop/drop_elaboration_with_errors.stderr index bec229631e18..ea2c9b949e42 100644 --- a/tests/ui/drop/drop_elaboration_with_errors.stderr +++ b/tests/ui/drop/drop_elaboration_with_errors.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/drop_elaboration_with_errors.rs:19:5 + --> $DIR/drop_elaboration_with_errors.rs:20:5 | LL | fn main() { | - expected `()` because of default return type diff --git a/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs b/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs index d0be240e07ba..4e6be341ef0d 100644 --- a/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs +++ b/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs @@ -4,7 +4,11 @@ pub mod foo { type MainFn = impl Fn(); fn bar() {} - pub const BAR: MainFn = bar; + #[define_opaque(MainFn)] + const fn def() -> MainFn { + bar + } + pub const BAR: MainFn = def(); } use foo::BAR as main; //~ ERROR `main` function not found in crate diff --git a/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr b/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr index 50e4cd7d39f7..375b3a53030a 100644 --- a/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr +++ b/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr @@ -1,5 +1,5 @@ error[E0601]: `main` function not found in crate `imported_main_const_fn_item_type_forbidden` - --> $DIR/imported_main_const_fn_item_type_forbidden.rs:10:22 + --> $DIR/imported_main_const_fn_item_type_forbidden.rs:14:22 | LL | use foo::BAR as main; | ---------------- ^ consider adding a `main` function to `$DIR/imported_main_const_fn_item_type_forbidden.rs` diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs index 6d17f5e837d9..ec70a20844a5 100644 --- a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs +++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -5,27 +5,32 @@ use std::fmt::Debug; type Foo = impl Debug; struct Bar(Foo); +#[define_opaque(Foo)] fn define() -> Bar { Bar(42) } type Foo2 = impl Debug; -fn define2(_: Foo2) { +#[define_opaque(Foo2)] +fn define2() { let x = || -> Foo2 { 42 }; } type Foo3 = impl Debug; +#[define_opaque(Foo3)] fn define3(x: Foo3) { let y: i32 = x; } -fn define3_1(_: Foo3) { +#[define_opaque(Foo3)] +fn define3_1() { define3(42) } type Foo4 = impl Debug; +#[define_opaque(Foo4)] fn define4(_: Foo4) { let y: Foo4 = 42; } diff --git a/tests/ui/fn/fn_def_opaque_coercion.rs b/tests/ui/fn/fn_def_opaque_coercion.rs index 0a8810cf4f8a..8235878c59d7 100644 --- a/tests/ui/fn/fn_def_opaque_coercion.rs +++ b/tests/ui/fn/fn_def_opaque_coercion.rs @@ -11,6 +11,7 @@ fn foo(t: T) -> T { type F = impl Sized; +#[define_opaque(F)] fn f(a: F) { let mut x = foo::; x = foo::<()>; @@ -20,6 +21,7 @@ fn f(a: F) { type G = impl Sized; +#[define_opaque(G)] fn g(a: G) { let x = foo::<()>; let _: () = x(a); @@ -27,6 +29,7 @@ fn g(a: G) { type H = impl Sized; +#[define_opaque(H)] fn h(a: H) { let x = foo::; let _: H = x(()); @@ -34,6 +37,7 @@ fn h(a: H) { type I = impl Sized; +#[define_opaque(I)] fn i(a: I) { let mut x = foo::<()>; x = foo::; @@ -43,6 +47,7 @@ fn i(a: I) { type J = impl Sized; +#[define_opaque(J)] fn j(a: J) { let x = match true { true => foo::, diff --git a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs index 5250e3a3d93e..e090b7039b8d 100644 --- a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs +++ b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs @@ -13,6 +13,7 @@ fn bar(t: T) -> T { type F = impl Sized; +#[define_opaque(F)] fn f(a: F) { let mut x = bar::; x = foo::<()>; //~ ERROR: mismatched types @@ -22,6 +23,7 @@ fn f(a: F) { type I = impl Sized; +#[define_opaque(I)] fn i(a: I) { let mut x = bar::<()>; x = foo::; //~ ERROR: mismatched types @@ -31,6 +33,7 @@ fn i(a: I) { type J = impl Sized; +#[define_opaque(J)] fn j(a: J) { let x = match true { true => bar::, diff --git a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr index 5000601e90f8..4a0991d0eb3c 100644 --- a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr +++ b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:18:9 + --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:19:9 | LL | type F = impl Sized; | ---------- the expected opaque type @@ -13,7 +13,7 @@ LL | x = foo::<()>; found fn item `fn(()) -> () {foo::<()>}` error[E0308]: mismatched types - --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:27:9 + --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:29:9 | LL | fn foo(t: T) -> T { | -------------------- function `foo` defined here diff --git a/tests/ui/generic-associated-types/issue-87258_b.rs b/tests/ui/generic-associated-types/issue-87258_b.rs index 7b7610b21c7d..84c7182cdcbc 100644 --- a/tests/ui/generic-associated-types/issue-87258_b.rs +++ b/tests/ui/generic-associated-types/issue-87258_b.rs @@ -18,6 +18,7 @@ type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1; impl<'c, S: Trait2> Trait2 for &'c mut S { type FooFuture<'a> = Helper<'c, 'a, S>; + #[define_opaque(Helper)] fn foo<'a>() -> Self::FooFuture<'a> { Struct(unimplemented!()) } diff --git a/tests/ui/generic-associated-types/issue-87258_b.stderr b/tests/ui/generic-associated-types/issue-87258_b.stderr index 73f984dcfb86..906ce1f50da7 100644 --- a/tests/ui/generic-associated-types/issue-87258_b.stderr +++ b/tests/ui/generic-associated-types/issue-87258_b.stderr @@ -4,7 +4,7 @@ error: unconstrained opaque type LL | type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1; | ^^^^^^^^^^^ | - = note: `Helper` must be used in combination with a concrete type within the same module + = note: `Helper` must be used in combination with a concrete type within the same crate error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/issue-88287.rs b/tests/ui/generic-associated-types/issue-88287.rs index 5d64ad8eeae0..ce0b9827d110 100644 --- a/tests/ui/generic-associated-types/issue-88287.rs +++ b/tests/ui/generic-associated-types/issue-88287.rs @@ -30,6 +30,7 @@ where A: SearchableResource + ?Sized + 'f, Self: 'f; + #[define_opaque(SearchFutureTy)] fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> { async move { todo!() } //~^ ERROR: the size for values of type `A` cannot be known at compilation time diff --git a/tests/ui/generic-associated-types/issue-88287.stderr b/tests/ui/generic-associated-types/issue-88287.stderr index 54ecc5cfcd81..71cd6677e63f 100644 --- a/tests/ui/generic-associated-types/issue-88287.stderr +++ b/tests/ui/generic-associated-types/issue-88287.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/issue-88287.rs:34:9 + --> $DIR/issue-88287.rs:35:9 | LL | type SearchFutureTy<'f, A, B: 'f> | - this type parameter needs to be `Sized` diff --git a/tests/ui/generic-associated-types/issue-90014-tait.stderr b/tests/ui/generic-associated-types/issue-90014-tait.stderr index 09c2903ab028..fffe5b93e5a9 100644 --- a/tests/ui/generic-associated-types/issue-90014-tait.stderr +++ b/tests/ui/generic-associated-types/issue-90014-tait.stderr @@ -1,3 +1,11 @@ +error: unconstrained opaque type + --> $DIR/issue-90014-tait.rs:15:20 + | +LL | type Fut<'a> = impl Future; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Fut` must be used in combination with a concrete type within the same impl + error[E0308]: mismatched types --> $DIR/issue-90014-tait.rs:18:9 | @@ -11,12 +19,7 @@ LL | async { () } | = note: expected opaque type `Foo<'_>::Fut<'a>` found `async` block `{async block@$DIR/issue-90014-tait.rs:18:9: 18:14}` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/issue-90014-tait.rs:17:8 - | -LL | fn make_fut<'a>(&'a self) -> Self::Fut<'a> { - | ^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.rs b/tests/ui/generic-associated-types/issue-90014-tait2.rs index 3f7a9ff63c31..472a0d500c88 100644 --- a/tests/ui/generic-associated-types/issue-90014-tait2.rs +++ b/tests/ui/generic-associated-types/issue-90014-tait2.rs @@ -20,6 +20,7 @@ impl<'x, T: 'x> Trait<'x> for (T,) { } impl Foo<'_> { + #[define_opaque(Fut)] fn make_fut(&self) -> Box Trait<'a, Thing = Fut<'a>>> { Box::new((async { () },)) //~^ ERROR expected generic lifetime parameter, found `'a` diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.stderr b/tests/ui/generic-associated-types/issue-90014-tait2.stderr index aa427d42649a..bf944aac7975 100644 --- a/tests/ui/generic-associated-types/issue-90014-tait2.stderr +++ b/tests/ui/generic-associated-types/issue-90014-tait2.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/issue-90014-tait2.rs:24:9 + --> $DIR/issue-90014-tait2.rs:25:9 | LL | type Fut<'a> = impl Future; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr index 57cbe1691182..34617448a692 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr @@ -1,18 +1,18 @@ -error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/norm-before-method-resolution-opaque-type.rs:16:4 +error: item does not constrain `Foo::{opaque#0}` + --> $DIR/norm-before-method-resolution-opaque-type.rs:17:4 | LL | fn weird_bound(x: &>::Out) -> X | ^^^^^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/norm-before-method-resolution-opaque-type.rs:14:12 | LL | type Foo = impl Sized; | ^^^^^^^^^^ error[E0507]: cannot move out of `*x` which is behind a shared reference - --> $DIR/norm-before-method-resolution-opaque-type.rs:22:13 + --> $DIR/norm-before-method-resolution-opaque-type.rs:23:13 | LL | let x = *x; | ^^ move occurs because `*x` has type `>::Out`, which does not implement the `Copy` trait diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs index 43207d892764..bb663c82abb0 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs @@ -13,6 +13,7 @@ impl<'a, T> Trait<'a> for T { type Foo = impl Sized; +#[define_opaque(Foo)] fn weird_bound(x: &>::Out) -> X //[old]~^ ERROR: item does not constrain where diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs index 65e90c1ca53c..f703269a4388 100644 --- a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs +++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs @@ -8,31 +8,29 @@ impl Captures<'_> for T {} pub struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>); unsafe impl Send for MyTy<'_, 'static> {} -pub mod step1 { - use super::*; - pub type Step1<'a, 'b: 'a> = impl Sized + Captures<'b> + 'a; - pub fn step1<'a, 'b: 'a>() -> Step1<'a, 'b> { - MyTy::<'a, 'b>(None) - } +pub type Step1<'a, 'b: 'a> = impl Sized + Captures<'b> + 'a; +#[define_opaque(Step1)] +pub fn step1<'a, 'b: 'a>() -> Step1<'a, 'b> { + MyTy::<'a, 'b>(None) } -pub mod step2 { - pub type Step2<'a> = impl Send + 'a; +pub type Step2<'a> = impl Send + 'a; - // Although `Step2` is WF at the definition site, it's not WF in its - // declaration site (above). We check this in `check_opaque_meets_bounds`, - // which must remain sound. - pub fn step2<'a, 'b: 'a>() -> Step2<'a> - where crate::step1::Step1<'a, 'b>: Send - { - crate::step1::step1::<'a, 'b>() - //~^ ERROR hidden type for `Step2<'a>` captures lifetime that does not appear in bounds - } +// Although `Step2` is WF at the definition site, it's not WF in its +// declaration site (above). We check this in `check_opaque_meets_bounds`, +// which must remain sound. +#[define_opaque(Step2)] +pub fn step2<'a, 'b: 'a>() -> Step2<'a> +where + Step1<'a, 'b>: Send, +{ + step1::<'a, 'b>() + //~^ ERROR hidden type for `Step2<'a>` captures lifetime that does not appear in bounds } fn step3<'a, 'b>() { fn is_send() {} - is_send::>(); + is_send::>(); } fn main() {} diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr index 58d7f9959d34..ce797ccf40c9 100644 --- a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr +++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr @@ -1,14 +1,14 @@ error[E0700]: hidden type for `Step2<'a>` captures lifetime that does not appear in bounds - --> $DIR/tait-hidden-erased-unsoundness-2.rs:28:9 + --> $DIR/tait-hidden-erased-unsoundness-2.rs:27:5 | -LL | pub type Step2<'a> = impl Send + 'a; - | -------------- opaque type defined here +LL | pub type Step2<'a> = impl Send + 'a; + | -------------- opaque type defined here ... -LL | pub fn step2<'a, 'b: 'a>() -> Step2<'a> - | -- hidden type `Step1<'a, 'b>` captures the lifetime `'b` as defined here +LL | pub fn step2<'a, 'b: 'a>() -> Step2<'a> + | -- hidden type `Step1<'a, 'b>` captures the lifetime `'b` as defined here ... -LL | crate::step1::step1::<'a, 'b>() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | step1::<'a, 'b>() + | ^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs index 40efd941e338..ba22f16003ca 100644 --- a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs +++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs @@ -12,16 +12,15 @@ fn step1<'a, 'b: 'a>() -> impl Sized + Captures<'b> + 'a { MyTy::<'a, 'b>(None) } -mod tait { - type Tait<'a> = impl Sized + 'a; - pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> { - super::step1::<'a, 'b>() - //~^ ERROR hidden type for `Tait<'a>` captures lifetime that does not appear in bounds - } +type Tait<'a> = impl Sized + 'a; +#[define_opaque(Tait)] +fn step2<'a, 'b: 'a>() -> Tait<'a> { + step1::<'a, 'b>() + //~^ ERROR hidden type for `Tait<'a>` captures lifetime that does not appear in bounds } fn step3<'a, 'b: 'a>() -> impl Send + 'a { - tait::step2::<'a, 'b>() + step2::<'a, 'b>() // This should not be Send unless `'b: 'static` } diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr index 6c9b8cf24273..ed1afd645072 100644 --- a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr +++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr @@ -1,12 +1,13 @@ error[E0700]: hidden type for `Tait<'a>` captures lifetime that does not appear in bounds - --> $DIR/tait-hidden-erased-unsoundness.rs:18:9 + --> $DIR/tait-hidden-erased-unsoundness.rs:18:5 | -LL | type Tait<'a> = impl Sized + 'a; - | --------------- opaque type defined here -LL | pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> { - | -- hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here -LL | super::step1::<'a, 'b>() - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Tait<'a> = impl Sized + 'a; + | --------------- opaque type defined here +LL | #[define_opaque(Tait)] +LL | fn step2<'a, 'b: 'a>() -> Tait<'a> { + | -- hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here +LL | step1::<'a, 'b>() + | ^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/associated-type-undefine.rs b/tests/ui/impl-trait/associated-type-undefine.rs index c8f07021fbf1..895525960fc1 100644 --- a/tests/ui/impl-trait/associated-type-undefine.rs +++ b/tests/ui/impl-trait/associated-type-undefine.rs @@ -16,6 +16,7 @@ impl Foo for u32 { impl Foo for () { type Bar = impl Sized; + //~^ ERROR: unconstrained opaque type type Gat = ::Bar; // Because we encounter `Gat` first, we never walk into another `Gat` // again, thus missing the opaque type that we could be defining. diff --git a/tests/ui/impl-trait/associated-type-undefine.stderr b/tests/ui/impl-trait/associated-type-undefine.stderr index 5d9d525eb93b..e567f1bcdf6a 100644 --- a/tests/ui/impl-trait/associated-type-undefine.stderr +++ b/tests/ui/impl-trait/associated-type-undefine.stderr @@ -1,5 +1,13 @@ +error: unconstrained opaque type + --> $DIR/associated-type-undefine.rs:18:16 + | +LL | type Bar = impl Sized; + | ^^^^^^^^^^ + | + = note: `Bar` must be used in combination with a concrete type within the same impl + error[E0308]: mismatched types - --> $DIR/associated-type-undefine.rs:23:14 + --> $DIR/associated-type-undefine.rs:24:14 | LL | type Bar = impl Sized; | ---------- the expected opaque type @@ -9,12 +17,7 @@ LL | ((), ()) | = note: expected opaque type `<() as Foo>::Bar` found unit type `()` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/associated-type-undefine.rs:22:8 - | -LL | fn foo(self) -> (::Gat, ::Gat) { - | ^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/async_scope_creep.rs b/tests/ui/impl-trait/async_scope_creep.rs index 0fb355c52337..449f090a2e47 100644 --- a/tests/ui/impl-trait/async_scope_creep.rs +++ b/tests/ui/impl-trait/async_scope_creep.rs @@ -22,11 +22,13 @@ impl Pending { } #[cfg(tait)] + #[define_opaque(OpeningReadFuture)] fn read_fut(&mut self) -> OpeningReadFuture<'_> { self.read() } #[cfg(rpit)] + #[define_opaque(PendingReader)] fn read_fut( &mut self, ) -> impl std::future::Future, CantOpen>> { diff --git a/tests/ui/impl-trait/auto-trait-coherence.rs b/tests/ui/impl-trait/auto-trait-coherence.rs index 0d7fef21cc92..fdb981ea4064 100644 --- a/tests/ui/impl-trait/auto-trait-coherence.rs +++ b/tests/ui/impl-trait/auto-trait-coherence.rs @@ -5,6 +5,7 @@ trait OpaqueTrait {} impl OpaqueTrait for T {} type OpaqueType = impl OpaqueTrait; +#[define_opaque(OpaqueType)] fn mk_opaque() -> OpaqueType { () } diff --git a/tests/ui/impl-trait/auto-trait-coherence.stderr b/tests/ui/impl-trait/auto-trait-coherence.stderr index e0f4c857717c..cfeccc3d7666 100644 --- a/tests/ui/impl-trait/auto-trait-coherence.stderr +++ b/tests/ui/impl-trait/auto-trait-coherence.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` - --> $DIR/auto-trait-coherence.rs:21:1 + --> $DIR/auto-trait-coherence.rs:22:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here diff --git a/tests/ui/impl-trait/bound-normalization-pass.rs b/tests/ui/impl-trait/bound-normalization-pass.rs index 801187b6f5e0..77bc0206830a 100644 --- a/tests/ui/impl-trait/bound-normalization-pass.rs +++ b/tests/ui/impl-trait/bound-normalization-pass.rs @@ -77,6 +77,7 @@ mod opaque_types { type Ex = impl Trait::Assoc>; + #[define_opaque(Ex)] fn define() -> Ex { () } diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs index e8c1fcdd2133..54d68afc31f6 100644 --- a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs +++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs @@ -5,7 +5,8 @@ type T = impl Sized; struct Foo; impl Into for Foo { -//~^ ERROR conflicting implementations of trait `Into<_>` for type `Foo` + //~^ ERROR conflicting implementations of trait `Into<_>` for type `Foo` + #[define_opaque(T)] fn into(self) -> T { Foo } diff --git a/tests/ui/impl-trait/deduce-signature-from-supertrait.rs b/tests/ui/impl-trait/deduce-signature-from-supertrait.rs index 4e452994f72e..28b6697f4bcb 100644 --- a/tests/ui/impl-trait/deduce-signature-from-supertrait.rs +++ b/tests/ui/impl-trait/deduce-signature-from-supertrait.rs @@ -8,7 +8,8 @@ impl SuperExpectation for T {} type Foo = impl SuperExpectation; -fn bop(_: Foo) { +#[define_opaque(Foo)] +fn bop() { let _: Foo = |x| { let _ = x.to_string(); }; diff --git a/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs index af623dc7cd9d..e8be2082d7c9 100644 --- a/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs +++ b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs @@ -7,15 +7,12 @@ use std::future::Future; -mod foo { - use std::future::Future; - pub type Fut<'a> = impl Future + 'a; +pub type Fut<'a> = impl Future + 'a; - fn foo<'a>(_: &()) -> Fut<'_> { - async {} - } +#[define_opaque(Fut)] +fn foo<'a>(_: &()) -> Fut<'_> { + async {} } -use foo::*; trait Test { fn hello(); diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr b/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr index 01c5a553dc50..dca0a7b0a1a9 100644 --- a/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr +++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr @@ -13,7 +13,7 @@ LL | Thunk::new(|mut cont: /* Type */| { | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/hidden-type-is-opaque-2.rs:20:17 + --> $DIR/hidden-type-is-opaque-2.rs:21:17 | LL | Thunk::new(|mut cont| { | ^^^^^^^^ diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr b/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr index 01c5a553dc50..dca0a7b0a1a9 100644 --- a/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr +++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr @@ -13,7 +13,7 @@ LL | Thunk::new(|mut cont: /* Type */| { | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/hidden-type-is-opaque-2.rs:20:17 + --> $DIR/hidden-type-is-opaque-2.rs:21:17 | LL | Thunk::new(|mut cont| { | ^^^^^^^^ diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.rs b/tests/ui/impl-trait/hidden-type-is-opaque-2.rs index 78ac8363ba93..7725a04c3584 100644 --- a/tests/ui/impl-trait/hidden-type-is-opaque-2.rs +++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.rs @@ -16,6 +16,7 @@ fn reify_as() -> Thunk Continuation> { type Tait = impl FnOnce(Continuation) -> Continuation; +#[define_opaque(Tait)] fn reify_as_tait() -> Thunk { Thunk::new(|mut cont| { //~^ ERROR type annotations needed diff --git a/tests/ui/impl-trait/hidden-type-is-opaque.rs b/tests/ui/impl-trait/hidden-type-is-opaque.rs index 3111a21e2096..aa9ea2a8a26d 100644 --- a/tests/ui/impl-trait/hidden-type-is-opaque.rs +++ b/tests/ui/impl-trait/hidden-type-is-opaque.rs @@ -10,6 +10,7 @@ fn reify_as() -> Thunk { type Tait = impl ContFn; +#[define_opaque(Tait)] fn reify_as_tait() -> Thunk { Thunk::new(|mut cont| { cont.reify_as(); diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr index 146a3d21068c..c76415d8114b 100644 --- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr +++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr @@ -1,5 +1,5 @@ error[E0407]: method `line_stream` is not a member of trait `X` - --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5 + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:5 | LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X` @@ -17,15 +17,23 @@ LL | type LineStream<'c, 'd> = impl Stream; | | | found 0 type parameters +error: unconstrained opaque type + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:31 + | +LL | type LineStream<'c, 'd> = impl Stream; + | ^^^^^^^^^^^ + | + = note: `LineStream` must be used in combination with a concrete type within the same impl + error[E0277]: `()` is not a future - --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:43 + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:43 | LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future | = help: the trait `Future` is not implemented for `()` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0049, E0277, E0407. For more information about an error, try `rustc --explain E0049`. diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr index ce64a022214e..4d72490ff956 100644 --- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr +++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr @@ -1,5 +1,5 @@ error[E0407]: method `line_stream` is not a member of trait `X` - --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5 + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:5 | LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X` @@ -17,25 +17,33 @@ LL | type LineStream<'c, 'd> = impl Stream; | | | found 0 type parameters +error: unconstrained opaque type + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:31 + | +LL | type LineStream<'c, 'd> = impl Stream; + | ^^^^^^^^^^^ + | + = note: `LineStream` must be used in combination with a concrete type within the same impl + error[E0271]: type mismatch resolving `::LineStreamFut<'a, Repr> == ()` - --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:43 + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:43 | LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ error[E0271]: type mismatch resolving `::LineStreamFut<'a, Repr> normalizes-to _` - --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:73 + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:73 | LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} | ^^ types differ error[E0271]: type mismatch resolving `::LineStreamFut<'a, Repr> normalizes-to _` - --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5 + --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:5 | LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0049, E0271, E0407. For more information about an error, try `rustc --explain E0049`. diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs index cb32723b22dd..a5a37dbb210f 100644 --- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs +++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs @@ -24,6 +24,7 @@ struct Y; impl X for Y { type LineStream<'c, 'd> = impl Stream; //~^ ERROR type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter + //~| ERROR: unconstrained opaque type type LineStreamFut<'a, Repr> = impl Future>; fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {} //~^ method `line_stream` is not a member of trait `X` diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr index 8351175099c9..c9e657b87d5a 100644 --- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr +++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr @@ -36,11 +36,6 @@ LL | fn method() -> Self::Ty; | ^^^^^^^^ = note: expected signature `fn() -> <() as compare_method::Trait>::Ty` found signature `fn() -> ()` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/in-assoc-type-unconstrained.rs:22:12 - | -LL | fn method() -> () {} - | ^^^^^^ help: change the output type to match the trait | LL - fn method() -> () {} diff --git a/tests/ui/impl-trait/in-assoc-type.stderr b/tests/ui/impl-trait/in-assoc-type.stderr index d5b543ea953d..5a8cc40d0276 100644 --- a/tests/ui/impl-trait/in-assoc-type.stderr +++ b/tests/ui/impl-trait/in-assoc-type.stderr @@ -11,11 +11,6 @@ LL | fn foo(&self) -> >::Bar {} | = note: expected opaque type `<() as Foo<()>>::Bar` found unit type `()` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/in-assoc-type.rs:20:8 - | -LL | fn foo(&self) -> >::Bar {} - | ^^^ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/issue-108591.rs b/tests/ui/impl-trait/issue-108591.rs index caf080245687..db1c73831ee7 100644 --- a/tests/ui/impl-trait/issue-108591.rs +++ b/tests/ui/impl-trait/issue-108591.rs @@ -15,6 +15,7 @@ impl MyTy<'_> { type Opaque2 = impl Sized; type Opaque<'a> = Opaque2; +#[define_opaque(Opaque)] fn define<'a>() -> Opaque<'a> {} fn test<'a>() { diff --git a/tests/ui/impl-trait/issue-108592.rs b/tests/ui/impl-trait/issue-108592.rs index 7db2e31549c0..facb8be9d230 100644 --- a/tests/ui/impl-trait/issue-108592.rs +++ b/tests/ui/impl-trait/issue-108592.rs @@ -11,13 +11,10 @@ fn test_closure() { closure(&opaque()); } -mod helper { - pub type Opaque2 = impl Sized; - pub type Opaque<'a> = Opaque2; - fn define<'a>() -> Opaque<'a> {} -} - -use helper::*; +pub type Opaque2 = impl Sized; +pub type Opaque<'a> = Opaque2; +#[define_opaque(Opaque)] +fn define<'a>() -> Opaque<'a> {} fn test_tait(_: &Opaque<'_>) { None::<&'static Opaque<'_>>; diff --git a/tests/ui/impl-trait/issue-99642-2.rs b/tests/ui/impl-trait/issue-99642-2.rs index acbf3e3e2a02..d8d367a5d35f 100644 --- a/tests/ui/impl-trait/issue-99642-2.rs +++ b/tests/ui/impl-trait/issue-99642-2.rs @@ -2,7 +2,8 @@ #![feature(type_alias_impl_trait)] type Opq = impl Sized; +#[define_opaque(Opq)] fn test() -> impl Iterator { Box::new(0..) as Box> } -fn main(){} +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-53457.rs b/tests/ui/impl-trait/issues/issue-53457.rs index bb248ef71773..a47c7655058d 100644 --- a/tests/ui/impl-trait/issues/issue-53457.rs +++ b/tests/ui/impl-trait/issues/issue-53457.rs @@ -7,6 +7,7 @@ fn bar(f: F) -> F { f } +#[define_opaque(X)] fn foo() -> X { bar(|_| ()) } diff --git a/tests/ui/impl-trait/issues/issue-70877.rs b/tests/ui/impl-trait/issues/issue-70877.rs index 6ced0bbba8b3..0f0a1b5187d3 100644 --- a/tests/ui/impl-trait/issues/issue-70877.rs +++ b/tests/ui/impl-trait/issues/issue-70877.rs @@ -15,27 +15,27 @@ impl Iterator for Bar { } } -mod ret { - pub type FooRet = impl std::fmt::Debug; - pub fn quux(st: super::FooArg) -> FooRet { - Some(st.to_string()) - } +pub type FooRet = impl std::fmt::Debug; +#[define_opaque(FooRet)] +pub fn quux(st: FooArg) -> FooRet { + Some(st.to_string()) } -use ret::*; -mod foo { - pub type Foo = impl Iterator; - pub fn ham() -> Foo { - super::Bar(1) - } - pub fn oof(_: Foo) -> impl std::fmt::Debug { - //~^ ERROR: item does not constrain `Foo::{opaque#0}`, but has it in its signature - let mut bar = ham(); - let func = bar.next().unwrap(); - return func(&"oof"); - } +pub type Foo = impl Iterator; +#[define_opaque(Foo)] +pub fn ham() -> Foo { + //~^ ERROR: item does not constrain `FooRet::{opaque#0}` + Bar(1) +} +#[define_opaque(Foo)] +pub fn oof() -> impl std::fmt::Debug { + //~^ ERROR: item does not constrain `FooRet::{opaque#0}` + //~| ERROR: item does not constrain `Foo::{opaque#0}` + let mut bar = ham(); + let func = bar.next().unwrap(); + return func(&"oof"); + //~^ ERROR: opaque type's hidden type cannot be another opaque type } -use foo::*; fn main() { - let _ = oof(ham()); + let _ = oof(); } diff --git a/tests/ui/impl-trait/issues/issue-70877.stderr b/tests/ui/impl-trait/issues/issue-70877.stderr index 4b23a02aaee3..b2f37c8af9eb 100644 --- a/tests/ui/impl-trait/issues/issue-70877.stderr +++ b/tests/ui/impl-trait/issues/issue-70877.stderr @@ -1,15 +1,58 @@ -error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/issue-70877.rs:30:12 +error: item does not constrain `FooRet::{opaque#0}` + --> $DIR/issue-70877.rs:25:8 | -LL | pub fn oof(_: Foo) -> impl std::fmt::Debug { - | ^^^ +LL | pub fn ham() -> Foo { + | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/issue-70877.rs:26:20 + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/issue-70877.rs:18:19 | -LL | pub type Foo = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub type FooRet = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: item does not constrain `FooRet::{opaque#0}` + --> $DIR/issue-70877.rs:30:8 + | +LL | pub fn oof() -> impl std::fmt::Debug { + | ^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/issue-70877.rs:18:19 + | +LL | pub type FooRet = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `Foo::{opaque#0}` + --> $DIR/issue-70877.rs:30:8 + | +LL | pub fn oof() -> impl std::fmt::Debug { + | ^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/issue-70877.rs:23:16 + | +LL | pub type Foo = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: opaque type's hidden type cannot be another opaque type from the same scope + --> $DIR/issue-70877.rs:35:12 + | +LL | return func(&"oof"); + | ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope + | +note: opaque type whose hidden type is being assigned + --> $DIR/issue-70877.rs:30:17 + | +LL | pub fn oof() -> impl std::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ +note: opaque type being used as hidden type + --> $DIR/issue-70877.rs:18:19 + | +LL | pub type FooRet = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors diff --git a/tests/ui/impl-trait/issues/issue-74282.rs b/tests/ui/impl-trait/issues/issue-74282.rs index 51bd5f67ed57..eb14a76a0692 100644 --- a/tests/ui/impl-trait/issues/issue-74282.rs +++ b/tests/ui/impl-trait/issues/issue-74282.rs @@ -3,7 +3,8 @@ type Closure = impl Fn() -> u64; struct Anonymous(Closure); -fn bop(_: Closure) { +#[define_opaque(Closure)] +fn bop() { let y = || -> Closure { || 3 }; Anonymous(|| { //~^ ERROR mismatched types diff --git a/tests/ui/impl-trait/issues/issue-74282.stderr b/tests/ui/impl-trait/issues/issue-74282.stderr index f8e85f7ae000..7a49041cace7 100644 --- a/tests/ui/impl-trait/issues/issue-74282.stderr +++ b/tests/ui/impl-trait/issues/issue-74282.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-74282.rs:8:15 + --> $DIR/issue-74282.rs:9:15 | LL | type Closure = impl Fn() -> u64; | ---------------- the expected opaque type @@ -14,7 +14,7 @@ LL | | }) | |_____^ expected opaque type, found closure | = note: expected opaque type `Closure` - found closure `{closure@$DIR/issue-74282.rs:8:15: 8:17}` + found closure `{closure@$DIR/issue-74282.rs:9:15: 9:17}` = note: no two closures, even if identical, have the same type = help: consider boxing your closure and/or using it as a trait object note: tuple struct defined here @@ -24,7 +24,7 @@ LL | struct Anonymous(Closure); | ^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/issue-74282.rs:8:5 + --> $DIR/issue-74282.rs:9:5 | LL | / Anonymous(|| { LL | | @@ -38,8 +38,8 @@ LL | }); | + help: try adding a return type | -LL | fn bop(_: Closure) -> Anonymous { - | ++++++++++++ +LL | fn bop() -> Anonymous { + | ++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/issues/issue-77987.rs b/tests/ui/impl-trait/issues/issue-77987.rs index a7e7b067d5ff..f134224071f7 100644 --- a/tests/ui/impl-trait/issues/issue-77987.rs +++ b/tests/ui/impl-trait/issues/issue-77987.rs @@ -5,17 +5,16 @@ pub trait Foo {} impl Foo for U {} -mod scope { - pub type Scope = impl super::Foo<()>; +pub type Scope = impl Foo<()>; - #[allow(unused)] - fn infer_scope() -> Scope { - () - } +#[allow(unused)] +#[define_opaque(Scope)] +fn infer_scope() -> Scope { + () } #[allow(unused)] -fn ice() -> impl Foo { +fn ice() -> impl Foo { loop {} } diff --git a/tests/ui/impl-trait/issues/issue-78722-2.rs b/tests/ui/impl-trait/issues/issue-78722-2.rs index e811620c03ba..ef4d26b69755 100644 --- a/tests/ui/impl-trait/issues/issue-78722-2.rs +++ b/tests/ui/impl-trait/issues/issue-78722-2.rs @@ -8,6 +8,7 @@ type F = impl core::future::Future; struct Bug { V1: [(); { + #[define_opaque(F)] fn concrete_use() -> F { //~^ ERROR future that resolves to `u8`, but it resolves to `()` async {} diff --git a/tests/ui/impl-trait/issues/issue-78722-2.stderr b/tests/ui/impl-trait/issues/issue-78722-2.stderr index 27b4b7128302..ede830bf72c8 100644 --- a/tests/ui/impl-trait/issues/issue-78722-2.stderr +++ b/tests/ui/impl-trait/issues/issue-78722-2.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-78722-2.rs:16:20 + --> $DIR/issue-78722-2.rs:17:20 | LL | type F = impl core::future::Future; | -------------------------------------- the expected future @@ -10,10 +10,10 @@ LL | let f: F = async { 1 }; | expected due to this | = note: expected opaque type `F` - found `async` block `{async block@$DIR/issue-78722-2.rs:16:20: 16:25}` + found `async` block `{async block@$DIR/issue-78722-2.rs:17:20: 17:25}` -error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:13:13: 13:18}` to be a future that resolves to `u8`, but it resolves to `()` - --> $DIR/issue-78722-2.rs:11:30 +error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:14:13: 14:18}` to be a future that resolves to `u8`, but it resolves to `()` + --> $DIR/issue-78722-2.rs:12:30 | LL | fn concrete_use() -> F { | ^ expected `u8`, found `()` diff --git a/tests/ui/impl-trait/issues/issue-78722.rs b/tests/ui/impl-trait/issues/issue-78722.rs index 5518c2cf12a3..374cd564b8e6 100644 --- a/tests/ui/impl-trait/issues/issue-78722.rs +++ b/tests/ui/impl-trait/issues/issue-78722.rs @@ -5,6 +5,7 @@ struct Bug { V1: [(); { type F = impl core::future::Future; + #[define_opaque(F)] fn concrete_use() -> F { //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()` async {} diff --git a/tests/ui/impl-trait/issues/issue-78722.stderr b/tests/ui/impl-trait/issues/issue-78722.stderr index 109bda0c5cd6..84c7dfb03384 100644 --- a/tests/ui/impl-trait/issues/issue-78722.stderr +++ b/tests/ui/impl-trait/issues/issue-78722.stderr @@ -1,5 +1,5 @@ error[E0658]: `async` blocks are not allowed in constants - --> $DIR/issue-78722.rs:12:20 + --> $DIR/issue-78722.rs:13:20 | LL | let f: F = async { 1 }; | ^^^^^^^^^^^ @@ -8,8 +8,8 @@ LL | let f: F = async { 1 }; = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0271]: expected `{async block@$DIR/issue-78722.rs:10:13: 10:18}` to be a future that resolves to `u8`, but it resolves to `()` - --> $DIR/issue-78722.rs:8:30 +error[E0271]: expected `{async block@$DIR/issue-78722.rs:11:13: 11:18}` to be a future that resolves to `u8`, but it resolves to `()` + --> $DIR/issue-78722.rs:9:30 | LL | fn concrete_use() -> F { | ^ expected `u8`, found `()` diff --git a/tests/ui/impl-trait/issues/issue-86201.rs b/tests/ui/impl-trait/issues/issue-86201.rs index cde0b8611603..19c68f7697ba 100644 --- a/tests/ui/impl-trait/issues/issue-86201.rs +++ b/tests/ui/impl-trait/issues/issue-86201.rs @@ -4,10 +4,13 @@ //@ check-pass type FunType = impl Fn<()>; -static STATIC_FN: FunType = some_fn; +#[define_opaque(FunType)] +fn foo() -> FunType { + some_fn +} fn some_fn() {} fn main() { - let _: >::Output = STATIC_FN(); + let _: >::Output = foo()(); } diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs index ff1d273ae482..c1176255f244 100644 --- a/tests/ui/impl-trait/issues/issue-86800.rs +++ b/tests/ui/impl-trait/issues/issue-86800.rs @@ -4,43 +4,41 @@ use std::future::Future; -struct Connection { -} +struct Connection {} -trait Transaction { -} +trait Transaction {} struct TestTransaction<'conn> { - conn: &'conn Connection + conn: &'conn Connection, } -impl<'conn> Transaction for TestTransaction<'conn> { -} +impl<'conn> Transaction for TestTransaction<'conn> {} -struct Context { -} +struct Context {} type TransactionResult = Result; type TransactionFuture<'__, O> = impl '__ + Future>; +#[define_opaque(TransactionFuture)] fn execute_transaction_fut<'f, F, O>( //~^ ERROR: item does not constrain f: F, ) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> where - F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f + F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f, { f //~^ ERROR expected generic lifetime parameter, found `'_` } impl Context { + #[define_opaque(TransactionFuture)] async fn do_transaction( //~^ ERROR: item does not constrain - &self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> - ) -> TransactionResult - { + &self, + f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>, + ) -> TransactionResult { //~^ ERROR expected generic lifetime parameter, found `'_` //~| ERROR: item does not constrain let mut conn = Connection {}; diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr index fd9b8e7ac999..11e23d97d72d 100644 --- a/tests/ui/impl-trait/issues/issue-86800.stderr +++ b/tests/ui/impl-trait/issues/issue-86800.stderr @@ -1,33 +1,34 @@ -error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature - --> $DIR/issue-86800.rs:27:4 +error: item does not constrain `TransactionFuture::{opaque#0}` + --> $DIR/issue-86800.rs:24:4 | LL | fn execute_transaction_fut<'f, F, O>( | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/issue-86800.rs:25:34 + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/issue-86800.rs:21:34 | LL | type TransactionFuture<'__, O> = impl '__ + Future>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature - --> $DIR/issue-86800.rs:39:14 +error: item does not constrain `TransactionFuture::{opaque#0}` + --> $DIR/issue-86800.rs:37:14 | LL | async fn do_transaction( | ^^^^^^^^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/issue-86800.rs:25:34 + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/issue-86800.rs:21:34 | LL | type TransactionFuture<'__, O> = impl '__ + Future>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature - --> $DIR/issue-86800.rs:43:5 +error: item does not constrain `TransactionFuture::{opaque#0}` + --> $DIR/issue-86800.rs:41:31 | -LL | / { +LL | ) -> TransactionResult { + | _______________________________^ LL | | LL | | LL | | let mut conn = Connection {}; @@ -36,15 +37,15 @@ LL | | f(&mut transaction).await LL | | } | |_____^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/issue-86800.rs:25:34 + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/issue-86800.rs:21:34 | LL | type TransactionFuture<'__, O> = impl '__ + Future>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-86800.rs:34:5 + --> $DIR/issue-86800.rs:31:5 | LL | type TransactionFuture<'__, O> = impl '__ + Future>; | --- this generic parameter must be used with a generic lifetime parameter @@ -53,12 +54,13 @@ LL | f | ^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-86800.rs:43:5 + --> $DIR/issue-86800.rs:41:31 | LL | type TransactionFuture<'__, O> = impl '__ + Future>; | --- this generic parameter must be used with a generic lifetime parameter ... -LL | / { +LL | ) -> TransactionResult { + | _______________________________^ LL | | LL | | LL | | let mut conn = Connection {}; diff --git a/tests/ui/impl-trait/issues/issue-89312.rs b/tests/ui/impl-trait/issues/issue-89312.rs index 3b0e976780be..35cba41dd4b2 100644 --- a/tests/ui/impl-trait/issues/issue-89312.rs +++ b/tests/ui/impl-trait/issues/issue-89312.rs @@ -2,23 +2,21 @@ //@ check-pass -mod helper { - pub trait T { - type Item; - } - - pub type Alias<'a> = impl T; - - struct S; - impl<'a> T for &'a S { - type Item = &'a (); - } - - pub fn filter_positive<'a>() -> Alias<'a> { - &S - } +pub trait T { + type Item; +} + +pub type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S { + type Item = &'a (); +} + +#[define_opaque(Alias)] +pub fn filter_positive<'a>() -> Alias<'a> { + &S } -use helper::*; fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); diff --git a/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs b/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs index b05579f21662..e19230b44b40 100644 --- a/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs +++ b/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs @@ -21,6 +21,7 @@ trait Bar { type Other; } +#[define_opaque(Tait)] fn tait() -> Tait {} fn main() {} diff --git a/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.rs b/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.rs index 2a2be6b74299..21ca558153de 100644 --- a/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.rs +++ b/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.rs @@ -7,6 +7,7 @@ impl Copy for CopyIfEq {} type E<'a, 'b> = impl Sized; +#[define_opaque(E)] fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { let v = CopyIfEq::<*mut _, *mut _>(&mut { x }, &mut y); diff --git a/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr b/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr index b968592beffd..712cbbecd74b 100644 --- a/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr +++ b/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr @@ -1,9 +1,9 @@ error[E0700]: hidden type for `E<'b, 'c>` captures lifetime that does not appear in bounds - --> $DIR/error-handling-2.rs:22:5 + --> $DIR/error-handling-2.rs:23:5 | LL | type E<'a, 'b> = impl Sized; | ---------- opaque type defined here -LL | +... LL | fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { | -- hidden type `*mut &'a i32` captures the lifetime `'a` as defined here ... diff --git a/tests/ui/impl-trait/multiple-lifetimes/error-handling.rs b/tests/ui/impl-trait/multiple-lifetimes/error-handling.rs index 367e7f4e6eaf..0f3b7506318b 100644 --- a/tests/ui/impl-trait/multiple-lifetimes/error-handling.rs +++ b/tests/ui/impl-trait/multiple-lifetimes/error-handling.rs @@ -7,6 +7,7 @@ impl Copy for CopyIfEq {} type E<'a, 'b> = impl Sized; +#[define_opaque(E)] fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { let v = CopyIfEq::<*mut _, *mut _>(&mut { x }, &mut y); diff --git a/tests/ui/impl-trait/multiple-lifetimes/error-handling.stderr b/tests/ui/impl-trait/multiple-lifetimes/error-handling.stderr index 945fb0fc618f..3732307ca354 100644 --- a/tests/ui/impl-trait/multiple-lifetimes/error-handling.stderr +++ b/tests/ui/impl-trait/multiple-lifetimes/error-handling.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/error-handling.rs:20:16 + --> $DIR/error-handling.rs:21:16 | LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { | -- -- lifetime `'b` defined here diff --git a/tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs b/tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs index 6f90160866ba..6a1cb61b8ba2 100644 --- a/tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs +++ b/tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs @@ -10,6 +10,7 @@ impl Trait<'_, '_> for T {} type Foo<'a, 'b> = impl Trait<'a, 'b>; +#[define_opaque(Foo)] fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> { // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like // diff --git a/tests/ui/impl-trait/negative-reasoning.rs b/tests/ui/impl-trait/negative-reasoning.rs index 0474dc0beda6..0d4a1ba75d8c 100644 --- a/tests/ui/impl-trait/negative-reasoning.rs +++ b/tests/ui/impl-trait/negative-reasoning.rs @@ -5,6 +5,7 @@ trait OpaqueTrait {} impl OpaqueTrait for T {} type OpaqueType = impl OpaqueTrait; +#[define_opaque(OpaqueType)] fn mk_opaque() -> OpaqueType { () } diff --git a/tests/ui/impl-trait/negative-reasoning.stderr b/tests/ui/impl-trait/negative-reasoning.stderr index 631784c817b8..2918be5135ce 100644 --- a/tests/ui/impl-trait/negative-reasoning.stderr +++ b/tests/ui/impl-trait/negative-reasoning.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` - --> $DIR/negative-reasoning.rs:19:1 + --> $DIR/negative-reasoning.rs:20:1 | LL | impl AnotherTrait for T {} | ------------------------------------------- first implementation here diff --git a/tests/ui/impl-trait/nested-return-type2-tait.rs b/tests/ui/impl-trait/nested-return-type2-tait.rs index 7cb98cfe0601..aa871df9d9c5 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait.rs +++ b/tests/ui/impl-trait/nested-return-type2-tait.rs @@ -25,10 +25,10 @@ type Sendable = impl Send; // the hidden type. We already have obligations registered on the inference // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque // type does not implement `Duh`, but if its hidden type does. +#[define_opaque(Sendable)] fn foo() -> impl Trait { //~^ WARN opaque type `impl Trait` does not satisfy its associated type bounds || 42 } -fn main() { -} +fn main() {} diff --git a/tests/ui/impl-trait/nested-return-type2-tait.stderr b/tests/ui/impl-trait/nested-return-type2-tait.stderr index 4383e8ab3a0c..8105990eac4a 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait.stderr +++ b/tests/ui/impl-trait/nested-return-type2-tait.stderr @@ -1,5 +1,5 @@ warning: opaque type `impl Trait` does not satisfy its associated type bounds - --> $DIR/nested-return-type2-tait.rs:28:24 + --> $DIR/nested-return-type2-tait.rs:29:24 | LL | type Assoc: Duh; | --- this associated type bound is unsatisfied for `Sendable` diff --git a/tests/ui/impl-trait/nested-return-type2-tait2.rs b/tests/ui/impl-trait/nested-return-type2-tait2.rs index 574602079d43..bd89dad7dfd6 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait2.rs +++ b/tests/ui/impl-trait/nested-return-type2-tait2.rs @@ -26,9 +26,9 @@ type Traitable = impl Trait; // the hidden type. We already have obligations registered on the inference // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque // type does not implement `Duh`, even if its hidden type does. So we error out. +#[define_opaque(Traitable)] fn foo() -> Traitable { || 42 } -fn main() { -} +fn main() {} diff --git a/tests/ui/impl-trait/nested-return-type2-tait3.rs b/tests/ui/impl-trait/nested-return-type2-tait3.rs index e34297317825..83bf441181a4 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait3.rs +++ b/tests/ui/impl-trait/nested-return-type2-tait3.rs @@ -25,9 +25,9 @@ type Traitable = impl Trait; // the hidden type. We already have obligations registered on the inference // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque // type does not implement `Duh`, even if its hidden type does. So we error out. +#[define_opaque(Traitable)] fn foo() -> Traitable { || 42 } -fn main() { -} +fn main() {} diff --git a/tests/ui/impl-trait/nested-return-type3-tait.rs b/tests/ui/impl-trait/nested-return-type3-tait.rs index 05759fb26979..fb2e4d875435 100644 --- a/tests/ui/impl-trait/nested-return-type3-tait.rs +++ b/tests/ui/impl-trait/nested-return-type3-tait.rs @@ -16,10 +16,10 @@ impl Trait for F { type Sendable = impl Send; +#[define_opaque(Sendable)] fn foo() -> impl Trait { //~^ WARN opaque type `impl Trait` does not satisfy its associated type bounds 42 } -fn main() { -} +fn main() {} diff --git a/tests/ui/impl-trait/nested-return-type3-tait.stderr b/tests/ui/impl-trait/nested-return-type3-tait.stderr index d32944a0d721..bb1f524b9925 100644 --- a/tests/ui/impl-trait/nested-return-type3-tait.stderr +++ b/tests/ui/impl-trait/nested-return-type3-tait.stderr @@ -1,5 +1,5 @@ warning: opaque type `impl Trait` does not satisfy its associated type bounds - --> $DIR/nested-return-type3-tait.rs:19:24 + --> $DIR/nested-return-type3-tait.rs:20:24 | LL | type Assoc: Duh; | --- this associated type bound is unsatisfied for `Sendable` diff --git a/tests/ui/impl-trait/nested-return-type3-tait2.rs b/tests/ui/impl-trait/nested-return-type3-tait2.rs index 927fa8d596b9..f3fda61e9207 100644 --- a/tests/ui/impl-trait/nested-return-type3-tait2.rs +++ b/tests/ui/impl-trait/nested-return-type3-tait2.rs @@ -18,9 +18,9 @@ type Sendable = impl Send; type Traitable = impl Trait; //~^ WARN opaque type `Traitable` does not satisfy its associated type bounds +#[define_opaque(Traitable)] fn foo() -> Traitable { 42 } -fn main() { -} +fn main() {} diff --git a/tests/ui/impl-trait/nested-return-type3-tait3.rs b/tests/ui/impl-trait/nested-return-type3-tait3.rs index 5b3b2d2e1986..d2acee9cafd3 100644 --- a/tests/ui/impl-trait/nested-return-type3-tait3.rs +++ b/tests/ui/impl-trait/nested-return-type3-tait3.rs @@ -17,9 +17,9 @@ impl Trait for F { type Traitable = impl Trait; //~^ WARN opaque type `Traitable` does not satisfy its associated type bounds +#[define_opaque(Traitable)] fn foo() -> Traitable { 42 } -fn main() { -} +fn main() {} diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index c6cd1b139c5b..d4ba9a311702 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -17,6 +17,14 @@ note: `Fn` can't be used with `~const` because it isn't annotated with `#[const_ --> $SRC_DIR/core/src/ops/function.rs:LL:COL = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: unconstrained opaque type + --> $DIR/normalize-tait-in-const.rs:14:26 + | +LL | pub type Alias<'a> = impl T; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Alias` must be used in combination with a concrete type within the same crate + error[E0015]: cannot call non-const closure in constant functions --> $DIR/normalize-tait-in-const.rs:28:5 | @@ -25,6 +33,26 @@ LL | fun(filter_positive()); | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 3 previous errors +error[E0308]: mismatched types + --> $DIR/normalize-tait-in-const.rs:22:9 + | +LL | pub type Alias<'a> = impl T; + | --------------------- the expected opaque type +... +LL | pub const fn filter_positive<'a>() -> &'a Alias<'a> { + | ------------- expected `&'a foo::Alias<'a>` because of return type +LL | &&S + | ^^^ expected `&Alias<'_>`, found `&&S` + | + = note: expected reference `&'a foo::Alias<'a>` + found reference `&&S` +note: this item must have a `#[define_opaque(foo::Alias)]` attribute to be able to define hidden types + --> $DIR/normalize-tait-in-const.rs:21:18 + | +LL | pub const fn filter_positive<'a>() -> &'a Alias<'a> { + | ^^^^^^^^^^^^^^^ -For more information about this error, try `rustc --explain E0015`. +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0015, E0308. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs index 0b29af5df5b5..662c7ee2ecf0 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs @@ -2,14 +2,12 @@ //@ check-pass -mod foo { - pub type Foo = impl PartialEq<(Foo, i32)>; +pub type Foo = impl PartialEq<(Foo, i32)>; - fn foo() -> Foo { - super::Bar - } +#[define_opaque(Foo)] +fn foo() -> Foo { + Bar } -use foo::Foo; struct Bar; diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs index 3f41c5984b41..5b9c40ecedea 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs @@ -6,6 +6,7 @@ mod a { struct Bar; impl PartialEq<(Bar, i32)> for Bar { + #[define_opaque(Foo)] fn eq(&self, _other: &(Foo, i32)) -> bool { //~^ ERROR: `eq` has an incompatible type for trait //~| ERROR: item does not constrain `a::Foo::{opaque#0}` diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr index 767bd312407a..7f642fa1bedf 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -1,5 +1,5 @@ error[E0053]: method `eq` has an incompatible type for trait - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:9:30 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:30 | LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the found opaque type @@ -15,21 +15,21 @@ LL - fn eq(&self, _other: &(Foo, i32)) -> bool { LL + fn eq(&self, _other: &(a::Bar, i32)) -> bool { | -error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:9:12 +error: item does not constrain `a::Foo::{opaque#0}` + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12 | LL | fn eq(&self, _other: &(Foo, i32)) -> bool { | ^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16 | LL | type Foo = impl PartialEq<(Foo, i32)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0053]: method `eq` has an incompatible type for trait - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:30 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:30 | LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the expected opaque type @@ -39,8 +39,8 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | = note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _` found signature `fn(&b::Bar, &(b::Bar, _)) -> _` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:12 +note: this item must have a `#[define_opaque(b::Foo)]` attribute to be able to define hidden types + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:12 | LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | ^^ @@ -51,12 +51,12 @@ LL + fn eq(&self, _other: &(b::Foo, i32)) -> bool { | error: unconstrained opaque type - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16 | LL | type Foo = impl PartialEq<(Foo, i32)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `Foo` must be used in combination with a concrete type within the same module + = note: `Foo` must be used in combination with a concrete type within the same crate error: aborting due to 4 previous errors diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs index aab10be2de27..372a095192bc 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs @@ -10,6 +10,7 @@ impl PartialEq<(Bar, i32)> for Bar { } } +#[define_opaque(Foo)] fn foo() -> Foo { //~^ ERROR can't compare `Bar` with `(Foo, i32)` Bar diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr index bc810c0f88f3..a9a5483caa9d 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `Bar` with `(Foo, i32)` - --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13 + --> $DIR/recursive-type-alias-impl-trait-declaration.rs:14:13 | LL | fn foo() -> Foo { | ^^^ no implementation for `Bar == (Foo, i32)` diff --git a/tests/ui/impl-trait/two_tait_defining_each_other.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other.current.stderr index bf194f997b4a..8845b3ff2c82 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other.current.stderr +++ b/tests/ui/impl-trait/two_tait_defining_each_other.current.stderr @@ -1,5 +1,5 @@ error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/two_tait_defining_each_other.rs:17:5 + --> $DIR/two_tait_defining_each_other.rs:18:5 | LL | x // A's hidden type is `Bar`, because all the hidden types of `B` are compared with each other | ^ one of the two opaque types used here has to be outside its defining scope diff --git a/tests/ui/impl-trait/two_tait_defining_each_other.rs b/tests/ui/impl-trait/two_tait_defining_each_other.rs index ebfe7f674be0..d3038688eee1 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other.rs @@ -10,6 +10,7 @@ type B = impl Foo; trait Foo {} +#[define_opaque(A, B)] fn muh(x: A) -> B { if false { return Bar; // B's hidden type is Bar diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr index 7d02a0606fc2..0711af1cad40 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr @@ -1,18 +1,18 @@ -error: item does not constrain `A::{opaque#0}`, but has it in its signature - --> $DIR/two_tait_defining_each_other2.rs:11:4 +error: item does not constrain `A::{opaque#0}` + --> $DIR/two_tait_defining_each_other2.rs:12:4 | LL | fn muh(x: A) -> B { | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/two_tait_defining_each_other2.rs:6:10 | LL | type A = impl Foo; | ^^^^^^^^ error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/two_tait_defining_each_other2.rs:14:5 + --> $DIR/two_tait_defining_each_other2.rs:15:5 | LL | x // B's hidden type is A (opaquely) | ^ one of the two opaque types used here has to be outside its defining scope diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr index 5316160125bf..1a4c0f5f7eef 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr @@ -1,5 +1,5 @@ error[E0284]: type annotations needed: cannot satisfy `_ == A` - --> $DIR/two_tait_defining_each_other2.rs:11:8 + --> $DIR/two_tait_defining_each_other2.rs:12:8 | LL | fn muh(x: A) -> B { | ^ cannot satisfy `_ == A` diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs index 1681b019418e..a3223b07a7ed 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs @@ -8,6 +8,7 @@ type B = impl Foo; trait Foo {} +#[define_opaque(A, B)] fn muh(x: A) -> B { //[current]~^ ERROR: item does not constrain `A::{opaque#0}` //[next]~^^ ERROR: cannot satisfy `_ == A` diff --git a/tests/ui/impl-trait/two_tait_defining_each_other3.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other3.current.stderr index fa353a775360..7b0003ff59b1 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other3.current.stderr +++ b/tests/ui/impl-trait/two_tait_defining_each_other3.current.stderr @@ -1,5 +1,5 @@ error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/two_tait_defining_each_other3.rs:14:16 + --> $DIR/two_tait_defining_each_other3.rs:15:16 | LL | return x; // B's hidden type is A (opaquely) | ^ one of the two opaque types used here has to be outside its defining scope diff --git a/tests/ui/impl-trait/two_tait_defining_each_other3.rs b/tests/ui/impl-trait/two_tait_defining_each_other3.rs index 33695d8ed803..ec3cd58a3a57 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other3.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other3.rs @@ -9,6 +9,7 @@ type B = impl Foo; trait Foo {} +#[define_opaque(A, B)] fn muh(x: A) -> B { if false { return x; // B's hidden type is A (opaquely) diff --git a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs index 4879d2db40b8..77b2407e304f 100644 --- a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs +++ b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs @@ -9,6 +9,7 @@ fn main() { //~^ ERROR: item does not constrain type Existential = impl Debug; + #[define_opaque(Existential)] fn f() -> Existential {} println!("{:?}", f()); } diff --git a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr index 7744fa2f2ae6..0877b4b71bee 100644 --- a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr +++ b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr @@ -1,11 +1,11 @@ -error: item does not constrain `Existential::{opaque#0}`, but has it in its signature +error: item does not constrain `Existential::{opaque#0}` --> $DIR/type-alias-impl-trait-in-fn-body.rs:8:4 | LL | fn main() { | ^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/type-alias-impl-trait-in-fn-body.rs:10:24 | LL | type Existential = impl Debug; diff --git a/tests/ui/impl-trait/where-allowed.rs b/tests/ui/impl-trait/where-allowed.rs index 3f435f0f443b..1c3c66c537ff 100644 --- a/tests/ui/impl-trait/where-allowed.rs +++ b/tests/ui/impl-trait/where-allowed.rs @@ -157,6 +157,7 @@ extern "C" fn in_extern_fn_return() -> impl Debug { type InTypeAlias = impl Debug; //~^ ERROR `impl Trait` in type aliases is unstable +//~| ERROR unconstrained opaque type type InReturnInTypeAlias = fn() -> impl Debug; //~^ ERROR `impl Trait` is not allowed in `fn` pointer diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index ebce9b7e445b..052ae5a99315 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -37,7 +37,7 @@ LL | type InTypeAlias = impl Debug; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:161:39 + --> $DIR/where-allowed.rs:162:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | fn in_foreign_return() -> impl Debug; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `fn` pointer return types - --> $DIR/where-allowed.rs:161:39 + --> $DIR/where-allowed.rs:162:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ @@ -207,7 +207,7 @@ LL | type InReturnInTypeAlias = fn() -> impl Debug; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in traits - --> $DIR/where-allowed.rs:166:16 + --> $DIR/where-allowed.rs:167:16 | LL | impl PartialEq for () { | ^^^^^^^^^^ @@ -215,7 +215,7 @@ LL | impl PartialEq for () { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in impl headers - --> $DIR/where-allowed.rs:171:24 + --> $DIR/where-allowed.rs:172:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ @@ -223,7 +223,7 @@ LL | impl PartialEq<()> for impl Debug { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in impl headers - --> $DIR/where-allowed.rs:176:6 + --> $DIR/where-allowed.rs:177:6 | LL | impl impl Debug { | ^^^^^^^^^^ @@ -231,7 +231,7 @@ LL | impl impl Debug { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in impl headers - --> $DIR/where-allowed.rs:182:24 + --> $DIR/where-allowed.rs:183:24 | LL | impl InInherentImplAdt { | ^^^^^^^^^^ @@ -239,7 +239,7 @@ LL | impl InInherentImplAdt { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in bounds - --> $DIR/where-allowed.rs:188:11 + --> $DIR/where-allowed.rs:189:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ @@ -247,7 +247,7 @@ LL | where impl Debug: Debug = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in bounds - --> $DIR/where-allowed.rs:195:15 + --> $DIR/where-allowed.rs:196:15 | LL | where Vec: Debug | ^^^^^^^^^^ @@ -255,7 +255,7 @@ LL | where Vec: Debug = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in bounds - --> $DIR/where-allowed.rs:202:24 + --> $DIR/where-allowed.rs:203:24 | LL | where T: PartialEq | ^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | where T: PartialEq = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in the parameters of `Fn` trait bounds - --> $DIR/where-allowed.rs:209:17 + --> $DIR/where-allowed.rs:210:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ @@ -271,7 +271,7 @@ LL | where T: Fn(impl Debug) = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in the return type of `Fn` trait bounds - --> $DIR/where-allowed.rs:216:22 + --> $DIR/where-allowed.rs:217:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ @@ -279,7 +279,7 @@ LL | where T: Fn() -> impl Debug = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:222:40 + --> $DIR/where-allowed.rs:223:40 | LL | struct InStructGenericParamDefault(T); | ^^^^^^^^^^ @@ -287,7 +287,7 @@ LL | struct InStructGenericParamDefault(T); = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:226:36 + --> $DIR/where-allowed.rs:227:36 | LL | enum InEnumGenericParamDefault { Variant(T) } | ^^^^^^^^^^ @@ -295,7 +295,7 @@ LL | enum InEnumGenericParamDefault { Variant(T) } = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:230:38 + --> $DIR/where-allowed.rs:231:38 | LL | trait InTraitGenericParamDefault {} | ^^^^^^^^^^ @@ -303,7 +303,7 @@ LL | trait InTraitGenericParamDefault {} = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:234:41 + --> $DIR/where-allowed.rs:235:41 | LL | type InTypeAliasGenericParamDefault = T; | ^^^^^^^^^^ @@ -311,7 +311,7 @@ LL | type InTypeAliasGenericParamDefault = T; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:238:11 + --> $DIR/where-allowed.rs:239:11 | LL | impl T {} | ^^^^^^^^^^ @@ -319,7 +319,7 @@ LL | impl T {} = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:245:40 + --> $DIR/where-allowed.rs:246:40 | LL | fn in_method_generic_param_default(_: T) {} | ^^^^^^^^^^ @@ -327,7 +327,7 @@ LL | fn in_method_generic_param_default(_: T) {} = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/where-allowed.rs:251:29 + --> $DIR/where-allowed.rs:252:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ @@ -338,7 +338,7 @@ LL | let _in_local_variable: impl Fn() = || {}; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in closure return types - --> $DIR/where-allowed.rs:253:46 + --> $DIR/where-allowed.rs:254:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ @@ -369,7 +369,7 @@ LL + fn in_trait_impl_return() -> <() as DummyTrait>::Out { () } | error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:245:36 + --> $DIR/where-allowed.rs:246:36 | LL | fn in_method_generic_param_default(_: T) {} | ^^^^^^^^^^^^^^ @@ -379,7 +379,7 @@ LL | fn in_method_generic_param_default(_: T) {} = note: `#[deny(invalid_type_param_default)]` on by default error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:238:7 + --> $DIR/where-allowed.rs:239:7 | LL | impl T {} | ^^^^^^^^^^^^^^ @@ -408,7 +408,7 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:238:1 + --> $DIR/where-allowed.rs:239:1 | LL | impl T {} | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type @@ -423,13 +423,21 @@ LL | type Out = impl Debug; | = note: `Out` must be used in combination with a concrete type within the same impl -error: aborting due to 49 previous errors +error: unconstrained opaque type + --> $DIR/where-allowed.rs:158:23 + | +LL | type InTypeAlias = impl Debug; + | ^^^^^^^^^^ + | + = note: `InTypeAlias` must be used in combination with a concrete type within the same crate + +error: aborting due to 50 previous errors Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666. For more information about an error, try `rustc --explain E0053`. Future incompatibility report: Future breakage diagnostic: error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:245:36 + --> $DIR/where-allowed.rs:246:36 | LL | fn in_method_generic_param_default(_: T) {} | ^^^^^^^^^^^^^^ @@ -440,7 +448,7 @@ LL | fn in_method_generic_param_default(_: T) {} Future breakage diagnostic: error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:238:7 + --> $DIR/where-allowed.rs:239:7 | LL | impl T {} | ^^^^^^^^^^^^^^ diff --git a/tests/ui/implied-bounds/dyn-erasure-tait.rs b/tests/ui/implied-bounds/dyn-erasure-tait.rs index 4766d221d67c..1744e5293936 100644 --- a/tests/ui/implied-bounds/dyn-erasure-tait.rs +++ b/tests/ui/implied-bounds/dyn-erasure-tait.rs @@ -14,6 +14,7 @@ type T<'lt> = &'lt str; type F<'a, 'b> = impl 'static + Fn(T<'a>) -> T<'b>; +#[define_opaque(F)] fn helper<'a, 'b>(_: [&'b &'a (); 0]) -> F<'a, 'b> { |x: T<'a>| -> T<'b> { x } // this should *not* be `: 'static` } diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index b87a1d2031df..90e3c58dad71 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -18,6 +18,7 @@ type Test = Result; //~ ERROR: layout_of #[rustc_layout(debug)] type T = impl std::fmt::Debug; //~ ERROR: layout_of +#[define_opaque(T)] fn f() -> T { 0i32 } diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 80b35ff6ad49..abaa16cdefac 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -1,5 +1,5 @@ error: unions cannot have zero fields - --> $DIR/debug.rs:83:1 + --> $DIR/debug.rs:84:1 | LL | union EmptyUnion {} | ^^^^^^^^^^^^^^^^^^^ @@ -372,7 +372,7 @@ error: layout_of(V) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, } - --> $DIR/debug.rs:26:1 + --> $DIR/debug.rs:27:1 | LL | pub union V { | ^^^^^^^^^^^ @@ -398,7 +398,7 @@ error: layout_of(W) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, } - --> $DIR/debug.rs:32:1 + --> $DIR/debug.rs:33:1 | LL | pub union W { | ^^^^^^^^^^^ @@ -424,7 +424,7 @@ error: layout_of(Y) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, } - --> $DIR/debug.rs:38:1 + --> $DIR/debug.rs:39:1 | LL | pub union Y { | ^^^^^^^^^^^ @@ -450,7 +450,7 @@ error: layout_of(P1) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/debug.rs:45:1 + --> $DIR/debug.rs:46:1 | LL | union P1 { x: u32 } | ^^^^^^^^ @@ -476,7 +476,7 @@ error: layout_of(P2) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/debug.rs:49:1 + --> $DIR/debug.rs:50:1 | LL | union P2 { x: (u32, u32) } | ^^^^^^^^ @@ -502,7 +502,7 @@ error: layout_of(P3) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/debug.rs:57:1 + --> $DIR/debug.rs:58:1 | LL | union P3 { x: F32x4 } | ^^^^^^^^ @@ -528,7 +528,7 @@ error: layout_of(P4) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/debug.rs:61:1 + --> $DIR/debug.rs:62:1 | LL | union P4 { x: E } | ^^^^^^^^ @@ -559,7 +559,7 @@ error: layout_of(P5) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/debug.rs:65:1 + --> $DIR/debug.rs:66:1 | LL | union P5 { zst: [u16; 0], byte: u8 } | ^^^^^^^^ @@ -590,19 +590,19 @@ error: layout_of(MaybeUninit) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/debug.rs:68:1 + --> $DIR/debug.rs:69:1 | LL | type X = std::mem::MaybeUninit; | ^^^^^^ error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases - --> $DIR/debug.rs:71:1 + --> $DIR/debug.rs:72:1 | LL | const C: () = (); | ^^^^^^^^^^^ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/debug.rs:79:19 + --> $DIR/debug.rs:80:19 | LL | type Impossible = (str, str); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -611,19 +611,19 @@ LL | type Impossible = (str, str); = note: only the last element of a tuple may have a dynamically sized type error: the type has an unknown layout - --> $DIR/debug.rs:83:1 + --> $DIR/debug.rs:84:1 | LL | union EmptyUnion {} | ^^^^^^^^^^^^^^^^ error: the type `T` does not have a fixed layout - --> $DIR/debug.rs:89:1 + --> $DIR/debug.rs:90:1 | LL | type TooGeneric = T; | ^^^^^^^^^^^^^^^^^^ error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases - --> $DIR/debug.rs:75:5 + --> $DIR/debug.rs:76:5 | LL | const C: () = (); | ^^^^^^^^^^^ diff --git a/tests/ui/lazy-type-alias-impl-trait/branches.rs b/tests/ui/lazy-type-alias-impl-trait/branches.rs index 95239e2e341c..30f9c08a27fd 100644 --- a/tests/ui/lazy-type-alias-impl-trait/branches.rs +++ b/tests/ui/lazy-type-alias-impl-trait/branches.rs @@ -2,16 +2,14 @@ type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo(b: bool) -> Foo { - if b { - vec![42_i32] - } else { - std::iter::empty().collect() - } + if b { vec![42_i32] } else { std::iter::empty().collect() } } type Bar = impl std::fmt::Debug; +#[define_opaque(Bar)] fn bar(b: bool) -> Bar { let x: Bar = if b { vec![42_i32] diff --git a/tests/ui/lazy-type-alias-impl-trait/branches.stderr b/tests/ui/lazy-type-alias-impl-trait/branches.stderr index 9e9376227751..0cc727bc3ded 100644 --- a/tests/ui/lazy-type-alias-impl-trait/branches.stderr +++ b/tests/ui/lazy-type-alias-impl-trait/branches.stderr @@ -1,5 +1,5 @@ error[E0277]: a value of type `Bar` cannot be built from an iterator over elements of type `_` - --> $DIR/branches.rs:19:28 + --> $DIR/branches.rs:17:28 | LL | std::iter::empty().collect() | ^^^^^^^ value of type `Bar` cannot be built from `std::iter::Iterator` diff --git a/tests/ui/lazy-type-alias-impl-trait/branches2.rs b/tests/ui/lazy-type-alias-impl-trait/branches2.rs index 467400f1c244..35b76845c85b 100644 --- a/tests/ui/lazy-type-alias-impl-trait/branches2.rs +++ b/tests/ui/lazy-type-alias-impl-trait/branches2.rs @@ -4,20 +4,13 @@ type Foo = impl std::iter::FromIterator + PartialEq> + std::fmt::Debug; +#[define_opaque(Foo)] fn foo(b: bool) -> Foo { - if b { - vec![42_i32] - } else { - std::iter::empty().collect() - } + if b { vec![42_i32] } else { std::iter::empty().collect() } } fn bar(b: bool) -> impl PartialEq> + std::fmt::Debug { - if b { - vec![42_i32] - } else { - std::iter::empty().collect() - } + if b { vec![42_i32] } else { std::iter::empty().collect() } } fn main() { diff --git a/tests/ui/lazy-type-alias-impl-trait/branches3.rs b/tests/ui/lazy-type-alias-impl-trait/branches3.rs index 30c0af8a5dc9..cff7a0b437f6 100644 --- a/tests/ui/lazy-type-alias-impl-trait/branches3.rs +++ b/tests/ui/lazy-type-alias-impl-trait/branches3.rs @@ -3,6 +3,7 @@ type Foo = impl for<'a> FnOnce(&'a str) -> usize; type Bar = impl FnOnce(&'static str) -> usize; +#[define_opaque(Foo)] fn foo() -> Foo { if true { |s| s.len() //~ ERROR type annotations needed @@ -10,6 +11,8 @@ fn foo() -> Foo { panic!() } } + +#[define_opaque(Bar)] fn bar() -> Bar { if true { |s| s.len() //~ ERROR type annotations needed diff --git a/tests/ui/lazy-type-alias-impl-trait/branches3.stderr b/tests/ui/lazy-type-alias-impl-trait/branches3.stderr index fe2631f94742..117d189867bd 100644 --- a/tests/ui/lazy-type-alias-impl-trait/branches3.stderr +++ b/tests/ui/lazy-type-alias-impl-trait/branches3.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/branches3.rs:8:10 + --> $DIR/branches3.rs:9:10 | LL | |s| s.len() | ^ - type must be known at this point @@ -10,7 +10,7 @@ LL | |s: /* Type */| s.len() | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/branches3.rs:15:10 + --> $DIR/branches3.rs:18:10 | LL | |s| s.len() | ^ - type must be known at this point @@ -21,7 +21,7 @@ LL | |s: /* Type */| s.len() | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/branches3.rs:23:10 + --> $DIR/branches3.rs:26:10 | LL | |s| s.len() | ^ - type must be known at this point @@ -32,7 +32,7 @@ LL | |s: /* Type */| s.len() | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/branches3.rs:30:10 + --> $DIR/branches3.rs:33:10 | LL | |s| s.len() | ^ - type must be known at this point diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion.rs b/tests/ui/lazy-type-alias-impl-trait/recursion.rs index 519335605990..33dbf8d0280b 100644 --- a/tests/ui/lazy-type-alias-impl-trait/recursion.rs +++ b/tests/ui/lazy-type-alias-impl-trait/recursion.rs @@ -4,9 +4,10 @@ type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo(b: bool) -> Foo { if b { - return 42 + return 42; } let x: u32 = foo(false); 99 @@ -14,7 +15,7 @@ fn foo(b: bool) -> Foo { fn bar(b: bool) -> impl std::fmt::Debug { if b { - return 42 + return 42; } let x: u32 = bar(false); 99 diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion2.rs b/tests/ui/lazy-type-alias-impl-trait/recursion2.rs index e14da32e1166..b28a95c53f48 100644 --- a/tests/ui/lazy-type-alias-impl-trait/recursion2.rs +++ b/tests/ui/lazy-type-alias-impl-trait/recursion2.rs @@ -4,6 +4,7 @@ type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo(b: bool) -> Foo { if b { return vec![]; @@ -14,7 +15,7 @@ fn foo(b: bool) -> Foo { fn bar(b: bool) -> impl std::fmt::Debug { if b { - return vec![] + return vec![]; } let x: Vec = bar(false); std::iter::empty().collect() diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion3.rs b/tests/ui/lazy-type-alias-impl-trait/recursion3.rs index 7f1cedae068f..0b15484f7ef5 100644 --- a/tests/ui/lazy-type-alias-impl-trait/recursion3.rs +++ b/tests/ui/lazy-type-alias-impl-trait/recursion3.rs @@ -2,9 +2,10 @@ type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo(b: bool) -> Foo { if b { - return 42 + return 42; } let x: u32 = foo(false) + 42; //~ ERROR cannot add 99 @@ -12,7 +13,7 @@ fn foo(b: bool) -> Foo { fn bar(b: bool) -> impl std::fmt::Debug { if b { - return 42 + return 42; } let x: u32 = bar(false) + 42; //~ ERROR cannot add 99 diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion3.stderr b/tests/ui/lazy-type-alias-impl-trait/recursion3.stderr index e1d5cafedc80..0cbedfb69f85 100644 --- a/tests/ui/lazy-type-alias-impl-trait/recursion3.stderr +++ b/tests/ui/lazy-type-alias-impl-trait/recursion3.stderr @@ -1,5 +1,5 @@ error[E0369]: cannot add `{integer}` to `Foo` - --> $DIR/recursion3.rs:9:29 + --> $DIR/recursion3.rs:10:29 | LL | let x: u32 = foo(false) + 42; | ---------- ^ -- {integer} @@ -7,7 +7,7 @@ LL | let x: u32 = foo(false) + 42; | Foo error[E0369]: cannot add `{integer}` to `impl Debug` - --> $DIR/recursion3.rs:17:29 + --> $DIR/recursion3.rs:18:29 | LL | let x: u32 = bar(false) + 42; | ---------- ^ -- {integer} diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion4.rs b/tests/ui/lazy-type-alias-impl-trait/recursion4.rs index 57dd7fb067c6..892e72e23358 100644 --- a/tests/ui/lazy-type-alias-impl-trait/recursion4.rs +++ b/tests/ui/lazy-type-alias-impl-trait/recursion4.rs @@ -2,6 +2,7 @@ type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo(b: bool) -> Foo { if b { return vec![]; diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion4.stderr b/tests/ui/lazy-type-alias-impl-trait/recursion4.stderr index d8ac39a4f27a..b04bf6b99877 100644 --- a/tests/ui/lazy-type-alias-impl-trait/recursion4.stderr +++ b/tests/ui/lazy-type-alias-impl-trait/recursion4.stderr @@ -1,5 +1,5 @@ error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_` - --> $DIR/recursion4.rs:10:28 + --> $DIR/recursion4.rs:11:28 | LL | x = std::iter::empty().collect(); | ^^^^^^^ value of type `Foo` cannot be built from `std::iter::Iterator` @@ -9,7 +9,7 @@ note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0277]: a value of type `impl Debug` cannot be built from an iterator over elements of type `_` - --> $DIR/recursion4.rs:19:28 + --> $DIR/recursion4.rs:20:28 | LL | x = std::iter::empty().collect(); | ^^^^^^^ value of type `impl Debug` cannot be built from `std::iter::Iterator` diff --git a/tests/ui/lint/issue-99387.rs b/tests/ui/lint/issue-99387.rs index 6f0822394564..b40d31384bed 100644 --- a/tests/ui/lint/issue-99387.rs +++ b/tests/ui/lint/issue-99387.rs @@ -6,6 +6,7 @@ pub type Successors<'a> = impl Iterator; +#[define_opaque(Successors)] pub fn f<'a>() -> Successors<'a> { None.into_iter() } diff --git a/tests/ui/lint/issue-99387.stderr b/tests/ui/lint/issue-99387.stderr index 4eee4f363929..0d9ded23c784 100644 --- a/tests/ui/lint/issue-99387.stderr +++ b/tests/ui/lint/issue-99387.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-99387.rs:22:5 + --> $DIR/issue-99387.rs:23:5 | LL | pub type Successors<'a> = impl Iterator; | ---------------------------- the expected opaque type @@ -11,8 +11,8 @@ LL | None.into_iter() | = note: expected opaque type `Successors<'a>` found struct `std::option::IntoIter<_>` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/issue-99387.rs:21:8 +note: this item must have a `#[define_opaque(Successors)]` attribute to be able to define hidden types + --> $DIR/issue-99387.rs:22:8 | LL | pub fn ohno<'a>() -> <&'a () as Tr>::Item { | ^^^^ diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.rs b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs index 84abb933911f..9782b3191fd6 100644 --- a/tests/ui/lint/let_underscore/issue-119697-extra-let.rs +++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs @@ -8,6 +8,7 @@ pub struct Foo { pub type Tait = impl Sized; +#[define_opaque(Tait)] pub fn ice_cold(beverage: Tait) { // Must destructure at least one field of `Foo` let Foo { field } = beverage; @@ -17,5 +18,4 @@ pub fn ice_cold(beverage: Tait) { let _ = field; //~ ERROR non-binding let on a type that has a destructor } - pub fn main() {} diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr index 3ff57ab441dc..8d5deadd46e2 100644 --- a/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr +++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr @@ -1,5 +1,5 @@ error: non-binding let on a type that has a destructor - --> $DIR/issue-119697-extra-let.rs:15:5 + --> $DIR/issue-119697-extra-let.rs:16:5 | LL | _ = field; | ^^^^^^^^^ @@ -21,7 +21,7 @@ LL + drop(field); | error: non-binding let on a type that has a destructor - --> $DIR/issue-119697-extra-let.rs:17:5 + --> $DIR/issue-119697-extra-let.rs:18:5 | LL | let _ = field; | ^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/lint-ctypes-73249-2.rs b/tests/ui/lint/lint-ctypes-73249-2.rs index f30377d6c16e..31af0e3d381e 100644 --- a/tests/ui/lint/lint-ctypes-73249-2.rs +++ b/tests/ui/lint/lint-ctypes-73249-2.rs @@ -7,6 +7,7 @@ impl Baz for () {} type Qux = impl Baz; +#[define_opaque(Qux)] fn assign() -> Qux {} trait Foo { diff --git a/tests/ui/lint/lint-ctypes-73249-2.stderr b/tests/ui/lint/lint-ctypes-73249-2.stderr index ef30a406969d..2d0dfe94f097 100644 --- a/tests/ui/lint/lint-ctypes-73249-2.stderr +++ b/tests/ui/lint/lint-ctypes-73249-2.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `Qux`, which is not FFI-safe - --> $DIR/lint-ctypes-73249-2.rs:26:21 + --> $DIR/lint-ctypes-73249-2.rs:27:21 | LL | fn lint_me() -> A<()>; | ^^^^^ not FFI-safe diff --git a/tests/ui/lint/lint-ctypes-73249-3.rs b/tests/ui/lint/lint-ctypes-73249-3.rs index ef8ab7e03d2f..8bdf536bf77e 100644 --- a/tests/ui/lint/lint-ctypes-73249-3.rs +++ b/tests/ui/lint/lint-ctypes-73249-3.rs @@ -7,6 +7,7 @@ impl Baz for u32 {} type Qux = impl Baz; +#[define_opaque(Qux)] fn assign() -> Qux { 3 } diff --git a/tests/ui/lint/lint-ctypes-73249-3.stderr b/tests/ui/lint/lint-ctypes-73249-3.stderr index e5607ba72e97..e1a313a29065 100644 --- a/tests/ui/lint/lint-ctypes-73249-3.stderr +++ b/tests/ui/lint/lint-ctypes-73249-3.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `Qux`, which is not FFI-safe - --> $DIR/lint-ctypes-73249-3.rs:20:25 + --> $DIR/lint-ctypes-73249-3.rs:21:25 | LL | pub fn lint_me() -> A; | ^ not FFI-safe diff --git a/tests/ui/lint/lint-ctypes-73249-5.rs b/tests/ui/lint/lint-ctypes-73249-5.rs index 083fb6c5fb16..cc6da59950d7 100644 --- a/tests/ui/lint/lint-ctypes-73249-5.rs +++ b/tests/ui/lint/lint-ctypes-73249-5.rs @@ -7,6 +7,7 @@ impl Baz for u32 {} type Qux = impl Baz; +#[define_opaque(Qux)] fn assign() -> Qux { 3 } diff --git a/tests/ui/lint/lint-ctypes-73249-5.stderr b/tests/ui/lint/lint-ctypes-73249-5.stderr index fcb106c485d8..c4fa955de05e 100644 --- a/tests/ui/lint/lint-ctypes-73249-5.stderr +++ b/tests/ui/lint/lint-ctypes-73249-5.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `Qux`, which is not FFI-safe - --> $DIR/lint-ctypes-73249-5.rs:20:25 + --> $DIR/lint-ctypes-73249-5.rs:21:25 | LL | pub fn lint_me() -> A; | ^ not FFI-safe diff --git a/tests/ui/lint/lint-ctypes-73251-1.rs b/tests/ui/lint/lint-ctypes-73251-1.rs index fc11f23a1049..07ae05be69f6 100644 --- a/tests/ui/lint/lint-ctypes-73251-1.rs +++ b/tests/ui/lint/lint-ctypes-73251-1.rs @@ -15,6 +15,7 @@ impl Foo for u32 { type Assoc = Qux; } +#[define_opaque(Qux)] fn assign() -> Qux { 1 } diff --git a/tests/ui/lint/lint-ctypes-73251-1.stderr b/tests/ui/lint/lint-ctypes-73251-1.stderr index a3b3ebaac303..675a9de51cd0 100644 --- a/tests/ui/lint/lint-ctypes-73251-1.stderr +++ b/tests/ui/lint/lint-ctypes-73251-1.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `Qux`, which is not FFI-safe - --> $DIR/lint-ctypes-73251-1.rs:23:21 + --> $DIR/lint-ctypes-73251-1.rs:24:21 | LL | fn lint_me() -> ::Assoc; | ^^^^^^^^^^^^^^^^^^^ not FFI-safe diff --git a/tests/ui/lint/lint-ctypes-73251-2.rs b/tests/ui/lint/lint-ctypes-73251-2.rs index fbe0a58f3b5b..c47118672e07 100644 --- a/tests/ui/lint/lint-ctypes-73251-2.rs +++ b/tests/ui/lint/lint-ctypes-73251-2.rs @@ -24,10 +24,12 @@ type AliasA = impl TraitA; type AliasB = impl TraitB; +#[define_opaque(AliasA)] fn use_of_a() -> AliasA { 3 } +#[define_opaque(AliasB)] fn use_of_b() -> AliasB { 3 } diff --git a/tests/ui/lint/lint-ctypes-73251-2.stderr b/tests/ui/lint/lint-ctypes-73251-2.stderr index 40a9cd00c50f..634950b29ed4 100644 --- a/tests/ui/lint/lint-ctypes-73251-2.stderr +++ b/tests/ui/lint/lint-ctypes-73251-2.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `AliasA`, which is not FFI-safe - --> $DIR/lint-ctypes-73251-2.rs:36:21 + --> $DIR/lint-ctypes-73251-2.rs:38:21 | LL | fn lint_me() -> ::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe diff --git a/tests/ui/lint/lint-ctypes-73251.rs b/tests/ui/lint/lint-ctypes-73251.rs index 68eeb67deeae..15c1dfcaabf5 100644 --- a/tests/ui/lint/lint-ctypes-73251.rs +++ b/tests/ui/lint/lint-ctypes-73251.rs @@ -13,6 +13,7 @@ impl Foo for () { type Bar = impl Foo; +#[define_opaque(Bar)] fn assign() -> Bar {} extern "C" { diff --git a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs index c83bca4a4c57..dee77cf48738 100644 --- a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs +++ b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs @@ -25,10 +25,12 @@ type AliasA = impl TraitA; type AliasB = impl TraitB; +#[define_opaque(AliasA)] fn use_of_a() -> AliasA { 3 } +#[define_opaque(AliasB)] fn use_of_b() -> AliasB { 3 } diff --git a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr index 9efc187833f0..020eac4febb8 100644 --- a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr +++ b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `AliasB`, which is not FFI-safe - --> $DIR/opaque-ty-ffi-normalization-cycle.rs:37:21 + --> $DIR/opaque-ty-ffi-normalization-cycle.rs:39:21 | LL | fn lint_me() -> ::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe diff --git a/tests/ui/lint/opaque-ty-ffi-unsafe.rs b/tests/ui/lint/opaque-ty-ffi-unsafe.rs index 5faeac9ed4c3..97016267fa87 100644 --- a/tests/ui/lint/opaque-ty-ffi-unsafe.rs +++ b/tests/ui/lint/opaque-ty-ffi-unsafe.rs @@ -3,6 +3,7 @@ type A = impl Fn(); +#[define_opaque(A)] pub(crate) fn ret_closure() -> A { || {} } diff --git a/tests/ui/lint/opaque-ty-ffi-unsafe.stderr b/tests/ui/lint/opaque-ty-ffi-unsafe.stderr index 7f5d1792bf12..5c52f7026714 100644 --- a/tests/ui/lint/opaque-ty-ffi-unsafe.stderr +++ b/tests/ui/lint/opaque-ty-ffi-unsafe.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `A`, which is not FFI-safe - --> $DIR/opaque-ty-ffi-unsafe.rs:11:24 + --> $DIR/opaque-ty-ffi-unsafe.rs:12:24 | LL | pub(crate) fn a(_: A); | ^ not FFI-safe diff --git a/tests/ui/methods/opaque_param_in_ufc.rs b/tests/ui/methods/opaque_param_in_ufc.rs index b170e6805f64..3b0c8b778ffc 100644 --- a/tests/ui/methods/opaque_param_in_ufc.rs +++ b/tests/ui/methods/opaque_param_in_ufc.rs @@ -11,11 +11,13 @@ impl Foo { type Bar = impl Sized; +#[define_opaque(Bar)] fn bar() -> Bar { 42_u32 } impl Foo { + #[define_opaque(Bar)] fn foo() -> Bar { Self::method(); Foo::::method(); diff --git a/tests/ui/mir/issue-75053.rs b/tests/ui/mir/issue-75053.rs index 38684f3548f2..9b247fa54349 100644 --- a/tests/ui/mir/issue-75053.rs +++ b/tests/ui/mir/issue-75053.rs @@ -13,13 +13,11 @@ trait MyFrom: Sized { fn my_from(value: T) -> Result; } -mod f { - pub trait F {} - impl F for () {} - pub type DummyT = impl F; - fn _dummy_t() -> DummyT {} -} -use f::*; +pub trait F {} +impl F for () {} +pub type DummyT = impl F; +#[define_opaque(DummyT)] +fn _dummy_t() -> DummyT {} struct Phantom1(PhantomData); struct Phantom2(PhantomData); diff --git a/tests/ui/mir/issue-75053.stderr b/tests/ui/mir/issue-75053.stderr index a464d3266f4e..91032bc3797e 100644 --- a/tests/ui/mir/issue-75053.stderr +++ b/tests/ui/mir/issue-75053.stderr @@ -1,5 +1,5 @@ error: fatal error triggered by #[rustc_error] - --> $DIR/issue-75053.rs:49:1 + --> $DIR/issue-75053.rs:47:1 | LL | fn main() { | ^^^^^^^^^ diff --git a/tests/ui/never_type/impl_trait_fallback2.rs b/tests/ui/never_type/impl_trait_fallback2.rs index 12c187b9e82a..399bd72561b4 100644 --- a/tests/ui/never_type/impl_trait_fallback2.rs +++ b/tests/ui/never_type/impl_trait_fallback2.rs @@ -12,11 +12,13 @@ fn should_ret_unit() -> impl T { type Foo = impl T; +#[define_opaque(Foo)] fn a() -> Foo { //~^ ERROR `(): T` is not satisfied panic!() } +#[define_opaque(Foo)] fn b() -> Foo { 42 } diff --git a/tests/ui/never_type/impl_trait_fallback2.stderr b/tests/ui/never_type/impl_trait_fallback2.stderr index 4c32dce465b8..0f197aa5cc6f 100644 --- a/tests/ui/never_type/impl_trait_fallback2.stderr +++ b/tests/ui/never_type/impl_trait_fallback2.stderr @@ -10,7 +10,7 @@ LL | panic!() = help: the trait `T` is implemented for `i32` error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/impl_trait_fallback2.rs:15:11 + --> $DIR/impl_trait_fallback2.rs:16:11 | LL | fn a() -> Foo { | ^^^ the trait `T` is not implemented for `()` diff --git a/tests/ui/never_type/impl_trait_fallback3.rs b/tests/ui/never_type/impl_trait_fallback3.rs index ed645b82394a..3740aad73f0b 100644 --- a/tests/ui/never_type/impl_trait_fallback3.rs +++ b/tests/ui/never_type/impl_trait_fallback3.rs @@ -8,6 +8,7 @@ trait T { type Foo = impl T; +#[define_opaque(Foo)] fn a() -> Foo { //~^ ERROR the trait bound `(): T` is not satisfied // This is not a defining use, it doesn't actually constrain the opaque type. diff --git a/tests/ui/never_type/impl_trait_fallback3.stderr b/tests/ui/never_type/impl_trait_fallback3.stderr index fde8d0896dda..11425a749534 100644 --- a/tests/ui/never_type/impl_trait_fallback3.stderr +++ b/tests/ui/never_type/impl_trait_fallback3.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/impl_trait_fallback3.rs:11:11 + --> $DIR/impl_trait_fallback3.rs:12:11 | LL | fn a() -> Foo { | ^^^ the trait `T` is not implemented for `()` diff --git a/tests/ui/never_type/impl_trait_fallback4.rs b/tests/ui/never_type/impl_trait_fallback4.rs index fe62773fa02d..2fa3d0028be8 100644 --- a/tests/ui/never_type/impl_trait_fallback4.rs +++ b/tests/ui/never_type/impl_trait_fallback4.rs @@ -15,6 +15,7 @@ fn foo() -> impl T { panic!() } +#[define_opaque(Foo)] fn a() -> Foo { foo() } diff --git a/tests/ui/pattern/usefulness/impl-trait.rs b/tests/ui/pattern/usefulness/impl-trait.rs index 16560a092675..47cee17b5799 100644 --- a/tests/ui/pattern/usefulness/impl-trait.rs +++ b/tests/ui/pattern/usefulness/impl-trait.rs @@ -25,6 +25,7 @@ fn friend_of_return_never_rpit(x: Void) { } type T = impl Copy; +#[define_opaque(T)] fn return_never_tait(x: Void) -> T { if false { match return_never_tait(x) { @@ -88,6 +89,7 @@ fn inner_tuple() { } type U = impl Copy; +#[define_opaque(U)] fn unify_never(x: Void, u: U) -> U { if false { match u { @@ -98,6 +100,7 @@ fn unify_never(x: Void, u: U) -> U { } type V = impl Copy; +#[define_opaque(V)] fn infer_in_match(x: Option) { match x { None => {} @@ -116,6 +119,7 @@ struct Rec<'a> { n: u32, w: Option<&'a W>, } +#[define_opaque(W)] fn recursive_opaque() -> W { if false { match recursive_opaque() { @@ -130,6 +134,7 @@ fn recursive_opaque() -> W { type X = impl Copy; struct SecretelyVoid(X); +#[define_opaque(X)] fn nested_empty_opaque(x: Void) -> X { if false { let opaque_void = nested_empty_opaque(x); @@ -143,6 +148,7 @@ fn nested_empty_opaque(x: Void) -> X { type Y = (impl Copy, impl Copy); struct SecretelyDoubleVoid(Y); +#[define_opaque(Y)] fn super_nested_empty_opaque(x: Void) -> Y { if false { let opaque_void = super_nested_empty_opaque(x); diff --git a/tests/ui/pattern/usefulness/impl-trait.stderr b/tests/ui/pattern/usefulness/impl-trait.stderr index c3e1c267b614..62045151968e 100644 --- a/tests/ui/pattern/usefulness/impl-trait.stderr +++ b/tests/ui/pattern/usefulness/impl-trait.stderr @@ -15,7 +15,7 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/impl-trait.rs:31:13 + --> $DIR/impl-trait.rs:32:13 | LL | _ => {} | ^------ @@ -25,6 +25,112 @@ LL | _ => {} | = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types +error: unreachable pattern + --> $DIR/impl-trait.rs:46:13 + | +LL | Some(_) => {} + | ^^^^^^^------ + | | + | matches no values because `Void` is uninhabited + | help: remove the match arm + | + = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types + +error: unreachable pattern + --> $DIR/impl-trait.rs:50:13 + | +LL | None => {} + | ---- matches all the relevant values +LL | _ => {} + | ^ no value can reach this + +error: unreachable pattern + --> $DIR/impl-trait.rs:60:13 + | +LL | Some(_) => {} + | ^^^^^^^------ + | | + | matches no values because `Void` is uninhabited + | help: remove the match arm + | + = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types + +error: unreachable pattern + --> $DIR/impl-trait.rs:64:13 + | +LL | None => {} + | ---- matches all the relevant values +LL | _ => {} + | ^ no value can reach this + +error: unreachable pattern + --> $DIR/impl-trait.rs:77:9 + | +LL | _ => {} + | ^------ + | | + | matches no values because `Void` is uninhabited + | help: remove the match arm + | + = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types + +error: unreachable pattern + --> $DIR/impl-trait.rs:87:9 + | +LL | _ => {} + | - matches any value +LL | Some((a, b)) => {} + | ^^^^^^^^^^^^ no value can reach this + +error: unreachable pattern + --> $DIR/impl-trait.rs:96:13 + | +LL | _ => {} + | ^------ + | | + | matches no values because `Void` is uninhabited + | help: remove the match arm + | + = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types + +error: unreachable pattern + --> $DIR/impl-trait.rs:108:9 + | +LL | Some((a, b)) => {} + | ------------ matches all the relevant values +LL | Some((mut x, mut y)) => { + | ^^^^^^^^^^^^^^^^^^^^ no value can reach this + +error: unreachable pattern + --> $DIR/impl-trait.rs:128:13 + | +LL | _ => {} + | - matches any value +LL | Rec { n: 0, w: Some(Rec { n: 0, w: _ }) } => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no value can reach this + +error: unreachable pattern + --> $DIR/impl-trait.rs:143:13 + | +LL | _ => {} + | ^------ + | | + | matches no values because `SecretelyVoid` is uninhabited + | help: remove the match arm + | + = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types + +error: unreachable pattern + --> $DIR/impl-trait.rs:157:13 + | +LL | _ => {} + | ^------ + | | + | matches no values because `SecretelyDoubleVoid` is uninhabited + | help: remove the match arm + | + = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types + error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty --> $DIR/impl-trait.rs:23:11 | @@ -39,76 +145,8 @@ LL + _ => todo!(), LL ~ } | -error: unreachable pattern - --> $DIR/impl-trait.rs:45:13 - | -LL | Some(_) => {} - | ^^^^^^^------ - | | - | matches no values because `Void` is uninhabited - | help: remove the match arm - | - = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types - -error: unreachable pattern - --> $DIR/impl-trait.rs:49:13 - | -LL | None => {} - | ---- matches all the relevant values -LL | _ => {} - | ^ no value can reach this - -error: unreachable pattern - --> $DIR/impl-trait.rs:59:13 - | -LL | Some(_) => {} - | ^^^^^^^------ - | | - | matches no values because `Void` is uninhabited - | help: remove the match arm - | - = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types - -error: unreachable pattern - --> $DIR/impl-trait.rs:63:13 - | -LL | None => {} - | ---- matches all the relevant values -LL | _ => {} - | ^ no value can reach this - -error: unreachable pattern - --> $DIR/impl-trait.rs:76:9 - | -LL | _ => {} - | ^------ - | | - | matches no values because `Void` is uninhabited - | help: remove the match arm - | - = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types - -error: unreachable pattern - --> $DIR/impl-trait.rs:86:9 - | -LL | _ => {} - | - matches any value -LL | Some((a, b)) => {} - | ^^^^^^^^^^^^ no value can reach this - -error: unreachable pattern - --> $DIR/impl-trait.rs:94:13 - | -LL | _ => {} - | ^------ - | | - | matches no values because `Void` is uninhabited - | help: remove the match arm - | - = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types - error[E0004]: non-exhaustive patterns: type `T` is non-empty - --> $DIR/impl-trait.rs:37:11 + --> $DIR/impl-trait.rs:38:11 | LL | match return_never_tait(x) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -121,44 +159,6 @@ LL + _ => todo!(), LL ~ } | -error: unreachable pattern - --> $DIR/impl-trait.rs:105:9 - | -LL | Some((a, b)) => {} - | ------------ matches all the relevant values -LL | Some((mut x, mut y)) => { - | ^^^^^^^^^^^^^^^^^^^^ no value can reach this - -error: unreachable pattern - --> $DIR/impl-trait.rs:124:13 - | -LL | _ => {} - | - matches any value -LL | Rec { n: 0, w: Some(Rec { n: 0, w: _ }) } => {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no value can reach this - -error: unreachable pattern - --> $DIR/impl-trait.rs:138:13 - | -LL | _ => {} - | ^------ - | | - | matches no values because `SecretelyVoid` is uninhabited - | help: remove the match arm - | - = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types - -error: unreachable pattern - --> $DIR/impl-trait.rs:151:13 - | -LL | _ => {} - | ^------ - | | - | matches no values because `SecretelyDoubleVoid` is uninhabited - | help: remove the match arm - | - = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types - error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs index fd0e07fb9b49..743ca650fdd4 100644 --- a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs +++ b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs @@ -8,6 +8,7 @@ pub type Pub = impl Default; #[derive(Default)] struct Priv; +#[define_opaque(Pub)] fn check() -> Pub { Priv } diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs index 34b94f2e1c78..4cf2d1ac4a6b 100644 --- a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs +++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs @@ -12,6 +12,7 @@ impl<'a, T> Trait<'a> for T { mod basic_pass { use super::*; type Opq<'a> = impl Sized + 'a; + #[define_opaque(Opq)] fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {} //~^ ERROR: expected generic lifetime parameter, found `'a` } @@ -27,6 +28,7 @@ mod capture_tait { type Opq0 = impl Sized; type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>; type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + #[define_opaque(Opq2)] fn test() -> Opq2 {} //~^ ERROR hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds } @@ -36,6 +38,7 @@ mod capture_tait_complex_pass { type Opq0<'a> = impl Sized; type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + #[define_opaque(Opq2)] fn test() -> Opq2 {} //~^ ERROR: expected generic lifetime parameter, found `'a` } @@ -46,6 +49,7 @@ mod capture_tait_complex_fail { type Opq0<'a> = impl Sized; type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + #[define_opaque(Opq2)] fn test() -> Opq2 {} //~^ ERROR hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds } @@ -54,18 +58,18 @@ mod capture_tait_complex_fail { mod constrain_fail0 { use super::*; type Opq0<'a, 'b> = impl Sized; + #[define_opaque(Opq0)] fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {} - //~^ ERROR non-defining opaque type use in defining scope - //~| ERROR: expected generic lifetime parameter, found `'a` + //~^ ERROR: expected generic lifetime parameter, found `'a` } // non-defining use because generic lifetime is used multiple times. mod constrain_fail { use super::*; type Opq0<'a, 'b> = impl Sized; + #[define_opaque(Opq0)] fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {} - //~^ ERROR non-defining opaque type use in defining scope - //~| ERROR: expected generic lifetime parameter, found `'a` + //~^ ERROR: expected generic lifetime parameter, found `'a` } mod constrain_pass { @@ -73,6 +77,7 @@ mod constrain_pass { type Opq0<'a, 'b> = impl Sized; type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>; type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + #[define_opaque(Opq2)] fn test() -> Opq2 {} //~^ ERROR: expected generic lifetime parameter, found `'a` } diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr index fb1e4cca3f40..3614fc8f45c7 100644 --- a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr +++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr @@ -1,13 +1,14 @@ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/higher-ranked-regions-basic.rs:15:55 + --> $DIR/higher-ranked-regions-basic.rs:16:55 | LL | type Opq<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter +LL | #[define_opaque(Opq)] LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {} | ^^ error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds - --> $DIR/higher-ranked-regions-basic.rs:21:58 + --> $DIR/higher-ranked-regions-basic.rs:22:58 | LL | fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {} | -- ---------- ^^ @@ -16,86 +17,64 @@ LL | fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {} | hidden type `&'a ()` captures the lifetime `'a` as defined here error[E0700]: hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds - --> $DIR/higher-ranked-regions-basic.rs:30:23 + --> $DIR/higher-ranked-regions-basic.rs:32:23 | LL | type Opq0 = impl Sized; | ---------- opaque type defined here LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>; | -- hidden type `&'b ()` captures the lifetime `'b` as defined here -LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; +... LL | fn test() -> Opq2 {} | ^^ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/higher-ranked-regions-basic.rs:39:23 + --> $DIR/higher-ranked-regions-basic.rs:42:23 | LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b | -- this generic parameter must be used with a generic lifetime parameter -LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; +... LL | fn test() -> Opq2 {} | ^^ error[E0700]: hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds - --> $DIR/higher-ranked-regions-basic.rs:49:23 + --> $DIR/higher-ranked-regions-basic.rs:53:23 | LL | type Opq0<'a> = impl Sized; | ---------- opaque type defined here LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a | -- hidden type `&'b ()` captures the lifetime `'b` as defined here -LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; +... LL | fn test() -> Opq2 {} | ^^ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/higher-ranked-regions-basic.rs:57:41 - | -LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {} - | ^^^^^^^^^^^^^^^^^^^^^^ argument `'static` is not a generic parameter - | -note: for this opaque type - --> $DIR/higher-ranked-regions-basic.rs:56:25 - | -LL | type Opq0<'a, 'b> = impl Sized; - | ^^^^^^^^^^ - error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/higher-ranked-regions-basic.rs:57:65 + --> $DIR/higher-ranked-regions-basic.rs:62:65 | LL | type Opq0<'a, 'b> = impl Sized; | -- this generic parameter must be used with a generic lifetime parameter +LL | #[define_opaque(Opq0)] LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {} | ^^ -error: non-defining opaque type use in defining scope - --> $DIR/higher-ranked-regions-basic.rs:66:41 - | -LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {} - | ^^^^^^^^^^^^^^^^^ generic argument `'a` used twice - | -note: for this opaque type - --> $DIR/higher-ranked-regions-basic.rs:65:25 - | -LL | type Opq0<'a, 'b> = impl Sized; - | ^^^^^^^^^^ - error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/higher-ranked-regions-basic.rs:66:60 + --> $DIR/higher-ranked-regions-basic.rs:71:60 | LL | type Opq0<'a, 'b> = impl Sized; | -- this generic parameter must be used with a generic lifetime parameter +LL | #[define_opaque(Opq0)] LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {} | ^^ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/higher-ranked-regions-basic.rs:76:23 + --> $DIR/higher-ranked-regions-basic.rs:81:23 | LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>; | -- this generic parameter must be used with a generic lifetime parameter -LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; +... LL | fn test() -> Opq2 {} | ^^ -error: aborting due to 10 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0700, E0792. For more information about an error, try `rustc --explain E0700`. diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs index db5e5e05e54b..e0b7909c2409 100644 --- a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs +++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs @@ -14,7 +14,10 @@ impl Trait for Struct { type Assoc<'a> = &'a u32; } -const FOO: Foo = Struct; -//~^ ERROR: expected generic lifetime parameter, found `'a` +#[define_opaque(Foo)] +fn foo() -> Foo { + Struct + //~^ ERROR: expected generic lifetime parameter, found `'a` +} fn main() {} diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr index 9b361445f1ec..b3edc9427327 100644 --- a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr +++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr @@ -1,11 +1,11 @@ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/higher-ranked-regions-gat.rs:17:18 + --> $DIR/higher-ranked-regions-gat.rs:19:5 | LL | pub type FooAssoc<'a> = impl Sized; | -- this generic parameter must be used with a generic lifetime parameter ... -LL | const FOO: Foo = Struct; - | ^^^^^^ +LL | Struct + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/self/arbitrary-self-opaque.rs b/tests/ui/self/arbitrary-self-opaque.rs index c26ef658b695..b176a982e5fc 100644 --- a/tests/ui/self/arbitrary-self-opaque.rs +++ b/tests/ui/self/arbitrary-self-opaque.rs @@ -4,6 +4,7 @@ struct Foo; type Bar = impl Sized; impl Foo { + #[define_opaque(Bar)] fn foo(self: Bar) {} //~^ ERROR: invalid `self` parameter type: `Bar` //~| ERROR: item does not constrain diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr index c75165d9f8e2..36ae3d6fd02b 100644 --- a/tests/ui/self/arbitrary-self-opaque.stderr +++ b/tests/ui/self/arbitrary-self-opaque.stderr @@ -1,5 +1,5 @@ error[E0307]: invalid `self` parameter type: `Bar` - --> $DIR/arbitrary-self-opaque.rs:7:18 + --> $DIR/arbitrary-self-opaque.rs:8:18 | LL | fn foo(self: Bar) {} | ^^^ @@ -7,14 +7,14 @@ LL | fn foo(self: Bar) {} = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error: item does not constrain `Bar::{opaque#0}`, but has it in its signature - --> $DIR/arbitrary-self-opaque.rs:7:8 +error: item does not constrain `Bar::{opaque#0}` + --> $DIR/arbitrary-self-opaque.rs:8:8 | LL | fn foo(self: Bar) {} | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/arbitrary-self-opaque.rs:4:12 | LL | type Bar = impl Sized; diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque.rs b/tests/ui/specialization/min_specialization/impl-on-opaque.rs index 7531dcaccf23..131ad8b9d65d 100644 --- a/tests/ui/specialization/min_specialization/impl-on-opaque.rs +++ b/tests/ui/specialization/min_specialization/impl-on-opaque.rs @@ -26,6 +26,7 @@ impl SpecTrait for () { fn f() {} } +#[define_opaque(Opaque)] fn foo() -> Opaque {} fn main() {} diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque2.rs b/tests/ui/specialization/min_specialization/impl-on-opaque2.rs index 0cd8be84ed37..bcdb54c2b4f7 100644 --- a/tests/ui/specialization/min_specialization/impl-on-opaque2.rs +++ b/tests/ui/specialization/min_specialization/impl-on-opaque2.rs @@ -23,6 +23,7 @@ impl SpecTrait<(), Opaque> for () { fn f() {} } +#[define_opaque(Opaque)] fn foo() -> Opaque {} fn main() {} diff --git a/tests/ui/traits/alias/issue-83613.rs b/tests/ui/traits/alias/issue-83613.rs index 6f0012bf0896..752c4b84546b 100644 --- a/tests/ui/traits/alias/issue-83613.rs +++ b/tests/ui/traits/alias/issue-83613.rs @@ -2,6 +2,7 @@ trait OpaqueTrait {} impl OpaqueTrait for T {} type OpaqueType = impl OpaqueTrait; +#[define_opaque(OpaqueType)] fn mk_opaque() -> OpaqueType { || 0 } diff --git a/tests/ui/traits/alias/issue-83613.stderr b/tests/ui/traits/alias/issue-83613.stderr index 47181c3f33ed..7d2bdd7e1863 100644 --- a/tests/ui/traits/alias/issue-83613.stderr +++ b/tests/ui/traits/alias/issue-83613.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `AnotherTrait` - --> $DIR/issue-83613.rs:10:1 + --> $DIR/issue-83613.rs:11:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here diff --git a/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs index cb9fe176ac95..92a0913dee28 100644 --- a/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs +++ b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs @@ -12,7 +12,8 @@ fn mk() -> T { todo!() } -fn a(_: Tait) { +#[define_opaque(Tait)] +fn a() { let x: Tait = mk(); let mut array = mk(); let mut z = IntoIterator::into_iter(array); diff --git a/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs index 8d92c88ae725..0e99ef87c89b 100644 --- a/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs +++ b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs @@ -28,7 +28,8 @@ goals together. Essentially: */ -fn a(_: Tait) { +#[define_opaque(Tait)] +fn a() { let _: Tait = IntoIterator::into_iter([0i32; 32]); } diff --git a/tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs b/tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs index 904bc1794959..38fcc561b32d 100644 --- a/tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs +++ b/tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs @@ -12,7 +12,8 @@ type Foo = impl NeedsSend; trait NeedsSend {} impl NeedsSend for T {} -fn define(a: A, b: B, _: Foo) { +#[define_opaque(Foo)] +fn define(a: A, b: B) { let y: Option> = Some(b); } diff --git a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr index 158fefd1538f..736c8c10da97 100644 --- a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr +++ b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr @@ -1,5 +1,5 @@ error[E0284]: type annotations needed: cannot satisfy `Foo == _` - --> $DIR/dont-type_of-tait-in-defining-scope.rs:15:18 + --> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18 | LL | needs_send::(); | ^^^ cannot satisfy `Foo == _` diff --git a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr index 158fefd1538f..736c8c10da97 100644 --- a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr +++ b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr @@ -1,5 +1,5 @@ error[E0284]: type annotations needed: cannot satisfy `Foo == _` - --> $DIR/dont-type_of-tait-in-defining-scope.rs:15:18 + --> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18 | LL | needs_send::(); | ^^^ cannot satisfy `Foo == _` diff --git a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs index 10b746cc9895..2a08a3b2b948 100644 --- a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs +++ b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs @@ -11,12 +11,14 @@ type Foo = impl Sized; fn needs_send() {} +#[define_opaque(Foo)] fn test(_: Foo) { needs_send::(); //~^ ERROR type annotations needed: cannot satisfy `Foo == _` } -fn defines(_: Foo) { +#[define_opaque(Foo)] +fn defines() { let _: Foo = (); } diff --git a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr index 9a28dc093c1b..5625cb24d426 100644 --- a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr +++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr @@ -4,31 +4,31 @@ error: unconstrained opaque type LL | type Tait1 = impl Sized; | ^^^^^^^^^^ | - = note: `Tait1` must be used in combination with a concrete type within the same module + = note: `Tait1` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/no-define-in-wf-check.rs:27:18 + --> $DIR/no-define-in-wf-check.rs:28:18 | LL | type Tait1 = impl Sized; | ^^^^^^^^^^ | - = note: `Tait1` must be used in combination with a concrete type within the same module + = note: `Tait1` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/no-define-in-wf-check.rs:36:18 + --> $DIR/no-define-in-wf-check.rs:38:18 | LL | type Tait1 = impl Sized; | ^^^^^^^^^^ | - = note: `Tait1` must be used in combination with a concrete type within the same module + = note: `Tait1` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/no-define-in-wf-check.rs:47:18 + --> $DIR/no-define-in-wf-check.rs:50:18 | LL | type Tait1 = impl Sized; | ^^^^^^^^^^ | - = note: `Tait1` must be used in combination with a concrete type within the same module + = note: `Tait1` must be used in combination with a concrete type within the same crate error: aborting due to 4 previous errors diff --git a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs index dd6df097da1b..31d07d89d8dc 100644 --- a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs +++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs @@ -18,6 +18,7 @@ mod ex0 { mod ex1 { type Tait1 = impl Sized; //[current]~^ ERROR unconstrained opaque type + #[define_opaque(Tait1)] fn foo(x: Tait1) -> impl Sized { let () = x; } @@ -27,6 +28,7 @@ mod ex2 { type Tait1 = impl Sized; //[current]~^ ERROR unconstrained opaque type type Tait2 = impl Sized; + #[define_opaque(Tait1, Tait2)] fn foo(x: Tait1) -> Tait2 { let () = x; } @@ -38,6 +40,7 @@ mod ex3 { trait Something {} impl Something for T {} type Tait2 = impl Something; + #[define_opaque(Tait1, Tait2)] fn foo(x: Tait1) -> Tait2 { let () = x; } @@ -58,6 +61,7 @@ mod ex4 { // // ambiguity proving `(): Trait`. type Tait2 = impl Trait<(), Assoc = impl Trait>; + #[define_opaque(Tait1, Tait2)] fn foo(x: Tait1) -> Tait2 { let () = x; } diff --git a/tests/ui/traits/pointee-tail-is-generic-errors.rs b/tests/ui/traits/pointee-tail-is-generic-errors.rs index 92a83f40b184..8ddac5b2f396 100644 --- a/tests/ui/traits/pointee-tail-is-generic-errors.rs +++ b/tests/ui/traits/pointee-tail-is-generic-errors.rs @@ -5,6 +5,7 @@ type Opaque = impl std::fmt::Debug + ?Sized; +#[define_opaque(Opaque)] fn opaque() -> &'static Opaque { &[1] as &[i32] } diff --git a/tests/ui/traits/pointee-tail-is-generic-errors.stderr b/tests/ui/traits/pointee-tail-is-generic-errors.stderr index 0c3d7060dd7c..907f07026a43 100644 --- a/tests/ui/traits/pointee-tail-is-generic-errors.stderr +++ b/tests/ui/traits/pointee-tail-is-generic-errors.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `::Metadata == ()` - --> $DIR/pointee-tail-is-generic-errors.rs:13:15 + --> $DIR/pointee-tail-is-generic-errors.rs:14:15 | LL | is_thin::(); | ^ expected `()`, found associated type @@ -9,13 +9,13 @@ LL | is_thin::(); = help: consider constraining the associated type `::Metadata` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html note: required by a bound in `is_thin` - --> $DIR/pointee-tail-is-generic-errors.rs:20:33 + --> $DIR/pointee-tail-is-generic-errors.rs:21:33 | LL | fn is_thin + ?Sized>() {} | ^^^^^^^^^^^^^ required by this bound in `is_thin` error[E0271]: type mismatch resolving `::Metadata == ()` - --> $DIR/pointee-tail-is-generic-errors.rs:16:15 + --> $DIR/pointee-tail-is-generic-errors.rs:17:15 | LL | type Opaque = impl std::fmt::Debug + ?Sized; | ----------------------------- the found opaque type @@ -26,7 +26,7 @@ LL | is_thin::(); = note: expected unit type `()` found associated type `::Metadata` note: required by a bound in `is_thin` - --> $DIR/pointee-tail-is-generic-errors.rs:20:33 + --> $DIR/pointee-tail-is-generic-errors.rs:21:33 | LL | fn is_thin + ?Sized>() {} | ^^^^^^^^^^^^^ required by this bound in `is_thin` diff --git a/tests/ui/traits/pointee-tail-is-generic.rs b/tests/ui/traits/pointee-tail-is-generic.rs index 14bdf0880c73..b41fb61e4a4a 100644 --- a/tests/ui/traits/pointee-tail-is-generic.rs +++ b/tests/ui/traits/pointee-tail-is-generic.rs @@ -4,12 +4,11 @@ #![feature(ptr_metadata)] #![feature(type_alias_impl_trait)] -mod opaque { - pub type Opaque = impl std::future::Future; +pub type Opaque = impl std::future::Future; - fn opaque() -> Opaque { - async {} - } +#[define_opaque(Opaque)] +fn opaque() -> Opaque { + async {} } fn a() { @@ -18,7 +17,7 @@ fn a() { // tail of ADT (which is a type param) is known to be sized is_thin::>(); // opaque type is known to be sized - is_thin::(); + is_thin::(); } fn a2() { diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs index ab3817da28b1..ed852ef986a3 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs @@ -15,6 +15,7 @@ fn test_correct2<'a>(x: &dyn Foo<'a>) { let _ = x as &dyn Bar<'_, '_, Tait>; } +#[define_opaque(Tait)] fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) { let _ = x as &dyn Bar<'_, '_, ()>; } diff --git a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs index 0548eda04684..3e36ce0dc726 100644 --- a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs +++ b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs @@ -17,6 +17,7 @@ impl Super for T { type Foo = impl Sized; +#[define_opaque(Foo)] fn upcast(x: &dyn Sub) -> &dyn Super { x } diff --git a/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr index cdf9deecd515..7f51d1519db2 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr @@ -19,7 +19,7 @@ error: unconstrained opaque type LL | type OpaqueType = impl OpaqueTrait; | ^^^^^^^^^^^^^^^^ | - = note: `OpaqueType` must be used in combination with a concrete type within the same module + = note: `OpaqueType` must be used in combination with a concrete type within the same crate error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/argument-types.rs b/tests/ui/type-alias-impl-trait/argument-types.rs index 7382d4c78c7d..ea87bcb3e456 100644 --- a/tests/ui/type-alias-impl-trait/argument-types.rs +++ b/tests/ui/type-alias-impl-trait/argument-types.rs @@ -2,20 +2,19 @@ #![allow(dead_code)] //@ check-pass -mod foo { - use std::fmt::Debug; +use std::fmt::Debug; - pub type Foo = impl Debug; +pub type Foo = impl Debug; - fn foo1(mut x: Foo) { - x = 22_u32; - } - - pub fn foo_value() -> Foo { - 11_u32 - } +#[define_opaque(Foo)] +fn foo1(mut x: Foo) { + x = 22_u32; +} + +#[define_opaque(Foo)] +pub fn foo_value() -> Foo { + 11_u32 } -use foo::*; fn foo2(mut x: Foo) { // no constraint on x diff --git a/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs b/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs index 9dcbc75db3f1..97c1c1b64cc4 100644 --- a/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs +++ b/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs @@ -2,23 +2,21 @@ //@ build-pass -mod helper { - pub trait T { - type Item; - } - - pub type Alias<'a> = impl T; - - struct S; - impl<'a> T for &'a S { - type Item = &'a (); - } - - pub fn filter_positive<'a>() -> Alias<'a> { - &S - } +pub trait T { + type Item; +} + +pub type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S { + type Item = &'a (); +} + +#[define_opaque(Alias)] +pub fn filter_positive<'a>() -> Alias<'a> { + &S } -use helper::*; fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); diff --git a/tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs b/tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs index a1185cd5ba88..6761835be896 100644 --- a/tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs +++ b/tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs @@ -15,9 +15,11 @@ type Helper = impl Bar; impl Foo for i32 { type Assoc = Helper; + #[define_opaque(Helper)] fn foo() -> Helper { Dummy } + #[define_opaque(Helper)] fn bar() -> Helper { Dummy } diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs index a03a146d0418..cf385223ce45 100644 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs +++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs @@ -3,16 +3,15 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -mod m { - pub(crate) type Foo = impl std::fmt::Debug; +pub(crate) type Foo = impl std::fmt::Debug; - pub(crate) fn foo() -> Foo { - 22_u32 - } +#[define_opaque(Foo)] +pub(crate) fn foo() -> Foo { + 22_u32 } fn is_send(_: T) {} fn main() { - is_send(m::foo()); + is_send(foo()); } diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs index fc89b0e870e3..6132eef0db5f 100644 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs +++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs @@ -1,16 +1,15 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -mod m { - use std::rc::Rc; +use std::rc::Rc; - type Foo = impl std::fmt::Debug; //~ NOTE appears within the type - //~^ within this `Foo` - //~| expansion of desugaring +type Foo = impl std::fmt::Debug; //~ NOTE appears within the type +//~^ within this `Foo` +//~| expansion of desugaring - pub fn foo() -> Foo { - Rc::new(22_u32) - } +#[define_opaque(Foo)] +pub fn foo() -> Foo { + Rc::new(22_u32) } fn is_send(_: T) {} @@ -18,7 +17,7 @@ fn is_send(_: T) {} //~| required by a bound fn main() { - is_send(m::foo()); + is_send(foo()); //~^ ERROR: `Rc` cannot be sent between threads safely [E0277] //~| NOTE cannot be sent //~| NOTE required by a bound diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr index 2ed918eca171..d2db468b5195 100644 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr +++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr @@ -1,22 +1,22 @@ error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/auto-trait-leakage2.rs:21:13 + --> $DIR/auto-trait-leakage2.rs:20:13 | -LL | type Foo = impl std::fmt::Debug; - | -------------------- within this `Foo` +LL | type Foo = impl std::fmt::Debug; + | -------------------- within this `Foo` ... -LL | is_send(m::foo()); - | ------- ^^^^^^^^ `Rc` cannot be sent between threads safely +LL | is_send(foo()); + | ------- ^^^^^ `Rc` cannot be sent between threads safely | | | required by a bound introduced by this call | = help: within `Foo`, the trait `Send` is not implemented for `Rc` note: required because it appears within the type `Foo` - --> $DIR/auto-trait-leakage2.rs:7:16 + --> $DIR/auto-trait-leakage2.rs:6:12 | -LL | type Foo = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `is_send` - --> $DIR/auto-trait-leakage2.rs:16:15 + --> $DIR/auto-trait-leakage2.rs:15:15 | LL | fn is_send(_: T) {} | ^^^^ required by this bound in `is_send` diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs index cad75cffe05f..3e0bd3b6521c 100644 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs +++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs @@ -1,17 +1,17 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -// FIXME This should compile, but it currently doesn't +//@ check-pass mod m { pub type Foo = impl std::fmt::Debug; + #[define_opaque(Foo)] pub fn foo() -> Foo { 22_u32 } pub fn bar() { is_send(foo()); - //~^ ERROR: cannot check whether the hidden type of `auto_trait_leakage3[211d]::m::Foo::{opaque#0} } fn is_send(_: T) {} diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr deleted file mode 100644 index 6bdc76aab450..000000000000 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error: cannot check whether the hidden type of `auto_trait_leakage3[211d]::m::Foo::{opaque#0}` satisfies auto traits - --> $DIR/auto-trait-leakage3.rs:13:17 - | -LL | is_send(foo()); - | ------- ^^^^^ - | | - | required by a bound introduced by this call - | - = note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule -note: opaque type is declared here - --> $DIR/auto-trait-leakage3.rs:7:20 - | -LL | pub type Foo = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `is_send` - --> $DIR/auto-trait-leakage3.rs:17:19 - | -LL | fn is_send(_: T) {} - | ^^^^ required by this bound in `is_send` - -error: aborting due to 1 previous error - diff --git a/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs b/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs index e7bca2231de4..c60fd0b6798f 100644 --- a/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs +++ b/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs @@ -5,6 +5,7 @@ pub type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] pub fn foo() -> Foo { 5 } diff --git a/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs b/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs index 54a22510066f..3c823d3e5d27 100644 --- a/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs +++ b/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs @@ -3,6 +3,7 @@ #![feature(type_alias_impl_trait)] type Tait = impl Sized; +#[define_opaque(Tait)] fn _constrain() -> Tait {} struct WrapperWithDrop(T); diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs index 4b2ee344aa32..b6870b164509 100644 --- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs @@ -8,9 +8,9 @@ pub enum UninhabitedVariants { Tuple(Alias), //~^ ERROR missing lifetime specifier //~| ERROR missing generics - //~| ERROR non-defining opaque type use in defining scope } +#[define_opaque(Alias)] fn uwu(x: UninhabitedVariants) { //~^ ERROR item does not constrain match x {} diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr index 38fbff9d59da..59909197e7bc 100644 --- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr @@ -26,26 +26,14 @@ help: add missing generic argument LL | Tuple(Alias), | +++ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/bad-tait-no-substs.rs:8:11 - | -LL | Tuple(Alias), - | ^^^^^ argument `'_` is not a generic parameter - | -note: for this opaque type - --> $DIR/bad-tait-no-substs.rs:5:21 - | -LL | type Alias<'a, U> = impl Trait; - | ^^^^^^^^^^^^^ - -error: item does not constrain `Alias::{opaque#0}`, but has it in its signature +error: item does not constrain `Alias::{opaque#0}` --> $DIR/bad-tait-no-substs.rs:14:4 | LL | fn uwu(x: UninhabitedVariants) { | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/bad-tait-no-substs.rs:5:21 | LL | type Alias<'a, U> = impl Trait; @@ -72,7 +60,7 @@ LL + UninhabitedVariants::Tuple(_) => todo!(), LL ~ } | -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0004, E0106, E0107, E0792. +Some errors have detailed explanations: E0004, E0106, E0107. For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs b/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs index 3b83b2e544b0..4dba8d7b2308 100644 --- a/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs +++ b/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs @@ -11,6 +11,7 @@ type Opaque<'a> = impl Sized + 'a; +#[define_opaque(Opaque)] fn test<'a>() -> Opaque<'a> { let _: () = test::<'a>(); } diff --git a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs index df589473a846..e714aca812bc 100644 --- a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs +++ b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs @@ -9,7 +9,7 @@ fn dyn_hoops() -> dyn for<'a> Iterator> { } pub fn main() { - //~^ ERROR item does not constrain `Opaque::{opaque#0}`, but has it in its signature + //~^ ERROR item does not constrain `Opaque::{opaque#0}` type Opaque = impl Sized; fn define() -> Opaque { let x: Opaque = dyn_hoops::<()>(); diff --git a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr index 59d9ff86c6e0..7219fda4772a 100644 --- a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr +++ b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr @@ -10,14 +10,14 @@ note: lifetime declared here LL | fn dyn_hoops() -> dyn for<'a> Iterator> { | ^^ -error: item does not constrain `Opaque::{opaque#0}`, but has it in its signature +error: item does not constrain `Opaque::{opaque#0}` --> $DIR/bound-lifetime-through-dyn-trait.rs:11:8 | LL | pub fn main() { | ^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/bound-lifetime-through-dyn-trait.rs:13:19 | LL | type Opaque = impl Sized; diff --git a/tests/ui/type-alias-impl-trait/bound_reduction.rs b/tests/ui/type-alias-impl-trait/bound_reduction.rs index 74012e34e921..5966b5cc8159 100644 --- a/tests/ui/type-alias-impl-trait/bound_reduction.rs +++ b/tests/ui/type-alias-impl-trait/bound_reduction.rs @@ -10,6 +10,7 @@ type Foo = impl std::fmt::Debug; trait Trait {} +#[define_opaque(Foo)] fn foo_desugared {} impl Trait for () {} +#[define_opaque(Foo)] fn foo_desugared(_: T) -> Foo { - //~^ ERROR non-defining opaque type use () //~^ ERROR expected generic type parameter, found `::Assoc` } diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr index 14f9dbbdb4e9..289826cc1d02 100644 --- a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -1,15 +1,3 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/bound_reduction2.rs:15:46 - | -LL | fn foo_desugared(_: T) -> Foo { - | ^^^^^^^^^^^^^ argument `::Assoc` is not a generic parameter - | -note: for this opaque type - --> $DIR/bound_reduction2.rs:9:15 - | -LL | type Foo = impl Trait; - | ^^^^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `::Assoc` --> $DIR/bound_reduction2.rs:17:5 | @@ -19,6 +7,6 @@ LL | type Foo = impl Trait; LL | () | ^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs index 45f54266014d..4151a6a5f12d 100644 --- a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs +++ b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs @@ -3,15 +3,13 @@ #![feature(type_alias_impl_trait)] -mod foo { - pub type X = impl Clone; +pub type X = impl Clone; - fn f(t: T) -> X { - t - //~^ ERROR the trait bound `T: Clone` is not satisfied - } +#[define_opaque(X)] +fn f(t: T) -> X { + t + //~^ ERROR the trait bound `T: Clone` is not satisfied } -use foo::X; fn g(o: Option>) -> Option> { o.clone() diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr index bbb32b2d604d..21166631c3e2 100644 --- a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr +++ b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr @@ -1,23 +1,23 @@ error[E0277]: the trait bound `T: Clone` is not satisfied - --> $DIR/bounds-are-checked-2.rs:10:9 + --> $DIR/bounds-are-checked-2.rs:10:5 | -LL | t - | ^ the trait `Clone` is not implemented for `T` +LL | t + | ^ the trait `Clone` is not implemented for `T` | note: required by a bound in an opaque type - --> $DIR/bounds-are-checked-2.rs:7:26 + --> $DIR/bounds-are-checked-2.rs:6:22 | -LL | pub type X = impl Clone; - | ^^^^^ +LL | pub type X = impl Clone; + | ^^^^^ note: this definition site has more where clauses than the opaque type - --> $DIR/bounds-are-checked-2.rs:9:5 + --> $DIR/bounds-are-checked-2.rs:9:1 | -LL | fn f(t: T) -> X { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn f(t: T) -> X { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider restricting type parameter `T` with trait `Clone` | -LL | pub type X = impl Clone; - | +++++++++++++++++++ +LL | pub type X = impl Clone; + | +++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked.rs index 7c3a3a844060..3d2953587282 100644 --- a/tests/ui/type-alias-impl-trait/bounds-are-checked.rs +++ b/tests/ui/type-alias-impl-trait/bounds-are-checked.rs @@ -5,6 +5,7 @@ type X<'a> = impl Into<&'static str> + From<&'a str>; +#[define_opaque(X)] fn f<'a: 'static>(t: &'a str) -> X<'a> { t //~^ ERROR expected generic lifetime parameter, found `'static` diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr index ad1b9f19d8ef..7617268dd8e0 100644 --- a/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr +++ b/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/bounds-are-checked.rs:9:5 + --> $DIR/bounds-are-checked.rs:10:5 | LL | type X<'a> = impl Into<&'static str> + From<&'a str>; | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs index 5a9e87c09196..a8524770a852 100644 --- a/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs +++ b/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs @@ -9,6 +9,7 @@ struct Struct(Option); type Foo = (impl Debug, Struct); //~^ ERROR: `T` doesn't implement `std::fmt::Display` +#[define_opaque(Foo)] fn foo() -> Foo { (Vec::::new(), Struct(None)) } diff --git a/tests/ui/type-alias-impl-trait/bounds.rs b/tests/ui/type-alias-impl-trait/bounds.rs index 8e24a937d1d4..c131d52a4bad 100644 --- a/tests/ui/type-alias-impl-trait/bounds.rs +++ b/tests/ui/type-alias-impl-trait/bounds.rs @@ -9,6 +9,7 @@ use std::fmt::Debug; // type alias bounds. type Foo = (impl Debug, usize); +#[define_opaque(Foo)] fn foo() -> Foo { (Vec::::new(), 1234) } diff --git a/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs b/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs index 0dfa1f40ae6c..7fd8fa6f9dba 100644 --- a/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs +++ b/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs @@ -6,14 +6,12 @@ use std::marker::PhantomData; -mod foo { - pub type WithEmplacableForFn<'a> = impl super::EmplacableFn + 'a; +type WithEmplacableForFn<'a> = impl EmplacableFn + 'a; - fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> { - () - } +#[define_opaque(WithEmplacableForFn)] +fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> { + () } -use foo::*; fn with_emplacable_for<'a, F, R>(mut f: F) -> R where diff --git a/tests/ui/type-alias-impl-trait/closure_args.rs b/tests/ui/type-alias-impl-trait/closure_args.rs index 0141a01aad02..8a518c19dbab 100644 --- a/tests/ui/type-alias-impl-trait/closure_args.rs +++ b/tests/ui/type-alias-impl-trait/closure_args.rs @@ -4,21 +4,19 @@ #![feature(type_alias_impl_trait)] -mod foo { - pub trait Anything {} - impl Anything for T {} - pub type Input = impl Anything; +pub trait Anything {} +impl Anything for T {} +pub type Input = impl Anything; - fn bop(_: Input) { - super::run( - |x: u32| { - println!("{x}"); - }, - 0, - ); - } +#[define_opaque(Input)] +fn bop(_: Input) { + run( + |x: u32| { + println!("{x}"); + }, + 0, + ); } -use foo::Input; fn run ()>(f: F, i: Input) { f(i); diff --git a/tests/ui/type-alias-impl-trait/closure_args2.rs b/tests/ui/type-alias-impl-trait/closure_args2.rs index 13ac3d31d838..257c5f86633e 100644 --- a/tests/ui/type-alias-impl-trait/closure_args2.rs +++ b/tests/ui/type-alias-impl-trait/closure_args2.rs @@ -2,27 +2,25 @@ #![feature(type_alias_impl_trait)] -mod foo { - pub trait Foo { - // This was reachable in https://github.com/rust-lang/rust/issues/100800 - fn foo(&self) { - unreachable!() - } - } - impl Foo for T {} - - pub struct B; - impl B { - fn foo(&self) {} - } - pub type Input = impl Foo; - fn bop() -> Input { - super::run1(|x: B| x.foo(), B); - super::run2(|x: B| x.foo(), B); - panic!() +pub trait Foo { + // This was reachable in https://github.com/rust-lang/rust/issues/100800 + fn foo(&self) { + unreachable!() } } -use foo::*; +impl Foo for T {} + +pub struct B; +impl B { + fn foo(&self) {} +} +pub type Input = impl Foo; +#[define_opaque(Input)] +fn bop() -> Input { + run1(|x: B| x.foo(), B); + run2(|x: B| x.foo(), B); + panic!() +} fn run1(f: F, i: Input) { f(i) diff --git a/tests/ui/type-alias-impl-trait/closure_infer.rs b/tests/ui/type-alias-impl-trait/closure_infer.rs index fa0514c34a09..2aa19913ad6e 100644 --- a/tests/ui/type-alias-impl-trait/closure_infer.rs +++ b/tests/ui/type-alias-impl-trait/closure_infer.rs @@ -22,12 +22,14 @@ impl StreamConsumer for DispatchExecutor { // Functions that constrain TAITs can contain closures with an `_` in the return type. type Foo = impl Sized; +#[define_opaque(Foo)] fn foo() -> Foo { || -> _ {} } // The `_` in the closure return type can also be the TAIT itself. type Bar = impl Sized; +#[define_opaque(Bar)] fn bar() -> impl FnOnce() -> Bar { || -> _ {} } diff --git a/tests/ui/type-alias-impl-trait/closure_parent_substs.rs b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs index e78c7c16c8e6..4c99778b66e7 100644 --- a/tests/ui/type-alias-impl-trait/closure_parent_substs.rs +++ b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs @@ -15,6 +15,7 @@ mod test1 { // Hidden type = Closure['?0] type Opaque = impl Sized; + #[define_opaque(Opaque)] fn define<'a: 'a>() -> Opaque { || {} } @@ -31,6 +32,7 @@ mod test2 { &'a (): Trait, = impl Sized + 'a; + #[define_opaque(Opaque)] fn define<'a, 'x, 'y>() -> Opaque<'a> where &'a (): Trait, @@ -52,6 +54,7 @@ mod test3 { (&'a (), &'b ()): Trait, = impl Sized + 'a + 'b; + #[define_opaque(Opaque)] fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> where (&'a (), &'b ()): Trait, diff --git a/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs b/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs index caa9b6d979ab..5316a47bbd46 100644 --- a/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs +++ b/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs @@ -13,6 +13,7 @@ mod test1 { type Opaque<'a, 'b> = impl Sized + 'a + 'b; + #[define_opaque(Opaque)] fn define<'a, 'b>() -> Opaque<'a, 'b> where 'a: 'b, @@ -26,6 +27,7 @@ mod test1 { mod test2 { type Opaque<'a, 'b> = impl Sized + 'a + 'b; + #[define_opaque(Opaque)] fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> where 'a: 'x, @@ -40,6 +42,7 @@ mod test2 { mod test2_fixed { type Opaque<'a: 'b, 'b> = impl Sized + 'a + 'b; + #[define_opaque(Opaque)] fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> where 'a: 'x, @@ -53,6 +56,7 @@ mod test2_fixed { mod test3 { type Opaque = impl Sized; + #[define_opaque(Opaque)] fn define() -> Opaque where T: 'static, diff --git a/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr b/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr index ae00d3fc6678..ccba2d37fd03 100644 --- a/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr +++ b/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr @@ -1,5 +1,5 @@ error[E0478]: lifetime bound not satisfied - --> $DIR/closure_wf_outlives.rs:20:9 + --> $DIR/closure_wf_outlives.rs:21:9 | LL | || {} | ^^^^^ @@ -16,34 +16,34 @@ LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ^^ error[E0803]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/closure_wf_outlives.rs:34:9 + --> $DIR/closure_wf_outlives.rs:36:9 | LL | || {} | ^^^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/closure_wf_outlives.rs:27:17 + --> $DIR/closure_wf_outlives.rs:28:17 | LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ^^ note: ...so that the declared lifetime parameter bounds are satisfied - --> $DIR/closure_wf_outlives.rs:34:9 + --> $DIR/closure_wf_outlives.rs:36:9 | LL | || {} | ^^^^^ note: but, the lifetime must be valid for the lifetime `'b` as defined here... - --> $DIR/closure_wf_outlives.rs:27:21 + --> $DIR/closure_wf_outlives.rs:28:21 | LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ^^ note: ...so that the declared lifetime parameter bounds are satisfied - --> $DIR/closure_wf_outlives.rs:34:9 + --> $DIR/closure_wf_outlives.rs:36:9 | LL | || {} | ^^^^^ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/closure_wf_outlives.rs:60:9 + --> $DIR/closure_wf_outlives.rs:64:9 | LL | || {} | ^^^^^ @@ -52,7 +52,7 @@ LL | || {} | ...so that the type `T` will meet its required lifetime bounds... | note: ...that is required by this bound - --> $DIR/closure_wf_outlives.rs:58:12 + --> $DIR/closure_wf_outlives.rs:62:12 | LL | T: 'static, | ^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/closures_in_branches.rs b/tests/ui/type-alias-impl-trait/closures_in_branches.rs index 7bb490bbec81..d83bf36a444e 100644 --- a/tests/ui/type-alias-impl-trait/closures_in_branches.rs +++ b/tests/ui/type-alias-impl-trait/closures_in_branches.rs @@ -2,6 +2,7 @@ type Foo = impl std::ops::FnOnce(String) -> usize; +#[define_opaque(Foo)] fn foo(b: bool) -> Foo { if b { |x| x.len() //~ ERROR type annotations needed @@ -10,8 +11,8 @@ fn foo(b: bool) -> Foo { } } - type Foo1 = impl std::ops::FnOnce(String) -> usize; +#[define_opaque(Foo1)] fn foo1(b: bool) -> Foo1 { |x| x.len() } diff --git a/tests/ui/type-alias-impl-trait/closures_in_branches.stderr b/tests/ui/type-alias-impl-trait/closures_in_branches.stderr index 9cc15f14a991..849ffd214f07 100644 --- a/tests/ui/type-alias-impl-trait/closures_in_branches.stderr +++ b/tests/ui/type-alias-impl-trait/closures_in_branches.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/closures_in_branches.rs:7:10 + --> $DIR/closures_in_branches.rs:8:10 | LL | |x| x.len() | ^ - type must be known at this point @@ -10,7 +10,7 @@ LL | |x: /* Type */| x.len() | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/closures_in_branches.rs:21:10 + --> $DIR/closures_in_branches.rs:22:10 | LL | |x| x.len() | ^ - type must be known at this point diff --git a/tests/ui/type-alias-impl-trait/coherence.classic.stderr b/tests/ui/type-alias-impl-trait/coherence.classic.stderr index 98badeef382d..e99d4636b134 100644 --- a/tests/ui/type-alias-impl-trait/coherence.classic.stderr +++ b/tests/ui/type-alias-impl-trait/coherence.classic.stderr @@ -1,5 +1,5 @@ error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence.rs:16:1 + --> $DIR/coherence.rs:17:1 | LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------- diff --git a/tests/ui/type-alias-impl-trait/coherence.next.stderr b/tests/ui/type-alias-impl-trait/coherence.next.stderr index 8d7183831109..6d14594e33a0 100644 --- a/tests/ui/type-alias-impl-trait/coherence.next.stderr +++ b/tests/ui/type-alias-impl-trait/coherence.next.stderr @@ -1,5 +1,5 @@ error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence.rs:16:1 + --> $DIR/coherence.rs:17:1 | LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------- diff --git a/tests/ui/type-alias-impl-trait/coherence.rs b/tests/ui/type-alias-impl-trait/coherence.rs index 760e5210c5b7..eb27c2708042 100644 --- a/tests/ui/type-alias-impl-trait/coherence.rs +++ b/tests/ui/type-alias-impl-trait/coherence.rs @@ -9,6 +9,7 @@ trait LocalTrait {} impl LocalTrait for foreign_crate::ForeignType {} type AliasOfForeignType = impl LocalTrait; +#[define_opaque(AliasOfForeignType)] fn use_alias(val: T) -> AliasOfForeignType { foreign_crate::ForeignType(val) } diff --git a/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs b/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs index c1958e4f246d..73f13f22bee2 100644 --- a/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs +++ b/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs @@ -13,6 +13,7 @@ trait OtherTrait {} type Alias = impl SomeTrait; +#[define_opaque(Alias)] fn constrain() -> Alias { () } diff --git a/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr b/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr index 893a27faced6..6b251cfac73c 100644 --- a/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr +++ b/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `OtherTrait` for type `Alias` - --> $DIR/coherence_cross_crate.rs:21:1 + --> $DIR/coherence_cross_crate.rs:22:1 | LL | impl OtherTrait for Alias {} | ------------------------- first implementation here diff --git a/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs b/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs index 39b3d535ad45..a7e251b1ab99 100644 --- a/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs +++ b/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs @@ -20,6 +20,7 @@ impl Trait for (TAIT, TAIT) {} impl Trait for (u32, i32) {} //~^ ERROR conflicting implementations of trait `Trait` for type `(TAIT, TAIT)` +#[define_opaque(TAIT)] fn define() -> TAIT {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/coherence_generalization.rs b/tests/ui/type-alias-impl-trait/coherence_generalization.rs index 2d7de1add490..46cde115b7f7 100644 --- a/tests/ui/type-alias-impl-trait/coherence_generalization.rs +++ b/tests/ui/type-alias-impl-trait/coherence_generalization.rs @@ -6,6 +6,7 @@ #![feature(type_alias_impl_trait)] trait Trait {} type Opaque = impl Sized; +#[define_opaque(Opaque)] fn foo() -> Opaque { () } diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr index 5b77bb6c2bc2..dc15d530fd7a 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr +++ b/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr @@ -1,8 +1,8 @@ error: `Bar` is forbidden as the type of a const generic parameter - --> $DIR/const_generic_type.rs:7:24 + --> $DIR/const_generic_type.rs:8:24 | -LL | async fn test() { - | ^^^^^^^^^^ +LL | async fn test() { + | ^^^ | = note: the only supported types are integers, `bool`, and `char` diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr index c7c93eee63e9..ba97bbf89f8b 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr +++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr @@ -1,36 +1,36 @@ error: `Bar` is forbidden as the type of a const generic parameter - --> $DIR/const_generic_type.rs:7:24 + --> $DIR/const_generic_type.rs:8:24 | -LL | async fn test() { - | ^^^^^^^^^^ +LL | async fn test() { + | ^^^ | = note: the only supported types are integers, `bool`, and `char` -error: item does not constrain `Bar::{opaque#0}`, but has it in its signature - --> $DIR/const_generic_type.rs:7:10 +error: item does not constrain `Bar::{opaque#0}` + --> $DIR/const_generic_type.rs:8:10 | -LL | async fn test() { +LL | async fn test() { | ^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/const_generic_type.rs:5:12 | LL | type Bar = impl std::fmt::Display; | ^^^^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `Bar::{opaque#0}`, but has it in its signature - --> $DIR/const_generic_type.rs:7:38 +error: item does not constrain `Bar::{opaque#0}` + --> $DIR/const_generic_type.rs:8:31 | -LL | async fn test() { - | ______________________________________^ +LL | async fn test() { + | _______________________________^ ... | LL | | let x: u32 = N; LL | | } | |_^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/const_generic_type.rs:5:12 | LL | type Bar = impl std::fmt::Display; diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.rs b/tests/ui/type-alias-impl-trait/const_generic_type.rs index 7149370048b3..5b093be92312 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.rs +++ b/tests/ui/type-alias-impl-trait/const_generic_type.rs @@ -4,7 +4,8 @@ #![feature(type_alias_impl_trait)] type Bar = impl std::fmt::Display; -async fn test() { +#[define_opaque(Bar)] +async fn test() { //~^ ERROR: `Bar` is forbidden as the type of a const generic parameter //[no_infer]~^^ ERROR item does not constrain //[no_infer]~| ERROR item does not constrain diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr index 580258bbb28e..c4c55d8e0927 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Foo: Trait` is not satisfied - --> $DIR/constrain_in_projection.rs:24:14 + --> $DIR/constrain_in_projection.rs:25:14 | LL | let x = >::Assoc::default(); | ^^^ the trait `Trait` is not implemented for `Foo` @@ -8,7 +8,7 @@ LL | let x = >::Assoc::default(); but trait `Trait<()>` is implemented for it error[E0277]: the trait bound `Foo: Trait` is not satisfied - --> $DIR/constrain_in_projection.rs:24:13 + --> $DIR/constrain_in_projection.rs:25:13 | LL | let x = >::Assoc::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Foo` diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs index 355c0e1692b2..64b9c583ca2e 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs @@ -20,7 +20,8 @@ impl Trait<()> for Foo { type Assoc = u32; } -fn bop(_: Bar) { +#[define_opaque(Bar)] +fn bop() { let x = >::Assoc::default(); //[current]~^ `Foo: Trait` is not satisfied //[current]~| `Foo: Trait` is not satisfied diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr index 777fe1e2788c..d7fb6e67ad29 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Foo: Trait` is not satisfied - --> $DIR/constrain_in_projection2.rs:27:14 + --> $DIR/constrain_in_projection2.rs:28:14 | LL | let x = >::Assoc::default(); | ^^^ the trait `Trait` is not implemented for `Foo` @@ -9,7 +9,7 @@ LL | let x = >::Assoc::default(); `Foo` implements `Trait` error[E0277]: the trait bound `Foo: Trait` is not satisfied - --> $DIR/constrain_in_projection2.rs:27:13 + --> $DIR/constrain_in_projection2.rs:28:13 | LL | let x = >::Assoc::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Foo` diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr index 0d6eac4216ba..7c09ab6a91ae 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr @@ -1,5 +1,5 @@ error[E0283]: type annotations needed: cannot satisfy `Foo: Trait` - --> $DIR/constrain_in_projection2.rs:27:14 + --> $DIR/constrain_in_projection2.rs:28:14 | LL | let x = >::Assoc::default(); | ^^^ help: use the fully qualified path to an implementation: `::Assoc` diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs index 16b1329b52f3..61773cf59d47 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs @@ -23,7 +23,8 @@ impl Trait for Foo { type Assoc = u32; } -fn bop(_: Bar) { +#[define_opaque(Bar)] +fn bop() { let x = >::Assoc::default(); //[next]~^ ERROR: cannot satisfy `Foo: Trait` //[current]~^^ ERROR: `Foo: Trait` is not satisfied diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs.rs b/tests/ui/type-alias-impl-trait/constrain_inputs.rs index 1391a2036b2e..7f6698e641d0 100644 --- a/tests/ui/type-alias-impl-trait/constrain_inputs.rs +++ b/tests/ui/type-alias-impl-trait/constrain_inputs.rs @@ -2,7 +2,9 @@ mod lifetime_params { type Ty<'a> = impl Sized; + #[define_opaque(Ty)] fn defining(s: &str) -> Ty<'_> { s } + #[define_opaque(Ty)] fn execute(ty: Ty<'_>) -> &str { todo!() } //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types //~| ERROR item does not constrain @@ -15,7 +17,9 @@ mod lifetime_params { mod lifetime_params_2 { type Ty<'a> = impl FnOnce() -> &'a str; + #[define_opaque(Ty)] fn defining(s: &str) -> Ty<'_> { move || s } + #[define_opaque(Ty)] fn execute(ty: Ty<'_>) -> &str { ty() } //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types //~| ERROR item does not constrain @@ -24,6 +28,7 @@ mod lifetime_params_2 { // regression test for https://github.com/rust-lang/rust/issues/97104 mod type_params { type Ty = impl Sized; + #[define_opaque(Ty)] fn define(s: T) -> Ty { s } type BadFnSig = fn(Ty<&str>) -> &str; diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs.stderr b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr index 436326e66c38..b016715b1292 100644 --- a/tests/ui/type-alias-impl-trait/constrain_inputs.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr @@ -1,5 +1,5 @@ error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types - --> $DIR/constrain_inputs.rs:6:31 + --> $DIR/constrain_inputs.rs:8:31 | LL | fn execute(ty: Ty<'_>) -> &str { todo!() } | ^^^^ @@ -8,7 +8,7 @@ LL | fn execute(ty: Ty<'_>) -> &str { todo!() } = note: consider introducing a named lifetime parameter error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types - --> $DIR/constrain_inputs.rs:10:35 + --> $DIR/constrain_inputs.rs:12:35 | LL | type BadFnSig = fn(Ty<'_>) -> &str; | ^^^^ @@ -17,7 +17,7 @@ LL | type BadFnSig = fn(Ty<'_>) -> &str; = note: consider introducing a named lifetime parameter error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types - --> $DIR/constrain_inputs.rs:12:42 + --> $DIR/constrain_inputs.rs:14:42 | LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str; | ^^^^ @@ -25,21 +25,21 @@ LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str; = note: lifetimes appearing in an associated or opaque type are not considered constrained = note: consider introducing a named lifetime parameter -error: item does not constrain `lifetime_params::Ty::{opaque#0}`, but has it in its signature - --> $DIR/constrain_inputs.rs:6:8 +error: item does not constrain `lifetime_params::Ty::{opaque#0}` + --> $DIR/constrain_inputs.rs:8:8 | LL | fn execute(ty: Ty<'_>) -> &str { todo!() } | ^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/constrain_inputs.rs:4:19 | LL | type Ty<'a> = impl Sized; | ^^^^^^^^^^ error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types - --> $DIR/constrain_inputs.rs:19:31 + --> $DIR/constrain_inputs.rs:23:31 | LL | fn execute(ty: Ty<'_>) -> &str { ty() } | ^^^^ @@ -47,21 +47,21 @@ LL | fn execute(ty: Ty<'_>) -> &str { ty() } = note: lifetimes appearing in an associated or opaque type are not considered constrained = note: consider introducing a named lifetime parameter -error: item does not constrain `lifetime_params_2::Ty::{opaque#0}`, but has it in its signature - --> $DIR/constrain_inputs.rs:19:8 +error: item does not constrain `lifetime_params_2::Ty::{opaque#0}` + --> $DIR/constrain_inputs.rs:23:8 | LL | fn execute(ty: Ty<'_>) -> &str { ty() } | ^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/constrain_inputs.rs:17:19 + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/constrain_inputs.rs:19:19 | LL | type Ty<'a> = impl FnOnce() -> &'a str; | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types - --> $DIR/constrain_inputs.rs:29:37 + --> $DIR/constrain_inputs.rs:34:37 | LL | type BadFnSig = fn(Ty<&str>) -> &str; | ^^^^ @@ -70,7 +70,7 @@ LL | type BadFnSig = fn(Ty<&str>) -> &str; = note: consider introducing a named lifetime parameter error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types - --> $DIR/constrain_inputs.rs:31:44 + --> $DIR/constrain_inputs.rs:36:44 | LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str; | ^^^^ diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs index 3bae0f173099..dc38e9a8cdc2 100644 --- a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs +++ b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs @@ -4,9 +4,12 @@ trait Static: 'static {} impl Static for () {} type Gal = impl Static; +#[define_opaque(Gal)] fn _defining() -> Gal {} -trait Callable { type Output; } +trait Callable { + type Output; +} /// We can infer `>::Output: 'static`, /// because we know `C: 'static` and `Arg: 'static`, diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr index 948bd6deacd0..0edb0a068846 100644 --- a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr @@ -1,5 +1,5 @@ error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types - --> $DIR/constrain_inputs_unsound.rs:23:58 + --> $DIR/constrain_inputs_unsound.rs:26:58 | LL | type MalformedTy = dyn for<'a> Callable, Output = &'a str>; | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs b/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs index db9c2cc096ab..6d9c05d9c68b 100644 --- a/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs +++ b/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs @@ -3,12 +3,10 @@ #![feature(type_alias_impl_trait)] -mod bar { - pub type Debuggable = impl core::fmt::Debug; - fn foo() -> Debuggable { - 0u32 - } +pub type Debuggable = impl core::fmt::Debug; +#[define_opaque(Debuggable)] +fn foo() -> Debuggable { + 0u32 } -use bar::Debuggable; static mut TEST: Option = None; diff --git a/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr b/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr index 772f487d96aa..c2c401da0e89 100644 --- a/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr +++ b/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr @@ -4,7 +4,7 @@ error: unconstrained opaque type LL | type Bar = impl std::fmt::Debug; | ^^^^^^^^^^^^^^^^^^^^ | - = note: `Bar` must be used in combination with a concrete type within the same module + = note: `Bar` must be used in combination with a concrete type within the same crate error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr index d60f1ffbccc2..e97a69bd92c0 100644 --- a/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr +++ b/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr @@ -4,7 +4,7 @@ error: unconstrained opaque type LL | pub type Boo = impl ::std::fmt::Debug; | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `Boo` must be used in combination with a concrete type within the same module + = note: `Boo` must be used in combination with a concrete type within the same crate error[E0308]: mismatched types --> $DIR/declared_but_not_defined_in_scope.rs:11:5 @@ -19,7 +19,7 @@ LL | "" | = note: expected opaque type `Boo` found reference `&'static str` -note: this item must have the opaque type in its signature in order to be able to register hidden types +note: this item must have a `#[define_opaque(Boo)]` attribute to be able to define hidden types --> $DIR/declared_but_not_defined_in_scope.rs:10:4 | LL | fn bomp() -> boo::Boo { diff --git a/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs index 75a4fbdb5d63..6a07ea05c1a1 100644 --- a/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs +++ b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs @@ -11,9 +11,11 @@ impl> Indirect for (A, B) { type Ty = (); } mod basic { use super::*; type Opq = impl Sized; + #[define_opaque(Opq)] fn define_1(_: Opq) { let _ = None::<<(Opq, u8) as Indirect>::Ty>; } + #[define_opaque(Opq)] fn define_2() -> Opq { 0u8 } @@ -23,6 +25,7 @@ mod basic { mod lifetime { use super::*; type Opq<'a> = impl Sized + 'a; + #[define_opaque(Opq)] fn define<'a: 'b, 'b: 'a>(_: Opq<'a>) { let _ = None::<<(Opq<'a>, &'b u8) as Indirect>::Ty>; } diff --git a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs index 9101e4385b3d..bc3904eb4e5f 100644 --- a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs @@ -2,6 +2,7 @@ mod case1 { type Opaque<'x> = impl Sized + 'x; + #[define_opaque(Opaque)] fn foo<'s>() -> Opaque<'s> { let _ = || { let _: Opaque<'s> = (); }; //~^ ERROR expected generic lifetime parameter, found `'_` @@ -10,6 +11,7 @@ mod case1 { mod case2 { type Opaque<'x> = impl Sized + 'x; + #[define_opaque(Opaque)] fn foo<'s>() -> Opaque<'s> { let _ = || -> Opaque<'s> {}; //~^ ERROR expected generic lifetime parameter, found `'_` diff --git a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr index a8fd1f691dd4..2210291d37b5 100644 --- a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr +++ b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr @@ -1,18 +1,18 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/defined-in-closure-external-lifetime.rs:6:29 + --> $DIR/defined-in-closure-external-lifetime.rs:7:29 | LL | type Opaque<'x> = impl Sized + 'x; | -- this generic parameter must be used with a generic lifetime parameter -LL | fn foo<'s>() -> Opaque<'s> { +... LL | let _ = || { let _: Opaque<'s> = (); }; | ^^^^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/defined-in-closure-external-lifetime.rs:14:34 + --> $DIR/defined-in-closure-external-lifetime.rs:16:34 | LL | type Opaque<'x> = impl Sized + 'x; | -- this generic parameter must be used with a generic lifetime parameter -LL | fn foo<'s>() -> Opaque<'s> { +... LL | let _ = || -> Opaque<'s> {}; | ^^ diff --git a/tests/ui/type-alias-impl-trait/defining-use-submodule.rs b/tests/ui/type-alias-impl-trait/defining-use-submodule.rs index 3e7bc32640f5..b953cd646a02 100644 --- a/tests/ui/type-alias-impl-trait/defining-use-submodule.rs +++ b/tests/ui/type-alias-impl-trait/defining-use-submodule.rs @@ -11,13 +11,24 @@ type Foo = impl std::fmt::Display; type Bar = impl std::fmt::Display; mod foo { + #[define_opaque(super::Foo)] pub(crate) fn foo() -> super::Foo { "foo" } pub(crate) mod bar { + #[define_opaque(crate::Bar)] pub(crate) fn bar() -> crate::Bar { 1 } } } + +mod bar { + pub type Baz = impl std::fmt::Display; +} + +#[define_opaque(bar::Baz)] +fn baz() -> bar::Baz { + "boom" +} diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs index eadf21c9138c..a3b1aba70411 100644 --- a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs +++ b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs @@ -10,6 +10,7 @@ pub struct Foo { pub type Tait = impl Sized; +#[define_opaque(Tait)] pub async fn ice_cold(beverage: Tait) { // Must destructure at least one field of `Foo` let Foo { field } = beverage; diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs index 8ce471e39568..e56f60a6693e 100644 --- a/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs @@ -2,10 +2,12 @@ pub type Opaque<'a> = impl Sized; +#[define_opaque(Opaque)] fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> { a } +#[define_opaque(Opaque)] fn get_iter<'a>() -> impl IntoIterator> { //~^ ERROR: item does not constrain None::> diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr b/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr index f27f22345252..587328e28700 100644 --- a/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr @@ -1,11 +1,11 @@ -error: item does not constrain `Opaque::{opaque#0}`, but has it in its signature - --> $DIR/different_args_considered_equal.rs:9:4 +error: item does not constrain `Opaque::{opaque#0}` + --> $DIR/different_args_considered_equal.rs:11:4 | LL | fn get_iter<'a>() -> impl IntoIterator> { | ^^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/different_args_considered_equal.rs:3:23 | LL | pub type Opaque<'a> = impl Sized; diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs index 43dfea97e6db..902d6ca57e6c 100644 --- a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs @@ -2,6 +2,7 @@ pub type Opaque<'a> = impl Sized; +#[define_opaque(Opaque)] fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator> { if a.is_null() { Some(a) diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr index 213272f5f345..562ab4168b53 100644 --- a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr @@ -1,9 +1,9 @@ error[E0700]: hidden type for `Opaque<'static>` captures lifetime that does not appear in bounds - --> $DIR/different_args_considered_equal2.rs:9:9 + --> $DIR/different_args_considered_equal2.rs:10:9 | LL | pub type Opaque<'a> = impl Sized; | ---------- opaque type defined here -LL | +... LL | fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator> { | -- hidden type `*mut &'a str` captures the lifetime `'a` as defined here ... diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs index ea69175ba310..85a7e371b073 100644 --- a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs @@ -5,14 +5,12 @@ #![feature(type_alias_impl_trait)] -mod defining_scope { - pub type Opaque<'a> = impl Sized; +pub type Opaque<'a> = impl Sized; - fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> { - a - } +#[define_opaque(Opaque)] +fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> { + a } -use defining_scope::Opaque; fn get_iter<'a>() -> impl IntoIterator> { None::> diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr index d8f70e3d7782..06d6433c4b5f 100644 --- a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/different_args_considered_equal3.rs:18:5 + --> $DIR/different_args_considered_equal3.rs:16:5 | LL | fn get_iter<'a>() -> impl IntoIterator> { | -- lifetime `'a` defined here diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses.rs b/tests/ui/type-alias-impl-trait/different_defining_uses.rs index 4505c4d95248..246f255e8fcf 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses.rs @@ -5,10 +5,12 @@ fn main() {} // two definitions with different types type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo() -> Foo { "" } +#[define_opaque(Foo)] fn bar() -> Foo { 42i32 //~^ ERROR concrete type differs from previous diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses.stderr index 9e6169b2af73..9a7f4b416f4b 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/different_defining_uses.rs:13:5 + --> $DIR/different_defining_uses.rs:15:5 | LL | 42i32 | ^^^^^ expected `&'static str`, got `i32` | note: previous use here - --> $DIR/different_defining_uses.rs:9:5 + --> $DIR/different_defining_uses.rs:10:5 | LL | "" | ^^ diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs index 4b5f455e3815..e8c40e8bf926 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs @@ -2,6 +2,7 @@ type Tait<'a> = impl Sized + 'a; +#[define_opaque(Tait)] fn foo<'a, 'b>() -> Tait<'a> { if false { if { return } { diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr index 6f5be5467f70..d4bd39759247 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr @@ -1,23 +1,23 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/different_defining_uses_never_type-2.rs:13:5 + --> $DIR/different_defining_uses_never_type-2.rs:14:5 | LL | x | ^ expected `i32`, got `()` | note: previous use here - --> $DIR/different_defining_uses_never_type-2.rs:8:31 + --> $DIR/different_defining_uses_never_type-2.rs:9:31 | LL | let y: Tait<'b> = 1i32; | ^^^^ error: concrete type differs from previous defining opaque type use - --> $DIR/different_defining_uses_never_type-2.rs:8:31 + --> $DIR/different_defining_uses_never_type-2.rs:9:31 | LL | let y: Tait<'b> = 1i32; | ^^^^ expected `()`, got `i32` | note: previous use here - --> $DIR/different_defining_uses_never_type-2.rs:7:14 + --> $DIR/different_defining_uses_never_type-2.rs:8:14 | LL | if { return } { | ^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs index a4ac27378e1d..b2713b9602ce 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs @@ -2,6 +2,7 @@ type Tait = impl Sized; +#[define_opaque(Tait)] fn foo() -> Tait { if false { if { return } { diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr index 0fdcb81f6672..cb12fddd9a03 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/different_defining_uses_never_type-3.rs:8:30 + --> $DIR/different_defining_uses_never_type-3.rs:9:30 | LL | let y: Tait = 1i32; | ^^^^ expected `()`, got `i32` | note: previous use here - --> $DIR/different_defining_uses_never_type-3.rs:12:22 + --> $DIR/different_defining_uses_never_type-3.rs:13:22 | LL | let x: Tait = (); | ^^ diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs index 0b8157fe33dd..38597ccaf427 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs @@ -5,14 +5,17 @@ fn main() {} // two definitions with different types type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo() -> Foo { "" } +#[define_opaque(Foo)] fn bar() -> Foo { //~ ERROR: concrete type differs from previous defining opaque type use panic!() } +#[define_opaque(Foo)] fn boo() -> Foo { loop {} } diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr index 2a77eb4c4ac3..38afa3cbcd0e 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/different_defining_uses_never_type.rs:12:13 + --> $DIR/different_defining_uses_never_type.rs:14:13 | LL | fn bar() -> Foo { | ^^^ expected `&'static str`, got `()` | note: previous use here - --> $DIR/different_defining_uses_never_type.rs:9:5 + --> $DIR/different_defining_uses_never_type.rs:10:5 | LL | "" | ^^ diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs index c39cc192dc74..03766da34cbb 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs @@ -7,10 +7,12 @@ fn main() {} // two definitions with different types type Foo = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo() -> Foo { "" } +#[define_opaque(Foo)] fn bar(arg: bool) -> Foo { if arg { panic!() @@ -19,6 +21,7 @@ fn bar(arg: bool) -> Foo { } } +#[define_opaque(Foo)] fn boo(arg: bool) -> Foo { if arg { loop {} @@ -27,6 +30,7 @@ fn boo(arg: bool) -> Foo { } } +#[define_opaque(Foo)] fn bar2(arg: bool) -> Foo { if arg { "bar2" @@ -35,6 +39,7 @@ fn bar2(arg: bool) -> Foo { } } +#[define_opaque(Foo)] fn boo2(arg: bool) -> Foo { if arg { "boo2" diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs index bc827a8f2113..b5c2bf504ac6 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs @@ -3,9 +3,11 @@ type Tait = impl Sized; struct One; +#[define_opaque(Tait)] fn one() -> Tait { One } struct Two(T); +#[define_opaque(Tait)] fn two() -> Tait { Two::<()>(todo!()) } //~^ ERROR concrete type differs from previous defining opaque type use diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr index abf4a0d241b2..21fab8180633 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/different_defining_uses_never_type3.rs:9:13 + --> $DIR/different_defining_uses_never_type3.rs:11:13 | LL | fn two() -> Tait { Two::<()>(todo!()) } | ^^^^ expected `One`, got `Two<()>` | note: previous use here - --> $DIR/different_defining_uses_never_type3.rs:6:20 + --> $DIR/different_defining_uses_never_type3.rs:7:20 | LL | fn one() -> Tait { One } | ^^^ diff --git a/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs index 4f424b8c665a..ba3265343c61 100644 --- a/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs +++ b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs @@ -3,10 +3,12 @@ type OneLifetime<'a, 'b> = impl std::fmt::Debug; +#[define_opaque(OneLifetime)] fn foo<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> { a } +#[define_opaque(OneLifetime)] fn bar<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> { b //~^ ERROR: concrete type differs from previous defining opaque type use diff --git a/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr index 07ba17ad27b8..b87e884708ab 100644 --- a/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr +++ b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/different_lifetimes_defining_uses.rs:11:5 + --> $DIR/different_lifetimes_defining_uses.rs:13:5 | LL | b | ^ expected `&'a u32`, got `&'b u32` | note: previous use here - --> $DIR/different_lifetimes_defining_uses.rs:7:5 + --> $DIR/different_lifetimes_defining_uses.rs:8:5 | LL | a | ^ diff --git a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs index 4332f1264a80..987ac3812898 100644 --- a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs +++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs @@ -2,29 +2,32 @@ #![feature(type_alias_impl_trait)] -mod impl_trait_mod { - use super::*; - pub type OpaqueBlock = impl Trait; - //~^ ERROR unconstrained opaque type - pub type OpaqueIf = impl Trait; +pub type OpaqueBlock = impl Trait; +//~^ ERROR unconstrained opaque type +pub type OpaqueIf = impl Trait; - pub struct BlockWrapper(OpaqueBlock); - pub struct IfWrapper(pub OpaqueIf); +pub struct BlockWrapper(OpaqueBlock); +pub struct IfWrapper(pub OpaqueIf); - pub fn if_impl() -> Parser { - bind(option(block()), |_| block()) - } +#[define_opaque(OpaqueIf)] +pub fn if_impl() -> Parser { + bind(option(block()), |_| block()) } -use impl_trait_mod::*; pub trait Trait { type Assoc; } pub struct Parser

(P); pub struct Bind(P, F); -impl Trait for Bind { type Assoc = (); } -impl Trait for BlockWrapper { type Assoc = (); } -impl Trait for IfWrapper { type Assoc = (); } +impl Trait for Bind { + type Assoc = (); +} +impl Trait for BlockWrapper { + type Assoc = (); +} +impl Trait for IfWrapper { + type Assoc = (); +} pub fn block() -> Parser { loop {} @@ -32,8 +35,9 @@ pub fn block() -> Parser { pub fn option(arg: Parser

) -> Parser { bind(arg, |_| block()) } -fn bind Parser>(_: Parser

, _: F) -> Parser> - { loop {} } +fn bind Parser>(_: Parser

, _: F) -> Parser> { + loop {} +} fn main() { if_impl().0; diff --git a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr index 8e5838d5ddf5..db97954f6985 100644 --- a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr +++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr @@ -1,10 +1,10 @@ error: unconstrained opaque type - --> $DIR/drop-analysis-on-unconstrained-tait.rs:7:28 + --> $DIR/drop-analysis-on-unconstrained-tait.rs:5:24 | -LL | pub type OpaqueBlock = impl Trait; - | ^^^^^^^^^^ +LL | pub type OpaqueBlock = impl Trait; + | ^^^^^^^^^^ | - = note: `OpaqueBlock` must be used in combination with a concrete type within the same module + = note: `OpaqueBlock` must be used in combination with a concrete type within the same crate error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs b/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs index b1d5961067bd..5dda2597c667 100644 --- a/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs +++ b/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs @@ -4,6 +4,7 @@ type Opaque<'lt> = impl Sized + 'lt; +#[define_opaque(Opaque)] fn test<'a>( arg: impl Iterator, ) -> impl Iterator> { diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs index b209b4bc89df..64f926fba9e4 100644 --- a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs +++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs @@ -7,19 +7,21 @@ impl Trait<'_, '_> for T {} mod mod1 { type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + #[define_opaque(Opaque)] fn test<'a>() -> Opaque<'a, 'a> {} //~^ ERROR non-defining opaque type use in defining scope - //~| ERROR non-defining opaque type use in defining scope } mod mod2 { type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + #[define_opaque(Opaque)] fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> {} //~^ ERROR non-defining opaque type use in defining scope } mod mod3 { type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + #[define_opaque(Opaque)] fn test<'a: 'b, 'b: 'a>(a: &'a str) -> Opaque<'a, 'b> { a } //~^ ERROR non-defining opaque type use in defining scope } @@ -30,6 +32,7 @@ mod mod3 { // it is ambiguous whether `Opaque<'a> := &'a ()` or `Opaque<'a> := &'static ()` mod mod4 { type Opaque<'a> = impl super::Trait<'a, 'a>; + #[define_opaque(Opaque)] fn test<'a: 'static>() -> Opaque<'a> {} //~^ ERROR expected generic lifetime parameter, found `'static` } diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr index b08bc8b82687..34af7cb32c27 100644 --- a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr +++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr @@ -1,17 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/equal-lifetime-params-not-ok.rs:10:22 - | -LL | fn test<'a>() -> Opaque<'a, 'a> {} - | ^^^^^^^^^^^^^^ generic argument `'a` used twice - | -note: for this opaque type - --> $DIR/equal-lifetime-params-not-ok.rs:9:27 - | -LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: non-defining opaque type use in defining scope - --> $DIR/equal-lifetime-params-not-ok.rs:10:37 + --> $DIR/equal-lifetime-params-not-ok.rs:11:37 | LL | fn test<'a>() -> Opaque<'a, 'a> {} | ^^ @@ -23,7 +11,7 @@ LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; | ^^ ^^ error: non-defining opaque type use in defining scope - --> $DIR/equal-lifetime-params-not-ok.rs:17:49 + --> $DIR/equal-lifetime-params-not-ok.rs:18:49 | LL | fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> {} | ^^ @@ -35,25 +23,26 @@ LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; | ^^ ^^ error: non-defining opaque type use in defining scope - --> $DIR/equal-lifetime-params-not-ok.rs:23:61 + --> $DIR/equal-lifetime-params-not-ok.rs:25:61 | LL | fn test<'a: 'b, 'b: 'a>(a: &'a str) -> Opaque<'a, 'b> { a } | ^ | note: lifetime used multiple times - --> $DIR/equal-lifetime-params-not-ok.rs:22:17 + --> $DIR/equal-lifetime-params-not-ok.rs:23:17 | LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; | ^^ ^^ error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/equal-lifetime-params-not-ok.rs:33:42 + --> $DIR/equal-lifetime-params-not-ok.rs:36:42 | LL | type Opaque<'a> = impl super::Trait<'a, 'a>; | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +LL | #[define_opaque(Opaque)] LL | fn test<'a: 'static>() -> Opaque<'a> {} | ^^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs b/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs index 0ce85a4d6cbe..711aca662d12 100644 --- a/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs +++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs @@ -12,6 +12,7 @@ impl Trait<'_, '_> for T {} mod equal_params { type Opaque<'a: 'b, 'b: 'a> = impl super::Trait<'a, 'b>; + #[define_opaque(Opaque)] fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> { let _ = None::<&'a &'b &'a ()>; 0u8 @@ -20,6 +21,7 @@ mod equal_params { mod equal_static { type Opaque<'a: 'static> = impl Sized + 'a; + #[define_opaque(Opaque)] fn test<'a: 'static>() -> Opaque<'a> { let _ = None::<&'static &'a ()>; 0u8 diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs index 07206dd2491e..31bdd0815ec3 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -16,6 +16,7 @@ impl Trait<'_> for () { impl Test<'_> for () {} +#[define_opaque(Foo)] fn constrain() -> Foo { () } diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs index 9ed010f2293e..726820bbd5a1 100644 --- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs +++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs @@ -22,10 +22,12 @@ type StateWidget<'a> = impl Widget<&'a ()>; impl Fn(&'a ()) -> StateWidget<'a>> Widget<()> for StatefulWidget { type State = (); + #[define_opaque(StateWidget)] fn make_state(&self) -> Self::State {} //~^ ERROR item does not constrain } +#[define_opaque(StateWidget)] fn new_stateful_widget Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> { //~^ ERROR item does not constrain StatefulWidget(build) diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr index 9a3f4ae4c1c3..4f5c65adab9c 100644 --- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr +++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr @@ -1,31 +1,40 @@ -error: item does not constrain `StateWidget::{opaque#0}`, but has it in its signature - --> $DIR/failed-to-normalize-ice-99945.rs:25:8 +error: item does not constrain `StateWidget::{opaque#0}` + --> $DIR/failed-to-normalize-ice-99945.rs:26:8 | LL | fn make_state(&self) -> Self::State {} | ^^^^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/failed-to-normalize-ice-99945.rs:20:24 | LL | type StateWidget<'a> = impl Widget<&'a ()>; | ^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `StateWidget::{opaque#0}`, but has it in its signature - --> $DIR/failed-to-normalize-ice-99945.rs:29:4 +error: item does not constrain `StateWidget::{opaque#0}` + --> $DIR/failed-to-normalize-ice-99945.rs:31:4 | LL | fn new_stateful_widget Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> { | ^^^^^^^^^^^^^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/failed-to-normalize-ice-99945.rs:20:24 | LL | type StateWidget<'a> = impl Widget<&'a ()>; | ^^^^^^^^^^^^^^^^^^^ +error[E0792]: expected generic lifetime parameter, found `'a` + --> $DIR/failed-to-normalize-ice-99945.rs:33:5 + | +LL | type StateWidget<'a> = impl Widget<&'a ()>; + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | StatefulWidget(build) + | ^^^^^^^^^^^^^^^^^^^^^ + error[E0308]: mismatched types - --> $DIR/failed-to-normalize-ice-99945.rs:36:29 + --> $DIR/failed-to-normalize-ice-99945.rs:38:29 | LL | type StateWidget<'a> = impl Widget<&'a ()>; | ------------------- the expected opaque type @@ -36,15 +45,6 @@ LL | new_stateful_widget(|_| ()).make_state(); = note: expected opaque type `StateWidget<'_>` found unit type `()` -error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/failed-to-normalize-ice-99945.rs:31:5 - | -LL | type StateWidget<'a> = impl Widget<&'a ()>; - | -- this generic parameter must be used with a generic lifetime parameter -... -LL | StatefulWidget(build) - | ^^^^^^^^^^^^^^^^^^^^^ - error: aborting due to 4 previous errors Some errors have detailed explanations: E0308, E0792. diff --git a/tests/ui/type-alias-impl-trait/fallback.rs b/tests/ui/type-alias-impl-trait/fallback.rs index d8cf7d71fef7..a2f25acca0d3 100644 --- a/tests/ui/type-alias-impl-trait/fallback.rs +++ b/tests/ui/type-alias-impl-trait/fallback.rs @@ -7,19 +7,20 @@ type Foo = impl Copy; enum Wrapper { First(T), - Second + Second, } // This method constrains `Foo` to be `bool` +#[define_opaque(Foo)] fn constrained_foo() -> Foo { true } - // This method does not constrain `Foo`. // Per RFC 2071, function bodies may either // fully constrain an opaque type, or place no // constraints on it. +#[define_opaque(Foo)] fn unconstrained_foo() -> Wrapper { Wrapper::Second //~^ ERROR: type annotations needed diff --git a/tests/ui/type-alias-impl-trait/fallback.stderr b/tests/ui/type-alias-impl-trait/fallback.stderr index c909ab66f0ee..1eb0afb13a8d 100644 --- a/tests/ui/type-alias-impl-trait/fallback.stderr +++ b/tests/ui/type-alias-impl-trait/fallback.stderr @@ -1,5 +1,5 @@ error[E0283]: type annotations needed - --> $DIR/fallback.rs:24:5 + --> $DIR/fallback.rs:25:5 | LL | fn unconstrained_foo() -> Wrapper { | ------------ type must be known at this point diff --git a/tests/ui/type-alias-impl-trait/field-types.rs b/tests/ui/type-alias-impl-trait/field-types.rs index 24e430afac3a..3ea73abb03f9 100644 --- a/tests/ui/type-alias-impl-trait/field-types.rs +++ b/tests/ui/type-alias-impl-trait/field-types.rs @@ -1,3 +1,6 @@ +//! Show that `defines(StructName)` works for +//! fields of that struct being an opaque type. + #![feature(type_alias_impl_trait)] #![allow(dead_code)] @@ -11,6 +14,7 @@ struct Bar { foo: Foo, } +#[define_opaque(Bar)] fn bar() -> Bar { Bar { foo: "foo" } } diff --git a/tests/ui/type-alias-impl-trait/future.rs b/tests/ui/type-alias-impl-trait/future.rs index 36d1dcd00ad1..e233554f6a13 100644 --- a/tests/ui/type-alias-impl-trait/future.rs +++ b/tests/ui/type-alias-impl-trait/future.rs @@ -11,6 +11,7 @@ trait Bar { type FooFuture = impl Future; +#[define_opaque(FooFuture)] fn foo(bar: B) -> FooFuture { async move { bar.bar() } //~^ ERROR: the trait bound `B: Bar` is not satisfied diff --git a/tests/ui/type-alias-impl-trait/future.stderr b/tests/ui/type-alias-impl-trait/future.stderr index 047ad164239c..8510ab27fb75 100644 --- a/tests/ui/type-alias-impl-trait/future.stderr +++ b/tests/ui/type-alias-impl-trait/future.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `B: Bar` is not satisfied - --> $DIR/future.rs:15:5 + --> $DIR/future.rs:16:5 | LL | async move { bar.bar() } | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B` | note: required by a bound in `foo` - --> $DIR/future.rs:14:11 + --> $DIR/future.rs:15:11 | LL | fn foo(bar: B) -> FooFuture { | ^^^ required by this bound in `foo` diff --git a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr index e5f86c8c1935..43e887f36c5f 100644 --- a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr +++ b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/generic-not-strictly-equal.rs:33:5 + --> $DIR/generic-not-strictly-equal.rs:34:5 | LL | type Opaque<'a> = impl Copy + Captures<'a>; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr index 693af69d6fab..4a5360c9922e 100644 --- a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr +++ b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr @@ -1,9 +1,9 @@ error[E0700]: hidden type for `Opaque<'x>` captures lifetime that does not appear in bounds - --> $DIR/generic-not-strictly-equal.rs:33:5 + --> $DIR/generic-not-strictly-equal.rs:34:5 | LL | type Opaque<'a> = impl Copy + Captures<'a>; | ------------------------ opaque type defined here -LL | +... LL | fn test<'x>(_: Opaque<'x>) { | -- hidden type `&'x u8` captures the lifetime `'x` as defined here ... diff --git a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs index a059fd3b8227..c1059e3da334 100644 --- a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs +++ b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs @@ -20,6 +20,7 @@ fn relate(_: X, _: X) {} type Opaque<'a> = impl Copy + Captures<'a>; +#[define_opaque(Opaque)] fn test<'x>(_: Opaque<'x>) { let opaque = None::>; // let's call this lifetime '?1 diff --git a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs index 8b683ad28288..d55a9a376b9f 100644 --- a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs +++ b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs @@ -4,10 +4,12 @@ fn main() {} type MyIter = impl Iterator; +#[define_opaque(MyIter)] fn my_iter(t: T) -> MyIter { std::iter::once(t) } +#[define_opaque(MyIter)] fn my_iter2(t: T) -> MyIter { Some(t).into_iter() //~^ ERROR concrete type differs from previous diff --git a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr index 72271d158a1a..6d3279144d8f 100644 --- a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr +++ b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_different_defining_uses.rs:12:5 + --> $DIR/generic_different_defining_uses.rs:14:5 | LL | Some(t).into_iter() | ^^^^^^^^^^^^^^^^^^^ expected `std::iter::Once`, got `std::option::IntoIter` | note: previous use here - --> $DIR/generic_different_defining_uses.rs:8:5 + --> $DIR/generic_different_defining_uses.rs:9:5 | LL | std::iter::once(t) | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs index 169d4f8d5094..45da4145278e 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs @@ -4,8 +4,8 @@ fn main() {} type Two<'a, 'b> = impl std::fmt::Debug; +#[define_opaque(Two)] fn one<'a>(t: &'a ()) -> Two<'a, 'a> { - //~^ ERROR non-defining opaque type use t //~^ ERROR non-defining opaque type use } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index b03bf2466e60..352e6fd3c5c8 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,15 +1,3 @@ -error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:7:26 - | -LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> { - | ^^^^^^^^^^^ generic argument `'a` used twice - | -note: for this opaque type - --> $DIR/generic_duplicate_lifetime_param.rs:5:20 - | -LL | type Two<'a, 'b> = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ - error: non-defining opaque type use in defining scope --> $DIR/generic_duplicate_lifetime_param.rs:9:5 | @@ -22,5 +10,5 @@ note: lifetime used multiple times LL | type Two<'a, 'b> = impl std::fmt::Debug; | ^^ ^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs index e3c6f4d874bc..e8ed38a24ceb 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -18,20 +18,20 @@ type TwoLifetimes<'a, 'b> = impl Debug; type TwoConsts = impl Debug; +#[define_opaque(TwoTys)] fn one_ty(t: T) -> TwoTys { - //~^ ERROR non-defining opaque type use in defining scope t //~^ ERROR non-defining opaque type use in defining scope } +#[define_opaque(TwoLifetimes)] fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { - //~^ ERROR non-defining opaque type use in defining scope t //~^ ERROR non-defining opaque type use in defining scope } +#[define_opaque(TwoConsts)] fn one_const(t: *mut [u8; N]) -> TwoConsts { - //~^ ERROR non-defining opaque type use in defining scope t //~^ ERROR non-defining opaque type use in defining scope } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr index 73570de53266..3e048c8138d0 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr @@ -1,15 +1,3 @@ -error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:21:30 - | -LL | fn one_ty(t: T) -> TwoTys { - | ^^^^^^^^^^^^ generic argument `T` used twice - | -note: for this opaque type - --> $DIR/generic_duplicate_param_use.rs:15:21 - | -LL | type TwoTys = impl Debug; - | ^^^^^^^^^^ - error: non-defining opaque type use in defining scope --> $DIR/generic_duplicate_param_use.rs:23:5 | @@ -22,30 +10,6 @@ note: type used multiple times LL | type TwoTys = impl Debug; | ^ ^ -error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:27:36 - | -LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { - | ^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice - | -note: for this opaque type - --> $DIR/generic_duplicate_param_use.rs:17:29 - | -LL | type TwoLifetimes<'a, 'b> = impl Debug; - | ^^^^^^^^^^ - -error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:33:50 - | -LL | fn one_const(t: *mut [u8; N]) -> TwoConsts { - | ^^^^^^^^^^^^^^^ generic argument `N` used twice - | -note: for this opaque type - --> $DIR/generic_duplicate_param_use.rs:19:50 - | -LL | type TwoConsts = impl Debug; - | ^^^^^^^^^^ - error: non-defining opaque type use in defining scope --> $DIR/generic_duplicate_param_use.rs:29:5 | @@ -70,5 +34,5 @@ note: constant used multiple times LL | type TwoConsts = impl Debug; | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs index 439214911eb9..849d237b8095 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs @@ -7,6 +7,7 @@ fn main() {} type Two = impl Debug; +#[define_opaque(Two)] fn two(t: T, _: U) -> Two { (t, 4u32) } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs index 201535efe153..073684b8adde 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs @@ -7,6 +7,7 @@ fn main() {} // test that unused generic parameters are ok type Two = impl Debug; +#[define_opaque(Two)] fn two(t: T, _: U) -> Two { t //~^ ERROR `T` doesn't implement `Debug` diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr index cd6e85764bda..ef0e73f1481f 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr @@ -1,5 +1,5 @@ error[E0277]: `T` doesn't implement `Debug` - --> $DIR/generic_duplicate_param_use2.rs:11:5 + --> $DIR/generic_duplicate_param_use2.rs:12:5 | LL | t | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` @@ -10,7 +10,7 @@ note: required by a bound in an opaque type LL | type Two = impl Debug; | ^^^^^ note: this definition site has more where clauses than the opaque type - --> $DIR/generic_duplicate_param_use2.rs:10:1 + --> $DIR/generic_duplicate_param_use2.rs:11:1 | LL | fn two(t: T, _: U) -> Two { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs index 2074f12750f6..f732b2333961 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs @@ -7,10 +7,12 @@ fn main() {} // test that unused generic parameters are ok type Two = impl Debug; +#[define_opaque(Two)] fn two(t: T, _: U) -> Two { t } +#[define_opaque(Two)] fn three(_: T, u: U) -> Two { u //~^ ERROR concrete type differs diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr index 9a10a4980d80..b0a1bd77f857 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use3.rs:15:5 + --> $DIR/generic_duplicate_param_use3.rs:17:5 | LL | u | ^ expected `T`, got `U` | note: previous use here - --> $DIR/generic_duplicate_param_use3.rs:11:5 + --> $DIR/generic_duplicate_param_use3.rs:12:5 | LL | t | ^ diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs index d1e5a0f0198b..68a8f3da168b 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs @@ -7,6 +7,7 @@ fn main() {} // test that unused generic parameters are ok type Two = impl Debug; +#[define_opaque(Two)] fn three(_: T, u: U) -> Two { u //~^ ERROR `U` doesn't implement `Debug` diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr index bf3c4a0e04fe..0932c72ff934 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr @@ -1,5 +1,5 @@ error[E0277]: `U` doesn't implement `Debug` - --> $DIR/generic_duplicate_param_use4.rs:11:5 + --> $DIR/generic_duplicate_param_use4.rs:12:5 | LL | u | ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` @@ -10,7 +10,7 @@ note: required by a bound in an opaque type LL | type Two = impl Debug; | ^^^^^ note: this definition site has more where clauses than the opaque type - --> $DIR/generic_duplicate_param_use4.rs:10:1 + --> $DIR/generic_duplicate_param_use4.rs:11:1 | LL | fn three(_: T, u: U) -> Two { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs index b3d6beaf8486..d450bef57581 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs @@ -7,10 +7,12 @@ fn main() {} // test that unused generic parameters are ok type Two = impl Debug; +#[define_opaque(Two)] fn two(t: T, u: U) -> Two { (t, u) } +#[define_opaque(Two)] fn three(t: T, u: U) -> Two { (u, t) //~^ ERROR concrete type differs diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr index b0027f8fa57b..b8a2a9374161 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use5.rs:15:5 + --> $DIR/generic_duplicate_param_use5.rs:17:5 | LL | (u, t) | ^^^^^^ expected `(T, U)`, got `(U, T)` | note: previous use here - --> $DIR/generic_duplicate_param_use5.rs:11:5 + --> $DIR/generic_duplicate_param_use5.rs:12:5 | LL | (t, u) | ^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs index fa8b2a290b93..24d03b9e60d2 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs @@ -7,10 +7,12 @@ fn main() {} // test that unused generic parameters are ok type Two = impl Debug; +#[define_opaque(Two)] fn two(t: T, u: U) -> Two { (t, t) } +#[define_opaque(Two)] fn three(t: T, u: U) -> Two { (u, t) //~^ ERROR concrete type differs diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr index 09c01932cef7..983e58d3c702 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use6.rs:15:5 + --> $DIR/generic_duplicate_param_use6.rs:17:5 | LL | (u, t) | ^^^^^^ expected `(T, T)`, got `(U, T)` | note: previous use here - --> $DIR/generic_duplicate_param_use6.rs:11:5 + --> $DIR/generic_duplicate_param_use6.rs:12:5 | LL | (t, t) | ^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs index adc912294fdf..6f4a81ed760a 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs @@ -7,18 +7,22 @@ fn main() {} type Two = impl Debug; +#[define_opaque(Two)] fn two(t: T, u: U) -> Two { (t, t) } +#[define_opaque(Two)] fn three(t: T, t2: T, u: U) -> Two { (t, t2) } +#[define_opaque(Two)] fn four(t: T, t2: T, u: U, v: V) -> Two { (t, t2) } +#[define_opaque(Two)] fn five(x: X, y: Y, y2: Y) -> Two { (y, y2) } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs index 76c13bb027b0..03057c847825 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs @@ -6,10 +6,12 @@ fn main() {} type Two = impl Debug; +#[define_opaque(Two)] fn two(t: T, _: U) -> Two { (t, 4u32) } +#[define_opaque(Two)] fn three(_: T, u: U) -> Two { (u, 4u32) //~^ concrete type differs diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr index 09d2abe36636..48c98c1e2b15 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use8.rs:14:5 + --> $DIR/generic_duplicate_param_use8.rs:16:5 | LL | (u, 4u32) | ^^^^^^^^^ expected `(T, u32)`, got `(U, u32)` | note: previous use here - --> $DIR/generic_duplicate_param_use8.rs:10:5 + --> $DIR/generic_duplicate_param_use8.rs:11:5 | LL | (t, 4u32) | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs index 5da7aab0da7a..74176550ab24 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs @@ -11,10 +11,12 @@ trait Foo { const BAR: Self::Bar; } +#[define_opaque(Two)] fn two(t: T, u: U) -> Two { (t, u, T::BAR) } +#[define_opaque(Two)] fn three(t: T, u: U) -> Two { (t, u, 42) //~^ ERROR concrete type differs diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr index 6e1bb3dfa174..542324c949f1 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use9.rs:19:5 + --> $DIR/generic_duplicate_param_use9.rs:21:5 | LL | (t, u, 42) | ^^^^^^^^^^ expected `(A, B, ::Bar)`, got `(A, B, i32)` | note: previous use here - --> $DIR/generic_duplicate_param_use9.rs:15:5 + --> $DIR/generic_duplicate_param_use9.rs:16:5 | LL | (t, u, T::BAR) | ^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs b/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs index b9b34f55e7e2..d5fb1b461ec4 100644 --- a/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs +++ b/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs @@ -6,6 +6,7 @@ fn main() {} type Region<'a> = impl std::fmt::Debug; +#[define_opaque(Region)] fn region<'b>(a: &'b ()) -> Region<'b> { a } diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs index 68f4c6923ae1..7791410294c0 100644 --- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs +++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -12,20 +12,20 @@ type OneConst = impl Debug; // Not defining uses, because they doesn't define *all* possible generics. +#[define_opaque(OneTy)] fn concrete_ty() -> OneTy { - //~^ ERROR: non-defining opaque type use in defining scope 5u32 //~^ ERROR: expected generic type parameter, found `u32` } +#[define_opaque(OneLifetime)] fn concrete_lifetime() -> OneLifetime<'static> { - //~^ ERROR: non-defining opaque type use in defining scope 6u32 //~^ ERROR: expected generic lifetime parameter, found `'static` } +#[define_opaque(OneConst)] fn concrete_const() -> OneConst<{ 123 }> { - //~^ ERROR: non-defining opaque type use in defining scope 7u32 //~^ ERROR: expected generic constant parameter, found `123` } diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr index bd68b4e3ea46..1b0ce7cc619f 100644 --- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -1,15 +1,3 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:15:21 - | -LL | fn concrete_ty() -> OneTy { - | ^^^^^^^^^^ argument `u32` is not a generic parameter - | -note: for this opaque type - --> $DIR/generic_nondefining_use.rs:7:17 - | -LL | type OneTy = impl Debug; - | ^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `u32` --> $DIR/generic_nondefining_use.rs:17:5 | @@ -19,30 +7,6 @@ LL | type OneTy = impl Debug; LL | 5u32 | ^^^^ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:21:27 - | -LL | fn concrete_lifetime() -> OneLifetime<'static> { - | ^^^^^^^^^^^^^^^^^^^^ argument `'static` is not a generic parameter - | -note: for this opaque type - --> $DIR/generic_nondefining_use.rs:9:24 - | -LL | type OneLifetime<'a> = impl Debug; - | ^^^^^^^^^^ - -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:27:24 - | -LL | fn concrete_const() -> OneConst<{ 123 }> { - | ^^^^^^^^^^^^^^^^^ argument `123` is not a generic parameter - | -note: for this opaque type - --> $DIR/generic_nondefining_use.rs:11:33 - | -LL | type OneConst = impl Debug; - | ^^^^^^^^^^ - error[E0792]: expected generic lifetime parameter, found `'static` --> $DIR/generic_nondefining_use.rs:23:5 | @@ -61,6 +25,6 @@ LL | type OneConst = impl Debug; LL | 7u32 | ^^^^ -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/generic_not_used.rs b/tests/ui/type-alias-impl-trait/generic_not_used.rs index c70f473cff57..6042cdd30a94 100644 --- a/tests/ui/type-alias-impl-trait/generic_not_used.rs +++ b/tests/ui/type-alias-impl-trait/generic_not_used.rs @@ -5,6 +5,7 @@ fn main() {} type WrongGeneric = impl 'static; //~^ ERROR: at least one trait must be specified +#[define_opaque(WrongGeneric)] fn wrong_generic(_: U, v: V) -> WrongGeneric { v //~^ ERROR type parameter `V` is part of concrete type but not used in parameter list diff --git a/tests/ui/type-alias-impl-trait/generic_not_used.stderr b/tests/ui/type-alias-impl-trait/generic_not_used.stderr index fd720239a523..5fe2fefcecfd 100644 --- a/tests/ui/type-alias-impl-trait/generic_not_used.stderr +++ b/tests/ui/type-alias-impl-trait/generic_not_used.stderr @@ -5,7 +5,7 @@ LL | type WrongGeneric = impl 'static; | ^^^^^^^^^^^^ error: type parameter `V` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/generic_not_used.rs:9:5 + --> $DIR/generic_not_used.rs:10:5 | LL | v | ^ diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs index c60f5c11cd18..4b8a1cfc4724 100644 --- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs +++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -9,6 +9,7 @@ fn main() { type WrongGeneric = impl 'static; //~^ ERROR: at least one trait must be specified + #[define_opaque(WrongGeneric)] fn wrong_generic(t: T) -> WrongGeneric { t //~^ ERROR the parameter type `T` may not live long enough diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index c352a33fbbcf..2b3f7d750283 100644 --- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr +++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -14,7 +14,7 @@ LL | type WrongGeneric = impl 'static; | - this generic parameter must be used with a generic type parameter error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:13:9 + --> $DIR/generic_type_does_not_live_long_enough.rs:14:9 | LL | t | ^ diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained.rs b/tests/ui/type-alias-impl-trait/generic_underconstrained.rs index 1acacc778de6..9c2180e92fc6 100644 --- a/tests/ui/type-alias-impl-trait/generic_underconstrained.rs +++ b/tests/ui/type-alias-impl-trait/generic_underconstrained.rs @@ -6,6 +6,7 @@ trait Trait {} type Underconstrained = impl Send; // no `Trait` bound +#[define_opaque(Underconstrained)] fn underconstrain(_: T) -> Underconstrained { //~^ ERROR the trait bound `T: Trait` //~| ERROR the trait bound `T: Trait` diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr index c24f8fd867fb..b1bc62c5910e 100644 --- a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr +++ b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/generic_underconstrained.rs:9:31 + --> $DIR/generic_underconstrained.rs:10:31 | LL | fn underconstrain(_: T) -> Underconstrained { | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` @@ -15,7 +15,7 @@ LL | fn underconstrain(_: T) -> Underconstrained { | +++++++ error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/generic_underconstrained.rs:9:31 + --> $DIR/generic_underconstrained.rs:10:31 | LL | fn underconstrain(_: T) -> Underconstrained { | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs b/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs index 1e1bece9a1c0..f05f9776006d 100644 --- a/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs +++ b/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs @@ -5,6 +5,7 @@ fn main() {} type Underconstrained = impl Send; // not a defining use, because it doesn't define *all* possible generics +#[define_opaque(Underconstrained)] fn underconstrained(_: U) -> Underconstrained { //~^ ERROR `U` doesn't implement `Debug` //~| ERROR `U` doesn't implement `Debug` @@ -14,6 +15,7 @@ fn underconstrained(_: U) -> Underconstrained { type Underconstrained2 = impl Send; // not a defining use, because it doesn't define *all* possible generics +#[define_opaque(Underconstrained2)] fn underconstrained2(_: U, _: V) -> Underconstrained2 { //~^ ERROR `V` doesn't implement `Debug` //~| ERROR `V` doesn't implement `Debug` diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr index 93df5ddca796..429c3b9175a5 100644 --- a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr +++ b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr @@ -1,5 +1,5 @@ error[E0277]: `U` doesn't implement `Debug` - --> $DIR/generic_underconstrained2.rs:8:33 + --> $DIR/generic_underconstrained2.rs:9:33 | LL | fn underconstrained(_: U) -> Underconstrained { | ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` @@ -15,13 +15,13 @@ LL | fn underconstrained(_: U) -> Underconstrained { | +++++++++++++++++ error[E0277]: `V` doesn't implement `Debug` - --> $DIR/generic_underconstrained2.rs:17:43 + --> $DIR/generic_underconstrained2.rs:19:43 | LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { | ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug` | note: required by a bound on the type alias `Underconstrained2` - --> $DIR/generic_underconstrained2.rs:14:27 + --> $DIR/generic_underconstrained2.rs:15:27 | LL | type Underconstrained2 = impl Send; | ^^^^^^^^^^^^^^^ required by this bound @@ -31,7 +31,7 @@ LL | fn underconstrained2(_: U, _: V) -> Underconstrained | +++++++++++++++++ error[E0277]: `U` doesn't implement `Debug` - --> $DIR/generic_underconstrained2.rs:8:33 + --> $DIR/generic_underconstrained2.rs:9:33 | LL | fn underconstrained(_: U) -> Underconstrained { | ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` @@ -48,13 +48,13 @@ LL | fn underconstrained(_: U) -> Underconstrained { | +++++++++++++++++ error[E0277]: `V` doesn't implement `Debug` - --> $DIR/generic_underconstrained2.rs:17:43 + --> $DIR/generic_underconstrained2.rs:19:43 | LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { | ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug` | note: required by a bound on the type alias `Underconstrained2` - --> $DIR/generic_underconstrained2.rs:14:27 + --> $DIR/generic_underconstrained2.rs:15:27 | LL | type Underconstrained2 = impl Send; | ^^^^^^^^^^^^^^^ required by this bound diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs index eb19b49c7e21..bf97dd9a25c5 100644 --- a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs +++ b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs @@ -15,6 +15,7 @@ trait Trait: Sized { impl Trait for Bar { type Assoc = impl std::fmt::Debug; + //~^ ERROR: unconstrained opaque type fn foo() -> Foo { Foo { field: () } //~^ ERROR: mismatched types diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr index 00aedfae4637..879f024dee71 100644 --- a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr +++ b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr @@ -1,20 +1,23 @@ +error: unconstrained opaque type + --> $DIR/hidden_behind_projection_behind_struct_field.rs:17:18 + | +LL | type Assoc = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Assoc` must be used in combination with a concrete type within the same impl + error[E0308]: mismatched types - --> $DIR/hidden_behind_projection_behind_struct_field.rs:19:22 + --> $DIR/hidden_behind_projection_behind_struct_field.rs:20:22 | LL | type Assoc = impl std::fmt::Debug; | -------------------- the expected opaque type -LL | fn foo() -> Foo { +... LL | Foo { field: () } | ^^ expected opaque type, found `()` | = note: expected opaque type `::Assoc` found unit type `()` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/hidden_behind_projection_behind_struct_field.rs:18:8 - | -LL | fn foo() -> Foo { - | ^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs index 3117060cef0d..b1dcf98f4dd2 100644 --- a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs +++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs @@ -13,6 +13,7 @@ trait Trait: Sized { impl Trait for Bar { type Assoc = impl std::fmt::Debug; + //~^ ERROR: unconstrained opaque type fn foo() -> Foo { Foo { field: () } //~^ ERROR: mismatched types diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr index 4910e794e8d6..1820560eaddd 100644 --- a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr +++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr @@ -1,20 +1,23 @@ +error: unconstrained opaque type + --> $DIR/hidden_behind_struct_field2.rs:15:18 + | +LL | type Assoc = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Assoc` must be used in combination with a concrete type within the same impl + error[E0308]: mismatched types - --> $DIR/hidden_behind_struct_field2.rs:17:22 + --> $DIR/hidden_behind_struct_field2.rs:18:22 | LL | type Assoc = impl std::fmt::Debug; | -------------------- the expected opaque type -LL | fn foo() -> Foo { +... LL | Foo { field: () } | ^^ expected opaque type, found `()` | = note: expected opaque type `::Assoc` found unit type `()` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/hidden_behind_struct_field2.rs:16:8 - | -LL | fn foo() -> Foo { - | ^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs index c1f135994121..70697e2fa658 100644 --- a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs +++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs @@ -14,6 +14,7 @@ trait Trait: Sized { impl Trait for Bar { type Assoc2 = impl std::fmt::Debug; + //~^ ERROR: unconstrained opaque type type Assoc = impl Iterator; fn foo() -> Self::Assoc { vec![Foo { field: () }].into_iter() diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr index f10ccc002997..9ce696fa26c4 100644 --- a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr +++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr @@ -1,5 +1,13 @@ +error: unconstrained opaque type + --> $DIR/hidden_behind_struct_field3.rs:16:19 + | +LL | type Assoc2 = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Assoc2` must be used in combination with a concrete type within the same impl + error[E0308]: mismatched types - --> $DIR/hidden_behind_struct_field3.rs:19:27 + --> $DIR/hidden_behind_struct_field3.rs:20:27 | LL | type Assoc2 = impl std::fmt::Debug; | -------------------- the expected opaque type @@ -9,12 +17,7 @@ LL | vec![Foo { field: () }].into_iter() | = note: expected opaque type `::Assoc2` found unit type `()` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/hidden_behind_struct_field3.rs:18:8 - | -LL | fn foo() -> Self::Assoc { - | ^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/hidden_type_mismatch.rs b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.rs index 5b5acb31812f..0a8860321daa 100644 --- a/tests/ui/type-alias-impl-trait/hidden_type_mismatch.rs +++ b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.rs @@ -9,6 +9,7 @@ mod sus { use super::*; pub type Sep = impl Sized + std::fmt::Display; + #[define_opaque(Sep)] pub fn mk_sep() -> Sep { String::from("hello") } @@ -34,6 +35,7 @@ mod sus { // `define_tait` is not actually callable, and thus assumed // `Bar<()>: Copy` even though it isn't. pub type Tait = impl Copy + From> + Into>; + #[define_opaque(Tait)] pub fn define_tait() -> Tait where // this proves `Bar<()>: Copy`, but `define_tait` is diff --git a/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr index 8547fd53c18e..20991a30b531 100644 --- a/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr +++ b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `<() as Proj>::Assoc == i32` - --> $DIR/hidden_type_mismatch.rs:43:9 + --> $DIR/hidden_type_mismatch.rs:45:9 | LL | pub type Sep = impl Sized + std::fmt::Display; | ------------------------------ the found opaque type @@ -8,26 +8,26 @@ LL | Bar { inner: 1i32, _marker: () } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Proj>::Assoc == i32` | note: expected this to be `i32` - --> $DIR/hidden_type_mismatch.rs:20:22 + --> $DIR/hidden_type_mismatch.rs:21:22 | LL | type Assoc = sus::Sep; | ^^^^^^^^ = note: expected type `i32` found opaque type `Sep` note: required for `Bar<()>` to implement `Copy` - --> $DIR/hidden_type_mismatch.rs:32:39 + --> $DIR/hidden_type_mismatch.rs:33:39 | LL | impl + Copy> Copy for Bar {} | ----------- ^^^^ ^^^^^^ | | | unsatisfied trait bound introduced here note: required by a bound in an opaque type - --> $DIR/hidden_type_mismatch.rs:36:26 + --> $DIR/hidden_type_mismatch.rs:37:26 | LL | pub type Tait = impl Copy + From> + Into>; | ^^^^ note: this definition site has more where clauses than the opaque type - --> $DIR/hidden_type_mismatch.rs:37:5 + --> $DIR/hidden_type_mismatch.rs:39:5 | LL | / pub fn define_tait() -> Tait LL | | where diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params.rs index e43f53e40578..6008df3b0a2f 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params.rs +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params.rs @@ -22,6 +22,7 @@ struct Terminator; type Successors<'a> = impl std::fmt::Debug + 'a; impl Terminator { + #[define_opaque(Successors)] fn successors(&self, _: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {} } diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs index 19c6099135d8..8ed7c1336f26 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs @@ -2,6 +2,7 @@ //! and normalizing something behind them actually works. //@ edition: 2021 +//@ check-pass #![feature(type_alias_impl_trait)] @@ -22,9 +23,9 @@ struct Terminator; type Successors<'a> = impl std::fmt::Debug + 'a; impl Terminator { + #[define_opaque(Successors, Tait)] fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { f = g; - //~^ ERROR mismatched types } } diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr b/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr deleted file mode 100644 index 790e7fe85803..000000000000 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/higher_kinded_params2.rs:26:13 - | -LL | type Tait = impl std::fmt::Debug; - | -------------------- the expected opaque type -... -LL | f = g; - | ^ expected fn pointer, found fn item - | - = note: expected fn pointer `for<'x> fn(&'x ()) -> Tait` - found fn item `for<'a> fn(&'a ()) -> String {g}` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/higher_kinded_params2.rs:25:8 - | -LL | fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { - | ^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs index 3845cde29fa5..4fb2e60b5c5a 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs @@ -22,6 +22,7 @@ struct Terminator; type Successors<'a> = impl std::fmt::Debug + 'a; impl Terminator { + #[define_opaque(Successors, Tait)] fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { f = g; //~^ ERROR mismatched types diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr index 41a3f9ce2682..558792987f31 100644 --- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr +++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr @@ -1,19 +1,14 @@ error[E0308]: mismatched types - --> $DIR/higher_kinded_params3.rs:26:13 + --> $DIR/higher_kinded_params3.rs:27:9 | LL | type Tait<'a> = impl std::fmt::Debug + 'a; | ------------------------- the expected opaque type ... LL | f = g; - | ^ expected fn pointer, found fn item + | ^^^^^ one type is more general than the other | = note: expected fn pointer `for<'x> fn(&'x ()) -> Tait<'x>` - found fn item `for<'a> fn(&'a ()) -> &'a () {g}` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/higher_kinded_params3.rs:25:8 - | -LL | fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> { - | ^^^^^^^^^^ + found fn pointer `for<'a> fn(&'a ()) -> &'a ()` error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden.rs index c6d1202ef85f..994adc476e24 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden.rs @@ -6,6 +6,7 @@ fn id(s: &str) -> &str { type Opaque<'a> = impl Sized + 'a; +#[define_opaque(Opaque)] fn test(s: &str) -> (impl Fn(&str) -> Opaque<'_>, impl Fn(&str) -> Opaque<'_>) { (id, id) //~ ERROR expected generic lifetime parameter, found `'_` } @@ -16,22 +17,26 @@ fn id2<'a, 'b>(s: (&'a str, &'b str)) -> (&'a str, &'b str) { type Opaque2<'a> = impl Sized + 'a; +#[define_opaque(Opaque2)] fn test2() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque2<'a>, Opaque2<'b>) { id2 //~ ERROR expected generic lifetime parameter, found `'a` } type Opaque3<'a> = impl Sized + 'a; +#[define_opaque(Opaque3)] fn test3(s: &str) -> (impl Fn(&str) -> Opaque3<'_>, Opaque3<'_>) { (id, s) //~ ERROR expected generic lifetime parameter, found `'_` } type Opaque4<'a> = impl Sized + 'a; +#[define_opaque(Opaque4)] fn test4(s: &str) -> (Opaque4<'_>, impl Fn(&str) -> Opaque4<'_>) { (s, id) //~ ERROR expected generic lifetime parameter, found `'_` } type Inner<'a> = impl Sized; +#[define_opaque(Inner)] fn outer_impl() -> impl for<'a> Fn(&'a ()) -> Inner<'a> { |x| x //~ ERROR expected generic lifetime parameter, found `'a` } diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden.stderr index d49be73d94e7..d404d60f31ed 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/hkl_forbidden.rs:10:5 + --> $DIR/hkl_forbidden.rs:11:5 | LL | type Opaque<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter @@ -8,7 +8,7 @@ LL | (id, id) | ^^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/hkl_forbidden.rs:20:5 + --> $DIR/hkl_forbidden.rs:22:5 | LL | type Opaque2<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter @@ -17,7 +17,7 @@ LL | id2 | ^^^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/hkl_forbidden.rs:26:5 + --> $DIR/hkl_forbidden.rs:29:5 | LL | type Opaque3<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter @@ -26,20 +26,20 @@ LL | (id, s) | ^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/hkl_forbidden.rs:31:5 + --> $DIR/hkl_forbidden.rs:35:5 | LL | type Opaque4<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter -LL | fn test4(s: &str) -> (Opaque4<'_>, impl Fn(&str) -> Opaque4<'_>) { +... LL | (s, id) | ^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/hkl_forbidden.rs:36:5 + --> $DIR/hkl_forbidden.rs:41:5 | LL | type Inner<'a> = impl Sized; | -- this generic parameter must be used with a generic lifetime parameter -LL | fn outer_impl() -> impl for<'a> Fn(&'a ()) -> Inner<'a> { +... LL | |x| x | ^^^^^ diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden2.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden2.rs index 3d583d4413d9..92e383d11f1c 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden2.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden2.rs @@ -10,6 +10,7 @@ impl<'a> Trait<'a> for () { type Assoc = (); } +#[define_opaque(Opaque)] fn test() -> &'static dyn for<'a> Trait<'a, Assoc = Opaque<'a>> { &() //~^ ERROR: expected generic lifetime parameter, found `'a` diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr index 0a9a9d6bcf4e..7404c844ae7b 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/hkl_forbidden2.rs:14:5 + --> $DIR/hkl_forbidden2.rs:15:5 | LL | type Opaque<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs index a4148599f77a..c7f04dc07bb1 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs @@ -6,6 +6,7 @@ fn foo<'a>(x: &'a ()) -> &'a () { x } +#[define_opaque(Opaque)] fn test() -> for<'a> fn(&'a ()) -> Opaque<'a> { foo //~ ERROR: mismatched types } diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr index d262177a86bc..b8c04185a7d1 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/hkl_forbidden3.rs:10:5 + --> $DIR/hkl_forbidden3.rs:11:5 | LL | type Opaque<'a> = impl Sized + 'a; | --------------- the expected opaque type diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs index fd06ea677c33..7e010918b294 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs @@ -15,6 +15,7 @@ async fn operation(_: &mut ()) -> () { //~^ ERROR: expected generic lifetime parameter, found `'any` } +#[define_opaque(FutNothing)] async fn call(_f: F) //~^ ERROR item does not constrain where diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index feb161c3b048..2ca6a1994485 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -1,3 +1,31 @@ +error: item does not constrain `FutNothing::{opaque#0}` + --> $DIR/hkl_forbidden4.rs:19:10 + | +LL | async fn call(_f: F) + | ^^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/hkl_forbidden4.rs:10:23 + | +LL | type FutNothing<'a> = impl 'a + Future; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `FutNothing::{opaque#0}` + --> $DIR/hkl_forbidden4.rs:23:1 + | +LL | / { +... | +LL | | } + | |_^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/hkl_forbidden4.rs:10:23 + | +LL | type FutNothing<'a> = impl 'a + Future; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: concrete type differs from previous defining opaque type use --> $DIR/hkl_forbidden4.rs:12:1 | @@ -10,34 +38,6 @@ note: previous use here LL | call(operation).await | ^^^^^^^^^^^^^^^ -error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature - --> $DIR/hkl_forbidden4.rs:18:10 - | -LL | async fn call(_f: F) - | ^^^^ - | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/hkl_forbidden4.rs:10:23 - | -LL | type FutNothing<'a> = impl 'a + Future; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature - --> $DIR/hkl_forbidden4.rs:22:1 - | -LL | / { -... | -LL | | } - | |_^ - | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/hkl_forbidden4.rs:10:23 - | -LL | type FutNothing<'a> = impl 'a + Future; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0792]: expected generic lifetime parameter, found `'any` --> $DIR/hkl_forbidden4.rs:14:5 | @@ -48,7 +48,7 @@ LL | call(operation).await | ^^^^^^^^^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:22:1 + --> $DIR/hkl_forbidden4.rs:23:1 | LL | type FutNothing<'a> = impl 'a + Future; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs index 2bcb8f06f4fd..29e7c7d19fc6 100644 --- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs +++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs @@ -18,6 +18,7 @@ trait MyFrom: Sized { trait F {} impl F for () {} type DummyT = impl F; +#[define_opaque(DummyT)] fn _dummy_t() -> DummyT {} struct Phantom1(PhantomData); @@ -25,6 +26,7 @@ struct Phantom2(PhantomData); struct Scope(Phantom2>); impl Scope { + #[define_opaque(DummyT)] fn new() -> Self { //~^ ERROR item does not constrain unimplemented!() @@ -41,6 +43,7 @@ impl MyFrom> for Phantom1 { impl>>, U> MyIndex> for Scope { //~^ ERROR the type parameter `T` is not constrained by the impl type O = T; + #[define_opaque(DummyT)] fn my_index(self) -> Self::O { MyFrom::my_from(self.0).ok().unwrap() } diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr index 0ab4c34381a2..d18a824287c0 100644 --- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr +++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr @@ -1,17 +1,17 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6 + --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:43:6 | LL | impl>>, U> MyIndex> for Scope { | ^ unconstrained type parameter -error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature - --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:28:8 +error: item does not constrain `DummyT::{opaque#0}` + --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:30:8 | LL | fn new() -> Self { | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:20:18 | LL | type DummyT = impl F; diff --git a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.rs b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.rs index 71416eb531ac..a9cae611ec55 100644 --- a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.rs +++ b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.rs @@ -18,6 +18,7 @@ impl Foo for () { type Baz = impl Sized; //~^ ERROR type `Baz` has 1 type parameter but its trait declaration has 0 type parameters + //~| ERROR: unconstrained opaque type fn test<'a>() -> Self::Bar<'a> { &() diff --git a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr index e5a21ff8b4e8..13f5d8b8ea6e 100644 --- a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr +++ b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr @@ -7,6 +7,14 @@ LL | type Baz<'a>; LL | type Baz = impl Sized; | ^ found 1 type parameter -error: aborting due to 1 previous error +error: unconstrained opaque type + --> $DIR/impl-trait-in-type-alias-with-bad-substs.rs:19:19 + | +LL | type Baz = impl Sized; + | ^^^^^^^^^^ + | + = note: `Baz` must be used in combination with a concrete type within the same impl + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs b/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs index 00d1a1a226d2..b50345bb637c 100644 --- a/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs +++ b/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs @@ -7,6 +7,7 @@ auto trait Trait {} impl Trait for Alias {} //~^ ERROR traits with a default impl, like `Trait`, cannot be implemented for type alias `Alias` +#[define_opaque(Alias)] fn _def() -> Alias { (42, 42) } diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs index 91610c92d227..3bbfee42ef6c 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs @@ -9,6 +9,7 @@ impl Foo for i32 { type Assoc = u32; } type ImplTrait = impl Sized; +#[define_opaque(ImplTrait)] fn constrain() -> ImplTrait { 1u64 } diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs index 3f1a9d12b44f..a05c65be48bc 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs @@ -5,6 +5,7 @@ impl Foo for () {} impl Foo for i32 {} type Bar = impl std::fmt::Debug; +#[define_opaque(Bar)] fn defining_use() -> Bar { 42 } @@ -18,6 +19,7 @@ impl Bop for Bar {} //~^ ERROR conflicting implementations type Barr = impl std::fmt::Debug; +#[define_opaque(Barr)] fn defining_use2() -> Barr { 42 } diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr index aaf75cc3db97..2f44ee481adc 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` - --> $DIR/impl_trait_for_same_tait.rs:17:1 + --> $DIR/impl_trait_for_same_tait.rs:18:1 | LL | impl Bop for Bar<()> {} | -------------------- first implementation here @@ -8,7 +8,7 @@ LL | impl Bop for Bar {} | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` - --> $DIR/impl_trait_for_same_tait.rs:26:1 + --> $DIR/impl_trait_for_same_tait.rs:28:1 | LL | impl Bop for Bar<()> {} | -------------------- first implementation here @@ -17,7 +17,7 @@ LL | impl Bop for Barr {} | ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` - --> $DIR/impl_trait_for_same_tait.rs:30:1 + --> $DIR/impl_trait_for_same_tait.rs:32:1 | LL | impl Bop for Bar<()> {} | -------------------- first implementation here diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs index bce5ba7c91c3..07ac284d5016 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs @@ -4,6 +4,7 @@ #![feature(type_alias_impl_trait)] type Alias = impl Sized; +#[define_opaque(Alias)] fn constrain() -> Alias { 1i32 } diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs index 8ec20acef4de..e0045df08ec7 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs @@ -3,17 +3,18 @@ use std::fmt::Debug; type Foo = impl Debug; -pub trait Yay { } -impl Yay for Foo { } +pub trait Yay {} +impl Yay for Foo {} +#[define_opaque(Foo)] fn foo() { - is_yay::(); //~ ERROR: the trait bound `u32: Yay` is not satisfied + is_yay::(); //~ ERROR: the trait bound `u32: Yay` is not satisfied is_debug::(); // OK - is_yay::(); // OK + is_yay::(); // OK is_debug::(); // OK } -fn is_yay() { } -fn is_debug() { } +fn is_yay() {} +fn is_debug() {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr index 9840bcef7d14..0ebf9f064373 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `u32: Yay` is not satisfied - --> $DIR/impl_trait_for_tait_bound.rs:10:14 + --> $DIR/impl_trait_for_tait_bound.rs:11:14 | LL | is_yay::(); | ^^^ the trait `Yay` is not implemented for `u32` | = help: the trait `Yay` is implemented for `Foo` note: required by a bound in `is_yay` - --> $DIR/impl_trait_for_tait_bound.rs:16:14 + --> $DIR/impl_trait_for_tait_bound.rs:17:14 | -LL | fn is_yay() { } +LL | fn is_yay() {} | ^^^ required by this bound in `is_yay` error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs index a4b8c2d190db..0a8dadb89e2e 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs @@ -4,13 +4,14 @@ use std::fmt::Debug; type Foo = impl Debug; -pub trait Yay { } -impl Yay for u32 { } +pub trait Yay {} +impl Yay for u32 {} +#[define_opaque(Foo)] fn foo() { is_yay::(); //~ ERROR: the trait bound `Foo: Yay` is not satisfied } -fn is_yay() { } +fn is_yay() {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr index 2259aa7bb150..4fff9ad26cb3 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `Foo: Yay` is not satisfied - --> $DIR/impl_trait_for_tait_bound2.rs:11:14 + --> $DIR/impl_trait_for_tait_bound2.rs:12:14 | LL | is_yay::(); | ^^^ the trait `Yay` is not implemented for `Foo` | = help: the trait `Yay` is implemented for `u32` note: required by a bound in `is_yay` - --> $DIR/impl_trait_for_tait_bound2.rs:14:14 + --> $DIR/impl_trait_for_tait_bound2.rs:15:14 | -LL | fn is_yay() { } +LL | fn is_yay() {} | ^^^ required by this bound in `is_yay` error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr index 1d7a97c53671..a7e4ba29d3a6 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr +++ b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr @@ -11,11 +11,6 @@ LL | let x: Self::Assoc = 42; | = note: expected opaque type `<() as Trait>::Assoc` found type `{integer}` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:14:8 - | -LL | fn foo() { - | ^^^ error[E0308]: mismatched types --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:31:30 @@ -30,11 +25,6 @@ LL | let x: Self::Assoc = 42; | = note: expected opaque type `<() as Trait2>::Assoc` found type `{integer}` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:30:11 - | -LL | const FOO: () = { - | ^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/implied_bounds.rs b/tests/ui/type-alias-impl-trait/implied_bounds.rs index 269c0eff025d..65d7234bd444 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds.rs +++ b/tests/ui/type-alias-impl-trait/implied_bounds.rs @@ -1,11 +1,8 @@ #![feature(type_alias_impl_trait)] -mod foo { - use super::Equals; - pub type WithLifetime<'a> = impl Equals; - fn _defining_use<'a>() -> WithLifetime<'a> {} -} -use foo::WithLifetime; +pub type WithLifetime<'a> = impl Equals; +#[define_opaque(WithLifetime)] +fn _defining_use<'a>() -> WithLifetime<'a> {} trait Convert<'a> { type Witness; diff --git a/tests/ui/type-alias-impl-trait/implied_bounds.stderr b/tests/ui/type-alias-impl-trait/implied_bounds.stderr index 23f1141e5444..eda87bcbf90c 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds.stderr +++ b/tests/ui/type-alias-impl-trait/implied_bounds.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/implied_bounds.rs:21:9 + --> $DIR/implied_bounds.rs:18:9 | LL | impl<'a> Convert<'a> for () { | -- lifetime `'a` defined here diff --git a/tests/ui/type-alias-impl-trait/implied_bounds2.rs b/tests/ui/type-alias-impl-trait/implied_bounds2.rs index 845476ef9741..0d829113ce70 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds2.rs +++ b/tests/ui/type-alias-impl-trait/implied_bounds2.rs @@ -2,12 +2,10 @@ #![feature(type_alias_impl_trait)] -mod helper { - pub type Ty<'a, A> = impl Sized + 'a; - fn defining<'a, A>() -> Ty<'a, A> {} - pub fn assert_static() {} -} -use helper::*; +pub type Ty<'a, A> = impl Sized + 'a; +#[define_opaque(Ty)] +fn defining<'a, A>() -> Ty<'a, A> {} +pub fn assert_static() {} fn test<'a, A>() where Ty<'a, A>: 'static, diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs index 76a63741e18e..b6120cd4cc3d 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs +++ b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs @@ -1,11 +1,8 @@ #![feature(type_alias_impl_trait)] -mod foo { - use super::Equals; - pub type WithLifetime = impl Equals; - fn _defining_use() -> WithLifetime {} -} -use foo::WithLifetime; +pub type WithLifetime = impl Equals; +#[define_opaque(WithLifetime)] +fn _defining_use() -> WithLifetime {} trait Convert<'a> { type Witness; diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr index 391a8a75786a..887c8552d2f7 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr +++ b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/implied_bounds_from_types.rs:21:9 + --> $DIR/implied_bounds_from_types.rs:18:9 | LL | impl<'a> Convert<'a> for () { | -- lifetime `'a` defined here diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr index 49997b073c95..3bc6b9205ec1 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Yay` for type `<() as HideIt>::Assoc` - --> $DIR/implied_lifetime_wf_check.rs:26:1 + --> $DIR/implied_lifetime_wf_check.rs:27:1 | LL | impl Yay for <() as HideIt>::Assoc {} | ---------------------------------- first implementation here diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs index d85c7f60023e..7950d6ad80c0 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs @@ -7,6 +7,7 @@ type Alias = impl Sized; +#[define_opaque(Alias)] fn constrain() -> Alias { 1i32 } diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs index fb251e9bde15..889438d1b733 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs @@ -2,6 +2,7 @@ mod test_lifetime_param { pub type Ty<'a> = impl Sized; + #[define_opaque(Ty)] fn defining(a: &str) -> Ty<'_> { a } @@ -17,6 +18,7 @@ where mod test_higher_kinded_lifetime_param { pub type Ty<'a> = impl Sized + 'a; + #[define_opaque(Ty)] fn defining(a: &str) -> Ty<'_> { a } @@ -40,6 +42,7 @@ mod test_higher_kinded_lifetime_param2 { mod test_type_param { pub type Ty = impl Sized; + #[define_opaque(Ty)] fn defining(s: A) -> Ty { s } @@ -54,13 +57,13 @@ where } mod test_implied_from_fn_sig { - mod foo { - pub type Opaque = impl Sized; - fn defining() -> Opaque {} - } + pub type Opaque = impl Sized; + #[define_opaque(Opaque)] + fn defining() -> Opaque {} + fn assert_static() {} - fn test(_: foo::Opaque) { + fn test(_: Opaque) { assert_static::(); } } diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr index c9af4bda572a..7311f5882f75 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:14:5 + --> $DIR/implied_lifetime_wf_check3.rs:15:5 | LL | fn test_lifetime_param_test<'a>() | -- lifetime `'a` defined here @@ -8,7 +8,7 @@ LL | test_lifetime_param::assert_static::<'a>() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:29:5 + --> $DIR/implied_lifetime_wf_check3.rs:31:5 | LL | fn test_higher_kinded_lifetime_param_test<'a>() | -- lifetime `'a` defined here @@ -17,7 +17,7 @@ LL | test_higher_kinded_lifetime_param::assert_static::<'a>() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:36:9 + --> $DIR/implied_lifetime_wf_check3.rs:38:9 | LL | fn test<'a>() { | -- lifetime `'a` defined here @@ -25,7 +25,7 @@ LL | assert_static::<'a>() | ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error[E0310]: the parameter type `A` may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:52:5 + --> $DIR/implied_lifetime_wf_check3.rs:55:5 | LL | test_type_param::assert_static::() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs index 7b2bbc995307..5484b91e6f1f 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs @@ -1,14 +1,12 @@ #![feature(type_alias_impl_trait)] -mod test_type_param_static { - pub type Ty = impl Sized + 'static; - fn defining(s: A) -> Ty { - s - //~^ ERROR: the parameter type `A` may not live long enough - } - pub fn assert_static() {} +pub type Ty = impl Sized + 'static; +#[define_opaque(Ty)] +fn defining(s: A) -> Ty { + s + //~^ ERROR: the parameter type `A` may not live long enough } -use test_type_param_static::*; +pub fn assert_static() {} fn test() where diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr index 060d68eb632b..3cec4bbb0993 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr @@ -1,24 +1,24 @@ error[E0310]: the parameter type `A` may not live long enough - --> $DIR/implied_lifetime_wf_check4_static.rs:6:9 + --> $DIR/implied_lifetime_wf_check4_static.rs:6:5 | -LL | s - | ^ - | | - | the parameter type `A` must be valid for the static lifetime... - | ...so that the type `A` will meet its required lifetime bounds... +LL | s + | ^ + | | + | the parameter type `A` must be valid for the static lifetime... + | ...so that the type `A` will meet its required lifetime bounds... | note: ...that is required by this bound - --> $DIR/implied_lifetime_wf_check4_static.rs:4:35 + --> $DIR/implied_lifetime_wf_check4_static.rs:3:31 | -LL | pub type Ty = impl Sized + 'static; - | ^^^^^^^ +LL | pub type Ty = impl Sized + 'static; + | ^^^^^^^ help: consider adding an explicit lifetime bound | -LL | pub type Ty = impl Sized + 'static; - | +++++++++ +LL | pub type Ty = impl Sized + 'static; + | +++++++++ error[E0310]: the parameter type `A` may not live long enough - --> $DIR/implied_lifetime_wf_check4_static.rs:17:5 + --> $DIR/implied_lifetime_wf_check4_static.rs:15:5 | LL | assert_static::() | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs index 4a9f162823e3..126fb66b9db6 100644 --- a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs +++ b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs @@ -2,19 +2,17 @@ #![feature(impl_trait_in_assoc_type, type_alias_impl_trait)] -mod foo { - pub trait Callable { - type Output; - fn call() -> Self::Output; - } - - pub type OutputHelper = impl Sized; - impl<'a> Callable for &'a () { - type Output = OutputHelper; - fn call() -> Self::Output {} - } +pub trait Callable { + type Output; + fn call() -> Self::Output; +} + +pub type OutputHelper = impl Sized; +impl<'a> Callable for &'a () { + type Output = OutputHelper; + #[define_opaque(OutputHelper)] + fn call() -> Self::Output {} } -use foo::*; fn test<'a>() -> impl Sized { <&'a () as Callable>::call() diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.rs b/tests/ui/type-alias-impl-trait/in-where-clause.rs index 065af57a8641..8d5bfc48a66e 100644 --- a/tests/ui/type-alias-impl-trait/in-where-clause.rs +++ b/tests/ui/type-alias-impl-trait/in-where-clause.rs @@ -5,6 +5,7 @@ type Bar = impl Sized; //~^ ERROR: cycle +#[define_opaque(Bar)] fn foo() -> Bar where Bar: Send, diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr index 5ac09e20b02c..114cac64573c 100644 --- a/tests/ui/type-alias-impl-trait/in-where-clause.stderr +++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr @@ -1,12 +1,12 @@ error[E0283]: type annotations needed: cannot satisfy `Bar: Send` - --> $DIR/in-where-clause.rs:12:9 + --> $DIR/in-where-clause.rs:13:9 | LL | [0; 1 + 2] | ^^^^^ | = note: cannot satisfy `Bar: Send` note: required by a bound in `foo` - --> $DIR/in-where-clause.rs:10:10 + --> $DIR/in-where-clause.rs:11:10 | LL | fn foo() -> Bar | --- required by a bound in this function @@ -21,7 +21,7 @@ LL | type Bar = impl Sized; | ^^^^^^^^^^ | note: ...which requires type-checking `foo`... - --> $DIR/in-where-clause.rs:8:1 + --> $DIR/in-where-clause.rs:9:1 | LL | / fn foo() -> Bar LL | | where diff --git a/tests/ui/type-alias-impl-trait/incomplete-inference.rs b/tests/ui/type-alias-impl-trait/incomplete-inference.rs index 4c8bf2cfca11..70acb1870e22 100644 --- a/tests/ui/type-alias-impl-trait/incomplete-inference.rs +++ b/tests/ui/type-alias-impl-trait/incomplete-inference.rs @@ -2,11 +2,13 @@ type Foo = impl Sized; +#[define_opaque(Foo)] fn bar() -> Foo { None //~^ ERROR: type annotations needed [E0282] } +#[define_opaque(Foo)] fn baz() -> Foo { Some(()) } diff --git a/tests/ui/type-alias-impl-trait/incomplete-inference.stderr b/tests/ui/type-alias-impl-trait/incomplete-inference.stderr index 3976a43a89c5..0b2bac0a153f 100644 --- a/tests/ui/type-alias-impl-trait/incomplete-inference.stderr +++ b/tests/ui/type-alias-impl-trait/incomplete-inference.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/incomplete-inference.rs:6:5 + --> $DIR/incomplete-inference.rs:7:5 | LL | None | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` diff --git a/tests/ui/type-alias-impl-trait/inference-cycle.rs b/tests/ui/type-alias-impl-trait/inference-cycle.rs index 6e4507ed4606..951f177377a1 100644 --- a/tests/ui/type-alias-impl-trait/inference-cycle.rs +++ b/tests/ui/type-alias-impl-trait/inference-cycle.rs @@ -1,24 +1,24 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -mod m { - pub type Foo = impl std::fmt::Debug; +//@ check-pass - pub fn foo() -> Foo { - is_send(bar()) - } +pub type Foo = impl std::fmt::Debug; - pub fn bar() { - // Cycle: error today, but it'd be nice if it eventually worked - is_send(foo()); - //~^ ERROR: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits - } - - fn baz() -> Foo { - () - } - - fn is_send(_: T) {} +#[define_opaque(Foo)] +pub fn foo() -> Foo { + is_send(bar()) } +pub fn bar() { + is_send(foo()); +} + +#[define_opaque(Foo)] +fn baz() -> Foo { + () +} + +fn is_send(_: T) {} + fn main() {} diff --git a/tests/ui/type-alias-impl-trait/inference-cycle.stderr b/tests/ui/type-alias-impl-trait/inference-cycle.stderr deleted file mode 100644 index 8b809ba014d9..000000000000 --- a/tests/ui/type-alias-impl-trait/inference-cycle.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits - --> $DIR/inference-cycle.rs:13:17 - | -LL | is_send(foo()); - | ------- ^^^^^ - | | - | required by a bound introduced by this call - | - = note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule -note: opaque type is declared here - --> $DIR/inference-cycle.rs:5:20 - | -LL | pub type Foo = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `is_send` - --> $DIR/inference-cycle.rs:21:19 - | -LL | fn is_send(_: T) {} - | ^^^^ required by this bound in `is_send` - -error: aborting due to 1 previous error - diff --git a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs index 6609d4eb5a27..ef6871bec7c4 100644 --- a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs +++ b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs @@ -3,6 +3,9 @@ type T = impl Copy; //~^ ERROR cannot resolve opaque type -static STATIC: T = None::<&'static T>; +#[define_opaque(T)] +fn foo() -> T { + None::<&'static T> +} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs index 93c52126d69b..ae9712bd891a 100644 --- a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs +++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs @@ -7,6 +7,7 @@ trait Foo { impl Foo for () { type Foo = impl std::fmt::Debug; + //~^ ERROR: unconstrained opaque type fn bar() { let x: Self::Foo = (); //~^ ERROR: mismatched types diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr index 169d8e41d20d..82bd0025d6d0 100644 --- a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr +++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr @@ -1,9 +1,17 @@ +error: unconstrained opaque type + --> $DIR/invalid_impl_trait_in_assoc_ty.rs:9:16 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same impl + error[E0308]: mismatched types - --> $DIR/invalid_impl_trait_in_assoc_ty.rs:11:28 + --> $DIR/invalid_impl_trait_in_assoc_ty.rs:12:28 | LL | type Foo = impl std::fmt::Debug; | -------------------- the expected opaque type -LL | fn bar() { +... LL | let x: Self::Foo = (); | --------- ^^ expected opaque type, found `()` | | @@ -11,12 +19,7 @@ LL | let x: Self::Foo = (); | = note: expected opaque type `<() as Foo>::Foo` found unit type `()` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:8 - | -LL | fn bar() { - | ^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/issue-101750.rs b/tests/ui/type-alias-impl-trait/issue-101750.rs index 9367be8ca07f..2f9304ce3bc6 100644 --- a/tests/ui/type-alias-impl-trait/issue-101750.rs +++ b/tests/ui/type-alias-impl-trait/issue-101750.rs @@ -2,21 +2,18 @@ //@ check-pass -mod foo { - pub trait Trait {} +pub trait Trait {} - pub type TAIT = impl Trait; +pub type TAIT = impl Trait; - pub struct Concrete; - impl Trait for Concrete {} +pub struct Concrete; +impl Trait for Concrete {} - pub fn tait() -> TAIT { - Concrete - } +#[define_opaque(TAIT)] +pub fn tait() -> TAIT { + Concrete } -use foo::*; - trait OuterTrait { type Item; } diff --git a/tests/ui/type-alias-impl-trait/issue-104817.rs b/tests/ui/type-alias-impl-trait/issue-104817.rs index 491463216145..13bbfa12a67a 100644 --- a/tests/ui/type-alias-impl-trait/issue-104817.rs +++ b/tests/ui/type-alias-impl-trait/issue-104817.rs @@ -8,6 +8,7 @@ trait OpaqueTrait {} impl OpaqueTrait for T {} type OpaqueType = impl OpaqueTrait; +#[define_opaque(OpaqueType)] fn mk_opaque() -> OpaqueType { || 0 } diff --git a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr index df5a6c320a8a..4f227310ee78 100644 --- a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr +++ b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `AnotherTrait` - --> $DIR/issue-104817.rs:16:1 + --> $DIR/issue-104817.rs:17:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here diff --git a/tests/ui/type-alias-impl-trait/issue-109054.rs b/tests/ui/type-alias-impl-trait/issue-109054.rs index d3eb65215934..0c9304a42f35 100644 --- a/tests/ui/type-alias-impl-trait/issue-109054.rs +++ b/tests/ui/type-alias-impl-trait/issue-109054.rs @@ -10,8 +10,10 @@ type FnType = impl Fn(&u32) -> ReturnType; impl std::ops::Deref for CallMe { type Target = FnType; + #[define_opaque(FnType)] fn deref(&self) -> &Self::Target { //~^ ERROR: item does not constrain `ReturnType + #[define_opaque(ReturnType)] fn inner(val: &u32) -> ReturnType { async move { *val * 2 } } diff --git a/tests/ui/type-alias-impl-trait/issue-109054.stderr b/tests/ui/type-alias-impl-trait/issue-109054.stderr index 2a4aa63bb8ca..919b0a287c4f 100644 --- a/tests/ui/type-alias-impl-trait/issue-109054.stderr +++ b/tests/ui/type-alias-impl-trait/issue-109054.stderr @@ -1,18 +1,18 @@ -error: item does not constrain `ReturnType::{opaque#0}`, but has it in its signature - --> $DIR/issue-109054.rs:13:8 +error: item does not constrain `ReturnType::{opaque#0}` + --> $DIR/issue-109054.rs:14:8 | LL | fn deref(&self) -> &Self::Target { | ^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/issue-109054.rs:7:23 | LL | type ReturnType<'a> = impl std::future::Future + 'a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-109054.rs:19:9 + --> $DIR/issue-109054.rs:21:9 | LL | type ReturnType<'a> = impl std::future::Future + 'a; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs b/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs deleted file mode 100644 index 50eeff0b18fd..000000000000 --- a/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Checks to ensure that we properly detect when a closure constrains an opaque type - -#![feature(type_alias_impl_trait)] - -use std::fmt::Debug; - -fn main() { - type Opaque = impl Debug; - fn _unused() -> Opaque { String::new() } - let null = || -> Opaque { 0 }; - //~^ ERROR: concrete type differs from previous defining opaque type use - println!("{:?}", null()); -} diff --git a/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr b/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr deleted file mode 100644 index 4570ce8e41da..000000000000 --- a/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/issue-52843-closure-constrain.rs:10:31 - | -LL | let null = || -> Opaque { 0 }; - | ^ expected `String`, got `i32` - | -note: previous use here - --> $DIR/issue-52843-closure-constrain.rs:9:30 - | -LL | fn _unused() -> Opaque { String::new() } - | ^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/type-alias-impl-trait/issue-52843.rs b/tests/ui/type-alias-impl-trait/issue-52843.rs index 159d3ccd27e0..fd28eb8381d6 100644 --- a/tests/ui/type-alias-impl-trait/issue-52843.rs +++ b/tests/ui/type-alias-impl-trait/issue-52843.rs @@ -3,6 +3,7 @@ type Foo = impl Default; #[allow(unused)] +#[define_opaque(Foo)] fn foo(t: T) -> Foo { t //~^ ERROR: the trait bound `T: Default` is not satisfied diff --git a/tests/ui/type-alias-impl-trait/issue-52843.stderr b/tests/ui/type-alias-impl-trait/issue-52843.stderr index 6673b03525d0..ee2390d09451 100644 --- a/tests/ui/type-alias-impl-trait/issue-52843.stderr +++ b/tests/ui/type-alias-impl-trait/issue-52843.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `T: Default` is not satisfied - --> $DIR/issue-52843.rs:7:5 + --> $DIR/issue-52843.rs:8:5 | LL | t | ^ the trait `Default` is not implemented for `T` @@ -10,7 +10,7 @@ note: required by a bound in an opaque type LL | type Foo = impl Default; | ^^^^^^^ note: this definition site has more where clauses than the opaque type - --> $DIR/issue-52843.rs:6:1 + --> $DIR/issue-52843.rs:7:1 | LL | fn foo(t: T) -> Foo { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.rs b/tests/ui/type-alias-impl-trait/issue-53092-2.rs index 43df49adc423..5f44a9aa2dfa 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.rs @@ -2,15 +2,14 @@ #![allow(dead_code)] type Bug = impl Fn(T) -> U + Copy; -//~^ ERROR cycle detected +#[define_opaque(Bug)] +//~^ ERROR: only functions and methods can define opaque types const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; -//~^ ERROR item does not constrain `Bug::{opaque#0}`, but has it in its signature -//~| ERROR item does not constrain `Bug::{opaque#0}`, but has it in its signature -//~| ERROR non-defining opaque type use in defining scope +#[define_opaque(Bug)] fn make_bug>() -> Bug { - |x| x.into() + |x| x.into() //~ ERROR is not satisfied } fn main() { diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr index 678b0c84f78b..5739662ff80b 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -1,68 +1,25 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-53092-2.rs:7:18 +error: only functions and methods can define opaque types + --> $DIR/issue-53092-2.rs:6:1 | -LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; - | ^^^^^^^^^^^ argument `u8` is not a generic parameter - | -note: for this opaque type - --> $DIR/issue-53092-2.rs:4:18 - | -LL | type Bug = impl Fn(T) -> U + Copy; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #[define_opaque(Bug)] + | ^^^^^^^^^^^^^^^^^^^^^ -error[E0391]: cycle detected when computing type of `Bug::{opaque#0}` - --> $DIR/issue-53092-2.rs:4:18 +error[E0277]: the trait bound `U: From` is not satisfied + --> $DIR/issue-53092-2.rs:12:5 | -LL | type Bug = impl Fn(T) -> U + Copy; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | |x| x.into() + | ^^^^^^^^^^^^ the trait `From` is not implemented for `U` | -note: ...which requires computing type of opaque `Bug::{opaque#0}`... - --> $DIR/issue-53092-2.rs:4:18 +note: required by a bound in `make_bug` + --> $DIR/issue-53092-2.rs:11:19 | -LL | type Bug = impl Fn(T) -> U + Copy; - | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires type-checking `CONST_BUG`... - --> $DIR/issue-53092-2.rs:7:1 +LL | fn make_bug>() -> Bug { + | ^^^^^^^ required by this bound in `make_bug` +help: consider restricting type parameter `U` with trait `From` | -LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing layout of `Bug`... - = note: ...which requires normalizing `Bug`... - = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle -note: cycle used when checking that `Bug::{opaque#0}` is well-formed - --> $DIR/issue-53092-2.rs:4:18 - | -LL | type Bug = impl Fn(T) -> U + Copy; - | ^^^^^^^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information +LL | type Bug> = impl Fn(T) -> U + Copy; + | +++++++++++++++++++++++ -error: item does not constrain `Bug::{opaque#0}`, but has it in its signature - --> $DIR/issue-53092-2.rs:7:7 - | -LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; - | ^^^^^^^^^ - | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/issue-53092-2.rs:4:18 - | -LL | type Bug = impl Fn(T) -> U + Copy; - | ^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors -error: item does not constrain `Bug::{opaque#0}`, but has it in its signature - --> $DIR/issue-53092-2.rs:7:61 - | -LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; - | ^^^^^^^ - | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/issue-53092-2.rs:4:18 - | -LL | type Bug = impl Fn(T) -> U + Copy; - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0391, E0792. -For more information about an error, try `rustc --explain E0391`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/issue-53092.rs b/tests/ui/type-alias-impl-trait/issue-53092.rs index 83b51227aaae..a2e6ddc11b60 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092.rs +++ b/tests/ui/type-alias-impl-trait/issue-53092.rs @@ -1,14 +1,13 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -mod bug { - pub type Bug = impl Fn(T) -> U + Copy; +pub type Bug = impl Fn(T) -> U + Copy; - fn make_bug>() -> Bug { - |x| x.into() //~ ERROR the trait bound `U: From` is not satisfied - } +#[define_opaque(Bug)] +fn make_bug>() -> Bug { + |x| x.into() + //~^ ERROR the trait bound `U: From` is not satisfied } -use bug::Bug; union Moo { x: Bug, diff --git a/tests/ui/type-alias-impl-trait/issue-53092.stderr b/tests/ui/type-alias-impl-trait/issue-53092.stderr index 579902aa3ab2..a8554b9a9892 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53092.stderr @@ -1,18 +1,18 @@ error[E0277]: the trait bound `U: From` is not satisfied - --> $DIR/issue-53092.rs:8:9 + --> $DIR/issue-53092.rs:8:5 | -LL | |x| x.into() - | ^^^^^^^^^^^^ the trait `From` is not implemented for `U` +LL | |x| x.into() + | ^^^^^^^^^^^^ the trait `From` is not implemented for `U` | note: required by a bound in `make_bug` - --> $DIR/issue-53092.rs:7:23 + --> $DIR/issue-53092.rs:7:19 | -LL | fn make_bug>() -> Bug { - | ^^^^^^^ required by this bound in `make_bug` +LL | fn make_bug>() -> Bug { + | ^^^^^^^ required by this bound in `make_bug` help: consider restricting type parameter `U` with trait `From` | -LL | pub type Bug> = impl Fn(T) -> U + Copy; - | +++++++++++++++++++++++ +LL | pub type Bug> = impl Fn(T) -> U + Copy; + | +++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-53096.rs b/tests/ui/type-alias-impl-trait/issue-53096.rs index 590fce84fc9f..c24f1bf44fab 100644 --- a/tests/ui/type-alias-impl-trait/issue-53096.rs +++ b/tests/ui/type-alias-impl-trait/issue-53096.rs @@ -1,13 +1,11 @@ #![feature(rustc_attrs)] #![feature(type_alias_impl_trait)] -mod foo { - pub type Foo = impl Fn() -> usize; - pub const fn bar() -> Foo { - || 0usize - } +pub type Foo = impl Fn() -> usize; +#[define_opaque(Foo)] +pub const fn bar() -> Foo { + || 0usize } -use foo::*; const BAZR: Foo = bar(); #[rustc_error] diff --git a/tests/ui/type-alias-impl-trait/issue-53096.stderr b/tests/ui/type-alias-impl-trait/issue-53096.stderr index 0a744e7be9cb..53490896af79 100644 --- a/tests/ui/type-alias-impl-trait/issue-53096.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53096.stderr @@ -1,5 +1,5 @@ error: fatal error triggered by #[rustc_error] - --> $DIR/issue-53096.rs:14:1 + --> $DIR/issue-53096.rs:12:1 | LL | fn main() {} | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs b/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs index 0d9126d39933..f02ccbbb93c4 100644 --- a/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs +++ b/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs @@ -3,21 +3,20 @@ //@ check-pass -mod gen { - use std::ops::Coroutine; +use std::ops::Coroutine; - pub type CoroOnce = impl Coroutine; +pub type CoroOnce = impl Coroutine; - pub const fn const_coroutine(yielding: Y, returning: R) -> CoroOnce { - #[coroutine] - move || { - yield yielding; +#[define_opaque(CoroOnce)] +pub const fn const_coroutine(yielding: Y, returning: R) -> CoroOnce { + #[coroutine] + move || { + yield yielding; - return returning; - } + return returning; } } -const FOO: gen::CoroOnce = gen::const_coroutine(10, 100); +const FOO: CoroOnce = const_coroutine(10, 100); fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs b/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs index e54dd01122e0..a3c37759ac0b 100644 --- a/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs +++ b/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs @@ -18,6 +18,7 @@ struct Foo<'a> { type F = impl Future; impl<'a> Foo<'a> { + #[define_opaque(F)] fn reply(&mut self) -> F { AndThen(|| ()) } diff --git a/tests/ui/type-alias-impl-trait/issue-57961.rs b/tests/ui/type-alias-impl-trait/issue-57961.rs index 61af7a0f6250..0b39e21d8b7e 100644 --- a/tests/ui/type-alias-impl-trait/issue-57961.rs +++ b/tests/ui/type-alias-impl-trait/issue-57961.rs @@ -11,6 +11,7 @@ impl Foo for () { //~^ ERROR expected `IntoIter` to be an iterator that yields `X`, but it yields `u32` } +#[define_opaque(X)] fn incoherent() -> X { 22_i32 } diff --git a/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs b/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs index 899e81ed562f..c2a9f153815e 100644 --- a/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs @@ -7,6 +7,7 @@ use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; type RandCoroutine<'a> = impl Coroutine + 'a; +#[define_opaque(RandCoroutine)] fn rand_coroutine<'a>(rng: &'a ()) -> RandCoroutine<'a> { #[coroutine] move || { @@ -18,6 +19,7 @@ fn rand_coroutine<'a>(rng: &'a ()) -> RandCoroutine<'a> { } pub type RandCoroutineWithIndirection<'c> = impl Coroutine + 'c; +#[define_opaque(RandCoroutineWithIndirection)] pub fn rand_coroutine_with_indirection<'a>(rng: &'a ()) -> RandCoroutineWithIndirection<'a> { fn helper<'b>(rng: &'b ()) -> impl 'b + Coroutine { #[coroutine] diff --git a/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs b/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs index 9d74c0687fe6..aef13947f554 100644 --- a/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs +++ b/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs @@ -8,6 +8,8 @@ trait Trait {} impl Trait for T {} type Foo<'c> = impl Trait + 'c; + +#[define_opaque(Foo)] fn foo<'a>(rng: &'a ()) -> Foo<'a> { fn helper<'b>(rng: &'b ()) -> impl 'b + Trait { rng @@ -16,5 +18,4 @@ fn foo<'a>(rng: &'a ()) -> Foo<'a> { helper(rng) } -fn main() { -} +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-58951-2.rs b/tests/ui/type-alias-impl-trait/issue-58951-2.rs index fb92b1274365..de6b9e741198 100644 --- a/tests/ui/type-alias-impl-trait/issue-58951-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-58951-2.rs @@ -2,14 +2,12 @@ #![feature(type_alias_impl_trait)] -mod defining_use_scope { - pub type A = impl Iterator; +pub type A = impl Iterator; - pub fn def_a() -> A { - 0..1 - } +#[define_opaque(A)] +pub fn def_a() -> A { + 0..1 } -use defining_use_scope::*; pub fn use_a() { def_a().map(|x| x); diff --git a/tests/ui/type-alias-impl-trait/issue-58951.rs b/tests/ui/type-alias-impl-trait/issue-58951.rs index b9f27b031c72..de6b9e741198 100644 --- a/tests/ui/type-alias-impl-trait/issue-58951.rs +++ b/tests/ui/type-alias-impl-trait/issue-58951.rs @@ -2,16 +2,15 @@ #![feature(type_alias_impl_trait)] -mod helper { - pub type A = impl Iterator; +pub type A = impl Iterator; - pub fn def_a() -> A { - 0..1 - } +#[define_opaque(A)] +pub fn def_a() -> A { + 0..1 } pub fn use_a() { - helper::def_a().map(|x| x); + def_a().map(|x| x); } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-60407.rs b/tests/ui/type-alias-impl-trait/issue-60407.rs index 6c7c76b5ac72..5b8ff6b74de5 100644 --- a/tests/ui/type-alias-impl-trait/issue-60407.rs +++ b/tests/ui/type-alias-impl-trait/issue-60407.rs @@ -1,13 +1,11 @@ #![feature(type_alias_impl_trait, rustc_attrs)] -mod bar { - pub type Debuggable = impl core::fmt::Debug; +pub type Debuggable = impl core::fmt::Debug; - pub fn foo() -> Debuggable { - 0u32 - } +#[define_opaque(Debuggable)] +pub fn foo() -> Debuggable { + 0u32 } -use bar::*; static mut TEST: Option = None; diff --git a/tests/ui/type-alias-impl-trait/issue-60407.stderr b/tests/ui/type-alias-impl-trait/issue-60407.stderr index bba9092e9775..f517d5b65fa2 100644 --- a/tests/ui/type-alias-impl-trait/issue-60407.stderr +++ b/tests/ui/type-alias-impl-trait/issue-60407.stderr @@ -1,5 +1,5 @@ error: fatal error triggered by #[rustc_error] - --> $DIR/issue-60407.rs:15:1 + --> $DIR/issue-60407.rs:13:1 | LL | fn main() { | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/issue-60564.rs b/tests/ui/type-alias-impl-trait/issue-60564.rs index 48bd70bcca95..f28258b3b227 100644 --- a/tests/ui/type-alias-impl-trait/issue-60564.rs +++ b/tests/ui/type-alias-impl-trait/issue-60564.rs @@ -16,8 +16,8 @@ where E: std::fmt::Debug, { type BitsIter = IterBitsIter; + #[define_opaque(IterBitsIter)] fn iter_bits(self, n: u8) -> Self::BitsIter { - //~^ ERROR non-defining opaque type use (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) //~^ ERROR expected generic type parameter, found `u8` } diff --git a/tests/ui/type-alias-impl-trait/issue-60564.stderr b/tests/ui/type-alias-impl-trait/issue-60564.stderr index d42495e934d3..6aaed7d4296a 100644 --- a/tests/ui/type-alias-impl-trait/issue-60564.stderr +++ b/tests/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,15 +1,3 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-60564.rs:19:34 - | -LL | fn iter_bits(self, n: u8) -> Self::BitsIter { - | ^^^^^^^^^^^^^^ argument `u8` is not a generic parameter - | -note: for this opaque type - --> $DIR/issue-60564.rs:8:30 - | -LL | type IterBitsIter = impl std::iter::Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `u8` --> $DIR/issue-60564.rs:21:9 | @@ -19,6 +7,6 @@ LL | type IterBitsIter = impl std::iter::Iterator; LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs b/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs index 38abc3ec7e85..6de026a26d58 100644 --- a/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs +++ b/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs @@ -8,6 +8,7 @@ pub type Closure = impl FnOnce(); +#[define_opaque(Closure)] fn bop() -> Closure { || -> Closure { || () }; panic!() diff --git a/tests/ui/type-alias-impl-trait/issue-63279.rs b/tests/ui/type-alias-impl-trait/issue-63279.rs index 02f2111468a2..10da40d2f90d 100644 --- a/tests/ui/type-alias-impl-trait/issue-63279.rs +++ b/tests/ui/type-alias-impl-trait/issue-63279.rs @@ -2,6 +2,7 @@ type Closure = impl FnOnce(); +#[define_opaque(Closure)] fn c() -> Closure { //~^ ERROR: expected a `FnOnce()` closure, found `()` || -> Closure { || () } diff --git a/tests/ui/type-alias-impl-trait/issue-63279.stderr b/tests/ui/type-alias-impl-trait/issue-63279.stderr index 97158ee297da..8f0e9c5fde04 100644 --- a/tests/ui/type-alias-impl-trait/issue-63279.stderr +++ b/tests/ui/type-alias-impl-trait/issue-63279.stderr @@ -1,5 +1,5 @@ error[E0277]: expected a `FnOnce()` closure, found `()` - --> $DIR/issue-63279.rs:5:11 + --> $DIR/issue-63279.rs:6:11 | LL | fn c() -> Closure { | ^^^^^^^ expected an `FnOnce()` closure, found `()` @@ -8,7 +8,7 @@ LL | fn c() -> Closure { = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` error[E0277]: expected a `FnOnce()` closure, found `()` - --> $DIR/issue-63279.rs:7:11 + --> $DIR/issue-63279.rs:8:11 | LL | || -> Closure { || () } | ^^^^^^^ expected an `FnOnce()` closure, found `()` @@ -17,26 +17,26 @@ LL | || -> Closure { || () } = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` error[E0308]: mismatched types - --> $DIR/issue-63279.rs:7:21 + --> $DIR/issue-63279.rs:8:21 | LL | || -> Closure { || () } | ^^^^^ expected `()`, found closure | = note: expected unit type `()` - found closure `{closure@$DIR/issue-63279.rs:7:21: 7:23}` + found closure `{closure@$DIR/issue-63279.rs:8:21: 8:23}` help: use parentheses to call this closure | LL | || -> Closure { (|| ())() } | + +++ error[E0308]: mismatched types - --> $DIR/issue-63279.rs:7:5 + --> $DIR/issue-63279.rs:8:5 | LL | || -> Closure { || () } | ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure | = note: expected unit type `()` - found closure `{closure@$DIR/issue-63279.rs:7:5: 7:18}` + found closure `{closure@$DIR/issue-63279.rs:8:5: 8:18}` help: use parentheses to call this closure | LL | (|| -> Closure { || () })() diff --git a/tests/ui/type-alias-impl-trait/issue-63355.rs b/tests/ui/type-alias-impl-trait/issue-63355.rs index a0d0355b5af5..0b29bfeb98f1 100644 --- a/tests/ui/type-alias-impl-trait/issue-63355.rs +++ b/tests/ui/type-alias-impl-trait/issue-63355.rs @@ -21,6 +21,7 @@ impl Foo for () {} impl Bar for () { type Foo = FooImpl; + #[define_opaque(FooImpl)] fn foo() -> Self::Foo { () } @@ -33,10 +34,12 @@ impl Baz for () { type Foo = FooImpl; type Bar = BarImpl; + #[define_opaque(FooImpl)] fn foo() -> Self::Foo { () } + #[define_opaque(BarImpl)] fn bar() -> Self::Bar { //~^ ERROR: item does not constrain `FooImpl::{opaque#0}` () diff --git a/tests/ui/type-alias-impl-trait/issue-63355.stderr b/tests/ui/type-alias-impl-trait/issue-63355.stderr index 6755c0380560..cb1ef0ce41de 100644 --- a/tests/ui/type-alias-impl-trait/issue-63355.stderr +++ b/tests/ui/type-alias-impl-trait/issue-63355.stderr @@ -1,12 +1,12 @@ -error: item does not constrain `FooImpl::{opaque#0}`, but has it in its signature - --> $DIR/issue-63355.rs:40:8 +error: item does not constrain `FooImpl::{opaque#0}` + --> $DIR/issue-63355.rs:43:8 | LL | fn bar() -> Self::Bar { | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/issue-63355.rs:29:20 + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/issue-63355.rs:30:20 | LL | pub type FooImpl = impl Foo; | ^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs b/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs index 51f95637969a..5ea739657018 100644 --- a/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs +++ b/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs @@ -16,6 +16,9 @@ impl Trait for S1 {} impl S2 {} impl T3 {} -pub fn use_t1() -> T1 { S1(()) } +#[define_opaque(T1)] +pub fn use_t1() -> T1 { + S1(()) +} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-65384.rs b/tests/ui/type-alias-impl-trait/issue-65384.rs index 44ca5cb94b0f..86bbc93c8bd6 100644 --- a/tests/ui/type-alias-impl-trait/issue-65384.rs +++ b/tests/ui/type-alias-impl-trait/issue-65384.rs @@ -9,6 +9,7 @@ type Bar = impl MyTrait; impl MyTrait for Bar {} //~^ ERROR: conflicting implementations of trait `MyTrait` for type `()` -fn bazr() -> Bar { } +#[define_opaque(Bar)] +fn bazr() -> Bar {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs index f98ce4a426c4..6fc3aa8ce7e6 100644 --- a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs +++ b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -1,20 +1,19 @@ //@ check-pass #![feature(type_alias_impl_trait, rustc_attrs)] -mod foo { - pub type T = impl Sized; - // The concrete type referred by impl-trait-type-alias(`T`) is guaranteed - // to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive; - // so difference assertion should not be declared on impl-trait-type-alias's instances. - // for details, check RFC-2515: - // https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md - fn bop(_: T) { - super::take(|| {}); - super::take(|| {}); - } +pub type T = impl Sized; +// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed +// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive; +// so difference assertion should not be declared on impl-trait-type-alias's instances. +// for details, check RFC-2515: +// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md + +#[define_opaque(T)] +fn bop() { + take(|| {}); + take(|| {}); } -use foo::*; fn take(_: fn() -> T) {} diff --git a/tests/ui/type-alias-impl-trait/issue-65918.rs b/tests/ui/type-alias-impl-trait/issue-65918.rs index 275b9717cef3..00dab6f2744d 100644 --- a/tests/ui/type-alias-impl-trait/issue-65918.rs +++ b/tests/ui/type-alias-impl-trait/issue-65918.rs @@ -15,13 +15,11 @@ trait MyFrom: Sized { } /* MCVE starts here */ -mod f { - pub trait F {} - impl F for () {} - pub type DummyT = impl F; - fn _dummy_t() -> DummyT {} -} -use f::DummyT; +pub trait F {} +impl F for () {} +pub type DummyT = impl F; +#[define_opaque(DummyT)] +fn _dummy_t() -> DummyT {} struct Phantom1(PhantomData); struct Phantom2(PhantomData); diff --git a/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs b/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs index 0e3d01c2d618..009dc31ba265 100644 --- a/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs +++ b/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs @@ -6,6 +6,7 @@ type Closure = impl FnOnce(); +#[define_opaque(Closure)] fn closure() -> Closure { || {} } diff --git a/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs b/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs index c320b0db31bb..2d38b3030be3 100644 --- a/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs +++ b/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs @@ -22,6 +22,7 @@ impl WithAssoc for MyStruct { type AssocType = MyParam; } +#[define_opaque(Return)] fn my_fun() -> Return { MyStruct } diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs index 9dcdb578568a..205d4832b0ac 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs @@ -6,9 +6,9 @@ trait Trait {} type Alias<'a, U> = impl Trait; +#[define_opaque(Alias)] fn f<'a>() -> Alias<'a, ()> {} -//~^ ERROR non-defining opaque type use -//~| ERROR expected generic type parameter, found `()` +//~^ ERROR expected generic type parameter, found `()` fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr index 085bffe907b4..178aa5cf3453 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr @@ -1,24 +1,12 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-68368-non-defining-use-2.rs:9:15 - | -LL | fn f<'a>() -> Alias<'a, ()> {} - | ^^^^^^^^^^^^^ argument `()` is not a generic parameter - | -note: for this opaque type - --> $DIR/issue-68368-non-defining-use-2.rs:7:21 - | -LL | type Alias<'a, U> = impl Trait; - | ^^^^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `()` - --> $DIR/issue-68368-non-defining-use-2.rs:9:29 + --> $DIR/issue-68368-non-defining-use-2.rs:10:29 | LL | type Alias<'a, U> = impl Trait; | - this generic parameter must be used with a generic type parameter -LL | +... LL | fn f<'a>() -> Alias<'a, ()> {} | ^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs index dfe2ee8204c7..f3fa4fea7465 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs @@ -6,9 +6,9 @@ trait Trait {} type Alias<'a, U> = impl Trait; +#[define_opaque(Alias)] fn f<'a>() -> Alias<'a, ()> {} //~^ ERROR expected generic type parameter, found `()` -//~| ERROR non-defining opaque type use fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr index ea704ffff97a..bfbd506a7a5c 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr @@ -1,24 +1,12 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-68368-non-defining-use.rs:9:15 - | -LL | fn f<'a>() -> Alias<'a, ()> {} - | ^^^^^^^^^^^^^ argument `()` is not a generic parameter - | -note: for this opaque type - --> $DIR/issue-68368-non-defining-use.rs:7:21 - | -LL | type Alias<'a, U> = impl Trait; - | ^^^^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `()` - --> $DIR/issue-68368-non-defining-use.rs:9:29 + --> $DIR/issue-68368-non-defining-use.rs:10:29 | LL | type Alias<'a, U> = impl Trait; | - this generic parameter must be used with a generic type parameter -LL | +... LL | fn f<'a>() -> Alias<'a, ()> {} | ^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs index a0f8e48e268c..f9a68a1b0b31 100644 --- a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs +++ b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs @@ -19,6 +19,7 @@ impl WithAssoc for () { type Return = impl WithAssoc; //~^ ERROR use of undeclared lifetime name `'a` +#[define_opaque(Return)] fn my_fun() -> Return {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs index 8e631fd1b6a3..f62260bd3f09 100644 --- a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs +++ b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs @@ -18,6 +18,7 @@ impl WithAssoc for () { type Return<'a> = impl WithAssoc; +#[define_opaque(Return)] fn my_fun<'a>() -> Return<'a> {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-69323.rs b/tests/ui/type-alias-impl-trait/issue-69323.rs index 18bc4cf91787..af536186f72b 100644 --- a/tests/ui/type-alias-impl-trait/issue-69323.rs +++ b/tests/ui/type-alias-impl-trait/issue-69323.rs @@ -9,6 +9,7 @@ fn test1>(x: A) -> Chain = Chain>; +#[define_opaque(I)] fn test2>(x: A) -> I { x.chain(once(",")) } diff --git a/tests/ui/type-alias-impl-trait/issue-70121.rs b/tests/ui/type-alias-impl-trait/issue-70121.rs index b90bd312a0ba..5aec99a1c371 100644 --- a/tests/ui/type-alias-impl-trait/issue-70121.rs +++ b/tests/ui/type-alias-impl-trait/issue-70121.rs @@ -2,6 +2,7 @@ pub type Successors<'a> = impl Iterator; +#[define_opaque(Successors)] pub fn f<'a>() -> Successors<'a> { None.into_iter() } diff --git a/tests/ui/type-alias-impl-trait/issue-70121.stderr b/tests/ui/type-alias-impl-trait/issue-70121.stderr index ed2eb17fbead..8388998956ff 100644 --- a/tests/ui/type-alias-impl-trait/issue-70121.stderr +++ b/tests/ui/type-alias-impl-trait/issue-70121.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-70121.rs:18:5 + --> $DIR/issue-70121.rs:19:5 | LL | pub type Successors<'a> = impl Iterator; | ---------------------------- the expected opaque type @@ -11,8 +11,8 @@ LL | None.into_iter() | = note: expected opaque type `Successors<'a>` found struct `std::option::IntoIter<_>` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/issue-70121.rs:17:8 +note: this item must have a `#[define_opaque(Successors)]` attribute to be able to define hidden types + --> $DIR/issue-70121.rs:18:8 | LL | pub fn kazusa<'a>() -> <&'a () as Tr>::Item { | ^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/issue-72793.rs b/tests/ui/type-alias-impl-trait/issue-72793.rs index 0353b7f3787b..a51d7f5634ae 100644 --- a/tests/ui/type-alias-impl-trait/issue-72793.rs +++ b/tests/ui/type-alias-impl-trait/issue-72793.rs @@ -3,24 +3,21 @@ #![feature(type_alias_impl_trait)] -mod foo { - pub trait T { - type Item; - } - - pub type Alias<'a> = impl T; - - struct S; - impl<'a> T for &'a S { - type Item = &'a (); - } - - pub fn filter_positive<'a>() -> Alias<'a> { - &S - } +pub trait T { + type Item; } -use foo::*; +pub type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S { + type Item = &'a (); +} + +#[define_opaque(Alias)] +pub fn filter_positive<'a>() -> Alias<'a> { + &S +} fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); diff --git a/tests/ui/type-alias-impl-trait/issue-74244.rs b/tests/ui/type-alias-impl-trait/issue-74244.rs index bb4104b3d251..60b1bee9ff63 100644 --- a/tests/ui/type-alias-impl-trait/issue-74244.rs +++ b/tests/ui/type-alias-impl-trait/issue-74244.rs @@ -13,6 +13,7 @@ impl Allocator for DefaultAllocator { type A = impl Fn(::Buffer); +#[define_opaque(A)] fn foo() -> A { |_| () } diff --git a/tests/ui/type-alias-impl-trait/issue-74280.rs b/tests/ui/type-alias-impl-trait/issue-74280.rs index ad641eaa00d3..c8dc1adec413 100644 --- a/tests/ui/type-alias-impl-trait/issue-74280.rs +++ b/tests/ui/type-alias-impl-trait/issue-74280.rs @@ -4,6 +4,7 @@ type Test = impl Copy; +#[define_opaque(Test)] fn test() -> Test { let y = || -> Test { () }; 7 //~ ERROR mismatched types diff --git a/tests/ui/type-alias-impl-trait/issue-74280.stderr b/tests/ui/type-alias-impl-trait/issue-74280.stderr index c09efbe4e133..a89a3f77b3d5 100644 --- a/tests/ui/type-alias-impl-trait/issue-74280.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74280.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-74280.rs:9:5 + --> $DIR/issue-74280.rs:10:5 | LL | fn test() -> Test { | ---- expected `()` because of return type diff --git a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs index 90ab4fd8d977..3e17126834cc 100644 --- a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs +++ b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs @@ -7,19 +7,17 @@ //@ check-pass #![feature(type_alias_impl_trait)] -mod g { - pub trait Dummy {} - impl Dummy for () {} - pub type F = impl Dummy; - pub fn f() -> F {} -} -use g::*; +pub trait Dummy {} +impl Dummy for () {} +pub type F = impl Dummy; +#[define_opaque(F)] +pub fn f() -> F {} trait Test { fn test(self); } -impl Test for define::F { +impl Test for F { fn test(self) {} } @@ -29,17 +27,14 @@ impl Test for i32 { fn test(self) {} } -mod define { - use super::*; +pub trait Dummy2 {} +impl Dummy2 for () {} - pub trait Dummy {} - impl Dummy for () {} - - pub type F = impl Dummy; - pub fn f() -> F {} -} +pub type F2 = impl Dummy2; +#[define_opaque(F2)] +pub fn f2() -> F2 {} fn main() { - let x = define::f(); + let x = f(); x.test(); } diff --git a/tests/ui/type-alias-impl-trait/issue-77179.rs b/tests/ui/type-alias-impl-trait/issue-77179.rs index 1dc74c6b5fea..18afc54dbdc6 100644 --- a/tests/ui/type-alias-impl-trait/issue-77179.rs +++ b/tests/ui/type-alias-impl-trait/issue-77179.rs @@ -4,10 +4,11 @@ type Pointer = impl std::ops::Deref; +#[define_opaque(Pointer)] fn test() -> Pointer<_> { //~^ ERROR: the placeholder `_` is not allowed within types Box::new(1) - //~^ ERROR: mismatched types + //~^ ERROR: expected generic type parameter, found `i32` } fn main() { diff --git a/tests/ui/type-alias-impl-trait/issue-77179.stderr b/tests/ui/type-alias-impl-trait/issue-77179.stderr index 16bbc996d909..bc11283f3282 100644 --- a/tests/ui/type-alias-impl-trait/issue-77179.stderr +++ b/tests/ui/type-alias-impl-trait/issue-77179.stderr @@ -1,36 +1,28 @@ -error[E0308]: mismatched types - --> $DIR/issue-77179.rs:9:5 - | -LL | type Pointer = impl std::ops::Deref; - | -------------------------------- the expected opaque type -LL | -LL | fn test() -> Pointer<_> { - | ---------- expected `Pointer<_>` because of return type -LL | -LL | Box::new(1) - | ^^^^^^^^^^^ expected opaque type, found `Box<{integer}>` - | - = note: expected opaque type `Pointer<_>` - found struct `Box<{integer}>` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/issue-77179.rs:7:4 - | -LL | fn test() -> Pointer<_> { - | ^^^^ - error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/issue-77179.rs:7:22 + --> $DIR/issue-77179.rs:8:22 | LL | fn test() -> Pointer<_> { - | ^ not allowed in type signatures + | --------^- + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `Pointer` error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/issue-77179.rs:18:25 + --> $DIR/issue-77179.rs:19:25 | LL | fn bar() -> Pointer<_>; | ^ not allowed in type signatures +error[E0792]: expected generic type parameter, found `i32` + --> $DIR/issue-77179.rs:10:5 + | +LL | type Pointer = impl std::ops::Deref; + | - this generic parameter must be used with a generic type parameter +... +LL | Box::new(1) + | ^^^^^^^^^^^ + error: aborting due to 3 previous errors -Some errors have detailed explanations: E0121, E0308. +Some errors have detailed explanations: E0121, E0792. For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs index 2a39da1176c3..99ad48c8c323 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs @@ -8,6 +8,7 @@ trait Foo {} impl Foo for () {} type Bar = impl Foo; +#[define_opaque(Bar)] fn _defining_use() -> Bar {} trait TraitArg { diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr index ec7b9e0e12b3..577d8667a57a 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:29:1 + --> $DIR/issue-84660-unsoundness.rs:31:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here @@ -7,14 +7,14 @@ LL | impl Trait for Out { LL | impl Trait<(), In> for Out { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation -error: item does not constrain `Bar::{opaque#0}`, but has it in its signature - --> $DIR/issue-84660-unsoundness.rs:22:8 +error: item does not constrain `Bar::{opaque#0}` + --> $DIR/issue-84660-unsoundness.rs:24:8 | LL | fn convert(_i: In) -> Self::Out { | ^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/issue-84660-unsoundness.rs:12:12 | LL | type Bar = impl Foo; diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr index e33102f687c5..9e83de5375fd 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:29:1 + --> $DIR/issue-84660-unsoundness.rs:31:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here @@ -8,7 +8,7 @@ LL | impl Trait<(), In> for Out { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error[E0284]: type annotations needed: cannot satisfy `Bar == _` - --> $DIR/issue-84660-unsoundness.rs:22:37 + --> $DIR/issue-84660-unsoundness.rs:24:37 | LL | fn convert(_i: In) -> Self::Out { | _____________________________________^ diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index f3234bafd115..4391bf01dc91 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -10,6 +10,7 @@ trait Foo {} impl Foo for () {} type Bar = impl Foo; +#[define_opaque(Bar)] fn _defining_use() -> Bar {} trait Trait { @@ -19,9 +20,10 @@ trait Trait { impl Trait for Out { type Out = Out; + #[define_opaque(Bar)] fn convert(_i: In) -> Self::Out { //[next]~^ ERROR: cannot satisfy `Bar == _` - //[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`, but has it in its signature + //[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}` unreachable!(); } } diff --git a/tests/ui/type-alias-impl-trait/issue-89686.rs b/tests/ui/type-alias-impl-trait/issue-89686.rs index f734c518dd21..5370b8844ffa 100644 --- a/tests/ui/type-alias-impl-trait/issue-89686.rs +++ b/tests/ui/type-alias-impl-trait/issue-89686.rs @@ -11,6 +11,7 @@ trait Trait { fn f(&self) -> Self::F; + #[define_opaque(G)] fn g<'a>(&'a self) -> G<'a, Self> where Self: Sized, diff --git a/tests/ui/type-alias-impl-trait/issue-89686.stderr b/tests/ui/type-alias-impl-trait/issue-89686.stderr index 6fa7e197c40c..7ad1442f666c 100644 --- a/tests/ui/type-alias-impl-trait/issue-89686.stderr +++ b/tests/ui/type-alias-impl-trait/issue-89686.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/issue-89686.rs:18:9 + --> $DIR/issue-89686.rs:19:9 | LL | async move { self.f().await } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` diff --git a/tests/ui/type-alias-impl-trait/issue-93411.rs b/tests/ui/type-alias-impl-trait/issue-93411.rs index 2d08b7ba4c11..11cbb8766315 100644 --- a/tests/ui/type-alias-impl-trait/issue-93411.rs +++ b/tests/ui/type-alias-impl-trait/issue-93411.rs @@ -14,6 +14,7 @@ fn main() { } type BlahFut<'a> = impl Future + Send + 'a; +#[define_opaque(BlahFut)] fn blah<'a>(_value: &'a u8) -> BlahFut<'a> { async {} } diff --git a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs index 7097123d608c..08f3c404bed6 100644 --- a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs +++ b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs @@ -44,6 +44,7 @@ fn r#struct() { mod only_pattern { type T = impl Copy; + #[define_opaque(T)] fn foo(foo: T) { let (mut x, mut y) = foo; x = 42; @@ -52,6 +53,7 @@ mod only_pattern { type U = impl Copy; + #[define_opaque(U)] fn bar(bar: Option) { match bar { Some((mut x, mut y)) => { @@ -64,6 +66,7 @@ mod only_pattern { type V = impl Copy; + #[define_opaque(V)] fn baz(baz: Option) { match baz { _ => {} diff --git a/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr b/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr index c177201431a6..5b38b83e4d93 100644 --- a/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr +++ b/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr @@ -11,11 +11,6 @@ LL | let x: <() as Foo>::Assoc = 42_i32; | = note: expected opaque type `<() as Foo>::Assoc` found type `i32` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/itiat-forbid-nested-items.rs:11:12 - | -LL | fn foo() -> <() as Foo>::Assoc { - | ^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs index 1bc352041a57..075b0bd75fa5 100644 --- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs +++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs @@ -6,6 +6,7 @@ type Tait = impl FnOnce() -> (); +#[define_opaque(Tait)] fn reify_as_tait() -> Thunk { //~^ ERROR: expected a `FnOnce()` closure, found `()` Thunk::new(|cont| cont) diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr index 921667f577b4..0bee0dfa9c7a 100644 --- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr +++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/lazy_subtyping_of_opaques.rs:11:5 + --> $DIR/lazy_subtyping_of_opaques.rs:12:5 | LL | fn reify_as_tait() -> Thunk { | ----------- expected `Thunk<_>` because of return type @@ -11,7 +11,7 @@ LL | Thunk::new(|cont| cont) found unit type `()` error[E0277]: expected a `FnOnce()` closure, found `()` - --> $DIR/lazy_subtyping_of_opaques.rs:11:23 + --> $DIR/lazy_subtyping_of_opaques.rs:12:23 | LL | Thunk::new(|cont| cont) | ^^^^ expected an `FnOnce()` closure, found `()` @@ -20,7 +20,7 @@ LL | Thunk::new(|cont| cont) = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` error[E0277]: expected a `FnOnce()` closure, found `()` - --> $DIR/lazy_subtyping_of_opaques.rs:9:23 + --> $DIR/lazy_subtyping_of_opaques.rs:10:23 | LL | fn reify_as_tait() -> Thunk { | ^^^^^^^^^^^ expected an `FnOnce()` closure, found `()` diff --git a/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs b/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs index 45a55050c443..b58840718a35 100644 --- a/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs +++ b/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs @@ -2,6 +2,7 @@ type Foo<'a> = impl Sized; +#[define_opaque(Foo)] fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> (Foo<'a>, Foo<'b>) { (x, y) //~^ ERROR opaque type used twice with different lifetimes @@ -9,6 +10,7 @@ fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> (Foo<'a>, Foo<'b>) { type Bar<'a, 'b> = impl std::fmt::Debug; +#[define_opaque(Bar)] fn bar<'x, 'y>(i: &'x i32, j: &'y i32) -> (Bar<'x, 'y>, Bar<'y, 'x>) { (i, j) //~^ ERROR opaque type used twice with different lifetimes diff --git a/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr b/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr index 4f7b0f174076..719748edc011 100644 --- a/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr +++ b/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr @@ -1,5 +1,5 @@ error: opaque type used twice with different lifetimes - --> $DIR/lifetime_mismatch.rs:6:5 + --> $DIR/lifetime_mismatch.rs:7:5 | LL | (x, y) | ^^^^^^ @@ -8,13 +8,13 @@ LL | (x, y) | lifetime `'b` previously used here | note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/lifetime_mismatch.rs:6:5 + --> $DIR/lifetime_mismatch.rs:7:5 | LL | (x, y) | ^^^^^^ error: opaque type used twice with different lifetimes - --> $DIR/lifetime_mismatch.rs:13:5 + --> $DIR/lifetime_mismatch.rs:15:5 | LL | (i, j) | ^^^^^^ @@ -23,7 +23,7 @@ LL | (i, j) | lifetime `'y` previously used here | note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/lifetime_mismatch.rs:13:5 + --> $DIR/lifetime_mismatch.rs:15:5 | LL | (i, j) | ^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/method_resolution.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution.current.stderr index a9c05ad33424..07e7126f8a05 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution.current.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution.current.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `bar` found for struct `Bar` in the current scope - --> $DIR/method_resolution.rs:21:14 + --> $DIR/method_resolution.rs:22:14 | LL | struct Bar(T); | ------------- method `bar` not found for this struct diff --git a/tests/ui/type-alias-impl-trait/method_resolution.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution.next.stderr index 6b34358a56ea..7462d2b478bb 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution.next.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `bar` found for struct `Bar` in the current scope - --> $DIR/method_resolution.rs:21:14 + --> $DIR/method_resolution.rs:22:14 | LL | struct Bar(T); | ------------- method `bar` not found for this struct diff --git a/tests/ui/type-alias-impl-trait/method_resolution.rs b/tests/ui/type-alias-impl-trait/method_resolution.rs index f636aba15c0c..a9162d0e28be 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution.rs @@ -11,6 +11,7 @@ type Foo = impl Sized; struct Bar(T); impl Bar { + #[define_opaque(Foo)] fn bar(mut self) { self.0 = 42_u32; } @@ -23,6 +24,7 @@ impl Bar { } } +#[define_opaque(Foo)] fn foo() -> Foo { 42_u32 } diff --git a/tests/ui/type-alias-impl-trait/method_resolution2.rs b/tests/ui/type-alias-impl-trait/method_resolution2.rs index f69661db7992..a4c4bbbace6b 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution2.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution2.rs @@ -12,6 +12,7 @@ type Foo = impl Sized; struct Bar(T); impl Bar { + #[define_opaque(Foo)] fn bar(self) { self.foo() } @@ -21,6 +22,7 @@ impl Bar { fn foo(self) {} } +#[define_opaque(Foo)] fn foo() -> Foo { 42_u32 } diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.rs b/tests/ui/type-alias-impl-trait/method_resolution3.rs index 0e6176bfe03c..a18dcc9a2fe3 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution3.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution3.rs @@ -27,6 +27,7 @@ impl Bar { fn foo(self) {} } +#[define_opaque(Foo)] fn foo() -> Foo { 42_u32 } diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr index e4c4d121733b..569a9f49bbe4 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr @@ -1,5 +1,5 @@ error[E0307]: invalid `self` parameter type: `Bar` - --> $DIR/method_resolution4.rs:27:18 + --> $DIR/method_resolution4.rs:25:18 | LL | fn foo(self: Bar) { | ^^^^^^^^ @@ -8,7 +8,7 @@ LL | fn foo(self: Bar) { = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0307]: invalid `self` parameter type: `&Bar` - --> $DIR/method_resolution4.rs:31:20 + --> $DIR/method_resolution4.rs:29:20 | LL | fn foomp(self: &Bar) { | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr index e4c4d121733b..569a9f49bbe4 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr @@ -1,5 +1,5 @@ error[E0307]: invalid `self` parameter type: `Bar` - --> $DIR/method_resolution4.rs:27:18 + --> $DIR/method_resolution4.rs:25:18 | LL | fn foo(self: Bar) { | ^^^^^^^^ @@ -8,7 +8,7 @@ LL | fn foo(self: Bar) { = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0307]: invalid `self` parameter type: `&Bar` - --> $DIR/method_resolution4.rs:31:20 + --> $DIR/method_resolution4.rs:29:20 | LL | fn foomp(self: &Bar) { | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.rs b/tests/ui/type-alias-impl-trait/method_resolution4.rs index f33b4e473ae8..8a1b60b0c6e3 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution4.rs @@ -7,14 +7,12 @@ #![feature(type_alias_impl_trait, arbitrary_self_types)] -mod foo { - pub type Foo = impl Copy; +pub type Foo = impl Copy; - fn foo() -> Foo { - 42_u32 - } +#[define_opaque(Foo)] +fn foo() -> Foo { + 42_u32 } -use foo::Foo; #[derive(Copy, Clone)] struct Bar(T); diff --git a/tests/ui/type-alias-impl-trait/method_resolution5.rs b/tests/ui/type-alias-impl-trait/method_resolution5.rs index 64355e4560de..b22c44ceb138 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution5.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution5.rs @@ -12,20 +12,20 @@ type Foo = impl Sized; struct Bar(T); impl Bar { + #[define_opaque(Foo)] fn bar(mut self) { self.0 = 42_u32; } } impl Bar { - fn foo(self) - where - Foo:, - { + #[define_opaque(Foo)] + fn foo(self) { self.bar() } } +#[define_opaque(Foo)] fn foo() -> Foo { 42_u32 } diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr index f331da1af879..841aa12f9830 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr @@ -1,11 +1,11 @@ -error: item does not constrain `Tait::{opaque#0}`, but has it in its signature - --> $DIR/method_resolution_trait_method_from_opaque.rs:24:8 +error: item does not constrain `Tait::{opaque#0}` + --> $DIR/method_resolution_trait_method_from_opaque.rs:26:8 | LL | fn foo(&mut self) { | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/method_resolution_trait_method_from_opaque.rs:17:13 | LL | type Tait = impl Iterator; diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr index 2617ce124c10..bbdd3923821f 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 + --> $DIR/method_resolution_trait_method_from_opaque.rs:28:9 | LL | self.bar.next().unwrap(); | ^^^^^^^^ cannot infer type diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs index b6adf08853f2..93461fcbb0b2 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs @@ -17,10 +17,12 @@ pub struct Foo { type Tait = impl Iterator; impl Foo { + #[define_opaque(Tait)] pub fn new() -> Foo { Foo { bar: std::iter::empty() } } + #[define_opaque(Tait)] fn foo(&mut self) { //[current]~^ ERROR: item does not constrain self.bar.next().unwrap(); diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs index c178fcf5a914..d77efa39aeb6 100644 --- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs +++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs @@ -2,6 +2,7 @@ type Opaque2 = impl Sized; type Opaque<'a, T> = Opaque2; +#[define_opaque(Opaque)] fn defining<'a, T>(x: &'a i32) -> Opaque { x } //~ WARNING elided lifetime has a name //~^ ERROR: hidden type for `Opaque2` captures lifetime that does not appear in bounds diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr index e2c21f1636b0..61eb76ffc5ae 100644 --- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr +++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr @@ -1,5 +1,5 @@ warning: elided lifetime has a name - --> $DIR/missing_lifetime_bound.rs:5:41 + --> $DIR/missing_lifetime_bound.rs:6:41 | LL | fn defining<'a, T>(x: &'a i32) -> Opaque { x } | -- ^ this elided lifetime gets resolved as `'a` @@ -9,11 +9,11 @@ LL | fn defining<'a, T>(x: &'a i32) -> Opaque { x } = note: `#[warn(elided_named_lifetimes)]` on by default error[E0700]: hidden type for `Opaque2` captures lifetime that does not appear in bounds - --> $DIR/missing_lifetime_bound.rs:5:47 + --> $DIR/missing_lifetime_bound.rs:6:47 | LL | type Opaque2 = impl Sized; | ---------- opaque type defined here -LL | type Opaque<'a, T> = Opaque2; +... LL | fn defining<'a, T>(x: &'a i32) -> Opaque { x } | -- ^ | | diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs index b887fcf30831..3dd2d53fe3d8 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs @@ -6,6 +6,7 @@ type Y = impl std::fmt::Debug; +#[define_opaque(Y)] fn g() -> (Y, Y) { (42_i64, 60) //~ ERROR concrete type differs from previous defining opaque type use } diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr index b050b08a8e2e..d6558576577f 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr @@ -1,5 +1,5 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn-infer.rs:10:5 + --> $DIR/multiple-def-uses-in-one-fn-infer.rs:11:5 | LL | (42_i64, 60) | ^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs index 580fb58ef838..39e4912ae3af 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs @@ -2,6 +2,7 @@ type Foo<'a, 'b> = impl std::fmt::Debug; +#[define_opaque(Foo)] fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { (i, j) //~^ ERROR opaque type used twice with different lifetimes diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr index b2b9e604a6b6..03f2b1c532a0 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr @@ -1,5 +1,5 @@ error: opaque type used twice with different lifetimes - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 + --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:7:5 | LL | (i, j) | ^^^^^^ @@ -8,7 +8,7 @@ LL | (i, j) | lifetime `'y` previously used here | note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 + --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:7:5 | LL | (i, j) | ^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs index aba41a9d8523..50c97060cef5 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs @@ -3,11 +3,13 @@ type X = impl ToString; +#[define_opaque(X)] fn f(a: A, b: B) -> (X, X) { (a.clone(), a) } type Tait<'x> = impl Sized; +#[define_opaque(Tait)] fn define<'a: 'b, 'b: 'a>(x: &'a u8, y: &'b u8) -> (Tait<'a>, Tait<'b>) { ((), ()) } diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs index da845e86147b..5e2b140ef8b4 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs @@ -6,6 +6,7 @@ type X = impl Into<&'static A>; +#[define_opaque(X)] fn f(a: &'static A, b: B) -> (X, X) { //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied (a, a) diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr index b5f38074632e..05a169882cb1 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied - --> $DIR/multiple-def-uses-in-one-fn.rs:9:45 + --> $DIR/multiple-def-uses-in-one-fn.rs:10:45 | LL | fn f(a: &'static A, b: B) -> (X, X) { | ^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B` diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs index 14510a5294e6..1357d772be17 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs @@ -6,6 +6,7 @@ type X = impl ToString; +#[define_opaque(X)] fn f(a: A, b: B) -> (X, X) { (a.clone(), a) //~^ ERROR concrete type differs from previous defining opaque type diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr index c7a4b2115bf2..15e9b6fbf761 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr @@ -1,5 +1,5 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn2.rs:10:5 + --> $DIR/multiple-def-uses-in-one-fn2.rs:11:5 | LL | (a.clone(), a) | ^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs index 11a922443e64..11d23efec75d 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs @@ -6,10 +6,12 @@ type X = impl ToString; +#[define_opaque(X)] fn f(a: A, b: B) -> (X, X) { (a, b) } +#[define_opaque(X)] fn g(a: A, b: B) -> (X, X) { (a, b) //~^ ERROR mismatched types diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr index c3128ea6f5e9..42ba769797b7 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9 + --> $DIR/multiple-def-uses-in-one-fn3.rs:16:9 | LL | fn g(a: A, b: B) -> (X, X) { | - - found type parameter diff --git a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr index ca15b134a994..3a13ab7cb957 100644 --- a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr +++ b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr @@ -31,7 +31,7 @@ error: unconstrained opaque type LL | pub type Tait = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `Tait` must be used in combination with a concrete type within the same module + = note: `Tait` must be used in combination with a concrete type within the same crate error: unconstrained opaque type --> $DIR/nested-impl-trait-in-tait.rs:3:54 @@ -39,7 +39,7 @@ error: unconstrained opaque type LL | pub type Tait = impl Iterator; | ^^^^^^^^^^^^^ | - = note: `Tait` must be used in combination with a concrete type within the same module + = note: `Tait` must be used in combination with a concrete type within the same crate error: aborting due to 4 previous errors diff --git a/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr b/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr index aa0c1076117c..54389efc9c6d 100644 --- a/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr +++ b/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr @@ -13,7 +13,7 @@ error: unconstrained opaque type LL | type B = impl Sized; | ^^^^^^^^^^ | - = note: `B` must be used in combination with a concrete type within the same item + = note: `B` must be used in combination with a concrete type within the same crate error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs index ba705d6f85ac..6ef6f31953fb 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs @@ -4,11 +4,13 @@ trait Trait<'a> { type Assoc; } impl<'a> Trait<'a> for () { type Assoc = &'a str; } type WithoutLt = impl Sized; +#[define_opaque(WithoutLt)] fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {} //~^ ERROR captures lifetime that does not appear in bounds type WithLt<'a> = impl Sized + 'a; +#[define_opaque(WithLt)] fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {} //~^ ERROR expected generic lifetime parameter, found `'a` diff --git a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr index f208730552d9..ad60d186dd36 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr @@ -1,19 +1,20 @@ error[E0700]: hidden type for `WithoutLt` captures lifetime that does not appear in bounds - --> $DIR/nested-tait-hrtb.rs:7:62 + --> $DIR/nested-tait-hrtb.rs:8:62 | LL | type WithoutLt = impl Sized; | ---------- opaque type defined here +LL | #[define_opaque(WithoutLt)] LL | fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {} | -- ^^ | | | hidden type `&'a str` captures the lifetime `'a` as defined here error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/nested-tait-hrtb.rs:12:60 + --> $DIR/nested-tait-hrtb.rs:14:60 | LL | type WithLt<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter -LL | +... LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {} | ^^ diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr index 915432bbe675..b19f34a67ff7 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference.rs:17:13 + --> $DIR/nested-tait-inference.rs:18:13 | LL | fn foo() -> impl Foo { | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs index 50d51c7faf91..d4ad72797cfe 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -14,6 +14,7 @@ trait Foo {} impl Foo<()> for () {} +#[define_opaque(FooX)] fn foo() -> impl Foo { //[current]~^ ERROR: the trait bound `(): Foo` is not satisfied // FIXME(type-alias-impl-trait): We could probably make this work. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr index 9da3926ac708..27372ceed949 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference2.rs:17:13 + --> $DIR/nested-tait-inference2.rs:18:13 | LL | fn foo() -> impl Foo { | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr index 9647d9e376eb..b733739e4c86 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr @@ -1,5 +1,5 @@ error[E0284]: type annotations needed: cannot satisfy `impl Foo == ()` - --> $DIR/nested-tait-inference2.rs:19:5 + --> $DIR/nested-tait-inference2.rs:20:5 | LL | () | ^^ cannot satisfy `impl Foo == ()` diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs index 28d72b0cbeed..4aeecb9140c5 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -14,6 +14,7 @@ trait Foo {} impl Foo<()> for () {} impl Foo for () {} +#[define_opaque(FooX)] fn foo() -> impl Foo { //[current]~^ ERROR: the trait bound `(): Foo` is not satisfied () diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs index aaf2812532d3..3e7b8c80d1b2 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs @@ -9,6 +9,7 @@ trait Foo {} impl Foo for () {} +#[define_opaque(FooX)] fn foo() -> impl Foo { //~^ ERROR: item does not constrain () diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr index 969409ebc59e..be7aec92312a 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr @@ -1,11 +1,11 @@ -error: item does not constrain `FooX::{opaque#0}`, but has it in its signature - --> $DIR/nested-tait-inference3.rs:12:4 +error: item does not constrain `FooX::{opaque#0}` + --> $DIR/nested-tait-inference3.rs:13:4 | LL | fn foo() -> impl Foo { | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/nested-tait-inference3.rs:6:13 | LL | type FooX = impl Debug; diff --git a/tests/ui/type-alias-impl-trait/nested.rs b/tests/ui/type-alias-impl-trait/nested.rs index 524703939f1d..1a89039af8a7 100644 --- a/tests/ui/type-alias-impl-trait/nested.rs +++ b/tests/ui/type-alias-impl-trait/nested.rs @@ -7,6 +7,7 @@ trait Trait {} impl Trait for U {} +#[define_opaque(Bar)] fn bar() -> Bar { //~^ ERROR: item does not constrain 42 diff --git a/tests/ui/type-alias-impl-trait/nested.stderr b/tests/ui/type-alias-impl-trait/nested.stderr index ca1cf6058ea9..59911f65a234 100644 --- a/tests/ui/type-alias-impl-trait/nested.stderr +++ b/tests/ui/type-alias-impl-trait/nested.stderr @@ -1,18 +1,18 @@ -error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/nested.rs:10:4 +error: item does not constrain `Foo::{opaque#0}` + --> $DIR/nested.rs:11:4 | LL | fn bar() -> Bar { | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/nested.rs:3:12 | LL | type Foo = impl std::fmt::Debug; | ^^^^^^^^^^^^^^^^^^^^ error[E0277]: `Bar` doesn't implement `Debug` - --> $DIR/nested.rs:16:22 + --> $DIR/nested.rs:17:22 | LL | println!("{:?}", bar()); | ^^^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug` diff --git a/tests/ui/type-alias-impl-trait/nested_inference_failure.rs b/tests/ui/type-alias-impl-trait/nested_inference_failure.rs index 004e79d67387..c0581b018e94 100644 --- a/tests/ui/type-alias-impl-trait/nested_inference_failure.rs +++ b/tests/ui/type-alias-impl-trait/nested_inference_failure.rs @@ -22,6 +22,7 @@ struct Foo { type ImplT = impl Debug; type FooImpl = Foo; +#[define_opaque(FooImpl)] fn bar() -> FooImpl { Foo:: { f: |_| (), _phantom: PhantomData } } diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs index 4def8948708f..5adae476bfe2 100644 --- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs +++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs @@ -1,21 +1,21 @@ #![feature(type_alias_impl_trait)] -mod my_mod { - use std::fmt::Debug; +use std::fmt::Debug; - pub type Foo = impl Debug; - pub type Foot = impl Debug; +pub type Foo = impl Debug; +pub type Foot = impl Debug; - pub fn get_foo() -> Foo { - 5i32 - } +#[define_opaque(Foo)] +pub fn get_foo() -> Foo { + 5i32 +} - pub fn get_foot(_: Foo) -> Foot { - //~^ ERROR: item does not constrain `Foo::{opaque#0}`, but has it in its signature - get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type - } +#[define_opaque(Foot, Foo)] +pub fn get_foot(_: Foo) -> Foot { + //~^ ERROR: item does not constrain `Foo::{opaque#0}` + get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type } fn main() { - let _: my_mod::Foot = my_mod::get_foot(my_mod::get_foo()); + let _: Foot = get_foot(get_foo()); } diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr index 889cff1ba09e..aabae3157775 100644 --- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr +++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr @@ -1,32 +1,32 @@ -error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/nested_type_alias_impl_trait.rs:13:12 +error: item does not constrain `Foo::{opaque#0}` + --> $DIR/nested_type_alias_impl_trait.rs:14:8 | -LL | pub fn get_foot(_: Foo) -> Foot { - | ^^^^^^^^ +LL | pub fn get_foot(_: Foo) -> Foot { + | ^^^^^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/nested_type_alias_impl_trait.rs:6:20 + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/nested_type_alias_impl_trait.rs:5:16 | -LL | pub type Foo = impl Debug; - | ^^^^^^^^^^ +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/nested_type_alias_impl_trait.rs:15:9 + --> $DIR/nested_type_alias_impl_trait.rs:16:5 | -LL | get_foo() - | ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope +LL | get_foo() + | ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope | note: opaque type whose hidden type is being assigned - --> $DIR/nested_type_alias_impl_trait.rs:7:21 + --> $DIR/nested_type_alias_impl_trait.rs:6:17 | -LL | pub type Foot = impl Debug; - | ^^^^^^^^^^ +LL | pub type Foot = impl Debug; + | ^^^^^^^^^^ note: opaque type being used as hidden type - --> $DIR/nested_type_alias_impl_trait.rs:6:20 + --> $DIR/nested_type_alias_impl_trait.rs:5:16 | -LL | pub type Foo = impl Debug; - | ^^^^^^^^^^ +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs b/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs index 590107d10384..fc47243d693f 100644 --- a/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs +++ b/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs @@ -4,10 +4,12 @@ fn main() {} type NoReveal = impl std::fmt::Debug; +#[define_opaque(NoReveal)] fn define_no_reveal() -> NoReveal { "" } +#[define_opaque(NoReveal)] fn no_reveal(x: NoReveal) { let _: &'static str = x; let _ = x as &'static str; diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs index 41238c27351d..8e5e47194153 100644 --- a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs +++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs @@ -3,18 +3,17 @@ #![feature(type_alias_impl_trait)] -mod foo { - pub type Foo = impl Copy; +pub type Foo = impl Copy; - // make compiler happy about using 'Foo' - pub fn bar(x: Foo) -> Foo { - //~^ ERROR: item does not constrain `Foo::{opaque#0}` - x - } +// make compiler happy about using 'Foo' +#[define_opaque(Foo)] +pub fn bar(x: Foo) -> Foo { + //~^ ERROR: item does not constrain `Foo::{opaque#0}` + x } fn main() { unsafe { - let _: foo::Foo = std::mem::transmute(0u8); + let _: Foo = std::mem::transmute(0u8); } } diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr index eed88c5df4f4..a57793d5a772 100644 --- a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr +++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -1,15 +1,15 @@ -error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/no_inferrable_concrete_type.rs:10:12 +error: item does not constrain `Foo::{opaque#0}` + --> $DIR/no_inferrable_concrete_type.rs:10:8 | -LL | pub fn bar(x: Foo) -> Foo { - | ^^^ +LL | pub fn bar(x: Foo) -> Foo { + | ^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/no_inferrable_concrete_type.rs:7:20 + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/no_inferrable_concrete_type.rs:6:16 | -LL | pub type Foo = impl Copy; - | ^^^^^^^^^ +LL | pub type Foo = impl Copy; + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs index 61153b1e1714..42161dcde660 100644 --- a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs +++ b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs @@ -2,11 +2,10 @@ fn main() {} -mod boo { - pub type Boo = impl ::std::fmt::Debug; - fn bomp() -> Boo { - "" - } +pub type Boo = impl ::std::fmt::Debug; +#[define_opaque(Boo)] +fn define() -> Boo { + "" } // We don't actually know the type here. @@ -15,10 +14,10 @@ fn bomp2() { let _: &str = bomp(); //~ ERROR mismatched types } -fn bomp() -> boo::Boo { +fn bomp() -> Boo { "" //~ ERROR mismatched types } -fn bomp_loop() -> boo::Boo { +fn bomp_loop() -> Boo { loop {} } diff --git a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr index 863282a0ff94..f4416eb009ae 100644 --- a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr +++ b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/no_revealing_outside_defining_module.rs:15:19 + --> $DIR/no_revealing_outside_defining_module.rs:14:19 | -LL | pub type Boo = impl ::std::fmt::Debug; - | ---------------------- the found opaque type +LL | pub type Boo = impl ::std::fmt::Debug; + | ---------------------- the found opaque type ... LL | let _: &str = bomp(); | ---- ^^^^^^ expected `&str`, found opaque type @@ -11,29 +11,29 @@ LL | let _: &str = bomp(); | = note: expected reference `&str` found opaque type `Boo` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/no_revealing_outside_defining_module.rs:14:4 +note: this item must have a `#[define_opaque(Boo)]` attribute to be able to define hidden types + --> $DIR/no_revealing_outside_defining_module.rs:13:4 | LL | fn bomp2() { | ^^^^^ error[E0308]: mismatched types - --> $DIR/no_revealing_outside_defining_module.rs:19:5 + --> $DIR/no_revealing_outside_defining_module.rs:18:5 | -LL | pub type Boo = impl ::std::fmt::Debug; - | ---------------------- the expected opaque type +LL | pub type Boo = impl ::std::fmt::Debug; + | ---------------------- the expected opaque type ... -LL | fn bomp() -> boo::Boo { - | -------- expected `Boo` because of return type +LL | fn bomp() -> Boo { + | --- expected `Boo` because of return type LL | "" | ^^ expected opaque type, found `&str` | = note: expected opaque type `Boo` found reference `&'static str` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/no_revealing_outside_defining_module.rs:18:4 +note: this item must have a `#[define_opaque(Boo)]` attribute to be able to define hidden types + --> $DIR/no_revealing_outside_defining_module.rs:17:4 | -LL | fn bomp() -> boo::Boo { +LL | fn bomp() -> Boo { | ^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs index 9fcf42e188c7..d0fcfb438fb9 100644 --- a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs +++ b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs @@ -18,7 +18,7 @@ pub fn tr1() -> impl Tr { } struct Inner { - x: helper::X, + x: X, } impl Tr for Inner { fn get(&self) -> u32 { @@ -26,14 +26,9 @@ impl Tr for Inner { } } -mod helper { - pub use super::*; - pub type X = impl Tr; +pub type X = impl Tr; - pub fn tr2() -> impl Tr - where - X:, - { - Inner { x: tr1() } - } +#[define_opaque(X)] +pub fn tr2() -> impl Tr { + Inner { x: tr1() } } diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr index a40dac06a01c..75cc5948e93c 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr @@ -1,29 +1,29 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/normalize-hidden-types.rs:26:20 + --> $DIR/normalize-hidden-types.rs:27:20 | LL | fn define() -> Opaque { | ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` | note: previous use here - --> $DIR/normalize-hidden-types.rs:27:9 + --> $DIR/normalize-hidden-types.rs:28:9 | LL | dyn_hoops::<_>(0) | ^^^^^^^^^^^^^^^^^ error: concrete type differs from previous defining opaque type use - --> $DIR/normalize-hidden-types.rs:34:22 + --> $DIR/normalize-hidden-types.rs:36:22 | LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } | ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` | note: previous use here - --> $DIR/normalize-hidden-types.rs:34:31 + --> $DIR/normalize-hidden-types.rs:36:31 | LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } | ^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/normalize-hidden-types.rs:43:25 + --> $DIR/normalize-hidden-types.rs:47:25 | LL | type Opaque = impl Sized; | ---------- the expected opaque type @@ -39,13 +39,13 @@ LL | let _: Opaque = dyn_hoops::(0); = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: concrete type differs from previous defining opaque type use - --> $DIR/normalize-hidden-types.rs:52:25 + --> $DIR/normalize-hidden-types.rs:57:25 | LL | let _: Opaque = dyn_hoops::<_>(0); | ^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` | note: previous use here - --> $DIR/normalize-hidden-types.rs:53:9 + --> $DIR/normalize-hidden-types.rs:58:9 | LL | None | ^^^^ diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs index 4028dba82bf1..bc007169b838 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs @@ -23,6 +23,7 @@ fn dyn_hoops(_: T) -> *const dyn FnOnce(T::Gat<'_>) { mod typeof_1 { use super::*; type Opaque = impl Sized; + #[define_opaque(Opaque)] fn define() -> Opaque { dyn_hoops::<_>(0) } @@ -31,13 +32,16 @@ mod typeof_1 { mod typeof_2 { use super::*; type Opaque = impl Sized; + #[define_opaque(Opaque)] fn define_1() -> Opaque { dyn_hoops::<_>(0) } + #[define_opaque(Opaque)] fn define_2() -> Opaque { dyn_hoops::(0) } } mod typeck { use super::*; type Opaque = impl Sized; + #[define_opaque(Opaque)] fn define() -> Option { let _: Opaque = dyn_hoops::<_>(0); let _: Opaque = dyn_hoops::(0); @@ -48,6 +52,7 @@ mod typeck { mod borrowck { use super::*; type Opaque = impl Sized; + #[define_opaque(Opaque)] fn define() -> Option { let _: Opaque = dyn_hoops::<_>(0); None diff --git a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.rs b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.rs index 131f8d999d87..112ee4d55715 100644 --- a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.rs +++ b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.rs @@ -9,6 +9,7 @@ trait Foo { struct DefinesOpaque; impl Foo for () { type Assoc = impl Sized; + //~^ ERROR: unconstrained opaque type // This test's return type is `u32`, *not* the opaque that is defined above. // Previously we were only checking that the self type of the assoc matched, diff --git a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr index d4528fb76fed..1d1b14e14635 100644 --- a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr +++ b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr @@ -1,5 +1,13 @@ +error: unconstrained opaque type + --> $DIR/not-matching-trait-refs-isnt-defining.rs:11:18 + | +LL | type Assoc = impl Sized; + | ^^^^^^^^^^ + | + = note: `Assoc` must be used in combination with a concrete type within the same impl + error[E0308]: mismatched types - --> $DIR/not-matching-trait-refs-isnt-defining.rs:17:54 + --> $DIR/not-matching-trait-refs-isnt-defining.rs:18:54 | LL | type Assoc = impl Sized; | ---------- the expected opaque type @@ -11,12 +19,7 @@ LL | let _: >::Assoc = ""; | = note: expected opaque type `<() as Foo>::Assoc` found reference `&'static str` -note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/not-matching-trait-refs-isnt-defining.rs:16:8 - | -LL | fn test() -> <() as Foo>::Assoc { - | ^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/not_a_defining_use.rs b/tests/ui/type-alias-impl-trait/not_a_defining_use.rs index b5ef1470629b..d20622dc2e05 100644 --- a/tests/ui/type-alias-impl-trait/not_a_defining_use.rs +++ b/tests/ui/type-alias-impl-trait/not_a_defining_use.rs @@ -6,6 +6,7 @@ fn main() {} type Two = impl Debug; +#[define_opaque(Two)] fn three(t: T) -> Two { (t, 5i8) } @@ -20,6 +21,7 @@ impl Bar for u32 { const FOO: i32 = 42; } +#[define_opaque(Two)] fn four(t: T) -> Two { (t, ::FOO) //~^ ERROR concrete type differs diff --git a/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr b/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr index b59f9c49b077..d90e4531879b 100644 --- a/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr +++ b/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/not_a_defining_use.rs:24:5 + --> $DIR/not_a_defining_use.rs:26:5 | LL | (t, ::FOO) | ^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, ::Blub)` | note: previous use here - --> $DIR/not_a_defining_use.rs:10:5 + --> $DIR/not_a_defining_use.rs:11:5 | LL | (t, 5i8) | ^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/not_well_formed.rs b/tests/ui/type-alias-impl-trait/not_well_formed.rs index 0cf8d41c7fd4..bd4477dbf0f3 100644 --- a/tests/ui/type-alias-impl-trait/not_well_formed.rs +++ b/tests/ui/type-alias-impl-trait/not_well_formed.rs @@ -16,6 +16,7 @@ trait Trait {} impl Trait for () {} +#[define_opaque(Foo)] fn foo_desugared(_: T) -> Foo { () } diff --git a/tests/ui/type-alias-impl-trait/obligation_ice.rs b/tests/ui/type-alias-impl-trait/obligation_ice.rs index e3698b23be86..134255e1eb26 100644 --- a/tests/ui/type-alias-impl-trait/obligation_ice.rs +++ b/tests/ui/type-alias-impl-trait/obligation_ice.rs @@ -8,6 +8,7 @@ trait Trait<'a, 'b: 'a> {} impl<'a, 'b: 'a, T> Trait<'a, 'b> for std::iter::Cloned {} type I<'a, 'b: 'a, A: Trait<'a, 'b>> = Chain>; +#[define_opaque(I)] fn test2<'a, 'b, A: Trait<'a, 'b> + Iterator>(x: A) -> I<'a, 'b, A> { x.chain(once("5")) } diff --git a/tests/ui/type-alias-impl-trait/outlives-bound-var.rs b/tests/ui/type-alias-impl-trait/outlives-bound-var.rs index 2c6f44d5416e..b1711e9eab84 100644 --- a/tests/ui/type-alias-impl-trait/outlives-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/outlives-bound-var.rs @@ -5,11 +5,9 @@ //@ check-pass #![feature(type_alias_impl_trait)] -mod tait { - pub type Ty<'a> = impl Sized + 'a; - fn define<'a>() -> Ty<'a> {} -} -use tait::Ty; +pub type Ty<'a> = impl Sized + 'a; +#[define_opaque(Ty)] +fn define<'a>() -> Ty<'a> {} // Ty<'^0>: 'static fn test1(_: &'static fn(Ty<'_>)) {} diff --git a/tests/ui/type-alias-impl-trait/param_mismatch.rs b/tests/ui/type-alias-impl-trait/param_mismatch.rs index c74650307137..4e4e06acfd40 100644 --- a/tests/ui/type-alias-impl-trait/param_mismatch.rs +++ b/tests/ui/type-alias-impl-trait/param_mismatch.rs @@ -8,6 +8,7 @@ fn id(s: &str) -> &str { } type Opaque<'a> = impl Sized + 'a; // The second `Opaque<'_>` has a higher kinded lifetime, not a generic parameter +#[define_opaque(Opaque)] fn test(s: &str) -> (Opaque<'_>, impl Fn(&str) -> Opaque<'_>) { (s, id) //~^ ERROR: expected generic lifetime parameter, found `'_` diff --git a/tests/ui/type-alias-impl-trait/param_mismatch.stderr b/tests/ui/type-alias-impl-trait/param_mismatch.stderr index 09ec550d7183..07a8ce38f980 100644 --- a/tests/ui/type-alias-impl-trait/param_mismatch.stderr +++ b/tests/ui/type-alias-impl-trait/param_mismatch.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/param_mismatch.rs:12:5 + --> $DIR/param_mismatch.rs:13:5 | LL | type Opaque<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/param_mismatch2.rs b/tests/ui/type-alias-impl-trait/param_mismatch2.rs index c7d5eaa16aae..f6a997114110 100644 --- a/tests/ui/type-alias-impl-trait/param_mismatch2.rs +++ b/tests/ui/type-alias-impl-trait/param_mismatch2.rs @@ -9,6 +9,7 @@ fn id(s: &str) -> &str { type Opaque<'a> = impl Sized + 'a; +#[define_opaque(Opaque)] fn test(s: &str) -> (impl Fn(&str) -> Opaque<'_>, impl Fn(&str) -> Opaque<'_>) { (id, id) //~ ERROR: expected generic lifetime parameter, found `'_` } diff --git a/tests/ui/type-alias-impl-trait/param_mismatch2.stderr b/tests/ui/type-alias-impl-trait/param_mismatch2.stderr index 1ecdd7c2b54c..f5ecade2f02e 100644 --- a/tests/ui/type-alias-impl-trait/param_mismatch2.stderr +++ b/tests/ui/type-alias-impl-trait/param_mismatch2.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/param_mismatch2.rs:13:5 + --> $DIR/param_mismatch2.rs:14:5 | LL | type Opaque<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/param_mismatch3.rs b/tests/ui/type-alias-impl-trait/param_mismatch3.rs index 03c133d5d3c2..17b6f8bce2a8 100644 --- a/tests/ui/type-alias-impl-trait/param_mismatch3.rs +++ b/tests/ui/type-alias-impl-trait/param_mismatch3.rs @@ -9,6 +9,7 @@ fn id2<'a, 'b>(s: (&'a str, &'b str)) -> (&'a str, &'b str) { type Opaque<'a> = impl Sized + 'a; +#[define_opaque(Opaque)] fn test() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque<'a>, Opaque<'b>) { id2 //~ ERROR expected generic lifetime parameter, found `'a` } @@ -19,6 +20,7 @@ fn id(s: &str) -> &str { type Opaque2<'a> = impl Sized + 'a; +#[define_opaque(Opaque2)] fn test2(s: &str) -> (impl Fn(&str) -> Opaque2<'_>, Opaque2<'_>) { (id, s) //~ ERROR: expected generic lifetime parameter, found `'_` } diff --git a/tests/ui/type-alias-impl-trait/param_mismatch3.stderr b/tests/ui/type-alias-impl-trait/param_mismatch3.stderr index b8805f9b7f65..7565bbfc6ff0 100644 --- a/tests/ui/type-alias-impl-trait/param_mismatch3.stderr +++ b/tests/ui/type-alias-impl-trait/param_mismatch3.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/param_mismatch3.rs:13:5 + --> $DIR/param_mismatch3.rs:14:5 | LL | type Opaque<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter @@ -8,7 +8,7 @@ LL | id2 | ^^^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/param_mismatch3.rs:23:5 + --> $DIR/param_mismatch3.rs:25:5 | LL | type Opaque2<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/param_mismatch4.rs b/tests/ui/type-alias-impl-trait/param_mismatch4.rs index e072f3ab8e05..bc32143d0eb1 100644 --- a/tests/ui/type-alias-impl-trait/param_mismatch4.rs +++ b/tests/ui/type-alias-impl-trait/param_mismatch4.rs @@ -8,6 +8,7 @@ type Opq<'a> = impl Sized; // Two defining uses: Opq<'{empty}> and Opq<'a>. // This used to ICE. // issue: #122782 +#[define_opaque(Opq)] fn build<'a>() -> Opq<'a> { let _: Opq<'_> = (); //~^ ERROR expected generic lifetime parameter, found `'_` diff --git a/tests/ui/type-alias-impl-trait/param_mismatch4.stderr b/tests/ui/type-alias-impl-trait/param_mismatch4.stderr index d3fdea25a3dc..647637ae32a7 100644 --- a/tests/ui/type-alias-impl-trait/param_mismatch4.stderr +++ b/tests/ui/type-alias-impl-trait/param_mismatch4.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/param_mismatch4.rs:12:12 + --> $DIR/param_mismatch4.rs:13:12 | LL | type Opq<'a> = impl Sized; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/path_resolution_taint.rs b/tests/ui/type-alias-impl-trait/path_resolution_taint.rs new file mode 100644 index 000000000000..b320e88450bd --- /dev/null +++ b/tests/ui/type-alias-impl-trait/path_resolution_taint.rs @@ -0,0 +1,16 @@ +//! This test used to ICE #131298 + +#![feature(type_alias_impl_trait)] + +fn dyn_hoops() -> *const dyn Iterator { + //~^ ERROR: cannot find trait `Captures` in this scope + loop {} +} + +type Opaque = impl Sized; +#[define_opaque(Opaque)] +fn define() -> Opaque { + let _: Opaque = dyn_hoops::(); +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/path_resolution_taint.stderr b/tests/ui/type-alias-impl-trait/path_resolution_taint.stderr new file mode 100644 index 000000000000..122c7c1ffbfa --- /dev/null +++ b/tests/ui/type-alias-impl-trait/path_resolution_taint.stderr @@ -0,0 +1,9 @@ +error[E0405]: cannot find trait `Captures` in this scope + --> $DIR/path_resolution_taint.rs:5:54 + | +LL | fn dyn_hoops() -> *const dyn Iterator { + | ^^^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/type-alias-impl-trait/privacy.rs b/tests/ui/type-alias-impl-trait/privacy.rs index a5386bbec0d2..4fbb9c7313f8 100644 --- a/tests/ui/type-alias-impl-trait/privacy.rs +++ b/tests/ui/type-alias-impl-trait/privacy.rs @@ -3,6 +3,7 @@ #![feature(type_alias_impl_trait)] type Foo = (impl Sized, u8); +#[define_opaque(Foo)] pub fn foo() -> Foo { //~^ WARNING type alias `Foo` is more private than the item `foo` (42, 42) diff --git a/tests/ui/type-alias-impl-trait/privacy.stderr b/tests/ui/type-alias-impl-trait/privacy.stderr index 50870905c30d..eeb49b1a4ac9 100644 --- a/tests/ui/type-alias-impl-trait/privacy.stderr +++ b/tests/ui/type-alias-impl-trait/privacy.stderr @@ -1,5 +1,5 @@ warning: type alias `Foo` is more private than the item `foo` - --> $DIR/privacy.rs:6:1 + --> $DIR/privacy.rs:7:1 | LL | pub fn foo() -> Foo { | ^^^^^^^^^^^^^^^^^^^ function `foo` is reachable at visibility `pub` diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs index 3d1759097d6b..cfd7e1bf3823 100644 --- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs +++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs @@ -3,10 +3,12 @@ pub type Diff = impl Fn(usize) -> usize; +#[define_opaque(Diff)] pub fn lift() -> Diff { |_: usize |loop {} } +#[define_opaque(Diff)] pub fn add( n: Diff, m: Diff, diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr index e8925b9b489f..1a8ab2194049 100644 --- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr +++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/recursive-fn-tait.rs:14:5 + --> $DIR/recursive-fn-tait.rs:16:5 | LL | move |x: usize| m(n(x)) - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:7:5: 7:16}`, got `{closure@$DIR/recursive-fn-tait.rs:14:5: 14:20}` + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:8:5: 8:16}`, got `{closure@$DIR/recursive-fn-tait.rs:16:5: 16:20}` | note: previous use here - --> $DIR/recursive-fn-tait.rs:7:5 + --> $DIR/recursive-fn-tait.rs:8:5 | LL | |_: usize |loop {} | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs index 10588398c9d7..26ffd5c16a29 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs @@ -3,11 +3,15 @@ #![feature(type_alias_impl_trait)] type Op = impl std::fmt::Display; -fn foo() -> Op { &"hello world" } +#[define_opaque(Op)] +fn foo() -> Op { + &"hello world" +} fn transform() -> impl std::fmt::Display { &0usize } +#[define_opaque(Op)] fn bad() -> Op { transform::() //~^ ERROR concrete type differs from previous defining opaque type use diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr index eec35548c550..259f3b2b9f3d 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/recursive-tait-conflicting-defn-2.rs:12:5 + --> $DIR/recursive-tait-conflicting-defn-2.rs:16:5 | LL | transform::() | ^^^^^^^^^^^^^^^^^ expected `&'static &'static str`, got `impl std::fmt::Display` | note: previous use here - --> $DIR/recursive-tait-conflicting-defn-2.rs:6:18 + --> $DIR/recursive-tait-conflicting-defn-2.rs:8:5 | -LL | fn foo() -> Op { &"hello world" } - | ^^^^^^^^^^^^^^ +LL | &"hello world" + | ^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs index 38fb493b4989..c9e2773905d7 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs @@ -14,24 +14,23 @@ struct B { impl Test for B {} -mod helper { - use super::*; - pub type TestImpl = impl Test; +pub type TestImpl = impl Test; - pub fn test() -> TestImpl { - A - } - - fn make_option2() -> Option { - let inner = make_option().unwrap(); - - Some(B { inner }) - //~^ ERROR concrete type differs from previous defining opaque type use - } +#[define_opaque(TestImpl)] +pub fn test() -> TestImpl { + A } -fn make_option() -> Option { - Some(helper::test()) +#[define_opaque(TestImpl)] +fn make_option2() -> Option { + let inner = make_option().unwrap(); + + Some(B { inner }) + //~^ ERROR concrete type differs from previous defining opaque type use +} + +fn make_option() -> Option { + Some(test()) } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr index 252c5d7dfa76..47471c9728c4 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/recursive-tait-conflicting-defn.rs:28:9 + --> $DIR/recursive-tait-conflicting-defn.rs:28:5 | -LL | Some(B { inner }) - | ^^^^^^^^^^^^^^^^^ expected `A`, got `B` +LL | Some(B { inner }) + | ^^^^^^^^^^^^^^^^^ expected `A`, got `B` | note: previous use here - --> $DIR/recursive-tait-conflicting-defn.rs:22:9 + --> $DIR/recursive-tait-conflicting-defn.rs:21:5 | -LL | A - | ^ +LL | A + | ^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/reveal_local.rs b/tests/ui/type-alias-impl-trait/reveal_local.rs index 34f3788e2341..1e1e118937b2 100644 --- a/tests/ui/type-alias-impl-trait/reveal_local.rs +++ b/tests/ui/type-alias-impl-trait/reveal_local.rs @@ -7,12 +7,13 @@ type Foo = impl Debug; fn is_send() {} fn not_good() { - // Error: this function does not constrain `Foo` to any particular - // hidden type, so it cannot rely on `Send` being true. + // This function does not define `Foo`, + // so it can actually check auto traits on the hidden type without + // risking cycle errors. is_send::(); - //~^ ERROR: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits } +#[define_opaque(Foo)] fn not_gooder() -> Foo { // Constrain `Foo = u32` let x: Foo = 22_u32; diff --git a/tests/ui/type-alias-impl-trait/reveal_local.stderr b/tests/ui/type-alias-impl-trait/reveal_local.stderr index 9829c58cf73b..bd0828885910 100644 --- a/tests/ui/type-alias-impl-trait/reveal_local.stderr +++ b/tests/ui/type-alias-impl-trait/reveal_local.stderr @@ -1,23 +1,5 @@ -error: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits - --> $DIR/reveal_local.rs:12:15 - | -LL | is_send::(); - | ^^^ - | - = note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule -note: opaque type is declared here - --> $DIR/reveal_local.rs:5:12 - | -LL | type Foo = impl Debug; - | ^^^^^^^^^^ -note: required by a bound in `is_send` - --> $DIR/reveal_local.rs:7:15 - | -LL | fn is_send() {} - | ^^^^ required by this bound in `is_send` - error[E0283]: type annotations needed: cannot satisfy `Foo: Send` - --> $DIR/reveal_local.rs:22:15 + --> $DIR/reveal_local.rs:23:15 | LL | is_send::(); | ^^^ @@ -29,6 +11,6 @@ note: required by a bound in `is_send` LL | fn is_send() {} | ^^^^ required by this bound in `is_send` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs index 37d84feee4b8..242a4b3cd3ee 100644 --- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs @@ -12,19 +12,16 @@ #![feature(type_alias_impl_trait)] -mod helper { - pub type Opaque = impl Sized; +pub type Opaque = impl Sized; - pub fn get_rpit() -> impl Clone {} +pub fn get_rpit() -> impl Clone {} - fn test() -> Opaque { - super::query(get_rpit); - get_rpit() - } +#[define_opaque(Opaque)] +fn test() -> Opaque { + query(get_rpit); + get_rpit() } -use helper::*; - fn query(_: impl FnOnce() -> Opaque) {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs index 80f1b1502d3b..dc489c0d6fb3 100644 --- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs @@ -5,16 +5,14 @@ #![feature(type_alias_impl_trait)] -mod helper { - pub type Opaque = impl Sized; +pub type Opaque = impl Sized; - pub fn get_rpit() -> impl Sized {} +pub fn get_rpit() -> impl Sized {} - fn test(_: Opaque) { - super::query(get_rpit); - } +#[define_opaque(Opaque)] +fn test() { + query(get_rpit); } -use helper::*; fn query(_: impl FnOnce() -> Opaque) {} diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr index e4399f2d8f4d..dca3ae05bb0e 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `i32` with `Foo` - --> $DIR/self-referential-2.rs:10:13 + --> $DIR/self-referential-2.rs:11:13 | LL | fn bar() -> Bar { | ^^^ no implementation for `i32 == Foo` diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs index f96364ccfcdd..d3effe817b84 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-2.rs @@ -7,6 +7,7 @@ type Foo = impl std::fmt::Debug; type Bar = impl PartialEq; +#[define_opaque(Bar)] fn bar() -> Bar { 42_i32 //[current]~^ ERROR can't compare `i32` with `Foo` } diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs index 18f09b548675..b55625328935 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs @@ -2,6 +2,7 @@ type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; +#[define_opaque(Bar)] fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { //~^ ERROR can't compare `&i32` with `Bar<'a, 'b>` i diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index 15ebcdafca6f..d0b1d46c29e0 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `&i32` with `Bar<'a, 'b>` - --> $DIR/self-referential-3.rs:5:31 + --> $DIR/self-referential-3.rs:6:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>` diff --git a/tests/ui/type-alias-impl-trait/self-referential-4.rs b/tests/ui/type-alias-impl-trait/self-referential-4.rs index 36742c8ad57f..36df087dfcb6 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-4.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-4.rs @@ -2,18 +2,21 @@ type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; +#[define_opaque(Bar)] fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { i //~^ ERROR can't compare `&i32` with `Bar<'b, 'static>` } type Foo<'a, 'b> = impl PartialEq> + std::fmt::Debug; +#[define_opaque(Foo)] fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { i //~^ ERROR can't compare `&i32` with `Foo<'static, 'b>` } type Moo<'a, 'b> = impl PartialEq> + std::fmt::Debug; +#[define_opaque(Moo)] fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { i //~^ ERROR can't compare `&i32` with `Moo<'static, 'a>` } diff --git a/tests/ui/type-alias-impl-trait/self-referential-4.stderr b/tests/ui/type-alias-impl-trait/self-referential-4.stderr index 98c762e3d382..92534981eb94 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-4.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-4.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `&i32` with `Bar<'b, 'static>` - --> $DIR/self-referential-4.rs:5:31 + --> $DIR/self-referential-4.rs:6:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'static>` @@ -10,7 +10,7 @@ LL | i = help: the trait `PartialEq` is implemented for `i32` error[E0277]: can't compare `&i32` with `Foo<'static, 'b>` - --> $DIR/self-referential-4.rs:11:31 + --> $DIR/self-referential-4.rs:13:31 | LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Foo<'static, 'b>` @@ -21,7 +21,7 @@ LL | i = help: the trait `PartialEq` is implemented for `i32` error[E0277]: can't compare `&i32` with `Moo<'static, 'a>` - --> $DIR/self-referential-4.rs:17:31 + --> $DIR/self-referential-4.rs:20:31 | LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Moo<'static, 'a>` diff --git a/tests/ui/type-alias-impl-trait/self-referential.rs b/tests/ui/type-alias-impl-trait/self-referential.rs index b899b12cc4a1..a1d3b275b19e 100644 --- a/tests/ui/type-alias-impl-trait/self-referential.rs +++ b/tests/ui/type-alias-impl-trait/self-referential.rs @@ -2,6 +2,7 @@ type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; +#[define_opaque(Bar)] fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { //~^ ERROR can't compare `&i32` with `Bar<'b, 'a>` i @@ -9,6 +10,7 @@ fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { type Foo<'a, 'b> = (i32, impl PartialEq> + std::fmt::Debug); +#[define_opaque(Foo)] fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { //~^ ERROR can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)` (42, i) @@ -16,6 +18,7 @@ fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { type Moo<'a, 'b> = (i32, impl PartialEq> + std::fmt::Debug); +#[define_opaque(Moo)] fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { //~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)` (42, i) diff --git a/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr index 57d67f693761..4bcf659e8e61 100644 --- a/tests/ui/type-alias-impl-trait/self-referential.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `&i32` with `Bar<'b, 'a>` - --> $DIR/self-referential.rs:5:31 + --> $DIR/self-referential.rs:6:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'a>` @@ -11,7 +11,7 @@ LL | i = help: the trait `PartialEq` is implemented for `i32` error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)` - --> $DIR/self-referential.rs:12:31 + --> $DIR/self-referential.rs:14:31 | LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)` @@ -23,7 +23,7 @@ LL | (42, i) = help: the trait `PartialEq` is implemented for `i32` error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)` - --> $DIR/self-referential.rs:19:31 + --> $DIR/self-referential.rs:22:31 | LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)` diff --git a/tests/ui/type-alias-impl-trait/self_implication.rs b/tests/ui/type-alias-impl-trait/self_implication.rs index 56464af96ed8..d7f701595714 100644 --- a/tests/ui/type-alias-impl-trait/self_implication.rs +++ b/tests/ui/type-alias-impl-trait/self_implication.rs @@ -20,11 +20,10 @@ struct Foo<'a> { x: &'a mut u8, } // desugared -mod foo { - pub type FooX = impl Sized; - impl<'a> super::Foo<'a> { - pub fn foo(&self) -> FooX {} - } +pub type FooX = impl Sized; +impl<'a> Foo<'a> { + #[define_opaque(FooX)] + pub fn foo(&self) -> FooX {} } fn bar() { diff --git a/tests/ui/type-alias-impl-trait/static-const-types.rs b/tests/ui/type-alias-impl-trait/static-const-types.rs deleted file mode 100644 index dad515aaa7bd..000000000000 --- a/tests/ui/type-alias-impl-trait/static-const-types.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![feature(type_alias_impl_trait)] -#![allow(dead_code)] - -//@ check-pass - -use std::fmt::Debug; - -type Foo = impl Debug; - -static FOO1: Foo = 22_u32; -const FOO2: Foo = 22_u32; - -fn main() {} diff --git a/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs b/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs index 27f5799c3804..a20ae814908b 100644 --- a/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs +++ b/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs @@ -1,15 +1,15 @@ #![feature(type_alias_impl_trait)] -mod bar { - pub type Bar = impl Send; +pub type Bar = impl Send; - // While i32 is structural-match, we do not want to leak this information. - // (See https://github.com/rust-lang/rust/issues/72156) - pub const fn leak_free() -> Bar { - 7i32 - } +// While i32 is structural-match, we do not want to leak this information. +// (See https://github.com/rust-lang/rust/issues/72156) +#[define_opaque(Bar)] +pub const fn leak_free() -> Bar { + 7i32 } -const LEAK_FREE: bar::Bar = bar::leak_free(); + +const LEAK_FREE: Bar = leak_free(); fn leak_free_test() { match LEAK_FREE { diff --git a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr index 28f5d6728a9d..5067d78d1697 100644 --- a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr +++ b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr @@ -1,8 +1,8 @@ error: opaque type `Bar` cannot be used in patterns --> $DIR/structural-match-no-leak.rs:16:9 | -LL | const LEAK_FREE: bar::Bar = bar::leak_free(); - | ------------------------- constant defined here +LL | const LEAK_FREE: Bar = leak_free(); + | -------------------- constant defined here ... LL | LEAK_FREE => (), | ^^^^^^^^^ opaque type can't be used in patterns diff --git a/tests/ui/type-alias-impl-trait/structural-match.rs b/tests/ui/type-alias-impl-trait/structural-match.rs index 502595915397..68a95560a465 100644 --- a/tests/ui/type-alias-impl-trait/structural-match.rs +++ b/tests/ui/type-alias-impl-trait/structural-match.rs @@ -1,22 +1,21 @@ #![feature(type_alias_impl_trait)] -mod foo { - pub type Foo = impl Send; +pub type Foo = impl Send; - // This is not structural-match - struct A; +// This is not structural-match +struct A; - pub const fn value() -> Foo { - A - } +#[define_opaque(Foo)] +pub const fn value() -> Foo { + A } -use foo::*; + const VALUE: Foo = value(); fn test() { match VALUE { VALUE => (), - //~^ `foo::Foo` cannot be used in patterns + //~^ `Foo` cannot be used in patterns _ => (), } } diff --git a/tests/ui/type-alias-impl-trait/structural-match.stderr b/tests/ui/type-alias-impl-trait/structural-match.stderr index b06b31a060fb..a86b7f42ead6 100644 --- a/tests/ui/type-alias-impl-trait/structural-match.stderr +++ b/tests/ui/type-alias-impl-trait/structural-match.stderr @@ -1,5 +1,5 @@ -error: opaque type `foo::Foo` cannot be used in patterns - --> $DIR/structural-match.rs:18:9 +error: opaque type `Foo` cannot be used in patterns + --> $DIR/structural-match.rs:17:9 | LL | const VALUE: Foo = value(); | ---------------- constant defined here diff --git a/tests/ui/type-alias-impl-trait/taint.rs b/tests/ui/type-alias-impl-trait/taint.rs index dfb947637c04..3d67c9bca416 100644 --- a/tests/ui/type-alias-impl-trait/taint.rs +++ b/tests/ui/type-alias-impl-trait/taint.rs @@ -9,6 +9,7 @@ fn set(x: &mut isize) -> isize { *x } +#[define_opaque(Two)] fn d(x: Two) { let c1 = || set(x); //~ ERROR: expected generic lifetime parameter, found `'_` c1; diff --git a/tests/ui/type-alias-impl-trait/taint.stderr b/tests/ui/type-alias-impl-trait/taint.stderr index 17fcd4b7e932..e2e34a5d1ba4 100644 --- a/tests/ui/type-alias-impl-trait/taint.stderr +++ b/tests/ui/type-alias-impl-trait/taint.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/taint.rs:13:17 + --> $DIR/taint.rs:14:17 | LL | type Two<'a, 'b> = impl std::fmt::Debug; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs index 109a70c766d4..ab33e9e794ed 100644 --- a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs +++ b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs @@ -19,6 +19,7 @@ type Sendable = impl Send + Duh; type Foo = impl Trait; +#[define_opaque(Foo)] fn foo() -> Foo { || 42 } diff --git a/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs b/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs index be743e8e2700..488c581247dc 100644 --- a/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs +++ b/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs @@ -10,9 +10,11 @@ impl Trait for (A, B, u8) where A: Deref, B: Deref, {} impl Trait for (A, B, i8) {} type TaitSized = impl Sized; +#[define_opaque(TaitSized)] fn def_tait1() -> TaitSized {} type TaitCopy = impl Copy; +#[define_opaque(TaitCopy)] fn def_tait2() -> TaitCopy {} fn impl_trait () {} diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs index 66a6c0a35b50..af787d66cc10 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs @@ -5,6 +5,7 @@ type Foo = Box>; +#[define_opaque(Foo)] fn make_foo() -> Foo { Box::new(vec![1, 2, 3].into_iter()) } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs index e46d2bd559cf..921dc17593d3 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs @@ -5,6 +5,7 @@ type Foo = impl Iterator; +#[define_opaque(Foo)] fn make_foo() -> Foo { vec![1, 2].into_iter() } @@ -12,6 +13,7 @@ fn make_foo() -> Foo { type Bar = impl Send; type Baz = impl Iterator; +#[define_opaque(Baz)] fn make_baz() -> Baz { vec!["1", "2"].into_iter() } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs index 6b37552fed14..b5533eeecba5 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs @@ -1,11 +1,19 @@ #![feature(type_alias_impl_trait)] -//@ check-pass -// Ensures that `const` items can constrain an opaque `impl Trait`. +// Ensures that `const` items can not constrain an opaque `impl Trait`. use std::fmt::Debug; pub type Foo = impl Debug; +//~^ ERROR unconstrained opaque type +#[define_opaque(Foo)] +//~^ ERROR only functions and methods can define opaque types const _FOO: Foo = 5; +//~^ ERROR mismatched types + +#[define_opaque(Foo)] +//~^ ERROR only functions and methods can define opaque types +static _BAR: Foo = 22_u32; +//~^ ERROR mismatched types fn main() {} diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr new file mode 100644 index 000000000000..dc15da665f32 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr @@ -0,0 +1,57 @@ +error: only functions and methods can define opaque types + --> $DIR/type-alias-impl-trait-const.rs:9:1 + | +LL | #[define_opaque(Foo)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: only functions and methods can define opaque types + --> $DIR/type-alias-impl-trait-const.rs:14:1 + | +LL | #[define_opaque(Foo)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: unconstrained opaque type + --> $DIR/type-alias-impl-trait-const.rs:6:16 + | +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same crate + +error[E0308]: mismatched types + --> $DIR/type-alias-impl-trait-const.rs:11:19 + | +LL | pub type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | const _FOO: Foo = 5; + | ^ expected opaque type, found integer + | + = note: expected opaque type `Foo` + found type `{integer}` +note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types + --> $DIR/type-alias-impl-trait-const.rs:11:7 + | +LL | const _FOO: Foo = 5; + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/type-alias-impl-trait-const.rs:16:20 + | +LL | pub type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | static _BAR: Foo = 22_u32; + | ^^^^^^ expected opaque type, found `u32` + | + = note: expected opaque type `Foo` + found type `u32` +note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types + --> $DIR/type-alias-impl-trait-const.rs:16:8 + | +LL | static _BAR: Foo = 22_u32; + | ^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs index cbd91066c49d..95d52e1ff96e 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs @@ -11,12 +11,14 @@ struct MyStruct { impl MyTrait for MyStruct {} +#[define_opaque(TE)] fn bla() -> TE { return MyStruct { v: 1 }; } +#[define_opaque(TE)] fn bla2() -> TE { - //~^ ERROR: item does not constrain `TE::{opaque#0}`, but has it in its signature + //~^ ERROR: item does not constrain `TE::{opaque#0}` bla() } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr index 819bde021836..12aa94386dcb 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr @@ -1,12 +1,12 @@ -error: item does not constrain `TE::{opaque#0}`, but has it in its signature - --> $DIR/type-alias-impl-trait-fns.rs:18:4 +error: item does not constrain `TE::{opaque#0}` + --> $DIR/type-alias-impl-trait-fns.rs:20:4 | LL | fn bla2() -> TE { | ^^^^ | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/type-alias-impl-trait-fns.rs:23:11 + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/type-alias-impl-trait-fns.rs:25:11 | LL | type TE = impl MyTrait; | ^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs index 188b23732f91..929dec39b2f5 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs @@ -3,21 +3,25 @@ #![feature(type_alias_impl_trait)] type A = impl Sized; +#[define_opaque(A)] fn f1() -> A { 0 } type B = impl ?Sized; +#[define_opaque(B)] fn f2() -> &'static B { &[0] } type C = impl ?Sized + 'static; +#[define_opaque(C)] fn f3() -> &'static C { &[0] } type D = impl ?Sized; +#[define_opaque(D)] fn f4() -> &'static D { &1 } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs index 1340a4214ee5..3fcb40df8324 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs @@ -5,6 +5,7 @@ type Foo = Vec; +#[define_opaque(Foo)] fn make_foo() -> Foo { vec![true, false] } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs index 8e90f9699532..32b39c8823d5 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs @@ -6,20 +6,17 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -mod foo { - pub trait MyTrait {} +pub trait MyTrait {} - impl MyTrait for bool {} +impl MyTrait for bool {} - pub type Foo = impl MyTrait; +pub type Foo = impl MyTrait; - pub fn make_foo() -> Foo { - true - } +#[define_opaque(Foo)] +pub fn make_foo() -> Foo { + true } -use foo::*; - struct Blah { my_foo: Foo, my_u8: u8, diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr index ee8922b673e2..ad96a0eeb87d 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr @@ -1,9 +1,10 @@ -error[E0275]: overflow evaluating the requirement `>::Output == Foo` - --> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:6:21 +error: unconstrained opaque type + --> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:4:12 | -LL | fn crash(x: Foo) -> Foo { - | ^^^ +LL | type Foo = impl Fn() -> Foo; + | ^^^^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same crate error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr index 3d0f1d30ca2b..e5bb8163a811 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr @@ -1,9 +1,10 @@ -error[E0275]: overflow evaluating the requirement `>::Item == Foo` - --> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:10:21 +error: unconstrained opaque type + --> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:8:12 | -LL | fn crash(x: Foo) -> Foo { - | ^^^ +LL | type Foo = impl Bar; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same crate error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr index 675689bac429..157310bf6236 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr @@ -1,9 +1,10 @@ -error[E0275]: overflow evaluating the requirement ` as FnOnce<()>>::Output == Foo<'a>` - --> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:6:40 +error: unconstrained opaque type + --> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:4:16 | -LL | fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> { - | ^^^^^^^ +LL | type Foo<'a> = impl Fn() -> Foo<'a>; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same crate error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs index 8ca279eec921..115df16bd3ea 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs @@ -3,6 +3,7 @@ type Foo = impl 'static; //~^ ERROR: at least one trait must be specified +#[define_opaque(Foo)] fn foo() -> Foo { "foo" } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr index 3f7acd338301..da8fc595f6a6 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr @@ -5,7 +5,7 @@ LL | type Foo = impl 'static; | ^^^^^^^^^^^^ error: at least one trait must be specified - --> $DIR/type-alias-impl-trait-with-no-traits.rs:10:13 + --> $DIR/type-alias-impl-trait-with-no-traits.rs:11:13 | LL | fn bar() -> impl 'static { | ^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs index 0fe653ac471a..ff11fb4fcaf0 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs @@ -17,6 +17,7 @@ fn main() { // single definition type Foo = impl std::fmt::Display; +#[define_opaque(Foo)] fn foo() -> Foo { "foo" } @@ -24,30 +25,36 @@ fn foo() -> Foo { // two definitions type Bar = impl std::fmt::Display; +#[define_opaque(Bar)] fn bar1() -> Bar { "bar1" } +#[define_opaque(Bar)] fn bar2() -> Bar { "bar2" } type MyIter = impl Iterator; +#[define_opaque(MyIter)] fn my_iter(t: T) -> MyIter { std::iter::once(t) } +#[define_opaque(MyIter)] fn my_iter2(t: T) -> MyIter { std::iter::once(t) } // param names should not have an effect! +#[define_opaque(MyIter)] fn my_iter3(u: U) -> MyIter { std::iter::once(u) } // param position should not have an effect! +#[define_opaque(MyIter)] fn my_iter4(_: U, v: V) -> MyIter { std::iter::once(v) } @@ -55,6 +62,7 @@ fn my_iter4(_: U, v: V) -> MyIter { // param names should not have an effect! type MyOtherIter = impl Iterator; +#[define_opaque(MyOtherIter)] fn my_other_iter(u: U) -> MyOtherIter { std::iter::once(u) } @@ -62,18 +70,18 @@ fn my_other_iter(u: U) -> MyOtherIter { trait Trait {} type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a; +#[define_opaque(GenericBound)] fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { t } -mod pass_through { - pub type Passthrough = impl Sized + 'static; +pub type Passthrough = impl Sized + 'static; - fn define_passthrough(t: T) -> Passthrough { - t - } +#[define_opaque(Passthrough)] +fn define_passthrough(t: T) -> Passthrough { + t } -fn use_passthrough(x: pass_through::Passthrough) -> pass_through::Passthrough { +fn use_passthrough(x: Passthrough) -> Passthrough { x } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs index 65e2feaf7954..e87fda8159bf 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs @@ -14,71 +14,74 @@ fn main() { assert_eq!(my_iter(42u8).collect::>(), vec![42u8]); } -use defining_use_scope::*; - -mod defining_use_scope { - // single definition - pub type Foo = impl std::fmt::Display; - - pub fn foo() -> Foo { - "foo" - } - - // two definitions - pub type Bar = impl std::fmt::Display; - - pub fn bar1() -> Bar { - "bar1" - } - - pub fn bar2() -> Bar { - "bar2" - } - - pub type MyIter = impl Iterator; - - pub fn my_iter(t: T) -> MyIter { - std::iter::once(t) - } - - fn my_iter2(t: T) -> MyIter { - std::iter::once(t) - } - - // param names should not have an effect! - fn my_iter3(u: U) -> MyIter { - std::iter::once(u) - } - - // param position should not have an effect! - fn my_iter4(_: U, v: V) -> MyIter { - std::iter::once(v) - } - - // param names should not have an effect! - type MyOtherIter = impl Iterator; - - fn my_other_iter(u: U) -> MyOtherIter { - std::iter::once(u) - } - - trait Trait {} - type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a; - - fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { - t - } - - mod pass_through { - pub type Passthrough = impl Sized + 'static; - - fn define_passthrough(t: T) -> Passthrough { - t - } - } - - fn use_passthrough(x: pass_through::Passthrough) -> pass_through::Passthrough { - x - } +// single definition +pub type Foo = impl std::fmt::Display; +#[define_opaque(Foo)] +pub fn foo() -> Foo { + "foo" +} + +// two definitions +pub type Bar = impl std::fmt::Display; + +#[define_opaque(Bar)] +pub fn bar1() -> Bar { + "bar1" +} + +#[define_opaque(Bar)] +pub fn bar2() -> Bar { + "bar2" +} + +pub type MyIter = impl Iterator; + +#[define_opaque(MyIter)] +pub fn my_iter(t: T) -> MyIter { + std::iter::once(t) +} + +#[define_opaque(MyIter)] +fn my_iter2(t: T) -> MyIter { + std::iter::once(t) +} + +// param names should not have an effect! +#[define_opaque(MyIter)] +fn my_iter3(u: U) -> MyIter { + std::iter::once(u) +} + +// param position should not have an effect! +#[define_opaque(MyIter)] +fn my_iter4(_: U, v: V) -> MyIter { + std::iter::once(v) +} + +// param names should not have an effect! +type MyOtherIter = impl Iterator; + +#[define_opaque(MyOtherIter)] +fn my_other_iter(u: U) -> MyOtherIter { + std::iter::once(u) +} + +trait Trait {} +type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a; + +#[define_opaque(GenericBound)] +fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { + t +} + +pub type Passthrough = impl Sized + 'static; + +#[define_opaque(Passthrough)] +fn define_passthrough(t: T) -> Passthrough { + t +} + +fn use_passthrough(x: Passthrough) -> Passthrough { + x } diff --git a/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs b/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs index af575a4ff36b..20209c7b28c6 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs @@ -2,9 +2,10 @@ #![feature(type_alias_impl_trait)] -use std::iter::{once, Chain}; +use std::iter::{Chain, once}; type I = Chain>; +#[define_opaque(I)] fn test2>(x: A) -> I { x.chain(once("5")) } diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr b/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr index 7cf2fe42da8b..d4a2c23f7a77 100644 --- a/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr +++ b/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/type_of_a_let.rs:21:16 + --> $DIR/type_of_a_let.rs:23:16 | LL | let x: Foo = 22_u32; | - move occurs because `x` has type `Foo`, which does not implement the `Copy` trait @@ -9,7 +9,7 @@ LL | same_type((x, y)); | ^ value used here after move error[E0382]: use of moved value: `y` - --> $DIR/type_of_a_let.rs:22:6 + --> $DIR/type_of_a_let.rs:24:6 | LL | let y: Foo = x; | - move occurs because `y` has type `Foo`, which does not implement the `Copy` trait diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.rs b/tests/ui/type-alias-impl-trait/type_of_a_let.rs index cc8caf886cfc..9479b1084df1 100644 --- a/tests/ui/type-alias-impl-trait/type_of_a_let.rs +++ b/tests/ui/type-alias-impl-trait/type_of_a_let.rs @@ -10,11 +10,13 @@ use std::fmt::Debug; type Foo = impl Debug; +#[define_opaque(Foo)] fn foo1() -> (u32, Foo) { let x: Foo = 22_u32; (x, todo!()) } +#[define_opaque(Foo)] fn foo2() -> (u32, Foo) { let x: Foo = 22_u32; let y: Foo = x; diff --git a/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs b/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs index 09ff006acbdd..063c4deaf06e 100644 --- a/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs +++ b/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs @@ -2,12 +2,9 @@ #![feature(type_alias_impl_trait)] -mod opaque { - pub type Opaque = impl Sized; - fn defining() -> Opaque {} -} - -use opaque::Opaque; +pub type Opaque = impl Sized; +#[define_opaque(Opaque)] +fn defining() -> Opaque {} struct Ss<'a, T>(&'a Opaque); diff --git a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs index ae3d317ab464..3f4d9d244ec3 100644 --- a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs +++ b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs @@ -3,6 +3,7 @@ type Tait = impl Copy; // Make sure that this TAIT isn't considered unconstrained... +#[define_opaque(Tait)] fn empty_opaque() -> Tait { if false { match empty_opaque() {} diff --git a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr index 5c9a4688105f..549e3bc8dc14 100644 --- a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr +++ b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `Tait` is non-empty - --> $DIR/unconstrained-due-to-bad-pattern.rs:8:15 + --> $DIR/unconstrained-due-to-bad-pattern.rs:9:15 | LL | match empty_opaque() {} | ^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs index b3510067047b..415021a1808c 100644 --- a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs +++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs @@ -3,6 +3,7 @@ use std::fmt::Display; type Opaque = impl Sized + 'static; +#[define_opaque(Opaque)] fn define() -> Opaque {} trait Trait { diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr index 6206f169c5b9..7a86685787ce 100644 --- a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr +++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr @@ -1,5 +1,5 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-impl-param.rs:11:6 + --> $DIR/unconstrained-impl-param.rs:12:6 | LL | impl<'a> Trait for Opaque<&'a str> { | ^^ unconstrained lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/under-binder.rs b/tests/ui/type-alias-impl-trait/under-binder.rs index caf21d64027d..bf8635b7d81f 100644 --- a/tests/ui/type-alias-impl-trait/under-binder.rs +++ b/tests/ui/type-alias-impl-trait/under-binder.rs @@ -2,6 +2,7 @@ type Opaque<'a> = impl Sized + 'a; +#[define_opaque(Opaque)] fn test(f: fn(u8)) -> fn(Opaque<'_>) { f //~ ERROR E0792 } diff --git a/tests/ui/type-alias-impl-trait/under-binder.stderr b/tests/ui/type-alias-impl-trait/under-binder.stderr index f4a121ce440d..0589f9ae11cd 100644 --- a/tests/ui/type-alias-impl-trait/under-binder.stderr +++ b/tests/ui/type-alias-impl-trait/under-binder.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/under-binder.rs:6:5 + --> $DIR/under-binder.rs:7:5 | LL | type Opaque<'a> = impl Sized + 'a; | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/type-alias-impl-trait/underconstrained_generic.rs b/tests/ui/type-alias-impl-trait/underconstrained_generic.rs index aa537dfc9176..dc2d37b9d053 100644 --- a/tests/ui/type-alias-impl-trait/underconstrained_generic.rs +++ b/tests/ui/type-alias-impl-trait/underconstrained_generic.rs @@ -18,11 +18,10 @@ impl ProofForConversion for () { type Converter = impl ProofForConversion; +#[define_opaque(Converter)] fn _defining_use() -> Converter { () //~^ ERROR the trait bound `T: Trait` is not satisfied } - -fn main() { -} +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr b/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr index e50949ed8f36..e05c3094d53a 100644 --- a/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr +++ b/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/underconstrained_generic.rs:22:5 + --> $DIR/underconstrained_generic.rs:23:5 | LL | () | ^^ the trait `Trait` is not implemented for `T` @@ -17,7 +17,7 @@ note: required by a bound in an opaque type LL | type Converter = impl ProofForConversion; | ^^^^^^^^^^^^^^^^^^^^^ note: this definition site has more where clauses than the opaque type - --> $DIR/underconstrained_generic.rs:21:1 + --> $DIR/underconstrained_generic.rs:22:1 | LL | fn _defining_use() -> Converter { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs index e8e7dd0ea082..f4611f33d23b 100644 --- a/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs +++ b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs @@ -15,6 +15,7 @@ impl<'a, 'b> ProofForConversion<'a, 'b> for &'b &'a () { type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>; // Even _defining_use with an explicit `'a: 'b` compiles fine, too. +#[define_opaque(Converter)] fn _defining_use<'a, 'b>(x: &'b &'a ()) -> Converter<'a, 'b> { x //~^ ERROR reference has a longer lifetime than the data it references diff --git a/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr index 7c07578d887e..6a1f2b49397a 100644 --- a/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr +++ b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr @@ -1,5 +1,5 @@ error[E0491]: in type `&'b &'a ()`, reference has a longer lifetime than the data it references - --> $DIR/underconstrained_lifetime.rs:19:5 + --> $DIR/underconstrained_lifetime.rs:20:5 | LL | x | ^ diff --git a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs index 56d975355c3e..2dab81cba6f6 100644 --- a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs +++ b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs @@ -5,6 +5,7 @@ mod foo { pub trait T {} pub type Alias<'a> = impl T; + //~^ ERROR: unconstrained opaque type fn bar() { super::with_positive(|&n| ()); //~^ ERROR mismatched types diff --git a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr index 279bd3bca5ab..b58eae671209 100644 --- a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr +++ b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr @@ -1,9 +1,17 @@ +error: unconstrained opaque type + --> $DIR/underef-index-out-of-bounds-121472.rs:7:26 + | +LL | pub type Alias<'a> = impl T; + | ^^^^^^ + | + = note: `Alias` must be used in combination with a concrete type within the same crate + error[E0308]: mismatched types - --> $DIR/underef-index-out-of-bounds-121472.rs:9:31 + --> $DIR/underef-index-out-of-bounds-121472.rs:10:31 | LL | pub type Alias<'a> = impl T; | ------ the expected opaque type -LL | fn bar() { +... LL | super::with_positive(|&n| ()); | ^^ | | @@ -18,6 +26,6 @@ LL - super::with_positive(|&n| ()); LL + super::with_positive(|n| ()); | -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.rs b/tests/ui/type-alias-impl-trait/unnameable_type.rs index 5813f529dea1..0b97cc2941f6 100644 --- a/tests/ui/type-alias-impl-trait/unnameable_type.rs +++ b/tests/ui/type-alias-impl-trait/unnameable_type.rs @@ -16,6 +16,7 @@ use private::Trait; // downstream type MyPrivate = impl Sized; impl Trait for u32 { + #[define_opaque(MyPrivate)] fn dont_define_this(private: MyPrivate) { //~^ ERROR: incompatible type for trait let _: () = private; diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr index 25dc41df4193..6e4e024ce691 100644 --- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr +++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr @@ -1,9 +1,9 @@ error[E0053]: method `dont_define_this` has an incompatible type for trait - --> $DIR/unnameable_type.rs:19:34 + --> $DIR/unnameable_type.rs:20:34 | LL | type MyPrivate = impl Sized; | ---------- the found opaque type -LL | impl Trait for u32 { +... LL | fn dont_define_this(private: MyPrivate) { | ^^^^^^^^^ expected `Private`, found opaque type | diff --git a/tests/ui/type-alias-impl-trait/unused_generic_param.rs b/tests/ui/type-alias-impl-trait/unused_generic_param.rs index b675bc2e6225..556e70d1c962 100644 --- a/tests/ui/type-alias-impl-trait/unused_generic_param.rs +++ b/tests/ui/type-alias-impl-trait/unused_generic_param.rs @@ -7,16 +7,19 @@ fn main() {} type PartiallyDefined = impl Sized; +#[define_opaque(PartiallyDefined)] fn partially_defined(_: T) -> PartiallyDefined { 4u32 } type PartiallyDefined2 = impl Sized; +#[define_opaque(PartiallyDefined2)] fn partially_defined2(_: T) -> PartiallyDefined2 { 4u32 } +#[define_opaque(PartiallyDefined2)] fn partially_defined22(_: T) -> PartiallyDefined2 { 4u32 } diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs index 40e8ec0129a3..ecd7158223c8 100644 --- a/tests/ui/type-alias-impl-trait/variance.rs +++ b/tests/ui/type-alias-impl-trait/variance.rs @@ -72,6 +72,7 @@ type NestedDeeply<'a> = >, >, >; +#[define_opaque(NestedDeeply)] fn test<'a>() -> NestedDeeply<'a> { &() } diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr index 79ce8148f19a..138e4080c29d 100644 --- a/tests/ui/type-alias-impl-trait/variance.stderr +++ b/tests/ui/type-alias-impl-trait/variance.stderr @@ -28,7 +28,7 @@ error: unconstrained opaque type LL | type NotCapturedEarly<'a> = impl Sized; | ^^^^^^^^^^ | - = note: `NotCapturedEarly` must be used in combination with a concrete type within the same module + = note: `NotCapturedEarly` must be used in combination with a concrete type within the same crate error: unconstrained opaque type --> $DIR/variance.rs:11:26 @@ -36,7 +36,7 @@ error: unconstrained opaque type LL | type CapturedEarly<'a> = impl Sized + Captures<'a>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `CapturedEarly` must be used in combination with a concrete type within the same module + = note: `CapturedEarly` must be used in combination with a concrete type within the same crate error: unconstrained opaque type --> $DIR/variance.rs:14:56 @@ -44,7 +44,7 @@ error: unconstrained opaque type LL | type NotCapturedLate<'a> = dyn for<'b> Iterator; | ^^^^^^^^^^ | - = note: `NotCapturedLate` must be used in combination with a concrete type within the same module + = note: `NotCapturedLate` must be used in combination with a concrete type within the same crate error: unconstrained opaque type --> $DIR/variance.rs:18:49 @@ -52,7 +52,7 @@ error: unconstrained opaque type LL | type Captured<'a> = dyn for<'b> Iterator>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `Captured` must be used in combination with a concrete type within the same module + = note: `Captured` must be used in combination with a concrete type within the same crate error: unconstrained opaque type --> $DIR/variance.rs:22:27 @@ -60,7 +60,7 @@ error: unconstrained opaque type LL | type Bar<'a, 'b: 'b, T> = impl Sized; | ^^^^^^^^^^ | - = note: `Bar` must be used in combination with a concrete type within the same module + = note: `Bar` must be used in combination with a concrete type within the same crate error: unconstrained opaque type --> $DIR/variance.rs:34:32 diff --git a/tests/ui/type-alias-impl-trait/weird-return-types.rs b/tests/ui/type-alias-impl-trait/weird-return-types.rs index 29d4faa7ba90..05668c836f9e 100644 --- a/tests/ui/type-alias-impl-trait/weird-return-types.rs +++ b/tests/ui/type-alias-impl-trait/weird-return-types.rs @@ -4,11 +4,12 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -use std::future::Future; use std::fmt::Debug; +use std::future::Future; type Foo = impl Debug; +#[define_opaque(Foo)] fn f() -> impl Future { async move { 22_u32 } } diff --git a/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs b/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs index 19dd4c179367..fd5edcc89eec 100644 --- a/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs +++ b/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs @@ -14,6 +14,7 @@ struct Static(T); type OpaqueRet<'a> = impl Sized + 'a; +#[define_opaque(OpaqueRet)] fn test_return<'a>(msg: Static<&'static u8>) -> OpaqueRet<'a> { msg } @@ -23,9 +24,9 @@ fn test_rpit<'a>(msg: Static<&'static u8>) -> impl Sized + 'a { } type OpaqueAssign<'a> = impl Sized + 'a; -fn test_assign<'a>(msg: Static<&'static u8>) -> Option> { +#[define_opaque(OpaqueAssign)] +fn test_assign<'a>(msg: Static<&'static u8>) { let _: OpaqueAssign<'a> = msg; - None } // `OpaqueRef<'a, T> = Ref<'a, T>`, vs @@ -33,6 +34,7 @@ fn test_assign<'a>(msg: Static<&'static u8>) -> Option> { trait RefAt<'a>: 'a {} struct Ref<'a, T: RefAt<'a>>(&'a T); type OpaqueRef<'a, T: RefAt<'static>> = impl Sized + 'a; +#[define_opaque(OpaqueRef)] fn test_trait<'a, T: RefAt<'static>>(msg: Ref<'static, T>) -> OpaqueRef<'a, T> { msg } diff --git a/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs b/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs index 449e9fbd0d84..6de2c0ccc37c 100644 --- a/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs +++ b/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs @@ -6,8 +6,11 @@ trait Bar { type FooFn = impl FnOnce(B); +#[define_opaque(FooFn)] fn foo() -> FooFn { - fn mop(bar: B) { bar.bar() } + fn mop(bar: B) { + bar.bar() + } mop // NOTE: no function pointer, but function zst item //~^ ERROR the trait bound `B: Bar` is not satisfied } diff --git a/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr b/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr index 9046a8a76b82..b52ed3f43f48 100644 --- a/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr +++ b/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `B: Bar` is not satisfied - --> $DIR/wf-check-fn-def.rs:11:5 + --> $DIR/wf-check-fn-def.rs:14:5 | LL | mop // NOTE: no function pointer, but function zst item | ^^^ the trait `Bar` is not implemented for `B` | note: required by a bound in `mop` - --> $DIR/wf-check-fn-def.rs:10:15 + --> $DIR/wf-check-fn-def.rs:11:15 | -LL | fn mop(bar: B) { bar.bar() } +LL | fn mop(bar: B) { | ^^^ required by this bound in `mop` help: consider restricting type parameter `B` with trait `Bar` | diff --git a/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs b/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs index 1484d9fd0734..fd9ed5337565 100644 --- a/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs +++ b/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs @@ -8,8 +8,11 @@ trait Bar { type FooFn = impl FnOnce(B); +#[define_opaque(FooFn)] fn foo() -> FooFn { - fn mop(bar: B) { bar.bar() } + fn mop(bar: B) { + bar.bar() + } mop as fn(B) // function pointers don't have any obligations on them, // thus the above compiles. It's obviously unsound to just diff --git a/tests/ui/type-alias-impl-trait/wf-nested.rs b/tests/ui/type-alias-impl-trait/wf-nested.rs index 56c524c6db06..074ea8703a40 100644 --- a/tests/ui/type-alias-impl-trait/wf-nested.rs +++ b/tests/ui/type-alias-impl-trait/wf-nested.rs @@ -19,7 +19,6 @@ impl Trait<&'static T> for () { type Out = IsStatic; } - // We could theoretically allow this (and previously did), as even // though the nested opaque is not well-formed, it can only be // used by normalizing the projection @@ -27,6 +26,7 @@ impl Trait<&'static T> for () { // Assuming that we check that this projection is well-formed, the wf // of the nested opaque is implied. type OuterOpaque1 = impl Trait<&'static T, Out = impl Sized>; +#[define_opaque(OuterOpaque1)] fn define() -> OuterOpaque1 {} //~^ ERROR `T` may not live long enough @@ -38,6 +38,7 @@ fn define_rpit() -> impl Trait<&'static T, Out = impl Sized> {} // soundness. type InnerOpaque = impl Sized; type OuterOpaque2 = impl Trait<&'static T, Out = InnerOpaque>; +#[define_opaque(OuterOpaque2)] fn define_nested_rpit() -> OuterOpaque2 {} //~^ ERROR the parameter type `T` may not live long enough diff --git a/tests/ui/type-alias-impl-trait/wf-nested.stderr b/tests/ui/type-alias-impl-trait/wf-nested.stderr index 6d50e11c5da8..d7ac5146c1e7 100644 --- a/tests/ui/type-alias-impl-trait/wf-nested.stderr +++ b/tests/ui/type-alias-impl-trait/wf-nested.stderr @@ -27,7 +27,7 @@ LL | fn define_rpit() -> impl Trait<&'static T, Out = impl Sized> {} | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/wf-nested.rs:41:47 + --> $DIR/wf-nested.rs:42:47 | LL | fn define_nested_rpit() -> OuterOpaque2 {} | ^^ diff --git a/tests/ui/type-alias-impl-trait/wf_check_closures.rs b/tests/ui/type-alias-impl-trait/wf_check_closures.rs index 2c70696ffcf4..c633909f5138 100644 --- a/tests/ui/type-alias-impl-trait/wf_check_closures.rs +++ b/tests/ui/type-alias-impl-trait/wf_check_closures.rs @@ -6,8 +6,9 @@ trait Bar { type FooFn = impl FnOnce(); +#[define_opaque(FooFn)] fn foo(bar: B) -> FooFn { - move || { bar.bar() } + move || bar.bar() //~^ ERROR the trait bound `B: Bar` is not satisfied } diff --git a/tests/ui/type-alias-impl-trait/wf_check_closures.stderr b/tests/ui/type-alias-impl-trait/wf_check_closures.stderr index 4156f0ca96ae..57e40445c87c 100644 --- a/tests/ui/type-alias-impl-trait/wf_check_closures.stderr +++ b/tests/ui/type-alias-impl-trait/wf_check_closures.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `B: Bar` is not satisfied - --> $DIR/wf_check_closures.rs:10:5 + --> $DIR/wf_check_closures.rs:11:5 | -LL | move || { bar.bar() } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B` +LL | move || bar.bar() + | ^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B` | note: required by a bound in `foo` - --> $DIR/wf_check_closures.rs:9:11 + --> $DIR/wf_check_closures.rs:10:11 | LL | fn foo(bar: B) -> FooFn { | ^^^ required by this bound in `foo` diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index 9f1bfd7909e3..d7351f2e51a8 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -181,6 +181,7 @@ trait Trait {} impl Trait for Struct {} type Y = impl Trait<_>; //~^ ERROR the placeholder `_` is not allowed within types on item signatures for type aliases +#[define_opaque(Y)] fn foo() -> Y { Struct } diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index c5bf9a47e913..2a4a5a62ab4c 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -29,7 +29,7 @@ LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error: associated constant in `impl` without body - --> $DIR/typeck_type_placeholder_item.rs:206:5 + --> $DIR/typeck_type_placeholder_item.rs:207:5 | LL | const C: _; | ^^^^^^^^^^- @@ -578,13 +578,13 @@ LL | type Y = impl Trait<_>; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item.rs:206:14 + --> $DIR/typeck_type_placeholder_item.rs:207:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item.rs:194:14 + --> $DIR/typeck_type_placeholder_item.rs:195:14 | LL | const D: _ = 42; | ^ not allowed in type signatures @@ -596,13 +596,13 @@ LL + const D: i32 = 42; | error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item.rs:209:14 + --> $DIR/typeck_type_placeholder_item.rs:210:14 | LL | const D: _ = 42; | ^ not allowed in type signatures error[E0046]: not all trait items implemented, missing: `F` - --> $DIR/typeck_type_placeholder_item.rs:200:1 + --> $DIR/typeck_type_placeholder_item.rs:201:1 | LL | type F: std::ops::Fn(_); | ----------------------- `F` from trait @@ -611,7 +611,7 @@ LL | impl Qux for Struct { | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:217:31 + --> $DIR/typeck_type_placeholder_item.rs:218:31 | LL | fn value() -> Option<&'static _> { | ----------------^- @@ -620,7 +620,7 @@ LL | fn value() -> Option<&'static _> { | help: replace with the correct return type: `Option<&'static u8>` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:222:17 + --> $DIR/typeck_type_placeholder_item.rs:223:17 | LL | const _: Option<_> = map(value); | ^ not allowed in type signatures @@ -632,7 +632,7 @@ LL + const _: Option = map(value); | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/typeck_type_placeholder_item.rs:226:31 + --> $DIR/typeck_type_placeholder_item.rs:227:31 | LL | fn evens_squared(n: usize) -> _ { | ^ @@ -641,13 +641,13 @@ LL | fn evens_squared(n: usize) -> _ { | help: replace with an appropriate return type: `impl Iterator` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:231:10 + --> $DIR/typeck_type_placeholder_item.rs:232:10 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^ not allowed in type signatures | -note: however, the inferred type `Map, {closure@typeck_type_placeholder_item.rs:231:29}>, {closure@typeck_type_placeholder_item.rs:231:49}>` cannot be named - --> $DIR/typeck_type_placeholder_item.rs:231:14 +note: however, the inferred type `Map, {closure@typeck_type_placeholder_item.rs:232:29}>, {closure@typeck_type_placeholder_item.rs:232:49}>` cannot be named + --> $DIR/typeck_type_placeholder_item.rs:232:14 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -695,53 +695,53 @@ LL + fn fn_test10(&self, _x : T) { } | error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/typeck_type_placeholder_item.rs:202:14 + --> $DIR/typeck_type_placeholder_item.rs:203:14 | LL | type A = _; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/typeck_type_placeholder_item.rs:204:14 + --> $DIR/typeck_type_placeholder_item.rs:205:14 | LL | type B = _; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/typeck_type_placeholder_item.rs:190:14 + --> $DIR/typeck_type_placeholder_item.rs:191:14 | LL | type B = _; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item.rs:192:14 + --> $DIR/typeck_type_placeholder_item.rs:193:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types - --> $DIR/typeck_type_placeholder_item.rs:197:26 + --> $DIR/typeck_type_placeholder_item.rs:198:26 | LL | type F: std::ops::Fn(_); | ^ not allowed in type signatures error[E0015]: cannot call non-const function `map::` in constants - --> $DIR/typeck_type_placeholder_item.rs:222:22 + --> $DIR/typeck_type_placeholder_item.rs:223:22 | LL | const _: Option<_> = map(value); | ^^^^^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:231:29: 231:32}>` in constants - --> $DIR/typeck_type_placeholder_item.rs:231:22 +error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:232:29: 232:32}>` in constants + --> $DIR/typeck_type_placeholder_item.rs:232:22 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^^^^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:231:29: 231:32}> as Iterator>::map::` in constants - --> $DIR/typeck_type_placeholder_item.rs:231:45 +error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:232:29: 232:32}> as Iterator>::map::` in constants + --> $DIR/typeck_type_placeholder_item.rs:232:45 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^ From 3e4e65ee8b8c5d7a1916fd6377901416f06dca4d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Feb 2025 09:52:55 +0000 Subject: [PATCH 959/991] Test invalid `define_opaques` attributes --- compiler/rustc_ast_lowering/src/item.rs | 26 ++++++++++------- .../define_opaques_attr/foreign_type.rs | 5 ++++ .../define_opaques_attr/foreign_type.stderr | 8 +++++ .../define_opaques_attr/generics.rs | 13 +++++++++ .../define_opaques_attr/generics.stderr | 29 +++++++++++++++++++ .../define_opaques_attr/invalid_path.rs | 5 ++++ .../define_opaques_attr/invalid_path.stderr | 9 ++++++ .../define_opaques_attr/missing_parens.rs | 5 ++++ .../define_opaques_attr/missing_parens.stderr | 8 +++++ .../define_opaques_attr/no_opaque.rs | 8 +++++ .../define_opaques_attr/non_type.rs | 7 +++++ .../define_opaques_attr/non_type.stderr | 9 ++++++ 12 files changed, 121 insertions(+), 11 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/foreign_type.rs create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/foreign_type.stderr create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/generics.rs create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/generics.stderr create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/invalid_path.rs create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/invalid_path.stderr create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/missing_parens.rs create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/missing_parens.stderr create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.rs create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/non_type.rs create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/non_type.stderr diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 0aa42a0c4e75..302936ad1a1f 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1683,17 +1683,21 @@ impl<'hir> LoweringContext<'_, 'hir> { let Some(define_opaque) = define_opaque.as_ref() else { return; }; - let define_opaque = define_opaque - .iter() - // TODO: error reporting for non-local items being mentioned and tests that go through these code paths - .map(|(id, _path)| { - self.resolver - .get_partial_res(*id) - .unwrap() - .expect_full_res() - .def_id() - .expect_local() - }); + let define_opaque = define_opaque.iter().filter_map(|(id, path)| { + let res = self.resolver.get_partial_res(*id).unwrap(); + let Some(did) = res.expect_full_res().opt_def_id() else { + self.dcx().span_delayed_bug(path.span, "should have errored in resolve"); + return None; + }; + let Some(did) = did.as_local() else { + self.dcx().span_err( + path.span, + "only opaque types defined in the local crate can be defined", + ); + return None; + }; + Some(did) + }); let define_opaque = self.arena.alloc_from_iter(define_opaque); self.define_opaque = Some(define_opaque); } diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/foreign_type.rs b/tests/ui/type-alias-impl-trait/define_opaques_attr/foreign_type.rs new file mode 100644 index 000000000000..c8b6bdbe2b92 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/foreign_type.rs @@ -0,0 +1,5 @@ +#![feature(type_alias_impl_trait)] + +#[define_opaque(String)] +//~^ ERROR: only opaque types defined in the local crate can be defined +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/foreign_type.stderr b/tests/ui/type-alias-impl-trait/define_opaques_attr/foreign_type.stderr new file mode 100644 index 000000000000..65820e158f37 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/foreign_type.stderr @@ -0,0 +1,8 @@ +error: only opaque types defined in the local crate can be defined + --> $DIR/foreign_type.rs:3:17 + | +LL | #[define_opaque(String)] + | ^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.rs b/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.rs new file mode 100644 index 000000000000..11825dc54ee8 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_impl_trait)] + +type Tait = impl Sized; +//~^ ERROR: unconstrained opaque type + +#[define_opaque(Tait::<()>)] +//~^ ERROR: expected unsuffixed literal +fn foo() {} + +#[define_opaque(Tait<()>)] +//~^ ERROR: expected one of `(`, `,`, `::`, or `=`, found `<` +fn main() {} +//~^ ERROR: `main` function not found diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.stderr b/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.stderr new file mode 100644 index 000000000000..8f33f3367283 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.stderr @@ -0,0 +1,29 @@ +error: expected unsuffixed literal, found `<` + --> $DIR/generics.rs:6:23 + | +LL | #[define_opaque(Tait::<()>)] + | ^ + +error: expected one of `(`, `,`, `::`, or `=`, found `<` + --> $DIR/generics.rs:10:21 + | +LL | #[define_opaque(Tait<()>)] + | ^ expected one of `(`, `,`, `::`, or `=` + +error[E0601]: `main` function not found in crate `generics` + --> $DIR/generics.rs:12:13 + | +LL | fn main() {} + | ^ consider adding a `main` function to `$DIR/generics.rs` + +error: unconstrained opaque type + --> $DIR/generics.rs:3:16 + | +LL | type Tait = impl Sized; + | ^^^^^^^^^^ + | + = note: `Tait` must be used in combination with a concrete type within the same crate + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid_path.rs b/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid_path.rs new file mode 100644 index 000000000000..a02e80c6d89c --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid_path.rs @@ -0,0 +1,5 @@ +#![feature(type_alias_impl_trait)] + +#[define_opaque(Boom)] +//~^ ERROR: cannot find type alias or associated type +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid_path.stderr b/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid_path.stderr new file mode 100644 index 000000000000..6b4cd4eac512 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid_path.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type alias or associated type with opaqaue types `Boom` in this scope + --> $DIR/invalid_path.rs:3:17 + | +LL | #[define_opaque(Boom)] + | ^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/missing_parens.rs b/tests/ui/type-alias-impl-trait/define_opaques_attr/missing_parens.rs new file mode 100644 index 000000000000..6a5a1b456c3a --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/missing_parens.rs @@ -0,0 +1,5 @@ +#![feature(type_alias_impl_trait)] + +#[define_opaque] +//~^ ERROR: expected list of type aliases +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/missing_parens.stderr b/tests/ui/type-alias-impl-trait/define_opaques_attr/missing_parens.stderr new file mode 100644 index 000000000000..a3b98ec83b2e --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/missing_parens.stderr @@ -0,0 +1,8 @@ +error: expected list of type aliases + --> $DIR/missing_parens.rs:3:1 + | +LL | #[define_opaque] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.rs b/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.rs new file mode 100644 index 000000000000..d995e785cc85 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.rs @@ -0,0 +1,8 @@ +//@ check-pass + +#![feature(type_alias_impl_trait)] + +type Thing = (); + +#[define_opaque(Thing)] +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/non_type.rs b/tests/ui/type-alias-impl-trait/define_opaques_attr/non_type.rs new file mode 100644 index 000000000000..0ad87616a518 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/non_type.rs @@ -0,0 +1,7 @@ +#![feature(type_alias_impl_trait)] + +fn foo() {} + +#[define_opaque(foo)] +//~^ ERROR: expected type alias or associated type with opaqaue types +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/non_type.stderr b/tests/ui/type-alias-impl-trait/define_opaques_attr/non_type.stderr new file mode 100644 index 000000000000..0f91533bf7e1 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/non_type.stderr @@ -0,0 +1,9 @@ +error[E0573]: expected type alias or associated type with opaqaue types, found function `foo` + --> $DIR/non_type.rs:5:17 + | +LL | #[define_opaque(foo)] + | ^^^ not a type alias or associated type with opaqaue types + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0573`. From 43e39260f9bc02e79891b87f346b456a069967f5 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Feb 2025 10:22:19 +0000 Subject: [PATCH 960/991] Keep items around even if builtin macros on them fail to parse --- compiler/rustc_expand/src/expand.rs | 4 ++-- .../define_opaques_attr/generics.rs | 1 - .../define_opaques_attr/generics.stderr | 9 +-------- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index c523bcece723..87f01be26c25 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -780,8 +780,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } Err(err) => { - let guar = err.emit(); - fragment_kind.dummy(span, guar) + let _guar = err.emit(); + fragment_kind.expect_from_annotatables(iter::once(item)) } } } diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.rs b/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.rs index 11825dc54ee8..2ca2a753e201 100644 --- a/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.rs +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.rs @@ -10,4 +10,3 @@ fn foo() {} #[define_opaque(Tait<()>)] //~^ ERROR: expected one of `(`, `,`, `::`, or `=`, found `<` fn main() {} -//~^ ERROR: `main` function not found diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.stderr b/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.stderr index 8f33f3367283..96e8bc9851c1 100644 --- a/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.stderr +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/generics.stderr @@ -10,12 +10,6 @@ error: expected one of `(`, `,`, `::`, or `=`, found `<` LL | #[define_opaque(Tait<()>)] | ^ expected one of `(`, `,`, `::`, or `=` -error[E0601]: `main` function not found in crate `generics` - --> $DIR/generics.rs:12:13 - | -LL | fn main() {} - | ^ consider adding a `main` function to `$DIR/generics.rs` - error: unconstrained opaque type --> $DIR/generics.rs:3:16 | @@ -24,6 +18,5 @@ LL | type Tait = impl Sized; | = note: `Tait` must be used in combination with a concrete type within the same crate -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0601`. From 69a1bb8bdba5ccb76a72e35a69fde1937c287386 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Feb 2025 10:31:11 +0000 Subject: [PATCH 961/991] Error on `define_opaques` entries without any opaques actually referenced --- compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_ty_utils/src/opaque_types.rs | 7 +++++-- .../define_opaques_attr/no_opaque.rs | 3 +-- .../define_opaques_attr/no_opaque.stderr | 8 ++++++++ 6 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.stderr diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 302936ad1a1f..f0b5f99cc9fa 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1696,7 +1696,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); return None; }; - Some(did) + Some((self.lower_span(path.span), did)) }); let define_opaque = self.arena.alloc_from_iter(define_opaque); self.define_opaque = Some(define_opaque); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e42a4b460fea..e5569458dbde 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -99,7 +99,7 @@ struct LoweringContext<'a, 'hir> { /// Bodies inside the owner being lowered. bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>, /// `#[define_opaque]` attributes - define_opaque: Option<&'hir [LocalDefId]>, + define_opaque: Option<&'hir [(Span, LocalDefId)]>, /// Attributes inside the owner being lowered. attrs: SortedMap, /// Collect items that were created by lowering the current owner. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 1c54b99b12fc..53f0194091cd 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1308,7 +1308,7 @@ impl Attribute { pub struct AttributeMap<'tcx> { pub map: SortedMap, /// Preprocessed `#[define_opaque]` attribute. - pub define_opaque: Option<&'tcx [LocalDefId]>, + pub define_opaque: Option<&'tcx [(Span, LocalDefId)]>, // Only present when the crate hash is needed. pub opt_hash: Option, } diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 2d590dfdd141..a107925fb188 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -190,11 +190,14 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { let Some(defines) = self.tcx.hir_attrs(hir_id.owner).define_opaque else { return; }; - for &define in defines { + for &(span, define) in defines { trace!(?define); let mode = std::mem::replace(&mut self.mode, CollectionMode::Taits); - // TODO: check that opaque types were introduced and error otherwise (also add tests) + let n = self.opaques.len(); super::sig_types::walk_types(self.tcx, define, self); + if n == self.opaques.len() { + self.tcx.dcx().span_err(span, "item does not contain any opaque types"); + } self.mode = mode; } // Allow using `#[define_opaque]` on assoc methods and type aliases to override the default collection mode in diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.rs b/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.rs index d995e785cc85..4b60bad5c03a 100644 --- a/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.rs +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.rs @@ -1,8 +1,7 @@ -//@ check-pass - #![feature(type_alias_impl_trait)] type Thing = (); #[define_opaque(Thing)] +//~^ ERROR item does not contain any opaque types fn main() {} diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.stderr b/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.stderr new file mode 100644 index 000000000000..66ae3a43b951 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/no_opaque.stderr @@ -0,0 +1,8 @@ +error: item does not contain any opaque types + --> $DIR/no_opaque.rs:5:17 + | +LL | #[define_opaque(Thing)] + | ^^^^^ + +error: aborting due to 1 previous error + From 3846f942300c4fd8f43a8a8a1324ad5e358b9459 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Mar 2025 14:32:03 +0100 Subject: [PATCH 962/991] miri native_calls: ensure we actually expose *mutable* provenance to the memory FFI can access --- compiler/rustc_const_eval/src/interpret/memory.rs | 4 ++++ compiler/rustc_middle/src/mir/interpret/allocation.rs | 5 +++++ src/tools/miri/src/alloc_addresses/mod.rs | 4 ++-- src/tools/miri/src/shims/native_lib.rs | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index ce0b5a350e03..e5af06736291 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -982,6 +982,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { todo.push(id); } } + // Also expose the provenance of the interpreter-level allocation, so it can + // be read by FFI. The `black_box` is defensive programming as LLVM likes + // to (incorrectly) optimize away ptr2int casts whose result is unused. + std::hint::black_box(alloc.get_bytes_unchecked_raw().expose_provenance()); // Prepare for possible write from native code if mutable. if info.mutbl.is_mut() { diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index ba65a7118155..b24f6bc7770d 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -679,6 +679,11 @@ impl Allocation // Set provenance of all bytes to wildcard. self.provenance.write_wildcards(self.len()); + // Also expose the provenance of the interpreter-level allocation, so it can + // be written by FFI. The `black_box` is defensive programming as LLVM likes + // to (incorrectly) optimize away ptr2int casts whose result is unused. + std::hint::black_box(self.get_bytes_unchecked_raw_mut().expose_provenance()); + Ok(()) } diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index ff3a25e94bd5..5d257029a46e 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -198,8 +198,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } AllocKind::Dead => unreachable!(), }; - // Ensure this pointer's provenance is exposed, so that it can be used by FFI code. - return interp_ok(base_ptr.expose_provenance().try_into().unwrap()); + // We don't have to expose this pointer yet, we do that in `prepare_for_native_call`. + return interp_ok(base_ptr.addr().try_into().unwrap()); } // We are not in native lib mode, so we control the addresses ourselves. if let Some((reuse_addr, clock)) = global_state.reuse.take_addr( diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index c6fcb0355eb8..0258a76c3e70 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -266,7 +266,7 @@ fn imm_to_carg<'tcx>(v: &ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<' CArg::USize(v.to_scalar().to_target_usize(cx)?.try_into().unwrap()), ty::RawPtr(..) => { let s = v.to_scalar().to_pointer(cx)?.addr(); - // This relies on the `expose_provenance` in `addr_from_alloc_id`. + // This relies on the `expose_provenance` in `prepare_for_native_call`. CArg::RawPtr(std::ptr::with_exposed_provenance_mut(s.bytes_usize())) } _ => throw_unsup_format!("unsupported argument type for native call: {}", v.layout.ty), From ba6c40685418a24334afcb9acd7aa9bcd8b65181 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 11 Mar 2025 15:30:39 +0100 Subject: [PATCH 963/991] let the bodies hit the floor remove unnecessary `body` arguments --- .../src/type_check/input_output.rs | 54 +++-- .../src/type_check/liveness/mod.rs | 18 +- .../src/type_check/liveness/trace.rs | 42 ++-- compiler/rustc_borrowck/src/type_check/mod.rs | 210 +++++++++--------- 4 files changed, 152 insertions(+), 172 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index f70b17e33624..c6b29fe36fd9 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -24,9 +24,9 @@ use crate::universal_regions::DefiningTy; impl<'a, 'tcx> TypeChecker<'a, 'tcx> { /// Check explicit closure signature annotation, /// e.g., `|x: FxIndexMap<_, &'static u32>| ...`. - #[instrument(skip(self, body), level = "debug")] - pub(super) fn check_signature_annotation(&mut self, body: &Body<'tcx>) { - let mir_def_id = body.source.def_id().expect_local(); + #[instrument(skip(self), level = "debug")] + pub(super) fn check_signature_annotation(&mut self) { + let mir_def_id = self.body.source.def_id().expect_local(); if !self.tcx().is_closure_like(mir_def_id.to_def_id()) { return; @@ -38,9 +38,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // (e.g., the `_` in the code above) with fresh variables. // Then replace the bound items in the fn sig with fresh variables, // so that they represent the view from "inside" the closure. - let user_provided_sig = self.instantiate_canonical(body.span, &user_provided_poly_sig); + let user_provided_sig = self.instantiate_canonical(self.body.span, &user_provided_poly_sig); let mut user_provided_sig = self.infcx.instantiate_binder_with_fresh_vars( - body.span, + self.body.span, BoundRegionConversionTime::FnCall, user_provided_sig, ); @@ -66,12 +66,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Ty::new_tup(self.tcx(), user_provided_sig.inputs()), args.tupled_upvars_ty(), args.coroutine_captures_by_ref_ty(), - self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(body.span), || { - RegionCtxt::Unknown - }), + self.infcx + .next_region_var(RegionVariableOrigin::MiscVariable(self.body.span), || { + RegionCtxt::Unknown + }), ); - let next_ty_var = || self.infcx.next_ty_var(body.span); + let next_ty_var = || self.infcx.next_ty_var(self.body.span); let output_ty = Ty::new_coroutine( self.tcx(), self.tcx().coroutine_for_closure(mir_def_id), @@ -107,9 +108,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { for (&user_ty, arg_decl) in user_provided_sig.inputs().iter().zip_eq( // In MIR, closure args begin with an implicit `self`. // Also, coroutines have a resume type which may be implicitly `()`. - body.args_iter() + self.body + .args_iter() .skip(1 + if is_coroutine_with_implicit_resume_ty { 1 } else { 0 }) - .map(|local| &body.local_decls[local]), + .map(|local| &self.body.local_decls[local]), ) { self.ascribe_user_type_skip_wf( arg_decl.ty, @@ -119,7 +121,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // If the user explicitly annotated the output type, enforce it. - let output_decl = &body.local_decls[RETURN_PLACE]; + let output_decl = &self.body.local_decls[RETURN_PLACE]; self.ascribe_user_type_skip_wf( output_decl.ty, ty::UserType::new(ty::UserTypeKind::Ty(user_provided_sig.output())), @@ -127,12 +129,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } - #[instrument(skip(self, body), level = "debug")] - pub(super) fn equate_inputs_and_outputs( - &mut self, - body: &Body<'tcx>, - normalized_inputs_and_output: &[Ty<'tcx>], - ) { + #[instrument(skip(self), level = "debug")] + pub(super) fn equate_inputs_and_outputs(&mut self, normalized_inputs_and_output: &[Ty<'tcx>]) { let (&normalized_output_ty, normalized_input_tys) = normalized_inputs_and_output.split_last().unwrap(); @@ -141,18 +139,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // Equate expected input tys with those in the MIR. for (argument_index, &normalized_input_ty) in normalized_input_tys.iter().enumerate() { - if argument_index + 1 >= body.local_decls.len() { + if argument_index + 1 >= self.body.local_decls.len() { self.tcx() .dcx() - .span_bug(body.span, "found more normalized_input_ty than local_decls"); + .span_bug(self.body.span, "found more normalized_input_ty than local_decls"); } // In MIR, argument N is stored in local N+1. let local = Local::from_usize(argument_index + 1); - let mir_input_ty = body.local_decls[local].ty; + let mir_input_ty = self.body.local_decls[local].ty; - let mir_input_span = body.local_decls[local].source_info.span; + let mir_input_span = self.body.local_decls[local].source_info.span; self.equate_normalized_input_or_output( normalized_input_ty, mir_input_ty, @@ -160,8 +158,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } - if let Some(mir_yield_ty) = body.yield_ty() { - let yield_span = body.local_decls[RETURN_PLACE].source_info.span; + if let Some(mir_yield_ty) = self.body.yield_ty() { + let yield_span = self.body.local_decls[RETURN_PLACE].source_info.span; self.equate_normalized_input_or_output( self.universal_regions.yield_ty.unwrap(), mir_yield_ty, @@ -169,8 +167,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } - if let Some(mir_resume_ty) = body.resume_ty() { - let yield_span = body.local_decls[RETURN_PLACE].source_info.span; + if let Some(mir_resume_ty) = self.body.resume_ty() { + let yield_span = self.body.local_decls[RETURN_PLACE].source_info.span; self.equate_normalized_input_or_output( self.universal_regions.resume_ty.unwrap(), mir_resume_ty, @@ -179,8 +177,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // Return types are a bit more complex. They may contain opaque `impl Trait` types. - let mir_output_ty = body.local_decls[RETURN_PLACE].ty; - let output_span = body.local_decls[RETURN_PLACE].source_info.span; + let mir_output_ty = self.body.local_decls[RETURN_PLACE].ty; + let output_span = self.body.local_decls[RETURN_PLACE].source_info.span; self.equate_normalized_input_or_output(normalized_output_ty, mir_output_ty, output_span); } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index dcc179030020..f17ad23f4bf6 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -31,7 +31,6 @@ mod trace; /// performed before pub(super) fn generate<'a, 'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, - body: &Body<'tcx>, location_map: &DenseLocationMap, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, move_data: &MoveData<'tcx>, @@ -51,23 +50,16 @@ pub(super) fn generate<'a, 'tcx>( // We do record these regions in the polonius context, since they're used to differentiate // relevant and boring locals, which is a key distinction used later in diagnostics. if typeck.tcx().sess.opts.unstable_opts.polonius.is_next_enabled() { - let (_, boring_locals) = compute_relevant_live_locals(typeck.tcx(), &free_regions, body); + let (_, boring_locals) = + compute_relevant_live_locals(typeck.tcx(), &free_regions, typeck.body); typeck.polonius_liveness.as_mut().unwrap().boring_nll_locals = boring_locals.into_iter().collect(); free_regions = typeck.universal_regions.universal_regions_iter().collect(); } let (relevant_live_locals, boring_locals) = - compute_relevant_live_locals(typeck.tcx(), &free_regions, body); + compute_relevant_live_locals(typeck.tcx(), &free_regions, typeck.body); - trace::trace( - typeck, - body, - location_map, - flow_inits, - move_data, - relevant_live_locals, - boring_locals, - ); + trace::trace(typeck, location_map, flow_inits, move_data, relevant_live_locals, boring_locals); // Mark regions that should be live where they appear within rvalues or within a call: like // args, regions, and types. @@ -76,7 +68,7 @@ pub(super) fn generate<'a, 'tcx>( &mut typeck.constraints.liveness_constraints, &typeck.universal_regions, &mut typeck.polonius_liveness, - body, + typeck.body, ); } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 32d398dc1605..7718644b9a9a 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -39,17 +39,15 @@ use crate::type_check::{NormalizeLocation, TypeChecker}; /// this respects `#[may_dangle]` annotations). pub(super) fn trace<'a, 'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, - body: &Body<'tcx>, location_map: &DenseLocationMap, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, move_data: &MoveData<'tcx>, relevant_live_locals: Vec, boring_locals: Vec, ) { - let local_use_map = &LocalUseMap::build(&relevant_live_locals, location_map, body); + let local_use_map = &LocalUseMap::build(&relevant_live_locals, location_map, typeck.body); let cx = LivenessContext { typeck, - body, flow_inits, location_map, local_use_map, @@ -69,14 +67,13 @@ pub(super) fn trace<'a, 'tcx>( /// Contextual state for the type-liveness coroutine. struct LivenessContext<'a, 'typeck, 'b, 'tcx> { /// Current type-checker, giving us our inference context etc. + /// + /// This also stores the body we're currently analyzing. typeck: &'a mut TypeChecker<'typeck, 'tcx>, /// Defines the `PointIndex` mapping location_map: &'a DenseLocationMap, - /// MIR we are analyzing. - body: &'a Body<'tcx>, - /// Mapping to/from the various indices used for initialization tracking. move_data: &'a MoveData<'tcx>, @@ -139,7 +136,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { self.compute_use_live_points_for(local); self.compute_drop_live_points_for(local); - let local_ty = self.cx.body.local_decls[local].ty; + let local_ty = self.cx.body().local_decls[local].ty; if !self.use_live_at.is_empty() { self.cx.add_use_live_facts_for(local_ty, &self.use_live_at); @@ -164,8 +161,8 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { /// and can therefore safely be dropped. fn dropck_boring_locals(&mut self, boring_locals: Vec) { for local in boring_locals { - let local_ty = self.cx.body.local_decls[local].ty; - let local_span = self.cx.body.local_decls[local].source_info.span; + let local_ty = self.cx.body().local_decls[local].ty; + let local_span = self.cx.body().local_decls[local].source_info.span; let drop_data = self.cx.drop_data.entry(local_ty).or_insert_with({ let typeck = &self.cx.typeck; move || LivenessContext::compute_drop_data(typeck, local_ty, local_span) @@ -173,7 +170,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { drop_data.dropck_result.report_overflows( self.cx.typeck.infcx.tcx, - self.cx.body.local_decls[local].source_info.span, + self.cx.typeck.body.local_decls[local].source_info.span, local_ty, ); } @@ -202,7 +199,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { .var_dropped_at .iter() .filter_map(|&(local, location_index)| { - let local_ty = self.cx.body.local_decls[local].ty; + let local_ty = self.cx.body().local_decls[local].ty; if relevant_live_locals.contains(&local) || !local_ty.has_free_regions() { return None; } @@ -278,9 +275,9 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { let block = self.cx.location_map.to_location(block_start).block; self.stack.extend( - self.cx.body.basic_blocks.predecessors()[block] + self.cx.body().basic_blocks.predecessors()[block] .iter() - .map(|&pred_bb| self.cx.body.terminator_loc(pred_bb)) + .map(|&pred_bb| self.cx.body().terminator_loc(pred_bb)) .map(|pred_loc| self.cx.location_map.point_from_location(pred_loc)), ); } @@ -305,7 +302,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { // Find the drops where `local` is initialized. for drop_point in self.cx.local_use_map.drops(local) { let location = self.cx.location_map.to_location(drop_point); - debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,); + debug_assert_eq!(self.cx.body().terminator_loc(location.block), location,); if self.cx.initialized_at_terminator(location.block, mpi) && self.drop_live_at.insert(drop_point) @@ -351,7 +348,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { // block. One of them may be either a definition or use // live point. let term_location = self.cx.location_map.to_location(term_point); - debug_assert_eq!(self.cx.body.terminator_loc(term_location.block), term_location,); + debug_assert_eq!(self.cx.body().terminator_loc(term_location.block), term_location,); let block = term_location.block; let entry_point = self.cx.location_map.entry_point(term_location.block); for p in (entry_point..term_point).rev() { @@ -376,7 +373,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { } } - let body = self.cx.body; + let body = self.cx.typeck.body; for &pred_block in body.basic_blocks.predecessors()[block].iter() { debug!("compute_drop_live_points_for_block: pred_block = {:?}", pred_block,); @@ -403,7 +400,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { continue; } - let pred_term_loc = self.cx.body.terminator_loc(pred_block); + let pred_term_loc = self.cx.body().terminator_loc(pred_block); let pred_term_point = self.cx.location_map.point_from_location(pred_term_loc); // If the terminator of this predecessor either *assigns* @@ -463,6 +460,9 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { } impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { + fn body(&self) -> &Body<'tcx> { + self.typeck.body + } /// Returns `true` if the local variable (or some part of it) is initialized at the current /// cursor position. Callers should call one of the `seek` methods immediately before to point /// the cursor to the desired location. @@ -481,7 +481,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { /// DROP of some local variable will have an effect -- note that /// drops, as they may unwind, are always terminators. fn initialized_at_terminator(&mut self, block: BasicBlock, mpi: MovePathIndex) -> bool { - self.flow_inits.seek_before_primary_effect(self.body.terminator_loc(block)); + self.flow_inits.seek_before_primary_effect(self.body().terminator_loc(block)); self.initialized_at_curr_loc(mpi) } @@ -491,7 +491,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { /// **Warning:** Does not account for the result of `Call` /// instructions. fn initialized_at_exit(&mut self, block: BasicBlock, mpi: MovePathIndex) -> bool { - self.flow_inits.seek_after_primary_effect(self.body.terminator_loc(block)); + self.flow_inits.seek_after_primary_effect(self.body().terminator_loc(block)); self.initialized_at_curr_loc(mpi) } @@ -526,7 +526,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { values::pretty_print_points(self.location_map, live_at.iter()), ); - let local_span = self.body.local_decls()[dropped_local].source_info.span; + let local_span = self.body().local_decls()[dropped_local].source_info.span; let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({ let typeck = &self.typeck; move || Self::compute_drop_data(typeck, dropped_ty, local_span) @@ -544,7 +544,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { drop_data.dropck_result.report_overflows( self.typeck.infcx.tcx, - self.body.source_info(*drop_locations.first().unwrap()).span, + self.typeck.body.source_info(*drop_locations.first().unwrap()).span, dropped_ty, ); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c1e23cb54117..9d5022f2bef4 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -174,11 +174,11 @@ pub(crate) fn type_check<'a, 'tcx>( let mut verifier = TypeVerifier { typeck: &mut typeck, promoted, last_span: body.span }; verifier.visit_body(body); - typeck.typeck_mir(body); - typeck.equate_inputs_and_outputs(body, &normalized_inputs_and_output); - typeck.check_signature_annotation(body); + typeck.typeck_mir(); + typeck.equate_inputs_and_outputs(&normalized_inputs_and_output); + typeck.check_signature_annotation(); - liveness::generate(&mut typeck, body, &location_map, flow_inits, move_data); + liveness::generate(&mut typeck, &location_map, flow_inits, move_data); let opaque_type_values = opaque_types::take_opaques_and_register_member_constraints(&mut typeck); @@ -485,6 +485,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_body(&mut self, body: &Body<'tcx>) { + debug_assert!(std::ptr::eq(self.typeck.body, body)); // We intentionally do not recurse into `body.required_consts` or // `body.mentioned_items` here as the MIR at this phase should still // refer to all items and we don't want to check them multiple times. @@ -542,7 +543,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { self.visit_body(promoted_body); - self.typeck.typeck_mir(promoted_body); + self.typeck.typeck_mir(); self.typeck.body = parent_body; // Merge the outlives constraints back in, at the given location. @@ -892,8 +893,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.infcx.tcx } - #[instrument(skip(self, body), level = "debug")] - fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) { + #[instrument(skip(self), level = "debug")] + fn check_stmt(&mut self, stmt: &Statement<'tcx>, location: Location) { let tcx = self.tcx(); debug!("stmt kind: {:?}", stmt.kind); match &stmt.kind { @@ -916,11 +917,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } Some(l) - if matches!(body.local_decls[l].local_info(), LocalInfo::AggregateTemp) => + if matches!( + self.body.local_decls[l].local_info(), + LocalInfo::AggregateTemp + ) => { ConstraintCategory::Usage } - Some(l) if !body.local_decls[l].is_user_variable() => { + Some(l) if !self.body.local_decls[l].is_user_variable() => { ConstraintCategory::Boring } _ => ConstraintCategory::Assignment, @@ -928,14 +932,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { debug!( "assignment category: {:?} {:?}", category, - place.as_local().map(|l| &body.local_decls[l]) + place.as_local().map(|l| &self.body.local_decls[l]) ); - let place_ty = place.ty(body, tcx).ty; + let place_ty = place.ty(self.body, tcx).ty; debug!(?place_ty); let place_ty = self.normalize(place_ty, location); debug!("place_ty normalized: {:?}", place_ty); - let rv_ty = rv.ty(body, tcx); + let rv_ty = rv.ty(self.body, tcx); debug!(?rv_ty); let rv_ty = self.normalize(rv_ty, location); debug!("normalized rv_ty: {:?}", rv_ty); @@ -972,7 +976,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - self.check_rvalue(body, rv, location); + self.check_rvalue(rv, location); if !self.unsized_feature_enabled() { let trait_ref = ty::TraitRef::new( tcx, @@ -987,7 +991,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } StatementKind::AscribeUserType(box (place, projection), variance) => { - let place_ty = place.ty(body, tcx).ty; + let place_ty = place.ty(self.body, tcx).ty; if let Err(terr) = self.relate_type_and_user_type( place_ty, *variance, @@ -1029,13 +1033,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - #[instrument(skip(self, body, term_location), level = "debug")] - fn check_terminator( - &mut self, - body: &Body<'tcx>, - term: &Terminator<'tcx>, - term_location: Location, - ) { + #[instrument(skip(self, term_location), level = "debug")] + fn check_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location) { let tcx = self.tcx(); debug!("terminator kind: {:?}", term.kind); match &term.kind { @@ -1055,7 +1054,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { TerminatorKind::SwitchInt { discr, .. } => { self.check_operand(discr, term_location); - let switch_ty = discr.ty(body, tcx); + let switch_ty = discr.ty(self.body, tcx); if !switch_ty.is_integral() && !switch_ty.is_char() && !switch_ty.is_bool() { span_mirbug!(self, term, "bad SwitchInt discr ty {:?}", switch_ty); } @@ -1074,7 +1073,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_operand(&arg.node, term_location); } - let func_ty = func.ty(body, tcx); + let func_ty = func.ty(self.body, tcx); debug!("func_ty.kind: {:?}", func_ty.kind()); let sig = match func_ty.kind() { @@ -1142,7 +1141,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } if let TerminatorKind::Call { destination, target, .. } = term.kind { - self.check_call_dest(body, term, &sig, destination, target, term_location); + self.check_call_dest(term, &sig, destination, target, term_location); } // The ordinary liveness rules will ensure that all @@ -1157,21 +1156,21 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.constraints.liveness_constraints.add_location(region_vid, term_location); } - self.check_call_inputs(body, term, func, &sig, args, term_location, call_source); + self.check_call_inputs(term, func, &sig, args, term_location, call_source); } TerminatorKind::Assert { cond, msg, .. } => { self.check_operand(cond, term_location); - let cond_ty = cond.ty(body, tcx); + let cond_ty = cond.ty(self.body, tcx); if cond_ty != tcx.types.bool { span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty); } if let AssertKind::BoundsCheck { len, index } = &**msg { - if len.ty(body, tcx) != tcx.types.usize { + if len.ty(self.body, tcx) != tcx.types.usize { span_mirbug!(self, len, "bounds-check length non-usize {:?}", len) } - if index.ty(body, tcx) != tcx.types.usize { + if index.ty(self.body, tcx) != tcx.types.usize { span_mirbug!(self, index, "bounds-check index non-usize {:?}", index) } } @@ -1179,10 +1178,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { TerminatorKind::Yield { value, resume_arg, .. } => { self.check_operand(value, term_location); - match body.yield_ty() { + match self.body.yield_ty() { None => span_mirbug!(self, term, "yield in non-coroutine"), Some(ty) => { - let value_ty = value.ty(body, tcx); + let value_ty = value.ty(self.body, tcx); if let Err(terr) = self.sub_types( value_ty, ty, @@ -1201,10 +1200,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - match body.resume_ty() { + match self.body.resume_ty() { None => span_mirbug!(self, term, "yield in non-coroutine"), Some(ty) => { - let resume_ty = resume_arg.ty(body, tcx); + let resume_ty = resume_arg.ty(self.body, tcx); if let Err(terr) = self.sub_types( ty, resume_ty.ty, @@ -1228,7 +1227,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn check_call_dest( &mut self, - body: &Body<'tcx>, term: &Terminator<'tcx>, sig: &ty::FnSig<'tcx>, destination: Place<'tcx>, @@ -1238,7 +1236,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let tcx = self.tcx(); match target { Some(_) => { - let dest_ty = destination.ty(body, tcx).ty; + let dest_ty = destination.ty(self.body, tcx).ty; let dest_ty = self.normalize(dest_ty, term_location); let category = match destination.as_local() { Some(RETURN_PLACE) => { @@ -1254,7 +1252,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Return(ReturnConstraint::Normal) } } - Some(l) if !body.local_decls[l].is_user_variable() => { + Some(l) if !self.body.local_decls[l].is_user_variable() => { ConstraintCategory::Boring } // The return type of a call is interesting for diagnostics. @@ -1295,10 +1293,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self, body, term, func, term_location, call_source))] + #[instrument(level = "debug", skip(self, term, func, term_location, call_source))] fn check_call_inputs( &mut self, - body: &Body<'tcx>, term: &Terminator<'tcx>, func: &Operand<'tcx>, sig: &ty::FnSig<'tcx>, @@ -1310,7 +1307,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); } - let func_ty = func.ty(body, self.infcx.tcx); + let func_ty = func.ty(self.body, self.infcx.tcx); if let ty::FnDef(def_id, _) = *func_ty.kind() { // Some of the SIMD intrinsics are special: they need a particular argument to be a // constant. (Eventually this should use const-generics, but those are not up for the @@ -1334,7 +1331,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { debug!(?func_ty); for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { - let op_arg_ty = op_arg.node.ty(body, self.tcx()); + let op_arg_ty = op_arg.node.ty(self.body, self.tcx()); let op_arg_ty = self.normalize(op_arg_ty, term_location); let category = if call_source.from_hir_call() { @@ -1358,16 +1355,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - fn check_iscleanup(&mut self, body: &Body<'tcx>, block_data: &BasicBlockData<'tcx>) { + fn check_iscleanup(&mut self, block_data: &BasicBlockData<'tcx>) { let is_cleanup = block_data.is_cleanup; self.last_span = block_data.terminator().source_info.span; match block_data.terminator().kind { TerminatorKind::Goto { target } => { - self.assert_iscleanup(body, block_data, target, is_cleanup) + self.assert_iscleanup(block_data, target, is_cleanup) } TerminatorKind::SwitchInt { ref targets, .. } => { for target in targets.all_targets() { - self.assert_iscleanup(body, block_data, *target, is_cleanup); + self.assert_iscleanup(block_data, *target, is_cleanup); } } TerminatorKind::UnwindResume => { @@ -1399,55 +1396,48 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if is_cleanup { span_mirbug!(self, block_data, "yield in cleanup block") } - self.assert_iscleanup(body, block_data, resume, is_cleanup); + self.assert_iscleanup(block_data, resume, is_cleanup); if let Some(drop) = drop { - self.assert_iscleanup(body, block_data, drop, is_cleanup); + self.assert_iscleanup(block_data, drop, is_cleanup); } } TerminatorKind::Unreachable => {} TerminatorKind::Drop { target, unwind, .. } | TerminatorKind::Assert { target, unwind, .. } => { - self.assert_iscleanup(body, block_data, target, is_cleanup); - self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup); + self.assert_iscleanup(block_data, target, is_cleanup); + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); } TerminatorKind::Call { ref target, unwind, .. } => { if let &Some(target) = target { - self.assert_iscleanup(body, block_data, target, is_cleanup); + self.assert_iscleanup(block_data, target, is_cleanup); } - self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup); + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); } TerminatorKind::FalseEdge { real_target, imaginary_target } => { - self.assert_iscleanup(body, block_data, real_target, is_cleanup); - self.assert_iscleanup(body, block_data, imaginary_target, is_cleanup); + self.assert_iscleanup(block_data, real_target, is_cleanup); + self.assert_iscleanup(block_data, imaginary_target, is_cleanup); } TerminatorKind::FalseUnwind { real_target, unwind } => { - self.assert_iscleanup(body, block_data, real_target, is_cleanup); - self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup); + self.assert_iscleanup(block_data, real_target, is_cleanup); + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); } TerminatorKind::InlineAsm { ref targets, unwind, .. } => { for &target in targets { - self.assert_iscleanup(body, block_data, target, is_cleanup); + self.assert_iscleanup(block_data, target, is_cleanup); } - self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup); + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); } } } - fn assert_iscleanup( - &mut self, - body: &Body<'tcx>, - ctxt: &dyn fmt::Debug, - bb: BasicBlock, - iscleanuppad: bool, - ) { - if body[bb].is_cleanup != iscleanuppad { + fn assert_iscleanup(&mut self, ctxt: &dyn fmt::Debug, bb: BasicBlock, iscleanuppad: bool) { + if self.body[bb].is_cleanup != iscleanuppad { span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad); } } fn assert_iscleanup_unwind( &mut self, - body: &Body<'tcx>, ctxt: &dyn fmt::Debug, unwind: UnwindAction, is_cleanup: bool, @@ -1457,7 +1447,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if is_cleanup { span_mirbug!(self, ctxt, "unwind on cleanup block") } - self.assert_iscleanup(body, ctxt, unwind, true); + self.assert_iscleanup(ctxt, unwind, true); } UnwindAction::Continue => { if is_cleanup { @@ -1468,8 +1458,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - fn check_local(&mut self, body: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) { - match body.local_kind(local) { + fn check_local(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { + match self.body.local_kind(local) { LocalKind::ReturnPointer | LocalKind::Arg => { // return values of normal functions are required to be // sized by typeck, but return values of ADT constructors are @@ -1598,23 +1588,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - #[instrument(skip(self, body), level = "debug")] - fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { + #[instrument(skip(self), level = "debug")] + fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { let tcx = self.tcx(); - let span = body.source_info(location).span; + let span = self.body.source_info(location).span; match rvalue { Rvalue::Aggregate(ak, ops) => { for op in ops { self.check_operand(op, location); } - self.check_aggregate_rvalue(body, rvalue, ak, ops, location) + self.check_aggregate_rvalue(rvalue, ak, ops, location) } Rvalue::Repeat(operand, len) => { self.check_operand(operand, location); - let array_ty = rvalue.ty(body.local_decls(), tcx); + let array_ty = rvalue.ty(self.body.local_decls(), tcx); self.prove_predicate( ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(array_ty.into())), Locations::Single(location), @@ -1633,7 +1623,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } Operand::Move(place) => { // Make sure that repeated elements implement `Copy`. - let ty = place.ty(body, tcx).ty; + let ty = place.ty(self.body, tcx).ty; let trait_ref = ty::TraitRef::new( tcx, tcx.require_lang_item(LangItem::Copy, Some(span)), @@ -1688,7 +1678,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { match *cast_kind { CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, coercion_source) => { let is_implicit_coercion = coercion_source == CoercionSource::Implicit; - let src_ty = op.ty(body, tcx); + let src_ty = op.ty(self.body, tcx); let mut src_sig = src_ty.fn_sig(tcx); if let ty::FnDef(def_id, _) = src_ty.kind() && let ty::FnPtr(_, target_hdr) = *ty.kind() @@ -1697,7 +1687,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { && let Some(safe_sig) = tcx.adjust_target_feature_sig( *def_id, src_sig, - body.source.def_id(), + self.body.source.def_id(), ) { src_sig = safe_sig; @@ -1790,7 +1780,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { PointerCoercion::ClosureFnPointer(safety), coercion_source, ) => { - let sig = match op.ty(body, tcx).kind() { + let sig = match op.ty(self.body, tcx).kind() { ty::Closure(_, args) => args.as_closure().sig(), _ => bug!(), }; @@ -1819,7 +1809,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { PointerCoercion::UnsafeFnPointer, coercion_source, ) => { - let fn_sig = op.ty(body, tcx).fn_sig(tcx); + let fn_sig = op.ty(self.body, tcx).fn_sig(tcx); // The type that we see in the fcx is like // `foo::<'a, 'b>`, where `foo` is the path to a @@ -1853,7 +1843,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let trait_ref = ty::TraitRef::new( tcx, tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)), - [op.ty(body, tcx), ty], + [op.ty(self.body, tcx), ty], ); let is_implicit_coercion = coercion_source == CoercionSource::Implicit; @@ -1879,7 +1869,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { _ => panic!("Invalid dyn* cast_ty"), }; - let self_ty = op.ty(body, tcx); + let self_ty = op.ty(self.body, tcx); let is_implicit_coercion = coercion_source == CoercionSource::Implicit; self.prove_predicates( @@ -1906,7 +1896,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { PointerCoercion::MutToConstPointer, coercion_source, ) => { - let ty::RawPtr(ty_from, hir::Mutability::Mut) = op.ty(body, tcx).kind() + let ty::RawPtr(ty_from, hir::Mutability::Mut) = + op.ty(self.body, tcx).kind() else { span_mirbug!(self, rvalue, "unexpected base type for cast {:?}", ty,); return; @@ -1934,7 +1925,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, coercion_source) => { - let ty_from = op.ty(body, tcx); + let ty_from = op.ty(self.body, tcx); let opt_ty_elem_mut = match ty_from.kind() { ty::RawPtr(array_ty, array_mut) => match array_ty.kind() { @@ -1997,7 +1988,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } CastKind::PointerExposeProvenance => { - let ty_from = op.ty(body, tcx); + let ty_from = op.ty(self.body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { @@ -2015,7 +2006,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } CastKind::PointerWithExposedProvenance => { - let ty_from = op.ty(body, tcx); + let ty_from = op.ty(self.body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { @@ -2032,7 +2023,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } CastKind::IntToInt => { - let ty_from = op.ty(body, tcx); + let ty_from = op.ty(self.body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { @@ -2049,7 +2040,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } CastKind::IntToFloat => { - let ty_from = op.ty(body, tcx); + let ty_from = op.ty(self.body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { @@ -2066,7 +2057,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } CastKind::FloatToInt => { - let ty_from = op.ty(body, tcx); + let ty_from = op.ty(self.body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { @@ -2083,7 +2074,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } CastKind::FloatToFloat => { - let ty_from = op.ty(body, tcx); + let ty_from = op.ty(self.body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { @@ -2100,7 +2091,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } CastKind::FnPtrToPtr => { - let ty_from = op.ty(body, tcx); + let ty_from = op.ty(self.body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { @@ -2117,7 +2108,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } CastKind::PtrToPtr => { - let ty_from = op.ty(body, tcx); + let ty_from = op.ty(self.body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { @@ -2193,7 +2184,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } Rvalue::Ref(region, _borrow_kind, borrowed_place) => { - self.add_reborrow_constraint(body, location, *region, borrowed_place); + self.add_reborrow_constraint(location, *region, borrowed_place); } Rvalue::BinaryOp( @@ -2203,12 +2194,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_operand(left, location); self.check_operand(right, location); - let ty_left = left.ty(body, tcx); + let ty_left = left.ty(self.body, tcx); match ty_left.kind() { // Types with regions are comparable if they have a common super-type. ty::RawPtr(_, _) | ty::FnPtr(..) => { - let ty_right = right.ty(body, tcx); - let common_ty = self.infcx.next_ty_var(body.source_info(location).span); + let ty_right = right.ty(self.body, tcx); + let common_ty = + self.infcx.next_ty_var(self.body.source_info(location).span); self.sub_types( ty_left, common_ty, @@ -2237,7 +2229,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // For types with no regions we can just check that the // both operands have the same type. ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_) - if ty_left == right.ty(body, tcx) => {} + if ty_left == right.ty(self.body, tcx) => {} // Other types are compared by trait methods, not by // `Rvalue::BinaryOp`. _ => span_mirbug!( @@ -2245,7 +2237,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { rvalue, "unexpected comparison types {:?} and {:?}", ty_left, - right.ty(body, tcx) + right.ty(self.body, tcx) ), } } @@ -2326,7 +2318,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn check_aggregate_rvalue( &mut self, - body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, aggregate_kind: &AggregateKind<'tcx>, operands: &IndexSlice>, @@ -2359,7 +2350,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { continue; } }; - let operand_ty = operand.ty(body, tcx); + let operand_ty = operand.ty(self.body, tcx); let operand_ty = self.normalize(operand_ty, location); if let Err(terr) = self.sub_types( @@ -2389,7 +2380,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { /// - `borrowed_place`: the place `P` being borrowed fn add_reborrow_constraint( &mut self, - body: &Body<'tcx>, location: Location, borrow_region: ty::Region<'tcx>, borrowed_place: &Place<'tcx>, @@ -2428,7 +2418,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let def = self.body.source.def_id().expect_local(); let upvars = tcx.closure_captures(def); let field = - path_utils::is_upvar_field_projection(tcx, upvars, borrowed_place.as_ref(), body); + path_utils::is_upvar_field_projection(tcx, upvars, borrowed_place.as_ref(), self.body); let category = if let Some(field) = field { ConstraintCategory::ClosureUpvar(field) } else { @@ -2440,7 +2430,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { match elem { ProjectionElem::Deref => { - let base_ty = base.ty(body, tcx).ty; + let base_ty = base.ty(self.body, tcx).ty; debug!("add_reborrow_constraint - base_ty = {:?}", base_ty); match base_ty.kind() { @@ -2449,7 +2439,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { sup: ref_region.as_var(), sub: borrow_region.as_var(), locations: location.to_locations(), - span: location.to_locations().span(body), + span: location.to_locations().span(self.body), category, variance_info: ty::VarianceDiagInfo::default(), from_closure: false, @@ -2634,27 +2624,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { tcx.predicates_of(def_id).instantiate(tcx, args) } - #[instrument(skip(self, body), level = "debug")] - fn typeck_mir(&mut self, body: &Body<'tcx>) { - self.last_span = body.span; - debug!(?body.span); + #[instrument(skip(self), level = "debug")] + fn typeck_mir(&mut self) { + self.last_span = self.body.span; + debug!(?self.body.span); - for (local, local_decl) in body.local_decls.iter_enumerated() { - self.check_local(body, local, local_decl); + for (local, local_decl) in self.body.local_decls.iter_enumerated() { + self.check_local(local, local_decl); } - for (block, block_data) in body.basic_blocks.iter_enumerated() { + for (block, block_data) in self.body.basic_blocks.iter_enumerated() { let mut location = Location { block, statement_index: 0 }; for stmt in &block_data.statements { if !stmt.source_info.span.is_dummy() { self.last_span = stmt.source_info.span; } - self.check_stmt(body, stmt, location); + self.check_stmt(stmt, location); location.statement_index += 1; } - self.check_terminator(body, block_data.terminator(), location); - self.check_iscleanup(body, block_data); + self.check_terminator(block_data.terminator(), location); + self.check_iscleanup(block_data); } } } From 75a69a48f3aebaaa7cb3ce2ffcd3816f10895f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Mar 2025 11:53:57 +0100 Subject: [PATCH 964/991] Do not download GCC in tests --- src/bootstrap/src/core/build_steps/gcc.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 7e1ec39659a3..5a4bc9bdbcba 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -13,11 +13,9 @@ use std::path::{Path, PathBuf}; use std::sync::OnceLock; use build_helper::ci::CiEnv; -use build_helper::git::get_closest_merge_commit; -use crate::Config; use crate::core::builder::{Builder, Cargo, Kind, RunConfig, ShouldRun, Step}; -use crate::core::config::{GccCiMode, TargetSelection}; +use crate::core::config::TargetSelection; use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash}; use crate::utils::exec::command; use crate::utils::helpers::{self, t}; @@ -93,9 +91,10 @@ pub enum GccBuildStatus { /// Tries to download GCC from CI if it is enabled and GCC artifacts /// are available for the given target. /// Returns a path to the libgccjit.so file. +#[cfg(not(test))] fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option { // Try to download GCC from CI if configured and available - if !matches!(builder.config.gcc_ci_mode, GccCiMode::DownloadFromCi) { + if !matches!(builder.config.gcc_ci_mode, crate::core::config::GccCiMode::DownloadFromCi) { return None; } if target != "x86_64-unknown-linux-gnu" { @@ -114,6 +113,11 @@ fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option, _target: TargetSelection) -> Option { + None +} + /// This returns information about whether GCC should be built or if it's already built. /// It transparently handles downloading GCC from CI if needed. /// @@ -247,12 +251,16 @@ pub fn add_cg_gcc_cargo_flags(cargo: &mut Cargo, gcc: &GccOutput) { } /// The absolute path to the downloaded GCC artifacts. -fn ci_gcc_root(config: &Config) -> PathBuf { +#[cfg(not(test))] +fn ci_gcc_root(config: &crate::Config) -> PathBuf { config.out.join(config.build).join("ci-gcc") } /// This retrieves the GCC sha we *want* to use, according to git history. -fn detect_gcc_sha(config: &Config, is_git: bool) -> String { +#[cfg(not(test))] +fn detect_gcc_sha(config: &crate::Config, is_git: bool) -> String { + use build_helper::git::get_closest_merge_commit; + let gcc_sha = if is_git { get_closest_merge_commit( Some(&config.src), From 436959e3f710d3161093bfa183e3c5deceff7ccf Mon Sep 17 00:00:00 2001 From: Aurelia Molzer <5550310+HeroicKatora@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:38:08 +0100 Subject: [PATCH 965/991] Add PeekMut::refresh This improves the useability of heaps for priority-based work queues. In certain scenarios, modifications on the most relevant or critical items are performed until a condition that determines the work items have been sufficiently addressed. The loop will repeatedly access the most critical item and put it back in a sorted position when it is complete. Crucially, due to the ordering invariant we know that all work was performed when the completed item remains the most critical. Getting this information from the heap position avoids a (potentially more costly) check on the item state itself. A customized `drop` with boolean result would avoid up to two more comparisons performed in both the last no-op refresh and Drop code but this occurs once in each execution of the above scenario whereas refresh occurs any number of times. Also note that the comparison overhead of Drop is only taken if the element is mutably inspected to determine the end condition, i.e. not when refresh itself is the break condition. --- .../alloc/src/collections/binary_heap/mod.rs | 82 ++++++++++++++++++- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 965fd63a5298..59e47bcd1183 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -359,6 +359,74 @@ impl DerefMut for PeekMut<'_, T, A> { } impl<'a, T: Ord, A: Allocator> PeekMut<'a, T, A> { + /// Sifts the current element to its new position. + /// + /// Afterwards refers to the new element. Returns if the element changed. + /// + /// ## Examples + /// + /// The condition can be used to upper bound all elements in the heap. When only few elements + /// are affected, the heap's sort ensures this is faster than a reconstruction from the raw + /// element list and requires no additional allocation. + /// + /// ``` + /// #![feature(binary_heap_peek_mut_refresh)] + /// use std::collections::BinaryHeap; + /// + /// let mut heap: BinaryHeap = (0..128).collect(); + /// let mut peek = heap.peek_mut().unwrap(); + /// + /// loop { + /// *peek = 99; + /// + /// if !peek.refresh() { + /// break; + /// } + /// } + /// + /// // Post condition, this is now an upper bound. + /// assert!(*peek < 100); + /// ``` + /// + /// When the element remains the maximum after modification, the peek remains unchanged: + /// + /// ``` + /// #![feature(binary_heap_peek_mut_refresh)] + /// use std::collections::BinaryHeap; + /// + /// let mut heap: BinaryHeap = [1, 2, 3].into(); + /// let mut peek = heap.peek_mut().unwrap(); + /// + /// assert_eq!(*peek, 3); + /// *peek = 42; + /// + /// // When we refresh, the peek is updated to the new maximum. + /// assert!(!peek.refresh(), "42 is even larger than 3"); + /// assert_eq!(*peek, 42); + /// ``` + #[unstable(feature = "binary_heap_peek_mut_refresh", issue = "138355")] + #[must_use = "is equivalent to dropping and getting a new PeekMut except for return information"] + pub fn refresh(&mut self) -> bool { + // The length of the underlying heap is unchanged by sifting down. The value stored for leak + // amplification thus remains accurate. We erase the leak amplification firstly because the + // operation is then equivalent to constructing a new PeekMut and secondly this avoids any + // future complication where original_len being non-empty would be interpreted as the heap + // having been leak amplified instead of checking the heap itself. + if let Some(original_len) = self.original_len.take() { + // SAFETY: This is how many elements were in the Vec at the time of + // the BinaryHeap::peek_mut call. + unsafe { self.heap.data.set_len(original_len.get()) }; + + // The length of the heap did not change by sifting, upholding our own invariants. + + // SAFETY: PeekMut is only instantiated for non-empty heaps. + (unsafe { self.heap.sift_down(0) }) != 0 + } else { + // The element was not modified. + false + } + } + /// Removes the peeked value from the heap and returns it. #[stable(feature = "binary_heap_peek_mut_pop", since = "1.18.0")] pub fn pop(mut this: PeekMut<'a, T, A>) -> T { @@ -670,6 +738,8 @@ impl BinaryHeap { /// # Safety /// /// The caller must guarantee that `pos < self.len()`. + /// + /// Returns the new position of the element. unsafe fn sift_up(&mut self, start: usize, pos: usize) -> usize { // Take out the value at `pos` and create a hole. // SAFETY: The caller guarantees that pos < self.len() @@ -696,10 +766,12 @@ impl BinaryHeap { /// Take an element at `pos` and move it down the heap, /// while its children are larger. /// + /// Returns the new position of the element. + /// /// # Safety /// /// The caller must guarantee that `pos < end <= self.len()`. - unsafe fn sift_down_range(&mut self, pos: usize, end: usize) { + unsafe fn sift_down_range(&mut self, pos: usize, end: usize) -> usize { // SAFETY: The caller guarantees that pos < end <= self.len(). let mut hole = unsafe { Hole::new(&mut self.data, pos) }; let mut child = 2 * hole.pos() + 1; @@ -719,7 +791,7 @@ impl BinaryHeap { // SAFETY: child is now either the old child or the old child+1 // We already proven that both are < self.len() and != hole.pos() if hole.element() >= unsafe { hole.get(child) } { - return; + return hole.pos(); } // SAFETY: same as above. @@ -734,16 +806,18 @@ impl BinaryHeap { // child == 2 * hole.pos() + 1 != hole.pos(). unsafe { hole.move_to(child) }; } + + hole.pos() } /// # Safety /// /// The caller must guarantee that `pos < self.len()`. - unsafe fn sift_down(&mut self, pos: usize) { + unsafe fn sift_down(&mut self, pos: usize) -> usize { let len = self.len(); // SAFETY: pos < len is guaranteed by the caller and // obviously len = self.len() <= self.len(). - unsafe { self.sift_down_range(pos, len) }; + unsafe { self.sift_down_range(pos, len) } } /// Take an element at `pos` and move it all the way down the heap, From 2f6aca820680c47a1a94dcfaa0644689ed4726c8 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 11 Mar 2025 16:08:38 +0100 Subject: [PATCH 966/991] change `TypeChecker` to a MIR visitor --- compiler/rustc_borrowck/src/type_check/mod.rs | 822 +++++++++--------- .../type-checking-test-4.stderr | 4 +- 2 files changed, 396 insertions(+), 430 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 9d5022f2bef4..1b03ccfc3695 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -174,7 +174,7 @@ pub(crate) fn type_check<'a, 'tcx>( let mut verifier = TypeVerifier { typeck: &mut typeck, promoted, last_span: body.span }; verifier.visit_body(body); - typeck.typeck_mir(); + typeck.visit_body(body); typeck.equate_inputs_and_outputs(&normalized_inputs_and_output); typeck.check_signature_annotation(); @@ -543,7 +543,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { self.visit_body(promoted_body); - self.typeck.typeck_mir(); + self.typeck.visit_body(promoted_body); self.typeck.body = parent_body; // Merge the outlives constraints back in, at the given location. @@ -732,6 +732,10 @@ impl Locations { } impl<'a, 'tcx> TypeChecker<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + fn body(&self) -> &Body<'tcx> { self.body } @@ -888,15 +892,38 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Locations::All(span), ); } +} - fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx +impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { + #[instrument(skip(self, body), level = "debug")] + fn visit_body(&mut self, body: &Body<'tcx>) { + debug_assert!(std::ptr::eq(self.body, body)); + self.last_span = body.span; + debug!(?body.span); + + for (local, local_decl) in body.local_decls.iter_enumerated() { + self.visit_local_decl(local, local_decl); + } + + for (block, block_data) in body.basic_blocks.iter_enumerated() { + let mut location = Location { block, statement_index: 0 }; + for stmt in &block_data.statements { + if !stmt.source_info.span.is_dummy() { + self.last_span = stmt.source_info.span; + } + self.visit_statement(stmt, location); + location.statement_index += 1; + } + + self.visit_terminator(block_data.terminator(), location); + self.check_iscleanup(block_data); + } } #[instrument(skip(self), level = "debug")] - fn check_stmt(&mut self, stmt: &Statement<'tcx>, location: Location) { + fn visit_statement(&mut self, stmt: &Statement<'tcx>, location: Location) { + self.super_statement(stmt, location); let tcx = self.tcx(); - debug!("stmt kind: {:?}", stmt.kind); match &stmt.kind { StatementKind::Assign(box (place, rv)) => { // Assignments to temporaries are not "interesting"; @@ -976,7 +1003,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - self.check_rvalue(rv, location); if !self.unsized_feature_enabled() { let trait_ref = ty::TraitRef::new( tcx, @@ -1011,14 +1037,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } } - StatementKind::Intrinsic(box kind) => match kind { - NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location), - NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!( - stmt.source_info.span, - "Unexpected NonDivergingIntrinsic::CopyNonOverlapping, should only appear after lowering_intrinsics", - ), - }, - StatementKind::FakeRead(..) + StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(..)) + | StatementKind::FakeRead(..) | StatementKind::StorageLive(..) | StatementKind::StorageDead(..) | StatementKind::Retag { .. } @@ -1027,14 +1047,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | StatementKind::PlaceMention(..) | StatementKind::BackwardIncompatibleDropHint { .. } | StatementKind::Nop => {} - StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { + StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(..)) + | StatementKind::Deinit(..) + | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } } } - #[instrument(skip(self, term_location), level = "debug")] - fn check_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location) { + #[instrument(skip(self), level = "debug")] + fn visit_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location) { + self.super_terminator(term, term_location); let tcx = self.tcx(); debug!("terminator kind: {:?}", term.kind); match &term.kind { @@ -1052,8 +1075,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } TerminatorKind::SwitchInt { discr, .. } => { - self.check_operand(discr, term_location); - let switch_ty = discr.ty(self.body, tcx); if !switch_ty.is_integral() && !switch_ty.is_char() && !switch_ty.is_bool() { span_mirbug!(self, term, "bad SwitchInt discr ty {:?}", switch_ty); @@ -1068,11 +1089,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { _ => unreachable!(), }; - self.check_operand(func, term_location); - for arg in args { - self.check_operand(&arg.node, term_location); - } - let func_ty = func.ty(self.body, tcx); debug!("func_ty.kind: {:?}", func_ty.kind()); @@ -1159,8 +1175,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_call_inputs(term, func, &sig, args, term_location, call_source); } TerminatorKind::Assert { cond, msg, .. } => { - self.check_operand(cond, term_location); - let cond_ty = cond.ty(self.body, tcx); if cond_ty != tcx.types.bool { span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty); @@ -1176,8 +1190,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } TerminatorKind::Yield { value, resume_arg, .. } => { - self.check_operand(value, term_location); - match self.body.yield_ty() { None => span_mirbug!(self, term, "yield in non-coroutine"), Some(ty) => { @@ -1225,240 +1237,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - fn check_call_dest( - &mut self, - term: &Terminator<'tcx>, - sig: &ty::FnSig<'tcx>, - destination: Place<'tcx>, - target: Option, - term_location: Location, - ) { - let tcx = self.tcx(); - match target { - Some(_) => { - let dest_ty = destination.ty(self.body, tcx).ty; - let dest_ty = self.normalize(dest_ty, term_location); - let category = match destination.as_local() { - Some(RETURN_PLACE) => { - if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) = - self.universal_regions.defining_ty - { - if tcx.is_static(def_id) { - ConstraintCategory::UseAsStatic - } else { - ConstraintCategory::UseAsConst - } - } else { - ConstraintCategory::Return(ReturnConstraint::Normal) - } - } - Some(l) if !self.body.local_decls[l].is_user_variable() => { - ConstraintCategory::Boring - } - // The return type of a call is interesting for diagnostics. - _ => ConstraintCategory::Assignment, - }; - - let locations = term_location.to_locations(); - - if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) { - span_mirbug!( - self, - term, - "call dest mismatch ({:?} <- {:?}): {:?}", - dest_ty, - sig.output(), - terr - ); - } - - // When `unsized_fn_params` and `unsized_locals` are both not enabled, - // this check is done at `check_local`. - if self.unsized_feature_enabled() { - let span = term.source_info.span; - self.ensure_place_sized(dest_ty, span); - } - } - None => { - // The signature in this call can reference region variables, - // so erase them before calling a query. - let output_ty = self.tcx().erase_regions(sig.output()); - if !output_ty.is_privately_uninhabited( - self.tcx(), - self.infcx.typing_env(self.infcx.param_env), - ) { - span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); - } - } - } - } - - #[instrument(level = "debug", skip(self, term, func, term_location, call_source))] - fn check_call_inputs( - &mut self, - term: &Terminator<'tcx>, - func: &Operand<'tcx>, - sig: &ty::FnSig<'tcx>, - args: &[Spanned>], - term_location: Location, - call_source: CallSource, - ) { - if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { - span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); - } - - let func_ty = func.ty(self.body, self.infcx.tcx); - if let ty::FnDef(def_id, _) = *func_ty.kind() { - // Some of the SIMD intrinsics are special: they need a particular argument to be a - // constant. (Eventually this should use const-generics, but those are not up for the - // task yet: https://github.com/rust-lang/rust/issues/85229.) - if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) = - self.tcx().intrinsic(def_id).map(|i| i.name) - { - let idx = match name { - sym::simd_shuffle => 2, - _ => 1, - }; - if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) { - self.tcx().dcx().emit_err(SimdIntrinsicArgConst { - span: term.source_info.span, - arg: idx + 1, - intrinsic: name.to_string(), - }); - } - } - } - debug!(?func_ty); - - for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { - let op_arg_ty = op_arg.node.ty(self.body, self.tcx()); - - let op_arg_ty = self.normalize(op_arg_ty, term_location); - let category = if call_source.from_hir_call() { - ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_regions(func_ty))) - } else { - ConstraintCategory::Boring - }; - if let Err(terr) = - self.sub_types(op_arg_ty, *fn_arg, term_location.to_locations(), category) - { - span_mirbug!( - self, - term, - "bad arg #{:?} ({:?} <- {:?}): {:?}", - n, - fn_arg, - op_arg_ty, - terr - ); - } - } - } - - fn check_iscleanup(&mut self, block_data: &BasicBlockData<'tcx>) { - let is_cleanup = block_data.is_cleanup; - self.last_span = block_data.terminator().source_info.span; - match block_data.terminator().kind { - TerminatorKind::Goto { target } => { - self.assert_iscleanup(block_data, target, is_cleanup) - } - TerminatorKind::SwitchInt { ref targets, .. } => { - for target in targets.all_targets() { - self.assert_iscleanup(block_data, *target, is_cleanup); - } - } - TerminatorKind::UnwindResume => { - if !is_cleanup { - span_mirbug!(self, block_data, "resume on non-cleanup block!") - } - } - TerminatorKind::UnwindTerminate(_) => { - if !is_cleanup { - span_mirbug!(self, block_data, "terminate on non-cleanup block!") - } - } - TerminatorKind::Return => { - if is_cleanup { - span_mirbug!(self, block_data, "return on cleanup block") - } - } - TerminatorKind::TailCall { .. } => { - if is_cleanup { - span_mirbug!(self, block_data, "tailcall on cleanup block") - } - } - TerminatorKind::CoroutineDrop { .. } => { - if is_cleanup { - span_mirbug!(self, block_data, "coroutine_drop in cleanup block") - } - } - TerminatorKind::Yield { resume, drop, .. } => { - if is_cleanup { - span_mirbug!(self, block_data, "yield in cleanup block") - } - self.assert_iscleanup(block_data, resume, is_cleanup); - if let Some(drop) = drop { - self.assert_iscleanup(block_data, drop, is_cleanup); - } - } - TerminatorKind::Unreachable => {} - TerminatorKind::Drop { target, unwind, .. } - | TerminatorKind::Assert { target, unwind, .. } => { - self.assert_iscleanup(block_data, target, is_cleanup); - self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); - } - TerminatorKind::Call { ref target, unwind, .. } => { - if let &Some(target) = target { - self.assert_iscleanup(block_data, target, is_cleanup); - } - self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); - } - TerminatorKind::FalseEdge { real_target, imaginary_target } => { - self.assert_iscleanup(block_data, real_target, is_cleanup); - self.assert_iscleanup(block_data, imaginary_target, is_cleanup); - } - TerminatorKind::FalseUnwind { real_target, unwind } => { - self.assert_iscleanup(block_data, real_target, is_cleanup); - self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); - } - TerminatorKind::InlineAsm { ref targets, unwind, .. } => { - for &target in targets { - self.assert_iscleanup(block_data, target, is_cleanup); - } - self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); - } - } - } - - fn assert_iscleanup(&mut self, ctxt: &dyn fmt::Debug, bb: BasicBlock, iscleanuppad: bool) { - if self.body[bb].is_cleanup != iscleanuppad { - span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad); - } - } - - fn assert_iscleanup_unwind( - &mut self, - ctxt: &dyn fmt::Debug, - unwind: UnwindAction, - is_cleanup: bool, - ) { - match unwind { - UnwindAction::Cleanup(unwind) => { - if is_cleanup { - span_mirbug!(self, ctxt, "unwind on cleanup block") - } - self.assert_iscleanup(ctxt, unwind, true); - } - UnwindAction::Continue => { - if is_cleanup { - span_mirbug!(self, ctxt, "unwind on cleanup block") - } - } - UnwindAction::Unreachable | UnwindAction::Terminate(_) => (), - } - } - - fn check_local(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { + fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { + self.super_local_decl(local, local_decl); match self.body.local_kind(local) { LocalKind::ReturnPointer | LocalKind::Arg => { // return values of normal functions are required to be @@ -1481,129 +1261,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) { - let tcx = self.tcx(); - - // Erase the regions from `ty` to get a global type. The - // `Sized` bound in no way depends on precise regions, so this - // shouldn't affect `is_sized`. - let erased_ty = tcx.erase_regions(ty); - // FIXME(#132279): Using `Ty::is_sized` causes us to incorrectly handle opaques here. - if !erased_ty.is_sized(tcx, self.infcx.typing_env(self.infcx.param_env)) { - // in current MIR construction, all non-control-flow rvalue - // expressions evaluate through `as_temp` or `into` a return - // slot or local, so to find all unsized rvalues it is enough - // to check all temps, return slots and locals. - if self.reported_errors.replace((ty, span)).is_none() { - // While this is located in `nll::typeck` this error is not - // an NLL error, it's a required check to prevent creation - // of unsized rvalues in a call expression. - self.tcx().dcx().emit_err(MoveUnsized { ty, span }); - } - } - } - - fn aggregate_field_ty( - &mut self, - ak: &AggregateKind<'tcx>, - field_index: FieldIdx, - location: Location, - ) -> Result, FieldAccessError> { - let tcx = self.tcx(); - - match *ak { - AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => { - let def = tcx.adt_def(adt_did); - let variant = &def.variant(variant_index); - let adj_field_index = active_field_index.unwrap_or(field_index); - if let Some(field) = variant.fields.get(adj_field_index) { - Ok(self.normalize(field.ty(tcx, args), location)) - } else { - Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) - } - } - AggregateKind::Closure(_, args) => { - match args.as_closure().upvar_tys().get(field_index.as_usize()) { - Some(ty) => Ok(*ty), - None => Err(FieldAccessError::OutOfRange { - field_count: args.as_closure().upvar_tys().len(), - }), - } - } - AggregateKind::Coroutine(_, args) => { - // It doesn't make sense to look at a field beyond the prefix; - // these require a variant index, and are not initialized in - // aggregate rvalues. - match args.as_coroutine().prefix_tys().get(field_index.as_usize()) { - Some(ty) => Ok(*ty), - None => Err(FieldAccessError::OutOfRange { - field_count: args.as_coroutine().prefix_tys().len(), - }), - } - } - AggregateKind::CoroutineClosure(_, args) => { - match args.as_coroutine_closure().upvar_tys().get(field_index.as_usize()) { - Some(ty) => Ok(*ty), - None => Err(FieldAccessError::OutOfRange { - field_count: args.as_coroutine_closure().upvar_tys().len(), - }), - } - } - AggregateKind::Array(ty) => Ok(ty), - AggregateKind::Tuple | AggregateKind::RawPtr(..) => { - unreachable!("This should have been covered in check_rvalues"); - } - } - } - - fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) { - debug!(?op, ?location, "check_operand"); - - if let Operand::Constant(constant) = op { - let maybe_uneval = match constant.const_ { - Const::Val(..) | Const::Ty(_, _) => None, - Const::Unevaluated(uv, _) => Some(uv), - }; - - if let Some(uv) = maybe_uneval { - if uv.promoted.is_none() { - let tcx = self.tcx(); - let def_id = uv.def; - if tcx.def_kind(def_id) == DefKind::InlineConst { - let def_id = def_id.expect_local(); - let predicates = self.prove_closure_bounds( - tcx, - def_id, - uv.args, - location.to_locations(), - ); - self.normalize_and_prove_instantiated_predicates( - def_id.to_def_id(), - predicates, - location.to_locations(), - ); - } - } - } - } - } - #[instrument(skip(self), level = "debug")] - fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { + fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { + self.super_rvalue(rvalue, location); let tcx = self.tcx(); let span = self.body.source_info(location).span; - match rvalue { - Rvalue::Aggregate(ak, ops) => { - for op in ops { - self.check_operand(op, location); - } - self.check_aggregate_rvalue(rvalue, ak, ops, location) - } + Rvalue::Aggregate(ak, ops) => self.check_aggregate_rvalue(rvalue, ak, ops, location), Rvalue::Repeat(operand, len) => { - self.check_operand(operand, location); - let array_ty = rvalue.ty(self.body.local_decls(), tcx); self.prove_predicate( ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(array_ty.into())), @@ -1656,9 +1322,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &Rvalue::NullaryOp(NullOp::ContractChecks, _) => {} &Rvalue::NullaryOp(NullOp::UbChecks, _) => {} - Rvalue::ShallowInitBox(operand, ty) => { - self.check_operand(operand, location); - + Rvalue::ShallowInitBox(_operand, ty) => { let trait_ref = ty::TraitRef::new( tcx, tcx.require_lang_item(LangItem::Sized, Some(span)), @@ -1673,8 +1337,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } Rvalue::Cast(cast_kind, op, ty) => { - self.check_operand(op, location); - match *cast_kind { CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, coercion_source) => { let is_implicit_coercion = coercion_source == CoercionSource::Implicit; @@ -2191,9 +1853,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge, box (left, right), ) => { - self.check_operand(left, location); - self.check_operand(right, location); - let ty_left = left.ty(self.body, tcx); match ty_left.kind() { // Types with regions are comparable if they have a common super-type. @@ -2242,23 +1901,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - Rvalue::Use(operand) | Rvalue::UnaryOp(_, operand) => { - self.check_operand(operand, location); - } - Rvalue::CopyForDeref(place) => { - let op = &Operand::Copy(*place); - self.check_operand(op, location); - } - - Rvalue::BinaryOp(_, box (left, right)) => { - self.check_operand(left, location); - self.check_operand(right, location); - } - Rvalue::WrapUnsafeBinder(op, ty) => { - self.check_operand(op, location); let operand_ty = op.ty(self.body, self.tcx()); - let ty::UnsafeBinder(binder_ty) = *ty.kind() else { unreachable!(); }; @@ -2276,7 +1920,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .unwrap(); } - Rvalue::RawPtr(..) + Rvalue::Use(_) + | Rvalue::UnaryOp(_, _) + | Rvalue::CopyForDeref(_) + | Rvalue::BinaryOp(..) + | Rvalue::RawPtr(..) | Rvalue::ThreadLocalRef(..) | Rvalue::Len(..) | Rvalue::Discriminant(..) @@ -2284,6 +1932,348 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } + #[instrument(level = "debug", skip(self))] + fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { + self.super_operand(op, location); + if let Operand::Constant(constant) = op { + let maybe_uneval = match constant.const_ { + Const::Val(..) | Const::Ty(_, _) => None, + Const::Unevaluated(uv, _) => Some(uv), + }; + + if let Some(uv) = maybe_uneval { + if uv.promoted.is_none() { + let tcx = self.tcx(); + let def_id = uv.def; + if tcx.def_kind(def_id) == DefKind::InlineConst { + let def_id = def_id.expect_local(); + let predicates = self.prove_closure_bounds( + tcx, + def_id, + uv.args, + location.to_locations(), + ); + self.normalize_and_prove_instantiated_predicates( + def_id.to_def_id(), + predicates, + location.to_locations(), + ); + } + } + } + } + } +} + +impl<'a, 'tcx> TypeChecker<'a, 'tcx> { + fn check_call_dest( + &mut self, + term: &Terminator<'tcx>, + sig: &ty::FnSig<'tcx>, + destination: Place<'tcx>, + target: Option, + term_location: Location, + ) { + let tcx = self.tcx(); + match target { + Some(_) => { + let dest_ty = destination.ty(self.body, tcx).ty; + let dest_ty = self.normalize(dest_ty, term_location); + let category = match destination.as_local() { + Some(RETURN_PLACE) => { + if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) = + self.universal_regions.defining_ty + { + if tcx.is_static(def_id) { + ConstraintCategory::UseAsStatic + } else { + ConstraintCategory::UseAsConst + } + } else { + ConstraintCategory::Return(ReturnConstraint::Normal) + } + } + Some(l) if !self.body.local_decls[l].is_user_variable() => { + ConstraintCategory::Boring + } + // The return type of a call is interesting for diagnostics. + _ => ConstraintCategory::Assignment, + }; + + let locations = term_location.to_locations(); + + if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) { + span_mirbug!( + self, + term, + "call dest mismatch ({:?} <- {:?}): {:?}", + dest_ty, + sig.output(), + terr + ); + } + + // When `unsized_fn_params` and `unsized_locals` are both not enabled, + // this check is done at `check_local`. + if self.unsized_feature_enabled() { + let span = term.source_info.span; + self.ensure_place_sized(dest_ty, span); + } + } + None => { + // The signature in this call can reference region variables, + // so erase them before calling a query. + let output_ty = self.tcx().erase_regions(sig.output()); + if !output_ty.is_privately_uninhabited( + self.tcx(), + self.infcx.typing_env(self.infcx.param_env), + ) { + span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); + } + } + } + } + + #[instrument(level = "debug", skip(self, term, func, term_location, call_source))] + fn check_call_inputs( + &mut self, + term: &Terminator<'tcx>, + func: &Operand<'tcx>, + sig: &ty::FnSig<'tcx>, + args: &[Spanned>], + term_location: Location, + call_source: CallSource, + ) { + if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { + span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); + } + + let func_ty = func.ty(self.body, self.infcx.tcx); + if let ty::FnDef(def_id, _) = *func_ty.kind() { + // Some of the SIMD intrinsics are special: they need a particular argument to be a + // constant. (Eventually this should use const-generics, but those are not up for the + // task yet: https://github.com/rust-lang/rust/issues/85229.) + if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) = + self.tcx().intrinsic(def_id).map(|i| i.name) + { + let idx = match name { + sym::simd_shuffle => 2, + _ => 1, + }; + if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) { + self.tcx().dcx().emit_err(SimdIntrinsicArgConst { + span: term.source_info.span, + arg: idx + 1, + intrinsic: name.to_string(), + }); + } + } + } + debug!(?func_ty); + + for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { + let op_arg_ty = op_arg.node.ty(self.body, self.tcx()); + + let op_arg_ty = self.normalize(op_arg_ty, term_location); + let category = if call_source.from_hir_call() { + ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_regions(func_ty))) + } else { + ConstraintCategory::Boring + }; + if let Err(terr) = + self.sub_types(op_arg_ty, *fn_arg, term_location.to_locations(), category) + { + span_mirbug!( + self, + term, + "bad arg #{:?} ({:?} <- {:?}): {:?}", + n, + fn_arg, + op_arg_ty, + terr + ); + } + } + } + + fn check_iscleanup(&mut self, block_data: &BasicBlockData<'tcx>) { + let is_cleanup = block_data.is_cleanup; + self.last_span = block_data.terminator().source_info.span; + match block_data.terminator().kind { + TerminatorKind::Goto { target } => { + self.assert_iscleanup(block_data, target, is_cleanup) + } + TerminatorKind::SwitchInt { ref targets, .. } => { + for target in targets.all_targets() { + self.assert_iscleanup(block_data, *target, is_cleanup); + } + } + TerminatorKind::UnwindResume => { + if !is_cleanup { + span_mirbug!(self, block_data, "resume on non-cleanup block!") + } + } + TerminatorKind::UnwindTerminate(_) => { + if !is_cleanup { + span_mirbug!(self, block_data, "terminate on non-cleanup block!") + } + } + TerminatorKind::Return => { + if is_cleanup { + span_mirbug!(self, block_data, "return on cleanup block") + } + } + TerminatorKind::TailCall { .. } => { + if is_cleanup { + span_mirbug!(self, block_data, "tailcall on cleanup block") + } + } + TerminatorKind::CoroutineDrop { .. } => { + if is_cleanup { + span_mirbug!(self, block_data, "coroutine_drop in cleanup block") + } + } + TerminatorKind::Yield { resume, drop, .. } => { + if is_cleanup { + span_mirbug!(self, block_data, "yield in cleanup block") + } + self.assert_iscleanup(block_data, resume, is_cleanup); + if let Some(drop) = drop { + self.assert_iscleanup(block_data, drop, is_cleanup); + } + } + TerminatorKind::Unreachable => {} + TerminatorKind::Drop { target, unwind, .. } + | TerminatorKind::Assert { target, unwind, .. } => { + self.assert_iscleanup(block_data, target, is_cleanup); + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); + } + TerminatorKind::Call { ref target, unwind, .. } => { + if let &Some(target) = target { + self.assert_iscleanup(block_data, target, is_cleanup); + } + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); + } + TerminatorKind::FalseEdge { real_target, imaginary_target } => { + self.assert_iscleanup(block_data, real_target, is_cleanup); + self.assert_iscleanup(block_data, imaginary_target, is_cleanup); + } + TerminatorKind::FalseUnwind { real_target, unwind } => { + self.assert_iscleanup(block_data, real_target, is_cleanup); + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); + } + TerminatorKind::InlineAsm { ref targets, unwind, .. } => { + for &target in targets { + self.assert_iscleanup(block_data, target, is_cleanup); + } + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); + } + } + } + + fn assert_iscleanup(&mut self, ctxt: &dyn fmt::Debug, bb: BasicBlock, iscleanuppad: bool) { + if self.body[bb].is_cleanup != iscleanuppad { + span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad); + } + } + + fn assert_iscleanup_unwind( + &mut self, + ctxt: &dyn fmt::Debug, + unwind: UnwindAction, + is_cleanup: bool, + ) { + match unwind { + UnwindAction::Cleanup(unwind) => { + if is_cleanup { + span_mirbug!(self, ctxt, "unwind on cleanup block") + } + self.assert_iscleanup(ctxt, unwind, true); + } + UnwindAction::Continue => { + if is_cleanup { + span_mirbug!(self, ctxt, "unwind on cleanup block") + } + } + UnwindAction::Unreachable | UnwindAction::Terminate(_) => (), + } + } + + fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) { + let tcx = self.tcx(); + + // Erase the regions from `ty` to get a global type. The + // `Sized` bound in no way depends on precise regions, so this + // shouldn't affect `is_sized`. + let erased_ty = tcx.erase_regions(ty); + // FIXME(#132279): Using `Ty::is_sized` causes us to incorrectly handle opaques here. + if !erased_ty.is_sized(tcx, self.infcx.typing_env(self.infcx.param_env)) { + // in current MIR construction, all non-control-flow rvalue + // expressions evaluate through `as_temp` or `into` a return + // slot or local, so to find all unsized rvalues it is enough + // to check all temps, return slots and locals. + if self.reported_errors.replace((ty, span)).is_none() { + // While this is located in `nll::typeck` this error is not + // an NLL error, it's a required check to prevent creation + // of unsized rvalues in a call expression. + self.tcx().dcx().emit_err(MoveUnsized { ty, span }); + } + } + } + + fn aggregate_field_ty( + &mut self, + ak: &AggregateKind<'tcx>, + field_index: FieldIdx, + location: Location, + ) -> Result, FieldAccessError> { + let tcx = self.tcx(); + + match *ak { + AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => { + let def = tcx.adt_def(adt_did); + let variant = &def.variant(variant_index); + let adj_field_index = active_field_index.unwrap_or(field_index); + if let Some(field) = variant.fields.get(adj_field_index) { + Ok(self.normalize(field.ty(tcx, args), location)) + } else { + Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) + } + } + AggregateKind::Closure(_, args) => { + match args.as_closure().upvar_tys().get(field_index.as_usize()) { + Some(ty) => Ok(*ty), + None => Err(FieldAccessError::OutOfRange { + field_count: args.as_closure().upvar_tys().len(), + }), + } + } + AggregateKind::Coroutine(_, args) => { + // It doesn't make sense to look at a field beyond the prefix; + // these require a variant index, and are not initialized in + // aggregate rvalues. + match args.as_coroutine().prefix_tys().get(field_index.as_usize()) { + Some(ty) => Ok(*ty), + None => Err(FieldAccessError::OutOfRange { + field_count: args.as_coroutine().prefix_tys().len(), + }), + } + } + AggregateKind::CoroutineClosure(_, args) => { + match args.as_coroutine_closure().upvar_tys().get(field_index.as_usize()) { + Some(ty) => Ok(*ty), + None => Err(FieldAccessError::OutOfRange { + field_count: args.as_coroutine_closure().upvar_tys().len(), + }), + } + } + AggregateKind::Array(ty) => Ok(ty), + AggregateKind::Tuple | AggregateKind::RawPtr(..) => { + unreachable!("This should have been covered in check_rvalues"); + } + } + } + /// If this rvalue supports a user-given type annotation, then /// extract and return it. This represents the final type of the /// rvalue and will be unified with the inferred type. @@ -2623,30 +2613,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { tcx.predicates_of(def_id).instantiate(tcx, args) } - - #[instrument(skip(self), level = "debug")] - fn typeck_mir(&mut self) { - self.last_span = self.body.span; - debug!(?self.body.span); - - for (local, local_decl) in self.body.local_decls.iter_enumerated() { - self.check_local(local, local_decl); - } - - for (block, block_data) in self.body.basic_blocks.iter_enumerated() { - let mut location = Location { block, statement_index: 0 }; - for stmt in &block_data.statements { - if !stmt.source_info.span.is_dummy() { - self.last_span = stmt.source_info.span; - } - self.check_stmt(stmt, location); - location.statement_index += 1; - } - - self.check_terminator(block_data.terminator(), location); - self.check_iscleanup(block_data); - } - } } trait NormalizeLocation: fmt::Debug + Copy { diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr index 55a5e4cd4971..0fca91fd2f2f 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -7,12 +7,12 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:22:18 + --> $DIR/type-checking-test-4.rs:22:13 | LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'a, 'static>; // Error - | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static` error: lifetime may not live long enough --> $DIR/type-checking-test-4.rs:28:5 From 50f5f607b4e34efb0e65583ce27ea6a95c31b049 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 11 Mar 2025 16:18:06 +0100 Subject: [PATCH 967/991] unify `last_span` computation --- compiler/rustc_borrowck/src/type_check/mod.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 1b03ccfc3695..852d71e4d0d8 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -497,9 +497,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { for (block, block_data) in body.basic_blocks.iter_enumerated() { let mut location = Location { block, statement_index: 0 }; for stmt in &block_data.statements { - if !stmt.source_info.span.is_dummy() { - self.last_span = stmt.source_info.span; - } self.visit_statement(stmt, location); location.statement_index += 1; } @@ -895,11 +892,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { + fn visit_span(&mut self, span: Span) { + if !span.is_dummy() { + debug!(?span); + self.last_span = span; + } + } + #[instrument(skip(self, body), level = "debug")] fn visit_body(&mut self, body: &Body<'tcx>) { debug_assert!(std::ptr::eq(self.body, body)); - self.last_span = body.span; - debug!(?body.span); for (local, local_decl) in body.local_decls.iter_enumerated() { self.visit_local_decl(local, local_decl); @@ -908,9 +910,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { for (block, block_data) in body.basic_blocks.iter_enumerated() { let mut location = Location { block, statement_index: 0 }; for stmt in &block_data.statements { - if !stmt.source_info.span.is_dummy() { - self.last_span = stmt.source_info.span; - } self.visit_statement(stmt, location); location.statement_index += 1; } @@ -2098,7 +2097,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn check_iscleanup(&mut self, block_data: &BasicBlockData<'tcx>) { let is_cleanup = block_data.is_cleanup; - self.last_span = block_data.terminator().source_info.span; match block_data.terminator().kind { TerminatorKind::Goto { target } => { self.assert_iscleanup(block_data, target, is_cleanup) From a5eb387d61c6de52372831fb60bd84858e1a12c4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 11 Mar 2025 16:34:15 +0100 Subject: [PATCH 968/991] merge `TypeChecker` and `TypeVerifier` --- compiler/rustc_borrowck/src/type_check/mod.rs | 683 ++++++++---------- tests/ui/consts/const-unsized.stderr | 12 +- 2 files changed, 311 insertions(+), 384 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 852d71e4d0d8..d2eb7a52f78a 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -156,6 +156,7 @@ pub(crate) fn type_check<'a, 'tcx>( infcx, last_span: body.span, body, + promoted, user_type_annotations: &body.user_type_annotations, region_bound_pairs, known_type_outlives_obligations, @@ -170,10 +171,6 @@ pub(crate) fn type_check<'a, 'tcx>( }; typeck.check_user_type_annotations(); - - let mut verifier = TypeVerifier { typeck: &mut typeck, promoted, last_span: body.span }; - verifier.visit_body(body); - typeck.visit_body(body); typeck.equate_inputs_and_outputs(&normalized_inputs_and_output); typeck.check_signature_annotation(); @@ -212,367 +209,6 @@ enum FieldAccessError { OutOfRange { field_count: usize }, } -/// Verifies that MIR types are sane. -/// -/// FIXME: This should be merged with the actual `TypeChecker`. -struct TypeVerifier<'a, 'b, 'tcx> { - typeck: &'a mut TypeChecker<'b, 'tcx>, - promoted: &'b IndexSlice>, - last_span: Span, -} - -impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { - fn visit_span(&mut self, span: Span) { - if !span.is_dummy() { - self.last_span = span; - } - } - - fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { - self.super_place(place, context, location); - let tcx = self.tcx(); - let place_ty = place.ty(self.body(), tcx); - if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), - [place_ty.ty], - ); - - // To have a `Copy` operand, the type `T` of the - // value must be `Copy`. Note that we prove that `T: Copy`, - // rather than using the `is_copy_modulo_regions` - // test. This is important because - // `is_copy_modulo_regions` ignores the resulting region - // obligations and assumes they pass. This can result in - // bounds from `Copy` impls being unsoundly ignored (e.g., - // #29149). Note that we decide to use `Copy` before knowing - // whether the bounds fully apply: in effect, the rule is - // that if a value of some type could implement `Copy`, then - // it must. - self.typeck.prove_trait_ref( - trait_ref, - location.to_locations(), - ConstraintCategory::CopyBound, - ); - } - } - - fn visit_projection_elem( - &mut self, - place: PlaceRef<'tcx>, - elem: PlaceElem<'tcx>, - context: PlaceContext, - location: Location, - ) { - let tcx = self.tcx(); - let base_ty = place.ty(self.body(), tcx); - match elem { - // All these projections don't add any constraints, so there's nothing to - // do here. We check their invariants in the MIR validator after all. - ProjectionElem::Deref - | ProjectionElem::Index(_) - | ProjectionElem::ConstantIndex { .. } - | ProjectionElem::Subslice { .. } - | ProjectionElem::Downcast(..) => {} - ProjectionElem::Field(field, fty) => { - let fty = self.typeck.normalize(fty, location); - let ty = base_ty.field_ty(tcx, field); - let ty = self.typeck.normalize(ty, location); - debug!(?fty, ?ty); - - if let Err(terr) = self.typeck.relate_types( - ty, - context.ambient_variance(), - fty, - location.to_locations(), - ConstraintCategory::Boring, - ) { - span_mirbug!(self, place, "bad field access ({:?}: {:?}): {:?}", ty, fty, terr); - } - } - ProjectionElem::OpaqueCast(ty) => { - let ty = self.typeck.normalize(ty, location); - self.typeck - .relate_types( - ty, - context.ambient_variance(), - base_ty.ty, - location.to_locations(), - ConstraintCategory::TypeAnnotation(AnnotationSource::OpaqueCast), - ) - .unwrap(); - } - ProjectionElem::UnwrapUnsafeBinder(ty) => { - let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else { - unreachable!(); - }; - let found_ty = self.typeck.infcx.instantiate_binder_with_fresh_vars( - self.body().source_info(location).span, - BoundRegionConversionTime::HigherRankedType, - binder_ty.into(), - ); - self.typeck - .relate_types( - ty, - context.ambient_variance(), - found_ty, - location.to_locations(), - ConstraintCategory::Boring, - ) - .unwrap(); - } - ProjectionElem::Subtype(_) => { - bug!("ProjectionElem::Subtype shouldn't exist in borrowck") - } - } - } - - #[instrument(level = "debug", skip(self))] - fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) { - self.super_const_operand(constant, location); - let ty = constant.const_.ty(); - - self.typeck.infcx.tcx.for_each_free_region(&ty, |live_region| { - let live_region_vid = self.typeck.universal_regions.to_region_vid(live_region); - self.typeck.constraints.liveness_constraints.add_location(live_region_vid, location); - }); - - let locations = location.to_locations(); - if let Some(annotation_index) = constant.user_ty { - if let Err(terr) = self.typeck.relate_type_and_user_type( - constant.const_.ty(), - ty::Invariant, - &UserTypeProjection { base: annotation_index, projs: vec![] }, - locations, - ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg), - ) { - let annotation = &self.typeck.user_type_annotations[annotation_index]; - span_mirbug!( - self, - constant, - "bad constant user type {:?} vs {:?}: {:?}", - annotation, - constant.const_.ty(), - terr, - ); - } - } else { - let tcx = self.tcx(); - let maybe_uneval = match constant.const_ { - Const::Ty(_, ct) => match ct.kind() { - ty::ConstKind::Unevaluated(uv) => { - Some(UnevaluatedConst { def: uv.def, args: uv.args, promoted: None }) - } - _ => None, - }, - Const::Unevaluated(uv, _) => Some(uv), - _ => None, - }; - - if let Some(uv) = maybe_uneval { - if let Some(promoted) = uv.promoted { - let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, - promoted: &Body<'tcx>, - ty, - san_ty| { - if let Err(terr) = verifier.typeck.eq_types( - ty, - san_ty, - locations, - ConstraintCategory::Boring, - ) { - span_mirbug!( - verifier, - promoted, - "bad promoted type ({:?}: {:?}): {:?}", - ty, - san_ty, - terr - ); - }; - }; - - let promoted_body = &self.promoted[promoted]; - self.verify_promoted(promoted_body, location); - - let promoted_ty = promoted_body.return_ty(); - check_err(self, promoted_body, ty, promoted_ty); - } else { - self.typeck.ascribe_user_type( - constant.const_.ty(), - ty::UserType::new(ty::UserTypeKind::TypeOf( - uv.def, - UserArgs { args: uv.args, user_self_ty: None }, - )), - locations.span(self.typeck.body), - ); - } - } else if let Some(static_def_id) = constant.check_static_ptr(tcx) { - let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity(); - let normalized_ty = self.typeck.normalize(unnormalized_ty, locations); - let literal_ty = constant.const_.ty().builtin_deref(true).unwrap(); - - if let Err(terr) = self.typeck.eq_types( - literal_ty, - normalized_ty, - locations, - ConstraintCategory::Boring, - ) { - span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr); - } - } - - if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() { - let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args); - self.typeck.normalize_and_prove_instantiated_predicates( - def_id, - instantiated_predicates, - locations, - ); - - assert!(!matches!( - tcx.impl_of_method(def_id).map(|imp| tcx.def_kind(imp)), - Some(DefKind::Impl { of_trait: true }) - )); - self.typeck.prove_predicates( - args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())), - locations, - ConstraintCategory::Boring, - ); - } - } - } - - fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { - self.super_local_decl(local, local_decl); - - for user_ty in - local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections) - { - let span = self.typeck.user_type_annotations[user_ty.base].span; - - let ty = if local_decl.is_nonref_binding() { - local_decl.ty - } else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() { - // If we have a binding of the form `let ref x: T = ..` - // then remove the outermost reference so we can check the - // type annotation for the remaining type. - rty - } else { - bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty); - }; - - if let Err(terr) = self.typeck.relate_type_and_user_type( - ty, - ty::Invariant, - user_ty, - Locations::All(span), - ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration), - ) { - span_mirbug!( - self, - local, - "bad user type on variable {:?}: {:?} != {:?} ({:?})", - local, - local_decl.ty, - local_decl.user_ty, - terr, - ); - } - } - } - - #[instrument(level = "debug", skip(self))] - fn visit_body(&mut self, body: &Body<'tcx>) { - debug_assert!(std::ptr::eq(self.typeck.body, body)); - // We intentionally do not recurse into `body.required_consts` or - // `body.mentioned_items` here as the MIR at this phase should still - // refer to all items and we don't want to check them multiple times. - - for (local, local_decl) in body.local_decls.iter_enumerated() { - self.visit_local_decl(local, local_decl); - } - - for (block, block_data) in body.basic_blocks.iter_enumerated() { - let mut location = Location { block, statement_index: 0 }; - for stmt in &block_data.statements { - self.visit_statement(stmt, location); - location.statement_index += 1; - } - - self.visit_terminator(block_data.terminator(), location); - } - } -} - -impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { - fn body(&self) -> &Body<'tcx> { - self.typeck.body - } - - fn tcx(&self) -> TyCtxt<'tcx> { - self.typeck.infcx.tcx - } - - fn verify_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Location) { - // Determine the constraints from the promoted MIR by running the type - // checker on the promoted MIR, then transfer the constraints back to - // the main MIR, changing the locations to the provided location. - - let parent_body = mem::replace(&mut self.typeck.body, promoted_body); - - // Use new sets of constraints and closure bounds so that we can - // modify their locations. - let polonius_facts = &mut None; - let mut constraints = Default::default(); - let mut liveness_constraints = - LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body))); - // Don't try to add borrow_region facts for the promoted MIR - - let mut swap_constraints = |this: &mut Self| { - mem::swap(this.typeck.polonius_facts, polonius_facts); - mem::swap(&mut this.typeck.constraints.outlives_constraints, &mut constraints); - mem::swap(&mut this.typeck.constraints.liveness_constraints, &mut liveness_constraints); - }; - - swap_constraints(self); - - self.visit_body(promoted_body); - - self.typeck.visit_body(promoted_body); - - self.typeck.body = parent_body; - // Merge the outlives constraints back in, at the given location. - swap_constraints(self); - - let locations = location.to_locations(); - for constraint in constraints.outlives().iter() { - let mut constraint = *constraint; - constraint.locations = locations; - if let ConstraintCategory::Return(_) - | ConstraintCategory::UseAsConst - | ConstraintCategory::UseAsStatic = constraint.category - { - // "Returning" from a promoted is an assignment to a - // temporary from the user's point of view. - constraint.category = ConstraintCategory::Boring; - } - self.typeck.constraints.outlives_constraints.push(constraint) - } - // If the region is live at least one location in the promoted MIR, - // then add a liveness constraint to the main MIR for this region - // at the location provided as an argument to this method - // - // add_location doesn't care about ordering so not a problem for the live regions to be - // unordered. - #[allow(rustc::potential_query_instability)] - for region in liveness_constraints.live_regions_unordered() { - self.typeck.constraints.liveness_constraints.add_location(region, location); - } - } -} - /// The MIR type checker. Visits the MIR and enforces all the /// constraints needed for it to be valid and well-typed. Along the /// way, it accrues region constraints -- these can later be used by @@ -581,6 +217,9 @@ struct TypeChecker<'a, 'tcx> { infcx: &'a BorrowckInferCtxt<'tcx>, last_span: Span, body: &'a Body<'tcx>, + /// The bodies of all promoteds. As promoteds have a completely separate CFG + /// recursing into them may corrupt your data structures if you're not careful. + promoted: &'a IndexSlice>, /// User type annotations are shared between the main MIR and the MIR of /// all of the promoted items. user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, @@ -860,6 +499,62 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Ok(()) } + fn check_promoted(&mut self, promoted_body: &'a Body<'tcx>, location: Location) { + // Determine the constraints from the promoted MIR by running the type + // checker on the promoted MIR, then transfer the constraints back to + // the main MIR, changing the locations to the provided location. + + let parent_body = mem::replace(&mut self.body, promoted_body); + + // Use new sets of constraints and closure bounds so that we can + // modify their locations. + let polonius_facts = &mut None; + let mut constraints = Default::default(); + let mut liveness_constraints = + LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body))); + + // Don't try to add borrow_region facts for the promoted MIR as they refer + // to the wrong locations. + let mut swap_constraints = |this: &mut Self| { + mem::swap(this.polonius_facts, polonius_facts); + mem::swap(&mut this.constraints.outlives_constraints, &mut constraints); + mem::swap(&mut this.constraints.liveness_constraints, &mut liveness_constraints); + }; + + swap_constraints(self); + + self.visit_body(promoted_body); + + self.body = parent_body; + + // Merge the outlives constraints back in, at the given location. + swap_constraints(self); + let locations = location.to_locations(); + for constraint in constraints.outlives().iter() { + let mut constraint = *constraint; + constraint.locations = locations; + if let ConstraintCategory::Return(_) + | ConstraintCategory::UseAsConst + | ConstraintCategory::UseAsStatic = constraint.category + { + // "Returning" from a promoted is an assignment to a + // temporary from the user's point of view. + constraint.category = ConstraintCategory::Boring; + } + self.constraints.outlives_constraints.push(constraint) + } + // If the region is live at least one location in the promoted MIR, + // then add a liveness constraint to the main MIR for this region + // at the location provided as an argument to this method + // + // add_location doesn't care about ordering so not a problem for the live regions to be + // unordered. + #[allow(rustc::potential_query_instability)] + for region in liveness_constraints.live_regions_unordered() { + self.constraints.liveness_constraints.add_location(region, location); + } + } + fn check_inline_const( &mut self, inferred_ty: Ty<'tcx>, @@ -1238,25 +933,61 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { self.super_local_decl(local, local_decl); - match self.body.local_kind(local) { - LocalKind::ReturnPointer | LocalKind::Arg => { - // return values of normal functions are required to be - // sized by typeck, but return values of ADT constructors are - // not because we don't include a `Self: Sized` bounds on them. - // - // Unbound parts of arguments were never required to be Sized - // - maybe we should make that a warning. - return; + + for user_ty in + local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections) + { + let span = self.user_type_annotations[user_ty.base].span; + + let ty = if local_decl.is_nonref_binding() { + local_decl.ty + } else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() { + // If we have a binding of the form `let ref x: T = ..` + // then remove the outermost reference so we can check the + // type annotation for the remaining type. + rty + } else { + bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty); + }; + + if let Err(terr) = self.relate_type_and_user_type( + ty, + ty::Invariant, + user_ty, + Locations::All(span), + ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration), + ) { + span_mirbug!( + self, + local, + "bad user type on variable {:?}: {:?} != {:?} ({:?})", + local, + local_decl.ty, + local_decl.user_ty, + terr, + ); } - LocalKind::Temp => {} } // When `unsized_fn_params` or `unsized_locals` is enabled, only function calls // and nullary ops are checked in `check_call_dest`. if !self.unsized_feature_enabled() { - let span = local_decl.source_info.span; - let ty = local_decl.ty; - self.ensure_place_sized(ty, span); + match self.body.local_kind(local) { + LocalKind::ReturnPointer | LocalKind::Arg => { + // return values of normal functions are required to be + // sized by typeck, but return values of ADT constructors are + // not because we don't include a `Self: Sized` bounds on them. + // + // Unbound parts of arguments were never required to be Sized + // - maybe we should make that a warning. + return; + } + LocalKind::Temp => { + let span = local_decl.source_info.span; + let ty = local_decl.ty; + self.ensure_place_sized(ty, span); + } + } } } @@ -1962,6 +1693,202 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } + + #[instrument(level = "debug", skip(self))] + fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) { + self.super_const_operand(constant, location); + let ty = constant.const_.ty(); + + self.infcx.tcx.for_each_free_region(&ty, |live_region| { + let live_region_vid = self.universal_regions.to_region_vid(live_region); + self.constraints.liveness_constraints.add_location(live_region_vid, location); + }); + + let locations = location.to_locations(); + if let Some(annotation_index) = constant.user_ty { + if let Err(terr) = self.relate_type_and_user_type( + constant.const_.ty(), + ty::Invariant, + &UserTypeProjection { base: annotation_index, projs: vec![] }, + locations, + ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg), + ) { + let annotation = &self.user_type_annotations[annotation_index]; + span_mirbug!( + self, + constant, + "bad constant user type {:?} vs {:?}: {:?}", + annotation, + constant.const_.ty(), + terr, + ); + } + } else { + let tcx = self.tcx(); + let maybe_uneval = match constant.const_ { + Const::Ty(_, ct) => match ct.kind() { + ty::ConstKind::Unevaluated(uv) => { + Some(UnevaluatedConst { def: uv.def, args: uv.args, promoted: None }) + } + _ => None, + }, + Const::Unevaluated(uv, _) => Some(uv), + _ => None, + }; + + if let Some(uv) = maybe_uneval { + if let Some(promoted) = uv.promoted { + let promoted_body = &self.promoted[promoted]; + self.check_promoted(promoted_body, location); + let promoted_ty = promoted_body.return_ty(); + if let Err(terr) = + self.eq_types(ty, promoted_ty, locations, ConstraintCategory::Boring) + { + span_mirbug!( + self, + promoted, + "bad promoted type ({:?}: {:?}): {:?}", + ty, + promoted_ty, + terr + ); + }; + } else { + self.ascribe_user_type( + constant.const_.ty(), + ty::UserType::new(ty::UserTypeKind::TypeOf( + uv.def, + UserArgs { args: uv.args, user_self_ty: None }, + )), + locations.span(self.body), + ); + } + } else if let Some(static_def_id) = constant.check_static_ptr(tcx) { + let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity(); + let normalized_ty = self.normalize(unnormalized_ty, locations); + let literal_ty = constant.const_.ty().builtin_deref(true).unwrap(); + + if let Err(terr) = + self.eq_types(literal_ty, normalized_ty, locations, ConstraintCategory::Boring) + { + span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr); + } + } + + if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() { + let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args); + self.normalize_and_prove_instantiated_predicates( + def_id, + instantiated_predicates, + locations, + ); + + assert!(!matches!( + tcx.impl_of_method(def_id).map(|imp| tcx.def_kind(imp)), + Some(DefKind::Impl { of_trait: true }) + )); + self.prove_predicates( + args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())), + locations, + ConstraintCategory::Boring, + ); + } + } + } + + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { + self.super_place(place, context, location); + let tcx = self.tcx(); + let place_ty = place.ty(self.body, tcx); + if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { + let trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), + [place_ty.ty], + ); + + // To have a `Copy` operand, the type `T` of the + // value must be `Copy`. Note that we prove that `T: Copy`, + // rather than using the `is_copy_modulo_regions` + // test. This is important because + // `is_copy_modulo_regions` ignores the resulting region + // obligations and assumes they pass. This can result in + // bounds from `Copy` impls being unsoundly ignored (e.g., + // #29149). Note that we decide to use `Copy` before knowing + // whether the bounds fully apply: in effect, the rule is + // that if a value of some type could implement `Copy`, then + // it must. + self.prove_trait_ref(trait_ref, location.to_locations(), ConstraintCategory::CopyBound); + } + } + + fn visit_projection_elem( + &mut self, + place: PlaceRef<'tcx>, + elem: PlaceElem<'tcx>, + context: PlaceContext, + location: Location, + ) { + let tcx = self.tcx(); + let base_ty = place.ty(self.body(), tcx); + match elem { + // All these projections don't add any constraints, so there's nothing to + // do here. We check their invariants in the MIR validator after all. + ProjectionElem::Deref + | ProjectionElem::Index(_) + | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subslice { .. } + | ProjectionElem::Downcast(..) => {} + ProjectionElem::Field(field, fty) => { + let fty = self.normalize(fty, location); + let ty = base_ty.field_ty(tcx, field); + let ty = self.normalize(ty, location); + debug!(?fty, ?ty); + + if let Err(terr) = self.relate_types( + ty, + context.ambient_variance(), + fty, + location.to_locations(), + ConstraintCategory::Boring, + ) { + span_mirbug!(self, place, "bad field access ({:?}: {:?}): {:?}", ty, fty, terr); + } + } + ProjectionElem::OpaqueCast(ty) => { + let ty = self.normalize(ty, location); + self.relate_types( + ty, + context.ambient_variance(), + base_ty.ty, + location.to_locations(), + ConstraintCategory::TypeAnnotation(AnnotationSource::OpaqueCast), + ) + .unwrap(); + } + ProjectionElem::UnwrapUnsafeBinder(ty) => { + let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else { + unreachable!(); + }; + let found_ty = self.infcx.instantiate_binder_with_fresh_vars( + self.body.source_info(location).span, + BoundRegionConversionTime::HigherRankedType, + binder_ty.into(), + ); + self.relate_types( + ty, + context.ambient_variance(), + found_ty, + location.to_locations(), + ConstraintCategory::Boring, + ) + .unwrap(); + } + ProjectionElem::Subtype(_) => { + bug!("ProjectionElem::Subtype shouldn't exist in borrowck") + } + } + } } impl<'a, 'tcx> TypeChecker<'a, 'tcx> { diff --git a/tests/ui/consts/const-unsized.stderr b/tests/ui/consts/const-unsized.stderr index 8328e19aac22..cee364b33f7a 100644 --- a/tests/ui/consts/const-unsized.stderr +++ b/tests/ui/consts/const-unsized.stderr @@ -58,18 +58,18 @@ error[E0507]: cannot move out of a shared reference LL | static STATIC_BAR: str = *"bar"; | ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait -error[E0161]: cannot move a value of type `str` - --> $DIR/const-unsized.rs:20:48 - | -LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); - | ^^^^^^^^^ the size of `str` cannot be statically determined - error[E0161]: cannot move a value of type `dyn Debug + Sync` --> $DIR/const-unsized.rs:20:38 | LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); | ^^^^^^^ the size of `dyn Debug + Sync` cannot be statically determined +error[E0161]: cannot move a value of type `str` + --> $DIR/const-unsized.rs:20:48 + | +LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); + | ^^^^^^^^^ the size of `str` cannot be statically determined + error: aborting due to 10 previous errors Some errors have detailed explanations: E0161, E0277, E0507. From c170d0f12fa9866d39190bc70c8df614083c3d5a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 11 Mar 2025 16:32:35 +0000 Subject: [PATCH 969/991] Elaborate param-env built for checking DispatchFromDyn for dyn compat --- .../src/traits/dyn_compatibility.rs | 19 ++++++---- tests/ui/associated-types/issue-59324.rs | 1 + tests/ui/associated-types/issue-59324.stderr | 21 +++++++--- .../dyn-dispatch-requires-supertrait-norm.rs | 38 +++++++++++++++++++ .../self/dyn-dispatch-requires-supertrait.rs | 38 +++++++++++++++++++ 5 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs create mode 100644 tests/ui/self/dyn-dispatch-requires-supertrait.rs diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index d4502be6ccfe..3fceada25104 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -24,7 +24,9 @@ use super::elaborate; use crate::infer::TyCtxtInferExt; pub use crate::traits::DynCompatibilityViolation; use crate::traits::query::evaluate_obligation::InferCtxtExt; -use crate::traits::{MethodViolationCode, Obligation, ObligationCause, util}; +use crate::traits::{ + MethodViolationCode, Obligation, ObligationCause, normalize_param_env_or_error, util, +}; /// Returns the dyn-compatibility violations that affect HIR ty lowering. /// @@ -579,8 +581,8 @@ fn receiver_is_dispatchable<'tcx>( let unsized_receiver_ty = receiver_for_self_ty(tcx, receiver_ty, unsized_self_ty, method.def_id); - // create a modified param env, with `Self: Unsize` and `U: Trait` added to caller bounds - // `U: ?Sized` is already implied here + // create a modified param env, with `Self: Unsize` and `U: Trait` (and all of + // its supertraits) added to caller bounds. `U: ?Sized` is already implied here. let param_env = { let param_env = tcx.param_env(method.def_id); @@ -598,10 +600,13 @@ fn receiver_is_dispatchable<'tcx>( ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx) }; - let caller_bounds = - param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]); - - ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds)) + normalize_param_env_or_error( + tcx, + ty::ParamEnv::new(tcx.mk_clauses_from_iter( + param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]), + )), + ObligationCause::dummy_with_span(tcx.def_span(method.def_id)), + ) }; // Receiver: DispatchFromDyn U]> diff --git a/tests/ui/associated-types/issue-59324.rs b/tests/ui/associated-types/issue-59324.rs index 7421e08c8988..3abe84730526 100644 --- a/tests/ui/associated-types/issue-59324.rs +++ b/tests/ui/associated-types/issue-59324.rs @@ -15,6 +15,7 @@ pub trait ThriftService: { fn get_service( //~^ ERROR the trait bound `Bug: Foo` is not satisfied + //~| ERROR the trait bound `Bug: Foo` is not satisfied &self, ) -> Self::AssocType; //~^ ERROR the trait bound `Bug: Foo` is not satisfied diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr index dc8f9cfe895b..f5e696b7ac1c 100644 --- a/tests/ui/associated-types/issue-59324.stderr +++ b/tests/ui/associated-types/issue-59324.stderr @@ -32,6 +32,7 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied | LL | / fn get_service( LL | | +LL | | LL | | &self, LL | | ) -> Self::AssocType; | |_________________________^ the trait `Foo` is not implemented for `Bug` @@ -41,8 +42,18 @@ help: consider further restricting type parameter `Bug` with trait `Foo` LL | pub trait ThriftService: | +++++ +error[E0277]: the trait bound `Bug: Foo` is not satisfied + --> $DIR/issue-59324.rs:16:5 + | +LL | / fn get_service( +LL | | +LL | | +LL | | &self, +LL | | ) -> Self::AssocType; + | |_________________________^ the trait `Foo` is not implemented for `Bug` + error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/issue-59324.rs:23:29 + --> $DIR/issue-59324.rs:24:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` @@ -54,7 +65,7 @@ LL | pub trait Foo: NotFoo { | ^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Bug: Foo` is not satisfied - --> $DIR/issue-59324.rs:19:10 + --> $DIR/issue-59324.rs:20:10 | LL | ) -> Self::AssocType; | ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug` @@ -65,7 +76,7 @@ LL | pub trait ThriftService: | +++++ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/issue-59324.rs:23:29 + --> $DIR/issue-59324.rs:24:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` @@ -78,7 +89,7 @@ LL | pub trait Foo: NotFoo { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the size for values of type `(dyn ThriftService<(), AssocType = _> + 'static)` cannot be known at compilation time - --> $DIR/issue-59324.rs:23:29 + --> $DIR/issue-59324.rs:24:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -95,6 +106,6 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn with_factory(factory: &dyn ThriftService<()>) {} | + -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs b/tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs new file mode 100644 index 000000000000..55c070eb0368 --- /dev/null +++ b/tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs @@ -0,0 +1,38 @@ +//@ check-pass + +#![feature(derive_coerce_pointee)] +#![feature(arbitrary_self_types)] + +use std::ops::Deref; +use std::marker::CoercePointee; +use std::sync::Arc; + +trait MyTrait {} + +#[derive(CoercePointee)] +#[repr(transparent)] +struct MyArc>(Arc); + +impl> Deref for MyArc { + type Target = T; + fn deref(&self) -> &T { + &self.0 + } +} + +trait Mirror { + type Assoc; +} +impl Mirror for T { + type Assoc = T; +} + +// This is variant on "tests/ui/self/dyn-dispatch-requires-supertrait.rs" but with +// a supertrait that requires normalization to match the pred in the old solver. +trait MyOtherTrait: MyTrait<::Assoc> { + fn foo(self: MyArc); +} + +fn test(_: MyArc) {} + +fn main() {} diff --git a/tests/ui/self/dyn-dispatch-requires-supertrait.rs b/tests/ui/self/dyn-dispatch-requires-supertrait.rs new file mode 100644 index 000000000000..f2661c406fef --- /dev/null +++ b/tests/ui/self/dyn-dispatch-requires-supertrait.rs @@ -0,0 +1,38 @@ +//@ check-pass + +#![feature(derive_coerce_pointee)] +#![feature(arbitrary_self_types)] + +use std::ops::Deref; +use std::marker::CoercePointee; +use std::sync::Arc; + +trait MyTrait {} + +#[derive(CoercePointee)] +#[repr(transparent)] +struct MyArc +where + T: MyTrait + ?Sized, +{ + inner: Arc +} + +impl Deref for MyArc { + type Target = T; + fn deref(&self) -> &T { + &self.inner + } +} + +// Proving that `MyArc` is dyn-dispatchable requires proving `MyArc` implements +// `DispatchFromDyn>`. The `DispatchFromDyn` impl that is generated from the +// `CoercePointee` implementation requires the pointee impls `MyTrait`, but previously we +// were only assuming the pointee impl'd `MyOtherTrait`. Elaboration comes to the rescue here. +trait MyOtherTrait: MyTrait { + fn foo(self: MyArc); +} + +fn test(_: MyArc) {} + +fn main() {} From 61339997194448cd8b18b422f32ced0126963213 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 11 Mar 2025 09:43:39 -0700 Subject: [PATCH 970/991] Fix `cargo vendor` not working without `rustc` installed This fixes an issue where vendoring would fail if `rustc` is not in PATH. This happens with the update of some workspaces to the 2024 edition which need to run `rustc -Vv` to determine which rust version is in use. --- src/bootstrap/src/core/build_steps/vendor.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 984c70955d7d..0caeb328811a 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -103,6 +103,7 @@ impl Step for Vendor { // Will read the libstd Cargo.toml // which uses the unstable `public-dependency` feature. cmd.env("RUSTC_BOOTSTRAP", "1"); + cmd.env("RUSTC", &builder.initial_rustc); cmd.current_dir(self.root_dir).arg(&self.output_dir); From faa5b3f7de0db76e41bcf5c54c401d7651e69c58 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 9 Mar 2025 18:49:59 +0100 Subject: [PATCH 971/991] Fix false-positive in `expr_or_init` and in the `invalid_from_utf8` lint --- compiler/rustc_lint/src/context.rs | 16 ++++++- tests/ui/lint/invalid_from_utf8.rs | 41 +++++++++++----- tests/ui/lint/invalid_from_utf8.stderr | 65 ++++++-------------------- 3 files changed, 58 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index cd4106ebf83a..017ae943e916 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -6,6 +6,7 @@ use std::cell::Cell; use std::slice; +use rustc_ast::BindingMode; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync; use rustc_data_structures::unord::UnordMap; @@ -14,6 +15,7 @@ use rustc_feature::Features; use rustc_hir::def::Res; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; +use rustc_hir::{Pat, PatKind}; use rustc_middle::bug; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; @@ -890,7 +892,12 @@ impl<'tcx> LateContext<'tcx> { } && let Some(init) = match parent_node { hir::Node::Expr(expr) => Some(expr), - hir::Node::LetStmt(hir::LetStmt { init, .. }) => *init, + hir::Node::LetStmt(hir::LetStmt { + init, + // Binding is immutable, init cannot be re-assigned + pat: Pat { kind: PatKind::Binding(BindingMode::NONE, ..), .. }, + .. + }) => *init, _ => None, } { @@ -935,7 +942,12 @@ impl<'tcx> LateContext<'tcx> { } && let Some(init) = match parent_node { hir::Node::Expr(expr) => Some(expr), - hir::Node::LetStmt(hir::LetStmt { init, .. }) => *init, + hir::Node::LetStmt(hir::LetStmt { + init, + // Binding is immutable, init cannot be re-assigned + pat: Pat { kind: PatKind::Binding(BindingMode::NONE, ..), .. }, + .. + }) => *init, hir::Node::Item(item) => match item.kind { hir::ItemKind::Const(.., body_id) | hir::ItemKind::Static(.., body_id) => { Some(self.tcx.hir_body(body_id).value) diff --git a/tests/ui/lint/invalid_from_utf8.rs b/tests/ui/lint/invalid_from_utf8.rs index 87a906761c07..cbc1d8e90459 100644 --- a/tests/ui/lint/invalid_from_utf8.rs +++ b/tests/ui/lint/invalid_from_utf8.rs @@ -128,18 +128,21 @@ pub fn from_utf8() { } pub fn from_utf8_with_indirections() { - let mut a = [99, 108, 130, 105, 112, 112, 121]; - std::str::from_utf8_mut(&mut a); - //~^ WARN calls to `std::str::from_utf8_mut` - str::from_utf8_mut(&mut a); - //~^ WARN calls to `str::from_utf8_mut` - let mut b = &mut a; - let mut c = b; - std::str::from_utf8_mut(c); - //~^ WARN calls to `std::str::from_utf8_mut` - str::from_utf8_mut(c); - //~^ WARN calls to `str::from_utf8_mut` - let mut c = &[99, 108, 130, 105, 112, 112, 121]; + // NOTE: We used to lint on the patterns below, but due to the + // binding being mutable it could be changed between the + // declaration and the call and that would have created a + // false-positive, so until we can reliably avoid those false + // postive we don't lint on them. Example of FP below. + // + // let mut a = [99, 108, 130, 105, 112, 112, 121]; + // std::str::from_utf8_mut(&mut a); + // str::from_utf8_mut(&mut a); + // let mut b = &mut a; + // let mut c = b; + // std::str::from_utf8_mut(c); + // str::from_utf8_mut(c); + + let c = &[99, 108, 130, 105, 112, 112, 121]; std::str::from_utf8(c); //~^ WARN calls to `std::str::from_utf8` str::from_utf8(c); @@ -164,6 +167,20 @@ pub fn from_utf8_with_indirections() { //~^ WARN calls to `std::str::from_utf8` str::from_utf8(INVALID_4); //~^ WARN calls to `str::from_utf8` + + let mut a = [99, 108, 130, 105, 112, 112, 121]; // invalid + loop { + a = [99, 108, 130, 105, 112, 112, 121]; // still invalid, but too complex + break; + } + std::str::from_utf8_mut(&mut a); + + let mut a = [99, 108, 130, 105, 112, 112]; // invalid + loop { + a = *b"clippy"; // valid + break; + } + std::str::from_utf8_mut(&mut a); } fn main() {} diff --git a/tests/ui/lint/invalid_from_utf8.stderr b/tests/ui/lint/invalid_from_utf8.stderr index 3cd4d227fc27..26bee5c40386 100644 --- a/tests/ui/lint/invalid_from_utf8.stderr +++ b/tests/ui/lint/invalid_from_utf8.stderr @@ -202,60 +202,25 @@ LL | str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | | | the literal was valid UTF-8 up to the 2 bytes -warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:132:5 - | -LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; - | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes -LL | std::str::from_utf8_mut(&mut a); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:134:5 - | -LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; - | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes -... -LL | str::from_utf8_mut(&mut a); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:138:5 - | -LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; - | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes -... -LL | std::str::from_utf8_mut(c); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:140:5 - | -LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; - | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes -... -LL | str::from_utf8_mut(c); - | ^^^^^^^^^^^^^^^^^^^^^ - warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:143:5 + --> $DIR/invalid_from_utf8.rs:146:5 | -LL | let mut c = &[99, 108, 130, 105, 112, 112, 121]; - | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes +LL | let c = &[99, 108, 130, 105, 112, 112, 121]; + | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes LL | std::str::from_utf8(c); | ^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:145:5 + --> $DIR/invalid_from_utf8.rs:148:5 | -LL | let mut c = &[99, 108, 130, 105, 112, 112, 121]; - | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes +LL | let c = &[99, 108, 130, 105, 112, 112, 121]; + | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes ... LL | str::from_utf8(c); | ^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:148:5 + --> $DIR/invalid_from_utf8.rs:151:5 | LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -263,7 +228,7 @@ LL | std::str::from_utf8(&INVALID_1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:150:5 + --> $DIR/invalid_from_utf8.rs:153:5 | LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -272,7 +237,7 @@ LL | str::from_utf8(&INVALID_1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:153:5 + --> $DIR/invalid_from_utf8.rs:156:5 | LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -280,7 +245,7 @@ LL | std::str::from_utf8(&INVALID_2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:155:5 + --> $DIR/invalid_from_utf8.rs:158:5 | LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -289,7 +254,7 @@ LL | str::from_utf8(&INVALID_2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:158:5 + --> $DIR/invalid_from_utf8.rs:161:5 | LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -297,7 +262,7 @@ LL | std::str::from_utf8(INVALID_3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:160:5 + --> $DIR/invalid_from_utf8.rs:163:5 | LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -306,7 +271,7 @@ LL | str::from_utf8(INVALID_3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:163:5 + --> $DIR/invalid_from_utf8.rs:166:5 | LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] }; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -314,7 +279,7 @@ LL | std::str::from_utf8(INVALID_4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:165:5 + --> $DIR/invalid_from_utf8.rs:168:5 | LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] }; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -322,5 +287,5 @@ LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 12 LL | str::from_utf8(INVALID_4); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 38 warnings emitted +warning: 34 warnings emitted From 64d143326f222ef477044d846e7e8f09ac6d6a3a Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Tue, 11 Mar 2025 22:57:01 +0200 Subject: [PATCH 972/991] Refactor pick2_mut & pick3_mut to use get_disjoint_mut --- compiler/rustc_index/src/slice.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index f17ea9e4b59a..6e28d1ccf279 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -120,13 +120,12 @@ impl IndexSlice { pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { let (ai, bi) = (a.index(), b.index()); assert!(ai != bi); + let len = self.raw.len(); + assert!(ai < len && bi < len); - if ai < bi { - let (c1, c2) = self.raw.split_at_mut(bi); - (&mut c1[ai], &mut c2[0]) - } else { - let (c2, c1) = self.pick2_mut(b, a); - (c1, c2) + match self.raw.get_disjoint_mut([ai, bi]) { + Ok([a, b]) => (a, b), + Err(_) => panic!("Can't get mutable references"), } } @@ -139,8 +138,11 @@ impl IndexSlice { assert!(ai != bi && bi != ci && ci != ai); let len = self.raw.len(); assert!(ai < len && bi < len && ci < len); - let ptr = self.raw.as_mut_ptr(); - unsafe { (&mut *ptr.add(ai), &mut *ptr.add(bi), &mut *ptr.add(ci)) } + + match self.raw.get_disjoint_mut([ai, bi, ci]) { + Ok([a, b, c]) => (a, b, c), + Err(_) => panic!("Can't get mutable references"), + } } #[inline] From d2642abed34822e845de35ebf4308adcfca15b1f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 21 Feb 2025 18:51:45 +1100 Subject: [PATCH 973/991] Adjust `Map`'s `to_string` functionality. `Map::node_to_string` just calls the free function `hir_id_to_string`. This commit removes the former and changes the latter into a `TyCtxt` method. --- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../rustc_hir_typeck/src/expr_use_visitor.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 8 +- compiler/rustc_middle/src/hir/map.rs | 230 +++++++++--------- compiler/rustc_middle/src/ty/context.rs | 8 +- .../rustc_middle/src/ty/typeck_results.rs | 4 +- compiler/rustc_passes/src/hir_id_validator.rs | 7 +- compiler/rustc_passes/src/reachable.rs | 2 +- 8 files changed, 132 insertions(+), 131 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 786e8b876a61..96ae35f8e8b1 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -298,7 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Combine the diverging and has_error flags. self.diverges.set(self.diverges.get() | old_diverges); - debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id)); + debug!("type of {} is...", self.tcx.hir_id_to_string(expr.hir_id)); debug!("... {:?}, expected is {:?}", ty, expected); ty diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 9ff7eeb23688..63e4a8fb44bd 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1235,7 +1235,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.cx.tainted_by_errors()?; bug!( "no type for node {} in mem_categorization", - self.cx.tcx().hir().node_to_string(id) + self.cx.tcx().hir_id_to_string(id) ); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index c46a42c5de1e..1f218ab36744 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -140,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> { self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| { - span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid)) + span_bug!(span, "no type for local variable {}", self.tcx.hir_id_to_string(nid)) }) } @@ -552,11 +552,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(&t) => t, None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e), None => { - bug!( - "no type for node {} in fcx {}", - self.tcx.hir().node_to_string(id), - self.tag() - ); + bug!("no type for node {} in fcx {}", self.tcx.hir_id_to_string(id), self.tag()); } } } diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index c85af81ee25b..35c8092244dc 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -275,7 +275,7 @@ impl<'tcx> TyCtxt<'tcx> { span_bug!( self.hir().span(hir_id), "body_owned_by: {} has no associated body", - self.hir().node_to_string(hir_id) + self.hir_id_to_string(hir_id) ); }) } @@ -674,6 +674,106 @@ impl<'tcx> TyCtxt<'tcx> { } } } + + /// Get a representation of this `id` for debugging purposes. + /// NOTE: Do NOT use this in diagnostics! + pub fn hir_id_to_string(self, id: HirId) -> String { + let path_str = |def_id: LocalDefId| self.def_path_str(def_id); + + let span_str = || { + self.sess.source_map().span_to_snippet(Map { tcx: self }.span(id)).unwrap_or_default() + }; + let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); + + match self.hir_node(id) { + Node::Item(item) => { + let item_str = match item.kind { + ItemKind::ExternCrate(..) => "extern crate", + ItemKind::Use(..) => "use", + ItemKind::Static(..) => "static", + ItemKind::Const(..) => "const", + ItemKind::Fn { .. } => "fn", + ItemKind::Macro(..) => "macro", + ItemKind::Mod(..) => "mod", + ItemKind::ForeignMod { .. } => "foreign mod", + ItemKind::GlobalAsm { .. } => "global asm", + ItemKind::TyAlias(..) => "ty", + ItemKind::Enum(..) => "enum", + ItemKind::Struct(..) => "struct", + ItemKind::Union(..) => "union", + ItemKind::Trait(..) => "trait", + ItemKind::TraitAlias(..) => "trait alias", + ItemKind::Impl { .. } => "impl", + }; + format!("{id} ({item_str} {})", path_str(item.owner_id.def_id)) + } + Node::ForeignItem(item) => { + format!("{id} (foreign item {})", path_str(item.owner_id.def_id)) + } + Node::ImplItem(ii) => { + let kind = match ii.kind { + ImplItemKind::Const(..) => "associated constant", + ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { + ImplicitSelfKind::None => "associated function", + _ => "method", + }, + ImplItemKind::Type(_) => "associated type", + }; + format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id)) + } + Node::TraitItem(ti) => { + let kind = match ti.kind { + TraitItemKind::Const(..) => "associated constant", + TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { + ImplicitSelfKind::None => "associated function", + _ => "trait method", + }, + TraitItemKind::Type(..) => "associated type", + }; + + format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id)) + } + Node::Variant(variant) => { + format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id)) + } + Node::Field(field) => { + format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id)) + } + Node::AnonConst(_) => node_str("const"), + Node::ConstBlock(_) => node_str("const"), + Node::ConstArg(_) => node_str("const"), + Node::Expr(_) => node_str("expr"), + Node::ExprField(_) => node_str("expr field"), + Node::Stmt(_) => node_str("stmt"), + Node::PathSegment(_) => node_str("path segment"), + Node::Ty(_) => node_str("type"), + Node::AssocItemConstraint(_) => node_str("assoc item constraint"), + Node::TraitRef(_) => node_str("trait ref"), + Node::OpaqueTy(_) => node_str("opaque type"), + Node::Pat(_) => node_str("pat"), + Node::TyPat(_) => node_str("pat ty"), + Node::PatField(_) => node_str("pattern field"), + Node::PatExpr(_) => node_str("pattern literal"), + Node::Param(_) => node_str("param"), + Node::Arm(_) => node_str("arm"), + Node::Block(_) => node_str("block"), + Node::Infer(_) => node_str("infer"), + Node::LetStmt(_) => node_str("local"), + Node::Ctor(ctor) => format!( + "{id} (ctor {})", + ctor.ctor_def_id().map_or("".into(), |def_id| path_str(def_id)), + ), + Node::Lifetime(_) => node_str("lifetime"), + Node::GenericParam(param) => { + format!("{id} (generic_param {})", path_str(param.def_id)) + } + Node::Crate(..) => String::from("(root_crate)"), + Node::WherePredicate(_) => node_str("where predicate"), + Node::Synthetic => unreachable!(), + Node::Err(_) => node_str("error"), + Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), + } + } } impl<'hir> Map<'hir> { @@ -686,28 +786,34 @@ impl<'hir> Map<'hir> { } bug!( "expected foreign mod or inlined parent, found {}", - self.node_to_string(HirId::make_owner(parent.def_id)) + self.tcx.hir_id_to_string(HirId::make_owner(parent.def_id)) ) } pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> { match self.tcx.expect_hir_owner_node(id) { OwnerNode::Item(item) => item, - _ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))), + _ => bug!("expected item, found {}", self.tcx.hir_id_to_string(HirId::make_owner(id))), } } pub fn expect_impl_item(self, id: LocalDefId) -> &'hir ImplItem<'hir> { match self.tcx.expect_hir_owner_node(id) { OwnerNode::ImplItem(item) => item, - _ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))), + _ => bug!( + "expected impl item, found {}", + self.tcx.hir_id_to_string(HirId::make_owner(id)) + ), } } pub fn expect_trait_item(self, id: LocalDefId) -> &'hir TraitItem<'hir> { match self.tcx.expect_hir_owner_node(id) { OwnerNode::TraitItem(item) => item, - _ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))), + _ => bug!( + "expected trait item, found {}", + self.tcx.hir_id_to_string(HirId::make_owner(id)) + ), } } @@ -718,14 +824,14 @@ impl<'hir> Map<'hir> { pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> { match self.tcx.hir_node(id) { Node::Variant(variant) => variant, - _ => bug!("expected variant, found {}", self.node_to_string(id)), + _ => bug!("expected variant, found {}", self.tcx.hir_id_to_string(id)), } } pub fn expect_field(self, id: HirId) -> &'hir FieldDef<'hir> { match self.tcx.hir_node(id) { Node::Field(field) => field, - _ => bug!("expected field, found {}", self.node_to_string(id)), + _ => bug!("expected field, found {}", self.tcx.hir_id_to_string(id)), } } @@ -735,7 +841,7 @@ impl<'hir> Map<'hir> { _ => { bug!( "expected foreign item, found {}", - self.node_to_string(HirId::make_owner(id.def_id)) + self.tcx.hir_id_to_string(HirId::make_owner(id.def_id)) ) } } @@ -748,7 +854,7 @@ impl<'hir> Map<'hir> { _ => { bug!( "expected opaque type definition, found {}", - self.node_to_string(self.tcx.local_def_id_to_hir_id(id)) + self.tcx.hir_id_to_string(self.tcx.local_def_id_to_hir_id(id)) ) } } @@ -757,7 +863,7 @@ impl<'hir> Map<'hir> { pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> { match self.tcx.hir_node(id) { Node::Expr(expr) => expr, - _ => bug!("expected expr, found {}", self.node_to_string(id)), + _ => bug!("expected expr, found {}", self.tcx.hir_id_to_string(id)), } } @@ -796,7 +902,7 @@ impl<'hir> Map<'hir> { } pub fn name(self, id: HirId) -> Symbol { - self.opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.node_to_string(id))) + self.opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.tcx.hir_id_to_string(id))) } /// Given a node ID, gets a list of attributes associated with the AST @@ -977,12 +1083,6 @@ impl<'hir> Map<'hir> { } } - /// Get a representation of this `id` for debugging purposes. - /// NOTE: Do NOT use this in diagnostics! - pub fn node_to_string(self, id: HirId) -> String { - hir_id_to_string(self, id) - } - /// Returns the HirId of `N` in `struct Foo` when /// called with the HirId for the `{ ... }` anon const pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option { @@ -1147,102 +1247,6 @@ fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> { upstream_crates } -fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { - let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id); - - let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default(); - let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); - - match map.tcx.hir_node(id) { - Node::Item(item) => { - let item_str = match item.kind { - ItemKind::ExternCrate(..) => "extern crate", - ItemKind::Use(..) => "use", - ItemKind::Static(..) => "static", - ItemKind::Const(..) => "const", - ItemKind::Fn { .. } => "fn", - ItemKind::Macro(..) => "macro", - ItemKind::Mod(..) => "mod", - ItemKind::ForeignMod { .. } => "foreign mod", - ItemKind::GlobalAsm { .. } => "global asm", - ItemKind::TyAlias(..) => "ty", - ItemKind::Enum(..) => "enum", - ItemKind::Struct(..) => "struct", - ItemKind::Union(..) => "union", - ItemKind::Trait(..) => "trait", - ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl { .. } => "impl", - }; - format!("{id} ({item_str} {})", path_str(item.owner_id.def_id)) - } - Node::ForeignItem(item) => { - format!("{id} (foreign item {})", path_str(item.owner_id.def_id)) - } - Node::ImplItem(ii) => { - let kind = match ii.kind { - ImplItemKind::Const(..) => "associated constant", - ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { - ImplicitSelfKind::None => "associated function", - _ => "method", - }, - ImplItemKind::Type(_) => "associated type", - }; - format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id)) - } - Node::TraitItem(ti) => { - let kind = match ti.kind { - TraitItemKind::Const(..) => "associated constant", - TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { - ImplicitSelfKind::None => "associated function", - _ => "trait method", - }, - TraitItemKind::Type(..) => "associated type", - }; - - format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id)) - } - Node::Variant(variant) => { - format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id)) - } - Node::Field(field) => { - format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id)) - } - Node::AnonConst(_) => node_str("const"), - Node::ConstBlock(_) => node_str("const"), - Node::ConstArg(_) => node_str("const"), - Node::Expr(_) => node_str("expr"), - Node::ExprField(_) => node_str("expr field"), - Node::Stmt(_) => node_str("stmt"), - Node::PathSegment(_) => node_str("path segment"), - Node::Ty(_) => node_str("type"), - Node::AssocItemConstraint(_) => node_str("assoc item constraint"), - Node::TraitRef(_) => node_str("trait ref"), - Node::OpaqueTy(_) => node_str("opaque type"), - Node::Pat(_) => node_str("pat"), - Node::TyPat(_) => node_str("pat ty"), - Node::PatField(_) => node_str("pattern field"), - Node::PatExpr(_) => node_str("pattern literal"), - Node::Param(_) => node_str("param"), - Node::Arm(_) => node_str("arm"), - Node::Block(_) => node_str("block"), - Node::Infer(_) => node_str("infer"), - Node::LetStmt(_) => node_str("local"), - Node::Ctor(ctor) => format!( - "{id} (ctor {})", - ctor.ctor_def_id().map_or("".into(), |def_id| path_str(def_id)), - ), - Node::Lifetime(_) => node_str("lifetime"), - Node::GenericParam(param) => { - format!("{id} (generic_param {})", path_str(param.def_id)) - } - Node::Crate(..) => String::from("(root_crate)"), - Node::WherePredicate(_) => node_str("where predicate"), - Node::Synthetic => unreachable!(), - Node::Err(_) => node_str("error"), - Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), - } -} - pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> ModuleItems { let mut collector = ItemCollector::new(tcx, false); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index edba2a2530f6..1b61496ebb32 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3118,9 +3118,11 @@ impl<'tcx> TyCtxt<'tcx> { pub fn late_bound_vars(self, id: HirId) -> &'tcx List { self.mk_bound_variable_kinds( - &self.late_bound_vars_map(id.owner).get(&id.local_id).cloned().unwrap_or_else(|| { - bug!("No bound vars found for {}", self.hir().node_to_string(id)) - }), + &self + .late_bound_vars_map(id.owner) + .get(&id.local_id) + .cloned() + .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))), ) } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 7d9c23c05f95..06054e22e760 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -310,7 +310,7 @@ impl<'tcx> TypeckResults<'tcx> { pub fn node_type(&self, id: HirId) -> Ty<'tcx> { self.node_type_opt(id).unwrap_or_else(|| { - bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir().node_to_string(id))) + bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir_id_to_string(id))) }) } @@ -554,7 +554,7 @@ fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) { ty::tls::with(|tcx| { bug!( "node {} cannot be placed in TypeckResults with hir_owner {:?}", - tcx.hir().node_to_string(hir_id), + tcx.hir_id_to_string(hir_id), hir_owner ) }); diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 509c2f547752..84b92d49f24c 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -60,19 +60,18 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> { .expect("owning item has no entry"); if max != self.hir_ids_seen.len() - 1 { - let hir = self.tcx.hir(); let pretty_owner = self.tcx.hir_def_path(owner.def_id).to_string_no_crate_verbose(); let missing_items: Vec<_> = (0..=max as u32) .map(|i| ItemLocalId::from_u32(i)) .filter(|&local_id| !self.hir_ids_seen.contains(local_id)) - .map(|local_id| hir.node_to_string(HirId { owner, local_id })) + .map(|local_id| self.tcx.hir_id_to_string(HirId { owner, local_id })) .collect(); let seen_items: Vec<_> = self .hir_ids_seen .iter() - .map(|local_id| hir.node_to_string(HirId { owner, local_id })) + .map(|local_id| self.tcx.hir_id_to_string(HirId { owner, local_id })) .collect(); self.error(|| { @@ -137,7 +136,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> { self.error(|| { format!( "HirIdValidator: The recorded owner of {} is {} instead of {}", - self.tcx.hir().node_to_string(hir_id), + self.tcx.hir_id_to_string(hir_id), self.tcx.hir_def_path(hir_id.owner.def_id).to_string_no_crate_verbose(), self.tcx.hir_def_path(owner.def_id).to_string_no_crate_verbose() ) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index fd465717bf76..599a08bac20d 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -291,7 +291,7 @@ impl<'tcx> ReachableContext<'tcx> { _ => { bug!( "found unexpected node kind in worklist: {} ({:?})", - self.tcx.hir().node_to_string(self.tcx.local_def_id_to_hir_id(search_item)), + self.tcx.hir_id_to_string(self.tcx.local_def_id_to_hir_id(search_item)), node, ); } From 281af35cc33e315bd6b52c8a0578108ece75e265 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 24 Feb 2025 13:01:43 +1100 Subject: [PATCH 974/991] Rename `hir_attrs` query as `hir_attr_map`. To make room for the moving of `Map::attrs` to `TyCtxt::hir_attrs` in the next commit. (It makes sense to rename the query, because it has many fewer uses than the method.) --- compiler/rustc_lint/src/levels.rs | 2 +- compiler/rustc_middle/src/hir/map.rs | 2 +- compiler/rustc_middle/src/hir/mod.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_ty_utils/src/opaque_types.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 4ede9b440879..aa6eef906ea4 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -152,7 +152,7 @@ fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { #[instrument(level = "trace", skip(tcx), ret)] fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap { let store = unerased_lint_store(tcx.sess); - let attrs = tcx.hir_attrs(owner); + let attrs = tcx.hir_attr_map(owner); let mut levels = LintLevelsBuilder { sess: tcx.sess, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 35c8092244dc..fcde11cf986f 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -908,7 +908,7 @@ impl<'hir> Map<'hir> { /// Given a node ID, gets a list of attributes associated with the AST /// corresponding to the node-ID. pub fn attrs(self, id: HirId) -> &'hir [Attribute] { - self.tcx.hir_attrs(id.owner).get(id.local_id) + self.tcx.hir_attr_map(id.owner).get(id.local_id) } /// Gets the span of the definition of the specified HIR node. diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 6071a58367ed..a19458ad7994 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -202,7 +202,7 @@ pub fn provide(providers: &mut Providers) { } }) }; - providers.hir_attrs = |tcx, id| { + providers.hir_attr_map = |tcx, id| { tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs) }; providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id)); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index c8708857565c..781a898a6e99 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -198,7 +198,7 @@ rustc_queries! { /// /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. - query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { + query hir_attr_map(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } feedable } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1b61496ebb32..d0de7eaf44b2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1299,7 +1299,7 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> { ), bodies, }))); - self.feed_owner_id().hir_attrs(attrs); + self.feed_owner_id().hir_attr_map(attrs); } } diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index a107925fb188..3aad97d86cca 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -187,7 +187,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { if !hir_id.is_owner() { return; } - let Some(defines) = self.tcx.hir_attrs(hir_id.owner).define_opaque else { + let Some(defines) = self.tcx.hir_attr_map(hir_id.owner).define_opaque else { return; }; for &(span, define) in defines { From 256c27e748b477c1ec1c59bdc23afade5eec84aa Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 21 Feb 2025 18:33:05 +1100 Subject: [PATCH 975/991] Move methods from `Map` to `TyCtxt`, part 4. Continuing the work from #137350. Removes the unused methods: `expect_variant`, `expect_field`, `expect_foreign_item`. Every method gains a `hir_` prefix. --- .../rustc_borrowck/src/diagnostics/mod.rs | 4 +- .../src/diagnostics/mutability_errors.rs | 2 +- .../src/diagnostics/opaque_suggestions.rs | 2 +- .../src/diagnostics/region_name.rs | 2 +- .../src/diagnostics/var_name.rs | 2 +- .../src/assert_module_sources.rs | 2 +- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- .../rustc_codegen_ssa/src/codegen_attrs.rs | 4 +- .../rustc_const_eval/src/check_consts/mod.rs | 2 +- compiler/rustc_driver_impl/src/pretty.rs | 3 +- .../rustc_hir_analysis/src/check/check.rs | 4 +- .../src/check/compare_impl_item.rs | 26 ++-- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../rustc_hir_analysis/src/check_unused.rs | 2 +- .../src/coherence/builtin.rs | 20 ++-- .../src/coherence/orphan.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 9 +- .../rustc_hir_analysis/src/collect/dump.rs | 2 +- .../rustc_hir_analysis/src/collect/type_of.rs | 2 +- compiler/rustc_hir_analysis/src/delegation.rs | 4 +- .../src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_typeck/src/callee.rs | 2 +- .../src/fn_ctxt/suggestions.rs | 2 +- .../src/method/prelude_edition_lints.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 11 +- compiler/rustc_hir_typeck/src/upvar.rs | 14 +-- .../rustc_incremental/src/assert_dep_graph.rs | 2 +- .../rustc_interface/src/proc_macro_decls.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 6 +- compiler/rustc_lint/src/expect.rs | 2 +- compiler/rustc_lint/src/late.rs | 2 +- compiler/rustc_lint/src/nonstandard_style.rs | 9 +- compiler/rustc_lint/src/types.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 9 +- compiler/rustc_middle/src/hir/map.rs | 112 +++++++----------- compiler/rustc_middle/src/hir/mod.rs | 2 +- compiler/rustc_middle/src/mir/pretty.rs | 4 +- .../src/traits/specialization_graph.rs | 2 +- compiler/rustc_middle/src/ty/closure.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 6 +- .../rustc_middle/src/ty/structural_impls.rs | 2 +- compiler/rustc_mir_build/src/builder/mod.rs | 4 +- compiler/rustc_mir_build/src/builder/scope.rs | 3 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 5 +- .../src/thir/pattern/check_match.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 19 ++- compiler/rustc_passes/src/dead.rs | 6 +- compiler/rustc_passes/src/diagnostic_items.rs | 2 +- compiler/rustc_passes/src/entry.rs | 6 +- compiler/rustc_passes/src/liveness.rs | 2 +- compiler/rustc_passes/src/loops.rs | 2 +- compiler/rustc_passes/src/stability.rs | 6 +- compiler/rustc_privacy/src/lib.rs | 6 +- compiler/rustc_smir/src/rustc_smir/context.rs | 2 +- .../src/error_reporting/infer/mod.rs | 4 +- .../error_reporting/infer/need_type_info.rs | 2 +- .../error_reporting/infer/note_and_explain.rs | 2 +- .../src/error_reporting/infer/region.rs | 2 +- .../src/error_reporting/infer/suggest.rs | 4 +- .../src/error_reporting/traits/suggestions.rs | 18 ++- compiler/rustc_ty_utils/src/assoc.rs | 6 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 2 +- src/doc/rustc-dev-guide/src/hir.md | 4 +- src/librustdoc/clean/inline.rs | 4 +- src/librustdoc/clean/mod.rs | 16 +-- src/librustdoc/doctest.rs | 2 +- src/librustdoc/doctest/rust.rs | 2 +- src/librustdoc/visit_ast.rs | 9 +- .../clippy/clippy_lints/src/attrs/mod.rs | 6 +- .../src/default_union_representation.rs | 2 +- .../clippy_lints/src/derivable_impls.rs | 4 +- src/tools/clippy/clippy_lints/src/derive.rs | 2 +- .../clippy_lints/src/doc/missing_headers.rs | 2 +- src/tools/clippy/clippy_lints/src/escape.rs | 3 +- .../clippy_lints/src/exhaustive_items.rs | 2 +- .../clippy/clippy_lints/src/format_impl.rs | 3 +- .../clippy_lints/src/four_forward_slashes.rs | 3 +- .../clippy_lints/src/functions/must_use.rs | 6 +- .../src/inconsistent_struct_constructor.rs | 2 +- .../src/inline_fn_without_body.rs | 3 +- .../clippy/clippy_lints/src/macro_use.rs | 2 +- .../clippy_lints/src/manual_non_exhaustive.rs | 6 +- .../src/matches/match_like_matches.rs | 2 +- .../src/matches/match_same_arms.rs | 2 +- .../clippy_lints/src/methods/is_empty.rs | 2 +- .../clippy/clippy_lints/src/methods/mod.rs | 2 +- .../clippy/clippy_lints/src/missing_doc.rs | 12 +- .../clippy/clippy_lints/src/missing_inline.rs | 6 +- .../src/mixed_read_write_in_expression.rs | 2 +- .../clippy/clippy_lints/src/needless_if.rs | 2 +- .../clippy_lints/src/needless_late_init.rs | 2 +- .../src/needless_pass_by_ref_mut.rs | 2 +- .../src/needless_pass_by_value.rs | 2 +- .../src/no_mangle_with_rust_abi.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 2 +- .../clippy_lints/src/operators/op_ref.rs | 4 +- .../clippy_lints/src/pass_by_ref_or_value.rs | 2 +- .../clippy_lints/src/pub_underscore_fields.rs | 2 +- .../clippy_lints/src/read_zero_byte_vec.rs | 2 +- .../src/return_self_not_must_use.rs | 2 +- src/tools/clippy/clippy_lints/src/returns.rs | 4 +- .../src/self_named_constructors.rs | 2 +- .../src/undocumented_unsafe_blocks.rs | 3 +- .../clippy/clippy_lints/src/unused_self.rs | 2 +- src/tools/clippy/clippy_lints/src/unwrap.rs | 2 +- .../clippy/clippy_lints/src/utils/author.rs | 2 +- .../clippy/clippy_lints/src/utils/dump_hir.rs | 2 +- .../internal_lints/lint_without_lint_pass.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 22 ++-- src/tools/clippy/clippy_utils/src/msrvs.rs | 2 +- src/tools/clippy/clippy_utils/src/sugg.rs | 4 +- 115 files changed, 269 insertions(+), 321 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index d1f238331d56..208d510db2e1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -505,7 +505,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let var_id = self.infcx.tcx.closure_captures(def_id)[field.index()].get_root_variable(); - Some(self.infcx.tcx.hir().name(var_id).to_string()) + Some(self.infcx.tcx.hir_name(var_id).to_string()) } _ => { // Might need a revision when the fields in trait RFC is implemented @@ -1124,7 +1124,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { def_id, target_place, places ); let hir_id = self.infcx.tcx.local_def_id_to_hir_id(def_id); - let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; + let expr = &self.infcx.tcx.hir_expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); if let &hir::ExprKind::Closure(&hir::Closure { kind, fn_decl_span, .. }) = expr { for (captured_place, place) in diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 145137f92369..3951b467961a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -698,7 +698,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if !matches!(k, hir::AssocItemKind::Fn { .. }) { continue; } - if self.infcx.tcx.hir().name(hi) != self.infcx.tcx.hir().name(my_hir) { + if self.infcx.tcx.hir_name(hi) != self.infcx.tcx.hir_name(my_hir) { continue; } f_in_trait_opt = Some(hi); diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs index 876b8f214b01..7192a889adcb 100644 --- a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs +++ b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs @@ -105,7 +105,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let Some(opaque_def_id) = opaque_def_id.as_local() && let hir::OpaqueTyOrigin::FnReturn { parent, .. } = - tcx.hir().expect_opaque_ty(opaque_def_id).origin + tcx.hir_expect_opaque_ty(opaque_def_id).origin { if let Some(sugg) = impl_trait_overcapture_suggestion( tcx, diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index a15f9744bf31..412aaf70c3f1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -343,7 +343,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { } }; let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }) = - tcx.hir().expect_expr(self.mir_hir_id()).kind + tcx.hir_expect_expr(self.mir_hir_id()).kind else { bug!("Closure is not defined by a closure expr"); }; diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs index 191c0444c742..693d22abbe6c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -69,7 +69,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let upvar_hir_id = upvars[upvar_index].get_root_variable(); debug!("get_upvar_name_and_span_for_region: upvar_hir_id={upvar_hir_id:?}"); - let upvar_name = tcx.hir().name(upvar_hir_id); + let upvar_name = tcx.hir_name(upvar_hir_id); let upvar_span = tcx.hir().span(upvar_hir_id); debug!( "get_upvar_name_and_span_for_region: upvar_name={upvar_name:?} upvar_span={upvar_span:?}", diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 32f689608f81..3710625ac12d 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -63,7 +63,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&mut CguReuseTr }, }; - for attr in tcx.hir().attrs(rustc_hir::CRATE_HIR_ID) { + for attr in tcx.hir_attrs(rustc_hir::CRATE_HIR_ID) { ams.check_attr(attr); } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 87992ce2e11b..9cc737d194ce 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -475,7 +475,7 @@ pub(crate) fn start_async_codegen( ) -> OngoingCodegen { let (coordinator_send, coordinator_receive) = channel(); - let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); let crate_info = CrateInfo::new(tcx, target_cpu); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 63f2f8fa3d17..e9c886d28edf 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -876,7 +876,7 @@ impl CrateInfo { let linked_symbols = crate_types.iter().map(|&c| (c, crate::back::linker::linked_symbols(tcx, c))).collect(); let local_crate_name = tcx.crate_name(LOCAL_CRATE); - let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); let subsystem = ast::attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 90c53c347689..97f0c6f73d5b 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -62,7 +62,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { ); } - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)); + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)); let mut codegen_fn_attrs = CodegenFnAttrs::new(); if tcx.should_inherit_track_caller(did) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; @@ -77,7 +77,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // When `no_builtins` is applied at the crate level, we should add the // `no-builtins` attribute to each function to ensure it takes effect in LTO. - let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); if no_builtins { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_BUILTINS; diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 607cb2e497d8..06ee7075170f 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -81,7 +81,7 @@ pub fn rustc_allow_const_fn_unstable( def_id: LocalDefId, feature_gate: Symbol, ) -> bool { - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(def_id)); + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); find_attr!(attrs, AttributeKind::AllowConstFnUnstable(syms) if syms.contains(&feature_gate)) } diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 828a14e707c5..16d70af7e05d 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -268,8 +268,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { let tcx = ex.tcx(); let f = |annotation: &dyn pprust_hir::PpAnn| { let sm = sess.source_map(); - let hir_map = tcx.hir(); - let attrs = |id| hir_map.attrs(id); + let attrs = |id| tcx.hir_attrs(id); pprust_hir::print_crate( sm, tcx.hir_root_module(), diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8dc5d3617504..a266286664cc 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -185,7 +185,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo` /// projections that would result in "inheriting lifetimes". fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let hir::OpaqueTy { origin, .. } = *tcx.hir().expect_opaque_ty(def_id); + let hir::OpaqueTy { origin, .. } = *tcx.hir_expect_opaque_ty(def_id); // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting // `async-std` (and `pub async fn` in general). @@ -785,7 +785,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_type_alias_type_params_are_used(tcx, def_id); } DefKind::ForeignMod => { - let it = tcx.hir().expect_item(def_id); + let it = tcx.hir_expect_item(def_id); let hir::ItemKind::ForeignMod { abi, items } = it.kind else { return; }; diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index c193aad2afd0..0a37a27b35ba 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1031,7 +1031,7 @@ fn report_trait_method_mismatch<'tcx>( // When the `impl` receiver is an arbitrary self type, like `self: Box`, the // span points only at the type `Box, but we want to cover the whole // argument pattern and type. - let (sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); + let (sig, body) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let span = tcx .hir_body_param_names(body) .zip(sig.decl.inputs.iter()) @@ -1051,7 +1051,7 @@ fn report_trait_method_mismatch<'tcx>( // Suggestion to change output type. We do not suggest in `async` functions // to avoid complex logic or incorrect output. if let ImplItemKind::Fn(sig, _) = - &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind + &tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).kind && !sig.header.asyncness.is_async() { let msg = "change the output type to match the trait"; @@ -1190,12 +1190,12 @@ fn extract_spans_for_error_reporting<'tcx>( ) -> (Span, Option) { let tcx = infcx.tcx; let mut impl_args = { - let (sig, _) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); + let (sig, _) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())) }; let trait_args = trait_m.def_id.as_local().map(|def_id| { - let (sig, _) = tcx.hir().expect_trait_item(def_id).expect_fn(); + let (sig, _) = tcx.hir_expect_trait_item(def_id).expect_fn(); sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())) }); @@ -1371,7 +1371,7 @@ fn compare_number_of_generics<'tcx>( spans }; let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() { - let trait_item = tcx.hir().expect_trait_item(def_id); + let trait_item = tcx.hir_expect_trait_item(def_id); let arg_spans: Vec = arg_spans(trait_.kind, trait_item.generics); let impl_trait_spans: Vec = trait_item .generics @@ -1388,7 +1388,7 @@ fn compare_number_of_generics<'tcx>( (trait_span.map(|s| vec![s]), vec![]) }; - let impl_item = tcx.hir().expect_impl_item(impl_.def_id.expect_local()); + let impl_item = tcx.hir_expect_impl_item(impl_.def_id.expect_local()); let impl_item_impl_trait_spans: Vec = impl_item .generics .params @@ -1466,7 +1466,7 @@ fn compare_number_of_method_arguments<'tcx>( .def_id .as_local() .and_then(|def_id| { - let (trait_m_sig, _) = &tcx.hir().expect_trait_item(def_id).expect_fn(); + let (trait_m_sig, _) = &tcx.hir_expect_trait_item(def_id).expect_fn(); let pos = trait_number_args.saturating_sub(1); trait_m_sig.decl.inputs.get(pos).map(|arg| { if pos == 0 { @@ -1478,7 +1478,7 @@ fn compare_number_of_method_arguments<'tcx>( }) .or_else(|| tcx.hir().span_if_local(trait_m.def_id)); - let (impl_m_sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); + let (impl_m_sig, _) = &tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let pos = impl_number_args.saturating_sub(1); let impl_span = impl_m_sig .decl @@ -1580,10 +1580,10 @@ fn compare_synthetic_generics<'tcx>( // as another generic argument let new_name = tcx.opt_item_name(trait_def_id)?; let trait_m = trait_m.def_id.as_local()?; - let trait_m = tcx.hir().expect_trait_item(trait_m); + let trait_m = tcx.hir_expect_trait_item(trait_m); let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); + let impl_m = tcx.hir_expect_impl_item(impl_m); // in case there are no generics, take the spot between the function name // and the opening paren of the argument list @@ -1613,7 +1613,7 @@ fn compare_synthetic_generics<'tcx>( err.span_label(impl_span, "expected `impl Trait`, found generic parameter"); let _: Option<_> = try { let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); + let impl_m = tcx.hir_expect_impl_item(impl_m); let (sig, _) = impl_m.expect_fn(); let input_tys = sig.decl.inputs; @@ -1855,7 +1855,7 @@ fn compare_const_predicate_entailment<'tcx>( debug!(?impl_ty, ?trait_ty); // Locate the Span containing just the type of the offending impl - let (ty, _) = tcx.hir().expect_impl_item(impl_ct_def_id).expect_const(); + let (ty, _) = tcx.hir_expect_impl_item(impl_ct_def_id).expect_const(); cause.span = ty.span; let mut diag = struct_span_code_err!( @@ -1868,7 +1868,7 @@ fn compare_const_predicate_entailment<'tcx>( let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| { // Add a label to the Span containing just the type of the const - let (ty, _) = tcx.hir().expect_trait_item(trait_ct_def_id).expect_const(); + let (ty, _) = tcx.hir_expect_trait_item(trait_ct_def_id).expect_const(); ty.span }); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a400aaa81427..fd5ffdc2d7a4 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -513,7 +513,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { continue; } - let gat_item_hir = tcx.hir().expect_trait_item(gat_def_id); + let gat_item_hir = tcx.hir_expect_trait_item(gat_def_id); debug!(?required_bounds); let param_env = tcx.param_env(gat_def_id); diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 750c09887a1e..464ffa8711a5 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -31,7 +31,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { if used_trait_imports.contains(&id) { continue; } - let item = tcx.hir().expect_item(id); + let item = tcx.hir_expect_item(id); if item.span.is_dummy() { continue; } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index cee2f487639d..c918abe4c075 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -82,7 +82,7 @@ fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaran _ => {} } - let impl_ = tcx.hir().expect_item(impl_did).expect_impl(); + let impl_ = tcx.hir_expect_item(impl_did).expect_impl(); Err(tcx.dcx().emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span })) } @@ -109,7 +109,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran match type_allowed_to_implement_copy(tcx, param_env, self_type, cause, impl_header.safety) { Ok(()) => Ok(()), Err(CopyImplementationError::InfringingFields(fields)) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error( tcx, fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)), @@ -119,15 +119,15 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran )) } Err(CopyImplementationError::NotAnAdt) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span })) } Err(CopyImplementationError::HasDestructor) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span })) } Err(CopyImplementationError::HasUnsafeFields) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx .dcx() .span_delayed_bug(span, format!("cannot implement `Copy` for `{}`", self_type))) @@ -157,7 +157,7 @@ fn visit_implementation_of_const_param_ty( match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, kind, cause) { Ok(()) => Ok(()), Err(ConstParamTyImplementationError::InfrigingFields(fields)) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error( tcx, fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)), @@ -167,11 +167,11 @@ fn visit_implementation_of_const_param_ty( )) } Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span })) } Err(ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(infringing_tys)) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error( tcx, infringing_tys.into_iter().map(|(ty, reason)| (span, ty, reason)), @@ -181,7 +181,7 @@ fn visit_implementation_of_const_param_ty( )) } Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnUnsized { span })) } } @@ -526,7 +526,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( note: true, })); } else if diff_fields.len() > 1 { - let item = tcx.hir().expect_item(impl_did); + let item = tcx.hir_expect_item(impl_did); let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(t), .. }) = &item.kind { t.path.span } else { diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index dbf7a7378f5a..0b7fc44460ea 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -376,7 +376,7 @@ fn emit_orphan_check_error<'tcx>( ) -> ErrorGuaranteed { match err { traits::OrphanCheckErr::NonLocalInputType(tys) => { - let item = tcx.hir().expect_item(impl_def_id); + let item = tcx.hir_expect_item(impl_def_id); let impl_ = item.expect_impl(); let hir_trait_ref = impl_.of_trait.as_ref().unwrap(); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 49523912b14d..cfb6cf8a2879 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -469,8 +469,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => { let item = self .tcx - .hir() - .expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); + .hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); match &item.kind { hir::ItemKind::Enum(_, generics) | hir::ItemKind::Struct(_, generics) @@ -1143,7 +1142,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { } fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); let (is_alias, is_auto, safety, items) = match item.kind { hir::ItemKind::Trait(is_auto, safety, .., items) => { @@ -1342,7 +1341,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn ), ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => { - let abi = tcx.hir().get_foreign_abi(hir_id); + let abi = tcx.hir_get_foreign_abi(hir_id); compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety()) } @@ -1597,7 +1596,7 @@ pub fn suggest_impl_trait<'tcx>( fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option> { let icx = ItemCtxt::new(tcx, def_id); - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); let impl_ = item.expect_impl(); impl_.of_trait.as_ref().map(|ast_trait_ref| { let selfty = tcx.type_of(def_id).instantiate_identity(); diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 4debd3977f50..7cbd31de6bab 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -13,7 +13,7 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { for id in tcx.hir_crate_items(()).opaques() { if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } = - tcx.hir().expect_opaque_ty(id).origin + tcx.hir_expect_opaque_ty(id).origin && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 6936544838c8..16caa4f6874c 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -480,5 +480,5 @@ pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> } } } - HasTait.visit_ty_unambig(tcx.hir().expect_item(def_id).expect_ty_alias().0).is_break() + HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().0).is_break() } diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 4dbdfa3d85a9..cb711ebb91a8 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -404,7 +404,7 @@ fn check_constraints<'tcx>( }; if let Some(local_sig_id) = sig_id.as_local() - && tcx.hir().opt_delegation_sig_id(local_sig_id).is_some() + && tcx.hir_opt_delegation_sig_id(local_sig_id).is_some() { emit("recursive delegation is not supported yet"); } @@ -416,7 +416,7 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, ) -> &'tcx [Ty<'tcx>] { - let sig_id = tcx.hir().opt_delegation_sig_id(def_id).unwrap(); + let sig_id = tcx.hir_opt_delegation_sig_id(def_id).unwrap(); let caller_sig = tcx.fn_sig(sig_id); if let Err(err) = check_constraints(tcx, def_id, sig_id) { let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index dd6c40bfbb8d..15f46fb38e31 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -370,7 +370,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { #[instrument(level = "debug", skip(self), ret)] pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> { let tcx = self.tcx(); - let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id)); + let lifetime_name = |def_id| tcx.hir_name(tcx.local_def_id_to_hir_id(def_id)); match resolved { rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static, diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 5e00161f693f..2a24d626ac35 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -799,7 +799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Emit a different diagnostic for local variables, as they are not // type definitions themselves, but rather variables *of* that type. Res::Local(hir_id) => { - err.arg("local_name", self.tcx.hir().name(hir_id)); + err.arg("local_name", self.tcx.hir_name(hir_id)); Some(fluent_generated::hir_typeck_invalid_local) } Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 35a3491f7c08..37aaaed5477d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -613,7 +613,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .take(4) .map(|(var_hir_id, upvar)| { - let var_name = self.tcx.hir().name(*var_hir_id).to_string(); + let var_name = self.tcx.hir_name(*var_hir_id).to_string(); let msg = format!("`{var_name}` captured here"); (upvar.span, msg) }) diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index 69d7a6c97cb3..72f8793d7839 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs @@ -363,7 +363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let import_items: Vec<_> = applicable_trait .import_ids .iter() - .map(|&import_id| self.tcx.hir().expect_item(import_id)) + .map(|&import_id| self.tcx.hir_expect_item(import_id)) .collect(); // Find an identifier with which this trait was imported (note that `_` doesn't count). diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index f87e5b5202ab..ee01d78965d5 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -2344,7 +2344,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return false; }; let hir_id = self.fcx.tcx.local_def_id_to_hir_id(local_def_id); - let attrs = self.fcx.tcx.hir().attrs(hir_id); + let attrs = self.fcx.tcx.hir_attrs(hir_id); for attr in attrs { if sym::doc == attr.name_or_empty() { } else if sym::rustc_confusables == attr.name_or_empty() { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index cb1e89fb9e59..1a1540f505d3 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -791,7 +791,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Ok(pick) = self.lookup_probe_for_diagnostic( item_name, Ty::new_ref(tcx, ty::Region::new_error_misc(tcx), ty, ptr_mutbl), - self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)), + self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)), ProbeScope::TraitsInScope, None, ) @@ -834,8 +834,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let SelfSource::MethodCall(rcvr_expr) = source { self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| { - let call_expr = - self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)); + let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)); let probe = self.lookup_probe_for_diagnostic( item_name, output_ty, @@ -2373,7 +2372,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } else { - let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id)); + let call_expr = tcx.hir_expect_expr(tcx.parent_hir_id(expr.hir_id)); if let Some(span) = call_expr.span.trim_start(item_name.span) { err.span_suggestion( @@ -2680,7 +2679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mod_id, expr.hir_id, ) { - let call_expr = self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id)); + let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(expr.hir_id)); let lang_items = self.tcx.lang_items(); let never_mention_traits = [ @@ -2757,7 +2756,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let SelfSource::MethodCall(expr) = source else { return; }; - let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id)); + let call_expr = tcx.hir_expect_expr(tcx.parent_hir_id(expr.hir_id)); let ty::Adt(kind, args) = actual.kind() else { return; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index f570d0d8a0d3..37f3786c00ab 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -781,7 +781,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id, base => bug!("Expected upvar, found={:?}", base), }; - let var_ident = self.tcx.hir().ident(var_hir_id); + let var_ident = self.tcx.hir_ident(var_hir_id); let Some(min_cap_list) = root_var_min_capture_list.get_mut(&var_hir_id) else { let mutability = self.determine_capture_mutability(&typeck_results, &place); @@ -988,13 +988,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => { let cause_span = self.tcx.hir().span(*capture_expr_id); lint.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`", - self.tcx.hir().name(*var_hir_id), + self.tcx.hir_name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span } => { lint.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect", - self.tcx.hir().name(*var_hir_id), + self.tcx.hir_name(*var_hir_id), )); } @@ -1009,13 +1009,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { lint.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure", - self.tcx.hir().name(*var_hir_id), + self.tcx.hir_name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span: _ } => { lint.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure", - v = self.tcx.hir().name(*var_hir_id), + v = self.tcx.hir_name(*var_hir_id), )); } } @@ -1026,7 +1026,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // not capturing something anymore cannot cause a trait to fail to be implemented: match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { - let var_name = self.tcx.hir().name(*var_hir_id); + let var_name = self.tcx.hir_name(*var_hir_id); lint.span_label(closure_head_span, format!("\ in Rust 2018, this closure implements {missing_trait} \ as `{var_name}` implements {missing_trait}, but in Rust 2021, \ @@ -2300,7 +2300,7 @@ fn construct_capture_info_string<'tcx>( } fn var_name(tcx: TyCtxt<'_>, var_hir_id: HirId) -> Symbol { - tcx.hir().name(var_hir_id) + tcx.hir_name(var_hir_id) } #[instrument(level = "debug", skip(tcx))] diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 8f2ca6babea8..1b2056f541f3 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -123,7 +123,7 @@ impl<'tcx> IfThisChanged<'tcx> { fn process_attrs(&mut self, def_id: LocalDefId) { let def_path_hash = self.tcx.def_path_hash(def_id.to_def_id()); let hir_id = self.tcx.local_def_id_to_hir_id(def_id); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { if attr.has_name(sym::rustc_if_this_changed) { let dep_node_interned = self.argument(attr); diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index 00600abb5f1e..a2c1f1dbeda6 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs @@ -8,7 +8,7 @@ fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option { let mut decls = None; for id in tcx.hir_free_items() { - let attrs = tcx.hir().attrs(id.hir_id()); + let attrs = tcx.hir_attrs(id.hir_id()); if attr::contains_name(attrs, sym::rustc_proc_macro_decls) { decls = Some(id.owner_id.def_id); } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f7be37dc4a2c..918a42f30478 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -419,7 +419,7 @@ impl MissingDoc { return; } - let attrs = cx.tcx.hir().attrs(cx.tcx.local_def_id_to_hir_id(def_id)); + let attrs = cx.tcx.hir_attrs(cx.tcx.local_def_id_to_hir_id(def_id)); let has_doc = attrs.iter().any(has_doc); if !has_doc { cx.emit_span_lint( @@ -997,7 +997,7 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); let check_no_mangle_on_generic_fn = |no_mangle_attr: &hir::Attribute, impl_generics: Option<&hir::Generics<'_>>, generics: &hir::Generics<'_>, @@ -1050,7 +1050,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { for it in *items { if let hir::AssocItemKind::Fn { .. } = it.kind { if let Some(no_mangle_attr) = - attr::find_by_name(cx.tcx.hir().attrs(it.id.hir_id()), sym::no_mangle) + attr::find_by_name(cx.tcx.hir_attrs(it.id.hir_id()), sym::no_mangle) { check_no_mangle_on_generic_fn( no_mangle_attr, diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 9ca148e1f254..4c2b82a9a23a 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -38,7 +38,7 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { } LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { // We are an `eval_always` query, so looking at the attribute's `AttrId` is ok. - let attr_id = tcx.hir().attrs(hir_id)[attr_index as usize].id(); + let attr_id = tcx.hir_attrs(hir_id)[attr_index as usize].id(); (attr_id, lint_index) } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 23d6efa05083..852bb01c0965 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -48,7 +48,7 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { where F: FnOnce(&mut Self), { - let attrs = self.context.tcx.hir().attrs(id); + let attrs = self.context.tcx.hir_attrs(id); let prev = self.context.last_node_with_lint_attrs; self.context.last_node_with_lint_attrs = id; debug!("late context: enter_attrs({:?})", attrs); diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 49f9ad39780a..722779d32689 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -342,8 +342,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name { Some(Ident::from_str(name)) } else { - ast::attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name) - .and_then(|attr| { + ast::attr::find_by_name(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), sym::crate_name).and_then( + |attr| { if let Attribute::Unparsed(n) = attr && let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: lit }, .. } = n.as_ref() @@ -371,7 +371,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { } else { None } - }) + }, + ) }; if let Some(ident) = &crate_ident { @@ -500,7 +501,7 @@ impl NonUpperCaseGlobals { impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); match it.kind { hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => { NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index fcadbfc3c4a7..6f3c32af5ef5 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1589,7 +1589,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations { fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, it: &hir::ForeignItem<'tcx>) { let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Declaration }; - let abi = cx.tcx.hir().get_foreign_abi(it.hir_id()); + let abi = cx.tcx.hir_get_foreign_abi(it.hir_id()); match it.kind { hir::ForeignItemKind::Fn(sig, _, _) => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 88a88847e6b8..57c941976e44 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1357,8 +1357,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { features: &tcx.features(), }; let attr_iter = tcx - .hir() - .attrs(tcx.local_def_id_to_hir_id(def_id)) + .hir_attrs(tcx.local_def_id_to_hir_id(def_id)) .iter() .filter(|attr| analyze_attr(*attr, &mut state)); @@ -1839,7 +1838,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_macro(&mut self, def_id: LocalDefId) { let tcx = self.tcx; - let hir::ItemKind::Macro(macro_def, _) = tcx.hir().expect_item(def_id).kind else { bug!() }; + let hir::ItemKind::Macro(macro_def, _) = tcx.hir_expect_item(def_id).kind else { bug!() }; self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules); record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); } @@ -1918,11 +1917,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for &proc_macro in &tcx.resolutions(()).proc_macros { let id = proc_macro; let proc_macro = tcx.local_def_id_to_hir_id(proc_macro); - let mut name = hir.name(proc_macro); + let mut name = tcx.hir_name(proc_macro); let span = hir.span(proc_macro); // Proc-macros may have attributes like `#[allow_internal_unstable]`, // so downstream crates need access to them. - let attrs = hir.attrs(proc_macro); + let attrs = tcx.hir_attrs(proc_macro); let macro_kind = if ast::attr::contains_name(attrs, sym::proc_macro) { MacroKind::Bang } else if ast::attr::contains_name(attrs, sym::proc_macro_attribute) { diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index fcde11cf986f..73c0af84a9fd 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -374,7 +374,7 @@ impl<'tcx> TyCtxt<'tcx> { /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. pub fn hir_krate_attrs(self) -> &'tcx [Attribute] { - self.hir().attrs(CRATE_HIR_ID) + self.hir_attrs(CRATE_HIR_ID) } pub fn hir_rustc_coherence_is_core(self) -> bool { @@ -774,110 +774,78 @@ impl<'tcx> TyCtxt<'tcx> { Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), } } -} -impl<'hir> Map<'hir> { - pub fn get_foreign_abi(self, hir_id: HirId) -> ExternAbi { - let parent = self.tcx.hir_get_parent_item(hir_id); + pub fn hir_get_foreign_abi(self, hir_id: HirId) -> ExternAbi { + let parent = self.hir_get_parent_item(hir_id); if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = - self.tcx.hir_owner_node(parent) + self.hir_owner_node(parent) { return *abi; } bug!( "expected foreign mod or inlined parent, found {}", - self.tcx.hir_id_to_string(HirId::make_owner(parent.def_id)) + self.hir_id_to_string(HirId::make_owner(parent.def_id)) ) } - pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> { - match self.tcx.expect_hir_owner_node(id) { + pub fn hir_expect_item(self, id: LocalDefId) -> &'tcx Item<'tcx> { + match self.expect_hir_owner_node(id) { OwnerNode::Item(item) => item, - _ => bug!("expected item, found {}", self.tcx.hir_id_to_string(HirId::make_owner(id))), + _ => bug!("expected item, found {}", self.hir_id_to_string(HirId::make_owner(id))), } } - pub fn expect_impl_item(self, id: LocalDefId) -> &'hir ImplItem<'hir> { - match self.tcx.expect_hir_owner_node(id) { + pub fn hir_expect_impl_item(self, id: LocalDefId) -> &'tcx ImplItem<'tcx> { + match self.expect_hir_owner_node(id) { OwnerNode::ImplItem(item) => item, - _ => bug!( - "expected impl item, found {}", - self.tcx.hir_id_to_string(HirId::make_owner(id)) - ), + _ => bug!("expected impl item, found {}", self.hir_id_to_string(HirId::make_owner(id))), } } - pub fn expect_trait_item(self, id: LocalDefId) -> &'hir TraitItem<'hir> { - match self.tcx.expect_hir_owner_node(id) { + pub fn hir_expect_trait_item(self, id: LocalDefId) -> &'tcx TraitItem<'tcx> { + match self.expect_hir_owner_node(id) { OwnerNode::TraitItem(item) => item, - _ => bug!( - "expected trait item, found {}", - self.tcx.hir_id_to_string(HirId::make_owner(id)) - ), - } - } - - pub fn get_fn_output(self, def_id: LocalDefId) -> Option<&'hir FnRetTy<'hir>> { - Some(&self.tcx.opt_hir_owner_node(def_id)?.fn_decl()?.output) - } - - pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> { - match self.tcx.hir_node(id) { - Node::Variant(variant) => variant, - _ => bug!("expected variant, found {}", self.tcx.hir_id_to_string(id)), - } - } - - pub fn expect_field(self, id: HirId) -> &'hir FieldDef<'hir> { - match self.tcx.hir_node(id) { - Node::Field(field) => field, - _ => bug!("expected field, found {}", self.tcx.hir_id_to_string(id)), - } - } - - pub fn expect_foreign_item(self, id: OwnerId) -> &'hir ForeignItem<'hir> { - match self.tcx.hir_owner_node(id) { - OwnerNode::ForeignItem(item) => item, _ => { - bug!( - "expected foreign item, found {}", - self.tcx.hir_id_to_string(HirId::make_owner(id.def_id)) - ) + bug!("expected trait item, found {}", self.hir_id_to_string(HirId::make_owner(id))) } } } + pub fn hir_get_fn_output(self, def_id: LocalDefId) -> Option<&'tcx FnRetTy<'tcx>> { + Some(&self.opt_hir_owner_node(def_id)?.fn_decl()?.output) + } + #[track_caller] - pub fn expect_opaque_ty(self, id: LocalDefId) -> &'hir OpaqueTy<'hir> { - match self.tcx.hir_node_by_def_id(id) { + pub fn hir_expect_opaque_ty(self, id: LocalDefId) -> &'tcx OpaqueTy<'tcx> { + match self.hir_node_by_def_id(id) { Node::OpaqueTy(opaq) => opaq, _ => { bug!( "expected opaque type definition, found {}", - self.tcx.hir_id_to_string(self.tcx.local_def_id_to_hir_id(id)) + self.hir_id_to_string(self.local_def_id_to_hir_id(id)) ) } } } - pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> { - match self.tcx.hir_node(id) { + pub fn hir_expect_expr(self, id: HirId) -> &'tcx Expr<'tcx> { + match self.hir_node(id) { Node::Expr(expr) => expr, - _ => bug!("expected expr, found {}", self.tcx.hir_id_to_string(id)), + _ => bug!("expected expr, found {}", self.hir_id_to_string(id)), } } - pub fn opt_delegation_sig_id(self, def_id: LocalDefId) -> Option { - self.tcx.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id() + pub fn hir_opt_delegation_sig_id(self, def_id: LocalDefId) -> Option { + self.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id() } #[inline] - fn opt_ident(self, id: HirId) -> Option { - match self.tcx.hir_node(id) { + fn hir_opt_ident(self, id: HirId) -> Option { + match self.hir_node(id) { Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::span`. - Node::Ctor(..) => match self.tcx.parent_hir_node(id) { + Node::Ctor(..) => match self.parent_hir_node(id) { Node::Item(item) => Some(item.ident), Node::Variant(variant) => Some(variant.ident), _ => unreachable!(), @@ -887,30 +855,32 @@ impl<'hir> Map<'hir> { } #[inline] - pub(super) fn opt_ident_span(self, id: HirId) -> Option { - self.opt_ident(id).map(|ident| ident.span) + pub(super) fn hir_opt_ident_span(self, id: HirId) -> Option { + self.hir_opt_ident(id).map(|ident| ident.span) } #[inline] - pub fn ident(self, id: HirId) -> Ident { - self.opt_ident(id).unwrap() + pub fn hir_ident(self, id: HirId) -> Ident { + self.hir_opt_ident(id).unwrap() } #[inline] - pub fn opt_name(self, id: HirId) -> Option { - self.opt_ident(id).map(|ident| ident.name) + pub fn hir_opt_name(self, id: HirId) -> Option { + self.hir_opt_ident(id).map(|ident| ident.name) } - pub fn name(self, id: HirId) -> Symbol { - self.opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.tcx.hir_id_to_string(id))) + pub fn hir_name(self, id: HirId) -> Symbol { + self.hir_opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.hir_id_to_string(id))) } /// Given a node ID, gets a list of attributes associated with the AST /// corresponding to the node-ID. - pub fn attrs(self, id: HirId) -> &'hir [Attribute] { - self.tcx.hir_attr_map(id.owner).get(id.local_id) + pub fn hir_attrs(self, id: HirId) -> &'tcx [Attribute] { + self.hir_attr_map(id.owner).get(id.local_id) } +} +impl<'hir> Map<'hir> { /// Gets the span of the definition of the specified HIR node. /// This is used by `tcx.def_span`. pub fn span(self, hir_id: HirId) -> Span { diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index a19458ad7994..68b9a4f56b96 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -208,7 +208,7 @@ pub fn provide(providers: &mut Providers) { providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id)); providers.def_ident_span = |tcx, def_id| { let hir_id = tcx.local_def_id_to_hir_id(def_id); - tcx.hir().opt_ident_span(hir_id) + tcx.hir_opt_ident_span(hir_id) }; providers.fn_arg_names = |tcx, def_id| { let hir = tcx.hir(); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f880b1364c2c..007e8d3a245c 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1200,7 +1200,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { && let Some(upvars) = tcx.upvars_mentioned(def_id) { for (&var_id, place) in iter::zip(upvars.keys(), places) { - let var_name = tcx.hir().name(var_id); + let var_name = tcx.hir_name(var_id); struct_fmt.field(var_name.as_str(), place); } } else { @@ -1221,7 +1221,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { && let Some(upvars) = tcx.upvars_mentioned(def_id) { for (&var_id, place) in iter::zip(upvars.keys(), places) { - let var_name = tcx.hir().name(var_id); + let var_name = tcx.hir_name(var_id); struct_fmt.field(var_name.as_str(), place); } } else { diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 9ce5373b0311..8e54a9d487d9 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -72,7 +72,7 @@ impl OverlapMode { .as_local() .into_iter() .flat_map(|local_def_id| { - tcx.hir().attrs(tcx.local_def_id_to_hir_id(local_def_id)) + tcx.hir_attrs(tcx.local_def_id_to_hir_id(local_def_id)) }) .find(|attr| attr.has_name(sym::rustc_strict_coherence)) .map(|attr| attr.span()); diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 5d9b1ddfa38e..703b6ce92471 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -296,7 +296,7 @@ pub struct CaptureInfo { pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) -> String { let mut curr_string: String = match place.base { - HirPlaceBase::Upvar(upvar_id) => tcx.hir().name(upvar_id.var_path.hir_id).to_string(), + HirPlaceBase::Upvar(upvar_id) => tcx.hir_name(upvar_id.var_path.hir_id).to_string(), _ => bug!("Capture_information should only contain upvars"), }; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d0de7eaf44b2..544a6cb64f31 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2214,7 +2214,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns the origin of the opaque type `def_id`. #[instrument(skip(self), level = "trace", ret)] pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin { - self.hir().expect_opaque_ty(def_id).origin + self.hir_expect_opaque_ty(def_id).origin } pub fn finish(self) { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c5509c0a6087..6612018b2556 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1696,7 +1696,7 @@ impl<'tcx> TyCtxt<'tcx> { // FIXME(@lcnr): Remove this function. pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [hir::Attribute] { if let Some(did) = did.as_local() { - self.hir().attrs(self.local_def_id_to_hir_id(did)) + self.hir_attrs(self.local_def_id_to_hir_id(did)) } else { self.attrs_for_def(did) } @@ -1720,7 +1720,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> impl Iterator { let did: DefId = did.into(); if let Some(did) = did.as_local() { - self.hir().attrs(self.local_def_id_to_hir_id(did)).iter() + self.hir_attrs(self.local_def_id_to_hir_id(did)).iter() } else { self.attrs_for_def(did).iter() } @@ -1764,7 +1764,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> impl Iterator { let filter_fn = move |a: &&hir::Attribute| a.path_matches(attr); if let Some(did) = did.as_local() { - self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn) + self.hir_attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn) } else { self.attrs_for_def(did).iter().filter(filter_fn) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 6c62c04f42e4..f1d03d0a6594 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -50,7 +50,7 @@ impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id)); + let name = ty::tls::with(|tcx| tcx.hir_name(self.var_path.hir_id)); write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id) } } diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index f9fa750e750b..2909dea98b74 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -485,7 +485,7 @@ fn construct_fn<'tcx>( }; if let Some(custom_mir_attr) = - tcx.hir().attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir) + tcx.hir_attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir) { return custom::build_custom_mir( tcx, @@ -741,7 +741,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { coroutine: Option>>, ) -> Builder<'a, 'tcx> { let tcx = infcx.tcx; - let attrs = tcx.hir().attrs(hir_id); + let attrs = tcx.hir_attrs(hir_id); // Some functions always have overflow checks enabled, // however, they may not get codegen'd, depending on // the settings for the crate they are codegened in. diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 815612394912..27ff01b48034 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -942,14 +942,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert_eq!(orig_id.owner, self.hir_id.owner); let mut id = orig_id; - let hir = self.tcx.hir(); loop { if id == self.hir_id { // This is a moderately common case, mostly hit for previously unseen nodes. break; } - if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) { + if self.tcx.hir_attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) { // This is a rare case. It's for a node path that doesn't reach the root due to an // intervening lint level attribute. This result doesn't get cached. return id; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index e46e8c9871a5..b8af77245f25 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -1041,7 +1041,7 @@ impl<'tcx> ThirBuildCx<'tcx> { "Should have already errored about late bound consts: {def_id:?}" ); }; - let name = self.tcx.hir().name(hir_id); + let name = self.tcx.hir_name(hir_id); let param = ty::ParamConst::new(index, name); ExprKind::ConstParam { param, def_id } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 2e069cae4269..1e84f4aada12 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -73,7 +73,6 @@ struct ThirBuildCx<'tcx> { impl<'tcx> ThirBuildCx<'tcx> { fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { let typeck_results = tcx.typeck(def); - let hir = tcx.hir(); let hir_id = tcx.local_def_id_to_hir_id(def); let body_type = match tcx.hir_body_owner_kind(def) { @@ -111,8 +110,8 @@ impl<'tcx> ThirBuildCx<'tcx> { typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, body_owner: def.to_def_id(), - apply_adjustments: hir - .attrs(hir_id) + apply_adjustments: tcx + .hir_attrs(hir_id) .iter() .all(|attr| attr.name_or_empty() != rustc_span::sym::custom_mir), } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index dadd1e854611..cbd29ba837ef 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1043,7 +1043,7 @@ fn find_fallback_pattern_typo<'tcx>( for item in cx.tcx.hir_crate_items(()).free_items() { if let DefKind::Use = cx.tcx.def_kind(item.owner_id) { // Look for consts being re-exported. - let item = cx.tcx.hir().expect_item(item.owner_id.def_id); + let item = cx.tcx.hir_expect_item(item.owner_id.def_id); let use_name = item.ident.name; let hir::ItemKind::Use(path, _) = item.kind else { continue; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c6ae2c0fb9bf..ece5a53aaa9c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -52,7 +52,7 @@ fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) hir::ImplItemKind::Const(..) => Target::AssocConst, hir::ImplItemKind::Fn(..) => { let parent_def_id = tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let containing_item = tcx.hir().expect_item(parent_def_id); + let containing_item = tcx.hir_expect_item(parent_def_id); let containing_impl_is_for_trait = match &containing_item.kind { hir::ItemKind::Impl(impl_) => impl_.of_trait.is_some(), _ => bug!("parent of an ImplItem must be an Impl"), @@ -114,7 +114,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut doc_aliases = FxHashMap::default(); let mut specified_inline = None; let mut seen = FxHashMap::default(); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { match attr { Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { @@ -899,7 +899,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Some(location) = match target { Target::AssocTy => { let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id; - let containing_item = self.tcx.hir().expect_item(parent_def_id); + let containing_item = self.tcx.hir_expect_item(parent_def_id); if Target::from_item(containing_item) == Target::Impl { Some("type alias in implementation block") } else { @@ -908,7 +908,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Target::AssocConst => { let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id; - let containing_item = self.tcx.hir().expect_item(parent_def_id); + let containing_item = self.tcx.hir_expect_item(parent_def_id); // We can't link to trait impl's consts. let err = "associated constant in trait implementation block"; match containing_item.kind { @@ -952,7 +952,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { tcx.dcx().emit_err(errors::DocAliasBadLocation { span, attr_str, location }); return; } - let item_name = self.tcx.hir().name(hir_id); + let item_name = self.tcx.hir_name(hir_id); if item_name == doc_alias { tcx.dcx().emit_err(errors::DocAliasNotAnAlias { span, attr_str }); return; @@ -1481,7 +1481,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // `#[must_use]` can be applied to a trait method definition with a default body if let Target::Method(MethodKind::Trait { body: true }) = target && let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id - && let containing_item = self.tcx.hir().expect_item(parent_def_id) + && let containing_item = self.tcx.hir_expect_item(parent_def_id) && let hir::ItemKind::Trait(..) = containing_item.kind { return; @@ -2572,7 +2572,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match (target, force_inline_attr) { (Target::Closure, None) => { let is_coro = matches!( - self.tcx.hir().expect_expr(hir_id).kind, + self.tcx.hir_expect_expr(hir_id).kind, hir::ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Coroutine(..) | hir::ClosureKind::CoroutineClosure(..), @@ -2644,8 +2644,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr]; let spans = self .tcx - .hir() - .attrs(where_predicate.hir_id) + .hir_attrs(where_predicate.hir_id) .iter() .filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym))) .map(|attr| attr.span()) @@ -2814,7 +2813,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { } fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) { - let attrs = tcx.hir().attrs(item.hir_id()); + let attrs = tcx.hir_attrs(item.hir_id()); for attr in attrs { if attr.has_name(sym::inline) { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 7a14a7a5db29..7029c60c3439 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -361,7 +361,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { self.tcx.hir_fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id)) && matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None) && let TyKind::Path(hir::QPath::Resolved(_, path)) = - self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind + self.tcx.hir_expect_item(local_impl_of).expect_impl().self_ty.kind && let Res::Def(def_kind, did) = path.res { match def_kind { @@ -424,7 +424,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { for impl_def_id in self.tcx.all_impls(item.owner_id.to_def_id()) { if let Some(local_def_id) = impl_def_id.as_local() && let ItemKind::Impl(impl_ref) = - self.tcx.hir().expect_item(local_def_id).kind + self.tcx.hir_expect_item(local_def_id).kind { // skip items // mark dependent traits live @@ -448,7 +448,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { for impl_id in self.tcx.all_impls(trait_id) { if let Some(local_impl_id) = impl_id.as_local() && let ItemKind::Impl(impl_ref) = - self.tcx.hir().expect_item(local_impl_id).kind + self.tcx.hir_expect_item(local_impl_id).kind { if !matches!(trait_item.kind, hir::TraitItemKind::Type(..)) && !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty) diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 323b414cca04..e13d94c1031a 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -19,7 +19,7 @@ use rustc_span::{Symbol, sym}; use crate::errors::DuplicateDiagnosticItemInCrate; fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) { - let attrs = tcx.hir().attrs(owner.into()); + let attrs = tcx.hir_attrs(owner.into()); if let Some(name) = extract(attrs) { // insert into our table collect_item(tcx, diagnostic_items, name, owner.to_def_id()); diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 25e679a84601..d2729876ebbb 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -31,7 +31,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { } // If the user wants no main function at all, then stop here. - if attr::contains_name(tcx.hir().attrs(CRATE_HIR_ID), sym::no_main) { + if attr::contains_name(tcx.hir_attrs(CRATE_HIR_ID), sym::no_main) { return None; } @@ -45,7 +45,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { } fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Option { - let attrs = ctxt.tcx.hir().attrs(id.hir_id()); + let attrs = ctxt.tcx.hir_attrs(id.hir_id()); attr::find_by_name(attrs, sym).map(|attr| attr.span()) } @@ -61,7 +61,7 @@ fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) { let at_root = ctxt.tcx.opt_local_parent(id.owner_id.def_id) == Some(CRATE_DEF_ID); - let attrs = ctxt.tcx.hir().attrs(id.hir_id()); + let attrs = ctxt.tcx.hir_attrs(id.hir_id()); let entry_point_type = rustc_ast::entry::entry_point_type( attrs, at_root, diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 822804893fe2..ed70d9ee91f5 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -157,7 +157,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { if let Some(upvars) = tcx.upvars_mentioned(def_id) { for &var_hir_id in upvars.keys() { - let var_name = tcx.hir().name(var_hir_id); + let var_name = tcx.hir_name(var_hir_id); maps.add_variable(Upvar(var_hir_id, var_name)); } } diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 8e59c0b3251c..b06f16cc7bd2 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -222,7 +222,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { if let Some(break_expr) = opt_expr { let (head, loop_label, loop_kind) = if let Some(loop_id) = loop_id { - match self.tcx.hir().expect_expr(loop_id).kind { + match self.tcx.hir_expect_expr(loop_id).kind { hir::ExprKind::Loop(_, label, source, sp) => { (Some(sp), label, Some(source)) } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 0fcf6a80ec4d..aea4386295f3 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -118,7 +118,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { ) where F: FnOnce(&mut Self), { - let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); + let attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id)); debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs); let depr = attr::find_attr!(attrs, AttributeKind::Deprecation{deprecation, span} => (*deprecation, *span)); @@ -795,7 +795,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { }) => { let features = self.tcx.features(); if features.staged_api() { - let attrs = self.tcx.hir().attrs(item.hir_id()); + let attrs = self.tcx.hir_attrs(item.hir_id()); let stab = attr::find_attr!(attrs, AttributeKind::Stability{stability, span} => (*stability, *span)); // FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem @@ -1034,7 +1034,7 @@ fn is_unstable_reexport(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { } // If this is a path that isn't a use, we don't need to do anything special - if !matches!(tcx.hir().expect_item(def_id).kind, ItemKind::Use(..)) { + if !matches!(tcx.hir_expect_item(def_id).kind, ItemKind::Use(..)) { return false; } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5271d03a6f61..3794b23c86a6 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -493,7 +493,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { ) { // Non-opaque macros cannot make other items more accessible than they already are. let hir_id = self.tcx.local_def_id_to_hir_id(local_def_id); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); if attr::find_attr!(attrs, AttributeKind::MacroTransparency(x) => *x) .unwrap_or(Transparency::fallback(md.macro_rules)) @@ -573,7 +573,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { // have normal hygiene, so we can treat them like other items without type // privacy and mark them reachable. DefKind::Macro(_) => { - let item = self.tcx.hir().expect_item(def_id); + let item = self.tcx.hir_expect_item(def_id); if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind { if vis.is_accessible_from(module, self.tcx) { self.update(def_id, macro_ev, Level::Reachable); @@ -597,7 +597,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { DefKind::Struct | DefKind::Union => { // While structs and unions have type privacy, their fields do not. - let item = self.tcx.hir().expect_item(def_id); + let item = self.tcx.hir_expect_item(def_id); if let hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) = item.kind { diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index acd3b7583510..aa1921fc8e78 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -272,7 +272,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let did = tables[def_id]; let attrs_iter = if let Some(did) = did.as_local() { - tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter() + tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)).iter() } else { tcx.attrs_for_def(did).iter() }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 42d37418fb84..baf2489b2b8b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -509,7 +509,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { hir::MatchSource::TryDesugar(scrut_hir_id), ) => { if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { - let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); + let scrut_expr = self.tcx.hir_expect_expr(scrut_hir_id); let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); self.typeck_results @@ -548,7 +548,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) => match source { hir::MatchSource::TryDesugar(scrut_hir_id) => { if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { - let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); + let scrut_expr = self.tcx.hir_expect_expr(scrut_hir_id); let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); self.typeck_results diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index a6d8eb6add7d..40958ec1088b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -1351,7 +1351,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { && !has_impl_trait(def_id) // FIXME(fn_delegation): In delegation item argument spans are equal to last path // segment. This leads to ICE's when emitting `multipart_suggestion`. - && tcx.hir().opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none() + && tcx.hir_opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none() { let successor = method_args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo())); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 51b2a0b36bb9..5583deda99a4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -743,7 +743,7 @@ fn foo(&self) -> Self::T { String::new() } if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() { let opaque_local_def_id = def_id.as_local(); let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id { - tcx.hir().expect_opaque_ty(opaque_local_def_id) + tcx.hir_expect_opaque_ty(opaque_local_def_id) } else { return false; }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index fecb38ab597e..c7f0a88f951a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -1023,7 +1023,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { format!(" for lifetime parameter `{name}`") } infer::UpvarRegion(ref upvar_id, _) => { - let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); + let var_name = self.tcx.hir_name(upvar_id.var_path.hir_id); format!(" for capture of `{var_name}` by closure") } infer::Nll(..) => bug!("NLL variable found in lexical phase"), diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index a7e68e6419d8..cdbb92f4c7ba 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -778,8 +778,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let exp_local_id = exp_def_id.as_local()?; match ( - &self.tcx.hir().expect_opaque_ty(last_local_id), - &self.tcx.hir().expect_opaque_ty(exp_local_id), + &self.tcx.hir_expect_opaque_ty(last_local_id), + &self.tcx.hir_expect_opaque_ty(exp_local_id), ) { ( hir::OpaqueTy { bounds: last_bounds, .. }, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ad46a15a5ac6..4f89f3c2b499 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -22,7 +22,6 @@ use rustc_hir::{ expr_needs_parens, is_range_literal, }; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk}; -use rustc_middle::hir::map; use rustc_middle::traits::IsConstable; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::{ @@ -93,7 +92,7 @@ impl<'a, 'tcx> CoroutineData<'a, 'tcx> { fn get_from_await_ty( &self, visitor: AwaitsVisitor, - hir: map::Map<'tcx>, + tcx: TyCtxt<'tcx>, ty_matches: F, ) -> Option where @@ -102,7 +101,7 @@ impl<'a, 'tcx> CoroutineData<'a, 'tcx> { visitor .awaits .into_iter() - .map(|id| hir.expect_expr(id)) + .map(|id| tcx.hir_expect_expr(id)) .find(|await_expr| ty_matches(ty::Binder::dummy(self.0.expr_ty_adjusted(await_expr)))) .map(|expr| expr.span) } @@ -2180,8 +2179,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: &mut Diag<'_, G>, obligation: &PredicateObligation<'tcx>, ) -> bool { - let hir = self.tcx.hir(); - // Attempt to detect an async-await error by looking at the obligation causes, looking // for a coroutine to be present. // @@ -2350,7 +2347,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut interior_or_upvar_span = None; - let from_awaited_ty = coroutine_data.get_from_await_ty(visitor, hir, ty_matches); + let from_awaited_ty = coroutine_data.get_from_await_ty(visitor, self.tcx, ty_matches); debug!(?from_awaited_ty); // Avoid disclosing internal information to downstream crates. @@ -2428,7 +2425,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Special case the primary error message when send or sync is the trait that was // not implemented. - let hir = self.tcx.hir(); let trait_explanation = if let Some(name @ (sym::Send | sym::Sync)) = self.tcx.get_diagnostic_name(trait_pred.def_id()) { @@ -2455,7 +2451,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .parent(coroutine_did) .as_local() .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id)) .map(|name| { format!("future returned by `{name}` is not {trait_name}") })?, @@ -2479,7 +2475,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .parent(coroutine_did) .as_local() .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id)) .map(|name| { format!("async iterator returned by `{name}` is not {trait_name}") })?, @@ -2502,7 +2498,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .parent(coroutine_did) .as_local() .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id)) .map(|name| { format!("iterator returned by `{name}` is not {trait_name}") })? @@ -3569,7 +3565,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ObligationCauseCode::OpaqueReturnType(expr_info) => { let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info { let expr_ty = tcx.short_string(expr_ty, err.long_ty_path()); - let expr = tcx.hir().expect_expr(hir_id); + let expr = tcx.hir_expect_expr(hir_id); (expr_ty, expr) } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id() && let body = tcx.hir_body(body_id) diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index c84055f5b84f..b7684e85d412 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -21,7 +21,7 @@ pub(crate) fn provide(providers: &mut Providers) { } fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); match item.kind { hir::ItemKind::Trait(.., trait_item_refs) => { // We collect RPITITs for each trait method's return type and create a @@ -96,7 +96,7 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem { let id = tcx.local_def_id_to_hir_id(def_id); let parent_def_id = tcx.hir_get_parent_item(id); - let parent_item = tcx.hir().expect_item(parent_def_id.def_id); + let parent_item = tcx.hir_expect_item(parent_def_id.def_id); match parent_item.kind { hir::ItemKind::Impl(impl_) => { if let Some(impl_item_ref) = impl_.items.iter().find(|i| i.id.owner_id.def_id == def_id) @@ -201,7 +201,7 @@ fn associated_types_for_impl_traits_in_associated_fn( let mut visitor = RPITVisitor { rpits: FxIndexSet::default() }; - if let Some(output) = tcx.hir().get_fn_output(fn_def_id) { + if let Some(output) = tcx.hir_get_fn_output(fn_def_id) { visitor.visit_fn_ret_ty(output); tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 6205578bf747..aeaa83c77b5f 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -161,7 +161,7 @@ fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator, def_id: LocalDefId) -> impl Iterator { - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); if let hir::ItemKind::Impl(impl_) = item.kind { let trait_args = impl_ .of_trait diff --git a/src/doc/rustc-dev-guide/src/hir.md b/src/doc/rustc-dev-guide/src/hir.md index 51893d537d75..75f5a9e20452 100644 --- a/src/doc/rustc-dev-guide/src/hir.md +++ b/src/doc/rustc-dev-guide/src/hir.md @@ -139,12 +139,12 @@ defined in the map. By matching on this, you can find out what sort of node the `HirId` referred to and also get a pointer to the data itself. Often, you know what sort of node `n` is – e.g. if you know that `n` must be some HIR expression, you can do -[`tcx.hir().expect_expr(n)`][expect_expr], which will extract and return the +[`tcx.hir_expect_expr(n)`][expect_expr], which will extract and return the [`&hir::Expr`][Expr], panicking if `n` is not in fact an expression. [find]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.find [`Node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html -[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.expect_expr +[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.expect_expr [Expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Expr.html Finally, you can use the HIR map to find the parents of nodes, via diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 8c6ea00d4890..e973b89b2375 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -181,7 +181,7 @@ pub(crate) fn try_inline_glob( .filter_map(|child| child.res.opt_def_id()) .filter(|def_id| !cx.tcx.is_doc_hidden(def_id)) .collect(); - let attrs = cx.tcx.hir().attrs(import.hir_id()); + let attrs = cx.tcx.hir_attrs(import.hir_id()); let mut items = build_module_items( cx, did, @@ -455,7 +455,7 @@ pub(crate) fn build_impl( } let impl_item = match did.as_local() { - Some(did) => match &tcx.hir().expect_item(did).kind { + Some(did) => match &tcx.hir_expect_item(did).kind { hir::ItemKind::Impl(impl_) => Some(impl_), _ => panic!("`DefID` passed to `build_impl` is not an `impl"), }, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 97ff4c2ef409..b213be5747be 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -112,7 +112,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< items.extend(doc.inlined_foreigns.iter().flat_map(|((_, renamed), (res, local_import_id))| { let Some(def_id) = res.opt_def_id() else { return Vec::new() }; let name = renamed.unwrap_or_else(|| cx.tcx.item_name(def_id)); - let import = cx.tcx.hir().expect_item(*local_import_id); + let import = cx.tcx.hir_expect_item(*local_import_id); match import.kind { hir::ItemKind::Use(path, kind) => { let hir::UsePath { segments, span, .. } = *path; @@ -125,7 +125,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< items.extend(doc.items.values().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { - let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); + let name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted) } else { // skip everything else @@ -986,7 +986,7 @@ fn clean_proc_macro<'tcx>( kind: MacroKind, cx: &mut DocContext<'tcx>, ) -> ItemKind { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); if kind == MacroKind::Derive && let Some(derive_name) = hir_attr_lists(attrs, sym::proc_macro_derive).find_map(|mi| mi.ident()) @@ -1019,7 +1019,7 @@ fn clean_fn_or_proc_macro<'tcx>( name: &mut Symbol, cx: &mut DocContext<'tcx>, ) -> ItemKind { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let macro_kind = attrs.iter().find_map(|a| { if a.has_name(sym::proc_macro) { Some(MacroKind::Bang) @@ -1756,7 +1756,7 @@ fn maybe_expand_private_type_alias<'tcx>( let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id()) && !cx.current_type_aliases.contains_key(&def_id.to_def_id()) { - &cx.tcx.hir().expect_item(def_id).kind + &cx.tcx.hir_expect_item(def_id).kind } else { return None; }; @@ -2762,7 +2762,7 @@ fn clean_maybe_renamed_item<'tcx>( use hir::ItemKind; let def_id = item.owner_id.to_def_id(); - let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); + let mut name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); cx.with_param_env(def_id, |cx| { let kind = match item.kind { ItemKind::Static(ty, mutability, body_id) => StaticItem(Static { @@ -2937,7 +2937,7 @@ fn clean_extern_crate<'tcx>( let cnum = cx.tcx.extern_mod_stmt_cnum(krate.owner_id.def_id).unwrap_or(LOCAL_CRATE); // this is the ID of the crate itself let crate_def_id = cnum.as_def_id(); - let attrs = cx.tcx.hir().attrs(krate.hir_id()); + let attrs = cx.tcx.hir_attrs(krate.hir_id()); let ty_vis = cx.tcx.visibility(krate.owner_id); let please_inline = ty_vis.is_public() && attrs.iter().any(|a| { @@ -3006,7 +3006,7 @@ fn clean_use_statement_inner<'tcx>( } let visibility = cx.tcx.visibility(import.owner_id); - let attrs = cx.tcx.hir().attrs(import.hir_id()); + let attrs = cx.tcx.hir_attrs(import.hir_id()); let inline_attr = hir_attr_lists(attrs, sym::doc).get_word_attr(sym::inline); let pub_underscore = visibility.is_public() && name == kw::Underscore; let current_mod = cx.tcx.parent_module_from_def_id(import.owner_id.def_id); diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 88af9a7388ce..f7f0c9766e2f 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -216,7 +216,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); - let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(CRATE_HIR_ID); let opts = scrape_test_config(crate_name, crate_attrs, args_path); let enable_per_target_ignores = options.enable_per_target_ignores; diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 907e2a3eb2fc..18ad442d0178 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -95,7 +95,7 @@ impl HirCollector<'_> { sp: Span, nested: F, ) { - let ast_attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); + let ast_attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id)); if let Some(ref cfg) = extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default()) && !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features())) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 7b6921afa080..68e381fa3f17 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -143,7 +143,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { && self.cx.tcx.has_attr(def_id, sym::macro_export) && inserted.insert(def_id) { - let item = self.cx.tcx.hir().expect_item(local_def_id); + let item = self.cx.tcx.hir_expect_item(local_def_id); top_level_module .items .insert((local_def_id, Some(item.ident.name)), (item, None, None)); @@ -153,8 +153,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.cx.cache.hidden_cfg = self .cx .tcx - .hir() - .attrs(CRATE_HIR_ID) + .hir_attrs(CRATE_HIR_ID) .iter() .filter(|attr| attr.has_name(sym::doc)) .flat_map(|attr| attr.meta_item_list().into_iter().flatten()) @@ -245,7 +244,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; let document_hidden = self.cx.render_options.document_hidden; - let use_attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(def_id)); + let use_attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. let is_no_inline = hir_attr_lists(use_attrs, sym::doc).has_word(sym::no_inline) || (document_hidden && hir_attr_lists(use_attrs, sym::doc).has_word(sym::hidden)); @@ -449,7 +448,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { continue; } - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(item.owner_id.def_id)); + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(item.owner_id.def_id)); // If there was a private module in the current path then don't bother inlining // anything as it will probably be stripped anyway. diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index 2b59c218d57a..f9a2f011a144 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -465,7 +465,7 @@ impl Attributes { impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); if is_relevant_item(cx, item) { inline_always::check(cx, item.span, item.ident.name, attrs); } @@ -474,13 +474,13 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { if is_relevant_impl(cx, item) { - inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())); + inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id())); } } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if is_relevant_trait(cx, item) { - inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())); + inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id())); } } } diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs index 085ed9222c91..7c64bf46e7bd 100644 --- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs +++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs @@ -97,7 +97,7 @@ fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: ty::GenericArgsR } fn has_c_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); find_attr!(attrs, AttributeKind::Repr(r) if r.iter().any(|(x, _)| *x == ReprAttr::ReprC)) } diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 66a3e5e3d3c7..8d9222e4bf61 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -197,9 +197,9 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() - && let attrs = cx.tcx.hir().attrs(item.hir_id()) + && let attrs = cx.tcx.hir_attrs(item.hir_id()) && !attrs.iter().any(|attr| attr.doc_str().is_some()) - && cx.tcx.hir().attrs(impl_item_hir).is_empty() + && cx.tcx.hir_attrs(impl_item_hir).is_empty() { if adt_def.is_struct() { check_struct(cx, item, self_ty, func_expr, adt_def, args, cx.tcx.typeck_body(*b)); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index db3e6034c5ba..2ae35b400557 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -384,7 +384,7 @@ fn check_unsafe_derive_deserialize<'tcx>( .tcx .inherent_impls(def.did()) .iter() - .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local())) + .map(|imp_did| cx.tcx.hir_expect_item(imp_did.expect_local())) .any(|imp| has_unsafe(cx, imp)) { span_lint_hir_and_then( diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs index e8638595c4b2..e75abf28bace 100644 --- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs +++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs @@ -25,7 +25,7 @@ pub fn check( && cx .tcx .hir_parent_iter(owner_id.into()) - .any(|(id, _node)| is_doc_hidden(cx.tcx.hir().attrs(id))) + .any(|(id, _node)| is_doc_hidden(cx.tcx.hir_attrs(id))) { return; } diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 33ba401d60c2..9298f56b68be 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -163,7 +163,6 @@ impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> { fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) { if cmt.place.projections.is_empty() { - let map = &self.cx.tcx.hir(); if is_argument(self.cx.tcx, cmt.hir_id) { // Skip closure arguments let parent_id = self.cx.tcx.parent_hir_id(cmt.hir_id); @@ -174,7 +173,7 @@ impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> { // skip if there is a `self` parameter binding to a type // that contains `Self` (i.e.: `self: Box`), see #4804 if let Some(trait_self_ty) = self.trait_self_ty { - if map.name(cmt.hir_id) == kw::SelfLower && cmt.place.ty().contains(trait_self_ty) { + if self.cx.tcx.hir_name(cmt.hir_id) == kw::SelfLower && cmt.place.ty().contains(trait_self_ty) { return; } } diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs index 9bf3baba4b59..591912cc8d5e 100644 --- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs @@ -84,7 +84,7 @@ impl LateLintPass<'_> for ExhaustiveItems { _ => return, }; if cx.effective_visibilities.is_exported(item.owner_id.def_id) - && let attrs = cx.tcx.hir().attrs(item.hir_id()) + && let attrs = cx.tcx.hir_attrs(item.hir_id()) && !attrs.iter().any(|a| a.has_name(sym::non_exhaustive)) && fields.iter().all(|f| cx.tcx.visibility(f.def_id).is_public()) { diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs index ff75fcf2b417..5b42a40d850b 100644 --- a/src/tools/clippy/clippy_lints/src/format_impl.rs +++ b/src/tools/clippy/clippy_lints/src/format_impl.rs @@ -209,9 +209,8 @@ impl FormatImplExpr<'_, '_> { // Handle dereference of &self -> self that is equivalent (i.e. via *self in fmt() impl) // Since the argument to fmt is itself a reference: &self let reference = peel_ref_operators(self.cx, arg); - let map = self.cx.tcx.hir(); // Is the reference self? - if path_to_local(reference).map(|x| map.name(x)) == Some(kw::SelfLower) { + if path_to_local(reference).map(|x| self.cx.tcx.hir_name(x)) == Some(kw::SelfLower) { let FormatTraitNames { name, .. } = self.format_trait_impl; span_lint( self.cx, diff --git a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs index 0bdb99d7b9a4..8822b87f92f7 100644 --- a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs +++ b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs @@ -43,8 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for FourForwardSlashes { let sm = cx.sess().source_map(); let mut span = cx .tcx - .hir() - .attrs(item.hir_id()) + .hir_attrs(item.hir_id()) .iter() .filter(|i| i.is_doc_comment()) .fold(item.span.shrink_to_lo(), |span, attr| span.to(attr.span())); diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index f1c9657f2240..c3e0d5e8b694 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -21,7 +21,7 @@ use core::ops::ControlFlow; use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT}; pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let hir::ItemKind::Fn { ref sig, @@ -51,7 +51,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp if let hir::ImplItemKind::Fn(ref sig, ref body_id) = item.kind { let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); @@ -74,7 +74,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); diff --git a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs index 5b58113169b1..e1dd7872b9d4 100644 --- a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs +++ b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs @@ -182,7 +182,7 @@ fn suggestion<'tcx>( } fn field_with_attrs_span(tcx: TyCtxt<'_>, field: &hir::ExprField<'_>) -> Span { - if let Some(attr) = tcx.hir().attrs(field.hir_id).first() { + if let Some(attr) = tcx.hir_attrs(field.hir_id).first() { field.span.with_lo(attr.span().lo()) } else { field.span diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs index 9b4a3b3f9c84..6a436fb4a9d1 100644 --- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs +++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs @@ -34,8 +34,7 @@ impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody { if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind && let Some(attr) = cx .tcx - .hir() - .attrs(item.hir_id()) + .hir_attrs(item.hir_id()) .iter() .find(|a| a.has_name(sym::inline)) { diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 20be22850b76..b712b351d063 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -98,7 +98,7 @@ impl LateLintPass<'_> for MacroUseImports { if cx.sess().opts.edition >= Edition::Edition2018 && let hir::ItemKind::Use(path, _kind) = &item.kind && let hir_id = item.hir_id() - && let attrs = cx.tcx.hir().attrs(hir_id) + && let attrs = cx.tcx.hir_attrs(hir_id) && let Some(mac_attr) = attrs.iter().find(|attr| attr.has_name(sym::macro_use)) && let Some(id) = path.res.iter().find_map(|res| match res { Res::Def(DefKind::Mod, id) => Some(id), diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 496e0660d4f9..64b07a5536b4 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -89,11 +89,11 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { match item.kind { ItemKind::Enum(def, _) if def.variants.len() > 1 => { let iter = def.variants.iter().filter_map(|v| { - (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir().attrs(v.hir_id))) + (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id))) .then_some((v.def_id, v.span)) }); if let Ok((id, span)) = iter.exactly_one() - && !attr::contains_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive) + && !attr::contains_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); } @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { "this seems like a manual implementation of the non-exhaustive pattern", |diag| { if let Some(non_exhaustive) = - attr::find_by_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive) + attr::find_by_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) { diag.span_note(non_exhaustive.span(), "the struct is already non-exhaustive"); } else { diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs index d697f427c705..d29d1ea3e96d 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs @@ -42,7 +42,7 @@ pub(super) fn check_match<'tcx>( cx, scrutinee, arms.iter() - .map(|arm| (cx.tcx.hir().attrs(arm.hir_id), Some(arm.pat), arm.body, arm.guard)), + .map(|arm| (cx.tcx.hir_attrs(arm.hir_id), Some(arm.pat), arm.body, arm.guard)), e, false, ) diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index 41e4c75f843e..250f17fa9025 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -75,7 +75,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { HirIdMapEntry::Occupied(entry) => return *entry.get() == b_id, } // the names technically don't have to match; this makes the lint more conservative - && cx.tcx.hir().name(a_id) == cx.tcx.hir().name(b_id) + && cx.tcx.hir_name(a_id) == cx.tcx.hir_name(b_id) && cx.typeck_results().expr_ty(a) == cx.typeck_results().expr_ty(b) && pat_contains_local(lhs.pat, a_id) && pat_contains_local(rhs.pat, b_id) diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs index 1c64f78678ae..7c190e123b72 100644 --- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs +++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs @@ -41,7 +41,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool { cx.tcx .hir_parent_id_iter(id) - .any(|id| cx.tcx.hir().attrs(id).iter().any(|attr| attr.has_name(sym::cfg))) + .any(|id| cx.tcx.hir_attrs(id).iter().any(|attr| attr.has_name(sym::cfg))) } /// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 94d3657d9f12..7dde21d3edb1 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -4731,7 +4731,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { } let name = impl_item.ident.name.as_str(); let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let item = cx.tcx.hir().expect_item(parent); + let item = cx.tcx.hir_expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })); diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 47a9e17b3cfe..3470c266c491 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_crate(&mut self, cx: &LateContext<'tcx>) { - let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID); + let attrs = cx.tcx.hir_attrs(hir::CRATE_HIR_ID); self.check_missing_docs_attrs(cx, CRATE_DEF_ID, attrs, cx.tcx.def_span(CRATE_DEF_ID), "the", "crate"); } @@ -224,7 +224,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id()); - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); if !is_from_proc_macro(cx, it) { self.check_missing_docs_attrs(cx, it.owner_id.def_id, attrs, it.span, article, desc); } @@ -234,7 +234,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) { let (article, desc) = cx.tcx.article_and_description(trait_item.owner_id.to_def_id()); - let attrs = cx.tcx.hir().attrs(trait_item.hir_id()); + let attrs = cx.tcx.hir_attrs(trait_item.hir_id()); if !is_from_proc_macro(cx, trait_item) { self.check_missing_docs_attrs(cx, trait_item.owner_id.def_id, attrs, trait_item.span, article, desc); } @@ -252,7 +252,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id()); - let attrs = cx.tcx.hir().attrs(impl_item.hir_id()); + let attrs = cx.tcx.hir_attrs(impl_item.hir_id()); if !is_from_proc_macro(cx, impl_item) { self.check_missing_docs_attrs(cx, impl_item.owner_id.def_id, attrs, impl_item.span, article, desc); } @@ -261,7 +261,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_field_def(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::FieldDef<'_>) { if !sf.is_positional() { - let attrs = cx.tcx.hir().attrs(sf.hir_id); + let attrs = cx.tcx.hir_attrs(sf.hir_id); if !is_from_proc_macro(cx, sf) { self.check_missing_docs_attrs(cx, sf.def_id, attrs, sf.span, "a", "struct field"); } @@ -270,7 +270,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) { - let attrs = cx.tcx.hir().attrs(v.hir_id); + let attrs = cx.tcx.hir_attrs(v.hir_id); if !is_from_proc_macro(cx, v) { self.check_missing_docs_attrs(cx, v.def_id, attrs, v.span, "a", "variant"); } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 3cf1a80607e8..2c578d816025 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { match it.kind { hir::ItemKind::Fn { .. } => { let desc = "a function"; - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); check_missing_inline_attrs(cx, attrs, it.span, desc); }, hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _generics, _bounds, trait_items) => { @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { // an impl is not provided let desc = "a default trait method"; let item = cx.tcx.hir_trait_item(tit.id); - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); check_missing_inline_attrs(cx, attrs, item.span, desc); } }, @@ -168,7 +168,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { } } - let attrs = cx.tcx.hir().attrs(impl_item.hir_id()); + let attrs = cx.tcx.hir_attrs(impl_item.hir_id()); check_missing_inline_attrs(cx, attrs, impl_item.span, desc); } } diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index a7452c8a3c84..be728e6c8b74 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -334,7 +334,7 @@ impl<'tcx> Visitor<'tcx> for ReadVisitor<'_, 'tcx> { self.cx, MIXED_READ_WRITE_IN_EXPRESSION, expr.span, - format!("unsequenced read of `{}`", self.cx.tcx.hir().name(self.var)), + format!("unsequenced read of `{}`", self.cx.tcx.hir_name(self.var)), |diag| { diag.span_note( self.write_expr.span, diff --git a/src/tools/clippy/clippy_lints/src/needless_if.rs b/src/tools/clippy/clippy_lints/src/needless_if.rs index 7eefb016aca9..c90019f6ee16 100644 --- a/src/tools/clippy/clippy_lints/src/needless_if.rs +++ b/src/tools/clippy/clippy_lints/src/needless_if.rs @@ -65,7 +65,7 @@ impl LateLintPass<'_> for NeedlessIf { stmt.span, "this `if` branch is empty", "you can remove it", - if cond.can_have_side_effects() || !cx.tcx.hir().attrs(stmt.hir_id).is_empty() { + if cond.can_have_side_effects() || !cx.tcx.hir_attrs(stmt.hir_id).is_empty() { // `{ foo }` or `{ foo } && bar` placed into a statement position would be // interpreted as a block statement, force it to be an expression if cond_snippet.starts_with('{') { diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs index 863a1f895c93..3efbed0c2365 100644 --- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs +++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs @@ -261,7 +261,7 @@ fn check<'tcx>( binding_id: HirId, ) -> Option<()> { let usage = first_usage(cx, binding_id, local_stmt.hir_id, block)?; - let binding_name = cx.tcx.hir().opt_name(binding_id)?; + let binding_name = cx.tcx.hir_opt_name(binding_id)?; let let_snippet = local_snippet_without_semicolon(cx, local)?; match usage.expr.kind { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index dc10de24bc8c..576bb27b254c 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -147,7 +147,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { // We don't check unsafe functions. return; } - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) { return; } diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index dc85176ebb9e..7bee89086b80 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { match kind { FnKind::ItemFn(.., header) => { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) { return; } diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs index 1baa3cb2f0fd..fe8a02c64c66 100644 --- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -40,7 +40,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { if let ItemKind::Fn { sig: fn_sig, .. } = &item.kind && !item.span.from_expansion() { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let mut app = Applicability::MaybeIncorrect; let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(item.ident.span.lo()), "..", &mut app); for attr in attrs { diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index d4da12451f18..9b53608ae7f3 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -351,7 +351,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { if let ImplItemKind::Const(_, body_id) = &impl_item.kind { let item_def_id = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let item = cx.tcx.hir().expect_item(item_def_id); + let item = cx.tcx.hir_expect_item(item_def_id); match &item.kind { ItemKind::Impl(Impl { diff --git a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs index c3c09946c27d..378fed481f4f 100644 --- a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs +++ b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs @@ -181,7 +181,7 @@ fn in_impl<'tcx>( ) -> Option<(&'tcx rustc_hir::Ty<'tcx>, &'tcx rustc_hir::Ty<'tcx>)> { if let Some(block) = get_enclosing_block(cx, e.hir_id) && let Some(impl_def_id) = cx.tcx.impl_of_method(block.hir_id.owner.to_def_id()) - && let item = cx.tcx.hir().expect_item(impl_def_id.expect_local()) + && let item = cx.tcx.hir_expect_item(impl_def_id.expect_local()) && let ItemKind::Impl(item) = &item.kind && let Some(of_trait) = &item.of_trait && let Some(seg) = of_trait.path.segments.last() @@ -200,7 +200,7 @@ fn in_impl<'tcx>( fn are_equal(cx: &LateContext<'_>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool { if let ty::Adt(adt_def, _) = middle_ty.kind() && let Some(local_did) = adt_def.did().as_local() - && let item = cx.tcx.hir().expect_item(local_did) + && let item = cx.tcx.hir_expect_item(local_did) && let middle_ty_id = item.owner_id.to_def_id() && let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind && let Res::Def(_, hir_ty_id) = path.res diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 49bc56083468..320c0286bb7b 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -280,7 +280,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { if header.abi != ExternAbi::Rust { return; } - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); for a in attrs { if let Some(meta_items) = a.meta_item_list() { if a.has_name(sym::proc_macro_derive) diff --git a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs index db03657c9af4..fd21893232db 100644 --- a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs +++ b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields { // Only pertains to fields that start with an underscore, and are public. if field.ident.as_str().starts_with('_') && is_visible(field) // We ignore fields that have `#[doc(hidden)]`. - && !is_doc_hidden(cx.tcx.hir().attrs(field.hir_id)) + && !is_doc_hidden(cx.tcx.hir_attrs(field.hir_id)) // We ignore fields that are `PhantomData`. && !is_path_lang_item(cx, field.ty, LangItem::PhantomData) { diff --git a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs index 6bd68dd4109d..49b522994fbf 100644 --- a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs +++ b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs @@ -93,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec { }, ), VecInitKind::WithExprCapacity(hir_id) => { - let e = cx.tcx.hir().expect_expr(hir_id); + let e = cx.tcx.hir_expect_expr(hir_id); span_lint_hir_and_then( cx, READ_ZERO_BYTE_VEC, diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs index 5a25483c397c..07ae92fa9843 100644 --- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs +++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs @@ -74,7 +74,7 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa // We only show this warning for public exported methods. && cx.effective_visibilities.is_exported(fn_def) // We don't want to emit this lint if the `#[must_use]` attribute is already there. - && !cx.tcx.hir().attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use)) + && !cx.tcx.hir_attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use)) && cx.tcx.visibility(fn_def.to_def_id()).is_public() && let ret_ty = return_ty(cx, owner_id) && let self_arg = nth_arg(cx, owner_id, 0) diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index 3ba6d6284592..4cb73df8b488 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -231,7 +231,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { && let Some(stmt) = block.stmts.iter().last() && let StmtKind::Let(local) = &stmt.kind && local.ty.is_none() - && cx.tcx.hir().attrs(local.hir_id).is_empty() + && cx.tcx.hir_attrs(local.hir_id).is_empty() && let Some(initexpr) = &local.init && let PatKind::Binding(_, local_id, _, _) = local.pat.kind && path_to_local_id(retexpr, local_id) @@ -401,7 +401,7 @@ fn check_final_expr<'tcx>( // This allows the addition of attributes, like `#[allow]` (See: clippy#9361) // `#[expect(clippy::needless_return)]` needs to be handled separately to // actually fulfill the expectation (clippy::#12998) - match cx.tcx.hir().attrs(expr.hir_id) { + match cx.tcx.hir_attrs(expr.hir_id) { [] => {}, [attr] => { if matches!(Level::from_attr(attr), Some(Level::Expect(_))) diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index fc02c3a51716..8b2d597b9e32 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { } let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let item = cx.tcx.hir().expect_item(parent); + let item = cx.tcx.hir_expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let ret_ty = return_ty(cx, impl_item.owner_id); diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 746bf018bcc3..be533ca915ed 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -429,8 +429,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span { span.to(cx .tcx - .hir() - .attrs(hir_id) + .hir_attrs(hir_id) .iter() .fold(span, |acc, attr| acc.to(attr.span()))) } diff --git a/src/tools/clippy/clippy_lints/src/unused_self.rs b/src/tools/clippy/clippy_lints/src/unused_self.rs index 2c6c75693166..582aa6e6001e 100644 --- a/src/tools/clippy/clippy_lints/src/unused_self.rs +++ b/src/tools/clippy/clippy_lints/src/unused_self.rs @@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { return; } let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let parent_item = cx.tcx.hir().expect_item(parent); + let parent_item = cx.tcx.hir_expect_item(parent); let assoc_item = cx.tcx.associated_item(impl_item.owner_id); let contains_todo = |cx, body: &'_ Body<'_>| -> bool { clippy_utils::visitors::for_each_expr_without_closures(body.value, |e| { diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 6f6683eb9712..b466a8e127a9 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -318,7 +318,7 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> { { if call_to_unwrap == unwrappable.safe_to_unwrap { let is_entire_condition = unwrappable.is_entire_condition; - let unwrappable_variable_name = self.cx.tcx.hir().name(unwrappable.local_id); + let unwrappable_variable_name = self.cx.tcx.hir_name(unwrappable.local_id); let suggested_pattern = if call_to_unwrap { unwrappable.kind.success_variant_pattern() } else { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 9d8c161873c0..4309cd2c9abd 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -793,7 +793,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { } fn has_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); get_attr(cx.sess(), attrs, "author").count() > 0 } diff --git a/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs b/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs index b108951978f3..9910be9bc285 100644 --- a/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs +++ b/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs @@ -59,6 +59,6 @@ impl<'tcx> LateLintPass<'tcx> for DumpHir { } fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); get_attr(cx.sess(), attrs, "dump").count() > 0 } diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index 89b4c48b8b11..16d51fa09025 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -247,7 +247,7 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<' /// This function extracts the version value of a `clippy::version` attribute if the given value has /// one pub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Option { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); attrs.iter().find_map(|attr| { if let hir::Attribute::Unparsed(attr_kind) = &attr // Identify attribute diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index d89692468441..80613a51c140 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2036,15 +2036,14 @@ pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool { } pub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - find_attr!(cx.tcx.hir().attrs(hir_id), AttributeKind::Repr(..)) + find_attr!(cx.tcx.hir_attrs(hir_id), AttributeKind::Repr(..)) } pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool { - let map = &tcx.hir(); let mut prev_enclosing_node = None; let mut enclosing_node = node; while Some(enclosing_node) != prev_enclosing_node { - if has_attr(map.attrs(enclosing_node), symbol) { + if has_attr(tcx.hir_attrs(enclosing_node), symbol) { return true; } prev_enclosing_node = Some(enclosing_node); @@ -2061,7 +2060,7 @@ pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool { .filter(|(_, node)| matches!(node, OwnerNode::Item(item) if matches!(item.kind, ItemKind::Impl(_)))) .any(|(id, _)| { has_attr( - tcx.hir().attrs(tcx.local_def_id_to_hir_id(id.def_id)), + tcx.hir_attrs(tcx.local_def_id_to_hir_id(id.def_id)), sym::automatically_derived, ) }) @@ -2344,16 +2343,14 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> { pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { cx.tcx - .hir() - .attrs(hir::CRATE_HIR_ID) + .hir_attrs(hir::CRATE_HIR_ID) .iter() .any(|attr| attr.name_or_empty() == sym::no_std) } pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { cx.tcx - .hir() - .attrs(hir::CRATE_HIR_ID) + .hir_attrs(hir::CRATE_HIR_ID) .iter() .any(|attr| attr.name_or_empty() == sym::no_core) } @@ -2643,8 +2640,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym // We could also check for the type name `test::TestDescAndFn` if let Res::Def(DefKind::Struct, _) = path.res { let has_test_marker = tcx - .hir() - .attrs(item.hir_id()) + .hir_attrs(item.hir_id()) .iter() .any(|a| a.has_name(sym::rustc_test_marker)); if has_test_marker { @@ -2688,7 +2684,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool { /// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent /// use [`is_in_cfg_test`] pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.hir().attrs(id).iter().any(|attr| { + tcx.hir_attrs(id).iter().any(|attr| { if attr.has_name(sym::cfg) && let Some(items) = attr.meta_item_list() && let [item] = &*items @@ -2713,12 +2709,10 @@ pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied. pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - let hir = tcx.hir(); - tcx.has_attr(def_id, sym::cfg) || tcx .hir_parent_iter(tcx.local_def_id_to_hir_id(def_id)) - .flat_map(|(parent_id, _)| hir.attrs(parent_id)) + .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)) .any(|attr| attr.has_name(sym::cfg)) } diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs index 5bb2b12988a6..0316de172de7 100644 --- a/src/tools/clippy/clippy_utils/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -108,7 +108,7 @@ impl Msrv { let start = cx.last_node_with_lint_attrs; if let Some(msrv_attr) = once(start) .chain(cx.tcx.hir_parent_id_iter(start)) - .find_map(|id| parse_attrs(cx.tcx.sess, cx.tcx.hir().attrs(id))) + .find_map(|id| parse_attrs(cx.tcx.sess, cx.tcx.hir_attrs(id))) { return Some(msrv_attr); } diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 24b4f0d9e6d8..9cc66593dcc3 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -847,7 +847,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { let mut start_snip = snippet_with_applicability(self.cx, start_span, "..", &mut self.applicability); // identifier referring to the variable currently triggered (i.e.: `fp`) - let ident_str = map.name(id).to_string(); + let ident_str = self.cx.tcx.hir_name(id).to_string(); // full identifier that includes projection (i.e.: `fp.field`) let ident_str_with_proj = snippet(self.cx, span, "..").to_string(); @@ -876,7 +876,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { // item is used in a call // i.e.: `Call`: `|x| please(x)` or `MethodCall`: `|x| [1, 2, 3].contains(x)` ExprKind::Call(_, call_args) | ExprKind::MethodCall(_, _, call_args, _) => { - let expr = self.cx.tcx.hir().expect_expr(cmt.hir_id); + let expr = self.cx.tcx.hir_expect_expr(cmt.hir_id); let arg_ty_kind = self.cx.typeck_results().expr_ty(expr).kind(); if matches!(arg_ty_kind, ty::Ref(_, _, Mutability::Not)) { From 763db5dcd9b95179915e13533af280ad5f6db403 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 5 Mar 2025 17:11:46 +1100 Subject: [PATCH 976/991] Convert a delayed bug to a bug. This is never hit in the test suite. At some point the check should be removed entirely. There are a million places in the compiler where an empty symbol doesn't make sense, so a check of this nature has almost zero value. But I'll leave it in place for now just in case it gets hit by fuzzing or in the wild. --- compiler/rustc_hir_typeck/src/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 786e8b876a61..7e4026db738d 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2933,7 +2933,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let guar = if field.name == kw::Empty { - self.dcx().span_delayed_bug(field.span, "field name with no name") + self.dcx().span_bug(field.span, "field name with no name") } else if self.method_exists_for_diagnostic( field, base_ty, From fe04460f6fdc32c0783ca7cab6a0fb73ed254100 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 7 Mar 2025 07:29:41 +1100 Subject: [PATCH 977/991] Remove an unnecessary `kw::Empty` check. Replace it with an assert for now, just in case it is reachable. --- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index c46a42c5de1e..61b6f21596e4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -825,15 +825,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_missing_method = matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait(); - if item_name.name != kw::Empty { - self.report_method_error( - hir_id, - ty.normalized, - error, - Expectation::NoExpectation, - trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021 - ); - } + assert_ne!(item_name.name, kw::Empty); + self.report_method_error( + hir_id, + ty.normalized, + error, + Expectation::NoExpectation, + trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021 + ); result }); From 0b2d7062c47fa385ff83e20dc53b13c8c5ba4616 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 4 Mar 2025 17:10:55 +1100 Subject: [PATCH 978/991] Introduce `sym::dummy` and `Ident::dummy`. The idea is to identify cases of symbols/identifiers that are not expected to be used. There isn't a perfectly sharp line between "dummy" and "not dummy", but I think it's useful nonetheless. --- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_attr_parsing/src/context.rs | 3 +-- compiler/rustc_attr_parsing/src/parser.rs | 4 ++-- compiler/rustc_expand/src/mbe/quoted.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 2 +- compiler/rustc_span/src/symbol.rs | 22 ++++++++++++++++++++++ 7 files changed, 29 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index e4396a50a15e..fc31912283a7 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1948,7 +1948,7 @@ impl DummyAstNode for Item { span: Default::default(), tokens: Default::default(), }, - ident: Ident::empty(), + ident: Ident::dummy(), kind: ItemKind::ExternCrate(None), tokens: Default::default(), } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 0e6b0bab082e..35541bb04bd7 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -9,7 +9,6 @@ use rustc_errors::{DiagCtxtHandle, Diagnostic}; use rustc_feature::Features; use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId}; use rustc_session::Session; -use rustc_span::symbol::kw; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser}; @@ -338,7 +337,7 @@ impl<'sess> AttributeParser<'sess> { "expr in place where literal is expected (builtin attr parsing)", ); ast::MetaItemLit { - symbol: kw::Empty, + symbol: sym::dummy, suffix: None, kind: ast::LitKind::Err(guar), span: DUMMY_SP, diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index f0cce26f4e24..a8a1460591cf 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -12,7 +12,7 @@ use rustc_ast::{AttrArgs, DelimArgs, Expr, ExprKind, LitKind, MetaItemLit, Norma use rustc_ast_pretty::pprust; use rustc_errors::DiagCtxtHandle; use rustc_hir::{self as hir, AttrPath}; -use rustc_span::symbol::{Ident, kw}; +use rustc_span::symbol::{Ident, kw, sym}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; pub struct SegmentIterator<'a> { @@ -360,7 +360,7 @@ fn expr_to_lit(dcx: DiagCtxtHandle<'_>, expr: &Expr, span: Span) -> MetaItemLit span, "expr in place where literal is expected (builtin attr parsing)", ); - MetaItemLit { symbol: kw::Empty, suffix: None, kind: LitKind::Err(guar), span } + MetaItemLit { symbol: sym::dummy, suffix: None, kind: LitKind::Err(guar), span } } } diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index 8cb001391c52..0ea53627fe78 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -274,7 +274,7 @@ fn parse_tree<'a>( let msg = format!("expected identifier, found `{}`", pprust::token_to_string(token),); sess.dcx().span_err(token.span, msg); - TokenTree::MetaVar(token.span, Ident::empty()) + TokenTree::MetaVar(token.span, Ident::dummy()) } // There are no more tokens. Just return the `$` we already have. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 53f0194091cd..4ec7aff72862 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -243,7 +243,7 @@ impl<'hir> PathSegment<'hir> { } pub fn invalid() -> Self { - Self::new(Ident::empty(), HirId::INVALID, Res::Err) + Self::new(Ident::dummy(), HirId::INVALID, Res::Err) } pub fn args(&self) -> &GenericArgs<'hir> { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index e3405c89b79a..88d1126de1ae 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2266,7 +2266,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && !first.ident.is_path_segment_keyword() => { // Insert a placeholder that's later replaced by `self`/`super`/etc. - path.insert(0, Segment::from_ident(Ident::empty())); + path.insert(0, Segment::from_ident(Ident::dummy())); } _ => return None, } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 718f23d761f0..8a8bec35d819 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -33,6 +33,15 @@ symbols! { // Special reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. // Matching predicates: `is_any_keyword`, `is_special`/`is_reserved` + // + // Notes about `kw::Empty`: + // - Its use can blur the lines between "empty symbol" and "no symbol". + // Using `Option` is preferable, where possible, because that + // is unambiguous. + // - For dummy symbols that are never used and absolutely must be + // present, it's better to use `sym::dummy` than `kw::Empty`, because + // it's clearer that it's intended as a dummy value, and more likely + // to be detected if it accidentally does get used. Empty: "", PathRoot: "{{root}}", DollarCrate: "$crate", @@ -834,6 +843,7 @@ symbols! { drop_types_in_const, dropck_eyepatch, dropck_parametricity, + dummy: "", // use this instead of `kw::Empty` for symbols that won't be used dummy_cgu_name, dylib, dyn_compatible_for_dispatch, @@ -2305,11 +2315,23 @@ impl Ident { Ident::new(name, DUMMY_SP) } + /// This is best avoided, because it blurs the lines between "empty + /// identifier" and "no identifier". Using `Option` is preferable, + /// where possible, because that is unambiguous. #[inline] pub fn empty() -> Ident { Ident::with_dummy_span(kw::Empty) } + // For dummy identifiers that are never used and absolutely must be + // present, it's better to use `Ident::dummy` than `Ident::Empty`, because + // it's clearer that it's intended as a dummy value, and more likely to be + // detected if it accidentally does get used. + #[inline] + pub fn dummy() -> Ident { + Ident::with_dummy_span(sym::dummy) + } + /// Maps a string to an identifier with a dummy span. pub fn from_str(string: &str) -> Ident { Ident::with_dummy_span(Symbol::intern(string)) From 4eadaff1844a0bfc7f8f69bbd1c137538b92b9dc Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Mar 2025 14:14:08 +1100 Subject: [PATCH 979/991] Convert a `kw::Empty` occurrence to `sym::dummy`. `adjust_ident_and_get_scope` returns the symbol it receives unchanged, and the call site ignores the returned symbol, so this symbol is unused. --- compiler/rustc_privacy/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5271d03a6f61..ff203b2938e0 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -40,7 +40,7 @@ use rustc_middle::ty::{ use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::hygiene::Transparency; -use rustc_span::{Ident, Span, Symbol, kw, sym}; +use rustc_span::{Ident, Span, Symbol, sym}; use tracing::debug; use {rustc_attr_parsing as attr, rustc_hir as hir}; @@ -935,8 +935,8 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { } // definition of the field - let ident = Ident::new(kw::Empty, use_ctxt); - let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id).1; + let ident = Ident::new(sym::dummy, use_ctxt); + let (_, def_id) = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id); !field.vis.is_accessible_from(def_id, self.tcx) } From 7398b39a0bfae6c778379b46f2d9e957c94f4f0d Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Wed, 12 Mar 2025 00:35:16 +0200 Subject: [PATCH 980/991] Make panic's more specific --- compiler/rustc_index/src/slice.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index 6e28d1ccf279..1f19d8c66f02 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -1,6 +1,7 @@ use std::fmt; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; +use std::slice::GetDisjointMutError::*; use std::slice::{self, SliceIndex}; use crate::{Idx, IndexVec, IntoSliceIdx}; @@ -115,33 +116,35 @@ impl IndexSlice { /// Returns mutable references to two distinct elements, `a` and `b`. /// - /// Panics if `a == b`. + /// Panics if `a == b` or if some of them are out of bounds. #[inline] pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { let (ai, bi) = (a.index(), b.index()); - assert!(ai != bi); - let len = self.raw.len(); - assert!(ai < len && bi < len); match self.raw.get_disjoint_mut([ai, bi]) { Ok([a, b]) => (a, b), - Err(_) => panic!("Can't get mutable references"), + Err(OverlappingIndices) => panic!("Indices {ai:?} and {bi:?} are not disjoint!"), + Err(IndexOutOfBounds) => { + panic!("Some indices among ({ai:?}, {bi:?}) are out of bounds") + } } } /// Returns mutable references to three distinct elements. /// - /// Panics if the elements are not distinct. + /// Panics if the elements are not distinct or if some of them are out of bounds. #[inline] pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) { let (ai, bi, ci) = (a.index(), b.index(), c.index()); - assert!(ai != bi && bi != ci && ci != ai); - let len = self.raw.len(); - assert!(ai < len && bi < len && ci < len); match self.raw.get_disjoint_mut([ai, bi, ci]) { Ok([a, b, c]) => (a, b, c), - Err(_) => panic!("Can't get mutable references"), + Err(OverlappingIndices) => { + panic!("Indices {ai:?}, {bi:?} and {ci:?} are not disjoint!") + } + Err(IndexOutOfBounds) => { + panic!("Some indices among ({ai:?}, {bi:?}, {ci:?}) are out of bounds") + } } } From d7029d7e2dbd1b2b4f6578e632e2cef8bd4ba0cc Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 7 Mar 2025 16:38:39 +1100 Subject: [PATCH 981/991] Remove unused `OwnerNode::ident` method. --- compiler/rustc_hir/src/hir.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 53f0194091cd..38af49971921 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4332,16 +4332,6 @@ pub enum OwnerNode<'hir> { } impl<'hir> OwnerNode<'hir> { - pub fn ident(&self) -> Option { - match self { - OwnerNode::Item(Item { ident, .. }) - | OwnerNode::ForeignItem(ForeignItem { ident, .. }) - | OwnerNode::ImplItem(ImplItem { ident, .. }) - | OwnerNode::TraitItem(TraitItem { ident, .. }) => Some(*ident), - OwnerNode::Crate(..) | OwnerNode::Synthetic => None, - } - } - pub fn span(&self) -> Span { match self { OwnerNode::Item(Item { span, .. }) From ed10418363ef580a08dc310b3108646d6742b470 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 7 Mar 2025 20:31:41 +1100 Subject: [PATCH 982/991] Inline and remove `State::print_item_type`. It has a single call site. The removal of the closure argument is a nice touch. --- compiler/rustc_hir_pretty/src/lib.rs | 33 ++++++++++------------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 163d9a1b9d97..ae624fc253f2 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -553,24 +553,6 @@ impl<'a> State<'a> { self.word(";") } - fn print_item_type( - &mut self, - item: &hir::Item<'_>, - generics: &hir::Generics<'_>, - inner: impl Fn(&mut Self), - ) { - self.head("type"); - self.print_ident(item.ident); - self.print_generic_params(generics.params); - self.end(); // end the inner ibox - - self.print_where_clause(generics); - self.space(); - inner(self); - self.word(";"); - self.end(); // end the outer ibox - } - fn print_item(&mut self, item: &hir::Item<'_>) { self.hardbreak_if_not_bol(); self.maybe_print_comment(item.span.lo()); @@ -683,10 +665,17 @@ impl<'a> State<'a> { self.end() } hir::ItemKind::TyAlias(ty, generics) => { - self.print_item_type(item, generics, |state| { - state.word_space("="); - state.print_type(ty); - }); + self.head("type"); + self.print_ident(item.ident); + self.print_generic_params(generics.params); + self.end(); // end the inner ibox + + self.print_where_clause(generics); + self.space(); + self.word_space("="); + self.print_type(ty); + self.word(";"); + self.end(); // end the outer ibox } hir::ItemKind::Enum(ref enum_definition, params) => { self.print_enum_def(enum_definition, params, item.ident.name, item.span); From ee9ef8279572ef9e3b47aa446b812c6e02e41572 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 7 Mar 2025 20:41:31 +1100 Subject: [PATCH 983/991] Factor out some repeated code in `parse_item_impl`. --- compiler/rustc_parse/src/parser/item.rs | 37 +++++++++---------------- 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e309f144b4f4..9e6cdfe59bba 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -646,7 +646,7 @@ impl<'a> Parser<'a> { let impl_items = self.parse_item_list(attrs, |p| p.parse_impl_item(ForceCollect::No))?; - let item_kind = match ty_second { + let (of_trait, self_ty) = match ty_second { Some(ty_second) => { // impl Trait for Type if !has_for { @@ -679,31 +679,20 @@ impl<'a> Parser<'a> { }; let trait_ref = TraitRef { path, ref_id: ty_first.id }; - ItemKind::Impl(Box::new(Impl { - safety, - polarity, - defaultness, - constness, - generics, - of_trait: Some(trait_ref), - self_ty: ty_second, - items: impl_items, - })) - } - None => { - // impl Type - ItemKind::Impl(Box::new(Impl { - safety, - polarity, - defaultness, - constness, - generics, - of_trait: None, - self_ty: ty_first, - items: impl_items, - })) + (Some(trait_ref), ty_second) } + None => (None, ty_first), // impl Type }; + let item_kind = ItemKind::Impl(Box::new(Impl { + safety, + polarity, + defaultness, + constness, + generics, + of_trait, + self_ty, + items: impl_items, + })); Ok((Ident::empty(), item_kind)) } From c0cee43af57a66e0bf0c0e88a2fb2342ba872fe2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 30 Jan 2025 13:23:37 +1100 Subject: [PATCH 984/991] Remove unnecessary lifetime from `PatInfo`. --- compiler/rustc_hir_typeck/src/pat.rs | 52 +++++++++++++++------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 19ae3e3899c9..7e6973259feb 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -87,10 +87,10 @@ struct TopInfo<'tcx> { } #[derive(Copy, Clone)] -struct PatInfo<'a, 'tcx> { +struct PatInfo<'tcx> { binding_mode: ByRef, max_ref_mutbl: MutblCap, - top_info: &'a TopInfo<'tcx>, + top_info: TopInfo<'tcx>, decl_origin: Option>, /// The depth of current pattern @@ -303,11 +303,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { origin_expr: Option<&'tcx hir::Expr<'tcx>>, decl_origin: Option>, ) { - let info = TopInfo { expected, origin_expr, span, hir_id: pat.hir_id }; + let top_info = TopInfo { expected, origin_expr, span, hir_id: pat.hir_id }; let pat_info = PatInfo { binding_mode: ByRef::No, max_ref_mutbl: MutblCap::Mut, - top_info: &info, + top_info, decl_origin, current_depth: 0, }; @@ -320,7 +320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Outside of this module, `check_pat_top` should always be used. /// Conversely, inside this module, `check_pat_top` should never be used. #[instrument(level = "debug", skip(self, pat_info))] - fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'_, 'tcx>) { + fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx>) { let PatInfo { binding_mode, max_ref_mutbl, top_info: ti, current_depth, .. } = pat_info; let path_res = match pat.kind { @@ -352,13 +352,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { qpath, path_res.unwrap(), expected, - ti, + &pat_info.top_info, ); self.write_ty(*hir_id, ty); ty } - PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, ti), - PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti), + PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, &pat_info.top_info), + PatKind::Range(lhs, rhs, _) => { + self.check_pat_range(pat.span, lhs, rhs, expected, &pat_info.top_info) + } PatKind::Binding(ba, var_id, ident, sub) => { self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info) } @@ -818,7 +820,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ident: Ident, sub: Option<&'tcx Pat<'tcx>>, expected: Ty<'tcx>, - pat_info: PatInfo<'_, 'tcx>, + pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { let PatInfo { binding_mode: def_br, top_info: ti, .. } = pat_info; @@ -914,12 +916,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // We have a concrete type for the local, so we do not need to taint it and hide follow up errors *using* the local. - let _ = self.demand_eqtype_pat(pat.span, eq_ty, local_ty, ti); + let _ = self.demand_eqtype_pat(pat.span, eq_ty, local_ty, &ti); // If there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be. if var_id != pat.hir_id { - self.check_binding_alt_eq_ty(user_bind_annot, pat.span, var_id, local_ty, ti); + self.check_binding_alt_eq_ty(user_bind_annot, pat.span, var_id, local_ty, &ti); } if let Some(p) = sub { @@ -1149,7 +1151,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fields: &'tcx [hir::PatField<'tcx>], has_rest_pat: bool, expected: Ty<'tcx>, - pat_info: PatInfo<'_, 'tcx>, + pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { // Resolve the path and check the definition for errors. let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) { @@ -1164,7 +1166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Type-check the path. - let _ = self.demand_eqtype_pat(pat.span, expected, pat_ty, pat_info.top_info); + let _ = self.demand_eqtype_pat(pat.span, expected, pat_ty, &pat_info.top_info); // Type-check subpatterns. match self.check_struct_pat_fields(pat_ty, pat, variant, fields, has_rest_pat, pat_info) { @@ -1353,7 +1355,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { subpats: &'tcx [Pat<'tcx>], ddpos: hir::DotDotPos, expected: Ty<'tcx>, - pat_info: PatInfo<'_, 'tcx>, + pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; let on_error = |e| { @@ -1403,7 +1405,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pat_ty = pat_ty.no_bound_vars().expect("expected fn type"); // Type-check the tuple struct pattern against the expected type. - let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, pat_info.top_info); + let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, &pat_info.top_info); let had_err = diag.map_err(|diag| diag.emit()); // Type-check subpatterns. @@ -1610,7 +1612,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { elements: &'tcx [Pat<'tcx>], ddpos: hir::DotDotPos, expected: Ty<'tcx>, - pat_info: PatInfo<'_, 'tcx>, + pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; let mut expected_len = elements.len(); @@ -1625,7 +1627,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let element_tys_iter = (0..max_len).map(|_| self.next_ty_var(span)); let element_tys = tcx.mk_type_list_from_iter(element_tys_iter); let pat_ty = Ty::new_tup(tcx, element_tys); - if let Err(reported) = self.demand_eqtype_pat(span, expected, pat_ty, pat_info.top_info) { + if let Err(reported) = self.demand_eqtype_pat(span, expected, pat_ty, &pat_info.top_info) { // Walk subpatterns with an expected type of `err` in this case to silence // further errors being emitted when using the bindings. #50333 let element_tys_iter = (0..max_len).map(|_| Ty::new_error(tcx, reported)); @@ -1648,7 +1650,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { variant: &'tcx ty::VariantDef, fields: &'tcx [hir::PatField<'tcx>], has_rest_pat: bool, - pat_info: PatInfo<'_, 'tcx>, + pat_info: PatInfo<'tcx>, ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx; @@ -2257,7 +2259,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, inner: &'tcx Pat<'tcx>, expected: Ty<'tcx>, - pat_info: PatInfo<'_, 'tcx>, + pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; let (box_ty, inner_ty) = self @@ -2267,7 +2269,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // think any errors can be introduced by using `demand::eqtype`. let inner_ty = self.next_ty_var(inner.span); let box_ty = Ty::new_box(tcx, inner_ty); - self.demand_eqtype_pat(span, expected, box_ty, pat_info.top_info)?; + self.demand_eqtype_pat(span, expected, box_ty, &pat_info.top_info)?; Ok((box_ty, inner_ty)) }) .unwrap_or_else(|guar| { @@ -2283,7 +2285,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, inner: &'tcx Pat<'tcx>, expected: Ty<'tcx>, - pat_info: PatInfo<'_, 'tcx>, + pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; // Register a `DerefPure` bound, which is required by all `deref!()` pats. @@ -2324,7 +2326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inner: &'tcx Pat<'tcx>, pat_mutbl: Mutability, mut expected: Ty<'tcx>, - mut pat_info: PatInfo<'_, 'tcx>, + mut pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; @@ -2482,7 +2484,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat.span, expected, ref_ty, - pat_info.top_info, + &pat_info.top_info, ); // Look for a case like `fn foo(&foo: u32)` and suggest @@ -2605,7 +2607,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { slice: Option<&'tcx Pat<'tcx>>, after: &'tcx [Pat<'tcx>], expected: Ty<'tcx>, - pat_info: PatInfo<'_, 'tcx>, + pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { let expected = self.try_structurally_resolve_type(span, expected); @@ -2767,7 +2769,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, span: Span, expected_ty: Ty<'tcx>, - pat_info: PatInfo<'_, 'tcx>, + pat_info: PatInfo<'tcx>, ) -> ErrorGuaranteed { let PatInfo { top_info: ti, current_depth, .. } = pat_info; From cf318a79d678bf8beec26a547b384975de5039b1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 12 Mar 2025 08:03:54 +0100 Subject: [PATCH 985/991] intrinsics: remove unnecessary leading underscore from argument names --- .../example/mini_core.rs | 16 +- .../rustc_codegen_gcc/example/mini_core.rs | 16 +- library/alloc/src/boxed.rs | 2 +- library/core/src/ffi/va_list.rs | 6 +- library/core/src/intrinsics/mod.rs | 499 +++++++++--------- library/core/src/intrinsics/simd.rs | 136 ++--- .../tests/fail/intrinsics/copy_overlapping.rs | 2 +- .../tests/fail/intrinsics/copy_unaligned.rs | 2 +- .../tests/fail/intrinsics/ctlz_nonzero.rs | 2 +- .../tests/fail/intrinsics/cttz_nonzero.rs | 2 +- .../fail/intrinsics/float_to_int_32_inf1.rs | 2 +- .../intrinsics/float_to_int_32_infneg1.rs | 2 +- .../fail/intrinsics/float_to_int_32_nan.rs | 2 +- .../fail/intrinsics/float_to_int_32_nanneg.rs | 2 +- .../fail/intrinsics/float_to_int_32_neg.rs | 2 +- .../intrinsics/float_to_int_32_too_big1.rs | 2 +- .../intrinsics/float_to_int_32_too_big2.rs | 2 +- .../intrinsics/float_to_int_32_too_small1.rs | 2 +- .../fail/intrinsics/float_to_int_64_inf1.rs | 2 +- .../intrinsics/float_to_int_64_infneg1.rs | 2 +- .../intrinsics/float_to_int_64_infneg2.rs | 2 +- .../fail/intrinsics/float_to_int_64_nan.rs | 2 +- .../fail/intrinsics/float_to_int_64_neg.rs | 2 +- .../intrinsics/float_to_int_64_too_big1.rs | 2 +- .../intrinsics/float_to_int_64_too_big2.rs | 2 +- .../intrinsics/float_to_int_64_too_big3.rs | 2 +- .../intrinsics/float_to_int_64_too_big4.rs | 2 +- .../intrinsics/float_to_int_64_too_big5.rs | 2 +- .../intrinsics/float_to_int_64_too_big6.rs | 2 +- .../intrinsics/float_to_int_64_too_big7.rs | 2 +- .../intrinsics/float_to_int_64_too_small1.rs | 2 +- .../intrinsics/float_to_int_64_too_small2.rs | 2 +- .../intrinsics/float_to_int_64_too_small3.rs | 2 +- .../tests/pass/intrinsics/portable-simd.rs | 2 +- 34 files changed, 362 insertions(+), 369 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 72c9df59d833..6e345b2a6fdf 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -624,25 +624,25 @@ pub mod intrinsics { #[rustc_intrinsic] pub fn size_of() -> usize; #[rustc_intrinsic] - pub unsafe fn size_of_val(_val: *const T) -> usize; + pub unsafe fn size_of_val(val: *const T) -> usize; #[rustc_intrinsic] pub fn min_align_of() -> usize; #[rustc_intrinsic] - pub unsafe fn min_align_of_val(_val: *const T) -> usize; + pub unsafe fn min_align_of_val(val: *const T) -> usize; #[rustc_intrinsic] - pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize); + pub unsafe fn copy(src: *const T, dst: *mut T, count: usize); #[rustc_intrinsic] - pub unsafe fn transmute(_e: T) -> U; + pub unsafe fn transmute(e: T) -> U; #[rustc_intrinsic] - pub unsafe fn ctlz_nonzero(_x: T) -> u32; + pub unsafe fn ctlz_nonzero(x: T) -> u32; #[rustc_intrinsic] pub fn needs_drop() -> bool; #[rustc_intrinsic] - pub fn bitreverse(_x: T) -> T; + pub fn bitreverse(x: T) -> T; #[rustc_intrinsic] - pub fn bswap(_x: T) -> T; + pub fn bswap(x: T) -> T; #[rustc_intrinsic] - pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize); + pub unsafe fn write_bytes(dst: *mut T, val: u8, count: usize); #[rustc_intrinsic] pub unsafe fn unreachable() -> !; } diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index 3dad35bc4ce4..5544aee9eaf1 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -595,25 +595,25 @@ pub mod intrinsics { #[rustc_intrinsic] pub fn size_of() -> usize; #[rustc_intrinsic] - pub unsafe fn size_of_val(_val: *const T) -> usize; + pub unsafe fn size_of_val(val: *const T) -> usize; #[rustc_intrinsic] pub fn min_align_of() -> usize; #[rustc_intrinsic] - pub unsafe fn min_align_of_val(_val: *const T) -> usize; + pub unsafe fn min_align_of_val(val: *const T) -> usize; #[rustc_intrinsic] - pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize); + pub unsafe fn copy(src: *const T, dst: *mut T, count: usize); #[rustc_intrinsic] - pub unsafe fn transmute(_e: T) -> U; + pub unsafe fn transmute(e: T) -> U; #[rustc_intrinsic] - pub unsafe fn ctlz_nonzero(_x: T) -> u32; + pub unsafe fn ctlz_nonzero(x: T) -> u32; #[rustc_intrinsic] pub fn needs_drop() -> bool; #[rustc_intrinsic] - pub fn bitreverse(_x: T) -> T; + pub fn bitreverse(x: T) -> T; #[rustc_intrinsic] - pub fn bswap(_x: T) -> T; + pub fn bswap(x: T) -> T; #[rustc_intrinsic] - pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize); + pub unsafe fn write_bytes(dst: *mut T, val: u8, count: usize); #[rustc_intrinsic] pub unsafe fn unreachable() -> !; } diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 9b19ab74edfd..e77caad65401 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -239,7 +239,7 @@ pub struct Box< /// This is the surface syntax for `box ` expressions. #[rustc_intrinsic] #[unstable(feature = "liballoc_internals", issue = "none")] -pub fn box_new(_x: T) -> Box; +pub fn box_new(x: T) -> Box; impl Box { /// Allocates memory on the heap and then places `x` into it. diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index cefa0e3950ca..1ad8038cbf6e 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -306,15 +306,15 @@ impl<'f> Drop for VaListImpl<'f> { /// `va_copy`. #[rustc_intrinsic] #[rustc_nounwind] -unsafe fn va_end(_ap: &mut VaListImpl<'_>); +unsafe fn va_end(ap: &mut VaListImpl<'_>); /// Copies the current location of arglist `src` to the arglist `dst`. #[rustc_intrinsic] #[rustc_nounwind] -unsafe fn va_copy<'f>(_dest: *mut VaListImpl<'f>, _src: &VaListImpl<'f>); +unsafe fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>); /// Loads an argument of type `T` from the `va_list` `ap` and increment the /// argument `ap` points to. #[rustc_intrinsic] #[rustc_nounwind] -unsafe fn va_arg(_ap: &mut VaListImpl<'_>) -> T; +unsafe fn va_arg(ap: &mut VaListImpl<'_>) -> T; diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 6af647b137da..ead7b2d29655 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -97,7 +97,7 @@ pub unsafe fn drop_in_place(to_drop: *mut T) { /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_relaxed_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_relaxed_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -106,7 +106,7 @@ pub unsafe fn atomic_cxchg_relaxed_relaxed(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_relaxed_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_relaxed_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -115,7 +115,7 @@ pub unsafe fn atomic_cxchg_relaxed_acquire(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_relaxed_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_relaxed_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -124,7 +124,7 @@ pub unsafe fn atomic_cxchg_relaxed_seqcst(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acquire_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_acquire_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -133,7 +133,7 @@ pub unsafe fn atomic_cxchg_acquire_relaxed(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acquire_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -142,7 +142,7 @@ pub unsafe fn atomic_cxchg_acquire_acquire(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acquire_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_acquire_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -151,7 +151,7 @@ pub unsafe fn atomic_cxchg_acquire_seqcst(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_release_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -160,7 +160,7 @@ pub unsafe fn atomic_cxchg_release_relaxed(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_release_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_release_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -169,7 +169,7 @@ pub unsafe fn atomic_cxchg_release_acquire(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_release_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_release_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -178,7 +178,7 @@ pub unsafe fn atomic_cxchg_release_seqcst(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acqrel_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_acqrel_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -187,7 +187,7 @@ pub unsafe fn atomic_cxchg_acqrel_relaxed(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acqrel_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_acqrel_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -196,7 +196,7 @@ pub unsafe fn atomic_cxchg_acqrel_acquire(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acqrel_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_acqrel_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -205,7 +205,7 @@ pub unsafe fn atomic_cxchg_acqrel_seqcst(_dst: *mut T, _old: T, _src: T /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_seqcst_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_seqcst_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -214,7 +214,7 @@ pub unsafe fn atomic_cxchg_seqcst_relaxed(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_seqcst_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_seqcst_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -223,7 +223,7 @@ pub unsafe fn atomic_cxchg_seqcst_acquire(_dst: *mut T, _old: T, _src: /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_seqcst_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchg_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// @@ -259,8 +259,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_acquire( /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_relaxed_seqcst(_dst: *mut T, _old: T, _src: T) --> (T, bool); +pub unsafe fn atomic_cxchgweak_relaxed_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -295,8 +294,7 @@ pub unsafe fn atomic_cxchgweak_acquire_acquire( /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acquire_seqcst(_dst: *mut T, _old: T, _src: T) --> (T, bool); +pub unsafe fn atomic_cxchgweak_acquire_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -331,8 +329,7 @@ pub unsafe fn atomic_cxchgweak_release_acquire( /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_release_seqcst(_dst: *mut T, _old: T, _src: T) --> (T, bool); +pub unsafe fn atomic_cxchgweak_release_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -341,8 +338,7 @@ pub unsafe fn atomic_cxchgweak_release_seqcst(_dst: *mut T, _old: T, _s /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acqrel_relaxed(_dst: *mut T, _old: T, _src: T) --> (T, bool); +pub unsafe fn atomic_cxchgweak_acqrel_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -351,8 +347,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_relaxed(_dst: *mut T, _old: T, _s /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acqrel_acquire(_dst: *mut T, _old: T, _src: T) --> (T, bool); +pub unsafe fn atomic_cxchgweak_acqrel_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -361,7 +356,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_acquire(_dst: *mut T, _old: T, _s /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acqrel_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchgweak_acqrel_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -370,8 +365,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_seqcst(_dst: *mut T, _old: T, _sr /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_seqcst_relaxed(_dst: *mut T, _old: T, _src: T) --> (T, bool); +pub unsafe fn atomic_cxchgweak_seqcst_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -380,8 +374,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_relaxed(_dst: *mut T, _old: T, _s /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_seqcst_acquire(_dst: *mut T, _old: T, _src: T) --> (T, bool); +pub unsafe fn atomic_cxchgweak_seqcst_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -390,7 +383,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_acquire(_dst: *mut T, _old: T, _s /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_seqcst_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); +pub unsafe fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Loads the current value of the pointer. /// @@ -399,7 +392,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_seqcst(_dst: *mut T, _old: T, _sr /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_load_seqcst(_src: *const T) -> T; +pub unsafe fn atomic_load_seqcst(src: *const T) -> T; /// Loads the current value of the pointer. /// /// The stabilized version of this intrinsic is available on the @@ -407,7 +400,7 @@ pub unsafe fn atomic_load_seqcst(_src: *const T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_load_acquire(_src: *const T) -> T; +pub unsafe fn atomic_load_acquire(src: *const T) -> T; /// Loads the current value of the pointer. /// /// The stabilized version of this intrinsic is available on the @@ -415,13 +408,13 @@ pub unsafe fn atomic_load_acquire(_src: *const T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_load_relaxed(_src: *const T) -> T; +pub unsafe fn atomic_load_relaxed(src: *const T) -> T; /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model! /// In terms of the Rust Abstract Machine, this operation is equivalent to `src.read()`, /// i.e., it performs a non-atomic read. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_load_unordered(_src: *const T) -> T; +pub unsafe fn atomic_load_unordered(src: *const T) -> T; /// Stores the value at the specified memory location. /// @@ -430,7 +423,7 @@ pub unsafe fn atomic_load_unordered(_src: *const T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_store_seqcst(_dst: *mut T, _val: T); +pub unsafe fn atomic_store_seqcst(dst: *mut T, val: T); /// Stores the value at the specified memory location. /// /// The stabilized version of this intrinsic is available on the @@ -438,7 +431,7 @@ pub unsafe fn atomic_store_seqcst(_dst: *mut T, _val: T); /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_store_release(_dst: *mut T, _val: T); +pub unsafe fn atomic_store_release(dst: *mut T, val: T); /// Stores the value at the specified memory location. /// /// The stabilized version of this intrinsic is available on the @@ -446,13 +439,13 @@ pub unsafe fn atomic_store_release(_dst: *mut T, _val: T); /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::store`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_store_relaxed(_dst: *mut T, _val: T); +pub unsafe fn atomic_store_relaxed(dst: *mut T, val: T); /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model! /// In terms of the Rust Abstract Machine, this operation is equivalent to `dst.write(val)`, /// i.e., it performs a non-atomic write. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_store_unordered(_dst: *mut T, _val: T); +pub unsafe fn atomic_store_unordered(dst: *mut T, val: T); /// Stores the value at the specified memory location, returning the old value. /// @@ -461,7 +454,7 @@ pub unsafe fn atomic_store_unordered(_dst: *mut T, _val: T); /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xchg_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T; /// Stores the value at the specified memory location, returning the old value. /// /// The stabilized version of this intrinsic is available on the @@ -469,7 +462,7 @@ pub unsafe fn atomic_xchg_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xchg_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xchg_acquire(dst: *mut T, src: T) -> T; /// Stores the value at the specified memory location, returning the old value. /// /// The stabilized version of this intrinsic is available on the @@ -477,7 +470,7 @@ pub unsafe fn atomic_xchg_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xchg_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xchg_release(dst: *mut T, src: T) -> T; /// Stores the value at the specified memory location, returning the old value. /// /// The stabilized version of this intrinsic is available on the @@ -485,7 +478,7 @@ pub unsafe fn atomic_xchg_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xchg_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xchg_acqrel(dst: *mut T, src: T) -> T; /// Stores the value at the specified memory location, returning the old value. /// /// The stabilized version of this intrinsic is available on the @@ -493,7 +486,7 @@ pub unsafe fn atomic_xchg_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xchg_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xchg_relaxed(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. /// @@ -502,7 +495,7 @@ pub unsafe fn atomic_xchg_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xadd_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -510,7 +503,7 @@ pub unsafe fn atomic_xadd_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xadd_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xadd_acquire(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -518,7 +511,7 @@ pub unsafe fn atomic_xadd_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xadd_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xadd_release(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -526,7 +519,7 @@ pub unsafe fn atomic_xadd_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xadd_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xadd_acqrel(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -534,7 +527,7 @@ pub unsafe fn atomic_xadd_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xadd_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xadd_relaxed(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. /// @@ -543,7 +536,7 @@ pub unsafe fn atomic_xadd_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xsub_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xsub_seqcst(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -551,7 +544,7 @@ pub unsafe fn atomic_xsub_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xsub_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xsub_acquire(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -559,7 +552,7 @@ pub unsafe fn atomic_xsub_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xsub_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xsub_release(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -567,7 +560,7 @@ pub unsafe fn atomic_xsub_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xsub_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xsub_acqrel(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -575,7 +568,7 @@ pub unsafe fn atomic_xsub_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xsub_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xsub_relaxed(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// @@ -584,7 +577,7 @@ pub unsafe fn atomic_xsub_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_and_seqcst(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -592,7 +585,7 @@ pub unsafe fn atomic_and_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_and_acquire(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -600,7 +593,7 @@ pub unsafe fn atomic_and_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_and_release(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -608,7 +601,7 @@ pub unsafe fn atomic_and_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_and_acqrel(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -616,7 +609,7 @@ pub unsafe fn atomic_and_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_and_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_and_relaxed(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// @@ -625,7 +618,7 @@ pub unsafe fn atomic_and_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_nand_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_nand_seqcst(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -633,7 +626,7 @@ pub unsafe fn atomic_nand_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_nand_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_nand_acquire(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -641,7 +634,7 @@ pub unsafe fn atomic_nand_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_nand_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_nand_release(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -649,7 +642,7 @@ pub unsafe fn atomic_nand_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_nand_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_nand_acqrel(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -657,7 +650,7 @@ pub unsafe fn atomic_nand_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_nand_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_nand_relaxed(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// @@ -666,7 +659,7 @@ pub unsafe fn atomic_nand_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_or_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_or_seqcst(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -674,7 +667,7 @@ pub unsafe fn atomic_or_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_or_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_or_acquire(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -682,7 +675,7 @@ pub unsafe fn atomic_or_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_or_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_or_release(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -690,7 +683,7 @@ pub unsafe fn atomic_or_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_or_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_or_acqrel(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -698,7 +691,7 @@ pub unsafe fn atomic_or_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_or_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_or_relaxed(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// @@ -707,7 +700,7 @@ pub unsafe fn atomic_or_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xor_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xor_seqcst(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -715,7 +708,7 @@ pub unsafe fn atomic_xor_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xor_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xor_acquire(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -723,7 +716,7 @@ pub unsafe fn atomic_xor_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xor_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xor_release(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -731,7 +724,7 @@ pub unsafe fn atomic_xor_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xor_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xor_acqrel(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the @@ -739,7 +732,7 @@ pub unsafe fn atomic_xor_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_xor_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_xor_relaxed(dst: *mut T, src: T) -> T; /// Maximum with the current value using a signed comparison. /// @@ -748,7 +741,7 @@ pub unsafe fn atomic_xor_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_max_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_max_seqcst(dst: *mut T, src: T) -> T; /// Maximum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the @@ -756,7 +749,7 @@ pub unsafe fn atomic_max_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_max_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_max_acquire(dst: *mut T, src: T) -> T; /// Maximum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the @@ -764,7 +757,7 @@ pub unsafe fn atomic_max_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_max_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_max_release(dst: *mut T, src: T) -> T; /// Maximum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the @@ -772,7 +765,7 @@ pub unsafe fn atomic_max_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_max_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_max_acqrel(dst: *mut T, src: T) -> T; /// Maximum with the current value. /// /// The stabilized version of this intrinsic is available on the @@ -780,7 +773,7 @@ pub unsafe fn atomic_max_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_max_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_max_relaxed(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. /// @@ -789,7 +782,7 @@ pub unsafe fn atomic_max_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_min_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_min_seqcst(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the @@ -797,7 +790,7 @@ pub unsafe fn atomic_min_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_min_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_min_acquire(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the @@ -805,7 +798,7 @@ pub unsafe fn atomic_min_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_min_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_min_release(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the @@ -813,7 +806,7 @@ pub unsafe fn atomic_min_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_min_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_min_acqrel(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the @@ -821,7 +814,7 @@ pub unsafe fn atomic_min_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_min_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_min_relaxed(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// @@ -830,7 +823,7 @@ pub unsafe fn atomic_min_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umin_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umin_seqcst(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the @@ -838,7 +831,7 @@ pub unsafe fn atomic_umin_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umin_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umin_acquire(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the @@ -846,7 +839,7 @@ pub unsafe fn atomic_umin_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umin_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umin_release(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the @@ -854,7 +847,7 @@ pub unsafe fn atomic_umin_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umin_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umin_acqrel(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the @@ -862,7 +855,7 @@ pub unsafe fn atomic_umin_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umin_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umin_relaxed(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// @@ -871,7 +864,7 @@ pub unsafe fn atomic_umin_relaxed(_dst: *mut T, _src: T) -> T; /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umax_seqcst(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umax_seqcst(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the @@ -879,7 +872,7 @@ pub unsafe fn atomic_umax_seqcst(_dst: *mut T, _src: T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umax_acquire(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umax_acquire(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the @@ -887,7 +880,7 @@ pub unsafe fn atomic_umax_acquire(_dst: *mut T, _src: T) -> T; /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umax_release(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umax_release(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the @@ -895,7 +888,7 @@ pub unsafe fn atomic_umax_release(_dst: *mut T, _src: T) -> T; /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umax_acqrel(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umax_acqrel(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the @@ -903,7 +896,7 @@ pub unsafe fn atomic_umax_acqrel(_dst: *mut T, _src: T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn atomic_umax_relaxed(_dst: *mut T, _src: T) -> T; +pub unsafe fn atomic_umax_relaxed(dst: *mut T, src: T) -> T; /// An atomic fence. /// @@ -1002,7 +995,7 @@ pub unsafe fn atomic_singlethreadfence_acqrel(); /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn prefetch_read_data(_data: *const T, _locality: i32); +pub unsafe fn prefetch_read_data(data: *const T, locality: i32); /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction /// if supported; otherwise, it is a no-op. /// Prefetches have no effect on the behavior of the program but can change its performance @@ -1014,7 +1007,7 @@ pub unsafe fn prefetch_read_data(_data: *const T, _locality: i32); /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn prefetch_write_data(_data: *const T, _locality: i32); +pub unsafe fn prefetch_write_data(data: *const T, locality: i32); /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction /// if supported; otherwise, it is a no-op. /// Prefetches have no effect on the behavior of the program but can change its performance @@ -1026,7 +1019,7 @@ pub unsafe fn prefetch_write_data(_data: *const T, _locality: i32); /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn prefetch_read_instruction(_data: *const T, _locality: i32); +pub unsafe fn prefetch_read_instruction(data: *const T, locality: i32); /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction /// if supported; otherwise, it is a no-op. /// Prefetches have no effect on the behavior of the program but can change its performance @@ -1038,7 +1031,7 @@ pub unsafe fn prefetch_read_instruction(_data: *const T, _locality: i32); /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn prefetch_write_instruction(_data: *const T, _locality: i32); +pub unsafe fn prefetch_write_instruction(data: *const T, locality: i32); /// Executes a breakpoint trap, for inspection by a debugger. /// @@ -1539,7 +1532,7 @@ pub const fn forget(_: T); #[rustc_diagnostic_item = "transmute"] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn transmute(_src: Src) -> Dst; +pub const unsafe fn transmute(src: Src) -> Dst; /// Like [`transmute`], but even less checked at compile-time: rather than /// giving an error for `size_of::() != size_of::()`, it's @@ -1553,7 +1546,7 @@ pub const unsafe fn transmute(_src: Src) -> Dst; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn transmute_unchecked(_src: Src) -> Dst; +pub const unsafe fn transmute_unchecked(src: Src) -> Dst; /// Returns `true` if the actual type given as `T` requires drop /// glue; returns `false` if the actual type provided for `T` @@ -1593,7 +1586,7 @@ pub const fn needs_drop() -> bool; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn offset(_dst: Ptr, _offset: Delta) -> Ptr; +pub const unsafe fn offset(dst: Ptr, offset: Delta) -> Ptr; /// Calculates the offset from a pointer, potentially wrapping. /// @@ -1612,7 +1605,7 @@ pub const unsafe fn offset(_dst: Ptr, _offset: Delta) -> Ptr; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn arith_offset(_dst: *const T, _offset: isize) -> *const T; +pub const unsafe fn arith_offset(dst: *const T, offset: isize) -> *const T; /// Masks out bits of the pointer according to a mask. /// @@ -1624,7 +1617,7 @@ pub const unsafe fn arith_offset(_dst: *const T, _offset: isize) -> *const T; /// Consider using [`pointer::mask`] instead. #[rustc_nounwind] #[rustc_intrinsic] -pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T; +pub fn ptr_mask(ptr: *const T, mask: usize) -> *const T; /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::()` and an alignment of @@ -1636,7 +1629,7 @@ pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn volatile_copy_nonoverlapping_memory(_dst: *mut T, _src: *const T, _count: usize); +pub unsafe fn volatile_copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with /// a size of `count * size_of::()` and an alignment of /// `min_align_of::()` @@ -1647,7 +1640,7 @@ pub unsafe fn volatile_copy_nonoverlapping_memory(_dst: *mut T, _src: *const /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn volatile_copy_memory(_dst: *mut T, _src: *const T, _count: usize); +pub unsafe fn volatile_copy_memory(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a /// size of `count * size_of::()` and an alignment of /// `min_align_of::()`. @@ -1658,20 +1651,20 @@ pub unsafe fn volatile_copy_memory(_dst: *mut T, _src: *const T, _count: usiz /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn volatile_set_memory(_dst: *mut T, _val: u8, _count: usize); +pub unsafe fn volatile_set_memory(dst: *mut T, val: u8, count: usize); /// Performs a volatile load from the `src` pointer. /// /// The stabilized version of this intrinsic is [`core::ptr::read_volatile`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn volatile_load(_src: *const T) -> T; +pub unsafe fn volatile_load(src: *const T) -> T; /// Performs a volatile store to the `dst` pointer. /// /// The stabilized version of this intrinsic is [`core::ptr::write_volatile`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn volatile_store(_dst: *mut T, _val: T); +pub unsafe fn volatile_store(dst: *mut T, val: T); /// Performs a volatile load from the `src` pointer /// The pointer is not required to be aligned. @@ -1680,7 +1673,7 @@ pub unsafe fn volatile_store(_dst: *mut T, _val: T); #[rustc_intrinsic] #[rustc_nounwind] #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"] -pub unsafe fn unaligned_volatile_load(_src: *const T) -> T; +pub unsafe fn unaligned_volatile_load(src: *const T) -> T; /// Performs a volatile store to the `dst` pointer. /// The pointer is not required to be aligned. /// @@ -1688,7 +1681,7 @@ pub unsafe fn unaligned_volatile_load(_src: *const T) -> T; #[rustc_intrinsic] #[rustc_nounwind] #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"] -pub unsafe fn unaligned_volatile_store(_dst: *mut T, _val: T); +pub unsafe fn unaligned_volatile_store(dst: *mut T, val: T); /// Returns the square root of an `f16` /// @@ -1696,28 +1689,28 @@ pub unsafe fn unaligned_volatile_store(_dst: *mut T, _val: T); /// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn sqrtf16(_x: f16) -> f16; +pub unsafe fn sqrtf16(x: f16) -> f16; /// Returns the square root of an `f32` /// /// The stabilized version of this intrinsic is /// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn sqrtf32(_x: f32) -> f32; +pub unsafe fn sqrtf32(x: f32) -> f32; /// Returns the square root of an `f64` /// /// The stabilized version of this intrinsic is /// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn sqrtf64(_x: f64) -> f64; +pub unsafe fn sqrtf64(x: f64) -> f64; /// Returns the square root of an `f128` /// /// The stabilized version of this intrinsic is /// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn sqrtf128(_x: f128) -> f128; +pub unsafe fn sqrtf128(x: f128) -> f128; /// Raises an `f16` to an integer power. /// @@ -1725,28 +1718,28 @@ pub unsafe fn sqrtf128(_x: f128) -> f128; /// [`f16::powi`](../../std/primitive.f16.html#method.powi) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn powif16(_a: f16, _x: i32) -> f16; +pub unsafe fn powif16(a: f16, x: i32) -> f16; /// Raises an `f32` to an integer power. /// /// The stabilized version of this intrinsic is /// [`f32::powi`](../../std/primitive.f32.html#method.powi) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn powif32(_a: f32, _x: i32) -> f32; +pub unsafe fn powif32(a: f32, x: i32) -> f32; /// Raises an `f64` to an integer power. /// /// The stabilized version of this intrinsic is /// [`f64::powi`](../../std/primitive.f64.html#method.powi) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn powif64(_a: f64, _x: i32) -> f64; +pub unsafe fn powif64(a: f64, x: i32) -> f64; /// Raises an `f128` to an integer power. /// /// The stabilized version of this intrinsic is /// [`f128::powi`](../../std/primitive.f128.html#method.powi) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn powif128(_a: f128, _x: i32) -> f128; +pub unsafe fn powif128(a: f128, x: i32) -> f128; /// Returns the sine of an `f16`. /// @@ -1754,28 +1747,28 @@ pub unsafe fn powif128(_a: f128, _x: i32) -> f128; /// [`f16::sin`](../../std/primitive.f16.html#method.sin) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn sinf16(_x: f16) -> f16; +pub unsafe fn sinf16(x: f16) -> f16; /// Returns the sine of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::sin`](../../std/primitive.f32.html#method.sin) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn sinf32(_x: f32) -> f32; +pub unsafe fn sinf32(x: f32) -> f32; /// Returns the sine of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::sin`](../../std/primitive.f64.html#method.sin) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn sinf64(_x: f64) -> f64; +pub unsafe fn sinf64(x: f64) -> f64; /// Returns the sine of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::sin`](../../std/primitive.f128.html#method.sin) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn sinf128(_x: f128) -> f128; +pub unsafe fn sinf128(x: f128) -> f128; /// Returns the cosine of an `f16`. /// @@ -1783,28 +1776,28 @@ pub unsafe fn sinf128(_x: f128) -> f128; /// [`f16::cos`](../../std/primitive.f16.html#method.cos) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn cosf16(_x: f16) -> f16; +pub unsafe fn cosf16(x: f16) -> f16; /// Returns the cosine of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::cos`](../../std/primitive.f32.html#method.cos) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn cosf32(_x: f32) -> f32; +pub unsafe fn cosf32(x: f32) -> f32; /// Returns the cosine of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::cos`](../../std/primitive.f64.html#method.cos) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn cosf64(_x: f64) -> f64; +pub unsafe fn cosf64(x: f64) -> f64; /// Returns the cosine of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::cos`](../../std/primitive.f128.html#method.cos) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn cosf128(_x: f128) -> f128; +pub unsafe fn cosf128(x: f128) -> f128; /// Raises an `f16` to an `f16` power. /// @@ -1812,28 +1805,28 @@ pub unsafe fn cosf128(_x: f128) -> f128; /// [`f16::powf`](../../std/primitive.f16.html#method.powf) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn powf16(_a: f16, _x: f16) -> f16; +pub unsafe fn powf16(a: f16, x: f16) -> f16; /// Raises an `f32` to an `f32` power. /// /// The stabilized version of this intrinsic is /// [`f32::powf`](../../std/primitive.f32.html#method.powf) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn powf32(_a: f32, _x: f32) -> f32; +pub unsafe fn powf32(a: f32, x: f32) -> f32; /// Raises an `f64` to an `f64` power. /// /// The stabilized version of this intrinsic is /// [`f64::powf`](../../std/primitive.f64.html#method.powf) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn powf64(_a: f64, _x: f64) -> f64; +pub unsafe fn powf64(a: f64, x: f64) -> f64; /// Raises an `f128` to an `f128` power. /// /// The stabilized version of this intrinsic is /// [`f128::powf`](../../std/primitive.f128.html#method.powf) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn powf128(_a: f128, _x: f128) -> f128; +pub unsafe fn powf128(a: f128, x: f128) -> f128; /// Returns the exponential of an `f16`. /// @@ -1841,28 +1834,28 @@ pub unsafe fn powf128(_a: f128, _x: f128) -> f128; /// [`f16::exp`](../../std/primitive.f16.html#method.exp) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn expf16(_x: f16) -> f16; +pub unsafe fn expf16(x: f16) -> f16; /// Returns the exponential of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::exp`](../../std/primitive.f32.html#method.exp) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn expf32(_x: f32) -> f32; +pub unsafe fn expf32(x: f32) -> f32; /// Returns the exponential of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::exp`](../../std/primitive.f64.html#method.exp) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn expf64(_x: f64) -> f64; +pub unsafe fn expf64(x: f64) -> f64; /// Returns the exponential of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::exp`](../../std/primitive.f128.html#method.exp) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn expf128(_x: f128) -> f128; +pub unsafe fn expf128(x: f128) -> f128; /// Returns 2 raised to the power of an `f16`. /// @@ -1870,28 +1863,28 @@ pub unsafe fn expf128(_x: f128) -> f128; /// [`f16::exp2`](../../std/primitive.f16.html#method.exp2) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn exp2f16(_x: f16) -> f16; +pub unsafe fn exp2f16(x: f16) -> f16; /// Returns 2 raised to the power of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::exp2`](../../std/primitive.f32.html#method.exp2) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn exp2f32(_x: f32) -> f32; +pub unsafe fn exp2f32(x: f32) -> f32; /// Returns 2 raised to the power of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::exp2`](../../std/primitive.f64.html#method.exp2) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn exp2f64(_x: f64) -> f64; +pub unsafe fn exp2f64(x: f64) -> f64; /// Returns 2 raised to the power of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::exp2`](../../std/primitive.f128.html#method.exp2) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn exp2f128(_x: f128) -> f128; +pub unsafe fn exp2f128(x: f128) -> f128; /// Returns the natural logarithm of an `f16`. /// @@ -1899,28 +1892,28 @@ pub unsafe fn exp2f128(_x: f128) -> f128; /// [`f16::ln`](../../std/primitive.f16.html#method.ln) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn logf16(_x: f16) -> f16; +pub unsafe fn logf16(x: f16) -> f16; /// Returns the natural logarithm of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::ln`](../../std/primitive.f32.html#method.ln) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn logf32(_x: f32) -> f32; +pub unsafe fn logf32(x: f32) -> f32; /// Returns the natural logarithm of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::ln`](../../std/primitive.f64.html#method.ln) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn logf64(_x: f64) -> f64; +pub unsafe fn logf64(x: f64) -> f64; /// Returns the natural logarithm of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::ln`](../../std/primitive.f128.html#method.ln) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn logf128(_x: f128) -> f128; +pub unsafe fn logf128(x: f128) -> f128; /// Returns the base 10 logarithm of an `f16`. /// @@ -1928,28 +1921,28 @@ pub unsafe fn logf128(_x: f128) -> f128; /// [`f16::log10`](../../std/primitive.f16.html#method.log10) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn log10f16(_x: f16) -> f16; +pub unsafe fn log10f16(x: f16) -> f16; /// Returns the base 10 logarithm of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::log10`](../../std/primitive.f32.html#method.log10) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn log10f32(_x: f32) -> f32; +pub unsafe fn log10f32(x: f32) -> f32; /// Returns the base 10 logarithm of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::log10`](../../std/primitive.f64.html#method.log10) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn log10f64(_x: f64) -> f64; +pub unsafe fn log10f64(x: f64) -> f64; /// Returns the base 10 logarithm of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::log10`](../../std/primitive.f128.html#method.log10) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn log10f128(_x: f128) -> f128; +pub unsafe fn log10f128(x: f128) -> f128; /// Returns the base 2 logarithm of an `f16`. /// @@ -1957,28 +1950,28 @@ pub unsafe fn log10f128(_x: f128) -> f128; /// [`f16::log2`](../../std/primitive.f16.html#method.log2) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn log2f16(_x: f16) -> f16; +pub unsafe fn log2f16(x: f16) -> f16; /// Returns the base 2 logarithm of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::log2`](../../std/primitive.f32.html#method.log2) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn log2f32(_x: f32) -> f32; +pub unsafe fn log2f32(x: f32) -> f32; /// Returns the base 2 logarithm of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::log2`](../../std/primitive.f64.html#method.log2) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn log2f64(_x: f64) -> f64; +pub unsafe fn log2f64(x: f64) -> f64; /// Returns the base 2 logarithm of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::log2`](../../std/primitive.f128.html#method.log2) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn log2f128(_x: f128) -> f128; +pub unsafe fn log2f128(x: f128) -> f128; /// Returns `a * b + c` for `f16` values. /// @@ -1986,28 +1979,28 @@ pub unsafe fn log2f128(_x: f128) -> f128; /// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmaf16(_a: f16, _b: f16, _c: f16) -> f16; +pub unsafe fn fmaf16(a: f16, b: f16, c: f16) -> f16; /// Returns `a * b + c` for `f32` values. /// /// The stabilized version of this intrinsic is /// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmaf32(_a: f32, _b: f32, _c: f32) -> f32; +pub unsafe fn fmaf32(a: f32, b: f32, c: f32) -> f32; /// Returns `a * b + c` for `f64` values. /// /// The stabilized version of this intrinsic is /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmaf64(_a: f64, _b: f64, _c: f64) -> f64; +pub unsafe fn fmaf64(a: f64, b: f64, c: f64) -> f64; /// Returns `a * b + c` for `f128` values. /// /// The stabilized version of this intrinsic is /// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmaf128(_a: f128, _b: f128, _c: f128) -> f128; +pub unsafe fn fmaf128(a: f128, b: f128, c: f128) -> f128; /// Returns `a * b + c` for `f16` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the @@ -2021,7 +2014,7 @@ pub unsafe fn fmaf128(_a: f128, _b: f128, _c: f128) -> f128; /// example. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmuladdf16(_a: f16, _b: f16, _c: f16) -> f16; +pub unsafe fn fmuladdf16(a: f16, b: f16, c: f16) -> f16; /// Returns `a * b + c` for `f32` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the /// intermediate result. @@ -2034,7 +2027,7 @@ pub unsafe fn fmuladdf16(_a: f16, _b: f16, _c: f16) -> f16; /// example. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmuladdf32(_a: f32, _b: f32, _c: f32) -> f32; +pub unsafe fn fmuladdf32(a: f32, b: f32, c: f32) -> f32; /// Returns `a * b + c` for `f64` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the /// intermediate result. @@ -2047,7 +2040,7 @@ pub unsafe fn fmuladdf32(_a: f32, _b: f32, _c: f32) -> f32; /// example. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmuladdf64(_a: f64, _b: f64, _c: f64) -> f64; +pub unsafe fn fmuladdf64(a: f64, b: f64, c: f64) -> f64; /// Returns `a * b + c` for `f128` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the /// intermediate result. @@ -2060,7 +2053,7 @@ pub unsafe fn fmuladdf64(_a: f64, _b: f64, _c: f64) -> f64; /// example. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmuladdf128(_a: f128, _b: f128, _c: f128) -> f128; +pub unsafe fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; /// Returns the largest integer less than or equal to an `f16`. /// @@ -2068,28 +2061,28 @@ pub unsafe fn fmuladdf128(_a: f128, _b: f128, _c: f128) -> f128; /// [`f16::floor`](../../std/primitive.f16.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf16(_x: f16) -> f16; +pub unsafe fn floorf16(x: f16) -> f16; /// Returns the largest integer less than or equal to an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::floor`](../../std/primitive.f32.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf32(_x: f32) -> f32; +pub unsafe fn floorf32(x: f32) -> f32; /// Returns the largest integer less than or equal to an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::floor`](../../std/primitive.f64.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf64(_x: f64) -> f64; +pub unsafe fn floorf64(x: f64) -> f64; /// Returns the largest integer less than or equal to an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::floor`](../../std/primitive.f128.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf128(_x: f128) -> f128; +pub unsafe fn floorf128(x: f128) -> f128; /// Returns the smallest integer greater than or equal to an `f16`. /// @@ -2097,28 +2090,28 @@ pub unsafe fn floorf128(_x: f128) -> f128; /// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf16(_x: f16) -> f16; +pub unsafe fn ceilf16(x: f16) -> f16; /// Returns the smallest integer greater than or equal to an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::ceil`](../../std/primitive.f32.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf32(_x: f32) -> f32; +pub unsafe fn ceilf32(x: f32) -> f32; /// Returns the smallest integer greater than or equal to an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf64(_x: f64) -> f64; +pub unsafe fn ceilf64(x: f64) -> f64; /// Returns the smallest integer greater than or equal to an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf128(_x: f128) -> f128; +pub unsafe fn ceilf128(x: f128) -> f128; /// Returns the integer part of an `f16`. /// @@ -2126,28 +2119,28 @@ pub unsafe fn ceilf128(_x: f128) -> f128; /// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf16(_x: f16) -> f16; +pub unsafe fn truncf16(x: f16) -> f16; /// Returns the integer part of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::trunc`](../../std/primitive.f32.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf32(_x: f32) -> f32; +pub unsafe fn truncf32(x: f32) -> f32; /// Returns the integer part of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf64(_x: f64) -> f64; +pub unsafe fn truncf64(x: f64) -> f64; /// Returns the integer part of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf128(_x: f128) -> f128; +pub unsafe fn truncf128(x: f128) -> f128; /// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2157,14 +2150,14 @@ pub unsafe fn truncf128(_x: f128) -> f128; #[rustc_intrinsic] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub fn round_ties_even_f16(_x: f16) -> f16; +pub fn round_ties_even_f16(x: f16) -> f16; /// To be removed on next bootstrap bump. #[cfg(bootstrap)] pub fn round_ties_even_f16(x: f16) -> f16 { #[rustc_intrinsic] #[rustc_nounwind] - unsafe fn rintf16(_x: f16) -> f16; + unsafe fn rintf16(x: f16) -> f16; // SAFETY: this intrinsic isn't actually unsafe unsafe { rintf16(x) } @@ -2178,14 +2171,14 @@ pub fn round_ties_even_f16(x: f16) -> f16 { #[rustc_intrinsic] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub fn round_ties_even_f32(_x: f32) -> f32; +pub fn round_ties_even_f32(x: f32) -> f32; /// To be removed on next bootstrap bump. #[cfg(bootstrap)] pub fn round_ties_even_f32(x: f32) -> f32 { #[rustc_intrinsic] #[rustc_nounwind] - unsafe fn rintf32(_x: f32) -> f32; + unsafe fn rintf32(x: f32) -> f32; // SAFETY: this intrinsic isn't actually unsafe unsafe { rintf32(x) } @@ -2205,14 +2198,14 @@ pub unsafe fn rintf32(x: f32) -> f32 { #[rustc_intrinsic] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub fn round_ties_even_f64(_x: f64) -> f64; +pub fn round_ties_even_f64(x: f64) -> f64; /// To be removed on next bootstrap bump. #[cfg(bootstrap)] pub fn round_ties_even_f64(x: f64) -> f64 { #[rustc_intrinsic] #[rustc_nounwind] - unsafe fn rintf64(_x: f64) -> f64; + unsafe fn rintf64(x: f64) -> f64; // SAFETY: this intrinsic isn't actually unsafe unsafe { rintf64(x) } @@ -2232,14 +2225,14 @@ pub unsafe fn rintf64(x: f64) -> f64 { #[rustc_intrinsic] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub fn round_ties_even_f128(_x: f128) -> f128; +pub fn round_ties_even_f128(x: f128) -> f128; /// To be removed on next bootstrap bump. #[cfg(bootstrap)] pub fn round_ties_even_f128(x: f128) -> f128 { #[rustc_intrinsic] #[rustc_nounwind] - unsafe fn rintf128(_x: f128) -> f128; + unsafe fn rintf128(x: f128) -> f128; // SAFETY: this intrinsic isn't actually unsafe unsafe { rintf128(x) } @@ -2251,28 +2244,28 @@ pub fn round_ties_even_f128(x: f128) -> f128 { /// [`f16::round`](../../std/primitive.f16.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf16(_x: f16) -> f16; +pub unsafe fn roundf16(x: f16) -> f16; /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f32::round`](../../std/primitive.f32.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf32(_x: f32) -> f32; +pub unsafe fn roundf32(x: f32) -> f32; /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f64::round`](../../std/primitive.f64.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf64(_x: f64) -> f64; +pub unsafe fn roundf64(x: f64) -> f64; /// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f128::round`](../../std/primitive.f128.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf128(_x: f128) -> f128; +pub unsafe fn roundf128(x: f128) -> f128; /// Float addition that allows optimizations based on algebraic rules. /// May assume inputs are finite. @@ -2280,7 +2273,7 @@ pub unsafe fn roundf128(_x: f128) -> f128; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fadd_fast(_a: T, _b: T) -> T; +pub unsafe fn fadd_fast(a: T, b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// May assume inputs are finite. @@ -2288,7 +2281,7 @@ pub unsafe fn fadd_fast(_a: T, _b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fsub_fast(_a: T, _b: T) -> T; +pub unsafe fn fsub_fast(a: T, b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// May assume inputs are finite. @@ -2296,7 +2289,7 @@ pub unsafe fn fsub_fast(_a: T, _b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmul_fast(_a: T, _b: T) -> T; +pub unsafe fn fmul_fast(a: T, b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// May assume inputs are finite. @@ -2304,7 +2297,7 @@ pub unsafe fn fmul_fast(_a: T, _b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fdiv_fast(_a: T, _b: T) -> T; +pub unsafe fn fdiv_fast(a: T, b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// May assume inputs are finite. @@ -2312,7 +2305,7 @@ pub unsafe fn fdiv_fast(_a: T, _b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn frem_fast(_a: T, _b: T) -> T; +pub unsafe fn frem_fast(a: T, b: T) -> T; /// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range /// () @@ -2320,42 +2313,42 @@ pub unsafe fn frem_fast(_a: T, _b: T) -> T; /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn float_to_int_unchecked(_value: Float) -> Int; +pub unsafe fn float_to_int_unchecked(value: Float) -> Int; /// Float addition that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -pub fn fadd_algebraic(_a: T, _b: T) -> T; +pub fn fadd_algebraic(a: T, b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -pub fn fsub_algebraic(_a: T, _b: T) -> T; +pub fn fsub_algebraic(a: T, b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -pub fn fmul_algebraic(_a: T, _b: T) -> T; +pub fn fmul_algebraic(a: T, b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -pub fn fdiv_algebraic(_a: T, _b: T) -> T; +pub fn fdiv_algebraic(a: T, b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -pub fn frem_algebraic(_a: T, _b: T) -> T; +pub fn frem_algebraic(a: T, b: T) -> T; /// Returns the number of bits set in an integer type `T` /// @@ -2370,7 +2363,7 @@ pub fn frem_algebraic(_a: T, _b: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn ctpop(_x: T) -> u32; +pub const fn ctpop(x: T) -> u32; /// Returns the number of leading unset bits (zeroes) in an integer type `T`. /// @@ -2411,7 +2404,7 @@ pub const fn ctpop(_x: T) -> u32; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn ctlz(_x: T) -> u32; +pub const fn ctlz(x: T) -> u32; /// Like `ctlz`, but extra-unsafe as it returns `undef` when /// given an `x` with value `0`. @@ -2433,7 +2426,7 @@ pub const fn ctlz(_x: T) -> u32; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn ctlz_nonzero(_x: T) -> u32; +pub const unsafe fn ctlz_nonzero(x: T) -> u32; /// Returns the number of trailing unset bits (zeroes) in an integer type `T`. /// @@ -2474,7 +2467,7 @@ pub const unsafe fn ctlz_nonzero(_x: T) -> u32; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn cttz(_x: T) -> u32; +pub const fn cttz(x: T) -> u32; /// Like `cttz`, but extra-unsafe as it returns `undef` when /// given an `x` with value `0`. @@ -2496,7 +2489,7 @@ pub const fn cttz(_x: T) -> u32; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn cttz_nonzero(_x: T) -> u32; +pub const unsafe fn cttz_nonzero(x: T) -> u32; /// Reverses the bytes in an integer type `T`. /// @@ -2511,7 +2504,7 @@ pub const unsafe fn cttz_nonzero(_x: T) -> u32; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn bswap(_x: T) -> T; +pub const fn bswap(x: T) -> T; /// Reverses the bits in an integer type `T`. /// @@ -2526,7 +2519,7 @@ pub const fn bswap(_x: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn bitreverse(_x: T) -> T; +pub const fn bitreverse(x: T) -> T; /// Does a three-way comparison between the two integer arguments. /// @@ -2536,7 +2529,7 @@ pub const fn bitreverse(_x: T) -> T; /// /// The stabilized version of this intrinsic is [`Ord::cmp`]. #[rustc_intrinsic] -pub const fn three_way_compare(_lhs: T, _rhss: T) -> crate::cmp::Ordering; +pub const fn three_way_compare(lhs: T, rhss: T) -> crate::cmp::Ordering; /// Combine two values which have no bits in common. /// @@ -2571,7 +2564,7 @@ pub const unsafe fn disjoint_bitor(a: T, b: T #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn add_with_overflow(_x: T, _y: T) -> (T, bool); +pub const fn add_with_overflow(x: T, y: T) -> (T, bool); /// Performs checked integer subtraction /// @@ -2586,7 +2579,7 @@ pub const fn add_with_overflow(_x: T, _y: T) -> (T, bool); #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn sub_with_overflow(_x: T, _y: T) -> (T, bool); +pub const fn sub_with_overflow(x: T, y: T) -> (T, bool); /// Performs checked integer multiplication /// @@ -2601,7 +2594,7 @@ pub const fn sub_with_overflow(_x: T, _y: T) -> (T, bool); #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn mul_with_overflow(_x: T, _y: T) -> (T, bool); +pub const fn mul_with_overflow(x: T, y: T) -> (T, bool); /// Performs full-width multiplication and addition with a carry: /// `multiplier * multiplicand + addend + carry`. @@ -2637,7 +2630,7 @@ pub const fn carrying_mul_add, /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn exact_div(_x: T, _y: T) -> T; +pub const unsafe fn exact_div(x: T, y: T) -> T; /// Performs an unchecked division, resulting in undefined behavior /// where `y == 0` or `x == T::MIN && y == -1` @@ -2648,7 +2641,7 @@ pub const unsafe fn exact_div(_x: T, _y: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn unchecked_div(_x: T, _y: T) -> T; +pub const unsafe fn unchecked_div(x: T, y: T) -> T; /// Returns the remainder of an unchecked division, resulting in /// undefined behavior when `y == 0` or `x == T::MIN && y == -1` /// @@ -2658,7 +2651,7 @@ pub const unsafe fn unchecked_div(_x: T, _y: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn unchecked_rem(_x: T, _y: T) -> T; +pub const unsafe fn unchecked_rem(x: T, y: T) -> T; /// Performs an unchecked left shift, resulting in undefined behavior when /// `y < 0` or `y >= N`, where N is the width of T in bits. @@ -2669,7 +2662,7 @@ pub const unsafe fn unchecked_rem(_x: T, _y: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn unchecked_shl(_x: T, _y: U) -> T; +pub const unsafe fn unchecked_shl(x: T, y: U) -> T; /// Performs an unchecked right shift, resulting in undefined behavior when /// `y < 0` or `y >= N`, where N is the width of T in bits. /// @@ -2679,7 +2672,7 @@ pub const unsafe fn unchecked_shl(_x: T, _y: U) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn unchecked_shr(_x: T, _y: U) -> T; +pub const unsafe fn unchecked_shr(x: T, y: U) -> T; /// Returns the result of an unchecked addition, resulting in /// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`. @@ -2689,7 +2682,7 @@ pub const unsafe fn unchecked_shr(_x: T, _y: U) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn unchecked_add(_x: T, _y: T) -> T; +pub const unsafe fn unchecked_add(x: T, y: T) -> T; /// Returns the result of an unchecked subtraction, resulting in /// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`. @@ -2699,7 +2692,7 @@ pub const unsafe fn unchecked_add(_x: T, _y: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn unchecked_sub(_x: T, _y: T) -> T; +pub const unsafe fn unchecked_sub(x: T, y: T) -> T; /// Returns the result of an unchecked multiplication, resulting in /// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`. @@ -2709,7 +2702,7 @@ pub const unsafe fn unchecked_sub(_x: T, _y: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn unchecked_mul(_x: T, _y: T) -> T; +pub const unsafe fn unchecked_mul(x: T, y: T) -> T; /// Performs rotate left. /// @@ -2724,7 +2717,7 @@ pub const unsafe fn unchecked_mul(_x: T, _y: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn rotate_left(_x: T, _shift: u32) -> T; +pub const fn rotate_left(x: T, shift: u32) -> T; /// Performs rotate right. /// @@ -2739,7 +2732,7 @@ pub const fn rotate_left(_x: T, _shift: u32) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn rotate_right(_x: T, _shift: u32) -> T; +pub const fn rotate_right(x: T, shift: u32) -> T; /// Returns (a + b) mod 2N, where N is the width of T in bits. /// @@ -2754,7 +2747,7 @@ pub const fn rotate_right(_x: T, _shift: u32) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn wrapping_add(_a: T, _b: T) -> T; +pub const fn wrapping_add(a: T, b: T) -> T; /// Returns (a - b) mod 2N, where N is the width of T in bits. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -2768,7 +2761,7 @@ pub const fn wrapping_add(_a: T, _b: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn wrapping_sub(_a: T, _b: T) -> T; +pub const fn wrapping_sub(a: T, b: T) -> T; /// Returns (a * b) mod 2N, where N is the width of T in bits. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -2782,7 +2775,7 @@ pub const fn wrapping_sub(_a: T, _b: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn wrapping_mul(_a: T, _b: T) -> T; +pub const fn wrapping_mul(a: T, b: T) -> T; /// Computes `a + b`, saturating at numeric bounds. /// @@ -2797,7 +2790,7 @@ pub const fn wrapping_mul(_a: T, _b: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn saturating_add(_a: T, _b: T) -> T; +pub const fn saturating_add(a: T, b: T) -> T; /// Computes `a - b`, saturating at numeric bounds. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -2811,7 +2804,7 @@ pub const fn saturating_add(_a: T, _b: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn saturating_sub(_a: T, _b: T) -> T; +pub const fn saturating_sub(a: T, b: T) -> T; /// This is an implementation detail of [`crate::ptr::read`] and should /// not be used anywhere else. See its comments for why this exists. @@ -2822,7 +2815,7 @@ pub const fn saturating_sub(_a: T, _b: T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn read_via_copy(_ptr: *const T) -> T; +pub const unsafe fn read_via_copy(ptr: *const T) -> T; /// This is an implementation detail of [`crate::ptr::write`] and should /// not be used anywhere else. See its comments for why this exists. @@ -2833,7 +2826,7 @@ pub const unsafe fn read_via_copy(_ptr: *const T) -> T; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn write_via_move(_ptr: *mut T, _value: T); +pub const unsafe fn write_via_move(ptr: *mut T, value: T); /// Returns the value of the discriminant for the variant in 'v'; /// if `T` has no discriminant, returns `0`. @@ -2847,7 +2840,7 @@ pub const unsafe fn write_via_move(_ptr: *mut T, _value: T); #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn discriminant_value(_v: &T) -> ::Discriminant; +pub const fn discriminant_value(v: &T) -> ::Discriminant; /// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the /// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs. @@ -2881,19 +2874,19 @@ pub unsafe fn catch_unwind( /// in ways that are not allowed for regular writes). #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn nontemporal_store(_ptr: *mut T, _val: T); +pub unsafe fn nontemporal_store(ptr: *mut T, val: T); /// See documentation of `<*const T>::offset_from` for details. #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn ptr_offset_from(_ptr: *const T, _base: *const T) -> isize; +pub const unsafe fn ptr_offset_from(ptr: *const T, base: *const T) -> isize; /// See documentation of `<*const T>::sub_ptr` for details. #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_const_stable_indirect] -pub const unsafe fn ptr_offset_from_unsigned(_ptr: *const T, _base: *const T) -> usize; +pub const unsafe fn ptr_offset_from_unsigned(ptr: *const T, base: *const T) -> usize; /// See documentation of `<*const T>::guaranteed_eq` for details. /// Returns `2` if the result is unknown. @@ -2933,7 +2926,7 @@ pub const fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8 { /// which is UB if any of their inputs are `undef`.) #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn raw_eq(_a: &T, _b: &T) -> bool; +pub const unsafe fn raw_eq(a: &T, b: &T) -> bool; /// Lexicographically compare `[left, left + bytes)` and `[right, right + bytes)` /// as unsigned bytes, returning negative if `left` is less, zero if all the @@ -2951,7 +2944,7 @@ pub const unsafe fn raw_eq(_a: &T, _b: &T) -> bool; /// [valid]: crate::ptr#safety #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: usize) -> i32; +pub const unsafe fn compare_bytes(left: *const u8, right: *const u8, bytes: usize) -> i32; /// See documentation of [`std::hint::black_box`] for details. /// @@ -2959,7 +2952,7 @@ pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: u #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_const_stable_indirect] -pub const fn black_box(_dummy: T) -> T; +pub const fn black_box(dummy: T) -> T; /// Selects which function to call depending on the context. /// @@ -3318,7 +3311,7 @@ pub fn contract_check_ensures<'a, Ret, C: Fn(&'a Ret) -> bool>(ret: &'a Ret, con #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -pub unsafe fn vtable_size(_ptr: *const ()) -> usize; +pub unsafe fn vtable_size(ptr: *const ()) -> usize; /// The intrinsic will return the alignment stored in that vtable. /// @@ -3328,7 +3321,7 @@ pub unsafe fn vtable_size(_ptr: *const ()) -> usize; #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -pub unsafe fn vtable_align(_ptr: *const ()) -> usize; +pub unsafe fn vtable_align(ptr: *const ()) -> usize; /// The size of a type in bytes. /// @@ -3395,7 +3388,7 @@ pub const fn variant_count() -> usize; #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] #[rustc_intrinsic_const_stable_indirect] -pub const unsafe fn size_of_val(_ptr: *const T) -> usize; +pub const unsafe fn size_of_val(ptr: *const T) -> usize; /// The required alignment of the referenced value. /// @@ -3408,7 +3401,7 @@ pub const unsafe fn size_of_val(_ptr: *const T) -> usize; #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] #[rustc_intrinsic_const_stable_indirect] -pub const unsafe fn min_align_of_val(_ptr: *const T) -> usize; +pub const unsafe fn min_align_of_val(ptr: *const T) -> usize; /// Gets a static string slice containing the name of a type. /// @@ -3447,7 +3440,7 @@ pub const fn type_id() -> u128; #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn aggregate_raw_ptr, D, M>(_data: D, _meta: M) -> P; +pub const fn aggregate_raw_ptr, D, M>(data: D, meta: M) -> P; #[unstable(feature = "core_intrinsics", issue = "none")] pub trait AggregateRawPtr { @@ -3467,7 +3460,7 @@ impl AggregateRawPtr<*mut T> for *mut P { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn ptr_metadata + ?Sized, M>(_ptr: *const P) -> M; +pub const fn ptr_metadata + ?Sized, M>(ptr: *const P) -> M; // Some functions are defined here because they accidentally got made // available in this module on stable. See . @@ -3569,7 +3562,7 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] - const unsafe fn copy_nonoverlapping(_src: *const T, _dst: *mut T, _count: usize); + const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); ub_checks::assert_unsafe_precondition!( check_language_ub, @@ -3670,7 +3663,7 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] - const unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize); + const unsafe fn copy(src: *const T, dst: *mut T, count: usize); // SAFETY: the safety contract for `copy` must be upheld by the caller. unsafe { @@ -3750,7 +3743,7 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] - const unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize); + const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize); // SAFETY: the safety contract for `write_bytes` must be upheld by the caller. unsafe { @@ -3778,7 +3771,7 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { /// [`f16::min`] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn minnumf16(_x: f16, _y: f16) -> f16; +pub const fn minnumf16(x: f16, y: f16) -> f16; /// Returns the minimum of two `f32` values. /// @@ -3792,7 +3785,7 @@ pub const fn minnumf16(_x: f16, _y: f16) -> f16; #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn minnumf32(_x: f32, _y: f32) -> f32; +pub const fn minnumf32(x: f32, y: f32) -> f32; /// Returns the minimum of two `f64` values. /// @@ -3806,7 +3799,7 @@ pub const fn minnumf32(_x: f32, _y: f32) -> f32; #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn minnumf64(_x: f64, _y: f64) -> f64; +pub const fn minnumf64(x: f64, y: f64) -> f64; /// Returns the minimum of two `f128` values. /// @@ -3819,7 +3812,7 @@ pub const fn minnumf64(_x: f64, _y: f64) -> f64; /// [`f128::min`] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn minnumf128(_x: f128, _y: f128) -> f128; +pub const fn minnumf128(x: f128, y: f128) -> f128; /// Returns the maximum of two `f16` values. /// @@ -3832,7 +3825,7 @@ pub const fn minnumf128(_x: f128, _y: f128) -> f128; /// [`f16::max`] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn maxnumf16(_x: f16, _y: f16) -> f16; +pub const fn maxnumf16(x: f16, y: f16) -> f16; /// Returns the maximum of two `f32` values. /// @@ -3846,7 +3839,7 @@ pub const fn maxnumf16(_x: f16, _y: f16) -> f16; #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn maxnumf32(_x: f32, _y: f32) -> f32; +pub const fn maxnumf32(x: f32, y: f32) -> f32; /// Returns the maximum of two `f64` values. /// @@ -3860,7 +3853,7 @@ pub const fn maxnumf32(_x: f32, _y: f32) -> f32; #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn maxnumf64(_x: f64, _y: f64) -> f64; +pub const fn maxnumf64(x: f64, y: f64) -> f64; /// Returns the maximum of two `f128` values. /// @@ -3873,7 +3866,7 @@ pub const fn maxnumf64(_x: f64, _y: f64) -> f64; /// [`f128::max`] #[rustc_nounwind] #[rustc_intrinsic] -pub const fn maxnumf128(_x: f128, _y: f128) -> f128; +pub const fn maxnumf128(x: f128, y: f128) -> f128; /// Returns the absolute value of an `f16`. /// @@ -3881,7 +3874,7 @@ pub const fn maxnumf128(_x: f128, _y: f128) -> f128; /// [`f16::abs`](../../std/primitive.f16.html#method.abs) #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn fabsf16(_x: f16) -> f16; +pub const unsafe fn fabsf16(x: f16) -> f16; /// Returns the absolute value of an `f32`. /// @@ -3890,7 +3883,7 @@ pub const unsafe fn fabsf16(_x: f16) -> f16; #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const unsafe fn fabsf32(_x: f32) -> f32; +pub const unsafe fn fabsf32(x: f32) -> f32; /// Returns the absolute value of an `f64`. /// @@ -3899,7 +3892,7 @@ pub const unsafe fn fabsf32(_x: f32) -> f32; #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const unsafe fn fabsf64(_x: f64) -> f64; +pub const unsafe fn fabsf64(x: f64) -> f64; /// Returns the absolute value of an `f128`. /// @@ -3907,7 +3900,7 @@ pub const unsafe fn fabsf64(_x: f64) -> f64; /// [`f128::abs`](../../std/primitive.f128.html#method.abs) #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn fabsf128(_x: f128) -> f128; +pub const unsafe fn fabsf128(x: f128) -> f128; /// Copies the sign from `y` to `x` for `f16` values. /// @@ -3915,7 +3908,7 @@ pub const unsafe fn fabsf128(_x: f128) -> f128; /// [`f16::copysign`](../../std/primitive.f16.html#method.copysign) #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16; +pub const unsafe fn copysignf16(x: f16, y: f16) -> f16; /// Copies the sign from `y` to `x` for `f32` values. /// @@ -3924,7 +3917,7 @@ pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16; #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32; +pub const unsafe fn copysignf32(x: f32, y: f32) -> f32; /// Copies the sign from `y` to `x` for `f64` values. /// /// The stabilized version of this intrinsic is @@ -3932,7 +3925,7 @@ pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32; #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64; +pub const unsafe fn copysignf64(x: f64, y: f64) -> f64; /// Copies the sign from `y` to `x` for `f128` values. /// @@ -3940,7 +3933,7 @@ pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64; /// [`f128::copysign`](../../std/primitive.f128.html#method.copysign) #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn copysignf128(_x: f128, _y: f128) -> f128; +pub const unsafe fn copysignf128(x: f128, y: f128) -> f128; /// Inform Miri that a given pointer definitely has a certain alignment. #[cfg(miri)] diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 935dd2e56731..ae6e1a779ed5 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -11,7 +11,7 @@ /// `idx` must be in-bounds of the vector. #[rustc_intrinsic] #[rustc_nounwind] -pub const unsafe fn simd_insert(_x: T, _idx: u32, _val: U) -> T; +pub const unsafe fn simd_insert(x: T, idx: u32, val: U) -> T; /// Extracts an element from a vector. /// @@ -22,28 +22,28 @@ pub const unsafe fn simd_insert(_x: T, _idx: u32, _val: U) -> T; /// `idx` must be in-bounds of the vector. #[rustc_intrinsic] #[rustc_nounwind] -pub const unsafe fn simd_extract(_x: T, _idx: u32) -> U; +pub const unsafe fn simd_extract(x: T, idx: u32) -> U; /// Adds two simd vectors elementwise. /// /// `T` must be a vector of integers or floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_add(_x: T, _y: T) -> T; +pub unsafe fn simd_add(x: T, y: T) -> T; /// Subtracts `rhs` from `lhs` elementwise. /// /// `T` must be a vector of integers or floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_sub(_lhs: T, _rhs: T) -> T; +pub unsafe fn simd_sub(lhs: T, rhs: T) -> T; /// Multiplies two simd vectors elementwise. /// /// `T` must be a vector of integers or floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_mul(_x: T, _y: T) -> T; +pub unsafe fn simd_mul(x: T, y: T) -> T; /// Divides `lhs` by `rhs` elementwise. /// @@ -54,7 +54,7 @@ pub unsafe fn simd_mul(_x: T, _y: T) -> T; /// Additionally for signed integers, `::MIN / -1` is undefined behavior. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_div(_lhs: T, _rhs: T) -> T; +pub unsafe fn simd_div(lhs: T, rhs: T) -> T; /// Returns remainder of two vectors elementwise. /// @@ -65,7 +65,7 @@ pub unsafe fn simd_div(_lhs: T, _rhs: T) -> T; /// Additionally for signed integers, `::MIN / -1` is undefined behavior. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_rem(_lhs: T, _rhs: T) -> T; +pub unsafe fn simd_rem(lhs: T, rhs: T) -> T; /// Shifts vector left elementwise, with UB on overflow. /// @@ -78,7 +78,7 @@ pub unsafe fn simd_rem(_lhs: T, _rhs: T) -> T; /// Each element of `rhs` must be less than `::BITS`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_shl(_lhs: T, _rhs: T) -> T; +pub unsafe fn simd_shl(lhs: T, rhs: T) -> T; /// Shifts vector right elementwise, with UB on overflow. /// @@ -91,28 +91,28 @@ pub unsafe fn simd_shl(_lhs: T, _rhs: T) -> T; /// Each element of `rhs` must be less than `::BITS`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_shr(_lhs: T, _rhs: T) -> T; +pub unsafe fn simd_shr(lhs: T, rhs: T) -> T; /// "Ands" vectors elementwise. /// /// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_and(_x: T, _y: T) -> T; +pub unsafe fn simd_and(x: T, y: T) -> T; /// "Ors" vectors elementwise. /// /// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_or(_x: T, _y: T) -> T; +pub unsafe fn simd_or(x: T, y: T) -> T; /// "Exclusive ors" vectors elementwise. /// /// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_xor(_x: T, _y: T) -> T; +pub unsafe fn simd_xor(x: T, y: T) -> T; /// Numerically casts a vector, elementwise. /// @@ -133,7 +133,7 @@ pub unsafe fn simd_xor(_x: T, _y: T) -> T; /// * Be representable in the return type, after truncating off its fractional part #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_cast(_x: T) -> U; +pub unsafe fn simd_cast(x: T) -> U; /// Numerically casts a vector, elementwise. /// @@ -147,7 +147,7 @@ pub unsafe fn simd_cast(_x: T) -> U; /// Otherwise, truncates or extends the value, maintaining the sign for signed integers. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_as(_x: T) -> U; +pub unsafe fn simd_as(x: T) -> U; /// Negates a vector elementwise. /// @@ -156,14 +156,14 @@ pub unsafe fn simd_as(_x: T) -> U; /// Rust panics for `-::Min` due to overflow, but it is not UB with this intrinsic. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_neg(_x: T) -> T; +pub unsafe fn simd_neg(x: T) -> T; /// Returns absolute value of a vector, elementwise. /// /// `T` must be a vector of floating-point primitive types. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_fabs(_x: T) -> T; +pub unsafe fn simd_fabs(x: T) -> T; /// Returns the minimum of two vectors, elementwise. /// @@ -172,7 +172,7 @@ pub unsafe fn simd_fabs(_x: T) -> T; /// Follows IEEE-754 `minNum` semantics. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_fmin(_x: T, _y: T) -> T; +pub unsafe fn simd_fmin(x: T, y: T) -> T; /// Returns the maximum of two vectors, elementwise. /// @@ -181,7 +181,7 @@ pub unsafe fn simd_fmin(_x: T, _y: T) -> T; /// Follows IEEE-754 `maxNum` semantics. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_fmax(_x: T, _y: T) -> T; +pub unsafe fn simd_fmax(x: T, y: T) -> T; /// Tests elementwise equality of two vectors. /// @@ -192,7 +192,7 @@ pub unsafe fn simd_fmax(_x: T, _y: T) -> T; /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_eq(_x: T, _y: T) -> U; +pub unsafe fn simd_eq(x: T, y: T) -> U; /// Tests elementwise inequality equality of two vectors. /// @@ -203,7 +203,7 @@ pub unsafe fn simd_eq(_x: T, _y: T) -> U; /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_ne(_x: T, _y: T) -> U; +pub unsafe fn simd_ne(x: T, y: T) -> U; /// Tests if `x` is less than `y`, elementwise. /// @@ -214,7 +214,7 @@ pub unsafe fn simd_ne(_x: T, _y: T) -> U; /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_lt(_x: T, _y: T) -> U; +pub unsafe fn simd_lt(x: T, y: T) -> U; /// Tests if `x` is less than or equal to `y`, elementwise. /// @@ -225,7 +225,7 @@ pub unsafe fn simd_lt(_x: T, _y: T) -> U; /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_le(_x: T, _y: T) -> U; +pub unsafe fn simd_le(x: T, y: T) -> U; /// Tests if `x` is greater than `y`, elementwise. /// @@ -236,7 +236,7 @@ pub unsafe fn simd_le(_x: T, _y: T) -> U; /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_gt(_x: T, _y: T) -> U; +pub unsafe fn simd_gt(x: T, y: T) -> U; /// Tests if `x` is greater than or equal to `y`, elementwise. /// @@ -247,7 +247,7 @@ pub unsafe fn simd_gt(_x: T, _y: T) -> U; /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_ge(_x: T, _y: T) -> U; +pub unsafe fn simd_ge(x: T, y: T) -> U; /// Shuffles two vectors by const indices. /// @@ -263,7 +263,7 @@ pub unsafe fn simd_ge(_x: T, _y: T) -> U; /// of `xy`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_shuffle(_x: T, _y: T, _idx: U) -> V; +pub unsafe fn simd_shuffle(x: T, y: T, idx: U) -> V; /// Reads a vector of pointers. /// @@ -284,7 +284,7 @@ pub unsafe fn simd_shuffle(_x: T, _y: T, _idx: U) -> V; /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_gather(_val: T, _ptr: U, _mask: V) -> T; +pub unsafe fn simd_gather(val: T, ptr: U, mask: V) -> T; /// Writes to a vector of pointers. /// @@ -308,7 +308,7 @@ pub unsafe fn simd_gather(_val: T, _ptr: U, _mask: V) -> T; /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_scatter(_val: T, _ptr: U, _mask: V); +pub unsafe fn simd_scatter(val: T, ptr: U, mask: V); /// Reads a vector of pointers. /// @@ -331,7 +331,7 @@ pub unsafe fn simd_scatter(_val: T, _ptr: U, _mask: V); /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_masked_load(_mask: V, _ptr: U, _val: T) -> T; +pub unsafe fn simd_masked_load(mask: V, ptr: U, val: T) -> T; /// Writes to a vector of pointers. /// @@ -353,14 +353,14 @@ pub unsafe fn simd_masked_load(_mask: V, _ptr: U, _val: T) -> T; /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_masked_store(_mask: V, _ptr: U, _val: T); +pub unsafe fn simd_masked_store(mask: V, ptr: U, val: T); /// Adds two simd vectors elementwise, with saturation. /// /// `T` must be a vector of integer primitive types. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_saturating_add(_x: T, _y: T) -> T; +pub unsafe fn simd_saturating_add(x: T, y: T) -> T; /// Subtracts two simd vectors elementwise, with saturation. /// @@ -369,7 +369,7 @@ pub unsafe fn simd_saturating_add(_x: T, _y: T) -> T; /// Subtract `rhs` from `lhs`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_saturating_sub(_lhs: T, _rhs: T) -> T; +pub unsafe fn simd_saturating_sub(lhs: T, rhs: T) -> T; /// Adds elements within a vector from left to right. /// @@ -380,7 +380,7 @@ pub unsafe fn simd_saturating_sub(_lhs: T, _rhs: T) -> T; /// Starting with the value `y`, add the elements of `x` and accumulate. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_add_ordered(_x: T, _y: U) -> U; +pub unsafe fn simd_reduce_add_ordered(x: T, y: U) -> U; /// Adds elements within a vector in arbitrary order. May also be re-associated with /// unordered additions on the inputs/outputs. @@ -390,7 +390,7 @@ pub unsafe fn simd_reduce_add_ordered(_x: T, _y: U) -> U; /// `U` must be the element type of `T`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_add_unordered(_x: T) -> U; +pub unsafe fn simd_reduce_add_unordered(x: T) -> U; /// Multiplies elements within a vector from left to right. /// @@ -401,7 +401,7 @@ pub unsafe fn simd_reduce_add_unordered(_x: T) -> U; /// Starting with the value `y`, multiply the elements of `x` and accumulate. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_mul_ordered(_x: T, _y: U) -> U; +pub unsafe fn simd_reduce_mul_ordered(x: T, y: U) -> U; /// Multiplies elements within a vector in arbitrary order. May also be re-associated with /// unordered additions on the inputs/outputs. @@ -411,7 +411,7 @@ pub unsafe fn simd_reduce_mul_ordered(_x: T, _y: U) -> U; /// `U` must be the element type of `T`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_mul_unordered(_x: T) -> U; +pub unsafe fn simd_reduce_mul_unordered(x: T) -> U; /// Checks if all mask values are true. /// @@ -421,7 +421,7 @@ pub unsafe fn simd_reduce_mul_unordered(_x: T) -> U; /// `x` must contain only `0` or `!0`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_all(_x: T) -> bool; +pub unsafe fn simd_reduce_all(x: T) -> bool; /// Checks if any mask value is true. /// @@ -431,7 +431,7 @@ pub unsafe fn simd_reduce_all(_x: T) -> bool; /// `x` must contain only `0` or `!0`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_any(_x: T) -> bool; +pub unsafe fn simd_reduce_any(x: T) -> bool; /// Returns the maximum element of a vector. /// @@ -442,7 +442,7 @@ pub unsafe fn simd_reduce_any(_x: T) -> bool; /// For floating-point values, uses IEEE-754 `maxNum`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_max(_x: T) -> U; +pub unsafe fn simd_reduce_max(x: T) -> U; /// Returns the minimum element of a vector. /// @@ -453,7 +453,7 @@ pub unsafe fn simd_reduce_max(_x: T) -> U; /// For floating-point values, uses IEEE-754 `minNum`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_min(_x: T) -> U; +pub unsafe fn simd_reduce_min(x: T) -> U; /// Logical "ands" all elements together. /// @@ -462,7 +462,7 @@ pub unsafe fn simd_reduce_min(_x: T) -> U; /// `U` must be the element type of `T`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_and(_x: T) -> U; +pub unsafe fn simd_reduce_and(x: T) -> U; /// Logical "ors" all elements together. /// @@ -471,7 +471,7 @@ pub unsafe fn simd_reduce_and(_x: T) -> U; /// `U` must be the element type of `T`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_or(_x: T) -> U; +pub unsafe fn simd_reduce_or(x: T) -> U; /// Logical "exclusive ors" all elements together. /// @@ -480,7 +480,7 @@ pub unsafe fn simd_reduce_or(_x: T) -> U; /// `U` must be the element type of `T`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_reduce_xor(_x: T) -> U; +pub unsafe fn simd_reduce_xor(x: T) -> U; /// Truncates an integer vector to a bitmask. /// @@ -517,7 +517,7 @@ pub unsafe fn simd_reduce_xor(_x: T) -> U; /// `x` must contain only `0` and `!0`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_bitmask(_x: T) -> U; +pub unsafe fn simd_bitmask(x: T) -> U; /// Selects elements from a mask. /// @@ -533,7 +533,7 @@ pub unsafe fn simd_bitmask(_x: T) -> U; /// `mask` must only contain `0` and `!0`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_select(_mask: M, _if_true: T, _if_false: T) -> T; +pub unsafe fn simd_select(mask: M, if_true: T, if_false: T) -> T; /// Selects elements from a bitmask. /// @@ -551,7 +551,7 @@ pub unsafe fn simd_select(_mask: M, _if_true: T, _if_false: T) -> T; /// Padding bits must be all zero. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_select_bitmask(_m: M, _yes: T, _no: T) -> T; +pub unsafe fn simd_select_bitmask(m: M, yes: T, no: T) -> T; /// Calculates the offset from a pointer vector elementwise, potentially /// wrapping. @@ -563,14 +563,14 @@ pub unsafe fn simd_select_bitmask(_m: M, _yes: T, _no: T) -> T; /// Operates as if by `::wrapping_offset`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_arith_offset(_ptr: T, _offset: U) -> T; +pub unsafe fn simd_arith_offset(ptr: T, offset: U) -> T; /// Casts a vector of pointers. /// /// `T` and `U` must be vectors of pointers with the same number of elements. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_cast_ptr(_ptr: T) -> U; +pub unsafe fn simd_cast_ptr(ptr: T) -> U; /// Exposes a vector of pointers as a vector of addresses. /// @@ -579,7 +579,7 @@ pub unsafe fn simd_cast_ptr(_ptr: T) -> U; /// `U` must be a vector of `usize` with the same length as `T`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_expose_provenance(_ptr: T) -> U; +pub unsafe fn simd_expose_provenance(ptr: T) -> U; /// Creates a vector of pointers from a vector of addresses. /// @@ -588,56 +588,56 @@ pub unsafe fn simd_expose_provenance(_ptr: T) -> U; /// `U` must be a vector of pointers, with the same length as `T`. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_with_exposed_provenance(_addr: T) -> U; +pub unsafe fn simd_with_exposed_provenance(addr: T) -> U; /// Swaps bytes of each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_bswap(_x: T) -> T; +pub unsafe fn simd_bswap(x: T) -> T; /// Reverses bits of each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_bitreverse(_x: T) -> T; +pub unsafe fn simd_bitreverse(x: T) -> T; /// Counts the leading zeros of each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_ctlz(_x: T) -> T; +pub unsafe fn simd_ctlz(x: T) -> T; /// Counts the number of ones in each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_ctpop(_x: T) -> T; +pub unsafe fn simd_ctpop(x: T) -> T; /// Counts the trailing zeros of each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_cttz(_x: T) -> T; +pub unsafe fn simd_cttz(x: T) -> T; /// Rounds up each element to the next highest integer-valued float. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_ceil(_x: T) -> T; +pub unsafe fn simd_ceil(x: T) -> T; /// Rounds down each element to the next lowest integer-valued float. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_floor(_x: T) -> T; +pub unsafe fn simd_floor(x: T) -> T; /// Rounds each element to the closest integer-valued float. /// Ties are resolved by rounding away from 0. @@ -645,7 +645,7 @@ pub unsafe fn simd_floor(_x: T) -> T; /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_round(_x: T) -> T; +pub unsafe fn simd_round(x: T) -> T; /// Returns the integer part of each element as an integer-valued float. /// In other words, non-integer values are truncated towards zero. @@ -653,21 +653,21 @@ pub unsafe fn simd_round(_x: T) -> T; /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_trunc(_x: T) -> T; +pub unsafe fn simd_trunc(x: T) -> T; /// Takes the square root of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_fsqrt(_x: T) -> T; +pub unsafe fn simd_fsqrt(x: T) -> T; /// Computes `(x*y) + z` for each element, but without any intermediate rounding. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_fma(_x: T, _y: T, _z: T) -> T; +pub unsafe fn simd_fma(x: T, y: T, z: T) -> T; /// Computes `(x*y) + z` for each element, non-deterministically executing either /// a fused multiply-add or two operations with rounding of the intermediate result. @@ -682,53 +682,53 @@ pub unsafe fn simd_fma(_x: T, _y: T, _z: T) -> T; /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_relaxed_fma(_x: T, _y: T, _z: T) -> T; +pub unsafe fn simd_relaxed_fma(x: T, y: T, z: T) -> T; // Computes the sine of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_fsin(_a: T) -> T; +pub unsafe fn simd_fsin(a: T) -> T; // Computes the cosine of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_fcos(_a: T) -> T; +pub unsafe fn simd_fcos(a: T) -> T; // Computes the exponential function of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_fexp(_a: T) -> T; +pub unsafe fn simd_fexp(a: T) -> T; // Computes 2 raised to the power of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_fexp2(_a: T) -> T; +pub unsafe fn simd_fexp2(a: T) -> T; // Computes the base 10 logarithm of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_flog10(_a: T) -> T; +pub unsafe fn simd_flog10(a: T) -> T; // Computes the base 2 logarithm of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_flog2(_a: T) -> T; +pub unsafe fn simd_flog2(a: T) -> T; // Computes the natural logarithm of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_flog(_a: T) -> T; +pub unsafe fn simd_flog(a: T) -> T; diff --git a/src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs b/src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs index 791ffa7343d4..e6282613df72 100644 --- a/src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs +++ b/src/tools/miri/tests/fail/intrinsics/copy_overlapping.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn copy_nonoverlapping(_src: *const T, _dst: *mut T, _count: usize); +unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); fn main() { let mut data = [0u8; 16]; diff --git a/src/tools/miri/tests/fail/intrinsics/copy_unaligned.rs b/src/tools/miri/tests/fail/intrinsics/copy_unaligned.rs index 9a82c69fba80..ded9d0b669e6 100644 --- a/src/tools/miri/tests/fail/intrinsics/copy_unaligned.rs +++ b/src/tools/miri/tests/fail/intrinsics/copy_unaligned.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn copy_nonoverlapping(_src: *const T, _dst: *mut T, _count: usize); +unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); fn main() { let mut data = [0u16; 8]; diff --git a/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs b/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs index e42811d9e13d..f73c1b6acb70 100644 --- a/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs +++ b/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs @@ -2,7 +2,7 @@ mod rusti { #[rustc_intrinsic] - pub unsafe fn ctlz_nonzero(_x: T) -> u32; + pub unsafe fn ctlz_nonzero(x: T) -> u32; } pub fn main() { diff --git a/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs b/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs index e046a30e7342..a41cb8b15536 100644 --- a/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs +++ b/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs @@ -2,7 +2,7 @@ mod rusti { #[rustc_intrinsic] - pub unsafe fn cttz_nonzero(_x: T) -> u32; + pub unsafe fn cttz_nonzero(x: T) -> u32; } pub fn main() { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs index d75046ff3606..7ee0117ffb33 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs index 8d343cdc1bd7..22bf881cef0a 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs index 737a6fbafe07..571121f4019f 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs index ee8b45c0aaee..12600ef61255 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs index 4bb5ded1033d..f848a137c279 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs index 6b42ae56ecee..43ef4a95738f 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs index 81019a1c6089..83432c2b77c0 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs index 24896bcae511..609443e6d4ef 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs index fbb67d28fed7..fb3eb11c0bb5 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs index 93236bf4874b..b46c4777ba71 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs index 2770dea44061..8a3b9dbdc710 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs index 1272566c07c1..e0c826cb0463 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs index a1165794982a..c7c5bf402264 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs index 0e68f4eaff76..fb3d7bda4e47 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs index ad3ac16dc6f7..2cf27b33553c 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs index 1addb9fb1d72..22dca505e64b 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs index a04c29c37da0..b59c8fa8e0c2 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs index 32bdcd070739..4ad0cd343a40 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs index 861af44a66f6..fd47dfc03d7a 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs index 3b3e208f32ff..680ebda1c96b 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs index 81ca766de472..e4cb36c5d2eb 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs index 2b437f385520..fe4bac92bd3e 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs index 94ee572f4d0f..219efd803162 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs @@ -2,7 +2,7 @@ // Directly call intrinsic to avoid debug assertions in libstd #[rustc_intrinsic] -unsafe fn float_to_int_unchecked(_value: Float) -> Int; +unsafe fn float_to_int_unchecked(value: Float) -> Int; fn main() { unsafe { diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index f043bb7ce9f5..cc753dac2156 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -16,7 +16,7 @@ use std::simd::prelude::*; #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_shuffle_const_generic(_x: T, _y: T) -> U; +pub unsafe fn simd_shuffle_const_generic(x: T, y: T) -> U; fn simd_ops_f32() { let a = f32x4::splat(10.0); From cb260791a43efb40abf22e7413249cbdf3615d8c Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 12 Mar 2025 10:29:13 +0300 Subject: [PATCH 986/991] fix incorrect tracing log Previous information is not correct. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 8cb3e3ed8729..20084a65b8a6 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -194,11 +194,7 @@ impl Step for Std { trace!(?compiler_to_use); if compiler_to_use != compiler { - trace!( - ?compiler_to_use, - ?compiler, - "compiler != compiler_to_use, handling cross-compile scenario" - ); + trace!(?compiler_to_use, ?compiler, "compiler != compiler_to_use, uplifting library"); builder.ensure(Std::new(compiler_to_use, target)); let msg = if compiler_to_use.host == target { From adbcb910f0fc63b9a4bf6daa89c1a534a08b1f02 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 12 Mar 2025 10:12:02 +0100 Subject: [PATCH 987/991] remove unnecessary variant --- compiler/rustc_middle/src/traits/mod.rs | 7 ++----- compiler/rustc_traits/src/codegen.rs | 2 +- compiler/rustc_ty_utils/src/instance.rs | 8 +++----- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 53f233f20eb9..7e6151745e2f 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -980,12 +980,9 @@ pub enum CodegenObligationError { /// overflow bug, since I believe this is the only case /// where ambiguity can result. Ambiguity, - /// This can trigger when we probe for the source of a `'static` lifetime requirement - /// on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound. - /// This can also trigger when we have a global bound that is not actually satisfied, - /// but was included during typeck due to the trivial_bounds feature. + /// This can trigger when we have a global bound that is not actually satisfied + /// due to trivial bounds. Unimplemented, - FulfillmentError, /// The selected impl has unconstrained generic parameters. This will emit an error /// during impl WF checking. UnconstrainedParam(ErrorGuaranteed), diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index cc329ca33288..4a889abfc28f 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -70,7 +70,7 @@ pub(crate) fn codegen_select_candidate<'tcx>( infcx.err_ctxt().report_overflow_obligation_cycle(&cycle); } } - return Err(CodegenObligationError::FulfillmentError); + return Err(CodegenObligationError::Unimplemented); } let impl_source = infcx.resolve_vars_if_possible(impl_source); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 6dc5a9c4a479..90b3517eded8 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -107,11 +107,9 @@ fn resolve_associated_item<'tcx>( let input = typing_env.as_query_input(trait_ref); let vtbl = match tcx.codegen_select_candidate(input) { Ok(vtbl) => vtbl, - Err( - CodegenObligationError::Ambiguity - | CodegenObligationError::Unimplemented - | CodegenObligationError::FulfillmentError, - ) => return Ok(None), + Err(CodegenObligationError::Ambiguity | CodegenObligationError::Unimplemented) => { + return Ok(None); + } Err(CodegenObligationError::UnconstrainedParam(guar)) => return Err(guar), }; From 7bfe2136e4ffa5b5f6c85f0544a5d7ef8ab2b705 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Wed, 12 Mar 2025 15:59:21 +0300 Subject: [PATCH 988/991] Delegation: one more ICE fix for `MethodCall` generation --- compiler/rustc_ast_lowering/src/delegation.rs | 1 + tests/ui/delegation/ice-issue-138362.rs | 15 +++++++++++++++ tests/ui/delegation/ice-issue-138362.stderr | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 tests/ui/delegation/ice-issue-138362.rs create mode 100644 tests/ui/delegation/ice-issue-138362.stderr diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 571172be4ed1..946f2cafa15f 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -330,6 +330,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .unwrap_or_default() && delegation.qself.is_none() && !has_generic_args + && !args.is_empty() { let ast_segment = delegation.path.segments.last().unwrap(); let segment = self.lower_path_segment( diff --git a/tests/ui/delegation/ice-issue-138362.rs b/tests/ui/delegation/ice-issue-138362.rs new file mode 100644 index 000000000000..c30660098555 --- /dev/null +++ b/tests/ui/delegation/ice-issue-138362.rs @@ -0,0 +1,15 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait HasSelf { + fn method(self); +} +trait NoSelf { + fn method(); +} +impl NoSelf for u8 { + reuse HasSelf::method; + //~^ ERROR this function takes 1 argument but 0 arguments were supplied +} + +fn main() {} diff --git a/tests/ui/delegation/ice-issue-138362.stderr b/tests/ui/delegation/ice-issue-138362.stderr new file mode 100644 index 000000000000..9feddc9feaec --- /dev/null +++ b/tests/ui/delegation/ice-issue-138362.stderr @@ -0,0 +1,19 @@ +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/ice-issue-138362.rs:11:20 + | +LL | reuse HasSelf::method; + | ^^^^^^ argument #1 is missing + | +note: method defined here + --> $DIR/ice-issue-138362.rs:5:8 + | +LL | fn method(self); + | ^^^^^^ ---- +help: provide the argument + | +LL | reuse HasSelf::method(/* value */); + | +++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0061`. From ccdba16f42c951163d00c7e6cd7051be64d2f847 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Wed, 12 Mar 2025 16:57:12 +0300 Subject: [PATCH 989/991] Delegation: reject C-variadics --- compiler/rustc_hir_analysis/src/delegation.rs | 5 ++++ tests/ui/delegation/fn-header-variadic.rs | 25 +++++++++++++++++++ tests/ui/delegation/fn-header-variadic.stderr | 22 ++++++++++++++++ tests/ui/delegation/fn-header.rs | 11 -------- 4 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 tests/ui/delegation/fn-header-variadic.rs create mode 100644 tests/ui/delegation/fn-header-variadic.stderr diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 4dbdfa3d85a9..b0b3590d68c8 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -409,6 +409,11 @@ fn check_constraints<'tcx>( emit("recursive delegation is not supported yet"); } + if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic { + // See issue #127443 for explanation. + emit("delegation to C-variadic functions is not allowed"); + } + ret } diff --git a/tests/ui/delegation/fn-header-variadic.rs b/tests/ui/delegation/fn-header-variadic.rs new file mode 100644 index 000000000000..2c83d64d0b3f --- /dev/null +++ b/tests/ui/delegation/fn-header-variadic.rs @@ -0,0 +1,25 @@ +//@ aux-crate:fn_header_aux=fn-header-aux.rs + +#![feature(c_variadic)] +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse { + pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} +} + +reuse to_reuse::variadic_fn; +//~^ ERROR delegation to C-variadic functions is not allowed +reuse fn_header_aux::variadic_fn_extern; +//~^ ERROR delegation to C-variadic functions is not allowed + +fn main() { + unsafe { + variadic_fn(0); + variadic_fn(0, 1); + variadic_fn_extern(0); + variadic_fn_extern(0, 1); + } + let _: unsafe extern "C" fn(usize, ...) = variadic_fn; + let _: unsafe extern "C" fn(usize, ...) = variadic_fn_extern; +} diff --git a/tests/ui/delegation/fn-header-variadic.stderr b/tests/ui/delegation/fn-header-variadic.stderr new file mode 100644 index 000000000000..688a965fb4d5 --- /dev/null +++ b/tests/ui/delegation/fn-header-variadic.stderr @@ -0,0 +1,22 @@ +error: delegation to C-variadic functions is not allowed + --> $DIR/fn-header-variadic.rs:11:17 + | +LL | pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} + | ------------------------------------------------------------- callee defined here +... +LL | reuse to_reuse::variadic_fn; + | ^^^^^^^^^^^ + +error: delegation to C-variadic functions is not allowed + --> $DIR/fn-header-variadic.rs:13:22 + | +LL | reuse fn_header_aux::variadic_fn_extern; + | ^^^^^^^^^^^^^^^^^^ + | + ::: $DIR/auxiliary/fn-header-aux.rs:7:1 + | +LL | pub unsafe extern "C" fn variadic_fn_extern(n: usize, mut args: ...) {} + | -------------------------------------------------------------------- callee defined here + +error: aborting due to 2 previous errors + diff --git a/tests/ui/delegation/fn-header.rs b/tests/ui/delegation/fn-header.rs index db20e1058e06..9de0d549f20a 100644 --- a/tests/ui/delegation/fn-header.rs +++ b/tests/ui/delegation/fn-header.rs @@ -10,20 +10,17 @@ mod to_reuse { pub unsafe fn unsafe_fn() {} pub extern "C" fn extern_fn() {} - pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} pub const fn const_fn() {} pub async fn async_fn() {} } reuse to_reuse::unsafe_fn; reuse to_reuse::extern_fn; -reuse to_reuse::variadic_fn; reuse to_reuse::const_fn; reuse to_reuse::async_fn; reuse fn_header_aux::unsafe_fn_extern; reuse fn_header_aux::extern_fn_extern; -reuse fn_header_aux::variadic_fn_extern; reuse fn_header_aux::const_fn_extern; reuse fn_header_aux::async_fn_extern; @@ -46,12 +43,4 @@ fn main() { extern_fn_extern(); let _: extern "C" fn() = extern_fn; let _: extern "C" fn() = extern_fn_extern; - unsafe { - variadic_fn(0); - variadic_fn(0, 1); - variadic_fn_extern(0); - variadic_fn_extern(0, 1); - } - let _: unsafe extern "C" fn(usize, ...) = variadic_fn; - let _: unsafe extern "C" fn(usize, ...) = variadic_fn_extern; } From 17d1e050e6fd0ad6bf9f85d3f81da5a39d09d03c Mon Sep 17 00:00:00 2001 From: Xing Xue Date: Wed, 12 Mar 2025 10:39:09 -0400 Subject: [PATCH 990/991] Use sa_sigaction instead of sa_union.__su_sigaction for AIX. --- .../auxiliary/assert-sigpipe-disposition.rs | 9 +-------- .../ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs | 9 +-------- tests/ui/runtime/signal-alternate-stack-cleanup.rs | 9 +-------- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs index f3f9ce0bd879..3a574af9bba7 100644 --- a/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs +++ b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs @@ -26,14 +26,7 @@ extern "C" fn main(argc: core::ffi::c_int, argv: *const *const u8) -> core::ffi: let actual = unsafe { let mut actual: libc::sigaction = core::mem::zeroed(); libc::sigaction(libc::SIGPIPE, core::ptr::null(), &mut actual); - #[cfg(not(target_os = "aix"))] - { - actual.sa_sigaction - } - #[cfg(target_os = "aix")] - { - actual.sa_union.__su_sigaction as libc::sighandler_t - } + actual.sa_sigaction }; assert_eq!(actual, expected, "actual and expected SIGPIPE disposition in child differs"); diff --git a/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs index d16a2b4d8c8a..3d93d50ca3fb 100644 --- a/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs +++ b/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs @@ -20,14 +20,7 @@ pub fn assert_sigpipe_handler(expected_handler: SignalHandler) { let actual = unsafe { let mut actual: libc::sigaction = std::mem::zeroed(); libc::sigaction(libc::SIGPIPE, std::ptr::null(), &mut actual); - #[cfg(not(target_os = "aix"))] - { - actual.sa_sigaction - } - #[cfg(target_os = "aix")] - { - actual.sa_union.__su_sigaction as libc::sighandler_t - } + actual.sa_sigaction }; let expected = match expected_handler { diff --git a/tests/ui/runtime/signal-alternate-stack-cleanup.rs b/tests/ui/runtime/signal-alternate-stack-cleanup.rs index 8fce09282731..f2af86be0a5f 100644 --- a/tests/ui/runtime/signal-alternate-stack-cleanup.rs +++ b/tests/ui/runtime/signal-alternate-stack-cleanup.rs @@ -29,14 +29,7 @@ fn main() { // Install signal handler that runs on alternate signal stack. let mut action: sigaction = std::mem::zeroed(); action.sa_flags = (SA_ONSTACK | SA_SIGINFO) as _; - #[cfg(not(target_os = "aix"))] - { - action.sa_sigaction = signal_handler as sighandler_t; - } - #[cfg(target_os = "aix")] - { - action.sa_union.__su_sigaction = signal_handler as sighandler_t; - } + action.sa_sigaction = signal_handler as sighandler_t; sigaction(SIGWINCH, &action, std::ptr::null_mut()); // Send SIGWINCH on exit. From 42773bfcac71decb4058ca1c3b4eff816235549f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 9 Mar 2025 06:00:54 +0000 Subject: [PATCH 991/991] Disentangle ForwardGenericParamBan and ConstParamTy ribs --- compiler/rustc_resolve/messages.ftl | 12 +++- compiler/rustc_resolve/src/diagnostics.rs | 30 ++++++--- compiler/rustc_resolve/src/errors.rs | 18 +++++- compiler/rustc_resolve/src/ident.rs | 61 +++++++++++++------ compiler/rustc_resolve/src/late.rs | 42 +++++++++---- compiler/rustc_resolve/src/lib.rs | 9 ++- ...const-param-type-depends-on-const-param.rs | 8 +-- ...onst-param-type-depends-on-parent-param.rs | 8 +++ ...-param-type-depends-on-parent-param.stderr | 9 +++ ...t-const-param-cannot-reference-self.stderr | 6 +- .../defaults/forward-declared.rs | 8 +-- .../defaults/forward-declared.stderr | 16 ++--- .../forward_declared_type.rs | 4 +- .../forward_declared_type.stderr | 9 ++- .../references-parent-generics.feat.stderr | 2 +- .../references-parent-generics.nofeat.stderr | 15 ++--- .../references-parent-generics.rs | 5 +- ...ms-in-ct-in-ty-param-lazy-norm.full.stderr | 4 +- ...ams-in-ct-in-ty-param-lazy-norm.min.stderr | 4 +- .../params-in-ct-in-ty-param-lazy-norm.rs | 2 +- tests/ui/error-codes/E0128.stderr | 4 +- .../generics/generic-non-trailing-defaults.rs | 2 +- .../generic-non-trailing-defaults.stderr | 4 +- .../generic-type-params-forward-mention.rs | 2 +- ...generic-type-params-forward-mention.stderr | 4 +- ...lt-type-param-cannot-reference-self.stderr | 12 ++-- tests/ui/issues/issue-18183.stderr | 4 +- tests/ui/issues/issue-26812.rs | 2 +- tests/ui/issues/issue-26812.stderr | 4 +- 29 files changed, 196 insertions(+), 114 deletions(-) create mode 100644 tests/ui/const-generics/const-param-type-depends-on-parent-param.rs create mode 100644 tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 9f062b3935fd..817aa5b43852 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -153,9 +153,13 @@ resolve_extern_crate_self_requires_renaming = `extern crate self;` requires renaming .suggestion = rename the `self` crate to be able to import it +resolve_forward_declared_generic_in_const_param_ty = + const parameter types cannot reference parameters before they are declared + .label = const parameter type cannot reference `{$param}` before it is declared + resolve_forward_declared_generic_param = - generic parameters with a default cannot use forward declared identifiers - .label = defaulted generic parameters cannot be forward declared + generic parameter defaults cannot reference parameters before they are declared + .label = cannot reference `{$param}` before it is declared resolve_found_an_item_configured_out = found an item that was configured out @@ -377,9 +381,11 @@ resolve_self_imports_only_allowed_within_multipart_suggestion = resolve_self_imports_only_allowed_within_suggestion = consider importing the module directly +resolve_self_in_const_generic_ty = + cannot use `Self` in const parameter type + resolve_self_in_generic_param_default = generic parameters cannot use `Self` in their defaults - .label = `Self` in generic parameter default resolve_similarly_named_defined_here = similarly named {$candidate_descr} `{$candidate}` defined here diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 88d1126de1ae..41f4254eede4 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -42,10 +42,10 @@ use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; use crate::{ AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize, - HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, ModuleKind, - ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, - ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError, - errors as errs, path_names_to_string, + ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, + ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, + PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, + VisResolutionError, errors as errs, path_names_to_string, }; type Res = def::Res; @@ -887,9 +887,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { participle, name, }), - ResolutionError::ForwardDeclaredGenericParam => { - self.dcx().create_err(errs::ForwardDeclaredGenericParam { span }) - } + ResolutionError::ForwardDeclaredGenericParam(param, reason) => match reason { + ForwardGenericParamBanReason::Default => { + self.dcx().create_err(errs::ForwardDeclaredGenericParam { param, span }) + } + ForwardGenericParamBanReason::ConstParamTy => self + .dcx() + .create_err(errs::ForwardDeclaredGenericInConstParamTy { param, span }), + }, ResolutionError::ParamInTyOfConstParam { name } => { self.dcx().create_err(errs::ParamInTyOfConstParam { span, name }) } @@ -908,9 +913,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self .dcx() .create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }), - ResolutionError::SelfInGenericParamDefault => { - self.dcx().create_err(errs::SelfInGenericParamDefault { span }) - } + ResolutionError::ForwardDeclaredSelf(reason) => match reason { + ForwardGenericParamBanReason::Default => { + self.dcx().create_err(errs::SelfInGenericParamDefault { span }) + } + ForwardGenericParamBanReason::ConstParamTy => { + self.dcx().create_err(errs::SelfInConstGenericTy { span }) + } + }, ResolutionError::UnreachableLabel { name, definition_span, suggestion } => { let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) = match suggestion { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index b5d3e5ea7767..2ae6892bc93e 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -338,6 +338,16 @@ pub(crate) struct ForwardDeclaredGenericParam { #[primary_span] #[label] pub(crate) span: Span, + pub(crate) param: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_forward_declared_generic_in_const_param_ty)] +pub(crate) struct ForwardDeclaredGenericInConstParamTy { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) param: Symbol, } #[derive(Diagnostic)] @@ -353,7 +363,13 @@ pub(crate) struct ParamInTyOfConstParam { #[diag(resolve_self_in_generic_param_default, code = E0735)] pub(crate) struct SelfInGenericParamDefault { #[primary_span] - #[label] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_self_in_const_generic_ty)] +pub(crate) struct SelfInConstGenericTy { + #[primary_span] pub(crate) span: Span, } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index d9776be4dd0a..5f0a2a597e9b 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1117,13 +1117,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { debug!("validate_res_from_ribs({:?})", res); let ribs = &all_ribs[rib_index + 1..]; - // An invalid forward use of a generic parameter from a previous default. - if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind { + // An invalid forward use of a generic parameter from a previous default + // or in a const param ty. + if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind { if let Some(span) = finalize { let res_error = if rib_ident.name == kw::SelfUpper { - ResolutionError::SelfInGenericParamDefault + ResolutionError::ForwardDeclaredSelf(reason) } else { - ResolutionError::ForwardDeclaredGenericParam + ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason) }; self.report_error(span, res_error); } @@ -1131,17 +1132,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return Res::Err; } - if let RibKind::ConstParamTy = all_ribs[rib_index].kind { - if let Some(span) = finalize { - self.report_error( - span, - ResolutionError::ParamInTyOfConstParam { name: rib_ident.name }, - ); - } - assert_eq!(res, Res::Err); - return Res::Err; - } - match res { Res::Local(_) => { use ResolutionError::*; @@ -1153,7 +1143,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | RibKind::FnOrCoroutine | RibKind::Module(..) | RibKind::MacroDefinition(..) - | RibKind::ForwardGenericParamBan => { + | RibKind::ForwardGenericParamBan(_) => { // Nothing to do. Continue. } RibKind::Item(..) | RibKind::AssocItem => { @@ -1247,12 +1237,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | RibKind::MacroDefinition(..) | RibKind::InlineAsmSym | RibKind::AssocItem - | RibKind::ConstParamTy - | RibKind::ForwardGenericParamBan => { + | RibKind::ForwardGenericParamBan(_) => { // Nothing to do. Continue. continue; } + RibKind::ConstParamTy => { + if !self.tcx.features().generic_const_parameter_types() { + if let Some(span) = finalize { + self.report_error( + span, + ResolutionError::ParamInTyOfConstParam { + name: rib_ident.name, + }, + ); + } + return Res::Err; + } else { + continue; + } + } + RibKind::ConstantItem(trivial, _) => { if let ConstantHasGenerics::No(cause) = trivial { // HACK(min_const_generics): If we encounter `Self` in an anonymous @@ -1325,8 +1330,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | RibKind::MacroDefinition(..) | RibKind::InlineAsmSym | RibKind::AssocItem - | RibKind::ConstParamTy - | RibKind::ForwardGenericParamBan => continue, + | RibKind::ForwardGenericParamBan(_) => continue, + + RibKind::ConstParamTy => { + if !self.tcx.features().generic_const_parameter_types() { + if let Some(span) = finalize { + self.report_error( + span, + ResolutionError::ParamInTyOfConstParam { + name: rib_ident.name, + }, + ); + } + return Res::Err; + } else { + continue; + } + } RibKind::ConstantItem(trivial, _) => { if let ConstantHasGenerics::No(cause) = trivial { @@ -1377,6 +1397,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } _ => {} } + res } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2c3e4bb505cc..d28988cd74f1 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -207,7 +207,7 @@ pub(crate) enum RibKind<'ra> { /// All bindings in this rib are generic parameters that can't be used /// from the default of a generic parameter because they're not declared /// before said generic parameter. Also see the `visit_generics` override. - ForwardGenericParamBan, + ForwardGenericParamBan(ForwardGenericParamBanReason), /// We are inside of the type of a const parameter. Can't refer to any /// parameters. @@ -218,6 +218,12 @@ pub(crate) enum RibKind<'ra> { InlineAsmSym, } +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub(crate) enum ForwardGenericParamBanReason { + Default, + ConstParamTy, +} + impl RibKind<'_> { /// Whether this rib kind contains generic parameters, as opposed to local /// variables. @@ -232,7 +238,7 @@ impl RibKind<'_> { RibKind::ConstParamTy | RibKind::AssocItem | RibKind::Item(..) - | RibKind::ForwardGenericParamBan => true, + | RibKind::ForwardGenericParamBan(_) => true, } } @@ -246,7 +252,7 @@ impl RibKind<'_> { | RibKind::Item(..) | RibKind::ConstantItem(..) | RibKind::Module(..) - | RibKind::ForwardGenericParamBan + | RibKind::ForwardGenericParamBan(_) | RibKind::ConstParamTy | RibKind::InlineAsmSym => true, } @@ -1561,8 +1567,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // provide previous type parameters as they're built. We // put all the parameters on the ban list and then remove // them one by one as they are processed and become available. - let mut forward_ty_ban_rib = Rib::new(RibKind::ForwardGenericParamBan); - let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan); + let mut forward_ty_ban_rib = + Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default)); + let mut forward_const_ban_rib = + Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default)); for param in params.iter() { match param.kind { GenericParamKind::Type { .. } => { @@ -1593,16 +1601,24 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err); } + // NOTE: We use different ribs here not for a technical reason, but just + // for better diagnostics. let mut forward_ty_ban_rib_const_param_ty = Rib { bindings: forward_ty_ban_rib.bindings.clone(), patterns_with_skipped_bindings: FxHashMap::default(), - kind: RibKind::ConstParamTy, + kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy), }; let mut forward_const_ban_rib_const_param_ty = Rib { bindings: forward_const_ban_rib.bindings.clone(), patterns_with_skipped_bindings: FxHashMap::default(), - kind: RibKind::ConstParamTy, + kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy), }; + // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better + // diagnostics, so we don't mention anything about const param tys having generics at all. + if !self.r.tcx.features().generic_const_parameter_types() { + forward_ty_ban_rib_const_param_ty.bindings.clear(); + forward_const_ban_rib_const_param_ty.bindings.clear(); + } self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { for param in params { @@ -1628,9 +1644,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Allow all following defaults to refer to this type parameter. let i = &Ident::with_dummy_span(param.ident.name); forward_ty_ban_rib.bindings.remove(i); - if this.r.tcx.features().generic_const_parameter_types() { - forward_ty_ban_rib_const_param_ty.bindings.remove(i); - } + forward_ty_ban_rib_const_param_ty.bindings.remove(i); } GenericParamKind::Const { ref ty, kw_span: _, ref default } => { // Const parameters can't have param bounds. @@ -1641,9 +1655,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if this.r.tcx.features().generic_const_parameter_types() { this.visit_ty(ty) } else { + this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy)); + this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy)); this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| { this.visit_ty(ty) }); + this.ribs[TypeNS].pop().unwrap(); + this.ribs[ValueNS].pop().unwrap(); } forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap(); forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap(); @@ -1662,9 +1680,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Allow all following defaults to refer to this const parameter. let i = &Ident::with_dummy_span(param.ident.name); forward_const_ban_rib.bindings.remove(i); - if this.r.tcx.features().generic_const_parameter_types() { - forward_const_ban_rib_const_param_ty.bindings.remove(i); - } + forward_const_ban_rib_const_param_ty.bindings.remove(i); } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ccdca8552320..e6fc390f24ca 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -32,7 +32,10 @@ use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; use effective_visibilities::EffectiveVisibilitiesVisitor; use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; use imports::{Import, ImportData, ImportKind, NameResolution}; -use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification}; +use late::{ + ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource, + UnnecessaryQualification, +}; use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::expand::StrippedCfgItem; @@ -273,7 +276,7 @@ enum ResolutionError<'ra> { shadowed_binding_span: Span, }, /// Error E0128: generic parameters with a default cannot use forward-declared identifiers. - ForwardDeclaredGenericParam, + ForwardDeclaredGenericParam(Symbol, ForwardGenericParamBanReason), // FIXME(generic_const_parameter_types): This should give custom output specifying it's only // problematic to use *forward declared* parameters when the feature is enabled. /// ERROR E0770: the type of const parameters must not depend on other generic parameters. @@ -287,7 +290,7 @@ enum ResolutionError<'ra> { /// This error is emitted even with `generic_const_exprs`. ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant }, /// Error E0735: generic parameters with a default cannot use `Self` - SelfInGenericParamDefault, + ForwardDeclaredSelf(ForwardGenericParamBanReason), /// Error E0767: use of unreachable label UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option }, /// Error E0323, E0324, E0325: mismatch between trait item and impl item. diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.rs b/tests/ui/const-generics/const-param-type-depends-on-const-param.rs index ee0e1326baa8..3372ea5b8531 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.rs +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.rs @@ -9,11 +9,11 @@ // We may want to lift this restriction in the future. pub struct Dependent([(); N]); -//~^ ERROR: the type of const parameters must not depend on other generic parameters -//[min]~^^ ERROR `[u8; N]` is forbidden +//~^ ERROR the type of const parameters must not depend on other generic parameters +//[min]~^^ ERROR `[u8; N]` is forbidden as the type of a const generic parameter pub struct SelfDependent; -//~^ ERROR: the type of const parameters must not depend on other generic parameters -//[min]~^^ ERROR `[u8; N]` is forbidden +//~^ ERROR the type of const parameters must not depend on other generic parameters +//[min]~^^ ERROR `[u8; N]` is forbidden as the type of a const generic parameter fn main() {} diff --git a/tests/ui/const-generics/const-param-type-depends-on-parent-param.rs b/tests/ui/const-generics/const-param-type-depends-on-parent-param.rs new file mode 100644 index 000000000000..83fe8c139f90 --- /dev/null +++ b/tests/ui/const-generics/const-param-type-depends-on-parent-param.rs @@ -0,0 +1,8 @@ +#![feature(adt_const_params)] + +trait Trait { + fn foo() {} + //~^ ERROR the type of const parameters must not depend on other generic parameters +} + +fn main() {} diff --git a/tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr b/tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr new file mode 100644 index 000000000000..ed0a4b118d49 --- /dev/null +++ b/tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr @@ -0,0 +1,9 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/const-param-type-depends-on-parent-param.rs:4:26 + | +LL | fn foo() {} + | ^ the type must not depend on the parameter `N` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr b/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr index 72d7001fdf1b..c074e2e897e9 100644 --- a/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr +++ b/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr @@ -2,19 +2,19 @@ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/default-const-param-cannot-reference-self.rs:1:34 | LL | struct Struct; - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/default-const-param-cannot-reference-self.rs:4:30 | LL | enum Enum { } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/default-const-param-cannot-reference-self.rs:7:32 | LL | union Union { not_empty: () } - | ^^^^ `Self` in generic parameter default + | ^^^^ error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/defaults/forward-declared.rs b/tests/ui/const-generics/defaults/forward-declared.rs index ede3d873bdcf..bd3abd4dcaa6 100644 --- a/tests/ui/const-generics/defaults/forward-declared.rs +++ b/tests/ui/const-generics/defaults/forward-declared.rs @@ -1,13 +1,13 @@ struct Foo; -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared enum Bar {} -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared struct Foo2; -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared enum Bar2 {} -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared fn main() {} diff --git a/tests/ui/const-generics/defaults/forward-declared.stderr b/tests/ui/const-generics/defaults/forward-declared.stderr index 4856c7a1fd2d..4331996bffcd 100644 --- a/tests/ui/const-generics/defaults/forward-declared.stderr +++ b/tests/ui/const-generics/defaults/forward-declared.stderr @@ -1,26 +1,26 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/forward-declared.rs:1:29 | LL | struct Foo; - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `M` before it is declared -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/forward-declared.rs:4:27 | LL | enum Bar {} - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `M` before it is declared -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/forward-declared.rs:7:30 | LL | struct Foo2; - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `N` before it is declared -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/forward-declared.rs:10:28 | LL | enum Bar2 {} - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `N` before it is declared error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs index 91c1c80e07c8..2abf7f44e203 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs +++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs @@ -4,8 +4,8 @@ use std::marker::PhantomData; struct UsesConst; -//~^ ERROR: the type of const parameters must not depend on other generic parameters +//~^ ERROR: const parameter types cannot reference parameters before they are declared struct UsesType(PhantomData); -//~^ ERROR: the type of const parameters must not depend on other generic parameters +//~^ ERROR: const parameter types cannot reference parameters before they are declared fn main() {} diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr index b0dbdff84136..5526668b0be9 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr @@ -1,15 +1,14 @@ -error[E0770]: the type of const parameters must not depend on other generic parameters +error: const parameter types cannot reference parameters before they are declared --> $DIR/forward_declared_type.rs:6:32 | LL | struct UsesConst; - | ^ the type must not depend on the parameter `M` + | ^ const parameter type cannot reference `M` before it is declared -error[E0770]: the type of const parameters must not depend on other generic parameters +error: const parameter types cannot reference parameters before they are declared --> $DIR/forward_declared_type.rs:8:27 | LL | struct UsesType(PhantomData); - | ^ the type must not depend on the parameter `T` + | ^ const parameter type cannot reference `T` before it is declared error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr index 29171c8006af..2d47797aef28 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr @@ -16,7 +16,7 @@ LL | type Assoc; = note: the only supported types are integers, `bool`, and `char` error: anonymous constants referencing generics are not yet supported - --> $DIR/references-parent-generics.rs:14:21 + --> $DIR/references-parent-generics.rs:15:21 | LL | let x: T::Assoc<3>; | ^ diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr index 64b413188144..68ce17317f69 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr @@ -1,16 +1,9 @@ -error: `Self` is forbidden as the type of a const generic parameter +error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/references-parent-generics.rs:7:25 | LL | type Assoc; - | ^^^^ - | - = note: the only supported types are integers, `bool`, and `char` + | ^^^^ the type must not depend on the parameter `Self` -error: anonymous constants referencing generics are not yet supported - --> $DIR/references-parent-generics.rs:14:21 - | -LL | let x: T::Assoc<3>; - | ^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs index 21994eb83b42..b91050d540c9 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs @@ -5,14 +5,15 @@ trait Foo { type Assoc; - //~^ ERROR `Self` is forbidden as the type of a const generic parameter + //[nofeat]~^ ERROR the type of const parameters must not depend on other generic parameters + //[feat]~^^ ERROR `Self` is forbidden as the type of a const generic parameter } fn foo() { // We used to end up feeding the type of this anon const to be `T`, but the anon const // doesn't inherit the generics of `foo`, which led to index oob errors. let x: T::Assoc<3>; - //~^ ERROR anonymous constants referencing generics are not yet supported + //[feat]~^ ERROR anonymous constants referencing generics are not yet supported } fn main() {} diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr index 9f0b2efae96c..dc28dea6851a 100644 --- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr +++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr @@ -4,11 +4,11 @@ error: generic parameters with a default must be trailing LL | struct Bar(T); | ^ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 | LL | struct Bar(T); - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `N` before it is declared error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr index 320c9c1c84de..3f0e5e96fc81 100644 --- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr +++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr @@ -13,11 +13,11 @@ LL | struct Foo()]>(T, U); = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 | LL | struct Bar(T); - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `N` before it is declared error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs index 2794ff3eaa9c..d212cc425a06 100644 --- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs +++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs @@ -6,7 +6,7 @@ struct Foo()]>(T, U); //[min]~^ ERROR generic parameters may not be used in const operations struct Bar(T); -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared //~| ERROR generic parameters with a default fn main() {} diff --git a/tests/ui/error-codes/E0128.stderr b/tests/ui/error-codes/E0128.stderr index c1ccb4c9e744..22f1e200e29c 100644 --- a/tests/ui/error-codes/E0128.stderr +++ b/tests/ui/error-codes/E0128.stderr @@ -1,8 +1,8 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/E0128.rs:1:14 | LL | struct Foo { - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `U` before it is declared error: aborting due to 1 previous error diff --git a/tests/ui/generics/generic-non-trailing-defaults.rs b/tests/ui/generics/generic-non-trailing-defaults.rs index 16ea71d48c82..ef500c420680 100644 --- a/tests/ui/generics/generic-non-trailing-defaults.rs +++ b/tests/ui/generics/generic-non-trailing-defaults.rs @@ -5,6 +5,6 @@ struct Vec(A, T); struct Foo, C>(A, B, C); //~^ ERROR generic parameters with a default must be trailing -//~| ERROR generic parameters with a default cannot use +//~| ERROR generic parameter defaults cannot reference parameters before they are declared fn main() {} diff --git a/tests/ui/generics/generic-non-trailing-defaults.stderr b/tests/ui/generics/generic-non-trailing-defaults.stderr index 713ba091b861..d9057e932f5f 100644 --- a/tests/ui/generics/generic-non-trailing-defaults.stderr +++ b/tests/ui/generics/generic-non-trailing-defaults.stderr @@ -10,11 +10,11 @@ error: generic parameters with a default must be trailing LL | struct Foo, C>(A, B, C); | ^ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/generic-non-trailing-defaults.rs:6:23 | LL | struct Foo, C>(A, B, C); - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `C` before it is declared error: aborting due to 3 previous errors diff --git a/tests/ui/generics/generic-type-params-forward-mention.rs b/tests/ui/generics/generic-type-params-forward-mention.rs index 000c47095d27..4a8f76d34aa9 100644 --- a/tests/ui/generics/generic-type-params-forward-mention.rs +++ b/tests/ui/generics/generic-type-params-forward-mention.rs @@ -1,6 +1,6 @@ // Ensure that we get an error and not an ICE for this problematic case. struct Foo, U = bool>(T, U); -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared fn main() { let x: Foo; } diff --git a/tests/ui/generics/generic-type-params-forward-mention.stderr b/tests/ui/generics/generic-type-params-forward-mention.stderr index d7a6faa19410..ecc2387b48be 100644 --- a/tests/ui/generics/generic-type-params-forward-mention.stderr +++ b/tests/ui/generics/generic-type-params-forward-mention.stderr @@ -1,8 +1,8 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/generic-type-params-forward-mention.rs:2:23 | LL | struct Foo, U = bool>(T, U); - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `U` before it is declared error: aborting due to 1 previous error diff --git a/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr b/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr index f3a550801b9b..f659a144deff 100644 --- a/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr +++ b/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr @@ -2,37 +2,37 @@ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:13:25 | LL | struct Snobound<'a, P = Self> { x: Option<&'a P> } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:16:23 | LL | enum Enobound<'a, P = Self> { A, B(Option<&'a P>) } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:19:24 | LL | union Unobound<'a, P = Self> { x: i32, y: Option<&'a P> } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:25:31 | LL | struct Ssized<'a, P: Sized = [Self]> { x: Option<&'a P> } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:28:29 | LL | enum Esized<'a, P: Sized = [Self]> { A, B(Option<&'a P>) } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:31:30 | LL | union Usized<'a, P: Sized = [Self]> { x: i32, y: Option<&'a P> } - | ^^^^ `Self` in generic parameter default + | ^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/issues/issue-18183.stderr b/tests/ui/issues/issue-18183.stderr index 11015d75d973..07fa4cdc7535 100644 --- a/tests/ui/issues/issue-18183.stderr +++ b/tests/ui/issues/issue-18183.stderr @@ -1,8 +1,8 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/issue-18183.rs:1:20 | LL | pub struct Foo(Bar); - | ^^^ defaulted generic parameters cannot be forward declared + | ^^^ cannot reference `Bar` before it is declared error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-26812.rs b/tests/ui/issues/issue-26812.rs index e0723e016b38..8eb030a8ec94 100644 --- a/tests/ui/issues/issue-26812.rs +++ b/tests/ui/issues/issue-26812.rs @@ -1,5 +1,5 @@ fn avg(_: T) {} -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared //~| ERROR defaults for type parameters //~| WARN previously accepted diff --git a/tests/ui/issues/issue-26812.stderr b/tests/ui/issues/issue-26812.stderr index 4a18b23fd8b1..bb60d67e2876 100644 --- a/tests/ui/issues/issue-26812.stderr +++ b/tests/ui/issues/issue-26812.stderr @@ -1,8 +1,8 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/issue-26812.rs:1:10 | LL | fn avg(_: T) {} - | ^^^^^^^ defaulted generic parameters cannot be forward declared + | ^^^^^^^ cannot reference `T` before it is declared error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions --> $DIR/issue-26812.rs:1:8

( _baz: P, ) { // CHECK-LABEL: fn bar( - // CHECK: let mut {{.*}}: &fn() {foo}; - // CHECK: let {{.*}}: fn() {foo}; // CHECK: (inlined hide_foo) - // CHECK-NOT: inlined + // CHECK: (inlined >::call - shim(fn() {foo})) + // CHECK: (inlined foo) hide_foo()(); } diff --git a/tests/mir-opt/inline_fn_call_for_fn_def.rs b/tests/mir-opt/inline_fn_call_for_fn_def.rs new file mode 100644 index 000000000000..7601feda5732 --- /dev/null +++ b/tests/mir-opt/inline_fn_call_for_fn_def.rs @@ -0,0 +1,19 @@ +//@ test-mir-pass: Inline +//@ compile-flags: --crate-type=lib -C panic=abort + +// EMIT_MIR inline_fn_call_for_fn_def.test.Inline.diff + +fn inline_fn(x: impl FnOnce() -> i32) -> i32 { + x() +} + +fn yield_number() -> i32 { + 64 +} + +fn test() -> i32 { + // CHECK: (inlined inline_fn:: i32 {yield_number}>) + // CHECK: (inlined i32 {yield_number} as FnOnce<()>>::call_once - shim(fn() -> i32 {yield_number})) + // CHECK: (inlined yield_number) + inline_fn(yield_number) +} diff --git a/tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff b/tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff new file mode 100644 index 000000000000..aef7aa239709 --- /dev/null +++ b/tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff @@ -0,0 +1,34 @@ +- // MIR for `test` before Inline ++ // MIR for `test` after Inline + + fn test() -> i32 { + let mut _0: i32; +- +- bb0: { +- _0 = inline_fn:: i32 {yield_number}>(yield_number) -> [return: bb1, unwind unreachable]; ++ let mut _1: fn() -> i32 {yield_number}; ++ scope 1 (inlined inline_fn:: i32 {yield_number}>) { ++ let mut _2: fn() -> i32 {yield_number}; ++ let mut _3: (); ++ scope 2 (inlined i32 {yield_number} as FnOnce<()>>::call_once - shim(fn() -> i32 {yield_number})) { ++ scope 3 (inlined yield_number) { ++ } ++ } + } + +- bb1: { ++ bb0: { ++ StorageLive(_1); ++ _1 = yield_number; ++ StorageLive(_2); ++ _2 = move _1; ++ StorageLive(_3); ++ _3 = (); ++ _0 = const 64_i32; ++ StorageDead(_3); ++ StorageDead(_2); ++ StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir similarity index 100% rename from tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir rename to tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir similarity index 100% rename from tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir rename to tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir new file mode 100644 index 000000000000..5876c55c52b9 --- /dev/null +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir @@ -0,0 +1,68 @@ +// MIR for `num_to_digit` after PreCodegen + +fn num_to_digit(_1: char) -> u32 { + debug num => _1; + let mut _0: u32; + let mut _4: std::option::Option; + scope 1 (inlined char::methods::::is_digit) { + let _2: std::option::Option; + scope 2 (inlined Option::::is_some) { + let mut _3: isize; + } + } + scope 3 (inlined #[track_caller] Option::::unwrap) { + let mut _5: isize; + let mut _6: !; + scope 4 { + } + } + + bb0: { + StorageLive(_2); + _2 = char::methods::::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageLive(_3); + _3 = discriminant(_2); + StorageDead(_2); + switchInt(move _3) -> [1: bb2, otherwise: bb7]; + } + + bb2: { + StorageDead(_3); + StorageLive(_4); + _4 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageLive(_5); + _5 = discriminant(_4); + switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6]; + } + + bb4: { + _6 = option::unwrap_failed() -> unwind unreachable; + } + + bb5: { + _0 = move ((_4 as Some).0: u32); + StorageDead(_5); + StorageDead(_4); + goto -> bb8; + } + + bb6: { + unreachable; + } + + bb7: { + StorageDead(_3); + _0 = const 0_u32; + goto -> bb8; + } + + bb8: { + return; + } +} diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir new file mode 100644 index 000000000000..f1185353a43c --- /dev/null +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir @@ -0,0 +1,68 @@ +// MIR for `num_to_digit` after PreCodegen + +fn num_to_digit(_1: char) -> u32 { + debug num => _1; + let mut _0: u32; + let mut _4: std::option::Option; + scope 1 (inlined char::methods::::is_digit) { + let _2: std::option::Option; + scope 2 (inlined Option::::is_some) { + let mut _3: isize; + } + } + scope 3 (inlined #[track_caller] Option::::unwrap) { + let mut _5: isize; + let mut _6: !; + scope 4 { + } + } + + bb0: { + StorageLive(_2); + _2 = char::methods::::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageLive(_3); + _3 = discriminant(_2); + StorageDead(_2); + switchInt(move _3) -> [1: bb2, otherwise: bb7]; + } + + bb2: { + StorageDead(_3); + StorageLive(_4); + _4 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue]; + } + + bb3: { + StorageLive(_5); + _5 = discriminant(_4); + switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6]; + } + + bb4: { + _6 = option::unwrap_failed() -> unwind continue; + } + + bb5: { + _0 = move ((_4 as Some).0: u32); + StorageDead(_5); + StorageDead(_4); + goto -> bb8; + } + + bb6: { + unreachable; + } + + bb7: { + StorageDead(_3); + _0 = const 0_u32; + goto -> bb8; + } + + bb8: { + return; + } +} diff --git a/tests/mir-opt/issues/issue_59352.rs b/tests/mir-opt/issues/issue_59352.rs index 9024dc976e49..516a712f1db1 100644 --- a/tests/mir-opt/issues/issue_59352.rs +++ b/tests/mir-opt/issues/issue_59352.rs @@ -1,4 +1,6 @@ // EMIT_MIR_FOR_EACH_PANIC_STRATEGY +// EMIT_MIR_FOR_EACH_BIT_WIDTH + // This test is a mirror of codegen/issue-59352.rs. // The LLVM inliner doesn't inline `char::method::is_digit()` and so it doesn't recognize this case // as effectively `if x.is_some() { x.unwrap() } else { 0 }`. diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir index 4977f39ccefe..d22ea54004c9 100644 --- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir @@ -29,6 +29,10 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { let mut _12: U; scope 6 { debug x => _10; + scope 7 (inlined ops::function::impls:: for &mut impl Fn(T) -> U>::call_once) { + debug self => _8; + debug args => _11; + } } } } @@ -85,7 +89,7 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { StorageLive(_12); StorageLive(_11); _11 = (copy _10,); - _12 = <&mut impl Fn(T) -> U as FnOnce<(T,)>>::call_once(move _8, move _11) -> [return: bb7, unwind: bb10]; + _12 = U as FnMut<(T,)>>::call_mut(move _8, move _11) -> [return: bb7, unwind: bb10]; } bb7: { From ab31129956869f6dfc25417230061bad72de9081 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 20:10:37 +0000 Subject: [PATCH 601/991] Point of macro expansion from call expr if it involves macro var --- .../rustc_hir_typeck/src/method/suggest.rs | 23 ++++++++++++++++--- compiler/rustc_span/src/lib.rs | 23 +++++++++++++++++++ .../ui/methods/ident-from-macro-expansion.rs | 18 +++++++++++++++ .../methods/ident-from-macro-expansion.stderr | 21 +++++++++++++++++ 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 tests/ui/methods/ident-from-macro-expansion.rs create mode 100644 tests/ui/methods/ident-from-macro-expansion.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 18218a7a0a64..41bd3933feec 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -158,7 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().used_trait_imports.insert(import_id); } - let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) { + let (span, expr_span, source, item_name, args) = match self.tcx.hir_node(call_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::MethodCall(segment, rcvr, args, _), span, @@ -194,6 +194,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { node => unreachable!("{node:?}"), }; + // Try to get the span of the identifier within the expression's syntax context (if that's different). + let within_macro_span = span.within_macro(expr_span); + // Avoid suggestions when we don't know what's going on. if let Err(guar) = rcvr_ty.error_reported() { return guar; @@ -207,10 +210,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_id, source, args, - sugg_span, + expr_span, &mut no_match_data, expected, trait_missing_method, + within_macro_span, ), MethodError::Ambiguity(mut sources) => { @@ -221,6 +225,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "multiple applicable items in scope" ); err.span_label(item_name.span, format!("multiple `{item_name}` found")); + if let Some(within_macro_span) = within_macro_span { + err.span_label(within_macro_span, "due to this macro variable"); + } self.note_candidates_on_method_error( rcvr_ty, @@ -230,7 +237,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, &mut err, &mut sources, - Some(sugg_span), + Some(expr_span), ); err.emit() } @@ -252,6 +259,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .span_if_local(def_id) .unwrap_or_else(|| self.tcx.def_span(def_id)); err.span_label(sp, format!("private {kind} defined here")); + if let Some(within_macro_span) = within_macro_span { + err.span_label(within_macro_span, "due to this macro variable"); + } self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true); err.emit() } @@ -268,6 +278,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !needs_mut { err.span_label(bound_span, "this has a `Sized` requirement"); } + if let Some(within_macro_span) = within_macro_span { + err.span_label(within_macro_span, "due to this macro variable"); + } if !candidates.is_empty() { let help = format!( "{an}other candidate{s} {were} found in the following trait{s}", @@ -581,6 +594,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, + within_macro_span: Option, ) -> ErrorGuaranteed { let mode = no_match_data.mode; let tcx = self.tcx; @@ -721,6 +735,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if tcx.sess.source_map().is_multiline(sugg_span) { err.span_label(sugg_span.with_hi(span.lo()), ""); } + if let Some(within_macro_span) = within_macro_span { + err.span_label(within_macro_span, "due to this macro variable"); + } if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 { ty_str = short_ty_str; diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index bca9323a50d4..d23e1825e6ea 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1057,6 +1057,29 @@ impl Span { } } + /// Returns the `Span` within the syntax context of "within". This is useful when + /// "self" is an expansion from a macro variable, since this can be used for + /// providing extra macro expansion context for certain errors. + /// + /// ```text + /// macro_rules! m { + /// ($ident:ident) => { ($ident,) } + /// } + /// + /// m!(outer_ident); + /// ``` + /// + /// If "self" is the span of the outer_ident, and "within" is the span of the `($ident,)` + /// expr, then this will return the span of the `$ident` macro variable. + pub fn within_macro(self, within: Span) -> Option { + match Span::prepare_to_combine(self, within) { + Ok((self_, _, parent)) if self_.lo != self.lo() && self.hi() != self_.hi => { + Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent)) + } + _ => None, + } + } + pub fn from_inner(self, inner: InnerSpan) -> Span { let span = self.data(); Span::new( diff --git a/tests/ui/methods/ident-from-macro-expansion.rs b/tests/ui/methods/ident-from-macro-expansion.rs new file mode 100644 index 000000000000..38d2fee0e53c --- /dev/null +++ b/tests/ui/methods/ident-from-macro-expansion.rs @@ -0,0 +1,18 @@ +macro_rules! dot { + ($id:ident) => { + ().$id(); + } +} + +macro_rules! dispatch { + ($id:ident) => { + <()>::$id(); + } +} + +fn main() { + dot!(hello); + //~^ ERROR no method named `hello` found for unit type `()` in the current scope + dispatch!(hello); + //~^ ERROR no function or associated item named `hello` found for unit type `()` in the current scope +} diff --git a/tests/ui/methods/ident-from-macro-expansion.stderr b/tests/ui/methods/ident-from-macro-expansion.stderr new file mode 100644 index 000000000000..b596ce29f6fe --- /dev/null +++ b/tests/ui/methods/ident-from-macro-expansion.stderr @@ -0,0 +1,21 @@ +error[E0599]: no method named `hello` found for unit type `()` in the current scope + --> $DIR/ident-from-macro-expansion.rs:14:10 + | +LL | ().$id(); + | --- due to this macro variable +... +LL | dot!(hello); + | ^^^^^ method not found in `()` + +error[E0599]: no function or associated item named `hello` found for unit type `()` in the current scope + --> $DIR/ident-from-macro-expansion.rs:16:15 + | +LL | <()>::$id(); + | --- due to this macro variable +... +LL | dispatch!(hello); + | ^^^^^ function or associated item not found in `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. From e4dfca8ac240d517e5d7008333fd7d3367d0176f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 20:20:54 +0000 Subject: [PATCH 602/991] Point out macro expansion ident in resolver errors too --- compiler/rustc_hir_typeck/src/method/suggest.rs | 3 ++- compiler/rustc_resolve/src/late/diagnostics.rs | 6 ++++++ tests/ui/hygiene/generate-mod.stderr | 6 ++++++ tests/ui/hygiene/globs.stderr | 6 ++++++ tests/ui/macros/macro-parameter-span.stderr | 3 +++ tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr | 3 +++ 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 41bd3933feec..09e1390cc3ec 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -194,7 +194,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { node => unreachable!("{node:?}"), }; - // Try to get the span of the identifier within the expression's syntax context (if that's different). + // Try to get the span of the identifier within the expression's syntax context + // (if that's different). let within_macro_span = span.within_macro(expr_span); // Avoid suggestions when we don't know what's going on. diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0e14e7671b17..c86305e23d1d 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -429,6 +429,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut err = self.r.dcx().struct_span_err(base_error.span, base_error.msg.clone()); err.code(code); + // Try to get the span of the identifier within the path's syntax context + // (if that's different). + if let Some(within_macro_span) = base_error.span.within_macro(span) { + err.span_label(within_macro_span, "within this macro"); + } + self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg); self.suggest_at_operator_in_slice_pat_with_range(&mut err, path); self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); diff --git a/tests/ui/hygiene/generate-mod.stderr b/tests/ui/hygiene/generate-mod.stderr index 32a2e145ca94..58b9c642dabe 100644 --- a/tests/ui/hygiene/generate-mod.stderr +++ b/tests/ui/hygiene/generate-mod.stderr @@ -1,12 +1,18 @@ error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:35:13 | +LL | type A = $FromOutside; + | ------------ due to this macro variable +... LL | genmod!(FromOutside, Outer); | ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:35:26 | +LL | struct $Outer; + | ------ due to this macro variable +... LL | genmod!(FromOutside, Outer); | ^^^^^ not found in this scope diff --git a/tests/ui/hygiene/globs.stderr b/tests/ui/hygiene/globs.stderr index 3f7a0ae7efa1..31f25b182f1f 100644 --- a/tests/ui/hygiene/globs.stderr +++ b/tests/ui/hygiene/globs.stderr @@ -50,6 +50,9 @@ error[E0425]: cannot find function `f` in this scope LL | n!(f); | ----- in this macro invocation ... +LL | $j(); + | -- due to this macro variable +... LL | n!(f); | ^ not found in this scope | @@ -63,6 +66,9 @@ error[E0425]: cannot find function `f` in this scope LL | n!(f); | ----- in this macro invocation ... +LL | $j(); + | -- due to this macro variable +... LL | f | ^ not found in this scope | diff --git a/tests/ui/macros/macro-parameter-span.stderr b/tests/ui/macros/macro-parameter-span.stderr index 247750a8ad70..44c8c56dff99 100644 --- a/tests/ui/macros/macro-parameter-span.stderr +++ b/tests/ui/macros/macro-parameter-span.stderr @@ -1,6 +1,9 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/macro-parameter-span.rs:11:9 | +LL | $id + | --- due to this macro variable +... LL | x | ^ not found in this scope diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr index ce7694ecb1da..d9646760cea9 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr @@ -338,6 +338,9 @@ LL | no_curly__no_rhs_dollar__no_round!(a); error[E0425]: cannot find value `a` in this scope --> $DIR/syntax-errors.rs:152:37 | +LL | ( $i:ident ) => { count($i) }; + | -- due to this macro variable +... LL | no_curly__rhs_dollar__no_round!(a); | ^ not found in this scope From 06072468fe8de249a39d2fcc42cea51db2649a80 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 20:36:15 +0000 Subject: [PATCH 603/991] Fix associated type errors too --- compiler/rustc_hir_analysis/messages.ftl | 2 ++ compiler/rustc_hir_analysis/src/errors.rs | 2 ++ .../src/hir_ty_lowering/errors.rs | 3 +++ .../ident-from-macro-expansion.rs | 23 +++++++++++++++++++ .../ident-from-macro-expansion.stderr | 22 ++++++++++++++++++ 5 files changed, 52 insertions(+) create mode 100644 tests/ui/associated-types/ident-from-macro-expansion.rs create mode 100644 tests/ui/associated-types/ident-from-macro-expansion.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 3f75cce00922..c2a6b5a890ec 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -620,6 +620,8 @@ hir_analysis_variances_of = {$variances} hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause .label = `main` cannot have a `where` clause +hir_analysis_within_macro = due to this macro variable + hir_analysis_wrong_number_of_generic_arguments_to_intrinsic = intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected} .label = expected {$expected} {$descr} {$expected -> diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 852533ff5c95..78b28048c8b0 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -84,6 +84,8 @@ pub(crate) struct AssocItemNotFound<'a> { pub label: Option>, #[subdiagnostic] pub sugg: Option>, + #[label(hir_analysis_within_macro)] + pub within_macro_span: Option, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 922578792ba8..156ddb8f2aab 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -151,6 +151,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { qself: &qself_str, label: None, sugg: None, + // Try to get the span of the identifier within the path's syntax context + // (if that's different). + within_macro_span: assoc_name.span.within_macro(span), }; if is_dummy { diff --git a/tests/ui/associated-types/ident-from-macro-expansion.rs b/tests/ui/associated-types/ident-from-macro-expansion.rs new file mode 100644 index 000000000000..6aabe4571406 --- /dev/null +++ b/tests/ui/associated-types/ident-from-macro-expansion.rs @@ -0,0 +1,23 @@ +trait Trait {} +impl Trait for () {} + +macro_rules! fully_qualified { + ($id:ident) => { + <() as Trait>::$id + } +} + +macro_rules! type_dependent { + ($t:ident, $id:ident) => { + T::$id + } +} + +fn t() { + let x: fully_qualified!(Assoc); + //~^ ERROR cannot find associated type `Assoc` in trait `Trait` + let x: type_dependent!(T, Assoc); + //~^ ERROR associated type `Assoc` not found for `T` +} + +fn main() {} diff --git a/tests/ui/associated-types/ident-from-macro-expansion.stderr b/tests/ui/associated-types/ident-from-macro-expansion.stderr new file mode 100644 index 000000000000..dabf13c2c172 --- /dev/null +++ b/tests/ui/associated-types/ident-from-macro-expansion.stderr @@ -0,0 +1,22 @@ +error[E0576]: cannot find associated type `Assoc` in trait `Trait` + --> $DIR/ident-from-macro-expansion.rs:17:29 + | +LL | <() as Trait>::$id + | --- due to this macro variable +... +LL | let x: fully_qualified!(Assoc); + | ^^^^^ not found in `Trait` + +error[E0220]: associated type `Assoc` not found for `T` + --> $DIR/ident-from-macro-expansion.rs:19:31 + | +LL | T::$id + | --- due to this macro variable +... +LL | let x: type_dependent!(T, Assoc); + | ^^^^^ associated type `Assoc` not found + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0220, E0576. +For more information about an error, try `rustc --explain E0220`. From 09e584671b439dc8a9d57cc900cc26668a69ddea Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 21:37:01 +0000 Subject: [PATCH 604/991] Also note struct access, and fix macro expansion from foreign crates --- .../src/hir_ty_lowering/errors.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 35 ++++++++++++------- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 6 ++-- compiler/rustc_span/src/lib.rs | 12 +++++-- .../ui/structs/ident-from-macro-expansion.rs | 19 ++++++++++ .../structs/ident-from-macro-expansion.stderr | 14 ++++++++ 7 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 tests/ui/structs/ident-from-macro-expansion.rs create mode 100644 tests/ui/structs/ident-from-macro-expansion.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 156ddb8f2aab..6b9c1c0b309a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -153,7 +153,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { sugg: None, // Try to get the span of the identifier within the path's syntax context // (if that's different). - within_macro_span: assoc_name.span.within_macro(span), + within_macro_span: assoc_name.span.within_macro(span, tcx.sess.source_map()), }; if is_dummy { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index dec1779d92ca..7f67e524fc4a 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3069,7 +3069,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}", ident, base, expr, base_ty ); - let mut err = self.no_such_field_err(ident, base_ty, base.hir_id); + let mut err = self.no_such_field_err(ident, base_ty, expr); match *base_ty.peel_refs().kind() { ty::Array(_, len) => { @@ -3282,18 +3282,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - fn no_such_field_err(&self, field: Ident, expr_t: Ty<'tcx>, id: HirId) -> Diag<'_> { + fn no_such_field_err( + &self, + field: Ident, + base_ty: Ty<'tcx>, + expr: &hir::Expr<'tcx>, + ) -> Diag<'_> { let span = field.span; - debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t); + debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, base_ty); - let mut err = self.dcx().create_err(NoFieldOnType { span, ty: expr_t, field }); - if expr_t.references_error() { + let mut err = self.dcx().create_err(NoFieldOnType { span, ty: base_ty, field }); + if base_ty.references_error() { err.downgrade_to_delayed_bug(); } + if let Some(within_macro_span) = span.within_macro(expr.span, self.tcx.sess.source_map()) { + err.span_label(within_macro_span, "due to this macro variable"); + } + // try to add a suggestion in case the field is a nested field of a field of the Adt - let mod_id = self.tcx.parent_module(id).to_def_id(); - let (ty, unwrap) = if let ty::Adt(def, args) = expr_t.kind() + let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id(); + let (ty, unwrap) = if let ty::Adt(def, args) = base_ty.kind() && (self.tcx.is_diagnostic_item(sym::Result, def.did()) || self.tcx.is_diagnostic_item(sym::Option, def.did())) && let Some(arg) = args.get(0) @@ -3301,10 +3310,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { (ty, "unwrap().") } else { - (expr_t, "") + (base_ty, "") }; for (found_fields, args) in - self.get_field_candidates_considering_privacy_for_diag(span, ty, mod_id, id) + self.get_field_candidates_considering_privacy_for_diag(span, ty, mod_id, expr.hir_id) { let field_names = found_fields.iter().map(|field| field.name).collect::>(); let mut candidate_fields: Vec<_> = found_fields @@ -3317,7 +3326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { args, vec![], mod_id, - id, + expr.hir_id, ) }) .map(|mut field_path| { @@ -3328,7 +3337,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { candidate_fields.sort(); let len = candidate_fields.len(); - if len > 0 { + // Don't suggest `.field` if the base expr is from a different + // syntax context than the field. + if len > 0 && expr.span.eq_ctxt(field.span) { err.span_suggestions( field.span.shrink_to_lo(), format!( @@ -3963,7 +3974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => (), }; - self.no_such_field_err(field, container, expr.hir_id).emit(); + self.no_such_field_err(field, container, expr).emit(); break; } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 09e1390cc3ec..cb1e89fb9e59 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -196,7 +196,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Try to get the span of the identifier within the expression's syntax context // (if that's different). - let within_macro_span = span.within_macro(expr_span); + let within_macro_span = span.within_macro(expr_span, self.tcx.sess.source_map()); // Avoid suggestions when we don't know what's going on. if let Err(guar) = rcvr_ty.error_reported() { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index c86305e23d1d..47b21f86641b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -431,8 +431,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // Try to get the span of the identifier within the path's syntax context // (if that's different). - if let Some(within_macro_span) = base_error.span.within_macro(span) { - err.span_label(within_macro_span, "within this macro"); + if let Some(within_macro_span) = + base_error.span.within_macro(span, self.r.tcx.sess.source_map()) + { + err.span_label(within_macro_span, "due to this macro variable"); } self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index d23e1825e6ea..798e186a94b1 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1071,9 +1071,17 @@ impl Span { /// /// If "self" is the span of the outer_ident, and "within" is the span of the `($ident,)` /// expr, then this will return the span of the `$ident` macro variable. - pub fn within_macro(self, within: Span) -> Option { + pub fn within_macro(self, within: Span, sm: &SourceMap) -> Option { match Span::prepare_to_combine(self, within) { - Ok((self_, _, parent)) if self_.lo != self.lo() && self.hi() != self_.hi => { + // Only return something if it doesn't overlap with the original span, + // and the span isn't "imported" (i.e. from unavailable sources). + // FIXME: This does limit the usefulness of the error when the macro is + // from a foreign crate; we could also take into account `-Zmacro-backtrace`, + // which doesn't redact this span (but that would mean passing in even more + // args to this function, lol). + Ok((self_, _, parent)) + if self_.hi < self.lo() || self.hi() < self_.lo && !sm.is_imported(within) => + { Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent)) } _ => None, diff --git a/tests/ui/structs/ident-from-macro-expansion.rs b/tests/ui/structs/ident-from-macro-expansion.rs new file mode 100644 index 000000000000..56d31a425616 --- /dev/null +++ b/tests/ui/structs/ident-from-macro-expansion.rs @@ -0,0 +1,19 @@ +struct Foo { + inner: Inner, +} + +struct Inner { + y: i32, +} + +macro_rules! access { + ($expr:expr, $ident:ident) => { + $expr.$ident + } +} + +fn main() { + let k = Foo { inner: Inner { y: 0 } }; + access!(k, y); + //~^ ERROR no field `y` on type `Foo` +} diff --git a/tests/ui/structs/ident-from-macro-expansion.stderr b/tests/ui/structs/ident-from-macro-expansion.stderr new file mode 100644 index 000000000000..be2ab7c2e996 --- /dev/null +++ b/tests/ui/structs/ident-from-macro-expansion.stderr @@ -0,0 +1,14 @@ +error[E0609]: no field `y` on type `Foo` + --> $DIR/ident-from-macro-expansion.rs:17:16 + | +LL | $expr.$ident + | ------ due to this macro variable +... +LL | access!(k, y); + | ^ unknown field + | + = note: available field is: `inner` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0609`. From 3e5fddc95ea2d8851def90b940030d1c97bd5b00 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Mar 2025 05:25:46 +0000 Subject: [PATCH 605/991] Allow struct field default values to reference struct's generics --- .../src/collect/generics_of.rs | 2 ++ compiler/rustc_resolve/src/late.rs | 4 ++- .../structs/default-field-values/failures.rs | 4 +-- .../default-field-values/failures.stderr | 17 +---------- .../field-references-param.rs | 29 +++++++++++++++++++ .../post-mono.direct.stderr | 23 +++++++++++++++ .../post-mono.indirect.stderr | 29 +++++++++++++++++++ .../structs/default-field-values/post-mono.rs | 23 +++++++++++++++ 8 files changed, 112 insertions(+), 19 deletions(-) create mode 100644 tests/ui/structs/default-field-values/field-references-param.rs create mode 100644 tests/ui/structs/default-field-values/post-mono.direct.stderr create mode 100644 tests/ui/structs/default-field-values/post-mono.indirect.stderr create mode 100644 tests/ui/structs/default-field-values/post-mono.rs diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index af1338e50d00..a153ce8ea902 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -187,6 +187,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { Some(parent_did) } Node::TyPat(_) => Some(parent_did), + // Field default values inherit the ADT's generics. + Node::Field(_) => Some(parent_did), _ => None, } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f119ed55e7d1..3e8946d9291c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -78,6 +78,7 @@ struct IsNeverPattern; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum AnonConstKind { EnumDiscriminant, + FieldDefaultValue, InlineConst, ConstArg(IsRepeatExpr), } @@ -1406,7 +1407,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r visit_opt!(self, visit_ident, ident); try_visit!(self.visit_ty(ty)); if let Some(v) = &default { - self.resolve_anon_const(v, AnonConstKind::ConstArg(IsRepeatExpr::No)); + self.resolve_anon_const(v, AnonConstKind::FieldDefaultValue); } } } @@ -4658,6 +4659,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { AnonConstKind::EnumDiscriminant => { ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant) } + AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes, AnonConstKind::InlineConst => ConstantHasGenerics::Yes, AnonConstKind::ConstArg(_) => { if self.r.tcx.features().generic_const_exprs() || is_trivial_const_arg { diff --git a/tests/ui/structs/default-field-values/failures.rs b/tests/ui/structs/default-field-values/failures.rs index 0ac071d91d65..1e94eecb4f87 100644 --- a/tests/ui/structs/default-field-values/failures.rs +++ b/tests/ui/structs/default-field-values/failures.rs @@ -17,9 +17,9 @@ pub struct Bar { #[derive(Default)] pub struct Qux { - bar: S = Self::S, //~ ERROR generic `Self` types are currently not permitted in anonymous constants + bar: S = Self::S, baz: i32 = foo(), - bat: i32 = as T>::K, //~ ERROR generic parameters may not be used in const operations + bat: i32 = as T>::K, bay: i32 = C, } diff --git a/tests/ui/structs/default-field-values/failures.stderr b/tests/ui/structs/default-field-values/failures.stderr index 65ec100fe2ea..50553816462d 100644 --- a/tests/ui/structs/default-field-values/failures.stderr +++ b/tests/ui/structs/default-field-values/failures.stderr @@ -6,27 +6,12 @@ LL | Variant {} | = help: consider a manual implementation of `Default` -error: generic parameters may not be used in const operations - --> $DIR/failures.rs:22:23 - | -LL | bat: i32 = as T>::K, - | ^ cannot perform const operation using `C` - | - = help: const parameters may only be used as standalone arguments, i.e. `C` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - error: default fields are not supported in tuple structs --> $DIR/failures.rs:26:22 | LL | pub struct Rak(i32 = 42); | ^^ default fields are only supported on structs -error: generic `Self` types are currently not permitted in anonymous constants - --> $DIR/failures.rs:20:14 - | -LL | bar: S = Self::S, - | ^^^^ - error[E0277]: the trait bound `S: Default` is not satisfied --> $DIR/failures.rs:14:5 | @@ -112,7 +97,7 @@ LL - let _ = Rak(.., 0); LL + let _ = Rak(0); | -error: aborting due to 9 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0061, E0277, E0308. For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/structs/default-field-values/field-references-param.rs b/tests/ui/structs/default-field-values/field-references-param.rs new file mode 100644 index 000000000000..ecee37edd42c --- /dev/null +++ b/tests/ui/structs/default-field-values/field-references-param.rs @@ -0,0 +1,29 @@ +//@ build-pass + +#![feature(default_field_values)] + +struct W; + +impl W { + const fn new() -> Self { W } +} + +struct Z { + // No inference. + one: W = W::::new(), + + // Inference works too. + two: W = W::new(), + + // An anon const that is too generic before substitution. + too_generic: usize = X + 1, +} + +fn use_generically() { + let x: Z = Z { .. }; +} + +fn main() { + let x: Z<0> = Z { .. }; + use_generically::<0>(); +} diff --git a/tests/ui/structs/default-field-values/post-mono.direct.stderr b/tests/ui/structs/default-field-values/post-mono.direct.stderr new file mode 100644 index 000000000000..cdd80620c48a --- /dev/null +++ b/tests/ui/structs/default-field-values/post-mono.direct.stderr @@ -0,0 +1,23 @@ +error[E0080]: evaluation of `Z::<1>::post_mono::{constant#0}` failed + --> $DIR/post-mono.rs:7:24 + | +LL | post_mono: usize = X / 0, + | ^^^^^ attempt to divide `1_usize` by zero + +note: erroneous constant encountered + --> $DIR/post-mono.rs:17:19 + | +LL | let x: Z<1> = Z { .. }; + | ^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/post-mono.rs:17:19 + | +LL | let x: Z<1> = Z { .. }; + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/structs/default-field-values/post-mono.indirect.stderr b/tests/ui/structs/default-field-values/post-mono.indirect.stderr new file mode 100644 index 000000000000..56c27a6e5dc8 --- /dev/null +++ b/tests/ui/structs/default-field-values/post-mono.indirect.stderr @@ -0,0 +1,29 @@ +error[E0080]: evaluation of `Z::<1>::post_mono::{constant#0}` failed + --> $DIR/post-mono.rs:7:24 + | +LL | post_mono: usize = X / 0, + | ^^^^^ attempt to divide `1_usize` by zero + +note: erroneous constant encountered + --> $DIR/post-mono.rs:12:19 + | +LL | let x: Z = Z { .. }; + | ^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/post-mono.rs:12:19 + | +LL | let x: Z = Z { .. }; + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +note: the above error was encountered while instantiating `fn indirect::<1>` + --> $DIR/post-mono.rs:22:5 + | +LL | indirect::<1>(); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/structs/default-field-values/post-mono.rs b/tests/ui/structs/default-field-values/post-mono.rs new file mode 100644 index 000000000000..4de31f6e2fba --- /dev/null +++ b/tests/ui/structs/default-field-values/post-mono.rs @@ -0,0 +1,23 @@ +//@ build-fail +//@ revisions: direct indirect + +#![feature(default_field_values)] + +struct Z { + post_mono: usize = X / 0, + //~^ ERROR evaluation of `Z::<1>::post_mono::{constant#0}` failed +} + +fn indirect() { + let x: Z = Z { .. }; +} + +#[cfg(direct)] +fn main() { + let x: Z<1> = Z { .. }; +} + +#[cfg(indirect)] +fn main() { + indirect::<1>(); +} From 12cc2b969d4f45423bff1771af7dcbd2f97707ff Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 4 Mar 2025 13:23:40 +1100 Subject: [PATCH 606/991] Remove unused `PpMode::needs_hir` --- compiler/rustc_session/src/config.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7586c5766b58..671d9741e2f2 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2883,14 +2883,6 @@ impl PpMode { | StableMir => true, } } - pub fn needs_hir(&self) -> bool { - use PpMode::*; - match *self { - Source(_) | AstTree | AstTreeExpanded => false, - - Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG | StableMir => true, - } - } pub fn needs_analysis(&self) -> bool { use PpMode::*; From 0d6dfc80316ebe20570ea1ecccd8981d82d22610 Mon Sep 17 00:00:00 2001 From: Tongjun Gao Date: Tue, 4 Mar 2025 11:50:11 +0800 Subject: [PATCH 607/991] Improve keyword completion for 'let' and 'let mut' --- .../ide-completion/src/completions/expr.rs | 3 +- .../ide-completion/src/completions/keyword.rs | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index 365d2dde7e94..bb7eb6feab94 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -365,7 +365,8 @@ pub(crate) fn complete_expr_path( add_keyword("false", "false"); if in_condition || in_block_expr { - add_keyword("let", "let"); + add_keyword("let mut", "let mut $0"); + add_keyword("let", "let $0"); } if after_if_expr { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs index 6541ee502d83..0a05cf67bd0e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs @@ -330,4 +330,34 @@ fn main() { ", ) } + + #[test] + fn completes_let_with_space() { + check_edit( + "let", + r#" +fn main() { + $0 +} +"#, + r#" +fn main() { + let $0 +} +"#, + ); + check_edit( + "let mut", + r#" +fn main() { + $0 +} +"#, + r#" +fn main() { + let mut $0 +} +"#, + ); + } } From 120d5490aa42fca4a0a7dbeb1322edd5fea2bb7d Mon Sep 17 00:00:00 2001 From: Tongjun Gao Date: Tue, 4 Mar 2025 12:04:54 +0800 Subject: [PATCH 608/991] change 'let mut' keyword completion into 'ietm' snippet --- .../rust-analyzer/crates/ide-completion/src/completions/expr.rs | 2 +- .../crates/ide-completion/src/completions/keyword.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index bb7eb6feab94..b28b6e50e228 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -365,7 +365,7 @@ pub(crate) fn complete_expr_path( add_keyword("false", "false"); if in_condition || in_block_expr { - add_keyword("let mut", "let mut $0"); + add_keyword("letm", "let mut $0"); add_keyword("let", "let $0"); } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs index 0a05cf67bd0e..26c29e0202c0 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs @@ -347,7 +347,7 @@ fn main() { "#, ); check_edit( - "let mut", + "letm", r#" fn main() { $0 From fe6cf341479c91ef90d8c809aea70193ed42036a Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Mon, 3 Mar 2025 21:07:55 -0800 Subject: [PATCH 609/991] Also simplify `Preorder`'s `size_hint` --- compiler/rustc_middle/src/mir/traversal.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 5fb3c648d5a2..9308570d89d1 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -23,19 +23,13 @@ pub struct Preorder<'a, 'tcx> { body: &'a Body<'tcx>, visited: DenseBitSet, worklist: Vec, - root_is_start_block: bool, } impl<'a, 'tcx> Preorder<'a, 'tcx> { pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> { let worklist = vec![root]; - Preorder { - body, - visited: DenseBitSet::new_empty(body.basic_blocks.len()), - worklist, - root_is_start_block: root == START_BLOCK, - } + Preorder { body, visited: DenseBitSet::new_empty(body.basic_blocks.len()), worklist } } } @@ -71,15 +65,11 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { } fn size_hint(&self) -> (usize, Option) { - // All the blocks, minus the number of blocks we've visited. - let upper = self.body.basic_blocks.len() - self.visited.count(); + // The worklist might be only things already visited. + let lower = 0; - let lower = if self.root_is_start_block { - // We will visit all remaining blocks exactly once. - upper - } else { - self.worklist.len() - }; + // This is extremely loose, but it's not worth a popcnt loop to do better. + let upper = self.body.basic_blocks.len(); (lower, Some(upper)) } From a8c0b3bfff36c5b7dbd429891b7fd2093e25a9ad Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 3 Mar 2025 23:36:12 -0600 Subject: [PATCH 610/991] rustdoc search: increase strictness of typechecking --- src/librustdoc/html/static/js/rustdoc.d.ts | 10 ++++++++-- src/librustdoc/html/static/js/search.js | 7 +++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index acea7828e86a..c7b7a46808f1 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -123,7 +123,7 @@ declare namespace rustdoc { * Same as QueryElement, but bindings and typeFilter support strings */ interface ParserQueryElement { - name: string, + name: string|null, id: number|null, fullPath: Array, pathWithoutLast: Array, @@ -131,10 +131,16 @@ declare namespace rustdoc { normalizedPathLast: string, generics: Array, bindings: Map>, - bindingName: {name: string, generics: ParserQueryElement[]}|null, + bindingName: {name: string|null, generics: ParserQueryElement[]}|null, typeFilter: string|null, } + /** + * Same as ParserQueryElement, but all fields are optional. + */ + type ParserQueryElementFields = { + [K in keyof ParserQueryElement]?: ParserQueryElement[T] + } /** * Intermediate parser state. Discarded when parsing is done. */ diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index ccbd6811b071..4073bb389c06 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -638,7 +638,6 @@ function getNextElem(query, parserState, elems, isInGenerics) { getFilteredNextElem(query, parserState, generics, isInGenerics); generics[generics.length - 1].bindingName = makePrimitiveElement("output"); } else { - // @ts-expect-error generics.push(makePrimitiveElement(null, { bindingName: makePrimitiveElement("output"), typeFilter: null, @@ -791,7 +790,7 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) { generics: generics.filter(gen => { // Syntactically, bindings are parsed as generics, // but the query engine treats them differently. - if (gen.bindingName !== null) { + if (gen.bindingName !== null && gen.bindingName.name !== null) { if (gen.name !== null) { gen.bindingName.generics.unshift(gen); } @@ -811,8 +810,8 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) { /** * - * @param {string} name - * @param {Object=} extra + * @param {string|null} name + * @param {rustdoc.ParserQueryElementFields=} extra * @returns {rustdoc.ParserQueryElement} */ function makePrimitiveElement(name, extra) { From 2f9ea8a55ad6397bae7d97f653bbe02915017f03 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 00:27:27 -0600 Subject: [PATCH 611/991] rustdoc search: give buildTypeMapIndex a conditional return type we encode "if the argument is a non-empty string, this will never return null" into the type signature. --- src/librustdoc/html/static/js/search.js | 26 ++++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 4073bb389c06..bd0dab97f018 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1477,73 +1477,61 @@ class DocSearch { * Special type name IDs for searching by array. * @type {number} */ - // @ts-expect-error this.typeNameIdOfArray = this.buildTypeMapIndex("array"); /** * Special type name IDs for searching by slice. * @type {number} */ - // @ts-expect-error this.typeNameIdOfSlice = this.buildTypeMapIndex("slice"); /** * Special type name IDs for searching by both array and slice (`[]` syntax). * @type {number} */ - // @ts-expect-error this.typeNameIdOfArrayOrSlice = this.buildTypeMapIndex("[]"); /** * Special type name IDs for searching by tuple. * @type {number} */ - // @ts-expect-error this.typeNameIdOfTuple = this.buildTypeMapIndex("tuple"); /** * Special type name IDs for searching by unit. * @type {number} */ - // @ts-expect-error this.typeNameIdOfUnit = this.buildTypeMapIndex("unit"); /** * Special type name IDs for searching by both tuple and unit (`()` syntax). * @type {number} */ - // @ts-expect-error this.typeNameIdOfTupleOrUnit = this.buildTypeMapIndex("()"); /** * Special type name IDs for searching `fn`. * @type {number} */ - // @ts-expect-error this.typeNameIdOfFn = this.buildTypeMapIndex("fn"); /** * Special type name IDs for searching `fnmut`. * @type {number} */ - // @ts-expect-error this.typeNameIdOfFnMut = this.buildTypeMapIndex("fnmut"); /** * Special type name IDs for searching `fnonce`. * @type {number} */ - // @ts-expect-error this.typeNameIdOfFnOnce = this.buildTypeMapIndex("fnonce"); /** * Special type name IDs for searching higher order functions (`->` syntax). * @type {number} */ - // @ts-expect-error this.typeNameIdOfHof = this.buildTypeMapIndex("->"); /** * Special type name IDs the output assoc type. * @type {number} */ - // @ts-expect-error this.typeNameIdOfOutput = this.buildTypeMapIndex("output", true); /** * Special type name IDs for searching by reference. * @type {number} */ - // @ts-expect-error this.typeNameIdOfReference = this.buildTypeMapIndex("reference"); /** @@ -1596,11 +1584,17 @@ class DocSearch { * This is effectively string interning, so that function matching can be * done more quickly. Two types with the same name but different item kinds * get the same ID. - * - * @param {string} name + * + * @template T extends string + * @overload + * @param {T} name * @param {boolean=} isAssocType - True if this is an assoc type - * - * @returns {number?} + * @returns {T extends "" ? null : number} + * + * @param {string} name + * @param {boolean=} isAssocType + * @returns {number | null} + * */ buildTypeMapIndex(name, isAssocType) { if (name === "" || name === null) { From 60c5855346576dea6666adb9e00479156242b495 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 4 Mar 2025 00:43:56 -0600 Subject: [PATCH 612/991] ParserQueryElement.typeFilter MAY be a string, OR number. ideally we would encode that it is a string before convertTypeFilterOnElem is called, and a number after, but i'm not sure that's possible without significant refactoring. --- src/librustdoc/html/static/js/rustdoc.d.ts | 2 +- src/librustdoc/html/static/js/search.js | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index c7b7a46808f1..bc4c9a12ac0a 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -132,7 +132,7 @@ declare namespace rustdoc { generics: Array, bindings: Map>, bindingName: {name: string|null, generics: ParserQueryElement[]}|null, - typeFilter: string|null, + typeFilter: number|string|null, } /** diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index bd0dab97f018..45077f7920ba 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2319,15 +2319,13 @@ class DocSearch { * @param {rustdoc.ParserQueryElement} elem */ function convertTypeFilterOnElem(elem) { - if (elem.typeFilter !== null) { + if (typeof elem.typeFilter === 'string') { let typeFilter = elem.typeFilter; if (typeFilter === "const") { typeFilter = "constant"; } - // @ts-expect-error elem.typeFilter = itemTypeFromName(typeFilter); } else { - // @ts-expect-error elem.typeFilter = NO_TYPE_FILTER; } for (const elem2 of elem.generics) { From 4febd273e5a82a9c5aa648e8d843baa184c30929 Mon Sep 17 00:00:00 2001 From: fuyangpengqi <995764973@qq.com> Date: Tue, 4 Mar 2025 16:05:32 +0800 Subject: [PATCH 613/991] Fix some typos Signed-off-by: fuyangpengqi <995764973@qq.com> --- CONTRIBUTING.md | 2 +- library/std/src/sys/pal/uefi/process.rs | 2 +- .../rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a5ddff595f5d..e155e253784a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ For submodules, changes need to be made against the repository corresponding the submodule, and not the main `rust-lang/rust` repository. For subtrees, prefer sending a PR against the subtree's repository if it does -not need to be made against the main `rust-lang/rust` repostory (e.g. a +not need to be made against the main `rust-lang/rust` repository (e.g. a rustc-dev-guide change that does not accompany a compiler change). ## About the [rustc-dev-guide] diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs index a47c8dbcaaaf..d4c09dc2ca0e 100644 --- a/library/std/src/sys/pal/uefi/process.rs +++ b/library/std/src/sys/pal/uefi/process.rs @@ -757,7 +757,7 @@ mod uefi_command_internal { } /// Create a map of environment variable changes. Allows efficient setting and rolling back of -/// enviroment variable changes. +/// environment variable changes. /// /// Entry: (Old Value, New Value) fn env_changes(env: &CommandEnv) -> Option, Option)>> { diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md index b57083980d27..dda2a50c33d7 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md @@ -65,7 +65,7 @@ section below. A RISC-V toolchain can be obtained for Windows/Mac/Linux from the [`riscv-gnu-toolchain`](https://github.com/riscv-collab/riscv-gnu-toolchain) -repostory. Binaries are available via +repository. Binaries are available via [embecosm](https://www.embecosm.com/resources/tool-chain-downloads/#riscv-linux), and may also be available from your OS's package manager. From 69c46515edc86dea961e1565ee2b34311ddaeb35 Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:01:00 +0100 Subject: [PATCH 614/991] ci: use ubuntu 24 on arm large runner --- src/ci/github-actions/jobs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 1504e5c60ce7..69a39b6eec2f 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -54,7 +54,7 @@ runners: <<: *base-job - &job-aarch64-linux-8c - os: ubuntu-22.04-arm64-8core-32gb + os: ubuntu-24.04-arm64-8core-32gb <<: *base-job envs: env-x86_64-apple-tests: &env-x86_64-apple-tests From 2816f0302265e999f3c09099830d029315acb4a8 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 4 Mar 2025 09:56:25 +0000 Subject: [PATCH 615/991] Add `avr-none` to SUMMARY.md and platform-support.md This was missed this in the implementation PR, so update the links here. --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 6c7cdec34802..d9c2f6b28a79 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -50,6 +50,7 @@ - [\*-linux-ohos](platform-support/openharmony.md) - [\*-hurd-gnu](platform-support/hurd.md) - [aarch64-unknown-teeos](platform-support/aarch64-unknown-teeos.md) + - [avr-none](platform-support/avr-none.md) - [\*-espidf](platform-support/esp-idf.md) - [\*-unknown-fuchsia](platform-support/fuchsia.md) - [\*-unknown-trusty](platform-support/trusty.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c4e5c1aac2f5..dd085f916b91 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -301,7 +301,7 @@ target | std | host | notes [`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat [`armv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX [`armv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat -`avr-none` | * | | AVR; requires `-Zbuild-std=core` and `-Ctarget-cpu=...` +[`avr-none`](platform-support/avr-none.md) | * | | AVR; requires `-Zbuild-std=core` and `-Ctarget-cpu=...` `bpfeb-unknown-none` | * | | BPF (big endian) `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian) From 00523bf7c367699bd8fb48172b4169085256fead Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Thu, 27 Feb 2025 08:46:27 +0000 Subject: [PATCH 616/991] =?UTF-8?q?`librustdoc`:=202024=20edition!=20?= =?UTF-8?q?=F0=9F=8E=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/librustdoc/Cargo.toml | 2 +- src/librustdoc/clean/cfg.rs | 4 ++-- src/librustdoc/clean/mod.rs | 4 ++-- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/clean/utils.rs | 11 ++++++----- src/librustdoc/html/format.rs | 2 +- src/librustdoc/html/render/mod.rs | 6 +++--- src/librustdoc/html/sources.rs | 2 +- src/librustdoc/lib.rs | 2 +- src/tools/rustdoc/Cargo.toml | 2 +- 10 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 91cc40887882..909b81a723b4 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustdoc" version = "0.0.0" -edition = "2021" +edition = "2024" build = "build.rs" [lib] diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index bec7fbe8f52b..ab169f3c2a4d 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -48,12 +48,12 @@ impl Cfg { exclude: &FxHashSet, ) -> Result, InvalidCfgError> { match nested_cfg { - MetaItemInner::MetaItem(ref cfg) => Cfg::parse_without(cfg, exclude), + MetaItemInner::MetaItem(cfg) => Cfg::parse_without(cfg, exclude), MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => match *b { true => Ok(Some(Cfg::True)), false => Ok(Some(Cfg::False)), }, - MetaItemInner::Lit(ref lit) => { + MetaItemInner::Lit(lit) => { Err(InvalidCfgError { msg: "unexpected literal", span: lit.span }) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ceffe5e5ce04..bb12e4a706e7 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -741,7 +741,7 @@ pub(crate) fn clean_generics<'tcx>( for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) { let mut p = clean_generic_param(cx, Some(gens), p); match &mut p.kind { - GenericParamDefKind::Lifetime { ref mut outlives } => { + GenericParamDefKind::Lifetime { outlives } => { if let Some(region_pred) = region_predicates.get_mut(&Lifetime(p.name)) { // We merge bounds in the `where` clause. for outlive in outlives.drain(..) { @@ -2688,7 +2688,7 @@ fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool { /// Before calling this function, make sure `normal` is a `#[doc]` attribute. fn filter_doc_attr(args: &mut hir::AttrArgs, is_inline: bool) { match args { - hir::AttrArgs::Delimited(ref mut args) => { + hir::AttrArgs::Delimited(args) => { let tokens = filter_tokens_from_list(&args.tokens, |token| { !matches!( token, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 178b6a60b41f..bd5fd612b38f 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -502,7 +502,7 @@ impl Item { let Some(links) = cx.cache().intra_doc_links.get(&self.item_id) else { return vec![] }; links .iter() - .filter_map(|ItemLink { link: s, link_text, page_id: id, ref fragment }| { + .filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| { debug!(?id); if let Ok((mut href, ..)) = href(*id, cx) { debug!(?href); diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 34656b26ce28..b71ff0c56f8a 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -60,7 +60,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { let primitives = local_crate.primitives(cx.tcx); let keywords = local_crate.keywords(cx.tcx); { - let ItemKind::ModuleItem(ref mut m) = &mut module.inner.kind else { unreachable!() }; + let ItemKind::ModuleItem(m) = &mut module.inner.kind else { unreachable!() }; m.items.extend(primitives.iter().map(|&(def_id, prim)| { Item::from_def_id_and_parts( def_id, @@ -302,7 +302,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { use rustc_hir::*; debug!("trying to get a name from pattern: {p:?}"); - Symbol::intern(&match p.kind { + Symbol::intern(&match &p.kind { // FIXME(never_patterns): does this make sense? PatKind::Wild | PatKind::Err(_) @@ -313,8 +313,9 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { } PatKind::Binding(_, _, ident, _) => return ident.name, PatKind::Box(p) | PatKind::Ref(p, _) | PatKind::Guard(p, _) => return name_from_pat(p), - PatKind::TupleStruct(ref p, ..) - | PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref p), .. }) => qpath_to_string(p), + PatKind::TupleStruct(p, ..) | PatKind::Expr(PatExpr { kind: PatExprKind::Path(p), .. }) => { + qpath_to_string(p) + } PatKind::Or(pats) => { fmt::from_fn(|f| pats.iter().map(|p| name_from_pat(p)).joined(" | ", f)).to_string() } @@ -493,7 +494,7 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type { pub(crate) fn synthesize_auto_trait_and_blanket_impls( cx: &mut DocContext<'_>, item_def_id: DefId, -) -> impl Iterator { +) -> impl Iterator + use<> { let auto_impls = cx .sess() .prof diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 522ef1af376c..925ebc244dc5 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -80,7 +80,7 @@ impl clean::GenericParamDef { print_generic_bounds(bounds, cx).fmt(f)?; } - if let Some(ref ty) = default { + if let Some(ty) = default { f.write_str(" = ")?; ty.print(cx).fmt(f)?; } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index bd4af359404a..94bde6c37d0a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -812,7 +812,7 @@ fn assoc_href_attr<'a, 'tcx>( } let href = match link { - AssocItemLink::Anchor(Some(ref id)) => Href::AnchorId(id), + AssocItemLink::Anchor(Some(id)) => Href::AnchorId(id), AssocItemLink::Anchor(None) => Href::Anchor(item_type), AssocItemLink::GotoSource(did, provided_methods) => { // We're creating a link from the implementation of an associated item to its @@ -1144,7 +1144,7 @@ fn render_assoc_item<'a, 'tcx>( cx, ) .fmt(f), - clean::RequiredAssocTypeItem(ref generics, ref bounds) => assoc_type( + clean::RequiredAssocTypeItem(generics, bounds) => assoc_type( item, generics, bounds, @@ -1154,7 +1154,7 @@ fn render_assoc_item<'a, 'tcx>( cx, ) .fmt(f), - clean::AssocTypeItem(ref ty, ref bounds) => assoc_type( + clean::AssocTypeItem(ty, bounds) => assoc_type( item, &ty.generics, bounds, diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 78c86a27632b..cbbd4b01d83e 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -333,7 +333,7 @@ pub(crate) fn print_src( source_context: &SourceContext<'_>, ) { let mut lines = s.lines().count(); - let line_info = if let SourceContext::Embedded(ref info) = source_context { + let line_info = if let SourceContext::Embedded(info) = source_context { highlight::LineInfo::new_scraped(lines as u32, info.offset as u32) } else { highlight::LineInfo::new(lines as u32) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c1e6d324d5a1..4fe5e13c3afe 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -147,7 +147,7 @@ pub fn main() { #[cfg(target_os = "macos")] { - extern "C" { + unsafe extern "C" { fn _rjem_je_zone_register(); } diff --git a/src/tools/rustdoc/Cargo.toml b/src/tools/rustdoc/Cargo.toml index c4101f72cc2d..d1682758d362 100644 --- a/src/tools/rustdoc/Cargo.toml +++ b/src/tools/rustdoc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustdoc-tool" version = "0.0.0" -edition = "2021" +edition = "2024" # Cargo adds a number of paths to the dylib search path on windows, which results in # the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" From 6e86aa17ec3460497fb6617d13e848257f46ffe1 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Thu, 27 Feb 2025 11:18:25 +0000 Subject: [PATCH 617/991] Adapt `librustdoc` to 2024 edition lifetieme capture rules Get rid of the `Captures` hack --- .../rustc_data_structures/src/captures.rs | 8 - compiler/rustc_data_structures/src/lib.rs | 1 - src/librustdoc/clean/types.rs | 6 +- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/html/format.rs | 144 +++----- src/librustdoc/html/render/mod.rs | 203 ++++++----- src/librustdoc/html/render/print_item.rs | 327 +++++++----------- src/librustdoc/html/render/type_layout.rs | 6 +- .../passes/collect_intra_doc_links.rs | 2 +- 9 files changed, 270 insertions(+), 429 deletions(-) delete mode 100644 compiler/rustc_data_structures/src/captures.rs diff --git a/compiler/rustc_data_structures/src/captures.rs b/compiler/rustc_data_structures/src/captures.rs deleted file mode 100644 index 677ccb31454e..000000000000 --- a/compiler/rustc_data_structures/src/captures.rs +++ /dev/null @@ -1,8 +0,0 @@ -/// "Signaling" trait used in impl trait to tag lifetimes that you may -/// need to capture but don't really need for other reasons. -/// Basically a workaround; see [this comment] for details. -/// -/// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 -pub trait Captures<'a> {} - -impl<'a, T: ?Sized> Captures<'a> for T {} diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 66d3834d8578..a3b62b469196 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -48,7 +48,6 @@ pub use rustc_index::static_assert_size; pub mod aligned; pub mod base_n; pub mod binary_search_util; -pub mod captures; pub mod fingerprint; pub mod flat_map_in_place; pub mod flock; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index bd5fd612b38f..5906a720e0fd 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1150,7 +1150,7 @@ pub(crate) struct Attributes { } impl Attributes { - pub(crate) fn lists(&self, name: Symbol) -> impl Iterator + '_ { + pub(crate) fn lists(&self, name: Symbol) -> impl Iterator { hir_attr_lists(&self.other_attrs[..], name) } @@ -1864,7 +1864,7 @@ impl PrimitiveType { .copied() } - pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator + '_ { + pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator { Self::simplified_types() .values() .flatten() @@ -2259,7 +2259,7 @@ impl GenericArgs { GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(), } } - pub(crate) fn constraints<'a>(&'a self) -> Box + 'a> { + pub(crate) fn constraints(&self) -> Box + '_> { match self { GenericArgs::AngleBracketed { constraints, .. } => { Box::new(constraints.iter().cloned()) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index b71ff0c56f8a..a284de5229a2 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -330,7 +330,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { return Symbol::intern("()"); } PatKind::Slice(begin, mid, end) => { - fn print_pat<'a>(pat: &'a Pat<'a>, wild: bool) -> impl Display + 'a { + fn print_pat(pat: &Pat<'_>, wild: bool) -> impl Display { fmt::from_fn(move |f| { if wild { f.write_str("..")?; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 925ebc244dc5..ea740508c583 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -15,7 +15,6 @@ use std::iter::{self, once}; use itertools::Either; use rustc_abi::ExternAbi; use rustc_attr_parsing::{ConstStability, StabilityLevel, StableSince}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -41,10 +40,10 @@ pub(crate) fn write_str(s: &mut String, f: fmt::Arguments<'_>) { s.write_fmt(f).unwrap(); } -pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( - bounds: &'a [clean::GenericBound], - cx: &'a Context<'tcx>, -) -> impl Display + 'a + Captures<'tcx> { +pub(crate) fn print_generic_bounds( + bounds: &[clean::GenericBound], + cx: &Context<'_>, +) -> impl Display { fmt::from_fn(move |f| { let mut bounds_dup = FxHashSet::default(); @@ -57,10 +56,7 @@ pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( } impl clean::GenericParamDef { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match &self.kind { clean::GenericParamDefKind::Lifetime { outlives } => { write!(f, "{}", self.name)?; @@ -107,10 +103,7 @@ impl clean::GenericParamDef { } impl clean::Generics { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable(); if real_params.peek().is_none() { @@ -134,10 +127,7 @@ pub(crate) enum Ending { NoNewline, } -fn print_where_predicate<'a, 'tcx: 'a>( - predicate: &'a clean::WherePredicate, - cx: &'a Context<'tcx>, -) -> impl Display + 'a + Captures<'tcx> { +fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { match predicate { clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { @@ -173,12 +163,12 @@ fn print_where_predicate<'a, 'tcx: 'a>( /// * The Generics from which to emit a where-clause. /// * The number of spaces to indent each line with. /// * Whether the where-clause needs to add a comma and newline after the last bound. -pub(crate) fn print_where_clause<'a, 'tcx: 'a>( - gens: &'a clean::Generics, - cx: &'a Context<'tcx>, +pub(crate) fn print_where_clause( + gens: &clean::Generics, + cx: &Context<'_>, indent: usize, ending: Ending, -) -> Option> { +) -> Option { if gens.where_predicates.is_empty() { return None; } @@ -250,13 +240,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( } impl clean::Lifetime { - pub(crate) fn print(&self) -> impl Display + '_ { + pub(crate) fn print(&self) -> impl Display { self.0.as_str() } } impl clean::ConstantKind { - pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display + '_ { + pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display { let expr = self.expr(tcx); fmt::from_fn(move |f| { if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) } @@ -265,7 +255,7 @@ impl clean::ConstantKind { } impl clean::PolyTrait { - fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> { + fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?; self.trait_.print(cx).fmt(f) @@ -274,10 +264,7 @@ impl clean::PolyTrait { } impl clean::GenericBound { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self { clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()), clean::GenericBound::TraitBound(ty, modifiers) => { @@ -304,7 +291,7 @@ impl clean::GenericBound { } impl clean::GenericArgs { - fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> { + fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { match self { clean::GenericArgs::AngleBracketed { args, constraints } => { @@ -809,11 +796,11 @@ fn primitive_link_fragment( Ok(()) } -fn tybounds<'a, 'tcx: 'a>( - bounds: &'a [clean::PolyTrait], - lt: &'a Option, - cx: &'a Context<'tcx>, -) -> impl Display + 'a + Captures<'tcx> { +fn tybounds( + bounds: &[clean::PolyTrait], + lt: &Option, + cx: &Context<'_>, +) -> impl Display { fmt::from_fn(move |f| { bounds.iter().map(|bound| bound.print(cx)).joined(" + ", f)?; if let Some(lt) = lt { @@ -825,11 +812,11 @@ fn tybounds<'a, 'tcx: 'a>( }) } -fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>( - params: &'a [clean::GenericParamDef], - cx: &'a Context<'tcx>, +fn print_higher_ranked_params_with_space( + params: &[clean::GenericParamDef], + cx: &Context<'_>, keyword: &'static str, -) -> impl Display + 'a + Captures<'tcx> { +) -> impl Display { fmt::from_fn(move |f| { if !params.is_empty() { f.write_str(keyword)?; @@ -841,11 +828,7 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>( }) } -pub(crate) fn anchor<'a: 'cx, 'cx>( - did: DefId, - text: Symbol, - cx: &'cx Context<'a>, -) -> impl Display + Captures<'a> + 'cx { +pub(crate) fn anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { let parts = href(did, cx); if let Ok((url, short_ty, fqp)) = parts { @@ -1121,29 +1104,19 @@ fn fmt_type( } impl clean::Type { - pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'b + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| fmt_type(self, f, false, cx)) } } impl clean::Path { - pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'b + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx)) } } impl clean::Impl { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - use_absolute: bool, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, use_absolute: bool, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { f.write_str("impl")?; self.generics.print(cx).fmt(f)?; @@ -1182,12 +1155,12 @@ impl clean::Impl { print_where_clause(&self.generics, cx, 0, Ending::Newline).maybe_display().fmt(f) }) } - fn print_type<'a, 'tcx: 'a>( + fn print_type( &self, type_: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool, - cx: &'a Context<'tcx>, + cx: &Context<'_>, ) -> Result<(), fmt::Error> { if let clean::Type::Tuple(types) = type_ && let [clean::Type::Generic(name)] = &types[..] @@ -1258,10 +1231,7 @@ impl clean::Impl { } impl clean::Arguments { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { self.values .iter() @@ -1301,10 +1271,7 @@ impl Display for Indent { } impl clean::FnDecl { - pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'b + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { let ellipsis = if self.c_variadic { ", ..." } else { "" }; if f.alternate() { @@ -1333,12 +1300,12 @@ impl clean::FnDecl { /// are preserved. /// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is /// necessary. - pub(crate) fn full_print<'a, 'tcx: 'a>( - &'a self, + pub(crate) fn full_print( + &self, header_len: usize, indent: usize, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + cx: &Context<'_>, + ) -> impl Display { fmt::from_fn(move |f| { // First, generate the text form of the declaration, with no line wrapping, and count the bytes. let mut counter = WriteCounter(0); @@ -1420,10 +1387,7 @@ impl clean::FnDecl { self.print_output(cx).fmt(f) } - fn print_output<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + fn print_output(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match &self.output { clean::Tuple(tys) if tys.is_empty() => Ok(()), ty if f.alternate() => { @@ -1434,10 +1398,7 @@ impl clean::FnDecl { } } -pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( - item: &clean::Item, - cx: &'a Context<'tcx>, -) -> impl Display + 'a + Captures<'tcx> { +pub(crate) fn visibility_print_with_space(item: &clean::Item, cx: &Context<'_>) -> impl Display { use std::fmt::Write as _; let vis: Cow<'static, str> = match item.visibility(cx.tcx()) { None => "".into(), @@ -1546,10 +1507,7 @@ pub(crate) fn print_constness_with_space( } impl clean::Import { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self.kind { clean::ImportKind::Simple(name) => { if name == self.source.path.last() { @@ -1570,10 +1528,7 @@ impl clean::Import { } impl clean::ImportSource { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self.did { Some(did) => resolved_path(f, did, &self.path, true, false, cx), _ => { @@ -1593,10 +1548,7 @@ impl clean::ImportSource { } impl clean::AssocItemConstraint { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { f.write_str(self.assoc.name.as_str())?; self.assoc.args.print(cx).fmt(f)?; @@ -1627,15 +1579,12 @@ pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display { }) } -pub(crate) fn print_default_space<'a>(v: bool) -> &'a str { +pub(crate) fn print_default_space(v: bool) -> &'static str { if v { "default " } else { "" } } impl clean::GenericArg { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self { clean::GenericArg::Lifetime(lt) => lt.print().fmt(f), clean::GenericArg::Type(ty) => ty.print(cx).fmt(f), @@ -1646,10 +1595,7 @@ impl clean::GenericArg { } impl clean::Term { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self { clean::Term::Type(ty) => ty.print(cx).fmt(f), clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 94bde6c37d0a..b2ad2fa773ae 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -47,7 +47,6 @@ use rinja::Template; use rustc_attr_parsing::{ ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince, }; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::Mutability; use rustc_hir::def_id::{DefId, DefIdSet}; @@ -82,7 +81,7 @@ use crate::html::{highlight, sources}; use crate::scrape_examples::{CallData, CallLocation}; use crate::{DOC_RUST_LANG_ORG_VERSION, try_none}; -pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { +pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display { fmt::from_fn(move |f| { if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) } }) @@ -310,7 +309,7 @@ impl ItemEntry { } impl ItemEntry { - pub(crate) fn print(&self) -> impl fmt::Display + '_ { + pub(crate) fn print(&self) -> impl fmt::Display { fmt::from_fn(move |f| write!(f, "{}", self.url, Escape(&self.name))) } } @@ -505,12 +504,12 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String { ) } -fn document<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - item: &'a clean::Item, - parent: Option<&'a clean::Item>, +fn document( + cx: &Context<'_>, + item: &clean::Item, + parent: Option<&clean::Item>, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { if let Some(ref name) = item.name { info!("Documenting {name}"); } @@ -526,12 +525,12 @@ fn document<'a, 'cx: 'a>( } /// Render md_text as markdown. -fn render_markdown<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - md_text: &'a str, +fn render_markdown( + cx: &Context<'_>, + md_text: &str, links: Vec, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { fmt::from_fn(move |f| { write!( f, @@ -552,13 +551,13 @@ fn render_markdown<'a, 'cx: 'a>( /// Writes a documentation block containing only the first paragraph of the documentation. If the /// docs are longer, a "Read more" link is appended to the end. -fn document_short<'a, 'cx: 'a>( - item: &'a clean::Item, - cx: &'a Context<'cx>, - link: AssocItemLink<'a>, - parent: &'a clean::Item, +fn document_short( + item: &clean::Item, + cx: &Context<'_>, + link: AssocItemLink<'_>, + parent: &clean::Item, show_def_docs: bool, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { fmt::from_fn(move |f| { document_item_info(cx, item, Some(parent)).render_into(f).unwrap(); if !show_def_docs { @@ -595,28 +594,28 @@ fn document_short<'a, 'cx: 'a>( }) } -fn document_full_collapsible<'a, 'cx: 'a>( - item: &'a clean::Item, - cx: &'a Context<'cx>, +fn document_full_collapsible( + item: &clean::Item, + cx: &Context<'_>, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { document_full_inner(item, cx, true, heading_offset) } -fn document_full<'a, 'cx: 'a>( - item: &'a clean::Item, - cx: &'a Context<'cx>, +fn document_full( + item: &clean::Item, + cx: &Context<'_>, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { document_full_inner(item, cx, false, heading_offset) } -fn document_full_inner<'a, 'cx: 'a>( - item: &'a clean::Item, - cx: &'a Context<'cx>, +fn document_full_inner( + item: &clean::Item, + cx: &Context<'_>, is_collapsible: bool, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { fmt::from_fn(move |f| { if let Some(s) = item.opt_doc_value() { debug!("Doc block: =====\n{s}\n====="); @@ -797,11 +796,11 @@ pub(crate) fn render_impls( } /// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item. -fn assoc_href_attr<'a, 'tcx>( +fn assoc_href_attr( it: &clean::Item, - link: AssocItemLink<'a>, - cx: &Context<'tcx>, -) -> Option> { + link: AssocItemLink<'_>, + cx: &Context<'_>, +) -> Option { let name = it.name.unwrap(); let item_type = it.type_(); @@ -877,15 +876,15 @@ enum AssocConstValue<'a> { None, } -fn assoc_const<'a, 'tcx>( - it: &'a clean::Item, - generics: &'a clean::Generics, - ty: &'a clean::Type, - value: AssocConstValue<'a>, - link: AssocItemLink<'a>, +fn assoc_const( + it: &clean::Item, + generics: &clean::Generics, + ty: &clean::Type, + value: AssocConstValue<'_>, + link: AssocItemLink<'_>, indent: usize, - cx: &'a Context<'tcx>, -) -> impl fmt::Display + 'a + Captures<'tcx> { + cx: &Context<'_>, +) -> impl fmt::Display { let tcx = cx.tcx(); fmt::from_fn(move |w| { write!( @@ -917,15 +916,15 @@ fn assoc_const<'a, 'tcx>( }) } -fn assoc_type<'a, 'tcx>( - it: &'a clean::Item, - generics: &'a clean::Generics, - bounds: &'a [clean::GenericBound], - default: Option<&'a clean::Type>, - link: AssocItemLink<'a>, +fn assoc_type( + it: &clean::Item, + generics: &clean::Generics, + bounds: &[clean::GenericBound], + default: Option<&clean::Type>, + link: AssocItemLink<'_>, indent: usize, - cx: &'a Context<'tcx>, -) -> impl fmt::Display + 'a + Captures<'tcx> { + cx: &Context<'_>, +) -> impl fmt::Display { fmt::from_fn(move |w| { write!( w, @@ -947,15 +946,15 @@ fn assoc_type<'a, 'tcx>( }) } -fn assoc_method<'a, 'tcx>( - meth: &'a clean::Item, - g: &'a clean::Generics, - d: &'a clean::FnDecl, - link: AssocItemLink<'a>, +fn assoc_method( + meth: &clean::Item, + g: &clean::Generics, + d: &clean::FnDecl, + link: AssocItemLink<'_>, parent: ItemType, - cx: &'a Context<'tcx>, + cx: &Context<'_>, render_mode: RenderMode, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { let tcx = cx.tcx(); let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item"); let name = meth.name.as_ref().unwrap(); @@ -1031,7 +1030,7 @@ fn render_stability_since_raw_with_extra( stable_version: Option, const_stability: Option, extra_class: &str, -) -> Option { +) -> Option { let mut title = String::new(); let mut stability = String::new(); @@ -1102,13 +1101,13 @@ fn render_stability_since_raw( render_stability_since_raw_with_extra(ver, const_stability, "") } -fn render_assoc_item<'a, 'tcx>( - item: &'a clean::Item, - link: AssocItemLink<'a>, +fn render_assoc_item( + item: &clean::Item, + link: AssocItemLink<'_>, parent: ItemType, - cx: &'a Context<'tcx>, + cx: &Context<'_>, render_mode: RenderMode, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { fmt::from_fn(move |f| match &item.kind { clean::StrippedItem(..) => Ok(()), clean::RequiredMethodItem(m) | clean::MethodItem(m, _) => { @@ -1170,11 +1169,7 @@ fn render_assoc_item<'a, 'tcx>( // When an attribute is rendered inside a `

` tag, it is formatted using
@@ -1230,29 +1206,29 @@ impl<'a> AssocItemLink<'a> {
     }
 }
 
-pub fn write_section_heading(
-    w: &mut impl fmt::Write,
-    title: &str,
-    id: &str,
-    extra_class: Option<&str>,
-    extra: impl fmt::Display,
-) {
-    let (extra_class, whitespace) = match extra_class {
-        Some(extra) => (extra, " "),
-        None => ("", ""),
-    };
-    write!(
-        w,
-        "

\ +pub fn write_section_heading<'a>( + title: &'a str, + id: &'a str, + extra_class: Option<&'a str>, + extra: impl fmt::Display + 'a, +) -> impl fmt::Display + 'a { + fmt::from_fn(move |w| { + let (extra_class, whitespace) = match extra_class { + Some(extra) => (extra, " "), + None => ("", ""), + }; + write!( + w, + "

\ {title}\ §\

{extra}", - ) - .unwrap(); + ) + }) } -fn write_impl_section_heading(w: &mut impl fmt::Write, title: &str, id: &str) { - write_section_heading(w, title, id, None, "") +fn write_impl_section_heading<'a>(title: &'a str, id: &'a str) -> impl fmt::Display + 'a { + write_section_heading(title, id, None, "") } pub(crate) fn render_all_impls( @@ -1269,24 +1245,32 @@ pub(crate) fn render_all_impls( buf }; if !impls.is_empty() { - write_impl_section_heading(&mut w, "Trait Implementations", "trait-implementations"); - write!(w, "
{impls}
").unwrap(); + write!( + w, + "{}
{impls}
", + write_impl_section_heading("Trait Implementations", "trait-implementations") + ) + .unwrap(); } if !synthetic.is_empty() { - write_impl_section_heading( - &mut w, - "Auto Trait Implementations", - "synthetic-implementations", - ); - w.write_str("
").unwrap(); + write!( + w, + "{}
", + write_impl_section_heading("Auto Trait Implementations", "synthetic-implementations",) + ) + .unwrap(); render_impls(cx, &mut w, synthetic, containing_item, false); w.write_str("
").unwrap(); } if !blanket_impl.is_empty() { - write_impl_section_heading(&mut w, "Blanket Implementations", "blanket-implementations"); - w.write_str("
").unwrap(); + write!( + w, + "{}
", + write_impl_section_heading("Blanket Implementations", "blanket-implementations") + ) + .unwrap(); render_impls(cx, &mut w, blanket_impl, containing_item, false); w.write_str("
").unwrap(); } @@ -1323,25 +1307,34 @@ fn render_assoc_items_inner( let mut tmp_buf = String::new(); let (render_mode, id, class_html) = match what { AssocItemRender::All => { - write_impl_section_heading(&mut tmp_buf, "Implementations", "implementations"); + write_str( + &mut tmp_buf, + format_args!( + "{}", + write_impl_section_heading("Implementations", "implementations") + ), + ); (RenderMode::Normal, "implementations-list".to_owned(), "") } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { let id = cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx)))); let derived_id = cx.derive_id(&id); - tmp_buf.push_str("
"); close_tags.push("
"); - write_impl_section_heading( + write_str( &mut tmp_buf, - &format!( - "Methods from {trait_}<Target = {type_}>", - trait_ = trait_.print(cx), - type_ = type_.print(cx), + format_args!( + "
{}", + write_impl_section_heading( + &format!( + "Methods from {trait_}<Target = {type_}>", + trait_ = trait_.print(cx), + type_ = type_.print(cx), + ), + &id, + ) ), - &id, ); - tmp_buf.push_str(""); if let Some(def_id) = type_.def_id(cx.cache()) { cx.deref_id_map.borrow_mut().insert(def_id, id); } @@ -1350,21 +1343,26 @@ fn render_assoc_items_inner( }; let mut impls_buf = String::new(); for i in &non_trait { - render_impl( + write_str( &mut impls_buf, - cx, - i, - containing_item, - AssocItemLink::Anchor(None), - render_mode, - None, - &[], - ImplRenderingParameters { - show_def_docs: true, - show_default_items: true, - show_non_assoc_items: true, - toggle_open_by_default: true, - }, + format_args!( + "{}", + render_impl( + cx, + i, + containing_item, + AssocItemLink::Anchor(None), + render_mode, + None, + &[], + ImplRenderingParameters { + show_def_docs: true, + show_default_items: true, + show_non_assoc_items: true, + toggle_open_by_default: true, + }, + ) + ), ); } if !impls_buf.is_empty() { @@ -1564,20 +1562,23 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { ); for it in &impl_.items { if let clean::AssocTypeItem(ref tydef, ref _bounds) = it.kind { - out.push_str("
"); let empty_set = FxIndexSet::default(); let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set); - assoc_type( + write_str( &mut out, - it, - &tydef.generics, - &[], // intentionally leaving out bounds - Some(&tydef.type_), - src_link, - 0, - cx, + format_args!( + "
{};
", + assoc_type( + it, + &tydef.generics, + &[], // intentionally leaving out bounds + Some(&tydef.type_), + src_link, + 0, + cx, + ) + ), ); - out.push_str(";
"); } } } @@ -1622,592 +1623,627 @@ struct ImplRenderingParameters { toggle_open_by_default: bool, } -fn render_impl( - w: &mut String, - cx: &Context<'_>, - i: &Impl, - parent: &clean::Item, - link: AssocItemLink<'_>, +fn render_impl<'a, 'tcx>( + cx: &'a Context<'tcx>, + i: &'a Impl, + parent: &'a clean::Item, + link: AssocItemLink<'a>, render_mode: RenderMode, use_absolute: Option, - aliases: &[String], + aliases: &'a [String], rendering_params: ImplRenderingParameters, -) { - let cache = &cx.shared.cache; - let traits = &cache.traits; - let trait_ = i.trait_did().map(|did| &traits[&did]); - let mut close_tags = >::with_capacity(2); +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + let cache = &cx.shared.cache; + let traits = &cache.traits; + let trait_ = i.trait_did().map(|did| &traits[&did]); + let mut close_tags = >::with_capacity(2); - // For trait implementations, the `interesting` output contains all methods that have doc - // comments, and the `boring` output contains all methods that do not. The distinction is - // used to allow hiding the boring methods. - // `containing_item` is used for rendering stability info. If the parent is a trait impl, - // `containing_item` will the grandparent, since trait impls can't have stability attached. - fn doc_impl_item( - boring: &mut String, - interesting: &mut String, - cx: &Context<'_>, - item: &clean::Item, - parent: &clean::Item, - link: AssocItemLink<'_>, - render_mode: RenderMode, - is_default_item: bool, - trait_: Option<&clean::Trait>, - rendering_params: ImplRenderingParameters, - ) { - let item_type = item.type_(); - let name = item.name.as_ref().unwrap(); + // For trait implementations, the `interesting` output contains all methods that have doc + // comments, and the `boring` output contains all methods that do not. The distinction is + // used to allow hiding the boring methods. + // `containing_item` is used for rendering stability info. If the parent is a trait impl, + // `containing_item` will the grandparent, since trait impls can't have stability attached. + fn doc_impl_item( + boring: &mut String, + interesting: &mut String, + cx: &Context<'_>, + item: &clean::Item, + parent: &clean::Item, + link: AssocItemLink<'_>, + render_mode: RenderMode, + is_default_item: bool, + trait_: Option<&clean::Trait>, + rendering_params: ImplRenderingParameters, + ) { + let item_type = item.type_(); + let name = item.name.as_ref().unwrap(); - let render_method_item = rendering_params.show_non_assoc_items - && match render_mode { - RenderMode::Normal => true, - RenderMode::ForDeref { mut_: deref_mut_ } => { - should_render_item(item, deref_mut_, cx.tcx()) - } - }; + let render_method_item = rendering_params.show_non_assoc_items + && match render_mode { + RenderMode::Normal => true, + RenderMode::ForDeref { mut_: deref_mut_ } => { + should_render_item(item, deref_mut_, cx.tcx()) + } + }; - let in_trait_class = if trait_.is_some() { " trait-impl" } else { "" }; + let in_trait_class = if trait_.is_some() { " trait-impl" } else { "" }; - let mut doc_buffer = String::new(); - let mut info_buffer = String::new(); - let mut short_documented = true; + let mut doc_buffer = String::new(); + let mut info_buffer = String::new(); + let mut short_documented = true; - if render_method_item { - if !is_default_item { - if let Some(t) = trait_ { - // The trait item may have been stripped so we might not - // find any documentation or stability for it. - if let Some(it) = t.items.iter().find(|i| i.name == item.name) { - // We need the stability of the item from the trait - // because impls can't have a stability. - if !item.doc_value().is_empty() { - document_item_info(cx, it, Some(parent)) - .render_into(&mut info_buffer) - .unwrap(); + if render_method_item { + if !is_default_item { + if let Some(t) = trait_ { + // The trait item may have been stripped so we might not + // find any documentation or stability for it. + if let Some(it) = t.items.iter().find(|i| i.name == item.name) { + // We need the stability of the item from the trait + // because impls can't have a stability. + if !item.doc_value().is_empty() { + document_item_info(cx, it, Some(parent)) + .render_into(&mut info_buffer) + .unwrap(); + write_str( + &mut doc_buffer, + format_args!("{}", document_full(item, cx, HeadingOffset::H5)), + ); + short_documented = false; + } else { + // In case the item isn't documented, + // provide short documentation from the trait. + write_str( + &mut doc_buffer, + format_args!( + "{}", + document_short( + it, + cx, + link, + parent, + rendering_params.show_def_docs, + ) + ), + ); + } + } + } else { + document_item_info(cx, item, Some(parent)) + .render_into(&mut info_buffer) + .unwrap(); + if rendering_params.show_def_docs { write_str( &mut doc_buffer, format_args!("{}", document_full(item, cx, HeadingOffset::H5)), ); short_documented = false; - } else { - // In case the item isn't documented, - // provide short documentation from the trait. - write_str( - &mut doc_buffer, - format_args!( - "{}", - document_short( - it, - cx, - link, - parent, - rendering_params.show_def_docs, - ) - ), - ); } } } else { - document_item_info(cx, item, Some(parent)) - .render_into(&mut info_buffer) - .unwrap(); - if rendering_params.show_def_docs { - write_str( - &mut doc_buffer, - format_args!("{}", document_full(item, cx, HeadingOffset::H5)), - ); - short_documented = false; - } + write_str( + &mut doc_buffer, + format_args!( + "{}", + document_short(item, cx, link, parent, rendering_params.show_def_docs) + ), + ); } - } else { + } + let w = if short_documented && trait_.is_some() { interesting } else { boring }; + + let toggled = !doc_buffer.is_empty(); + if toggled { + let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" }; write_str( - &mut doc_buffer, - format_args!( - "{}", - document_short(item, cx, link, parent, rendering_params.show_def_docs) - ), + w, + format_args!("
"), ); } - } - let w = if short_documented && trait_.is_some() { interesting } else { boring }; - - let toggled = !doc_buffer.is_empty(); - if toggled { - let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" }; - write_str( - w, - format_args!("
"), - ); - } - match &item.kind { - clean::MethodItem(..) | clean::RequiredMethodItem(_) => { - // Only render when the method is not static or we allow static methods - if render_method_item { - let id = cx.derive_id(format!("{item_type}.{name}")); - let source_id = trait_ - .and_then(|trait_| { - trait_ - .items - .iter() - .find(|item| item.name.map(|n| n == *name).unwrap_or(false)) - }) - .map(|item| format!("{}.{name}", item.type_())); + match &item.kind { + clean::MethodItem(..) | clean::RequiredMethodItem(_) => { + // Only render when the method is not static or we allow static methods + if render_method_item { + let id = cx.derive_id(format!("{item_type}.{name}")); + let source_id = trait_ + .and_then(|trait_| { + trait_ + .items + .iter() + .find(|item| item.name.map(|n| n == *name).unwrap_or(false)) + }) + .map(|item| format!("{}.{name}", item.type_())); + write_str( + w, + format_args!( + "
\ + {}", + render_rightside(cx, item, render_mode) + ), + ); + if trait_.is_some() { + // Anchors are only used on trait impls. + write_str(w, format_args!("§")); + } + write_str( + w, + format_args!( + "

{}

", + render_assoc_item( + item, + link.anchor(source_id.as_ref().unwrap_or(&id)), + ItemType::Impl, + cx, + render_mode, + ), + ), + ); + } + } + clean::RequiredAssocConstItem(ref generics, ref ty) => { + let source_id = format!("{item_type}.{name}"); + let id = cx.derive_id(&source_id); write_str( w, - format_args!("
"), + format_args!( + "
\ + {}", + render_rightside(cx, item, render_mode) + ), ); - render_rightside(w, cx, item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. write_str(w, format_args!("§")); } - w.push_str("

"); - render_assoc_item( + write_str( w, - item, - link.anchor(source_id.as_ref().unwrap_or(&id)), - ItemType::Impl, - cx, - render_mode, - ); - w.push_str("

"); - } - } - clean::RequiredAssocConstItem(ref generics, ref ty) => { - let source_id = format!("{item_type}.{name}"); - let id = cx.derive_id(&source_id); - write_str( - w, - format_args!("
"), - ); - render_rightside(w, cx, item, render_mode); - if trait_.is_some() { - // Anchors are only used on trait impls. - write_str(w, format_args!("§")); - } - w.push_str("

"); - assoc_const( - w, - item, - generics, - ty, - AssocConstValue::None, - link.anchor(if trait_.is_some() { &source_id } else { &id }), - 0, - cx, - ); - w.push_str("

"); - } - clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => { - let source_id = format!("{item_type}.{name}"); - let id = cx.derive_id(&source_id); - write_str( - w, - format_args!("
"), - ); - render_rightside(w, cx, item, render_mode); - if trait_.is_some() { - // Anchors are only used on trait impls. - write_str(w, format_args!("§")); - } - w.push_str("

"); - assoc_const( - w, - item, - &ci.generics, - &ci.type_, - match item.kind { - clean::ProvidedAssocConstItem(_) => AssocConstValue::TraitDefault(&ci.kind), - clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind), - _ => unreachable!(), - }, - link.anchor(if trait_.is_some() { &source_id } else { &id }), - 0, - cx, - ); - w.push_str("

"); - } - clean::RequiredAssocTypeItem(ref generics, ref bounds) => { - let source_id = format!("{item_type}.{name}"); - let id = cx.derive_id(&source_id); - write_str( - w, - format_args!("
"), - ); - render_rightside(w, cx, item, render_mode); - if trait_.is_some() { - // Anchors are only used on trait impls. - write_str(w, format_args!("§")); - } - w.push_str("

"); - assoc_type( - w, - item, - generics, - bounds, - None, - link.anchor(if trait_.is_some() { &source_id } else { &id }), - 0, - cx, - ); - w.push_str("

"); - } - clean::AssocTypeItem(tydef, _bounds) => { - let source_id = format!("{item_type}.{name}"); - let id = cx.derive_id(&source_id); - write_str( - w, - format_args!("
"), - ); - render_rightside(w, cx, item, render_mode); - if trait_.is_some() { - // Anchors are only used on trait impls. - write_str(w, format_args!("§")); - } - w.push_str("

"); - assoc_type( - w, - item, - &tydef.generics, - &[], // intentionally leaving out bounds - Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)), - link.anchor(if trait_.is_some() { &source_id } else { &id }), - 0, - cx, - ); - w.push_str("

"); - } - clean::StrippedItem(..) => return, - _ => panic!("can't make docs for trait item with name {:?}", item.name), - } - - w.push_str(&info_buffer); - if toggled { - w.push_str("
"); - w.push_str(&doc_buffer); - w.push_str("
"); - } - } - - let mut impl_items = String::new(); - let mut default_impl_items = String::new(); - let impl_ = i.inner_impl(); - - // Impl items are grouped by kinds: - // - // 1. Constants - // 2. Types - // 3. Functions - // - // This order is because you can have associated constants used in associated types (like array - // length), and both in associcated functions. So with this order, when reading from top to - // bottom, you should see items definitions before they're actually used most of the time. - let mut assoc_types = Vec::new(); - let mut methods = Vec::new(); - - if !impl_.is_negative_trait_impl() { - for trait_item in &impl_.items { - match trait_item.kind { - clean::MethodItem(..) | clean::RequiredMethodItem(_) => methods.push(trait_item), - clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => { - assoc_types.push(trait_item) - } - clean::RequiredAssocConstItem(..) - | clean::ProvidedAssocConstItem(_) - | clean::ImplAssocConstItem(_) => { - // We render it directly since they're supposed to come first. - doc_impl_item( - &mut default_impl_items, - &mut impl_items, - cx, - trait_item, - if trait_.is_some() { &i.impl_item } else { parent }, - link, - render_mode, - false, - trait_, - rendering_params, + format_args!( + "

{}

", + assoc_const( + item, + generics, + ty, + AssocConstValue::None, + link.anchor(if trait_.is_some() { &source_id } else { &id }), + 0, + cx, + ) + ), ); } - _ => {} + clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => { + let source_id = format!("{item_type}.{name}"); + let id = cx.derive_id(&source_id); + write_str( + w, + format_args!( + "
\ + {}", + render_rightside(cx, item, render_mode) + ), + ); + if trait_.is_some() { + // Anchors are only used on trait impls. + write_str(w, format_args!("§")); + } + write_str( + w, + format_args!( + "

{}

", + assoc_const( + item, + &ci.generics, + &ci.type_, + match item.kind { + clean::ProvidedAssocConstItem(_) => + AssocConstValue::TraitDefault(&ci.kind), + clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind), + _ => unreachable!(), + }, + link.anchor(if trait_.is_some() { &source_id } else { &id }), + 0, + cx, + ) + ), + ); + } + clean::RequiredAssocTypeItem(ref generics, ref bounds) => { + let source_id = format!("{item_type}.{name}"); + let id = cx.derive_id(&source_id); + write_str( + w, + format_args!( + "
\ + {}", + render_rightside(cx, item, render_mode) + ), + ); + if trait_.is_some() { + // Anchors are only used on trait impls. + write_str(w, format_args!("§")); + } + write_str( + w, + format_args!( + "

{}

", + assoc_type( + item, + generics, + bounds, + None, + link.anchor(if trait_.is_some() { &source_id } else { &id }), + 0, + cx, + ) + ), + ); + } + clean::AssocTypeItem(tydef, _bounds) => { + let source_id = format!("{item_type}.{name}"); + let id = cx.derive_id(&source_id); + write_str( + w, + format_args!( + "
\ + {}", + render_rightside(cx, item, render_mode) + ), + ); + if trait_.is_some() { + // Anchors are only used on trait impls. + write_str(w, format_args!("§")); + } + write_str( + w, + format_args!( + "

{}

", + assoc_type( + item, + &tydef.generics, + &[], // intentionally leaving out bounds + Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)), + link.anchor(if trait_.is_some() { &source_id } else { &id }), + 0, + cx, + ) + ), + ); + } + clean::StrippedItem(..) => return, + _ => panic!("can't make docs for trait item with name {:?}", item.name), + } + + w.push_str(&info_buffer); + if toggled { + w.push_str("
"); + w.push_str(&doc_buffer); + w.push_str("
"); } } - for assoc_type in assoc_types { - doc_impl_item( - &mut default_impl_items, - &mut impl_items, - cx, - assoc_type, - if trait_.is_some() { &i.impl_item } else { parent }, - link, - render_mode, - false, - trait_, - rendering_params, - ); - } - for method in methods { - doc_impl_item( - &mut default_impl_items, - &mut impl_items, - cx, - method, - if trait_.is_some() { &i.impl_item } else { parent }, - link, - render_mode, - false, - trait_, - rendering_params, - ); - } - } + let mut impl_items = String::new(); + let mut default_impl_items = String::new(); + let impl_ = i.inner_impl(); - fn render_default_items( - boring: &mut String, - interesting: &mut String, - cx: &Context<'_>, - t: &clean::Trait, - i: &clean::Impl, - parent: &clean::Item, - render_mode: RenderMode, - rendering_params: ImplRenderingParameters, - ) { - for trait_item in &t.items { - // Skip over any default trait items that are impossible to reference - // (e.g. if it has a `Self: Sized` bound on an unsized type). - if let Some(impl_def_id) = parent.item_id.as_def_id() - && let Some(trait_item_def_id) = trait_item.item_id.as_def_id() - && cx.tcx().is_impossible_associated_item((impl_def_id, trait_item_def_id)) + // Impl items are grouped by kinds: + // + // 1. Constants + // 2. Types + // 3. Functions + // + // This order is because you can have associated constants used in associated types (like array + // length), and both in associcated functions. So with this order, when reading from top to + // bottom, you should see items definitions before they're actually used most of the time. + let mut assoc_types = Vec::new(); + let mut methods = Vec::new(); + + if !impl_.is_negative_trait_impl() { + for trait_item in &impl_.items { + match trait_item.kind { + clean::MethodItem(..) | clean::RequiredMethodItem(_) => { + methods.push(trait_item) + } + clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => { + assoc_types.push(trait_item) + } + clean::RequiredAssocConstItem(..) + | clean::ProvidedAssocConstItem(_) + | clean::ImplAssocConstItem(_) => { + // We render it directly since they're supposed to come first. + doc_impl_item( + &mut default_impl_items, + &mut impl_items, + cx, + trait_item, + if trait_.is_some() { &i.impl_item } else { parent }, + link, + render_mode, + false, + trait_, + rendering_params, + ); + } + _ => {} + } + } + + for assoc_type in assoc_types { + doc_impl_item( + &mut default_impl_items, + &mut impl_items, + cx, + assoc_type, + if trait_.is_some() { &i.impl_item } else { parent }, + link, + render_mode, + false, + trait_, + rendering_params, + ); + } + for method in methods { + doc_impl_item( + &mut default_impl_items, + &mut impl_items, + cx, + method, + if trait_.is_some() { &i.impl_item } else { parent }, + link, + render_mode, + false, + trait_, + rendering_params, + ); + } + } + + fn render_default_items( + boring: &mut String, + interesting: &mut String, + cx: &Context<'_>, + t: &clean::Trait, + i: &clean::Impl, + parent: &clean::Item, + render_mode: RenderMode, + rendering_params: ImplRenderingParameters, + ) { + for trait_item in &t.items { + // Skip over any default trait items that are impossible to reference + // (e.g. if it has a `Self: Sized` bound on an unsized type). + if let Some(impl_def_id) = parent.item_id.as_def_id() + && let Some(trait_item_def_id) = trait_item.item_id.as_def_id() + && cx.tcx().is_impossible_associated_item((impl_def_id, trait_item_def_id)) + { + continue; + } + + let n = trait_item.name; + if i.items.iter().any(|m| m.name == n) { + continue; + } + let did = i.trait_.as_ref().unwrap().def_id(); + let provided_methods = i.provided_trait_methods(cx.tcx()); + let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods); + + doc_impl_item( + boring, + interesting, + cx, + trait_item, + parent, + assoc_link, + render_mode, + true, + Some(t), + rendering_params, + ); + } + } + + // If we've implemented a trait, then also emit documentation for all + // default items which weren't overridden in the implementation block. + // We don't emit documentation for default items if they appear in the + // Implementations on Foreign Types or Implementors sections. + if rendering_params.show_default_items { + if let Some(t) = trait_ + && !impl_.is_negative_trait_impl() { - continue; + render_default_items( + &mut default_impl_items, + &mut impl_items, + cx, + t, + impl_, + &i.impl_item, + render_mode, + rendering_params, + ); } - - let n = trait_item.name; - if i.items.iter().any(|m| m.name == n) { - continue; - } - let did = i.trait_.as_ref().unwrap().def_id(); - let provided_methods = i.provided_trait_methods(cx.tcx()); - let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods); - - doc_impl_item( - boring, - interesting, - cx, - trait_item, - parent, - assoc_link, - render_mode, - true, - Some(t), - rendering_params, - ); } - } - - // If we've implemented a trait, then also emit documentation for all - // default items which weren't overridden in the implementation block. - // We don't emit documentation for default items if they appear in the - // Implementations on Foreign Types or Implementors sections. - if rendering_params.show_default_items { - if let Some(t) = trait_ - && !impl_.is_negative_trait_impl() - { - render_default_items( - &mut default_impl_items, - &mut impl_items, - cx, - t, - impl_, - &i.impl_item, - render_mode, - rendering_params, - ); - } - } - if render_mode == RenderMode::Normal { - let toggled = !(impl_items.is_empty() && default_impl_items.is_empty()); - if toggled { - close_tags.push("
"); - write_str( - w, - format_args!( + if render_mode == RenderMode::Normal { + let toggled = !(impl_items.is_empty() && default_impl_items.is_empty()); + if toggled { + close_tags.push(""); + write!( + w, "
\ ", if rendering_params.toggle_open_by_default { " open" } else { "" } - ), - ); - } + )?; + } - let (before_dox, after_dox) = i - .impl_item - .opt_doc_value() - .map(|dox| { - Markdown { - content: &dox, - links: &i.impl_item.links(cx), - ids: &mut cx.id_map.borrow_mut(), - error_codes: cx.shared.codes, - edition: cx.shared.edition(), - playground: &cx.shared.playground, - heading_offset: HeadingOffset::H4, - } - .split_summary_and_content() - }) - .unwrap_or((None, None)); - render_impl_summary( - w, - cx, - i, - parent, - rendering_params.show_def_docs, - use_absolute, - aliases, - &before_dox, - ); - if toggled { - w.push_str(""); - } + let (before_dox, after_dox) = i + .impl_item + .opt_doc_value() + .map(|dox| { + Markdown { + content: &dox, + links: &i.impl_item.links(cx), + ids: &mut cx.id_map.borrow_mut(), + error_codes: cx.shared.codes, + edition: cx.shared.edition(), + playground: &cx.shared.playground, + heading_offset: HeadingOffset::H4, + } + .split_summary_and_content() + }) + .unwrap_or((None, None)); + write!( + w, + "{}", + render_impl_summary( + cx, + i, + parent, + rendering_params.show_def_docs, + use_absolute, + aliases, + before_dox.as_deref(), + ) + )?; + if toggled { + w.write_str("")?; + } - if before_dox.is_some() { - if trait_.is_none() && impl_.items.is_empty() { - w.push_str( - "
\ + if before_dox.is_some() { + if trait_.is_none() && impl_.items.is_empty() { + w.write_str( + "
\
This impl block contains no items.
\
", - ); + )?; + } + if let Some(after_dox) = after_dox { + write!(w, "
{after_dox}
")?; + } } - if let Some(after_dox) = after_dox { - write_str(w, format_args!("
{after_dox}
")); + if !default_impl_items.is_empty() || !impl_items.is_empty() { + w.write_str("
")?; + close_tags.push("
"); } } if !default_impl_items.is_empty() || !impl_items.is_empty() { - w.push_str("
"); - close_tags.push("
"); + w.write_str(&default_impl_items)?; + w.write_str(&impl_items)?; } - } - if !default_impl_items.is_empty() || !impl_items.is_empty() { - w.push_str(&default_impl_items); - w.push_str(&impl_items); - } - for tag in close_tags.into_iter().rev() { - w.push_str(tag); - } + for tag in close_tags.into_iter().rev() { + w.write_str(tag)?; + } + Ok(()) + }) } // Render the items that appear on the right side of methods, impls, and // associated types. For example "1.0.0 (const: 1.39.0) · source". -fn render_rightside(w: &mut String, cx: &Context<'_>, item: &clean::Item, render_mode: RenderMode) { +fn render_rightside<'a, 'tcx>( + cx: &'a Context<'tcx>, + item: &'a clean::Item, + render_mode: RenderMode, +) -> impl fmt::Display + 'a + Captures<'tcx> { let tcx = cx.tcx(); - // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove - // this condition. - let const_stability = match render_mode { - RenderMode::Normal => item.const_stability(tcx), - RenderMode::ForDeref { .. } => None, - }; - let src_href = cx.src_href(item); - let has_src_ref = src_href.is_some(); + fmt::from_fn(move |w| { + // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove + // this condition. + let const_stability = match render_mode { + RenderMode::Normal => item.const_stability(tcx), + RenderMode::ForDeref { .. } => None, + }; + let src_href = cx.src_href(item); + let stability = render_stability_since_raw_with_extra( + item.stable_since(tcx), + const_stability, + if src_href.is_some() { "" } else { " rightside" }, + ); - let mut rightside = String::new(); - let has_stability = render_stability_since_raw_with_extra( - &mut rightside, - item.stable_since(tcx), - const_stability, - if has_src_ref { "" } else { " rightside" }, - ); - if let Some(link) = src_href { - if has_stability { - write_str( - &mut rightside, - format_args!(" · Source"), - ); - } else { - write_str( - &mut rightside, - format_args!("Source"), - ); + match (stability, src_href) { + (Some(stability), Some(link)) => { + write!( + w, + "{stability} · Source", + ) + } + (Some(stability), None) => { + write!(w, "{stability}") + } + (None, Some(link)) => { + write!(w, "Source") + } + (None, None) => Ok(()), } - } - if has_stability && has_src_ref { - write_str(w, format_args!("{rightside}")); - } else { - w.push_str(&rightside); - } + }) } -pub(crate) fn render_impl_summary( - w: &mut String, - cx: &Context<'_>, - i: &Impl, - parent: &clean::Item, +pub(crate) fn render_impl_summary<'a, 'tcx>( + cx: &'a Context<'tcx>, + i: &'a Impl, + parent: &'a clean::Item, show_def_docs: bool, use_absolute: Option, // This argument is used to reference same type with different paths to avoid duplication // in documentation pages for trait with automatic implementations like "Send" and "Sync". - aliases: &[String], - doc: &Option, -) { - let inner_impl = i.inner_impl(); - let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id)); - let aliases = (!aliases.is_empty()) - .then_some(fmt::from_fn(|f| { - write!(f, " data-aliases=\"{}\"", fmt::from_fn(|f| aliases.iter().joined(",", f))) - })) - .maybe_display(); - write_str(w, format_args!("
")); - render_rightside(w, cx, &i.impl_item, RenderMode::Normal); - write_str( - w, - format_args!( - "§\ -

" - ), - ); + aliases: &'a [String], + doc: Option<&'a str>, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + let inner_impl = i.inner_impl(); + let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id)); + let aliases = (!aliases.is_empty()) + .then_some(fmt::from_fn(|f| { + write!(f, " data-aliases=\"{}\"", fmt::from_fn(|f| aliases.iter().joined(",", f))) + })) + .maybe_display(); + write!( + w, + "
\ + {}\ + §\ +

", + render_rightside(cx, &i.impl_item, RenderMode::Normal) + )?; - if let Some(use_absolute) = use_absolute { - write_str(w, format_args!("{}", inner_impl.print(use_absolute, cx))); - if show_def_docs { - for it in &inner_impl.items { - if let clean::AssocTypeItem(ref tydef, ref _bounds) = it.kind { - w.push_str("
"); - assoc_type( - w, - it, - &tydef.generics, - &[], // intentionally leaving out bounds - Some(&tydef.type_), - AssocItemLink::Anchor(None), - 0, - cx, - ); - w.push_str(";
"); + if let Some(use_absolute) = use_absolute { + write!(w, "{}", inner_impl.print(use_absolute, cx))?; + if show_def_docs { + for it in &inner_impl.items { + if let clean::AssocTypeItem(ref tydef, ref _bounds) = it.kind { + write!( + w, + "
{};
", + assoc_type( + it, + &tydef.generics, + &[], // intentionally leaving out bounds + Some(&tydef.type_), + AssocItemLink::Anchor(None), + 0, + cx, + ) + )?; + } } } + } else { + write!(w, "{}", inner_impl.print(false, cx))?; } - } else { - write_str(w, format_args!("{}", inner_impl.print(false, cx))); - } - w.push_str("

"); + w.write_str("

")?; - let is_trait = inner_impl.trait_.is_some(); - if is_trait && let Some(portability) = portability(&i.impl_item, Some(parent)) { - write_str( - w, - format_args!( + let is_trait = inner_impl.trait_.is_some(); + if is_trait && let Some(portability) = portability(&i.impl_item, Some(parent)) { + write!( + w, "\ -
{portability}
\ -
", - ), - ); - } +
{portability}
\ + ", + )?; + } - if let Some(doc) = doc { - write_str(w, format_args!("
{doc}
")); - } + if let Some(doc) = doc { + write!(w, "
{doc}
")?; + } - w.push_str("
"); + w.write_str("") + }) } pub(crate) fn small_url_encode(s: String) -> String { diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index f32011470399..b647b2aad75a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; use std::fmt; -use std::fmt::Display; +use std::fmt::{Display, Write as _}; use rinja::Template; use rustc_abi::VariantIdx; @@ -32,7 +32,7 @@ use crate::formats::item_type::ItemType; use crate::html::escape::{Escape, EscapeBodyTextWithWbr}; use crate::html::format::{ Ending, PrintWithSpace, join_with_double_colon, print_abi_with_space, - print_constness_with_space, print_where_clause, visibility_print_with_space, write_str, + print_constness_with_space, print_where_clause, visibility_print_with_space, }; use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine}; use crate::html::render::{document_full, document_item_info}; @@ -162,132 +162,139 @@ struct ItemVars<'a> { src_href: Option<&'a str>, } -/// Calls `print_where_clause` and returns `true` if a `where` clause was generated. -fn print_where_clause_and_check<'a, 'tcx: 'a>( - buffer: &mut String, - gens: &'a clean::Generics, +pub(super) fn print_item<'a, 'tcx>( cx: &'a Context<'tcx>, -) -> bool { - let len_before = buffer.len(); - write_str(buffer, format_args!("{}", print_where_clause(gens, cx, 0, Ending::Newline))); - len_before != buffer.len() -} - -pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut String) { + item: &'a clean::Item, +) -> impl fmt::Display + 'a + Captures<'tcx> { debug_assert!(!item.is_stripped()); - let typ = match item.kind { - clean::ModuleItem(_) => { - if item.is_crate() { - "Crate " - } else { - "Module " + + fmt::from_fn(|buf| { + let typ = match item.kind { + clean::ModuleItem(_) => { + if item.is_crate() { + "Crate " + } else { + "Module " + } } - } - clean::FunctionItem(..) | clean::ForeignFunctionItem(..) => "Function ", - clean::TraitItem(..) => "Trait ", - clean::StructItem(..) => "Struct ", - clean::UnionItem(..) => "Union ", - clean::EnumItem(..) => "Enum ", - clean::TypeAliasItem(..) => "Type Alias ", - clean::MacroItem(..) => "Macro ", - clean::ProcMacroItem(ref mac) => match mac.kind { - MacroKind::Bang => "Macro ", - MacroKind::Attr => "Attribute Macro ", - MacroKind::Derive => "Derive Macro ", - }, - clean::PrimitiveItem(..) => "Primitive Type ", - clean::StaticItem(..) | clean::ForeignStaticItem(..) => "Static ", - clean::ConstantItem(..) => "Constant ", - clean::ForeignTypeItem => "Foreign Type ", - clean::KeywordItem => "Keyword ", - clean::TraitAliasItem(..) => "Trait Alias ", - _ => { - // We don't generate pages for any other type. - unreachable!(); - } - }; - let stability_since_raw = { - let mut buf = String::new(); - render_stability_since_raw( - &mut buf, - item.stable_since(cx.tcx()), - item.const_stability(cx.tcx()), - ); - buf - }; + clean::FunctionItem(..) | clean::ForeignFunctionItem(..) => "Function ", + clean::TraitItem(..) => "Trait ", + clean::StructItem(..) => "Struct ", + clean::UnionItem(..) => "Union ", + clean::EnumItem(..) => "Enum ", + clean::TypeAliasItem(..) => "Type Alias ", + clean::MacroItem(..) => "Macro ", + clean::ProcMacroItem(ref mac) => match mac.kind { + MacroKind::Bang => "Macro ", + MacroKind::Attr => "Attribute Macro ", + MacroKind::Derive => "Derive Macro ", + }, + clean::PrimitiveItem(..) => "Primitive Type ", + clean::StaticItem(..) | clean::ForeignStaticItem(..) => "Static ", + clean::ConstantItem(..) => "Constant ", + clean::ForeignTypeItem => "Foreign Type ", + clean::KeywordItem => "Keyword ", + clean::TraitAliasItem(..) => "Trait Alias ", + _ => { + // We don't generate pages for any other type. + unreachable!(); + } + }; + let stability_since_raw = + render_stability_since_raw(item.stable_since(cx.tcx()), item.const_stability(cx.tcx())) + .maybe_display() + .to_string(); - // Write source tag - // - // When this item is part of a `crate use` in a downstream crate, the - // source link in the downstream documentation will actually come back to - // this page, and this link will be auto-clicked. The `id` attribute is - // used to find the link to auto-click. - let src_href = - if cx.info.include_sources && !item.is_primitive() { cx.src_href(item) } else { None }; + // Write source tag + // + // When this item is part of a `crate use` in a downstream crate, the + // source link in the downstream documentation will actually come back to + // this page, and this link will be auto-clicked. The `id` attribute is + // used to find the link to auto-click. + let src_href = + if cx.info.include_sources && !item.is_primitive() { cx.src_href(item) } else { None }; - let path_components = if item.is_primitive() || item.is_keyword() { - vec![] - } else { - let cur = &cx.current; - let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() }; - cur.iter() - .enumerate() - .take(amt) - .map(|(i, component)| PathComponent { - path: "../".repeat(cur.len() - i - 1), - name: *component, - }) - .collect() - }; + let path_components = if item.is_primitive() || item.is_keyword() { + vec![] + } else { + let cur = &cx.current; + let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() }; + cur.iter() + .enumerate() + .take(amt) + .map(|(i, component)| PathComponent { + path: "../".repeat(cur.len() - i - 1), + name: *component, + }) + .collect() + }; - let item_vars = ItemVars { - typ, - name: item.name.as_ref().unwrap().as_str(), - item_type: &item.type_().to_string(), - path_components, - stability_since_raw: &stability_since_raw, - src_href: src_href.as_deref(), - }; + let item_vars = ItemVars { + typ, + name: item.name.as_ref().unwrap().as_str(), + item_type: &item.type_().to_string(), + path_components, + stability_since_raw: &stability_since_raw, + src_href: src_href.as_deref(), + }; - item_vars.render_into(buf).unwrap(); + item_vars.render_into(buf).unwrap(); - match &item.kind { - clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items), - clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f, _) => { - item_function(buf, cx, item, f) - } - clean::TraitItem(ref t) => item_trait(buf, cx, item, t), - clean::StructItem(ref s) => item_struct(buf, cx, item, s), - clean::UnionItem(ref s) => item_union(buf, cx, item, s), - clean::EnumItem(ref e) => item_enum(buf, cx, item, e), - clean::TypeAliasItem(ref t) => item_type_alias(buf, cx, item, t), - clean::MacroItem(ref m) => item_macro(buf, cx, item, m), - clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m), - clean::PrimitiveItem(_) => item_primitive(buf, cx, item), - clean::StaticItem(ref i) => item_static(buf, cx, item, i, None), - clean::ForeignStaticItem(ref i, safety) => item_static(buf, cx, item, i, Some(*safety)), - clean::ConstantItem(ci) => item_constant(buf, cx, item, &ci.generics, &ci.type_, &ci.kind), - clean::ForeignTypeItem => item_foreign_type(buf, cx, item), - clean::KeywordItem => item_keyword(buf, cx, item), - clean::TraitAliasItem(ref ta) => item_trait_alias(buf, cx, item, ta), - _ => { - // We don't generate pages for any other type. - unreachable!(); - } - } + match &item.kind { + clean::ModuleItem(ref m) => { + write!(buf, "{}", item_module(cx, item, &m.items)) + } + clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f, _) => { + write!(buf, "{}", item_function(cx, item, f)) + } + clean::TraitItem(ref t) => write!(buf, "{}", item_trait(cx, item, t)), + clean::StructItem(ref s) => { + write!(buf, "{}", item_struct(cx, item, s)) + } + clean::UnionItem(ref s) => write!(buf, "{}", item_union(cx, item, s)), + clean::EnumItem(ref e) => write!(buf, "{}", item_enum(cx, item, e)), + clean::TypeAliasItem(ref t) => { + write!(buf, "{}", item_type_alias(cx, item, t)) + } + clean::MacroItem(ref m) => write!(buf, "{}", item_macro(cx, item, m)), + clean::ProcMacroItem(ref m) => { + write!(buf, "{}", item_proc_macro(cx, item, m)) + } + clean::PrimitiveItem(_) => write!(buf, "{}", item_primitive(cx, item)), + clean::StaticItem(ref i) => { + write!(buf, "{}", item_static(cx, item, i, None)) + } + clean::ForeignStaticItem(ref i, safety) => { + write!(buf, "{}", item_static(cx, item, i, Some(*safety))) + } + clean::ConstantItem(ci) => { + write!(buf, "{}", item_constant(cx, item, &ci.generics, &ci.type_, &ci.kind)) + } + clean::ForeignTypeItem => { + write!(buf, "{}", item_foreign_type(cx, item)) + } + clean::KeywordItem => write!(buf, "{}", item_keyword(cx, item)), + clean::TraitAliasItem(ref ta) => { + write!(buf, "{}", item_trait_alias(cx, item, ta)) + } + _ => { + // We don't generate pages for any other type. + unreachable!(); + } + }?; - // Render notable-traits.js used for all methods in this module. - let mut types_with_notable_traits = cx.types_with_notable_traits.borrow_mut(); - if !types_with_notable_traits.is_empty() { - write_str( - buf, - format_args!( + // Render notable-traits.js used for all methods in this module. + let mut types_with_notable_traits = cx.types_with_notable_traits.borrow_mut(); + if !types_with_notable_traits.is_empty() { + write!( + buf, r#""#, - notable_traits_json(types_with_notable_traits.iter(), cx) - ), - ); - types_with_notable_traits.clear(); - } + notable_traits_json(types_with_notable_traits.iter(), cx), + )?; + types_with_notable_traits.clear(); + } + Ok(()) + }) } /// For large structs, enums, unions, etc, determine whether to hide their fields @@ -314,192 +321,198 @@ trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + Display { fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>); } -fn item_module(w: &mut String, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) { - write_str(w, format_args!("{}", document(cx, item, None, HeadingOffset::H2))); +fn item_module<'a, 'tcx>( + cx: &'a Context<'tcx>, + item: &'a clean::Item, + items: &'a [clean::Item], +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?; - let mut not_stripped_items = - items.iter().filter(|i| !i.is_stripped()).enumerate().collect::>(); + let mut not_stripped_items = + items.iter().filter(|i| !i.is_stripped()).enumerate().collect::>(); - // the order of item types in the listing - fn reorder(ty: ItemType) -> u8 { - match ty { - ItemType::ExternCrate => 0, - ItemType::Import => 1, - ItemType::Primitive => 2, - ItemType::Module => 3, - ItemType::Macro => 4, - ItemType::Struct => 5, - ItemType::Enum => 6, - ItemType::Constant => 7, - ItemType::Static => 8, - ItemType::Trait => 9, - ItemType::Function => 10, - ItemType::TypeAlias => 12, - ItemType::Union => 13, - _ => 14 + ty as u8, - } - } - - fn cmp(i1: &clean::Item, i2: &clean::Item, tcx: TyCtxt<'_>) -> Ordering { - let rty1 = reorder(i1.type_()); - let rty2 = reorder(i2.type_()); - if rty1 != rty2 { - return rty1.cmp(&rty2); - } - let is_stable1 = i1.stability(tcx).as_ref().map(|s| s.level.is_stable()).unwrap_or(true); - let is_stable2 = i2.stability(tcx).as_ref().map(|s| s.level.is_stable()).unwrap_or(true); - if is_stable1 != is_stable2 { - // true is bigger than false in the standard bool ordering, - // but we actually want stable items to come first - return is_stable2.cmp(&is_stable1); - } - let lhs = i1.name.unwrap_or(kw::Empty); - let rhs = i2.name.unwrap_or(kw::Empty); - compare_names(lhs.as_str(), rhs.as_str()) - } - - let tcx = cx.tcx(); - - match cx.shared.module_sorting { - ModuleSorting::Alphabetical => { - not_stripped_items.sort_by(|(_, i1), (_, i2)| cmp(i1, i2, tcx)); - } - ModuleSorting::DeclarationOrder => {} - } - // This call is to remove re-export duplicates in cases such as: - // - // ``` - // pub(crate) mod foo { - // pub(crate) mod bar { - // pub(crate) trait Double { fn foo(); } - // } - // } - // - // pub(crate) use foo::bar::*; - // pub(crate) use foo::*; - // ``` - // - // `Double` will appear twice in the generated docs. - // - // FIXME: This code is quite ugly and could be improved. Small issue: DefId - // can be identical even if the elements are different (mostly in imports). - // So in case this is an import, we keep everything by adding a "unique id" - // (which is the position in the vector). - not_stripped_items.dedup_by_key(|(idx, i)| { - ( - i.item_id, - if i.name.is_some() { Some(full_path(cx, i)) } else { None }, - i.type_(), - if i.is_import() { *idx } else { 0 }, - ) - }); - - debug!("{not_stripped_items:?}"); - let mut last_section = None; - - for (_, myitem) in ¬_stripped_items { - let my_section = item_ty_to_section(myitem.type_()); - if Some(my_section) != last_section { - if last_section.is_some() { - w.push_str(ITEM_TABLE_CLOSE); + // the order of item types in the listing + fn reorder(ty: ItemType) -> u8 { + match ty { + ItemType::ExternCrate => 0, + ItemType::Import => 1, + ItemType::Primitive => 2, + ItemType::Module => 3, + ItemType::Macro => 4, + ItemType::Struct => 5, + ItemType::Enum => 6, + ItemType::Constant => 7, + ItemType::Static => 8, + ItemType::Trait => 9, + ItemType::Function => 10, + ItemType::TypeAlias => 12, + ItemType::Union => 13, + _ => 14 + ty as u8, } - last_section = Some(my_section); - let section_id = my_section.id(); - let tag = - if section_id == "reexports" { REEXPORTS_TABLE_OPEN } else { ITEM_TABLE_OPEN }; - write_section_heading(w, my_section.name(), &cx.derive_id(section_id), None, tag); } - match myitem.kind { - clean::ExternCrateItem { ref src } => { - use crate::html::format::anchor; + fn cmp(i1: &clean::Item, i2: &clean::Item, tcx: TyCtxt<'_>) -> Ordering { + let rty1 = reorder(i1.type_()); + let rty2 = reorder(i2.type_()); + if rty1 != rty2 { + return rty1.cmp(&rty2); + } + let is_stable1 = + i1.stability(tcx).as_ref().map(|s| s.level.is_stable()).unwrap_or(true); + let is_stable2 = + i2.stability(tcx).as_ref().map(|s| s.level.is_stable()).unwrap_or(true); + if is_stable1 != is_stable2 { + // true is bigger than false in the standard bool ordering, + // but we actually want stable items to come first + return is_stable2.cmp(&is_stable1); + } + let lhs = i1.name.unwrap_or(kw::Empty); + let rhs = i2.name.unwrap_or(kw::Empty); + compare_names(lhs.as_str(), rhs.as_str()) + } - match *src { - Some(src) => { - write_str( - w, - format_args!( + let tcx = cx.tcx(); + + match cx.shared.module_sorting { + ModuleSorting::Alphabetical => { + not_stripped_items.sort_by(|(_, i1), (_, i2)| cmp(i1, i2, tcx)); + } + ModuleSorting::DeclarationOrder => {} + } + // This call is to remove re-export duplicates in cases such as: + // + // ``` + // pub(crate) mod foo { + // pub(crate) mod bar { + // pub(crate) trait Double { fn foo(); } + // } + // } + // + // pub(crate) use foo::bar::*; + // pub(crate) use foo::*; + // ``` + // + // `Double` will appear twice in the generated docs. + // + // FIXME: This code is quite ugly and could be improved. Small issue: DefId + // can be identical even if the elements are different (mostly in imports). + // So in case this is an import, we keep everything by adding a "unique id" + // (which is the position in the vector). + not_stripped_items.dedup_by_key(|(idx, i)| { + ( + i.item_id, + if i.name.is_some() { Some(full_path(cx, i)) } else { None }, + i.type_(), + if i.is_import() { *idx } else { 0 }, + ) + }); + + debug!("{not_stripped_items:?}"); + let mut last_section = None; + + for (_, myitem) in ¬_stripped_items { + let my_section = item_ty_to_section(myitem.type_()); + if Some(my_section) != last_section { + if last_section.is_some() { + w.write_str(ITEM_TABLE_CLOSE)?; + } + last_section = Some(my_section); + let section_id = my_section.id(); + let tag = + if section_id == "reexports" { REEXPORTS_TABLE_OPEN } else { ITEM_TABLE_OPEN }; + write!( + w, + "{}", + write_section_heading(my_section.name(), &cx.derive_id(section_id), None, tag) + )?; + } + + match myitem.kind { + clean::ExternCrateItem { ref src } => { + use crate::html::format::anchor; + + match *src { + Some(src) => { + write!( + w, "
{}extern crate {} as {};", visibility_print_with_space(myitem, cx), anchor(myitem.item_id.expect_def_id(), src, cx), EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()) - ), - ); - } - None => { - write_str( - w, - format_args!( + )?; + } + None => { + write!( + w, "
{}extern crate {};", visibility_print_with_space(myitem, cx), anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx) - ), - ); + )?; + } } + w.write_str("
")?; } - w.push_str(""); - } - clean::ImportItem(ref import) => { - let stab_tags = import.source.did.map_or_else(String::new, |import_def_id| { - extra_info_tags(tcx, myitem, item, Some(import_def_id)).to_string() - }); + clean::ImportItem(ref import) => { + let stab_tags = import.source.did.map_or_else(String::new, |import_def_id| { + extra_info_tags(tcx, myitem, item, Some(import_def_id)).to_string() + }); - let id = match import.kind { - clean::ImportKind::Simple(s) => { - format!(" id=\"{}\"", cx.derive_id(format!("reexport.{s}"))) - } - clean::ImportKind::Glob => String::new(), - }; - write_str( - w, - format_args!( + let id = match import.kind { + clean::ImportKind::Simple(s) => { + format!(" id=\"{}\"", cx.derive_id(format!("reexport.{s}"))) + } + clean::ImportKind::Glob => String::new(), + }; + write!( + w, "\ {vis}{imp}{stab_tags}\ ", vis = visibility_print_with_space(myitem, cx), imp = import.print(cx) - ), - ); - } - - _ => { - if myitem.name.is_none() { - continue; + )?; } - let unsafety_flag = match myitem.kind { - clean::FunctionItem(_) | clean::ForeignFunctionItem(..) - if myitem.fn_header(tcx).unwrap().is_unsafe() => - { - "" + _ => { + if myitem.name.is_none() { + continue; } - clean::ForeignStaticItem(_, hir::Safety::Unsafe) => { - "" - } - _ => "", - }; - let visibility_and_hidden = match myitem.visibility(tcx) { - Some(ty::Visibility::Restricted(_)) => { - if myitem.is_doc_hidden() { - // Don't separate with a space when there are two of them - " 🔒👻 " - } else { - " 🔒 " + let unsafety_flag = match myitem.kind { + clean::FunctionItem(_) | clean::ForeignFunctionItem(..) + if myitem.fn_header(tcx).unwrap().is_unsafe() => + { + "" } - } - _ if myitem.is_doc_hidden() => " 👻 ", - _ => "", - }; + clean::ForeignStaticItem(_, hir::Safety::Unsafe) => { + "" + } + _ => "", + }; - let docs = - MarkdownSummaryLine(&myitem.doc_value(), &myitem.links(cx)).into_string(); - let (docs_before, docs_after) = - if docs.is_empty() { ("", "") } else { ("
", "
") }; - write_str( - w, - format_args!( + let visibility_and_hidden = match myitem.visibility(tcx) { + Some(ty::Visibility::Restricted(_)) => { + if myitem.is_doc_hidden() { + // Don't separate with a space when there are two of them + " 🔒👻 " + } else { + " 🔒 " + } + } + _ if myitem.is_doc_hidden() => { + " 👻 " + } + _ => "", + }; + + let docs = + MarkdownSummaryLine(&myitem.doc_value(), &myitem.links(cx)).into_string(); + let (docs_before, docs_after) = + if docs.is_empty() { ("", "") } else { ("
", "
") }; + write!( + w, "
\ {name}\ {visibility_and_hidden}\ @@ -514,15 +527,16 @@ fn item_module(w: &mut String, cx: &Context<'_>, item: &clean::Item, items: &[cl unsafety_flag = unsafety_flag, href = item_path(myitem.type_(), myitem.name.unwrap().as_str()), title = format_args!("{} {}", myitem.type_(), full_path(cx, myitem)), - ), - ); + )?; + } } } - } - if last_section.is_some() { - w.push_str(ITEM_TABLE_CLOSE); - } + if last_section.is_some() { + w.write_str(ITEM_TABLE_CLOSE)?; + } + Ok(()) + }) } /// Render the stability, deprecation and portability tags that are displayed in the item's summary @@ -583,44 +597,47 @@ fn extra_info_tags<'a, 'tcx: 'a>( }) } -fn item_function(w: &mut String, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) { - let tcx = cx.tcx(); - let header = it.fn_header(tcx).expect("printing a function which isn't a function"); - debug!( - "item_function/const: {:?} {:?} {:?} {:?}", - it.name, - &header.constness, - it.stable_since(tcx), - it.const_stability(tcx), - ); - let constness = print_constness_with_space( - &header.constness, - it.stable_since(tcx), - it.const_stability(tcx), - ); - let safety = header.safety.print_with_space(); - let abi = print_abi_with_space(header.abi).to_string(); - let asyncness = header.asyncness.print_with_space(); - let visibility = visibility_print_with_space(it, cx).to_string(); - let name = it.name.unwrap(); +fn item_function<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + f: &'a clean::Function, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + let tcx = cx.tcx(); + let header = it.fn_header(tcx).expect("printing a function which isn't a function"); + debug!( + "item_function/const: {:?} {:?} {:?} {:?}", + it.name, + &header.constness, + it.stable_since(tcx), + it.const_stability(tcx), + ); + let constness = print_constness_with_space( + &header.constness, + it.stable_since(tcx), + it.const_stability(tcx), + ); + let safety = header.safety.print_with_space(); + let abi = print_abi_with_space(header.abi).to_string(); + let asyncness = header.asyncness.print_with_space(); + let visibility = visibility_print_with_space(it, cx).to_string(); + let name = it.name.unwrap(); - let generics_len = format!("{:#}", f.generics.print(cx)).len(); - let header_len = "fn ".len() - + visibility.len() - + constness.len() - + asyncness.len() - + safety.len() - + abi.len() - + name.as_str().len() - + generics_len; + let generics_len = format!("{:#}", f.generics.print(cx)).len(); + let header_len = "fn ".len() + + visibility.len() + + constness.len() + + asyncness.len() + + safety.len() + + abi.len() + + name.as_str().len() + + generics_len; - let notable_traits = notable_traits_button(&f.decl.output, cx).maybe_display(); + let notable_traits = notable_traits_button(&f.decl.output, cx).maybe_display(); - wrap_item(w, |w| { - w.reserve(header_len); - write_str( - w, - format_args!( + wrap_item(w, |w| { + write!( + w, "{attrs}{vis}{constness}{asyncness}{safety}{abi}fn \ {name}{generics}{decl}{notable_traits}{where_clause}", attrs = render_attributes_in_pre(it, "", cx), @@ -631,35 +648,41 @@ fn item_function(w: &mut String, cx: &Context<'_>, it: &clean::Item, f: &clean:: abi = abi, name = name, generics = f.generics.print(cx), - where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline), + where_clause = + print_where_clause(&f.generics, cx, 0, Ending::Newline).maybe_display(), decl = f.decl.full_print(header_len, 0, cx), - ), - ); - }); - write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); + ) + })?; + write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) + }) } -fn item_trait(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) { - let tcx = cx.tcx(); - let bounds = bounds(&t.bounds, false, cx); - let required_types = - t.items.iter().filter(|m| m.is_required_associated_type()).collect::>(); - let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::>(); - let required_consts = - t.items.iter().filter(|m| m.is_required_associated_const()).collect::>(); - let provided_consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>(); - let required_methods = t.items.iter().filter(|m| m.is_ty_method()).collect::>(); - let provided_methods = t.items.iter().filter(|m| m.is_method()).collect::>(); - let count_types = required_types.len() + provided_types.len(); - let count_consts = required_consts.len() + provided_consts.len(); - let count_methods = required_methods.len() + provided_methods.len(); - let must_implement_one_of_functions = tcx.trait_def(t.def_id).must_implement_one_of.clone(); +fn item_trait<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + t: &'a clean::Trait, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + let tcx = cx.tcx(); + let bounds = bounds(&t.bounds, false, cx); + let required_types = + t.items.iter().filter(|m| m.is_required_associated_type()).collect::>(); + let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::>(); + let required_consts = + t.items.iter().filter(|m| m.is_required_associated_const()).collect::>(); + let provided_consts = + t.items.iter().filter(|m| m.is_associated_const()).collect::>(); + let required_methods = t.items.iter().filter(|m| m.is_ty_method()).collect::>(); + let provided_methods = t.items.iter().filter(|m| m.is_method()).collect::>(); + let count_types = required_types.len() + provided_types.len(); + let count_consts = required_consts.len() + provided_consts.len(); + let count_methods = required_methods.len() + provided_methods.len(); + let must_implement_one_of_functions = tcx.trait_def(t.def_id).must_implement_one_of.clone(); - // Output the trait definition - wrap_item(w, |mut w| { - write_str( - w, - format_args!( + // Output the trait definition + wrap_item(w, |mut w| { + write!( + w, "{attrs}{vis}{safety}{is_auto}trait {name}{generics}{bounds}", attrs = render_attributes_in_pre(it, "", cx), vis = visibility_print_with_space(it, cx), @@ -667,747 +690,820 @@ fn item_trait(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra is_auto = if t.is_auto(tcx) { "auto " } else { "" }, name = it.name.unwrap(), generics = t.generics.print(cx), - ), - ); + )?; - if !t.generics.where_predicates.is_empty() { - write_str( - w, - format_args!("{}", print_where_clause(&t.generics, cx, 0, Ending::Newline)), - ); - } else { - w.push_str(" "); - } - - if t.items.is_empty() { - w.push_str("{ }"); - } else { - // FIXME: we should be using a derived_id for the Anchors here - w.push_str("{\n"); - let mut toggle = false; - - // If there are too many associated types, hide _everything_ - if should_hide_fields(count_types) { - toggle = true; - toggle_open( - &mut w, - format_args!("{} associated items", count_types + count_consts + count_methods), - ); + if !t.generics.where_predicates.is_empty() { + write!( + w, + "{}", + print_where_clause(&t.generics, cx, 0, Ending::Newline).maybe_display() + )?; + } else { + w.write_char(' ')?; } - for types in [&required_types, &provided_types] { - for t in types { - render_assoc_item( - w, - t, - AssocItemLink::Anchor(None), - ItemType::Trait, - cx, - RenderMode::Normal, + + if t.items.is_empty() { + w.write_str("{ }") + } else { + // FIXME: we should be using a derived_id for the Anchors here + w.write_str("{\n")?; + let mut toggle = false; + + // If there are too many associated types, hide _everything_ + if should_hide_fields(count_types) { + toggle = true; + toggle_open( + &mut w, + format_args!( + "{} associated items", + count_types + count_consts + count_methods + ), ); - w.push_str(";\n"); } - } - // If there are too many associated constants, hide everything after them - // We also do this if the types + consts is large because otherwise we could - // render a bunch of types and _then_ a bunch of consts just because both were - // _just_ under the limit - if !toggle && should_hide_fields(count_types + count_consts) { - toggle = true; - toggle_open( - &mut w, - format_args!( - "{count_consts} associated constant{plural_const} and \ - {count_methods} method{plural_method}", - plural_const = pluralize(count_consts), - plural_method = pluralize(count_methods), - ), - ); - } - if count_types != 0 && (count_consts != 0 || count_methods != 0) { - w.push_str("\n"); - } - for consts in [&required_consts, &provided_consts] { - for c in consts { - render_assoc_item( - w, - c, - AssocItemLink::Anchor(None), - ItemType::Trait, - cx, - RenderMode::Normal, - ); - w.push_str(";\n"); - } - } - if !toggle && should_hide_fields(count_methods) { - toggle = true; - toggle_open(&mut w, format_args!("{count_methods} methods")); - } - if count_consts != 0 && count_methods != 0 { - w.push_str("\n"); - } - - if !required_methods.is_empty() { - write_str( - w, - format_args_nl!(" // Required method{}", pluralize(required_methods.len())), - ); - } - for (pos, m) in required_methods.iter().enumerate() { - render_assoc_item( - w, - m, - AssocItemLink::Anchor(None), - ItemType::Trait, - cx, - RenderMode::Normal, - ); - w.push_str(";\n"); - - if pos < required_methods.len() - 1 { - w.push_str(""); - } - } - if !required_methods.is_empty() && !provided_methods.is_empty() { - w.push_str("\n"); - } - - if !provided_methods.is_empty() { - write_str( - w, - format_args_nl!(" // Provided method{}", pluralize(provided_methods.len())), - ); - } - for (pos, m) in provided_methods.iter().enumerate() { - render_assoc_item( - w, - m, - AssocItemLink::Anchor(None), - ItemType::Trait, - cx, - RenderMode::Normal, - ); - - w.push_str(" { ... }\n"); - - if pos < provided_methods.len() - 1 { - w.push_str(""); - } - } - if toggle { - toggle_close(&mut w); - } - w.push_str("}"); - } - }); - - // Trait documentation - write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); - - fn trait_item(w: &mut String, cx: &Context<'_>, m: &clean::Item, t: &clean::Item) { - let name = m.name.unwrap(); - info!("Documenting {name} on {ty_name:?}", ty_name = t.name); - let item_type = m.type_(); - let id = cx.derive_id(format!("{item_type}.{name}")); - - let mut content = String::new(); - write_str(&mut content, format_args!("{}", document_full(m, cx, HeadingOffset::H5))); - - let toggled = !content.is_empty(); - if toggled { - let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" }; - write_str( - w, - format_args!("
"), - ); - } - write_str(w, format_args!("
")); - render_rightside(w, cx, m, RenderMode::Normal); - write_str(w, format_args!("

")); - render_assoc_item( - w, - m, - AssocItemLink::Anchor(Some(&id)), - ItemType::Impl, - cx, - RenderMode::Normal, - ); - w.push_str("

"); - document_item_info(cx, m, Some(t)).render_into(w).unwrap(); - if toggled { - write_str(w, format_args!("
")); - w.push_str(&content); - write_str(w, format_args!("
")); - } - } - - if !required_consts.is_empty() { - write_section_heading( - w, - "Required Associated Constants", - "required-associated-consts", - None, - "
", - ); - for t in required_consts { - trait_item(w, cx, t, it); - } - w.push_str("
"); - } - if !provided_consts.is_empty() { - write_section_heading( - w, - "Provided Associated Constants", - "provided-associated-consts", - None, - "
", - ); - for t in provided_consts { - trait_item(w, cx, t, it); - } - w.push_str("
"); - } - - if !required_types.is_empty() { - write_section_heading( - w, - "Required Associated Types", - "required-associated-types", - None, - "
", - ); - for t in required_types { - trait_item(w, cx, t, it); - } - w.push_str("
"); - } - if !provided_types.is_empty() { - write_section_heading( - w, - "Provided Associated Types", - "provided-associated-types", - None, - "
", - ); - for t in provided_types { - trait_item(w, cx, t, it); - } - w.push_str("
"); - } - - // Output the documentation for each function individually - if !required_methods.is_empty() || must_implement_one_of_functions.is_some() { - write_section_heading( - w, - "Required Methods", - "required-methods", - None, - "
", - ); - - if let Some(list) = must_implement_one_of_functions.as_deref() { - write_str( - w, - format_args!( - "
At least one of the `{}` methods is required.
", - fmt::from_fn(|f| list.iter().joined("`, `", f)) - ), - ); - } - - for m in required_methods { - trait_item(w, cx, m, it); - } - w.push_str("
"); - } - if !provided_methods.is_empty() { - write_section_heading( - w, - "Provided Methods", - "provided-methods", - None, - "
", - ); - for m in provided_methods { - trait_item(w, cx, m, it); - } - w.push_str("
"); - } - - // If there are methods directly on this trait object, render them here. - write_str( - w, - format_args!( - "{}", - render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All) - ), - ); - - let mut extern_crates = FxIndexSet::default(); - - if !t.is_dyn_compatible(cx.tcx()) { - write_section_heading( - w, - "Dyn Compatibility", - "dyn-compatibility", - None, - format!( - "

This trait is not \ - dyn compatible.

\ -

In older versions of Rust, dyn compatibility was called \"object safety\", \ - so this trait is not object safe.

", - base = crate::clean::utils::DOC_RUST_LANG_ORG_VERSION - ), - ); - } - - if let Some(implementors) = cx.shared.cache.implementors.get(&it.item_id.expect_def_id()) { - // The DefId is for the first Type found with that name. The bool is - // if any Types with the same name but different DefId have been found. - let mut implementor_dups: FxHashMap = FxHashMap::default(); - for implementor in implementors { - if let Some(did) = - implementor.inner_impl().for_.without_borrowed_ref().def_id(&cx.shared.cache) - && !did.is_local() - { - extern_crates.insert(did.krate); - } - match implementor.inner_impl().for_.without_borrowed_ref() { - clean::Type::Path { ref path } if !path.is_assoc_ty() => { - let did = path.def_id(); - let &mut (prev_did, ref mut has_duplicates) = - implementor_dups.entry(path.last()).or_insert((did, false)); - if prev_did != did { - *has_duplicates = true; + for types in [&required_types, &provided_types] { + for t in types { + writeln!( + w, + "{};", + render_assoc_item( + t, + AssocItemLink::Anchor(None), + ItemType::Trait, + cx, + RenderMode::Normal, + ) + )?; } } - _ => {} + // If there are too many associated constants, hide everything after them + // We also do this if the types + consts is large because otherwise we could + // render a bunch of types and _then_ a bunch of consts just because both were + // _just_ under the limit + if !toggle && should_hide_fields(count_types + count_consts) { + toggle = true; + toggle_open( + &mut w, + format_args!( + "{count_consts} associated constant{plural_const} and \ + {count_methods} method{plural_method}", + plural_const = pluralize(count_consts), + plural_method = pluralize(count_methods), + ), + ); + } + if count_types != 0 && (count_consts != 0 || count_methods != 0) { + w.write_str("\n")?; + } + for consts in [&required_consts, &provided_consts] { + for c in consts { + writeln!( + w, + "{};", + render_assoc_item( + c, + AssocItemLink::Anchor(None), + ItemType::Trait, + cx, + RenderMode::Normal, + ) + )?; + } + } + if !toggle && should_hide_fields(count_methods) { + toggle = true; + toggle_open(&mut w, format_args!("{count_methods} methods")); + } + if count_consts != 0 && count_methods != 0 { + w.write_str("\n")?; + } + + if !required_methods.is_empty() { + writeln!(w, " // Required method{}", pluralize(required_methods.len()))?; + } + for (pos, m) in required_methods.iter().enumerate() { + writeln!( + w, + "{};", + render_assoc_item( + m, + AssocItemLink::Anchor(None), + ItemType::Trait, + cx, + RenderMode::Normal, + ) + )?; + + if pos < required_methods.len() - 1 { + w.write_str("")?; + } + } + if !required_methods.is_empty() && !provided_methods.is_empty() { + w.write_str("\n")?; + } + + if !provided_methods.is_empty() { + writeln!(w, " // Provided method{}", pluralize(provided_methods.len()))?; + } + for (pos, m) in provided_methods.iter().enumerate() { + writeln!( + w, + "{} {{ ... }}", + render_assoc_item( + m, + AssocItemLink::Anchor(None), + ItemType::Trait, + cx, + RenderMode::Normal, + ) + )?; + + if pos < provided_methods.len() - 1 { + w.write_str("")?; + } + } + if toggle { + toggle_close(&mut w); + } + w.write_str("}") } + })?; + + // Trait documentation + write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; + + fn trait_item<'a, 'tcx>( + cx: &'a Context<'tcx>, + m: &'a clean::Item, + t: &'a clean::Item, + ) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + let name = m.name.unwrap(); + info!("Documenting {name} on {ty_name:?}", ty_name = t.name); + let item_type = m.type_(); + let id = cx.derive_id(format!("{item_type}.{name}")); + + let content = document_full(m, cx, HeadingOffset::H5).to_string(); + + let toggled = !content.is_empty(); + if toggled { + let method_toggle_class = + if item_type.is_method() { " method-toggle" } else { "" }; + write!(w, "
")?; + } + write!( + w, + "
\ + {}\ +

{}

", + render_rightside(cx, m, RenderMode::Normal), + render_assoc_item( + m, + AssocItemLink::Anchor(Some(&id)), + ItemType::Impl, + cx, + RenderMode::Normal, + ) + )?; + document_item_info(cx, m, Some(t)).render_into(w).unwrap(); + if toggled { + write!(w, "
{content}
")?; + } + Ok(()) + }) } - let (local, mut foreign) = - implementors.iter().partition::, _>(|i| i.is_on_local_type(cx)); - - let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = - local.iter().partition(|i| i.inner_impl().kind.is_auto()); - - synthetic.sort_by_cached_key(|i| ImplString::new(i, cx)); - concrete.sort_by_cached_key(|i| ImplString::new(i, cx)); - foreign.sort_by_cached_key(|i| ImplString::new(i, cx)); - - if !foreign.is_empty() { - write_section_heading(w, "Implementations on Foreign Types", "foreign-impls", None, ""); - - for implementor in foreign { - let provided_methods = implementor.inner_impl().provided_trait_methods(tcx); - let assoc_link = - AssocItemLink::GotoSource(implementor.impl_item.item_id, &provided_methods); - render_impl( - w, - cx, - implementor, - it, - assoc_link, - RenderMode::Normal, + if !required_consts.is_empty() { + write!( + w, + "{}", + write_section_heading( + "Required Associated Constants", + "required-associated-consts", None, - &[], - ImplRenderingParameters { - show_def_docs: false, - show_default_items: false, - show_non_assoc_items: true, - toggle_open_by_default: false, - }, - ); + "
", + ) + )?; + for t in required_consts { + write!(w, "{}", trait_item(cx, t, it))?; } + w.write_str("
")?; } - - write_section_heading( - w, - "Implementors", - "implementors", - None, - "
", - ); - for implementor in concrete { - render_implementor(cx, implementor, it, w, &implementor_dups, &[]); - } - w.push_str("
"); - - if t.is_auto(tcx) { - write_section_heading( + if !provided_consts.is_empty() { + write!( w, - "Auto implementors", - "synthetic-implementors", - None, - "
", - ); - for implementor in synthetic { - render_implementor( - cx, - implementor, - it, + "{}", + write_section_heading( + "Provided Associated Constants", + "provided-associated-consts", + None, + "
", + ) + )?; + for t in provided_consts { + write!(w, "{}", trait_item(cx, t, it))?; + } + w.write_str("
")?; + } + + if !required_types.is_empty() { + write!( + w, + "{}", + write_section_heading( + "Required Associated Types", + "required-associated-types", + None, + "
", + ) + )?; + for t in required_types { + write!(w, "{}", trait_item(cx, t, it))?; + } + w.write_str("
")?; + } + if !provided_types.is_empty() { + write!( + w, + "{}", + write_section_heading( + "Provided Associated Types", + "provided-associated-types", + None, + "
", + ) + )?; + for t in provided_types { + write!(w, "{}", trait_item(cx, t, it))?; + } + w.write_str("
")?; + } + + // Output the documentation for each function individually + if !required_methods.is_empty() || must_implement_one_of_functions.is_some() { + write!( + w, + "{}", + write_section_heading( + "Required Methods", + "required-methods", + None, + "
", + ) + )?; + + if let Some(list) = must_implement_one_of_functions.as_deref() { + write!( w, - &implementor_dups, - &collect_paths_for_type( - implementor.inner_impl().for_.clone(), - &cx.shared.cache, - ), - ); + "
At least one of the `{}` methods is required.
", + fmt::from_fn(|f| list.iter().joined("`, `", f)), + )?; } - w.push_str("
"); - } - } else { - // even without any implementations to write in, we still want the heading and list, so the - // implementors javascript file pulled in below has somewhere to write the impls into - write_section_heading( - w, - "Implementors", - "implementors", - None, - "
", - ); - if t.is_auto(tcx) { - write_section_heading( + for m in required_methods { + write!(w, "{}", trait_item(cx, m, it))?; + } + w.write_str("
")?; + } + if !provided_methods.is_empty() { + write!( w, - "Auto implementors", - "synthetic-implementors", - None, - "
", - ); + "{}", + write_section_heading( + "Provided Methods", + "provided-methods", + None, + "
", + ) + )?; + for m in provided_methods { + write!(w, "{}", trait_item(cx, m, it))?; + } + w.write_str("
")?; } - } - // [RUSTDOCIMPL] trait.impl - // - // Include implementors in crates that depend on the current crate. - // - // This is complicated by the way rustdoc is invoked, which is basically - // the same way rustc is invoked: it gets called, one at a time, for each - // crate. When building the rustdocs for the current crate, rustdoc can - // see crate metadata for its dependencies, but cannot see metadata for its - // dependents. - // - // To make this work, we generate a "hook" at this stage, and our - // dependents can "plug in" to it when they build. For simplicity's sake, - // it's [JSONP]: a JavaScript file with the data we need (and can parse), - // surrounded by a tiny wrapper that the Rust side ignores, but allows the - // JavaScript side to include without having to worry about Same Origin - // Policy. The code for *that* is in `write_shared.rs`. - // - // This is further complicated by `#[doc(inline)]`. We want all copies - // of an inlined trait to reference the same JS file, to address complex - // dependency graphs like this one (lower crates depend on higher crates): - // - // ```text - // -------------------------------------------- - // | crate A: trait Foo | - // -------------------------------------------- - // | | - // -------------------------------- | - // | crate B: impl A::Foo for Bar | | - // -------------------------------- | - // | | - // --------------------------------------------- - // | crate C: #[doc(inline)] use A::Foo as Baz | - // | impl Baz for Quux | - // --------------------------------------------- - // ``` - // - // Basically, we want `C::Baz` and `A::Foo` to show the same set of - // impls, which is easier if they both treat `/trait.impl/A/trait.Foo.js` - // as the Single Source of Truth. - // - // We also want the `impl Baz for Quux` to be written to - // `trait.Foo.js`. However, when we generate plain HTML for `C::Baz`, - // we're going to want to generate plain HTML for `impl Baz for Quux` too, - // because that'll load faster, and it's better for SEO. And we don't want - // the same impl to show up twice on the same page. - // - // To make this work, the trait.impl/A/trait.Foo.js JS file has a structure kinda - // like this: - // - // ```js - // JSONP({ - // "B": {"impl A::Foo for Bar"}, - // "C": {"impl Baz for Quux"}, - // }); - // ``` - // - // First of all, this means we can rebuild a crate, and it'll replace its own - // data if something changes. That is, `rustdoc` is idempotent. The other - // advantage is that we can list the crates that get included in the HTML, - // and ignore them when doing the JavaScript-based part of rendering. - // So C's HTML will have something like this: - // - // ```html - // - // ``` - // - // And, when the JS runs, anything in data-ignore-extern-crates is known - // to already be in the HTML, and will be ignored. - // - // [JSONP]: https://en.wikipedia.org/wiki/JSONP - let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..") - .take(cx.current.len()) - .chain(std::iter::once("trait.impl")) - .collect(); - if let Some(did) = it.item_id.as_def_id() - && let get_extern = { || cx.shared.cache.external_paths.get(&did).map(|s| &s.0) } - && let Some(fqp) = cx.shared.cache.exact_paths.get(&did).or_else(get_extern) - { - js_src_path.extend(fqp[..fqp.len() - 1].iter().copied()); - js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), fqp.last().unwrap())); - } else { - js_src_path.extend(cx.current.iter().copied()); - js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), it.name.unwrap())); - } - let extern_crates = fmt::from_fn(|f| { - if !extern_crates.is_empty() { - f.write_str(" data-ignore-extern-crates=\"")?; - extern_crates.iter().map(|&cnum| tcx.crate_name(cnum)).joined(",", f)?; - f.write_str("\"")?; - } - Ok(()) - }); - write_str( - w, - format_args!( - "", - src = js_src_path.finish() - ), - ); -} - -fn item_trait_alias( - w: &mut impl fmt::Write, - cx: &Context<'_>, - it: &clean::Item, - t: &clean::TraitAlias, -) { - wrap_item(w, |w| { + // If there are methods directly on this trait object, render them here. write!( w, - "{attrs}trait {name}{generics}{where_b} = {bounds};", - attrs = render_attributes_in_pre(it, "", cx), - name = it.name.unwrap(), - generics = t.generics.print(cx), - where_b = print_where_clause(&t.generics, cx, 0, Ending::Newline), - bounds = bounds(&t.bounds, true, cx), - ) - .unwrap(); - }); + "{}", + render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All) + )?; - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); - // Render any items associated directly to this alias, as otherwise they - // won't be visible anywhere in the docs. It would be nice to also show - // associated items from the aliased type (see discussion in #32077), but - // we need #14072 to make sense of the generics. - write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All)) - .unwrap(); + let mut extern_crates = FxIndexSet::default(); + + if !t.is_dyn_compatible(cx.tcx()) { + write!( + w, + "{}", + write_section_heading( + "Dyn Compatibility", + "dyn-compatibility", + None, + format!( + "

This trait is not \ + dyn compatible.

\ +

In older versions of Rust, dyn compatibility was called \"object safety\", \ + so this trait is not object safe.

", + base = crate::clean::utils::DOC_RUST_LANG_ORG_VERSION + ), + ), + )?; + } + + if let Some(implementors) = cx.shared.cache.implementors.get(&it.item_id.expect_def_id()) { + // The DefId is for the first Type found with that name. The bool is + // if any Types with the same name but different DefId have been found. + let mut implementor_dups: FxHashMap = FxHashMap::default(); + for implementor in implementors { + if let Some(did) = + implementor.inner_impl().for_.without_borrowed_ref().def_id(&cx.shared.cache) + && !did.is_local() + { + extern_crates.insert(did.krate); + } + match implementor.inner_impl().for_.without_borrowed_ref() { + clean::Type::Path { ref path } if !path.is_assoc_ty() => { + let did = path.def_id(); + let &mut (prev_did, ref mut has_duplicates) = + implementor_dups.entry(path.last()).or_insert((did, false)); + if prev_did != did { + *has_duplicates = true; + } + } + _ => {} + } + } + + let (local, mut foreign) = + implementors.iter().partition::, _>(|i| i.is_on_local_type(cx)); + + let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = + local.iter().partition(|i| i.inner_impl().kind.is_auto()); + + synthetic.sort_by_cached_key(|i| ImplString::new(i, cx)); + concrete.sort_by_cached_key(|i| ImplString::new(i, cx)); + foreign.sort_by_cached_key(|i| ImplString::new(i, cx)); + + if !foreign.is_empty() { + write!( + w, + "{}", + write_section_heading( + "Implementations on Foreign Types", + "foreign-impls", + None, + "" + ) + )?; + + for implementor in foreign { + let provided_methods = implementor.inner_impl().provided_trait_methods(tcx); + let assoc_link = + AssocItemLink::GotoSource(implementor.impl_item.item_id, &provided_methods); + write!( + w, + "{}", + render_impl( + cx, + implementor, + it, + assoc_link, + RenderMode::Normal, + None, + &[], + ImplRenderingParameters { + show_def_docs: false, + show_default_items: false, + show_non_assoc_items: true, + toggle_open_by_default: false, + }, + ) + )?; + } + } + + write!( + w, + "{}", + write_section_heading( + "Implementors", + "implementors", + None, + "
", + ) + )?; + for implementor in concrete { + write!(w, "{}", render_implementor(cx, implementor, it, &implementor_dups, &[]))?; + } + w.write_str("
")?; + + if t.is_auto(tcx) { + write!( + w, + "{}", + write_section_heading( + "Auto implementors", + "synthetic-implementors", + None, + "
", + ) + )?; + for implementor in synthetic { + write!( + w, + "{}", + render_implementor( + cx, + implementor, + it, + &implementor_dups, + &collect_paths_for_type( + implementor.inner_impl().for_.clone(), + &cx.shared.cache, + ), + ) + )?; + } + w.write_str("
")?; + } + } else { + // even without any implementations to write in, we still want the heading and list, so the + // implementors javascript file pulled in below has somewhere to write the impls into + write!( + w, + "{}", + write_section_heading( + "Implementors", + "implementors", + None, + "
", + ) + )?; + + if t.is_auto(tcx) { + write!( + w, + "{}", + write_section_heading( + "Auto implementors", + "synthetic-implementors", + None, + "
", + ) + )?; + } + } + + // [RUSTDOCIMPL] trait.impl + // + // Include implementors in crates that depend on the current crate. + // + // This is complicated by the way rustdoc is invoked, which is basically + // the same way rustc is invoked: it gets called, one at a time, for each + // crate. When building the rustdocs for the current crate, rustdoc can + // see crate metadata for its dependencies, but cannot see metadata for its + // dependents. + // + // To make this work, we generate a "hook" at this stage, and our + // dependents can "plug in" to it when they build. For simplicity's sake, + // it's [JSONP]: a JavaScript file with the data we need (and can parse), + // surrounded by a tiny wrapper that the Rust side ignores, but allows the + // JavaScript side to include without having to worry about Same Origin + // Policy. The code for *that* is in `write_shared.rs`. + // + // This is further complicated by `#[doc(inline)]`. We want all copies + // of an inlined trait to reference the same JS file, to address complex + // dependency graphs like this one (lower crates depend on higher crates): + // + // ```text + // -------------------------------------------- + // | crate A: trait Foo | + // -------------------------------------------- + // | | + // -------------------------------- | + // | crate B: impl A::Foo for Bar | | + // -------------------------------- | + // | | + // --------------------------------------------- + // | crate C: #[doc(inline)] use A::Foo as Baz | + // | impl Baz for Quux | + // --------------------------------------------- + // ``` + // + // Basically, we want `C::Baz` and `A::Foo` to show the same set of + // impls, which is easier if they both treat `/trait.impl/A/trait.Foo.js` + // as the Single Source of Truth. + // + // We also want the `impl Baz for Quux` to be written to + // `trait.Foo.js`. However, when we generate plain HTML for `C::Baz`, + // we're going to want to generate plain HTML for `impl Baz for Quux` too, + // because that'll load faster, and it's better for SEO. And we don't want + // the same impl to show up twice on the same page. + // + // To make this work, the trait.impl/A/trait.Foo.js JS file has a structure kinda + // like this: + // + // ```js + // JSONP({ + // "B": {"impl A::Foo for Bar"}, + // "C": {"impl Baz for Quux"}, + // }); + // ``` + // + // First of all, this means we can rebuild a crate, and it'll replace its own + // data if something changes. That is, `rustdoc` is idempotent. The other + // advantage is that we can list the crates that get included in the HTML, + // and ignore them when doing the JavaScript-based part of rendering. + // So C's HTML will have something like this: + // + // ```html + // + // ``` + // + // And, when the JS runs, anything in data-ignore-extern-crates is known + // to already be in the HTML, and will be ignored. + // + // [JSONP]: https://en.wikipedia.org/wiki/JSONP + let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..") + .take(cx.current.len()) + .chain(std::iter::once("trait.impl")) + .collect(); + if let Some(did) = it.item_id.as_def_id() + && let get_extern = { || cx.shared.cache.external_paths.get(&did).map(|s| &s.0) } + && let Some(fqp) = cx.shared.cache.exact_paths.get(&did).or_else(get_extern) + { + js_src_path.extend(fqp[..fqp.len() - 1].iter().copied()); + js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), fqp.last().unwrap())); + } else { + js_src_path.extend(cx.current.iter().copied()); + js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), it.name.unwrap())); + } + let extern_crates = fmt::from_fn(|f| { + if !extern_crates.is_empty() { + f.write_str(" data-ignore-extern-crates=\"")?; + extern_crates.iter().map(|&cnum| tcx.crate_name(cnum)).joined(",", f)?; + f.write_str("\"")?; + } + Ok(()) + }); + write!( + w, + "", + src = js_src_path.finish() + ) + }) } -fn item_type_alias(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) { - wrap_item(w, |w| { - write_str( +fn item_trait_alias<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + t: &'a clean::TraitAlias, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + wrap_item(w, |w| { + write!( + w, + "{attrs}trait {name}{generics}{where_b} = {bounds};", + attrs = render_attributes_in_pre(it, "", cx), + name = it.name.unwrap(), + generics = t.generics.print(cx), + where_b = print_where_clause(&t.generics, cx, 0, Ending::Newline).maybe_display(), + bounds = bounds(&t.bounds, true, cx), + ) + })?; + + write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; + // Render any items associated directly to this alias, as otherwise they + // won't be visible anywhere in the docs. It would be nice to also show + // associated items from the aliased type (see discussion in #32077), but + // we need #14072 to make sense of the generics. + write!( w, - format_args!( + "{}", + render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All) + ) + }) +} + +fn item_type_alias<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + t: &'a clean::TypeAlias, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + wrap_item(w, |w| { + write!( + w, "{attrs}{vis}type {name}{generics}{where_clause} = {type_};", attrs = render_attributes_in_pre(it, "", cx), vis = visibility_print_with_space(it, cx), name = it.name.unwrap(), generics = t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline), + where_clause = + print_where_clause(&t.generics, cx, 0, Ending::Newline).maybe_display(), type_ = t.type_.print(cx), - ), - ); - }); + ) + })?; - write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); + write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; - if let Some(inner_type) = &t.inner_type { - write_section_heading(w, "Aliased Type", "aliased-type", None, ""); + if let Some(inner_type) = &t.inner_type { + write!(w, "{}", write_section_heading("Aliased Type", "aliased-type", None, ""),)?; - match inner_type { - clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive } => { - let variants_iter = || variants.iter().filter(|i| !i.is_stripped()); - let ty = cx.tcx().type_of(it.def_id().unwrap()).instantiate_identity(); - let enum_def_id = ty.ty_adt_def().unwrap().did(); + match inner_type { + clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive } => { + let variants_iter = || variants.iter().filter(|i| !i.is_stripped()); + let ty = cx.tcx().type_of(it.def_id().unwrap()).instantiate_identity(); + let enum_def_id = ty.ty_adt_def().unwrap().did(); - wrap_item(w, |w| { - let variants_len = variants.len(); - let variants_count = variants_iter().count(); - let has_stripped_entries = variants_len != variants_count; + wrap_item(w, |w| { + let variants_len = variants.len(); + let variants_count = variants_iter().count(); + let has_stripped_entries = variants_len != variants_count; - write_str(w, format_args!("enum {}{}", it.name.unwrap(), t.generics.print(cx))); - render_enum_fields( - w, - cx, - Some(&t.generics), - variants, - variants_count, - has_stripped_entries, - *is_non_exhaustive, - enum_def_id, - ) - }); - item_variants(w, cx, it, variants, enum_def_id); - } - clean::TypeAliasInnerType::Union { fields } => { - wrap_item(w, |w| { - let fields_count = fields.iter().filter(|i| !i.is_stripped()).count(); - let has_stripped_fields = fields.len() != fields_count; + write!( + w, + "enum {}{}{}", + it.name.unwrap(), + t.generics.print(cx), + render_enum_fields( + cx, + Some(&t.generics), + variants, + variants_count, + has_stripped_entries, + *is_non_exhaustive, + enum_def_id, + ) + ) + })?; + write!(w, "{}", item_variants(cx, it, variants, enum_def_id))?; + } + clean::TypeAliasInnerType::Union { fields } => { + wrap_item(w, |w| { + let fields_count = fields.iter().filter(|i| !i.is_stripped()).count(); + let has_stripped_fields = fields.len() != fields_count; - write_str( - w, - format_args!("union {}{}", it.name.unwrap(), t.generics.print(cx)), - ); - render_struct_fields( - w, - Some(&t.generics), - None, - fields, - "", - true, - has_stripped_fields, - cx, - ); - }); - item_fields(w, cx, it, fields, None); - } - clean::TypeAliasInnerType::Struct { ctor_kind, fields } => { - wrap_item(w, |w| { - let fields_count = fields.iter().filter(|i| !i.is_stripped()).count(); - let has_stripped_fields = fields.len() != fields_count; + write!( + w, + "union {}{}{}", + it.name.unwrap(), + t.generics.print(cx), + render_struct_fields( + Some(&t.generics), + None, + fields, + "", + true, + has_stripped_fields, + cx, + ), + ) + })?; + write!(w, "{}", item_fields(cx, it, fields, None))?; + } + clean::TypeAliasInnerType::Struct { ctor_kind, fields } => { + wrap_item(w, |w| { + let fields_count = fields.iter().filter(|i| !i.is_stripped()).count(); + let has_stripped_fields = fields.len() != fields_count; - write_str( - w, - format_args!("struct {}{}", it.name.unwrap(), t.generics.print(cx)), - ); - render_struct_fields( - w, - Some(&t.generics), - *ctor_kind, - fields, - "", - true, - has_stripped_fields, - cx, - ); - }); - item_fields(w, cx, it, fields, None); + write!( + w, + "struct {}{}{}", + it.name.unwrap(), + t.generics.print(cx), + render_struct_fields( + Some(&t.generics), + *ctor_kind, + fields, + "", + true, + has_stripped_fields, + cx, + ), + ) + })?; + write!(w, "{}", item_fields(cx, it, fields, None))?; + } } } - } - let def_id = it.item_id.expect_def_id(); - // Render any items associated directly to this alias, as otherwise they - // won't be visible anywhere in the docs. It would be nice to also show - // associated items from the aliased type (see discussion in #32077), but - // we need #14072 to make sense of the generics. - write_str(w, format_args!("{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))); - write_str(w, format_args!("{}", document_type_layout(cx, def_id))); - - // [RUSTDOCIMPL] type.impl - // - // Include type definitions from the alias target type. - // - // Earlier versions of this code worked by having `render_assoc_items` - // include this data directly. That generates *O*`(types*impls)` of HTML - // text, and some real crates have a lot of types and impls. - // - // To create the same UX without generating half a gigabyte of HTML for a - // crate that only contains 20 megabytes of actual documentation[^115718], - // rustdoc stashes these type-alias-inlined docs in a [JSONP] - // "database-lite". The file itself is generated in `write_shared.rs`, - // and hooks into functions provided by `main.js`. - // - // The format of `trait.impl` and `type.impl` JS files are superficially - // similar. Each line, except the JSONP wrapper itself, belongs to a crate, - // and they are otherwise separate (rustdoc should be idempotent). The - // "meat" of the file is HTML strings, so the frontend code is very simple. - // Links are relative to the doc root, though, so the frontend needs to fix - // that up, and inlined docs can reuse these files. - // - // However, there are a few differences, caused by the sophisticated - // features that type aliases have. Consider this crate graph: - // - // ```text - // --------------------------------- - // | crate A: struct Foo | - // | type Bar = Foo | - // | impl X for Foo | - // | impl Y for Foo | - // --------------------------------- - // | - // ---------------------------------- - // | crate B: type Baz = A::Foo | - // | type Xyy = A::Foo | - // | impl Z for Xyy | - // ---------------------------------- - // ``` - // - // The type.impl/A/struct.Foo.js JS file has a structure kinda like this: - // - // ```js - // JSONP({ - // "A": [["impl Y for Foo", "Y", "A::Bar"]], - // "B": [["impl X for Foo", "X", "B::Baz", "B::Xyy"], ["impl Z for Xyy", "Z", "B::Baz"]], - // }); - // ``` - // - // When the type.impl file is loaded, only the current crate's docs are - // actually used. The main reason to bundle them together is that there's - // enough duplication in them for DEFLATE to remove the redundancy. - // - // The contents of a crate are a list of impl blocks, themselves - // represented as lists. The first item in the sublist is the HTML block, - // the second item is the name of the trait (which goes in the sidebar), - // and all others are the names of type aliases that successfully match. - // - // This way: - // - // - There's no need to generate these files for types that have no aliases - // in the current crate. If a dependent crate makes a type alias, it'll - // take care of generating its own docs. - // - There's no need to reimplement parts of the type checker in - // JavaScript. The Rust backend does the checking, and includes its - // results in the file. - // - Docs defined directly on the type alias are dropped directly in the - // HTML by `render_assoc_items`, and are accessible without JavaScript. - // The JSONP file will not list impl items that are known to be part - // of the main HTML file already. - // - // [JSONP]: https://en.wikipedia.org/wiki/JSONP - // [^115718]: https://github.com/rust-lang/rust/issues/115718 - let cache = &cx.shared.cache; - if let Some(target_did) = t.type_.def_id(cache) && - let get_extern = { || cache.external_paths.get(&target_did) } && - let Some(&(ref target_fqp, target_type)) = cache.paths.get(&target_did).or_else(get_extern) && - target_type.is_adt() && // primitives cannot be inlined - let Some(self_did) = it.item_id.as_def_id() && - let get_local = { || cache.paths.get(&self_did).map(|(p, _)| p) } && - let Some(self_fqp) = cache.exact_paths.get(&self_did).or_else(get_local) - { - let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..") - .take(cx.current.len()) - .chain(std::iter::once("type.impl")) - .collect(); - js_src_path.extend(target_fqp[..target_fqp.len() - 1].iter().copied()); - js_src_path.push_fmt(format_args!("{target_type}.{}.js", target_fqp.last().unwrap())); - let self_path = fmt::from_fn(|f| self_fqp.iter().joined("::", f)); - write_str( + let def_id = it.item_id.expect_def_id(); + // Render any items associated directly to this alias, as otherwise they + // won't be visible anywhere in the docs. It would be nice to also show + // associated items from the aliased type (see discussion in #32077), but + // we need #14072 to make sense of the generics. + write!( w, - format_args!( + "{}{}", + render_assoc_items(cx, it, def_id, AssocItemRender::All), + document_type_layout(cx, def_id) + )?; + + // [RUSTDOCIMPL] type.impl + // + // Include type definitions from the alias target type. + // + // Earlier versions of this code worked by having `render_assoc_items` + // include this data directly. That generates *O*`(types*impls)` of HTML + // text, and some real crates have a lot of types and impls. + // + // To create the same UX without generating half a gigabyte of HTML for a + // crate that only contains 20 megabytes of actual documentation[^115718], + // rustdoc stashes these type-alias-inlined docs in a [JSONP] + // "database-lite". The file itself is generated in `write_shared.rs`, + // and hooks into functions provided by `main.js`. + // + // The format of `trait.impl` and `type.impl` JS files are superficially + // similar. Each line, except the JSONP wrapper itself, belongs to a crate, + // and they are otherwise separate (rustdoc should be idempotent). The + // "meat" of the file is HTML strings, so the frontend code is very simple. + // Links are relative to the doc root, though, so the frontend needs to fix + // that up, and inlined docs can reuse these files. + // + // However, there are a few differences, caused by the sophisticated + // features that type aliases have. Consider this crate graph: + // + // ```text + // --------------------------------- + // | crate A: struct Foo | + // | type Bar = Foo | + // | impl X for Foo | + // | impl Y for Foo | + // --------------------------------- + // | + // ---------------------------------- + // | crate B: type Baz = A::Foo | + // | type Xyy = A::Foo | + // | impl Z for Xyy | + // ---------------------------------- + // ``` + // + // The type.impl/A/struct.Foo.js JS file has a structure kinda like this: + // + // ```js + // JSONP({ + // "A": [["impl Y for Foo", "Y", "A::Bar"]], + // "B": [["impl X for Foo", "X", "B::Baz", "B::Xyy"], ["impl Z for Xyy", "Z", "B::Baz"]], + // }); + // ``` + // + // When the type.impl file is loaded, only the current crate's docs are + // actually used. The main reason to bundle them together is that there's + // enough duplication in them for DEFLATE to remove the redundancy. + // + // The contents of a crate are a list of impl blocks, themselves + // represented as lists. The first item in the sublist is the HTML block, + // the second item is the name of the trait (which goes in the sidebar), + // and all others are the names of type aliases that successfully match. + // + // This way: + // + // - There's no need to generate these files for types that have no aliases + // in the current crate. If a dependent crate makes a type alias, it'll + // take care of generating its own docs. + // - There's no need to reimplement parts of the type checker in + // JavaScript. The Rust backend does the checking, and includes its + // results in the file. + // - Docs defined directly on the type alias are dropped directly in the + // HTML by `render_assoc_items`, and are accessible without JavaScript. + // The JSONP file will not list impl items that are known to be part + // of the main HTML file already. + // + // [JSONP]: https://en.wikipedia.org/wiki/JSONP + // [^115718]: https://github.com/rust-lang/rust/issues/115718 + let cache = &cx.shared.cache; + if let Some(target_did) = t.type_.def_id(cache) + && let get_extern = { || cache.external_paths.get(&target_did) } + && let Some(&(ref target_fqp, target_type)) = + cache.paths.get(&target_did).or_else(get_extern) + && target_type.is_adt() // primitives cannot be inlined + && let Some(self_did) = it.item_id.as_def_id() + && let get_local = { || cache.paths.get(&self_did).map(|(p, _)| p) } + && let Some(self_fqp) = cache.exact_paths.get(&self_did).or_else(get_local) + { + let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..") + .take(cx.current.len()) + .chain(std::iter::once("type.impl")) + .collect(); + js_src_path.extend(target_fqp[..target_fqp.len() - 1].iter().copied()); + js_src_path.push_fmt(format_args!("{target_type}.{}.js", target_fqp.last().unwrap())); + let self_path = fmt::from_fn(|f| self_fqp.iter().joined("::", f)); + write!( + w, "", - src = js_src_path.finish() - ), - ); - } + src = js_src_path.finish(), + )?; + } + Ok(()) + }) } -fn item_union(w: &mut String, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) { +fn item_union<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + s: &'a clean::Union, +) -> impl fmt::Display + 'a + Captures<'tcx> { item_template!( #[template(path = "item_union.html")] struct ItemUnion<'a, 'cx> { @@ -1464,7 +1560,10 @@ fn item_union(w: &mut String, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni } } - ItemUnion { cx, it, s }.render_into(w).unwrap(); + fmt::from_fn(|w| { + ItemUnion { cx, it, s }.render_into(w).unwrap(); + Ok(()) + }) } fn print_tuple_struct_fields<'a, 'cx: 'a>( @@ -1492,40 +1591,46 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>( }) } -fn item_enum(w: &mut String, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) { - let count_variants = e.variants().count(); - wrap_item(w, |w| { - render_attributes_in_code(w, it, cx); - write_str( - w, - format_args!( - "{}enum {}{}", +fn item_enum<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + e: &'a clean::Enum, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + let count_variants = e.variants().count(); + wrap_item(w, |w| { + render_attributes_in_code(w, it, cx); + write!( + w, + "{}enum {}{}{}", visibility_print_with_space(it, cx), it.name.unwrap(), e.generics.print(cx), - ), - ); + render_enum_fields( + cx, + Some(&e.generics), + &e.variants, + count_variants, + e.has_stripped_entries(), + it.is_non_exhaustive(), + it.def_id().unwrap(), + ), + ) + })?; - render_enum_fields( + write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; + + if count_variants != 0 { + write!(w, "{}", item_variants(cx, it, &e.variants, it.def_id().unwrap()))?; + } + let def_id = it.item_id.expect_def_id(); + write!( w, - cx, - Some(&e.generics), - &e.variants, - count_variants, - e.has_stripped_entries(), - it.is_non_exhaustive(), - it.def_id().unwrap(), - ); - }); - - write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); - - if count_variants != 0 { - item_variants(w, cx, it, &e.variants, it.def_id().unwrap()); - } - let def_id = it.item_id.expect_def_id(); - write_str(w, format_args!("{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))); - write_str(w, format_args!("{}", document_type_layout(cx, def_id))); + "{}{}", + render_assoc_items(cx, it, def_id, AssocItemRender::All), + document_type_layout(cx, def_id) + ) + }) } /// It'll return false if any variant is not a C-like variant. Otherwise it'll return true if at @@ -1553,456 +1658,508 @@ fn should_show_enum_discriminant( repr.c() || repr.int.is_some() } -fn display_c_like_variant( - w: &mut String, - cx: &Context<'_>, - item: &clean::Item, - variant: &clean::Variant, +fn display_c_like_variant<'a, 'tcx>( + cx: &'a Context<'tcx>, + item: &'a clean::Item, + variant: &'a clean::Variant, index: VariantIdx, should_show_enum_discriminant: bool, enum_def_id: DefId, -) { - let name = item.name.unwrap(); - if let Some(ref value) = variant.discriminant { - write_str(w, format_args!("{} = {}", name.as_str(), value.value(cx.tcx(), true))); - } else if should_show_enum_discriminant { - let adt_def = cx.tcx().adt_def(enum_def_id); - let discr = adt_def.discriminant_for_variant(cx.tcx(), index); - if discr.ty.is_signed() { - write_str(w, format_args!("{} = {}", name.as_str(), discr.val as i128)); +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + let name = item.name.unwrap(); + if let Some(ref value) = variant.discriminant { + write!(w, "{} = {}", name.as_str(), value.value(cx.tcx(), true))?; + } else if should_show_enum_discriminant { + let adt_def = cx.tcx().adt_def(enum_def_id); + let discr = adt_def.discriminant_for_variant(cx.tcx(), index); + if discr.ty.is_signed() { + write!(w, "{} = {}", name.as_str(), discr.val as i128)?; + } else { + write!(w, "{} = {}", name.as_str(), discr.val)?; + } } else { - write_str(w, format_args!("{} = {}", name.as_str(), discr.val)); + write!(w, "{name}")?; } - } else { - w.push_str(name.as_str()); - } + Ok(()) + }) } -fn render_enum_fields( - mut w: &mut String, - cx: &Context<'_>, - g: Option<&clean::Generics>, - variants: &IndexVec, +fn render_enum_fields<'a, 'tcx>( + cx: &'a Context<'tcx>, + g: Option<&'a clean::Generics>, + variants: &'a IndexVec, count_variants: usize, has_stripped_entries: bool, is_non_exhaustive: bool, enum_def_id: DefId, -) { - let should_show_enum_discriminant = should_show_enum_discriminant(cx, enum_def_id, variants); - if !g.is_some_and(|g| print_where_clause_and_check(w, g, cx)) { - // If there wasn't a `where` clause, we add a whitespace. - w.push_str(" "); - } - - let variants_stripped = has_stripped_entries; - if count_variants == 0 && !variants_stripped { - w.push_str("{}"); - } else { - w.push_str("{\n"); - let toggle = should_hide_fields(count_variants); - if toggle { - toggle_open(&mut w, format_args!("{count_variants} variants")); +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + let should_show_enum_discriminant = + should_show_enum_discriminant(cx, enum_def_id, variants); + if let Some(generics) = g + && let Some(where_clause) = print_where_clause(generics, cx, 0, Ending::Newline) + { + write!(w, "{where_clause}")?; + } else { + // If there wasn't a `where` clause, we add a whitespace. + w.write_char(' ')?; } - const TAB: &str = " "; - for (index, v) in variants.iter_enumerated() { - if v.is_stripped() { + + let variants_stripped = has_stripped_entries; + if count_variants == 0 && !variants_stripped { + w.write_str("{}") + } else { + w.write_str("{\n")?; + let toggle = should_hide_fields(count_variants); + if toggle { + toggle_open(&mut *w, format_args!("{count_variants} variants")); + } + const TAB: &str = " "; + for (index, v) in variants.iter_enumerated() { + if v.is_stripped() { + continue; + } + w.write_str(TAB)?; + match v.kind { + clean::VariantItem(ref var) => match var.kind { + clean::VariantKind::CLike => { + write!( + w, + "{}", + display_c_like_variant( + cx, + v, + var, + index, + should_show_enum_discriminant, + enum_def_id, + ) + )?; + } + clean::VariantKind::Tuple(ref s) => { + write!(w, "{}({})", v.name.unwrap(), print_tuple_struct_fields(cx, s))?; + } + clean::VariantKind::Struct(ref s) => { + write!( + w, + "{}", + render_struct(v, None, None, &s.fields, TAB, false, cx) + )?; + } + }, + _ => unreachable!(), + } + w.write_str(",\n")?; + } + + if variants_stripped && !is_non_exhaustive { + w.write_str(" // some variants omitted\n")?; + } + if toggle { + toggle_close(&mut *w); + } + w.write_str("}") + } + }) +} + +fn item_variants<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + variants: &'a IndexVec, + enum_def_id: DefId, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + let tcx = cx.tcx(); + write!( + w, + "{}", + write_section_heading( + &format!("Variants{}", document_non_exhaustive_header(it)), + "variants", + Some("variants"), + format!("{}
", document_non_exhaustive(it)), + ), + )?; + + let should_show_enum_discriminant = + should_show_enum_discriminant(cx, enum_def_id, variants); + for (index, variant) in variants.iter_enumerated() { + if variant.is_stripped() { continue; } - w.push_str(TAB); - match v.kind { - clean::VariantItem(ref var) => match var.kind { - clean::VariantKind::CLike => display_c_like_variant( - w, + let id = cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.unwrap())); + write!( + w, + "
\ + §\ + {}\ +

", + render_stability_since_raw_with_extra( + variant.stable_since(tcx), + variant.const_stability(tcx), + " rightside", + ) + .maybe_display() + )?; + if let clean::VariantItem(ref var) = variant.kind + && let clean::VariantKind::CLike = var.kind + { + write!( + w, + "{}", + display_c_like_variant( cx, - v, + variant, var, index, should_show_enum_discriminant, enum_def_id, - ), - clean::VariantKind::Tuple(ref s) => { - write_str( - w, - format_args!( - "{}({})", - v.name.unwrap(), - print_tuple_struct_fields(cx, s) - ), - ); + ) + )?; + } else { + w.write_str(variant.name.unwrap().as_str())?; + } + + let clean::VariantItem(variant_data) = &variant.kind else { unreachable!() }; + + if let clean::VariantKind::Tuple(ref s) = variant_data.kind { + write!(w, "({})", print_tuple_struct_fields(cx, s))?; + } + w.write_str("

")?; + + write!(w, "{}", document(cx, variant, Some(it), HeadingOffset::H4))?; + + let heading_and_fields = match &variant_data.kind { + clean::VariantKind::Struct(s) => { + // If there is no field to display, no need to add the heading. + if s.fields.iter().any(|f| !f.is_doc_hidden()) { + Some(("Fields", &s.fields)) + } else { + None } - clean::VariantKind::Struct(ref s) => { - render_struct(w, v, None, None, &s.fields, TAB, false, cx); + } + clean::VariantKind::Tuple(fields) => { + // Documentation on tuple variant fields is rare, so to reduce noise we only emit + // the section if at least one field is documented. + if fields.iter().any(|f| !f.doc_value().is_empty()) { + Some(("Tuple Fields", fields)) + } else { + None } - }, - _ => unreachable!(), - } - w.push_str(",\n"); - } - - if variants_stripped && !is_non_exhaustive { - w.push_str(" // some variants omitted\n"); - } - if toggle { - toggle_close(&mut w); - } - w.push_str("}"); - } -} - -fn item_variants( - w: &mut String, - cx: &Context<'_>, - it: &clean::Item, - variants: &IndexVec, - enum_def_id: DefId, -) { - let tcx = cx.tcx(); - write_section_heading( - w, - &format!("Variants{}", document_non_exhaustive_header(it)), - "variants", - Some("variants"), - format!("{}
", document_non_exhaustive(it)), - ); - - let should_show_enum_discriminant = should_show_enum_discriminant(cx, enum_def_id, variants); - for (index, variant) in variants.iter_enumerated() { - if variant.is_stripped() { - continue; - } - let id = cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.unwrap())); - write_str( - w, - format_args!( - "
\ - §" - ), - ); - render_stability_since_raw_with_extra( - w, - variant.stable_since(tcx), - variant.const_stability(tcx), - " rightside", - ); - w.push_str("

"); - if let clean::VariantItem(ref var) = variant.kind - && let clean::VariantKind::CLike = var.kind - { - display_c_like_variant( - w, - cx, - variant, - var, - index, - should_show_enum_discriminant, - enum_def_id, - ); - } else { - w.push_str(variant.name.unwrap().as_str()); - } - - let clean::VariantItem(variant_data) = &variant.kind else { unreachable!() }; - - if let clean::VariantKind::Tuple(ref s) = variant_data.kind { - write_str(w, format_args!("({})", print_tuple_struct_fields(cx, s))); - } - w.push_str("

"); - - write_str(w, format_args!("{}", document(cx, variant, Some(it), HeadingOffset::H4))); - - let heading_and_fields = match &variant_data.kind { - clean::VariantKind::Struct(s) => { - // If there is no field to display, no need to add the heading. - if s.fields.iter().any(|f| !f.is_doc_hidden()) { - Some(("Fields", &s.fields)) - } else { - None } - } - clean::VariantKind::Tuple(fields) => { - // Documentation on tuple variant fields is rare, so to reduce noise we only emit - // the section if at least one field is documented. - if fields.iter().any(|f| !f.doc_value().is_empty()) { - Some(("Tuple Fields", fields)) - } else { - None - } - } - clean::VariantKind::CLike => None, - }; + clean::VariantKind::CLike => None, + }; - if let Some((heading, fields)) = heading_and_fields { - let variant_id = - cx.derive_id(format!("{}.{}.fields", ItemType::Variant, variant.name.unwrap())); - write_str( - w, - format_args!( + if let Some((heading, fields)) = heading_and_fields { + let variant_id = + cx.derive_id(format!("{}.{}.fields", ItemType::Variant, variant.name.unwrap())); + write!( + w, "
\

{heading}

\ {}", document_non_exhaustive(variant) - ), - ); - for field in fields { - match field.kind { - clean::StrippedItem(box clean::StructFieldItem(_)) => {} - clean::StructFieldItem(ref ty) => { - let id = cx.derive_id(format!( - "variant.{}.field.{}", - variant.name.unwrap(), - field.name.unwrap() - )); - write_str( - w, - format_args!( + )?; + for field in fields { + match field.kind { + clean::StrippedItem(box clean::StructFieldItem(_)) => {} + clean::StructFieldItem(ref ty) => { + let id = cx.derive_id(format!( + "variant.{}.field.{}", + variant.name.unwrap(), + field.name.unwrap() + )); + write!( + w, "
\ \ §\ {f}: {t}\ - ", + \ + {doc}\ +
", f = field.name.unwrap(), t = ty.print(cx), - ), - ); - write_str( - w, - format_args!( - "{}
", - document(cx, field, Some(variant), HeadingOffset::H5), - ), - ); + doc = document(cx, field, Some(variant), HeadingOffset::H5), + )?; + } + _ => unreachable!(), } - _ => unreachable!(), } + w.write_str("
")?; } - w.push_str("
"); } - } - write_str(w, format_args!("
")); + w.write_str("
") + }) } -fn item_macro(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) { - wrap_item(w, |w| { - // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. - if !t.macro_rules { - write_str(w, format_args!("{}", visibility_print_with_space(it, cx))); - } - write_str(w, format_args!("{}", Escape(&t.source))); - }); - write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); +fn item_macro<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + t: &'a clean::Macro, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + wrap_item(w, |w| { + // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. + if !t.macro_rules { + write!(w, "{}", visibility_print_with_space(it, cx))?; + } + write!(w, "{}", Escape(&t.source)) + })?; + write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) + }) } -fn item_proc_macro( - w: &mut impl fmt::Write, - cx: &Context<'_>, - it: &clean::Item, - m: &clean::ProcMacro, -) { - wrap_item(w, |buffer| { - let name = it.name.expect("proc-macros always have names"); - match m.kind { - MacroKind::Bang => { - write!(buffer, "{name}!() {{ /* proc-macro */ }}") - .unwrap(); - } - MacroKind::Attr => { - write!(buffer, "#[{name}]").unwrap(); - } - MacroKind::Derive => { - write!(buffer, "#[derive({name})]").unwrap(); - if !m.helpers.is_empty() { - buffer - .write_str( +fn item_proc_macro<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + m: &'a clean::ProcMacro, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + wrap_item(w, |w| { + let name = it.name.expect("proc-macros always have names"); + match m.kind { + MacroKind::Bang => { + write!(w, "{name}!() {{ /* proc-macro */ }}")?; + } + MacroKind::Attr => { + write!(w, "#[{name}]")?; + } + MacroKind::Derive => { + write!(w, "#[derive({name})]")?; + if !m.helpers.is_empty() { + w.write_str( "\n{\n \ - // Attributes available to this derive:\n", - ) - .unwrap(); - for attr in &m.helpers { - writeln!(buffer, " #[{attr}]").unwrap(); + // Attributes available to this derive:\n", + )?; + for attr in &m.helpers { + writeln!(w, " #[{attr}]")?; + } + w.write_str("}\n")?; } - buffer.write_str("}\n").unwrap(); } } + Ok(()) + })?; + write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) + }) +} + +fn item_primitive<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + let def_id = it.item_id.expect_def_id(); + write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; + if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) { + write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))?; + } else { + // We handle the "reference" primitive type on its own because we only want to list + // implementations on generic types. + let (concrete, synthetic, blanket_impl) = + get_filtered_impls_for_reference(&cx.shared, it); + + render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl); } - }); - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); + Ok(()) + }) } -fn item_primitive(w: &mut impl fmt::Write, cx: &Context<'_>, it: &clean::Item) { - let def_id = it.item_id.expect_def_id(); - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); - if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) { - write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)).unwrap(); - } else { - // We handle the "reference" primitive type on its own because we only want to list - // implementations on generic types. - let (concrete, synthetic, blanket_impl) = get_filtered_impls_for_reference(&cx.shared, it); +fn item_constant<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + generics: &'a clean::Generics, + ty: &'a clean::Type, + c: &'a clean::ConstantKind, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + wrap_item(w, |w| { + let tcx = cx.tcx(); + render_attributes_in_code(w, it, cx); - render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl); - } -} - -fn item_constant( - w: &mut String, - cx: &Context<'_>, - it: &clean::Item, - generics: &clean::Generics, - ty: &clean::Type, - c: &clean::ConstantKind, -) { - wrap_item(w, |w| { - let tcx = cx.tcx(); - render_attributes_in_code(w, it, cx); - - write_str( - w, - format_args!( + write!( + w, "{vis}const {name}{generics}: {typ}{where_clause}", vis = visibility_print_with_space(it, cx), name = it.name.unwrap(), generics = generics.print(cx), typ = ty.print(cx), - where_clause = print_where_clause(generics, cx, 0, Ending::NoNewline) - ), - ); + where_clause = + print_where_clause(generics, cx, 0, Ending::NoNewline).maybe_display(), + )?; - // FIXME: The code below now prints - // ` = _; // 100i32` - // if the expression is - // `50 + 50` - // which looks just wrong. - // Should we print - // ` = 100i32;` - // instead? + // FIXME: The code below now prints + // ` = _; // 100i32` + // if the expression is + // `50 + 50` + // which looks just wrong. + // Should we print + // ` = 100i32;` + // instead? - let value = c.value(tcx); - let is_literal = c.is_literal(tcx); - let expr = c.expr(tcx); - if value.is_some() || is_literal { - write_str(w, format_args!(" = {expr};", expr = Escape(&expr))); - } else { - w.push_str(";"); - } + let value = c.value(tcx); + let is_literal = c.is_literal(tcx); + let expr = c.expr(tcx); + if value.is_some() || is_literal { + write!(w, " = {expr};", expr = Escape(&expr))?; + } else { + w.write_str(";")?; + } - if !is_literal { - if let Some(value) = &value { - let value_lowercase = value.to_lowercase(); - let expr_lowercase = expr.to_lowercase(); + if !is_literal { + if let Some(value) = &value { + let value_lowercase = value.to_lowercase(); + let expr_lowercase = expr.to_lowercase(); - if value_lowercase != expr_lowercase - && value_lowercase.trim_end_matches("i32") != expr_lowercase - { - write_str(w, format_args!(" // {value}", value = Escape(value))); + if value_lowercase != expr_lowercase + && value_lowercase.trim_end_matches("i32") != expr_lowercase + { + write!(w, " // {value}", value = Escape(value))?; + } } } - } - }); + Ok(()) + })?; - write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); + write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) + }) } -fn item_struct(w: &mut String, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) { - wrap_item(w, |w| { - render_attributes_in_code(w, it, cx); - render_struct(w, it, Some(&s.generics), s.ctor_kind, &s.fields, "", true, cx); - }); +fn item_struct<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + s: &'a clean::Struct, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + wrap_item(w, |w| { + render_attributes_in_code(w, it, cx); + write!( + w, + "{}", + render_struct(it, Some(&s.generics), s.ctor_kind, &s.fields, "", true, cx) + ) + })?; - write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); + let def_id = it.item_id.expect_def_id(); - item_fields(w, cx, it, &s.fields, s.ctor_kind); - - let def_id = it.item_id.expect_def_id(); - write_str(w, format_args!("{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))); - write_str(w, format_args!("{}", document_type_layout(cx, def_id))); + write!( + w, + "{}{}{}{}", + document(cx, it, None, HeadingOffset::H2), + item_fields(cx, it, &s.fields, s.ctor_kind), + render_assoc_items(cx, it, def_id, AssocItemRender::All), + document_type_layout(cx, def_id), + ) + }) } -fn item_fields( - w: &mut String, - cx: &Context<'_>, - it: &clean::Item, - fields: &[clean::Item], +fn item_fields<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + fields: &'a [clean::Item], ctor_kind: Option, -) { - let mut fields = fields - .iter() - .filter_map(|f| match f.kind { - clean::StructFieldItem(ref ty) => Some((f, ty)), - _ => None, - }) - .peekable(); - if let None | Some(CtorKind::Fn) = ctor_kind { - if fields.peek().is_some() { - let title = format!( - "{}{}", - if ctor_kind.is_none() { "Fields" } else { "Tuple Fields" }, - document_non_exhaustive_header(it), - ); - write_section_heading(w, &title, "fields", Some("fields"), document_non_exhaustive(it)); - for (index, (field, ty)) in fields.enumerate() { - let field_name = - field.name.map_or_else(|| index.to_string(), |sym| sym.as_str().to_string()); - let id = cx.derive_id(format!("{typ}.{field_name}", typ = ItemType::StructField)); - write_str( +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + let mut fields = fields + .iter() + .filter_map(|f| match f.kind { + clean::StructFieldItem(ref ty) => Some((f, ty)), + _ => None, + }) + .peekable(); + if let None | Some(CtorKind::Fn) = ctor_kind { + if fields.peek().is_some() { + let title = format!( + "{}{}", + if ctor_kind.is_none() { "Fields" } else { "Tuple Fields" }, + document_non_exhaustive_header(it), + ); + write!( w, - format_args!( + "{}", + write_section_heading( + &title, + "fields", + Some("fields"), + document_non_exhaustive(it) + ) + )?; + for (index, (field, ty)) in fields.enumerate() { + let field_name = field + .name + .map_or_else(|| index.to_string(), |sym| sym.as_str().to_string()); + let id = + cx.derive_id(format!("{typ}.{field_name}", typ = ItemType::StructField)); + write!( + w, "\ §\ {field_name}: {ty}\ - ", + \ + {doc}", item_type = ItemType::StructField, - ty = ty.print(cx) - ), - ); - write_str(w, format_args!("{}", document(cx, field, Some(it), HeadingOffset::H3))); + ty = ty.print(cx), + doc = document(cx, field, Some(it), HeadingOffset::H3), + )?; + } } } - } + Ok(()) + }) } -fn item_static( - w: &mut impl fmt::Write, - cx: &Context<'_>, - it: &clean::Item, - s: &clean::Static, +fn item_static<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, + s: &'a clean::Static, safety: Option, -) { - wrap_item(w, |buffer| { - render_attributes_in_code(buffer, it, cx); - write!( - buffer, - "{vis}{safe}static {mutability}{name}: {typ}", - vis = visibility_print_with_space(it, cx), - safe = safety.map(|safe| safe.prefix_str()).unwrap_or(""), - mutability = s.mutability.print_with_space(), - name = it.name.unwrap(), - typ = s.type_.print(cx) - ) - .unwrap(); - }); +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + wrap_item(w, |w| { + render_attributes_in_code(w, it, cx); + write!( + w, + "{vis}{safe}static {mutability}{name}: {typ}", + vis = visibility_print_with_space(it, cx), + safe = safety.map(|safe| safe.prefix_str()).unwrap_or(""), + mutability = s.mutability.print_with_space(), + name = it.name.unwrap(), + typ = s.type_.print(cx) + ) + })?; - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); + write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) + }) } -fn item_foreign_type(w: &mut impl fmt::Write, cx: &Context<'_>, it: &clean::Item) { - wrap_item(w, |buffer| { - buffer.write_str("extern {\n").unwrap(); - render_attributes_in_code(buffer, it, cx); - write!( - buffer, - " {}type {};\n}}", - visibility_print_with_space(it, cx), - it.name.unwrap(), - ) - .unwrap(); - }); +fn item_foreign_type<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(|w| { + wrap_item(w, |w| { + w.write_str("extern {\n")?; + render_attributes_in_code(w, it, cx); + write!(w, " {}type {};\n}}", visibility_print_with_space(it, cx), it.name.unwrap(),) + })?; - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); - write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All)) - .unwrap(); + write!( + w, + "{}{}", + document(cx, it, None, HeadingOffset::H2), + render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All) + ) + }) } -fn item_keyword(w: &mut String, cx: &Context<'_>, it: &clean::Item) { - write_str(w, format_args!("{}", document(cx, it, None, HeadingOffset::H2))); +fn item_keyword<'a, 'tcx>( + cx: &'a Context<'tcx>, + it: &'a clean::Item, +) -> impl fmt::Display + 'a + Captures<'tcx> { + document(cx, it, None, HeadingOffset::H2) } /// Compare two strings treating multi-digit numbers as single units (i.e. natural sort order). @@ -2140,14 +2297,15 @@ fn bounds<'a, 'tcx>( .maybe_display() } -fn wrap_item(w: &mut W, f: F) +fn wrap_item(w: &mut W, f: F) -> T where W: fmt::Write, - F: FnOnce(&mut W), + F: FnOnce(&mut W) -> T, { write!(w, r#"
"#).unwrap();
-    f(w);
+    let res = f(w);
     write!(w, "
").unwrap(); + res } #[derive(PartialEq, Eq)] @@ -2171,14 +2329,13 @@ impl Ord for ImplString { } } -fn render_implementor( - cx: &Context<'_>, - implementor: &Impl, - trait_: &clean::Item, - w: &mut String, - implementor_dups: &FxHashMap, - aliases: &[String], -) { +fn render_implementor<'a, 'tcx>( + cx: &'a Context<'tcx>, + implementor: &'a Impl, + trait_: &'a clean::Item, + implementor_dups: &'a FxHashMap, + aliases: &'a [String], +) -> impl fmt::Display + 'a + Captures<'tcx> { // If there's already another implementor that has the same abridged name, use the // full path, for example in `std::iter::ExactSizeIterator` let use_absolute = match implementor.inner_impl().for_ { @@ -2191,7 +2348,6 @@ fn render_implementor( _ => false, }; render_impl( - w, cx, implementor, trait_, @@ -2205,7 +2361,7 @@ fn render_implementor( show_non_assoc_items: false, toggle_open_by_default: false, }, - ); + ) } fn render_union<'a, 'cx: 'a>( @@ -2217,14 +2373,17 @@ fn render_union<'a, 'cx: 'a>( fmt::from_fn(move |mut f| { write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?; - let where_displayed = g - .map(|g| { - let mut buf = g.print(cx).to_string(); - let where_displayed = print_where_clause_and_check(&mut buf, g, cx); - f.write_str(&buf).unwrap(); - where_displayed - }) - .unwrap_or(false); + let where_displayed = if let Some(generics) = g { + write!(f, "{}", generics.print(cx))?; + if let Some(where_clause) = print_where_clause(generics, cx, 0, Ending::Newline) { + write!(f, "{where_clause}")?; + true + } else { + false + } + } else { + false + }; // If there wasn't a `where` clause, we add a whitespace. if !where_displayed { @@ -2262,148 +2421,160 @@ fn render_union<'a, 'cx: 'a>( }) } -fn render_struct( - w: &mut String, - it: &clean::Item, - g: Option<&clean::Generics>, +fn render_struct<'a, 'tcx>( + it: &'a clean::Item, + g: Option<&'a clean::Generics>, ty: Option, - fields: &[clean::Item], - tab: &str, + fields: &'a [clean::Item], + tab: &'a str, structhead: bool, - cx: &Context<'_>, -) { - write_str( - w, - format_args!( + cx: &'a Context<'tcx>, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + write!( + w, "{}{}{}", visibility_print_with_space(it, cx), if structhead { "struct " } else { "" }, it.name.unwrap() - ), - ); - if let Some(g) = g { - write_str(w, format_args!("{}", g.print(cx))); - } - render_struct_fields( - w, - g, - ty, - fields, - tab, - structhead, - it.has_stripped_entries().unwrap_or(false), - cx, - ) + )?; + if let Some(g) = g { + write!(w, "{}", g.print(cx))?; + } + write!( + w, + "{}", + render_struct_fields( + g, + ty, + fields, + tab, + structhead, + it.has_stripped_entries().unwrap_or(false), + cx, + ) + ) + }) } -fn render_struct_fields( - mut w: &mut String, - g: Option<&clean::Generics>, +fn render_struct_fields<'a, 'tcx>( + g: Option<&'a clean::Generics>, ty: Option, - fields: &[clean::Item], - tab: &str, + fields: &'a [clean::Item], + tab: &'a str, structhead: bool, has_stripped_entries: bool, - cx: &Context<'_>, -) { - match ty { - None => { - let where_displayed = - g.map(|g| print_where_clause_and_check(w, g, cx)).unwrap_or(false); + cx: &'a Context<'tcx>, +) -> impl fmt::Display + 'a + Captures<'tcx> { + fmt::from_fn(move |w| { + match ty { + None => { + let where_displayed = if let Some(generics) = g + && let Some(where_clause) = print_where_clause(generics, cx, 0, Ending::Newline) + { + write!(w, "{where_clause}")?; + true + } else { + false + }; - // If there wasn't a `where` clause, we add a whitespace. - if !where_displayed { - w.push_str(" {"); - } else { - w.push_str("{"); - } - let count_fields = - fields.iter().filter(|f| matches!(f.kind, clean::StructFieldItem(..))).count(); - let has_visible_fields = count_fields > 0; - let toggle = should_hide_fields(count_fields); - if toggle { - toggle_open(&mut w, format_args!("{count_fields} fields")); - } - for field in fields { - if let clean::StructFieldItem(ref ty) = field.kind { - write_str( - w, - format_args!( + // If there wasn't a `where` clause, we add a whitespace. + if !where_displayed { + w.write_str(" {")?; + } else { + w.write_str("{")?; + } + let count_fields = + fields.iter().filter(|f| matches!(f.kind, clean::StructFieldItem(..))).count(); + let has_visible_fields = count_fields > 0; + let toggle = should_hide_fields(count_fields); + if toggle { + toggle_open(&mut *w, format_args!("{count_fields} fields")); + } + for field in fields { + if let clean::StructFieldItem(ref ty) = field.kind { + write!( + w, "\n{tab} {vis}{name}: {ty},", vis = visibility_print_with_space(field, cx), name = field.name.unwrap(), ty = ty.print(cx) - ), - ); - } - } - - if has_visible_fields { - if has_stripped_entries { - write_str( - w, - format_args!( - "\n{tab} /* private fields */" - ), - ); - } - write_str(w, format_args!("\n{tab}")); - } else if has_stripped_entries { - write_str(w, format_args!(" /* private fields */ ")); - } - if toggle { - toggle_close(&mut w); - } - w.push_str("}"); - } - Some(CtorKind::Fn) => { - w.push_str("("); - if !fields.is_empty() - && fields.iter().all(|field| { - matches!(field.kind, clean::StrippedItem(box clean::StructFieldItem(..))) - }) - { - write_str(w, format_args!("/* private fields */")); - } else { - for (i, field) in fields.iter().enumerate() { - if i > 0 { - w.push_str(", "); + )?; } - match field.kind { - clean::StrippedItem(box clean::StructFieldItem(..)) => { - write_str(w, format_args!("_")); + } + + if has_visible_fields { + if has_stripped_entries { + write!( + w, + "\n{tab} /* private fields */" + )?; + } + write!(w, "\n{tab}")?; + } else if has_stripped_entries { + write!(w, " /* private fields */ ")?; + } + if toggle { + toggle_close(&mut *w); + } + w.write_str("}")?; + } + Some(CtorKind::Fn) => { + w.write_str("(")?; + if !fields.is_empty() + && fields.iter().all(|field| { + matches!(field.kind, clean::StrippedItem(box clean::StructFieldItem(..))) + }) + { + write!(w, "/* private fields */")?; + } else { + for (i, field) in fields.iter().enumerate() { + if i > 0 { + w.write_str(", ")?; } - clean::StructFieldItem(ref ty) => { - write_str( - w, - format_args!( + match field.kind { + clean::StrippedItem(box clean::StructFieldItem(..)) => { + write!(w, "_")?; + } + clean::StructFieldItem(ref ty) => { + write!( + w, "{}{}", visibility_print_with_space(field, cx), ty.print(cx) - ), - ); + )?; + } + _ => unreachable!(), } - _ => unreachable!(), } } + w.write_str(")")?; + if let Some(g) = g { + write!( + w, + "{}", + print_where_clause(g, cx, 0, Ending::NoNewline).maybe_display() + )?; + } + // We only want a ";" when we are displaying a tuple struct, not a variant tuple struct. + if structhead { + w.write_str(";")?; + } } - w.push_str(")"); - if let Some(g) = g { - write_str(w, format_args!("{}", print_where_clause(g, cx, 0, Ending::NoNewline))); - } - // We only want a ";" when we are displaying a tuple struct, not a variant tuple struct. - if structhead { - w.push_str(";"); + Some(CtorKind::Const) => { + // Needed for PhantomData. + if let Some(g) = g { + write!( + w, + "{}", + print_where_clause(g, cx, 0, Ending::NoNewline).maybe_display() + )?; + } + w.write_str(";")?; } } - Some(CtorKind::Const) => { - // Needed for PhantomData. - if let Some(g) = g { - write_str(w, format_args!("{}", print_where_clause(g, cx, 0, Ending::NoNewline))); - } - w.push_str(";"); - } - } + Ok(()) + }) } fn document_non_exhaustive_header(item: &clean::Item) -> &str { diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index a4dec013fc04..0185d0c3bb54 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -636,26 +636,22 @@ impl TypeAliasPart { } else { AssocItemLink::Anchor(None) }; - let text = { - let mut buf = String::new(); - super::render_impl( - &mut buf, - cx, - impl_, - type_alias_item, - assoc_link, - RenderMode::Normal, - None, - &[], - ImplRenderingParameters { - show_def_docs: true, - show_default_items: true, - show_non_assoc_items: true, - toggle_open_by_default: true, - }, - ); - buf - }; + let text = super::render_impl( + cx, + impl_, + type_alias_item, + assoc_link, + RenderMode::Normal, + None, + &[], + ImplRenderingParameters { + show_def_docs: true, + show_default_items: true, + show_non_assoc_items: true, + toggle_open_by_default: true, + }, + ) + .to_string(); let type_alias_fqp = (*type_alias_fqp).iter().join("::"); if Some(&text) == ret.last().map(|s: &AliasSerializableImpl| &s.text) { ret.last_mut() From 11959a8b6e75d2c55500a703070a248342d29549 Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 23 Feb 2025 14:44:27 +0800 Subject: [PATCH 230/991] Fix invalid suggestion from type error for derive macro --- .../src/fn_ctxt/suggestions.rs | 14 +++++++++----- .../auxiliary/derive-demo-issue-136343.rs | 7 +++++++ ...alid-sugg-for-derive-macro-issue-136343.rs | 9 +++++++++ ...-sugg-for-derive-macro-issue-136343.stderr | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 tests/ui/typeck/auxiliary/derive-demo-issue-136343.rs create mode 100644 tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs create mode 100644 tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index f9fc12159363..35a3491f7c08 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::{ }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; -use rustc_span::{Ident, Span, Symbol, sym}; +use rustc_span::{ExpnKind, Ident, MacroKind, Span, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::traits::DefIdOrName; use rustc_trait_selection::infer::InferCtxtExt; @@ -1365,6 +1365,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.param_env, ty::TraitRef::new(self.tcx, into_def_id, [expr_ty, expected_ty]), )) + && !expr + .span + .macro_backtrace() + .any(|x| matches!(x.kind, ExpnKind::Macro(MacroKind::Attr | MacroKind::Derive, ..))) { let span = expr.span.find_oldest_ancestor_in_same_ctxt(); @@ -1380,10 +1384,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg.insert(0, (expr.span.shrink_to_lo(), format!("{}: ", name))); } diag.multipart_suggestion( - format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"), - sugg, - Applicability::MaybeIncorrect - ); + format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"), + sugg, + Applicability::MaybeIncorrect + ); return true; } diff --git a/tests/ui/typeck/auxiliary/derive-demo-issue-136343.rs b/tests/ui/typeck/auxiliary/derive-demo-issue-136343.rs new file mode 100644 index 000000000000..65be439b49a9 --- /dev/null +++ b/tests/ui/typeck/auxiliary/derive-demo-issue-136343.rs @@ -0,0 +1,7 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(Sample)] +pub fn sample(_: TokenStream) -> TokenStream { + "fn bad, U>(a: T) -> U { a }".parse().unwrap() +} diff --git a/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs new file mode 100644 index 000000000000..c08030fc5c15 --- /dev/null +++ b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs @@ -0,0 +1,9 @@ +//@ proc-macro: derive-demo-issue-136343.rs + +#[macro_use] +extern crate derive_demo_issue_136343; + +#[derive(Sample)] //~ ERROR mismatched types +struct Test; + +fn main() {} diff --git a/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr new file mode 100644 index 000000000000..0b9c1d9123aa --- /dev/null +++ b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/invalid-sugg-for-derive-macro-issue-136343.rs:6:10 + | +LL | #[derive(Sample)] + | ^^^^^^ + | | + | expected type parameter `U`, found type parameter `T` + | expected `U` because of return type + | + = note: expected type parameter `U` + found type parameter `T` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + = note: the caller chooses a type for `U` which can be different from `T` + = note: this error originates in the derive macro `Sample` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From b34054511401f7aed8e76b8d5663651b5b4ced2a Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 11 Feb 2025 22:50:26 +0000 Subject: [PATCH 231/991] [illumos] attempt to use posix_spawn to spawn processes illumos has `posix_spawn`, and the very newest versions also have `_addchdir`, so use that. This is a nice ~4x performance improvement for process creation. My go-to as usual is nextest against the clap repo, which acts as a stress test for process creation -- with [this commit]: ```console $ cargo nextest run -E 'not test(ui_tests) and not test(example_tests)' before: Summary [ 1.747s] 879 tests run: 879 passed, 2 skipped after: Summary [ 0.445s] 879 tests run: 879 passed, 2 skipped ``` [this commit]: https://github.com/clap-rs/clap/commit/fde45f9aea766fb8de46e3d46e6575f393c3b6b9 --- library/Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- .../src/sys/pal/unix/process/process_unix.rs | 17 ++++++++++++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index 0be2f9a15493..6bc3cf4da9f7 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.169" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" dependencies = [ "rustc-std-workspace-core", ] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 228ee6eea05f..cec5cdbb92c2 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -35,7 +35,7 @@ miniz_oxide = { version = "0.8.0", optional = true, default-features = false } addr2line = { version = "0.24.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.169", default-features = false, features = [ +libc = { version = "0.2.170", default-features = false, features = [ 'rustc-dep-of-std', ], public = true } diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index aa7406dd5487..7c5b0fca11a1 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -410,6 +410,7 @@ impl Command { #[cfg(not(any( target_os = "freebsd", + target_os = "illumos", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), target_os = "nto", @@ -427,6 +428,7 @@ impl Command { // directly. #[cfg(any( target_os = "freebsd", + target_os = "illumos", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), target_os = "nto", @@ -584,6 +586,10 @@ impl Command { fn get_posix_spawn_addchdir() -> Option { use crate::sys::weak::weak; + // POSIX.1-2024 standardizes this function: + // https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addchdir.html. + // The _np version is more widely available, though, so try that first. + weak! { fn posix_spawn_file_actions_addchdir_np( *mut libc::posix_spawn_file_actions_t, @@ -591,7 +597,16 @@ impl Command { ) -> libc::c_int } - posix_spawn_file_actions_addchdir_np.get() + weak! { + fn posix_spawn_file_actions_addchdir( + *mut libc::posix_spawn_file_actions_t, + *const libc::c_char + ) -> libc::c_int + } + + posix_spawn_file_actions_addchdir_np + .get() + .or_else(|| posix_spawn_file_actions_addchdir.get()) } /// Get the function pointer for adding a chdir action to a From db1f0d045887e8046dd542e119b27773991039b6 Mon Sep 17 00:00:00 2001 From: Mahmoud Mazouz Date: Sun, 23 Feb 2025 12:22:52 +0100 Subject: [PATCH 232/991] Return error on unexpected termination in `Thread::join`. There is a time window during which the OS can terminate a thread before stdlib can retreive its `Packet`. Currently the `Thread::join` panics with no message in such an event, which makes debugging difficult; fixes #124466. --- library/std/src/thread/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 59b395336f2e..f5101a66ce19 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1739,7 +1739,11 @@ struct JoinInner<'scope, T> { impl<'scope, T> JoinInner<'scope, T> { fn join(mut self) -> Result { self.native.join(); - Arc::get_mut(&mut self.packet).unwrap().result.get_mut().take().unwrap() + if let Some(packet) = Arc::get_mut(&mut self.packet) { + packet.result.get_mut().take().unwrap() + } else { + Err(Box::new("thread terminated unexpectedly (e.g. due to OS intervention)")) + } } } From 1a99ca8da98061a52b9b429d1a859b1e1475cae9 Mon Sep 17 00:00:00 2001 From: DianQK Date: Sun, 17 Nov 2024 14:21:23 +0800 Subject: [PATCH 233/991] The embedded bitcode should always be prepared for LTO/ThinLTO --- .../rustc_codegen_cranelift/src/driver/aot.rs | 2 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 10 +- compiler/rustc_codegen_llvm/src/back/write.rs | 133 ++++++++++++------ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 4 +- compiler/rustc_codegen_ssa/src/back/write.rs | 3 + .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 66 ++++++--- compiler/rustc_session/src/config.rs | 11 +- tests/codegen/overaligned-constant.rs | 4 +- tests/codegen/uninit-consts.rs | 8 +- .../run-make/pgo-embed-bc-lto/interesting.rs | 16 +++ tests/run-make/pgo-embed-bc-lto/main.rs | 5 + tests/run-make/pgo-embed-bc-lto/opaque.rs | 5 + tests/run-make/pgo-embed-bc-lto/rmake.rs | 67 +++++++++ 13 files changed, 265 insertions(+), 69 deletions(-) create mode 100644 tests/run-make/pgo-embed-bc-lto/interesting.rs create mode 100644 tests/run-make/pgo-embed-bc-lto/main.rs create mode 100644 tests/run-make/pgo-embed-bc-lto/opaque.rs create mode 100644 tests/run-make/pgo-embed-bc-lto/rmake.rs diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index a52b18573b15..366e83853e51 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -210,7 +210,7 @@ fn produce_final_output_artifacts( // to get rid of it. for output_type in crate_output.outputs.keys() { match *output_type { - OutputType::Bitcode | OutputType::ThinLinkBitcode => { + OutputType::Bitcode | OutputType::ThinLinkBitcode | OutputType::ThinBitcode => { // Cranelift doesn't have bitcode // user_wants_bitcode = true; // // Copy to .bc, but always keep the .0.bc. There is a later diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 99906ea7bce3..6676afe489f2 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -2,6 +2,7 @@ use std::collections::BTreeMap; use std::ffi::{CStr, CString}; use std::fs::File; use std::path::Path; +use std::ptr::NonNull; use std::sync::Arc; use std::{io, iter, slice}; @@ -655,14 +656,14 @@ pub(crate) fn run_pass_manager( } unsafe { - write::llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, stage)?; + write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?; } if cfg!(llvm_enzyme) && enable_ad { let opt_stage = llvm::OptStage::FatLTO; let stage = write::AutodiffStage::PostAD; unsafe { - write::llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, stage)?; + write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?; } // This is the final IR, so people should be able to inspect the optimized autodiff output. @@ -729,6 +730,11 @@ impl ThinBuffer { ThinBuffer(buffer) } } + + pub unsafe fn from_raw_ptr(ptr: *mut llvm::ThinLTOBuffer) -> ThinBuffer { + let mut ptr = NonNull::new(ptr).unwrap(); + ThinBuffer(unsafe { ptr.as_mut() }) + } } impl ThinBufferMethods for ThinBuffer { diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index b67890c04657..1ad256d3b75d 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -1,6 +1,7 @@ use std::ffi::{CStr, CString}; use std::io::{self, Write}; use std::path::{Path, PathBuf}; +use std::ptr::null_mut; use std::sync::Arc; use std::{fs, slice, str}; @@ -15,7 +16,7 @@ use rustc_codegen_ssa::back::write::{ TargetMachineFactoryFn, }; use rustc_codegen_ssa::traits::*; -use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; +use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::small_c_str::SmallCStr; use rustc_errors::{DiagCtxtHandle, FatalError, Level}; @@ -551,6 +552,7 @@ pub(crate) unsafe fn llvm_optimize( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, module: &ModuleCodegen, + thin_lto_buffer: Option<&mut *mut llvm::ThinLTOBuffer>, config: &ModuleConfig, opt_level: config::OptLevel, opt_stage: llvm::OptStage, @@ -584,7 +586,17 @@ pub(crate) unsafe fn llvm_optimize( vectorize_loop = config.vectorize_loop; } trace!(?unroll_loops, ?vectorize_slp, ?vectorize_loop, ?run_enzyme); - let using_thin_buffers = opt_stage == llvm::OptStage::PreLinkThinLTO || config.bitcode_needed(); + if thin_lto_buffer.is_some() { + assert!( + matches!( + opt_stage, + llvm::OptStage::PreLinkNoLTO + | llvm::OptStage::PreLinkFatLTO + | llvm::OptStage::PreLinkThinLTO + ), + "the bitcode for LTO can only be obtained at the pre-link stage" + ); + } let pgo_gen_path = get_pgo_gen_path(config); let pgo_use_path = get_pgo_use_path(config); let pgo_sample_use_path = get_pgo_sample_use_path(config); @@ -644,7 +656,9 @@ pub(crate) unsafe fn llvm_optimize( config.no_prepopulate_passes, config.verify_llvm_ir, config.lint_llvm_ir, - using_thin_buffers, + thin_lto_buffer, + config.emit_thin_lto, + config.emit_thin_lto_summary, config.merge_functions, unroll_loops, vectorize_slp, @@ -705,9 +719,56 @@ pub(crate) unsafe fn optimize( // Otherwise we pretend AD is already done and run the normal opt pipeline (=PostAD). let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable); let autodiff_stage = if consider_ad { AutodiffStage::PreAD } else { AutodiffStage::PostAD }; - return unsafe { - llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, autodiff_stage) + // The embedded bitcode is used to run LTO/ThinLTO. + // The bitcode obtained during the `codegen` phase is no longer suitable for performing LTO. + // It may have undergone LTO due to ThinLocal, so we need to obtain the embedded bitcode at + // this point. + let mut thin_lto_buffer = if (module.kind == ModuleKind::Regular + && config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full)) + || config.emit_thin_lto_summary + { + Some(null_mut()) + } else { + None }; + unsafe { + llvm_optimize( + cgcx, + dcx, + module, + thin_lto_buffer.as_mut(), + config, + opt_level, + opt_stage, + autodiff_stage, + ) + }?; + if let Some(thin_lto_buffer) = thin_lto_buffer { + let thin_lto_buffer = unsafe { ThinBuffer::from_raw_ptr(thin_lto_buffer) }; + let thin_bc_out = cgcx.output_filenames.temp_path(OutputType::ThinBitcode, module_name); + if let Err(err) = fs::write(&thin_bc_out, thin_lto_buffer.data()) { + dcx.emit_err(WriteBytecode { path: &thin_bc_out, err }); + } + let bc_summary_out = + cgcx.output_filenames.temp_path(OutputType::ThinLinkBitcode, module_name); + if config.emit_thin_lto_summary + && let Some(thin_link_bitcode_filename) = bc_summary_out.file_name() + { + let summary_data = thin_lto_buffer.thin_link_data(); + cgcx.prof.artifact_size( + "llvm_bitcode_summary", + thin_link_bitcode_filename.to_string_lossy(), + summary_data.len() as u64, + ); + let _timer = cgcx.prof.generic_activity_with_arg( + "LLVM_module_codegen_emit_bitcode_summary", + &*module.name, + ); + if let Err(err) = fs::write(&bc_summary_out, summary_data) { + dcx.emit_err(WriteBytecode { path: &bc_summary_out, err }); + } + } + } } Ok(()) } @@ -760,59 +821,47 @@ pub(crate) unsafe fn codegen( // otherwise requested. let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); - let bc_summary_out = - cgcx.output_filenames.temp_path(OutputType::ThinLinkBitcode, module_name); let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); if config.bitcode_needed() { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &*module.name); - let thin = ThinBuffer::new(llmod, config.emit_thin_lto, config.emit_thin_lto_summary); - let data = thin.data(); - - if let Some(bitcode_filename) = bc_out.file_name() { - cgcx.prof.artifact_size( - "llvm_bitcode", - bitcode_filename.to_string_lossy(), - data.len() as u64, - ); - } - - if config.emit_thin_lto_summary - && let Some(thin_link_bitcode_filename) = bc_summary_out.file_name() - { - let summary_data = thin.thin_link_data(); - cgcx.prof.artifact_size( - "llvm_bitcode_summary", - thin_link_bitcode_filename.to_string_lossy(), - summary_data.len() as u64, - ); - - let _timer = cgcx.prof.generic_activity_with_arg( - "LLVM_module_codegen_emit_bitcode_summary", - &*module.name, - ); - if let Err(err) = fs::write(&bc_summary_out, summary_data) { - dcx.emit_err(WriteBytecode { path: &bc_summary_out, err }); - } - } - if config.emit_bc || config.emit_obj == EmitObj::Bitcode { + let thin = { + let _timer = cgcx.prof.generic_activity_with_arg( + "LLVM_module_codegen_make_bitcode", + &*module.name, + ); + ThinBuffer::new(llmod, config.emit_thin_lto, false) + }; + let data = thin.data(); let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_emit_bitcode", &*module.name); + if let Some(bitcode_filename) = bc_out.file_name() { + cgcx.prof.artifact_size( + "llvm_bitcode", + bitcode_filename.to_string_lossy(), + data.len() as u64, + ); + } if let Err(err) = fs::write(&bc_out, data) { dcx.emit_err(WriteBytecode { path: &bc_out, err }); } } - if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { + if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) + && module.kind == ModuleKind::Regular + { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_embed_bitcode", &*module.name); + let thin_bc_out = + cgcx.output_filenames.temp_path(OutputType::ThinBitcode, module_name); + assert!(thin_bc_out.exists(), "cannot find {:?} as embedded bitcode", thin_bc_out); + let data = fs::read(&thin_bc_out).unwrap(); + debug!("removing embed bitcode file {:?}", thin_bc_out); + ensure_removed(dcx, &thin_bc_out); unsafe { - embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); + embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, &data); } } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 3b0187b9d37b..ac91a416edcb 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2421,7 +2421,9 @@ unsafe extern "C" { NoPrepopulatePasses: bool, VerifyIR: bool, LintIR: bool, - UseThinLTOBuffers: bool, + ThinLTOBuffer: Option<&mut *mut ThinLTOBuffer>, + EmitThinLTO: bool, + EmitThinLTOSummary: bool, MergeFunctions: bool, UnrollLoops: bool, SLPVectorize: bool, diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index d2548deb8c7a..47e7dec48e4f 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -626,6 +626,9 @@ fn produce_final_output_artifacts( // them for making an rlib. copy_if_one_unit(OutputType::Bitcode, true); } + OutputType::ThinBitcode => { + copy_if_one_unit(OutputType::ThinBitcode, true); + } OutputType::ThinLinkBitcode => { copy_if_one_unit(OutputType::ThinLinkBitcode, false); } diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 9ce4abdb432e..6e607baebb5c 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -7,6 +7,7 @@ #include "llvm/Analysis/Lint.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Bitcode/BitcodeWriter.h" +#include "llvm/Bitcode/BitcodeWriterPass.h" #include "llvm/CodeGen/CommandFlags.h" #include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/AutoUpgrade.h" @@ -37,6 +38,7 @@ #include "llvm/Transforms/Instrumentation/InstrProfiling.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" +#include "llvm/Transforms/Scalar/AnnotationRemarks.h" #include "llvm/Transforms/Utils/CanonicalizeAliases.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" #include "llvm/Transforms/Utils/NameAnonGlobals.h" @@ -195,6 +197,19 @@ extern "C" void LLVMRustTimeTraceProfilerFinish(const char *FileName) { GEN_SUBTARGETS #undef SUBTARGET +// This struct and various functions are sort of a hack right now, but the +// problem is that we've got in-memory LLVM modules after we generate and +// optimize all codegen-units for one compilation in rustc. To be compatible +// with the LTO support above we need to serialize the modules plus their +// ThinLTO summary into memory. +// +// This structure is basically an owned version of a serialize module, with +// a ThinLTO summary attached. +struct LLVMRustThinLTOBuffer { + std::string data; + std::string thin_link_data; +}; + extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM, const char *Feature) { TargetMachine *Target = unwrap(TM); @@ -704,7 +719,8 @@ extern "C" LLVMRustResult LLVMRustOptimize( LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef, LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage, bool IsLinkerPluginLTO, bool NoPrepopulatePasses, bool VerifyIR, - bool LintIR, bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops, + bool LintIR, LLVMRustThinLTOBuffer **ThinLTOBufferRef, bool EmitThinLTO, + bool EmitThinLTOSummary, bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers, bool RunEnzyme, LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath, @@ -952,7 +968,10 @@ extern "C" LLVMRustResult LLVMRustOptimize( } ModulePassManager MPM; - bool NeedThinLTOBufferPasses = UseThinLTOBuffers; + bool NeedThinLTOBufferPasses = EmitThinLTO; + auto ThinLTOBuffer = std::make_unique(); + raw_string_ostream ThinLTODataOS(ThinLTOBuffer->data); + raw_string_ostream ThinLinkDataOS(ThinLTOBuffer->thin_link_data); if (!NoPrepopulatePasses) { // The pre-link pipelines don't support O0 and require using // buildO0DefaultPipeline() instead. At the same time, the LTO pipelines do @@ -976,7 +995,25 @@ extern "C" LLVMRustResult LLVMRustOptimize( switch (OptStage) { case LLVMRustOptStage::PreLinkNoLTO: - MPM = PB.buildPerModuleDefaultPipeline(OptLevel); + if (ThinLTOBufferRef) { + // This is similar to LLVM's `buildFatLTODefaultPipeline`, where the + // bitcode for embedding is obtained after performing + // `ThinLTOPreLinkDefaultPipeline`. + MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(OptLevel)); + if (EmitThinLTO) { + MPM.addPass(ThinLTOBitcodeWriterPass( + ThinLTODataOS, EmitThinLTOSummary ? &ThinLinkDataOS : nullptr)); + } else { + MPM.addPass(BitcodeWriterPass(ThinLTODataOS)); + } + *ThinLTOBufferRef = ThinLTOBuffer.release(); + MPM.addPass(PB.buildModuleOptimizationPipeline( + OptLevel, ThinOrFullLTOPhase::None)); + MPM.addPass( + createModuleToFunctionPassAdaptor(AnnotationRemarksPass())); + } else { + MPM = PB.buildPerModuleDefaultPipeline(OptLevel); + } break; case LLVMRustOptStage::PreLinkThinLTO: MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel); @@ -1022,6 +1059,16 @@ extern "C" LLVMRustResult LLVMRustOptimize( MPM.addPass(CanonicalizeAliasesPass()); MPM.addPass(NameAnonGlobalPass()); } + // For `-Copt-level=0`, ThinLTO, or LTO. + if (ThinLTOBufferRef && *ThinLTOBufferRef == nullptr) { + if (EmitThinLTO) { + MPM.addPass(ThinLTOBitcodeWriterPass( + ThinLTODataOS, EmitThinLTOSummary ? &ThinLinkDataOS : nullptr)); + } else { + MPM.addPass(BitcodeWriterPass(ThinLTODataOS)); + } + *ThinLTOBufferRef = ThinLTOBuffer.release(); + } // now load "-enzyme" pass: #ifdef ENZYME @@ -1500,19 +1547,6 @@ extern "C" bool LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, return true; } -// This struct and various functions are sort of a hack right now, but the -// problem is that we've got in-memory LLVM modules after we generate and -// optimize all codegen-units for one compilation in rustc. To be compatible -// with the LTO support above we need to serialize the modules plus their -// ThinLTO summary into memory. -// -// This structure is basically an owned version of a serialize module, with -// a ThinLTO summary attached. -struct LLVMRustThinLTOBuffer { - std::string data; - std::string thin_link_data; -}; - extern "C" LLVMRustThinLTOBuffer * LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin, bool emit_summary) { auto Ret = std::make_unique(); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8f0b17b5e887..d94338443b32 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -541,6 +541,7 @@ impl FromStr for SplitDwarfKind { pub enum OutputType { Bitcode, ThinLinkBitcode, + ThinBitcode, Assembly, LlvmAssembly, Mir, @@ -571,6 +572,7 @@ impl OutputType { OutputType::Exe | OutputType::DepInfo | OutputType::Metadata => true, OutputType::Bitcode | OutputType::ThinLinkBitcode + | OutputType::ThinBitcode | OutputType::Assembly | OutputType::LlvmAssembly | OutputType::Mir @@ -582,6 +584,7 @@ impl OutputType { match *self { OutputType::Bitcode => "llvm-bc", OutputType::ThinLinkBitcode => "thin-link-bitcode", + OutputType::ThinBitcode => "thin-llvm-bc", OutputType::Assembly => "asm", OutputType::LlvmAssembly => "llvm-ir", OutputType::Mir => "mir", @@ -599,6 +602,7 @@ impl OutputType { "mir" => OutputType::Mir, "llvm-bc" => OutputType::Bitcode, "thin-link-bitcode" => OutputType::ThinLinkBitcode, + "thin-llvm-bc" => OutputType::ThinBitcode, "obj" => OutputType::Object, "metadata" => OutputType::Metadata, "link" => OutputType::Exe, @@ -609,9 +613,10 @@ impl OutputType { fn shorthands_display() -> String { format!( - "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`", + "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`", OutputType::Bitcode.shorthand(), OutputType::ThinLinkBitcode.shorthand(), + OutputType::ThinBitcode.shorthand(), OutputType::Assembly.shorthand(), OutputType::LlvmAssembly.shorthand(), OutputType::Mir.shorthand(), @@ -626,6 +631,7 @@ impl OutputType { match *self { OutputType::Bitcode => "bc", OutputType::ThinLinkBitcode => "indexing.o", + OutputType::ThinBitcode => "thin.bc", OutputType::Assembly => "s", OutputType::LlvmAssembly => "ll", OutputType::Mir => "mir", @@ -644,6 +650,7 @@ impl OutputType { | OutputType::DepInfo => true, OutputType::Bitcode | OutputType::ThinLinkBitcode + | OutputType::ThinBitcode | OutputType::Object | OutputType::Metadata | OutputType::Exe => false, @@ -731,6 +738,7 @@ impl OutputTypes { self.0.keys().any(|k| match *k { OutputType::Bitcode | OutputType::ThinLinkBitcode + | OutputType::ThinBitcode | OutputType::Assembly | OutputType::LlvmAssembly | OutputType::Mir @@ -745,6 +753,7 @@ impl OutputTypes { self.0.keys().any(|k| match *k { OutputType::Bitcode | OutputType::ThinLinkBitcode + | OutputType::ThinBitcode | OutputType::Assembly | OutputType::LlvmAssembly | OutputType::Mir diff --git a/tests/codegen/overaligned-constant.rs b/tests/codegen/overaligned-constant.rs index e5540aca3878..0f5977880f2e 100644 --- a/tests/codegen/overaligned-constant.rs +++ b/tests/codegen/overaligned-constant.rs @@ -9,14 +9,14 @@ struct S(i32); struct SmallStruct(f32, Option, &'static [f32]); -// CHECK: @0 = private unnamed_addr constant +// CHECK: [[const:@.*]] = private unnamed_addr constant // CHECK-SAME: , align 8 #[no_mangle] pub fn overaligned_constant() { // CHECK-LABEL: @overaligned_constant // CHECK: [[full:%_.*]] = alloca [32 x i8], align 8 - // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[full]], ptr align 8 @0, i64 32, i1 false) + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[full]], ptr align 8 [[const]], i64 32, i1 false) let mut s = S(1); s.0 = 3; diff --git a/tests/codegen/uninit-consts.rs b/tests/codegen/uninit-consts.rs index 649927b87b40..a58008e171e2 100644 --- a/tests/codegen/uninit-consts.rs +++ b/tests/codegen/uninit-consts.rs @@ -11,15 +11,15 @@ pub struct PartiallyUninit { y: MaybeUninit<[u8; 10]>, } -// CHECK: [[FULLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [10 x i8] }> undef +// CHECK: [[FULLY_UNINIT:@.*]] = private unnamed_addr constant <{ [10 x i8] }> undef -// CHECK: [[PARTIALLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [4 x i8], [12 x i8] }> <{ [4 x i8] c"{{\\EF\\BE\\AD\\DE|\\DE\\AD\\BE\\EF}}", [12 x i8] undef }>, align 4 +// CHECK: [[PARTIALLY_UNINIT:@.*]] = private unnamed_addr constant <{ [4 x i8], [12 x i8] }> <{ [4 x i8] c"{{\\EF\\BE\\AD\\DE|\\DE\\AD\\BE\\EF}}", [12 x i8] undef }>, align 4 // This shouldn't contain undef, since it contains more chunks // than the default value of uninit_const_chunk_threshold. -// CHECK: [[UNINIT_PADDING_HUGE:@[0-9]+]] = private unnamed_addr constant <{ [32768 x i8] }> <{ [32768 x i8] c"{{.+}}" }>, align 4 +// CHECK: [[UNINIT_PADDING_HUGE:@.*]] = private unnamed_addr constant <{ [32768 x i8] }> <{ [32768 x i8] c"{{.+}}" }>, align 4 -// CHECK: [[FULLY_UNINIT_HUGE:@[0-9]+]] = private unnamed_addr constant <{ [16384 x i8] }> undef +// CHECK: [[FULLY_UNINIT_HUGE:@.*]] = private unnamed_addr constant <{ [16384 x i8] }> undef // CHECK-LABEL: @fully_uninit #[no_mangle] diff --git a/tests/run-make/pgo-embed-bc-lto/interesting.rs b/tests/run-make/pgo-embed-bc-lto/interesting.rs new file mode 100644 index 000000000000..13105c17e126 --- /dev/null +++ b/tests/run-make/pgo-embed-bc-lto/interesting.rs @@ -0,0 +1,16 @@ +#![crate_name = "interesting"] +#![crate_type = "rlib"] + +extern crate opaque; + +#[no_mangle] +#[inline(never)] +pub fn function_called_once() { + opaque::foo(); +} + +// CHECK-LABEL: @function_called_once +// CHECK-SAME: !prof [[function_called_once_id:![0-9]+]] { +// CHECK: "CG Profile" +// CHECK-NOT: "CG Profile" +// CHECK-DAG: [[function_called_once_id]] = !{!"function_entry_count", i64 1} diff --git a/tests/run-make/pgo-embed-bc-lto/main.rs b/tests/run-make/pgo-embed-bc-lto/main.rs new file mode 100644 index 000000000000..ce8747bef3c2 --- /dev/null +++ b/tests/run-make/pgo-embed-bc-lto/main.rs @@ -0,0 +1,5 @@ +extern crate interesting; + +fn main() { + interesting::function_called_once(); +} diff --git a/tests/run-make/pgo-embed-bc-lto/opaque.rs b/tests/run-make/pgo-embed-bc-lto/opaque.rs new file mode 100644 index 000000000000..b4467dc77968 --- /dev/null +++ b/tests/run-make/pgo-embed-bc-lto/opaque.rs @@ -0,0 +1,5 @@ +#![crate_name = "opaque"] +#![crate_type = "rlib"] + +#[inline(never)] +pub fn foo() {} diff --git a/tests/run-make/pgo-embed-bc-lto/rmake.rs b/tests/run-make/pgo-embed-bc-lto/rmake.rs new file mode 100644 index 000000000000..b7eba0c68e34 --- /dev/null +++ b/tests/run-make/pgo-embed-bc-lto/rmake.rs @@ -0,0 +1,67 @@ +// This test case verifies that we successfully complete an LTO build with PGO +// using the embedded bitcode. +// It also ensures that the generated IR correctly includes the call results. + +//@ needs-profiler-runtime +//@ ignore-cross-compile + +use std::path::Path; + +use run_make_support::{ + has_extension, has_prefix, llvm_filecheck, llvm_profdata, rfs, run, rustc, shallow_find_files, +}; + +fn run_test(cg_units: usize) { + let path_prof_data_dir = Path::new("prof_data_dir"); + if path_prof_data_dir.exists() { + rfs::remove_dir_all(path_prof_data_dir); + } + rfs::create_dir_all(&path_prof_data_dir); + let path_merged_profdata = path_prof_data_dir.join("merged.profdata"); + rustc().input("opaque.rs").codegen_units(1).run(); + rustc() + .input("interesting.rs") + .profile_generate(&path_prof_data_dir) + .opt() + .crate_type("lib,cdylib") + .codegen_units(cg_units) + .run(); + rustc() + .input("main.rs") + .arg("-Clto=thin") + .opt() + .codegen_units(cg_units) + .profile_generate(&path_prof_data_dir) + .opt() + .run(); + run("main"); + llvm_profdata().merge().output(&path_merged_profdata).input(path_prof_data_dir).run(); + rustc() + .input("interesting.rs") + .profile_use(&path_merged_profdata) + .opt() + .crate_type("lib,cdylib") + .codegen_units(cg_units) + .emit("link") + .run(); + rustc() + .input("main.rs") + .arg("-Clto=thin") + .opt() + .codegen_units(cg_units) + .profile_use(&path_merged_profdata) + .emit("llvm-ir,link") + .opt() + .run(); + let files = shallow_find_files(".", |path| { + has_prefix(path, "main.interesting.interesting") && has_extension(path, "ll") + }); + assert_eq!(files.len(), 1); + let llvm_ir = &files[0]; + llvm_filecheck().patterns("interesting.rs").stdin_buf(rfs::read(llvm_ir)).run(); +} + +fn main() { + run_test(1); + run_test(16); +} From f32ca1afafa6dbe565b7209067f29c8cf9d074c3 Mon Sep 17 00:00:00 2001 From: DianQK Date: Wed, 8 Jan 2025 22:50:04 +0800 Subject: [PATCH 234/991] Document bitcode in `OutputType` --- compiler/rustc_session/src/config.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index d94338443b32..23553a5540c6 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -539,8 +539,13 @@ impl FromStr for SplitDwarfKind { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, HashStable_Generic)] #[derive(Encodable, Decodable)] pub enum OutputType { + /// This is the optimized bitcode, which could be either pre-LTO or non-LTO bitcode, + /// depending on the specific request type. Bitcode, + /// This is the summary or index data part of the ThinLTO bitcode. ThinLinkBitcode, + /// This is ThinLTO's pre-link bitcode, primarily used for embedding bitcode in object files. + /// This can also be used for FatLTO. ThinBitcode, Assembly, LlvmAssembly, From 9431427cc363d0a1c36401cb98f15a7426f2220f Mon Sep 17 00:00:00 2001 From: DianQK Date: Thu, 6 Feb 2025 21:59:36 +0800 Subject: [PATCH 235/991] Add `new_regular` and `new_allocator` to `ModuleCodegen` --- compiler/rustc_codegen_gcc/src/back/lto.rs | 9 ++++----- compiler/rustc_codegen_gcc/src/base.rs | 11 +++++------ compiler/rustc_codegen_llvm/src/back/lto.rs | 13 +++---------- compiler/rustc_codegen_llvm/src/base.rs | 8 ++------ compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_codegen_ssa/src/lib.rs | 8 ++++++++ 6 files changed, 23 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs index cb4caec8c326..e5221c7da319 100644 --- a/compiler/rustc_codegen_gcc/src/back/lto.rs +++ b/compiler/rustc_codegen_gcc/src/back/lto.rs @@ -632,17 +632,16 @@ pub unsafe fn optimize_thin_module( Arc::new(SyncContext::new(context)) } }; - let module = ModuleCodegen { - module_llvm: GccContext { + let module = ModuleCodegen::new_regular( + thin_module.name().to_string(), + GccContext { context, should_combine_object_files, // TODO(antoyo): use the correct relocation model here. relocation_model: RelocModel::Pic, temp_dir: None, }, - name: thin_module.name().to_string(), - kind: ModuleKind::Regular, - }; + ); /*{ let target = &*module.module_llvm.tm; let llmod = module.module_llvm.llmod(); diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index 962f4b161d78..9b495174a3fa 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -4,10 +4,10 @@ use std::sync::Arc; use std::time::Instant; use gccjit::{CType, Context, FunctionType, GlobalKind}; +use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::DebugInfoCodegenMethods; -use rustc_codegen_ssa::{ModuleCodegen, ModuleKind}; use rustc_middle::dep_graph; use rustc_middle::mir::mono::Linkage; #[cfg(feature = "master")] @@ -237,16 +237,15 @@ pub fn compile_codegen_unit( } } - ModuleCodegen { - name: cgu_name.to_string(), - module_llvm: GccContext { + ModuleCodegen::new_regular( + cgu_name.to_string(), + GccContext { context: Arc::new(SyncContext::new(context)), relocation_model: tcx.sess.relocation_model(), should_combine_object_files: false, temp_dir: None, }, - kind: ModuleKind::Regular, - } + ) } (module, cost) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 6676afe489f2..dfad2db44fae 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -306,11 +306,8 @@ fn fat_lto( assert!(!serialized_modules.is_empty(), "must have at least one serialized module"); let (buffer, name) = serialized_modules.remove(0); info!("no in-memory regular modules to choose from, parsing {:?}", name); - ModuleCodegen { - module_llvm: ModuleLlvm::parse(cgcx, &name, buffer.data(), dcx)?, - name: name.into_string().unwrap(), - kind: ModuleKind::Regular, - } + let llvm_module = ModuleLlvm::parse(cgcx, &name, buffer.data(), dcx)?; + ModuleCodegen::new_regular(name.into_string().unwrap(), llvm_module) } }; { @@ -778,11 +775,7 @@ pub(crate) unsafe fn optimize_thin_module( // crates but for locally codegened modules we may be able to reuse // that LLVM Context and Module. let module_llvm = ModuleLlvm::parse(cgcx, module_name, thin_module.data(), dcx)?; - let mut module = ModuleCodegen { - module_llvm, - name: thin_module.name().to_string(), - kind: ModuleKind::Regular, - }; + let mut module = ModuleCodegen::new_regular(thin_module.name(), module_llvm); { let target = &*module.module_llvm.tm; let llmod = module.module_llvm.llmod(); diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index d35c7945baec..6bd27914dbd1 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -13,10 +13,10 @@ use std::time::Instant; +use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::*; -use rustc_codegen_ssa::{ModuleCodegen, ModuleKind}; use rustc_data_structures::small_c_str::SmallCStr; use rustc_middle::dep_graph; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; @@ -133,11 +133,7 @@ pub(crate) fn compile_codegen_unit( } } - ModuleCodegen { - name: cgu_name.to_string(), - module_llvm: llvm_module, - kind: ModuleKind::Regular, - } + ModuleCodegen::new_regular(cgu_name.to_string(), llvm_module) } (module, cost) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 40238f4b4915..2e1dd66f1b4b 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -686,7 +686,7 @@ pub fn codegen_crate( submit_codegened_module_to_llvm( &backend, &ongoing_codegen.coordinator.sender, - ModuleCodegen { name: llmod_id, module_llvm, kind: ModuleKind::Allocator }, + ModuleCodegen::new_allocator(llmod_id, module_llvm), cost, ); } diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 9d2ac219d592..3ddae7c670a5 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -78,6 +78,14 @@ pub struct ModuleCodegen { } impl ModuleCodegen { + pub fn new_regular(name: impl Into, module: M) -> Self { + Self { name: name.into(), module_llvm: module, kind: ModuleKind::Regular } + } + + pub fn new_allocator(name: impl Into, module: M) -> Self { + Self { name: name.into(), module_llvm: module, kind: ModuleKind::Allocator } + } + pub fn into_compiled_module( self, emit_obj: bool, From da50297a6ea8454b0e36ef110370bec914c408d1 Mon Sep 17 00:00:00 2001 From: DianQK Date: Thu, 6 Feb 2025 22:00:19 +0800 Subject: [PATCH 236/991] Save pre-link bitcode to `ModuleCodegen` --- compiler/rustc_codegen_gcc/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 4 ++++ compiler/rustc_codegen_llvm/src/back/write.rs | 21 ++++++------------- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- compiler/rustc_codegen_ssa/src/back/write.rs | 8 +++++-- compiler/rustc_codegen_ssa/src/lib.rs | 16 ++++++++++++-- .../rustc_codegen_ssa/src/traits/write.rs | 2 +- 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 6455bcec6851..9d91aab72ab3 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -393,7 +393,7 @@ impl WriteBackendMethods for GccCodegenBackend { unsafe fn optimize( _cgcx: &CodegenContext, _dcx: DiagCtxtHandle<'_>, - module: &ModuleCodegen, + module: &mut ModuleCodegen, config: &ModuleConfig, ) -> Result<(), FatalError> { module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level)); diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index dfad2db44fae..03fb44325e29 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -776,6 +776,10 @@ pub(crate) unsafe fn optimize_thin_module( // that LLVM Context and Module. let module_llvm = ModuleLlvm::parse(cgcx, module_name, thin_module.data(), dcx)?; let mut module = ModuleCodegen::new_regular(thin_module.name(), module_llvm); + // Given that the newly created module lacks a thinlto buffer for embedding, we need to re-add it here. + if cgcx.config(ModuleKind::Regular).embed_bitcode() { + module.thin_lto_buffer = Some(thin_module.data().to_vec()); + } { let target = &*module.module_llvm.tm; let llmod = module.module_llvm.llmod(); diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 1ad256d3b75d..c5208f7c538f 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -689,7 +689,7 @@ pub(crate) unsafe fn llvm_optimize( pub(crate) unsafe fn optimize( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, - module: &ModuleCodegen, + module: &mut ModuleCodegen, config: &ModuleConfig, ) -> Result<(), FatalError> { let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &*module.name); @@ -745,10 +745,7 @@ pub(crate) unsafe fn optimize( }?; if let Some(thin_lto_buffer) = thin_lto_buffer { let thin_lto_buffer = unsafe { ThinBuffer::from_raw_ptr(thin_lto_buffer) }; - let thin_bc_out = cgcx.output_filenames.temp_path(OutputType::ThinBitcode, module_name); - if let Err(err) = fs::write(&thin_bc_out, thin_lto_buffer.data()) { - dcx.emit_err(WriteBytecode { path: &thin_bc_out, err }); - } + module.thin_lto_buffer = Some(thin_lto_buffer.data().to_vec()); let bc_summary_out = cgcx.output_filenames.temp_path(OutputType::ThinLinkBitcode, module_name); if config.emit_thin_lto_summary @@ -848,20 +845,14 @@ pub(crate) unsafe fn codegen( } } - if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) - && module.kind == ModuleKind::Regular - { + if config.embed_bitcode() && module.kind == ModuleKind::Regular { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_embed_bitcode", &*module.name); - let thin_bc_out = - cgcx.output_filenames.temp_path(OutputType::ThinBitcode, module_name); - assert!(thin_bc_out.exists(), "cannot find {:?} as embedded bitcode", thin_bc_out); - let data = fs::read(&thin_bc_out).unwrap(); - debug!("removing embed bitcode file {:?}", thin_bc_out); - ensure_removed(dcx, &thin_bc_out); + let thin_bc = + module.thin_lto_buffer.as_deref().expect("cannot find embedded bitcode"); unsafe { - embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, &data); + embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, &thin_bc); } } } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index e9e1b644f183..c88372db4913 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -194,7 +194,7 @@ impl WriteBackendMethods for LlvmCodegenBackend { unsafe fn optimize( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, - module: &ModuleCodegen, + module: &mut ModuleCodegen, config: &ModuleConfig, ) -> Result<(), FatalError> { unsafe { back::write::optimize(cgcx, dcx, module, config) } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 47e7dec48e4f..927c9d1fa1ec 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -278,6 +278,10 @@ impl ModuleConfig { || self.emit_obj == EmitObj::Bitcode || self.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) } + + pub fn embed_bitcode(&self) -> bool { + self.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) + } } /// Configuration passed to the function returned by the `target_machine_factory`. @@ -880,14 +884,14 @@ pub(crate) fn compute_per_cgu_lto_type( fn execute_optimize_work_item( cgcx: &CodegenContext, - module: ModuleCodegen, + mut module: ModuleCodegen, module_config: &ModuleConfig, ) -> Result, FatalError> { let dcx = cgcx.create_dcx(); let dcx = dcx.handle(); unsafe { - B::optimize(cgcx, dcx, &module, module_config)?; + B::optimize(cgcx, dcx, &mut module, module_config)?; } // After we've done the initial round of optimizations we need to diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 3ddae7c670a5..4e758bfdec39 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -75,15 +75,27 @@ pub struct ModuleCodegen { pub name: String, pub module_llvm: M, pub kind: ModuleKind, + /// Saving the ThinLTO buffer for embedding in the object file. + pub thin_lto_buffer: Option>, } impl ModuleCodegen { pub fn new_regular(name: impl Into, module: M) -> Self { - Self { name: name.into(), module_llvm: module, kind: ModuleKind::Regular } + Self { + name: name.into(), + module_llvm: module, + kind: ModuleKind::Regular, + thin_lto_buffer: None, + } } pub fn new_allocator(name: impl Into, module: M) -> Self { - Self { name: name.into(), module_llvm: module, kind: ModuleKind::Allocator } + Self { + name: name.into(), + module_llvm: module, + kind: ModuleKind::Allocator, + thin_lto_buffer: None, + } } pub fn into_compiled_module( diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index 97fe614aa10c..c77efdd17287 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -40,7 +40,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { unsafe fn optimize( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, - module: &ModuleCodegen, + module: &mut ModuleCodegen, config: &ModuleConfig, ) -> Result<(), FatalError>; fn optimize_fat( From a897cc03519c83e1c426be491c9a1bea63609e16 Mon Sep 17 00:00:00 2001 From: DianQK Date: Thu, 6 Feb 2025 22:01:08 +0800 Subject: [PATCH 237/991] Remove unused `OutputType::ThinLinkBitcode` --- compiler/rustc_codegen_cranelift/src/driver/aot.rs | 2 +- compiler/rustc_codegen_ssa/src/back/write.rs | 3 --- compiler/rustc_session/src/config.rs | 13 +------------ 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 366e83853e51..a52b18573b15 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -210,7 +210,7 @@ fn produce_final_output_artifacts( // to get rid of it. for output_type in crate_output.outputs.keys() { match *output_type { - OutputType::Bitcode | OutputType::ThinLinkBitcode | OutputType::ThinBitcode => { + OutputType::Bitcode | OutputType::ThinLinkBitcode => { // Cranelift doesn't have bitcode // user_wants_bitcode = true; // // Copy to .bc, but always keep the .0.bc. There is a later diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 927c9d1fa1ec..b3ad3370cf95 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -630,9 +630,6 @@ fn produce_final_output_artifacts( // them for making an rlib. copy_if_one_unit(OutputType::Bitcode, true); } - OutputType::ThinBitcode => { - copy_if_one_unit(OutputType::ThinBitcode, true); - } OutputType::ThinLinkBitcode => { copy_if_one_unit(OutputType::ThinLinkBitcode, false); } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 23553a5540c6..00f79a00e68f 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -544,9 +544,6 @@ pub enum OutputType { Bitcode, /// This is the summary or index data part of the ThinLTO bitcode. ThinLinkBitcode, - /// This is ThinLTO's pre-link bitcode, primarily used for embedding bitcode in object files. - /// This can also be used for FatLTO. - ThinBitcode, Assembly, LlvmAssembly, Mir, @@ -577,7 +574,6 @@ impl OutputType { OutputType::Exe | OutputType::DepInfo | OutputType::Metadata => true, OutputType::Bitcode | OutputType::ThinLinkBitcode - | OutputType::ThinBitcode | OutputType::Assembly | OutputType::LlvmAssembly | OutputType::Mir @@ -589,7 +585,6 @@ impl OutputType { match *self { OutputType::Bitcode => "llvm-bc", OutputType::ThinLinkBitcode => "thin-link-bitcode", - OutputType::ThinBitcode => "thin-llvm-bc", OutputType::Assembly => "asm", OutputType::LlvmAssembly => "llvm-ir", OutputType::Mir => "mir", @@ -607,7 +602,6 @@ impl OutputType { "mir" => OutputType::Mir, "llvm-bc" => OutputType::Bitcode, "thin-link-bitcode" => OutputType::ThinLinkBitcode, - "thin-llvm-bc" => OutputType::ThinBitcode, "obj" => OutputType::Object, "metadata" => OutputType::Metadata, "link" => OutputType::Exe, @@ -618,10 +612,9 @@ impl OutputType { fn shorthands_display() -> String { format!( - "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`", + "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`", OutputType::Bitcode.shorthand(), OutputType::ThinLinkBitcode.shorthand(), - OutputType::ThinBitcode.shorthand(), OutputType::Assembly.shorthand(), OutputType::LlvmAssembly.shorthand(), OutputType::Mir.shorthand(), @@ -636,7 +629,6 @@ impl OutputType { match *self { OutputType::Bitcode => "bc", OutputType::ThinLinkBitcode => "indexing.o", - OutputType::ThinBitcode => "thin.bc", OutputType::Assembly => "s", OutputType::LlvmAssembly => "ll", OutputType::Mir => "mir", @@ -655,7 +647,6 @@ impl OutputType { | OutputType::DepInfo => true, OutputType::Bitcode | OutputType::ThinLinkBitcode - | OutputType::ThinBitcode | OutputType::Object | OutputType::Metadata | OutputType::Exe => false, @@ -743,7 +734,6 @@ impl OutputTypes { self.0.keys().any(|k| match *k { OutputType::Bitcode | OutputType::ThinLinkBitcode - | OutputType::ThinBitcode | OutputType::Assembly | OutputType::LlvmAssembly | OutputType::Mir @@ -758,7 +748,6 @@ impl OutputTypes { self.0.keys().any(|k| match *k { OutputType::Bitcode | OutputType::ThinLinkBitcode - | OutputType::ThinBitcode | OutputType::Assembly | OutputType::LlvmAssembly | OutputType::Mir From 4ab9329699392901e7b0f2b3000923a6e15380cb Mon Sep 17 00:00:00 2001 From: Tim Hutt Date: Fri, 21 Feb 2025 20:01:33 +0000 Subject: [PATCH 238/991] Include private items in completions for local crates Don't filter out private items when completing paths in the same crate. Instead respect the `privateEditable` setting. Fixes #9850 --- .../crates/ide-completion/src/completions/expr.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index e71017517019..365d2dde7e94 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -147,7 +147,10 @@ pub(crate) fn complete_expr_path( }); match resolution { hir::PathResolution::Def(hir::ModuleDef::Module(module)) => { - let module_scope = module.scope(ctx.db, Some(ctx.module)); + // Set visible_from to None so private items are returned. + // They will be possibly filtered out in add_path_resolution() + // via def_is_visible(). + let module_scope = module.scope(ctx.db, None); for (name, def) in module_scope { if scope_def_applicable(def) { acc.add_path_resolution( From 5d6a6e70e34e9b39e1bccb1c48e7b7c5264c838a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 4 Feb 2025 21:54:15 +0800 Subject: [PATCH 239/991] compiletest: disambiguate between root build dir vs test suite specific build dir - Introduce and use `--build-{root,test-suite-root}` over `--build-base`. - A few minor cleanups. --- src/tools/compiletest/src/common.rs | 20 +++++++++++------- src/tools/compiletest/src/header.rs | 10 +++++---- src/tools/compiletest/src/header/tests.rs | 3 ++- src/tools/compiletest/src/lib.rs | 21 ++++++++++++++----- src/tools/compiletest/src/runtest.rs | 16 +++++++------- src/tools/compiletest/src/runtest/run_make.rs | 17 ++++++--------- src/tools/compiletest/src/runtest/ui.rs | 2 +- 7 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 98ab7adf5a72..b302c6a49f58 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -220,8 +220,10 @@ pub struct Config { /// The directory containing the test suite sources. Must be a subdirectory of `src_root`. pub src_test_suite_root: PathBuf, - /// The directory where programs should be built - pub build_base: PathBuf, + /// Root build directory (e.g. `build/`). + pub build_root: PathBuf, + /// Test suite specific build directory (e.g. `build/host/test/ui/`). + pub build_test_suite_root: PathBuf, /// The directory containing the compiler sysroot pub sysroot_base: PathBuf, @@ -347,7 +349,7 @@ pub struct Config { /// If true, this will generate a coverage file with UI test files that run `MachineApplicable` /// diagnostics but are missing `run-rustfix` annotations. The generated coverage file is - /// created in `//rustfix_missing_coverage.txt` + /// created in `/rustfix_missing_coverage.txt` pub rustfix_coverage: bool, /// whether to run `tidy` (html-tidy) when a rustdoc test fails @@ -812,12 +814,16 @@ pub const UI_STDERR_16: &str = "16bit.stderr"; pub const UI_COVERAGE: &str = "coverage"; pub const UI_COVERAGE_MAP: &str = "cov-map"; -/// Absolute path to the directory where all output for all tests in the given -/// `relative_dir` group should reside. Example: -/// /path/to/build/host-tuple/test/ui/relative/ +/// Absolute path to the directory where all output for all tests in the given `relative_dir` group +/// should reside. Example: +/// +/// ```text +/// /path/to/build/host-tuple/test/ui/relative/ +/// ``` +/// /// This is created early when tests are collected to avoid race conditions. pub fn output_relative_path(config: &Config, relative_dir: &Path) -> PathBuf { - config.build_base.join(relative_dir) + config.build_test_suite_root.join(relative_dir) } /// Generates a unique name for the test, such as `testname.revision.mode`. diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 3bdf37a1f294..53ee901b8bc4 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1070,10 +1070,11 @@ impl Config { } } +// FIXME(jieyouxu): fix some of these variable names to more accurately reflect what they do. fn expand_variables(mut value: String, config: &Config) -> String { const CWD: &str = "{{cwd}}"; const SRC_BASE: &str = "{{src-base}}"; - const BUILD_BASE: &str = "{{build-base}}"; + const TEST_SUITE_BUILD_BASE: &str = "{{build-base}}"; const RUST_SRC_BASE: &str = "{{rust-src-base}}"; const SYSROOT_BASE: &str = "{{sysroot-base}}"; const TARGET_LINKER: &str = "{{target-linker}}"; @@ -1088,12 +1089,13 @@ fn expand_variables(mut value: String, config: &Config) -> String { value = value.replace(SRC_BASE, &config.src_test_suite_root.to_str().unwrap()); } - if value.contains(BUILD_BASE) { - value = value.replace(BUILD_BASE, &config.build_base.to_string_lossy()); + if value.contains(TEST_SUITE_BUILD_BASE) { + value = + value.replace(TEST_SUITE_BUILD_BASE, &config.build_test_suite_root.to_str().unwrap()); } if value.contains(SYSROOT_BASE) { - value = value.replace(SYSROOT_BASE, &config.sysroot_base.to_string_lossy()); + value = value.replace(SYSROOT_BASE, &config.sysroot_base.to_str().unwrap()); } if value.contains(TARGET_LINKER) { diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index c9536b7a19b7..e47ea001e7e6 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -155,7 +155,8 @@ impl ConfigBuilder { "--jsondocck-path=", "--src-root=", "--src-test-suite-root=", - "--build-base=", + "--build-root=", + "--build-test-suite-root=", "--sysroot-base=", "--cc=c", "--cxx=c++", diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 979821701385..9dff7047bc4a 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -63,7 +63,8 @@ pub fn parse_config(args: Vec) -> Config { .optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR") .reqopt("", "src-root", "directory containing sources", "PATH") .reqopt("", "src-test-suite-root", "directory containing test suite sources", "PATH") - .reqopt("", "build-base", "directory to deposit test outputs", "PATH") + .reqopt("", "build-root", "path to root build directory", "PATH") + .reqopt("", "build-test-suite-root", "path to test suite specific build directory", "PATH") .reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH") .reqopt("", "stage", "stage number under test", "N") .reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET") @@ -157,7 +158,7 @@ pub fn parse_config(args: Vec) -> Config { "", "rustfix-coverage", "enable this to generate a Rustfix coverage file, which is saved in \ - `.//rustfix_missing_coverage.txt`", + `.//rustfix_missing_coverage.txt`", ) .optflag("", "force-rerun", "rerun tests even if the inputs are unchanged") .optflag("", "only-modified", "only run tests that result been modified") @@ -309,6 +310,10 @@ pub fn parse_config(args: Vec) -> Config { src_test_suite_root.display() ); + let build_root = opt_path(matches, "build-root"); + let build_test_suite_root = opt_path(matches, "build-test-suite-root"); + assert!(build_test_suite_root.starts_with(&build_root)); + Config { bless: matches.opt_present("bless"), compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")), @@ -327,7 +332,9 @@ pub fn parse_config(args: Vec) -> Config { src_root, src_test_suite_root, - build_base: opt_path(matches, "build-base"), + build_root, + build_test_suite_root, + sysroot_base: opt_path(matches, "sysroot-base"), stage, @@ -438,7 +445,11 @@ pub fn log_config(config: &Config) { logv(c, format!("src_root: {}", config.src_root.display())); logv(c, format!("src_test_suite_root: {}", config.src_test_suite_root.display())); - logv(c, format!("build_base: {:?}", config.build_base.display())); + logv(c, format!("build_root: {}", config.build_root.display())); + logv(c, format!("build_test_suite_root: {}", config.build_test_suite_root.display())); + + logv(c, format!("sysroot_base: {}", config.sysroot_base.display())); + logv(c, format!("stage: {}", config.stage)); logv(c, format!("stage_id: {}", config.stage_id)); logv(c, format!("mode: {}", config.mode)); @@ -488,7 +499,7 @@ pub fn run_tests(config: Arc) { // we first make sure that the coverage file does not exist. // It will be created later on. if config.rustfix_coverage { - let mut coverage_file_path = config.build_base.clone(); + let mut coverage_file_path = config.build_test_suite_root.clone(); coverage_file_path.push("rustfix_missing_coverage.txt"); if coverage_file_path.exists() { if let Err(e) = fs::remove_file(&coverage_file_path) { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 536e19bc4933..f36d43b211ff 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -535,7 +535,9 @@ impl<'test> TestCx<'test> { .arg(&out_dir) .arg(&format!("--target={}", target)) .arg("-L") - .arg(&self.config.build_base) + // FIXME(jieyouxu): this search path seems questionable. Is this intended for + // `rust_test_helpers` in ui tests? + .arg(&self.config.build_test_suite_root) .arg("-L") .arg(aux_dir) .arg("-A") @@ -1366,7 +1368,7 @@ impl<'test> TestCx<'test> { // Note: avoid adding a subdirectory of an already filtered directory here, otherwise the // same slice of text will be double counted and the truncation might not happen. add_path(&self.config.src_test_suite_root); - add_path(&self.config.build_base); + add_path(&self.config.build_test_suite_root); read2_abbreviated(child, &filter_paths_from_len).expect("failed to read output") } @@ -1421,7 +1423,7 @@ impl<'test> TestCx<'test> { } fn get_mir_dump_dir(&self) -> PathBuf { - let mut mir_dump_dir = PathBuf::from(self.config.build_base.as_path()); + let mut mir_dump_dir = self.config.build_test_suite_root.clone(); debug!("input_file: {:?}", self.testpaths.file); mir_dump_dir.push(&self.testpaths.relative_dir); mir_dump_dir.push(self.testpaths.file.file_stem().unwrap()); @@ -2410,14 +2412,10 @@ impl<'test> TestCx<'test> { let rust_src_dir = rust_src_dir.read_link().unwrap_or(rust_src_dir.to_path_buf()); normalize_path(&rust_src_dir.join("library"), "$SRC_DIR_REAL"); - // Paths into the build directory - let test_build_dir = &self.config.build_base; - let parent_build_dir = test_build_dir.parent().unwrap().parent().unwrap().parent().unwrap(); - // eg. /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui - normalize_path(test_build_dir, "$TEST_BUILD_DIR"); + normalize_path(&self.config.build_test_suite_root, "$TEST_BUILD_DIR"); // eg. /home/user/rust/build - normalize_path(parent_build_dir, "$BUILD_DIR"); + normalize_path(&self.config.build_root, "$BUILD_DIR"); if json { // escaped newlines in json strings should be readable diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 74e6af36ea1d..9bb3993223e2 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -179,12 +179,7 @@ impl TestCx<'_> { // library. // 2. We need to run the recipe binary. - // `self.config.build_base` is actually the build base folder + "test" + test suite name, it - // looks like `build//test/run-make`. But we want `build//`. Note - // that the `build` directory does not need to be called `build`, nor does it need to be - // under `src_root`, so we must compute it based off of `self.config.build_base`. - let build_root = - self.config.build_base.parent().and_then(Path::parent).unwrap().to_path_buf(); + let host_build_root = self.config.build_root.join(&self.config.host); // We construct the following directory tree for each rmake.rs test: // ``` @@ -242,10 +237,10 @@ impl TestCx<'_> { let stage_number = self.config.stage; - let stage_tools_bin = build_root.join(format!("stage{stage_number}-tools-bin")); + let stage_tools_bin = host_build_root.join(format!("stage{stage_number}-tools-bin")); let support_lib_path = stage_tools_bin.join("librun_make_support.rlib"); - let stage_tools = build_root.join(format!("stage{stage_number}-tools")); + let stage_tools = host_build_root.join(format!("stage{stage_number}-tools")); let support_lib_deps = stage_tools.join(&self.config.host).join("release").join("deps"); let support_lib_deps_deps = stage_tools.join("release").join("deps"); @@ -311,7 +306,7 @@ impl TestCx<'_> { // to work correctly. // // See for more background. - let stage0_sysroot = build_root.join("stage0-sysroot"); + let stage0_sysroot = host_build_root.join("stage0-sysroot"); if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() { rustc.arg("--sysroot").arg(&stage0_sysroot); } @@ -326,7 +321,7 @@ impl TestCx<'_> { // provided through env vars. // Compute stage-specific standard library paths. - let stage_std_path = build_root.join(format!("stage{stage_number}")).join("lib"); + let stage_std_path = host_build_root.join(format!("stage{stage_number}")).join("lib"); // Compute dynamic library search paths for recipes. let recipe_dylib_search_paths = { @@ -372,7 +367,7 @@ impl TestCx<'_> { // Provide path to sources root. .env("SOURCE_ROOT", &self.config.src_root) // Path to the host build directory. - .env("BUILD_ROOT", &build_root) + .env("BUILD_ROOT", &host_build_root) // Provide path to stage-corresponding rustc. .env("RUSTC", &self.config.rustc_path) // Provide the directory to libraries that are needed to run the *compiler*. This is not diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index 0c6d46188e6f..3329e10745f8 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -66,7 +66,7 @@ impl TestCx<'_> { && !self.props.run_rustfix && !self.props.rustfix_only_machine_applicable { - let mut coverage_file_path = self.config.build_base.clone(); + let mut coverage_file_path = self.config.build_test_suite_root.clone(); coverage_file_path.push("rustfix_missing_coverage.txt"); debug!("coverage_file_path: {}", coverage_file_path.display()); From 5238337d522351eaa71659c3865b6bd7cf9341c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 4 Feb 2025 21:28:32 +0800 Subject: [PATCH 240/991] bootstrap: remove `--build-base` and use `--build-root` and `--build-test-suite-root` instead --- src/bootstrap/src/core/build_steps/test.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 604f9e73b458..cdb1ae70ab61 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1774,7 +1774,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--src-root").arg(&builder.src); cmd.arg("--src-test-suite-root").arg(builder.src.join("tests").join(suite)); - cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite)); + // N.B. it's important to distinguish between the *root* build directory, the *host* build + // directory immediately under the root build directory, and the test-suite-specific build + // directory. + cmd.arg("--build-root").arg(&builder.out); + cmd.arg("--build-test-suite-root").arg(testdir(builder, compiler.host).join(suite)); // When top stage is 0, that means that we're testing an externally provided compiler. // In that case we need to use its specific sysroot for tests to pass. From 7d2e4e4b6966ae4646e4f87800dafe6cc1b839c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 4 Feb 2025 21:30:36 +0800 Subject: [PATCH 241/991] bootstrap: remove redundant `to_path_buf()` --- src/bootstrap/src/core/build_steps/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index cdb1ae70ab61..2053e9c97d74 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1785,7 +1785,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let sysroot = if builder.top_stage == 0 { builder.initial_sysroot.clone() } else { - builder.sysroot(compiler).to_path_buf() + builder.sysroot(compiler) }; cmd.arg("--sysroot-base").arg(sysroot); From 6fc19785f7d4d0b91304a8c90348a2dbfd24d664 Mon Sep 17 00:00:00 2001 From: Tapan Prakash Date: Sun, 23 Feb 2025 22:17:18 +0530 Subject: [PATCH 242/991] fixed by differentiating glob export --- src/librustdoc/passes/propagate_stability.rs | 12 +++++++++ tests/rustdoc/inline_local/staged-inline.rs | 28 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index 9c958710c420..8cf39afd55c5 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -39,6 +39,16 @@ impl DocFolder for StabilityPropagator<'_, '_> { let item_stability = self.cx.tcx.lookup_stability(def_id); let inline_stability = item.inline_stmt_id.and_then(|did| self.cx.tcx.lookup_stability(did)); + let is_glob_export = item.inline_stmt_id.and_then(|id| { + let hir_id = self.cx.tcx.local_def_id_to_hir_id(id); + Some(matches!( + self.cx.tcx.hir_node(hir_id), + rustc_hir::Node::Item(rustc_hir::Item { + kind: rustc_hir::ItemKind::Use(_, rustc_hir::UseKind::Glob), + .. + }) + )) + }); let own_stability = if let Some(item_stab) = item_stability && let StabilityLevel::Stable { since: _, allowed_through_unstable_modules } = item_stab.level @@ -47,6 +57,8 @@ impl DocFolder for StabilityPropagator<'_, '_> { since: inline_since, allowed_through_unstable_modules: _, } = inline_stab.level + && let Some(is_global_export) = is_glob_export + && !is_global_export { inline_stab.level = StabilityLevel::Stable { since: inline_since, diff --git a/tests/rustdoc/inline_local/staged-inline.rs b/tests/rustdoc/inline_local/staged-inline.rs index f2131ad5f944..ffe9a5d7c3c2 100644 --- a/tests/rustdoc/inline_local/staged-inline.rs +++ b/tests/rustdoc/inline_local/staged-inline.rs @@ -16,3 +16,31 @@ pub mod ffi { //@ has "foo/struct.CStr.html" "//span[@class='sub-heading']/span[@class='since']" "1.0.0" //@ !has - "//span[@class='sub-heading']/span[@class='since']" "1.99.0" pub use ffi::CStr; + +// https://github.com/rust-lang/rust/issues/137141 +#[stable(feature = "futures_api", since = "1.36.0")] +//@ has "foo/task/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.36.0" +//@ !has - "//span[@class='sub-heading']/span[@class='since']" "1.0.0" +pub mod task { + + #[doc(inline)] + #[stable(feature = "futures_api", since = "1.36.0")] + //@ has "foo/task/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.36.0" + //@ has "foo/task/ready/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.64.0" + pub use core::task::*; +} + +#[stable(feature = "futures_api", since = "1.36.0")] +//@ has "foo/core/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.36.0" +//@ !has - "//span[@class='sub-heading']/span[@class='since']" "1.0.0" +pub mod core { + #[stable(feature = "futures_api", since = "1.36.0")] + //@ has "foo/core/task/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.36.0" + pub mod task { + + #[stable(feature = "ready_macro", since = "1.64.0")] + //@ has "foo/core/task/ready/index.html" "//span[@class='sub-heading']/span[@class='since']" "1.64.0" + pub mod ready { + } + } +} \ No newline at end of file From afc89a1e021c99bdcd89a71c4c93ff6f3a2072c8 Mon Sep 17 00:00:00 2001 From: Tapan Prakash Date: Sun, 23 Feb 2025 22:24:00 +0530 Subject: [PATCH 243/991] Fixed tidy error --- tests/rustdoc/inline_local/staged-inline.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rustdoc/inline_local/staged-inline.rs b/tests/rustdoc/inline_local/staged-inline.rs index ffe9a5d7c3c2..d0dc3f9eea7f 100644 --- a/tests/rustdoc/inline_local/staged-inline.rs +++ b/tests/rustdoc/inline_local/staged-inline.rs @@ -43,4 +43,4 @@ pub mod core { pub mod ready { } } -} \ No newline at end of file +} From e4de3acb971ce3c22d2cea43a8664bc570a9b3a8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Feb 2025 07:50:28 +0100 Subject: [PATCH 244/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index a2a2f28ea71c..6cd39fabeeee 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -17c1c329a5512d718b67ef6797538b154016cd34 +e0be1a02626abef2878cb7f4aaef7ae409477112 From 23c6b93de8fdee21f50bfd20b8e9a30f24234fbe Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 23 Feb 2025 23:18:04 -0800 Subject: [PATCH 245/991] Don't re-`assume` in `transmute`s that don't change niches --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 7 ++++++ tests/codegen/intrinsics/transmute.rs | 25 ++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index daa4fa90ed70..de3cd27c9432 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -386,6 +386,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ) -> Bx::Value { assert_eq!(from_scalar.size(self.cx), to_scalar.size(self.cx)); + // While optimizations will remove no-op transmutes, they might still be + // there in debug or things that aren't no-op in MIR because they change + // the Rust type but not the underlying layout/niche. + if from_scalar == to_scalar && from_backend_ty == to_backend_ty { + return imm; + } + use abi::Primitive::*; imm = bx.from_immediate(imm); diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index ff297b270657..4849b88c09c2 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -10,6 +10,7 @@ use std::intrinsics::mir::*; use std::intrinsics::{transmute, transmute_unchecked}; use std::mem::MaybeUninit; +use std::num::NonZero; // FIXME(LLVM18REMOVED): `trunc nuw` doesn't exist in LLVM 18, so once we no // longer support it the optional flag checks can be changed to required. @@ -470,3 +471,27 @@ pub unsafe fn check_from_overalign(x: HighAlignScalar) -> u64 { // CHECK: ret i64 %[[VAL]] transmute(x) } + +#[repr(transparent)] +struct Level1(std::num::NonZero); +#[repr(transparent)] +struct Level2(Level1); +#[repr(transparent)] +struct Level3(Level2); + +// CHECK-LABEL: @repeatedly_transparent_transmute +// CHECK-SAME: (i32{{.+}}%[[ARG:[^)]+]]) +#[no_mangle] +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub unsafe fn repeatedly_transparent_transmute(x: NonZero) -> Level3 { + // CHECK: start + // CHECK-NEXT: ret i32 %[[ARG]] + mir! { + { + let A = CastTransmute::, Level1>(x); + let B = CastTransmute::(A); + RET = CastTransmute::(B); + Return() + } + } +} From 86b53db3e618fb89df012748180144c3c586b6e0 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Feb 2025 16:41:38 +0000 Subject: [PATCH 246/991] type_ir: remove redundant part of comment This refers to a `PredicatePolarity::Reserved` which no longer exists. --- compiler/rustc_type_ir/src/predicate.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 51790b13ec77..46385ca3a6fd 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -131,8 +131,6 @@ pub struct TraitPredicate { /// If polarity is Negative: we are proving that a negative impl of this trait /// exists. (Note that coherence also checks whether negative impls of supertraits /// exist via a series of predicates.) - /// - /// If polarity is Reserved: that's a bug. pub polarity: PredicatePolarity, } From 1ee134f10dafe4374ff0de6d50bedcb01fee5296 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 13 Feb 2025 15:10:49 +0000 Subject: [PATCH 247/991] feature: fix typo in attribute description The force inlining attribute isn't is never used with `#![..]` attribute syntax, only `#[..]` syntax. --- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- tests/ui/force-inlining/gate.rs | 4 ++-- tests/ui/force-inlining/gate.stderr | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 6d16dc00ef4e..306535bf7642 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1011,7 +1011,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), rustc_attr!( rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes, - "#![rustc_force_inline] forces a free function to be inlined" + "#[rustc_force_inline] forces a free function to be inlined" ), // ========================================================================== diff --git a/tests/ui/force-inlining/gate.rs b/tests/ui/force-inlining/gate.rs index d6a01a74a44b..cea094c14f2d 100644 --- a/tests/ui/force-inlining/gate.rs +++ b/tests/ui/force-inlining/gate.rs @@ -2,11 +2,11 @@ #![allow(internal_features)] #[rustc_force_inline] -//~^ ERROR #![rustc_force_inline] forces a free function to be inlined +//~^ ERROR #[rustc_force_inline] forces a free function to be inlined pub fn bare() { } #[rustc_force_inline = "the test requires it"] -//~^ ERROR #![rustc_force_inline] forces a free function to be inlined +//~^ ERROR #[rustc_force_inline] forces a free function to be inlined pub fn justified() { } diff --git a/tests/ui/force-inlining/gate.stderr b/tests/ui/force-inlining/gate.stderr index e3973a08c232..964d43fa18f6 100644 --- a/tests/ui/force-inlining/gate.stderr +++ b/tests/ui/force-inlining/gate.stderr @@ -1,4 +1,4 @@ -error[E0658]: #![rustc_force_inline] forces a free function to be inlined +error[E0658]: #[rustc_force_inline] forces a free function to be inlined --> $DIR/gate.rs:4:1 | LL | #[rustc_force_inline] @@ -7,7 +7,7 @@ LL | #[rustc_force_inline] = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: #![rustc_force_inline] forces a free function to be inlined +error[E0658]: #[rustc_force_inline] forces a free function to be inlined --> $DIR/gate.rs:9:1 | LL | #[rustc_force_inline = "the test requires it"] From 5afa6a111bcf8552b8de15d1aec060580add640f Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 4 Dec 2024 12:51:59 +0000 Subject: [PATCH 248/991] ssa/mono: deduplicate `type_has_metadata` The implementation of the `type_has_metadata` function is duplicated in `rustc_codegen_ssa` and `rustc_monomorphize`, so move this to `rustc_middle`. --- compiler/rustc_codegen_ssa/src/mir/place.rs | 8 ++++++-- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 4 ++-- compiler/rustc_codegen_ssa/src/traits/type_.rs | 15 +-------------- compiler/rustc_middle/src/ty/util.rs | 14 ++++++++++++++ compiler/rustc_monomorphize/src/collector.rs | 13 +------------ 5 files changed, 24 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index edd09b9c3c5f..00e01e47fee3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -2,7 +2,7 @@ use rustc_abi::Primitive::{Int, Pointer}; use rustc_abi::{Align, BackendRepr, FieldsShape, Size, TagEncoding, VariantIdx, Variants}; use rustc_middle::mir::PlaceTy; use rustc_middle::mir::interpret::Scalar; -use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Ty}; use rustc_middle::{bug, mir}; use tracing::{debug, instrument}; @@ -168,7 +168,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { }; let val = PlaceValue { llval, - llextra: if bx.cx().type_has_metadata(field.ty) { self.val.llextra } else { None }, + llextra: if bx.cx().tcx().type_has_metadata(field.ty, bx.cx().typing_env()) { + self.val.llextra + } else { + None + }, align: effective_field_align, }; val.with_type(field) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 1eebe04225be..d24e48b37a46 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -3,7 +3,7 @@ use std::assert_matches::assert_matches; use arrayvec::ArrayVec; use rustc_abi::{self as abi, FIRST_VARIANT, FieldIdx}; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_middle::{bug, mir, span_bug}; use rustc_session::config::OptLevel; @@ -878,7 +878,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = cg_place.layout.ty; assert!( - if bx.cx().type_has_metadata(ty) { + if bx.cx().tcx().type_has_metadata(ty, bx.cx().typing_env()) { matches!(val, OperandValue::Pair(..)) } else { matches!(val, OperandValue::Immediate(..)) diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index c178ebc596e1..fbd927d0d663 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -1,7 +1,7 @@ use rustc_abi::{AddressSpace, Float, Integer, Reg}; use rustc_middle::bug; +use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout}; -use rustc_middle::ty::{self, Ty}; use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi}; use super::BackendTypes; @@ -84,19 +84,6 @@ pub trait DerivedTypeCodegenMethods<'tcx>: fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { ty.is_freeze(self.tcx(), self.typing_env()) } - - fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { - if ty.is_sized(self.tcx(), self.typing_env()) { - return false; - } - - let tail = self.tcx().struct_tail_for_codegen(ty, self.typing_env()); - match tail.kind() { - ty::Foreign(..) => false, - ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, - _ => bug!("unexpected unsized tail: {:?}", tail), - } - } } impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c153f6bb7d77..4d917963cd6c 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -208,6 +208,20 @@ impl<'tcx> TyCtxt<'tcx> { tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(typing_env, ty), || {}) } + /// Returns true if a type has metadata. + pub fn type_has_metadata(self, ty: Ty<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool { + if ty.is_sized(self, typing_env) { + return false; + } + + let tail = self.struct_tail_for_codegen(ty, typing_env); + match tail.kind() { + ty::Foreign(..) => false, + ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, + _ => bug!("unexpected unsized tail: {:?}", tail), + } + } + /// Returns the deeply last field of nested structures, or the same type if /// not a structure at all. Corresponds to the only possible unsized field, /// and its type can be used to determine unsizing strategy. diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index d7cb8f18f826..f8af6837fc25 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1043,18 +1043,7 @@ fn find_vtable_types_for_unsizing<'tcx>( ) -> (Ty<'tcx>, Ty<'tcx>) { let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { let typing_env = ty::TypingEnv::fully_monomorphized(); - let type_has_metadata = |ty: Ty<'tcx>| -> bool { - if ty.is_sized(tcx.tcx, typing_env) { - return false; - } - let tail = tcx.struct_tail_for_codegen(ty, typing_env); - match tail.kind() { - ty::Foreign(..) => false, - ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, - _ => bug!("unexpected unsized tail: {:?}", tail), - } - }; - if type_has_metadata(inner_source) { + if tcx.type_has_metadata(inner_source, typing_env) { (inner_source, inner_target) } else { tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, typing_env) From a5615d3c626549df8da9ccf1a284e1262967ddfa Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 4 Feb 2025 12:20:09 +0000 Subject: [PATCH 249/991] codegen_llvm: avoid `Deref` impls w/ extern type `rustc_codegen_llvm` relied on `Deref` impls where `Deref::Target` was or contained an extern type - in my experimental implementation of rust-lang/rfcs#3729, this isn't possible as the `Target` associated type's `?Sized` bound cannot be relaxed backwards compatibly (unless we come up with some way of doing this). In later pull requests with the rust-lang/rfcs#3729 implementation, breakage like this could only occur for nightly users relying on the `extern_types` feature. Upstreaming this to avoid needing to keep carrying this patch locally, and I think it'll necessarily need to change eventually. --- compiler/rustc_codegen_llvm/src/back/lto.rs | 6 ++++-- .../src/back/owned_target_machine.rs | 11 +++++----- compiler/rustc_codegen_llvm/src/back/write.rs | 6 +++--- compiler/rustc_codegen_llvm/src/builder.rs | 6 +++--- compiler/rustc_codegen_llvm/src/common.rs | 2 +- compiler/rustc_codegen_llvm/src/context.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm/mod.rs | 21 +++++++++---------- compiler/rustc_codegen_llvm/src/llvm_util.rs | 7 ++++--- 8 files changed, 31 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 99906ea7bce3..05a2cd1c5a32 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -793,7 +793,9 @@ pub(crate) unsafe fn optimize_thin_module( { let _timer = cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name()); - unsafe { llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) }; + unsafe { + llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target.raw()) + }; save_temp_bitcode(cgcx, &module, "thin-lto-after-rename"); } @@ -823,7 +825,7 @@ pub(crate) unsafe fn optimize_thin_module( let _timer = cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name()); if unsafe { - !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target) + !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target.raw()) } { return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule)); } diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs index f075f332462f..dfde45955906 100644 --- a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs +++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs @@ -1,6 +1,5 @@ use std::ffi::{CStr, c_char}; use std::marker::PhantomData; -use std::ops::Deref; use std::ptr::NonNull; use rustc_data_structures::small_c_str::SmallCStr; @@ -80,12 +79,12 @@ impl OwnedTargetMachine { .map(|tm_unique| Self { tm_unique, phantom: PhantomData }) .ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) }) } -} -impl Deref for OwnedTargetMachine { - type Target = llvm::TargetMachine; - - fn deref(&self) -> &Self::Target { + /// Returns inner `llvm::TargetMachine` type. + /// + /// This could be a `Deref` implementation, but `llvm::TargetMachine` is an extern type and + /// `Deref::Target: ?Sized`. + pub fn raw(&self) -> &llvm::TargetMachine { // SAFETY: constructing ensures we have a valid pointer created by // llvm::LLVMRustCreateTargetMachine. unsafe { self.tm_unique.as_ref() } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index b67890c04657..29d6121844f1 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -637,7 +637,7 @@ pub(crate) unsafe fn llvm_optimize( let result = unsafe { llvm::LLVMRustOptimize( module.module_llvm.llmod(), - &*module.module_llvm.tm, + &*module.module_llvm.tm.raw(), to_pass_builder_opt_level(opt_level), opt_stage, cgcx.opts.cg.linker_plugin_lto.enabled(), @@ -875,7 +875,7 @@ pub(crate) unsafe fn codegen( }; write_output_file( dcx, - tm, + tm.raw(), config.no_builtins, llmod, &path, @@ -909,7 +909,7 @@ pub(crate) unsafe fn codegen( write_output_file( dcx, - tm, + tm.raw(), config.no_builtins, llmod, &obj_out, diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 677a9cd3e90e..3f20350d0efd 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -405,7 +405,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // Emit KCFI operand bundle let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn); - if let Some(kcfi_bundle) = kcfi_bundle.as_deref() { + if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) { bundles.push(kcfi_bundle); } @@ -1433,7 +1433,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // Emit KCFI operand bundle let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn); - if let Some(kcfi_bundle) = kcfi_bundle.as_deref() { + if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) { bundles.push(kcfi_bundle); } @@ -1782,7 +1782,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { // Emit KCFI operand bundle let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn); - if let Some(kcfi_bundle) = kcfi_bundle.as_deref() { + if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) { bundles.push(kcfi_bundle); } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index f17d98fa242b..0621b893e755 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -77,7 +77,7 @@ impl<'ll> Funclet<'ll> { } pub(crate) fn bundle(&self) -> &llvm::OperandBundle<'ll> { - &self.operand + self.operand.raw() } } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index e7952bc95e7f..ed8426ae1974 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -205,7 +205,7 @@ pub(crate) unsafe fn create_module<'ll>( { let tm = crate::back::write::create_informational_target_machine(tcx.sess, false); unsafe { - llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm); + llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm.raw()); } let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) }; diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 5ec934241314..a36226b25a24 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -1,7 +1,6 @@ #![allow(non_snake_case)] use std::ffi::{CStr, CString}; -use std::ops::Deref; use std::ptr; use std::str::FromStr; use std::string::FromUtf8Error; @@ -355,6 +354,16 @@ impl<'a> OperandBundleOwned<'a> { }; OperandBundleOwned { raw: ptr::NonNull::new(raw).unwrap() } } + + /// Returns inner `OperandBundle` type. + /// + /// This could be a `Deref` implementation, but `OperandBundle` contains an extern type and + /// `Deref::Target: ?Sized`. + pub(crate) fn raw(&self) -> &OperandBundle<'a> { + // SAFETY: The returned reference is opaque and can only used for FFI. + // It is valid for as long as `&self` is. + unsafe { self.raw.as_ref() } + } } impl Drop for OperandBundleOwned<'_> { @@ -365,16 +374,6 @@ impl Drop for OperandBundleOwned<'_> { } } -impl<'a> Deref for OperandBundleOwned<'a> { - type Target = OperandBundle<'a>; - - fn deref(&self) -> &Self::Target { - // SAFETY: The returned reference is opaque and can only used for FFI. - // It is valid for as long as `&self` is. - unsafe { self.raw.as_ref() } - } -} - pub(crate) fn add_module_flag_u32( module: &Module, merge_behavior: ModuleFlagMergeBehavior, diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 1fcb20e0d7b2..5cc4f4ab9e67 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -331,7 +331,8 @@ pub(crate) fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec print_target_cpus(sess, &tm, out), - PrintKind::TargetFeatures => print_target_features(sess, &tm, out), + PrintKind::TargetCPUs => print_target_cpus(sess, tm.raw(), out), + PrintKind::TargetFeatures => print_target_features(sess, tm.raw(), out), _ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req), } } From 1ccdc06136ccb134f30d6604e89a659eae62b032 Mon Sep 17 00:00:00 2001 From: Mahmoud Mazouz Date: Mon, 24 Feb 2025 09:50:46 +0100 Subject: [PATCH 250/991] Remove speculation on cause of error Co-authored-by: Jubilee --- library/std/src/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index f5101a66ce19..d9e28acdcdac 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1742,7 +1742,7 @@ impl<'scope, T> JoinInner<'scope, T> { if let Some(packet) = Arc::get_mut(&mut self.packet) { packet.result.get_mut().take().unwrap() } else { - Err(Box::new("thread terminated unexpectedly (e.g. due to OS intervention)")) + Err(Box::new("thread terminated unexpectedly")) } } } From 21d41b09dfb782d44da4c487d5c377bf36e9bddc Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 24 Feb 2025 08:11:02 +0000 Subject: [PATCH 251/991] trait_sel: resolve vars in host effects In the standard library, the `Extend` impl for `Iterator` (specialised with `TrustedLen`) has a parameter which is constrained by a projection predicate. This projection predicate provides a value for an inference variable but host effect evaluation wasn't resolving variables first. Adding the extra resolve can the number of errors in some tests when they gain host effect predicates, but this is not unexpected as calls to `resolve_vars_if_possible` can cause more error tainting to happen. Co-authored-by: Boxy --- .../src/traits/effects.rs | 2 ++ .../unconstrained-var-specialization.rs | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/ui/traits/const-traits/unconstrained-var-specialization.rs diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index b32909efe0be..3c127416cbf7 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -31,6 +31,8 @@ pub fn evaluate_host_effect_obligation<'tcx>( ); } + let ref obligation = selcx.infcx.resolve_vars_if_possible(obligation.clone()); + // Force ambiguity for infer self ty. if obligation.predicate.self_ty().is_ty_var() { return Err(EvaluationFailure::Ambiguous); diff --git a/tests/ui/traits/const-traits/unconstrained-var-specialization.rs b/tests/ui/traits/const-traits/unconstrained-var-specialization.rs new file mode 100644 index 000000000000..43a331144501 --- /dev/null +++ b/tests/ui/traits/const-traits/unconstrained-var-specialization.rs @@ -0,0 +1,36 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![no_std] +#![allow(internal_features)] +#![feature(rustc_attrs, min_specialization, const_trait_impl)] + +// In the default impl below, `A` is constrained by the projection predicate, and if the host effect +// predicate for `const Foo` doesn't resolve vars, then specialization will fail. + +#[const_trait] +trait Foo {} + +pub trait Iterator { + type Item; +} + +#[rustc_unsafe_specialization_marker] +pub trait MoreSpecificThanIterator: Iterator {} + +pub trait Tr { + fn foo(); +} + +impl Tr for Iter + where + Iter: Iterator, +{ + default fn foo() {} +} + +impl Tr for Iter + where + Iter: MoreSpecificThanIterator, +{ + fn foo() {} +} From cede9029fd97bef27565269f7f251ca5d3ac2c4a Mon Sep 17 00:00:00 2001 From: klensy Date: Mon, 24 Feb 2025 12:19:52 +0300 Subject: [PATCH 252/991] cleanup few unused args --- compiler/rustc_borrowck/src/lib.rs | 4 ++-- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 9 ++------- compiler/rustc_resolve/src/imports.rs | 8 +++----- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index a98984a4b4c7..68e0ab0933e6 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -648,7 +648,7 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt< | StatementKind::StorageLive(..) => {} // This does not affect borrowck StatementKind::BackwardIncompatibleDropHint { place, reason: BackwardIncompatibleDropReason::Edition2024 } => { - self.check_backward_incompatible_drop(location, (**place, span), state); + self.check_backward_incompatible_drop(location, **place, state); } StatementKind::StorageDead(local) => { self.access_place( @@ -1174,7 +1174,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { fn check_backward_incompatible_drop( &mut self, location: Location, - (place, place_span): (Place<'tcx>, Span), + place: Place<'tcx>, state: &BorrowckDomain, ) { let tcx = self.infcx.tcx; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 1195c25e1308..9d9032025a41 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -752,7 +752,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { /// This does not walk the MIR of the constant as that is not needed for codegen, all we need is /// to ensure that the constant evaluates successfully and walk the result. #[instrument(skip(self), level = "debug")] - fn visit_const_operand(&mut self, constant: &mir::ConstOperand<'tcx>, location: Location) { + fn visit_const_operand(&mut self, constant: &mir::ConstOperand<'tcx>, _location: Location) { // No `super_constant` as we don't care about `visit_ty`/`visit_ty_const`. let Some(val) = self.eval_constant(constant) else { return }; collect_const_value(self.tcx, val, self.used_items); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 5db6f83f3ee5..f0418e9c27b1 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2252,7 +2252,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { #[instrument(level = "debug", skip(self, parent_scope))] pub(crate) fn make_path_suggestion( &mut self, - span: Span, mut path: Vec, parent_scope: &ParentScope<'ra>, ) -> Option<(Vec, Option)> { @@ -2480,7 +2479,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // or `use a::{b, c, d}};` // ^^^^^^^^^^^ let (has_nested, after_crate_name) = - find_span_immediately_after_crate_name(self.tcx.sess, module_name, import.use_span); + find_span_immediately_after_crate_name(self.tcx.sess, import.use_span); debug!(has_nested, ?after_crate_name); let source_map = self.tcx.sess.source_map(); @@ -2687,11 +2686,7 @@ fn extend_span_to_previous_binding(sess: &Session, binding_span: Span) -> Option /// // ^^^^^^^^^^^^^^^ -- true /// ``` #[instrument(level = "debug", skip(sess))] -fn find_span_immediately_after_crate_name( - sess: &Session, - module_name: Symbol, - use_span: Span, -) -> (bool, Span) { +fn find_span_immediately_after_crate_name(sess: &Session, use_span: Span) -> (bool, Span) { let source_map = sess.source_map(); // Using `use issue_59764::foo::{baz, makro};` as an example throughout.. diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 46e52e1f131b..59081134a6d3 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -955,11 +955,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } else { None }; - let err = match self.make_path_suggestion( - span, - import.module_path.clone(), - &import.parent_scope, - ) { + let err = match self + .make_path_suggestion(import.module_path.clone(), &import.parent_scope) + { Some((suggestion, note)) => UnresolvedImportError { span, label: None, From 92eb4450fa1ae37a948178c9d14bfb145a69562d Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 24 Feb 2025 09:26:54 +0000 Subject: [PATCH 253/991] tests: use minicore more minicore makes it much easier to add new language items to all of the existing `no_core` tests. --- tests/assembly/aarch64-pointer-auth.rs | 5 +- tests/assembly/cmse.rs | 8 +-- tests/assembly/dwarf4.rs | 7 +- tests/assembly/dwarf5.rs | 7 +- tests/assembly/pic-relocation-model.rs | 7 +- tests/assembly/pie-relocation-model.rs | 7 +- tests/assembly/powerpc64-struct-abi.rs | 17 +---- .../riscv-soft-abi-with-float-features.rs | 12 +--- tests/assembly/s390x-backchain-toggle.rs | 5 +- tests/assembly/simd-bitmask.rs | 9 +-- tests/assembly/simd-intrinsic-gather.rs | 9 +-- tests/assembly/simd-intrinsic-mask-load.rs | 10 +-- tests/assembly/simd-intrinsic-mask-reduce.rs | 9 +-- tests/assembly/simd-intrinsic-mask-store.rs | 10 +-- tests/assembly/simd-intrinsic-scatter.rs | 9 +-- tests/assembly/simd-intrinsic-select.rs | 9 +-- tests/assembly/sparc-struct-abi.rs | 8 +-- tests/assembly/stack-probes.rs | 9 +-- .../stack-protector-target-support.rs | 7 +- tests/assembly/static-relocation-model.rs | 17 +---- tests/assembly/target-feature-multiple.rs | 8 +-- tests/assembly/targets/targets-amdgpu.rs | 5 +- tests/assembly/targets/targets-elf.rs | 5 +- tests/assembly/targets/targets-macho.rs | 5 +- tests/assembly/targets/targets-nvptx.rs | 5 +- tests/assembly/targets/targets-pe.rs | 5 +- tests/auxiliary/minicore.rs | 66 ++++++++++++++++++- tests/codegen/aarch64-softfloat.rs | 9 +-- tests/codegen/aarch64-struct-align-128.rs | 9 +-- tests/codegen/abi-efiapi.rs | 9 +-- tests/codegen/abi-repr-ext.rs | 9 +-- tests/codegen/abi-sysv64.rs | 8 +-- tests/codegen/abi-win64-zst.rs | 1 + tests/codegen/abi-x86-interrupt.rs | 8 +-- tests/codegen/avr/avr-func-addrspace.rs | 42 +----------- tests/codegen/branch-protection-old-llvm.rs | 5 +- tests/codegen/branch-protection.rs | 5 +- tests/codegen/cast-target-abi.rs | 9 +-- tests/codegen/cf-protection.rs | 5 +- tests/codegen/cffi/ffi-out-of-bounds-loads.rs | 9 +-- tests/codegen/default-requires-uwtable.rs | 5 +- tests/codegen/fastcall-inreg.rs | 7 +- tests/codegen/fixed-x18.rs | 5 +- tests/codegen/frame-pointer.rs | 9 ++- tests/codegen/function-return.rs | 5 +- tests/codegen/gpu-kernel-abi.rs | 9 +-- tests/codegen/intrinsics/nontemporal.rs | 10 +-- .../loongarch-abi/loongarch64-lp64d-abi.rs | 9 +-- .../macos/i686-macosx-deployment-target.rs | 10 +-- .../macos/i686-no-macosx-deployment-target.rs | 10 +-- .../macos/x86_64-macosx-deployment-target.rs | 10 +-- .../x86_64-no-macosx-deployment-target.rs | 10 +-- tests/codegen/naked-fn/instruction-set.rs | 12 +--- tests/codegen/naked-fn/naked-functions.rs | 12 +--- tests/codegen/no-jump-tables.rs | 5 +- tests/codegen/powerpc64le-struct-align-128.rs | 9 +-- tests/codegen/regparm-inreg.rs | 8 +-- .../repr/transparent-byval-struct-ptr.rs | 10 +-- tests/codegen/repr/transparent-imm-array.rs | 11 +--- tests/codegen/repr/transparent-mips64.rs | 10 +-- tests/codegen/repr/transparent-opaque-ptr.rs | 10 +-- tests/codegen/repr/transparent-sparc64.rs | 11 +--- tests/codegen/repr/transparent-sysv64.rs | 9 +-- .../riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs | 16 +---- tests/codegen/riscv-abi/riscv64-lp64d-abi.rs | 9 +-- .../riscv-abi/riscv64-lp64f-lp64d-abi.rs | 9 +-- tests/codegen/riscv-target-abi.rs | 5 +- ...arch64-shadow-call-stack-with-fixed-x18.rs | 5 +- .../sanitizer/kasan-emits-instrumentation.rs | 10 +-- .../kcfi/add-cfi-normalize-integers-flag.rs | 7 +- tests/codegen/sanitizer/kcfi/add-kcfi-flag.rs | 7 +- .../sanitizer/kcfi/add-kcfi-offset-flag.rs | 7 +- ...it-kcfi-operand-bundle-attr-no-sanitize.rs | 9 +-- ...rand-bundle-itanium-cxx-abi-generalized.rs | 9 +-- ...-itanium-cxx-abi-normalized-generalized.rs | 9 +-- ...erand-bundle-itanium-cxx-abi-normalized.rs | 9 +-- ...mit-kcfi-operand-bundle-itanium-cxx-abi.rs | 9 +-- .../kcfi/emit-kcfi-operand-bundle.rs | 9 +-- .../kcfi/emit-type-metadata-trait-objects.rs | 26 +------- .../sanitizer/riscv64-shadow-call-stack.rs | 5 +- .../some-abis-do-extend-params-to-32-bits.rs | 9 +-- tests/codegen/sparc-struct-abi.rs | 9 +-- tests/codegen/stack-probes-inline.rs | 5 +- tests/codegen/target-feature-overrides.rs | 7 +- tests/codegen/tied-features-strength.rs | 5 +- tests/ui/abi/arm-unadjusted-intrinsic.rs | 16 +---- ...cv-discoverability-guidance.riscv32.stderr | 4 +- ...cv-discoverability-guidance.riscv64.stderr | 4 +- .../ui/abi/riscv-discoverability-guidance.rs | 12 ++-- tests/ui/abi/sparcv8plus-llvm19.rs | 7 +- tests/ui/abi/sparcv8plus-llvm19.sparc.stderr | 2 +- .../sparcv8plus-llvm19.sparc_cpu_v9.stderr | 2 +- ...-llvm19.sparc_cpu_v9_feature_v8plus.stderr | 2 +- ...cv8plus-llvm19.sparc_feature_v8plus.stderr | 2 +- .../abi/sparcv8plus-llvm19.sparcv8plus.stderr | 2 +- tests/ui/abi/sparcv8plus.rs | 7 +- tests/ui/abi/sparcv8plus.sparc.stderr | 2 +- tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr | 2 +- ...cv8plus.sparc_cpu_v9_feature_v8plus.stderr | 2 +- .../sparcv8plus.sparc_feature_v8plus.stderr | 2 +- tests/ui/abi/sparcv8plus.sparcv8plus.stderr | 2 +- tests/ui/abi/unsupported.aarch64.stderr | 58 ++++++++-------- tests/ui/abi/unsupported.arm.stderr | 52 +++++++-------- tests/ui/abi/unsupported.i686.stderr | 40 +++++------ tests/ui/abi/unsupported.riscv32.stderr | 52 +++++++-------- tests/ui/abi/unsupported.riscv64.stderr | 52 +++++++-------- tests/ui/abi/unsupported.rs | 7 +- tests/ui/abi/unsupported.x64.stderr | 52 +++++++-------- ...ed-types-ICE-when-projecting-out-of-err.rs | 14 +--- ...ypes-ICE-when-projecting-out-of-err.stderr | 8 +-- tests/ui/borrowck/issue-92157.rs | 26 +------- tests/ui/borrowck/issue-92157.stderr | 2 +- tests/ui/c-variadic/variadic-ffi-1.rs | 6 +- tests/ui/c-variadic/variadic-ffi-1.stderr | 26 ++++---- tests/ui/check-cfg/my-awesome-platform.json | 2 +- tests/ui/check-cfg/values-target-json.rs | 5 +- .../callback-as-argument.rs | 9 ++- .../cmse-nonsecure-call/generics.rs | 9 ++- .../cmse-nonsecure-call/generics.stderr | 18 ++--- .../cmse-nonsecure-call/params-via-stack.rs | 9 ++- .../params-via-stack.stderr | 10 +-- .../cmse-nonsecure-call/return-via-stack.rs | 1 + .../return-via-stack.stderr | 18 ++--- .../cmse-nonsecure-call/via-registers.rs | 9 ++- .../wrong-abi-location-1.rs | 6 +- .../wrong-abi-location-1.stderr | 2 +- .../wrong-abi-location-2.rs | 6 +- .../wrong-abi-location-2.stderr | 2 +- .../cmse-nonsecure-entry/generics.rs | 9 ++- .../cmse-nonsecure-entry/generics.stderr | 18 ++--- .../cmse-nonsecure-entry/params-via-stack.rs | 9 ++- .../params-via-stack.stderr | 10 +-- .../cmse-nonsecure-entry/return-via-stack.rs | 1 + .../return-via-stack.stderr | 18 ++--- .../trustzone-only.aarch64.stderr | 2 +- .../cmse-nonsecure-entry/trustzone-only.rs | 9 +-- .../trustzone-only.thumb7.stderr | 2 +- .../trustzone-only.x86.stderr | 2 +- .../cmse-nonsecure-entry/via-registers.rs | 10 ++- tests/ui/deriving/deriving-with-helper.rs | 7 +- .../feature-gate-abi-avr-interrupt.rs | 6 +- .../feature-gate-abi-avr-interrupt.stderr | 28 ++++---- .../feature-gate-abi-msp430-interrupt.rs | 6 +- .../feature-gate-abi-msp430-interrupt.stderr | 14 ++-- .../feature-gate-abi-riscv-interrupt.rs | 6 +- .../feature-gate-abi-riscv-interrupt.stderr | 12 ++-- .../feature-gate-abi-x86-interrupt.rs | 6 +- .../feature-gate-abi-x86-interrupt.stderr | 14 ++-- tests/ui/feature-gates/feature-gate-abi.rs | 8 +-- .../ui/feature-gates/feature-gate-abi.stderr | 54 +++++++-------- .../feature-gate-abi_gpu_kernel.rs | 8 +-- .../feature-gate-abi_gpu_kernel.stderr | 26 ++++---- .../ui/feature-gates/feature-gate-abi_ptx.rs | 6 +- .../feature-gates/feature-gate-abi_ptx.stderr | 14 ++-- .../feature-gate-asm_experimental_arch.rs | 12 +--- .../feature-gate-asm_experimental_arch.stderr | 2 +- .../feature-gate-asm_experimental_reg.rs | 12 +--- .../feature-gate-asm_experimental_reg.stderr | 4 +- .../feature-gates/feature-gate-vectorcall.rs | 6 +- .../feature-gate-vectorcall.stderr | 14 ++-- tests/ui/force-inlining/asm.rs | 14 +--- tests/ui/force-inlining/asm.stderr | 8 +-- tests/ui/layout/hexagon-enum.rs | 5 +- tests/ui/layout/hexagon-enum.stderr | 10 +-- tests/ui/layout/thumb-enum.rs | 5 +- tests/ui/layout/thumb-enum.stderr | 10 +-- tests/ui/layout/too-big-with-padding.rs | 9 ++- tests/ui/layout/too-big-with-padding.stderr | 2 +- tests/ui/mir/checks_without_panic_impl.rs | 5 +- tests/ui/repr/16-bit-repr-c-enum.rs | 9 ++- ...-variants.aarch64-unknown-linux-gnu.stderr | 6 +- ...-c-dead-variants.armebv7r-none-eabi.stderr | 6 +- ...-dead-variants.i686-pc-windows-msvc.stderr | 6 +- tests/ui/repr/repr-c-dead-variants.rs | 7 +- ...d-variants.x86_64-unknown-linux-gnu.stderr | 6 +- .../repr_align_greater_usize.msp430.stderr | 4 +- tests/ui/repr/repr_align_greater_usize.rs | 5 +- tests/ui/sanitizer/cfg-kasan.rs | 5 +- tests/ui/sanitizer/cfg.rs | 7 +- tests/ui/static/static_sized_requirement.rs | 7 +- tests/ui/target-feature/no-llvm-leaks.rs | 9 +-- tests/ui/target-feature/tied-features.rs | 5 +- tests/ui/target-feature/tied-features.stderr | 6 +- 183 files changed, 828 insertions(+), 1063 deletions(-) diff --git a/tests/assembly/aarch64-pointer-auth.rs b/tests/assembly/aarch64-pointer-auth.rs index 344e9e74bc2a..8c0069826795 100644 --- a/tests/assembly/aarch64-pointer-auth.rs +++ b/tests/assembly/aarch64-pointer-auth.rs @@ -1,5 +1,6 @@ // Test that PAC instructions are emitted when branch-protection is specified. +//@ add-core-stubs //@ revisions: PACRET PAUTHLR_NOP PAUTHLR //@ assembly-output: emit-asm //@ needs-llvm-components: aarch64 @@ -14,8 +15,8 @@ #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // PACRET: hint #25 // PACRET: hint #29 diff --git a/tests/assembly/cmse.rs b/tests/assembly/cmse.rs index e0ada8dc2f15..2984df92225c 100644 --- a/tests/assembly/cmse.rs +++ b/tests/assembly/cmse.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: hard soft //@ assembly-output: emit-asm //@ [hard] compile-flags: --target thumbv8m.main-none-eabihf --crate-type lib -Copt-level=1 @@ -7,10 +8,9 @@ #![crate_type = "lib"] #![feature(abi_c_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items)] #![no_core] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} + +extern crate minicore; +use minicore::*; // CHECK-LABEL: __acle_se_entry_point: // CHECK-NEXT: entry_point: diff --git a/tests/assembly/dwarf4.rs b/tests/assembly/dwarf4.rs index 22be8e5603f2..6013adf3386a 100644 --- a/tests/assembly/dwarf4.rs +++ b/tests/assembly/dwarf4.rs @@ -1,5 +1,6 @@ // Makes sure that `-Z dwarf-version=4` causes `rustc` to emit DWARF version 4. //@ assembly-output: emit-asm +//@ add-core-stubs //@ compile-flags: -g --target x86_64-unknown-linux-gnu -Z dwarf-version=4 -Copt-level=0 //@ needs-llvm-components: x86 @@ -7,10 +8,8 @@ #![crate_type = "rlib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; pub fn wibble() {} diff --git a/tests/assembly/dwarf5.rs b/tests/assembly/dwarf5.rs index 35f2716e9fa9..9cd596e78345 100644 --- a/tests/assembly/dwarf5.rs +++ b/tests/assembly/dwarf5.rs @@ -1,4 +1,5 @@ // Makes sure that `-Z dwarf-version=5` causes `rustc` to emit DWARF version 5. +//@ add-core-stubs //@ assembly-output: emit-asm //@ compile-flags: -g --target x86_64-unknown-linux-gnu -Z dwarf-version=5 -Copt-level=0 //@ needs-llvm-components: x86 @@ -7,10 +8,8 @@ #![crate_type = "rlib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; pub fn wibble() {} diff --git a/tests/assembly/pic-relocation-model.rs b/tests/assembly/pic-relocation-model.rs index 73db94791ec6..d35cd968389a 100644 --- a/tests/assembly/pic-relocation-model.rs +++ b/tests/assembly/pic-relocation-model.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x64 //@ assembly-output: emit-asm //@ [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=pic @@ -7,10 +8,8 @@ #![no_core] #![crate_type = "rlib"] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // CHECK-LABEL: call_other_fn: // CHECK: {{(jmpq|callq)}} *other_fn@GOTPCREL(%rip) diff --git a/tests/assembly/pie-relocation-model.rs b/tests/assembly/pie-relocation-model.rs index e632b4dd5823..5c74b34eb313 100644 --- a/tests/assembly/pie-relocation-model.rs +++ b/tests/assembly/pie-relocation-model.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x64 //@ assembly-output: emit-asm //@ [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=pie @@ -7,10 +8,8 @@ #![no_core] #![crate_type = "rlib"] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // CHECK-LABEL: call_other_fn: // With PIE local functions are called "directly". diff --git a/tests/assembly/powerpc64-struct-abi.rs b/tests/assembly/powerpc64-struct-abi.rs index 0332eb94d8a7..eb27afc4f23c 100644 --- a/tests/assembly/powerpc64-struct-abi.rs +++ b/tests/assembly/powerpc64-struct-abi.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: elfv1-be elfv2-be elfv2-le aix //@ assembly-output: emit-asm //@ compile-flags: -Copt-level=3 @@ -20,21 +21,9 @@ #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; -#[lang = "copy"] -trait Copy {} - -#[lang = "freeze"] -trait Freeze {} - -#[lang = "unpin"] -trait Unpin {} - -impl Copy for u8 {} -impl Copy for u16 {} -impl Copy for u32 {} impl Copy for FiveU32s {} impl Copy for FiveU16s {} impl Copy for ThreeU8s {} diff --git a/tests/assembly/riscv-soft-abi-with-float-features.rs b/tests/assembly/riscv-soft-abi-with-float-features.rs index 8ccfa72a7b6f..72cbd3841c12 100644 --- a/tests/assembly/riscv-soft-abi-with-float-features.rs +++ b/tests/assembly/riscv-soft-abi-with-float-features.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ assembly-output: emit-asm //@ compile-flags: --target riscv64imac-unknown-none-elf -Ctarget-feature=+f,+d //@ needs-llvm-components: riscv @@ -9,15 +10,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[lang = "copy"] -trait Copy {} - -impl Copy for f16 {} -impl Copy for f32 {} -impl Copy for f64 {} +extern crate minicore; +use minicore::*; // This test checks that the floats are all returned in `a0` as required by the `lp64` ABI. diff --git a/tests/assembly/s390x-backchain-toggle.rs b/tests/assembly/s390x-backchain-toggle.rs index 7ef0292d911e..83c7b82d0d4b 100644 --- a/tests/assembly/s390x-backchain-toggle.rs +++ b/tests/assembly/s390x-backchain-toggle.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: enable-backchain disable-backchain //@ assembly-output: emit-asm //@ compile-flags: -Copt-level=3 --crate-type=lib --target=s390x-unknown-linux-gnu @@ -8,8 +9,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; extern "C" { fn extern_func(); diff --git a/tests/assembly/simd-bitmask.rs b/tests/assembly/simd-bitmask.rs index 4a829c4dd98b..a632791153b2 100644 --- a/tests/assembly/simd-bitmask.rs +++ b/tests/assembly/simd-bitmask.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x86 x86-avx2 x86-avx512 aarch64 //@ [x86] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel //@ [x86] needs-llvm-components: x86 @@ -16,12 +17,8 @@ #![no_core] #![allow(non_camel_case_types)] -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct m8x16([i8; 16]); diff --git a/tests/assembly/simd-intrinsic-gather.rs b/tests/assembly/simd-intrinsic-gather.rs index 3152de35f295..8c17a58046d8 100644 --- a/tests/assembly/simd-intrinsic-gather.rs +++ b/tests/assembly/simd-intrinsic-gather.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x86-avx512 //@ [x86-avx512] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel //@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq @@ -9,12 +10,8 @@ #![no_core] #![allow(non_camel_case_types)] -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct f64x4([f64; 4]); diff --git a/tests/assembly/simd-intrinsic-mask-load.rs b/tests/assembly/simd-intrinsic-mask-load.rs index efe3e3752fab..a0d0514c0141 100644 --- a/tests/assembly/simd-intrinsic-mask-load.rs +++ b/tests/assembly/simd-intrinsic-mask-load.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x86-avx2 x86-avx512 //@ [x86-avx2] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel //@ [x86-avx2] compile-flags: -C target-feature=+avx2 @@ -12,13 +13,8 @@ #![no_core] #![allow(non_camel_case_types)] -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy {} -impl Copy for *const T {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct i8x16([i8; 16]); diff --git a/tests/assembly/simd-intrinsic-mask-reduce.rs b/tests/assembly/simd-intrinsic-mask-reduce.rs index 4d4adda6c24f..959c4ddefdb0 100644 --- a/tests/assembly/simd-intrinsic-mask-reduce.rs +++ b/tests/assembly/simd-intrinsic-mask-reduce.rs @@ -1,4 +1,5 @@ // verify that simd mask reductions do not introduce additional bit shift operations +//@ add-core-stubs //@ revisions: x86 aarch64 //@ [x86] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel // Set the base cpu explicitly, in case the default has been changed. @@ -13,12 +14,8 @@ #![no_core] #![allow(non_camel_case_types)] -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct mask8x16([i8; 16]); diff --git a/tests/assembly/simd-intrinsic-mask-store.rs b/tests/assembly/simd-intrinsic-mask-store.rs index f5d924f24a76..4be9194943c7 100644 --- a/tests/assembly/simd-intrinsic-mask-store.rs +++ b/tests/assembly/simd-intrinsic-mask-store.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x86-avx2 x86-avx512 //@ [x86-avx2] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel //@ [x86-avx2] compile-flags: -C target-feature=+avx2 @@ -12,13 +13,8 @@ #![no_core] #![allow(non_camel_case_types)] -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy {} -impl Copy for *mut T {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct i8x16([i8; 16]); diff --git a/tests/assembly/simd-intrinsic-scatter.rs b/tests/assembly/simd-intrinsic-scatter.rs index 5f52ababd19c..715de04af4d7 100644 --- a/tests/assembly/simd-intrinsic-scatter.rs +++ b/tests/assembly/simd-intrinsic-scatter.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x86-avx512 //@ [x86-avx512] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel //@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq @@ -9,12 +10,8 @@ #![no_core] #![allow(non_camel_case_types)] -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct f64x4([f64; 4]); diff --git a/tests/assembly/simd-intrinsic-select.rs b/tests/assembly/simd-intrinsic-select.rs index 74784a772133..7f1e42662bfb 100644 --- a/tests/assembly/simd-intrinsic-select.rs +++ b/tests/assembly/simd-intrinsic-select.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x86-avx2 x86-avx512 aarch64 //@ [x86-avx2] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel //@ [x86-avx2] compile-flags: -C target-feature=+avx2 @@ -14,12 +15,8 @@ #![no_core] #![allow(non_camel_case_types)] -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct i8x16([i8; 16]); diff --git a/tests/assembly/sparc-struct-abi.rs b/tests/assembly/sparc-struct-abi.rs index 3a254f179641..b1594428811f 100644 --- a/tests/assembly/sparc-struct-abi.rs +++ b/tests/assembly/sparc-struct-abi.rs @@ -2,6 +2,7 @@ // - float structure members are passes in floating point registers // (#86163) +//@ add-core-stubs //@ assembly-output: emit-asm //@ needs-llvm-components: sparc //@ compile-flags: --target=sparcv9-sun-solaris -Copt-level=3 @@ -9,11 +10,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} -impl Copy for f32 {} +extern crate minicore; +use minicore::*; #[repr(C)] pub struct Franta { diff --git a/tests/assembly/stack-probes.rs b/tests/assembly/stack-probes.rs index e0931157ce17..de245431f470 100644 --- a/tests/assembly/stack-probes.rs +++ b/tests/assembly/stack-probes.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x86_64 i686 aarch64 //@ assembly-output: emit-asm //@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel @@ -11,12 +12,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -impl Copy for u8 {} +extern crate minicore; +use minicore::*; // Check that inline-asm stack probes are generated correctly. // To avoid making this test fragile to slight asm changes, diff --git a/tests/assembly/stack-protector/stack-protector-target-support.rs b/tests/assembly/stack-protector/stack-protector-target-support.rs index 74a609dcdcc1..e9ba0f9ba899 100644 --- a/tests/assembly/stack-protector/stack-protector-target-support.rs +++ b/tests/assembly/stack-protector/stack-protector-target-support.rs @@ -1,6 +1,7 @@ // Test that stack smash protection code is emitted for all tier1 and tier2 // targets, with the exception of nvptx64-nvidia-cuda // +//@ add-core-stubs //@ revisions: r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 //@ revisions: r24 r25 r26 r27 r28 r29 r30 r31 r32 r33 r35 r36 r37 r38 r39 r40 r41 r42 r43 r44 //@ revisions: r45 r46 r47 r48 r49 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63 r64 r65 @@ -183,10 +184,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[no_mangle] pub fn foo() { diff --git a/tests/assembly/static-relocation-model.rs b/tests/assembly/static-relocation-model.rs index eafdfd485baa..53fa18852b69 100644 --- a/tests/assembly/static-relocation-model.rs +++ b/tests/assembly/static-relocation-model.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x64 A64 ppc64le //@ assembly-output: emit-asm //@ [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=static @@ -11,20 +12,8 @@ #![no_core] #![crate_type = "rlib"] -#[lang = "sized"] -trait Sized {} - -#[lang = "copy"] -trait Copy {} - -#[lang = "sync"] -trait Sync {} - -#[lang = "drop_in_place"] -fn drop_in_place(_: *mut T) {} - -impl Copy for u8 {} -impl Sync for u8 {} +extern crate minicore; +use minicore::*; #[no_mangle] pub static PIERIS: u8 = 42; diff --git a/tests/assembly/target-feature-multiple.rs b/tests/assembly/target-feature-multiple.rs index 83c385686476..bc432d219317 100644 --- a/tests/assembly/target-feature-multiple.rs +++ b/tests/assembly/target-feature-multiple.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ assembly-output: emit-asm //@ needs-llvm-components: x86 //@ revisions: TWOFLAGS SINGLEFLAG @@ -19,11 +20,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for u32 {} +extern crate minicore; +use minicore::*; // Use of these requires target features to be enabled extern "unadjusted" { diff --git a/tests/assembly/targets/targets-amdgpu.rs b/tests/assembly/targets/targets-amdgpu.rs index 501eed2e2478..1d10b8fc315c 100644 --- a/tests/assembly/targets/targets-amdgpu.rs +++ b/tests/assembly/targets/targets-amdgpu.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ assembly-output: emit-asm // ignore-tidy-linelength //@ revisions: amdgcn_amd_amdhsa @@ -11,8 +12,8 @@ #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; pub fn test() -> u8 { 42 diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 3e73d2c6eb72..dc564c60f807 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ assembly-output: emit-asm // ignore-tidy-linelength //@ revisions: aarch64_be_unknown_linux_gnu @@ -709,8 +710,8 @@ #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // Force linkage to ensure code is actually generated #[no_mangle] diff --git a/tests/assembly/targets/targets-macho.rs b/tests/assembly/targets/targets-macho.rs index 25e9059afeb1..92bde1c6971b 100644 --- a/tests/assembly/targets/targets-macho.rs +++ b/tests/assembly/targets/targets-macho.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ assembly-output: emit-asm // ignore-tidy-linelength //@ revisions: aarch64_apple_darwin @@ -80,8 +81,8 @@ #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // Force linkage to ensure code is actually generated #[no_mangle] diff --git a/tests/assembly/targets/targets-nvptx.rs b/tests/assembly/targets/targets-nvptx.rs index 9048191affa1..49c12aebaaaf 100644 --- a/tests/assembly/targets/targets-nvptx.rs +++ b/tests/assembly/targets/targets-nvptx.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ assembly-output: emit-asm // ignore-tidy-linelength //@ revisions: nvptx64_nvidia_cuda @@ -11,8 +12,8 @@ #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; pub fn test() -> u8 { 42 diff --git a/tests/assembly/targets/targets-pe.rs b/tests/assembly/targets/targets-pe.rs index b74d0181c4d6..f895b79ba507 100644 --- a/tests/assembly/targets/targets-pe.rs +++ b/tests/assembly/targets/targets-pe.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ assembly-output: emit-asm // ignore-tidy-linelength //@ revisions: aarch64_pc_windows_msvc @@ -95,8 +96,8 @@ #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; pub fn test() -> u8 { 42 diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 0aa8b6b8f891..03aa84765082 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -25,7 +25,8 @@ naked_functions, f16, f128, - asm_experimental_arch + asm_experimental_arch, + unboxed_closures )] #![allow(unused, improper_ctypes_definitions, internal_features)] #![no_std] @@ -61,7 +62,7 @@ pub auto trait Unpin {} impl_marker_trait!( Copy => [ - bool, char, + char, bool, isize, i8, i16, i32, i64, i128, usize, u8, u16, u32, u64, u128, f16, f32, f64, f128, @@ -102,6 +103,9 @@ pub struct UnsafeCell { } impl !Freeze for UnsafeCell {} +#[lang = "tuple_trait"] +pub trait Tuple {} + #[rustc_builtin_macro] pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ @@ -129,3 +133,61 @@ macro_rules! stringify { /* compiler built-in */ }; } + +#[lang = "add"] +pub trait Add { + type Output; + + fn add(self, _: Rhs) -> Self::Output; +} + +impl Add for isize { + type Output = isize; + + fn add(self, other: isize) -> isize { + 7 // avoid needing to add all of the overflow handling and panic language items + } +} + +#[lang = "sync"] +trait Sync {} +impl Sync for u8 {} + +#[lang = "drop_in_place"] +fn drop_in_place(_: *mut T) {} + +#[lang = "fn_once"] +pub trait FnOnce { + #[lang = "fn_once_output"] + type Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +#[lang = "fn_mut"] +pub trait FnMut: FnOnce { + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; +} + +#[lang = "fn"] +pub trait Fn: FnMut { + extern "rust-call" fn call(&self, args: Args) -> Self::Output; +} + +#[lang = "dispatch_from_dyn"] +trait DispatchFromDyn {} + +impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} + +#[lang = "unsize"] +trait Unsize {} + +#[lang = "coerce_unsized"] +pub trait CoerceUnsized {} + +impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} + +#[lang = "drop"] +trait Drop { + fn drop(&mut self); +} diff --git a/tests/codegen/aarch64-softfloat.rs b/tests/codegen/aarch64-softfloat.rs index 85380a6c4728..4f5366e047fb 100644 --- a/tests/codegen/aarch64-softfloat.rs +++ b/tests/codegen/aarch64-softfloat.rs @@ -1,15 +1,12 @@ +//@ add-core-stubs //@ compile-flags: --target aarch64-unknown-none-softfloat -Zmerge-functions=disabled //@ needs-llvm-components: aarch64 #![crate_type = "lib"] #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for f32 {} -impl Copy for f64 {} +extern crate minicore; +use minicore::*; // CHECK: i64 @pass_f64_C(i64 {{[^,]*}}) #[no_mangle] diff --git a/tests/codegen/aarch64-struct-align-128.rs b/tests/codegen/aarch64-struct-align-128.rs index 3fed19d96b12..ba1d19680f4e 100644 --- a/tests/codegen/aarch64-struct-align-128.rs +++ b/tests/codegen/aarch64-struct-align-128.rs @@ -1,5 +1,6 @@ // Test that structs aligned to 128 bits are passed with the correct ABI on aarch64. +//@ add-core-stubs //@ revisions: linux darwin win //@[linux] compile-flags: --target aarch64-unknown-linux-gnu //@[darwin] compile-flags: --target aarch64-apple-darwin @@ -12,12 +13,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // Passed as `[i64 x 2]`, since it's an aggregate with size <= 128 bits, align < 128 bits. #[repr(C)] diff --git a/tests/codegen/abi-efiapi.rs b/tests/codegen/abi-efiapi.rs index 986d042268aa..1736f0daf0fa 100644 --- a/tests/codegen/abi-efiapi.rs +++ b/tests/codegen/abi-efiapi.rs @@ -1,5 +1,6 @@ // Checks if the correct annotation for the efiapi ABI is passed to llvm. +//@ add-core-stubs //@ revisions:x86_64 i686 aarch64 arm riscv //@[x86_64] compile-flags: --target x86_64-unknown-uefi //@[x86_64] needs-llvm-components: aarch64 arm riscv @@ -17,12 +18,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; //x86_64: define win64cc void @has_efiapi //i686: define void @has_efiapi diff --git a/tests/codegen/abi-repr-ext.rs b/tests/codegen/abi-repr-ext.rs index b06d225ed70e..1da28a94d9dd 100644 --- a/tests/codegen/abi-repr-ext.rs +++ b/tests/codegen/abi-repr-ext.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 //@ revisions:x86_64 i686 aarch64-apple aarch64-windows aarch64-linux arm riscv @@ -24,12 +25,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(i8)] pub enum Type { diff --git a/tests/codegen/abi-sysv64.rs b/tests/codegen/abi-sysv64.rs index ec555ee5f1d9..7ade17f2baec 100644 --- a/tests/codegen/abi-sysv64.rs +++ b/tests/codegen/abi-sysv64.rs @@ -2,6 +2,7 @@ // llvm. Also checks that the abi-sysv64 feature gate allows usage // of the sysv64 abi. // +//@ add-core-stubs //@ needs-llvm-components: x86 //@ compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu -Copt-level=0 @@ -9,11 +10,8 @@ #![no_core] #![feature(abi_x86_interrupt, no_core, lang_items)] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for i64 {} +extern crate minicore; +use minicore::*; // CHECK: define x86_64_sysvcc i64 @has_sysv64_abi #[no_mangle] diff --git a/tests/codegen/abi-win64-zst.rs b/tests/codegen/abi-win64-zst.rs index 825a5c1b09c1..e46f9666d42e 100644 --- a/tests/codegen/abi-win64-zst.rs +++ b/tests/codegen/abi-win64-zst.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: -Z merge-functions=disabled //@ add-core-stubs diff --git a/tests/codegen/abi-x86-interrupt.rs b/tests/codegen/abi-x86-interrupt.rs index b8f3ebb99dd5..255ccba2c111 100644 --- a/tests/codegen/abi-x86-interrupt.rs +++ b/tests/codegen/abi-x86-interrupt.rs @@ -2,6 +2,7 @@ // llvm. Also checks that the abi_x86_interrupt feature gate allows usage // of the x86-interrupt abi. +//@ add-core-stubs //@ needs-llvm-components: x86 //@ compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu -Copt-level=0 @@ -9,11 +10,8 @@ #![no_core] #![feature(abi_x86_interrupt, no_core, lang_items)] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for i64 {} +extern crate minicore; +use minicore::*; // CHECK: define x86_intrcc i64 @has_x86_interrupt_abi #[no_mangle] diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs index 2ec7c86b5f43..2ae2f40d7b34 100644 --- a/tests/codegen/avr/avr-func-addrspace.rs +++ b/tests/codegen/avr/avr-func-addrspace.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 --target=avr-none -C target-cpu=atmega328p --crate-type=rlib -C panic=abort //@ needs-llvm-components: avr @@ -13,45 +14,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} -impl Copy for *const T {} -#[lang = "legacy_receiver"] -pub trait LegacyReceiver {} -#[lang = "tuple_trait"] -pub trait Tuple {} - -pub struct Result { - _a: T, - _b: E, -} - -impl Copy for usize {} -impl Copy for &usize {} - -#[lang = "drop_in_place"] -pub unsafe fn drop_in_place(_: *mut T) {} - -#[lang = "fn_once"] -pub trait FnOnce { - #[lang = "fn_once_output"] - type Output; - - extern "rust-call" fn call_once(self, args: Args) -> Self::Output; -} - -#[lang = "fn_mut"] -pub trait FnMut: FnOnce { - extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; -} - -#[lang = "fn"] -pub trait Fn: FnOnce { - /// Performs the call operation. - extern "rust-call" fn call(&self, args: Args) -> Self::Output; -} +extern crate minicore; +use minicore::*; extern "rust-intrinsic" { pub fn transmute(src: Src) -> Dst; diff --git a/tests/codegen/branch-protection-old-llvm.rs b/tests/codegen/branch-protection-old-llvm.rs index 1846f35479db..14b34ac50188 100644 --- a/tests/codegen/branch-protection-old-llvm.rs +++ b/tests/codegen/branch-protection-old-llvm.rs @@ -1,5 +1,6 @@ // Test that the correct module flags are emitted with different branch protection flags. +//@ add-core-stubs //@ revisions: BTI PACRET LEAF BKEY NONE //@ needs-llvm-components: aarch64 //@ [BTI] compile-flags: -Z branch-protection=bti @@ -13,8 +14,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // A basic test function. pub fn test() {} diff --git a/tests/codegen/branch-protection.rs b/tests/codegen/branch-protection.rs index 945bad056256..ae14eae9ae0d 100644 --- a/tests/codegen/branch-protection.rs +++ b/tests/codegen/branch-protection.rs @@ -1,5 +1,6 @@ // Test that the correct module flags are emitted with different branch protection flags. +//@ add-core-stubs //@ revisions: BTI PACRET LEAF BKEY PAUTHLR PAUTHLR_BKEY PAUTHLR_LEAF PAUTHLR_BTI NONE //@ needs-llvm-components: aarch64 //@ [BTI] compile-flags: -Z branch-protection=bti @@ -17,8 +18,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // A basic test function. // CHECK: @test(){{.*}} [[ATTR:#[0-9]+]] { diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs index a0801eb98269..186198bc631e 100644 --- a/tests/codegen/cast-target-abi.rs +++ b/tests/codegen/cast-target-abi.rs @@ -1,4 +1,5 @@ // ignore-tidy-linelength +//@ add-core-stubs //@ revisions:aarch64 loongarch64 powerpc64 sparc64 x86_64 //@ min-llvm-version: 19 //@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes -Zlint-llvm-ir -Cllvm-args=-lint-abort-on-error @@ -21,12 +22,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // This struct will be passed as a single `i64` or `i32`. // This may be (if `i64)) larger than the Rust layout, which is just `{ i16, i16 }`. diff --git a/tests/codegen/cf-protection.rs b/tests/codegen/cf-protection.rs index 244d1eb25442..f1349a5dcb98 100644 --- a/tests/codegen/cf-protection.rs +++ b/tests/codegen/cf-protection.rs @@ -1,5 +1,6 @@ // Test that the correct module flags are emitted with different control-flow protection flags. +//@ add-core-stubs //@ revisions: undefined none branch return full //@ needs-llvm-components: x86 //@ [undefined] compile-flags: @@ -13,8 +14,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // A basic test function. pub fn test() {} diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs index ae8d8383f5b9..404f6237849e 100644 --- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs +++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: linux apple //@ min-llvm-version: 19 //@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -Zlint-llvm-ir -Cllvm-args=-lint-abort-on-error @@ -14,12 +15,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(C)] struct S { diff --git a/tests/codegen/default-requires-uwtable.rs b/tests/codegen/default-requires-uwtable.rs index 3cb35cea022a..54a6e171db66 100644 --- a/tests/codegen/default-requires-uwtable.rs +++ b/tests/codegen/default-requires-uwtable.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: WINDOWS_ ANDROID_ //@ compile-flags: -C panic=abort -Copt-level=0 //@ [WINDOWS_] compile-flags: --target=x86_64-pc-windows-msvc @@ -9,8 +10,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // CHECK: attributes #{{.*}} uwtable pub fn foo() {} diff --git a/tests/codegen/fastcall-inreg.rs b/tests/codegen/fastcall-inreg.rs index 00b390bf1bf1..066943d6e7eb 100644 --- a/tests/codegen/fastcall-inreg.rs +++ b/tests/codegen/fastcall-inreg.rs @@ -2,6 +2,7 @@ // as "inreg" like the C/C++ compilers for the platforms. // x86 only. +//@ add-core-stubs //@ compile-flags: --target i686-unknown-linux-gnu -Cno-prepopulate-passes -Copt-level=3 //@ needs-llvm-components: x86 @@ -9,10 +10,8 @@ #![no_core] #![feature(no_core, lang_items)] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; pub mod tests { // CHECK: @f1(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 noundef %_3) diff --git a/tests/codegen/fixed-x18.rs b/tests/codegen/fixed-x18.rs index 4997a39a7263..a5767cfa456b 100644 --- a/tests/codegen/fixed-x18.rs +++ b/tests/codegen/fixed-x18.rs @@ -1,6 +1,7 @@ // Test that the `reserve-x18` target feature is (not) emitted when // the `-Zfixed-x18` flag is (not) set. +//@ add-core-stubs //@ revisions: unset set //@ needs-llvm-components: aarch64 //@ compile-flags: --target aarch64-unknown-none @@ -10,8 +11,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; #[no_mangle] pub fn foo() { diff --git a/tests/codegen/frame-pointer.rs b/tests/codegen/frame-pointer.rs index da81c2e9cd9a..1f7c9a59c988 100644 --- a/tests/codegen/frame-pointer.rs +++ b/tests/codegen/frame-pointer.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: --crate-type=rlib -Copt-level=0 //@ revisions: aarch64-apple aarch64-linux force x64-apple x64-linux //@ [aarch64-apple] needs-llvm-components: aarch64 @@ -13,11 +14,9 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for u32 {} + +extern crate minicore; +use minicore::*; // CHECK: define i32 @peach{{.*}}[[PEACH_ATTRS:\#[0-9]+]] { #[no_mangle] diff --git a/tests/codegen/function-return.rs b/tests/codegen/function-return.rs index 2b9de4e14785..4127f5160385 100644 --- a/tests/codegen/function-return.rs +++ b/tests/codegen/function-return.rs @@ -1,6 +1,7 @@ // Test that the `fn_ret_thunk_extern` function attribute is (not) emitted when // the `-Zfunction-return={keep,thunk-extern}` flag is (not) set. +//@ add-core-stubs //@ revisions: unset keep thunk-extern keep-thunk-extern thunk-extern-keep //@ needs-llvm-components: x86 //@ compile-flags: --target x86_64-unknown-linux-gnu @@ -13,8 +14,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; #[no_mangle] pub fn foo() { diff --git a/tests/codegen/gpu-kernel-abi.rs b/tests/codegen/gpu-kernel-abi.rs index fba179364943..8ac376d93381 100644 --- a/tests/codegen/gpu-kernel-abi.rs +++ b/tests/codegen/gpu-kernel-abi.rs @@ -1,17 +1,14 @@ // Checks that the gpu-kernel calling convention correctly translates to LLVM calling conventions. +//@ add-core-stubs //@ revisions: nvptx //@ [nvptx] compile-flags: --crate-type=rlib --target=nvptx64-nvidia-cuda //@ [nvptx] needs-llvm-components: nvptx #![feature(no_core, lang_items, abi_gpu_kernel)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // nvptx: define ptx_kernel void @fun(i32 #[no_mangle] diff --git a/tests/codegen/intrinsics/nontemporal.rs b/tests/codegen/intrinsics/nontemporal.rs index af8892d30e7f..1d4fae83c29d 100644 --- a/tests/codegen/intrinsics/nontemporal.rs +++ b/tests/codegen/intrinsics/nontemporal.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 //@revisions: with_nontemporal without_nontemporal //@[with_nontemporal] compile-flags: --target aarch64-unknown-linux-gnu @@ -14,13 +15,8 @@ #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} - -impl Copy for u32 {} -impl Copy for *mut T {} +extern crate minicore; +use minicore::*; extern "rust-intrinsic" { pub fn nontemporal_store(ptr: *mut T, val: T); diff --git a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs index b11bd657c18e..93c8d60930b7 100644 --- a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs +++ b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes --target loongarch64-unknown-linux-gnu //@ needs-llvm-components: loongarch @@ -6,12 +7,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // CHECK: define void @f_fpr_tracking(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, i8 noundef zeroext %i) #[no_mangle] diff --git a/tests/codegen/macos/i686-macosx-deployment-target.rs b/tests/codegen/macos/i686-macosx-deployment-target.rs index 1f44bdfc6485..cfa91e61cb00 100644 --- a/tests/codegen/macos/i686-macosx-deployment-target.rs +++ b/tests/codegen/macos/i686-macosx-deployment-target.rs @@ -1,19 +1,15 @@ -// // Checks that we correctly modify the target when MACOSX_DEPLOYMENT_TARGET is set. // See issue #60235. +//@ add-core-stubs //@ compile-flags: -Copt-level=3 --target=i686-apple-darwin --crate-type=rlib //@ needs-llvm-components: x86 //@ rustc-env:MACOSX_DEPLOYMENT_TARGET=10.14 #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(C)] pub struct Bool { diff --git a/tests/codegen/macos/i686-no-macosx-deployment-target.rs b/tests/codegen/macos/i686-no-macosx-deployment-target.rs index a09773e0b9e2..25ec5f6acbb7 100644 --- a/tests/codegen/macos/i686-no-macosx-deployment-target.rs +++ b/tests/codegen/macos/i686-no-macosx-deployment-target.rs @@ -1,19 +1,15 @@ -// // Checks that we leave the target alone MACOSX_DEPLOYMENT_TARGET is unset. // See issue #60235. +//@ add-core-stubs //@ compile-flags: -Copt-level=3 --target=i686-apple-darwin --crate-type=rlib //@ needs-llvm-components: x86 //@ unset-rustc-env:MACOSX_DEPLOYMENT_TARGET #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(C)] pub struct Bool { diff --git a/tests/codegen/macos/x86_64-macosx-deployment-target.rs b/tests/codegen/macos/x86_64-macosx-deployment-target.rs index bd8c027a9fb9..8ea95ba0575e 100644 --- a/tests/codegen/macos/x86_64-macosx-deployment-target.rs +++ b/tests/codegen/macos/x86_64-macosx-deployment-target.rs @@ -1,19 +1,15 @@ -// // Checks that we correctly modify the target when MACOSX_DEPLOYMENT_TARGET is set. // See issue #60235. +//@ add-core-stubs //@ compile-flags: -Copt-level=3 --target=x86_64-apple-darwin --crate-type=rlib //@ needs-llvm-components: x86 //@ rustc-env:MACOSX_DEPLOYMENT_TARGET=10.14 #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(C)] pub struct Bool { diff --git a/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs b/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs index ff4a8fc46f98..474094957aeb 100644 --- a/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs +++ b/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs @@ -1,19 +1,15 @@ -// // Checks that we leave the target alone when MACOSX_DEPLOYMENT_TARGET is unset. // See issue #60235. +//@ add-core-stubs //@ compile-flags: -Copt-level=3 --target=x86_64-apple-darwin --crate-type=rlib //@ needs-llvm-components: x86 //@ unset-rustc-env:MACOSX_DEPLOYMENT_TARGET #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(C)] pub struct Bool { diff --git a/tests/codegen/naked-fn/instruction-set.rs b/tests/codegen/naked-fn/instruction-set.rs index 5b790b2034c0..a7b4c22a59bf 100644 --- a/tests/codegen/naked-fn/instruction-set.rs +++ b/tests/codegen/naked-fn/instruction-set.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: arm-mode thumb-mode //@ [arm-mode] compile-flags: --target armv5te-none-eabi //@ [thumb-mode] compile-flags: --target thumbv5te-none-eabi @@ -8,15 +9,8 @@ #![feature(no_core, lang_items, rustc_attrs, naked_functions)] #![no_core] -#[rustc_builtin_macro] -macro_rules! naked_asm { - () => {}; -} - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // arm-mode: .arm // thumb-mode: .thumb diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs index f505d27d48c6..6483e27c97a2 100644 --- a/tests/codegen/naked-fn/naked-functions.rs +++ b/tests/codegen/naked-fn/naked-functions.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: linux win macos thumb // //@[linux] compile-flags: --target x86_64-unknown-linux-gnu @@ -13,15 +14,8 @@ #![feature(no_core, lang_items, rustc_attrs, naked_functions)] #![no_core] -#[rustc_builtin_macro] -macro_rules! naked_asm { - () => {}; -} - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // linux,win: .intel_syntax // diff --git a/tests/codegen/no-jump-tables.rs b/tests/codegen/no-jump-tables.rs index 654da2cec11c..e49de7e9dc1e 100644 --- a/tests/codegen/no-jump-tables.rs +++ b/tests/codegen/no-jump-tables.rs @@ -1,6 +1,7 @@ // Test that the `no-jump-tables` function attribute are (not) emitted when // the `-Zno-jump-tables` flag is (not) set. +//@ add-core-stubs //@ revisions: unset set //@ needs-llvm-components: x86 //@ compile-flags: --target x86_64-unknown-linux-gnu @@ -10,8 +11,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; #[no_mangle] pub fn foo() { diff --git a/tests/codegen/powerpc64le-struct-align-128.rs b/tests/codegen/powerpc64le-struct-align-128.rs index 3981cd121296..c1c1ac264854 100644 --- a/tests/codegen/powerpc64le-struct-align-128.rs +++ b/tests/codegen/powerpc64le-struct-align-128.rs @@ -1,6 +1,7 @@ // Test that structs aligned to 128 bits are passed with the correct ABI on powerpc64le. // This is similar to aarch64-struct-align-128.rs, but for ppc. +//@ add-core-stubs //@ compile-flags: --target powerpc64le-unknown-linux-gnu //@ needs-llvm-components: powerpc @@ -8,12 +9,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(C)] pub struct Align8 { diff --git a/tests/codegen/regparm-inreg.rs b/tests/codegen/regparm-inreg.rs index 82e157311287..8dae3a83e4ed 100644 --- a/tests/codegen/regparm-inreg.rs +++ b/tests/codegen/regparm-inreg.rs @@ -2,6 +2,7 @@ // marks function arguments as "inreg" like the C/C++ compilers for the platforms. // x86 only. +//@ add-core-stubs //@ compile-flags: --target i686-unknown-linux-gnu -Cno-prepopulate-passes -Copt-level=3 //@ needs-llvm-components: x86 @@ -14,10 +15,9 @@ #![crate_type = "lib"] #![no_core] #![feature(no_core, lang_items, repr_simd)] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} + +extern crate minicore; +use minicore::*; pub mod tests { // regparm doesn't work for "fastcall" calling conv (only 2 inregs) diff --git a/tests/codegen/repr/transparent-byval-struct-ptr.rs b/tests/codegen/repr/transparent-byval-struct-ptr.rs index f9cfeb90390c..0918884144fc 100644 --- a/tests/codegen/repr/transparent-byval-struct-ptr.rs +++ b/tests/codegen/repr/transparent-byval-struct-ptr.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: i686-linux i686-freebsd x64-linux x64-apple //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes @@ -21,14 +22,9 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; -impl Copy for [u32; 16] {} impl Copy for BigS {} impl Copy for BigU {} diff --git a/tests/codegen/repr/transparent-imm-array.rs b/tests/codegen/repr/transparent-imm-array.rs index f790d093cf4a..6dad04477845 100644 --- a/tests/codegen/repr/transparent-imm-array.rs +++ b/tests/codegen/repr/transparent-imm-array.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: arm-linux arm-android armv7-linux armv7-android mips thumb sparc //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes @@ -27,14 +28,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} - -impl Copy for [u32; 16] {} +extern crate minicore; +use minicore::*; impl Copy for BigS {} impl Copy for BigU {} diff --git a/tests/codegen/repr/transparent-mips64.rs b/tests/codegen/repr/transparent-mips64.rs index 7282654b8562..98901350154e 100644 --- a/tests/codegen/repr/transparent-mips64.rs +++ b/tests/codegen/repr/transparent-mips64.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: mips64 mips64el //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes @@ -13,14 +14,9 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; -impl Copy for [u32; 16] {} impl Copy for BigS {} impl Copy for BigU {} diff --git a/tests/codegen/repr/transparent-opaque-ptr.rs b/tests/codegen/repr/transparent-opaque-ptr.rs index 798b7e01bba5..7911370c478c 100644 --- a/tests/codegen/repr/transparent-opaque-ptr.rs +++ b/tests/codegen/repr/transparent-opaque-ptr.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: aarch64-linux aarch64-darwin wasm32-wasip1 //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes @@ -19,14 +20,9 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; -impl Copy for [u32; 16] {} impl Copy for BigS {} impl Copy for BigU {} diff --git a/tests/codegen/repr/transparent-sparc64.rs b/tests/codegen/repr/transparent-sparc64.rs index 05c090bd6721..62bfc8a5fce2 100644 --- a/tests/codegen/repr/transparent-sparc64.rs +++ b/tests/codegen/repr/transparent-sparc64.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes --target sparc64-unknown-linux-gnu //@ needs-llvm-components: sparc @@ -8,14 +9,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} - -impl Copy for [u32; 16] {} +extern crate minicore; +use minicore::*; impl Copy for BigS {} impl Copy for BigU {} diff --git a/tests/codegen/repr/transparent-sysv64.rs b/tests/codegen/repr/transparent-sysv64.rs index 99c855db9620..3efc3f7c3911 100644 --- a/tests/codegen/repr/transparent-sysv64.rs +++ b/tests/codegen/repr/transparent-sysv64.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: linux apple win //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes @@ -13,12 +14,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(C)] pub struct Rgb8 { diff --git a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs index 46f747ad4075..df99f6969fc1 100644 --- a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs +++ b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: --target riscv64gc-unknown-linux-gnu -Copt-level=3 -C no-prepopulate-passes -C panic=abort //@ needs-llvm-components: riscv @@ -6,19 +7,8 @@ #![feature(no_core, lang_items)] #![allow(improper_ctypes)] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for bool {} -impl Copy for i8 {} -impl Copy for u8 {} -impl Copy for i32 {} -impl Copy for i64 {} -impl Copy for u64 {} -impl Copy for f32 {} -impl Copy for f64 {} -impl Copy for *mut T {} +extern crate minicore; +use minicore::*; // CHECK: define void @f_void() #[no_mangle] diff --git a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs index bef8fe0c0441..d768ab9381aa 100644 --- a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs +++ b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes --target riscv64gc-unknown-linux-gnu //@ needs-llvm-components: riscv @@ -6,12 +7,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // CHECK: define void @f_fpr_tracking(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, i8 noundef zeroext %i) #[no_mangle] diff --git a/tests/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs index 214370f424c2..361f03226904 100644 --- a/tests/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs +++ b/tests/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes --target riscv64gc-unknown-linux-gnu //@ needs-llvm-components: riscv @@ -6,12 +7,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // CHECK: define void @f_fpr_tracking(float %0, float %1, float %2, float %3, float %4, float %5, float %6, float %7, i8 noundef zeroext %i) #[no_mangle] diff --git a/tests/codegen/riscv-target-abi.rs b/tests/codegen/riscv-target-abi.rs index 88da4ece7ba3..d41fcb4dd845 100644 --- a/tests/codegen/riscv-target-abi.rs +++ b/tests/codegen/riscv-target-abi.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions:riscv64gc riscv32gc riscv32imac //@[riscv64gc] compile-flags: --target=riscv64gc-unknown-linux-gnu @@ -16,5 +17,5 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; diff --git a/tests/codegen/sanitizer/aarch64-shadow-call-stack-with-fixed-x18.rs b/tests/codegen/sanitizer/aarch64-shadow-call-stack-with-fixed-x18.rs index e2e14ab14a80..e1d7dc2d631f 100644 --- a/tests/codegen/sanitizer/aarch64-shadow-call-stack-with-fixed-x18.rs +++ b/tests/codegen/sanitizer/aarch64-shadow-call-stack-with-fixed-x18.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: aarch64 android //@[aarch64] compile-flags: --target aarch64-unknown-none -Zfixed-x18 -Zsanitizer=shadow-call-stack //@[aarch64] needs-llvm-components: aarch64 @@ -9,8 +10,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // CHECK: ; Function Attrs:{{.*}}shadowcallstack #[no_mangle] diff --git a/tests/codegen/sanitizer/kasan-emits-instrumentation.rs b/tests/codegen/sanitizer/kasan-emits-instrumentation.rs index 56ee875286a2..774c9ab53f1e 100644 --- a/tests/codegen/sanitizer/kasan-emits-instrumentation.rs +++ b/tests/codegen/sanitizer/kasan-emits-instrumentation.rs @@ -1,5 +1,6 @@ // Verifies that `-Zsanitizer=kernel-address` emits sanitizer instrumentation. +//@ add-core-stubs //@ compile-flags: -Zsanitizer=kernel-address -Copt-level=0 //@ revisions: aarch64 riscv64imac riscv64gc x86_64 //@[aarch64] compile-flags: --target aarch64-unknown-none @@ -15,13 +16,8 @@ #![feature(no_core, no_sanitize, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[lang = "copy"] -trait Copy {} - -impl Copy for u8 {} +extern crate minicore; +use minicore::*; // CHECK-LABEL: ; kasan_emits_instrumentation::unsanitized // CHECK-NEXT: ; Function Attrs: diff --git a/tests/codegen/sanitizer/kcfi/add-cfi-normalize-integers-flag.rs b/tests/codegen/sanitizer/kcfi/add-cfi-normalize-integers-flag.rs index d48e4016a16c..0be1ff197749 100644 --- a/tests/codegen/sanitizer/kcfi/add-cfi-normalize-integers-flag.rs +++ b/tests/codegen/sanitizer/kcfi/add-cfi-normalize-integers-flag.rs @@ -1,5 +1,6 @@ // Verifies that "cfi-normalize-integers" module flag is added. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,10 +12,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; pub fn foo() {} diff --git a/tests/codegen/sanitizer/kcfi/add-kcfi-flag.rs b/tests/codegen/sanitizer/kcfi/add-kcfi-flag.rs index 013de74f8d68..eabe0409c9a3 100644 --- a/tests/codegen/sanitizer/kcfi/add-kcfi-flag.rs +++ b/tests/codegen/sanitizer/kcfi/add-kcfi-flag.rs @@ -1,5 +1,6 @@ // Verifies that "kcfi" module flag is added. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,10 +12,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; pub fn foo() {} diff --git a/tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs b/tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs index b4924719f4c1..2f18c9d84b90 100644 --- a/tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs +++ b/tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs @@ -1,5 +1,6 @@ // Verifies that "kcfi-offset" module flag is added. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,10 +12,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; pub fn foo() {} diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs index ba2e397f6daa..6b40918dd3af 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs @@ -1,5 +1,6 @@ // Verifies that KCFI operand bundles are omitted. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,12 +12,8 @@ #![feature(no_core, no_sanitize, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -impl Copy for i32 {} +extern crate minicore; +use minicore::*; #[no_sanitize(kcfi)] pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs index 4e95bdf4d7c4..942b50deb028 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs @@ -1,5 +1,6 @@ // Verifies that generalized KCFI type metadata for functions are emitted. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,12 +12,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -impl Copy for i32 {} +extern crate minicore; +use minicore::*; pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs index 31b43b509880..c89d9bdd1217 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs @@ -1,5 +1,6 @@ // Verifies that normalized and generalized KCFI type metadata for functions are emitted. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,12 +12,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -impl Copy for i32 {} +extern crate minicore; +use minicore::*; pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs index 4755f6062aaa..220cae1a4fa3 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs @@ -1,5 +1,6 @@ // Verifies that normalized KCFI type metadata for functions are emitted. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,12 +12,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -impl Copy for i32 {} +extern crate minicore; +use minicore::*; pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs index be9760bd9afa..bb9a00059030 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs @@ -1,5 +1,6 @@ // Verifies that KCFI type metadata for functions are emitted. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,12 +12,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -impl Copy for i32 {} +extern crate minicore; +use minicore::*; pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo diff --git a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle.rs b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle.rs index c9c94cdb3292..8b844b991429 100644 --- a/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle.rs +++ b/tests/codegen/sanitizer/kcfi/emit-kcfi-operand-bundle.rs @@ -1,5 +1,6 @@ // Verifies that KCFI operand bundles are emitted. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,12 +12,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -impl Copy for i32 {} +extern crate minicore; +use minicore::*; pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-LABEL: define{{.*}}foo{{.*}}!{{|kcfi_type}} !{{[0-9]+}} diff --git a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs index 5ab55a467268..15c107bea158 100644 --- a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs +++ b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs @@ -1,5 +1,6 @@ // Verifies that type metadata identifiers for trait objects are emitted correctly. // +//@ add-core-stubs //@ revisions: aarch64 x86_64 //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 @@ -11,29 +12,8 @@ #![feature(arbitrary_self_types, no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for &T {} -#[lang = "legacy_receiver"] -trait LegacyReceiver {} -#[lang = "dispatch_from_dyn"] -trait DispatchFromDyn {} -impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} -#[lang = "unsize"] -trait Unsize {} -#[lang = "coerce_unsized"] -pub trait CoerceUnsized {} -impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "drop_in_place"] -fn drop_in_place_fn() {} -#[lang = "drop"] -trait Drop { - fn drop(&mut self); -} +extern crate minicore; +use minicore::*; pub trait Trait1 { fn foo(&self); diff --git a/tests/codegen/sanitizer/riscv64-shadow-call-stack.rs b/tests/codegen/sanitizer/riscv64-shadow-call-stack.rs index 5833b832ba40..945e46218d04 100644 --- a/tests/codegen/sanitizer/riscv64-shadow-call-stack.rs +++ b/tests/codegen/sanitizer/riscv64-shadow-call-stack.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: --target riscv64imac-unknown-none-elf -Zsanitizer=shadow-call-stack //@ needs-llvm-components: riscv @@ -6,8 +7,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // CHECK: ; Function Attrs:{{.*}}shadowcallstack // CHECK: define dso_local void @foo() unnamed_addr #0 diff --git a/tests/codegen/some-abis-do-extend-params-to-32-bits.rs b/tests/codegen/some-abis-do-extend-params-to-32-bits.rs index 10970cacdcf0..6ca6697588fd 100644 --- a/tests/codegen/some-abis-do-extend-params-to-32-bits.rs +++ b/tests/codegen/some-abis-do-extend-params-to-32-bits.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: -Cno-prepopulate-passes -Copt-level=0 //@ revisions:x86_64 i686 aarch64-apple aarch64-windows aarch64-linux arm riscv @@ -24,12 +25,8 @@ #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // The patterns in this file are written in the style of a table to make the // uniformities and distinctions more apparent. diff --git a/tests/codegen/sparc-struct-abi.rs b/tests/codegen/sparc-struct-abi.rs index 0a8720c4fcae..32d2c5bb0ef8 100644 --- a/tests/codegen/sparc-struct-abi.rs +++ b/tests/codegen/sparc-struct-abi.rs @@ -1,17 +1,14 @@ // Checks that we correctly codegen extern "C" functions returning structs. // See issues #52638 and #86163. +//@ add-core-stubs //@ compile-flags: -Copt-level=3 --target=sparc64-unknown-linux-gnu --crate-type=rlib //@ needs-llvm-components: sparc #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(C)] pub struct Bool { diff --git a/tests/codegen/stack-probes-inline.rs b/tests/codegen/stack-probes-inline.rs index c5073b9cc221..746272b09941 100644 --- a/tests/codegen/stack-probes-inline.rs +++ b/tests/codegen/stack-probes-inline.rs @@ -1,6 +1,7 @@ // Check the "probe-stack" attribute for targets with `StackProbeType::Inline`, // or `StackProbeType::InlineOrCall` when running on newer LLVM. +//@ add-core-stubs //@ compile-flags: -C no-prepopulate-passes //@ revisions: aarch64 powerpc powerpc64 powerpc64le s390x i686 x86_64 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu @@ -22,8 +23,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; #[no_mangle] pub fn foo() { diff --git a/tests/codegen/target-feature-overrides.rs b/tests/codegen/target-feature-overrides.rs index f38a1ae72de5..0fc1e0136b3f 100644 --- a/tests/codegen/target-feature-overrides.rs +++ b/tests/codegen/target-feature-overrides.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: COMPAT INCOMPAT //@ needs-llvm-components: x86 //@ compile-flags: --target=x86_64-unknown-linux-gnu -Copt-level=3 @@ -9,10 +10,8 @@ #![crate_type = "lib"] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; extern "C" { fn peach() -> u32; diff --git a/tests/codegen/tied-features-strength.rs b/tests/codegen/tied-features-strength.rs index 1b2b63c3d1ac..8b1f3b14fc30 100644 --- a/tests/codegen/tied-features-strength.rs +++ b/tests/codegen/tied-features-strength.rs @@ -1,4 +1,5 @@ // ignore-tidy-linelength +//@ add-core-stubs //@ revisions: ENABLE_SVE DISABLE_SVE DISABLE_NEON ENABLE_NEON //@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu //@ needs-llvm-components: aarch64 @@ -22,7 +23,7 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; pub fn test() {} diff --git a/tests/ui/abi/arm-unadjusted-intrinsic.rs b/tests/ui/abi/arm-unadjusted-intrinsic.rs index 533cd40b30a5..dcf0d9f39f67 100644 --- a/tests/ui/abi/arm-unadjusted-intrinsic.rs +++ b/tests/ui/abi/arm-unadjusted-intrinsic.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ build-pass //@ revisions: arm //@[arm] compile-flags: --target arm-unknown-linux-gnueabi @@ -14,19 +15,8 @@ #![crate_type = "lib"] #![allow(non_camel_case_types)] -/// To work cross-target this test must be no_core. -/// This little prelude supplies what we need. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -pub trait Copy: Sized {} -impl Copy for i8 {} -impl Copy for *const T {} -impl Copy for *mut T {} - -// I hate no_core tests! -impl Copy for [T; N] {} +extern crate minicore; +use minicore::*; // Regression test for https://github.com/rust-lang/rust/issues/118124. diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr index e1f433479857..02620da3a21a 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr @@ -1,5 +1,5 @@ error[E0703]: invalid ABI: found `riscv-interrupt` - --> $DIR/riscv-discoverability-guidance.rs:17:8 + --> $DIR/riscv-discoverability-guidance.rs:15:8 | LL | extern "riscv-interrupt" fn isr() {} | ^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | extern "riscv-interrupt" fn isr() {} = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions error[E0703]: invalid ABI: found `riscv-interrupt-u` - --> $DIR/riscv-discoverability-guidance.rs:22:8 + --> $DIR/riscv-discoverability-guidance.rs:20:8 | LL | extern "riscv-interrupt-u" fn isr_U() {} | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr index e1f433479857..02620da3a21a 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr @@ -1,5 +1,5 @@ error[E0703]: invalid ABI: found `riscv-interrupt` - --> $DIR/riscv-discoverability-guidance.rs:17:8 + --> $DIR/riscv-discoverability-guidance.rs:15:8 | LL | extern "riscv-interrupt" fn isr() {} | ^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | extern "riscv-interrupt" fn isr() {} = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions error[E0703]: invalid ABI: found `riscv-interrupt-u` - --> $DIR/riscv-discoverability-guidance.rs:22:8 + --> $DIR/riscv-discoverability-guidance.rs:20:8 | LL | extern "riscv-interrupt-u" fn isr_U() {} | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/riscv-discoverability-guidance.rs b/tests/ui/abi/riscv-discoverability-guidance.rs index dec5059b0a7f..41cce35aefad 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.rs +++ b/tests/ui/abi/riscv-discoverability-guidance.rs @@ -1,4 +1,5 @@ // ignore-tidy-linelength +//@ add-core-stubs //@ revisions: riscv32 riscv64 // //@ [riscv32] needs-llvm-components: riscv @@ -6,13 +7,10 @@ //@ [riscv64] needs-llvm-components: riscv //@ [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib #![no_core] -#![feature( - no_core, - lang_items, - abi_riscv_interrupt -)] -#[lang = "sized"] -trait Sized {} +#![feature(no_core, lang_items, abi_riscv_interrupt)] + +extern crate minicore; +use minicore::*; extern "riscv-interrupt" fn isr() {} //~^ ERROR invalid ABI diff --git a/tests/ui/abi/sparcv8plus-llvm19.rs b/tests/ui/abi/sparcv8plus-llvm19.rs index a884e5ca06f1..3d6d8568b6e5 100644 --- a/tests/ui/abi/sparcv8plus-llvm19.rs +++ b/tests/ui/abi/sparcv8plus-llvm19.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: sparc sparcv8plus sparc_cpu_v9 sparc_feature_v8plus sparc_cpu_v9_feature_v8plus //@[sparc] compile-flags: --target sparc-unknown-none-elf //@[sparc] needs-llvm-components: sparc @@ -15,10 +16,8 @@ #![feature(no_core, rustc_attrs, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[rustc_builtin_macro] macro_rules! compile_error { diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr index 7eedf26135f5..d3462ae87d33 100644 --- a/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr +++ b/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr @@ -1,5 +1,5 @@ error: -v8plus,-v9 - --> $DIR/sparcv8plus-llvm19.rs:29:1 + --> $DIR/sparcv8plus-llvm19.rs:28:1 | LL | compile_error!("-v8plus,-v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr index ac61df356780..9891aec94b86 100644 --- a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr +++ b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr @@ -1,5 +1,5 @@ error: +v8plus,+v9 - --> $DIR/sparcv8plus-llvm19.rs:34:1 + --> $DIR/sparcv8plus-llvm19.rs:33:1 | LL | compile_error!("+v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr index ac61df356780..9891aec94b86 100644 --- a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr +++ b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,+v9 - --> $DIR/sparcv8plus-llvm19.rs:34:1 + --> $DIR/sparcv8plus-llvm19.rs:33:1 | LL | compile_error!("+v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr index 1bf7a3ad76a8..dbcdb8ed121b 100644 --- a/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr +++ b/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,-v9 (FIXME) - --> $DIR/sparcv8plus-llvm19.rs:39:1 + --> $DIR/sparcv8plus-llvm19.rs:38:1 | LL | compile_error!("+v8plus,-v9 (FIXME)"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr index ac61df356780..9891aec94b86 100644 --- a/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr +++ b/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,+v9 - --> $DIR/sparcv8plus-llvm19.rs:34:1 + --> $DIR/sparcv8plus-llvm19.rs:33:1 | LL | compile_error!("+v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus.rs b/tests/ui/abi/sparcv8plus.rs index a78ae0cd3288..6c17f7218386 100644 --- a/tests/ui/abi/sparcv8plus.rs +++ b/tests/ui/abi/sparcv8plus.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: sparc sparcv8plus sparc_cpu_v9 sparc_feature_v8plus sparc_cpu_v9_feature_v8plus //@[sparc] compile-flags: --target sparc-unknown-none-elf //@[sparc] needs-llvm-components: sparc @@ -15,10 +16,8 @@ #![feature(no_core, rustc_attrs, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[rustc_builtin_macro] macro_rules! compile_error { diff --git a/tests/ui/abi/sparcv8plus.sparc.stderr b/tests/ui/abi/sparcv8plus.sparc.stderr index 6d14ff53ab9c..e2aa89a92731 100644 --- a/tests/ui/abi/sparcv8plus.sparc.stderr +++ b/tests/ui/abi/sparcv8plus.sparc.stderr @@ -1,5 +1,5 @@ error: -v8plus,-v9 - --> $DIR/sparcv8plus.rs:29:1 + --> $DIR/sparcv8plus.rs:28:1 | LL | compile_error!("-v8plus,-v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr b/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr index 00fd7ef4ea8f..2c5699f2dec2 100644 --- a/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr +++ b/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr @@ -1,5 +1,5 @@ error: -v8plus,+v9 - --> $DIR/sparcv8plus.rs:42:1 + --> $DIR/sparcv8plus.rs:41:1 | LL | compile_error!("-v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr index a3c74e67f8f1..4b96e4421f9f 100644 --- a/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr +++ b/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,+v9 - --> $DIR/sparcv8plus.rs:33:1 + --> $DIR/sparcv8plus.rs:32:1 | LL | compile_error!("+v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr index 84f560d158ca..dfdec88961be 100644 --- a/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr +++ b/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,-v9 (FIXME) - --> $DIR/sparcv8plus.rs:38:1 + --> $DIR/sparcv8plus.rs:37:1 | LL | compile_error!("+v8plus,-v9 (FIXME)"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus.sparcv8plus.stderr b/tests/ui/abi/sparcv8plus.sparcv8plus.stderr index a3c74e67f8f1..4b96e4421f9f 100644 --- a/tests/ui/abi/sparcv8plus.sparcv8plus.stderr +++ b/tests/ui/abi/sparcv8plus.sparcv8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,+v9 - --> $DIR/sparcv8plus.rs:33:1 + --> $DIR/sparcv8plus.rs:32:1 | LL | compile_error!("+v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 2eb6ab08232e..01f071f1f310 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:41:1 + --> $DIR/unsupported.rs:40:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:65:1 + --> $DIR/unsupported.rs:64:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:79:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:89:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:97:17 + --> $DIR/unsupported.rs:96:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:107:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:119:15 + --> $DIR/unsupported.rs:118:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:129:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:155:1 + --> $DIR/unsupported.rs:154:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -114,13 +114,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:181:1 + --> $DIR/unsupported.rs:180:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -138,67 +138,67 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:201:1 + --> $DIR/unsupported.rs:200:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:34:1 + --> $DIR/unsupported.rs:33:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:72:1 + --> $DIR/unsupported.rs:71:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:1 + --> $DIR/unsupported.rs:81:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:1 + --> $DIR/unsupported.rs:91:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:114:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:136:1 + --> $DIR/unsupported.rs:135:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:162:1 + --> $DIR/unsupported.rs:161:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:194:1 + --> $DIR/unsupported.rs:193:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index ee878379cc64..dfb4b573349b 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:41:1 + --> $DIR/unsupported.rs:40:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:79:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:89:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:97:17 + --> $DIR/unsupported.rs:96:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:107:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:119:15 + --> $DIR/unsupported.rs:118:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:129:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:155:1 + --> $DIR/unsupported.rs:154:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:181:1 + --> $DIR/unsupported.rs:180:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,61 +123,61 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:201:1 + --> $DIR/unsupported.rs:200:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:34:1 + --> $DIR/unsupported.rs:33:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:72:1 + --> $DIR/unsupported.rs:71:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:1 + --> $DIR/unsupported.rs:81:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:1 + --> $DIR/unsupported.rs:91:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:114:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:136:1 + --> $DIR/unsupported.rs:135:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:162:1 + --> $DIR/unsupported.rs:161:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:194:1 + --> $DIR/unsupported.rs:193:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 02b2cdd356f7..d7b76a4730b2 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:41:1 + --> $DIR/unsupported.rs:40:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:65:1 + --> $DIR/unsupported.rs:64:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:79:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:89:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:97:17 + --> $DIR/unsupported.rs:96:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:107:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,49 +93,49 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:201:1 + --> $DIR/unsupported.rs:200:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:34:1 + --> $DIR/unsupported.rs:33:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:72:1 + --> $DIR/unsupported.rs:71:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:1 + --> $DIR/unsupported.rs:81:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:1 + --> $DIR/unsupported.rs:91:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:194:1 + --> $DIR/unsupported.rs:193:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index abf403da8bd1..eef2ead4f0f3 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:41:1 + --> $DIR/unsupported.rs:40:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:65:1 + --> $DIR/unsupported.rs:64:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:79:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:89:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:119:15 + --> $DIR/unsupported.rs:118:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:129:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:155:1 + --> $DIR/unsupported.rs:154:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:181:1 + --> $DIR/unsupported.rs:180:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,61 +123,61 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:201:1 + --> $DIR/unsupported.rs:200:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:34:1 + --> $DIR/unsupported.rs:33:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:72:1 + --> $DIR/unsupported.rs:71:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:1 + --> $DIR/unsupported.rs:81:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:114:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:136:1 + --> $DIR/unsupported.rs:135:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:162:1 + --> $DIR/unsupported.rs:161:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:194:1 + --> $DIR/unsupported.rs:193:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index abf403da8bd1..eef2ead4f0f3 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:41:1 + --> $DIR/unsupported.rs:40:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:65:1 + --> $DIR/unsupported.rs:64:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:79:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:89:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:119:15 + --> $DIR/unsupported.rs:118:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:129:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:155:1 + --> $DIR/unsupported.rs:154:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:181:1 + --> $DIR/unsupported.rs:180:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,61 +123,61 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:201:1 + --> $DIR/unsupported.rs:200:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:34:1 + --> $DIR/unsupported.rs:33:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:72:1 + --> $DIR/unsupported.rs:71:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:1 + --> $DIR/unsupported.rs:81:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:114:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:136:1 + --> $DIR/unsupported.rs:135:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:162:1 + --> $DIR/unsupported.rs:161:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:194:1 + --> $DIR/unsupported.rs:193:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index 7d4142f0dee7..84646502f6fd 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x64 i686 aarch64 arm riscv32 riscv64 // //@ [x64] needs-llvm-components: x86 @@ -25,11 +26,9 @@ abi_c_cmse_nonsecure_call, cmse_nonsecure_entry )] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; extern "ptx-kernel" fn ptx() {} //~^ ERROR is not a supported ABI diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 824a33c948ad..80613d83e588 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:36:15 + --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:41:1 + --> $DIR/unsupported.rs:40:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:52:17 + --> $DIR/unsupported.rs:51:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:65:1 + --> $DIR/unsupported.rs:64:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:74:18 + --> $DIR/unsupported.rs:73:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:79:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:84:15 + --> $DIR/unsupported.rs:83:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:89:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:97:17 + --> $DIR/unsupported.rs:96:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:107:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:142:20 + --> $DIR/unsupported.rs:141:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:155:1 + --> $DIR/unsupported.rs:154:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:168:19 + --> $DIR/unsupported.rs:167:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:181:1 + --> $DIR/unsupported.rs:180:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:188:21 + --> $DIR/unsupported.rs:187:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:196:22 + --> $DIR/unsupported.rs:195:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,61 +123,61 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:201:1 + --> $DIR/unsupported.rs:200:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:34:1 + --> $DIR/unsupported.rs:33:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:72:1 + --> $DIR/unsupported.rs:71:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:1 + --> $DIR/unsupported.rs:81:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:1 + --> $DIR/unsupported.rs:91:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:136:1 + --> $DIR/unsupported.rs:135:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:162:1 + --> $DIR/unsupported.rs:161:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:194:1 + --> $DIR/unsupported.rs:193:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs b/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs index 707bcac78bf9..227860436931 100644 --- a/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs +++ b/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs // Test that we do not ICE when the self type is `ty::err`, but rather // just propagate the error. @@ -6,17 +7,8 @@ #![feature(no_core)] #![no_core] -#[lang="sized"] -pub trait Sized { - // Empty. -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, _: RHS) -> Self::Output; -} +extern crate minicore; +use minicore::*; fn ice(a: A) { let r = loop {}; diff --git a/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr b/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr index ebe56c8cd689..0bbb601a6d23 100644 --- a/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr +++ b/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr @@ -1,14 +1,8 @@ error[E0277]: the trait bound `(): Add` is not satisfied - --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:23:11 + --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:15:11 | LL | r = r + a; | ^ the trait `Add` is not implemented for `()` - | -help: this trait has no implementations, consider adding one - --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:15:1 - | -LL | trait Add { - | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-92157.rs b/tests/ui/borrowck/issue-92157.rs index a2b685cdf6ed..72f216e301df 100644 --- a/tests/ui/borrowck/issue-92157.rs +++ b/tests/ui/borrowck/issue-92157.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs #![feature(no_core)] #![feature(lang_items)] @@ -13,28 +14,7 @@ fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { 40+2 } -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - drop_in_place(to_drop) -} - -#[lang = "add"] -trait Add { - type Output; - fn add(self, other: RHS) -> Self::Output; -} - -impl Add for isize { - type Output = isize; - fn add(self, other: isize) -> isize { - self + other - } -} +extern crate minicore; +use minicore::*; fn main() {} diff --git a/tests/ui/borrowck/issue-92157.stderr b/tests/ui/borrowck/issue-92157.stderr index 0ffedccd6906..248d700ab4b9 100644 --- a/tests/ui/borrowck/issue-92157.stderr +++ b/tests/ui/borrowck/issue-92157.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/issue-92157.rs:11:1 + --> $DIR/issue-92157.rs:12:1 | LL | fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/c-variadic/variadic-ffi-1.rs b/tests/ui/c-variadic/variadic-ffi-1.rs index e41ab2692111..9dcd55d13e3c 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.rs +++ b/tests/ui/c-variadic/variadic-ffi-1.rs @@ -1,9 +1,11 @@ +//@ add-core-stubs //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib #![no_core] #![feature(no_core, lang_items)] -#[lang="sized"] -trait Sized { } + +extern crate minicore; +use minicore::*; extern "stdcall" { fn printf(_: *const u8, ...); diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr index 39dfb2548a3b..f99abed0a625 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.stderr +++ b/tests/ui/c-variadic/variadic-ffi-1.stderr @@ -1,17 +1,17 @@ error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` - --> $DIR/variadic-ffi-1.rs:9:5 + --> $DIR/variadic-ffi-1.rs:11:5 | LL | fn printf(_: *const u8, ...); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied - --> $DIR/variadic-ffi-1.rs:22:9 + --> $DIR/variadic-ffi-1.rs:24:9 | LL | foo(); | ^^^-- two arguments of type `isize` and `u8` are missing | note: function defined here - --> $DIR/variadic-ffi-1.rs:15:8 + --> $DIR/variadic-ffi-1.rs:17:8 | LL | fn foo(f: isize, x: u8, ...); | ^^^ - - @@ -21,13 +21,13 @@ LL | foo(/* isize */, /* u8 */); | +++++++++++++++++++++ error[E0060]: this function takes at least 2 arguments but 1 argument was supplied - --> $DIR/variadic-ffi-1.rs:23:9 + --> $DIR/variadic-ffi-1.rs:25:9 | LL | foo(1); | ^^^--- argument #2 of type `u8` is missing | note: function defined here - --> $DIR/variadic-ffi-1.rs:15:8 + --> $DIR/variadic-ffi-1.rs:17:8 | LL | fn foo(f: isize, x: u8, ...); | ^^^ - @@ -37,7 +37,7 @@ LL | foo(1, /* u8 */); | ++++++++++ error[E0308]: mismatched types - --> $DIR/variadic-ffi-1.rs:25:56 + --> $DIR/variadic-ffi-1.rs:27:56 | LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo; | ------------------------------------- ^^^ expected non-variadic fn, found variadic function @@ -48,7 +48,7 @@ LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo; found fn item `unsafe extern "C" fn(_, _, ...) {foo}` error[E0308]: mismatched types - --> $DIR/variadic-ffi-1.rs:26:54 + --> $DIR/variadic-ffi-1.rs:28:54 | LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar; | ----------------------------------- ^^^ expected variadic fn, found non-variadic function @@ -59,7 +59,7 @@ LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar; found fn item `extern "C" fn(_, _) {bar}` error[E0617]: can't pass `f32` to variadic function - --> $DIR/variadic-ffi-1.rs:28:19 + --> $DIR/variadic-ffi-1.rs:30:19 | LL | foo(1, 2, 3f32); | ^^^^ @@ -70,7 +70,7 @@ LL | foo(1, 2, 3f32 as c_double); | +++++++++++ error[E0617]: can't pass `bool` to variadic function - --> $DIR/variadic-ffi-1.rs:29:19 + --> $DIR/variadic-ffi-1.rs:31:19 | LL | foo(1, 2, true); | ^^^^ @@ -81,7 +81,7 @@ LL | foo(1, 2, true as c_int); | ++++++++ error[E0617]: can't pass `i8` to variadic function - --> $DIR/variadic-ffi-1.rs:30:19 + --> $DIR/variadic-ffi-1.rs:32:19 | LL | foo(1, 2, 1i8); | ^^^ @@ -92,7 +92,7 @@ LL | foo(1, 2, 1i8 as c_int); | ++++++++ error[E0617]: can't pass `u8` to variadic function - --> $DIR/variadic-ffi-1.rs:31:19 + --> $DIR/variadic-ffi-1.rs:33:19 | LL | foo(1, 2, 1u8); | ^^^ @@ -103,7 +103,7 @@ LL | foo(1, 2, 1u8 as c_uint); | +++++++++ error[E0617]: can't pass `i16` to variadic function - --> $DIR/variadic-ffi-1.rs:32:19 + --> $DIR/variadic-ffi-1.rs:34:19 | LL | foo(1, 2, 1i16); | ^^^^ @@ -114,7 +114,7 @@ LL | foo(1, 2, 1i16 as c_int); | ++++++++ error[E0617]: can't pass `u16` to variadic function - --> $DIR/variadic-ffi-1.rs:33:19 + --> $DIR/variadic-ffi-1.rs:35:19 | LL | foo(1, 2, 1u16); | ^^^^ diff --git a/tests/ui/check-cfg/my-awesome-platform.json b/tests/ui/check-cfg/my-awesome-platform.json index 5e9ab8f1a2d0..03b08b727bd3 100644 --- a/tests/ui/check-cfg/my-awesome-platform.json +++ b/tests/ui/check-cfg/my-awesome-platform.json @@ -1,6 +1,6 @@ { "llvm-target": "x86_64-unknown-none-gnu", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", "arch": "x86_64", "target-endian": "little", "target-pointer-width": "64", diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index b52decdf6c0c..d473f39c3d6a 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs @@ -1,5 +1,6 @@ // This test checks that we don't lint values defined by a custom target (target json) // +//@ add-core-stubs //@ check-pass //@ no-auto-check-cfg //@ needs-llvm-components: x86 @@ -8,8 +9,8 @@ #![feature(lang_items, no_core, auto_traits)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; #[cfg(target_os = "linux")] fn target_os_linux() {} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs index 37c8319d98d0..b25a81b858be 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs @@ -1,13 +1,12 @@ +//@ add-core-stubs //@ build-pass //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm #![feature(abi_c_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items, intrinsics)] #![no_core] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} -impl Copy for u32 {} + +extern crate minicore; +use minicore::*; #[no_mangle] pub extern "C-cmse-nonsecure-entry" fn test( diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs index 31782b05105f..18041b080617 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs @@ -1,12 +1,11 @@ +//@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm #![feature(abi_c_cmse_nonsecure_call, no_core, lang_items)] #![no_core] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} -impl Copy for u32 {} + +extern crate minicore; +use minicore::*; #[repr(C)] struct Wrapper(T); diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr index 0560f0eec1c0..ab7c9cee4f03 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr @@ -1,11 +1,11 @@ error: function pointer types may not have generic parameters - --> $DIR/generics.rs:15:42 + --> $DIR/generics.rs:14:42 | LL | f1: extern "C-cmse-nonsecure-call" fn(U, u32, u32, u32) -> u64, | ^^^^^^^^^ error[E0412]: cannot find type `U` in this scope - --> $DIR/generics.rs:15:52 + --> $DIR/generics.rs:14:52 | LL | struct Test { | - similarly named type parameter `T` defined here @@ -23,7 +23,7 @@ LL | struct Test { | +++ error[E0562]: `impl Trait` is not allowed in `fn` pointer parameters - --> $DIR/generics.rs:18:43 + --> $DIR/generics.rs:17:43 | LL | f2: extern "C-cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> u64, | ^^^^^^^^^ @@ -31,19 +31,19 @@ LL | f2: extern "C-cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> u64, = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0798]: function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type - --> $DIR/generics.rs:20:9 + --> $DIR/generics.rs:19:9 | LL | f3: extern "C-cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0798]: function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type - --> $DIR/generics.rs:21:9 + --> $DIR/generics.rs:20:9 | LL | f4: extern "C-cmse-nonsecure-call" fn(Wrapper, u32, u32, u32) -> u64, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:27:73 + --> $DIR/generics.rs:26:73 | LL | type WithTraitObject = extern "C-cmse-nonsecure-call" fn(&dyn Trait) -> &dyn Trait; | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -52,7 +52,7 @@ LL | type WithTraitObject = extern "C-cmse-nonsecure-call" fn(&dyn Trait) -> &dy = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:31:62 + --> $DIR/generics.rs:30:62 | LL | extern "C-cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn Trait; | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -61,7 +61,7 @@ LL | extern "C-cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn T = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:38:62 + --> $DIR/generics.rs:37:62 | LL | extern "C-cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTransparent; | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -70,7 +70,7 @@ LL | extern "C-cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTranspa = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` - --> $DIR/generics.rs:41:20 + --> $DIR/generics.rs:40:20 | LL | type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs index 083a563bd7ba..8328f9b6dd55 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs @@ -1,12 +1,11 @@ +//@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm #![feature(abi_c_cmse_nonsecure_call, no_core, lang_items)] #![no_core] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} -impl Copy for u32 {} + +extern crate minicore; +use minicore::*; #[repr(C, align(16))] #[allow(unused)] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr index a5f5e1c3151d..10a5e8561075 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: arguments for `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:17:63 + --> $DIR/params-via-stack.rs:16:63 | LL | f1: extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32, x: u32, y: u32), | ^^^^^^^^^^^^^^ these arguments don't fit in the available registers @@ -7,7 +7,7 @@ LL | f1: extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32, x: u32, y: u3 = note: functions with the `"C-cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers error[E0798]: arguments for `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:18:63 + --> $DIR/params-via-stack.rs:17:63 | LL | f2: extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u16, u16), | ^^^ this argument doesn't fit in the available registers @@ -15,7 +15,7 @@ LL | f2: extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u16, u16), = note: functions with the `"C-cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers error[E0798]: arguments for `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:19:53 + --> $DIR/params-via-stack.rs:18:53 | LL | f3: extern "C-cmse-nonsecure-call" fn(u32, u64, u32), | ^^^ this argument doesn't fit in the available registers @@ -23,7 +23,7 @@ LL | f3: extern "C-cmse-nonsecure-call" fn(u32, u64, u32), = note: functions with the `"C-cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers error[E0798]: arguments for `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:20:58 + --> $DIR/params-via-stack.rs:19:58 | LL | f4: extern "C-cmse-nonsecure-call" fn(AlignRelevant, u32), | ^^^ this argument doesn't fit in the available registers @@ -31,7 +31,7 @@ LL | f4: extern "C-cmse-nonsecure-call" fn(AlignRelevant, u32), = note: functions with the `"C-cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers error[E0798]: arguments for `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:21:43 + --> $DIR/params-via-stack.rs:20:43 | LL | f5: extern "C-cmse-nonsecure-call" fn([u32; 5]), | ^^^^^^^^ this argument doesn't fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs index b052aabb499e..890ec4b00f6a 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm //@ add-core-stubs diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr index 89f7f159d6e4..d2077352900a 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:35:50 + --> $DIR/return-via-stack.rs:36:50 | LL | u128: extern "C-cmse-nonsecure-call" fn() -> u128, | ^^^^ this type doesn't fit in the available registers @@ -8,7 +8,7 @@ LL | u128: extern "C-cmse-nonsecure-call" fn() -> u128, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:36:50 + --> $DIR/return-via-stack.rs:37:50 | LL | i128: extern "C-cmse-nonsecure-call" fn() -> i128, | ^^^^ this type doesn't fit in the available registers @@ -17,7 +17,7 @@ LL | i128: extern "C-cmse-nonsecure-call" fn() -> i128, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:25:48 + --> $DIR/return-via-stack.rs:26:48 | LL | f1: extern "C-cmse-nonsecure-call" fn() -> ReprCU64, | ^^^^^^^^ this type doesn't fit in the available registers @@ -26,7 +26,7 @@ LL | f1: extern "C-cmse-nonsecure-call" fn() -> ReprCU64, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:26:48 + --> $DIR/return-via-stack.rs:27:48 | LL | f2: extern "C-cmse-nonsecure-call" fn() -> ReprCBytes, | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -35,7 +35,7 @@ LL | f2: extern "C-cmse-nonsecure-call" fn() -> ReprCBytes, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:27:48 + --> $DIR/return-via-stack.rs:28:48 | LL | f3: extern "C-cmse-nonsecure-call" fn() -> U64Compound, | ^^^^^^^^^^^ this type doesn't fit in the available registers @@ -44,7 +44,7 @@ LL | f3: extern "C-cmse-nonsecure-call" fn() -> U64Compound, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:28:48 + --> $DIR/return-via-stack.rs:29:48 | LL | f4: extern "C-cmse-nonsecure-call" fn() -> ReprCAlign16, | ^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -53,7 +53,7 @@ LL | f4: extern "C-cmse-nonsecure-call" fn() -> ReprCAlign16, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:29:48 + --> $DIR/return-via-stack.rs:30:48 | LL | f5: extern "C-cmse-nonsecure-call" fn() -> [u8; 5], | ^^^^^^^ this type doesn't fit in the available registers @@ -62,7 +62,7 @@ LL | f5: extern "C-cmse-nonsecure-call" fn() -> [u8; 5], = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:51:48 + --> $DIR/return-via-stack.rs:52:48 | LL | f1: extern "C-cmse-nonsecure-call" fn() -> ReprRustUnionU64, | ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -71,7 +71,7 @@ LL | f1: extern "C-cmse-nonsecure-call" fn() -> ReprRustUnionU64, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:52:48 + --> $DIR/return-via-stack.rs:53:48 | LL | f2: extern "C-cmse-nonsecure-call" fn() -> ReprCUnionU64, | ^^^^^^^^^^^^^ this type doesn't fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs index 9fda55c2a480..7dfe6cf9672a 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs @@ -1,13 +1,12 @@ +//@ add-core-stubs //@ build-pass //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm #![feature(abi_c_cmse_nonsecure_call, no_core, lang_items, intrinsics)] #![no_core] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} -impl Copy for u32 {} + +extern crate minicore; +use minicore::*; #[repr(transparent)] pub struct ReprTransparentStruct { diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs index 3265cf4146dc..5a2d2db19c54 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs @@ -1,8 +1,10 @@ +//@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm #![feature(abi_c_cmse_nonsecure_call, lang_items, no_core)] #![no_core] -#[lang="sized"] -trait Sized { } + +extern crate minicore; +use minicore::*; pub extern "C-cmse-nonsecure-call" fn test() {} //~ ERROR [E0781] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr index 8d1b10eaeb5b..f49fab043a47 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr @@ -1,5 +1,5 @@ error[E0781]: the `"C-cmse-nonsecure-call"` ABI is only allowed on function pointers - --> $DIR/wrong-abi-location-1.rs:8:1 + --> $DIR/wrong-abi-location-1.rs:10:1 | LL | pub extern "C-cmse-nonsecure-call" fn test() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs index b47471c6ad7c..e93b153949a3 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs @@ -1,9 +1,11 @@ +//@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm #![feature(abi_c_cmse_nonsecure_call, lang_items, no_core)] #![no_core] -#[lang="sized"] -trait Sized { } + +extern crate minicore; +use minicore::*; extern "C-cmse-nonsecure-call" { //~ ERROR [E0781] fn test(); diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr index 917098e21d82..bae8d20d81c5 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr @@ -1,5 +1,5 @@ error[E0781]: the `"C-cmse-nonsecure-call"` ABI is only allowed on function pointers - --> $DIR/wrong-abi-location-2.rs:8:1 + --> $DIR/wrong-abi-location-2.rs:10:1 | LL | / extern "C-cmse-nonsecure-call" { LL | | fn test(); diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index a264bba6f3cd..19b6179dde75 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -1,12 +1,11 @@ +//@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm #![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)] #![no_core] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} -impl Copy for u32 {} + +extern crate minicore; +use minicore::*; #[repr(C)] struct Wrapper(T); diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr index 9e67f881f75c..c314671dc297 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -1,11 +1,11 @@ error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg - --> $DIR/generics.rs:74:55 + --> $DIR/generics.rs:73:55 | LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { | ^^^^^^ error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type - --> $DIR/generics.rs:31:1 + --> $DIR/generics.rs:30:1 | LL | / extern "C-cmse-nonsecure-entry" fn introduced_generic( LL | | @@ -17,19 +17,19 @@ LL | | ) -> u64 { | |________^ error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type - --> $DIR/generics.rs:41:1 + --> $DIR/generics.rs:40:1 | LL | extern "C-cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type - --> $DIR/generics.rs:15:5 + --> $DIR/generics.rs:14:5 | LL | extern "C-cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type - --> $DIR/generics.rs:20:5 + --> $DIR/generics.rs:19:5 | LL | / extern "C-cmse-nonsecure-entry" fn ambient_generic_nested( LL | | @@ -41,7 +41,7 @@ LL | | ) -> u64 { | |____________^ error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:52:67 + --> $DIR/generics.rs:51:67 | LL | extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait { | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -50,7 +50,7 @@ LL | extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trai = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:59:6 + --> $DIR/generics.rs:58:6 | LL | ) -> &'static dyn Trait { | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -59,7 +59,7 @@ LL | ) -> &'static dyn Trait { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:69:6 + --> $DIR/generics.rs:68:6 | LL | ) -> WrapperTransparent { | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -68,7 +68,7 @@ LL | ) -> WrapperTransparent { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error: requires `va_list` lang_item - --> $DIR/generics.rs:74:55 + --> $DIR/generics.rs:73:55 | LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { | ^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs index 572d792d5a5d..4c53f9422dab 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs @@ -1,12 +1,11 @@ +//@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for u32 {} + +extern crate minicore; +use minicore::*; #[repr(C, align(16))] #[allow(unused)] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr index b77e64c6bfba..24e9ddf32feb 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:16:78 + --> $DIR/params-via-stack.rs:15:78 | LL | pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {} | ^^^^^^^^^^^ these arguments don't fit in the available registers @@ -7,7 +7,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _ = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:18:78 + --> $DIR/params-via-stack.rs:17:78 | LL | pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {} | ^^^ this argument doesn't fit in the available registers @@ -15,7 +15,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _ = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:20:62 + --> $DIR/params-via-stack.rs:19:62 | LL | pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} | ^^^ this argument doesn't fit in the available registers @@ -23,7 +23,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:22:64 + --> $DIR/params-via-stack.rs:21:64 | LL | pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} | ^^^ this argument doesn't fit in the available registers @@ -31,7 +31,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:26:46 + --> $DIR/params-via-stack.rs:25:46 | LL | pub extern "C-cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} | ^^^^^^^^ this argument doesn't fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs index 23d55526e578..735eab10fa15 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm //@ add-core-stubs diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr index d37d9b5e8ff7..9c885d953181 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:24:48 + --> $DIR/return-via-stack.rs:25:48 | LL | pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 { | ^^^^^^^^ this type doesn't fit in the available registers @@ -8,7 +8,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:29:48 + --> $DIR/return-via-stack.rs:30:48 | LL | pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes { | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -17,7 +17,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:34:48 + --> $DIR/return-via-stack.rs:35:48 | LL | pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound { | ^^^^^^^^^^^ this type doesn't fit in the available registers @@ -26,7 +26,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:39:48 + --> $DIR/return-via-stack.rs:40:48 | LL | pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { | ^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -35,7 +35,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:46:48 + --> $DIR/return-via-stack.rs:47:48 | LL | pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] { | ^^^^^^^ this type doesn't fit in the available registers @@ -44,7 +44,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:52:50 + --> $DIR/return-via-stack.rs:53:50 | LL | pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 { | ^^^^ this type doesn't fit in the available registers @@ -53,7 +53,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:58:50 + --> $DIR/return-via-stack.rs:59:50 | LL | pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 { | ^^^^ this type doesn't fit in the available registers @@ -62,7 +62,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:75:56 + --> $DIR/return-via-stack.rs:76:56 | LL | pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { | ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -71,7 +71,7 @@ LL | pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:80:53 + --> $DIR/return-via-stack.rs:81:53 | LL | pub extern "C-cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 { | ^^^^^^^^^^^^^ this type doesn't fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr index 26409279fbeb..6a90dc8d635b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr @@ -1,5 +1,5 @@ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/trustzone-only.rs:20:1 + --> $DIR/trustzone-only.rs:17:1 | LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs index a4ea7a1757d2..6d84dab2166e 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: x86 aarch64 thumb7 // //@[x86] compile-flags: --target x86_64-unknown-linux-gnu @@ -9,12 +10,8 @@ #![feature(no_core, lang_items, rustc_attrs, cmse_nonsecure_entry)] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -impl Copy for u32 {} +extern crate minicore; +use minicore::*; #[no_mangle] pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr index 26409279fbeb..6a90dc8d635b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr @@ -1,5 +1,5 @@ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/trustzone-only.rs:20:1 + --> $DIR/trustzone-only.rs:17:1 | LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr index 26409279fbeb..6a90dc8d635b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr @@ -1,5 +1,5 @@ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/trustzone-only.rs:20:1 + --> $DIR/trustzone-only.rs:17:1 | LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs index 8978b35d356f..912fc8b85ebd 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs @@ -1,15 +1,13 @@ +//@ add-core-stubs //@ build-pass //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for u32 {} -impl Copy for u8 {} + +extern crate minicore; +use minicore::*; #[repr(transparent)] pub struct ReprTransparentStruct { diff --git a/tests/ui/deriving/deriving-with-helper.rs b/tests/ui/deriving/deriving-with-helper.rs index c71d553c8927..df98bb6beb9f 100644 --- a/tests/ui/deriving/deriving-with-helper.rs +++ b/tests/ui/deriving/deriving-with-helper.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ check-pass //@ compile-flags: --crate-type=lib @@ -8,6 +9,9 @@ #![no_core] +extern crate minicore; +use minicore::*; + #[rustc_builtin_macro] macro derive() {} @@ -26,9 +30,6 @@ mod default { } } -#[lang = "sized"] -trait Sized {} - #[derive(Default)] enum S { #[default] // OK diff --git a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs index ce3d3fc645d7..6901a2ab9f18 100644 --- a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs @@ -1,9 +1,11 @@ +//@ add-core-stubs //@ needs-llvm-components: avr //@ compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib #![no_core] #![feature(no_core, lang_items)] -#[lang="sized"] -trait Sized { } + +extern crate minicore; +use minicore::*; // Test that the AVR interrupt ABI cannot be used when avr_interrupt // feature gate is not used. diff --git a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr index d9f3c3adc7f0..768209eec632 100644 --- a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr +++ b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr @@ -1,5 +1,5 @@ error[E0658]: the extern "avr-non-blocking-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:11:8 + --> $DIR/feature-gate-abi-avr-interrupt.rs:13:8 | LL | extern "avr-non-blocking-interrupt" fn fu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | extern "avr-non-blocking-interrupt" fn fu() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:13:8 + --> $DIR/feature-gate-abi-avr-interrupt.rs:15:8 | LL | extern "avr-interrupt" fn f() {} | ^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | extern "avr-interrupt" fn f() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:17:12 + --> $DIR/feature-gate-abi-avr-interrupt.rs:19:12 | LL | extern "avr-interrupt" fn m(); | ^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | extern "avr-interrupt" fn m(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-non-blocking-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:19:12 + --> $DIR/feature-gate-abi-avr-interrupt.rs:21:12 | LL | extern "avr-non-blocking-interrupt" fn mu(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | extern "avr-non-blocking-interrupt" fn mu(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:22:12 + --> $DIR/feature-gate-abi-avr-interrupt.rs:24:12 | LL | extern "avr-interrupt" fn dm() {} | ^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | extern "avr-interrupt" fn dm() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-non-blocking-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:24:12 + --> $DIR/feature-gate-abi-avr-interrupt.rs:26:12 | LL | extern "avr-non-blocking-interrupt" fn dmu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | extern "avr-non-blocking-interrupt" fn dmu() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:30:12 + --> $DIR/feature-gate-abi-avr-interrupt.rs:32:12 | LL | extern "avr-interrupt" fn m() {} | ^^^^^^^^^^^^^^^ @@ -69,7 +69,7 @@ LL | extern "avr-interrupt" fn m() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-non-blocking-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:32:12 + --> $DIR/feature-gate-abi-avr-interrupt.rs:34:12 | LL | extern "avr-non-blocking-interrupt" fn mu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,7 +79,7 @@ LL | extern "avr-non-blocking-interrupt" fn mu() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:37:12 + --> $DIR/feature-gate-abi-avr-interrupt.rs:39:12 | LL | extern "avr-interrupt" fn im() {} | ^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | extern "avr-interrupt" fn im() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-non-blocking-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:39:12 + --> $DIR/feature-gate-abi-avr-interrupt.rs:41:12 | LL | extern "avr-non-blocking-interrupt" fn imu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL | extern "avr-non-blocking-interrupt" fn imu() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:43:18 + --> $DIR/feature-gate-abi-avr-interrupt.rs:45:18 | LL | type TA = extern "avr-interrupt" fn(); | ^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | type TA = extern "avr-interrupt" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-non-blocking-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:45:19 + --> $DIR/feature-gate-abi-avr-interrupt.rs:47:19 | LL | type TAU = extern "avr-non-blocking-interrupt" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | type TAU = extern "avr-non-blocking-interrupt" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:48:8 + --> $DIR/feature-gate-abi-avr-interrupt.rs:50:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | extern "avr-interrupt" {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "avr-non-blocking-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-avr-interrupt.rs:50:8 + --> $DIR/feature-gate-abi-avr-interrupt.rs:52:8 | LL | extern "avr-non-blocking-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs index bb69a638ceea..60bf69f597cc 100644 --- a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs @@ -1,9 +1,11 @@ +//@ add-core-stubs //@ needs-llvm-components: msp430 //@ compile-flags: --target=msp430-none-elf --crate-type=rlib #![no_core] #![feature(no_core, lang_items)] -#[lang="sized"] -trait Sized { } + +extern crate minicore; +use minicore::*; extern "msp430-interrupt" fn f() {} //~^ ERROR "msp430-interrupt" ABI is experimental diff --git a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr index 21ddbf7a86df..4a995b4efa6f 100644 --- a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr +++ b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr @@ -1,5 +1,5 @@ error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:8:8 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:10:8 | LL | extern "msp430-interrupt" fn f() {} | ^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | extern "msp430-interrupt" fn f() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:12:12 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:14:12 | LL | extern "msp430-interrupt" fn m(); | ^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | extern "msp430-interrupt" fn m(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:15:12 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:17:12 | LL | extern "msp430-interrupt" fn dm() {} | ^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | extern "msp430-interrupt" fn dm() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:21:12 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:23:12 | LL | extern "msp430-interrupt" fn m() {} | ^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | extern "msp430-interrupt" fn m() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:26:12 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:28:12 | LL | extern "msp430-interrupt" fn im() {} | ^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | extern "msp430-interrupt" fn im() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:30:18 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:32:18 | LL | type TA = extern "msp430-interrupt" fn(); | ^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | type TA = extern "msp430-interrupt" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:33:8 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:35:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs index 6f4989fbd9fe..006d01c55896 100644 --- a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs @@ -1,9 +1,11 @@ +//@ add-core-stubs //@ needs-llvm-components: riscv //@ compile-flags: --target=riscv32imc-unknown-none-elf --crate-type=rlib #![no_core] #![feature(no_core, lang_items)] -#[lang = "sized"] -trait Sized {} + +extern crate minicore; +use minicore::*; // Test that the riscv interrupt ABIs cannot be used when riscv_interrupt // feature gate is not used. diff --git a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr index 3c9e99aa1b9b..af956c35da6d 100644 --- a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr +++ b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr @@ -1,5 +1,5 @@ error[E0658]: the extern "riscv-interrupt-m" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-riscv-interrupt.rs:11:8 + --> $DIR/feature-gate-abi-riscv-interrupt.rs:13:8 | LL | extern "riscv-interrupt-m" fn f() {} | ^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | extern "riscv-interrupt-m" fn f() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "riscv-interrupt-s" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-riscv-interrupt.rs:13:8 + --> $DIR/feature-gate-abi-riscv-interrupt.rs:15:8 | LL | extern "riscv-interrupt-s" fn f_s() {} | ^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | extern "riscv-interrupt-s" fn f_s() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "riscv-interrupt-m" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-riscv-interrupt.rs:17:12 + --> $DIR/feature-gate-abi-riscv-interrupt.rs:19:12 | LL | extern "riscv-interrupt-m" fn m(); | ^^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | extern "riscv-interrupt-m" fn m(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "riscv-interrupt-m" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-riscv-interrupt.rs:23:12 + --> $DIR/feature-gate-abi-riscv-interrupt.rs:25:12 | LL | extern "riscv-interrupt-m" fn m() {} | ^^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | extern "riscv-interrupt-m" fn m() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "riscv-interrupt-m" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-riscv-interrupt.rs:28:12 + --> $DIR/feature-gate-abi-riscv-interrupt.rs:30:12 | LL | extern "riscv-interrupt-m" fn im() {} | ^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | extern "riscv-interrupt-m" fn im() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "riscv-interrupt-m" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-riscv-interrupt.rs:32:18 + --> $DIR/feature-gate-abi-riscv-interrupt.rs:34:18 | LL | type TA = extern "riscv-interrupt-m" fn(); | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs index 93c59364f10b..c4fdb5f427ca 100644 --- a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.rs @@ -1,9 +1,11 @@ +//@ add-core-stubs //@ needs-llvm-components: x86 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib #![no_core] #![feature(no_core, lang_items)] -#[lang="sized"] -trait Sized { } + +extern crate minicore; +use minicore::*; extern "x86-interrupt" fn f7() {} //~ ERROR "x86-interrupt" ABI is experimental trait Tr { diff --git a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr index 231cf207c862..67211d402c6c 100644 --- a/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr +++ b/tests/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr @@ -1,5 +1,5 @@ error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-x86-interrupt.rs:8:8 + --> $DIR/feature-gate-abi-x86-interrupt.rs:10:8 | LL | extern "x86-interrupt" fn f7() {} | ^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | extern "x86-interrupt" fn f7() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-x86-interrupt.rs:10:12 + --> $DIR/feature-gate-abi-x86-interrupt.rs:12:12 | LL | extern "x86-interrupt" fn m7(); | ^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | extern "x86-interrupt" fn m7(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-x86-interrupt.rs:11:12 + --> $DIR/feature-gate-abi-x86-interrupt.rs:13:12 | LL | extern "x86-interrupt" fn dm7() {} | ^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | extern "x86-interrupt" fn dm7() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-x86-interrupt.rs:18:12 + --> $DIR/feature-gate-abi-x86-interrupt.rs:20:12 | LL | extern "x86-interrupt" fn m7() {} | ^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | extern "x86-interrupt" fn m7() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-x86-interrupt.rs:23:12 + --> $DIR/feature-gate-abi-x86-interrupt.rs:25:12 | LL | extern "x86-interrupt" fn im7() {} | ^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | extern "x86-interrupt" fn im7() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-x86-interrupt.rs:26:18 + --> $DIR/feature-gate-abi-x86-interrupt.rs:28:18 | LL | type A7 = extern "x86-interrupt" fn(); | ^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | type A7 = extern "x86-interrupt" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "x86-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-x86-interrupt.rs:28:8 + --> $DIR/feature-gate-abi-x86-interrupt.rs:30:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-abi.rs b/tests/ui/feature-gates/feature-gate-abi.rs index 7ab05889c20a..2af623734ee8 100644 --- a/tests/ui/feature-gates/feature-gate-abi.rs +++ b/tests/ui/feature-gates/feature-gate-abi.rs @@ -1,14 +1,12 @@ // gate-test-intrinsics +//@ add-core-stubs //@ compile-flags: --crate-type=rlib #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } - -#[lang="tuple_trait"] -trait Tuple { } +extern crate minicore; +use minicore::*; // Functions extern "rust-intrinsic" fn f1() {} //~ ERROR extern "rust-intrinsic" ABI is an implementation detail diff --git a/tests/ui/feature-gates/feature-gate-abi.stderr b/tests/ui/feature-gates/feature-gate-abi.stderr index 70ec64e5135e..a974c0099cbd 100644 --- a/tests/ui/feature-gates/feature-gate-abi.stderr +++ b/tests/ui/feature-gates/feature-gate-abi.stderr @@ -1,5 +1,5 @@ error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:14:8 + --> $DIR/feature-gate-abi.rs:12:8 | LL | extern "rust-intrinsic" fn f1() {} | ^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | extern "rust-intrinsic" fn f1() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:16:8 + --> $DIR/feature-gate-abi.rs:14:8 | LL | extern "rust-intrinsic" fn f2() {} | ^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | extern "rust-intrinsic" fn f2() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-call" ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:18:8 + --> $DIR/feature-gate-abi.rs:16:8 | LL | extern "rust-call" fn f4(_: ()) {} | ^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | extern "rust-call" fn f4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:22:12 + --> $DIR/feature-gate-abi.rs:20:12 | LL | extern "rust-intrinsic" fn m1(); | ^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | extern "rust-intrinsic" fn m1(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:24:12 + --> $DIR/feature-gate-abi.rs:22:12 | LL | extern "rust-intrinsic" fn m2(); | ^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | extern "rust-intrinsic" fn m2(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-call" ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:26:12 + --> $DIR/feature-gate-abi.rs:24:12 | LL | extern "rust-call" fn m4(_: ()); | ^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | extern "rust-call" fn m4(_: ()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-call" ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:28:12 + --> $DIR/feature-gate-abi.rs:26:12 | LL | extern "rust-call" fn dm4(_: ()) {} | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | extern "rust-call" fn dm4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:35:12 + --> $DIR/feature-gate-abi.rs:33:12 | LL | extern "rust-intrinsic" fn m1() {} | ^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | extern "rust-intrinsic" fn m1() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:37:12 + --> $DIR/feature-gate-abi.rs:35:12 | LL | extern "rust-intrinsic" fn m2() {} | ^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | extern "rust-intrinsic" fn m2() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-call" ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:39:12 + --> $DIR/feature-gate-abi.rs:37:12 | LL | extern "rust-call" fn m4(_: ()) {} | ^^^^^^^^^^^ @@ -93,7 +93,7 @@ LL | extern "rust-call" fn m4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:44:12 + --> $DIR/feature-gate-abi.rs:42:12 | LL | extern "rust-intrinsic" fn im1() {} | ^^^^^^^^^^^^^^^^ @@ -102,7 +102,7 @@ LL | extern "rust-intrinsic" fn im1() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:46:12 + --> $DIR/feature-gate-abi.rs:44:12 | LL | extern "rust-intrinsic" fn im2() {} | ^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | extern "rust-intrinsic" fn im2() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-call" ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:48:12 + --> $DIR/feature-gate-abi.rs:46:12 | LL | extern "rust-call" fn im4(_: ()) {} | ^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | extern "rust-call" fn im4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:52:18 + --> $DIR/feature-gate-abi.rs:50:18 | LL | type A1 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^ @@ -130,7 +130,7 @@ LL | type A1 = extern "rust-intrinsic" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:53:18 + --> $DIR/feature-gate-abi.rs:51:18 | LL | type A2 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | type A2 = extern "rust-intrinsic" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-call" ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:54:18 + --> $DIR/feature-gate-abi.rs:52:18 | LL | type A4 = extern "rust-call" fn(_: ()); | ^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | type A4 = extern "rust-call" fn(_: ()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:57:8 + --> $DIR/feature-gate-abi.rs:55:8 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^ @@ -158,7 +158,7 @@ LL | extern "rust-intrinsic" {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-intrinsic" ABI is an implementation detail and perma-unstable - --> $DIR/feature-gate-abi.rs:58:8 + --> $DIR/feature-gate-abi.rs:56:8 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | extern "rust-intrinsic" {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "rust-call" ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:59:8 + --> $DIR/feature-gate-abi.rs:57:8 | LL | extern "rust-call" {} | ^^^^^^^^^^^ @@ -177,49 +177,49 @@ LL | extern "rust-call" {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:22:32 + --> $DIR/feature-gate-abi.rs:20:32 | LL | extern "rust-intrinsic" fn m1(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:24:32 + --> $DIR/feature-gate-abi.rs:22:32 | LL | extern "rust-intrinsic" fn m2(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:14:33 + --> $DIR/feature-gate-abi.rs:12:33 | LL | extern "rust-intrinsic" fn f1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:16:33 + --> $DIR/feature-gate-abi.rs:14:33 | LL | extern "rust-intrinsic" fn f2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:35:37 + --> $DIR/feature-gate-abi.rs:33:37 | LL | extern "rust-intrinsic" fn m1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:37:37 + --> $DIR/feature-gate-abi.rs:35:37 | LL | extern "rust-intrinsic" fn m2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:44:38 + --> $DIR/feature-gate-abi.rs:42:38 | LL | extern "rust-intrinsic" fn im1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:46:38 + --> $DIR/feature-gate-abi.rs:44:38 | LL | extern "rust-intrinsic" fn im2() {} | ^^ diff --git a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.rs b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.rs index fb04906dafe9..d9027b417b4d 100644 --- a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.rs +++ b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.rs @@ -1,13 +1,11 @@ +//@ add-core-stubs //@ compile-flags: --crate-type=rlib #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized { } - -#[lang="tuple_trait"] -trait Tuple { } +extern crate minicore; +use minicore::*; // Functions extern "gpu-kernel" fn f1(_: ()) {} //~ ERROR "gpu-kernel" ABI is experimental and subject to change diff --git a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr index b05c16e3d9ee..d8dbd94696eb 100644 --- a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr +++ b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr @@ -1,5 +1,5 @@ error[E0658]: the extern "gpu-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_gpu_kernel.rs:13:8 + --> $DIR/feature-gate-abi_gpu_kernel.rs:11:8 | LL | extern "gpu-kernel" fn f1(_: ()) {} | ^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | extern "gpu-kernel" fn f1(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "gpu-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_gpu_kernel.rs:18:12 + --> $DIR/feature-gate-abi_gpu_kernel.rs:16:12 | LL | extern "gpu-kernel" fn m1(_: ()); | ^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | extern "gpu-kernel" fn m1(_: ()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "gpu-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_gpu_kernel.rs:20:12 + --> $DIR/feature-gate-abi_gpu_kernel.rs:18:12 | LL | extern "gpu-kernel" fn dm1(_: ()) {} | ^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | extern "gpu-kernel" fn dm1(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "gpu-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_gpu_kernel.rs:28:12 + --> $DIR/feature-gate-abi_gpu_kernel.rs:26:12 | LL | extern "gpu-kernel" fn m1(_: ()) {} | ^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | extern "gpu-kernel" fn m1(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "gpu-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_gpu_kernel.rs:34:12 + --> $DIR/feature-gate-abi_gpu_kernel.rs:32:12 | LL | extern "gpu-kernel" fn im1(_: ()) {} | ^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | extern "gpu-kernel" fn im1(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "gpu-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_gpu_kernel.rs:39:18 + --> $DIR/feature-gate-abi_gpu_kernel.rs:37:18 | LL | type A1 = extern "gpu-kernel" fn(_: ()); | ^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | type A1 = extern "gpu-kernel" fn(_: ()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "gpu-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_gpu_kernel.rs:44:8 + --> $DIR/feature-gate-abi_gpu_kernel.rs:42:8 | LL | extern "gpu-kernel" {} | ^^^^^^^^^^^^ @@ -69,7 +69,7 @@ LL | extern "gpu-kernel" {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: the calling convention "gpu-kernel" is not supported on this target - --> $DIR/feature-gate-abi_gpu_kernel.rs:39:11 + --> $DIR/feature-gate-abi_gpu_kernel.rs:37:11 | LL | type A1 = extern "gpu-kernel" fn(_: ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,31 +79,31 @@ LL | type A1 = extern "gpu-kernel" fn(_: ()); = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/feature-gate-abi_gpu_kernel.rs:44:1 + --> $DIR/feature-gate-abi_gpu_kernel.rs:42:1 | LL | extern "gpu-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/feature-gate-abi_gpu_kernel.rs:13:1 + --> $DIR/feature-gate-abi_gpu_kernel.rs:11:1 | LL | extern "gpu-kernel" fn f1(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/feature-gate-abi_gpu_kernel.rs:20:5 + --> $DIR/feature-gate-abi_gpu_kernel.rs:18:5 | LL | extern "gpu-kernel" fn dm1(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/feature-gate-abi_gpu_kernel.rs:28:5 + --> $DIR/feature-gate-abi_gpu_kernel.rs:26:5 | LL | extern "gpu-kernel" fn m1(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/feature-gate-abi_gpu_kernel.rs:34:5 + --> $DIR/feature-gate-abi_gpu_kernel.rs:32:5 | LL | extern "gpu-kernel" fn im1(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-abi_ptx.rs b/tests/ui/feature-gates/feature-gate-abi_ptx.rs index e742492303ad..3cc2b7861924 100644 --- a/tests/ui/feature-gates/feature-gate-abi_ptx.rs +++ b/tests/ui/feature-gates/feature-gate-abi_ptx.rs @@ -1,9 +1,11 @@ +//@ add-core-stubs //@ needs-llvm-components: nvptx //@ compile-flags: --target=nvptx64-nvidia-cuda --crate-type=rlib #![no_core] #![feature(no_core, lang_items)] -#[lang="sized"] -trait Sized { } + +extern crate minicore; +use minicore::*; extern "ptx-kernel" fn fu() {} //~ ERROR extern "ptx-kernel" ABI is experimental diff --git a/tests/ui/feature-gates/feature-gate-abi_ptx.stderr b/tests/ui/feature-gates/feature-gate-abi_ptx.stderr index d128075919b0..cbe9fd8d834e 100644 --- a/tests/ui/feature-gates/feature-gate-abi_ptx.stderr +++ b/tests/ui/feature-gates/feature-gate-abi_ptx.stderr @@ -1,5 +1,5 @@ error[E0658]: the extern "ptx-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_ptx.rs:8:8 + --> $DIR/feature-gate-abi_ptx.rs:10:8 | LL | extern "ptx-kernel" fn fu() {} | ^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | extern "ptx-kernel" fn fu() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "ptx-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_ptx.rs:11:12 + --> $DIR/feature-gate-abi_ptx.rs:13:12 | LL | extern "ptx-kernel" fn mu(); | ^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | extern "ptx-kernel" fn mu(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "ptx-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_ptx.rs:12:12 + --> $DIR/feature-gate-abi_ptx.rs:14:12 | LL | extern "ptx-kernel" fn dmu() {} | ^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | extern "ptx-kernel" fn dmu() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "ptx-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_ptx.rs:17:12 + --> $DIR/feature-gate-abi_ptx.rs:19:12 | LL | extern "ptx-kernel" fn mu() {} | ^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | extern "ptx-kernel" fn mu() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "ptx-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_ptx.rs:21:12 + --> $DIR/feature-gate-abi_ptx.rs:23:12 | LL | extern "ptx-kernel" fn imu() {} | ^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | extern "ptx-kernel" fn imu() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "ptx-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_ptx.rs:24:19 + --> $DIR/feature-gate-abi_ptx.rs:26:19 | LL | type TAU = extern "ptx-kernel" fn(); | ^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | type TAU = extern "ptx-kernel" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "ptx-kernel" ABI is experimental and subject to change - --> $DIR/feature-gate-abi_ptx.rs:26:8 + --> $DIR/feature-gate-abi_ptx.rs:28:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_arch.rs b/tests/ui/feature-gates/feature-gate-asm_experimental_arch.rs index a52fbbe4075e..a3b41e071954 100644 --- a/tests/ui/feature-gates/feature-gate-asm_experimental_arch.rs +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_arch.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: --target mips-unknown-linux-gnu //@ needs-llvm-components: mips @@ -5,15 +6,8 @@ #![crate_type = "rlib"] #![no_core] -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; unsafe fn main() { asm!(""); diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_arch.stderr b/tests/ui/feature-gates/feature-gate-asm_experimental_arch.stderr index d930429779c0..e59a10c11c3e 100644 --- a/tests/ui/feature-gates/feature-gate-asm_experimental_arch.stderr +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_arch.stderr @@ -1,5 +1,5 @@ error[E0658]: inline assembly is not stable yet on this architecture - --> $DIR/feature-gate-asm_experimental_arch.rs:19:5 + --> $DIR/feature-gate-asm_experimental_arch.rs:13:5 | LL | asm!(""); | ^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs index 7aec7455b2e6..6c53c2213a5e 100644 --- a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ needs-asm-support //@ compile-flags: --target s390x-unknown-linux-gnu //@ needs-llvm-components: systemz @@ -6,15 +7,8 @@ #![crate_type = "rlib"] #![no_core] -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; unsafe fn main() { asm!("", in("v0") 0); diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr index 0791ce4543ca..6f2ea0ddaec1 100644 --- a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr @@ -1,5 +1,5 @@ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/feature-gate-asm_experimental_reg.rs:20:14 + --> $DIR/feature-gate-asm_experimental_reg.rs:14:14 | LL | asm!("", in("v0") 0); | ^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | asm!("", in("v0") 0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/feature-gate-asm_experimental_reg.rs:20:23 + --> $DIR/feature-gate-asm_experimental_reg.rs:14:23 | LL | asm!("", in("v0") 0); | ^ diff --git a/tests/ui/feature-gates/feature-gate-vectorcall.rs b/tests/ui/feature-gates/feature-gate-vectorcall.rs index aafa6a2ed629..b29fd08473a0 100644 --- a/tests/ui/feature-gates/feature-gate-vectorcall.rs +++ b/tests/ui/feature-gates/feature-gate-vectorcall.rs @@ -1,10 +1,12 @@ // gate-test-abi_vectorcall +//@ add-core-stubs //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib #![no_core] #![feature(no_core, lang_items)] -#[lang="sized"] -trait Sized { } + +extern crate minicore; +use minicore::*; // Test that the "vectorcall" ABI is feature-gated, and cannot be used when // the `vectorcall` feature gate is not used. diff --git a/tests/ui/feature-gates/feature-gate-vectorcall.stderr b/tests/ui/feature-gates/feature-gate-vectorcall.stderr index 8f3f47a3d488..81dd10f5fe50 100644 --- a/tests/ui/feature-gates/feature-gate-vectorcall.stderr +++ b/tests/ui/feature-gates/feature-gate-vectorcall.stderr @@ -1,5 +1,5 @@ error[E0658]: the extern "vectorcall" ABI is experimental and subject to change - --> $DIR/feature-gate-vectorcall.rs:12:8 + --> $DIR/feature-gate-vectorcall.rs:14:8 | LL | extern "vectorcall" fn f() {} | ^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | extern "vectorcall" fn f() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "vectorcall" ABI is experimental and subject to change - --> $DIR/feature-gate-vectorcall.rs:15:12 + --> $DIR/feature-gate-vectorcall.rs:17:12 | LL | extern "vectorcall" fn m(); | ^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | extern "vectorcall" fn m(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "vectorcall" ABI is experimental and subject to change - --> $DIR/feature-gate-vectorcall.rs:17:12 + --> $DIR/feature-gate-vectorcall.rs:19:12 | LL | extern "vectorcall" fn dm() {} | ^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | extern "vectorcall" fn dm() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "vectorcall" ABI is experimental and subject to change - --> $DIR/feature-gate-vectorcall.rs:22:12 + --> $DIR/feature-gate-vectorcall.rs:24:12 | LL | extern "vectorcall" fn m() {} | ^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | extern "vectorcall" fn m() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "vectorcall" ABI is experimental and subject to change - --> $DIR/feature-gate-vectorcall.rs:26:12 + --> $DIR/feature-gate-vectorcall.rs:28:12 | LL | extern "vectorcall" fn im() {} | ^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | extern "vectorcall" fn im() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "vectorcall" ABI is experimental and subject to change - --> $DIR/feature-gate-vectorcall.rs:29:18 + --> $DIR/feature-gate-vectorcall.rs:31:18 | LL | type TA = extern "vectorcall" fn(); | ^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | type TA = extern "vectorcall" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "vectorcall" ABI is experimental and subject to change - --> $DIR/feature-gate-vectorcall.rs:31:8 + --> $DIR/feature-gate-vectorcall.rs:33:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ diff --git a/tests/ui/force-inlining/asm.rs b/tests/ui/force-inlining/asm.rs index 85014ffa5158..2b5f87c59d35 100644 --- a/tests/ui/force-inlining/asm.rs +++ b/tests/ui/force-inlining/asm.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ build-fail //@ compile-flags: --crate-type=lib --target thumbv4t-none-eabi //@ needs-llvm-components: arm @@ -9,17 +10,8 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} -#[lang = "freeze"] -pub unsafe trait Freeze {} - -#[lang = "start"] -fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { - 0 -} +extern crate minicore; +use minicore::*; #[rustc_builtin_macro] #[macro_export] diff --git a/tests/ui/force-inlining/asm.stderr b/tests/ui/force-inlining/asm.stderr index ef04688965bb..1744c0215bb4 100644 --- a/tests/ui/force-inlining/asm.stderr +++ b/tests/ui/force-inlining/asm.stderr @@ -1,5 +1,5 @@ error: `instruction_set_a32` could not be inlined into `t32` but is required to be inlined - --> $DIR/asm.rs:53:5 + --> $DIR/asm.rs:45:5 | LL | instruction_set_a32(); | ^^^^^^^^^^^^^^^^^^^^^ ...`instruction_set_a32` called here @@ -7,7 +7,7 @@ LL | instruction_set_a32(); = note: could not be inlined due to: incompatible instruction set error: `inline_always_and_using_inline_asm` could not be inlined into `t32` but is required to be inlined - --> $DIR/asm.rs:57:5 + --> $DIR/asm.rs:49:5 | LL | inline_always_and_using_inline_asm(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...`inline_always_and_using_inline_asm` called here @@ -15,7 +15,7 @@ LL | inline_always_and_using_inline_asm(); = note: could not be inlined due to: cannot move inline-asm across instruction sets error: `instruction_set_a32` could not be inlined into `default` but is required to be inlined - --> $DIR/asm.rs:62:5 + --> $DIR/asm.rs:54:5 | LL | instruction_set_a32(); | ^^^^^^^^^^^^^^^^^^^^^ ...`instruction_set_a32` called here @@ -23,7 +23,7 @@ LL | instruction_set_a32(); = note: could not be inlined due to: incompatible instruction set error: `instruction_set_t32` could not be inlined into `default` but is required to be inlined - --> $DIR/asm.rs:64:5 + --> $DIR/asm.rs:56:5 | LL | instruction_set_t32(); | ^^^^^^^^^^^^^^^^^^^^^ ...`instruction_set_t32` called here diff --git a/tests/ui/layout/hexagon-enum.rs b/tests/ui/layout/hexagon-enum.rs index 5fa12e479e7d..02833eb41fad 100644 --- a/tests/ui/layout/hexagon-enum.rs +++ b/tests/ui/layout/hexagon-enum.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: --target hexagon-unknown-linux-musl //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ needs-llvm-components: hexagon @@ -9,8 +10,8 @@ #![crate_type = "lib"] #![no_core] -#[lang="sized"] -trait Sized {} +extern crate minicore; +use minicore::*; #[rustc_layout(debug)] #[repr(C)] diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 90c06ba1f834..b802b400b18b 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -71,7 +71,7 @@ error: layout_of(A) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:17:1 + --> $DIR/hexagon-enum.rs:18:1 | LL | enum A { Apple } | ^^^^^^ @@ -149,7 +149,7 @@ error: layout_of(B) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:21:1 + --> $DIR/hexagon-enum.rs:22:1 | LL | enum B { Banana = 255, } | ^^^^^^ @@ -227,7 +227,7 @@ error: layout_of(C) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:25:1 + --> $DIR/hexagon-enum.rs:26:1 | LL | enum C { Chaenomeles = 256, } | ^^^^^^ @@ -305,7 +305,7 @@ error: layout_of(P) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:29:1 + --> $DIR/hexagon-enum.rs:30:1 | LL | enum P { Peach = 0x1000_0000isize, } | ^^^^^^ @@ -383,7 +383,7 @@ error: layout_of(T) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:35:1 + --> $DIR/hexagon-enum.rs:36:1 | LL | enum T { Tangerine = TANGERINE as isize } | ^^^^^^ diff --git a/tests/ui/layout/thumb-enum.rs b/tests/ui/layout/thumb-enum.rs index 2381d9d02926..1c4fab812f96 100644 --- a/tests/ui/layout/thumb-enum.rs +++ b/tests/ui/layout/thumb-enum.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabihf //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ needs-llvm-components: arm @@ -9,8 +10,8 @@ #![crate_type = "lib"] #![no_core] -#[lang="sized"] -trait Sized {} +extern crate minicore; +use minicore::*; #[rustc_layout(debug)] #[repr(C)] diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 0c3433185647..07153fee0273 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -71,7 +71,7 @@ error: layout_of(A) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:17:1 + --> $DIR/thumb-enum.rs:18:1 | LL | enum A { Apple } | ^^^^^^ @@ -149,7 +149,7 @@ error: layout_of(B) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:21:1 + --> $DIR/thumb-enum.rs:22:1 | LL | enum B { Banana = 255, } | ^^^^^^ @@ -227,7 +227,7 @@ error: layout_of(C) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:25:1 + --> $DIR/thumb-enum.rs:26:1 | LL | enum C { Chaenomeles = 256, } | ^^^^^^ @@ -305,7 +305,7 @@ error: layout_of(P) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:29:1 + --> $DIR/thumb-enum.rs:30:1 | LL | enum P { Peach = 0x1000_0000isize, } | ^^^^^^ @@ -383,7 +383,7 @@ error: layout_of(T) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:35:1 + --> $DIR/thumb-enum.rs:36:1 | LL | enum T { Tangerine = TANGERINE as isize } | ^^^^^^ diff --git a/tests/ui/layout/too-big-with-padding.rs b/tests/ui/layout/too-big-with-padding.rs index 8423ad2e1d60..0f03bd10fb63 100644 --- a/tests/ui/layout/too-big-with-padding.rs +++ b/tests/ui/layout/too-big-with-padding.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ build-fail //@ compile-flags: --target i686-unknown-linux-gnu --crate-type lib //@ needs-llvm-components: x86 @@ -6,13 +7,11 @@ #![no_std] #![no_core] +extern crate minicore; +use minicore::*; + // 0x7fffffff is fine, but after rounding up it becomes too big #[repr(C, align(2))] pub struct Example([u8; 0x7fffffff]); pub fn lib(_x: Example) {} //~ERROR: too big for the target architecture - -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy: Sized {} diff --git a/tests/ui/layout/too-big-with-padding.stderr b/tests/ui/layout/too-big-with-padding.stderr index fc3b4db049ac..761ac7514ee3 100644 --- a/tests/ui/layout/too-big-with-padding.stderr +++ b/tests/ui/layout/too-big-with-padding.stderr @@ -1,5 +1,5 @@ error: values of the type `Example` are too big for the target architecture - --> $DIR/too-big-with-padding.rs:13:1 + --> $DIR/too-big-with-padding.rs:17:1 | LL | pub fn lib(_x: Example) {} | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/mir/checks_without_panic_impl.rs b/tests/ui/mir/checks_without_panic_impl.rs index 0dba5784daa5..11ab50a5f9af 100644 --- a/tests/ui/mir/checks_without_panic_impl.rs +++ b/tests/ui/mir/checks_without_panic_impl.rs @@ -2,6 +2,7 @@ // does not prevent crates without a panic_impl from compiling. // See rust-lang/rust#109996 +//@ add-core-stubs //@ build-pass //@ compile-flags: -Cdebug-assertions=yes @@ -11,7 +12,7 @@ #![feature(no_core)] #![no_core] -#[lang = "sized"] -trait Foo {} +extern crate minicore; +use minicore::*; pub unsafe fn foo(x: *const i32) -> &'static i32 { unsafe { &*x } } diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs index 8c2d2fafce07..d4d5a086dcc0 100644 --- a/tests/ui/repr/16-bit-repr-c-enum.rs +++ b/tests/ui/repr/16-bit-repr-c-enum.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ build-pass //@ revisions: avr msp430 // @@ -11,6 +12,9 @@ #![stable(feature = "intrinsics_for_test", since = "3.3.3")] #![allow(dead_code)] +extern crate minicore; +use minicore::*; + // Test that the repr(C) attribute doesn't break compilation // Previous bad assumption was that 32-bit enum default width is fine on msp430, avr // But the width of the C int on these platforms is 16 bits, and C enums <= C int range @@ -26,11 +30,6 @@ enum Foo { #[rustc_intrinsic] const fn size_of() -> usize; -#[lang="sized"] -trait Sized {} -#[lang="copy"] -trait Copy {} - const EXPECTED: usize = 2; const ACTUAL: usize = size_of::(); // Validate that the size is indeed 16 bits, to match this C static_assert: diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 204db30786ee..42fcaee2d4aa 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -81,7 +81,7 @@ error: layout_of(Univariant) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:39:1 + --> $DIR/repr-c-dead-variants.rs:43:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:46:1 + --> $DIR/repr-c-dead-variants.rs:50:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -327,7 +327,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:58:1 + --> $DIR/repr-c-dead-variants.rs:62:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 1fab00bf50c4..bb2c6e70dc7a 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -81,7 +81,7 @@ error: layout_of(Univariant) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:39:1 + --> $DIR/repr-c-dead-variants.rs:43:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:46:1 + --> $DIR/repr-c-dead-variants.rs:50:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -327,7 +327,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:58:1 + --> $DIR/repr-c-dead-variants.rs:62:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 204db30786ee..42fcaee2d4aa 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -81,7 +81,7 @@ error: layout_of(Univariant) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:39:1 + --> $DIR/repr-c-dead-variants.rs:43:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:46:1 + --> $DIR/repr-c-dead-variants.rs:50:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -327,7 +327,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:58:1 + --> $DIR/repr-c-dead-variants.rs:62:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.rs b/tests/ui/repr/repr-c-dead-variants.rs index 99f20982a996..7f2743085623 100644 --- a/tests/ui/repr/repr-c-dead-variants.rs +++ b/tests/ui/repr/repr-c-dead-variants.rs @@ -4,8 +4,12 @@ #![no_std] #![no_core] +extern crate minicore; +use minicore::*; + // See also: repr-c-int-dead-variants.rs +//@ add-core-stubs //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" @@ -59,6 +63,3 @@ enum DeadBranchHasOtherField { //~ ERROR layout_of Variant1(Void, Align8U64), Variant2(u8), } - -#[lang = "sized"] -trait Sized {} diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 204db30786ee..42fcaee2d4aa 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -81,7 +81,7 @@ error: layout_of(Univariant) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:39:1 + --> $DIR/repr-c-dead-variants.rs:43:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:46:1 + --> $DIR/repr-c-dead-variants.rs:50:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -327,7 +327,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:58:1 + --> $DIR/repr-c-dead-variants.rs:62:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr_align_greater_usize.msp430.stderr b/tests/ui/repr/repr_align_greater_usize.msp430.stderr index 7c85249c0099..db25cb1b5f2e 100644 --- a/tests/ui/repr/repr_align_greater_usize.msp430.stderr +++ b/tests/ui/repr/repr_align_greater_usize.msp430.stderr @@ -1,5 +1,5 @@ error[E0589]: alignment must not be greater than `isize::MAX` bytes - --> $DIR/repr_align_greater_usize.rs:21:8 + --> $DIR/repr_align_greater_usize.rs:22:8 | LL | #[repr(align(32768))] | ^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[repr(align(32768))] = note: `isize::MAX` is 32767 for the current target error[E0589]: alignment must not be greater than `isize::MAX` bytes - --> $DIR/repr_align_greater_usize.rs:24:8 + --> $DIR/repr_align_greater_usize.rs:25:8 | LL | #[repr(align(65536))] | ^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr_align_greater_usize.rs b/tests/ui/repr/repr_align_greater_usize.rs index b47320b6d9b6..7499e242d597 100644 --- a/tests/ui/repr/repr_align_greater_usize.rs +++ b/tests/ui/repr/repr_align_greater_usize.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: msp430 aarch32 //@[msp430] needs-llvm-components: msp430 //@[msp430] compile-flags: --target=msp430-none-elf @@ -12,8 +13,8 @@ #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; #[repr(align(16384))] struct Kitten; diff --git a/tests/ui/sanitizer/cfg-kasan.rs b/tests/ui/sanitizer/cfg-kasan.rs index 491eaf3acc17..ba0abf605707 100644 --- a/tests/ui/sanitizer/cfg-kasan.rs +++ b/tests/ui/sanitizer/cfg-kasan.rs @@ -1,6 +1,7 @@ // Verifies that when compiling with -Zsanitizer=kernel-address, // the `#[cfg(sanitize = "address")]` attribute is configured. +//@ add-core-stubs //@ check-pass //@ compile-flags: -Zsanitizer=kernel-address //@ revisions: aarch64 riscv64imac riscv64gc x86_64 @@ -17,8 +18,8 @@ #![feature(cfg_sanitize, no_core, lang_items)] #![no_core] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; const _: fn() -> () = main; diff --git a/tests/ui/sanitizer/cfg.rs b/tests/ui/sanitizer/cfg.rs index 7b8f285e41a8..a43813c04469 100644 --- a/tests/ui/sanitizer/cfg.rs +++ b/tests/ui/sanitizer/cfg.rs @@ -1,6 +1,7 @@ // Verifies that when compiling with -Zsanitizer=option, // the `#[cfg(sanitize = "option")]` attribute is configured. +//@ add-core-stubs //@ check-pass //@ revisions: address cfi kcfi leak memory thread //@compile-flags: -Ctarget-feature=-crt-static @@ -23,10 +24,8 @@ #![crate_type="lib"] #![no_core] -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } +extern crate minicore; +use minicore::*; #[cfg(all(sanitize = "address", address))] fn main() {} diff --git a/tests/ui/static/static_sized_requirement.rs b/tests/ui/static/static_sized_requirement.rs index 80f93dea0544..25e1359607c9 100644 --- a/tests/ui/static/static_sized_requirement.rs +++ b/tests/ui/static/static_sized_requirement.rs @@ -1,11 +1,12 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//@ add-core-stubs +//@ check-pass #![feature(no_core, lang_items)] #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; extern "C" { pub static A: u32; diff --git a/tests/ui/target-feature/no-llvm-leaks.rs b/tests/ui/target-feature/no-llvm-leaks.rs index d4f70fe70694..50544b97a96d 100644 --- a/tests/ui/target-feature/no-llvm-leaks.rs +++ b/tests/ui/target-feature/no-llvm-leaks.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: aarch64 x86-64 //@ [aarch64] compile-flags: -Ctarget-feature=+neon,+fp16,+fhm --target=aarch64-unknown-linux-gnu //@ [aarch64] needs-llvm-components: aarch64 @@ -9,12 +10,8 @@ #![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api)] #![stable(feature = "test", since = "1.0.0")] -// Supporting minimal rust core code -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for bool {} +extern crate minicore; +use minicore::*; #[stable(feature = "test", since = "1.0.0")] #[rustc_const_stable(feature = "test", since = "1.0.0")] diff --git a/tests/ui/target-feature/tied-features.rs b/tests/ui/target-feature/tied-features.rs index c6cdf21a3e3f..9aa5291e68cb 100644 --- a/tests/ui/target-feature/tied-features.rs +++ b/tests/ui/target-feature/tied-features.rs @@ -1,10 +1,11 @@ +//@ add-core-stubs //@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu //@ needs-llvm-components: aarch64 #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +extern crate minicore; +use minicore::*; pub fn main() { #[target_feature(enable = "pacg")] diff --git a/tests/ui/target-feature/tied-features.stderr b/tests/ui/target-feature/tied-features.stderr index 8d677735e846..49df4f109ba7 100644 --- a/tests/ui/target-feature/tied-features.stderr +++ b/tests/ui/target-feature/tied-features.stderr @@ -1,5 +1,5 @@ error: the target features paca, pacg must all be either enabled or disabled together - --> $DIR/tied-features.rs:10:5 + --> $DIR/tied-features.rs:11:5 | LL | #[target_feature(enable = "pacg")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[target_feature(enable = "pacg")] = help: add the missing features in a `target_feature` attribute error: the target features paca, pacg must all be either enabled or disabled together - --> $DIR/tied-features.rs:22:1 + --> $DIR/tied-features.rs:23:1 | LL | #[target_feature(enable = "paca")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | #[target_feature(enable = "paca")] = help: add the missing features in a `target_feature` attribute error: the target features paca, pacg must all be either enabled or disabled together - --> $DIR/tied-features.rs:35:1 + --> $DIR/tied-features.rs:36:1 | LL | #[target_feature(enable = "paca")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 7bf6fc16f24902d5efc5fc2c5ba6b72840a239b9 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 24 Feb 2025 09:49:06 +0000 Subject: [PATCH 254/991] tests: add variance test for const traits Added to demonstrate change in output in following commit. Many more interesting tests change with different output, missing errors, new errors, etc related to this but they all depend on feature flags and are much more complex than this. --- tests/ui/traits/const-traits/variance.rs | 14 ++++++++++++++ tests/ui/traits/const-traits/variance.stderr | 8 ++++++++ 2 files changed, 22 insertions(+) create mode 100644 tests/ui/traits/const-traits/variance.rs create mode 100644 tests/ui/traits/const-traits/variance.stderr diff --git a/tests/ui/traits/const-traits/variance.rs b/tests/ui/traits/const-traits/variance.rs new file mode 100644 index 000000000000..9eaf7910cb88 --- /dev/null +++ b/tests/ui/traits/const-traits/variance.rs @@ -0,0 +1,14 @@ +#![feature(rustc_attrs, const_trait_impl)] +#![allow(internal_features)] +#![rustc_variance_of_opaques] + +#[const_trait] +trait Foo {} + +impl const Foo for () {} + +fn foo<'a: 'a>() -> impl const Foo {} +//~^ ERROR ['a: o] + +fn main() {} + diff --git a/tests/ui/traits/const-traits/variance.stderr b/tests/ui/traits/const-traits/variance.stderr new file mode 100644 index 000000000000..f6efc24b747b --- /dev/null +++ b/tests/ui/traits/const-traits/variance.stderr @@ -0,0 +1,8 @@ +error: ['a: o] + --> $DIR/variance.rs:10:21 + | +LL | fn foo<'a: 'a>() -> impl const Foo {} + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From 0bed12e02d75f9d786a3496cb243355e603809ad Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 24 Feb 2025 09:50:22 +0000 Subject: [PATCH 255/991] hir_analysis: skip self type of host effect preds Like trait predicates, the self type ought to be skipped here. --- compiler/rustc_hir_analysis/src/variance/mod.rs | 4 ++++ tests/ui/traits/const-traits/variance.rs | 3 +-- tests/ui/traits/const-traits/variance.stderr | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index a7760326bb4c..0800d99e9452 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -198,6 +198,10 @@ fn variance_of_opaque( ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: _, args, .. }, polarity: _, + }) + | ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref: ty::TraitRef { def_id: _, args, .. }, + constness: _, }) => { for arg in &args[1..] { arg.visit_with(&mut collector); diff --git a/tests/ui/traits/const-traits/variance.rs b/tests/ui/traits/const-traits/variance.rs index 9eaf7910cb88..90b5c50161d5 100644 --- a/tests/ui/traits/const-traits/variance.rs +++ b/tests/ui/traits/const-traits/variance.rs @@ -8,7 +8,6 @@ trait Foo {} impl const Foo for () {} fn foo<'a: 'a>() -> impl const Foo {} -//~^ ERROR ['a: o] +//~^ ERROR ['a: *] fn main() {} - diff --git a/tests/ui/traits/const-traits/variance.stderr b/tests/ui/traits/const-traits/variance.stderr index f6efc24b747b..f55069311848 100644 --- a/tests/ui/traits/const-traits/variance.stderr +++ b/tests/ui/traits/const-traits/variance.stderr @@ -1,4 +1,4 @@ -error: ['a: o] +error: ['a: *] --> $DIR/variance.rs:10:21 | LL | fn foo<'a: 'a>() -> impl const Foo {} From 6b2f5cf43ffd9a71883bd2ddd82e65ad7ef4bf86 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 24 Feb 2025 11:52:33 +0100 Subject: [PATCH 256/991] Update browser-ui-test version to `0.20.3` --- .../docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index a158e5b6253c..3428dd4826a7 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.20.2 \ No newline at end of file +0.20.3 \ No newline at end of file From e2a773123f4af391f22e2a109ff3e4a4ae89408b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 24 Feb 2025 14:11:12 +0200 Subject: [PATCH 257/991] Downgrade to ubuntu-22.04 for aarch64-unknown-linux-gnu and arm-unknown-linux-gnueabihf builds --- src/tools/rust-analyzer/.github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml index fe090267dc9b..5159ffc8fee8 100644 --- a/src/tools/rust-analyzer/.github/workflows/release.yaml +++ b/src/tools/rust-analyzer/.github/workflows/release.yaml @@ -38,10 +38,10 @@ jobs: target: x86_64-unknown-linux-gnu code-target: linux-x64 container: rockylinux:8 - - os: ubuntu-latest + - os: ubuntu-22.04 target: aarch64-unknown-linux-gnu code-target: linux-arm64 - - os: ubuntu-latest + - os: ubuntu-22.04 target: arm-unknown-linux-gnueabihf code-target: linux-armhf - os: macos-13 From 561dce772fed55a73f474b2e3f79c43981ea084f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Feb 2025 10:57:57 +0100 Subject: [PATCH 258/991] sanity-check for HOST_TARGET --- src/tools/miri/ci/ci.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 5583030b490a..3327ad17c44e 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -euo pipefail +set -eu function begingroup { echo "::group::$@" @@ -11,6 +11,17 @@ function endgroup { echo "::endgroup" } +begingroup "Sanity-check environment" + +# Ensure the HOST_TARGET is what it should be. +if ! rustc -vV | grep -q "^host: $HOST_TARGET\$"; then + echo "This runner should be using host target $HOST_TARGET but rustc disagrees:" + rustc -vV + exit 1 +fi + +endgroup + begingroup "Building Miri" # Global configuration From 5397431162022f6b360a71b0df9f5dcf9347b975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 24 Feb 2025 14:25:55 +0200 Subject: [PATCH 259/991] Fix event_name check in workflows --- src/tools/rust-analyzer/.github/workflows/autopublish.yaml | 2 +- src/tools/rust-analyzer/.github/workflows/fuzz.yml | 2 +- src/tools/rust-analyzer/.github/workflows/publish-libs.yaml | 2 +- src/tools/rust-analyzer/.github/workflows/release.yaml | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml index e4fa94643ba1..d3f0499e4342 100644 --- a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml +++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml @@ -11,7 +11,7 @@ on: jobs: publish: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: publish runs-on: ubuntu-latest steps: diff --git a/src/tools/rust-analyzer/.github/workflows/fuzz.yml b/src/tools/rust-analyzer/.github/workflows/fuzz.yml index f88c7f95d5c9..7acfcbe351fe 100644 --- a/src/tools/rust-analyzer/.github/workflows/fuzz.yml +++ b/src/tools/rust-analyzer/.github/workflows/fuzz.yml @@ -19,7 +19,7 @@ env: jobs: rust: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: Rust runs-on: ubuntu-latest env: diff --git a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml index 5023a634fde4..93ae5675a71a 100644 --- a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml +++ b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml @@ -9,7 +9,7 @@ on: jobs: publish-libs: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: publish runs-on: ubuntu-latest steps: diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml index fe090267dc9b..0625fbf42bbb 100644 --- a/src/tools/rust-analyzer/.github/workflows/release.yaml +++ b/src/tools/rust-analyzer/.github/workflows/release.yaml @@ -22,7 +22,7 @@ env: jobs: dist: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} strategy: matrix: include: @@ -139,7 +139,7 @@ jobs: path: ./dist dist-x86_64-unknown-linux-musl: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: dist (x86_64-unknown-linux-musl) runs-on: ubuntu-latest env: @@ -185,7 +185,7 @@ jobs: path: ./dist publish: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: publish runs-on: ubuntu-latest needs: ["dist", "dist-x86_64-unknown-linux-musl"] From 61a25fd270b9a0e172fdc3e390c0cdad1e5c2dbb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Feb 2025 13:27:18 +0100 Subject: [PATCH 260/991] make sure we install the toolchain for the intended host target --- src/tools/miri/.github/workflows/ci.yml | 2 ++ src/tools/miri/.github/workflows/setup/action.yml | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 81df0964d591..59bae513a58f 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -30,6 +30,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: ./.github/workflows/setup + with: + toolchain_flags: "--host ${{ matrix.host_target }}" # The `style` job only runs on Linux; this makes sure the Windows-host-specific # code is also covered by clippy. diff --git a/src/tools/miri/.github/workflows/setup/action.yml b/src/tools/miri/.github/workflows/setup/action.yml index bf5749a7b17e..146b432171e1 100644 --- a/src/tools/miri/.github/workflows/setup/action.yml +++ b/src/tools/miri/.github/workflows/setup/action.yml @@ -1,5 +1,9 @@ name: "Miri CI setup" description: "Sets up Miri CI" +inputs: + toolchain_flags: + required: false + default: '' runs: using: "composite" steps: @@ -45,7 +49,7 @@ runs: echo "Building against latest rustc git version" git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1 > rust-version fi - ./miri toolchain + ./miri toolchain ${{ inputs.toolchain_flags }} shell: bash - name: Show Rust version (miri toolchain) From b4bb011cbcf73bdecc499562346cb8a0f33b44bb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Feb 2025 13:43:52 +0100 Subject: [PATCH 261/991] add missing float non-determinism tests and skip some on i686-pc-windows-msvc that are internally implemented via f64 --- src/tools/miri/tests/pass/float.rs | 36 +++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 0eb7d6e83095..d8792a6c3026 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -1327,15 +1327,24 @@ fn test_non_determinism() { ensure_nondet(|| 3.0f32.hypot(4.0f32)); ensure_nondet(|| 1f32.sin()); ensure_nondet(|| 0f32.cos()); - ensure_nondet(|| 1.0f32.sinh()); + // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version, + // which means the little rounding errors Miri introduces are discard by the cast down to `f32`. + // Just skip the test for them. + if !cfg!(all(target_os = "windows", target_env = "msvc", target_arch = "x86")) { + ensure_nondet(|| 1.0f32.tan()); + ensure_nondet(|| 1.0f32.asin()); + ensure_nondet(|| 5.0f32.acos()); + ensure_nondet(|| 1.0f32.atan()); + ensure_nondet(|| 1.0f32.atan2(2.0f32)); + ensure_nondet(|| 1.0f32.sinh()); + ensure_nondet(|| 1.0f32.cosh()); + ensure_nondet(|| 1.0f32.tanh()); + } ensure_nondet(|| 1.0f32.asinh()); - ensure_nondet(|| 1.0f32.cosh()); ensure_nondet(|| 2.0f32.acosh()); - ensure_nondet(|| 1.0f32.tan()); - ensure_nondet(|| 1.0f32.tanh()); - ensure_nondet(|| 1.0f32.atan2(2.0f32)); ensure_nondet(|| 0.5f32.atanh()); ensure_nondet(|| 5.0f32.gamma()); + ensure_nondet(|| 5.0f32.ln_gamma()); ensure_nondet(|| 5.0f32.erf()); ensure_nondet(|| 5.0f32.erfc()); } @@ -1348,18 +1357,23 @@ fn test_non_determinism() { ensure_nondet(|| 1f64.ln_1p()); ensure_nondet(|| f64::consts::E.log10()); ensure_nondet(|| f64::consts::E.log2()); - ensure_nondet(|| 1f64.sin()); - ensure_nondet(|| 0f64.cos()); ensure_nondet(|| 27.0f64.cbrt()); ensure_nondet(|| 3.0f64.hypot(4.0f64)); - ensure_nondet(|| 1.0f64.sinh()); - ensure_nondet(|| 1.0f64.asinh()); - ensure_nondet(|| 1.0f64.cosh()); - ensure_nondet(|| 3.0f64.acosh()); + ensure_nondet(|| 1f64.sin()); + ensure_nondet(|| 0f64.cos()); ensure_nondet(|| 1.0f64.tan()); + ensure_nondet(|| 1.0f64.asin()); + ensure_nondet(|| 5.0f64.acos()); + ensure_nondet(|| 1.0f64.atan()); + ensure_nondet(|| 1.0f64.atan2(2.0f64)); + ensure_nondet(|| 1.0f64.sinh()); + ensure_nondet(|| 1.0f64.cosh()); ensure_nondet(|| 1.0f64.tanh()); + ensure_nondet(|| 1.0f64.asinh()); + ensure_nondet(|| 3.0f64.acosh()); ensure_nondet(|| 0.5f64.atanh()); ensure_nondet(|| 5.0f64.gamma()); + ensure_nondet(|| 5.0f64.ln_gamma()); ensure_nondet(|| 5.0f64.erf()); ensure_nondet(|| 5.0f64.erfc()); } From 4303a14bdd8388e5934c0d823c54b8f935b2e1b3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Feb 2025 13:50:42 +0100 Subject: [PATCH 262/991] slightly extend comment --- src/tools/miri/src/shims/aarch64.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/src/shims/aarch64.rs b/src/tools/miri/src/shims/aarch64.rs index fc6e3b303d1c..7cccc9e51d8e 100644 --- a/src/tools/miri/src/shims/aarch64.rs +++ b/src/tools/miri/src/shims/aarch64.rs @@ -33,7 +33,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement the vpmaxq_u8 function. - // Folding maximum of adjacent pairs. + // Computes the maximum of adjacent pairs; the first half of the output is produced from the + // `left` input, the second half of the output from the `right` input. // https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_u8 "neon.umaxp.v16i8" => { let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; From 7bba76eccc8be554daad85459408aa0ef737fc0a Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 24 Feb 2025 13:52:46 +0100 Subject: [PATCH 263/991] Disable incremental on release builds --- src/tools/rust-analyzer/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 5060013b1398..d363bb59be70 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -25,7 +25,6 @@ salsa.opt-level = 3 miniz_oxide.opt-level = 3 [profile.release] -incremental = true # Set this to 1 or 2 to get more useful backtraces in debugger. debug = 0 From d761f9b682c7b38412723aa90a1a571151cdd353 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 24 Feb 2025 14:00:16 +0100 Subject: [PATCH 264/991] Vendor always-assert --- src/tools/rust-analyzer/Cargo.lock | 5 +- .../crates/rust-analyzer/Cargo.toml | 2 +- .../rust-analyzer/crates/stdx/Cargo.toml | 3 +- .../rust-analyzer/crates/stdx/src/assert.rs | 115 ++++++++++++++++++ .../rust-analyzer/crates/stdx/src/lib.rs | 5 +- 5 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/stdx/src/assert.rs diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index fc3680ce274e..b4e97261d723 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -22,9 +22,6 @@ name = "always-assert" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1078fa1ce1e34b1872d8611ad921196d76bdd7027e949fbe31231abde201892" -dependencies = [ - "tracing", -] [[package]] name = "anyhow" @@ -1922,13 +1919,13 @@ dependencies = [ name = "stdx" version = "0.0.0" dependencies = [ - "always-assert", "backtrace", "crossbeam-channel", "itertools", "jod-thread", "libc", "miow", + "tracing", "windows-sys 0.59.0", ] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index b8ce2b7430b9..64c8afdc1f74 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -94,7 +94,7 @@ syntax-bridge.workspace = true [features] jemalloc = ["jemallocator", "profile/jemalloc"] -force-always-assert = ["always-assert/force"] +force-always-assert = ["stdx/force-always-assert"] sysroot-abi = [] in-rust-tree = [ "sysroot-abi", diff --git a/src/tools/rust-analyzer/crates/stdx/Cargo.toml b/src/tools/rust-analyzer/crates/stdx/Cargo.toml index 1ebb48c577a6..62c32d68e6fb 100644 --- a/src/tools/rust-analyzer/crates/stdx/Cargo.toml +++ b/src/tools/rust-analyzer/crates/stdx/Cargo.toml @@ -14,11 +14,11 @@ doctest = false [dependencies] backtrace = { version = "0.3.67", optional = true } -always-assert = { version = "0.2.0", features = ["tracing"] } jod-thread = "0.1.2" libc.workspace = true crossbeam-channel.workspace = true itertools.workspace = true +tracing.workspace = true # Think twice before adding anything here [target.'cfg(windows)'.dependencies] @@ -28,6 +28,7 @@ windows-sys = { version = "0.59", features = ["Win32_Foundation"] } [features] # Uncomment to enable for the whole crate graph # default = [ "backtrace" ] +force-always-assert = [] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/stdx/src/assert.rs b/src/tools/rust-analyzer/crates/stdx/src/assert.rs new file mode 100644 index 000000000000..91c279798c26 --- /dev/null +++ b/src/tools/rust-analyzer/crates/stdx/src/assert.rs @@ -0,0 +1,115 @@ +// Vendored from https://github.com/matklad/always-assert/commit/4cf564eea6fcf18b30c3c3483a611004dc03afbb +//! Recoverable assertions, inspired by [the use of `assert()` in +//! SQLite](https://www.sqlite.org/assert.html). +//! +//! `never!` and `always!` return the actual value of the condition if +//! `debug_assertions` are disabled. +//! +//! Use them when terminating on assertion failure is worse than continuing. +//! +//! One example would be a critical application like a database: +//! +//! ```ignore +//! use stdx::never; +//! +//! fn apply_transaction(&mut self, tx: Transaction) -> Result<(), TransactionAborted> { +//! let delta = self.compute_delta(&tx); +//! +//! if never!(!self.check_internal_invariant(&delta)) { +//! // Ok, something in this transaction messed up our internal state. +//! // This really shouldn't be happening, and this signifies a bug. +//! // Luckily, we can recover by just rejecting the transaction. +//! return abort_transaction(tx); +//! } +//! self.commit(delta); +//! Ok(()) +//! } +//! ``` +//! +//! Another example is assertions about non-critical functionality in usual apps +//! +//! ```ignore +//! use stdx::never; +//! +//! let english_message = "super app installed!" +//! let mut local_message = localize(english_message); +//! if never!(local_message.is_empty(), "missing localization for {}", english_message) { +//! // We localized all the messages but this one slipper through the cracks? +//! // Better to show the english one then than to fail outright; +//! local_message = english_message; +//! } +//! println!("{}", local_message); +//! ``` + +/// Asserts that the condition is always true and returns its actual value. +/// +/// If the condition is true does nothing and and evaluates to true. +/// +/// If the condition is false: +/// * panics if `force` feature or `debug_assertions` are enabled, +/// * logs an error if the `tracing` feature is enabled, +/// * evaluates to false. +/// +/// Accepts `format!` style arguments. +#[macro_export] +macro_rules! always { + ($cond:expr) => { + $crate::always!($cond, "assertion failed: {}", stringify!($cond)) + }; + + ($cond:expr, $fmt:literal $($arg:tt)*) => {{ + let cond = $cond; + if cfg!(debug_assertions) || $crate::assert::__FORCE { + assert!(cond, $fmt $($arg)*); + } + if !cond { + $crate::assert::__tracing_error!($fmt $($arg)*); + } + cond + }}; +} + +/// Asserts that the condition is never true and returns its actual value. +/// +/// If the condition is false does nothing and and evaluates to false. +/// +/// If the condition is true: +/// * panics if `force` feature or `debug_assertions` are enabled, +/// * logs an error if the `tracing` feature is enabled, +/// * evaluates to true. +/// +/// Accepts `format!` style arguments. +/// +/// Empty condition is equivalent to false: +/// +/// ```ignore +/// never!("oups") ~= unreachable!("oups") +/// ``` +#[macro_export] +macro_rules! never { + (true $($tt:tt)*) => { $crate::never!((true) $($tt)*) }; + (false $($tt:tt)*) => { $crate::never!((false) $($tt)*) }; + () => { $crate::never!("assertion failed: entered unreachable code") }; + ($fmt:literal $(, $($arg:tt)*)?) => {{ + if cfg!(debug_assertions) || $crate::assert::__FORCE { + unreachable!($fmt $(, $($arg)*)?); + } + $crate::assert::__tracing_error!($fmt $(, $($arg)*)?); + }}; + + ($cond:expr) => {{ + let cond = !$crate::always!(!$cond); + cond + }}; + + ($cond:expr, $fmt:literal $($arg:tt)*) => {{ + let cond = !$crate::always!(!$cond, $fmt $($arg)*); + cond + }}; +} + +#[doc(hidden)] +pub use tracing::error as __tracing_error; + +#[doc(hidden)] +pub const __FORCE: bool = cfg!(feature = "force-always-assert"); diff --git a/src/tools/rust-analyzer/crates/stdx/src/lib.rs b/src/tools/rust-analyzer/crates/stdx/src/lib.rs index 04c2153abf41..8313e1871f13 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/lib.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/lib.rs @@ -4,8 +4,10 @@ use std::io as sio; use std::process::Command; use std::{cmp::Ordering, ops, time::Instant}; -pub mod anymap; mod macros; + +pub mod anymap; +pub mod assert; pub mod non_empty_vec; pub mod panic_context; pub mod process; @@ -13,7 +15,6 @@ pub mod rand; pub mod thin_vec; pub mod thread; -pub use always_assert::{always, never}; pub use itertools; #[inline(always)] From 592028a2fc5f2f9af5aa7d802111b81393736ea0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 24 Feb 2025 14:27:33 +0100 Subject: [PATCH 265/991] Add rustdoc-gui regression test for #137082 --- tests/rustdoc-gui/code-example-buttons.goml | 2 ++ tests/rustdoc-gui/copy-path.goml | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/rustdoc-gui/code-example-buttons.goml b/tests/rustdoc-gui/code-example-buttons.goml index c62683b45da9..b96f6ddcc37a 100644 --- a/tests/rustdoc-gui/code-example-buttons.goml +++ b/tests/rustdoc-gui/code-example-buttons.goml @@ -26,6 +26,8 @@ click: ".example-wrap .copy-button" move-cursor-to: ".search-input" assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0) assert-css: (".example-wrap .copy-button", { "visibility": "hidden" }) +// Since we clicked on the copy button, the clipboard content should have been updated. +assert-clipboard: 'println!("nothing fancy");\nprintln!("but with two lines!");' define-function: ( "check-buttons", diff --git a/tests/rustdoc-gui/copy-path.goml b/tests/rustdoc-gui/copy-path.goml index dc05b96f7aed..e8766688f8d5 100644 --- a/tests/rustdoc-gui/copy-path.goml +++ b/tests/rustdoc-gui/copy-path.goml @@ -1,12 +1,17 @@ // Checks that the "copy path" button is not triggering JS error and its display -// isn't broken. -go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" +// isn't broken and the copied path is as expected. +go-to: "file://" + |DOC_PATH| + "/test_docs/foreign_impl_order/trait.Foo.html" + +// We ensure that the clipboard is empty. +assert-clipboard: "" // First we store the size of the button before we click on it. store-size: ("#copy-path", {"width": width, "height": height}) click: "#copy-path" // We wait for the new text to appear. wait-for: "#copy-path.clicked" +// We check that the clipboard value is the expected one. +assert-clipboard: "test_docs::foreign_impl_order::Foo" // We check that the size didn't change. assert-size: ("#copy-path.clicked", {"width": |width|, "height": |height|}) // We wait for the button to turn back to its original state. From 443b0f5ccf3181f18afa6102008ab4536ef0e5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 9 Feb 2025 22:49:57 +0100 Subject: [PATCH 266/991] Fix rustdoc and clippy --- clippy_lints/src/attrs/inline_always.rs | 2 +- clippy_lints/src/attrs/repr_attributes.rs | 42 ++++++------- .../src/attrs/unnecessary_clippy_cfg.rs | 2 +- clippy_lints/src/attrs/utils.rs | 2 +- .../src/default_union_representation.rs | 17 ++---- clippy_lints/src/disallowed_macros.rs | 1 + .../src/doc/include_in_doc_without_cfg.rs | 9 ++- clippy_lints/src/doc/mod.rs | 12 +++- .../src/doc/suspicious_doc_comments.rs | 10 ++-- .../src/doc/too_long_first_doc_paragraph.rs | 9 +-- clippy_lints/src/four_forward_slashes.rs | 3 +- clippy_lints/src/functions/must_use.rs | 7 ++- .../src/inconsistent_struct_constructor.rs | 2 +- clippy_lints/src/inline_fn_without_body.rs | 4 +- clippy_lints/src/large_include_file.rs | 59 +++++++++++-------- clippy_lints/src/lib.rs | 4 +- clippy_lints/src/macro_use.rs | 6 +- clippy_lints/src/manual_non_exhaustive.rs | 2 +- clippy_lints/src/no_mangle_with_rust_abi.rs | 2 +- .../src/undocumented_unsafe_blocks.rs | 2 +- clippy_utils/src/lib.rs | 3 +- .../large_include_file.stderr | 20 +++---- tests/ui/must_use_unit.fixed | 4 +- tests/ui/must_use_unit.stderr | 6 +- 24 files changed, 118 insertions(+), 112 deletions(-) diff --git a/clippy_lints/src/attrs/inline_always.rs b/clippy_lints/src/attrs/inline_always.rs index 2325f914b0b0..cb63fadb4e21 100644 --- a/clippy_lints/src/attrs/inline_always.rs +++ b/clippy_lints/src/attrs/inline_always.rs @@ -20,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Att span_lint( cx, INLINE_ALWAYS, - attr.span, + attr.span(), format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"), ); } diff --git a/clippy_lints/src/attrs/repr_attributes.rs b/clippy_lints/src/attrs/repr_attributes.rs index 6d1ab46aa0c1..6cc47596bbb6 100644 --- a/clippy_lints/src/attrs/repr_attributes.rs +++ b/clippy_lints/src/attrs/repr_attributes.rs @@ -1,6 +1,7 @@ +use rustc_attr_parsing::{find_attr, AttributeKind, ReprAttr}; use rustc_hir::Attribute; use rustc_lint::LateContext; -use rustc_span::{Span, sym}; +use rustc_span::Span; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs; @@ -14,30 +15,21 @@ pub(super) fn check(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute], } fn check_packed(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute]) { - if let Some(items) = attrs.iter().find_map(|attr| { - if attr.ident().is_some_and(|ident| matches!(ident.name, sym::repr)) { - attr.meta_item_list() - } else { - None + if let Some(reprs) = find_attr!(attrs, AttributeKind::Repr(r) => r) { + let packed_span = reprs.iter().find(|(r, _)| matches!(r, ReprAttr::ReprPacked(..))).map(|(_, s)| *s); + + if let Some(packed_span) = packed_span && !reprs.iter().any(|(x, _)| *x == ReprAttr::ReprC || *x == ReprAttr::ReprRust) { + span_lint_and_then( + cx, + REPR_PACKED_WITHOUT_ABI, + item_span, + "item uses `packed` representation without ABI-qualification", + |diag| { + diag.warn("unqualified `#[repr(packed)]` defaults to `#[repr(Rust, packed)]`, which has no stable ABI") + .help("qualify the desired ABI explicity via `#[repr(C, packed)]` or `#[repr(Rust, packed)]`") + .span_label(packed_span, "`packed` representation set here"); + }, + ); } - }) && let Some(packed) = items - .iter() - .find(|item| item.ident().is_some_and(|ident| matches!(ident.name, sym::packed))) - && !items.iter().any(|item| { - item.ident() - .is_some_and(|ident| matches!(ident.name, sym::C | sym::Rust)) - }) - { - span_lint_and_then( - cx, - REPR_PACKED_WITHOUT_ABI, - item_span, - "item uses `packed` representation without ABI-qualification", - |diag| { - diag.warn("unqualified `#[repr(packed)]` defaults to `#[repr(Rust, packed)]`, which has no stable ABI") - .help("qualify the desired ABI explicity via `#[repr(C, packed)]` or `#[repr(Rust, packed)]`") - .span_label(packed.span(), "`packed` representation set here"); - }, - ); } } diff --git a/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs b/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs index 478ba7a187be..6ee3290fa761 100644 --- a/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs +++ b/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs @@ -15,7 +15,7 @@ pub(super) fn check( ) { if cfg_attr.has_name(sym::clippy) && let Some(ident) = behind_cfg_attr.ident() - && Level::from_symbol(ident.name, Some(attr.id)).is_some() + && Level::from_symbol(ident.name, || Some(attr.id)).is_some() && let Some(items) = behind_cfg_attr.meta_item_list() { let nb_items = items.len(); diff --git a/clippy_lints/src/attrs/utils.rs b/clippy_lints/src/attrs/utils.rs index a667649f7343..0e650e493925 100644 --- a/clippy_lints/src/attrs/utils.rs +++ b/clippy_lints/src/attrs/utils.rs @@ -17,7 +17,7 @@ pub(super) fn is_word(nmi: &MetaItemInner, expected: Symbol) -> bool { } pub(super) fn is_lint_level(symbol: Symbol, attr_id: AttrId) -> bool { - Level::from_symbol(symbol, Some(attr_id)).is_some() + Level::from_symbol(symbol, || Some(attr_id)).is_some() } pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool { diff --git a/clippy_lints/src/default_union_representation.rs b/clippy_lints/src/default_union_representation.rs index 9f020d3081c4..6e6d81db11c0 100644 --- a/clippy_lints/src/default_union_representation.rs +++ b/clippy_lints/src/default_union_representation.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_then; +use rustc_attr_parsing::{find_attr, AttributeKind, ReprAttr}; use rustc_hir::{HirId, Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, FieldDef}; use rustc_session::declare_lint_pass; -use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -97,16 +97,7 @@ fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: ty::GenericArgsR } fn has_c_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - cx.tcx.hir().attrs(hir_id).iter().any(|attr| { - if attr.has_name(sym::repr) { - if let Some(items) = attr.meta_item_list() { - for item in items { - if item.is_word() && matches!(item.name_or_empty(), sym::C) { - return true; - } - } - } - } - false - }) + let attrs = cx.tcx.hir().attrs(hir_id); + + find_attr!(attrs, AttributeKind::Repr(r) if r.iter().any(|(x, _)| *x == ReprAttr::ReprC)) } diff --git a/clippy_lints/src/disallowed_macros.rs b/clippy_lints/src/disallowed_macros.rs index 4e8853821c3e..6de16e306c9a 100644 --- a/clippy_lints/src/disallowed_macros.rs +++ b/clippy_lints/src/disallowed_macros.rs @@ -1,3 +1,4 @@ + use clippy_config::Conf; use clippy_config::types::create_disallowed_map; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; diff --git a/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/clippy_lints/src/doc/include_in_doc_without_cfg.rs index 4b40fc0b1ee2..aa29705cf938 100644 --- a/clippy_lints/src/doc/include_in_doc_without_cfg.rs +++ b/clippy_lints/src/doc/include_in_doc_without_cfg.rs @@ -1,18 +1,17 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; -use rustc_ast::AttrStyle; use rustc_errors::Applicability; -use rustc_hir::{AttrArgs, AttrKind, Attribute}; -use rustc_lint::LateContext; +use rustc_lint::EarlyContext; +use rustc_ast::{Attribute, AttrKind, AttrArgs, AttrStyle}; use super::DOC_INCLUDE_WITHOUT_CFG; -pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { +pub fn check(cx: &EarlyContext<'_>, attrs: &[Attribute]) { for attr in attrs { if !attr.span.from_expansion() && let AttrKind::Normal(ref item) = attr.kind && attr.doc_str().is_some() - && let AttrArgs::Eq { expr: meta, .. } = &item.args + && let AttrArgs::Eq { expr: meta, .. } = &item.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 713d62a8801d..42192801af7c 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -20,7 +20,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind}; -use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc_middle::hir::nested_filter; use rustc_middle::ty; use rustc_resolve::rustdoc::{ @@ -577,6 +577,13 @@ impl_lint_pass!(Documentation => [ DOC_INCLUDE_WITHOUT_CFG, ]); + +impl EarlyLintPass for Documentation { + fn check_attributes(&mut self, cx: &EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) { + include_in_doc_without_cfg::check(cx, attrs); + } +} + impl<'tcx> LateLintPass<'tcx> for Documentation { fn check_attributes(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { @@ -704,14 +711,13 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ Some(("fake".into(), "fake".into())) } - include_in_doc_without_cfg::check(cx, attrs); if suspicious_doc_comments::check(cx, attrs) || is_doc_hidden(attrs) { return None; } let (fragments, _) = attrs_to_doc_fragments( attrs.iter().filter_map(|attr| { - if attr.span.in_external_macro(cx.sess().source_map()) { + if !attr.doc_str_and_comment_kind().is_some() || attr.span().in_external_macro(cx.sess().source_map()) { None } else { Some((attr, None)) diff --git a/clippy_lints/src/doc/suspicious_doc_comments.rs b/clippy_lints/src/doc/suspicious_doc_comments.rs index 84393213e6f0..bfc36deea7b2 100644 --- a/clippy_lints/src/doc/suspicious_doc_comments.rs +++ b/clippy_lints/src/doc/suspicious_doc_comments.rs @@ -3,6 +3,7 @@ use rustc_ast::AttrStyle; use rustc_ast::token::CommentKind; use rustc_errors::Applicability; use rustc_hir::Attribute; +use rustc_attr_parsing::AttributeKind; use rustc_lint::LateContext; use rustc_span::Span; @@ -36,15 +37,14 @@ fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { attrs .iter() .filter_map(|attr| { - if let Some((sym, com_kind)) = attr.doc_str_and_comment_kind() - && let AttrStyle::Outer = attr.style - && let Some(com) = sym.as_str().strip_prefix('!') + if let Attribute::Parsed(AttributeKind::DocComment{ style: AttrStyle::Outer, kind, comment, ..}) = attr + && let Some(com) = comment.as_str().strip_prefix('!') { - let sugg = match com_kind { + let sugg = match kind { CommentKind::Line => format!("//!{com}"), CommentKind::Block => format!("/*!{com}*/"), }; - Some((attr.span, sugg)) + Some((attr.span(), sugg)) } else { None } diff --git a/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/clippy_lints/src/doc/too_long_first_doc_paragraph.rs index 1f89cab91480..1eda73a96727 100644 --- a/clippy_lints/src/doc/too_long_first_doc_paragraph.rs +++ b/clippy_lints/src/doc/too_long_first_doc_paragraph.rs @@ -1,5 +1,6 @@ use rustc_errors::Applicability; use rustc_hir::{Attribute, Item, ItemKind}; +use rustc_attr_parsing::AttributeKind; use rustc_lint::LateContext; use clippy_utils::diagnostics::span_lint_and_then; @@ -43,9 +44,9 @@ pub(super) fn check( let mut should_suggest_empty_doc = false; for attr in attrs { - if let Some(doc) = attr.doc_str() { - spans.push(attr.span); - let doc = doc.as_str(); + if let Attribute::Parsed(AttributeKind::DocComment {span, comment, ..}) = attr { + spans.push(span); + let doc = comment.as_str(); let doc = doc.trim(); if spans.len() == 1 { // We make this suggestion only if the first doc line ends with a punctuation @@ -78,7 +79,7 @@ pub(super) fn check( && let new_span = first_span.with_hi(second_span.lo()).with_lo(first_span.hi()) && let Some(snippet) = snippet_opt(cx, new_span) { - let Some(first) = snippet_opt(cx, first_span) else { + let Some(first) = snippet_opt(cx, *first_span) else { return; }; let Some(comment_form) = first.get(..3) else { diff --git a/clippy_lints/src/four_forward_slashes.rs b/clippy_lints/src/four_forward_slashes.rs index 0599e08e6c0a..0bdb99d7b9a4 100644 --- a/clippy_lints/src/four_forward_slashes.rs +++ b/clippy_lints/src/four_forward_slashes.rs @@ -46,7 +46,8 @@ impl<'tcx> LateLintPass<'tcx> for FourForwardSlashes { .hir() .attrs(item.hir_id()) .iter() - .fold(item.span.shrink_to_lo(), |span, attr| span.to(attr.span)); + .filter(|i| i.is_doc_comment()) + .fold(item.span.shrink_to_lo(), |span, attr| span.to(attr.span())); let (Some(file), _, _, end_line, _) = sm.span_to_location_info(span) else { return; }; diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index e6e3ea59a9f6..dbc08fca3624 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -95,6 +95,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr } } +// FIXME: needs to be an EARLY LINT. all attribute lints should be #[allow(clippy::too_many_arguments)] fn check_needless_must_use( cx: &LateContext<'_>, @@ -117,7 +118,7 @@ fn check_needless_must_use( fn_header_span, "this unit-returning function has a `#[must_use]` attribute", |diag| { - diag.span_suggestion(attr.span, "remove the attribute", "", Applicability::MachineApplicable); + diag.span_suggestion(attr.span(), "remove the attribute", "", Applicability::MachineApplicable); }, ); } else { @@ -130,7 +131,7 @@ fn check_needless_must_use( "this unit-returning function has a `#[must_use]` attribute", |diag| { let mut attrs_without_must_use = attrs.to_vec(); - attrs_without_must_use.retain(|a| a.id != attr.id); + attrs_without_must_use.retain(|a| a.id() != attr.id()); let sugg_str = attrs_without_must_use .iter() .map(|a| { @@ -143,7 +144,7 @@ fn check_needless_must_use( .join(", "); diag.span_suggestion( - attrs[0].span.with_hi(attrs[attrs.len() - 1].span.hi()), + attrs[0].span().with_hi(attrs[attrs.len() - 1].span().hi()), "change these attributes to", sugg_str, Applicability::MachineApplicable, diff --git a/clippy_lints/src/inconsistent_struct_constructor.rs b/clippy_lints/src/inconsistent_struct_constructor.rs index 39ff3c13bcce..5b58113169b1 100644 --- a/clippy_lints/src/inconsistent_struct_constructor.rs +++ b/clippy_lints/src/inconsistent_struct_constructor.rs @@ -183,7 +183,7 @@ fn suggestion<'tcx>( fn field_with_attrs_span(tcx: TyCtxt<'_>, field: &hir::ExprField<'_>) -> Span { if let Some(attr) = tcx.hir().attrs(field.hir_id).first() { - field.span.with_lo(attr.span.lo()) + field.span.with_lo(attr.span().lo()) } else { field.span } diff --git a/clippy_lints/src/inline_fn_without_body.rs b/clippy_lints/src/inline_fn_without_body.rs index 1b900f6be8e8..9b4a3b3f9c84 100644 --- a/clippy_lints/src/inline_fn_without_body.rs +++ b/clippy_lints/src/inline_fn_without_body.rs @@ -42,10 +42,10 @@ impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody { span_lint_and_then( cx, INLINE_FN_WITHOUT_BODY, - attr.span, + attr.span(), format!("use of `#[inline]` on trait method `{}` which has no body", item.ident), |diag| { - diag.suggest_remove_item(cx, attr.span, "remove", Applicability::MachineApplicable); + diag.suggest_remove_item(cx, attr.span(), "remove", Applicability::MachineApplicable); }, ); } diff --git a/clippy_lints/src/large_include_file.rs b/clippy_lints/src/large_include_file.rs index f3d62b513e84..53dc070833b5 100644 --- a/clippy_lints/src/large_include_file.rs +++ b/clippy_lints/src/large_include_file.rs @@ -3,10 +3,11 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::snippet_opt; use rustc_ast::LitKind; -use rustc_hir::{AttrArgs, AttrKind, Attribute, Expr, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_hir::{Expr, ExprKind}; +use rustc_ast::{Attribute, AttrArgs, AttrKind}; +use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::{Span, sym}; +use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -52,24 +53,6 @@ impl LargeIncludeFile { impl_lint_pass!(LargeIncludeFile => [LARGE_INCLUDE_FILE]); -impl LargeIncludeFile { - fn emit_lint(&self, cx: &LateContext<'_>, span: Span) { - #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] - span_lint_and_then( - cx, - LARGE_INCLUDE_FILE, - span, - "attempted to include a large file", - |diag| { - diag.note(format!( - "the configuration allows a maximum size of {} bytes", - self.max_file_size - )); - }, - ); - } -} - impl LateLintPass<'_> for LargeIncludeFile { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) { if let ExprKind::Lit(lit) = &expr.kind @@ -85,18 +68,32 @@ impl LateLintPass<'_> for LargeIncludeFile { && (cx.tcx.is_diagnostic_item(sym::include_bytes_macro, macro_call.def_id) || cx.tcx.is_diagnostic_item(sym::include_str_macro, macro_call.def_id)) { - self.emit_lint(cx, expr.span.source_callsite()); + #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] + span_lint_and_then( + cx, + LARGE_INCLUDE_FILE, + expr.span.source_callsite(), + "attempted to include a large file", + |diag| { + diag.note(format!( + "the configuration allows a maximum size of {} bytes", + self.max_file_size + )); + }, + ); } } +} - fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &Attribute) { +impl EarlyLintPass for LargeIncludeFile { + fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) { if !attr.span.from_expansion() // Currently, rustc limits the usage of macro at the top-level of attributes, // so we don't need to recurse into each level. && let AttrKind::Normal(ref item) = attr.kind && let Some(doc) = attr.doc_str() && doc.as_str().len() as u64 > self.max_file_size - && let AttrArgs::Eq { expr: meta, .. } = &item.args + && let AttrArgs::Eq { expr: meta, .. } = &item.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. @@ -113,7 +110,19 @@ impl LateLintPass<'_> for LargeIncludeFile { && let sub_snippet = sub_snippet.trim() && (sub_snippet.starts_with("include_str!") || sub_snippet.starts_with("include_bytes!")) { - self.emit_lint(cx, attr.span); + #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] + span_lint_and_then( + cx, + LARGE_INCLUDE_FILE, + attr.span, + "attempted to include a large file", + |diag| { + diag.note(format!( + "the configuration allows a maximum size of {} bytes", + self.max_file_size + )); + }, + ); } } } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 13218331a67b..177f83921cd5 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -407,9 +407,9 @@ mod zombie_processes; use clippy_config::{Conf, get_configuration_metadata, sanitize_explanation}; use clippy_utils::macros::FormatArgsStorage; +use utils::attr_collector::{AttrCollector, AttrStorage}; use rustc_data_structures::fx::FxHashSet; use rustc_lint::{Lint, LintId}; -use utils::attr_collector::{AttrCollector, AttrStorage}; /// Register all pre expansion lints /// @@ -717,6 +717,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(move |_| Box::new(disallowed_names::DisallowedNames::new(conf))); store.register_late_pass(move |tcx| Box::new(functions::Functions::new(tcx, conf))); store.register_late_pass(move |_| Box::new(doc::Documentation::new(conf))); + store.register_early_pass(move || Box::new(doc::Documentation::new(conf))); store.register_late_pass(|_| Box::new(neg_multiply::NegMultiply)); store.register_late_pass(|_| Box::new(let_if_seq::LetIfSeq)); store.register_late_pass(|_| Box::new(mixed_read_write_in_expression::EvalOrderDependence)); @@ -860,6 +861,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_early_pass(|| Box::new(pub_use::PubUse)); store.register_late_pass(|_| Box::new(format_push_string::FormatPushString)); store.register_late_pass(move |_| Box::new(large_include_file::LargeIncludeFile::new(conf))); + store.register_early_pass(move || Box::new(large_include_file::LargeIncludeFile::new(conf))); store.register_late_pass(|_| Box::new(strings::TrimSplitWhitespace)); store.register_late_pass(|_| Box::new(rc_clone_in_vec_init::RcCloneInVecInit)); store.register_early_pass(|| Box::::default()); diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs index 374128665392..165e8c2ea05a 100644 --- a/clippy_lints/src/macro_use.rs +++ b/clippy_lints/src/macro_use.rs @@ -94,7 +94,7 @@ impl LateLintPass<'_> for MacroUseImports { { for kid in cx.tcx.module_children(id) { if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res { - let span = mac_attr.span; + let span = mac_attr.span(); let def_path = cx.tcx.def_path_str(mac_id); self.imports.push((def_path, span, hir_id)); } @@ -104,8 +104,8 @@ impl LateLintPass<'_> for MacroUseImports { } } fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &hir::Attribute) { - if attr.span.from_expansion() { - self.push_unique_macro(cx, attr.span); + if attr.span().from_expansion() { + self.push_unique_macro(cx, attr.span()); } } fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) { diff --git a/clippy_lints/src/manual_non_exhaustive.rs b/clippy_lints/src/manual_non_exhaustive.rs index 00800231fe46..83d8a5093906 100644 --- a/clippy_lints/src/manual_non_exhaustive.rs +++ b/clippy_lints/src/manual_non_exhaustive.rs @@ -116,7 +116,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { if let Some(non_exhaustive) = attr::find_by_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive) { - diag.span_note(non_exhaustive.span, "the struct is already non-exhaustive"); + diag.span_note(non_exhaustive.span(), "the struct is already non-exhaustive"); } else { let indent = snippet_indent(cx, item.span).unwrap_or_default(); diag.span_suggestion_verbose( diff --git a/clippy_lints/src/no_mangle_with_rust_abi.rs b/clippy_lints/src/no_mangle_with_rust_abi.rs index b73b9083a991..6eca3f12cf25 100644 --- a/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { .span .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len())) .shrink_to_lo(); - let attr_snippet = snippet(cx, attr.span, ".."); + let attr_snippet = snippet(cx, attr.span(), ".."); span_lint_and_then( cx, diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index 93abf95e3577..16916e3aaad5 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -432,7 +432,7 @@ fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Spa .hir() .attrs(hir_id) .iter() - .fold(span, |acc, attr| acc.to(attr.span))) + .fold(span, |acc, attr| acc.to(attr.span()))) } enum HasSafetyComment { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 40ddd75b7fad..7fc25e3617d0 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -93,6 +93,7 @@ use std::sync::{Mutex, MutexGuard, OnceLock}; use itertools::Itertools; use rustc_ast::ast::{self, LitKind, RangeLimits}; +use rustc_attr_parsing::{find_attr, AttributeKind}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::packed::Pu128; use rustc_data_structures::unhash::UnhashMap; @@ -1949,7 +1950,7 @@ pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool { } pub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - has_attr(cx.tcx.hir().attrs(hir_id), sym::repr) + find_attr!(cx.tcx.hir().attrs(hir_id), AttributeKind::Repr(..)) } pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool { diff --git a/tests/ui-toml/large_include_file/large_include_file.stderr b/tests/ui-toml/large_include_file/large_include_file.stderr index 82b926cc53ba..c9f0e661dbd1 100644 --- a/tests/ui-toml/large_include_file/large_include_file.stderr +++ b/tests/ui-toml/large_include_file/large_include_file.stderr @@ -1,3 +1,13 @@ +error: attempted to include a large file + --> tests/ui-toml/large_include_file/large_include_file.rs:19:1 + | +LL | #[doc = include_str!("too_big.txt")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the configuration allows a maximum size of 600 bytes + = note: `-D clippy::large-include-file` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::large_include_file)]` + error: attempted to include a large file --> tests/ui-toml/large_include_file/large_include_file.rs:14:43 | @@ -5,8 +15,6 @@ LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the configuration allows a maximum size of 600 bytes - = note: `-D clippy::large-include-file` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::large_include_file)]` error: attempted to include a large file --> tests/ui-toml/large_include_file/large_include_file.rs:16:35 @@ -16,13 +24,5 @@ LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt"); | = note: the configuration allows a maximum size of 600 bytes -error: attempted to include a large file - --> tests/ui-toml/large_include_file/large_include_file.rs:19:1 - | -LL | #[doc = include_str!("too_big.txt")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the configuration allows a maximum size of 600 bytes - error: aborting due to 3 previous errors diff --git a/tests/ui/must_use_unit.fixed b/tests/ui/must_use_unit.fixed index b92d9379c904..f2b990beddc4 100644 --- a/tests/ui/must_use_unit.fixed +++ b/tests/ui/must_use_unit.fixed @@ -24,8 +24,8 @@ fn main() { ); } -#[cfg_attr(all(), deprecated)] +#[cfg_attr(all(), )] fn issue_12320() {} -#[cfg_attr(all(), deprecated, doc = "foo")] +#[cfg_attr(all(), deprecateddoc = "foo", doc = "foo", must_use)] fn issue_12320_2() {} diff --git a/tests/ui/must_use_unit.stderr b/tests/ui/must_use_unit.stderr index b435568deeab..40a0dc3ca9b0 100644 --- a/tests/ui/must_use_unit.stderr +++ b/tests/ui/must_use_unit.stderr @@ -25,19 +25,21 @@ LL | #[must_use = "With note"] LL | pub fn must_use_with_note() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +[Unparsed(AttrItem { path: AttrPath { segments: [must_use#0], span: tests/ui/must_use_unit.rs:30:19: 30:27 (#0) }, args: Empty, id: HashIgnoredAttrId { attr_id: AttrId(9) }, style: Outer, span: tests/ui/must_use_unit.rs:30:19: 30:27 (#0) }), Parsed(Deprecation { deprecation: Deprecation { since: Unspecified, note: None, suggestion: None }, span: tests/ui/must_use_unit.rs:30:29: 30:39 (#0) })] error: this unit-returning function has a `#[must_use]` attribute --> tests/ui/must_use_unit.rs:31:1 | LL | #[cfg_attr(all(), must_use, deprecated)] - | -------------------- help: change these attributes to: `deprecated` + | -------------------- help: change these attributes to LL | fn issue_12320() {} | ^^^^^^^^^^^^^^^^ +[Unparsed(AttrItem { path: AttrPath { segments: [doc#0], span: tests/ui/must_use_unit.rs:33:31: 33:34 (#0) }, args: Eq { eq_span: tests/ui/must_use_unit.rs:33:35: 33:36 (#0), expr: MetaItemLit { symbol: "foo", suffix: None, kind: Str("foo", Cooked), span: tests/ui/must_use_unit.rs:33:37: 33:42 (#0) } }, id: HashIgnoredAttrId { attr_id: AttrId(12) }, style: Outer, span: tests/ui/must_use_unit.rs:33:31: 33:42 (#0) }), Unparsed(AttrItem { path: AttrPath { segments: [must_use#0], span: tests/ui/must_use_unit.rs:33:44: 33:52 (#0) }, args: Empty, id: HashIgnoredAttrId { attr_id: AttrId(13) }, style: Outer, span: tests/ui/must_use_unit.rs:33:44: 33:52 (#0) }), Parsed(Deprecation { deprecation: Deprecation { since: Unspecified, note: None, suggestion: None }, span: tests/ui/must_use_unit.rs:33:19: 33:29 (#0) })] error: this unit-returning function has a `#[must_use]` attribute --> tests/ui/must_use_unit.rs:34:1 | LL | #[cfg_attr(all(), deprecated, doc = "foo", must_use)] - | --------------------------------- help: change these attributes to: `deprecated, doc = "foo"` + | -- help: change these attributes to: `doc = "foo",` LL | fn issue_12320_2() {} | ^^^^^^^^^^^^^^^^^^ From 17bda0c0febb8c51fb14a6856d365eab86fc6162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 9 Feb 2025 22:49:59 +0100 Subject: [PATCH 267/991] simplify must-use lint slightly --- clippy_lints/src/functions/must_use.rs | 30 ++++++-------------------- tests/ui/must_use_unit.fixed | 5 ----- tests/ui/must_use_unit.rs | 5 ----- tests/ui/must_use_unit.stderr | 20 +---------------- tests/ui/must_use_unit_12320.rs | 11 ++++++++++ tests/ui/must_use_unit_12320.stderr | 28 ++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 52 deletions(-) create mode 100644 tests/ui/must_use_unit_12320.rs create mode 100644 tests/ui/must_use_unit_12320.stderr diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index dbc08fca3624..0ed4426d6e92 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -124,32 +124,16 @@ fn check_needless_must_use( } else { // When there are multiple attributes, it is not sufficient to simply make `must_use` empty, see // issue #12320. - span_lint_and_then( + // FIXME(jdonszelmann): this used to give a machine-applicable fix. However, it was super fragile, + // honestly looked incorrect, and is a little hard to support for a little bit now. Some day this could be + // re-added. + span_lint_and_help( cx, - MUST_USE_UNIT, + DOUBLE_MUST_USE, fn_header_span, "this unit-returning function has a `#[must_use]` attribute", - |diag| { - let mut attrs_without_must_use = attrs.to_vec(); - attrs_without_must_use.retain(|a| a.id() != attr.id()); - let sugg_str = attrs_without_must_use - .iter() - .map(|a| { - if a.value_str().is_none() { - return a.name_or_empty().to_string(); - } - format!("{} = \"{}\"", a.name_or_empty(), a.value_str().unwrap()) - }) - .collect::>() - .join(", "); - - diag.span_suggestion( - attrs[0].span().with_hi(attrs[attrs.len() - 1].span().hi()), - "change these attributes to", - sugg_str, - Applicability::MachineApplicable, - ); - }, + Some(attr.span()), + "remove `must_use`", ); } } else if attr.value_str().is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) { diff --git a/tests/ui/must_use_unit.fixed b/tests/ui/must_use_unit.fixed index f2b990beddc4..7e2a72960492 100644 --- a/tests/ui/must_use_unit.fixed +++ b/tests/ui/must_use_unit.fixed @@ -24,8 +24,3 @@ fn main() { ); } -#[cfg_attr(all(), )] -fn issue_12320() {} - -#[cfg_attr(all(), deprecateddoc = "foo", doc = "foo", must_use)] -fn issue_12320_2() {} diff --git a/tests/ui/must_use_unit.rs b/tests/ui/must_use_unit.rs index c77e72827504..f41b1a7c8005 100644 --- a/tests/ui/must_use_unit.rs +++ b/tests/ui/must_use_unit.rs @@ -27,8 +27,3 @@ fn main() { ); } -#[cfg_attr(all(), must_use, deprecated)] -fn issue_12320() {} - -#[cfg_attr(all(), deprecated, doc = "foo", must_use)] -fn issue_12320_2() {} diff --git a/tests/ui/must_use_unit.stderr b/tests/ui/must_use_unit.stderr index 40a0dc3ca9b0..c2ee2edda7dc 100644 --- a/tests/ui/must_use_unit.stderr +++ b/tests/ui/must_use_unit.stderr @@ -25,23 +25,5 @@ LL | #[must_use = "With note"] LL | pub fn must_use_with_note() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -[Unparsed(AttrItem { path: AttrPath { segments: [must_use#0], span: tests/ui/must_use_unit.rs:30:19: 30:27 (#0) }, args: Empty, id: HashIgnoredAttrId { attr_id: AttrId(9) }, style: Outer, span: tests/ui/must_use_unit.rs:30:19: 30:27 (#0) }), Parsed(Deprecation { deprecation: Deprecation { since: Unspecified, note: None, suggestion: None }, span: tests/ui/must_use_unit.rs:30:29: 30:39 (#0) })] -error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit.rs:31:1 - | -LL | #[cfg_attr(all(), must_use, deprecated)] - | -------------------- help: change these attributes to -LL | fn issue_12320() {} - | ^^^^^^^^^^^^^^^^ - -[Unparsed(AttrItem { path: AttrPath { segments: [doc#0], span: tests/ui/must_use_unit.rs:33:31: 33:34 (#0) }, args: Eq { eq_span: tests/ui/must_use_unit.rs:33:35: 33:36 (#0), expr: MetaItemLit { symbol: "foo", suffix: None, kind: Str("foo", Cooked), span: tests/ui/must_use_unit.rs:33:37: 33:42 (#0) } }, id: HashIgnoredAttrId { attr_id: AttrId(12) }, style: Outer, span: tests/ui/must_use_unit.rs:33:31: 33:42 (#0) }), Unparsed(AttrItem { path: AttrPath { segments: [must_use#0], span: tests/ui/must_use_unit.rs:33:44: 33:52 (#0) }, args: Empty, id: HashIgnoredAttrId { attr_id: AttrId(13) }, style: Outer, span: tests/ui/must_use_unit.rs:33:44: 33:52 (#0) }), Parsed(Deprecation { deprecation: Deprecation { since: Unspecified, note: None, suggestion: None }, span: tests/ui/must_use_unit.rs:33:19: 33:29 (#0) })] -error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit.rs:34:1 - | -LL | #[cfg_attr(all(), deprecated, doc = "foo", must_use)] - | -- help: change these attributes to: `doc = "foo",` -LL | fn issue_12320_2() {} - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/must_use_unit_12320.rs b/tests/ui/must_use_unit_12320.rs new file mode 100644 index 000000000000..39dcafdb38b5 --- /dev/null +++ b/tests/ui/must_use_unit_12320.rs @@ -0,0 +1,11 @@ +//@aux-build:proc_macros.rs +//@no-rustfix + +#![warn(clippy::must_use_unit)] +#![allow(clippy::unused_unit)] + +#[cfg_attr(all(), must_use, deprecated)] +fn issue_12320() {} + +#[cfg_attr(all(), deprecated, doc = "foo", must_use)] +fn issue_12320_2() {} diff --git a/tests/ui/must_use_unit_12320.stderr b/tests/ui/must_use_unit_12320.stderr new file mode 100644 index 000000000000..b3e1cbc04576 --- /dev/null +++ b/tests/ui/must_use_unit_12320.stderr @@ -0,0 +1,28 @@ +error: this unit-returning function has a `#[must_use]` attribute + --> tests/ui/must_use_unit_12320.rs:8:1 + | +LL | fn issue_12320() {} + | ^^^^^^^^^^^^^^^^ + | +help: remove `must_use` + --> tests/ui/must_use_unit_12320.rs:7:19 + | +LL | #[cfg_attr(all(), must_use, deprecated)] + | ^^^^^^^^ + = note: `-D clippy::double-must-use` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]` + +error: this unit-returning function has a `#[must_use]` attribute + --> tests/ui/must_use_unit_12320.rs:11:1 + | +LL | fn issue_12320_2() {} + | ^^^^^^^^^^^^^^^^^^ + | +help: remove `must_use` + --> tests/ui/must_use_unit_12320.rs:10:44 + | +LL | #[cfg_attr(all(), deprecated, doc = "foo", must_use)] + | ^^^^^^^^ + +error: aborting due to 2 previous errors + From 67a99a36a6bb07a906a93b20fab25876336de8ae Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Mon, 17 Feb 2025 23:36:44 +0900 Subject: [PATCH 268/991] Migrate some leftovers in `add_missing_match_arms` --- .../src/handlers/add_missing_match_arms.rs | 63 ++++--- .../crates/syntax/src/ast/make.rs | 2 +- .../src/ast/syntax_factory/constructors.rs | 156 ++++++++++++++++++ 3 files changed, 196 insertions(+), 25 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 4a9e2256e9b0..eec1e648c0ab 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -1,4 +1,6 @@ use std::iter::{self, Peekable}; +use std::ops::Deref; +use std::rc::Rc; use either::Either; use hir::{sym, Adt, Crate, HasAttrs, ImportPathConfig, ModuleDef, Semantics}; @@ -76,6 +78,11 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let cfg = ctx.config.import_path_config(); + // As `make` is borrowed by the closure that builds `missing_pats`, this is needed + // to satisfy the borrow checker. + let make = Rc::new(SyntaxFactory::new()); + let make_weak = Rc::downgrade(&make); + let module = ctx.sema.scope(expr.syntax())?.module(); let (mut missing_pats, is_non_exhaustive, has_hidden_variants): ( Peekable>>, @@ -92,8 +99,9 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let missing_pats = variants .into_iter() .filter_map(|variant| { + let make = make_weak.upgrade()?; Some(( - build_pat(ctx, module, variant, cfg)?, + build_pat(ctx, make, module, variant, cfg)?, variant.should_be_hidden(ctx.db(), module.krate()), )) }) @@ -140,14 +148,17 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .multi_cartesian_product() .inspect(|_| cov_mark::hit!(add_missing_match_arms_lazy_computation)) - .map(|variants| { + .filter_map(|variants| { let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = - variants.into_iter().filter_map(|variant| build_pat(ctx, module, variant, cfg)); + let patterns = variants.into_iter().filter_map(|variant| { + make_weak.upgrade().and_then(|make| build_pat(ctx, make, module, variant, cfg)) + }); - (ast::Pat::from(make::tuple_pat(patterns)), is_hidden) + make_weak + .upgrade() + .map(|make| (ast::Pat::from(make.tuple_pat(patterns)), is_hidden)) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); ( @@ -172,13 +183,17 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .multi_cartesian_product() .inspect(|_| cov_mark::hit!(add_missing_match_arms_lazy_computation)) - .map(|variants| { + .filter_map(|variants| { let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = - variants.into_iter().filter_map(|variant| build_pat(ctx, module, variant, cfg)); - (ast::Pat::from(make::slice_pat(patterns)), is_hidden) + let patterns = variants.into_iter().filter_map(|variant| { + make_weak.upgrade().and_then(|make| build_pat(ctx, make, module, variant, cfg)) + }); + + make_weak + .upgrade() + .map(|make| (ast::Pat::from(make.slice_pat(patterns)), is_hidden)) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); ( @@ -203,8 +218,6 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) "Fill match arms", ctx.sema.original_range(match_expr.syntax()).range, |builder| { - let make = SyntaxFactory::new(); - // having any hidden variants means that we need a catch-all arm needs_catch_all_arm |= has_hidden_variants; @@ -243,7 +256,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) if needs_catch_all_arm && !has_catch_all_arm { cov_mark::hit!(added_wildcard_pattern); - let arm = make.match_arm(make::wildcard_pat().into(), None, make::ext::expr_todo()); + let arm = make.match_arm(make.wildcard_pat().into(), None, make::ext::expr_todo()); arms.push(arm); } @@ -290,7 +303,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) } } - editor.add_mappings(make.finish_with_mappings()); + editor.add_mappings(Rc::into_inner(make).unwrap().finish_with_mappings()); builder.add_file_edits(ctx.file_id(), editor); }, ) @@ -445,6 +458,7 @@ fn resolve_array_of_enum_def( fn build_pat( ctx: &AssistContext<'_>, + make: impl Deref, module: hir::Module, var: ExtendedVariant, cfg: ImportPathConfig, @@ -455,31 +469,32 @@ fn build_pat( let edition = module.krate().edition(db); let path = mod_path_to_ast(&module.find_path(db, ModuleDef::from(var), cfg)?, edition); let fields = var.fields(db); - let pat = match var.kind(db) { + let pat: ast::Pat = match var.kind(db) { hir::StructKind::Tuple => { let mut name_generator = suggest_name::NameGenerator::new(); let pats = fields.into_iter().map(|f| { let name = name_generator.for_type(&f.ty(db), db, edition); match name { - Some(name) => make::ext::simple_ident_pat(make::name(&name)).into(), - None => make::wildcard_pat().into(), + Some(name) => make::ext::simple_ident_pat(make.name(&name)).into(), + None => make.wildcard_pat().into(), } }); - make::tuple_struct_pat(path, pats).into() + make.tuple_struct_pat(path, pats).into() } hir::StructKind::Record => { - let pats = fields + let fields = fields .into_iter() - .map(|f| make::name(f.name(db).as_str())) - .map(|name| make::ext::simple_ident_pat(name).into()); - make::record_pat(path, pats).into() + .map(|f| make.name_ref(f.name(db).as_str())) + .map(|name_ref| make.record_pat_field_shorthand(name_ref)); + let fields = make.record_pat_field_list(fields, None); + make.record_pat_with_fields(path, fields).into() } - hir::StructKind::Unit => make::path_pat(path), + hir::StructKind::Unit => make.path_pat(path), }; Some(pat) } - ExtendedVariant::True => Some(ast::Pat::from(make::literal_pat("true"))), - ExtendedVariant::False => Some(ast::Pat::from(make::literal_pat("false"))), + ExtendedVariant::True => Some(ast::Pat::from(make.literal_pat("true"))), + ExtendedVariant::False => Some(ast::Pat::from(make.literal_pat("false"))), } } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index 9dc2d8325304..231c21c38f85 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -784,7 +784,7 @@ pub fn record_pat_field_shorthand(name_ref: ast::NameRef) -> ast::RecordPatField ast_from_text(&format!("fn f(S {{ {name_ref} }}: ()))")) } -/// Returns a `BindPat` if the path has just one segment, a `PathPat` otherwise. +/// Returns a `IdentPat` if the path has just one segment, a `PathPat` otherwise. pub fn path_pat(path: ast::Path) -> ast::Pat { return from_text(&path.to_string()); fn from_text(text: &str) -> ast::Pat { diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 572622db544c..044d68b528f3 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -156,6 +156,32 @@ impl SyntaxFactory { make::literal_pat(text).clone_for_update() } + pub fn slice_pat(&self, pats: impl IntoIterator) -> ast::SlicePat { + let (pats, input) = iterator_input(pats); + let ast = make::slice_pat(pats).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input.into_iter(), ast.pats().map(|it| it.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + + pub fn tuple_pat(&self, pats: impl IntoIterator) -> ast::TuplePat { + let (pats, input) = iterator_input(pats); + let ast = make::tuple_pat(pats).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + pub fn tuple_struct_pat( &self, path: ast::Path, @@ -174,6 +200,96 @@ impl SyntaxFactory { ast } + pub fn record_pat_with_fields( + &self, + path: ast::Path, + fields: ast::RecordPatFieldList, + ) -> ast::RecordPat { + let ast = make::record_pat_with_fields(path.clone(), fields.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone()); + builder.map_node( + fields.syntax().clone(), + ast.record_pat_field_list().unwrap().syntax().clone(), + ); + builder.finish(&mut mapping); + } + + ast + } + + pub fn record_pat_field_list( + &self, + fields: impl IntoIterator, + rest_pat: Option, + ) -> ast::RecordPatFieldList { + let (fields, input) = iterator_input(fields); + let ast = make::record_pat_field_list(fields, rest_pat.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + if let Some(rest_pat) = rest_pat { + builder + .map_node(rest_pat.syntax().clone(), ast.rest_pat().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast + } + + pub fn record_pat_field(self, name_ref: ast::NameRef, pat: ast::Pat) -> ast::RecordPatField { + let ast = make::record_pat_field(name_ref.clone(), pat.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(name_ref.syntax().clone(), ast.name_ref().unwrap().syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn record_pat_field_shorthand(&self, name_ref: ast::NameRef) -> ast::RecordPatField { + let ast = make::record_pat_field_shorthand(name_ref.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(name_ref.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn path_pat(&self, path: ast::Path) -> ast::Pat { + let ast = make::path_pat(path.clone()).clone_for_update(); + + match &ast { + ast::Pat::PathPat(ast) => { + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone()); + builder.finish(&mut mapping) + } + } + ast::Pat::IdentPat(ast) => { + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(path.syntax().clone(), ast.name().unwrap().syntax().clone()); + builder.finish(&mut mapping) + } + } + _ => unreachable!(), + } + + ast + } + pub fn block_expr( &self, statements: impl IntoIterator, @@ -214,6 +330,21 @@ impl SyntaxFactory { make::expr_empty_block().clone_for_update() } + pub fn expr_paren(&self, expr: ast::Expr) -> ast::ParenExpr { + // FIXME: `make::expr_paren` should return a `MethodCallExpr`, not just an `Expr` + let ast::Expr::ParenExpr(ast) = make::expr_paren(expr.clone()).clone_for_update() else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn expr_tuple(&self, fields: impl IntoIterator) -> ast::TupleExpr { let (fields, input) = iterator_input(fields); let ast = make::expr_tuple(fields).clone_for_update(); @@ -292,6 +423,31 @@ impl SyntaxFactory { ast } + pub fn expr_method_call( + &self, + receiver: ast::Expr, + method: ast::NameRef, + arg_list: ast::ArgList, + ) -> ast::MethodCallExpr { + // FIXME: `make::expr_method_call` should return a `MethodCallExpr`, not just an `Expr` + let ast::Expr::MethodCallExpr(ast) = + make::expr_method_call(receiver.clone(), method.clone(), arg_list.clone()) + .clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(receiver.syntax().clone(), ast.receiver().unwrap().syntax().clone()); + builder.map_node(method.syntax().clone(), ast.name_ref().unwrap().syntax().clone()); + builder.map_node(arg_list.syntax().clone(), ast.arg_list().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn arg_list(&self, args: impl IntoIterator) -> ast::ArgList { let (args, input) = iterator_input(args); let ast = make::arg_list(args).clone_for_update(); From 756f2131e012be1017a25a4c0222cb9c47182464 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 18 Feb 2025 04:09:27 +0900 Subject: [PATCH 269/991] Migrate `apply_demorgan` to `SyntaxEditor` --- .../src/handlers/apply_demorgan.rs | 120 ++++++++++++------ .../src/handlers/convert_bool_then.rs | 4 +- .../src/handlers/convert_to_guarded_return.rs | 4 +- .../src/handlers/convert_while_to_loop.rs | 4 +- .../ide-assists/src/handlers/invert_if.rs | 4 +- .../crates/ide-assists/src/utils.rs | 78 +++++++++++- 6 files changed, 162 insertions(+), 52 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs index 491727a30a88..83c049d4613b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -3,12 +3,12 @@ use std::collections::VecDeque; use ide_db::{ assists::GroupLabel, famous_defs::FamousDefs, - source_change::SourceChangeBuilder, syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, }; use syntax::{ - ast::{self, make, AstNode, Expr::BinExpr, HasArgList}, - ted, SyntaxKind, T, + ast::{self, syntax_factory::SyntaxFactory, AstNode, Expr::BinExpr, HasArgList}, + syntax_editor::{Position, SyntaxEditor}, + SyntaxKind, SyntaxNode, T, }; use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists}; @@ -58,9 +58,12 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti _ => return None, }; - let demorganed = bin_expr.clone_subtree().clone_for_update(); + let make = SyntaxFactory::new(); + + let demorganed = bin_expr.clone_subtree(); + let mut editor = SyntaxEditor::new(demorganed.syntax().clone()); + editor.replace(demorganed.op_token()?, make.token(inv_token)); - ted::replace(demorganed.op_token()?, ast::make::token(inv_token)); let mut exprs = VecDeque::from([ (bin_expr.lhs()?, demorganed.lhs()?), (bin_expr.rhs()?, demorganed.rhs()?), @@ -70,35 +73,39 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti if let BinExpr(bin_expr) = &expr { if let BinExpr(cbin_expr) = &dm { if op == bin_expr.op_kind()? { - ted::replace(cbin_expr.op_token()?, ast::make::token(inv_token)); + editor.replace(cbin_expr.op_token()?, make.token(inv_token)); exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?)); exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?)); } else { - let mut inv = invert_boolean_expression(expr); - if inv.needs_parens_in(dm.syntax().parent()?) { - inv = ast::make::expr_paren(inv).clone_for_update(); + let mut inv = invert_boolean_expression(&make, expr); + if needs_parens_in_place_of(&inv, &dm.syntax().parent()?, &dm) { + inv = make.expr_paren(inv).into(); } - ted::replace(dm.syntax(), inv.syntax()); + editor.replace(dm.syntax(), inv.syntax()); } } else { return None; } } else { - let mut inv = invert_boolean_expression(dm.clone_subtree()).clone_for_update(); - if inv.needs_parens_in(dm.syntax().parent()?) { - inv = ast::make::expr_paren(inv).clone_for_update(); + let mut inv = invert_boolean_expression(&make, dm.clone()); + if needs_parens_in_place_of(&inv, &dm.syntax().parent()?, &dm) { + inv = make.expr_paren(inv).into(); } - ted::replace(dm.syntax(), inv.syntax()); + editor.replace(dm.syntax(), inv.syntax()); } } + editor.add_mappings(make.finish_with_mappings()); + let edit = editor.finish(); + let demorganed = ast::Expr::cast(edit.new_root().clone())?; + acc.add_group( &GroupLabel("Apply De Morgan's law".to_owned()), AssistId("apply_demorgan", AssistKind::RefactorRewrite), "Apply De Morgan's law", op_range, - |edit| { - let demorganed = ast::Expr::BinExpr(demorganed); + |builder| { + let make = SyntaxFactory::new(); let paren_expr = bin_expr.syntax().parent().and_then(ast::ParenExpr::cast); let neg_expr = paren_expr .clone() @@ -107,24 +114,32 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti .filter(|prefix_expr| matches!(prefix_expr.op_kind(), Some(ast::UnaryOp::Not))) .map(ast::Expr::PrefixExpr); + let mut editor; if let Some(paren_expr) = paren_expr { if let Some(neg_expr) = neg_expr { cov_mark::hit!(demorgan_double_negation); let parent = neg_expr.syntax().parent(); + editor = builder.make_editor(neg_expr.syntax()); if parent.is_some_and(|parent| demorganed.needs_parens_in(parent)) { cov_mark::hit!(demorgan_keep_parens_for_op_precedence2); - edit.replace_ast(neg_expr, make::expr_paren(demorganed)); + editor.replace(neg_expr.syntax(), make.expr_paren(demorganed).syntax()); } else { - edit.replace_ast(neg_expr, demorganed); + editor.replace(neg_expr.syntax(), demorganed.syntax()); }; } else { cov_mark::hit!(demorgan_double_parens); - edit.replace_ast(paren_expr.into(), add_bang_paren(demorganed)); + editor = builder.make_editor(paren_expr.syntax()); + + editor.replace(paren_expr.syntax(), add_bang_paren(&make, demorganed).syntax()); } } else { - edit.replace_ast(bin_expr.into(), add_bang_paren(demorganed)); + editor = builder.make_editor(bin_expr.syntax()); + editor.replace(bin_expr.syntax(), add_bang_paren(&make, demorganed).syntax()); } + + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } @@ -161,7 +176,7 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> let (name, arg_expr) = validate_method_call_expr(ctx, &method_call)?; let ast::Expr::ClosureExpr(closure_expr) = arg_expr else { return None }; - let closure_body = closure_expr.body()?; + let closure_body = closure_expr.body()?.clone_for_update(); let op_range = method_call.syntax().text_range(); let label = format!("Apply De Morgan's law to `Iterator::{}`", name.text().as_str()); @@ -170,18 +185,19 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> AssistId("apply_demorgan_iterator", AssistKind::RefactorRewrite), label, op_range, - |edit| { + |builder| { + let make = SyntaxFactory::new(); + let mut editor = builder.make_editor(method_call.syntax()); // replace the method name let new_name = match name.text().as_str() { - "all" => make::name_ref("any"), - "any" => make::name_ref("all"), + "all" => make.name_ref("any"), + "any" => make.name_ref("all"), _ => unreachable!(), - } - .clone_for_update(); - edit.replace_ast(name, new_name); + }; + editor.replace(name.syntax(), new_name.syntax()); // negate all tail expressions in the closure body - let tail_cb = &mut |e: &_| tail_cb_impl(edit, e); + let tail_cb = &mut |e: &_| tail_cb_impl(&mut editor, &make, e); walk_expr(&closure_body, &mut |expr| { if let ast::Expr::ReturnExpr(ret_expr) = expr { if let Some(ret_expr_arg) = &ret_expr.expr() { @@ -198,15 +214,15 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> .and_then(ast::PrefixExpr::cast) .filter(|prefix_expr| matches!(prefix_expr.op_kind(), Some(ast::UnaryOp::Not))) { - edit.delete( - prefix_expr - .op_token() - .expect("prefix expression always has an operator") - .text_range(), + editor.delete( + prefix_expr.op_token().expect("prefix expression always has an operator"), ); } else { - edit.insert(method_call.syntax().text_range().start(), "!"); + editor.insert(Position::before(method_call.syntax()), make.token(SyntaxKind::BANG)); } + + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } @@ -233,26 +249,50 @@ fn validate_method_call_expr( it_type.impls_trait(sema.db, iter_trait, &[]).then_some((name_ref, arg_expr)) } -fn tail_cb_impl(edit: &mut SourceChangeBuilder, e: &ast::Expr) { +fn tail_cb_impl(editor: &mut SyntaxEditor, make: &SyntaxFactory, e: &ast::Expr) { match e { ast::Expr::BreakExpr(break_expr) => { if let Some(break_expr_arg) = break_expr.expr() { - for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(edit, e)) + for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(editor, make, e)) } } ast::Expr::ReturnExpr(_) => { // all return expressions have already been handled by the walk loop } e => { - let inverted_body = invert_boolean_expression(e.clone()); - edit.replace(e.syntax().text_range(), inverted_body.syntax().text()); + let inverted_body = invert_boolean_expression(make, e.clone()); + editor.replace(e.syntax(), inverted_body.syntax()); } } } /// Add bang and parentheses to the expression. -fn add_bang_paren(expr: ast::Expr) -> ast::Expr { - make::expr_prefix(T![!], make::expr_paren(expr)).into() +fn add_bang_paren(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr { + make.expr_prefix(T![!], make.expr_paren(expr).into()).into() +} + +fn needs_parens_in_place_of( + this: &ast::Expr, + parent: &SyntaxNode, + in_place_of: &ast::Expr, +) -> bool { + assert_eq!(Some(parent), in_place_of.syntax().parent().as_ref()); + + let child_idx = parent + .children() + .enumerate() + .find_map(|(i, it)| if &it == in_place_of.syntax() { Some(i) } else { None }) + .unwrap(); + let parent = parent.clone_subtree(); + let subtree_place = parent.children().nth(child_idx).unwrap(); + + let mut editor = SyntaxEditor::new(parent); + editor.replace(subtree_place, this.syntax()); + let edit = editor.finish(); + + let replaced = edit.new_root().children().nth(child_idx).unwrap(); + let replaced = ast::Expr::cast(replaced).unwrap(); + replaced.needs_parens_in(edit.new_root().clone()) } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index eb784cd1226f..8d391c64ce61 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -13,7 +13,7 @@ use syntax::{ }; use crate::{ - utils::{invert_boolean_expression, unwrap_trivial_block}, + utils::{invert_boolean_expression_legacy, unwrap_trivial_block}, AssistContext, AssistId, AssistKind, Assists, }; @@ -119,7 +119,7 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> | ast::Expr::WhileExpr(_) | ast::Expr::YieldExpr(_) ); - let cond = if invert_cond { invert_boolean_expression(cond) } else { cond }; + let cond = if invert_cond { invert_boolean_expression_legacy(cond) } else { cond }; let cond = if parenthesize { make::expr_paren(cond) } else { cond }; let arg_list = make::arg_list(Some(make::expr_closure(None, closure_body))); let mcall = make::expr_method_call(cond, make::name_ref("then"), arg_list); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index e1966d476c5d..b7a77644496f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -17,7 +17,7 @@ use syntax::{ use crate::{ assist_context::{AssistContext, Assists}, - utils::invert_boolean_expression, + utils::invert_boolean_expression_legacy, AssistId, AssistKind, }; @@ -139,7 +139,7 @@ fn if_expr_to_guarded_return( let new_expr = { let then_branch = make::block_expr(once(make::expr_stmt(early_expression).into()), None); - let cond = invert_boolean_expression(cond_expr); + let cond = invert_boolean_expression_legacy(cond_expr); make::expr_if(cond, then_branch, None).indent(if_indent_level) }; new_expr.syntax().clone_for_update() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs index 0b92beefbcdf..beec64d13b68 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs @@ -13,7 +13,7 @@ use syntax::{ use crate::{ assist_context::{AssistContext, Assists}, - utils::invert_boolean_expression, + utils::invert_boolean_expression_legacy, AssistId, AssistKind, }; @@ -63,7 +63,7 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) let stmts = iter::once(make::expr_stmt(if_expr.into()).into()); make::block_expr(stmts, None) } else { - let if_cond = invert_boolean_expression(while_cond); + let if_cond = invert_boolean_expression_legacy(while_cond); let if_expr = make::expr_if(if_cond, break_block, None).syntax().clone().into(); let elements = while_body.stmt_list().map_or_else( || Either::Left(iter::empty()), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs index 547158e29778..ac710503d8a0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs @@ -6,7 +6,7 @@ use syntax::{ use crate::{ assist_context::{AssistContext, Assists}, - utils::invert_boolean_expression, + utils::invert_boolean_expression_legacy, AssistId, AssistKind, }; @@ -48,7 +48,7 @@ pub(crate) fn invert_if(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() }; acc.add(AssistId("invert_if", AssistKind::RefactorRewrite), "Invert if", if_range, |edit| { - let flip_cond = invert_boolean_expression(cond.clone()); + let flip_cond = invert_boolean_expression_legacy(cond.clone()); edit.replace_ast(cond, flip_cond); let else_node = else_block.syntax(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index c1332d99bff9..39686f065a9c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -17,7 +17,9 @@ use syntax::{ self, edit::{AstNodeEdit, IndentLevel}, edit_in_place::{AttrsOwnerEdit, Indent, Removable}, - make, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, + make, + syntax_factory::SyntaxFactory, + HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, }, ted, AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile, SyntaxKind::*, @@ -245,11 +247,79 @@ pub(crate) fn vis_offset(node: &SyntaxNode) -> TextSize { .unwrap_or_else(|| node.text_range().start()) } -pub(crate) fn invert_boolean_expression(expr: ast::Expr) -> ast::Expr { - invert_special_case(&expr).unwrap_or_else(|| make::expr_prefix(T![!], expr).into()) +pub(crate) fn invert_boolean_expression(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr { + invert_special_case(make, &expr).unwrap_or_else(|| make.expr_prefix(T![!], expr).into()) } -fn invert_special_case(expr: &ast::Expr) -> Option { +// FIXME: Migrate usages of this function to the above function and remove this. +pub(crate) fn invert_boolean_expression_legacy(expr: ast::Expr) -> ast::Expr { + invert_special_case_legacy(&expr).unwrap_or_else(|| make::expr_prefix(T![!], expr).into()) +} + +fn invert_special_case(make: &SyntaxFactory, expr: &ast::Expr) -> Option { + match expr { + ast::Expr::BinExpr(bin) => { + let op_kind = bin.op_kind()?; + let rev_kind = match op_kind { + ast::BinaryOp::CmpOp(ast::CmpOp::Eq { negated }) => { + ast::BinaryOp::CmpOp(ast::CmpOp::Eq { negated: !negated }) + } + ast::BinaryOp::CmpOp(ast::CmpOp::Ord { ordering: ast::Ordering::Less, strict }) => { + ast::BinaryOp::CmpOp(ast::CmpOp::Ord { + ordering: ast::Ordering::Greater, + strict: !strict, + }) + } + ast::BinaryOp::CmpOp(ast::CmpOp::Ord { + ordering: ast::Ordering::Greater, + strict, + }) => ast::BinaryOp::CmpOp(ast::CmpOp::Ord { + ordering: ast::Ordering::Less, + strict: !strict, + }), + // Parenthesize other expressions before prefixing `!` + _ => { + return Some( + make.expr_prefix(T![!], make.expr_paren(expr.clone()).into()).into(), + ); + } + }; + + Some(make.expr_bin(bin.lhs()?, rev_kind, bin.rhs()?).into()) + } + ast::Expr::MethodCallExpr(mce) => { + let receiver = mce.receiver()?; + let method = mce.name_ref()?; + let arg_list = mce.arg_list()?; + + let method = match method.text().as_str() { + "is_some" => "is_none", + "is_none" => "is_some", + "is_ok" => "is_err", + "is_err" => "is_ok", + _ => return None, + }; + + Some(make.expr_method_call(receiver, make.name_ref(method), arg_list).into()) + } + ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::UnaryOp::Not => match pe.expr()? { + ast::Expr::ParenExpr(parexpr) => { + parexpr.expr().map(|e| e.clone_subtree().clone_for_update()) + } + _ => pe.expr().map(|e| e.clone_subtree().clone_for_update()), + }, + ast::Expr::Literal(lit) => match lit.kind() { + ast::LiteralKind::Bool(b) => match b { + true => Some(ast::Expr::Literal(make.expr_literal("false"))), + false => Some(ast::Expr::Literal(make.expr_literal("true"))), + }, + _ => None, + }, + _ => None, + } +} + +fn invert_special_case_legacy(expr: &ast::Expr) -> Option { match expr { ast::Expr::BinExpr(bin) => { let bin = bin.clone_for_update(); From 1c2225be63da396aec64544c7867428fc17739eb Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 18 Feb 2025 23:58:18 +0900 Subject: [PATCH 270/991] Add `take()` method to `SyntaxEditor` --- .../src/handlers/add_missing_match_arms.rs | 38 +++++++------------ .../crates/syntax/src/ast/syntax_factory.rs | 5 +++ .../src/ast/syntax_factory/constructors.rs | 2 +- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index eec1e648c0ab..37f5f44dfa02 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -1,6 +1,4 @@ use std::iter::{self, Peekable}; -use std::ops::Deref; -use std::rc::Rc; use either::Either; use hir::{sym, Adt, Crate, HasAttrs, ImportPathConfig, ModuleDef, Semantics}; @@ -78,10 +76,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let cfg = ctx.config.import_path_config(); - // As `make` is borrowed by the closure that builds `missing_pats`, this is needed - // to satisfy the borrow checker. - let make = Rc::new(SyntaxFactory::new()); - let make_weak = Rc::downgrade(&make); + let make = SyntaxFactory::new(); let module = ctx.sema.scope(expr.syntax())?.module(); let (mut missing_pats, is_non_exhaustive, has_hidden_variants): ( @@ -99,9 +94,8 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let missing_pats = variants .into_iter() .filter_map(|variant| { - let make = make_weak.upgrade()?; Some(( - build_pat(ctx, make, module, variant, cfg)?, + build_pat(ctx, &make, module, variant, cfg)?, variant.should_be_hidden(ctx.db(), module.krate()), )) }) @@ -148,17 +142,15 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .multi_cartesian_product() .inspect(|_| cov_mark::hit!(add_missing_match_arms_lazy_computation)) - .filter_map(|variants| { + .map(|variants| { let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = variants.into_iter().filter_map(|variant| { - make_weak.upgrade().and_then(|make| build_pat(ctx, make, module, variant, cfg)) - }); + let patterns = variants + .into_iter() + .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg)); - make_weak - .upgrade() - .map(|make| (ast::Pat::from(make.tuple_pat(patterns)), is_hidden)) + (ast::Pat::from(make.tuple_pat(patterns)), is_hidden) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); ( @@ -183,17 +175,15 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .multi_cartesian_product() .inspect(|_| cov_mark::hit!(add_missing_match_arms_lazy_computation)) - .filter_map(|variants| { + .map(|variants| { let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = variants.into_iter().filter_map(|variant| { - make_weak.upgrade().and_then(|make| build_pat(ctx, make, module, variant, cfg)) - }); + let patterns = variants + .into_iter() + .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg)); - make_weak - .upgrade() - .map(|make| (ast::Pat::from(make.slice_pat(patterns)), is_hidden)) + (ast::Pat::from(make.slice_pat(patterns)), is_hidden) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); ( @@ -303,7 +293,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) } } - editor.add_mappings(Rc::into_inner(make).unwrap().finish_with_mappings()); + editor.add_mappings(make.take()); builder.add_file_edits(ctx.file_id(), editor); }, ) @@ -458,7 +448,7 @@ fn resolve_array_of_enum_def( fn build_pat( ctx: &AssistContext<'_>, - make: impl Deref, + make: &SyntaxFactory, module: hir::Module, var: ExtendedVariant, cfg: ImportPathConfig, diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs index 73bbe49105d9..1c517ac2c77e 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs @@ -33,6 +33,11 @@ impl SyntaxFactory { self.mappings.unwrap_or_default().into_inner() } + /// Take all of the tracked syntax mappings, leaving `SyntaxMapping::default()` in its place, if any. + pub fn take(&self) -> SyntaxMapping { + self.mappings.as_ref().map(|mappings| mappings.take()).unwrap_or_default() + } + fn mappings(&self) -> Option> { self.mappings.as_ref().map(|it| it.borrow_mut()) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 044d68b528f3..19c5c64e2184 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -331,7 +331,7 @@ impl SyntaxFactory { } pub fn expr_paren(&self, expr: ast::Expr) -> ast::ParenExpr { - // FIXME: `make::expr_paren` should return a `MethodCallExpr`, not just an `Expr` + // FIXME: `make::expr_paren` should return a `ParenExpr`, not just an `Expr` let ast::Expr::ParenExpr(ast) = make::expr_paren(expr.clone()).clone_for_update() else { unreachable!() }; From efcf1f57302b9d865caea8e069aef826e060e0b2 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Tue, 7 Jan 2025 16:01:23 +0000 Subject: [PATCH 271/991] Split needless_lifetime '_ suggestions into elidable_lifetime_names --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lifetimes.rs | 110 ++++++-- ... elidable_lifetime_names_impl_trait.fixed} | 6 +- ... => elidable_lifetime_names_impl_trait.rs} | 6 +- ...elidable_lifetime_names_impl_trait.stderr} | 10 +- tests/ui/elidable_lifetime_names.fixed | 194 ++++++++++++++ tests/ui/elidable_lifetime_names.rs | 194 ++++++++++++++ tests/ui/elidable_lifetime_names.stderr | 162 ++++++++++++ tests/ui/methods.rs | 1 + tests/ui/methods.stderr | 4 +- tests/ui/needless_lifetimes.fixed | 199 +-------------- tests/ui/needless_lifetimes.rs | 199 +-------------- tests/ui/needless_lifetimes.stderr | 237 +++--------------- 14 files changed, 687 insertions(+), 637 deletions(-) rename tests/ui/crashes/{needless_lifetimes_impl_trait.fixed => elidable_lifetime_names_impl_trait.fixed} (65%) rename tests/ui/crashes/{needless_lifetimes_impl_trait.rs => elidable_lifetime_names_impl_trait.rs} (67%) rename tests/ui/crashes/{needless_lifetimes_impl_trait.stderr => elidable_lifetime_names_impl_trait.stderr} (67%) create mode 100644 tests/ui/elidable_lifetime_names.fixed create mode 100644 tests/ui/elidable_lifetime_names.rs create mode 100644 tests/ui/elidable_lifetime_names.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index be5e95e9744e..fa2143a3493e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5592,6 +5592,7 @@ Released 2018-09-13 [`duplicated_attributes`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicated_attributes [`duration_subsec`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_subsec [`eager_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#eager_transmute +[`elidable_lifetime_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#elidable_lifetime_names [`else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else [`empty_docs`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_docs [`empty_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_drop diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 9df9a62438ce..0bfc6b14588b 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -273,6 +273,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::let_underscore::LET_UNDERSCORE_MUST_USE_INFO, crate::let_underscore::LET_UNDERSCORE_UNTYPED_INFO, crate::let_with_type_underscore::LET_WITH_TYPE_UNDERSCORE_INFO, + crate::lifetimes::ELIDABLE_LIFETIME_NAMES_INFO, crate::lifetimes::EXTRA_UNUSED_LIFETIMES_INFO, crate::lifetimes::NEEDLESS_LIFETIMES_INFO, crate::lines_filter_map_ok::LINES_FILTER_MAP_OK_INFO, diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index f08812017b9c..7589ab1229af 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -38,8 +38,8 @@ declare_clippy_lint! { /// them leads to more readable code. /// /// ### Known problems - /// - We bail out if the function has a `where` clause where lifetimes - /// are mentioned due to potential false positives. + /// This lint ignores functions with `where` clauses that reference + /// lifetimes to prevent false positives. /// /// ### Example /// ```no_run @@ -62,6 +62,38 @@ declare_clippy_lint! { would allow omitting them" } +declare_clippy_lint! { + /// ### What it does + /// Checks for lifetime annotations which can be replaced with anonymous lifetimes (`'_`). + /// + /// ### Why is this bad? + /// The additional lifetimes can make the code look more complicated. + /// + /// ### Known problems + /// This lint ignores functions with `where` clauses that reference + /// lifetimes to prevent false positives. + /// + /// ### Example + /// ```no_run + /// # use std::str::Chars; + /// fn f<'a>(x: &'a str) -> Chars<'a> { + /// x.chars() + /// } + /// ``` + /// + /// Use instead: + /// ```no_run + /// # use std::str::Chars; + /// fn f(x: &str) -> Chars<'_> { + /// x.chars() + /// } + /// ``` + #[clippy::version = "1.84.0"] + pub ELIDABLE_LIFETIME_NAMES, + pedantic, + "lifetime name that can be replaced with the anonymous lifetime" +} + declare_clippy_lint! { /// ### What it does /// Checks for lifetimes in generics that are never used @@ -104,7 +136,11 @@ impl Lifetimes { } } -impl_lint_pass!(Lifetimes => [NEEDLESS_LIFETIMES, EXTRA_UNUSED_LIFETIMES]); +impl_lint_pass!(Lifetimes => [ + NEEDLESS_LIFETIMES, + ELIDABLE_LIFETIME_NAMES, + EXTRA_UNUSED_LIFETIMES, +]); impl<'tcx> LateLintPass<'tcx> for Lifetimes { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { @@ -746,6 +782,15 @@ fn report_elidable_impl_lifetimes<'tcx>( report_elidable_lifetimes(cx, impl_.generics, &elidable_lts, &usages, true); } +#[derive(Copy, Clone)] +enum ElidableUsage { + /// Used in a ref (`&'a T`), can be removed + Ref(Span), + /// Used as a generic param (`T<'a>`) or an impl lifetime (`impl T + 'a`), can be replaced + /// with `'_` + Other(Span), +} + /// Generate diagnostic messages for elidable lifetimes. fn report_elidable_lifetimes( cx: &LateContext<'_>, @@ -763,9 +808,29 @@ fn report_elidable_lifetimes( .collect::>() .join(", "); + let elidable_usages: Vec = usages + .iter() + .filter(|usage| named_lifetime(usage).is_some_and(|id| elidable_lts.contains(&id))) + .map(|usage| match cx.tcx.parent_hir_node(usage.hir_id) { + Node::Ty(Ty { + kind: TyKind::Ref(..), .. + }) => ElidableUsage::Ref(usage.ident.span), + _ => ElidableUsage::Other(usage.ident.span), + }) + .collect(); + + let lint = if elidable_usages + .iter() + .any(|usage| matches!(usage, ElidableUsage::Other(_))) + { + ELIDABLE_LIFETIME_NAMES + } else { + NEEDLESS_LIFETIMES + }; + span_lint_and_then( cx, - NEEDLESS_LIFETIMES, + lint, elidable_lts .iter() .map(|<| cx.tcx.def_span(lt)) @@ -785,7 +850,7 @@ fn report_elidable_lifetimes( return; } - if let Some(suggestions) = elision_suggestions(cx, generics, elidable_lts, usages) { + if let Some(suggestions) = elision_suggestions(cx, generics, elidable_lts, &elidable_usages) { diag.multipart_suggestion("elide the lifetimes", suggestions, Applicability::MachineApplicable); } }, @@ -796,7 +861,7 @@ fn elision_suggestions( cx: &LateContext<'_>, generics: &Generics<'_>, elidable_lts: &[LocalDefId], - usages: &[Lifetime], + usages: &[ElidableUsage], ) -> Option> { let explicit_params = generics .params @@ -836,26 +901,21 @@ fn elision_suggestions( .collect::>>()? }; - suggestions.extend( - usages - .iter() - .filter(|usage| named_lifetime(usage).is_some_and(|id| elidable_lts.contains(&id))) - .map(|usage| { - match cx.tcx.parent_hir_node(usage.hir_id) { - Node::Ty(Ty { - kind: TyKind::Ref(..), .. - }) => { - // expand `&'a T` to `&'a T` - // ^^ ^^^ - let span = cx.sess().source_map().span_extend_while_whitespace(usage.ident.span); + suggestions.extend(usages.iter().map(|&usage| { + match usage { + ElidableUsage::Ref(span) => { + // expand `&'a T` to `&'a T` + // ^^ ^^^ + let span = cx.sess().source_map().span_extend_while_whitespace(span); - (span, String::new()) - }, - // `T<'a>` and `impl Foo + 'a` should be replaced by `'_` - _ => (usage.ident.span, String::from("'_")), - } - }), - ); + (span, String::new()) + }, + ElidableUsage::Other(span) => { + // `T<'a>` and `impl Foo + 'a` should be replaced by `'_` + (span, String::from("'_")) + }, + } + })); Some(suggestions) } diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.fixed b/tests/ui/crashes/elidable_lifetime_names_impl_trait.fixed similarity index 65% rename from tests/ui/crashes/needless_lifetimes_impl_trait.fixed rename to tests/ui/crashes/elidable_lifetime_names_impl_trait.fixed index da3b82a60c5f..681887314ed5 100644 --- a/tests/ui/crashes/needless_lifetimes_impl_trait.fixed +++ b/tests/ui/crashes/elidable_lifetime_names_impl_trait.fixed @@ -1,4 +1,4 @@ -#![deny(clippy::needless_lifetimes)] +#![deny(clippy::elidable_lifetime_names)] #![allow(dead_code)] trait Foo {} @@ -10,11 +10,11 @@ struct Baz<'a> { } impl Foo for Baz<'_> {} -//~^ needless_lifetimes +//~^ elidable_lifetime_names impl Bar { fn baz(&self) -> impl Foo + '_ { - //~^ needless_lifetimes + //~^ elidable_lifetime_names Baz { bar: self } } diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.rs b/tests/ui/crashes/elidable_lifetime_names_impl_trait.rs similarity index 67% rename from tests/ui/crashes/needless_lifetimes_impl_trait.rs rename to tests/ui/crashes/elidable_lifetime_names_impl_trait.rs index 456d315926db..ed5f95bdca82 100644 --- a/tests/ui/crashes/needless_lifetimes_impl_trait.rs +++ b/tests/ui/crashes/elidable_lifetime_names_impl_trait.rs @@ -1,4 +1,4 @@ -#![deny(clippy::needless_lifetimes)] +#![deny(clippy::elidable_lifetime_names)] #![allow(dead_code)] trait Foo {} @@ -10,11 +10,11 @@ struct Baz<'a> { } impl<'a> Foo for Baz<'a> {} -//~^ needless_lifetimes +//~^ elidable_lifetime_names impl Bar { fn baz<'a>(&'a self) -> impl Foo + 'a { - //~^ needless_lifetimes + //~^ elidable_lifetime_names Baz { bar: self } } diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.stderr b/tests/ui/crashes/elidable_lifetime_names_impl_trait.stderr similarity index 67% rename from tests/ui/crashes/needless_lifetimes_impl_trait.stderr rename to tests/ui/crashes/elidable_lifetime_names_impl_trait.stderr index 97fb6d29cfbe..ef4b7e0a476e 100644 --- a/tests/ui/crashes/needless_lifetimes_impl_trait.stderr +++ b/tests/ui/crashes/elidable_lifetime_names_impl_trait.stderr @@ -1,14 +1,14 @@ error: the following explicit lifetimes could be elided: 'a - --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:12:6 + --> tests/ui/crashes/elidable_lifetime_names_impl_trait.rs:12:6 | LL | impl<'a> Foo for Baz<'a> {} | ^^ ^^ | note: the lint level is defined here - --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:1:9 + --> tests/ui/crashes/elidable_lifetime_names_impl_trait.rs:1:9 | -LL | #![deny(clippy::needless_lifetimes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(clippy::elidable_lifetime_names)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: elide the lifetimes | LL - impl<'a> Foo for Baz<'a> {} @@ -16,7 +16,7 @@ LL + impl Foo for Baz<'_> {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:16:12 + --> tests/ui/crashes/elidable_lifetime_names_impl_trait.rs:16:12 | LL | fn baz<'a>(&'a self) -> impl Foo + 'a { | ^^ ^^ ^^ diff --git a/tests/ui/elidable_lifetime_names.fixed b/tests/ui/elidable_lifetime_names.fixed new file mode 100644 index 000000000000..abeee5c4cef3 --- /dev/null +++ b/tests/ui/elidable_lifetime_names.fixed @@ -0,0 +1,194 @@ +#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)] + +type Ref<'r> = &'r u8; + +// No error; same lifetime on two params. +fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {} + +//~v ERROR: could be elided: 'a, 'b +fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {} + +// No error; bounded lifetime. +fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {} + +// No error; bounded lifetime. +fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8) +where + 'b: 'a, +{ +} + +struct Lt<'a, I: 'static> { + x: &'a I, +} + +// No error; fn bound references `'a`. +fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> +where + F: Fn(Lt<'a, I>) -> Lt<'a, I>, +{ + unreachable!() +} + +//~v ERROR: could be elided: 'a +fn fn_bound_2(_m: Lt<'_, I>, _f: F) -> Lt<'_, I> +where + for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>, +{ + unreachable!() +} + +struct Foo<'a>(&'a u8); + +//~v ERROR: could be elided: 'a +fn struct_with_lt(_foo: Foo<'_>) -> &str { + unimplemented!() +} + +// No warning; two input lifetimes (named on the reference, anonymous on `Foo`). +fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str { + unimplemented!() +} + +// No warning; two input lifetimes (anonymous on the reference, named on `Foo`). +fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str { + unimplemented!() +} + +//~v ERROR: could be elided: 'b +fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { + unimplemented!() +} + +type FooAlias<'a> = Foo<'a>; + +//~v ERROR: could be elided: 'a +fn alias_with_lt(_foo: FooAlias<'_>) -> &str { + unimplemented!() +} + +// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`). +fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str { + unimplemented!() +} + +// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`). +fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str { + unimplemented!() +} + +//~v ERROR: could be elided: 'b +fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { + unimplemented!() +} + +// Issue #3284: give hint regarding lifetime in return type. +struct Cow<'a> { + x: &'a str, +} + +//~v ERROR: could be elided: 'a +fn out_return_type_lts(e: &str) -> Cow<'_> { + unimplemented!() +} + +mod issue2944 { + trait Foo {} + struct Bar; + struct Baz<'a> { + bar: &'a Bar, + } + + //~v ERROR: could be elided: 'a + impl Foo for Baz<'_> {} + impl Bar { + //~v ERROR: could be elided: 'a + fn baz(&self) -> impl Foo + '_ { + Baz { bar: self } + } + } +} + +mod issue13923 { + struct Py<'py> { + data: &'py str, + } + + enum Content<'t, 'py> { + Py(Py<'py>), + T1(&'t str), + T2(&'t str), + } + + enum ContentString<'t> { + T1(&'t str), + T2(&'t str), + } + + impl<'t, 'py> ContentString<'t> { + // `'py` cannot be elided + fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { + match self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(content) => Content::T2(f(content)), + } + } + } + + //~v ERROR: could be elided: 'py + impl<'t> ContentString<'t> { + // `'py` can be elided because of `&self` + fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { + match self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(content) => Content::T2(f(content)), + } + } + } + + //~v ERROR: could be elided: 'py + impl<'t> ContentString<'t> { + // `'py` can be elided because of `&'_ self` + fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { + match self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(content) => Content::T2(f(content)), + } + } + } + + impl<'t, 'py> ContentString<'t> { + // `'py` should not be elided as the default lifetime, even if working, could be named as `'t` + fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> { + match self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(_) => Content::T2(o), + } + } + } + + //~v ERROR: could be elided: 'py + impl<'t> ContentString<'t> { + // `'py` can be elided because of `&Self` + fn map_content5( + self: std::pin::Pin<&Self>, + f: impl FnOnce(&'t str) -> &'t str, + o: &'t str, + ) -> Content<'t, '_> { + match *self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(_) => Content::T2(o), + } + } + } + + struct Cx<'a, 'b> { + a: &'a u32, + b: &'b u32, + } + + // `'c` cannot be elided because we have several input lifetimes + fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 { + x.b + } +} diff --git a/tests/ui/elidable_lifetime_names.rs b/tests/ui/elidable_lifetime_names.rs new file mode 100644 index 000000000000..fae3577a8e96 --- /dev/null +++ b/tests/ui/elidable_lifetime_names.rs @@ -0,0 +1,194 @@ +#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)] + +type Ref<'r> = &'r u8; + +// No error; same lifetime on two params. +fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {} + +//~v ERROR: could be elided: 'a, 'b +fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} + +// No error; bounded lifetime. +fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {} + +// No error; bounded lifetime. +fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8) +where + 'b: 'a, +{ +} + +struct Lt<'a, I: 'static> { + x: &'a I, +} + +// No error; fn bound references `'a`. +fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> +where + F: Fn(Lt<'a, I>) -> Lt<'a, I>, +{ + unreachable!() +} + +//~v ERROR: could be elided: 'a +fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> +where + for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>, +{ + unreachable!() +} + +struct Foo<'a>(&'a u8); + +//~v ERROR: could be elided: 'a +fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { + unimplemented!() +} + +// No warning; two input lifetimes (named on the reference, anonymous on `Foo`). +fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str { + unimplemented!() +} + +// No warning; two input lifetimes (anonymous on the reference, named on `Foo`). +fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str { + unimplemented!() +} + +//~v ERROR: could be elided: 'b +fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { + unimplemented!() +} + +type FooAlias<'a> = Foo<'a>; + +//~v ERROR: could be elided: 'a +fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { + unimplemented!() +} + +// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`). +fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str { + unimplemented!() +} + +// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`). +fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str { + unimplemented!() +} + +//~v ERROR: could be elided: 'b +fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { + unimplemented!() +} + +// Issue #3284: give hint regarding lifetime in return type. +struct Cow<'a> { + x: &'a str, +} + +//~v ERROR: could be elided: 'a +fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { + unimplemented!() +} + +mod issue2944 { + trait Foo {} + struct Bar; + struct Baz<'a> { + bar: &'a Bar, + } + + //~v ERROR: could be elided: 'a + impl<'a> Foo for Baz<'a> {} + impl Bar { + //~v ERROR: could be elided: 'a + fn baz<'a>(&'a self) -> impl Foo + 'a { + Baz { bar: self } + } + } +} + +mod issue13923 { + struct Py<'py> { + data: &'py str, + } + + enum Content<'t, 'py> { + Py(Py<'py>), + T1(&'t str), + T2(&'t str), + } + + enum ContentString<'t> { + T1(&'t str), + T2(&'t str), + } + + impl<'t, 'py> ContentString<'t> { + // `'py` cannot be elided + fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { + match self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(content) => Content::T2(f(content)), + } + } + } + + //~v ERROR: could be elided: 'py + impl<'t, 'py> ContentString<'t> { + // `'py` can be elided because of `&self` + fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { + match self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(content) => Content::T2(f(content)), + } + } + } + + //~v ERROR: could be elided: 'py + impl<'t, 'py> ContentString<'t> { + // `'py` can be elided because of `&'_ self` + fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { + match self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(content) => Content::T2(f(content)), + } + } + } + + impl<'t, 'py> ContentString<'t> { + // `'py` should not be elided as the default lifetime, even if working, could be named as `'t` + fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> { + match self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(_) => Content::T2(o), + } + } + } + + //~v ERROR: could be elided: 'py + impl<'t, 'py> ContentString<'t> { + // `'py` can be elided because of `&Self` + fn map_content5( + self: std::pin::Pin<&Self>, + f: impl FnOnce(&'t str) -> &'t str, + o: &'t str, + ) -> Content<'t, 'py> { + match *self { + Self::T1(content) => Content::T1(f(content)), + Self::T2(_) => Content::T2(o), + } + } + } + + struct Cx<'a, 'b> { + a: &'a u32, + b: &'b u32, + } + + // `'c` cannot be elided because we have several input lifetimes + fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 { + x.b + } +} diff --git a/tests/ui/elidable_lifetime_names.stderr b/tests/ui/elidable_lifetime_names.stderr new file mode 100644 index 000000000000..a60dfc697564 --- /dev/null +++ b/tests/ui/elidable_lifetime_names.stderr @@ -0,0 +1,162 @@ +error: the following explicit lifetimes could be elided: 'a, 'b + --> tests/ui/elidable_lifetime_names.rs:9:21 + | +LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} + | ^^ ^^ ^^ ^^ + | + = note: `-D clippy::elidable-lifetime-names` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::elidable_lifetime_names)]` +help: elide the lifetimes + | +LL - fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} +LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {} + | + +error: the following explicit lifetimes could be elided: 'a + --> tests/ui/elidable_lifetime_names.rs:34:15 + | +LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> + | ^^ ^^ ^^ + | +help: elide the lifetimes + | +LL - fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> +LL + fn fn_bound_2(_m: Lt<'_, I>, _f: F) -> Lt<'_, I> + | + +error: the following explicit lifetimes could be elided: 'a + --> tests/ui/elidable_lifetime_names.rs:44:19 + | +LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { + | ^^ ^^ ^^ + | +help: elide the lifetimes + | +LL - fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { +LL + fn struct_with_lt(_foo: Foo<'_>) -> &str { + | + +error: the following explicit lifetimes could be elided: 'b + --> tests/ui/elidable_lifetime_names.rs:59:25 + | +LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { + | ^^ ^^ + | +help: elide the lifetimes + | +LL - fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { +LL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { + | + +error: the following explicit lifetimes could be elided: 'a + --> tests/ui/elidable_lifetime_names.rs:66:18 + | +LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { + | ^^ ^^ ^^ + | +help: elide the lifetimes + | +LL - fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { +LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str { + | + +error: the following explicit lifetimes could be elided: 'b + --> tests/ui/elidable_lifetime_names.rs:81:24 + | +LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { + | ^^ ^^ + | +help: elide the lifetimes + | +LL - fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { +LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { + | + +error: the following explicit lifetimes could be elided: 'a + --> tests/ui/elidable_lifetime_names.rs:91:24 + | +LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { + | ^^ ^^ ^^ + | +help: elide the lifetimes + | +LL - fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { +LL + fn out_return_type_lts(e: &str) -> Cow<'_> { + | + +error: the following explicit lifetimes could be elided: 'a + --> tests/ui/elidable_lifetime_names.rs:103:10 + | +LL | impl<'a> Foo for Baz<'a> {} + | ^^ ^^ + | +help: elide the lifetimes + | +LL - impl<'a> Foo for Baz<'a> {} +LL + impl Foo for Baz<'_> {} + | + +error: the following explicit lifetimes could be elided: 'a + --> tests/ui/elidable_lifetime_names.rs:106:16 + | +LL | fn baz<'a>(&'a self) -> impl Foo + 'a { + | ^^ ^^ ^^ + | +help: elide the lifetimes + | +LL - fn baz<'a>(&'a self) -> impl Foo + 'a { +LL + fn baz(&self) -> impl Foo + '_ { + | + +error: the following explicit lifetimes could be elided: 'py + --> tests/ui/elidable_lifetime_names.rs:139:14 + | +LL | impl<'t, 'py> ContentString<'t> { + | ^^^ +LL | // `'py` can be elided because of `&self` +LL | fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { + | ^^^ + | +help: elide the lifetimes + | +LL ~ impl<'t> ContentString<'t> { +LL | // `'py` can be elided because of `&self` +LL ~ fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { + | + +error: the following explicit lifetimes could be elided: 'py + --> tests/ui/elidable_lifetime_names.rs:150:14 + | +LL | impl<'t, 'py> ContentString<'t> { + | ^^^ +LL | // `'py` can be elided because of `&'_ self` +LL | fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { + | ^^^ + | +help: elide the lifetimes + | +LL ~ impl<'t> ContentString<'t> { +LL | // `'py` can be elided because of `&'_ self` +LL ~ fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { + | + +error: the following explicit lifetimes could be elided: 'py + --> tests/ui/elidable_lifetime_names.rs:171:14 + | +LL | impl<'t, 'py> ContentString<'t> { + | ^^^ +... +LL | ) -> Content<'t, 'py> { + | ^^^ + | +help: elide the lifetimes + | +LL ~ impl<'t> ContentString<'t> { +LL | // `'py` can be elided because of `&Self` +... +LL | o: &'t str, +LL ~ ) -> Content<'t, '_> { + | + +error: aborting due to 12 previous errors + diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs index 85a4d59e5ca0..76b0d131dd41 100644 --- a/tests/ui/methods.rs +++ b/tests/ui/methods.rs @@ -11,6 +11,7 @@ clippy::new_without_default, clippy::needless_pass_by_value, clippy::needless_lifetimes, + clippy::elidable_lifetime_names, clippy::print_stdout, clippy::must_use_candidate, clippy::use_self, diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr index 30e8d0794f71..353b999d7da0 100644 --- a/tests/ui/methods.stderr +++ b/tests/ui/methods.stderr @@ -1,5 +1,5 @@ error: methods called `new` usually return `Self` - --> tests/ui/methods.rs:103:5 + --> tests/ui/methods.rs:104:5 | LL | / fn new() -> i32 { LL | | @@ -11,7 +11,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::new_ret_no_self)]` error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead - --> tests/ui/methods.rs:125:13 + --> tests/ui/methods.rs:126:13 | LL | let _ = v.iter().filter(|&x| { | _____________^ diff --git a/tests/ui/needless_lifetimes.fixed b/tests/ui/needless_lifetimes.fixed index 283635d42def..d59393fb3f3c 100644 --- a/tests/ui/needless_lifetimes.fixed +++ b/tests/ui/needless_lifetimes.fixed @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs -#![warn(clippy::needless_lifetimes)] +#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)] #![allow( unused, clippy::boxed_local, @@ -101,44 +101,6 @@ where Ok(x) } -type Ref<'r> = &'r u8; - -// No error; same lifetime on two params. -fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {} - -fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {} -//~^ needless_lifetimes - -// No error; bounded lifetime. -fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {} - -// No error; bounded lifetime. -fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8) -where - 'b: 'a, -{ -} - -struct Lt<'a, I: 'static> { - x: &'a I, -} - -// No error; fn bound references `'a`. -fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> -where - F: Fn(Lt<'a, I>) -> Lt<'a, I>, -{ - unreachable!() -} - -fn fn_bound_2(_m: Lt<'_, I>, _f: F) -> Lt<'_, I> -//~^ needless_lifetimes -where - for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>, -{ - unreachable!() -} - // No error; see below. fn fn_bound_3<'a, F: FnOnce(&'a i32)>(x: &'a i32, f: F) { f(x); @@ -203,30 +165,6 @@ fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 { unimplemented!() } -fn struct_with_lt(_foo: Foo<'_>) -> &str { - //~^ needless_lifetimes - unimplemented!() -} - -// No warning; two input lifetimes (named on the reference, anonymous on `Foo`). -fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str { - unimplemented!() -} - -// No warning; two input lifetimes (anonymous on the reference, named on `Foo`). -fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str { - unimplemented!() -} - -// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is -// valid: -// fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str -// ^^ -fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { - //~^ needless_lifetimes - unimplemented!() -} - // Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is // valid: // fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str @@ -254,30 +192,6 @@ fn trait_obj_elided2(_arg: &dyn Drop) -> &str { type FooAlias<'a> = Foo<'a>; -fn alias_with_lt(_foo: FooAlias<'_>) -> &str { - //~^ needless_lifetimes - unimplemented!() -} - -// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`). -fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str { - unimplemented!() -} - -// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`). -fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str { - unimplemented!() -} - -// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is -// valid: -// fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str -// ^^ -fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { - //~^ needless_lifetimes - unimplemented!() -} - // Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is // valid: // fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str @@ -329,15 +243,6 @@ fn test<'a>(x: &'a [u8]) -> u8 { *y } -// Issue #3284: give hint regarding lifetime in return type. -struct Cow<'a> { - x: &'a str, -} -fn out_return_type_lts(e: &str) -> Cow<'_> { - //~^ needless_lifetimes - unimplemented!() -} - // Make sure we still warn on implementations mod issue4291 { trait BadTrait { @@ -351,23 +256,6 @@ mod issue4291 { } } -mod issue2944 { - trait Foo {} - struct Bar; - struct Baz<'a> { - bar: &'a Bar, - } - - impl Foo for Baz<'_> {} - //~^ needless_lifetimes - impl Bar { - fn baz(&self) -> impl Foo + '_ { - //~^ needless_lifetimes - Baz { bar: self } - } - } -} - mod nested_elision_sites { // issue #issue2944 @@ -646,89 +534,4 @@ mod issue13749bis { impl<'a, T: 'a> Generic {} } -mod issue13923 { - struct Py<'py> { - data: &'py str, - } - - enum Content<'t, 'py> { - Py(Py<'py>), - T1(&'t str), - T2(&'t str), - } - - enum ContentString<'t> { - T1(&'t str), - T2(&'t str), - } - - impl<'t, 'py> ContentString<'t> { - // `'py` cannot be elided - fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { - match self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(content) => Content::T2(f(content)), - } - } - } - - impl<'t> ContentString<'t> { - //~^ needless_lifetimes - // `'py` can be elided because of `&self` - fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { - match self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(content) => Content::T2(f(content)), - } - } - } - - impl<'t> ContentString<'t> { - //~^ needless_lifetimes - // `'py` can be elided because of `&'_ self` - fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { - match self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(content) => Content::T2(f(content)), - } - } - } - - impl<'t, 'py> ContentString<'t> { - // `'py` should not be elided as the default lifetime, even if working, could be named as `'t` - fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> { - match self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(_) => Content::T2(o), - } - } - } - - impl<'t> ContentString<'t> { - //~^ needless_lifetimes - // `'py` can be elided because of `&Self` - fn map_content5( - self: std::pin::Pin<&Self>, - f: impl FnOnce(&'t str) -> &'t str, - o: &'t str, - ) -> Content<'t, '_> { - match *self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(_) => Content::T2(o), - } - } - } - - struct Cx<'a, 'b> { - a: &'a u32, - b: &'b u32, - } - - // `'c` cannot be elided because we have several input lifetimes - fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 { - x.b - //~^ needless_borrow - } -} - fn main() {} diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs index 2853870473db..e24907ab5fcd 100644 --- a/tests/ui/needless_lifetimes.rs +++ b/tests/ui/needless_lifetimes.rs @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs -#![warn(clippy::needless_lifetimes)] +#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)] #![allow( unused, clippy::boxed_local, @@ -101,44 +101,6 @@ where Ok(x) } -type Ref<'r> = &'r u8; - -// No error; same lifetime on two params. -fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {} - -fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} -//~^ needless_lifetimes - -// No error; bounded lifetime. -fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {} - -// No error; bounded lifetime. -fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8) -where - 'b: 'a, -{ -} - -struct Lt<'a, I: 'static> { - x: &'a I, -} - -// No error; fn bound references `'a`. -fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> -where - F: Fn(Lt<'a, I>) -> Lt<'a, I>, -{ - unreachable!() -} - -fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> -//~^ needless_lifetimes -where - for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>, -{ - unreachable!() -} - // No error; see below. fn fn_bound_3<'a, F: FnOnce(&'a i32)>(x: &'a i32, f: F) { f(x); @@ -203,30 +165,6 @@ fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 { unimplemented!() } -fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { - //~^ needless_lifetimes - unimplemented!() -} - -// No warning; two input lifetimes (named on the reference, anonymous on `Foo`). -fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str { - unimplemented!() -} - -// No warning; two input lifetimes (anonymous on the reference, named on `Foo`). -fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str { - unimplemented!() -} - -// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is -// valid: -// fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str -// ^^ -fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { - //~^ needless_lifetimes - unimplemented!() -} - // Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is // valid: // fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str @@ -254,30 +192,6 @@ fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str { type FooAlias<'a> = Foo<'a>; -fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { - //~^ needless_lifetimes - unimplemented!() -} - -// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`). -fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str { - unimplemented!() -} - -// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`). -fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str { - unimplemented!() -} - -// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is -// valid: -// fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str -// ^^ -fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { - //~^ needless_lifetimes - unimplemented!() -} - // Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is // valid: // fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str @@ -329,15 +243,6 @@ fn test<'a>(x: &'a [u8]) -> u8 { *y } -// Issue #3284: give hint regarding lifetime in return type. -struct Cow<'a> { - x: &'a str, -} -fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { - //~^ needless_lifetimes - unimplemented!() -} - // Make sure we still warn on implementations mod issue4291 { trait BadTrait { @@ -351,23 +256,6 @@ mod issue4291 { } } -mod issue2944 { - trait Foo {} - struct Bar; - struct Baz<'a> { - bar: &'a Bar, - } - - impl<'a> Foo for Baz<'a> {} - //~^ needless_lifetimes - impl Bar { - fn baz<'a>(&'a self) -> impl Foo + 'a { - //~^ needless_lifetimes - Baz { bar: self } - } - } -} - mod nested_elision_sites { // issue #issue2944 @@ -646,89 +534,4 @@ mod issue13749bis { impl<'a, T: 'a> Generic {} } -mod issue13923 { - struct Py<'py> { - data: &'py str, - } - - enum Content<'t, 'py> { - Py(Py<'py>), - T1(&'t str), - T2(&'t str), - } - - enum ContentString<'t> { - T1(&'t str), - T2(&'t str), - } - - impl<'t, 'py> ContentString<'t> { - // `'py` cannot be elided - fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { - match self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(content) => Content::T2(f(content)), - } - } - } - - impl<'t, 'py> ContentString<'t> { - //~^ needless_lifetimes - // `'py` can be elided because of `&self` - fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { - match self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(content) => Content::T2(f(content)), - } - } - } - - impl<'t, 'py> ContentString<'t> { - //~^ needless_lifetimes - // `'py` can be elided because of `&'_ self` - fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { - match self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(content) => Content::T2(f(content)), - } - } - } - - impl<'t, 'py> ContentString<'t> { - // `'py` should not be elided as the default lifetime, even if working, could be named as `'t` - fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> { - match self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(_) => Content::T2(o), - } - } - } - - impl<'t, 'py> ContentString<'t> { - //~^ needless_lifetimes - // `'py` can be elided because of `&Self` - fn map_content5( - self: std::pin::Pin<&Self>, - f: impl FnOnce(&'t str) -> &'t str, - o: &'t str, - ) -> Content<'t, 'py> { - match *self { - Self::T1(content) => Content::T1(f(content)), - Self::T2(_) => Content::T2(o), - } - } - } - - struct Cx<'a, 'b> { - a: &'a u32, - b: &'b u32, - } - - // `'c` cannot be elided because we have several input lifetimes - fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 { - &x.b - //~^ needless_borrow - } -} - fn main() {} diff --git a/tests/ui/needless_lifetimes.stderr b/tests/ui/needless_lifetimes.stderr index b1d1c88a2968..138d0498c43e 100644 --- a/tests/ui/needless_lifetimes.stderr +++ b/tests/ui/needless_lifetimes.stderr @@ -108,32 +108,8 @@ LL - fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> LL + fn where_clause_without_lt(x: &u8, _y: u8) -> Result<&u8, ()> | -error: the following explicit lifetimes could be elided: 'a, 'b - --> tests/ui/needless_lifetimes.rs:109:21 - | -LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} - | ^^ ^^ ^^ ^^ - | -help: elide the lifetimes - | -LL - fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} -LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {} - | - -error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:134:15 - | -LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> - | ^^ ^^ ^^ - | -help: elide the lifetimes - | -LL - fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> -LL + fn fn_bound_2(_m: Lt<'_, I>, _f: F) -> Lt<'_, I> - | - error: the following explicit lifetimes could be elided: 's - --> tests/ui/needless_lifetimes.rs:165:21 + --> tests/ui/needless_lifetimes.rs:127:21 | LL | fn self_and_out<'s>(&'s self) -> &'s u8 { | ^^ ^^ ^^ @@ -145,7 +121,7 @@ LL + fn self_and_out(&self) -> &u8 { | error: the following explicit lifetimes could be elided: 't - --> tests/ui/needless_lifetimes.rs:173:30 + --> tests/ui/needless_lifetimes.rs:135:30 | LL | fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 { | ^^ ^^ @@ -157,7 +133,7 @@ LL + fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 { | error: the following explicit lifetimes could be elided: 's - --> tests/ui/needless_lifetimes.rs:181:26 + --> tests/ui/needless_lifetimes.rs:143:26 | LL | fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 { | ^^ ^^ @@ -169,7 +145,7 @@ LL + fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 { | error: the following explicit lifetimes could be elided: 's, 't - --> tests/ui/needless_lifetimes.rs:186:29 + --> tests/ui/needless_lifetimes.rs:148:29 | LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {} | ^^ ^^ ^^ ^^ @@ -181,31 +157,7 @@ LL + fn distinct_self_and_in(&self, _x: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:206:19 - | -LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { - | ^^ ^^ ^^ - | -help: elide the lifetimes - | -LL - fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { -LL + fn struct_with_lt(_foo: Foo<'_>) -> &str { - | - -error: the following explicit lifetimes could be elided: 'b - --> tests/ui/needless_lifetimes.rs:225:25 - | -LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { - | ^^ ^^ - | -help: elide the lifetimes - | -LL - fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { -LL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { - | - -error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:234:21 + --> tests/ui/needless_lifetimes.rs:172:21 | LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str { | ^^ ^^ @@ -217,7 +169,7 @@ LL + fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:250:22 + --> tests/ui/needless_lifetimes.rs:188:22 | LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str { | ^^ ^^ ^^ @@ -229,31 +181,7 @@ LL + fn trait_obj_elided2(_arg: &dyn Drop) -> &str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:257:18 - | -LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { - | ^^ ^^ ^^ - | -help: elide the lifetimes - | -LL - fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { -LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str { - | - -error: the following explicit lifetimes could be elided: 'b - --> tests/ui/needless_lifetimes.rs:276:24 - | -LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { - | ^^ ^^ - | -help: elide the lifetimes - | -LL - fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { -LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { - | - -error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:285:20 + --> tests/ui/needless_lifetimes.rs:199:20 | LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str { | ^^ ^^ @@ -265,7 +193,7 @@ LL + fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:290:30 + --> tests/ui/needless_lifetimes.rs:204:30 | LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str { | ^^ ^^ ^ @@ -277,7 +205,7 @@ LL + fn named_input_elided_output(_arg: &str) -> &str { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:299:19 + --> tests/ui/needless_lifetimes.rs:213:19 | LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { | ^^ ^^ @@ -289,19 +217,7 @@ LL + fn trait_bound_ok>(_: &u8, _: T) { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:336:24 - | -LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { - | ^^ ^^ ^^ - | -help: elide the lifetimes - | -LL - fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { -LL + fn out_return_type_lts(e: &str) -> Cow<'_> { - | - -error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:344:24 + --> tests/ui/needless_lifetimes.rs:249:24 | LL | fn needless_lt<'a>(x: &'a u8) {} | ^^ ^^ @@ -313,7 +229,7 @@ LL + fn needless_lt(x: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:349:24 + --> tests/ui/needless_lifetimes.rs:254:24 | LL | fn needless_lt<'a>(_x: &'a u8) {} | ^^ ^^ @@ -325,31 +241,7 @@ LL + fn needless_lt(_x: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:361:10 - | -LL | impl<'a> Foo for Baz<'a> {} - | ^^ ^^ - | -help: elide the lifetimes - | -LL - impl<'a> Foo for Baz<'a> {} -LL + impl Foo for Baz<'_> {} - | - -error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:364:16 - | -LL | fn baz<'a>(&'a self) -> impl Foo + 'a { - | ^^ ^^ ^^ - | -help: elide the lifetimes - | -LL - fn baz<'a>(&'a self) -> impl Foo + 'a { -LL + fn baz(&self) -> impl Foo + '_ { - | - -error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:397:55 + --> tests/ui/needless_lifetimes.rs:285:55 | LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 { | ^^ ^^ ^^ @@ -361,7 +253,7 @@ LL + fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(& | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:407:26 + --> tests/ui/needless_lifetimes.rs:295:26 | LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 { | ^^ ^^ ^^ @@ -373,7 +265,7 @@ LL + fn generics_elidable &i32>(i: &i32, f: T) -> &i32 { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:420:30 + --> tests/ui/needless_lifetimes.rs:308:30 | LL | fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32 | ^^ ^^ ^^ @@ -385,7 +277,7 @@ LL + fn where_clause_elidable(i: &i32, f: T) -> &i32 | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:436:28 + --> tests/ui/needless_lifetimes.rs:324:28 | LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 { | ^^ ^^ ^^ @@ -397,7 +289,7 @@ LL + fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:450:28 + --> tests/ui/needless_lifetimes.rs:338:28 | LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 { | ^^ ^^ @@ -409,7 +301,7 @@ LL + fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:454:28 + --> tests/ui/needless_lifetimes.rs:342:28 | LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) { | ^^ ^^ @@ -421,7 +313,7 @@ LL + fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:477:21 + --> tests/ui/needless_lifetimes.rs:365:21 | LL | fn implicit<'a>(&'a self) -> &'a () { | ^^ ^^ ^^ @@ -433,7 +325,7 @@ LL + fn implicit(&self) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:481:25 + --> tests/ui/needless_lifetimes.rs:369:25 | LL | fn implicit_mut<'a>(&'a mut self) -> &'a () { | ^^ ^^ ^^ @@ -445,7 +337,7 @@ LL + fn implicit_mut(&mut self) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:486:21 + --> tests/ui/needless_lifetimes.rs:374:21 | LL | fn explicit<'a>(self: &'a Arc) -> &'a () { | ^^ ^^ ^^ @@ -457,7 +349,7 @@ LL + fn explicit(self: &Arc) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:491:25 + --> tests/ui/needless_lifetimes.rs:379:25 | LL | fn explicit_mut<'a>(self: &'a mut Rc) -> &'a () { | ^^ ^^ ^^ @@ -469,7 +361,7 @@ LL + fn explicit_mut(self: &mut Rc) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:504:31 + --> tests/ui/needless_lifetimes.rs:392:31 | LL | fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a () { | ^^ ^^ ^^ @@ -481,7 +373,7 @@ LL + fn lifetime_elsewhere(self: Box, here: &()) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:511:21 + --> tests/ui/needless_lifetimes.rs:399:21 | LL | fn implicit<'a>(&'a self) -> &'a (); | ^^ ^^ ^^ @@ -493,7 +385,7 @@ LL + fn implicit(&self) -> &(); | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:513:30 + --> tests/ui/needless_lifetimes.rs:401:30 | LL | fn implicit_provided<'a>(&'a self) -> &'a () { | ^^ ^^ ^^ @@ -505,7 +397,7 @@ LL + fn implicit_provided(&self) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:519:21 + --> tests/ui/needless_lifetimes.rs:407:21 | LL | fn explicit<'a>(self: &'a Arc) -> &'a (); | ^^ ^^ ^^ @@ -517,7 +409,7 @@ LL + fn explicit(self: &Arc) -> &(); | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:522:30 + --> tests/ui/needless_lifetimes.rs:410:30 | LL | fn explicit_provided<'a>(self: &'a Arc) -> &'a () { | ^^ ^^ ^^ @@ -529,7 +421,7 @@ LL + fn explicit_provided(self: &Arc) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:533:31 + --> tests/ui/needless_lifetimes.rs:421:31 | LL | fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a (); | ^^ ^^ ^^ @@ -541,7 +433,7 @@ LL + fn lifetime_elsewhere(self: Box, here: &()) -> &(); | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:535:40 + --> tests/ui/needless_lifetimes.rs:423:40 | LL | fn lifetime_elsewhere_provided<'a>(self: Box, here: &'a ()) -> &'a () { | ^^ ^^ ^^ @@ -553,7 +445,7 @@ LL + fn lifetime_elsewhere_provided(self: Box, here: &()) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:545:12 + --> tests/ui/needless_lifetimes.rs:433:12 | LL | fn foo<'a>(x: &'a u8, y: &'_ u8) {} | ^^ ^^ @@ -565,7 +457,7 @@ LL + fn foo(x: &u8, y: &'_ u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:548:12 + --> tests/ui/needless_lifetimes.rs:436:12 | LL | fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {} | ^^ ^^ @@ -577,7 +469,7 @@ LL + fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {} | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:556:18 + --> tests/ui/needless_lifetimes.rs:444:18 | LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { | ^^ ^^ ^^ @@ -589,7 +481,7 @@ LL + fn one_input(x: &u8) -> &u8 { | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:562:42 + --> tests/ui/needless_lifetimes.rs:450:42 | LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 { | ^^ ^^ @@ -601,7 +493,7 @@ LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) | error: the following explicit lifetimes could be elided: 'a - --> tests/ui/needless_lifetimes.rs:579:22 + --> tests/ui/needless_lifetimes.rs:467:22 | LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { | ^^ ^^ ^^ @@ -613,66 +505,5 @@ LL - fn one_input<'a>(x: &'a u8) -> &'a u8 { LL + fn one_input(x: &u8) -> &u8 { | -error: the following explicit lifetimes could be elided: 'py - --> tests/ui/needless_lifetimes.rs:675:14 - | -LL | impl<'t, 'py> ContentString<'t> { - | ^^^ -... -LL | fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { - | ^^^ - | -help: elide the lifetimes - | -LL ~ impl<'t> ContentString<'t> { -LL | -LL | // `'py` can be elided because of `&self` -LL ~ fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { - | - -error: the following explicit lifetimes could be elided: 'py - --> tests/ui/needless_lifetimes.rs:686:14 - | -LL | impl<'t, 'py> ContentString<'t> { - | ^^^ -... -LL | fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> { - | ^^^ - | -help: elide the lifetimes - | -LL ~ impl<'t> ContentString<'t> { -LL | -LL | // `'py` can be elided because of `&'_ self` -LL ~ fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> { - | - -error: the following explicit lifetimes could be elided: 'py - --> tests/ui/needless_lifetimes.rs:707:14 - | -LL | impl<'t, 'py> ContentString<'t> { - | ^^^ -... -LL | ) -> Content<'t, 'py> { - | ^^^ - | -help: elide the lifetimes - | -LL ~ impl<'t> ContentString<'t> { -LL | -... -LL | o: &'t str, -LL ~ ) -> Content<'t, '_> { - | - -error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_lifetimes.rs:729:9 - | -LL | &x.b - | ^^^^ help: change this to: `x.b` - | - = note: `-D clippy::needless-borrow` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]` - -error: aborting due to 55 previous errors +error: aborting due to 42 previous errors From d6bb98e7579b3d8711cc00dc95a9425395bae9df Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 12 Feb 2025 05:41:02 +0000 Subject: [PATCH 272/991] span: add a "future" edition It's hard to implement edition migrations without having a perma-unstable "future" edition to target. --- .../src/standard_library_imports.rs | 1 + compiler/rustc_span/src/edition.rs | 29 +++++++++++++++++-- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/prelude/mod.rs | 23 +++++++++++++++ library/std/src/prelude/mod.rs | 15 ++++++++++ 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index 6933ca09349a..ba63b185e096 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -60,6 +60,7 @@ pub fn inject( Edition2018 => sym::rust_2018, Edition2021 => sym::rust_2021, Edition2024 => sym::rust_2024, + EditionFuture => sym::rust_future, }]) .map(|&symbol| Ident::new(symbol, span)) .collect(); diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index 36f9b4cff60b..da298080ed2f 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -23,11 +23,27 @@ pub enum Edition { Edition2021, /// The 2024 edition Edition2024, + /// The future edition - this variant will always exist and features associated with this + /// edition can be moved to the next 20XX edition when it is established and it is confirmed + /// that those features will be part of that edition. + /// + /// This variant allows edition changes to be implemented before being assigned to a concrete + /// edition - primarily when there are two different unstable behaviours that need tested across + /// an edition boundary. + /// + /// This edition will be permanently unstable and any features associated with this edition + /// must also be behind a feature gate. + EditionFuture, } // Must be in order from oldest to newest. -pub const ALL_EDITIONS: &[Edition] = - &[Edition::Edition2015, Edition::Edition2018, Edition::Edition2021, Edition::Edition2024]; +pub const ALL_EDITIONS: &[Edition] = &[ + Edition::Edition2015, + Edition::Edition2018, + Edition::Edition2021, + Edition::Edition2024, + Edition::EditionFuture, +]; pub const EDITION_NAME_LIST: &str = "2015|2018|2021|2024"; @@ -42,6 +58,7 @@ impl fmt::Display for Edition { Edition::Edition2018 => "2018", Edition::Edition2021 => "2021", Edition::Edition2024 => "2024", + Edition::EditionFuture => "future", }; write!(f, "{s}") } @@ -54,6 +71,7 @@ impl Edition { Edition::Edition2018 => "rust_2018_compatibility", Edition::Edition2021 => "rust_2021_compatibility", Edition::Edition2024 => "rust_2024_compatibility", + Edition::EditionFuture => "edition_future_compatibility", } } @@ -63,6 +81,7 @@ impl Edition { Edition::Edition2018 => true, Edition::Edition2021 => true, Edition::Edition2024 => true, + Edition::EditionFuture => false, } } @@ -85,6 +104,11 @@ impl Edition { pub fn at_least_rust_2024(self) -> bool { self >= Edition::Edition2024 } + + /// Are we allowed to use features from the future edition? + pub fn at_least_edition_future(self) -> bool { + self >= Edition::EditionFuture + } } impl FromStr for Edition { @@ -95,6 +119,7 @@ impl FromStr for Edition { "2018" => Ok(Edition::Edition2018), "2021" => Ok(Edition::Edition2021), "2024" => Ok(Edition::Edition2024), + "future" => Ok(Edition::EditionFuture), _ => Err(()), } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 172c2faca963..1823a7de5180 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1711,6 +1711,7 @@ symbols! { rust_cold_cc, rust_eh_catch_typeinfo, rust_eh_personality, + rust_future, rust_logo, rust_out, rustc, diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs index 590ffd64b5bf..8d867a269a21 100644 --- a/library/core/src/prelude/mod.rs +++ b/library/core/src/prelude/mod.rs @@ -70,3 +70,26 @@ pub mod rust_2024 { #[doc(no_inline)] pub use crate::future::{Future, IntoFuture}; } + +/// The Future version of the core prelude. +/// +/// See the [module-level documentation](self) for more. +#[doc(hidden)] +#[unstable(feature = "prelude_future", issue = "none")] +pub mod rust_future { + #[stable(feature = "rust1", since = "1.0.0")] + #[doc(no_inline)] + pub use super::v1::*; + + #[stable(feature = "prelude_2021", since = "1.55.0")] + #[doc(no_inline)] + pub use crate::iter::FromIterator; + + #[stable(feature = "prelude_2021", since = "1.55.0")] + #[doc(no_inline)] + pub use crate::convert::{TryFrom, TryInto}; + + #[stable(feature = "prelude_2024", since = "1.85.0")] + #[doc(no_inline)] + pub use crate::future::{Future, IntoFuture}; +} diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs index 992a9207a720..5f7097c26e22 100644 --- a/library/std/src/prelude/mod.rs +++ b/library/std/src/prelude/mod.rs @@ -160,3 +160,18 @@ pub mod rust_2024 { #[doc(no_inline)] pub use core::prelude::rust_2024::*; } + +/// The Future version of the prelude of The Rust Standard Library. +/// +/// See the [module-level documentation](self) for more. +#[doc(hidden)] +#[unstable(feature = "prelude_future", issue = "none")] +pub mod rust_future { + #[stable(feature = "rust1", since = "1.0.0")] + #[doc(no_inline)] + pub use super::v1::*; + + #[unstable(feature = "prelude_next", issue = "none")] + #[doc(no_inline)] + pub use core::prelude::rust_future::*; +} From db6da1268e874dad5d727a916edfd7ebb615129c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 24 Feb 2025 17:49:20 +0300 Subject: [PATCH 273/991] tests: Add regression test for derive token invalidation (#81099) --- .../ui/proc-macro/derive-cfg-nested-tokens.rs | 23 +++ .../derive-cfg-nested-tokens.stdout | 149 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 tests/ui/proc-macro/derive-cfg-nested-tokens.rs create mode 100644 tests/ui/proc-macro/derive-cfg-nested-tokens.stdout diff --git a/tests/ui/proc-macro/derive-cfg-nested-tokens.rs b/tests/ui/proc-macro/derive-cfg-nested-tokens.rs new file mode 100644 index 000000000000..7d4e8d8373d6 --- /dev/null +++ b/tests/ui/proc-macro/derive-cfg-nested-tokens.rs @@ -0,0 +1,23 @@ +// A regression test for issue #81099. + +//@ check-pass +//@ proc-macro:test-macros.rs + +#![feature(stmt_expr_attributes)] +#![feature(proc_macro_hygiene)] + +#[macro_use] +extern crate test_macros; + +#[derive(Clone, Copy)] +struct S { + // `print_args` runs twice + // - on eagerly configured `S` (from `impl Copy`), only 11 should be printed + // - on non-configured `S` (from `struct S`), both 10 and 11 should be printed + field: [u8; #[print_attr] { + #[cfg(FALSE)] { 10 } + #[cfg(not(FALSE))] { 11 } + }], +} + +fn main() {} diff --git a/tests/ui/proc-macro/derive-cfg-nested-tokens.stdout b/tests/ui/proc-macro/derive-cfg-nested-tokens.stdout new file mode 100644 index 000000000000..05bf21ee8f9b --- /dev/null +++ b/tests/ui/proc-macro/derive-cfg-nested-tokens.stdout @@ -0,0 +1,149 @@ +PRINT-ATTR INPUT (DISPLAY): { #[cfg(not(FALSE))] { 11 } } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Group { + delimiter: Brace, + stream: TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: #0 bytes(491..492), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "cfg", + span: #0 bytes(493..496), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "not", + span: #0 bytes(497..500), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "FALSE", + span: #0 bytes(501..506), + }, + ], + span: #0 bytes(500..507), + }, + ], + span: #0 bytes(496..508), + }, + ], + span: #0 bytes(492..509), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Literal { + kind: Integer, + symbol: "11", + suffix: None, + span: #0 bytes(513..515), + }, + ], + span: #0 bytes(511..517), + }, + ], + span: #0 bytes(452..523), + }, +] +PRINT-ATTR INPUT (DISPLAY): { #[cfg(FALSE)] { 10 } #[cfg(not(FALSE))] { 11 } } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Group { + delimiter: Brace, + stream: TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: #0 bytes(462..463), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "cfg", + span: #0 bytes(464..467), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "FALSE", + span: #0 bytes(468..473), + }, + ], + span: #0 bytes(467..474), + }, + ], + span: #0 bytes(463..475), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Literal { + kind: Integer, + symbol: "10", + suffix: None, + span: #0 bytes(478..480), + }, + ], + span: #0 bytes(476..482), + }, + Punct { + ch: '#', + spacing: Alone, + span: #0 bytes(491..492), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "cfg", + span: #0 bytes(493..496), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "not", + span: #0 bytes(497..500), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "FALSE", + span: #0 bytes(501..506), + }, + ], + span: #0 bytes(500..507), + }, + ], + span: #0 bytes(496..508), + }, + ], + span: #0 bytes(492..509), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Literal { + kind: Integer, + symbol: "11", + suffix: None, + span: #0 bytes(513..515), + }, + ], + span: #0 bytes(511..517), + }, + ], + span: #0 bytes(452..523), + }, +] From a54bfcf52b1b7ec105358c12987435cb88da4668 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 21 Feb 2025 17:23:49 +0000 Subject: [PATCH 274/991] Use safe FFI for various functions in codegen_llvm --- compiler/rustc_codegen_llvm/src/builder.rs | 8 ++------ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 677a9cd3e90e..2b84c01a2d8d 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -100,9 +100,7 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { } fn ret_void(&mut self) { - unsafe { - llvm::LLVMBuildRetVoid(self.llbuilder); - } + llvm::LLVMBuildRetVoid(self.llbuilder); } fn ret(&mut self, v: &'ll Value) { @@ -293,9 +291,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn ret_void(&mut self) { - unsafe { - llvm::LLVMBuildRetVoid(self.llbuilder); - } + llvm::LLVMBuildRetVoid(self.llbuilder); } fn ret(&mut self, v: &'ll Value) { diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index da91e6edbcfb..fa4adfd0b43e 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1204,7 +1204,7 @@ unsafe extern "C" { pub(crate) fn LLVMGetCurrentDebugLocation2<'a>(Builder: &Builder<'a>) -> Option<&'a Metadata>; // Terminators - pub(crate) fn LLVMBuildRetVoid<'a>(B: &Builder<'a>) -> &'a Value; + pub(crate) safe fn LLVMBuildRetVoid<'a>(B: &Builder<'a>) -> &'a Value; pub(crate) fn LLVMBuildRet<'a>(B: &Builder<'a>, V: &'a Value) -> &'a Value; pub(crate) fn LLVMBuildBr<'a>(B: &Builder<'a>, Dest: &'a BasicBlock) -> &'a Value; pub(crate) fn LLVMBuildCondBr<'a>( From d4379d2afda292f0a2986fa32bd0b967d83c7e0a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 08:07:11 +0000 Subject: [PATCH 275/991] Remove an unnecessary lifetime --- compiler/rustc_codegen_gcc/src/common.rs | 4 ++-- compiler/rustc_codegen_gcc/src/consts.rs | 6 +++--- compiler/rustc_codegen_llvm/src/common.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mir/place.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/consts.rs | 4 ++-- compiler/rustc_codegen_ssa/src/traits/mod.rs | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 20a3482aaa27..0ee13498ccad 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -59,7 +59,7 @@ pub fn type_is_pointer(typ: Type<'_>) -> bool { typ.get_pointee().is_some() } -impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { +impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> { fn const_null(&self, typ: Type<'gcc>) -> RValue<'gcc> { if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) } } @@ -263,7 +263,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } } - fn const_data_from_alloc(&self, alloc: ConstAllocation<'tcx>) -> Self::Value { + fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value { const_alloc_to_gcc(self, alloc) } diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index fb0ca31c5433..c514b7a428bc 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -302,9 +302,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -pub fn const_alloc_to_gcc<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, - alloc: ConstAllocation<'tcx>, +pub fn const_alloc_to_gcc<'gcc>( + cx: &CodegenCx<'gcc, '_>, + alloc: ConstAllocation<'_>, ) -> RValue<'gcc> { let alloc = alloc.inner(); let mut llvals = Vec::with_capacity(alloc.provenance().ptrs().len() + 1); diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index f17d98fa242b..5f5a3570ebdd 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -118,7 +118,7 @@ impl<'ll> CodegenCx<'ll, '_> { } } -impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { +impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> { fn const_null(&self, t: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMConstNull(t) } } @@ -350,7 +350,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - fn const_data_from_alloc(&self, alloc: ConstAllocation<'tcx>) -> Self::Value { + fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value { const_alloc_to_llvm(self, alloc, /*static*/ false) } diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index edd09b9c3c5f..b1b4270234e3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -133,7 +133,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { Self::alloca(bx, ptr_layout) } - pub fn len>(&self, cx: &Cx) -> V { + pub fn len>(&self, cx: &Cx) -> V { if let FieldsShape::Array { count, .. } = self.layout.fields { if self.layout.is_unsized() { assert_eq!(count, 0); diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index 5cfb56ebacee..5db7e072ca53 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -3,7 +3,7 @@ use rustc_middle::mir::interpret::{ConstAllocation, Scalar}; use super::BackendTypes; -pub trait ConstCodegenMethods<'tcx>: BackendTypes { +pub trait ConstCodegenMethods: BackendTypes { // Constant constructors fn const_null(&self, t: Self::Type) -> Self::Value; /// Generate an uninitialized value (matching uninitialized memory in MIR). @@ -38,7 +38,7 @@ pub trait ConstCodegenMethods<'tcx>: BackendTypes { fn const_to_opt_uint(&self, v: Self::Value) -> Option; fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option; - fn const_data_from_alloc(&self, alloc: ConstAllocation<'tcx>) -> Self::Value; + fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value; fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value; diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs index 90fcfbe4da7a..239857a4298d 100644 --- a/compiler/rustc_codegen_ssa/src/traits/mod.rs +++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs @@ -55,7 +55,7 @@ pub trait CodegenObject = Copy + PartialEq + fmt::Debug; pub trait CodegenMethods<'tcx> = LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>> + FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>> + TypeCodegenMethods<'tcx> - + ConstCodegenMethods<'tcx> + + ConstCodegenMethods + StaticCodegenMethods + DebugInfoCodegenMethods<'tcx> + AsmCodegenMethods<'tcx> From bfd88cead0dd79717f123ad7e9a26ecad88653cb Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 08:15:31 +0000 Subject: [PATCH 276/991] Avoid some duplication between SimpleCx and CodegenCx --- compiler/rustc_codegen_llvm/src/builder.rs | 58 ++++------ .../src/builder/autodiff.rs | 2 +- compiler/rustc_codegen_llvm/src/context.rs | 100 ++++++++++-------- compiler/rustc_codegen_llvm/src/type_.rs | 26 +++-- 4 files changed, 96 insertions(+), 90 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 2b84c01a2d8d..aaddde2e15a1 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -30,7 +30,7 @@ use tracing::{debug, instrument}; use crate::abi::FnAbiLlvmExt; use crate::common::Funclet; -use crate::context::{CodegenCx, SimpleCx}; +use crate::context::{CodegenCx, FullCx, GenericCx, SCx}; use crate::llvm::{ self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, GEPNoWrapFlags, Metadata, True, }; @@ -40,15 +40,15 @@ use crate::value::Value; use crate::{attributes, llvm_util}; #[must_use] -pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow>> { +pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow>> { pub llbuilder: &'ll mut llvm::Builder<'ll>, - pub cx: &'a CX, + pub cx: &'a GenericCx<'ll, CX>, } -pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SimpleCx<'ll>>; -pub(crate) type Builder<'a, 'll, 'tcx> = GenericBuilder<'a, 'll, CodegenCx<'ll, 'tcx>>; +pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SCx<'ll>>; +pub(crate) type Builder<'a, 'll, 'tcx> = GenericBuilder<'a, 'll, FullCx<'ll, 'tcx>>; -impl<'a, 'll, CX: Borrow>> Drop for GenericBuilder<'a, 'll, CX> { +impl<'a, 'll, CX: Borrow>> Drop for GenericBuilder<'a, 'll, CX> { fn drop(&mut self) { unsafe { llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _)); @@ -87,14 +87,15 @@ impl<'a, 'll> SBuilder<'a, 'll> { }; call } - - fn with_scx(scx: &'a SimpleCx<'ll>) -> Self { - // Create a fresh builder from the simple context. - let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(scx.llcx) }; - SBuilder { llbuilder, cx: scx } - } } -impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { + +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { + fn with_cx(scx: &'a GenericCx<'ll, CX>) -> Self { + // Create a fresh builder from the simple context. + let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(scx.deref().borrow().llcx) }; + GenericBuilder { llbuilder, cx: scx } + } + pub(crate) fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) } } @@ -108,16 +109,17 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { llvm::LLVMBuildRet(self.llbuilder, v); } } -} -impl<'a, 'll> SBuilder<'a, 'll> { - fn build(cx: &'a SimpleCx<'ll>, llbb: &'ll BasicBlock) -> SBuilder<'a, 'll> { - let bx = SBuilder::with_scx(cx); + + fn build(cx: &'a GenericCx<'ll, CX>, llbb: &'ll BasicBlock) -> Self { + let bx = Self::with_cx(cx); unsafe { llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb); } bx } +} +impl<'a, 'll> SBuilder<'a, 'll> { fn check_call<'b>( &mut self, typ: &str, @@ -1472,26 +1474,12 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> { } impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { - fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Builder<'a, 'll, 'tcx> { - let bx = Builder::with_cx(cx); - unsafe { - llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb); - } - bx - } - - fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self { - // Create a fresh builder from the crate context. - let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) }; - Builder { llbuilder, cx } - } - pub(crate) fn llfn(&self) -> &'ll Value { unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) } } } -impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { fn position_at_start(&mut self, llbb: &'ll BasicBlock) { unsafe { llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb); @@ -1521,7 +1509,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { } } } -impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) } } @@ -1666,7 +1654,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { Cow::Owned(casted_args) } } -impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) } } @@ -1690,7 +1678,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { self.call_intrinsic(intrinsic, &[self.cx.const_u64(size), ptr]); } } -impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { pub(crate) fn phi( &mut self, ty: &'ll Type, diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index 2c7899975e3e..78a9b168e87c 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -286,7 +286,7 @@ pub(crate) fn differentiate<'ll>( } let diag_handler = cgcx.create_dcx(); - let cx = SimpleCx { llmod: module.module_llvm.llmod(), llcx: module.module_llvm.llcx }; + let cx = SimpleCx::new(module.module_llvm.llmod(), module.module_llvm.llcx); // First of all, did the user try to use autodiff without using the -Zautodiff=Enable flag? if !diff_items.is_empty() diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index e7952bc95e7f..8dce03328576 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -1,6 +1,7 @@ use std::borrow::Borrow; use std::cell::{Cell, RefCell}; use std::ffi::{CStr, c_char, c_uint}; +use std::marker::PhantomData; use std::ops::Deref; use std::str; @@ -43,18 +44,18 @@ use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util}; /// However, there are various cx related functions which we want to be available to the builder and /// other compiler pieces. Here we define a small subset which has enough information and can be /// moved around more freely. -pub(crate) struct SimpleCx<'ll> { +pub(crate) struct SCx<'ll> { pub llmod: &'ll llvm::Module, pub llcx: &'ll llvm::Context, } -impl<'ll> Borrow> for CodegenCx<'ll, '_> { - fn borrow(&self) -> &SimpleCx<'ll> { +impl<'ll> Borrow> for FullCx<'ll, '_> { + fn borrow(&self) -> &SCx<'ll> { &self.scx } } -impl<'ll, 'tcx> Deref for CodegenCx<'ll, 'tcx> { +impl<'ll, 'tcx> Deref for FullCx<'ll, 'tcx> { type Target = SimpleCx<'ll>; #[inline] @@ -63,10 +64,25 @@ impl<'ll, 'tcx> Deref for CodegenCx<'ll, 'tcx> { } } +pub(crate) struct GenericCx<'ll, T: Borrow>>(T, PhantomData>); + +impl<'ll, T: Borrow>> Deref for GenericCx<'ll, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +pub(crate) type SimpleCx<'ll> = GenericCx<'ll, SCx<'ll>>; + /// There is one `CodegenCx` per codegen unit. Each one has its own LLVM /// `llvm::Context` so that several codegen units may be processed in parallel. /// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`. -pub(crate) struct CodegenCx<'ll, 'tcx> { +pub(crate) type CodegenCx<'ll, 'tcx> = GenericCx<'ll, FullCx<'ll, 'tcx>>; + +pub(crate) struct FullCx<'ll, 'tcx> { pub tcx: TyCtxt<'tcx>, pub scx: SimpleCx<'ll>, pub use_dll_storage_attrs: bool, @@ -581,31 +597,34 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { let isize_ty = Type::ix_llcx(llcx, tcx.data_layout.pointer_size.bits()); - CodegenCx { - tcx, - scx: SimpleCx { llcx, llmod }, - use_dll_storage_attrs, - tls_model, - codegen_unit, - instances: Default::default(), - vtables: Default::default(), - const_str_cache: Default::default(), - const_globals: Default::default(), - statics_to_rauw: RefCell::new(Vec::new()), - used_statics: RefCell::new(Vec::new()), - compiler_used_statics: RefCell::new(Vec::new()), - type_lowering: Default::default(), - scalar_lltypes: Default::default(), - isize_ty, - coverage_cx, - dbg_cx, - eh_personality: Cell::new(None), - eh_catch_typeinfo: Cell::new(None), - rust_try_fn: Cell::new(None), - intrinsics: Default::default(), - local_gen_sym_counter: Cell::new(0), - renamed_statics: Default::default(), - } + GenericCx( + FullCx { + tcx, + scx: SimpleCx::new(llmod, llcx), + use_dll_storage_attrs, + tls_model, + codegen_unit, + instances: Default::default(), + vtables: Default::default(), + const_str_cache: Default::default(), + const_globals: Default::default(), + statics_to_rauw: RefCell::new(Vec::new()), + used_statics: RefCell::new(Vec::new()), + compiler_used_statics: RefCell::new(Vec::new()), + type_lowering: Default::default(), + scalar_lltypes: Default::default(), + isize_ty, + coverage_cx, + dbg_cx, + eh_personality: Cell::new(None), + eh_catch_typeinfo: Cell::new(None), + rust_try_fn: Cell::new(None), + intrinsics: Default::default(), + local_gen_sym_counter: Cell::new(0), + renamed_statics: Default::default(), + }, + PhantomData, + ) } pub(crate) fn statics_to_rauw(&self) -> &RefCell> { @@ -628,7 +647,12 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { llvm::set_section(g, c"llvm.metadata"); } } + impl<'ll> SimpleCx<'ll> { + pub(crate) fn new(llmod: &'ll llvm::Module, llcx: &'ll llvm::Context) -> Self { + Self(SCx { llmod, llcx }, PhantomData) + } + pub(crate) fn val_ty(&self, v: &'ll Value) -> &'ll Type { common::val_ty(v) } @@ -1203,25 +1227,13 @@ impl CodegenCx<'_, '_> { name.push_str(&(idx as u64).to_base(ALPHANUMERIC_ONLY)); name } - - /// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`. - pub(crate) fn set_metadata<'a>(&self, val: &'a Value, kind_id: MetadataType, md: &'a Metadata) { - unsafe { - let node = llvm::LLVMMetadataAsValue(&self.llcx, md); - llvm::LLVMSetMetadata(val, kind_id as c_uint, node); - } - } } -// This is a duplication of the set_metadata function above. However, so far it's the only one -// shared between both contexts, so it doesn't seem worth it to make the Cx generic like we did it -// for the Builder. -impl SimpleCx<'_> { - #[allow(unused)] +impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { /// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`. pub(crate) fn set_metadata<'a>(&self, val: &'a Value, kind_id: MetadataType, md: &'a Metadata) { unsafe { - let node = llvm::LLVMMetadataAsValue(&self.llcx, md); + let node = llvm::LLVMMetadataAsValue(self.llcx(), md); llvm::LLVMSetMetadata(val, kind_id as c_uint, node); } } diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index d61ce4175627..4cd30973a73c 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -1,3 +1,4 @@ +use std::borrow::Borrow; use std::{fmt, ptr}; use libc::{c_char, c_uint}; @@ -11,7 +12,7 @@ use rustc_middle::ty::{self, Ty}; use rustc_target::callconv::{CastTarget, FnAbi}; use crate::abi::{FnAbiLlvmExt, LlvmType}; -use crate::context::{CodegenCx, SimpleCx}; +use crate::context::{CodegenCx, GenericCx, SCx}; pub(crate) use crate::llvm::Type; use crate::llvm::{Bool, False, Metadata, True}; use crate::type_of::LayoutLlvmExt; @@ -36,29 +37,29 @@ impl fmt::Debug for Type { } impl<'ll> CodegenCx<'ll, '_> {} -impl<'ll> SimpleCx<'ll> { +impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { pub(crate) fn type_named_struct(&self, name: &str) -> &'ll Type { let name = SmallCStr::new(name); - unsafe { llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) } + unsafe { llvm::LLVMStructCreateNamed(self.llcx(), name.as_ptr()) } } pub(crate) fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) { unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) } } pub(crate) fn type_void(&self) -> &'ll Type { - unsafe { llvm::LLVMVoidTypeInContext(self.llcx) } + unsafe { llvm::LLVMVoidTypeInContext(self.llcx()) } } pub(crate) fn type_token(&self) -> &'ll Type { - unsafe { llvm::LLVMTokenTypeInContext(self.llcx) } + unsafe { llvm::LLVMTokenTypeInContext(self.llcx()) } } pub(crate) fn type_metadata(&self) -> &'ll Type { - unsafe { llvm::LLVMMetadataTypeInContext(self.llcx) } + unsafe { llvm::LLVMMetadataTypeInContext(self.llcx()) } } ///x Creates an integer type with the given number of bits, e.g., i24 pub(crate) fn type_ix(&self, num_bits: u64) -> &'ll Type { - unsafe { llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint) } + unsafe { llvm::LLVMIntTypeInContext(self.llcx(), num_bits as c_uint) } } pub(crate) fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type { @@ -121,19 +122,24 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { self.type_array(self.type_from_integer(unit), size / unit_size) } } -impl<'ll> SimpleCx<'ll> { + +impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { + pub(crate) fn llcx(&self) -> &'ll llvm::Context { + (**self).borrow().llcx + } + pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) } } pub(crate) fn type_i1(&self) -> &'ll Type { - unsafe { llvm::LLVMInt1TypeInContext(self.llcx) } + unsafe { llvm::LLVMInt1TypeInContext(self.llcx()) } } pub(crate) fn type_struct(&self, els: &[&'ll Type], packed: bool) -> &'ll Type { unsafe { llvm::LLVMStructTypeInContext( - self.llcx, + self.llcx(), els.as_ptr(), els.len() as c_uint, packed as Bool, From 75356b74370d21045099cb2a1ad81dc7a3c2579f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 11:06:25 +0000 Subject: [PATCH 277/991] Generalize `BackendTypes` over `GenericCx` --- compiler/rustc_codegen_llvm/src/builder.rs | 20 ++++++++++---------- compiler/rustc_codegen_llvm/src/common.rs | 5 ++++- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index aaddde2e15a1..1f7372e5cc5c 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -167,17 +167,17 @@ impl<'a, 'll> SBuilder<'a, 'll> { // FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer. const UNNAMED: *const c_char = c"".as_ptr(); -impl<'ll, 'tcx> BackendTypes for Builder<'_, 'll, 'tcx> { - type Value = as BackendTypes>::Value; - type Metadata = as BackendTypes>::Metadata; - type Function = as BackendTypes>::Function; - type BasicBlock = as BackendTypes>::BasicBlock; - type Type = as BackendTypes>::Type; - type Funclet = as BackendTypes>::Funclet; +impl<'ll, CX: Borrow>> BackendTypes for GenericBuilder<'_, 'll, CX> { + type Value = as BackendTypes>::Value; + type Metadata = as BackendTypes>::Metadata; + type Function = as BackendTypes>::Function; + type BasicBlock = as BackendTypes>::BasicBlock; + type Type = as BackendTypes>::Type; + type Funclet = as BackendTypes>::Funclet; - type DIScope = as BackendTypes>::DIScope; - type DILocation = as BackendTypes>::DILocation; - type DIVariable = as BackendTypes>::DIVariable; + type DIScope = as BackendTypes>::DIScope; + type DILocation = as BackendTypes>::DILocation; + type DIVariable = as BackendTypes>::DIVariable; } impl abi::HasDataLayout for Builder<'_, '_, '_> { diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 5f5a3570ebdd..7af2815e64cc 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -1,5 +1,7 @@ //! Code that is useful in various codegen modules. +use std::borrow::Borrow; + use libc::{c_char, c_uint}; use rustc_abi as abi; use rustc_abi::Primitive::Pointer; @@ -18,6 +20,7 @@ use tracing::debug; use crate::consts::const_alloc_to_llvm; pub(crate) use crate::context::CodegenCx; +use crate::context::{GenericCx, SCx}; use crate::llvm::{self, BasicBlock, Bool, ConstantInt, False, Metadata, True}; use crate::type_::Type; use crate::value::Value; @@ -81,7 +84,7 @@ impl<'ll> Funclet<'ll> { } } -impl<'ll> BackendTypes for CodegenCx<'ll, '_> { +impl<'ll, CX: Borrow>> BackendTypes for GenericCx<'ll, CX> { type Value = &'ll Value; type Metadata = &'ll Metadata; // FIXME(eddyb) replace this with a `Function` "subclass" of `Value`. From 840e31b29f93a5e0569d05c8879468877a9991d4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 11:31:43 +0000 Subject: [PATCH 278/991] Generalize BaseTypeCodegenMethods --- compiler/rustc_codegen_gcc/src/type_.rs | 2 +- .../src/builder/autodiff.rs | 3 +- compiler/rustc_codegen_llvm/src/context.rs | 19 +++++++------ compiler/rustc_codegen_llvm/src/type_.rs | 28 +++++++++++-------- compiler/rustc_codegen_ssa/src/back/write.rs | 3 ++ .../rustc_codegen_ssa/src/traits/type_.rs | 9 ++---- 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index cb08723431a9..4e0a250b5509 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/src/type_.rs @@ -123,7 +123,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -impl<'gcc, 'tcx> BaseTypeCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { +impl<'gcc, 'tcx> BaseTypeCodegenMethods for CodegenCx<'gcc, 'tcx> { fn type_i8(&self) -> Type<'gcc> { self.i8_type } diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index 78a9b168e87c..1e12d1a1cb3e 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -286,7 +286,8 @@ pub(crate) fn differentiate<'ll>( } let diag_handler = cgcx.create_dcx(); - let cx = SimpleCx::new(module.module_llvm.llmod(), module.module_llvm.llcx); + + let cx = SimpleCx::new(module.module_llvm.llmod(), module.module_llvm.llcx, cgcx.pointer_size); // First of all, did the user try to use autodiff without using the -Zautodiff=Enable flag? if !diff_items.is_empty() diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 8dce03328576..6a7c042e03af 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -5,7 +5,7 @@ use std::marker::PhantomData; use std::ops::Deref; use std::str; -use rustc_abi::{HasDataLayout, TargetDataLayout, VariantIdx}; +use rustc_abi::{HasDataLayout, Size, TargetDataLayout, VariantIdx}; use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::common::TypeKind; @@ -47,6 +47,7 @@ use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util}; pub(crate) struct SCx<'ll> { pub llmod: &'ll llvm::Module, pub llcx: &'ll llvm::Context, + pub isize_ty: &'ll Type, } impl<'ll> Borrow> for FullCx<'ll, '_> { @@ -120,8 +121,6 @@ pub(crate) struct FullCx<'ll, 'tcx> { /// Mapping of scalar types to llvm types. pub scalar_lltypes: RefCell, &'ll Type>>, - pub isize_ty: &'ll Type, - /// Extra per-CGU codegen state needed when coverage instrumentation is enabled. pub coverage_cx: Option>, pub dbg_cx: Option>, @@ -595,12 +594,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { None }; - let isize_ty = Type::ix_llcx(llcx, tcx.data_layout.pointer_size.bits()); - GenericCx( FullCx { tcx, - scx: SimpleCx::new(llmod, llcx), + scx: SimpleCx::new(llmod, llcx, tcx.data_layout.pointer_size), use_dll_storage_attrs, tls_model, codegen_unit, @@ -613,7 +610,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { compiler_used_statics: RefCell::new(Vec::new()), type_lowering: Default::default(), scalar_lltypes: Default::default(), - isize_ty, coverage_cx, dbg_cx, eh_personality: Cell::new(None), @@ -649,8 +645,13 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { } impl<'ll> SimpleCx<'ll> { - pub(crate) fn new(llmod: &'ll llvm::Module, llcx: &'ll llvm::Context) -> Self { - Self(SCx { llmod, llcx }, PhantomData) + pub(crate) fn new( + llmod: &'ll llvm::Module, + llcx: &'ll llvm::Context, + pointer_size: Size, + ) -> Self { + let isize_ty = llvm::Type::ix_llcx(llcx, pointer_size.bits()); + Self(SCx { llmod, llcx, isize_ty }, PhantomData) } pub(crate) fn val_ty(&self, v: &'ll Value) -> &'ll Type { diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 4cd30973a73c..b89ce90d1a1d 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -128,6 +128,10 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { (**self).borrow().llcx } + pub(crate) fn isize_ty(&self) -> &'ll Type { + (**self).borrow().isize_ty + } + pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) } } @@ -148,45 +152,45 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { } } -impl<'ll, 'tcx> BaseTypeCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { +impl<'ll, CX: Borrow>> BaseTypeCodegenMethods for GenericCx<'ll, CX> { fn type_i8(&self) -> &'ll Type { - unsafe { llvm::LLVMInt8TypeInContext(self.llcx) } + unsafe { llvm::LLVMInt8TypeInContext(self.llcx()) } } fn type_i16(&self) -> &'ll Type { - unsafe { llvm::LLVMInt16TypeInContext(self.llcx) } + unsafe { llvm::LLVMInt16TypeInContext(self.llcx()) } } fn type_i32(&self) -> &'ll Type { - unsafe { llvm::LLVMInt32TypeInContext(self.llcx) } + unsafe { llvm::LLVMInt32TypeInContext(self.llcx()) } } fn type_i64(&self) -> &'ll Type { - unsafe { llvm::LLVMInt64TypeInContext(self.llcx) } + unsafe { llvm::LLVMInt64TypeInContext(self.llcx()) } } fn type_i128(&self) -> &'ll Type { - unsafe { llvm::LLVMIntTypeInContext(self.llcx, 128) } + unsafe { llvm::LLVMIntTypeInContext(self.llcx(), 128) } } fn type_isize(&self) -> &'ll Type { - self.isize_ty + self.isize_ty() } fn type_f16(&self) -> &'ll Type { - unsafe { llvm::LLVMHalfTypeInContext(self.llcx) } + unsafe { llvm::LLVMHalfTypeInContext(self.llcx()) } } fn type_f32(&self) -> &'ll Type { - unsafe { llvm::LLVMFloatTypeInContext(self.llcx) } + unsafe { llvm::LLVMFloatTypeInContext(self.llcx()) } } fn type_f64(&self) -> &'ll Type { - unsafe { llvm::LLVMDoubleTypeInContext(self.llcx) } + unsafe { llvm::LLVMDoubleTypeInContext(self.llcx()) } } fn type_f128(&self) -> &'ll Type { - unsafe { llvm::LLVMFP128TypeInContext(self.llcx) } + unsafe { llvm::LLVMFP128TypeInContext(self.llcx()) } } fn type_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { @@ -202,7 +206,7 @@ impl<'ll, 'tcx> BaseTypeCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn type_ptr_ext(&self, address_space: AddressSpace) -> &'ll Type { - unsafe { llvm::LLVMPointerTypeInContext(self.llcx, address_space.0) } + unsafe { llvm::LLVMPointerTypeInContext(self.llcx(), address_space.0) } } fn element_type(&self, ty: &'ll Type) -> &'ll Type { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index f008bd12ed8f..f6f5f851d3c2 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender, channel}; use std::{fs, io, mem, str, thread}; +use rustc_abi::Size; use rustc_ast::attr; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; @@ -351,6 +352,7 @@ pub struct CodegenContext { pub target_is_like_aix: bool, pub split_debuginfo: rustc_target::spec::SplitDebuginfo, pub split_dwarf_kind: rustc_session::config::SplitDwarfKind, + pub pointer_size: Size, /// All commandline args used to invoke the compiler, with @file args fully expanded. /// This will only be used within debug info, e.g. in the pdb file on windows @@ -1212,6 +1214,7 @@ fn start_executing_work( split_debuginfo: tcx.sess.split_debuginfo(), split_dwarf_kind: tcx.sess.opts.unstable_opts.split_dwarf_kind, parallel: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend, + pointer_size: tcx.data_layout.pointer_size, }; // This is the "main loop" of parallel work happening for parallel codegen. diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index c178ebc596e1..7e32d956ee63 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -9,7 +9,7 @@ use super::misc::MiscCodegenMethods; use crate::common::TypeKind; use crate::mir::place::PlaceRef; -pub trait BaseTypeCodegenMethods<'tcx>: BackendTypes { +pub trait BaseTypeCodegenMethods: BackendTypes { fn type_i8(&self) -> Self::Type; fn type_i16(&self) -> Self::Type; fn type_i32(&self) -> Self::Type; @@ -41,7 +41,7 @@ pub trait BaseTypeCodegenMethods<'tcx>: BackendTypes { } pub trait DerivedTypeCodegenMethods<'tcx>: - BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + HasTypingEnv<'tcx> + BaseTypeCodegenMethods + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + HasTypingEnv<'tcx> { fn type_int(&self) -> Self::Type { match &self.sess().target.c_int_width[..] { @@ -100,10 +100,7 @@ pub trait DerivedTypeCodegenMethods<'tcx>: } impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where - Self: BaseTypeCodegenMethods<'tcx> - + MiscCodegenMethods<'tcx> - + HasTyCtxt<'tcx> - + HasTypingEnv<'tcx> + Self: BaseTypeCodegenMethods + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + HasTypingEnv<'tcx> { } From 396baa750e51a0e40fb0b803bfa6399a35e604a2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 11:14:21 +0000 Subject: [PATCH 279/991] Make allocator shim creation mostly use safe code --- compiler/rustc_codegen_llvm/src/allocator.rs | 150 +++++++++---------- compiler/rustc_codegen_llvm/src/builder.rs | 8 +- compiler/rustc_codegen_llvm/src/declare.rs | 17 ++- compiler/rustc_codegen_llvm/src/lib.rs | 7 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 +- 5 files changed, 91 insertions(+), 93 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 66723cbf8820..e614115f64b9 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -3,33 +3,31 @@ use rustc_ast::expand::allocator::{ ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, default_fn_name, global_fn_name, }; +use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::config::{DebugInfo, OomStrategy}; -use crate::common::AsCCharPtr; -use crate::llvm::{self, Context, False, Module, True, Type}; -use crate::{ModuleLlvm, attributes, debuginfo}; +use crate::builder::SBuilder; +use crate::declare::declare_simple_fn; +use crate::llvm::{self, False, True, Type}; +use crate::{SimpleCx, attributes, debuginfo}; pub(crate) unsafe fn codegen( tcx: TyCtxt<'_>, - module_llvm: &mut ModuleLlvm, + cx: SimpleCx<'_>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) { - let llcx = &*module_llvm.llcx; - let llmod = module_llvm.llmod(); - let usize = unsafe { - match tcx.sess.target.pointer_width { - 16 => llvm::LLVMInt16TypeInContext(llcx), - 32 => llvm::LLVMInt32TypeInContext(llcx), - 64 => llvm::LLVMInt64TypeInContext(llcx), - tws => bug!("Unsupported target word size for int: {}", tws), - } + let usize = match tcx.sess.target.pointer_width { + 16 => cx.type_i16(), + 32 => cx.type_i32(), + 64 => cx.type_i64(), + tws => bug!("Unsupported target word size for int: {}", tws), }; - let i8 = unsafe { llvm::LLVMInt8TypeInContext(llcx) }; - let i8p = unsafe { llvm::LLVMPointerTypeInContext(llcx, 0) }; + let i8 = cx.type_i8(); + let i8p = cx.type_ptr(); if kind == AllocatorKind::Default { for method in ALLOCATOR_METHODS { @@ -58,15 +56,14 @@ pub(crate) unsafe fn codegen( let from_name = global_fn_name(method.name); let to_name = default_fn_name(method.name); - create_wrapper_function(tcx, llcx, llmod, &from_name, &to_name, &args, output, false); + create_wrapper_function(tcx, &cx, &from_name, &to_name, &args, output, false); } } // rust alloc error handler create_wrapper_function( tcx, - llcx, - llmod, + &cx, "__rust_alloc_error_handler", alloc_error_handler_name(alloc_error_handler_kind), &[usize, usize], // size, align @@ -77,21 +74,21 @@ pub(crate) unsafe fn codegen( unsafe { // __rust_alloc_error_handler_should_panic let name = OomStrategy::SYMBOL; - let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_c_char_ptr(), name.len(), i8); + let ll_g = cx.declare_global(name, i8); llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility())); let val = tcx.sess.opts.unstable_opts.oom.should_panic(); let llval = llvm::LLVMConstInt(i8, val as u64, False); llvm::set_initializer(ll_g, llval); let name = NO_ALLOC_SHIM_IS_UNSTABLE; - let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_c_char_ptr(), name.len(), i8); + let ll_g = cx.declare_global(name, i8); llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility())); let llval = llvm::LLVMConstInt(i8, 0, False); llvm::set_initializer(ll_g, llval); } if tcx.sess.opts.debuginfo != DebugInfo::None { - let dbg_cx = debuginfo::CodegenUnitDebugContext::new(llmod); + let dbg_cx = debuginfo::CodegenUnitDebugContext::new(cx.llmod); debuginfo::metadata::build_compile_unit_di_node(tcx, module_name, &dbg_cx); dbg_cx.finalize(tcx.sess); } @@ -99,77 +96,64 @@ pub(crate) unsafe fn codegen( fn create_wrapper_function( tcx: TyCtxt<'_>, - llcx: &Context, - llmod: &Module, + cx: &SimpleCx<'_>, from_name: &str, to_name: &str, args: &[&Type], output: Option<&Type>, no_return: bool, ) { - unsafe { - let ty = llvm::LLVMFunctionType( - output.unwrap_or_else(|| llvm::LLVMVoidTypeInContext(llcx)), - args.as_ptr(), - args.len() as c_uint, - False, - ); - let llfn = llvm::LLVMRustGetOrInsertFunction( - llmod, - from_name.as_c_char_ptr(), - from_name.len(), - ty, - ); - let no_return = if no_return { - // -> ! DIFlagNoReturn - let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]); - Some(no_return) - } else { - None - }; + let ty = cx.type_func(args, output.unwrap_or_else(|| cx.type_void())); + let llfn = declare_simple_fn( + &cx, + from_name, + llvm::CallConv::CCallConv, + llvm::UnnamedAddr::Global, + llvm::Visibility::from_generic(tcx.sess.default_visibility()), + ty, + ); + let no_return = if no_return { + // -> ! DIFlagNoReturn + let no_return = llvm::AttributeKind::NoReturn.create_attr(cx.llcx); + attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]); + Some(no_return) + } else { + None + }; - llvm::set_visibility(llfn, llvm::Visibility::from_generic(tcx.sess.default_visibility())); + if tcx.sess.must_emit_unwind_tables() { + let uwtable = + attributes::uwtable_attr(cx.llcx, tcx.sess.opts.unstable_opts.use_sync_unwind); + attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]); + } - if tcx.sess.must_emit_unwind_tables() { - let uwtable = - attributes::uwtable_attr(llcx, tcx.sess.opts.unstable_opts.use_sync_unwind); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]); - } + let callee = declare_simple_fn( + &cx, + to_name, + llvm::CallConv::CCallConv, + llvm::UnnamedAddr::Global, + llvm::Visibility::Hidden, + ty, + ); + if let Some(no_return) = no_return { + // -> ! DIFlagNoReturn + attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]); + } + llvm::set_visibility(callee, llvm::Visibility::Hidden); - let callee = - llvm::LLVMRustGetOrInsertFunction(llmod, to_name.as_c_char_ptr(), to_name.len(), ty); - if let Some(no_return) = no_return { - // -> ! DIFlagNoReturn - attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]); - } - llvm::set_visibility(callee, llvm::Visibility::Hidden); + let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) }; - let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, c"entry".as_ptr()); - - let llbuilder = llvm::LLVMCreateBuilderInContext(llcx); - llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb); - let args = args - .iter() - .enumerate() - .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint)) - .collect::>(); - let ret = llvm::LLVMBuildCallWithOperandBundles( - llbuilder, - ty, - callee, - args.as_ptr(), - args.len() as c_uint, - [].as_ptr(), - 0 as c_uint, - c"".as_ptr(), - ); - llvm::LLVMSetTailCall(ret, True); - if output.is_some() { - llvm::LLVMBuildRet(llbuilder, ret); - } else { - llvm::LLVMBuildRetVoid(llbuilder); - } - llvm::LLVMDisposeBuilder(llbuilder); + let mut bx = SBuilder::build(&cx, llbb); + let args = args + .iter() + .enumerate() + .map(|(i, _)| llvm::get_param(llfn, i as c_uint)) + .collect::>(); + let ret = bx.call(ty, callee, &args, None); + llvm::LLVMSetTailCall(ret, True); + if output.is_some() { + bx.ret(ret); + } else { + bx.ret_void() } } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 1f7372e5cc5c..aab63324f426 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -57,7 +57,7 @@ impl<'a, 'll, CX: Borrow>> Drop for GenericBuilder<'a, 'll, CX> { } impl<'a, 'll> SBuilder<'a, 'll> { - fn call( + pub(crate) fn call( &mut self, llty: &'ll Type, llfn: &'ll Value, @@ -100,17 +100,17 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) } } - fn ret_void(&mut self) { + pub(crate) fn ret_void(&mut self) { llvm::LLVMBuildRetVoid(self.llbuilder); } - fn ret(&mut self, v: &'ll Value) { + pub(crate) fn ret(&mut self, v: &'ll Value) { unsafe { llvm::LLVMBuildRet(self.llbuilder, v); } } - fn build(cx: &'a GenericCx<'ll, CX>, llbb: &'ll BasicBlock) -> Self { + pub(crate) fn build(cx: &'a GenericCx<'ll, CX>, llbb: &'ll BasicBlock) -> Self { let bx = Self::with_cx(cx); unsafe { llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb); diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index e79662ebc647..2419ec1f8885 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -11,6 +11,8 @@ //! * Use define_* family of methods when you might be defining the Value. //! * When in doubt, define. +use std::borrow::Borrow; + use itertools::Itertools; use rustc_codegen_ssa::traits::TypeMembershipCodegenMethods; use rustc_data_structures::fx::FxIndexSet; @@ -22,7 +24,7 @@ use tracing::debug; use crate::abi::FnAbiLlvmExt; use crate::common::AsCCharPtr; -use crate::context::{CodegenCx, SimpleCx}; +use crate::context::{CodegenCx, GenericCx, SCx, SimpleCx}; use crate::llvm::AttributePlace::Function; use crate::llvm::Visibility; use crate::type_::Type; @@ -81,16 +83,25 @@ pub(crate) fn declare_raw_fn<'ll, 'tcx>( llfn } -impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { +impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { /// Declare a global value. /// /// If there’s a value with the same name already declared, the function will /// return its Value instead. pub(crate) fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value { debug!("declare_global(name={:?})", name); - unsafe { llvm::LLVMRustGetOrInsertGlobal(self.llmod, name.as_c_char_ptr(), name.len(), ty) } + unsafe { + llvm::LLVMRustGetOrInsertGlobal( + (**self).borrow().llmod, + name.as_c_char_ptr(), + name.len(), + ty, + ) + } } +} +impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// Declare a C ABI function. /// /// Only use this for foreign function ABIs and glue. For Rust functions use diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index e9e1b644f183..a15ec6000bca 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -29,6 +29,7 @@ use std::mem::ManuallyDrop; use back::owned_target_machine::OwnedTargetMachine; use back::write::{create_informational_target_machine, create_target_machine}; +use context::SimpleCx; use errors::{AutoDiffWithoutLTO, ParseTargetMachineConfig}; pub(crate) use llvm_util::target_features_cfg; use rustc_ast::expand::allocator::AllocatorKind; @@ -116,9 +117,11 @@ impl ExtraBackendMethods for LlvmCodegenBackend { kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) -> ModuleLlvm { - let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name); + let module_llvm = ModuleLlvm::new_metadata(tcx, module_name); + let cx = + SimpleCx::new(module_llvm.llmod(), &module_llvm.llcx, tcx.data_layout.pointer_size); unsafe { - allocator::codegen(tcx, &mut module_llvm, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, cx, module_name, kind, alloc_error_handler_kind); } module_llvm } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index fa4adfd0b43e..2738fee64cf9 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1147,7 +1147,7 @@ unsafe extern "C" { pub(crate) fn LLVMSetThreadLocalMode(GlobalVar: &Value, Mode: ThreadLocalMode); pub(crate) fn LLVMIsGlobalConstant(GlobalVar: &Value) -> Bool; pub(crate) fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool); - pub(crate) fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool); + pub(crate) safe fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool); // Operations on attributes pub(crate) fn LLVMCreateStringAttribute( From 29440b84a9f1eb216ce3c937bbd9cc126078a437 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 12:23:45 +0000 Subject: [PATCH 280/991] Remove an unused lifetime param --- compiler/rustc_codegen_gcc/src/abi.rs | 2 +- compiler/rustc_codegen_llvm/src/abi.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/abi.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/builder.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 717baebcd8cd..9fe6baa3d257 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -16,7 +16,7 @@ use crate::context::CodegenCx; use crate::intrinsic::ArgAbiExt; use crate::type_of::LayoutGccExt; -impl<'a, 'gcc, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { +impl AbiBuilderMethods for Builder<'_, '_, '_> { fn get_param(&mut self, index: usize) -> Self::Value { let func = self.current_func(); let param = func.get_param(index as i32); diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 8c75125e009b..710593381513 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -654,7 +654,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } } -impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { +impl AbiBuilderMethods for Builder<'_, '_, '_> { fn get_param(&mut self, index: usize) -> Self::Value { llvm::get_param(self.llfn(), index as c_uint) } diff --git a/compiler/rustc_codegen_ssa/src/traits/abi.rs b/compiler/rustc_codegen_ssa/src/traits/abi.rs index 60d8f2a9ece4..49c51caa996e 100644 --- a/compiler/rustc_codegen_ssa/src/traits/abi.rs +++ b/compiler/rustc_codegen_ssa/src/traits/abi.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -pub trait AbiBuilderMethods<'tcx>: BackendTypes { +pub trait AbiBuilderMethods: BackendTypes { fn get_param(&mut self, index: usize) -> Self::Value; } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 99fd6b6510ff..5f91133d5b47 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -40,7 +40,7 @@ pub trait BuilderMethods<'a, 'tcx>: + CoverageInfoBuilderMethods<'tcx> + DebugInfoBuilderMethods + ArgAbiBuilderMethods<'tcx> - + AbiBuilderMethods<'tcx> + + AbiBuilderMethods + IntrinsicCallBuilderMethods<'tcx> + AsmBuilderMethods<'tcx> + StaticBuilderMethods From 241c83f0c7877815b592a276bb13af57fbb8d7fc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 14:28:50 +0000 Subject: [PATCH 281/991] Deduplicate more functions between `SimpleCx` and `CodegenCx` --- compiler/rustc_codegen_llvm/src/builder.rs | 53 ++-------------------- compiler/rustc_codegen_llvm/src/context.rs | 5 -- 2 files changed, 4 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index aab63324f426..17579ebe72c4 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -119,49 +119,6 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { } } -impl<'a, 'll> SBuilder<'a, 'll> { - fn check_call<'b>( - &mut self, - typ: &str, - fn_ty: &'ll Type, - llfn: &'ll Value, - args: &'b [&'ll Value], - ) -> Cow<'b, [&'ll Value]> { - assert!( - self.cx.type_kind(fn_ty) == TypeKind::Function, - "builder::{typ} not passed a function, but {fn_ty:?}" - ); - - let param_tys = self.cx.func_params_types(fn_ty); - - let all_args_match = iter::zip(¶m_tys, args.iter().map(|&v| self.cx.val_ty(v))) - .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); - - if all_args_match { - return Cow::Borrowed(args); - } - - let casted_args: Vec<_> = iter::zip(param_tys, args) - .enumerate() - .map(|(i, (expected_ty, &actual_val))| { - let actual_ty = self.cx.val_ty(actual_val); - if expected_ty != actual_ty { - debug!( - "type mismatch in function call of {:?}. \ - Expected {:?} for param {}, got {:?}; injecting bitcast", - llfn, expected_ty, i, actual_ty - ); - self.bitcast(actual_val, expected_ty) - } else { - actual_val - } - }) - .collect(); - - Cow::Owned(casted_args) - } -} - /// Empty string, to be used where LLVM expects an instruction name, indicating /// that the instruction is to be left unnamed (i.e. numbered, in textual IR). // FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer. @@ -1610,9 +1567,7 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) }; ret.expect("LLVM does not have support for catchret") } -} -impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { fn check_call<'b>( &mut self, typ: &str, @@ -1627,7 +1582,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { let param_tys = self.cx.func_params_types(fn_ty); - let all_args_match = iter::zip(¶m_tys, args.iter().map(|&v| self.val_ty(v))) + let all_args_match = iter::zip(¶m_tys, args.iter().map(|&v| self.cx.val_ty(v))) .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); if all_args_match { @@ -1637,7 +1592,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { let casted_args: Vec<_> = iter::zip(param_tys, args) .enumerate() .map(|(i, (expected_ty, &actual_val))| { - let actual_ty = self.val_ty(actual_val); + let actual_ty = self.cx.val_ty(actual_val); if expected_ty != actual_ty { debug!( "type mismatch in function call of {:?}. \ @@ -1653,12 +1608,12 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { Cow::Owned(casted_args) } -} -impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { + pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) } } } + impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value { let (ty, f) = self.cx.get_intrinsic(intrinsic); diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 6a7c042e03af..c3f8f60eb5ec 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -8,7 +8,6 @@ use std::str; use rustc_abi::{HasDataLayout, Size, TargetDataLayout, VariantIdx}; use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh}; -use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::traits::*; use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN}; @@ -682,10 +681,6 @@ impl<'ll> SimpleCx<'ll> { llvm::LLVMMDStringInContext2(self.llcx, name.as_ptr() as *const c_char, name.len()) }) } - - pub(crate) fn type_kind(&self, ty: &'ll Type) -> TypeKind { - unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() } - } } impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { From f16f64b15a51789984d9014e92e86fb3a2fe8ce0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 14:33:55 +0000 Subject: [PATCH 282/991] Remove inherent function that has a trait method duplicate of a commonly imported trait --- compiler/rustc_codegen_llvm/src/asm.rs | 7 +------ .../rustc_codegen_llvm/src/builder/autodiff.rs | 1 + compiler/rustc_codegen_llvm/src/context.rs | 16 +++++++--------- .../src/coverageinfo/mapgen/covfun.rs | 2 +- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index be5673eddf93..5fc99ced9937 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -1,6 +1,5 @@ use std::assert_matches::assert_matches; -use libc::{c_char, c_uint}; use rustc_abi::{BackendRepr, Float, Integer, Primitive, Scalar}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_codegen_ssa::mir::operand::OperandValue; @@ -512,11 +511,7 @@ pub(crate) fn inline_asm_call<'ll>( // Store mark in a metadata node so we can map LLVM errors // back to source locations. See #17552. let key = "srcloc"; - let kind = llvm::LLVMGetMDKindIDInContext( - bx.llcx, - key.as_ptr().cast::(), - key.len() as c_uint, - ); + let kind = bx.get_md_kind_id(key); // `srcloc` contains one 64-bit integer for each line of assembly code, // where the lower 32 bits hold the lo byte position and the upper 32 bits diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index 1e12d1a1cb3e..71705ecb4d0f 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -3,6 +3,7 @@ use std::ptr; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, AutoDiffItem, DiffActivity, DiffMode}; use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::back::write::ModuleConfig; +use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; use rustc_errors::FatalError; use tracing::{debug, trace}; diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index c3f8f60eb5ec..a4e88e5a23f7 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -32,7 +32,7 @@ use smallvec::SmallVec; use crate::back::write::to_llvm_code_model; use crate::callee::get_fn; -use crate::common::{self, AsCCharPtr}; +use crate::common::AsCCharPtr; use crate::debuginfo::metadata::apply_vcall_visibility_metadata; use crate::llvm::{Metadata, MetadataType}; use crate::type_::Type; @@ -652,24 +652,22 @@ impl<'ll> SimpleCx<'ll> { let isize_ty = llvm::Type::ix_llcx(llcx, pointer_size.bits()); Self(SCx { llmod, llcx, isize_ty }, PhantomData) } +} - pub(crate) fn val_ty(&self, v: &'ll Value) -> &'ll Type { - common::val_ty(v) - } - +impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { pub(crate) fn get_metadata_value(&self, metadata: &'ll Metadata) -> &'ll Value { - unsafe { llvm::LLVMMetadataAsValue(self.llcx, metadata) } + unsafe { llvm::LLVMMetadataAsValue(self.llcx(), metadata) } } pub(crate) fn get_function(&self, name: &str) -> Option<&'ll Value> { let name = SmallCStr::new(name); - unsafe { llvm::LLVMGetNamedFunction(self.llmod, name.as_ptr()) } + unsafe { llvm::LLVMGetNamedFunction((**self).borrow().llmod, name.as_ptr()) } } pub(crate) fn get_md_kind_id(&self, name: &str) -> u32 { unsafe { llvm::LLVMGetMDKindIDInContext( - self.llcx, + self.llcx(), name.as_ptr() as *const c_char, name.len() as c_uint, ) @@ -678,7 +676,7 @@ impl<'ll> SimpleCx<'ll> { pub(crate) fn create_metadata(&self, name: String) -> Option<&'ll Metadata> { Some(unsafe { - llvm::LLVMMDStringInContext2(self.llcx, name.as_ptr() as *const c_char, name.len()) + llvm::LLVMMDStringInContext2(self.llcx(), name.as_ptr() as *const c_char, name.len()) }) } } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs index c53ea6d46661..80e54bf045e2 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs @@ -8,7 +8,7 @@ use std::ffi::CString; use rustc_abi::Align; use rustc_codegen_ssa::traits::{ - BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods, + BaseTypeCodegenMethods as _, ConstCodegenMethods, StaticCodegenMethods, }; use rustc_middle::mir::coverage::{ BasicCoverageBlock, CovTerm, CoverageIdsInfo, Expression, FunctionCoverageInfo, Mapping, From 3565603d2522cb96f52b74dba3d64f5869a5ad4c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 14:45:16 +0000 Subject: [PATCH 283/991] Use a safe wrapper around an LLVM FFI function --- compiler/rustc_codegen_llvm/src/asm.rs | 2 +- compiler/rustc_codegen_llvm/src/consts.rs | 2 +- compiler/rustc_codegen_llvm/src/context.rs | 11 ++++++++--- compiler/rustc_codegen_llvm/src/intrinsic.rs | 4 ++-- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 5fc99ced9937..6f344e1ea2e2 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -533,7 +533,7 @@ pub(crate) fn inline_asm_call<'ll>( )) })); let md = llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()); - let md = llvm::LLVMMetadataAsValue(&bx.llcx, md); + let md = bx.get_metadata_value(md); llvm::LLVMSetMetadata(call, kind, md); Some(call) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 330e8a8f4069..0dec0d869b0a 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -490,7 +490,7 @@ impl<'ll> CodegenCx<'ll, '_> { llvm::LLVMMDStringInContext2(self.llcx, bytes.as_c_char_ptr(), bytes.len()); let data = [section, alloc]; let meta = llvm::LLVMMDNodeInContext2(self.llcx, data.as_ptr(), data.len()); - let val = llvm::LLVMMetadataAsValue(self.llcx, meta); + let val = self.get_metadata_value(meta); llvm::LLVMAddNamedMetadataOperand( self.llmod, c"wasm.custom_sections".as_ptr(), diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index a4e88e5a23f7..c8a55d5c03ac 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -656,7 +656,7 @@ impl<'ll> SimpleCx<'ll> { impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { pub(crate) fn get_metadata_value(&self, metadata: &'ll Metadata) -> &'ll Value { - unsafe { llvm::LLVMMetadataAsValue(self.llcx(), metadata) } + llvm::LLVMMetadataAsValue(self.llcx(), metadata) } pub(crate) fn get_function(&self, name: &str) -> Option<&'ll Value> { @@ -1225,9 +1225,14 @@ impl CodegenCx<'_, '_> { impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { /// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`. - pub(crate) fn set_metadata<'a>(&self, val: &'a Value, kind_id: MetadataType, md: &'a Metadata) { + pub(crate) fn set_metadata<'a>( + &self, + val: &'a Value, + kind_id: MetadataType, + md: &'ll Metadata, + ) { + let node = self.get_metadata_value(md); unsafe { - let node = llvm::LLVMMetadataAsValue(self.llcx(), md); llvm::LLVMSetMetadata(val, kind_id as c_uint, node); } } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index dfbb5bc1731d..5e9f7f26f486 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -649,7 +649,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { fn type_test(&mut self, pointer: Self::Value, typeid: Self::Metadata) -> Self::Value { // Test the called operand using llvm.type.test intrinsic. The LowerTypeTests link-time // optimization pass replaces calls to this intrinsic with code to test type membership. - let typeid = unsafe { llvm::LLVMMetadataAsValue(&self.llcx, typeid) }; + let typeid = self.get_metadata_value(typeid); self.call_intrinsic("llvm.type.test", &[pointer, typeid]) } @@ -659,7 +659,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { vtable_byte_offset: u64, typeid: &'ll Metadata, ) -> Self::Value { - let typeid = unsafe { llvm::LLVMMetadataAsValue(&self.llcx, typeid) }; + let typeid = self.get_metadata_value(typeid); let vtable_byte_offset = self.const_i32(vtable_byte_offset as i32); let type_checked_load = self.call_intrinsic("llvm.type.checked.load", &[llvtable, vtable_byte_offset, typeid]); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 2738fee64cf9..7dc50eb68499 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1680,7 +1680,7 @@ unsafe extern "C" { Packed: Bool, ); - pub(crate) fn LLVMMetadataAsValue<'a>(C: &'a Context, MD: &'a Metadata) -> &'a Value; + pub(crate) safe fn LLVMMetadataAsValue<'a>(C: &'a Context, MD: &'a Metadata) -> &'a Value; pub(crate) fn LLVMSetUnnamedAddress(Global: &Value, UnnamedAddr: UnnamedAddr); From 553828c6f48adcf3f2443bf1972909db518e3c89 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Feb 2025 14:38:55 +0000 Subject: [PATCH 284/991] Mark more LLVM FFI as safe --- compiler/rustc_codegen_llvm/src/asm.rs | 95 ++++++++++--------- compiler/rustc_codegen_llvm/src/builder.rs | 4 +- compiler/rustc_codegen_llvm/src/context.rs | 10 +- .../rustc_codegen_llvm/src/llvm/enzyme_ffi.rs | 3 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 16 +++- 5 files changed, 69 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 6f344e1ea2e2..6e931aa0bc76 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -482,12 +482,13 @@ pub(crate) fn inline_asm_call<'ll>( debug!("Asm Output Type: {:?}", output); let fty = bx.cx.type_func(&argtys, output); - unsafe { - // Ask LLVM to verify that the constraints are well-formed. - let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_c_char_ptr(), cons.len()); - debug!("constraint verification result: {:?}", constraints_ok); - if constraints_ok { - let v = llvm::LLVMRustInlineAsm( + // Ask LLVM to verify that the constraints are well-formed. + let constraints_ok = + unsafe { llvm::LLVMRustInlineAsmVerify(fty, cons.as_c_char_ptr(), cons.len()) }; + debug!("constraint verification result: {:?}", constraints_ok); + if constraints_ok { + let v = unsafe { + llvm::LLVMRustInlineAsm( fty, asm.as_c_char_ptr(), asm.len(), @@ -497,50 +498,50 @@ pub(crate) fn inline_asm_call<'ll>( alignstack, dia, can_throw, - ); + ) + }; - let call = if !labels.is_empty() { - assert!(catch_funclet.is_none()); - bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None) - } else if let Some((catch, funclet)) = catch_funclet { - bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None) - } else { - bx.call(fty, None, None, v, inputs, None, None) - }; - - // Store mark in a metadata node so we can map LLVM errors - // back to source locations. See #17552. - let key = "srcloc"; - let kind = bx.get_md_kind_id(key); - - // `srcloc` contains one 64-bit integer for each line of assembly code, - // where the lower 32 bits hold the lo byte position and the upper 32 bits - // hold the hi byte position. - let mut srcloc = vec![]; - if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 { - // LLVM inserts an extra line to add the ".intel_syntax", so add - // a dummy srcloc entry for it. - // - // Don't do this if we only have 1 line span since that may be - // due to the asm template string coming from a macro. LLVM will - // default to the first srcloc for lines that don't have an - // associated srcloc. - srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0))); - } - srcloc.extend(line_spans.iter().map(|span| { - llvm::LLVMValueAsMetadata(bx.const_u64( - u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32), - )) - })); - let md = llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()); - let md = bx.get_metadata_value(md); - llvm::LLVMSetMetadata(call, kind, md); - - Some(call) + let call = if !labels.is_empty() { + assert!(catch_funclet.is_none()); + bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None) + } else if let Some((catch, funclet)) = catch_funclet { + bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None) } else { - // LLVM has detected an issue with our constraints, bail out - None + bx.call(fty, None, None, v, inputs, None, None) + }; + + // Store mark in a metadata node so we can map LLVM errors + // back to source locations. See #17552. + let key = "srcloc"; + let kind = bx.get_md_kind_id(key); + + // `srcloc` contains one 64-bit integer for each line of assembly code, + // where the lower 32 bits hold the lo byte position and the upper 32 bits + // hold the hi byte position. + let mut srcloc = vec![]; + if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 { + // LLVM inserts an extra line to add the ".intel_syntax", so add + // a dummy srcloc entry for it. + // + // Don't do this if we only have 1 line span since that may be + // due to the asm template string coming from a macro. LLVM will + // default to the first srcloc for lines that don't have an + // associated srcloc. + srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0))); } + srcloc.extend(line_spans.iter().map(|span| { + llvm::LLVMValueAsMetadata( + bx.const_u64(u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32)), + ) + })); + let md = unsafe { llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()) }; + let md = bx.get_metadata_value(md); + llvm::LLVMSetMetadata(call, kind, md); + + Some(call) + } else { + // LLVM has detected an issue with our constraints, bail out + None } } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 17579ebe72c4..7e8b2467989d 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -311,8 +311,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // This function handles switch instructions with more than 2 targets and it needs to // emit branch weights metadata instead of using the intrinsic. // The values 1 and 2000 are the same as the values used by the `llvm.expect` intrinsic. - let cold_weight = unsafe { llvm::LLVMValueAsMetadata(self.cx.const_u32(1)) }; - let hot_weight = unsafe { llvm::LLVMValueAsMetadata(self.cx.const_u32(2000)) }; + let cold_weight = llvm::LLVMValueAsMetadata(self.cx.const_u32(1)); + let hot_weight = llvm::LLVMValueAsMetadata(self.cx.const_u32(2000)); let weight = |is_cold: bool| -> &Metadata { if is_cold { cold_weight } else { hot_weight } }; diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index c8a55d5c03ac..ecef54d31659 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -34,7 +34,7 @@ use crate::back::write::to_llvm_code_model; use crate::callee::get_fn; use crate::common::AsCCharPtr; use crate::debuginfo::metadata::apply_vcall_visibility_metadata; -use crate::llvm::{Metadata, MetadataType}; +use crate::llvm::Metadata; use crate::type_::Type; use crate::value::Value; use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util}; @@ -664,7 +664,7 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { unsafe { llvm::LLVMGetNamedFunction((**self).borrow().llmod, name.as_ptr()) } } - pub(crate) fn get_md_kind_id(&self, name: &str) -> u32 { + pub(crate) fn get_md_kind_id(&self, name: &str) -> llvm::MetadataKindId { unsafe { llvm::LLVMGetMDKindIDInContext( self.llcx(), @@ -1228,13 +1228,11 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { pub(crate) fn set_metadata<'a>( &self, val: &'a Value, - kind_id: MetadataType, + kind_id: impl Into, md: &'ll Metadata, ) { let node = self.get_metadata_value(md); - unsafe { - llvm::LLVMSetMetadata(val, kind_id as c_uint, node); - } + llvm::LLVMSetMetadata(val, kind_id.into(), node); } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 3c2c6964a3d7..ac8d4e572837 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -3,13 +3,14 @@ use libc::{c_char, c_uint}; +use super::MetadataKindId; use super::ffi::{BasicBlock, Metadata, Module, Type, Value}; use crate::llvm::Bool; #[link(name = "llvm-wrapper", kind = "static")] unsafe extern "C" { // Enzyme - pub(crate) fn LLVMRustHasMetadata(I: &Value, KindID: c_uint) -> bool; + pub(crate) safe fn LLVMRustHasMetadata(I: &Value, KindID: MetadataKindId) -> bool; pub(crate) fn LLVMRustEraseInstUntilInclusive(BB: &BasicBlock, I: &Value); pub(crate) fn LLVMRustGetLastInstruction<'a>(BB: &BasicBlock) -> Option<&'a Value>; pub(crate) fn LLVMRustDIGetInstMetadata(I: &Value) -> Option<&Metadata>; diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 7dc50eb68499..6801f21aa77c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -976,6 +976,16 @@ pub type SelfProfileAfterPassCallback = unsafe extern "C" fn(*mut c_void); pub type GetSymbolsCallback = unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void; pub type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void; +#[derive(Copy, Clone)] +#[repr(transparent)] +pub struct MetadataKindId(c_uint); + +impl From for MetadataKindId { + fn from(value: MetadataType) -> Self { + Self(value as c_uint) + } +} + unsafe extern "C" { // Create and destroy contexts. pub(crate) fn LLVMContextDispose(C: &'static mut Context); @@ -983,7 +993,7 @@ unsafe extern "C" { C: &Context, Name: *const c_char, SLen: c_uint, - ) -> c_uint; + ) -> MetadataKindId; // Create modules. pub(crate) fn LLVMModuleCreateWithNameInContext( @@ -1051,9 +1061,9 @@ unsafe extern "C" { pub(crate) fn LLVMGetValueName2(Val: &Value, Length: *mut size_t) -> *const c_char; pub(crate) fn LLVMSetValueName2(Val: &Value, Name: *const c_char, NameLen: size_t); pub(crate) fn LLVMReplaceAllUsesWith<'a>(OldVal: &'a Value, NewVal: &'a Value); - pub(crate) fn LLVMSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Node: &'a Value); + pub(crate) safe fn LLVMSetMetadata<'a>(Val: &'a Value, KindID: MetadataKindId, Node: &'a Value); pub(crate) fn LLVMGlobalSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata); - pub(crate) fn LLVMValueAsMetadata(Node: &Value) -> &Metadata; + pub(crate) safe fn LLVMValueAsMetadata(Node: &Value) -> &Metadata; // Operations on constants of any type pub(crate) fn LLVMConstNull(Ty: &Type) -> &Value; From bab03bf1768fea8512ece42dea6d66f6f4743145 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 22 Feb 2025 22:05:48 +0000 Subject: [PATCH 285/991] Improve behavior of IF_LET_RESCOPE around temporaries and place expressions --- compiler/rustc_lint/src/if_let_rescope.rs | 152 ++++++++---------- .../lint-if-let-rescope-false-positives.rs | 29 ++++ 2 files changed, 98 insertions(+), 83 deletions(-) create mode 100644 tests/ui/drop/lint-if-let-rescope-false-positives.rs diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index c1aa95667da6..7a6d656d00dc 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -1,7 +1,7 @@ use std::iter::repeat; use std::ops::ControlFlow; -use hir::intravisit::Visitor; +use hir::intravisit::{self, Visitor}; use rustc_ast::Recovered; use rustc_errors::{ Applicability, Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic, SuggestionStyle, @@ -9,6 +9,7 @@ use rustc_errors::{ use rustc_hir::{self as hir, HirIdSet}; use rustc_macros::LintDiagnostic; use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::adjustment::Adjust; use rustc_session::lint::{FutureIncompatibilityReason, LintId}; use rustc_session::{declare_lint, impl_lint_pass}; use rustc_span::Span; @@ -160,7 +161,7 @@ impl IfLetRescope { let lifetime_end = source_map.end_point(conseq.span); if let ControlFlow::Break(significant_dropper) = - (FindSignificantDropper { cx }).visit_expr(init) + (FindSignificantDropper { cx }).check_if_let_scrutinee(init) { first_if_to_lint = first_if_to_lint.or_else(|| Some((span, expr.hir_id))); significant_droppers.push(significant_dropper); @@ -363,96 +364,81 @@ enum SingleArmMatchBegin { WithoutOpenBracket(Span), } -struct FindSignificantDropper<'tcx, 'a> { +struct FindSignificantDropper<'a, 'tcx> { cx: &'a LateContext<'tcx>, } -impl<'tcx, 'a> Visitor<'tcx> for FindSignificantDropper<'tcx, 'a> { - type Result = ControlFlow; +impl<'tcx> FindSignificantDropper<'_, 'tcx> { + fn check_if_let_scrutinee(&mut self, init: &'tcx hir::Expr<'tcx>) -> ControlFlow { + self.check_promoted_temp_with_drop(init)?; + self.visit_expr(init) + } - fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { - if self + // Check that an expression is not a promoted temporary with a significant + // drop impl. + // + // An expression is a promoted temporary if it has an addr taken (i.e. `&expr`) + // or is the scrutinee of the `if let`, *and* the expression is not a place + // expr, and it has a significant drop. + fn check_promoted_temp_with_drop(&self, expr: &'tcx hir::Expr<'tcx>) -> ControlFlow { + if !expr.is_place_expr(|base| { + self.cx + .typeck_results() + .adjustments() + .get(base.hir_id) + .is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_)))) + }) && self .cx .typeck_results() .expr_ty(expr) .has_significant_drop(self.cx.tcx, self.cx.typing_env()) { - return ControlFlow::Break(expr.span); - } - match expr.kind { - hir::ExprKind::ConstBlock(_) - | hir::ExprKind::Lit(_) - | hir::ExprKind::Path(_) - | hir::ExprKind::Assign(_, _, _) - | hir::ExprKind::AssignOp(_, _, _) - | hir::ExprKind::Break(_, _) - | hir::ExprKind::Continue(_) - | hir::ExprKind::Ret(_) - | hir::ExprKind::Become(_) - | hir::ExprKind::InlineAsm(_) - | hir::ExprKind::OffsetOf(_, _) - | hir::ExprKind::Repeat(_, _) - | hir::ExprKind::Err(_) - | hir::ExprKind::Struct(_, _, _) - | hir::ExprKind::Closure(_) - | hir::ExprKind::Block(_, _) - | hir::ExprKind::DropTemps(_) - | hir::ExprKind::Loop(_, _, _, _) => ControlFlow::Continue(()), - - hir::ExprKind::Tup(exprs) | hir::ExprKind::Array(exprs) => { - for expr in exprs { - self.visit_expr(expr)?; - } - ControlFlow::Continue(()) - } - hir::ExprKind::Call(callee, args) => { - self.visit_expr(callee)?; - for expr in args { - self.visit_expr(expr)?; - } - ControlFlow::Continue(()) - } - hir::ExprKind::MethodCall(_, receiver, args, _) => { - self.visit_expr(receiver)?; - for expr in args { - self.visit_expr(expr)?; - } - ControlFlow::Continue(()) - } - hir::ExprKind::Index(left, right, _) | hir::ExprKind::Binary(_, left, right) => { - self.visit_expr(left)?; - self.visit_expr(right) - } - hir::ExprKind::Unary(_, expr) - | hir::ExprKind::Cast(expr, _) - | hir::ExprKind::Type(expr, _) - | hir::ExprKind::UnsafeBinderCast(_, expr, _) - | hir::ExprKind::Yield(expr, _) - | hir::ExprKind::AddrOf(_, _, expr) - | hir::ExprKind::Match(expr, _, _) - | hir::ExprKind::Field(expr, _) - | hir::ExprKind::Let(&hir::LetExpr { - init: expr, - span: _, - pat: _, - ty: _, - recovered: Recovered::No, - }) => self.visit_expr(expr), - hir::ExprKind::Let(_) => ControlFlow::Continue(()), - - hir::ExprKind::If(cond, _, _) => { - if let hir::ExprKind::Let(hir::LetExpr { - init, - span: _, - pat: _, - ty: _, - recovered: Recovered::No, - }) = cond.kind - { - self.visit_expr(init)?; - } - ControlFlow::Continue(()) - } + ControlFlow::Break(expr.span) + } else { + ControlFlow::Continue(()) + } + } +} + +impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { + type Result = ControlFlow; + + fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) -> Self::Result { + // Blocks introduce temporary terminating scope for all of its + // statements, so just visit the tail expr. + if let Some(expr) = b.expr { self.visit_expr(expr) } else { ControlFlow::Continue(()) } + } + + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { + // Check for promoted temporaries from autoref, e.g. + // `if let None = TypeWithDrop.as_ref() {} else {}` + // where `fn as_ref(&self) -> Option<...>`. + for adj in self.cx.typeck_results().expr_adjustments(expr) { + match adj.kind { + Adjust::Deref(_) => break, + Adjust::Borrow(_) => { + self.check_promoted_temp_with_drop(expr)?; + } + _ => {} + } + } + + match expr.kind { + // Check for cases like `if let None = Some(&Drop) {} else {}`. + hir::ExprKind::AddrOf(_, _, expr) => { + self.check_promoted_temp_with_drop(expr)?; + intravisit::walk_expr(self, expr) + } + // If always introduces a temporary terminating scope for its cond and arms, + // so don't visit them. + hir::ExprKind::If(..) => ControlFlow::Continue(()), + // Match introduces temporary terminating scopes for arms, so don't visit + // them, and only visit the scrutinee to account for cases like: + // `if let None = match &Drop { _ => Some(1) } {} else {}`. + hir::ExprKind::Match(scrut, _, _) => self.visit_expr(scrut), + // Self explanatory. + hir::ExprKind::DropTemps(_) => ControlFlow::Continue(()), + _ => intravisit::walk_expr(self, expr), } } } diff --git a/tests/ui/drop/lint-if-let-rescope-false-positives.rs b/tests/ui/drop/lint-if-let-rescope-false-positives.rs new file mode 100644 index 000000000000..533d0f2f982b --- /dev/null +++ b/tests/ui/drop/lint-if-let-rescope-false-positives.rs @@ -0,0 +1,29 @@ +//@ edition: 2021 +//@ check-pass + +#![deny(if_let_rescope)] + +struct Drop; +impl std::ops::Drop for Drop { + fn drop(&mut self) { + println!("drop") + } +} + +impl Drop { + fn as_ref(&self) -> Option { + Some(1) + } +} + +fn consume(_: impl Sized) -> Option { Some(1) } + +fn main() { + let drop = Drop; + + // Make sure we don't drop if we don't actually make a temporary. + if let None = drop.as_ref() {} else {} + + // Make sure we don't lint if we consume the droppy value. + if let None = consume(Drop) {} else {} +} From 2797936f6dcd29777f236a5d966d487a7f4cbbb3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 22 Feb 2025 22:13:23 +0000 Subject: [PATCH 286/991] More comments --- compiler/rustc_lint/src/if_let_rescope.rs | 24 +++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 7a6d656d00dc..55d900e03199 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -369,17 +369,22 @@ struct FindSignificantDropper<'a, 'tcx> { } impl<'tcx> FindSignificantDropper<'_, 'tcx> { + /// Check the scrutinee of an `if let` to see if it promotes any temporary values + /// that would change drop order in edition 2024. Specifically, it checks the value + /// of the scrutinee itself, and also recurses into the expression to find any ref + /// exprs (or autoref) which would promote temporaries that would be scoped to the + /// end of this `if`. fn check_if_let_scrutinee(&mut self, init: &'tcx hir::Expr<'tcx>) -> ControlFlow { self.check_promoted_temp_with_drop(init)?; self.visit_expr(init) } - // Check that an expression is not a promoted temporary with a significant - // drop impl. - // - // An expression is a promoted temporary if it has an addr taken (i.e. `&expr`) - // or is the scrutinee of the `if let`, *and* the expression is not a place - // expr, and it has a significant drop. + /// Check that an expression is not a promoted temporary with a significant + /// drop impl. + /// + /// An expression is a promoted temporary if it has an addr taken (i.e. `&expr` or autoref) + /// or is the scrutinee of the `if let`, *and* the expression is not a place + /// expr, and it has a significant drop. fn check_promoted_temp_with_drop(&self, expr: &'tcx hir::Expr<'tcx>) -> ControlFlow { if !expr.is_place_expr(|base| { self.cx @@ -405,7 +410,8 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) -> Self::Result { // Blocks introduce temporary terminating scope for all of its - // statements, so just visit the tail expr. + // statements, so just visit the tail expr, skipping over any + // statements. This prevents false positives like `{ let x = &Drop; }`. if let Some(expr) = b.expr { self.visit_expr(expr) } else { ControlFlow::Continue(()) } } @@ -415,6 +421,7 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { // where `fn as_ref(&self) -> Option<...>`. for adj in self.cx.typeck_results().expr_adjustments(expr) { match adj.kind { + // Skip when we hit the first deref expr. Adjust::Deref(_) => break, Adjust::Borrow(_) => { self.check_promoted_temp_with_drop(expr)?; @@ -424,7 +431,7 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { } match expr.kind { - // Check for cases like `if let None = Some(&Drop) {} else {}`. + // Account for cases like `if let None = Some(&Drop) {} else {}`. hir::ExprKind::AddrOf(_, _, expr) => { self.check_promoted_temp_with_drop(expr)?; intravisit::walk_expr(self, expr) @@ -438,6 +445,7 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { hir::ExprKind::Match(scrut, _, _) => self.visit_expr(scrut), // Self explanatory. hir::ExprKind::DropTemps(_) => ControlFlow::Continue(()), + // Otherwise, walk into the expr's parts. _ => intravisit::walk_expr(self, expr), } } From bad8e98c7d0ed217b58362e61ae4357e5344d995 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 23 Feb 2025 01:09:51 +0000 Subject: [PATCH 287/991] Consider lvalues of field and index as possibly temporary places --- compiler/rustc_lint/src/if_let_rescope.rs | 8 +++++++ .../lint-if-let-rescope-false-positives.rs | 4 ++++ tests/ui/drop/lint-if-let-rescope.fixed | 6 +++++ tests/ui/drop/lint-if-let-rescope.rs | 6 +++++ tests/ui/drop/lint-if-let-rescope.stderr | 23 ++++++++++++++++++- 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 55d900e03199..23f037f3692a 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -436,6 +436,14 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { self.check_promoted_temp_with_drop(expr)?; intravisit::walk_expr(self, expr) } + // `(Drop, ()).1` introduces a temporary and then moves out of + // part of it, therefore we should check it for temporaries. + // FIXME: This may have false positives if we move the part + // that actually has drop, but oh well. + hir::ExprKind::Index(expr, _, _) | hir::ExprKind::Field(expr, _) => { + self.check_promoted_temp_with_drop(expr)?; + intravisit::walk_expr(self, expr) + } // If always introduces a temporary terminating scope for its cond and arms, // so don't visit them. hir::ExprKind::If(..) => ControlFlow::Continue(()), diff --git a/tests/ui/drop/lint-if-let-rescope-false-positives.rs b/tests/ui/drop/lint-if-let-rescope-false-positives.rs index 533d0f2f982b..77b7df4bc3ba 100644 --- a/tests/ui/drop/lint-if-let-rescope-false-positives.rs +++ b/tests/ui/drop/lint-if-let-rescope-false-positives.rs @@ -26,4 +26,8 @@ fn main() { // Make sure we don't lint if we consume the droppy value. if let None = consume(Drop) {} else {} + + // Make sure we don't lint on field exprs of place exprs. + let tup_place = (Drop, ()); + if let None = consume(tup_place.1) {} else {} } diff --git a/tests/ui/drop/lint-if-let-rescope.fixed b/tests/ui/drop/lint-if-let-rescope.fixed index 182190aa323b..79858e6f225a 100644 --- a/tests/ui/drop/lint-if-let-rescope.fixed +++ b/tests/ui/drop/lint-if-let-rescope.fixed @@ -94,6 +94,12 @@ fn main() { //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } + match Some((droppy(), ()).1) { Some(_value) => {} _ => {}} + //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| HELP: the value is now dropped here in Edition 2024 + //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 + // We want to keep the `if let`s below as direct descendents of match arms, // so the formatting is suppressed. #[rustfmt::skip] diff --git a/tests/ui/drop/lint-if-let-rescope.rs b/tests/ui/drop/lint-if-let-rescope.rs index e1b38be0a0f5..9d873c65426f 100644 --- a/tests/ui/drop/lint-if-let-rescope.rs +++ b/tests/ui/drop/lint-if-let-rescope.rs @@ -94,6 +94,12 @@ fn main() { //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } + if let Some(_value) = Some((droppy(), ()).1) {} else {} + //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| HELP: the value is now dropped here in Edition 2024 + //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 + // We want to keep the `if let`s below as direct descendents of match arms, // so the formatting is suppressed. #[rustfmt::skip] diff --git a/tests/ui/drop/lint-if-let-rescope.stderr b/tests/ui/drop/lint-if-let-rescope.stderr index 2b0fcb7a938a..b17239976cc0 100644 --- a/tests/ui/drop/lint-if-let-rescope.stderr +++ b/tests/ui/drop/lint-if-let-rescope.stderr @@ -175,5 +175,26 @@ LL - while (if let Some(_value) = droppy().get() { false } else { true }) { LL + while (match droppy().get() { Some(_value) => { false } _ => { true }}) { | -error: aborting due to 7 previous errors +error: `if let` assigns a shorter lifetime since Edition 2024 + --> $DIR/lint-if-let-rescope.rs:97:8 + | +LL | if let Some(_value) = Some((droppy(), ()).1) {} else {} + | ^^^^^^^^^^^^^^^^^^^^^^^^--------------^^^ + | | + | this value has a significant drop implementation which may observe a major change in drop order and requires your discretion + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see +help: the value is now dropped here in Edition 2024 + --> $DIR/lint-if-let-rescope.rs:97:51 + | +LL | if let Some(_value) = Some((droppy(), ()).1) {} else {} + | ^ +help: a `match` with a single arm can preserve the drop order up to Edition 2021 + | +LL - if let Some(_value) = Some((droppy(), ()).1) {} else {} +LL + match Some((droppy(), ()).1) { Some(_value) => {} _ => {}} + | + +error: aborting due to 8 previous errors From 60fc2beebbc0509e89af89cb021bdd67ea6239df Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 24 Feb 2025 19:48:24 +0100 Subject: [PATCH 288/991] run some tests on emscripten again these were ignored because of #45351, but that issue has long been fixed. Let's see if these pass, or if there is some issue lurking still --- .../simd/intrinsic/generic-arithmetic-pass.rs | 2 -- tests/ui/simd/intrinsic/generic-cast-pass.rs | 2 -- .../simd/intrinsic/generic-comparison-pass.rs | 18 ++++++++---------- .../ui/simd/intrinsic/generic-elements-pass.rs | 2 -- tests/ui/simd/issue-32947.rs | 5 +---- tests/ui/simd/issue-39720.rs | 1 - 6 files changed, 9 insertions(+), 21 deletions(-) diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs index 4a18c0164e4b..29d82255d4ea 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs +++ b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(non_camel_case_types)] -//@ ignore-emscripten FIXME(#45351) hits an LLVM assert #![feature(repr_simd, intrinsics)] #[repr(simd)] @@ -53,7 +52,6 @@ unsafe fn simd_or(x: T, y: T) -> T; #[rustc_intrinsic] unsafe fn simd_xor(x: T, y: T) -> T; - #[rustc_intrinsic] unsafe fn simd_neg(x: T) -> T; diff --git a/tests/ui/simd/intrinsic/generic-cast-pass.rs b/tests/ui/simd/intrinsic/generic-cast-pass.rs index 2155d8458647..aab7347d1de5 100644 --- a/tests/ui/simd/intrinsic/generic-cast-pass.rs +++ b/tests/ui/simd/intrinsic/generic-cast-pass.rs @@ -1,9 +1,7 @@ //@ run-pass -//@ ignore-emscripten FIXME(#45351) hits an LLVM assert #![feature(repr_simd, intrinsics)] - #[rustc_intrinsic] unsafe fn simd_cast(x: T) -> U; diff --git a/tests/ui/simd/intrinsic/generic-comparison-pass.rs b/tests/ui/simd/intrinsic/generic-comparison-pass.rs index 68f98372e1dc..d0ec25036020 100644 --- a/tests/ui/simd/intrinsic/generic-comparison-pass.rs +++ b/tests/ui/simd/intrinsic/generic-comparison-pass.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ ignore-emscripten FIXME(#45351) hits an LLVM assert #![feature(repr_simd, intrinsics, concat_idents)] #![allow(non_camel_case_types)] @@ -14,7 +13,6 @@ struct u32x4(pub [u32; 4]); #[derive(Copy, Clone)] struct f32x4(pub [f32; 4]); - #[rustc_intrinsic] unsafe fn simd_eq(x: T, y: T) -> U; @@ -39,11 +37,11 @@ macro_rules! cmp { let rhs = $rhs; let e: u32x4 = concat_idents!(simd_, $method)($lhs, $rhs); // assume the scalar version is correct/the behaviour we want. - assert!((e.0[0] != 0) == lhs.0[0] .$method(&rhs.0[0])); - assert!((e.0[1] != 0) == lhs.0[1] .$method(&rhs.0[1])); - assert!((e.0[2] != 0) == lhs.0[2] .$method(&rhs.0[2])); - assert!((e.0[3] != 0) == lhs.0[3] .$method(&rhs.0[3])); - }} + assert!((e.0[0] != 0) == lhs.0[0].$method(&rhs.0[0])); + assert!((e.0[1] != 0) == lhs.0[1].$method(&rhs.0[1])); + assert!((e.0[2] != 0) == lhs.0[2].$method(&rhs.0[2])); + assert!((e.0[3] != 0) == lhs.0[3].$method(&rhs.0[3])); + }}; } macro_rules! tests { ($($lhs: ident, $rhs: ident;)*) => {{ @@ -75,9 +73,9 @@ fn main() { let i2 = i32x4([5, -5, 20, -100]); let i3 = i32x4([10, -11, 20, -100]); - let u1 = u32x4([10, !11+1, 12, 13]); - let u2 = u32x4([5, !5+1, 20, !100+1]); - let u3 = u32x4([10, !11+1, 20, !100+1]); + let u1 = u32x4([10, !11 + 1, 12, 13]); + let u2 = u32x4([5, !5 + 1, 20, !100 + 1]); + let u3 = u32x4([10, !11 + 1, 20, !100 + 1]); let f1 = f32x4([10.0, -11.0, 12.0, 13.0]); let f2 = f32x4([5.0, -5.0, 20.0, -100.0]); diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs index 8cb600bc9e45..b8d872c5cb77 100644 --- a/tests/ui/simd/intrinsic/generic-elements-pass.rs +++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ ignore-emscripten FIXME(#45351) hits an LLVM assert #![feature(repr_simd, intrinsics)] @@ -22,7 +21,6 @@ unsafe fn simd_insert(x: T, idx: u32, y: E) -> T; #[rustc_intrinsic] unsafe fn simd_extract(x: T, idx: u32) -> E; - #[rustc_intrinsic] unsafe fn simd_shuffle(x: T, y: T, idx: I) -> U; diff --git a/tests/ui/simd/issue-32947.rs b/tests/ui/simd/issue-32947.rs index dc5e7a4ec915..b34484b2d3b5 100644 --- a/tests/ui/simd/issue-32947.rs +++ b/tests/ui/simd/issue-32947.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ ignore-emscripten FIXME(#45351) #![feature(repr_simd, test)] @@ -15,9 +14,7 @@ fn main() { // non-optimized builds unsafe { let memory = &mut [0u64; 8] as *mut _ as *mut u8; - let misaligned_ptr: &mut [u8; 32] = { - std::mem::transmute(memory.offset(1)) - }; + let misaligned_ptr: &mut [u8; 32] = { std::mem::transmute(memory.offset(1)) }; *misaligned_ptr = std::mem::transmute(Mu64([1, 1, 1, 1])); test::black_box(memory); } diff --git a/tests/ui/simd/issue-39720.rs b/tests/ui/simd/issue-39720.rs index 8d7666faaf93..c3c4750d6deb 100644 --- a/tests/ui/simd/issue-39720.rs +++ b/tests/ui/simd/issue-39720.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ ignore-emscripten FIXME(#45351) #![feature(repr_simd, intrinsics)] From 1ff2593da98bb0c5e77d99eded59f039b9014b0d Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Mon, 24 Feb 2025 13:37:06 -0500 Subject: [PATCH 289/991] minor: Add tabstop to impl body in `generate_trait_impl` assist --- .../ide-assists/src/handlers/generate_impl.rs | 26 +++++++++++-------- .../crates/ide-assists/src/tests/generated.rs | 2 +- .../docs/book/src/assists_generated.md | 4 +-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs index 7b7dac9a3d6c..4439830947ad 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs @@ -78,7 +78,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio // data: T, // } // -// impl ${0:_} for Ctx {} +// impl ${1:_} for Ctx {$0} // ``` pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let nominal = ctx.find_node_at_offset::()?; @@ -102,6 +102,10 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> if let Some(trait_) = impl_.trait_() { edit.add_placeholder_snippet(cap, trait_); } + + if let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) { + edit.add_tabstop_after_token(cap, l_curly); + } } insert_impl(impl_, &edit.make_mut(nominal)); @@ -278,7 +282,7 @@ mod tests { r#" struct Foo {} - impl ${0:_} for Foo {} + impl ${1:_} for Foo {$0} "#, ); } @@ -293,7 +297,7 @@ mod tests { r#" struct Foo {} - impl ${0:_} for Foo {} + impl ${1:_} for Foo {$0} "#, ); } @@ -308,7 +312,7 @@ mod tests { r#" struct Foo<'a, T: Foo<'a>> {} - impl<'a, T: Foo<'a>> ${0:_} for Foo<'a, T> {} + impl<'a, T: Foo<'a>> ${1:_} for Foo<'a, T> {$0} "#, ); } @@ -326,7 +330,7 @@ mod tests { struct Foo<'a, T: Foo<'a>> {} #[cfg(feature = "foo")] - impl<'a, T: Foo<'a>> ${0:_} for Foo<'a, T> {} + impl<'a, T: Foo<'a>> ${1:_} for Foo<'a, T> {$0} "#, ); } @@ -341,7 +345,7 @@ mod tests { r#" struct Defaulted {} - impl ${0:_} for Defaulted {} + impl ${1:_} for Defaulted {$0} "#, ); } @@ -356,7 +360,7 @@ mod tests { r#" struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {} - impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> ${0:_} for Defaulted<'a, 'b, T, S> {} + impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> ${1:_} for Defaulted<'a, 'b, T, S> {$0} "#, ); } @@ -371,7 +375,7 @@ mod tests { r#" struct Defaulted {} - impl ${0:_} for Defaulted {} + impl ${1:_} for Defaulted {$0} "#, ); } @@ -398,10 +402,10 @@ mod tests { inner: T, } - impl ${0:_} for Struct + impl ${1:_} for Struct where T: Trait, - { + {$0 } "#, ); @@ -476,7 +480,7 @@ mod tests { mod foo { struct Bar {} - impl ${0:_} for Bar {} + impl ${1:_} for Bar {$0} } "#, ); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 0662527a387d..74ae126adae8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -1961,7 +1961,7 @@ struct Ctx { data: T, } -impl ${0:_} for Ctx {} +impl ${1:_} for Ctx {$0} "#####, ) } diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 9d68a873ffef..52da98dbd21d 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -280,7 +280,7 @@ fn main() { ### `apply_demorgan_iterator` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L132) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L147) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to `Iterator::all` and `Iterator::any`. @@ -2161,7 +2161,7 @@ struct Ctx { data: T, } -impl ${0:_} for Ctx {} +impl ${1:_} for Ctx {┃} ``` From 13f3bd1f7a4191e1adae4bef5ee9a715f0a1c7bf Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 24 Feb 2025 13:48:29 +0000 Subject: [PATCH 290/991] add `tool::CargoClippy` binary to target sysroot Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/tool.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 39acb646dff4..42424b885958 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1187,12 +1187,17 @@ fn run_tool_build_step( } tool_extended!(Cargofmt { path: "src/tools/rustfmt", tool_name: "cargo-fmt", stable: true }); -tool_extended!(CargoClippy { path: "src/tools/clippy", tool_name: "cargo-clippy", stable: true }); +tool_extended!(CargoClippy { + path: "src/tools/clippy", + tool_name: "cargo-clippy", + stable: true, + add_bins_to_sysroot: ["cargo-clippy"] +}); tool_extended!(Clippy { path: "src/tools/clippy", tool_name: "clippy-driver", stable: true, - add_bins_to_sysroot: ["clippy-driver", "cargo-clippy"] + add_bins_to_sysroot: ["clippy-driver"] }); tool_extended!(Miri { path: "src/tools/miri", From f677bab5dae958a6853f9298697780975199a64c Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 24 Feb 2025 14:13:12 +0000 Subject: [PATCH 291/991] add `tool::Cargofmt` binary to target sysroot Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/tool.rs | 9 +++++++-- src/bootstrap/src/core/builder/mod.rs | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 42424b885958..ee6b5d2a5de5 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1186,7 +1186,12 @@ fn run_tool_build_step( } } -tool_extended!(Cargofmt { path: "src/tools/rustfmt", tool_name: "cargo-fmt", stable: true }); +tool_extended!(Cargofmt { + path: "src/tools/rustfmt", + tool_name: "cargo-fmt", + stable: true, + add_bins_to_sysroot: ["cargo-fmt"] +}); tool_extended!(CargoClippy { path: "src/tools/clippy", tool_name: "cargo-clippy", @@ -1216,7 +1221,7 @@ tool_extended!(Rustfmt { path: "src/tools/rustfmt", tool_name: "rustfmt", stable: true, - add_bins_to_sysroot: ["rustfmt", "cargo-fmt"] + add_bins_to_sysroot: ["rustfmt"] }); #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 9c04f097bee2..52b9caa48dc6 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -890,6 +890,7 @@ impl<'a> Builder<'a> { gcc::Gcc, llvm::Sanitizers, tool::Rustfmt, + tool::Cargofmt, tool::Miri, tool::CargoMiri, llvm::Lld, From 78615ff2ae2813a1fd4e26ab1d9f7e914f6c7902 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Mon, 24 Feb 2025 23:34:46 +0000 Subject: [PATCH 292/991] Stablize `string_extend_from_within` --- library/alloc/src/string.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 9446afd4b24b..88227688ede0 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1137,7 +1137,6 @@ impl String { /// # Examples /// /// ``` - /// #![feature(string_extend_from_within)] /// let mut string = String::from("abcde"); /// /// string.extend_from_within(2..); @@ -1150,7 +1149,7 @@ impl String { /// assert_eq!(string, "abcdecdeabecde"); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "string_extend_from_within", issue = "103806")] + #[stable(feature = "string_extend_from_within", since = "CURRENT_RUSTC_VERSION")] pub fn extend_from_within(&mut self, src: R) where R: RangeBounds, From 7d2cfcab9d8291e412f41e43cdadf587d700d577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kostrubiec?= Date: Tue, 25 Feb 2025 00:43:25 +0100 Subject: [PATCH 293/991] Changed interners to start with preallocated capacity --- compiler/rustc_data_structures/src/sharded.rs | 3 ++ compiler/rustc_middle/src/ty/context.rs | 54 ++++++++++--------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index 65488c73d3cd..5a53f8af5f8c 100644 --- a/compiler/rustc_data_structures/src/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs @@ -143,6 +143,9 @@ pub fn shards() -> usize { pub type ShardedHashMap = Sharded>; impl ShardedHashMap { + pub fn with_capacity(cap: usize) -> Self { + Self::new(|| FxHashMap::with_capacity_and_hasher(cap, rustc_hash::FxBuildHasher::default())) + } pub fn len(&self) -> usize { self.lock_shards().map(|shard| shard.len()).sum() } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 35893ad953d1..e63c53cf54d6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -812,32 +812,38 @@ pub struct CtxtInterners<'tcx> { impl<'tcx> CtxtInterners<'tcx> { fn new(arena: &'tcx WorkerLocal>) -> CtxtInterners<'tcx> { + // Default interner size - this value has been chosen empirically, and may need to be adjusted + // as the compiler evolves. + const N: usize = 2048; CtxtInterners { arena, - type_: Default::default(), - const_lists: Default::default(), - args: Default::default(), - type_lists: Default::default(), - region: Default::default(), - poly_existential_predicates: Default::default(), - canonical_var_infos: Default::default(), - predicate: Default::default(), - clauses: Default::default(), - projs: Default::default(), - place_elems: Default::default(), - const_: Default::default(), - pat: Default::default(), - const_allocation: Default::default(), - bound_variable_kinds: Default::default(), - layout: Default::default(), - adt_def: Default::default(), - external_constraints: Default::default(), - predefined_opaques_in_body: Default::default(), - fields: Default::default(), - local_def_ids: Default::default(), - captures: Default::default(), - offset_of: Default::default(), - valtree: Default::default(), + // The factors have been chosen by @FractalFir based on observed interner sizes, and local perf runs. + // To get the interner sizes, insert `eprintln` printing the size of the interner in functions like `intern_ty`. + // Bigger benchmarks tend to give more accurate ratios, so use something like `x perf eprintln --includes cargo`. + type_: InternedSet::with_capacity(N * 16), + const_lists: InternedSet::with_capacity(N * 4), + args: InternedSet::with_capacity(N * 4), + type_lists: InternedSet::with_capacity(N * 4), + region: InternedSet::with_capacity(N * 4), + poly_existential_predicates: InternedSet::with_capacity(N / 4), + canonical_var_infos: InternedSet::with_capacity(N / 2), + predicate: InternedSet::with_capacity(N), + clauses: InternedSet::with_capacity(N), + projs: InternedSet::with_capacity(N * 4), + place_elems: InternedSet::with_capacity(N * 2), + const_: InternedSet::with_capacity(N * 2), + pat: InternedSet::with_capacity(N), + const_allocation: InternedSet::with_capacity(N), + bound_variable_kinds: InternedSet::with_capacity(N * 2), + layout: InternedSet::with_capacity(N), + adt_def: InternedSet::with_capacity(N), + external_constraints: InternedSet::with_capacity(N), + predefined_opaques_in_body: InternedSet::with_capacity(N), + fields: InternedSet::with_capacity(N * 4), + local_def_ids: InternedSet::with_capacity(N), + captures: InternedSet::with_capacity(N), + offset_of: InternedSet::with_capacity(N), + valtree: InternedSet::with_capacity(N), } } From 91ff4208d110c57fe76734013c33edb05936f8e9 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 24 Feb 2025 23:20:26 +0530 Subject: [PATCH 294/991] doc: remove nit from setup.md --- .../docs/book/src/contributing/setup.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/setup.md b/src/tools/rust-analyzer/docs/book/src/contributing/setup.md index d8a7840d3760..eab65e779ed4 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/setup.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/setup.md @@ -17,10 +17,13 @@ Since rust-analyzer is a Rust project, you will need to install Rust. You can do **Step 04**: Install the language server locally by running the following command: ```sh -cargo xtask install --server --code-bin code-insiders --dev-rel +# Install only the language server +cargo xtask install --server \ + --code-bin code-insiders \ # Target a specific editor (code, code-exploration, code-insiders, codium, or code-oss) + --dev-rel # Build in release mode with debug info level 2 ``` -In the output of this command, there should be a file path provided to the installed binary on your local machine. +In the output of this command, there should be a file path provided to the installed binary on your local machine. It should look something like the following output below: ``` @@ -48,9 +51,12 @@ An example debugging statement could go into the `main_loop.rs` file which can b ```rs eprintln!("Hello, world!"); ``` +Now, run the following commands to check the project and reinstall the server: -Now we run `cargo build` and `sh -cargo xtask install --server --code-bin code-insiders --dev-rel` to reinstall the server. +```sh +cargo check +cargo xtask install --server --code-bin code-insiders --dev-rel +``` Now on Visual Studio Code Insiders, we should be able to open the Output tab on our terminal and switch to Rust Analyzer Language Server to see the `eprintln!` statement we just wrote. From 7a60c49c649a91e47ee3e093d3bff95847e5cf4c Mon Sep 17 00:00:00 2001 From: Geoffry Song Date: Mon, 24 Feb 2025 18:24:22 -0800 Subject: [PATCH 295/991] Don't doc-comment BTreeMap --- library/alloc/src/collections/btree/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 6d305386dbfa..78b7da9d6b3e 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -289,7 +289,7 @@ impl Clone for BTreeMap { } } -/// Internal functionality for `BTreeSet`. +// Internal functionality for `BTreeSet`. impl BTreeMap { pub(super) fn replace(&mut self, key: K) -> Option where From d5a85af7c0a990dd05cb210fbfd0ca956e3a2000 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 25 Feb 2025 04:50:26 +0200 Subject: [PATCH 296/991] Support target features implications in target_feature 1.1 We vendor the list of implications, which isn't nice, but t-compiler doesn't want to make rustc_target available to us. --- .../rust-analyzer/crates/hir-ty/src/lib.rs | 6 +- .../crates/hir-ty/src/target_feature.rs | 259 ++++++++++++++++++ .../rust-analyzer/crates/hir-ty/src/utils.rs | 37 +-- .../src/handlers/missing_unsafe.rs | 2 +- 4 files changed, 268 insertions(+), 36 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 302be4836d96..707c43777267 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -36,6 +36,7 @@ mod inhabitedness; mod interner; mod lower; mod mapping; +mod target_feature; mod tls; mod utils; @@ -107,10 +108,9 @@ pub use mapping::{ to_foreign_def_id, to_placeholder_idx, }; pub use method_resolution::check_orphan_rules; +pub use target_feature::TargetFeatures; pub use traits::TraitEnvironment; -pub use utils::{ - all_super_traits, direct_super_traits, is_fn_unsafe_to_call, TargetFeatures, Unsafety, -}; +pub use utils::{all_super_traits, direct_super_traits, is_fn_unsafe_to_call, Unsafety}; pub use variance::Variance; pub use chalk_ir::{ diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs new file mode 100644 index 000000000000..17a1b8efee36 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs @@ -0,0 +1,259 @@ +//! Stuff for handling `#[target_feature]` (needed for unsafe check). + +use std::sync::LazyLock; + +use hir_def::attr::Attrs; +use hir_def::tt; +use intern::{sym, Symbol}; +use rustc_hash::{FxHashMap, FxHashSet}; + +#[derive(Debug, Default)] +pub struct TargetFeatures { + pub(crate) enabled: FxHashSet, +} + +impl TargetFeatures { + pub fn from_attrs(attrs: &Attrs) -> Self { + let mut result = TargetFeatures::from_attrs_no_implications(attrs); + result.expand_implications(); + result + } + + fn expand_implications(&mut self) { + let all_implications = LazyLock::force(&TARGET_FEATURE_IMPLICATIONS); + let mut queue = self.enabled.iter().cloned().collect::>(); + while let Some(feature) = queue.pop() { + if let Some(implications) = all_implications.get(&feature) { + for implication in implications { + if self.enabled.insert(implication.clone()) { + queue.push(implication.clone()); + } + } + } + } + } + + /// Retrieves the target features from the attributes, and does not expand the target features implied by them. + pub(crate) fn from_attrs_no_implications(attrs: &Attrs) -> Self { + let enabled = attrs + .by_key(&sym::target_feature) + .tt_values() + .filter_map(|tt| { + match tt.token_trees().flat_tokens() { + [ + tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)), + tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })), + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, symbol: features, .. })), + ] if enable_ident.sym == sym::enable => Some(features), + _ => None, + } + }) + .flat_map(|features| features.as_str().split(',').map(Symbol::intern)) + .collect(); + Self { enabled } + } +} + +// List of the target features each target feature implies. +// Ideally we'd depend on rustc for this, but rustc_target doesn't compile on stable, +// and t-compiler prefers for it to stay this way. + +static TARGET_FEATURE_IMPLICATIONS: LazyLock>> = + LazyLock::new(|| { + let mut result = FxHashMap::>::default(); + for &(feature_str, implications) in TARGET_FEATURE_IMPLICATIONS_RAW { + let feature = Symbol::intern(feature_str); + let implications = implications.iter().copied().map(Symbol::intern); + // Some target features appear in two archs, e.g. Arm and x86. + // Sometimes they contain different implications, e.g. `aes`. + // We should probably choose by the active arch, but for now just merge them. + result.entry(feature).or_default().extend(implications); + } + let mut result = result + .into_iter() + .map(|(feature, implications)| (feature, Box::from_iter(implications))) + .collect::>(); + result.shrink_to_fit(); + result + }); + +const TARGET_FEATURE_IMPLICATIONS_RAW: &[(&str, &[&str])] = &[ + // Arm + ("aes", &["neon"]), + ("dotprod", &["neon"]), + ("fp-armv8", &["vfp4"]), + ("fp16", &["neon"]), + ("i8mm", &["neon"]), + ("neon", &["vfp3"]), + ("sha2", &["neon"]), + ("v6", &["v5te"]), + ("v6k", &["v6"]), + ("v6t2", &["v6k", "thumb2"]), + ("v7", &["v6t2"]), + ("v8", &["v7"]), + ("vfp3", &["vfp2", "d32"]), + ("vfp4", &["vfp3"]), + // Aarch64 + ("aes", &["neon"]), + ("dotprod", &["neon"]), + ("dpb2", &["dpb"]), + ("f32mm", &["sve"]), + ("f64mm", &["sve"]), + ("fcma", &["neon"]), + ("fhm", &["fp16"]), + ("fp16", &["neon"]), + ("fp8", &["faminmax", "lut", "bf16"]), + ("fp8dot2", &["fp8dot4"]), + ("fp8dot4", &["fp8fma"]), + ("fp8fma", &["fp8"]), + ("jsconv", &["neon"]), + ("lse128", &["lse"]), + ("rcpc2", &["rcpc"]), + ("rcpc3", &["rcpc2"]), + ("rdm", &["neon"]), + ("sha2", &["neon"]), + ("sha3", &["sha2"]), + ("sm4", &["neon"]), + ("sme", &["bf16"]), + ("sme-b16b16", &["bf16", "sme2", "sve-b16b16"]), + ("sme-f16f16", &["sme2"]), + ("sme-f64f64", &["sme"]), + ("sme-f8f16", &["sme-f8f32"]), + ("sme-f8f32", &["sme2", "fp8"]), + ("sme-fa64", &["sme", "sve2"]), + ("sme-i16i64", &["sme"]), + ("sme2", &["sme"]), + ("sme2p1", &["sme2"]), + ("ssve-fp8dot2", &["ssve-fp8dot4"]), + ("ssve-fp8dot4", &["ssve-fp8fma"]), + ("ssve-fp8fma", &["sme2", "fp8"]), + ("sve", &["neon"]), + ("sve-b16b16", &["bf16"]), + ("sve2", &["sve"]), + ("sve2-aes", &["sve2", "aes"]), + ("sve2-bitperm", &["sve2"]), + ("sve2-sha3", &["sve2", "sha3"]), + ("sve2-sm4", &["sve2", "sm4"]), + ("sve2p1", &["sve2"]), + ("v8.1a", &["crc", "lse", "rdm", "pan", "lor", "vh"]), + ("v8.2a", &["v8.1a", "ras", "dpb"]), + ("v8.3a", &["v8.2a", "rcpc", "paca", "pacg", "jsconv"]), + ("v8.4a", &["v8.3a", "dotprod", "dit", "flagm"]), + ("v8.5a", &["v8.4a", "ssbs", "sb", "dpb2", "bti"]), + ("v8.6a", &["v8.5a", "bf16", "i8mm"]), + ("v8.7a", &["v8.6a", "wfxt"]), + ("v8.8a", &["v8.7a", "hbc", "mops"]), + ("v8.9a", &["v8.8a", "cssc"]), + ("v9.1a", &["v9a", "v8.6a"]), + ("v9.2a", &["v9.1a", "v8.7a"]), + ("v9.3a", &["v9.2a", "v8.8a"]), + ("v9.4a", &["v9.3a", "v8.9a"]), + ("v9.5a", &["v9.4a"]), + ("v9a", &["v8.5a", "sve2"]), + // x86 + ("aes", &["sse2"]), + ("amx-bf16", &["amx-tile"]), + ("amx-complex", &["amx-tile"]), + ("amx-fp16", &["amx-tile"]), + ("amx-int8", &["amx-tile"]), + ("avx", &["sse4.2"]), + ("avx2", &["avx"]), + ("avx512bf16", &["avx512bw"]), + ("avx512bitalg", &["avx512bw"]), + ("avx512bw", &["avx512f"]), + ("avx512cd", &["avx512f"]), + ("avx512dq", &["avx512f"]), + ("avx512f", &["avx2", "fma", "f16c"]), + ("avx512fp16", &["avx512bw", "avx512vl", "avx512dq"]), + ("avx512ifma", &["avx512f"]), + ("avx512vbmi", &["avx512bw"]), + ("avx512vbmi2", &["avx512bw"]), + ("avx512vl", &["avx512f"]), + ("avx512vnni", &["avx512f"]), + ("avx512vp2intersect", &["avx512f"]), + ("avx512vpopcntdq", &["avx512f"]), + ("avxifma", &["avx2"]), + ("avxneconvert", &["avx2"]), + ("avxvnni", &["avx2"]), + ("avxvnniint16", &["avx2"]), + ("avxvnniint8", &["avx2"]), + ("f16c", &["avx"]), + ("fma", &["avx"]), + ("gfni", &["sse2"]), + ("kl", &["sse2"]), + ("pclmulqdq", &["sse2"]), + ("sha", &["sse2"]), + ("sha512", &["avx2"]), + ("sm3", &["avx"]), + ("sm4", &["avx2"]), + ("sse2", &["sse"]), + ("sse3", &["sse2"]), + ("sse4.1", &["ssse3"]), + ("sse4.2", &["sse4.1"]), + ("sse4a", &["sse3"]), + ("ssse3", &["sse3"]), + ("vaes", &["avx2", "aes"]), + ("vpclmulqdq", &["avx", "pclmulqdq"]), + ("widekl", &["kl"]), + ("xop", &[/*"fma4", */ "avx", "sse4a"]), + ("xsavec", &["xsave"]), + ("xsaveopt", &["xsave"]), + ("xsaves", &["xsave"]), + // Hexagon + ("hvx-length128b", &["hvx"]), + // PowerPC + ("power10-vector", &["power9-vector"]), + ("power8-altivec", &["altivec"]), + ("power8-crypto", &["power8-altivec"]), + ("power8-vector", &["vsx", "power8-altivec"]), + ("power9-altivec", &["power8-altivec"]), + ("power9-vector", &["power8-vector", "power9-altivec"]), + ("vsx", &["altivec"]), + // MIPS + // RISC-V + ("a", &["zaamo", "zalrsc"]), + ("d", &["f"]), + ("zabha", &["zaamo"]), + ("zdinx", &["zfinx"]), + ("zfh", &["zfhmin"]), + ("zfhmin", &["f"]), + ("zhinx", &["zhinxmin"]), + ("zhinxmin", &["zfinx"]), + ("zk", &["zkn", "zkr", "zkt"]), + ("zkn", &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]), + ("zks", &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]), + // WASM + ("relaxed-simd", &["simd128"]), + // BPF + ("alu32", &[]), + // CSKY + ("10e60", &["7e10"]), + ("2e3", &["e2"]), + ("3e3r2", &["3e3r1", "doloop"]), + ("3e3r3", &["doloop"]), + ("3e7", &["2e3"]), + ("7e10", &["3e7"]), + ("e1", &["elrw"]), + ("e2", &["e2"]), + ("mp", &["2e3"]), + ("mp1e2", &["3e7"]), + // LoongArch + ("d", &["f"]), + ("lasx", &["lsx"]), + ("lsx", &["d"]), + // IBM Z + ("nnp-assist", &["vector"]), + ("vector-enhancements-1", &["vector"]), + ("vector-enhancements-2", &["vector-enhancements-1"]), + ("vector-packed-decimal", &["vector"]), + ("vector-packed-decimal-enhancement", &["vector-packed-decimal"]), + ("vector-packed-decimal-enhancement-2", &["vector-packed-decimal-enhancement"]), + // SPARC + // m68k + ("isa-68010", &["isa-68000"]), + ("isa-68020", &["isa-68010"]), + ("isa-68030", &["isa-68020"]), + ("isa-68040", &["isa-68030", "isa-68882"]), + ("isa-68060", &["isa-68040"]), + ("isa-68882", &["isa-68881"]), +]; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index c131e97bc4cb..89d89fe2230a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -9,18 +9,16 @@ use chalk_ir::{ DebruijnIndex, }; use hir_def::{ - attr::Attrs, db::DefDatabase, generics::{WherePredicate, WherePredicateTypeTarget}, lang_item::LangItem, resolver::{HasResolver, TypeNs}, - tt, type_ref::{TraitBoundModifier, TypeRef}, EnumId, EnumVariantId, FunctionId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId, TypeOrConstParamId, }; use hir_expand::name::Name; -use intern::{sym, Symbol}; +use intern::sym; use rustc_abi::TargetDataLayout; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; @@ -32,8 +30,8 @@ use crate::{ db::HirDatabase, layout::{Layout, TagEncoding}, mir::pad16, - ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TraitRef, TraitRefExt, - Ty, WhereClause, + ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TargetFeatures, TraitRef, + TraitRefExt, Ty, WhereClause, }; pub(crate) fn fn_traits( @@ -267,32 +265,6 @@ impl<'a> ClosureSubst<'a> { } } -#[derive(Debug, Default)] -pub struct TargetFeatures { - enabled: FxHashSet, -} - -impl TargetFeatures { - pub fn from_attrs(attrs: &Attrs) -> Self { - let enabled = attrs - .by_key(&sym::target_feature) - .tt_values() - .filter_map(|tt| { - match tt.token_trees().flat_tokens() { - [ - tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)), - tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })), - tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, symbol: features, .. })), - ] if enable_ident.sym == sym::enable => Some(features), - _ => None, - } - }) - .flat_map(|features| features.as_str().split(',').map(Symbol::intern)) - .collect(); - Self { enabled } - } -} - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Unsafety { Safe, @@ -314,7 +286,8 @@ pub fn is_fn_unsafe_to_call( if data.has_target_feature() { // RFC 2396 . - let callee_target_features = TargetFeatures::from_attrs(&db.attrs(func.into())); + let callee_target_features = + TargetFeatures::from_attrs_no_implications(&db.attrs(func.into())); if !caller_target_features.enabled.is_superset(&callee_target_features.enabled) { return Unsafety::Unsafe; } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs index 323a5723d4a3..040aa2949aa9 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs @@ -854,7 +854,7 @@ fn main() { #[target_feature(enable = "avx")] fn foo() {} -#[target_feature(enable = "avx,avx2")] +#[target_feature(enable = "avx2")] fn bar() { foo(); } From 5c654dcb46f436a135c06aae736ec8792c4364c8 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 25 Feb 2025 05:00:49 +0200 Subject: [PATCH 297/991] Disable typos checker for the target feature names --- src/tools/rust-analyzer/.typos.toml | 2 ++ src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/tools/rust-analyzer/.typos.toml b/src/tools/rust-analyzer/.typos.toml index 0f2f9b1b2750..e938bddd4b12 100644 --- a/src/tools/rust-analyzer/.typos.toml +++ b/src/tools/rust-analyzer/.typos.toml @@ -18,6 +18,8 @@ extend-ignore-re = [ "INOUT", "optin", "=Pn", + # ignore `// spellchecker:off` until `// spellchecker:on` + "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on", ] [default.extend-words] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs index 17a1b8efee36..fe9416c6cfc6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs @@ -77,6 +77,7 @@ static TARGET_FEATURE_IMPLICATIONS: LazyLock>> = result }); +// spellchecker:off const TARGET_FEATURE_IMPLICATIONS_RAW: &[(&str, &[&str])] = &[ // Arm ("aes", &["neon"]), @@ -257,3 +258,4 @@ const TARGET_FEATURE_IMPLICATIONS_RAW: &[(&str, &[&str])] = &[ ("isa-68060", &["isa-68040"]), ("isa-68882", &["isa-68881"]), ]; +// spellchecker:on From 3835dc2a0449347cb79dc5d467a37d729e389609 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 25 Feb 2025 13:01:19 +0800 Subject: [PATCH 298/991] fix doc in library/core/src/sync/atomic.rs Signed-off-by: xizheyin --- library/core/src/sync/atomic.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 73180bde54aa..0f725ec56eca 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -3997,24 +3997,24 @@ unsafe fn atomic_umin(dst: *mut T, val: T, order: Ordering) -> T { /// /// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes /// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there -/// exist operations X and Y, both operating on some atomic object 'M' such +/// exist operations X and Y, both operating on some atomic object 'm' such /// that A is sequenced before X, Y is sequenced before B and Y observes -/// the change to M. This provides a happens-before dependence between A and B. +/// the change to m. This provides a happens-before dependence between A and B. /// /// ```text /// Thread 1 Thread 2 /// /// fence(Release); A -------------- -/// x.store(3, Relaxed); X --------- | +/// m.store(3, Relaxed); X --------- | /// | | /// | | -/// -------------> Y if x.load(Relaxed) == 3 { +/// -------------> Y if m.load(Relaxed) == 3 { /// |-------> B fence(Acquire); /// ... /// } /// ``` /// -/// Note that in the example above, it is crucial that the accesses to `x` are atomic. Fences cannot +/// Note that in the example above, it is crucial that the accesses to `m` are atomic. Fences cannot /// be used to establish synchronization among non-atomic accesses in different threads. However, /// thanks to the happens-before relationship between A and B, any non-atomic accesses that /// happen-before A are now also properly synchronized with any non-atomic accesses that From 88f5f1ef2cfc4c2ce7cd3b159e990871cb6f78de Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Feb 2025 08:14:07 +0100 Subject: [PATCH 299/991] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 6cd39fabeeee..b3e207f53b8b 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -e0be1a02626abef2878cb7f4aaef7ae409477112 +f5729cfed3c45e061e8a443677fc1d5ef9277df7 From 60a268998c606440de092452a6380dde749f89c5 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 25 Feb 2025 09:20:10 +0100 Subject: [PATCH 300/991] remove `simd_fpow` and `simd_fpowi` --- .../src/intrinsics/simd.rs | 58 ------------- .../rustc_codegen_gcc/src/intrinsic/simd.rs | 28 ++---- compiler/rustc_codegen_llvm/src/intrinsic.rs | 4 - .../rustc_hir_analysis/src/check/intrinsic.rs | 2 - compiler/rustc_span/src/symbol.rs | 2 - .../simd-intrinsic-float-pow.rs | 87 ------------------- .../simd-intrinsic-float-powi.rs | 87 ------------------- tests/ui/simd/intrinsic/float-math-pass.rs | 25 ++---- 8 files changed, 13 insertions(+), 280 deletions(-) delete mode 100644 tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs delete mode 100644 tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index fcccda62355c..0c13fa91f7a7 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -460,64 +460,6 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }); } - sym::simd_fpow => { - intrinsic_args!(fx, args => (a, b); intrinsic); - - if !a.layout().ty.is_simd() { - report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty); - return; - } - - simd_pair_for_each_lane(fx, a, b, ret, &|fx, lane_ty, _ret_lane_ty, a_lane, b_lane| { - match lane_ty.kind() { - ty::Float(FloatTy::F32) => fx.lib_call( - "powf", - vec![AbiParam::new(types::F32), AbiParam::new(types::F32)], - vec![AbiParam::new(types::F32)], - &[a_lane, b_lane], - )[0], - ty::Float(FloatTy::F64) => fx.lib_call( - "pow", - vec![AbiParam::new(types::F64), AbiParam::new(types::F64)], - vec![AbiParam::new(types::F64)], - &[a_lane, b_lane], - )[0], - _ => unreachable!("{:?}", lane_ty), - } - }); - } - - sym::simd_fpowi => { - intrinsic_args!(fx, args => (a, exp); intrinsic); - let exp = exp.load_scalar(fx); - - if !a.layout().ty.is_simd() { - report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty); - return; - } - - simd_for_each_lane( - fx, - a, - ret, - &|fx, lane_ty, _ret_lane_ty, lane| match lane_ty.kind() { - ty::Float(FloatTy::F32) => fx.lib_call( - "__powisf2", // compiler-builtins - vec![AbiParam::new(types::F32), AbiParam::new(types::I32)], - vec![AbiParam::new(types::F32)], - &[lane, exp], - )[0], - ty::Float(FloatTy::F64) => fx.lib_call( - "__powidf2", // compiler-builtins - vec![AbiParam::new(types::F64), AbiParam::new(types::I32)], - vec![AbiParam::new(types::F64)], - &[lane, exp], - )[0], - _ => unreachable!("{:?}", lane_ty), - }, - ); - } - sym::simd_fsin | sym::simd_fcos | sym::simd_fexp diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 84cd5b002fbb..8b454ab2a424 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -772,8 +772,6 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( sym::simd_floor => "floor", sym::simd_fma => "fma", sym::simd_relaxed_fma => "fma", // FIXME: this should relax to non-fused multiply-add when necessary - sym::simd_fpowi => "__builtin_powi", - sym::simd_fpow => "pow", sym::simd_fsin => "sin", sym::simd_fsqrt => "sqrt", sym::simd_round => "round", @@ -788,24 +786,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let mut vector_elements = vec![]; for i in 0..in_len { let index = bx.context.new_rvalue_from_long(bx.ulong_type, i as i64); - // we have to treat fpowi specially, since fpowi's second argument is always an i32 let mut arguments = vec![]; - if name == sym::simd_fpowi { - arguments = vec![ - bx.extract_element(args[0].immediate(), index).to_rvalue(), - args[1].immediate(), - ]; - } else { - for arg in args { - let mut element = bx.extract_element(arg.immediate(), index).to_rvalue(); - // FIXME: it would probably be better to not have casts here and use the proper - // instructions. - if let Some(typ) = cast_type { - element = bx.context.new_cast(None, element, typ); - } - arguments.push(element); + for arg in args { + let mut element = bx.extract_element(arg.immediate(), index).to_rvalue(); + // FIXME: it would probably be better to not have casts here and use the proper + // instructions. + if let Some(typ) = cast_type { + element = bx.context.new_cast(None, element, typ); } - }; + arguments.push(element); + } let mut result = bx.context.new_call(None, function, &arguments); if cast_type.is_some() { result = bx.context.new_cast(None, result, elem_ty); @@ -829,8 +819,6 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( | sym::simd_floor | sym::simd_fma | sym::simd_relaxed_fma - | sym::simd_fpow - | sym::simd_fpowi | sym::simd_fsin | sym::simd_fsqrt | sym::simd_round diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7e1a9d361e6f..2d8edb1cddd0 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1587,8 +1587,6 @@ fn generic_simd_intrinsic<'ll, 'tcx>( sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)), sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)), sym::simd_relaxed_fma => ("fmuladd", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)), - sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)), - sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)), sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)), sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), @@ -1621,8 +1619,6 @@ fn generic_simd_intrinsic<'ll, 'tcx>( | sym::simd_flog | sym::simd_floor | sym::simd_fma - | sym::simd_fpow - | sym::simd_fpowi | sym::simd_fsin | sym::simd_fsqrt | sym::simd_relaxed_fma diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 08e0e52a4925..41822c14ba3a 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -651,7 +651,6 @@ pub fn check_intrinsic_type( | sym::simd_xor | sym::simd_fmin | sym::simd_fmax - | sym::simd_fpow | sym::simd_saturating_add | sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)), sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)), @@ -674,7 +673,6 @@ pub fn check_intrinsic_type( | sym::simd_floor | sym::simd_round | sym::simd_trunc => (1, 0, vec![param(0)], param(0)), - sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)), sym::simd_fma | sym::simd_relaxed_fma => { (1, 0, vec![param(0), param(0), param(0)], param(0)) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d4d435d9b746..c2a8545de785 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1886,8 +1886,6 @@ symbols! { simd_fma, simd_fmax, simd_fmin, - simd_fpow, - simd_fpowi, simd_fsin, simd_fsqrt, simd_gather, diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs deleted file mode 100644 index 3527f71c00b4..000000000000 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs +++ /dev/null @@ -1,87 +0,0 @@ -//@ compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); - -extern "rust-intrinsic" { - fn simd_fpow(x: T, b: T) -> T; -} - -// CHECK-LABEL: @fpow_32x2 -#[no_mangle] -pub unsafe fn fpow_32x2(a: f32x2, b: f32x2) -> f32x2 { - // CHECK: call <2 x float> @llvm.pow.v2f32 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_32x4 -#[no_mangle] -pub unsafe fn fpow_32x4(a: f32x4, b: f32x4) -> f32x4 { - // CHECK: call <4 x float> @llvm.pow.v4f32 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_32x8 -#[no_mangle] -pub unsafe fn fpow_32x8(a: f32x8, b: f32x8) -> f32x8 { - // CHECK: call <8 x float> @llvm.pow.v8f32 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_32x16 -#[no_mangle] -pub unsafe fn fpow_32x16(a: f32x16, b: f32x16) -> f32x16 { - // CHECK: call <16 x float> @llvm.pow.v16f32 - simd_fpow(a, b) -} - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - -// CHECK-LABEL: @fpow_64x4 -#[no_mangle] -pub unsafe fn fpow_64x4(a: f64x4, b: f64x4) -> f64x4 { - // CHECK: call <4 x double> @llvm.pow.v4f64 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_64x2 -#[no_mangle] -pub unsafe fn fpow_64x2(a: f64x2, b: f64x2) -> f64x2 { - // CHECK: call <2 x double> @llvm.pow.v2f64 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_64x8 -#[no_mangle] -pub unsafe fn fpow_64x8(a: f64x8, b: f64x8) -> f64x8 { - // CHECK: call <8 x double> @llvm.pow.v8f64 - simd_fpow(a, b) -} diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs deleted file mode 100644 index 4f0b5e4e01a3..000000000000 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs +++ /dev/null @@ -1,87 +0,0 @@ -//@ compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); - -extern "rust-intrinsic" { - fn simd_fpowi(x: T, b: i32) -> T; -} - -// CHECK-LABEL: @fpowi_32x2 -#[no_mangle] -pub unsafe fn fpowi_32x2(a: f32x2, b: i32) -> f32x2 { - // CHECK: call <2 x float> @llvm.powi.v2f32 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_32x4 -#[no_mangle] -pub unsafe fn fpowi_32x4(a: f32x4, b: i32) -> f32x4 { - // CHECK: call <4 x float> @llvm.powi.v4f32 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_32x8 -#[no_mangle] -pub unsafe fn fpowi_32x8(a: f32x8, b: i32) -> f32x8 { - // CHECK: call <8 x float> @llvm.powi.v8f32 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_32x16 -#[no_mangle] -pub unsafe fn fpowi_32x16(a: f32x16, b: i32) -> f32x16 { - // CHECK: call <16 x float> @llvm.powi.v16f32 - simd_fpowi(a, b) -} - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - -// CHECK-LABEL: @fpowi_64x4 -#[no_mangle] -pub unsafe fn fpowi_64x4(a: f64x4, b: i32) -> f64x4 { - // CHECK: call <4 x double> @llvm.powi.v4f64 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_64x2 -#[no_mangle] -pub unsafe fn fpowi_64x2(a: f64x2, b: i32) -> f64x2 { - // CHECK: call <2 x double> @llvm.powi.v2f64 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_64x8 -#[no_mangle] -pub unsafe fn fpowi_64x8(a: f64x8, b: i32) -> f64x8 { - // CHECK: call <8 x double> @llvm.powi.v8f64 - simd_fpowi(a, b) -} diff --git a/tests/ui/simd/intrinsic/float-math-pass.rs b/tests/ui/simd/intrinsic/float-math-pass.rs index 74cb51a06068..91059f353fd9 100644 --- a/tests/ui/simd/intrinsic/float-math-pass.rs +++ b/tests/ui/simd/intrinsic/float-math-pass.rs @@ -48,13 +48,6 @@ unsafe fn simd_flog10(x: T) -> T; #[rustc_intrinsic] unsafe fn simd_flog2(x: T) -> T; -#[rustc_intrinsic] -unsafe fn simd_fpow(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_fpowi(x: T, y: i32) -> T; - - // rounding functions #[rustc_intrinsic] unsafe fn simd_ceil(x: T) -> T; @@ -68,23 +61,21 @@ unsafe fn simd_round(x: T) -> T; #[rustc_intrinsic] unsafe fn simd_trunc(x: T) -> T; - macro_rules! assert_approx_eq_f32 { - ($a:expr, $b:expr) => ({ + ($a:expr, $b:expr) => {{ let (a, b) = (&$a, &$b); - assert!((*a - *b).abs() < 1.0e-6, - "{} is not approximately equal to {}", *a, *b); - }) + assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b); + }}; } macro_rules! assert_approx_eq { - ($a:expr, $b:expr) => ({ + ($a:expr, $b:expr) => {{ let a = $a; let b = $b; assert_approx_eq_f32!(a.0[0], b.0[0]); assert_approx_eq_f32!(a.0[1], b.0[1]); assert_approx_eq_f32!(a.0[2], b.0[2]); assert_approx_eq_f32!(a.0[3], b.0[3]); - }) + }}; } fn main() { @@ -125,12 +116,6 @@ fn main() { let r = simd_flog10(x); assert_approx_eq!(z, r); - let r = simd_fpow(h, x); - assert_approx_eq!(h, r); - - let r = simd_fpowi(h, 1); - assert_approx_eq!(h, r); - let r = simd_fsin(z); assert_approx_eq!(z, r); From 5e4c582b3e125c1260d05609aee276155b0e9b72 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Feb 2025 09:35:15 +0100 Subject: [PATCH 301/991] disable a potentially bogus test on Miri --- library/coretests/tests/num/int_log.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/coretests/tests/num/int_log.rs b/library/coretests/tests/num/int_log.rs index 60902752dab6..9c630a61dd5b 100644 --- a/library/coretests/tests/num/int_log.rs +++ b/library/coretests/tests/num/int_log.rs @@ -34,6 +34,7 @@ fn checked_ilog() { } #[test] +#[cfg_attr(miri, ignore)] // FIXME test is broken on Miri: https://github.com/rust-lang/rust/issues/137591 fn checked_ilog2() { assert_eq!(5u32.checked_ilog2(), Some(2)); assert_eq!(0u64.checked_ilog2(), None); From 8467a7658133fdc274e18f36357768000a3a7519 Mon Sep 17 00:00:00 2001 From: klensy Date: Mon, 24 Feb 2025 12:25:17 +0300 Subject: [PATCH 302/991] remove unused field from VariantDef::new and convert debug to instrument --- compiler/rustc_hir_analysis/src/collect.rs | 1 - compiler/rustc_metadata/src/rmeta/decoder.rs | 1 - compiler/rustc_middle/src/ty/mod.rs | 8 +------- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 5bb77c096dcf..1a0d1cc7b9f0 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1075,7 +1075,6 @@ fn lower_variant<'tcx>( def.ctor().map(|(kind, _, def_id)| (kind, def_id.to_def_id())), discr, fields, - adt_kind, parent_did.to_def_id(), recovered, adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index e8dcda875e67..93594ff0f9a0 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1118,7 +1118,6 @@ impl<'a> CrateMetadataRef<'a> { value: self.get_default_field(did.index), }) .collect(), - adt_kind, parent_did, None, data.is_non_exhaustive, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index bd1fb0ca41cf..c44dca91fd97 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1183,23 +1183,17 @@ impl VariantDef { /// /// If someone speeds up attribute loading to not be a performance concern, they can /// remove this hack and use the constructor `DefId` everywhere. + #[instrument(level = "debug")] pub fn new( name: Symbol, variant_did: Option, ctor: Option<(CtorKind, DefId)>, discr: VariantDiscr, fields: IndexVec, - adt_kind: AdtKind, parent_did: DefId, recover_tainted: Option, is_field_list_non_exhaustive: bool, ) -> Self { - debug!( - "VariantDef::new(name = {:?}, variant_did = {:?}, ctor = {:?}, discr = {:?}, - fields = {:?}, adt_kind = {:?}, parent_did = {:?})", - name, variant_did, ctor, discr, fields, adt_kind, parent_did, - ); - let mut flags = VariantFlags::NO_VARIANT_FLAGS; if is_field_list_non_exhaustive { flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; From 00e80e7b8b436430b4f4d065f0fde1646eff6a76 Mon Sep 17 00:00:00 2001 From: Colin Pitrat Date: Tue, 25 Feb 2025 11:47:11 +0000 Subject: [PATCH 303/991] Complete the list of resources used in rustdoc output --- src/librustdoc/html/static/COPYRIGHT.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/librustdoc/html/static/COPYRIGHT.txt b/src/librustdoc/html/static/COPYRIGHT.txt index 111340298c5e..84826e5d077d 100644 --- a/src/librustdoc/html/static/COPYRIGHT.txt +++ b/src/librustdoc/html/static/COPYRIGHT.txt @@ -45,6 +45,17 @@ included, and carry their own copyright notices and license terms: Licensed under the SIL Open Font License, Version 1.1. See SourceSerif4-LICENSE.md. +* Nanum Barun Gothic Font (NanumBarunGothic.woff2) + + Copyright 2017 NAVER, free for personal and commercial use. + https://hangeul.naver.com/2017/nanum + +* Rust logos (rust-logo.svg, favicon.svg, favicon-32x32.png) + + Copyright 2025 Rust Foundation. + Licensed under the Creative Commons Attribution license (CC-BY). + https://rustfoundation.org/policy/rust-trademark-policy/ + This copyright file is intended to be distributed with rustdoc output. # REUSE-IgnoreEnd From cb53e9787099f0837a008ca3b41af5e97cf81f2e Mon Sep 17 00:00:00 2001 From: Vayun Biyani Date: Tue, 25 Feb 2025 17:25:50 +0530 Subject: [PATCH 304/991] Fix enzyme build errors --- compiler/rustc_builtin_macros/src/autodiff.rs | 8 ++++---- compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 8d7ac6de8010..cad041c7deba 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -133,7 +133,7 @@ mod llvm_enzyme { let dcx = ecx.sess.dcx(); // first get the annotable item: let (sig, is_impl): (FnSig, bool) = match &item { - Annotatable::Item(ref iitem) => { + Annotatable::Item(iitem) => { let sig = match &iitem.kind { ItemKind::Fn(box ast::Fn { sig, .. }) => sig, _ => { @@ -143,7 +143,7 @@ mod llvm_enzyme { }; (sig.clone(), false) } - Annotatable::AssocItem(ref assoc_item, _) => { + Annotatable::AssocItem(assoc_item, _) => { let sig = match &assoc_item.kind { ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig, _ => { @@ -171,8 +171,8 @@ mod llvm_enzyme { let sig_span = ecx.with_call_site_ctxt(sig.span); let (vis, primal) = match &item { - Annotatable::Item(ref iitem) => (iitem.vis.clone(), iitem.ident.clone()), - Annotatable::AssocItem(ref assoc_item, _) => { + Annotatable::Item(iitem) => (iitem.vis.clone(), iitem.ident.clone()), + Annotatable::AssocItem(assoc_item, _) => { (assoc_item.vis.clone(), assoc_item.ident.clone()) } _ => { diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 3c2c6964a3d7..25ca34988034 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -42,10 +42,10 @@ pub use self::Enzyme_AD::*; #[cfg(llvm_enzyme)] pub mod Enzyme_AD { use libc::c_void; - extern "C" { + unsafe extern "C" { pub fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8); } - extern "C" { + unsafe extern "C" { static mut EnzymePrintPerf: c_void; static mut EnzymePrintActivity: c_void; static mut EnzymePrintType: c_void; From 7058f62d0a57d94eb25047741460656f1b14e566 Mon Sep 17 00:00:00 2001 From: Mahmoud Mazouz Date: Tue, 25 Feb 2025 13:09:09 +0100 Subject: [PATCH 305/991] Use `.expect(..)` instead --- library/std/src/thread/mod.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index d9e28acdcdac..3f3ba02361cc 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1739,11 +1739,16 @@ struct JoinInner<'scope, T> { impl<'scope, T> JoinInner<'scope, T> { fn join(mut self) -> Result { self.native.join(); - if let Some(packet) = Arc::get_mut(&mut self.packet) { - packet.result.get_mut().take().unwrap() - } else { - Err(Box::new("thread terminated unexpectedly")) - } + Arc::get_mut(&mut self.packet) + // FIXME(fuzzypixelz): returning an error instead of panicking here + // would require updating the documentation of + // `std::thread::Result`; currently we can return `Err` if and only + // if the thread had panicked. + .expect("threads should not terminate unexpectedly") + .result + .get_mut() + .take() + .unwrap() } } From eaf8fc56d7695b5d6681518a74c4bf8050a4ff5e Mon Sep 17 00:00:00 2001 From: Colin Pitrat Date: Tue, 25 Feb 2025 12:24:30 +0000 Subject: [PATCH 306/991] Update information about NanumBarunGothic --- src/librustdoc/html/static/COPYRIGHT.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/COPYRIGHT.txt b/src/librustdoc/html/static/COPYRIGHT.txt index 84826e5d077d..752dab0a3478 100644 --- a/src/librustdoc/html/static/COPYRIGHT.txt +++ b/src/librustdoc/html/static/COPYRIGHT.txt @@ -47,8 +47,18 @@ included, and carry their own copyright notices and license terms: * Nanum Barun Gothic Font (NanumBarunGothic.woff2) - Copyright 2017 NAVER, free for personal and commercial use. + Copyright 2010, NAVER Corporation (http://www.nhncorp.com) + with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, + NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, + Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, + Naver NanumMyeongjoEco, NanumMyeongjoEco, Naver NanumGothicLight, + NanumGothicLight, NanumBarunGothic, Naver NanumBarunGothic. + https://hangeul.naver.com/2017/nanum + https://github.com/hiun/NanumBarunGothic + + Licensed under the SIL Open Font License, Version 1.1. + See NanumBarunGothic-LICENSE.txt. * Rust logos (rust-logo.svg, favicon.svg, favicon-32x32.png) From 48483adcb42ea07858800cf9c0be6531e204c6b7 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 25 Feb 2025 21:21:00 +0800 Subject: [PATCH 307/991] fix doc in library/core/src/pin.rs Signed-off-by: xizheyin --- library/core/src/pin.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 2a0bf89fcf7a..7fcd19f67ee2 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1240,8 +1240,8 @@ impl Pin { /// points to is pinned, that is a violation of the API contract and may lead to undefined /// behavior in later (even safe) operations. /// - /// By using this method, you are also making a promise about the [`Deref`] and - /// [`DerefMut`] implementations of `Ptr`, if they exist. Most importantly, they + /// By using this method, you are also making a promise about the [`Deref`], + /// [`DerefMut`], and [`Drop`] implementations of `Ptr`, if they exist. Most importantly, they /// must not move out of their `self` arguments: `Pin::as_mut` and `Pin::as_ref` /// will call `DerefMut::deref_mut` and `Deref::deref` *on the pointer type `Ptr`* /// and expect these methods to uphold the pinning invariants. From 41a7c8312d9b21bbf96da0d39b5650dde03ec7ef Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Tue, 25 Feb 2025 13:08:59 +0000 Subject: [PATCH 308/991] Skip `tidy` in pre-push hook if the user is deleting a remote branch --- src/etc/pre-push.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh index 6f86c7ab8a44..7bacc943f258 100755 --- a/src/etc/pre-push.sh +++ b/src/etc/pre-push.sh @@ -7,6 +7,20 @@ set -Euo pipefail +# Check if the push is doing anything other than deleting remote branches +SKIP=true +while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do + if [[ "$LOCAL_REF" != "(delete)" || \ + "$LOCAL_SHA" != "0000000000000000000000000000000000000000" ]]; then + SKIP=false + fi +done + +if $SKIP; then + echo "Skipping tidy check for branch deletion" + exit 0 +fi + ROOT_DIR="$(git rev-parse --show-toplevel)" echo "Running pre-push script $ROOT_DIR/x test tidy" From 622b4fac824a8dc166fddb73ca521b2a4caa1bc8 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Tue, 25 Feb 2025 16:07:05 +0100 Subject: [PATCH 309/991] fix: attr cast for espidf --- library/std/src/sys/pal/unix/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 37d5e01790a0..4c5757b890ad 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -59,7 +59,7 @@ impl Thread { assert_eq!( libc::pthread_attr_setstacksize( attr.as_mut_ptr(), - cmp::max(stack, min_stack_size(&attr)) + cmp::max(stack, min_stack_size(attr.as_ptr())) ), 0 ); From f7adafc7a31192f23e1c2707714662d14251ec53 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:33:21 -0600 Subject: [PATCH 310/991] internal: Improve reporting of intersecting changes --- .../crates/syntax/src/syntax_editor.rs | 59 +++++++++++++ .../syntax/src/syntax_editor/edit_algo.rs | 87 +++++++++++++++++-- .../crates/test-utils/src/lib.rs | 4 +- 3 files changed, 142 insertions(+), 8 deletions(-) diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs index b82181ae13ad..48c160b9a9ac 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs @@ -5,6 +5,7 @@ //! [`SyntaxEditor`]: https://github.com/dotnet/roslyn/blob/43b0b05cc4f492fd5de00f6f6717409091df8daa/src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs use std::{ + fmt, num::NonZeroU32, ops::RangeInclusive, sync::atomic::{AtomicU32, Ordering}, @@ -282,6 +283,64 @@ enum ChangeKind { Replace, } +impl fmt::Display for Change { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Change::Insert(position, node_or_token) => { + let parent = position.parent(); + let mut parent_str = parent.to_string(); + let target_range = self.target_range().start() - parent.text_range().start(); + + parent_str.insert_str( + target_range.into(), + &format!("\x1b[42m{node_or_token}\x1b[0m\x1b[K"), + ); + f.write_str(&parent_str) + } + Change::InsertAll(position, vec) => { + let parent = position.parent(); + let mut parent_str = parent.to_string(); + let target_range = self.target_range().start() - parent.text_range().start(); + let insertion: String = vec.iter().map(|it| it.to_string()).collect(); + + parent_str + .insert_str(target_range.into(), &format!("\x1b[42m{insertion}\x1b[0m\x1b[K")); + f.write_str(&parent_str) + } + Change::Replace(old, new) => { + if let Some(new) = new { + write!(f, "\x1b[41m{old}\x1b[42m{new}\x1b[0m\x1b[K") + } else { + write!(f, "\x1b[41m{old}\x1b[0m\x1b[K") + } + } + Change::ReplaceWithMany(old, vec) => { + let new: String = vec.iter().map(|it| it.to_string()).collect(); + write!(f, "\x1b[41m{old}\x1b[42m{new}\x1b[0m\x1b[K") + } + Change::ReplaceAll(range, vec) => { + let parent = range.start().parent().unwrap(); + let parent_str = parent.to_string(); + let pre_range = + TextRange::new(parent.text_range().start(), range.start().text_range().start()); + let old_range = TextRange::new( + range.start().text_range().start(), + range.end().text_range().end(), + ); + let post_range = + TextRange::new(range.end().text_range().end(), parent.text_range().end()); + + let pre_str = &parent_str[pre_range - parent.text_range().start()]; + let old_str = &parent_str[old_range - parent.text_range().start()]; + let post_str = &parent_str[post_range - parent.text_range().start()]; + let new: String = vec.iter().map(|it| it.to_string()).collect(); + + write!(f, "{pre_str}\x1b[41m{old_str}\x1b[42m{new}\x1b[0m\x1b[K{post_str}") + } + } + } +} + /// Utility trait to allow calling syntax editor functions with references or owned /// nodes. Do not use outside of this module. pub trait Element { diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs index 57ecbe57019b..d6d903715d10 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs @@ -1,9 +1,14 @@ //! Implementation of applying changes to a syntax tree. -use std::{cmp::Ordering, collections::VecDeque, ops::RangeInclusive}; +use std::{ + cmp::Ordering, + collections::VecDeque, + ops::{Range, RangeInclusive}, +}; use rowan::TextRange; use rustc_hash::FxHashMap; +use stdx::format_to; use crate::{ syntax_editor::{mapping::MissingMapping, Change, ChangeKind, PositionRepr}, @@ -76,11 +81,9 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { || (l.target_range().end() <= r.target_range().start()) }); - if stdx::never!( - !disjoint_replaces_ranges, - "some replace change ranges intersect: {:?}", - changes - ) { + if !disjoint_replaces_ranges { + report_intersecting_changes(&changes, get_node_depth, &root); + return SyntaxEdit { old_root: root.clone(), new_root: root, @@ -293,6 +296,78 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { } } +fn report_intersecting_changes( + changes: &[Change], + mut get_node_depth: impl FnMut(rowan::SyntaxNode) -> usize, + root: &rowan::SyntaxNode, +) { + let intersecting_changes = changes + .iter() + .zip(changes.iter().skip(1)) + .filter(|(l, r)| { + // We only care about checking for disjoint replace ranges. + matches!( + (l.change_kind(), r.change_kind()), + ( + ChangeKind::Replace | ChangeKind::ReplaceRange, + ChangeKind::Replace | ChangeKind::ReplaceRange + ) + ) + }) + .filter(|(l, r)| { + get_node_depth(l.target_parent()) == get_node_depth(r.target_parent()) + && (l.target_range().end() > r.target_range().start()) + }); + + let mut error_msg = String::from("some replace change ranges intersect!\n"); + + let parent_str = root.to_string(); + + for (l, r) in intersecting_changes { + let mut highlighted_str = parent_str.clone(); + let l_range = l.target_range(); + let r_range = r.target_range(); + + let i_range = l_range.intersect(r_range).unwrap(); + let i_str = format!("\x1b[46m{}", &parent_str[i_range]); + + let pre_range: Range = l_range.start().into()..i_range.start().into(); + let pre_str = format!("\x1b[44m{}", &parent_str[pre_range]); + + let (highlight_range, highlight_str) = if l_range == r_range { + format_to!(error_msg, "\x1b[46mleft change:\x1b[0m {l:?} {l}\n"); + format_to!(error_msg, "\x1b[46mequals\x1b[0m\n"); + format_to!(error_msg, "\x1b[46mright change:\x1b[0m {r:?} {r}\n"); + let i_highlighted = format!("{i_str}\x1b[0m\x1b[K"); + let total_range: Range = i_range.into(); + (total_range, i_highlighted) + } else { + format_to!(error_msg, "\x1b[44mleft change:\x1b[0m {l:?} {l}\n"); + let range_end = if l_range.contains_range(r_range) { + format_to!(error_msg, "\x1b[46mcovers\x1b[0m\n"); + format_to!(error_msg, "\x1b[46mright change:\x1b[0m {r:?} {r}\n"); + l_range.end() + } else { + format_to!(error_msg, "\x1b[46mintersects\x1b[0m\n"); + format_to!(error_msg, "\x1b[42mright change:\x1b[0m {r:?} {r}\n"); + r_range.end() + }; + + let post_range: Range = i_range.end().into()..range_end.into(); + + let post_str = format!("\x1b[42m{}", &parent_str[post_range]); + let result = format!("{pre_str}{i_str}{post_str}\x1b[0m\x1b[K"); + let total_range: Range = l_range.start().into()..range_end.into(); + (total_range, result) + }; + highlighted_str.replace_range(highlight_range, &highlight_str); + + format_to!(error_msg, "{highlighted_str}\n"); + } + + stdx::always!(false, "{}", error_msg); +} + fn to_owning_node(element: &SyntaxElement) -> SyntaxNode { match element { SyntaxElement::Node(node) => node.clone(), diff --git a/src/tools/rust-analyzer/crates/test-utils/src/lib.rs b/src/tools/rust-analyzer/crates/test-utils/src/lib.rs index e7279fa1f661..d3afac85017f 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/lib.rs @@ -421,8 +421,8 @@ pub fn format_diff(chunks: Vec>) -> String { for chunk in chunks { let formatted = match chunk { dissimilar::Chunk::Equal(text) => text.into(), - dissimilar::Chunk::Delete(text) => format!("\x1b[41m{text}\x1b[0m"), - dissimilar::Chunk::Insert(text) => format!("\x1b[42m{text}\x1b[0m"), + dissimilar::Chunk::Delete(text) => format!("\x1b[41m{text}\x1b[0m\x1b[K"), + dissimilar::Chunk::Insert(text) => format!("\x1b[42m{text}\x1b[0m\x1b[K"), }; buf.push_str(&formatted); } From cac5153961f31fd6765be31d0dca4f1aeaa43631 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:34:37 -0600 Subject: [PATCH 311/991] internal: Migrate `remove_mut` assist to `SyntaxEditor` --- .../crates/ide-assists/src/handlers/remove_mut.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs index 0b299e8349ac..43740a5a6d5c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs @@ -1,4 +1,4 @@ -use syntax::{SyntaxKind, TextRange, T}; +use syntax::{SyntaxKind, T}; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -19,11 +19,6 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // ``` pub(crate) fn remove_mut(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let mut_token = ctx.find_token_syntax_at_offset(T![mut])?; - let delete_from = mut_token.text_range().start(); - let delete_to = match mut_token.next_token() { - Some(it) if it.kind() == SyntaxKind::WHITESPACE => it.text_range().end(), - _ => mut_token.text_range().end(), - }; let target = mut_token.text_range(); acc.add( @@ -31,7 +26,13 @@ pub(crate) fn remove_mut(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( "Remove `mut` keyword", target, |builder| { - builder.delete(TextRange::new(delete_from, delete_to)); + let mut editor = builder.make_editor(&mut_token.parent().unwrap()); + match mut_token.next_token() { + Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it), + _ => (), + } + editor.delete(mut_token); + builder.add_file_edits(ctx.file_id(), editor); }, ) } From 8036e841b099fe468bbc2b0d0a7592f00f950ae1 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 4 Dec 2024 19:51:15 -0500 Subject: [PATCH 312/991] internal: Migrate `remove_parentheses` assist to `SyntaxEditor` --- .../src/handlers/remove_parentheses.rs | 17 +++++++++++++---- .../docs/book/src/assists_generated.md | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs index f74fc2611282..143d5e542428 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs @@ -1,4 +1,8 @@ -use syntax::{ast, AstNode, SyntaxKind, T}; +use syntax::{ + ast::{self, syntax_factory::SyntaxFactory}, + syntax_editor::Position, + AstNode, SyntaxKind, T, +}; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -40,6 +44,7 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) -> "Remove redundant parentheses", target, |builder| { + let mut editor = builder.make_editor(parens.syntax()); let prev_token = parens.syntax().first_token().and_then(|it| it.prev_token()); let need_to_add_ws = match prev_token { Some(it) => { @@ -48,9 +53,13 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) -> } None => false, }; - let expr = if need_to_add_ws { format!(" {expr}") } else { expr.to_string() }; - - builder.replace(parens.syntax().text_range(), expr) + if need_to_add_ws { + let make = SyntaxFactory::new(); + editor.insert(Position::before(parens.syntax()), make.whitespace(" ")); + editor.add_mappings(make.finish_with_mappings()); + } + editor.replace(parens.syntax(), expr.syntax()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 52da98dbd21d..a05536e2d2d5 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -2974,7 +2974,7 @@ impl Walrus { ### `remove_parentheses` -**Source:** [remove_parentheses.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_parentheses.rs#L5) +**Source:** [remove_parentheses.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_parentheses.rs#L9) Removes redundant parentheses. From 1d5f831ffc0010e3483b780808960da3a13b64e5 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 4 Dec 2024 19:53:22 -0500 Subject: [PATCH 313/991] fix: Properly handle removals in `SyntaxEditor` --- .../syntax/src/syntax_editor/edit_algo.rs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs index d6d903715d10..fa51fb6eef42 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs @@ -102,6 +102,7 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { let mut changed_ancestors: VecDeque = VecDeque::new(); let mut dependent_changes = vec![]; let mut independent_changes = vec![]; + let mut outdated_changes = vec![]; for (change_index, change) in changes.iter().enumerate() { // Check if this change is dependent on another change (i.e. it's contained within another range) @@ -116,10 +117,14 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { // FIXME: Resolve changes that depend on a range of elements let ancestor = &changed_ancestors[index]; - dependent_changes.push(DependentChange { - parent: ancestor.change_index as u32, - child: change_index as u32, - }); + if let Change::Replace(_, None) = changes[ancestor.change_index] { + outdated_changes.push(change_index as u32); + } else { + dependent_changes.push(DependentChange { + parent: ancestor.change_index as u32, + child: change_index as u32, + }); + } } else { // This change is independent of any other change @@ -195,8 +200,9 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { Change::Replace(target, Some(new_target)) => { (to_owning_node(target), to_owning_node(new_target)) } - // Silently drop outdated change - Change::Replace(_, None) => continue, + Change::Replace(_, None) => { + unreachable!("deletions should not generate dependent changes") + } Change::ReplaceAll(_, _) | Change::ReplaceWithMany(_, _) => { unimplemented!("cannot resolve changes that depend on replacing many elements") } @@ -234,6 +240,12 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { } } + // We reverse here since we pushed to this in ascending order, + // and we want to remove elements in descending order + for idx in outdated_changes.into_iter().rev() { + changes.remove(idx as usize); + } + // Apply changes let mut root = tree_mutator.mutable_clone; From 6e6e7e966910e7dc5776f760f4848af740a1c581 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 4 Dec 2024 19:55:16 -0500 Subject: [PATCH 314/991] internal: Migrate `remove_unused_param` assist to `SyntaxEditor` --- .../src/handlers/remove_unused_param.rs | 62 ++++++++++++++----- .../rust-analyzer/crates/syntax/src/algo.rs | 24 ++++++- .../docs/book/src/assists_generated.md | 2 +- 3 files changed, 71 insertions(+), 17 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs index 75120768da0f..5ddb17b20729 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs @@ -1,8 +1,9 @@ use ide_db::{defs::Definition, search::FileReference, EditionedFileId}; use syntax::{ - algo::find_node_at_range, + algo::{find_node_at_range, least_common_ancestor_element}, ast::{self, HasArgList}, - AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, T, + syntax_editor::Element, + AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, T, }; use SyntaxKind::WHITESPACE; @@ -74,15 +75,21 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) -> cov_mark::hit!(keep_used); return None; } + let parent = param.syntax().parent()?; acc.add( AssistId("remove_unused_param", AssistKind::Refactor), "Remove unused parameter", param.syntax().text_range(), |builder| { - builder.delete(range_to_remove(param.syntax())); + let mut editor = builder.make_editor(&parent); + let elements = elements_to_remove(param.syntax()); + for element in elements { + editor.delete(element); + } for (file_id, references) in fn_def.usages(&ctx.sema).all() { process_usages(ctx, builder, file_id, references, param_position, is_self_present); } + builder.add_file_edits(ctx.file_id(), editor); }, ) } @@ -96,20 +103,24 @@ fn process_usages( is_self_present: bool, ) { let source_file = ctx.sema.parse(file_id); - builder.edit_file(file_id); let possible_ranges = references .into_iter() .filter_map(|usage| process_usage(&source_file, usage, arg_to_remove, is_self_present)); - let mut ranges_to_delete: Vec = vec![]; - for range in possible_ranges { - if !ranges_to_delete.iter().any(|it| it.contains_range(range)) { - ranges_to_delete.push(range) + for element_range in possible_ranges { + let Some(SyntaxElement::Node(parent)) = element_range + .iter() + .cloned() + .reduce(|a, b| least_common_ancestor_element(&a, &b).unwrap().syntax_element()) + else { + continue; + }; + let mut editor = builder.make_editor(&parent); + for element in element_range { + editor.delete(element); } - } - for range in ranges_to_delete { - builder.delete(range) + builder.add_file_edits(file_id, editor); } } @@ -118,7 +129,7 @@ fn process_usage( FileReference { range, .. }: FileReference, mut arg_to_remove: usize, is_self_present: bool, -) -> Option { +) -> Option> { let call_expr_opt: Option = find_node_at_range(source_file.syntax(), range); if let Some(call_expr) = call_expr_opt { let call_expr_range = call_expr.expr()?.syntax().text_range(); @@ -127,7 +138,7 @@ fn process_usage( } let arg = call_expr.arg_list()?.args().nth(arg_to_remove)?; - return Some(range_to_remove(arg.syntax())); + return Some(elements_to_remove(arg.syntax())); } let method_call_expr_opt: Option = @@ -143,7 +154,7 @@ fn process_usage( } let arg = method_call_expr.arg_list()?.args().nth(arg_to_remove)?; - return Some(range_to_remove(arg.syntax())); + return Some(elements_to_remove(arg.syntax())); } None @@ -174,6 +185,29 @@ pub(crate) fn range_to_remove(node: &SyntaxNode) -> TextRange { } } +pub(crate) fn elements_to_remove(node: &SyntaxNode) -> Vec { + let up_to_comma = next_prev().find_map(|dir| { + node.siblings_with_tokens(dir) + .filter_map(|it| it.into_token()) + .find(|it| it.kind() == T![,]) + .map(|it| (dir, it)) + }); + if let Some((dir, token)) = up_to_comma { + let after = token.siblings_with_tokens(dir).nth(1).unwrap(); + let mut result: Vec<_> = + node.siblings_with_tokens(dir).take_while(|it| it != &after).collect(); + if node.next_sibling().is_some() { + result.extend( + token.siblings_with_tokens(dir).skip(1).take_while(|it| it.kind() == WHITESPACE), + ); + } + + result + } else { + vec![node.syntax_element()] + } +} + #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; diff --git a/src/tools/rust-analyzer/crates/syntax/src/algo.rs b/src/tools/rust-analyzer/crates/syntax/src/algo.rs index 2acb2158318a..3b85b137aa9b 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/algo.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/algo.rs @@ -3,8 +3,8 @@ use itertools::Itertools; use crate::{ - AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, - TextSize, + syntax_editor::Element, AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, + SyntaxToken, TextRange, TextSize, }; /// Returns ancestors of the node at the offset, sorted by length. This should @@ -89,6 +89,26 @@ pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option Option { + let u = u.syntax_element(); + let v = v.syntax_element(); + if u == v { + return match u { + NodeOrToken::Node(node) => Some(node), + NodeOrToken::Token(token) => token.parent(), + }; + } + + let u_depth = u.ancestors().count(); + let v_depth = v.ancestors().count(); + let keep = u_depth.min(v_depth); + + let u_candidates = u.ancestors().skip(u_depth - keep); + let v_candidates = v.ancestors().skip(v_depth - keep); + let (res, _) = u_candidates.zip(v_candidates).find(|(x, y)| x == y)?; + Some(res) +} + pub fn neighbor(me: &T, direction: Direction) -> Option { me.syntax().siblings(direction).skip(1).find_map(T::cast) } diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index a05536e2d2d5..2d233ca62ad6 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -3015,7 +3015,7 @@ mod foo { ### `remove_unused_param` -**Source:** [remove_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_param.rs#L15) +**Source:** [remove_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_param.rs#L16) Removes unused function parameter. From d12ecaed558426ec7998816d64b240ea685a2a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 18 Feb 2025 01:15:59 +0000 Subject: [PATCH 315/991] Teach structured errors to display short `Ty` Make it so that every structured error annotated with `#[derive(Diagnostic)]` that has a field of type `Ty<'_>`, the printing of that value into a `String` will look at the thread-local storage `TyCtxt` in order to shorten to a length appropriate with the terminal width. When this happen, the resulting error will have a note with the file where the full type name was written to. ``` error[E0618]: expected function, found `((..., ..., ..., ...), ..., ..., ...)`` --> long.rs:7:5 | 6 | fn foo(x: D) { //~ `x` has type `(... | - `x` has type `((..., ..., ..., ...), ..., ..., ...)` 7 | x(); //~ ERROR expected function, found `(... | ^-- | | | call expression requires function | = note: the full name for the type has been written to 'long.long-type-14182675702747116984.txt' = note: consider using `--verbose` to print the full type name to the console ``` --- compiler/rustc_ast_passes/src/errors.rs | 1 - .../src/diagnostics/conflict_errors.rs | 1 - .../src/diagnostics/move_errors.rs | 9 +- .../src/diagnostics/region_name.rs | 4 +- .../rustc_borrowck/src/session_diagnostics.rs | 6 +- .../src/assert_module_sources.rs | 2 +- compiler/rustc_codegen_ssa/src/errors.rs | 4 +- .../rustc_const_eval/src/const_eval/error.rs | 8 +- compiler/rustc_const_eval/src/errors.rs | 2 +- compiler/rustc_errors/src/diagnostic.rs | 6 +- compiler/rustc_errors/src/diagnostic_impls.rs | 96 +++++++++---------- compiler/rustc_hir_typeck/messages.ftl | 6 +- compiler/rustc_hir_typeck/src/callee.rs | 47 +++++---- compiler/rustc_hir_typeck/src/cast.rs | 15 ++- compiler/rustc_hir_typeck/src/errors.rs | 19 ++-- compiler/rustc_metadata/src/locator.rs | 2 +- compiler/rustc_middle/src/error.rs | 4 +- .../rustc_middle/src/mir/interpret/error.rs | 8 +- compiler/rustc_middle/src/mir/terminator.rs | 2 +- compiler/rustc_middle/src/ty/consts/int.rs | 2 +- compiler/rustc_middle/src/ty/diagnostics.rs | 10 +- compiler/rustc_middle/src/ty/error.rs | 10 +- compiler/rustc_middle/src/ty/generic_args.rs | 4 +- compiler/rustc_middle/src/ty/layout.rs | 4 +- compiler/rustc_middle/src/ty/predicate.rs | 18 ++-- compiler/rustc_middle/src/ty/print/pretty.rs | 18 ++-- compiler/rustc_mir_build/src/errors.rs | 4 +- .../src/thir/pattern/check_match.rs | 6 +- compiler/rustc_parse/src/errors.rs | 1 - compiler/rustc_passes/src/check_attr.rs | 4 +- compiler/rustc_passes/src/errors.rs | 4 +- compiler/rustc_passes/src/layout_test.rs | 3 +- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_session/src/config.rs | 4 +- compiler/rustc_session/src/session.rs | 4 +- .../src/error_reporting/infer/mod.rs | 2 +- .../error_reporting/infer/need_type_info.rs | 2 +- .../nice_region_error/placeholder_error.rs | 2 +- compiler/rustc_trait_selection/src/errors.rs | 6 +- .../src/errors/note_and_explain.rs | 4 +- tests/ui/diagnostic-width/long-E0618.rs | 13 +++ tests/ui/diagnostic-width/long-E0618.stderr | 16 ++++ 42 files changed, 217 insertions(+), 168 deletions(-) create mode 100644 tests/ui/diagnostic-width/long-E0618.rs create mode 100644 tests/ui/diagnostic-width/long-E0618.stderr diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 9f0d2325475a..8e53e600f7ac 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -535,7 +535,6 @@ pub(crate) struct WhereClauseBeforeTypeAlias { } #[derive(Subdiagnostic)] - pub(crate) enum WhereClauseBeforeTypeAliasSugg { #[suggestion(ast_passes_remove_suggestion, applicability = "machine-applicable", code = "")] Remove { diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index f33f2ab58e05..2694a1eda78d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -287,7 +287,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { None => "value".to_owned(), }; if needs_note { - let ty = self.infcx.tcx.short_string(ty, err.long_ty_path()); if let Some(local) = place.as_local() { let span = self.body.local_decls[local].source_info.span; err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 5e83d2ffa97a..29cc749877b3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -596,10 +596,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning(err, place_ty, expr, None); } - let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path()); err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { is_partial_move: false, - ty, + ty: place_ty, place: &place_desc, span, }); @@ -629,10 +628,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning(err, place_ty, expr, Some(use_spans)); } - let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path()); err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { is_partial_move: false, - ty, + ty: place_ty, place: &place_desc, span: use_span, }); @@ -833,10 +831,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning(err, bind_to.ty, expr, None); } - let ty = self.infcx.tcx.short_string(bind_to.ty, err.long_ty_path()); err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { is_partial_move: false, - ty, + ty: bind_to.ty, place: place_desc, span: binding_span, }); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index be28f84debd9..a15f9744bf31 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -194,8 +194,8 @@ impl Display for RegionName { } impl rustc_errors::IntoDiagArg for RegionName { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> rustc_errors::DiagArgValue { + self.to_string().into_diag_arg(path) } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 11b30c145c2c..4be5d0dbf428 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -459,17 +459,17 @@ pub(crate) enum OnClosureNote<'a> { } #[derive(Subdiagnostic)] -pub(crate) enum TypeNoCopy<'a> { +pub(crate) enum TypeNoCopy<'a, 'tcx> { #[label(borrowck_ty_no_impl_copy)] Label { is_partial_move: bool, - ty: String, + ty: Ty<'tcx>, place: &'a str, #[primary_span] span: Span, }, #[note(borrowck_ty_no_impl_copy)] - Note { is_partial_move: bool, ty: String, place: &'a str }, + Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index da9f8d692972..32f689608f81 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -211,7 +211,7 @@ impl fmt::Display for CguReuse { } impl IntoDiagArg for CguReuse { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(self.to_string())) } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 5e25de02a77f..7e28961599f0 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -161,7 +161,7 @@ impl<'a> CopyPath<'a> { struct DebugArgPath<'a>(pub &'a Path); impl IntoDiagArg for DebugArgPath<'_> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { DiagArgValue::Str(Cow::Owned(format!("{:?}", self.0))) } } @@ -1087,7 +1087,7 @@ pub enum ExpectedPointerMutability { } impl IntoDiagArg for ExpectedPointerMutability { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { match self { ExpectedPointerMutability::Mut => DiagArgValue::Str(Cow::Borrowed("*mut")), ExpectedPointerMutability::Not => DiagArgValue::Str(Cow::Borrowed("*_")), diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index cc21a18af3a0..3e32336d8fca 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -49,10 +49,10 @@ impl MachineStopType for ConstEvalErrKind { | WriteThroughImmutablePointer => {} AssertFailure(kind) => kind.add_args(adder), Panic { msg, line, col, file } => { - adder("msg".into(), msg.into_diag_arg()); - adder("file".into(), file.into_diag_arg()); - adder("line".into(), line.into_diag_arg()); - adder("col".into(), col.into_diag_arg()); + adder("msg".into(), msg.into_diag_arg(&mut None)); + adder("file".into(), file.into_diag_arg(&mut None)); + adder("line".into(), line.into_diag_arg(&mut None)); + adder("col".into(), col.into_diag_arg(&mut None)); } } } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index c08495c012f8..ef756e58c5e0 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -967,7 +967,7 @@ impl ReportErrorExt for ResourceExhaustionInfo { } impl rustc_errors::IntoDiagArg for InternKind { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(match self { InternKind::Static(Mutability::Not) => "static", InternKind::Static(Mutability::Mut) => "static_mut", diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 29a74ed3f4e4..97daf891b0fe 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -148,11 +148,11 @@ where /// converted rather than on `DiagArgValue`, which enables types from other `rustc_*` crates to /// implement this. pub trait IntoDiagArg { - fn into_diag_arg(self) -> DiagArgValue; + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue; } impl IntoDiagArg for DiagArgValue { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { self } } @@ -395,7 +395,7 @@ impl DiagInner { } pub(crate) fn arg(&mut self, name: impl Into, arg: impl IntoDiagArg) { - self.args.insert(name.into(), arg.into_diag_arg()); + self.args.insert(name.into(), arg.into_diag_arg(&mut self.long_ty_path)); } /// Fields used for Hash, and PartialEq trait. diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index db6532f41eab..e0c8caf1317e 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -25,8 +25,8 @@ use crate::{ pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display); impl IntoDiagArg for DiagArgFromDisplay<'_> { - fn into_diag_arg(self) -> DiagArgValue { - self.0.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + self.0.to_string().into_diag_arg(path) } } @@ -43,8 +43,8 @@ impl<'a, T: fmt::Display> From<&'a T> for DiagArgFromDisplay<'a> { } impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T { - fn into_diag_arg(self) -> DiagArgValue { - self.clone().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + self.clone().into_diag_arg(path) } } @@ -53,8 +53,8 @@ macro_rules! into_diag_arg_using_display { ($( $ty:ty ),+ $(,)?) => { $( impl IntoDiagArg for $ty { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(path) } } )+ @@ -65,13 +65,13 @@ macro_rules! into_diag_arg_for_number { ($( $ty:ty ),+ $(,)?) => { $( impl IntoDiagArg for $ty { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { // Convert to a string if it won't fit into `Number`. #[allow(irrefutable_let_patterns)] if let Ok(n) = TryInto::::try_into(self) { DiagArgValue::Number(n) } else { - self.to_string().into_diag_arg() + self.to_string().into_diag_arg(path) } } } @@ -104,26 +104,26 @@ impl IntoDiagArg for RustcVersion { } impl IntoDiagArg for rustc_type_ir::TraitRef { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(path) } } impl IntoDiagArg for rustc_type_ir::ExistentialTraitRef { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(path) } } impl IntoDiagArg for rustc_type_ir::UnevaluatedConst { - fn into_diag_arg(self) -> DiagArgValue { - format!("{self:?}").into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + format!("{self:?}").into_diag_arg(path) } } impl IntoDiagArg for rustc_type_ir::FnSig { - fn into_diag_arg(self) -> DiagArgValue { - format!("{self:?}").into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + format!("{self:?}").into_diag_arg(path) } } @@ -131,15 +131,15 @@ impl IntoDiagArg for rustc_type_ir::Binder where T: IntoDiagArg, { - fn into_diag_arg(self) -> DiagArgValue { - self.skip_binder().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + self.skip_binder().into_diag_arg(path) } } into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize); impl IntoDiagArg for bool { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { if self { DiagArgValue::Str(Cow::Borrowed("true")) } else { @@ -149,13 +149,13 @@ impl IntoDiagArg for bool { } impl IntoDiagArg for char { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(format!("{self:?}"))) } } impl IntoDiagArg for Vec { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::StrListSepByAnd( self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(), ) @@ -163,49 +163,49 @@ impl IntoDiagArg for Vec { } impl IntoDiagArg for Symbol { - fn into_diag_arg(self) -> DiagArgValue { - self.to_ident_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + self.to_ident_string().into_diag_arg(path) } } impl<'a> IntoDiagArg for &'a str { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(path) } } impl IntoDiagArg for String { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(self)) } } impl<'a> IntoDiagArg for Cow<'a, str> { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(self.into_owned())) } } impl<'a> IntoDiagArg for &'a Path { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(self.display().to_string())) } } impl IntoDiagArg for PathBuf { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(self.display().to_string())) } } impl IntoDiagArg for PanicStrategy { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(self.desc().to_string())) } } impl IntoDiagArg for hir::ConstContext { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(match self { hir::ConstContext::ConstFn => "const_fn", hir::ConstContext::Static(_) => "static", @@ -215,49 +215,49 @@ impl IntoDiagArg for hir::ConstContext { } impl IntoDiagArg for ast::Expr { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(pprust::expr_to_string(&self))) } } impl IntoDiagArg for ast::Path { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(pprust::path_to_string(&self))) } } impl IntoDiagArg for ast::token::Token { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(pprust::token_to_string(&self)) } } impl IntoDiagArg for ast::token::TokenKind { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(pprust::token_kind_to_string(&self)) } } impl IntoDiagArg for FloatTy { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(self.name_str())) } } impl IntoDiagArg for std::ffi::CString { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) } } impl IntoDiagArg for rustc_data_structures::small_c_str::SmallCStr { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) } } impl IntoDiagArg for ast::Visibility { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { let s = pprust::vis_to_string(&self); let s = s.trim_end().to_string(); DiagArgValue::Str(Cow::Owned(s)) @@ -265,49 +265,49 @@ impl IntoDiagArg for ast::Visibility { } impl IntoDiagArg for rustc_lint_defs::Level { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(self.to_cmd_flag())) } } impl IntoDiagArg for hir::def::Res { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(self.descr())) } } impl IntoDiagArg for DiagLocation { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::from(self.to_string())) } } impl IntoDiagArg for Backtrace { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::from(self.to_string())) } } impl IntoDiagArg for Level { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::from(self.to_string())) } } impl IntoDiagArg for ClosureKind { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(self.as_str().into()) } } impl IntoDiagArg for hir::def::Namespace { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(self.descr())) } } impl IntoDiagArg for ExprPrecedence { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Number(self as i32) } } @@ -328,7 +328,7 @@ impl FromIterator for DiagSymbolList { } impl IntoDiagArg for DiagSymbolList { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::StrListSepByAnd( self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(), ) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index a994b31aeb43..291c61fb0f62 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -112,7 +112,11 @@ hir_typeck_int_to_fat = cannot cast `{$expr_ty}` to a pointer that {$known_wide hir_typeck_int_to_fat_label = creating a `{$cast_ty}` requires both an address and {$metadata} hir_typeck_int_to_fat_label_nightly = consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` -hir_typeck_invalid_callee = expected function, found {$ty} +hir_typeck_invalid_callee = expected function, found {$found} +hir_typeck_invalid_defined = `{$path}` defined here +hir_typeck_invalid_defined_kind = {$kind} `{$path}` defined here +hir_typeck_invalid_fn_defined = `{$func}` defined here returns `{$ty}` +hir_typeck_invalid_local = `{$local_name}` has type `{$ty}` hir_typeck_lossy_provenance_int2ptr = strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}` diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index d18869b6d90c..5e00161f693f 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -23,7 +23,7 @@ use tracing::{debug, instrument}; use super::method::MethodCallee; use super::method::probe::ProbeScope; use super::{Expectation, FnCtxt, TupleArgumentsFlag}; -use crate::errors; +use crate::{errors, fluent_generated}; /// Checks that it is legal to call methods of the trait corresponding /// to `trait_id` (this only cares about the trait, not the specific @@ -674,13 +674,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let callee_ty = self.resolve_vars_if_possible(callee_ty); + let mut path = None; let mut err = self.dcx().create_err(errors::InvalidCallee { span: callee_expr.span, - ty: match &unit_variant { + ty: callee_ty, + found: match &unit_variant { Some((_, kind, path)) => format!("{kind} `{path}`"), - None => format!("`{callee_ty}`"), + None => format!("`{}`", self.tcx.short_string(callee_ty, &mut path)), }, }); + *err.long_ty_path() = path; if callee_ty.references_error() { err.downgrade_to_delayed_bug(); } @@ -780,27 +783,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(span) = self.tcx.hir().res_span(def) { let callee_ty = callee_ty.to_string(); let label = match (unit_variant, inner_callee_path) { - (Some((_, kind, path)), _) => Some(format!("{kind} `{path}` defined here")), - (_, Some(hir::QPath::Resolved(_, path))) => self - .tcx - .sess - .source_map() - .span_to_snippet(path.span) - .ok() - .map(|p| format!("`{p}` defined here returns `{callee_ty}`")), + (Some((_, kind, path)), _) => { + err.arg("kind", kind); + err.arg("path", path); + Some(fluent_generated::hir_typeck_invalid_defined_kind) + } + (_, Some(hir::QPath::Resolved(_, path))) => { + self.tcx.sess.source_map().span_to_snippet(path.span).ok().map(|p| { + err.arg("func", p); + fluent_generated::hir_typeck_invalid_fn_defined + }) + } _ => { match def { // Emit a different diagnostic for local variables, as they are not // type definitions themselves, but rather variables *of* that type. - Res::Local(hir_id) => Some(format!( - "`{}` has type `{}`", - self.tcx.hir().name(hir_id), - callee_ty - )), - Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => { - Some(format!("`{}` defined here", self.tcx.def_path_str(def_id),)) + Res::Local(hir_id) => { + err.arg("local_name", self.tcx.hir().name(hir_id)); + Some(fluent_generated::hir_typeck_invalid_local) + } + Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => { + err.arg("path", self.tcx.def_path_str(def_id)); + Some(fluent_generated::hir_typeck_invalid_defined) + } + _ => { + err.arg("path", callee_ty); + Some(fluent_generated::hir_typeck_invalid_defined) } - _ => Some(format!("`{callee_ty}` defined here")), } } }; diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index f5f6ada12c3c..462983be88d8 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -548,17 +548,19 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.emit(); } CastError::SizedUnsizedCast => { + let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); + let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); fcx.dcx().emit_err(errors::CastThinPointerToWidePointer { span: self.span, - expr_ty: self.expr_ty, - cast_ty: fcx.ty_to_string(self.cast_ty), + expr_ty, + cast_ty, teach: fcx.tcx.sess.teach(E0607), }); } CastError::IntToWideCast(known_metadata) => { let expr_if_nightly = fcx.tcx.sess.is_nightly_build().then_some(self.expr_span); let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); - let expr_ty = fcx.ty_to_string(self.expr_ty); + let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); let metadata = known_metadata.unwrap_or("type-specific metadata"); let known_wide = known_metadata.is_some(); let span = self.cast_span; @@ -1164,10 +1166,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { if let Some((deref_ty, _)) = derefed { // Give a note about what the expr derefs to. if deref_ty != self.expr_ty.peel_refs() { - err.subdiagnostic(errors::DerefImplsIsEmpty { - span: self.expr_span, - deref_ty: fcx.ty_to_string(deref_ty), - }); + err.subdiagnostic(errors::DerefImplsIsEmpty { span: self.expr_span, deref_ty }); } // Create a multipart suggestion: add `!` and `.is_empty()` in @@ -1175,7 +1174,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.subdiagnostic(errors::UseIsEmpty { lo: self.expr_span.shrink_to_lo(), hi: self.span.with_lo(self.expr_span.hi()), - expr_ty: fcx.ty_to_string(self.expr_ty), + expr_ty: self.expr_ty, }); } } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 1bf8aa4f78d4..4347c5a92770 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -91,7 +91,7 @@ pub(crate) enum ReturnLikeStatementKind { } impl IntoDiagArg for ReturnLikeStatementKind { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { let kind = match self { Self::Return => "return", Self::Become => "become", @@ -456,10 +456,11 @@ impl HelpUseLatestEdition { #[derive(Diagnostic)] #[diag(hir_typeck_invalid_callee, code = E0618)] -pub(crate) struct InvalidCallee { +pub(crate) struct InvalidCallee<'tcx> { #[primary_span] pub span: Span, - pub ty: String, + pub ty: Ty<'tcx>, + pub found: String, } #[derive(Diagnostic)] @@ -469,7 +470,7 @@ pub(crate) struct IntToWide<'tcx> { #[label(hir_typeck_int_to_fat_label)] pub span: Span, pub metadata: &'tcx str, - pub expr_ty: String, + pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, #[label(hir_typeck_int_to_fat_label_nightly)] pub expr_if_nightly: Option, @@ -581,12 +582,12 @@ pub(crate) struct UnionPatDotDot { applicability = "maybe-incorrect", style = "verbose" )] -pub(crate) struct UseIsEmpty { +pub(crate) struct UseIsEmpty<'tcx> { #[suggestion_part(code = "!")] pub lo: Span, #[suggestion_part(code = ".is_empty()")] pub hi: Span, - pub expr_ty: String, + pub expr_ty: Ty<'tcx>, } #[derive(Diagnostic)] @@ -745,10 +746,10 @@ pub(crate) struct CtorIsPrivate { #[derive(Subdiagnostic)] #[note(hir_typeck_deref_is_empty)] -pub(crate) struct DerefImplsIsEmpty { +pub(crate) struct DerefImplsIsEmpty<'tcx> { #[primary_span] pub span: Span, - pub deref_ty: String, + pub deref_ty: Ty<'tcx>, } #[derive(Subdiagnostic)] @@ -826,7 +827,7 @@ pub(crate) struct CastThinPointerToWidePointer<'tcx> { #[primary_span] pub span: Span, pub expr_ty: Ty<'tcx>, - pub cast_ty: String, + pub cast_ty: Ty<'tcx>, #[note(hir_typeck_teach_help)] pub(crate) teach: bool, } diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 3f3e58384cbf..d5dd5059aacc 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -290,7 +290,7 @@ impl fmt::Display for CrateFlavor { } impl IntoDiagArg for CrateFlavor { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { match self { CrateFlavor::Rlib => DiagArgValue::Str(Cow::Borrowed("rlib")), CrateFlavor::Rmeta => DiagArgValue::Str(Cow::Borrowed("rmeta")), diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index be8a3403ba95..bd315577efb5 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -47,10 +47,10 @@ pub struct UnsupportedUnion { // FIXME(autodiff): I should get used somewhere #[derive(Diagnostic)] #[diag(middle_autodiff_unsafe_inner_const_ref)] -pub struct AutodiffUnsafeInnerConstRef { +pub struct AutodiffUnsafeInnerConstRef<'tcx> { #[primary_span] pub span: Span, - pub ty: String, + pub ty: Ty<'tcx>, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 743812e3a20a..890756a17cae 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -248,7 +248,7 @@ pub enum InvalidMetaKind { } impl IntoDiagArg for InvalidMetaKind { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(match self { InvalidMetaKind::SliceTooBig => "slice_too_big", InvalidMetaKind::TooBig => "too_big", @@ -282,7 +282,7 @@ pub struct Misalignment { macro_rules! impl_into_diag_arg_through_debug { ($($ty:ty),*$(,)?) => {$( impl IntoDiagArg for $ty { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(format!("{self:?}"))) } } @@ -401,7 +401,7 @@ pub enum PointerKind { } impl IntoDiagArg for PointerKind { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str( match self { Self::Ref(_) => "ref", @@ -666,7 +666,7 @@ macro_rules! err_ub_custom { msg: || $msg, add_args: Box::new(move |mut set_arg| { $($( - set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name)); + set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name, &mut None)); )*)? }) } diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index b887370fd699..bc77f22af67b 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -357,7 +357,7 @@ impl AssertKind { macro_rules! add { ($name: expr, $value: expr) => { - adder($name.into(), $value.into_diag_arg()); + adder($name.into(), $value.into_diag_arg(&mut None)); }; } diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index b72edc1c5325..7c9280fae16d 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -118,7 +118,7 @@ impl std::fmt::Debug for ConstInt { impl IntoDiagArg for ConstInt { // FIXME this simply uses the Debug impl, but we could probably do better by converting both // to an inherent method that returns `Cow`. - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(format!("{self:?}").into()) } } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index cb218a27e623..881381a5ee61 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -19,8 +19,16 @@ use crate::ty::{ TypeSuperVisitable, TypeVisitable, TypeVisitor, }; +impl IntoDiagArg for Ty<'_> { + fn into_diag_arg(self, path: &mut Option) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let ty = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(ty)) + }) + } +} + into_diag_arg_using_display! { - Ty<'_>, ty::Region<'_>, } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 8c1991ddb36e..a0e67929c528 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -213,10 +213,9 @@ impl<'tcx> Ty<'tcx> { } impl<'tcx> TyCtxt<'tcx> { - pub fn string_with_limit<'a, T>(self, p: T, length_limit: usize) -> String + pub fn string_with_limit(self, p: T, length_limit: usize) -> String where - T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift> + Copy, - >>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>, + T: Copy + for<'a, 'b> Lift, Lifted: Print<'b, FmtPrinter<'a, 'b>>>, { let mut type_limit = 50; let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| { @@ -253,10 +252,9 @@ impl<'tcx> TyCtxt<'tcx> { /// `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that keeps /// the existence of a "long type" anywhere in the diagnostic, so the note telling the user /// where we wrote the file to is only printed once. - pub fn short_string<'a, T>(self, p: T, path: &mut Option) -> String + pub fn short_string(self, p: T, path: &mut Option) -> String where - T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift> + Copy + Hash, - >>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>, + T: Copy + Hash + for<'a, 'b> Lift, Lifted: Print<'b, FmtPrinter<'a, 'b>>>, { let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| { self.lift(p).expect("could not lift for printing").print(cx) diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index ed0b3059d752..27576a2ec4a2 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -159,8 +159,8 @@ unsafe impl<'tcx> Sync for GenericArg<'tcx> where } impl<'tcx> IntoDiagArg for GenericArg<'tcx> { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(&mut None) } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index eb14ed20fbac..272bb0cc915f 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -315,8 +315,8 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { } impl<'tcx> IntoDiagArg for LayoutError<'tcx> { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(&mut None) } } diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 553de83dfcb4..de6d30a89d47 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -158,15 +158,21 @@ impl<'tcx> Predicate<'tcx> { } } -impl rustc_errors::IntoDiagArg for Predicate<'_> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(self.to_string())) +impl<'tcx> rustc_errors::IntoDiagArg for Predicate<'tcx> { + fn into_diag_arg(self, path: &mut Option) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let pred = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(pred)) + }) } } -impl rustc_errors::IntoDiagArg for Clause<'_> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(self.to_string())) +impl<'tcx> rustc_errors::IntoDiagArg for Clause<'tcx> { + fn into_diag_arg(self, path: &mut Option) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let clause = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(clause)) + }) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index ed0839f47e69..942411945bfe 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2898,12 +2898,15 @@ where /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only /// the trait path. That is, it will print `Trait` instead of /// `>`. -#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)] +#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)] pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>); impl<'tcx> rustc_errors::IntoDiagArg for TraitRefPrintOnlyTraitPath<'tcx> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let trait_ref = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(trait_ref)) + }) } } @@ -2915,12 +2918,15 @@ impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> { /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only /// the trait path, and additionally tries to "sugar" `Fn(...)` trait bounds. -#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)] +#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)] pub struct TraitRefPrintSugared<'tcx>(ty::TraitRef<'tcx>); impl<'tcx> rustc_errors::IntoDiagArg for TraitRefPrintSugared<'tcx> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, path: &mut Option) -> rustc_errors::DiagArgValue { + ty::tls::with(|tcx| { + let trait_ref = tcx.short_string(self, path); + rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(trait_ref)) + }) } } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index f1753be845d4..17b22f25dbb0 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -828,7 +828,7 @@ pub(crate) struct IrrefutableLetPatternsWhileLet { #[derive(Diagnostic)] #[diag(mir_build_borrow_of_moved_value)] -pub(crate) struct BorrowOfMovedValue { +pub(crate) struct BorrowOfMovedValue<'tcx> { #[primary_span] #[label] #[label(mir_build_occurs_because_label)] @@ -836,7 +836,7 @@ pub(crate) struct BorrowOfMovedValue { #[label(mir_build_value_borrowed_label)] pub(crate) conflicts_ref: Vec, pub(crate) name: Ident, - pub(crate) ty: String, + pub(crate) ty: Ty<'tcx>, #[suggestion(code = "ref ", applicability = "machine-applicable")] pub(crate) suggest_borrowing: Option, } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index d60ae6484afb..954d0cf97abe 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -786,17 +786,13 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: } }); if !conflicts_ref.is_empty() { - let mut path = None; - let ty = cx.tcx.short_string(ty, &mut path); - let mut err = sess.dcx().create_err(BorrowOfMovedValue { + sess.dcx().emit_err(BorrowOfMovedValue { binding_span: pat.span, conflicts_ref, name: Ident::new(name, pat.span), ty, suggest_borrowing: Some(pat.span.shrink_to_lo()), }); - *err.long_ty_path() = path; - err.emit(); } return; } diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index dc03d6f9521d..173c68b3a722 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -772,7 +772,6 @@ pub(crate) struct LabeledLoopInBreak { } #[derive(Subdiagnostic)] - pub(crate) enum WrapInParentheses { #[multipart_suggestion( parse_sugg_wrap_expression_in_parentheses, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9be868122872..5ada289cc209 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -80,13 +80,13 @@ pub(crate) enum ProcMacroKind { } impl IntoDiagArg for ProcMacroKind { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { match self { ProcMacroKind::Attribute => "attribute proc macro", ProcMacroKind::Derive => "derive proc macro", ProcMacroKind::FunctionLike => "function-like proc macro", } - .into_diag_arg() + .into_diag_arg(&mut None) } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 5f686f38babd..51b5861ee0ae 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1005,10 +1005,10 @@ pub(crate) struct LayoutHomogeneousAggregate { #[derive(Diagnostic)] #[diag(passes_layout_of)] -pub(crate) struct LayoutOf { +pub(crate) struct LayoutOf<'tcx> { #[primary_span] pub span: Span, - pub normalized_ty: String, + pub normalized_ty: Ty<'tcx>, pub ty_layout: String, } diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 1133cf93304d..d4512c9417eb 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -112,8 +112,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { } sym::debug => { - let normalized_ty = - format!("{}", tcx.normalize_erasing_regions(typing_env, ty)); + let normalized_ty = tcx.normalize_erasing_regions(typing_env, ty); // FIXME: using the `Debug` impl here isn't ideal. let ty_layout = format!("{:#?}", *ty_layout); tcx.dcx().emit_err(LayoutOf { span, normalized_ty, ty_layout }); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ad9c3465f0cc..32ef781631be 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -94,7 +94,7 @@ impl PatternSource { } impl IntoDiagArg for PatternSource { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(self.descr())) } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8f0b17b5e887..ba7ccd6a02da 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2807,8 +2807,8 @@ impl fmt::Display for CrateType { } impl IntoDiagArg for CrateType { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(&mut None) } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 8e5ff1d3bc48..ecdf76d22fb2 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -109,8 +109,8 @@ impl Mul for Limit { } impl rustc_errors::IntoDiagArg for Limit { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - self.to_string().into_diag_arg() + fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { + self.to_string().into_diag_arg(&mut None) } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index a618bae269fa..847bd06bb017 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -2418,7 +2418,7 @@ impl<'tcx> ObligationCause<'tcx> { pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>); impl IntoDiagArg for ObligationCauseAsDiagArg<'_> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { let kind = match self.0.code() { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn, .. } => "method_compat", ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type, .. } => "type_compat", diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index bed9734f389c..a6d8eb6add7d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -137,7 +137,7 @@ impl InferenceDiagnosticsParentData { } impl IntoDiagArg for UnderspecifiedArgKind { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { let kind = match self { Self::Type { .. } => "type", Self::Const { is_parameter: true } => "const_with_param", diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs index aaaefd81d19b..5056161e117e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs @@ -31,7 +31,7 @@ impl<'tcx, T> IntoDiagArg for Highlighted<'tcx, T> where T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>, { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { rustc_errors::DiagArgValue::Str(self.to_string().into()) } } diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 23aa38006604..fe859eb53cd7 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -784,10 +784,10 @@ pub enum TyOrSig<'tcx> { } impl IntoDiagArg for TyOrSig<'_> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self, path: &mut Option) -> rustc_errors::DiagArgValue { match self { - TyOrSig::Ty(ty) => ty.into_diag_arg(), - TyOrSig::ClosureSig(sig) => sig.into_diag_arg(), + TyOrSig::Ty(ty) => ty.into_diag_arg(path), + TyOrSig::ClosureSig(sig) => sig.into_diag_arg(path), } } } diff --git a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs index 4601ddf678a0..46622246a178 100644 --- a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs @@ -105,7 +105,7 @@ pub enum SuffixKind { } impl IntoDiagArg for PrefixKind { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { let kind = match self { Self::Empty => "empty", Self::RefValidFor => "ref_valid_for", @@ -127,7 +127,7 @@ impl IntoDiagArg for PrefixKind { } impl IntoDiagArg for SuffixKind { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { let kind = match self { Self::Empty => "empty", Self::Continues => "continues", diff --git a/tests/ui/diagnostic-width/long-E0618.rs b/tests/ui/diagnostic-width/long-E0618.rs new file mode 100644 index 000000000000..f8626ab9455e --- /dev/null +++ b/tests/ui/diagnostic-width/long-E0618.rs @@ -0,0 +1,13 @@ +//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" +type A = (i32, i32, i32, i32); +type B = (A, A, A, A); +type C = (B, B, B, B); +type D = (C, C, C, C); + +fn foo(x: D) { //~ `x` has type `(... + x(); //~ ERROR expected function, found `(... +} + +fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0618.stderr b/tests/ui/diagnostic-width/long-E0618.stderr new file mode 100644 index 000000000000..f0838cbddcc6 --- /dev/null +++ b/tests/ui/diagnostic-width/long-E0618.stderr @@ -0,0 +1,16 @@ +error[E0618]: expected function, found `(..., ..., ..., ...)` + --> $DIR/long-E0618.rs:10:5 + | +LL | fn foo(x: D) { + | - `x` has type `(..., ..., ..., ...)` +LL | x(); + | ^-- + | | + | call expression requires function + | + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: consider using `--verbose` to print the full type name to the console + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0618`. From 693ed264cee6844006dc9e30295ba176a3e819b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 18 Feb 2025 01:16:16 +0000 Subject: [PATCH 316/991] Add tests --- tests/ui/diagnostic-width/long-E0529.rs | 14 ++++++++++++++ tests/ui/diagnostic-width/long-E0529.stderr | 9 +++++++++ tests/ui/diagnostic-width/long-E0609.rs | 13 +++++++++++++ tests/ui/diagnostic-width/long-E0609.stderr | 9 +++++++++ tests/ui/diagnostic-width/long-E0614.rs | 13 +++++++++++++ tests/ui/diagnostic-width/long-E0614.stderr | 9 +++++++++ 6 files changed, 67 insertions(+) create mode 100644 tests/ui/diagnostic-width/long-E0529.rs create mode 100644 tests/ui/diagnostic-width/long-E0529.stderr create mode 100644 tests/ui/diagnostic-width/long-E0609.rs create mode 100644 tests/ui/diagnostic-width/long-E0609.stderr create mode 100644 tests/ui/diagnostic-width/long-E0614.rs create mode 100644 tests/ui/diagnostic-width/long-E0614.stderr diff --git a/tests/ui/diagnostic-width/long-E0529.rs b/tests/ui/diagnostic-width/long-E0529.rs new file mode 100644 index 000000000000..2ebc21f51ef3 --- /dev/null +++ b/tests/ui/diagnostic-width/long-E0529.rs @@ -0,0 +1,14 @@ +//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" +type A = (i32, i32, i32, i32); +type B = (A, A, A, A); +type C = (B, B, B, B); +type D = (C, C, C, C); + +fn foo(x: D) { + let [] = x; //~ ERROR expected an array or slice, found `( + //~^ pattern cannot match with input type `( +} + +fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0529.stderr b/tests/ui/diagnostic-width/long-E0529.stderr new file mode 100644 index 000000000000..8dcd4fa6b382 --- /dev/null +++ b/tests/ui/diagnostic-width/long-E0529.stderr @@ -0,0 +1,9 @@ +error[E0529]: expected an array or slice, found `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))` + --> $DIR/long-E0529.rs:10:9 + | +LL | let [] = x; + | ^^ pattern cannot match with input type `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0529`. diff --git a/tests/ui/diagnostic-width/long-E0609.rs b/tests/ui/diagnostic-width/long-E0609.rs new file mode 100644 index 000000000000..ae57e4f76d2f --- /dev/null +++ b/tests/ui/diagnostic-width/long-E0609.rs @@ -0,0 +1,13 @@ +//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" +type A = (i32, i32, i32, i32); +type B = (A, A, A, A); +type C = (B, B, B, B); +type D = (C, C, C, C); + +fn foo(x: D) { + x.field; //~ ERROR no field `field` on type `( +} + +fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0609.stderr b/tests/ui/diagnostic-width/long-E0609.stderr new file mode 100644 index 000000000000..708cd4ef93a8 --- /dev/null +++ b/tests/ui/diagnostic-width/long-E0609.stderr @@ -0,0 +1,9 @@ +error[E0609]: no field `field` on type `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))` + --> $DIR/long-E0609.rs:10:7 + | +LL | x.field; + | ^^^^^ unknown field + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/diagnostic-width/long-E0614.rs b/tests/ui/diagnostic-width/long-E0614.rs new file mode 100644 index 000000000000..35129c909da4 --- /dev/null +++ b/tests/ui/diagnostic-width/long-E0614.rs @@ -0,0 +1,13 @@ +//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" +type A = (i32, i32, i32, i32); +type B = (A, A, A, A); +type C = (B, B, B, B); +type D = (C, C, C, C); + +fn foo(x: D) { + *x; //~ ERROR type `( +} + +fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0614.stderr b/tests/ui/diagnostic-width/long-E0614.stderr new file mode 100644 index 000000000000..6bbfbad57f23 --- /dev/null +++ b/tests/ui/diagnostic-width/long-E0614.stderr @@ -0,0 +1,9 @@ +error[E0614]: type `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))` cannot be dereferenced + --> $DIR/long-E0614.rs:10:5 + | +LL | *x; + | ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0614`. From ae3a825faa5dbcba6a223d0d225fd5535bf5f014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 18 Feb 2025 01:39:08 +0000 Subject: [PATCH 317/991] Make E0529 a structured error --- compiler/rustc_hir_typeck/messages.ftl | 6 ++++ compiler/rustc_hir_typeck/src/errors.rs | 38 +++++++++++++++++++++ compiler/rustc_hir_typeck/src/pat.rs | 34 +++++++----------- tests/ui/diagnostic-width/long-E0529.rs | 4 +-- tests/ui/diagnostic-width/long-E0529.stderr | 7 ++-- 5 files changed, 64 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 291c61fb0f62..9c1f1bb91be5 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -10,6 +10,7 @@ hir_typeck_address_of_temporary_taken = cannot take address of a temporary hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but rustc had trouble determining where .note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new +hir_typeck_as_deref_suggestion = consider using `as_deref` here hir_typeck_base_expression_double_dot = base expression required after `..` hir_typeck_base_expression_double_dot_add_expr = add a base expression here hir_typeck_base_expression_double_dot_enable_default_field_values = @@ -72,6 +73,9 @@ hir_typeck_dependency_on_unit_never_type_fallback = this function depends on nev hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty` +hir_typeck_expected_array_or_slice = expected an array or slice, found `{$ty}` +hir_typeck_expected_array_or_slice_label = pattern cannot match with input type `{$ty}` + hir_typeck_expected_default_return_type = expected `()` because of default return type hir_typeck_expected_return_type = expected `{$expected}` because of return type @@ -187,6 +191,8 @@ hir_typeck_self_ctor_from_outer_item = can't reference `Self` constructor from o .label = the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference .suggestion = replace `Self` with the actual type +hir_typeck_slicing_suggestion = consider slicing here + hir_typeck_struct_expr_non_exhaustive = cannot create non-exhaustive {$what} using struct expression diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 4347c5a92770..335ac1c57a71 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -454,6 +454,44 @@ impl HelpUseLatestEdition { } } +#[derive(Diagnostic)] +#[diag(hir_typeck_expected_array_or_slice, code = E0529)] +pub(crate) struct ExpectedArrayOrSlice<'tcx> { + #[primary_span] + #[label(hir_typeck_expected_array_or_slice_label)] + pub(crate) span: Span, + pub(crate) ty: Ty<'tcx>, + pub(crate) slice_pat_semantics: bool, + #[subdiagnostic] + pub(crate) as_deref: Option, + #[subdiagnostic] + pub(crate) slicing: Option, +} + +#[derive(Subdiagnostic)] +#[suggestion( + hir_typeck_as_deref_suggestion, + code = ".as_deref()", + style = "verbose", + applicability = "maybe-incorrect" +)] +pub(crate) struct AsDerefSuggestion { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion( + hir_typeck_slicing_suggestion, + code = "[..]", + style = "verbose", + applicability = "maybe-incorrect" +)] +pub(crate) struct SlicingSuggestion { + #[primary_span] + pub(crate) span: Span, +} + #[derive(Diagnostic)] #[diag(hir_typeck_invalid_callee, code = E0618)] pub(crate) struct InvalidCallee<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index bd0848b99166..19ae3e3899c9 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2771,16 +2771,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> ErrorGuaranteed { let PatInfo { top_info: ti, current_depth, .. } = pat_info; - let mut err = struct_span_code_err!( - self.dcx(), - span, - E0529, - "expected an array or slice, found `{expected_ty}`" - ); + let mut slice_pat_semantics = false; + let mut as_deref = None; + let mut slicing = None; if let ty::Ref(_, ty, _) = expected_ty.kind() && let ty::Array(..) | ty::Slice(..) = ty.kind() { - err.help("the semantics of slice patterns changed recently; see issue #62254"); + slice_pat_semantics = true; } else if self .autoderef(span, expected_ty) .silence_errors() @@ -2797,28 +2794,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) => { // Slicing won't work here, but `.as_deref()` might (issue #91328). - err.span_suggestion_verbose( - span.shrink_to_hi(), - "consider using `as_deref` here", - ".as_deref()", - Applicability::MaybeIncorrect, - ); + as_deref = Some(errors::AsDerefSuggestion { span: span.shrink_to_hi() }); } _ => (), } let is_top_level = current_depth <= 1; if is_slice_or_array_or_vector && is_top_level { - err.span_suggestion_verbose( - span.shrink_to_hi(), - "consider slicing here", - "[..]", - Applicability::MachineApplicable, - ); + slicing = Some(errors::SlicingSuggestion { span: span.shrink_to_hi() }); } } - err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`")); - err.emit() + self.dcx().emit_err(errors::ExpectedArrayOrSlice { + span, + ty: expected_ty, + slice_pat_semantics, + as_deref, + slicing, + }) } fn is_slice_or_array_or_vector(&self, ty: Ty<'tcx>) -> (bool, Ty<'tcx>) { diff --git a/tests/ui/diagnostic-width/long-E0529.rs b/tests/ui/diagnostic-width/long-E0529.rs index 2ebc21f51ef3..3ebc4f5f8c82 100644 --- a/tests/ui/diagnostic-width/long-E0529.rs +++ b/tests/ui/diagnostic-width/long-E0529.rs @@ -7,8 +7,8 @@ type C = (B, B, B, B); type D = (C, C, C, C); fn foo(x: D) { - let [] = x; //~ ERROR expected an array or slice, found `( - //~^ pattern cannot match with input type `( + let [] = x; //~ ERROR expected an array or slice, found `(... + //~^ pattern cannot match with input type `(... } fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0529.stderr b/tests/ui/diagnostic-width/long-E0529.stderr index 8dcd4fa6b382..da03e5fab2ca 100644 --- a/tests/ui/diagnostic-width/long-E0529.stderr +++ b/tests/ui/diagnostic-width/long-E0529.stderr @@ -1,8 +1,11 @@ -error[E0529]: expected an array or slice, found `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))` +error[E0529]: expected an array or slice, found `(..., ..., ..., ...)` --> $DIR/long-E0529.rs:10:9 | LL | let [] = x; - | ^^ pattern cannot match with input type `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))` + | ^^ pattern cannot match with input type `(..., ..., ..., ...)` + | + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error From 7302dc660b997c882b3a250fb6a23f60259fbdf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 18 Feb 2025 01:50:10 +0000 Subject: [PATCH 318/991] Make E0614 a structured error ``` error[E0614]: type `(..., ..., ..., ...)` cannot be dereferenced --> $DIR/long-E0614.rs:10:5 | LL | *x; | ^^ can't be dereferenced | = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console ``` --- compiler/rustc_hir_typeck/messages.ftl | 3 +++ compiler/rustc_hir_typeck/src/errors.rs | 9 +++++++++ compiler/rustc_hir_typeck/src/expr.rs | 15 +++++---------- tests/ui/deref-non-pointer.stderr | 2 +- tests/ui/diagnostic-width/long-E0614.rs | 2 +- tests/ui/diagnostic-width/long-E0614.stderr | 7 +++++-- tests/ui/error-codes/E0614.stderr | 2 +- tests/ui/issues/issue-17373.stderr | 2 +- tests/ui/issues/issue-9814.stderr | 2 +- tests/ui/parser/expr-as-stmt.stderr | 2 +- .../nested-binding-modes-ref.stderr | 4 ++-- tests/ui/reachable/expr_unary.stderr | 2 +- .../ui/type/type-check/missing_trait_impl.stderr | 2 +- 13 files changed, 32 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 9c1f1bb91be5..1a75a2ec3152 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -28,6 +28,9 @@ hir_typeck_cannot_cast_to_bool = cannot cast `{$expr_ty}` as `bool` .help = compare with zero instead .label = unsupported cast +hir_typeck_cant_dereference = type `{$ty}` cannot be dereferenced +hir_typeck_cant_dereference_label = can't be dereferenced + hir_typeck_cast_enum_drop = cannot cast enum `{$expr_ty}` into integer `{$cast_ty}` because it implements `Drop` hir_typeck_cast_thin_pointer_to_wide_pointer = cannot cast thin pointer `{$expr_ty}` to wide pointer `{$cast_ty}` diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 335ac1c57a71..968bcee45cf4 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -454,6 +454,15 @@ impl HelpUseLatestEdition { } } +#[derive(Diagnostic)] +#[diag(hir_typeck_cant_dereference, code = E0614)] +pub(crate) struct CantDereference<'tcx> { + #[primary_span] + #[label(hir_typeck_cant_dereference_label)] + pub(crate) span: Span, + pub(crate) ty: Ty<'tcx>, +} + #[derive(Diagnostic)] #[diag(hir_typeck_expected_array_or_slice, code = E0529)] pub(crate) struct ExpectedArrayOrSlice<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 4815627a0ce0..a857a91834e6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -45,9 +45,9 @@ use crate::coercion::{CoerceMany, DynamicCoerceMany}; use crate::errors::{ AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr, BaseExpressionDoubleDotEnableDefaultFieldValues, BaseExpressionDoubleDotRemove, - FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, HelpUseLatestEdition, - ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, - TypeMismatchFruTypo, YieldExprOutsideOfCoroutine, + CantDereference, FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, + HelpUseLatestEdition, ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody, + StructExprNonExhaustive, TypeMismatchFruTypo, YieldExprOutsideOfCoroutine, }; use crate::{ BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, Needs, cast, fatally_break_rust, @@ -607,13 +607,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) { oprnd_t = ty; } else { - let mut err = type_error_struct!( - self.dcx(), - expr.span, - oprnd_t, - E0614, - "type `{oprnd_t}` cannot be dereferenced", - ); + let mut err = + self.dcx().create_err(CantDereference { span: expr.span, ty: oprnd_t }); let sp = tcx.sess.source_map().start_point(expr.span).with_parent(None); if let Some(sp) = tcx.sess.psess.ambiguous_block_expr_parse.borrow().get(&sp) diff --git a/tests/ui/deref-non-pointer.stderr b/tests/ui/deref-non-pointer.stderr index 2e5e574fb6c7..3ee354819e5d 100644 --- a/tests/ui/deref-non-pointer.stderr +++ b/tests/ui/deref-non-pointer.stderr @@ -2,7 +2,7 @@ error[E0614]: type `{integer}` cannot be dereferenced --> $DIR/deref-non-pointer.rs:2:9 | LL | match *1 { - | ^^ + | ^^ can't be dereferenced error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-E0614.rs b/tests/ui/diagnostic-width/long-E0614.rs index 35129c909da4..0b78444a00d2 100644 --- a/tests/ui/diagnostic-width/long-E0614.rs +++ b/tests/ui/diagnostic-width/long-E0614.rs @@ -7,7 +7,7 @@ type C = (B, B, B, B); type D = (C, C, C, C); fn foo(x: D) { - *x; //~ ERROR type `( + *x; //~ ERROR type `(... } fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0614.stderr b/tests/ui/diagnostic-width/long-E0614.stderr index 6bbfbad57f23..1c16ff617faa 100644 --- a/tests/ui/diagnostic-width/long-E0614.stderr +++ b/tests/ui/diagnostic-width/long-E0614.stderr @@ -1,8 +1,11 @@ -error[E0614]: type `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))` cannot be dereferenced +error[E0614]: type `(..., ..., ..., ...)` cannot be dereferenced --> $DIR/long-E0614.rs:10:5 | LL | *x; - | ^^ + | ^^ can't be dereferenced + | + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0614.stderr b/tests/ui/error-codes/E0614.stderr index ae7c2ce9a132..0bba0753980d 100644 --- a/tests/ui/error-codes/E0614.stderr +++ b/tests/ui/error-codes/E0614.stderr @@ -2,7 +2,7 @@ error[E0614]: type `u32` cannot be dereferenced --> $DIR/E0614.rs:3:5 | LL | *y; - | ^^ + | ^^ can't be dereferenced error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-17373.stderr b/tests/ui/issues/issue-17373.stderr index 9438f5c6345d..0e16d08c87d3 100644 --- a/tests/ui/issues/issue-17373.stderr +++ b/tests/ui/issues/issue-17373.stderr @@ -2,7 +2,7 @@ error[E0614]: type `!` cannot be dereferenced --> $DIR/issue-17373.rs:2:5 | LL | *return - | ^^^^^^^ + | ^^^^^^^ can't be dereferenced error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-9814.stderr b/tests/ui/issues/issue-9814.stderr index d647edaf37e2..fa23fb7c1762 100644 --- a/tests/ui/issues/issue-9814.stderr +++ b/tests/ui/issues/issue-9814.stderr @@ -2,7 +2,7 @@ error[E0614]: type `Foo` cannot be dereferenced --> $DIR/issue-9814.rs:7:13 | LL | let _ = *Foo::Bar(2); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ can't be dereferenced error: aborting due to 1 previous error diff --git a/tests/ui/parser/expr-as-stmt.stderr b/tests/ui/parser/expr-as-stmt.stderr index 76a83aa0161b..577c3455a718 100644 --- a/tests/ui/parser/expr-as-stmt.stderr +++ b/tests/ui/parser/expr-as-stmt.stderr @@ -133,7 +133,7 @@ error[E0614]: type `{integer}` cannot be dereferenced --> $DIR/expr-as-stmt.rs:25:11 | LL | { 3 } * 3 - | ^^^ + | ^^^ can't be dereferenced | help: parentheses are required to parse this as an expression | diff --git a/tests/ui/pattern/bindings-after-at/nested-binding-modes-ref.stderr b/tests/ui/pattern/bindings-after-at/nested-binding-modes-ref.stderr index b378fe356ce1..46477f16090b 100644 --- a/tests/ui/pattern/bindings-after-at/nested-binding-modes-ref.stderr +++ b/tests/ui/pattern/bindings-after-at/nested-binding-modes-ref.stderr @@ -2,13 +2,13 @@ error[E0614]: type `{integer}` cannot be dereferenced --> $DIR/nested-binding-modes-ref.rs:4:5 | LL | *is_val; - | ^^^^^^^ + | ^^^^^^^ can't be dereferenced error[E0614]: type `{integer}` cannot be dereferenced --> $DIR/nested-binding-modes-ref.rs:9:5 | LL | *is_val; - | ^^^^^^^ + | ^^^^^^^ can't be dereferenced error: aborting due to 2 previous errors diff --git a/tests/ui/reachable/expr_unary.stderr b/tests/ui/reachable/expr_unary.stderr index 0a763087c6f1..7deca1b86021 100644 --- a/tests/ui/reachable/expr_unary.stderr +++ b/tests/ui/reachable/expr_unary.stderr @@ -2,7 +2,7 @@ error[E0614]: type `!` cannot be dereferenced --> $DIR/expr_unary.rs:8:16 | LL | let x: ! = * { return; }; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ can't be dereferenced error: unreachable expression --> $DIR/expr_unary.rs:8:16 diff --git a/tests/ui/type/type-check/missing_trait_impl.stderr b/tests/ui/type/type-check/missing_trait_impl.stderr index 033b42e6736d..28ffae2d5e55 100644 --- a/tests/ui/type/type-check/missing_trait_impl.stderr +++ b/tests/ui/type/type-check/missing_trait_impl.stderr @@ -50,7 +50,7 @@ error[E0614]: type `T` cannot be dereferenced --> $DIR/missing_trait_impl.rs:15:13 | LL | let y = *x; - | ^^ + | ^^ can't be dereferenced error: aborting due to 5 previous errors From 26f74ef586d2d8849e93e9a1a6c6e803a0d21065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 18 Feb 2025 03:54:04 +0000 Subject: [PATCH 319/991] Make E0609 a structured error --- compiler/rustc_hir_typeck/messages.ftl | 6 ++++ compiler/rustc_hir_typeck/src/errors.rs | 23 +++++++++++++ compiler/rustc_hir_typeck/src/expr.rs | 36 ++++++++++----------- tests/ui/diagnostic-width/long-E0609.rs | 2 +- tests/ui/diagnostic-width/long-E0609.stderr | 5 ++- 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 1a75a2ec3152..ed80bc3e7be7 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -153,6 +153,12 @@ hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for { *[other] {" "}in the current scope } +hir_typeck_no_field_on_type = no field `{$field}` on type `{$ty}` + +hir_typeck_no_field_on_variant = no field named `{$field}` on enum variant `{$container}::{$ident}` +hir_typeck_no_field_on_variant_enum = this enum variant... +hir_typeck_no_field_on_variant_field = ...does not have this field + hir_typeck_note_caller_chooses_ty_for_ty_param = the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}` hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 968bcee45cf4..20688a5b949d 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -454,6 +454,29 @@ impl HelpUseLatestEdition { } } +#[derive(Diagnostic)] +#[diag(hir_typeck_no_field_on_type, code = E0609)] +pub(crate) struct NoFieldOnType<'tcx> { + #[primary_span] + pub(crate) span: Span, + pub(crate) ty: Ty<'tcx>, + pub(crate) field: Ident, +} + +#[derive(Diagnostic)] +#[diag(hir_typeck_no_field_on_variant, code = E0609)] +pub(crate) struct NoFieldOnVariant<'tcx> { + #[primary_span] + pub(crate) span: Span, + pub(crate) container: Ty<'tcx>, + pub(crate) ident: Ident, + pub(crate) field: Ident, + #[label(hir_typeck_no_field_on_variant_enum)] + pub(crate) enum_span: Span, + #[label(hir_typeck_no_field_on_variant_field)] + pub(crate) field_span: Span, +} + #[derive(Diagnostic)] #[diag(hir_typeck_cant_dereference, code = E0614)] pub(crate) struct CantDereference<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index a857a91834e6..43dfec0f408b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -46,8 +46,9 @@ use crate::errors::{ AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr, BaseExpressionDoubleDotEnableDefaultFieldValues, BaseExpressionDoubleDotRemove, CantDereference, FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, - HelpUseLatestEdition, ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody, - StructExprNonExhaustive, TypeMismatchFruTypo, YieldExprOutsideOfCoroutine, + HelpUseLatestEdition, NoFieldOnType, NoFieldOnVariant, ReturnLikeStatementKind, + ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, TypeMismatchFruTypo, + YieldExprOutsideOfCoroutine, }; use crate::{ BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, Needs, cast, fatally_break_rust, @@ -3282,13 +3283,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let span = field.span; debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t); - let mut err = type_error_struct!( - self.dcx(), - span, - expr_t, - E0609, - "no field `{field}` on type `{expr_t}`", - ); + let mut err = self.dcx().create_err(NoFieldOnType { span, ty: expr_t, field }); + if expr_t.references_error() { + err.downgrade_to_delayed_bug(); + } // try to add a suggestion in case the field is a nested field of a field of the Adt let mod_id = self.tcx.parent_module(id).to_def_id(); @@ -3862,16 +3860,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter_enumerated() .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident) else { - type_error_struct!( - self.dcx(), - ident.span, - container, - E0609, - "no field named `{subfield}` on enum variant `{container}::{ident}`", - ) - .with_span_label(field.span, "this enum variant...") - .with_span_label(subident.span, "...does not have this field") - .emit(); + self.dcx() + .create_err(NoFieldOnVariant { + span: ident.span, + container, + ident, + field: subfield, + enum_span: field.span, + field_span: subident.span, + }) + .emit_unless(container.references_error()); break; }; diff --git a/tests/ui/diagnostic-width/long-E0609.rs b/tests/ui/diagnostic-width/long-E0609.rs index ae57e4f76d2f..39442bdeae03 100644 --- a/tests/ui/diagnostic-width/long-E0609.rs +++ b/tests/ui/diagnostic-width/long-E0609.rs @@ -7,7 +7,7 @@ type C = (B, B, B, B); type D = (C, C, C, C); fn foo(x: D) { - x.field; //~ ERROR no field `field` on type `( + x.field; //~ ERROR no field `field` on type `(... } fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0609.stderr b/tests/ui/diagnostic-width/long-E0609.stderr index 708cd4ef93a8..6815caa6b6ba 100644 --- a/tests/ui/diagnostic-width/long-E0609.stderr +++ b/tests/ui/diagnostic-width/long-E0609.stderr @@ -1,8 +1,11 @@ -error[E0609]: no field `field` on type `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))` +error[E0609]: no field `field` on type `(..., ..., ..., ...)` --> $DIR/long-E0609.rs:10:7 | LL | x.field; | ^^^^^ unknown field + | + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error From a4e89deb52eac24d857823f46a3f38b02178731a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 18 Feb 2025 20:45:27 +0000 Subject: [PATCH 320/991] add doc comment detail --- compiler/rustc_errors/src/diagnostic.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 97daf891b0fe..7fffeaddb866 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -148,6 +148,12 @@ where /// converted rather than on `DiagArgValue`, which enables types from other `rustc_*` crates to /// implement this. pub trait IntoDiagArg { + /// Convert `Self` into a `DiagArgValue` suitable for rendering in a diagnostic. + /// + /// It takes a `path` where "long values" could be written to, if the `DiagArgValue` is too big + /// for displaying on the terminal. This path comes from the `Diag` itself. When rendering + /// values that come from `TyCtxt`, like `Ty<'_>`, they can use `TyCtxt::short_string`. If a + /// value has no shortening logic that could be used, the argument can be safely ignored. fn into_diag_arg(self, path: &mut Option) -> DiagArgValue; } From 716dd22c04e936853b9bc963da616e1b28525e6b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Feb 2025 16:53:18 +0100 Subject: [PATCH 321/991] disable float non-determinism for now to be able to complete the sync --- src/build_helper/src/git.rs | 1 - src/tools/miri/src/intrinsics/mod.rs | 22 +++++---- src/tools/miri/src/shims/foreign_items.rs | 56 +++++++++++++---------- src/tools/miri/tests/pass/float.rs | 4 +- 4 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 3ef9c7ac35e9..8f0b67ddbd36 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -154,7 +154,6 @@ pub fn get_closest_merge_commit( "rev-list", &format!("--author={}", config.git_merge_commit_email), "-n1", - "--first-parent", &merge_base, ]); diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index b85e38eab2aa..85fb280a9a90 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -251,11 +251,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = res.to_soft(); // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = apply_random_float_error_ulp( - this, - res, - 4, // log2(16) - ); + // FIXME: temporarily disabled as it breaks std tests. + // let res = apply_random_float_error_ulp( + // this, + // res, + // 4, // log2(16) + // ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } @@ -286,11 +287,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = res.to_soft(); // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = apply_random_float_error_ulp( - this, - res, - 4, // log2(16) - ); + // FIXME: temporarily disabled as it breaks std tests. + // let res = apply_random_float_error_ulp( + // this, + // res, + // 4, // log2(16) + // ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index ee755e4c1826..505c079143a4 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -765,13 +765,15 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "erfcf" => f_host.erfc(), _ => bug!(), }; + let res = res.to_soft(); // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = math::apply_random_float_error_ulp( - this, - res.to_soft(), - 4, // log2(16) - ); + // FIXME: temporarily disabled as it breaks std tests. + // let res = math::apply_random_float_error_ulp( + // this, + // res, + // 4, // log2(16) + // ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } @@ -796,11 +798,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { }; // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = math::apply_random_float_error_ulp( - this, - res, - 4, // log2(16) - ); + // FIXME: temporarily disabled as it breaks std tests. + // let res = math::apply_random_float_error_ulp( + // this, + // res, + // 4, // log2(16) + // ); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; } @@ -839,13 +842,15 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "erfc" => f_host.erfc(), _ => bug!(), }; + let res = res.to_soft(); // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = math::apply_random_float_error_ulp( - this, - res.to_soft(), - 4, // log2(16) - ); + // FIXME: temporarily disabled as it breaks std tests. + // let res = math::apply_random_float_error_ulp( + // this, + // res.to_soft(), + // 4, // log2(16) + // ); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } @@ -870,11 +875,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { }; // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = math::apply_random_float_error_ulp( - this, - res, - 4, // log2(16) - ); + // FIXME: temporarily disabled as it breaks std tests. + // let res = math::apply_random_float_error_ulp( + // this, + // res, + // 4, // log2(16) + // ); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; } @@ -900,10 +906,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Using host floats (but it's fine, these operations do not have guaranteed precision). let (res, sign) = x.to_host().ln_gamma(); this.write_int(sign, &signp)?; + let res = res.to_soft(); // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = - math::apply_random_float_error_ulp(this, res.to_soft(), 4 /* log2(16) */); + // FIXME: temporarily disabled as it breaks std tests. + // let res = math::apply_random_float_error_ulp(this, res, 4 /* log2(16) */); let res = this.adjust_nan(res, &[x]); this.write_scalar(res, dest)?; } @@ -915,10 +922,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Using host floats (but it's fine, these operations do not have guaranteed precision). let (res, sign) = x.to_host().ln_gamma(); this.write_int(sign, &signp)?; + let res = res.to_soft(); // Apply a relative error of 16ULP to introduce some non-determinism // simulating imprecise implementations and optimizations. - let res = - math::apply_random_float_error_ulp(this, res.to_soft(), 4 /* log2(16) */); + // FIXME: temporarily disabled as it breaks std tests. + // let res = math::apply_random_float_error_ulp(this, res, 4 /* log2(16) */); let res = this.adjust_nan(res, &[x]); this.write_scalar(res, dest)?; } diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index d8792a6c3026..b3b6fe1a5d73 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -1281,6 +1281,7 @@ fn test_non_determinism() { /// Ensure that the operation is non-deterministic #[track_caller] fn ensure_nondet(f: impl Fn() -> T) { + let rounds = 16; let first = f(); for _ in 1..rounds { @@ -1290,7 +1291,8 @@ fn test_non_determinism() { } } // We saw the same thing N times. - panic!("expected non-determinism, got {rounds} times the same result: {first:?}"); + // FIXME: temporarily disabled as it breaks std tests. + //panic!("expected non-determinism, got {rounds} times the same result: {first:?}"); } macro_rules! test_operations_f { From 4bf66c57fad749b0efe331c4c9e40f0a65e56e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 25 Feb 2025 16:53:10 +0100 Subject: [PATCH 322/991] fix #137589 --- compiler/rustc_attr_parsing/src/context.rs | 5 ++++- compiler/rustc_attr_parsing/src/parser.rs | 13 +++++++----- tests/ui/attributes/crate-type-macro-empty.rs | 7 +++++++ .../attributes/crate-type-macro-empty.stderr | 20 +++++++++++++++++++ .../attributes/crate-type-macro-not-crate.rs | 9 +++++++++ .../crate-type-macro-not-crate.stderr | 17 ++++++++++++++++ .../attributes/crate-type-macro-not-found.rs | 8 ++++++++ .../crate-type-macro-not-found.stderr | 14 +++++++++++++ 8 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 tests/ui/attributes/crate-type-macro-empty.rs create mode 100644 tests/ui/attributes/crate-type-macro-empty.stderr create mode 100644 tests/ui/attributes/crate-type-macro-not-crate.rs create mode 100644 tests/ui/attributes/crate-type-macro-not-crate.stderr create mode 100644 tests/ui/attributes/crate-type-macro-not-found.rs create mode 100644 tests/ui/attributes/crate-type-macro-not-found.stderr diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 99eee0d3c4a2..0e6b0bab082e 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -333,7 +333,10 @@ impl<'sess> AttributeParser<'sess> { { lit } else { - let guar = self.dcx().has_errors().unwrap(); + let guar = self.dcx().span_delayed_bug( + args.span().unwrap_or(DUMMY_SP), + "expr in place where literal is expected (builtin attr parsing)", + ); ast::MetaItemLit { symbol: kw::Empty, suffix: None, diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 0ee0ea4ea595..b6d66af4466e 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -13,7 +13,7 @@ use rustc_ast_pretty::pprust; use rustc_errors::DiagCtxtHandle; use rustc_hir::{self as hir, AttrPath}; use rustc_span::symbol::{Ident, kw}; -use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol}; +use rustc_span::{ErrorGuaranteed, Span, Symbol}; pub struct SegmentIterator<'a> { offset: usize, @@ -127,7 +127,7 @@ impl<'a> ArgParser<'a> { } AttrArgs::Eq { eq_span, expr } => Self::NameValue(NameValueParser { eq_span: *eq_span, - value: expr_to_lit(dcx, &expr), + value: expr_to_lit(dcx, &expr, *eq_span), value_span: expr.span, }), } @@ -348,7 +348,7 @@ impl NameValueParser { } } -fn expr_to_lit(dcx: DiagCtxtHandle<'_>, expr: &Expr) -> MetaItemLit { +fn expr_to_lit(dcx: DiagCtxtHandle<'_>, expr: &Expr, span: Span) -> MetaItemLit { // In valid code the value always ends up as a single literal. Otherwise, a dummy // literal suffices because the error is handled elsewhere. if let ExprKind::Lit(token_lit) = expr.kind @@ -356,8 +356,11 @@ fn expr_to_lit(dcx: DiagCtxtHandle<'_>, expr: &Expr) -> MetaItemLit { { lit } else { - let guar = dcx.has_errors().unwrap(); - MetaItemLit { symbol: kw::Empty, suffix: None, kind: LitKind::Err(guar), span: DUMMY_SP } + let guar = dcx.span_delayed_bug( + span, + "expr in place where literal is expected (builtin attr parsing)", + ); + MetaItemLit { symbol: kw::Empty, suffix: None, kind: LitKind::Err(guar), span } } } diff --git a/tests/ui/attributes/crate-type-macro-empty.rs b/tests/ui/attributes/crate-type-macro-empty.rs new file mode 100644 index 000000000000..5ff7fc002fde --- /dev/null +++ b/tests/ui/attributes/crate-type-macro-empty.rs @@ -0,0 +1,7 @@ +// Tests for the issue in #137589 +#[crate_type = foo!()] +//~^ ERROR cannot find macro `foo` in this scope + +macro_rules! foo {} //~ ERROR unexpected end of macro invocation + +fn main() {} diff --git a/tests/ui/attributes/crate-type-macro-empty.stderr b/tests/ui/attributes/crate-type-macro-empty.stderr new file mode 100644 index 000000000000..e48d3d95470d --- /dev/null +++ b/tests/ui/attributes/crate-type-macro-empty.stderr @@ -0,0 +1,20 @@ +error: unexpected end of macro invocation + --> $DIR/crate-type-macro-empty.rs:5:1 + | +LL | macro_rules! foo {} + | ^^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments + +error: cannot find macro `foo` in this scope + --> $DIR/crate-type-macro-empty.rs:2:16 + | +LL | #[crate_type = foo!()] + | ^^^ consider moving the definition of `foo` before this call + | +note: a macro with the same name exists, but it appears later + --> $DIR/crate-type-macro-empty.rs:5:14 + | +LL | macro_rules! foo {} + | ^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/attributes/crate-type-macro-not-crate.rs b/tests/ui/attributes/crate-type-macro-not-crate.rs new file mode 100644 index 000000000000..e5eb22d6f6e2 --- /dev/null +++ b/tests/ui/attributes/crate-type-macro-not-crate.rs @@ -0,0 +1,9 @@ +// Tests for the issue in #137589 + + +macro_rules! foo { + ($x:expr) => {"rlib"} +} + +#[crate_type = foo!()] //~ ERROR unexpected end of macro invocation +fn main() {} diff --git a/tests/ui/attributes/crate-type-macro-not-crate.stderr b/tests/ui/attributes/crate-type-macro-not-crate.stderr new file mode 100644 index 000000000000..ce188b3eef5f --- /dev/null +++ b/tests/ui/attributes/crate-type-macro-not-crate.stderr @@ -0,0 +1,17 @@ +error: unexpected end of macro invocation + --> $DIR/crate-type-macro-not-crate.rs:8:16 + | +LL | macro_rules! foo { + | ---------------- when calling this macro +... +LL | #[crate_type = foo!()] + | ^^^^^^ missing tokens in macro arguments + | +note: while trying to match meta-variable `$x:expr` + --> $DIR/crate-type-macro-not-crate.rs:5:6 + | +LL | ($x:expr) => {"rlib"} + | ^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/crate-type-macro-not-found.rs b/tests/ui/attributes/crate-type-macro-not-found.rs new file mode 100644 index 000000000000..824468c0e85b --- /dev/null +++ b/tests/ui/attributes/crate-type-macro-not-found.rs @@ -0,0 +1,8 @@ +// Tests for the issue in #137589 +#[crate_type = foo!()] //~ ERROR cannot find macro `foo` in this scope + +macro_rules! foo { + ($x:expr) => {"rlib"} +} + +fn main() {} diff --git a/tests/ui/attributes/crate-type-macro-not-found.stderr b/tests/ui/attributes/crate-type-macro-not-found.stderr new file mode 100644 index 000000000000..a4967e4f12e9 --- /dev/null +++ b/tests/ui/attributes/crate-type-macro-not-found.stderr @@ -0,0 +1,14 @@ +error: cannot find macro `foo` in this scope + --> $DIR/crate-type-macro-not-found.rs:2:16 + | +LL | #[crate_type = foo!()] + | ^^^ consider moving the definition of `foo` before this call + | +note: a macro with the same name exists, but it appears later + --> $DIR/crate-type-macro-not-found.rs:4:14 + | +LL | macro_rules! foo { + | ^^^ + +error: aborting due to 1 previous error + From c550bee64148a8f702f5fd18d4da75b93832c4df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 25 Feb 2025 17:27:22 +0000 Subject: [PATCH 323/991] Fix rebase --- compiler/rustc_errors/src/diagnostic_impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index e0c8caf1317e..cb2e1769fa1c 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -98,7 +98,7 @@ into_diag_arg_using_display!( ); impl IntoDiagArg for RustcVersion { - fn into_diag_arg(self) -> DiagArgValue { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Owned(self.to_string())) } } From b6f22400002f7921feed13e35852e3041cf2b145 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Feb 2025 20:26:12 +0100 Subject: [PATCH 324/991] rustdoc: disable forbidden #[target_feature] check --- compiler/rustc_codegen_ssa/src/target_features.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index d8b9bdb55da6..28c6932dd5b9 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -87,7 +87,10 @@ pub(crate) fn from_target_feature_attr( // But ensure the ABI does not forbid enabling this. // Here we do assume that LLVM doesn't add even more implied features // we don't know about, at least no features that would have ABI effects! - if abi_feature_constraints.incompatible.contains(&name.as_str()) { + // We skip this check in rustdoc, like we skip all target feature related checks. + if !tcx.sess.opts.actually_rustdoc + && abi_feature_constraints.incompatible.contains(&name.as_str()) + { tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr { span: item.span(), feature: name.as_str(), @@ -142,8 +145,11 @@ pub(crate) fn provide(providers: &mut Providers) { rust_target_features: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); if tcx.sess.opts.actually_rustdoc { - // rustdoc needs to be able to document functions that use all the features, so - // whitelist them all + // HACK: rustdoc would like to pretend that we have all the target features, so we + // have to merge all the lists into one. The result has a "random" stability + // (depending on the order in which we consider features); all places that check + // target stability are expected to check `actually_rustdoc` and do nothing when + // that is set. rustc_target::target_features::all_rust_features() .map(|(a, b)| (a.to_string(), b)) .collect() From 039af88e09f4f4beb47406f4771bffc2e61d800a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 25 Feb 2025 20:38:13 +0100 Subject: [PATCH 325/991] also fix potential issues with mixed stable/unstable target features in rustdoc --- .../rustc_codegen_ssa/src/target_features.rs | 45 ++++++++++++++----- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 28c6932dd5b9..a63e1877e453 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -10,7 +10,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, sym}; -use rustc_target::target_features; +use rustc_target::target_features::{self, Stability}; use crate::errors; @@ -87,10 +87,7 @@ pub(crate) fn from_target_feature_attr( // But ensure the ABI does not forbid enabling this. // Here we do assume that LLVM doesn't add even more implied features // we don't know about, at least no features that would have ABI effects! - // We skip this check in rustdoc, like we skip all target feature related checks. - if !tcx.sess.opts.actually_rustdoc - && abi_feature_constraints.incompatible.contains(&name.as_str()) - { + if abi_feature_constraints.incompatible.contains(&name.as_str()) { tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr { span: item.span(), feature: name.as_str(), @@ -146,13 +143,37 @@ pub(crate) fn provide(providers: &mut Providers) { assert_eq!(cnum, LOCAL_CRATE); if tcx.sess.opts.actually_rustdoc { // HACK: rustdoc would like to pretend that we have all the target features, so we - // have to merge all the lists into one. The result has a "random" stability - // (depending on the order in which we consider features); all places that check - // target stability are expected to check `actually_rustdoc` and do nothing when - // that is set. - rustc_target::target_features::all_rust_features() - .map(|(a, b)| (a.to_string(), b)) - .collect() + // have to merge all the lists into one. To ensure an unstable target never prevents + // a stable one from working, we merge the stability info of all instances of the + // same target feature name, with the "most stable" taking precedence. And then we + // hope that this doesn't cause issues anywhere else in the compiler... + let mut result: UnordMap = Default::default(); + for (name, stability) in rustc_target::target_features::all_rust_features() { + use std::collections::hash_map::Entry; + match result.entry(name.to_owned()) { + Entry::Vacant(vacant_entry) => { + vacant_entry.insert(stability); + } + Entry::Occupied(mut occupied_entry) => { + // Merge the two stabilities, "more stable" taking precedence. + match (occupied_entry.get(), stability) { + (Stability::Stable, _) + | ( + Stability::Unstable { .. }, + Stability::Unstable { .. } | Stability::Forbidden { .. }, + ) + | (Stability::Forbidden { .. }, Stability::Forbidden { .. }) => { + // The stability in the entry is at least as good as the new one, just keep it. + } + _ => { + // Overwrite stabilite. + occupied_entry.insert(stability); + } + } + } + } + } + result } else { tcx.sess .target From 9313580e2aa4f7463d9413169fe5d70eba7a7428 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 25 Feb 2025 20:01:48 +0000 Subject: [PATCH 326/991] Don't suggest constraining unstable associated types --- .../src/error_reporting/traits/suggestions.rs | 5 ++++- .../async-await/async-fn/suggest-constrain.rs | 11 +++++++++++ .../async-fn/suggest-constrain.stderr | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/ui/async-await/async-fn/suggest-constrain.rs create mode 100644 tests/ui/async-await/async-fn/suggest-constrain.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index c7e71a626dc5..0ff00e752a26 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -136,7 +136,10 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>( ) { if hir_generics.where_clause_span.from_expansion() || hir_generics.where_clause_span.desugaring_kind().is_some() - || projection.is_some_and(|projection| tcx.is_impl_trait_in_trait(projection.def_id)) + || projection.is_some_and(|projection| { + tcx.is_impl_trait_in_trait(projection.def_id) + || tcx.lookup_stability(projection.def_id).is_some_and(|stab| stab.is_unstable()) + }) { return; } diff --git a/tests/ui/async-await/async-fn/suggest-constrain.rs b/tests/ui/async-await/async-fn/suggest-constrain.rs new file mode 100644 index 000000000000..319dcc0084a7 --- /dev/null +++ b/tests/ui/async-await/async-fn/suggest-constrain.rs @@ -0,0 +1,11 @@ +// Ensure that we don't suggest constraining `CallRefFuture` here, +// since that isn't stable. + +fn spawn(f: F) { + check_send(f()); + //~^ ERROR cannot be sent between threads safely +} + +fn check_send(_: T) {} + +fn main() {} diff --git a/tests/ui/async-await/async-fn/suggest-constrain.stderr b/tests/ui/async-await/async-fn/suggest-constrain.stderr new file mode 100644 index 000000000000..94270aad63e2 --- /dev/null +++ b/tests/ui/async-await/async-fn/suggest-constrain.stderr @@ -0,0 +1,18 @@ +error[E0277]: `>::CallRefFuture<'_>` cannot be sent between threads safely + --> $DIR/suggest-constrain.rs:5:16 + | +LL | check_send(f()); + | ---------- ^^^ `>::CallRefFuture<'_>` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Send` is not implemented for `>::CallRefFuture<'_>` +note: required by a bound in `check_send` + --> $DIR/suggest-constrain.rs:9:18 + | +LL | fn check_send(_: T) {} + | ^^^^ required by this bound in `check_send` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From b7a549725c98de36144e1257b5fbca5372d82a51 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 26 Feb 2025 04:12:20 +0900 Subject: [PATCH 327/991] fix #137508 rename ui tests check if res is trait def fix typo regression test for #137554 --- .../src/hir_ty_lowering/errors.rs | 6 +++- ...issing-associated_item_or_field_def_ids.rs | 8 ++++++ ...ng-associated_item_or_field_def_ids.stderr | 25 +++++++++++++++++ ...ing-associated-items-of-undefined-trait.rs | 12 ++++++++ ...associated-items-of-undefined-trait.stderr | 28 +++++++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs create mode 100644 tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr create mode 100644 tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs create mode 100644 tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 7eb982a31798..1b1f4bf44188 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -789,7 +789,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some(args.constraints.iter().filter_map(|constraint| { let ident = constraint.ident; - let trait_def = path.res.def_id(); + + let Res::Def(DefKind::Trait, trait_def) = path.res else { + return None; + }; + let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind( tcx, ident, diff --git a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs new file mode 100644 index 000000000000..b90bb9ea4ddf --- /dev/null +++ b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs @@ -0,0 +1,8 @@ +// Regression test for . + +fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { + //~^ ERROR `?Trait` is not permitted in trait object types + //~| ERROR expected trait, found associated function `Iterator::advance_by` + //~| ERROR the value of the associated type `Item` in `Iterator` must be specified + todo!() +} diff --git a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr new file mode 100644 index 000000000000..7f0fbc800ed1 --- /dev/null +++ b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr @@ -0,0 +1,25 @@ +error[E0658]: `?Trait` is not permitted in trait object types + --> $DIR/missing-associated_item_or_field_def_ids.rs:3:29 + | +LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0404]: expected trait, found associated function `Iterator::advance_by` + --> $DIR/missing-associated_item_or_field_def_ids.rs:3:30 + | +LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a trait + +error[E0191]: the value of the associated type `Item` in `Iterator` must be specified + --> $DIR/missing-associated_item_or_field_def_ids.rs:3:18 + | +LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { + | ^^^^^^^^ help: specify the associated type: `Iterator` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0191, E0404, E0658. +For more information about an error, try `rustc --explain E0191`. diff --git a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs new file mode 100644 index 000000000000..f6b749a5100b --- /dev/null +++ b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs @@ -0,0 +1,12 @@ +// Fix for . + +trait Tr { + type Item; +} + +fn main() { + let _: dyn Tr + ?Foo; + //~^ ERROR: `?Trait` is not permitted in trait object types + //~| ERROR: cannot find trait `Foo` in this scope + //~| ERROR: the value of the associated type `Item` in `Tr` must be specified +} diff --git a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr new file mode 100644 index 000000000000..f31a1de76a79 --- /dev/null +++ b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr @@ -0,0 +1,28 @@ +error[E0658]: `?Trait` is not permitted in trait object types + --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:21 + | +LL | let _: dyn Tr + ?Foo; + | ^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0405]: cannot find trait `Foo` in this scope + --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:22 + | +LL | let _: dyn Tr + ?Foo; + | ^^^ not found in this scope + +error[E0191]: the value of the associated type `Item` in `Tr` must be specified + --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:16 + | +LL | type Item; + | --------- `Item` defined here +... +LL | let _: dyn Tr + ?Foo; + | ^^ help: specify the associated type: `Tr` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0191, E0405, E0658. +For more information about an error, try `rustc --explain E0191`. From 33ee398fdaa849e096e4935dba7cf599b9f6b832 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Tue, 25 Feb 2025 13:02:48 -0800 Subject: [PATCH 328/991] More precisely document `Global::deallocate()`'s safety. There is a subtlety which "other conditions must be upheld by the caller" does not capture: `GlobalAlloc`/`alloc::dealloc()` require that the provided layout will be *equal*, not just that it "fits", the layout used to allocate. This is always true here due to how `allocate()`, `grow()`, and `shrink()` are implemented (they never return a larger allocation than requested), but that is a non-local property of the implementation, so it should be documented explicitly. --- library/alloc/src/alloc.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index e686a02f29b0..3bfdc68dcdaf 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -264,8 +264,14 @@ unsafe impl Allocator for Global { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { if layout.size() != 0 { - // SAFETY: `layout` is non-zero in size, - // other conditions must be upheld by the caller + // SAFETY: + // * We have checked that `layout` is non-zero in size. + // * The caller is obligated to provide a layout that "fits", and in this case, + // "fit" always means a layout that is equal to the original, because our + // `allocate()`, `grow()`, and `shrink()` implementations never returns a larger + // allocation than requested. + // * Other conditions must be upheld by the caller, as per `Allocator::deallocate()`'s + // safety documentation. unsafe { dealloc(ptr.as_ptr(), layout) } } } From a7bd4a309c2d154ab4bafee9b575d4196b5d3222 Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 25 Feb 2025 22:26:52 +0000 Subject: [PATCH 329/991] Add DWARF test case for non-C-like `repr128` enums --- tests/run-make/repr128-dwarf/main.rs | 25 ++++++ tests/run-make/repr128-dwarf/rmake.rs | 117 +++++++++++++++++++++----- 2 files changed, 120 insertions(+), 22 deletions(-) diff --git a/tests/run-make/repr128-dwarf/main.rs b/tests/run-make/repr128-dwarf/main.rs index 57923a8386db..9842ab4a3426 100644 --- a/tests/run-make/repr128-dwarf/main.rs +++ b/tests/run-make/repr128-dwarf/main.rs @@ -19,8 +19,33 @@ pub enum I128Enum { I128D = i128::MAX.to_le(), } +#[cfg(not(old_llvm))] +#[repr(u128)] +pub enum U128VariantEnum { + VariantU128A(u8) = 0_u128.to_le(), + VariantU128B = 1_u128.to_le(), + VariantU128C = (u64::MAX as u128 + 1).to_le(), + VariantU128D = u128::MAX.to_le(), +} + +#[cfg(not(old_llvm))] +#[repr(i128)] +pub enum I128VariantEnum { + VariantI128A(u8) = 0_i128.to_le(), + VariantI128B = (-1_i128).to_le(), + VariantI128C = i128::MIN.to_le(), + VariantI128D = i128::MAX.to_le(), +} + pub fn f(_: U128Enum, _: I128Enum) {} +#[cfg(not(old_llvm))] +pub fn g(_: U128VariantEnum, _: I128VariantEnum) {} + fn main() { f(U128Enum::U128A, I128Enum::I128A); + #[cfg(not(old_llvm))] + { + g(U128VariantEnum::VariantU128A(1), I128VariantEnum::VariantI128A(2)); + } } diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs index 2fd54c186b93..15eb186717f6 100644 --- a/tests/run-make/repr128-dwarf/rmake.rs +++ b/tests/run-make/repr128-dwarf/rmake.rs @@ -5,13 +5,32 @@ use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; +use gimli::read::DebuggingInformationEntry; use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian}; use object::{Object, ObjectSection}; use run_make_support::{gimli, object, rfs, rustc}; fn main() { + // Before LLVM 20, 128-bit enums with variants didn't emit debuginfo correctly. + // This check can be removed once Rust no longer supports LLVM 18 and 19. + let llvm_version = rustc() + .verbose() + .arg("--version") + .run() + .stdout_utf8() + .lines() + .filter_map(|line| line.strip_prefix("LLVM version: ")) + .map(|version| version.split(".").next().unwrap().parse::().unwrap()) + .next() + .unwrap(); + let is_old_llvm = llvm_version < 20; + let output = PathBuf::from("repr128"); - rustc().input("main.rs").output(&output).arg("-Cdebuginfo=2").run(); + let mut rustc = rustc(); + if is_old_llvm { + rustc.cfg("old_llvm"); + } + rustc.input("main.rs").output(&output).arg("-Cdebuginfo=2").run(); // Mach-O uses packed debug info let dsym_location = output .with_extension("dSYM") @@ -29,7 +48,8 @@ fn main() { }) .unwrap(); let mut iter = dwarf.units(); - let mut still_to_find = HashMap::from([ + + let mut enumerators_to_find = HashMap::from([ ("U128A", 0_u128), ("U128B", 1_u128), ("U128C", u64::MAX as u128 + 1), @@ -39,35 +59,88 @@ fn main() { ("I128C", i128::MIN as u128), ("I128D", i128::MAX as u128), ]); + let mut variants_to_find = HashMap::from([ + ("VariantU128A", 0_u128), + ("VariantU128B", 1_u128), + ("VariantU128C", u64::MAX as u128 + 1), + ("VariantU128D", u128::MAX), + ("VariantI128A", 0_i128 as u128), + ("VariantI128B", (-1_i128) as u128), + ("VariantI128C", i128::MIN as u128), + ("VariantI128D", i128::MAX as u128), + ]); + while let Some(header) = iter.next().unwrap() { let unit = dwarf.unit(header).unwrap(); let mut cursor = unit.entries(); + + let get_name = |entry: &DebuggingInformationEntry<'_, '_, _>| { + let name = dwarf + .attr_string( + &unit, + entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(), + ) + .unwrap(); + name.to_string().unwrap().to_string() + }; + while let Some((_, entry)) = cursor.next_dfs().unwrap() { - if entry.tag() == gimli::constants::DW_TAG_enumerator { - let name = dwarf - .attr_string( - &unit, - entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(), - ) - .unwrap(); - let name = name.to_string().unwrap(); - if let Some(expected) = still_to_find.remove(name.as_ref()) { - match entry.attr(gimli::constants::DW_AT_const_value).unwrap().unwrap().value() + match entry.tag() { + gimli::constants::DW_TAG_variant if !is_old_llvm => { + let value = match entry + .attr(gimli::constants::DW_AT_discr_value) + .unwrap() + .unwrap() + .value() { - AttributeValue::Block(value) => { - assert_eq!( - value.to_slice().unwrap(), - expected.to_le_bytes().as_slice(), - "{name}" - ); - } - value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"), + AttributeValue::Block(value) => value.to_slice().unwrap().to_vec(), + value => panic!("unexpected DW_AT_discr_value of {value:?}"), + }; + // The `DW_TAG_member` that is a child of `DW_TAG_variant` will contain the + // variant's name. + let Some((1, child_entry)) = cursor.next_dfs().unwrap() else { + panic!("Missing child of DW_TAG_variant"); + }; + assert_eq!(child_entry.tag(), gimli::constants::DW_TAG_member); + let name = get_name(child_entry); + if let Some(expected) = variants_to_find.remove(name.as_str()) { + // This test uses LE byte order is used for consistent values across + // architectures. + assert_eq!(value.as_slice(), expected.to_le_bytes().as_slice(), "{name}"); } } + + gimli::constants::DW_TAG_enumerator => { + let name = get_name(entry); + if let Some(expected) = enumerators_to_find.remove(name.as_str()) { + match entry + .attr(gimli::constants::DW_AT_const_value) + .unwrap() + .unwrap() + .value() + { + AttributeValue::Block(value) => { + // This test uses LE byte order is used for consistent values across + // architectures. + assert_eq!( + value.to_slice().unwrap(), + expected.to_le_bytes().as_slice(), + "{name}" + ); + } + value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"), + } + } + } + + _ => {} } } } - if !still_to_find.is_empty() { - panic!("Didn't find debug entries for {still_to_find:?}"); + if !enumerators_to_find.is_empty() { + panic!("Didn't find debug enumerator entries for {enumerators_to_find:?}"); + } + if !is_old_llvm && !variants_to_find.is_empty() { + panic!("Didn't find debug variant entries for {variants_to_find:?}"); } } From b41c232488e17b4d7447c74ab1143bbd51af43a0 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Fri, 21 Feb 2025 11:54:43 -0500 Subject: [PATCH 330/991] tests: fix up new test for nocapture -> capture(none) change Same motivation as #136287, but for a newly introduced test. Rather than over-constraining here, we just match the sret and accept pretty much all other attributes. @rustbot label llvm-main r? @nikic --- tests/codegen/uninhabited-transparent-return-abi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/codegen/uninhabited-transparent-return-abi.rs b/tests/codegen/uninhabited-transparent-return-abi.rs index 6e8b1683163e..face1577c3f6 100644 --- a/tests/codegen/uninhabited-transparent-return-abi.rs +++ b/tests/codegen/uninhabited-transparent-return-abi.rs @@ -24,7 +24,7 @@ extern "Rust" { pub fn test_uninhabited_ret_by_ref() { // CHECK: %_1 = alloca [24 x i8], align {{8|4}} // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_1) - // CHECK-NEXT: call void @opaque(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_1) #2 + // CHECK-NEXT: call void @opaque({{.*}} sret([24 x i8]) {{.*}} %_1) #2 // CHECK-NEXT: unreachable unsafe { opaque(); @@ -36,7 +36,7 @@ pub fn test_uninhabited_ret_by_ref() { pub fn test_uninhabited_ret_by_ref_with_arg(rsi: u32) { // CHECK: %_2 = alloca [24 x i8], align {{8|4}} // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_2) - // CHECK-NEXT: call void @opaque_with_arg(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_2, i32 noundef %rsi) #2 + // CHECK-NEXT: call void @opaque_with_arg({{.*}} sret([24 x i8]) {{.*}} %_2, i32 noundef %rsi) #2 // CHECK-NEXT: unreachable unsafe { opaque_with_arg(rsi); From 325bfef88d03cb79c6369d22adb14d997d090573 Mon Sep 17 00:00:00 2001 From: Bryce Berger Date: Sat, 22 Feb 2025 18:53:25 -0500 Subject: [PATCH 331/991] configuration option to lint `incompatible_msrv` in test code --- CHANGELOG.md | 1 + book/src/lint_configuration.md | 10 ++++++ clippy_config/src/conf.rs | 3 ++ clippy_lints/src/incompatible_msrv.rs | 4 ++- ..._incompatible_msrv_in_tests.default.stderr | 11 +++++++ ..._incompatible_msrv_in_tests.enabled.stderr | 23 ++++++++++++++ .../check_incompatible_msrv_in_tests.rs | 31 +++++++++++++++++++ .../default/clippy.toml | 1 + .../enabled/clippy.toml | 1 + .../toml_unknown_key/conf_unknown_key.stderr | 3 ++ 10 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.default.stderr create mode 100644 tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr create mode 100644 tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs create mode 100644 tests/ui-toml/check_incompatible_msrv_in_tests/default/clippy.toml create mode 100644 tests/ui-toml/check_incompatible_msrv_in_tests/enabled/clippy.toml diff --git a/CHANGELOG.md b/CHANGELOG.md index be5e95e9744e..58172b7a15dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6341,6 +6341,7 @@ Released 2018-09-13 [`avoid-breaking-exported-api`]: https://doc.rust-lang.org/clippy/lint_configuration.html#avoid-breaking-exported-api [`await-holding-invalid-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#await-holding-invalid-types [`cargo-ignore-publish`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cargo-ignore-publish +[`check-incompatible-msrv-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-incompatible-msrv-in-tests [`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items [`cognitive-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cognitive-complexity-threshold [`disallowed-macros`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-macros diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 74c2be3479ec..5f4d31e2bad0 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -415,6 +415,16 @@ For internal testing only, ignores the current `publish` settings in the Cargo m * [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata) +## `check-incompatible-msrv-in-tests` +Whether to check MSRV compatibility in `#[test]` and `#[cfg(test)]` code. + +**Default Value:** `false` + +--- +**Affected lints:** +* [`incompatible_msrv`](https://rust-lang.github.io/rust-clippy/master/index.html#incompatible_msrv) + + ## `check-private-items` Whether to also run the listed lints on private items. diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index ff2a86182402..1dd7a6ac4219 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -464,6 +464,9 @@ define_Conf! { /// For internal testing only, ignores the current `publish` settings in the Cargo manifest. #[lints(cargo_common_metadata)] cargo_ignore_publish: bool = false, + /// Whether to check MSRV compatibility in `#[test]` and `#[cfg(test)]` code. + #[lints(incompatible_msrv)] + check_incompatible_msrv_in_tests: bool = false, /// Whether to also run the listed lints on private items. #[lints(missing_errors_doc, missing_panics_doc, missing_safety_doc, unnecessary_safety_doc)] check_private_items: bool = false, diff --git a/clippy_lints/src/incompatible_msrv.rs b/clippy_lints/src/incompatible_msrv.rs index b10206dcd05e..26df41e42a60 100644 --- a/clippy_lints/src/incompatible_msrv.rs +++ b/clippy_lints/src/incompatible_msrv.rs @@ -42,6 +42,7 @@ declare_clippy_lint! { pub struct IncompatibleMsrv { msrv: Msrv, is_above_msrv: FxHashMap, + check_in_tests: bool, } impl_lint_pass!(IncompatibleMsrv => [INCOMPATIBLE_MSRV]); @@ -51,6 +52,7 @@ impl IncompatibleMsrv { Self { msrv: conf.msrv.clone(), is_above_msrv: FxHashMap::default(), + check_in_tests: conf.check_incompatible_msrv_in_tests, } } @@ -87,7 +89,7 @@ impl IncompatibleMsrv { return; } let version = self.get_def_id_version(cx.tcx, def_id); - if self.msrv.meets(version) || is_in_test(cx.tcx, node) { + if self.msrv.meets(version) || (!self.check_in_tests && is_in_test(cx.tcx, node)) { return; } if let ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) = span.ctxt().outer_expn_data().kind { diff --git a/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.default.stderr b/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.default.stderr new file mode 100644 index 000000000000..2a6170b0bcdc --- /dev/null +++ b/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.default.stderr @@ -0,0 +1,11 @@ +error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0` + --> tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs:14:5 + | +LL | sleep(Duration::new(1, 0)) + | ^^^^^ + | + = note: `-D clippy::incompatible-msrv` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]` + +error: aborting due to 1 previous error + diff --git a/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr b/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr new file mode 100644 index 000000000000..8a85d38fba3c --- /dev/null +++ b/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr @@ -0,0 +1,23 @@ +error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0` + --> tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs:14:5 + | +LL | sleep(Duration::new(1, 0)) + | ^^^^^ + | + = note: `-D clippy::incompatible-msrv` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]` + +error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0` + --> tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs:20:5 + | +LL | sleep(Duration::new(1, 0)); + | ^^^^^ + +error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0` + --> tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs:28:9 + | +LL | sleep(Duration::new(1, 0)); + | ^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs b/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs new file mode 100644 index 000000000000..fed5f350b722 --- /dev/null +++ b/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs @@ -0,0 +1,31 @@ +//@compile-flags: --test +//@revisions: default enabled +//@[enabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/check_incompatible_msrv_in_tests/enabled +//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/check_incompatible_msrv_in_tests/default + +#![warn(clippy::incompatible_msrv)] +#![feature(custom_inner_attributes)] +#![clippy::msrv = "1.3.0"] + +use std::thread::sleep; +use std::time::Duration; + +fn main() { + sleep(Duration::new(1, 0)) + //~^ incompatible_msrv +} + +#[test] +fn test() { + sleep(Duration::new(1, 0)); + //~[enabled]^ incompatible_msrv +} + +#[cfg(test)] +mod tests { + use super::*; + fn helper() { + sleep(Duration::new(1, 0)); + //~[enabled]^ incompatible_msrv + } +} diff --git a/tests/ui-toml/check_incompatible_msrv_in_tests/default/clippy.toml b/tests/ui-toml/check_incompatible_msrv_in_tests/default/clippy.toml new file mode 100644 index 000000000000..1d13759aceb7 --- /dev/null +++ b/tests/ui-toml/check_incompatible_msrv_in_tests/default/clippy.toml @@ -0,0 +1 @@ +# default config has check-incompatible-msrv-in-tests as false diff --git a/tests/ui-toml/check_incompatible_msrv_in_tests/enabled/clippy.toml b/tests/ui-toml/check_incompatible_msrv_in_tests/enabled/clippy.toml new file mode 100644 index 000000000000..c56af6c82186 --- /dev/null +++ b/tests/ui-toml/check_incompatible_msrv_in_tests/enabled/clippy.toml @@ -0,0 +1 @@ +check-incompatible-msrv-in-tests = true diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 842059df1e92..acfe739277cc 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -31,6 +31,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect await-holding-invalid-types blacklisted-names cargo-ignore-publish + check-incompatible-msrv-in-tests check-private-items cognitive-complexity-threshold cyclomatic-complexity-threshold @@ -122,6 +123,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect await-holding-invalid-types blacklisted-names cargo-ignore-publish + check-incompatible-msrv-in-tests check-private-items cognitive-complexity-threshold cyclomatic-complexity-threshold @@ -213,6 +215,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni await-holding-invalid-types blacklisted-names cargo-ignore-publish + check-incompatible-msrv-in-tests check-private-items cognitive-complexity-threshold cyclomatic-complexity-threshold From ee8ed8c2072554feecd745c66b64ab1cc5f3dd95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 26 Feb 2025 09:23:52 +0100 Subject: [PATCH 332/991] Update gcc submodule To add support for the x87 feature. --- src/gcc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gcc b/src/gcc index e607be166673..48664a6cab29 160000 --- a/src/gcc +++ b/src/gcc @@ -1 +1 @@ -Subproject commit e607be166673a8de9fc07f6f02c60426e556c5f2 +Subproject commit 48664a6cab29d48138ffa004b7978d52ef73e3ac From 28d3fef3991d52cf7bf3908944191d86b487a815 Mon Sep 17 00:00:00 2001 From: DianQK Date: Wed, 26 Feb 2025 19:54:34 +0800 Subject: [PATCH 333/991] Add a test case for #137646 --- tests/ui/virtual-call-attrs-issue-137646.rs | 47 +++++++++++++++++++ ...virtual-call-attrs-issue-137646.run.stderr | 20 ++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/ui/virtual-call-attrs-issue-137646.rs create mode 100644 tests/ui/virtual-call-attrs-issue-137646.run.stderr diff --git a/tests/ui/virtual-call-attrs-issue-137646.rs b/tests/ui/virtual-call-attrs-issue-137646.rs new file mode 100644 index 000000000000..055dc6ea4f2d --- /dev/null +++ b/tests/ui/virtual-call-attrs-issue-137646.rs @@ -0,0 +1,47 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/137646. +//! FIXME: The parameter value at all calls to `check` should be `(1, 1, 1)`. + +//@ run-pass +//@ check-run-results + +use std::hint::black_box; + +type T = (i32, i32, i32); + +pub trait Trait { + fn m(&self, _: T, _: T) {} +} + +impl Trait for () { + fn m(&self, mut _v1: T, v2: T) { + _v1 = (0, 0, 0); + check(v2); + } +} + +pub fn run_1(trait_: &dyn Trait) { + let v1 = (1, 1, 1); + let v2 = (1, 1, 1); + trait_.m(v1, v2); +} + +pub fn run_2(trait_: &dyn Trait) { + let v1 = (1, 1, 1); + let v2 = (1, 1, 1); + trait_.m(v1, v2); + check(v1); + check(v2); +} + +#[inline(never)] +fn check(v: T) { + dbg!(v); + // assert_eq!(v, (1, 1, 1)); +} + +fn main() { + black_box(run_1 as fn(&dyn Trait)); + black_box(run_2 as fn(&dyn Trait)); + run_1(&()); + run_2(&()); +} diff --git a/tests/ui/virtual-call-attrs-issue-137646.run.stderr b/tests/ui/virtual-call-attrs-issue-137646.run.stderr new file mode 100644 index 000000000000..445975e1e54e --- /dev/null +++ b/tests/ui/virtual-call-attrs-issue-137646.run.stderr @@ -0,0 +1,20 @@ +[$DIR/virtual-call-attrs-issue-137646.rs:38:5] v = ( + 498486832, + 22093, + 498491440, +) +[$DIR/virtual-call-attrs-issue-137646.rs:38:5] v = ( + 0, + 0, + 0, +) +[$DIR/virtual-call-attrs-issue-137646.rs:38:5] v = ( + 0, + 0, + 0, +) +[$DIR/virtual-call-attrs-issue-137646.rs:38:5] v = ( + 0, + 0, + 0, +) From b8c7e8aa72e0ab103b781c7beaded88aeb49f8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Wed, 26 Feb 2025 13:07:12 +0100 Subject: [PATCH 334/991] Make -Z unpretty=mir suggest -Z dump-mir as well --- compiler/rustc_middle/src/mir/pretty.rs | 1 + tests/run-make/const_fn_mir/dump.mir | 1 + 2 files changed, 2 insertions(+) diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 875f5282bf29..f880b1364c2c 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -319,6 +319,7 @@ pub fn write_mir_pretty<'tcx>( writeln!(w, "// WARNING: This output format is intended for human consumers only")?; writeln!(w, "// and is subject to change without notice. Knock yourself out.")?; + writeln!(w, "// HINT: See also -Z dump-mir for MIR at specific points during compilation.")?; let mut first = true; for def_id in dump_mir_def_ids(tcx, single) { diff --git a/tests/run-make/const_fn_mir/dump.mir b/tests/run-make/const_fn_mir/dump.mir index b1802c990cf8..2b5c684bbef0 100644 --- a/tests/run-make/const_fn_mir/dump.mir +++ b/tests/run-make/const_fn_mir/dump.mir @@ -1,5 +1,6 @@ // WARNING: This output format is intended for human consumers only // and is subject to change without notice. Knock yourself out. +// HINT: See also -Z dump-mir for MIR at specific points during compilation. fn foo() -> i32 { let mut _0: i32; let mut _1: (i32, bool); From fae88f2ab5f0ea14f6bf99e63a6f743ce0709c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Wed, 26 Feb 2025 12:35:48 +0200 Subject: [PATCH 335/991] Use cargo zigbuild for releases --- .../.github/workflows/release.yaml | 55 +++++++++---------- src/tools/rust-analyzer/xtask/src/dist.rs | 29 +++++++--- src/tools/rust-analyzer/xtask/src/flags.rs | 3 + src/tools/rust-analyzer/xtask/src/release.rs | 2 +- 4 files changed, 49 insertions(+), 40 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml index 3687c84bea5c..9ab4a0b9d255 100644 --- a/src/tools/rust-analyzer/.github/workflows/release.yaml +++ b/src/tools/rust-analyzer/.github/workflows/release.yaml @@ -17,8 +17,8 @@ env: RUSTUP_MAX_RETRIES: 10 FETCH_DEPTH: 0 # pull in the tags for the version string MACOSX_DEPLOYMENT_TARGET: 13.0 - CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc - CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc + ZIG_VERSION: 0.13.0 + ZIGBUILD_VERSION: 0.19.8 jobs: dist: @@ -36,13 +36,15 @@ jobs: code-target: win32-arm64 - os: ubuntu-latest target: x86_64-unknown-linux-gnu + zig_target: x86_64-unknown-linux-gnu.2.28 code-target: linux-x64 - container: rockylinux:8 - - os: ubuntu-22.04 + - os: ubuntu-latest target: aarch64-unknown-linux-gnu + zig_target: aarch64-unknown-linux-gnu.2.28 code-target: linux-arm64 - - os: ubuntu-22.04 + - os: ubuntu-latest target: arm-unknown-linux-gnueabihf + zig_target: arm-unknown-linux-gnueabihf.2.28 code-target: linux-armhf - os: macos-13 target: x86_64-apple-darwin @@ -64,40 +66,33 @@ jobs: with: fetch-depth: ${{ env.FETCH_DEPTH }} - - name: Install toolchain dependencies - if: matrix.container == 'rockylinux:8' - shell: bash - run: | - dnf install -y gcc - curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --profile minimal --default-toolchain none -y - echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH + - name: Install Node.js toolchain + uses: actions/setup-node@v4 + with: + node-version: 20 - name: Install Rust toolchain run: | rustup update --no-self-update stable - rustup target add ${{ matrix.target }} rustup component add rust-src + rustup target add ${{ matrix.target }} - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: 18 + - name: Install Zig toolchain + if: ${{ matrix.zig_target }} + run: | + which cargo + curl -L "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-$(uname -m)-${ZIG_VERSION}.tar.xz" | sudo tar JxC /usr/local + sudo ln -s "/usr/local/zig-linux-$(uname -m)-${ZIG_VERSION}/zig" /usr/local/bin/zig + curl -L "https://github.com/rust-cross/cargo-zigbuild/releases/download/v${ZIGBUILD_VERSION}/cargo-zigbuild-v${ZIGBUILD_VERSION}.x86_64-unknown-linux-musl.tar.gz" | tar zxC ~/.cargo/bin - - name: Update apt repositories - if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf' - run: sudo apt-get update - - - name: Install AArch64 target toolchain - if: matrix.target == 'aarch64-unknown-linux-gnu' - run: sudo apt-get install gcc-aarch64-linux-gnu - - - name: Install ARM target toolchain - if: matrix.target == 'arm-unknown-linux-gnueabihf' - run: sudo apt-get install gcc-arm-linux-gnueabihf - - - name: Dist + - name: Dist (plain) + if: ${{ !matrix.zig_target }} run: cargo xtask dist --client-patch-version ${{ github.run_number }} + - name: Dist (using zigbuild) + if: ${{ matrix.zig_target }} + run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig + - run: npm ci working-directory: editors/code diff --git a/src/tools/rust-analyzer/xtask/src/dist.rs b/src/tools/rust-analyzer/xtask/src/dist.rs index c6a0be8aeb99..99483f4a5dc2 100644 --- a/src/tools/rust-analyzer/xtask/src/dist.rs +++ b/src/tools/rust-analyzer/xtask/src/dist.rs @@ -38,11 +38,11 @@ impl flags::Dist { // A hack to make VS Code prefer nightly over stable. format!("{VERSION_NIGHTLY}.{patch_version}") }; - dist_server(sh, &format!("{version}-standalone"), &target, allocator)?; + dist_server(sh, &format!("{version}-standalone"), &target, allocator, self.zig)?; let release_tag = if stable { date_iso(sh)? } else { "nightly".to_owned() }; dist_client(sh, &version, &release_tag, &target)?; } else { - dist_server(sh, "0.0.0-standalone", &target, allocator)?; + dist_server(sh, "0.0.0-standalone", &target, allocator, self.zig)?; } Ok(()) } @@ -83,6 +83,7 @@ fn dist_server( release: &str, target: &Target, allocator: Malloc, + zig: bool, ) -> anyhow::Result<()> { let _e = sh.push_env("CFG_RELEASE", release); let _e = sh.push_env("CARGO_PROFILE_RELEASE_LTO", "thin"); @@ -92,13 +93,14 @@ fn dist_server( // * on Linux, this blows up the binary size from 8MB to 43MB, which is unreasonable. // let _e = sh.push_env("CARGO_PROFILE_RELEASE_DEBUG", "1"); - if target.name.contains("-linux-") { - env::set_var("CC", "clang"); - } - - let target_name = &target.name; + let linux_target = target.is_linux(); + let target_name = match &target.libc_suffix { + Some(libc_suffix) if zig => format!("{}.{libc_suffix}", target.name), + _ => target.name.to_owned(), + }; let features = allocator.to_features(); - cmd!(sh, "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --release").run()?; + let command = if linux_target && zig { "zigbuild" } else { "build" }; + cmd!(sh, "cargo {command} --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --release").run()?; let dst = Path::new("dist").join(&target.artifact_name); if target_name.contains("-windows-") { @@ -156,6 +158,7 @@ fn zip(src_path: &Path, symbols_path: Option<&PathBuf>, dest_path: &Path) -> any struct Target { name: String, + libc_suffix: Option, server_path: PathBuf, symbols_path: Option, artifact_name: String, @@ -177,6 +180,10 @@ impl Target { } } }; + let (name, libc_suffix) = match name.split_once('.') { + Some((l, r)) => (l.to_owned(), Some(r.to_owned())), + None => (name, None), + }; let out_path = project_root.join("target").join(&name).join("release"); let (exe_suffix, symbols_path) = if name.contains("-windows-") { (".exe".into(), Some(out_path.join("rust_analyzer.pdb"))) @@ -185,7 +192,11 @@ impl Target { }; let server_path = out_path.join(format!("rust-analyzer{exe_suffix}")); let artifact_name = format!("rust-analyzer-{name}{exe_suffix}"); - Self { name, server_path, symbols_path, artifact_name } + Self { name, libc_suffix, server_path, symbols_path, artifact_name } + } + + fn is_linux(&self) -> bool { + self.name.contains("-linux-") } } diff --git a/src/tools/rust-analyzer/xtask/src/flags.rs b/src/tools/rust-analyzer/xtask/src/flags.rs index ebb9e71a4f46..d03e2f8437ec 100644 --- a/src/tools/rust-analyzer/xtask/src/flags.rs +++ b/src/tools/rust-analyzer/xtask/src/flags.rs @@ -57,6 +57,8 @@ xflags::xflags! { /// Use jemalloc allocator for server optional --jemalloc optional --client-patch-version version: String + /// Use cargo-zigbuild + optional --zig } /// Read a changelog AsciiDoc file and update the GitHub Releases entry in Markdown. cmd publish-release-notes { @@ -144,6 +146,7 @@ pub struct Dist { pub mimalloc: bool, pub jemalloc: bool, pub client_patch_version: Option, + pub zig: bool, } #[derive(Debug)] diff --git a/src/tools/rust-analyzer/xtask/src/release.rs b/src/tools/rust-analyzer/xtask/src/release.rs index 8e56ce439c55..9f65c4029536 100644 --- a/src/tools/rust-analyzer/xtask/src/release.rs +++ b/src/tools/rust-analyzer/xtask/src/release.rs @@ -50,7 +50,7 @@ impl flags::Release { .unwrap_or_default(); let tags = cmd!(sh, "git tag --list").read()?; - let prev_tag = tags.lines().filter(|line| is_release_tag(line)).last().unwrap(); + let prev_tag = tags.lines().filter(|line| is_release_tag(line)).next_back().unwrap(); let contents = changelog::get_changelog(sh, changelog_n, &commit, prev_tag, &today)?; let path = changelog_dir.join(format!("{today}-changelog-{changelog_n}.adoc")); From bab71fc8d6a10937ba6ee70d3a9b9bb36cc54e53 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 26 Feb 2025 13:35:51 +0100 Subject: [PATCH 336/991] revert accidental change in get_closest_merge_commit --- src/build_helper/src/git.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 8f0b67ddbd36..3ef9c7ac35e9 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -154,6 +154,7 @@ pub fn get_closest_merge_commit( "rev-list", &format!("--author={}", config.git_merge_commit_email), "-n1", + "--first-parent", &merge_base, ]); From 30703af6f34e96d3e51b665aeb56f44749d11265 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Wed, 26 Feb 2025 21:40:14 +0800 Subject: [PATCH 337/991] Enable `f16` for LoongArch --- library/std/build.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/std/build.rs b/library/std/build.rs index 723d1eb02e07..5e2ac839e1e3 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -106,7 +106,6 @@ fn main() { // Infinite recursion ("csky", _) => false, ("hexagon", _) => false, - ("loongarch64", _) => false, ("powerpc" | "powerpc64", _) => false, ("sparc" | "sparc64", _) => false, ("wasm32" | "wasm64", _) => false, From 9f190d764f3a81fc372c76d2615fd441a129d133 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 26 Feb 2025 13:45:35 +0000 Subject: [PATCH 338/991] Restore usage of io::Error --- compiler/rustc_codegen_llvm/src/back/archive.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 91dce57ed1ef..0a161442933a 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -132,7 +132,7 @@ fn get_llvm_object_symbols( if err.is_null() { return Ok(true); } else { - let error = unsafe { *Box::from_raw(err as *mut String) }; + let error = unsafe { *Box::from_raw(err as *mut io::Error) }; // These are the magic constants for LLVM bitcode files: // https://github.com/llvm/llvm-project/blob/7eadc1960d199676f04add402bb0aa6f65b7b234/llvm/lib/BinaryFormat/Magic.cpp#L90-L97 if buf.starts_with(&[0xDE, 0xCE, 0x17, 0x0B]) || buf.starts_with(&[b'B', b'C', 0xC0, 0xDE]) @@ -150,7 +150,7 @@ fn get_llvm_object_symbols( eprintln!("warning: Failed to read symbol table from LLVM bitcode: {}", error); return Ok(true); } else { - return Err(io::Error::new(io::ErrorKind::Other, format!("LLVM error: {}", error))); + return Err(error); } } @@ -158,13 +158,16 @@ fn get_llvm_object_symbols( let f = unsafe { &mut *(state as *mut &mut dyn FnMut(&[u8]) -> io::Result<()>) }; match f(unsafe { CStr::from_ptr(symbol_name) }.to_bytes()) { Ok(()) => std::ptr::null_mut(), - Err(err) => Box::into_raw(Box::new(err.to_string()) as Box) as *mut c_void, + Err(err) => Box::into_raw(Box::new(err) as Box) as *mut c_void, } } unsafe extern "C" fn error_callback(error: *const c_char) -> *mut c_void { let error = unsafe { CStr::from_ptr(error) }; - Box::into_raw(Box::new(error.to_string_lossy().into_owned()) as Box) as *mut c_void + Box::into_raw(Box::new(io::Error::new( + io::ErrorKind::Other, + format!("LLVM error: {}", error.to_string_lossy()), + )) as Box) as *mut c_void } } From 4fcebee60a1f8fc069dd546aa8d7c93983c57ada Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 26 Feb 2025 13:18:44 +0000 Subject: [PATCH 339/991] Fix Windows `Command` search path bug --- library/std/src/sys/pal/windows/process.rs | 3 +- tests/ui/process/win-command-child-path.rs | 72 ++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 tests/ui/process/win-command-child-path.rs diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs index a41dfbfe6014..6eff471f3867 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/pal/windows/process.rs @@ -260,9 +260,10 @@ impl Command { needs_stdin: bool, proc_thread_attribute_list: Option<&ProcThreadAttributeList<'_>>, ) -> io::Result<(Process, StdioPipes)> { + let env_saw_path = self.env.have_changed_path(); let maybe_env = self.env.capture_if_changed(); - let child_paths = if let Some(env) = maybe_env.as_ref() { + let child_paths = if env_saw_path && let Some(env) = maybe_env.as_ref() { env.get(&EnvKey::new("PATH")).map(|s| s.as_os_str()) } else { None diff --git a/tests/ui/process/win-command-child-path.rs b/tests/ui/process/win-command-child-path.rs new file mode 100644 index 000000000000..7ec2679749fb --- /dev/null +++ b/tests/ui/process/win-command-child-path.rs @@ -0,0 +1,72 @@ +//@ run-pass +//@ only-windows +//@ needs-subprocess +//@ no-prefer-dynamic + +// Test Windows std::process::Command search path semantics when setting PATH on the child process. +// NOTE: The exact semantics here are (possibly) subject to change. + +use std::process::Command; +use std::{env, fs, path}; + +fn main() { + if env::args().skip(1).any(|s| s == "--child") { + child(); + } else if env::args().skip(1).any(|s| s == "--parent") { + parent(); + } else { + setup(); + } +} + +// Set up the directories so that there are three app dirs: +// app: Where the parent app is run from +// parent: In the parent's PATH env var +// child: In the child's PATH env var +fn setup() { + let exe = env::current_exe().unwrap(); + + fs::create_dir_all("app").unwrap(); + fs::copy(&exe, "app/myapp.exe").unwrap(); + fs::create_dir_all("parent").unwrap(); + fs::copy(&exe, "parent/myapp.exe").unwrap(); + fs::create_dir_all("child").unwrap(); + fs::copy(&exe, "child/myapp.exe").unwrap(); + + let parent_path = path::absolute("parent").unwrap(); + let status = + Command::new("./app/myapp.exe").env("PATH", parent_path).arg("--parent").status().unwrap(); + // print the status in case of abnormal exit + dbg!(status); + assert!(status.success()); +} + +// The child simply prints the name of its parent directory. +fn child() { + let exe = env::current_exe().unwrap(); + let parent = exe.parent().unwrap().file_name().unwrap(); + println!("{}", parent.display()); +} + +fn parent() { + let exe = env::current_exe().unwrap(); + let name = exe.file_name().unwrap(); + + // By default, the application dir will be search first for the exe + let output = Command::new(&name).arg("--child").output().unwrap(); + assert_eq!(output.stdout, b"app\n"); + + // Setting an environment variable should not change the above. + let output = Command::new(&name).arg("--child").env("a", "b").output().unwrap(); + assert_eq!(output.stdout, b"app\n"); + + // Setting a child path means that path will be searched first. + let child_path = path::absolute("child").unwrap(); + let output = Command::new(&name).arg("--child").env("PATH", child_path).output().unwrap(); + assert_eq!(output.stdout, b"child\n"); + + // Setting a child path that does not contain the exe (currently) means + // we fallback to searching the app dir. + let output = Command::new(&name).arg("--child").env("PATH", "").output().unwrap(); + assert_eq!(output.stdout, b"app\n"); +} From 6af901c51edbe2019e6aa18f7b33eb8581dc49af Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Sat, 28 Dec 2024 20:23:14 -0500 Subject: [PATCH 340/991] Add `unnecessary_debug_formatting` lint Address review comments Fix adjacent code Required now that the lint is pedantic Add inline formatting tests Add note re formatting changes Address `unnecessary_map_or` warnings Address additional review comments Typo Update Clippy version --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/format_args.rs | 122 ++++++++++++++++-- clippy_lints/src/lib.rs | 2 +- lintcheck/src/input.rs | 4 +- tests/compile-test.rs | 6 +- .../ui/unnecessary_os_str_debug_formatting.rs | 23 ++++ ...unnecessary_os_str_debug_formatting.stderr | 58 +++++++++ tests/ui/unnecessary_path_debug_formatting.rs | 44 +++++++ .../unnecessary_path_debug_formatting.stderr | 67 ++++++++++ 10 files changed, 314 insertions(+), 14 deletions(-) create mode 100644 tests/ui/unnecessary_os_str_debug_formatting.rs create mode 100644 tests/ui/unnecessary_os_str_debug_formatting.stderr create mode 100644 tests/ui/unnecessary_path_debug_formatting.rs create mode 100644 tests/ui/unnecessary_path_debug_formatting.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 664a7e766304..f72632371291 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6110,6 +6110,7 @@ Released 2018-09-13 [`unnecessary_box_returns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns [`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast [`unnecessary_clippy_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_clippy_cfg +[`unnecessary_debug_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_debug_formatting [`unnecessary_fallible_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fallible_conversions [`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map [`unnecessary_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_find_map diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 7451fb909ef8..985278e47802 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -191,6 +191,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::format_args::FORMAT_IN_FORMAT_ARGS_INFO, crate::format_args::TO_STRING_IN_FORMAT_ARGS_INFO, crate::format_args::UNINLINED_FORMAT_ARGS_INFO, + crate::format_args::UNNECESSARY_DEBUG_FORMATTING_INFO, crate::format_args::UNUSED_FORMAT_SPECS_INFO, crate::format_impl::PRINT_IN_FORMAT_IMPL_INFO, crate::format_impl::RECURSIVE_FORMAT_IMPL_INFO, diff --git a/clippy_lints/src/format_args.rs b/clippy_lints/src/format_args.rs index da5825b7ab21..ea617dd1bab8 100644 --- a/clippy_lints/src/format_args.rs +++ b/clippy_lints/src/format_args.rs @@ -1,26 +1,27 @@ use arrayvec::ArrayVec; use clippy_config::Conf; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::is_diag_trait_item; use clippy_utils::macros::{ FormatArgsStorage, FormatParamUsage, MacroCall, find_format_arg_expr, format_arg_removal_span, format_placeholder_format_span, is_assert_macro, is_format_macro, is_panic, matching_root_macro_call, root_macro_call_first_node, }; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::SpanRangeExt; +use clippy_utils::source::{SpanRangeExt, snippet}; use clippy_utils::ty::{implements_trait, is_type_lang_item}; +use clippy_utils::{is_diag_trait_item, is_from_proc_macro}; use itertools::Itertools; use rustc_ast::{ FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions, FormatPlaceholder, FormatTrait, }; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode}; use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty::Ty; use rustc_middle::ty::adjustment::{Adjust, Adjustment}; +use rustc_middle::ty::{List, Ty, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::edition::Edition::Edition2021; use rustc_span::{Span, Symbol, sym}; @@ -50,6 +51,36 @@ declare_clippy_lint! { "`format!` used in a macro that does formatting" } +declare_clippy_lint! { + /// ### What it does + /// Checks for `Debug` formatting (`{:?}`) applied to an `OsStr` or `Path`. + /// + /// ### Why is this bad? + /// Rust doesn't guarantee what `Debug` formatting looks like, and it could + /// change in the future. `OsStr`s and `Path`s can be `Display` formatted + /// using their `display` methods. + /// + /// Furthermore, with `Debug` formatting, certain characters are escaped. + /// Thus, a `Debug` formatted `Path` is less likely to be clickable. + /// + /// ### Example + /// ```no_run + /// # use std::path::Path; + /// let path = Path::new("..."); + /// println!("The path is {:?}", path); + /// ``` + /// Use instead: + /// ```no_run + /// # use std::path::Path; + /// let path = Path::new("…"); + /// println!("The path is {}", path.display()); + /// ``` + #[clippy::version = "1.87.0"] + pub UNNECESSARY_DEBUG_FORMATTING, + pedantic, + "`Debug` formatting applied to an `OsStr` or `Path` when `.display()` is available" +} + declare_clippy_lint! { /// ### What it does /// Checks for [`ToString::to_string`](https://doc.rust-lang.org/std/string/trait.ToString.html#tymethod.to_string) @@ -162,31 +193,35 @@ declare_clippy_lint! { "use of a format specifier that has no effect" } -impl_lint_pass!(FormatArgs => [ +impl_lint_pass!(FormatArgs<'_> => [ FORMAT_IN_FORMAT_ARGS, TO_STRING_IN_FORMAT_ARGS, UNINLINED_FORMAT_ARGS, + UNNECESSARY_DEBUG_FORMATTING, UNUSED_FORMAT_SPECS, ]); #[allow(clippy::struct_field_names)] -pub struct FormatArgs { +pub struct FormatArgs<'tcx> { format_args: FormatArgsStorage, msrv: Msrv, ignore_mixed: bool, + ty_feature_map: FxHashMap, Option>, } -impl FormatArgs { - pub fn new(conf: &'static Conf, format_args: FormatArgsStorage) -> Self { +impl<'tcx> FormatArgs<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>, conf: &'static Conf, format_args: FormatArgsStorage) -> Self { + let ty_feature_map = make_ty_feature_map(tcx); Self { format_args, msrv: conf.msrv.clone(), ignore_mixed: conf.allow_mixed_uninlined_format_args, + ty_feature_map, } } } -impl<'tcx> LateLintPass<'tcx> for FormatArgs { +impl<'tcx> LateLintPass<'tcx> for FormatArgs<'tcx> { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if let Some(macro_call) = root_macro_call_first_node(cx, expr) && is_format_macro(cx, macro_call.def_id) @@ -198,6 +233,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs { macro_call: ¯o_call, format_args, ignore_mixed: self.ignore_mixed, + ty_feature_map: &self.ty_feature_map, }; linter.check_templates(); @@ -217,9 +253,10 @@ struct FormatArgsExpr<'a, 'tcx> { macro_call: &'a MacroCall, format_args: &'a rustc_ast::FormatArgs, ignore_mixed: bool, + ty_feature_map: &'a FxHashMap, Option>, } -impl FormatArgsExpr<'_, '_> { +impl<'tcx> FormatArgsExpr<'_, 'tcx> { fn check_templates(&self) { for piece in &self.format_args.template { if let FormatArgsPiece::Placeholder(placeholder) = piece @@ -237,6 +274,11 @@ impl FormatArgsExpr<'_, '_> { self.check_format_in_format_args(name, arg_expr); self.check_to_string_in_format_args(name, arg_expr); } + + if placeholder.format_trait == FormatTrait::Debug { + let name = self.cx.tcx.item_name(self.macro_call.def_id); + self.check_unnecessary_debug_formatting(name, arg_expr); + } } } } @@ -439,6 +481,33 @@ impl FormatArgsExpr<'_, '_> { } } + fn check_unnecessary_debug_formatting(&self, name: Symbol, value: &Expr<'tcx>) { + let cx = self.cx; + if !value.span.from_expansion() + && !is_from_proc_macro(cx, value) + && let ty = cx.typeck_results().expr_ty(value) + && self.can_display_format(ty) + { + let snippet = snippet(cx.sess(), value.span, ".."); + span_lint_and_then( + cx, + UNNECESSARY_DEBUG_FORMATTING, + value.span, + format!("unnecessary `Debug` formatting in `{name}!` args"), + |diag| { + diag.help(format!( + "use `Display` formatting and change this to `{snippet}.display()`" + )); + diag.note( + "switching to `Display` formatting will change how the value is shown; \ + escaped characters will no longer be escaped and surrounding quotes will \ + be removed", + ); + }, + ); + } + } + fn format_arg_positions(&self) -> impl Iterator { self.format_args.template.iter().flat_map(|piece| match piece { FormatArgsPiece::Placeholder(placeholder) => { @@ -465,6 +534,41 @@ impl FormatArgsExpr<'_, '_> { .at_most_one() .is_err() } + + fn can_display_format(&self, ty: Ty<'tcx>) -> bool { + let ty = ty.peel_refs(); + + if let Some(feature) = self.ty_feature_map.get(&ty) + && feature.is_none_or(|feature| self.cx.tcx.features().enabled(feature)) + { + return true; + } + + // Even if `ty` is not in `self.ty_feature_map`, check whether `ty` implements `Deref` with + // a `Target` that is in `self.ty_feature_map`. + if let Some(deref_trait_id) = self.cx.tcx.lang_items().deref_trait() + && implements_trait(self.cx, ty, deref_trait_id, &[]) + && let Some(target_ty) = self.cx.get_associated_type(ty, deref_trait_id, "Target") + && let Some(feature) = self.ty_feature_map.get(&target_ty) + && feature.is_none_or(|feature| self.cx.tcx.features().enabled(feature)) + { + return true; + } + + false + } +} + +fn make_ty_feature_map(tcx: TyCtxt<'_>) -> FxHashMap, Option> { + [(sym::OsStr, Some(Symbol::intern("os_str_display"))), (sym::Path, None)] + .into_iter() + .filter_map(|(name, feature)| { + tcx.get_diagnostic_item(name).map(|def_id| { + let ty = Ty::new_adt(tcx, tcx.adt_def(def_id), List::empty()); + (ty, feature) + }) + }) + .collect() } fn count_needed_derefs<'tcx, I>(mut ty: Ty<'tcx>, mut iter: I) -> (usize, Ty<'tcx>) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index fad6f9d08803..ea7566a8e858 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -835,7 +835,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(move |_| Box::new(non_send_fields_in_send_ty::NonSendFieldInSendTy::new(conf))); store.register_late_pass(move |_| Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks::new(conf))); let format_args = format_args_storage.clone(); - store.register_late_pass(move |_| Box::new(format_args::FormatArgs::new(conf, format_args.clone()))); + store.register_late_pass(move |tcx| Box::new(format_args::FormatArgs::new(tcx, conf, format_args.clone()))); store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray)); store.register_early_pass(|| Box::new(octal_escapes::OctalEscapes)); store.register_late_pass(|_| Box::new(needless_late_init::NeedlessLateInit)); diff --git a/lintcheck/src/input.rs b/lintcheck/src/input.rs index 3383d50fa02c..83eb0a577d6b 100644 --- a/lintcheck/src/input.rs +++ b/lintcheck/src/input.rs @@ -288,11 +288,11 @@ impl CrateWithSource { // as a result of this filter. let dest_crate_root = PathBuf::from(LINTCHECK_SOURCES).join(name); if dest_crate_root.exists() { - println!("Deleting existing directory at {dest_crate_root:?}"); + println!("Deleting existing directory at `{}`", dest_crate_root.display()); fs::remove_dir_all(&dest_crate_root).unwrap(); } - println!("Copying {path:?} to {dest_crate_root:?}"); + println!("Copying `{}` to `{}`", path.display(), dest_crate_root.display()); for entry in WalkDir::new(path).into_iter().filter_entry(|e| !is_cache_dir(e)) { let entry = entry.unwrap(); diff --git a/tests/compile-test.rs b/tests/compile-test.rs index e2e4d92df79f..10a3e85ed1df 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -377,13 +377,15 @@ fn ui_cargo_toml_metadata() { .map(|component| component.as_os_str().to_string_lossy().replace('-', "_")) .any(|s| *s == name) || path.starts_with(&cargo_common_metadata_path), - "{path:?} has incorrect package name" + "`{}` has incorrect package name", + path.display(), ); let publish = package.get("publish").and_then(toml::Value::as_bool).unwrap_or(true); assert!( !publish || publish_exceptions.contains(&path.parent().unwrap().to_path_buf()), - "{path:?} lacks `publish = false`" + "`{}` lacks `publish = false`", + path.display(), ); } } diff --git a/tests/ui/unnecessary_os_str_debug_formatting.rs b/tests/ui/unnecessary_os_str_debug_formatting.rs new file mode 100644 index 000000000000..3c264e5fc598 --- /dev/null +++ b/tests/ui/unnecessary_os_str_debug_formatting.rs @@ -0,0 +1,23 @@ +#![feature(os_str_display)] +#![warn(clippy::unnecessary_debug_formatting)] + +use std::ffi::{OsStr, OsString}; + +fn main() { + let os_str = OsStr::new("abc"); + let os_string = os_str.to_os_string(); + + // negative tests + println!("{}", os_str.display()); + println!("{}", os_string.display()); + + // positive tests + println!("{:?}", os_str); //~ unnecessary_debug_formatting + println!("{:?}", os_string); //~ unnecessary_debug_formatting + + println!("{os_str:?}"); //~ unnecessary_debug_formatting + println!("{os_string:?}"); //~ unnecessary_debug_formatting + + let _: String = format!("{:?}", os_str); //~ unnecessary_debug_formatting + let _: String = format!("{:?}", os_string); //~ unnecessary_debug_formatting +} diff --git a/tests/ui/unnecessary_os_str_debug_formatting.stderr b/tests/ui/unnecessary_os_str_debug_formatting.stderr new file mode 100644 index 000000000000..382e59b04619 --- /dev/null +++ b/tests/ui/unnecessary_os_str_debug_formatting.stderr @@ -0,0 +1,58 @@ +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_os_str_debug_formatting.rs:15:22 + | +LL | println!("{:?}", os_str); + | ^^^^^^ + | + = help: use `Display` formatting and change this to `os_str.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + = note: `-D clippy::unnecessary-debug-formatting` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_debug_formatting)]` + +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_os_str_debug_formatting.rs:16:22 + | +LL | println!("{:?}", os_string); + | ^^^^^^^^^ + | + = help: use `Display` formatting and change this to `os_string.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_os_str_debug_formatting.rs:18:16 + | +LL | println!("{os_str:?}"); + | ^^^^^^ + | + = help: use `Display` formatting and change this to `os_str.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_os_str_debug_formatting.rs:19:16 + | +LL | println!("{os_string:?}"); + | ^^^^^^^^^ + | + = help: use `Display` formatting and change this to `os_string.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `format!` args + --> tests/ui/unnecessary_os_str_debug_formatting.rs:21:37 + | +LL | let _: String = format!("{:?}", os_str); + | ^^^^^^ + | + = help: use `Display` formatting and change this to `os_str.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `format!` args + --> tests/ui/unnecessary_os_str_debug_formatting.rs:22:37 + | +LL | let _: String = format!("{:?}", os_string); + | ^^^^^^^^^ + | + = help: use `Display` formatting and change this to `os_string.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: aborting due to 6 previous errors + diff --git a/tests/ui/unnecessary_path_debug_formatting.rs b/tests/ui/unnecessary_path_debug_formatting.rs new file mode 100644 index 000000000000..96ad2ee2bf23 --- /dev/null +++ b/tests/ui/unnecessary_path_debug_formatting.rs @@ -0,0 +1,44 @@ +#![warn(clippy::unnecessary_debug_formatting)] + +use std::ffi::{OsStr, OsString}; +use std::ops::Deref; +use std::path::{Path, PathBuf}; + +struct DerefPath<'a> { + path: &'a Path, +} + +impl Deref for DerefPath<'_> { + type Target = Path; + fn deref(&self) -> &Self::Target { + self.path + } +} + +fn main() { + let path = Path::new("/a/b/c"); + let path_buf = path.to_path_buf(); + let os_str = OsStr::new("abc"); + let os_string = os_str.to_os_string(); + + // negative tests + println!("{}", path.display()); + println!("{}", path_buf.display()); + + // should not fire because feature `os_str_display` is not enabled + println!("{:?}", os_str); + println!("{:?}", os_string); + + // positive tests + println!("{:?}", path); //~ unnecessary_debug_formatting + println!("{:?}", path_buf); //~ unnecessary_debug_formatting + + println!("{path:?}"); //~ unnecessary_debug_formatting + println!("{path_buf:?}"); //~ unnecessary_debug_formatting + + let _: String = format!("{:?}", path); //~ unnecessary_debug_formatting + let _: String = format!("{:?}", path_buf); //~ unnecessary_debug_formatting + + let deref_path = DerefPath { path }; + println!("{:?}", &*deref_path); //~ unnecessary_debug_formatting +} diff --git a/tests/ui/unnecessary_path_debug_formatting.stderr b/tests/ui/unnecessary_path_debug_formatting.stderr new file mode 100644 index 000000000000..c9f649dbc0a1 --- /dev/null +++ b/tests/ui/unnecessary_path_debug_formatting.stderr @@ -0,0 +1,67 @@ +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_path_debug_formatting.rs:33:22 + | +LL | println!("{:?}", path); + | ^^^^ + | + = help: use `Display` formatting and change this to `path.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + = note: `-D clippy::unnecessary-debug-formatting` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_debug_formatting)]` + +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_path_debug_formatting.rs:34:22 + | +LL | println!("{:?}", path_buf); + | ^^^^^^^^ + | + = help: use `Display` formatting and change this to `path_buf.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_path_debug_formatting.rs:36:16 + | +LL | println!("{path:?}"); + | ^^^^ + | + = help: use `Display` formatting and change this to `path.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_path_debug_formatting.rs:37:16 + | +LL | println!("{path_buf:?}"); + | ^^^^^^^^ + | + = help: use `Display` formatting and change this to `path_buf.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `format!` args + --> tests/ui/unnecessary_path_debug_formatting.rs:39:37 + | +LL | let _: String = format!("{:?}", path); + | ^^^^ + | + = help: use `Display` formatting and change this to `path.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `format!` args + --> tests/ui/unnecessary_path_debug_formatting.rs:40:37 + | +LL | let _: String = format!("{:?}", path_buf); + | ^^^^^^^^ + | + = help: use `Display` formatting and change this to `path_buf.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_path_debug_formatting.rs:43:22 + | +LL | println!("{:?}", &*deref_path); + | ^^^^^^^^^^^^ + | + = help: use `Display` formatting and change this to `&*deref_path.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: aborting due to 7 previous errors + From 9a2362a76eac403552fd93a0977e10731f3d9de3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 26 Feb 2025 16:24:39 +0300 Subject: [PATCH 341/991] linker: Fix escaping style for response files on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we use a С/С++ compiler as linker, then Posix-style escaping should be used. --- compiler/rustc_codegen_ssa/src/back/link.rs | 8 ++++++-- src/bootstrap/src/core/build_steps/test.rs | 20 ++++++++++++++++---- src/bootstrap/src/core/builder/cargo.rs | 6 +++--- src/bootstrap/src/core/builder/mod.rs | 2 +- src/bootstrap/src/utils/helpers.rs | 14 +++++++++++--- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b090730ac6b5..5054ae561c04 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1726,8 +1726,12 @@ fn exec_linker( args.push_str( &Escape { arg: arg.to_str().unwrap(), - // LLD also uses MSVC-like parsing for @-files by default when running on windows hosts - is_like_msvc: sess.target.is_like_msvc || (cfg!(windows) && flavor.uses_lld()), + // Windows-style escaping for @-files is used by + // - all linkers targeting MSVC-like targets, including LLD + // - all LLD flavors running on Windows hosts + // С/С++ compilers use Posix-style escaping (except clang-cl, which we do not use). + is_like_msvc: sess.target.is_like_msvc + || (cfg!(windows) && flavor.uses_lld() && !flavor.uses_cc()), } .to_string(), ); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index dfcf26cedd65..e4f888ac793c 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -269,7 +269,13 @@ impl Step for Cargotest { .args(builder.config.test_args()) .env("RUSTC", builder.rustc(compiler)) .env("RUSTDOC", builder.rustdoc(compiler)); - add_rustdoc_cargo_linker_args(&mut cmd, builder, compiler.host, LldThreads::No); + add_rustdoc_cargo_linker_args( + &mut cmd, + builder, + compiler.host, + LldThreads::No, + compiler.stage, + ); cmd.delay_failure().run(builder); } } @@ -847,7 +853,7 @@ impl Step for RustdocTheme { .env("CFG_RELEASE_CHANNEL", &builder.config.channel) .env("RUSTDOC_REAL", builder.rustdoc(self.compiler)) .env("RUSTC_BOOTSTRAP", "1"); - cmd.args(linker_args(builder, self.compiler.host, LldThreads::No)); + cmd.args(linker_args(builder, self.compiler.host, LldThreads::No, self.compiler.stage)); cmd.delay_failure().run(builder); } @@ -1023,7 +1029,13 @@ impl Step for RustdocGUI { cmd.env("RUSTDOC", builder.rustdoc(self.compiler)) .env("RUSTC", builder.rustc(self.compiler)); - add_rustdoc_cargo_linker_args(&mut cmd, builder, self.compiler.host, LldThreads::No); + add_rustdoc_cargo_linker_args( + &mut cmd, + builder, + self.compiler.host, + LldThreads::No, + self.compiler.stage, + ); for path in &builder.paths { if let Some(p) = helpers::is_valid_test_suite_arg(path, "tests/rustdoc-gui", builder) { @@ -1883,7 +1895,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let mut hostflags = flags.clone(); hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display())); - hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No)); + hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No, compiler.stage)); let mut targetflags = flags; targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display())); diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 4f6d53e9fc89..8ada7afed8e9 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -260,7 +260,7 @@ impl Cargo { } } - for arg in linker_args(builder, compiler.host, LldThreads::Yes) { + for arg in linker_args(builder, compiler.host, LldThreads::Yes, 0) { self.hostflags.arg(&arg); } @@ -270,10 +270,10 @@ impl Cargo { } // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not // `linker_args` here. - for flag in linker_flags(builder, target, LldThreads::Yes) { + for flag in linker_flags(builder, target, LldThreads::Yes, compiler.stage) { self.rustflags.arg(&flag); } - for arg in linker_args(builder, target, LldThreads::Yes) { + for arg in linker_args(builder, target, LldThreads::Yes, compiler.stage) { self.rustdocflags.arg(&arg); } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 9c04f097bee2..c8e2856bdc87 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1462,7 +1462,7 @@ impl<'a> Builder<'a> { cmd.arg("-Dwarnings"); } cmd.arg("-Znormalize-docs"); - cmd.args(linker_args(self, compiler.host, LldThreads::Yes)); + cmd.args(linker_args(self, compiler.host, LldThreads::Yes, compiler.stage)); cmd } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 3fee397da091..7ad308cd0672 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -430,8 +430,9 @@ pub fn linker_args( builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, + stage: u32, ) -> Vec { - let mut args = linker_flags(builder, target, lld_threads); + let mut args = linker_flags(builder, target, lld_threads, stage); if let Some(linker) = builder.linker(target) { args.push(format!("-Clinker={}", linker.display())); @@ -446,12 +447,18 @@ pub fn linker_flags( builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, + stage: u32, ) -> Vec { let mut args = vec![]; if !builder.is_lld_direct_linker(target) && builder.config.lld_mode.is_used() { match builder.config.lld_mode { LldMode::External => { - args.push("-Clinker-flavor=gnu-lld-cc".to_string()); + // cfg(bootstrap) - remove after updating bootstrap compiler (#137498) + if stage == 0 && target.is_windows() { + args.push("-Clink-arg=-fuse-ld=lld".to_string()); + } else { + args.push("-Clinker-flavor=gnu-lld-cc".to_string()); + } // FIXME(kobzol): remove this flag once MCP510 gets stabilized args.push("-Zunstable-options".to_string()); } @@ -479,8 +486,9 @@ pub fn add_rustdoc_cargo_linker_args( builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, + stage: u32, ) { - let args = linker_args(builder, target, lld_threads); + let args = linker_args(builder, target, lld_threads, stage); let mut flags = cmd .get_envs() .find_map(|(k, v)| if k == OsStr::new("RUSTDOCFLAGS") { v } else { None }) From b60aeb05ddd58e509fbedddfd2d1b8cfcb143e8f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 26 Feb 2025 14:52:13 +0000 Subject: [PATCH 342/991] Stop passing --lib to cargo test This overrides the test=false flag in Cargo.toml and it shouldn't be necessary as --tests is already passed. --- src/bootstrap/src/core/build_steps/test.rs | 65 +++++----------------- src/bootstrap/src/core/metadata.rs | 8 --- src/bootstrap/src/lib.rs | 1 - 3 files changed, 15 insertions(+), 59 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index dfcf26cedd65..03d89ec165ef 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -90,7 +90,7 @@ impl Step for CrateBootstrap { ); let crate_name = path.rsplit_once('/').unwrap().1; - run_cargo_test(cargo, &[], &[], crate_name, crate_name, bootstrap_host, builder); + run_cargo_test(cargo, &[], &[], crate_name, bootstrap_host, builder); } } @@ -140,15 +140,7 @@ You can skip linkcheck with --skip src/tools/linkchecker" SourceType::InTree, &[], ); - run_cargo_test( - cargo, - &[], - &[], - "linkchecker", - "linkchecker self tests", - bootstrap_host, - builder, - ); + run_cargo_test(cargo, &[], &[], "linkchecker self tests", bootstrap_host, builder); if builder.doc_tests == DocTests::No { return; @@ -331,7 +323,7 @@ impl Step for Cargo { ); // NOTE: can't use `run_cargo_test` because we need to overwrite `PATH` - let mut cargo = prepare_cargo_test(cargo, &[], &[], "cargo", self.host, builder); + let mut cargo = prepare_cargo_test(cargo, &[], &[], self.host, builder); // Don't run cross-compile tests, we may not have cross-compiled libstd libs // available. @@ -417,7 +409,7 @@ impl Step for RustAnalyzer { cargo.env("SKIP_SLOW_TESTS", "1"); cargo.add_rustc_lib_path(builder); - run_cargo_test(cargo, &[], &[], "rust-analyzer", "rust-analyzer", host, builder); + run_cargo_test(cargo, &[], &[], "rust-analyzer", host, builder); } } @@ -466,7 +458,7 @@ impl Step for Rustfmt { cargo.add_rustc_lib_path(builder); - run_cargo_test(cargo, &[], &[], "rustfmt", "rustfmt", host, builder); + run_cargo_test(cargo, &[], &[], "rustfmt", host, builder); } } @@ -582,7 +574,7 @@ impl Step for Miri { // We can NOT use `run_cargo_test` since Miri's integration tests do not use the usual test // harness and therefore do not understand the flags added by `add_flags_and_try_run_test`. - let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", host, builder); + let mut cargo = prepare_cargo_test(cargo, &[], &[], host, builder); // miri tests need to know about the stage sysroot cargo.env("MIRI_SYSROOT", &miri_sysroot); @@ -730,7 +722,7 @@ impl Step for CompiletestTest { &[], ); cargo.allow_features("test"); - run_cargo_test(cargo, &[], &[], "compiletest", "compiletest self test", host, builder); + run_cargo_test(cargo, &[], &[], "compiletest self test", host, builder); } } @@ -791,7 +783,7 @@ impl Step for Clippy { cargo.env("HOST_LIBS", host_libs); cargo.add_rustc_lib_path(builder); - let cargo = prepare_cargo_test(cargo, &[], &[], "clippy", host, builder); + let cargo = prepare_cargo_test(cargo, &[], &[], host, builder); let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host); @@ -1318,15 +1310,7 @@ impl Step for CrateRunMakeSupport { &[], ); cargo.allow_features("test"); - run_cargo_test( - cargo, - &[], - &[], - "run-make-support", - "run-make-support self test", - host, - builder, - ); + run_cargo_test(cargo, &[], &[], "run-make-support self test", host, builder); } } @@ -1363,7 +1347,7 @@ impl Step for CrateBuildHelper { &[], ); cargo.allow_features("test"); - run_cargo_test(cargo, &[], &[], "build_helper", "build_helper self test", host, builder); + run_cargo_test(cargo, &[], &[], "build_helper self test", host, builder); } } @@ -2569,13 +2553,12 @@ fn run_cargo_test<'a>( cargo: builder::Cargo, libtest_args: &[&str], crates: &[String], - primary_crate: &str, description: impl Into>, target: TargetSelection, builder: &Builder<'_>, ) -> bool { let compiler = cargo.compiler(); - let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, primary_crate, target, builder); + let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, target, builder); let _time = helpers::timeit(builder); let _group = description.into().and_then(|what| { builder.msg_sysroot_tool(Kind::Test, compiler.stage, what, compiler.host, target) @@ -2599,7 +2582,6 @@ fn prepare_cargo_test( cargo: builder::Cargo, libtest_args: &[&str], crates: &[String], - primary_crate: &str, target: TargetSelection, builder: &Builder<'_>, ) -> BootstrapCommand { @@ -2629,13 +2611,6 @@ fn prepare_cargo_test( cargo.arg("--doc"); } DocTests::No => { - let krate = &builder - .crates - .get(primary_crate) - .unwrap_or_else(|| panic!("missing crate {primary_crate}")); - if krate.has_lib { - cargo.arg("--lib"); - } cargo.args(["--bins", "--examples", "--tests", "--benches"]); } DocTests::Yes => {} @@ -2814,7 +2789,6 @@ impl Step for Crate { cargo, &[], &self.crates, - &self.crates[0], &*crate_description(&self.crates), target, builder, @@ -2911,15 +2885,7 @@ impl Step for CrateRustdoc { dylib_path.insert(0, PathBuf::from(&*libdir)); cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); - run_cargo_test( - cargo, - &[], - &["rustdoc:0.0.0".to_string()], - "rustdoc", - "rustdoc", - target, - builder, - ); + run_cargo_test(cargo, &[], &["rustdoc:0.0.0".to_string()], "rustdoc", target, builder); } } @@ -2976,7 +2942,6 @@ impl Step for CrateRustdocJsonTypes { libtest_args, &["rustdoc-json-types".to_string()], "rustdoc-json-types", - "rustdoc-json-types", target, builder, ); @@ -3156,7 +3121,7 @@ impl Step for Bootstrap { // bootstrap tests are racy on directory creation so just run them one at a time. // Since there's not many this shouldn't be a problem. - run_cargo_test(cargo, &["--test-threads=1"], &[], "bootstrap", None, host, builder); + run_cargo_test(cargo, &["--test-threads=1"], &[], None, host, builder); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -3281,7 +3246,7 @@ impl Step for RustInstaller { bootstrap_host, bootstrap_host, ); - run_cargo_test(cargo, &[], &[], "installer", None, bootstrap_host, builder); + run_cargo_test(cargo, &[], &[], None, bootstrap_host, builder); // We currently don't support running the test.sh script outside linux(?) environments. // Eventually this should likely migrate to #[test]s in rust-installer proper rather than a @@ -3672,7 +3637,7 @@ impl Step for TestFloatParse { &[], ); - run_cargo_test(cargo_test, &[], &[], crate_name, crate_name, bootstrap_host, builder); + run_cargo_test(cargo_test, &[], &[], crate_name, bootstrap_host, builder); // Run the actual parse tests. let mut cargo_run = tool::prepare_tool_cargo( diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 01cbf6629408..2706aba5ffc8 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -28,7 +28,6 @@ struct Package { source: Option, manifest_path: String, dependencies: Vec, - targets: Vec, features: BTreeMap>, } @@ -40,11 +39,6 @@ struct Dependency { source: Option, } -#[derive(Debug, Deserialize)] -struct Target { - kind: Vec, -} - /// Collects and stores package metadata of each workspace members into `build`, /// by executing `cargo metadata` commands. pub fn build(build: &mut Build) { @@ -59,12 +53,10 @@ pub fn build(build: &mut Build) { .filter(|dep| dep.source.is_none()) .map(|dep| dep.name) .collect(); - let has_lib = package.targets.iter().any(|t| t.kind.iter().any(|k| k == "lib")); let krate = Crate { name: name.clone(), deps, path, - has_lib, features: package.features.keys().cloned().collect(), }; let relative_path = krate.local_path(build); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 351e67f6702d..4ea711c1325e 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -185,7 +185,6 @@ struct Crate { name: String, deps: HashSet, path: PathBuf, - has_lib: bool, features: Vec, } From b491494a20bc1cde315c3d51055122e957188492 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 19 Feb 2025 15:58:08 +0000 Subject: [PATCH 343/991] Also test coretests when running ./x.py test core It is reasonable to expect that ./x.py test core is enough to run tests when you are working on core. In addition it seems like CI for wasm32 at least doesn't run coretests currently, which this commit fixes. --- src/bootstrap/src/core/build_steps/test.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 03d89ec165ef..3781d020604f 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2785,14 +2785,15 @@ impl Step for Crate { _ => panic!("can only test libraries"), }; - run_cargo_test( - cargo, - &[], - &self.crates, - &*crate_description(&self.crates), - target, - builder, - ); + let mut crates = self.crates.clone(); + // The core crate can't directly be tested. We could silently + // ignore it, but adding it's own test crate is less confusing + // for users. We still keep core itself for doctests. + if crates.iter().any(|crate_| crate_ == "core") { + crates.push("coretests".to_owned()); + } + + run_cargo_test(cargo, &[], &crates, &*crate_description(&self.crates), target, builder); } } From 169e731f53788c21b1c864fb67e4a574f95f0026 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 26 Feb 2025 14:51:37 +0000 Subject: [PATCH 344/991] Fix unused import in coretests on wasm32 --- library/coretests/tests/slice.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs index 1c5c8a9ebf25..fe356dcc43c7 100644 --- a/library/coretests/tests/slice.rs +++ b/library/coretests/tests/slice.rs @@ -5,8 +5,6 @@ use core::num::NonZero; use core::ops::{Range, RangeInclusive}; use core::slice; -use rand::seq::IndexedRandom; - #[test] fn test_position() { let b = [1, 2, 3, 5, 5]; @@ -1810,6 +1808,7 @@ fn select_nth_unstable() { use core::cmp::Ordering::{Equal, Greater, Less}; use rand::Rng; + use rand::seq::IndexedRandom; let mut rng = crate::test_rng(); From 3477297c374f2b12a5846b8b522b1e69ea08cc5e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:40:41 +0000 Subject: [PATCH 345/991] Fix UB in ThinVec::flat_map_in_place thin_vec.as_ptr() goes through the Deref impl of ThinVec, which will not allow access to any memory as we did call set_len(0) first. --- .../src/flat_map_in_place.rs | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_data_structures/src/flat_map_in_place.rs b/compiler/rustc_data_structures/src/flat_map_in_place.rs index e66b00b75576..6d718059f9c8 100644 --- a/compiler/rustc_data_structures/src/flat_map_in_place.rs +++ b/compiler/rustc_data_structures/src/flat_map_in_place.rs @@ -1,4 +1,4 @@ -use std::ptr; +use std::{mem, ptr}; use smallvec::{Array, SmallVec}; use thin_vec::ThinVec; @@ -13,39 +13,44 @@ pub trait FlatMapInPlace: Sized { // The implementation of this method is syntactically identical for all the // different vector types. macro_rules! flat_map_in_place { - () => { + ($vec:ident $( where T: $bound:path)?) => { fn flat_map_in_place(&mut self, mut f: F) where F: FnMut(T) -> I, I: IntoIterator, { + struct LeakGuard<'a, T $(: $bound)?>(&'a mut $vec); + + impl<'a, T $(: $bound)?> Drop for LeakGuard<'a, T> { + fn drop(&mut self) { + unsafe { + self.0.set_len(0); // make sure we just leak elements in case of panic + } + } + } + + let this = LeakGuard(self); + let mut read_i = 0; let mut write_i = 0; unsafe { - let mut old_len = self.len(); - self.set_len(0); // make sure we just leak elements in case of panic - - while read_i < old_len { + while read_i < this.0.len() { // move the read_i'th item out of the vector and map it // to an iterator - let e = ptr::read(self.as_ptr().add(read_i)); + let e = ptr::read(this.0.as_ptr().add(read_i)); let iter = f(e).into_iter(); read_i += 1; for e in iter { if write_i < read_i { - ptr::write(self.as_mut_ptr().add(write_i), e); + ptr::write(this.0.as_mut_ptr().add(write_i), e); write_i += 1; } else { // If this is reached we ran out of space // in the middle of the vector. // However, the vector is in a valid state here, // so we just do a somewhat inefficient insert. - self.set_len(old_len); - self.insert(write_i, e); - - old_len = self.len(); - self.set_len(0); + this.0.insert(write_i, e); read_i += 1; write_i += 1; @@ -54,20 +59,23 @@ macro_rules! flat_map_in_place { } // write_i tracks the number of actually written new items. - self.set_len(write_i); + this.0.set_len(write_i); + + // The ThinVec is in a sane state again. Prevent the LeakGuard from leaking the data. + mem::forget(this); } } }; } impl FlatMapInPlace for Vec { - flat_map_in_place!(); + flat_map_in_place!(Vec); } impl> FlatMapInPlace for SmallVec { - flat_map_in_place!(); + flat_map_in_place!(SmallVec where T: Array); } impl FlatMapInPlace for ThinVec { - flat_map_in_place!(); + flat_map_in_place!(ThinVec); } From 745297e7aa714ea4a657adb7403a18d9766ce2bd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Feb 2025 17:08:35 +0100 Subject: [PATCH 346/991] Use helper function instead of reimplementing the logic to check if rustdoc should emit crate --- src/librustdoc/html/render/write_shared.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index a4dec013fc04..adb77653efdc 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -153,7 +153,7 @@ fn write_rendered_cross_crate_info( include_sources: bool, ) -> Result<(), Error> { let m = &opt.should_merge; - if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) { + if opt.should_emit_crate() { if include_sources { write_rendered_cci::(SourcesPart::blank, dst, crates, m)?; } From 98eb2e3e5ac1c2de47c63d71cb8d4244f8174b16 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Feb 2025 17:13:30 +0100 Subject: [PATCH 347/991] Add rustdoc support for `--emit=dep-info[=path]` --- src/librustdoc/config.rs | 28 ++++++++++++++++++++++------ src/librustdoc/core.rs | 24 ++++++++++++++++++------ src/librustdoc/lib.rs | 10 ++++++++-- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index fd4d9845c892..e67fe6c88ea4 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -315,23 +315,30 @@ pub(crate) enum ModuleSorting { Alphabetical, } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum EmitType { Unversioned, Toolchain, InvocationSpecific, + DepInfo(Option), } impl FromStr for EmitType { type Err = (); fn from_str(s: &str) -> Result { - use EmitType::*; match s { - "unversioned-shared-resources" => Ok(Unversioned), - "toolchain-shared-resources" => Ok(Toolchain), - "invocation-specific" => Ok(InvocationSpecific), - _ => Err(()), + "unversioned-shared-resources" => Ok(Self::Unversioned), + "toolchain-shared-resources" => Ok(Self::Toolchain), + "invocation-specific" => Ok(Self::InvocationSpecific), + "dep-info" => Ok(Self::DepInfo(None)), + option => { + if let Some(file) = option.strip_prefix("dep-info=") { + Ok(Self::DepInfo(Some(Path::new(file).into()))) + } else { + Err(()) + } + } } } } @@ -340,6 +347,15 @@ impl RenderOptions { pub(crate) fn should_emit_crate(&self) -> bool { self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific) } + + pub(crate) fn dep_info(&self) -> Option> { + for emit in &self.emit { + if let EmitType::DepInfo(file) = emit { + return Some(file.as_deref()); + } + } + None + } } /// Create the input (string or file path) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 757a2a6e0dd0..679921c32693 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -15,11 +15,12 @@ use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{HirId, Path}; -use rustc_interface::interface; use rustc_lint::{MissingDoc, late_lint_mod}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; -use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks}; +use rustc_session::config::{ + self, CrateType, ErrorOutputType, Input, OutFileName, OutputType, OutputTypes, ResolveDocLinks, +}; pub(crate) use rustc_session::config::{Options, UnstableOptions}; use rustc_session::{Session, lint}; use rustc_span::source_map; @@ -219,7 +220,7 @@ pub(crate) fn create_config( remap_path_prefix, .. }: RustdocOptions, - RenderOptions { document_private, .. }: &RenderOptions, + render_options: &RenderOptions, ) -> rustc_interface::Config { // Add the doc cfg into the doc build. cfgs.push("doc".to_string()); @@ -245,8 +246,11 @@ pub(crate) fn create_config( let crate_types = if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] }; - let resolve_doc_links = - if *document_private { ResolveDocLinks::All } else { ResolveDocLinks::Exported }; + let resolve_doc_links = if render_options.document_private { + ResolveDocLinks::All + } else { + ResolveDocLinks::Exported + }; let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false); // plays with error output here! let sessopts = config::Options { @@ -269,10 +273,18 @@ pub(crate) fn create_config( crate_name, test, remap_path_prefix, + output_types: if let Some(file) = render_options.dep_info() { + OutputTypes::new(&[( + OutputType::DepInfo, + file.map(|f| OutFileName::Real(f.to_path_buf())), + )]) + } else { + OutputTypes::new(&[]) + }, ..Options::default() }; - interface::Config { + rustc_interface::Config { opts: sessopts, crate_cfg: cfgs, crate_check_cfg: check_cfgs, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 1f2f8f7d33a4..c1e6d324d5a1 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -561,7 +561,7 @@ fn opts() -> Vec { "", "emit", "Comma separated list of types of output for rustdoc to emit", - "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]", + "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]", ), opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""), opt( @@ -890,7 +890,13 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { // if we ran coverage, bail early, we don't need to also generate docs at this point // (also we didn't load in any of the useful passes) return; - } else if run_check { + } + + if render_opts.dep_info().is_some() { + rustc_interface::passes::write_dep_info(tcx); + } + + if run_check { // Since we're in "check" mode, no need to generate anything beyond this point. return; } From 46a39f0b27f20848757b60e6d8caf274de7aefaa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Feb 2025 17:13:48 +0100 Subject: [PATCH 348/991] Add new `Rustdoc::emit` method in `run-make-support` --- src/tools/run-make-support/src/external_deps/rustdoc.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/run-make-support/src/external_deps/rustdoc.rs b/src/tools/run-make-support/src/external_deps/rustdoc.rs index 3c0e9c82f0bb..8a659cd3d8ab 100644 --- a/src/tools/run-make-support/src/external_deps/rustdoc.rs +++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs @@ -132,4 +132,11 @@ impl Rustdoc { self.cmd.arg(format); self } + + /// Specify type(s) of output files to generate. + pub fn emit>(&mut self, kinds: S) -> &mut Self { + let kinds = kinds.as_ref(); + self.cmd.arg(format!("--emit={kinds}")); + self + } } From 6e4adbed76ff406994682ee526366f6f2ea11b9f Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Wed, 26 Feb 2025 15:59:38 +0000 Subject: [PATCH 349/991] Remove visit_const_block in typeck writeback There is a `visit_inline_const` visitor method and it is used instead. --- compiler/rustc_hir_typeck/src/writeback.rs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 3e9ce0e11e40..6c6538d09def 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -248,13 +248,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } } - - fn visit_const_block(&mut self, span: Span, anon_const: &hir::ConstBlock) { - self.visit_node_id(span, anon_const.hir_id); - - let body = self.tcx().hir_body(anon_const.body); - self.visit_body(body); - } } /////////////////////////////////////////////////////////////////////////// @@ -284,9 +277,6 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { hir::ExprKind::Field(..) | hir::ExprKind::OffsetOf(..) => { self.visit_field_id(e.hir_id); } - hir::ExprKind::ConstBlock(ref anon_const) => { - self.visit_const_block(e.span, anon_const); - } _ => {} } @@ -297,6 +287,14 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { self.fix_index_builtin_expr(e); } + fn visit_inline_const(&mut self, anon_const: &hir::ConstBlock) { + let span = self.tcx().def_span(anon_const.def_id); + self.visit_node_id(span, anon_const.hir_id); + + let body = self.tcx().hir_body(anon_const.body); + self.visit_body(body); + } + fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) { match &p.kind { hir::GenericParamKind::Lifetime { .. } => { @@ -343,9 +341,6 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { fn visit_pat_expr(&mut self, expr: &'tcx hir::PatExpr<'tcx>) { self.visit_node_id(expr.span, expr.hir_id); - if let hir::PatExprKind::ConstBlock(c) = &expr.kind { - self.visit_const_block(expr.span, c); - } intravisit::walk_pat_expr(self, expr); } From 8282181e425d1a34f0c27c150f7fc91b892f73b2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 26 Feb 2025 17:32:26 +0000 Subject: [PATCH 350/991] Use Binder> instead of Vec> in new solver --- .../src/infer/relate/higher_ranked.rs | 6 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 47 +++++++------ .../src/solve/assembly/structural_traits.rs | 68 ++++++++----------- .../src/solve/eval_ctxt/mod.rs | 2 +- .../src/solve/trait_goals.rs | 16 ++--- compiler/rustc_type_ir/src/infer_ctxt.rs | 2 +- compiler/rustc_type_ir/src/interner.rs | 2 +- 8 files changed, 70 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs index 0998f3c47902..a12d83db91f2 100644 --- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs +++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs @@ -2,6 +2,7 @@ //! the end of the file for details. use rustc_middle::ty::fold::FnMutDelegate; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use tracing::{debug, instrument}; @@ -26,8 +27,9 @@ impl<'tcx> InferCtxt<'tcx> { where T: TypeFoldable>, { - if let Some(inner) = binder.clone().no_bound_vars() { - return inner; + // Inlined `no_bound_vars`. + if !binder.as_ref().skip_binder().has_escaping_bound_vars() { + return binder.skip_binder(); } let next_universe = self.create_next_universe(); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 62a384af12f2..edecf49b9897 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -327,7 +327,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn bound_coroutine_hidden_types( self, def_id: DefId, - ) -> impl IntoIterator>>> { + ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List>>> { self.bound_coroutine_hidden_types(def_id) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c153f6bb7d77..3c3bc23826bd 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -748,29 +748,32 @@ impl<'tcx> TyCtxt<'tcx> { pub fn bound_coroutine_hidden_types( self, def_id: DefId, - ) -> impl Iterator>>> { + ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List>>> { let coroutine_layout = self.mir_coroutine_witnesses(def_id); - coroutine_layout - .as_ref() - .map_or_else(|| [].iter(), |l| l.field_tys.iter()) - .filter(|decl| !decl.ignore_for_traits) - .map(move |decl| { - let mut vars = vec![]; - let ty = fold_regions(self, decl.ty, |re, debruijn| { - assert_eq!(re, self.lifetimes.re_erased); - let var = ty::BoundVar::from_usize(vars.len()); - vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon)); - ty::Region::new_bound( - self, - debruijn, - ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon }, - ) - }); - ty::EarlyBinder::bind(ty::Binder::bind_with_vars( - ty, - self.mk_bound_variable_kinds(&vars), - )) - }) + let mut vars = vec![]; + let bound_tys = self.mk_type_list_from_iter( + coroutine_layout + .as_ref() + .map_or_else(|| [].iter(), |l| l.field_tys.iter()) + .filter(|decl| !decl.ignore_for_traits) + .map(|decl| { + let ty = fold_regions(self, decl.ty, |re, debruijn| { + assert_eq!(re, self.lifetimes.re_erased); + let var = ty::BoundVar::from_usize(vars.len()); + vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon)); + ty::Region::new_bound( + self, + debruijn, + ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon }, + ) + }); + ty + }), + ); + ty::EarlyBinder::bind(ty::Binder::bind_with_vars( + bound_tys, + self.mk_bound_variable_kinds(&vars), + )) } /// Expands the given impl trait type, stopping if the type is recursive. diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index dc0f4c4483e6..7b0996e02f04 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -18,7 +18,7 @@ use crate::solve::{AdtDestructorKind, EvalCtxt, Goal, NoSolution}; pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait( ecx: &EvalCtxt<'_, D>, ty: I::Ty, -) -> Result>, NoSolution> +) -> Result>, NoSolution> where D: SolverDelegate, I: Interner, @@ -33,10 +33,10 @@ where | ty::FnPtr(..) | ty::Error(_) | ty::Never - | ty::Char => Ok(vec![]), + | ty::Char => Ok(ty::Binder::dummy(vec![])), // Treat `str` like it's defined as `struct str([u8]);` - ty::Str => Ok(vec![ty::Binder::dummy(Ty::new_slice(cx, Ty::new_u8(cx)))]), + ty::Str => Ok(ty::Binder::dummy(vec![Ty::new_slice(cx, Ty::new_u8(cx))])), ty::Dynamic(..) | ty::Param(..) @@ -49,53 +49,49 @@ where } ty::RawPtr(element_ty, _) | ty::Ref(_, element_ty, _) => { - Ok(vec![ty::Binder::dummy(element_ty)]) + Ok(ty::Binder::dummy(vec![element_ty])) } ty::Pat(element_ty, _) | ty::Array(element_ty, _) | ty::Slice(element_ty) => { - Ok(vec![ty::Binder::dummy(element_ty)]) + Ok(ty::Binder::dummy(vec![element_ty])) } ty::Tuple(tys) => { // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet - Ok(tys.iter().map(ty::Binder::dummy).collect()) + Ok(ty::Binder::dummy(tys.to_vec())) } - ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]), + ty::Closure(_, args) => Ok(ty::Binder::dummy(vec![args.as_closure().tupled_upvars_ty()])), ty::CoroutineClosure(_, args) => { - Ok(vec![ty::Binder::dummy(args.as_coroutine_closure().tupled_upvars_ty())]) + Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()])) } ty::Coroutine(_, args) => { let coroutine_args = args.as_coroutine(); - Ok(vec![ - ty::Binder::dummy(coroutine_args.tupled_upvars_ty()), - ty::Binder::dummy(coroutine_args.witness()), - ]) + Ok(ty::Binder::dummy(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()])) } ty::CoroutineWitness(def_id, args) => Ok(ecx .cx() .bound_coroutine_hidden_types(def_id) - .into_iter() - .map(|bty| bty.instantiate(cx, args)) - .collect()), + .instantiate(cx, args) + .map_bound(|tys| tys.to_vec())), - ty::UnsafeBinder(bound_ty) => Ok(vec![bound_ty.into()]), + ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])), // For `PhantomData`, we pass `T`. - ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]), + ty::Adt(def, args) if def.is_phantom_data() => Ok(ty::Binder::dummy(vec![args.type_at(0)])), ty::Adt(def, args) => { - Ok(def.all_field_tys(cx).iter_instantiated(cx, args).map(ty::Binder::dummy).collect()) + Ok(ty::Binder::dummy(def.all_field_tys(cx).iter_instantiated(cx, args).collect())) } ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - Ok(vec![ty::Binder::dummy(cx.type_of(def_id).instantiate(cx, args))]) + Ok(ty::Binder::dummy(vec![cx.type_of(def_id).instantiate(cx, args)])) } } } @@ -104,7 +100,7 @@ where pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait( ecx: &EvalCtxt<'_, D>, ty: I::Ty, -) -> Result>, NoSolution> +) -> Result>, NoSolution> where D: SolverDelegate, I: Interner, @@ -130,7 +126,7 @@ where | ty::CoroutineClosure(..) | ty::Never | ty::Dynamic(_, _, ty::DynStar) - | ty::Error(_) => Ok(vec![]), + | ty::Error(_) => Ok(ty::Binder::dummy(vec![])), ty::Str | ty::Slice(_) @@ -145,11 +141,11 @@ where panic!("unexpected type `{ty:?}`") } - ty::UnsafeBinder(bound_ty) => Ok(vec![bound_ty.into()]), + ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])), // impl Sized for () // impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1 - ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |ty| vec![ty::Binder::dummy(ty)])), + ty::Tuple(tys) => Ok(ty::Binder::dummy(tys.last().map_or_else(Vec::new, |ty| vec![ty]))), // impl Sized for Adt where sized_constraint(Adt): Sized // `sized_constraint(Adt)` is the deepest struct trail that can be determined @@ -162,9 +158,9 @@ where // if the ADT is sized for all possible args. ty::Adt(def, args) => { if let Some(sized_crit) = def.sized_constraint(ecx.cx()) { - Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), args))]) + Ok(ty::Binder::dummy(vec![sized_crit.instantiate(ecx.cx(), args)])) } else { - Ok(vec![]) + Ok(ty::Binder::dummy(vec![])) } } } @@ -174,14 +170,14 @@ where pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait( ecx: &EvalCtxt<'_, D>, ty: I::Ty, -) -> Result>, NoSolution> +) -> Result>, NoSolution> where D: SolverDelegate, I: Interner, { match ty.kind() { // impl Copy/Clone for FnDef, FnPtr - ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) => Ok(vec![]), + ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) => Ok(ty::Binder::dummy(vec![])), // Implementations are provided in core ty::Uint(_) @@ -197,7 +193,7 @@ where // Cannot implement in core, as we can't be generic over patterns yet, // so we'd have to list all patterns and type combinations. - ty::Pat(ty, ..) => Ok(vec![ty::Binder::dummy(ty)]), + ty::Pat(ty, ..) => Ok(ty::Binder::dummy(vec![ty])), ty::Dynamic(..) | ty::Str @@ -215,14 +211,14 @@ where } // impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone - ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()), + ty::Tuple(tys) => Ok(ty::Binder::dummy(tys.to_vec())), // impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone - ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]), + ty::Closure(_, args) => Ok(ty::Binder::dummy(vec![args.as_closure().tupled_upvars_ty()])), // impl Copy/Clone for CoroutineClosure where Self::TupledUpvars: Copy/Clone ty::CoroutineClosure(_, args) => { - Ok(vec![ty::Binder::dummy(args.as_coroutine_closure().tupled_upvars_ty())]) + Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()])) } // only when `coroutine_clone` is enabled and the coroutine is movable @@ -232,10 +228,7 @@ where Movability::Movable => { if ecx.cx().features().coroutine_clone() { let coroutine = args.as_coroutine(); - Ok(vec![ - ty::Binder::dummy(coroutine.tupled_upvars_ty()), - ty::Binder::dummy(coroutine.witness()), - ]) + Ok(ty::Binder::dummy(vec![coroutine.tupled_upvars_ty(), coroutine.witness()])) } else { Err(NoSolution) } @@ -248,9 +241,8 @@ where ty::CoroutineWitness(def_id, args) => Ok(ecx .cx() .bound_coroutine_hidden_types(def_id) - .into_iter() - .map(|bty| bty.instantiate(ecx.cx(), args)) - .collect()), + .instantiate(ecx.cx(), args) + .map_bound(|tys| tys.to_vec())), } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index b0a34b9ce756..491250f4a691 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -913,7 +913,7 @@ where /// `enter_forall`, but takes `&mut self` and passes it back through the /// callback since it can't be aliased during the call. - pub(super) fn enter_forall + Copy, U>( + pub(super) fn enter_forall, U>( &mut self, value: ty::Binder, f: impl FnOnce(&mut Self, T) -> U, diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 1665dbb30189..a34a56ae8c8e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1239,17 +1239,15 @@ where constituent_tys: impl Fn( &EvalCtxt<'_, D>, I::Ty, - ) -> Result>, NoSolution>, + ) -> Result>, NoSolution>, ) -> Result, NoSolution> { self.probe_trait_candidate(source).enter(|ecx| { - let goals = constituent_tys(ecx, goal.predicate.self_ty())? - .into_iter() - .map(|ty| { - ecx.enter_forall(ty, |ecx, ty| { - goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty)) - }) - }) - .collect::>(); + let goals = + ecx.enter_forall(constituent_tys(ecx, goal.predicate.self_ty())?, |ecx, tys| { + tys.into_iter() + .map(|ty| goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty))) + .collect::>() + }); ecx.add_goals(GoalSource::ImplWhereBound, goals); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index c9b636132f80..d5edc9610a4a 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -151,7 +151,7 @@ pub trait InferCtxtLike: Sized { value: ty::Binder, ) -> T; - fn enter_forall + Copy, U>( + fn enter_forall, U>( &self, value: ty::Binder, f: impl FnOnce(T) -> U, diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index aae2d2e96b96..1cd0a8653fd9 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -192,7 +192,7 @@ pub trait Interner: fn bound_coroutine_hidden_types( self, def_id: Self::DefId, - ) -> impl IntoIterator>>; + ) -> ty::EarlyBinder>; fn fn_sig( self, From ad747886704b256fe72aa97a35d36fb91401b610 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 26 Feb 2025 17:31:41 +0000 Subject: [PATCH 351/991] Use bound_coroutine_witnesses in old solver --- compiler/rustc_middle/src/ty/context.rs | 4 +- compiler/rustc_middle/src/ty/util.rs | 19 +---- .../src/solve/assembly/structural_traits.rs | 4 +- .../src/traits/select/mod.rs | 79 +++++-------------- compiler/rustc_type_ir/src/interner.rs | 2 +- 5 files changed, 27 insertions(+), 81 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index edecf49b9897..dffa685955ca 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -324,11 +324,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.features() } - fn bound_coroutine_hidden_types( + fn coroutine_hidden_types( self, def_id: DefId, ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List>>> { - self.bound_coroutine_hidden_types(def_id) + self.coroutine_hidden_types(def_id) } fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 3c3bc23826bd..6c6dc30bbcc1 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -725,27 +725,10 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// Return the set of types that should be taken into account when checking - /// trait bounds on a coroutine's internal state. - // FIXME(compiler-errors): We should remove this when the old solver goes away; - // and all other usages of this function should go through `bound_coroutine_hidden_types` - // instead. - pub fn coroutine_hidden_types( - self, - def_id: DefId, - ) -> impl Iterator>> { - let coroutine_layout = self.mir_coroutine_witnesses(def_id); - coroutine_layout - .as_ref() - .map_or_else(|| [].iter(), |l| l.field_tys.iter()) - .filter(|decl| !decl.ignore_for_traits) - .map(|decl| ty::EarlyBinder::bind(decl.ty)) - } - /// Return the set of types that should be taken into account when checking /// trait bounds on a coroutine's internal state. This properly replaces /// `ReErased` with new existential bound lifetimes. - pub fn bound_coroutine_hidden_types( + pub fn coroutine_hidden_types( self, def_id: DefId, ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List>>> { diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 7b0996e02f04..93804b14125d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -74,7 +74,7 @@ where ty::CoroutineWitness(def_id, args) => Ok(ecx .cx() - .bound_coroutine_hidden_types(def_id) + .coroutine_hidden_types(def_id) .instantiate(cx, args) .map_bound(|tys| tys.to_vec())), @@ -240,7 +240,7 @@ where // impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types ty::CoroutineWitness(def_id, args) => Ok(ecx .cx() - .bound_coroutine_hidden_types(def_id) + .coroutine_hidden_types(def_id) .instantiate(ecx.cx(), args) .map_bound(|tys| tys.to_vec())), } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 436ce3dddd9f..dead95e8475b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -9,7 +9,7 @@ use std::ops::ControlFlow; use std::{cmp, iter}; use hir::def::DefKind; -use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir as hir; @@ -25,7 +25,6 @@ use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds}; pub use rustc_middle::traits::select::*; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::TypeErrorToStringExt; -use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, @@ -2199,8 +2198,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } ty::CoroutineWitness(def_id, args) => { - let hidden_types = bind_coroutine_hidden_types_above( - self.infcx, + let hidden_types = rebind_coroutine_witness_types( + self.infcx.tcx, def_id, args, obligation.predicate.bound_vars(), @@ -2348,7 +2347,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } ty::CoroutineWitness(def_id, args) => { - bind_coroutine_hidden_types_above(self.infcx, def_id, args, t.bound_vars()) + rebind_coroutine_witness_types(self.infcx.tcx, def_id, args, t.bound_vars()) } // For `PhantomData`, we pass `T`. @@ -2843,6 +2842,23 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } +fn rebind_coroutine_witness_types<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + bound_vars: &'tcx ty::List, +) -> ty::Binder<'tcx, Vec>> { + let bound_coroutine_types = tcx.coroutine_hidden_types(def_id).skip_binder(); + let shifted_coroutine_types = + tcx.shift_bound_var_indices(bound_vars.len(), bound_coroutine_types.skip_binder()); + ty::Binder::bind_with_vars( + ty::EarlyBinder::bind(shifted_coroutine_types.to_vec()).instantiate(tcx, args), + tcx.mk_bound_variable_kinds_from_iter( + bound_vars.iter().chain(bound_coroutine_types.bound_vars()), + ), + ) +} + impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> { fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> { TraitObligationStackList::with(self) @@ -3151,56 +3167,3 @@ pub(crate) enum ProjectionMatchesProjection { Ambiguous, No, } - -/// Replace all regions inside the coroutine interior with late bound regions. -/// Note that each region slot in the types gets a new fresh late bound region, which means that -/// none of the regions inside relate to any other, even if typeck had previously found constraints -/// that would cause them to be related. -#[instrument(level = "trace", skip(infcx), ret)] -fn bind_coroutine_hidden_types_above<'tcx>( - infcx: &InferCtxt<'tcx>, - def_id: DefId, - args: ty::GenericArgsRef<'tcx>, - bound_vars: &ty::List, -) -> ty::Binder<'tcx, Vec>> { - let tcx = infcx.tcx; - let mut seen_tys = FxHashSet::default(); - - let considering_regions = infcx.considering_regions; - - let num_bound_variables = bound_vars.len() as u32; - let mut counter = num_bound_variables; - - let hidden_types: Vec<_> = tcx - .coroutine_hidden_types(def_id) - // Deduplicate tys to avoid repeated work. - .filter(|bty| seen_tys.insert(*bty)) - .map(|mut bty| { - // Only remap erased regions if we use them. - if considering_regions { - bty = bty.map_bound(|ty| { - fold_regions(tcx, ty, |r, current_depth| match r.kind() { - ty::ReErased => { - let br = ty::BoundRegion { - var: ty::BoundVar::from_u32(counter), - kind: ty::BoundRegionKind::Anon, - }; - counter += 1; - ty::Region::new_bound(tcx, current_depth, br) - } - r => bug!("unexpected region: {r:?}"), - }) - }) - } - - bty.instantiate(tcx, args) - }) - .collect(); - let bound_vars = tcx.mk_bound_variable_kinds_from_iter( - bound_vars.iter().chain( - (num_bound_variables..counter) - .map(|_| ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon)), - ), - ); - ty::Binder::bind_with_vars(hidden_types, bound_vars) -} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 1cd0a8653fd9..584f3985624f 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -189,7 +189,7 @@ pub trait Interner: type Features: Features; fn features(self) -> Self::Features; - fn bound_coroutine_hidden_types( + fn coroutine_hidden_types( self, def_id: Self::DefId, ) -> ty::EarlyBinder>; From a954c512809a2d6f3e592c0287dbe41264b54808 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Sat, 18 Jan 2025 18:19:42 +0100 Subject: [PATCH 352/991] Support raw-dylib link kind on ELF raw-dylib is a link kind that allows rustc to link against a library without having any library files present. This currently only exists on Windows. rustc will take all the symbols from raw-dylib link blocks and put them in an import library, where they can then be resolved by the linker. While import libraries don't exist on ELF, it would still be convenient to have this same functionality. Not having the libraries present at build-time can be convenient for several reasons, especially cross-compilation. With raw-dylib, code linking against a library can be cross-compiled without needing to have these libraries available on the build machine. If the libc crate makes use of this, it would allow cross-compilation without having any libc available on the build machine. This is not yet possible with this implementation, at least against libc's like glibc that use symbol versioning. The raw-dylib kind could be extended with support for symbol versioning in the future. This implementation is very experimental and I have not tested it very well. I have tested it for a toy example and the lz4-sys crate, where it was able to successfully link a binary despite not having a corresponding library at build-time. --- compiler/rustc_codegen_ssa/src/back/link.rs | 218 ++++------ .../src/back/link/raw_dylib.rs | 373 ++++++++++++++++++ .../rustc_codegen_ssa/src/back/metadata.rs | 86 ++-- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_metadata/messages.ftl | 3 + compiler/rustc_metadata/src/native_libs.rs | 21 +- compiler/rustc_session/src/utils.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/spec/mod.rs | 55 ++- .../rustc-dev-guide/src/tests/directives.md | 1 + src/tools/compiletest/src/directive-list.rs | 2 + src/tools/compiletest/src/header/cfg.rs | 10 + tests/run-make/linker-warning/rmake.rs | 2 + tests/run-make/linker-warning/short-error.txt | 2 +- .../raw-dylib-elf-verbatim-absolute/main.rs | 11 + .../output.txt | 1 + .../raw-dylib-elf-verbatim-absolute/rmake.rs | 20 + .../run-make/raw-dylib-elf-verbatim/library.c | 3 + tests/run-make/raw-dylib-elf-verbatim/main.rs | 11 + .../raw-dylib-elf-verbatim/output.txt | 1 + .../run-make/raw-dylib-elf-verbatim/rmake.rs | 31 ++ tests/run-make/raw-dylib-elf/library.c | 3 + tests/run-make/raw-dylib-elf/main.rs | 11 + tests/run-make/raw-dylib-elf/output.txt | 1 + tests/run-make/raw-dylib-elf/rmake.rs | 29 ++ tests/run-make/reproducible-build/linker.rs | 2 + .../feature-gate-raw-dylib-elf.rs | 9 + .../feature-gate-raw-dylib-elf.stderr | 13 + .../raw-dylib/elf/multiple-libraries.rs | 37 ++ .../raw-dylib/elf/single-symbol.rs | 28 ++ .../ui/linkage-attr/raw-dylib/elf/verbatim.rs | 29 ++ .../raw-dylib/windows}/dlltool-failed.rs | 0 .../raw-dylib/windows}/dlltool-failed.stderr | 0 .../import-name-type-invalid-format.rs | 0 .../import-name-type-invalid-format.stderr | 0 .../windows}/import-name-type-multiple.rs | 0 .../windows}/import-name-type-multiple.stderr | 0 .../import-name-type-unknown-value.rs | 0 .../import-name-type-unknown-value.stderr | 0 .../import-name-type-unsupported-link-kind.rs | 0 ...ort-name-type-unsupported-link-kind.stderr | 0 .../windows}/import-name-type-x86-only.rs | 0 .../windows}/import-name-type-x86-only.stderr | 0 .../raw-dylib/windows}/invalid-dlltool.rs | 0 .../raw-dylib/windows}/invalid-dlltool.stderr | 0 .../windows}/link-ordinal-and-name.rs | 0 .../windows}/link-ordinal-and-name.stderr | 0 .../windows}/link-ordinal-invalid-format.rs | 0 .../link-ordinal-invalid-format.stderr | 0 .../windows}/link-ordinal-missing-argument.rs | 0 .../link-ordinal-missing-argument.stderr | 0 .../windows}/link-ordinal-multiple.rs | 0 .../windows}/link-ordinal-multiple.stderr | 0 .../windows}/link-ordinal-not-foreign-fn.rs | 0 .../link-ordinal-not-foreign-fn.stderr | 0 .../windows}/link-ordinal-too-large.rs | 0 .../windows}/link-ordinal-too-large.stderr | 0 .../link-ordinal-too-many-arguments.rs | 0 .../link-ordinal-too-many-arguments.stderr | 0 .../link-ordinal-unsupported-link-kind.rs | 0 .../link-ordinal-unsupported-link-kind.stderr | 0 .../windows}/multiple-declarations.rs | 0 .../windows}/multiple-declarations.stderr | 0 .../windows/raw-dylib-windows-only.elf.stderr | 13 + .../raw-dylib-windows-only.notelf.stderr} | 2 +- .../windows/raw-dylib-windows-only.rs | 9 + .../raw-dylib/windows}/unsupported-abi.rs | 0 .../raw-dylib/windows}/unsupported-abi.stderr | 0 .../raw-dylib-windows-only.rs | 5 - 69 files changed, 839 insertions(+), 207 deletions(-) create mode 100644 compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs create mode 100644 tests/run-make/raw-dylib-elf-verbatim-absolute/main.rs create mode 100644 tests/run-make/raw-dylib-elf-verbatim-absolute/output.txt create mode 100644 tests/run-make/raw-dylib-elf-verbatim-absolute/rmake.rs create mode 100644 tests/run-make/raw-dylib-elf-verbatim/library.c create mode 100644 tests/run-make/raw-dylib-elf-verbatim/main.rs create mode 100644 tests/run-make/raw-dylib-elf-verbatim/output.txt create mode 100644 tests/run-make/raw-dylib-elf-verbatim/rmake.rs create mode 100644 tests/run-make/raw-dylib-elf/library.c create mode 100644 tests/run-make/raw-dylib-elf/main.rs create mode 100644 tests/run-make/raw-dylib-elf/output.txt create mode 100644 tests/run-make/raw-dylib-elf/rmake.rs create mode 100644 tests/ui/feature-gates/feature-gate-raw-dylib-elf.rs create mode 100644 tests/ui/feature-gates/feature-gate-raw-dylib-elf.stderr create mode 100644 tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs create mode 100644 tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs create mode 100644 tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/dlltool-failed.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/dlltool-failed.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-invalid-format.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-invalid-format.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-multiple.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-multiple.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-unknown-value.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-unknown-value.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-unsupported-link-kind.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-unsupported-link-kind.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-x86-only.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/import-name-type-x86-only.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/invalid-dlltool.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/invalid-dlltool.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-and-name.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-and-name.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-invalid-format.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-invalid-format.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-missing-argument.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-missing-argument.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-multiple.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-multiple.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-not-foreign-fn.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-not-foreign-fn.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-too-large.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-too-large.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-too-many-arguments.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-too-many-arguments.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-unsupported-link-kind.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/link-ordinal-unsupported-link-kind.stderr (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/multiple-declarations.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/multiple-declarations.stderr (100%) create mode 100644 tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.elf.stderr rename tests/ui/{rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr => linkage-attr/raw-dylib/windows/raw-dylib-windows-only.notelf.stderr} (86%) create mode 100644 tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.rs rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/unsupported-abi.rs (100%) rename tests/ui/{rfcs/rfc-2627-raw-dylib => linkage-attr/raw-dylib/windows}/unsupported-abi.stderr (100%) delete mode 100644 tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.rs diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b090730ac6b5..177161461409 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1,3 +1,5 @@ +mod raw_dylib; + use std::collections::BTreeSet; use std::ffi::OsString; use std::fs::{File, OpenOptions, read}; @@ -12,7 +14,7 @@ use itertools::Itertools; use regex::Regex; use rustc_arena::TypedArena; use rustc_ast::CRATE_NODE_ID; -use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_errors::{DiagCtxtHandle, LintDiagnostic}; @@ -30,7 +32,6 @@ use rustc_session::config::{ self, CFGuard, CrateType, DebugInfo, LinkerFeaturesCli, OutFileName, OutputFilenames, OutputType, PrintKind, SplitDwarfKind, Strip, }; -use rustc_session::cstore::DllImport; use rustc_session::lint::builtin::LINKER_MESSAGES; use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; use rustc_session::search_paths::PathKind; @@ -41,22 +42,21 @@ use rustc_session::{Session, filesearch}; use rustc_span::Symbol; use rustc_target::spec::crt_objects::CrtObjects; use rustc_target::spec::{ - Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFeatures, - LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, - SplitDebuginfo, + BinaryFormat, Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, + LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel, + SanitizerSet, SplitDebuginfo, }; use tempfile::Builder as TempFileBuilder; use tracing::{debug, info, warn}; -use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder, ImportLibraryItem}; +use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; use super::command::Command; use super::linker::{self, Linker}; use super::metadata::{MetadataPosition, create_wrapper_file}; use super::rpath::{self, RPathConfig}; use super::{apple, versioned_llvm_target}; use crate::{ - CodegenResults, CompiledModule, CrateInfo, NativeLib, common, errors, - looks_like_rust_object_file, + CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file, }; pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) { @@ -376,16 +376,22 @@ fn link_rlib<'a>( } } - for output_path in create_dll_import_libs( - sess, - archive_builder_builder, - codegen_results.crate_info.used_libraries.iter(), - tmpdir.as_ref(), - true, - ) { - ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| { - sess.dcx().emit_fatal(errors::AddNativeLibrary { library_path: output_path, error }); - }); + // On Windows, we add the raw-dylib import libraries to the rlibs already. + // But on ELF, this is not possible, as a shared object cannot be a member of a static library. + // Instead, we add all raw-dylibs to the final link on ELF. + if sess.target.is_like_windows { + for output_path in raw_dylib::create_raw_dylib_dll_import_libs( + sess, + archive_builder_builder, + codegen_results.crate_info.used_libraries.iter(), + tmpdir.as_ref(), + true, + ) { + ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| { + sess.dcx() + .emit_fatal(errors::AddNativeLibrary { library_path: output_path, error }); + }); + } } if let Some(trailing_metadata) = trailing_metadata { @@ -426,108 +432,6 @@ fn link_rlib<'a>( ab } -/// Extract all symbols defined in raw-dylib libraries, collated by library name. -/// -/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library, -/// then the CodegenResults value contains one NativeLib instance for each block. However, the -/// linker appears to expect only a single import library for each library used, so we need to -/// collate the symbols together by library name before generating the import libraries. -fn collate_raw_dylibs<'a>( - sess: &Session, - used_libraries: impl IntoIterator, -) -> Vec<(String, Vec)> { - // Use index maps to preserve original order of imports and libraries. - let mut dylib_table = FxIndexMap::>::default(); - - for lib in used_libraries { - if lib.kind == NativeLibKind::RawDylib { - let ext = if lib.verbatim { "" } else { ".dll" }; - let name = format!("{}{}", lib.name, ext); - let imports = dylib_table.entry(name.clone()).or_default(); - for import in &lib.dll_imports { - if let Some(old_import) = imports.insert(import.name, import) { - // FIXME: when we add support for ordinals, figure out if we need to do anything - // if we have two DllImport values with the same name but different ordinals. - if import.calling_convention != old_import.calling_convention { - sess.dcx().emit_err(errors::MultipleExternalFuncDecl { - span: import.span, - function: import.name, - library_name: &name, - }); - } - } - } - } - } - sess.dcx().abort_if_errors(); - dylib_table - .into_iter() - .map(|(name, imports)| { - (name, imports.into_iter().map(|(_, import)| import.clone()).collect()) - }) - .collect() -} - -fn create_dll_import_libs<'a>( - sess: &Session, - archive_builder_builder: &dyn ArchiveBuilderBuilder, - used_libraries: impl IntoIterator, - tmpdir: &Path, - is_direct_dependency: bool, -) -> Vec { - collate_raw_dylibs(sess, used_libraries) - .into_iter() - .map(|(raw_dylib_name, raw_dylib_imports)| { - let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" }; - let output_path = tmpdir.join(format!("{raw_dylib_name}{name_suffix}.lib")); - - let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(&sess.target); - - let items: Vec = raw_dylib_imports - .iter() - .map(|import: &DllImport| { - if sess.target.arch == "x86" { - ImportLibraryItem { - name: common::i686_decorated_name( - import, - mingw_gnu_toolchain, - false, - false, - ), - ordinal: import.ordinal(), - symbol_name: import.is_missing_decorations().then(|| { - common::i686_decorated_name( - import, - mingw_gnu_toolchain, - false, - true, - ) - }), - is_data: !import.is_fn, - } - } else { - ImportLibraryItem { - name: import.name.to_string(), - ordinal: import.ordinal(), - symbol_name: None, - is_data: !import.is_fn, - } - } - }) - .collect(); - - archive_builder_builder.create_dll_import_lib( - sess, - &raw_dylib_name, - items, - &output_path, - ); - - output_path - }) - .collect() -} - /// Create a static archive. /// /// This is essentially the same thing as an rlib, but it also involves adding all of the upstream @@ -2418,15 +2322,39 @@ fn linker_with_args( link_output_kind, ); + // Raw-dylibs from all crates. + let raw_dylib_dir = tmpdir.join("raw-dylibs"); + if sess.target.binary_format == BinaryFormat::Elf { + // On ELF we can't pass the raw-dylibs stubs to the linker as a path, + // instead we need to pass them via -l. To find the stub, we need to add + // the directory of the stub to the linker search path. + // We make an extra directory for this to avoid polluting the search path. + if let Err(error) = fs::create_dir(&raw_dylib_dir) { + sess.dcx().emit_fatal(errors::CreateTempDir { error }) + } + cmd.include_path(&raw_dylib_dir); + } + // Link with the import library generated for any raw-dylib functions. - for output_path in create_dll_import_libs( - sess, - archive_builder_builder, - codegen_results.crate_info.used_libraries.iter(), - tmpdir, - true, - ) { - cmd.add_object(&output_path); + if sess.target.is_like_windows { + for output_path in raw_dylib::create_raw_dylib_dll_import_libs( + sess, + archive_builder_builder, + codegen_results.crate_info.used_libraries.iter(), + tmpdir, + true, + ) { + cmd.add_object(&output_path); + } + } else { + for link_path in raw_dylib::create_raw_dylib_elf_stub_shared_objects( + sess, + codegen_results.crate_info.used_libraries.iter(), + &raw_dylib_dir, + ) { + // Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects. + cmd.link_dylib_by_name(&link_path, true, false); + } } // As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case // they are used within inlined functions or instantiated generic functions. We do this *after* @@ -2445,19 +2373,35 @@ fn linker_with_args( .native_libraries .iter() .filter_map(|(&cnum, libraries)| { - (dependency_linkage[cnum] != Linkage::Static).then_some(libraries) + if sess.target.is_like_windows { + (dependency_linkage[cnum] != Linkage::Static).then_some(libraries) + } else { + Some(libraries) + } }) .flatten() .collect::>(); native_libraries_from_nonstatics.sort_unstable_by(|a, b| a.name.as_str().cmp(b.name.as_str())); - for output_path in create_dll_import_libs( - sess, - archive_builder_builder, - native_libraries_from_nonstatics, - tmpdir, - false, - ) { - cmd.add_object(&output_path); + + if sess.target.is_like_windows { + for output_path in raw_dylib::create_raw_dylib_dll_import_libs( + sess, + archive_builder_builder, + native_libraries_from_nonstatics, + tmpdir, + false, + ) { + cmd.add_object(&output_path); + } + } else { + for link_path in raw_dylib::create_raw_dylib_elf_stub_shared_objects( + sess, + native_libraries_from_nonstatics, + &raw_dylib_dir, + ) { + // Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects. + cmd.link_dylib_by_name(&link_path, true, false); + } } // Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs new file mode 100644 index 000000000000..2c24378afe13 --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -0,0 +1,373 @@ +use std::fs; +use std::io::{BufWriter, Write}; +use std::path::{Path, PathBuf}; + +use rustc_abi::Endian; +use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN}; +use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::stable_hasher::StableHasher; +use rustc_hashes::Hash128; +use rustc_session::Session; +use rustc_session::cstore::DllImport; +use rustc_session::utils::NativeLibKind; +use rustc_span::Symbol; + +use crate::back::archive::ImportLibraryItem; +use crate::back::link::ArchiveBuilderBuilder; +use crate::errors::ErrorCreatingImportLibrary; +use crate::{NativeLib, common, errors}; + +/// Extract all symbols defined in raw-dylib libraries, collated by library name. +/// +/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library, +/// then the CodegenResults value contains one NativeLib instance for each block. However, the +/// linker appears to expect only a single import library for each library used, so we need to +/// collate the symbols together by library name before generating the import libraries. +fn collate_raw_dylibs_windows<'a>( + sess: &Session, + used_libraries: impl IntoIterator, +) -> Vec<(String, Vec)> { + // Use index maps to preserve original order of imports and libraries. + let mut dylib_table = FxIndexMap::>::default(); + + for lib in used_libraries { + if lib.kind == NativeLibKind::RawDylib { + let ext = if lib.verbatim { "" } else { ".dll" }; + let name = format!("{}{}", lib.name, ext); + let imports = dylib_table.entry(name.clone()).or_default(); + for import in &lib.dll_imports { + if let Some(old_import) = imports.insert(import.name, import) { + // FIXME: when we add support for ordinals, figure out if we need to do anything + // if we have two DllImport values with the same name but different ordinals. + if import.calling_convention != old_import.calling_convention { + sess.dcx().emit_err(errors::MultipleExternalFuncDecl { + span: import.span, + function: import.name, + library_name: &name, + }); + } + } + } + } + } + sess.dcx().abort_if_errors(); + dylib_table + .into_iter() + .map(|(name, imports)| { + (name, imports.into_iter().map(|(_, import)| import.clone()).collect()) + }) + .collect() +} + +pub(super) fn create_raw_dylib_dll_import_libs<'a>( + sess: &Session, + archive_builder_builder: &dyn ArchiveBuilderBuilder, + used_libraries: impl IntoIterator, + tmpdir: &Path, + is_direct_dependency: bool, +) -> Vec { + collate_raw_dylibs_windows(sess, used_libraries) + .into_iter() + .map(|(raw_dylib_name, raw_dylib_imports)| { + let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" }; + let output_path = tmpdir.join(format!("{raw_dylib_name}{name_suffix}.lib")); + + let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(&sess.target); + + let items: Vec = raw_dylib_imports + .iter() + .map(|import: &DllImport| { + if sess.target.arch == "x86" { + ImportLibraryItem { + name: common::i686_decorated_name( + import, + mingw_gnu_toolchain, + false, + false, + ), + ordinal: import.ordinal(), + symbol_name: import.is_missing_decorations().then(|| { + common::i686_decorated_name( + import, + mingw_gnu_toolchain, + false, + true, + ) + }), + is_data: !import.is_fn, + } + } else { + ImportLibraryItem { + name: import.name.to_string(), + ordinal: import.ordinal(), + symbol_name: None, + is_data: !import.is_fn, + } + } + }) + .collect(); + + archive_builder_builder.create_dll_import_lib( + sess, + &raw_dylib_name, + items, + &output_path, + ); + + output_path + }) + .collect() +} + +/// Extract all symbols defined in raw-dylib libraries, collated by library name. +/// +/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library, +/// then the CodegenResults value contains one NativeLib instance for each block. However, the +/// linker appears to expect only a single import library for each library used, so we need to +/// collate the symbols together by library name before generating the import libraries. +fn collate_raw_dylibs_elf<'a>( + sess: &Session, + used_libraries: impl IntoIterator, +) -> Vec<(String, Vec)> { + // Use index maps to preserve original order of imports and libraries. + let mut dylib_table = FxIndexMap::>::default(); + + for lib in used_libraries { + if lib.kind == NativeLibKind::RawDylib { + let filename = if lib.verbatim { + lib.name.as_str().to_owned() + } else { + let ext = sess.target.dll_suffix.as_ref(); + let prefix = sess.target.dll_prefix.as_ref(); + format!("{prefix}{}{ext}", lib.name) + }; + + let imports = dylib_table.entry(filename.clone()).or_default(); + for import in &lib.dll_imports { + imports.insert(import.name, import); + } + } + } + sess.dcx().abort_if_errors(); + dylib_table + .into_iter() + .map(|(name, imports)| { + (name, imports.into_iter().map(|(_, import)| import.clone()).collect()) + }) + .collect() +} + +pub(super) fn create_raw_dylib_elf_stub_shared_objects<'a>( + sess: &Session, + used_libraries: impl IntoIterator, + raw_dylib_so_dir: &Path, +) -> Vec { + collate_raw_dylibs_elf(sess, used_libraries) + .into_iter() + .map(|(load_filename, raw_dylib_imports)| { + use std::hash::Hash; + + // `load_filename` is the *target/loader* filename that will end up in NEEDED. + // Usually this will be something like `libc.so` or `libc.so.6` but with + // verbatim it might also be an absolute path. + // To be able to support this properly, we always put this load filename + // into the SONAME of the library and link it via a temporary file with a random name. + // This also avoids naming conflicts with non-raw-dylib linkage of the same library. + + let shared_object = create_elf_raw_dylib_stub(sess, &load_filename, &raw_dylib_imports); + + let mut file_name_hasher = StableHasher::new(); + load_filename.hash(&mut file_name_hasher); + for raw_dylib in raw_dylib_imports { + raw_dylib.name.as_str().hash(&mut file_name_hasher); + } + + let library_filename: Hash128 = file_name_hasher.finish(); + let temporary_lib_name = format!( + "{}{}{}", + sess.target.dll_prefix, + library_filename.as_u128().to_base_fixed_len(CASE_INSENSITIVE), + sess.target.dll_suffix + ); + let link_path = raw_dylib_so_dir.join(&temporary_lib_name); + + let file = match fs::File::create_new(&link_path) { + Ok(file) => file, + Err(error) => sess.dcx().emit_fatal(ErrorCreatingImportLibrary { + lib_name: &load_filename, + error: error.to_string(), + }), + }; + if let Err(error) = BufWriter::new(file).write_all(&shared_object) { + sess.dcx().emit_fatal(ErrorCreatingImportLibrary { + lib_name: &load_filename, + error: error.to_string(), + }); + }; + + temporary_lib_name + }) + .collect() +} + +/// Create an ELF .so stub file for raw-dylib. +/// It exports all the provided symbols, but is otherwise empty. +fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]) -> Vec { + use object::write::elf as write; + use object::{Architecture, elf}; + + let mut stub_buf = Vec::new(); + + // Build the stub ELF using the object crate. + // The high-level portable API does not allow for the fine-grained control we need, + // so this uses the low-level object::write::elf API. + // The low-level API consists of two stages: reservation and writing. + // We first reserve space for all the things in the binary and then write them. + // It is important that the order of reservation matches the order of writing. + // The object crate contains many debug asserts that fire if you get this wrong. + + let endianness = match sess.target.options.endian { + Endian::Little => object::Endianness::Little, + Endian::Big => object::Endianness::Big, + }; + let mut stub = write::Writer::new(endianness, true, &mut stub_buf); + + // These initial reservations don't reserve any bytes in the binary yet, + // they just allocate in the internal data structures. + + // First, we crate the dynamic symbol table. It starts with a null symbol + // and then all the symbols and their dynamic strings. + stub.reserve_null_dynamic_symbol_index(); + + let dynstrs = symbols + .iter() + .map(|sym| { + stub.reserve_dynamic_symbol_index(); + (sym, stub.add_dynamic_string(sym.name.as_str().as_bytes())) + }) + .collect::>(); + + let soname = stub.add_dynamic_string(soname.as_bytes()); + + // Reserve the sections. + // We have the minimal sections for a dynamic SO and .text where we point our dummy symbols to. + stub.reserve_shstrtab_section_index(); + let text_section_name = stub.add_section_name(".text".as_bytes()); + let text_section = stub.reserve_section_index(); + stub.reserve_dynstr_section_index(); + stub.reserve_dynsym_section_index(); + stub.reserve_dynamic_section_index(); + + // These reservations now determine the actual layout order of the object file. + stub.reserve_file_header(); + stub.reserve_shstrtab(); + stub.reserve_section_headers(); + stub.reserve_dynstr(); + stub.reserve_dynsym(); + stub.reserve_dynamic(2); // DT_SONAME, DT_NULL + + // First write the ELF header with the arch information. + let Some((arch, sub_arch)) = sess.target.object_architecture(&sess.unstable_target_features) + else { + sess.dcx().fatal(format!( + "raw-dylib is not supported for the architecture `{}`", + sess.target.arch + )); + }; + let e_machine = match (arch, sub_arch) { + (Architecture::Aarch64, None) => elf::EM_AARCH64, + (Architecture::Aarch64_Ilp32, None) => elf::EM_AARCH64, + (Architecture::Arm, None) => elf::EM_ARM, + (Architecture::Avr, None) => elf::EM_AVR, + (Architecture::Bpf, None) => elf::EM_BPF, + (Architecture::Csky, None) => elf::EM_CSKY, + (Architecture::E2K32, None) => elf::EM_MCST_ELBRUS, + (Architecture::E2K64, None) => elf::EM_MCST_ELBRUS, + (Architecture::I386, None) => elf::EM_386, + (Architecture::X86_64, None) => elf::EM_X86_64, + (Architecture::X86_64_X32, None) => elf::EM_X86_64, + (Architecture::Hexagon, None) => elf::EM_HEXAGON, + (Architecture::LoongArch64, None) => elf::EM_LOONGARCH, + (Architecture::M68k, None) => elf::EM_68K, + (Architecture::Mips, None) => elf::EM_MIPS, + (Architecture::Mips64, None) => elf::EM_MIPS, + (Architecture::Mips64_N32, None) => elf::EM_MIPS, + (Architecture::Msp430, None) => elf::EM_MSP430, + (Architecture::PowerPc, None) => elf::EM_PPC, + (Architecture::PowerPc64, None) => elf::EM_PPC64, + (Architecture::Riscv32, None) => elf::EM_RISCV, + (Architecture::Riscv64, None) => elf::EM_RISCV, + (Architecture::S390x, None) => elf::EM_S390, + (Architecture::Sbf, None) => elf::EM_SBF, + (Architecture::Sharc, None) => elf::EM_SHARC, + (Architecture::Sparc, None) => elf::EM_SPARC, + (Architecture::Sparc32Plus, None) => elf::EM_SPARC32PLUS, + (Architecture::Sparc64, None) => elf::EM_SPARCV9, + (Architecture::Xtensa, None) => elf::EM_XTENSA, + _ => { + sess.dcx().fatal(format!( + "raw-dylib is not supported for the architecture `{}`", + sess.target.arch + )); + } + }; + + stub.write_file_header(&write::FileHeader { + os_abi: crate::back::metadata::elf_os_abi(sess), + abi_version: 0, + e_type: object::elf::ET_DYN, + e_machine, + e_entry: 0, + e_flags: crate::back::metadata::elf_e_flags(arch, sess), + }) + .unwrap(); + + // .shstrtab + stub.write_shstrtab(); + + // Section headers + stub.write_null_section_header(); + stub.write_shstrtab_section_header(); + // Create a dummy .text section for our dummy symbols. + stub.write_section_header(&write::SectionHeader { + name: Some(text_section_name), + sh_type: elf::SHT_PROGBITS, + sh_flags: 0, + sh_addr: 0, + sh_offset: 0, + sh_size: 0, + sh_link: 0, + sh_info: 0, + sh_addralign: 1, + sh_entsize: 0, + }); + stub.write_dynstr_section_header(0); + stub.write_dynsym_section_header(0, 1); + stub.write_dynamic_section_header(0); + + // .dynstr + stub.write_dynstr(); + + // .dynsym + stub.write_null_dynamic_symbol(); + for (_, name) in dynstrs { + stub.write_dynamic_symbol(&write::Sym { + name: Some(name), + st_info: (elf::STB_GLOBAL << 4) | elf::STT_NOTYPE, + st_other: elf::STV_DEFAULT, + section: Some(text_section), + st_shndx: 0, // ignored by object in favor of the `section` field + st_value: 0, + st_size: 0, + }); + } + + // .dynamic + // the DT_SONAME will be used by the linker to populate DT_NEEDED + // which the loader uses to find the library. + // DT_NULL terminates the .dynamic table. + stub.write_dynamic_string(elf::DT_SONAME, soname); + stub.write_dynamic(elf::DT_NULL, 0); + + stub_buf +} diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 236507ac0cd2..75179a65e342 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -9,8 +9,7 @@ use itertools::Itertools; use object::write::{self, StandardSegment, Symbol, SymbolSection}; use object::{ Architecture, BinaryFormat, Endianness, FileFlags, Object, ObjectSection, ObjectSymbol, - SectionFlags, SectionKind, SubArchitecture, SymbolFlags, SymbolKind, SymbolScope, elf, pe, - xcoff, + SectionFlags, SectionKind, SymbolFlags, SymbolKind, SymbolScope, elf, pe, xcoff, }; use rustc_abi::Endian; use rustc_data_structures::memmap::Mmap; @@ -206,51 +205,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option Endianness::Little, Endian::Big => Endianness::Big, }; - let (architecture, sub_architecture) = match &sess.target.arch[..] { - "arm" => (Architecture::Arm, None), - "aarch64" => ( - if sess.target.pointer_width == 32 { - Architecture::Aarch64_Ilp32 - } else { - Architecture::Aarch64 - }, - None, - ), - "x86" => (Architecture::I386, None), - "s390x" => (Architecture::S390x, None), - "mips" | "mips32r6" => (Architecture::Mips, None), - "mips64" | "mips64r6" => (Architecture::Mips64, None), - "x86_64" => ( - if sess.target.pointer_width == 32 { - Architecture::X86_64_X32 - } else { - Architecture::X86_64 - }, - None, - ), - "powerpc" => (Architecture::PowerPc, None), - "powerpc64" => (Architecture::PowerPc64, None), - "riscv32" => (Architecture::Riscv32, None), - "riscv64" => (Architecture::Riscv64, None), - "sparc" => { - if sess.unstable_target_features.contains(&sym::v8plus) { - // Target uses V8+, aka EM_SPARC32PLUS, aka 64-bit V9 but in 32-bit mode - (Architecture::Sparc32Plus, None) - } else { - // Target uses V7 or V8, aka EM_SPARC - (Architecture::Sparc, None) - } - } - "sparc64" => (Architecture::Sparc64, None), - "avr" => (Architecture::Avr, None), - "msp430" => (Architecture::Msp430, None), - "hexagon" => (Architecture::Hexagon, None), - "bpf" => (Architecture::Bpf, None), - "loongarch64" => (Architecture::LoongArch64, None), - "csky" => (Architecture::Csky, None), - "arm64ec" => (Architecture::Aarch64, Some(SubArchitecture::Arm64EC)), - // Unsupported architecture. - _ => return None, + let Some((architecture, sub_architecture)) = + sess.target.object_architecture(&sess.unstable_target_features) + else { + return None; }; let binary_format = sess.target.binary_format.to_object(); @@ -292,7 +250,26 @@ pub(crate) fn create_object_file(sess: &Session) -> Option u8 { + match sess.target.options.os.as_ref() { + "hermit" => elf::ELFOSABI_STANDALONE, + "freebsd" => elf::ELFOSABI_FREEBSD, + "solaris" => elf::ELFOSABI_SOLARIS, + _ => elf::ELFOSABI_NONE, + } +} + +pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { + match architecture { Architecture::Mips => { let arch = match sess.target.options.cpu.as_ref() { "mips1" => elf::EF_MIPS_ARCH_1, @@ -383,18 +360,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option 0, - }; - // adapted from LLVM's `MCELFObjectTargetWriter::getOSABI` - let os_abi = match sess.target.options.os.as_ref() { - "hermit" => elf::ELFOSABI_STANDALONE, - "freebsd" => elf::ELFOSABI_FREEBSD, - "solaris" => elf::ELFOSABI_SOLARIS, - _ => elf::ELFOSABI_NONE, - }; - let abi_version = 0; - add_gnu_property_note(&mut file, architecture, binary_format, endianness); - file.flags = FileFlags::Elf { os_abi, abi_version, e_flags }; - Some(file) + } } /// Mach-O files contain information about: diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 66c26a541f17..813a773c70e5 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -599,6 +599,8 @@ declare_features! ( (unstable, precise_capturing_in_traits, "1.83.0", Some(130044)), /// Allows macro attributes on expressions, statements and non-inline modules. (unstable, proc_macro_hygiene, "1.30.0", Some(54727)), + /// Allows the use of raw-dylibs on ELF platforms + (incomplete, raw_dylib_elf, "CURRENT_RUSTC_VERSION", Some(135694)), /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)), /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index df0a25712cca..20f66fae5c01 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -244,6 +244,9 @@ metadata_prev_alloc_error_handler = metadata_prev_global_alloc = previous global allocator defined here +metadata_raw_dylib_elf_unstable = + link kind `raw-dylib` is unstable on ELF platforms + metadata_raw_dylib_no_nul = link name must not contain NUL characters if link kind is `raw-dylib` diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index e2d043f47c0e..b96921a63f35 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -17,7 +17,7 @@ use rustc_session::search_paths::PathKind; use rustc_session::utils::NativeLibKind; use rustc_span::def_id::{DefId, LOCAL_CRATE}; use rustc_span::{Symbol, sym}; -use rustc_target::spec::LinkSelfContainedComponents; +use rustc_target::spec::{BinaryFormat, LinkSelfContainedComponents}; use crate::{errors, fluent_generated}; @@ -263,9 +263,26 @@ impl<'tcx> Collector<'tcx> { NativeLibKind::Framework { as_needed: None } } "raw-dylib" => { - if !sess.target.is_like_windows { + if sess.target.is_like_windows { + // raw-dylib is stable and working on Windows + } else if sess.target.binary_format == BinaryFormat::Elf + && features.raw_dylib_elf() + { + // raw-dylib is unstable on ELF, but the user opted in + } else if sess.target.binary_format == BinaryFormat::Elf + && sess.is_nightly_build() + { + feature_err( + sess, + sym::raw_dylib_elf, + span, + fluent_generated::metadata_raw_dylib_elf_unstable, + ) + .emit(); + } else { sess.dcx().emit_err(errors::RawDylibOnlyWindows { span }); } + NativeLibKind::RawDylib } "link-arg" => { diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index 9182789cf026..fcede379b893 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -34,6 +34,7 @@ pub enum NativeLibKind { as_needed: Option, }, /// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library. + /// On Linux, it refers to a generated shared library stub. RawDylib, /// A macOS-specific kind of dynamic libraries. Framework { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 501c9039f2de..e8d47d4330a7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1624,6 +1624,7 @@ symbols! { quote, range_inclusive_new, raw_dylib, + raw_dylib_elf, raw_eq, raw_identifiers, raw_ref_op, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index cc8162a2f27e..72202129f5b6 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -43,7 +43,7 @@ use std::str::FromStr; use std::{fmt, io}; use rustc_abi::{Endian, ExternAbi, Integer, Size, TargetDataLayout, TargetDataLayoutErrors}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_fs_util::try_canonicalize; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -3535,6 +3535,59 @@ impl Target { s => s.clone(), } } + + pub fn object_architecture( + &self, + unstable_target_features: &FxIndexSet, + ) -> Option<(object::Architecture, Option)> { + use object::Architecture; + Some(match self.arch.as_ref() { + "arm" => (Architecture::Arm, None), + "aarch64" => ( + if self.pointer_width == 32 { + Architecture::Aarch64_Ilp32 + } else { + Architecture::Aarch64 + }, + None, + ), + "x86" => (Architecture::I386, None), + "s390x" => (Architecture::S390x, None), + "mips" | "mips32r6" => (Architecture::Mips, None), + "mips64" | "mips64r6" => (Architecture::Mips64, None), + "x86_64" => ( + if self.pointer_width == 32 { + Architecture::X86_64_X32 + } else { + Architecture::X86_64 + }, + None, + ), + "powerpc" => (Architecture::PowerPc, None), + "powerpc64" => (Architecture::PowerPc64, None), + "riscv32" => (Architecture::Riscv32, None), + "riscv64" => (Architecture::Riscv64, None), + "sparc" => { + if unstable_target_features.contains(&sym::v8plus) { + // Target uses V8+, aka EM_SPARC32PLUS, aka 64-bit V9 but in 32-bit mode + (Architecture::Sparc32Plus, None) + } else { + // Target uses V7 or V8, aka EM_SPARC + (Architecture::Sparc, None) + } + } + "sparc64" => (Architecture::Sparc64, None), + "avr" => (Architecture::Avr, None), + "msp430" => (Architecture::Msp430, None), + "hexagon" => (Architecture::Hexagon, None), + "bpf" => (Architecture::Bpf, None), + "loongarch64" => (Architecture::LoongArch64, None), + "csky" => (Architecture::Csky, None), + "arm64ec" => (Architecture::Aarch64, Some(object::SubArchitecture::Arm64EC)), + // Unsupported architecture. + _ => return None, + }) + } } /// Either a target tuple string or a path to a JSON file. diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 00bb2bc4dbb1..af9cb85d27b5 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -142,6 +142,7 @@ Some examples of `X` in `ignore-X` or `only-X`: matches that target as well as the emscripten targets. - Pointer width: `32bit`, `64bit` - Endianness: `endian-big` +- Binary format: `elf` - Stage: `stage0`, `stage1`, `stage2` - Channel: `stable`, `beta` - When cross compiling: `cross-compile` diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 8c909bcb1952..b2ad5a3b3d0b 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -52,6 +52,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-coverage-run", "ignore-cross-compile", "ignore-eabi", + "ignore-elf", "ignore-emscripten", "ignore-endian-big", "ignore-enzyme", @@ -182,6 +183,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-bpf", "only-cdb", "only-dist", + "only-elf", "only-emscripten", "only-gnu", "only-i686-pc-windows-gnu", diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs index 72a3b9d85c8c..c369fff97f4f 100644 --- a/src/tools/compiletest/src/header/cfg.rs +++ b/src/tools/compiletest/src/header/cfg.rs @@ -166,6 +166,16 @@ fn parse_cfg_name_directive<'a>( message: "when the target vendor is Apple" } + condition! { + name: "elf", + condition: !config.target.contains("windows") + && !config.target.contains("wasm") + && !config.target.contains("apple") + && !config.target.contains("aix") + && !config.target.contains("uefi"), + message: "when the target binary format is ELF" + } + condition! { name: "enzyme", condition: config.has_enzyme, diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs index 30387af428c6..73ad248b6f36 100644 --- a/tests/run-make/linker-warning/rmake.rs +++ b/tests/run-make/linker-warning/rmake.rs @@ -60,6 +60,8 @@ fn main() { regex::escape(run_make_support::build_root().to_str().unwrap()), "/build-root", ) + .normalize(r#""[^"]*\/symbols.o""#, "\"/symbols.o\"") + .normalize(r#""[^"]*\/raw-dylibs""#, "\"/raw-dylibs\"") .run(); } diff --git a/tests/run-make/linker-warning/short-error.txt b/tests/run-make/linker-warning/short-error.txt index dd3b742bbfd5..a7f48af885a0 100644 --- a/tests/run-make/linker-warning/short-error.txt +++ b/tests/run-make/linker-warning/short-error.txt @@ -1,6 +1,6 @@ error: linking with `./fake-linker` failed: exit status: 1 | - = note: "./fake-linker" "-m64" "/tmp/rustc/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error" + = note: "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error" = note: some arguments are omitted. use `--verbose` to show all linker arguments = note: error: baz diff --git a/tests/run-make/raw-dylib-elf-verbatim-absolute/main.rs b/tests/run-make/raw-dylib-elf-verbatim-absolute/main.rs new file mode 100644 index 000000000000..75bd7747f4fe --- /dev/null +++ b/tests/run-make/raw-dylib-elf-verbatim-absolute/main.rs @@ -0,0 +1,11 @@ +#![feature(raw_dylib_elf)] +#![allow(incomplete_features)] + +#[link(name = "/absolute-path/liblibrary.so.1", kind = "raw-dylib", modifiers = "+verbatim")] +unsafe extern "C" { + safe fn this_is_a_library_function() -> core::ffi::c_int; +} + +fn main() { + println!("{}", this_is_a_library_function()) +} diff --git a/tests/run-make/raw-dylib-elf-verbatim-absolute/output.txt b/tests/run-make/raw-dylib-elf-verbatim-absolute/output.txt new file mode 100644 index 000000000000..d81cc0710eb6 --- /dev/null +++ b/tests/run-make/raw-dylib-elf-verbatim-absolute/output.txt @@ -0,0 +1 @@ +42 diff --git a/tests/run-make/raw-dylib-elf-verbatim-absolute/rmake.rs b/tests/run-make/raw-dylib-elf-verbatim-absolute/rmake.rs new file mode 100644 index 000000000000..d2a9b0477e5e --- /dev/null +++ b/tests/run-make/raw-dylib-elf-verbatim-absolute/rmake.rs @@ -0,0 +1,20 @@ +//@ only-elf +//@ ignore-cross-compile: Runs a binary. +//@ needs-dynamic-linking +// FIXME(raw_dylib_elf): Debug the failures on other targets. +//@ only-gnu +//@ only-x86_64 + +//! Ensure ELF raw-dylib is able to link against a non-existent verbatim absolute path +//! by embedding the absolute path in the DT_SONAME and passing a different path for +//! the linker for the stub. + +use run_make_support::{build_native_dynamic_lib, cwd, diff, rfs, run, rustc}; + +fn main() { + // We compile the binary without having the library present. + // The verbatim library name is an absolute path. + rustc().crate_type("bin").input("main.rs").run(); + + // FIXME(raw_dylib_elf): Read the NEEDED of the library to ensure it's the absolute path. +} diff --git a/tests/run-make/raw-dylib-elf-verbatim/library.c b/tests/run-make/raw-dylib-elf-verbatim/library.c new file mode 100644 index 000000000000..2e3a95b7edec --- /dev/null +++ b/tests/run-make/raw-dylib-elf-verbatim/library.c @@ -0,0 +1,3 @@ +int this_is_a_library_function() { + return 42; +} diff --git a/tests/run-make/raw-dylib-elf-verbatim/main.rs b/tests/run-make/raw-dylib-elf-verbatim/main.rs new file mode 100644 index 000000000000..044b7400a841 --- /dev/null +++ b/tests/run-make/raw-dylib-elf-verbatim/main.rs @@ -0,0 +1,11 @@ +#![feature(raw_dylib_elf)] +#![allow(incomplete_features)] + +#[link(name = "liblibrary.so.1", kind = "raw-dylib", modifiers = "+verbatim")] +unsafe extern "C" { + safe fn this_is_a_library_function() -> core::ffi::c_int; +} + +fn main() { + println!("{}", this_is_a_library_function()) +} diff --git a/tests/run-make/raw-dylib-elf-verbatim/output.txt b/tests/run-make/raw-dylib-elf-verbatim/output.txt new file mode 100644 index 000000000000..d81cc0710eb6 --- /dev/null +++ b/tests/run-make/raw-dylib-elf-verbatim/output.txt @@ -0,0 +1 @@ +42 diff --git a/tests/run-make/raw-dylib-elf-verbatim/rmake.rs b/tests/run-make/raw-dylib-elf-verbatim/rmake.rs new file mode 100644 index 000000000000..319534b24c88 --- /dev/null +++ b/tests/run-make/raw-dylib-elf-verbatim/rmake.rs @@ -0,0 +1,31 @@ +//@ only-elf +//@ ignore-cross-compile: Runs a binary. +//@ needs-dynamic-linking +// FIXME(raw_dylib_elf): Debug the failures on other targets. +//@ only-gnu +//@ only-x86_64 + +//! Ensure ELF raw-dylib is able to link against the verbatim versioned library +//! without it being present, and then be executed against this library. + +use run_make_support::{build_native_dynamic_lib, cwd, diff, rfs, run, rustc}; + +fn main() { + // We compile the binary without having the library present. + // We also set the rpath to the current directory so we can pick up the library at runtime. + rustc() + .crate_type("bin") + .input("main.rs") + .arg(&format!("-Wl,-rpath={}", cwd().display())) + .run(); + + // Now, *after* building the binary, we build the library... + build_native_dynamic_lib("library"); + // ... rename it to have the versioned library name... + rfs::rename("liblibrary.so", "liblibrary.so.1"); + + // ... and run with this library, ensuring it was linked correctly at runtime. + let output = run("main").stdout_utf8(); + + diff().expected_file("output.txt").actual_text("actual", output).run(); +} diff --git a/tests/run-make/raw-dylib-elf/library.c b/tests/run-make/raw-dylib-elf/library.c new file mode 100644 index 000000000000..2e3a95b7edec --- /dev/null +++ b/tests/run-make/raw-dylib-elf/library.c @@ -0,0 +1,3 @@ +int this_is_a_library_function() { + return 42; +} diff --git a/tests/run-make/raw-dylib-elf/main.rs b/tests/run-make/raw-dylib-elf/main.rs new file mode 100644 index 000000000000..3be944d29514 --- /dev/null +++ b/tests/run-make/raw-dylib-elf/main.rs @@ -0,0 +1,11 @@ +#![feature(raw_dylib_elf)] +#![allow(incomplete_features)] + +#[link(name = "library", kind = "raw-dylib")] +unsafe extern "C" { + safe fn this_is_a_library_function() -> core::ffi::c_int; +} + +fn main() { + println!("{}", this_is_a_library_function()) +} diff --git a/tests/run-make/raw-dylib-elf/output.txt b/tests/run-make/raw-dylib-elf/output.txt new file mode 100644 index 000000000000..d81cc0710eb6 --- /dev/null +++ b/tests/run-make/raw-dylib-elf/output.txt @@ -0,0 +1 @@ +42 diff --git a/tests/run-make/raw-dylib-elf/rmake.rs b/tests/run-make/raw-dylib-elf/rmake.rs new file mode 100644 index 000000000000..59f901ac1ed7 --- /dev/null +++ b/tests/run-make/raw-dylib-elf/rmake.rs @@ -0,0 +1,29 @@ +//@ only-elf +//@ ignore-cross-compile: Runs a binary. +//@ needs-dynamic-linking +// FIXME(raw_dylib_elf): Debug the failures on other targets. +//@ only-gnu +//@ only-x86_64 + +//! Ensure ELF raw-dylib is able to link the binary without having the library present, +//! and then successfully run against the real library. + +use run_make_support::{build_native_dynamic_lib, cwd, diff, run, rustc}; + +fn main() { + // We compile the binary without having the library present. + // We also set the rpath to the current directory so we can pick up the library at runtime. + rustc() + .crate_type("bin") + .input("main.rs") + .arg(&format!("-Wl,-rpath={}", cwd().display())) + .run(); + + // Now, *after* building the binary, we build the library... + build_native_dynamic_lib("library"); + + // ... and run with this library, ensuring it was linked correctly at runtime. + let output = run("main").stdout_utf8(); + + diff().expected_file("output.txt").actual_text("actual", output).run(); +} diff --git a/tests/run-make/reproducible-build/linker.rs b/tests/run-make/reproducible-build/linker.rs index ab3b4049cc32..2f57d9f9be9a 100644 --- a/tests/run-make/reproducible-build/linker.rs +++ b/tests/run-make/reproducible-build/linker.rs @@ -17,6 +17,8 @@ fn main() { for arg in env::args().skip(1) { let path = Path::new(&arg); if !path.is_file() { + // This directory is produced during linking in a temporary directory (ELF only). + let arg = if arg.ends_with("/raw-dylibs") { "/raw-dylibs" } else { &*arg }; out.push_str(&arg); out.push_str("\n"); continue; diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-elf.rs b/tests/ui/feature-gates/feature-gate-raw-dylib-elf.rs new file mode 100644 index 000000000000..ec49e53d9b44 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-raw-dylib-elf.rs @@ -0,0 +1,9 @@ +//@ only-elf +//@ needs-dynamic-linking + +#[link(name = "meow", kind = "raw-dylib")] //~ ERROR: link kind `raw-dylib` is unstable on ELF platforms +unsafe extern "C" { + safe fn meowmeow(); +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-elf.stderr b/tests/ui/feature-gates/feature-gate-raw-dylib-elf.stderr new file mode 100644 index 000000000000..dfbf39f5a189 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-raw-dylib-elf.stderr @@ -0,0 +1,13 @@ +error[E0658]: link kind `raw-dylib` is unstable on ELF platforms + --> $DIR/feature-gate-raw-dylib-elf.rs:4:30 + | +LL | #[link(name = "meow", kind = "raw-dylib")] + | ^^^^^^^^^^^ + | + = note: see issue #135694 for more information + = help: add `#![feature(raw_dylib_elf)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs b/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs new file mode 100644 index 000000000000..f4715ff2d3d6 --- /dev/null +++ b/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs @@ -0,0 +1,37 @@ +//@ only-elf +//@ needs-dynamic-linking +// FIXME(raw_dylib_elf): Debug the failures on other targets. +//@ only-gnu +//@ only-x86_64 + +//@ revisions: with without + +//@ [without] build-fail +//@ [without] regex-error-pattern:error: linking with `.*` failed +//@ [without] dont-check-compiler-stderr + +//@ [with] build-pass + +//! Ensures that linking fails when there's an undefined symbol, +//! and that it does succeed with raw-dylib. + +#![feature(raw_dylib_elf)] +#![allow(incomplete_features)] + +#[cfg_attr(with, link(name = "rawdylibbutforcats", kind = "raw-dylib"))] +#[cfg_attr(without, link(name = "rawdylibbutforcats"))] +unsafe extern "C" { + safe fn meooooooooooooooow(); +} + + +#[cfg_attr(with, link(name = "rawdylibbutfordogs", kind = "raw-dylib"))] +#[cfg_attr(without, link(name = "rawdylibbutfordogs"))] +unsafe extern "C" { + safe fn woooooooooooooooooof(); +} + +fn main() { + meooooooooooooooow(); + woooooooooooooooooof(); +} diff --git a/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs b/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs new file mode 100644 index 000000000000..fe9c7884e54d --- /dev/null +++ b/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs @@ -0,0 +1,28 @@ +//@ only-elf +//@ needs-dynamic-linking +// FIXME(raw_dylib_elf): Debug the failures on other targets. +//@ only-gnu +//@ only-x86_64 +//@ revisions: with without + +//@ [without] build-fail +//@ [without] regex-error-pattern:error: linking with `.*` failed +//@ [without] dont-check-compiler-stderr + +//@ [with] build-pass + +//! Ensures that linking fails when there's an undefined symbol, +//! and that it does succeed with raw-dylib. + +#![feature(raw_dylib_elf)] +#![allow(incomplete_features)] + +#[cfg_attr(with, link(name = "rawdylibbutforcats", kind = "raw-dylib"))] +#[cfg_attr(without, link(name = "rawdylibbutforcats"))] +unsafe extern "C" { + safe fn meooooooooooooooow(); +} + +fn main() { + meooooooooooooooow(); +} diff --git a/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs b/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs new file mode 100644 index 000000000000..72cba18d8411 --- /dev/null +++ b/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs @@ -0,0 +1,29 @@ +//@ only-elf +//@ needs-dynamic-linking +// FIXME(raw_dylib_elf): Debug the failures on other targets. +//@ only-gnu +//@ only-x86_64 + +//@ revisions: with without + +//@ [without] build-fail +//@ [without] regex-error-pattern:error: linking with `.*` failed +//@ [without] dont-check-compiler-stderr + +//@ [with] build-pass + +//! Ensures that linking fails when there's an undefined symbol, +//! and that it does succeed with raw-dylib, but with verbatim. + +#![feature(raw_dylib_elf)] +#![allow(incomplete_features)] + +#[cfg_attr(with, link(name = "rawdylibbutforcats", kind = "raw-dylib", modifiers = "+verbatim"))] +#[cfg_attr(without, link(name = "rawdylibbutforcats", modifiers = "+verbatim"))] +unsafe extern "C" { + safe fn meooooooooooooooow(); +} + +fn main() { + meooooooooooooooow(); +} diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs rename to tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.rs rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.rs rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.rs rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.rs rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs rename to tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.stderr b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.rs rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.rs rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.rs rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.rs b/tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.rs rename to tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr b/tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.stderr diff --git a/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.elf.stderr b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.elf.stderr new file mode 100644 index 000000000000..70945ed6fc0b --- /dev/null +++ b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.elf.stderr @@ -0,0 +1,13 @@ +error[E0658]: link kind `raw-dylib` is unstable on ELF platforms + --> $DIR/raw-dylib-windows-only.rs:6:29 + | +LL | #[link(name = "foo", kind = "raw-dylib")] + | ^^^^^^^^^^^ + | + = note: see issue #135694 for more information + = help: add `#![feature(raw_dylib_elf)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.notelf.stderr similarity index 86% rename from tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.notelf.stderr index ede20cb8c3f7..daed15d784a5 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.notelf.stderr @@ -1,5 +1,5 @@ error[E0455]: link kind `raw-dylib` is only supported on Windows targets - --> $DIR/raw-dylib-windows-only.rs:3:29 + --> $DIR/raw-dylib-windows-only.rs:6:29 | LL | #[link(name = "foo", kind = "raw-dylib")] | ^^^^^^^^^^^ diff --git a/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.rs b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.rs new file mode 100644 index 000000000000..935c59b5aaa5 --- /dev/null +++ b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.rs @@ -0,0 +1,9 @@ +//@ revisions: elf notelf +//@ [elf] only-elf +//@ [notelf] ignore-windows +//@ [notelf] ignore-elf +//@ compile-flags: --crate-type lib +#[link(name = "foo", kind = "raw-dylib")] +//[notelf]~^ ERROR: link kind `raw-dylib` is only supported on Windows targets +//[elf]~^^ ERROR: link kind `raw-dylib` is unstable on ELF platforms +extern "C" {} diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.rs b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.rs rename to tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr rename to tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.rs deleted file mode 100644 index 3b982857db8d..000000000000 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ ignore-windows -//@ compile-flags: --crate-type lib -#[link(name = "foo", kind = "raw-dylib")] -//~^ ERROR: link kind `raw-dylib` is only supported on Windows targets -extern "C" {} From 864cca80b02e9daa2c41440f1bf9787083c9f149 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 23 Feb 2025 03:34:33 +0000 Subject: [PATCH 353/991] Print out destructor --- Cargo.lock | 1 + compiler/rustc_lint/Cargo.toml | 1 + compiler/rustc_lint/messages.ftl | 5 + compiler/rustc_lint/src/if_let_rescope.rs | 77 ++++++-- compiler/rustc_middle/src/ty/mod.rs | 1 + .../src/ty/significant_drop_order.rs | 172 +++++++++++++++++ .../src/lint_tail_expr_drop_order.rs | 174 +----------------- .../drop/drop-order-comparisons.e2021.stderr | 90 +++++++++ ...nt-if-let-rescope-gated.edition2021.stderr | 9 + .../lint-if-let-rescope-with-macro.stderr | 9 + tests/ui/drop/lint-if-let-rescope.stderr | 72 ++++++++ 11 files changed, 425 insertions(+), 186 deletions(-) create mode 100644 compiler/rustc_middle/src/ty/significant_drop_order.rs diff --git a/Cargo.lock b/Cargo.lock index fb4cf235c6f4..2227f5f3e993 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3916,6 +3916,7 @@ dependencies = [ "rustc_target", "rustc_trait_selection", "rustc_type_ir", + "smallvec", "tracing", "unicode-security", ] diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index 24e7b40c8a2d..d6014f5006ad 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -24,6 +24,7 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_type_ir = { path = "../rustc_type_ir" } +smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" unicode-security = "0.1.0" # tidy-alphabetical-end diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 679367634276..d51865810b9a 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -333,6 +333,11 @@ lint_identifier_uncommon_codepoints = identifier contains {$codepoints_len -> *[other] {" "}{$identifier_type} } Unicode general security profile +lint_if_let_dtor = {$dtor_kind -> + [dyn] value may invoke a custom destructor because it contains a trait object + *[concrete] value invokes this custom destructor + } + lint_if_let_rescope = `if let` assigns a shorter lifetime since Edition 2024 .label = this value has a significant drop implementation which may observe a major change in drop order and requires your discretion .help = the value is now dropped here in Edition 2024 diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 23f037f3692a..39ea8d8e3246 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -7,13 +7,17 @@ use rustc_errors::{ Applicability, Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic, SuggestionStyle, }; use rustc_hir::{self as hir, HirIdSet}; -use rustc_macros::LintDiagnostic; -use rustc_middle::ty::TyCtxt; +use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::adjustment::Adjust; +use rustc_middle::ty::significant_drop_order::{ + extract_component_with_significant_dtor, ty_dtor_span, +}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint::{FutureIncompatibilityReason, LintId}; use rustc_session::{declare_lint, impl_lint_pass}; -use rustc_span::Span; use rustc_span::edition::Edition; +use rustc_span::{DUMMY_SP, Span}; +use smallvec::SmallVec; use crate::{LateContext, LateLintPass}; @@ -130,6 +134,7 @@ impl IfLetRescope { hir::ExprKind::If(_cond, _conseq, Some(alt)) => alt.span.shrink_to_hi(), _ => return, }; + let mut seen_dyn = false; let mut add_bracket_to_match_head = match_head_needs_bracket(tcx, expr); let mut significant_droppers = vec![]; let mut lifetime_ends = vec![]; @@ -137,6 +142,7 @@ impl IfLetRescope { let mut alt_heads = vec![]; let mut match_heads = vec![]; let mut consequent_heads = vec![]; + let mut destructors = vec![]; let mut first_if_to_lint = None; let mut first_if_to_rewrite = false; let mut empty_alt = false; @@ -160,11 +166,25 @@ impl IfLetRescope { let before_conseq = conseq.span.shrink_to_lo(); let lifetime_end = source_map.end_point(conseq.span); - if let ControlFlow::Break(significant_dropper) = + if let ControlFlow::Break((drop_span, drop_tys)) = (FindSignificantDropper { cx }).check_if_let_scrutinee(init) { + destructors.extend(drop_tys.into_iter().filter_map(|ty| { + if let Some(span) = ty_dtor_span(tcx, ty) { + Some(DestructorLabel { span, dtor_kind: "concrete" }) + } else if matches!(ty.kind(), ty::Dynamic(..)) { + if seen_dyn { + None + } else { + seen_dyn = true; + Some(DestructorLabel { span: DUMMY_SP, dtor_kind: "dyn" }) + } + } else { + None + } + })); first_if_to_lint = first_if_to_lint.or_else(|| Some((span, expr.hir_id))); - significant_droppers.push(significant_dropper); + significant_droppers.push(drop_span); lifetime_ends.push(lifetime_end); if ty_ascription.is_some() || !expr.span.can_be_used_for_suggestions() @@ -227,6 +247,7 @@ impl IfLetRescope { hir_id, span, IfLetRescopeLint { + destructors, significant_droppers, lifetime_ends, rewrite: first_if_to_rewrite.then_some(IfLetRescopeRewrite { @@ -288,6 +309,8 @@ impl<'tcx> LateLintPass<'tcx> for IfLetRescope { #[derive(LintDiagnostic)] #[diag(lint_if_let_rescope)] struct IfLetRescopeLint { + #[subdiagnostic] + destructors: Vec, #[label] significant_droppers: Vec, #[help] @@ -347,6 +370,14 @@ impl Subdiagnostic for IfLetRescopeRewrite { } } +#[derive(Subdiagnostic)] +#[note(lint_if_let_dtor)] +struct DestructorLabel { + #[primary_span] + span: Span, + dtor_kind: &'static str, +} + struct AltHead(Span); struct ConsequentRewrite { @@ -374,7 +405,10 @@ impl<'tcx> FindSignificantDropper<'_, 'tcx> { /// of the scrutinee itself, and also recurses into the expression to find any ref /// exprs (or autoref) which would promote temporaries that would be scoped to the /// end of this `if`. - fn check_if_let_scrutinee(&mut self, init: &'tcx hir::Expr<'tcx>) -> ControlFlow { + fn check_if_let_scrutinee( + &mut self, + init: &'tcx hir::Expr<'tcx>, + ) -> ControlFlow<(Span, SmallVec<[Ty<'tcx>; 4]>)> { self.check_promoted_temp_with_drop(init)?; self.visit_expr(init) } @@ -385,28 +419,35 @@ impl<'tcx> FindSignificantDropper<'_, 'tcx> { /// An expression is a promoted temporary if it has an addr taken (i.e. `&expr` or autoref) /// or is the scrutinee of the `if let`, *and* the expression is not a place /// expr, and it has a significant drop. - fn check_promoted_temp_with_drop(&self, expr: &'tcx hir::Expr<'tcx>) -> ControlFlow { - if !expr.is_place_expr(|base| { + fn check_promoted_temp_with_drop( + &self, + expr: &'tcx hir::Expr<'tcx>, + ) -> ControlFlow<(Span, SmallVec<[Ty<'tcx>; 4]>)> { + if expr.is_place_expr(|base| { self.cx .typeck_results() .adjustments() .get(base.hir_id) .is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_)))) - }) && self - .cx - .typeck_results() - .expr_ty(expr) - .has_significant_drop(self.cx.tcx, self.cx.typing_env()) - { - ControlFlow::Break(expr.span) - } else { - ControlFlow::Continue(()) + }) { + return ControlFlow::Continue(()); } + + let drop_tys = extract_component_with_significant_dtor( + self.cx.tcx, + self.cx.typing_env(), + self.cx.typeck_results().expr_ty(expr), + ); + if drop_tys.is_empty() { + return ControlFlow::Continue(()); + } + + ControlFlow::Break((expr.span, drop_tys)) } } impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { - type Result = ControlFlow; + type Result = ControlFlow<(Span, SmallVec<[Ty<'tcx>; 4]>)>; fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) -> Self::Result { // Blocks introduce temporary terminating scope for all of its diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index eb70a35d3708..d926d6cc02a5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -122,6 +122,7 @@ pub mod normalize_erasing_regions; pub mod pattern; pub mod print; pub mod relate; +pub mod significant_drop_order; pub mod trait_def; pub mod util; pub mod visit; diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs new file mode 100644 index 000000000000..7f0d82d89fed --- /dev/null +++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs @@ -0,0 +1,172 @@ +use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::unord::UnordSet; +use rustc_hir::def_id::DefId; +use rustc_span::Span; +use smallvec::{SmallVec, smallvec}; +use tracing::{debug, instrument}; + +use crate::ty::{self, Ty, TyCtxt}; + +/// An additional filter to exclude well-known types from the ecosystem +/// because their drops are trivial. +/// This returns additional types to check if the drops are delegated to those. +/// A typical example is `hashbrown::HashMap`, whose drop is delegated to `K` and `V`. +fn true_significant_drop_ty<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, +) -> Option; 2]>> { + if let ty::Adt(def, args) = ty.kind() { + let mut did = def.did(); + let mut name_rev = vec![]; + loop { + let key = tcx.def_key(did); + + match key.disambiguated_data.data { + rustc_hir::definitions::DefPathData::CrateRoot => { + name_rev.push(tcx.crate_name(did.krate)) + } + rustc_hir::definitions::DefPathData::TypeNs(symbol) => name_rev.push(symbol), + _ => return None, + } + if let Some(parent) = key.parent { + did = DefId { krate: did.krate, index: parent }; + } else { + break; + } + } + let name_str: Vec<_> = name_rev.iter().rev().map(|x| x.as_str()).collect(); + debug!(?name_str); + match name_str[..] { + // These are the types from Rust core ecosystem + ["syn" | "proc_macro2", ..] + | ["core" | "std", "task", "LocalWaker" | "Waker"] + | ["core" | "std", "task", "wake", "LocalWaker" | "Waker"] => Some(smallvec![]), + // These are important types from Rust ecosystem + ["tracing", "instrument", "Instrumented"] | ["bytes", "Bytes"] => Some(smallvec![]), + ["hashbrown", "raw", "RawTable" | "RawIntoIter"] => { + if let [ty, ..] = &***args + && let Some(ty) = ty.as_type() + { + Some(smallvec![ty]) + } else { + None + } + } + ["hashbrown", "raw", "RawDrain"] => { + if let [_, ty, ..] = &***args + && let Some(ty) = ty.as_type() + { + Some(smallvec![ty]) + } else { + None + } + } + _ => None, + } + } else { + None + } +} + +/// Returns the list of types with a "potentially sigificant" that may be dropped +/// by dropping a value of type `ty`. +#[instrument(level = "trace", skip(tcx, typing_env))] +pub fn extract_component_raw<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, + ty_seen: &mut UnordSet>, +) -> SmallVec<[Ty<'tcx>; 4]> { + // Droppiness does not depend on regions, so let us erase them. + let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + + let tys = tcx.list_significant_drop_tys(typing_env.as_query_input(ty)); + debug!(?ty, "components"); + let mut out_tys = smallvec![]; + for ty in tys { + if let Some(tys) = true_significant_drop_ty(tcx, ty) { + // Some types can be further opened up because the drop is simply delegated + for ty in tys { + if ty_seen.insert(ty) { + out_tys.extend(extract_component_raw(tcx, typing_env, ty, ty_seen)); + } + } + } else { + if ty_seen.insert(ty) { + out_tys.push(ty); + } + } + } + out_tys +} + +#[instrument(level = "trace", skip(tcx, typing_env))] +pub fn extract_component_with_significant_dtor<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, +) -> SmallVec<[Ty<'tcx>; 4]> { + let mut tys = extract_component_raw(tcx, typing_env, ty, &mut Default::default()); + let mut deduplicate = FxHashSet::default(); + tys.retain(|oty| deduplicate.insert(*oty)); + tys.into_iter().collect() +} + +/// Extract the span of the custom destructor of a type +/// especially the span of the `impl Drop` header or its entire block +/// when we are working with current local crate. +#[instrument(level = "trace", skip(tcx))] +pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { + match ty.kind() { + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Error(_) + | ty::Str + | ty::Never + | ty::RawPtr(_, _) + | ty::Ref(_, _, _) + | ty::FnPtr(_, _) + | ty::Tuple(_) + | ty::Dynamic(_, _, _) + | ty::Alias(_, _) + | ty::Bound(_, _) + | ty::Pat(_, _) + | ty::Placeholder(_) + | ty::Infer(_) + | ty::Slice(_) + | ty::Array(_, _) + | ty::UnsafeBinder(_) => None, + + ty::Adt(adt_def, _) => { + let did = adt_def.did(); + let try_local_did_span = |did: DefId| { + if let Some(local) = did.as_local() { + tcx.source_span(local) + } else { + tcx.def_span(did) + } + }; + let dtor = if let Some(dtor) = tcx.adt_destructor(did) { + dtor.did + } else if let Some(dtor) = tcx.adt_async_destructor(did) { + dtor.future + } else { + return Some(try_local_did_span(did)); + }; + let def_key = tcx.def_key(dtor); + let Some(parent_index) = def_key.parent else { return Some(try_local_did_span(dtor)) }; + let parent_did = DefId { index: parent_index, krate: dtor.krate }; + Some(try_local_did_span(parent_did)) + } + ty::Coroutine(did, _) + | ty::CoroutineWitness(did, _) + | ty::CoroutineClosure(did, _) + | ty::Closure(did, _) + | ty::FnDef(did, _) + | ty::Foreign(did) => Some(tcx.def_span(did)), + ty::Param(_) => None, + } +} diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index e3260e45bc52..7d77fffa83fd 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::Subdiagnostic; use rustc_hir::CRATE_HIR_ID; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::MixedBitSet; use rustc_index::{IndexSlice, IndexVec}; use rustc_macros::{LintDiagnostic, Subdiagnostic}; @@ -15,7 +15,10 @@ use rustc_middle::mir::{ self, BasicBlock, Body, ClearCrossCrate, Local, Location, Place, StatementKind, TerminatorKind, dump_mir, }; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::significant_drop_order::{ + extract_component_with_significant_dtor, ty_dtor_span, +}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex}; use rustc_mir_dataflow::{Analysis, MaybeReachable, ResultsCursor}; @@ -23,8 +26,7 @@ use rustc_session::lint::builtin::TAIL_EXPR_DROP_ORDER; use rustc_session::lint::{self}; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_type_ir::data_structures::IndexMap; -use smallvec::{SmallVec, smallvec}; -use tracing::{debug, instrument}; +use tracing::debug; fn place_has_common_prefix<'tcx>(left: &Place<'tcx>, right: &Place<'tcx>) -> bool { left.local == right.local @@ -155,170 +157,6 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> { } } -/// An additional filter to exclude well-known types from the ecosystem -/// because their drops are trivial. -/// This returns additional types to check if the drops are delegated to those. -/// A typical example is `hashbrown::HashMap`, whose drop is delegated to `K` and `V`. -fn true_significant_drop_ty<'tcx>( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, -) -> Option; 2]>> { - if let ty::Adt(def, args) = ty.kind() { - let mut did = def.did(); - let mut name_rev = vec![]; - loop { - let key = tcx.def_key(did); - - match key.disambiguated_data.data { - rustc_hir::definitions::DefPathData::CrateRoot => { - name_rev.push(tcx.crate_name(did.krate)) - } - rustc_hir::definitions::DefPathData::TypeNs(symbol) => name_rev.push(symbol), - _ => return None, - } - if let Some(parent) = key.parent { - did = DefId { krate: did.krate, index: parent }; - } else { - break; - } - } - let name_str: Vec<_> = name_rev.iter().rev().map(|x| x.as_str()).collect(); - debug!(?name_str); - match name_str[..] { - // These are the types from Rust core ecosystem - ["syn" | "proc_macro2", ..] - | ["core" | "std", "task", "LocalWaker" | "Waker"] - | ["core" | "std", "task", "wake", "LocalWaker" | "Waker"] => Some(smallvec![]), - // These are important types from Rust ecosystem - ["tracing", "instrument", "Instrumented"] | ["bytes", "Bytes"] => Some(smallvec![]), - ["hashbrown", "raw", "RawTable" | "RawIntoIter"] => { - if let [ty, ..] = &***args - && let Some(ty) = ty.as_type() - { - Some(smallvec![ty]) - } else { - None - } - } - ["hashbrown", "raw", "RawDrain"] => { - if let [_, ty, ..] = &***args - && let Some(ty) = ty.as_type() - { - Some(smallvec![ty]) - } else { - None - } - } - _ => None, - } - } else { - None - } -} - -/// Returns the list of types with a "potentially sigificant" that may be dropped -/// by dropping a value of type `ty`. -#[instrument(level = "debug", skip(tcx, typing_env))] -fn extract_component_raw<'tcx>( - tcx: TyCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - ty: Ty<'tcx>, - ty_seen: &mut UnordSet>, -) -> SmallVec<[Ty<'tcx>; 4]> { - // Droppiness does not depend on regions, so let us erase them. - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); - - let tys = tcx.list_significant_drop_tys(typing_env.as_query_input(ty)); - debug!(?ty, "components"); - let mut out_tys = smallvec![]; - for ty in tys { - if let Some(tys) = true_significant_drop_ty(tcx, ty) { - // Some types can be further opened up because the drop is simply delegated - for ty in tys { - if ty_seen.insert(ty) { - out_tys.extend(extract_component_raw(tcx, typing_env, ty, ty_seen)); - } - } - } else { - if ty_seen.insert(ty) { - out_tys.push(ty); - } - } - } - out_tys -} - -#[instrument(level = "debug", skip(tcx, typing_env))] -fn extract_component_with_significant_dtor<'tcx>( - tcx: TyCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - ty: Ty<'tcx>, -) -> SmallVec<[Ty<'tcx>; 4]> { - let mut tys = extract_component_raw(tcx, typing_env, ty, &mut Default::default()); - let mut deduplicate = FxHashSet::default(); - tys.retain(|oty| deduplicate.insert(*oty)); - tys.into_iter().collect() -} - -/// Extract the span of the custom destructor of a type -/// especially the span of the `impl Drop` header or its entire block -/// when we are working with current local crate. -#[instrument(level = "debug", skip(tcx))] -fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { - match ty.kind() { - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Error(_) - | ty::Str - | ty::Never - | ty::RawPtr(_, _) - | ty::Ref(_, _, _) - | ty::FnPtr(_, _) - | ty::Tuple(_) - | ty::Dynamic(_, _, _) - | ty::Alias(_, _) - | ty::Bound(_, _) - | ty::Pat(_, _) - | ty::Placeholder(_) - | ty::Infer(_) - | ty::Slice(_) - | ty::Array(_, _) - | ty::UnsafeBinder(_) => None, - - ty::Adt(adt_def, _) => { - let did = adt_def.did(); - let try_local_did_span = |did: DefId| { - if let Some(local) = did.as_local() { - tcx.source_span(local) - } else { - tcx.def_span(did) - } - }; - let dtor = if let Some(dtor) = tcx.adt_destructor(did) { - dtor.did - } else if let Some(dtor) = tcx.adt_async_destructor(did) { - dtor.future - } else { - return Some(try_local_did_span(did)); - }; - let def_key = tcx.def_key(dtor); - let Some(parent_index) = def_key.parent else { return Some(try_local_did_span(dtor)) }; - let parent_did = DefId { index: parent_index, krate: dtor.krate }; - Some(try_local_did_span(parent_did)) - } - ty::Coroutine(did, _) - | ty::CoroutineWitness(did, _) - | ty::CoroutineClosure(did, _) - | ty::Closure(did, _) - | ty::FnDef(did, _) - | ty::Foreign(did) => Some(tcx.def_span(did)), - ty::Param(_) => None, - } -} - /// Check if a moved place at `idx` is a part of a BID. /// The use of this check is that we will consider drops on these /// as a drop of the overall BID and, thus, we can exclude it from the diagnosis. diff --git a/tests/ui/drop/drop-order-comparisons.e2021.stderr b/tests/ui/drop/drop-order-comparisons.e2021.stderr index 158d18f68826..601b0a38412f 100644 --- a/tests/ui/drop/drop-order-comparisons.e2021.stderr +++ b/tests/ui/drop/drop-order-comparisons.e2021.stderr @@ -242,6 +242,15 @@ LL | _ = (if let Ok(_) = e.ok(4).as_ref() { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:127:5 | @@ -267,6 +276,15 @@ LL | _ = (if let Ok(_) = e.err(4).as_ref() {} else { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:145:44 | @@ -291,6 +309,15 @@ LL | if let Ok(_) = e.err(4).as_ref() {} else { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:247:43 | @@ -315,6 +342,15 @@ LL | if let true = e.err(9).is_ok() {} else { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:352:41 | @@ -339,6 +375,15 @@ LL | if let Ok(_v) = e.err(8) {} else { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:355:35 | @@ -363,6 +408,15 @@ LL | if let Ok(_) = e.err(7) {} else { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:358:34 | @@ -387,6 +441,15 @@ LL | if let Ok(_) = e.err(6).as_ref() {} else { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:361:43 | @@ -411,6 +474,15 @@ LL | if let Ok(_v) = e.err(5) {} else { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:365:35 | @@ -435,6 +507,15 @@ LL | if let Ok(_) = e.err(4) {} else { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:368:34 | @@ -459,6 +540,15 @@ LL | if let Ok(_) = e.err(4).as_ref() {} else { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/drop-order-comparisons.rs:571:1 + | +LL | / impl<'b> Drop for LogDrop<'b> { +LL | | fn drop(&mut self) { +LL | | self.0.mark(self.1); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/drop-order-comparisons.rs:404:43 | diff --git a/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr b/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr index 546a5fe0fd04..070ba1c6a4cf 100644 --- a/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr +++ b/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr @@ -8,6 +8,15 @@ LL | if let Some(_value) = Droppy.get() { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope-gated.rs:14:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/lint-if-let-rescope-gated.rs:30:5 | diff --git a/tests/ui/drop/lint-if-let-rescope-with-macro.stderr b/tests/ui/drop/lint-if-let-rescope-with-macro.stderr index 029d5c749293..f1ca0ba57de4 100644 --- a/tests/ui/drop/lint-if-let-rescope-with-macro.stderr +++ b/tests/ui/drop/lint-if-let-rescope-with-macro.stderr @@ -15,6 +15,15 @@ LL | | }; | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope-with-macro.rs:22:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/lint-if-let-rescope-with-macro.rs:12:38 | diff --git a/tests/ui/drop/lint-if-let-rescope.stderr b/tests/ui/drop/lint-if-let-rescope.stderr index b17239976cc0..e95ec8fcea7f 100644 --- a/tests/ui/drop/lint-if-let-rescope.stderr +++ b/tests/ui/drop/lint-if-let-rescope.stderr @@ -8,6 +8,15 @@ LL | if let Some(_value) = droppy().get() { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope.rs:11:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/lint-if-let-rescope.rs:32:5 | @@ -43,6 +52,24 @@ LL | } else if let Some(_value) = droppy().get() { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope.rs:11:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope.rs:11:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/lint-if-let-rescope.rs:42:5 | @@ -75,6 +102,15 @@ LL | } else if let Some(_value) = droppy().get() { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope.rs:11:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/lint-if-let-rescope.rs:54:5 | @@ -101,6 +137,15 @@ LL | if let Some(1) = { if let Some(_value) = Droppy.get() { Some(1) } else | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope.rs:11:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/lint-if-let-rescope.rs:58:69 | @@ -122,6 +167,15 @@ LL | if (if let Some(_value) = droppy().get() { true } else { false }) { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope.rs:11:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/lint-if-let-rescope.rs:72:53 | @@ -143,6 +197,15 @@ LL | } else if (((if let Some(_value) = droppy().get() { true } else { false | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope.rs:11:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/lint-if-let-rescope.rs:78:62 | @@ -164,6 +227,15 @@ LL | while (if let Some(_value) = droppy().get() { false } else { true }) { | = warning: this changes meaning in Rust 2024 = note: for more information, see +note: value invokes this custom destructor + --> $DIR/lint-if-let-rescope.rs:11:1 + | +LL | / impl Drop for Droppy { +LL | | fn drop(&mut self) { +LL | | println!("dropped"); +LL | | } +LL | | } + | |_^ help: the value is now dropped here in Edition 2024 --> $DIR/lint-if-let-rescope.rs:90:57 | From f482460f92e8713f701bb3eefcd6866f9b065d39 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Wed, 26 Feb 2025 16:28:37 +0000 Subject: [PATCH 354/991] Handle asm const similar to inline const --- compiler/rustc_ast_lowering/src/asm.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir/src/intravisit.rs | 2 +- .../src/check/intrinsicck.rs | 34 +++++++++++----- .../src/collect/generics_of.rs | 11 ------ .../rustc_hir_analysis/src/collect/type_of.rs | 34 +--------------- compiler/rustc_hir_pretty/src/lib.rs | 3 +- compiler/rustc_hir_typeck/src/expr.rs | 7 ++-- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 11 +++++- compiler/rustc_mir_build/src/thir/cx/expr.rs | 18 ++++++--- compiler/rustc_resolve/src/def_collector.rs | 39 +++++++++++++++++++ 11 files changed, 95 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index cfd32fc066f4..87af7959a884 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -195,7 +195,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } InlineAsmOperand::Const { anon_const } => hir::InlineAsmOperand::Const { - anon_const: self.lower_anon_const_to_anon_const(anon_const), + anon_const: self.lower_const_block(anon_const), }, InlineAsmOperand::Sym { sym } => { let static_def_id = self diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f0eaec55dbdd..b7d24c745dc9 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3506,7 +3506,7 @@ pub enum InlineAsmOperand<'hir> { out_expr: Option<&'hir Expr<'hir>>, }, Const { - anon_const: &'hir AnonConst, + anon_const: ConstBlock, }, SymFn { expr: &'hir Expr<'hir>, diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index d5fa7ec366b2..e349e23f7dcf 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1447,7 +1447,7 @@ pub fn walk_inline_asm<'v, V: Visitor<'v>>( visit_opt!(visitor, visit_expr, out_expr); } InlineAsmOperand::Const { anon_const, .. } => { - try_visit!(visitor.visit_anon_const(anon_const)); + try_visit!(visitor.visit_inline_const(anon_const)); } InlineAsmOperand::SymFn { expr, .. } => { try_visit!(visitor.visit_expr(expr)); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 511947404506..590ade516ec6 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -1,5 +1,3 @@ -use std::assert_matches::debug_assert_matches; - use rustc_abi::FieldIdx; use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxIndexSet; @@ -21,6 +19,7 @@ pub struct InlineAsmCtxt<'a, 'tcx: 'a> { typing_env: ty::TypingEnv<'tcx>, target_features: &'tcx FxIndexSet, expr_ty: Box) -> Ty<'tcx> + 'a>, + node_ty: Box Ty<'tcx> + 'a>, } enum NonAsmTypeReason<'tcx> { @@ -35,13 +34,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { tcx: TyCtxt<'tcx>, def_id: LocalDefId, typing_env: ty::TypingEnv<'tcx>, - get_operand_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a, + expr_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a, + node_ty: impl Fn(hir::HirId) -> Ty<'tcx> + 'a, ) -> Self { InlineAsmCtxt { tcx, typing_env, target_features: tcx.asm_target_features(def_id), - expr_ty: Box::new(get_operand_ty), + expr_ty: Box::new(expr_ty), + node_ty: Box::new(node_ty), } } @@ -49,6 +50,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { (self.expr_ty)(expr) } + fn node_ty(&self, hir_id: hir::HirId) -> Ty<'tcx> { + (self.node_ty)(hir_id) + } + // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()` fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool { // Type still may have region variables, but `Sized` does not depend @@ -487,12 +492,23 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ); } } - // Typeck has checked that Const operands are integers. hir::InlineAsmOperand::Const { anon_const } => { - debug_assert_matches!( - self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(), - ty::Error(_) | ty::Int(_) | ty::Uint(_) - ); + let ty = self.node_ty(anon_const.hir_id); + match ty.kind() { + ty::Error(_) => {} + _ if ty.is_integral() => {} + _ => { + self.tcx + .dcx() + .struct_span_err(op_sp, "invalid type for `const` operand") + .with_span_label( + self.tcx.def_span(anon_const.def_id), + format!("is {} `{}`", ty.kind().article(), ty), + ) + .with_help("`const` operands must be of an integer type") + .emit(); + } + } } // Typeck has checked that SymFn refers to a function. hir::InlineAsmOperand::SymFn { expr } => { diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 2cdd9a3a9348..af1338e50d00 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -186,17 +186,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { { Some(parent_did) } - // Exclude `GlobalAsm` here which cannot have generics. - Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } => { - anon_const.hir_id == hir_id - } - _ => false, - }) => - { - Some(parent_did) - } Node::TyPat(_) => Some(parent_did), _ => None, } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index d564dc9699a8..6936544838c8 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -8,7 +8,7 @@ use rustc_middle::query::plumbing::CyclePlaceholder; use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span}; @@ -35,13 +35,6 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx let parent_node_id = tcx.parent_hir_id(hir_id); let parent_node = tcx.hir_node(parent_node_id); - let find_const = |&(op, op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == hir_id => { - Some((anon_const, op_sp)) - } - _ => None, - }; - match parent_node { // Anon consts "inside" the type system. Node::ConstArg(&ConstArg { @@ -50,31 +43,6 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx .. }) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span), - // Anon consts outside the type system. - Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm { asm, .. }, .. }) - if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_const) => - { - let ty = tcx.typeck(def_id).node_type(hir_id); - - match ty.kind() { - ty::Error(_) => ty, - ty::Int(_) | ty::Uint(_) => ty, - _ => { - let guar = tcx - .dcx() - .struct_span_err(op_sp, "invalid type for `const` operand") - .with_span_label( - tcx.def_span(anon_const.def_id), - format!("is {} `{}`", ty.kind().article(), ty), - ) - .with_help("`const` operands must be of an integer type") - .emit(); - - Ty::new_error(tcx, guar) - } - } - } Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => { tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 5c7426d76b31..de5fe0479e72 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1414,7 +1414,8 @@ impl<'a> State<'a> { hir::InlineAsmOperand::Const { ref anon_const } => { s.word("const"); s.space(); - s.print_anon_const(anon_const); + // Not using `print_inline_const` to avoid additional `const { ... }` + s.ann.nested(s, Nested::Body(anon_const.body)) } hir::InlineAsmOperand::SymFn { ref expr } => { s.word("sym_fn"); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 4815627a0ce0..50538e9efb1f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3778,13 +3778,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_expr_asm_operand(out_expr, false); } } + hir::InlineAsmOperand::Const { ref anon_const } => { + self.check_expr_const_block(anon_const, Expectation::NoExpectation); + } hir::InlineAsmOperand::SymFn { expr } => { self.check_expr(expr); } - // `AnonConst`s have their own body and is type-checked separately. - // As they don't flow into the type system we don't need them to - // be well-formed. - hir::InlineAsmOperand::Const { .. } => {} hir::InlineAsmOperand::SymStatic { .. } => {} hir::InlineAsmOperand::Label { block } => { let previous_diverges = self.diverges.get(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 63c1c0608274..a017aa0998f1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -110,8 +110,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.erase_regions(ty) } }; - InlineAsmCtxt::new(self.tcx, enclosing_id, self.typing_env(self.param_env), expr_ty) - .check_asm(asm); + let node_ty = |hir_id: HirId| self.typeck_results.borrow().node_type(hir_id); + InlineAsmCtxt::new( + self.tcx, + enclosing_id, + self.typing_env(self.param_env), + expr_ty, + node_ty, + ) + .check_asm(asm); } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 88877d05ffad..7139516702e9 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -730,12 +730,20 @@ impl<'tcx> ThirBuildCx<'tcx> { } } hir::InlineAsmOperand::Const { ref anon_const } => { - let value = - mir::Const::from_unevaluated(tcx, anon_const.def_id.to_def_id()) - .instantiate_identity(); - let span = tcx.def_span(anon_const.def_id); + let ty = self.typeck_results.node_type(anon_const.hir_id); + let did = anon_const.def_id.to_def_id(); + let typeck_root_def_id = tcx.typeck_root_def_id(did); + let parent_args = tcx.erase_regions(GenericArgs::identity_for_item( + tcx, + typeck_root_def_id, + )); + let args = + InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }) + .args; - InlineAsmOperand::Const { value, span } + let uneval = mir::UnevaluatedConst::new(did, args); + let value = mir::Const::Unevaluated(uneval, ty); + InlineAsmOperand::Const { value, span: tcx.def_span(did) } } hir::InlineAsmOperand::SymFn { expr } => { InlineAsmOperand::SymFn { value: self.mirror_expr(expr) } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 75972a71c8e5..9d78c71b76aa 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -459,4 +459,43 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { visit::walk_attribute(self, attr); self.in_attr = orig_in_attr; } + + fn visit_inline_asm(&mut self, asm: &'a InlineAsm) { + let InlineAsm { + asm_macro: _, + template: _, + template_strs: _, + operands, + clobber_abis: _, + options: _, + line_spans: _, + } = asm; + for (op, _span) in operands { + match op { + InlineAsmOperand::In { expr, reg: _ } + | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } + | InlineAsmOperand::InOut { expr, reg: _, late: _ } => { + self.visit_expr(expr); + } + InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} + InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { + self.visit_expr(in_expr); + if let Some(expr) = out_expr { + self.visit_expr(expr); + } + } + InlineAsmOperand::Const { anon_const } => { + let def = self.create_def( + anon_const.id, + kw::Empty, + DefKind::InlineConst, + anon_const.value.span, + ); + self.with_parent(def, |this| visit::walk_anon_const(this, anon_const)); + } + InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym), + InlineAsmOperand::Label { block } => self.visit_block(block), + } + } + } } From 395b0fb4d9c969b5db0ec1a6b9a0b3203cacbed6 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Wed, 26 Feb 2025 17:13:01 +0000 Subject: [PATCH 355/991] Bless tests --- tests/crashes/117877.rs | 13 ------------- tests/ui/asm/const-resolve-error.rs | 10 ++++++++++ tests/ui/asm/const-resolve-error.stderr | 14 ++++++++++++++ tests/ui/asm/fail-const-eval-issue-121099.rs | 4 ++-- tests/ui/asm/fail-const-eval-issue-121099.stderr | 4 ++-- tests/ui/asm/invalid-const-operand.stderr | 2 +- 6 files changed, 29 insertions(+), 18 deletions(-) delete mode 100644 tests/crashes/117877.rs create mode 100644 tests/ui/asm/const-resolve-error.rs create mode 100644 tests/ui/asm/const-resolve-error.stderr diff --git a/tests/crashes/117877.rs b/tests/crashes/117877.rs deleted file mode 100644 index b1effc0cbcb1..000000000000 --- a/tests/crashes/117877.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #117877 -//@ edition:2021 -//@ needs-rustc-debug-assertions -//@ only-x86_64 -#![feature(asm_const)] - -use std::arch::asm; - -async unsafe fn foo<'a>() { - asm!("/* {0} */", const N); -} - -fn main() {} diff --git a/tests/ui/asm/const-resolve-error.rs b/tests/ui/asm/const-resolve-error.rs new file mode 100644 index 000000000000..19c8af0d542e --- /dev/null +++ b/tests/ui/asm/const-resolve-error.rs @@ -0,0 +1,10 @@ +//@ edition:2021 +//@ needs-asm-support + +use std::arch::asm; + +async unsafe fn foo<'a>() { + asm!("/* {0} */", const N); //~ ERROR E0425 +} + +fn main() {} diff --git a/tests/ui/asm/const-resolve-error.stderr b/tests/ui/asm/const-resolve-error.stderr new file mode 100644 index 000000000000..f02a7f0a6b12 --- /dev/null +++ b/tests/ui/asm/const-resolve-error.stderr @@ -0,0 +1,14 @@ +error[E0425]: cannot find value `N` in this scope + --> $DIR/const-resolve-error.rs:7:29 + | +LL | asm!("/* {0} */", const N); + | ^ not found in this scope + | +help: you might be missing a const parameter + | +LL | async unsafe fn foo<'a, const N: /* Type */>() { + | +++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/asm/fail-const-eval-issue-121099.rs b/tests/ui/asm/fail-const-eval-issue-121099.rs index 36d00b1e5d23..c91bbfd1b73f 100644 --- a/tests/ui/asm/fail-const-eval-issue-121099.rs +++ b/tests/ui/asm/fail-const-eval-issue-121099.rs @@ -5,6 +5,6 @@ use std::arch::global_asm; fn main() {} -global_asm!("/* {} */", const 1 << 500); //~ ERROR evaluation of constant value failed [E0080] +global_asm!("/* {} */", const 1 << 500); //~ ERROR E0080 -global_asm!("/* {} */", const 1 / 0); //~ ERROR evaluation of constant value failed [E0080] +global_asm!("/* {} */", const 1 / 0); //~ ERROR E0080 diff --git a/tests/ui/asm/fail-const-eval-issue-121099.stderr b/tests/ui/asm/fail-const-eval-issue-121099.stderr index 5d86c3a5f7bd..eb662dadffb1 100644 --- a/tests/ui/asm/fail-const-eval-issue-121099.stderr +++ b/tests/ui/asm/fail-const-eval-issue-121099.stderr @@ -1,10 +1,10 @@ -error[E0080]: evaluation of constant value failed +error[E0080]: evaluation of `{global_asm#0}::{constant#0}` failed --> $DIR/fail-const-eval-issue-121099.rs:8:31 | LL | global_asm!("/* {} */", const 1 << 500); | ^^^^^^^^ attempt to shift left by `500_i32`, which would overflow -error[E0080]: evaluation of constant value failed +error[E0080]: evaluation of `{global_asm#1}::{constant#0}` failed --> $DIR/fail-const-eval-issue-121099.rs:10:31 | LL | global_asm!("/* {} */", const 1 / 0); diff --git a/tests/ui/asm/invalid-const-operand.stderr b/tests/ui/asm/invalid-const-operand.stderr index 13bb10e84a53..1cedabeef289 100644 --- a/tests/ui/asm/invalid-const-operand.stderr +++ b/tests/ui/asm/invalid-const-operand.stderr @@ -80,7 +80,7 @@ error: invalid type for `const` operand LL | asm!("{}", const &0); | ^^^^^^-- | | - | is a `&i32` + | is a `&{integer}` | = help: `const` operands must be of an integer type From b97310c4491c989e74d42b48483626b988d1f5a6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Feb 2025 17:14:10 +0100 Subject: [PATCH 356/991] Add run-make test for rustdoc `--emit=dep-info` option --- .../output-default.stdout | 2 +- tests/run-make/rustdoc-dep-info/bar.rs | 1 + tests/run-make/rustdoc-dep-info/doc.md | 1 + tests/run-make/rustdoc-dep-info/foo.rs | 1 + tests/run-make/rustdoc-dep-info/lib.rs | 6 ++++++ tests/run-make/rustdoc-dep-info/rmake.rs | 21 +++++++++++++++++++ 6 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/run-make/rustdoc-dep-info/bar.rs create mode 100644 tests/run-make/rustdoc-dep-info/doc.md create mode 100644 tests/run-make/rustdoc-dep-info/foo.rs create mode 100644 tests/run-make/rustdoc-dep-info/lib.rs create mode 100644 tests/run-make/rustdoc-dep-info/rmake.rs diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index c1b246e849ce..01f470f6e162 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -153,7 +153,7 @@ Options: --generate-redirect-map Generate JSON file at the top level instead of generating HTML redirection files - --emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific] + --emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info] Comma separated list of types of output for rustdoc to emit --no-run Compile doctests without running them diff --git a/tests/run-make/rustdoc-dep-info/bar.rs b/tests/run-make/rustdoc-dep-info/bar.rs new file mode 100644 index 000000000000..76b8dcd05c8f --- /dev/null +++ b/tests/run-make/rustdoc-dep-info/bar.rs @@ -0,0 +1 @@ +include!("foo.rs"); diff --git a/tests/run-make/rustdoc-dep-info/doc.md b/tests/run-make/rustdoc-dep-info/doc.md new file mode 100644 index 000000000000..6a4238fc8b61 --- /dev/null +++ b/tests/run-make/rustdoc-dep-info/doc.md @@ -0,0 +1 @@ +blablabla diff --git a/tests/run-make/rustdoc-dep-info/foo.rs b/tests/run-make/rustdoc-dep-info/foo.rs new file mode 100644 index 000000000000..b76b4321d62a --- /dev/null +++ b/tests/run-make/rustdoc-dep-info/foo.rs @@ -0,0 +1 @@ +pub fn foo() {} diff --git a/tests/run-make/rustdoc-dep-info/lib.rs b/tests/run-make/rustdoc-dep-info/lib.rs new file mode 100644 index 000000000000..1f003f79b1f4 --- /dev/null +++ b/tests/run-make/rustdoc-dep-info/lib.rs @@ -0,0 +1,6 @@ +#![crate_name = "foo"] + +#[cfg_attr(doc, doc = include_str!("doc.md"))] +pub struct Bar; + +mod bar; diff --git a/tests/run-make/rustdoc-dep-info/rmake.rs b/tests/run-make/rustdoc-dep-info/rmake.rs new file mode 100644 index 000000000000..6902bfc21ca2 --- /dev/null +++ b/tests/run-make/rustdoc-dep-info/rmake.rs @@ -0,0 +1,21 @@ +// This is a simple smoke test for rustdoc's `--emit dep-info` feature. It prints out +// information about dependencies in a Makefile-compatible format, as a `.d` file. + +use run_make_support::assertion_helpers::assert_contains; +use run_make_support::{path, rfs, rustdoc}; + +fn main() { + // We're only emitting dep info, so we shouldn't be running static analysis to + // figure out that this program is erroneous. + rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info").run(); + + let content = rfs::read_to_string("foo.d"); + assert_contains(&content, "lib.rs:"); + assert_contains(&content, "foo.rs:"); + assert_contains(&content, "bar.rs:"); + assert_contains(&content, "doc.md:"); + + // Now we check that we can provide a file name to the `dep-info` argument. + rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info=bla.d").run(); + assert!(path("bla.d").exists()); +} From b3330f81824b2266de07c647df2c72245f90f5ad Mon Sep 17 00:00:00 2001 From: Boxy Date: Wed, 26 Feb 2025 19:41:53 +0000 Subject: [PATCH 357/991] Remove `ParamEnv::without_caller_bounds` --- compiler/rustc_middle/src/ty/mod.rs | 6 ------ compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index eb70a35d3708..bb4275fbcef6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -991,12 +991,6 @@ impl<'tcx> ParamEnv<'tcx> { ParamEnv { caller_bounds } } - /// Returns this same environment but with no caller bounds. - #[inline] - pub fn without_caller_bounds(self) -> Self { - Self::new(ListWithCachedTypeInfo::empty()) - } - /// Creates a pair of param-env and value for use in queries. pub fn and>>(self, value: T) -> ParamEnvAnd<'tcx, T> { ParamEnvAnd { param_env: self, value } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 436ce3dddd9f..d5e7a9eba139 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1008,7 +1008,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // depend on its particular value in order to work, so we can clear // out the param env and get better caching. debug!("in global"); - obligation.param_env = obligation.param_env.without_caller_bounds(); + obligation.param_env = ty::ParamEnv::empty(); } let stack = self.push_stack(previous_stack, &obligation); From faaba55be14ab477dae8230217dbf8a883123d8c Mon Sep 17 00:00:00 2001 From: David Richey Date: Tue, 4 Feb 2025 13:20:01 -0600 Subject: [PATCH 358/991] Allow rust-project.json to specify sysroot workspace --- .../crates/project-model/src/lib.rs | 1 + .../crates/project-model/src/project_json.rs | 12 +- .../crates/project-model/src/sysroot.rs | 11 +- .../crates/project-model/src/workspace.rs | 172 ++++++++++++------ 4 files changed, 135 insertions(+), 61 deletions(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs index 0c7344746824..d7c00b9179c0 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs @@ -262,6 +262,7 @@ fn parse_cfg(s: &str) -> Result { #[derive(Clone, Debug, PartialEq, Eq)] pub enum RustSourceWorkspaceConfig { CargoMetadata(CargoMetadataConfig), + Json(ProjectJson), Stitched, } diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index 2f9612e3a478..0282a714645b 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -65,6 +65,8 @@ pub struct ProjectJson { pub(crate) sysroot: Option, /// e.g. `path/to/sysroot/lib/rustlib/src/rust/library` pub(crate) sysroot_src: Option, + /// A nested project describing the layout of the sysroot + pub(crate) sysroot_project: Option>, project_root: AbsPathBuf, /// The path to the rust-project.json file. May be None if this /// data was generated by the discoverConfig command. @@ -91,9 +93,16 @@ impl ProjectJson { data: ProjectJsonData, ) -> ProjectJson { let absolutize_on_base = |p| base.absolutize(p); + let sysroot_src = data.sysroot_src.map(absolutize_on_base); + let sysroot_project = + data.sysroot_project.zip(sysroot_src.clone()).map(|(sysroot_data, sysroot_src)| { + Box::new(ProjectJson::new(None, &sysroot_src, *sysroot_data)) + }); + ProjectJson { sysroot: data.sysroot.map(absolutize_on_base), - sysroot_src: data.sysroot_src.map(absolutize_on_base), + sysroot_src, + sysroot_project, project_root: base.to_path_buf(), manifest, runnables: data.runnables.into_iter().map(Runnable::from).collect(), @@ -330,6 +339,7 @@ pub enum RunnableKind { pub struct ProjectJsonData { sysroot: Option, sysroot_src: Option, + sysroot_project: Option>, #[serde(default)] cfg_groups: FxHashMap, crates: Vec, diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs index fb752fe47b37..77332bfa13c1 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs @@ -21,7 +21,7 @@ use stdx::format_to; use toolchain::{probe_for_binary, Tool}; use crate::{ - cargo_workspace::CargoMetadataConfig, utf8_stdout, CargoWorkspace, ManifestPath, + cargo_workspace::CargoMetadataConfig, utf8_stdout, CargoWorkspace, ManifestPath, ProjectJson, RustSourceWorkspaceConfig, }; @@ -36,6 +36,7 @@ pub struct Sysroot { #[derive(Debug, Clone, Eq, PartialEq)] pub enum RustLibSrcWorkspace { Workspace(CargoWorkspace), + Json(ProjectJson), Stitched(Stitched), Empty, } @@ -114,6 +115,7 @@ impl Sysroot { pub fn is_rust_lib_src_empty(&self) -> bool { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().next().is_none(), + RustLibSrcWorkspace::Json(project_json) => project_json.n_crates() == 0, RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.is_empty(), RustLibSrcWorkspace::Empty => true, } @@ -126,6 +128,7 @@ impl Sysroot { pub fn num_packages(&self) -> usize { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().count(), + RustLibSrcWorkspace::Json(project_json) => project_json.n_crates(), RustLibSrcWorkspace::Stitched(c) => c.crates().count(), RustLibSrcWorkspace::Empty => 0, } @@ -252,6 +255,8 @@ impl Sysroot { return Some(loaded); } } + } else if let RustSourceWorkspaceConfig::Json(project_json) = sysroot_source_config { + return Some(RustLibSrcWorkspace::Json(project_json.clone())); } tracing::debug!("Stitching sysroot library: {src_root}"); @@ -308,6 +313,10 @@ impl Sysroot { RustLibSrcWorkspace::Workspace(ws) => { ws.packages().any(|p| ws[p].name == "core") } + RustLibSrcWorkspace::Json(project_json) => project_json + .crates() + .filter_map(|(_, krate)| krate.display_name.clone()) + .any(|name| name.canonical_name().as_str() == "core"), RustLibSrcWorkspace::Stitched(stitched) => stitched.by_name("core").is_some(), RustLibSrcWorkspace::Empty => true, }; diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 16b5bb11afa8..7b964d201bb0 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -69,6 +69,7 @@ pub struct ProjectWorkspace { } #[derive(Clone)] +#[allow(clippy::large_enum_variant)] pub enum ProjectWorkspaceKind { /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. Cargo { @@ -400,20 +401,17 @@ impl ProjectWorkspace { } pub fn load_inline( - project_json: ProjectJson, + mut project_json: ProjectJson, config: &CargoConfig, progress: &dyn Fn(String), ) -> ProjectWorkspace { progress("Discovering sysroot".to_owned()); let mut sysroot = Sysroot::new(project_json.sysroot.clone(), project_json.sysroot_src.clone()); - let loaded_sysroot = sysroot.load_workspace(&RustSourceWorkspaceConfig::Stitched); - if let Some(loaded_sysroot) = loaded_sysroot { - sysroot.set_workspace(loaded_sysroot); - } tracing::info!(workspace = %project_json.manifest_or_root(), src_root = ?sysroot.rust_lib_src_root(), root = ?sysroot.root(), "Using sysroot"); progress("Querying project metadata".to_owned()); + let sysroot_project = project_json.sysroot_project.take(); let query_config = QueryConfig::Rustc(&sysroot, project_json.path().as_ref()); let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env) .unwrap_or_default(); @@ -435,14 +433,31 @@ impl ProjectWorkspace { &config.extra_env, ) }); - thread::Result::Ok((toolchain.join()?, rustc_cfg.join()?, data_layout.join()?)) + let loaded_sysroot = s.spawn(|| { + if let Some(sysroot_project) = sysroot_project { + sysroot.load_workspace(&RustSourceWorkspaceConfig::Json(*sysroot_project)) + } else { + sysroot.load_workspace(&RustSourceWorkspaceConfig::Stitched) + } + }); + + thread::Result::Ok(( + toolchain.join()?, + rustc_cfg.join()?, + data_layout.join()?, + loaded_sysroot.join()?, + )) }); - let (toolchain, rustc_cfg, target_layout) = match join { + let (toolchain, rustc_cfg, target_layout, loaded_sysroot) = match join { Ok(it) => it, Err(e) => std::panic::resume_unwind(e), }; + if let Some(loaded_sysroot) = loaded_sysroot { + sysroot.set_workspace(loaded_sysroot); + } + ProjectWorkspace { kind: ProjectWorkspaceKind::Json(project_json), sysroot, @@ -667,6 +682,14 @@ impl ProjectWorkspace { Some(PackageRoot { is_local: false, include, exclude }) }) .collect(), + RustLibSrcWorkspace::Json(project_json) => project_json + .crates() + .map(|(_, krate)| PackageRoot { + is_local: false, + include: krate.include.clone(), + exclude: krate.exclude.clone(), + }) + .collect(), RustLibSrcWorkspace::Stitched(_) | RustLibSrcWorkspace::Empty => vec![], }; @@ -1490,6 +1513,65 @@ impl SysrootPublicDeps { } } +fn extend_crate_graph_with_sysroot( + crate_graph: &mut CrateGraph, + mut sysroot_crate_graph: CrateGraph, + mut sysroot_proc_macros: ProcMacroPaths, +) -> (SysrootPublicDeps, Option) { + let mut pub_deps = vec![]; + let mut libproc_macro = None; + let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap(); + for (cid, c) in sysroot_crate_graph.iter_mut() { + // uninject `test` flag so `core` keeps working. + Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone()); + // patch the origin + if c.origin.is_local() { + let lang_crate = LangCrateOrigin::from( + c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()), + ); + c.origin = CrateOrigin::Lang(lang_crate); + match lang_crate { + LangCrateOrigin::Test + | LangCrateOrigin::Alloc + | LangCrateOrigin::Core + | LangCrateOrigin::Std => pub_deps.push(( + CrateName::normalize_dashes(&lang_crate.to_string()), + cid, + !matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc), + )), + LangCrateOrigin::ProcMacro => libproc_macro = Some(cid), + LangCrateOrigin::Other => (), + } + } + } + + let mut marker_set = vec![]; + for &(_, cid, _) in pub_deps.iter() { + marker_set.extend(sysroot_crate_graph.transitive_deps(cid)); + } + if let Some(cid) = libproc_macro { + marker_set.extend(sysroot_crate_graph.transitive_deps(cid)); + } + + marker_set.sort(); + marker_set.dedup(); + + // Remove all crates except the ones we are interested in to keep the sysroot graph small. + let removed_mapping = sysroot_crate_graph.remove_crates_except(&marker_set); + let mapping = crate_graph.extend(sysroot_crate_graph, &mut sysroot_proc_macros); + + // Map the id through the removal mapping first, then through the crate graph extension mapping. + pub_deps.iter_mut().for_each(|(_, cid, _)| { + *cid = mapping[&removed_mapping[cid.into_raw().into_u32() as usize].unwrap()] + }); + if let Some(libproc_macro) = &mut libproc_macro { + *libproc_macro = + mapping[&removed_mapping[libproc_macro.into_raw().into_u32() as usize].unwrap()]; + } + + (SysrootPublicDeps { deps: pub_deps }, libproc_macro) +} + fn sysroot_to_crate_graph( crate_graph: &mut CrateGraph, sysroot: &Sysroot, @@ -1499,7 +1581,7 @@ fn sysroot_to_crate_graph( let _p = tracing::info_span!("sysroot_to_crate_graph").entered(); match sysroot.workspace() { RustLibSrcWorkspace::Workspace(cargo) => { - let (mut cg, mut pm) = cargo_to_crate_graph( + let (cg, pm) = cargo_to_crate_graph( load, None, cargo, @@ -1520,58 +1602,30 @@ fn sysroot_to_crate_graph( false, ); - let mut pub_deps = vec![]; - let mut libproc_macro = None; - let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap(); - for (cid, c) in cg.iter_mut() { - // uninject `test` flag so `core` keeps working. - Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone()); - // patch the origin - if c.origin.is_local() { - let lang_crate = LangCrateOrigin::from( - c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()), - ); - c.origin = CrateOrigin::Lang(lang_crate); - match lang_crate { - LangCrateOrigin::Test - | LangCrateOrigin::Alloc - | LangCrateOrigin::Core - | LangCrateOrigin::Std => pub_deps.push(( - CrateName::normalize_dashes(&lang_crate.to_string()), - cid, - !matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc), - )), - LangCrateOrigin::ProcMacro => libproc_macro = Some(cid), - LangCrateOrigin::Other => (), - } - } - } + extend_crate_graph_with_sysroot(crate_graph, cg, pm) + } + RustLibSrcWorkspace::Json(project_json) => { + let (cg, pm) = project_json_to_crate_graph( + rustc_cfg, + load, + project_json, + &Sysroot::empty(), + &FxHashMap::default(), + &CfgOverrides { + global: CfgDiff::new( + vec![ + CfgAtom::Flag(sym::debug_assertions.clone()), + CfgAtom::Flag(sym::miri.clone()), + ], + vec![], + ) + .unwrap(), + ..Default::default() + }, + false, + ); - let mut marker_set = vec![]; - for &(_, cid, _) in pub_deps.iter() { - marker_set.extend(cg.transitive_deps(cid)); - } - if let Some(cid) = libproc_macro { - marker_set.extend(cg.transitive_deps(cid)); - } - - marker_set.sort(); - marker_set.dedup(); - - // Remove all crates except the ones we are interested in to keep the sysroot graph small. - let removed_mapping = cg.remove_crates_except(&marker_set); - let mapping = crate_graph.extend(cg, &mut pm); - - // Map the id through the removal mapping first, then through the crate graph extension mapping. - pub_deps.iter_mut().for_each(|(_, cid, _)| { - *cid = mapping[&removed_mapping[cid.into_raw().into_u32() as usize].unwrap()] - }); - if let Some(libproc_macro) = &mut libproc_macro { - *libproc_macro = mapping - [&removed_mapping[libproc_macro.into_raw().into_u32() as usize].unwrap()]; - } - - (SysrootPublicDeps { deps: pub_deps }, libproc_macro) + extend_crate_graph_with_sysroot(crate_graph, cg, pm) } RustLibSrcWorkspace::Stitched(stitched) => { let cfg_options = Arc::new({ From 5109c0b9e4c2428733313b6287375874693bc54b Mon Sep 17 00:00:00 2001 From: David Richey Date: Thu, 6 Feb 2025 10:21:31 -0600 Subject: [PATCH 359/991] Drop support for stitched sysroot --- .../crates/project-model/src/lib.rs | 1 - .../crates/project-model/src/sysroot.rs | 136 +---- .../crates/project-model/src/tests.rs | 14 - .../crates/project-model/src/workspace.rs | 61 +-- .../test_data/is-proc-macro-project.json | 13 - .../output/rust_project_cfg_groups.txt | 501 +----------------- ...rust_project_hello_world_project_model.txt | 454 +--------------- 7 files changed, 12 insertions(+), 1168 deletions(-) delete mode 100644 src/tools/rust-analyzer/crates/project-model/test_data/is-proc-macro-project.json diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs index d7c00b9179c0..21a993c5a5ed 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs @@ -263,7 +263,6 @@ fn parse_cfg(s: &str) -> Result { pub enum RustSourceWorkspaceConfig { CargoMetadata(CargoMetadataConfig), Json(ProjectJson), - Stitched, } impl Default for RustSourceWorkspaceConfig { diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs index 77332bfa13c1..1e3c5a94786f 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs @@ -4,17 +4,10 @@ //! but we can't process `.rlib` and need source code instead. The source code //! is typically installed with `rustup component add rust-src` command. -use std::{ - env, fs, - ops::{self, Not}, - path::Path, - process::Command, -}; +use std::{env, fs, ops::Not, path::Path, process::Command}; use anyhow::{format_err, Result}; -use base_db::CrateName; use itertools::Itertools; -use la_arena::{Arena, Idx}; use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use rustc_hash::FxHashMap; use stdx::format_to; @@ -37,58 +30,9 @@ pub struct Sysroot { pub enum RustLibSrcWorkspace { Workspace(CargoWorkspace), Json(ProjectJson), - Stitched(Stitched), Empty, } -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct Stitched { - crates: Arena, -} - -impl ops::Index for Stitched { - type Output = RustLibSrcCrateData; - fn index(&self, index: RustLibSrcCrate) -> &RustLibSrcCrateData { - &self.crates[index] - } -} - -impl Stitched { - pub(crate) fn public_deps( - &self, - ) -> impl Iterator + '_ { - // core is added as a dependency before std in order to - // mimic rustcs dependency order - [("core", true), ("alloc", false), ("std", true), ("test", false)].into_iter().filter_map( - move |(name, prelude)| { - Some((CrateName::new(name).unwrap(), self.by_name(name)?, prelude)) - }, - ) - } - - pub(crate) fn proc_macro(&self) -> Option { - self.by_name("proc_macro") - } - - pub(crate) fn crates(&self) -> impl ExactSizeIterator + '_ { - self.crates.iter().map(|(id, _data)| id) - } - - fn by_name(&self, name: &str) -> Option { - let (id, _data) = self.crates.iter().find(|(_id, data)| data.name == name)?; - Some(id) - } -} - -pub(crate) type RustLibSrcCrate = Idx; - -#[derive(Debug, Clone, Eq, PartialEq)] -pub(crate) struct RustLibSrcCrateData { - pub(crate) name: String, - pub(crate) root: ManifestPath, - pub(crate) deps: Vec, -} - impl Sysroot { pub const fn empty() -> Sysroot { Sysroot { @@ -116,7 +60,6 @@ impl Sysroot { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().next().is_none(), RustLibSrcWorkspace::Json(project_json) => project_json.n_crates() == 0, - RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.is_empty(), RustLibSrcWorkspace::Empty => true, } } @@ -129,7 +72,6 @@ impl Sysroot { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().count(), RustLibSrcWorkspace::Json(project_json) => project_json.n_crates(), - RustLibSrcWorkspace::Stitched(c) => c.crates().count(), RustLibSrcWorkspace::Empty => 0, } } @@ -258,51 +200,8 @@ impl Sysroot { } else if let RustSourceWorkspaceConfig::Json(project_json) = sysroot_source_config { return Some(RustLibSrcWorkspace::Json(project_json.clone())); } - tracing::debug!("Stitching sysroot library: {src_root}"); - let mut stitched = Stitched { crates: Arena::default() }; - - for path in SYSROOT_CRATES.trim().lines() { - let name = path.split('/').last().unwrap(); - let root = [format!("{path}/src/lib.rs"), format!("lib{path}/lib.rs")] - .into_iter() - .map(|it| src_root.join(it)) - .filter_map(|it| ManifestPath::try_from(it).ok()) - .find(|it| fs::metadata(it).is_ok()); - - if let Some(root) = root { - stitched.crates.alloc(RustLibSrcCrateData { - name: name.into(), - root, - deps: Vec::new(), - }); - } - } - - if let Some(std) = stitched.by_name("std") { - for dep in STD_DEPS.trim().lines() { - if let Some(dep) = stitched.by_name(dep) { - stitched.crates[std].deps.push(dep) - } - } - } - - if let Some(alloc) = stitched.by_name("alloc") { - for dep in ALLOC_DEPS.trim().lines() { - if let Some(dep) = stitched.by_name(dep) { - stitched.crates[alloc].deps.push(dep) - } - } - } - - if let Some(proc_macro) = stitched.by_name("proc_macro") { - for dep in PROC_MACRO_DEPS.trim().lines() { - if let Some(dep) = stitched.by_name(dep) { - stitched.crates[proc_macro].deps.push(dep) - } - } - } - Some(RustLibSrcWorkspace::Stitched(stitched)) + None } pub fn set_workspace(&mut self, workspace: RustLibSrcWorkspace) { @@ -317,7 +216,6 @@ impl Sysroot { .crates() .filter_map(|(_, krate)| krate.display_name.clone()) .any(|name| name.canonical_name().as_str() == "core"), - RustLibSrcWorkspace::Stitched(stitched) => stitched.by_name("core").is_some(), RustLibSrcWorkspace::Empty => true, }; if !has_core { @@ -493,33 +391,3 @@ fn get_rust_lib_src(sysroot_path: &AbsPath) -> Option { None } } - -const SYSROOT_CRATES: &str = " -alloc -backtrace -core -panic_abort -panic_unwind -proc_macro -profiler_builtins -std -stdarch/crates/std_detect -test -unwind"; - -const ALLOC_DEPS: &str = "core"; - -const STD_DEPS: &str = " -alloc -panic_unwind -panic_abort -core -profiler_builtins -unwind -std_detect -test"; - -// core is required for our builtin derives to work in the proc_macro lib currently -const PROC_MACRO_DEPS: &str = " -std -core"; diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index 54eb0e3478a7..cfc666970bd6 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -1,5 +1,3 @@ -use std::ops::Deref; - use base_db::{CrateGraph, ProcMacroPaths}; use cargo_metadata::Metadata; use cfg::{CfgAtom, CfgDiff}; @@ -225,18 +223,6 @@ fn rust_project_cfg_groups() { check_crate_graph(crate_graph, expect_file!["../test_data/output/rust_project_cfg_groups.txt"]); } -#[test] -fn rust_project_is_proc_macro_has_proc_macro_dep() { - let (crate_graph, _proc_macros) = load_rust_project("is-proc-macro-project.json"); - // Since the project only defines one crate (outside the sysroot crates), - // it should be the one with the biggest Id. - let crate_id = crate_graph.iter().max().unwrap(); - let crate_data = &crate_graph[crate_id]; - // Assert that the project crate with `is_proc_macro` has a dependency - // on the proc_macro sysroot crate. - crate_data.dependencies.iter().find(|&dep| *dep.name.deref() == sym::proc_macro).unwrap(); -} - #[test] fn crate_graph_dedup_identical() { let (mut crate_graph, proc_macros) = load_cargo("regex-metadata.json"); diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 7b964d201bb0..6b6fb5f9ec1f 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -23,7 +23,7 @@ use crate::{ cargo_workspace::{CargoMetadataConfig, DepKind, PackageData, RustLibSource}, env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env}, project_json::{Crate, CrateArrayIdx}, - sysroot::{RustLibSrcCrate, RustLibSrcWorkspace}, + sysroot::RustLibSrcWorkspace, toolchain_info::{rustc_cfg, target_data_layout, target_tuple, version, QueryConfig}, CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath, Package, ProjectJson, ProjectManifest, RustSourceWorkspaceConfig, Sysroot, TargetData, TargetKind, @@ -437,7 +437,9 @@ impl ProjectWorkspace { if let Some(sysroot_project) = sysroot_project { sysroot.load_workspace(&RustSourceWorkspaceConfig::Json(*sysroot_project)) } else { - sysroot.load_workspace(&RustSourceWorkspaceConfig::Stitched) + sysroot.load_workspace(&RustSourceWorkspaceConfig::CargoMetadata( + sysroot_metadata_config(&config.extra_env, &targets), + )) } }); @@ -690,7 +692,7 @@ impl ProjectWorkspace { exclude: krate.exclude.clone(), }) .collect(), - RustLibSrcWorkspace::Stitched(_) | RustLibSrcWorkspace::Empty => vec![], + RustLibSrcWorkspace::Empty => vec![], }; r.push(PackageRoot { @@ -1627,60 +1629,7 @@ fn sysroot_to_crate_graph( extend_crate_graph_with_sysroot(crate_graph, cg, pm) } - RustLibSrcWorkspace::Stitched(stitched) => { - let cfg_options = Arc::new({ - let mut cfg_options = CfgOptions::default(); - cfg_options.extend(rustc_cfg); - cfg_options.insert_atom(sym::debug_assertions.clone()); - cfg_options.insert_atom(sym::miri.clone()); - cfg_options - }); - let sysroot_crates: FxHashMap = stitched - .crates() - .filter_map(|krate| { - let file_id = load(&stitched[krate].root)?; - let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name); - let crate_id = crate_graph.add_crate_root( - file_id, - Edition::CURRENT_FIXME, - Some(display_name), - None, - cfg_options.clone(), - None, - Env::default(), - CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)), - false, - None, - ); - Some((krate, crate_id)) - }) - .collect(); - - for from in stitched.crates() { - for &to in stitched[from].deps.iter() { - let name = CrateName::new(&stitched[to].name).unwrap(); - if let (Some(&from), Some(&to)) = - (sysroot_crates.get(&from), sysroot_crates.get(&to)) - { - add_dep(crate_graph, from, name, to); - } - } - } - - let public_deps = SysrootPublicDeps { - deps: stitched - .public_deps() - .filter_map(|(name, idx, prelude)| { - Some((name, *sysroot_crates.get(&idx)?, prelude)) - }) - .collect::>(), - }; - - let libproc_macro = - stitched.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); - (public_deps, libproc_macro) - } RustLibSrcWorkspace::Empty => (SysrootPublicDeps { deps: vec![] }, None), } } diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/is-proc-macro-project.json b/src/tools/rust-analyzer/crates/project-model/test_data/is-proc-macro-project.json deleted file mode 100644 index 5d500a4729f5..000000000000 --- a/src/tools/rust-analyzer/crates/project-model/test_data/is-proc-macro-project.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "sysroot_src": null, - "crates": [ - { - "display_name": "is_proc_macro", - "root_module": "$ROOT$src/lib.rs", - "edition": "2018", - "deps": [], - "is_workspace_member": true, - "is_proc_macro": true - } - ] -} diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt index 9b4be19c41c8..28ca4eb53487 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt @@ -3,417 +3,6 @@ root_file_id: FileId( 1, ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "alloc", - ), - canonical_name: "alloc", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Alloc, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 1: CrateData { - root_file_id: FileId( - 2, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "core", - ), - canonical_name: "core", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Core, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 2: CrateData { - root_file_id: FileId( - 3, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_abort", - ), - canonical_name: "panic_abort", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 3: CrateData { - root_file_id: FileId( - 4, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_unwind", - ), - canonical_name: "panic_unwind", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 4: CrateData { - root_file_id: FileId( - 5, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "proc_macro", - ), - canonical_name: "proc_macro", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - ProcMacro, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 5: CrateData { - root_file_id: FileId( - 6, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "profiler_builtins", - ), - canonical_name: "profiler_builtins", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 6: CrateData { - root_file_id: FileId( - 7, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std", - ), - canonical_name: "std", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(3), - name: CrateName( - "panic_unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(2), - name: CrateName( - "panic_abort", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(5), - name: CrateName( - "profiler_builtins", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(9), - name: CrateName( - "unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(7), - name: CrateName( - "std_detect", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Std, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 7: CrateData { - root_file_id: FileId( - 8, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std_detect", - ), - canonical_name: "std_detect", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 8: CrateData { - root_file_id: FileId( - 9, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "test", - ), - canonical_name: "test", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Test, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 9: CrateData { - root_file_id: FileId( - 10, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "unwind", - ), - canonical_name: "unwind", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 10: CrateData { - root_file_id: FileId( - 11, - ), edition: Edition2018, version: None, display_name: Some( @@ -438,48 +27,7 @@ env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "proc_macro", - ), - prelude: false, - sysroot: true, - }, - ], + dependencies: [], origin: Local { repo: None, name: Some( @@ -489,9 +37,9 @@ is_proc_macro: false, proc_macro_cwd: None, }, - 11: CrateData { + 1: CrateData { root_file_id: FileId( - 11, + 1, ), edition: Edition2018, version: None, @@ -517,48 +65,7 @@ env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "proc_macro", - ), - prelude: false, - sysroot: true, - }, - ], + dependencies: [], origin: Local { repo: None, name: Some( diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt index 4c8e66e8e968..dde8d3023dc2 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt @@ -3,417 +3,6 @@ root_file_id: FileId( 1, ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "alloc", - ), - canonical_name: "alloc", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Alloc, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 1: CrateData { - root_file_id: FileId( - 2, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "core", - ), - canonical_name: "core", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Core, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 2: CrateData { - root_file_id: FileId( - 3, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_abort", - ), - canonical_name: "panic_abort", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 3: CrateData { - root_file_id: FileId( - 4, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_unwind", - ), - canonical_name: "panic_unwind", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 4: CrateData { - root_file_id: FileId( - 5, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "proc_macro", - ), - canonical_name: "proc_macro", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - ProcMacro, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 5: CrateData { - root_file_id: FileId( - 6, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "profiler_builtins", - ), - canonical_name: "profiler_builtins", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 6: CrateData { - root_file_id: FileId( - 7, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std", - ), - canonical_name: "std", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(3), - name: CrateName( - "panic_unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(2), - name: CrateName( - "panic_abort", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(5), - name: CrateName( - "profiler_builtins", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(9), - name: CrateName( - "unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(7), - name: CrateName( - "std_detect", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Std, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 7: CrateData { - root_file_id: FileId( - 8, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std_detect", - ), - canonical_name: "std_detect", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 8: CrateData { - root_file_id: FileId( - 9, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "test", - ), - canonical_name: "test", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Test, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 9: CrateData { - root_file_id: FileId( - 10, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "unwind", - ), - canonical_name: "unwind", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 10: CrateData { - root_file_id: FileId( - 11, - ), edition: Edition2018, version: None, display_name: Some( @@ -435,48 +24,7 @@ env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "proc_macro", - ), - prelude: false, - sysroot: true, - }, - ], + dependencies: [], origin: Local { repo: None, name: Some( From e28500d28be270396b9e6a5c4219fb02e0a38ecc Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 26 Feb 2025 19:42:37 +0000 Subject: [PATCH 360/991] Re-enable `--generate-link-to-defintion` for tools internal rustdoc --- src/bootstrap/src/core/build_steps/doc.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index aee56fe78e21..8e913f681842 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -987,9 +987,7 @@ macro_rules! tool_doc { cargo.rustdocflag("-Arustdoc::private-intra-doc-links"); cargo.rustdocflag("--enable-index-page"); cargo.rustdocflag("--show-type-layout"); - // FIXME: `--generate-link-to-definition` tries to resolve cfged out code - // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222 - // cargo.rustdocflag("--generate-link-to-definition"); + cargo.rustdocflag("--generate-link-to-definition"); let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target).join("doc"); $(for krate in $crates { From df845c97f3b9b6a0ae278c0a7097af6923fc7bc5 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 26 Feb 2025 22:04:51 +0000 Subject: [PATCH 361/991] Spruce up `AttributeKind` docs - Remove dead link to `rustc_attr` crate. - Add link to `rustc_attr_parsing` crate. - Split up first paragraph so it looks better at crate-level summary --- .../rustc_attr_data_structures/src/attributes.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 9ac8de0227d7..d2d1285b0756 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -138,13 +138,14 @@ impl Deprecation { } } -/// Attributes represent parsed, *built in*, inert attributes. That means, -/// attributes that are not actually ever expanded. -/// For more information on this, see the module docs on the rustc_attr_parsing crate. +/// Represent parsed, *built in*, inert attributes. +/// +/// That means attributes that are not actually ever expanded. +/// For more information on this, see the module docs on the [`rustc_attr_parsing`] crate. /// They're instead used as markers, to guide the compilation process in various way in most every stage of the compiler. /// These are kept around after the AST, into the HIR and further on. /// -/// The word parsed could be a little misleading here, because the parser already parses +/// The word "parsed" could be a little misleading here, because the parser already parses /// attributes early on. However, the result, an [`ast::Attribute`] /// is only parsed at a high level, still containing a token stream in many cases. That is /// because the structure of the contents varies from attribute to attribute. @@ -153,7 +154,9 @@ impl Deprecation { /// the place where `must_use` is checked) little to no extra parsing or validating needs to /// happen. /// -/// For more docs, look in [`rustc_attr`](https://doc.rust-lang.org/stable/nightly-rustc/rustc_attr/index.html) +/// For more docs, look in [`rustc_attr_parsing`]. +/// +/// [`rustc_attr_parsing`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html #[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] pub enum AttributeKind { // tidy-alphabetical-start From e9561289d6835bcb32f2c59aea81b77914e7e669 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 26 Feb 2025 23:36:10 +0100 Subject: [PATCH 362/991] Remove obsolete TODO --- clippy_lints/src/doc/lazy_continuation.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/clippy_lints/src/doc/lazy_continuation.rs b/clippy_lints/src/doc/lazy_continuation.rs index 2577324f23df..8aeb835fe393 100644 --- a/clippy_lints/src/doc/lazy_continuation.rs +++ b/clippy_lints/src/doc/lazy_continuation.rs @@ -16,7 +16,6 @@ fn map_container_to_text(c: &super::Container) -> &'static str { } } -// TODO: Adjust the parameters as necessary pub(super) fn check( cx: &LateContext<'_>, doc: &str, From a8364f3b2ad63c19037bdf060e49ad9ca07e16b6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Dec 2024 16:24:06 +1100 Subject: [PATCH 363/991] In `AssocOp::AssignOp`, use `BinOpKind` instead of `BinOpToken` `AssocOp::AssignOp` contains a `BinOpToken`. `ExprKind::AssignOp` contains a `BinOpKind`. Given that `AssocOp` is basically a cut-down version of `ExprKind`, it makes sense to make `AssocOp` more like `ExprKind`. Especially given that `AssocOp` and `BinOpKind` use semantic operation names (e.g. `Mul`, `Div`), but `BinOpToken` uses syntactic names (e.g. `Star`, `Slash`). This results in more concise code, and removes the need for various conversions. (Note that the removed functions `hirbinop2assignop` and `astbinop2assignop` are semantically identical, because `hir::BinOp` is just a synonum for `ast::BinOp`!) The only downside to this is that it allows the possibility of some nonsensical combinations, such as `AssocOp::AssignOp(BinOpKind::Lt)`. But `ExprKind::AssignOp` already has that problem. The problem can be fixed for both types in the future with some effort, by introducing an `AssignOpKind` type. --- compiler/rustc_ast/src/util/parser.rs | 25 ++++++---- compiler/rustc_parse/src/parser/expr.rs | 16 +------ src/tools/clippy/clippy_utils/src/lib.rs | 1 - src/tools/clippy/clippy_utils/src/sugg.rs | 58 ++--------------------- 4 files changed, 23 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 8f2b7a23c01c..69df9ff93b4f 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -46,8 +46,8 @@ pub enum AssocOp { GreaterEqual, /// `=` Assign, - /// `?=` where ? is one of the BinOpToken - AssignOp(BinOpToken), + /// `?=` where ? is one of the assignable BinOps + AssignOp(BinOpKind), /// `as` As, /// `..` range @@ -71,18 +71,27 @@ impl AssocOp { pub fn from_token(t: &Token) -> Option { use AssocOp::*; match t.kind { - token::BinOpEq(k) => Some(AssignOp(k)), token::Eq => Some(Assign), + token::BinOpEq(BinOpToken::Plus) => Some(AssignOp(BinOpKind::Add)), + token::BinOpEq(BinOpToken::Minus) => Some(AssignOp(BinOpKind::Sub)), + token::BinOpEq(BinOpToken::Star) => Some(AssignOp(BinOpKind::Mul)), + token::BinOpEq(BinOpToken::Slash) => Some(AssignOp(BinOpKind::Div)), + token::BinOpEq(BinOpToken::Percent) => Some(AssignOp(BinOpKind::Rem)), + token::BinOpEq(BinOpToken::Caret) => Some(AssignOp(BinOpKind::BitXor)), + token::BinOpEq(BinOpToken::And) => Some(AssignOp(BinOpKind::BitAnd)), + token::BinOpEq(BinOpToken::Or) => Some(AssignOp(BinOpKind::BitOr)), + token::BinOpEq(BinOpToken::Shl) => Some(AssignOp(BinOpKind::Shl)), + token::BinOpEq(BinOpToken::Shr) => Some(AssignOp(BinOpKind::Shr)), + token::BinOp(BinOpToken::Plus) => Some(Add), + token::BinOp(BinOpToken::Minus) => Some(Subtract), token::BinOp(BinOpToken::Star) => Some(Multiply), token::BinOp(BinOpToken::Slash) => Some(Divide), token::BinOp(BinOpToken::Percent) => Some(Modulus), - token::BinOp(BinOpToken::Plus) => Some(Add), - token::BinOp(BinOpToken::Minus) => Some(Subtract), + token::BinOp(BinOpToken::Caret) => Some(BitXor), + token::BinOp(BinOpToken::And) => Some(BitAnd), + token::BinOp(BinOpToken::Or) => Some(BitOr), token::BinOp(BinOpToken::Shl) => Some(ShiftLeft), token::BinOp(BinOpToken::Shr) => Some(ShiftRight), - token::BinOp(BinOpToken::And) => Some(BitAnd), - token::BinOp(BinOpToken::Caret) => Some(BitXor), - token::BinOp(BinOpToken::Or) => Some(BitOr), token::Lt => Some(Less), token::Le => Some(LessEqual), token::Ge => Some(GreaterEqual), diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b2e58c942806..935e13cedef8 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -313,19 +313,7 @@ impl<'a> Parser<'a> { self.mk_expr(span, binary) } AssocOp::Assign => self.mk_expr(span, ExprKind::Assign(lhs, rhs, cur_op_span)), - AssocOp::AssignOp(k) => { - let aop = match k { - token::Plus => BinOpKind::Add, - token::Minus => BinOpKind::Sub, - token::Star => BinOpKind::Mul, - token::Slash => BinOpKind::Div, - token::Percent => BinOpKind::Rem, - token::Caret => BinOpKind::BitXor, - token::And => BinOpKind::BitAnd, - token::Or => BinOpKind::BitOr, - token::Shl => BinOpKind::Shl, - token::Shr => BinOpKind::Shr, - }; + AssocOp::AssignOp(aop) => { let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(span, aopexpr) } @@ -395,7 +383,7 @@ impl<'a> Parser<'a> { AssocOp::ShiftRight | AssocOp::Greater | AssocOp::GreaterEqual - | AssocOp::AssignOp(token::BinOpToken::Shr), + | AssocOp::AssignOp(BinOpKind::Shr), ), _, ) if self.restrictions.contains(Restrictions::CONST_EXPR) => { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 7fc25e3617d0..f7266ef4d4eb 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -31,7 +31,6 @@ // (Currently there is no way to opt into sysroot crates without `extern crate`.) extern crate rustc_abi; extern crate rustc_ast; -extern crate rustc_ast_pretty; extern crate rustc_attr_parsing; extern crate rustc_const_eval; extern crate rustc_data_structures; diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index d5e0e2e3436e..ff5bcba5adb8 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -5,8 +5,7 @@ use crate::source::{snippet, snippet_opt, snippet_with_applicability, snippet_wi use crate::ty::expr_sig; use crate::{get_parent_expr_for_hir, higher}; use rustc_ast::util::parser::AssocOp; -use rustc_ast::{ast, token}; -use rustc_ast_pretty::pprust::token_kind_to_string; +use rustc_ast::ast; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::{Closure, ExprKind, HirId, MutTy, TyKind}; @@ -158,7 +157,7 @@ impl<'a> Sugg<'a> { Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span)) }, ExprKind::AssignOp(op, lhs, rhs) => { - Sugg::BinOp(hirbinop2assignop(op), get_snippet(lhs.span), get_snippet(rhs.span)) + Sugg::BinOp(AssocOp::AssignOp(op.node), get_snippet(lhs.span), get_snippet(rhs.span)) }, ExprKind::Binary(op, lhs, rhs) => Sugg::BinOp( AssocOp::from_ast_binop(op.node), @@ -245,7 +244,7 @@ impl<'a> Sugg<'a> { snippet(rhs.span), ), ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => Sugg::BinOp( - astbinop2assignop(op), + AssocOp::AssignOp(op.node), snippet(lhs.span), snippet(rhs.span), ), @@ -389,7 +388,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String { }, AssocOp::Assign => format!("{lhs} = {rhs}"), AssocOp::AssignOp(op) => { - format!("{lhs} {}= {rhs}", token_kind_to_string(&token::BinOp(op))) + format!("{lhs} {}= {rhs}", op.as_str()) }, AssocOp::As => format!("{lhs} as {rhs}"), AssocOp::DotDot => format!("{lhs}..{rhs}"), @@ -619,55 +618,6 @@ fn associativity(op: AssocOp) -> Associativity { } } -/// Converts a `hir::BinOp` to the corresponding assigning binary operator. -fn hirbinop2assignop(op: hir::BinOp) -> AssocOp { - use rustc_ast::token::BinOpToken::{And, Caret, Minus, Or, Percent, Plus, Shl, Shr, Slash, Star}; - - AssocOp::AssignOp(match op.node { - hir::BinOpKind::Add => Plus, - hir::BinOpKind::BitAnd => And, - hir::BinOpKind::BitOr => Or, - hir::BinOpKind::BitXor => Caret, - hir::BinOpKind::Div => Slash, - hir::BinOpKind::Mul => Star, - hir::BinOpKind::Rem => Percent, - hir::BinOpKind::Shl => Shl, - hir::BinOpKind::Shr => Shr, - hir::BinOpKind::Sub => Minus, - - hir::BinOpKind::And - | hir::BinOpKind::Eq - | hir::BinOpKind::Ge - | hir::BinOpKind::Gt - | hir::BinOpKind::Le - | hir::BinOpKind::Lt - | hir::BinOpKind::Ne - | hir::BinOpKind::Or => panic!("This operator does not exist"), - }) -} - -/// Converts an `ast::BinOp` to the corresponding assigning binary operator. -fn astbinop2assignop(op: ast::BinOp) -> AssocOp { - use rustc_ast::ast::BinOpKind::{ - Add, And, BitAnd, BitOr, BitXor, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Rem, Shl, Shr, Sub, - }; - use rustc_ast::token::BinOpToken; - - AssocOp::AssignOp(match op.node { - Add => BinOpToken::Plus, - BitAnd => BinOpToken::And, - BitOr => BinOpToken::Or, - BitXor => BinOpToken::Caret, - Div => BinOpToken::Slash, - Mul => BinOpToken::Star, - Rem => BinOpToken::Percent, - Shl => BinOpToken::Shl, - Shr => BinOpToken::Shr, - Sub => BinOpToken::Minus, - And | Eq | Ge | Gt | Le | Lt | Ne | Or => panic!("This operator does not exist"), - }) -} - /// Returns the indentation before `span` if there are nothing but `[ \t]` /// before it on its line. fn indentation(cx: &T, span: Span) -> Option { From ceafbad81fcf71423d4dc7a90fe962bc5895b108 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Dec 2024 18:24:07 +1100 Subject: [PATCH 364/991] Introduce `AssocOp::Binary`. It mirrors `ExprKind::Binary`, and contains a `BinOpKind`. This makes `AssocOp` more like `ExprKind`. Note that the variants removed from `AssocOp` are all named differently to `BinOpToken`, e.g. `Multiply` instead of `Mul`, so that's an inconsistency removed. The commit adds `precedence` and `fixity` methods to `BinOpKind`, and calls them from the corresponding methods in `AssocOp`. This avoids the need to create an `AssocOp` from a `BinOpKind` in a bunch of places, and `AssocOp::from_ast_binop` is removed. `AssocOp::to_ast_binop` is also no longer needed. Overall things are shorter and nicer. --- compiler/rustc_ast/src/ast.rs | 35 +++- compiler/rustc_ast/src/util/parser.rs | 182 ++++-------------- .../rustc_ast_pretty/src/pprust/state/expr.rs | 7 +- compiler/rustc_hir/src/hir.rs | 4 +- compiler/rustc_hir_pretty/src/lib.rs | 7 +- compiler/rustc_middle/src/ty/print/pretty.rs | 5 +- .../rustc_parse/src/parser/diagnostics.rs | 36 ++-- compiler/rustc_parse/src/parser/expr.rs | 61 ++---- .../operators/float_equality_without_abs.rs | 2 +- src/tools/clippy/clippy_utils/src/sugg.rs | 69 +++---- 10 files changed, 152 insertions(+), 256 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 29c1d34a125a..65dd0a34aeca 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -39,7 +39,7 @@ pub use crate::format::*; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter}; use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream}; -use crate::util::parser::{AssocOp, ExprPrecedence}; +use crate::util::parser::{ExprPrecedence, Fixity}; /// A "Label" is an identifier of some point in sources, /// e.g. in the following code: @@ -937,8 +937,37 @@ impl BinOpKind { matches!(self, BinOpKind::And | BinOpKind::Or) } + pub fn precedence(&self) -> ExprPrecedence { + use BinOpKind::*; + match *self { + Mul | Div | Rem => ExprPrecedence::Product, + Add | Sub => ExprPrecedence::Sum, + Shl | Shr => ExprPrecedence::Shift, + BitAnd => ExprPrecedence::BitAnd, + BitXor => ExprPrecedence::BitXor, + BitOr => ExprPrecedence::BitOr, + Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare, + And => ExprPrecedence::LAnd, + Or => ExprPrecedence::LOr, + } + } + + pub fn fixity(&self) -> Fixity { + use BinOpKind::*; + match self { + Eq | Ne | Lt | Le | Gt | Ge => Fixity::None, + Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => { + Fixity::Left + } + } + } + pub fn is_comparison(self) -> bool { - crate::util::parser::AssocOp::from_ast_binop(self).is_comparison() + use BinOpKind::*; + match self { + Eq | Ne | Lt | Le | Gt | Ge => true, + Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false, + } } /// Returns `true` if the binary operator takes its arguments by value. @@ -1332,7 +1361,7 @@ impl Expr { ExprKind::Range(..) => ExprPrecedence::Range, // Binop-like expr kinds, handled by `AssocOp`. - ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence(), + ExprKind::Binary(op, ..) => op.node.precedence(), ExprKind::Cast(..) => ExprPrecedence::Cast, ExprKind::Assign(..) | diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 69df9ff93b4f..e7c26aa30928 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -3,51 +3,15 @@ use rustc_span::kw; use crate::ast::{self, BinOpKind}; use crate::token::{self, BinOpToken, Token}; -/// Associative operator with precedence. -/// -/// This is the enum which specifies operator precedence and fixity to the parser. +/// Associative operator. #[derive(Copy, Clone, PartialEq, Debug)] pub enum AssocOp { - /// `+` - Add, - /// `-` - Subtract, - /// `*` - Multiply, - /// `/` - Divide, - /// `%` - Modulus, - /// `&&` - LAnd, - /// `||` - LOr, - /// `^` - BitXor, - /// `&` - BitAnd, - /// `|` - BitOr, - /// `<<` - ShiftLeft, - /// `>>` - ShiftRight, - /// `==` - Equal, - /// `<` - Less, - /// `<=` - LessEqual, - /// `!=` - NotEqual, - /// `>` - Greater, - /// `>=` - GreaterEqual, - /// `=` - Assign, + /// A binary op. + Binary(BinOpKind), /// `?=` where ? is one of the assignable BinOps AssignOp(BinOpKind), + /// `=` + Assign, /// `as` As, /// `..` range @@ -67,11 +31,21 @@ pub enum Fixity { } impl AssocOp { - /// Creates a new AssocOP from a token + /// Creates a new AssocOp from a token. pub fn from_token(t: &Token) -> Option { use AssocOp::*; match t.kind { token::Eq => Some(Assign), + token::BinOp(BinOpToken::Plus) => Some(Binary(BinOpKind::Add)), + token::BinOp(BinOpToken::Minus) => Some(Binary(BinOpKind::Sub)), + token::BinOp(BinOpToken::Star) => Some(Binary(BinOpKind::Mul)), + token::BinOp(BinOpToken::Slash) => Some(Binary(BinOpKind::Div)), + token::BinOp(BinOpToken::Percent) => Some(Binary(BinOpKind::Rem)), + token::BinOp(BinOpToken::Caret) => Some(Binary(BinOpKind::BitXor)), + token::BinOp(BinOpToken::And) => Some(Binary(BinOpKind::BitAnd)), + token::BinOp(BinOpToken::Or) => Some(Binary(BinOpKind::BitOr)), + token::BinOp(BinOpToken::Shl) => Some(Binary(BinOpKind::Shl)), + token::BinOp(BinOpToken::Shr) => Some(Binary(BinOpKind::Shr)), token::BinOpEq(BinOpToken::Plus) => Some(AssignOp(BinOpKind::Add)), token::BinOpEq(BinOpToken::Minus) => Some(AssignOp(BinOpKind::Sub)), token::BinOpEq(BinOpToken::Star) => Some(AssignOp(BinOpKind::Mul)), @@ -82,74 +56,31 @@ impl AssocOp { token::BinOpEq(BinOpToken::Or) => Some(AssignOp(BinOpKind::BitOr)), token::BinOpEq(BinOpToken::Shl) => Some(AssignOp(BinOpKind::Shl)), token::BinOpEq(BinOpToken::Shr) => Some(AssignOp(BinOpKind::Shr)), - token::BinOp(BinOpToken::Plus) => Some(Add), - token::BinOp(BinOpToken::Minus) => Some(Subtract), - token::BinOp(BinOpToken::Star) => Some(Multiply), - token::BinOp(BinOpToken::Slash) => Some(Divide), - token::BinOp(BinOpToken::Percent) => Some(Modulus), - token::BinOp(BinOpToken::Caret) => Some(BitXor), - token::BinOp(BinOpToken::And) => Some(BitAnd), - token::BinOp(BinOpToken::Or) => Some(BitOr), - token::BinOp(BinOpToken::Shl) => Some(ShiftLeft), - token::BinOp(BinOpToken::Shr) => Some(ShiftRight), - token::Lt => Some(Less), - token::Le => Some(LessEqual), - token::Ge => Some(GreaterEqual), - token::Gt => Some(Greater), - token::EqEq => Some(Equal), - token::Ne => Some(NotEqual), - token::AndAnd => Some(LAnd), - token::OrOr => Some(LOr), + token::Lt => Some(Binary(BinOpKind::Lt)), + token::Le => Some(Binary(BinOpKind::Le)), + token::Ge => Some(Binary(BinOpKind::Ge)), + token::Gt => Some(Binary(BinOpKind::Gt)), + token::EqEq => Some(Binary(BinOpKind::Eq)), + token::Ne => Some(Binary(BinOpKind::Ne)), + token::AndAnd => Some(Binary(BinOpKind::And)), + token::OrOr => Some(Binary(BinOpKind::Or)), token::DotDot => Some(DotDot), token::DotDotEq => Some(DotDotEq), // DotDotDot is no longer supported, but we need some way to display the error token::DotDotDot => Some(DotDotEq), // `<-` should probably be `< -` - token::LArrow => Some(Less), + token::LArrow => Some(Binary(BinOpKind::Lt)), _ if t.is_keyword(kw::As) => Some(As), _ => None, } } - /// Creates a new AssocOp from ast::BinOpKind. - pub fn from_ast_binop(op: BinOpKind) -> Self { - use AssocOp::*; - match op { - BinOpKind::Lt => Less, - BinOpKind::Gt => Greater, - BinOpKind::Le => LessEqual, - BinOpKind::Ge => GreaterEqual, - BinOpKind::Eq => Equal, - BinOpKind::Ne => NotEqual, - BinOpKind::Mul => Multiply, - BinOpKind::Div => Divide, - BinOpKind::Rem => Modulus, - BinOpKind::Add => Add, - BinOpKind::Sub => Subtract, - BinOpKind::Shl => ShiftLeft, - BinOpKind::Shr => ShiftRight, - BinOpKind::BitAnd => BitAnd, - BinOpKind::BitXor => BitXor, - BinOpKind::BitOr => BitOr, - BinOpKind::And => LAnd, - BinOpKind::Or => LOr, - } - } - /// Gets the precedence of this operator pub fn precedence(&self) -> ExprPrecedence { use AssocOp::*; match *self { As => ExprPrecedence::Cast, - Multiply | Divide | Modulus => ExprPrecedence::Product, - Add | Subtract => ExprPrecedence::Sum, - ShiftLeft | ShiftRight => ExprPrecedence::Shift, - BitAnd => ExprPrecedence::BitAnd, - BitXor => ExprPrecedence::BitXor, - BitOr => ExprPrecedence::BitOr, - Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => ExprPrecedence::Compare, - LAnd => ExprPrecedence::LAnd, - LOr => ExprPrecedence::LOr, + Binary(bin_op) => bin_op.precedence(), DotDot | DotDotEq => ExprPrecedence::Range, Assign | AssignOp(_) => ExprPrecedence::Assign, } @@ -161,22 +92,17 @@ impl AssocOp { // NOTE: it is a bug to have an operators that has same precedence but different fixities! match *self { Assign | AssignOp(_) => Fixity::Right, - As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd - | BitXor | BitOr | LAnd | LOr => Fixity::Left, - Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | DotDot | DotDotEq => { - Fixity::None - } + Binary(binop) => binop.fixity(), + As => Fixity::Left, + DotDot | DotDotEq => Fixity::None, } } pub fn is_comparison(&self) -> bool { use AssocOp::*; match *self { - Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true, - Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract - | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | DotDotEq => { - false - } + Binary(binop) => binop.is_comparison(), + Assign | AssignOp(_) | As | DotDot | DotDotEq => false, } } @@ -184,34 +110,7 @@ impl AssocOp { use AssocOp::*; match *self { Assign | AssignOp(_) => true, - Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply - | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor - | BitOr | LAnd | LOr | DotDot | DotDotEq => false, - } - } - - pub fn to_ast_binop(&self) -> Option { - use AssocOp::*; - match *self { - Less => Some(BinOpKind::Lt), - Greater => Some(BinOpKind::Gt), - LessEqual => Some(BinOpKind::Le), - GreaterEqual => Some(BinOpKind::Ge), - Equal => Some(BinOpKind::Eq), - NotEqual => Some(BinOpKind::Ne), - Multiply => Some(BinOpKind::Mul), - Divide => Some(BinOpKind::Div), - Modulus => Some(BinOpKind::Rem), - Add => Some(BinOpKind::Add), - Subtract => Some(BinOpKind::Sub), - ShiftLeft => Some(BinOpKind::Shl), - ShiftRight => Some(BinOpKind::Shr), - BitAnd => Some(BinOpKind::BitAnd), - BitXor => Some(BinOpKind::BitXor), - BitOr => Some(BinOpKind::BitOr), - LAnd => Some(BinOpKind::And), - LOr => Some(BinOpKind::Or), - Assign | AssignOp(_) | As | DotDot | DotDotEq => None, + As | Binary(_) | DotDot | DotDotEq => false, } } @@ -221,16 +120,19 @@ impl AssocOp { /// parentheses while having a high degree of confidence on the correctness of the suggestion. pub fn can_continue_expr_unambiguously(&self) -> bool { use AssocOp::*; + use BinOpKind::*; matches!( self, - BitXor | // `{ 42 } ^ 3` Assign | // `{ 42 } = { 42 }` - Divide | // `{ 42 } / 42` - Modulus | // `{ 42 } % 2` - ShiftRight | // `{ 42 } >> 2` - LessEqual | // `{ 42 } <= 3` - Greater | // `{ 42 } > 3` - GreaterEqual | // `{ 42 } >= 3` + Binary( + BitXor | // `{ 42 } ^ 3` + Div | // `{ 42 } / 42` + Rem | // `{ 42 } % 2` + Shr | // `{ 42 } >> 2` + Le | // `{ 42 } <= 3` + Gt | // `{ 42 } > 3` + Ge // `{ 42 } >= 3` + ) | AssignOp(_) | // `{ 42 } +=` // Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect // NotEqual | // `{ 42 } != { 42 } struct literals parser recovery. diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 4b1374ceef31..496323a35b8d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -5,7 +5,7 @@ use itertools::{Itertools, Position}; use rustc_ast::ptr::P; use rustc_ast::util::classify; use rustc_ast::util::literal::escape_byte_str_symbol; -use rustc_ast::util::parser::{self, AssocOp, ExprPrecedence, Fixity}; +use rustc_ast::util::parser::{self, ExprPrecedence, Fixity}; use rustc_ast::{ self as ast, BlockCheckMode, FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount, FormatDebugHex, FormatSign, FormatTrait, token, @@ -279,12 +279,11 @@ impl<'a> State<'a> { rhs: &ast::Expr, fixup: FixupContext, ) { - let assoc_op = AssocOp::from_ast_binop(op.node); - let binop_prec = assoc_op.precedence(); + let binop_prec = op.node.precedence(); let left_prec = lhs.precedence(); let right_prec = rhs.precedence(); - let (mut left_needs_paren, right_needs_paren) = match assoc_op.fixity() { + let (mut left_needs_paren, right_needs_paren) = match op.node.fixity() { Fixity::Left => (left_prec < binop_prec, right_prec <= binop_prec), Fixity::Right => (left_prec <= binop_prec, right_prec < binop_prec), Fixity::None => (left_prec <= binop_prec, right_prec <= binop_prec), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f0eaec55dbdd..3c75bc588a13 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4,7 +4,7 @@ use std::fmt; use rustc_abi::ExternAbi; use rustc_ast::attr::AttributeExt; use rustc_ast::token::CommentKind; -use rustc_ast::util::parser::{AssocOp, ExprPrecedence}; +use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::{ self as ast, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitIntType, LitKind, TraitObjectSyntax, UintTy, UnsafeBinderCastKind, @@ -2124,7 +2124,7 @@ impl Expr<'_> { | ExprKind::Become(..) => ExprPrecedence::Jump, // Binop-like expr kinds, handled by `AssocOp`. - ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence(), + ExprKind::Binary(op, ..) => op.node.precedence(), ExprKind::Cast(..) => ExprPrecedence::Cast, ExprKind::Assign(..) | diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 5c7426d76b31..b3377b487694 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -10,7 +10,7 @@ use std::cell::Cell; use std::vec; use rustc_abi::ExternAbi; -use rustc_ast::util::parser::{self, AssocOp, ExprPrecedence, Fixity}; +use rustc_ast::util::parser::{self, ExprPrecedence, Fixity}; use rustc_ast::{AttrStyle, DUMMY_NODE_ID, DelimArgs}; use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; @@ -1296,12 +1296,11 @@ impl<'a> State<'a> { } fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) { - let assoc_op = AssocOp::from_ast_binop(op.node); - let binop_prec = assoc_op.precedence(); + let binop_prec = op.node.precedence(); let left_prec = lhs.precedence(); let right_prec = rhs.precedence(); - let (mut left_needs_paren, right_needs_paren) = match assoc_op.fixity() { + let (mut left_needs_paren, right_needs_paren) = match op.node.fixity() { Fixity::Left => (left_prec < binop_prec, right_prec <= binop_prec), Fixity::Right => (left_prec <= binop_prec, right_prec < binop_prec), Fixity::None => (left_prec <= binop_prec, right_prec <= binop_prec), diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index ed0839f47e69..4a4e4a8c33d8 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1516,10 +1516,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::ExprKind::Binop(op) => { let (_, _, c1, c2) = expr.binop_args(); - let precedence = |binop: crate::mir::BinOp| { - use rustc_ast::util::parser::AssocOp; - AssocOp::from_ast_binop(binop.to_hir_binop()).precedence() - }; + let precedence = |binop: crate::mir::BinOp| binop.to_hir_binop().precedence(); let op_precedence = precedence(op); let formatted_op = op.to_hir_binop().as_str(); let (lhs_parenthesized, rhs_parenthesized) = match (c1.kind(), c2.kind()) { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 67abc2d53940..b35a57ae4929 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1350,13 +1350,13 @@ impl<'a> Parser<'a> { } return match (op.node, &outer_op.node) { // `x == y == z` - (BinOpKind::Eq, AssocOp::Equal) | + (BinOpKind::Eq, AssocOp::Binary(BinOpKind::Eq)) | // `x < y < z` and friends. - (BinOpKind::Lt, AssocOp::Less | AssocOp::LessEqual) | - (BinOpKind::Le, AssocOp::LessEqual | AssocOp::Less) | + (BinOpKind::Lt, AssocOp::Binary(BinOpKind::Lt | BinOpKind::Le)) | + (BinOpKind::Le, AssocOp::Binary(BinOpKind::Lt | BinOpKind::Le)) | // `x > y > z` and friends. - (BinOpKind::Gt, AssocOp::Greater | AssocOp::GreaterEqual) | - (BinOpKind::Ge, AssocOp::GreaterEqual | AssocOp::Greater) => { + (BinOpKind::Gt, AssocOp::Binary(BinOpKind::Gt | BinOpKind::Ge)) | + (BinOpKind::Ge, AssocOp::Binary(BinOpKind::Gt | BinOpKind::Ge)) => { let expr_to_str = |e: &Expr| { self.span_to_snippet(e.span) .unwrap_or_else(|_| pprust::expr_to_string(e)) @@ -1368,7 +1368,10 @@ impl<'a> Parser<'a> { false // Keep the current parse behavior, where the AST is `(x < y) < z`. } // `x == y < z` - (BinOpKind::Eq, AssocOp::Less | AssocOp::LessEqual | AssocOp::Greater | AssocOp::GreaterEqual) => { + ( + BinOpKind::Eq, + AssocOp::Binary(BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge) + ) => { // Consume `z`/outer-op-rhs. let snapshot = self.create_snapshot_for_diagnostic(); match self.parse_expr() { @@ -1389,7 +1392,10 @@ impl<'a> Parser<'a> { } } // `x > y == z` - (BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge, AssocOp::Equal) => { + ( + BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge, + AssocOp::Binary(BinOpKind::Eq) + ) => { let snapshot = self.create_snapshot_for_diagnostic(); // At this point it is always valid to enclose the lhs in parentheses, no // further checks are necessary. @@ -1457,10 +1463,10 @@ impl<'a> Parser<'a> { // Include `<` to provide this recommendation even in a case like // `Foo>>` - if op.node == BinOpKind::Lt && outer_op.node == AssocOp::Less - || outer_op.node == AssocOp::Greater + if op.node == BinOpKind::Lt && outer_op.node == AssocOp::Binary(BinOpKind::Lt) + || outer_op.node == AssocOp::Binary(BinOpKind::Gt) { - if outer_op.node == AssocOp::Less { + if outer_op.node == AssocOp::Binary(BinOpKind::Lt) { let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); // So far we have parsed `foo Parser<'a> { ) -> PResult<'a, GenericArg> { let is_op_or_dot = AssocOp::from_token(&self.token) .and_then(|op| { - if let AssocOp::Greater - | AssocOp::Less - | AssocOp::ShiftRight - | AssocOp::GreaterEqual + if let AssocOp::Binary( + BinOpKind::Gt + | BinOpKind::Lt + | BinOpKind::Shr + | BinOpKind::Ge + ) // Don't recover from `foo::`, because this could be an attempt to // assign a value to a defaulted generic parameter. | AssocOp::Assign diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 935e13cedef8..00a5f2fa28fb 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -188,17 +188,12 @@ impl<'a> Parser<'a> { } // Look for JS' `===` and `!==` and recover - if (op.node == AssocOp::Equal || op.node == AssocOp::NotEqual) + if let AssocOp::Binary(bop @ BinOpKind::Eq | bop @ BinOpKind::Ne) = op.node && self.token == token::Eq && self.prev_token.span.hi() == self.token.span.lo() { let sp = op.span.to(self.token.span); - let sugg = match op.node { - AssocOp::Equal => "==", - AssocOp::NotEqual => "!=", - _ => unreachable!(), - } - .into(); + let sugg = bop.as_str().into(); let invalid = format!("{sugg}="); self.dcx().emit_err(errors::InvalidComparisonOperator { span: sp, @@ -213,7 +208,7 @@ impl<'a> Parser<'a> { } // Look for PHP's `<>` and recover - if op.node == AssocOp::Less + if op.node == AssocOp::Binary(BinOpKind::Lt) && self.token == token::Gt && self.prev_token.span.hi() == self.token.span.lo() { @@ -231,7 +226,7 @@ impl<'a> Parser<'a> { } // Look for C++'s `<=>` and recover - if op.node == AssocOp::LessEqual + if op.node == AssocOp::Binary(BinOpKind::Le) && self.token == token::Gt && self.prev_token.span.hi() == self.token.span.lo() { @@ -290,25 +285,7 @@ impl<'a> Parser<'a> { let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span); lhs = match op { - AssocOp::Add - | AssocOp::Subtract - | AssocOp::Multiply - | AssocOp::Divide - | AssocOp::Modulus - | AssocOp::LAnd - | AssocOp::LOr - | AssocOp::BitXor - | AssocOp::BitAnd - | AssocOp::BitOr - | AssocOp::ShiftLeft - | AssocOp::ShiftRight - | AssocOp::Equal - | AssocOp::Less - | AssocOp::LessEqual - | AssocOp::NotEqual - | AssocOp::Greater - | AssocOp::GreaterEqual => { - let ast_op = op.to_ast_binop().unwrap(); + AssocOp::Binary(ast_op) => { let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs); self.mk_expr(span, binary) } @@ -335,13 +312,14 @@ impl<'a> Parser<'a> { // An exhaustive check is done in the following block, but these are checked first // because they *are* ambiguous but also reasonable looking incorrect syntax, so we // want to keep their span info to improve diagnostics in these cases in a later stage. - (true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3` - (true, Some(AssocOp::Subtract)) | // `{ 42 } -5` - (true, Some(AssocOp::Add)) | // `{ 42 } + 42` (unary plus) - (true, Some(AssocOp::LAnd)) | // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }` - (true, Some(AssocOp::LOr)) | // `{ 42 } || 42` ("logical or" or closure) - (true, Some(AssocOp::BitOr)) // `{ 42 } | 42` or `{ 42 } |x| 42` - => { + (true, Some(AssocOp::Binary( + BinOpKind::Mul | // `{ 42 } *foo = bar;` or `{ 42 } * 3` + BinOpKind::Sub | // `{ 42 } -5` + BinOpKind::Add | // `{ 42 } + 42` (unary plus) + BinOpKind::And | // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }` + BinOpKind::Or | // `{ 42 } || 42` ("logical or" or closure) + BinOpKind::BitOr // `{ 42 } | 42` or `{ 42 } |x| 42` + ))) => { // These cases are ambiguous and can't be identified in the parser alone. // // Bitwise AND is left out because guessing intent is hard. We can make @@ -380,21 +358,20 @@ impl<'a> Parser<'a> { // When parsing const expressions, stop parsing when encountering `>`. ( Some( - AssocOp::ShiftRight - | AssocOp::Greater - | AssocOp::GreaterEqual + AssocOp::Binary(BinOpKind::Shr | BinOpKind::Gt | BinOpKind::Ge) | AssocOp::AssignOp(BinOpKind::Shr), ), _, ) if self.restrictions.contains(Restrictions::CONST_EXPR) => { return None; } - // When recovering patterns as expressions, stop parsing when encountering an assignment `=`, an alternative `|`, or a range `..`. + // When recovering patterns as expressions, stop parsing when encountering an + // assignment `=`, an alternative `|`, or a range `..`. ( Some( AssocOp::Assign | AssocOp::AssignOp(_) - | AssocOp::BitOr + | AssocOp::Binary(BinOpKind::BitOr) | AssocOp::DotDot | AssocOp::DotDotEq, ), @@ -411,7 +388,7 @@ impl<'a> Parser<'a> { incorrect: "and".into(), sub: errors::InvalidLogicalOperatorSub::Conjunction(self.token.span), }); - (AssocOp::LAnd, span) + (AssocOp::Binary(BinOpKind::And), span) } (None, Some((Ident { name: sym::or, span }, IdentIsRaw::No))) if self.may_recover() => { self.dcx().emit_err(errors::InvalidLogicalOperator { @@ -419,7 +396,7 @@ impl<'a> Parser<'a> { incorrect: "or".into(), sub: errors::InvalidLogicalOperatorSub::Disjunction(self.token.span), }); - (AssocOp::LOr, span) + (AssocOp::Binary(BinOpKind::Or), span) } _ => return None, }; diff --git a/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs b/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs index 34f7dbea84e4..74e0a6333db0 100644 --- a/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs +++ b/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs @@ -50,7 +50,7 @@ pub(crate) fn check<'tcx>( // format the suggestion let suggestion = format!( "{}.abs()", - sugg::make_assoc(AssocOp::Subtract, &sug_l, &sug_r).maybe_par() + sugg::make_assoc(AssocOp::Binary(BinOpKind::Sub), &sug_l, &sug_r).maybe_par() ); // spans the lint span_lint_and_then( diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index ff5bcba5adb8..6e16778b343d 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -160,7 +160,7 @@ impl<'a> Sugg<'a> { Sugg::BinOp(AssocOp::AssignOp(op.node), get_snippet(lhs.span), get_snippet(rhs.span)) }, ExprKind::Binary(op, lhs, rhs) => Sugg::BinOp( - AssocOp::from_ast_binop(op.node), + AssocOp::Binary(op.node), get_snippet(lhs.span), get_snippet(rhs.span), ), @@ -249,7 +249,7 @@ impl<'a> Sugg<'a> { snippet(rhs.span), ), ast::ExprKind::Binary(op, ref lhs, ref rhs) => Sugg::BinOp( - AssocOp::from_ast_binop(op.node), + AssocOp::Binary(op.node), snippet(lhs.span), snippet(rhs.span), ), @@ -366,30 +366,9 @@ impl<'a> Sugg<'a> { /// Generates a string from the operator and both sides. fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String { match op { - AssocOp::Add - | AssocOp::Subtract - | AssocOp::Multiply - | AssocOp::Divide - | AssocOp::Modulus - | AssocOp::LAnd - | AssocOp::LOr - | AssocOp::BitXor - | AssocOp::BitAnd - | AssocOp::BitOr - | AssocOp::ShiftLeft - | AssocOp::ShiftRight - | AssocOp::Equal - | AssocOp::Less - | AssocOp::LessEqual - | AssocOp::NotEqual - | AssocOp::Greater - | AssocOp::GreaterEqual => { - format!("{lhs} {} {rhs}", op.to_ast_binop().expect("Those are AST ops").as_str()) - }, + AssocOp::Binary(op) => format!("{lhs} {} {rhs}", op.as_str()), AssocOp::Assign => format!("{lhs} = {rhs}"), - AssocOp::AssignOp(op) => { - format!("{lhs} {}= {rhs}", op.as_str()) - }, + AssocOp::AssignOp(op) => format!("{lhs} {}= {rhs}", op.as_str()), AssocOp::As => format!("{lhs} as {rhs}"), AssocOp::DotDot => format!("{lhs}..{rhs}"), AssocOp::DotDotEq => format!("{lhs}..={rhs}"), @@ -476,16 +455,17 @@ impl Neg for Sugg<'_> { impl<'a> Not for Sugg<'a> { type Output = Sugg<'a>; fn not(self) -> Sugg<'a> { - use AssocOp::{Equal, Greater, GreaterEqual, Less, LessEqual, NotEqual}; + use AssocOp::Binary; + use ast::BinOpKind::{Eq, Gt, Ge, Lt, Le, Ne}; if let Sugg::BinOp(op, lhs, rhs) = self { let to_op = match op { - Equal => NotEqual, - NotEqual => Equal, - Less => GreaterEqual, - GreaterEqual => Less, - Greater => LessEqual, - LessEqual => Greater, + Binary(Eq) => Binary(Ne), + Binary(Ne) => Binary(Eq), + Binary(Lt) => Binary(Ge), + Binary(Ge) => Binary(Lt), + Binary(Gt) => Binary(Le), + Binary(Le) => Binary(Gt), _ => return make_unop("!", Sugg::BinOp(op, lhs, rhs)), }; Sugg::BinOp(to_op, lhs, rhs) @@ -537,7 +517,7 @@ pub fn make_unop(op: &str, expr: Sugg<'_>) -> Sugg<'static> { pub fn make_assoc(op: AssocOp, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static> { /// Returns `true` if the operator is a shift operator `<<` or `>>`. fn is_shift(op: AssocOp) -> bool { - matches!(op, AssocOp::ShiftLeft | AssocOp::ShiftRight) + matches!(op, AssocOp::Binary(ast::BinOpKind::Shl | ast::BinOpKind::Shr)) } /// Returns `true` if the operator is an arithmetic operator @@ -545,7 +525,13 @@ pub fn make_assoc(op: AssocOp, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static> fn is_arith(op: AssocOp) -> bool { matches!( op, - AssocOp::Add | AssocOp::Subtract | AssocOp::Multiply | AssocOp::Divide | AssocOp::Modulus + AssocOp::Binary( + ast::BinOpKind::Add + | ast::BinOpKind::Sub + | ast::BinOpKind::Mul + | ast::BinOpKind::Div + | ast::BinOpKind::Rem + ) ) } @@ -577,9 +563,9 @@ pub fn make_assoc(op: AssocOp, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static> Sugg::BinOp(op, lhs.into(), rhs.into()) } -/// Convenience wrapper around `make_assoc` and `AssocOp::from_ast_binop`. +/// Convenience wrapper around `make_assoc` and `AssocOp::Binary`. pub fn make_binop(op: ast::BinOpKind, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static> { - make_assoc(AssocOp::from_ast_binop(op), lhs, rhs) + make_assoc(AssocOp::Binary(op), lhs, rhs) } #[derive(PartialEq, Eq, Clone, Copy)] @@ -604,16 +590,15 @@ enum Associativity { /// associative. #[must_use] fn associativity(op: AssocOp) -> Associativity { - use rustc_ast::util::parser::AssocOp::{ - Add, As, Assign, AssignOp, BitAnd, BitOr, BitXor, Divide, DotDot, DotDotEq, Equal, Greater, GreaterEqual, LAnd, - LOr, Less, LessEqual, Modulus, Multiply, NotEqual, ShiftLeft, ShiftRight, Subtract, + use rustc_ast::util::parser::AssocOp::{As, Assign, AssignOp, Binary, DotDot, DotDotEq}; + use ast::BinOpKind::{ + Add, BitAnd, BitOr, BitXor, Div, Eq, Gt, Ge, And, Or, Lt, Le, Rem, Mul, Ne, Shl, Shr, Sub, }; match op { Assign | AssignOp(_) => Associativity::Right, - Add | BitAnd | BitOr | BitXor | LAnd | LOr | Multiply | As => Associativity::Both, - Divide | Equal | Greater | GreaterEqual | Less | LessEqual | Modulus | NotEqual | ShiftLeft | ShiftRight - | Subtract => Associativity::Left, + Binary(Add | BitAnd | BitOr | BitXor | And | Or | Mul) | As => Associativity::Both, + Binary(Div | Eq | Gt | Ge | Lt | Le | Rem | Ne | Shl | Shr | Sub) => Associativity::Left, DotDot | DotDotEq => Associativity::None, } } From fc8e87b27418704316047eb15ff40382d8d847bc Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Dec 2024 21:42:46 +1100 Subject: [PATCH 365/991] Replace `AssocOp::DotDot{,Eq}` with `AssocOp::Range`. It makes `AssocOp` more similar to `ExprKind` and makes things a little simpler. And the semantic names make more sense here than the syntactic names. --- compiler/rustc_ast/src/ast.rs | 9 +++++++ compiler/rustc_ast/src/util/parser.rs | 21 +++++++--------- compiler/rustc_parse/src/parser/expr.rs | 15 +++++------- src/tools/clippy/clippy_utils/src/sugg.rs | 30 ++++++----------------- 4 files changed, 32 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 65dd0a34aeca..5c44fda22624 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1453,6 +1453,15 @@ pub enum RangeLimits { Closed, } +impl RangeLimits { + pub fn as_str(&self) -> &'static str { + match self { + RangeLimits::HalfOpen => "..", + RangeLimits::Closed => "..=", + } + } +} + /// A method call (e.g. `x.foo::(a, b, c)`). #[derive(Clone, Encodable, Decodable, Debug)] pub struct MethodCall { diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index e7c26aa30928..c610f933074d 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -1,6 +1,6 @@ use rustc_span::kw; -use crate::ast::{self, BinOpKind}; +use crate::ast::{self, BinOpKind, RangeLimits}; use crate::token::{self, BinOpToken, Token}; /// Associative operator. @@ -14,10 +14,8 @@ pub enum AssocOp { Assign, /// `as` As, - /// `..` range - DotDot, - /// `..=` range - DotDotEq, + /// `..` or `..=` range + Range(RangeLimits), } #[derive(PartialEq, Debug)] @@ -64,10 +62,9 @@ impl AssocOp { token::Ne => Some(Binary(BinOpKind::Ne)), token::AndAnd => Some(Binary(BinOpKind::And)), token::OrOr => Some(Binary(BinOpKind::Or)), - token::DotDot => Some(DotDot), - token::DotDotEq => Some(DotDotEq), + token::DotDot => Some(Range(RangeLimits::HalfOpen)), // DotDotDot is no longer supported, but we need some way to display the error - token::DotDotDot => Some(DotDotEq), + token::DotDotEq | token::DotDotDot => Some(Range(RangeLimits::Closed)), // `<-` should probably be `< -` token::LArrow => Some(Binary(BinOpKind::Lt)), _ if t.is_keyword(kw::As) => Some(As), @@ -81,7 +78,7 @@ impl AssocOp { match *self { As => ExprPrecedence::Cast, Binary(bin_op) => bin_op.precedence(), - DotDot | DotDotEq => ExprPrecedence::Range, + Range(_) => ExprPrecedence::Range, Assign | AssignOp(_) => ExprPrecedence::Assign, } } @@ -94,7 +91,7 @@ impl AssocOp { Assign | AssignOp(_) => Fixity::Right, Binary(binop) => binop.fixity(), As => Fixity::Left, - DotDot | DotDotEq => Fixity::None, + Range(_) => Fixity::None, } } @@ -102,7 +99,7 @@ impl AssocOp { use AssocOp::*; match *self { Binary(binop) => binop.is_comparison(), - Assign | AssignOp(_) | As | DotDot | DotDotEq => false, + Assign | AssignOp(_) | As | Range(_) => false, } } @@ -110,7 +107,7 @@ impl AssocOp { use AssocOp::*; match *self { Assign | AssignOp(_) => true, - As | Binary(_) | DotDot | DotDotEq => false, + As | Binary(_) | Range(_) => false, } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 00a5f2fa28fb..50ce6fa1a906 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -171,7 +171,7 @@ impl<'a> Parser<'a> { break; } // Check for deprecated `...` syntax - if self.token == token::DotDotDot && op.node == AssocOp::DotDotEq { + if self.token == token::DotDotDot && op.node == AssocOp::Range(RangeLimits::Closed) { self.err_dotdotdot_syntax(self.token.span); } @@ -267,10 +267,10 @@ impl<'a> Parser<'a> { if op == AssocOp::As { lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; continue; - } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq { + } else if let AssocOp::Range(limits) = op { // If we didn't have to handle `x..`/`x..=`, it would be pretty easy to // generalise it to the Fixity::None code. - lhs = self.parse_expr_range(prec, lhs, op, cur_op_span)?; + lhs = self.parse_expr_range(prec, lhs, limits, cur_op_span)?; break; } @@ -294,7 +294,7 @@ impl<'a> Parser<'a> { let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(span, aopexpr) } - AssocOp::As | AssocOp::DotDot | AssocOp::DotDotEq => { + AssocOp::As | AssocOp::Range(_) => { self.dcx().span_bug(span, "AssocOp should have been handled by special case") } }; @@ -372,8 +372,7 @@ impl<'a> Parser<'a> { AssocOp::Assign | AssocOp::AssignOp(_) | AssocOp::Binary(BinOpKind::BitOr) - | AssocOp::DotDot - | AssocOp::DotDotEq, + | AssocOp::Range(_), ), _, ) if self.restrictions.contains(Restrictions::IS_PAT) => { @@ -414,7 +413,7 @@ impl<'a> Parser<'a> { &mut self, prec: ExprPrecedence, lhs: P, - op: AssocOp, + limits: RangeLimits, cur_op_span: Span, ) -> PResult<'a, P> { let rhs = if self.is_at_start_of_range_notation_rhs() { @@ -430,8 +429,6 @@ impl<'a> Parser<'a> { }; let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span); let span = self.mk_expr_sp(&lhs, lhs.span, rhs_span); - let limits = - if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed }; let range = self.mk_range(Some(lhs), rhs, limits); Ok(self.mk_expr(span, range)) } diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 6e16778b343d..fe5ae54fe50b 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -113,10 +113,7 @@ impl<'a> Sugg<'a> { /// function variants of `Sugg`, since these use different snippet functions. fn hir_from_snippet(expr: &hir::Expr<'_>, mut get_snippet: impl FnMut(Span) -> Cow<'a, str>) -> Self { if let Some(range) = higher::Range::hir(expr) { - let op = match range.limits { - ast::RangeLimits::HalfOpen => AssocOp::DotDot, - ast::RangeLimits::Closed => AssocOp::DotDotEq, - }; + let op = AssocOp::Range(range.limits); let start = range.start.map_or("".into(), |expr| get_snippet(expr.span)); let end = range.end.map_or("".into(), |expr| get_snippet(expr.span)); @@ -178,8 +175,6 @@ impl<'a> Sugg<'a> { ctxt: SyntaxContext, app: &mut Applicability, ) -> Self { - use rustc_ast::ast::RangeLimits; - let mut snippet = |span: Span| snippet_with_context(cx, span, ctxt, default, app).0; match expr.kind { @@ -228,13 +223,8 @@ impl<'a> Sugg<'a> { | ast::ExprKind::Err(_) | ast::ExprKind::Dummy | ast::ExprKind::UnsafeBinderCast(..) => Sugg::NonParen(snippet(expr.span)), - ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::HalfOpen) => Sugg::BinOp( - AssocOp::DotDot, - lhs.as_ref().map_or("".into(), |lhs| snippet(lhs.span)), - rhs.as_ref().map_or("".into(), |rhs| snippet(rhs.span)), - ), - ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::Closed) => Sugg::BinOp( - AssocOp::DotDotEq, + ast::ExprKind::Range(ref lhs, ref rhs, limits) => Sugg::BinOp( + AssocOp::Range(limits), lhs.as_ref().map_or("".into(), |lhs| snippet(lhs.span)), rhs.as_ref().map_or("".into(), |rhs| snippet(rhs.span)), ), @@ -326,11 +316,8 @@ impl<'a> Sugg<'a> { /// Convenience method to create the `..` or `...` /// suggestion. - pub fn range(self, end: &Self, limit: ast::RangeLimits) -> Sugg<'static> { - match limit { - ast::RangeLimits::HalfOpen => make_assoc(AssocOp::DotDot, &self, end), - ast::RangeLimits::Closed => make_assoc(AssocOp::DotDotEq, &self, end), - } + pub fn range(self, end: &Self, limits: ast::RangeLimits) -> Sugg<'static> { + make_assoc(AssocOp::Range(limits), &self, end) } /// Adds parentheses to any expression that might need them. Suitable to the @@ -370,8 +357,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String { AssocOp::Assign => format!("{lhs} = {rhs}"), AssocOp::AssignOp(op) => format!("{lhs} {}= {rhs}", op.as_str()), AssocOp::As => format!("{lhs} as {rhs}"), - AssocOp::DotDot => format!("{lhs}..{rhs}"), - AssocOp::DotDotEq => format!("{lhs}..={rhs}"), + AssocOp::Range(limits) => format!("{lhs}{}{rhs}", limits.as_str()), } } @@ -590,7 +576,7 @@ enum Associativity { /// associative. #[must_use] fn associativity(op: AssocOp) -> Associativity { - use rustc_ast::util::parser::AssocOp::{As, Assign, AssignOp, Binary, DotDot, DotDotEq}; + use rustc_ast::util::parser::AssocOp::{As, Assign, AssignOp, Binary, Range}; use ast::BinOpKind::{ Add, BitAnd, BitOr, BitXor, Div, Eq, Gt, Ge, And, Or, Lt, Le, Rem, Mul, Ne, Shl, Shr, Sub, }; @@ -599,7 +585,7 @@ fn associativity(op: AssocOp) -> Associativity { Assign | AssignOp(_) => Associativity::Right, Binary(Add | BitAnd | BitOr | BitXor | And | Or | Mul) | As => Associativity::Both, Binary(Div | Eq | Gt | Ge | Lt | Le | Rem | Ne | Shl | Shr | Sub) => Associativity::Left, - DotDot | DotDotEq => Associativity::None, + Range(_) => Associativity::None, } } From 2ac46f651789950b6bafabcd5621080c9ff649f7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Dec 2024 21:46:44 +1100 Subject: [PATCH 366/991] Rename `AssocOp::As` as `AssocOp::Cast`. To match `ExprKind::Cast`, and because a semantic name makes more sense here than a syntactic name. --- compiler/rustc_ast/src/util/parser.rs | 14 +++++++------- compiler/rustc_parse/src/parser/expr.rs | 4 ++-- src/tools/clippy/clippy_utils/src/sugg.rs | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index c610f933074d..69454967eed6 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -13,7 +13,7 @@ pub enum AssocOp { /// `=` Assign, /// `as` - As, + Cast, /// `..` or `..=` range Range(RangeLimits), } @@ -67,7 +67,7 @@ impl AssocOp { token::DotDotEq | token::DotDotDot => Some(Range(RangeLimits::Closed)), // `<-` should probably be `< -` token::LArrow => Some(Binary(BinOpKind::Lt)), - _ if t.is_keyword(kw::As) => Some(As), + _ if t.is_keyword(kw::As) => Some(Cast), _ => None, } } @@ -76,7 +76,7 @@ impl AssocOp { pub fn precedence(&self) -> ExprPrecedence { use AssocOp::*; match *self { - As => ExprPrecedence::Cast, + Cast => ExprPrecedence::Cast, Binary(bin_op) => bin_op.precedence(), Range(_) => ExprPrecedence::Range, Assign | AssignOp(_) => ExprPrecedence::Assign, @@ -90,7 +90,7 @@ impl AssocOp { match *self { Assign | AssignOp(_) => Fixity::Right, Binary(binop) => binop.fixity(), - As => Fixity::Left, + Cast => Fixity::Left, Range(_) => Fixity::None, } } @@ -99,7 +99,7 @@ impl AssocOp { use AssocOp::*; match *self { Binary(binop) => binop.is_comparison(), - Assign | AssignOp(_) | As | Range(_) => false, + Assign | AssignOp(_) | Cast | Range(_) => false, } } @@ -107,7 +107,7 @@ impl AssocOp { use AssocOp::*; match *self { Assign | AssignOp(_) => true, - As | Binary(_) | Range(_) => false, + Cast | Binary(_) | Range(_) => false, } } @@ -133,7 +133,7 @@ impl AssocOp { AssignOp(_) | // `{ 42 } +=` // Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect // NotEqual | // `{ 42 } != { 42 } struct literals parser recovery. - As // `{ 42 } as usize` + Cast // `{ 42 } as usize` ) } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 50ce6fa1a906..c934c1e36d52 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -264,7 +264,7 @@ impl<'a> Parser<'a> { let op = op.node; // Special cases: - if op == AssocOp::As { + if op == AssocOp::Cast { lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; continue; } else if let AssocOp::Range(limits) = op { @@ -294,7 +294,7 @@ impl<'a> Parser<'a> { let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(span, aopexpr) } - AssocOp::As | AssocOp::Range(_) => { + AssocOp::Cast | AssocOp::Range(_) => { self.dcx().span_bug(span, "AssocOp should have been handled by special case") } }; diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index fe5ae54fe50b..4a9ab17d4a60 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -163,7 +163,7 @@ impl<'a> Sugg<'a> { ), ExprKind::Cast(lhs, ty) | //FIXME(chenyukang), remove this after type ascription is removed from AST - ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)), + ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::Cast, get_snippet(lhs.span), get_snippet(ty.span)), } } @@ -246,7 +246,7 @@ impl<'a> Sugg<'a> { ast::ExprKind::Cast(ref lhs, ref ty) | //FIXME(chenyukang), remove this after type ascription is removed from AST ast::ExprKind::Type(ref lhs, ref ty) => Sugg::BinOp( - AssocOp::As, + AssocOp::Cast, snippet(lhs.span), snippet(ty.span), ), @@ -265,7 +265,7 @@ impl<'a> Sugg<'a> { /// Convenience method to create the ` as ` suggestion. pub fn as_ty(self, rhs: R) -> Sugg<'static> { - make_assoc(AssocOp::As, &self, &Sugg::NonParen(rhs.to_string().into())) + make_assoc(AssocOp::Cast, &self, &Sugg::NonParen(rhs.to_string().into())) } /// Convenience method to create the `&` suggestion. @@ -356,7 +356,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String { AssocOp::Binary(op) => format!("{lhs} {} {rhs}", op.as_str()), AssocOp::Assign => format!("{lhs} = {rhs}"), AssocOp::AssignOp(op) => format!("{lhs} {}= {rhs}", op.as_str()), - AssocOp::As => format!("{lhs} as {rhs}"), + AssocOp::Cast => format!("{lhs} as {rhs}"), AssocOp::Range(limits) => format!("{lhs}{}{rhs}", limits.as_str()), } } @@ -432,7 +432,7 @@ impl Neg for Sugg<'_> { type Output = Sugg<'static>; fn neg(self) -> Sugg<'static> { match &self { - Self::BinOp(AssocOp::As, ..) => Sugg::MaybeParen(format!("-({self})").into()), + Self::BinOp(AssocOp::Cast, ..) => Sugg::MaybeParen(format!("-({self})").into()), _ => make_unop("-", self), } } @@ -576,14 +576,14 @@ enum Associativity { /// associative. #[must_use] fn associativity(op: AssocOp) -> Associativity { - use rustc_ast::util::parser::AssocOp::{As, Assign, AssignOp, Binary, Range}; + use rustc_ast::util::parser::AssocOp::{Assign, AssignOp, Binary, Cast, Range}; use ast::BinOpKind::{ Add, BitAnd, BitOr, BitXor, Div, Eq, Gt, Ge, And, Or, Lt, Le, Rem, Mul, Ne, Shl, Shr, Sub, }; match op { Assign | AssignOp(_) => Associativity::Right, - Binary(Add | BitAnd | BitOr | BitXor | And | Or | Mul) | As => Associativity::Both, + Binary(Add | BitAnd | BitOr | BitXor | And | Or | Mul) | Cast => Associativity::Both, Binary(Div | Eq | Gt | Ge | Lt | Le | Rem | Ne | Shl | Shr | Sub) => Associativity::Left, Range(_) => Associativity::None, } From cc783862b01467f4683e830d0e12b52b3684b898 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Feb 2025 12:01:44 +1100 Subject: [PATCH 367/991] Always inline `query_get_at`. --- compiler/rustc_middle/src/query/plumbing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 690b8128b1ae..3857ee83a0f4 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -165,7 +165,7 @@ impl<'tcx> TyCtxt<'tcx> { } } -#[inline] +#[inline(always)] pub fn query_get_at<'tcx, Cache>( tcx: TyCtxt<'tcx>, execute_query: fn(TyCtxt<'tcx>, Span, Cache::Key, QueryMode) -> Option, From dae664d09a0f4c72702d96877aeace83cc100f41 Mon Sep 17 00:00:00 2001 From: LuuuXXX Date: Thu, 27 Feb 2025 11:43:03 +0800 Subject: [PATCH 368/991] Cofigurate out ohos target to avoid compilation crashes --- src/tools/rust-analyzer/crates/profile/Cargo.toml | 2 +- .../rust-analyzer/crates/profile/src/stop_watch.rs | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/profile/Cargo.toml b/src/tools/rust-analyzer/crates/profile/Cargo.toml index 3179c810f699..65eec868af3d 100644 --- a/src/tools/rust-analyzer/crates/profile/Cargo.toml +++ b/src/tools/rust-analyzer/crates/profile/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = "1.0.0" libc.workspace = true jemalloc-ctl = { version = "0.5.0", package = "tikv-jemalloc-ctl", optional = true } -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(all(target_os = "linux", not(target_env = "ohos")))'.dependencies] perf-event = "=0.4.7" [target.'cfg(windows)'.dependencies] diff --git a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs index 0a803959eeda..9f3e636ef816 100644 --- a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs +++ b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs @@ -11,7 +11,7 @@ use crate::MemoryUsage; pub struct StopWatch { time: Instant, - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] counter: Option, memory: MemoryUsage, } @@ -24,7 +24,7 @@ pub struct StopWatchSpan { impl StopWatch { pub fn start() -> StopWatch { - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] let counter = { // When debugging rust-analyzer using rr, the perf-related syscalls cause it to abort. // We allow disabling perf by setting the env var `RA_DISABLE_PERF`. @@ -51,7 +51,7 @@ impl StopWatch { let time = Instant::now(); StopWatch { time, - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] counter, memory, } @@ -60,10 +60,12 @@ impl StopWatch { pub fn elapsed(&mut self) -> StopWatchSpan { let time = self.time.elapsed(); - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] let instructions = self.counter.as_mut().and_then(|it| { it.read().map_err(|err| eprintln!("Failed to read perf counter: {err}")).ok() }); + #[cfg(all(target_os = "linux", target_env = "ohos"))] + let instructions = None; #[cfg(not(target_os = "linux"))] let instructions = None; From ef66cbb27bc2a911edf4541e1c56102dc03e42d9 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 7 Feb 2025 21:58:08 +0800 Subject: [PATCH 369/991] require trait impls to have matching const stabilities as the traits --- .../rustc_const_eval/src/check_consts/mod.rs | 5 ++ compiler/rustc_passes/messages.ftl | 6 ++ compiler/rustc_passes/src/errors.rs | 39 +++++++++++ compiler/rustc_passes/src/stability.rs | 60 ++++++++++++---- library/core/src/ops/arith.rs | 1 + library/core/src/ops/deref.rs | 3 + tests/ui/traits/const-traits/staged-api.rs | 32 +++++++++ .../ui/traits/const-traits/staged-api.stderr | 69 ++++++++++++++++++- 8 files changed, 200 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 659d4a304563..607cb2e497d8 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -94,6 +94,11 @@ pub fn rustc_allow_const_fn_unstable( /// world into two functions: those that are safe to expose on stable (and hence may not use /// unstable features, not even recursively), and those that are not. pub fn is_fn_or_trait_safe_to_expose_on_stable(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + // A default body in a `#[const_trait]` is const-stable when the trait is const-stable. + if tcx.is_const_default_method(def_id) { + return is_fn_or_trait_safe_to_expose_on_stable(tcx, tcx.parent(def_id)); + } + match tcx.lookup_const_stability(def_id) { None => { // In a `staged_api` crate, we do enforce recursive const stability for all unmarked diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index bc43580a7f00..b65430c34802 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -725,6 +725,12 @@ passes_target_feature_on_statement = .warn = {-passes_previously_accepted} .label = {passes_should_be_applied_to_fn.label} +passes_trait_impl_const_stability_mismatch = const stability on the impl does not match the const stability on the trait +passes_trait_impl_const_stability_mismatch_impl_stable = this impl is (implicitly) stable... +passes_trait_impl_const_stability_mismatch_impl_unstable = this impl is unstable... +passes_trait_impl_const_stability_mismatch_trait_stable = ...but the trait is stable +passes_trait_impl_const_stability_mismatch_trait_unstable = ...but the trait is unstable + passes_trait_impl_const_stable = trait implementations cannot be const stable yet .note = see issue #67792 for more information diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 51b5861ee0ae..9bb9b2353dc8 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1552,6 +1552,45 @@ pub(crate) struct TraitImplConstStable { pub span: Span, } +#[derive(Diagnostic)] +#[diag(passes_trait_impl_const_stability_mismatch)] +pub(crate) struct TraitImplConstStabilityMismatch { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub impl_stability: ImplConstStability, + #[subdiagnostic] + pub trait_stability: TraitConstStability, +} + +#[derive(Subdiagnostic)] +pub(crate) enum TraitConstStability { + #[note(passes_trait_impl_const_stability_mismatch_trait_stable)] + Stable { + #[primary_span] + span: Span, + }, + #[note(passes_trait_impl_const_stability_mismatch_trait_unstable)] + Unstable { + #[primary_span] + span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub(crate) enum ImplConstStability { + #[note(passes_trait_impl_const_stability_mismatch_impl_stable)] + Stable { + #[primary_span] + span: Span, + }, + #[note(passes_trait_impl_const_stability_mismatch_impl_unstable)] + Unstable { + #[primary_span] + span: Span, + }, +} + #[derive(Diagnostic)] #[diag(passes_unknown_feature, code = E0635)] pub(crate) struct UnknownFeature { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 8a4bdf3875c4..0fcf6a80ec4d 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -313,7 +313,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { .map(|(stab, _span)| ConstStability::from_partial(stab, const_stability_indirect)); // If this is a const fn but not annotated with stability markers, see if we can inherit regular stability. - if fn_sig.is_some_and(|s| s.header.is_const()) && const_stab.is_none() && + if fn_sig.is_some_and(|s| s.header.is_const()) && const_stab.is_none() && // We only ever inherit unstable features. let Some(inherit_regular_stab) = final_stab.filter(|s| s.is_unstable()) @@ -826,24 +826,56 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { } } - // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable - // needs to have an error emitted. if features.const_trait_impl() - && self.tcx.is_const_trait_impl(item.owner_id.to_def_id()) - && const_stab.is_some_and(|stab| stab.is_const_stable()) + && let hir::Constness::Const = constness { - self.tcx.dcx().emit_err(errors::TraitImplConstStable { span: item.span }); + let stable_or_implied_stable = match const_stab { + None => true, + Some(stab) if stab.is_const_stable() => { + // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable + // needs to have an error emitted. + // Note: Remove this error once `const_trait_impl` is stabilized + self.tcx + .dcx() + .emit_err(errors::TraitImplConstStable { span: item.span }); + true + } + Some(_) => false, + }; + + if let Some(trait_id) = t.trait_def_id() + && let Some(const_stab) = self.tcx.lookup_const_stability(trait_id) + { + // the const stability of a trait impl must match the const stability on the trait. + if const_stab.is_const_stable() != stable_or_implied_stable { + let trait_span = self.tcx.def_ident_span(trait_id).unwrap(); + + let impl_stability = if stable_or_implied_stable { + errors::ImplConstStability::Stable { span: item.span } + } else { + errors::ImplConstStability::Unstable { span: item.span } + }; + let trait_stability = if const_stab.is_const_stable() { + errors::TraitConstStability::Stable { span: trait_span } + } else { + errors::TraitConstStability::Unstable { span: trait_span } + }; + + self.tcx.dcx().emit_err(errors::TraitImplConstStabilityMismatch { + span: item.span, + impl_stability, + trait_stability, + }); + } + } } } - match constness { - rustc_hir::Constness::Const => { - if let Some(def_id) = t.trait_def_id() { - // FIXME(const_trait_impl): Improve the span here. - self.tcx.check_const_stability(def_id, t.path.span, t.path.span); - } - } - rustc_hir::Constness::NotConst => {} + if let hir::Constness::Const = constness + && let Some(def_id) = t.trait_def_id() + { + // FIXME(const_trait_impl): Improve the span here. + self.tcx.check_const_stability(def_id, t.path.span, t.path.span); } for impl_item_ref in *items { diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index fe7ff2d9ede6..54d79beca95a 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -96,6 +96,7 @@ pub trait Add { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] impl const Add for $t { type Output = $t; diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index 11490ea2bfcb..e74f5443ac2d 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -150,6 +150,7 @@ pub trait Deref { } #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] impl const Deref for &T { type Target = T; @@ -163,6 +164,7 @@ impl const Deref for &T { impl !DerefMut for &T {} #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] impl const Deref for &mut T { type Target = T; @@ -273,6 +275,7 @@ pub trait DerefMut: ~const Deref { } #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] impl const DerefMut for &mut T { fn deref_mut(&mut self) -> &mut T { *self diff --git a/tests/ui/traits/const-traits/staged-api.rs b/tests/ui/traits/const-traits/staged-api.rs index 9a030dafd6bc..8dd7226fc298 100644 --- a/tests/ui/traits/const-traits/staged-api.rs +++ b/tests/ui/traits/const-traits/staged-api.rs @@ -85,4 +85,36 @@ const fn implicitly_stable_const_context() { //~^ ERROR cannot use `#[feature(const_trait_impl)]` } +// check that const stability of impls and traits must match +#[const_trait] +#[rustc_const_unstable(feature = "beef", issue = "none")] +trait U {} + +#[const_trait] +#[rustc_const_stable(since = "0.0.0", feature = "beef2")] +trait S {} + +// implied stable +impl const U for u8 {} +//~^ const stability on the impl does not match the const stability on the trait + +#[rustc_const_stable(since = "0.0.0", feature = "beef2")] +impl const U for u16 {} +//~^ const stability on the impl does not match the const stability on the trait +//~| trait implementations cannot be const stable yet + +#[rustc_const_unstable(feature = "beef", issue = "none")] +impl const U for u32 {} + +// implied stable +impl const S for u8 {} + +#[rustc_const_stable(since = "0.0.0", feature = "beef2")] +impl const S for u16 {} +//~^ trait implementations cannot be const stable yet + +#[rustc_const_unstable(feature = "beef", issue = "none")] +impl const S for u32 {} +//~^ const stability on the impl does not match the const stability on the trait + fn main() {} diff --git a/tests/ui/traits/const-traits/staged-api.stderr b/tests/ui/traits/const-traits/staged-api.stderr index a7a7a1ee7215..cdf577287eec 100644 --- a/tests/ui/traits/const-traits/staged-api.stderr +++ b/tests/ui/traits/const-traits/staged-api.stderr @@ -1,3 +1,70 @@ +error: const stability on the impl does not match the const stability on the trait + --> $DIR/staged-api.rs:98:1 + | +LL | impl const U for u8 {} + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: this impl is (implicitly) stable... + --> $DIR/staged-api.rs:98:1 + | +LL | impl const U for u8 {} + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...but the trait is unstable + --> $DIR/staged-api.rs:91:7 + | +LL | trait U {} + | ^ + +error: trait implementations cannot be const stable yet + --> $DIR/staged-api.rs:102:1 + | +LL | impl const U for u16 {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #67792 for more information + +error: const stability on the impl does not match the const stability on the trait + --> $DIR/staged-api.rs:102:1 + | +LL | impl const U for u16 {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this impl is (implicitly) stable... + --> $DIR/staged-api.rs:102:1 + | +LL | impl const U for u16 {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...but the trait is unstable + --> $DIR/staged-api.rs:91:7 + | +LL | trait U {} + | ^ + +error: trait implementations cannot be const stable yet + --> $DIR/staged-api.rs:113:1 + | +LL | impl const S for u16 {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #67792 for more information + +error: const stability on the impl does not match the const stability on the trait + --> $DIR/staged-api.rs:117:1 + | +LL | impl const S for u32 {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this impl is unstable... + --> $DIR/staged-api.rs:117:1 + | +LL | impl const S for u32 {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...but the trait is stable + --> $DIR/staged-api.rs:95:7 + | +LL | trait S {} + | ^ + error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_trait_impl)]` --> $DIR/staged-api.rs:38:5 | @@ -323,5 +390,5 @@ LL + #[rustc_allow_const_fn_unstable(const_trait_impl)] LL | const fn implicitly_stable_const_context() { | -error: aborting due to 19 previous errors +error: aborting due to 24 previous errors From 8089fce101f4ac2ed68c8df080c61102b0210429 Mon Sep 17 00:00:00 2001 From: DianQK Date: Wed, 26 Feb 2025 19:54:34 +0800 Subject: [PATCH 370/991] Don't infer attributes of virtual calls based on the function body --- compiler/rustc_middle/src/ty/instance.rs | 5 +- compiler/rustc_ty_utils/src/abi.rs | 63 +++++++++---------- .../virtual-call-attrs-issue-137646.rs | 18 ++++++ tests/ui/virtual-call-attrs-issue-137646.rs | 6 +- ...virtual-call-attrs-issue-137646.run.stderr | 20 ------ 5 files changed, 52 insertions(+), 60 deletions(-) create mode 100644 tests/codegen/virtual-call-attrs-issue-137646.rs delete mode 100644 tests/ui/virtual-call-attrs-issue-137646.run.stderr diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index e9c19331e4a0..98ca71b86be0 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -111,8 +111,9 @@ pub enum InstanceKind<'tcx> { /// Dynamic dispatch to `::fn`. /// - /// This `InstanceKind` does not have callable MIR. Calls to `Virtual` instances must be - /// codegen'd as virtual calls through the vtable. + /// This `InstanceKind` may have a callable MIR as the default implementation. + /// Calls to `Virtual` instances must be codegen'd as virtual calls through the vtable. + /// *This means we might not know exactly what is being called.* /// /// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more /// details on that). diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 0ff82f0c256d..4fa8c9fe15d0 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -309,15 +309,11 @@ fn fn_abi_of_fn_ptr<'tcx>( query: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)>, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> { let ty::PseudoCanonicalInput { typing_env, value: (sig, extra_args) } = query; - - let cx = LayoutCx::new(tcx, typing_env); fn_abi_new_uncached( - &cx, + &LayoutCx::new(tcx, typing_env), tcx.instantiate_bound_regions_with_erased(sig), extra_args, None, - None, - false, ) } @@ -326,19 +322,11 @@ fn fn_abi_of_instance<'tcx>( query: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)>, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> { let ty::PseudoCanonicalInput { typing_env, value: (instance, extra_args) } = query; - - let sig = fn_sig_for_fn_abi(tcx, instance, typing_env); - - let caller_location = - instance.def.requires_caller_location(tcx).then(|| tcx.caller_location_ty()); - fn_abi_new_uncached( &LayoutCx::new(tcx, typing_env), - sig, + fn_sig_for_fn_abi(tcx, instance, typing_env), extra_args, - caller_location, - Some(instance.def_id()), - matches!(instance.def, ty::InstanceKind::Virtual(..)), + Some(instance), ) } @@ -547,19 +535,23 @@ fn fn_abi_sanity_check<'tcx>( fn_arg_sanity_check(cx, fn_abi, spec_abi, &fn_abi.ret); } -// FIXME(eddyb) perhaps group the signature/type-containing (or all of them?) -// arguments of this method, into a separate `struct`. -#[tracing::instrument(level = "debug", skip(cx, caller_location, fn_def_id, force_thin_self_ptr))] +#[tracing::instrument(level = "debug", skip(cx, instance))] fn fn_abi_new_uncached<'tcx>( cx: &LayoutCx<'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>], - caller_location: Option>, - fn_def_id: Option, - // FIXME(eddyb) replace this with something typed, like an `enum`. - force_thin_self_ptr: bool, + instance: Option>, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> { let tcx = cx.tcx(); + let (caller_location, fn_def_id, is_virtual_call) = if let Some(instance) = instance { + ( + instance.def.requires_caller_location(tcx).then(|| tcx.caller_location_ty()), + Some(instance.def_id()), + matches!(instance.def, ty::InstanceKind::Virtual(..)), + ) + } else { + (None, None, false) + }; let sig = tcx.normalize_erasing_regions(cx.typing_env, sig); let conv = conv_from_spec_abi(cx.tcx(), sig.abi, sig.c_variadic); @@ -568,16 +560,11 @@ fn fn_abi_new_uncached<'tcx>( let extra_args = if sig.abi == ExternAbi::RustCall { assert!(!sig.c_variadic && extra_args.is_empty()); - if let Some(input) = sig.inputs().last() { - if let ty::Tuple(tupled_arguments) = input.kind() { - inputs = &sig.inputs()[0..sig.inputs().len() - 1]; - tupled_arguments - } else { - bug!( - "argument to function with \"rust-call\" ABI \ - is not a tuple" - ); - } + if let Some(input) = sig.inputs().last() + && let ty::Tuple(tupled_arguments) = input.kind() + { + inputs = &sig.inputs()[0..sig.inputs().len() - 1]; + tupled_arguments } else { bug!( "argument to function with \"rust-call\" ABI \ @@ -603,7 +590,7 @@ fn fn_abi_new_uncached<'tcx>( }); let layout = cx.layout_of(ty).map_err(|err| &*tcx.arena.alloc(FnAbiError::Layout(*err)))?; - let layout = if force_thin_self_ptr && arg_idx == Some(0) { + let layout = if is_virtual_call && arg_idx == Some(0) { // Don't pass the vtable, it's not an argument of the virtual fn. // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen @@ -648,7 +635,15 @@ fn fn_abi_new_uncached<'tcx>( conv, can_unwind: fn_can_unwind(cx.tcx(), fn_def_id, sig.abi), }; - fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi, fn_def_id); + fn_abi_adjust_for_abi( + cx, + &mut fn_abi, + sig.abi, + // If this is a virtual call, we cannot pass the `fn_def_id`, as it might call other + // functions from vtable. Internally, `deduced_param_attrs` attempts to infer attributes by + // visit the function body. + fn_def_id.filter(|_| !is_virtual_call), + ); debug!("fn_abi_new_uncached = {:?}", fn_abi); fn_abi_sanity_check(cx, &fn_abi, sig.abi); Ok(tcx.arena.alloc(fn_abi)) diff --git a/tests/codegen/virtual-call-attrs-issue-137646.rs b/tests/codegen/virtual-call-attrs-issue-137646.rs new file mode 100644 index 000000000000..72a25b758569 --- /dev/null +++ b/tests/codegen/virtual-call-attrs-issue-137646.rs @@ -0,0 +1,18 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/137646. +//! Since we don't know the exact implementation of the virtual call, +//! it might write to parameters, we can't infer the readonly attribute. +//@ compile-flags: -C opt-level=3 -C no-prepopulate-passes + +#![crate_type = "lib"] + +pub trait Trait { + fn m(&self, _: (i32, i32, i32)) {} +} + +#[no_mangle] +pub fn foo(trait_: &dyn Trait) { + // CHECK-LABEL: @foo( + // CHECK: call void + // CHECK-NOT: readonly + trait_.m((1, 1, 1)); +} diff --git a/tests/ui/virtual-call-attrs-issue-137646.rs b/tests/ui/virtual-call-attrs-issue-137646.rs index 055dc6ea4f2d..e80bd5768a42 100644 --- a/tests/ui/virtual-call-attrs-issue-137646.rs +++ b/tests/ui/virtual-call-attrs-issue-137646.rs @@ -1,8 +1,7 @@ //! Regression test for https://github.com/rust-lang/rust/issues/137646. -//! FIXME: The parameter value at all calls to `check` should be `(1, 1, 1)`. +//! The parameter value at all calls to `check` should be `(1, 1, 1)`. //@ run-pass -//@ check-run-results use std::hint::black_box; @@ -35,8 +34,7 @@ pub fn run_2(trait_: &dyn Trait) { #[inline(never)] fn check(v: T) { - dbg!(v); - // assert_eq!(v, (1, 1, 1)); + assert_eq!(v, (1, 1, 1)); } fn main() { diff --git a/tests/ui/virtual-call-attrs-issue-137646.run.stderr b/tests/ui/virtual-call-attrs-issue-137646.run.stderr deleted file mode 100644 index 445975e1e54e..000000000000 --- a/tests/ui/virtual-call-attrs-issue-137646.run.stderr +++ /dev/null @@ -1,20 +0,0 @@ -[$DIR/virtual-call-attrs-issue-137646.rs:38:5] v = ( - 498486832, - 22093, - 498491440, -) -[$DIR/virtual-call-attrs-issue-137646.rs:38:5] v = ( - 0, - 0, - 0, -) -[$DIR/virtual-call-attrs-issue-137646.rs:38:5] v = ( - 0, - 0, - 0, -) -[$DIR/virtual-call-attrs-issue-137646.rs:38:5] v = ( - 0, - 0, - 0, -) From fbe0075a86601e490ae217f3b291768759c39930 Mon Sep 17 00:00:00 2001 From: DianQK Date: Thu, 27 Feb 2025 09:22:19 +0800 Subject: [PATCH 371/991] Don't infer unwinding of virtual calls based on the function attributes --- compiler/rustc_ty_utils/src/abi.rs | 19 +++++++++++++------ .../virtual-call-attrs-issue-137646.rs | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 4fa8c9fe15d0..74ab65b4f58b 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -543,11 +543,13 @@ fn fn_abi_new_uncached<'tcx>( instance: Option>, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> { let tcx = cx.tcx(); - let (caller_location, fn_def_id, is_virtual_call) = if let Some(instance) = instance { + let (caller_location, determined_fn_def_id, is_virtual_call) = if let Some(instance) = instance + { + let is_virtual_call = matches!(instance.def, ty::InstanceKind::Virtual(..)); ( instance.def.requires_caller_location(tcx).then(|| tcx.caller_location_ty()), - Some(instance.def_id()), - matches!(instance.def, ty::InstanceKind::Virtual(..)), + if is_virtual_call { None } else { Some(instance.def_id()) }, + is_virtual_call, ) } else { (None, None, false) @@ -577,7 +579,7 @@ fn fn_abi_new_uncached<'tcx>( }; let is_drop_in_place = - fn_def_id.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::DropInPlace)); + determined_fn_def_id.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::DropInPlace)); let arg_of = |ty: Ty<'tcx>, arg_idx: Option| -> Result<_, &'tcx FnAbiError<'tcx>> { let span = tracing::debug_span!("arg_of"); @@ -633,7 +635,12 @@ fn fn_abi_new_uncached<'tcx>( c_variadic: sig.c_variadic, fixed_count: inputs.len() as u32, conv, - can_unwind: fn_can_unwind(cx.tcx(), fn_def_id, sig.abi), + can_unwind: fn_can_unwind( + tcx, + // Since `#[rustc_nounwind]` can change unwinding, we cannot infer unwinding by `fn_def_id` for a virtual call. + determined_fn_def_id, + sig.abi, + ), }; fn_abi_adjust_for_abi( cx, @@ -642,7 +649,7 @@ fn fn_abi_new_uncached<'tcx>( // If this is a virtual call, we cannot pass the `fn_def_id`, as it might call other // functions from vtable. Internally, `deduced_param_attrs` attempts to infer attributes by // visit the function body. - fn_def_id.filter(|_| !is_virtual_call), + determined_fn_def_id, ); debug!("fn_abi_new_uncached = {:?}", fn_abi); fn_abi_sanity_check(cx, &fn_abi, sig.abi); diff --git a/tests/codegen/virtual-call-attrs-issue-137646.rs b/tests/codegen/virtual-call-attrs-issue-137646.rs index 72a25b758569..5e453947f27d 100644 --- a/tests/codegen/virtual-call-attrs-issue-137646.rs +++ b/tests/codegen/virtual-call-attrs-issue-137646.rs @@ -4,8 +4,10 @@ //@ compile-flags: -C opt-level=3 -C no-prepopulate-passes #![crate_type = "lib"] +#![feature(rustc_attrs)] pub trait Trait { + #[rustc_nounwind] fn m(&self, _: (i32, i32, i32)) {} } @@ -16,3 +18,20 @@ pub fn foo(trait_: &dyn Trait) { // CHECK-NOT: readonly trait_.m((1, 1, 1)); } + +#[no_mangle] +#[rustc_nounwind] +pub fn foo_nounwind(trait_: &dyn Trait) { + // CHECK-LABEL: @foo_nounwind( + // FIXME: Here should be invoke. + // COM: CHECK: invoke + trait_.m((1, 1, 1)); +} + +#[no_mangle] +pub extern "C" fn c_nounwind(trait_: &dyn Trait) { + // CHECK-LABEL: @c_nounwind( + // FIXME: Here should be invoke. + // COM: CHECK: invoke + trait_.m((1, 1, 1)); +} From a36d8acd835c96de1b1184d97648a16648591607 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Feb 2025 18:10:17 +1100 Subject: [PATCH 372/991] Optimize empty provenance range checks. Currently it gets the pointers in the range and checks if the result is empty, but it can be done faster if you combine those two steps. --- .../rustc_data_structures/src/sorted_map.rs | 33 +++++++++++++++++ .../interpret/allocation/provenance_map.rs | 37 ++++++++++++++----- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index 066ea03b4ace..a01a420dfbd6 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -1,4 +1,5 @@ use std::borrow::Borrow; +use std::cmp::Ordering; use std::fmt::Debug; use std::mem; use std::ops::{Bound, Index, IndexMut, RangeBounds}; @@ -156,6 +157,38 @@ impl SortedMap { &self.data[start..end] } + /// `sm.range_is_empty(r)` == `sm.range(r).is_empty()`, but is faster. + #[inline] + pub fn range_is_empty(&self, range: R) -> bool + where + R: RangeBounds, + { + // `range` must (via `range_slice_indices`) search for the start and + // end separately. But here we can do a single binary search for the + // entire range. If a single `x` matching `range` is found then the + // range is *not* empty. + self.data + .binary_search_by(|(x, _)| { + // Is `x` below `range`? + match range.start_bound() { + Bound::Included(start) if x < start => return Ordering::Less, + Bound::Excluded(start) if x <= start => return Ordering::Less, + _ => {} + }; + + // Is `x` above `range`? + match range.end_bound() { + Bound::Included(end) if x > end => return Ordering::Greater, + Bound::Excluded(end) if x >= end => return Ordering::Greater, + _ => {} + }; + + // `x` must be within `range`. + Ordering::Equal + }) + .is_err() + } + #[inline] pub fn remove_range(&mut self, range: R) where diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index 2f13f9635785..82fb5f33b4c8 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -2,6 +2,7 @@ //! representation for the common case where PTR_SIZE consecutive bytes have the same provenance. use std::cmp; +use std::ops::Range; use rustc_abi::{HasDataLayout, Size}; use rustc_data_structures::sorted_map::SortedMap; @@ -66,6 +67,15 @@ impl ProvenanceMap { } impl ProvenanceMap { + fn adjusted_range(range: AllocRange, cx: &impl HasDataLayout) -> Range { + // We have to go back `pointer_size - 1` bytes, as that one would still overlap with + // the beginning of this range. + let adjusted_start = Size::from_bytes( + range.start.bytes().saturating_sub(cx.data_layout().pointer_size.bytes() - 1), + ); + adjusted_start..range.end() + } + /// Returns all ptr-sized provenance in the given range. /// If the range has length 0, returns provenance that crosses the edge between `start-1` and /// `start`. @@ -74,12 +84,17 @@ impl ProvenanceMap { range: AllocRange, cx: &impl HasDataLayout, ) -> &[(Size, Prov)] { - // We have to go back `pointer_size - 1` bytes, as that one would still overlap with - // the beginning of this range. - let adjusted_start = Size::from_bytes( - range.start.bytes().saturating_sub(cx.data_layout().pointer_size.bytes() - 1), - ); - self.ptrs.range(adjusted_start..range.end()) + self.ptrs.range(Self::adjusted_range(range, cx)) + } + + /// `pm.range_get_ptrs_is_empty(r, cx)` == `pm.range_get_ptrs(r, cx).is_empty()`, but is + /// faster. + pub(super) fn range_get_ptrs_is_empty( + &self, + range: AllocRange, + cx: &impl HasDataLayout, + ) -> bool { + self.ptrs.range_is_empty(Self::adjusted_range(range, cx)) } /// Returns all byte-wise provenance in the given range. @@ -117,7 +132,7 @@ impl ProvenanceMap { /// limit access to provenance outside of the `Allocation` abstraction. /// pub fn range_empty(&self, range: AllocRange, cx: &impl HasDataLayout) -> bool { - self.range_get_ptrs(range, cx).is_empty() && self.range_get_bytes(range).is_empty() + self.range_get_ptrs_is_empty(range, cx) && self.range_get_bytes(range).is_empty() } /// Yields all the provenances stored in this map. @@ -149,12 +164,14 @@ impl ProvenanceMap { // provenance that overlaps with the given range. let (first, last) = { // Find all provenance overlapping the given range. - let provenance = self.range_get_ptrs(range, cx); - if provenance.is_empty() { - // No provenance in this range, we are done. + if self.range_get_ptrs_is_empty(range, cx) { + // No provenance in this range, we are done. This is the common case. return Ok(()); } + // This redoes some of the work of `range_get_ptrs_is_empty`, but this path is much + // colder than the early return above, so it's worth it. + let provenance = self.range_get_ptrs(range, cx); ( provenance.first().unwrap().0, provenance.last().unwrap().0 + cx.data_layout().pointer_size, From 3a715798bce929ceca07b17ec1cb09112d5618d5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 26 Feb 2025 09:36:50 +0100 Subject: [PATCH 373/991] Update to LLVM 20 rc 3 --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 92e80685d0d5..1c3bb96fdb6d 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 92e80685d0d5dcea3ccf321995c43b72338639c6 +Subproject commit 1c3bb96fdb6db7b8e8f24edb016099c223fdd27e From e399e152e8e5c0060c4f37d39de202d5c9b546d1 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 27 Feb 2025 10:18:44 +0100 Subject: [PATCH 374/991] Fix ICE --- clippy_lints/src/doc/mod.rs | 11 +++++++- .../ui/doc/doc_nested_refdef_list_item.fixed | 8 ++++++ tests/ui/doc/doc_nested_refdef_list_item.rs | 8 ++++++ .../ui/doc/doc_nested_refdef_list_item.stderr | 26 ++++++++++++++++++- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index bc3e78c7a2c6..984a5e74ce4f 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -1004,7 +1004,12 @@ fn check_doc<'a, Events: Iterator, Range range.start { + start - range.start + } else { + 0 + } } } else { 0 @@ -1184,6 +1189,10 @@ impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> { #[expect(clippy::range_plus_one)] // inclusive ranges aren't the same type fn looks_like_refdef(doc: &str, range: Range) -> Option> { + if range.end < range.start { + return None; + } + let offset = range.start; let mut iterator = doc.as_bytes()[range].iter().copied().enumerate(); let mut start = None; diff --git a/tests/ui/doc/doc_nested_refdef_list_item.fixed b/tests/ui/doc/doc_nested_refdef_list_item.fixed index fcfcfcc40736..065f4486e390 100644 --- a/tests/ui/doc/doc_nested_refdef_list_item.fixed +++ b/tests/ui/doc/doc_nested_refdef_list_item.fixed @@ -69,3 +69,11 @@ pub struct NotEmpty; /// - [link]\: notdef /// inner text pub struct NotEmptyTight; + +/// ## Heading +/// +/// - [x][] - Done +//~^ ERROR: link reference defined in list item +/// - [ ][] - Not Done +//~^ ERROR: link reference defined in list item +pub struct GithubCheckboxes; diff --git a/tests/ui/doc/doc_nested_refdef_list_item.rs b/tests/ui/doc/doc_nested_refdef_list_item.rs index 53368de4616d..c7eab50c8b38 100644 --- a/tests/ui/doc/doc_nested_refdef_list_item.rs +++ b/tests/ui/doc/doc_nested_refdef_list_item.rs @@ -69,3 +69,11 @@ pub struct NotEmpty; /// - [link]\: notdef /// inner text pub struct NotEmptyTight; + +/// ## Heading +/// +/// - [x] - Done +//~^ ERROR: link reference defined in list item +/// - [ ] - Not Done +//~^ ERROR: link reference defined in list item +pub struct GithubCheckboxes; diff --git a/tests/ui/doc/doc_nested_refdef_list_item.stderr b/tests/ui/doc/doc_nested_refdef_list_item.stderr index 27314c7e968d..5a815dabf4d8 100644 --- a/tests/ui/doc/doc_nested_refdef_list_item.stderr +++ b/tests/ui/doc/doc_nested_refdef_list_item.stderr @@ -144,5 +144,29 @@ help: for an intra-doc link, add `[]` between the label and the colon LL | /// - [link][]: def "title" | ++ -error: aborting due to 12 previous errors +error: link reference defined in list item + --> tests/ui/doc/doc_nested_refdef_list_item.rs:75:7 + | +LL | /// - [x] - Done + | ^^^ + | + = help: link definitions are not shown in rendered documentation +help: for an intra-doc link, add `[]` between the label and the colon + | +LL | /// - [x][] - Done + | ++ + +error: link reference defined in list item + --> tests/ui/doc/doc_nested_refdef_list_item.rs:77:7 + | +LL | /// - [ ] - Not Done + | ^^^ + | + = help: link definitions are not shown in rendered documentation +help: for an intra-doc link, add `[]` between the label and the colon + | +LL | /// - [ ][] - Not Done + | ++ + +error: aborting due to 14 previous errors From 5765005a7fb7c7363b44c96b0c56ccbb77bb173d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Thu, 27 Feb 2025 09:14:31 +0100 Subject: [PATCH 375/991] Clean up TypeckResults::extract_binding_mode - Remove the `Option` from the result type, as `None` is never returned. - Document the difference from the `BindingMode` in `PatKind::Binding`. --- compiler/rustc_hir/src/hir.rs | 6 ++ .../rustc_hir_typeck/src/expr_use_visitor.rs | 70 +++++++++---------- compiler/rustc_hir_typeck/src/writeback.rs | 7 +- .../rustc_middle/src/ty/typeck_results.rs | 6 +- src/tools/clippy/clippy_utils/src/lib.rs | 1 - 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f0eaec55dbdd..d946cda04e89 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1683,6 +1683,12 @@ pub enum PatKind<'hir> { /// The `HirId` is the canonical ID for the variable being bound, /// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID), /// which is the pattern ID of the first `x`. + /// + /// The `BindingMode` is what's provided by the user, before match + /// ergonomics are applied. For the binding mode actually in use, + /// see [`TypeckResults::extract_binding_mode`]. + /// + /// [`TypeckResults::extract_binding_mode`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.extract_binding_mode Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>), /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 9b85b2aeec6e..c0617119d67c 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -895,48 +895,44 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx match pat.kind { PatKind::Binding(_, canonical_id, ..) => { debug!("walk_pat: binding place={:?} pat={:?}", place, pat); - if let Some(bm) = self + let bm = self .cx .typeck_results() - .extract_binding_mode(tcx.sess, pat.hir_id, pat.span) - { - debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); + .extract_binding_mode(tcx.sess, pat.hir_id, pat.span); + debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); - // pat_ty: the type of the binding being produced. - let pat_ty = self.node_ty(pat.hir_id)?; - debug!("walk_pat: pat_ty={:?}", pat_ty); + // pat_ty: the type of the binding being produced. + let pat_ty = self.node_ty(pat.hir_id)?; + debug!("walk_pat: pat_ty={:?}", pat_ty); - let def = Res::Local(canonical_id); - if let Ok(ref binding_place) = - self.cat_res(pat.hir_id, pat.span, pat_ty, def) - { - self.delegate.borrow_mut().bind(binding_place, binding_place.hir_id); + let def = Res::Local(canonical_id); + if let Ok(ref binding_place) = self.cat_res(pat.hir_id, pat.span, pat_ty, def) { + self.delegate.borrow_mut().bind(binding_place, binding_place.hir_id); + } + + // Subtle: MIR desugaring introduces immutable borrows for each pattern + // binding when lowering pattern guards to ensure that the guard does not + // modify the scrutinee. + if has_guard { + self.delegate.borrow_mut().borrow( + place, + discr_place.hir_id, + BorrowKind::Immutable, + ); + } + + // It is also a borrow or copy/move of the value being matched. + // In a cases of pattern like `let pat = upvar`, don't use the span + // of the pattern, as this just looks confusing, instead use the span + // of the discriminant. + match bm.0 { + hir::ByRef::Yes(m) => { + let bk = ty::BorrowKind::from_mutbl(m); + self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); } - - // Subtle: MIR desugaring introduces immutable borrows for each pattern - // binding when lowering pattern guards to ensure that the guard does not - // modify the scrutinee. - if has_guard { - self.delegate.borrow_mut().borrow( - place, - discr_place.hir_id, - BorrowKind::Immutable, - ); - } - - // It is also a borrow or copy/move of the value being matched. - // In a cases of pattern like `let pat = upvar`, don't use the span - // of the pattern, as this just looks confusing, instead use the span - // of the discriminant. - match bm.0 { - hir::ByRef::Yes(m) => { - let bk = ty::BorrowKind::from_mutbl(m); - self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); - } - hir::ByRef::No => { - debug!("walk_pat binding consuming pat"); - self.consume_or_copy(place, discr_place.hir_id); - } + hir::ByRef::No => { + debug!("walk_pat binding consuming pat"); + self.consume_or_copy(place, discr_place.hir_id); } } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 3e9ce0e11e40..9857f4434ffe 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -319,11 +319,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { match p.kind { hir::PatKind::Binding(..) => { let typeck_results = self.fcx.typeck_results.borrow(); - if let Some(bm) = - typeck_results.extract_binding_mode(self.tcx().sess, p.hir_id, p.span) - { - self.typeck_results.pat_binding_modes_mut().insert(p.hir_id, bm); - } + let bm = typeck_results.extract_binding_mode(self.tcx().sess, p.hir_id, p.span); + self.typeck_results.pat_binding_modes_mut().insert(p.hir_id, bm); } hir::PatKind::Struct(_, fields, _) => { for field in fields { diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index d4484a16fea4..7d9c23c05f95 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -394,8 +394,10 @@ impl<'tcx> TypeckResults<'tcx> { matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _)))) } - pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option { - self.pat_binding_modes().get(id).copied().or_else(|| { + /// Returns the computed binding mode for a `PatKind::Binding` pattern + /// (after match ergonomics adjustments). + pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> BindingMode { + self.pat_binding_modes().get(id).copied().unwrap_or_else(|| { s.dcx().span_bug(sp, "missing binding mode"); }) } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 7fc25e3617d0..c127cdce7a7b 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1095,7 +1095,6 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind { pat.each_binding_or_first(&mut |_, id, span, _| match cx .typeck_results() .extract_binding_mode(cx.sess(), id, span) - .unwrap() .0 { ByRef::No if !is_copy(cx, cx.typeck_results().node_type(id)) => { From 44cccae02a66821aae3b828d1e08c53b6ff74657 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Thu, 27 Feb 2025 08:21:47 +0000 Subject: [PATCH 376/991] Delete tuple unsizing --- compiler/rustc_feature/src/unstable.rs | 2 - compiler/rustc_hir_typeck/src/coercion.rs | 29 +---- .../src/solve/trait_goals.rs | 49 -------- compiler/rustc_span/src/symbol.rs | 4 +- .../src/traits/project.rs | 6 +- .../src/traits/select/candidate_assembly.rs | 7 -- .../src/traits/select/confirmation.rs | 29 ----- compiler/rustc_ty_utils/src/instance.rs | 3 +- compiler/rustc_type_ir/src/solve/mod.rs | 5 - library/coretests/tests/lib.rs | 1 - library/coretests/tests/ptr.rs | 10 +- .../unsized-tuple-coercion.md | 27 ---- src/tools/miri/tests/pass/unsized.rs | 13 -- .../crates/ide-db/src/generated/lints.rs | 34 ----- tests/debuginfo/unsized.rs | 21 ---- ...sized-args-in-c-abi-issues-94223-115845.rs | 7 +- tests/ui/cast/cast-rfc0401-vtable-kinds.rs | 16 --- .../ui/cast/cast-rfc0401-vtable-kinds.stderr | 2 +- tests/ui/dst/dst-bad-assign-3.rs | 6 +- tests/ui/dst/dst-bad-assign-3.stderr | 4 +- tests/ui/dst/dst-bad-coerce1.rs | 14 --- tests/ui/dst/dst-bad-coerce1.stderr | 32 +---- tests/ui/dst/dst-bad-coerce3.rs | 12 -- tests/ui/dst/dst-bad-coerce3.stderr | 38 +----- tests/ui/dst/dst-bad-coerce4.rs | 10 -- tests/ui/dst/dst-bad-coerce4.stderr | 15 +-- tests/ui/dst/dst-bad-deep-2.rs | 8 +- tests/ui/dst/dst-bad-deep-2.stderr | 18 +-- .../dst-irrefutable-bind.rs | 11 -- tests/ui/dynamically-sized-types/dst-raw.rs | 35 ------ .../dst-trait-tuple.rs | 102 --------------- .../dst-tuple-no-reorder.rs | 26 ---- .../dynamically-sized-types/dst-tuple-sole.rs | 79 ------------ .../dst-tuple-zst-offsets.rs | 22 ---- tests/ui/dynamically-sized-types/dst-tuple.rs | 119 ------------------ .../feature-gate-unsized_tuple_coercion.rs | 2 +- ...feature-gate-unsized_tuple_coercion.stderr | 13 +- tests/ui/impl-trait/unsize_tuple.rs | 15 --- tests/ui/traits/next-solver/unsize-good.rs | 6 - tests/ui/unsized-locals/rust-call.rs | 12 -- tests/ui/unsized-locals/rust-call.stderr | 13 -- .../ui/unsized-locals/unsized-exprs-rpass.rs | 6 +- tests/ui/unsized-locals/unsized-exprs.rs | 7 +- tests/ui/unsized-locals/unsized-exprs.stderr | 16 +-- tests/ui/unsized-locals/unsized-exprs2.rs | 5 +- tests/ui/unsized-locals/unsized-exprs2.stderr | 2 +- tests/ui/unsized/unsized-tuple-impls.rs | 21 ---- 47 files changed, 55 insertions(+), 879 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md delete mode 100644 tests/ui/dynamically-sized-types/dst-trait-tuple.rs delete mode 100644 tests/ui/dynamically-sized-types/dst-tuple-no-reorder.rs delete mode 100644 tests/ui/dynamically-sized-types/dst-tuple-sole.rs delete mode 100644 tests/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs delete mode 100644 tests/ui/dynamically-sized-types/dst-tuple.rs delete mode 100644 tests/ui/impl-trait/unsize_tuple.rs delete mode 100644 tests/ui/unsized-locals/rust-call.rs delete mode 100644 tests/ui/unsized-locals/rust-call.stderr delete mode 100644 tests/ui/unsized/unsized-tuple-impls.rs diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 66c26a541f17..1101843b2188 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -655,8 +655,6 @@ declare_features! ( (internal, unsized_fn_params, "1.49.0", Some(48055)), /// Allows unsized rvalues at arguments and parameters. (incomplete, unsized_locals, "1.30.0", Some(48055)), - /// Allows unsized tuple coercion. - (unstable, unsized_tuple_coercion, "1.20.0", Some(42877)), /// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute. (unstable, used_with_arg, "1.60.0", Some(93798)), /// Allows use of x86 `AMX` target-feature attributes and intrinsics diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index a5108e7a0326..67419fdf1c3e 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -51,15 +51,13 @@ use rustc_infer::traits::{ PredicateObligations, }; use rustc_middle::span_bug; -use rustc_middle::traits::BuiltinImplSource; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion, }; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; -use rustc_session::parse::feature_err; -use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span, sym}; +use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span}; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ @@ -610,8 +608,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target]) )]; - let mut has_unsized_tuple_coercion = false; - // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where // inference might unify those two inner type variables later. @@ -690,31 +686,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // be silent, as it causes a type mismatch later. } - Ok(Some(impl_source)) => { - // Some builtin coercions are still unstable so we detect - // these here and emit a feature error if coercion doesn't fail - // due to another reason. - match impl_source { - traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => { - has_unsized_tuple_coercion = true; - } - _ => {} - } - queue.extend(impl_source.nested_obligations()) - } + Ok(Some(impl_source)) => queue.extend(impl_source.nested_obligations()), } } - if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion() { - feature_err( - &self.tcx.sess, - sym::unsized_tuple_coercion, - self.cause.span, - "unsized tuple coercion is not stable enough for use and is subject to change", - ) - .emit(); - } - Ok(coercion) } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 1665dbb30189..75ebaa68420d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -787,13 +787,6 @@ where ) } - // `(A, B, T)` -> `(A, B, U)` where `T: Unsize` - (ty::Tuple(a_tys), ty::Tuple(b_tys)) - if a_tys.len() == b_tys.len() && !a_tys.is_empty() => - { - result_to_single(ecx.consider_builtin_tuple_unsize(goal, a_tys, b_tys)) - } - _ => vec![], } }) @@ -1085,48 +1078,6 @@ where .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } - /// We generate the following builtin impl for tuples of all sizes. - /// - /// This impl is still unstable and we emit a feature error when it - /// when it is used by a coercion. - /// ```ignore (builtin impl example) - /// impl Unsize<(T, V)> for (T, U) - /// where - /// U: Unsize, - /// {} - /// ``` - fn consider_builtin_tuple_unsize( - &mut self, - goal: Goal, - a_tys: I::Tys, - b_tys: I::Tys, - ) -> Result, NoSolution> { - let cx = self.cx(); - let Goal { predicate: (_a_ty, b_ty), .. } = goal; - - let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap(); - let b_last_ty = b_tys.last().unwrap(); - - // Instantiate just the tail field of B., and require that they're equal. - let unsized_a_ty = Ty::new_tup_from_iter(cx, a_rest_tys.iter().copied().chain([b_last_ty])); - self.eq(goal.param_env, unsized_a_ty, b_ty)?; - - // Similar to ADTs, require that we can unsize the tail. - self.add_goal( - GoalSource::ImplWhereBound, - goal.with( - cx, - ty::TraitRef::new( - cx, - cx.require_lang_item(TraitSolverLangItem::Unsize), - [a_last_ty, b_last_ty], - ), - ), - ); - self.probe_builtin_trait_candidate(BuiltinImplSource::TupleUnsizing) - .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) - } - // Return `Some` if there is an impl (built-in or user provided) that may // hold for the self type of the goal, which for coherence and soundness // purposes must disqualify the built-in auto impl assembled by considering diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 501c9039f2de..14280b433ae8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1,5 +1,4 @@ -//! An "interner" is a data structure that associates values with usize tags and -//! allows bidirectional lookup; i.e., given a value, one can easily find the +//! An "interner" is a data structure that associates values with usize tags and allows bidirectional lookup; i.e., given a value, one can easily find the //! type, and vice versa. use std::hash::{Hash, Hasher}; @@ -2165,7 +2164,6 @@ symbols! { unsized_const_params, unsized_fn_params, unsized_locals, - unsized_tuple_coercion, unstable, unstable_location_reason_default: "this crate is being loaded from the sysroot, an \ unstable location; did you mean to load this crate \ diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index de5aaa5bd972..4d9cf6620d62 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1232,8 +1232,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // why we special case object types. false } - ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) - | ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => { + ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => { // These traits have no associated types. selcx.tcx().dcx().span_delayed_bug( obligation.cause.span, @@ -1325,8 +1324,7 @@ fn confirm_select_candidate<'cx, 'tcx>( } ImplSource::Builtin(BuiltinImplSource::Object { .. }, _) | ImplSource::Param(..) - | ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) - | ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => { + | ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => { // we don't create Select candidates with this kind of resolution span_bug!( obligation.cause.span, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 11b6b826efe5..a8d8003ead6e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -1017,13 +1017,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - // `(.., T)` -> `(.., U)` - (&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => { - if tys_a.len() == tys_b.len() { - candidates.vec.push(BuiltinUnsizeCandidate); - } - } - _ => {} }; } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 32cbb97e314d..a1fd3ea6d092 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -7,7 +7,6 @@ //! [rustc dev guide]: //! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation -use std::iter; use std::ops::ControlFlow; use rustc_ast::Mutability; @@ -1320,34 +1319,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplSource::Builtin(BuiltinImplSource::Misc, nested) } - // `(.., T)` -> `(.., U)` - (&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => { - assert_eq!(tys_a.len(), tys_b.len()); - - // The last field of the tuple has to exist. - let (&a_last, a_mid) = tys_a.split_last().ok_or(Unimplemented)?; - let &b_last = tys_b.last().unwrap(); - - // Check that the source tuple with the target's - // last element is equal to the target. - let new_tuple = - Ty::new_tup_from_iter(tcx, a_mid.iter().copied().chain(iter::once(b_last))); - let InferOk { mut obligations, .. } = self - .infcx - .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::Yes, target, new_tuple) - .map_err(|_| Unimplemented)?; - - // Add a nested `T: Unsize` predicate. - let last_unsize_obligation = obligation.with( - tcx, - ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]), - ); - obligations.push(last_unsize_obligation); - - ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, obligations) - } - _ => bug!("source: {source}, target: {target}"), }) } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index d059d6dcd139..6dc5a9c4a479 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -381,8 +381,7 @@ fn resolve_associated_item<'tcx>( } } traits::ImplSource::Param(..) - | traits::ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) - | traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => None, + | traits::ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => None, }) } diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index a562b751d8a9..6288a4b70cde 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -181,11 +181,6 @@ pub enum BuiltinImplSource { /// /// The index is only used for winnowing. TraitUpcasting(usize), - /// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`. - /// - /// This can be removed when `feature(tuple_unsizing)` is stabilized, since we only - /// use it to detect when unsizing tuples in hir typeck. - TupleUnsizing, } #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 4f21ae5013b6..aa37e71f17b0 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -88,7 +88,6 @@ #![feature(try_find)] #![feature(try_trait_v2)] #![feature(unsize)] -#![feature(unsized_tuple_coercion)] #![feature(unwrap_infallible)] // tidy-alphabetical-end #![allow(internal_features)] diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs index 0c9f9b338b0c..c5fd7f014107 100644 --- a/library/coretests/tests/ptr.rs +++ b/library/coretests/tests/ptr.rs @@ -525,31 +525,24 @@ fn ptr_metadata() { assert_eq!(metadata("foo"), 3_usize); assert_eq!(metadata(&[4, 7][..]), 2_usize); - let dst_tuple: &(bool, [u8]) = &(true, [0x66, 0x6F, 0x6F]); let dst_struct: &Pair = &Pair(true, [0x66, 0x6F, 0x6F]); - assert_eq!(metadata(dst_tuple), 3_usize); assert_eq!(metadata(dst_struct), 3_usize); unsafe { - let dst_tuple: &(bool, str) = std::mem::transmute(dst_tuple); let dst_struct: &Pair = std::mem::transmute(dst_struct); - assert_eq!(&dst_tuple.1, "foo"); assert_eq!(&dst_struct.1, "foo"); - assert_eq!(metadata(dst_tuple), 3_usize); assert_eq!(metadata(dst_struct), 3_usize); } let vtable_1: DynMetadata = metadata(&4_u16 as &dyn Debug); let vtable_2: DynMetadata = metadata(&4_u16 as &dyn Display); let vtable_3: DynMetadata = metadata(&4_u32 as &dyn Display); - let vtable_4: DynMetadata = metadata(&(true, 7_u32) as &(bool, dyn Display)); - let vtable_5: DynMetadata = + let vtable_4: DynMetadata = metadata(&Pair(true, 7_u32) as &Pair); unsafe { let address_1: *const () = std::mem::transmute(vtable_1); let address_2: *const () = std::mem::transmute(vtable_2); let address_3: *const () = std::mem::transmute(vtable_3); let address_4: *const () = std::mem::transmute(vtable_4); - let address_5: *const () = std::mem::transmute(vtable_5); // Different trait => different vtable pointer assert_ne!(address_1, address_2); // Different erased type => different vtable pointer @@ -558,7 +551,6 @@ fn ptr_metadata() { // This is *not guaranteed*, so we skip it in Miri. if !cfg!(miri) { assert_eq!(address_3, address_4); - assert_eq!(address_3, address_5); } } } diff --git a/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md b/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md deleted file mode 100644 index 310c8d962948..000000000000 --- a/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md +++ /dev/null @@ -1,27 +0,0 @@ -# `unsized_tuple_coercion` - -The tracking issue for this feature is: [#42877] - -[#42877]: https://github.com/rust-lang/rust/issues/42877 - ------------------------- - -This is a part of [RFC0401]. According to the RFC, there should be an implementation like this: - -```rust,ignore (partial-example) -impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized {} -``` - -This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this: - -```rust -#![feature(unsized_tuple_coercion)] - -fn main() { - let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]); - let y : &([i32; 3], [i32]) = &x; - assert_eq!(y.1[0], 4); -} -``` - -[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md diff --git a/src/tools/miri/tests/pass/unsized.rs b/src/tools/miri/tests/pass/unsized.rs index 5c6929882f6b..acda3d4ce10f 100644 --- a/src/tools/miri/tests/pass/unsized.rs +++ b/src/tools/miri/tests/pass/unsized.rs @@ -1,22 +1,10 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows -#![feature(unsized_tuple_coercion)] #![feature(unsized_fn_params)] #![feature(custom_mir, core_intrinsics)] use std::mem; -fn unsized_tuple() { - let x: &(i32, i32, [i32]) = &(0, 1, [2, 3]); - let y: &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]); - let mut a = [y, x]; - a.sort(); - assert_eq!(a, [x, y]); - - assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]"); - assert_eq!(mem::size_of_val(x), 16); -} - fn unsized_params() { pub fn f0(_f: dyn FnOnce()) {} pub fn f1(_s: str) {} @@ -56,7 +44,6 @@ fn unsized_field_projection() { } fn main() { - unsized_tuple(); unsized_params(); unsized_field_projection(); } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index ed9d6c67501e..9c983e7c4a6f 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs @@ -12311,40 +12311,6 @@ fn main() { ``` will unnecessarily extend the stack frame. -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "unsized_tuple_coercion", - description: r##"# `unsized_tuple_coercion` - -The tracking issue for this feature is: [#42877] - -[#42877]: https://github.com/rust-lang/rust/issues/42877 - ------------------------- - -This is a part of [RFC0401]. According to the RFC, there should be an implementation like this: - -```rust,ignore (partial-example) -impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized {} -``` - -This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this: - -```rust -#![feature(unsized_tuple_coercion)] - -fn main() { - let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]); - let y : &([i32; 3], [i32]) = &x; - assert_eq!(y.1[0], 4); -} -``` - -[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md "##, default_severity: Severity::Allow, warn_since: None, diff --git a/tests/debuginfo/unsized.rs b/tests/debuginfo/unsized.rs index acfe511be7c0..17c5e463fbac 100644 --- a/tests/debuginfo/unsized.rs +++ b/tests/debuginfo/unsized.rs @@ -18,12 +18,6 @@ // gdb-command:print _box // gdb-check:$4 = alloc::boxed::Box, alloc::alloc::Global> {pointer: [...], vtable: [...]} -// gdb-command:print tuple_slice -// gdb-check:$5 = &(i32, i32, [i32]) {data_ptr: [...], length: 2} - -// gdb-command:print tuple_dyn -// gdb-check:$6 = &(i32, i32, dyn core::fmt::Debug) {pointer: [...], vtable: [...]} - // === CDB TESTS =================================================================================== // cdb-command: g @@ -48,17 +42,6 @@ // cdb-check:[+0x000] pointer : 0x[...] [Type: unsized::Foo > *] // cdb-check:[...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[4]] -// cdb-command:dx tuple_slice -// cdb-check:tuple_slice [Type: ref$ > >] -// cdb-check: [+0x000] data_ptr : 0x[...] [Type: tuple$ > *] -// cdb-check: [...] length : 0x2 [Type: unsigned [...]int[...] - -// cdb-command:dx tuple_dyn -// cdb-check:tuple_dyn [Type: ref$ > >] -// cdb-check: [+0x000] pointer : 0x[...] [Type: tuple$ > *] -// cdb-check: [...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[4]] - -#![feature(unsized_tuple_coercion)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] @@ -77,10 +60,6 @@ fn main() { let c: &Foo = &Foo { value: 7i32 }; let _box: Box> = Box::new(Foo { value: 8i32 }); - // Also check unsized tuples - let tuple_slice: &(i32, i32, [i32]) = &(0, 1, [2, 3]); - let tuple_dyn: &(i32, i32, dyn std::fmt::Debug) = &(0, 1, &3u64); - zzz(); // #break } diff --git a/tests/ui/abi/unsized-args-in-c-abi-issues-94223-115845.rs b/tests/ui/abi/unsized-args-in-c-abi-issues-94223-115845.rs index 376630b8d33f..7d21307e1b2d 100644 --- a/tests/ui/abi/unsized-args-in-c-abi-issues-94223-115845.rs +++ b/tests/ui/abi/unsized-args-in-c-abi-issues-94223-115845.rs @@ -1,9 +1,10 @@ //@ check-pass #![allow(improper_ctypes_definitions)] -#![feature(unsized_tuple_coercion)] #![feature(unsized_fn_params)] #![crate_type = "lib"] +struct Fat(T); + // Check that computing the fn abi for `bad`, with a external ABI fn ptr that is not FFI-safe, does // not ICE. @@ -19,12 +20,12 @@ pub extern "C" fn declare_bad(_x: str) {} pub extern "system" fn declare_more_bad(f: dyn FnOnce()) { } -fn make_bad() -> extern "C" fn(([u8],)) { +fn make_bad() -> extern "C" fn(Fat<[u8]>) { todo!() } pub fn call_bad() { let f = make_bad(); - let slice: Box<([u8],)> = Box::new(([1; 8],)); + let slice: Box> = Box::new(Fat([1; 8])); f(*slice); } diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs index 5704a33cc870..78f6dca18185 100644 --- a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs +++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs @@ -2,8 +2,6 @@ // Check that you can cast between different pointers to trait objects // whose vtable have the same kind (both lengths, or both trait pointers). -#![feature(unsized_tuple_coercion)] - trait Bar { //~ WARN trait `Bar` is never used fn bar(&self) { println!("Bar!"); } } @@ -19,10 +17,6 @@ fn foo_to_bar(u: *const FooS) -> *const BarS { u as *const BarS } -fn tuple_i32_to_u32(u: *const (i32, T)) -> *const (u32, T) { - u as *const (u32, T) -} - fn main() { let s = FooS([0,1,2]); @@ -31,14 +25,4 @@ fn main() { let bar_ref : *const BarS<[u32]> = foo_to_bar(u); let z : &BarS<[u32]> = unsafe{&*bar_ref}; assert_eq!(&z.0, &[0,1,2]); - - // this assumes that tuple reprs for (i32, _) and (u32, _) are - // the same. - let s = (0i32, [0, 1, 2]); - let u: &(i32, [u8]) = &s; - let u: *const (i32, [u8]) = u; - let u_u32 : *const (u32, [u8]) = tuple_i32_to_u32(u); - unsafe { - assert_eq!(&(*u_u32).1, &[0, 1, 2]); - } } diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr index 4f57e2e7df75..01277fd632e1 100644 --- a/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr +++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr @@ -1,5 +1,5 @@ warning: trait `Bar` is never used - --> $DIR/cast-rfc0401-vtable-kinds.rs:7:7 + --> $DIR/cast-rfc0401-vtable-kinds.rs:5:7 | LL | trait Bar { | ^^^ diff --git a/tests/ui/dst/dst-bad-assign-3.rs b/tests/ui/dst/dst-bad-assign-3.rs index d199864d99c2..f96ecf7762c0 100644 --- a/tests/ui/dst/dst-bad-assign-3.rs +++ b/tests/ui/dst/dst-bad-assign-3.rs @@ -1,8 +1,6 @@ // Forbid assignment into a dynamically sized type. -#![feature(unsized_tuple_coercion)] - -type Fat = (isize, &'static str, T); +struct Fat(isize, &'static str, T); #[derive(PartialEq,Eq)] struct Bar; @@ -28,7 +26,7 @@ impl ToBar for Bar1 { pub fn main() { // Assignment. - let f5: &mut Fat = &mut (5, "some str", Bar1 {f :42}); + let f5: &mut Fat = &mut Fat(5, "some str", Bar1 {f :42}); let z: Box = Box::new(Bar1 {f: 36}); f5.2 = Bar1 {f: 36}; //~^ ERROR mismatched types diff --git a/tests/ui/dst/dst-bad-assign-3.stderr b/tests/ui/dst/dst-bad-assign-3.stderr index 007f6b898bee..4aa1677e7517 100644 --- a/tests/ui/dst/dst-bad-assign-3.stderr +++ b/tests/ui/dst/dst-bad-assign-3.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/dst-bad-assign-3.rs:33:12 + --> $DIR/dst-bad-assign-3.rs:31:12 | LL | f5.2 = Bar1 {f: 36}; | ---- ^^^^^^^^^^^^ expected `dyn ToBar`, found `Bar1` @@ -11,7 +11,7 @@ LL | f5.2 = Bar1 {f: 36}; = help: `Bar1` implements `ToBar` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time - --> $DIR/dst-bad-assign-3.rs:33:5 + --> $DIR/dst-bad-assign-3.rs:31:5 | LL | f5.2 = Bar1 {f: 36}; | ^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/dst/dst-bad-coerce1.rs b/tests/ui/dst/dst-bad-coerce1.rs index 7ef237e39e36..5ee0bfa9fbfb 100644 --- a/tests/ui/dst/dst-bad-coerce1.rs +++ b/tests/ui/dst/dst-bad-coerce1.rs @@ -1,7 +1,5 @@ // Attempt to change the type as well as unsizing. -#![feature(unsized_tuple_coercion)] - struct Fat { ptr: T } @@ -21,16 +19,4 @@ pub fn main() { let f2: &Fat = &f1; let f3: &Fat = f2; //~^ ERROR `Foo: Bar` is not satisfied - - // Tuple with a vec of isize. - let f1 = ([1, 2, 3],); - let f2: &([isize; 3],) = &f1; - let f3: &([usize],) = f2; - //~^ ERROR mismatched types - - // Tuple with a trait. - let f1 = (Foo,); - let f2: &(Foo,) = &f1; - let f3: &(dyn Bar,) = f2; - //~^ ERROR `Foo: Bar` is not satisfied } diff --git a/tests/ui/dst/dst-bad-coerce1.stderr b/tests/ui/dst/dst-bad-coerce1.stderr index 455d15e935fa..68456b8642c7 100644 --- a/tests/ui/dst/dst-bad-coerce1.stderr +++ b/tests/ui/dst/dst-bad-coerce1.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/dst-bad-coerce1.rs:16:29 + --> $DIR/dst-bad-coerce1.rs:14:29 | LL | let f3: &Fat<[usize]> = f2; | ------------- ^^ expected `&Fat<[usize]>`, found `&Fat<[isize; 3]>` @@ -10,43 +10,19 @@ LL | let f3: &Fat<[usize]> = f2; found reference `&Fat<[isize; 3]>` error[E0277]: the trait bound `Foo: Bar` is not satisfied - --> $DIR/dst-bad-coerce1.rs:22:29 + --> $DIR/dst-bad-coerce1.rs:20:29 | LL | let f3: &Fat = f2; | ^^ the trait `Bar` is not implemented for `Foo` | help: this trait has no implementations, consider adding one - --> $DIR/dst-bad-coerce1.rs:10:1 + --> $DIR/dst-bad-coerce1.rs:8:1 | LL | trait Bar { fn bar(&self) {} } | ^^^^^^^^^ = note: required for the cast from `&Fat` to `&Fat` -error[E0308]: mismatched types - --> $DIR/dst-bad-coerce1.rs:28:27 - | -LL | let f3: &([usize],) = f2; - | ----------- ^^ expected `&([usize],)`, found `&([isize; 3],)` - | | - | expected due to this - | - = note: expected reference `&([usize],)` - found reference `&([isize; 3],)` - -error[E0277]: the trait bound `Foo: Bar` is not satisfied - --> $DIR/dst-bad-coerce1.rs:34:27 - | -LL | let f3: &(dyn Bar,) = f2; - | ^^ the trait `Bar` is not implemented for `Foo` - | -help: this trait has no implementations, consider adding one - --> $DIR/dst-bad-coerce1.rs:10:1 - | -LL | trait Bar { fn bar(&self) {} } - | ^^^^^^^^^ - = note: required for the cast from `&(Foo,)` to `&(dyn Bar,)` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/dst/dst-bad-coerce3.rs b/tests/ui/dst/dst-bad-coerce3.rs index fd5ee3b57bb4..508f009c33e4 100644 --- a/tests/ui/dst/dst-bad-coerce3.rs +++ b/tests/ui/dst/dst-bad-coerce3.rs @@ -1,7 +1,5 @@ // Attempt to extend the lifetime as well as unsizing. -#![feature(unsized_tuple_coercion)] - struct Fat { ptr: T } @@ -20,16 +18,6 @@ fn baz<'a>() { let f1 = Fat { ptr: Foo }; let f2: &Fat = &f1; //~ ERROR `f1` does not live long enough let f3: &'a Fat = f2; - - // Tuple with a vec of ints. - let f1 = ([1, 2, 3],); - let f2: &([isize; 3],) = &f1; //~ ERROR `f1` does not live long enough - let f3: &'a ([isize],) = f2; - - // Tuple with a trait. - let f1 = (Foo,); - let f2: &(Foo,) = &f1; //~ ERROR `f1` does not live long enough - let f3: &'a (dyn Bar,) = f2; } pub fn main() { diff --git a/tests/ui/dst/dst-bad-coerce3.stderr b/tests/ui/dst/dst-bad-coerce3.stderr index 1254250bcbd8..177535b8c7c7 100644 --- a/tests/ui/dst/dst-bad-coerce3.stderr +++ b/tests/ui/dst/dst-bad-coerce3.stderr @@ -1,5 +1,5 @@ error[E0597]: `f1` does not live long enough - --> $DIR/dst-bad-coerce3.rs:16:32 + --> $DIR/dst-bad-coerce3.rs:14:32 | LL | fn baz<'a>() { | -- lifetime `'a` defined here @@ -15,7 +15,7 @@ LL | } | - `f1` dropped here while still borrowed error[E0597]: `f1` does not live long enough - --> $DIR/dst-bad-coerce3.rs:21:25 + --> $DIR/dst-bad-coerce3.rs:19:25 | LL | fn baz<'a>() { | -- lifetime `'a` defined here @@ -26,41 +26,9 @@ LL | let f2: &Fat = &f1; | ^^^ borrowed value does not live long enough LL | let f3: &'a Fat = f2; | ---------------- type annotation requires that `f1` is borrowed for `'a` -... LL | } | - `f1` dropped here while still borrowed -error[E0597]: `f1` does not live long enough - --> $DIR/dst-bad-coerce3.rs:26:30 - | -LL | fn baz<'a>() { - | -- lifetime `'a` defined here -... -LL | let f1 = ([1, 2, 3],); - | -- binding `f1` declared here -LL | let f2: &([isize; 3],) = &f1; - | ^^^ borrowed value does not live long enough -LL | let f3: &'a ([isize],) = f2; - | -------------- type annotation requires that `f1` is borrowed for `'a` -... -LL | } - | - `f1` dropped here while still borrowed - -error[E0597]: `f1` does not live long enough - --> $DIR/dst-bad-coerce3.rs:31:23 - | -LL | fn baz<'a>() { - | -- lifetime `'a` defined here -... -LL | let f1 = (Foo,); - | -- binding `f1` declared here -LL | let f2: &(Foo,) = &f1; - | ^^^ borrowed value does not live long enough -LL | let f3: &'a (dyn Bar,) = f2; - | -------------- type annotation requires that `f1` is borrowed for `'a` -LL | } - | - `f1` dropped here while still borrowed - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/dst/dst-bad-coerce4.rs b/tests/ui/dst/dst-bad-coerce4.rs index 9f297915e58c..25410aa4fac7 100644 --- a/tests/ui/dst/dst-bad-coerce4.rs +++ b/tests/ui/dst/dst-bad-coerce4.rs @@ -1,7 +1,5 @@ // Attempt to coerce from unsized to sized. -#![feature(unsized_tuple_coercion)] - struct Fat { ptr: T } @@ -14,12 +12,4 @@ pub fn main() { //~| expected `&Fat<[isize; 3]>`, found `&Fat<[isize]>` //~| expected reference `&Fat<[isize; 3]>` //~| found reference `&Fat<[isize]>` - - // Tuple with a vec of isizes. - let f1: &([isize],) = &([1, 2, 3],); - let f2: &([isize; 3],) = f1; - //~^ ERROR mismatched types - //~| expected `&([isize; 3],)`, found `&([isize],)` - //~| expected reference `&([isize; 3],)` - //~| found reference `&([isize],)` } diff --git a/tests/ui/dst/dst-bad-coerce4.stderr b/tests/ui/dst/dst-bad-coerce4.stderr index 46e7dba817c8..5c14c0bfedd4 100644 --- a/tests/ui/dst/dst-bad-coerce4.stderr +++ b/tests/ui/dst/dst-bad-coerce4.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/dst-bad-coerce4.rs:12:32 + --> $DIR/dst-bad-coerce4.rs:10:32 | LL | let f2: &Fat<[isize; 3]> = f1; | ---------------- ^^ expected `&Fat<[isize; 3]>`, found `&Fat<[isize]>` @@ -9,17 +9,6 @@ LL | let f2: &Fat<[isize; 3]> = f1; = note: expected reference `&Fat<[isize; 3]>` found reference `&Fat<[isize]>` -error[E0308]: mismatched types - --> $DIR/dst-bad-coerce4.rs:20:30 - | -LL | let f2: &([isize; 3],) = f1; - | -------------- ^^ expected `&([isize; 3],)`, found `&([isize],)` - | | - | expected due to this - | - = note: expected reference `&([isize; 3],)` - found reference `&([isize],)` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/dst/dst-bad-deep-2.rs b/tests/ui/dst/dst-bad-deep-2.rs index e587399135d3..76d357513697 100644 --- a/tests/ui/dst/dst-bad-deep-2.rs +++ b/tests/ui/dst/dst-bad-deep-2.rs @@ -3,11 +3,11 @@ // because it would require stack allocation of an unsized temporary (*g in the // test). -#![feature(unsized_tuple_coercion)] +struct Fat(T); pub fn main() { - let f: ([isize; 3],) = ([5, 6, 7],); - let g: &([isize],) = &f; - let h: &(([isize],),) = &(*g,); + let f: Fat<[isize; 3]> = Fat([5, 6, 7]); + let g: &Fat<[isize]> = &f; + let h: &Fat> = &Fat(*g); //~^ ERROR the size for values of type } diff --git a/tests/ui/dst/dst-bad-deep-2.stderr b/tests/ui/dst/dst-bad-deep-2.stderr index c7e9854340f0..de3f71d206fb 100644 --- a/tests/ui/dst/dst-bad-deep-2.stderr +++ b/tests/ui/dst/dst-bad-deep-2.stderr @@ -1,13 +1,17 @@ error[E0277]: the size for values of type `[isize]` cannot be known at compilation time - --> $DIR/dst-bad-deep-2.rs:11:30 + --> $DIR/dst-bad-deep-2.rs:11:38 | -LL | let h: &(([isize],),) = &(*g,); - | ^^^^^ doesn't have a size known at compile-time +LL | let h: &Fat> = &Fat(*g); + | ^^ doesn't have a size known at compile-time | - = help: within `(([isize],),)`, the trait `Sized` is not implemented for `[isize]` - = note: required because it appears within the type `([isize],)` - = note: required because it appears within the type `(([isize],),)` - = note: tuples must have a statically known size to be initialized + = help: within `Fat<[isize]>`, the trait `Sized` is not implemented for `[isize]` +note: required because it appears within the type `Fat<[isize]>` + --> $DIR/dst-bad-deep-2.rs:6:8 + | +LL | struct Fat(T); + | ^^^ + = note: all function arguments must have a statically known size + = help: unsized fn params are gated as an unstable feature error: aborting due to 1 previous error diff --git a/tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs b/tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs index 5e352e930d82..f4576229864b 100644 --- a/tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs +++ b/tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs @@ -1,5 +1,4 @@ //@ run-pass -#![feature(unsized_tuple_coercion)] struct Test(T); @@ -14,14 +13,4 @@ fn main() { let slice = &[1,2,3]; let x = Test(&slice); let Test(&_slice) = x; - - - let x = (10, [1,2,3]); - let x : &(i32, [i32]) = &x; - - let & ref _y = x; - - let slice = &[1,2,3]; - let x = (10, &slice); - let (_, &_slice) = x; } diff --git a/tests/ui/dynamically-sized-types/dst-raw.rs b/tests/ui/dynamically-sized-types/dst-raw.rs index c32ee67dab9f..111848c5a7f0 100644 --- a/tests/ui/dynamically-sized-types/dst-raw.rs +++ b/tests/ui/dynamically-sized-types/dst-raw.rs @@ -1,9 +1,6 @@ //@ run-pass // Test DST raw pointers - -#![feature(unsized_tuple_coercion)] - trait Trait { fn foo(&self) -> isize; } @@ -38,14 +35,6 @@ pub fn main() { }; assert_eq!(r, 42); - // raw DST tuple - let p = (A { f: 42 },); - let o: *const (dyn Trait,) = &p; - let r = unsafe { - (&*o).0.foo() - }; - assert_eq!(r, 42); - // raw slice let a: *const [_] = &[1, 2, 3]; unsafe { @@ -73,15 +62,6 @@ pub fn main() { assert_eq!(len, 3); } - // raw DST tuple with slice - let c: *const ([_],) = &([1, 2, 3],); - unsafe { - let b = (&*c).0[0]; - assert_eq!(b, 1); - let len = (&*c).0.len(); - assert_eq!(len, 3); - } - // all of the above with *mut let mut x = A { f: 42 }; let z: *mut dyn Trait = &mut x; @@ -97,13 +77,6 @@ pub fn main() { }; assert_eq!(r, 42); - let mut p = (A { f: 42 },); - let o: *mut (dyn Trait,) = &mut p; - let r = unsafe { - (&*o).0.foo() - }; - assert_eq!(r, 42); - let a: *mut [_] = &mut [1, 2, 3]; unsafe { let b = (*a)[2]; @@ -127,12 +100,4 @@ pub fn main() { let len = (&*c).f.len(); assert_eq!(len, 3); } - - let c: *mut ([_],) = &mut ([1, 2, 3],); - unsafe { - let b = (&*c).0[0]; - assert_eq!(b, 1); - let len = (&*c).0.len(); - assert_eq!(len, 3); - } } diff --git a/tests/ui/dynamically-sized-types/dst-trait-tuple.rs b/tests/ui/dynamically-sized-types/dst-trait-tuple.rs deleted file mode 100644 index 6ab8829859bf..000000000000 --- a/tests/ui/dynamically-sized-types/dst-trait-tuple.rs +++ /dev/null @@ -1,102 +0,0 @@ -//@ run-pass -#![allow(type_alias_bounds)] - -#![allow(unused_features)] -#![feature(unsized_tuple_coercion)] - -type Fat = (isize, &'static str, T); - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -struct Bar; - -#[derive(Copy, Clone, PartialEq, Eq)] -struct Bar1 { - f: isize -} - -trait ToBar { - fn to_bar(&self) -> Bar; - fn to_val(&self) -> isize; -} - -impl ToBar for Bar { - fn to_bar(&self) -> Bar { - *self - } - fn to_val(&self) -> isize { - 0 - } -} -impl ToBar for Bar1 { - fn to_bar(&self) -> Bar { - Bar - } - fn to_val(&self) -> isize { - self.f - } -} - -// x is a fat pointer -fn foo(x: &Fat) { - assert_eq!(x.0, 5); - assert_eq!(x.1, "some str"); - assert_eq!(x.2.to_bar(), Bar); - assert_eq!(x.2.to_val(), 42); - - let y = &x.2; - assert_eq!(y.to_bar(), Bar); - assert_eq!(y.to_val(), 42); -} - -fn bar(x: &dyn ToBar) { - assert_eq!(x.to_bar(), Bar); - assert_eq!(x.to_val(), 42); -} - -fn baz(x: &Fat>) { - assert_eq!(x.0, 5); - assert_eq!(x.1, "some str"); - assert_eq!((x.2).0, 8); - assert_eq!((x.2).1, "deep str"); - assert_eq!((x.2).2.to_bar(), Bar); - assert_eq!((x.2).2.to_val(), 42); - - let y = &(x.2).2; - assert_eq!(y.to_bar(), Bar); - assert_eq!(y.to_val(), 42); - -} - -pub fn main() { - let f1 = (5, "some str", Bar1 {f :42}); - foo(&f1); - let f2 = &f1; - foo(f2); - let f3: &Fat = f2; - foo(f3); - let f4: &Fat = &f1; - foo(f4); - let f5: &Fat = &(5, "some str", Bar1 {f :42}); - foo(f5); - - // Zero size object. - let f6: &Fat = &(5, "some str", Bar); - assert_eq!(f6.2.to_bar(), Bar); - - // &* - // - let f7: Box = Box::new(Bar1 {f :42}); - bar(&*f7); - - // Deep nesting - let f1 = (5, "some str", (8, "deep str", Bar1 {f :42})); - baz(&f1); - let f2 = &f1; - baz(f2); - let f3: &Fat> = f2; - baz(f3); - let f4: &Fat> = &f1; - baz(f4); - let f5: &Fat> = &(5, "some str", (8, "deep str", Bar1 {f :42})); - baz(f5); -} diff --git a/tests/ui/dynamically-sized-types/dst-tuple-no-reorder.rs b/tests/ui/dynamically-sized-types/dst-tuple-no-reorder.rs deleted file mode 100644 index ad48d88e4807..000000000000 --- a/tests/ui/dynamically-sized-types/dst-tuple-no-reorder.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ run-pass - -#![feature(unsized_tuple_coercion)] - -// Ensure that unsizable fields that might be accessed don't get reordered - -fn nonzero_size() { - let sized: (u8, [u32; 2]) = (123, [456, 789]); - let unsize: &(u8, [u32]) = &sized; - assert_eq!(unsize.0, 123); - assert_eq!(unsize.1.len(), 2); - assert_eq!(unsize.1[0], 456); - assert_eq!(unsize.1[1], 789); -} - -fn zst() { - let sized: (u8, [u32; 0]) = (123, []); - let unsize: &(u8, [u32]) = &sized; - assert_eq!(unsize.0, 123); - assert_eq!(unsize.1.len(), 0); -} - -pub fn main() { - nonzero_size(); - zst(); -} diff --git a/tests/ui/dynamically-sized-types/dst-tuple-sole.rs b/tests/ui/dynamically-sized-types/dst-tuple-sole.rs deleted file mode 100644 index dc3363b9bde3..000000000000 --- a/tests/ui/dynamically-sized-types/dst-tuple-sole.rs +++ /dev/null @@ -1,79 +0,0 @@ -//@ run-pass -#![allow(stable_features)] -#![allow(type_alias_bounds)] - -// As dst-tuple.rs, but the unsized field is the only field in the tuple. - - -#![feature(unsized_tuple_coercion)] - -type Fat = (T,); - -// x is a fat pointer -fn foo(x: &Fat<[isize]>) { - let y = &x.0; - assert_eq!(x.0.len(), 3); - assert_eq!(y[0], 1); - assert_eq!(x.0[1], 2); -} - -fn foo2(x: &Fat<[T]>) { - let y = &x.0; - let bar = Bar; - assert_eq!(x.0.len(), 3); - assert_eq!(y[0].to_bar(), bar); - assert_eq!(x.0[1].to_bar(), bar); -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -struct Bar; - -trait ToBar { - fn to_bar(&self) -> Bar; -} - -impl ToBar for Bar { - fn to_bar(&self) -> Bar { - *self - } -} - -pub fn main() { - // With a vec of ints. - let f1 = ([1, 2, 3],); - foo(&f1); - let f2 = &f1; - foo(f2); - let f3: &Fat<[isize]> = f2; - foo(f3); - let f4: &Fat<[isize]> = &f1; - foo(f4); - let f5: &Fat<[isize]> = &([1, 2, 3],); - foo(f5); - - // With a vec of Bars. - let bar = Bar; - let f1 = ([bar, bar, bar],); - foo2(&f1); - let f2 = &f1; - foo2(f2); - let f3: &Fat<[Bar]> = f2; - foo2(f3); - let f4: &Fat<[Bar]> = &f1; - foo2(f4); - let f5: &Fat<[Bar]> = &([bar, bar, bar],); - foo2(f5); - - // Assignment. - let f5: &mut Fat<[isize]> = &mut ([1, 2, 3],); - f5.0[1] = 34; - assert_eq!(f5.0[0], 1); - assert_eq!(f5.0[1], 34); - assert_eq!(f5.0[2], 3); - - // Zero size vec. - let f5: &Fat<[isize]> = &([],); - assert!(f5.0.is_empty()); - let f5: &Fat<[Bar]> = &([],); - assert!(f5.0.is_empty()); -} diff --git a/tests/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs b/tests/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs deleted file mode 100644 index b4ee0fb4070d..000000000000 --- a/tests/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ run-pass - -#![feature(unsized_tuple_coercion)] - -// Check that we do not change the offsets of ZST fields when unsizing - -fn scalar_layout() { - let sized: &(u8, [(); 13]) = &(123, [(); 13]); - let unsize: &(u8, [()]) = sized; - assert_eq!(sized.1.as_ptr(), unsize.1.as_ptr()); -} - -fn scalarpair_layout() { - let sized: &(u8, u16, [(); 13]) = &(123, 456, [(); 13]); - let unsize: &(u8, u16, [()]) = sized; - assert_eq!(sized.2.as_ptr(), unsize.2.as_ptr()); -} - -pub fn main() { - scalar_layout(); - scalarpair_layout(); -} diff --git a/tests/ui/dynamically-sized-types/dst-tuple.rs b/tests/ui/dynamically-sized-types/dst-tuple.rs deleted file mode 100644 index 52fc69f7809f..000000000000 --- a/tests/ui/dynamically-sized-types/dst-tuple.rs +++ /dev/null @@ -1,119 +0,0 @@ -//@ run-pass -#![allow(type_alias_bounds)] - -#![feature(unsized_tuple_coercion)] - -type Fat = (isize, &'static str, T); - -// x is a fat pointer -fn foo(x: &Fat<[isize]>) { - let y = &x.2; - assert_eq!(x.2.len(), 3); - assert_eq!(y[0], 1); - assert_eq!(x.2[1], 2); - assert_eq!(x.0, 5); - assert_eq!(x.1, "some str"); -} - -fn foo2(x: &Fat<[T]>) { - let y = &x.2; - let bar = Bar; - assert_eq!(x.2.len(), 3); - assert_eq!(y[0].to_bar(), bar); - assert_eq!(x.2[1].to_bar(), bar); - assert_eq!(x.0, 5); - assert_eq!(x.1, "some str"); -} - -fn foo3(x: &Fat>) { - let y = &(x.2).2; - assert_eq!(x.0, 5); - assert_eq!(x.1, "some str"); - assert_eq!((x.2).0, 8); - assert_eq!((x.2).1, "deep str"); - assert_eq!((x.2).2.len(), 3); - assert_eq!(y[0], 1); - assert_eq!((x.2).2[1], 2); -} - - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -struct Bar; - -trait ToBar { - fn to_bar(&self) -> Bar; -} - -impl ToBar for Bar { - fn to_bar(&self) -> Bar { - *self - } -} - -pub fn main() { - // With a vec of ints. - let f1 = (5, "some str", [1, 2, 3]); - foo(&f1); - let f2 = &f1; - foo(f2); - let f3: &Fat<[isize]> = f2; - foo(f3); - let f4: &Fat<[isize]> = &f1; - foo(f4); - let f5: &Fat<[isize]> = &(5, "some str", [1, 2, 3]); - foo(f5); - - // With a vec of Bars. - let bar = Bar; - let f1 = (5, "some str", [bar, bar, bar]); - foo2(&f1); - let f2 = &f1; - foo2(f2); - let f3: &Fat<[Bar]> = f2; - foo2(f3); - let f4: &Fat<[Bar]> = &f1; - foo2(f4); - let f5: &Fat<[Bar]> = &(5, "some str", [bar, bar, bar]); - foo2(f5); - - // Assignment. - let f5: &mut Fat<[isize]> = &mut (5, "some str", [1, 2, 3]); - f5.2[1] = 34; - assert_eq!(f5.2[0], 1); - assert_eq!(f5.2[1], 34); - assert_eq!(f5.2[2], 3); - - // Zero size vec. - let f5: &Fat<[isize]> = &(5, "some str", []); - assert!(f5.2.is_empty()); - let f5: &Fat<[Bar]> = &(5, "some str", []); - assert!(f5.2.is_empty()); - - // Deeply nested. - let f1 = (5, "some str", (8, "deep str", [1, 2, 3])); - foo3(&f1); - let f2 = &f1; - foo3(f2); - let f3: &Fat> = f2; - foo3(f3); - let f4: &Fat> = &f1; - foo3(f4); - let f5: &Fat> = &(5, "some str", (8, "deep str", [1, 2, 3])); - foo3(f5); - - // Box. - let f1 = Box::new([1, 2, 3]); - assert_eq!((*f1)[1], 2); - let f2: Box<[isize]> = f1; - assert_eq!((*f2)[1], 2); - - // Nested Box. - let f1 : Box> = Box::new((5, "some str", [1, 2, 3])); - foo(&*f1); - let f2 : Box> = f1; - foo(&*f2); - - let f3 : Box> = - Box::>::new((5, "some str", [1, 2, 3])); - foo(&*f3); -} diff --git a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs index c3d62a231e5e..b5fbcc9ccf8c 100644 --- a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs +++ b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs @@ -1,4 +1,4 @@ fn main() { let _ : &(dyn Send,) = &((),); - //~^ ERROR unsized tuple coercion is not stable enough + //~^ ERROR 2:28: 2:34: mismatched types [E0308] } diff --git a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr index 251928658df2..12847bd3c0df 100644 --- a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr +++ b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr @@ -1,13 +1,14 @@ -error[E0658]: unsized tuple coercion is not stable enough for use and is subject to change +error[E0308]: mismatched types --> $DIR/feature-gate-unsized_tuple_coercion.rs:2:28 | LL | let _ : &(dyn Send,) = &((),); - | ^^^^^^ + | ------------ ^^^^^^ expected `&(dyn Send,)`, found `&((),)` + | | + | expected due to this | - = note: see issue #42877 for more information - = help: add `#![feature(unsized_tuple_coercion)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: expected reference `&(dyn Send,)` + found reference `&((),)` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/unsize_tuple.rs b/tests/ui/impl-trait/unsize_tuple.rs deleted file mode 100644 index 2678564f0e86..000000000000 --- a/tests/ui/impl-trait/unsize_tuple.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! Test that we allow unsizing `([Opaque; N],)` to `([Concrete],)`. - -//@check-pass - -#![feature(unsized_tuple_coercion)] - -fn hello() -> ([impl Sized; 2],) { - if false { - let x = hello(); - let _: &([i32],) = &x; - } - todo!() -} - -fn main() {} diff --git a/tests/ui/traits/next-solver/unsize-good.rs b/tests/ui/traits/next-solver/unsize-good.rs index 4456e4f21884..f3d8b08e693c 100644 --- a/tests/ui/traits/next-solver/unsize-good.rs +++ b/tests/ui/traits/next-solver/unsize-good.rs @@ -1,8 +1,6 @@ //@ compile-flags: -Znext-solver //@ check-pass -#![feature(unsized_tuple_coercion)] - trait Foo {} impl Foo for i32 {} @@ -15,10 +13,6 @@ fn main() { let y = [1, 2, 3]; let _: &[i32] = &y; - // Tuple unsizing - let hi = (1i32,); - let _: &(dyn Foo,) = &hi; - // Dropping auto traits let a: &(dyn Foo + Send) = &1; let _: &dyn Foo = a; diff --git a/tests/ui/unsized-locals/rust-call.rs b/tests/ui/unsized-locals/rust-call.rs deleted file mode 100644 index ff4075aa4c03..000000000000 --- a/tests/ui/unsized-locals/rust-call.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(unsized_tuple_coercion)] -#![feature(unboxed_closures)] -#![feature(unsized_fn_params)] - -fn bad() -> extern "rust-call" fn(([u8],)) { todo!() } - -fn main() { - let f = bad(); - let slice: Box<([u8],)> = Box::new(([1; 8],)); - f(*slice); - //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time -} diff --git a/tests/ui/unsized-locals/rust-call.stderr b/tests/ui/unsized-locals/rust-call.stderr deleted file mode 100644 index 9eb0f3dabcca..000000000000 --- a/tests/ui/unsized-locals/rust-call.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/rust-call.rs:10:7 - | -LL | f(*slice); - | ^^^^^^ doesn't have a size known at compile-time - | - = help: within `([u8],)`, the trait `Sized` is not implemented for `[u8]` - = note: required because it appears within the type `([u8],)` - = note: argument required to be sized due to `extern "rust-call"` ABI - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unsized-locals/unsized-exprs-rpass.rs b/tests/ui/unsized-locals/unsized-exprs-rpass.rs index a5aada20d3eb..861583efc401 100644 --- a/tests/ui/unsized-locals/unsized-exprs-rpass.rs +++ b/tests/ui/unsized-locals/unsized-exprs-rpass.rs @@ -1,6 +1,6 @@ //@ run-pass #![allow(incomplete_features, unused_braces, unused_parens)] -#![feature(unsized_tuple_coercion, unsized_locals, unsized_fn_params)] +#![feature(unsized_locals, unsized_fn_params)] struct A(#[allow(dead_code)] X); @@ -8,9 +8,6 @@ fn udrop(_x: T) {} fn foo() -> Box<[u8]> { Box::new(*b"foo") } -fn tfoo() -> Box<(i32, [u8])> { - Box::new((42, *b"foo")) -} fn afoo() -> Box> { Box::new(A(*b"foo")) } @@ -27,7 +24,6 @@ fn main() { udrop::<[u8]>(if true { *foo() } else { *foo() }); udrop::<[u8]>({ *foo() }); udrop::<[u8]>((*foo())); - udrop::<[u8]>((*tfoo()).1); *afoo() + 42; udrop as fn([u8]); } diff --git a/tests/ui/unsized-locals/unsized-exprs.rs b/tests/ui/unsized-locals/unsized-exprs.rs index 1729b9ffa867..8fe5dcba8a90 100644 --- a/tests/ui/unsized-locals/unsized-exprs.rs +++ b/tests/ui/unsized-locals/unsized-exprs.rs @@ -1,4 +1,4 @@ -#![feature(unsized_tuple_coercion, unsized_fn_params)] +#![feature(unsized_fn_params)] struct A(X); @@ -6,9 +6,6 @@ fn udrop(_x: T) {} fn foo() -> Box<[u8]> { Box::new(*b"foo") } -fn tfoo() -> Box<(i32, [u8])> { - Box::new((42, *b"foo")) -} fn afoo() -> Box> { Box::new(A(*b"foo")) } @@ -19,8 +16,6 @@ impl std::ops::Add for A<[u8]> { } fn main() { - udrop::<(i32, [u8])>((42, *foo())); - //~^ERROR E0277 udrop::>(A { 0: *foo() }); //~^ERROR E0277 udrop::>(A(*foo())); diff --git a/tests/ui/unsized-locals/unsized-exprs.stderr b/tests/ui/unsized-locals/unsized-exprs.stderr index 8a2ecf0f6c33..1b61254870f6 100644 --- a/tests/ui/unsized-locals/unsized-exprs.stderr +++ b/tests/ui/unsized-locals/unsized-exprs.stderr @@ -1,15 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/unsized-exprs.rs:22:26 - | -LL | udrop::<(i32, [u8])>((42, *foo())); - | ^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: within `({integer}, [u8])`, the trait `Sized` is not implemented for `[u8]` - = note: required because it appears within the type `({integer}, [u8])` - = note: tuples must have a statically known size to be initialized - -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/unsized-exprs.rs:24:22 + --> $DIR/unsized-exprs.rs:19:22 | LL | udrop::>(A { 0: *foo() }); | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -23,7 +13,7 @@ LL | struct A(X); = note: structs must have a statically known size to be initialized error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/unsized-exprs.rs:26:22 + --> $DIR/unsized-exprs.rs:21:22 | LL | udrop::>(A(*foo())); | ^^^^^^^^^ doesn't have a size known at compile-time @@ -36,6 +26,6 @@ LL | struct A(X); | ^ = note: the return type of a function must have a statically known size -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unsized-locals/unsized-exprs2.rs b/tests/ui/unsized-locals/unsized-exprs2.rs index 127d8717e580..7706c8b8b8f2 100644 --- a/tests/ui/unsized-locals/unsized-exprs2.rs +++ b/tests/ui/unsized-locals/unsized-exprs2.rs @@ -1,4 +1,4 @@ -#![feature(unsized_tuple_coercion, unsized_fn_params)] +#![feature(unsized_fn_params)] struct A(X); @@ -6,9 +6,6 @@ fn udrop(_x: T) {} fn foo() -> Box<[u8]> { Box::new(*b"foo") } -fn tfoo() -> Box<(i32, [u8])> { - Box::new((42, *b"foo")) -} fn afoo() -> Box> { Box::new(A(*b"foo")) } diff --git a/tests/ui/unsized-locals/unsized-exprs2.stderr b/tests/ui/unsized-locals/unsized-exprs2.stderr index 47b6d72acc7f..79f0d93d4214 100644 --- a/tests/ui/unsized-locals/unsized-exprs2.stderr +++ b/tests/ui/unsized-locals/unsized-exprs2.stderr @@ -1,5 +1,5 @@ error[E0508]: cannot move out of type `[u8]`, a non-copy slice - --> $DIR/unsized-exprs2.rs:22:5 + --> $DIR/unsized-exprs2.rs:19:5 | LL | udrop::<[u8]>(foo()[..]); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unsized/unsized-tuple-impls.rs b/tests/ui/unsized/unsized-tuple-impls.rs deleted file mode 100644 index a76e2df57507..000000000000 --- a/tests/ui/unsized/unsized-tuple-impls.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ run-pass - -#![feature(unsized_tuple_coercion)] - -use std::collections::HashSet; - -fn main() { - let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]); - let y : &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]); - let mut a = [y, x]; - a.sort(); - assert_eq!(a, [x, y]); - - assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]"); - - let mut h = HashSet::new(); - h.insert(x); - h.insert(y); - assert!(h.contains(x)); - assert!(h.contains(y)); -} From f20dd49b743b81346adea6175b9c40eb955fbd29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 27 Feb 2025 11:45:37 +0100 Subject: [PATCH 377/991] Use original command for showing sccache stats --- src/ci/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index 536754f12bc6..b874f71832d7 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -279,5 +279,5 @@ if [ "$RUN_CHECK_WITH_PARALLEL_QUERIES" != "" ]; then fi echo "::group::sccache stats" -sccache --show-adv-stats || true +sccache --show-stats || true echo "::endgroup::" From 4747bb6017a50771f48bee856c839311134eed48 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Feb 2025 11:53:30 +0100 Subject: [PATCH 378/991] Add missing case explanation for doc inlined re-export of doc hidden item --- .../src/write-documentation/re-exports.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/write-documentation/re-exports.md b/src/doc/rustdoc/src/write-documentation/re-exports.md index 34688545c74e..ee60916351ab 100644 --- a/src/doc/rustdoc/src/write-documentation/re-exports.md +++ b/src/doc/rustdoc/src/write-documentation/re-exports.md @@ -85,7 +85,22 @@ pub struct Hidden; pub use self::Hidden as InlinedHidden; ``` -The same applies on re-exports themselves: if you have multiple re-exports and some of them have +However, if you still want the re-export itself to be visible, you can add the `#[doc(inline)]` +attribute on it: + +```rust,ignore (inline) +// This struct won't be visible. +#[doc(hidden)] +pub struct Hidden; + +#[doc(inline)] +pub use self::Hidden as InlinedHidden; +``` + +In this case, you will have `pub use self::Hidden as InlinedHidden;` in the generated documentation +but no link to the `Hidden` item. + +So back to `#[doc(hidden)]`: if you have multiple re-exports and some of them have `#[doc(hidden)]`, then these ones (and only these) won't appear in the documentation: ```rust,ignore (inline) From d8a067b9310c4a4ca561f7b303cf069b1ff2c71a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 24 Feb 2025 17:26:56 +0100 Subject: [PATCH 379/991] remove most `simd_` intrinsic declaration in tests instead, we can just import the intrinsics from core --- tests/codegen/issues/issue-84268.rs | 5 +- .../simd-intrinsic-float-abs.rs | 9 +- .../simd-intrinsic-float-ceil.rs | 9 +- .../simd-intrinsic-float-cos.rs | 9 +- .../simd-intrinsic-float-exp.rs | 9 +- .../simd-intrinsic-float-exp2.rs | 9 +- .../simd-intrinsic-float-floor.rs | 9 +- .../simd-intrinsic-float-fma.rs | 9 +- .../simd-intrinsic-float-fsqrt.rs | 9 +- .../simd-intrinsic-float-log.rs | 9 +- .../simd-intrinsic-float-log10.rs | 9 +- .../simd-intrinsic-float-log2.rs | 9 +- .../simd-intrinsic-float-minmax.rs | 10 +- .../simd-intrinsic-float-sin.rs | 9 +- ...intrinsic-generic-arithmetic-saturating.rs | 104 ++++++++---------- .../simd-intrinsic-generic-bitmask.rs | 9 +- .../simd-intrinsic-generic-gather.rs | 23 ++-- .../simd-intrinsic-generic-masked-load.rs | 19 ++-- .../simd-intrinsic-generic-masked-store.rs | 9 +- .../simd-intrinsic-generic-scatter.rs | 20 ++-- .../simd-intrinsic-generic-select.rs | 10 +- .../simd-intrinsic-mask-reduce.rs | 10 +- .../simd-intrinsic-transmute-array.rs | 2 +- tests/codegen/simd/simd_arith_offset.rs | 4 +- tests/incremental/issue-61530.rs | 8 +- .../consts/const-eval/simd/insert_extract.rs | 16 ++- tests/ui/error-codes/E0511.rs | 10 +- tests/ui/error-codes/E0511.stderr | 6 +- .../bad-intrinsic-monomorphization.rs | 6 +- .../bad-intrinsic-monomorphization.stderr | 10 +- tests/ui/simd/array-trait.rs | 13 +-- tests/ui/simd/array-type.rs | 11 +- tests/ui/simd/generics.rs | 10 +- tests/ui/simd/intrinsic/float-math-pass.rs | 48 +------- .../ui/simd/intrinsic/generic-arithmetic-2.rs | 54 +-------- .../intrinsic/generic-arithmetic-2.stderr | 48 ++++---- .../simd/intrinsic/generic-arithmetic-pass.rs | 50 +-------- .../generic-arithmetic-saturating-2.rs | 12 +- .../generic-arithmetic-saturating-2.stderr | 4 +- .../generic-arithmetic-saturating-pass.rs | 11 +- tests/ui/simd/intrinsic/generic-as.rs | 6 +- .../ui/simd/intrinsic/generic-bitmask-pass.rs | 9 +- tests/ui/simd/intrinsic/generic-bitmask.rs | 10 +- .../ui/simd/intrinsic/generic-bitmask.stderr | 10 +- tests/ui/simd/intrinsic/generic-bswap-byte.rs | 7 +- tests/ui/simd/intrinsic/generic-cast-pass.rs | 5 +- .../intrinsic/generic-cast-pointer-width.rs | 5 +- tests/ui/simd/intrinsic/generic-cast.rs | 10 +- tests/ui/simd/intrinsic/generic-cast.stderr | 8 +- .../simd/intrinsic/generic-comparison-pass.rs | 22 +--- tests/ui/simd/intrinsic/generic-comparison.rs | 33 ++---- .../simd/intrinsic/generic-comparison.stderr | 36 +++--- .../simd/intrinsic/generic-elements-pass.rs | 13 +-- tests/ui/simd/intrinsic/generic-elements.rs | 29 +++-- .../ui/simd/intrinsic/generic-elements.stderr | 42 +++---- .../ui/simd/intrinsic/generic-gather-pass.rs | 62 +++-------- .../simd/intrinsic/generic-reduction-pass.rs | 42 +------ tests/ui/simd/intrinsic/generic-reduction.rs | 28 +---- .../simd/intrinsic/generic-reduction.stderr | 20 ++-- .../ui/simd/intrinsic/generic-select-pass.rs | 12 +- tests/ui/simd/intrinsic/generic-select.rs | 12 +- tests/ui/simd/intrinsic/generic-select.stderr | 16 +-- tests/ui/simd/intrinsic/generic-shuffle.rs | 8 +- .../ui/simd/intrinsic/generic-shuffle.stderr | 8 +- .../simd/intrinsic/inlining-issue67557-ice.rs | 5 +- .../ui/simd/intrinsic/inlining-issue67557.rs | 6 +- tests/ui/simd/intrinsic/issue-85855.rs | 3 +- tests/ui/simd/intrinsic/issue-85855.stderr | 6 +- tests/ui/simd/intrinsic/ptr-cast.rs | 12 +- tests/ui/simd/issue-105439.rs | 8 +- tests/ui/simd/issue-39720.rs | 7 +- tests/ui/simd/issue-85915-simd-ptrs.rs | 17 +-- tests/ui/simd/issue-89193.rs | 23 ++-- tests/ui/simd/masked-load-store-build-fail.rs | 73 +++--------- .../simd/masked-load-store-build-fail.stderr | 80 ++++---------- tests/ui/simd/masked-load-store-check-fail.rs | 25 ++--- .../simd/masked-load-store-check-fail.stderr | 56 +++------- tests/ui/simd/masked-load-store.rs | 15 +-- .../monomorphize-shuffle-index.generic.stderr | 2 +- tests/ui/simd/monomorphize-shuffle-index.rs | 18 +-- tests/ui/simd/repr_packed.rs | 7 +- tests/ui/simd/shuffle.rs | 5 +- tests/ui/simd/simd-bitmask-notpow2.rs | 9 +- tests/ui/simd/simd-bitmask.rs | 9 +- 84 files changed, 482 insertions(+), 1007 deletions(-) diff --git a/tests/codegen/issues/issue-84268.rs b/tests/codegen/issues/issue-84268.rs index 8a8ea9d1ccf8..2eebf4479375 100644 --- a/tests/codegen/issues/issue-84268.rs +++ b/tests/codegen/issues/issue-84268.rs @@ -1,10 +1,7 @@ //@ compile-flags: -Copt-level=3 --crate-type=rlib #![feature(intrinsics, repr_simd)] -extern "rust-intrinsic" { - fn simd_fabs(x: T) -> T; - fn simd_eq(x: T, y: T) -> U; -} +use std::intrinsics::simd::{simd_eq, simd_fabs}; #[repr(simd)] pub struct V([f32; 4]); diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs index 4a5a6391c052..485ba92272dd 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_fabs; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_fabs(x: T) -> T; -} - // CHECK-LABEL: @fabs_32x2 #[no_mangle] pub unsafe fn fabs_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs index 89e54f579ff7..e8bda7c29c4b 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_ceil; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_ceil(x: T) -> T; -} - // CHECK-LABEL: @ceil_32x2 #[no_mangle] pub unsafe fn ceil_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs index b40fd5365de5..8dc967bc3adc 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_fcos; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_fcos(x: T) -> T; -} - // CHECK-LABEL: @fcos_32x2 #[no_mangle] pub unsafe fn fcos_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs index fef003dde5bb..00caca2f2949 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_fexp; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_fexp(x: T) -> T; -} - // CHECK-LABEL: @exp_32x2 #[no_mangle] pub unsafe fn exp_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs index 779c0fc403a3..eda4053189cb 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_fexp2; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_fexp2(x: T) -> T; -} - // CHECK-LABEL: @exp2_32x2 #[no_mangle] pub unsafe fn exp2_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs index b2bd27a5b75c..ad69d4cdd88c 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_floor; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_floor(x: T) -> T; -} - // CHECK-LABEL: @floor_32x2 #[no_mangle] pub unsafe fn floor_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs index 37f4782626ad..cbeefdc31c0d 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_fma; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_fma(x: T, b: T, c: T) -> T; -} - // CHECK-LABEL: @fma_32x2 #[no_mangle] pub unsafe fn fma_32x2(a: f32x2, b: f32x2, c: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs index 336adf6db73f..618daa4b44d0 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_fsqrt; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_fsqrt(x: T) -> T; -} - // CHECK-LABEL: @fsqrt_32x2 #[no_mangle] pub unsafe fn fsqrt_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs index 8e97abc3a661..98a481e4004e 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_flog; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_flog(x: T) -> T; -} - // CHECK-LABEL: @log_32x2 #[no_mangle] pub unsafe fn log_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs index 1d4d4dc24e9a..9108cd963f02 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_flog10; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_flog10(x: T) -> T; -} - // CHECK-LABEL: @log10_32x2 #[no_mangle] pub unsafe fn log10_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs index 28f2f1516175..2b20850dbd9a 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_flog2; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_flog2(x: T) -> T; -} - // CHECK-LABEL: @log2_32x2 #[no_mangle] pub unsafe fn log2_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs index 50c51bebe37e..ce07b212e846 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs @@ -1,19 +1,15 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::{simd_fmax, simd_fmin}; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x4(pub [f32; 4]); -extern "rust-intrinsic" { - fn simd_fmin(x: T, y: T) -> T; - fn simd_fmax(x: T, y: T) -> T; -} - // CHECK-LABEL: @fmin #[no_mangle] pub unsafe fn fmin(a: f32x4, b: f32x4) -> f32x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs index 4173809e3a9b..7de26b415bbb 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_fsin; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x2(pub [f32; 2]); @@ -21,10 +22,6 @@ pub struct f32x8(pub [f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x16(pub [f32; 16]); -extern "rust-intrinsic" { - fn simd_fsin(x: T) -> T; -} - // CHECK-LABEL: @fsin_32x2 #[no_mangle] pub unsafe fn fsin_32x2(a: f32x2) -> f32x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs index a5afa27876a0..ecf5eb24ee5b 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs @@ -1,71 +1,71 @@ //@ compile-flags: -C no-prepopulate-passes -// #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] #![deny(unused)] -// signed integer types +use std::intrinsics::simd::{simd_saturating_add, simd_saturating_sub}; -#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x2([i8; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x4([i8; 4]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x8([i8; 8]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x16([i8; 16]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x32([i8; 32]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x64([i8; 64]); +#[rustfmt::skip] +mod types { + // signed integer types -#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x2([i16; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x4([i16; 4]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x8([i16; 8]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x16([i16; 16]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x32([i16; 32]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x2([i8; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x4([i8; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x8([i8; 8]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x16([i8; 16]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x32([i8; 32]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x64([i8; 64]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x2([i32; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x4([i32; 4]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x8([i32; 8]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x16([i32; 16]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x2([i16; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x4([i16; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x8([i16; 8]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x16([i16; 16]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x32([i16; 32]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i64x2([i64; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i64x4([i64; 4]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i64x8([i64; 8]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x2([i32; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x4([i32; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x8([i32; 8]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x16([i32; 16]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i128x2([i128; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct i128x4([i128; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i64x2([i64; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i64x4([i64; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i64x8([i64; 8]); -// unsigned integer types + #[repr(simd)] #[derive(Copy, Clone)] pub struct i128x2([i128; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct i128x4([i128; 4]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x2([u8; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x4([u8; 4]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x8([u8; 8]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x16([u8; 16]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x32([u8; 32]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x64([u8; 64]); + // unsigned integer types -#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x2([u16; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x4([u16; 4]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x8([u16; 8]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x16([u16; 16]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x32([u16; 32]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x2([u8; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x4([u8; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x8([u8; 8]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x16([u8; 16]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x32([u8; 32]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x64([u8; 64]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x2([u32; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x4([u32; 4]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x8([u32; 8]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x16([u32; 16]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x2([u16; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x4([u16; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x8([u16; 8]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x16([u16; 16]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x32([u16; 32]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u64x2([u64; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u64x4([u64; 4]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u64x8([u64; 8]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x2([u32; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x4([u32; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x8([u32; 8]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x16([u32; 16]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u128x2([u128; 2]); -#[repr(simd)] #[derive(Copy, Clone)] pub struct u128x4([u128; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u64x2([u64; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u64x4([u64; 4]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u64x8([u64; 8]); -extern "rust-intrinsic" { - fn simd_saturating_add(x: T, y: T) -> T; - fn simd_saturating_sub(x: T, y: T) -> T; + #[repr(simd)] #[derive(Copy, Clone)] pub struct u128x2([u128; 2]); + #[repr(simd)] #[derive(Copy, Clone)] pub struct u128x4([u128; 4]); } +use types::*; + // NOTE(eddyb) `%{{x|0}}` is used because on some targets (e.g. WASM) // SIMD vectors are passed directly, resulting in `%x` being a vector, // while on others they're passed indirectly, resulting in `%x` being @@ -213,8 +213,6 @@ pub unsafe fn sadd_i128x4(x: i128x4, y: i128x4) -> i128x4 { simd_saturating_add(x, y) } - - // CHECK-LABEL: @uadd_u8x2 #[no_mangle] pub unsafe fn uadd_u8x2(x: u8x2, y: u8x2) -> u8x2 { @@ -355,10 +353,6 @@ pub unsafe fn uadd_u128x4(x: u128x4, y: u128x4) -> u128x4 { simd_saturating_add(x, y) } - - - - // CHECK-LABEL: @ssub_i8x2 #[no_mangle] pub unsafe fn ssub_i8x2(x: i8x2, y: i8x2) -> i8x2 { @@ -499,8 +493,6 @@ pub unsafe fn ssub_i128x4(x: i128x4, y: i128x4) -> i128x4 { simd_saturating_sub(x, y) } - - // CHECK-LABEL: @usub_u8x2 #[no_mangle] pub unsafe fn usub_u8x2(x: u8x2, y: u8x2) -> u8x2 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs index e9112f1f321b..a2c40aa91b51 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs @@ -2,10 +2,11 @@ // #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_bitmask; + #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x2([u32; 2]); @@ -18,10 +19,6 @@ pub struct i32x2([i32; 2]); #[derive(Copy, Clone)] pub struct i8x16([i8; 16]); -extern "rust-intrinsic" { - fn simd_bitmask(x: T) -> U; -} - // NOTE(eddyb) `%{{x|1}}` is used because on some targets (e.g. WASM) // SIMD vectors are passed directly, resulting in `%x` being a vector, // while on others they're passed indirectly, resulting in `%x` being diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs index 7f99f695bf4f..9bb46a3546bf 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs @@ -3,10 +3,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_gather; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct Vec2(pub [T; 2]); @@ -15,14 +16,13 @@ pub struct Vec2(pub [T; 2]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct Vec4(pub [T; 4]); -extern "rust-intrinsic" { - fn simd_gather(value: T, pointers: P, mask: M) -> T; -} - // CHECK-LABEL: @gather_f32x2 #[no_mangle] -pub unsafe fn gather_f32x2(pointers: Vec2<*const f32>, mask: Vec2, - values: Vec2) -> Vec2 { +pub unsafe fn gather_f32x2( + pointers: Vec2<*const f32>, + mask: Vec2, + values: Vec2, +) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // CHECK: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) @@ -31,8 +31,11 @@ pub unsafe fn gather_f32x2(pointers: Vec2<*const f32>, mask: Vec2, // CHECK-LABEL: @gather_pf32x2 #[no_mangle] -pub unsafe fn gather_pf32x2(pointers: Vec2<*const *const f32>, mask: Vec2, - values: Vec2<*const f32>) -> Vec2<*const f32> { +pub unsafe fn gather_pf32x2( + pointers: Vec2<*const *const f32>, + mask: Vec2, + values: Vec2<*const f32>, +) -> Vec2<*const f32> { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // CHECK: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x ptr> {{.*}}) diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs index 7f46630e920d..fcc4cb5d6300 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_masked_load; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct Vec2(pub [T; 2]); @@ -13,14 +14,9 @@ pub struct Vec2(pub [T; 2]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct Vec4(pub [T; 4]); -extern "rust-intrinsic" { - fn simd_masked_load(mask: M, pointer: P, values: T) -> T; -} - // CHECK-LABEL: @load_f32x2 #[no_mangle] -pub unsafe fn load_f32x2(mask: Vec2, pointer: *const f32, - values: Vec2) -> Vec2 { +pub unsafe fn load_f32x2(mask: Vec2, pointer: *const f32, values: Vec2) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) @@ -29,8 +25,11 @@ pub unsafe fn load_f32x2(mask: Vec2, pointer: *const f32, // CHECK-LABEL: @load_pf32x4 #[no_mangle] -pub unsafe fn load_pf32x4(mask: Vec4, pointer: *const *const f32, - values: Vec4<*const f32>) -> Vec4<*const f32> { +pub unsafe fn load_pf32x4( + mask: Vec4, + pointer: *const *const f32, + values: Vec4<*const f32>, +) -> Vec4<*const f32> { // CHECK: [[A:%[0-9]+]] = lshr <4 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> // CHECK: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs index 0d43234f1e29..04f4a0c63829 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_masked_store; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct Vec2(pub [T; 2]); @@ -13,10 +14,6 @@ pub struct Vec2(pub [T; 2]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct Vec4(pub [T; 4]); -extern "rust-intrinsic" { - fn simd_masked_store(mask: M, pointer: P, values: T) -> (); -} - // CHECK-LABEL: @store_f32x2 #[no_mangle] pub unsafe fn store_f32x2(mask: Vec2, pointer: *mut f32, values: Vec2) { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs index ef7827bd96f0..9506f8f6d3a8 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs @@ -3,10 +3,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_scatter; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct Vec2(pub [T; 2]); @@ -15,25 +16,22 @@ pub struct Vec2(pub [T; 2]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct Vec4(pub [T; 4]); -extern "rust-intrinsic" { - fn simd_scatter(value: T, pointers: P, mask: M); -} - // CHECK-LABEL: @scatter_f32x2 #[no_mangle] -pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2, - values: Vec2) { +pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2, values: Vec2) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // CHECK: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] simd_scatter(values, pointers, mask) } - // CHECK-LABEL: @scatter_pf32x2 #[no_mangle] -pub unsafe fn scatter_pf32x2(pointers: Vec2<*mut *const f32>, mask: Vec2, - values: Vec2<*const f32>) { +pub unsafe fn scatter_pf32x2( + pointers: Vec2<*mut *const f32>, + mask: Vec2, + values: Vec2<*const f32>, +) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // CHECK: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs index 33ed2b437f9b..71279d9f0eac 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::{simd_select, simd_select_bitmask}; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] pub struct f32x4(pub [f32; 4]); @@ -21,11 +22,6 @@ pub struct b8x4(pub [i8; 4]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct i32x4([i32; 4]); -extern "rust-intrinsic" { - fn simd_select(x: T, a: U, b: U) -> U; - fn simd_select_bitmask(x: T, a: U, b: U) -> U; -} - // CHECK-LABEL: @select_m8 #[no_mangle] pub unsafe fn select_m8(m: b8x4, a: f32x4, b: f32x4) -> f32x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs index 92067db9b153..269fe41225ef 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs @@ -1,10 +1,11 @@ //@ compile-flags: -C no-prepopulate-passes -// #![crate_type = "lib"] -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::{simd_reduce_all, simd_reduce_any}; + #[repr(simd)] #[derive(Copy, Clone)] pub struct mask32x2([i32; 2]); @@ -13,11 +14,6 @@ pub struct mask32x2([i32; 2]); #[derive(Copy, Clone)] pub struct mask8x16([i8; 16]); -extern "rust-intrinsic" { - fn simd_reduce_all(x: T) -> bool; - fn simd_reduce_any(x: T) -> bool; -} - // NOTE(eddyb) `%{{x|1}}` is used because on some targets (e.g. WASM) // SIMD vectors are passed directly, resulting in `%x` being a vector, // while on others they're passed indirectly, resulting in `%x` being diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs index 0d21d5105576..d3853361de9e 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs @@ -12,7 +12,7 @@ #![crate_type = "lib"] #![allow(non_camel_case_types)] -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #[repr(simd)] #[derive(Copy, Clone)] diff --git a/tests/codegen/simd/simd_arith_offset.rs b/tests/codegen/simd/simd_arith_offset.rs index e14fce1d4187..475ac37804fb 100644 --- a/tests/codegen/simd/simd_arith_offset.rs +++ b/tests/codegen/simd/simd_arith_offset.rs @@ -5,9 +5,7 @@ #![crate_type = "lib"] #![feature(repr_simd, intrinsics)] -extern "rust-intrinsic" { - pub(crate) fn simd_arith_offset(ptrs: T, offsets: U) -> T; -} +use std::intrinsics::simd::simd_arith_offset; /// A vector of *const T. #[derive(Debug, Copy, Clone)] diff --git a/tests/incremental/issue-61530.rs b/tests/incremental/issue-61530.rs index 71ac39d0e039..673556a9d02f 100644 --- a/tests/incremental/issue-61530.rs +++ b/tests/incremental/issue-61530.rs @@ -1,14 +1,12 @@ -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] //@ revisions:rpass1 rpass2 +use std::intrinsics::simd::simd_shuffle; + #[repr(simd)] struct I32x2([i32; 2]); -extern "rust-intrinsic" { - fn simd_shuffle(x: T, y: T, idx: I) -> U; -} - #[repr(simd)] struct SimdShuffleIdx([u32; LEN]); diff --git a/tests/ui/consts/const-eval/simd/insert_extract.rs b/tests/ui/consts/const-eval/simd/insert_extract.rs index e5873ea26e8d..526f2b180427 100644 --- a/tests/ui/consts/const-eval/simd/insert_extract.rs +++ b/tests/ui/consts/const-eval/simd/insert_extract.rs @@ -1,14 +1,12 @@ //@ run-pass #![feature(repr_simd)] -#![feature(intrinsics, rustc_attrs)] +#![feature(intrinsics, core_intrinsics, rustc_attrs)] #![feature(staged_api)] #![stable(feature = "foo", since = "1.3.37")] #![allow(non_camel_case_types)] -// repr(simd) now only supports array types -#[repr(simd)] struct i8x1([i8; 1]); -#[repr(simd)] struct u16x2([u16; 2]); -#[repr(simd)] struct f32x4([f32; 4]); +// FIXME these intrinsics are not marked as const fn +// use std::intrinsics::simd::{simd_extract, simd_insert}; #[stable(feature = "foo", since = "1.3.37")] #[rustc_const_stable(feature = "foo", since = "1.3.37")] @@ -24,6 +22,14 @@ const unsafe fn simd_extract(_x: T, _idx: u32) -> U { unimplemented!() } +// repr(simd) now only supports array types +#[repr(simd)] +struct i8x1([i8; 1]); +#[repr(simd)] +struct u16x2([u16; 2]); +#[repr(simd)] +struct f32x4([f32; 4]); + fn main() { { const U: i8x1 = i8x1([13]); diff --git a/tests/ui/error-codes/E0511.rs b/tests/ui/error-codes/E0511.rs index 81656c710882..c7e59c5c6c96 100644 --- a/tests/ui/error-codes/E0511.rs +++ b/tests/ui/error-codes/E0511.rs @@ -1,11 +1,11 @@ //@ build-fail -#![feature(intrinsics)] +#![feature(core_intrinsics)] -extern "rust-intrinsic" { - fn simd_add(a: T, b: T) -> T; -} +use std::intrinsics::simd::simd_add; fn main() { - unsafe { simd_add(0, 1); } //~ ERROR E0511 + unsafe { + simd_add(0, 1) //~ ERROR E0511 + }; } diff --git a/tests/ui/error-codes/E0511.stderr b/tests/ui/error-codes/E0511.stderr index 59eb19d2ee52..45f5b8d238da 100644 --- a/tests/ui/error-codes/E0511.stderr +++ b/tests/ui/error-codes/E0511.stderr @@ -1,8 +1,8 @@ error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/E0511.rs:10:14 + --> $DIR/E0511.rs:9:9 | -LL | unsafe { simd_add(0, 1); } - | ^^^^^^^^^^^^^^ +LL | simd_add(0, 1) + | ^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs index 254ac24f0b94..d68cbf26ef11 100644 --- a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs @@ -7,10 +7,6 @@ // Bad monomorphizations could previously cause LLVM asserts even though the // error was caught in the compiler. -extern "rust-intrinsic" { - fn simd_add(x: T, y: T) -> T; -} - use std::intrinsics; #[derive(Copy, Clone)] @@ -27,6 +23,6 @@ pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo { } pub unsafe fn test_simd_add(a: Foo, b: Foo) -> Foo { - simd_add(a, b) + intrinsics::simd::simd_add(a, b) //~^ ERROR `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo` } diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr index c070f0181819..f49d95e9cfcb 100644 --- a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr @@ -1,20 +1,20 @@ error[E0511]: invalid monomorphization of `cttz` intrinsic: expected basic integer type, found `Foo` - --> $DIR/bad-intrinsic-monomorphization.rs:20:5 + --> $DIR/bad-intrinsic-monomorphization.rs:16:5 | LL | intrinsics::cttz(v) | ^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `fadd_fast` intrinsic: expected basic float type, found `Foo` - --> $DIR/bad-intrinsic-monomorphization.rs:25:5 + --> $DIR/bad-intrinsic-monomorphization.rs:21:5 | LL | intrinsics::fadd_fast(a, b) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo` - --> $DIR/bad-intrinsic-monomorphization.rs:30:5 + --> $DIR/bad-intrinsic-monomorphization.rs:26:5 | -LL | simd_add(a, b) - | ^^^^^^^^^^^^^^ +LL | intrinsics::simd::simd_add(a, b) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/tests/ui/simd/array-trait.rs b/tests/ui/simd/array-trait.rs index 32cbf01428ca..262188567713 100644 --- a/tests/ui/simd/array-trait.rs +++ b/tests/ui/simd/array-trait.rs @@ -1,11 +1,11 @@ // Figuring out the size of a vector type that depends on traits doesn't ICE #![allow(dead_code)] - - -#![feature(repr_simd, intrinsics, generic_const_exprs)] +#![feature(repr_simd, core_intrinsics, generic_const_exprs)] #![allow(non_camel_case_types, incomplete_features)] +use std::intrinsics::simd::{simd_extract, simd_insert}; + pub trait Simd { type Lane: Clone + Copy; const SIZE: usize; @@ -24,13 +24,6 @@ pub struct T([S::Lane; S::SIZE]); //~| ERROR SIMD vector element type should be a primitive scalar //~| ERROR unconstrained generic constant -#[rustc_intrinsic] -unsafe fn simd_insert(x: T, idx: u32, y: E) -> T; - -#[rustc_intrinsic] -unsafe fn simd_extract(x: T, idx: u32) -> E; - - pub fn main() { let mut t = T::([0; 4]); unsafe { diff --git a/tests/ui/simd/array-type.rs b/tests/ui/simd/array-type.rs index d1de70044169..468e0b2f9b50 100644 --- a/tests/ui/simd/array-type.rs +++ b/tests/ui/simd/array-type.rs @@ -1,8 +1,8 @@ //@ run-pass #![allow(dead_code)] +#![feature(repr_simd, core_intrinsics)] - -#![feature(repr_simd, intrinsics)] +use std::intrinsics::simd::{simd_extract, simd_insert}; #[repr(simd)] #[derive(Copy, Clone)] @@ -12,13 +12,6 @@ struct S([i32; 4]); #[derive(Copy, Clone)] struct T([i32; N]); -#[rustc_intrinsic] -unsafe fn simd_insert(x: T, idx: u32, y: E) -> T; - -#[rustc_intrinsic] -unsafe fn simd_extract(x: T, idx: u32) -> E; - - pub fn main() { let mut s = S([0; 4]); diff --git a/tests/ui/simd/generics.rs b/tests/ui/simd/generics.rs index 453ed86c14a9..1ae08fef7cdf 100644 --- a/tests/ui/simd/generics.rs +++ b/tests/ui/simd/generics.rs @@ -1,7 +1,8 @@ //@ run-pass #![allow(non_camel_case_types)] -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] +use std::intrinsics::simd::simd_add; use std::ops; #[repr(simd)] @@ -20,11 +21,7 @@ struct B([T; 4]); #[derive(Copy, Clone)] struct C([T; N]); - -#[rustc_intrinsic] -unsafe fn simd_add(x: T, y: T) -> T; - -fn add>(lhs: T, rhs: T) -> T { +fn add>(lhs: T, rhs: T) -> T { lhs + rhs } @@ -60,7 +57,6 @@ impl ops::Add for C { } } - pub fn main() { let x = [1.0f32, 2.0f32, 3.0f32, 4.0f32]; let y = [2.0f32, 4.0f32, 6.0f32, 8.0f32]; diff --git a/tests/ui/simd/intrinsic/float-math-pass.rs b/tests/ui/simd/intrinsic/float-math-pass.rs index 91059f353fd9..4c28568a739b 100644 --- a/tests/ui/simd/intrinsic/float-math-pass.rs +++ b/tests/ui/simd/intrinsic/float-math-pass.rs @@ -8,58 +8,14 @@ // Test that the simd floating-point math intrinsics produce correct results. -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, intrinsics, core_intrinsics)] #![allow(non_camel_case_types)] #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] struct f32x4(pub [f32; 4]); -#[rustc_intrinsic] -unsafe fn simd_fsqrt(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_fabs(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_fsin(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_fcos(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_fexp(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_fexp2(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_fma(x: T, y: T, z: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_relaxed_fma(x: T, y: T, z: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_flog(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_flog10(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_flog2(x: T) -> T; - -// rounding functions -#[rustc_intrinsic] -unsafe fn simd_ceil(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_floor(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_round(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_trunc(x: T) -> T; +use std::intrinsics::simd::*; macro_rules! assert_approx_eq_f32 { ($a:expr, $b:expr) => {{ diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs index 0fcff8584c85..fdf06b7882ed 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs +++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs @@ -1,7 +1,10 @@ //@ build-fail -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] + +use std::intrinsics::simd::*; + #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x4(pub [i32; 4]); @@ -14,55 +17,6 @@ pub struct u32x4(pub [u32; 4]); #[derive(Copy, Clone)] pub struct f32x4(pub [f32; 4]); -#[rustc_intrinsic] -unsafe fn simd_add(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_sub(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_mul(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_div(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_rem(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_shl(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_shr(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_and(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_or(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_xor(x: T, y: T) -> T; - - -#[rustc_intrinsic] -unsafe fn simd_neg(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_bswap(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_bitreverse(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_ctlz(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_ctpop(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_cttz(x: T) -> T; - fn main() { let x = i32x4([0, 0, 0, 0]); let y = u32x4([0, 0, 0, 0]); diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr b/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr index e67de2fe9034..76db6d5328f5 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr +++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr @@ -1,143 +1,143 @@ error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:110:9 + --> $DIR/generic-arithmetic-2.rs:64:9 | LL | simd_add(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_sub` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:112:9 + --> $DIR/generic-arithmetic-2.rs:66:9 | LL | simd_sub(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_mul` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:114:9 + --> $DIR/generic-arithmetic-2.rs:68:9 | LL | simd_mul(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_div` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:116:9 + --> $DIR/generic-arithmetic-2.rs:70:9 | LL | simd_div(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shl` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:118:9 + --> $DIR/generic-arithmetic-2.rs:72:9 | LL | simd_shl(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shr` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:120:9 + --> $DIR/generic-arithmetic-2.rs:74:9 | LL | simd_shr(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_and` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:122:9 + --> $DIR/generic-arithmetic-2.rs:76:9 | LL | simd_and(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_or` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:124:9 + --> $DIR/generic-arithmetic-2.rs:78:9 | LL | simd_or(0, 0); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_xor` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:126:9 + --> $DIR/generic-arithmetic-2.rs:80:9 | LL | simd_xor(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_neg` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:129:9 + --> $DIR/generic-arithmetic-2.rs:83:9 | LL | simd_neg(0); | ^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:131:9 + --> $DIR/generic-arithmetic-2.rs:85:9 | LL | simd_bswap(0); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:133:9 + --> $DIR/generic-arithmetic-2.rs:87:9 | LL | simd_bitreverse(0); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:135:9 + --> $DIR/generic-arithmetic-2.rs:89:9 | LL | simd_ctlz(0); | ^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:137:9 + --> $DIR/generic-arithmetic-2.rs:91:9 | LL | simd_cttz(0); | ^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shl` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:140:9 + --> $DIR/generic-arithmetic-2.rs:94:9 | LL | simd_shl(z, z); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shr` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:142:9 + --> $DIR/generic-arithmetic-2.rs:96:9 | LL | simd_shr(z, z); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_and` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:144:9 + --> $DIR/generic-arithmetic-2.rs:98:9 | LL | simd_and(z, z); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_or` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:146:9 + --> $DIR/generic-arithmetic-2.rs:100:9 | LL | simd_or(z, z); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_xor` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:148:9 + --> $DIR/generic-arithmetic-2.rs:102:9 | LL | simd_xor(z, z); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:150:9 + --> $DIR/generic-arithmetic-2.rs:104:9 | LL | simd_bswap(z); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:152:9 + --> $DIR/generic-arithmetic-2.rs:106:9 | LL | simd_bitreverse(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:154:9 + --> $DIR/generic-arithmetic-2.rs:108:9 | LL | simd_ctlz(z); | ^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ctpop` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:156:9 + --> $DIR/generic-arithmetic-2.rs:110:9 | LL | simd_ctpop(z); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:158:9 + --> $DIR/generic-arithmetic-2.rs:112:9 | LL | simd_cttz(z); | ^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs index 29d82255d4ea..3f0325d690b5 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs +++ b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs @@ -1,6 +1,6 @@ //@ run-pass #![allow(non_camel_case_types)] -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #[repr(simd)] #[derive(Copy, Clone)] @@ -22,53 +22,7 @@ macro_rules! all_eq { }}; } -#[rustc_intrinsic] -unsafe fn simd_add(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_sub(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_mul(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_div(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_rem(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_shl(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_shr(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_and(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_or(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_xor(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_neg(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_bswap(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_bitreverse(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_ctlz(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_ctpop(x: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_cttz(x: T) -> T; +use std::intrinsics::simd::*; fn main() { let x1 = i32x4([1, 2, 3, 4]); diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs index 85464402d6af..ca170f2d8502 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs +++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs @@ -1,7 +1,10 @@ //@ build-fail //@ ignore-emscripten -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] + +use std::intrinsics::simd::{simd_saturating_add, simd_saturating_sub}; + #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x4(pub [i32; 4]); @@ -14,13 +17,6 @@ pub struct x4(pub [T; 4]); #[derive(Copy, Clone)] pub struct f32x4(pub [f32; 4]); -#[rustc_intrinsic] -unsafe fn simd_saturating_add(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_saturating_sub(x: T, y: T) -> T; - - fn main() { let x = i32x4([0, 0, 0, 0]); let y = x4([0_usize, 0, 0, 0]); diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr index cf275db7e435..f78745823402 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr +++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr @@ -1,11 +1,11 @@ error[E0511]: invalid monomorphization of `simd_saturating_add` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type - --> $DIR/generic-arithmetic-saturating-2.rs:35:9 + --> $DIR/generic-arithmetic-saturating-2.rs:31:9 | LL | simd_saturating_add(z, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_saturating_sub` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type - --> $DIR/generic-arithmetic-saturating-2.rs:37:9 + --> $DIR/generic-arithmetic-saturating-2.rs:33:9 | LL | simd_saturating_sub(z, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs index 5fe65257d15f..4d12a312331a 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs +++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs @@ -2,7 +2,9 @@ //@ ignore-emscripten #![allow(non_camel_case_types)] -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] + +use std::intrinsics::simd::{simd_saturating_add, simd_saturating_sub}; #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] @@ -12,13 +14,6 @@ struct u32x4(pub [u32; 4]); #[derive(Copy, Clone)] struct I32([i32; N]); -#[rustc_intrinsic] -unsafe fn simd_saturating_add(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_saturating_sub(x: T, y: T) -> T; - - fn main() { // unsigned { diff --git a/tests/ui/simd/intrinsic/generic-as.rs b/tests/ui/simd/intrinsic/generic-as.rs index 124ca56bc889..da53211cbc74 100644 --- a/tests/ui/simd/intrinsic/generic-as.rs +++ b/tests/ui/simd/intrinsic/generic-as.rs @@ -1,10 +1,8 @@ //@ run-pass -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] - -#[rustc_intrinsic] -unsafe fn simd_as(x: T) -> U; +use std::intrinsics::simd::simd_as; #[derive(Copy, Clone)] #[repr(simd)] diff --git a/tests/ui/simd/intrinsic/generic-bitmask-pass.rs b/tests/ui/simd/intrinsic/generic-bitmask-pass.rs index 08526991fbe1..cb3221e21d53 100644 --- a/tests/ui/simd/intrinsic/generic-bitmask-pass.rs +++ b/tests/ui/simd/intrinsic/generic-bitmask-pass.rs @@ -1,13 +1,12 @@ //@ run-pass #![allow(non_camel_case_types)] - //@ ignore-emscripten //@ ignore-endian-big behavior of simd_bitmask is endian-specific // Test that the simd_bitmask intrinsic produces correct results. +#![feature(repr_simd, core_intrinsics)] -#![feature(repr_simd, intrinsics)] -#[allow(non_camel_case_types)] +use std::intrinsics::simd::simd_bitmask; #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] @@ -21,9 +20,6 @@ struct u8x4(pub [u8; 4]); #[derive(Copy, Clone, PartialEq, Debug)] struct Tx4(pub [T; 4]); -#[rustc_intrinsic] -unsafe fn simd_bitmask(x: T) -> U; - fn main() { let z = u32x4([0, 0, 0, 0]); let ez = 0_u8; @@ -56,6 +52,5 @@ fn main() { let r: u8 = simd_bitmask(msize); assert_eq!(r, e); - } } diff --git a/tests/ui/simd/intrinsic/generic-bitmask.rs b/tests/ui/simd/intrinsic/generic-bitmask.rs index 49589d22bbfa..9f5e806337eb 100644 --- a/tests/ui/simd/intrinsic/generic-bitmask.rs +++ b/tests/ui/simd/intrinsic/generic-bitmask.rs @@ -3,9 +3,11 @@ // Test that the simd_bitmask intrinsic produces ok-ish error // messages when misused. -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_bitmask; + #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x2([u32; 2]); @@ -30,9 +32,6 @@ struct u8x32([u8; 32]); #[derive(Copy, Clone)] struct u8x64([u8; 64]); -#[rustc_intrinsic] -unsafe fn simd_bitmask(x: T) -> U; - fn main() { let m2 = u32x2([0; 2]); let m4 = u32x4([0; 4]); @@ -63,6 +62,5 @@ fn main() { let _: u128 = simd_bitmask(m64); //~^ ERROR invalid monomorphization of `simd_bitmask` intrinsic - - } + } } diff --git a/tests/ui/simd/intrinsic/generic-bitmask.stderr b/tests/ui/simd/intrinsic/generic-bitmask.stderr index c217bb2d8f1a..3c4878f39cc9 100644 --- a/tests/ui/simd/intrinsic/generic-bitmask.stderr +++ b/tests/ui/simd/intrinsic/generic-bitmask.stderr @@ -1,29 +1,29 @@ error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u16`, expected `u8` or `[u8; 1]` - --> $DIR/generic-bitmask.rs:52:22 + --> $DIR/generic-bitmask.rs:51:22 | LL | let _: u16 = simd_bitmask(m2); | ^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u16`, expected `u8` or `[u8; 1]` - --> $DIR/generic-bitmask.rs:55:22 + --> $DIR/generic-bitmask.rs:54:22 | LL | let _: u16 = simd_bitmask(m8); | ^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u32`, expected `u16` or `[u8; 2]` - --> $DIR/generic-bitmask.rs:58:22 + --> $DIR/generic-bitmask.rs:57:22 | LL | let _: u32 = simd_bitmask(m16); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u64`, expected `u32` or `[u8; 4]` - --> $DIR/generic-bitmask.rs:61:22 + --> $DIR/generic-bitmask.rs:60:22 | LL | let _: u64 = simd_bitmask(m32); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u128`, expected `u64` or `[u8; 8]` - --> $DIR/generic-bitmask.rs:64:23 + --> $DIR/generic-bitmask.rs:63:23 | LL | let _: u128 = simd_bitmask(m64); | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/generic-bswap-byte.rs b/tests/ui/simd/intrinsic/generic-bswap-byte.rs index 4521573636c0..903a07656a70 100644 --- a/tests/ui/simd/intrinsic/generic-bswap-byte.rs +++ b/tests/ui/simd/intrinsic/generic-bswap-byte.rs @@ -1,7 +1,9 @@ //@ run-pass -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_bswap; + #[repr(simd)] #[derive(Copy, Clone)] struct i8x4([i8; 4]); @@ -10,9 +12,6 @@ struct i8x4([i8; 4]); #[derive(Copy, Clone)] struct u8x4([u8; 4]); -#[rustc_intrinsic] -unsafe fn simd_bswap(x: T) -> T; - fn main() { unsafe { assert_eq!(simd_bswap(i8x4([0, 1, 2, 3])).0, [0, 1, 2, 3]); diff --git a/tests/ui/simd/intrinsic/generic-cast-pass.rs b/tests/ui/simd/intrinsic/generic-cast-pass.rs index aab7347d1de5..7a4663bcad2b 100644 --- a/tests/ui/simd/intrinsic/generic-cast-pass.rs +++ b/tests/ui/simd/intrinsic/generic-cast-pass.rs @@ -1,9 +1,8 @@ //@ run-pass -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] -#[rustc_intrinsic] -unsafe fn simd_cast(x: T) -> U; +use std::intrinsics::simd::simd_cast; use std::cmp::{max, min}; diff --git a/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs b/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs index 9f28898654f2..ea34e9ffeb8e 100644 --- a/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs +++ b/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs @@ -1,8 +1,7 @@ //@ run-pass -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] -#[rustc_intrinsic] -unsafe fn simd_cast(x: T) -> U; +use std::intrinsics::simd::simd_cast; #[derive(Copy, Clone)] #[repr(simd)] diff --git a/tests/ui/simd/intrinsic/generic-cast.rs b/tests/ui/simd/intrinsic/generic-cast.rs index 7f398804eb4f..4b13a93f323f 100644 --- a/tests/ui/simd/intrinsic/generic-cast.rs +++ b/tests/ui/simd/intrinsic/generic-cast.rs @@ -1,6 +1,8 @@ //@ build-fail -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] + +use std::intrinsics::simd::simd_cast; #[repr(simd)] #[derive(Copy, Clone)] @@ -20,10 +22,6 @@ struct f32x4([f32; 4]); #[allow(non_camel_case_types)] struct f32x8([f32; 8]); - -#[rustc_intrinsic] -unsafe fn simd_cast(x: T) -> U; - fn main() { let x = i32x4([0, 0, 0, 0]); @@ -35,6 +33,6 @@ fn main() { simd_cast::(x); //~^ ERROR expected SIMD return type, found non-SIMD `i32` simd_cast::<_, i32x8>(x); -//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8 + //~^ ERROR return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8 } } diff --git a/tests/ui/simd/intrinsic/generic-cast.stderr b/tests/ui/simd/intrinsic/generic-cast.stderr index 1b6ac03f8c96..192aa13216b1 100644 --- a/tests/ui/simd/intrinsic/generic-cast.stderr +++ b/tests/ui/simd/intrinsic/generic-cast.stderr @@ -1,23 +1,23 @@ error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-cast.rs:31:9 + --> $DIR/generic-cast.rs:29:9 | LL | simd_cast::(0); | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-cast.rs:33:9 + --> $DIR/generic-cast.rs:31:9 | LL | simd_cast::(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD return type, found non-SIMD `i32` - --> $DIR/generic-cast.rs:35:9 + --> $DIR/generic-cast.rs:33:9 | LL | simd_cast::(x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8 - --> $DIR/generic-cast.rs:37:9 + --> $DIR/generic-cast.rs:35:9 | LL | simd_cast::<_, i32x8>(x); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/generic-comparison-pass.rs b/tests/ui/simd/intrinsic/generic-comparison-pass.rs index d0ec25036020..2ee164cdfd80 100644 --- a/tests/ui/simd/intrinsic/generic-comparison-pass.rs +++ b/tests/ui/simd/intrinsic/generic-comparison-pass.rs @@ -1,8 +1,10 @@ //@ run-pass -#![feature(repr_simd, intrinsics, concat_idents)] +#![feature(repr_simd, core_intrinsics, concat_idents)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::{simd_eq, simd_ge, simd_gt, simd_le, simd_lt, simd_ne}; + #[repr(simd)] #[derive(Copy, Clone)] struct i32x4([i32; 4]); @@ -13,24 +15,6 @@ struct u32x4(pub [u32; 4]); #[derive(Copy, Clone)] struct f32x4(pub [f32; 4]); -#[rustc_intrinsic] -unsafe fn simd_eq(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_ne(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_lt(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_le(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_gt(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_ge(x: T, y: T) -> U; - macro_rules! cmp { ($method: ident($lhs: expr, $rhs: expr)) => {{ let lhs = $lhs; diff --git a/tests/ui/simd/intrinsic/generic-comparison.rs b/tests/ui/simd/intrinsic/generic-comparison.rs index e5adb49f6a3b..ebd1f629be47 100644 --- a/tests/ui/simd/intrinsic/generic-comparison.rs +++ b/tests/ui/simd/intrinsic/generic-comparison.rs @@ -1,6 +1,6 @@ //@ build-fail -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #[repr(simd)] #[derive(Copy, Clone)] @@ -11,24 +11,7 @@ struct i32x4([i32; 4]); #[allow(non_camel_case_types)] struct i16x8([i16; 8]); - -#[rustc_intrinsic] -unsafe fn simd_eq(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_ne(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_lt(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_le(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_gt(x: T, y: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_ge(x: T, y: T) -> U; +use std::intrinsics::simd::{simd_eq, simd_ge, simd_gt, simd_le, simd_lt, simd_ne}; fn main() { let x = i32x4([0, 0, 0, 0]); @@ -61,16 +44,16 @@ fn main() { //~^ ERROR expected SIMD return type, found non-SIMD `i32` simd_eq::<_, i16x8>(x, x); -//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 + //~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 simd_ne::<_, i16x8>(x, x); -//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 + //~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 simd_lt::<_, i16x8>(x, x); -//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 + //~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 simd_le::<_, i16x8>(x, x); -//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 + //~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 simd_gt::<_, i16x8>(x, x); -//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 + //~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 simd_ge::<_, i16x8>(x, x); -//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 + //~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 } } diff --git a/tests/ui/simd/intrinsic/generic-comparison.stderr b/tests/ui/simd/intrinsic/generic-comparison.stderr index cc66d2ce40a9..a6e91bf6a36b 100644 --- a/tests/ui/simd/intrinsic/generic-comparison.stderr +++ b/tests/ui/simd/intrinsic/generic-comparison.stderr @@ -1,107 +1,107 @@ error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:37:9 + --> $DIR/generic-comparison.rs:20:9 | LL | simd_eq::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:39:9 + --> $DIR/generic-comparison.rs:22:9 | LL | simd_ne::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:41:9 + --> $DIR/generic-comparison.rs:24:9 | LL | simd_lt::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:43:9 + --> $DIR/generic-comparison.rs:26:9 | LL | simd_le::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:45:9 + --> $DIR/generic-comparison.rs:28:9 | LL | simd_gt::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:47:9 + --> $DIR/generic-comparison.rs:30:9 | LL | simd_ge::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD return type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:50:9 + --> $DIR/generic-comparison.rs:33:9 | LL | simd_eq::<_, i32>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD return type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:52:9 + --> $DIR/generic-comparison.rs:35:9 | LL | simd_ne::<_, i32>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD return type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:54:9 + --> $DIR/generic-comparison.rs:37:9 | LL | simd_lt::<_, i32>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD return type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:56:9 + --> $DIR/generic-comparison.rs:39:9 | LL | simd_le::<_, i32>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD return type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:58:9 + --> $DIR/generic-comparison.rs:41:9 | LL | simd_gt::<_, i32>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD return type, found non-SIMD `i32` - --> $DIR/generic-comparison.rs:60:9 + --> $DIR/generic-comparison.rs:43:9 | LL | simd_ge::<_, i32>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 - --> $DIR/generic-comparison.rs:63:9 + --> $DIR/generic-comparison.rs:46:9 | LL | simd_eq::<_, i16x8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 - --> $DIR/generic-comparison.rs:65:9 + --> $DIR/generic-comparison.rs:48:9 | LL | simd_ne::<_, i16x8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 - --> $DIR/generic-comparison.rs:67:9 + --> $DIR/generic-comparison.rs:50:9 | LL | simd_lt::<_, i16x8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 - --> $DIR/generic-comparison.rs:69:9 + --> $DIR/generic-comparison.rs:52:9 | LL | simd_le::<_, i16x8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 - --> $DIR/generic-comparison.rs:71:9 + --> $DIR/generic-comparison.rs:54:9 | LL | simd_gt::<_, i16x8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8 - --> $DIR/generic-comparison.rs:73:9 + --> $DIR/generic-comparison.rs:56:9 | LL | simd_ge::<_, i16x8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs index b8d872c5cb77..4dc2e4d5a80a 100644 --- a/tests/ui/simd/intrinsic/generic-elements-pass.rs +++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs @@ -1,6 +1,8 @@ //@ run-pass -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] + +use std::intrinsics::simd::{simd_extract, simd_insert, simd_shuffle}; #[repr(simd)] #[derive(Copy, Clone, Debug, PartialEq)] @@ -15,15 +17,6 @@ struct i32x4([i32; 4]); #[allow(non_camel_case_types)] struct i32x8([i32; 8]); -#[rustc_intrinsic] -unsafe fn simd_insert(x: T, idx: u32, y: E) -> T; - -#[rustc_intrinsic] -unsafe fn simd_extract(x: T, idx: u32) -> E; - -#[rustc_intrinsic] -unsafe fn simd_shuffle(x: T, y: T, idx: I) -> U; - #[repr(simd)] struct SimdShuffleIdx([u32; LEN]); diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs index 54cf35df8c75..905299a92897 100644 --- a/tests/ui/simd/intrinsic/generic-elements.rs +++ b/tests/ui/simd/intrinsic/generic-elements.rs @@ -1,8 +1,20 @@ //@ build-fail -#![feature(repr_simd, intrinsics, rustc_attrs, adt_const_params, unsized_const_params)] +#![feature( + repr_simd, + intrinsics, + core_intrinsics, + rustc_attrs, + adt_const_params, + unsized_const_params +)] #![allow(incomplete_features)] +use std::intrinsics::simd::{simd_extract, simd_insert, simd_shuffle}; + +#[rustc_intrinsic] +unsafe fn simd_shuffle_const_generic(x: T, y: T) -> U; + #[repr(simd)] #[derive(Copy, Clone)] #[allow(non_camel_case_types)] @@ -29,21 +41,6 @@ struct f32x4([f32; 4]); #[allow(non_camel_case_types)] struct f32x8([f32; 8]); - -#[rustc_intrinsic] -unsafe fn simd_insert(x: T, idx: u32, y: E) -> T; - -#[rustc_intrinsic] -unsafe fn simd_extract(x: T, idx: u32) -> E; - - -#[rustc_intrinsic] -unsafe fn simd_shuffle(x: T, y: T, idx: I) -> U; - -#[rustc_intrinsic] -unsafe fn simd_shuffle_const_generic(x: T, y: T) -> U; - - #[repr(simd)] struct SimdShuffleIdx([u32; LEN]); diff --git a/tests/ui/simd/intrinsic/generic-elements.stderr b/tests/ui/simd/intrinsic/generic-elements.stderr index 1b3e8d592133..3779aa86cee1 100644 --- a/tests/ui/simd/intrinsic/generic-elements.stderr +++ b/tests/ui/simd/intrinsic/generic-elements.stderr @@ -1,125 +1,125 @@ error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:54:9 + --> $DIR/generic-elements.rs:51:9 | LL | simd_insert(0, 0, 0); | ^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64` - --> $DIR/generic-elements.rs:56:9 + --> $DIR/generic-elements.rs:53:9 | LL | simd_insert(x, 0, 1.0); | ^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32` - --> $DIR/generic-elements.rs:58:9 + --> $DIR/generic-elements.rs:55:9 | LL | simd_extract::<_, f32>(x, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:62:9 + --> $DIR/generic-elements.rs:59:9 | LL | simd_shuffle::(0, 0, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:65:9 + --> $DIR/generic-elements.rs:62:9 | LL | simd_shuffle::(0, 0, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:68:9 + --> $DIR/generic-elements.rs:65:9 | LL | simd_shuffle::(0, 0, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` - --> $DIR/generic-elements.rs:71:9 + --> $DIR/generic-elements.rs:68:9 | LL | simd_shuffle::<_, _, f32x2>(x, x, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` - --> $DIR/generic-elements.rs:73:9 + --> $DIR/generic-elements.rs:70:9 | LL | simd_shuffle::<_, _, f32x4>(x, x, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` - --> $DIR/generic-elements.rs:75:9 + --> $DIR/generic-elements.rs:72:9 | LL | simd_shuffle::<_, _, f32x8>(x, x, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:78:9 + --> $DIR/generic-elements.rs:75:9 | LL | simd_shuffle::<_, _, i32x8>(x, x, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 4, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:80:9 + --> $DIR/generic-elements.rs:77:9 | LL | simd_shuffle::<_, _, i32x8>(x, x, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 8, found `i32x2` with length 2 - --> $DIR/generic-elements.rs:82:9 + --> $DIR/generic-elements.rs:79:9 | LL | simd_shuffle::<_, _, i32x2>(x, x, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:86:9 + --> $DIR/generic-elements.rs:83:9 | LL | simd_shuffle_const_generic::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:89:9 + --> $DIR/generic-elements.rs:86:9 | LL | simd_shuffle_const_generic::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:92:9 + --> $DIR/generic-elements.rs:89:9 | LL | simd_shuffle_const_generic::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` - --> $DIR/generic-elements.rs:95:9 + --> $DIR/generic-elements.rs:92:9 | LL | simd_shuffle_const_generic::<_, f32x2, I2>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` - --> $DIR/generic-elements.rs:97:9 + --> $DIR/generic-elements.rs:94:9 | LL | simd_shuffle_const_generic::<_, f32x4, I4>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` - --> $DIR/generic-elements.rs:99:9 + --> $DIR/generic-elements.rs:96:9 | LL | simd_shuffle_const_generic::<_, f32x8, I8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:102:9 + --> $DIR/generic-elements.rs:99:9 | LL | simd_shuffle_const_generic::<_, i32x8, I2>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:104:9 + --> $DIR/generic-elements.rs:101:9 | LL | simd_shuffle_const_generic::<_, i32x8, I4>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2 - --> $DIR/generic-elements.rs:106:9 + --> $DIR/generic-elements.rs:103:9 | LL | simd_shuffle_const_generic::<_, i32x2, I8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/generic-gather-pass.rs b/tests/ui/simd/intrinsic/generic-gather-pass.rs index 0b2cf47e9898..b98d4d6575bb 100644 --- a/tests/ui/simd/intrinsic/generic-gather-pass.rs +++ b/tests/ui/simd/intrinsic/generic-gather-pass.rs @@ -3,19 +3,15 @@ // Test that the simd_{gather,scatter} intrinsics produce the correct results. -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::{simd_gather, simd_scatter}; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] struct x4(pub [T; 4]); -#[rustc_intrinsic] -unsafe fn simd_gather(x: T, y: U, z: V) -> T; - -#[rustc_intrinsic] -unsafe fn simd_scatter(x: T, y: U, z: V) -> (); - fn main() { let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.]; @@ -26,12 +22,8 @@ fn main() { // reading from *const unsafe { let pointer = x.as_ptr(); - let pointers = x4([ - pointer.offset(0), - pointer.offset(2), - pointer.offset(4), - pointer.offset(6) - ]); + let pointers = + x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); let r_strided = simd_gather(default, pointers, mask); @@ -41,12 +33,8 @@ fn main() { // reading from *mut unsafe { let pointer = x.as_mut_ptr(); - let pointers = x4([ - pointer.offset(0), - pointer.offset(2), - pointer.offset(4), - pointer.offset(6) - ]); + let pointers = + x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); let r_strided = simd_gather(default, pointers, mask); @@ -56,12 +44,8 @@ fn main() { // writing to *mut unsafe { let pointer = x.as_mut_ptr(); - let pointers = x4([ - pointer.offset(0), - pointer.offset(2), - pointer.offset(4), - pointer.offset(6) - ]); + let pointers = + x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); let values = x4([42_f32, 43_f32, 44_f32, 45_f32]); simd_scatter(values, pointers, mask); @@ -78,7 +62,7 @@ fn main() { &x[4] as *const f32, &x[5] as *const f32, &x[6] as *const f32, - &x[7] as *const f32 + &x[7] as *const f32, ]; let default = x4([y[0], y[0], y[0], y[0]]); @@ -87,12 +71,8 @@ fn main() { // reading from *const unsafe { let pointer = y.as_ptr(); - let pointers = x4([ - pointer.offset(0), - pointer.offset(2), - pointer.offset(4), - pointer.offset(6) - ]); + let pointers = + x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); let r_strided = simd_gather(default, pointers, mask); @@ -102,12 +82,8 @@ fn main() { // reading from *mut unsafe { let pointer = y.as_mut_ptr(); - let pointers = x4([ - pointer.offset(0), - pointer.offset(2), - pointer.offset(4), - pointer.offset(6) - ]); + let pointers = + x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); let r_strided = simd_gather(default, pointers, mask); @@ -117,12 +93,8 @@ fn main() { // writing to *mut unsafe { let pointer = y.as_mut_ptr(); - let pointers = x4([ - pointer.offset(0), - pointer.offset(2), - pointer.offset(4), - pointer.offset(6) - ]); + let pointers = + x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); let values = x4([y[7], y[6], y[5], y[1]]); simd_scatter(values, pointers, mask); @@ -135,7 +107,7 @@ fn main() { &x[4] as *const f32, &x[5] as *const f32, &x[1] as *const f32, - &x[7] as *const f32 + &x[7] as *const f32, ]; assert_eq!(y, s); } diff --git a/tests/ui/simd/intrinsic/generic-reduction-pass.rs b/tests/ui/simd/intrinsic/generic-reduction-pass.rs index 8408d0f203bf..9d76df49a8a9 100644 --- a/tests/ui/simd/intrinsic/generic-reduction-pass.rs +++ b/tests/ui/simd/intrinsic/generic-reduction-pass.rs @@ -1,12 +1,15 @@ //@ run-pass #![allow(non_camel_case_types)] - //@ ignore-emscripten // Test that the simd_reduce_{op} intrinsics produce the correct results. +#![feature(repr_simd, core_intrinsics)] -#![feature(repr_simd, intrinsics)] -#[allow(non_camel_case_types)] +use std::intrinsics::simd::{ + simd_reduce_add_ordered, simd_reduce_add_unordered, simd_reduce_all, simd_reduce_and, + simd_reduce_any, simd_reduce_max, simd_reduce_min, simd_reduce_mul_ordered, + simd_reduce_mul_unordered, simd_reduce_or, simd_reduce_xor, +}; #[repr(simd)] #[derive(Copy, Clone)] @@ -24,39 +27,6 @@ struct f32x4(pub [f32; 4]); #[derive(Copy, Clone)] struct b8x4(pub [i8; 4]); -#[rustc_intrinsic] -unsafe fn simd_reduce_add_unordered(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_mul_unordered(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_add_ordered(x: T, acc: U) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_mul_ordered(x: T, acc: U) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_min(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_max(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_and(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_or(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_xor(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_all(x: T) -> bool; - -#[rustc_intrinsic] -unsafe fn simd_reduce_any(x: T) -> bool; - fn main() { unsafe { let x = i32x4([1, -2, 3, 4]); diff --git a/tests/ui/simd/intrinsic/generic-reduction.rs b/tests/ui/simd/intrinsic/generic-reduction.rs index ead13250643c..1ba187339d0a 100644 --- a/tests/ui/simd/intrinsic/generic-reduction.rs +++ b/tests/ui/simd/intrinsic/generic-reduction.rs @@ -4,9 +4,14 @@ // Test that the simd_reduce_{op} intrinsics produce ok-ish error // messages when misused. -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::{ + simd_reduce_add_ordered, simd_reduce_all, simd_reduce_and, simd_reduce_any, + simd_reduce_mul_ordered, simd_reduce_or, simd_reduce_xor, +}; + #[repr(simd)] #[derive(Copy, Clone)] pub struct f32x4(pub [f32; 4]); @@ -15,27 +20,6 @@ pub struct f32x4(pub [f32; 4]); #[derive(Copy, Clone)] pub struct u32x4(pub [u32; 4]); -#[rustc_intrinsic] -unsafe fn simd_reduce_add_ordered(x: T, y: U) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_mul_ordered(x: T, y: U) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_and(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_or(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_xor(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_reduce_all(x: T) -> bool; - -#[rustc_intrinsic] -unsafe fn simd_reduce_any(x: T) -> bool; - fn main() { let x = u32x4([0, 0, 0, 0]); let z = f32x4([0.0, 0.0, 0.0, 0.0]); diff --git a/tests/ui/simd/intrinsic/generic-reduction.stderr b/tests/ui/simd/intrinsic/generic-reduction.stderr index 302b9ae1d778..31294a77e467 100644 --- a/tests/ui/simd/intrinsic/generic-reduction.stderr +++ b/tests/ui/simd/intrinsic/generic-reduction.stderr @@ -1,59 +1,59 @@ error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32` - --> $DIR/generic-reduction.rs:44:9 + --> $DIR/generic-reduction.rs:28:9 | LL | simd_reduce_add_ordered(z, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32` - --> $DIR/generic-reduction.rs:46:9 + --> $DIR/generic-reduction.rs:30:9 | LL | simd_reduce_mul_ordered(z, 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/generic-reduction.rs:49:22 + --> $DIR/generic-reduction.rs:33:22 | LL | let _: f32 = simd_reduce_and(x); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/generic-reduction.rs:51:22 + --> $DIR/generic-reduction.rs:35:22 | LL | let _: f32 = simd_reduce_or(x); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/generic-reduction.rs:53:22 + --> $DIR/generic-reduction.rs:37:22 | LL | let _: f32 = simd_reduce_xor(x); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32` - --> $DIR/generic-reduction.rs:56:22 + --> $DIR/generic-reduction.rs:40:22 | LL | let _: f32 = simd_reduce_and(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32` - --> $DIR/generic-reduction.rs:58:22 + --> $DIR/generic-reduction.rs:42:22 | LL | let _: f32 = simd_reduce_or(z); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32` - --> $DIR/generic-reduction.rs:60:22 + --> $DIR/generic-reduction.rs:44:22 | LL | let _: f32 = simd_reduce_xor(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool` - --> $DIR/generic-reduction.rs:63:23 + --> $DIR/generic-reduction.rs:47:23 | LL | let _: bool = simd_reduce_all(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool` - --> $DIR/generic-reduction.rs:65:23 + --> $DIR/generic-reduction.rs:49:23 | LL | let _: bool = simd_reduce_any(z); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/generic-select-pass.rs b/tests/ui/simd/intrinsic/generic-select-pass.rs index 6b1b6cb79dbc..0e5f7c4902f3 100644 --- a/tests/ui/simd/intrinsic/generic-select-pass.rs +++ b/tests/ui/simd/intrinsic/generic-select-pass.rs @@ -1,13 +1,12 @@ //@ run-pass #![allow(non_camel_case_types)] - //@ ignore-emscripten //@ ignore-endian-big behavior of simd_select_bitmask is endian-specific // Test that the simd_select intrinsics produces correct results. +#![feature(repr_simd, core_intrinsics)] -#![feature(repr_simd, intrinsics)] -#[allow(non_camel_case_types)] +use std::intrinsics::simd::{simd_select, simd_select_bitmask}; #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] @@ -29,13 +28,6 @@ struct f32x4(pub [f32; 4]); #[derive(Copy, Clone, PartialEq, Debug)] struct b8x4(pub [i8; 4]); -#[rustc_intrinsic] -unsafe fn simd_select(x: T, a: U, b: U) -> U; - -#[rustc_intrinsic] -unsafe fn simd_select_bitmask(x: T, a: U, b: U) -> U; - - fn main() { let m0 = b8x4([!0, !0, !0, !0]); let m1 = b8x4([0, 0, 0, 0]); diff --git a/tests/ui/simd/intrinsic/generic-select.rs b/tests/ui/simd/intrinsic/generic-select.rs index 340fe3f35929..917ad3ca6046 100644 --- a/tests/ui/simd/intrinsic/generic-select.rs +++ b/tests/ui/simd/intrinsic/generic-select.rs @@ -3,9 +3,11 @@ // Test that the simd_select intrinsic produces ok-ish error // messages when misused. -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::{simd_select, simd_select_bitmask}; + #[repr(simd)] #[derive(Copy, Clone)] pub struct f32x4(pub [f32; 4]); @@ -22,14 +24,6 @@ struct b8x4(pub [i8; 4]); #[derive(Copy, Clone, PartialEq)] struct b8x8(pub [i8; 8]); - -#[rustc_intrinsic] -unsafe fn simd_select(x: T, a: U, b: U) -> U; - -#[rustc_intrinsic] -unsafe fn simd_select_bitmask(x: T, a: U, b: U) -> U; - - fn main() { let m4 = b8x4([0, 0, 0, 0]); let m8 = b8x8([0, 0, 0, 0, 0, 0, 0, 0]); diff --git a/tests/ui/simd/intrinsic/generic-select.stderr b/tests/ui/simd/intrinsic/generic-select.stderr index a97fc91f951d..c46584d117ce 100644 --- a/tests/ui/simd/intrinsic/generic-select.stderr +++ b/tests/ui/simd/intrinsic/generic-select.stderr @@ -1,47 +1,47 @@ error[E0511]: invalid monomorphization of `simd_select` intrinsic: mismatched lengths: mask length `8` != other vector length `4` - --> $DIR/generic-select.rs:42:9 + --> $DIR/generic-select.rs:36:9 | LL | simd_select(m8, x, x); | ^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `u32`, expected `i_` - --> $DIR/generic-select.rs:45:9 + --> $DIR/generic-select.rs:39:9 | LL | simd_select(x, x, x); | ^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `f32`, expected `i_` - --> $DIR/generic-select.rs:48:9 + --> $DIR/generic-select.rs:42:9 | LL | simd_select(z, z, z); | ^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select` intrinsic: expected SIMD argument type, found non-SIMD `u32` - --> $DIR/generic-select.rs:51:9 + --> $DIR/generic-select.rs:45:9 | LL | simd_select(m4, 0u32, 1u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: invalid bitmask `u16`, expected `u8` or `[u8; 1]` - --> $DIR/generic-select.rs:54:9 + --> $DIR/generic-select.rs:48:9 | LL | simd_select_bitmask(0u16, x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: expected SIMD argument type, found non-SIMD `u32` - --> $DIR/generic-select.rs:57:9 + --> $DIR/generic-select.rs:51:9 | LL | simd_select_bitmask(0u8, 1u32, 2u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: invalid bitmask `f32`, expected `u8` or `[u8; 1]` - --> $DIR/generic-select.rs:60:9 + --> $DIR/generic-select.rs:54:9 | LL | simd_select_bitmask(0.0f32, x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: invalid bitmask `&str`, expected `u8` or `[u8; 1]` - --> $DIR/generic-select.rs:63:9 + --> $DIR/generic-select.rs:57:9 | LL | simd_select_bitmask("x", x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/generic-shuffle.rs b/tests/ui/simd/intrinsic/generic-shuffle.rs index 1223b8ebe190..7cfd764f5d5e 100644 --- a/tests/ui/simd/intrinsic/generic-shuffle.rs +++ b/tests/ui/simd/intrinsic/generic-shuffle.rs @@ -3,16 +3,14 @@ // Test that the simd_shuffle intrinsic produces ok-ish error // messages when misused. -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] + +use std::intrinsics::simd::simd_shuffle; #[repr(simd)] #[derive(Copy, Clone)] pub struct Simd([T; N]); -#[rustc_intrinsic] -unsafe fn simd_shuffle(a: T, b: T, i: I) -> U; - - fn main() { const I: Simd = Simd([0; 2]); const I2: Simd = Simd([0.; 2]); diff --git a/tests/ui/simd/intrinsic/generic-shuffle.stderr b/tests/ui/simd/intrinsic/generic-shuffle.stderr index 7e6d51a5f655..e8cd528b7020 100644 --- a/tests/ui/simd/intrinsic/generic-shuffle.stderr +++ b/tests/ui/simd/intrinsic/generic-shuffle.stderr @@ -1,23 +1,23 @@ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `[u32; 2]` - --> $DIR/generic-shuffle.rs:24:31 + --> $DIR/generic-shuffle.rs:22:31 | LL | let _: Simd = simd_shuffle(v, v, const { [0u32; 2] }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd` with length 4 - --> $DIR/generic-shuffle.rs:27:31 + --> $DIR/generic-shuffle.rs:25:31 | LL | let _: Simd = simd_shuffle(v, v, I); | ^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd`), found `Simd` with element type `f32` - --> $DIR/generic-shuffle.rs:30:31 + --> $DIR/generic-shuffle.rs:28:31 | LL | let _: Simd = simd_shuffle(v, v, I); | ^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `Simd` - --> $DIR/generic-shuffle.rs:33:31 + --> $DIR/generic-shuffle.rs:31:31 | LL | let _: Simd = simd_shuffle(v, v, I2); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs index b324ac40749f..49a26ff57341 100644 --- a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs +++ b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs @@ -3,10 +3,9 @@ // //@ run-pass //@ compile-flags: -Zmir-opt-level=4 -#![feature(intrinsics, repr_simd)] +#![feature(core_intrinsics, repr_simd)] -#[rustc_intrinsic] -unsafe fn simd_shuffle(x: T, y: T, idx: I) -> U; +use std::intrinsics::simd::simd_shuffle; #[repr(simd)] #[derive(Debug, PartialEq)] diff --git a/tests/ui/simd/intrinsic/inlining-issue67557.rs b/tests/ui/simd/intrinsic/inlining-issue67557.rs index 319bb15c0157..13e7266b2a56 100644 --- a/tests/ui/simd/intrinsic/inlining-issue67557.rs +++ b/tests/ui/simd/intrinsic/inlining-issue67557.rs @@ -3,10 +3,9 @@ // //@ run-pass //@ compile-flags: -Zmir-opt-level=4 -#![feature(intrinsics, repr_simd)] +#![feature(core_intrinsics, repr_simd)] -#[rustc_intrinsic] -unsafe fn simd_shuffle(x: T, y: T, idx: I) -> U; +use std::intrinsics::simd::simd_shuffle; #[repr(simd)] #[derive(Debug, PartialEq)] @@ -36,7 +35,6 @@ fn assert_10_13(x: Simd2) { assert_eq!(x, Simd2([10, 13])); } - #[inline(always)] unsafe fn inline_me() -> Simd2 { const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 3]); diff --git a/tests/ui/simd/intrinsic/issue-85855.rs b/tests/ui/simd/intrinsic/issue-85855.rs index daeea793d1bc..cbaa8f046bee 100644 --- a/tests/ui/simd/intrinsic/issue-85855.rs +++ b/tests/ui/simd/intrinsic/issue-85855.rs @@ -3,8 +3,7 @@ // that no ICE occurs in these cases. #![feature(intrinsics)] -#![crate_type="lib"] - +#![crate_type = "lib"] #[rustc_intrinsic] unsafe fn simd_saturating_add<'a, T: 'a>(x: T, y: T); diff --git a/tests/ui/simd/intrinsic/issue-85855.stderr b/tests/ui/simd/intrinsic/issue-85855.stderr index b91a606ba68a..af61c6fcdc13 100644 --- a/tests/ui/simd/intrinsic/issue-85855.stderr +++ b/tests/ui/simd/intrinsic/issue-85855.stderr @@ -1,17 +1,17 @@ error[E0094]: intrinsic has wrong number of lifetime parameters: found 1, expected 0 - --> $DIR/issue-85855.rs:10:30 + --> $DIR/issue-85855.rs:9:30 | LL | unsafe fn simd_saturating_add<'a, T: 'a>(x: T, y: T); | ^^^^^^^^^^^ expected 0 lifetime parameters error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1 - --> $DIR/issue-85855.rs:17:19 + --> $DIR/issue-85855.rs:16:19 | LL | unsafe fn simd_sub(x: T, y: U); | ^^^^^^ expected 1 type parameter error[E0094]: intrinsic has wrong number of const parameters: found 1, expected 0 - --> $DIR/issue-85855.rs:21:19 + --> $DIR/issue-85855.rs:20:19 | LL | unsafe fn simd_mul(x: T, y: T); | ^^^^^^^^^^^^^^^^^^^ expected 0 const parameters diff --git a/tests/ui/simd/intrinsic/ptr-cast.rs b/tests/ui/simd/intrinsic/ptr-cast.rs index 559b8ba1b5c2..3a73c0273e1a 100644 --- a/tests/ui/simd/intrinsic/ptr-cast.rs +++ b/tests/ui/simd/intrinsic/ptr-cast.rs @@ -1,16 +1,8 @@ //@ run-pass -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] - -#[rustc_intrinsic] -unsafe fn simd_cast_ptr(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_expose_provenance(x: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_with_exposed_provenance(x: T) -> U; +use std::intrinsics::simd::{simd_cast_ptr, simd_expose_provenance, simd_with_exposed_provenance}; #[derive(Copy, Clone)] #[repr(simd)] diff --git a/tests/ui/simd/issue-105439.rs b/tests/ui/simd/issue-105439.rs index 108bb282df2a..0a44f36fb2ec 100644 --- a/tests/ui/simd/issue-105439.rs +++ b/tests/ui/simd/issue-105439.rs @@ -1,17 +1,13 @@ //@ run-pass //@ compile-flags: -O -Zverify-llvm-ir -#![feature(repr_simd)] -#![feature(intrinsics)] +#![feature(repr_simd, core_intrinsics)] #[allow(non_camel_case_types)] #[derive(Clone, Copy)] #[repr(simd)] struct i32x4([i32; 4]); -#[rustc_intrinsic] -pub(crate) unsafe fn simd_add(x: T, y: T) -> T; - #[inline(always)] fn to_array(a: i32x4) -> [i32; 4] { a.0 @@ -19,6 +15,6 @@ fn to_array(a: i32x4) -> [i32; 4] { fn main() { let a = i32x4([1, 2, 3, 4]); - let b = unsafe { simd_add(a, a) }; + let b = unsafe { std::intrinsics::simd::simd_add(a, a) }; assert_eq!(to_array(b), [2, 4, 6, 8]); } diff --git a/tests/ui/simd/issue-39720.rs b/tests/ui/simd/issue-39720.rs index c3c4750d6deb..db441e551679 100644 --- a/tests/ui/simd/issue-39720.rs +++ b/tests/ui/simd/issue-39720.rs @@ -1,6 +1,6 @@ //@ run-pass -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #[repr(simd)] #[derive(Copy, Clone, Debug)] @@ -10,11 +10,8 @@ pub struct Char3(pub [i8; 3]); #[derive(Copy, Clone, Debug)] pub struct Short3(pub [i16; 3]); -#[rustc_intrinsic] -unsafe fn simd_cast(x: T) -> U; - fn main() { - let cast: Short3 = unsafe { simd_cast(Char3([10, -3, -9])) }; + let cast: Short3 = unsafe { std::intrinsics::simd::simd_cast(Char3([10, -3, -9])) }; println!("{:?}", cast); } diff --git a/tests/ui/simd/issue-85915-simd-ptrs.rs b/tests/ui/simd/issue-85915-simd-ptrs.rs index 2e7baf48ee32..4e2379d05251 100644 --- a/tests/ui/simd/issue-85915-simd-ptrs.rs +++ b/tests/ui/simd/issue-85915-simd-ptrs.rs @@ -3,9 +3,11 @@ // Short form of the generic gather/scatter tests, // verifying simd([*const T; N]) and simd([*mut T; N]) pass typeck and work. -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::{simd_gather, simd_scatter}; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] struct cptrx4([*const T; 4]); @@ -22,13 +24,6 @@ struct f32x4([f32; 4]); #[derive(Copy, Clone, PartialEq, Debug)] struct i32x4([i32; 4]); - -#[rustc_intrinsic] -unsafe fn simd_gather(x: T, y: U, z: V) -> T; - -#[rustc_intrinsic] -unsafe fn simd_scatter(x: T, y: U, z: V) -> (); - fn main() { let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.]; @@ -39,11 +34,11 @@ fn main() { // reading from *const unsafe { let pointer = &x as *const f32; - let pointers = cptrx4([ + let pointers = cptrx4([ pointer.offset(0) as *const f32, pointer.offset(2), pointer.offset(4), - pointer.offset(6) + pointer.offset(6), ]); let r_strided = simd_gather(default, pointers, mask); @@ -58,7 +53,7 @@ fn main() { pointer.offset(0) as *mut f32, pointer.offset(2), pointer.offset(4), - pointer.offset(6) + pointer.offset(6), ]); let values = f32x4([42_f32, 43_f32, 44_f32, 45_f32]); diff --git a/tests/ui/simd/issue-89193.rs b/tests/ui/simd/issue-89193.rs index 4b4fb9d91696..a6c3017572a1 100644 --- a/tests/ui/simd/issue-89193.rs +++ b/tests/ui/simd/issue-89193.rs @@ -3,16 +3,15 @@ // Test that simd gather instructions on slice of usize don't cause crash // See issue #89183 - https://github.com/rust-lang/rust/issues/89193 -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_gather; + #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] struct x4(pub [T; 4]); -#[rustc_intrinsic] -unsafe fn simd_gather(x: T, y: U, z: V) -> T; - fn main() { let x: [usize; 4] = [10, 11, 12, 13]; let default = x4([0_usize, 1, 2, 3]); @@ -22,12 +21,8 @@ fn main() { unsafe { let pointer = x.as_ptr(); - let pointers = x4([ - pointer.offset(0), - pointer.offset(1), - pointer.offset(2), - pointer.offset(3) - ]); + let pointers = + x4([pointer.offset(0), pointer.offset(1), pointer.offset(2), pointer.offset(3)]); let result = simd_gather(default, pointers, mask); assert_eq!(result, expected); } @@ -39,12 +34,8 @@ fn main() { unsafe { let pointer = x.as_ptr(); - let pointers = x4([ - pointer.offset(0), - pointer.offset(1), - pointer.offset(2), - pointer.offset(3) - ]); + let pointers = + x4([pointer.offset(0), pointer.offset(1), pointer.offset(2), pointer.offset(3)]); let result = simd_gather(default, pointers, mask); assert_eq!(result, expected); } diff --git a/tests/ui/simd/masked-load-store-build-fail.rs b/tests/ui/simd/masked-load-store-build-fail.rs index b8742184eb02..ad2de5561033 100644 --- a/tests/ui/simd/masked-load-store-build-fail.rs +++ b/tests/ui/simd/masked-load-store-build-fail.rs @@ -1,12 +1,7 @@ //@ build-fail -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] - -#[rustc_intrinsic] -unsafe fn simd_masked_load(mask: M, pointer: P, values: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_masked_store(mask: M, pointer: P, values: T) -> (); +use std::intrinsics::simd::{simd_masked_load, simd_masked_store}; #[derive(Copy, Clone)] #[repr(simd)] @@ -17,60 +12,28 @@ fn main() { let mut arr = [4u8, 5, 6, 7]; let default = Simd::([9; 4]); - simd_masked_load( - Simd::([-1, 0, -1, -1, 0, 0, 0, 0]), - arr.as_ptr(), - default - ); - //~^^^^^ ERROR expected third argument with length 8 (same as input type `Simd`), found `Simd` with length 4 + simd_masked_load(Simd::([-1, 0, -1, -1, 0, 0, 0, 0]), arr.as_ptr(), default); + //~^ ERROR expected third argument with length 8 (same as input type `Simd`), found `Simd` with length 4 - simd_masked_load( - Simd::([-1, 0, -1, -1]), - arr.as_ptr() as *const i8, - default - ); - //~^^^^^ ERROR expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*_ u8` + simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr() as *const i8, default); + //~^ ERROR expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*_ u8` - simd_masked_load( - Simd::([-1, 0, -1, -1]), - arr.as_ptr(), - Simd::([9; 4]) - ); - //~^^^^^ ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*_ u32` + simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); + //~^ ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*_ u32` - simd_masked_load( - Simd::([1, 0, 1, 1]), - arr.as_ptr(), - default - ); - //~^^^^^ ERROR expected element type `u8` of third argument `Simd` to be a signed integer type + simd_masked_load(Simd::([1, 0, 1, 1]), arr.as_ptr(), default); + //~^ ERROR expected element type `u8` of third argument `Simd` to be a signed integer type - simd_masked_store( - Simd([-1i8; 4]), - arr.as_ptr(), - Simd([5u32; 4]) - ); - //~^^^^^ ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*mut u32` + simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u32; 4])); + //~^ ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*mut u32` - simd_masked_store( - Simd([-1i8; 4]), - arr.as_ptr(), - Simd([5u8; 4]) - ); - //~^^^^^ ERROR expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*mut u8` + simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u8; 4])); + //~^ ERROR expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*mut u8` - simd_masked_store( - Simd([-1i8; 4]), - arr.as_mut_ptr(), - Simd([5u8; 2]) - ); - //~^^^^^ ERROR expected third argument with length 4 (same as input type `Simd`), found `Simd` with length 2 + simd_masked_store(Simd([-1i8; 4]), arr.as_mut_ptr(), Simd([5u8; 2])); + //~^ ERROR expected third argument with length 4 (same as input type `Simd`), found `Simd` with length 2 - simd_masked_store( - Simd([1u32; 4]), - arr.as_mut_ptr(), - Simd([5u8; 4]) - ); - //~^^^^^ ERROR expected element type `u8` of third argument `Simd` to be a signed integer type + simd_masked_store(Simd([1u32; 4]), arr.as_mut_ptr(), Simd([5u8; 4])); + //~^ ERROR expected element type `u8` of third argument `Simd` to be a signed integer type } } diff --git a/tests/ui/simd/masked-load-store-build-fail.stderr b/tests/ui/simd/masked-load-store-build-fail.stderr index 8a8d8eb99e27..d57e0aa539f5 100644 --- a/tests/ui/simd/masked-load-store-build-fail.stderr +++ b/tests/ui/simd/masked-load-store-build-fail.stderr @@ -1,82 +1,50 @@ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected third argument with length 8 (same as input type `Simd`), found `Simd` with length 4 - --> $DIR/masked-load-store-build-fail.rs:20:9 + --> $DIR/masked-load-store-build-fail.rs:15:9 | -LL | / simd_masked_load( -LL | | Simd::([-1, 0, -1, -1, 0, 0, 0, 0]), -LL | | arr.as_ptr(), -LL | | default -LL | | ); - | |_________^ +LL | simd_masked_load(Simd::([-1, 0, -1, -1, 0, 0, 0, 0]), arr.as_ptr(), default); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*_ u8` - --> $DIR/masked-load-store-build-fail.rs:27:9 + --> $DIR/masked-load-store-build-fail.rs:18:9 | -LL | / simd_masked_load( -LL | | Simd::([-1, 0, -1, -1]), -LL | | arr.as_ptr() as *const i8, -LL | | default -LL | | ); - | |_________^ +LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr() as *const i8, default); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*_ u32` - --> $DIR/masked-load-store-build-fail.rs:34:9 + --> $DIR/masked-load-store-build-fail.rs:21:9 | -LL | / simd_masked_load( -LL | | Simd::([-1, 0, -1, -1]), -LL | | arr.as_ptr(), -LL | | Simd::([9; 4]) -LL | | ); - | |_________^ +LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u8` of third argument `Simd` to be a signed integer type - --> $DIR/masked-load-store-build-fail.rs:41:9 + --> $DIR/masked-load-store-build-fail.rs:24:9 | -LL | / simd_masked_load( -LL | | Simd::([1, 0, 1, 1]), -LL | | arr.as_ptr(), -LL | | default -LL | | ); - | |_________^ +LL | simd_masked_load(Simd::([1, 0, 1, 1]), arr.as_ptr(), default); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*mut u32` - --> $DIR/masked-load-store-build-fail.rs:48:9 + --> $DIR/masked-load-store-build-fail.rs:27:9 | -LL | / simd_masked_store( -LL | | Simd([-1i8; 4]), -LL | | arr.as_ptr(), -LL | | Simd([5u32; 4]) -LL | | ); - | |_________^ +LL | simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u32; 4])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*mut u8` - --> $DIR/masked-load-store-build-fail.rs:55:9 + --> $DIR/masked-load-store-build-fail.rs:30:9 | -LL | / simd_masked_store( -LL | | Simd([-1i8; 4]), -LL | | arr.as_ptr(), -LL | | Simd([5u8; 4]) -LL | | ); - | |_________^ +LL | simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u8; 4])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected third argument with length 4 (same as input type `Simd`), found `Simd` with length 2 - --> $DIR/masked-load-store-build-fail.rs:62:9 + --> $DIR/masked-load-store-build-fail.rs:33:9 | -LL | / simd_masked_store( -LL | | Simd([-1i8; 4]), -LL | | arr.as_mut_ptr(), -LL | | Simd([5u8; 2]) -LL | | ); - | |_________^ +LL | simd_masked_store(Simd([-1i8; 4]), arr.as_mut_ptr(), Simd([5u8; 2])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u8` of third argument `Simd` to be a signed integer type - --> $DIR/masked-load-store-build-fail.rs:69:9 + --> $DIR/masked-load-store-build-fail.rs:36:9 | -LL | / simd_masked_store( -LL | | Simd([1u32; 4]), -LL | | arr.as_mut_ptr(), -LL | | Simd([5u8; 4]) -LL | | ); - | |_________^ +LL | simd_masked_store(Simd([1u32; 4]), arr.as_mut_ptr(), Simd([5u8; 4])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 8 previous errors diff --git a/tests/ui/simd/masked-load-store-check-fail.rs b/tests/ui/simd/masked-load-store-check-fail.rs index 0f36bf6443f9..3ed47cd9ed40 100644 --- a/tests/ui/simd/masked-load-store-check-fail.rs +++ b/tests/ui/simd/masked-load-store-check-fail.rs @@ -1,11 +1,7 @@ //@ check-fail -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] -#[rustc_intrinsic] -unsafe fn simd_masked_load(mask: M, pointer: P, values: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_masked_store(mask: M, pointer: P, values: T) -> (); +use std::intrinsics::simd::{simd_masked_load, simd_masked_store}; #[derive(Copy, Clone)] #[repr(simd)] @@ -16,18 +12,11 @@ fn main() { let mut arr = [4u8, 5, 6, 7]; let default = Simd::([9; 4]); - let _x: Simd = simd_masked_load( - Simd::([-1, 0, -1, -1]), - arr.as_ptr(), - Simd::([9; 4]) - ); - //~^^ ERROR mismatched types + let _x: Simd = + simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); + //~^ ERROR mismatched types - let _x: Simd = simd_masked_load( - Simd::([1, 0, 1, 1]), - arr.as_ptr(), - default - ); - //~^^ ERROR mismatched types + let _x: Simd = simd_masked_load(Simd::([1, 0, 1, 1]), arr.as_ptr(), default); + //~^ ERROR mismatched types } } diff --git a/tests/ui/simd/masked-load-store-check-fail.stderr b/tests/ui/simd/masked-load-store-check-fail.stderr index fa65798fc94d..1c9f9d246df5 100644 --- a/tests/ui/simd/masked-load-store-check-fail.stderr +++ b/tests/ui/simd/masked-load-store-check-fail.stderr @@ -1,58 +1,38 @@ error[E0308]: mismatched types - --> $DIR/masked-load-store-check-fail.rs:22:13 + --> $DIR/masked-load-store-check-fail.rs:16:76 | -LL | let _x: Simd = simd_masked_load( - | ---------------- arguments to this function are incorrect -... -LL | Simd::([9; 4]) - | ^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4` +LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); + | ---------------- arguments to this function are incorrect ^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4` | = note: expected struct `Simd<_, 2>` found struct `Simd<_, 4>` help: the return type of this call is `Simd` due to the type of the argument passed - --> $DIR/masked-load-store-check-fail.rs:19:31 + --> $DIR/masked-load-store-check-fail.rs:16:13 | -LL | let _x: Simd = simd_masked_load( - | _______________________________^ -LL | | Simd::([-1, 0, -1, -1]), -LL | | arr.as_ptr(), -LL | | Simd::([9; 4]) - | | --------------------- this argument influences the return type of `simd_masked_load` -LL | | ); - | |_________^ +LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------^ + | | + | this argument influences the return type of `simd_masked_load` note: function defined here - --> $DIR/masked-load-store-check-fail.rs:5:11 - | -LL | unsafe fn simd_masked_load(mask: M, pointer: P, values: T) -> T; - | ^^^^^^^^^^^^^^^^ --------- + --> $SRC_DIR/core/src/intrinsics/simd.rs:LL:COL error[E0308]: mismatched types - --> $DIR/masked-load-store-check-fail.rs:29:13 + --> $DIR/masked-load-store-check-fail.rs:19:92 | -LL | let _x: Simd = simd_masked_load( - | ---------------- arguments to this function are incorrect -... -LL | default - | ^^^^^^^ expected `Simd`, found `Simd` +LL | let _x: Simd = simd_masked_load(Simd::([1, 0, 1, 1]), arr.as_ptr(), default); + | ---------------- arguments to this function are incorrect ^^^^^^^ expected `Simd`, found `Simd` | = note: expected struct `Simd` found struct `Simd` help: the return type of this call is `Simd` due to the type of the argument passed - --> $DIR/masked-load-store-check-fail.rs:26:32 + --> $DIR/masked-load-store-check-fail.rs:19:32 | -LL | let _x: Simd = simd_masked_load( - | ________________________________^ -LL | | Simd::([1, 0, 1, 1]), -LL | | arr.as_ptr(), -LL | | default - | | ------- this argument influences the return type of `simd_masked_load` -LL | | ); - | |_________^ +LL | let _x: Simd = simd_masked_load(Simd::([1, 0, 1, 1]), arr.as_ptr(), default); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^ + | | + | this argument influences the return type of `simd_masked_load` note: function defined here - --> $DIR/masked-load-store-check-fail.rs:5:11 - | -LL | unsafe fn simd_masked_load(mask: M, pointer: P, values: T) -> T; - | ^^^^^^^^^^^^^^^^ --------- + --> $SRC_DIR/core/src/intrinsics/simd.rs:LL:COL error: aborting due to 2 previous errors diff --git a/tests/ui/simd/masked-load-store.rs b/tests/ui/simd/masked-load-store.rs index 4b4195f51f18..69ea76581ee6 100644 --- a/tests/ui/simd/masked-load-store.rs +++ b/tests/ui/simd/masked-load-store.rs @@ -1,11 +1,7 @@ //@ run-pass -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] -#[rustc_intrinsic] -unsafe fn simd_masked_load(mask: M, pointer: P, values: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_masked_store(mask: M, pointer: P, values: T) -> (); +use std::intrinsics::simd::{simd_masked_load, simd_masked_store}; #[derive(Copy, Clone)] #[repr(simd)] @@ -16,11 +12,8 @@ fn main() { let a = Simd::([0, 1, 2, 3]); let b_src = [4u8, 5, 6, 7]; let b_default = Simd::([9; 4]); - let b: Simd:: = simd_masked_load( - Simd::([-1, 0, -1, -1]), - b_src.as_ptr(), - b_default - ); + let b: Simd = + simd_masked_load(Simd::([-1, 0, -1, -1]), b_src.as_ptr(), b_default); assert_eq!(&b.0, &[4, 9, 6, 7]); diff --git a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr index 8d4bf1e0533a..b0742bc5ef80 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr +++ b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr @@ -1,5 +1,5 @@ error: overly complex generic constant - --> $DIR/monomorphize-shuffle-index.rs:32:51 + --> $DIR/monomorphize-shuffle-index.rs:36:51 | LL | return simd_shuffle_const_generic::<_, _, { &Self::I.0 }>(a, b); | ^^----------^^ diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs index 026193e6af6a..3a074dfd432c 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.rs +++ b/tests/ui/simd/monomorphize-shuffle-index.rs @@ -1,19 +1,23 @@ +//@ revisions: old generic generic_with_fn //@[old]run-pass //@[generic_with_fn]run-pass -//@ revisions: old generic generic_with_fn -#![feature(repr_simd, intrinsics, adt_const_params, unsized_const_params, generic_const_exprs)] +#![feature( + repr_simd, + core_intrinsics, + intrinsics, + adt_const_params, + unsized_const_params, + generic_const_exprs +)] #![allow(incomplete_features)] - -#[rustc_intrinsic] #[cfg(old)] -unsafe fn simd_shuffle(a: T, b: T, i: I) -> U; +use std::intrinsics::simd::simd_shuffle; -#[rustc_intrinsic] #[cfg(any(generic, generic_with_fn))] +#[rustc_intrinsic] unsafe fn simd_shuffle_const_generic(a: T, b: T) -> U; - #[derive(Copy, Clone)] #[repr(simd)] struct Simd([T; N]); diff --git a/tests/ui/simd/repr_packed.rs b/tests/ui/simd/repr_packed.rs index a666892226ea..cc54477ae713 100644 --- a/tests/ui/simd/repr_packed.rs +++ b/tests/ui/simd/repr_packed.rs @@ -1,8 +1,10 @@ //@ run-pass -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +use std::intrinsics::simd::simd_add; + #[repr(simd, packed)] struct Simd([T; N]); @@ -22,9 +24,6 @@ fn check_ty() { check_size_align::(); } -#[rustc_intrinsic] -unsafe fn simd_add(a: T, b: T) -> T; - fn main() { check_ty::(); check_ty::(); diff --git a/tests/ui/simd/shuffle.rs b/tests/ui/simd/shuffle.rs index 2cae5a1e7de2..cd270edcf00c 100644 --- a/tests/ui/simd/shuffle.rs +++ b/tests/ui/simd/shuffle.rs @@ -2,14 +2,13 @@ //@ revisions: opt noopt //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] #![allow(incomplete_features)] #![feature(adt_const_params)] use std::marker::ConstParamTy; -#[rustc_intrinsic] -unsafe fn simd_shuffle(a: T, b: T, i: I) -> U; +use std::intrinsics::simd::simd_shuffle; #[derive(Copy, Clone, ConstParamTy, PartialEq, Eq)] #[repr(simd)] diff --git a/tests/ui/simd/simd-bitmask-notpow2.rs b/tests/ui/simd/simd-bitmask-notpow2.rs index d7572ef4a2a4..4935097065ea 100644 --- a/tests/ui/simd/simd-bitmask-notpow2.rs +++ b/tests/ui/simd/simd-bitmask-notpow2.rs @@ -2,14 +2,9 @@ // FIXME: broken codegen on big-endian (https://github.com/rust-lang/rust/issues/127205) // This should be merged into `simd-bitmask` once that's fixed. //@ ignore-endian-big -#![feature(repr_simd, intrinsics)] - -#[rustc_intrinsic] -unsafe fn simd_bitmask(v: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_select_bitmask(m: T, a: U, b: U) -> U; +#![feature(repr_simd, core_intrinsics)] +use std::intrinsics::simd::{simd_bitmask, simd_select_bitmask}; fn main() { // Non-power-of-2 multi-byte mask. diff --git a/tests/ui/simd/simd-bitmask.rs b/tests/ui/simd/simd-bitmask.rs index 4275ab0f40c9..6fcceeaa24bb 100644 --- a/tests/ui/simd/simd-bitmask.rs +++ b/tests/ui/simd/simd-bitmask.rs @@ -1,12 +1,7 @@ //@run-pass -#![feature(repr_simd, intrinsics)] - -#[rustc_intrinsic] -unsafe fn simd_bitmask(v: T) -> U; - -#[rustc_intrinsic] -unsafe fn simd_select_bitmask(m: T, a: U, b: U) -> U; +#![feature(repr_simd, core_intrinsics)] +use std::intrinsics::simd::{simd_bitmask, simd_select_bitmask}; #[derive(Copy, Clone)] #[repr(simd)] From a837e9966b96741f52efd991eb15f70ad6bdda32 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 24 Feb 2025 18:46:56 +0100 Subject: [PATCH 380/991] simplify some imports with `simd::*` --- tests/ui/simd/intrinsic/generic-reduction-pass.rs | 6 +----- tests/ui/simd/intrinsic/generic-reduction.rs | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/tests/ui/simd/intrinsic/generic-reduction-pass.rs b/tests/ui/simd/intrinsic/generic-reduction-pass.rs index 9d76df49a8a9..2d5d75447b66 100644 --- a/tests/ui/simd/intrinsic/generic-reduction-pass.rs +++ b/tests/ui/simd/intrinsic/generic-reduction-pass.rs @@ -5,11 +5,7 @@ // Test that the simd_reduce_{op} intrinsics produce the correct results. #![feature(repr_simd, core_intrinsics)] -use std::intrinsics::simd::{ - simd_reduce_add_ordered, simd_reduce_add_unordered, simd_reduce_all, simd_reduce_and, - simd_reduce_any, simd_reduce_max, simd_reduce_min, simd_reduce_mul_ordered, - simd_reduce_mul_unordered, simd_reduce_or, simd_reduce_xor, -}; +use std::intrinsics::simd::*; #[repr(simd)] #[derive(Copy, Clone)] diff --git a/tests/ui/simd/intrinsic/generic-reduction.rs b/tests/ui/simd/intrinsic/generic-reduction.rs index 1ba187339d0a..49a33ac35e74 100644 --- a/tests/ui/simd/intrinsic/generic-reduction.rs +++ b/tests/ui/simd/intrinsic/generic-reduction.rs @@ -7,10 +7,7 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::{ - simd_reduce_add_ordered, simd_reduce_all, simd_reduce_and, simd_reduce_any, - simd_reduce_mul_ordered, simd_reduce_or, simd_reduce_xor, -}; +use std::intrinsics::simd::*; #[repr(simd)] #[derive(Copy, Clone)] From 4e961dc01538096d649fbdbb8cd8b6979df5bb35 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 24 Feb 2025 18:53:49 +0100 Subject: [PATCH 381/991] make `simd_insert` and `simd_extract` `const fn`s --- library/core/src/intrinsics/simd.rs | 4 ++-- .../consts/const-eval/simd/insert_extract.rs | 17 +--------------- .../simd/intrinsic/generic-reduction.stderr | 20 +++++++++---------- 3 files changed, 13 insertions(+), 28 deletions(-) diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 3bde183fefb7..3881cf90ad72 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -11,7 +11,7 @@ /// `idx` must be in-bounds of the vector. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_insert(_x: T, _idx: u32, _val: U) -> T; +pub const unsafe fn simd_insert(_x: T, _idx: u32, _val: U) -> T; /// Extracts an element from a vector. /// @@ -22,7 +22,7 @@ pub unsafe fn simd_insert(_x: T, _idx: u32, _val: U) -> T; /// `idx` must be in-bounds of the vector. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_extract(_x: T, _idx: u32) -> U; +pub const unsafe fn simd_extract(_x: T, _idx: u32) -> U; /// Adds two simd vectors elementwise. /// diff --git a/tests/ui/consts/const-eval/simd/insert_extract.rs b/tests/ui/consts/const-eval/simd/insert_extract.rs index 526f2b180427..fc97f9ec1418 100644 --- a/tests/ui/consts/const-eval/simd/insert_extract.rs +++ b/tests/ui/consts/const-eval/simd/insert_extract.rs @@ -5,22 +5,7 @@ #![stable(feature = "foo", since = "1.3.37")] #![allow(non_camel_case_types)] -// FIXME these intrinsics are not marked as const fn -// use std::intrinsics::simd::{simd_extract, simd_insert}; - -#[stable(feature = "foo", since = "1.3.37")] -#[rustc_const_stable(feature = "foo", since = "1.3.37")] -#[rustc_intrinsic] -const unsafe fn simd_insert(_x: T, _idx: u32, _val: U) -> T { - unimplemented!() -} - -#[stable(feature = "foo", since = "1.3.37")] -#[rustc_const_stable(feature = "foo", since = "1.3.37")] -#[rustc_intrinsic] -const unsafe fn simd_extract(_x: T, _idx: u32) -> U { - unimplemented!() -} +use std::intrinsics::simd::{simd_extract, simd_insert}; // repr(simd) now only supports array types #[repr(simd)] diff --git a/tests/ui/simd/intrinsic/generic-reduction.stderr b/tests/ui/simd/intrinsic/generic-reduction.stderr index 31294a77e467..eaa7b8d48eb3 100644 --- a/tests/ui/simd/intrinsic/generic-reduction.stderr +++ b/tests/ui/simd/intrinsic/generic-reduction.stderr @@ -1,59 +1,59 @@ error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32` - --> $DIR/generic-reduction.rs:28:9 + --> $DIR/generic-reduction.rs:25:9 | LL | simd_reduce_add_ordered(z, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32` - --> $DIR/generic-reduction.rs:30:9 + --> $DIR/generic-reduction.rs:27:9 | LL | simd_reduce_mul_ordered(z, 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/generic-reduction.rs:33:22 + --> $DIR/generic-reduction.rs:30:22 | LL | let _: f32 = simd_reduce_and(x); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/generic-reduction.rs:35:22 + --> $DIR/generic-reduction.rs:32:22 | LL | let _: f32 = simd_reduce_or(x); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/generic-reduction.rs:37:22 + --> $DIR/generic-reduction.rs:34:22 | LL | let _: f32 = simd_reduce_xor(x); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32` - --> $DIR/generic-reduction.rs:40:22 + --> $DIR/generic-reduction.rs:37:22 | LL | let _: f32 = simd_reduce_and(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32` - --> $DIR/generic-reduction.rs:42:22 + --> $DIR/generic-reduction.rs:39:22 | LL | let _: f32 = simd_reduce_or(z); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32` - --> $DIR/generic-reduction.rs:44:22 + --> $DIR/generic-reduction.rs:41:22 | LL | let _: f32 = simd_reduce_xor(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool` - --> $DIR/generic-reduction.rs:47:23 + --> $DIR/generic-reduction.rs:44:23 | LL | let _: bool = simd_reduce_all(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool` - --> $DIR/generic-reduction.rs:49:23 + --> $DIR/generic-reduction.rs:46:23 | LL | let _: bool = simd_reduce_any(z); | ^^^^^^^^^^^^^^^^^^ From 038f4e2ff67b66ec2b8fcf84025d79ff9a29ba1a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 24 Feb 2025 18:55:26 +0100 Subject: [PATCH 382/991] use the right feature in codegen tests --- tests/codegen/issues/issue-84268.rs | 2 +- tests/codegen/simd/simd_arith_offset.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/codegen/issues/issue-84268.rs b/tests/codegen/issues/issue-84268.rs index 2eebf4479375..1dc55a909ad6 100644 --- a/tests/codegen/issues/issue-84268.rs +++ b/tests/codegen/issues/issue-84268.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Copt-level=3 --crate-type=rlib -#![feature(intrinsics, repr_simd)] +#![feature(core_intrinsics, repr_simd)] use std::intrinsics::simd::{simd_eq, simd_fabs}; diff --git a/tests/codegen/simd/simd_arith_offset.rs b/tests/codegen/simd/simd_arith_offset.rs index 475ac37804fb..b8af6fce3326 100644 --- a/tests/codegen/simd/simd_arith_offset.rs +++ b/tests/codegen/simd/simd_arith_offset.rs @@ -3,7 +3,7 @@ // #![crate_type = "lib"] -#![feature(repr_simd, intrinsics)] +#![feature(repr_simd, core_intrinsics)] use std::intrinsics::simd::simd_arith_offset; From cabb08ded5a8ac6d06f8f0803939d31e274da799 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 27 Feb 2025 11:55:22 +0100 Subject: [PATCH 383/991] Fix sysroot crate-graph construction not mapping crate-ids for proc-macros --- .../rust-analyzer/crates/project-model/src/workspace.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 6b6fb5f9ec1f..2c9f41e828ec 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -1094,8 +1094,7 @@ fn cargo_to_crate_graph( ) -> (CrateGraph, ProcMacroPaths) { let _p = tracing::info_span!("cargo_to_crate_graph").entered(); let mut res = (CrateGraph::default(), ProcMacroPaths::default()); - let crate_graph = &mut res.0; - let proc_macros = &mut res.1; + let (crate_graph, proc_macros) = &mut res; let (public_deps, libproc_macro) = sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); @@ -1560,6 +1559,10 @@ fn extend_crate_graph_with_sysroot( // Remove all crates except the ones we are interested in to keep the sysroot graph small. let removed_mapping = sysroot_crate_graph.remove_crates_except(&marker_set); + sysroot_proc_macros = sysroot_proc_macros + .into_iter() + .filter_map(|(k, v)| Some((removed_mapping[k.into_raw().into_u32() as usize]?, v))) + .collect(); let mapping = crate_graph.extend(sysroot_crate_graph, &mut sysroot_proc_macros); // Map the id through the removal mapping first, then through the crate graph extension mapping. From 660241d1d47ac939e88163bab747c853be82eac0 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Mon, 24 Feb 2025 13:28:55 +0000 Subject: [PATCH 384/991] Fix test directives that were accidentally ignored --- tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs | 8 ++++---- .../run-make/rustdoc-scrape-examples-multiple/src/lib.rs | 7 +++---- .../run-make/rustdoc-scrape-examples-ordering/src/lib.rs | 8 ++++---- tests/run-make/rustdoc-scrape-examples-remap/src/lib.rs | 4 ++-- tests/run-make/rustdoc-scrape-examples-test/src/lib.rs | 2 +- .../rustdoc-scrape-examples-whitespace/src/lib.rs | 2 +- tests/run-make/rustdoc-themes/foo.rs | 6 +++--- tests/run-make/rustdoc-with-out-dir-option/src/lib.rs | 2 +- tests/run-make/rustdoc-with-output-option/src/lib.rs | 2 +- .../run-make/rustdoc-with-short-out-dir-option/src/lib.rs | 2 +- tests/rustdoc-ui/unused-extern-crate.rs | 1 - tests/ui/inline-const/collect-scopes-in-pat.rs | 2 +- 12 files changed, 22 insertions(+), 24 deletions(-) diff --git a/tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs index 26ab1390a49a..3ec2cf66fa30 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs +++ b/tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs @@ -1,8 +1,8 @@ // Scraped example should only include line numbers for items b and c in ex.rs -// @!has foobar/fn.f.html '//*[@class="src-line-numbers"]' '14' -// @has foobar/fn.f.html '//*[@class="src-line-numbers"]' '15' -// @has foobar/fn.f.html '//*[@class="src-line-numbers"]' '21' -// @!has foobar/fn.f.html '//*[@class="src-line-numbers"]' '22' +//@ !has foobar/fn.f.html '//span[@data-nosnippet]' '14' +//@ has foobar/fn.f.html '//span[@data-nosnippet]' '15' +//@ has foobar/fn.f.html '//span[@data-nosnippet]' '21' +//@ !has foobar/fn.f.html '//span[@data-nosnippet]' '22' pub fn f() {} diff --git a/tests/run-make/rustdoc-scrape-examples-multiple/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-multiple/src/lib.rs index bdfeda92d79a..25600915f5f9 100644 --- a/tests/run-make/rustdoc-scrape-examples-multiple/src/lib.rs +++ b/tests/run-make/rustdoc-scrape-examples-multiple/src/lib.rs @@ -1,6 +1,5 @@ -// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]//*[@class="prev"]' '' -// @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' '' -// @has src/ex/ex.rs.html -// @has foobar/fn.ok.html '//a[@href="../src/ex/ex.rs.html#2"]' '' +//@ has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' '' +//@ has src/ex/ex.rs.html +//@ has foobar/fn.ok.html '//a[@href="../src/ex/ex.rs.html#2"]' '' pub fn ok() {} diff --git a/tests/run-make/rustdoc-scrape-examples-ordering/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-ordering/src/lib.rs index c53c987a7cbf..c957263c048f 100644 --- a/tests/run-make/rustdoc-scrape-examples-ordering/src/lib.rs +++ b/tests/run-make/rustdoc-scrape-examples-ordering/src/lib.rs @@ -1,6 +1,6 @@ -// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' 'ex2' -// @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' 'ex1' -// @has foobar/fn.ok.html '//*[@class="highlight focus"]' 'ok' -// @has foobar/fn.ok.html '//*[@class="highlight"]' 'ok' +//@ has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' 'ex2' +//@ has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' 'ex1' +//@ has foobar/fn.ok.html '//*[@class="highlight focus"]' 'ok' +//@ has foobar/fn.ok.html '//*[@class="highlight"]' 'ok' pub fn ok(_x: i32) {} diff --git a/tests/run-make/rustdoc-scrape-examples-remap/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-remap/src/lib.rs index f525a4270dde..e1dc4f915068 100644 --- a/tests/run-make/rustdoc-scrape-examples-remap/src/lib.rs +++ b/tests/run-make/rustdoc-scrape-examples-remap/src/lib.rs @@ -1,5 +1,5 @@ -// @has foobar/b/fn.foo.html '//*[@class="scraped-example expanded"]' 'ex.rs' -// @has foobar/c/fn.foo.html '//*[@class="scraped-example expanded"]' 'ex.rs' +//@ has foobar/b/fn.foo.html '//*[@class="scraped-example expanded"]' 'ex.rs' +//@ has foobar/c/fn.foo.html '//*[@class="scraped-example expanded"]' 'ex.rs' #[path = "a.rs"] pub mod b; diff --git a/tests/run-make/rustdoc-scrape-examples-test/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-test/src/lib.rs index 22be1ad41010..93d56b7e972f 100644 --- a/tests/run-make/rustdoc-scrape-examples-test/src/lib.rs +++ b/tests/run-make/rustdoc-scrape-examples-test/src/lib.rs @@ -1,3 +1,3 @@ -// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' '' +//@ has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' '' pub fn ok() {} diff --git a/tests/run-make/rustdoc-scrape-examples-whitespace/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-whitespace/src/lib.rs index 28c34716c2f3..8fc3a5e41d2e 100644 --- a/tests/run-make/rustdoc-scrape-examples-whitespace/src/lib.rs +++ b/tests/run-make/rustdoc-scrape-examples-whitespace/src/lib.rs @@ -1,3 +1,3 @@ -// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]//code' ' ' +//@ has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]//code' ' ' pub fn ok() {} diff --git a/tests/run-make/rustdoc-themes/foo.rs b/tests/run-make/rustdoc-themes/foo.rs index 8b1e75b0ae13..555429b07df2 100644 --- a/tests/run-make/rustdoc-themes/foo.rs +++ b/tests/run-make/rustdoc-themes/foo.rs @@ -1,4 +1,4 @@ -// @has test.css -// @has foo/struct.Foo.html -// @has - '//*[@name="rustdoc-vars"]/@data-themes' 'test' +//@ has test.css +//@ has foo/struct.Foo.html +//@ has - '//*[@name="rustdoc-vars"]/@data-themes' 'test' pub struct Foo; diff --git a/tests/run-make/rustdoc-with-out-dir-option/src/lib.rs b/tests/run-make/rustdoc-with-out-dir-option/src/lib.rs index 044bb6acb19b..98753560d3a4 100644 --- a/tests/run-make/rustdoc-with-out-dir-option/src/lib.rs +++ b/tests/run-make/rustdoc-with-out-dir-option/src/lib.rs @@ -1,2 +1,2 @@ -// @has foobar/fn.ok.html +//@ has foobar/fn.ok.html pub fn ok() {} diff --git a/tests/run-make/rustdoc-with-output-option/src/lib.rs b/tests/run-make/rustdoc-with-output-option/src/lib.rs index 044bb6acb19b..98753560d3a4 100644 --- a/tests/run-make/rustdoc-with-output-option/src/lib.rs +++ b/tests/run-make/rustdoc-with-output-option/src/lib.rs @@ -1,2 +1,2 @@ -// @has foobar/fn.ok.html +//@ has foobar/fn.ok.html pub fn ok() {} diff --git a/tests/run-make/rustdoc-with-short-out-dir-option/src/lib.rs b/tests/run-make/rustdoc-with-short-out-dir-option/src/lib.rs index 044bb6acb19b..98753560d3a4 100644 --- a/tests/run-make/rustdoc-with-short-out-dir-option/src/lib.rs +++ b/tests/run-make/rustdoc-with-short-out-dir-option/src/lib.rs @@ -1,2 +1,2 @@ -// @has foobar/fn.ok.html +//@ has foobar/fn.ok.html pub fn ok() {} diff --git a/tests/rustdoc-ui/unused-extern-crate.rs b/tests/rustdoc-ui/unused-extern-crate.rs index 240dd1f00e22..62fd51aba9a5 100644 --- a/tests/rustdoc-ui/unused-extern-crate.rs +++ b/tests/rustdoc-ui/unused-extern-crate.rs @@ -1,3 +1,2 @@ //@ check-pass //@ aux-crate:panic_item=panic-item.rs -// @has unused_extern_crate/index.html diff --git a/tests/ui/inline-const/collect-scopes-in-pat.rs b/tests/ui/inline-const/collect-scopes-in-pat.rs index 024fde537413..16baf920f584 100644 --- a/tests/ui/inline-const/collect-scopes-in-pat.rs +++ b/tests/ui/inline-const/collect-scopes-in-pat.rs @@ -1,4 +1,4 @@ -// @compile-flags: -Zlint-mir +//@ compile-flags: -Zlint-mir //@ check-pass #![feature(inline_const_pat)] From 0881dba5d38331ecb0a4b4e259d77cf57b95636f Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Thu, 27 Feb 2025 13:20:52 +0000 Subject: [PATCH 385/991] Move "unused_exter_crate" test from rustdoc-ui to rustdoc --- tests/{rustdoc-ui => rustdoc}/auxiliary/panic-item.rs | 0 tests/{rustdoc-ui => rustdoc}/unused-extern-crate.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{rustdoc-ui => rustdoc}/auxiliary/panic-item.rs (100%) rename tests/{rustdoc-ui => rustdoc}/unused-extern-crate.rs (50%) diff --git a/tests/rustdoc-ui/auxiliary/panic-item.rs b/tests/rustdoc/auxiliary/panic-item.rs similarity index 100% rename from tests/rustdoc-ui/auxiliary/panic-item.rs rename to tests/rustdoc/auxiliary/panic-item.rs diff --git a/tests/rustdoc-ui/unused-extern-crate.rs b/tests/rustdoc/unused-extern-crate.rs similarity index 50% rename from tests/rustdoc-ui/unused-extern-crate.rs rename to tests/rustdoc/unused-extern-crate.rs index 62fd51aba9a5..cdc00fd313af 100644 --- a/tests/rustdoc-ui/unused-extern-crate.rs +++ b/tests/rustdoc/unused-extern-crate.rs @@ -1,2 +1,2 @@ -//@ check-pass //@ aux-crate:panic_item=panic-item.rs +//@ has unused_extern_crate/index.html From 329acde93e357e9797dc14aec9503b1f9234dfc9 Mon Sep 17 00:00:00 2001 From: yanglsh Date: Thu, 27 Feb 2025 16:20:29 +0800 Subject: [PATCH 386/991] fix: `map_entry` FP inside closure --- clippy_lints/src/entry.rs | 5 +++-- tests/ui/entry.fixed | 8 ++++++++ tests/ui/entry.rs | 8 ++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index f8a5cf53cda0..f404bc59b3b8 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -8,7 +8,7 @@ use clippy_utils::{ use core::fmt::{self, Write}; use rustc_errors::Applicability; use rustc_hir::hir_id::HirIdSet; -use rustc_hir::intravisit::{Visitor, walk_expr}; +use rustc_hir::intravisit::{Visitor, walk_body, walk_expr}; use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -331,7 +331,7 @@ impl<'tcx> Edit<'tcx> { if let Self::Insertion(i) = self { Some(i) } else { None } } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] struct Insertion<'tcx> { call: &'tcx Expr<'tcx>, value: &'tcx Expr<'tcx>, @@ -544,6 +544,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> { ExprKind::InlineAsm(_) => { self.can_use_entry = false; }, + ExprKind::Closure(closure) => walk_body(self, self.cx.tcx.hir_body(closure.body)), _ => { self.allow_insert_closure &= !self.in_tail_pos; self.allow_insert_closure &= diff --git a/tests/ui/entry.fixed b/tests/ui/entry.fixed index d52299306fd0..69452a8d9a67 100644 --- a/tests/ui/entry.fixed +++ b/tests/ui/entry.fixed @@ -218,4 +218,12 @@ mod issue13934 { } } +fn issue11976() { + let mut hashmap = std::collections::HashMap::new(); + if !hashmap.contains_key(&0) { + let _ = || hashmap.get(&0); + hashmap.insert(0, 0); + } +} + fn main() {} diff --git a/tests/ui/entry.rs b/tests/ui/entry.rs index 25cd6eaa4132..3578324f01c5 100644 --- a/tests/ui/entry.rs +++ b/tests/ui/entry.rs @@ -224,4 +224,12 @@ mod issue13934 { } } +fn issue11976() { + let mut hashmap = std::collections::HashMap::new(); + if !hashmap.contains_key(&0) { + let _ = || hashmap.get(&0); + hashmap.insert(0, 0); + } +} + fn main() {} From 8c16ded966f92e7dbcc06cf43bd2a9eae815159f Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Thu, 27 Feb 2025 00:59:02 +0100 Subject: [PATCH 387/991] enable doctest --- src/tools/rust-analyzer/crates/base-db/Cargo.toml | 1 - src/tools/rust-analyzer/crates/cfg/Cargo.toml | 1 - src/tools/rust-analyzer/crates/hir-expand/Cargo.toml | 1 - src/tools/rust-analyzer/crates/hir-ty/Cargo.toml | 1 - src/tools/rust-analyzer/crates/hir/Cargo.toml | 1 - src/tools/rust-analyzer/crates/ide-assists/Cargo.toml | 1 - src/tools/rust-analyzer/crates/ide-completion/Cargo.toml | 1 - src/tools/rust-analyzer/crates/ide-db/Cargo.toml | 1 - src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml | 1 - src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml | 1 - src/tools/rust-analyzer/crates/ide/Cargo.toml | 1 - src/tools/rust-analyzer/crates/intern/Cargo.toml | 1 - src/tools/rust-analyzer/crates/mbe/Cargo.toml | 1 - src/tools/rust-analyzer/crates/parser/Cargo.toml | 1 - src/tools/rust-analyzer/crates/paths/Cargo.toml | 1 - src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml | 1 - src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml | 1 - .../crates/proc-macro-srv/proc-macro-test/Cargo.toml | 1 - .../crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml | 1 - src/tools/rust-analyzer/crates/profile/Cargo.toml | 1 - src/tools/rust-analyzer/crates/project-model/Cargo.toml | 1 - src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml | 1 - src/tools/rust-analyzer/crates/stdx/Cargo.toml | 1 - src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml | 1 - src/tools/rust-analyzer/crates/syntax/Cargo.toml | 1 - src/tools/rust-analyzer/crates/test-utils/Cargo.toml | 1 - src/tools/rust-analyzer/crates/toolchain/Cargo.toml | 1 - src/tools/rust-analyzer/crates/tt/Cargo.toml | 1 - src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml | 1 - src/tools/rust-analyzer/crates/vfs/Cargo.toml | 1 - 30 files changed, 30 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml index 788ceb8857e9..042dd36488aa 100644 --- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] lz4_flex = { version = "0.11", default-features = false } diff --git a/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml index 040bddbd7fd3..e887368ef28f 100644 --- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml +++ b/src/tools/rust-analyzer/crates/cfg/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] rustc-hash.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml index b193a34a01d9..7d561e0527d9 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml index 4d36de0b383c..27849f3b449d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/hir/Cargo.toml b/src/tools/rust-analyzer/crates/hir/Cargo.toml index c68ff706e481..2af3c2e4c351 100644 --- a/src/tools/rust-analyzer/crates/hir/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] rustc-hash.workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml b/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml index ba215868710e..3768c2257cad 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml index 1bef82af5ac9..68cc7a0b9a6d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml index c8a8a2d16981..641998c3daca 100644 --- a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml index 281a08e5429f..483cb6df8623 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml index 256146762888..fa75e5a42147 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/ide/Cargo.toml b/src/tools/rust-analyzer/crates/ide/Cargo.toml index 7c66b36dc8e9..9af56c40e982 100644 --- a/src/tools/rust-analyzer/crates/ide/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/intern/Cargo.toml b/src/tools/rust-analyzer/crates/intern/Cargo.toml index c0358ef929b4..397eba092967 100644 --- a/src/tools/rust-analyzer/crates/intern/Cargo.toml +++ b/src/tools/rust-analyzer/crates/intern/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] diff --git a/src/tools/rust-analyzer/crates/mbe/Cargo.toml b/src/tools/rust-analyzer/crates/mbe/Cargo.toml index b37d57f28012..e6fbb298ebdb 100644 --- a/src/tools/rust-analyzer/crates/mbe/Cargo.toml +++ b/src/tools/rust-analyzer/crates/mbe/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/parser/Cargo.toml b/src/tools/rust-analyzer/crates/parser/Cargo.toml index 48436ec71f7a..a36a39dbee6c 100644 --- a/src/tools/rust-analyzer/crates/parser/Cargo.toml +++ b/src/tools/rust-analyzer/crates/parser/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] drop_bomb = "0.1.5" diff --git a/src/tools/rust-analyzer/crates/paths/Cargo.toml b/src/tools/rust-analyzer/crates/paths/Cargo.toml index f0dafab70c16..4cc70726da0b 100644 --- a/src/tools/rust-analyzer/crates/paths/Cargo.toml +++ b/src/tools/rust-analyzer/crates/paths/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] camino.workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml index dac8e0943576..f5ba40a994b1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] serde.workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml index 191535ac55e9..d3b56b402ea8 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] object.workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml index 7c6a1ba46b5f..16fcc9296207 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" license = "MIT OR Apache-2.0" [lib] -doctest = false [build-dependencies] cargo_metadata = "0.18.1" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml index fa189752b76f..fb98d758a8b7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" publish = false [lib] -doctest = false proc-macro = true [dependencies] diff --git a/src/tools/rust-analyzer/crates/profile/Cargo.toml b/src/tools/rust-analyzer/crates/profile/Cargo.toml index 65eec868af3d..9384fe265584 100644 --- a/src/tools/rust-analyzer/crates/profile/Cargo.toml +++ b/src/tools/rust-analyzer/crates/profile/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cfg-if = "1.0.0" diff --git a/src/tools/rust-analyzer/crates/project-model/Cargo.toml b/src/tools/rust-analyzer/crates/project-model/Cargo.toml index ed647950e663..83def0e6b2a9 100644 --- a/src/tools/rust-analyzer/crates/project-model/Cargo.toml +++ b/src/tools/rust-analyzer/crates/project-model/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] anyhow.workspace = true diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index 64c8afdc1f74..6c81c238fd3f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -13,7 +13,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [[bin]] name = "rust-analyzer" diff --git a/src/tools/rust-analyzer/crates/stdx/Cargo.toml b/src/tools/rust-analyzer/crates/stdx/Cargo.toml index 62c32d68e6fb..3727d0c9562e 100644 --- a/src/tools/rust-analyzer/crates/stdx/Cargo.toml +++ b/src/tools/rust-analyzer/crates/stdx/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] backtrace = { version = "0.3.67", optional = true } diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml b/src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml index f9a9f40541d5..3e663422a04e 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml +++ b/src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] rustc-hash.workspace = true diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml index 51eaea54346d..3fe6e01dc3c9 100644 --- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml +++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/src/tools/rust-analyzer/crates/test-utils/Cargo.toml b/src/tools/rust-analyzer/crates/test-utils/Cargo.toml index b1457722a922..b99a2c4bd75c 100644 --- a/src/tools/rust-analyzer/crates/test-utils/Cargo.toml +++ b/src/tools/rust-analyzer/crates/test-utils/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] # Avoid adding deps here, this crate is widely used in tests it should compile fast! diff --git a/src/tools/rust-analyzer/crates/toolchain/Cargo.toml b/src/tools/rust-analyzer/crates/toolchain/Cargo.toml index 87e8efb20fc6..38daacdf951a 100644 --- a/src/tools/rust-analyzer/crates/toolchain/Cargo.toml +++ b/src/tools/rust-analyzer/crates/toolchain/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] home = "0.5.4" diff --git a/src/tools/rust-analyzer/crates/tt/Cargo.toml b/src/tools/rust-analyzer/crates/tt/Cargo.toml index 82e7c24668fe..529fad3244a6 100644 --- a/src/tools/rust-analyzer/crates/tt/Cargo.toml +++ b/src/tools/rust-analyzer/crates/tt/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] arrayvec.workspace = true diff --git a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml index bc54d7168f09..48b4d22de2f0 100644 --- a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml +++ b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] tracing.workspace = true diff --git a/src/tools/rust-analyzer/crates/vfs/Cargo.toml b/src/tools/rust-analyzer/crates/vfs/Cargo.toml index e8a6195036ed..546195481c6a 100644 --- a/src/tools/rust-analyzer/crates/vfs/Cargo.toml +++ b/src/tools/rust-analyzer/crates/vfs/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] rustc-hash.workspace = true From df903a55dd46c49204a2157786c67af93f4f3573 Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Thu, 27 Feb 2025 00:59:13 +0100 Subject: [PATCH 388/991] fix doc tests --- src/tools/rust-analyzer/crates/hir-def/Cargo.toml | 1 - .../rust-analyzer/crates/hir-def/src/dyn_map.rs | 4 +++- .../rust-analyzer/crates/hir-def/src/item_tree.rs | 6 +++--- .../crates/hir-def/src/nameres/mod_resolution.rs | 2 +- .../rust-analyzer/crates/hir-def/src/resolver.rs | 5 +++-- .../crates/hir-expand/src/builtin/attr_macro.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/display.rs | 2 +- src/tools/rust-analyzer/crates/hir-ty/src/infer.rs | 9 +++++---- .../crates/hir/src/semantics/source_to_def.rs | 2 +- .../crates/hir/src/term_search/expr.rs | 2 +- .../src/handlers/convert_comment_from_or_to_doc.rs | 6 +++--- .../ide-assists/src/handlers/extract_function.rs | 4 ++-- .../ide-assists/src/handlers/generate_function.rs | 2 +- .../ide-assists/src/handlers/inline_type_alias.rs | 2 +- .../crates/ide-completion/src/context.rs | 4 ++-- .../crates/ide-completion/src/context/analysis.rs | 5 +++-- .../crates/ide-completion/src/item.rs | 14 +++++++------- .../rust-analyzer/crates/ide-completion/src/lib.rs | 2 +- .../crates/ide-db/src/path_transform.rs | 2 +- .../crates/ide-db/src/source_change.rs | 2 +- .../ide-db/src/syntax_helpers/suggest_name.rs | 4 +++- .../crates/ide-diagnostics/src/lib.rs | 2 +- src/tools/rust-analyzer/crates/mbe/src/parser.rs | 4 ++-- src/tools/rust-analyzer/crates/parser/src/input.rs | 2 +- src/tools/rust-analyzer/crates/parser/src/lib.rs | 2 +- .../rust-analyzer/crates/parser/src/output.rs | 5 +++-- .../crates/rust-analyzer/src/op_queue.rs | 2 +- .../crates/rust-analyzer/src/tracing/config.rs | 4 ++-- .../crates/rust-analyzer/src/tracing/hprof.rs | 3 ++- .../crates/rust-analyzer/src/tracing/json.rs | 3 ++- src/tools/rust-analyzer/crates/stdx/src/anymap.rs | 3 ++- src/tools/rust-analyzer/crates/stdx/src/macros.rs | 2 +- src/tools/rust-analyzer/crates/syntax/src/algo.rs | 2 +- .../rust-analyzer/crates/syntax/src/ast/edit.rs | 4 ++-- .../crates/test-utils/src/assert_linear.rs | 2 +- .../rust-analyzer/crates/test-utils/src/fixture.rs | 12 ++++++++---- .../rust-analyzer/crates/vfs/src/anchored_path.rs | 2 +- 37 files changed, 75 insertions(+), 61 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml index 9a448ec14ea1..a22961c26c84 100644 --- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] arrayvec.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs index e9318d146ddf..8868bc0cd95b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs @@ -5,7 +5,9 @@ //! //! It is used like this: //! -//! ``` +//! ```ignore +//! # use hir_def::dyn_map::DynMap; +//! # use hir_def::dyn_map::Key; //! // keys define submaps of a `DynMap` //! const STRING_TO_U32: Key = Key::new(); //! const U32_TO_VEC: Key> = Key::new(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 8d5b3eeb28e1..382afbcb1dd4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -883,20 +883,20 @@ pub struct UseTree { #[derive(Debug, Clone, Eq, PartialEq)] pub enum UseTreeKind { - /// ``` + /// ```ignore /// use path::to::Item; /// use path::to::Item as Renamed; /// use path::to::Trait as _; /// ``` Single { path: Interned, alias: Option }, - /// ``` + /// ```ignore /// use *; // (invalid, but can occur in nested tree) /// use path::*; /// ``` Glob { path: Option> }, - /// ``` + /// ```ignore /// use prefix::{self, Item, ...}; /// ``` Prefixed { prefix: Option>, list: Box<[UseTree]> }, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs index afee42ecec0b..17d09bcbd047 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs @@ -134,7 +134,7 @@ impl DirPath { /// So this is the case which doesn't really work I think if we try to be /// 100% platform agnostic: /// - /// ``` + /// ```ignore /// mod a { /// #[path="C://sad/face"] /// mod b { mod c; } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 9dfb6e3cc4b7..e5774b48044f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -532,16 +532,17 @@ impl Resolver { /// Note that in Rust one name can be bound to several items: /// /// ``` + /// # #![allow(non_camel_case_types)] /// macro_rules! t { () => (()) } /// type t = t!(); - /// const t: t = t!() + /// const t: t = t!(); /// ``` /// /// That's why we return a multimap. /// /// The shadowing is accounted for: in /// - /// ``` + /// ```ignore /// let it = 92; /// { /// let it = 92; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs index f250620e775a..e9dc17a28f68 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs @@ -101,7 +101,7 @@ fn dummy_gate_test_expand( /// somewhat inconsistently resolve derive attributes. /// /// As such, we expand `#[derive(Foo, bar::Bar)]` into -/// ``` +/// ```ignore /// #![Foo] /// #![bar::Bar] /// ``` diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index ae8fbe2ce6d7..49f061813d10 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -95,7 +95,7 @@ pub struct HirFormatter<'a> { enum BoundsFormattingCtx { Entered { /// We can have recursive bounds like the following case: - /// ```rust + /// ```ignore /// where /// T: Foo, /// T::FooAssoc: Baz<::BarAssoc> + Bar diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 0cb7002f4460..556091c40461 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -335,7 +335,7 @@ impl Default for InternedStandardTypes { /// sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is /// represented by: /// -/// ``` +/// ```ignore /// Deref(None) -> [i32; 4], /// Borrow(AutoBorrow::Ref) -> &[i32; 4], /// Unsize -> &[i32], @@ -481,9 +481,10 @@ pub struct InferenceResult { /// or pattern can have multiple binding modes. For example: /// ``` /// fn foo(mut slice: &[u32]) -> usize { - /// slice = match slice { - /// [0, rest @ ..] | rest => rest, - /// }; + /// slice = match slice { + /// [0, rest @ ..] | rest => rest, + /// }; + /// 0 /// } /// ``` /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`. diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 4481b8855fd6..18cbaa15aeae 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -5,7 +5,7 @@ //! //! This module solves the following problem: //! -//! Given a piece of syntax, find the corresponding semantic definition (def). +//! > Given a piece of syntax, find the corresponding semantic definition (def). //! //! This problem is a part of more-or-less every IDE feature implemented. Every //! IDE functionality (like goto to definition), conceptually starts with a diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs index 6ad074e8e5c8..d2070f0e18b4 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs @@ -40,7 +40,7 @@ fn mod_item_path_str( /// Type tree shows how can we get from set of types to some type. /// /// Consider the following code as an example -/// ``` +/// ```ignore /// fn foo(x: i32, y: bool) -> Option { None } /// fn bar() { /// let a = 1; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs index c7b1314c861e..5a9db67a5fb6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs @@ -136,7 +136,7 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem /// Not all comments are valid candidates for conversion into doc comments. For example, the /// comments in the code: -/// ```rust +/// ```ignore /// // Brilliant module right here /// /// // Really good right @@ -148,7 +148,7 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem /// mod nice_module {} /// ``` /// can be converted to doc comments. However, the comments in this example: -/// ```rust +/// ```ignore /// fn foo_bar(foo: Foo /* not bar yet */) -> Bar { /// foo.into_bar() /// // Nicely done @@ -162,7 +162,7 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem /// are not allowed to become doc comments. Moreover, some comments _are_ allowed, but aren't common /// style in Rust. For example, the following comments are allowed to be doc comments, but it is not /// common style for them to be: -/// ```rust +/// ```ignore /// fn foo_bar(foo: Foo) -> Bar { /// // this could be an inner comment with //! /// foo.into_bar() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 967da41c15f7..751e4a5a5719 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -272,7 +272,7 @@ fn make_function_name(semantics_scope: &hir::SemanticsScope<'_>) -> ast::NameRef /// * We want whole node, like `loop {}`, `2 + 2`, `{ let n = 1; }` exprs. /// Then we can use `ast::Expr` /// * We want a few statements for a block. E.g. -/// ```rust,no_run +/// ```ignore /// fn foo() -> i32 { /// let m = 1; /// $0 @@ -386,7 +386,7 @@ struct ContainerInfo { /// Control flow that is exported from extracted function /// /// E.g.: -/// ```rust,no_run +/// ```ignore /// loop { /// $0 /// if 42 == 42 { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index 8f5daa4125a3..91e248a1de51 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -1037,7 +1037,7 @@ fn filter_bounds_in_scope( /// Makes duplicate argument names unique by appending incrementing numbers. /// -/// ``` +/// ```ignore /// let mut names: Vec = /// vec!["foo".into(), "foo".into(), "bar".into(), "baz".into(), "bar".into()]; /// deduplicate_arg_names(&mut names); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs index 66dffde505c1..76d465b01103 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -276,7 +276,7 @@ impl ConstAndTypeMap { /// 1. Map the provided instance's generic args to the type alias's generic /// params: /// -/// ``` +/// ```ignore /// type A<'a, const N: usize, T = u64> = &'a [T; N]; /// ^ alias generic params /// let a: A<100>; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index 7862b258789c..919b30f7f971 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -249,8 +249,8 @@ pub(crate) enum Qualified { /// This would be None, if path is not solely made of /// `super` segments, e.g. /// - /// ```rust - /// use super::foo; + /// ```ignore + /// use super::foo; /// ``` /// /// Otherwise it should be Some(count of `super`) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index eecd412bc43e..1a34548f7082 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -97,7 +97,8 @@ fn token_at_offset_ignore_whitespace(file: &SyntaxNode, offset: TextSize) -> Opt /// We do this by recursively expanding all macros and picking the best possible match. We cannot just /// choose the first expansion each time because macros can expand to something that does not include /// our completion marker, e.g.: -/// ``` +/// +/// ```ignore /// macro_rules! helper { ($v:ident) => {} } /// macro_rules! my_macro { /// ($v:ident) => { @@ -106,7 +107,7 @@ fn token_at_offset_ignore_whitespace(file: &SyntaxNode, offset: TextSize) -> Opt /// }; /// } /// -/// my_macro!(complete_me_here) +/// my_macro!(complete_me_here); /// ``` /// If we would expand the first thing we encounter only (which in fact this method used to do), we would /// be unable to complete here, because we would be walking directly into the void. So we instead try diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs index 41a82409597b..b3dd8a8d06eb 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs @@ -149,9 +149,9 @@ pub struct CompletionRelevance { /// This is set when the identifier being completed matches up with the name that is expected, /// like in a function argument. /// - /// ``` + /// ```ignore /// fn f(spam: String) {} - /// fn main { + /// fn main() { /// let spam = 92; /// f($0) // name of local matches the name of param /// } @@ -161,7 +161,7 @@ pub struct CompletionRelevance { pub type_match: Option, /// Set for local variables. /// - /// ``` + /// ```ignore /// fn foo(a: u32) { /// let b = 0; /// $0 // `a` and `b` are local @@ -195,7 +195,7 @@ pub struct CompletionRelevanceTraitInfo { pub enum CompletionRelevanceTypeMatch { /// This is set in cases like these: /// - /// ``` + /// ```ignore /// enum Option { Some(T), None } /// fn f(a: Option) {} /// fn main { @@ -205,9 +205,9 @@ pub enum CompletionRelevanceTypeMatch { CouldUnify, /// This is set in cases where the type matches the expected type, like: /// - /// ``` + /// ```ignore /// fn f(spam: String) {} - /// fn main { + /// fn main() { /// let foo = String::new(); /// f($0) // type of local matches the type of param /// } @@ -221,7 +221,7 @@ pub enum CompletionRelevancePostfixMatch { NonExact, /// This is set in cases like these: /// - /// ``` + /// ```ignore /// (a > b).not$0 /// ``` /// diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index a1f2eaeb1b6d..a990b39481a1 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -143,7 +143,7 @@ impl CompletionFieldsToResolve { /// already present, it should give all possible variants for the identifier at /// the caret. In other words, for /// -/// ```no_run +/// ```ignore /// fn f() { /// let foo = 92; /// let _ = bar$0 diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index f045e44dd318..126b30470b7e 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -32,7 +32,7 @@ type DefaultedParam = Either; /// block), you generally want to appropriately qualify the names, and sometimes /// you might want to substitute generic parameters as well: /// -/// ``` +/// ```ignore /// mod x { /// pub struct A; /// pub trait T { fn foo(&self, _: U) -> A; } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs index 27ff91dc19d9..34642d7eaf9d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs @@ -493,7 +493,7 @@ pub enum Snippet { Placeholder(TextRange), /// A group of placeholder snippets, e.g. /// - /// ```no_run + /// ```ignore /// let ${0:new_var} = 4; /// fun(1, 2, 3, ${0:new_var}); /// ``` diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs index 0a7141c19b6b..e085bf15cb92 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs @@ -79,7 +79,9 @@ const USELESS_METHODS: &[&str] = &[ /// the name, e.g. `a`, `a1`, `a2`, ... /// /// # Examples -/// ```rust +/// +/// ``` +/// # use ide_db::syntax_helpers::suggest_name::NameGenerator; /// let mut generator = NameGenerator::new(); /// assert_eq!(generator.suggest_name("a"), "a"); /// assert_eq!(generator.suggest_name("a"), "a1"); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index 3ea41aa7e859..0a55b6e9bee8 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -697,7 +697,7 @@ struct SeverityAttr { /// #[warn(non_snake_case)] /// mod foo { /// #[allow(nonstandard_style)] - /// mod bar; + /// mod bar {} /// } /// ``` /// We want to not warn on non snake case inside `bar`. If we are traversing this for the first diff --git a/src/tools/rust-analyzer/crates/mbe/src/parser.rs b/src/tools/rust-analyzer/crates/mbe/src/parser.rs index 16d55492a04b..0a670053c988 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/parser.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/parser.rs @@ -13,8 +13,8 @@ use crate::ParseError; /// Consider /// /// ``` -/// macro_rules! an_macro { -/// ($x:expr + $y:expr) => ($y * $x) +/// macro_rules! a_macro { +/// ($x:expr, $y:expr) => ($y * $x) /// } /// ``` /// diff --git a/src/tools/rust-analyzer/crates/parser/src/input.rs b/src/tools/rust-analyzer/crates/parser/src/input.rs index c90b358cfbb4..cabdff214df3 100644 --- a/src/tools/rust-analyzer/crates/parser/src/input.rs +++ b/src/tools/rust-analyzer/crates/parser/src/input.rs @@ -36,7 +36,7 @@ impl Input { /// the *previous* token was joint, with mbe, you know whether the *current* /// one is joint. This API allows for styles of usage: /// - /// ``` + /// ```ignore /// // In text: /// tokens.was_joint(prev_joint); /// tokens.push(curr); diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs index e461492cc6f9..398ad7cf66ce 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lib.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs @@ -59,7 +59,7 @@ pub use crate::{ /// /// That is, for something like /// -/// ``` +/// ```ignore /// quick_check! { /// fn prop() {} /// } diff --git a/src/tools/rust-analyzer/crates/parser/src/output.rs b/src/tools/rust-analyzer/crates/parser/src/output.rs index 386d03a62cc1..0ea15a656c1b 100644 --- a/src/tools/rust-analyzer/crates/parser/src/output.rs +++ b/src/tools/rust-analyzer/crates/parser/src/output.rs @@ -16,8 +16,9 @@ pub struct Output { /// 32-bit encoding of events. If LSB is zero, then that's an index into the /// error vector. Otherwise, it's one of the thee other variants, with data encoded as /// - /// |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover| - /// + /// ```text + /// |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover| + /// `````` event: Vec, error: Vec, } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs index 123f20605ab3..709d99bda751 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs @@ -6,7 +6,7 @@ pub(crate) type Cause = String; /// A single-item queue that allows callers to request an operation to /// be performed later. /// -/// ``` +/// ```ignore /// let queue = OpQueue::default(); /// /// // Request work to be done. diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs index 02ae4186ab69..4f208b6c5dd6 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs @@ -31,7 +31,7 @@ pub struct Config { /// that specify level. pub chalk_filter: Option, /// Filtering syntax, set in a shell: - /// ``` + /// ```text /// env RA_PROFILE=* // dump everything /// env RA_PROFILE=foo|bar|baz // enabled only selected entries /// env RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more than 10 @@ -39,7 +39,7 @@ pub struct Config { pub profile_filter: Option, /// Filtering syntax, set in a shell: - /// ``` + /// ```text /// env RA_PROFILE_JSON=foo|bar|baz /// ``` pub json_profile_filter: Option, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/hprof.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/hprof.rs index d466acef0115..5b18762bb974 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/hprof.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/hprof.rs @@ -6,7 +6,8 @@ //! //! Usage: //! -//! ```rust +//! ```ignore +//! # use tracing_subscriber::Registry; //! let layer = hprof::SpanTree::default(); //! Registry::default().with(layer).init(); //! ``` diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs index 9e35990a5bc8..f5394d023a10 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs @@ -2,7 +2,8 @@ //! //! Usage: //! -//! ```rust +//! ```ignore +//! # use tracing_subscriber::Registry; //! let layer = json::TimingLayer::new(std::io::stderr); //! Registry::default().with(layer).init(); //! ``` diff --git a/src/tools/rust-analyzer/crates/stdx/src/anymap.rs b/src/tools/rust-analyzer/crates/stdx/src/anymap.rs index 91fab8e92380..faf2e6c71789 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/anymap.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/anymap.rs @@ -83,7 +83,8 @@ pub type RawMap = hash_map::HashMap, BuildHasherDefault[anymap::Map][Map]::<[core::any::Any]>::new()
instead if desired.) /// -/// ```rust +/// ``` +/// # use stdx::anymap; #[doc = "let mut data = anymap::AnyMap::new();"] /// assert_eq!(data.get(), None::<&i32>); /// ``` diff --git a/src/tools/rust-analyzer/crates/stdx/src/macros.rs b/src/tools/rust-analyzer/crates/stdx/src/macros.rs index 85d9008fe123..880e2da70fc3 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/macros.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/macros.rs @@ -34,7 +34,7 @@ macro_rules! format_to_acc { /// /// # Example /// -/// ```rust +/// ```ignore /// impl_from!(Struct, Union, Enum for Adt); /// ``` #[macro_export] diff --git a/src/tools/rust-analyzer/crates/syntax/src/algo.rs b/src/tools/rust-analyzer/crates/syntax/src/algo.rs index 3b85b137aa9b..a8a83893946a 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/algo.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/algo.rs @@ -25,7 +25,7 @@ pub fn ancestors_at_offset( /// imprecise: if the cursor is strictly between two nodes of the desired type, /// as in /// -/// ```no_run +/// ```ignore /// struct Foo {}|struct Bar; /// ``` /// diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs index 579f3ba8b4fe..052d018e5c9e 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs @@ -72,9 +72,9 @@ impl IndentLevel { } /// XXX: this intentionally doesn't change the indent of the very first token. - /// Ie, in something like + /// For example, in something like: /// ``` - /// fn foo() { + /// fn foo() -> i32 { /// 92 /// } /// ``` diff --git a/src/tools/rust-analyzer/crates/test-utils/src/assert_linear.rs b/src/tools/rust-analyzer/crates/test-utils/src/assert_linear.rs index 15c30c52a548..f78bf59a2fdc 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/assert_linear.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/assert_linear.rs @@ -11,7 +11,7 @@ //! Ideally, we should use a proper "model selection" to directly compare //! quadratic and linear models, but that sounds rather complicated: //! -//! https://stats.stackexchange.com/questions/21844/selecting-best-model-based-on-linear-quadratic-and-cubic-fit-of-data +//! > https://stats.stackexchange.com/questions/21844/selecting-best-model-based-on-linear-quadratic-and-cubic-fit-of-data //! //! We might get false positives on a VM, but never false negatives. So, if the //! first round fails, we repeat the ordeal three more times and fail only if diff --git a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs index 7fe26d53bf21..daeb56c5835c 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs @@ -6,7 +6,8 @@ //! Use this to test functionality local to one file. //! //! Simple Example: -//! ``` +//! +//! ```ignore //! r#" //! fn main() { //! println!("Hello World") @@ -19,7 +20,8 @@ //! which is also how to define multiple files in a single test fixture //! //! Example using two files in the same crate: -//! ``` +//! +//! ```ignore //! " //! //- /main.rs //! mod foo; @@ -33,7 +35,8 @@ //! ``` //! //! Example using two crates with one file each, with one crate depending on the other: -//! ``` +//! +//! ```ignore //! r#" //! //- /main.rs crate:a deps:b //! fn main() { @@ -51,7 +54,8 @@ //! for the syntax. //! //! Example using some available metadata: -//! ``` +//! +//! ```ignore //! " //! //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo //! fn insert_source_code_here() {} diff --git a/src/tools/rust-analyzer/crates/vfs/src/anchored_path.rs b/src/tools/rust-analyzer/crates/vfs/src/anchored_path.rs index db15a2a21cd6..1b9fb355b481 100644 --- a/src/tools/rust-analyzer/crates/vfs/src/anchored_path.rs +++ b/src/tools/rust-analyzer/crates/vfs/src/anchored_path.rs @@ -2,7 +2,7 @@ //! //! The primary goal of this is to losslessly represent paths like //! -//! ``` +//! ```ignore //! #[path = "./bar.rs"] //! mod foo; //! ``` From c85f038307da4435361b2eaaccd187a50ece2c76 Mon Sep 17 00:00:00 2001 From: Vayun Biyani Date: Thu, 27 Feb 2025 19:32:30 +0530 Subject: [PATCH 389/991] switch #[cfg(not(llvm_enzyme))] to cfg!(llvm_enzyme) --- compiler/rustc_builtin_macros/src/autodiff.rs | 26 +++---------------- compiler/rustc_builtin_macros/src/errors.rs | 4 --- 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index cad041c7deba..6d9c35756574 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -3,7 +3,6 @@ //! configs (autodiff enabled or disabled), so we have to add cfg's to each import. //! FIXME(ZuseZ4): Remove this once we have a smarter linter. -#[cfg(llvm_enzyme)] mod llvm_enzyme { use std::str::FromStr; use std::string::String; @@ -130,6 +129,10 @@ mod llvm_enzyme { meta_item: &ast::MetaItem, mut item: Annotatable, ) -> Vec { + if cfg!(not(llvm_enzyme)) { + ecx.sess.dcx().emit_err(errors::AutoDiffSupportNotBuild { span: meta_item.span }); + return vec![item]; + } let dcx = ecx.sess.dcx(); // first get the annotable item: let (sig, is_impl): (FnSig, bool) = match &item { @@ -801,25 +804,4 @@ mod llvm_enzyme { } } -#[cfg(not(llvm_enzyme))] -mod ad_fallback { - use rustc_ast::ast; - use rustc_expand::base::{Annotatable, ExtCtxt}; - use rustc_span::Span; - - use crate::errors; - pub(crate) fn expand( - ecx: &mut ExtCtxt<'_>, - _expand_span: Span, - meta_item: &ast::MetaItem, - item: Annotatable, - ) -> Vec { - ecx.sess.dcx().emit_err(errors::AutoDiffSupportNotBuild { span: meta_item.span }); - return vec![item]; - } -} - -#[cfg(not(llvm_enzyme))] -pub(crate) use ad_fallback::expand; -#[cfg(llvm_enzyme)] pub(crate) use llvm_enzyme::expand; diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 6213bd802c75..ab1e0d8ee896 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -144,10 +144,8 @@ pub(crate) struct AllocMustStatics { pub(crate) span: Span, } -#[cfg(llvm_enzyme)] pub(crate) use autodiff::*; -#[cfg(llvm_enzyme)] mod autodiff { use super::*; #[derive(Diagnostic)] @@ -203,9 +201,7 @@ mod autodiff { } } -#[cfg(not(llvm_enzyme))] pub(crate) use ad_fallback::*; -#[cfg(not(llvm_enzyme))] mod ad_fallback { use super::*; #[derive(Diagnostic)] From 8cab0ba91afce2b9f0c0947e61a2d2ace329ca48 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Thu, 27 Feb 2025 14:15:23 +0000 Subject: [PATCH 390/991] Remove unneeded import --- src/tools/miri/tests/pass/unsized.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tools/miri/tests/pass/unsized.rs b/src/tools/miri/tests/pass/unsized.rs index acda3d4ce10f..6ad063543029 100644 --- a/src/tools/miri/tests/pass/unsized.rs +++ b/src/tools/miri/tests/pass/unsized.rs @@ -3,8 +3,6 @@ #![feature(unsized_fn_params)] #![feature(custom_mir, core_intrinsics)] -use std::mem; - fn unsized_params() { pub fn f0(_f: dyn FnOnce()) {} pub fn f1(_s: str) {} From 31388f52806c339123575871048dcb7ca25ae9f7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 27 Feb 2025 15:37:59 +0100 Subject: [PATCH 391/991] checked_ilog tests: deal with a bit of float imprecision --- library/coretests/tests/num/int_log.rs | 74 +++++++++++++++++++------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/library/coretests/tests/num/int_log.rs b/library/coretests/tests/num/int_log.rs index 9c630a61dd5b..e8d35fc21ce6 100644 --- a/library/coretests/tests/num/int_log.rs +++ b/library/coretests/tests/num/int_log.rs @@ -1,5 +1,13 @@ //! Tests for the `Integer::{ilog,log2,log10}` methods. +/// Rounds the argument down to the next integer, except that we account for potential imprecision +/// in the input, so if `f` is very close to an integer, it will round to that. +fn round_down_imprecise(f: f32) -> u32 { + // Rounds up for values less than 16*EPSILON below an integer, + // and rounds down for everything else. + (f + 16.0 * f32::EPSILON) as u32 +} + #[test] fn checked_ilog() { assert_eq!(999u32.checked_ilog(10), Some(2)); @@ -25,11 +33,19 @@ fn checked_ilog() { } #[cfg(not(miri))] // Miri is too slow for i in 1..=i16::MAX { - assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32), "checking {i}"); + assert_eq!( + i.checked_ilog(13), + Some(round_down_imprecise((i as f32).log(13.0))), + "checking {i}" + ); } #[cfg(not(miri))] // Miri is too slow for i in 1..=u16::MAX { - assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32), "checking {i}"); + assert_eq!( + i.checked_ilog(13), + Some(round_down_imprecise((i as f32).log(13.0))), + "checking {i}" + ); } } @@ -46,25 +62,34 @@ fn checked_ilog2() { assert_eq!(0i8.checked_ilog2(), None); assert_eq!(0i16.checked_ilog2(), None); - assert_eq!(8192u16.checked_ilog2(), Some((8192f32).log2() as u32)); - assert_eq!(32768u16.checked_ilog2(), Some((32768f32).log2() as u32)); - assert_eq!(8192i16.checked_ilog2(), Some((8192f32).log2() as u32)); + assert_eq!(8192u16.checked_ilog2(), Some(round_down_imprecise((8192f32).log2()))); + assert_eq!(32768u16.checked_ilog2(), Some(round_down_imprecise((32768f32).log2()))); + assert_eq!(8192i16.checked_ilog2(), Some(round_down_imprecise((8192f32).log2()))); for i in 1..=u8::MAX { - assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32), "checking {i}"); + assert_eq!( + i.checked_ilog2(), + Some(round_down_imprecise((i as f32).log2())), + "checking {i}" + ); } #[cfg(not(miri))] // Miri is too slow for i in 1..=u16::MAX { - // Guard against Android's imprecise f32::ilog2 implementation. - if i != 8192 && i != 32768 { - assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32), "checking {i}"); - } + assert_eq!( + i.checked_ilog2(), + Some(round_down_imprecise((i as f32).log2())), + "checking {i}" + ); } for i in i8::MIN..=0 { assert_eq!(i.checked_ilog2(), None, "checking {i}"); } for i in 1..=i8::MAX { - assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32), "checking {i}"); + assert_eq!( + i.checked_ilog2(), + Some(round_down_imprecise((i as f32).log2())), + "checking {i}" + ); } #[cfg(not(miri))] // Miri is too slow for i in i16::MIN..=0 { @@ -72,10 +97,11 @@ fn checked_ilog2() { } #[cfg(not(miri))] // Miri is too slow for i in 1..=i16::MAX { - // Guard against Android's imprecise f32::ilog2 implementation. - if i != 8192 { - assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32), "checking {i}"); - } + assert_eq!( + i.checked_ilog2(), + Some(round_down_imprecise((i as f32).log2())), + "checking {i}" + ); } } @@ -92,15 +118,27 @@ fn checked_ilog10() { } #[cfg(not(miri))] // Miri is too slow for i in 1..=i16::MAX { - assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32), "checking {i}"); + assert_eq!( + i.checked_ilog10(), + Some(round_down_imprecise((i as f32).log10())), + "checking {i}" + ); } #[cfg(not(miri))] // Miri is too slow for i in 1..=u16::MAX { - assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32), "checking {i}"); + assert_eq!( + i.checked_ilog10(), + Some(round_down_imprecise((i as f32).log10())), + "checking {i}" + ); } #[cfg(not(miri))] // Miri is too slow for i in 1..=100_000u32 { - assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32), "checking {i}"); + assert_eq!( + i.checked_ilog10(), + Some(round_down_imprecise((i as f32).log10())), + "checking {i}" + ); } } From 040415665484327a5ca425d5c39ef6dfaa19bafa Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Thu, 27 Feb 2025 15:57:08 +0100 Subject: [PATCH 392/991] ignore doc test that only fails on windows --- src/tools/rust-analyzer/crates/paths/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/paths/src/lib.rs b/src/tools/rust-analyzer/crates/paths/src/lib.rs index 008424416169..3d722b1ff115 100644 --- a/src/tools/rust-analyzer/crates/paths/src/lib.rs +++ b/src/tools/rust-analyzer/crates/paths/src/lib.rs @@ -232,7 +232,7 @@ impl AbsPath { /// - Removes trailing slashes: `/a/b/` becomes `/a/b`. /// /// # Example - /// ``` + /// ```ignore /// # use paths::AbsPathBuf; /// let abs_path_buf = AbsPathBuf::assert("/a/../../b/.//c//".into()); /// let normalized = abs_path_buf.normalize(); From 1b6c4b777038fb25de42d44772ad7bff1899d545 Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Thu, 27 Feb 2025 16:09:00 +0100 Subject: [PATCH 393/991] ignore another test that fails on windows --- src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs b/src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs index 3c8e37413f68..cce8595cc4a9 100644 --- a/src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs +++ b/src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs @@ -59,7 +59,7 @@ impl VfsPath { /// /// # Example /// - /// ``` + /// ```ignore /// # use vfs::{AbsPathBuf, VfsPath}; /// let mut path = VfsPath::from(AbsPathBuf::assert("/foo/bar".into())); /// assert!(path.pop()); From e100fd4d52c2e0f7a02c8237da5a65ea3e8c6d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kostrubiec?= Date: Thu, 27 Feb 2025 16:05:01 +0100 Subject: [PATCH 394/991] Changed the dependency graph to start preallocated with 128 capacity --- compiler/rustc_query_system/src/dep_graph/graph.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 5e6bee1dbd5a..6ece01c211ba 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1299,12 +1299,11 @@ impl Default for TaskDeps { #[cfg(debug_assertions)] node: None, reads: EdgesVec::new(), - read_set: FxHashSet::default(), + read_set: FxHashSet::with_capacity_and_hasher(128, Default::default()), phantom_data: PhantomData, } } } - // A data structure that stores Option values as a contiguous // array, using one u32 per entry. struct DepNodeColorMap { From 6cc6b86e400ccbcf024b371c5a3fae5d160e397b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 27 Feb 2025 08:33:44 -0800 Subject: [PATCH 395/991] Update E0133 docs for 2024 edition --- compiler/rustc_error_codes/src/error_codes/E0133.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0133.md b/compiler/rustc_error_codes/src/error_codes/E0133.md index 8ca3f03ce156..854cca3d10ff 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0133.md +++ b/compiler/rustc_error_codes/src/error_codes/E0133.md @@ -45,6 +45,7 @@ unsafe fn g() { ``` Linting against this is controlled via the `unsafe_op_in_unsafe_fn` lint, which -is `allow` by default but will be upgraded to `warn` in a future edition. +is `warn` by default in the 2024 edition and `allow` by default in earlier +editions. [unsafe-section]: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html From 66368aa629ff844aa6e92ed49dc6ed12bc65f4e5 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 27 Feb 2025 16:49:37 +0100 Subject: [PATCH 396/991] Allow unsetting default cfgs --- .../rust-analyzer/crates/cfg/src/cfg_expr.rs | 19 +++++++ src/tools/rust-analyzer/crates/cfg/src/dnf.rs | 19 ++----- src/tools/rust-analyzer/crates/cfg/src/lib.rs | 20 ++++--- .../crates/project-model/src/tests.rs | 4 +- .../crates/project-model/src/workspace.rs | 8 +-- .../rust-analyzer/src/cli/analysis_stats.rs | 2 +- .../crates/rust-analyzer/src/config.rs | 56 +++++++++++-------- .../crates/rust-analyzer/src/flycheck.rs | 26 +++++---- .../docs/book/src/configuration_generated.md | 4 ++ .../rust-analyzer/editors/code/package.json | 2 +- 10 files changed, 96 insertions(+), 64 deletions(-) diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs index 84b91a527f05..0ec082dfa7fc 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs @@ -18,6 +18,25 @@ pub enum CfgAtom { KeyValue { key: Symbol, value: Symbol }, } +impl PartialOrd for CfgAtom { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for CfgAtom { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match (self, other) { + (CfgAtom::Flag(a), CfgAtom::Flag(b)) => a.as_str().cmp(b.as_str()), + (CfgAtom::Flag(_), CfgAtom::KeyValue { .. }) => std::cmp::Ordering::Less, + (CfgAtom::KeyValue { .. }, CfgAtom::Flag(_)) => std::cmp::Ordering::Greater, + (CfgAtom::KeyValue { key, value }, CfgAtom::KeyValue { key: key2, value: value2 }) => { + key.as_str().cmp(key2.as_str()).then(value.as_str().cmp(value2.as_str())) + } + } + } +} + impl fmt::Display for CfgAtom { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/src/tools/rust-analyzer/crates/cfg/src/dnf.rs b/src/tools/rust-analyzer/crates/cfg/src/dnf.rs index f3ebca046509..424672a275e5 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/dnf.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/dnf.rs @@ -66,9 +66,9 @@ impl DnfExpr { } } - res.enabled.sort_unstable_by(compare); + res.enabled.sort_unstable(); res.enabled.dedup(); - res.disabled.sort_unstable_by(compare); + res.disabled.sort_unstable(); res.disabled.dedup(); Some(res) } @@ -114,25 +114,14 @@ impl DnfExpr { }; // Undo the FxHashMap randomization for consistent output. - diff.enable.sort_unstable_by(compare); - diff.disable.sort_unstable_by(compare); + diff.enable.sort_unstable(); + diff.disable.sort_unstable(); Some(diff) }) } } -fn compare(a: &CfgAtom, b: &CfgAtom) -> std::cmp::Ordering { - match (a, b) { - (CfgAtom::Flag(a), CfgAtom::Flag(b)) => a.as_str().cmp(b.as_str()), - (CfgAtom::Flag(_), CfgAtom::KeyValue { .. }) => std::cmp::Ordering::Less, - (CfgAtom::KeyValue { .. }, CfgAtom::Flag(_)) => std::cmp::Ordering::Greater, - (CfgAtom::KeyValue { key, value }, CfgAtom::KeyValue { key: key2, value: value2 }) => { - key.as_str().cmp(key2.as_str()).then(value.as_str().cmp(value2.as_str())) - } - } -} - impl fmt::Display for DnfExpr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.conjunctions.len() != 1 { diff --git a/src/tools/rust-analyzer/crates/cfg/src/lib.rs b/src/tools/rust-analyzer/crates/cfg/src/lib.rs index 6a6213a871fd..08545b685119 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/lib.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/lib.rs @@ -148,16 +148,20 @@ pub struct CfgDiff { } impl CfgDiff { - /// Create a new CfgDiff. Will return None if the same item appears more than once in the set - /// of both. - pub fn new(enable: Vec, disable: Vec) -> Option { - let mut occupied = FxHashSet::default(); - if enable.iter().chain(disable.iter()).any(|item| !occupied.insert(item)) { - // was present - return None; + /// Create a new CfgDiff. + pub fn new(mut enable: Vec, mut disable: Vec) -> CfgDiff { + enable.sort(); + enable.dedup(); + disable.sort(); + disable.dedup(); + for i in (0..enable.len()).rev() { + if let Some(j) = disable.iter().position(|atom| *atom == enable[i]) { + enable.remove(i); + disable.remove(j); + } } - Some(CfgDiff { enable, disable }) + CfgDiff { enable, disable } } /// Returns the total number of atoms changed by this diff. diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index cfc666970bd6..837406227323 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -166,7 +166,7 @@ fn check_crate_graph(crate_graph: CrateGraph, expect: ExpectFile) { #[test] fn cargo_hello_world_project_model_with_wildcard_overrides() { let cfg_overrides = CfgOverrides { - global: CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]).unwrap(), + global: CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]), selective: Default::default(), }; let (crate_graph, _proc_macros) = @@ -185,7 +185,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { global: Default::default(), selective: std::iter::once(( "libc".to_owned(), - CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]).unwrap(), + CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]), )) .collect(), }; diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 6b6fb5f9ec1f..8321d41466eb 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -1522,7 +1522,7 @@ fn extend_crate_graph_with_sysroot( ) -> (SysrootPublicDeps, Option) { let mut pub_deps = vec![]; let mut libproc_macro = None; - let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap(); + let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]); for (cid, c) in sysroot_crate_graph.iter_mut() { // uninject `test` flag so `core` keeps working. Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone()); @@ -1596,8 +1596,7 @@ fn sysroot_to_crate_graph( CfgAtom::Flag(sym::miri.clone()), ], vec![], - ) - .unwrap(), + ), ..Default::default() }, &WorkspaceBuildScripts::default(), @@ -1620,8 +1619,7 @@ fn sysroot_to_crate_graph( CfgAtom::Flag(sym::miri.clone()), ], vec![], - ) - .unwrap(), + ), ..Default::default() }, false, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 4fc6180920f5..b9e4457fc98d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -69,7 +69,7 @@ impl flags::AnalysisStats { all_targets: true, set_test: !self.no_test, cfg_overrides: CfgOverrides { - global: CfgDiff::new(vec![CfgAtom::Flag(hir::sym::miri.clone())], vec![]).unwrap(), + global: CfgDiff::new(vec![CfgAtom::Flag(hir::sym::miri.clone())], vec![]), selective: Default::default(), }, ..Default::default() diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 713e28c87cbe..45ac68339b38 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -18,7 +18,7 @@ use ide_db::{ imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind}, SnippetCap, }; -use itertools::Itertools; +use itertools::{Either, Itertools}; use paths::{Utf8Path, Utf8PathBuf}; use project_model::{ CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectJsonFromCommand, @@ -589,6 +589,10 @@ config_data! { /// avoid checking unnecessary things. cargo_buildScripts_useRustcWrapper: bool = true, /// List of cfg options to enable with the given values. + /// + /// To enable a name without a value, use `"key"`. + /// To enable a name with a value, use `"key=value"`. + /// To disable, prefix the entry with a `!`. cargo_cfgs: Vec = { vec!["debug_assertions".into(), "miri".into()] }, @@ -1980,27 +1984,35 @@ impl Config { rustc_source, extra_includes, cfg_overrides: project_model::CfgOverrides { - global: CfgDiff::new( - self.cargo_cfgs(source_root) - .iter() - // parse any cfg setting formatted as key=value or just key (without value) - .filter_map(|s| { - let mut sp = s.splitn(2, "="); - let key = sp.next(); - let val = sp.next(); - key.map(|key| (key, val)) - }) - .map(|(key, val)| match val { - Some(val) => CfgAtom::KeyValue { - key: Symbol::intern(key), - value: Symbol::intern(val), - }, - None => CfgAtom::Flag(Symbol::intern(key)), - }) - .collect(), - vec![], - ) - .unwrap(), + global: { + let (enabled, disabled): (Vec<_>, Vec<_>) = + self.cargo_cfgs(source_root).iter().partition_map(|s| { + s.strip_prefix("!").map_or(Either::Left(s), Either::Right) + }); + CfgDiff::new( + enabled + .into_iter() + // parse any cfg setting formatted as key=value or just key (without value) + .map(|s| match s.split_once("=") { + Some((key, val)) => CfgAtom::KeyValue { + key: Symbol::intern(key), + value: Symbol::intern(val), + }, + None => CfgAtom::Flag(Symbol::intern(s)), + }) + .collect(), + disabled + .into_iter() + .map(|s| match s.split_once("=") { + Some((key, val)) => CfgAtom::KeyValue { + key: Symbol::intern(key), + value: Symbol::intern(val), + }, + None => CfgAtom::Flag(Symbol::intern(s)), + }) + .collect(), + ) + }, selective: Default::default(), }, wrap_rustc_in_build_scripts: *self.cargo_buildScripts_useRustcWrapper(source_root), diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 2309f94a7429..7529e7c188f8 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -244,8 +244,14 @@ struct FlycheckActor { /// The receiver side of the channel mentioned above. command_receiver: Option>, diagnostics_cleared_for: FxHashSet>, - diagnostics_cleared_for_all: bool, - diagnostics_received: bool, + diagnostics_received: DiagnosticsReceived, +} + +#[derive(PartialEq)] +enum DiagnosticsReceived { + Yes, + No, + YesAndClearedForAll, } #[allow(clippy::large_enum_variant)] @@ -276,8 +282,7 @@ impl FlycheckActor { command_handle: None, command_receiver: None, diagnostics_cleared_for: Default::default(), - diagnostics_cleared_for_all: false, - diagnostics_received: false, + diagnostics_received: DiagnosticsReceived::No, } } @@ -354,7 +359,7 @@ impl FlycheckActor { error ); } - if !self.diagnostics_received { + if self.diagnostics_received == DiagnosticsReceived::No { tracing::trace!(flycheck_id = self.id, "clearing diagnostics"); // We finished without receiving any diagnostics. // Clear everything for good measure @@ -396,7 +401,7 @@ impl FlycheckActor { package_id = package_id.as_ref().map(|it| &it.repr), "diagnostic received" ); - self.diagnostics_received = true; + self.diagnostics_received = DiagnosticsReceived::Yes; if let Some(package_id) = &package_id { if self.diagnostics_cleared_for.insert(package_id.clone()) { tracing::trace!( @@ -409,8 +414,10 @@ impl FlycheckActor { package_id: Some(package_id.clone()), }); } - } else if !self.diagnostics_cleared_for_all { - self.diagnostics_cleared_for_all = true; + } else if self.diagnostics_received + != DiagnosticsReceived::YesAndClearedForAll + { + self.diagnostics_received = DiagnosticsReceived::YesAndClearedForAll; self.send(FlycheckMessage::ClearDiagnostics { id: self.id, package_id: None, @@ -445,8 +452,7 @@ impl FlycheckActor { fn clear_diagnostics_state(&mut self) { self.diagnostics_cleared_for.clear(); - self.diagnostics_cleared_for_all = false; - self.diagnostics_received = false; + self.diagnostics_received = DiagnosticsReceived::No; } /// Construct a `Command` object for checking the user's code. If the user diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index 1cbe51836f47..0a612d20b9cc 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -102,6 +102,10 @@ Default: List of cfg options to enable with the given values. +To enable a name without a value, use `"key"`. +To enable a name with a value, use `"key=value"`. +To disable, prefix the entry with a `!`. + **rust-analyzer.cargo.extraArgs** (default: []) diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index a7c8506a45e6..df0a9466a56a 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -818,7 +818,7 @@ "title": "cargo", "properties": { "rust-analyzer.cargo.cfgs": { - "markdownDescription": "List of cfg options to enable with the given values.", + "markdownDescription": "List of cfg options to enable with the given values.\n\nTo enable a name without a value, use `\"key\"`.\nTo enable a name with a value, use `\"key=value\"`.\nTo disable, prefix the entry with a `!`.", "default": [ "debug_assertions", "miri" From f19b205df4cf90067c9590a752b3de46df4baf22 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 27 Feb 2025 17:40:10 +0100 Subject: [PATCH 397/991] Warn when the used toolchain looks too old for rust-analyzer --- .../rust-analyzer/src/handlers/request.rs | 2 +- .../crates/rust-analyzer/src/lib.rs | 121 ++---------------- .../crates/rust-analyzer/src/lsp.rs | 113 ++++++++++++++++ .../crates/rust-analyzer/src/lsp/to_proto.rs | 2 +- .../crates/rust-analyzer/src/reload.rs | 16 +++ 5 files changed, 140 insertions(+), 114 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index b91a5dbd4166..4ab96e9e2d58 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -32,13 +32,13 @@ use triomphe::Arc; use vfs::{AbsPath, AbsPathBuf, FileId, VfsPath}; use crate::{ - completion_item_hash, config::{Config, RustfmtConfig, WorkspaceSymbolConfig}, diagnostics::convert_diagnostic, global_state::{FetchWorkspaceRequest, GlobalState, GlobalStateSnapshot}, hack_recover_crate_name, line_index::LineEndings, lsp::{ + completion_item_hash, ext::{ InternalTestingFetchConfigOption, InternalTestingFetchConfigParams, InternalTestingFetchConfigResponse, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 27d6225cdb7e..a0d6a0d6da6f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -9,6 +9,15 @@ //! The `cli` submodule implements some batch-processing analysis, primarily as //! a debugging aid. +/// Any toolchain less than this version will likely not work with rust-analyzer built from this revision. +pub const MINIMUM_SUPPORTED_TOOLCHAIN_VERSION: semver::Version = semver::Version { + major: 1, + minor: 78, + patch: 0, + pre: semver::Prerelease::EMPTY, + build: semver::BuildMetadata::EMPTY, +}; + pub mod cli; mod command; @@ -47,10 +56,7 @@ use self::lsp::ext as lsp_ext; #[cfg(test)] mod integrated_benchmarks; -use hir::Mutability; -use ide::{CompletionItem, CompletionItemRefMode, CompletionRelevance}; use serde::de::DeserializeOwned; -use tenthash::TentHash; pub use crate::{ lsp::capabilities::server_capabilities, main_loop::main_loop, reload::ws_to_crate_graph, @@ -65,115 +71,6 @@ pub fn from_json( .map_err(|e| anyhow::format_err!("Failed to deserialize {what}: {e}; {json}")) } -fn completion_item_hash(item: &CompletionItem, is_ref_completion: bool) -> [u8; 20] { - fn hash_completion_relevance(hasher: &mut TentHash, relevance: &CompletionRelevance) { - use ide_completion::{ - CompletionRelevancePostfixMatch, CompletionRelevanceReturnType, - CompletionRelevanceTypeMatch, - }; - - hasher.update([ - u8::from(relevance.exact_name_match), - u8::from(relevance.is_local), - u8::from(relevance.is_name_already_imported), - u8::from(relevance.requires_import), - u8::from(relevance.is_private_editable), - ]); - - match relevance.type_match { - None => hasher.update([0u8]), - Some(CompletionRelevanceTypeMatch::CouldUnify) => hasher.update([1u8]), - Some(CompletionRelevanceTypeMatch::Exact) => hasher.update([2u8]), - } - - hasher.update([u8::from(relevance.trait_.is_some())]); - if let Some(trait_) = &relevance.trait_ { - hasher.update([u8::from(trait_.is_op_method), u8::from(trait_.notable_trait)]); - } - - match relevance.postfix_match { - None => hasher.update([0u8]), - Some(CompletionRelevancePostfixMatch::NonExact) => hasher.update([1u8]), - Some(CompletionRelevancePostfixMatch::Exact) => hasher.update([2u8]), - } - - hasher.update([u8::from(relevance.function.is_some())]); - if let Some(function) = &relevance.function { - hasher.update([u8::from(function.has_params), u8::from(function.has_self_param)]); - let discriminant: u8 = match function.return_type { - CompletionRelevanceReturnType::Other => 0, - CompletionRelevanceReturnType::DirectConstructor => 1, - CompletionRelevanceReturnType::Constructor => 2, - CompletionRelevanceReturnType::Builder => 3, - }; - hasher.update([discriminant]); - } - } - - let mut hasher = TentHash::new(); - hasher.update([ - u8::from(is_ref_completion), - u8::from(item.is_snippet), - u8::from(item.deprecated), - u8::from(item.trigger_call_info), - ]); - - hasher.update(item.label.primary.len().to_ne_bytes()); - hasher.update(&item.label.primary); - - hasher.update([u8::from(item.label.detail_left.is_some())]); - if let Some(label_detail) = &item.label.detail_left { - hasher.update(label_detail.len().to_ne_bytes()); - hasher.update(label_detail); - } - - hasher.update([u8::from(item.label.detail_right.is_some())]); - if let Some(label_detail) = &item.label.detail_right { - hasher.update(label_detail.len().to_ne_bytes()); - hasher.update(label_detail); - } - - // NB: do not hash edits or source range, as those may change between the time the client sends the resolve request - // and the time it receives it: some editors do allow changing the buffer between that, leading to ranges being different. - // - // Documentation hashing is skipped too, as it's a large blob to process, - // while not really making completion properties more unique as they are already. - - let kind_tag = item.kind.tag(); - hasher.update(kind_tag.len().to_ne_bytes()); - hasher.update(kind_tag); - - hasher.update(item.lookup.len().to_ne_bytes()); - hasher.update(&item.lookup); - - hasher.update([u8::from(item.detail.is_some())]); - if let Some(detail) = &item.detail { - hasher.update(detail.len().to_ne_bytes()); - hasher.update(detail); - } - - hash_completion_relevance(&mut hasher, &item.relevance); - - hasher.update([u8::from(item.ref_match.is_some())]); - if let Some((ref_mode, text_size)) = &item.ref_match { - let discriminant = match ref_mode { - CompletionItemRefMode::Reference(Mutability::Shared) => 0u8, - CompletionItemRefMode::Reference(Mutability::Mut) => 1u8, - CompletionItemRefMode::Dereference => 2u8, - }; - hasher.update([discriminant]); - hasher.update(u32::from(*text_size).to_ne_bytes()); - } - - hasher.update(item.import_to_add.len().to_ne_bytes()); - for import_path in &item.import_to_add { - hasher.update(import_path.len().to_ne_bytes()); - hasher.update(import_path); - } - - hasher.finalize() -} - #[doc(hidden)] macro_rules! try_default_ { ($it:expr $(,)?) => { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs index 122ad20d65ee..c7a5a95e66bb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs @@ -2,6 +2,10 @@ use core::fmt; +use hir::Mutability; +use ide::{CompletionItem, CompletionItemRefMode, CompletionRelevance}; +use tenthash::TentHash; + pub mod ext; pub(crate) mod capabilities; @@ -29,3 +33,112 @@ impl fmt::Display for LspError { } impl std::error::Error for LspError {} + +pub(crate) fn completion_item_hash(item: &CompletionItem, is_ref_completion: bool) -> [u8; 20] { + fn hash_completion_relevance(hasher: &mut TentHash, relevance: &CompletionRelevance) { + use ide_completion::{ + CompletionRelevancePostfixMatch, CompletionRelevanceReturnType, + CompletionRelevanceTypeMatch, + }; + + hasher.update([ + u8::from(relevance.exact_name_match), + u8::from(relevance.is_local), + u8::from(relevance.is_name_already_imported), + u8::from(relevance.requires_import), + u8::from(relevance.is_private_editable), + ]); + + match relevance.type_match { + None => hasher.update([0u8]), + Some(CompletionRelevanceTypeMatch::CouldUnify) => hasher.update([1u8]), + Some(CompletionRelevanceTypeMatch::Exact) => hasher.update([2u8]), + } + + hasher.update([u8::from(relevance.trait_.is_some())]); + if let Some(trait_) = &relevance.trait_ { + hasher.update([u8::from(trait_.is_op_method), u8::from(trait_.notable_trait)]); + } + + match relevance.postfix_match { + None => hasher.update([0u8]), + Some(CompletionRelevancePostfixMatch::NonExact) => hasher.update([1u8]), + Some(CompletionRelevancePostfixMatch::Exact) => hasher.update([2u8]), + } + + hasher.update([u8::from(relevance.function.is_some())]); + if let Some(function) = &relevance.function { + hasher.update([u8::from(function.has_params), u8::from(function.has_self_param)]); + let discriminant: u8 = match function.return_type { + CompletionRelevanceReturnType::Other => 0, + CompletionRelevanceReturnType::DirectConstructor => 1, + CompletionRelevanceReturnType::Constructor => 2, + CompletionRelevanceReturnType::Builder => 3, + }; + hasher.update([discriminant]); + } + } + + let mut hasher = TentHash::new(); + hasher.update([ + u8::from(is_ref_completion), + u8::from(item.is_snippet), + u8::from(item.deprecated), + u8::from(item.trigger_call_info), + ]); + + hasher.update(item.label.primary.len().to_ne_bytes()); + hasher.update(&item.label.primary); + + hasher.update([u8::from(item.label.detail_left.is_some())]); + if let Some(label_detail) = &item.label.detail_left { + hasher.update(label_detail.len().to_ne_bytes()); + hasher.update(label_detail); + } + + hasher.update([u8::from(item.label.detail_right.is_some())]); + if let Some(label_detail) = &item.label.detail_right { + hasher.update(label_detail.len().to_ne_bytes()); + hasher.update(label_detail); + } + + // NB: do not hash edits or source range, as those may change between the time the client sends the resolve request + // and the time it receives it: some editors do allow changing the buffer between that, leading to ranges being different. + // + // Documentation hashing is skipped too, as it's a large blob to process, + // while not really making completion properties more unique as they are already. + + let kind_tag = item.kind.tag(); + hasher.update(kind_tag.len().to_ne_bytes()); + hasher.update(kind_tag); + + hasher.update(item.lookup.len().to_ne_bytes()); + hasher.update(&item.lookup); + + hasher.update([u8::from(item.detail.is_some())]); + if let Some(detail) = &item.detail { + hasher.update(detail.len().to_ne_bytes()); + hasher.update(detail); + } + + hash_completion_relevance(&mut hasher, &item.relevance); + + hasher.update([u8::from(item.ref_match.is_some())]); + if let Some((ref_mode, text_size)) = &item.ref_match { + let discriminant = match ref_mode { + CompletionItemRefMode::Reference(Mutability::Shared) => 0u8, + CompletionItemRefMode::Reference(Mutability::Mut) => 1u8, + CompletionItemRefMode::Dereference => 2u8, + }; + hasher.update([discriminant]); + hasher.update(u32::from(*text_size).to_ne_bytes()); + } + + hasher.update(item.import_to_add.len().to_ne_bytes()); + for import_path in &item.import_to_add { + hasher.update(import_path.len().to_ne_bytes()); + hasher.update(import_path); + } + + hasher.finalize() +} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 446549c90700..3c206f47db5e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -24,11 +24,11 @@ use serde_json::to_value; use vfs::AbsPath; use crate::{ - completion_item_hash, config::{CallInfoConfig, Config}, global_state::GlobalStateSnapshot, line_index::{LineEndings, LineIndex, PositionEncoding}, lsp::{ + completion_item_hash, ext::ShellRunnableArgs, semantic_tokens::{self, standard_fallback_type}, utils::invalid_params_error, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 56dcad0eb18b..733a7c359b8e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -182,6 +182,22 @@ impl GlobalState { self.proc_macro_clients.iter().map(Some).chain(iter::repeat_with(|| None)); for (ws, proc_macro_client) in self.workspaces.iter().zip(proc_macro_clients) { + if let Some(toolchain) = &ws.toolchain { + if *toolchain < crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION { + status.health |= lsp_ext::Health::Warning; + format_to!( + message, + "Workspace `{}` is using an outdated toolchain version `{}` but \ + rust-analyzer only supports `{}` and higher.\n\ + Consider using the rust-analyzer rustup component for your toolchain or + upgrade your toolchain to a supported version.\n\n", + ws.manifest_or_root(), + toolchain, + crate::MINIMUM_SUPPORTED_TOOLCHAIN_VERSION, + ); + } + } + if let ProjectWorkspaceKind::Cargo { error: Some(error), .. } | ProjectWorkspaceKind::DetachedFile { cargo: Some((_, _, Some(error))), .. From 396c2a8659b0b99254a25b7c0431a99d8223fb5c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 27 Feb 2025 09:09:52 -0800 Subject: [PATCH 398/991] Stop using `hash_raw_entry` in `CodegenCx::const_str` That unstable feature completed fcp-close, so the compiler needs to be migrated away to allow its removal. In this case, `cg_llvm` and `cg_gcc` were using raw entries to optimize their `const_str_cache` lookup and insertion. We can change that to separate `get` and (on miss) `insert` calls, so we still have the fast path avoiding string allocation when the cache hits. --- compiler/rustc_codegen_gcc/src/common.rs | 13 ++++---- compiler/rustc_codegen_gcc/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/src/common.rs | 40 ++++++++++------------- compiler/rustc_codegen_llvm/src/lib.rs | 1 - 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 20a3482aaa27..ce1a20088647 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -146,13 +146,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } fn const_str(&self, s: &str) -> (RValue<'gcc>, RValue<'gcc>) { - let str_global = *self - .const_str_cache - .borrow_mut() - .raw_entry_mut() - .from_key(s) - .or_insert_with(|| (s.to_owned(), self.global_string(s))) - .1; + let mut const_str_cache = self.const_str_cache.borrow_mut(); + let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| { + let g = self.global_string(s); + const_str_cache.insert(s.to_owned(), g); + g + }); let len = s.len(); let cs = self.const_ptrcast( str_global.get_address(None), diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 6455bcec6851..741386876790 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -16,7 +16,7 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry, let_chains)] +#![feature(rustc_private, decl_macro, never_type, trusted_len, let_chains)] #![allow(broken_intra_doc_links)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 0621b893e755..6eaecfa87a9c 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -209,28 +209,24 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn const_str(&self, s: &str) -> (&'ll Value, &'ll Value) { - let str_global = *self - .const_str_cache - .borrow_mut() - .raw_entry_mut() - .from_key(s) - .or_insert_with(|| { - let sc = self.const_bytes(s.as_bytes()); - let sym = self.generate_local_symbol_name("str"); - let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| { - bug!("symbol `{}` is already defined", sym); - }); - llvm::set_initializer(g, sc); - unsafe { - llvm::LLVMSetGlobalConstant(g, True); - llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global); - } - llvm::set_linkage(g, llvm::Linkage::InternalLinkage); - // Cast to default address space if globals are in a different addrspace - let g = self.const_pointercast(g, self.type_ptr()); - (s.to_owned(), g) - }) - .1; + let mut const_str_cache = self.const_str_cache.borrow_mut(); + let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| { + let sc = self.const_bytes(s.as_bytes()); + let sym = self.generate_local_symbol_name("str"); + let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| { + bug!("symbol `{}` is already defined", sym); + }); + llvm::set_initializer(g, sc); + unsafe { + llvm::LLVMSetGlobalConstant(g, True); + llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global); + } + llvm::set_linkage(g, llvm::Linkage::InternalLinkage); + // Cast to default address space if globals are in a different addrspace + let g = self.const_pointercast(g, self.type_ptr()); + const_str_cache.insert(s.to_owned(), g); + g + }); let len = s.len(); (str_global, self.const_usize(len as u64)) } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index e9e1b644f183..929111b493ee 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -12,7 +12,6 @@ #![feature(exact_size_is_empty)] #![feature(extern_types)] #![feature(file_buffered)] -#![feature(hash_raw_entry)] #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] From d504f70ec9e56a49337173d384061d0b1cdd15e8 Mon Sep 17 00:00:00 2001 From: Mu001999 Date: Fri, 28 Feb 2025 00:57:54 +0800 Subject: [PATCH 399/991] Unconditionally lower match arm even if it's unneeded for never pattern in match --- compiler/rustc_ast_lowering/src/expr.rs | 7 ++-- .../unused_trait_in_never_pattern_body.rs | 12 +++++++ .../unused_trait_in_never_pattern_body.stderr | 36 +++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/ui/never_type/unused_trait_in_never_pattern_body.rs create mode 100644 tests/ui/never_type/unused_trait_in_never_pattern_body.stderr diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index af53c7ec2157..5b0f4f52c218 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -672,10 +672,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let span = self.lower_span(arm.span); self.lower_attrs(hir_id, &arm.attrs); let is_never_pattern = pat.is_never_pattern(); - let body = if let Some(body) = &arm.body + // We need to lower the body even if it's unneeded for never pattern in match, + // ensure that we can get HirId for DefId if need (issue #137708). + let body = arm.body.as_ref().map(|x| self.lower_expr(x)); + let body = if let Some(body) = body && !is_never_pattern { - self.lower_expr(body) + body } else { // Either `body.is_none()` or `is_never_pattern` here. if !is_never_pattern { diff --git a/tests/ui/never_type/unused_trait_in_never_pattern_body.rs b/tests/ui/never_type/unused_trait_in_never_pattern_body.rs new file mode 100644 index 000000000000..8179c94b72b2 --- /dev/null +++ b/tests/ui/never_type/unused_trait_in_never_pattern_body.rs @@ -0,0 +1,12 @@ +fn a() { + match 0 { + ! => || { //~ ERROR `!` patterns are experimental + //~^ ERROR a never pattern is always unreachable + //~^^ ERROR mismatched types + use std::ops::Add; + 0.add(1) + }, + } +} + +fn main() {} diff --git a/tests/ui/never_type/unused_trait_in_never_pattern_body.stderr b/tests/ui/never_type/unused_trait_in_never_pattern_body.stderr new file mode 100644 index 000000000000..18ca9f12b7e8 --- /dev/null +++ b/tests/ui/never_type/unused_trait_in_never_pattern_body.stderr @@ -0,0 +1,36 @@ +error[E0658]: `!` patterns are experimental + --> $DIR/unused_trait_in_never_pattern_body.rs:3:9 + | +LL | ! => || { + | ^ + | + = note: see issue #118155 for more information + = help: add `#![feature(never_patterns)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: a never pattern is always unreachable + --> $DIR/unused_trait_in_never_pattern_body.rs:3:14 + | +LL | ! => || { + | ______________^ +LL | | +LL | | +LL | | use std::ops::Add; +LL | | 0.add(1) +LL | | }, + | | ^ + | | | + | |_________this will never be executed + | help: remove this expression + +error: mismatched types + --> $DIR/unused_trait_in_never_pattern_body.rs:3:9 + | +LL | ! => || { + | ^ a never pattern must be used on an uninhabited type + | + = note: the matched value is of type `i32` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. From fb3aa33418fcca981493a60f4c2a1c8558ddca93 Mon Sep 17 00:00:00 2001 From: Niels Saurer Date: Thu, 27 Feb 2025 18:32:09 +0100 Subject: [PATCH 400/991] Revert "Derive `Clone` on fewer THIR types." This reverts commit f0b6d660c9c13ab7b19da9e12aeb4dcab45e544b. --- compiler/rustc_middle/src/thir.rs | 44 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index e5592de81cd7..fabee391ac67 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -19,7 +19,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd}; use rustc_index::{IndexVec, newtype_index}; -use rustc_macros::{HashStable, TypeVisitable}; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable}; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span, Symbol}; use rustc_target::asm::InlineAsmRegOrRegClass; @@ -52,7 +52,7 @@ macro_rules! thir_with_elements { /// A container for a THIR body. /// /// This can be indexed directly by any THIR index (e.g. [`ExprId`]). - #[derive(Debug, HashStable)] + #[derive(Debug, HashStable, Clone)] pub struct Thir<'tcx> { pub body_type: BodyTy<'tcx>, $( @@ -90,7 +90,7 @@ thir_with_elements! { params: ParamId => Param<'tcx> => "p{}", } -#[derive(Debug, HashStable)] +#[derive(Debug, HashStable, Clone)] pub enum BodyTy<'tcx> { Const(Ty<'tcx>), Fn(FnSig<'tcx>), @@ -98,7 +98,7 @@ pub enum BodyTy<'tcx> { } /// Description of a type-checked function parameter. -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Param<'tcx> { /// The pattern that appears in the parameter list, or None for implicit parameters. pub pat: Option>>, @@ -118,7 +118,7 @@ pub enum LintLevel { Explicit(HirId), } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Block { /// Whether the block itself has a label. Used by `label: {}` /// and `try` blocks. @@ -138,7 +138,7 @@ pub struct Block { type UserTy<'tcx> = Option>>; -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct AdtExpr<'tcx> { /// The ADT we're constructing. pub adt_def: AdtDef<'tcx>, @@ -155,7 +155,7 @@ pub struct AdtExpr<'tcx> { pub base: AdtExprBase<'tcx>, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub enum AdtExprBase<'tcx> { /// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`. None, @@ -168,7 +168,7 @@ pub enum AdtExprBase<'tcx> { DefaultFields(Box<[Ty<'tcx>]>), } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct ClosureExpr<'tcx> { pub closure_id: LocalDefId, pub args: UpvarArgs<'tcx>, @@ -177,7 +177,7 @@ pub struct ClosureExpr<'tcx> { pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct InlineAsmExpr<'tcx> { pub asm_macro: AsmMacro, pub template: &'tcx [InlineAsmTemplatePiece], @@ -195,12 +195,12 @@ pub enum BlockSafety { ExplicitUnsafe(HirId), } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Stmt<'tcx> { pub kind: StmtKind<'tcx>, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub enum StmtKind<'tcx> { /// An expression with a trailing semicolon. Expr { @@ -240,11 +240,11 @@ pub enum StmtKind<'tcx> { }, } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, HashStable)] +#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] pub struct LocalVarId(pub HirId); /// A THIR expression. -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Expr<'tcx> { /// kind of expression pub kind: ExprKind<'tcx>, @@ -271,7 +271,7 @@ pub struct TempLifetime { pub backwards_incompatible: Option, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub enum ExprKind<'tcx> { /// `Scope`s are used to explicitly mark destruction scopes, /// and to track the `HirId` of the expressions within the scope. @@ -548,20 +548,20 @@ pub enum ExprKind<'tcx> { /// Represents the association of a field identifier and an expression. /// /// This is used in struct constructors. -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct FieldExpr { pub name: FieldIdx, pub expr: ExprId, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct FruInfo<'tcx> { pub base: ExprId, pub field_types: Box<[Ty<'tcx>]>, } /// A `match` arm. -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Arm<'tcx> { pub pattern: Box>, pub guard: Option, @@ -579,7 +579,7 @@ pub enum LogicalOp { Or, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub enum InlineAsmOperand<'tcx> { In { reg: InlineAsmRegOrRegClass, @@ -616,13 +616,13 @@ pub enum InlineAsmOperand<'tcx> { }, } -#[derive(Debug, HashStable, TypeVisitable)] +#[derive(Clone, Debug, HashStable, TypeVisitable)] pub struct FieldPat<'tcx> { pub field: FieldIdx, pub pattern: Pat<'tcx>, } -#[derive(Debug, HashStable, TypeVisitable)] +#[derive(Clone, Debug, HashStable, TypeVisitable)] pub struct Pat<'tcx> { pub ty: Ty<'tcx>, pub span: Span, @@ -729,7 +729,7 @@ impl<'tcx> Pat<'tcx> { } } -#[derive(Debug, HashStable, TypeVisitable)] +#[derive(Clone, Debug, HashStable, TypeVisitable)] pub struct Ascription<'tcx> { pub annotation: CanonicalUserTypeAnnotation<'tcx>, /// Variance to use when relating the `user_ty` to the **type of the value being @@ -753,7 +753,7 @@ pub struct Ascription<'tcx> { pub variance: ty::Variance, } -#[derive(Debug, HashStable, TypeVisitable)] +#[derive(Clone, Debug, HashStable, TypeVisitable)] pub enum PatKind<'tcx> { /// A wildcard pattern: `_`. Wild, From b5f0c82eba0bdc1d753dc5e0e62326769d7360d2 Mon Sep 17 00:00:00 2001 From: Niels Saurer Date: Thu, 27 Feb 2025 18:33:44 +0100 Subject: [PATCH 401/991] Add note to Thir struct about necessity of Clone derive --- compiler/rustc_middle/src/thir.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index fabee391ac67..72f31cec0082 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -49,6 +49,9 @@ macro_rules! thir_with_elements { } )* + // Note: Making `Thir` implement `Clone` is useful for external tools that need access to + // THIR bodies even after the `Steal` query result has been stolen. + // One such tool is https://github.com/rust-corpus/qrates/. /// A container for a THIR body. /// /// This can be indexed directly by any THIR index (e.g. [`ExprId`]). From 063d6aef0eb8fe81d83a896400c15c6fe9cf0c34 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 27 Feb 2025 20:36:19 +0100 Subject: [PATCH 402/991] macro_use_import: Don't check is attribute comes from expansion It is not possible to write a declarative macro, that produces an attribute w/o an item attached to it. This means that the `check_item` will already insert the span in the map, if it came from an expansion. So additionally checking if the macro came from an expansion doesn't add anything here. So the `check_attribute` function, and with that the problematic `attr.span()` call can be completely removed. Fixes #14303 --- clippy_lints/src/macro_use.rs | 5 ----- tests/ui/crashes/ice-14303.rs | 12 ++++++++++++ 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 tests/ui/crashes/ice-14303.rs diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs index bb6e22d9e5c7..68dc1903a248 100644 --- a/clippy_lints/src/macro_use.rs +++ b/clippy_lints/src/macro_use.rs @@ -117,11 +117,6 @@ impl LateLintPass<'_> for MacroUseImports { self.push_unique_macro_pat_ty(cx, item.span); } } - fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &hir::Attribute) { - if attr.span.from_expansion() { - self.push_unique_macro(cx, attr.span); - } - } fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) { if expr.span.from_expansion() { self.push_unique_macro(cx, expr.span); diff --git a/tests/ui/crashes/ice-14303.rs b/tests/ui/crashes/ice-14303.rs new file mode 100644 index 000000000000..e81f29cd7af9 --- /dev/null +++ b/tests/ui/crashes/ice-14303.rs @@ -0,0 +1,12 @@ +//@check-pass +#![warn(clippy::macro_use_imports)] + +#[repr(transparent)] +pub struct X(()); + +#[repr(u8)] +pub enum Action { + Off = 0, +} + +fn main() {} From d6f5377826996a26d39003eec123ffdc6b3ac9ae Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Wed, 26 Feb 2025 17:17:07 +0100 Subject: [PATCH 403/991] Update Node.js, vscode, and ts deps --- .../rust-analyzer/.github/workflows/ci.yaml | 2 +- .../.github/workflows/release.yaml | 4 +- .../rust-analyzer/editors/code/.eslintignore | 2 - .../rust-analyzer/editors/code/.eslintrc.js | 46 - .../rust-analyzer/editors/code/.prettierrc.js | 5 - .../editors/code/eslint.config.mts | 48 + .../editors/code/package-lock.json | 3670 ++++++++++------- .../rust-analyzer/editors/code/package.json | 51 +- .../editors/code/prettier.config.mts | 12 + .../editors/code/src/bootstrap.ts | 4 +- .../rust-analyzer/editors/code/src/client.ts | 531 ++- .../editors/code/src/commands.ts | 12 +- .../rust-analyzer/editors/code/src/config.ts | 28 +- .../rust-analyzer/editors/code/src/ctx.ts | 41 +- .../rust-analyzer/editors/code/src/debug.ts | 9 +- .../editors/code/src/diagnostics.ts | 35 +- .../editors/code/src/lang_client.ts | 2 + .../rust-analyzer/editors/code/src/lsp_ext.ts | 1 + .../rust-analyzer/editors/code/src/main.ts | 1 + .../editors/code/src/persistent_state.ts | 1 + .../editors/code/src/snippets.ts | 4 +- .../editors/code/src/syntax_tree_provider.ts | 2 + .../editors/code/src/test_explorer.ts | 2 +- .../editors/code/src/toolchain.ts | 20 +- .../rust-analyzer/editors/code/src/util.ts | 18 +- .../editors/code/tests/unit/index.ts | 3 +- .../editors/code/tests/unit/tasks.test.ts | 5 +- .../editors/code/tsconfig.eslint.json | 2 +- .../rust-analyzer/editors/code/tsconfig.json | 11 +- 29 files changed, 2715 insertions(+), 1857 deletions(-) delete mode 100644 src/tools/rust-analyzer/editors/code/.eslintignore delete mode 100644 src/tools/rust-analyzer/editors/code/.eslintrc.js delete mode 100644 src/tools/rust-analyzer/editors/code/.prettierrc.js create mode 100644 src/tools/rust-analyzer/editors/code/eslint.config.mts create mode 100644 src/tools/rust-analyzer/editors/code/prettier.config.mts diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index 81b55712d7f3..bc770dbe71e4 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -174,7 +174,7 @@ jobs: - name: Install Nodejs uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 22 if: needs.changes.outputs.typescript == 'true' - name: Install xvfb diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml index 9ab4a0b9d255..c8e6de72ce98 100644 --- a/src/tools/rust-analyzer/.github/workflows/release.yaml +++ b/src/tools/rust-analyzer/.github/workflows/release.yaml @@ -69,7 +69,7 @@ jobs: - name: Install Node.js toolchain uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: Install Rust toolchain run: | @@ -188,7 +188,7 @@ jobs: - name: Install Nodejs uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - run: echo "TAG=$(date --iso -u)" >> $GITHUB_ENV if: github.ref == 'refs/heads/release' diff --git a/src/tools/rust-analyzer/editors/code/.eslintignore b/src/tools/rust-analyzer/editors/code/.eslintignore deleted file mode 100644 index 3a1e8e186f5d..000000000000 --- a/src/tools/rust-analyzer/editors/code/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.eslintrc.js diff --git a/src/tools/rust-analyzer/editors/code/.eslintrc.js b/src/tools/rust-analyzer/editors/code/.eslintrc.js deleted file mode 100644 index 9705c5f5ec6c..000000000000 --- a/src/tools/rust-analyzer/editors/code/.eslintrc.js +++ /dev/null @@ -1,46 +0,0 @@ -module.exports = { - env: { - es6: true, - node: true, - }, - extends: ["prettier"], - parser: "@typescript-eslint/parser", - parserOptions: { - project: true, - tsconfigRootDir: __dirname, - sourceType: "module", - }, - plugins: ["@typescript-eslint"], - rules: { - camelcase: ["error"], - eqeqeq: ["error", "always", { null: "ignore" }], - curly: ["error", "multi-line"], - "no-console": ["error", { allow: ["warn", "error"] }], - "prefer-const": "error", - "@typescript-eslint/member-delimiter-style": [ - "error", - { - multiline: { - delimiter: "semi", - requireLast: true, - }, - singleline: { - delimiter: "semi", - requireLast: false, - }, - }, - ], - "@typescript-eslint/semi": ["error", "always"], - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-floating-promises": "error", - - "@typescript-eslint/consistent-type-imports": [ - "error", - { - prefer: "type-imports", - fixStyle: "inline-type-imports", - }, - ], - "@typescript-eslint/no-import-type-side-effects": "error", - }, -}; diff --git a/src/tools/rust-analyzer/editors/code/.prettierrc.js b/src/tools/rust-analyzer/editors/code/.prettierrc.js deleted file mode 100644 index cafb12f0e6dd..000000000000 --- a/src/tools/rust-analyzer/editors/code/.prettierrc.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - // use 100 because it's Rustfmt's default - // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#max_width - printWidth: 100, -}; diff --git a/src/tools/rust-analyzer/editors/code/eslint.config.mts b/src/tools/rust-analyzer/editors/code/eslint.config.mts new file mode 100644 index 000000000000..3520593eef28 --- /dev/null +++ b/src/tools/rust-analyzer/editors/code/eslint.config.mts @@ -0,0 +1,48 @@ +import eslintConfigPrettier from "eslint-config-prettier"; +import stylistic from "@stylistic/eslint-plugin"; +import eslint from "@eslint/js"; +import tseslint from "typescript-eslint"; +import stylisticJs from "@stylistic/eslint-plugin-js"; +import { type FlatESLintConfig } from "eslint-define-config"; + +const config: FlatESLintConfig[] = [ + eslintConfigPrettier, + eslint.configs.recommended, + stylisticJs.configs["disable-legacy"], + ...tseslint.configs.recommended, + stylistic.configs.customize({ + indent: 4, + quotes: "double", + semi: true, + braceStyle: "1tbs", + arrowParens: true, + }), + { + rules: { + "no-console": "warn", + "@typescript-eslint/no-unused-vars": [ + "error", + { + args: "all", + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + varsIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + // the following stylistic lints conflict with prettier + "@stylistic/operator-linebreak": "off", + "@stylistic/indent-binary-ops": "off", + "@stylistic/indent": "off", + "@stylistic/brace-style": "off", + "@stylistic/quotes": "off", + }, + }, + { + ignores: ["out/", ".vscode-test/", "node_modules/"], + }, +]; + +export default config; diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json index 86a066454a5c..11a37c218f7f 100644 --- a/src/tools/rust-analyzer/editors/code/package-lock.json +++ b/src/tools/rust-analyzer/editors/code/package-lock.json @@ -9,39 +9,36 @@ "version": "0.5.0-dev", "license": "MIT OR Apache-2.0", "dependencies": { - "@hpcc-js/wasm": "^2.13.0", - "anser": "^2.1.1", - "d3": "^7.8.5", - "d3-graphviz": "^5.0.2", + "@hpcc-js/wasm": "^2.22.4", + "anser": "^2.3.2", + "d3": "^7.9.0", + "d3-graphviz": "^5.6.0", + "jiti": "^2.4.2", "vscode-languageclient": "^9.0.1" }, "devDependencies": { - "@tsconfig/strictest": "^2.0.1", - "@types/node": "~16.11.7", - "@types/vscode": "~1.83", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", - "@vscode/test-electron": "^2.3.8", - "@vscode/vsce": "^3.0.0", + "@eslint/js": "^9.21.0", + "@stylistic/eslint-plugin": "^4.1.0", + "@stylistic/eslint-plugin-js": "^4.1.0", + "@tsconfig/strictest": "^2.0.5", + "@types/node": "~22.13.4", + "@types/vscode": "~1.93.0", + "@typescript-eslint/eslint-plugin": "^8.25.0", + "@typescript-eslint/parser": "^8.25.0", + "@vscode/test-electron": "^2.4.1", + "@vscode/vsce": "^3.2.2", "esbuild": "^0.25.0", - "eslint": "^8.44.0", - "eslint-config-prettier": "^8.8.0", - "ovsx": "^0.8.2", - "prettier": "^3.0.0", - "tslib": "^2.6.0", - "typescript": "^5.6.0" + "eslint": "^9.21.0", + "eslint-config-prettier": "^10.0.2", + "eslint-define-config": "^2.1.0", + "ovsx": "0.10.1", + "prettier": "^3.5.2", + "tslib": "^2.8.1", + "typescript": "^5.7.3", + "typescript-eslint": "^8.25.0" }, "engines": { - "vscode": "^1.83.0" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "vscode": "^1.93.0" } }, "node_modules/@azure/abort-controller": { @@ -92,16 +89,16 @@ } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.17.0.tgz", - "integrity": "sha512-62Vv8nC+uPId3j86XJ0WI+sBf0jlqTqPUFCBNrGtlaUeQUIXWV/D8GE5A1d+Qx8H7OQojn2WguC8kChD6v0shA==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.19.0.tgz", + "integrity": "sha512-bM3308LRyg5g7r3Twprtqww0R/r7+GyVxj4BafcmVPo4WQoGt5JXuaqxHEFjw2o3rvFZcUPiqJMg6WuvEEeVUA==", "dev": true, "license": "MIT", "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-auth": "^1.8.0", "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.9.0", + "@azure/core-util": "^1.11.0", "@azure/logger": "^1.0.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", @@ -111,47 +108,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/core-rest-pipeline/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@azure/core-rest-pipeline/node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@azure/core-rest-pipeline/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/@azure/core-tracing": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", @@ -180,9 +136,9 @@ } }, "node_modules/@azure/identity": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.5.0.tgz", - "integrity": "sha512-EknvVmtBuSIic47xkOqyNabAme0RYTw52BTMz8eBgU1ysTyMrD1uOoM+JdS0J/4Yfp98IBT3osqq3BfwSaNaGQ==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.7.0.tgz", + "integrity": "sha512-6z/S2KorkbKaZ0DgZFVRdu7RCuATmMSTjKpuhj7YpjxkJ0vnJ7kTM3cpNgzFgk9OPYfZ31wrBEtC/iwAS4jQDA==", "dev": true, "license": "MIT", "dependencies": { @@ -193,11 +149,11 @@ "@azure/core-tracing": "^1.0.0", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^3.26.1", - "@azure/msal-node": "^2.15.0", + "@azure/msal-browser": "^4.2.0", + "@azure/msal-node": "^3.2.1", "events": "^3.0.0", "jws": "^4.0.0", - "open": "^8.0.0", + "open": "^10.1.0", "stoppable": "^1.1.0", "tslib": "^2.2.0" }, @@ -219,22 +175,22 @@ } }, "node_modules/@azure/msal-browser": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.26.1.tgz", - "integrity": "sha512-y78sr9g61aCAH9fcLO1um+oHFXc1/5Ap88RIsUSuzkm0BHzFnN+PXGaQeuM1h5Qf5dTnWNOd6JqkskkMPAhh7Q==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.4.0.tgz", + "integrity": "sha512-rU6juYXk67CKQmpgi6fDgZoPQ9InZ1760z1BSAH7RbeIc4lHZM/Tu+H0CyRk7cnrfvTkexyYE4pjYhMghpzheA==", "dev": true, "license": "MIT", "dependencies": { - "@azure/msal-common": "14.15.0" + "@azure/msal-common": "15.2.0" }, "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-common": { - "version": "14.15.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.15.0.tgz", - "integrity": "sha512-ImAQHxmpMneJ/4S8BRFhjt1MZ3bppmpRPYYNyzeQPeFN288YKbb8TmmISQEbtfkQ1BPASvYZU5doIZOPBAqENQ==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.2.0.tgz", + "integrity": "sha512-HiYfGAKthisUYqHG1nImCf/uzcyS31wng3o+CycWLIM9chnYJ9Lk6jZ30Y6YiYYpTQ9+z/FGUpiKKekd3Arc0A==", "dev": true, "license": "MIT", "engines": { @@ -242,13 +198,13 @@ } }, "node_modules/@azure/msal-node": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.15.0.tgz", - "integrity": "sha512-gVPW8YLz92ZeCibQH2QUw96odJoiM3k/ZPH3f2HxptozmH6+OnyyvKXo/Egg39HAM230akarQKHf0W74UHlh0Q==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.2.3.tgz", + "integrity": "sha512-0eaPqBIWEAizeYiXdeHb09Iq0tvHJ17ztvNEaLdr/KcJJhJxbpkkEQf09DB+vKlFE0tzYi7j4rYLTXtES/InEQ==", "dev": true, "license": "MIT", "dependencies": { - "@azure/msal-common": "14.15.0", + "@azure/msal-common": "15.2.0", "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" }, @@ -682,45 +638,30 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -728,38 +669,198 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz", + "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.12.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@hpcc-js/wasm": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.13.0.tgz", - "integrity": "sha512-MvnUPnyMlN3/2IONCXwl/SBVWIfVOFJqvw+kFfI1QcwKjNmkwTAtG+9/m3nvofTymkASUUxNULbBmRDIr2uzIA==", + "version": "2.22.4", + "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.22.4.tgz", + "integrity": "sha512-58JkRkxZffiBAbZhc7z+9iaaAOmn1cyxLL3rRwsUvco/I0Wwb7uVAlHM9HiU6XASe2k11jrIjCFff1t9QKjlqg==", + "license": "Apache-2.0", "dependencies": { "yargs": "17.7.2" }, "bin": { - "dot-wasm": "bin/dot-wasm.js" + "dot-wasm": "node ./node_modules/@hpcc-js/wasm-graphviz-cli/bin/index.js" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { @@ -767,6 +868,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -775,11 +877,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -799,96 +909,12 @@ "node": ">=12" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -902,6 +928,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -911,6 +938,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -919,121 +947,148 @@ "node": ">= 8" } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "node_modules/@stylistic/eslint-plugin": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.1.0.tgz", + "integrity": "sha512-bytbL7qiici7yPyEiId0fGPK9kjQbzcPMj2aftPfzTCyJ/CRSKdtI+iVjM0LSGzGxfunflI+MDDU9vyIIeIpoQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.23.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, "engines": { - "node": ">= 6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-4.1.0.tgz", + "integrity": "sha512-YOe+dChNoR26JVVt+7BjyebsPIQF05OLNmHCXivq8lLZ4ZeVs4+wXaW+pREVboDiAaSRznauAdAU8f+iQouw6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" } }, "node_modules/@tsconfig/strictest": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/strictest/-/strictest-2.0.1.tgz", - "integrity": "sha512-7JHHCbyCsGUxLd0pDbp24yz3zjxw2t673W5oAP6HCEdr/UUhaRhYd3SSnUsGCk+VnPVJVA4mXROzbhI+nyIk+w==", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@tsconfig/strictest/-/strictest-2.0.5.tgz", + "integrity": "sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "16.11.68", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz", - "integrity": "sha512-JkRpuVz3xCNCWaeQ5EHLR/6woMbHZz/jZ7Kmc63AkU+1HxnoUugzSWMck7dsR4DvNYX8jp9wTi9K7WvnxOIQZQ==", - "dev": true - }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true + "version": "22.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", + "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } }, "node_modules/@types/vscode": { - "version": "1.83.3", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.83.3.tgz", - "integrity": "sha512-ZPp5+OQNYrCSFoT4jWOZKdcuXijj+JdN2BJNDhWH4pPbVL6PRQycG9NT8C4a94oul1tFMbkVbXXa9HasI7cLUg==", - "dev": true + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.93.0.tgz", + "integrity": "sha512-kUK6jAHSR5zY8ps42xuW89NLcBpw1kOabah7yv38J8MyiYuOHxLQBi0e7zeXbQgVefDy/mZZetqEFC+Fl5eIEQ==", + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz", - "integrity": "sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.25.0.tgz", + "integrity": "sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.5.0", - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/type-utils": "6.0.0", - "@typescript-eslint/utils": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.25.0", + "@typescript-eslint/type-utils": "8.25.0", + "@typescript-eslint/utils": "8.25.0", + "@typescript-eslint/visitor-keys": "8.25.0", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.5.0", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^2.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.0.0.tgz", - "integrity": "sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.25.0.tgz", + "integrity": "sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/typescript-estree": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", + "@typescript-eslint/scope-manager": "8.25.0", + "@typescript-eslint/types": "8.25.0", + "@typescript-eslint/typescript-estree": "8.25.0", + "@typescript-eslint/visitor-keys": "8.25.0", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz", - "integrity": "sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.25.0.tgz", + "integrity": "sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0" + "@typescript-eslint/types": "8.25.0", + "@typescript-eslint/visitor-keys": "8.25.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1041,39 +1096,37 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz", - "integrity": "sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.25.0.tgz", + "integrity": "sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "6.0.0", - "@typescript-eslint/utils": "6.0.0", + "@typescript-eslint/typescript-estree": "8.25.0", + "@typescript-eslint/utils": "8.25.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^2.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.0.0.tgz", - "integrity": "sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.25.0.tgz", + "integrity": "sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw==", "dev": true, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1081,69 +1134,68 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz", - "integrity": "sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.25.0.tgz", + "integrity": "sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", + "@typescript-eslint/types": "8.25.0", + "@typescript-eslint/visitor-keys": "8.25.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "semver": "^7.5.0", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.0.0.tgz", - "integrity": "sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.3.0", - "@types/json-schema": "^7.0.11", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/typescript-estree": "6.0.0", - "eslint-scope": "^5.1.1", - "semver": "^7.5.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.25.0.tgz", + "integrity": "sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.25.0", + "@typescript-eslint/types": "8.25.0", + "@typescript-eslint/typescript-estree": "8.25.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz", - "integrity": "sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.25.0.tgz", + "integrity": "sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.0.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.25.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1151,24 +1203,26 @@ } }, "node_modules/@vscode/test-electron": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.8.tgz", - "integrity": "sha512-b4aZZsBKtMGdDljAsOPObnAi7+VWIaYl3ylCz1jTs+oV6BZ4TNHcVNC3xUn0azPeszBmwSBDQYfFESIaUQnrOg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.4.1.tgz", + "integrity": "sha512-Gc6EdaLANdktQ1t+zozoBVRynfIsMKMc94Svu1QreOBC8y76x4tvaK32TljrLi1LI2+PK58sDVbL7ALdqf3VRQ==", "dev": true, + "license": "MIT", "dependencies": { - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "jszip": "^3.10.1", - "semver": "^7.5.2" + "ora": "^7.0.1", + "semver": "^7.6.2" }, "engines": { "node": ">=16" } }, "node_modules/@vscode/vsce": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.1.1.tgz", - "integrity": "sha512-N62Ca9ElRPLUUzf7l9CeEBlLrYzFPRQq7huKk4pVW+LjIOSXfFIPudixn5QvZcz+yXDOh15IopI3K2o3y9666Q==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.2.2.tgz", + "integrity": "sha512-4TqdUq/yKlQTHcQMk/DamR632bq/+IJDomSbexOMee/UAYWqYm0XHWA6scGslsCpzY+sCWEhhl0nqdOB0XW1kw==", "dev": true, "license": "MIT", "dependencies": { @@ -1178,7 +1232,7 @@ "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.9", "cockatiel": "^3.1.2", - "commander": "^6.2.1", + "commander": "^12.1.0", "form-data": "^4.0.0", "glob": "^11.0.0", "hosted-git-info": "^4.0.2", @@ -1208,9 +1262,9 @@ } }, "node_modules/@vscode/vsce-sign": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.4.tgz", - "integrity": "sha512-0uL32egStKYfy60IqnynAChMTbL0oqpqk0Ew0YHiIb+fayuGZWADuIPHWUcY1GCnAA+VgchOPDMxnc2R3XGWEA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.5.tgz", + "integrity": "sha512-GfYWrsT/vypTMDMgWDm75iDmAOMe7F71sZECJ+Ws6/xyIfmB3ELVnVN+LwMFAvmXY+e6eWhR2EzNGF/zAhWY3Q==", "dev": true, "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE.txt", @@ -1352,141 +1406,36 @@ "win32" ] }, - "node_modules/@vscode/vsce/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@vscode/vsce/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@vscode/vsce/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@vscode/vsce/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@vscode/vsce/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@vscode/vsce/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@vscode/vsce/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@vscode/vsce/node_modules/glob": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", - "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "node_modules/@vscode/vsce/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vscode/vsce/node_modules/glob/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vscode/vsce/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@vscode/vsce/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "node": "*" } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1499,20 +1448,19 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "dev": true, - "dependencies": { - "debug": "4" - }, + "license": "MIT", "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -1520,6 +1468,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1532,46 +1481,43 @@ } }, "node_modules/anser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/anser/-/anser-2.1.1.tgz", - "integrity": "sha512-nqLm4HxOTpeLOxcmB3QWmV5TcDFhW9y/fyQ+hivtDFcK4OQ+pQ5fzPnXHM1Mfcm0VkLtvVi1TCPr++Qy0Q/3EQ==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/anser/-/anser-2.3.2.tgz", + "integrity": "sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==", + "license": "MIT" }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=4" } }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "Python-2.0" }, "node_modules/asynckit": { "version": "0.4.0", @@ -1594,7 +1540,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", @@ -1615,26 +1562,26 @@ "url": "https://feross.org/support" } ], - "optional": true + "license": "MIT" }, "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", "dev": true, - "optional": true, + "license": "MIT", "dependencies": { - "buffer": "^5.5.0", + "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "optional": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -1648,16 +1595,16 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -1665,6 +1612,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1673,9 +1621,9 @@ } }, "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, "funding": [ { @@ -1691,10 +1639,10 @@ "url": "https://feross.org/support" } ], - "optional": true, + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ieee754": "^1.2.1" } }, "node_modules/buffer-crc32": { @@ -1702,6 +1650,7 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -1713,18 +1662,45 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -1738,42 +1714,47 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=4" } }, "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", "dev": true, + "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">=18.17" }, "funding": { "url": "https://github.com/cheeriojs/cheerio?sponsor=1" @@ -1784,6 +1765,7 @@ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", @@ -1801,18 +1783,50 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true, + "license": "ISC", "optional": true }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -1822,6 +1836,97 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/cockatiel": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.2.1.tgz", @@ -1833,20 +1938,21 @@ } }, "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "color-name": "1.1.3" } }, "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -1862,30 +1968,35 @@ } }, "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=18" } }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1900,6 +2011,7 @@ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -1916,6 +2028,7 @@ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -1924,9 +2037,10 @@ } }, "node_modules/d3": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", - "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", "dependencies": { "d3-array": "3", "d3-axis": "3", @@ -1964,9 +2078,10 @@ } }, "node_modules/d3-array": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.2.tgz", - "integrity": "sha512-yEEyEAbDrF8C6Ob2myOBLjwBLck1Z89jMGFee0oPsn95GqjerpaOA4ch+vc2l0FNFFwMD5N7OCSEN5eAlsUbgQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", "dependencies": { "internmap": "1 - 2" }, @@ -1978,6 +2093,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -1986,6 +2102,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -2001,6 +2118,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", "dependencies": { "d3-path": "1 - 3" }, @@ -2012,6 +2130,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2020,6 +2139,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", "dependencies": { "d3-array": "^3.2.0" }, @@ -2028,9 +2148,10 @@ } }, "node_modules/d3-delaunay": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.2.tgz", - "integrity": "sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", "dependencies": { "delaunator": "5" }, @@ -2042,6 +2163,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2050,6 +2172,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" @@ -2062,6 +2185,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", "dependencies": { "commander": "7", "iconv-lite": "0.6", @@ -2082,10 +2206,20 @@ "node": ">=12" } }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", "engines": { "node": ">=12" } @@ -2094,6 +2228,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", "dependencies": { "d3-dsv": "1 - 3" }, @@ -2105,6 +2240,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", @@ -2118,14 +2254,16 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", "dependencies": { "d3-array": "2.5.0 - 3" }, @@ -2134,11 +2272,12 @@ } }, "node_modules/d3-graphviz": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-5.0.2.tgz", - "integrity": "sha512-EVRow9rnFgm/L1trbbnu2PGOND11IcSEdWXbrDbz9hH0/Kj3YM2AqMkkTN/EAWgawD5/zryyCy+3Vm05oSJ1Kg==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-5.6.0.tgz", + "integrity": "sha512-46OOyRv5Ioo9kZBc919FVIYPD/ObtdSZxOK1hv+qwmD7TunpPvvmsI1dSdxhVgH4GragJxFZ31+TQC5aOuXzzw==", + "license": "BSD-3-Clause", "dependencies": { - "@hpcc-js/wasm": "2.5.0", + "@hpcc-js/wasm": "^2.20.0", "d3-dispatch": "^3.0.1", "d3-format": "^3.1.0", "d3-interpolate": "^3.0.1", @@ -2154,38 +2293,11 @@ "d3-selection": "^3.0.0" } }, - "node_modules/d3-graphviz/node_modules/@hpcc-js/wasm": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.5.0.tgz", - "integrity": "sha512-G26BamgaHW46f6P8bmkygapgNcy+tTDMwIvCzmMzdp39sxUS1u4gaT/vR2SSDc4x3SfL5RE4B2B8ef/wd429Hg==", - "dependencies": { - "yargs": "17.6.2" - }, - "bin": { - "dot-wasm": "bin/dot-wasm.js" - } - }, - "node_modules/d3-graphviz/node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/d3-hierarchy": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2194,6 +2306,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3" }, @@ -2205,6 +2318,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2213,6 +2327,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2221,6 +2336,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2229,6 +2345,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2237,6 +2354,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", @@ -2249,9 +2367,10 @@ } }, "node_modules/d3-scale-chromatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", - "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" @@ -2264,6 +2383,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2272,6 +2392,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", "dependencies": { "d3-path": "^3.1.0" }, @@ -2283,6 +2404,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", "dependencies": { "d3-array": "2 - 3" }, @@ -2294,6 +2416,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", "dependencies": { "d3-time": "1 - 3" }, @@ -2305,6 +2428,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2313,6 +2437,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", @@ -2331,6 +2456,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -2343,12 +2469,13 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -2364,6 +2491,7 @@ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "mimic-response": "^3.1.0" @@ -2380,6 +2508,7 @@ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=4.0.0" @@ -2389,42 +2518,59 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/delaunator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", - "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", "dependencies": { - "robust-predicates": "^3.0.0" + "robust-predicates": "^3.0.2" } }, "node_modules/delayed-stream": { @@ -2438,44 +2584,22 @@ } }, "node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "dev": true, + "license": "Apache-2.0", "optional": true, "engines": { "node": ">=8" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -2495,13 +2619,15 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ] + ], + "license": "BSD-2-Clause" }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -2513,19 +2639,35 @@ } }, "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" + "domhandler": "^5.0.3" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2544,25 +2686,43 @@ } }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "once": "^1.4.0" } }, "node_modules/entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -2571,14 +2731,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -2593,6 +2750,35 @@ "node": ">= 0.4" } }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", @@ -2635,18 +2821,219 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz", + "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.21.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.2.tgz", + "integrity": "sha512-1105/17ZIMjmCOJOPNfVdbXafLCLj3hPmkmB7dLgt7XsQ/zkxSuDerE/xgO3RxoHysR1N1whmquY0lSn2O0VLg==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "build/bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-define-config": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-define-config/-/eslint-define-config-2.1.0.tgz", + "integrity": "sha512-QUp6pM9pjKEVannNAbSJNeRuYwW3LshejfyBBpjeMGaJjaDUpVps4C6KVR8R7dWZnD3i0synmrE36znjTkJvdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/Shinigami92" + }, + { + "type": "paypal", + "url": "https://www.paypal.com/donate/?hosted_button_id=L7GY729FBKTZY" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.0.0", + "npm": ">=9.0.0", + "pnpm": ">=8.6.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2654,146 +3041,66 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", - "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "*" } }, - "node_modules/eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { + "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "has-flag": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" + "node": ">=8" } }, "node_modules/espree": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", - "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2801,20 +3108,12 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2822,20 +3121,12 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2845,6 +3136,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2864,6 +3156,7 @@ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "dev": true, + "license": "(MIT OR WTFPL)", "optional": true, "engines": { "node": ">=6" @@ -2873,19 +3166,21 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -2896,6 +3191,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2907,19 +3203,22 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", + "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -2929,20 +3228,22 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, + "license": "MIT", "dependencies": { "pend": "~1.2.0" } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { @@ -2950,6 +3251,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2962,6 +3264,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -2974,28 +3277,30 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "dev": true, "funding": [ { @@ -3003,6 +3308,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -3030,14 +3336,15 @@ } }, "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" }, "engines": { @@ -3049,14 +3356,9 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "dev": true, + "license": "MIT", "optional": true }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3071,22 +3373,28 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -3095,28 +3403,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", + "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", "dev": true, + "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -3127,6 +3454,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -3134,92 +3462,39 @@ "node": ">=10.13.0" } }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, + "license": "ISC", "dependencies": { - "type-fest": "^0.20.2" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=8" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", "engines": { @@ -3229,12 +3504,45 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, "engines": { "node": ">= 0.4" }, @@ -3260,6 +3568,7 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -3268,9 +3577,9 @@ } }, "node_modules/htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", @@ -3279,44 +3588,47 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "entities": "^4.3.0" + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" } }, "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, + "license": "MIT", "dependencies": { - "agent-base": "6", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -3343,13 +3655,14 @@ "url": "https://feross.org/support" } ], - "optional": true + "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -3358,13 +3671,15 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3381,37 +3696,31 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true, + "license": "ISC", "optional": true }, "node_modules/internmap": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -3421,6 +3730,7 @@ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, + "license": "MIT", "dependencies": { "ci-info": "^2.0.0" }, @@ -3429,16 +3739,16 @@ } }, "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "dev": true, "license": "MIT", "bin": { "is-docker": "cli.js" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3449,6 +3759,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3457,6 +3768,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -3466,6 +3778,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -3473,53 +3786,95 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, "license": "MIT", "dependencies": { - "is-docker": "^2.0.0" + "is-inside-container": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/jackspeak": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", - "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", + "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -3532,11 +3887,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -3544,23 +3909,33 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" }, "node_modules/jsonwebtoken": { "version": "9.0.2", @@ -3613,6 +3988,7 @@ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", @@ -3649,17 +4025,29 @@ "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "dependencies": { "node-addon-api": "^4.3.0", "prebuild-install": "^7.0.1" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3669,6 +4057,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -3682,6 +4071,7 @@ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "dev": true, + "license": "MIT", "dependencies": { "immediate": "~3.0.5" } @@ -3701,6 +4091,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -3757,7 +4148,8 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", @@ -3766,10 +4158,42 @@ "dev": true, "license": "MIT" }, + "node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -3795,6 +4219,16 @@ "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -3807,6 +4241,7 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -3825,11 +4260,25 @@ "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -3860,11 +4309,22 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=10" @@ -3874,22 +4334,27 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "optional": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3910,44 +4375,44 @@ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-abi": { - "version": "3.31.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.31.0.tgz", - "integrity": "sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==", + "version": "3.74.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz", + "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "semver": "^7.3.5" @@ -3961,6 +4426,7 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/nth-check": { @@ -3968,6 +4434,7 @@ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" }, @@ -3976,9 +4443,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", "engines": { @@ -3993,251 +4460,180 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", + "optional": true, "dependencies": { "wrappy": "1" } }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "license": "MIT", "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">=12" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/ovsx": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.8.2.tgz", - "integrity": "sha512-btDXZorXlmwN9+9Un3khrVygCXmhwbrtg8gifNXw92rZPXcRBAiLG/L09Kb6srhGEratsFt42AktfD8t9XhzoA==", + "node_modules/ora": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz", + "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==", "dev": true, + "license": "MIT", "dependencies": { - "@vscode/vsce": "^2.19.0", - "commander": "^6.1.0", + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.3.0", + "log-symbols": "^5.1.0", + "stdin-discarder": "^0.1.0", + "string-width": "^6.1.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ora/node_modules/string-width": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", + "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^10.2.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ovsx": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.10.1.tgz", + "integrity": "sha512-8i7+MJMMeq73m1zPEIClSFe17SNuuzU5br7G77ZIfOC24elB4pGQs0N1qRd+gnnbyhL5Qu96G21nFOVOBa2OBg==", + "dev": true, + "license": "EPL-2.0", + "dependencies": { + "@vscode/vsce": "^3.2.1", + "commander": "^6.2.1", "follow-redirects": "^1.14.6", "is-ci": "^2.0.0", "leven": "^3.1.0", - "semver": "^7.5.2", - "tmp": "^0.2.1" + "semver": "^7.6.0", + "tmp": "^0.2.3", + "yauzl": "^3.1.3" }, "bin": { "ovsx": "lib/ovsx" }, "engines": { - "node": ">= 14" + "node": ">= 20" } }, - "node_modules/ovsx/node_modules/@vscode/vsce": { - "version": "2.32.0", - "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.32.0.tgz", - "integrity": "sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/identity": "^4.1.0", - "@vscode/vsce-sign": "^2.0.0", - "azure-devops-node-api": "^12.5.0", - "chalk": "^2.4.2", - "cheerio": "^1.0.0-rc.9", - "cockatiel": "^3.1.2", - "commander": "^6.2.1", - "form-data": "^4.0.0", - "glob": "^7.0.6", - "hosted-git-info": "^4.0.2", - "jsonc-parser": "^3.2.0", - "leven": "^3.1.0", - "markdown-it": "^12.3.2", - "mime": "^1.3.4", - "minimatch": "^3.0.3", - "parse-semver": "^1.1.1", - "read": "^1.0.7", - "semver": "^7.5.2", - "tmp": "^0.2.1", - "typed-rest-client": "^1.8.4", - "url-join": "^4.0.1", - "xml2js": "^0.5.0", - "yauzl": "^2.3.1", - "yazl": "^2.2.2" - }, - "bin": { - "vsce": "vsce" - }, - "engines": { - "node": ">= 16" - }, - "optionalDependencies": { - "keytar": "^7.7.0" - } - }, - "node_modules/ovsx/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ovsx/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ovsx/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ovsx/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, "node_modules/ovsx/node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, - "node_modules/ovsx/node_modules/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/ovsx/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ovsx/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ovsx/node_modules/linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "node_modules/ovsx/node_modules/yauzl": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", + "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", "dev": true, "license": "MIT", "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/ovsx/node_modules/markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/ovsx/node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/ovsx/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" + "buffer-crc32": "~0.2.3", + "pend": "~1.2.0" }, "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/ovsx/node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true, - "license": "MIT" - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -4253,6 +4649,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -4274,13 +4671,15 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "dev": true, + "license": "(MIT AND Zlib)" }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -4293,6 +4692,7 @@ "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^5.1.0" } @@ -4302,29 +4702,45 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dev": true, + "license": "MIT", "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" } }, "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", "dependencies": { - "domhandler": "^5.0.2", "parse5": "^7.0.0" }, "funding": { @@ -4336,24 +4752,17 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4376,47 +4785,41 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", - "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", "dev": true, "license": "ISC", "engines": { "node": "20 || >=22" } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "detect-libc": "^2.0.0", @@ -4424,7 +4827,7 @@ "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", + "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", @@ -4444,15 +4847,17 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", - "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz", + "integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -4467,13 +4872,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "end-of-stream": "^1.1.0", @@ -4481,10 +4888,11 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4500,13 +4908,13 @@ } }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -4533,13 +4941,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "optional": true, "dependencies": { "deep-extend": "^0.6.0", @@ -4556,6 +4966,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -4566,6 +4977,7 @@ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", "dev": true, + "license": "ISC", "dependencies": { "mute-stream": "~0.0.4" }, @@ -4578,6 +4990,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4588,10 +5001,18 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4601,40 +5022,65 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/rimraf": { + "node_modules/robust-predicates": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "license": "MIT", + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/robust-predicates": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz", - "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4654,6 +5100,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -4661,32 +5108,48 @@ "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "license": "ISC" }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4694,35 +5157,19 @@ "node": ">=10" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -4735,21 +5182,79 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -4790,6 +5295,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true }, "node_modules/simple-get": { @@ -4811,6 +5317,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true, "dependencies": { "decompress-response": "^6.0.0", @@ -4818,13 +5325,20 @@ "simple-concat": "^1.0.0" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/stdin-discarder": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", + "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^5.0.0" + }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/stoppable": { @@ -4843,21 +5357,34 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string-width-cjs": { @@ -4876,10 +5403,29 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4887,6 +5433,22 @@ "node": ">=8" } }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", @@ -4901,11 +5463,22 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4914,22 +5487,24 @@ } }, "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", + "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "chownr": "^1.1.1", @@ -4943,6 +5518,7 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "bl": "^4.0.3", @@ -4955,11 +5531,51 @@ "node": ">=6" } }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/tar-stream/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", "optional": true, "dependencies": { "inherits": "^2.0.3", @@ -4970,12 +5586,6 @@ "node": ">= 6" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, "node_modules/tmp": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", @@ -4991,6 +5601,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4999,21 +5610,22 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", "dev": true, + "license": "MIT", "engines": { - "node": ">=16.13.0" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD" }, @@ -5032,6 +5644,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "safe-buffer": "^5.0.1" @@ -5045,6 +5658,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -5052,18 +5666,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typed-rest-client": { "version": "1.8.11", "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", @@ -5077,9 +5679,9 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -5090,6 +5692,29 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.25.0.tgz", + "integrity": "sha512-TxRdQQLH4g7JkoFlYG3caW5v1S6kEkz8rqt80iQJZUYPq1zD1Ra7HfQBJJ88ABRaMvHAXnwRvRB4V+6sQ9xN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.25.0", + "@typescript-eslint/parser": "8.25.0", + "@typescript-eslint/utils": "8.25.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", @@ -5104,11 +5729,29 @@ "dev": true, "license": "MIT" }, + "node_modules/undici": { + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -5117,13 +5760,15 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/uuid": { "version": "8.3.2", @@ -5139,6 +5784,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -5147,6 +5793,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz", "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==", + "license": "MIT", "dependencies": { "minimatch": "^5.1.0", "semver": "^7.3.7", @@ -5156,18 +5803,11 @@ "vscode": "^1.82.0" } }, - "node_modules/vscode-languageclient/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/vscode-languageclient/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5179,6 +5819,7 @@ "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" @@ -5187,13 +5828,38 @@ "node_modules/vscode-languageserver-types": { "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5204,17 +5870,29 @@ "node": ">= 8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -5239,11 +5917,107 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC", + "optional": true }, "node_modules/xml2js": { "version": "0.5.0", @@ -5264,6 +6038,7 @@ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4.0" } @@ -5272,6 +6047,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", "engines": { "node": ">=10" } @@ -5279,12 +6055,15 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -5302,15 +6081,58 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { "node": ">=12" } }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -5321,6 +6143,7 @@ "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3" } @@ -5330,6 +6153,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index a7c8506a45e6..587ae92520b4 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -7,6 +7,7 @@ "version": "0.5.0-dev", "releaseTag": null, "publisher": "rust-lang", + "type": "commonjs", "repository": { "url": "https://github.com/rust-lang/rust-analyzer.git", "type": "git" @@ -27,45 +28,51 @@ } }, "engines": { - "vscode": "^1.83.0" + "vscode": "^1.93.0" }, "enabledApiProposals": [], "scripts": { "vscode:prepublish": "npm run build-base -- --minify", "package": "vsce package -o rust-analyzer.vsix", - "build-base": "esbuild ./src/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node --target=node16", + "build-base": "esbuild ./src/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node --target=node20", "build": "npm run build-base -- --sourcemap", "watch": "npm run build-base -- --sourcemap --watch", - "format": "prettier --write .", - "format:check": "prettier --check .", - "lint": "eslint -c .eslintrc.js --ext ts ./src ./tests", + "format": "node --experimental-strip-types node_modules/prettier/bin/prettier.cjs . --write", + "format:check": "node --experimental-strip-types node_modules/prettier/bin/prettier.cjs . --check", + "lint": "eslint .", "lint:fix": "npm run lint -- --fix", "typecheck": "tsc", "pretest": "npm run typecheck && npm run build", "test": "node ./out/tests/runTests.js" }, "dependencies": { - "@hpcc-js/wasm": "^2.13.0", - "anser": "^2.1.1", - "d3": "^7.8.5", - "d3-graphviz": "^5.0.2", + "@hpcc-js/wasm": "^2.22.4", + "anser": "^2.3.2", + "d3": "^7.9.0", + "d3-graphviz": "^5.6.0", + "jiti": "^2.4.2", "vscode-languageclient": "^9.0.1" }, "devDependencies": { - "@tsconfig/strictest": "^2.0.1", - "@types/node": "~16.11.7", - "@types/vscode": "~1.83", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", - "@vscode/test-electron": "^2.3.8", - "@vscode/vsce": "^3.0.0", + "@eslint/js": "^9.21.0", + "@stylistic/eslint-plugin": "^4.1.0", + "@stylistic/eslint-plugin-js": "^4.1.0", + "@tsconfig/strictest": "^2.0.5", + "@types/node": "~22.13.4", + "@types/vscode": "~1.93.0", + "@typescript-eslint/eslint-plugin": "^8.25.0", + "@typescript-eslint/parser": "^8.25.0", + "@vscode/test-electron": "^2.4.1", + "@vscode/vsce": "^3.2.2", "esbuild": "^0.25.0", - "eslint": "^8.44.0", - "eslint-config-prettier": "^8.8.0", - "ovsx": "^0.8.2", - "prettier": "^3.0.0", - "tslib": "^2.6.0", - "typescript": "^5.6.0" + "eslint": "^9.21.0", + "eslint-config-prettier": "^10.0.2", + "eslint-define-config": "^2.1.0", + "ovsx": "0.10.1", + "prettier": "^3.5.2", + "tslib": "^2.8.1", + "typescript": "^5.7.3", + "typescript-eslint": "^8.25.0" }, "activationEvents": [ "workspaceContains:Cargo.toml", diff --git a/src/tools/rust-analyzer/editors/code/prettier.config.mts b/src/tools/rust-analyzer/editors/code/prettier.config.mts new file mode 100644 index 000000000000..45cb3874eeab --- /dev/null +++ b/src/tools/rust-analyzer/editors/code/prettier.config.mts @@ -0,0 +1,12 @@ +import { type Config } from "prettier"; + +const config: Config = { + // use 4 because it's Rustfmt's default + // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#%5C34%20%5C%20%5C(default%5C)%5C%3A + tabWidth: 4, + // use 100 because it's Rustfmt's default + // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#max_width + printWidth: 100, +}; + +export default config; diff --git a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts index 8fc9f09324a8..bccae73c9a78 100644 --- a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts +++ b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts @@ -177,9 +177,9 @@ async function hasToolchainFileWithRaDeclared(uri: vscode.Uri): Promise await vscode.workspace.fs.readFile(uri), ); return ( - toolchainFileContents.match(/components\s*=\s*\[.*\"rust-analyzer\".*\]/g)?.length === 1 + toolchainFileContents.match(/components\s*=\s*\[.*"rust-analyzer".*\]/g)?.length === 1 ); - } catch (e) { + } catch (_) { return false; } } diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts index eac7b849fdb9..cdeea7333a67 100644 --- a/src/tools/rust-analyzer/editors/code/src/client.ts +++ b/src/tools/rust-analyzer/editors/code/src/client.ts @@ -18,282 +18,263 @@ export async function createClient( config: Config, unlinkedFiles: vscode.Uri[], ): Promise { + const raMiddleware: lc.Middleware = { + workspace: { + // HACK: This is a workaround, when the client has been disposed, VSCode + // continues to emit events to the client and the default one for this event + // attempt to restart the client for no reason + async didChangeWatchedFile(event, next) { + if (client.isRunning()) { + await next(event); + } + }, + async configuration( + params: lc.ConfigurationParams, + token: vscode.CancellationToken, + next: lc.ConfigurationRequest.HandlerSignature, + ) { + const resp = await next(params, token); + if (resp && Array.isArray(resp)) { + return resp.map((val) => { + return prepareVSCodeConfig(val); + }); + } else { + return resp; + } + }, + }, + async handleDiagnostics( + uri: vscode.Uri, + diagnosticList: vscode.Diagnostic[], + next: lc.HandleDiagnosticsSignature, + ) { + const preview = config.previewRustcOutput; + const errorCode = config.useRustcErrorCode; + diagnosticList.forEach((diag, idx) => { + const value = + typeof diag.code === "string" || typeof diag.code === "number" + ? diag.code + : diag.code?.value; + if ( + // FIXME: We currently emit this diagnostic way too early, before we have + // loaded the project fully + // value === "unlinked-file" && + value === "temporary-disabled" && + !unlinkedFiles.includes(uri) && + (diag.message === "file not included in crate hierarchy" || + diag.message.startsWith("This file is not included in any crates")) + ) { + const config = vscode.workspace.getConfiguration("rust-analyzer"); + if (config.get("showUnlinkedFileNotification")) { + unlinkedFiles.push(uri); + const folder = vscode.workspace.getWorkspaceFolder(uri)?.uri.fsPath; + if (folder) { + const parentBackslash = uri.fsPath.lastIndexOf(pathSeparator + "src"); + const parent = uri.fsPath.substring(0, parentBackslash); + + if (parent.startsWith(folder)) { + const path = vscode.Uri.file(parent + pathSeparator + "Cargo.toml"); + void vscode.workspace.fs.stat(path).then(async () => { + const choice = await vscode.window.showInformationMessage( + `This rust file does not belong to a loaded cargo project. It looks like it might belong to the workspace at ${path.path}, do you want to add it to the linked Projects?`, + "Yes", + "No", + "Don't show this again", + ); + switch (choice) { + case undefined: + break; + case "No": + break; + case "Yes": { + const pathToInsert = + "." + + parent.substring(folder.length) + + pathSeparator + + "Cargo.toml"; + const value = config + // eslint-disable-next-line @typescript-eslint/no-explicit-any + .get("linkedProjects") + ?.concat(pathToInsert); + await config.update("linkedProjects", value, false); + break; + } + case "Don't show this again": + await config.update( + "showUnlinkedFileNotification", + false, + false, + ); + break; + } + }); + } + } + } + } + + // Abuse the fact that VSCode leaks the LSP diagnostics data field through the + // Diagnostic class, if they ever break this we are out of luck and have to go + // back to the worst diagnostics experience ever:) + + // We encode the rendered output of a rustc diagnostic in the rendered field of + // the data payload of the lsp diagnostic. If that field exists, overwrite the + // diagnostic code such that clicking it opens the diagnostic in a readonly + // text editor for easy inspection + const rendered = (diag as unknown as { data?: { rendered?: string } }).data + ?.rendered; + if (rendered) { + if (preview) { + const decolorized = anser.ansiToText(rendered); + const index = decolorized.match(/^(note|help):/m)?.index || rendered.length; + diag.message = decolorized + .substring(0, index) + .replace(/^ -->[^\n]+\n/m, ""); + } + diag.code = { + target: vscode.Uri.from({ + scheme: diagnostics.URI_SCHEME, + path: `/diagnostic message [${idx.toString()}]`, + fragment: uri.toString(), + query: idx.toString(), + }), + value: errorCode && value ? value : "Click for full compiler diagnostic", + }; + } + }); + return next(uri, diagnosticList); + }, + async provideHover( + document: vscode.TextDocument, + position: vscode.Position, + token: vscode.CancellationToken, + _next: lc.ProvideHoverSignature, + ) { + const editor = vscode.window.activeTextEditor; + const positionOrRange = editor?.selection?.contains(position) + ? client.code2ProtocolConverter.asRange(editor.selection) + : client.code2ProtocolConverter.asPosition(position); + const params = { + textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), + position: positionOrRange, + }; + return client.sendRequest(ra.hover, params, token).then( + (result) => { + if (!result) return null; + const hover = client.protocol2CodeConverter.asHover(result); + if (result.actions) { + hover.contents.push(renderHoverActions(result.actions)); + } + return hover; + }, + (error) => { + client.handleFailedRequest(lc.HoverRequest.type, token, error, null); + return Promise.resolve(null); + }, + ); + }, + // Using custom handling of CodeActions to support action groups and snippet edits. + // Note that this means we have to re-implement lazy edit resolving ourselves as well. + async provideCodeActions( + document: vscode.TextDocument, + range: vscode.Range, + context: vscode.CodeActionContext, + token: vscode.CancellationToken, + _next: lc.ProvideCodeActionsSignature, + ) { + const params: lc.CodeActionParams = { + textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), + range: client.code2ProtocolConverter.asRange(range), + context: await client.code2ProtocolConverter.asCodeActionContext(context, token), + }; + const callback = async ( + values: (lc.Command | lc.CodeAction)[] | null, + ): Promise<(vscode.Command | vscode.CodeAction)[] | undefined> => { + if (values === null) return undefined; + const result: (vscode.CodeAction | vscode.Command)[] = []; + const groups = new Map(); + for (const item of values) { + // In our case we expect to get code edits only from diagnostics + if (lc.CodeAction.is(item)) { + assert(!item.command, "We don't expect to receive commands in CodeActions"); + const action = await client.protocol2CodeConverter.asCodeAction( + item, + token, + ); + result.push(action); + continue; + } + assert( + isCodeActionWithoutEditsAndCommands(item), + "We don't expect edits or commands here", + ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind); + const action = new vscode.CodeAction(item.title, kind); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const group = (item as any).group; + action.command = { + command: "rust-analyzer.resolveCodeAction", + title: item.title, + arguments: [item], + }; + + // Set a dummy edit, so that VS Code doesn't try to resolve this. + action.edit = new WorkspaceEdit(); + + if (group) { + let entry = groups.get(group); + if (!entry) { + entry = { index: result.length, items: [] }; + groups.set(group, entry); + result.push(action); + } + entry.items.push(action); + } else { + result.push(action); + } + } + for (const [group, { index, items }] of groups) { + if (items.length === 1) { + const item = unwrapUndefinable(items[0]); + result[index] = item; + } else { + const action = new vscode.CodeAction(group); + const item = unwrapUndefinable(items[0]); + action.kind = item.kind; + action.command = { + command: "rust-analyzer.applyActionGroup", + title: "", + arguments: [ + items.map((item) => { + return { + label: item.title, + arguments: item.command!.arguments![0], + }; + }), + ], + }; + + // Set a dummy edit, so that VS Code doesn't try to resolve this. + action.edit = new WorkspaceEdit(); + + result[index] = action; + } + } + return result; + }; + return client + .sendRequest(lc.CodeActionRequest.type, params, token) + .then(callback, (_error) => undefined); + }, + }; const clientOptions: lc.LanguageClientOptions = { documentSelector: [{ scheme: "file", language: "rust" }], initializationOptions, diagnosticCollectionName: "rustc", traceOutputChannel, outputChannel, - middleware: { - workspace: { - // HACK: This is a workaround, when the client has been disposed, VSCode - // continues to emit events to the client and the default one for this event - // attempt to restart the client for no reason - async didChangeWatchedFile(event, next) { - if (client.isRunning()) { - await next(event); - } - }, - async configuration( - params: lc.ConfigurationParams, - token: vscode.CancellationToken, - next: lc.ConfigurationRequest.HandlerSignature, - ) { - const resp = await next(params, token); - if (resp && Array.isArray(resp)) { - return resp.map((val) => { - return prepareVSCodeConfig(val); - }); - } else { - return resp; - } - }, - }, - async handleDiagnostics( - uri: vscode.Uri, - diagnosticList: vscode.Diagnostic[], - next: lc.HandleDiagnosticsSignature, - ) { - const preview = config.previewRustcOutput; - const errorCode = config.useRustcErrorCode; - diagnosticList.forEach((diag, idx) => { - const value = - typeof diag.code === "string" || typeof diag.code === "number" - ? diag.code - : diag.code?.value; - if ( - // FIXME: We currently emit this diagnostic way too early, before we have - // loaded the project fully - // value === "unlinked-file" && - value === "temporary-disabled" && - !unlinkedFiles.includes(uri) && - (diag.message === "file not included in crate hierarchy" || - diag.message.startsWith("This file is not included in any crates")) - ) { - const config = vscode.workspace.getConfiguration("rust-analyzer"); - if (config.get("showUnlinkedFileNotification")) { - unlinkedFiles.push(uri); - const folder = vscode.workspace.getWorkspaceFolder(uri)?.uri.fsPath; - if (folder) { - const parentBackslash = uri.fsPath.lastIndexOf( - pathSeparator + "src", - ); - const parent = uri.fsPath.substring(0, parentBackslash); - - if (parent.startsWith(folder)) { - const path = vscode.Uri.file( - parent + pathSeparator + "Cargo.toml", - ); - void vscode.workspace.fs.stat(path).then(async () => { - const choice = await vscode.window.showInformationMessage( - `This rust file does not belong to a loaded cargo project. It looks like it might belong to the workspace at ${path.path}, do you want to add it to the linked Projects?`, - "Yes", - "No", - "Don't show this again", - ); - switch (choice) { - case undefined: - break; - case "No": - break; - case "Yes": - const pathToInsert = - "." + - parent.substring(folder.length) + - pathSeparator + - "Cargo.toml"; - await config.update( - "linkedProjects", - config - .get("linkedProjects") - ?.concat(pathToInsert), - false, - ); - break; - case "Don't show this again": - await config.update( - "showUnlinkedFileNotification", - false, - false, - ); - break; - } - }); - } - } - } - } - - // Abuse the fact that VSCode leaks the LSP diagnostics data field through the - // Diagnostic class, if they ever break this we are out of luck and have to go - // back to the worst diagnostics experience ever:) - - // We encode the rendered output of a rustc diagnostic in the rendered field of - // the data payload of the lsp diagnostic. If that field exists, overwrite the - // diagnostic code such that clicking it opens the diagnostic in a readonly - // text editor for easy inspection - const rendered = (diag as unknown as { data?: { rendered?: string } }).data - ?.rendered; - if (rendered) { - if (preview) { - const decolorized = anser.ansiToText(rendered); - const index = - decolorized.match(/^(note|help):/m)?.index || rendered.length; - diag.message = decolorized - .substring(0, index) - .replace(/^ -->[^\n]+\n/m, ""); - } - diag.code = { - target: vscode.Uri.from({ - scheme: diagnostics.URI_SCHEME, - path: `/diagnostic message [${idx.toString()}]`, - fragment: uri.toString(), - query: idx.toString(), - }), - value: - errorCode && value ? value : "Click for full compiler diagnostic", - }; - } - }); - return next(uri, diagnosticList); - }, - async provideHover( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken, - _next: lc.ProvideHoverSignature, - ) { - const editor = vscode.window.activeTextEditor; - const positionOrRange = editor?.selection?.contains(position) - ? client.code2ProtocolConverter.asRange(editor.selection) - : client.code2ProtocolConverter.asPosition(position); - return client - .sendRequest( - ra.hover, - { - textDocument: - client.code2ProtocolConverter.asTextDocumentIdentifier(document), - position: positionOrRange, - }, - token, - ) - .then( - (result) => { - if (!result) return null; - const hover = client.protocol2CodeConverter.asHover(result); - if (!!result.actions) { - hover.contents.push(renderHoverActions(result.actions)); - } - return hover; - }, - (error) => { - client.handleFailedRequest(lc.HoverRequest.type, token, error, null); - return Promise.resolve(null); - }, - ); - }, - // Using custom handling of CodeActions to support action groups and snippet edits. - // Note that this means we have to re-implement lazy edit resolving ourselves as well. - async provideCodeActions( - document: vscode.TextDocument, - range: vscode.Range, - context: vscode.CodeActionContext, - token: vscode.CancellationToken, - _next: lc.ProvideCodeActionsSignature, - ) { - const params: lc.CodeActionParams = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), - range: client.code2ProtocolConverter.asRange(range), - context: await client.code2ProtocolConverter.asCodeActionContext( - context, - token, - ), - }; - return client.sendRequest(lc.CodeActionRequest.type, params, token).then( - async (values) => { - if (values === null) return undefined; - const result: (vscode.CodeAction | vscode.Command)[] = []; - const groups = new Map< - string, - { index: number; items: vscode.CodeAction[] } - >(); - for (const item of values) { - // In our case we expect to get code edits only from diagnostics - if (lc.CodeAction.is(item)) { - assert( - !item.command, - "We don't expect to receive commands in CodeActions", - ); - const action = await client.protocol2CodeConverter.asCodeAction( - item, - token, - ); - result.push(action); - continue; - } - assert( - isCodeActionWithoutEditsAndCommands(item), - "We don't expect edits or commands here", - ); - const kind = client.protocol2CodeConverter.asCodeActionKind( - (item as any).kind, - ); - const action = new vscode.CodeAction(item.title, kind); - const group = (item as any).group; - action.command = { - command: "rust-analyzer.resolveCodeAction", - title: item.title, - arguments: [item], - }; - - // Set a dummy edit, so that VS Code doesn't try to resolve this. - action.edit = new WorkspaceEdit(); - - if (group) { - let entry = groups.get(group); - if (!entry) { - entry = { index: result.length, items: [] }; - groups.set(group, entry); - result.push(action); - } - entry.items.push(action); - } else { - result.push(action); - } - } - for (const [group, { index, items }] of groups) { - if (items.length === 1) { - const item = unwrapUndefinable(items[0]); - result[index] = item; - } else { - const action = new vscode.CodeAction(group); - const item = unwrapUndefinable(items[0]); - action.kind = item.kind; - action.command = { - command: "rust-analyzer.applyActionGroup", - title: "", - arguments: [ - items.map((item) => { - return { - label: item.title, - arguments: item.command!.arguments![0], - }; - }), - ], - }; - - // Set a dummy edit, so that VS Code doesn't try to resolve this. - action.edit = new WorkspaceEdit(); - - result[index] = action; - } - } - return result; - }, - (_error) => undefined, - ); - }, - }, + middleware: raMiddleware, markdown: { supportHtml: true, }, @@ -319,9 +300,11 @@ class ExperimentalFeatures implements lc.StaticFeature { constructor(config: Config) { this.testExplorer = config.testExplorer || false; } + getState(): lc.FeatureState { return { kind: "static" }; } + fillClientCapabilities(capabilities: lc.ClientCapabilities): void { capabilities.experimental = { snippetTextEdit: true, @@ -345,11 +328,14 @@ class ExperimentalFeatures implements lc.StaticFeature { ...capabilities.experimental, }; } + initialize( _capabilities: lc.ServerCapabilities, _documentSelector: lc.DocumentSelector | undefined, ): void {} + dispose(): void {} + clear(): void {} } @@ -357,6 +343,7 @@ class OverrideFeatures implements lc.StaticFeature { getState(): lc.FeatureState { return { kind: "static" }; } + fillClientCapabilities(capabilities: lc.ClientCapabilities): void { // Force disable `augmentsSyntaxTokens`, VSCode's textmate grammar is somewhat incomplete // making the experience generally worse @@ -365,14 +352,18 @@ class OverrideFeatures implements lc.StaticFeature { caps.augmentsSyntaxTokens = false; } } + initialize( _capabilities: lc.ServerCapabilities, _documentSelector: lc.DocumentSelector | undefined, ): void {} + dispose(): void {} + clear(): void {} } +// eslint-disable-next-line @typescript-eslint/no-explicit-any function isCodeActionWithoutEditsAndCommands(value: any): boolean { const candidate: lc.CodeAction = value; return ( diff --git a/src/tools/rust-analyzer/editors/code/src/commands.ts b/src/tools/rust-analyzer/editors/code/src/commands.ts index eee623ecae9a..4e614d320571 100644 --- a/src/tools/rust-analyzer/editors/code/src/commands.ts +++ b/src/tools/rust-analyzer/editors/code/src/commands.ts @@ -78,6 +78,7 @@ export function memoryUsage(ctx: CtxInit): Cmd { provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult { if (!vscode.window.activeTextEditor) return ""; + // eslint-disable-next-line @typescript-eslint/no-explicit-any return ctx.client.sendRequest(ra.memoryUsage).then((mem: any) => { return "Per-query memory usage:\n" + mem + "\n(note: database has been cleared)"; }); @@ -161,7 +162,7 @@ export function joinLines(ctx: CtxInit): Cmd { }); const textEdits = await client.protocol2CodeConverter.asTextEdits(items); await editor.edit((builder) => { - textEdits.forEach((edit: any) => { + textEdits.forEach((edit: vscode.TextEdit) => { builder.replace(edit.range, edit.newText); }); }); @@ -209,6 +210,7 @@ export function onEnter(ctx: CtxInit): Cmd { ), position: client.code2ProtocolConverter.asPosition(editor.selection.active), }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .catch((_error: any) => { // client.handleFailedRequest(OnEnterRequest.type, error, null); return null; @@ -528,6 +530,7 @@ function viewFileUsingTextDocumentContentProvider( void sleep(10).then(() => this.eventEmitter.fire(this.uri)); } } + private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) { if (editor && isRustEditor(editor) && shouldUpdate) { this.eventEmitter.fire(this.uri); @@ -620,6 +623,7 @@ export function viewFileText(ctx: CtxInit): Cmd { void sleep(10).then(() => this.eventEmitter.fire(this.uri)); } } + private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) { if (editor && isRustEditor(editor)) { this.eventEmitter.fire(this.uri); @@ -683,6 +687,7 @@ export function viewItemTree(ctx: CtxInit): Cmd { void sleep(10).then(() => this.eventEmitter.fire(this.uri)); } } + private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) { if (editor && isRustEditor(editor)) { this.eventEmitter.fire(this.uri); @@ -1001,9 +1006,8 @@ export function resolveCodeAction(ctx: CtxInit): Cmd { ...itemEdit, documentChanges: itemEdit.documentChanges?.filter((change) => "kind" in change), }; - const fileSystemEdit = await client.protocol2CodeConverter.asWorkspaceEdit( - lcFileSystemEdit, - ); + const fileSystemEdit = + await client.protocol2CodeConverter.asWorkspaceEdit(lcFileSystemEdit); await vscode.workspace.applyEdit(fileSystemEdit); // replace all text edits so that we can convert snippet text edits into `vscode.SnippetTextEdit`s diff --git a/src/tools/rust-analyzer/editors/code/src/config.ts b/src/tools/rust-analyzer/editors/code/src/config.ts index d1467a4e8241..2ae329134520 100644 --- a/src/tools/rust-analyzer/editors/code/src/config.ts +++ b/src/tools/rust-analyzer/editors/code/src/config.ts @@ -13,12 +13,7 @@ export type RunnableEnvCfgItem = { }; export type RunnableEnvCfg = Record | RunnableEnvCfgItem[]; -type ShowStatusBar = - | "always" - | "never" - | { - documentSelector: vscode.DocumentSelector; - }; +type ShowStatusBar = "always" | "never" | { documentSelector: vscode.DocumentSelector }; export class Config { readonly extensionId = "rust-lang.rust-analyzer"; @@ -145,13 +140,13 @@ export class Config { { // Parent doc single-line comment // e.g. //!| - beforeText: /^\s*\/{2}\!.*$/, + beforeText: /^\s*\/{2}!.*$/, action: { indentAction, appendText: "//! " }, }, { // Begins an auto-closed multi-line comment (standard or parent doc) // e.g. /** | */ or /*! | */ - beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/, + beforeText: /^\s*\/\*(\*|!)(?!\/)([^*]|\*(?!\/))*$/, afterText: /^\s*\*\/$/, action: { indentAction: vscode.IndentAction.IndentOutdent, @@ -161,19 +156,19 @@ export class Config { { // Begins a multi-line comment (standard or parent doc) // e.g. /** ...| or /*! ...| - beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/, + beforeText: /^\s*\/\*(\*|!)(?!\/)([^*]|\*(?!\/))*$/, action: { indentAction, appendText: " * " }, }, { // Continues a multi-line comment // e.g. * ...| - beforeText: /^(\ \ )*\ \*(\ ([^\*]|\*(?!\/))*)?$/, + beforeText: /^( {2})* \*( ([^*]|\*(?!\/))*)?$/, action: { indentAction, appendText: "* " }, }, { // Dedents after closing a multi-line comment // e.g. */| - beforeText: /^(\ \ )*\ \*\/\s*$/, + beforeText: /^( {2})* \*\/\s*$/, action: { indentAction, removeText: 1 }, }, ]; @@ -227,9 +222,11 @@ export class Config { ), ); } + get checkOnSave() { return this.get("checkOnSave") ?? false; } + async toggleCheckOnSave() { const config = this.cfg.inspect("checkOnSave") ?? { key: "checkOnSave" }; let overrideInLanguage; @@ -269,8 +266,10 @@ export class Config { } runnablesExtraEnv(label: string): Record | undefined { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const item = this.get("runnables.extraEnv") ?? this.get("runnableEnv"); if (!item) return undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any const fixRecord = (r: Record) => { for (const key in r) { if (typeof r[key] !== "string") { @@ -339,6 +338,7 @@ export class Config { gotoTypeDef: this.get("hover.actions.gotoTypeDef.enable"), }; } + get previewRustcOutput() { return this.get("diagnostics.previewRustcOutput"); } @@ -370,6 +370,7 @@ export class Config { get askBeforeUpdateTest() { return this.get("runnables.askBeforeUpdateTest"); } + async setAskBeforeUpdateTest(value: boolean) { await this.cfg.update("runnables.askBeforeUpdateTest", value, true); } @@ -378,11 +379,13 @@ export class Config { export function prepareVSCodeConfig(resp: T): T { if (Is.string(resp)) { return substituteVSCodeVariableInString(resp) as T; + // eslint-disable-next-line @typescript-eslint/no-explicit-any } else if (resp && Is.array(resp)) { return resp.map((val) => { return prepareVSCodeConfig(val); }) as T; } else if (resp && typeof resp === "object") { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const res: { [key: string]: any } = {}; for (const key in resp) { const val = resp[key]; @@ -489,8 +492,7 @@ function computeVscodeVar(varName: string): string | null { // TODO: support for remote workspaces? const fsPath: string = folder === undefined - ? // no workspace opened - "" + ? "" // no workspace opened : // could use currently opened document to detect the correct // workspace. However, that would be determined by the document // user has opened on Editor startup. Could lead to diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts index 4248305d5cc1..ac73f2ae6bf1 100644 --- a/src/tools/rust-analyzer/editors/code/src/ctx.ts +++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts @@ -34,13 +34,8 @@ import type { RustAnalyzerExtensionApi } from "./main"; export type Workspace = | { kind: "Empty" } - | { - kind: "Workspace Folder"; - } - | { - kind: "Detached Files"; - files: vscode.TextDocument[]; - }; + | { kind: "Workspace Folder" } + | { kind: "Detached Files"; files: vscode.TextDocument[] }; export function fetchWorkspace(): Workspace { const folders = (vscode.workspace.workspaceFolders || []).filter( @@ -53,10 +48,7 @@ export function fetchWorkspace(): Workspace { return folders.length === 0 ? rustDocuments.length === 0 ? { kind: "Empty" } - : { - kind: "Detached Files", - files: rustDocuments, - } + : { kind: "Detached Files", files: rustDocuments } : { kind: "Workspace Folder" }; } @@ -89,6 +81,7 @@ export class Ctx implements RustAnalyzerExtensionApi { private _dependencyTreeView: | vscode.TreeView | undefined; + private _syntaxTreeProvider: SyntaxTreeProvider | undefined; private _syntaxTreeView: vscode.TreeView | undefined; private lastStatus: ServerStatusParams | { health: "stopped" } = { health: "stopped" }; @@ -267,7 +260,7 @@ export class Ctx implements RustAnalyzerExtensionApi { let message = "bootstrap error. "; message += - 'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). '; + 'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically).'; message += 'To enable verbose logs, click the gear icon in the "OUTPUT" tab and select "Debug".'; @@ -476,9 +469,11 @@ export class Ctx implements RustAnalyzerExtensionApi { this.lastStatus = status; this.updateStatusBarItem(); } + refreshServerStatus() { this.updateStatusBarItem(); } + private updateStatusBarItem() { let icon = ""; const status = this.lastStatus; @@ -533,19 +528,14 @@ export class Ctx implements RustAnalyzerExtensionApi { const toggleCheckOnSave = this.config.checkOnSave ? "Disable" : "Enable"; statusBar.tooltip.appendMarkdown( - `[Extension Info](command:rust-analyzer.serverVersion "Show version and server binary info"): Version ${this.version}, Server Version ${this._serverVersion}` + - "\n\n---\n\n" + - '[$(terminal) Open Logs](command:rust-analyzer.openLogs "Open the server logs")' + - "\n\n" + - `[$(settings) ${toggleCheckOnSave} Check on Save](command:rust-analyzer.toggleCheckOnSave "Temporarily ${toggleCheckOnSave.toLowerCase()} check on save functionality")` + - "\n\n" + - '[$(refresh) Reload Workspace](command:rust-analyzer.reloadWorkspace "Reload and rediscover workspaces")' + - "\n\n" + - '[$(symbol-property) Rebuild Build Dependencies](command:rust-analyzer.rebuildProcMacros "Rebuild build scripts and proc-macros")' + - "\n\n" + - '[$(stop-circle) Stop server](command:rust-analyzer.stopServer "Stop the server")' + - "\n\n" + - '[$(debug-restart) Restart server](command:rust-analyzer.restartServer "Restart the server")', + `[Extension Info](command:rust-analyzer.serverVersion "Show version and server binary info"): Version ${this.version}, Server Version ${this._serverVersion}\n\n` + + `---\n\n` + + `[$(terminal) Open Logs](command:rust-analyzer.openLogs "Open the server logs")\n\n` + + `[$(settings) ${toggleCheckOnSave} Check on Save](command:rust-analyzer.toggleCheckOnSave "Temporarily ${toggleCheckOnSave.toLowerCase()} check on save functionality")\n\n` + + `[$(refresh) Reload Workspace](command:rust-analyzer.reloadWorkspace "Reload and rediscover workspaces")\n\n` + + `[$(symbol-property) Rebuild Build Dependencies](command:rust-analyzer.rebuildProcMacros "Rebuild build scripts and proc-macros")\n\n` + + `[$(stop-circle) Stop server](command:rust-analyzer.stopServer "Stop the server")\n\n` + + `[$(debug-restart) Restart server](command:rust-analyzer.restartServer "Restart the server")`, ); if (!status.quiescent) icon = "$(loading~spin) "; statusBar.text = `${icon}rust-analyzer`; @@ -580,4 +570,5 @@ export interface Disposable { dispose(): void; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type Cmd = (...args: any[]) => unknown; diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts index f21ca2e8f96f..72a9aabc0434 100644 --- a/src/tools/rust-analyzer/editors/code/src/debug.ts +++ b/src/tools/rust-analyzer/editors/code/src/debug.ts @@ -22,6 +22,7 @@ export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise< if (!debugConfig) return; const wsLaunchSection = vscode.workspace.getConfiguration("launch", scope); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const configurations = wsLaunchSection.get("configurations") || []; const index = configurations.findIndex((c) => c.name === debugConfig.name); @@ -46,6 +47,7 @@ export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promis let message = ""; const wsLaunchSection = vscode.workspace.getConfiguration("launch"); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const configurations = wsLaunchSection.get("configurations") || []; // The runnable label is the name of the test with the "test prefix" @@ -121,7 +123,7 @@ async function getDebugConfiguration( debugOutput.show(true); } // folder exists or RA is not active. - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const workspaceFolders = vscode.workspace.workspaceFolders!; const isMultiFolderWorkspace = workspaceFolders.length > 1; const firstWorkspace = workspaceFolders[0]; @@ -189,8 +191,9 @@ async function getDebugConfiguration( sourceFileMap, ); if (debugConfig.type in debugOptions.engineSettings) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type]; - for (var key in settingsMap) { + for (const key in settingsMap) { debugConfig[key] = settingsMap[key]; } } @@ -409,7 +412,7 @@ function quote(xs: string[]) { return "'" + s.replace(/(['\\])/g, "\\$1") + "'"; } if (/["'\s]/.test(s)) { - return '"' + s.replace(/(["\\$`!])/g, "\\$1") + '"'; + return `"${s.replace(/(["\\$`!])/g, "\\$1")}"`; } return s.replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g, "$1\\$2"); }) diff --git a/src/tools/rust-analyzer/editors/code/src/diagnostics.ts b/src/tools/rust-analyzer/editors/code/src/diagnostics.ts index 9fb2993d12f7..73621dda9ccb 100644 --- a/src/tools/rust-analyzer/editors/code/src/diagnostics.ts +++ b/src/tools/rust-analyzer/editors/code/src/diagnostics.ts @@ -104,10 +104,7 @@ export class AnsiDecorationProvider implements vscode.Disposable { for (const [lineNumber, line] of lines.entries()) { const totalEscapeLength = 0; - - // eslint-disable-next-line camelcase const parsed = anser.ansiToJson(line, { use_classes: true }); - let offset = 0; for (const span of parsed) { @@ -162,23 +159,23 @@ export class AnsiDecorationProvider implements vscode.Disposable { // NOTE: This could just be a kebab-case to camelCase conversion, but I think it's // a short enough list to just write these by hand static readonly _anserToThemeColor: Record = { - "ansi-black": "ansiBlack", - "ansi-white": "ansiWhite", - "ansi-red": "ansiRed", - "ansi-green": "ansiGreen", - "ansi-yellow": "ansiYellow", - "ansi-blue": "ansiBlue", - "ansi-magenta": "ansiMagenta", - "ansi-cyan": "ansiCyan", + "ansi-black": new ThemeColor("terminal.ansiBlack"), + "ansi-white": new ThemeColor("terminal.ansiWhite"), + "ansi-red": new ThemeColor("terminal.ansiRed"), + "ansi-green": new ThemeColor("terminal.ansiGreen"), + "ansi-yellow": new ThemeColor("terminal.ansiYellow"), + "ansi-blue": new ThemeColor("terminal.ansiBlue"), + "ansi-magenta": new ThemeColor("terminal.ansiMagenta"), + "ansi-cyan": new ThemeColor("terminal.ansiCyan"), - "ansi-bright-black": "ansiBrightBlack", - "ansi-bright-white": "ansiBrightWhite", - "ansi-bright-red": "ansiBrightRed", - "ansi-bright-green": "ansiBrightGreen", - "ansi-bright-yellow": "ansiBrightYellow", - "ansi-bright-blue": "ansiBrightBlue", - "ansi-bright-magenta": "ansiBrightMagenta", - "ansi-bright-cyan": "ansiBrightCyan", + "ansi-bright-black": new ThemeColor("terminal.ansiBrightBlack"), + "ansi-bright-white": new ThemeColor("terminal.ansiBrightWhite"), + "ansi-bright-red": new ThemeColor("terminal.ansiBrightRed"), + "ansi-bright-green": new ThemeColor("terminal.ansiBrightGreen"), + "ansi-bright-yellow": new ThemeColor("terminal.ansiBrightYellow"), + "ansi-bright-blue": new ThemeColor("terminal.ansiBrightBlue"), + "ansi-bright-magenta": new ThemeColor("terminal.ansiBrightMagenta"), + "ansi-bright-cyan": new ThemeColor("terminal.ansiBrightCyan"), }; private static _convertColor( diff --git a/src/tools/rust-analyzer/editors/code/src/lang_client.ts b/src/tools/rust-analyzer/editors/code/src/lang_client.ts index 09d64efc048a..dc448f554c5e 100644 --- a/src/tools/rust-analyzer/editors/code/src/lang_client.ts +++ b/src/tools/rust-analyzer/editors/code/src/lang_client.ts @@ -5,6 +5,8 @@ export class RaLanguageClient extends lc.LanguageClient { override handleFailedRequest( type: lc.MessageSignature, token: vscode.CancellationToken | undefined, + // declared as `any` in vscode-languageclient + // eslint-disable-next-line @typescript-eslint/no-explicit-any error: any, defaultValue: T, showNotification?: boolean | undefined, diff --git a/src/tools/rust-analyzer/editors/code/src/lsp_ext.ts b/src/tools/rust-analyzer/editors/code/src/lsp_ext.ts index af86d9efd142..af5129ac9635 100644 --- a/src/tools/rust-analyzer/editors/code/src/lsp_ext.ts +++ b/src/tools/rust-analyzer/editors/code/src/lsp_ext.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ /** * This file mirrors `crates/rust-analyzer/src/lsp_ext.rs` declarations. */ diff --git a/src/tools/rust-analyzer/editors/code/src/main.ts b/src/tools/rust-analyzer/editors/code/src/main.ts index c84b69b66cd2..451294e26f6c 100644 --- a/src/tools/rust-analyzer/editors/code/src/main.ts +++ b/src/tools/rust-analyzer/editors/code/src/main.ts @@ -214,6 +214,7 @@ function checkConflictingExtensions() { "both plugins to not work correctly. You should disable one of them.", "Got it", ) + // eslint-disable-next-line no-console .then(() => {}, console.error); } } diff --git a/src/tools/rust-analyzer/editors/code/src/persistent_state.ts b/src/tools/rust-analyzer/editors/code/src/persistent_state.ts index cebd16a3c90a..3f90cd3bb935 100644 --- a/src/tools/rust-analyzer/editors/code/src/persistent_state.ts +++ b/src/tools/rust-analyzer/editors/code/src/persistent_state.ts @@ -14,6 +14,7 @@ export class PersistentState { get serverVersion(): string | undefined { return this.globalState.get("serverVersion"); } + async updateServerVersion(value: string | undefined) { await this.globalState.update("serverVersion", value); } diff --git a/src/tools/rust-analyzer/editors/code/src/snippets.ts b/src/tools/rust-analyzer/editors/code/src/snippets.ts index a469a9cd1f45..e3f43a80670a 100644 --- a/src/tools/rust-analyzer/editors/code/src/snippets.ts +++ b/src/tools/rust-analyzer/editors/code/src/snippets.ts @@ -24,9 +24,7 @@ export async function applySnippetWorkspaceEdit( for (const indel of edits) { assert( !(indel instanceof vscode.SnippetTextEdit), - `bad ws edit: snippet received with multiple edits: ${JSON.stringify( - edit, - )}`, + `bad ws edit: snippet received with multiple edits: ${JSON.stringify(edit)}`, ); builder.replace(indel.range, indel.newText); } diff --git a/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts b/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts index 3f7e30f13a3b..b86f8cbc707b 100644 --- a/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts +++ b/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts @@ -7,8 +7,10 @@ import * as ra from "./lsp_ext"; export class SyntaxTreeProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; + ctx: CtxInit; root: SyntaxNode | undefined; hideWhitespace: boolean = false; diff --git a/src/tools/rust-analyzer/editors/code/src/test_explorer.ts b/src/tools/rust-analyzer/editors/code/src/test_explorer.ts index de41d2a57eca..e45f8282942f 100644 --- a/src/tools/rust-analyzer/editors/code/src/test_explorer.ts +++ b/src/tools/rust-analyzer/editors/code/src/test_explorer.ts @@ -133,7 +133,7 @@ export const prepareTestExplorer = ( } if (scope) { const recursivelyRemove = (tests: vscode.TestItemCollection) => { - for (const [_, test] of tests) { + for (const [, test] of tests) { if (!testSet.has(test.id)) { deleteTest(test, tests); } else { diff --git a/src/tools/rust-analyzer/editors/code/src/toolchain.ts b/src/tools/rust-analyzer/editors/code/src/toolchain.ts index e8bab9c3d847..bb0614429531 100644 --- a/src/tools/rust-analyzer/editors/code/src/toolchain.ts +++ b/src/tools/rust-analyzer/editors/code/src/toolchain.ts @@ -18,6 +18,22 @@ export interface ArtifactSpec { filter?: (artifacts: CompilationArtifact[]) => CompilationArtifact[]; } +interface CompilerMessage { + reason: string; + executable?: string; + target: { + crate_types: [string, ...string[]]; + kind: [string, ...string[]]; + name: string; + }; + profile: { + test: boolean; + }; + message: { + rendered: string; + }; +} + export class Cargo { constructor( readonly rootFolder: string, @@ -109,7 +125,7 @@ export class Cargo { private async runCargo( cargoArgs: string[], - onStdoutJson: (obj: any) => void, + onStdoutJson: (obj: CompilerMessage) => void, onStderrString: (data: string) => void, env?: Record, ): Promise { @@ -131,7 +147,7 @@ export class Cargo { onStdoutJson(message); }); - cargo.on("exit", (exitCode, _) => { + cargo.on("exit", (exitCode) => { if (exitCode === 0) resolve(exitCode); else reject(new Error(`exit code: ${exitCode}.`)); }); diff --git a/src/tools/rust-analyzer/editors/code/src/util.ts b/src/tools/rust-analyzer/editors/code/src/util.ts index d7ca6b3557df..2f7702baebb6 100644 --- a/src/tools/rust-analyzer/editors/code/src/util.ts +++ b/src/tools/rust-analyzer/editors/code/src/util.ts @@ -104,6 +104,7 @@ export function isDocumentInWorkspace(document: RustDocument): boolean { } /** Sets ['when'](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts) clause contexts */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function setContextValue(key: string, value: any): Thenable { return vscode.commands.executeCommand("setContext", key, value); } @@ -167,27 +168,35 @@ export class LazyOutputChannel implements vscode.OutputChannel { append(value: string): void { this.channel.append(value); } + appendLine(value: string): void { this.channel.appendLine(value); } + replace(value: string): void { this.channel.replace(value); } + clear(): void { if (this._channel) { this._channel.clear(); } } - show(preserveFocus?: boolean): void; - show(column?: vscode.ViewColumn, preserveFocus?: boolean): void; - show(column?: any, preserveFocus?: any): void { - this.channel.show(column, preserveFocus); + + show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void { + if (typeof columnOrPreserveFocus === "boolean") { + this.channel.show(columnOrPreserveFocus); + } else { + this.channel.show(columnOrPreserveFocus, preserveFocus); + } } + hide(): void { if (this._channel) { this._channel.hide(); } } + dispose(): void { if (this._channel) { this._channel.dispose(); @@ -276,6 +285,7 @@ export async function spawnAsync( stderr: res.stderr, status: res.status, }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (e: any) { return { stdout: e.stdout, diff --git a/src/tools/rust-analyzer/editors/code/tests/unit/index.ts b/src/tools/rust-analyzer/editors/code/tests/unit/index.ts index 8ad46546abd8..bf74060c7301 100644 --- a/src/tools/rust-analyzer/editors/code/tests/unit/index.ts +++ b/src/tools/rust-analyzer/editors/code/tests/unit/index.ts @@ -1,6 +1,7 @@ import * as assert from "node:assert/strict"; import { readdir } from "fs/promises"; import * as path from "path"; +import { pathToFileURL } from "url"; class Test { readonly name: string; @@ -67,7 +68,7 @@ export async function run(): Promise { ); for (const testFile of testFiles) { try { - const testModule = require(path.resolve(__dirname, testFile)); + const testModule = await import(pathToFileURL(path.resolve(__dirname, testFile)).href); await testModule.getTests(context); } catch (e) { error(`${e}`); diff --git a/src/tools/rust-analyzer/editors/code/tests/unit/tasks.test.ts b/src/tools/rust-analyzer/editors/code/tests/unit/tasks.test.ts index 9bccaaf3d475..9b5d98ee7e92 100644 --- a/src/tools/rust-analyzer/editors/code/tests/unit/tasks.test.ts +++ b/src/tools/rust-analyzer/editors/code/tests/unit/tasks.test.ts @@ -114,6 +114,7 @@ function f(task: vscode.Task): { execution, }; } + function executionToSimple( taskExecution: vscode.ProcessExecution | vscode.ShellExecution | vscode.CustomExecution, ): { @@ -122,8 +123,8 @@ function executionToSimple( const exec = taskExecution as vscode.ProcessExecution | vscode.ShellExecution; if (exec instanceof vscode.ShellExecution) { return { - command: typeof exec.command === "string" ? exec.command : exec.command.value, - args: exec.args.map((arg) => { + command: typeof exec.command === "string" ? exec.command : (exec.command?.value ?? ""), + args: (exec.args ?? []).map((arg) => { if (typeof arg === "string") { return arg; } diff --git a/src/tools/rust-analyzer/editors/code/tsconfig.eslint.json b/src/tools/rust-analyzer/editors/code/tsconfig.eslint.json index 5e2b33ca39f8..eceffeef5984 100644 --- a/src/tools/rust-analyzer/editors/code/tsconfig.eslint.json +++ b/src/tools/rust-analyzer/editors/code/tsconfig.eslint.json @@ -6,6 +6,6 @@ "src", "tests", // these are the eslint-only inclusions - ".eslintrc.js" + "eslint.config.mts" ] } diff --git a/src/tools/rust-analyzer/editors/code/tsconfig.json b/src/tools/rust-analyzer/editors/code/tsconfig.json index 87cfd1b2ee11..a13afab17059 100644 --- a/src/tools/rust-analyzer/editors/code/tsconfig.json +++ b/src/tools/rust-analyzer/editors/code/tsconfig.json @@ -2,18 +2,17 @@ "extends": "@tsconfig/strictest/tsconfig.json", "compilerOptions": { "esModuleInterop": false, - "module": "Node16", - "moduleResolution": "Node16", - "target": "ES2021", + "module": "NodeNext", + "moduleResolution": "nodenext", + "target": "ES2024", "outDir": "out", - "lib": ["ES2021"], + "lib": ["ES2024"], "sourceMap": true, "rootDir": ".", "newLine": "lf", - // FIXME: https://github.com/rust-lang/rust-analyzer/issues/15253 "exactOptionalPropertyTypes": false }, - "exclude": ["node_modules", ".vscode-test"], + "exclude": ["node_modules", ".vscode-test", "out"], "include": ["src", "tests"] } From cdd8895d727c6b731cdfa25939c7586bc7426a88 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 14 Feb 2025 21:45:39 +0000 Subject: [PATCH 404/991] Add inference constraining Copy impl test --- tests/ui/repeat-expr/infer-eager.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/ui/repeat-expr/infer-eager.rs diff --git a/tests/ui/repeat-expr/infer-eager.rs b/tests/ui/repeat-expr/infer-eager.rs new file mode 100644 index 000000000000..afac4aaa3fd7 --- /dev/null +++ b/tests/ui/repeat-expr/infer-eager.rs @@ -0,0 +1,21 @@ +//@ check-pass + +use std::marker::PhantomData; + +struct Foo(PhantomData); + +impl Clone for Foo { + fn clone(&self) -> Self { + Foo(PhantomData) + } +} +impl Copy for Foo {} + +fn extract(_: [Foo; N]) -> T { + loop {} +} + +fn main() { + let x = [Foo(PhantomData); 2]; + _ = extract(x).max(2); +} From dc6db192c4bc8906b42c68f5ed586cf1b41477a2 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 14 Feb 2025 21:14:14 +0000 Subject: [PATCH 405/991] Defer repeat expr `Copy` check --- compiler/rustc_hir_typeck/src/expr.rs | 11 ++-- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 51 +++++++++++++++---- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 25 +++++++++ compiler/rustc_hir_typeck/src/lib.rs | 9 ++++ .../rustc_hir_typeck/src/typeck_root_ctxt.rs | 4 ++ 5 files changed, 85 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 43dfec0f408b..dcbadf215154 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1853,12 +1853,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Ty::new_error(tcx, guar); } + // We defer checking whether the element type is `Copy` as it is possible to have + // an inference variable as a repeat count and it seems unlikely that `Copy` would + // have inference side effects required for type checking to succeed. + if tcx.features().generic_arg_infer() { + self.deferred_repeat_expr_checks.borrow_mut().push((element, element_ty, count)); // If the length is 0, we don't create any elements, so we don't copy any. // If the length is 1, we don't copy that one element, we move it. Only check // for `Copy` if the length is larger, or unevaluated. - // FIXME(min_const_generic_exprs): We could perhaps defer this check so that - // we don't require `::CONST` doesn't unnecessarily require `Copy`. - if count.try_to_target_usize(tcx).is_none_or(|x| x > 1) { + } else if count.try_to_target_usize(self.tcx).is_none_or(|x| x > 1) { self.enforce_repeat_element_needs_copy_bound(element, element_ty); } @@ -1868,7 +1871,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Requires that `element_ty` is `Copy` (unless it's a const expression itself). - fn enforce_repeat_element_needs_copy_bound( + pub(super) fn enforce_repeat_element_needs_copy_bound( &self, element: &hir::Expr<'_>, element_ty: Ty<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2d7d80e39bc3..c9288b6a9d1e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -85,25 +85,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - /// Resolves type and const variables in `ty` if possible. Unlike the infcx + /// Resolves type and const variables in `t` if possible. Unlike the infcx /// version (resolve_vars_if_possible), this version will /// also select obligations if it seems useful, in an effort /// to get more type information. // FIXME(-Znext-solver): A lot of the calls to this method should // probably be `try_structurally_resolve_type` or `structurally_resolve_type` instead. #[instrument(skip(self), level = "debug", ret)] - pub(crate) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> { + pub(crate) fn resolve_vars_with_obligations>>( + &self, + mut t: T, + ) -> T { // No Infer()? Nothing needs doing. - if !ty.has_non_region_infer() { + if !t.has_non_region_infer() { debug!("no inference var, nothing needs doing"); - return ty; + return t; } - // If `ty` is a type variable, see whether we already know what it is. - ty = self.resolve_vars_if_possible(ty); - if !ty.has_non_region_infer() { - debug!(?ty); - return ty; + // If `t` is a type variable, see whether we already know what it is. + t = self.resolve_vars_if_possible(t); + if !t.has_non_region_infer() { + debug!(?t); + return t; } // If not, try resolving pending obligations as much as @@ -111,7 +114,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // indirect dependencies that don't seem worth tracking // precisely. self.select_obligations_where_possible(|_| {}); - self.resolve_vars_if_possible(ty) + self.resolve_vars_if_possible(t) } pub(crate) fn record_deferred_call_resolution( @@ -1454,7 +1457,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sp: Span, ct: ty::Const<'tcx>, ) -> ty::Const<'tcx> { - // FIXME(min_const_generic_exprs): We could process obligations here if `ct` is a var. + let ct = self.resolve_vars_with_obligations(ct); if self.next_trait_solver() && let ty::ConstKind::Unevaluated(..) = ct.kind() @@ -1510,6 +1513,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + pub(crate) fn structurally_resolve_const( + &self, + sp: Span, + ct: ty::Const<'tcx>, + ) -> ty::Const<'tcx> { + let ct = self.try_structurally_resolve_const(sp, ct); + + if !ct.is_ct_infer() { + ct + } else { + let e = self.tainted_by_errors().unwrap_or_else(|| { + self.err_ctxt() + .emit_inference_failure_err( + self.body_id, + sp, + ct.into(), + TypeAnnotationNeeded::E0282, + true, + ) + .emit() + }); + // FIXME: Infer `?ct = {const error}`? + ty::Const::new_error(self.tcx, e) + } + } + pub(crate) fn with_breakable_ctxt R, R>( &self, id: HirId, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 63c1c0608274..85de70138fbd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -115,6 +115,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + pub(in super::super) fn check_repeat_exprs(&self) { + let mut deferred_repeat_expr_checks = self.deferred_repeat_expr_checks.borrow_mut(); + debug!("FnCtxt::check_repeat_exprs: {} deferred checks", deferred_repeat_expr_checks.len()); + for (element, element_ty, count) in deferred_repeat_expr_checks.drain(..) { + // We want to emit an error if the const is not structurally resolveable as otherwise + // we can find up conservatively proving `Copy` which may infer the repeat expr count + // to something that never required `Copy` in the first place. + let count = + self.structurally_resolve_const(element.span, self.normalize(element.span, count)); + + // Avoid run on "`NotCopy: Copy` is not implemented" errors when the repeat expr count + // is erroneous/unknown. The user might wind up specifying a repeat count of 0/1. + if count.references_error() { + continue; + } + + // If the length is 0, we don't create any elements, so we don't copy any. + // If the length is 1, we don't copy that one element, we move it. Only check + // for `Copy` if the length is larger. + if count.try_to_target_usize(self.tcx).is_none_or(|x| x > 1) { + self.enforce_repeat_element_needs_copy_bound(element, element_ty); + } + } + } + pub(in super::super) fn check_method_argument_types( &self, sp: Span, diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 0130ad775d9e..8b9c2b4a6ca0 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -199,6 +199,15 @@ fn typeck_with_inspect<'tcx>( fcx.write_ty(id, expected_type); }; + // Whether to check repeat exprs before/after inference fallback is somewhat arbitrary of a decision + // as neither option is strictly more permissive than the other. However, we opt to check repeat exprs + // first as errors from not having inferred array lengths yet seem less confusing than errors from inference + // fallback arbitrarily inferring something incompatible with `Copy` inference side effects. + // + // This should also be forwards compatible with moving repeat expr checks to a custom goal kind or using + // marker traits in the future. + fcx.check_repeat_exprs(); + fcx.type_inference_fallback(); // Even though coercion casts provide type hints, we check casts after fallback for diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index 903be7e732af..381606a9fb02 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -62,6 +62,9 @@ pub(crate) struct TypeckRootCtxt<'tcx> { pub(super) deferred_coroutine_interiors: RefCell)>>, + pub(super) deferred_repeat_expr_checks: + RefCell, Ty<'tcx>, ty::Const<'tcx>)>>, + /// Whenever we introduce an adjustment from `!` into a type variable, /// we record that type variable here. This is later used to inform /// fallback. See the `fallback` module for details. @@ -96,6 +99,7 @@ impl<'tcx> TypeckRootCtxt<'tcx> { deferred_transmute_checks: RefCell::new(Vec::new()), deferred_asm_checks: RefCell::new(Vec::new()), deferred_coroutine_interiors: RefCell::new(Vec::new()), + deferred_repeat_expr_checks: RefCell::new(Vec::new()), diverging_type_vars: RefCell::new(Default::default()), infer_var_info: RefCell::new(Default::default()), } From 6c3243f0086c0f6a77b4a66fdfcf7f55c36f94a1 Mon Sep 17 00:00:00 2001 From: Boxy Date: Sat, 15 Feb 2025 02:01:41 +0000 Subject: [PATCH 406/991] Bless --- tests/ui/consts/const-fn-in-vec.rs | 11 +++- tests/ui/consts/const-fn-in-vec.stderr | 2 +- .../copy-check-deferred-after-fallback.rs | 37 ++++++++++++ .../copy-check-deferred-after-fallback.stderr | 14 +++++ .../copy-check-deferred-before-fallback.rs | 59 +++++++++++++++++++ ...inference-side-effects-are-lazy.gai.stderr | 17 ++++++ ...> copy-inference-side-effects-are-lazy.rs} | 6 +- ...nfer.rs => copy-inference-side-effects.rs} | 0 .../repeat-expr/dont-require-copy-on-infer.rs | 6 ++ .../no-conservative-copy-impl-requirement.rs | 20 +++++++ ...-conservative-copy-impl-requirement.stderr | 14 +++++ 11 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs create mode 100644 tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr create mode 100644 tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs create mode 100644 tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr rename tests/ui/repeat-expr/{infer-eager.rs => copy-inference-side-effects-are-lazy.rs} (69%) rename tests/ui/repeat-expr/{infer.rs => copy-inference-side-effects.rs} (100%) create mode 100644 tests/ui/repeat-expr/dont-require-copy-on-infer.rs create mode 100644 tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs create mode 100644 tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr diff --git a/tests/ui/consts/const-fn-in-vec.rs b/tests/ui/consts/const-fn-in-vec.rs index 0483800efefd..d1430bc8e002 100644 --- a/tests/ui/consts/const-fn-in-vec.rs +++ b/tests/ui/consts/const-fn-in-vec.rs @@ -1,11 +1,16 @@ static _MAYBE_STRINGS: [Option; 5] = [None; 5]; //~^ ERROR the trait bound `String: Copy` is not satisfied -fn main() { - // should hint to create an inline `const` block - // or to create a new `const` item +// should hint to create an inline `const` block +// or to create a new `const` item +fn foo() { let _strings: [String; 5] = [String::new(); 5]; //~^ ERROR the trait bound `String: Copy` is not satisfied +} + +fn bar() { let _maybe_strings: [Option; 5] = [None; 5]; //~^ ERROR the trait bound `String: Copy` is not satisfied } + +fn main() {} diff --git a/tests/ui/consts/const-fn-in-vec.stderr b/tests/ui/consts/const-fn-in-vec.stderr index b31e180fea2b..5be26d7c121b 100644 --- a/tests/ui/consts/const-fn-in-vec.stderr +++ b/tests/ui/consts/const-fn-in-vec.stderr @@ -22,7 +22,7 @@ LL | let _strings: [String; 5] = [String::new(); 5]; = note: the `Copy` trait is required because this value will be copied for each element of the array error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/const-fn-in-vec.rs:9:48 + --> $DIR/const-fn-in-vec.rs:12:48 | LL | let _maybe_strings: [Option; 5] = [None; 5]; | ^^^^ diff --git a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs new file mode 100644 index 000000000000..d9ad93541ecf --- /dev/null +++ b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs @@ -0,0 +1,37 @@ +#![feature(generic_arg_infer)] + +// Test that would start passing if we defer repeat expr copy checks to end of +// typechecking and they're checked after integer fallback occurs. We accomplish +// this by contriving a situation where integer fallback allows progress to be +// made on a trait goal that infers the length of a repeat expr. + +use std::marker::PhantomData; + +struct NotCopy; + +trait Trait {} + +impl Trait<2> for u32 {} +impl Trait<1> for i32 {} + +fn make_goal, const N: usize>(_: &T, _: [NotCopy; N]) {} + +fn main() { + let a = 1; + let b = [NotCopy; _]; + //~^ ERROR: type annotations needed + + // a is of type `?y` + // b is of type `[NotCopy; ?x]` + // there is a goal ?y: Trait` with two candidates: + // - `i32: Trait<1>`, ?y=i32 ?x=1 which doesnt require `NotCopy: Copy` + // - `u32: Trait<2>` ?y=u32 ?x=2 which requires `NotCopy: Copy` + make_goal(&a, b); + + // final repeat expr checks: + // + // `NotCopy; ?x` + // - succeeds if fallback happens before repeat exprs as `i32: Trait` infers `?x=1` + // - fails if repeat expr checks happen first as `?x` is unconstrained so cannot be + // structurally resolved +} diff --git a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr new file mode 100644 index 000000000000..2a0cb3fb7a39 --- /dev/null +++ b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `[NotCopy; _]` + --> $DIR/copy-check-deferred-after-fallback.rs:21:9 + | +LL | let b = [NotCopy; _]; + | ^ ------- type must be known at this point + | +help: consider giving `b` an explicit type, where the value of const parameter `N` is specified + | +LL | let b: [_; N] = [NotCopy; _]; + | ++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs new file mode 100644 index 000000000000..4654d7483a64 --- /dev/null +++ b/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs @@ -0,0 +1,59 @@ +//@ check-pass + +#![feature(generic_arg_infer)] + +// Test that if we defer repeat expr copy checks to end of typechecking they're +// checked before integer fallback occurs. We accomplish this by contriving a +// situation where we have a goal that can be proven either via another repeat expr +// check or by integer fallback. In the integer fallback case an array length would +// be inferred to `2` requiring `NotCopy: Copy`, and in the repeat expr case it would +// be inferred to `1`. + +use std::marker::PhantomData; + +struct NotCopy; + +struct Foo(PhantomData); + +impl Clone for Foo { + fn clone(&self) -> Self { + Foo(PhantomData) + } +} + +impl Copy for Foo {} + +fn tie(_: &T, _: [Foo; 2]) {} + +trait Trait {} + +impl Trait<2> for i32 {} +impl Trait<1> for u32 {} + +fn make_goal, const N: usize>(_: &T, _: [NotCopy; N]) {} + +fn main() { + let a = 1; + let b: [Foo<_>; 2] = [Foo(PhantomData); _]; + tie(&a, b); + let c = [NotCopy; _]; + + // a is of type `?y` + // b is of type `[Foo; 2]` + // c is of type `[NotCopy; ?x]` + // there is a goal ?y: Trait` with two candidates: + // - `i32: Trait<2>`, ?y=i32 ?x=2 which requires `NotCopy: Copy` when expr checks happen + // - `u32: Trait<1>` ?y=u32 ?x=1 which doesnt require `NotCopy: Copy` + make_goal(&a, c); + + // final repeat expr checks: + // + // `Foo; 2` + // - Foo: Copy + // - requires ?y=u32 + // + // `NotCopy; ?x` + // - fails if fallback happens before repeat exprs as `i32: Trait` infers `?x=2` + // - succeeds if repeat expr checks happen first as `?y=u32` means `u32: Trait` + // infers `?x=1` +} diff --git a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr new file mode 100644 index 000000000000..de38476c82b3 --- /dev/null +++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr @@ -0,0 +1,17 @@ +error[E0282]: type annotations needed for `[Foo<_>; 2]` + --> $DIR/copy-inference-side-effects-are-lazy.rs:22:9 + | +LL | let x = [Foo(PhantomData); 2]; + | ^ +LL | +LL | _ = extract(x).max(2); + | ---------- type must be known at this point + | +help: consider giving `x` an explicit type, where the type for type parameter `T` is specified + | +LL | let x: [Foo; 2] = [Foo(PhantomData); 2]; + | +++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/repeat-expr/infer-eager.rs b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs similarity index 69% rename from tests/ui/repeat-expr/infer-eager.rs rename to tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs index afac4aaa3fd7..0b0672d9c2b5 100644 --- a/tests/ui/repeat-expr/infer-eager.rs +++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs @@ -1,4 +1,7 @@ -//@ check-pass +//@revisions: current gai +//@[current] check-pass + +#![cfg_attr(gai, feature(generic_arg_infer))] use std::marker::PhantomData; @@ -17,5 +20,6 @@ fn extract(_: [Foo; N]) -> T { fn main() { let x = [Foo(PhantomData); 2]; + //[gai]~^ ERROR: type annotations needed _ = extract(x).max(2); } diff --git a/tests/ui/repeat-expr/infer.rs b/tests/ui/repeat-expr/copy-inference-side-effects.rs similarity index 100% rename from tests/ui/repeat-expr/infer.rs rename to tests/ui/repeat-expr/copy-inference-side-effects.rs diff --git a/tests/ui/repeat-expr/dont-require-copy-on-infer.rs b/tests/ui/repeat-expr/dont-require-copy-on-infer.rs new file mode 100644 index 000000000000..e81bf1595be1 --- /dev/null +++ b/tests/ui/repeat-expr/dont-require-copy-on-infer.rs @@ -0,0 +1,6 @@ +//@ check-pass +#![feature(generic_arg_infer)] + +fn main() { + let a: [_; 1] = [String::new(); _]; +} diff --git a/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs new file mode 100644 index 000000000000..eb70df62996f --- /dev/null +++ b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs @@ -0,0 +1,20 @@ +#![feature(generic_arg_infer)] + +struct Foo; + +impl Clone for Foo<1> { + fn clone(&self) -> Self { + Foo + } +} +impl Copy for Foo<1> {} + +fn unify(_: &[Foo; N]) { + loop {} +} + +fn main() { + let x = &[Foo::<_>; _]; + //~^ ERROR: type annotations needed for `&[Foo<_>; _]` + _ = unify(x); +} diff --git a/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr new file mode 100644 index 000000000000..04f8ff33fdab --- /dev/null +++ b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `&[Foo<_>; _]` + --> $DIR/no-conservative-copy-impl-requirement.rs:17:9 + | +LL | let x = &[Foo::<_>; _]; + | ^ -------- type must be known at this point + | +help: consider giving `x` an explicit type, where the value of const parameter `N` is specified + | +LL | let x: &[Foo; N] = &[Foo::<_>; _]; + | ++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. From 6ea4823733254432aee255465177b8e53f01a79d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 27 Feb 2025 21:36:28 +0100 Subject: [PATCH 407/991] Fix 32-bit MSVC CI By throwing more hardware at it. --- src/ci/github-actions/jobs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 64e64867de26..279c7649ca3d 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -474,13 +474,13 @@ auto: env: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc --enable-sanitizers SCRIPT: make ci-msvc-py - <<: *job-windows + <<: *job-windows-8c - name: i686-msvc-2 env: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc --enable-sanitizers SCRIPT: make ci-msvc-ps1 - <<: *job-windows + <<: *job-windows-8c # x86_64-msvc-ext is split into multiple jobs to run tests in parallel. - name: x86_64-msvc-ext1 @@ -595,7 +595,7 @@ auto: SCRIPT: python x.py dist bootstrap --include-default-paths DIST_REQUIRE_ALL_TOOLS: 1 CODEGEN_BACKENDS: llvm,cranelift - <<: *job-windows + <<: *job-windows-8c - name: dist-aarch64-msvc env: From 53a1ff70e87ba92caddfbcc9feee8bc89e4a02fc Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Wed, 26 Feb 2025 19:46:01 +0100 Subject: [PATCH 408/991] Check os_str_display MSRV instead of feature This feature was stabilized, so the FormatArgs lints should check if the MSRV of the stabilization is met, rather than checking if the feature is enabled. --- clippy_lints/src/format_args.rs | 29 +++++++------- clippy_utils/src/msrvs.rs | 1 + .../ui/unnecessary_os_str_debug_formatting.rs | 1 - ...unnecessary_os_str_debug_formatting.stderr | 12 +++--- tests/ui/unnecessary_path_debug_formatting.rs | 7 ++-- .../unnecessary_path_debug_formatting.stderr | 38 ++++++++++++++----- 6 files changed, 54 insertions(+), 34 deletions(-) diff --git a/clippy_lints/src/format_args.rs b/clippy_lints/src/format_args.rs index ea617dd1bab8..1ba355938b68 100644 --- a/clippy_lints/src/format_args.rs +++ b/clippy_lints/src/format_args.rs @@ -15,6 +15,7 @@ use rustc_ast::{ FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions, FormatPlaceholder, FormatTrait, }; +use rustc_attr_parsing::RustcVersion; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode}; @@ -206,17 +207,17 @@ pub struct FormatArgs<'tcx> { format_args: FormatArgsStorage, msrv: Msrv, ignore_mixed: bool, - ty_feature_map: FxHashMap, Option>, + ty_msrv_map: FxHashMap, Option>, } impl<'tcx> FormatArgs<'tcx> { pub fn new(tcx: TyCtxt<'tcx>, conf: &'static Conf, format_args: FormatArgsStorage) -> Self { - let ty_feature_map = make_ty_feature_map(tcx); + let ty_msrv_map = make_ty_msrv_map(tcx); Self { format_args, msrv: conf.msrv.clone(), ignore_mixed: conf.allow_mixed_uninlined_format_args, - ty_feature_map, + ty_msrv_map, } } } @@ -233,7 +234,8 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs<'tcx> { macro_call: ¯o_call, format_args, ignore_mixed: self.ignore_mixed, - ty_feature_map: &self.ty_feature_map, + msrv: &self.msrv, + ty_msrv_map: &self.ty_msrv_map, }; linter.check_templates(); @@ -253,7 +255,8 @@ struct FormatArgsExpr<'a, 'tcx> { macro_call: &'a MacroCall, format_args: &'a rustc_ast::FormatArgs, ignore_mixed: bool, - ty_feature_map: &'a FxHashMap, Option>, + msrv: &'a Msrv, + ty_msrv_map: &'a FxHashMap, Option>, } impl<'tcx> FormatArgsExpr<'_, 'tcx> { @@ -538,19 +541,19 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> { fn can_display_format(&self, ty: Ty<'tcx>) -> bool { let ty = ty.peel_refs(); - if let Some(feature) = self.ty_feature_map.get(&ty) - && feature.is_none_or(|feature| self.cx.tcx.features().enabled(feature)) + if let Some(msrv) = self.ty_msrv_map.get(&ty) + && msrv.is_none_or(|msrv| self.msrv.meets(msrv)) { return true; } - // Even if `ty` is not in `self.ty_feature_map`, check whether `ty` implements `Deref` with - // a `Target` that is in `self.ty_feature_map`. + // Even if `ty` is not in `self.ty_msrv_map`, check whether `ty` implements `Deref` with + // a `Target` that is in `self.ty_msrv_map`. if let Some(deref_trait_id) = self.cx.tcx.lang_items().deref_trait() && implements_trait(self.cx, ty, deref_trait_id, &[]) && let Some(target_ty) = self.cx.get_associated_type(ty, deref_trait_id, "Target") - && let Some(feature) = self.ty_feature_map.get(&target_ty) - && feature.is_none_or(|feature| self.cx.tcx.features().enabled(feature)) + && let Some(msrv) = self.ty_msrv_map.get(&target_ty) + && msrv.is_none_or(|msrv| self.msrv.meets(msrv)) { return true; } @@ -559,8 +562,8 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> { } } -fn make_ty_feature_map(tcx: TyCtxt<'_>) -> FxHashMap, Option> { - [(sym::OsStr, Some(Symbol::intern("os_str_display"))), (sym::Path, None)] +fn make_ty_msrv_map(tcx: TyCtxt<'_>) -> FxHashMap, Option> { + [(sym::OsStr, Some(msrvs::OS_STR_DISPLAY)), (sym::Path, None)] .into_iter() .filter_map(|(name, feature)| { tcx.get_diagnostic_item(name).map(|def_id| { diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 8c9832af0a19..8a7a7d006352 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -19,6 +19,7 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { + 1,87,0 { OS_STR_DISPLAY } 1,84,0 { CONST_OPTION_AS_SLICE } 1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP } 1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP } diff --git a/tests/ui/unnecessary_os_str_debug_formatting.rs b/tests/ui/unnecessary_os_str_debug_formatting.rs index 3c264e5fc598..12663ec9a528 100644 --- a/tests/ui/unnecessary_os_str_debug_formatting.rs +++ b/tests/ui/unnecessary_os_str_debug_formatting.rs @@ -1,4 +1,3 @@ -#![feature(os_str_display)] #![warn(clippy::unnecessary_debug_formatting)] use std::ffi::{OsStr, OsString}; diff --git a/tests/ui/unnecessary_os_str_debug_formatting.stderr b/tests/ui/unnecessary_os_str_debug_formatting.stderr index 382e59b04619..001309ab817a 100644 --- a/tests/ui/unnecessary_os_str_debug_formatting.stderr +++ b/tests/ui/unnecessary_os_str_debug_formatting.stderr @@ -1,5 +1,5 @@ error: unnecessary `Debug` formatting in `println!` args - --> tests/ui/unnecessary_os_str_debug_formatting.rs:15:22 + --> tests/ui/unnecessary_os_str_debug_formatting.rs:14:22 | LL | println!("{:?}", os_str); | ^^^^^^ @@ -10,7 +10,7 @@ LL | println!("{:?}", os_str); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_debug_formatting)]` error: unnecessary `Debug` formatting in `println!` args - --> tests/ui/unnecessary_os_str_debug_formatting.rs:16:22 + --> tests/ui/unnecessary_os_str_debug_formatting.rs:15:22 | LL | println!("{:?}", os_string); | ^^^^^^^^^ @@ -19,7 +19,7 @@ LL | println!("{:?}", os_string); = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed error: unnecessary `Debug` formatting in `println!` args - --> tests/ui/unnecessary_os_str_debug_formatting.rs:18:16 + --> tests/ui/unnecessary_os_str_debug_formatting.rs:17:16 | LL | println!("{os_str:?}"); | ^^^^^^ @@ -28,7 +28,7 @@ LL | println!("{os_str:?}"); = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed error: unnecessary `Debug` formatting in `println!` args - --> tests/ui/unnecessary_os_str_debug_formatting.rs:19:16 + --> tests/ui/unnecessary_os_str_debug_formatting.rs:18:16 | LL | println!("{os_string:?}"); | ^^^^^^^^^ @@ -37,7 +37,7 @@ LL | println!("{os_string:?}"); = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed error: unnecessary `Debug` formatting in `format!` args - --> tests/ui/unnecessary_os_str_debug_formatting.rs:21:37 + --> tests/ui/unnecessary_os_str_debug_formatting.rs:20:37 | LL | let _: String = format!("{:?}", os_str); | ^^^^^^ @@ -46,7 +46,7 @@ LL | let _: String = format!("{:?}", os_str); = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed error: unnecessary `Debug` formatting in `format!` args - --> tests/ui/unnecessary_os_str_debug_formatting.rs:22:37 + --> tests/ui/unnecessary_os_str_debug_formatting.rs:21:37 | LL | let _: String = format!("{:?}", os_string); | ^^^^^^^^^ diff --git a/tests/ui/unnecessary_path_debug_formatting.rs b/tests/ui/unnecessary_path_debug_formatting.rs index 96ad2ee2bf23..02adeece2809 100644 --- a/tests/ui/unnecessary_path_debug_formatting.rs +++ b/tests/ui/unnecessary_path_debug_formatting.rs @@ -25,11 +25,10 @@ fn main() { println!("{}", path.display()); println!("{}", path_buf.display()); - // should not fire because feature `os_str_display` is not enabled - println!("{:?}", os_str); - println!("{:?}", os_string); - // positive tests + println!("{:?}", os_str); //~ unnecessary_debug_formatting + println!("{:?}", os_string); //~ unnecessary_debug_formatting + println!("{:?}", path); //~ unnecessary_debug_formatting println!("{:?}", path_buf); //~ unnecessary_debug_formatting diff --git a/tests/ui/unnecessary_path_debug_formatting.stderr b/tests/ui/unnecessary_path_debug_formatting.stderr index c9f649dbc0a1..f12fa72c84b3 100644 --- a/tests/ui/unnecessary_path_debug_formatting.stderr +++ b/tests/ui/unnecessary_path_debug_formatting.stderr @@ -1,16 +1,34 @@ error: unnecessary `Debug` formatting in `println!` args - --> tests/ui/unnecessary_path_debug_formatting.rs:33:22 + --> tests/ui/unnecessary_path_debug_formatting.rs:29:22 + | +LL | println!("{:?}", os_str); + | ^^^^^^ + | + = help: use `Display` formatting and change this to `os_str.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + = note: `-D clippy::unnecessary-debug-formatting` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_debug_formatting)]` + +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_path_debug_formatting.rs:30:22 + | +LL | println!("{:?}", os_string); + | ^^^^^^^^^ + | + = help: use `Display` formatting and change this to `os_string.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_path_debug_formatting.rs:32:22 | LL | println!("{:?}", path); | ^^^^ | = help: use `Display` formatting and change this to `path.display()` = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed - = note: `-D clippy::unnecessary-debug-formatting` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::unnecessary_debug_formatting)]` error: unnecessary `Debug` formatting in `println!` args - --> tests/ui/unnecessary_path_debug_formatting.rs:34:22 + --> tests/ui/unnecessary_path_debug_formatting.rs:33:22 | LL | println!("{:?}", path_buf); | ^^^^^^^^ @@ -19,7 +37,7 @@ LL | println!("{:?}", path_buf); = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed error: unnecessary `Debug` formatting in `println!` args - --> tests/ui/unnecessary_path_debug_formatting.rs:36:16 + --> tests/ui/unnecessary_path_debug_formatting.rs:35:16 | LL | println!("{path:?}"); | ^^^^ @@ -28,7 +46,7 @@ LL | println!("{path:?}"); = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed error: unnecessary `Debug` formatting in `println!` args - --> tests/ui/unnecessary_path_debug_formatting.rs:37:16 + --> tests/ui/unnecessary_path_debug_formatting.rs:36:16 | LL | println!("{path_buf:?}"); | ^^^^^^^^ @@ -37,7 +55,7 @@ LL | println!("{path_buf:?}"); = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed error: unnecessary `Debug` formatting in `format!` args - --> tests/ui/unnecessary_path_debug_formatting.rs:39:37 + --> tests/ui/unnecessary_path_debug_formatting.rs:38:37 | LL | let _: String = format!("{:?}", path); | ^^^^ @@ -46,7 +64,7 @@ LL | let _: String = format!("{:?}", path); = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed error: unnecessary `Debug` formatting in `format!` args - --> tests/ui/unnecessary_path_debug_formatting.rs:40:37 + --> tests/ui/unnecessary_path_debug_formatting.rs:39:37 | LL | let _: String = format!("{:?}", path_buf); | ^^^^^^^^ @@ -55,7 +73,7 @@ LL | let _: String = format!("{:?}", path_buf); = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed error: unnecessary `Debug` formatting in `println!` args - --> tests/ui/unnecessary_path_debug_formatting.rs:43:22 + --> tests/ui/unnecessary_path_debug_formatting.rs:42:22 | LL | println!("{:?}", &*deref_path); | ^^^^^^^^^^^^ @@ -63,5 +81,5 @@ LL | println!("{:?}", &*deref_path); = help: use `Display` formatting and change this to `&*deref_path.display()` = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed -error: aborting due to 7 previous errors +error: aborting due to 9 previous errors From 28555d1231beb1546b6ac5e1f81780db00aa46aa Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Wed, 26 Feb 2025 19:47:30 +0100 Subject: [PATCH 409/991] Split must_use_unit test into an unfixable part With the attribute refactor in rustc, making this case machine applicable is not easily possible anymore. This splits up the tests properly. --- tests/ui/must_use_unit.fixed | 8 -------- tests/ui/must_use_unit.rs | 8 -------- tests/ui/must_use_unit.stderr | 18 +----------------- ...nit_12320.rs => must_use_unit_unfixable.rs} | 8 ++++---- ...0.stderr => must_use_unit_unfixable.stderr} | 12 ++++++------ 5 files changed, 11 insertions(+), 43 deletions(-) rename tests/ui/{must_use_unit_12320.rs => must_use_unit_unfixable.rs} (62%) rename tests/ui/{must_use_unit_12320.stderr => must_use_unit_unfixable.stderr} (62%) diff --git a/tests/ui/must_use_unit.fixed b/tests/ui/must_use_unit.fixed index 5a8603ceb562..683754a98c82 100644 --- a/tests/ui/must_use_unit.fixed +++ b/tests/ui/must_use_unit.fixed @@ -26,11 +26,3 @@ fn main() { fn foo() {} ); } - -#[cfg_attr(all(), deprecated)] -fn issue_12320() {} -//~^ must_use_unit - -#[cfg_attr(all(), deprecated, doc = "foo")] -fn issue_12320_2() {} -//~^ must_use_unit diff --git a/tests/ui/must_use_unit.rs b/tests/ui/must_use_unit.rs index ab2764841cb4..519b8fa36821 100644 --- a/tests/ui/must_use_unit.rs +++ b/tests/ui/must_use_unit.rs @@ -29,11 +29,3 @@ fn main() { fn foo() {} ); } - -#[cfg_attr(all(), must_use, deprecated)] -fn issue_12320() {} -//~^ must_use_unit - -#[cfg_attr(all(), deprecated, doc = "foo", must_use)] -fn issue_12320_2() {} -//~^ must_use_unit diff --git a/tests/ui/must_use_unit.stderr b/tests/ui/must_use_unit.stderr index 3df9738a9693..8f2af0cbd291 100644 --- a/tests/ui/must_use_unit.stderr +++ b/tests/ui/must_use_unit.stderr @@ -25,21 +25,5 @@ LL | #[must_use = "With note"] LL | pub fn must_use_with_note() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit.rs:34:1 - | -LL | #[cfg_attr(all(), must_use, deprecated)] - | -------------------- help: change these attributes to: `deprecated` -LL | fn issue_12320() {} - | ^^^^^^^^^^^^^^^^ - -error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit.rs:38:1 - | -LL | #[cfg_attr(all(), deprecated, doc = "foo", must_use)] - | --------------------------------- help: change these attributes to: `deprecated, doc = "foo"` -LL | fn issue_12320_2() {} - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/must_use_unit_12320.rs b/tests/ui/must_use_unit_unfixable.rs similarity index 62% rename from tests/ui/must_use_unit_12320.rs rename to tests/ui/must_use_unit_unfixable.rs index 39dcafdb38b5..0dba7996bac3 100644 --- a/tests/ui/must_use_unit_12320.rs +++ b/tests/ui/must_use_unit_unfixable.rs @@ -1,11 +1,11 @@ -//@aux-build:proc_macros.rs //@no-rustfix -#![warn(clippy::must_use_unit)] -#![allow(clippy::unused_unit)] - #[cfg_attr(all(), must_use, deprecated)] fn issue_12320() {} +//~^ must_use_unit #[cfg_attr(all(), deprecated, doc = "foo", must_use)] fn issue_12320_2() {} +//~^ must_use_unit + +fn main() {} diff --git a/tests/ui/must_use_unit_12320.stderr b/tests/ui/must_use_unit_unfixable.stderr similarity index 62% rename from tests/ui/must_use_unit_12320.stderr rename to tests/ui/must_use_unit_unfixable.stderr index b3e1cbc04576..087682199afb 100644 --- a/tests/ui/must_use_unit_12320.stderr +++ b/tests/ui/must_use_unit_unfixable.stderr @@ -1,25 +1,25 @@ error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit_12320.rs:8:1 + --> tests/ui/must_use_unit_unfixable.rs:4:1 | LL | fn issue_12320() {} | ^^^^^^^^^^^^^^^^ | help: remove `must_use` - --> tests/ui/must_use_unit_12320.rs:7:19 + --> tests/ui/must_use_unit_unfixable.rs:3:19 | LL | #[cfg_attr(all(), must_use, deprecated)] | ^^^^^^^^ - = note: `-D clippy::double-must-use` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]` + = note: `-D clippy::must-use-unit` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::must_use_unit)]` error: this unit-returning function has a `#[must_use]` attribute - --> tests/ui/must_use_unit_12320.rs:11:1 + --> tests/ui/must_use_unit_unfixable.rs:8:1 | LL | fn issue_12320_2() {} | ^^^^^^^^^^^^^^^^^^ | help: remove `must_use` - --> tests/ui/must_use_unit_12320.rs:10:44 + --> tests/ui/must_use_unit_unfixable.rs:7:44 | LL | #[cfg_attr(all(), deprecated, doc = "foo", must_use)] | ^^^^^^^^ From b3d35b1af6d997b138d679aa4c1143dbac11c11e Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 27 Feb 2025 21:49:59 +0100 Subject: [PATCH 410/991] Bump nightly version -> 2025-02-27 --- clippy_utils/README.md | 2 +- rust-toolchain | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 41f3b1cbd507..5dd31b52f880 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-02-06 +nightly-2025-02-27 ``` diff --git a/rust-toolchain b/rust-toolchain index ab760287e83a..a4931499c802 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-02-06" +channel = "nightly-2025-02-27" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" From 06175f43b3119b537b48291fa771c7396b8e92cd Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Tue, 17 Dec 2024 22:43:19 +0100 Subject: [PATCH 411/991] Add `is_float_literal` utility --- clippy_utils/src/lib.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index dc3bbb417c0a..3e9429399b31 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1752,6 +1752,17 @@ pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool { false } +/// Checks whether the given expression is a constant literal of the given value. +pub fn is_float_literal(expr: &Expr<'_>, value: f64) -> bool { + if let ExprKind::Lit(spanned) = expr.kind + && let LitKind::Float(v, _) = spanned.node + { + v.as_str().parse() == Ok(value) + } else { + false + } +} + /// Returns `true` if the given `Expr` has been coerced before. /// /// Examples of coercions can be found in the Nomicon at From baadee8fd36e951c258d3d8505aa292bc3165b31 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Tue, 17 Dec 2024 22:43:19 +0100 Subject: [PATCH 412/991] New lint: `manual_midpoint` --- CHANGELOG.md | 1 + book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/operators/manual_midpoint.rs | 64 ++++++++++++++++ clippy_lints/src/operators/mod.rs | 32 ++++++++ clippy_utils/src/msrvs.rs | 3 +- tests/ui/manual_midpoint.fixed | 74 +++++++++++++++++++ tests/ui/manual_midpoint.rs | 74 +++++++++++++++++++ tests/ui/manual_midpoint.stderr | 65 ++++++++++++++++ tests/ui/option_if_let_else.fixed | 1 + tests/ui/option_if_let_else.rs | 1 + tests/ui/option_if_let_else.stderr | 50 ++++++------- tests/ui/suspicious_operation_groupings.fixed | 2 +- tests/ui/suspicious_operation_groupings.rs | 2 +- 15 files changed, 344 insertions(+), 28 deletions(-) create mode 100644 clippy_lints/src/operators/manual_midpoint.rs create mode 100644 tests/ui/manual_midpoint.fixed create mode 100644 tests/ui/manual_midpoint.rs create mode 100644 tests/ui/manual_midpoint.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e8ca7cb1496..ce3960186e39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5807,6 +5807,7 @@ Released 2018-09-13 [`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_main_separator_str [`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map [`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy +[`manual_midpoint`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_midpoint [`manual_next_back`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_next_back [`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive [`manual_ok_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_err diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 7a70c6c40ac8..4b416c2b595d 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -771,6 +771,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one) * [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check) * [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) +* [`manual_midpoint`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_midpoint) * [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive) * [`manual_option_as_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_as_slice) * [`manual_pattern_char_comparison`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 23d585a6c159..c97f5b0f8067 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -626,6 +626,7 @@ define_Conf! { manual_hash_one, manual_is_ascii_check, manual_let_else, + manual_midpoint, manual_non_exhaustive, manual_option_as_slice, manual_pattern_char_comparison, diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 9dde6a7933c6..0834618499c7 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -608,6 +608,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::operators::IMPOSSIBLE_COMPARISONS_INFO, crate::operators::INEFFECTIVE_BIT_MASK_INFO, crate::operators::INTEGER_DIVISION_INFO, + crate::operators::MANUAL_MIDPOINT_INFO, crate::operators::MISREFACTORED_ASSIGN_OP_INFO, crate::operators::MODULO_ARITHMETIC_INFO, crate::operators::MODULO_ONE_INFO, diff --git a/clippy_lints/src/operators/manual_midpoint.rs b/clippy_lints/src/operators/manual_midpoint.rs new file mode 100644 index 000000000000..61ef5670a5ad --- /dev/null +++ b/clippy_lints/src/operators/manual_midpoint.rs @@ -0,0 +1,64 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::sugg::Sugg; +use clippy_utils::{is_float_literal, is_integer_literal}; +use rustc_ast::BinOpKind; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; + +use super::MANUAL_MIDPOINT; + +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + op: BinOpKind, + left: &'tcx Expr<'_>, + right: &'tcx Expr<'_>, + msrv: &Msrv, +) { + if !left.span.from_expansion() + && !right.span.from_expansion() + && op == BinOpKind::Div + && (is_integer_literal(right, 2) || is_float_literal(right, 2.0)) + && let Some((ll_expr, lr_expr)) = add_operands(left) + && add_operands(ll_expr).is_none() && add_operands(lr_expr).is_none() + && let left_ty = cx.typeck_results().expr_ty_adjusted(ll_expr) + && let right_ty = cx.typeck_results().expr_ty_adjusted(lr_expr) + && left_ty == right_ty + // Do not lint on `(_+1)/2` and `(1+_)/2`, it is likely a `div_ceil()` operation + && !is_integer_literal(ll_expr, 1) && !is_integer_literal(lr_expr, 1) + && is_midpoint_implemented(left_ty, msrv) + { + let mut app = Applicability::MachineApplicable; + let left_sugg = Sugg::hir_with_context(cx, ll_expr, expr.span.ctxt(), "..", &mut app); + let right_sugg = Sugg::hir_with_context(cx, lr_expr, expr.span.ctxt(), "..", &mut app); + let sugg = format!("{left_ty}::midpoint({left_sugg}, {right_sugg})"); + span_lint_and_sugg( + cx, + MANUAL_MIDPOINT, + expr.span, + "manual implementation of `midpoint` which can overflow", + format!("use `{left_ty}::midpoint` instead"), + sugg, + app, + ); + } +} + +/// Return the left and right operands if `expr` represents an addition +fn add_operands<'e, 'tcx>(expr: &'e Expr<'tcx>) -> Option<(&'e Expr<'tcx>, &'e Expr<'tcx>)> { + match expr.kind { + ExprKind::Binary(op, left, right) if op.node == BinOpKind::Add => Some((left, right)), + _ => None, + } +} + +fn is_midpoint_implemented(ty: Ty<'_>, msrv: &Msrv) -> bool { + match ty.kind() { + ty::Uint(_) | ty::Float(_) => msrv.meets(msrvs::UINT_FLOAT_MIDPOINT), + ty::Int(_) => msrv.meets(msrvs::INT_MIDPOINT), + _ => false, + } +} diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 9ad32c2bd396..43b657ea7ff0 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -11,6 +11,7 @@ mod float_cmp; mod float_equality_without_abs; mod identity_op; mod integer_division; +mod manual_midpoint; mod misrefactored_assign_op; mod modulo_arithmetic; mod modulo_one; @@ -24,6 +25,7 @@ mod verbose_bit_mask; pub(crate) mod arithmetic_side_effects; use clippy_config::Conf; +use clippy_utils::msrvs::Msrv; use rustc_hir::{Body, Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; @@ -834,10 +836,35 @@ declare_clippy_lint! { "explicit self-assignment" } +declare_clippy_lint! { + /// ### What it does + /// Checks for manual implementation of `midpoint`. + /// + /// ### Why is this bad? + /// Using `(x + y) / 2` might cause an overflow on the intermediate + /// addition result. + /// + /// ### Example + /// ```no_run + /// # let a: u32 = 0; + /// let c = (a + 10) / 2; + /// ``` + /// Use instead: + /// ```no_run + /// # let a: u32 = 0; + /// let c = u32::midpoint(a, 10); + /// ``` + #[clippy::version = "1.87.0"] + pub MANUAL_MIDPOINT, + pedantic, + "manual implementation of `midpoint` which can overflow" +} + pub struct Operators { arithmetic_context: numeric_arithmetic::Context, verbose_bit_mask_threshold: u64, modulo_arithmetic_allow_comparison_to_zero: bool, + msrv: Msrv, } impl Operators { pub fn new(conf: &'static Conf) -> Self { @@ -845,6 +872,7 @@ impl Operators { arithmetic_context: numeric_arithmetic::Context::default(), verbose_bit_mask_threshold: conf.verbose_bit_mask_threshold, modulo_arithmetic_allow_comparison_to_zero: conf.allow_comparison_to_zero, + msrv: conf.msrv.clone(), } } } @@ -876,6 +904,7 @@ impl_lint_pass!(Operators => [ NEEDLESS_BITWISE_BOOL, PTR_EQ, SELF_ASSIGNMENT, + MANUAL_MIDPOINT, ]); impl<'tcx> LateLintPass<'tcx> for Operators { @@ -893,6 +922,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators { identity_op::check(cx, e, op.node, lhs, rhs); needless_bitwise_bool::check(cx, e, op.node, lhs, rhs); ptr_eq::check(cx, e, op.node, lhs, rhs); + manual_midpoint::check(cx, e, op.node, lhs, rhs, &self.msrv); } self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs); bit_mask::check(cx, e, op.node, lhs, rhs); @@ -943,6 +973,8 @@ impl<'tcx> LateLintPass<'tcx> for Operators { fn check_body_post(&mut self, cx: &LateContext<'tcx>, b: &Body<'_>) { self.arithmetic_context.body_post(cx, b); } + + extract_msrv_attr!(LateContext); } fn macro_with_not_op(e: &Expr<'_>) -> bool { diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 8a7a7d006352..f9cf29cbdf46 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -19,7 +19,8 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { - 1,87,0 { OS_STR_DISPLAY } + 1,87,0 { OS_STR_DISPLAY, INT_MIDPOINT } + 1,85,0 { UINT_FLOAT_MIDPOINT } 1,84,0 { CONST_OPTION_AS_SLICE } 1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP } 1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP } diff --git a/tests/ui/manual_midpoint.fixed b/tests/ui/manual_midpoint.fixed new file mode 100644 index 000000000000..63116ced8438 --- /dev/null +++ b/tests/ui/manual_midpoint.fixed @@ -0,0 +1,74 @@ +#![warn(clippy::manual_midpoint)] + +macro_rules! mac { + ($a: expr, $b: expr) => { + ($a + $b) / 2 + }; +} + +macro_rules! add { + ($a: expr, $b: expr) => { + ($a + $b) + }; +} + +macro_rules! two { + () => { + 2 + }; +} + +#[clippy::msrv = "1.84"] +fn older_msrv() { + let a: u32 = 10; + let _ = (a + 5) / 2; +} + +#[clippy::msrv = "1.85"] +fn main() { + let a: u32 = 10; + let _ = u32::midpoint(a, 5); //~ ERROR: manual implementation of `midpoint` + + let f: f32 = 10.0; + let _ = f32::midpoint(f, 5.0); //~ ERROR: manual implementation of `midpoint` + + let _: u32 = 5 + u32::midpoint(8, 8) + 2; //~ ERROR: manual implementation of `midpoint` + let _: u32 = const { u32::midpoint(8, 8) }; //~ ERROR: manual implementation of `midpoint` + let _: f64 = const { f64::midpoint(8.0f64, 8.) }; //~ ERROR: manual implementation of `midpoint` + let _: u32 = u32::midpoint(u32::default(), u32::default()); //~ ERROR: manual implementation of `midpoint` + let _: u32 = u32::midpoint(two!(), two!()); //~ ERROR: manual implementation of `midpoint` + + // Do not lint in presence of an addition with more than 2 operands + let _: u32 = (10 + 20 + 30) / 2; + + // Do not lint if whole or part is coming from a macro + let _ = mac!(10, 20); + let _: u32 = add!(10u32, 20u32) / 2; + let _: u32 = (10 + 20) / two!(); + + // Do not lint if a literal is not present + let _ = (f + 5.0) / (1.0 + 1.0); + + // Do not lint on signed integer types + let i: i32 = 10; + let _ = (i + 5) / 2; + + // Do not lint on (x+1)/2 or (1+x)/2 as this looks more like a `div_ceil()` operation + let _ = (i + 1) / 2; + let _ = (1 + i) / 2; + + // But if we see (x+1.0)/2.0 or (x+1.0)/2.0, it is probably a midpoint operation + let _ = f32::midpoint(f, 1.0); //~ ERROR: manual implementation of `midpoint` + let _ = f32::midpoint(1.0, f); //~ ERROR: manual implementation of `midpoint` +} + +#[clippy::msrv = "1.86"] +fn older_signed_midpoint(i: i32) { + // Do not lint + let _ = (i + 10) / 2; +} + +#[clippy::msrv = "1.87"] +fn signed_midpoint(i: i32) { + let _ = i32::midpoint(i, 10); //~ ERROR: manual implementation of `midpoint` +} diff --git a/tests/ui/manual_midpoint.rs b/tests/ui/manual_midpoint.rs new file mode 100644 index 000000000000..47f1b88c78cd --- /dev/null +++ b/tests/ui/manual_midpoint.rs @@ -0,0 +1,74 @@ +#![warn(clippy::manual_midpoint)] + +macro_rules! mac { + ($a: expr, $b: expr) => { + ($a + $b) / 2 + }; +} + +macro_rules! add { + ($a: expr, $b: expr) => { + ($a + $b) + }; +} + +macro_rules! two { + () => { + 2 + }; +} + +#[clippy::msrv = "1.84"] +fn older_msrv() { + let a: u32 = 10; + let _ = (a + 5) / 2; +} + +#[clippy::msrv = "1.85"] +fn main() { + let a: u32 = 10; + let _ = (a + 5) / 2; //~ ERROR: manual implementation of `midpoint` + + let f: f32 = 10.0; + let _ = (f + 5.0) / 2.0; //~ ERROR: manual implementation of `midpoint` + + let _: u32 = 5 + (8 + 8) / 2 + 2; //~ ERROR: manual implementation of `midpoint` + let _: u32 = const { (8 + 8) / 2 }; //~ ERROR: manual implementation of `midpoint` + let _: f64 = const { (8.0f64 + 8.) / 2. }; //~ ERROR: manual implementation of `midpoint` + let _: u32 = (u32::default() + u32::default()) / 2; //~ ERROR: manual implementation of `midpoint` + let _: u32 = (two!() + two!()) / 2; //~ ERROR: manual implementation of `midpoint` + + // Do not lint in presence of an addition with more than 2 operands + let _: u32 = (10 + 20 + 30) / 2; + + // Do not lint if whole or part is coming from a macro + let _ = mac!(10, 20); + let _: u32 = add!(10u32, 20u32) / 2; + let _: u32 = (10 + 20) / two!(); + + // Do not lint if a literal is not present + let _ = (f + 5.0) / (1.0 + 1.0); + + // Do not lint on signed integer types + let i: i32 = 10; + let _ = (i + 5) / 2; + + // Do not lint on (x+1)/2 or (1+x)/2 as this looks more like a `div_ceil()` operation + let _ = (i + 1) / 2; + let _ = (1 + i) / 2; + + // But if we see (x+1.0)/2.0 or (x+1.0)/2.0, it is probably a midpoint operation + let _ = (f + 1.0) / 2.0; //~ ERROR: manual implementation of `midpoint` + let _ = (1.0 + f) / 2.0; //~ ERROR: manual implementation of `midpoint` +} + +#[clippy::msrv = "1.86"] +fn older_signed_midpoint(i: i32) { + // Do not lint + let _ = (i + 10) / 2; +} + +#[clippy::msrv = "1.87"] +fn signed_midpoint(i: i32) { + let _ = (i + 10) / 2; //~ ERROR: manual implementation of `midpoint` +} diff --git a/tests/ui/manual_midpoint.stderr b/tests/ui/manual_midpoint.stderr new file mode 100644 index 000000000000..3d588e2114df --- /dev/null +++ b/tests/ui/manual_midpoint.stderr @@ -0,0 +1,65 @@ +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:30:13 + | +LL | let _ = (a + 5) / 2; + | ^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(a, 5)` + | + = note: `-D clippy::manual-midpoint` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_midpoint)]` + +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:33:13 + | +LL | let _ = (f + 5.0) / 2.0; + | ^^^^^^^^^^^^^^^ help: use `f32::midpoint` instead: `f32::midpoint(f, 5.0)` + +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:35:22 + | +LL | let _: u32 = 5 + (8 + 8) / 2 + 2; + | ^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(8, 8)` + +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:36:26 + | +LL | let _: u32 = const { (8 + 8) / 2 }; + | ^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(8, 8)` + +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:37:26 + | +LL | let _: f64 = const { (8.0f64 + 8.) / 2. }; + | ^^^^^^^^^^^^^^^^^^ help: use `f64::midpoint` instead: `f64::midpoint(8.0f64, 8.)` + +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:38:18 + | +LL | let _: u32 = (u32::default() + u32::default()) / 2; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(u32::default(), u32::default())` + +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:39:18 + | +LL | let _: u32 = (two!() + two!()) / 2; + | ^^^^^^^^^^^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(two!(), two!())` + +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:61:13 + | +LL | let _ = (f + 1.0) / 2.0; + | ^^^^^^^^^^^^^^^ help: use `f32::midpoint` instead: `f32::midpoint(f, 1.0)` + +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:62:13 + | +LL | let _ = (1.0 + f) / 2.0; + | ^^^^^^^^^^^^^^^ help: use `f32::midpoint` instead: `f32::midpoint(1.0, f)` + +error: manual implementation of `midpoint` which can overflow + --> tests/ui/manual_midpoint.rs:73:13 + | +LL | let _ = (i + 10) / 2; + | ^^^^^^^^^^^^ help: use `i32::midpoint` instead: `i32::midpoint(i, 10)` + +error: aborting due to 10 previous errors + diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index 56b313244e36..f5a869cf2831 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -4,6 +4,7 @@ clippy::equatable_if_let, clippy::let_unit_value, clippy::redundant_locals, + clippy::manual_midpoint, clippy::manual_unwrap_or_default, clippy::manual_unwrap_or )] diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index 4a4bb141ed54..d48272e618ac 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -4,6 +4,7 @@ clippy::equatable_if_let, clippy::let_unit_value, clippy::redundant_locals, + clippy::manual_midpoint, clippy::manual_unwrap_or_default, clippy::manual_unwrap_or )] diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index f872ac991840..9eb41f81a539 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -1,5 +1,5 @@ error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:12:5 + --> tests/ui/option_if_let_else.rs:13:5 | LL | / if let Some(x) = string { LL | | @@ -13,19 +13,19 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:31:13 + --> tests/ui/option_if_let_else.rs:32:13 | LL | let _ = if let Some(s) = *string { s.len() } else { 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:33:13 + --> tests/ui/option_if_let_else.rs:34:13 | LL | let _ = if let Some(s) = &num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:35:13 + --> tests/ui/option_if_let_else.rs:36:13 | LL | let _ = if let Some(s) = &mut num { | _____________^ @@ -47,13 +47,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:42:13 + --> tests/ui/option_if_let_else.rs:43:13 | LL | let _ = if let Some(ref s) = num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:44:13 + --> tests/ui/option_if_let_else.rs:45:13 | LL | let _ = if let Some(mut s) = num { | _____________^ @@ -75,7 +75,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:51:13 + --> tests/ui/option_if_let_else.rs:52:13 | LL | let _ = if let Some(ref mut s) = num { | _____________^ @@ -97,7 +97,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:61:5 + --> tests/ui/option_if_let_else.rs:62:5 | LL | / if let Some(x) = arg { LL | | @@ -118,7 +118,7 @@ LL + }) | error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:75:13 + --> tests/ui/option_if_let_else.rs:76:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -131,7 +131,7 @@ LL | | }; | |_____^ help: try: `arg.map_or_else(side_effect, |x| x)` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:85:13 + --> tests/ui/option_if_let_else.rs:86:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -154,7 +154,7 @@ LL ~ }, |x| x * x * x * x); | error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:119:13 + --> tests/ui/option_if_let_else.rs:120:13 | LL | / if let Some(idx) = s.find('.') { LL | | @@ -165,7 +165,7 @@ LL | | } | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:131:5 + --> tests/ui/option_if_let_else.rs:132:5 | LL | / if let Ok(binding) = variable { LL | | @@ -189,13 +189,13 @@ LL + }) | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:156:13 + --> tests/ui/option_if_let_else.rs:157:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:167:13 + --> tests/ui/option_if_let_else.rs:168:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -217,13 +217,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:196:13 + --> tests/ui/option_if_let_else.rs:197:13 | LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:201:13 + --> tests/ui/option_if_let_else.rs:202:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -245,7 +245,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:241:13 + --> tests/ui/option_if_let_else.rs:242:13 | LL | let _ = match s { | _____________^ @@ -256,7 +256,7 @@ LL | | }; | |_____^ help: try: `s.map_or(1, |string| string.len())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:246:13 + --> tests/ui/option_if_let_else.rs:247:13 | LL | let _ = match Some(10) { | _____________^ @@ -267,7 +267,7 @@ LL | | }; | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:253:13 + --> tests/ui/option_if_let_else.rs:254:13 | LL | let _ = match res { | _____________^ @@ -278,7 +278,7 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:258:13 + --> tests/ui/option_if_let_else.rs:259:13 | LL | let _ = match res { | _____________^ @@ -289,13 +289,13 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:263:13 + --> tests/ui/option_if_let_else.rs:264:13 | LL | let _ = if let Ok(a) = res { a + 1 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:281:17 + --> tests/ui/option_if_let_else.rs:282:17 | LL | let _ = match initial { | _________________^ @@ -306,7 +306,7 @@ LL | | }; | |_________^ help: try: `initial.as_ref().map_or(42, |value| do_something(value))` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:289:17 + --> tests/ui/option_if_let_else.rs:290:17 | LL | let _ = match initial { | _________________^ @@ -317,7 +317,7 @@ LL | | }; | |_________^ help: try: `initial.as_mut().map_or(42, |value| do_something2(value))` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:313:24 + --> tests/ui/option_if_let_else.rs:314:24 | LL | let mut _hashmap = if let Some(hm) = &opt { | ________________________^ @@ -329,7 +329,7 @@ LL | | }; | |_____^ help: try: `opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone())` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:320:19 + --> tests/ui/option_if_let_else.rs:321:19 | LL | let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())` diff --git a/tests/ui/suspicious_operation_groupings.fixed b/tests/ui/suspicious_operation_groupings.fixed index 37054222bd62..fa680e537d30 100644 --- a/tests/ui/suspicious_operation_groupings.fixed +++ b/tests/ui/suspicious_operation_groupings.fixed @@ -1,7 +1,7 @@ //@compile-flags: -Zdeduplicate-diagnostics=yes #![warn(clippy::suspicious_operation_groupings)] -#![allow(dead_code, unused_parens, clippy::eq_op)] +#![allow(dead_code, unused_parens, clippy::eq_op, clippy::manual_midpoint)] struct Vec3 { x: f64, diff --git a/tests/ui/suspicious_operation_groupings.rs b/tests/ui/suspicious_operation_groupings.rs index f4d1c3c70b56..4ffee640e8bd 100644 --- a/tests/ui/suspicious_operation_groupings.rs +++ b/tests/ui/suspicious_operation_groupings.rs @@ -1,7 +1,7 @@ //@compile-flags: -Zdeduplicate-diagnostics=yes #![warn(clippy::suspicious_operation_groupings)] -#![allow(dead_code, unused_parens, clippy::eq_op)] +#![allow(dead_code, unused_parens, clippy::eq_op, clippy::manual_midpoint)] struct Vec3 { x: f64, From 60bf07a26c88b6ebd2522e5ae9cd1afcfa3887f4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Feb 2025 08:55:03 +1100 Subject: [PATCH 413/991] Adjust `ConstraintGraphDirection` methods. This facilitates the next commit. --- .../rustc_borrowck/src/constraints/graph.rs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/graph.rs b/compiler/rustc_borrowck/src/constraints/graph.rs index 9d500586f084..3f2064680ae9 100644 --- a/compiler/rustc_borrowck/src/constraints/graph.rs +++ b/compiler/rustc_borrowck/src/constraints/graph.rs @@ -23,8 +23,8 @@ pub(crate) type ReverseConstraintGraph = ConstraintGraph; /// Marker trait that controls whether a `R1: R2` constraint /// represents an edge `R1 -> R2` or `R2 -> R1`. pub(crate) trait ConstraintGraphDirection: Copy + 'static { - fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid; - fn end_region(c: &OutlivesConstraint<'_>) -> RegionVid; + fn start_region(sup: RegionVid, sub: RegionVid) -> RegionVid; + fn end_region(sup: RegionVid, sub: RegionVid) -> RegionVid; fn is_normal() -> bool; } @@ -36,12 +36,12 @@ pub(crate) trait ConstraintGraphDirection: Copy + 'static { pub(crate) struct Normal; impl ConstraintGraphDirection for Normal { - fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid { - c.sup + fn start_region(sup: RegionVid, _sub: RegionVid) -> RegionVid { + sup } - fn end_region(c: &OutlivesConstraint<'_>) -> RegionVid { - c.sub + fn end_region(_sup: RegionVid, sub: RegionVid) -> RegionVid { + sub } fn is_normal() -> bool { @@ -57,12 +57,12 @@ impl ConstraintGraphDirection for Normal { pub(crate) struct Reverse; impl ConstraintGraphDirection for Reverse { - fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid { - c.sub + fn start_region(_sup: RegionVid, sub: RegionVid) -> RegionVid { + sub } - fn end_region(c: &OutlivesConstraint<'_>) -> RegionVid { - c.sup + fn end_region(sup: RegionVid, _sub: RegionVid) -> RegionVid { + sup } fn is_normal() -> bool { @@ -84,7 +84,7 @@ impl ConstraintGraph { let mut next_constraints = IndexVec::from_elem(None, &set.outlives); for (idx, constraint) in set.outlives.iter_enumerated().rev() { - let head = &mut first_constraints[D::start_region(constraint)]; + let head = &mut first_constraints[D::start_region(constraint.sup, constraint.sub)]; let next = &mut next_constraints[idx]; debug_assert!(next.is_none()); *next = *head; @@ -207,7 +207,7 @@ impl<'a, 'tcx, D: ConstraintGraphDirection> Iterator for Successors<'a, 'tcx, D> type Item = RegionVid; fn next(&mut self) -> Option { - self.edges.next().map(|c| D::end_region(&c)) + self.edges.next().map(|c| D::end_region(c.sup, c.sub)) } } From ef1114a964bcb15ba5c60551f925d287eb153bb9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Apr 2024 12:44:11 +1000 Subject: [PATCH 414/991] Remove `NtPat`. The one notable test change is `tests/ui/macros/trace_faulty_macros.rs`. This commit removes the complicated `Interpolated` handling in `expected_expression_found` that results in a longer error message. But I think the new, shorter message is actually an improvement. The original complaint was in #71039, when the error message started with "error: expected expression, found `1 + 1`". That was confusing because `1 + 1` is an expression. Other than that, the reporter said "the whole error message is not too bad if you ignore the first line". Subsequently, extra complexity and wording was added to the error message. But I don't think the extra wording actually helps all that much. In particular, it still says of the `1+1` that "this is expected to be expression". This repeats the problem from the original complaint! This commit removes the extra complexity, reverting to a simpler error message. This is primarily because the traversal is a pain without `Interpolated` tokens. Nonetheless, I think the error message is *improved*. It now starts with "expected expression, found `pat` metavariable", which is much clearer and the real problem. It also doesn't say anything specific about `1+1`, which is good, because the `1+1` isn't really relevant to the error -- it's the `$e:pat` that's important. --- compiler/rustc_ast/src/ast_traits.rs | 2 - compiler/rustc_ast/src/mut_visit.rs | 1 - compiler/rustc_ast/src/token.rs | 5 -- compiler/rustc_ast/src/tokenstream.rs | 1 - compiler/rustc_expand/src/mbe/transcribe.rs | 18 +++++-- .../rustc_parse/src/parser/diagnostics.rs | 52 +------------------ compiler/rustc_parse/src/parser/item.rs | 8 +-- compiler/rustc_parse/src/parser/mod.rs | 4 +- .../rustc_parse/src/parser/nonterminal.rs | 24 +++++---- compiler/rustc_parse/src/parser/pat.rs | 37 ++++++++++--- tests/ui/macros/trace_faulty_macros.rs | 2 +- tests/ui/macros/trace_faulty_macros.stderr | 13 ++--- .../issue-65122-mac-invoc-in-mut-patterns.rs | 2 +- ...sue-65122-mac-invoc-in-mut-patterns.stderr | 4 +- tests/ui/parser/mut-patterns.rs | 2 +- tests/ui/parser/mut-patterns.stderr | 4 +- 16 files changed, 77 insertions(+), 102 deletions(-) diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 346edc87c86b..8b94d65c44ec 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -202,7 +202,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtItem(item) => item.tokens(), Nonterminal::NtStmt(stmt) => stmt.tokens(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(), - Nonterminal::NtPat(pat) => pat.tokens(), Nonterminal::NtMeta(attr_item) => attr_item.tokens(), Nonterminal::NtPath(path) => path.tokens(), Nonterminal::NtBlock(block) => block.tokens(), @@ -213,7 +212,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtItem(item) => item.tokens_mut(), Nonterminal::NtStmt(stmt) => stmt.tokens_mut(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(), - Nonterminal::NtPat(pat) => pat.tokens_mut(), Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(), Nonterminal::NtPath(path) => path.tokens_mut(), Nonterminal::NtBlock(block) => block.tokens_mut(), diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 40b29fdba250..6ebe52738b9c 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -905,7 +905,6 @@ fn visit_nonterminal(vis: &mut T, nt: &mut token::Nonterminal) { vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item") }) }), - token::NtPat(pat) => vis.visit_pat(pat), token::NtExpr(expr) => vis.visit_expr(expr), token::NtLiteral(expr) => vis.visit_expr(expr), token::NtMeta(item) => { diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 97d121909f8d..ff8a68ff711e 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -659,7 +659,6 @@ impl Token { | NtExpr(..) | NtLiteral(..) | NtMeta(..) - | NtPat(..) | NtPath(..) ), OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( @@ -1075,7 +1074,6 @@ pub enum Nonterminal { NtItem(P), NtBlock(P), NtStmt(P), - NtPat(P), NtExpr(P), NtLiteral(P), /// Stuff inside brackets for attributes @@ -1172,7 +1170,6 @@ impl Nonterminal { NtItem(item) => item.span, NtBlock(block) => block.span, NtStmt(stmt) => stmt.span, - NtPat(pat) => pat.span, NtExpr(expr) | NtLiteral(expr) => expr.span, NtMeta(attr_item) => attr_item.span(), NtPath(path) => path.span, @@ -1184,7 +1181,6 @@ impl Nonterminal { NtItem(..) => "item", NtBlock(..) => "block", NtStmt(..) => "statement", - NtPat(..) => "pattern", NtExpr(..) => "expression", NtLiteral(..) => "literal", NtMeta(..) => "attribute", @@ -1209,7 +1205,6 @@ impl fmt::Debug for Nonterminal { NtItem(..) => f.pad("NtItem(..)"), NtBlock(..) => f.pad("NtBlock(..)"), NtStmt(..) => f.pad("NtStmt(..)"), - NtPat(..) => f.pad("NtPat(..)"), NtExpr(..) => f.pad("NtExpr(..)"), NtLiteral(..) => f.pad("NtLiteral(..)"), NtMeta(..) => f.pad("NtMeta(..)"), diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 1123ea3a449b..2b4c818fc322 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -468,7 +468,6 @@ impl TokenStream { TokenStream::token_alone(token::Semi, stmt.span) } Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt), - Nonterminal::NtPat(pat) => TokenStream::from_ast(pat), Nonterminal::NtMeta(attr) => TokenStream::from_ast(attr), Nonterminal::NtPath(path) => TokenStream::from_ast(path), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr), diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 7fe9fa7937d9..79f65a8c8b56 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -279,9 +279,9 @@ pub(super) fn transcribe<'a>( if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) { // We wrap the tokens in invisible delimiters, unless they are already wrapped // in invisible delimiters with the same `MetaVarKind`. Because some proc - // macros can't multiple layers of invisible delimiters of the same + // macros can't handle multiple layers of invisible delimiters of the same // `MetaVarKind`. This loses some span info, though it hopefully won't matter. - let mut mk_delimited = |mv_kind, mut stream: TokenStream| { + let mut mk_delimited = |mk_span, mv_kind, mut stream: TokenStream| { if stream.len() == 1 { let tree = stream.iter().next().unwrap(); if let TokenTree::Delimited(_, _, delim, inner) = tree @@ -295,6 +295,7 @@ pub(super) fn transcribe<'a>( // Emit as a token stream within `Delimiter::Invisible` to maintain // parsing priorities. marker.visit_span(&mut sp); + with_metavar_spans(|mspans| mspans.insert(mk_span, sp)); // Both the open delim and close delim get the same span, which covers the // `$foo` in the decl macro RHS. TokenTree::Delimited( @@ -322,12 +323,21 @@ pub(super) fn transcribe<'a>( let kind = token::NtLifetime(*ident, *is_raw); TokenTree::token_alone(kind, sp) } + MatchedSingle(ParseNtResult::Pat(pat, pat_kind)) => mk_delimited( + pat.span, + MetaVarKind::Pat(*pat_kind), + TokenStream::from_ast(pat), + ), MatchedSingle(ParseNtResult::Ty(ty)) => { let is_path = matches!(&ty.kind, TyKind::Path(None, _path)); - mk_delimited(MetaVarKind::Ty { is_path }, TokenStream::from_ast(ty)) + mk_delimited( + ty.span, + MetaVarKind::Ty { is_path }, + TokenStream::from_ast(ty), + ) } MatchedSingle(ParseNtResult::Vis(vis)) => { - mk_delimited(MetaVarKind::Vis, TokenStream::from_ast(vis)) + mk_delimited(vis.span, MetaVarKind::Vis, TokenStream::from_ast(vis)) } MatchedSingle(ParseNtResult::Nt(nt)) => { // Other variables are emitted into the output stream as groups with diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 67abc2d53940..5291345a29dc 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1,17 +1,15 @@ use std::mem::take; use std::ops::{Deref, DerefMut}; -use std::sync::Arc; use ast::token::IdentIsRaw; use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Lit, LitKind, Token, TokenKind}; -use rustc_ast::tokenstream::AttrTokenTree; use rustc_ast::util::parser::AssocOp; use rustc_ast::{ AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block, - BlockCheckMode, Expr, ExprKind, GenericArg, Generics, HasTokens, Item, ItemKind, Param, Pat, - PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind, + BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, PatKind, + Path, PathSegment, QSelf, Recovered, Ty, TyKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; @@ -2400,52 +2398,6 @@ impl<'a> Parser<'a> { err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } err.span_label(span, "expected expression"); - - // Walk the chain of macro expansions for the current token to point at how the original - // code was interpreted. This helps the user realize when a macro argument of one type is - // later reinterpreted as a different type, like `$x:expr` being reinterpreted as `$x:pat` - // in a subsequent macro invocation (#71039). - let mut tok = self.token.clone(); - let mut labels = vec![]; - while let TokenKind::Interpolated(nt) = &tok.kind { - let tokens = nt.tokens(); - labels.push(Arc::clone(nt)); - if let Some(tokens) = tokens - && let tokens = tokens.to_attr_token_stream() - && let tokens = tokens.0.deref() - && let [AttrTokenTree::Token(token, _)] = &tokens[..] - { - tok = token.clone(); - } else { - break; - } - } - let mut iter = labels.into_iter().peekable(); - let mut show_link = false; - while let Some(nt) = iter.next() { - let descr = nt.descr(); - if let Some(next) = iter.peek() { - let next_descr = next.descr(); - if next_descr != descr { - err.span_label(next.use_span(), format!("this is expected to be {next_descr}")); - err.span_label( - nt.use_span(), - format!( - "this is interpreted as {}, but it is expected to be {}", - next_descr, descr, - ), - ); - show_link = true; - } - } - } - if show_link { - err.note( - "when forwarding a matched fragment to another macro-by-example, matchers in the \ - second macro will see an opaque AST of the fragment type, not the underlying \ - tokens", - ); - } err } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index c923717ecaf2..5765a5b5315b 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -4,7 +4,7 @@ use std::mem; use ast::token::IdentIsRaw; use rustc_ast::ast::*; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Delimiter, TokenKind}; +use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::util::case::Case; use rustc_ast::{self as ast}; @@ -3071,8 +3071,10 @@ impl<'a> Parser<'a> { fn is_named_param(&self) -> bool { let offset = match &self.token.kind { - token::Interpolated(nt) => match &**nt { - token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon), + token::OpenDelim(Delimiter::Invisible(origin)) => match origin { + InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => { + return self.check_noexpect_past_close_delim(&token::Colon); + } _ => 0, }, token::BinOp(token::And) | token::AndAnd => 1, diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 80a33a760059..ca9671f90fee 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -24,7 +24,8 @@ pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma}; use path::PathStyle; use rustc_ast::ptr::P; use rustc_ast::token::{ - self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, Token, TokenKind, + self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, NtPatKind, Token, + TokenKind, }; use rustc_ast::tokenstream::{AttrsTarget, Spacing, TokenStream, TokenTree}; use rustc_ast::util::case::Case; @@ -1745,6 +1746,7 @@ pub enum ParseNtResult { Tt(TokenTree), Ident(Ident, IdentIsRaw), Lifetime(Ident, IdentIsRaw), + Pat(P, NtPatKind), Ty(P), Vis(P), diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index f202f85752e1..39a0d4151ec6 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -49,7 +49,6 @@ impl<'a> Parser<'a> { fn nt_may_be_ident(nt: &Nonterminal) -> bool { match nt { NtStmt(_) - | NtPat(_) | NtExpr(_) | NtLiteral(_) // `true`, `false` | NtMeta(_) @@ -99,7 +98,7 @@ impl<'a> Parser<'a> { token::NtLifetime(..) => true, token::Interpolated(nt) => match &**nt { NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, - NtItem(_) | NtPat(_) | NtMeta(_) | NtPath(_) => false, + NtItem(_) | NtMeta(_) | NtPath(_) => false, }, token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k { MetaVarKind::Block @@ -170,15 +169,18 @@ impl<'a> Parser<'a> { } }, NonterminalKind::Pat(pat_kind) => { - NtPat(self.collect_tokens_no_attrs(|this| match pat_kind { - PatParam { .. } => this.parse_pat_no_top_alt(None, None), - PatWithOr => this.parse_pat_no_top_guard( - None, - RecoverComma::No, - RecoverColon::No, - CommaRecoveryMode::EitherTupleOrPipe, - ), - })?) + return Ok(ParseNtResult::Pat( + self.collect_tokens_no_attrs(|this| match pat_kind { + PatParam { .. } => this.parse_pat_no_top_alt(None, None), + PatWithOr => this.parse_pat_no_top_guard( + None, + RecoverComma::No, + RecoverColon::No, + CommaRecoveryMode::EitherTupleOrPipe, + ), + })?, + pat_kind, + )); } NonterminalKind::Expr(_) => NtExpr(self.parse_expr_force_collect()?), NonterminalKind::Literal => { diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 8ce749ec8141..40f2e228b24e 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -2,7 +2,8 @@ use std::ops::Bound; use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::ptr::P; -use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token}; +use rustc_ast::token::NtPatKind::*; +use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, MetaVarKind, Token}; use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{ @@ -30,7 +31,7 @@ use crate::errors::{ UnexpectedVertVertInPattern, WrapInParens, }; use crate::parser::expr::{DestructuredFloat, could_be_unclosed_char_literal}; -use crate::{exp, maybe_recover_from_interpolated_ty_qpath, maybe_whole}; +use crate::{exp, maybe_recover_from_interpolated_ty_qpath}; #[derive(PartialEq, Copy, Clone)] pub enum Expected { @@ -689,6 +690,27 @@ impl<'a> Parser<'a> { PatVisitor { parser: self, stmt, arm: None, field: None }.visit_stmt(stmt); } + fn eat_metavar_pat(&mut self) -> Option> { + // Must try both kinds of pattern nonterminals. + if let Some(pat) = self.eat_metavar_seq_with_matcher( + |mv_kind| matches!(mv_kind, MetaVarKind::Pat(PatParam { .. })), + |this| this.parse_pat_no_top_alt(None, None), + ) { + Some(pat) + } else if let Some(pat) = self.eat_metavar_seq(MetaVarKind::Pat(PatWithOr), |this| { + this.parse_pat_no_top_guard( + None, + RecoverComma::No, + RecoverColon::No, + CommaRecoveryMode::EitherTupleOrPipe, + ) + }) { + Some(pat) + } else { + None + } + } + /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are /// allowed). fn parse_pat_with_range_pat( @@ -698,7 +720,10 @@ impl<'a> Parser<'a> { syntax_loc: Option, ) -> PResult<'a, P> { maybe_recover_from_interpolated_ty_qpath!(self, true); - maybe_whole!(self, NtPat, |pat| pat); + + if let Some(pat) = self.eat_metavar_pat() { + return Ok(pat); + } let mut lo = self.token.span; @@ -1043,10 +1068,8 @@ impl<'a> Parser<'a> { self.recover_additional_muts(); // Make sure we don't allow e.g. `let mut $p;` where `$p:pat`. - if let token::Interpolated(nt) = &self.token.kind { - if let token::NtPat(..) = &**nt { - self.expected_ident_found_err().emit(); - } + if let Some(MetaVarKind::Pat(_)) = self.token.is_metavar_seq() { + self.expected_ident_found_err().emit(); } // Parse the pattern we hope to be an identifier. diff --git a/tests/ui/macros/trace_faulty_macros.rs b/tests/ui/macros/trace_faulty_macros.rs index 87036bb9c6f7..e0cbbd8f5c9e 100644 --- a/tests/ui/macros/trace_faulty_macros.rs +++ b/tests/ui/macros/trace_faulty_macros.rs @@ -46,7 +46,7 @@ macro_rules! test { (let $p:pat = $e:expr) => {test!(($p,$e))}; // this should be expr // vvv - (($p:pat, $e:pat)) => {let $p = $e;}; //~ ERROR expected expression, found pattern `1+1` + (($p:pat, $e:pat)) => {let $p = $e;}; //~ ERROR expected expression, found `pat` metavariable } fn foo() { diff --git a/tests/ui/macros/trace_faulty_macros.stderr b/tests/ui/macros/trace_faulty_macros.stderr index 10ad3faab161..73fed66e6190 100644 --- a/tests/ui/macros/trace_faulty_macros.stderr +++ b/tests/ui/macros/trace_faulty_macros.stderr @@ -50,7 +50,7 @@ LL | my_recursive_macro!(); = note: expanding `my_recursive_macro! { }` = note: to `my_recursive_macro! ();` -error: expected expression, found pattern `A { a : a, b : 0, c : _, .. }` +error: expected expression, found `pat` metavariable --> $DIR/trace_faulty_macros.rs:16:9 | LL | $a @@ -69,22 +69,15 @@ LL | #[derive(Debug)] LL | fn use_derive_macro_as_attr() {} | -------------------------------- not a `struct`, `enum` or `union` -error: expected expression, found pattern `1+1` +error: expected expression, found `pat` metavariable --> $DIR/trace_faulty_macros.rs:49:37 | -LL | (let $p:pat = $e:expr) => {test!(($p,$e))}; - | -- this is interpreted as expression, but it is expected to be pattern -... LL | (($p:pat, $e:pat)) => {let $p = $e;}; | ^^ expected expression ... LL | test!(let x = 1+1); - | ------------------ - | | | - | | this is expected to be expression - | in this macro invocation + | ------------------ in this macro invocation | - = note: when forwarding a matched fragment to another macro-by-example, matchers in the second macro will see an opaque AST of the fragment type, not the underlying tokens = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) note: trace_macro diff --git a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs index 30f3781bf774..1a0833ebb2f6 100644 --- a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs +++ b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs @@ -12,7 +12,7 @@ macro_rules! mac2 { ($eval:pat) => { let mut $eval = (); //~^ ERROR `mut` must be followed by a named binding - //~| ERROR expected identifier, found `does_not_exist!()` + //~| ERROR expected identifier, found metavariable }; } diff --git a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr index dda37d83282c..59e1b64686b4 100644 --- a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr +++ b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr @@ -15,11 +15,11 @@ LL - let mut $eval = (); LL + let $eval = (); | -error: expected identifier, found `does_not_exist!()` +error: expected identifier, found metavariable --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:13:17 | LL | let mut $eval = (); - | ^^^^^ expected identifier + | ^^^^^ expected identifier, found metavariable ... LL | mac2! { does_not_exist!() } | --------------------------- in this macro invocation diff --git a/tests/ui/parser/mut-patterns.rs b/tests/ui/parser/mut-patterns.rs index 45968a516e3d..ed33968c627e 100644 --- a/tests/ui/parser/mut-patterns.rs +++ b/tests/ui/parser/mut-patterns.rs @@ -45,7 +45,7 @@ pub fn main() { // Make sure we don't accidentally allow `mut $p` where `$p:pat`. macro_rules! foo { ($p:pat) => { - let mut $p = 0; //~ ERROR expected identifier, found `x` + let mut $p = 0; //~ ERROR expected identifier, found metavariable } } foo!(x); diff --git a/tests/ui/parser/mut-patterns.stderr b/tests/ui/parser/mut-patterns.stderr index 43f6a344bf39..9dda2499f03c 100644 --- a/tests/ui/parser/mut-patterns.stderr +++ b/tests/ui/parser/mut-patterns.stderr @@ -158,11 +158,11 @@ LL - let mut W(mut a, W(b, W(ref c, W(d, B { box f })))) LL + let W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f })))) | -error: expected identifier, found `x` +error: expected identifier, found metavariable --> $DIR/mut-patterns.rs:48:21 | LL | let mut $p = 0; - | ^^ expected identifier + | ^^ expected identifier, found metavariable ... LL | foo!(x); | ------- in this macro invocation From 7ea59e053bed52249ba8f42cbdbc7301312197e3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Apr 2024 16:22:02 +1000 Subject: [PATCH 415/991] Remove `NtMeta`. Note: there was an existing code path involving `Interpolated` in `MetaItem::from_tokens` that was dead. This commit transfers that to the new form, but puts an `unreachable!` call inside it. --- compiler/rustc_ast/src/ast_traits.rs | 2 - compiler/rustc_ast/src/attr/mod.rs | 12 +++++- compiler/rustc_ast/src/mut_visit.rs | 6 --- compiler/rustc_ast/src/token.rs | 15 +++----- compiler/rustc_ast/src/tokenstream.rs | 1 - compiler/rustc_attr_parsing/src/parser.rs | 9 ----- compiler/rustc_expand/src/mbe/transcribe.rs | 8 ++++ compiler/rustc_parse/messages.ftl | 2 +- compiler/rustc_parse/src/errors.rs | 2 +- compiler/rustc_parse/src/parser/attr.rs | 38 +++++++++++-------- compiler/rustc_parse/src/parser/mod.rs | 1 + .../rustc_parse/src/parser/nonterminal.rs | 11 +++--- tests/ui/attributes/nonterminal-expansion.rs | 2 +- .../attributes/nonterminal-expansion.stderr | 2 +- .../cfg-attr-syntax-validation.rs | 4 +- .../cfg-attr-syntax-validation.stderr | 4 +- tests/ui/parser/attribute/attr-bad-meta-4.rs | 4 +- .../parser/attribute/attr-bad-meta-4.stderr | 4 +- .../parser/attribute/attr-unquoted-ident.rs | 2 +- .../attribute/attr-unquoted-ident.stderr | 2 +- 20 files changed, 67 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 8b94d65c44ec..30b8216df879 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -202,7 +202,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtItem(item) => item.tokens(), Nonterminal::NtStmt(stmt) => stmt.tokens(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(), - Nonterminal::NtMeta(attr_item) => attr_item.tokens(), Nonterminal::NtPath(path) => path.tokens(), Nonterminal::NtBlock(block) => block.tokens(), } @@ -212,7 +211,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtItem(item) => item.tokens_mut(), Nonterminal::NtStmt(stmt) => stmt.tokens_mut(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(), - Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(), Nonterminal::NtPath(path) => path.tokens_mut(), Nonterminal::NtBlock(block) => block.tokens_mut(), } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index df2f4b887124..be2e897e460c 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -14,7 +14,7 @@ use crate::ast::{ PathSegment, Safety, }; use crate::ptr::P; -use crate::token::{self, CommentKind, Delimiter, Token}; +use crate::token::{self, CommentKind, Delimiter, InvisibleOrigin, MetaVarKind, Token}; use crate::tokenstream::{ DelimSpan, LazyAttrTokenStream, Spacing, TokenStream, TokenStreamIter, TokenTree, }; @@ -406,10 +406,18 @@ impl MetaItem { Path { span, segments, tokens: None } } Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt { - token::Nonterminal::NtMeta(item) => return item.meta(item.path.span), token::Nonterminal::NtPath(path) => (**path).clone(), _ => return None, }, + Some(TokenTree::Delimited( + _span, + _spacing, + Delimiter::Invisible(InvisibleOrigin::MetaVar(MetaVarKind::Meta { .. })), + _stream, + )) => { + // This path is currently unreachable in the test suite. + unreachable!() + } Some(TokenTree::Token( Token { kind: token::OpenDelim(_) | token::CloseDelim(_), .. }, _, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 6ebe52738b9c..27fab2a02ed8 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -907,12 +907,6 @@ fn visit_nonterminal(vis: &mut T, nt: &mut token::Nonterminal) { }), token::NtExpr(expr) => vis.visit_expr(expr), token::NtLiteral(expr) => vis.visit_expr(expr), - token::NtMeta(item) => { - let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut(); - vis.visit_path(path); - visit_attr_args(vis, args); - visit_lazy_tts(vis, tokens); - } token::NtPath(path) => vis.visit_path(path), } } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index ff8a68ff711e..ff590df0d680 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -90,7 +90,10 @@ pub enum MetaVarKind { Ident, Lifetime, Literal, - Meta, + Meta { + /// Will `AttrItem::meta` succeed on this, if reparsed? + has_meta_form: bool, + }, Path, Vis, TT, @@ -110,7 +113,7 @@ impl fmt::Display for MetaVarKind { MetaVarKind::Ident => sym::ident, MetaVarKind::Lifetime => sym::lifetime, MetaVarKind::Literal => sym::literal, - MetaVarKind::Meta => sym::meta, + MetaVarKind::Meta { .. } => sym::meta, MetaVarKind::Path => sym::path, MetaVarKind::Vis => sym::vis, MetaVarKind::TT => sym::tt, @@ -658,13 +661,12 @@ impl Token { matches!(&**nt, | NtExpr(..) | NtLiteral(..) - | NtMeta(..) | NtPath(..) ), OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( MetaVarKind::Expr { .. } | MetaVarKind::Literal | - MetaVarKind::Meta | + MetaVarKind::Meta { .. } | MetaVarKind::Pat(_) | MetaVarKind::Path | MetaVarKind::Ty { .. } @@ -1076,8 +1078,6 @@ pub enum Nonterminal { NtStmt(P), NtExpr(P), NtLiteral(P), - /// Stuff inside brackets for attributes - NtMeta(P), NtPath(P), } @@ -1171,7 +1171,6 @@ impl Nonterminal { NtBlock(block) => block.span, NtStmt(stmt) => stmt.span, NtExpr(expr) | NtLiteral(expr) => expr.span, - NtMeta(attr_item) => attr_item.span(), NtPath(path) => path.span, } } @@ -1183,7 +1182,6 @@ impl Nonterminal { NtStmt(..) => "statement", NtExpr(..) => "expression", NtLiteral(..) => "literal", - NtMeta(..) => "attribute", NtPath(..) => "path", } } @@ -1207,7 +1205,6 @@ impl fmt::Debug for Nonterminal { NtStmt(..) => f.pad("NtStmt(..)"), NtExpr(..) => f.pad("NtExpr(..)"), NtLiteral(..) => f.pad("NtLiteral(..)"), - NtMeta(..) => f.pad("NtMeta(..)"), NtPath(..) => f.pad("NtPath(..)"), } } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 2b4c818fc322..489b5ad1a778 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -468,7 +468,6 @@ impl TokenStream { TokenStream::token_alone(token::Semi, stmt.span) } Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt), - Nonterminal::NtMeta(attr) => TokenStream::from_ast(attr), Nonterminal::NtPath(path) => TokenStream::from_ast(path), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr), } diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index b6d66af4466e..2604188bca24 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -481,15 +481,6 @@ impl<'a> MetaItemListParserContext<'a> { self.inside_delimiters.peek() { match &**nt { - // or maybe a full nt meta including the path but we return immediately - token::Nonterminal::NtMeta(item) => { - self.inside_delimiters.next(); - - return Some(MetaItemOrLitParser::MetaItemParser(MetaItemParser { - path: PathParser::Ast(&item.path), - args: ArgParser::from_attr_args(&item.args, self.dcx), - })); - } // an already interpolated path from a macro expansion is a path, no need to parse // one from tokens token::Nonterminal::NtPath(path) => { diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 79f65a8c8b56..3f2d8b282609 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -336,6 +336,14 @@ pub(super) fn transcribe<'a>( TokenStream::from_ast(ty), ) } + MatchedSingle(ParseNtResult::Meta(attr_item)) => { + let has_meta_form = attr_item.meta_kind().is_some(); + mk_delimited( + attr_item.span(), + MetaVarKind::Meta { has_meta_form }, + TokenStream::from_ast(attr_item), + ) + } MatchedSingle(ParseNtResult::Vis(vis)) => { mk_delimited(vis.span, MetaVarKind::Vis, TokenStream::from_ast(vis)) } diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 563081c7240c..1d5b59421706 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -424,7 +424,7 @@ parse_invalid_logical_operator = `{$incorrect}` is not a logical operator .use_amp_amp_for_conjunction = use `&&` to perform logical conjunction .use_pipe_pipe_for_disjunction = use `||` to perform logical disjunction -parse_invalid_meta_item = expected unsuffixed literal, found `{$token}` +parse_invalid_meta_item = expected unsuffixed literal, found {$descr} .quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal parse_invalid_offset_of = offset_of expects dot-separated field and variant names diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 173c68b3a722..fc7a3323fc11 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1024,7 +1024,7 @@ pub(crate) struct SuffixedLiteralInAttribute { pub(crate) struct InvalidMetaItem { #[primary_span] pub span: Span, - pub token: Token, + pub descr: String, #[subdiagnostic] pub quote_ident_sugg: Option, } diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 2691e6f56d68..98fdd35190d8 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -1,4 +1,6 @@ -use rustc_ast::{self as ast, Attribute, attr, token}; +use rustc_ast as ast; +use rustc_ast::token::{self, MetaVarKind}; +use rustc_ast::{Attribute, attr}; use rustc_errors::codes::*; use rustc_errors::{Diag, PResult}; use rustc_span::{BytePos, Span}; @@ -9,7 +11,7 @@ use super::{ AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, ParserRange, PathStyle, Trailing, UsePreAttrPos, }; -use crate::{errors, exp, fluent_generated as fluent, maybe_whole}; +use crate::{errors, exp, fluent_generated as fluent}; // Public for rustfmt usage #[derive(Debug)] @@ -269,7 +271,12 @@ impl<'a> Parser<'a> { /// PATH `=` UNSUFFIXED_LIT /// The delimiters or `=` are still put into the resulting token stream. pub fn parse_attr_item(&mut self, force_collect: ForceCollect) -> PResult<'a, ast::AttrItem> { - maybe_whole!(self, NtMeta, |attr| attr.into_inner()); + if let Some(item) = self.eat_metavar_seq_with_matcher( + |mv_kind| matches!(mv_kind, MetaVarKind::Meta { .. }), + |this| this.parse_attr_item(force_collect), + ) { + return Ok(item); + } // Attr items don't have attributes. self.collect_tokens(None, AttrWrapper::empty(), force_collect, |this, _empty_attrs| { @@ -396,18 +403,17 @@ impl<'a> Parser<'a> { &mut self, unsafe_allowed: AllowLeadingUnsafe, ) -> PResult<'a, ast::MetaItem> { - // We can't use `maybe_whole` here because it would bump in the `None` - // case, which we don't want. - if let token::Interpolated(nt) = &self.token.kind - && let token::NtMeta(attr_item) = &**nt - { - match attr_item.meta(attr_item.path.span) { - Some(meta) => { - self.bump(); - return Ok(meta); - } - None => self.unexpected()?, - } + if let Some(MetaVarKind::Meta { has_meta_form }) = self.token.is_metavar_seq() { + return if has_meta_form { + let attr_item = self + .eat_metavar_seq(MetaVarKind::Meta { has_meta_form: true }, |this| { + this.parse_attr_item(ForceCollect::No) + }) + .unwrap(); + Ok(attr_item.meta(attr_item.path.span).unwrap()) + } else { + self.unexpected_any() + }; } let lo = self.token.span; @@ -464,7 +470,7 @@ impl<'a> Parser<'a> { let mut err = errors::InvalidMetaItem { span: self.token.span, - token: self.token.clone(), + descr: super::token_descr(&self.token), quote_ident_sugg: None, }; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index ca9671f90fee..3b3c2e6137d4 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1748,6 +1748,7 @@ pub enum ParseNtResult { Lifetime(Ident, IdentIsRaw), Pat(P, NtPatKind), Ty(P), + Meta(P), Vis(P), /// This variant will eventually be removed, along with `Token::Interpolate`. diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 39a0d4151ec6..d4e4d5580327 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -32,7 +32,7 @@ impl<'a> Parser<'a> { | MetaVarKind::Expr { .. } | MetaVarKind::Ty { .. } | MetaVarKind::Literal // `true`, `false` - | MetaVarKind::Meta + | MetaVarKind::Meta { .. } | MetaVarKind::Path => true, MetaVarKind::Item @@ -51,7 +51,6 @@ impl<'a> Parser<'a> { NtStmt(_) | NtExpr(_) | NtLiteral(_) // `true`, `false` - | NtMeta(_) | NtPath(_) => true, NtItem(_) | NtBlock(_) => false, @@ -98,7 +97,7 @@ impl<'a> Parser<'a> { token::NtLifetime(..) => true, token::Interpolated(nt) => match &**nt { NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, - NtItem(_) | NtMeta(_) | NtPath(_) => false, + NtItem(_) | NtPath(_) => false, }, token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k { MetaVarKind::Block @@ -108,7 +107,7 @@ impl<'a> Parser<'a> { MetaVarKind::Item | MetaVarKind::Pat(_) | MetaVarKind::Ty { .. } - | MetaVarKind::Meta + | MetaVarKind::Meta { .. } | MetaVarKind::Path | MetaVarKind::Vis => false, MetaVarKind::Lifetime | MetaVarKind::Ident | MetaVarKind::TT => { @@ -207,7 +206,9 @@ impl<'a> Parser<'a> { NonterminalKind::Path => { NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?)) } - NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(ForceCollect::Yes)?)), + NonterminalKind::Meta => { + return Ok(ParseNtResult::Meta(P(self.parse_attr_item(ForceCollect::Yes)?))); + } NonterminalKind::Vis => { return Ok(ParseNtResult::Vis(P(self.collect_tokens_no_attrs(|this| { this.parse_visibility(FollowedByType::Yes) diff --git a/tests/ui/attributes/nonterminal-expansion.rs b/tests/ui/attributes/nonterminal-expansion.rs index 5ea30bb8627b..83c8f00999a7 100644 --- a/tests/ui/attributes/nonterminal-expansion.rs +++ b/tests/ui/attributes/nonterminal-expansion.rs @@ -5,7 +5,7 @@ macro_rules! pass_nonterminal { ($n:expr) => { #[repr(align($n))] - //~^ ERROR expected unsuffixed literal, found `n!()` + //~^ ERROR expected unsuffixed literal, found expression `n!()` //~^^ ERROR incorrect `repr(align)` attribute format: `align` expects a literal integer as argument [E0693] struct S; }; diff --git a/tests/ui/attributes/nonterminal-expansion.stderr b/tests/ui/attributes/nonterminal-expansion.stderr index cce5c453d520..8a85731bd5a1 100644 --- a/tests/ui/attributes/nonterminal-expansion.stderr +++ b/tests/ui/attributes/nonterminal-expansion.stderr @@ -1,4 +1,4 @@ -error: expected unsuffixed literal, found `n!()` +error: expected unsuffixed literal, found expression `n!()` --> $DIR/nonterminal-expansion.rs:7:22 | LL | #[repr(align($n))] diff --git a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs index d88528124920..9a041557c7cc 100644 --- a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs +++ b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs @@ -28,8 +28,8 @@ struct S9; macro_rules! generate_s10 { ($expr: expr) => { #[cfg(feature = $expr)] - //~^ ERROR expected unsuffixed literal, found `concat!("nonexistent")` - //~| ERROR expected unsuffixed literal, found `concat!("nonexistent")` + //~^ ERROR expected unsuffixed literal, found expression `concat!("nonexistent")` + //~| ERROR expected unsuffixed literal, found expression `concat!("nonexistent")` struct S10; } } diff --git a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr index 3dd0823389cd..21a3712d9391 100644 --- a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr @@ -54,7 +54,7 @@ LL | #[cfg(a = b"hi")] | | | help: consider removing the prefix -error: expected unsuffixed literal, found `concat!("nonexistent")` +error: expected unsuffixed literal, found expression `concat!("nonexistent")` --> $DIR/cfg-attr-syntax-validation.rs:30:25 | LL | #[cfg(feature = $expr)] @@ -65,7 +65,7 @@ LL | generate_s10!(concat!("nonexistent")); | = note: this error originates in the macro `generate_s10` (in Nightly builds, run with -Z macro-backtrace for more info) -error: expected unsuffixed literal, found `concat!("nonexistent")` +error: expected unsuffixed literal, found expression `concat!("nonexistent")` --> $DIR/cfg-attr-syntax-validation.rs:30:25 | LL | #[cfg(feature = $expr)] diff --git a/tests/ui/parser/attribute/attr-bad-meta-4.rs b/tests/ui/parser/attribute/attr-bad-meta-4.rs index 2a69ae5ac063..2d0c6dbb50ab 100644 --- a/tests/ui/parser/attribute/attr-bad-meta-4.rs +++ b/tests/ui/parser/attribute/attr-bad-meta-4.rs @@ -1,8 +1,8 @@ macro_rules! mac { ($attr_item: meta) => { #[cfg($attr_item)] - //~^ ERROR expected unsuffixed literal, found `an(arbitrary token stream)` - //~| ERROR expected unsuffixed literal, found `an(arbitrary token stream)` + //~^ ERROR expected unsuffixed literal, found `meta` metavariable + //~| ERROR expected unsuffixed literal, found `meta` metavariable struct S; } } diff --git a/tests/ui/parser/attribute/attr-bad-meta-4.stderr b/tests/ui/parser/attribute/attr-bad-meta-4.stderr index 192be28db3fb..dea574fd36d5 100644 --- a/tests/ui/parser/attribute/attr-bad-meta-4.stderr +++ b/tests/ui/parser/attribute/attr-bad-meta-4.stderr @@ -4,7 +4,7 @@ error: expected unsuffixed literal, found `-` LL | #[cfg(feature = -1)] | ^ -error: expected unsuffixed literal, found `an(arbitrary token stream)` +error: expected unsuffixed literal, found `meta` metavariable --> $DIR/attr-bad-meta-4.rs:3:15 | LL | #[cfg($attr_item)] @@ -15,7 +15,7 @@ LL | mac!(an(arbitrary token stream)); | = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) -error: expected unsuffixed literal, found `an(arbitrary token stream)` +error: expected unsuffixed literal, found `meta` metavariable --> $DIR/attr-bad-meta-4.rs:3:15 | LL | #[cfg($attr_item)] diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.rs b/tests/ui/parser/attribute/attr-unquoted-ident.rs index 5b15b8d69fcf..396265f715e9 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.rs +++ b/tests/ui/parser/attribute/attr-unquoted-ident.rs @@ -19,7 +19,7 @@ fn main() { macro_rules! make { ($name:ident) => { #[doc(alias = $name)] pub struct S; } - //~^ ERROR expected unsuffixed literal, found `nickname` + //~^ ERROR expected unsuffixed literal, found identifier `nickname` } make!(nickname); //~ NOTE in this expansion diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.stderr b/tests/ui/parser/attribute/attr-unquoted-ident.stderr index e0f99459c44e..2d7997f1aea5 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.stderr +++ b/tests/ui/parser/attribute/attr-unquoted-ident.stderr @@ -20,7 +20,7 @@ help: surround the identifier with quotation marks to make it into a string lite LL | #[cfg(key="foo bar baz")] | + + -error: expected unsuffixed literal, found `nickname` +error: expected unsuffixed literal, found identifier `nickname` --> $DIR/attr-unquoted-ident.rs:21:38 | LL | ($name:ident) => { #[doc(alias = $name)] pub struct S; } From 50076cdeb9fd1ecf2d85e481dc284525f9c509db Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Apr 2024 20:09:37 +1000 Subject: [PATCH 416/991] Remove `NtPath`. --- compiler/rustc_ast/src/ast_traits.rs | 2 -- compiler/rustc_ast/src/attr/mod.rs | 8 ++--- compiler/rustc_ast/src/mut_visit.rs | 1 - compiler/rustc_ast/src/token.rs | 30 ++++------------ compiler/rustc_ast/src/tokenstream.rs | 1 - compiler/rustc_attr_parsing/src/parser.rs | 35 +++++++------------ compiler/rustc_expand/src/mbe/transcribe.rs | 3 ++ compiler/rustc_parse/src/parser/expr.rs | 12 +++---- compiler/rustc_parse/src/parser/mod.rs | 1 + .../rustc_parse/src/parser/nonterminal.rs | 8 +++-- compiler/rustc_parse/src/parser/path.rs | 10 ++++-- tests/ui/imports/import-prefix-macro-2.rs | 2 +- tests/ui/imports/import-prefix-macro-2.stderr | 4 +-- tests/ui/macros/nonterminal-matching.rs | 2 +- tests/ui/macros/nonterminal-matching.stderr | 2 +- 15 files changed, 48 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 30b8216df879..4a2d95593850 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -202,7 +202,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtItem(item) => item.tokens(), Nonterminal::NtStmt(stmt) => stmt.tokens(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(), - Nonterminal::NtPath(path) => path.tokens(), Nonterminal::NtBlock(block) => block.tokens(), } } @@ -211,7 +210,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtItem(item) => item.tokens_mut(), Nonterminal::NtStmt(stmt) => stmt.tokens_mut(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(), - Nonterminal::NtPath(path) => path.tokens_mut(), Nonterminal::NtBlock(block) => block.tokens_mut(), } } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index be2e897e460c..4d613085d793 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -405,14 +405,12 @@ impl MetaItem { let span = span.with_hi(segments.last().unwrap().ident.span.hi()); Path { span, segments, tokens: None } } - Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt { - token::Nonterminal::NtPath(path) => (**path).clone(), - _ => return None, - }, Some(TokenTree::Delimited( _span, _spacing, - Delimiter::Invisible(InvisibleOrigin::MetaVar(MetaVarKind::Meta { .. })), + Delimiter::Invisible(InvisibleOrigin::MetaVar( + MetaVarKind::Meta { .. } | MetaVarKind::Path, + )), _stream, )) => { // This path is currently unreachable in the test suite. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 27fab2a02ed8..9be364e320b7 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -907,7 +907,6 @@ fn visit_nonterminal(vis: &mut T, nt: &mut token::Nonterminal) { }), token::NtExpr(expr) => vis.visit_expr(expr), token::NtLiteral(expr) => vis.visit_expr(expr), - token::NtPath(path) => vis.visit_path(path), } } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index ff590df0d680..6cd0e15c557f 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -624,8 +624,7 @@ impl Token { matches!(&**nt, NtBlock(..) | NtExpr(..) | - NtLiteral(..) | - NtPath(..) + NtLiteral(..) ), OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( MetaVarKind::Block | @@ -661,7 +660,6 @@ impl Token { matches!(&**nt, | NtExpr(..) | NtLiteral(..) - | NtPath(..) ), OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( MetaVarKind::Expr { .. } | @@ -690,7 +688,6 @@ impl Token { Lifetime(..) | // lifetime bound in trait object Lt | BinOp(Shl) | // associated path PathSep => true, // global path - Interpolated(ref nt) => matches!(&**nt, NtPath(..)), OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( MetaVarKind::Ty { .. } | MetaVarKind::Path @@ -849,27 +846,16 @@ impl Token { self.ident().is_some_and(|(ident, _)| ident.name == name) } - /// Returns `true` if the token is an interpolated path. - fn is_whole_path(&self) -> bool { - if let Interpolated(nt) = &self.kind - && let NtPath(..) = &**nt - { - return true; - } - - false - } - /// Is this a pre-parsed expression dropped into the token stream /// (which happens while parsing the result of macro expansion)? pub fn is_whole_expr(&self) -> bool { if let Interpolated(nt) = &self.kind - && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = &**nt + && let NtExpr(_) | NtLiteral(_) | NtBlock(_) = &**nt { - return true; + true + } else { + matches!(self.is_metavar_seq(), Some(MetaVarKind::Path)) } - - false } /// Is the token an interpolated block (`$b:block`)? @@ -895,7 +881,7 @@ impl Token { pub fn is_path_start(&self) -> bool { self == &PathSep || self.is_qpath_start() - || self.is_whole_path() + || matches!(self.is_metavar_seq(), Some(MetaVarKind::Path)) || self.is_path_segment_keyword() || self.is_ident() && !self.is_reserved_ident() } @@ -1078,7 +1064,6 @@ pub enum Nonterminal { NtStmt(P), NtExpr(P), NtLiteral(P), - NtPath(P), } #[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)] @@ -1171,7 +1156,6 @@ impl Nonterminal { NtBlock(block) => block.span, NtStmt(stmt) => stmt.span, NtExpr(expr) | NtLiteral(expr) => expr.span, - NtPath(path) => path.span, } } @@ -1182,7 +1166,6 @@ impl Nonterminal { NtStmt(..) => "statement", NtExpr(..) => "expression", NtLiteral(..) => "literal", - NtPath(..) => "path", } } } @@ -1205,7 +1188,6 @@ impl fmt::Debug for Nonterminal { NtStmt(..) => f.pad("NtStmt(..)"), NtExpr(..) => f.pad("NtExpr(..)"), NtLiteral(..) => f.pad("NtLiteral(..)"), - NtPath(..) => f.pad("NtPath(..)"), } } } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 489b5ad1a778..49ae8cc78fc5 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -468,7 +468,6 @@ impl TokenStream { TokenStream::token_alone(token::Semi, stmt.span) } Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt), - Nonterminal::NtPath(path) => TokenStream::from_ast(path), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr), } } diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 2604188bca24..96fc9d7d9ac4 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -477,32 +477,21 @@ impl<'a> MetaItemListParserContext<'a> { // or a path. let path = - if let Some(TokenTree::Token(Token { kind: token::Interpolated(nt), span, .. }, _)) = + if let Some(TokenTree::Token(Token { kind: token::Interpolated(_), span, .. }, _)) = self.inside_delimiters.peek() { - match &**nt { - // an already interpolated path from a macro expansion is a path, no need to parse - // one from tokens - token::Nonterminal::NtPath(path) => { - self.inside_delimiters.next(); + self.inside_delimiters.next(); + // We go into this path if an expr ended up in an attribute that + // expansion did not turn into a literal. Say, `#[repr(align(macro!()))]` + // where the macro didn't expand to a literal. An error is already given + // for this at this point, and then we do continue. This makes this path + // reachable... + let e = self.dcx.span_delayed_bug( + *span, + "expr in place where literal is expected (builtin attr parsing)", + ); - AttrPath::from_ast(path) - } - _ => { - self.inside_delimiters.next(); - // we go into this path if an expr ended up in an attribute that - // expansion did not turn into a literal. Say, `#[repr(align(macro!()))]` - // where the macro didn't expand to a literal. An error is already given - // for this at this point, and then we do continue. This makes this path - // reachable... - let e = self.dcx.span_delayed_bug( - *span, - "expr in place where literal is expected (builtin attr parsing)", - ); - - return Some(MetaItemOrLitParser::Err(*span, e)); - } - } + return Some(MetaItemOrLitParser::Err(*span, e)); } else { self.next_path()? }; diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 3f2d8b282609..70107c80147f 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -344,6 +344,9 @@ pub(super) fn transcribe<'a>( TokenStream::from_ast(attr_item), ) } + MatchedSingle(ParseNtResult::Path(path)) => { + mk_delimited(path.span, MetaVarKind::Path, TokenStream::from_ast(path)) + } MatchedSingle(ParseNtResult::Vis(vis)) => { mk_delimited(vis.span, MetaVarKind::Vis, TokenStream::from_ast(vis)) } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b2e58c942806..18082004d7a0 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -4,7 +4,7 @@ use core::mem; use core::ops::{Bound, ControlFlow}; use ast::mut_visit::{self, MutVisitor}; -use ast::token::IdentIsRaw; +use ast::token::{IdentIsRaw, MetaVarKind}; use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment, Recovered}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; @@ -1382,6 +1382,7 @@ impl<'a> Parser<'a> { fn parse_expr_bottom(&mut self) -> PResult<'a, P> { maybe_recover_from_interpolated_ty_qpath!(self, true); + let span = self.token.span; if let token::Interpolated(nt) = &self.token.kind { match &**nt { token::NtExpr(e) | token::NtLiteral(e) => { @@ -1389,11 +1390,6 @@ impl<'a> Parser<'a> { self.bump(); return Ok(e); } - token::NtPath(path) => { - let path = (**path).clone(); - self.bump(); - return Ok(self.mk_expr(self.prev_token.span, ExprKind::Path(None, path))); - } token::NtBlock(block) => { let block = block.clone(); self.bump(); @@ -1401,6 +1397,10 @@ impl<'a> Parser<'a> { } _ => {} }; + } else if let Some(path) = self.eat_metavar_seq(MetaVarKind::Path, |this| { + this.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type)) + }) { + return Ok(self.mk_expr(span, ExprKind::Path(None, path))); } // Outer attributes are already parsed and will be diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 3b3c2e6137d4..00282ef86799 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1749,6 +1749,7 @@ pub enum ParseNtResult { Pat(P, NtPatKind), Ty(P), Meta(P), + Path(P), Vis(P), /// This variant will eventually be removed, along with `Token::Interpolate`. diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index d4e4d5580327..d537bc17ce37 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -51,7 +51,7 @@ impl<'a> Parser<'a> { NtStmt(_) | NtExpr(_) | NtLiteral(_) // `true`, `false` - | NtPath(_) => true, + => true, NtItem(_) | NtBlock(_) => false, } @@ -97,7 +97,7 @@ impl<'a> Parser<'a> { token::NtLifetime(..) => true, token::Interpolated(nt) => match &**nt { NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, - NtItem(_) | NtPath(_) => false, + NtItem(_) => false, }, token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k { MetaVarKind::Block @@ -204,7 +204,9 @@ impl<'a> Parser<'a> { }; } NonterminalKind::Path => { - NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?)) + return Ok(ParseNtResult::Path(P( + self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))? + ))); } NonterminalKind::Meta => { return Ok(ParseNtResult::Meta(P(self.parse_attr_item(ForceCollect::Yes)?))); diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index c24305ea9a86..1280a1cd3121 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -15,9 +15,9 @@ use tracing::debug; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; -use crate::errors::{PathSingleColon, PathTripleColon}; +use crate::errors::{self, PathSingleColon, PathTripleColon}; +use crate::exp; use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma}; -use crate::{errors, exp, maybe_whole}; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -194,7 +194,11 @@ impl<'a> Parser<'a> { } }; - maybe_whole!(self, NtPath, |path| reject_generics_if_mod_style(self, path.into_inner())); + if let Some(path) = + self.eat_metavar_seq(MetaVarKind::Path, |this| this.parse_path(PathStyle::Type)) + { + return Ok(reject_generics_if_mod_style(self, path)); + } // If we have a `ty` metavar in the form of a path, reparse it directly as a path, instead // of reparsing it as a `ty` and then extracting the path. diff --git a/tests/ui/imports/import-prefix-macro-2.rs b/tests/ui/imports/import-prefix-macro-2.rs index 952d161e83fa..17898c0a6799 100644 --- a/tests/ui/imports/import-prefix-macro-2.rs +++ b/tests/ui/imports/import-prefix-macro-2.rs @@ -8,7 +8,7 @@ mod a { } macro_rules! import { - ($p: path) => (use ::$p {S, Z}); //~ERROR expected identifier, found `a::b::c` + ($p: path) => (use ::$p {S, Z}); //~ERROR expected identifier, found metavariable } import! { a::b::c } diff --git a/tests/ui/imports/import-prefix-macro-2.stderr b/tests/ui/imports/import-prefix-macro-2.stderr index 070186f2bf2f..fbeca99b1380 100644 --- a/tests/ui/imports/import-prefix-macro-2.stderr +++ b/tests/ui/imports/import-prefix-macro-2.stderr @@ -1,8 +1,8 @@ -error: expected identifier, found `a::b::c` +error: expected identifier, found metavariable --> $DIR/import-prefix-macro-2.rs:11:26 | LL | ($p: path) => (use ::$p {S, Z}); - | ^^ expected identifier + | ^^ expected identifier, found metavariable ... LL | import! { a::b::c } | ------------------- in this macro invocation diff --git a/tests/ui/macros/nonterminal-matching.rs b/tests/ui/macros/nonterminal-matching.rs index a655b6651031..ca95e8fac050 100644 --- a/tests/ui/macros/nonterminal-matching.rs +++ b/tests/ui/macros/nonterminal-matching.rs @@ -31,7 +31,7 @@ macro_rules! foo { (tt $x:tt) => { bar!(tt $x); }; (expr $x:expr) => { bar!(expr $x); }; //~ ERROR: no rules expected expression `3` (literal $x:literal) => { bar!(literal $x); }; //~ ERROR: no rules expected literal `4` - (path $x:path) => { bar!(path $x); }; //~ ERROR: no rules expected path `a::b::c` + (path $x:path) => { bar!(path $x); }; //~ ERROR: no rules expected `path` metavariable (stmt $x:stmt) => { bar!(stmt $x); }; //~ ERROR: no rules expected statement `let abc = 0` } diff --git a/tests/ui/macros/nonterminal-matching.stderr b/tests/ui/macros/nonterminal-matching.stderr index e283dfcb8fdc..ba2b3e213ad0 100644 --- a/tests/ui/macros/nonterminal-matching.stderr +++ b/tests/ui/macros/nonterminal-matching.stderr @@ -67,7 +67,7 @@ LL | (literal 4) => {}; = help: try using `:tt` instead in the macro definition = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) -error: no rules expected path `a::b::c` +error: no rules expected `path` metavariable --> $DIR/nonterminal-matching.rs:34:35 | LL | (path $x:path) => { bar!(path $x); }; From 775cb23dbc58f991f300cea5d3f66b088a3950d0 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 27 Feb 2025 23:07:50 +0100 Subject: [PATCH 417/991] doc: update Wasmtime flags Wasmtime's `--wasm-features` and `--wasi-modules` flags have been renamed since these docs were initially written. Additionally, from my testing I don't believe `--wasm threads` is needed if `--wasi threads` is passed already. --- src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md | 2 +- src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md index 994c0f4bbb3e..1b0a312ca9c7 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md @@ -100,7 +100,7 @@ This target is not a stable target. This means that there are a few engines which implement the `wasi-threads` feature and if they do they're likely behind a flag, for example: -* Wasmtime - `--wasm-features=threads --wasi-modules=experimental-wasi-threads` +* Wasmtime - `--wasi threads` * [WAMR](https://github.com/bytecodealliance/wasm-micro-runtime) - needs to be built with WAMR_BUILD_LIB_WASI_THREADS=1 ## Building the target diff --git a/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md index 6932e6a5764b..a717f5dad797 100644 --- a/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md +++ b/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md @@ -36,7 +36,7 @@ which implement the `memory64` feature and if they do they're likely behind a flag, for example: * Nodejs - `--experimental-wasm-memory64` -* Wasmtime - `--wasm-features memory64` +* Wasmtime - `--wasm memory64` Also note that at this time the `wasm64-unknown-unknown` target assumes the presence of other merged wasm proposals such as (with their LLVM feature flags): From afc5e1fba5e12da77c6bcb8183c277c6e61de6a3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Feb 2025 09:00:47 +1100 Subject: [PATCH 418/991] Split the `Edges` iterator. The `Edges` iterator returns `OutlivesConstraint` elements, which are 72 bytes. This is big enough to affect performance. Return `&OutlivesConstraint` would be better. However, each `Edges` iterator is really one of two different iterators. The "from graph" case does a graph traversal and could return `&OutlivesConstraint`. But the "from static" case just does a `0..n` iteration and constructs a new `OutlivesConstraint` from that, so it can't return a reference. This commit splits `Edges into `EdgesFromGraph` and `EdgesFromStatic`, which allows them to have different return types. This is a perf win for the `wg-grammar` benchmark. --- .../rustc_borrowck/src/constraints/graph.rs | 104 ++++++++++-------- .../rustc_borrowck/src/region_infer/mod.rs | 40 +++++-- 2 files changed, 84 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/graph.rs b/compiler/rustc_borrowck/src/constraints/graph.rs index 3f2064680ae9..1209d8bf5967 100644 --- a/compiler/rustc_borrowck/src/constraints/graph.rs +++ b/compiler/rustc_borrowck/src/constraints/graph.rs @@ -1,11 +1,8 @@ use rustc_data_structures::graph; use rustc_index::IndexVec; -use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::{RegionVid, VarianceDiagInfo}; -use rustc_span::DUMMY_SP; +use rustc_middle::ty::RegionVid; use crate::constraints::{OutlivesConstraint, OutlivesConstraintIndex, OutlivesConstraintSet}; -use crate::type_check::Locations; /// The construct graph organizes the constraints by their end-points. /// It can be used to view a `R1: R2` constraint as either an edge `R1 @@ -105,63 +102,57 @@ impl ConstraintGraph { RegionGraph::new(set, self, static_region) } + pub(crate) fn is_normal(&self) -> bool { + D::is_normal() + } + /// Given a region `R`, iterate over all constraints `R: R1`. - pub(crate) fn outgoing_edges<'a, 'tcx>( + pub(crate) fn outgoing_edges_from_graph<'a, 'tcx>( &'a self, region_sup: RegionVid, constraints: &'a OutlivesConstraintSet<'tcx>, - static_region: RegionVid, - ) -> Edges<'a, 'tcx, D> { - //if this is the `'static` region and the graph's direction is normal, - //then setup the Edges iterator to return all regions #53178 - if region_sup == static_region && D::is_normal() { - Edges { - graph: self, - constraints, - pointer: None, - next_static_idx: Some(0), - static_region, - } - } else { - //otherwise, just setup the iterator as normal - let first = self.first_constraints[region_sup]; - Edges { graph: self, constraints, pointer: first, next_static_idx: None, static_region } - } + ) -> EdgesFromGraph<'a, 'tcx, D> { + EdgesFromGraph { graph: self, constraints, pointer: self.first_constraints[region_sup] } + } + + /// Returns all regions (#53178). + pub(crate) fn outgoing_edges_from_static(&self) -> EdgesFromStatic { + EdgesFromStatic { next_static_idx: 0, end_static_idx: self.first_constraints.len() } } } -pub(crate) struct Edges<'a, 'tcx, D: ConstraintGraphDirection> { +pub(crate) struct EdgesFromGraph<'a, 'tcx, D: ConstraintGraphDirection> { graph: &'a ConstraintGraph, constraints: &'a OutlivesConstraintSet<'tcx>, pointer: Option, - next_static_idx: Option, - static_region: RegionVid, } -impl<'a, 'tcx, D: ConstraintGraphDirection> Iterator for Edges<'a, 'tcx, D> { - type Item = OutlivesConstraint<'tcx>; +impl<'a, 'tcx, D: ConstraintGraphDirection> Iterator for EdgesFromGraph<'a, 'tcx, D> { + type Item = &'a OutlivesConstraint<'tcx>; fn next(&mut self) -> Option { if let Some(p) = self.pointer { self.pointer = self.graph.next_constraints[p]; + Some(&self.constraints[p]) + } else { + None + } + } +} - Some(self.constraints[p]) - } else if let Some(next_static_idx) = self.next_static_idx { - self.next_static_idx = if next_static_idx == (self.graph.first_constraints.len() - 1) { - None - } else { - Some(next_static_idx + 1) - }; +pub(crate) struct EdgesFromStatic { + next_static_idx: usize, + end_static_idx: usize, +} - Some(OutlivesConstraint { - sup: self.static_region, - sub: next_static_idx.into(), - locations: Locations::All(DUMMY_SP), - span: DUMMY_SP, - category: ConstraintCategory::Internal, - variance_info: VarianceDiagInfo::default(), - from_closure: false, - }) +impl Iterator for EdgesFromStatic { + type Item = RegionVid; + + fn next(&mut self) -> Option { + if self.next_static_idx < self.end_static_idx { + let ret = RegionVid::from_usize(self.next_static_idx); + self.next_static_idx += 1; + Some(ret) } else { None } @@ -193,21 +184,38 @@ impl<'a, 'tcx, D: ConstraintGraphDirection> RegionGraph<'a, 'tcx, D> { /// Given a region `R`, iterate over all regions `R1` such that /// there exists a constraint `R: R1`. pub(crate) fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'a, 'tcx, D> { - Successors { - edges: self.constraint_graph.outgoing_edges(region_sup, self.set, self.static_region), + // If this is the `'static` region and the graph's direction is normal, + // then setup the Edges iterator to return all regions (#53178). + if region_sup == self.static_region && D::is_normal() { + Successors::FromStatic(self.constraint_graph.outgoing_edges_from_static()) + } else { + // Otherwise, just setup the iterator as normal. + Successors::FromGraph( + self.constraint_graph.outgoing_edges_from_graph(region_sup, self.set), + ) } } } -pub(crate) struct Successors<'a, 'tcx, D: ConstraintGraphDirection> { - edges: Edges<'a, 'tcx, D>, +pub(crate) enum Successors<'a, 'tcx, D: ConstraintGraphDirection> { + FromStatic(EdgesFromStatic), + FromGraph(EdgesFromGraph<'a, 'tcx, D>), } impl<'a, 'tcx, D: ConstraintGraphDirection> Iterator for Successors<'a, 'tcx, D> { type Item = RegionVid; fn next(&mut self) -> Option { - self.edges.next().map(|c| D::end_region(c.sup, c.sub)) + match self { + Successors::FromStatic(edges) => { + // No `D::end_region` call needed here: static successors are only possible when + // the direction is `Normal`, so we can directly use what would be the `sub` value. + edges.next() + } + Successors::FromGraph(edges) => { + edges.next().map(|constraint| D::end_region(constraint.sup, constraint.sub)) + } + } } } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index a00fce08c9ba..abe9efe83649 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -21,8 +21,8 @@ use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex}; use rustc_mir_dataflow::points::DenseLocationMap; -use rustc_span::Span; use rustc_span::hygiene::DesugaringKind; +use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument, trace}; use crate::BorrowckInferCtxt; @@ -1809,27 +1809,43 @@ impl<'tcx> RegionInferenceContext<'tcx> { // A constraint like `'r: 'x` can come from our constraint // graph. let fr_static = self.universal_regions().fr_static; - let outgoing_edges_from_graph = - self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static); // Always inline this closure because it can be hot. let mut handle_constraint = #[inline(always)] - |constraint: OutlivesConstraint<'tcx>| { + |constraint: &OutlivesConstraint<'tcx>| { debug_assert_eq!(constraint.sup, r); let sub_region = constraint.sub; if let Trace::NotVisited = context[sub_region] { - context[sub_region] = Trace::FromOutlivesConstraint(constraint); + context[sub_region] = Trace::FromOutlivesConstraint(*constraint); deque.push_back(sub_region); } }; - // This loop can be hot. - for constraint in outgoing_edges_from_graph { - if matches!(constraint.category, ConstraintCategory::IllegalUniverse) { - debug!("Ignoring illegal universe constraint: {constraint:?}"); - continue; + // If this is the `'static` region and the graph's direction is normal, then set up the + // Edges iterator to return all regions (#53178). + if r == fr_static && self.constraint_graph.is_normal() { + for next_static_idx in self.constraint_graph.outgoing_edges_from_static() { + let constraint = OutlivesConstraint { + sup: fr_static, + sub: next_static_idx, + locations: Locations::All(DUMMY_SP), + span: DUMMY_SP, + category: ConstraintCategory::Internal, + variance_info: ty::VarianceDiagInfo::default(), + from_closure: false, + }; + handle_constraint(&constraint); + } + } else { + let edges = self.constraint_graph.outgoing_edges_from_graph(r, &self.constraints); + // This loop can be hot. + for constraint in edges { + if matches!(constraint.category, ConstraintCategory::IllegalUniverse) { + debug!("Ignoring illegal universe constraint: {constraint:?}"); + continue; + } + handle_constraint(constraint); } - handle_constraint(constraint); } // Member constraints can also give rise to `'r: 'x` edges that @@ -1846,7 +1862,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { variance_info: ty::VarianceDiagInfo::default(), from_closure: false, }; - handle_constraint(constraint); + handle_constraint(&constraint); } } From 9a0513ad7134f75d51b16ac359e41f52f9dda463 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Feb 2025 10:03:33 +1100 Subject: [PATCH 419/991] Optimize `Trace`. `Trace::FromOutlivesConstraint` contains an `OutlivesConstraint`, which is 72 bytes. Lots of these are created but never used. This commit splits `Trace::FromOutlivesConstraint` into three new variants: `FromVanilla`, `FromStatic`, `FromMember`. Each of these contains just enough data to construct an `OutlivesConstraint`, if necessary. This reduces the size of `Trace` from 72 bytes to 16 bytes. All this avoids some memory traffic. --- .../rustc_borrowck/src/region_infer/mod.rs | 87 +++++++++++-------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index abe9efe83649..bb209a957118 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -311,9 +311,11 @@ enum RegionRelationCheckResult { } #[derive(Clone, PartialEq, Eq, Debug)] -enum Trace<'tcx> { +enum Trace<'a, 'tcx> { StartRegion, - FromOutlivesConstraint(OutlivesConstraint<'tcx>), + FromGraph(&'a OutlivesConstraint<'tcx>), + FromStatic(RegionVid), + FromMember(RegionVid, RegionVid, Span), NotVisited, } @@ -1764,6 +1766,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut context = IndexVec::from_elem(Trace::NotVisited, &self.definitions); context[from_region] = Trace::StartRegion; + let fr_static = self.universal_regions().fr_static; + // Use a deque so that we do a breadth-first search. We will // stop at the first match, which ought to be the shortest // path (fewest constraints). @@ -1783,13 +1787,39 @@ impl<'tcx> RegionInferenceContext<'tcx> { if target_test(r) { let mut result = vec![]; let mut p = r; + // This loop is cold and runs at the end, which is why we delay + // `OutlivesConstraint` construction until now. loop { - match context[p].clone() { - Trace::NotVisited => { - bug!("found unvisited region {:?} on path to {:?}", p, r) + match context[p] { + Trace::FromGraph(c) => { + p = c.sup; + result.push(*c); } - Trace::FromOutlivesConstraint(c) => { + Trace::FromStatic(sub) => { + let c = OutlivesConstraint { + sup: fr_static, + sub, + locations: Locations::All(DUMMY_SP), + span: DUMMY_SP, + category: ConstraintCategory::Internal, + variance_info: ty::VarianceDiagInfo::default(), + from_closure: false, + }; + p = c.sup; + result.push(c); + } + + Trace::FromMember(sup, sub, span) => { + let c = OutlivesConstraint { + sup, + sub, + locations: Locations::All(span), + span, + category: ConstraintCategory::OpaqueType, + variance_info: ty::VarianceDiagInfo::default(), + from_closure: false, + }; p = c.sup; result.push(c); } @@ -1798,6 +1828,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { result.reverse(); return Some((result, r)); } + + Trace::NotVisited => { + bug!("found unvisited region {:?} on path to {:?}", p, r) + } } } } @@ -1808,33 +1842,21 @@ impl<'tcx> RegionInferenceContext<'tcx> { // A constraint like `'r: 'x` can come from our constraint // graph. - let fr_static = self.universal_regions().fr_static; // Always inline this closure because it can be hot. - let mut handle_constraint = #[inline(always)] - |constraint: &OutlivesConstraint<'tcx>| { - debug_assert_eq!(constraint.sup, r); - let sub_region = constraint.sub; - if let Trace::NotVisited = context[sub_region] { - context[sub_region] = Trace::FromOutlivesConstraint(*constraint); - deque.push_back(sub_region); + let mut handle_trace = #[inline(always)] + |sub, trace| { + if let Trace::NotVisited = context[sub] { + context[sub] = trace; + deque.push_back(sub); } }; // If this is the `'static` region and the graph's direction is normal, then set up the // Edges iterator to return all regions (#53178). if r == fr_static && self.constraint_graph.is_normal() { - for next_static_idx in self.constraint_graph.outgoing_edges_from_static() { - let constraint = OutlivesConstraint { - sup: fr_static, - sub: next_static_idx, - locations: Locations::All(DUMMY_SP), - span: DUMMY_SP, - category: ConstraintCategory::Internal, - variance_info: ty::VarianceDiagInfo::default(), - from_closure: false, - }; - handle_constraint(&constraint); + for sub in self.constraint_graph.outgoing_edges_from_static() { + handle_trace(sub, Trace::FromStatic(sub)); } } else { let edges = self.constraint_graph.outgoing_edges_from_graph(r, &self.constraints); @@ -1844,7 +1866,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("Ignoring illegal universe constraint: {constraint:?}"); continue; } - handle_constraint(constraint); + debug_assert_eq!(constraint.sup, r); + handle_trace(constraint.sub, Trace::FromGraph(constraint)); } } @@ -1852,17 +1875,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { // were not part of the graph initially, so watch out for those. // (But they are extremely rare; this loop is very cold.) for constraint in self.applied_member_constraints(self.constraint_sccs.scc(r)) { + let sub = constraint.min_choice; let p_c = &self.member_constraints[constraint.member_constraint_index]; - let constraint = OutlivesConstraint { - sup: r, - sub: constraint.min_choice, - locations: Locations::All(p_c.definition_span), - span: p_c.definition_span, - category: ConstraintCategory::OpaqueType, - variance_info: ty::VarianceDiagInfo::default(), - from_closure: false, - }; - handle_constraint(&constraint); + handle_trace(sub, Trace::FromMember(r, sub, p_c.definition_span)); } } From af0c8b7f25977a7ad2bfefafd005a5ff4bd50827 Mon Sep 17 00:00:00 2001 From: Nicholas Crothers Date: Thu, 27 Feb 2025 16:39:07 -0600 Subject: [PATCH 420/991] Add anchor for intra-doc links to associated items --- .../rust-analyzer/crates/ide/src/doc_links.rs | 14 +-- .../crates/ide/src/doc_links/tests.rs | 92 +++++++++++++++++++ 2 files changed, 99 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index e35e47e74718..d88f7c5033e0 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -379,13 +379,15 @@ fn rewrite_intra_doc_link( let resolved = resolve_doc_path_for_def(db, def, link, ns)?; let mut url = get_doc_base_urls(db, resolved, None, None).0?; - let (_, file, _) = filename_and_frag_for_def(db, resolved)?; + let (_, file, frag) = filename_and_frag_for_def(db, resolved)?; if let Some(path) = mod_path_of_def(db, resolved) { url = url.join(&path).ok()?; } + let frag = anchor.or(frag.as_deref()); + url = url.join(&file).ok()?; - url.set_fragment(anchor); + url.set_fragment(frag); Some((url.into(), strip_prefixes_suffixes(title).to_owned())) } @@ -621,11 +623,9 @@ fn filename_and_frag_for_def( format!("fn.{}.html", f.name(db).as_str()) } Definition::Variant(ev) => { - format!( - "enum.{}.html#variant.{}", - ev.parent_enum(db).name(db).as_str(), - ev.name(db).as_str() - ) + let def = Definition::Adt(ev.parent_enum(db).into()); + let (_, file, _) = filename_and_frag_for_def(db, def)?; + return Some((def, file, Some(format!("variant.{}", ev.name(db).as_str())))); } Definition::Const(c) => { format!("const.{}.html", c.name(db)?.as_str()) diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs index d7291c4b9f32..b09e3a3c8047 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs @@ -686,3 +686,95 @@ fn rewrite_intra_doc_link_with_anchor() { expect!["[PartialEq#derivable](https://doc.rust-lang.org/stable/core/cmp/trait.PartialEq.html#derivable)"], ); } + +#[test] +fn rewrite_intra_doc_link_to_associated_item() { + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::bar] +pub struct $0Foo; + +impl Foo { + fn bar() {} +} +"#, + expect![[r#"[Foo::bar](https://docs.rs/foo/*/foo/struct.Foo.html#method.bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::bar] +pub struct $0Foo { + bar: () +} +"#, + expect![[r#"[Foo::bar](https://docs.rs/foo/*/foo/struct.Foo.html#structfield.bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::Bar] +pub enum $0Foo { + Bar +} +"#, + expect![[r#"[Foo::Bar](https://docs.rs/foo/*/foo/enum.Foo.html#variant.Bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::BAR] +pub struct $0Foo; + +impl Foo { + const BAR: () = (); +} +"#, + expect![[ + r#"[Foo::BAR](https://docs.rs/foo/*/foo/struct.Foo.html#associatedconstant.BAR)"# + ]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::bar] +pub trait $0Foo { + fn bar(); +} +"#, + expect![[r#"[Foo::bar](https://docs.rs/foo/*/foo/trait.Foo.html#tymethod.bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::Bar] +pub trait $0Foo { + type Bar; +} +"#, + expect![[r#"[Foo::Bar](https://docs.rs/foo/*/foo/trait.Foo.html#associatedtype.Bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::bar#anchor] +pub struct $0Foo { + bar: (), +} +"#, + expect![[r#"[Foo::bar#anchor](https://docs.rs/foo/*/foo/struct.Foo.html#anchor)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [method](Foo::bar) +pub struct $0Foo; + +impl Foo { + fn bar() {} +} +"#, + expect![[r#"[method](https://docs.rs/foo/*/foo/struct.Foo.html#method.bar)"#]], + ); +} From 059c0abeee26f6f38eb24190ae00aa8d5848a778 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 27 Feb 2025 20:23:54 +0100 Subject: [PATCH 421/991] Fix method name in `TyCtxt::hir_crate()` documentation --- compiler/rustc_middle/src/query/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7c4ea06a7461..46a960d9945e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -143,11 +143,11 @@ rustc_queries! { /// Represents crate as a whole (as distinct from the top-level crate module). /// - /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`), + /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir_crate()`), /// we will have to assume that any change means that you need to be recompiled. /// This is because the `hir_crate` query gives you access to all other items. - /// To avoid this fate, do not call `tcx.hir().krate()`; instead, - /// prefer wrappers like `tcx.visit_all_items_in_krate()`. + /// To avoid this fate, do not call `tcx.hir_crate()`; instead, + /// prefer wrappers like [`TyCtxt::hir_visit_all_item_likes_in_crate`]. query hir_crate(key: ()) -> &'tcx Crate<'tcx> { arena_cache eval_always From 0ca1c9c1dd184da0786e76d674e8f0c7f64ef124 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Thu, 6 Feb 2025 13:19:11 -0800 Subject: [PATCH 422/991] Count char width at most once in Formatter::pad When both width and precision flags are specified, then the character width is counted twice. Instead, record the character width when truncating it to the precision, so it does not need to be recomputed. Simplify control flow so the cases are more clear. --- library/core/src/fmt/mod.rs | 66 ++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 764e7fff33ec..3f60bb067d6e 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -1693,49 +1693,41 @@ impl<'a> Formatter<'a> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn pad(&mut self, s: &str) -> Result { - // Make sure there's a fast path up front + // Make sure there's a fast path up front. if self.options.width.is_none() && self.options.precision.is_none() { return self.buf.write_str(s); } - // The `precision` field can be interpreted as a `max-width` for the + + // The `precision` field can be interpreted as a maximum width for the // string being formatted. - let s = if let Some(max) = self.options.precision { - // If our string is longer that the precision, then we must have - // truncation. However other flags like `fill`, `width` and `align` - // must act as always. - if let Some((i, _)) = s.char_indices().nth(max) { - // LLVM here can't prove that `..i` won't panic `&s[..i]`, but - // we know that it can't panic. Use `get` + `unwrap_or` to avoid - // `unsafe` and otherwise don't emit any panic-related code - // here. - s.get(..i).unwrap_or(s) - } else { - &s - } + let (s, char_count) = if let Some(max_char_count) = self.options.precision { + let mut iter = s.char_indices(); + let remaining = match iter.advance_by(max_char_count) { + Ok(()) => 0, + Err(remaining) => remaining.get(), + }; + // SAFETY: The offset of `.char_indices()` is guaranteed to be + // in-bounds and between character boundaries. + let truncated = unsafe { s.get_unchecked(..iter.offset()) }; + (truncated, max_char_count - remaining) } else { - &s + // Use the optimized char counting algorithm for the full string. + (s, s.chars().count()) }; - // The `width` field is more of a `min-width` parameter at this point. - match self.options.width { - // If we're under the maximum length, and there's no minimum length - // requirements, then we can just emit the string - None => self.buf.write_str(s), - Some(width) => { - let chars_count = s.chars().count(); - // If we're under the maximum width, check if we're over the minimum - // width, if so it's as easy as just emitting the string. - if chars_count >= width { - self.buf.write_str(s) - } - // If we're under both the maximum and the minimum width, then fill - // up the minimum width with the specified string + some alignment. - else { - let align = Alignment::Left; - let post_padding = self.padding(width - chars_count, align)?; - self.buf.write_str(s)?; - post_padding.write(self) - } - } + + // The `width` field is more of a minimum width parameter at this point. + if let Some(width) = self.options.width + && char_count < width + { + // If we're under the minimum width, then fill up the minimum width + // with the specified string + some alignment. + let post_padding = self.padding(width - char_count, Alignment::Left)?; + self.buf.write_str(s)?; + post_padding.write(self) + } else { + // If we're over the minimum width or there is no minimum width, we + // can just emit the string. + self.buf.write_str(s) } } From f3399516fac53bc0f3ee1c23fbefc41b442eb7bb Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Fri, 28 Feb 2025 00:47:38 +0000 Subject: [PATCH 423/991] Revert "Fix 32-bit MSVC CI" This reverts commit 6ea4823733254432aee255465177b8e53f01a79d. --- src/ci/github-actions/jobs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 279c7649ca3d..64e64867de26 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -474,13 +474,13 @@ auto: env: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc --enable-sanitizers SCRIPT: make ci-msvc-py - <<: *job-windows-8c + <<: *job-windows - name: i686-msvc-2 env: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc --enable-sanitizers SCRIPT: make ci-msvc-ps1 - <<: *job-windows-8c + <<: *job-windows # x86_64-msvc-ext is split into multiple jobs to run tests in parallel. - name: x86_64-msvc-ext1 @@ -595,7 +595,7 @@ auto: SCRIPT: python x.py dist bootstrap --include-default-paths DIST_REQUIRE_ALL_TOOLS: 1 CODEGEN_BACKENDS: llvm,cranelift - <<: *job-windows-8c + <<: *job-windows - name: dist-aarch64-msvc env: From 67cc82a704a38fcd574b0dc4373d939effed9496 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Sat, 15 Feb 2025 01:56:52 -0800 Subject: [PATCH 424/991] Inline VecDeque and BorrowedCursor methods All other methods in this file have #[inline] and these methods are very similar to those of &[u8] which are already inlined here. --- library/std/src/io/impls.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index 8239b29884e8..7885332cfde5 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -515,6 +515,7 @@ impl Read for VecDeque { Ok(n) } + #[inline] fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { let (front, back) = self.as_slices(); @@ -547,6 +548,7 @@ impl Read for VecDeque { Ok(()) } + #[inline] fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> { let len = cursor.capacity(); let (front, back) = self.as_slices(); @@ -646,6 +648,7 @@ impl Write for VecDeque { #[unstable(feature = "read_buf", issue = "78485")] impl<'a> io::Write for core::io::BorrowedCursor<'a> { + #[inline] fn write(&mut self, buf: &[u8]) -> io::Result { let amt = cmp::min(buf.len(), self.capacity()); self.append(&buf[..amt]); From 41bdd2b74a8c380fb0fec1ad4d8ee21a11238a8b Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Sat, 15 Feb 2025 18:51:33 -0800 Subject: [PATCH 425/991] Override default Write methods for cursor-like types --- library/std/src/io/cursor.rs | 100 ++++++++++++++++++++++++++++++----- library/std/src/io/impls.rs | 57 +++++++++++++++++++- 2 files changed, 143 insertions(+), 14 deletions(-) diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index 08832bbc1e3d..d7131e2fe92f 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -439,6 +439,27 @@ fn slice_write_vectored( Ok(nwritten) } +#[inline] +fn slice_write_all(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<()> { + let n = slice_write(pos_mut, slice, buf)?; + if n < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) } +} + +#[inline] +fn slice_write_all_vectored( + pos_mut: &mut u64, + slice: &mut [u8], + bufs: &[IoSlice<'_>], +) -> io::Result<()> { + for buf in bufs { + let n = slice_write(pos_mut, slice, buf)?; + if n < buf.len() { + return Err(io::Error::WRITE_ALL_EOF); + } + } + Ok(()) +} + /// Reserves the required space, and pads the vec with 0s if necessary. fn reserve_and_pad( pos_mut: &mut u64, @@ -481,9 +502,12 @@ fn reserve_and_pad( Ok(pos) } -/// Writes the slice to the vec without allocating -/// # Safety: vec must have buf.len() spare capacity -unsafe fn vec_write_unchecked(pos: usize, vec: &mut Vec, buf: &[u8]) -> usize +/// Writes the slice to the vec without allocating. +/// +/// # Safety +/// +/// `vec` must have `buf.len()` spare capacity. +unsafe fn vec_write_all_unchecked(pos: usize, vec: &mut Vec, buf: &[u8]) -> usize where A: Allocator, { @@ -492,7 +516,7 @@ where pos + buf.len() } -/// Resizing write implementation for [`Cursor`] +/// Resizing `write_all` implementation for [`Cursor`]. /// /// Cursor is allowed to have a pre-allocated and initialised /// vector body, but with a position of 0. This means the [`Write`] @@ -501,7 +525,7 @@ where /// This also allows for the vec body to be empty, but with a position of N. /// This means that [`Write`] will pad the vec with 0 initially, /// before writing anything from that point -fn vec_write(pos_mut: &mut u64, vec: &mut Vec, buf: &[u8]) -> io::Result +fn vec_write_all(pos_mut: &mut u64, vec: &mut Vec, buf: &[u8]) -> io::Result where A: Allocator, { @@ -512,7 +536,7 @@ where // Safety: we have ensured that the capacity is available // and that all bytes get written up to pos unsafe { - pos = vec_write_unchecked(pos, vec, buf); + pos = vec_write_all_unchecked(pos, vec, buf); if pos > vec.len() { vec.set_len(pos); } @@ -523,7 +547,7 @@ where Ok(buf_len) } -/// Resizing write_vectored implementation for [`Cursor`] +/// Resizing `write_all_vectored` implementation for [`Cursor`]. /// /// Cursor is allowed to have a pre-allocated and initialised /// vector body, but with a position of 0. This means the [`Write`] @@ -532,7 +556,7 @@ where /// This also allows for the vec body to be empty, but with a position of N. /// This means that [`Write`] will pad the vec with 0 initially, /// before writing anything from that point -fn vec_write_vectored( +fn vec_write_all_vectored( pos_mut: &mut u64, vec: &mut Vec, bufs: &[IoSlice<'_>], @@ -550,7 +574,7 @@ where // and that all bytes get written up to the last pos unsafe { for buf in bufs { - pos = vec_write_unchecked(pos, vec, buf); + pos = vec_write_all_unchecked(pos, vec, buf); } if pos > vec.len() { vec.set_len(pos); @@ -579,6 +603,16 @@ impl Write for Cursor<&mut [u8]> { true } + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + slice_write_all(&mut self.pos, self.inner, buf) + } + + #[inline] + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + slice_write_all_vectored(&mut self.pos, self.inner, bufs) + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) @@ -591,11 +625,11 @@ where A: Allocator, { fn write(&mut self, buf: &[u8]) -> io::Result { - vec_write(&mut self.pos, self.inner, buf) + vec_write_all(&mut self.pos, self.inner, buf) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - vec_write_vectored(&mut self.pos, self.inner, bufs) + vec_write_all_vectored(&mut self.pos, self.inner, bufs) } #[inline] @@ -603,6 +637,16 @@ where true } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + vec_write_all(&mut self.pos, self.inner, buf)?; + Ok(()) + } + + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + vec_write_all_vectored(&mut self.pos, self.inner, bufs)?; + Ok(()) + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) @@ -615,11 +659,11 @@ where A: Allocator, { fn write(&mut self, buf: &[u8]) -> io::Result { - vec_write(&mut self.pos, &mut self.inner, buf) + vec_write_all(&mut self.pos, &mut self.inner, buf) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - vec_write_vectored(&mut self.pos, &mut self.inner, bufs) + vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs) } #[inline] @@ -627,6 +671,16 @@ where true } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + vec_write_all(&mut self.pos, &mut self.inner, buf)?; + Ok(()) + } + + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)?; + Ok(()) + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) @@ -653,6 +707,16 @@ where true } + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + slice_write_all(&mut self.pos, &mut self.inner, buf) + } + + #[inline] + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs) + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) @@ -676,6 +740,16 @@ impl Write for Cursor<[u8; N]> { true } + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + slice_write_all(&mut self.pos, &mut self.inner, buf) + } + + #[inline] + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs) + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index 7885332cfde5..d0245f3d4984 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -455,7 +455,17 @@ impl Write for &mut [u8] { #[inline] fn write_all(&mut self, data: &[u8]) -> io::Result<()> { - if self.write(data)? == data.len() { Ok(()) } else { Err(io::Error::WRITE_ALL_EOF) } + if self.write(data)? < data.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) } + } + + #[inline] + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + for buf in bufs { + if self.write(buf)? < buf.len() { + return Err(io::Error::WRITE_ALL_EOF); + } + } + Ok(()) } #[inline] @@ -495,6 +505,12 @@ impl Write for Vec { Ok(()) } + #[inline] + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + self.write_vectored(bufs)?; + Ok(()) + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) @@ -640,6 +656,12 @@ impl Write for VecDeque { Ok(()) } + #[inline] + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + self.write_vectored(bufs)?; + Ok(()) + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) @@ -655,6 +677,39 @@ impl<'a> io::Write for core::io::BorrowedCursor<'a> { Ok(amt) } + #[inline] + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + let mut nwritten = 0; + for buf in bufs { + let n = self.write(buf)?; + nwritten += n; + if n < buf.len() { + break; + } + } + Ok(nwritten) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + if self.write(buf)? < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) } + } + + #[inline] + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + for buf in bufs { + if self.write(buf)? < buf.len() { + return Err(io::Error::WRITE_ALL_EOF); + } + } + Ok(()) + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) From 371c073ecff1d9e9ad6adb46e25bdbc53834be61 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Feb 2025 01:27:04 +0000 Subject: [PATCH 426/991] Use mk_ty_from_kind a bit less, clean up lifetime handling in borrowck --- compiler/rustc_borrowck/src/type_check/mod.rs | 44 ++++++------------- compiler/rustc_hir_typeck/src/cast.rs | 10 +++-- compiler/rustc_middle/src/ty/codec.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 2 +- 4 files changed, 21 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index bd0d98028ae8..6d05696e146f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -38,7 +38,7 @@ use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::source_map::Spanned; -use rustc_span::{DUMMY_SP, Span, sym}; +use rustc_span::{Span, sym}; use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; use tracing::{debug, instrument, trace}; @@ -51,7 +51,6 @@ use crate::polonius::legacy::{PoloniusFacts, PoloniusLocationTable}; use crate::polonius::{PoloniusContext, PoloniusLivenessContext}; use crate::region_infer::TypeTest; use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices}; -use crate::renumber::RegionCtxt; use crate::session_diagnostics::{MoveUnsized, SimdIntrinsicArgConst}; use crate::type_check::free_region_relations::{CreateResult, UniversalRegionRelations}; use crate::universal_regions::{DefiningTy, UniversalRegions}; @@ -2121,35 +2120,31 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // // Note that other checks (such as denying `dyn Send` -> `dyn // Debug`) are in `rustc_hir_typeck`. - if let ty::Dynamic(src_tty, ..) = src_tail.kind() - && let ty::Dynamic(dst_tty, ..) = dst_tail.kind() + if let ty::Dynamic(src_tty, _src_lt, _) = *src_tail.kind() + && let ty::Dynamic(dst_tty, dst_lt, _) = *dst_tail.kind() && src_tty.principal().is_some() && dst_tty.principal().is_some() { // Remove auto traits. // Auto trait checks are handled in `rustc_hir_typeck` as FCW. - let src_obj = tcx.mk_ty_from_kind(ty::Dynamic( + let src_obj = Ty::new_dynamic( + tcx, tcx.mk_poly_existential_predicates( &src_tty.without_auto_traits().collect::>(), ), - tcx.lifetimes.re_static, + // FIXME: Once we disallow casting `*const dyn Trait + 'short` + // to `*const dyn Trait + 'long`, then this can just be `src_lt`. + dst_lt, ty::Dyn, - )); - let dst_obj = tcx.mk_ty_from_kind(ty::Dynamic( + ); + let dst_obj = Ty::new_dynamic( + tcx, tcx.mk_poly_existential_predicates( &dst_tty.without_auto_traits().collect::>(), ), - tcx.lifetimes.re_static, + dst_lt, ty::Dyn, - )); - - // Replace trait object lifetimes with fresh vars, to allow - // casts like - // `*mut dyn FnOnce() + 'a` -> `*mut dyn FnOnce() + 'static` - let src_obj = - freshen_single_trait_object_lifetime(self.infcx, src_obj); - let dst_obj = - freshen_single_trait_object_lifetime(self.infcx, dst_obj); + ); debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); @@ -2707,16 +2702,3 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> { Ok(output) } } - -fn freshen_single_trait_object_lifetime<'tcx>( - infcx: &BorrowckInferCtxt<'tcx>, - ty: Ty<'tcx>, -) -> Ty<'tcx> { - let &ty::Dynamic(tty, _, dyn_kind @ ty::Dyn) = ty.kind() else { bug!("expected trait object") }; - - let fresh = infcx - .next_region_var(rustc_infer::infer::RegionVariableOrigin::MiscVariable(DUMMY_SP), || { - RegionCtxt::Unknown - }); - infcx.tcx.mk_ty_from_kind(ty::Dynamic(tty, fresh, dyn_kind)) -} diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 462983be88d8..ea4ec345ad0c 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -895,20 +895,22 @@ impl<'a, 'tcx> CastCheck<'tcx> { // e.g. we want to allow `dyn T -> (dyn T,)`, etc. // // We also need to skip auto traits to emit an FCW and not an error. - let src_obj = tcx.mk_ty_from_kind(ty::Dynamic( + let src_obj = Ty::new_dynamic( + tcx, tcx.mk_poly_existential_predicates( &src_tty.without_auto_traits().collect::>(), ), tcx.lifetimes.re_erased, ty::Dyn, - )); - let dst_obj = tcx.mk_ty_from_kind(ty::Dynamic( + ); + let dst_obj = Ty::new_dynamic( + tcx, tcx.mk_poly_existential_predicates( &dst_tty.without_auto_traits().collect::>(), ), tcx.lifetimes.re_erased, ty::Dyn, - )); + ); // `dyn Src = dyn Dst`, this checks for matching traits/generics/projections // This is `fcx.demand_eqtype`, but inlined to give a better error. diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 41958949836a..fe42a224d9f2 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -224,7 +224,7 @@ impl<'tcx, D: TyDecoder>> Decodable for Ty<'tcx> { }) } else { let tcx = decoder.interner(); - tcx.mk_ty_from_kind(rustc_type_ir::TyKind::decode(decoder)) + tcx.mk_ty_from_kind(ty::TyKind::decode(decoder)) } } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d5617adf26b4..09e372c3e0f3 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -461,7 +461,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_param(tcx: TyCtxt<'tcx>, index: u32, name: Symbol) -> Ty<'tcx> { - tcx.mk_ty_from_kind(Param(ParamTy { index, name })) + Ty::new(tcx, Param(ParamTy { index, name })) } #[inline] From dbf8fe068a30b9dc0186410e3e977cabe4e5aedb Mon Sep 17 00:00:00 2001 From: 11happy Date: Sun, 2 Feb 2025 11:11:48 +0530 Subject: [PATCH 427/991] fix: fix overflowing hex wrong suggestion Signed-off-by: 11happy rebase Signed-off-by: 11happy fix: rebless Signed-off-by: 11happy --- compiler/rustc_lint/src/types/literal.rs | 2 +- tests/ui/lint/type-overflow.rs | 6 +++++- tests/ui/lint/type-overflow.stderr | 19 ++++++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index 3e4532a6dbee..7cb00262b6ff 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -186,7 +186,7 @@ fn report_bin_hex_error( lit_no_suffix, negative_val: actually.clone(), int_ty: int_ty.name_str(), - uint_ty: int_ty.to_unsigned().name_str(), + uint_ty: Integer::fit_unsigned(val).uint_ty_str(), }) }) .flatten(); diff --git a/tests/ui/lint/type-overflow.rs b/tests/ui/lint/type-overflow.rs index 1e74a8925f62..16a021da0658 100644 --- a/tests/ui/lint/type-overflow.rs +++ b/tests/ui/lint/type-overflow.rs @@ -41,8 +41,12 @@ fn main() { let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for `i32` //~| HELP consider using the type `u64` instead - //~| HELP + //~| HELP consider using the type `u64` for the literal and cast it to `i32` let fail = -0b1111_1111i8; //~WARNING literal out of range for `i8` //~| HELP consider using the type `i16` instead + + let fail = 0x8000_0000_0000_0000_0000_0000_FFFF_FFFE; //~WARNING literal out of range for `i32` + //~| HELP consider using the type `u128` instead + //~| HELP consider using the type `u128` for the literal and cast it to `i32` } diff --git a/tests/ui/lint/type-overflow.stderr b/tests/ui/lint/type-overflow.stderr index 4d6403b1e7db..065c530adcf5 100644 --- a/tests/ui/lint/type-overflow.stderr +++ b/tests/ui/lint/type-overflow.stderr @@ -112,9 +112,9 @@ LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; | = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into the type `i32` and will become `-2i32` = help: consider using the type `u64` instead -help: to use as a negative number (decimal `-2`), consider using the type `u32` for the literal and cast it to `i32` +help: to use as a negative number (decimal `-2`), consider using the type `u64` for the literal and cast it to `i32` | -LL | let fail = 0x8FFF_FFFF_FFFF_FFFEu32 as i32; +LL | let fail = 0x8FFF_FFFF_FFFF_FFFEu64 as i32; | ++++++++++ warning: literal out of range for `i8` @@ -126,5 +126,18 @@ LL | let fail = -0b1111_1111i8; = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into the type `i8` = note: and the value `-0b1111_1111i8` will become `1i8` -warning: 11 warnings emitted +warning: literal out of range for `i32` + --> $DIR/type-overflow.rs:49:16 + | +LL | let fail = 0x8000_0000_0000_0000_0000_0000_FFFF_FFFE; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000_0000_0000_FFFF_FFFE` (decimal `170141183460469231731687303720179073022`) does not fit into the type `i32` and will become `-2i32` + = help: consider using the type `u128` instead +help: to use as a negative number (decimal `-2`), consider using the type `u128` for the literal and cast it to `i32` + | +LL | let fail = 0x8000_0000_0000_0000_0000_0000_FFFF_FFFEu128 as i32; + | +++++++++++ + +warning: 12 warnings emitted From 5bf22375cf14d31a81362fe4230e4756e01483a0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Feb 2025 02:59:37 +0000 Subject: [PATCH 428/991] Do not yeet unsafe<> from type --- src/tools/rustfmt/src/types.rs | 6 +++++- src/tools/rustfmt/tests/source/unsafe-binders.rs | 3 +++ src/tools/rustfmt/tests/target/unsafe-binders.rs | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 0009490e86fe..7b44b47c7196 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -1019,7 +1019,11 @@ impl Rewrite for ast::Ty { } ast::TyKind::UnsafeBinder(ref binder) => { let mut result = String::new(); - if let Some(ref lifetime_str) = + if binder.generic_params.is_empty() { + // We always want to write `unsafe<>` since `unsafe<> Ty` + // and `Ty` are distinct types. + result.push_str("unsafe<> ") + } else if let Some(ref lifetime_str) = rewrite_bound_params(context, shape, &binder.generic_params) { result.push_str("unsafe<"); diff --git a/src/tools/rustfmt/tests/source/unsafe-binders.rs b/src/tools/rustfmt/tests/source/unsafe-binders.rs index ccf7c8bb9afa..2f43af54d204 100644 --- a/src/tools/rustfmt/tests/source/unsafe-binders.rs +++ b/src/tools/rustfmt/tests/source/unsafe-binders.rs @@ -9,3 +9,6 @@ struct Foo { struct Bar(unsafe<'a> &'a ()); impl Trait for unsafe<'a> &'a () {} + +fn empty() +-> unsafe<> () {} diff --git a/src/tools/rustfmt/tests/target/unsafe-binders.rs b/src/tools/rustfmt/tests/target/unsafe-binders.rs index 9d308f4a8946..d52dc5595196 100644 --- a/src/tools/rustfmt/tests/target/unsafe-binders.rs +++ b/src/tools/rustfmt/tests/target/unsafe-binders.rs @@ -7,3 +7,5 @@ struct Foo { struct Bar(unsafe<'a> &'a ()); impl Trait for unsafe<'a> &'a () {} + +fn empty() -> unsafe<> () {} From b2bb7cc8ae45e8852e4b76fa10408a1eed626412 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Thu, 27 Feb 2025 19:06:06 -0800 Subject: [PATCH 429/991] Fix char count in Display for ByteStr --- library/core/src/bstr.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/bstr.rs b/library/core/src/bstr.rs index 74e07f3d242c..ae84fd8adb61 100644 --- a/library/core/src/bstr.rs +++ b/library/core/src/bstr.rs @@ -151,7 +151,9 @@ impl fmt::Display for ByteStr { }; let nchars: usize = self .utf8_chunks() - .map(|chunk| chunk.valid().len() + if chunk.invalid().is_empty() { 0 } else { 1 }) + .map(|chunk| { + chunk.valid().chars().count() + if chunk.invalid().is_empty() { 0 } else { 1 } + }) .sum(); let padding = f.width().unwrap_or(0).saturating_sub(nchars); let fill = f.fill(); From b67b6c05032e98a5984ebb39f581125e7d0b48b9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Feb 2025 03:17:02 +0000 Subject: [PATCH 430/991] Fix sized constraint for unsafe binder --- compiler/rustc_ty_utils/src/ty.rs | 9 ++++++--- tests/ui/unsafe-binders/binder-sized-crit.rs | 18 ++++++++++++++++++ .../ui/unsafe-binders/binder-sized-crit.stderr | 11 +++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 tests/ui/unsafe-binders/binder-sized-crit.rs create mode 100644 tests/ui/unsafe-binders/binder-sized-crit.stderr diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 8ed45b4e5415..8610c30ab703 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -37,8 +37,6 @@ fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option None, - UnsafeBinder(_) => todo!(), - // these are never sized Str | Slice(..) | Dynamic(_, _, ty::Dyn) | Foreign(..) => Some(ty), @@ -52,9 +50,14 @@ fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option Some(ty), + // We cannot instantiate the binder, so just return the *original* type back, + // but only if the inner type has a sized constraint. Thus we skip the binder, + // but don't actually use the result from `sized_constraint_for_ty`. + UnsafeBinder(inner_ty) => sized_constraint_for_ty(tcx, inner_ty.skip_binder()).map(|_| ty), + Placeholder(..) | Bound(..) | Infer(..) => { bug!("unexpected type `{ty:?}` in sized_constraint_for_ty") } diff --git a/tests/ui/unsafe-binders/binder-sized-crit.rs b/tests/ui/unsafe-binders/binder-sized-crit.rs new file mode 100644 index 000000000000..37677c0ef69b --- /dev/null +++ b/tests/ui/unsafe-binders/binder-sized-crit.rs @@ -0,0 +1,18 @@ +//@ check-pass + +#![feature(unsafe_binders)] +//~^ WARN the feature `unsafe_binders` is incomplete + +use std::unsafe_binder::wrap_binder; + +struct A { + b: unsafe<> (), +} + +fn main() { + unsafe { + let _ = A { + b: wrap_binder!(()), + }; + } +} diff --git a/tests/ui/unsafe-binders/binder-sized-crit.stderr b/tests/ui/unsafe-binders/binder-sized-crit.stderr new file mode 100644 index 000000000000..3ba6cf2ef8c1 --- /dev/null +++ b/tests/ui/unsafe-binders/binder-sized-crit.stderr @@ -0,0 +1,11 @@ +warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/binder-sized-crit.rs:3:12 + | +LL | #![feature(unsafe_binders)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #130516 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + From 86945c0a545643457e551a78e8c2a90355d0f17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 28 Feb 2025 03:35:13 +0000 Subject: [PATCH 431/991] Tweak incorrect ABI suggestion Provide a better suggestion message, and make the suggestion verbose. ``` error[E0703]: invalid ABI: found `riscv-interrupt` --> $DIR/riscv-discoverability-guidance.rs:17:8 | LL | extern "riscv-interrupt" fn isr() {} | ^^^^^^^^^^^^^^^^^ invalid ABI | = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions help: there's a similarly named valid ABI `"riscv-interrupt-m"` | LL | extern "riscv-interrupt-m" fn isr() {} | ++ ``` --- compiler/rustc_ast_lowering/messages.ftl | 2 +- compiler/rustc_ast_lowering/src/errors.rs | 5 +++-- compiler/rustc_ast_lowering/src/item.rs | 2 +- ...cv-discoverability-guidance.riscv32.stderr | 19 +++++++++++-------- ...cv-discoverability-guidance.riscv64.stderr | 19 +++++++++++-------- tests/ui/suggestions/abi-typo.stderr | 10 ++++++---- 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 1b91c33742d8..f29c98164d02 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -88,7 +88,7 @@ ast_lowering_invalid_abi_clobber_abi = invalid ABI for `clobber_abi` .note = the following ABIs are supported on this target: {$supported_abis} -ast_lowering_invalid_abi_suggestion = did you mean +ast_lowering_invalid_abi_suggestion = there's a similarly named valid ABI `{$suggestion}` ast_lowering_invalid_asm_template_modifier_const = asm template modifiers are not allowed for `const` arguments diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index f31e2db051d8..766c02334087 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -46,8 +46,9 @@ pub(crate) struct TupleStructWithDefault { #[derive(Subdiagnostic)] #[suggestion( ast_lowering_invalid_abi_suggestion, - code = "{suggestion}", - applicability = "maybe-incorrect" + code = "\"{suggestion}\"", + applicability = "maybe-incorrect", + style = "verbose" )] pub(crate) struct InvalidAbiSuggestion { #[primary_span] diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index a4fc4b3e3a12..15802101f71a 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1510,7 +1510,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span: abi.span, suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion { span: abi.span, - suggestion: format!("\"{suggested_name}\""), + suggestion: suggested_name.to_string(), }), command: "rustc --print=calling-conventions".to_string(), }); diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr index e1f433479857..efa70df9277a 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr @@ -2,23 +2,26 @@ error[E0703]: invalid ABI: found `riscv-interrupt` --> $DIR/riscv-discoverability-guidance.rs:17:8 | LL | extern "riscv-interrupt" fn isr() {} - | ^^^^^^^^^^^^^^^^^ - | | - | invalid ABI - | help: did you mean: `"riscv-interrupt-m"` + | ^^^^^^^^^^^^^^^^^ invalid ABI | = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions +help: there's a similarly named valid ABI `riscv-interrupt-m` + | +LL | extern "riscv-interrupt-m" fn isr() {} + | ++ error[E0703]: invalid ABI: found `riscv-interrupt-u` --> $DIR/riscv-discoverability-guidance.rs:22:8 | LL | extern "riscv-interrupt-u" fn isr_U() {} - | ^^^^^^^^^^^^^^^^^^^ - | | - | invalid ABI - | help: did you mean: `"riscv-interrupt-m"` + | ^^^^^^^^^^^^^^^^^^^ invalid ABI | = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions +help: there's a similarly named valid ABI `riscv-interrupt-m` + | +LL - extern "riscv-interrupt-u" fn isr_U() {} +LL + extern "riscv-interrupt-m" fn isr_U() {} + | error: aborting due to 2 previous errors diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr index e1f433479857..efa70df9277a 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr @@ -2,23 +2,26 @@ error[E0703]: invalid ABI: found `riscv-interrupt` --> $DIR/riscv-discoverability-guidance.rs:17:8 | LL | extern "riscv-interrupt" fn isr() {} - | ^^^^^^^^^^^^^^^^^ - | | - | invalid ABI - | help: did you mean: `"riscv-interrupt-m"` + | ^^^^^^^^^^^^^^^^^ invalid ABI | = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions +help: there's a similarly named valid ABI `riscv-interrupt-m` + | +LL | extern "riscv-interrupt-m" fn isr() {} + | ++ error[E0703]: invalid ABI: found `riscv-interrupt-u` --> $DIR/riscv-discoverability-guidance.rs:22:8 | LL | extern "riscv-interrupt-u" fn isr_U() {} - | ^^^^^^^^^^^^^^^^^^^ - | | - | invalid ABI - | help: did you mean: `"riscv-interrupt-m"` + | ^^^^^^^^^^^^^^^^^^^ invalid ABI | = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions +help: there's a similarly named valid ABI `riscv-interrupt-m` + | +LL - extern "riscv-interrupt-u" fn isr_U() {} +LL + extern "riscv-interrupt-m" fn isr_U() {} + | error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/abi-typo.stderr b/tests/ui/suggestions/abi-typo.stderr index 5195c43220b4..4d89ac16570e 100644 --- a/tests/ui/suggestions/abi-typo.stderr +++ b/tests/ui/suggestions/abi-typo.stderr @@ -2,12 +2,14 @@ error[E0703]: invalid ABI: found `cdedl` --> $DIR/abi-typo.rs:2:8 | LL | extern "cdedl" fn cdedl() {} - | ^^^^^^^ - | | - | invalid ABI - | help: did you mean: `"cdecl"` + | ^^^^^^^ invalid ABI | = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions +help: there's a similarly named valid ABI `cdecl` + | +LL - extern "cdedl" fn cdedl() {} +LL + extern "cdecl" fn cdedl() {} + | error: aborting due to 1 previous error From 73488449c53821a8f4860f67e8580fc9eeb65e26 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 26 Feb 2025 20:24:37 +0530 Subject: [PATCH 432/991] Avoid suggesting redundant borrowing in completion results --- src/tools/rust-analyzer/crates/ide-completion/src/render.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index dc7eacbfbafd..d9f3fe132677 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -628,11 +628,9 @@ fn compute_ref_match( let expected_type = ctx.expected_type.as_ref()?; let expected_without_ref = expected_type.remove_ref(); let completion_without_ref = completion_ty.remove_ref(); - - if completion_ty == expected_type { + if expected_type.could_unify_with(ctx.db, completion_ty) { return None; } - if let Some(expected_without_ref) = &expected_without_ref { if completion_ty.autoderef(ctx.db).any(|ty| ty == *expected_without_ref) { cov_mark::hit!(suggest_ref); From 2071cc27f23aa0134e2a1f8bf3328f371ee559be Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 26 Feb 2025 22:19:22 +0530 Subject: [PATCH 433/991] add test --- .../crates/ide-completion/src/render.rs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index d9f3fe132677..4f6c4cb66393 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -2005,6 +2005,30 @@ fn f() { ); } + #[test] + fn test_avoid_redundant_suggestion() { + check_relevance( + r#" +struct aa([u8]); + +impl aa { + fn from_bytes(bytes: &[u8]) -> &Self { + unsafe { &*(bytes as *const [u8] as *const aa) } + } +} + +fn bb()-> &'static aa { + let bytes = b"hello"; + aa::$0 +} +"#, + expect![[r#" + ex bb() [type] + fn from_bytes(…) fn(&[u8]) -> &aa [type_could_unify] + "#]], + ); + } + #[test] fn suggest_ref_mut() { cov_mark::check!(suggest_ref); From 5f58985f5df2e7fbbef6c1acf54ece9df90ccbf3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 28 Feb 2025 16:34:41 +1100 Subject: [PATCH 434/991] Remove `rustc_transmute`'s dependence on `rustc_infer`. `TransmuteTypeEnv` only needs a `TyCtxt`, not an `InferCtxt`. --- Cargo.lock | 1 - .../error_reporting/traits/fulfillment_errors.rs | 2 +- .../rustc_trait_selection/src/solve/delegate.rs | 2 +- .../src/traits/select/confirmation.rs | 2 +- compiler/rustc_transmute/Cargo.toml | 2 -- compiler/rustc_transmute/src/lib.rs | 13 ++++++------- 6 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb4cf235c6f4..4cb87ec4413f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4500,7 +4500,6 @@ dependencies = [ "rustc_abi", "rustc_data_structures", "rustc_hir", - "rustc_infer", "rustc_macros", "rustc_middle", "rustc_span", diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 596f794568c5..b2cc1804673c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2544,7 +2544,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let src = trait_pred.trait_ref.args.type_at(1); let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`"); - match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable( + match rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx).is_transmutable( obligation.cause, src_and_dst, assume, diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 58d8a3a62547..550ffe8cc3bd 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -236,7 +236,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< }; // FIXME(transmutability): This really should be returning nested goals for `Answer::If*` - match rustc_transmute::TransmuteTypeEnv::new(&self.0).is_transmutable( + match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx).is_transmutable( ObligationCause::dummy(), rustc_transmute::Types { src, dst }, assume, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 32cbb97e314d..53c61c15a21a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -424,7 +424,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let src = predicate.trait_ref.args.type_at(1); debug!(?src, ?dst); - let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx); + let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx); let maybe_transmutable = transmute_env.is_transmutable( obligation.cause.clone(), rustc_transmute::Types { dst, src }, diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index e9daf6b0c384..3b6bb59196e2 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" rustc_abi = { path = "../rustc_abi", optional = true } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir", optional = true } -rustc_infer = { path = "../rustc_infer", optional = true } rustc_macros = { path = "../rustc_macros", optional = true } rustc_middle = { path = "../rustc_middle", optional = true } rustc_span = { path = "../rustc_span", optional = true } @@ -19,7 +18,6 @@ tracing = "0.1" rustc = [ "dep:rustc_abi", "dep:rustc_hir", - "dep:rustc_infer", "dep:rustc_macros", "dep:rustc_middle", "dep:rustc_span", diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index f9537f708ef8..9726c9e98aad 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -81,7 +81,6 @@ pub enum Reason { #[cfg(feature = "rustc")] mod rustc { use rustc_hir::lang_items::LangItem; - use rustc_infer::infer::InferCtxt; use rustc_macros::TypeVisitable; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{Const, ParamEnv, Ty, TyCtxt}; @@ -97,13 +96,13 @@ mod rustc { pub dst: Ty<'tcx>, } - pub struct TransmuteTypeEnv<'cx, 'tcx> { - infcx: &'cx InferCtxt<'tcx>, + pub struct TransmuteTypeEnv<'tcx> { + tcx: TyCtxt<'tcx>, } - impl<'cx, 'tcx> TransmuteTypeEnv<'cx, 'tcx> { - pub fn new(infcx: &'cx InferCtxt<'tcx>) -> Self { - Self { infcx } + impl<'tcx> TransmuteTypeEnv<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>) -> Self { + Self { tcx } } #[allow(unused)] @@ -117,7 +116,7 @@ mod rustc { types.src, types.dst, assume, - self.infcx.tcx, + self.tcx, ) .answer() } From 43e017fd01c5ecb74dccee44c6f7b360cf7a518a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 28 Feb 2025 16:38:07 +1100 Subject: [PATCH 435/991] Remove `rustc_transmute`'s dependence on `rustc_macros`. --- Cargo.lock | 1 - compiler/rustc_transmute/Cargo.toml | 2 -- compiler/rustc_transmute/src/lib.rs | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4cb87ec4413f..572d4c6b49d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4500,7 +4500,6 @@ dependencies = [ "rustc_abi", "rustc_data_structures", "rustc_hir", - "rustc_macros", "rustc_middle", "rustc_span", "tracing", diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index 3b6bb59196e2..f0c783b30020 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" rustc_abi = { path = "../rustc_abi", optional = true } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir", optional = true } -rustc_macros = { path = "../rustc_macros", optional = true } rustc_middle = { path = "../rustc_middle", optional = true } rustc_span = { path = "../rustc_span", optional = true } tracing = "0.1" @@ -18,7 +17,6 @@ tracing = "0.1" rustc = [ "dep:rustc_abi", "dep:rustc_hir", - "dep:rustc_macros", "dep:rustc_middle", "dep:rustc_span", ] diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 9726c9e98aad..e10532af1455 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -81,14 +81,13 @@ pub enum Reason { #[cfg(feature = "rustc")] mod rustc { use rustc_hir::lang_items::LangItem; - use rustc_macros::TypeVisitable; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{Const, ParamEnv, Ty, TyCtxt}; use super::*; /// The source and destination types of a transmutation. - #[derive(TypeVisitable, Debug, Clone, Copy)] + #[derive(Debug, Clone, Copy)] pub struct Types<'tcx> { /// The source type. pub src: Ty<'tcx>, From 1970311146873c6f061035ed22d483d36fd978f7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 28 Feb 2025 16:42:11 +1100 Subject: [PATCH 436/991] Remove unnecessary `allow(unused)` attribute. --- compiler/rustc_transmute/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index e10532af1455..740c899fbf88 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -104,7 +104,6 @@ mod rustc { Self { tcx } } - #[allow(unused)] pub fn is_transmutable( &mut self, cause: ObligationCause<'tcx>, From dfb22229521cac9ede98d8f6f8b765ccc3defb86 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 28 Feb 2025 16:53:09 +1100 Subject: [PATCH 437/991] Remove unused feature from `rustc_transmute`. --- compiler/rustc_transmute/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 740c899fbf88..39250f0eb3f0 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![allow(unused_variables)] -#![feature(alloc_layout_extra)] #![feature(never_type)] #![warn(unreachable_pub)] // tidy-alphabetical-end From 785e21d382ed83121cb3751c1fd05147c2eb41f2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 28 Feb 2025 16:52:28 +1100 Subject: [PATCH 438/991] Remove `allow(unused_variables)` for `rustc_transmute`. This was hiding some genuine sins, including unused arguments in numerous functions/methods (incl. trait methods), and some unnecessary computation. --- compiler/rustc_next_trait_solver/src/delegate.rs | 1 - .../src/solve/eval_ctxt/mod.rs | 3 +-- .../src/solve/trait_goals.rs | 1 - .../error_reporting/traits/fulfillment_errors.rs | 12 ++++-------- .../rustc_trait_selection/src/solve/delegate.rs | 12 ++++-------- .../src/traits/select/confirmation.rs | 11 +++-------- compiler/rustc_transmute/src/layout/tree.rs | 14 ++++++-------- compiler/rustc_transmute/src/lib.rs | 16 +++------------- .../src/maybe_transmutable/mod.rs | 6 +++--- .../src/maybe_transmutable/tests.rs | 1 - 10 files changed, 24 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index a64941cce3af..850d86d91e88 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -102,7 +102,6 @@ pub trait SolverDelegate: Deref + Sized { fn is_transmutable( &self, - param_env: ::ParamEnv, dst: ::Ty, src: ::Ty, assume: ::Const, diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index b0a34b9ce756..8d3afe7e13f6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -1037,12 +1037,11 @@ where pub(super) fn is_transmutable( &mut self, - param_env: I::ParamEnv, dst: I::Ty, src: I::Ty, assume: I::Const, ) -> Result { - self.delegate.is_transmutable(param_env, dst, src, assume) + self.delegate.is_transmutable(dst, src, assume) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 1665dbb30189..22d29fc535c4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -617,7 +617,6 @@ where )?; let certainty = ecx.is_transmutable( - goal.param_env, goal.predicate.trait_ref.args.type_at(0), goal.predicate.trait_ref.args.type_at(1), assume, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index b2cc1804673c..8902e935b6c9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2530,9 +2530,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return GetSafeTransmuteErrorAndReason::Silent; }; - let Some(assume) = - rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, assume) - else { + let Some(assume) = rustc_transmute::Assume::from_const(self.infcx.tcx, assume) else { self.dcx().span_delayed_bug( span, "Unable to construct rustc_transmute::Assume where it was previously possible", @@ -2544,11 +2542,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let src = trait_pred.trait_ref.args.type_at(1); let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`"); - match rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx).is_transmutable( - obligation.cause, - src_and_dst, - assume, - ) { + match rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx) + .is_transmutable(src_and_dst, assume) + { Answer::No(reason) => { let safe_transmute_explanation = match reason { rustc_transmute::Reason::SrcIsNotYetSupported => { diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 550ffe8cc3bd..e69bad095e33 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -7,7 +7,6 @@ use rustc_infer::infer::canonical::{ Canonical, CanonicalExt as _, CanonicalQueryInput, CanonicalVarInfo, CanonicalVarValues, }; use rustc_infer::infer::{InferCtxt, RegionVariableOrigin, TyCtxtInferExt}; -use rustc_infer::traits::ObligationCause; use rustc_infer::traits::solve::Goal; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; @@ -222,7 +221,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< // register candidates. We probably need to register >1 since we may have an OR of ANDs. fn is_transmutable( &self, - param_env: ty::ParamEnv<'tcx>, dst: Ty<'tcx>, src: Ty<'tcx>, assume: ty::Const<'tcx>, @@ -231,16 +229,14 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< // which will ICE for region vars. let (dst, src) = self.tcx.erase_regions((dst, src)); - let Some(assume) = rustc_transmute::Assume::from_const(self.tcx, param_env, assume) else { + let Some(assume) = rustc_transmute::Assume::from_const(self.tcx, assume) else { return Err(NoSolution); }; // FIXME(transmutability): This really should be returning nested goals for `Answer::If*` - match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx).is_transmutable( - ObligationCause::dummy(), - rustc_transmute::Types { src, dst }, - assume, - ) { + match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx) + .is_transmutable(rustc_transmute::Types { src, dst }, assume) + { rustc_transmute::Answer::Yes => Ok(Certainty::Yes), rustc_transmute::Answer::No(_) | rustc_transmute::Answer::If(_) => Err(NoSolution), } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 53c61c15a21a..a58317dd56d2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -414,9 +414,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if self.tcx().features().generic_const_exprs() { assume = crate::traits::evaluate_const(self.infcx, assume, obligation.param_env) } - let Some(assume) = - rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, assume) - else { + let Some(assume) = rustc_transmute::Assume::from_const(self.infcx.tcx, assume) else { return Err(Unimplemented); }; @@ -425,11 +423,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?src, ?dst); let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx); - let maybe_transmutable = transmute_env.is_transmutable( - obligation.cause.clone(), - rustc_transmute::Types { dst, src }, - assume, - ); + let maybe_transmutable = + transmute_env.is_transmutable(rustc_transmute::Types { dst, src }, assume); let fully_flattened = match maybe_transmutable { Answer::No(_) => Err(Unimplemented)?, diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index b00585d29221..a21be5dda4ee 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -237,7 +237,7 @@ pub(crate) mod rustc { ty::Tuple(members) => Self::from_tuple((ty, layout), members, cx), - ty::Array(inner_ty, len) => { + ty::Array(inner_ty, _len) => { let FieldsShape::Array { stride, count } = &layout.fields else { return Err(Err::NotYetSupported); }; @@ -282,7 +282,6 @@ pub(crate) mod rustc { FieldsShape::Primitive => { assert_eq!(members.len(), 1); let inner_ty = members[0]; - let inner_layout = layout_of(cx, inner_ty)?; Self::from_ty(inner_ty, cx) } FieldsShape::Arbitrary { offsets, .. } => { @@ -345,7 +344,7 @@ pub(crate) mod rustc { // the enum delegates its layout to the variant at `index`. layout_of_variant(*index, None) } - Variants::Multiple { tag, tag_encoding, tag_field, .. } => { + Variants::Multiple { tag: _, tag_encoding, tag_field, .. } => { // `Variants::Multiple` denotes an enum with multiple // variants. The layout of such an enum is the disjunction // of the layouts of its tagged variants. @@ -356,7 +355,7 @@ pub(crate) mod rustc { let variants = def.discriminants(cx.tcx()).try_fold( Self::uninhabited(), - |variants, (idx, ref discriminant)| { + |variants, (idx, _discriminant)| { let variant = layout_of_variant(idx, Some(tag_encoding.clone()))?; Result::::Ok(variants.or(variant)) }, @@ -414,7 +413,7 @@ pub(crate) mod rustc { // Append the fields, in memory order, to the layout. let inverse_memory_index = memory_index.invert_bijective_mapping(); - for (memory_idx, &field_idx) in inverse_memory_index.iter_enumerated() { + for &field_idx in inverse_memory_index.iter() { // Add interfield padding. let padding_needed = offsets[field_idx] - size; let padding = Self::padding(padding_needed.bytes_usize()); @@ -468,15 +467,14 @@ pub(crate) mod rustc { // This constructor does not support non-`FieldsShape::Union` // layouts. Fields of this shape are all placed at offset 0. - let FieldsShape::Union(fields) = layout.fields() else { + let FieldsShape::Union(_fields) = layout.fields() else { return Err(Err::NotYetSupported); }; let fields = &def.non_enum_variant().fields; let fields = fields.iter_enumerated().try_fold( Self::uninhabited(), - |fields, (idx, field_def)| { - let field_def = Def::Field(field_def); + |fields, (idx, _field_def)| { let field_ty = ty_field(cx, (ty, layout), idx); let field_layout = layout_of(cx, field_ty)?; let field = Self::from_ty(field_ty, cx)?; diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 39250f0eb3f0..81a11f7cfb26 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![allow(unused_variables)] #![feature(never_type)] #![warn(unreachable_pub)] // tidy-alphabetical-end @@ -80,8 +79,7 @@ pub enum Reason { #[cfg(feature = "rustc")] mod rustc { use rustc_hir::lang_items::LangItem; - use rustc_middle::traits::ObligationCause; - use rustc_middle::ty::{Const, ParamEnv, Ty, TyCtxt}; + use rustc_middle::ty::{Const, Ty, TyCtxt}; use super::*; @@ -105,15 +103,11 @@ mod rustc { pub fn is_transmutable( &mut self, - cause: ObligationCause<'tcx>, types: Types<'tcx>, assume: crate::Assume, ) -> crate::Answer> { crate::maybe_transmutable::MaybeTransmutableQuery::new( - types.src, - types.dst, - assume, - self.tcx, + types.src, types.dst, assume, self.tcx, ) .answer() } @@ -121,11 +115,7 @@ mod rustc { impl Assume { /// Constructs an `Assume` from a given const-`Assume`. - pub fn from_const<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - ct: Const<'tcx>, - ) -> Option { + pub fn from_const<'tcx>(tcx: TyCtxt<'tcx>, ct: Const<'tcx>) -> Option { use rustc_middle::ty::ScalarInt; use rustc_span::sym; diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs index 023c8fad781d..63fabc9c83d9 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs @@ -79,12 +79,12 @@ where pub(crate) fn answer(self) -> Answer<::Ref> { let Self { src, dst, assume, context } = self; - // Unconditionally all `Def` nodes from `src`, without pruning away the + // Unconditionally remove all `Def` nodes from `src`, without pruning away the // branches they appear in. This is valid to do for value-to-value // transmutations, but not for `&mut T` to `&mut U`; we will need to be // more sophisticated to handle transmutations between mutable // references. - let src = src.prune(&|def| false); + let src = src.prune(&|_def| false); if src.is_inhabited() && !dst.is_inhabited() { return Answer::No(Reason::DstUninhabited); @@ -96,7 +96,7 @@ where let dst = if assume.safety { // ...if safety is assumed, don't check if they carry safety // invariants; retain all paths. - dst.prune(&|def| false) + dst.prune(&|_def| false) } else { // ...otherwise, prune away all paths with safety invariants from // the `Dst` layout. diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs index 84af20c773e0..4d81382eba02 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs @@ -92,7 +92,6 @@ mod bool { #[test] fn should_permit_validity_expansion_and_reject_contraction() { - let un = layout::Tree::::uninhabited(); let b0 = layout::Tree::::from_bits(0); let b1 = layout::Tree::::from_bits(1); let b2 = layout::Tree::::from_bits(2); From b0530c9361603f9317a598c4854f8ab3469a9d40 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 28 Feb 2025 17:30:25 +1100 Subject: [PATCH 439/991] Remove `allow(dead_code)` attributes. By either removing the function, or change the attribute to something more precise. --- compiler/rustc_transmute/src/layout/dfa.rs | 11 +---------- compiler/rustc_transmute/src/layout/nfa.rs | 5 ----- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/compiler/rustc_transmute/src/layout/dfa.rs b/compiler/rustc_transmute/src/layout/dfa.rs index a70dc034e63d..a29baade42fb 100644 --- a/compiler/rustc_transmute/src/layout/dfa.rs +++ b/compiler/rustc_transmute/src/layout/dfa.rs @@ -38,7 +38,7 @@ impl Transitions where R: Ref, { - #[allow(dead_code)] + #[cfg(test)] fn insert(&mut self, transition: Transition, state: State) { match transition { Transition::Byte(b) => { @@ -86,15 +86,6 @@ impl Dfa where R: Ref, { - #[allow(dead_code)] - pub(crate) fn unit() -> Self { - let transitions: Map> = Map::default(); - let start = State::new(); - let accepting = start; - - Self { transitions, start, accepting } - } - #[cfg(test)] pub(crate) fn bool() -> Self { let mut transitions: Map> = Map::default(); diff --git a/compiler/rustc_transmute/src/layout/nfa.rs b/compiler/rustc_transmute/src/layout/nfa.rs index 3b49c59fa686..9c21fd94f03e 100644 --- a/compiler/rustc_transmute/src/layout/nfa.rs +++ b/compiler/rustc_transmute/src/layout/nfa.rs @@ -159,11 +159,6 @@ where } Self { transitions, start, accepting } } - - #[allow(dead_code)] - pub(crate) fn edges_from(&self, start: State) -> Option<&Map, Set>> { - self.transitions.get(&start) - } } impl State { From 4c452857e88549008b5ae720b358339a114f86a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 26 Feb 2025 11:59:00 +0100 Subject: [PATCH 440/991] Add `dist:Gcc` build step To distribute the prebuilt libgccjit.so from CI. --- src/bootstrap/src/core/build_steps/dist.rs | 27 ++++++++++++++++++++++ src/bootstrap/src/core/builder/mod.rs | 1 + src/tools/opt-dist/src/main.rs | 1 + 3 files changed, 29 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 26b3e0b701c4..e0ad6856dc72 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2464,3 +2464,30 @@ impl Step for ReproducibleArtifacts { if added_anything { Some(tarball.generate()) } else { None } } } + +/// Tarball containing a prebuilt version of the libgccjit library, +/// needed as a dependency for the GCC codegen backend (similarly to the LLVM +/// backend needing a prebuilt libLLVM). +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Gcc { + pub target: TargetSelection, +} + +impl Step for Gcc { + type Output = GeneratedTarball; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("gcc") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Gcc { target: run.target }); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let tarball = Tarball::new(builder, "gcc", &self.target.triple); + let output = builder.ensure(super::gcc::Gcc { target: self.target }); + tarball.add_file(output.libgccjit, ".", 0o644); + tarball.generate() + } +} diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 9c04f097bee2..10bd67c5b6c1 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1072,6 +1072,7 @@ impl<'a> Builder<'a> { dist::PlainSourceTarball, dist::BuildManifest, dist::ReproducibleArtifacts, + dist::Gcc ), Kind::Install => describe!( install::Docs, diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 565721a90934..3111149f2ae2 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -389,6 +389,7 @@ fn main() -> anyhow::Result<()> { "clippy", "miri", "rustfmt", + "gcc", ] { build_args.extend(["--skip".to_string(), target.to_string()]); } From e4bfad2ba1ee8df8147a41e480d0c2735e12dbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 28 Feb 2025 09:43:05 +0100 Subject: [PATCH 441/991] Build GCC on the Linux x64 dist runner --- src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 0b4682ac32ba..f54ecef1e308 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -101,7 +101,7 @@ ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \ ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \ --host $HOSTS --target $HOSTS \ --include-default-paths \ - build-manifest bootstrap + build-manifest bootstrap gcc ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang # This is the only builder which will create source tarballs From 41dd80aeaa706c169df62bdf16033b61b914cb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 26 Feb 2025 14:29:19 +0100 Subject: [PATCH 442/991] add test to reproduce #137662 (using ty decl macro fragment in an attr) and fix it --- compiler/rustc_attr_parsing/src/parser.rs | 9 +++++++++ .../attributes/decl_macro_ty_in_attr_macro.rs | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/ui/attributes/decl_macro_ty_in_attr_macro.rs diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index b6d66af4466e..6c2448b75128 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -473,6 +473,15 @@ impl<'a> MetaItemListParserContext<'a> { { self.inside_delimiters.next(); return Some(MetaItemOrLitParser::Lit(lit)); + } else if let Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) = + self.inside_delimiters.peek() + { + self.inside_delimiters.next(); + return MetaItemListParserContext { + inside_delimiters: inner_tokens.iter().peekable(), + dcx: self.dcx, + } + .next(); } // or a path. diff --git a/tests/ui/attributes/decl_macro_ty_in_attr_macro.rs b/tests/ui/attributes/decl_macro_ty_in_attr_macro.rs new file mode 100644 index 000000000000..e633c08be3ad --- /dev/null +++ b/tests/ui/attributes/decl_macro_ty_in_attr_macro.rs @@ -0,0 +1,20 @@ +// tests for #137662: using a ty or (or most other) fragment inside an attr macro wouldn't work +// because of a missing code path. With $repr: tt it did work. +//@ check-pass + +macro_rules! foo { + { + $repr:ty + } => { + #[repr($repr)] + pub enum Foo { + Bar = 0i32, + } + } +} + +foo! { + i32 +} + +fn main() {} From 90390a1642fcfc2050f06d897faa8cb36f106303 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 28 Feb 2025 03:53:22 -0500 Subject: [PATCH 443/991] update enzyme to handle range metadata --- src/tools/enzyme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/enzyme b/src/tools/enzyme index 5004a8f6f5d8..a35f4f773118 160000 --- a/src/tools/enzyme +++ b/src/tools/enzyme @@ -1 +1 @@ -Subproject commit 5004a8f6f5d8468b64fae457afb7d96e1784c783 +Subproject commit a35f4f773118ccfbd8d05102eb12a34097b1ee55 From 25617c7e695d716d0ecb3cf2366d371441505e47 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 27 Feb 2025 21:50:30 +0000 Subject: [PATCH 444/991] Remove Win SDK 10.0.26100.0 from CI --- .github/workflows/ci.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de144ee6104c..949932b8e2aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -179,6 +179,20 @@ jobs: - name: show the current environment run: src/ci/scripts/dump-environment.sh + # Temporary fix to unblock CI + # Remove the latest Windows SDK for 32-bit Windows MSVC builds. + # See issue https://github.com/rust-lang/rust/issues/137733 for more details. + - name: Remove Windows SDK 10.0.26100.0 + shell: powershell + if: ${{ matrix.name == 'i686-msvc-1' || matrix.name == 'i686-msvc-2' || matrix.name == 'dist-i686-msvc' }} + run: | + $kits = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots').KitsRoot10 + $sdk_version = "10.0.26100.0" + + foreach ($kind in 'Bin', 'Lib', 'Include') { + Remove-Item -Force -Recurse $kits\$kind\$sdk_version -ErrorAction Continue + } + - name: run the build # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. run: src/ci/scripts/run-build-from-ci.sh 2>&1 From 637dbe56fa651c8ce1f37fb8c78c959a55742e46 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 Feb 2025 09:45:24 +0100 Subject: [PATCH 445/991] Fix prefix adjustment hints unnecessarily introducing parens --- .../crates/ide/src/inlay_hints/adjustment.rs | 14 ++++++++++--- .../crates/syntax/src/ast/prec.rs | 21 +++++++++++-------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs index d3b95750f7e1..40156ace26bc 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs @@ -260,7 +260,7 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, if postfix { // postfix ops have higher precedence than any other operator, so we need to wrap // any inner expression that is below (except for jumps if they don't have a value) - let needs_inner_parens = prec < ExprPrecedence::Unambiguous && { + let needs_inner_parens = prec < ExprPrecedence::Postfix && { prec != ExprPrecedence::Jump || !expr.is_ret_like_with_no_value() }; // given we are the higher precedence, no parent expression will have stronger requirements @@ -276,9 +276,12 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, // if we are already wrapped, great, no need to wrap again .filter(|it| !matches!(it, ast::Expr::ParenExpr(_))) .map(|it| it.precedence()); + // if we have no parent, we don't need outer parens to disambiguate // otherwise anything with higher precedence than what we insert needs to wrap us - let needs_outer_parens = parent.is_some_and(|prec| prec > ExprPrecedence::Prefix); + // that means only postfix ops + let needs_outer_parens = + parent.is_some_and(|parent_prec| parent_prec == ExprPrecedence::Postfix); (needs_outer_parens, needs_inner_parens) } } @@ -291,7 +294,7 @@ mod tests { }; #[test] - fn adjustment_hints() { + fn adjustment_hints_prefix() { check_with_config( InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG }, r#" @@ -381,6 +384,8 @@ fn main() { &mut Struct[0]; //^^^^^^(&mut $ //^^^^^^) + let _: (&mut (),) = (&mut (),); + //^^^^^^^&mut * } #[derive(Copy, Clone)] @@ -472,6 +477,9 @@ fn main() { //^^^^^^.& &mut Struct[0]; //^^^^^^.&mut + let _: (&mut (),) = (&mut (),); + //^^^^^^^( + //^^^^^^^).*.&mut } #[derive(Copy, Clone)] diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs index 5d33f132ac15..a7f1a3788c2a 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs @@ -35,7 +35,9 @@ pub enum ExprPrecedence { Cast, // unary - * ! & &mut Prefix, - // paths, loops, function calls, array indexing, field expressions, method calls + // function calls, array indexing, field expressions, method calls + Postfix, + // paths, loops, Unambiguous, } @@ -57,6 +59,7 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence { }, Expr::BreakExpr(_) + | Expr::BecomeExpr(_) | Expr::ContinueExpr(_) | Expr::ReturnExpr(_) | Expr::YeetExpr(_) @@ -89,27 +92,27 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence { Expr::LetExpr(_) | Expr::PrefixExpr(_) | Expr::RefExpr(_) => ExprPrecedence::Prefix, - Expr::ArrayExpr(_) - | Expr::AsmExpr(_) - | Expr::AwaitExpr(_) - | Expr::BecomeExpr(_) - | Expr::BlockExpr(_) + Expr::AwaitExpr(_) | Expr::CallExpr(_) | Expr::FieldExpr(_) + | Expr::IndexExpr(_) + | Expr::MethodCallExpr(_) + | Expr::TryExpr(_) => ExprPrecedence::Postfix, + + Expr::ArrayExpr(_) + | Expr::AsmExpr(_) + | Expr::BlockExpr(_) | Expr::ForExpr(_) | Expr::FormatArgsExpr(_) | Expr::IfExpr(_) - | Expr::IndexExpr(_) | Expr::Literal(_) | Expr::LoopExpr(_) | Expr::MacroExpr(_) | Expr::MatchExpr(_) - | Expr::MethodCallExpr(_) | Expr::OffsetOfExpr(_) | Expr::ParenExpr(_) | Expr::PathExpr(_) | Expr::RecordExpr(_) - | Expr::TryExpr(_) | Expr::TupleExpr(_) | Expr::UnderscoreExpr(_) | Expr::WhileExpr(_) => ExprPrecedence::Unambiguous, From 786fc1b0a78b424c06d9d08f00fa0dcff980bbdb Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 28 Feb 2025 10:32:57 +0100 Subject: [PATCH 446/991] Fix typo in query expansion documentation --- compiler/rustc_middle/src/query/plumbing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 690b8128b1ae..66a9e5fed4c3 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -258,7 +258,7 @@ macro_rules! query_if_arena { }; } -/// If `separate_provide_if_extern`, then the key can be projected to its +/// If `separate_provide_extern`, then the key can be projected to its /// local key via `<$K as AsLocalKey>::LocalKey`. macro_rules! local_key_if_separate_extern { ([] $($K:tt)*) => { From 1ccff0e01a8dd25623b535bc80b4d5d791e8f62d Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 18 Feb 2025 15:05:22 +0100 Subject: [PATCH 447/991] support rust.channel = "auto-detect" --- config.example.toml | 9 +++++---- src/bootstrap/src/core/config/config.rs | 6 +++++- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/config.example.toml b/config.example.toml index a17d3ec9f884..2e26c024865d 100644 --- a/config.example.toml +++ b/config.example.toml @@ -608,11 +608,12 @@ # The "channel" for the Rust build to produce. The stable/beta channels only # allow using stable features, whereas the nightly and dev channels allow using -# nightly features +# nightly features. # -# If using tarball sources, default value for `channel` is taken from the `src/ci/channel` file; -# otherwise, it's "dev". -#channel = if "is a tarball source" { content of `src/ci/channel` file } else { "dev" } +# You can set the channel to "auto-detect" to load the channel name from `src/ci/channel`. +# +# If using tarball sources, default value is "auto-detect", otherwise, it's "dev". +#channel = if "is a tarball source" { "auto-detect" } else { "dev" } # A descriptive string to be appended to `rustc --version` output, which is # also used in places like debuginfo `DW_AT_producer`. This may be useful for diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 2be42f16e2ab..d0e0ed50ad89 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1777,7 +1777,11 @@ impl Config { let is_user_configured_rust_channel = if let Some(channel) = toml.rust.as_ref().and_then(|r| r.channel.clone()) { - config.channel = channel; + if channel == "auto-detect" { + config.channel = ci_channel.into(); + } else { + config.channel = channel; + } true } else { false diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 8dfe0d3a35ef..5f49c50c5ad3 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -360,4 +360,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "Added `build.test-stage = 2` to 'tools' profile defaults", }, + ChangeInfo { + change_id: 137220, + severity: ChangeSeverity::Info, + summary: "`rust.channel` now supports \"auto-detect\" to load the channel from `src/ci/channel`", + }, ]; From ff7de58156e38b0aa76eda1b9088f1ce16a579be Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 Feb 2025 09:45:24 +0100 Subject: [PATCH 448/991] Have inline_local_variable use precedence calculation for parentheses --- .../src/handlers/inline_const_as_literal.rs | 23 ++------ .../src/handlers/inline_local_variable.rs | 59 ++++++++----------- .../crates/ide/src/inlay_hints/adjustment.rs | 12 ++-- .../crates/syntax/src/ast/prec.rs | 13 +++- .../crates/syntax/src/ast/token_ext.rs | 4 +- 5 files changed, 44 insertions(+), 67 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs index c92c22378f87..139078eee7c4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs @@ -39,25 +39,10 @@ pub(crate) fn inline_const_as_literal(acc: &mut Assists, ctx: &AssistContext<'_> // FIXME: Add support to handle type aliases for builtin scalar types. validate_type_recursively(ctx, Some(&konst_ty), false, fuel)?; - let expr = konst.value(ctx.sema.db)?; - - let value = match expr { - ast::Expr::BlockExpr(_) - | ast::Expr::Literal(_) - | ast::Expr::RefExpr(_) - | ast::Expr::ArrayExpr(_) - | ast::Expr::TupleExpr(_) - | ast::Expr::IfExpr(_) - | ast::Expr::ParenExpr(_) - | ast::Expr::MatchExpr(_) - | ast::Expr::MacroExpr(_) - | ast::Expr::BinExpr(_) - | ast::Expr::CallExpr(_) => konst - .eval(ctx.sema.db) - .ok()? - .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)), - _ => return None, - }; + let value = konst + .eval(ctx.sema.db) + .ok()? + .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)); let id = AssistId("inline_const_as_literal", AssistKind::RefactorInline); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs index b9fc075ae838..5d4fbfc10ab0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs @@ -5,7 +5,11 @@ use ide_db::{ EditionedFileId, RootDatabase, }; use syntax::{ - ast::{self, AstNode, AstToken, HasName}, + ast::{ + self, + prec::{precedence, ExprPrecedence}, + AstNode, AstToken, HasName, + }, SyntaxElement, TextRange, }; @@ -79,33 +83,16 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) Some(u) => u, None => return Some((range, name_ref, false)), }; - let initializer = matches!( - initializer_expr, - ast::Expr::CallExpr(_) - | ast::Expr::IndexExpr(_) - | ast::Expr::MethodCallExpr(_) - | ast::Expr::FieldExpr(_) - | ast::Expr::TryExpr(_) - | ast::Expr::Literal(_) - | ast::Expr::TupleExpr(_) - | ast::Expr::ArrayExpr(_) - | ast::Expr::ParenExpr(_) - | ast::Expr::PathExpr(_) - | ast::Expr::BlockExpr(_), - ); - let parent = matches!( - usage_parent, - ast::Expr::TupleExpr(_) - | ast::Expr::ArrayExpr(_) - | ast::Expr::ParenExpr(_) - | ast::Expr::ForExpr(_) - | ast::Expr::WhileExpr(_) - | ast::Expr::BreakExpr(_) - | ast::Expr::ReturnExpr(_) - | ast::Expr::MatchExpr(_) - | ast::Expr::BlockExpr(_) - ); - Some((range, name_ref, !(initializer || parent))) + let initializer = precedence(&initializer_expr); + let parent = precedence(&usage_parent); + Some(( + range, + name_ref, + parent != ExprPrecedence::Unambiguous + && initializer < parent + // initializer == ExprPrecedence::Prefix -> parent != ExprPrecedence::Jump + && (initializer != ExprPrecedence::Prefix || parent != ExprPrecedence::Jump), + )) }) .collect::>>()?; @@ -281,11 +268,11 @@ fn foo() { r" fn bar(a: usize) {} fn foo() { - (1 + 1) + 1; - if (1 + 1) > 10 { + 1 + 1 + 1; + if 1 + 1 > 10 { } - while (1 + 1) > 10 { + while 1 + 1 > 10 { } let b = (1 + 1) * 10; @@ -350,14 +337,14 @@ fn foo() { r" fn bar(a: usize) -> usize { a } fn foo() { - (bar(1) as u64) + 1; - if (bar(1) as u64) > 10 { + bar(1) as u64 + 1; + if bar(1) as u64 > 10 { } - while (bar(1) as u64) > 10 { + while bar(1) as u64 > 10 { } - let b = (bar(1) as u64) * 10; + let b = bar(1) as u64 * 10; bar(bar(1) as u64); }", ); @@ -574,7 +561,7 @@ fn foo() { r" fn foo() { let bar = 10; - let b = (&bar) * 10; + let b = &bar * 10; }", ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs index 40156ace26bc..6b2e41f42b6b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs @@ -259,10 +259,8 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, let prec = expr.precedence(); if postfix { // postfix ops have higher precedence than any other operator, so we need to wrap - // any inner expression that is below (except for jumps if they don't have a value) - let needs_inner_parens = prec < ExprPrecedence::Postfix && { - prec != ExprPrecedence::Jump || !expr.is_ret_like_with_no_value() - }; + // any inner expression that is below + let needs_inner_parens = prec < ExprPrecedence::Postfix; // given we are the higher precedence, no parent expression will have stronger requirements let needs_outer_parens = false; (needs_outer_parens, needs_inner_parens) @@ -275,13 +273,13 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, .and_then(ast::Expr::cast) // if we are already wrapped, great, no need to wrap again .filter(|it| !matches!(it, ast::Expr::ParenExpr(_))) - .map(|it| it.precedence()); + .map(|it| it.precedence()) + .filter(|&prec| prec != ExprPrecedence::Unambiguous); // if we have no parent, we don't need outer parens to disambiguate // otherwise anything with higher precedence than what we insert needs to wrap us - // that means only postfix ops let needs_outer_parens = - parent.is_some_and(|parent_prec| parent_prec == ExprPrecedence::Postfix); + parent.is_some_and(|parent_prec| parent_prec > ExprPrecedence::Prefix); (needs_outer_parens, needs_inner_parens) } } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs index a7f1a3788c2a..2a47b3bea5b6 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs @@ -7,7 +7,7 @@ use crate::{ #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] pub enum ExprPrecedence { - // return, break, yield, closures + // return val, break val, yield val, closures Jump, // = += -= *= /= %= &= |= ^= <<= >>= Assign, @@ -58,12 +58,18 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence { Some(_) => ExprPrecedence::Unambiguous, }, + Expr::BreakExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::BecomeExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::ReturnExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::YeetExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::YieldExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::BreakExpr(_) | Expr::BecomeExpr(_) - | Expr::ContinueExpr(_) | Expr::ReturnExpr(_) | Expr::YeetExpr(_) - | Expr::YieldExpr(_) => ExprPrecedence::Jump, + | Expr::YieldExpr(_) + | Expr::ContinueExpr(_) => ExprPrecedence::Unambiguous, Expr::RangeExpr(..) => ExprPrecedence::Range, @@ -387,6 +393,7 @@ impl Expr { BreakExpr(e) => e.expr().is_none(), ContinueExpr(_) => true, YieldExpr(e) => e.expr().is_none(), + BecomeExpr(e) => e.expr().is_none(), _ => false, } } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs index 7d5ca2704354..df851ab5b252 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs @@ -269,7 +269,7 @@ impl ast::ByteString { } (Ok(c), true) => { buf.reserve_exact(text.len()); - buf.extend_from_slice(text[..prev_end].as_bytes()); + buf.extend_from_slice(&text.as_bytes()[..prev_end]); buf.push(c as u8); } (Err(e), _) => has_error = Some(e), @@ -333,7 +333,7 @@ impl ast::CString { } (Ok(u), true) => { buf.reserve_exact(text.len()); - buf.extend(text[..prev_end].as_bytes()); + buf.extend(&text.as_bytes()[..prev_end]); extend_unit(&mut buf, u); } (Err(e), _) => has_error = Some(e), From 46faf4bed643172fd0e04b28d93a3288fa998e99 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 10 Feb 2025 14:45:24 +0100 Subject: [PATCH 449/991] rework cycle handling A cycle was previously coinductive if all steps were coinductive. Change this to instead considerm cycles to be coinductive if they step through at least one where-bound of an impl of a coinductive trait goal. --- compiler/rustc_middle/src/ty/context.rs | 4 + compiler/rustc_middle/src/ty/predicate.rs | 6 +- .../src/solve/eval_ctxt/canonical.rs | 57 +-- .../src/solve/eval_ctxt/mod.rs | 72 +++- .../src/solve/eval_ctxt/probe.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 1 - .../src/solve/search_graph.rs | 5 - compiler/rustc_type_ir/src/inherent.rs | 2 - compiler/rustc_type_ir/src/interner.rs | 2 + .../rustc_type_ir/src/search_graph/mod.rs | 346 +++++++++++------- 10 files changed, 315 insertions(+), 182 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 00993c40dea9..38a3f722ca2e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -594,6 +594,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.trait_is_auto(trait_def_id) } + fn trait_is_coinductive(self, trait_def_id: DefId) -> bool { + self.trait_is_coinductive(trait_def_id) + } + fn trait_is_alias(self, trait_def_id: DefId) -> bool { self.trait_is_alias(trait_def_id) } diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index de6d30a89d47..089855bfb613 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -51,10 +51,6 @@ impl<'tcx> rustc_type_ir::inherent::Predicate> for Predicate<'tcx> self.as_clause() } - fn is_coinductive(self, interner: TyCtxt<'tcx>) -> bool { - self.is_coinductive(interner) - } - fn allow_normalization(self) -> bool { self.allow_normalization() } @@ -119,6 +115,8 @@ impl<'tcx> Predicate<'tcx> { Some(tcx.mk_predicate(kind)) } + /// Only used by the old solver to decide whether a predicate is accepted + /// in a coinductive trait solver cycle. #[instrument(level = "debug", skip(tcx), ret)] pub fn is_coinductive(self, tcx: TyCtxt<'tcx>) -> bool { match self.kind().skip_binder() { diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 2491f09a0e28..ce53a3968c7a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -21,7 +21,7 @@ use tracing::{debug, instrument, trace}; use crate::canonicalizer::Canonicalizer; use crate::delegate::SolverDelegate; use crate::resolve::EagerResolver; -use crate::solve::eval_ctxt::NestedGoals; +use crate::solve::eval_ctxt::{CurrentGoalKind, NestedGoals}; use crate::solve::{ CanonicalInput, CanonicalResponse, Certainty, EvalCtxt, ExternalConstraintsData, Goal, MaybeCause, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryInput, @@ -109,18 +109,22 @@ where // // As we return all ambiguous nested goals, we can ignore the certainty returned // by `try_evaluate_added_goals()`. - let (certainty, normalization_nested_goals) = if self.is_normalizes_to_goal { - let NestedGoals { normalizes_to_goals, goals } = std::mem::take(&mut self.nested_goals); - if cfg!(debug_assertions) { - assert!(normalizes_to_goals.is_empty()); - if goals.is_empty() { - assert!(matches!(goals_certainty, Certainty::Yes)); + let (certainty, normalization_nested_goals) = match self.current_goal_kind { + CurrentGoalKind::NormalizesTo => { + let NestedGoals { normalizes_to_goals, goals } = + std::mem::take(&mut self.nested_goals); + if cfg!(debug_assertions) { + assert!(normalizes_to_goals.is_empty()); + if goals.is_empty() { + assert!(matches!(goals_certainty, Certainty::Yes)); + } } + (certainty, NestedNormalizationGoals(goals)) + } + CurrentGoalKind::Misc | CurrentGoalKind::CoinductiveTrait => { + let certainty = certainty.unify_with(goals_certainty); + (certainty, NestedNormalizationGoals::empty()) } - (certainty, NestedNormalizationGoals(goals)) - } else { - let certainty = certainty.unify_with(goals_certainty); - (certainty, NestedNormalizationGoals::empty()) }; if let Certainty::Maybe(cause @ MaybeCause::Overflow { .. }) = certainty { @@ -163,19 +167,24 @@ where // ambiguous alias types which get replaced with fresh inference variables // during generalization. This prevents hangs caused by an exponential blowup, // see tests/ui/traits/next-solver/coherence-alias-hang.rs. - // - // We don't do so for `NormalizesTo` goals as we erased the expected term and - // bailing with overflow here would prevent us from detecting a type-mismatch, - // causing a coherence error in diesel, see #131969. We still bail with overflow - // when later returning from the parent AliasRelate goal. - if !self.is_normalizes_to_goal { - let num_non_region_vars = - canonical.variables.iter().filter(|c| !c.is_region() && c.is_existential()).count(); - if num_non_region_vars > self.cx().recursion_limit() { - debug!(?num_non_region_vars, "too many inference variables -> overflow"); - return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow { - suggest_increasing_limit: true, - })); + match self.current_goal_kind { + // We don't do so for `NormalizesTo` goals as we erased the expected term and + // bailing with overflow here would prevent us from detecting a type-mismatch, + // causing a coherence error in diesel, see #131969. We still bail with overflow + // when later returning from the parent AliasRelate goal. + CurrentGoalKind::NormalizesTo => {} + CurrentGoalKind::Misc | CurrentGoalKind::CoinductiveTrait => { + let num_non_region_vars = canonical + .variables + .iter() + .filter(|c| !c.is_region() && c.is_existential()) + .count(); + if num_non_region_vars > self.cx().recursion_limit() { + debug!(?num_non_region_vars, "too many inference variables -> overflow"); + return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow { + suggest_increasing_limit: true, + })); + } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index b0a34b9ce756..b349df325740 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -9,6 +9,7 @@ use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::relate::Relate; use rustc_type_ir::relate::solver_relating::RelateExt; +use rustc_type_ir::search_graph::PathKind; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; use rustc_type_ir::{self as ty, CanonicalVarValues, InferCtxtLike, Interner, TypingMode}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; @@ -20,12 +21,51 @@ use crate::solve::inspect::{self, ProofTreeBuilder}; use crate::solve::search_graph::SearchGraph; use crate::solve::{ CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind, GoalSource, - HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryResult, + HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryInput, + QueryResult, }; pub(super) mod canonical; mod probe; +/// The kind of goal we're currently proving. +/// +/// This has effects on cycle handling handling and on how we compute +/// query responses, see the variant descriptions for more info. +#[derive(Debug, Copy, Clone)] +enum CurrentGoalKind { + Misc, + /// We're proving an trait goal for a coinductive trait, either an auto trait or `Sized`. + /// + /// These are currently the only goals whose impl where-clauses are considered to be + /// productive steps. + CoinductiveTrait, + /// Unlike other goals, `NormalizesTo` goals act like functions with the expected term + /// always being fully unconstrained. This would weaken inference however, as the nested + /// goals never get the inference constraints from the actual normalized-to type. + /// + /// Because of this we return any ambiguous nested goals from `NormalizesTo` to the + /// caller when then adds these to its own context. The caller is always an `AliasRelate` + /// goal so this never leaks out of the solver. + NormalizesTo, +} + +impl CurrentGoalKind { + fn from_query_input(cx: I, input: QueryInput) -> CurrentGoalKind { + match input.goal.predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { + if cx.trait_is_coinductive(pred.trait_ref.def_id) { + CurrentGoalKind::CoinductiveTrait + } else { + CurrentGoalKind::Misc + } + } + ty::PredicateKind::NormalizesTo(_) => CurrentGoalKind::NormalizesTo, + _ => CurrentGoalKind::Misc, + } + } +} + pub struct EvalCtxt<'a, D, I = ::Interner> where D: SolverDelegate, @@ -51,14 +91,10 @@ where /// The variable info for the `var_values`, only used to make an ambiguous response /// with no constraints. variables: I::CanonicalVars, - /// Whether we're currently computing a `NormalizesTo` goal. Unlike other goals, - /// `NormalizesTo` goals act like functions with the expected term always being - /// fully unconstrained. This would weaken inference however, as the nested goals - /// never get the inference constraints from the actual normalized-to type. Because - /// of this we return any ambiguous nested goals from `NormalizesTo` to the caller - /// when then adds these to its own context. The caller is always an `AliasRelate` - /// goal so this never leaks out of the solver. - is_normalizes_to_goal: bool, + + /// What kind of goal we're currently computing, see the enum definition + /// for more info. + current_goal_kind: CurrentGoalKind, pub(super) var_values: CanonicalVarValues, predefined_opaques_in_body: I::PredefinedOpaques, @@ -226,8 +262,11 @@ where self.delegate.typing_mode() } - pub(super) fn set_is_normalizes_to_goal(&mut self) { - self.is_normalizes_to_goal = true; + pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind { + match (self.current_goal_kind, source) { + (CurrentGoalKind::CoinductiveTrait, GoalSource::ImplWhereBound) => PathKind::Coinductive, + _ => PathKind::Inductive, + } } /// Creates a root evaluation context and search graph. This should only be @@ -256,7 +295,7 @@ where max_input_universe: ty::UniverseIndex::ROOT, variables: Default::default(), var_values: CanonicalVarValues::dummy(), - is_normalizes_to_goal: false, + current_goal_kind: CurrentGoalKind::Misc, origin_span, tainted: Ok(()), }; @@ -294,7 +333,7 @@ where delegate, variables: canonical_input.canonical.variables, var_values, - is_normalizes_to_goal: false, + current_goal_kind: CurrentGoalKind::from_query_input(cx, input), predefined_opaques_in_body: input.predefined_opaques_in_body, max_input_universe: canonical_input.canonical.max_universe, search_graph, @@ -340,6 +379,7 @@ where cx: I, search_graph: &'a mut SearchGraph, canonical_input: CanonicalInput, + step_kind_from_parent: PathKind, goal_evaluation: &mut ProofTreeBuilder, ) -> QueryResult { let mut canonical_goal_evaluation = @@ -352,6 +392,7 @@ where search_graph.with_new_goal( cx, canonical_input, + step_kind_from_parent, &mut canonical_goal_evaluation, |search_graph, canonical_goal_evaluation| { EvalCtxt::enter_canonical( @@ -395,12 +436,10 @@ where /// `NormalizesTo` is only used by `AliasRelate`, all other callsites /// should use [`EvalCtxt::evaluate_goal`] which discards that empty /// storage. - // FIXME(-Znext-solver=coinduction): `_source` is currently unused but will - // be necessary once we implement the new coinduction approach. pub(super) fn evaluate_goal_raw( &mut self, goal_evaluation_kind: GoalEvaluationKind, - _source: GoalSource, + source: GoalSource, goal: Goal, ) -> Result<(NestedNormalizationGoals, HasChanged, Certainty), NoSolution> { let (orig_values, canonical_goal) = self.canonicalize_goal(goal); @@ -410,6 +449,7 @@ where self.cx(), self.search_graph, canonical_goal, + self.step_kind_for_source(source), &mut goal_evaluation, ); let response = match canonical_response { diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs index add96a1fdf7a..0a9e7fafaea6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs @@ -34,7 +34,7 @@ where delegate, variables: outer_ecx.variables, var_values: outer_ecx.var_values, - is_normalizes_to_goal: outer_ecx.is_normalizes_to_goal, + current_goal_kind: outer_ecx.current_goal_kind, predefined_opaques_in_body: outer_ecx.predefined_opaques_in_body, max_input_universe, search_graph: outer_ecx.search_graph, diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 88002e1a88a8..de6d21da0f59 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -28,7 +28,6 @@ where &mut self, goal: Goal>, ) -> QueryResult { - self.set_is_normalizes_to_goal(); debug_assert!(self.term_is_fully_unconstrained(goal)); let cx = self.cx(); match goal.predicate.alias.kind(cx) { diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index 843200ca184e..67eb442d2cce 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -2,7 +2,6 @@ use std::convert::Infallible; use std::marker::PhantomData; use rustc_type_ir::Interner; -use rustc_type_ir::inherent::*; use rustc_type_ir::search_graph::{self, PathKind}; use rustc_type_ir::solve::{CanonicalInput, Certainty, QueryResult}; @@ -94,10 +93,6 @@ where let certainty = from_result.unwrap().value.certainty; response_no_constraints(cx, for_input, certainty) } - - fn step_is_coinductive(cx: I, input: CanonicalInput) -> bool { - input.canonical.value.goal.predicate.is_coinductive(cx) - } } fn response_no_constraints( diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 9277226b718b..d4134bdf3a78 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -462,8 +462,6 @@ pub trait Predicate>: { fn as_clause(self) -> Option; - fn is_coinductive(self, interner: I) -> bool; - // FIXME: Eventually uplift the impl out of rustc and make this defaulted. fn allow_normalization(self) -> bool; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index aae2d2e96b96..291ac42525eb 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -279,6 +279,8 @@ pub trait Interner: fn trait_is_auto(self, trait_def_id: Self::DefId) -> bool; + fn trait_is_coinductive(self, trait_def_id: Self::DefId) -> bool; + fn trait_is_alias(self, trait_def_id: Self::DefId) -> bool; fn trait_is_dyn_compatible(self, trait_def_id: Self::DefId) -> bool; diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 082cfff72e20..0cf8cfb879f8 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -12,7 +12,7 @@ /// The global cache has to be completely unobservable, while the per-cycle cache may impact /// behavior as long as the resulting behavior is still correct. use std::cmp::Ordering; -use std::collections::BTreeSet; +use std::collections::BTreeMap; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; @@ -104,8 +104,6 @@ pub trait Delegate { for_input: ::Input, from_result: ::Result, ) -> ::Result; - - fn step_is_coinductive(cx: Self::Cx, input: ::Input) -> bool; } /// In the initial iteration of a cycle, we do not yet have a provisional @@ -116,15 +114,38 @@ pub enum PathKind { Coinductive, Inductive, } +impl PathKind { + /// Returns the path kind when merging `self` with `rest`. + /// + /// Given an inductive path `self` and a coinductive path `rest`, + /// the path `self -> rest` would be coinductive. + fn extend(self, rest: PathKind) -> PathKind { + match self { + PathKind::Coinductive => PathKind::Coinductive, + PathKind::Inductive => rest, + } + } +} +/// The kinds of cycles a cycle head was involved in. +/// +/// This is used to avoid rerunning a cycle if there's +/// just a single usage kind and the final result matches +/// its provisional result. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum UsageKind { Single(PathKind), Mixed, } +impl From for UsageKind { + fn from(path: PathKind) -> UsageKind { + UsageKind::Single(path) + } +} impl UsageKind { - fn merge(self, other: Self) -> Self { - match (self, other) { + #[must_use] + fn merge(self, other: impl Into) -> Self { + match (self, other.into()) { (UsageKind::Mixed, _) | (_, UsageKind::Mixed) => UsageKind::Mixed, (UsageKind::Single(lhs), UsageKind::Single(rhs)) => { if lhs == rhs { @@ -135,7 +156,42 @@ impl UsageKind { } } } - fn and_merge(&mut self, other: Self) { + fn and_merge(&mut self, other: impl Into) { + *self = self.merge(other); + } +} + +/// For each goal we track whether the paths from this goal +/// to its cycle heads are coinductive. +/// +/// This is a necessary condition to rebase provisional cache +/// entries. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum AllPathsToHeadCoinductive { + Yes, + No, +} +impl From for AllPathsToHeadCoinductive { + fn from(path: PathKind) -> AllPathsToHeadCoinductive { + match path { + PathKind::Coinductive => AllPathsToHeadCoinductive::Yes, + _ => AllPathsToHeadCoinductive::No, + } + } +} +impl AllPathsToHeadCoinductive { + #[must_use] + fn merge(self, other: impl Into) -> Self { + match (self, other.into()) { + (AllPathsToHeadCoinductive::Yes, AllPathsToHeadCoinductive::Yes) => { + AllPathsToHeadCoinductive::Yes + } + (AllPathsToHeadCoinductive::No, _) | (_, AllPathsToHeadCoinductive::No) => { + AllPathsToHeadCoinductive::No + } + } + } + fn and_merge(&mut self, other: impl Into) { *self = self.merge(other); } } @@ -177,10 +233,11 @@ impl AvailableDepth { /// All cycle heads a given goal depends on, ordered by their stack depth. /// -/// We therefore pop the cycle heads from highest to lowest. +/// We also track all paths from this goal to that head. This is necessary +/// when rebasing provisional cache results. #[derive(Clone, Debug, PartialEq, Eq, Default)] struct CycleHeads { - heads: BTreeSet, + heads: BTreeMap, } impl CycleHeads { @@ -189,15 +246,15 @@ impl CycleHeads { } fn highest_cycle_head(&self) -> StackDepth { - *self.heads.last().unwrap() + self.opt_highest_cycle_head().unwrap() } fn opt_highest_cycle_head(&self) -> Option { - self.heads.last().copied() + self.heads.last_key_value().map(|(k, _)| *k) } fn opt_lowest_cycle_head(&self) -> Option { - self.heads.first().copied() + self.heads.first_key_value().map(|(k, _)| *k) } fn remove_highest_cycle_head(&mut self) { @@ -205,28 +262,42 @@ impl CycleHeads { debug_assert_ne!(last, None); } - fn insert(&mut self, head: StackDepth) { - self.heads.insert(head); + fn insert( + &mut self, + head: StackDepth, + path_from_entry: impl Into + Copy, + ) { + self.heads.entry(head).or_insert(path_from_entry.into()).and_merge(path_from_entry); } fn merge(&mut self, heads: &CycleHeads) { - for &head in heads.heads.iter() { - self.insert(head); + for (&head, &path_from_entry) in heads.heads.iter() { + self.insert(head, path_from_entry); + debug_assert!(matches!(self.heads[&head], AllPathsToHeadCoinductive::Yes)); } } + fn iter(&self) -> impl Iterator + '_ { + self.heads.iter().map(|(k, v)| (*k, *v)) + } + /// Update the cycle heads of a goal at depth `this` given the cycle heads /// of a nested goal. This merges the heads after filtering the parent goal /// itself. - fn extend_from_child(&mut self, this: StackDepth, child: &CycleHeads) { - for &head in child.heads.iter() { + fn extend_from_child(&mut self, this: StackDepth, step_kind: PathKind, child: &CycleHeads) { + for (&head, &path_from_entry) in child.heads.iter() { match head.cmp(&this) { Ordering::Less => {} Ordering::Equal => continue, Ordering::Greater => unreachable!(), } - self.insert(head); + let path_from_entry = match step_kind { + PathKind::Coinductive => AllPathsToHeadCoinductive::Yes, + PathKind::Inductive => path_from_entry, + }; + + self.insert(head, path_from_entry); } } } @@ -246,7 +317,7 @@ impl CycleHeads { /// We need to disable the global cache if using it would hide a cycle, as /// cycles can impact behavior. The cycle ABA may have different final /// results from a the cycle BAB depending on the cycle root. -#[derive_where(Debug, Default; X: Cx)] +#[derive_where(Debug, Default, Clone; X: Cx)] struct NestedGoals { nested_goals: HashMap, } @@ -259,13 +330,6 @@ impl NestedGoals { self.nested_goals.entry(input).or_insert(path_from_entry).and_merge(path_from_entry); } - fn merge(&mut self, nested_goals: &NestedGoals) { - #[allow(rustc::potential_query_instability)] - for (input, path_from_entry) in nested_goals.iter() { - self.insert(input, path_from_entry); - } - } - /// Adds the nested goals of a nested goal, given that the path `step_kind` from this goal /// to the parent goal. /// @@ -276,8 +340,8 @@ impl NestedGoals { #[allow(rustc::potential_query_instability)] for (input, path_from_entry) in nested_goals.iter() { let path_from_entry = match step_kind { - PathKind::Coinductive => path_from_entry, - PathKind::Inductive => UsageKind::Single(PathKind::Inductive), + PathKind::Coinductive => UsageKind::Single(PathKind::Coinductive), + PathKind::Inductive => path_from_entry, }; self.insert(input, path_from_entry); } @@ -289,10 +353,6 @@ impl NestedGoals { self.nested_goals.iter().map(|(i, p)| (*i, *p)) } - fn get(&self, input: X::Input) -> Option { - self.nested_goals.get(&input).copied() - } - fn contains(&self, input: X::Input) -> bool { self.nested_goals.contains_key(&input) } @@ -310,6 +370,12 @@ rustc_index::newtype_index! { struct StackEntry { input: X::Input, + /// Whether proving this goal is a coinductive step. + /// + /// This is used when encountering a trait solver cycle to + /// decide whether the initial provisional result of the cycle. + step_kind_from_parent: PathKind, + /// The available depth of a given goal, immutable. available_depth: AvailableDepth, @@ -346,9 +412,9 @@ struct ProvisionalCacheEntry { encountered_overflow: bool, /// All cycle heads this cache entry depends on. heads: CycleHeads, - /// The path from the highest cycle head to this goal. + /// The path from the highest cycle head to this goal. This differs from + /// `heads` which tracks the path to the cycle head *from* this goal. path_from_head: PathKind, - nested_goals: NestedGoals, result: X::Result, } @@ -367,6 +433,20 @@ pub struct SearchGraph, X: Cx = ::Cx> { _marker: PhantomData, } +/// While [`SearchGraph::update_parent_goal`] can be mostly shared between +/// ordinary nested goals/global cache hits and provisional cache hits, +/// using the provisional cache should not add any nested goals. +/// +/// `nested_goals` are only used when checking whether global cache entries +/// are applicable. This only cares about whether a goal is actually accessed. +/// Given that the usage of the provisional cache is fully determinstic, we +/// don't need to track the nested goals used while computing a provisional +/// cache entry. +enum UpdateParentGoalCtxt<'a, X: Cx> { + Ordinary(&'a NestedGoals), + ProvisionalCacheHit, +} + impl, X: Cx> SearchGraph { pub fn new(root_depth: usize) -> SearchGraph { Self { @@ -382,27 +462,32 @@ impl, X: Cx> SearchGraph { /// and using existing global cache entries to make sure they /// have the same impact on the remaining evaluation. fn update_parent_goal( - cx: X, stack: &mut IndexVec>, + step_kind_from_parent: PathKind, reached_depth: StackDepth, heads: &CycleHeads, encountered_overflow: bool, - nested_goals: &NestedGoals, + context: UpdateParentGoalCtxt<'_, X>, ) { if let Some(parent_index) = stack.last_index() { let parent = &mut stack[parent_index]; parent.reached_depth = parent.reached_depth.max(reached_depth); parent.encountered_overflow |= encountered_overflow; - parent.heads.extend_from_child(parent_index, heads); - let step_kind = Self::step_kind(cx, parent.input); - parent.nested_goals.extend_from_child(step_kind, nested_goals); + parent.heads.extend_from_child(parent_index, step_kind_from_parent, heads); + let parent_depends_on_cycle = match context { + UpdateParentGoalCtxt::Ordinary(nested_goals) => { + parent.nested_goals.extend_from_child(step_kind_from_parent, nested_goals); + !nested_goals.is_empty() + } + UpdateParentGoalCtxt::ProvisionalCacheHit => true, + }; // Once we've got goals which encountered overflow or a cycle, // we track all goals whose behavior may depend depend on these // goals as this change may cause them to now depend on additional // goals, resulting in new cycles. See the dev-guide for examples. - if !nested_goals.is_empty() { - parent.nested_goals.insert(parent.input, UsageKind::Single(PathKind::Coinductive)) + if parent_depends_on_cycle { + parent.nested_goals.insert(parent.input, UsageKind::Single(PathKind::Inductive)) } } } @@ -422,21 +507,19 @@ impl, X: Cx> SearchGraph { self.stack.len() } - fn step_kind(cx: X, input: X::Input) -> PathKind { - if D::step_is_coinductive(cx, input) { PathKind::Coinductive } else { PathKind::Inductive } - } - /// Whether the path from `head` to the current stack entry is inductive or coinductive. - fn stack_path_kind( - cx: X, + /// + /// The `step_kind_to_head` is used to add a single additional path segment to the path on + /// the stack which completes the cycle. This given an inductive step AB which then cycles + /// coinductively with A, we need to treat this cycle as coinductive. + fn cycle_path_kind( stack: &IndexVec>, + step_kind_to_head: PathKind, head: StackDepth, ) -> PathKind { - if stack.raw[head.index()..].iter().all(|entry| D::step_is_coinductive(cx, entry.input)) { - PathKind::Coinductive - } else { - PathKind::Inductive - } + stack.raw[head.index() + 1..] + .iter() + .fold(step_kind_to_head, |curr, entry| curr.extend(entry.step_kind_from_parent)) } /// Probably the most involved method of the whole solver. @@ -447,6 +530,7 @@ impl, X: Cx> SearchGraph { &mut self, cx: X, input: X::Input, + step_kind_from_parent: PathKind, inspect: &mut D::ProofTreeBuilder, mut evaluate_goal: impl FnMut(&mut Self, &mut D::ProofTreeBuilder) -> X::Result, ) -> X::Result { @@ -464,7 +548,7 @@ impl, X: Cx> SearchGraph { // - A // - BA cycle // - CB :x: - if let Some(result) = self.lookup_provisional_cache(cx, input) { + if let Some(result) = self.lookup_provisional_cache(input, step_kind_from_parent) { return result; } @@ -477,10 +561,12 @@ impl, X: Cx> SearchGraph { // global cache has been disabled as it may otherwise change the result for // cyclic goals. We don't care about goals which are not on the current stack // so it's fine to drop their scope eagerly. - self.lookup_global_cache_untracked(cx, input, available_depth) + self.lookup_global_cache_untracked(cx, input, step_kind_from_parent, available_depth) .inspect(|expected| debug!(?expected, "validate cache entry")) .map(|r| (scope, r)) - } else if let Some(result) = self.lookup_global_cache(cx, input, available_depth) { + } else if let Some(result) = + self.lookup_global_cache(cx, input, step_kind_from_parent, available_depth) + { return result; } else { None @@ -490,8 +576,8 @@ impl, X: Cx> SearchGraph { // avoid iterating over the stack in case a goal has already been computed. // This may not have an actual performance impact and we could reorder them // as it may reduce the number of `nested_goals` we need to track. - if let Some(result) = self.check_cycle_on_stack(cx, input) { - debug_assert!(validate_cache.is_none(), "global cache and cycle on stack"); + if let Some(result) = self.check_cycle_on_stack(cx, input, step_kind_from_parent) { + debug_assert!(validate_cache.is_none(), "global cache and cycle on stack: {input:?}"); return result; } @@ -499,6 +585,7 @@ impl, X: Cx> SearchGraph { let depth = self.stack.next_index(); let entry = StackEntry { input, + step_kind_from_parent, available_depth, reached_depth: depth, heads: Default::default(), @@ -522,12 +609,12 @@ impl, X: Cx> SearchGraph { // We've finished computing the goal and have popped it from the stack, // lazily update its parent goal. Self::update_parent_goal( - cx, &mut self.stack, + final_entry.step_kind_from_parent, final_entry.reached_depth, &final_entry.heads, final_entry.encountered_overflow, - &final_entry.nested_goals, + UpdateParentGoalCtxt::Ordinary(&final_entry.nested_goals), ); // We're now done with this goal. We only add the root of cycles to the global cache. @@ -541,19 +628,20 @@ impl, X: Cx> SearchGraph { self.insert_global_cache(cx, input, final_entry, result, dep_node) } } else if D::ENABLE_PROVISIONAL_CACHE { - debug_assert!(validate_cache.is_none()); + debug_assert!(validate_cache.is_none(), "unexpected non-root: {input:?}"); let entry = self.provisional_cache.entry(input).or_default(); - let StackEntry { heads, nested_goals, encountered_overflow, .. } = final_entry; - let path_from_head = Self::stack_path_kind(cx, &self.stack, heads.highest_cycle_head()); - entry.push(ProvisionalCacheEntry { - encountered_overflow, - heads, - path_from_head, - nested_goals, - result, - }); + let StackEntry { heads, encountered_overflow, .. } = final_entry; + let path_from_head = Self::cycle_path_kind( + &self.stack, + step_kind_from_parent, + heads.highest_cycle_head(), + ); + let provisional_cache_entry = + ProvisionalCacheEntry { encountered_overflow, heads, path_from_head, result }; + debug!(?provisional_cache_entry); + entry.push(provisional_cache_entry); } else { - debug_assert!(validate_cache.is_none()); + debug_assert!(validate_cache.is_none(), "unexpected non-root: {input:?}"); } result @@ -575,7 +663,7 @@ impl, X: Cx> SearchGraph { // // We must therefore not use the global cache entry for `B` in that case. // See tests/ui/traits/next-solver/cycles/hidden-by-overflow.rs - last.nested_goals.insert(last.input, UsageKind::Single(PathKind::Coinductive)); + last.nested_goals.insert(last.input, UsageKind::Single(PathKind::Inductive)); } debug!("encountered stack overflow"); @@ -607,7 +695,6 @@ impl, X: Cx> SearchGraph { /// This can be thought of rotating the sub-tree of this provisional result and changing /// its entry point while making sure that all paths through this sub-tree stay the same. /// - /// /// In case the popped cycle head failed to reach a fixpoint anything which depends on /// its provisional result is invalid. Actually discarding provisional cache entries in /// this case would cause hangs, so we instead change the result of dependant provisional @@ -616,7 +703,6 @@ impl, X: Cx> SearchGraph { /// to me. fn rebase_provisional_cache_entries( &mut self, - cx: X, stack_entry: &StackEntry, mut mutate_result: impl FnMut(X::Input, X::Result) -> X::Result, ) { @@ -628,25 +714,24 @@ impl, X: Cx> SearchGraph { encountered_overflow: _, heads, path_from_head, - nested_goals, result, } = entry; - if heads.highest_cycle_head() != head { + if heads.highest_cycle_head() == head { + heads.remove_highest_cycle_head() + } else { return true; } - // We don't try rebasing if the path from the current head - // to the cache entry is not coinductive or if the path from - // the cache entry to the current head is not coinductive. - // - // Both of these constraints could be weakened, but by only - // accepting coinductive paths we don't have to worry about - // changing the cycle kind of the remaining cycles. We can - // extend this in the future once there's a known issue - // caused by it. - if *path_from_head != PathKind::Coinductive - || nested_goals.get(stack_entry.input).unwrap() - != UsageKind::Single(PathKind::Coinductive) + // We only try to rebase if all paths from the cache entry + // to its heads are coinductive. In this case these cycle + // kinds won't change, no matter the goals between these + // heads and the provisional cache entry. + if heads.iter().any(|(_, p)| matches!(p, AllPathsToHeadCoinductive::No)) { + return false; + } + + // The same for nested goals of the cycle head. + if stack_entry.heads.iter().any(|(_, p)| matches!(p, AllPathsToHeadCoinductive::No)) { return false; } @@ -654,20 +739,23 @@ impl, X: Cx> SearchGraph { // Merge the cycle heads of the provisional cache entry and the // popped head. If the popped cycle head was a root, discard all // provisional cache entries which depend on it. - heads.remove_highest_cycle_head(); heads.merge(&stack_entry.heads); let Some(head) = heads.opt_highest_cycle_head() else { return false; }; - // As we've made sure that the path from the new highest cycle - // head to the uses of the popped cycle head are fully coinductive, - // we can be sure that the paths to all nested goals of the popped - // cycle head remain the same. We can simply merge them. - nested_goals.merge(&stack_entry.nested_goals); // We now care about the path from the next highest cycle head to the // provisional cache entry. - *path_from_head = Self::stack_path_kind(cx, &self.stack, head); + match path_from_head { + PathKind::Coinductive => {} + PathKind::Inductive => { + *path_from_head = Self::cycle_path_kind( + &self.stack, + stack_entry.step_kind_from_parent, + head, + ) + } + } // Mutate the result of the provisional cache entry in case we did // not reach a fixpoint. *result = mutate_result(input, *result); @@ -677,19 +765,18 @@ impl, X: Cx> SearchGraph { }); } - fn lookup_provisional_cache(&mut self, cx: X, input: X::Input) -> Option { + fn lookup_provisional_cache( + &mut self, + input: X::Input, + step_kind_from_parent: PathKind, + ) -> Option { if !D::ENABLE_PROVISIONAL_CACHE { return None; } let entries = self.provisional_cache.get(&input)?; - for &ProvisionalCacheEntry { - encountered_overflow, - ref heads, - path_from_head, - ref nested_goals, - result, - } in entries + for &ProvisionalCacheEntry { encountered_overflow, ref heads, path_from_head, result } in + entries { let head = heads.highest_cycle_head(); if encountered_overflow { @@ -710,22 +797,18 @@ impl, X: Cx> SearchGraph { // A provisional cache entry is only valid if the current path from its // highest cycle head to the goal is the same. - if path_from_head == Self::stack_path_kind(cx, &self.stack, head) { + if path_from_head == Self::cycle_path_kind(&self.stack, step_kind_from_parent, head) { // While we don't have to track the full depth of the provisional cache entry, // we do have to increment the required depth by one as we'd have already failed // with overflow otherwise let next_index = self.stack.next_index(); - let last = &mut self.stack.raw.last_mut().unwrap(); - let path_from_entry = Self::step_kind(cx, last.input); - last.nested_goals.insert(input, UsageKind::Single(path_from_entry)); - Self::update_parent_goal( - cx, &mut self.stack, + step_kind_from_parent, next_index, heads, - false, - nested_goals, + encountered_overflow, + UpdateParentGoalCtxt::ProvisionalCacheHit, ); debug_assert!(self.stack[head].has_been_used.is_some()); debug!(?head, ?path_from_head, "provisional cache hit"); @@ -740,8 +823,8 @@ impl, X: Cx> SearchGraph { /// evaluating this entry would not have ended up depending on either a goal /// already on the stack or a provisional cache entry. fn candidate_is_applicable( - cx: X, stack: &IndexVec>, + step_kind_from_parent: PathKind, provisional_cache: &HashMap>>, nested_goals: &NestedGoals, ) -> bool { @@ -773,7 +856,6 @@ impl, X: Cx> SearchGraph { encountered_overflow, ref heads, path_from_head, - nested_goals: _, result: _, } in entries.iter() { @@ -786,9 +868,9 @@ impl, X: Cx> SearchGraph { // A provisional cache entry only applies if the path from its highest head // matches the path when encountering the goal. let head = heads.highest_cycle_head(); - let full_path = match Self::stack_path_kind(cx, stack, head) { - PathKind::Coinductive => path_from_global_entry, - PathKind::Inductive => UsageKind::Single(PathKind::Inductive), + let full_path = match Self::cycle_path_kind(stack, step_kind_from_parent, head) { + PathKind::Coinductive => UsageKind::Single(PathKind::Coinductive), + PathKind::Inductive => path_from_global_entry, }; match (full_path, path_from_head) { @@ -816,14 +898,15 @@ impl, X: Cx> SearchGraph { &self, cx: X, input: X::Input, + step_kind_from_parent: PathKind, available_depth: AvailableDepth, ) -> Option { cx.with_global_cache(|cache| { cache .get(cx, input, available_depth, |nested_goals| { Self::candidate_is_applicable( - cx, &self.stack, + step_kind_from_parent, &self.provisional_cache, nested_goals, ) @@ -839,14 +922,15 @@ impl, X: Cx> SearchGraph { &mut self, cx: X, input: X::Input, + step_kind_from_parent: PathKind, available_depth: AvailableDepth, ) -> Option { cx.with_global_cache(|cache| { let CacheData { result, additional_depth, encountered_overflow, nested_goals } = cache .get(cx, input, available_depth, |nested_goals| { Self::candidate_is_applicable( - cx, &self.stack, + step_kind_from_parent, &self.provisional_cache, nested_goals, ) @@ -860,12 +944,12 @@ impl, X: Cx> SearchGraph { // cycle heads are always empty. let heads = Default::default(); Self::update_parent_goal( - cx, &mut self.stack, + step_kind_from_parent, reached_depth, &heads, encountered_overflow, - nested_goals, + UpdateParentGoalCtxt::Ordinary(nested_goals), ); debug!(?additional_depth, "global cache hit"); @@ -873,16 +957,21 @@ impl, X: Cx> SearchGraph { }) } - fn check_cycle_on_stack(&mut self, cx: X, input: X::Input) -> Option { + fn check_cycle_on_stack( + &mut self, + cx: X, + input: X::Input, + step_kind_from_parent: PathKind, + ) -> Option { let (head, _stack_entry) = self.stack.iter_enumerated().find(|(_, e)| e.input == input)?; - debug!("encountered cycle with depth {head:?}"); // We have a nested goal which directly relies on a goal deeper in the stack. // // We start by tagging all cycle participants, as that's necessary for caching. // // Finally we can return either the provisional response or the initial response // in case we're in the first fixpoint iteration for this goal. - let path_kind = Self::stack_path_kind(cx, &self.stack, head); + let path_kind = Self::cycle_path_kind(&self.stack, step_kind_from_parent, head); + debug!(?path_kind, "encountered cycle with depth {head:?}"); let usage_kind = UsageKind::Single(path_kind); self.stack[head].has_been_used = Some(self.stack[head].has_been_used.map_or(usage_kind, |prev| prev.merge(usage_kind))); @@ -894,11 +983,10 @@ impl, X: Cx> SearchGraph { let last = &mut self.stack[last_index]; last.reached_depth = last.reached_depth.max(next_index); - let path_from_entry = Self::step_kind(cx, last.input); - last.nested_goals.insert(input, UsageKind::Single(path_from_entry)); - last.nested_goals.insert(last.input, UsageKind::Single(PathKind::Coinductive)); + last.nested_goals.insert(input, UsageKind::Single(step_kind_from_parent)); + last.nested_goals.insert(last.input, UsageKind::Single(PathKind::Inductive)); if last_index != head { - last.heads.insert(head); + last.heads.insert(head, step_kind_from_parent); } // Return the provisional result or, if we're in the first iteration, @@ -964,7 +1052,7 @@ impl, X: Cx> SearchGraph { // this was only the root of either coinductive or inductive cycles, and the // final result is equal to the initial response for that case. if self.reached_fixpoint(cx, &stack_entry, usage_kind, result) { - self.rebase_provisional_cache_entries(cx, &stack_entry, |_, result| result); + self.rebase_provisional_cache_entries(&stack_entry, |_, result| result); return (stack_entry, result); } @@ -981,7 +1069,7 @@ impl, X: Cx> SearchGraph { // we also taint all provisional cache entries which depend on the // current goal. if D::is_ambiguous_result(result) { - self.rebase_provisional_cache_entries(cx, &stack_entry, |input, _| { + self.rebase_provisional_cache_entries(&stack_entry, |input, _| { D::propagate_ambiguity(cx, input, result) }); return (stack_entry, result); @@ -993,7 +1081,7 @@ impl, X: Cx> SearchGraph { if i >= D::FIXPOINT_STEP_LIMIT { debug!("canonical cycle overflow"); let result = D::on_fixpoint_overflow(cx, input); - self.rebase_provisional_cache_entries(cx, &stack_entry, |input, _| { + self.rebase_provisional_cache_entries(&stack_entry, |input, _| { D::on_fixpoint_overflow(cx, input) }); return (stack_entry, result); From edadb54f6f731727383569045e91b908a0ea854d Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 10 Feb 2025 15:30:42 +0100 Subject: [PATCH 450/991] fix rustc_type_ir without the nightly feature --- compiler/rustc_type_ir/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index d8184da927c3..7b2593b96e37 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -16,7 +16,7 @@ rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } -smallvec = { version = "1.8.1", default-features = false } +smallvec = { version = "1.8.1", default-features = false, features = ["const_generics"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end From 933d45fe8f29904f315161b9c42b96a72e3eefb4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 10 Feb 2025 16:14:52 +0100 Subject: [PATCH 451/991] fix typo --- .../rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs index 25e8708a3322..1d1ff09ee410 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs @@ -39,7 +39,7 @@ where // // FIXME(-Znext-solver=coinductive): I think this should be split // and we tag the impl bounds with `GoalSource::ImplWhereBound`? - // Right not this includes both the impl and the assoc item where bounds, + // Right now this includes both the impl and the assoc item where bounds, // and I don't think the assoc item where-bounds are allowed to be coinductive. self.add_goals( GoalSource::Misc, From a7970c0b271b3fc4c19f580977a44c46130c077a Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 17 Feb 2025 15:25:06 +0100 Subject: [PATCH 452/991] remove useless tests they don't detect any bugs in the search graph. We instead check for these via `search_graph_fuzz`. --- .../double-cycle-inductive-coinductive.rs | 37 --------------- .../double-cycle-inductive-coinductive.stderr | 27 ----------- .../cycles/inductive-not-on-stack.rs | 46 ------------------- .../cycles/inductive-not-on-stack.stderr | 27 ----------- .../next-solver/cycles/mixed-cycles-1.rs | 39 ---------------- .../next-solver/cycles/mixed-cycles-1.stderr | 15 ------ .../next-solver/cycles/mixed-cycles-2.rs | 32 ------------- .../next-solver/cycles/mixed-cycles-2.stderr | 15 ------ 8 files changed, 238 deletions(-) delete mode 100644 tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs delete mode 100644 tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr delete mode 100644 tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs delete mode 100644 tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr delete mode 100644 tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs delete mode 100644 tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr delete mode 100644 tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs delete mode 100644 tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr diff --git a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs deleted file mode 100644 index 0d3872142087..000000000000 --- a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs +++ /dev/null @@ -1,37 +0,0 @@ -//@ compile-flags: -Znext-solver -#![feature(rustc_attrs)] - -// Test that having both an inductive and a coinductive cycle -// is handled correctly. - -#[rustc_coinductive] -trait Trait {} -impl Trait for T {} - -trait Inductive {} -impl Inductive for T {} -#[rustc_coinductive] -trait Coinductive {} -impl Coinductive for T {} - -fn impls_trait() {} - -#[rustc_coinductive] -trait TraitRev {} -impl TraitRev for T {} - -trait InductiveRev {} -impl InductiveRev for T {} -#[rustc_coinductive] -trait CoinductiveRev {} -impl CoinductiveRev for T {} - -fn impls_trait_rev() {} - -fn main() { - impls_trait::<()>(); - //~^ ERROR overflow evaluating the requirement - - impls_trait_rev::<()>(); - //~^ ERROR overflow evaluating the requirement -} diff --git a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr deleted file mode 100644 index 7cedb4d36c98..000000000000 --- a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0275]: overflow evaluating the requirement `(): Trait` - --> $DIR/double-cycle-inductive-coinductive.rs:32:19 - | -LL | impls_trait::<()>(); - | ^^ - | -note: required by a bound in `impls_trait` - --> $DIR/double-cycle-inductive-coinductive.rs:17:19 - | -LL | fn impls_trait() {} - | ^^^^^ required by this bound in `impls_trait` - -error[E0275]: overflow evaluating the requirement `(): TraitRev` - --> $DIR/double-cycle-inductive-coinductive.rs:35:23 - | -LL | impls_trait_rev::<()>(); - | ^^ - | -note: required by a bound in `impls_trait_rev` - --> $DIR/double-cycle-inductive-coinductive.rs:29:23 - | -LL | fn impls_trait_rev() {} - | ^^^^^^^^ required by this bound in `impls_trait_rev` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs deleted file mode 100644 index 78683372580b..000000000000 --- a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs +++ /dev/null @@ -1,46 +0,0 @@ -//@ compile-flags: -Znext-solver -#![feature(rustc_attrs, trivial_bounds)] - -// We have to be careful here: -// -// We either have the provisional result of `A -> B -> A` on the -// stack, which is a fully coinductive cycle. Accessing the -// provisional result for `B` as part of the `A -> C -> B -> A` cycle -// has to make sure we don't just use the result of `A -> B -> A` as the -// new cycle is inductive. -// -// Alternatively, if we have `A -> C -> A` first, then `A -> B -> A` has -// a purely inductive stack, so something could also go wrong here. - -#[rustc_coinductive] -trait A {} -#[rustc_coinductive] -trait B {} -trait C {} - -impl A for T {} -impl B for T {} -impl C for T {} - -fn impls_a() {} - -// The same test with reordered where clauses to make sure we're actually testing anything. -#[rustc_coinductive] -trait AR {} -#[rustc_coinductive] -trait BR {} -trait CR {} - -impl AR for T {} -impl BR for T {} -impl CR for T {} - -fn impls_ar() {} - -fn main() { - impls_a::<()>(); - //~^ ERROR overflow evaluating the requirement `(): A` - - impls_ar::<()>(); - //~^ ERROR overflow evaluating the requirement `(): AR` -} diff --git a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr deleted file mode 100644 index e9cc6bc6c81a..000000000000 --- a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0275]: overflow evaluating the requirement `(): A` - --> $DIR/inductive-not-on-stack.rs:41:15 - | -LL | impls_a::<()>(); - | ^^ - | -note: required by a bound in `impls_a` - --> $DIR/inductive-not-on-stack.rs:25:15 - | -LL | fn impls_a() {} - | ^ required by this bound in `impls_a` - -error[E0275]: overflow evaluating the requirement `(): AR` - --> $DIR/inductive-not-on-stack.rs:44:16 - | -LL | impls_ar::<()>(); - | ^^ - | -note: required by a bound in `impls_ar` - --> $DIR/inductive-not-on-stack.rs:38:16 - | -LL | fn impls_ar() {} - | ^^ required by this bound in `impls_ar` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs deleted file mode 100644 index 6d75d2418643..000000000000 --- a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs +++ /dev/null @@ -1,39 +0,0 @@ -//@ compile-flags: -Znext-solver -#![feature(rustc_attrs)] - -// A test intended to check how we handle provisional results -// for a goal computed with an inductive and a coinductive stack. -// -// Unfortunately this doesn't really detect whether we've done -// something wrong but instead only showcases that we thought of -// this. -// -// FIXME(-Znext-solver=coinductive): With the new coinduction approach -// the same goal stack can be both inductive and coinductive, depending -// on why we're proving a specific nested goal. Rewrite this test -// at that point instead of relying on `BInd`. - - -#[rustc_coinductive] -trait A {} - -#[rustc_coinductive] -trait B {} -trait BInd {} -impl BInd for T {} - -#[rustc_coinductive] -trait C {} -trait CInd {} -impl CInd for T {} - -impl A for T {} -impl B for T {} -impl C for T {} - -fn impls_a() {} - -fn main() { - impls_a::<()>(); - //~^ ERROR overflow evaluating the requirement `(): A` -} diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr deleted file mode 100644 index 17544eb1da52..000000000000 --- a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0275]: overflow evaluating the requirement `(): A` - --> $DIR/mixed-cycles-1.rs:37:15 - | -LL | impls_a::<()>(); - | ^^ - | -note: required by a bound in `impls_a` - --> $DIR/mixed-cycles-1.rs:34:15 - | -LL | fn impls_a() {} - | ^ required by this bound in `impls_a` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs deleted file mode 100644 index c939a6e5ef2f..000000000000 --- a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs +++ /dev/null @@ -1,32 +0,0 @@ -//@ compile-flags: -Znext-solver -#![feature(rustc_attrs)] - -// A test showcasing that the solver may need to -// compute a goal which is already in the provisional -// cache. -// -// However, given that `(): BInd` and `(): B` are currently distinct -// goals, this is actually not possible right now. -// -// FIXME(-Znext-solver=coinductive): With the new coinduction approach -// the same goal stack can be both inductive and coinductive, depending -// on why we're proving a specific nested goal. Rewrite this test -// at that point. - -#[rustc_coinductive] -trait A {} - -#[rustc_coinductive] -trait B {} -trait BInd {} -impl BInd for T {} - -impl A for T {} -impl B for T {} - -fn impls_a() {} - -fn main() { - impls_a::<()>(); - //~^ ERROR overflow evaluating the requirement `(): A` -} diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr deleted file mode 100644 index a9be1016c741..000000000000 --- a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0275]: overflow evaluating the requirement `(): A` - --> $DIR/mixed-cycles-2.rs:30:15 - | -LL | impls_a::<()>(); - | ^^ - | -note: required by a bound in `impls_a` - --> $DIR/mixed-cycles-2.rs:27:15 - | -LL | fn impls_a() {} - | ^ required by this bound in `impls_a` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0275`. From 7eb677e7eb4d7f8235d43e1b01669557fca80487 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 21 Feb 2025 10:11:56 +0100 Subject: [PATCH 453/991] normalizing where-clauses is also coinductive, add tests --- .../src/solve/eval_ctxt/mod.rs | 33 ++++++-- .../src/solve/fulfill/derive_errors.rs | 5 +- .../rustc_type_ir/src/search_graph/mod.rs | 5 +- compiler/rustc_type_ir/src/solve/mod.rs | 9 +++ .../const-generics/issues/issue-88119.stderr | 76 +++++++++++++++++-- tests/ui/sized/coinductive-1.rs | 3 + ...bound-via-impl-where-clause.current.stderr | 23 ++++++ ...em-bound-via-impl-where-clause.next.stderr | 49 ++++++++++++ .../item-bound-via-impl-where-clause.rs | 39 ++++++++++ ...ursive-enum-and-array-impl.current.stderr} | 0 ...-recursive-enum-and-array-impl.next.stderr | 10 +++ .../129541-recursive-enum-and-array-impl.rs | 4 + ...541-recursive-struct.multiple_curr.stderr} | 0 ...541-recursive-struct.multiple_next.stderr} | 0 .../solver-cycles/129541-recursive-struct.rs | 7 +- ...129541-recursive-struct.unique_curr.stderr | 6 ++ ...129541-recursive-struct.unique_next.stderr | 6 ++ 17 files changed, 255 insertions(+), 20 deletions(-) create mode 100644 tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.current.stderr create mode 100644 tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.next.stderr create mode 100644 tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.rs rename tests/ui/traits/solver-cycles/{129541-recursive-enum-and-array-impl.stderr => 129541-recursive-enum-and-array-impl.current.stderr} (100%) create mode 100644 tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.next.stderr rename tests/ui/traits/solver-cycles/{129541-recursive-struct.multiple.stderr => 129541-recursive-struct.multiple_curr.stderr} (100%) rename tests/ui/traits/solver-cycles/{129541-recursive-struct.unique.stderr => 129541-recursive-struct.multiple_next.stderr} (100%) create mode 100644 tests/ui/traits/solver-cycles/129541-recursive-struct.unique_curr.stderr create mode 100644 tests/ui/traits/solver-cycles/129541-recursive-struct.unique_next.stderr diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index b349df325740..d9e26a3cfd3a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -264,7 +264,10 @@ where pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind { match (self.current_goal_kind, source) { - (CurrentGoalKind::CoinductiveTrait, GoalSource::ImplWhereBound) => PathKind::Coinductive, + (_, GoalSource::NormalizeGoal(step_kind)) => step_kind, + (CurrentGoalKind::CoinductiveTrait, GoalSource::ImplWhereBound) => { + PathKind::Coinductive + } _ => PathKind::Inductive, } } @@ -670,8 +673,11 @@ where #[instrument(level = "trace", skip(self))] pub(super) fn add_normalizes_to_goal(&mut self, mut goal: Goal>) { - goal.predicate = - goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(self, goal.param_env)); + goal.predicate = goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new( + self, + GoalSource::Misc, + goal.param_env, + )); self.inspect.add_normalizes_to_goal(self.delegate, self.max_input_universe, goal); self.nested_goals.normalizes_to_goals.push(goal); } @@ -679,7 +685,7 @@ where #[instrument(level = "debug", skip(self))] pub(super) fn add_goal(&mut self, source: GoalSource, mut goal: Goal) { goal.predicate = - goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(self, goal.param_env)); + goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(self, source, goal.param_env)); self.inspect.add_goal(self.delegate, self.max_input_universe, source, goal); self.nested_goals.goals.push((source, goal)); } @@ -1100,6 +1106,7 @@ where { ecx: &'me mut EvalCtxt<'a, D>, param_env: I::ParamEnv, + normalization_goal_source: GoalSource, cache: HashMap, } @@ -1108,8 +1115,18 @@ where D: SolverDelegate, I: Interner, { - fn new(ecx: &'me mut EvalCtxt<'a, D>, param_env: I::ParamEnv) -> Self { - ReplaceAliasWithInfer { ecx, param_env, cache: Default::default() } + fn new( + ecx: &'me mut EvalCtxt<'a, D>, + for_goal_source: GoalSource, + param_env: I::ParamEnv, + ) -> Self { + let step_kind = ecx.step_kind_for_source(for_goal_source); + ReplaceAliasWithInfer { + ecx, + param_env, + normalization_goal_source: GoalSource::NormalizeGoal(step_kind), + cache: Default::default(), + } } } @@ -1132,7 +1149,7 @@ where ty::AliasRelationDirection::Equate, ); self.ecx.add_goal( - GoalSource::Misc, + self.normalization_goal_source, Goal::new(self.cx(), self.param_env, normalizes_to), ); infer_ty @@ -1161,7 +1178,7 @@ where ty::AliasRelationDirection::Equate, ); self.ecx.add_goal( - GoalSource::Misc, + self.normalization_goal_source, Goal::new(self.cx(), self.param_env, normalizes_to), ); infer_ct diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 982782bc57c1..4f177df89e23 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -438,7 +438,10 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { let obligation; match (child_mode, nested_goal.source()) { - (ChildMode::Trait(_) | ChildMode::Host(_), GoalSource::Misc) => { + ( + ChildMode::Trait(_) | ChildMode::Host(_), + GoalSource::Misc | GoalSource::NormalizeGoal(_), + ) => { continue; } (ChildMode::Trait(parent_trait_pred), GoalSource::ImplWhereBound) => { diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 0cf8cfb879f8..18e84db5d686 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -19,6 +19,8 @@ use std::marker::PhantomData; use derive_where::derive_where; use rustc_index::{Idx, IndexVec}; +#[cfg(feature = "nightly")] +use rustc_macros::HashStable_NoContext; use tracing::debug; use crate::data_structures::HashMap; @@ -109,7 +111,8 @@ pub trait Delegate { /// In the initial iteration of a cycle, we do not yet have a provisional /// result. In the case we return an initial provisional result depending /// on the kind of cycle. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub enum PathKind { Coinductive, Inductive, diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index a562b751d8a9..25081976c9e3 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -8,6 +8,7 @@ use derive_where::derive_where; use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use crate::search_graph::PathKind; use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; pub type CanonicalInput::Predicate> = @@ -78,6 +79,14 @@ pub enum GoalSource { /// This is used in two places: projecting to an opaque whose hidden type /// is already registered in the opaque type storage, and for rigid projections. AliasWellFormed, + + /// In case normalizing aliases in nested goals cycles, eagerly normalizing these + /// aliases in the context of the parent may incorrectly change the cycle kind. + /// Normalizing aliases in goals therefore tracks the original path kind for this + /// nested goal. + /// + /// This is necessary for tests/ui/sized/coinductive-1.rs to compile. + NormalizeGoal(PathKind), } #[derive_where(Clone; I: Interner, Goal: Clone)] diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr index c497f1b6d0bd..94f06bbbbc45 100644 --- a/tests/ui/const-generics/issues/issue-88119.stderr +++ b/tests/ui/const-generics/issues/issue-88119.stderr @@ -6,30 +6,90 @@ LL | #![feature(const_trait_impl, generic_const_exprs)] | = help: remove one of these features -error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::()` can be evaluated` +error[E0275]: overflow evaluating the requirement `&T: ~const ConstName` + --> $DIR/issue-88119.rs:19:49 + | +LL | impl const ConstName for &T + | ^^ + +error[E0275]: overflow evaluating the requirement `&T: ConstName` + --> $DIR/issue-88119.rs:19:49 + | +LL | impl const ConstName for &T + | ^^ + +error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` --> $DIR/issue-88119.rs:21:5 | LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::()` can be evaluated` + | ^^^^^^^^^^^^^^^^^^^^^ | note: required by a bound in `<&T as ConstName>` + --> $DIR/issue-88119.rs:21:5 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` + +error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` --> $DIR/issue-88119.rs:21:10 | LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` + | ^^^^^^^^^^^^^^^ + | +note: required by a bound in `<&T as ConstName>` + --> $DIR/issue-88119.rs:21:5 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` -error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::()` can be evaluated` +error[E0275]: overflow evaluating the requirement `&mut T: ~const ConstName` + --> $DIR/issue-88119.rs:26:49 + | +LL | impl const ConstName for &mut T + | ^^^^^^ + +error[E0275]: overflow evaluating the requirement `&mut T: ConstName` + --> $DIR/issue-88119.rs:26:49 + | +LL | impl const ConstName for &mut T + | ^^^^^^ + +error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` --> $DIR/issue-88119.rs:28:5 | LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::()` can be evaluated` + | ^^^^^^^^^^^^^^^^^^^^^ | note: required by a bound in `<&mut T as ConstName>` + --> $DIR/issue-88119.rs:28:5 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` + +error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` --> $DIR/issue-88119.rs:28:10 | LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` + | ^^^^^^^^^^^^^^^ + | +note: required by a bound in `<&mut T as ConstName>` + --> $DIR/issue-88119.rs:28:5 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` -error: aborting due to 3 previous errors +error[E0275]: overflow evaluating the requirement `&&mut u8: ConstName` + --> $DIR/issue-88119.rs:33:35 + | +LL | pub const ICE_1: &'static [u8] = <&&mut u8 as ConstName>::NAME_BYTES; + | ^^^^^^^^ -For more information about this error, try `rustc --explain E0284`. +error[E0275]: overflow evaluating the requirement `&mut &u8: ConstName` + --> $DIR/issue-88119.rs:34:35 + | +LL | pub const ICE_2: &'static [u8] = <&mut &u8 as ConstName>::NAME_BYTES; + | ^^^^^^^^ + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/sized/coinductive-1.rs b/tests/ui/sized/coinductive-1.rs index 3c1ee557af77..42dd8d1f6042 100644 --- a/tests/ui/sized/coinductive-1.rs +++ b/tests/ui/sized/coinductive-1.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver struct Node>(C::Assoc); trait Trait { diff --git a/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.current.stderr b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.current.stderr new file mode 100644 index 000000000000..dd9f7d89aa10 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.current.stderr @@ -0,0 +1,23 @@ +error[E0275]: overflow evaluating the requirement `Vec: Trait` + --> $DIR/item-bound-via-impl-where-clause.rs:31:21 + | +LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required for `Vec` to implement `Trait` + --> $DIR/item-bound-via-impl-where-clause.rs:22:12 + | +LL | impl Trait for L + | ^^^^^^^^ ^ +LL | where +LL | L: Trait, + | -------- unsatisfied trait bound introduced here +note: required by a bound in `transmute` + --> $DIR/item-bound-via-impl-where-clause.rs:29:17 + | +LL | fn transmute, R>(r: L) -> >::Proof { r } + | ^^^^^^^^ required by this bound in `transmute` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.next.stderr b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.next.stderr new file mode 100644 index 000000000000..451c1442ed29 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.next.stderr @@ -0,0 +1,49 @@ +error[E0275]: overflow evaluating the requirement `Vec: Trait` + --> $DIR/item-bound-via-impl-where-clause.rs:31:33 + | +LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]); + | ^ + | +note: required by a bound in `transmute` + --> $DIR/item-bound-via-impl-where-clause.rs:29:17 + | +LL | fn transmute, R>(r: L) -> >::Proof { r } + | ^^^^^^^^ required by this bound in `transmute` + +error[E0275]: overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof == _` + --> $DIR/item-bound-via-impl-where-clause.rs:31:21 + | +LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof == String` + --> $DIR/item-bound-via-impl-where-clause.rs:31:21 + | +LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof: Sized` + --> $DIR/item-bound-via-impl-where-clause.rs:31:21 + | +LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the return type of a function must have a statically known size + +error[E0275]: overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof well-formed` + --> $DIR/item-bound-via-impl-where-clause.rs:31:21 + | +LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof == _` + --> $DIR/item-bound-via-impl-where-clause.rs:31:21 + | +LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.rs b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.rs new file mode 100644 index 000000000000..39381d17f7af --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.rs @@ -0,0 +1,39 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// A variation of #135246 where the cyclic bounds are part of +// the impl instead of the impl associated item. + +trait Trait: Sized { + type Proof: Trait; +} + +// We need to use indirection here as we otherwise normalize +// `>::Proof` before recursing into +// `R: Trait>::Proof>`. +trait Indir, R>: Trait>::Proof> {} +impl Indir for R +where + L: Trait, + R: Trait>::Proof>, +{} + +impl Trait for L +where + L: Trait, + R: Indir, + { + type Proof = R; +} +fn transmute, R>(r: L) -> >::Proof { r } +fn main() { + let s: String = transmute::<_, String>(vec![65_u8, 66, 67]); + //~^ ERROR overflow evaluating the requirement `Vec: Trait` + //[next]~| ERROR overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof == _` + //[next]~| ERROR overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof == String` + //[next]~| ERROR overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof: Sized` + //[next]~| ERROR overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof well-formed` + //[next]~| ERROR overflow evaluating the requirement `< as Trait>::Proof as Trait>::Proof == _` + println!("{}", s); // ABC +} diff --git a/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.stderr b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.current.stderr similarity index 100% rename from tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.stderr rename to tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.current.stderr diff --git a/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.next.stderr b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.next.stderr new file mode 100644 index 000000000000..50dcea0bfac6 --- /dev/null +++ b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.next.stderr @@ -0,0 +1,10 @@ +error[E0391]: cycle detected when computing layout of `<[Hello] as Normalize>::Assoc` + | + = note: ...which requires computing layout of `Hello`... + = note: ...which again requires computing layout of `<[Hello] as Normalize>::Assoc`, completing the cycle + = note: cycle used when computing layout of `Hello` + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs index 197207dfb4be..5b7bf5f3404c 100644 --- a/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs +++ b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs @@ -1,6 +1,10 @@ // Regression test for #129541 //~^ ERROR cycle detected when computing layout of `<[Hello] as Normalize>::Assoc` [E0391] +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + trait Bound {} trait Normalize { type Assoc; diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.multiple.stderr b/tests/ui/traits/solver-cycles/129541-recursive-struct.multiple_curr.stderr similarity index 100% rename from tests/ui/traits/solver-cycles/129541-recursive-struct.multiple.stderr rename to tests/ui/traits/solver-cycles/129541-recursive-struct.multiple_curr.stderr diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.unique.stderr b/tests/ui/traits/solver-cycles/129541-recursive-struct.multiple_next.stderr similarity index 100% rename from tests/ui/traits/solver-cycles/129541-recursive-struct.unique.stderr rename to tests/ui/traits/solver-cycles/129541-recursive-struct.multiple_next.stderr diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs index 729771e560e9..1f5d0a772a2b 100644 --- a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs +++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs @@ -1,6 +1,9 @@ // Regression test for #129541 -//@ revisions: unique multiple +//@ revisions: unique_curr unique_next multiple_curr multiple_next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[unique_next] compile-flags: -Znext-solver +//@[multiple_next] compile-flags: -Znext-solver //@ error-pattern: reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc` trait Bound {} @@ -8,7 +11,7 @@ trait Normalize { type Assoc; } -#[cfg(multiple)] +#[cfg(any(multiple_curr, multiple_next))] impl Normalize for T { type Assoc = T; } diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.unique_curr.stderr b/tests/ui/traits/solver-cycles/129541-recursive-struct.unique_curr.stderr new file mode 100644 index 000000000000..93b064cdce2a --- /dev/null +++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.unique_curr.stderr @@ -0,0 +1,6 @@ +error: reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` + +error: aborting due to 1 previous error + diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.unique_next.stderr b/tests/ui/traits/solver-cycles/129541-recursive-struct.unique_next.stderr new file mode 100644 index 000000000000..93b064cdce2a --- /dev/null +++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.unique_next.stderr @@ -0,0 +1,6 @@ +error: reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` + +error: aborting due to 1 previous error + From fe874cd99bd4ed85e31144c9c359ac3f99dfa4cd Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 21 Feb 2025 10:24:11 +0100 Subject: [PATCH 454/991] add test for newly supported behavior --- ...one-coinductive-step-needed.current.stderr | 17 ++++++++++++ .../only-one-coinductive-step-needed.rs | 26 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr create mode 100644 tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr new file mode 100644 index 000000000000..5e8e2ece54db --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr @@ -0,0 +1,17 @@ +error[E0275]: overflow evaluating the requirement `Foo: SendIndir` + --> $DIR/only-one-coinductive-step-needed.rs:9:15 + | +LL | struct Foo( as Trait>::Assoc); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required for `Foo` to implement `Trait` + --> $DIR/only-one-coinductive-step-needed.rs:18:20 + | +LL | impl Trait for T { + | --------- ^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs new file mode 100644 index 000000000000..c73189fbb08a --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs @@ -0,0 +1,26 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +// #136824 changed cycles to be coinductive if they have at least +// one productive step, causing this test to pass with the new solver. + +struct Foo( as Trait>::Assoc); +//[current]~^ ERROR overflow evaluating the requirement `Foo: SendIndir` + +trait SendIndir {} +impl SendIndir for T {} + +trait Trait { + type Assoc; +} +impl Trait for T { + type Assoc = (); +} + +fn is_send() {} + +fn main() { + is_send::>(); +} From ef771b84505c1d7b87bbc071c67393c278dce952 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 26 Feb 2025 14:28:44 +0100 Subject: [PATCH 455/991] review --- compiler/rustc_middle/src/ty/predicate.rs | 14 -------------- .../src/solve/eval_ctxt/mod.rs | 15 +++++++++++++++ .../src/traits/select/mod.rs | 12 +++++++++--- compiler/rustc_type_ir/src/solve/mod.rs | 5 ++--- ...nly-one-coinductive-step-needed.current.stderr | 4 ++-- .../only-one-coinductive-step-needed.rs | 8 ++++++++ 6 files changed, 36 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 089855bfb613..1674ca4cfc56 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -4,7 +4,6 @@ use rustc_data_structures::intern::Interned; use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, extension}; use rustc_type_ir as ir; -use tracing::instrument; use crate::ty::{ self, DebruijnIndex, EarlyBinder, PredicatePolarity, Ty, TyCtxt, TypeFlags, Upcast, UpcastFrom, @@ -115,19 +114,6 @@ impl<'tcx> Predicate<'tcx> { Some(tcx.mk_predicate(kind)) } - /// Only used by the old solver to decide whether a predicate is accepted - /// in a coinductive trait solver cycle. - #[instrument(level = "debug", skip(tcx), ret)] - pub fn is_coinductive(self, tcx: TyCtxt<'tcx>) -> bool { - match self.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { - tcx.trait_is_coinductive(data.def_id()) - } - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => true, - _ => false, - } - } - /// Whether this projection can be soundly normalized. /// /// Wf predicates must not be normalized, as normalization diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index d9e26a3cfd3a..cee52c05efb8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -262,6 +262,14 @@ where self.delegate.typing_mode() } + /// Computes the `PathKind` for the step from the current goal to the + /// nested goal required due to `source`. + /// + /// See #136824 for a more detailed reasoning for this behavior. We + /// consider cycles to be coinductive if they 'step into' a where-clause + /// of a coinductive trait. We will likely extend this function in the future + /// and will need to clearly document it in the rustc-dev-guide before + /// stabilization. pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind { match (self.current_goal_kind, source) { (_, GoalSource::NormalizeGoal(step_kind)) => step_kind, @@ -1099,6 +1107,13 @@ where /// /// This is a performance optimization to more eagerly detect cycles during trait /// solving. See tests/ui/traits/next-solver/cycles/cycle-modulo-ambig-aliases.rs. +/// +/// The emitted goals get evaluated in the context of the parent goal; by +/// replacing aliases in nested goals we essentially pull the normalization out of +/// the nested goal. We want to treat the goal as if the normalization still happens +/// inside of the nested goal by inheriting the `step_kind` of the nested goal and +/// storing it in the `GoalSource` of the emitted `AliasRelate` goals. +/// This is necessary for tests/ui/sized/coinductive-1.rs to compile. struct ReplaceAliasWithInfer<'me, 'a, D, I> where D: SolverDelegate, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 436ce3dddd9f..a4ee1cbb8531 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1225,15 +1225,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// that recursion is ok. This routine returns `true` if the top of the /// stack (`cycle[0]`): /// - /// - is a defaulted trait, + /// - is a coinductive trait: an auto-trait or `Sized`, /// - it also appears in the backtrace at some position `X`, /// - all the predicates at positions `X..` between `X` and the top are - /// also defaulted traits. + /// also coinductive traits. pub(crate) fn coinductive_match(&mut self, mut cycle: I) -> bool where I: Iterator>, { - cycle.all(|predicate| predicate.is_coinductive(self.tcx())) + cycle.all(|p| match p.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { + self.infcx.tcx.trait_is_coinductive(data.def_id()) + } + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => true, + _ => false, + }) } /// Further evaluates `candidate` to decide whether all type parameters match and whether nested diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 25081976c9e3..b93668b5111b 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -83,9 +83,8 @@ pub enum GoalSource { /// In case normalizing aliases in nested goals cycles, eagerly normalizing these /// aliases in the context of the parent may incorrectly change the cycle kind. /// Normalizing aliases in goals therefore tracks the original path kind for this - /// nested goal. - /// - /// This is necessary for tests/ui/sized/coinductive-1.rs to compile. + /// nested goal. See the comment of the `ReplaceAliasWithInfer` visitor for more + /// details. NormalizeGoal(PathKind), } diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr index 5e8e2ece54db..ec2198780586 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr @@ -1,11 +1,11 @@ error[E0275]: overflow evaluating the requirement `Foo: SendIndir` - --> $DIR/only-one-coinductive-step-needed.rs:9:15 + --> $DIR/only-one-coinductive-step-needed.rs:17:15 | LL | struct Foo( as Trait>::Assoc); | ^^^^^^^^^^^^^^^^^^^^^^^^ | note: required for `Foo` to implement `Trait` - --> $DIR/only-one-coinductive-step-needed.rs:18:20 + --> $DIR/only-one-coinductive-step-needed.rs:26:20 | LL | impl Trait for T { | --------- ^^^^^ ^ diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs index c73189fbb08a..e41f7d7f3ceb 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs @@ -5,6 +5,14 @@ // #136824 changed cycles to be coinductive if they have at least // one productive step, causing this test to pass with the new solver. +// +// The cycle in the test is the following: +// - `Foo: Send`, builtin auto-trait impl requires +// - ` as Trait>::Assoc: Send`, requires normalizing self type via impl, requires +// - `Foo: SendIndir`, via impl requires +// - `Foo: Send` cycle +// +// The old solver treats this cycle as inductive due to the `Foo: SendIndir` step. struct Foo( as Trait>::Assoc); //[current]~^ ERROR overflow evaluating the requirement `Foo: SendIndir` From 6a3b30fdf4c7ba5569181b50469ca6d198ab46b8 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 28 Feb 2025 12:05:31 +0100 Subject: [PATCH 456/991] add test using only trait bounds --- ...inductive-step-needed-trait.current.stderr | 22 ++++++++++++++++ .../only-one-coinductive-step-needed-trait.rs | 26 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.current.stderr create mode 100644 tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.rs diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.current.stderr b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.current.stderr new file mode 100644 index 000000000000..89b8b53c3f4d --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.current.stderr @@ -0,0 +1,22 @@ +error[E0275]: overflow evaluating the requirement `u32: SendIndir>` + --> $DIR/only-one-coinductive-step-needed-trait.rs:24:5 + | +LL | is_send::>(); + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: required for `Foo` to implement `Send` + --> $DIR/only-one-coinductive-step-needed-trait.rs:17:35 + | +LL | unsafe impl>> Send for Foo {} + | ----------------- ^^^^ ^^^^^^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `is_send` + --> $DIR/only-one-coinductive-step-needed-trait.rs:22:15 + | +LL | fn is_send() {} + | ^^^^ required by this bound in `is_send` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.rs b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.rs new file mode 100644 index 000000000000..294156869284 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.rs @@ -0,0 +1,26 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +// #136824 changed cycles to be coinductive if they have at least +// one productive step, causing this test to pass with the new solver. +// +// The cycle in the test is the following: +// - `Foo: Send`, impl requires +// - `T: SendIndir>`, impl requires +// - `Foo: Send` cycle +// +// The old solver treats this cycle as inductive due to the `T: SendIndir` step. + +struct Foo(T); +unsafe impl>> Send for Foo {} + +trait SendIndir {} +impl SendIndir for T {} + +fn is_send() {} +fn main() { + is_send::>(); + //[current]~^ ERROR overflow evaluating the requirement `u32: SendIndir>` +} From e3f42aa59fd9e325690bb32f10e865c9a6f47779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Fri, 28 Feb 2025 21:10:21 +0800 Subject: [PATCH 457/991] compiler: bump `cc` to 1.2.16 to fix `x86` Windows jobs on newest Windows SDK See . --- Cargo.lock | 4 ++-- compiler/rustc_codegen_ssa/Cargo.toml | 2 +- compiler/rustc_llvm/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2227f5f3e993..e93af7926a2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -407,9 +407,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.2.13" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "shlex", ] diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 83d847f2d155..1346efcb87c2 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -11,7 +11,7 @@ bitflags = "2.4.1" bstr = "1.11.3" # Pinned so `cargo update` bumps don't cause breakage. Please also update the # `cc` in `rustc_llvm` if you update the `cc` here. -cc = "=1.2.13" +cc = "=1.2.16" either = "1.5.0" itertools = "0.12" pathdiff = "0.2.0" diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 4f3ce77efc44..061562b2ec5e 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -12,5 +12,5 @@ libc = "0.2.73" # tidy-alphabetical-start # Pinned so `cargo update` bumps don't cause breakage. Please also update the # pinned `cc` in `rustc_codegen_ssa` if you update `cc` here. -cc = "=1.2.13" +cc = "=1.2.16" # tidy-alphabetical-end From be5495b1917873d1ff28e051ad94c46a46142781 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 28 Feb 2025 08:30:41 -0500 Subject: [PATCH 458/991] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 1d1d646c06a8..2622e844bc1e 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 1d1d646c06a84c1aa53967b394b7f1218f85db82 +Subproject commit 2622e844bc1e2e6123e54e94e4706f7b6195ce3d From da0fbc19a5b2710d03c9f2d9ccd6bc572c2b2ffa Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Fri, 28 Feb 2025 09:10:09 -0500 Subject: [PATCH 459/991] Allow the optimizer to elide bounds checks when enumerating `IndexSlice`/`IndecVec`. --- compiler/rustc_index/src/slice.rs | 6 ++++++ compiler/rustc_index/src/vec.rs | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index f17ea9e4b59a..0f4f885bb3ae 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -65,6 +65,8 @@ impl IndexSlice { #[inline] pub fn iter_enumerated(&self) -> impl DoubleEndedIterator + ExactSizeIterator { + // Allow the optimizer to elide the bounds checking when creating each index. + let _ = I::new(self.len()); self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t)) } @@ -72,6 +74,8 @@ impl IndexSlice { pub fn indices( &self, ) -> impl DoubleEndedIterator + ExactSizeIterator + Clone + 'static { + // Allow the optimizer to elide the bounds checking when creating each index. + let _ = I::new(self.len()); (0..self.len()).map(|n| I::new(n)) } @@ -84,6 +88,8 @@ impl IndexSlice { pub fn iter_enumerated_mut( &mut self, ) -> impl DoubleEndedIterator + ExactSizeIterator { + // Allow the optimizer to elide the bounds checking when creating each index. + let _ = I::new(self.len()); self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t)) } diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 7f3f3ead5f2a..13f0dda180be 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -93,6 +93,8 @@ impl IndexVec { /// be allocated only once, with a capacity of at least `n`.) #[inline] pub fn from_fn_n(func: impl FnMut(I) -> T, n: usize) -> Self { + // Allow the optimizer to elide the bounds checking when creating each index. + let _ = I::new(n); IndexVec::from_raw((0..n).map(I::new).map(func).collect()) } @@ -128,6 +130,8 @@ impl IndexVec { pub fn into_iter_enumerated( self, ) -> impl DoubleEndedIterator + ExactSizeIterator { + // Allow the optimizer to elide the bounds checking when creating each index. + let _ = I::new(self.len()); self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t)) } From e66bf08f93de71125765d0e7e1a5f5d1550406ea Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 28 Feb 2025 16:10:38 +0200 Subject: [PATCH 460/991] sort list --- .../ui/attributes/auxiliary/used_pre_main_constructor.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs index 686dcb277f89..192594d2d104 100644 --- a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs +++ b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs @@ -10,14 +10,14 @@ #[cfg_attr( any( - target_os = "linux", target_os = "android", + target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", target_os = "netbsd", target_os = "openbsd", - target_os = "dragonfly", - target_os = "illumos", - target_os = "haiku" ), link_section = ".init_array" )] From f8091c49ffc2bccce89972b0b4058b92a62ee260 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 28 Feb 2025 16:10:14 +0200 Subject: [PATCH 461/991] qnx: avoid test failure Fixes tests/ui/attributes/used_with_archive.rs fail --- tests/ui/attributes/auxiliary/used_pre_main_constructor.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs index 192594d2d104..d94572ef5d6c 100644 --- a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs +++ b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs @@ -17,6 +17,7 @@ target_os = "illumos", target_os = "linux", target_os = "netbsd", + target_os = "nto", target_os = "openbsd", ), link_section = ".init_array" From 7fdd193e23c2c1afaa071ee167232c07bd2a4be8 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 28 Feb 2025 16:48:58 +0300 Subject: [PATCH 462/991] tests: Unignore target modifier tests on all platforms These tests can be `check-pass` and do not need dynamic libraries. Also remove other unnecessary stuff from them. --- .../auxiliary/default_reg_struct_return.rs | 21 +++------------ .../auxiliary/wrong_regparm.rs | 21 +++------------ .../auxiliary/wrong_regparm_and_ret.rs | 21 +++------------ .../defaults_check.error.stderr | 4 +-- tests/ui/target_modifiers/defaults_check.rs | 27 +++++++------------ ...ncompatible_regparm.error_generated.stderr | 4 +-- .../target_modifiers/incompatible_regparm.rs | 23 ++++++---------- tests/ui/target_modifiers/two_flags.rs | 22 +++++---------- .../two_flags.unknown_allowed.stderr | 4 +-- 9 files changed, 43 insertions(+), 104 deletions(-) diff --git a/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs b/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs index 355e7c56e946..2bbdc8392110 100644 --- a/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs +++ b/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs @@ -1,20 +1,7 @@ -//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort -// Auxiliary build problems with aarch64-apple: -// Shared library linking cc seems to convert "-m32" flag into -arch armv4t -// Auxiliary build problems with i686-mingw: linker `cc` not found -//@ only-x86 -//@ ignore-windows -//@ ignore-apple +//@ no-prefer-dynamic +//@ compile-flags: --target i686-unknown-linux-gnu //@ needs-llvm-components: x86 + +#![feature(no_core)] #![crate_type = "rlib"] #![no_core] -#![feature(no_core, lang_items, repr_simd)] - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -pub fn somefun() {} - -pub struct S; diff --git a/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs b/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs index 2e16f1ee747c..267292faecd5 100644 --- a/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs +++ b/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs @@ -1,20 +1,7 @@ -//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Cpanic=abort -// Auxiliary build problems with aarch64-apple: -// Shared library linking cc seems to convert "-m32" flag into -arch armv4t -// Auxiliary build problems with i686-mingw: linker `cc` not found -//@ only-x86 -//@ ignore-windows -//@ ignore-apple +//@ no-prefer-dynamic +//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 //@ needs-llvm-components: x86 + +#![feature(no_core)] #![crate_type = "rlib"] #![no_core] -#![feature(no_core, lang_items, repr_simd)] - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -pub fn somefun() {} - -pub struct S; diff --git a/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs b/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs index 39c6be9d5892..82ee3e71d16a 100644 --- a/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs +++ b/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs @@ -1,20 +1,7 @@ -//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Zreg-struct-return=true -Cpanic=abort -// Auxiliary build problems with aarch64-apple: -// Shared library linking cc seems to convert "-m32" flag into -arch armv4t -// Auxiliary build problems with i686-mingw: linker `cc` not found -//@ only-x86 -//@ ignore-windows -//@ ignore-apple +//@ no-prefer-dynamic +//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Zreg-struct-return=true //@ needs-llvm-components: x86 + +#![feature(no_core)] #![crate_type = "rlib"] #![no_core] -#![feature(no_core, lang_items, repr_simd)] - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -pub fn somefun() {} - -pub struct S; diff --git a/tests/ui/target_modifiers/defaults_check.error.stderr b/tests/ui/target_modifiers/defaults_check.error.stderr index c545dd710690..4833fe906775 100644 --- a/tests/ui/target_modifiers/defaults_check.error.stderr +++ b/tests/ui/target_modifiers/defaults_check.error.stderr @@ -1,7 +1,7 @@ error: mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check` - --> $DIR/defaults_check.rs:20:1 + --> $DIR/defaults_check.rs:15:1 | -LL | #![crate_type = "rlib"] +LL | #![feature(no_core)] | ^ | = help: the `-Zreg-struct-return` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely diff --git a/tests/ui/target_modifiers/defaults_check.rs b/tests/ui/target_modifiers/defaults_check.rs index b8f4848d3a42..de72acd32bc1 100644 --- a/tests/ui/target_modifiers/defaults_check.rs +++ b/tests/ui/target_modifiers/defaults_check.rs @@ -1,27 +1,20 @@ // Tests that default unspecified target modifier value in dependency crate is ok linked // with the same value, explicitly specified -//@ aux-crate:default_reg_struct_return=default_reg_struct_return.rs + +//@ aux-build:default_reg_struct_return.rs //@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort -//@ revisions:error ok ok_explicit +//@ needs-llvm-components: x86 + +//@ revisions: ok ok_explicit error //@[ok] compile-flags: //@[ok_explicit] compile-flags: -Zreg-struct-return=false //@[error] compile-flags: -Zreg-struct-return=true +//@[ok] check-pass +//@[ok_explicit] check-pass -// Auxiliary build problems with aarch64-apple: -// Shared library linking cc seems to convert "-m32" flag into -arch armv4t -// Auxiliary build problems with i686-mingw: linker `cc` not found -//@ only-x86 -//@ ignore-windows -//@ ignore-apple -//@ needs-llvm-components: x86 -//@[ok] build-pass -//@[ok_explicit] build-pass - -#![crate_type = "rlib"] +#![feature(no_core)] //[error]~^ ERROR mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check` +#![crate_type = "rlib"] #![no_core] -#![feature(no_core, lang_items, repr_simd)] -fn foo() { - default_reg_struct_return::somefun(); -} +extern crate default_reg_struct_return; diff --git a/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr b/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr index 692fc7a4e3fa..81015694d05e 100644 --- a/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr +++ b/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr @@ -1,7 +1,7 @@ error: mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm` - --> $DIR/incompatible_regparm.rs:16:1 + --> $DIR/incompatible_regparm.rs:11:1 | -LL | #![crate_type = "rlib"] +LL | #![feature(no_core)] | ^ | = help: the `-Zregparm` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely diff --git a/tests/ui/target_modifiers/incompatible_regparm.rs b/tests/ui/target_modifiers/incompatible_regparm.rs index e866c5aa891b..befe573b276c 100644 --- a/tests/ui/target_modifiers/incompatible_regparm.rs +++ b/tests/ui/target_modifiers/incompatible_regparm.rs @@ -1,23 +1,16 @@ -//@ aux-crate:wrong_regparm=wrong_regparm.rs -//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=1 -Cpanic=abort -// Auxiliary build problems with aarch64-apple: -// Shared library linking cc seems to convert "-m32" flag into -arch armv4t -// Auxiliary build problems with i686-mingw: linker `cc` not found -//@ only-x86 -//@ ignore-windows -//@ ignore-apple +//@ aux-build:wrong_regparm.rs +//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=1 //@ needs-llvm-components: x86 -//@ revisions:error_generated allow_regparm_mismatch allow_no_value +//@ revisions:allow_regparm_mismatch allow_no_value error_generated //@[allow_regparm_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=regparm -//@[allow_regparm_mismatch] build-pass //@[allow_no_value] compile-flags: -Cunsafe-allow-abi-mismatch +//@[error_generated] compile-flags: +//@[allow_regparm_mismatch] check-pass -#![crate_type = "rlib"] +#![feature(no_core)] //[error_generated]~^ ERROR mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm` +#![crate_type = "rlib"] #![no_core] -#![feature(no_core, lang_items, repr_simd)] -fn foo() { - wrong_regparm::somefun(); -} +extern crate wrong_regparm; diff --git a/tests/ui/target_modifiers/two_flags.rs b/tests/ui/target_modifiers/two_flags.rs index ca17117a267b..d5b5a923ca09 100644 --- a/tests/ui/target_modifiers/two_flags.rs +++ b/tests/ui/target_modifiers/two_flags.rs @@ -1,23 +1,15 @@ -//@ aux-crate:wrong_regparm_and_ret=wrong_regparm_and_ret.rs -//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort -// Auxiliary build problems with aarch64-apple: -// Shared library linking cc seems to convert "-m32" flag into -arch armv4t -// Auxiliary build problems with i686-mingw: linker `cc` not found -//@ only-x86 -//@ ignore-windows -//@ ignore-apple +//@ aux-build:wrong_regparm_and_ret.rs +//@ compile-flags: --target i686-unknown-linux-gnu //@ needs-llvm-components: x86 + //@ revisions:two_allowed unknown_allowed - //@[two_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=regparm,reg-struct-return -//@[two_allowed] build-pass //@[unknown_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=unknown_flag -Zregparm=2 -Zreg-struct-return=true +//@[two_allowed] check-pass -#![crate_type = "rlib"] +#![feature(no_core)] //[unknown_allowed]~^ ERROR unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag` +#![crate_type = "rlib"] #![no_core] -#![feature(no_core, lang_items, repr_simd)] -fn foo() { - wrong_regparm_and_ret::somefun(); -} +extern crate wrong_regparm_and_ret; diff --git a/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr b/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr index c8040c6e389b..248bde452f22 100644 --- a/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr +++ b/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr @@ -1,7 +1,7 @@ error: unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag` - --> $DIR/two_flags.rs:16:1 + --> $DIR/two_flags.rs:10:1 | -LL | #![crate_type = "rlib"] +LL | #![feature(no_core)] | ^ error: aborting due to 1 previous error From 50a37ca56c1f13fdfc0df789a92d0052e731e9ba Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Feb 2025 15:54:26 +0100 Subject: [PATCH 463/991] miri native-call support: all previously exposed provenance is accessible to the callee --- .../rustc_const_eval/src/interpret/memory.rs | 15 +++---- src/tools/miri/src/alloc_addresses/mod.rs | 25 +++++++++++- src/tools/miri/src/machine.rs | 10 +---- src/tools/miri/src/shims/native_lib.rs | 16 +++----- .../tests/native-lib/pass/ptr_write_access.rs | 40 +++++++++++++++++-- .../miri/tests/native-lib/ptr_write_access.c | 19 +++++++++ 6 files changed, 92 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 4f4b6785844d..ce0b5a350e03 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -955,18 +955,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Handle the effect an FFI call might have on the state of allocations. /// This overapproximates the modifications which external code might make to memory: - /// We set all reachable allocations as initialized, mark all provenances as exposed + /// We set all reachable allocations as initialized, mark all reachable provenances as exposed /// and overwrite them with `Provenance::WILDCARD`. - pub fn prepare_for_native_call( - &mut self, - id: AllocId, - initial_prov: M::Provenance, - ) -> InterpResult<'tcx> { - // Expose provenance of the root allocation. - M::expose_provenance(self, initial_prov)?; - + /// + /// The allocations in `ids` are assumed to be already exposed. + pub fn prepare_for_native_call(&mut self, ids: Vec) -> InterpResult<'tcx> { let mut done = FxHashSet::default(); - let mut todo = vec![id]; + let mut todo = ids; while let Some(id) = todo.pop() { if !done.insert(id) { // We already saw this allocation before, don't process it again. diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index a4f2a117b181..ff3a25e94bd5 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -285,9 +285,19 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { - fn expose_ptr(&self, alloc_id: AllocId, tag: BorTag) -> InterpResult<'tcx> { + fn expose_provenance(&self, provenance: Provenance) -> InterpResult<'tcx> { let this = self.eval_context_ref(); let mut global_state = this.machine.alloc_addresses.borrow_mut(); + + let (alloc_id, tag) = match provenance { + Provenance::Concrete { alloc_id, tag } => (alloc_id, tag), + Provenance::Wildcard => { + // No need to do anything for wildcard pointers as + // their provenances have already been previously exposed. + return interp_ok(()); + } + }; + // In strict mode, we don't need this, so we can save some cycles by not tracking it. if global_state.provenance_mode == ProvenanceMode::Strict { return interp_ok(()); @@ -422,6 +432,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let rel_offset = this.truncate_to_target_usize(addr.bytes().wrapping_sub(base_addr)); Some((alloc_id, Size::from_bytes(rel_offset))) } + + /// Prepare all exposed memory for a native call. + /// This overapproximates the modifications which external code might make to memory: + /// We set all reachable allocations as initialized, mark all reachable provenances as exposed + /// and overwrite them with `Provenance::WILDCARD`. + fn prepare_exposed_for_native_call(&mut self) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + // We need to make a deep copy of this list, but it's fine; it also serves as scratch space + // for the search within `prepare_for_native_call`. + let exposed: Vec = + this.machine.alloc_addresses.get_mut().exposed.iter().copied().collect(); + this.prepare_for_native_call(exposed) + } } impl<'tcx> MiriMachine<'tcx> { diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 4ece8f7895de..dbb092f67286 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1291,18 +1291,12 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { /// Called on `ptr as usize` casts. /// (Actually computing the resulting `usize` doesn't need machine help, /// that's just `Scalar::try_to_int`.) + #[inline(always)] fn expose_provenance( ecx: &InterpCx<'tcx, Self>, provenance: Self::Provenance, ) -> InterpResult<'tcx> { - match provenance { - Provenance::Concrete { alloc_id, tag } => ecx.expose_ptr(alloc_id, tag), - Provenance::Wildcard => { - // No need to do anything for wildcard pointers as - // their provenances have already been previously exposed. - interp_ok(()) - } - } + ecx.expose_provenance(provenance) } /// Convert a pointer with provenance into an allocation-offset pair and extra provenance info. diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index 8c9e1860f31d..c6fcb0355eb8 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -160,16 +160,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let imm = this.read_immediate(arg)?; libffi_args.push(imm_to_carg(&imm, this)?); - // If we are passing a pointer, prepare the memory it points to. + // If we are passing a pointer, expose its provenance. Below, all exposed memory + // (previously exposed and new exposed) will then be properly prepared. if matches!(arg.layout.ty.kind(), ty::RawPtr(..)) { let ptr = imm.to_scalar().to_pointer(this)?; let Some(prov) = ptr.provenance else { - // Pointer without provenance may not access any memory. - continue; - }; - // We use `get_alloc_id` for its best-effort behaviour with Wildcard provenance. - let Some(alloc_id) = prov.get_alloc_id() else { - // Wildcard pointer, whatever it points to must be already exposed. + // Pointer without provenance may not access any memory anyway, skip. continue; }; // The first time this happens, print a warning. @@ -178,12 +174,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.emit_diagnostic(NonHaltingDiagnostic::NativeCallSharedMem); } - this.prepare_for_native_call(alloc_id, prov)?; + this.expose_provenance(prov)?; } } - // FIXME: In the future, we should also call `prepare_for_native_call` on all previously - // exposed allocations, since C may access any of them. + // Prepare all exposed memory. + this.prepare_exposed_for_native_call()?; // Convert them to `libffi::high::Arg` type. let libffi_args = libffi_args diff --git a/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs b/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs index a92e63a4da6d..bd4e0b23601f 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs +++ b/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs @@ -6,7 +6,7 @@ #![feature(box_as_ptr)] use std::mem::MaybeUninit; -use std::ptr::null; +use std::ptr; fn main() { test_increment_int(); @@ -20,6 +20,8 @@ fn main() { test_pass_dangling(); test_swap_ptr_triple_dangling(); test_return_ptr(); + test_pass_ptr_as_int(); + test_pass_ptr_via_previously_shared_mem(); } /// Test function that modifies an int. @@ -112,7 +114,7 @@ fn test_swap_ptr() { } let x = 61; - let (mut ptr0, mut ptr1) = (&raw const x, null()); + let (mut ptr0, mut ptr1) = (&raw const x, ptr::null()); unsafe { swap_ptr(&mut ptr0, &mut ptr1) }; assert_eq!(unsafe { *ptr1 }, x); @@ -131,7 +133,7 @@ fn test_swap_ptr_tuple() { } let x = 71; - let mut tuple = Tuple { ptr0: &raw const x, ptr1: null() }; + let mut tuple = Tuple { ptr0: &raw const x, ptr1: ptr::null() }; unsafe { swap_ptr_tuple(&mut tuple) } assert_eq!(unsafe { *tuple.ptr1 }, x); @@ -148,7 +150,7 @@ fn test_overwrite_dangling() { drop(b); unsafe { overwrite_ptr(&mut ptr) }; - assert_eq!(ptr, null()); + assert_eq!(ptr, ptr::null()); } /// Test function that passes a dangling pointer. @@ -200,3 +202,33 @@ fn test_return_ptr() { let ptr = unsafe { return_ptr(ptr) }; assert_eq!(unsafe { *ptr }, x); } + +/// Test casting a pointer to an integer and passing that to C. +fn test_pass_ptr_as_int() { + extern "C" { + fn pass_ptr_as_int(ptr: usize, set_to_val: i32); + } + + let mut m: MaybeUninit = MaybeUninit::uninit(); + unsafe { pass_ptr_as_int(m.as_mut_ptr() as usize, 42) }; + assert_eq!(unsafe { m.assume_init() }, 42); +} + +fn test_pass_ptr_via_previously_shared_mem() { + extern "C" { + fn set_shared_mem(ptr: *mut *mut i32); + fn init_ptr_stored_in_shared_mem(val: i32); + } + + let mut m: *mut i32 = ptr::null_mut(); + let ptr_to_m = &raw mut m; + unsafe { set_shared_mem(&raw mut m) }; + + let mut m2: MaybeUninit = MaybeUninit::uninit(); + // Store a pointer to m2 somewhere that C code can access it. + unsafe { ptr_to_m.write(m2.as_mut_ptr()) }; + // Have C code write there. + unsafe { init_ptr_stored_in_shared_mem(42) }; + // Ensure this memory is now considered initialized. + assert_eq!(unsafe { m2.assume_init() }, 42); +} diff --git a/src/tools/miri/tests/native-lib/ptr_write_access.c b/src/tools/miri/tests/native-lib/ptr_write_access.c index b54c5d86b210..96fe413c0d8c 100644 --- a/src/tools/miri/tests/native-lib/ptr_write_access.c +++ b/src/tools/miri/tests/native-lib/ptr_write_access.c @@ -1,4 +1,5 @@ #include +#include // See comments in build_native_lib() #define EXPORT __attribute__((visibility("default"))) @@ -88,3 +89,21 @@ EXPORT void swap_ptr_triple_dangling(Triple *t_ptr) { EXPORT const int *return_ptr(const int *ptr) { return ptr; } + +/* Test: test_pass_ptr_as_int */ + +EXPORT void pass_ptr_as_int(uintptr_t ptr, int set_to_val) { + *(int*)ptr = set_to_val; +} + +/* Test: test_pass_ptr_via_previously_shared_mem */ + +int** shared_place; + +EXPORT void set_shared_mem(int** ptr) { + shared_place = ptr; +} + +EXPORT void init_ptr_stored_in_shared_mem(int val) { + **shared_place = val; +} From 88f988cf139797edd56aea011998d5c9f07b5685 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Feb 2025 16:06:27 +0100 Subject: [PATCH 464/991] use fixed-width integer types in C code --- .../miri/tests/native-lib/ptr_read_access.c | 15 +++--- .../miri/tests/native-lib/ptr_write_access.c | 46 +++++++++---------- .../miri/tests/native-lib/scalar_arguments.c | 13 +++--- 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/tools/miri/tests/native-lib/ptr_read_access.c b/src/tools/miri/tests/native-lib/ptr_read_access.c index 3b427d6033e3..b89126d3d7c8 100644 --- a/src/tools/miri/tests/native-lib/ptr_read_access.c +++ b/src/tools/miri/tests/native-lib/ptr_read_access.c @@ -1,33 +1,34 @@ #include +#include // See comments in build_native_lib() #define EXPORT __attribute__((visibility("default"))) /* Test: test_access_pointer */ -EXPORT void print_pointer(const int *ptr) { +EXPORT void print_pointer(const int32_t *ptr) { printf("printing pointer dereference from C: %d\n", *ptr); } /* Test: test_access_simple */ typedef struct Simple { - int field; + int32_t field; } Simple; -EXPORT int access_simple(const Simple *s_ptr) { +EXPORT int32_t access_simple(const Simple *s_ptr) { return s_ptr->field; } /* Test: test_access_nested */ typedef struct Nested { - int value; + int32_t value; struct Nested *next; } Nested; // Returns the innermost/last value of a Nested pointer chain. -EXPORT int access_nested(const Nested *n_ptr) { +EXPORT int32_t access_nested(const Nested *n_ptr) { // Edge case: `n_ptr == NULL` (i.e. first Nested is None). if (!n_ptr) { return 0; } @@ -41,10 +42,10 @@ EXPORT int access_nested(const Nested *n_ptr) { /* Test: test_access_static */ typedef struct Static { - int value; + int32_t value; struct Static *recurse; } Static; -EXPORT int access_static(const Static *s_ptr) { +EXPORT int32_t access_static(const Static *s_ptr) { return s_ptr->recurse->recurse->value; } diff --git a/src/tools/miri/tests/native-lib/ptr_write_access.c b/src/tools/miri/tests/native-lib/ptr_write_access.c index 96fe413c0d8c..fd8b005499c7 100644 --- a/src/tools/miri/tests/native-lib/ptr_write_access.c +++ b/src/tools/miri/tests/native-lib/ptr_write_access.c @@ -6,19 +6,19 @@ /* Test: test_increment_int */ -EXPORT void increment_int(int *ptr) { +EXPORT void increment_int(int32_t *ptr) { *ptr += 1; } /* Test: test_init_int */ -EXPORT void init_int(int *ptr, int val) { +EXPORT void init_int(int32_t *ptr, int32_t val) { *ptr = val; } /* Test: test_init_array */ -EXPORT void init_array(int *array, size_t len, int val) { +EXPORT void init_array(int32_t *array, size_t len, int32_t val) { for (size_t i = 0; i < len; i++) { array[i] = val; } @@ -27,28 +27,28 @@ EXPORT void init_array(int *array, size_t len, int val) { /* Test: test_init_static_inner */ typedef struct SyncPtr { - int *ptr; + int32_t *ptr; } SyncPtr; -EXPORT void init_static_inner(const SyncPtr *s_ptr, int val) { +EXPORT void init_static_inner(const SyncPtr *s_ptr, int32_t val) { *(s_ptr->ptr) = val; } /* Tests: test_exposed, test_pass_dangling */ -EXPORT void ignore_ptr(__attribute__((unused)) const int *ptr) { +EXPORT void ignore_ptr(__attribute__((unused)) const int32_t *ptr) { return; } /* Test: test_expose_int */ -EXPORT void expose_int(const int *int_ptr, const int **pptr) { +EXPORT void expose_int(const int32_t *int_ptr, const int32_t **pptr) { *pptr = int_ptr; } /* Test: test_swap_ptr */ -EXPORT void swap_ptr(const int **pptr0, const int **pptr1) { - const int *tmp = *pptr0; +EXPORT void swap_ptr(const int32_t **pptr0, const int32_t **pptr1) { + const int32_t *tmp = *pptr0; *pptr0 = *pptr1; *pptr1 = tmp; } @@ -56,54 +56,54 @@ EXPORT void swap_ptr(const int **pptr0, const int **pptr1) { /* Test: test_swap_ptr_tuple */ typedef struct Tuple { - int *ptr0; - int *ptr1; + int32_t *ptr0; + int32_t *ptr1; } Tuple; EXPORT void swap_ptr_tuple(Tuple *t_ptr) { - int *tmp = t_ptr->ptr0; + int32_t *tmp = t_ptr->ptr0; t_ptr->ptr0 = t_ptr->ptr1; t_ptr->ptr1 = tmp; } /* Test: test_overwrite_dangling */ -EXPORT void overwrite_ptr(const int **pptr) { +EXPORT void overwrite_ptr(const int32_t **pptr) { *pptr = NULL; } /* Test: test_swap_ptr_triple_dangling */ typedef struct Triple { - int *ptr0; - int *ptr1; - int *ptr2; + int32_t *ptr0; + int32_t *ptr1; + int32_t *ptr2; } Triple; EXPORT void swap_ptr_triple_dangling(Triple *t_ptr) { - int *tmp = t_ptr->ptr0; + int32_t *tmp = t_ptr->ptr0; t_ptr->ptr0 = t_ptr->ptr2; t_ptr->ptr2 = tmp; } -EXPORT const int *return_ptr(const int *ptr) { +EXPORT const int32_t *return_ptr(const int32_t *ptr) { return ptr; } /* Test: test_pass_ptr_as_int */ -EXPORT void pass_ptr_as_int(uintptr_t ptr, int set_to_val) { - *(int*)ptr = set_to_val; +EXPORT void pass_ptr_as_int(uintptr_t ptr, int32_t set_to_val) { + *(int32_t*)ptr = set_to_val; } /* Test: test_pass_ptr_via_previously_shared_mem */ -int** shared_place; +int32_t** shared_place; -EXPORT void set_shared_mem(int** ptr) { +EXPORT void set_shared_mem(int32_t** ptr) { shared_place = ptr; } -EXPORT void init_ptr_stored_in_shared_mem(int val) { +EXPORT void init_ptr_stored_in_shared_mem(int32_t val) { **shared_place = val; } diff --git a/src/tools/miri/tests/native-lib/scalar_arguments.c b/src/tools/miri/tests/native-lib/scalar_arguments.c index 6da730a49872..acccf06f3df2 100644 --- a/src/tools/miri/tests/native-lib/scalar_arguments.c +++ b/src/tools/miri/tests/native-lib/scalar_arguments.c @@ -1,9 +1,10 @@ #include +#include // See comments in build_native_lib() #define EXPORT __attribute__((visibility("default"))) -EXPORT int add_one_int(int x) { +EXPORT int32_t add_one_int(int32_t x) { return 2 + x; } @@ -13,23 +14,23 @@ EXPORT void printer(void) { // function with many arguments, to test functionality when some args are stored // on the stack -EXPORT int test_stack_spill(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l) { +EXPORT int32_t test_stack_spill(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f, int32_t g, int32_t h, int32_t i, int32_t j, int32_t k, int32_t l) { return a+b+c+d+e+f+g+h+i+j+k+l; } -EXPORT unsigned int get_unsigned_int(void) { +EXPORT uint32_t get_unsigned_int(void) { return -10; } -EXPORT short add_int16(short x) { +EXPORT short add_int16(int16_t x) { return x + 3; } -EXPORT long add_short_to_long(short x, long y) { +EXPORT long add_short_to_long(int16_t x, int64_t y) { return x + y; } // To test that functions not marked with EXPORT cannot be called by Miri. -int not_exported(void) { +int32_t not_exported(void) { return 0; } From 476b0980f22f4a4de2102f2994da39600fc4546d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Feb 2025 16:30:59 +0100 Subject: [PATCH 465/991] adjust Layout debug printing to match the internal field names --- compiler/rustc_abi/src/lib.rs | 2 +- tests/ui/abi/c-zst.aarch64-darwin.stderr | 4 +- tests/ui/abi/c-zst.powerpc-linux.stderr | 4 +- tests/ui/abi/c-zst.s390x-linux.stderr | 4 +- tests/ui/abi/c-zst.sparc64-linux.stderr | 4 +- tests/ui/abi/c-zst.x86_64-linux.stderr | 4 +- .../ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 4 +- tests/ui/abi/debug.stderr | 48 +++++++++---------- tests/ui/abi/sysv64-zst.stderr | 4 +- tests/ui/layout/debug.stderr | 36 +++++++------- tests/ui/layout/hexagon-enum.stderr | 20 ++++---- ...-scalarpair-payload-might-be-uninit.stderr | 34 ++++++------- .../issue-96185-overaligned-enum.stderr | 12 ++--- tests/ui/layout/thumb-enum.stderr | 20 ++++---- .../layout/zero-sized-array-enum-niche.stderr | 26 +++++----- ...-variants.aarch64-unknown-linux-gnu.stderr | 16 +++---- ...-c-dead-variants.armebv7r-none-eabi.stderr | 16 +++---- ...-dead-variants.i686-pc-windows-msvc.stderr | 16 +++---- ...d-variants.x86_64-unknown-linux-gnu.stderr | 16 +++---- tests/ui/repr/repr-c-int-dead-variants.stderr | 16 +++---- .../type/pattern_types/range_patterns.stderr | 18 +++---- 21 files changed, 162 insertions(+), 162 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 81e4e255f379..b91dedfe2005 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1812,7 +1812,7 @@ where f.debug_struct("Layout") .field("size", size) .field("align", align) - .field("abi", backend_repr) + .field("backend_repr", backend_repr) .field("fields", fields) .field("largest_niche", largest_niche) .field("uninhabited", uninhabited) diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index 57cc48aa9cf4..48fa2bf29bc4 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -38,7 +38,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index 673801767300..bfdf94c99007 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index 673801767300..bfdf94c99007 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index 673801767300..bfdf94c99007 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index 57cc48aa9cf4..48fa2bf29bc4 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -38,7 +38,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index 673801767300..bfdf94c99007 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index 5f73ff7d6bd5..2239ba0e5880 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(test) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -48,7 +48,7 @@ error: fn_abi_of(test) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -107,7 +107,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -155,7 +155,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -205,7 +205,7 @@ error: fn_abi_of(test_generic) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Pointer( AddressSpace( @@ -245,7 +245,7 @@ error: fn_abi_of(test_generic) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -292,7 +292,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -331,7 +331,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -366,7 +366,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -405,7 +405,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -446,7 +446,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Array { @@ -486,7 +486,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -521,7 +521,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Array { @@ -561,7 +561,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -602,7 +602,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Float( F32, @@ -640,7 +640,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -675,7 +675,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -714,7 +714,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -755,7 +755,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -794,7 +794,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -829,7 +829,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -868,7 +868,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -923,7 +923,7 @@ error: fn_abi_of(assoc_test) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Pointer( AddressSpace( @@ -975,7 +975,7 @@ error: fn_abi_of(assoc_test) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index ec85030c1068..59d7b0044179 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -38,7 +38,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 07cad7766920..80b35ff6ad49 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -10,7 +10,7 @@ error: layout_of(E) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: layout_of(E) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -71,7 +71,7 @@ error: layout_of(E) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -112,7 +112,7 @@ error: layout_of(S) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -160,7 +160,7 @@ error: layout_of(U) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -186,7 +186,7 @@ error: layout_of(Result) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -238,7 +238,7 @@ error: layout_of(Result) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -277,7 +277,7 @@ error: layout_of(Result) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -327,7 +327,7 @@ error: layout_of(i32) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -357,7 +357,7 @@ error: layout_of(V) = Layout { abi: Align(2 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -383,7 +383,7 @@ error: layout_of(W) = Layout { abi: Align(2 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -409,7 +409,7 @@ error: layout_of(Y) = Layout { abi: Align(2 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -435,7 +435,7 @@ error: layout_of(P1) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -461,7 +461,7 @@ error: layout_of(P2) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -487,7 +487,7 @@ error: layout_of(P3) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -513,7 +513,7 @@ error: layout_of(P4) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -539,7 +539,7 @@ error: layout_of(P5) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Union { value: Int( I8, @@ -570,7 +570,7 @@ error: layout_of(MaybeUninit) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Union { value: Int( I8, diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 90c06ba1f834..1cd4efbcdad3 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -4,7 +4,7 @@ error: layout_of(A) = Layout { abi: Align(1 bytes), pref: Align(1 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -49,7 +49,7 @@ error: layout_of(A) = Layout { abi: Align(1 bytes), pref: Align(1 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -82,7 +82,7 @@ error: layout_of(B) = Layout { abi: Align(1 bytes), pref: Align(1 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -127,7 +127,7 @@ error: layout_of(B) = Layout { abi: Align(1 bytes), pref: Align(1 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -160,7 +160,7 @@ error: layout_of(C) = Layout { abi: Align(2 bytes), pref: Align(2 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I16, @@ -205,7 +205,7 @@ error: layout_of(C) = Layout { abi: Align(2 bytes), pref: Align(2 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -238,7 +238,7 @@ error: layout_of(P) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -283,7 +283,7 @@ error: layout_of(P) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -316,7 +316,7 @@ error: layout_of(T) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -361,7 +361,7 @@ error: layout_of(T) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index 3bdb9c5c143e..ef7f0cd2d1c3 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -4,7 +4,7 @@ error: layout_of(MissingPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -55,7 +55,7 @@ error: layout_of(MissingPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -93,7 +93,7 @@ error: layout_of(MissingPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -126,7 +126,7 @@ error: layout_of(CommonPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -178,7 +178,7 @@ error: layout_of(CommonPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -217,7 +217,7 @@ error: layout_of(CommonPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -267,7 +267,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -318,7 +318,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -356,7 +356,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -405,7 +405,7 @@ error: layout_of(NicheFirst) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -460,7 +460,7 @@ error: layout_of(NicheFirst) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -510,7 +510,7 @@ error: layout_of(NicheFirst) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -532,7 +532,7 @@ error: layout_of(NicheFirst) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -565,7 +565,7 @@ error: layout_of(NicheSecond) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -620,7 +620,7 @@ error: layout_of(NicheSecond) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -670,7 +670,7 @@ error: layout_of(NicheSecond) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -692,7 +692,7 @@ error: layout_of(NicheSecond) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 1d4e44364482..a9081afc5094 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -4,7 +4,7 @@ error: layout_of(Aligned1) = Layout { abi: Align(8 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -43,7 +43,7 @@ error: layout_of(Aligned1) = Layout { abi: Align(8 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -67,7 +67,7 @@ error: layout_of(Aligned1) = Layout { abi: Align(8 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -104,7 +104,7 @@ error: layout_of(Aligned2) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -149,7 +149,7 @@ error: layout_of(Aligned2) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -173,7 +173,7 @@ error: layout_of(Aligned2) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 0c3433185647..c1defe720db9 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -4,7 +4,7 @@ error: layout_of(A) = Layout { abi: Align(1 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -49,7 +49,7 @@ error: layout_of(A) = Layout { abi: Align(1 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -82,7 +82,7 @@ error: layout_of(B) = Layout { abi: Align(1 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -127,7 +127,7 @@ error: layout_of(B) = Layout { abi: Align(1 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -160,7 +160,7 @@ error: layout_of(C) = Layout { abi: Align(2 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I16, @@ -205,7 +205,7 @@ error: layout_of(C) = Layout { abi: Align(2 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -238,7 +238,7 @@ error: layout_of(P) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -283,7 +283,7 @@ error: layout_of(P) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -316,7 +316,7 @@ error: layout_of(T) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -361,7 +361,7 @@ error: layout_of(T) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index 33d2eede2209..1ba184bdacef 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -4,7 +4,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -43,7 +43,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -69,7 +69,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -115,7 +115,7 @@ error: layout_of(MultipleAlignments) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -154,7 +154,7 @@ error: layout_of(MultipleAlignments) = Layout { abi: Align(2 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -180,7 +180,7 @@ error: layout_of(MultipleAlignments) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -206,7 +206,7 @@ error: layout_of(MultipleAlignments) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -252,7 +252,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -291,7 +291,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -317,7 +317,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -363,7 +363,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -406,7 +406,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -432,7 +432,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 204db30786ee..5ae5aeb7d2c3 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 1fab00bf50c4..a325cb8d71ff 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 204db30786ee..5ae5aeb7d2c3 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 204db30786ee..5ae5aeb7d2c3 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index f852212deb90..f63574182c25 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -4,7 +4,7 @@ error: layout_of(UnivariantU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -49,7 +49,7 @@ error: layout_of(UnivariantU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -92,7 +92,7 @@ error: layout_of(TwoVariantsU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -143,7 +143,7 @@ error: layout_of(TwoVariantsU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -181,7 +181,7 @@ error: layout_of(TwoVariantsU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 690592ba0b8d..7eda50fd1211 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -4,7 +4,7 @@ error: layout_of(NonZero) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -50,7 +50,7 @@ error: layout_of((u32) is 1..=) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -89,7 +89,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -129,7 +129,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -151,7 +151,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -203,7 +203,7 @@ error: layout_of(Option>) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -243,7 +243,7 @@ error: layout_of(Option>) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -265,7 +265,7 @@ error: layout_of(Option>) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -317,7 +317,7 @@ error: layout_of(NonZeroU32New) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, From 6563437773dcf87a71c9a41a8aec90d23efeb4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 21 Feb 2025 13:02:41 +0100 Subject: [PATCH 466/991] Create the `OptimizedDist` tool with a macro --- src/bootstrap/src/core/build_steps/tool.rs | 40 +--------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 39acb646dff4..27cc49d3be7c 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -445,51 +445,13 @@ bootstrap_tool!( WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization"; UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator"; FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump"; + OptimizedDist, "src/tools/opt-dist", "opt-dist", submodules = &["src/tools/rustc-perf"]; ); /// These are the submodules that are required for rustbook to work due to /// depending on mdbook plugins. pub static SUBMODULES_FOR_RUSTBOOK: &[&str] = &["src/doc/book", "src/doc/reference"]; -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct OptimizedDist { - pub compiler: Compiler, - pub target: TargetSelection, -} - -impl Step for OptimizedDist { - type Output = ToolBuildResult; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/opt-dist") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(OptimizedDist { - compiler: run.builder.compiler(0, run.builder.config.build), - target: run.target, - }); - } - - fn run(self, builder: &Builder<'_>) -> ToolBuildResult { - // We need to ensure the rustc-perf submodule is initialized when building opt-dist since - // the tool requires it to be in place to run. - builder.require_submodule("src/tools/rustc-perf", None); - - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, - tool: "opt-dist", - mode: Mode::ToolBootstrap, - path: "src/tools/opt-dist", - source_type: SourceType::InTree, - extra_features: Vec::new(), - allow_features: "", - cargo_args: Vec::new(), - }) - } -} - /// The [rustc-perf](https://github.com/rust-lang/rustc-perf) benchmark suite, which is added /// as a submodule at `src/tools/rustc-perf`. #[derive(Debug, Clone, Hash, PartialEq, Eq)] From 96a91975f1a2695bba3ed633f825062be748007b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 21 Feb 2025 13:20:32 +0100 Subject: [PATCH 467/991] Allow specifying that tools build a library, not a binary --- src/bootstrap/src/core/build_steps/tool.rs | 40 +++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 27cc49d3be7c..e401a0bdfc84 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -34,6 +34,12 @@ pub enum SourceType { Submodule, } +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub enum ToolArtifactKind { + Binary, + Library, +} + #[derive(Debug, Clone, Hash, PartialEq, Eq)] struct ToolBuild { compiler: Compiler, @@ -47,6 +53,8 @@ struct ToolBuild { allow_features: &'static str, /// Additional arguments to pass to the `cargo` invocation. cargo_args: Vec, + /// Whether the tool builds a binary or a library. + artifact_kind: ToolArtifactKind, } impl Builder<'_> { @@ -79,7 +87,7 @@ impl Builder<'_> { /// for using this type as `type Output = ToolBuildResult;` #[derive(Clone)] pub struct ToolBuildResult { - /// Executable path of the corresponding tool that was built. + /// Artifact path of the corresponding tool that was built. pub tool_path: PathBuf, /// Compiler used to build the tool. For non-`ToolRustc` tools this is equal to `target_compiler`. /// For `ToolRustc` this is one stage before of the `target_compiler`. @@ -179,8 +187,14 @@ impl Step for ToolBuild { if tool == "tidy" { tool = "rust-tidy"; } - let tool_path = - copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool); + let tool_path = match self.artifact_kind { + ToolArtifactKind::Binary => { + copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool) + } + ToolArtifactKind::Library => builder + .cargo_out(self.compiler, self.mode, self.target) + .join(format!("lib{tool}.rlib")), + }; ToolBuildResult { tool_path, build_compiler: self.compiler, target_compiler } } @@ -330,6 +344,7 @@ macro_rules! bootstrap_tool { $(,is_unstable_tool = $unstable:expr)* $(,allow_features = $allow_features:expr)? $(,submodules = $submodules:expr)? + $(,artifact_kind = $artifact_kind:expr)? ; )+) => { #[derive(PartialEq, Eq, Clone)] @@ -389,6 +404,7 @@ macro_rules! bootstrap_tool { builder.require_submodule(submodule, None); } )* + builder.ensure(ToolBuild { compiler: self.compiler, target: self.target, @@ -407,7 +423,12 @@ macro_rules! bootstrap_tool { }, extra_features: vec![], allow_features: concat!($($allow_features)*), - cargo_args: vec![] + cargo_args: vec![], + artifact_kind: if false $(|| $artifact_kind == ToolArtifactKind::Library)* { + ToolArtifactKind::Library + } else { + ToolArtifactKind::Binary + } }) } } @@ -491,6 +512,7 @@ impl Step for RustcPerf { // Only build the collector package, which is used for benchmarking through // a CLI. cargo_args: vec!["-p".to_string(), "collector".to_string()], + artifact_kind: ToolArtifactKind::Binary, }; let res = builder.ensure(tool.clone()); // We also need to symlink the `rustc-fake` binary to the corresponding directory, @@ -548,6 +570,7 @@ impl Step for ErrorIndex { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } @@ -583,6 +606,7 @@ impl Step for RemoteTestServer { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } @@ -687,6 +711,7 @@ impl Step for Rustdoc { extra_features, allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }); // don't create a stage0-sysroot/bin directory. @@ -741,6 +766,7 @@ impl Step for Cargo { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } @@ -789,6 +815,7 @@ impl Step for LldWrapper { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }); let libdir_bin = builder.sysroot_target_bindir(self.target_compiler, target); @@ -849,6 +876,7 @@ impl Step for RustAnalyzer { source_type: SourceType::InTree, allow_features: RustAnalyzer::ALLOW_FEATURES, cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } @@ -893,6 +921,7 @@ impl Step for RustAnalyzerProcMacroSrv { source_type: SourceType::InTree, allow_features: RustAnalyzer::ALLOW_FEATURES, cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }); // Copy `rust-analyzer-proc-macro-srv` to `/libexec/` @@ -947,6 +976,7 @@ impl Step for LlvmBitcodeLinker { extra_features: self.extra_features, allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }); if tool_result.target_compiler.stage > 0 { @@ -1126,6 +1156,7 @@ fn run_tool_build_step( source_type: SourceType::InTree, allow_features: "", cargo_args: vec![], + artifact_kind: ToolArtifactKind::Binary, }); // FIXME: This should just be an if-let-chain, but those are unstable. @@ -1204,6 +1235,7 @@ impl Step for TestFloatParse { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } From 807f6ffa91268f72f738b2b1776a19e8a0a025f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 21 Feb 2025 13:36:29 +0100 Subject: [PATCH 468/991] Implement `RunMakeSupport` tool using the `bootstrap_tool!` macro --- src/bootstrap/src/core/build_steps/test.rs | 53 ---------------------- src/bootstrap/src/core/build_steps/tool.rs | 1 + 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 709711d9d34c..efdac694aee2 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1230,59 +1230,6 @@ macro_rules! test { }; } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct RunMakeSupport { - pub compiler: Compiler, - pub target: TargetSelection, -} - -impl Step for RunMakeSupport { - type Output = PathBuf; - const DEFAULT: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.never() - } - - fn make_run(run: RunConfig<'_>) { - let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); - run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() }); - } - - /// Builds run-make-support and returns the path to the resulting rlib. - fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.ensure(compile::Std::new(self.compiler, self.target)); - - let cargo = tool::prepare_tool_cargo( - builder, - self.compiler, - Mode::ToolStd, - self.target, - Kind::Build, - "src/tools/run-make-support", - SourceType::InTree, - &[], - ); - - let _guard = builder.msg_tool( - Kind::Build, - Mode::ToolStd, - "run-make-support", - self.compiler.stage, - &self.compiler.host, - &self.target, - ); - cargo.into_cmd().run(builder); - - let lib_name = "librun_make_support.rlib"; - let lib = builder.tools_dir(self.compiler).join(lib_name); - - let cargo_out = builder.cargo_out(self.compiler, Mode::ToolStd, self.target).join(lib_name); - builder.copy_link(&cargo_out, &lib); - lib - } -} - /// Runs `cargo test` on the `src/tools/run-make-support` crate. /// That crate is used by run-make tests. #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index e401a0bdfc84..0149709f5c51 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -467,6 +467,7 @@ bootstrap_tool!( UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator"; FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump"; OptimizedDist, "src/tools/opt-dist", "opt-dist", submodules = &["src/tools/rustc-perf"]; + RunMakeSupport, "src/tools/run-make-support", "run_make_support", artifact_kind = ToolArtifactKind::Library; ); /// These are the submodules that are required for rustbook to work due to From 4af94f842d37c15a0428e50c10fc2293f3b7a9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 21 Feb 2025 13:36:45 +0100 Subject: [PATCH 469/991] Implement `RunMake` test suite using the `test!` macro --- src/bootstrap/src/core/build_steps/test.rs | 38 +++------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index efdac694aee2..79be42cdd2f2 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1381,40 +1381,7 @@ test!(Pretty { only_hosts: true, }); -/// Special-handling is needed for `run-make`, so don't use `test!` for defining `RunMake` -/// tests. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct RunMake { - pub compiler: Compiler, - pub target: TargetSelection, -} - -impl Step for RunMake { - type Output = (); - const DEFAULT: bool = true; - const ONLY_HOSTS: bool = false; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.suite_path("tests/run-make") - } - - fn make_run(run: RunConfig<'_>) { - let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); - run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() }); - run.builder.ensure(RunMake { compiler, target: run.target }); - } - - fn run(self, builder: &Builder<'_>) { - builder.ensure(Compiletest { - compiler: self.compiler, - target: self.target, - mode: "run-make", - suite: "run-make", - path: "tests/run-make", - compare_mode: None, - }); - } -} +test!(RunMake { path: "tests/run-make", mode: "run-make", suite: "run-make", default: true }); test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly", default: true }); @@ -1657,6 +1624,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the host: target, }); } + if suite == "run-make" { + builder.tool_exe(Tool::RunMakeSupport); + } // Also provide `rust_test_helpers` for the host. builder.ensure(TestHelpers { target: compiler.host }); From dc04c0ca48c7285d74a0489354ed7d013dc25799 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Feb 2025 16:51:53 +0100 Subject: [PATCH 470/991] add test --- tests/rustdoc-ui/target-feature-stability.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/rustdoc-ui/target-feature-stability.rs diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs new file mode 100644 index 000000000000..4ade9690310e --- /dev/null +++ b/tests/rustdoc-ui/target-feature-stability.rs @@ -0,0 +1,18 @@ +//! This is a regression test for , ensuring +//! that we can use the `neon` target feature on ARM-32 targets in rustdoc despite there +//! being a "forbidden" feature of the same name for aarch64, and rustdoc merging the +//! target features of all targets. +//@ check-pass +//@ compile-flags: --target armv7-unknown-linux-gnueabihf + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![feature(arm_target_feature)] +#![no_core] + +#[lang = "sized"] +pub trait Sized {} + +// `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`. +#[target_feature(enable = "fp-armv8")] +pub fn fun() {} From c86a7ef793b2186e15a74ab37b642f8859fec0f3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Feb 2025 17:15:17 +0100 Subject: [PATCH 471/991] Fully qualify `Result` in generated doctest code --- src/librustdoc/doctest/make.rs | 2 +- src/librustdoc/doctest/tests.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 4792bc525a59..9935074877bc 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -208,7 +208,7 @@ impl DocTestBuilder { let (main_pre, main_post) = if returns_result { ( format!( - "fn main() {{ {inner_attr}fn {inner_fn_name}() -> Result<(), impl core::fmt::Debug> {{\n", + "fn main() {{ {inner_attr}fn {inner_fn_name}() -> core::result::Result<(), impl core::fmt::Debug> {{\n", ), format!("\n}} {inner_fn_name}().unwrap() }}"), ) diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index fa6cca3681be..e2b964bf5af5 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -316,7 +316,7 @@ let mut input = String::new(); io::stdin().read_line(&mut input)?; Ok::<(), io:Error>(())"; let expected = "#![allow(unused)] -fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> { +fn main() { fn _inner() -> core::result::Result<(), impl core::fmt::Debug> { use std::io; let mut input = String::new(); io::stdin().read_line(&mut input)?; From aac65f562b3e9351d4a4336c270ce13c130de467 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Feb 2025 16:29:07 +0100 Subject: [PATCH 472/991] =?UTF-8?q?rename=20BackendRepr::Vector=20?= =?UTF-8?q?=E2=86=92=20SimdVector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/rustc_abi/src/callconv.rs | 2 +- compiler/rustc_abi/src/layout.rs | 12 ++++-- compiler/rustc_abi/src/layout/ty.rs | 2 +- compiler/rustc_abi/src/lib.rs | 28 ++++++------- .../src/abi/pass_mode.rs | 4 +- .../src/intrinsics/mod.rs | 2 +- .../src/value_and_place.rs | 8 ++-- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 2 +- compiler/rustc_codegen_gcc/src/type_of.rs | 10 ++--- compiler/rustc_codegen_llvm/src/asm.rs | 39 ++++++++++--------- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- compiler/rustc_codegen_llvm/src/type_of.rs | 10 ++--- .../rustc_codegen_ssa/src/mir/naked_asm.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 6 +-- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- .../src/interpret/validity.rs | 2 +- .../src/util/check_validity_requirement.rs | 2 +- compiler/rustc_mir_transform/src/gvn.rs | 2 +- .../src/mono_checks/abi_check.rs | 2 +- .../rustc_smir/src/rustc_smir/convert/abi.rs | 2 +- .../rustc_target/src/callconv/loongarch.rs | 4 +- compiler/rustc_target/src/callconv/mod.rs | 6 +-- compiler/rustc_target/src/callconv/riscv.rs | 4 +- compiler/rustc_target/src/callconv/s390x.rs | 4 +- compiler/rustc_target/src/callconv/x86.rs | 2 +- compiler/rustc_target/src/callconv/x86_64.rs | 2 +- .../rustc_target/src/callconv/x86_win64.rs | 2 +- compiler/rustc_target/src/callconv/xtensa.rs | 2 +- compiler/rustc_ty_utils/src/abi.rs | 2 +- compiler/rustc_ty_utils/src/layout.rs | 2 +- .../rustc_ty_utils/src/layout/invariant.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/layout.rs | 2 +- 32 files changed, 92 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs index 4529ab8058e9..a21e1aee9b08 100644 --- a/compiler/rustc_abi/src/callconv.rs +++ b/compiler/rustc_abi/src/callconv.rs @@ -74,7 +74,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size })) } - BackendRepr::Vector { .. } => { + BackendRepr::SimdVector { .. } => { assert!(!self.is_zst()); Ok(HomogeneousAggregate::Homogeneous(Reg { kind: RegKind::Vector, diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 3f83787ea376..d3ae6a29f10f 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -386,13 +386,15 @@ impl LayoutCalculator { BackendRepr::Memory { sized: true } } // Vectors require at least element alignment, else disable the opt - BackendRepr::Vector { element, count: _ } if element.align(dl).abi > align.abi => { + BackendRepr::SimdVector { element, count: _ } + if element.align(dl).abi > align.abi => + { BackendRepr::Memory { sized: true } } // the alignment tests passed and we can use this BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..) - | BackendRepr::Vector { .. } + | BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => repr, }, }; @@ -464,7 +466,7 @@ impl LayoutCalculator { hide_niches(a); hide_niches(b); } - BackendRepr::Vector { element, count: _ } => hide_niches(element), + BackendRepr::SimdVector { element, count: _ } => hide_niches(element), BackendRepr::Memory { sized: _ } => {} } st.largest_niche = None; @@ -1314,7 +1316,9 @@ impl LayoutCalculator { match field.backend_repr { // For plain scalars, or vectors of them, we can't unpack // newtypes for `#[repr(C)]`, as that affects C ABIs. - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } if optimize_abi => { + BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } + if optimize_abi => + { abi = field.backend_repr; } // But scalar pairs are Rust-specific and get diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 221e990ae863..03f3f043c218 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -219,7 +219,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { C: HasDataLayout, { match self.backend_repr { - BackendRepr::Vector { .. } => self.size == expected_size, + BackendRepr::SimdVector { .. } => self.size == expected_size, BackendRepr::Memory { .. } => { if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 { self.field(cx, 0).is_single_vector_element(cx, expected_size) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 81e4e255f379..2197dd68eaf6 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1410,7 +1410,7 @@ impl AddressSpace { pub enum BackendRepr { Scalar(Scalar), ScalarPair(Scalar, Scalar), - Vector { + SimdVector { element: Scalar, count: u64, }, @@ -1426,9 +1426,9 @@ impl BackendRepr { #[inline] pub fn is_unsized(&self) -> bool { match *self { - BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => { - false - } + BackendRepr::Scalar(_) + | BackendRepr::ScalarPair(..) + | BackendRepr::SimdVector { .. } => false, BackendRepr::Memory { sized } => !sized, } } @@ -1467,7 +1467,7 @@ impl BackendRepr { BackendRepr::Scalar(s) => Some(s.align(cx).abi), BackendRepr::ScalarPair(s1, s2) => Some(s1.align(cx).max(s2.align(cx)).abi), // The align of a Vector can vary in surprising ways - BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => None, + BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => None, } } @@ -1489,7 +1489,7 @@ impl BackendRepr { Some(size) } // The size of a Vector can vary in surprising ways - BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => None, + BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => None, } } @@ -1500,8 +1500,8 @@ impl BackendRepr { BackendRepr::ScalarPair(s1, s2) => { BackendRepr::ScalarPair(s1.to_union(), s2.to_union()) } - BackendRepr::Vector { element, count } => { - BackendRepr::Vector { element: element.to_union(), count } + BackendRepr::SimdVector { element, count } => { + BackendRepr::SimdVector { element: element.to_union(), count } } BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true }, } @@ -1513,8 +1513,8 @@ impl BackendRepr { // We do *not* ignore the sign since it matters for some ABIs (e.g. s390x). (BackendRepr::Scalar(l), BackendRepr::Scalar(r)) => l.primitive() == r.primitive(), ( - BackendRepr::Vector { element: element_l, count: count_l }, - BackendRepr::Vector { element: element_r, count: count_r }, + BackendRepr::SimdVector { element: element_l, count: count_l }, + BackendRepr::SimdVector { element: element_r, count: count_r }, ) => element_l.primitive() == element_r.primitive() && count_l == count_r, (BackendRepr::ScalarPair(l1, l2), BackendRepr::ScalarPair(r1, r2)) => { l1.primitive() == r1.primitive() && l2.primitive() == r2.primitive() @@ -1735,7 +1735,7 @@ impl LayoutData { /// Returns `true` if this is an aggregate type (including a ScalarPair!) pub fn is_aggregate(&self) -> bool { match self.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => false, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true, } } @@ -1877,9 +1877,9 @@ impl LayoutData { /// non-trivial alignment constraints. You probably want to use `is_1zst` instead. pub fn is_zst(&self) -> bool { match self.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => { - false - } + BackendRepr::Scalar(_) + | BackendRepr::ScalarPair(..) + | BackendRepr::SimdVector { .. } => false, BackendRepr::Memory { sized } => sized && self.size.bytes() == 0, } } diff --git a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs index b28c4c9539ce..06d89bc9ea7d 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs @@ -84,7 +84,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { AbiParam::new(scalar_to_clif_type(tcx, scalar)), attrs )], - BackendRepr::Vector { .. } => { + BackendRepr::SimdVector { .. } => { let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout); smallvec![AbiParam::new(vector_ty)] } @@ -135,7 +135,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { BackendRepr::Scalar(scalar) => { (None, vec![AbiParam::new(scalar_to_clif_type(tcx, scalar))]) } - BackendRepr::Vector { .. } => { + BackendRepr::SimdVector { .. } => { let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout); (None, vec![AbiParam::new(vector_ty)]) } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 4d9bed8652cb..6735ae024d1c 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -53,7 +53,7 @@ fn report_atomic_type_validation_error<'tcx>( pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> Type { let (element, count) = match layout.backend_repr { - BackendRepr::Vector { element, count } => (element, count), + BackendRepr::SimdVector { element, count } => (element, count), _ => unreachable!(), }; diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 1b3f86c8405d..cc739fefcd06 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -173,9 +173,11 @@ impl<'tcx> CValue<'tcx> { CValueInner::ByRef(ptr, None) => { let clif_ty = match layout.backend_repr { BackendRepr::Scalar(scalar) => scalar_to_clif_type(fx.tcx, scalar), - BackendRepr::Vector { element, count } => scalar_to_clif_type(fx.tcx, element) - .by(u32::try_from(count).unwrap()) - .unwrap(), + BackendRepr::SimdVector { element, count } => { + scalar_to_clif_type(fx.tcx, element) + .by(u32::try_from(count).unwrap()) + .unwrap() + } _ => unreachable!("{:?}", layout.ty), }; let mut flags = MemFlags::new(); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index f8672c072999..f38622074f18 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -312,7 +312,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Vector { .. } => false, + SimdVector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index bac4fc51300a..ae98b3d0b56e 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -63,7 +63,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( ) -> Type<'gcc> { match layout.backend_repr { BackendRepr::Scalar(_) => bug!("handled elsewhere"), - BackendRepr::Vector { ref element, count } => { + BackendRepr::SimdVector { ref element, count } => { let element = layout.scalar_gcc_type_at(cx, element, Size::ZERO); let element = // NOTE: gcc doesn't allow pointer types in vectors. @@ -178,7 +178,7 @@ pub trait LayoutGccExt<'tcx> { impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, + BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -186,9 +186,9 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { - false - } + BackendRepr::Scalar(_) + | BackendRepr::SimdVector { .. } + | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index be5673eddf93..e8a697431571 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -939,9 +939,10 @@ fn llvm_fixup_input<'ll, 'tcx>( } bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0)) } - (AArch64(AArch64InlineAsmRegClass::vreg_low16), BackendRepr::Vector { element, count }) - if layout.size.bytes() == 8 => - { + ( + AArch64(AArch64InlineAsmRegClass::vreg_low16), + BackendRepr::SimdVector { element, count }, + ) if layout.size.bytes() == 8 => { let elem_ty = llvm_asm_scalar_type(bx.cx, element); let vec_ty = bx.cx.type_vector(elem_ty, count); let indices: Vec<_> = (0..count * 2).map(|x| bx.const_i32(x as i32)).collect(); @@ -954,7 +955,7 @@ fn llvm_fixup_input<'ll, 'tcx>( } ( X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg), - BackendRepr::Vector { .. }, + BackendRepr::SimdVector { .. }, ) if layout.size.bytes() == 64 => bx.bitcast(value, bx.cx.type_vector(bx.cx.type_f64(), 8)), ( X86( @@ -989,7 +990,7 @@ fn llvm_fixup_input<'ll, 'tcx>( | X86InlineAsmRegClass::ymm_reg | X86InlineAsmRegClass::zmm_reg, ), - BackendRepr::Vector { element, count: count @ (8 | 16) }, + BackendRepr::SimdVector { element, count: count @ (8 | 16) }, ) if element.primitive() == Primitive::Float(Float::F16) => { bx.bitcast(value, bx.type_vector(bx.type_i16(), count)) } @@ -1026,7 +1027,7 @@ fn llvm_fixup_input<'ll, 'tcx>( | ArmInlineAsmRegClass::qreg_low4 | ArmInlineAsmRegClass::qreg_low8, ), - BackendRepr::Vector { element, count: count @ (4 | 8) }, + BackendRepr::SimdVector { element, count: count @ (4 | 8) }, ) if element.primitive() == Primitive::Float(Float::F16) => { bx.bitcast(value, bx.type_vector(bx.type_i16(), count)) } @@ -1099,9 +1100,10 @@ fn llvm_fixup_output<'ll, 'tcx>( } value } - (AArch64(AArch64InlineAsmRegClass::vreg_low16), BackendRepr::Vector { element, count }) - if layout.size.bytes() == 8 => - { + ( + AArch64(AArch64InlineAsmRegClass::vreg_low16), + BackendRepr::SimdVector { element, count }, + ) if layout.size.bytes() == 8 => { let elem_ty = llvm_asm_scalar_type(bx.cx, element); let vec_ty = bx.cx.type_vector(elem_ty, count * 2); let indices: Vec<_> = (0..count).map(|x| bx.const_i32(x as i32)).collect(); @@ -1114,7 +1116,7 @@ fn llvm_fixup_output<'ll, 'tcx>( } ( X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg), - BackendRepr::Vector { .. }, + BackendRepr::SimdVector { .. }, ) if layout.size.bytes() == 64 => bx.bitcast(value, layout.llvm_type(bx.cx)), ( X86( @@ -1145,7 +1147,7 @@ fn llvm_fixup_output<'ll, 'tcx>( | X86InlineAsmRegClass::ymm_reg | X86InlineAsmRegClass::zmm_reg, ), - BackendRepr::Vector { element, count: count @ (8 | 16) }, + BackendRepr::SimdVector { element, count: count @ (8 | 16) }, ) if element.primitive() == Primitive::Float(Float::F16) => { bx.bitcast(value, bx.type_vector(bx.type_f16(), count)) } @@ -1182,7 +1184,7 @@ fn llvm_fixup_output<'ll, 'tcx>( | ArmInlineAsmRegClass::qreg_low4 | ArmInlineAsmRegClass::qreg_low8, ), - BackendRepr::Vector { element, count: count @ (4 | 8) }, + BackendRepr::SimdVector { element, count: count @ (4 | 8) }, ) if element.primitive() == Primitive::Float(Float::F16) => { bx.bitcast(value, bx.type_vector(bx.type_f16(), count)) } @@ -1243,9 +1245,10 @@ fn llvm_fixup_output_type<'ll, 'tcx>( let count = 16 / layout.size.bytes(); cx.type_vector(elem_ty, count) } - (AArch64(AArch64InlineAsmRegClass::vreg_low16), BackendRepr::Vector { element, count }) - if layout.size.bytes() == 8 => - { + ( + AArch64(AArch64InlineAsmRegClass::vreg_low16), + BackendRepr::SimdVector { element, count }, + ) if layout.size.bytes() == 8 => { let elem_ty = llvm_asm_scalar_type(cx, element); cx.type_vector(elem_ty, count * 2) } @@ -1256,7 +1259,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>( } ( X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg), - BackendRepr::Vector { .. }, + BackendRepr::SimdVector { .. }, ) if layout.size.bytes() == 64 => cx.type_vector(cx.type_f64(), 8), ( X86( @@ -1284,7 +1287,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>( | X86InlineAsmRegClass::ymm_reg | X86InlineAsmRegClass::zmm_reg, ), - BackendRepr::Vector { element, count: count @ (8 | 16) }, + BackendRepr::SimdVector { element, count: count @ (8 | 16) }, ) if element.primitive() == Primitive::Float(Float::F16) => { cx.type_vector(cx.type_i16(), count) } @@ -1321,7 +1324,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>( | ArmInlineAsmRegClass::qreg_low4 | ArmInlineAsmRegClass::qreg_low8, ), - BackendRepr::Vector { element, count: count @ (4 | 8) }, + BackendRepr::SimdVector { element, count: count @ (4 | 8) }, ) if element.primitive() == Primitive::Float(Float::F16) => { cx.type_vector(cx.type_i16(), count) } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 1169b9c067d7..0272667e2239 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -470,7 +470,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let layout = self.layout_of(tp_ty).layout; let use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Vector { .. } => false, + SimdVector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index ba01fbff3853..4e7096da502d 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -19,7 +19,7 @@ fn uncached_llvm_type<'a, 'tcx>( ) -> &'a Type { match layout.backend_repr { BackendRepr::Scalar(_) => bug!("handled elsewhere"), - BackendRepr::Vector { element, count } => { + BackendRepr::SimdVector { element, count } => { let element = layout.scalar_llvm_type_at(cx, element); return cx.type_vector(element, count); } @@ -171,7 +171,7 @@ pub(crate) trait LayoutLlvmExt<'tcx> { impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { fn is_llvm_immediate(&self) -> bool { match self.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, + BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -179,9 +179,9 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { fn is_llvm_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { - false - } + BackendRepr::Scalar(_) + | BackendRepr::SimdVector { .. } + | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 0593fb420c30..96d1ab018f60 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -349,7 +349,7 @@ fn wasm_type<'tcx>( PassMode::Direct(_) => { let direct_type = match arg_abi.layout.backend_repr { BackendRepr::Scalar(scalar) => wasm_primitive(scalar.primitive(), ptr_type), - BackendRepr::Vector { .. } => "v128", + BackendRepr::SimdVector { .. } => "v128", BackendRepr::Memory { .. } => { // FIXME: remove this branch once the wasm32-unknown-unknown ABI is fixed let _ = WasmCAbi::Legacy; diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 461cf1b8acda..4b33bdeadba4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -359,7 +359,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let offset = self.layout.fields.offset(i); if !bx.is_backend_ref(self.layout) && bx.is_backend_ref(field) { - if let BackendRepr::Vector { count, .. } = self.layout.backend_repr + if let BackendRepr::SimdVector { count, .. } = self.layout.backend_repr && let BackendRepr::Memory { sized: true } = field.backend_repr && count.is_power_of_two() { @@ -404,7 +404,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { } }; OperandValue::Immediate(match field.backend_repr { - BackendRepr::Vector { .. } => imm, + BackendRepr::SimdVector { .. } => imm, BackendRepr::Scalar(out_scalar) => { let Some(in_scalar) = in_scalar else { span_bug!( @@ -666,7 +666,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // However, some SIMD types do not actually use the vector ABI // (in particular, packed SIMD types do not). Ensure we exclude those. let layout = bx.layout_of(constant_ty); - if let BackendRepr::Vector { .. } = layout.backend_repr { + if let BackendRepr::SimdVector { .. } = layout.backend_repr { let (llval, ty) = self.immediate_const_vector(bx, constant); return OperandRef { val: OperandValue::Immediate(llval), diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index d24e48b37a46..67555d403320 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -1190,7 +1190,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { assert!(!self.cx.is_backend_scalar_pair(layout)); OperandValueKind::Immediate(match layout.backend_repr { abi::BackendRepr::Scalar(s) => s, - abi::BackendRepr::Vector { element, .. } => element, + abi::BackendRepr::SimdVector { element, .. } => element, x => span_bug!(self.mir.span, "Couldn't translate {x:?} as backend immediate"), }) } else if self.cx.is_backend_scalar_pair(layout) { diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 40dec0cb39e7..eb3f552cd278 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1296,7 +1296,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, self.visit_scalar(b, b_layout)?; } } - BackendRepr::Vector { .. } => { + BackendRepr::SimdVector { .. } => { // No checks here, we assume layout computation gets this right. // (This is harder to check since Miri does not represent these as `Immediate`. We // also cannot use field projections since this might be a newtype around a vector.) diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 6426bca2332d..d7e97f32bae9 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -117,7 +117,7 @@ fn check_validity_requirement_lax<'tcx>( BackendRepr::ScalarPair(s1, s2) => { scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2) } - BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s), + BackendRepr::SimdVector { element: s, count } => count == 0 || scalar_allows_raw_init(s), BackendRepr::Memory { .. } => true, // Fields are checked below. }; if !valid { diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 29521d427201..981dedd5b5c7 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1567,7 +1567,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { BackendRepr::ScalarPair(a, b) => { !a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx) } - BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => false, + BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index 4c8dd933317e..9f26da7d5c64 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -18,7 +18,7 @@ fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool { cast.prefix.iter().any(|r| r.is_some_and(|x| x.kind == RegKind::Vector)) || cast.rest.unit.kind == RegKind::Vector } - PassMode::Direct(..) | PassMode::Pair(..) => matches!(repr, BackendRepr::Vector { .. }), + PassMode::Direct(..) | PassMode::Pair(..) => matches!(repr, BackendRepr::SimdVector { .. }), } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs index a627e0e69b62..62cbab9b723c 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs @@ -206,7 +206,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { rustc_abi::BackendRepr::ScalarPair(first, second) => { ValueAbi::ScalarPair(first.stable(tables), second.stable(tables)) } - rustc_abi::BackendRepr::Vector { element, count } => { + rustc_abi::BackendRepr::SimdVector { element, count } => { ValueAbi::Vector { element: element.stable(tables), count } } rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized }, diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs index 3fa67c624a7b..209d7483e612 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs @@ -25,7 +25,7 @@ struct CannotUseFpConv; fn is_loongarch_aggregate(arg: &ArgAbi<'_, Ty>) -> bool { match arg.layout.backend_repr { - BackendRepr::Vector { .. } => true, + BackendRepr::SimdVector { .. } => true, _ => arg.layout.is_aggregate(), } } @@ -80,7 +80,7 @@ where } } }, - BackendRepr::Vector { .. } => return Err(CannotUseFpConv), + BackendRepr::SimdVector { .. } => return Err(CannotUseFpConv), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 1c044fe98b3e..198d08864bec 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -357,7 +357,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { scalar_attrs(&layout, a, Size::ZERO), scalar_attrs(&layout, b, a.size(cx).align_to(b.align(cx).abi)), ), - BackendRepr::Vector { .. } => PassMode::Direct(ArgAttributes::new()), + BackendRepr::SimdVector { .. } => PassMode::Direct(ArgAttributes::new()), BackendRepr::Memory { .. } => Self::indirect_pass_mode(&layout), }; ArgAbi { layout, mode } @@ -759,7 +759,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { if arg_idx.is_none() && arg.layout.size > Primitive::Pointer(AddressSpace::DATA).size(cx) * 2 - && !matches!(arg.layout.backend_repr, BackendRepr::Vector { .. }) + && !matches!(arg.layout.backend_repr, BackendRepr::SimdVector { .. }) { // Return values larger than 2 registers using a return area // pointer. LLVM and Cranelift disagree about how to return @@ -826,7 +826,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { } } - BackendRepr::Vector { .. } => { + BackendRepr::SimdVector { .. } => { // This is a fun case! The gist of what this is doing is // that we want callers and callees to always agree on the // ABI of how they pass SIMD arguments. If we were to *not* diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs index 785175229b03..7368e225efa7 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs @@ -31,7 +31,7 @@ struct CannotUseFpConv; fn is_riscv_aggregate(arg: &ArgAbi<'_, Ty>) -> bool { match arg.layout.backend_repr { - BackendRepr::Vector { .. } => true, + BackendRepr::SimdVector { .. } => true, _ => arg.layout.is_aggregate(), } } @@ -86,7 +86,7 @@ where } } }, - BackendRepr::Vector { .. } => return Err(CannotUseFpConv), + BackendRepr::SimdVector { .. } => return Err(CannotUseFpConv), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/s390x.rs b/compiler/rustc_target/src/callconv/s390x.rs index 4f69e32b2e3d..1ba792c5acc5 100644 --- a/compiler/rustc_target/src/callconv/s390x.rs +++ b/compiler/rustc_target/src/callconv/s390x.rs @@ -8,7 +8,7 @@ use crate::spec::HasTargetSpec; fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { let size = ret.layout.size; - if size.bits() <= 128 && matches!(ret.layout.backend_repr, BackendRepr::Vector { .. }) { + if size.bits() <= 128 && matches!(ret.layout.backend_repr, BackendRepr::SimdVector { .. }) { return; } if !ret.layout.is_aggregate() && size.bits() <= 64 { @@ -40,7 +40,7 @@ where let size = arg.layout.size; if size.bits() <= 128 { - if let BackendRepr::Vector { .. } = arg.layout.backend_repr { + if let BackendRepr::SimdVector { .. } = arg.layout.backend_repr { // pass non-wrapped vector types using `PassMode::Direct` return; } diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 7e5aab0201b6..73aff85a0ad8 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -109,7 +109,7 @@ where { match layout.backend_repr { BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) => false, - BackendRepr::Vector { .. } => true, + BackendRepr::SimdVector { .. } => true, BackendRepr::Memory { .. } => { for i in 0..layout.fields.count() { if contains_vector(cx, layout.field(cx, i)) { diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index ab306e202396..300b19f62e72 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -56,7 +56,7 @@ where Primitive::Float(_) => Class::Sse, }, - BackendRepr::Vector { .. } => Class::Sse, + BackendRepr::SimdVector { .. } => Class::Sse, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => { for i in 0..layout.fields.count() { diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs index 4d99a9f9ba06..8f8597ea662a 100644 --- a/compiler/rustc_target/src/callconv/x86_win64.rs +++ b/compiler/rustc_target/src/callconv/x86_win64.rs @@ -18,7 +18,7 @@ pub(crate) fn compute_abi_info(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<' _ => a.make_indirect(), } } - BackendRepr::Vector { .. } => { + BackendRepr::SimdVector { .. } => { // FIXME(eddyb) there should be a size cap here // (probably what clang calls "illegal vectors"). } diff --git a/compiler/rustc_target/src/callconv/xtensa.rs b/compiler/rustc_target/src/callconv/xtensa.rs index 6c030cb3bf77..b687f0e20c66 100644 --- a/compiler/rustc_target/src/callconv/xtensa.rs +++ b/compiler/rustc_target/src/callconv/xtensa.rs @@ -116,7 +116,7 @@ where fn is_xtensa_aggregate<'a, Ty>(arg: &ArgAbi<'a, Ty>) -> bool { match arg.layout.backend_repr { - BackendRepr::Vector { .. } => true, + BackendRepr::SimdVector { .. } => true, _ => arg.layout.is_aggregate(), } } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 74ab65b4f58b..e317768ff602 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -460,7 +460,7 @@ fn fn_abi_sanity_check<'tcx>( // `layout.backend_repr` and ignore everything else. We should just reject //`Aggregate` entirely here, but some targets need to be fixed first. match arg.layout.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => {} + BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => {} BackendRepr::ScalarPair(..) => { panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty) } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 2ab6b8e17c4c..1a82d1713075 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -553,7 +553,7 @@ fn layout_of_uncached<'tcx>( ) } else { ( - BackendRepr::Vector { element: e_abi, count: e_len }, + BackendRepr::SimdVector { element: e_abi, count: e_len }, dl.llvmlike_vector_align(size), ) }; diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index c695e2887fd6..7423a156a217 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -234,7 +234,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou "`ScalarPair` second field with bad ABI in {inner:#?}", ); } - BackendRepr::Vector { element, count } => { + BackendRepr::SimdVector { element, count } => { let align = layout.align.abi; let size = layout.size; let element_align = element.align(cx).abi; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index e2ab336d2e46..a4e49e0aa10a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -192,7 +192,7 @@ fn layout_of_simd_ty( Ok(Arc::new(Layout { variants: Variants::Single { index: struct_variant_idx() }, fields, - backend_repr: BackendRepr::Vector { element: e_abi, count: e_len }, + backend_repr: BackendRepr::SimdVector { element: e_abi, count: e_len }, largest_niche: e_ly.largest_niche, uninhabited: false, size, From 7d4d09eeeb7de6afae90b6cdbabed257eb77727f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Feb 2025 18:43:55 +0000 Subject: [PATCH 473/991] Shorten span of panic failures in const context Previously, we included a redundant prefix on the panic message and a postfix of the location of the panic. The prefix didn't carry any additional information beyond "something failed", and the location of the panic is redundant with the diagnostic's span, which gets printed out even if its code is not shown. ``` error[E0080]: evaluation of constant value failed --> $DIR/assert-type-intrinsics.rs:11:9 | LL | MaybeUninit::::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: aborted execution: attempted to instantiate uninhabited type `!` ``` ``` error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-closure.rs:9:19 | LL | const C: () = panic!(); | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ``` ``` error[E0080]: evaluation of constant value failed --> $DIR/uninhabited.rs:41:9 | LL | assert!(false); | ^^^^^^^^^^^^^^ evaluation panicked: assertion failed: false | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) ``` --- When the primary span for a const error is the same as the first frame in the const error report, skip it. ``` error[E0080]: evaluation of constant value failed --> $DIR/issue-88434-removal-index-should-be-less.rs:3:24 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^ evaluation panicked: explicit panic | note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34}>` --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 | LL | panic!() | ^^^^^^^^ the failure occurred here = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ``` instead of ``` error[E0080]: evaluation of constant value failed --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 | LL | panic!() | ^^^^^^^^ explicit panic | note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34}>` --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 | LL | panic!() | ^^^^^^^^ note: inside `_CONST` --> $DIR/issue-88434-removal-index-should-be-less.rs:3:24 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ``` --- Revert order of constant evaluation errors Point at the code the user wrote first and std functions last. ``` error[E0080]: evaluation of constant value failed --> $DIR/const-errs-dont-conflict-103369.rs:5:25 | LL | impl ConstGenericTrait<{my_fn(1)}> for () {} | ^^^^^^^^ evaluation panicked: Some error occurred | note: called from `my_fn` --> $DIR/const-errs-dont-conflict-103369.rs:10:5 | LL | panic!("Some error occurred"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ``` instead of ``` error[E0080]: evaluation of constant value failed --> $DIR/const-errs-dont-conflict-103369.rs:10:5 | LL | panic!("Some error occurred"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some error occurred | note: called from `<() as ConstGenericTrait<{my_fn(1)}>>::{constant#0}` --> $DIR/const-errs-dont-conflict-103369.rs:5:25 | LL | impl ConstGenericTrait<{my_fn(1)}> for () {} | ^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) ``` --- compiler/rustc_const_eval/messages.ftl | 5 +- .../rustc_const_eval/src/const_eval/error.rs | 21 +- compiler/rustc_const_eval/src/errors.rs | 25 +- .../rustc_const_eval/src/interpret/stack.rs | 10 +- .../miri/tests/fail/erroneous_const.stderr | 2 +- tests/ui/borrowck/issue-81899.rs | 5 +- tests/ui/borrowck/issue-81899.stderr | 13 +- .../borrowck/issue-88434-minimal-example.rs | 5 +- .../issue-88434-minimal-example.stderr | 13 +- ...ssue-88434-removal-index-should-be-less.rs | 5 +- ...-88434-removal-index-should-be-less.stderr | 13 +- .../const-errs-dont-conflict-103369.rs | 7 +- .../const-errs-dont-conflict-103369.stderr | 34 +- .../ui/const-generics/issues/issue-100313.rs | 5 +- .../const-generics/issues/issue-100313.stderr | 13 +- tests/ui/const-ptr/forbidden_slices.rs | 7 +- tests/ui/const-ptr/forbidden_slices.stderr | 78 +- tests/ui/const-ptr/out_of_bounds_read.stderr | 40 +- tests/ui/consts/assert-type-intrinsics.stderr | 6 +- .../consts/const-eval/const_fn_ptr_fail2.rs | 10 +- .../const-eval/const_fn_ptr_fail2.stderr | 36 +- .../const_panic-normalize-tabs-115498.stderr | 2 +- tests/ui/consts/const-eval/const_panic.stderr | 24 +- .../consts/const-eval/const_panic_2021.stderr | 20 +- .../const-eval/const_panic_libcore_bin.stderr | 6 +- .../const-eval/const_panic_track_caller.rs | 9 +- .../const_panic_track_caller.stderr | 13 +- .../const-eval/heap/alloc_intrinsic_errors.rs | 5 +- .../heap/alloc_intrinsic_errors.stderr | 13 +- .../const-eval/panic-assoc-never-type.stderr | 2 +- .../consts/const-eval/panic-never-type.stderr | 2 +- tests/ui/consts/const-eval/parse_ints.rs | 4 +- tests/ui/consts/const-eval/parse_ints.stderr | 32 +- tests/ui/consts/const-eval/raw-pointer-ub.rs | 5 +- .../consts/const-eval/raw-pointer-ub.stderr | 20 +- .../const-eval/transmute-size-mismatch.rs | 12 +- .../const-eval/transmute-size-mismatch.stderr | 26 +- tests/ui/consts/const-eval/ub-enum.rs | 2 +- tests/ui/consts/const-eval/ub-enum.stderr | 12 +- .../ui/consts/const-eval/ub-invalid-values.rs | 7 +- .../const-eval/ub-invalid-values.stderr | 13 +- tests/ui/consts/const-eval/ub-ref-ptr.rs | 2 +- tests/ui/consts/const-eval/ub-ref-ptr.stderr | 16 +- tests/ui/consts/const-eval/unwind-abort.rs | 4 +- .../ui/consts/const-eval/unwind-abort.stderr | 13 +- .../const-eval/validate_uninhabited_zsts.rs | 4 +- .../validate_uninhabited_zsts.stderr | 13 +- tests/ui/consts/const-ptr-is-null.rs | 2 +- tests/ui/consts/const-ptr-is-null.stderr | 18 +- tests/ui/consts/const-unwrap.rs | 2 +- tests/ui/consts/const-unwrap.stderr | 4 +- .../ui/consts/const_unsafe_unreachable_ub.rs | 7 +- .../consts/const_unsafe_unreachable_ub.stderr | 16 +- tests/ui/consts/control-flow/assert.stderr | 2 +- tests/ui/consts/issue-32829.stderr | 2 +- .../issue-66693-panic-in-array-len.stderr | 2 +- tests/ui/consts/issue-66693.stderr | 4 +- tests/ui/consts/issue-76064.stderr | 2 +- tests/ui/consts/issue-miri-1910.rs | 1 + tests/ui/consts/issue-miri-1910.stderr | 16 +- .../ui/consts/miri_unleashed/abi-mismatch.rs | 9 +- .../consts/miri_unleashed/abi-mismatch.stderr | 13 +- tests/ui/consts/miri_unleashed/assoc_const.rs | 4 +- .../consts/miri_unleashed/assoc_const.stderr | 18 +- tests/ui/consts/miri_unleashed/drop.stderr | 12 +- tests/ui/consts/missing_span_in_backtrace.rs | 2 +- .../consts/missing_span_in_backtrace.stderr | 24 +- tests/ui/consts/offset_from_ub.rs | 6 +- tests/ui/consts/offset_from_ub.stderr | 34 +- tests/ui/consts/offset_ub.rs | 22 +- tests/ui/consts/offset_ub.stderr | 128 +- .../consts/qualif-indirect-mutation-fail.rs | 4 +- .../qualif-indirect-mutation-fail.stderr | 40 +- tests/ui/consts/recursive.rs | 3 +- tests/ui/consts/recursive.stderr | 19 +- .../collect-in-called-fn.noopt.stderr | 2 +- .../collect-in-called-fn.opt.stderr | 2 +- .../collect-in-dead-closure.noopt.stderr | 2 +- .../collect-in-dead-closure.opt.stderr | 2 +- .../collect-in-dead-drop.noopt.stderr | 2 +- .../collect-in-dead-drop.opt.stderr | 2 +- ...-in-dead-fn-behind-assoc-type.noopt.stderr | 2 +- ...ct-in-dead-fn-behind-assoc-type.opt.stderr | 2 +- ...ect-in-dead-fn-behind-generic.noopt.stderr | 2 +- ...llect-in-dead-fn-behind-generic.opt.stderr | 2 +- ...in-dead-fn-behind-opaque-type.noopt.stderr | 2 +- ...t-in-dead-fn-behind-opaque-type.opt.stderr | 2 +- .../collect-in-dead-fn.noopt.stderr | 2 +- .../collect-in-dead-fn.opt.stderr | 2 +- ...ollect-in-dead-fnptr-in-const.noopt.stderr | 2 +- .../collect-in-dead-fnptr-in-const.opt.stderr | 2 +- .../collect-in-dead-fnptr.noopt.stderr | 2 +- .../collect-in-dead-fnptr.opt.stderr | 2 +- .../collect-in-dead-move.noopt.stderr | 2 +- .../collect-in-dead-move.opt.stderr | 2 +- .../collect-in-dead-vtable.noopt.stderr | 2 +- .../collect-in-dead-vtable.opt.stderr | 2 +- .../collect-in-promoted-const.noopt.stderr | 2 +- .../collect-in-promoted-const.opt.stderr | 4 +- .../interpret-in-const-called-fn.noopt.stderr | 2 +- .../interpret-in-const-called-fn.opt.stderr | 2 +- .../interpret-in-promoted.noopt.stderr | 14 +- .../interpret-in-promoted.opt.stderr | 14 +- .../required-consts/interpret-in-promoted.rs | 4 +- .../interpret-in-static.noopt.stderr | 2 +- .../interpret-in-static.opt.stderr | 2 +- .../consts/uninhabited-const-issue-61744.rs | 4 +- .../uninhabited-const-issue-61744.stderr | 1271 ++++++++-------- .../ctfe-id-unlimited.return.stderr | 27 +- .../explicit-tail-calls/ctfe-id-unlimited.rs | 3 +- .../ctfe-tail-call-panic.rs | 11 +- .../ctfe-tail-call-panic.stderr | 13 +- .../def-site-eval.fail.stderr | 2 +- .../post_monomorphization_error_backtrace.rs | 4 +- ...st_monomorphization_error_backtrace.stderr | 4 +- .../infinite/infinite-recursion-const-fn.rs | 4 +- .../infinite-recursion-const-fn.stderr | 1279 ++++++++--------- .../const-expr-generic-err.stderr | 2 +- tests/ui/inline-const/required-const.stderr | 2 +- tests/ui/issues/issue-76191.stderr | 2 +- .../invalid-unsized-in-always-sized-tail.rs | 2 +- ...nvalid-unsized-in-always-sized-tail.stderr | 12 +- .../unknown-when-no-type-parameter.stderr | 12 +- tests/ui/limits/issue-55878.stderr | 12 +- .../ui/simd/const-err-trumps-simd-err.stderr | 2 +- .../default-field-values/invalid-const.stderr | 2 +- tests/ui/transmutability/uninhabited.stderr | 6 +- 127 files changed, 1798 insertions(+), 2018 deletions(-) diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index eecc6690f515..ccf9b240d408 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -109,6 +109,8 @@ const_eval_frame_note_inner = inside {$where_ -> *[other] {""} } +const_eval_frame_note_last = the failure occurred here + const_eval_in_bounds_test = out-of-bounds pointer use const_eval_incompatible_calling_conventions = calling a function with calling convention {$callee_conv} using calling convention {$caller_conv} @@ -300,8 +302,7 @@ const_eval_overflow_arith = const_eval_overflow_shift = overflowing shift by {$shift_amount} in `{$intrinsic}` -const_eval_panic = - the evaluated program panicked at '{$msg}', {$file}:{$line}:{$col} +const_eval_panic = evaluation panicked: {$msg} const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str` diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 3e32336d8fca..ffb32fa41eb5 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -48,11 +48,8 @@ impl MachineStopType for ConstEvalErrKind { | ModifiedGlobal | WriteThroughImmutablePointer => {} AssertFailure(kind) => kind.add_args(adder), - Panic { msg, line, col, file } => { + Panic { msg, .. } => { adder("msg".into(), msg.into_diag_arg(&mut None)); - adder("file".into(), file.into_diag_arg(&mut None)); - adder("line".into(), line.into_diag_arg(&mut None)); - adder("col".into(), col.into_diag_arg(&mut None)); } } } @@ -72,7 +69,7 @@ pub fn get_span_and_frames<'tcx>( let mut stacktrace = Frame::generate_stacktrace_from_stack(stack); // Filter out `requires_caller_location` frames. stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*tcx)); - let span = stacktrace.first().map(|f| f.span).unwrap_or(tcx.span); + let span = stacktrace.last().map(|f| f.span).unwrap_or(tcx.span); let mut frames = Vec::new(); @@ -115,6 +112,20 @@ pub fn get_span_and_frames<'tcx>( } } + // In `rustc`, we present const-eval errors from the outer-most place first to the inner-most. + // So we reverse the frames here. The first frame will be the same as the span from the current + // `TyCtxtAt<'_>`, so we remove it as it would be redundant. + frames.reverse(); + if frames.len() > 0 { + frames.remove(0); + } + if let Some(last) = frames.last_mut() + // If the span is not going to be printed, we don't want the span label for `is_last`. + && tcx.sess.source_map().span_to_snippet(last.span.source_callsite()).is_ok() + { + last.has_label = true; + } + (span, frames) } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index ef756e58c5e0..b020eeccf717 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -6,6 +6,7 @@ use rustc_abi::WrappingRange; use rustc_errors::codes::*; use rustc_errors::{ Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, Level, + MultiSpan, SubdiagMessageOp, Subdiagnostic, }; use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -17,6 +18,7 @@ use rustc_middle::mir::interpret::{ use rustc_middle::ty::{self, Mutability, Ty}; use rustc_span::{Span, Symbol}; +use crate::fluent_generated as fluent; use crate::interpret::InternKind; #[derive(Diagnostic)] @@ -278,14 +280,31 @@ pub(crate) struct NonConstImplNote { pub span: Span, } -#[derive(Subdiagnostic, Clone)] -#[note(const_eval_frame_note)] +#[derive(Clone)] pub struct FrameNote { - #[primary_span] pub span: Span, pub times: i32, pub where_: &'static str, pub instance: String, + pub has_label: bool, +} + +impl Subdiagnostic for FrameNote { + fn add_to_diag_with>( + self, + diag: &mut Diag<'_, G>, + f: &F, + ) { + diag.arg("times", self.times); + diag.arg("where_", self.where_); + diag.arg("instance", self.instance); + let mut span: MultiSpan = self.span.into(); + if self.has_label && !self.span.is_dummy() { + span.push_span_label(self.span, fluent::const_eval_frame_note_last); + } + let msg = f(diag, fluent::const_eval_frame_note.into()); + diag.span_note(span, msg); + } } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 7d0e0492792a..d7b03776bc48 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -231,13 +231,19 @@ impl<'tcx> FrameInfo<'tcx> { pub fn as_note(&self, tcx: TyCtxt<'tcx>) -> errors::FrameNote { let span = self.span; if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::Closure { - errors::FrameNote { where_: "closure", span, instance: String::new(), times: 0 } + errors::FrameNote { + where_: "closure", + span, + instance: String::new(), + times: 0, + has_label: false, + } } else { let instance = format!("{}", self.instance); // Note: this triggers a `must_produce_diag` state, which means that if we ever get // here we must emit a diagnostic. We should never display a `FrameInfo` unless we // actually want to emit a warning or error to the user. - errors::FrameNote { where_: "instance", span, instance, times: 0 } + errors::FrameNote { where_: "instance", span, instance, times: 0, has_label: false } } } } diff --git a/src/tools/miri/tests/fail/erroneous_const.stderr b/src/tools/miri/tests/fail/erroneous_const.stderr index 3528620cb6a8..2906ac6b20a7 100644 --- a/src/tools/miri/tests/fail/erroneous_const.stderr +++ b/src/tools/miri/tests/fail/erroneous_const.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `PrintName::::VOID` failed --> tests/fail/erroneous_const.rs:LL:CC | LL | const VOID: ! = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', tests/fail/erroneous_const.rs:LL:CC + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/borrowck/issue-81899.rs b/tests/ui/borrowck/issue-81899.rs index 1f1af5c7e050..380c03751f50 100644 --- a/tests/ui/borrowck/issue-81899.rs +++ b/tests/ui/borrowck/issue-81899.rs @@ -1,15 +1,14 @@ // Regression test for #81899. // The `panic!()` below is important to trigger the fixed ICE. -const _CONST: &[u8] = &f(&[], |_| {}); +const _CONST: &[u8] = &f(&[], |_| {}); //~ ERROR evaluation of constant value failed //~^ constant const fn f(_: &[u8], _: F) -> &[u8] where F: FnMut(&u8), { - panic!() //~ ERROR evaluation of constant value failed - //~^ panic + panic!() //~ inside `f } fn main() {} diff --git a/tests/ui/borrowck/issue-81899.stderr b/tests/ui/borrowck/issue-81899.stderr index 1da573ea97c1..2e6e7511ec91 100644 --- a/tests/ui/borrowck/issue-81899.stderr +++ b/tests/ui/borrowck/issue-81899.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-81899.rs:11:5 + --> $DIR/issue-81899.rs:4:24 | -LL | panic!() - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-81899.rs:11:5 +LL | const _CONST: &[u8] = &f(&[], |_| {}); + | ^^^^^^^^^^^^^^ evaluation panicked: explicit panic | note: inside `f::<{closure@$DIR/issue-81899.rs:4:31: 4:34}>` --> $DIR/issue-81899.rs:11:5 | LL | panic!() - | ^^^^^^^^ -note: inside `_CONST` - --> $DIR/issue-81899.rs:4:24 - | -LL | const _CONST: &[u8] = &f(&[], |_| {}); - | ^^^^^^^^^^^^^^ + | ^^^^^^^^ the failure occurred here = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered diff --git a/tests/ui/borrowck/issue-88434-minimal-example.rs b/tests/ui/borrowck/issue-88434-minimal-example.rs index b75abcb731e2..ebaa9a92273b 100644 --- a/tests/ui/borrowck/issue-88434-minimal-example.rs +++ b/tests/ui/borrowck/issue-88434-minimal-example.rs @@ -1,14 +1,13 @@ // Regression test related to issue 88434 -const _CONST: &() = &f(&|_| {}); +const _CONST: &() = &f(&|_| {}); //~ ERROR evaluation of constant value failed //~^ constant const fn f(_: &F) where F: FnMut(&u8), { - panic!() //~ ERROR evaluation of constant value failed - //~^ panic + panic!() //~ inside `f } fn main() { } diff --git a/tests/ui/borrowck/issue-88434-minimal-example.stderr b/tests/ui/borrowck/issue-88434-minimal-example.stderr index b32331ce448e..c8ac13a3473d 100644 --- a/tests/ui/borrowck/issue-88434-minimal-example.stderr +++ b/tests/ui/borrowck/issue-88434-minimal-example.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-88434-minimal-example.rs:10:5 + --> $DIR/issue-88434-minimal-example.rs:3:22 | -LL | panic!() - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:10:5 +LL | const _CONST: &() = &f(&|_| {}); + | ^^^^^^^^^^ evaluation panicked: explicit panic | note: inside `f::<{closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:28}>` --> $DIR/issue-88434-minimal-example.rs:10:5 | LL | panic!() - | ^^^^^^^^ -note: inside `_CONST` - --> $DIR/issue-88434-minimal-example.rs:3:22 - | -LL | const _CONST: &() = &f(&|_| {}); - | ^^^^^^^^^^ + | ^^^^^^^^ the failure occurred here = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered diff --git a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.rs b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.rs index f9134e669dca..8d042630424b 100644 --- a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.rs +++ b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.rs @@ -1,14 +1,13 @@ // Regression test for issue 88434 -const _CONST: &[u8] = &f(&[], |_| {}); +const _CONST: &[u8] = &f(&[], |_| {}); //~ ERROR evaluation of constant value failed //~^ constant const fn f(_: &[u8], _: F) -> &[u8] where F: FnMut(&u8), { - panic!() //~ ERROR evaluation of constant value failed - //~^ panic + panic!() //~ inside `f } fn main() { } diff --git a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr index e3c881dd4650..0041759609ca 100644 --- a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr +++ b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 + --> $DIR/issue-88434-removal-index-should-be-less.rs:3:24 | -LL | panic!() - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5 +LL | const _CONST: &[u8] = &f(&[], |_| {}); + | ^^^^^^^^^^^^^^ evaluation panicked: explicit panic | note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34}>` --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 | LL | panic!() - | ^^^^^^^^ -note: inside `_CONST` - --> $DIR/issue-88434-removal-index-should-be-less.rs:3:24 - | -LL | const _CONST: &[u8] = &f(&[], |_| {}); - | ^^^^^^^^^^^^^^ + | ^^^^^^^^ the failure occurred here = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered diff --git a/tests/ui/coherence/const-errs-dont-conflict-103369.rs b/tests/ui/coherence/const-errs-dont-conflict-103369.rs index c7d46a8000d4..14937e0f02ec 100644 --- a/tests/ui/coherence/const-errs-dont-conflict-103369.rs +++ b/tests/ui/coherence/const-errs-dont-conflict-103369.rs @@ -2,13 +2,12 @@ pub trait ConstGenericTrait {} -impl ConstGenericTrait<{my_fn(1)}> for () {} +impl ConstGenericTrait<{my_fn(1)}> for () {} //~ ERROR E0080 -impl ConstGenericTrait<{my_fn(2)}> for () {} +impl ConstGenericTrait<{my_fn(2)}> for () {} //~ ERROR E0080 const fn my_fn(v: u32) -> u32 { - panic!("Some error occurred"); //~ ERROR E0080 - //~| ERROR E0080 + panic!("Some error occurred"); } fn main() {} diff --git a/tests/ui/coherence/const-errs-dont-conflict-103369.stderr b/tests/ui/coherence/const-errs-dont-conflict-103369.stderr index 22066d6b6bde..4acaaf22ae8f 100644 --- a/tests/ui/coherence/const-errs-dont-conflict-103369.stderr +++ b/tests/ui/coherence/const-errs-dont-conflict-103369.stderr @@ -1,37 +1,27 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const-errs-dont-conflict-103369.rs:10:5 - | -LL | panic!("Some error occurred"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'Some error occurred', $DIR/const-errs-dont-conflict-103369.rs:10:5 - | -note: inside `my_fn` - --> $DIR/const-errs-dont-conflict-103369.rs:10:5 - | -LL | panic!("Some error occurred"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `<() as ConstGenericTrait<{my_fn(1)}>>::{constant#0}` --> $DIR/const-errs-dont-conflict-103369.rs:5:25 | LL | impl ConstGenericTrait<{my_fn(1)}> for () {} - | ^^^^^^^^ - = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0080]: evaluation of constant value failed - --> $DIR/const-errs-dont-conflict-103369.rs:10:5 - | -LL | panic!("Some error occurred"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'Some error occurred', $DIR/const-errs-dont-conflict-103369.rs:10:5 + | ^^^^^^^^ evaluation panicked: Some error occurred | note: inside `my_fn` --> $DIR/const-errs-dont-conflict-103369.rs:10:5 | LL | panic!("Some error occurred"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `<() as ConstGenericTrait<{my_fn(2)}>>::{constant#0}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: evaluation of constant value failed --> $DIR/const-errs-dont-conflict-103369.rs:7:25 | LL | impl ConstGenericTrait<{my_fn(2)}> for () {} - | ^^^^^^^^ + | ^^^^^^^^ evaluation panicked: Some error occurred + | +note: inside `my_fn` + --> $DIR/const-errs-dont-conflict-103369.rs:10:5 + | +LL | panic!("Some error occurred"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-100313.rs b/tests/ui/const-generics/issues/issue-100313.rs index 553165f90b88..7ce2a3b908c5 100644 --- a/tests/ui/const-generics/issues/issue-100313.rs +++ b/tests/ui/const-generics/issues/issue-100313.rs @@ -6,15 +6,14 @@ struct T; impl T { const fn set_false(&self) { unsafe { - *(B as *const bool as *mut bool) = false; - //~^ ERROR evaluation of constant value failed [E0080] + *(B as *const bool as *mut bool) = false; //~ inside `T } } } const _: () = { let x = T::<{ &true }>; - x.set_false(); + x.set_false(); //~ ERROR evaluation of constant value failed [E0080] }; fn main() {} diff --git a/tests/ui/const-generics/issues/issue-100313.stderr b/tests/ui/const-generics/issues/issue-100313.stderr index 6e419078e5ee..03a658a83aff 100644 --- a/tests/ui/const-generics/issues/issue-100313.stderr +++ b/tests/ui/const-generics/issues/issue-100313.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-100313.rs:9:13 + --> $DIR/issue-100313.rs:16:5 | -LL | *(B as *const bool as *mut bool) = false; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to ALLOC0 which is read-only +LL | x.set_false(); + | ^^^^^^^^^^^^^ writing to ALLOC0 which is read-only | note: inside `T::<&true>::set_false` --> $DIR/issue-100313.rs:9:13 | LL | *(B as *const bool as *mut bool) = false; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `_` - --> $DIR/issue-100313.rs:17:5 - | -LL | x.set_false(); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here error: aborting due to 1 previous error diff --git a/tests/ui/const-ptr/forbidden_slices.rs b/tests/ui/const-ptr/forbidden_slices.rs index 59ea92c5ab38..001cfd66ad14 100644 --- a/tests/ui/const-ptr/forbidden_slices.rs +++ b/tests/ui/const-ptr/forbidden_slices.rs @@ -48,9 +48,11 @@ pub static S8: &[u64] = unsafe { pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; //~^ ERROR it is undefined behavior to use this value pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; // errors inside libcore +//~^ ERROR could not evaluate static initializer pub static R2: &[u32] = unsafe { let ptr = &D0 as *const u32; from_ptr_range(ptr..ptr.add(2)) // errors inside libcore + //~^ ERROR could not evaluate static initializer }; pub static R4: &[u8] = unsafe { //~^ ERROR: it is undefined behavior to use this value @@ -74,13 +76,16 @@ pub static R7: &[u16] = unsafe { }; pub static R8: &[u64] = unsafe { let ptr = (&D4 as *const [u32; 2] as *const u32).byte_add(1).cast::(); - from_ptr_range(ptr..ptr.add(1)) //~ inside `R8` + from_ptr_range(ptr..ptr.add(1)) + //~^ ERROR could not evaluate static initializer }; // This is sneaky: &D0 and &D0 point to different objects // (even if at runtime they have the same address) pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) }; +//~^ ERROR could not evaluate static initializer pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) }; +//~^ ERROR could not evaluate static initializer const D0: u32 = 0x11111111; // Constant chosen for endianness-independent behavior. const D1: MaybeUninit<&u32> = MaybeUninit::uninit(); diff --git a/tests/ui/const-ptr/forbidden_slices.stderr b/tests/ui/const-ptr/forbidden_slices.stderr index df588fcc5e10..a4e9c972cebb 100644 --- a/tests/ui/const-ptr/forbidden_slices.stderr +++ b/tests/ui/const-ptr/forbidden_slices.stderr @@ -100,36 +100,28 @@ LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) } } error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | -note: inside `std::ptr::const_ptr::::offset_from_unsigned` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `from_ptr_range::<'_, ()>` - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `R1` --> $DIR/forbidden_slices.rs:50:33 | LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; // errors inside libcore - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize + | +note: inside `from_ptr_range::<'_, ()>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `std::ptr::const_ptr::::offset_from_unsigned` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + --> $DIR/forbidden_slices.rs:54:25 | - = note: out-of-bounds pointer arithmetic: expected a pointer to 8 bytes of memory, but got ALLOC10 which is only 4 bytes from the end of the allocation +LL | from_ptr_range(ptr..ptr.add(2)) // errors inside libcore + | ^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to 8 bytes of memory, but got ALLOC10 which is only 4 bytes from the end of the allocation | note: inside `std::ptr::const_ptr::::add` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `R2` - --> $DIR/forbidden_slices.rs:53:25 - | -LL | from_ptr_range(ptr..ptr.add(2)) // errors inside libcore - | ^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:55:1 + --> $DIR/forbidden_slices.rs:57:1 | LL | pub static R4: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered uninitialized memory, but expected an integer @@ -140,7 +132,7 @@ LL | pub static R4: &[u8] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:60:1 + --> $DIR/forbidden_slices.rs:62:1 | LL | pub static R5: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered a pointer, but expected an integer @@ -153,7 +145,7 @@ LL | pub static R5: &[u8] = unsafe { = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:65:1 + --> $DIR/forbidden_slices.rs:67:1 | LL | pub static R6: &[bool] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x11, but expected a boolean @@ -164,7 +156,7 @@ LL | pub static R6: &[bool] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:70:1 + --> $DIR/forbidden_slices.rs:72:1 | LL | pub static R7: &[u16] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) @@ -175,47 +167,35 @@ LL | pub static R7: &[u16] = unsafe { } error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + --> $DIR/forbidden_slices.rs:79:25 | - = note: out-of-bounds pointer arithmetic: expected a pointer to 8 bytes of memory, but got ALLOC11+0x1 which is only 7 bytes from the end of the allocation +LL | from_ptr_range(ptr..ptr.add(1)) + | ^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to 8 bytes of memory, but got ALLOC11+0x1 which is only 7 bytes from the end of the allocation | note: inside `std::ptr::const_ptr::::add` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `R8` - --> $DIR/forbidden_slices.rs:77:25 - | -LL | from_ptr_range(ptr..ptr.add(1)) - | ^^^^^^^^^^ error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation - | -note: inside `std::ptr::const_ptr::::offset_from_unsigned` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `from_ptr_range::<'_, u32>` - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `R9` - --> $DIR/forbidden_slices.rs:82:34 + --> $DIR/forbidden_slices.rs:85:34 | LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation | - = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation - | -note: inside `std::ptr::const_ptr::::offset_from_unsigned` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `R10` - --> $DIR/forbidden_slices.rs:83:35 +note: inside `std::ptr::const_ptr::::offset_from_unsigned` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + +error[E0080]: could not evaluate static initializer + --> $DIR/forbidden_slices.rs:87:35 | LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation + | +note: inside `from_ptr_range::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `std::ptr::const_ptr::::offset_from_unsigned` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL error: aborting due to 18 previous errors diff --git a/tests/ui/const-ptr/out_of_bounds_read.stderr b/tests/ui/const-ptr/out_of_bounds_read.stderr index 7f354963eb1f..899e151c9b81 100644 --- a/tests/ui/const-ptr/out_of_bounds_read.stderr +++ b/tests/ui/const-ptr/out_of_bounds_read.stderr @@ -1,45 +1,33 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes - | -note: inside `std::ptr::read::` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `_READ` --> $DIR/out_of_bounds_read.rs:10:33 | LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes + | ^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes | note: inside `std::ptr::read::` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::const_ptr::::read` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `_CONST_READ` + +error[E0080]: evaluation of constant value failed --> $DIR/out_of_bounds_read.rs:11:39 | LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() }; - | ^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes + | ^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes | +note: inside `std::ptr::const_ptr::::read` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `std::ptr::read::` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::mut_ptr::::read` - --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL -note: inside `_MUT_READ` + +error[E0080]: evaluation of constant value failed --> $DIR/out_of_bounds_read.rs:12:37 | LL | const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes + | +note: inside `std::ptr::mut_ptr::::read` + --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL error: aborting due to 3 previous errors diff --git a/tests/ui/consts/assert-type-intrinsics.stderr b/tests/ui/consts/assert-type-intrinsics.stderr index 66c4f0f9cd65..92c0610a2480 100644 --- a/tests/ui/consts/assert-type-intrinsics.stderr +++ b/tests/ui/consts/assert-type-intrinsics.stderr @@ -2,19 +2,19 @@ error[E0080]: evaluation of constant value failed --> $DIR/assert-type-intrinsics.rs:11:9 | LL | MaybeUninit::::uninit().assume_init(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'aborted execution: attempted to instantiate uninhabited type `!`', $DIR/assert-type-intrinsics.rs:11:36 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: aborted execution: attempted to instantiate uninhabited type `!` error[E0080]: evaluation of constant value failed --> $DIR/assert-type-intrinsics.rs:15:9 | LL | intrinsics::assert_mem_uninitialized_valid::<&'static i32>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'aborted execution: attempted to leave type `&i32` uninitialized, which is invalid', $DIR/assert-type-intrinsics.rs:15:9 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: aborted execution: attempted to leave type `&i32` uninitialized, which is invalid error[E0080]: evaluation of constant value failed --> $DIR/assert-type-intrinsics.rs:19:9 | LL | intrinsics::assert_zero_valid::<&'static i32>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'aborted execution: attempted to zero-initialize type `&i32`, which is invalid', $DIR/assert-type-intrinsics.rs:19:9 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: aborted execution: attempted to zero-initialize type `&i32`, which is invalid error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs b/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs index 87f8b52a650b..7db8c6e81ab5 100644 --- a/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs +++ b/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs @@ -7,12 +7,18 @@ const X: fn(usize) -> usize = double; const fn bar(x: fn(usize) -> usize, y: usize) -> usize { x(y) - //~^ ERROR evaluation of constant value failed - //~| ERROR evaluation of constant value failed + //~^ NOTE inside `bar` + //~| NOTE the failure occurred here + //~| NOTE inside `bar` + //~| NOTE the failure occurred here } const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday +//~^ ERROR evaluation of constant value failed +//~| NOTE calling non-const function `double` const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday +//~^ ERROR evaluation of constant value failed +//~| NOTE calling non-const function `double` fn main() { assert_eq!(Y, 4); diff --git a/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr index 0734f479f989..a4d2e26c3afb 100644 --- a/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -1,36 +1,26 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const_fn_ptr_fail2.rs:9:5 - | -LL | x(y) - | ^^^^ calling non-const function `double` - | -note: inside `bar` - --> $DIR/const_fn_ptr_fail2.rs:9:5 - | -LL | x(y) - | ^^^^ -note: inside `Y` - --> $DIR/const_fn_ptr_fail2.rs:14:18 + --> $DIR/const_fn_ptr_fail2.rs:16:18 | LL | const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday - | ^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $DIR/const_fn_ptr_fail2.rs:9:5 - | -LL | x(y) - | ^^^^ calling non-const function `double` + | ^^^^^^^^^ calling non-const function `double` | note: inside `bar` --> $DIR/const_fn_ptr_fail2.rs:9:5 | LL | x(y) - | ^^^^ -note: inside `Z` - --> $DIR/const_fn_ptr_fail2.rs:15:18 + | ^^^^ the failure occurred here + +error[E0080]: evaluation of constant value failed + --> $DIR/const_fn_ptr_fail2.rs:19:18 | LL | const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ calling non-const function `double` + | +note: inside `bar` + --> $DIR/const_fn_ptr_fail2.rs:9:5 + | +LL | x(y) + | ^^^^ the failure occurred here warning: skipping const checks | diff --git a/tests/ui/consts/const-eval/const_panic-normalize-tabs-115498.stderr b/tests/ui/consts/const-eval/const_panic-normalize-tabs-115498.stderr index 5f4af25611f0..64e227c4f45c 100644 --- a/tests/ui/consts/const-eval/const_panic-normalize-tabs-115498.stderr +++ b/tests/ui/consts/const-eval/const_panic-normalize-tabs-115498.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic-normalize-tabs-115498.rs:3:17 | LL | struct Bug([u8; panic!{"\t"}]); - | ^^^^^^^^^^^^ the evaluated program panicked at ' ', $DIR/const_panic-normalize-tabs-115498.rs:3:17 + | ^^^^^^^^^^^^ evaluation panicked: | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-eval/const_panic.stderr b/tests/ui/consts/const-eval/const_panic.stderr index 0f7be46072df..0816b04faca0 100644 --- a/tests/ui/consts/const-eval/const_panic.stderr +++ b/tests/ui/consts/const-eval/const_panic.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:6:15 | LL | const Z: () = std::panic!("cheese"); - | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:6:15 + | ^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: cheese | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -10,7 +10,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:9:16 | LL | const Z2: () = std::panic!(); - | ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:9:16 + | ^^^^^^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -18,7 +18,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:12:15 | LL | const Y: () = std::unreachable!(); - | ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:12:15 + | ^^^^^^^^^^^^^^^^^^^ evaluation panicked: internal error: entered unreachable code | = note: this error originates in the macro `$crate::panic::unreachable_2015` which comes from the expansion of the macro `std::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -26,7 +26,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:15:15 | LL | const X: () = std::unimplemented!(); - | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:15:15 + | ^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: not implemented | = note: this error originates in the macro `std::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -34,7 +34,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:18:15 | LL | const W: () = std::panic!(MSG); - | ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:18:15 + | ^^^^^^^^^^^^^^^^ evaluation panicked: hello | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -42,7 +42,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:21:16 | LL | const W2: () = std::panic!("{}", MSG); - | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:21:16 + | ^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: hello | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -50,7 +50,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:24:20 | LL | const Z_CORE: () = core::panic!("cheese"); - | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:24:20 + | ^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: cheese | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -58,7 +58,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:27:21 | LL | const Z2_CORE: () = core::panic!(); - | ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:27:21 + | ^^^^^^^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -66,7 +66,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:30:20 | LL | const Y_CORE: () = core::unreachable!(); - | ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:30:20 + | ^^^^^^^^^^^^^^^^^^^^ evaluation panicked: internal error: entered unreachable code | = note: this error originates in the macro `$crate::panic::unreachable_2015` which comes from the expansion of the macro `core::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -74,7 +74,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:33:20 | LL | const X_CORE: () = core::unimplemented!(); - | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:33:20 + | ^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: not implemented | = note: this error originates in the macro `core::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -82,7 +82,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:36:20 | LL | const W_CORE: () = core::panic!(MSG); - | ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:36:20 + | ^^^^^^^^^^^^^^^^^ evaluation panicked: hello | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -90,7 +90,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:39:21 | LL | const W2_CORE: () = core::panic!("{}", MSG); - | ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:39:21 + | ^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: hello | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-eval/const_panic_2021.stderr b/tests/ui/consts/const-eval/const_panic_2021.stderr index 192fa3a12c25..4faa2a1e4cfd 100644 --- a/tests/ui/consts/const-eval/const_panic_2021.stderr +++ b/tests/ui/consts/const-eval/const_panic_2021.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:6:15 | LL | const A: () = std::panic!("blåhaj"); - | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'blåhaj', $DIR/const_panic_2021.rs:6:15 + | ^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: blåhaj | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -10,7 +10,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:9:15 | LL | const B: () = std::panic!(); - | ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:9:15 + | ^^^^^^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -18,7 +18,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:12:15 | LL | const C: () = std::unreachable!(); - | ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:12:15 + | ^^^^^^^^^^^^^^^^^^^ evaluation panicked: internal error: entered unreachable code | = note: this error originates in the macro `$crate::panic::unreachable_2021` which comes from the expansion of the macro `std::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -26,7 +26,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:15:15 | LL | const D: () = std::unimplemented!(); - | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:15:15 + | ^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: not implemented | = note: this error originates in the macro `std::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -34,7 +34,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:18:15 | LL | const E: () = std::panic!("{}", MSG); - | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:18:15 + | ^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: hello | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -42,7 +42,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:21:20 | LL | const A_CORE: () = core::panic!("shark"); - | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'shark', $DIR/const_panic_2021.rs:21:20 + | ^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: shark | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -50,7 +50,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:24:20 | LL | const B_CORE: () = core::panic!(); - | ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:24:20 + | ^^^^^^^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -58,7 +58,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:27:20 | LL | const C_CORE: () = core::unreachable!(); - | ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:27:20 + | ^^^^^^^^^^^^^^^^^^^^ evaluation panicked: internal error: entered unreachable code | = note: this error originates in the macro `$crate::panic::unreachable_2021` which comes from the expansion of the macro `core::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -66,7 +66,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:30:20 | LL | const D_CORE: () = core::unimplemented!(); - | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:30:20 + | ^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: not implemented | = note: this error originates in the macro `core::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -74,7 +74,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:33:20 | LL | const E_CORE: () = core::panic!("{}", MSG); - | ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:33:20 + | ^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: hello | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr b/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr index df19ed4a8986..11e70c484990 100644 --- a/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr +++ b/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_libcore_bin.rs:8:15 | LL | const Z: () = panic!("cheese"); - | ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_bin.rs:8:15 + | ^^^^^^^^^^^^^^^^ evaluation panicked: cheese | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -10,7 +10,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_libcore_bin.rs:11:15 | LL | const Y: () = unreachable!(); - | ^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_bin.rs:11:15 + | ^^^^^^^^^^^^^^ evaluation panicked: internal error: entered unreachable code | = note: this error originates in the macro `$crate::panic::unreachable_2015` which comes from the expansion of the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -18,7 +18,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_libcore_bin.rs:14:15 | LL | const X: () = unimplemented!(); - | ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore_bin.rs:14:15 + | ^^^^^^^^^^^^^^^^ evaluation panicked: not implemented | = note: this error originates in the macro `unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-eval/const_panic_track_caller.rs b/tests/ui/consts/const-eval/const_panic_track_caller.rs index 9cf7a3ba7dc1..799a59d16ca2 100644 --- a/tests/ui/consts/const-eval/const_panic_track_caller.rs +++ b/tests/ui/consts/const-eval/const_panic_track_caller.rs @@ -12,11 +12,10 @@ const fn b() -> u32 { } const fn c() -> u32 { - b() - //~^ ERROR evaluation of constant value failed - //~| NOTE the evaluated program panicked - //~| NOTE inside + b() //~ NOTE inside `c` + //~^ NOTE the failure occurred here } const X: u32 = c(); -//~^ NOTE inside +//~^ ERROR evaluation of constant value failed +//~| NOTE hey diff --git a/tests/ui/consts/const-eval/const_panic_track_caller.stderr b/tests/ui/consts/const-eval/const_panic_track_caller.stderr index a7df82705b88..8736a8c9409d 100644 --- a/tests/ui/consts/const-eval/const_panic_track_caller.stderr +++ b/tests/ui/consts/const-eval/const_panic_track_caller.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const_panic_track_caller.rs:15:5 + --> $DIR/const_panic_track_caller.rs:19:16 | -LL | b() - | ^^^ the evaluated program panicked at 'hey', $DIR/const_panic_track_caller.rs:15:5 +LL | const X: u32 = c(); + | ^^^ evaluation panicked: hey | note: inside `c` --> $DIR/const_panic_track_caller.rs:15:5 | LL | b() - | ^^^ -note: inside `X` - --> $DIR/const_panic_track_caller.rs:21:16 - | -LL | const X: u32 = c(); - | ^^^ + | ^^^ the failure occurred here error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs index 9cf9360dcbd0..c1a544031c2a 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs @@ -2,11 +2,10 @@ #![feature(const_heap)] use std::intrinsics; -const FOO: i32 = foo(); +const FOO: i32 = foo(); //~ error: evaluation of constant value failed const fn foo() -> i32 { unsafe { - let _ = intrinsics::const_allocate(4, 3) as *mut i32; - //~^ error: evaluation of constant value failed + let _ = intrinsics::const_allocate(4, 3) as *mut i32; //~ inside `foo` } 1 } diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr index 2fd7222da521..e1cb7a839961 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/alloc_intrinsic_errors.rs:8:17 + --> $DIR/alloc_intrinsic_errors.rs:5:18 | -LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid align passed to `const_allocate`: 3 is not a power of 2 +LL | const FOO: i32 = foo(); + | ^^^^^ invalid align passed to `const_allocate`: 3 is not a power of 2 | note: inside `foo` --> $DIR/alloc_intrinsic_errors.rs:8:17 | LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `FOO` - --> $DIR/alloc_intrinsic_errors.rs:5:18 - | -LL | const FOO: i32 = foo(); - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr index eef39255927a..efdbbe5698f0 100644 --- a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr +++ b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/panic-assoc-never-type.rs:9:21 | LL | const VOID: ! = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/panic-assoc-never-type.rs:9:21 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-eval/panic-never-type.stderr b/tests/ui/consts/const-eval/panic-never-type.stderr index d3ba3eefb1ab..30a320f8db2f 100644 --- a/tests/ui/consts/const-eval/panic-never-type.stderr +++ b/tests/ui/consts/const-eval/panic-never-type.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/panic-never-type.rs:4:17 | LL | const VOID: ! = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/panic-never-type.rs:4:17 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-eval/parse_ints.rs b/tests/ui/consts/const-eval/parse_ints.rs index cb9a3eb43129..309b7ee5d27a 100644 --- a/tests/ui/consts/const-eval/parse_ints.rs +++ b/tests/ui/consts/const-eval/parse_ints.rs @@ -2,7 +2,7 @@ const _OK: () = match i32::from_str_radix("-1234", 10) { Ok(x) => assert!(x == -1234), Err(_) => panic!(), }; -const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); }; -const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); }; +const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); }; //~ ERROR evaluation of constant value failed +const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); }; //~ ERROR evaluation of constant value failed fn main () {} diff --git a/tests/ui/consts/const-eval/parse_ints.stderr b/tests/ui/consts/const-eval/parse_ints.stderr index 189d3c3958bb..7a855bb9e5cc 100644 --- a/tests/ui/consts/const-eval/parse_ints.stderr +++ b/tests/ui/consts/const-eval/parse_ints.stderr @@ -1,33 +1,25 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/num/mod.rs:LL:COL - | - = note: the evaluated program panicked at 'from_ascii_radix: radix must lie in the range `[2, 36]`', $SRC_DIR/core/src/num/mod.rs:LL:COL - | -note: inside `core::num::::from_ascii_radix` - --> $SRC_DIR/core/src/num/mod.rs:LL:COL -note: inside `core::num::::from_str_radix` - --> $SRC_DIR/core/src/num/mod.rs:LL:COL -note: inside `_TOO_LOW` --> $DIR/parse_ints.rs:5:24 | LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: from_ascii_radix: radix must lie in the range `[2, 36]` + | +note: inside `core::num::::from_str_radix` + --> $SRC_DIR/core/src/num/mod.rs:LL:COL +note: inside `core::num::::from_ascii_radix` + --> $SRC_DIR/core/src/num/mod.rs:LL:COL = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/num/mod.rs:LL:COL - | - = note: the evaluated program panicked at 'from_ascii_radix: radix must lie in the range `[2, 36]`', $SRC_DIR/core/src/num/mod.rs:LL:COL - | -note: inside `core::num::::from_ascii_radix` - --> $SRC_DIR/core/src/num/mod.rs:LL:COL -note: inside `core::num::::from_str_radix` - --> $SRC_DIR/core/src/num/mod.rs:LL:COL -note: inside `_TOO_HIGH` --> $DIR/parse_ints.rs:6:25 | LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: from_ascii_radix: radix must lie in the range `[2, 36]` + | +note: inside `core::num::::from_str_radix` + --> $SRC_DIR/core/src/num/mod.rs:LL:COL +note: inside `core::num::::from_ascii_radix` + --> $SRC_DIR/core/src/num/mod.rs:LL:COL = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/raw-pointer-ub.rs b/tests/ui/consts/const-eval/raw-pointer-ub.rs index 5724293f145f..478e93a910e0 100644 --- a/tests/ui/consts/const-eval/raw-pointer-ub.rs +++ b/tests/ui/consts/const-eval/raw-pointer-ub.rs @@ -17,7 +17,10 @@ const MISALIGNED_COPY: () = unsafe { let y = x.as_ptr().cast::(); let mut z = 123; y.copy_to_nonoverlapping(&mut z, 1); - //~^NOTE + //~^ ERROR evaluation of constant value failed + //~| NOTE inside `std::ptr::const_ptr + //~| NOTE inside `copy_nonoverlapping::` + //~| NOTE accessing memory with alignment 1, but alignment 4 is required // The actual error points into the implementation of `copy_to_nonoverlapping`. }; diff --git a/tests/ui/consts/const-eval/raw-pointer-ub.stderr b/tests/ui/consts/const-eval/raw-pointer-ub.stderr index c3360c8b3e21..4fff293b2eef 100644 --- a/tests/ui/consts/const-eval/raw-pointer-ub.stderr +++ b/tests/ui/consts/const-eval/raw-pointer-ub.stderr @@ -11,28 +11,24 @@ LL | *ptr = 0; | ^^^^^^^^ accessing memory based on pointer with alignment 1, but alignment 4 is required error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL - | - = note: accessing memory with alignment 1, but alignment 4 is required - | -note: inside `copy_nonoverlapping::` - --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL -note: inside `std::ptr::const_ptr::::copy_to_nonoverlapping` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `MISALIGNED_COPY` --> $DIR/raw-pointer-ub.rs:19:5 | LL | y.copy_to_nonoverlapping(&mut z, 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment 1, but alignment 4 is required + | +note: inside `std::ptr::const_ptr::::copy_to_nonoverlapping` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `copy_nonoverlapping::` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL error[E0080]: evaluation of constant value failed - --> $DIR/raw-pointer-ub.rs:31:16 + --> $DIR/raw-pointer-ub.rs:34:16 | LL | let _val = (*ptr).0; | ^^^^^^^^ accessing memory based on pointer with alignment 4, but alignment 16 is required error[E0080]: evaluation of constant value failed - --> $DIR/raw-pointer-ub.rs:38:16 + --> $DIR/raw-pointer-ub.rs:41:16 | LL | let _val = *ptr; | ^^^^ memory access failed: expected a pointer to 8 bytes of memory, but got ALLOC0 which is only 4 bytes from the end of the allocation diff --git a/tests/ui/consts/const-eval/transmute-size-mismatch.rs b/tests/ui/consts/const-eval/transmute-size-mismatch.rs index 2410baea28c3..8a7fd8257b00 100644 --- a/tests/ui/consts/const-eval/transmute-size-mismatch.rs +++ b/tests/ui/consts/const-eval/transmute-size-mismatch.rs @@ -10,15 +10,19 @@ const unsafe fn mir_transmute(x: T) -> U { mir!{ { RET = CastTransmute(x); - //~^ ERROR evaluation of constant value failed - //~| ERROR evaluation of constant value failed + //~^ NOTE inside `mir_transmute + //~| NOTE inside `mir_transmute + //~| NOTE the failure occurred here + //~| NOTE the failure occurred here Return() } } } -const FROM_BIGGER: u16 = unsafe { mir_transmute(123_i32) }; +const FROM_BIGGER: u16 = unsafe { mir_transmute(123_i32) }; //~ ERROR evaluation of constant value failed +//~^ NOTE transmuting from 4-byte type to 2-byte type: `i32` -> `u16` -const FROM_SMALLER: u32 = unsafe { mir_transmute(123_i16) }; +const FROM_SMALLER: u32 = unsafe { mir_transmute(123_i16) }; //~ ERROR evaluation of constant value failed +//~^ NOTE transmuting from 2-byte type to 4-byte type: `i16` -> `u32` fn main() {} diff --git a/tests/ui/consts/const-eval/transmute-size-mismatch.stderr b/tests/ui/consts/const-eval/transmute-size-mismatch.stderr index e051491d3430..888df16ec4ee 100644 --- a/tests/ui/consts/const-eval/transmute-size-mismatch.stderr +++ b/tests/ui/consts/const-eval/transmute-size-mismatch.stderr @@ -1,36 +1,26 @@ error[E0080]: evaluation of constant value failed - --> $DIR/transmute-size-mismatch.rs:12:13 + --> $DIR/transmute-size-mismatch.rs:22:35 | -LL | RET = CastTransmute(x); - | ^^^^^^^^^^^^^^^^^^^^^^ transmuting from 4-byte type to 2-byte type: `i32` -> `u16` +LL | const FROM_BIGGER: u16 = unsafe { mir_transmute(123_i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^ transmuting from 4-byte type to 2-byte type: `i32` -> `u16` | note: inside `mir_transmute::` --> $DIR/transmute-size-mismatch.rs:12:13 | LL | RET = CastTransmute(x); - | ^^^^^^^^^^^^^^^^^^^^^^ -note: inside `FROM_BIGGER` - --> $DIR/transmute-size-mismatch.rs:20:35 - | -LL | const FROM_BIGGER: u16 = unsafe { mir_transmute(123_i32) }; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here error[E0080]: evaluation of constant value failed - --> $DIR/transmute-size-mismatch.rs:12:13 + --> $DIR/transmute-size-mismatch.rs:25:36 | -LL | RET = CastTransmute(x); - | ^^^^^^^^^^^^^^^^^^^^^^ transmuting from 2-byte type to 4-byte type: `i16` -> `u32` +LL | const FROM_SMALLER: u32 = unsafe { mir_transmute(123_i16) }; + | ^^^^^^^^^^^^^^^^^^^^^^ transmuting from 2-byte type to 4-byte type: `i16` -> `u32` | note: inside `mir_transmute::` --> $DIR/transmute-size-mismatch.rs:12:13 | LL | RET = CastTransmute(x); - | ^^^^^^^^^^^^^^^^^^^^^^ -note: inside `FROM_SMALLER` - --> $DIR/transmute-size-mismatch.rs:22:36 - | -LL | const FROM_SMALLER: u32 = unsafe { mir_transmute(123_i16) }; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index 11cd87023d17..5be444e667a1 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -101,7 +101,7 @@ const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem: const TEST_ICE_89765: () = { // This is a regression test for https://github.com/rust-lang/rust/issues/89765. unsafe { std::mem::discriminant(&*(&() as *const () as *const Never)); }; - //~^ inside `TEST_ICE_89765` + //~^ ERROR evaluation of constant value failed }; fn main() { diff --git a/tests/ui/consts/const-eval/ub-enum.stderr b/tests/ui/consts/const-eval/ub-enum.stderr index a0712f64c7bc..cfb7eaf537ac 100644 --- a/tests/ui/consts/const-eval/ub-enum.stderr +++ b/tests/ui/consts/const-eval/ub-enum.stderr @@ -117,17 +117,13 @@ LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: read discriminant of an uninhabited enum variant - | -note: inside `discriminant::` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `TEST_ICE_89765` --> $DIR/ub-enum.rs:103:14 | LL | unsafe { std::mem::discriminant(&*(&() as *const () as *const Never)); }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ read discriminant of an uninhabited enum variant + | +note: inside `discriminant::` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL error: aborting due to 14 previous errors diff --git a/tests/ui/consts/const-eval/ub-invalid-values.rs b/tests/ui/consts/const-eval/ub-invalid-values.rs index 1724a88dd3d9..c0b68d7619a0 100644 --- a/tests/ui/consts/const-eval/ub-invalid-values.rs +++ b/tests/ui/consts/const-eval/ub-invalid-values.rs @@ -1,11 +1,12 @@ const fn bool_cast(ptr: *const bool) { unsafe { - let _val = *ptr as u32; //~ERROR: evaluation of constant value failed - //~^ interpreting an invalid 8-bit value as a bool + let _val = *ptr as u32; //~ NOTE inside `bool_cast` + //~^ NOTE the failure occurred here }} const _: () = { let v = 3_u8; - bool_cast(&v as *const u8 as *const bool); + bool_cast(&v as *const u8 as *const bool); //~ ERROR: evaluation of constant value failed + //~^ NOTE interpreting an invalid 8-bit value as a bool }; fn main() {} diff --git a/tests/ui/consts/const-eval/ub-invalid-values.stderr b/tests/ui/consts/const-eval/ub-invalid-values.stderr index edf72f731e5a..76952c1f1a32 100644 --- a/tests/ui/consts/const-eval/ub-invalid-values.stderr +++ b/tests/ui/consts/const-eval/ub-invalid-values.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/ub-invalid-values.rs:2:16 + --> $DIR/ub-invalid-values.rs:8:5 | -LL | let _val = *ptr as u32; - | ^^^^^^^^^^^ interpreting an invalid 8-bit value as a bool: 0x03 +LL | bool_cast(&v as *const u8 as *const bool); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ interpreting an invalid 8-bit value as a bool: 0x03 | note: inside `bool_cast` --> $DIR/ub-invalid-values.rs:2:16 | LL | let _val = *ptr as u32; - | ^^^^^^^^^^^ -note: inside `_` - --> $DIR/ub-invalid-values.rs:8:5 - | -LL | bool_cast(&v as *const u8 as *const bool); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ the failure occurred here error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index 78d6fb5b65ba..50e510a3d546 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs @@ -63,7 +63,7 @@ const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; const UNALIGNED_READ: () = unsafe { let x = &[0u8; 4]; let ptr = x.as_ptr().cast::(); - ptr.read(); //~ inside `UNALIGNED_READ` + ptr.read(); //~ ERROR evaluation of constant value failed }; diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index 3bbf2977392c..72a523282e6b 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr @@ -149,19 +149,15 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; } error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: accessing memory based on pointer with alignment 1, but alignment 4 is required - | -note: inside `std::ptr::read::` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::const_ptr::::read` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `UNALIGNED_READ` --> $DIR/ub-ref-ptr.rs:66:5 | LL | ptr.read(); - | ^^^^^^^^^^ + | ^^^^^^^^^^ accessing memory based on pointer with alignment 1, but alignment 4 is required + | +note: inside `std::ptr::const_ptr::::read` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL error: aborting due to 15 previous errors diff --git a/tests/ui/consts/const-eval/unwind-abort.rs b/tests/ui/consts/const-eval/unwind-abort.rs index 8d5ed876e439..fee53f8528d6 100644 --- a/tests/ui/consts/const-eval/unwind-abort.rs +++ b/tests/ui/consts/const-eval/unwind-abort.rs @@ -1,8 +1,8 @@ const extern "C" fn foo() { - panic!() //~ ERROR evaluation of constant value failed + panic!() //~ inside `foo` } -const _: () = foo(); +const _: () = foo(); //~ ERROR evaluation of constant value failed // Ensure that the CTFE engine handles calls to `extern "C"` aborting gracefully fn main() { diff --git a/tests/ui/consts/const-eval/unwind-abort.stderr b/tests/ui/consts/const-eval/unwind-abort.stderr index 340f1dbe841f..96c0dd7c5e95 100644 --- a/tests/ui/consts/const-eval/unwind-abort.stderr +++ b/tests/ui/consts/const-eval/unwind-abort.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/unwind-abort.rs:2:5 + --> $DIR/unwind-abort.rs:5:15 | -LL | panic!() - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:2:5 +LL | const _: () = foo(); + | ^^^^^ evaluation panicked: explicit panic | note: inside `foo` --> $DIR/unwind-abort.rs:2:5 | LL | panic!() - | ^^^^^^^^ -note: inside `_` - --> $DIR/unwind-abort.rs:5:15 - | -LL | const _: () = foo(); - | ^^^^^ + | ^^^^^^^^ the failure occurred here = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs b/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs index 261dea6182d3..c4df93b6239a 100644 --- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs +++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs @@ -1,6 +1,5 @@ const fn foo() -> ! { - unsafe { std::mem::transmute(()) } - //~^ ERROR evaluation of constant value failed + unsafe { std::mem::transmute(()) } //~ inside `foo` } // Type defined in a submodule, so that it is not "visibly" @@ -14,6 +13,7 @@ pub mod empty { } const FOO: [empty::Empty; 3] = [foo(); 3]; +//~^ ERROR evaluation of constant value failed const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; //~^ ERROR evaluation of constant value failed diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr index d9f1780f7b99..29311fdb25a2 100644 --- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/validate_uninhabited_zsts.rs:2:14 + --> $DIR/validate_uninhabited_zsts.rs:15:33 | -LL | unsafe { std::mem::transmute(()) } - | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a value of the never type `!` +LL | const FOO: [empty::Empty; 3] = [foo(); 3]; + | ^^^^^ constructing invalid value: encountered a value of the never type `!` | note: inside `foo` --> $DIR/validate_uninhabited_zsts.rs:2:14 | LL | unsafe { std::mem::transmute(()) } - | ^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `FOO` - --> $DIR/validate_uninhabited_zsts.rs:16:33 - | -LL | const FOO: [empty::Empty; 3] = [foo(); 3]; - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here error[E0080]: evaluation of constant value failed --> $DIR/validate_uninhabited_zsts.rs:18:42 diff --git a/tests/ui/consts/const-ptr-is-null.rs b/tests/ui/consts/const-ptr-is-null.rs index 0abd9afa4224..319f6b1a62ba 100644 --- a/tests/ui/consts/const-ptr-is-null.rs +++ b/tests/ui/consts/const-ptr-is-null.rs @@ -19,7 +19,7 @@ const MAYBE_NULL: () = { assert!(!ptr.wrapping_byte_sub(1).is_null()); // ... but once we shift outside the allocation, with an offset divisible by 4, // we might become null. - assert!(!ptr.wrapping_sub(512).is_null()); //~inside `MAYBE_NULL` + assert!(!ptr.wrapping_sub(512).is_null()); //~ ERROR evaluation of constant value failed }; fn main() {} diff --git a/tests/ui/consts/const-ptr-is-null.stderr b/tests/ui/consts/const-ptr-is-null.stderr index 5ef79790d93b..ff2db14a2f51 100644 --- a/tests/ui/consts/const-ptr-is-null.stderr +++ b/tests/ui/consts/const-ptr-is-null.stderr @@ -1,18 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: the evaluated program panicked at 'null-ness of this pointer cannot be determined in const context', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | -note: inside `std::ptr::const_ptr::::is_null::compiletime` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `std::ptr::const_ptr::::is_null` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `MAYBE_NULL` --> $DIR/const-ptr-is-null.rs:22:14 | LL | assert!(!ptr.wrapping_sub(512).is_null()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: null-ness of this pointer cannot be determined in const context + | +note: inside `std::ptr::const_ptr::::is_null` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `std::ptr::const_ptr::::is_null::compiletime` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-unwrap.rs b/tests/ui/consts/const-unwrap.rs index ea0a15af1be7..d48078a0834c 100644 --- a/tests/ui/consts/const-unwrap.rs +++ b/tests/ui/consts/const-unwrap.rs @@ -5,7 +5,7 @@ const FOO: i32 = Some(42i32).unwrap(); const BAR: i32 = Option::::None.unwrap(); //~^ ERROR: evaluation of constant value failed -//~| NOTE: the evaluated program panicked +//~| NOTE: called `Option::unwrap()` on a `None` value const BAZ: i32 = Option::::None.expect("absolutely not!"); //~^ ERROR: evaluation of constant value failed diff --git a/tests/ui/consts/const-unwrap.stderr b/tests/ui/consts/const-unwrap.stderr index aa5dd9a5c36c..832c95992c87 100644 --- a/tests/ui/consts/const-unwrap.stderr +++ b/tests/ui/consts/const-unwrap.stderr @@ -2,13 +2,13 @@ error[E0080]: evaluation of constant value failed --> $DIR/const-unwrap.rs:6:18 | LL | const BAR: i32 = Option::::None.unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'called `Option::unwrap()` on a `None` value', $DIR/const-unwrap.rs:6:38 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: called `Option::unwrap()` on a `None` value error[E0080]: evaluation of constant value failed --> $DIR/const-unwrap.rs:10:18 | LL | const BAZ: i32 = Option::::None.expect("absolutely not!"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'absolutely not!', $DIR/const-unwrap.rs:10:38 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: absolutely not! error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const_unsafe_unreachable_ub.rs b/tests/ui/consts/const_unsafe_unreachable_ub.rs index 705e208b56d7..a3f7fd46a759 100644 --- a/tests/ui/consts/const_unsafe_unreachable_ub.rs +++ b/tests/ui/consts/const_unsafe_unreachable_ub.rs @@ -1,13 +1,14 @@ -//@ error-pattern: evaluation of constant value failed - const unsafe fn foo(x: bool) -> bool { match x { true => true, - false => std::hint::unreachable_unchecked(), + false => std::hint::unreachable_unchecked(), //~ NOTE inside `foo` } } const BAR: bool = unsafe { foo(false) }; +//~^ ERROR evaluation of constant value failed +//~| NOTE entering unreachable code +//~| NOTE inside `unreachable_unchecked` fn main() { assert_eq!(BAR, true); diff --git a/tests/ui/consts/const_unsafe_unreachable_ub.stderr b/tests/ui/consts/const_unsafe_unreachable_ub.stderr index 6394563e2bb8..079ed77b219b 100644 --- a/tests/ui/consts/const_unsafe_unreachable_ub.stderr +++ b/tests/ui/consts/const_unsafe_unreachable_ub.stderr @@ -1,20 +1,16 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/hint.rs:LL:COL + --> $DIR/const_unsafe_unreachable_ub.rs:8:28 | - = note: entering unreachable code +LL | const BAR: bool = unsafe { foo(false) }; + | ^^^^^^^^^^ entering unreachable code | -note: inside `unreachable_unchecked` - --> $SRC_DIR/core/src/hint.rs:LL:COL note: inside `foo` - --> $DIR/const_unsafe_unreachable_ub.rs:6:18 + --> $DIR/const_unsafe_unreachable_ub.rs:4:18 | LL | false => std::hint::unreachable_unchecked(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `BAR` - --> $DIR/const_unsafe_unreachable_ub.rs:10:28 - | -LL | const BAR: bool = unsafe { foo(false) }; - | ^^^^^^^^^^ +note: inside `unreachable_unchecked` + --> $SRC_DIR/core/src/hint.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/consts/control-flow/assert.stderr b/tests/ui/consts/control-flow/assert.stderr index 2f863daf760d..fc378f57fa43 100644 --- a/tests/ui/consts/control-flow/assert.stderr +++ b/tests/ui/consts/control-flow/assert.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/assert.rs:5:15 | LL | const _: () = assert!(false); - | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/assert.rs:5:15 + | ^^^^^^^^^^^^^^ evaluation panicked: assertion failed: false | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/issue-32829.stderr b/tests/ui/consts/issue-32829.stderr index 8eee87af8e1b..0cbc73cfaa39 100644 --- a/tests/ui/consts/issue-32829.stderr +++ b/tests/ui/consts/issue-32829.stderr @@ -2,7 +2,7 @@ error[E0080]: could not evaluate static initializer --> $DIR/issue-32829.rs:1:22 | LL | static S : u64 = { { panic!("foo"); 0 } }; - | ^^^^^^^^^^^^^ the evaluated program panicked at 'foo', $DIR/issue-32829.rs:1:22 + | ^^^^^^^^^^^^^ evaluation panicked: foo | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/issue-66693-panic-in-array-len.stderr b/tests/ui/consts/issue-66693-panic-in-array-len.stderr index 1585ea317d9b..9cf5ad126f33 100644 --- a/tests/ui/consts/issue-66693-panic-in-array-len.stderr +++ b/tests/ui/consts/issue-66693-panic-in-array-len.stderr @@ -10,7 +10,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-66693-panic-in-array-len.rs:10:21 | LL | let _ = [false; panic!()]; - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-66693-panic-in-array-len.rs:10:21 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/issue-66693.stderr b/tests/ui/consts/issue-66693.stderr index a435ace47730..46f30a8cbab6 100644 --- a/tests/ui/consts/issue-66693.stderr +++ b/tests/ui/consts/issue-66693.stderr @@ -18,7 +18,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-66693.rs:16:15 | LL | const _: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-66693.rs:16:15 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -26,7 +26,7 @@ error[E0080]: could not evaluate static initializer --> $DIR/issue-66693.rs:18:19 | LL | static _BAR: () = panic!("panic in static"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'panic in static', $DIR/issue-66693.rs:18:19 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: panic in static | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/issue-76064.stderr b/tests/ui/consts/issue-76064.stderr index fabebdb1a774..55059220388a 100644 --- a/tests/ui/consts/issue-76064.stderr +++ b/tests/ui/consts/issue-76064.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-76064.rs:1:17 | LL | struct Bug([u8; panic!("panic")]); - | ^^^^^^^^^^^^^^^ the evaluated program panicked at 'panic', $DIR/issue-76064.rs:1:17 + | ^^^^^^^^^^^^^^^ evaluation panicked: panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/issue-miri-1910.rs b/tests/ui/consts/issue-miri-1910.rs index 107d9742b92a..d194dd3c78bb 100644 --- a/tests/ui/consts/issue-miri-1910.rs +++ b/tests/ui/consts/issue-miri-1910.rs @@ -5,6 +5,7 @@ const C: () = unsafe { let foo = Some(&42 as *const i32); let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3; (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read(); + //~^ ERROR evaluation of constant value failed }; fn main() { diff --git a/tests/ui/consts/issue-miri-1910.stderr b/tests/ui/consts/issue-miri-1910.stderr index 32beed5dba09..59cbccc13a72 100644 --- a/tests/ui/consts/issue-miri-1910.stderr +++ b/tests/ui/consts/issue-miri-1910.stderr @@ -1,17 +1,13 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: unable to turn pointer into integer - | -note: inside `std::ptr::read::` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::const_ptr::::read` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `C` --> $DIR/issue-miri-1910.rs:7:5 | LL | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer + | +note: inside `std::ptr::const_ptr::::read` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported diff --git a/tests/ui/consts/miri_unleashed/abi-mismatch.rs b/tests/ui/consts/miri_unleashed/abi-mismatch.rs index da5b1dd5802d..ea640ae78d55 100644 --- a/tests/ui/consts/miri_unleashed/abi-mismatch.rs +++ b/tests/ui/consts/miri_unleashed/abi-mismatch.rs @@ -4,13 +4,12 @@ const extern "C" fn c_fn() {} const fn call_rust_fn(my_fn: extern "Rust" fn()) { - my_fn(); - //~^ ERROR could not evaluate static initializer - //~| NOTE calling a function with calling convention C using calling convention Rust - //~| NOTE inside `call_rust_fn` + my_fn(); //~ NOTE inside `call_rust_fn` + //~^ NOTE the failure occurred here } static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) }); -//~^ NOTE inside `VAL` +//~^ ERROR could not evaluate static initializer +//~| NOTE calling a function with calling convention C using calling convention Rust fn main() {} diff --git a/tests/ui/consts/miri_unleashed/abi-mismatch.stderr b/tests/ui/consts/miri_unleashed/abi-mismatch.stderr index 639795efae79..88623b134b0b 100644 --- a/tests/ui/consts/miri_unleashed/abi-mismatch.stderr +++ b/tests/ui/consts/miri_unleashed/abi-mismatch.stderr @@ -1,19 +1,14 @@ error[E0080]: could not evaluate static initializer - --> $DIR/abi-mismatch.rs:7:5 + --> $DIR/abi-mismatch.rs:11:18 | -LL | my_fn(); - | ^^^^^^^ calling a function with calling convention C using calling convention Rust +LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling a function with calling convention C using calling convention Rust | note: inside `call_rust_fn` --> $DIR/abi-mismatch.rs:7:5 | LL | my_fn(); - | ^^^^^^^ -note: inside `VAL` - --> $DIR/abi-mismatch.rs:13:18 - | -LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ the failure occurred here warning: skipping const checks | diff --git a/tests/ui/consts/miri_unleashed/assoc_const.rs b/tests/ui/consts/miri_unleashed/assoc_const.rs index db37197f1902..96b47ff4e5e2 100644 --- a/tests/ui/consts/miri_unleashed/assoc_const.rs +++ b/tests/ui/consts/miri_unleashed/assoc_const.rs @@ -9,7 +9,7 @@ trait Foo { } trait Bar> { - const F: u32 = (U::X, 42).1; + const F: u32 = (U::X, 42).1; //~ ERROR } impl Foo for () { @@ -26,5 +26,5 @@ fn main() { // this is fine, but would have been forbidden by the static checks on `F` let x = <() as Bar>::F; // this test only causes errors due to the line below, so post-monomorphization - let y = , String>>::F; //~ constant + let y = , String>>::F; } diff --git a/tests/ui/consts/miri_unleashed/assoc_const.stderr b/tests/ui/consts/miri_unleashed/assoc_const.stderr index 3303a7842653..f259765f6e57 100644 --- a/tests/ui/consts/miri_unleashed/assoc_const.stderr +++ b/tests/ui/consts/miri_unleashed/assoc_const.stderr @@ -1,17 +1,13 @@ -error[E0080]: evaluation of `, String>>::F` failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function ` as Drop>::drop` - | -note: inside `std::ptr::drop_in_place::> - shim(Some(Vec))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::drop_in_place::<(Vec, u32)> - shim(Some((Vec, u32)))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `, String>>::F` +error[E0080]: evaluation of `std::ptr::drop_in_place::> - shim(Some(Vec))` failed --> $DIR/assoc_const.rs:12:31 | LL | const F: u32 = (U::X, 42).1; - | ^ + | ^ calling non-const function ` as Drop>::drop` + | +note: inside `std::ptr::drop_in_place::<(Vec, u32)> - shim(Some((Vec, u32)))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `std::ptr::drop_in_place::> - shim(Some(Vec))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: erroneous constant encountered --> $DIR/assoc_const.rs:29:13 diff --git a/tests/ui/consts/miri_unleashed/drop.stderr b/tests/ui/consts/miri_unleashed/drop.stderr index 5c415b5bac18..40a29d5a819a 100644 --- a/tests/ui/consts/miri_unleashed/drop.stderr +++ b/tests/ui/consts/miri_unleashed/drop.stderr @@ -1,15 +1,11 @@ error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function ` as Drop>::drop` - | -note: inside `std::ptr::drop_in_place::> - shim(Some(Vec))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `TEST_BAD` --> $DIR/drop.rs:17:1 | LL | }; - | ^ + | ^ calling non-const function ` as Drop>::drop` + | +note: inside `std::ptr::drop_in_place::> - shim(Some(Vec))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL warning: skipping const checks | diff --git a/tests/ui/consts/missing_span_in_backtrace.rs b/tests/ui/consts/missing_span_in_backtrace.rs index 703cc7fbf89b..c8c7453daa12 100644 --- a/tests/ui/consts/missing_span_in_backtrace.rs +++ b/tests/ui/consts/missing_span_in_backtrace.rs @@ -13,7 +13,7 @@ const X: () = { // Swap them, bytewise. unsafe { - ptr::swap_nonoverlapping( + ptr::swap_nonoverlapping( //~ ERROR evaluation of constant value failed &mut ptr1 as *mut _ as *mut MaybeUninit, &mut ptr2 as *mut _ as *mut MaybeUninit, mem::size_of::<&i32>(), diff --git a/tests/ui/consts/missing_span_in_backtrace.stderr b/tests/ui/consts/missing_span_in_backtrace.stderr index 05ae7305dbc0..2f3a65302bd5 100644 --- a/tests/ui/consts/missing_span_in_backtrace.stderr +++ b/tests/ui/consts/missing_span_in_backtrace.stderr @@ -1,17 +1,4 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: unable to copy parts of a pointer from memory at ALLOC0 - | -note: inside `std::ptr::read::>>` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::swap_nonoverlapping_simple_untyped::>` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `swap_nonoverlapping::compiletime::>` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `swap_nonoverlapping::>` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `X` --> $DIR/missing_span_in_backtrace.rs:16:9 | 16 | / ptr::swap_nonoverlapping( @@ -19,7 +6,16 @@ note: inside `X` 18 | | &mut ptr2 as *mut _ as *mut MaybeUninit, 19 | | mem::size_of::<&i32>(), 20 | | ); - | |_________^ + | |_________^ unable to copy parts of a pointer from memory at ALLOC0 + | +note: inside `swap_nonoverlapping::>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `swap_nonoverlapping::compiletime::>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `std::ptr::swap_nonoverlapping_simple_untyped::>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `std::ptr::read::>>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/offset_from_ub.rs b/tests/ui/consts/offset_from_ub.rs index 39384bf0c8b9..53d9c7a39da8 100644 --- a/tests/ui/consts/offset_from_ub.rs +++ b/tests/ui/consts/offset_from_ub.rs @@ -21,7 +21,7 @@ pub const DIFFERENT_ALLOC: usize = { }; pub const NOT_PTR: usize = { - unsafe { (42 as *const u8).offset_from(&5u8) as usize } + unsafe { (42 as *const u8).offset_from(&5u8) as usize } //~ ERROR evaluation of constant value failed }; pub const NOT_MULTIPLE_OF_SIZE: isize = { @@ -107,13 +107,13 @@ pub const OFFSET_VERY_FAR1: isize = { let ptr1 = ptr::null::(); let ptr2 = ptr1.wrapping_offset(isize::MAX); unsafe { ptr2.offset_from(ptr1) } - //~^ inside + //~^ ERROR evaluation of constant value failed }; pub const OFFSET_VERY_FAR2: isize = { let ptr1 = ptr::null::(); let ptr2 = ptr1.wrapping_offset(isize::MAX); unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) } - //~^ inside + //~^ ERROR evaluation of constant value failed }; // If the pointers are the same, OOB/null/UAF is fine. diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr index 8cfbdd131909..08e42c9f30ba 100644 --- a/tests/ui/consts/offset_from_ub.stderr +++ b/tests/ui/consts/offset_from_ub.stderr @@ -5,17 +5,13 @@ LL | let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation - | -note: inside `std::ptr::const_ptr::::offset_from` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `NOT_PTR` --> $DIR/offset_from_ub.rs:24:14 | LL | unsafe { (42 as *const u8).offset_from(&5u8) as usize } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation + | +note: inside `std::ptr::const_ptr::::offset_from` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:31:14 @@ -78,30 +74,22 @@ LL | unsafe { ptr_offset_from_unsigned(ptr2, ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer is too far ahead of second error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation - | -note: inside `std::ptr::const_ptr::::offset_from` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `OFFSET_VERY_FAR1` --> $DIR/offset_from_ub.rs:109:14 | LL | unsafe { ptr2.offset_from(ptr1) } - | ^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: `ptr_offset_from` called when first pointer is too far before second + | ^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation | note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `OFFSET_VERY_FAR2` + +error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:115:14 | LL | unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second + | +note: inside `std::ptr::const_ptr::::offset_from` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL error: aborting due to 14 previous errors diff --git a/tests/ui/consts/offset_ub.rs b/tests/ui/consts/offset_ub.rs index dda6dd388f28..8c52586c485f 100644 --- a/tests/ui/consts/offset_ub.rs +++ b/tests/ui/consts/offset_ub.rs @@ -5,21 +5,21 @@ use std::ptr; //@ normalize-stderr: "\d+ bytes" -> "$$BYTES bytes" -pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; //~NOTE -pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) }; //~NOTE -pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) }; //~NOTE +pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; //~ ERROR +pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) }; //~ ERROR +pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) }; //~ ERROR -pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) }; //~NOTE -pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; //~NOTE -pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) }; //~NOTE -pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; //~NOTE -pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; //~NOTE +pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) }; //~ ERROR +pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; //~ ERROR +pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) }; //~ ERROR +pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; //~ ERROR +pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; //~ ERROR -pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; //~NOTE -pub const DANGLING: *const u8 = unsafe { ptr::NonNull::::dangling().as_ptr().offset(4) }; //~NOTE +pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; //~ ERROR +pub const DANGLING: *const u8 = unsafe { ptr::NonNull::::dangling().as_ptr().offset(4) }; //~ ERROR // Make sure that we don't panic when computing abs(offset*size_of::()) -pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) }; //~NOTE +pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) }; //~ ERROR // Offset-by-zero is allowed. pub const NULL_OFFSET_ZERO: *const u8 = unsafe { ptr::null::().offset(0) }; diff --git a/tests/ui/consts/offset_ub.stderr b/tests/ui/consts/offset_ub.stderr index 779cb9654f4d..a247ad254651 100644 --- a/tests/ui/consts/offset_ub.stderr +++ b/tests/ui/consts/offset_ub.stderr @@ -1,145 +1,101 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: out-of-bounds pointer arithmetic: expected a pointer to the end of 1 byte of memory, but got ALLOC0 which is at the beginning of the allocation - | -note: inside `std::ptr::const_ptr::::offset` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `BEFORE_START` --> $DIR/offset_ub.rs:8:46 | LL | pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: out-of-bounds pointer arithmetic: expected a pointer to $BYTES bytes of memory, but got ALLOC1 which is only 1 byte from the end of the allocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to the end of 1 byte of memory, but got ALLOC0 which is at the beginning of the allocation | note: inside `std::ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `AFTER_END` + +error[E0080]: evaluation of constant value failed --> $DIR/offset_ub.rs:9:43 | LL | pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: out-of-bounds pointer arithmetic: expected a pointer to $BYTES bytes of memory, but got ALLOC2 which is only $BYTES bytes from the end of the allocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to $BYTES bytes of memory, but got ALLOC1 which is only 1 byte from the end of the allocation | note: inside `std::ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `AFTER_ARRAY` + +error[E0080]: evaluation of constant value failed --> $DIR/offset_ub.rs:10:45 | LL | pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to $BYTES bytes of memory, but got ALLOC2 which is only $BYTES bytes from the end of the allocation + | +note: inside `std::ptr::const_ptr::::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize` - | -note: inside `std::ptr::const_ptr::::offset` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `OVERFLOW` --> $DIR/offset_ub.rs:12:43 | LL | pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize` | note: inside `std::ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `UNDERFLOW` + +error[E0080]: evaluation of constant value failed --> $DIR/offset_ub.rs:13:44 | LL | pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize` + | +note: inside `std::ptr::const_ptr::::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: out-of-bounds pointer arithmetic: expected a pointer to $BYTES bytes of memory, but got 0xf..f[noalloc] which is a dangling pointer (it has no provenance) - | -note: inside `std::ptr::const_ptr::::offset` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `OVERFLOW_ADDRESS_SPACE` --> $DIR/offset_ub.rs:14:56 | LL | pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: out-of-bounds pointer arithmetic: expected a pointer to the end of $BYTES bytes of memory, but got 0x1[noalloc] which is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to $BYTES bytes of memory, but got 0xf..f[noalloc] which is a dangling pointer (it has no provenance) | note: inside `std::ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `UNDERFLOW_ADDRESS_SPACE` + +error[E0080]: evaluation of constant value failed --> $DIR/offset_ub.rs:15:57 | LL | pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: out-of-bounds pointer arithmetic: expected a pointer to the end of $BYTES bytes of memory, but got ALLOC3-0x2 which points to before the beginning of the allocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to the end of $BYTES bytes of memory, but got 0x1[noalloc] which is a dangling pointer (it has no provenance) | note: inside `std::ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `NEGATIVE_OFFSET` + +error[E0080]: evaluation of constant value failed --> $DIR/offset_ub.rs:16:49 | LL | pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: out-of-bounds pointer arithmetic: expected a pointer to 1 byte of memory, but got ALLOC4 which is at or beyond the end of the allocation of size $BYTES bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to the end of $BYTES bytes of memory, but got ALLOC3-0x2 which points to before the beginning of the allocation | note: inside `std::ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `ZERO_SIZED_ALLOC` + +error[E0080]: evaluation of constant value failed --> $DIR/offset_ub.rs:18:50 | LL | pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - | - = note: out-of-bounds pointer arithmetic: expected a pointer to $BYTES bytes of memory, but got 0x1[noalloc] which is a dangling pointer (it has no provenance) - | -note: inside `std::ptr::mut_ptr::::offset` - --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL -note: inside `DANGLING` - --> $DIR/offset_ub.rs:19:42 - | -LL | pub const DANGLING: *const u8 = unsafe { ptr::NonNull::::dangling().as_ptr().offset(4) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: out-of-bounds pointer arithmetic: expected a pointer to the end of $BYTES bytes of memory, but got 0xf..f[noalloc] which is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to 1 byte of memory, but got ALLOC4 which is at or beyond the end of the allocation of size $BYTES bytes | note: inside `std::ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `UNDERFLOW_ABS` + +error[E0080]: evaluation of constant value failed + --> $DIR/offset_ub.rs:19:42 + | +LL | pub const DANGLING: *const u8 = unsafe { ptr::NonNull::::dangling().as_ptr().offset(4) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to $BYTES bytes of memory, but got 0x1[noalloc] which is a dangling pointer (it has no provenance) + | +note: inside `std::ptr::mut_ptr::::offset` + --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + +error[E0080]: evaluation of constant value failed --> $DIR/offset_ub.rs:22:47 | LL | pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to the end of $BYTES bytes of memory, but got 0xf..f[noalloc] which is a dangling pointer (it has no provenance) + | +note: inside `std::ptr::const_ptr::::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL error: aborting due to 11 previous errors diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.rs b/tests/ui/consts/qualif-indirect-mutation-fail.rs index 0f59a86b7cc0..4abb231c29f6 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.rs +++ b/tests/ui/consts/qualif-indirect-mutation-fail.rs @@ -15,7 +15,7 @@ pub const A1: () = { let b = &mut y; std::mem::swap(a, b); std::mem::forget(y); -}; +}; //~ ERROR evaluation of constant value failed // Mutable borrow of a type with drop impl. pub const A2: () = { @@ -26,7 +26,7 @@ pub const A2: () = { std::mem::swap(a, b); std::mem::forget(y); let _z = x; //~ ERROR destructor of -}; +}; //~ ERROR evaluation of constant value failed // Shared borrow of a type that might be !Freeze and Drop. pub const fn g1() { diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr index e76d7d3b6705..d3bb01af7547 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr +++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr @@ -8,21 +8,17 @@ LL | }; | - value is dropped here error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function ` as Drop>::drop` - | -note: inside `std::ptr::drop_in_place::> - shim(Some(Vec))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::drop_in_place:: - shim(Some(String))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::drop_in_place::> - shim(Some(Option))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `A1` --> $DIR/qualif-indirect-mutation-fail.rs:18:1 | LL | }; - | ^ + | ^ calling non-const function ` as Drop>::drop` + | +note: inside `std::ptr::drop_in_place::> - shim(Some(Option))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `std::ptr::drop_in_place:: - shim(Some(String))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `std::ptr::drop_in_place::> - shim(Some(Vec))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL error[E0493]: destructor of `Option` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:28:9 @@ -33,21 +29,17 @@ LL | }; | - value is dropped here error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function ` as Drop>::drop` - | -note: inside `std::ptr::drop_in_place::> - shim(Some(Vec))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::drop_in_place:: - shim(Some(String))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::drop_in_place::> - shim(Some(Option))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `A2` --> $DIR/qualif-indirect-mutation-fail.rs:29:1 | LL | }; - | ^ + | ^ calling non-const function ` as Drop>::drop` + | +note: inside `std::ptr::drop_in_place::> - shim(Some(Option))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `std::ptr::drop_in_place:: - shim(Some(String))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `std::ptr::drop_in_place::> - shim(Some(Vec))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL error[E0493]: destructor of `(u32, Option)` cannot be evaluated at compile-time --> $DIR/qualif-indirect-mutation-fail.rs:6:9 diff --git a/tests/ui/consts/recursive.rs b/tests/ui/consts/recursive.rs index 5d736e31bcb4..b5703d11310f 100644 --- a/tests/ui/consts/recursive.rs +++ b/tests/ui/consts/recursive.rs @@ -2,9 +2,8 @@ const fn f(x: T) { //~ WARN function cannot return without recursing f(x); - //~^ ERROR evaluation of constant value failed } -const X: () = f(1); +const X: () = f(1); //~ ERROR evaluation of constant value failed fn main() {} diff --git a/tests/ui/consts/recursive.stderr b/tests/ui/consts/recursive.stderr index 0046005c74f0..fd38b078b94e 100644 --- a/tests/ui/consts/recursive.stderr +++ b/tests/ui/consts/recursive.stderr @@ -10,26 +10,21 @@ LL | f(x); = note: `#[warn(unconditional_recursion)]` on by default error[E0080]: evaluation of constant value failed - --> $DIR/recursive.rs:4:5 + --> $DIR/recursive.rs:7:15 | -LL | f(x); - | ^^^^ reached the configured maximum number of stack frames +LL | const X: () = f(1); + | ^^^^ reached the configured maximum number of stack frames | -note: inside `f::` - --> $DIR/recursive.rs:4:5 - | -LL | f(x); - | ^^^^ note: [... 126 additional calls inside `f::` ...] --> $DIR/recursive.rs:4:5 | LL | f(x); | ^^^^ -note: inside `X` - --> $DIR/recursive.rs:8:15 +note: inside `f::` + --> $DIR/recursive.rs:4:5 | -LL | const X: () = f(1); - | ^^^^ +LL | f(x); + | ^^^^ the failure occurred here error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/consts/required-consts/collect-in-called-fn.noopt.stderr b/tests/ui/consts/required-consts/collect-in-called-fn.noopt.stderr index c3b641a899ac..08d0b338728f 100644 --- a/tests/ui/consts/required-consts/collect-in-called-fn.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-called-fn.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-called-fn.rs:10:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-called-fn.rs:10:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-called-fn.opt.stderr b/tests/ui/consts/required-consts/collect-in-called-fn.opt.stderr index c3b641a899ac..08d0b338728f 100644 --- a/tests/ui/consts/required-consts/collect-in-called-fn.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-called-fn.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-called-fn.rs:10:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-called-fn.rs:10:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-closure.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-closure.noopt.stderr index 75c3575a1106..41fe2cf84e49 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-closure.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-closure.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-closure.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-closure.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-closure.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-closure.opt.stderr index 75c3575a1106..41fe2cf84e49 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-closure.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-closure.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-closure.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-closure.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr index 73790f7517db..b62b25bd3aa4 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-drop.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-drop.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-drop.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-drop.opt.stderr index 73790f7517db..b62b25bd3aa4 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-drop.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-drop.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-drop.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-drop.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.noopt.stderr index 706c0d55b622..c8a7cf983c41 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-fn-behind-assoc-type.rs:10:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fn-behind-assoc-type.rs:10:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.opt.stderr index 706c0d55b622..c8a7cf983c41 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-assoc-type.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-fn-behind-assoc-type.rs:10:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fn-behind-assoc-type.rs:10:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.noopt.stderr index 581edd2b7b8f..1e68d66cf5ea 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-fn-behind-generic.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fn-behind-generic.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.opt.stderr index 581edd2b7b8f..1e68d66cf5ea 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-generic.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-fn-behind-generic.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fn-behind-generic.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.noopt.stderr index 07e46b8a816f..a9cc56fba458 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `m::Fail::::C` failed --> $DIR/collect-in-dead-fn-behind-opaque-type.rs:11:23 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fn-behind-opaque-type.rs:11:23 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.opt.stderr index 07e46b8a816f..a9cc56fba458 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `m::Fail::::C` failed --> $DIR/collect-in-dead-fn-behind-opaque-type.rs:11:23 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fn-behind-opaque-type.rs:11:23 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fn.noopt.stderr index 52462076ff90..ec549561a176 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fn.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-fn.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fn.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fn.opt.stderr index 52462076ff90..ec549561a176 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fn.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fn.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-fn.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fn.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.noopt.stderr index dea2a3423837..dfaf69d52b26 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Late::::FAIL` failed --> $DIR/collect-in-dead-fnptr-in-const.rs:9:22 | LL | const FAIL: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fnptr-in-const.rs:9:22 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.opt.stderr index dea2a3423837..dfaf69d52b26 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fnptr-in-const.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Late::::FAIL` failed --> $DIR/collect-in-dead-fnptr-in-const.rs:9:22 | LL | const FAIL: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fnptr-in-const.rs:9:22 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fnptr.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fnptr.noopt.stderr index 51c687826873..7cbd423cdc08 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fnptr.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fnptr.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-fnptr.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fnptr.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-fnptr.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fnptr.opt.stderr index 51c687826873..7cbd423cdc08 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-fnptr.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-fnptr.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-fnptr.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fnptr.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr index 2ab1f80e2d3b..58e9d7a2c9a6 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-move.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-move.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-move.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-move.opt.stderr index 2ab1f80e2d3b..58e9d7a2c9a6 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-move.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-move.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-move.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-move.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-vtable.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-vtable.noopt.stderr index b4e187064892..6c78ca79fd6d 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-vtable.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-vtable.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-vtable.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-vtable.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-dead-vtable.opt.stderr b/tests/ui/consts/required-consts/collect-in-dead-vtable.opt.stderr index b4e187064892..6c78ca79fd6d 100644 --- a/tests/ui/consts/required-consts/collect-in-dead-vtable.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-dead-vtable.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-dead-vtable.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-vtable.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr b/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr index a50c49d53625..fd231e1101d1 100644 --- a/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-promoted-const.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-promoted-const.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr b/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr index cf0aa8ef7a73..0f3f77769adf 100644 --- a/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-promoted-const.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-promoted-const.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -16,7 +16,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/collect-in-promoted-const.rs:9:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-promoted-const.rs:9:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr index 0e3bbbcc2ec5..d2145089028e 100644 --- a/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/interpret-in-const-called-fn.rs:8:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/interpret-in-const-called-fn.rs:8:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr b/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr index 0e3bbbcc2ec5..d2145089028e 100644 --- a/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/interpret-in-const-called-fn.rs:8:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/interpret-in-const-called-fn.rs:8:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr index 6ab991b64719..2bd0b92d4c22 100644 --- a/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr @@ -1,20 +1,16 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/hint.rs:LL:COL + --> $DIR/interpret-in-promoted.rs:13:28 | - = note: entering unreachable code +LL | let _x: &'static () = &ub(); + | ^^^^ entering unreachable code | -note: inside `unreachable_unchecked` - --> $SRC_DIR/core/src/hint.rs:LL:COL note: inside `ub` --> $DIR/interpret-in-promoted.rs:7:5 | LL | std::hint::unreachable_unchecked(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `FOO` - --> $DIR/interpret-in-promoted.rs:13:28 - | -LL | let _x: &'static () = &ub(); - | ^^^^ +note: inside `unreachable_unchecked` + --> $SRC_DIR/core/src/hint.rs:LL:COL note: erroneous constant encountered --> $DIR/interpret-in-promoted.rs:13:27 diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr b/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr index 6ab991b64719..2bd0b92d4c22 100644 --- a/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr @@ -1,20 +1,16 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/hint.rs:LL:COL + --> $DIR/interpret-in-promoted.rs:13:28 | - = note: entering unreachable code +LL | let _x: &'static () = &ub(); + | ^^^^ entering unreachable code | -note: inside `unreachable_unchecked` - --> $SRC_DIR/core/src/hint.rs:LL:COL note: inside `ub` --> $DIR/interpret-in-promoted.rs:7:5 | LL | std::hint::unreachable_unchecked(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `FOO` - --> $DIR/interpret-in-promoted.rs:13:28 - | -LL | let _x: &'static () = &ub(); - | ^^^^ +note: inside `unreachable_unchecked` + --> $SRC_DIR/core/src/hint.rs:LL:COL note: erroneous constant encountered --> $DIR/interpret-in-promoted.rs:13:27 diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.rs b/tests/ui/consts/required-consts/interpret-in-promoted.rs index 48caece6ff56..2c7b3375054d 100644 --- a/tests/ui/consts/required-consts/interpret-in-promoted.rs +++ b/tests/ui/consts/required-consts/interpret-in-promoted.rs @@ -4,13 +4,13 @@ //! Make sure we evaluate const fn calls even if they get promoted and their result ignored. const unsafe fn ub() { - std::hint::unreachable_unchecked(); + std::hint::unreachable_unchecked(); //~ inside `ub` } pub const FOO: () = unsafe { // Make sure that this gets promoted and then fails to evaluate, and we deal with that // correctly. - let _x: &'static () = &ub(); //~ erroneous constant + let _x: &'static () = &ub(); //~ ERROR evaluation of constant value failed }; fn main() {} diff --git a/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr index 5e8da609e766..f999bf370b85 100644 --- a/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/interpret-in-static.rs:8:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/interpret-in-static.rs:8:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/required-consts/interpret-in-static.opt.stderr b/tests/ui/consts/required-consts/interpret-in-static.opt.stderr index 5e8da609e766..f999bf370b85 100644 --- a/tests/ui/consts/required-consts/interpret-in-static.opt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-static.opt.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `Fail::::C` failed --> $DIR/interpret-in-static.rs:8:19 | LL | const C: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/interpret-in-static.rs:8:19 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/uninhabited-const-issue-61744.rs b/tests/ui/consts/uninhabited-const-issue-61744.rs index 19ee842c36bf..743aaf58ef5a 100644 --- a/tests/ui/consts/uninhabited-const-issue-61744.rs +++ b/tests/ui/consts/uninhabited-const-issue-61744.rs @@ -1,7 +1,7 @@ //@ build-fail pub const unsafe fn fake_type() -> T { - hint_unreachable() //~ ERROR evaluation of `::CONSTANT` failed + hint_unreachable() //~ inside } pub const unsafe fn hint_unreachable() -> ! { @@ -9,7 +9,7 @@ pub const unsafe fn hint_unreachable() -> ! { } trait Const { - const CONSTANT: i32 = unsafe { fake_type() }; //~ inside + const CONSTANT: i32 = unsafe { fake_type() }; //~ ERROR evaluation of `fake_type::` failed } impl Const for T {} diff --git a/tests/ui/consts/uninhabited-const-issue-61744.stderr b/tests/ui/consts/uninhabited-const-issue-61744.stderr index 7575ad730b30..dd175b925934 100644 --- a/tests/ui/consts/uninhabited-const-issue-61744.stderr +++ b/tests/ui/consts/uninhabited-const-issue-61744.stderr @@ -1,649 +1,644 @@ -error[E0080]: evaluation of `::CONSTANT` failed - --> $DIR/uninhabited-const-issue-61744.rs:4:5 +error[E0080]: evaluation of `fake_type::` failed + --> $DIR/uninhabited-const-issue-61744.rs:12:36 | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ reached the configured maximum number of stack frames +LL | const CONSTANT: i32 = unsafe { fake_type() }; + | ^^^^^^^^^^^ reached the configured maximum number of stack frames | -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ -note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 - | -LL | hint_unreachable() - | ^^^^^^^^^^^^^^^^^^ -note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 - | -LL | fake_type() - | ^^^^^^^^^^^ note: inside `fake_type::` --> $DIR/uninhabited-const-issue-61744.rs:4:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ -note: inside `::CONSTANT` - --> $DIR/uninhabited-const-issue-61744.rs:12:36 +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 | -LL | const CONSTANT: i32 = unsafe { fake_type() }; - | ^^^^^^^^^^^ +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ the failure occurred here error: aborting due to 1 previous error diff --git a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr index 46769cdea8a7..8fb51f5b637c 100644 --- a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr +++ b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr @@ -1,29 +1,24 @@ error[E0080]: evaluation of constant value failed - --> $DIR/ctfe-id-unlimited.rs:17:42 + --> $DIR/ctfe-id-unlimited.rs:28:20 | -LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), - | ^^^^^^^^^^^^^^^^^^^^^ reached the configured maximum number of stack frames +LL | const ID_ED: u32 = rec_id(ORIGINAL); + | ^^^^^^^^^^^^^^^^ reached the configured maximum number of stack frames | -note: inside `inner` - --> $DIR/ctfe-id-unlimited.rs:17:42 +note: inside `rec_id` + --> $DIR/ctfe-id-unlimited.rs:21:5 | -LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), - | ^^^^^^^^^^^^^^^^^^^^^ +LL | inner(0, n) + | ^^^^^^^^^^^ note: [... 125 additional calls inside `inner` ...] --> $DIR/ctfe-id-unlimited.rs:17:42 | LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), | ^^^^^^^^^^^^^^^^^^^^^ -note: inside `rec_id` - --> $DIR/ctfe-id-unlimited.rs:22:5 +note: inside `inner` + --> $DIR/ctfe-id-unlimited.rs:17:42 | -LL | inner(0, n) - | ^^^^^^^^^^^ -note: inside `ID_ED` - --> $DIR/ctfe-id-unlimited.rs:29:20 - | -LL | const ID_ED: u32 = rec_id(ORIGINAL); - | ^^^^^^^^^^^^^^^^ +LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), + | ^^^^^^^^^^^^^^^^^^^^^ the failure occurred here error: aborting due to 1 previous error diff --git a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs index 2a04d4893e68..9e89f4066bb7 100644 --- a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs +++ b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs @@ -15,7 +15,6 @@ const fn rec_id(n: u32) -> u32 { 0 => acc, #[cfg(r#become)] _ => become inner(acc + 1, n - 1), #[cfg(r#return)] _ => return inner(acc + 1, n - 1), - //[return]~^ error: evaluation of constant value failed } } @@ -26,7 +25,7 @@ const fn rec_id(n: u32) -> u32 { const ORIGINAL: u32 = 12345; // Original number, but with identity function applied // (this is the same, but requires execution of the recursion) -const ID_ED: u32 = rec_id(ORIGINAL); +const ID_ED: u32 = rec_id(ORIGINAL); //[return]~ error: evaluation of constant value failed // Assert to make absolutely sure the computation actually happens const ASSERT: () = assert!(ORIGINAL == ID_ED); diff --git a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs index fba4a2692afe..e7038a01d2de 100644 --- a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs +++ b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs @@ -6,14 +6,11 @@ pub const fn f() { } const fn g() { - panic!() - //~^ error: evaluation of constant value failed - //~| note: in this expansion of panic! - //~| note: inside `g` - //~| note: in this expansion of panic! + panic!() //~ NOTE inside `g` + //~^ NOTE in this expansion of panic! } -const _: () = f(); -//~^ note: inside `_` +const _: () = f(); //~ ERROR evaluation of constant value failed +//~^ NOTE explicit panic fn main() {} diff --git a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr index 8c0705121057..ef71722a0ab5 100644 --- a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr +++ b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr @@ -1,19 +1,14 @@ error[E0080]: evaluation of constant value failed - --> $DIR/ctfe-tail-call-panic.rs:9:5 + --> $DIR/ctfe-tail-call-panic.rs:13:15 | -LL | panic!() - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/ctfe-tail-call-panic.rs:9:5 +LL | const _: () = f(); + | ^^^ evaluation panicked: explicit panic | note: inside `g` --> $DIR/ctfe-tail-call-panic.rs:9:5 | LL | panic!() - | ^^^^^^^^ -note: inside `_` - --> $DIR/ctfe-tail-call-panic.rs:16:15 - | -LL | const _: () = f(); - | ^^^ + | ^^^^^^^^ the failure occurred here = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/generic-const-items/def-site-eval.fail.stderr b/tests/ui/generic-const-items/def-site-eval.fail.stderr index 22a5f2916977..1ba4455c7beb 100644 --- a/tests/ui/generic-const-items/def-site-eval.fail.stderr +++ b/tests/ui/generic-const-items/def-site-eval.fail.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `_::<'_>` failed --> $DIR/def-site-eval.rs:14:20 | LL | const _<'_a>: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/def-site-eval.rs:14:20 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/generics/post_monomorphization_error_backtrace.rs b/tests/ui/generics/post_monomorphization_error_backtrace.rs index 2c18f2b233ad..f5f36ef03ae6 100644 --- a/tests/ui/generics/post_monomorphization_error_backtrace.rs +++ b/tests/ui/generics/post_monomorphization_error_backtrace.rs @@ -6,10 +6,10 @@ fn assert_zst() { const V: () = assert!(std::mem::size_of::() == 0); //~^ ERROR: evaluation of `assert_zst::F::::V` failed [E0080] //~| NOTE: in this expansion of assert! - //~| NOTE: the evaluated program panicked + //~| NOTE: assertion failed //~| ERROR: evaluation of `assert_zst::F::::V` failed [E0080] //~| NOTE: in this expansion of assert! - //~| NOTE: the evaluated program panicked + //~| NOTE: assertion failed } F::::V; //~^NOTE: erroneous constant diff --git a/tests/ui/generics/post_monomorphization_error_backtrace.stderr b/tests/ui/generics/post_monomorphization_error_backtrace.stderr index 8a57979bca7d..1366d5491f40 100644 --- a/tests/ui/generics/post_monomorphization_error_backtrace.stderr +++ b/tests/ui/generics/post_monomorphization_error_backtrace.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `assert_zst::F::::V` failed --> $DIR/post_monomorphization_error_backtrace.rs:6:23 | LL | const V: () = assert!(std::mem::size_of::() == 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::() == 0', $DIR/post_monomorphization_error_backtrace.rs:6:23 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: assertion failed: std::mem::size_of::() == 0 | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -22,7 +22,7 @@ error[E0080]: evaluation of `assert_zst::F::::V` failed --> $DIR/post_monomorphization_error_backtrace.rs:6:23 | LL | const V: () = assert!(std::mem::size_of::() == 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::() == 0', $DIR/post_monomorphization_error_backtrace.rs:6:23 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: assertion failed: std::mem::size_of::() == 0 | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/infinite/infinite-recursion-const-fn.rs b/tests/ui/infinite/infinite-recursion-const-fn.rs index 4209153116d9..7b7f6fafab5f 100644 --- a/tests/ui/infinite/infinite-recursion-const-fn.rs +++ b/tests/ui/infinite/infinite-recursion-const-fn.rs @@ -1,11 +1,11 @@ //https://github.com/rust-lang/rust/issues/31364 const fn a() -> usize { - b() //~ ERROR evaluation of constant value failed [E0080] + b() } const fn b() -> usize { a() } -const ARR: [i32; a()] = [5; 6]; +const ARR: [i32; a()] = [5; 6]; //~ ERROR evaluation of constant value failed [E0080] fn main() {} diff --git a/tests/ui/infinite/infinite-recursion-const-fn.stderr b/tests/ui/infinite/infinite-recursion-const-fn.stderr index fd5a3c3c5464..524abdf4d7ad 100644 --- a/tests/ui/infinite/infinite-recursion-const-fn.stderr +++ b/tests/ui/infinite/infinite-recursion-const-fn.stderr @@ -1,649 +1,644 @@ error[E0080]: evaluation of constant value failed - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ reached the configured maximum number of stack frames - | -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `b` - --> $DIR/infinite-recursion-const-fn.rs:7:5 - | -LL | a() - | ^^^ -note: inside `a` - --> $DIR/infinite-recursion-const-fn.rs:4:5 - | -LL | b() - | ^^^ -note: inside `ARR::{constant#0}` --> $DIR/infinite-recursion-const-fn.rs:9:18 | LL | const ARR: [i32; a()] = [5; 6]; - | ^^^ + | ^^^ reached the configured maximum number of stack frames + | +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ the failure occurred here error: aborting due to 1 previous error diff --git a/tests/ui/inline-const/const-expr-generic-err.stderr b/tests/ui/inline-const/const-expr-generic-err.stderr index dcd6b62bbfc1..e67c0b28e023 100644 --- a/tests/ui/inline-const/const-expr-generic-err.stderr +++ b/tests/ui/inline-const/const-expr-generic-err.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `foo::::{constant#0}` failed --> $DIR/const-expr-generic-err.rs:4:13 | LL | const { assert!(std::mem::size_of::() == 0); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::() == 0', $DIR/const-expr-generic-err.rs:4:13 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: assertion failed: std::mem::size_of::() == 0 | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/inline-const/required-const.stderr b/tests/ui/inline-const/required-const.stderr index 6ca4c250223e..a6c630b5477a 100644 --- a/tests/ui/inline-const/required-const.stderr +++ b/tests/ui/inline-const/required-const.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `foo::::{constant#0}` failed --> $DIR/required-const.rs:6:17 | LL | const { panic!() } - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/required-const.rs:6:17 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/issues/issue-76191.stderr b/tests/ui/issues/issue-76191.stderr index a397d0821420..de08fc4ed0d8 100644 --- a/tests/ui/issues/issue-76191.stderr +++ b/tests/ui/issues/issue-76191.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-76191.rs:8:37 | LL | const RANGE2: RangeInclusive = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-76191.rs:8:37 + | ^^^^^^^^ evaluation panicked: explicit panic | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/layout/invalid-unsized-in-always-sized-tail.rs b/tests/ui/layout/invalid-unsized-in-always-sized-tail.rs index 5df97338710d..c6d5f2bfa0ee 100644 --- a/tests/ui/layout/invalid-unsized-in-always-sized-tail.rs +++ b/tests/ui/layout/invalid-unsized-in-always-sized-tail.rs @@ -12,6 +12,6 @@ struct P2 { //~^ ERROR: the size for values of type `[bool]` cannot be known at compilation time } -static CHECK: () = assert!(align_of::() == 1); +static CHECK: () = assert!(align_of::() == 1); //~ ERROR could not evaluate static initializer fn main() {} diff --git a/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr b/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr index f54e97e2a5c7..3a4735e4832f 100644 --- a/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr +++ b/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr @@ -19,17 +19,13 @@ LL | struct MySlice(T); | this could be changed to `T: ?Sized`... error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: the type `MySlice<[bool]>` has an unknown layout - | -note: inside `align_of::` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `CHECK` --> $DIR/invalid-unsized-in-always-sized-tail.rs:15:28 | LL | static CHECK: () = assert!(align_of::() == 1); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ the type `MySlice<[bool]>` has an unknown layout + | +note: inside `align_of::` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL error: aborting due to 2 previous errors diff --git a/tests/ui/layout/unknown-when-no-type-parameter.stderr b/tests/ui/layout/unknown-when-no-type-parameter.stderr index d0456e2b3293..9e414d224bbc 100644 --- a/tests/ui/layout/unknown-when-no-type-parameter.stderr +++ b/tests/ui/layout/unknown-when-no-type-parameter.stderr @@ -1,15 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: the type `<() as Project>::Assoc` has an unknown layout - | -note: inside `std::mem::size_of::<<() as Project>::Assoc>` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `foo::{constant#0}` --> $DIR/unknown-when-no-type-parameter.rs:11:10 | LL | [(); size_of::<<() as Project>::Assoc>()]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `<() as Project>::Assoc` has an unknown layout + | +note: inside `std::mem::size_of::<<() as Project>::Assoc>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr index d2b5150c5561..d705b3daf79e 100644 --- a/tests/ui/limits/issue-55878.stderr +++ b/tests/ui/limits/issue-55878.stderr @@ -1,15 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: values of the type `[u8; usize::MAX]` are too big for the target architecture - | -note: inside `std::mem::size_of::<[u8; usize::MAX]>` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `main` --> $DIR/issue-55878.rs:5:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; usize::MAX]` are too big for the target architecture + | +note: inside `std::mem::size_of::<[u8; usize::MAX]>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/simd/const-err-trumps-simd-err.stderr b/tests/ui/simd/const-err-trumps-simd-err.stderr index 11cbcad227ff..e88c277885e3 100644 --- a/tests/ui/simd/const-err-trumps-simd-err.stderr +++ b/tests/ui/simd/const-err-trumps-simd-err.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of `get_elem::<4>::{constant#0}` failed --> $DIR/const-err-trumps-simd-err.rs:16:13 | LL | const { assert!(LANE < 4); } // the error should be here... - | ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: LANE < 4', $DIR/const-err-trumps-simd-err.rs:16:13 + | ^^^^^^^^^^^^^^^^^ evaluation panicked: assertion failed: LANE < 4 | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/structs/default-field-values/invalid-const.stderr b/tests/ui/structs/default-field-values/invalid-const.stderr index f4a3437031bd..56d20d8d7111 100644 --- a/tests/ui/structs/default-field-values/invalid-const.stderr +++ b/tests/ui/structs/default-field-values/invalid-const.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/invalid-const.rs:5:19 | LL | pub bax: u8 = panic!("asdf"), - | ^^^^^^^^^^^^^^ the evaluated program panicked at 'asdf', $DIR/invalid-const.rs:5:19 + | ^^^^^^^^^^^^^^ evaluation panicked: asdf | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/transmutability/uninhabited.stderr b/tests/ui/transmutability/uninhabited.stderr index b8b7b67f7816..39f8bf19c363 100644 --- a/tests/ui/transmutability/uninhabited.stderr +++ b/tests/ui/transmutability/uninhabited.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/uninhabited.rs:41:9 | LL | assert!(false); - | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:41:9 + | ^^^^^^^^^^^^^^ evaluation panicked: assertion failed: false | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -10,7 +10,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/uninhabited.rs:63:9 | LL | assert!(false); - | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:63:9 + | ^^^^^^^^^^^^^^ evaluation panicked: assertion failed: false | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -18,7 +18,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/uninhabited.rs:87:9 | LL | assert!(false); - | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:87:9 + | ^^^^^^^^^^^^^^ evaluation panicked: assertion failed: false | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) From 91034adf30b3055e489d59f4483ed5def9cc9f19 Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Fri, 28 Feb 2025 16:32:06 +0000 Subject: [PATCH 474/991] Do not require that unsafe fields lack drop glue Instead, we adopt the position that introducing an `unsafe` field itself carries a safety invariant: that if you assign an invariant to that field weaker than what the field's destructor requires, you must ensure that field is in a droppable state in your destructor. See: - https://github.com/rust-lang/rfcs/pull/3458#discussion_r1971676100 - https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/unsafe.20fields.20RFC/near/502113897 --- compiler/rustc_hir_analysis/messages.ftl | 7 ---- .../rustc_hir_analysis/src/check/check.rs | 32 ------------------- compiler/rustc_hir_analysis/src/errors.rs | 23 ------------- library/core/src/marker.rs | 4 +-- tests/ui/unsafe-fields/unsafe-fields.rs | 2 +- tests/ui/unsafe-fields/unsafe-fields.stderr | 17 ++-------- 6 files changed, 5 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 3f75cce00922..fe2254faf61e 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -278,13 +278,6 @@ hir_analysis_invalid_union_field = hir_analysis_invalid_union_field_sugg = wrap the field type in `ManuallyDrop<...>` -hir_analysis_invalid_unsafe_field = - field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe - .note = unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` - -hir_analysis_invalid_unsafe_field_sugg = - wrap the field type in `ManuallyDrop<...>` - hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl .label = const parameter declared here diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f2331f3fd8e1..25dc6b7954b2 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -70,7 +70,6 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_transparent(tcx, def); check_packed(tcx, span, def); - check_unsafe_fields(tcx, def_id); } fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) { @@ -144,36 +143,6 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b true } -/// Check that the unsafe fields do not need dropping. -fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) { - let span = tcx.def_span(item_def_id); - let def = tcx.adt_def(item_def_id); - - let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id); - let args = ty::GenericArgs::identity_for_item(tcx, item_def_id); - - for field in def.all_fields() { - if !field.safety.is_unsafe() { - continue; - } - - if !allowed_union_or_unsafe_field(tcx, field.ty(tcx, args), typing_env, span) { - let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.expect_local()) else { - unreachable!("field has to correspond to hir field") - }; - let ty_span = field.ty.span; - tcx.dcx().emit_err(errors::InvalidUnsafeField { - field_span: field.span, - sugg: errors::InvalidUnsafeFieldSuggestion { - lo: ty_span.shrink_to_lo(), - hi: ty_span.shrink_to_hi(), - }, - note: (), - }); - } - } -} - /// Check that a `static` is inhabited. fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { // Make sure statics are inhabited. @@ -1517,7 +1486,6 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { detect_discriminant_duplicate(tcx, def); check_transparent(tcx, def); - check_unsafe_fields(tcx, def_id); } /// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 852533ff5c95..d000314974ce 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -710,17 +710,6 @@ pub(crate) struct InvalidUnionField { pub note: (), } -#[derive(Diagnostic)] -#[diag(hir_analysis_invalid_unsafe_field, code = E0740)] -pub(crate) struct InvalidUnsafeField { - #[primary_span] - pub field_span: Span, - #[subdiagnostic] - pub sugg: InvalidUnsafeFieldSuggestion, - #[note] - pub note: (), -} - #[derive(Diagnostic)] #[diag(hir_analysis_return_type_notation_on_non_rpitit)] pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> { @@ -742,18 +731,6 @@ pub(crate) struct InvalidUnionFieldSuggestion { pub hi: Span, } -#[derive(Subdiagnostic)] -#[multipart_suggestion( - hir_analysis_invalid_unsafe_field_sugg, - applicability = "machine-applicable" -)] -pub(crate) struct InvalidUnsafeFieldSuggestion { - #[suggestion_part(code = "std::mem::ManuallyDrop<")] - pub lo: Span, - #[suggestion_part(code = ">")] - pub hi: Span, -} - #[derive(Diagnostic)] #[diag(hir_analysis_return_type_notation_equality_bound)] pub(crate) struct ReturnTypeNotationEqualityBound { diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b0571bf7247a..e2dd813981d0 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -453,8 +453,8 @@ impl Copy for ! {} #[stable(feature = "rust1", since = "1.0.0")] impl Copy for &T {} -/// Marker trait for the types that are allowed in union fields, unsafe fields, -/// and unsafe binder types. +/// Marker trait for the types that are allowed in union fields and unsafe +/// binder types. /// /// Implemented for: /// * `&T`, `&mut T` for all `T`, diff --git a/tests/ui/unsafe-fields/unsafe-fields.rs b/tests/ui/unsafe-fields/unsafe-fields.rs index 637471582d7e..cb86479bb20d 100644 --- a/tests/ui/unsafe-fields/unsafe-fields.rs +++ b/tests/ui/unsafe-fields/unsafe-fields.rs @@ -17,7 +17,7 @@ fn f(a: A) { } struct WithInvalidUnsafeField { - unsafe unsafe_noncopy_field: Vec, //~ ERROR + unsafe unsafe_noncopy_field: Vec, } struct WithManuallyDropUnsafeField { diff --git a/tests/ui/unsafe-fields/unsafe-fields.stderr b/tests/ui/unsafe-fields/unsafe-fields.stderr index a1c5d2b44cdf..d0e2dc16a13d 100644 --- a/tests/ui/unsafe-fields/unsafe-fields.stderr +++ b/tests/ui/unsafe-fields/unsafe-fields.stderr @@ -1,15 +1,3 @@ -error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe - --> $DIR/unsafe-fields.rs:20:5 - | -LL | unsafe unsafe_noncopy_field: Vec, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` -help: wrap the field type in `ManuallyDrop<...>` - | -LL | unsafe unsafe_noncopy_field: std::mem::ManuallyDrop>, - | +++++++++++++++++++++++ + - error[E0133]: use of unsafe field is unsafe and requires unsafe block --> $DIR/unsafe-fields.rs:15:30 | @@ -69,7 +57,6 @@ LL | &raw const self.unsafe_field | = note: unsafe fields may carry library invariants -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0133, E0740. -For more information about an error, try `rustc --explain E0133`. +For more information about this error, try `rustc --explain E0133`. From cdef38812dd4de2a3fa3b3512b64c28c278ff7cc Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Fri, 28 Feb 2025 17:50:38 +0100 Subject: [PATCH 475/991] Use correct error message casing for `io::const_error`s Error messages are supposed to start with lowercase letters, but a lot of `io::const_error` messages did not. This fixes them to start with a lowercase letter. I did consider adding a const check for this to the macro, but some of them start with proper nouns that make sense to uppercase them. See https://doc.rust-lang.org/1.85.0/std/error/trait.Error.html --- library/std/src/io/error.rs | 2 +- library/std/src/os/windows/io/socket.rs | 2 +- .../sys/net/connection/xous/tcplistener.rs | 20 +++++----- .../src/sys/net/connection/xous/tcpstream.rs | 38 +++++++++---------- .../std/src/sys/net/connection/xous/udp.rs | 34 ++++++++--------- library/std/src/sys/pal/hermit/thread.rs | 2 +- library/std/src/sys/pal/uefi/helpers.rs | 10 ++--- library/std/src/sys/pal/uefi/os.rs | 12 +++--- library/std/src/sys/pal/uefi/process.rs | 2 +- library/std/src/sys/pal/uefi/stdio.rs | 2 +- library/std/src/sys/pal/unix/os.rs | 4 +- .../sys/pal/unix/process/process_fuchsia.rs | 4 +- .../src/sys/pal/unix/process/process_unix.rs | 2 +- library/std/src/sys/pal/unix/thread.rs | 4 +- library/std/src/sys/pal/unix/time.rs | 2 +- library/std/src/sys/pal/windows/fs.rs | 4 +- library/test/src/formatters/junit.rs | 6 +-- 17 files changed, 75 insertions(+), 75 deletions(-) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 30bc0e3b0883..5aa048c4cbc8 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -83,7 +83,7 @@ impl Error { pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_error!( ErrorKind::NotFound, - "The number of hardware threads is not known for the target platform", + "the number of hardware threads is not known for the target platform", ); pub(crate) const UNSUPPORTED_PLATFORM: Self = diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs index 2bc6ce222ae5..1c228914de93 100644 --- a/library/std/src/os/windows/io/socket.rs +++ b/library/std/src/os/windows/io/socket.rs @@ -90,7 +90,7 @@ impl OwnedSocket { #[cfg(target_vendor = "uwp")] pub(crate) fn set_no_inherit(&self) -> io::Result<()> { - Err(io::const_error!(io::ErrorKind::Unsupported, "Unavailable on UWP")) + Err(io::const_error!(io::ErrorKind::Unsupported, "unavailable on UWP")) } } diff --git a/library/std/src/sys/net/connection/xous/tcplistener.rs b/library/std/src/sys/net/connection/xous/tcplistener.rs index 851d2eb8178d..7f13ca559204 100644 --- a/library/std/src/sys/net/connection/xous/tcplistener.rs +++ b/library/std/src/sys/net/connection/xous/tcplistener.rs @@ -11,7 +11,7 @@ macro_rules! unimpl { () => { return Err(io::const_error!( io::ErrorKind::Unsupported, - "This function is not yet implemented", + "this function is not yet implemented", )); }; } @@ -71,7 +71,7 @@ impl TcpListener { 0, 4096, ) else { - return Err(io::const_error!(io::ErrorKind::InvalidInput, "Invalid response")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid response")); }; // The first four bytes should be zero upon success, and will be nonzero @@ -80,15 +80,15 @@ impl TcpListener { if response[0] != 0 || valid == 0 { let errcode = response[1]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_error!(io::ErrorKind::ResourceBusy, "Socket in use")); + return Err(io::const_error!(io::ErrorKind::ResourceBusy, "socket in use")); } else if errcode == NetError::Invalid as u8 { - return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, "Invalid address")); + return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, "invalid address")); } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, "Library error")); + return Err(io::const_error!(io::ErrorKind::Other, "library error")); } else { return Err(io::const_error!( io::ErrorKind::Other, - "Unable to connect or internal error", + "unable to connect or internal error", )); } } @@ -131,7 +131,7 @@ impl TcpListener { } else if receive_request.raw[1] == NetError::WouldBlock as u8 { return Err(io::const_error!(io::ErrorKind::WouldBlock, "accept would block")); } else if receive_request.raw[1] == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, "Library error")); + return Err(io::const_error!(io::ErrorKind::Other, "library error")); } else { return Err(io::const_error!(io::ErrorKind::Other, "library error")); } @@ -169,7 +169,7 @@ impl TcpListener { Ok((TcpStream::from_listener(stream_fd, self.local.port(), port, addr), addr)) } } else { - Err(io::const_error!(io::ErrorKind::InvalidInput, "Unable to accept")) + Err(io::const_error!(io::ErrorKind::InvalidInput, "unable to accept")) } } @@ -186,7 +186,7 @@ impl TcpListener { services::net_server(), services::NetBlockingScalar::StdSetTtlTcp(self.fd.load(Ordering::Relaxed), ttl).into(), ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "unexpected return value"))) .map(|_| ()) } @@ -195,7 +195,7 @@ impl TcpListener { services::net_server(), services::NetBlockingScalar::StdGetTtlTcp(self.fd.load(Ordering::Relaxed)).into(), ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "unexpected return value"))) .map(|res| res[0] as _)?) } diff --git a/library/std/src/sys/net/connection/xous/tcpstream.rs b/library/std/src/sys/net/connection/xous/tcpstream.rs index 7f7bbfb7fed3..283b1fe9a33b 100644 --- a/library/std/src/sys/net/connection/xous/tcpstream.rs +++ b/library/std/src/sys/net/connection/xous/tcpstream.rs @@ -12,7 +12,7 @@ macro_rules! unimpl { () => { return Err(io::const_error!( io::ErrorKind::Unsupported, - "This function is not yet implemented", + "this function is not yet implemented", )); }; } @@ -96,7 +96,7 @@ impl TcpStream { 0, 4096, ) else { - return Err(io::const_error!(io::ErrorKind::InvalidInput, "Invalid response")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid response")); }; // The first four bytes should be zero upon success, and will be nonzero @@ -106,13 +106,13 @@ impl TcpStream { // errcode is a u8 but stuck in a u16 where the upper byte is invalid. Mask & decode accordingly. let errcode = response[0]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_error!(io::ErrorKind::ResourceBusy, "Socket in use")); + return Err(io::const_error!(io::ErrorKind::ResourceBusy, "socket in use")); } else if errcode == NetError::Unaddressable as u8 { - return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, "Invalid address")); + return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, "invalid address")); } else { return Err(io::const_error!( io::ErrorKind::InvalidInput, - "Unable to connect or internal error", + "unable to connect or internal error", )); } } @@ -198,7 +198,7 @@ impl TcpStream { ) else { return Err(io::const_error!( io::ErrorKind::InvalidInput, - "Library failure: wrong message type or messaging error", + "library failure: wrong message type or messaging error", )); }; @@ -212,11 +212,11 @@ impl TcpStream { if result[0] != 0 { if result[1] == 8 { // timed out - return Err(io::const_error!(io::ErrorKind::TimedOut, "Timeout")); + return Err(io::const_error!(io::ErrorKind::TimedOut, "timeout")); } if result[1] == 9 { // would block - return Err(io::const_error!(io::ErrorKind::WouldBlock, "Would block")); + return Err(io::const_error!(io::ErrorKind::WouldBlock, "would block")); } } Err(io::const_error!(io::ErrorKind::Other, "recv_slice failure")) @@ -258,20 +258,20 @@ impl TcpStream { self.write_timeout.load(Ordering::Relaxed) as usize, buf_len, ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Internal error")))?; + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "internal error")))?; if send_request.raw[0] != 0 { if send_request.raw[4] == 8 { // timed out return Err(io::const_error!( io::ErrorKind::BrokenPipe, - "Timeout or connection closed", + "timeout or connection closed", )); } else if send_request.raw[4] == 9 { // would block - return Err(io::const_error!(io::ErrorKind::WouldBlock, "Would block")); + return Err(io::const_error!(io::ErrorKind::WouldBlock, "would block")); } else { - return Err(io::const_error!(io::ErrorKind::InvalidInput, "Error when sending")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, "error when sending")); } } Ok(u32::from_le_bytes([ @@ -304,7 +304,7 @@ impl TcpStream { 0, 0, ) else { - return Err(io::const_error!(io::ErrorKind::InvalidInput, "Internal error")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, "internal error")); }; let mut i = get_addr.raw.iter(); match *i.next().unwrap() { @@ -324,7 +324,7 @@ impl TcpStream { } Ok(SocketAddr::V6(SocketAddrV6::new(new_addr.into(), self.local_port, 0, 0))) } - _ => Err(io::const_error!(io::ErrorKind::InvalidInput, "Internal error")), + _ => Err(io::const_error!(io::ErrorKind::InvalidInput, "tnternal error")), } } @@ -333,7 +333,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdTcpStreamShutdown(self.fd, how).into(), ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "unexpected return value"))) .map(|_| ()) } @@ -355,7 +355,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdSetNodelay(self.fd, enabled).into(), ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "unexpected return value"))) .map(|_| ()) } @@ -364,7 +364,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdGetNodelay(self.fd).into(), ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "unexpected return value"))) .map(|res| res[0] != 0)?) } @@ -376,7 +376,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdSetTtlTcp(self.fd, ttl).into(), ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "unexpected return value"))) .map(|_| ()) } @@ -385,7 +385,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdGetTtlTcp(self.fd).into(), ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "unexpected return value"))) .map(|res| res[0] as _)?) } diff --git a/library/std/src/sys/net/connection/xous/udp.rs b/library/std/src/sys/net/connection/xous/udp.rs index ab5bd357b612..f35970bc3215 100644 --- a/library/std/src/sys/net/connection/xous/udp.rs +++ b/library/std/src/sys/net/connection/xous/udp.rs @@ -13,7 +13,7 @@ macro_rules! unimpl { () => { return Err(io::const_error!( io::ErrorKind::Unsupported, - "This function is not yet implemented", + "this function is not yet implemented", )); }; } @@ -72,18 +72,18 @@ impl UdpSocket { if response[0] != 0 || valid == 0 { let errcode = response[1]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_error!(io::ErrorKind::ResourceBusy, "Socket in use")); + return Err(io::const_error!(io::ErrorKind::ResourceBusy, "socket in use")); } else if errcode == NetError::Invalid as u8 { return Err(io::const_error!( io::ErrorKind::InvalidInput, - "Port can't be 0 or invalid address", + "port can't be 0 or invalid address", )); } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, "Library error")); + return Err(io::const_error!(io::ErrorKind::Other, "library error")); } else { return Err(io::const_error!( io::ErrorKind::Other, - "Unable to connect or internal error", + "unable to connect or internal error", )); } } @@ -98,13 +98,13 @@ impl UdpSocket { nonblocking: Cell::new(false), }); } - Err(io::const_error!(io::ErrorKind::InvalidInput, "Invalid response")) + Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid response")) } pub fn peer_addr(&self) -> io::Result { match self.remote.get() { Some(dest) => Ok(dest), - None => Err(io::const_error!(io::ErrorKind::NotConnected, "No peer specified")), + None => Err(io::const_error!(io::ErrorKind::NotConnected, "no peer specified")), } } @@ -145,7 +145,7 @@ impl UdpSocket { } else if receive_request.raw[1] == NetError::WouldBlock as u8 { return Err(io::const_error!(io::ErrorKind::WouldBlock, "recv would block")); } else if receive_request.raw[1] == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, "Library error")); + return Err(io::const_error!(io::ErrorKind::Other, "library error")); } else { return Err(io::const_error!(io::ErrorKind::Other, "library error")); } @@ -178,7 +178,7 @@ impl UdpSocket { Ok((rxlen as usize, addr)) } } else { - Err(io::const_error!(io::ErrorKind::InvalidInput, "Unable to recv")) + Err(io::const_error!(io::ErrorKind::InvalidInput, "unable to recv")) } } @@ -281,19 +281,19 @@ impl UdpSocket { if errcode == NetError::SocketInUse as u8 { return Err(io::const_error!( io::ErrorKind::ResourceBusy, - "Socket in use", + "socket in use", )); } else if errcode == NetError::Invalid as u8 { return Err(io::const_error!( io::ErrorKind::InvalidInput, - "Socket not valid", + "socket not valid", )); } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_error!(io::ErrorKind::Other, "Library error")); + return Err(io::const_error!(io::ErrorKind::Other, "library error")); } else { return Err(io::const_error!( io::ErrorKind::Other, - "Unable to connect", + "unable to connect", )); } } else { @@ -303,13 +303,13 @@ impl UdpSocket { } Err(crate::os::xous::ffi::Error::ServerQueueFull) => { if now.elapsed() >= write_timeout { - return Err(io::const_error!(io::ErrorKind::WouldBlock, "Write timed out")); + return Err(io::const_error!(io::ErrorKind::WouldBlock, "write timed out")); } else { // question: do we want to do something a bit more gentle than immediately retrying? crate::thread::yield_now(); } } - _ => return Err(io::const_error!(io::ErrorKind::Other, "Library error")), + _ => return Err(io::const_error!(io::ErrorKind::Other, "library error")), } } } @@ -363,7 +363,7 @@ impl UdpSocket { services::net_server(), services::NetBlockingScalar::StdSetTtlUdp(self.fd, ttl).into(), ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "unexpected return value"))) .map(|_| ()) } @@ -372,7 +372,7 @@ impl UdpSocket { services::net_server(), services::NetBlockingScalar::StdGetTtlUdp(self.fd).into(), ) - .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, "unexpected return value"))) .map(|res| res[0] as _)?) } diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs index 4a7afddbec10..bb68a824fc31 100644 --- a/library/std/src/sys/pal/hermit/thread.rs +++ b/library/std/src/sys/pal/hermit/thread.rs @@ -41,7 +41,7 @@ impl Thread { unsafe { drop(Box::from_raw(p)); } - Err(io::const_error!(io::ErrorKind::Uncategorized, "Unable to create thread!")) + Err(io::const_error!(io::ErrorKind::Uncategorized, "unable to create thread!")) } else { Ok(Thread { tid }) }; diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index ec2da4e4ee7a..cb6aacd0063d 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -158,7 +158,7 @@ pub(crate) unsafe fn close_event(evt: NonNull) -> io::Result /// Note: Some protocols need to be manually freed. It is the caller's responsibility to do so. pub(crate) fn image_handle_protocol(protocol_guid: Guid) -> io::Result> { let system_handle = uefi::env::try_image_handle() - .ok_or(io::const_error!(io::ErrorKind::NotFound, "Protocol not found in Image handle"))?; + .ok_or(io::const_error!(io::ErrorKind::NotFound, "protocol not found in Image handle"))?; open_protocol(system_handle, protocol_guid) } @@ -178,7 +178,7 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R }; let path = os_string_from_raw(path_ptr) - .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "invalid path"))?; if let Some(boot_services) = crate::os::uefi::env::boot_services() { let boot_services: NonNull = boot_services.cast(); @@ -213,7 +213,7 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R } } - Err(io::const_error!(io::ErrorKind::NotFound, "No device path to text protocol found")) + Err(io::const_error!(io::ErrorKind::NotFound, "no device path to text protocol found")) } /// Gets RuntimeServices. @@ -245,7 +245,7 @@ impl OwnedDevicePath { NonNull::new(path) .map(OwnedDevicePath) - .ok_or_else(|| const_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path")) + .ok_or_else(|| const_error!(io::ErrorKind::InvalidFilename, "invalid Device Path")) } static LAST_VALID_HANDLE: AtomicPtr = @@ -490,7 +490,7 @@ pub(crate) fn get_device_path_from_map(map: &Path) -> io::Result io::Result { let path_ptr = unsafe { ((*shell.as_ptr()).get_cur_dir)(crate::ptr::null_mut()) }; helpers::os_string_from_raw(path_ptr) .map(PathBuf::from) - .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path")) + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "invalid path")) } None => { let mut t = current_exe()?; @@ -86,7 +86,7 @@ pub fn chdir(p: &path::Path) -> io::Result<()> { let shell = helpers::open_shell().ok_or(unsupported_err())?; let mut p = helpers::os_string_to_raw(p.as_os_str()) - .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "invalid path"))?; let r = unsafe { ((*shell.as_ptr()).set_cur_dir)(crate::ptr::null_mut(), p.as_mut_ptr()) }; if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } @@ -229,15 +229,15 @@ mod uefi_env { pub(crate) fn set(key: &OsStr, val: &OsStr) -> io::Result<()> { let mut key_ptr = helpers::os_string_to_raw(key) - .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid key"))?; let mut val_ptr = helpers::os_string_to_raw(val) - .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid value"))?; unsafe { set_raw(key_ptr.as_mut_ptr(), val_ptr.as_mut_ptr()) } } pub(crate) fn unset(key: &OsStr) -> io::Result<()> { let mut key_ptr = helpers::os_string_to_raw(key) - .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid key"))?; unsafe { set_raw(key_ptr.as_mut_ptr(), crate::ptr::null_mut()) } } @@ -267,7 +267,7 @@ mod uefi_env { }); // SAFETY: val.add(start) is always NULL terminated let val = unsafe { get_raw(shell, val.add(start)) } - .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid value"))?; vars.push((key, val)); start = i + 1; diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs index c73a6350357a..a47c8dbcaaaf 100644 --- a/library/std/src/sys/pal/uefi/process.rs +++ b/library/std/src/sys/pal/uefi/process.rs @@ -613,7 +613,7 @@ mod uefi_command_internal { OsString::from_wide(&self._buffer) .into_string() .map(Into::into) - .map_err(|_| const_error!(io::ErrorKind::Other, "utf8 conversion failed")) + .map_err(|_| const_error!(io::ErrorKind::Other, "UTF-8 conversion failed")) } extern "efiapi" fn reset( diff --git a/library/std/src/sys/pal/uefi/stdio.rs b/library/std/src/sys/pal/uefi/stdio.rs index d049d19bc83e..257e321dd03d 100644 --- a/library/std/src/sys/pal/uefi/stdio.rs +++ b/library/std/src/sys/pal/uefi/stdio.rs @@ -71,7 +71,7 @@ impl io::Read for Stdin { }; if ch.len() > 1 { - return Err(io::const_error!(io::ErrorKind::InvalidData, "invalid utf-16 sequence")); + return Err(io::const_error!(io::ErrorKind::InvalidData, "invalid UTF-16 sequence")); } match ch.pop().unwrap() { diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 78404b4afa79..3a238d160cb5 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -475,7 +475,7 @@ pub fn current_exe() -> io::Result { ); if result != libc::B_OK { use crate::io::ErrorKind; - Err(io::const_error!(ErrorKind::Uncategorized, "Error getting executable path")) + Err(io::const_error!(ErrorKind::Uncategorized, "error getting executable path")) } else { // find_path adds the null terminator. let name = CStr::from_ptr(name.as_ptr()).to_bytes(); @@ -492,7 +492,7 @@ pub fn current_exe() -> io::Result { #[cfg(target_os = "l4re")] pub fn current_exe() -> io::Result { use crate::io::ErrorKind; - Err(io::const_error!(ErrorKind::Unsupported, "Not yet implemented!")) + Err(io::const_error!(ErrorKind::Unsupported, "not yet implemented!")) } #[cfg(target_os = "vxworks")] diff --git a/library/std/src/sys/pal/unix/process/process_fuchsia.rs b/library/std/src/sys/pal/unix/process/process_fuchsia.rs index b7a35718757a..4ddc96356b99 100644 --- a/library/std/src/sys/pal/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/pal/unix/process/process_fuchsia.rs @@ -187,7 +187,7 @@ impl Process { if actual != 1 { return Err(io::const_error!( io::ErrorKind::InvalidData, - "Failed to get exit status of process", + "failed to get exit status of process", )); } Ok(ExitStatus(proc_info.return_code)) @@ -224,7 +224,7 @@ impl Process { if actual != 1 { return Err(io::const_error!( io::ErrorKind::InvalidData, - "Failed to get exit status of process", + "failed to get exit status of process", )); } Ok(Some(ExitStatus(proc_info.return_code))) diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index aa7406dd5487..1f3abd4cc128 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -1228,7 +1228,7 @@ mod linux_child_ext { .as_ref() // SAFETY: The os type is a transparent wrapper, therefore we can transmute references .map(|fd| unsafe { mem::transmute::<&imp::PidFd, &os::PidFd>(fd) }) - .ok_or_else(|| io::const_error!(ErrorKind::Uncategorized, "No pidfd was created.")) + .ok_or_else(|| io::const_error!(ErrorKind::Uncategorized, "no pidfd was created.")) } fn into_pidfd(mut self) -> Result { diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 4c5757b890ad..3dedc8d1257c 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -480,7 +480,7 @@ pub fn available_parallelism() -> io::Result> { unsafe { use libc::_syspage_ptr; if _syspage_ptr.is_null() { - Err(io::const_error!(io::ErrorKind::NotFound, "No syspage available")) + Err(io::const_error!(io::ErrorKind::NotFound, "no syspage available")) } else { let cpus = (*_syspage_ptr).num_cpu; NonZero::new(cpus as usize) @@ -520,7 +520,7 @@ pub fn available_parallelism() -> io::Result> { } } else { // FIXME: implement on Redox, l4re - Err(io::const_error!(io::ErrorKind::Unsupported, "Getting the number of hardware threads is not supported on the target platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "getting the number of hardware threads is not supported on the target platform")) } } } diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index e224980e95f3..0271626380c5 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -92,7 +92,7 @@ impl Timespec { if tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64 { Ok(unsafe { Self::new_unchecked(tv_sec, tv_nsec) }) } else { - Err(io::const_error!(io::ErrorKind::InvalidData, "Invalid timestamp")) + Err(io::const_error!(io::ErrorKind::InvalidData, "invalid timestamp")) } } diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index dce5a429cb0d..623a7d89ba5a 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -724,7 +724,7 @@ impl File { { return Err(io::const_error!( io::ErrorKind::InvalidInput, - "Cannot set file timestamp to 0", + "cannot set file timestamp to 0", )); } let is_max = |t: c::FILETIME| t.dwLowDateTime == u32::MAX && t.dwHighDateTime == u32::MAX; @@ -734,7 +734,7 @@ impl File { { return Err(io::const_error!( io::ErrorKind::InvalidInput, - "Cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF", + "cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF", )); } cvt(unsafe { diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs index 36158b0258a6..84153a9d05b5 100644 --- a/library/test/src/formatters/junit.rs +++ b/library/test/src/formatters/junit.rs @@ -39,15 +39,15 @@ fn str_to_cdata(s: &str) -> String { impl OutputFormatter for JunitFormatter { fn write_discovery_start(&mut self) -> io::Result<()> { - Err(io::const_error!(io::ErrorKind::NotFound, "Not yet implemented!")) + Err(io::const_error!(io::ErrorKind::NotFound, "not yet implemented!")) } fn write_test_discovered(&mut self, _desc: &TestDesc, _test_type: &str) -> io::Result<()> { - Err(io::const_error!(io::ErrorKind::NotFound, "Not yet implemented!")) + Err(io::const_error!(io::ErrorKind::NotFound, "not yet implemented!")) } fn write_discovery_finish(&mut self, _state: &ConsoleTestDiscoveryState) -> io::Result<()> { - Err(io::const_error!(io::ErrorKind::NotFound, "Not yet implemented!")) + Err(io::const_error!(io::ErrorKind::NotFound, "not yet implemented!")) } fn write_run_start( From 0972c3b56596b51f9cfdf99a5ad74c754e94d3aa Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Fri, 13 Dec 2024 17:40:07 +0000 Subject: [PATCH 476/991] Check for MSRV attributes in late passes using the HIR --- book/src/development/adding_lints.md | 31 ++-- clippy_config/src/conf.rs | 2 +- clippy_dev/src/main.rs | 6 +- clippy_dev/src/new_lint.rs | 82 ++++++----- clippy_utils/src/lib.rs | 17 +-- clippy_utils/src/msrvs.rs | 139 +++++++++++------- clippy_utils/src/paths.rs | 3 +- clippy_utils/src/qualify_min_const_fn.rs | 123 +++++++++------- .../ui-internal/invalid_msrv_attr_impl.fixed | 11 +- tests/ui-internal/invalid_msrv_attr_impl.rs | 8 +- .../ui-internal/invalid_msrv_attr_impl.stderr | 26 +--- .../ui/msrv_attributes_without_early_lints.rs | 12 ++ 12 files changed, 246 insertions(+), 214 deletions(-) create mode 100644 tests/ui/msrv_attributes_without_early_lints.rs diff --git a/book/src/development/adding_lints.md b/book/src/development/adding_lints.md index 60135e96c5a5..0b9010f01071 100644 --- a/book/src/development/adding_lints.md +++ b/book/src/development/adding_lints.md @@ -460,7 +460,7 @@ pub struct ManualStrip { impl ManualStrip { pub fn new(conf: &'static Conf) -> Self { - Self { msrv: conf.msrv.clone() } + Self { msrv: conf.msrv } } } ``` @@ -469,24 +469,13 @@ The project's MSRV can then be matched against the feature MSRV in the LintPass using the `Msrv::meets` method. ``` rust -if !self.msrv.meets(msrvs::STR_STRIP_PREFIX) { +if !self.msrv.meets(cx, msrvs::STR_STRIP_PREFIX) { return; } ``` -The project's MSRV can also be specified as an attribute, which overrides -the value from `clippy.toml`. This can be accounted for using the -`extract_msrv_attr!(LintContext)` macro and passing -`LateContext`/`EarlyContext`. - -```rust,ignore -impl<'tcx> LateLintPass<'tcx> for ManualStrip { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - ... - } - extract_msrv_attr!(LateContext); -} -``` +Early lint passes should instead use `MsrvStack` coupled with +`extract_msrv_attr!()` Once the `msrv` is added to the lint, a relevant test case should be added to the lint's test file, `tests/ui/manual_strip.rs` in this example. It should @@ -512,8 +501,16 @@ in `clippy_config/src/conf.rs`: ```rust define_Conf! { - /// Lint: LIST, OF, LINTS, . The minimum rust version that the project supports - (msrv: Option = None), + #[lints( + allow_attributes, + allow_attributes_without_reason, + .. + , + .. + unused_trait_names, + use_self, + )] + msrv: Msrv = Msrv::default(), ... } ``` diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index e4571204f46a..a61acbaa96bc 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -670,7 +670,7 @@ define_Conf! { unused_trait_names, use_self, )] - msrv: Msrv = Msrv::empty(), + msrv: Msrv = Msrv::default(), /// The minimum size (in bytes) to consider a type for passing by reference instead of by value. #[lints(large_types_passed_by_value)] pass_by_value_size_limit: u64 = 256, diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs index fcdee073f88d..074dea4ab77b 100644 --- a/clippy_dev/src/main.rs +++ b/clippy_dev/src/main.rs @@ -35,7 +35,7 @@ fn main() { category, r#type, msrv, - } => match new_lint::create(&pass, &name, &category, r#type.as_deref(), msrv) { + } => match new_lint::create(pass, &name, &category, r#type.as_deref(), msrv) { Ok(()) => update_lints::update(utils::UpdateMode::Change), Err(e) => eprintln!("Unable to create lint: {e}"), }, @@ -147,9 +147,9 @@ enum DevCommand { #[command(name = "new_lint")] /// Create a new lint and run `cargo dev update_lints` NewLint { - #[arg(short, long, value_parser = ["early", "late"], conflicts_with = "type", default_value = "late")] + #[arg(short, long, conflicts_with = "type", default_value = "late")] /// Specify whether the lint runs during the early or late pass - pass: String, + pass: new_lint::Pass, #[arg( short, long, diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index cf6e44245660..96e12706c9e2 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -1,13 +1,28 @@ use crate::utils::{clippy_project_root, clippy_version}; +use clap::ValueEnum; use indoc::{formatdoc, writedoc}; -use std::fmt::Write as _; +use std::fmt::{self, Write as _}; use std::fs::{self, OpenOptions}; -use std::io::prelude::*; +use std::io::{self, Write as _}; use std::path::{Path, PathBuf}; -use std::{fmt, io}; + +#[derive(Clone, Copy, PartialEq, ValueEnum)] +pub enum Pass { + Early, + Late, +} + +impl fmt::Display for Pass { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Pass::Early => "early", + Pass::Late => "late", + }) + } +} struct LintData<'a> { - pass: &'a str, + pass: Pass, name: &'a str, category: &'a str, ty: Option<&'a str>, @@ -35,7 +50,7 @@ impl Context for io::Result { /// # Errors /// /// This function errors out if the files couldn't be created or written to. -pub fn create(pass: &str, name: &str, category: &str, mut ty: Option<&str>, msrv: bool) -> io::Result<()> { +pub fn create(pass: Pass, name: &str, category: &str, mut ty: Option<&str>, msrv: bool) -> io::Result<()> { if category == "cargo" && ty.is_none() { // `cargo` is a special category, these lints should always be in `clippy_lints/src/cargo` ty = Some("cargo"); @@ -56,7 +71,7 @@ pub fn create(pass: &str, name: &str, category: &str, mut ty: Option<&str>, msrv add_lint(&lint, msrv).context("Unable to add lint to clippy_lints/src/lib.rs")?; } - if pass == "early" { + if pass == Pass::Early { println!( "\n\ NOTE: Use a late pass unless you need something specific from\n\ @@ -136,23 +151,17 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> { let mut lib_rs = fs::read_to_string(path).context("reading")?; let comment_start = lib_rs.find("// add lints here,").expect("Couldn't find comment"); + let ctor_arg = if lint.pass == Pass::Late { "_" } else { "" }; + let lint_pass = lint.pass; + let module_name = lint.name; + let camel_name = to_camel_case(lint.name); let new_lint = if enable_msrv { format!( "store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(conf)));\n ", - lint_pass = lint.pass, - ctor_arg = if lint.pass == "late" { "_" } else { "" }, - module_name = lint.name, - camel_name = to_camel_case(lint.name), ) } else { - format!( - "store.register_{lint_pass}_pass(|{ctor_arg}| Box::new({module_name}::{camel_name}));\n ", - lint_pass = lint.pass, - ctor_arg = if lint.pass == "late" { "_" } else { "" }, - module_name = lint.name, - camel_name = to_camel_case(lint.name), - ) + format!("store.register_{lint_pass}_pass(|{ctor_arg}| Box::new({module_name}::{camel_name}));\n ",) }; lib_rs.insert_str(comment_start, &new_lint); @@ -242,11 +251,16 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { let mut result = String::new(); let (pass_type, pass_lifetimes, pass_import, context_import) = match lint.pass { - "early" => ("EarlyLintPass", "", "use rustc_ast::ast::*;", "EarlyContext"), - "late" => ("LateLintPass", "<'_>", "use rustc_hir::*;", "LateContext"), - _ => { - unreachable!("`pass_type` should only ever be `early` or `late`!"); - }, + Pass::Early => ("EarlyLintPass", "", "use rustc_ast::ast::*;", "EarlyContext"), + Pass::Late => ("LateLintPass", "<'_>", "use rustc_hir::*;", "LateContext"), + }; + let (msrv_ty, msrv_ctor, extract_msrv) = match lint.pass { + Pass::Early => ( + "MsrvStack", + "MsrvStack::new(conf.msrv)", + "\n extract_msrv_attr!();\n", + ), + Pass::Late => ("Msrv", "conf.msrv", ""), }; let lint_name = lint.name; @@ -258,10 +272,10 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { let _: fmt::Result = writedoc!( result, r" - use clippy_utils::msrvs::{{self, Msrv}}; + use clippy_utils::msrvs::{{self, {msrv_ty}}}; use clippy_config::Conf; {pass_import} - use rustc_lint::{{{context_import}, {pass_type}, LintContext}}; + use rustc_lint::{{{context_import}, {pass_type}}}; use rustc_session::impl_lint_pass; " @@ -285,20 +299,18 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { result, r" pub struct {name_camel} {{ - msrv: Msrv, + msrv: {msrv_ty}, }} impl {name_camel} {{ pub fn new(conf: &'static Conf) -> Self {{ - Self {{ msrv: conf.msrv.clone() }} + Self {{ msrv: {msrv_ctor} }} }} }} impl_lint_pass!({name_camel} => [{name_upper}]); - impl {pass_type}{pass_lifetimes} for {name_camel} {{ - extract_msrv_attr!({context_import}); - }} + impl {pass_type}{pass_lifetimes} for {name_camel} {{{extract_msrv}}} // TODO: Add MSRV level to `clippy_config/src/msrvs.rs` if needed. // TODO: Update msrv config comment in `clippy_config/src/conf.rs` @@ -375,9 +387,9 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R let mod_file_path = ty_dir.join("mod.rs"); let context_import = setup_mod_file(&mod_file_path, lint)?; - let pass_lifetimes = match context_import { - "LateContext" => "<'_>", - _ => "", + let (pass_lifetimes, msrv_ty, msrv_ref, msrv_cx) = match context_import { + "LateContext" => ("<'_>", "Msrv", "", "cx, "), + _ => ("", "MsrvStack", "&", ""), }; let name_upper = lint.name.to_uppercase(); @@ -387,14 +399,14 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R let _: fmt::Result = writedoc!( lint_file_contents, r#" - use clippy_utils::msrvs::{{self, Msrv}}; + use clippy_utils::msrvs::{{self, {msrv_ty}}}; use rustc_lint::{{{context_import}, LintContext}}; use super::{name_upper}; // TODO: Adjust the parameters as necessary - pub(super) fn check(cx: &{context_import}{pass_lifetimes}, msrv: &Msrv) {{ - if !msrv.meets(todo!("Add a new entry in `clippy_utils/src/msrvs`")) {{ + pub(super) fn check(cx: &{context_import}{pass_lifetimes}, msrv: {msrv_ref}{msrv_ty}) {{ + if !msrv.meets({msrv_cx}todo!("Add a new entry in `clippy_utils/src/msrvs`")) {{ return; }} todo!(); diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 3e9429399b31..ba7346979460 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -137,24 +137,13 @@ use rustc_middle::hir::nested_filter; #[macro_export] macro_rules! extract_msrv_attr { - (LateContext) => { - fn check_attributes(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) { + () => { + fn check_attributes(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); self.msrv.check_attributes(sess, attrs); } - fn check_attributes_post(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) { - let sess = rustc_lint::LintContext::sess(cx); - self.msrv.check_attributes_post(sess, attrs); - } - }; - (EarlyContext) => { - fn check_attributes(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) { - let sess = rustc_lint::LintContext::sess(cx); - self.msrv.check_attributes(sess, attrs); - } - - fn check_attributes_post(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) { + fn check_attributes_post(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); self.msrv.check_attributes_post(sess, attrs); } diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index f9cf29cbdf46..5bb2b12988a6 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -1,11 +1,14 @@ +use rustc_ast::Attribute; use rustc_ast::attr::AttributeExt; use rustc_attr_parsing::{RustcVersion, parse_version}; +use rustc_lint::LateContext; use rustc_session::Session; use rustc_span::{Symbol, sym}; use serde::Deserialize; -use smallvec::{SmallVec, smallvec}; -use std::fmt; +use smallvec::SmallVec; +use std::iter::once; +use std::sync::atomic::{AtomicBool, Ordering}; macro_rules! msrv_aliases { ($($major:literal,$minor:literal,$patch:literal { @@ -73,21 +76,15 @@ msrv_aliases! { 1,15,0 { MAYBE_BOUND_IN_WHERE } } -/// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]` -#[derive(Debug, Clone)] -pub struct Msrv { - stack: SmallVec<[RustcVersion; 2]>, -} +/// `#[clippy::msrv]` attributes are rarely used outside of Clippy's test suite, as a basic +/// optimization we can skip traversing the HIR in [`Msrv::meets`] if we never saw an MSRV attribute +/// during the early lint passes +static SEEN_MSRV_ATTR: AtomicBool = AtomicBool::new(false); -impl fmt::Display for Msrv { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(msrv) = self.current() { - write!(f, "{msrv}") - } else { - f.write_str("1.0.0") - } - } -} +/// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]` in late +/// lint passes, use [`MsrvStack`] for early passes +#[derive(Copy, Clone, Debug, Default)] +pub struct Msrv(Option); impl<'de> Deserialize<'de> for Msrv { fn deserialize(deserializer: D) -> Result @@ -96,14 +93,36 @@ impl<'de> Deserialize<'de> for Msrv { { let v = String::deserialize(deserializer)?; parse_version(Symbol::intern(&v)) - .map(|v| Msrv { stack: smallvec![v] }) + .map(|v| Self(Some(v))) .ok_or_else(|| serde::de::Error::custom("not a valid Rust version")) } } impl Msrv { - pub fn empty() -> Msrv { - Msrv { stack: SmallVec::new() } + /// Returns the MSRV at the current node + /// + /// If the crate being linted uses an `#[clippy::msrv]` attribute this will search the parent + /// nodes for that attribute, prefer to run this check after cheaper pattern matching operations + pub fn current(self, cx: &LateContext<'_>) -> Option { + if SEEN_MSRV_ATTR.load(Ordering::Relaxed) { + let start = cx.last_node_with_lint_attrs; + if let Some(msrv_attr) = once(start) + .chain(cx.tcx.hir_parent_id_iter(start)) + .find_map(|id| parse_attrs(cx.tcx.sess, cx.tcx.hir().attrs(id))) + { + return Some(msrv_attr); + } + } + + self.0 + } + + /// Checks if a required version from [this module](self) is met at the current node + /// + /// If the crate being linted uses an `#[clippy::msrv]` attribute this will search the parent + /// nodes for that attribute, prefer to run this check after cheaper pattern matching operations + pub fn meets(self, cx: &LateContext<'_>, required: RustcVersion) -> bool { + self.current(cx).is_none_or(|msrv| msrv >= required) } pub fn read_cargo(&mut self, sess: &Session) { @@ -111,8 +130,8 @@ impl Msrv { .ok() .and_then(|v| parse_version(Symbol::intern(&v))); - match (self.current(), cargo_msrv) { - (None, Some(cargo_msrv)) => self.stack = smallvec![cargo_msrv], + match (self.0, cargo_msrv) { + (None, Some(cargo_msrv)) => self.0 = Some(cargo_msrv), (Some(clippy_msrv), Some(cargo_msrv)) => { if clippy_msrv != cargo_msrv { sess.dcx().warn(format!( @@ -123,6 +142,21 @@ impl Msrv { _ => {}, } } +} + +/// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]` in early +/// lint passes, use [`Msrv`] for late passes +#[derive(Debug, Clone)] +pub struct MsrvStack { + stack: SmallVec<[RustcVersion; 2]>, +} + +impl MsrvStack { + pub fn new(initial: Msrv) -> Self { + Self { + stack: SmallVec::from_iter(initial.0), + } + } pub fn current(&self) -> Option { self.stack.last().copied() @@ -132,42 +166,43 @@ impl Msrv { self.current().is_none_or(|msrv| msrv >= required) } - fn parse_attr(sess: &Session, attrs: &[impl AttributeExt]) -> Option { - let sym_msrv = Symbol::intern("msrv"); - let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv])); - - if let Some(msrv_attr) = msrv_attrs.next() { - if let Some(duplicate) = msrv_attrs.next_back() { - sess.dcx() - .struct_span_err(duplicate.span(), "`clippy::msrv` is defined multiple times") - .with_span_note(msrv_attr.span(), "first definition found here") - .emit(); - } - - if let Some(msrv) = msrv_attr.value_str() { - if let Some(version) = parse_version(msrv) { - return Some(version); - } - - sess.dcx() - .span_err(msrv_attr.span(), format!("`{msrv}` is not a valid Rust version")); - } else { - sess.dcx().span_err(msrv_attr.span(), "bad clippy attribute"); - } - } - - None - } - - pub fn check_attributes(&mut self, sess: &Session, attrs: &[impl AttributeExt]) { - if let Some(version) = Self::parse_attr(sess, attrs) { + pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) { + if let Some(version) = parse_attrs(sess, attrs) { + SEEN_MSRV_ATTR.store(true, Ordering::Relaxed); self.stack.push(version); } } - pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[impl AttributeExt]) { - if Self::parse_attr(sess, attrs).is_some() { + pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) { + if parse_attrs(sess, attrs).is_some() { self.stack.pop(); } } } + +fn parse_attrs(sess: &Session, attrs: &[impl AttributeExt]) -> Option { + let sym_msrv = Symbol::intern("msrv"); + let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv])); + + if let Some(msrv_attr) = msrv_attrs.next() { + if let Some(duplicate) = msrv_attrs.next_back() { + sess.dcx() + .struct_span_err(duplicate.span(), "`clippy::msrv` is defined multiple times") + .with_span_note(msrv_attr.span(), "first definition found here") + .emit(); + } + + if let Some(msrv) = msrv_attr.value_str() { + if let Some(version) = parse_version(msrv) { + return Some(version); + } + + sess.dcx() + .span_err(msrv_attr.span(), format!("`{msrv}` is not a valid Rust version")); + } else { + sess.dcx().span_err(msrv_attr.span(), "bad clippy attribute"); + } + } + + None +} diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 452bb4ce4c77..51d06ad9b1aa 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -19,7 +19,6 @@ pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"]; pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"]; pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"]; pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"]; -pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"]; pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"]; pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"]; pub const SYMBOL_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Symbol", "as_str"]; @@ -33,7 +32,7 @@ pub const IO_ERROR_NEW: [&str; 5] = ["std", "io", "error", "Error", "new"]; pub const IO_ERRORKIND_OTHER: [&str; 5] = ["std", "io", "error", "ErrorKind", "Other"]; // Paths in clippy itself -pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"]; +pub const MSRV_STACK: [&str; 3] = ["clippy_utils", "msrvs", "MsrvStack"]; // Paths in external crates #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index c7890f33f27e..8e6f4d4a317e 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -11,6 +11,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::Obligation; +use rustc_lint::LateContext; use rustc_middle::mir::{ Body, CastKind, NonDivergingIntrinsic, NullOp, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, @@ -25,16 +26,16 @@ use std::borrow::Cow; type McfResult = Result<(), (Span, Cow<'static, str>)>; -pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) -> McfResult { +pub fn is_min_const_fn<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, msrv: Msrv) -> McfResult { let def_id = body.source.def_id(); for local in &body.local_decls { - check_ty(tcx, local.ty, local.source_info.span, msrv)?; + check_ty(cx, local.ty, local.source_info.span, msrv)?; } // impl trait is gone in MIR, so check the return type manually check_ty( - tcx, - tcx.fn_sig(def_id).instantiate_identity().output().skip_binder(), + cx, + cx.tcx.fn_sig(def_id).instantiate_identity().output().skip_binder(), body.local_decls.iter().next().unwrap().source_info.span, msrv, )?; @@ -43,16 +44,16 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) // Cleanup blocks are ignored entirely by const eval, so we can too: // https://github.com/rust-lang/rust/blob/1dea922ea6e74f99a0e97de5cdb8174e4dea0444/compiler/rustc_const_eval/src/transform/check_consts/check.rs#L382 if !bb.is_cleanup { - check_terminator(tcx, body, bb.terminator(), msrv)?; + check_terminator(cx, body, bb.terminator(), msrv)?; for stmt in &bb.statements { - check_statement(tcx, body, def_id, stmt, msrv)?; + check_statement(cx, body, def_id, stmt, msrv)?; } } } Ok(()) } -fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, msrv: &Msrv) -> McfResult { +fn check_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, msrv: Msrv) -> McfResult { for arg in ty.walk() { let ty = match arg.unpack() { GenericArgKind::Type(ty) => ty, @@ -63,7 +64,7 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, msrv: &Msrv) -> M }; match ty.kind() { - ty::Ref(_, _, hir::Mutability::Mut) if !msrv.meets(msrvs::CONST_MUT_REFS) => { + ty::Ref(_, _, hir::Mutability::Mut) if !msrv.meets(cx, msrvs::CONST_MUT_REFS) => { return Err((span, "mutable references in const fn are unstable".into())); }, ty::Alias(ty::Opaque, ..) => return Err((span, "`impl Trait` in const fn is unstable".into())), @@ -82,7 +83,7 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, msrv: &Msrv) -> M )); }, ty::ExistentialPredicate::Trait(trait_ref) => { - if Some(trait_ref.def_id) != tcx.lang_items().sized_trait() { + if Some(trait_ref.def_id) != cx.tcx.lang_items().sized_trait() { return Err(( span, "trait bounds other than `Sized` \ @@ -101,19 +102,19 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, msrv: &Msrv) -> M } fn check_rvalue<'tcx>( - tcx: TyCtxt<'tcx>, + cx: &LateContext<'tcx>, body: &Body<'tcx>, def_id: DefId, rvalue: &Rvalue<'tcx>, span: Span, - msrv: &Msrv, + msrv: Msrv, ) -> McfResult { match rvalue { Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())), Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => { - check_place(tcx, *place, span, body, msrv) + check_place(cx, *place, span, body, msrv) }, - Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv), + Rvalue::CopyForDeref(place) => check_place(cx, *place, span, body, msrv), Rvalue::Repeat(operand, _) | Rvalue::Use(operand) | Rvalue::WrapUnsafeBinder(operand, _) @@ -128,7 +129,7 @@ fn check_rvalue<'tcx>( | CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, _), operand, _, - ) => check_operand(tcx, operand, span, body, msrv), + ) => check_operand(cx, operand, span, body, msrv), Rvalue::Cast( CastKind::PointerCoercion( PointerCoercion::UnsafeFnPointer @@ -144,9 +145,11 @@ fn check_rvalue<'tcx>( // We cannot allow this for now. return Err((span, "unsizing casts are only allowed for references right now".into())); }; - let unsized_ty = tcx.struct_tail_for_codegen(pointee_ty, ty::TypingEnv::post_analysis(tcx, def_id)); + let unsized_ty = cx + .tcx + .struct_tail_for_codegen(pointee_ty, ty::TypingEnv::post_analysis(cx.tcx, def_id)); if let ty::Slice(_) | ty::Str = unsized_ty.kind() { - check_operand(tcx, op, span, body, msrv)?; + check_operand(cx, op, span, body, msrv)?; // Casting/coercing things to slices is fine. Ok(()) } else { @@ -167,9 +170,9 @@ fn check_rvalue<'tcx>( )), // binops are fine on integers Rvalue::BinaryOp(_, box (lhs, rhs)) => { - check_operand(tcx, lhs, span, body, msrv)?; - check_operand(tcx, rhs, span, body, msrv)?; - let ty = lhs.ty(body, tcx); + check_operand(cx, lhs, span, body, msrv)?; + check_operand(cx, rhs, span, body, msrv)?; + let ty = lhs.ty(body, cx.tcx); if ty.is_integral() || ty.is_bool() || ty.is_char() { Ok(()) } else { @@ -185,16 +188,16 @@ fn check_rvalue<'tcx>( ) | Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::UnaryOp(_, operand) => { - let ty = operand.ty(body, tcx); + let ty = operand.ty(body, cx.tcx); if ty.is_integral() || ty.is_bool() { - check_operand(tcx, operand, span, body, msrv) + check_operand(cx, operand, span, body, msrv) } else { Err((span, "only int and `bool` operations are stable in const fn".into())) } }, Rvalue::Aggregate(_, operands) => { for operand in operands { - check_operand(tcx, operand, span, body, msrv)?; + check_operand(cx, operand, span, body, msrv)?; } Ok(()) }, @@ -202,33 +205,33 @@ fn check_rvalue<'tcx>( } fn check_statement<'tcx>( - tcx: TyCtxt<'tcx>, + cx: &LateContext<'tcx>, body: &Body<'tcx>, def_id: DefId, statement: &Statement<'tcx>, - msrv: &Msrv, + msrv: Msrv, ) -> McfResult { let span = statement.source_info.span; match &statement.kind { StatementKind::Assign(box (place, rval)) => { - check_place(tcx, *place, span, body, msrv)?; - check_rvalue(tcx, body, def_id, rval, span, msrv) + check_place(cx, *place, span, body, msrv)?; + check_rvalue(cx, body, def_id, rval, span, msrv) }, - StatementKind::FakeRead(box (_, place)) => check_place(tcx, *place, span, body, msrv), + StatementKind::FakeRead(box (_, place)) => check_place(cx, *place, span, body, msrv), // just an assignment StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => { - check_place(tcx, **place, span, body, msrv) + check_place(cx, **place, span, body, msrv) }, - StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => check_operand(tcx, op, span, body, msrv), + StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => check_operand(cx, op, span, body, msrv), StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping( rustc_middle::mir::CopyNonOverlapping { dst, src, count }, )) => { - check_operand(tcx, dst, span, body, msrv)?; - check_operand(tcx, src, span, body, msrv)?; - check_operand(tcx, count, span, body, msrv) + check_operand(cx, dst, span, body, msrv)?; + check_operand(cx, src, span, body, msrv)?; + check_operand(cx, count, span, body, msrv) }, // These are all NOPs StatementKind::StorageLive(_) @@ -244,16 +247,16 @@ fn check_statement<'tcx>( } fn check_operand<'tcx>( - tcx: TyCtxt<'tcx>, + cx: &LateContext<'tcx>, operand: &Operand<'tcx>, span: Span, body: &Body<'tcx>, - msrv: &Msrv, + msrv: Msrv, ) -> McfResult { match operand { Operand::Move(place) => { if !place.projection.as_ref().is_empty() - && !is_ty_const_destruct(tcx, place.ty(&body.local_decls, tcx).ty, body) + && !is_ty_const_destruct(cx.tcx, place.ty(&body.local_decls, cx.tcx).ty, body) { return Err(( span, @@ -261,29 +264,35 @@ fn check_operand<'tcx>( )); } - check_place(tcx, *place, span, body, msrv) + check_place(cx, *place, span, body, msrv) }, - Operand::Copy(place) => check_place(tcx, *place, span, body, msrv), - Operand::Constant(c) => match c.check_static_ptr(tcx) { + Operand::Copy(place) => check_place(cx, *place, span, body, msrv), + Operand::Constant(c) => match c.check_static_ptr(cx.tcx) { Some(_) => Err((span, "cannot access `static` items in const fn".into())), None => Ok(()), }, } } -fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &Body<'tcx>, msrv: &Msrv) -> McfResult { +fn check_place<'tcx>( + cx: &LateContext<'tcx>, + place: Place<'tcx>, + span: Span, + body: &Body<'tcx>, + msrv: Msrv, +) -> McfResult { for (base, elem) in place.as_ref().iter_projections() { match elem { ProjectionElem::Field(..) => { - if base.ty(body, tcx).ty.is_union() && !msrv.meets(msrvs::CONST_FN_UNION) { + if base.ty(body, cx.tcx).ty.is_union() && !msrv.meets(cx, msrvs::CONST_FN_UNION) { return Err((span, "accessing union fields is unstable".into())); } }, - ProjectionElem::Deref => match base.ty(body, tcx).ty.kind() { + ProjectionElem::Deref => match base.ty(body, cx.tcx).ty.kind() { ty::RawPtr(_, hir::Mutability::Mut) => { return Err((span, "dereferencing raw mut pointer in const fn is unstable".into())); }, - ty::RawPtr(_, hir::Mutability::Not) if !msrv.meets(msrvs::CONST_RAW_PTR_DEREF) => { + ty::RawPtr(_, hir::Mutability::Not) if !msrv.meets(cx, msrvs::CONST_RAW_PTR_DEREF) => { return Err((span, "dereferencing raw const pointer in const fn is unstable".into())); }, _ => (), @@ -302,10 +311,10 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B } fn check_terminator<'tcx>( - tcx: TyCtxt<'tcx>, + cx: &LateContext<'tcx>, body: &Body<'tcx>, terminator: &Terminator<'tcx>, - msrv: &Msrv, + msrv: Msrv, ) -> McfResult { let span = terminator.source_info.span; match &terminator.kind { @@ -317,7 +326,7 @@ fn check_terminator<'tcx>( | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Unreachable => Ok(()), TerminatorKind::Drop { place, .. } => { - if !is_ty_const_destruct(tcx, place.ty(&body.local_decls, tcx).ty, body) { + if !is_ty_const_destruct(cx.tcx, place.ty(&body.local_decls, cx.tcx).ty, body) { return Err(( span, "cannot drop locals with a non constant destructor in const fn".into(), @@ -325,7 +334,7 @@ fn check_terminator<'tcx>( } Ok(()) }, - TerminatorKind::SwitchInt { discr, targets: _ } => check_operand(tcx, discr, span, body, msrv), + TerminatorKind::SwitchInt { discr, targets: _ } => check_operand(cx, discr, span, body, msrv), TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } => { Err((span, "const fn coroutines are unstable".into())) }, @@ -339,9 +348,9 @@ fn check_terminator<'tcx>( fn_span: _, } | TerminatorKind::TailCall { func, args, fn_span: _ } => { - let fn_ty = func.ty(body, tcx); + let fn_ty = func.ty(body, cx.tcx); if let ty::FnDef(fn_def_id, _) = *fn_ty.kind() { - if !is_stable_const_fn(tcx, fn_def_id, msrv) { + if !is_stable_const_fn(cx, fn_def_id, msrv) { return Err(( span, format!( @@ -356,17 +365,17 @@ fn check_terminator<'tcx>( // within const fns. `transmute` is allowed in all other const contexts. // This won't really scale to more intrinsics or functions. Let's allow const // transmutes in const fn before we add more hacks to this. - if tcx.is_intrinsic(fn_def_id, sym::transmute) { + if cx.tcx.is_intrinsic(fn_def_id, sym::transmute) { return Err(( span, "can only call `transmute` from const items, not `const fn`".into(), )); } - check_operand(tcx, func, span, body, msrv)?; + check_operand(cx, func, span, body, msrv)?; for arg in args { - check_operand(tcx, &arg.node, span, body, msrv)?; + check_operand(cx, &arg.node, span, body, msrv)?; } Ok(()) } else { @@ -379,14 +388,14 @@ fn check_terminator<'tcx>( msg: _, target: _, unwind: _, - } => check_operand(tcx, cond, span, body, msrv), + } => check_operand(cx, cond, span, body, msrv), TerminatorKind::InlineAsm { .. } => Err((span, "cannot use inline assembly in const fn".into())), } } -fn is_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool { - tcx.is_const_fn(def_id) - && tcx.lookup_const_stability(def_id).is_none_or(|const_stab| { +fn is_stable_const_fn(cx: &LateContext<'_>, def_id: DefId, msrv: Msrv) -> bool { + cx.tcx.is_const_fn(def_id) + && cx.tcx.lookup_const_stability(def_id).is_none_or(|const_stab| { if let rustc_attr_parsing::StabilityLevel::Stable { since, .. } = const_stab.level { // Checking MSRV is manually necessary because `rustc` has no such concept. This entire // function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`. @@ -398,10 +407,10 @@ fn is_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool { StableSince::Err => return false, }; - msrv.meets(const_stab_rust_version) + msrv.meets(cx, const_stab_rust_version) } else { // Unstable const fn, check if the feature is enabled. - tcx.features().enabled(const_stab.feature) && msrv.current().is_none() + cx.tcx.features().enabled(const_stab.feature) && msrv.current(cx).is_none() } }) } diff --git a/tests/ui-internal/invalid_msrv_attr_impl.fixed b/tests/ui-internal/invalid_msrv_attr_impl.fixed index 928596d08091..7011ef518f20 100644 --- a/tests/ui-internal/invalid_msrv_attr_impl.fixed +++ b/tests/ui-internal/invalid_msrv_attr_impl.fixed @@ -9,7 +9,7 @@ extern crate rustc_middle; #[macro_use] extern crate rustc_session; use clippy_utils::extract_msrv_attr; -use clippy_utils::msrvs::Msrv; +use clippy_utils::msrvs::MsrvStack; use rustc_hir::Expr; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; @@ -20,18 +20,13 @@ declare_lint! { } struct Pass { - msrv: Msrv, + msrv: MsrvStack, } impl_lint_pass!(Pass => [TEST_LINT]); -impl LateLintPass<'_> for Pass { - extract_msrv_attr!(LateContext); - fn check_expr(&mut self, _: &LateContext<'_>, _: &Expr<'_>) {} -} - impl EarlyLintPass for Pass { - extract_msrv_attr!(EarlyContext); + extract_msrv_attr!(); fn check_expr(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Expr) {} } diff --git a/tests/ui-internal/invalid_msrv_attr_impl.rs b/tests/ui-internal/invalid_msrv_attr_impl.rs index 50b28648ccc9..323061decd23 100644 --- a/tests/ui-internal/invalid_msrv_attr_impl.rs +++ b/tests/ui-internal/invalid_msrv_attr_impl.rs @@ -9,7 +9,7 @@ extern crate rustc_middle; #[macro_use] extern crate rustc_session; use clippy_utils::extract_msrv_attr; -use clippy_utils::msrvs::Msrv; +use clippy_utils::msrvs::MsrvStack; use rustc_hir::Expr; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; @@ -20,15 +20,11 @@ declare_lint! { } struct Pass { - msrv: Msrv, + msrv: MsrvStack, } impl_lint_pass!(Pass => [TEST_LINT]); -impl LateLintPass<'_> for Pass { - fn check_expr(&mut self, _: &LateContext<'_>, _: &Expr<'_>) {} -} - impl EarlyLintPass for Pass { fn check_expr(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Expr) {} } diff --git a/tests/ui-internal/invalid_msrv_attr_impl.stderr b/tests/ui-internal/invalid_msrv_attr_impl.stderr index 8b69af122e45..8ba42e4bb2b2 100644 --- a/tests/ui-internal/invalid_msrv_attr_impl.stderr +++ b/tests/ui-internal/invalid_msrv_attr_impl.stderr @@ -1,8 +1,8 @@ -error: `extract_msrv_attr!` macro missing from `LateLintPass` implementation +error: `extract_msrv_attr!` macro missing from `EarlyLintPass` implementation --> tests/ui-internal/invalid_msrv_attr_impl.rs:28:1 | -LL | impl LateLintPass<'_> for Pass { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl EarlyLintPass for Pass { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> tests/ui-internal/invalid_msrv_attr_impl.rs:1:9 @@ -10,23 +10,11 @@ note: the lint level is defined here LL | #![deny(clippy::internal)] | ^^^^^^^^^^^^^^^^ = note: `#[deny(clippy::missing_msrv_attr_impl)]` implied by `#[deny(clippy::internal)]` -help: add `extract_msrv_attr!(LateContext)` to the `LateLintPass` implementation +help: add `extract_msrv_attr!()` to the `EarlyLintPass` implementation | -LL ~ impl LateLintPass<'_> for Pass { -LL + extract_msrv_attr!(LateContext); +LL + impl EarlyLintPass for Pass { +LL + extract_msrv_attr!(); | -error: `extract_msrv_attr!` macro missing from `EarlyLintPass` implementation - --> tests/ui-internal/invalid_msrv_attr_impl.rs:32:1 - | -LL | impl EarlyLintPass for Pass { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add `extract_msrv_attr!(EarlyContext)` to the `EarlyLintPass` implementation - | -LL ~ impl EarlyLintPass for Pass { -LL + extract_msrv_attr!(EarlyContext); - | - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/msrv_attributes_without_early_lints.rs b/tests/ui/msrv_attributes_without_early_lints.rs new file mode 100644 index 000000000000..dec62c15079d --- /dev/null +++ b/tests/ui/msrv_attributes_without_early_lints.rs @@ -0,0 +1,12 @@ +#![allow(clippy::all, clippy::pedantic, clippy::restriction, clippy::nursery)] +#![forbid(clippy::ptr_as_ptr)] + +/// MSRV checking in late passes skips checking the parent nodes if no early pass sees a +/// `#[clippy::msrv]` attribute +/// +/// Here we ensure that even if all early passes are allowed (above) the attribute is still detected +/// in late lints such as `clippy::ptr_as_ptr` +#[clippy::msrv = "1.37"] +fn f(p: *const i32) { + let _ = p as *const i64; +} From 5b0004c45fae362f50e9e587f7a16249501d07f8 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Sat, 18 Jan 2025 17:41:57 +0000 Subject: [PATCH 477/991] Migrate `clippy_lints` to new MSRV API --- clippy_lints/src/almost_complete_range.rs | 8 +-- clippy_lints/src/approx_const.rs | 8 +-- clippy_lints/src/assigning_clones.rs | 8 +-- clippy_lints/src/attrs/deprecated_cfg_attr.rs | 4 +- clippy_lints/src/attrs/mod.rs | 22 +++---- clippy_lints/src/attrs/repr_attributes.rs | 11 +--- clippy_lints/src/booleans.rs | 22 +++---- clippy_lints/src/casts/borrow_as_ptr.rs | 4 +- .../src/casts/cast_abs_to_unsigned.rs | 6 +- clippy_lints/src/casts/cast_lossless.rs | 6 +- .../src/casts/cast_slice_different_sizes.rs | 9 +-- .../src/casts/cast_slice_from_raw_parts.rs | 6 +- clippy_lints/src/casts/mod.rs | 24 +++---- clippy_lints/src/casts/ptr_as_ptr.rs | 7 +- clippy_lints/src/casts/ptr_cast_constness.rs | 4 +- clippy_lints/src/checked_conversions.rs | 8 +-- clippy_lints/src/derivable_impls.rs | 8 +-- clippy_lints/src/format_args.rs | 10 ++- clippy_lints/src/from_over_into.rs | 10 +-- clippy_lints/src/functions/mod.rs | 10 ++- clippy_lints/src/functions/result.rs | 10 +-- clippy_lints/src/if_then_some_else_none.rs | 10 +-- clippy_lints/src/implicit_saturating_sub.rs | 16 ++--- clippy_lints/src/incompatible_msrv.rs | 39 +++++------ clippy_lints/src/index_refutable_slice.rs | 6 +- clippy_lints/src/instant_subtraction.rs | 8 +-- clippy_lints/src/legacy_numeric_constants.rs | 12 ++-- clippy_lints/src/lifetimes.rs | 27 +++----- clippy_lints/src/lines_filter_map_ok.rs | 10 +-- clippy_lints/src/loops/explicit_iter_loop.rs | 13 ++-- clippy_lints/src/loops/manual_flatten.rs | 4 +- clippy_lints/src/loops/manual_slice_fill.rs | 8 +-- clippy_lints/src/loops/mod.rs | 12 ++-- clippy_lints/src/loops/same_item_push.rs | 6 +- clippy_lints/src/manual_bits.rs | 8 +-- clippy_lints/src/manual_clamp.rs | 14 ++-- clippy_lints/src/manual_div_ceil.rs | 11 +--- clippy_lints/src/manual_float_methods.rs | 8 +-- clippy_lints/src/manual_hash_one.rs | 8 +-- clippy_lints/src/manual_is_ascii_check.rs | 10 +-- clippy_lints/src/manual_let_else.rs | 2 +- clippy_lints/src/manual_main_separator_str.rs | 8 +-- clippy_lints/src/manual_non_exhaustive.rs | 6 +- clippy_lints/src/manual_option_as_slice.rs | 45 +++++++------ clippy_lints/src/manual_rem_euclid.rs | 10 +-- clippy_lints/src/manual_retain.rs | 26 ++++---- clippy_lints/src/manual_strip.rs | 9 +-- clippy_lints/src/matches/collapsible_match.rs | 8 +-- clippy_lints/src/matches/mod.rs | 28 ++++---- clippy_lints/src/matches/redundant_guards.rs | 6 +- clippy_lints/src/mem_replace.rs | 20 +++--- .../src/methods/cloned_instead_of_copied.rs | 6 +- clippy_lints/src/methods/err_expect.rs | 7 +- clippy_lints/src/methods/filter_map_next.rs | 4 +- clippy_lints/src/methods/io_other_error.rs | 6 +- .../src/methods/is_digit_ascii_radix.rs | 10 +-- clippy_lints/src/methods/iter_kv_map.rs | 4 +- .../src/methods/manual_c_str_literals.rs | 8 +-- clippy_lints/src/methods/manual_inspect.rs | 6 +- .../src/methods/manual_is_variant_and.rs | 4 +- clippy_lints/src/methods/manual_repeat_n.rs | 6 +- clippy_lints/src/methods/manual_try_fold.rs | 4 +- clippy_lints/src/methods/map_clone.rs | 6 +- clippy_lints/src/methods/map_unwrap_or.rs | 4 +- .../map_with_unused_argument_over_ranges.rs | 6 +- clippy_lints/src/methods/mod.rs | 64 +++++++++---------- .../src/methods/option_as_ref_deref.rs | 8 +-- .../src/methods/option_map_unwrap_or.rs | 8 +-- .../src/methods/path_ends_with_ext.rs | 4 +- clippy_lints/src/methods/str_splitn.rs | 4 +- .../src/methods/string_lit_chars_any.rs | 6 +- .../src/methods/unnecessary_map_or.rs | 6 +- .../src/methods/unnecessary_to_owned.rs | 6 +- .../methods/useless_nonzero_new_unchecked.rs | 6 +- clippy_lints/src/missing_const_for_fn.rs | 26 ++++---- .../src/missing_const_for_thread_local.rs | 16 ++--- .../src/needless_borrows_for_generic_args.rs | 10 ++- clippy_lints/src/non_std_lazy_statics.rs | 34 +++------- clippy_lints/src/operators/manual_midpoint.rs | 10 +-- clippy_lints/src/operators/mod.rs | 6 +- clippy_lints/src/question_mark.rs | 3 +- clippy_lints/src/ranges.rs | 7 +- clippy_lints/src/redundant_field_names.rs | 9 +-- .../src/redundant_static_lifetimes.rs | 8 +-- clippy_lints/src/repeat_vec_with_capacity.rs | 13 ++-- clippy_lints/src/std_instead_of_core.rs | 12 ++-- clippy_lints/src/string_patterns.rs | 12 ++-- clippy_lints/src/trait_bounds.rs | 8 +-- clippy_lints/src/transmute/mod.rs | 16 ++--- .../src/transmute/transmute_float_to_int.rs | 4 +- .../src/transmute/transmute_int_to_float.rs | 4 +- .../src/transmute/transmute_num_to_bytes.rs | 5 +- .../src/transmute/transmute_ptr_to_ptr.rs | 6 +- .../src/transmute/transmute_ptr_to_ref.rs | 6 +- clippy_lints/src/tuple_array_conversions.rs | 8 +-- clippy_lints/src/unnested_or_patterns.rs | 8 +-- clippy_lints/src/unused_trait_names.rs | 10 +-- clippy_lints/src/use_self.rs | 10 ++- .../utils/internal_lints/msrv_attr_impl.rs | 13 ++-- clippy_lints/src/vec.rs | 6 +- .../ui-internal/invalid_msrv_attr_impl.stderr | 2 +- .../ui/msrv_attributes_without_early_lints.rs | 2 + 102 files changed, 430 insertions(+), 640 deletions(-) diff --git a/clippy_lints/src/almost_complete_range.rs b/clippy_lints/src/almost_complete_range.rs index 0f7f779e8ea7..4f55968d5625 100644 --- a/clippy_lints/src/almost_complete_range.rs +++ b/clippy_lints/src/almost_complete_range.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::msrvs::{self, MsrvStack}; use clippy_utils::source::{trim_span, walk_span_to_context}; use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits}; use rustc_errors::Applicability; @@ -31,12 +31,12 @@ declare_clippy_lint! { impl_lint_pass!(AlmostCompleteRange => [ALMOST_COMPLETE_RANGE]); pub struct AlmostCompleteRange { - msrv: Msrv, + msrv: MsrvStack, } impl AlmostCompleteRange { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: MsrvStack::new(conf.msrv), } } } @@ -96,7 +96,7 @@ impl EarlyLintPass for AlmostCompleteRange { } } - extract_msrv_attr!(EarlyContext); + extract_msrv_attr!(); } fn is_incomplete_range(start: &Expr, end: &Expr) -> bool { diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs index fbcd49f00184..9ae746c13b26 100644 --- a/clippy_lints/src/approx_const.rs +++ b/clippy_lints/src/approx_const.rs @@ -69,9 +69,7 @@ pub struct ApproxConstant { impl ApproxConstant { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -89,8 +87,6 @@ impl LateLintPass<'_> for ApproxConstant { _ => (), } } - - extract_msrv_attr!(LateContext); } impl ApproxConstant { @@ -98,7 +94,7 @@ impl ApproxConstant { let s = s.as_str(); if s.parse::().is_ok() { for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS { - if is_approx_const(constant, s, min_digits) && msrv.is_none_or(|msrv| self.msrv.meets(msrv)) { + if is_approx_const(constant, s, min_digits) && msrv.is_none_or(|msrv| self.msrv.meets(cx, msrv)) { span_lint_and_help( cx, APPROX_CONSTANT, diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs index 348495f97a27..ab34af7c3174 100644 --- a/clippy_lints/src/assigning_clones.rs +++ b/clippy_lints/src/assigning_clones.rs @@ -59,9 +59,7 @@ pub struct AssigningClones { impl AssigningClones { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -90,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones { sym::clone if is_diag_trait_item(cx, fn_id, sym::Clone) => CloneTrait::Clone, _ if fn_name.as_str() == "to_owned" && is_diag_trait_item(cx, fn_id, sym::ToOwned) - && self.msrv.meets(msrvs::CLONE_INTO) => + && self.msrv.meets(cx, msrvs::CLONE_INTO) => { CloneTrait::ToOwned }, @@ -143,8 +141,6 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones { ); } } - - extract_msrv_attr!(LateContext); } /// Checks if the data being cloned borrows from the place that is being assigned to: diff --git a/clippy_lints/src/attrs/deprecated_cfg_attr.rs b/clippy_lints/src/attrs/deprecated_cfg_attr.rs index 3a462018e3e0..cd38aed26a3e 100644 --- a/clippy_lints/src/attrs/deprecated_cfg_attr.rs +++ b/clippy_lints/src/attrs/deprecated_cfg_attr.rs @@ -1,12 +1,12 @@ use super::{Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR, unnecessary_clippy_cfg}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::msrvs::{self, MsrvStack}; use rustc_ast::AttrStyle; use rustc_errors::Applicability; use rustc_lint::EarlyContext; use rustc_span::sym; -pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &Msrv) { +pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) { // check cfg_attr if attr.has_name(sym::cfg_attr) && let Some(items) = attr.meta_item_list() diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index e0aab8c95a8e..2b59c218d57a 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -14,7 +14,7 @@ mod useless_attribute; mod utils; use clippy_config::Conf; -use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::msrvs::{self, Msrv, MsrvStack}; use rustc_ast::{self as ast, Attribute, MetaItemInner, MetaItemKind}; use rustc_hir::{ImplItem, Item, TraitItem}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; @@ -459,9 +459,7 @@ impl_lint_pass!(Attributes => [ impl Attributes { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -471,7 +469,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { if is_relevant_item(cx, item) { inline_always::check(cx, item.span, item.ident.name, attrs); } - repr_attributes::check(cx, item.span, attrs, &self.msrv); + repr_attributes::check(cx, item.span, attrs, self.msrv); } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { @@ -485,18 +483,16 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())); } } - - extract_msrv_attr!(LateContext); } pub struct EarlyAttributes { - msrv: Msrv, + msrv: MsrvStack, } impl EarlyAttributes { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: MsrvStack::new(conf.msrv), } } } @@ -515,17 +511,17 @@ impl EarlyLintPass for EarlyAttributes { non_minimal_cfg::check(cx, attr); } - extract_msrv_attr!(EarlyContext); + extract_msrv_attr!(); } pub struct PostExpansionEarlyAttributes { - msrv: Msrv, + msrv: MsrvStack, } impl PostExpansionEarlyAttributes { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: MsrvStack::new(conf.msrv), } } } @@ -589,5 +585,5 @@ impl EarlyLintPass for PostExpansionEarlyAttributes { duplicated_attributes::check(cx, &item.attrs); } - extract_msrv_attr!(EarlyContext); + extract_msrv_attr!(); } diff --git a/clippy_lints/src/attrs/repr_attributes.rs b/clippy_lints/src/attrs/repr_attributes.rs index 3efb8bd3ff00..e5cfbaf952a7 100644 --- a/clippy_lints/src/attrs/repr_attributes.rs +++ b/clippy_lints/src/attrs/repr_attributes.rs @@ -4,17 +4,11 @@ use rustc_lint::LateContext; use rustc_span::Span; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs; +use clippy_utils::msrvs::{self, Msrv}; use super::REPR_PACKED_WITHOUT_ABI; -pub(super) fn check(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute], msrv: &msrvs::Msrv) { - if msrv.meets(msrvs::REPR_RUST) { - check_packed(cx, item_span, attrs); - } -} - -fn check_packed(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute]) { +pub(super) fn check(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute], msrv: Msrv) { if let Some(reprs) = find_attr!(attrs, AttributeKind::Repr(r) => r) { let packed_span = reprs .iter() @@ -25,6 +19,7 @@ fn check_packed(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute]) { && !reprs .iter() .any(|(x, _)| *x == ReprAttr::ReprC || *x == ReprAttr::ReprRust) + && msrv.meets(cx, msrvs::REPR_RUST) { span_lint_and_then( cx, diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index f57f56f3efdc..48b5d4da8886 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -85,9 +85,7 @@ pub struct NonminimalBool { impl NonminimalBool { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -103,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool { _: Span, _: LocalDefId, ) { - NonminimalBoolVisitor { cx, msrv: &self.msrv }.visit_body(body); + NonminimalBoolVisitor { cx, msrv: self.msrv }.visit_body(body); } fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { @@ -120,8 +118,6 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool { _ => {}, } } - - extract_msrv_attr!(LateContext); } fn inverted_bin_op_eq_str(op: BinOpKind) -> Option<&'static str> { @@ -198,7 +194,7 @@ fn check_inverted_bool_in_condition( ); } -fn check_simplify_not(cx: &LateContext<'_>, msrv: &Msrv, expr: &Expr<'_>) { +fn check_simplify_not(cx: &LateContext<'_>, msrv: Msrv, expr: &Expr<'_>) { if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind && !expr.span.from_expansion() && !inner.span.from_expansion() @@ -234,7 +230,7 @@ fn check_simplify_not(cx: &LateContext<'_>, msrv: &Msrv, expr: &Expr<'_>) { struct NonminimalBoolVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, - msrv: &'a Msrv, + msrv: Msrv, } use quine_mc_cluskey::Bool; @@ -327,7 +323,7 @@ impl<'v> Hir2Qmm<'_, '_, 'v> { struct SuggestContext<'a, 'tcx, 'v> { terminals: &'v [&'v Expr<'v>], cx: &'a LateContext<'tcx>, - msrv: &'a Msrv, + msrv: Msrv, output: String, } @@ -398,7 +394,7 @@ impl SuggestContext<'_, '_, '_> { } } -fn simplify_not(cx: &LateContext<'_>, curr_msrv: &Msrv, expr: &Expr<'_>) -> Option { +fn simplify_not(cx: &LateContext<'_>, curr_msrv: Msrv, expr: &Expr<'_>) -> Option { match &expr.kind { ExprKind::Binary(binop, lhs, rhs) => { if !implements_ord(cx, lhs) { @@ -440,7 +436,9 @@ fn simplify_not(cx: &LateContext<'_>, curr_msrv: &Msrv, expr: &Expr<'_>) -> Opti .iter() .copied() .flat_map(|(msrv, a, b)| vec![(msrv, a, b), (msrv, b, a)]) - .find(|&(msrv, a, _)| msrv.is_none_or(|msrv| curr_msrv.meets(msrv)) && a == path.ident.name.as_str()) + .find(|&(msrv, a, _)| { + a == path.ident.name.as_str() && msrv.is_none_or(|msrv| curr_msrv.meets(cx, msrv)) + }) .and_then(|(_, _, neg_method)| { let negated_args = args .iter() @@ -469,7 +467,7 @@ fn simplify_not(cx: &LateContext<'_>, curr_msrv: &Msrv, expr: &Expr<'_>) -> Opti } } -fn suggest(cx: &LateContext<'_>, msrv: &Msrv, suggestion: &Bool, terminals: &[&Expr<'_>]) -> String { +fn suggest(cx: &LateContext<'_>, msrv: Msrv, suggestion: &Bool, terminals: &[&Expr<'_>]) -> String { let mut suggest_context = SuggestContext { terminals, cx, diff --git a/clippy_lints/src/casts/borrow_as_ptr.rs b/clippy_lints/src/casts/borrow_as_ptr.rs index 6057144bc6a4..d143629da3a0 100644 --- a/clippy_lints/src/casts/borrow_as_ptr.rs +++ b/clippy_lints/src/casts/borrow_as_ptr.rs @@ -16,7 +16,7 @@ pub(super) fn check<'tcx>( expr: &'tcx Expr<'_>, cast_expr: &'tcx Expr<'_>, cast_to: &'tcx Ty<'_>, - msrv: &Msrv, + msrv: Msrv, ) -> bool { if matches!(cast_to.kind, TyKind::Ptr(_)) && let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind @@ -34,7 +34,7 @@ pub(super) fn check<'tcx>( return false; } - let (suggestion, span) = if msrv.meets(msrvs::RAW_REF_OP) { + let (suggestion, span) = if msrv.meets(cx, msrvs::RAW_REF_OP) { let operator_kind = match mutability { Mutability::Not => "const", Mutability::Mut => "mut", diff --git a/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/clippy_lints/src/casts/cast_abs_to_unsigned.rs index ae433773193a..8b3529e84fc6 100644 --- a/clippy_lints/src/casts/cast_abs_to_unsigned.rs +++ b/clippy_lints/src/casts/cast_abs_to_unsigned.rs @@ -14,13 +14,13 @@ pub(super) fn check( cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>, - msrv: &Msrv, + msrv: Msrv, ) { - if msrv.meets(msrvs::UNSIGNED_ABS) - && let ty::Int(from) = cast_from.kind() + if let ty::Int(from) = cast_from.kind() && let ty::Uint(to) = cast_to.kind() && let ExprKind::MethodCall(method_path, receiver, [], _) = cast_expr.kind && method_path.ident.name.as_str() == "abs" + && msrv.meets(cx, msrvs::UNSIGNED_ABS) { let span = if from.bit_width() == to.bit_width() { expr.span diff --git a/clippy_lints/src/casts/cast_lossless.rs b/clippy_lints/src/casts/cast_lossless.rs index c326a0d935c7..3ae43732dc03 100644 --- a/clippy_lints/src/casts/cast_lossless.rs +++ b/clippy_lints/src/casts/cast_lossless.rs @@ -19,7 +19,7 @@ pub(super) fn check( cast_from: Ty<'_>, cast_to: Ty<'_>, cast_to_hir: &rustc_hir::Ty<'_>, - msrv: &Msrv, + msrv: Msrv, ) { if !should_lint(cx, cast_from, cast_to, msrv) { return; @@ -70,7 +70,7 @@ pub(super) fn check( ); } -fn should_lint(cx: &LateContext<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>, msrv: &Msrv) -> bool { +fn should_lint(cx: &LateContext<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>, msrv: Msrv) -> bool { // Do not suggest using From in consts/statics until it is valid to do so (see #2267). if is_in_const_context(cx) { return false; @@ -96,7 +96,7 @@ fn should_lint(cx: &LateContext<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>, msrv: & }; !is_isize_or_usize(cast_from) && from_nbits < to_nbits }, - (false, true) if matches!(cast_from.kind(), ty::Bool) && msrv.meets(msrvs::FROM_BOOL) => true, + (false, true) if matches!(cast_from.kind(), ty::Bool) && msrv.meets(cx, msrvs::FROM_BOOL) => true, (_, _) => { matches!(cast_from.kind(), ty::Float(FloatTy::F32)) && matches!(cast_to.kind(), ty::Float(FloatTy::F64)) }, diff --git a/clippy_lints/src/casts/cast_slice_different_sizes.rs b/clippy_lints/src/casts/cast_slice_different_sizes.rs index 030c2d322db6..c48f253606dc 100644 --- a/clippy_lints/src/casts/cast_slice_different_sizes.rs +++ b/clippy_lints/src/casts/cast_slice_different_sizes.rs @@ -9,12 +9,7 @@ use rustc_middle::ty::{self, Ty, TypeAndMut}; use super::CAST_SLICE_DIFFERENT_SIZES; -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv) { - // suggestion is invalid if `ptr::slice_from_raw_parts` does not exist - if !msrv.meets(msrvs::PTR_SLICE_RAW_PARTS) { - return; - } - +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Msrv) { // if this cast is the child of another cast expression then don't emit something for it, the full // chain will be analyzed if is_child_of_cast(cx, expr) { @@ -30,7 +25,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv if let (Ok(from_layout), Ok(to_layout)) = (cx.layout_of(start_ty.ty), cx.layout_of(end_ty.ty)) { let from_size = from_layout.size.bytes(); let to_size = to_layout.size.bytes(); - if from_size != to_size && from_size != 0 && to_size != 0 { + if from_size != to_size && from_size != 0 && to_size != 0 && msrv.meets(cx, msrvs::PTR_SLICE_RAW_PARTS) { span_lint_and_then( cx, CAST_SLICE_DIFFERENT_SIZES, diff --git a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs index c3bc5c0c9f2a..46b0c88d3fed 100644 --- a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs +++ b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs @@ -23,9 +23,8 @@ fn raw_parts_kind(cx: &LateContext<'_>, did: DefId) -> Option { } } -pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>, msrv: &Msrv) { - if msrv.meets(msrvs::PTR_SLICE_RAW_PARTS) - && let ty::RawPtr(ptrty, _) = cast_to.kind() +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>, msrv: Msrv) { + if let ty::RawPtr(ptrty, _) = cast_to.kind() && let ty::Slice(_) = ptrty.kind() && let ExprKind::Call(fun, [ptr_arg, len_arg]) = cast_expr.peel_blocks().kind && let ExprKind::Path(ref qpath) = fun.kind @@ -33,6 +32,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, && let Some(rpk) = raw_parts_kind(cx, fun_def_id) && let ctxt = expr.span.ctxt() && cast_expr.span.ctxt() == ctxt + && msrv.meets(cx, msrvs::PTR_SLICE_RAW_PARTS) { let func = match rpk { RawPartsKind::Immutable => "from_raw_parts", diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 3701f9eb5e86..dc2a1fa85bf5 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -765,9 +765,7 @@ pub struct Casts { impl Casts { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -817,8 +815,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts { if !expr.span.from_expansion() && unnecessary_cast::check(cx, expr, cast_from_expr, cast_from, cast_to) { return; } - cast_slice_from_raw_parts::check(cx, expr, cast_from_expr, cast_to, &self.msrv); - ptr_cast_constness::check(cx, expr, cast_from_expr, cast_from, cast_to, &self.msrv); + cast_slice_from_raw_parts::check(cx, expr, cast_from_expr, cast_to, self.msrv); + ptr_cast_constness::check(cx, expr, cast_from_expr, cast_from, cast_to, self.msrv); as_ptr_cast_mut::check(cx, expr, cast_from_expr, cast_to); fn_to_numeric_cast_any::check(cx, expr, cast_from_expr, cast_from, cast_to); fn_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to); @@ -831,29 +829,27 @@ impl<'tcx> LateLintPass<'tcx> for Casts { cast_possible_wrap::check(cx, expr, cast_from, cast_to); cast_precision_loss::check(cx, expr, cast_from, cast_to); cast_sign_loss::check(cx, expr, cast_from_expr, cast_from, cast_to); - cast_abs_to_unsigned::check(cx, expr, cast_from_expr, cast_from, cast_to, &self.msrv); + cast_abs_to_unsigned::check(cx, expr, cast_from_expr, cast_from, cast_to, self.msrv); cast_nan_to_int::check(cx, expr, cast_from_expr, cast_from, cast_to); } - cast_lossless::check(cx, expr, cast_from_expr, cast_from, cast_to, cast_to_hir, &self.msrv); + cast_lossless::check(cx, expr, cast_from_expr, cast_from, cast_to, cast_to_hir, self.msrv); cast_enum_constructor::check(cx, expr, cast_from_expr, cast_from); } as_underscore::check(cx, expr, cast_to_hir); as_pointer_underscore::check(cx, cast_to, cast_to_hir); - let was_borrow_as_ptr_emitted = self.msrv.meets(msrvs::BORROW_AS_PTR) - && borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir, &self.msrv); - if self.msrv.meets(msrvs::PTR_FROM_REF) && !was_borrow_as_ptr_emitted { + let was_borrow_as_ptr_emitted = self.msrv.meets(cx, msrvs::BORROW_AS_PTR) + && borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir, self.msrv); + if !was_borrow_as_ptr_emitted && self.msrv.meets(cx, msrvs::PTR_FROM_REF) { ref_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir); } } cast_ptr_alignment::check(cx, expr); char_lit_as_u8::check(cx, expr); - ptr_as_ptr::check(cx, expr, &self.msrv); - cast_slice_different_sizes::check(cx, expr, &self.msrv); + ptr_as_ptr::check(cx, expr, self.msrv); + cast_slice_different_sizes::check(cx, expr, self.msrv); ptr_cast_constness::check_null_ptr_cast_method(cx, expr); } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/casts/ptr_as_ptr.rs b/clippy_lints/src/casts/ptr_as_ptr.rs index bdc389d39dd3..d57e391b55d5 100644 --- a/clippy_lints/src/casts/ptr_as_ptr.rs +++ b/clippy_lints/src/casts/ptr_as_ptr.rs @@ -26,11 +26,7 @@ impl OmitFollowedCastReason<'_> { } } -pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) { - if !msrv.meets(msrvs::POINTER_CAST) { - return; - } - +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Msrv) { if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind && let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr)) && let ty::RawPtr(_, from_mutbl) = cast_from.kind() @@ -40,6 +36,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) { // The `U` in `pointer::cast` have to be `Sized` // as explained here: https://github.com/rust-lang/rust/issues/60602. && to_pointee_ty.is_sized(cx.tcx, cx.typing_env()) + && msrv.meets(cx, msrvs::POINTER_CAST) { let mut app = Applicability::MachineApplicable; let turbofish = match &cast_to_hir_ty.kind { diff --git a/clippy_lints/src/casts/ptr_cast_constness.rs b/clippy_lints/src/casts/ptr_cast_constness.rs index 945c05ee9436..cad9c1df273f 100644 --- a/clippy_lints/src/casts/ptr_cast_constness.rs +++ b/clippy_lints/src/casts/ptr_cast_constness.rs @@ -16,7 +16,7 @@ pub(super) fn check<'tcx>( cast_expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>, - msrv: &Msrv, + msrv: Msrv, ) { if let ty::RawPtr(from_ty, from_mutbl) = cast_from.kind() && let ty::RawPtr(to_ty, to_mutbl) = cast_to.kind() @@ -52,7 +52,7 @@ pub(super) fn check<'tcx>( return; } - if msrv.meets(msrvs::POINTER_CAST_CONSTNESS) { + if msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS) { let sugg = Sugg::hir(cx, cast_expr, "_"); let constness = match *to_mutbl { Mutability::Not => "const", diff --git a/clippy_lints/src/checked_conversions.rs b/clippy_lints/src/checked_conversions.rs index 9516af7334d7..b36c8662289c 100644 --- a/clippy_lints/src/checked_conversions.rs +++ b/clippy_lints/src/checked_conversions.rs @@ -39,9 +39,7 @@ pub struct CheckedConversions { impl CheckedConversions { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -65,7 +63,6 @@ impl LateLintPass<'_> for CheckedConversions { } && !item.span.in_external_macro(cx.sess().source_map()) && !is_in_const_context(cx) - && self.msrv.meets(msrvs::TRY_FROM) && let Some(cv) = match op2 { // todo: check for case signed -> larger unsigned == only x >= 0 None => check_upper_bound(lt1, gt1).filter(|cv| cv.cvt == ConversionType::FromUnsigned), @@ -79,6 +76,7 @@ impl LateLintPass<'_> for CheckedConversions { }, } && let Some(to_type) = cv.to_type + && self.msrv.meets(cx, msrvs::TRY_FROM) { let mut applicability = Applicability::MachineApplicable; let snippet = snippet_with_applicability(cx, cv.expr_to_cast.span, "_", &mut applicability); @@ -93,8 +91,6 @@ impl LateLintPass<'_> for CheckedConversions { ); } } - - extract_msrv_attr!(LateContext); } /// Contains the result of a tried conversion check diff --git a/clippy_lints/src/derivable_impls.rs b/clippy_lints/src/derivable_impls.rs index bb445e0155f6..66a3e5e3d3c7 100644 --- a/clippy_lints/src/derivable_impls.rs +++ b/clippy_lints/src/derivable_impls.rs @@ -62,9 +62,7 @@ pub struct DerivableImpls { impl DerivableImpls { pub fn new(conf: &'static Conf) -> Self { - DerivableImpls { - msrv: conf.msrv.clone(), - } + DerivableImpls { msrv: conf.msrv } } } @@ -205,11 +203,9 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { { if adt_def.is_struct() { check_struct(cx, item, self_ty, func_expr, adt_def, args, cx.tcx.typeck_body(*b)); - } else if adt_def.is_enum() && self.msrv.meets(msrvs::DEFAULT_ENUM_ATTRIBUTE) { + } else if adt_def.is_enum() && self.msrv.meets(cx, msrvs::DEFAULT_ENUM_ATTRIBUTE) { check_enum(cx, item, func_expr, adt_def); } } } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/format_args.rs b/clippy_lints/src/format_args.rs index 1ba355938b68..fc5f76179f90 100644 --- a/clippy_lints/src/format_args.rs +++ b/clippy_lints/src/format_args.rs @@ -215,7 +215,7 @@ impl<'tcx> FormatArgs<'tcx> { let ty_msrv_map = make_ty_msrv_map(tcx); Self { format_args, - msrv: conf.msrv.clone(), + msrv: conf.msrv, ignore_mixed: conf.allow_mixed_uninlined_format_args, ty_msrv_map, } @@ -240,13 +240,11 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs<'tcx> { linter.check_templates(); - if self.msrv.meets(msrvs::FORMAT_ARGS_CAPTURE) { + if self.msrv.meets(cx, msrvs::FORMAT_ARGS_CAPTURE) { linter.check_uninlined_args(); } } } - - extract_msrv_attr!(LateContext); } struct FormatArgsExpr<'a, 'tcx> { @@ -542,7 +540,7 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> { let ty = ty.peel_refs(); if let Some(msrv) = self.ty_msrv_map.get(&ty) - && msrv.is_none_or(|msrv| self.msrv.meets(msrv)) + && msrv.is_none_or(|msrv| self.msrv.meets(self.cx, msrv)) { return true; } @@ -553,7 +551,7 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> { && implements_trait(self.cx, ty, deref_trait_id, &[]) && let Some(target_ty) = self.cx.get_associated_type(ty, deref_trait_id, "Target") && let Some(msrv) = self.ty_msrv_map.get(&target_ty) - && msrv.is_none_or(|msrv| self.msrv.meets(msrv)) + && msrv.is_none_or(|msrv| self.msrv.meets(self.cx, msrv)) { return true; } diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs index 41bf6e81916a..6da5567d9c70 100644 --- a/clippy_lints/src/from_over_into.rs +++ b/clippy_lints/src/from_over_into.rs @@ -58,9 +58,7 @@ pub struct FromOverInto { impl FromOverInto { pub fn new(conf: &'static Conf) -> Self { - FromOverInto { - msrv: conf.msrv.clone(), - } + FromOverInto { msrv: conf.msrv } } } @@ -77,12 +75,12 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { && let Some(into_trait_seg) = hir_trait_ref.path.segments.last() // `impl Into for self_ty` && let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args - && self.msrv.meets(msrvs::RE_REBALANCING_COHERENCE) && span_is_local(item.span) && let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id) - .map(ty::EarlyBinder::instantiate_identity) + .map(ty::EarlyBinder::instantiate_identity) && cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id) && !matches!(middle_trait_ref.args.type_at(1).kind(), ty::Alias(ty::Opaque, _)) + && self.msrv.meets(cx, msrvs::RE_REBALANCING_COHERENCE) { span_lint_and_then( cx, @@ -114,8 +112,6 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { ); } } - - extract_msrv_attr!(LateContext); } /// Finds the occurrences of `Self` and `self` diff --git a/clippy_lints/src/functions/mod.rs b/clippy_lints/src/functions/mod.rs index 243eb5cbfd40..5f3fc5100e75 100644 --- a/clippy_lints/src/functions/mod.rs +++ b/clippy_lints/src/functions/mod.rs @@ -471,7 +471,7 @@ impl Functions { .iter() .flat_map(|p| def_path_def_ids(tcx, &p.split("::").collect::>())) .collect(), - msrv: conf.msrv.clone(), + msrv: conf.msrv, } } } @@ -521,12 +521,12 @@ impl<'tcx> LateLintPass<'tcx> for Functions { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { must_use::check_item(cx, item); - result::check_item(cx, item, self.large_error_threshold, &self.msrv); + result::check_item(cx, item, self.large_error_threshold, self.msrv); } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { must_use::check_impl_item(cx, item); - result::check_impl_item(cx, item, self.large_error_threshold, &self.msrv); + result::check_impl_item(cx, item, self.large_error_threshold, self.msrv); impl_trait_in_params::check_impl_item(cx, item); renamed_function_params::check_impl_item(cx, item, &self.trait_ids); } @@ -535,10 +535,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions { too_many_arguments::check_trait_item(cx, item, self.too_many_arguments_threshold); not_unsafe_ptr_arg_deref::check_trait_item(cx, item); must_use::check_trait_item(cx, item); - result::check_trait_item(cx, item, self.large_error_threshold, &self.msrv); + result::check_trait_item(cx, item, self.large_error_threshold, self.msrv); impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api); ref_option::check_trait_item(cx, item, self.avoid_breaking_exported_api); } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/functions/result.rs b/clippy_lints/src/functions/result.rs index 74d365a72556..cade56f58226 100644 --- a/clippy_lints/src/functions/result.rs +++ b/clippy_lints/src/functions/result.rs @@ -34,7 +34,7 @@ fn result_err_ty<'tcx>( } } -pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64, msrv: &Msrv) { +pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64, msrv: Msrv) { if let hir::ItemKind::Fn { ref sig, .. } = item.kind && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span) { @@ -50,7 +50,7 @@ pub(super) fn check_impl_item<'tcx>( cx: &LateContext<'tcx>, item: &hir::ImplItem<'tcx>, large_err_threshold: u64, - msrv: &Msrv, + msrv: Msrv, ) { // Don't lint if method is a trait's implementation, we can't do anything about those if let hir::ImplItemKind::Fn(ref sig, _) = item.kind @@ -69,7 +69,7 @@ pub(super) fn check_trait_item<'tcx>( cx: &LateContext<'tcx>, item: &hir::TraitItem<'tcx>, large_err_threshold: u64, - msrv: &Msrv, + msrv: Msrv, ) { if let hir::TraitItemKind::Fn(ref sig, _) = item.kind { let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); @@ -82,8 +82,8 @@ pub(super) fn check_trait_item<'tcx>( } } -fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: Span, msrv: &Msrv) { - if err_ty.is_unit() && (!is_no_std_crate(cx) || msrv.meets(msrvs::ERROR_IN_CORE)) { +fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: Span, msrv: Msrv) { + if err_ty.is_unit() && (!is_no_std_crate(cx) || msrv.meets(cx, msrvs::ERROR_IN_CORE)) { span_lint_and_help( cx, RESULT_UNIT_ERR, diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs index 28e6344186fa..fbbd33efd02d 100644 --- a/clippy_lints/src/if_then_some_else_none.rs +++ b/clippy_lints/src/if_then_some_else_none.rs @@ -54,9 +54,7 @@ pub struct IfThenSomeElseNone { impl IfThenSomeElseNone { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -79,10 +77,10 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { && !is_else_clause(cx.tcx, expr) && !is_in_const_context(cx) && !expr.span.in_external_macro(cx.sess().source_map()) - && self.msrv.meets(msrvs::BOOL_THEN) + && self.msrv.meets(cx, msrvs::BOOL_THEN) && !contains_return(then_block.stmts) { - let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(msrvs::BOOL_THEN_SOME) { + let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) { "then_some" } else { "then" @@ -120,6 +118,4 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { ); } } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs index 152d506a7c00..f2d16ff2e564 100644 --- a/clippy_lints/src/implicit_saturating_sub.rs +++ b/clippy_lints/src/implicit_saturating_sub.rs @@ -83,9 +83,7 @@ impl_lint_pass!(ImplicitSaturatingSub => [IMPLICIT_SATURATING_SUB, INVERTED_SATU impl ImplicitSaturatingSub { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -108,12 +106,10 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub { && let ExprKind::Binary(ref cond_op, cond_left, cond_right) = cond.kind { check_manual_check( - cx, expr, cond_op, cond_left, cond_right, if_block, else_block, &self.msrv, + cx, expr, cond_op, cond_left, cond_right, if_block, else_block, self.msrv, ); } } - - extract_msrv_attr!(LateContext); } #[allow(clippy::too_many_arguments)] @@ -125,7 +121,7 @@ fn check_manual_check<'tcx>( right_hand: &Expr<'tcx>, if_block: &Expr<'tcx>, else_block: &Expr<'tcx>, - msrv: &Msrv, + msrv: Msrv, ) { let ty = cx.typeck_results().expr_ty(left_hand); if ty.is_numeric() && !ty.is_signed() { @@ -178,7 +174,7 @@ fn check_gt( little_var: &Expr<'_>, if_block: &Expr<'_>, else_block: &Expr<'_>, - msrv: &Msrv, + msrv: Msrv, is_composited: bool, ) { if let Some(big_var) = Var::new(big_var) @@ -221,7 +217,7 @@ fn check_subtraction( little_var: Var, if_block: &Expr<'_>, else_block: &Expr<'_>, - msrv: &Msrv, + msrv: Msrv, is_composited: bool, ) { let if_block = peel_blocks(if_block); @@ -258,7 +254,7 @@ fn check_subtraction( // if `snippet_opt` fails, it won't try the next conditions. if let Some(big_var_snippet) = snippet_opt(cx, big_var.span) && let Some(little_var_snippet) = snippet_opt(cx, little_var.span) - && (!is_in_const_context(cx) || msrv.meets(msrvs::SATURATING_SUB_CONST)) + && (!is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST)) { let sugg = format!( "{}{big_var_snippet}.saturating_sub({little_var_snippet}){}", diff --git a/clippy_lints/src/incompatible_msrv.rs b/clippy_lints/src/incompatible_msrv.rs index 26df41e42a60..12dfb14c454d 100644 --- a/clippy_lints/src/incompatible_msrv.rs +++ b/clippy_lints/src/incompatible_msrv.rs @@ -50,7 +50,7 @@ impl_lint_pass!(IncompatibleMsrv => [INCOMPATIBLE_MSRV]); impl IncompatibleMsrv { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: conf.msrv, is_above_msrv: FxHashMap::default(), check_in_tests: conf.check_incompatible_msrv_in_tests, } @@ -88,39 +88,30 @@ impl IncompatibleMsrv { // We don't check local items since their MSRV is supposed to always be valid. return; } - let version = self.get_def_id_version(cx.tcx, def_id); - if self.msrv.meets(version) || (!self.check_in_tests && is_in_test(cx.tcx, node)) { - return; - } if let ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) = span.ctxt().outer_expn_data().kind { // Desugared expressions get to cheat and stability is ignored. // Intentionally not using `.from_expansion()`, since we do still care about macro expansions return; } - self.emit_lint_for(cx, span, version); - } - - fn emit_lint_for(&self, cx: &LateContext<'_>, span: Span, version: RustcVersion) { - span_lint( - cx, - INCOMPATIBLE_MSRV, - span, - format!( - "current MSRV (Minimum Supported Rust Version) is `{}` but this item is stable since `{version}`", - self.msrv - ), - ); + if (self.check_in_tests || !is_in_test(cx.tcx, node)) + && let Some(current) = self.msrv.current(cx) + && let version = self.get_def_id_version(cx.tcx, def_id) + && version > current + { + span_lint( + cx, + INCOMPATIBLE_MSRV, + span, + format!( + "current MSRV (Minimum Supported Rust Version) is `{current}` but this item is stable since `{version}`" + ), + ); + } } } impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv { - extract_msrv_attr!(LateContext); - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { - if self.msrv.current().is_none() { - // If there is no MSRV, then no need to check anything... - return; - } match expr.kind { ExprKind::MethodCall(_, _, _, span) => { if let Some(method_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs index deac51ab4c49..d53e139de014 100644 --- a/clippy_lints/src/index_refutable_slice.rs +++ b/clippy_lints/src/index_refutable_slice.rs @@ -62,7 +62,7 @@ impl IndexRefutableSlice { pub fn new(conf: &'static Conf) -> Self { Self { max_suggested_slice: conf.max_suggested_slice_pattern_length, - msrv: conf.msrv.clone(), + msrv: conf.msrv, } } } @@ -74,19 +74,17 @@ impl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice { if let Some(IfLet { let_pat, if_then, .. }) = IfLet::hir(cx, expr) && (!expr.span.from_expansion() || is_expn_of(expr.span, "if_chain").is_some()) && !is_lint_allowed(cx, INDEX_REFUTABLE_SLICE, expr.hir_id) - && self.msrv.meets(msrvs::SLICE_PATTERNS) && let found_slices = find_slice_values(cx, let_pat) && !found_slices.is_empty() && let filtered_slices = filter_lintable_slices(cx, found_slices, self.max_suggested_slice, if_then) && !filtered_slices.is_empty() + && self.msrv.meets(cx, msrvs::SLICE_PATTERNS) { for slice in filtered_slices.values() { lint_slice(cx, slice); } } } - - extract_msrv_attr!(LateContext); } fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap { diff --git a/clippy_lints/src/instant_subtraction.rs b/clippy_lints/src/instant_subtraction.rs index f4e41dc826b0..4ae1119ab3a2 100644 --- a/clippy_lints/src/instant_subtraction.rs +++ b/clippy_lints/src/instant_subtraction.rs @@ -70,9 +70,7 @@ pub struct InstantSubtraction { impl InstantSubtraction { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -99,14 +97,12 @@ impl LateLintPass<'_> for InstantSubtraction { print_manual_instant_elapsed_sugg(cx, expr, sugg); } else if ty::is_type_diagnostic_item(cx, rhs_ty, sym::Duration) && !expr.span.from_expansion() - && self.msrv.meets(msrvs::TRY_FROM) + && self.msrv.meets(cx, msrvs::TRY_FROM) { print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); } } } - - extract_msrv_attr!(LateContext); } fn is_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool { diff --git a/clippy_lints/src/legacy_numeric_constants.rs b/clippy_lints/src/legacy_numeric_constants.rs index 6f2ce04e8f8e..3939318bee6e 100644 --- a/clippy_lints/src/legacy_numeric_constants.rs +++ b/clippy_lints/src/legacy_numeric_constants.rs @@ -39,9 +39,7 @@ pub struct LegacyNumericConstants { impl LegacyNumericConstants { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -52,9 +50,9 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { // Integer modules are "TBD" deprecated, and the contents are too, // so lint on the `use` statement directly. if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind - && self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS) && !item.span.in_external_macro(cx.sess().source_map()) && let Some(def_id) = path.res[0].opt_def_id() + && self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS) { let module = if is_integer_module(cx, def_id) { true @@ -137,8 +135,8 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { return; }; - if self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS) - && !expr.span.in_external_macro(cx.sess().source_map()) + if !expr.span.in_external_macro(cx.sess().source_map()) + && self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS) && !is_from_proc_macro(cx, expr) { span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| { @@ -151,8 +149,6 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { }); } } - - extract_msrv_attr!(LateContext); } fn is_integer_module(cx: &LateContext<'_>, did: DefId) -> bool { diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 7589ab1229af..3dd2de1fafc7 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -130,9 +130,7 @@ pub struct Lifetimes { impl Lifetimes { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -151,7 +149,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes { .. } = item.kind { - check_fn_inner(cx, sig, Some(id), None, generics, item.span, true, &self.msrv); + check_fn_inner(cx, sig, Some(id), None, generics, item.span, true, self.msrv); } else if let ItemKind::Impl(impl_) = item.kind { if !item.span.from_expansion() { report_extra_impl_lifetimes(cx, impl_); @@ -170,7 +168,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes { item.generics, item.span, report_extra_lifetimes, - &self.msrv, + self.msrv, ); } } @@ -181,11 +179,9 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes { TraitFn::Required(sig) => (None, Some(sig)), TraitFn::Provided(id) => (Some(id), None), }; - check_fn_inner(cx, sig, body, trait_sig, item.generics, item.span, true, &self.msrv); + check_fn_inner(cx, sig, body, trait_sig, item.generics, item.span, true, self.msrv); } } - - extract_msrv_attr!(LateContext); } #[allow(clippy::too_many_arguments)] @@ -197,7 +193,7 @@ fn check_fn_inner<'tcx>( generics: &'tcx Generics<'_>, span: Span, report_extra_lifetimes: bool, - msrv: &Msrv, + msrv: Msrv, ) { if span.in_external_macro(cx.sess().source_map()) || has_where_lifetimes(cx, generics) { return; @@ -270,7 +266,7 @@ fn could_use_elision<'tcx>( body: Option, trait_sig: Option<&[Ident]>, named_generics: &'tcx [GenericParam<'_>], - msrv: &Msrv, + msrv: Msrv, ) -> Option<(Vec, Vec)> { // There are two scenarios where elision works: // * no output references, all input references have different LT @@ -388,17 +384,12 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxIndexSet( - cx: &LateContext<'tcx>, - func: &FnDecl<'tcx>, - ident: Option, - msrv: &Msrv, -) -> bool { - if !msrv.meets(msrvs::EXPLICIT_SELF_TYPE_ELISION) - && let Some(ident) = ident +fn non_elidable_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option, msrv: Msrv) -> bool { + if let Some(ident) = ident && ident.name == kw::SelfLower && !func.implicit_self.has_implicit_self() && let Some(self_ty) = func.inputs.first() + && !msrv.meets(cx, msrvs::EXPLICIT_SELF_TYPE_ELISION) { let mut visitor = RefVisitor::new(cx); visitor.visit_ty_unambig(self_ty); diff --git a/clippy_lints/src/lines_filter_map_ok.rs b/clippy_lints/src/lines_filter_map_ok.rs index 08548f564009..d8af44233d3e 100644 --- a/clippy_lints/src/lines_filter_map_ok.rs +++ b/clippy_lints/src/lines_filter_map_ok.rs @@ -15,9 +15,7 @@ pub struct LinesFilterMapOk { impl LinesFilterMapOk { pub fn new(conf: &Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -74,13 +72,13 @@ impl_lint_pass!(LinesFilterMapOk => [LINES_FILTER_MAP_OK]); impl LateLintPass<'_> for LinesFilterMapOk { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if self.msrv.meets(msrvs::MAP_WHILE) - && let ExprKind::MethodCall(fm_method, fm_receiver, fm_args, fm_span) = expr.kind + if let ExprKind::MethodCall(fm_method, fm_receiver, fm_args, fm_span) = expr.kind && is_trait_method(cx, expr, sym::Iterator) && let fm_method_str = fm_method.ident.as_str() && matches!(fm_method_str, "filter_map" | "flat_map" | "flatten") && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), sym::IoLines) && should_lint(cx, fm_args, fm_method_str) + && self.msrv.meets(cx, msrvs::MAP_WHILE) { span_lint_and_then( cx, @@ -101,8 +99,6 @@ impl LateLintPass<'_> for LinesFilterMapOk { ); } } - - extract_msrv_attr!(LateContext); } fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> bool { diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs index 06cf901bfb23..412c78cc8041 100644 --- a/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_iter_loop.rs @@ -17,7 +17,7 @@ pub(super) fn check( cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<'_>, - msrv: &Msrv, + msrv: Msrv, enforce_iter_loop_reborrow: bool, ) { let Some((adjust, ty)) = is_ref_iterable(cx, self_arg, call_expr, enforce_iter_loop_reborrow, msrv) else { @@ -26,10 +26,11 @@ pub(super) fn check( if let ty::Array(_, count) = *ty.peel_refs().kind() { if !ty.is_ref() { - if !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) { + if !msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) { return; } - } else if count.try_to_target_usize(cx.tcx).is_none_or(|x| x > 32) && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN) { + } else if count.try_to_target_usize(cx.tcx).is_none_or(|x| x > 32) && !msrv.meets(cx, msrvs::ARRAY_IMPL_ANY_LEN) + { return; } } @@ -106,7 +107,7 @@ fn is_ref_iterable<'tcx>( self_arg: &Expr<'_>, call_expr: &Expr<'_>, enforce_iter_loop_reborrow: bool, - msrv: &Msrv, + msrv: Msrv, ) -> Option<(AdjustKind, Ty<'tcx>)> { let typeck = cx.typeck_results(); if let Some(trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator) @@ -126,8 +127,8 @@ fn is_ref_iterable<'tcx>( let self_ty = typeck.expr_ty(self_arg); let self_is_copy = is_copy(cx, self_ty); - if !msrv.meets(msrvs::BOX_INTO_ITER) - && is_type_lang_item(cx, self_ty.peel_refs(), rustc_hir::LangItem::OwnedBox) + if is_type_lang_item(cx, self_ty.peel_refs(), rustc_hir::LangItem::OwnedBox) + && !msrv.meets(cx, msrvs::BOX_INTO_ITER) { return None; } diff --git a/clippy_lints/src/loops/manual_flatten.rs b/clippy_lints/src/loops/manual_flatten.rs index ffeb7e889c2e..9b6f97b9a2eb 100644 --- a/clippy_lints/src/loops/manual_flatten.rs +++ b/clippy_lints/src/loops/manual_flatten.rs @@ -19,7 +19,7 @@ pub(super) fn check<'tcx>( arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>, span: Span, - msrv: &Msrv, + msrv: Msrv, ) { let inner_expr = peel_blocks_with_stmt(body); if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else: None, .. }) @@ -36,7 +36,7 @@ pub(super) fn check<'tcx>( && (some_ctor || ok_ctor) // Ensure expr in `if let` is not used afterwards && !is_local_used(cx, if_then, pat_hir_id) - && msrv.meets(msrvs::ITER_FLATTEN) + && msrv.meets(cx, msrvs::ITER_FLATTEN) { let if_let_type = if some_ctor { "Some" } else { "Ok" }; // Prepare the error message diff --git a/clippy_lints/src/loops/manual_slice_fill.rs b/clippy_lints/src/loops/manual_slice_fill.rs index a97641788621..343f7c5d2d12 100644 --- a/clippy_lints/src/loops/manual_slice_fill.rs +++ b/clippy_lints/src/loops/manual_slice_fill.rs @@ -24,12 +24,8 @@ pub(super) fn check<'tcx>( arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>, expr: &'tcx Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) { - if !msrv.meets(msrvs::SLICE_FILL) { - return; - } - // `for _ in 0..slice.len() { slice[_] = value; }` if let Some(higher::Range { start: Some(start), @@ -61,6 +57,7 @@ pub(super) fn check<'tcx>( && let ExprKind::Path(Resolved(_, idx_path)) = idx.kind && let Res::Local(idx_hir) = idx_path.res && !is_local_used(cx, assignval, idx_hir) + && msrv.meets(cx, msrvs::SLICE_FILL) { sugg(cx, body, expr, slice.span, assignval.span); } @@ -81,6 +78,7 @@ pub(super) fn check<'tcx>( // The `fill` method cannot be used if the slice's element type does not implement the `Clone` trait. && let Some(clone_trait) = cx.tcx.lang_items().clone_trait() && implements_trait(cx, cx.typeck_results().expr_ty(recv), clone_trait, &[]) + && msrv.meets(cx, msrvs::SLICE_FILL) { sugg(cx, body, expr, recv_path.span, assignval.span); } diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index ffe7566f5fb6..ed725a039891 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -747,7 +747,7 @@ pub struct Loops { impl Loops { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: conf.msrv, enforce_iter_loop_reborrow: conf.enforce_iter_loop_reborrow, } } @@ -832,8 +832,6 @@ impl<'tcx> LateLintPass<'tcx> for Loops { manual_while_let_some::check(cx, condition, body, span); } } - - extract_msrv_attr!(LateContext); } impl Loops { @@ -850,7 +848,7 @@ impl Loops { ) { let is_manual_memcpy_triggered = manual_memcpy::check(cx, pat, arg, body, expr); if !is_manual_memcpy_triggered { - manual_slice_fill::check(cx, pat, arg, body, expr, &self.msrv); + manual_slice_fill::check(cx, pat, arg, body, expr, self.msrv); needless_range_loop::check(cx, pat, arg, body, expr); explicit_counter_loop::check(cx, pat, arg, body, expr, label); } @@ -858,8 +856,8 @@ impl Loops { for_kv_map::check(cx, pat, arg, body); mut_range_bound::check(cx, arg, body); single_element_loop::check(cx, pat, arg, body, expr); - same_item_push::check(cx, pat, arg, body, expr, &self.msrv); - manual_flatten::check(cx, pat, arg, body, span, &self.msrv); + same_item_push::check(cx, pat, arg, body, expr, self.msrv); + manual_flatten::check(cx, pat, arg, body, span, self.msrv); manual_find::check(cx, pat, arg, body, span, expr); unused_enumerate_index::check(cx, pat, arg, body); } @@ -868,7 +866,7 @@ impl Loops { if let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind { match method.ident.as_str() { "iter" | "iter_mut" => { - explicit_iter_loop::check(cx, self_arg, arg, &self.msrv, self.enforce_iter_loop_reborrow); + explicit_iter_loop::check(cx, self_arg, arg, self.msrv, self.enforce_iter_loop_reborrow); }, "into_iter" => { explicit_into_iter_loop::check(cx, self_arg, arg); diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs index c27e930c99a5..661b4b590d8f 100644 --- a/clippy_lints/src/loops/same_item_push.rs +++ b/clippy_lints/src/loops/same_item_push.rs @@ -20,14 +20,14 @@ pub(super) fn check<'tcx>( _: &'tcx Expr<'_>, body: &'tcx Expr<'_>, _: &'tcx Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) { - fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>, ctxt: SyntaxContext, msrv: &Msrv) { + fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>, ctxt: SyntaxContext, msrv: Msrv) { let mut app = Applicability::Unspecified; let vec_str = snippet_with_context(cx, vec.span, ctxt, "", &mut app).0; let item_str = snippet_with_context(cx, pushed_item.span, ctxt, "", &mut app).0; - let secondary_help = if msrv.meets(msrvs::REPEAT_N) + let secondary_help = if msrv.meets(cx, msrvs::REPEAT_N) && let Some(std_or_core) = std_or_core(cx) { format!("or `{vec_str}.extend({std_or_core}::iter::repeat_n({item_str}, SIZE))`") diff --git a/clippy_lints/src/manual_bits.rs b/clippy_lints/src/manual_bits.rs index 4a34a334cf2b..39c4857b3e87 100644 --- a/clippy_lints/src/manual_bits.rs +++ b/clippy_lints/src/manual_bits.rs @@ -40,9 +40,7 @@ pub struct ManualBits { impl ManualBits { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -53,7 +51,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits { if let ExprKind::Binary(bin_op, left_expr, right_expr) = expr.kind && let BinOpKind::Mul = &bin_op.node && !expr.span.from_expansion() - && self.msrv.meets(msrvs::INTEGER_BITS) && let ctxt = expr.span.ctxt() && left_expr.span.ctxt() == ctxt && right_expr.span.ctxt() == ctxt @@ -61,6 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits { && matches!(resolved_ty.kind(), ty::Int(_) | ty::Uint(_)) && let ExprKind::Lit(lit) = &other_expr.kind && let LitKind::Int(Pu128(8), _) = lit.node + && self.msrv.meets(cx, msrvs::INTEGER_BITS) { let mut app = Applicability::MachineApplicable; let ty_snip = snippet_with_context(cx, real_ty_span, ctxt, "..", &mut app).0; @@ -77,8 +75,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits { ); } } - - extract_msrv_attr!(LateContext); } fn get_one_size_of_ty<'tcx>( diff --git a/clippy_lints/src/manual_clamp.rs b/clippy_lints/src/manual_clamp.rs index 484a7ba256bd..50c8331eebab 100644 --- a/clippy_lints/src/manual_clamp.rs +++ b/clippy_lints/src/manual_clamp.rs @@ -99,9 +99,7 @@ pub struct ManualClamp { impl ManualClamp { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -144,30 +142,28 @@ struct InputMinMax<'tcx> { impl<'tcx> LateLintPass<'tcx> for ManualClamp { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { - if !self.msrv.meets(msrvs::CLAMP) { - return; - } if !expr.span.from_expansion() && !is_in_const_context(cx) { let suggestion = is_if_elseif_else_pattern(cx, expr) .or_else(|| is_max_min_pattern(cx, expr)) .or_else(|| is_call_max_min_pattern(cx, expr)) .or_else(|| is_match_pattern(cx, expr)) .or_else(|| is_if_elseif_pattern(cx, expr)); - if let Some(suggestion) = suggestion { + if let Some(suggestion) = suggestion + && self.msrv.meets(cx, msrvs::CLAMP) + { maybe_emit_suggestion(cx, &suggestion); } } } fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) { - if !self.msrv.meets(msrvs::CLAMP) || is_in_const_context(cx) { + if is_in_const_context(cx) || !self.msrv.meets(cx, msrvs::CLAMP) { return; } for suggestion in is_two_if_pattern(cx, block) { maybe_emit_suggestion(cx, &suggestion); } } - extract_msrv_attr!(LateContext); } fn maybe_emit_suggestion<'tcx>(cx: &LateContext<'tcx>, suggestion: &ClampSuggestion<'tcx>) { diff --git a/clippy_lints/src/manual_div_ceil.rs b/clippy_lints/src/manual_div_ceil.rs index 04357cdd8f66..9c1419175d55 100644 --- a/clippy_lints/src/manual_div_ceil.rs +++ b/clippy_lints/src/manual_div_ceil.rs @@ -49,9 +49,7 @@ pub struct ManualDivCeil { impl ManualDivCeil { #[must_use] pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -59,10 +57,6 @@ impl_lint_pass!(ManualDivCeil => [MANUAL_DIV_CEIL]); impl<'tcx> LateLintPass<'tcx> for ManualDivCeil { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { - if !self.msrv.meets(msrvs::MANUAL_DIV_CEIL) { - return; - } - let mut applicability = Applicability::MachineApplicable; if let ExprKind::Binary(div_op, div_lhs, div_rhs) = expr.kind @@ -70,6 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualDivCeil { && check_int_ty_and_feature(cx, div_lhs) && check_int_ty_and_feature(cx, div_rhs) && let ExprKind::Binary(inner_op, inner_lhs, inner_rhs) = div_lhs.kind + && self.msrv.meets(cx, msrvs::MANUAL_DIV_CEIL) { // (x + (y - 1)) / y if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind @@ -122,8 +117,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualDivCeil { } } } - - extract_msrv_attr!(LateContext); } /// Checks if two expressions represent non-zero integer literals such that `small_expr + 1 == diff --git a/clippy_lints/src/manual_float_methods.rs b/clippy_lints/src/manual_float_methods.rs index 2a5aa12d126c..bd2785fea270 100644 --- a/clippy_lints/src/manual_float_methods.rs +++ b/clippy_lints/src/manual_float_methods.rs @@ -90,9 +90,7 @@ pub struct ManualFloatMethods { impl ManualFloatMethods { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -144,7 +142,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods { && !expr.span.in_external_macro(cx.sess().source_map()) && ( is_not_const(cx.tcx, cx.tcx.hir_enclosing_body_owner(expr.hir_id).into()) - || self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY) + || self.msrv.meets(cx, msrvs::CONST_FLOAT_CLASSIFY) ) && let [first, second, const_1, const_2] = exprs && let ecx = ConstEvalCtxt::new(cx) @@ -202,8 +200,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods { }); } } - - extract_msrv_attr!(LateContext); } fn is_infinity(constant: &Constant<'_>) -> bool { diff --git a/clippy_lints/src/manual_hash_one.rs b/clippy_lints/src/manual_hash_one.rs index 7e092d11f1b4..f71264a93ca8 100644 --- a/clippy_lints/src/manual_hash_one.rs +++ b/clippy_lints/src/manual_hash_one.rs @@ -53,9 +53,7 @@ pub struct ManualHashOne { impl ManualHashOne { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -98,7 +96,7 @@ impl LateLintPass<'_> for ManualHashOne { && let ExprKind::MethodCall(seg, _, [], _) = finish_expr.kind && seg.ident.name.as_str() == "finish" - && self.msrv.meets(msrvs::BUILD_HASHER_HASH_ONE) + && self.msrv.meets(cx, msrvs::BUILD_HASHER_HASH_ONE) { span_lint_hir_and_then( cx, @@ -129,6 +127,4 @@ impl LateLintPass<'_> for ManualHashOne { ); } } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs index 38106277a88f..faf01a276a13 100644 --- a/clippy_lints/src/manual_is_ascii_check.rs +++ b/clippy_lints/src/manual_is_ascii_check.rs @@ -64,9 +64,7 @@ pub struct ManualIsAsciiCheck { impl ManualIsAsciiCheck { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -91,11 +89,11 @@ enum CharRange { impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if !self.msrv.meets(msrvs::IS_ASCII_DIGIT) { + if !self.msrv.meets(cx, msrvs::IS_ASCII_DIGIT) { return; } - if is_in_const_context(cx) && !self.msrv.meets(msrvs::IS_ASCII_DIGIT_CONST) { + if is_in_const_context(cx) && !self.msrv.meets(cx, msrvs::IS_ASCII_DIGIT_CONST) { return; } @@ -119,8 +117,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck { check_is_ascii(cx, expr.span, arg, &range, ty_sugg); } } - - extract_msrv_attr!(LateContext); } fn get_ty_sugg<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'_>) -> Option<(Span, Ty<'tcx>)> { diff --git a/clippy_lints/src/manual_let_else.rs b/clippy_lints/src/manual_let_else.rs index 3643b8c4425e..47939767212e 100644 --- a/clippy_lints/src/manual_let_else.rs +++ b/clippy_lints/src/manual_let_else.rs @@ -53,8 +53,8 @@ impl<'tcx> QuestionMark { && local.ty.is_none() && init.span.eq_ctxt(stmt.span) && let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init) - && self.msrv.meets(msrvs::LET_ELSE) && !stmt.span.in_external_macro(cx.sess().source_map()) + && self.msrv.meets(cx, msrvs::LET_ELSE) { match if_let_or_match { IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else, ..) => { diff --git a/clippy_lints/src/manual_main_separator_str.rs b/clippy_lints/src/manual_main_separator_str.rs index b7563a2508d0..f54ccf2c87b0 100644 --- a/clippy_lints/src/manual_main_separator_str.rs +++ b/clippy_lints/src/manual_main_separator_str.rs @@ -39,9 +39,7 @@ pub struct ManualMainSeparatorStr { impl ManualMainSeparatorStr { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -55,10 +53,10 @@ impl LateLintPass<'_> for ManualMainSeparatorStr { && let ExprKind::Path(QPath::Resolved(None, path)) = receiver.kind && let Res::Def(DefKind::Const, receiver_def_id) = path.res && is_trait_method(cx, target, sym::ToString) - && self.msrv.meets(msrvs::PATH_MAIN_SEPARATOR_STR) && cx.tcx.is_diagnostic_item(sym::path_main_separator, receiver_def_id) && let ty::Ref(_, ty, Mutability::Not) = cx.typeck_results().expr_ty_adjusted(expr).kind() && ty.is_str() + && self.msrv.meets(cx, msrvs::PATH_MAIN_SEPARATOR_STR) { span_lint_and_sugg( cx, @@ -71,6 +69,4 @@ impl LateLintPass<'_> for ManualMainSeparatorStr { ); } } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/manual_non_exhaustive.rs b/clippy_lints/src/manual_non_exhaustive.rs index 83d8a5093906..496e0660d4f9 100644 --- a/clippy_lints/src/manual_non_exhaustive.rs +++ b/clippy_lints/src/manual_non_exhaustive.rs @@ -71,7 +71,7 @@ pub struct ManualNonExhaustive { impl ManualNonExhaustive { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: conf.msrv, constructed_enum_variants: FxHashSet::default(), potential_enums: Vec::new(), } @@ -82,7 +82,7 @@ impl_lint_pass!(ManualNonExhaustive => [MANUAL_NON_EXHAUSTIVE]); impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if !self.msrv.meets(msrvs::NON_EXHAUSTIVE) || !cx.effective_visibilities.is_exported(item.owner_id.def_id) { + if !cx.effective_visibilities.is_exported(item.owner_id.def_id) || !self.msrv.meets(cx, msrvs::NON_EXHAUSTIVE) { return; } @@ -171,6 +171,4 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { ); } } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/manual_option_as_slice.rs b/clippy_lints/src/manual_option_as_slice.rs index e4360518b66e..8dee29b2a0b5 100644 --- a/clippy_lints/src/manual_option_as_slice.rs +++ b/clippy_lints/src/manual_option_as_slice.rs @@ -1,5 +1,6 @@ use clippy_config::Conf; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::msrvs::Msrv; use clippy_utils::{is_none_arm, msrvs, peel_hir_expr_refs}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; @@ -40,31 +41,21 @@ declare_clippy_lint! { } pub struct ManualOptionAsSlice { - msrv: msrvs::Msrv, + msrv: Msrv, } impl ManualOptionAsSlice { pub fn new(conf: &Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } impl_lint_pass!(ManualOptionAsSlice => [MANUAL_OPTION_AS_SLICE]); impl LateLintPass<'_> for ManualOptionAsSlice { - extract_msrv_attr!(LateContext); - fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { let span = expr.span; - if span.from_expansion() - || !self.msrv.meets(if clippy_utils::is_in_const_context(cx) { - msrvs::CONST_OPTION_AS_SLICE - } else { - msrvs::OPTION_AS_SLICE - }) - { + if span.from_expansion() { return; } match expr.kind { @@ -72,7 +63,7 @@ impl LateLintPass<'_> for ManualOptionAsSlice { if is_none_arm(cx, arm2) && check_arms(cx, arm2, arm1) || is_none_arm(cx, arm1) && check_arms(cx, arm1, arm2) { - check_as_ref(cx, scrutinee, span); + check_as_ref(cx, scrutinee, span, self.msrv); } }, ExprKind::If(cond, then, Some(other)) => { @@ -81,23 +72,23 @@ impl LateLintPass<'_> for ManualOptionAsSlice { && check_some_body(cx, binding, then) && is_empty_slice(cx, other.peel_blocks()) { - check_as_ref(cx, let_expr.init, span); + check_as_ref(cx, let_expr.init, span, self.msrv); } }, ExprKind::MethodCall(seg, callee, [], _) => { if seg.ident.name.as_str() == "unwrap_or_default" { - check_map(cx, callee, span); + check_map(cx, callee, span, self.msrv); } }, ExprKind::MethodCall(seg, callee, [or], _) => match seg.ident.name.as_str() { "unwrap_or" => { if is_empty_slice(cx, or) { - check_map(cx, callee, span); + check_map(cx, callee, span, self.msrv); } }, "unwrap_or_else" => { if returns_empty_slice(cx, or) { - check_map(cx, callee, span); + check_map(cx, callee, span, self.msrv); } }, _ => {}, @@ -105,12 +96,12 @@ impl LateLintPass<'_> for ManualOptionAsSlice { ExprKind::MethodCall(seg, callee, [or_else, map], _) => match seg.ident.name.as_str() { "map_or" => { if is_empty_slice(cx, or_else) && is_slice_from_ref(cx, map) { - check_as_ref(cx, callee, span); + check_as_ref(cx, callee, span, self.msrv); } }, "map_or_else" => { if returns_empty_slice(cx, or_else) && is_slice_from_ref(cx, map) { - check_as_ref(cx, callee, span); + check_as_ref(cx, callee, span, self.msrv); } }, _ => {}, @@ -120,20 +111,28 @@ impl LateLintPass<'_> for ManualOptionAsSlice { } } -fn check_map(cx: &LateContext<'_>, map: &Expr<'_>, span: Span) { +fn check_map(cx: &LateContext<'_>, map: &Expr<'_>, span: Span, msrv: Msrv) { if let ExprKind::MethodCall(seg, callee, [mapping], _) = map.kind && seg.ident.name == sym::map && is_slice_from_ref(cx, mapping) { - check_as_ref(cx, callee, span); + check_as_ref(cx, callee, span, msrv); } } -fn check_as_ref(cx: &LateContext<'_>, expr: &Expr<'_>, span: Span) { +fn check_as_ref(cx: &LateContext<'_>, expr: &Expr<'_>, span: Span, msrv: Msrv) { if let ExprKind::MethodCall(seg, callee, [], _) = expr.kind && seg.ident.name == sym::as_ref && let ty::Adt(adtdef, ..) = cx.typeck_results().expr_ty(callee).kind() && cx.tcx.is_diagnostic_item(sym::Option, adtdef.did()) + && msrv.meets( + cx, + if clippy_utils::is_in_const_context(cx) { + msrvs::CONST_OPTION_AS_SLICE + } else { + msrvs::OPTION_AS_SLICE + }, + ) { if let Some(snippet) = clippy_utils::source::snippet_opt(cx, callee.span) { span_lint_and_sugg( diff --git a/clippy_lints/src/manual_rem_euclid.rs b/clippy_lints/src/manual_rem_euclid.rs index 469b4b7cf89f..41e07e26bff0 100644 --- a/clippy_lints/src/manual_rem_euclid.rs +++ b/clippy_lints/src/manual_rem_euclid.rs @@ -39,9 +39,7 @@ pub struct ManualRemEuclid { impl ManualRemEuclid { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -60,8 +58,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { && add_lhs.span.ctxt() == ctxt && add_rhs.span.ctxt() == ctxt && !expr.span.in_external_macro(cx.sess().source_map()) - && self.msrv.meets(msrvs::REM_EUCLID) - && (self.msrv.meets(msrvs::REM_EUCLID_CONST) || !is_in_const_context(cx)) && let Some(const1) = check_for_unsigned_int_constant(cx, rem_rhs) && let Some((const2, add_other)) = check_for_either_unsigned_int_constant(cx, add_lhs, add_rhs) && let ExprKind::Binary(rem2_op, rem2_lhs, rem2_rhs) = add_other.kind @@ -73,6 +69,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { && const2 == const3 && rem2_lhs.span.ctxt() == ctxt && rem2_rhs.span.ctxt() == ctxt + && self.msrv.meets(cx, msrvs::REM_EUCLID) + && (self.msrv.meets(cx, msrvs::REM_EUCLID_CONST) || !is_in_const_context(cx)) { // Apply only to params or locals with annotated types match cx.tcx.parent_hir_node(hir_id) { @@ -99,8 +97,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { ); } } - - extract_msrv_attr!(LateContext); } // Checks if either the left or right expressions can be an unsigned int constant and returns that diff --git a/clippy_lints/src/manual_retain.rs b/clippy_lints/src/manual_retain.rs index 0a4e756096e9..16dd1ad4e478 100644 --- a/clippy_lints/src/manual_retain.rs +++ b/clippy_lints/src/manual_retain.rs @@ -50,9 +50,7 @@ pub struct ManualRetain { impl ManualRetain { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -66,13 +64,11 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain { && let Some(collect_def_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id) && cx.tcx.is_diagnostic_item(sym::iterator_collect_fn, collect_def_id) { - check_into_iter(cx, left_expr, target_expr, expr.span, &self.msrv); - check_iter(cx, left_expr, target_expr, expr.span, &self.msrv); - check_to_owned(cx, left_expr, target_expr, expr.span, &self.msrv); + check_into_iter(cx, left_expr, target_expr, expr.span, self.msrv); + check_iter(cx, left_expr, target_expr, expr.span, self.msrv); + check_to_owned(cx, left_expr, target_expr, expr.span, self.msrv); } } - - extract_msrv_attr!(LateContext); } fn check_into_iter( @@ -80,7 +76,7 @@ fn check_into_iter( left_expr: &hir::Expr<'_>, target_expr: &hir::Expr<'_>, parent_expr_span: Span, - msrv: &Msrv, + msrv: Msrv, ) { if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind && let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id) @@ -123,7 +119,7 @@ fn check_iter( left_expr: &hir::Expr<'_>, target_expr: &hir::Expr<'_>, parent_expr_span: Span, - msrv: &Msrv, + msrv: Msrv, ) { if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind && let Some(copied_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id) @@ -181,10 +177,9 @@ fn check_to_owned( left_expr: &hir::Expr<'_>, target_expr: &hir::Expr<'_>, parent_expr_span: Span, - msrv: &Msrv, + msrv: Msrv, ) { - if msrv.meets(msrvs::STRING_RETAIN) - && let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind + if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind && let Some(to_owned_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id) && cx.tcx.is_diagnostic_item(sym::to_owned_method, to_owned_def_id) && let hir::ExprKind::MethodCall(_, chars_expr, [_], _) = &filter_expr.kind @@ -200,6 +195,7 @@ fn check_to_owned( && let hir::ExprKind::Closure(closure) = closure_expr.kind && let filter_body = cx.tcx.hir_body(closure.body) && let [filter_params] = filter_body.params + && msrv.meets(cx, msrvs::STRING_RETAIN) { if let hir::PatKind::Ref(pat, _) = filter_params.pat.kind { make_span_lint_and_sugg( @@ -253,7 +249,7 @@ fn match_acceptable_sym(cx: &LateContext<'_>, collect_def_id: DefId) -> bool { .any(|&method| cx.tcx.is_diagnostic_item(method, collect_def_id)) } -fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv) -> bool { +fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: Msrv) -> bool { let ty = cx.typeck_results().expr_ty(expr).peel_refs(); let required = match get_type_diagnostic_name(cx, ty) { Some(sym::BinaryHeap) => msrvs::BINARY_HEAP_RETAIN, @@ -264,7 +260,7 @@ fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv Some(sym::Vec | sym::VecDeque) => return true, _ => return false, }; - msrv.meets(required) + msrv.meets(cx, required) } fn match_map_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { diff --git a/clippy_lints/src/manual_strip.rs b/clippy_lints/src/manual_strip.rs index daed88b492e6..9e911e61f196 100644 --- a/clippy_lints/src/manual_strip.rs +++ b/clippy_lints/src/manual_strip.rs @@ -56,9 +56,7 @@ pub struct ManualStrip { impl ManualStrip { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -75,7 +73,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip { if let Some(higher::If { cond, then, .. }) = higher::If::hir(expr) && let ExprKind::MethodCall(_, target_arg, [pattern], _) = cond.kind && let ExprKind::Path(target_path) = &target_arg.kind - && self.msrv.meets(msrvs::STR_STRIP_PREFIX) && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(cond.hir_id) { let strip_kind = if cx.tcx.is_diagnostic_item(sym::str_starts_with, method_def_id) { @@ -98,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip { } let (strippings, bindings) = find_stripping(cx, strip_kind, target_res, pattern, then); - if !strippings.is_empty() { + if !strippings.is_empty() && self.msrv.meets(cx, msrvs::STR_STRIP_PREFIX) { let kind_word = match strip_kind { StripKind::Prefix => "prefix", StripKind::Suffix => "suffix", @@ -156,8 +153,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip { } } } - - extract_msrv_attr!(LateContext); } // Returns `Some(arg)` if `expr` matches `arg.len()` and `None` otherwise. diff --git a/clippy_lints/src/matches/collapsible_match.rs b/clippy_lints/src/matches/collapsible_match.rs index 97e8423695d9..6f446bf95658 100644 --- a/clippy_lints/src/matches/collapsible_match.rs +++ b/clippy_lints/src/matches/collapsible_match.rs @@ -14,7 +14,7 @@ use rustc_span::Span; use super::{COLLAPSIBLE_MATCH, pat_contains_disallowed_or}; -pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], msrv: &Msrv) { +pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], msrv: Msrv) { if let Some(els_arm) = arms.iter().rfind(|arm| arm_is_wild_like(cx, arm)) { for arm in arms { check_arm(cx, true, arm.pat, arm.body, arm.guard, Some(els_arm.body), msrv); @@ -27,7 +27,7 @@ pub(super) fn check_if_let<'tcx>( pat: &'tcx Pat<'_>, body: &'tcx Expr<'_>, else_expr: Option<&'tcx Expr<'_>>, - msrv: &Msrv, + msrv: Msrv, ) { check_arm(cx, false, pat, body, None, else_expr, msrv); } @@ -39,7 +39,7 @@ fn check_arm<'tcx>( outer_then_body: &'tcx Expr<'tcx>, outer_guard: Option<&'tcx Expr<'tcx>>, outer_else_body: Option<&'tcx Expr<'tcx>>, - msrv: &Msrv, + msrv: Msrv, ) { let inner_expr = peel_blocks_with_stmt(outer_then_body); if let Some(inner) = IfLetOrMatch::parse(cx, inner_expr) @@ -60,7 +60,7 @@ fn check_arm<'tcx>( // match expression must be a local binding // match { .. } && let Some(binding_id) = path_to_local(peel_ref_operators(cx, inner_scrutinee)) - && !pat_contains_disallowed_or(inner_then_pat, msrv) + && !pat_contains_disallowed_or(cx, inner_then_pat, msrv) // the binding must come from the pattern of the containing match arm // .... => match { .. } && let (Some(binding_span), is_innermost_parent_pat_struct) diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs index 9ca914af281b..35caa7d1f3a6 100644 --- a/clippy_lints/src/matches/mod.rs +++ b/clippy_lints/src/matches/mod.rs @@ -1014,7 +1014,7 @@ pub struct Matches { impl Matches { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: conf.msrv, infallible_destructuring_match_linted: false, } } @@ -1073,7 +1073,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches { significant_drop_in_scrutinee::check_match(cx, expr, ex, arms, source); } - collapsible_match::check_match(cx, arms, &self.msrv); + collapsible_match::check_match(cx, arms, self.msrv); if !from_expansion { // These don't depend on a relationship between multiple arms match_wild_err_arm::check(cx, ex, arms); @@ -1086,7 +1086,9 @@ impl<'tcx> LateLintPass<'tcx> for Matches { if !from_expansion && !contains_cfg_arm(cx, expr, ex, arms) { if source == MatchSource::Normal { - if !(self.msrv.meets(msrvs::MATCHES_MACRO) && match_like_matches::check_match(cx, expr, ex, arms)) { + if !(self.msrv.meets(cx, msrvs::MATCHES_MACRO) + && match_like_matches::check_match(cx, expr, ex, arms)) + { match_same_arms::check(cx, arms); } @@ -1120,7 +1122,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches { needless_match::check_match(cx, ex, arms, expr); match_on_vec_items::check(cx, ex); match_str_case_mismatch::check(cx, ex, arms); - redundant_guards::check(cx, arms, &self.msrv); + redundant_guards::check(cx, arms, self.msrv); if !is_in_const_context(cx) { manual_unwrap_or::check_match(cx, expr, ex, arms); @@ -1138,11 +1140,11 @@ impl<'tcx> LateLintPass<'tcx> for Matches { match_ref_pats::check(cx, ex, arms.iter().map(|el| el.pat), expr); } } else if let Some(if_let) = higher::IfLet::hir(cx, expr) { - collapsible_match::check_if_let(cx, if_let.let_pat, if_let.if_then, if_let.if_else, &self.msrv); + collapsible_match::check_if_let(cx, if_let.let_pat, if_let.if_then, if_let.if_else, self.msrv); significant_drop_in_scrutinee::check_if_let(cx, expr, if_let.let_expr, if_let.if_then, if_let.if_else); if !from_expansion { if let Some(else_expr) = if_let.if_else { - if self.msrv.meets(msrvs::MATCHES_MACRO) { + if self.msrv.meets(cx, msrvs::MATCHES_MACRO) { match_like_matches::check_if_let( cx, expr, @@ -1208,8 +1210,6 @@ impl<'tcx> LateLintPass<'tcx> for Matches { fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) { rest_pat_in_fully_bound_struct::check(cx, pat); } - - extract_msrv_attr!(LateContext); } /// Checks if there are any arms with a `#[cfg(..)]` attribute. @@ -1274,16 +1274,12 @@ fn contains_cfg_arm(cx: &LateContext<'_>, e: &Expr<'_>, scrutinee: &Expr<'_>, ar } /// Checks if `pat` contains OR patterns that cannot be nested due to a too low MSRV. -fn pat_contains_disallowed_or(pat: &Pat<'_>, msrv: &Msrv) -> bool { - if msrv.meets(msrvs::OR_PATTERNS) { - return false; - } - - let mut result = false; +fn pat_contains_disallowed_or(cx: &LateContext<'_>, pat: &Pat<'_>, msrv: Msrv) -> bool { + let mut contains_or = false; pat.walk(|p| { let is_or = matches!(p.kind, PatKind::Or(_)); - result |= is_or; + contains_or |= is_or; !is_or }); - result + contains_or && !msrv.meets(cx, msrvs::OR_PATTERNS) } diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index dfc0513add93..ab53ad98572e 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -16,7 +16,7 @@ use std::ops::ControlFlow; use super::{REDUNDANT_GUARDS, pat_contains_disallowed_or}; -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: &Msrv) { +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: Msrv) { for outer_arm in arms { let Some(guard) = outer_arm.guard else { continue; @@ -26,7 +26,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: if let ExprKind::Match(scrutinee, [arm, _], MatchSource::Normal) = guard.kind && matching_root_macro_call(cx, guard.span, sym::matches_macro).is_some() && let Some(binding) = get_pat_binding(cx, scrutinee, outer_arm) - && !pat_contains_disallowed_or(arm.pat, msrv) + && !pat_contains_disallowed_or(cx, arm.pat, msrv) { let pat_span = match (arm.pat.kind, binding.byref_ident) { (PatKind::Ref(pat, _), Some(_)) => pat.span, @@ -45,7 +45,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: // `Some(x) if let Some(2) = x` else if let ExprKind::Let(let_expr) = guard.kind && let Some(binding) = get_pat_binding(cx, let_expr.init, outer_arm) - && !pat_contains_disallowed_or(let_expr.pat, msrv) + && !pat_contains_disallowed_or(cx, let_expr.pat, msrv) { let pat_span = match (let_expr.pat.kind, binding.byref_ident) { (PatKind::Ref(pat, _), Some(_)) => pat.span, diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 2fe5f6a3a37a..a0919947b3fc 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -160,11 +160,11 @@ fn check_replace_option_with_some( src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span, - msrv: &Msrv, + msrv: Msrv, ) -> bool { - if msrv.meets(msrvs::OPTION_REPLACE) - && let ExprKind::Call(src_func, [src_arg]) = src.kind + if let ExprKind::Call(src_func, [src_arg]) = src.kind && is_res_lang_ctor(cx, path_res(cx, src_func), OptionSome) + && msrv.meets(cx, msrvs::OPTION_REPLACE) { // We do not have to check for a `const` context here, because `core::mem::replace()` and // `Option::replace()` have been const-stabilized simultaneously in version 1.83.0. @@ -250,15 +250,16 @@ fn check_replace_with_default( src: &Expr<'_>, dest: &Expr<'_>, expr: &Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) -> bool { - if msrv.meets(msrvs::MEM_TAKE) && is_expr_used_or_unified(cx.tcx, expr) + if is_expr_used_or_unified(cx.tcx, expr) // disable lint for primitives && let expr_type = cx.typeck_results().expr_ty_adjusted(src) && !is_non_aggregate_primitive_type(expr_type) && is_default_equivalent(cx, src) && !expr.span.in_external_macro(cx.tcx.sess.source_map()) && let Some(top_crate) = std_or_core(cx) + && msrv.meets(cx, msrvs::MEM_TAKE) { span_lint_and_then( cx, @@ -292,9 +293,7 @@ pub struct MemReplace { impl MemReplace { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -308,12 +307,11 @@ impl<'tcx> LateLintPass<'tcx> for MemReplace { { // Check that second argument is `Option::None` if !check_replace_option_with_none(cx, src, dest, expr.span) - && !check_replace_option_with_some(cx, src, dest, expr.span, &self.msrv) - && !check_replace_with_default(cx, src, dest, expr, &self.msrv) + && !check_replace_option_with_some(cx, src, dest, expr.span, self.msrv) + && !check_replace_with_default(cx, src, dest, expr, self.msrv) { check_replace_with_uninit(cx, src, dest, expr.span); } } } - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/methods/cloned_instead_of_copied.rs b/clippy_lints/src/methods/cloned_instead_of_copied.rs index 223a960b800e..f50fb627b89a 100644 --- a/clippy_lints/src/methods/cloned_instead_of_copied.rs +++ b/clippy_lints/src/methods/cloned_instead_of_copied.rs @@ -10,16 +10,16 @@ use rustc_span::{Span, sym}; use super::CLONED_INSTEAD_OF_COPIED; -pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: &Msrv) { +pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: Msrv) { let recv_ty = cx.typeck_results().expr_ty_adjusted(recv); let inner_ty = match recv_ty.kind() { // `Option` -> `T` ty::Adt(adt, subst) - if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && msrv.meets(msrvs::OPTION_COPIED) => + if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && msrv.meets(cx, msrvs::OPTION_COPIED) => { subst.type_at(0) }, - _ if is_trait_method(cx, expr, sym::Iterator) && msrv.meets(msrvs::ITERATOR_COPIED) => { + _ if is_trait_method(cx, expr, sym::Iterator) && msrv.meets(cx, msrvs::ITERATOR_COPIED) => { match get_iterator_item_ty(cx, recv_ty) { // ::Item Some(ty) => ty, diff --git a/clippy_lints/src/methods/err_expect.rs b/clippy_lints/src/methods/err_expect.rs index f2786efa44cb..91ddaca07d8b 100644 --- a/clippy_lints/src/methods/err_expect.rs +++ b/clippy_lints/src/methods/err_expect.rs @@ -14,19 +14,16 @@ pub(super) fn check( recv: &rustc_hir::Expr<'_>, expect_span: Span, err_span: Span, - msrv: &Msrv, + msrv: Msrv, ) { if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result) - // Test the version to make sure the lint can be showed (expect_err has been - // introduced in rust 1.17.0 : https://github.com/rust-lang/rust/pull/38982) - && msrv.meets(msrvs::EXPECT_ERR) - // Grabs the `Result` type && let result_type = cx.typeck_results().expr_ty(recv) // Tests if the T type in a `Result` is not None && let Some(data_type) = get_data_type(cx, result_type) // Tests if the T type in a `Result` implements debug && has_debug_impl(cx, data_type) + && msrv.meets(cx, msrvs::EXPECT_ERR) { span_lint_and_sugg( cx, diff --git a/clippy_lints/src/methods/filter_map_next.rs b/clippy_lints/src/methods/filter_map_next.rs index 3f89e5931487..9f3c346042ff 100644 --- a/clippy_lints/src/methods/filter_map_next.rs +++ b/clippy_lints/src/methods/filter_map_next.rs @@ -14,10 +14,10 @@ pub(super) fn check<'tcx>( expr: &'tcx hir::Expr<'_>, recv: &'tcx hir::Expr<'_>, arg: &'tcx hir::Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) { if is_trait_method(cx, expr, sym::Iterator) { - if !msrv.meets(msrvs::ITERATOR_FIND_MAP) { + if !msrv.meets(cx, msrvs::ITERATOR_FIND_MAP) { return; } diff --git a/clippy_lints/src/methods/io_other_error.rs b/clippy_lints/src/methods/io_other_error.rs index e0ce013ca7b7..4659e9e163fe 100644 --- a/clippy_lints/src/methods/io_other_error.rs +++ b/clippy_lints/src/methods/io_other_error.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{IO_ERROR_OTHER, Msrv}; +use clippy_utils::msrvs::{self, Msrv}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::LateContext; -pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, path: &Expr<'_>, args: &[Expr<'_>], msrv: &Msrv) { +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, path: &Expr<'_>, args: &[Expr<'_>], msrv: Msrv) { if let [error_kind, error] = args && !expr.span.from_expansion() && !error_kind.span.from_expansion() @@ -15,7 +15,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, path: &Expr<'_>, args &clippy_utils::paths::IO_ERRORKIND_OTHER, ) && let ExprKind::Path(QPath::TypeRelative(_, new_segment)) = path.kind - && msrv.meets(IO_ERROR_OTHER) + && msrv.meets(cx, msrvs::IO_ERROR_OTHER) { span_lint_and_then( cx, diff --git a/clippy_lints/src/methods/is_digit_ascii_radix.rs b/clippy_lints/src/methods/is_digit_ascii_radix.rs index d8bb9e377a0c..9c32e9ac539d 100644 --- a/clippy_lints/src/methods/is_digit_ascii_radix.rs +++ b/clippy_lints/src/methods/is_digit_ascii_radix.rs @@ -12,12 +12,8 @@ pub(super) fn check<'tcx>( expr: &'tcx Expr<'_>, self_arg: &'tcx Expr<'_>, radix: &'tcx Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) { - if !msrv.meets(msrvs::IS_ASCII_DIGIT) { - return; - } - if !cx.typeck_results().expr_ty_adjusted(self_arg).peel_refs().is_char() { return; } @@ -30,6 +26,10 @@ pub(super) fn check<'tcx>( }; let mut applicability = Applicability::MachineApplicable; + if !msrv.meets(cx, msrvs::IS_ASCII_DIGIT) { + return; + } + span_lint_and_sugg( cx, IS_DIGIT_ASCII_RADIX, diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index 518041177e92..94415fc91061 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -20,9 +20,9 @@ pub(super) fn check<'tcx>( expr: &'tcx Expr<'tcx>, // .iter().map(|(_, v_| v)) recv: &'tcx Expr<'tcx>, // hashmap m_arg: &'tcx Expr<'tcx>, // |(_, v)| v - msrv: &Msrv, + msrv: Msrv, ) { - if map_type == "into_iter" && !msrv.meets(msrvs::INTO_KEYS) { + if map_type == "into_iter" && !msrv.meets(cx, msrvs::INTO_KEYS) { return; } if !expr.span.from_expansion() diff --git a/clippy_lints/src/methods/manual_c_str_literals.rs b/clippy_lints/src/methods/manual_c_str_literals.rs index e1ebca0b09df..0274e31b4c33 100644 --- a/clippy_lints/src/methods/manual_c_str_literals.rs +++ b/clippy_lints/src/methods/manual_c_str_literals.rs @@ -22,7 +22,7 @@ pub(super) fn check_as_ptr<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, receiver: &'tcx Expr<'tcx>, - msrv: &Msrv, + msrv: Msrv, ) { if let ExprKind::Lit(lit) = receiver.kind && let LitKind::ByteStr(_, StrStyle::Cooked) | LitKind::Str(_, StrStyle::Cooked) = lit.node @@ -32,7 +32,7 @@ pub(super) fn check_as_ptr<'tcx>( |parent| matches!(parent.kind, ExprKind::Call(func, _) if is_c_str_function(cx, func).is_some()), ) && let Some(sugg) = rewrite_as_cstr(cx, lit.span) - && msrv.meets(msrvs::C_STR_LITERALS) + && msrv.meets(cx, msrvs::C_STR_LITERALS) { span_lint_and_sugg( cx, @@ -65,11 +65,11 @@ fn is_c_str_function(cx: &LateContext<'_>, func: &Expr<'_>) -> Option { /// - `CStr::from_bytes_with_nul(..)` /// - `CStr::from_bytes_with_nul_unchecked(..)` /// - `CStr::from_ptr(..)` -pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>], msrv: &Msrv) { +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>], msrv: Msrv) { if let Some(fn_name) = is_c_str_function(cx, func) && let [arg] = args && cx.tcx.sess.edition() >= Edition2021 - && msrv.meets(msrvs::C_STR_LITERALS) + && msrv.meets(cx, msrvs::C_STR_LITERALS) { match fn_name.as_str() { name @ ("from_bytes_with_nul" | "from_bytes_with_nul_unchecked") diff --git a/clippy_lints/src/methods/manual_inspect.rs b/clippy_lints/src/methods/manual_inspect.rs index 09ccb386a20b..173ebcb7020b 100644 --- a/clippy_lints/src/methods/manual_inspect.rs +++ b/clippy_lints/src/methods/manual_inspect.rs @@ -14,14 +14,14 @@ use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use super::MANUAL_INSPECT; #[expect(clippy::too_many_lines)] -pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: &str, name_span: Span, msrv: &Msrv) { +pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: &str, name_span: Span, msrv: Msrv) { if let ExprKind::Closure(c) = arg.kind && matches!(c.kind, ClosureKind::Closure) && let typeck = cx.typeck_results() && let Some(fn_id) = typeck.type_dependent_def_id(expr.hir_id) && (is_diag_trait_item(cx, fn_id, sym::Iterator) - || (msrv.meets(msrvs::OPTION_RESULT_INSPECT) - && (is_diag_item_method(cx, fn_id, sym::Option) || is_diag_item_method(cx, fn_id, sym::Result)))) + || ((is_diag_item_method(cx, fn_id, sym::Option) || is_diag_item_method(cx, fn_id, sym::Result)) + && msrv.meets(cx, msrvs::OPTION_RESULT_INSPECT))) && let body = cx.tcx.hir_body(c.body) && let [param] = body.params && let PatKind::Binding(BindingMode(ByRef::No, Mutability::Not), arg_id, _, None) = param.pat.kind diff --git a/clippy_lints/src/methods/manual_is_variant_and.rs b/clippy_lints/src/methods/manual_is_variant_and.rs index 90e502f244fa..40aad03960c4 100644 --- a/clippy_lints/src/methods/manual_is_variant_and.rs +++ b/clippy_lints/src/methods/manual_is_variant_and.rs @@ -14,7 +14,7 @@ pub(super) fn check<'tcx>( map_recv: &'tcx rustc_hir::Expr<'_>, map_arg: &'tcx rustc_hir::Expr<'_>, map_span: Span, - msrv: &Msrv, + msrv: Msrv, ) { // Don't lint if: @@ -36,7 +36,7 @@ pub(super) fn check<'tcx>( } // 4. msrv doesn't meet `OPTION_RESULT_IS_VARIANT_AND` - if !msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND) { + if !msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) { return; } diff --git a/clippy_lints/src/methods/manual_repeat_n.rs b/clippy_lints/src/methods/manual_repeat_n.rs index 6e09bf132aa1..83b57cca17bf 100644 --- a/clippy_lints/src/methods/manual_repeat_n.rs +++ b/clippy_lints/src/methods/manual_repeat_n.rs @@ -14,16 +14,16 @@ pub(super) fn check<'tcx>( expr: &'tcx Expr<'tcx>, repeat_expr: &Expr<'_>, take_arg: &Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) { - if msrv.meets(msrvs::REPEAT_N) - && !expr.span.from_expansion() + if !expr.span.from_expansion() && is_trait_method(cx, expr, sym::Iterator) && let ExprKind::Call(_, [repeat_arg]) = repeat_expr.kind && let Some(def_id) = fn_def_id(cx, repeat_expr) && cx.tcx.is_diagnostic_item(sym::iter_repeat, def_id) && !expr_use_ctxt(cx, expr).is_ty_unified && let Some(std_or_core) = std_or_core(cx) + && msrv.meets(cx, msrvs::REPEAT_N) { let mut app = Applicability::MachineApplicable; span_lint_and_sugg( diff --git a/clippy_lints/src/methods/manual_try_fold.rs b/clippy_lints/src/methods/manual_try_fold.rs index a56378b5b73a..23dba47f60f4 100644 --- a/clippy_lints/src/methods/manual_try_fold.rs +++ b/clippy_lints/src/methods/manual_try_fold.rs @@ -17,10 +17,9 @@ pub(super) fn check<'tcx>( init: &Expr<'_>, acc: &Expr<'_>, fold_span: Span, - msrv: &Msrv, + msrv: Msrv, ) { if !fold_span.in_external_macro(cx.sess().source_map()) - && msrv.meets(msrvs::ITERATOR_TRY_FOLD) && is_trait_method(cx, expr, sym::Iterator) && let init_ty = cx.typeck_results().expr_ty(init) && let Some(try_trait) = cx.tcx.lang_items().try_trait() @@ -29,6 +28,7 @@ pub(super) fn check<'tcx>( && let ExprKind::Path(qpath) = path.kind && let Res::Def(DefKind::Ctor(_, _), _) = cx.qpath_res(&qpath, path.hir_id) && let ExprKind::Closure(closure) = acc.kind + && msrv.meets(cx, msrvs::ITERATOR_TRY_FOLD) && !is_from_proc_macro(cx, expr) && let Some(args_snip) = closure .fn_arg_span diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs index b2705e1ffc2d..128b3695f48b 100644 --- a/clippy_lints/src/methods/map_clone.rs +++ b/clippy_lints/src/methods/map_clone.rs @@ -41,7 +41,7 @@ fn should_run_lint(cx: &LateContext<'_>, e: &hir::Expr<'_>, method_id: DefId) -> true } -pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>, msrv: &Msrv) { +pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>, msrv: Msrv) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && should_run_lint(cx, e, method_id) { @@ -169,10 +169,10 @@ fn lint_path(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool) { ); } -fn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool, msrv: &Msrv) { +fn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool, msrv: Msrv) { let mut applicability = Applicability::MachineApplicable; - let (message, sugg_method) = if is_copy && msrv.meets(msrvs::ITERATOR_COPIED) { + let (message, sugg_method) = if is_copy && msrv.meets(cx, msrvs::ITERATOR_COPIED) { ("you are using an explicit closure for copying elements", "copied") } else { ("you are using an explicit closure for cloning elements", "cloned") diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs index 428da0cf107e..df5a0de3392b 100644 --- a/clippy_lints/src/methods/map_unwrap_or.rs +++ b/clippy_lints/src/methods/map_unwrap_or.rs @@ -19,13 +19,13 @@ pub(super) fn check<'tcx>( recv: &'tcx hir::Expr<'_>, map_arg: &'tcx hir::Expr<'_>, unwrap_arg: &'tcx hir::Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) -> bool { // lint if the caller of `map()` is an `Option` or a `Result`. let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option); let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result); - if is_result && !msrv.meets(msrvs::RESULT_MAP_OR_ELSE) { + if is_result && !msrv.meets(cx, msrvs::RESULT_MAP_OR_ELSE) { return false; } diff --git a/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs b/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs index 35dd7c082c90..6cf0936c598f 100644 --- a/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs +++ b/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs @@ -62,7 +62,7 @@ pub(super) fn check( ex: &Expr<'_>, receiver: &Expr<'_>, arg: &Expr<'_>, - msrv: &Msrv, + msrv: Msrv, method_call_span: Span, ) { let mut applicability = Applicability::MaybeIncorrect; @@ -82,7 +82,7 @@ pub(super) fn check( let use_take; if eager_or_lazy::switch_to_eager_eval(cx, body_expr) { - if msrv.meets(msrvs::REPEAT_N) { + if msrv.meets(cx, msrvs::REPEAT_N) { method_to_use_name = "repeat_n"; let body_snippet = snippet_with_applicability(cx, body_expr.span, "..", &mut applicability); new_span = (arg.span, format!("{body_snippet}, {count}")); @@ -93,7 +93,7 @@ pub(super) fn check( new_span = (arg.span, body_snippet.to_string()); use_take = true; } - } else if msrv.meets(msrvs::REPEAT_WITH) { + } else if msrv.meets(cx, msrvs::REPEAT_WITH) { method_to_use_name = "repeat_with"; new_span = (param.span, String::new()); use_take = true; diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 0c154b296bc1..94d3657d9f12 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -4503,7 +4503,7 @@ impl Methods { Self { avoid_breaking_exported_api: conf.avoid_breaking_exported_api, - msrv: conf.msrv.clone(), + msrv: conf.msrv, allow_expect_in_tests: conf.allow_expect_in_tests, allow_unwrap_in_tests: conf.allow_unwrap_in_tests, allow_expect_in_consts: conf.allow_expect_in_consts, @@ -4688,9 +4688,9 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ExprKind::Call(func, args) => { from_iter_instead_of_collect::check(cx, expr, args, func); unnecessary_fallible_conversions::check_function(cx, expr, func); - manual_c_str_literals::check(cx, expr, func, args, &self.msrv); - useless_nonzero_new_unchecked::check(cx, expr, func, args, &self.msrv); - io_other_error::check(cx, expr, func, args, &self.msrv); + manual_c_str_literals::check(cx, expr, func, args, self.msrv); + useless_nonzero_new_unchecked::check(cx, expr, func, args, self.msrv); + io_other_error::check(cx, expr, func, args, self.msrv); }, ExprKind::MethodCall(method_call, receiver, args, _) => { let method_span = method_call.ident.span; @@ -4709,7 +4709,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { inefficient_to_string::check(cx, expr, method_call.ident.name, receiver, args); single_char_add_str::check(cx, expr, receiver, args); into_iter_on_ref::check(cx, expr, method_span, method_call.ident.name, receiver); - unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, &self.msrv); + unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, self.msrv); }, ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => { let mut info = BinaryExprInfo { @@ -4855,8 +4855,6 @@ impl<'tcx> LateLintPass<'tcx> for Methods { ); } } - - extract_msrv_attr!(LateContext); } impl Methods { @@ -4914,7 +4912,7 @@ impl Methods { && let body = cx.tcx.hir_body(arg.body) && let [param] = body.params => { - string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), &self.msrv); + string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), self.msrv); }, Some(("map", _, [map_arg], _, map_call_span)) => { map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, "any"); @@ -4938,12 +4936,12 @@ impl Methods { sliced_string_as_bytes::check(cx, expr, recv); }, ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv), - ("as_ptr", []) => manual_c_str_literals::check_as_ptr(cx, expr, recv, &self.msrv), + ("as_ptr", []) => manual_c_str_literals::check_as_ptr(cx, expr, recv, self.msrv), ("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv), ("assume_init", []) => uninit_assumed_init::check(cx, expr, recv), ("bytes", []) => unbuffered_bytes::check(cx, expr, recv), ("cloned", []) => { - cloned_instead_of_copied::check(cx, expr, recv, span, &self.msrv); + cloned_instead_of_copied::check(cx, expr, recv, span, self.msrv); option_as_ref_cloned::check(cx, recv, span); }, ("collect", []) if is_trait_method(cx, expr, sym::Iterator) => { @@ -4957,7 +4955,7 @@ impl Methods { format_collect::check(cx, expr, m_arg, m_ident_span); }, Some(("take", take_self_arg, [take_arg], _, _)) => { - if self.msrv.meets(msrvs::STR_REPEAT) { + if self.msrv.meets(cx, msrvs::STR_REPEAT) { manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg); } }, @@ -4996,13 +4994,13 @@ impl Methods { if let ExprKind::MethodCall(.., span) = expr.kind { case_sensitive_file_extension_comparisons::check(cx, expr, span, recv, arg); } - path_ends_with_ext::check(cx, recv, arg, expr, &self.msrv, &self.allowed_dotfiles); + path_ends_with_ext::check(cx, recv, arg, expr, self.msrv, &self.allowed_dotfiles); }, ("expect", [_]) => { match method_call(recv) { Some(("ok", recv, [], _, _)) => ok_expect::check(cx, expr, recv), Some(("err", recv, [], err_span, _)) => { - err_expect::check(cx, expr, recv, span, err_span, &self.msrv); + err_expect::check(cx, expr, recv, span, err_span, self.msrv); }, _ => unwrap_expect_used::check( cx, @@ -5044,7 +5042,7 @@ impl Methods { false, ); } - if self.msrv.meets(msrvs::ITER_FLATTEN) { + if self.msrv.meets(cx, msrvs::ITER_FLATTEN) { // use the sourcemap to get the span of the closure iter_filter::check(cx, expr, arg, span); } @@ -5092,7 +5090,7 @@ impl Methods { _ => {}, }, ("fold", [init, acc]) => { - manual_try_fold::check(cx, expr, init, acc, call_span, &self.msrv); + manual_try_fold::check(cx, expr, init, acc, call_span, self.msrv); unnecessary_fold::check(cx, expr, init, acc, span); }, ("for_each", [arg]) => { @@ -5133,7 +5131,7 @@ impl Methods { is_empty::check(cx, expr, recv); }, ("is_file", []) => filetype_is_file::check(cx, expr, recv), - ("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, &self.msrv), + ("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv), ("is_none", []) => check_is_some_is_none(cx, expr, recv, call_span, false), ("is_some", []) => check_is_some_is_none(cx, expr, recv, call_span, true), ("iter" | "iter_mut" | "into_iter", []) => { @@ -5170,11 +5168,11 @@ impl Methods { (name @ ("map" | "map_err"), [m_arg]) => { if name == "map" { unused_enumerate_index::check(cx, expr, recv, m_arg); - map_clone::check(cx, expr, recv, m_arg, &self.msrv); - map_with_unused_argument_over_ranges::check(cx, expr, recv, m_arg, &self.msrv, span); + map_clone::check(cx, expr, recv, m_arg, self.msrv); + map_with_unused_argument_over_ranges::check(cx, expr, recv, m_arg, self.msrv, span); match method_call(recv) { Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) => { - iter_kv_map::check(cx, map_name, expr, recv2, m_arg, &self.msrv); + iter_kv_map::check(cx, map_name, expr, recv2, m_arg, self.msrv); }, Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( cx, @@ -5191,8 +5189,8 @@ impl Methods { } if let Some((name, recv2, args, span2, _)) = method_call(recv) { match (name, args) { - ("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, &self.msrv), - ("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, &self.msrv), + ("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, self.msrv), + ("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, self.msrv), ("filter", [f_arg]) => { filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, false); }, @@ -5203,7 +5201,7 @@ impl Methods { } } map_identity::check(cx, expr, recv, m_arg, name, span); - manual_inspect::check(cx, expr, m_arg, name, span, &self.msrv); + manual_inspect::check(cx, expr, m_arg, name, span, self.msrv); crate::useless_conversion::check_function_application(cx, expr, recv, m_arg); }, ("map_break" | "map_continue", [m_arg]) => { @@ -5212,7 +5210,7 @@ impl Methods { ("map_or", [def, map]) => { option_map_or_none::check(cx, expr, recv, def, map); manual_ok_or::check(cx, expr, recv, def, map); - unnecessary_map_or::check(cx, expr, recv, def, map, span, &self.msrv); + unnecessary_map_or::check(cx, expr, recv, def, map, span, self.msrv); }, ("map_or_else", [def, map]) => { result_map_or_else_none::check(cx, expr, recv, def, map); @@ -5230,7 +5228,7 @@ impl Methods { false, ), ("filter", [arg]) => filter_next::check(cx, expr, recv2, arg), - ("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, &self.msrv), + ("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, self.msrv), ("iter", []) => iter_next_slice::check(cx, expr, recv2), ("skip", [arg]) => iter_skip_next::check(cx, expr, recv2, arg), ("skip_while", [_]) => skip_while_next::check(cx, expr), @@ -5286,7 +5284,7 @@ impl Methods { no_effect_replace::check(cx, expr, arg1, arg2); // Check for repeated `str::replace` calls to perform `collapsible_str_replace` lint - if self.msrv.meets(msrvs::PATTERN_TRAIT_CHAR_ARRAY) + if self.msrv.meets(cx, msrvs::PATTERN_TRAIT_CHAR_ARRAY) && name == "replace" && let Some(("replace", ..)) = method_call(recv) { @@ -5297,10 +5295,10 @@ impl Methods { vec_resize_to_zero::check(cx, expr, count_arg, default_arg, span); }, ("seek", [arg]) => { - if self.msrv.meets(msrvs::SEEK_FROM_CURRENT) { + if self.msrv.meets(cx, msrvs::SEEK_FROM_CURRENT) { seek_from_current::check(cx, expr, recv, arg); } - if self.msrv.meets(msrvs::SEEK_REWIND) { + if self.msrv.meets(cx, msrvs::SEEK_REWIND) { seek_to_start_instead_of_rewind::check(cx, expr, recv, arg, span); } }, @@ -5334,7 +5332,7 @@ impl Methods { ("splitn" | "rsplitn", [count_arg, pat_arg]) => { if let Some(Constant::Int(count)) = ConstEvalCtxt::new(cx).eval(count_arg) { suspicious_splitn::check(cx, name, expr, recv, count); - str_splitn::check(cx, name, expr, recv, pat_arg, count, &self.msrv); + str_splitn::check(cx, name, expr, recv, pat_arg, count, self.msrv); } }, ("splitn_mut" | "rsplitn_mut", [count_arg, _]) => { @@ -5345,7 +5343,7 @@ impl Methods { ("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg), ("take", [arg]) => { iter_out_of_bounds::check_take(cx, expr, recv, arg); - manual_repeat_n::check(cx, expr, recv, arg, &self.msrv); + manual_repeat_n::check(cx, expr, recv, arg, self.msrv); if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { iter_overeager_cloned::check( cx, @@ -5359,7 +5357,7 @@ impl Methods { }, ("take", []) => needless_option_take::check(cx, expr, recv), ("then", [arg]) => { - if !self.msrv.meets(msrvs::BOOL_THEN_SOME) { + if !self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) { return; } unnecessary_lazy_eval::check(cx, expr, recv, arg, "then_some"); @@ -5420,7 +5418,7 @@ impl Methods { manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, &arith["checked_".len()..]); }, Some(("map", m_recv, [m_arg], span, _)) => { - option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, &self.msrv); + option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv); }, Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => { obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method, "unwrap_or"); @@ -5431,7 +5429,7 @@ impl Methods { }, ("unwrap_or_default", []) => { if let Some(("map", m_recv, [arg], span, _)) = method_call(recv) { - manual_is_variant_and::check(cx, expr, m_recv, arg, span, &self.msrv); + manual_is_variant_and::check(cx, expr, m_recv, arg, span, self.msrv); } unnecessary_literal_unwrap::check(cx, expr, recv, name, args); }, @@ -5441,7 +5439,7 @@ impl Methods { ("unwrap_or_else", [u_arg]) => { match method_call(recv) { Some(("map", recv, [map_arg], _, _)) - if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {}, + if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {}, Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => { obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method, "unwrap_or_else"); }, diff --git a/clippy_lints/src/methods/option_as_ref_deref.rs b/clippy_lints/src/methods/option_as_ref_deref.rs index 469fcccbe4f6..63ee922acfa0 100644 --- a/clippy_lints/src/methods/option_as_ref_deref.rs +++ b/clippy_lints/src/methods/option_as_ref_deref.rs @@ -18,12 +18,8 @@ pub(super) fn check( as_ref_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>, is_mut: bool, - msrv: &Msrv, + msrv: Msrv, ) { - if !msrv.meets(msrvs::OPTION_AS_DEREF) { - return; - } - let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not); let option_ty = cx.typeck_results().expr_ty(as_ref_recv); @@ -93,7 +89,7 @@ pub(super) fn check( _ => false, }; - if is_deref { + if is_deref && msrv.meets(cx, msrvs::OPTION_AS_DEREF) { let current_method = if is_mut { format!(".as_mut().map({})", snippet(cx, map_arg.span, "..")) } else { diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index b1107d8cc72f..4ba8e0109042 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -24,7 +24,7 @@ pub(super) fn check<'tcx>( unwrap_recv: &rustc_hir::Expr<'_>, unwrap_arg: &'tcx rustc_hir::Expr<'_>, map_span: Span, - msrv: &Msrv, + msrv: Msrv, ) { // lint if the caller of `map()` is an `Option` if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option) { @@ -71,9 +71,9 @@ pub(super) fn check<'tcx>( } // is_some_and is stabilised && `unwrap_or` argument is false; suggest `is_some_and` instead - let suggest_is_some_and = msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND) - && matches!(&unwrap_arg.kind, ExprKind::Lit(lit) - if matches!(lit.node, rustc_ast::LitKind::Bool(false))); + let suggest_is_some_and = matches!(&unwrap_arg.kind, ExprKind::Lit(lit) + if matches!(lit.node, rustc_ast::LitKind::Bool(false))) + && msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND); let mut applicability = Applicability::MachineApplicable; // get snippet for unwrap_or() diff --git a/clippy_lints/src/methods/path_ends_with_ext.rs b/clippy_lints/src/methods/path_ends_with_ext.rs index b3811a335e1a..d3f513e7abd2 100644 --- a/clippy_lints/src/methods/path_ends_with_ext.rs +++ b/clippy_lints/src/methods/path_ends_with_ext.rs @@ -20,7 +20,7 @@ pub(super) fn check( recv: &Expr<'_>, path: &Expr<'_>, expr: &Expr<'_>, - msrv: &Msrv, + msrv: Msrv, allowed_dotfiles: &FxHashSet<&'static str>, ) { if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv).peel_refs(), sym::Path) @@ -33,7 +33,7 @@ pub(super) fn check( && path.chars().all(char::is_alphanumeric) { let mut sugg = snippet(cx, recv.span, "..").into_owned(); - if msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND) { + if msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) { let _ = write!(sugg, r#".extension().is_some_and(|ext| ext == "{path}")"#); } else { let _ = write!(sugg, r#".extension().map_or(false, |ext| ext == "{path}")"#); diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs index 8389c2e3f982..4ccefb7ec9d7 100644 --- a/clippy_lints/src/methods/str_splitn.rs +++ b/clippy_lints/src/methods/str_splitn.rs @@ -23,7 +23,7 @@ pub(super) fn check( self_arg: &Expr<'_>, pat_arg: &Expr<'_>, count: u128, - msrv: &Msrv, + msrv: Msrv, ) { if count < 2 || !cx.typeck_results().expr_ty_adjusted(self_arg).peel_refs().is_str() { return; @@ -33,7 +33,7 @@ pub(super) fn check( IterUsageKind::Nth(n) => count > n + 1, IterUsageKind::NextTuple => count > 2, }; - let manual = count == 2 && msrv.meets(msrvs::STR_SPLIT_ONCE); + let manual = count == 2 && msrv.meets(cx, msrvs::STR_SPLIT_ONCE); match parse_iter_usage(cx, expr.span.ctxt(), cx.tcx.hir_parent_iter(expr.hir_id)) { Some(usage) if needless(usage.kind) => lint_needless(cx, method_name, expr, self_arg, pat_arg), diff --git a/clippy_lints/src/methods/string_lit_chars_any.rs b/clippy_lints/src/methods/string_lit_chars_any.rs index cb719b34b1f0..f0f9d30d3000 100644 --- a/clippy_lints/src/methods/string_lit_chars_any.rs +++ b/clippy_lints/src/methods/string_lit_chars_any.rs @@ -17,10 +17,9 @@ pub(super) fn check<'tcx>( recv: &Expr<'_>, param: &'tcx Param<'tcx>, body: &Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) { - if msrv.meets(msrvs::MATCHES_MACRO) - && is_trait_method(cx, expr, sym::Iterator) + if is_trait_method(cx, expr, sym::Iterator) && let PatKind::Binding(_, arg, _, _) = param.pat.kind && let ExprKind::Lit(lit_kind) = recv.kind && let LitKind::Str(val, _) = lit_kind.node @@ -33,6 +32,7 @@ pub(super) fn check<'tcx>( (false, true) => lhs, _ => return, } + && msrv.meets(cx, msrvs::MATCHES_MACRO) && !is_from_proc_macro(cx, expr) && let Some(scrutinee_snip) = scrutinee.span.get_source_text(cx) { diff --git a/clippy_lints/src/methods/unnecessary_map_or.rs b/clippy_lints/src/methods/unnecessary_map_or.rs index 3a669fca177f..d7bd522ddab9 100644 --- a/clippy_lints/src/methods/unnecessary_map_or.rs +++ b/clippy_lints/src/methods/unnecessary_map_or.rs @@ -42,7 +42,7 @@ pub(super) fn check<'a>( def: &Expr<'_>, map: &Expr<'_>, method_span: Span, - msrv: &Msrv, + msrv: Msrv, ) { let ExprKind::Lit(def_kind) = def.kind else { return; @@ -119,14 +119,14 @@ pub(super) fn check<'a>( .into_string(); (vec![(expr.span, sugg)], "a standard comparison", app) - } else if !def_bool && msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND) { + } else if !def_bool && msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) { let suggested_name = variant.method_name(); ( vec![(method_span, suggested_name.into()), (ext_def_span, String::default())], suggested_name, Applicability::MachineApplicable, ) - } else if def_bool && matches!(variant, Variant::Some) && msrv.meets(msrvs::IS_NONE_OR) { + } else if def_bool && matches!(variant, Variant::Some) && msrv.meets(cx, msrvs::IS_NONE_OR) { ( vec![(method_span, "is_none_or".into()), (ext_def_span, String::default())], "is_none_or", diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index ea134c057053..a71b3659fd24 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -31,7 +31,7 @@ pub fn check<'tcx>( method_name: Symbol, receiver: &'tcx Expr<'_>, args: &'tcx [Expr<'_>], - msrv: &Msrv, + msrv: Msrv, ) { if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && args.is_empty() @@ -207,7 +207,7 @@ fn check_into_iter_call_arg( expr: &Expr<'_>, method_name: Symbol, receiver: &Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) -> bool { if let Some(parent) = get_parent_expr(cx, expr) && let Some(callee_def_id) = fn_def_id(cx, parent) @@ -224,7 +224,7 @@ fn check_into_iter_call_arg( return true; } - let cloned_or_copied = if is_copy(cx, item_ty) && msrv.meets(msrvs::ITERATOR_COPIED) { + let cloned_or_copied = if is_copy(cx, item_ty) && msrv.meets(cx, msrvs::ITERATOR_COPIED) { "copied" } else { "cloned" diff --git a/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs b/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs index 0bd50429c09d..22df1f3f485e 100644 --- a/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs +++ b/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs @@ -10,13 +10,13 @@ use rustc_span::sym; use super::USELESS_NONZERO_NEW_UNCHECKED; -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, func: &Expr<'tcx>, args: &[Expr<'_>], msrv: &Msrv) { - if msrv.meets(msrvs::CONST_UNWRAP) - && let ExprKind::Path(QPath::TypeRelative(ty, segment)) = func.kind +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, func: &Expr<'tcx>, args: &[Expr<'_>], msrv: Msrv) { + if let ExprKind::Path(QPath::TypeRelative(ty, segment)) = func.kind && segment.ident.name == sym::new_unchecked && let [init_arg] = args && is_inside_always_const_context(cx.tcx, expr.hir_id) && is_type_diagnostic_item(cx, cx.typeck_results().node_type(ty.hir_id), sym::NonZero) + && msrv.meets(cx, msrvs::CONST_UNWRAP) { let mut app = Applicability::MachineApplicable; let ty_str = snippet_with_applicability(cx, ty.span, "_", &mut app); diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index bc60fa507b12..38a19dd2999b 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -80,9 +80,7 @@ pub struct MissingConstForFn { impl MissingConstForFn { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -101,10 +99,6 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { return; } - if !self.msrv.meets(msrvs::CONST_IF_MATCH) { - return; - } - if span.in_external_macro(cx.tcx.sess.source_map()) || is_entrypoint_fn(cx, def_id.to_def_id()) { return; } @@ -123,7 +117,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { .iter() .any(|param| matches!(param.kind, GenericParamKind::Const { .. })); - if already_const(header) || has_const_generic_params || !could_be_const_with_abi(&self.msrv, header.abi) + if already_const(header) + || has_const_generic_params + || !could_be_const_with_abi(cx, self.msrv, header.abi) { return; } @@ -152,13 +148,17 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { } } + if !self.msrv.meets(cx, msrvs::CONST_IF_MATCH) { + return; + } + if is_from_proc_macro(cx, &(&kind, body, hir_id, span)) { return; } let mir = cx.tcx.optimized_mir(def_id); - if let Ok(()) = is_min_const_fn(cx.tcx, mir, &self.msrv) + if let Ok(()) = is_min_const_fn(cx, mir, self.msrv) && let hir::Node::Item(hir::Item { vis_span, .. }) | hir::Node::ImplItem(hir::ImplItem { vis_span, .. }) = cx.tcx.hir_node_by_def_id(def_id) { @@ -173,8 +173,6 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { }); } } - - extract_msrv_attr!(LateContext); } // We don't have to lint on something that's already `const` @@ -183,13 +181,13 @@ fn already_const(header: hir::FnHeader) -> bool { header.constness == Constness::Const } -fn could_be_const_with_abi(msrv: &Msrv, abi: ExternAbi) -> bool { +fn could_be_const_with_abi(cx: &LateContext<'_>, msrv: Msrv, abi: ExternAbi) -> bool { match abi { ExternAbi::Rust => true, // `const extern "C"` was stabilized after 1.62.0 - ExternAbi::C { unwind: false } => msrv.meets(msrvs::CONST_EXTERN_C_FN), + ExternAbi::C { unwind: false } => msrv.meets(cx, msrvs::CONST_EXTERN_C_FN), // Rest ABIs are still unstable and need the `const_extern_fn` feature enabled. - _ => msrv.meets(msrvs::CONST_EXTERN_FN), + _ => msrv.meets(cx, msrvs::CONST_EXTERN_FN), } } diff --git a/clippy_lints/src/missing_const_for_thread_local.rs b/clippy_lints/src/missing_const_for_thread_local.rs index d4181c677afd..ea74940828a1 100644 --- a/clippy_lints/src/missing_const_for_thread_local.rs +++ b/clippy_lints/src/missing_const_for_thread_local.rs @@ -49,9 +49,7 @@ pub struct MissingConstForThreadLocal { impl MissingConstForThreadLocal { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -91,11 +89,11 @@ fn is_unreachable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { } #[inline] -fn initializer_can_be_made_const(cx: &LateContext<'_>, defid: rustc_span::def_id::DefId, msrv: &Msrv) -> bool { +fn initializer_can_be_made_const(cx: &LateContext<'_>, defid: rustc_span::def_id::DefId, msrv: Msrv) -> bool { // Building MIR for `fn`s with unsatisfiable preds results in ICE. if !fn_has_unsatisfiable_preds(cx, defid) && let mir = cx.tcx.optimized_mir(defid) - && let Ok(()) = is_min_const_fn(cx.tcx, mir, msrv) + && let Ok(()) = is_min_const_fn(cx, mir, msrv) { return true; } @@ -113,8 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForThreadLocal { local_defid: rustc_span::def_id::LocalDefId, ) { let defid = local_defid.to_def_id(); - if self.msrv.meets(msrvs::THREAD_LOCAL_CONST_INIT) - && is_thread_local_initializer(cx, fn_kind, span).unwrap_or(false) + if is_thread_local_initializer(cx, fn_kind, span).unwrap_or(false) // Some implementations of `thread_local!` include an initializer fn. // In the case of a const initializer, the init fn is also const, // so we can skip the lint in that case. This occurs only on some @@ -131,11 +128,12 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForThreadLocal { // https://github.com/rust-lang/rust-clippy/issues/12637 // we ensure that this is reachable before we check in mir && !is_unreachable(cx, ret_expr) - && initializer_can_be_made_const(cx, defid, &self.msrv) + && initializer_can_be_made_const(cx, defid, self.msrv) // we know that the function is const-qualifiable, so now // we need only to get the initializer expression to span-lint it. && let initializer_snippet = snippet(cx, ret_expr.span, "thread_local! { ... }") && initializer_snippet != "thread_local! { ... }" + && self.msrv.meets(cx, msrvs::THREAD_LOCAL_CONST_INIT) { span_lint_and_sugg( cx, @@ -148,6 +146,4 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForThreadLocal { ); } } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/needless_borrows_for_generic_args.rs b/clippy_lints/src/needless_borrows_for_generic_args.rs index ea1d7e5d4382..f686cc912ddb 100644 --- a/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -72,7 +72,7 @@ impl NeedlessBorrowsForGenericArgs<'_> { pub fn new(conf: &'static Conf) -> Self { Self { possible_borrowers: Vec::new(), - msrv: conf.msrv.clone(), + msrv: conf.msrv, } } } @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { i, param_ty, expr, - &self.msrv, + self.msrv, ) && count != 0 { @@ -142,8 +142,6 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { self.possible_borrowers.pop(); } } - - extract_msrv_attr!(LateContext); } fn path_has_args(p: &QPath<'_>) -> bool { @@ -172,7 +170,7 @@ fn needless_borrow_count<'tcx>( arg_index: usize, param_ty: ParamTy, mut expr: &Expr<'tcx>, - msrv: &Msrv, + msrv: Msrv, ) -> usize { let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait(); let sized_trait_def_id = cx.tcx.lang_items().sized_trait(); @@ -273,7 +271,7 @@ fn needless_borrow_count<'tcx>( && let ty::Param(param_ty) = trait_predicate.self_ty().kind() && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack() && ty.is_array() - && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) + && !msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) { return false; } diff --git a/clippy_lints/src/non_std_lazy_statics.rs b/clippy_lints/src/non_std_lazy_statics.rs index 774a182d089f..a82365f94318 100644 --- a/clippy_lints/src/non_std_lazy_statics.rs +++ b/clippy_lints/src/non_std_lazy_statics.rs @@ -1,8 +1,8 @@ use clippy_config::Conf; use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; -use clippy_utils::msrvs::Msrv; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::visitors::for_each_expr; -use clippy_utils::{def_path_def_ids, fn_def_id, path_def_id}; +use clippy_utils::{def_path_def_ids, fn_def_id, is_no_std_crate, path_def_id}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; @@ -75,7 +75,7 @@ impl NonStdLazyStatic { #[must_use] pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: conf.msrv, lazy_static_lazy_static: Vec::new(), once_cell_crate: Vec::new(), once_cell_sync_lazy: Vec::new(), @@ -89,23 +89,12 @@ impl NonStdLazyStatic { impl_lint_pass!(NonStdLazyStatic => [NON_STD_LAZY_STATICS]); -/// Return if current MSRV does not meet the requirement for `lazy_cell` feature, -/// or current context has `no_std` attribute. -macro_rules! ensure_prerequisite { - ($msrv:expr, $cx:ident) => { - if !$msrv.meets(clippy_utils::msrvs::LAZY_CELL) || clippy_utils::is_no_std_crate($cx) { - return; - } - }; +fn can_use_lazy_cell(cx: &LateContext<'_>, msrv: Msrv) -> bool { + msrv.meets(cx, msrvs::LAZY_CELL) && !is_no_std_crate(cx) } impl<'hir> LateLintPass<'hir> for NonStdLazyStatic { - extract_msrv_attr!(LateContext); - fn check_crate(&mut self, cx: &LateContext<'hir>) { - // Do not lint if current crate does not support `LazyLock`. - ensure_prerequisite!(self.msrv, cx); - // Fetch def_ids for external paths self.lazy_static_lazy_static = def_path_def_ids(cx.tcx, &["lazy_static", "lazy_static"]).collect(); self.once_cell_sync_lazy = def_path_def_ids(cx.tcx, &["once_cell", "sync", "Lazy"]).collect(); @@ -123,11 +112,10 @@ impl<'hir> LateLintPass<'hir> for NonStdLazyStatic { } fn check_item(&mut self, cx: &LateContext<'hir>, item: &Item<'hir>) { - ensure_prerequisite!(self.msrv, cx); - if let ItemKind::Static(..) = item.kind && let Some(macro_call) = clippy_utils::macros::root_macro_call(item.span) && self.lazy_static_lazy_static.contains(¯o_call.def_id) + && can_use_lazy_cell(cx, self.msrv) { span_lint( cx, @@ -142,14 +130,14 @@ impl<'hir> LateLintPass<'hir> for NonStdLazyStatic { return; } - if let Some(lazy_info) = LazyInfo::from_item(self, cx, item) { + if let Some(lazy_info) = LazyInfo::from_item(self, cx, item) + && can_use_lazy_cell(cx, self.msrv) + { self.lazy_type_defs.insert(item.owner_id.to_def_id(), lazy_info); } } fn check_expr(&mut self, cx: &LateContext<'hir>, expr: &Expr<'hir>) { - ensure_prerequisite!(self.msrv, cx); - // All functions in the `FUNCTION_REPLACEMENTS` have only one args if let ExprKind::Call(callee, [arg]) = expr.kind && let Some(call_def_id) = fn_def_id(cx, expr) @@ -163,8 +151,6 @@ impl<'hir> LateLintPass<'hir> for NonStdLazyStatic { } fn check_ty(&mut self, cx: &LateContext<'hir>, ty: &'hir rustc_hir::Ty<'hir, rustc_hir::AmbigArg>) { - ensure_prerequisite!(self.msrv, cx); - // Record if types from `once_cell` besides `sync::Lazy` are used. if let rustc_hir::TyKind::Path(qpath) = ty.peel_refs().kind && let Some(ty_def_id) = cx.qpath_res(&qpath, ty.hir_id).opt_def_id() @@ -178,8 +164,6 @@ impl<'hir> LateLintPass<'hir> for NonStdLazyStatic { } fn check_crate_post(&mut self, cx: &LateContext<'hir>) { - ensure_prerequisite!(self.msrv, cx); - if !self.uses_other_once_cell_types { for (_, lazy_info) in &self.lazy_type_defs { lazy_info.lint(cx, &self.sugg_map); diff --git a/clippy_lints/src/operators/manual_midpoint.rs b/clippy_lints/src/operators/manual_midpoint.rs index 61ef5670a5ad..81721a9f2af5 100644 --- a/clippy_lints/src/operators/manual_midpoint.rs +++ b/clippy_lints/src/operators/manual_midpoint.rs @@ -16,7 +16,7 @@ pub(super) fn check<'tcx>( op: BinOpKind, left: &'tcx Expr<'_>, right: &'tcx Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) { if !left.span.from_expansion() && !right.span.from_expansion() @@ -29,7 +29,7 @@ pub(super) fn check<'tcx>( && left_ty == right_ty // Do not lint on `(_+1)/2` and `(1+_)/2`, it is likely a `div_ceil()` operation && !is_integer_literal(ll_expr, 1) && !is_integer_literal(lr_expr, 1) - && is_midpoint_implemented(left_ty, msrv) + && is_midpoint_implemented(cx, left_ty, msrv) { let mut app = Applicability::MachineApplicable; let left_sugg = Sugg::hir_with_context(cx, ll_expr, expr.span.ctxt(), "..", &mut app); @@ -55,10 +55,10 @@ fn add_operands<'e, 'tcx>(expr: &'e Expr<'tcx>) -> Option<(&'e Expr<'tcx>, &'e E } } -fn is_midpoint_implemented(ty: Ty<'_>, msrv: &Msrv) -> bool { +fn is_midpoint_implemented(cx: &LateContext<'_>, ty: Ty<'_>, msrv: Msrv) -> bool { match ty.kind() { - ty::Uint(_) | ty::Float(_) => msrv.meets(msrvs::UINT_FLOAT_MIDPOINT), - ty::Int(_) => msrv.meets(msrvs::INT_MIDPOINT), + ty::Uint(_) | ty::Float(_) => msrv.meets(cx, msrvs::UINT_FLOAT_MIDPOINT), + ty::Int(_) => msrv.meets(cx, msrvs::INT_MIDPOINT), _ => false, } } diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 43b657ea7ff0..80459945094e 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -872,7 +872,7 @@ impl Operators { arithmetic_context: numeric_arithmetic::Context::default(), verbose_bit_mask_threshold: conf.verbose_bit_mask_threshold, modulo_arithmetic_allow_comparison_to_zero: conf.allow_comparison_to_zero, - msrv: conf.msrv.clone(), + msrv: conf.msrv, } } } @@ -922,7 +922,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators { identity_op::check(cx, e, op.node, lhs, rhs); needless_bitwise_bool::check(cx, e, op.node, lhs, rhs); ptr_eq::check(cx, e, op.node, lhs, rhs); - manual_midpoint::check(cx, e, op.node, lhs, rhs, &self.msrv); + manual_midpoint::check(cx, e, op.node, lhs, rhs, self.msrv); } self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs); bit_mask::check(cx, e, op.node, lhs, rhs); @@ -973,8 +973,6 @@ impl<'tcx> LateLintPass<'tcx> for Operators { fn check_body_post(&mut self, cx: &LateContext<'tcx>, b: &Body<'_>) { self.arithmetic_context.body_post(cx, b); } - - extract_msrv_attr!(LateContext); } fn macro_with_not_op(e: &Expr<'_>) -> bool { diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index ffc3b86c502e..4f5f3eb6c15a 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -68,7 +68,7 @@ impl_lint_pass!(QuestionMark => [QUESTION_MARK, MANUAL_LET_ELSE]); impl QuestionMark { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: conf.msrv, matches_behaviour: conf.matches_for_let_else, try_block_depth_stack: Vec::new(), inferred_ret_closure_stack: 0, @@ -543,5 +543,4 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark { .expect("blocks are always part of bodies and must have a depth") -= 1; } } - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index 1b0c0a4956f7..cc423eca74fb 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -166,9 +166,7 @@ pub struct Ranges { impl Ranges { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -182,7 +180,7 @@ impl_lint_pass!(Ranges => [ impl<'tcx> LateLintPass<'tcx> for Ranges { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Binary(ref op, l, r) = expr.kind { - if self.msrv.meets(msrvs::RANGE_CONTAINS) { + if self.msrv.meets(cx, msrvs::RANGE_CONTAINS) { check_possible_range_contains(cx, op.node, l, r, expr, expr.span); } } @@ -191,7 +189,6 @@ impl<'tcx> LateLintPass<'tcx> for Ranges { check_inclusive_range_minus_one(cx, expr); check_reversed_empty_range(cx, expr); } - extract_msrv_attr!(LateContext); } fn check_possible_range_contains( diff --git a/clippy_lints/src/redundant_field_names.rs b/clippy_lints/src/redundant_field_names.rs index 707abc008a86..feefe10f57d7 100644 --- a/clippy_lints/src/redundant_field_names.rs +++ b/clippy_lints/src/redundant_field_names.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::msrvs::{self, MsrvStack}; use rustc_ast::ast::{Expr, ExprKind}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; @@ -36,13 +36,13 @@ declare_clippy_lint! { } pub struct RedundantFieldNames { - msrv: Msrv, + msrv: MsrvStack, } impl RedundantFieldNames { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: MsrvStack::new(conf.msrv), } } } @@ -80,5 +80,6 @@ impl EarlyLintPass for RedundantFieldNames { } } } - extract_msrv_attr!(EarlyContext); + + extract_msrv_attr!(); } diff --git a/clippy_lints/src/redundant_static_lifetimes.rs b/clippy_lints/src/redundant_static_lifetimes.rs index 06c854338066..b4e1f70d1535 100644 --- a/clippy_lints/src/redundant_static_lifetimes.rs +++ b/clippy_lints/src/redundant_static_lifetimes.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::msrvs::{self, MsrvStack}; use clippy_utils::source::snippet; use rustc_ast::ast::{ConstItem, Item, ItemKind, StaticItem, Ty, TyKind}; use rustc_errors::Applicability; @@ -35,13 +35,13 @@ declare_clippy_lint! { } pub struct RedundantStaticLifetimes { - msrv: Msrv, + msrv: MsrvStack, } impl RedundantStaticLifetimes { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: MsrvStack::new(conf.msrv), } } } @@ -115,5 +115,5 @@ impl EarlyLintPass for RedundantStaticLifetimes { } } - extract_msrv_attr!(EarlyContext); + extract_msrv_attr!(); } diff --git a/clippy_lints/src/repeat_vec_with_capacity.rs b/clippy_lints/src/repeat_vec_with_capacity.rs index 40263afd28f1..8805687efccf 100644 --- a/clippy_lints/src/repeat_vec_with_capacity.rs +++ b/clippy_lints/src/repeat_vec_with_capacity.rs @@ -18,9 +18,7 @@ pub struct RepeatVecWithCapacity { impl RepeatVecWithCapacity { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -101,13 +99,14 @@ fn check_vec_macro(cx: &LateContext<'_>, expr: &Expr<'_>) { } /// Checks `iter::repeat(Vec::with_capacity(x))` -fn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>) { +fn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Msrv) { if !expr.span.from_expansion() && fn_def_id(cx, expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::iter_repeat, did)) && let ExprKind::Call(_, [repeat_expr]) = expr.kind && fn_def_id(cx, repeat_expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::vec_with_capacity, did)) && !repeat_expr.span.from_expansion() && let Some(exec_context) = std_or_core(cx) + && msrv.meets(cx, msrvs::REPEAT_WITH) { emit_lint( cx, @@ -126,10 +125,6 @@ fn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>) { impl LateLintPass<'_> for RepeatVecWithCapacity { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { check_vec_macro(cx, expr); - if self.msrv.meets(msrvs::REPEAT_WITH) { - check_repeat_fn(cx, expr); - } + check_repeat_fn(cx, expr, self.msrv); } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index 59c13a1e2c53..d68ac8bab128 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -99,7 +99,7 @@ impl StdReexports { pub fn new(conf: &'static Conf) -> Self { Self { prev_span: Span::default(), - msrv: conf.msrv.clone(), + msrv: conf.msrv, } } } @@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, _: HirId) { if let Res::Def(_, def_id) = path.res && let Some(first_segment) = get_first_segment(path) - && is_stable(cx, def_id, &self.msrv) + && is_stable(cx, def_id, self.msrv) && !path.span.in_external_macro(cx.sess().source_map()) && !is_from_proc_macro(cx, &first_segment.ident) { @@ -153,8 +153,6 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { } } } - - extract_msrv_attr!(LateContext); } /// Returns the first named segment of a [`Path`]. @@ -174,7 +172,7 @@ fn get_first_segment<'tcx>(path: &Path<'tcx>) -> Option<&'tcx PathSegment<'tcx>> /// or now stable moves that were once unstable. /// /// Does not catch individually moved items -fn is_stable(cx: &LateContext<'_>, mut def_id: DefId, msrv: &Msrv) -> bool { +fn is_stable(cx: &LateContext<'_>, mut def_id: DefId, msrv: Msrv) -> bool { loop { if let Some(stability) = cx.tcx.lookup_stability(def_id) && let StabilityLevel::Stable { @@ -183,8 +181,8 @@ fn is_stable(cx: &LateContext<'_>, mut def_id: DefId, msrv: &Msrv) -> bool { } = stability.level { let stable = match since { - StableSince::Version(v) => msrv.meets(v), - StableSince::Current => msrv.current().is_none(), + StableSince::Version(v) => msrv.meets(cx, v), + StableSince::Current => msrv.current(cx).is_none(), StableSince::Err => false, }; diff --git a/clippy_lints/src/string_patterns.rs b/clippy_lints/src/string_patterns.rs index 694ad4f6347b..5c95dfe83473 100644 --- a/clippy_lints/src/string_patterns.rs +++ b/clippy_lints/src/string_patterns.rs @@ -77,9 +77,7 @@ pub struct StringPatterns { impl StringPatterns { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -136,7 +134,7 @@ fn get_char_span<'tcx>(cx: &'_ LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Optio } } -fn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr<'_>, msrv: &Msrv) { +fn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr<'_>, msrv: Msrv) { if let ExprKind::Closure(closure) = method_arg.kind && let body = cx.tcx.hir_body(closure.body) && let Some(PatKind::Binding(_, binding, ..)) = body.params.first().map(|p| p.pat.kind) @@ -192,7 +190,7 @@ fn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr< { return; } - if set_char_spans.len() > 1 && !msrv.meets(msrvs::PATTERN_TRAIT_CHAR_ARRAY) { + if set_char_spans.len() > 1 && !msrv.meets(cx, msrvs::PATTERN_TRAIT_CHAR_ARRAY) { return; } span_lint_and_then( @@ -238,9 +236,7 @@ impl<'tcx> LateLintPass<'tcx> for StringPatterns { { check_single_char_pattern_lint(cx, arg); - check_manual_pattern_char_comparison(cx, arg, &self.msrv); + check_manual_pattern_char_comparison(cx, arg, self.msrv); } } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index cbf7b126632e..f961e1c4d1a3 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -95,7 +95,7 @@ impl TraitBounds { pub fn new(conf: &'static Conf) -> Self { Self { max_trait_bounds: conf.max_trait_bounds, - msrv: conf.msrv.clone(), + msrv: conf.msrv, } } } @@ -223,17 +223,15 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { } } } - - extract_msrv_attr!(LateContext); } impl TraitBounds { /// Is the given bound a `?Sized` bound, and is combining it (i.e. `T: X + ?Sized`) an error on /// this MSRV? See for details. fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool { - if !self.msrv.meets(msrvs::MAYBE_BOUND_IN_WHERE) - && let GenericBound::Trait(tr) = bound + if let GenericBound::Trait(tr) = bound && let BoundPolarity::Maybe(_) = tr.modifiers.polarity + && !self.msrv.meets(cx, msrvs::MAYBE_BOUND_IN_WHERE) { cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id() } else { diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 7c83a2187990..f2da8d35cb4f 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -598,9 +598,7 @@ impl_lint_pass!(Transmute => [ ]); impl Transmute { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } impl<'tcx> LateLintPass<'tcx> for Transmute { @@ -632,16 +630,16 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { | crosspointer_transmute::check(cx, e, from_ty, to_ty) | transmuting_null::check(cx, e, arg, to_ty) | transmute_null_to_fn::check(cx, e, arg, to_ty) - | transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, &self.msrv) + | transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, self.msrv) | missing_transmute_annotations::check(cx, path, from_ty, to_ty, e.hir_id) | transmute_int_to_char::check(cx, e, from_ty, to_ty, arg, const_context) | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context) - | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, &self.msrv) + | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, self.msrv) | transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg) - | transmute_int_to_float::check(cx, e, from_ty, to_ty, arg, const_context, &self.msrv) + | transmute_int_to_float::check(cx, e, from_ty, to_ty, arg, const_context, self.msrv) | transmute_int_to_non_zero::check(cx, e, from_ty, to_ty, arg) - | transmute_float_to_int::check(cx, e, from_ty, to_ty, arg, const_context, &self.msrv) - | transmute_num_to_bytes::check(cx, e, from_ty, to_ty, arg, const_context, &self.msrv) + | transmute_float_to_int::check(cx, e, from_ty, to_ty, arg, const_context, self.msrv) + | transmute_num_to_bytes::check(cx, e, from_ty, to_ty, arg, const_context, self.msrv) | (unsound_collection_transmute::check(cx, e, from_ty, to_ty) || transmute_undefined_repr::check(cx, e, from_ty, to_ty)) | (eager_transmute::check(cx, e, arg, from_ty, to_ty)); @@ -651,6 +649,4 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { } } } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/transmute/transmute_float_to_int.rs b/clippy_lints/src/transmute/transmute_float_to_int.rs index f0b8abf9af66..f2c757952af3 100644 --- a/clippy_lints/src/transmute/transmute_float_to_int.rs +++ b/clippy_lints/src/transmute/transmute_float_to_int.rs @@ -17,11 +17,11 @@ pub(super) fn check<'tcx>( to_ty: Ty<'tcx>, mut arg: &'tcx Expr<'_>, const_context: bool, - msrv: &Msrv, + msrv: Msrv, ) -> bool { match (&from_ty.kind(), &to_ty.kind()) { (ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) - if !const_context || msrv.meets(msrvs::CONST_FLOAT_BITS_CONV) => + if !const_context || msrv.meets(cx, msrvs::CONST_FLOAT_BITS_CONV) => { span_lint_and_then( cx, diff --git a/clippy_lints/src/transmute/transmute_int_to_float.rs b/clippy_lints/src/transmute/transmute_int_to_float.rs index e5b9aea6423a..aaa95396b4b4 100644 --- a/clippy_lints/src/transmute/transmute_int_to_float.rs +++ b/clippy_lints/src/transmute/transmute_int_to_float.rs @@ -16,10 +16,10 @@ pub(super) fn check<'tcx>( to_ty: Ty<'tcx>, arg: &'tcx Expr<'_>, const_context: bool, - msrv: &Msrv, + msrv: Msrv, ) -> bool { match (&from_ty.kind(), &to_ty.kind()) { - (ty::Int(_) | ty::Uint(_), ty::Float(_)) if !const_context || msrv.meets(msrvs::CONST_FLOAT_BITS_CONV) => { + (ty::Int(_) | ty::Uint(_), ty::Float(_)) if !const_context || msrv.meets(cx, msrvs::CONST_FLOAT_BITS_CONV) => { span_lint_and_then( cx, TRANSMUTE_INT_TO_FLOAT, diff --git a/clippy_lints/src/transmute/transmute_num_to_bytes.rs b/clippy_lints/src/transmute/transmute_num_to_bytes.rs index 6d828bad9b32..d72be270b731 100644 --- a/clippy_lints/src/transmute/transmute_num_to_bytes.rs +++ b/clippy_lints/src/transmute/transmute_num_to_bytes.rs @@ -16,14 +16,15 @@ pub(super) fn check<'tcx>( to_ty: Ty<'tcx>, arg: &'tcx Expr<'_>, const_context: bool, - msrv: &Msrv, + msrv: Msrv, ) -> bool { match (&from_ty.kind(), &to_ty.kind()) { (ty::Int(_) | ty::Uint(_) | ty::Float(_), ty::Array(arr_ty, _)) => { if !matches!(arr_ty.kind(), ty::Uint(UintTy::U8)) { return false; } - if matches!(from_ty.kind(), ty::Float(_)) && const_context && !msrv.meets(msrvs::CONST_FLOAT_BITS_CONV) { + if matches!(from_ty.kind(), ty::Float(_)) && const_context && !msrv.meets(cx, msrvs::CONST_FLOAT_BITS_CONV) + { return false; } diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs index c4a2e20fa9d3..fcc763763bd2 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs @@ -15,7 +15,7 @@ pub(super) fn check<'tcx>( from_ty: Ty<'tcx>, to_ty: Ty<'tcx>, arg: &'tcx Expr<'_>, - msrv: &Msrv, + msrv: Msrv, ) -> bool { match (from_ty.kind(), to_ty.kind()) { (ty::RawPtr(from_pointee_ty, from_mutbl), ty::RawPtr(to_pointee_ty, to_mutbl)) => { @@ -28,7 +28,7 @@ pub(super) fn check<'tcx>( if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) { if from_mutbl == to_mutbl && to_pointee_ty.is_sized(cx.tcx, cx.typing_env()) - && msrv.meets(msrvs::POINTER_CAST) + && msrv.meets(cx, msrvs::POINTER_CAST) { diag.span_suggestion_verbose( e.span, @@ -43,7 +43,7 @@ pub(super) fn check<'tcx>( _ => None, } && !from_pointee_ty.has_erased_regions() - && msrv.meets(msrvs::POINTER_CAST_CONSTNESS) + && msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS) { diag.span_suggestion_verbose( e.span, diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index ef18633d945f..45ee83c78ab6 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -17,7 +17,7 @@ pub(super) fn check<'tcx>( to_ty: Ty<'tcx>, arg: &'tcx Expr<'_>, path: &'tcx Path<'_>, - msrv: &Msrv, + msrv: Msrv, ) -> bool { match (&from_ty.kind(), &to_ty.kind()) { (ty::RawPtr(from_ptr_ty, _), ty::Ref(_, to_ref_ty, mutbl)) => { @@ -37,7 +37,7 @@ pub(super) fn check<'tcx>( let sugg = if let Some(ty) = get_explicit_type(path) { let ty_snip = snippet_with_applicability(cx, ty.span, "..", &mut app); - if msrv.meets(msrvs::POINTER_CAST) { + if msrv.meets(cx, msrvs::POINTER_CAST) { format!("{deref}{}.cast::<{ty_snip}>()", arg.maybe_par()) } else if from_ptr_ty.has_erased_regions() { sugg::make_unop(deref, arg.as_ty(format!("{cast} () as {cast} {ty_snip}"))).to_string() @@ -46,7 +46,7 @@ pub(super) fn check<'tcx>( } } else if *from_ptr_ty == *to_ref_ty { if from_ptr_ty.has_erased_regions() { - if msrv.meets(msrvs::POINTER_CAST) { + if msrv.meets(cx, msrvs::POINTER_CAST) { format!("{deref}{}.cast::<{to_ref_ty}>()", arg.maybe_par()) } else { sugg::make_unop(deref, arg.as_ty(format!("{cast} () as {cast} {to_ref_ty}"))) diff --git a/clippy_lints/src/tuple_array_conversions.rs b/clippy_lints/src/tuple_array_conversions.rs index c7aefc65f707..95ce19975c7e 100644 --- a/clippy_lints/src/tuple_array_conversions.rs +++ b/clippy_lints/src/tuple_array_conversions.rs @@ -47,15 +47,13 @@ pub struct TupleArrayConversions { } impl TupleArrayConversions { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } impl LateLintPass<'_> for TupleArrayConversions { fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { - if expr.span.in_external_macro(cx.sess().source_map()) || !self.msrv.meets(msrvs::TUPLE_ARRAY_CONVERSIONS) { + if expr.span.in_external_macro(cx.sess().source_map()) || !self.msrv.meets(cx, msrvs::TUPLE_ARRAY_CONVERSIONS) { return; } @@ -65,8 +63,6 @@ impl LateLintPass<'_> for TupleArrayConversions { _ => {}, } } - - extract_msrv_attr!(LateContext); } fn check_array<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &'tcx [Expr<'tcx>]) { diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 8923484bb58f..f43715d6752e 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -3,7 +3,7 @@ use clippy_config::Conf; use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_maybe_qself, eq_pat, eq_path}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::msrvs::{self, MsrvStack}; use clippy_utils::over; use rustc_ast::PatKind::*; use rustc_ast::mut_visit::*; @@ -48,13 +48,13 @@ declare_clippy_lint! { } pub struct UnnestedOrPatterns { - msrv: Msrv, + msrv: MsrvStack, } impl UnnestedOrPatterns { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: MsrvStack::new(conf.msrv), } } } @@ -88,7 +88,7 @@ impl EarlyLintPass for UnnestedOrPatterns { } } - extract_msrv_attr!(EarlyContext); + extract_msrv_attr!(); } fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) { diff --git a/clippy_lints/src/unused_trait_names.rs b/clippy_lints/src/unused_trait_names.rs index f83415834351..2577f1ceaa2c 100644 --- a/clippy_lints/src/unused_trait_names.rs +++ b/clippy_lints/src/unused_trait_names.rs @@ -51,9 +51,7 @@ pub struct UnusedTraitNames { impl UnusedTraitNames { pub fn new(conf: &'static Conf) -> Self { - Self { - msrv: conf.msrv.clone(), - } + Self { msrv: conf.msrv } } } @@ -61,8 +59,7 @@ impl_lint_pass!(UnusedTraitNames => [UNUSED_TRAIT_NAMES]); impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - if self.msrv.meets(msrvs::UNDERSCORE_IMPORTS) - && !item.span.in_external_macro(cx.sess().source_map()) + if !item.span.in_external_macro(cx.sess().source_map()) && let ItemKind::Use(path, UseKind::Single) = item.kind // Ignore imports that already use Underscore && item.ident.name != kw::Underscore @@ -74,6 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames { && cx.tcx.visibility(item.owner_id.def_id) == Visibility::Restricted(module.to_def_id()) && let Some(last_segment) = path.segments.last() && let Some(snip) = snippet_opt(cx, last_segment.ident.span) + && self.msrv.meets(cx, msrvs::UNDERSCORE_IMPORTS) && !is_from_proc_macro(cx, &last_segment.ident) { let complete_span = last_segment.ident.span.to(item.ident.span); @@ -88,6 +86,4 @@ impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames { ); } } - - extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 569260eda34c..743f54ca993a 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -62,7 +62,7 @@ pub struct UseSelf { impl UseSelf { pub fn new(conf: &'static Conf) -> Self { Self { - msrv: conf.msrv.clone(), + msrv: conf.msrv, stack: Vec::new(), } } @@ -198,7 +198,6 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) { if !hir_ty.span.from_expansion() - && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS) && let Some(&StackItem::Check { impl_id, ref types_to_skip, @@ -216,6 +215,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { // the lifetime parameters of `ty` are elided (`impl<'a> Foo<'a> { fn new() -> Self { Foo{..} } }`, in // which case we must still trigger the lint. && (has_no_lifetime(ty) || same_lifetimes(ty, impl_ty)) + && self.msrv.meets(cx, msrvs::TYPE_ALIAS_ENUM_VARIANTS) { span_lint(cx, hir_ty.span); } @@ -223,9 +223,9 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if !expr.span.from_expansion() - && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS) && let Some(&StackItem::Check { impl_id, .. }) = self.stack.last() && cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id).instantiate_identity() + && self.msrv.meets(cx, msrvs::TYPE_ALIAS_ENUM_VARIANTS) { } else { return; @@ -244,19 +244,17 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) { if !pat.span.from_expansion() - && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS) && let Some(&StackItem::Check { impl_id, .. }) = self.stack.last() // get the path from the pattern && let PatKind::Expr(&PatExpr { kind: PatExprKind::Path(QPath::Resolved(_, path)), .. }) | PatKind::TupleStruct(QPath::Resolved(_, path), _, _) | PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind && cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).instantiate_identity() + && self.msrv.meets(cx, msrvs::TYPE_ALIAS_ENUM_VARIANTS) { check_path(cx, path); } } - - extract_msrv_attr!(LateContext); } #[derive(Default)] diff --git a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs index 686922461530..558acacb9724 100644 --- a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs +++ b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs @@ -30,8 +30,7 @@ impl LateLintPass<'_> for MsrvAttrImpl { .tcx .impl_trait_ref(item.owner_id) .map(EarlyBinder::instantiate_identity) - && let is_late_pass = match_def_path(cx, trait_ref.def_id, &paths::LATE_LINT_PASS) - && (is_late_pass || match_def_path(cx, trait_ref.def_id, &paths::EARLY_LINT_PASS)) + && match_def_path(cx, trait_ref.def_id, &paths::EARLY_LINT_PASS) && let ty::Adt(self_ty_def, _) = trait_ref.self_ty().kind() && self_ty_def.is_struct() && self_ty_def.all_fields().any(|f| { @@ -40,20 +39,18 @@ impl LateLintPass<'_> for MsrvAttrImpl { .instantiate_identity() .walk() .filter(|t| matches!(t.unpack(), GenericArgKind::Type(_))) - .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV)) + .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV_STACK)) }) && !items.iter().any(|item| item.ident.name.as_str() == "check_attributes") { - let context = if is_late_pass { "LateContext" } else { "EarlyContext" }; - let lint_pass = if is_late_pass { "LateLintPass" } else { "EarlyLintPass" }; let span = cx.sess().source_map().span_through_char(item.span, '{'); span_lint_and_sugg( cx, MISSING_MSRV_ATTR_IMPL, span, - format!("`extract_msrv_attr!` macro missing from `{lint_pass}` implementation"), - format!("add `extract_msrv_attr!({context})` to the `{lint_pass}` implementation"), - format!("{}\n extract_msrv_attr!({context});", snippet(cx, span, "..")), + "`extract_msrv_attr!` macro missing from `EarlyLintPass` implementation", + "add `extract_msrv_attr!()` to the `EarlyLintPass` implementation", + format!("{}\n extract_msrv_attr!();", snippet(cx, span, "..")), Applicability::MachineApplicable, ); } diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 03c667846b61..3346b15dae9c 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -27,7 +27,7 @@ impl UselessVec { pub fn new(conf: &'static Conf) -> Self { Self { too_large_for_stack: conf.too_large_for_stack, - msrv: conf.msrv.clone(), + msrv: conf.msrv, span_to_lint_map: BTreeMap::new(), allow_in_test: conf.allow_useless_vec_in_tests, } @@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { }, // search for `for _ in vec![...]` Node::Expr(Expr { span, .. }) - if span.is_desugaring(DesugaringKind::ForLoop) && self.msrv.meets(msrvs::ARRAY_INTO_ITERATOR) => + if span.is_desugaring(DesugaringKind::ForLoop) && self.msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) => { let suggest_slice = suggest_type(expr); self.check_vec_macro(cx, &vec_args, callsite, expr.hir_id, suggest_slice); @@ -149,8 +149,6 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { } } } - - extract_msrv_attr!(LateContext); } impl UselessVec { diff --git a/tests/ui-internal/invalid_msrv_attr_impl.stderr b/tests/ui-internal/invalid_msrv_attr_impl.stderr index 8ba42e4bb2b2..0a7636313eff 100644 --- a/tests/ui-internal/invalid_msrv_attr_impl.stderr +++ b/tests/ui-internal/invalid_msrv_attr_impl.stderr @@ -12,7 +12,7 @@ LL | #![deny(clippy::internal)] = note: `#[deny(clippy::missing_msrv_attr_impl)]` implied by `#[deny(clippy::internal)]` help: add `extract_msrv_attr!()` to the `EarlyLintPass` implementation | -LL + impl EarlyLintPass for Pass { +LL ~ impl EarlyLintPass for Pass { LL + extract_msrv_attr!(); | diff --git a/tests/ui/msrv_attributes_without_early_lints.rs b/tests/ui/msrv_attributes_without_early_lints.rs index dec62c15079d..dcef1a485fce 100644 --- a/tests/ui/msrv_attributes_without_early_lints.rs +++ b/tests/ui/msrv_attributes_without_early_lints.rs @@ -1,3 +1,5 @@ +//@check-pass + #![allow(clippy::all, clippy::pedantic, clippy::restriction, clippy::nursery)] #![forbid(clippy::ptr_as_ptr)] From 2d3639d55915748aeef28cab982492581d2a0bfc Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Fri, 28 Feb 2025 14:27:22 -0500 Subject: [PATCH 478/991] tests: adapt for LLVM 21 changes Per discussion in #137799 we don't really need this readonly attribute, so let's just drop it so the test passes on LLVM 21. Fixes #137799. --- tests/codegen/issues/issue-114312.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/codegen/issues/issue-114312.rs b/tests/codegen/issues/issue-114312.rs index e9418249089d..61355dd5873c 100644 --- a/tests/codegen/issues/issue-114312.rs +++ b/tests/codegen/issues/issue-114312.rs @@ -15,7 +15,6 @@ pub enum Expr { #[no_mangle] pub extern "C" fn issue_114312(expr: Expr) { // CHECK-LABEL: @issue_114312( - // CHECK-NOT: readonly // CHECK-SAME: byval // CHECK-NEXT: start: // CHECK-NEXT: ret void From 900aab72cd801926ee52ba02d982ae6d92c0df4d Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 28 Feb 2025 21:09:27 +0100 Subject: [PATCH 479/991] Fix ICE in manual_map lint node_args doesn't work with struct literals and expr_ty must be used instead --- clippy_utils/src/lib.rs | 5 ++++- tests/ui/crashes/ice-14325.rs | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/ui/crashes/ice-14325.rs diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 3e9429399b31..64955003bd2c 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -3651,7 +3651,10 @@ pub fn expr_requires_coercion<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) - ExprKind::Struct(qpath, _, _) => { let res = cx.typeck_results().qpath_res(qpath, expr.hir_id); if let Some((_, v_def)) = adt_and_variant_of_res(cx, res) { - let generic_args = cx.typeck_results().node_args(expr.hir_id); + let rustc_ty::Adt(_, generic_args) = cx.typeck_results().expr_ty_adjusted(expr).kind() else { + // This should never happen, but when it does, not linting is the better option. + return true; + }; v_def .fields .iter() diff --git a/tests/ui/crashes/ice-14325.rs b/tests/ui/crashes/ice-14325.rs new file mode 100644 index 000000000000..d762bd6c9e00 --- /dev/null +++ b/tests/ui/crashes/ice-14325.rs @@ -0,0 +1,17 @@ +//@check-pass + +#![allow(clippy::redundant_pattern_matching)] + +struct S<'a> { + s: &'a str, +} + +fn foo() -> Option> { + if let Some(_) = Some(0) { + Some(S { s: "xyz" }) + } else { + None + } +} + +fn main() {} From a9ca11320a36e9c729b7d4a15959701c72f2f961 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 28 Feb 2025 20:27:19 +0000 Subject: [PATCH 480/991] Update query normalizer docs --- .../src/traits/query/normalize.rs | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 2ef9d5421ba6..6bf76eaee5c6 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -31,20 +31,19 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// normalized. If you don't care about regions, you should prefer /// `normalize_erasing_regions`, which is more efficient. /// - /// If the normalization succeeds and is unambiguous, returns back - /// the normalized value along with various outlives relations (in - /// the form of obligations that must be discharged). + /// If the normalization succeeds, returns back the normalized + /// value along with various outlives relations (in the form of + /// obligations that must be discharged). /// - /// N.B., this will *eventually* be the main means of - /// normalizing, but for now should be used only when we actually - /// know that normalization will succeed, since error reporting - /// and other details are still "under development". - /// - /// This normalization should *only* be used when the projection does not - /// have possible ambiguity or may not be well-formed. + /// This normalization should *only* be used when the projection is well-formed and + /// does not have possible ambiguity (contains inference variables). /// /// After codegen, when lifetimes do not matter, it is preferable to instead /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure. + /// + /// N.B. Once the new solver is stabilized this method of normalization will + /// likely be removed as trait solver operations are already cached by the query + /// system making this redundant. fn query_normalize(self, value: T) -> Result, NoSolution> where T: TypeFoldable>, @@ -210,8 +209,6 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { // See note in `rustc_trait_selection::traits::project` about why we // wait to fold the args. - - // Wrap this in a closure so we don't accidentally return from the outer function let res = match kind { ty::Opaque => { // Only normalize `impl Trait` outside of type inference, usually in codegen. From df5b279ca962a84c83a6766dbb02cf23b866082a Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 25 Feb 2025 00:06:38 +0000 Subject: [PATCH 481/991] Introduce `feature(generic_const_parameter_types)` --- compiler/rustc_feature/src/unstable.rs | 2 + .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- compiler/rustc_hir_analysis/src/collect.rs | 5 +- .../src/collect/predicates_of.rs | 5 +- .../src/hir_ty_lowering/generics.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 67 +++++++++++++++---- compiler/rustc_hir_analysis/src/lib.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 23 +++++-- .../rustc_hir_typeck/src/method/confirm.rs | 6 +- compiler/rustc_middle/src/ty/sty.rs | 1 + compiler/rustc_resolve/messages.ftl | 9 --- compiler/rustc_resolve/src/diagnostics.rs | 6 +- compiler/rustc_resolve/src/errors.rs | 13 ---- compiler/rustc_resolve/src/ident.rs | 42 ++++-------- compiler/rustc_resolve/src/late.rs | 49 ++++++++++---- .../rustc_resolve/src/late/diagnostics.rs | 1 - compiler/rustc_resolve/src/lib.rs | 8 +-- compiler/rustc_span/src/symbol.rs | 1 + .../traits/fulfillment_errors.rs | 3 - ...am-type-depends-on-const-param.full.stderr | 4 -- ...ram-type-depends-on-const-param.min.stderr | 4 -- ...-type-depends-on-type-param-ungated.stderr | 2 - ...ram-type-depends-on-type-param.full.stderr | 2 - ...aram-type-depends-on-type-param.min.stderr | 2 - .../bad_inference.rs | 23 +++++++ .../bad_inference.stderr | 14 ++++ .../evaluate_const_parameter_in_mir.rs | 19 ++++++ .../forward_declared_type.rs | 11 +++ .../forward_declared_type.stderr | 15 +++++ .../inferred_from_arg.rs | 13 ++++ .../lifetime_dependent_const_param.rs | 20 ++++++ .../lifetime_dependent_const_param.stderr | 23 +++++++ .../mismatched_args_with_value.rs | 15 +++++ .../mismatched_args_with_value.stderr | 21 ++++++ .../no_const_param_ty_bound.rs | 9 +++ .../no_const_param_ty_bound.stderr | 11 +++ .../unrelated_inferred_arg.rs | 21 ++++++ .../issues/issue-56445-1.full.stderr | 2 - .../issues/issue-56445-1.min.stderr | 2 - .../issues/issue-62878.full.stderr | 2 - .../issues/issue-62878.min.stderr | 2 - .../issues/issue-71169.full.stderr | 2 - .../issues/issue-71169.min.stderr | 2 - .../issues/issue-71381.full.stderr | 4 -- .../issues/issue-71381.min.stderr | 4 -- .../issues/issue-71611.full.stderr | 2 - .../issues/issue-71611.min.stderr | 2 - .../const-generics/issues/issue-88997.stderr | 4 -- .../const-generics/issues/issue-90364.stderr | 2 - tests/ui/error-codes/E0771.stderr | 2 - ...eneric-const-parameter-types.normal.stderr | 21 ++++++ ...ture-gate-generic-const-parameter-types.rs | 11 +++ .../wfcheck_err_leak_issue_118179.stderr | 2 - .../lifetimes/unusual-rib-combinations.stderr | 2 - ...ce-hir-wf-check-anon-const-issue-122989.rs | 1 + ...ir-wf-check-anon-const-issue-122989.stderr | 26 ++++++- 56 files changed, 419 insertions(+), 154 deletions(-) create mode 100644 tests/ui/const-generics/generic_const_parameter_types/bad_inference.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/bad_inference.stderr create mode 100644 tests/ui/const-generics/generic_const_parameter_types/evaluate_const_parameter_in_mir.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr create mode 100644 tests/ui/const-generics/generic_const_parameter_types/inferred_from_arg.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.stderr create mode 100644 tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.stderr create mode 100644 tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.rs create mode 100644 tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr create mode 100644 tests/ui/const-generics/generic_const_parameter_types/unrelated_inferred_arg.rs create mode 100644 tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr create mode 100644 tests/ui/feature-gates/feature-gate-generic-const-parameter-types.rs diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 66c26a541f17..0acd3b0f8002 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -508,6 +508,8 @@ declare_features! ( (incomplete, generic_const_exprs, "1.56.0", Some(76560)), /// Allows generic parameters and where-clauses on free & associated const items. (incomplete, generic_const_items, "1.73.0", Some(113521)), + /// Allows the type of const generics to depend on generic parameters + (incomplete, generic_const_parameter_types, "CURRENT_RUSTC_VERSION", Some(137626)), /// Allows any generic constants being used as pattern type range ends (incomplete, generic_pattern_types, "1.86.0", Some(136574)), /// Allows registering static items globally, possibly across crates, to iterate over at runtime. diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index e6ea6eddcaaf..d72cf00293f0 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -966,7 +966,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), let ty = tcx.type_of(param.def_id).instantiate_identity(); if tcx.features().unsized_const_params() { - enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| { + enter_wf_checking_ctxt(tcx, hir_ty.span, tcx.local_parent(param.def_id), |wfcx| { wfcx.register_bound( ObligationCause::new( hir_ty.span, @@ -980,7 +980,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), Ok(()) }) } else if tcx.features().adt_const_params() { - enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| { + enter_wf_checking_ctxt(tcx, hir_ty.span, tcx.local_parent(param.def_id), |wfcx| { wfcx.register_bound( ObligationCause::new( hir_ty.span, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 08d63f4349e9..027aa5554a40 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1822,6 +1822,9 @@ fn const_param_default<'tcx>( ), }; let icx = ItemCtxt::new(tcx, def_id); - let ct = icx.lowerer().lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id())); + let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); + let ct = icx + .lowerer() + .lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id(), identity_args)); ty::EarlyBinder::bind(ct) } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 5b511d270743..495493353633 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -223,10 +223,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } hir::GenericParamKind::Const { .. } => { let param_def_id = param.def_id.to_def_id(); - let ct_ty = tcx - .type_of(param_def_id) - .no_bound_vars() - .expect("const parameters cannot be generic"); + let ct_ty = tcx.type_of(param_def_id).instantiate_identity(); let ct = icx.lowerer().lower_const_param(param_def_id, param.hir_id); predicates .insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span)); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 8d58a3bfbd3c..fa58f12c553c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -273,7 +273,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( // We lower to an infer even when the feature gate is not enabled // as it is useful for diagnostics to be able to see a `ConstKind::Infer` - args.push(ctx.provided_kind(param, arg)); + args.push(ctx.provided_kind(&args, param, arg)); args_iter.next(); params.next(); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 750770178eef..a0f848f07c4b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -232,12 +232,15 @@ impl AssocItemQSelf { /// Use this enum with `::lower_const_arg` to instruct it with the /// desired behavior. #[derive(Debug, Clone, Copy)] -pub enum FeedConstTy { +pub enum FeedConstTy<'a, 'tcx> { /// Feed the type. /// /// The `DefId` belongs to the const param that we are supplying /// this (anon) const arg to. - Param(DefId), + /// + /// The list of generic args is used to instantiate the parameters + /// used by the type of the const param specified by `DefId`. + Param(DefId, &'a [ty::GenericArg<'tcx>]), /// Don't feed the type. No, } @@ -298,6 +301,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> { fn provided_kind( &mut self, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx>; @@ -481,6 +485,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn provided_kind( &mut self, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { @@ -526,7 +531,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self .lowerer // Ambig portions of `ConstArg` are handled in the match arm below - .lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id)) + .lower_const_arg( + ct.as_unambig_ct(), + FeedConstTy::Param(param.def_id, preceding_args), + ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { self.lowerer.ct_infer(Some(param), inf.span).into() @@ -582,8 +590,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ty = tcx .at(self.span) .type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"); + .instantiate(tcx, preceding_args); if let Err(guar) = ty.error_reported() { return ty::Const::new_error(tcx, guar).into(); } @@ -2107,14 +2114,50 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { pub fn lower_const_arg( &self, const_arg: &hir::ConstArg<'tcx>, - feed: FeedConstTy, + feed: FeedConstTy<'_, 'tcx>, ) -> Const<'tcx> { let tcx = self.tcx(); - if let FeedConstTy::Param(param_def_id) = feed + if let FeedConstTy::Param(param_def_id, args) = feed && let hir::ConstArgKind::Anon(anon) = &const_arg.kind { - tcx.feed_anon_const_type(anon.def_id, tcx.type_of(param_def_id)); + let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args); + + // We must error if the instantiated type has any inference variables as we will + // use this type to feed the `type_of` and query results must not contain inference + // variables otherwise we will ICE. + // + // We also error if the type contains any regions as effectively any region will wind + // up as a region variable in mir borrowck. It would also be somewhat concerning if + // hir typeck was using equality but mir borrowck wound up using subtyping as that could + // result in a non-infer in hir typeck but a region variable in borrowck. + // + // FIXME(generic_const_parameter_types): Ideally we remove these errors one day when + // we have the ability to intermix typeck of anon const const args with the parent + // bodies typeck. + if tcx.features().generic_const_parameter_types() + && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions()) + { + let e = tcx.dcx().span_err( + const_arg.span(), + "anonymous constants with lifetimes in their type are not yet supported", + ); + tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); + return ty::Const::new_error(tcx, e); + } + if anon_const_type.has_non_region_infer() { + let e = tcx.dcx().span_err( + const_arg.span(), + "anonymous constants with inferred types are not yet supported", + ); + tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); + return ty::Const::new_error(tcx, e); + } + + tcx.feed_anon_const_type( + anon.def_id, + ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)), + ); } let hir_id = const_arg.hir_id; @@ -2230,10 +2273,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let expr = &tcx.hir_body(anon.body).value; debug!(?expr); - let ty = tcx - .type_of(anon.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"); + // FIXME(generic_const_parameter_types): We should use the proper generic args + // here. It's only used as a hint for literals so doesn't matter too much to use the right + // generic arguments, just weaker type inference. + let ty = tcx.type_of(anon.def_id).instantiate_identity(); match self.try_lower_anon_const_lit(ty, expr) { Some(v) => v, diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index bdfbd540e40a..cf18bab950ae 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -260,7 +260,7 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { pub fn lower_const_arg_for_rustdoc<'tcx>( tcx: TyCtxt<'tcx>, hir_ct: &hir::ConstArg<'tcx>, - feed: FeedConstTy, + feed: FeedConstTy<'_, 'tcx>, ) -> Const<'tcx> { let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id); collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2d7d80e39bc3..7c01c26bed87 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -519,7 +519,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn lower_const_arg( &self, const_arg: &'tcx hir::ConstArg<'tcx>, - feed: FeedConstTy, + feed: FeedConstTy<'_, 'tcx>, ) -> ty::Const<'tcx> { let ct = self.lowerer().lower_const_arg(const_arg, feed); self.register_wf_obligation( @@ -1135,7 +1135,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .last() .is_some_and(|GenericPathSegment(def_id, _)| tcx.generics_of(*def_id).has_self); - let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res { + let (res, implicit_args) = if let Res::Def(DefKind::ConstParam, def) = res { + // types of const parameters are somewhat special as they are part of + // the same environment as the const parameter itself. this means that + // unlike most paths `type-of(N)` can return a type naming parameters + // introduced by the containing item, rather than provided through `N`. + // + // for example given `` and some + // `let a = N;` expression. The path to `N` would wind up with no args + // (as it has no args), but instantiating the early binder on `typeof(N)` + // requires providing generic arguments for `[T, M, N]`. + (res, Some(ty::GenericArgs::identity_for_item(tcx, tcx.parent(def)))) + } else if let Res::SelfCtor(impl_def_id) = res { let ty = LoweredTy::from_raw( self, span, @@ -1261,6 +1272,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn provided_kind( &mut self, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { @@ -1280,7 +1292,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self .fcx // Ambiguous parts of `ConstArg` are handled in the match arms below - .lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id)) + .lower_const_arg( + ct.as_unambig_ct(), + FeedConstTy::Param(param.def_id, preceding_args), + ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { self.fcx.ct_infer(Some(param), inf.span).into() @@ -1320,7 +1335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - let args_raw = self_ctor_args.unwrap_or_else(|| { + let args_raw = implicit_args.unwrap_or_else(|| { lower_generic_args( self, def_id, diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 3b107fbf1739..0483164ca030 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -426,6 +426,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn provided_kind( &mut self, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { @@ -446,7 +447,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self .cfcx // We handle the ambig portions of `ConstArg` in the match arms below - .lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id)) + .lower_const_arg( + ct.as_unambig_ct(), + FeedConstTy::Param(param.def_id, preceding_args), + ) .into(), (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { self.cfcx.ct_infer(Some(param), inf.span).into() diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d5617adf26b4..e46ab302be27 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -342,6 +342,7 @@ impl ParamConst { ParamConst::new(def.index, def.name) } + #[instrument(level = "debug")] pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> { let mut candidates = env.caller_bounds().iter().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index b13de2875bc2..9f062b3935fd 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -125,9 +125,6 @@ resolve_const_param_in_enum_discriminant = resolve_const_param_in_non_trivial_anon_const = const parameters may only be used as standalone arguments, i.e. `{$name}` -resolve_const_param_in_ty_of_const_param = - const parameters may not be used in the type of const parameters - resolve_constructor_private_if_any_field_private = a constructor is private if any of the fields is private @@ -250,9 +247,6 @@ resolve_lifetime_param_in_enum_discriminant = resolve_lifetime_param_in_non_trivial_anon_const = lifetime parameters may not be used in const expressions -resolve_lifetime_param_in_ty_of_const_param = - lifetime parameters may not be used in the type of const parameters - resolve_lowercase_self = attempt to use a non-constant value in a constant .suggestion = try using `Self` @@ -437,9 +431,6 @@ resolve_type_param_in_enum_discriminant = resolve_type_param_in_non_trivial_anon_const = type parameters may not be used in const expressions -resolve_type_param_in_ty_of_const_param = - type parameters may not be used in the type of const parameters - resolve_undeclared_label = use of undeclared label `{$name}` .label = undeclared label `{$name}` diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 20af56e7ee48..e3405c89b79a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -890,9 +890,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ResolutionError::ForwardDeclaredGenericParam => { self.dcx().create_err(errs::ForwardDeclaredGenericParam { span }) } - ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self - .dcx() - .create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }), + ResolutionError::ParamInTyOfConstParam { name } => { + self.dcx().create_err(errs::ParamInTyOfConstParam { span, name }) + } ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => { self.dcx().create_err(errs::ParamInNonTrivialAnonConst { span, diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 7eb795034b03..b5d3e5ea7767 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -347,19 +347,6 @@ pub(crate) struct ParamInTyOfConstParam { #[label] pub(crate) span: Span, pub(crate) name: Symbol, - #[subdiagnostic] - pub(crate) param_kind: Option, -} - -#[derive(Debug)] -#[derive(Subdiagnostic)] -pub(crate) enum ParamKindInTyOfConstParam { - #[note(resolve_type_param_in_ty_of_const_param)] - Type, - #[note(resolve_const_param_in_ty_of_const_param)] - Const, - #[note(resolve_lifetime_param_in_ty_of_const_param)] - Lifetime, } #[derive(Diagnostic)] diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 499b9bca4d2a..d9776be4dd0a 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1131,6 +1131,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return Res::Err; } + if let RibKind::ConstParamTy = all_ribs[rib_index].kind { + if let Some(span) = finalize { + self.report_error( + span, + ResolutionError::ParamInTyOfConstParam { name: rib_ident.name }, + ); + } + assert_eq!(res, Res::Err); + return Res::Err; + } + match res { Res::Local(_) => { use ResolutionError::*; @@ -1209,10 +1220,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some(span) = finalize { self.report_error( span, - ParamInTyOfConstParam { - name: rib_ident.name, - param_kind: None, - }, + ParamInTyOfConstParam { name: rib_ident.name }, ); } return Res::Err; @@ -1239,6 +1247,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | RibKind::MacroDefinition(..) | RibKind::InlineAsmSym | RibKind::AssocItem + | RibKind::ConstParamTy | RibKind::ForwardGenericParamBan => { // Nothing to do. Continue. continue; @@ -1292,18 +1301,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { RibKind::Item(has_generic_params, def_kind) => { (has_generic_params, def_kind) } - RibKind::ConstParamTy => { - if let Some(span) = finalize { - self.report_error( - span, - ResolutionError::ParamInTyOfConstParam { - name: rib_ident.name, - param_kind: Some(errors::ParamKindInTyOfConstParam::Type), - }, - ); - } - return Res::Err; - } }; if let Some(span) = finalize { @@ -1328,6 +1325,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | RibKind::MacroDefinition(..) | RibKind::InlineAsmSym | RibKind::AssocItem + | RibKind::ConstParamTy | RibKind::ForwardGenericParamBan => continue, RibKind::ConstantItem(trivial, _) => { @@ -1361,18 +1359,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { RibKind::Item(has_generic_params, def_kind) => { (has_generic_params, def_kind) } - RibKind::ConstParamTy => { - if let Some(span) = finalize { - self.report_error( - span, - ResolutionError::ParamInTyOfConstParam { - name: rib_ident.name, - param_kind: Some(errors::ParamKindInTyOfConstParam::Const), - }, - ); - } - return Res::Err; - } }; // This was an attempt to use a const parameter outside its scope. diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 32ef781631be..f119ed55e7d1 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -227,9 +227,11 @@ impl RibKind<'_> { | RibKind::ConstantItem(..) | RibKind::Module(_) | RibKind::MacroDefinition(_) - | RibKind::ConstParamTy | RibKind::InlineAsmSym => false, - RibKind::AssocItem | RibKind::Item(..) | RibKind::ForwardGenericParamBan => true, + RibKind::ConstParamTy + | RibKind::AssocItem + | RibKind::Item(..) + | RibKind::ForwardGenericParamBan => true, } } @@ -1570,6 +1572,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err); } + let mut forward_ty_ban_rib_const_param_ty = Rib { + bindings: forward_ty_ban_rib.bindings.clone(), + patterns_with_skipped_bindings: FxHashMap::default(), + kind: RibKind::ConstParamTy, + }; + let mut forward_const_ban_rib_const_param_ty = Rib { + bindings: forward_const_ban_rib.bindings.clone(), + patterns_with_skipped_bindings: FxHashMap::default(), + kind: RibKind::ConstParamTy, + }; + self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { for param in params { match param.kind { @@ -1592,21 +1605,27 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } // Allow all following defaults to refer to this type parameter. - forward_ty_ban_rib - .bindings - .remove(&Ident::with_dummy_span(param.ident.name)); + let i = &Ident::with_dummy_span(param.ident.name); + forward_ty_ban_rib.bindings.remove(i); + if this.r.tcx.features().generic_const_parameter_types() { + forward_ty_ban_rib_const_param_ty.bindings.remove(i); + } } GenericParamKind::Const { ref ty, kw_span: _, ref default } => { // Const parameters can't have param bounds. assert!(param.bounds.is_empty()); - this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy)); - this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy)); - this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| { + this.ribs[TypeNS].push(forward_ty_ban_rib_const_param_ty); + this.ribs[ValueNS].push(forward_const_ban_rib_const_param_ty); + if this.r.tcx.features().generic_const_parameter_types() { this.visit_ty(ty) - }); - this.ribs[TypeNS].pop().unwrap(); - this.ribs[ValueNS].pop().unwrap(); + } else { + this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| { + this.visit_ty(ty) + }); + } + forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap(); + forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap(); if let Some(expr) = default { this.ribs[TypeNS].push(forward_ty_ban_rib); @@ -1620,9 +1639,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } // Allow all following defaults to refer to this const parameter. - forward_const_ban_rib - .bindings - .remove(&Ident::with_dummy_span(param.ident.name)); + let i = &Ident::with_dummy_span(param.ident.name); + forward_const_ban_rib.bindings.remove(i); + if this.r.tcx.features().generic_const_parameter_types() { + forward_const_ban_rib_const_param_ty.bindings.remove(i); + } } } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index fa9c42e35933..0e14e7671b17 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3052,7 +3052,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .create_err(errors::ParamInTyOfConstParam { span: lifetime_ref.ident.span, name: lifetime_ref.ident.name, - param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime), }) .emit(); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ea48d0cad745..4c5d4041022a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -30,9 +30,7 @@ use std::sync::Arc; use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; use effective_visibilities::EffectiveVisibilitiesVisitor; -use errors::{ - ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam, -}; +use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; use imports::{Import, ImportData, ImportKind, NameResolution}; use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification}; use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; @@ -276,8 +274,10 @@ enum ResolutionError<'ra> { }, /// Error E0128: generic parameters with a default cannot use forward-declared identifiers. ForwardDeclaredGenericParam, + // FIXME(generic_const_parameter_types): This should give custom output specifying it's only + // problematic to use *forward declared* parameters when the feature is enabled. /// ERROR E0770: the type of const parameters must not depend on other generic parameters. - ParamInTyOfConstParam { name: Symbol, param_kind: Option }, + ParamInTyOfConstParam { name: Symbol }, /// generic parameters must not be used inside const evaluations. /// /// This error is only emitted when using `min_const_generics`. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 501c9039f2de..2a709b072557 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1037,6 +1037,7 @@ symbols! { generic_associated_types_extended, generic_const_exprs, generic_const_items, + generic_const_parameter_types, generic_param_attrs, generic_pattern_types, get_context, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 596f794568c5..75616046a4d6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1189,9 +1189,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let span = obligation.cause.span; let mut diag = match ty.kind() { - _ if ty.has_param() => { - span_bug!(span, "const param tys cannot mention other generic parameters"); - } ty::Float(_) => { struct_span_code_err!( self.dcx(), diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr index 539d840f0a80..f639e276f466 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr @@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Dependent([(); N]); | ^ the type must not depend on the parameter `N` - | - = note: const parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/const-param-type-depends-on-const-param.rs:15:40 | LL | pub struct SelfDependent; | ^ the type must not depend on the parameter `N` - | - = note: const parameters may not be used in the type of const parameters error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr index 18b899632678..44fcf9a13b12 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr @@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Dependent([(); N]); | ^ the type must not depend on the parameter `N` - | - = note: const parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/const-param-type-depends-on-const-param.rs:15:40 | LL | pub struct SelfDependent; | ^ the type must not depend on the parameter `N` - | - = note: const parameters may not be used in the type of const parameters error: `[u8; N]` is forbidden as the type of a const generic parameter --> $DIR/const-param-type-depends-on-const-param.rs:11:47 diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index 55bced29aff1..3075597895b0 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | struct B(PhantomData<[T; N]>); | ^ the type must not depend on the parameter `T` - | - = note: type parameters may not be used in the type of const parameters error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr index 49cf42813235..e8257ace692f 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Dependent([(); X]); | ^ the type must not depend on the parameter `T` - | - = note: type parameters may not be used in the type of const parameters error[E0392]: type parameter `T` is never used --> $DIR/const-param-type-depends-on-type-param.rs:11:22 diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr index 49cf42813235..e8257ace692f 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Dependent([(); X]); | ^ the type must not depend on the parameter `T` - | - = note: type parameters may not be used in the type of const parameters error[E0392]: type parameter `T` is never used --> $DIR/const-param-type-depends-on-type-param.rs:11:22 diff --git a/tests/ui/const-generics/generic_const_parameter_types/bad_inference.rs b/tests/ui/const-generics/generic_const_parameter_types/bad_inference.rs new file mode 100644 index 000000000000..de2e687e870c --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/bad_inference.rs @@ -0,0 +1,23 @@ +#![feature( + adt_const_params, + unsized_const_params, + generic_const_parameter_types, + generic_arg_infer +)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy_; + +fn foo() -> [T; N] { + loop {} +} + +fn main() { + // Requires inferring `T`/`N` from `12_u8` and `2` respectively. + let a = foo::<_, _, { [12_u8; 2] }>(); + //~^ ERROR: anonymous constants with inferred types are not yet supported + + // Requires inferring `T`/`N`/`12_?i`/`_` from `[u8; 2]` + let b: [u8; 2] = foo::<_, _, { [12; _] }>(); + //~^ ERROR: anonymous constants with inferred types are not yet supported +} diff --git a/tests/ui/const-generics/generic_const_parameter_types/bad_inference.stderr b/tests/ui/const-generics/generic_const_parameter_types/bad_inference.stderr new file mode 100644 index 000000000000..1ac67fe622b5 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/bad_inference.stderr @@ -0,0 +1,14 @@ +error: anonymous constants with inferred types are not yet supported + --> $DIR/bad_inference.rs:17:25 + | +LL | let a = foo::<_, _, { [12_u8; 2] }>(); + | ^^^^^^^^^^^^^^ + +error: anonymous constants with inferred types are not yet supported + --> $DIR/bad_inference.rs:21:34 + | +LL | let b: [u8; 2] = foo::<_, _, { [12; _] }>(); + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/generic_const_parameter_types/evaluate_const_parameter_in_mir.rs b/tests/ui/const-generics/generic_const_parameter_types/evaluate_const_parameter_in_mir.rs new file mode 100644 index 000000000000..910deb6632d7 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/evaluate_const_parameter_in_mir.rs @@ -0,0 +1,19 @@ +//@ check-pass + +#![feature( + adt_const_params, + unsized_const_params, + generic_const_parameter_types, + generic_arg_infer +)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy_; + +fn foo() -> [T; N] { + M +} + +fn main() { + let a: [u8; 2] = foo::(); +} diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs new file mode 100644 index 000000000000..91c1c80e07c8 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs @@ -0,0 +1,11 @@ +#![feature(adt_const_params, generic_const_parameter_types)] +#![expect(incomplete_features)] + +use std::marker::PhantomData; + +struct UsesConst; +//~^ ERROR: the type of const parameters must not depend on other generic parameters +struct UsesType(PhantomData); +//~^ ERROR: the type of const parameters must not depend on other generic parameters + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr new file mode 100644 index 000000000000..b0dbdff84136 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr @@ -0,0 +1,15 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/forward_declared_type.rs:6:32 + | +LL | struct UsesConst; + | ^ the type must not depend on the parameter `M` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/forward_declared_type.rs:8:27 + | +LL | struct UsesType(PhantomData); + | ^ the type must not depend on the parameter `T` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/generic_const_parameter_types/inferred_from_arg.rs b/tests/ui/const-generics/generic_const_parameter_types/inferred_from_arg.rs new file mode 100644 index 000000000000..d655fc174ee5 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/inferred_from_arg.rs @@ -0,0 +1,13 @@ +//@ check-pass + +#![feature(adt_const_params, generic_arg_infer, generic_const_parameter_types)] +#![expect(incomplete_features)] + +struct Bar; + +fn foo(_: Bar) {} + +fn main() { + foo(Bar::<2, { [1; 2] }>); + foo::<_, _>(Bar::<2, { [1; 2] }>); +} diff --git a/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.rs b/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.rs new file mode 100644 index 000000000000..6b81ca743aa7 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.rs @@ -0,0 +1,20 @@ +#![feature(generic_const_parameter_types, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + +fn foo<'a, const N: &'a u32>() {} + +fn bar() { + foo::<'static, { &1_u32 }>(); + //~^ ERROR: anonymous constants with lifetimes in their type are not yet supported + foo::<'_, { &1_u32 }>(); + //~^ ERROR: anonymous constants with lifetimes in their type are not yet supported +} + +fn borrowck<'a, const N: &'static u32, const M: &'a u32>() { + foo::<'a, M>(); + foo::<'static, M>(); + //~^ ERROR: lifetime may not live long enough + foo::<'static, N>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.stderr b/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.stderr new file mode 100644 index 000000000000..be5f27bcbc0b --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.stderr @@ -0,0 +1,23 @@ +error: anonymous constants with lifetimes in their type are not yet supported + --> $DIR/lifetime_dependent_const_param.rs:7:20 + | +LL | foo::<'static, { &1_u32 }>(); + | ^^^^^^^^^^ + +error: anonymous constants with lifetimes in their type are not yet supported + --> $DIR/lifetime_dependent_const_param.rs:9:15 + | +LL | foo::<'_, { &1_u32 }>(); + | ^^^^^^^^^^ + +error: lifetime may not live long enough + --> $DIR/lifetime_dependent_const_param.rs:15:5 + | +LL | fn borrowck<'a, const N: &'static u32, const M: &'a u32>() { + | -- lifetime `'a` defined here +LL | foo::<'a, M>(); +LL | foo::<'static, M>(); + | ^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.rs b/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.rs new file mode 100644 index 000000000000..df8a057b335a --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.rs @@ -0,0 +1,15 @@ +#![feature(adt_const_params, unsized_const_params, generic_const_parameter_types)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy_; + +fn foo() {} +fn bar() {} + +fn main() { + foo::<3, { [1; 2] }>(); + //~^ ERROR: mismatched type + + bar::(); + //~^ ERROR: mismatched type +} diff --git a/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.stderr b/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.stderr new file mode 100644 index 000000000000..2411d31b9801 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/mismatched_args_with_value.rs:10:16 + | +LL | foo::<3, { [1; 2] }>(); + | ^^^^^^ expected an array with a size of 3, found one with a size of 2 + +error[E0308]: mismatched types + --> $DIR/mismatched_args_with_value.rs:13:18 + | +LL | bar::(); + | ^^^^^ expected `u8`, found `u16` + | +help: change the type of the numeric literal from `u16` to `u8` + | +LL - bar::(); +LL + bar::(); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.rs b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.rs new file mode 100644 index 000000000000..1a5ab46cda19 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.rs @@ -0,0 +1,9 @@ +#![feature(adt_const_params, unsized_const_params, generic_const_parameter_types)] +#![expect(incomplete_features)] + +use std::marker::{ConstParamTy_, PhantomData}; + +struct UsesType(PhantomData); +//~^ ERROR: `[T; N]` can't be used as a const parameter type + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr new file mode 100644 index 000000000000..4ea323f4a5c8 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr @@ -0,0 +1,11 @@ +error[E0741]: `[T; N]` can't be used as a const parameter type + --> $DIR/no_const_param_ty_bound.rs:6:45 + | +LL | struct UsesType(PhantomData); + | ^^^^^^ + | + = note: `T` must implement `UnsizedConstParamTy`, but it does not + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/generic_const_parameter_types/unrelated_inferred_arg.rs b/tests/ui/const-generics/generic_const_parameter_types/unrelated_inferred_arg.rs new file mode 100644 index 000000000000..b389e12884ea --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/unrelated_inferred_arg.rs @@ -0,0 +1,21 @@ +//@ check-pass + +#![feature( + adt_const_params, + unsized_const_params, + generic_const_parameter_types, + generic_arg_infer +)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy_; + +fn foo(_: U) -> [T; N] { + loop {} +} + +fn main() { + // Check that `_` doesnt cause a "Type of const argument is uninferred" error + // as it is not actually used by the type of `M`. + let a = foo::<_, u8, 2, { [12; _] }>(true); +} diff --git a/tests/ui/const-generics/issues/issue-56445-1.full.stderr b/tests/ui/const-generics/issues/issue-56445-1.full.stderr index 86eb57355bd6..392a125de67a 100644 --- a/tests/ui/const-generics/issues/issue-56445-1.full.stderr +++ b/tests/ui/const-generics/issues/issue-56445-1.full.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | ^^ the type must not depend on the parameter `'a` - | - = note: lifetime parameters may not be used in the type of const parameters error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-56445-1.min.stderr b/tests/ui/const-generics/issues/issue-56445-1.min.stderr index 86eb57355bd6..392a125de67a 100644 --- a/tests/ui/const-generics/issues/issue-56445-1.min.stderr +++ b/tests/ui/const-generics/issues/issue-56445-1.min.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | ^^ the type must not depend on the parameter `'a` - | - = note: lifetime parameters may not be used in the type of const parameters error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-62878.full.stderr b/tests/ui/const-generics/issues/issue-62878.full.stderr index 615bfeb65a51..5e6b3ad9f4c4 100644 --- a/tests/ui/const-generics/issues/issue-62878.full.stderr +++ b/tests/ui/const-generics/issues/issue-62878.full.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn foo() {} | ^ the type must not depend on the parameter `N` - | - = note: const parameters may not be used in the type of const parameters error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index 1bb111b188df..d3d4fa438710 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn foo() {} | ^ the type must not depend on the parameter `N` - | - = note: const parameters may not be used in the type of const parameters error: `[u8; N]` is forbidden as the type of a const generic parameter --> $DIR/issue-62878.rs:5:33 diff --git a/tests/ui/const-generics/issues/issue-71169.full.stderr b/tests/ui/const-generics/issues/issue-71169.full.stderr index 9553be6fc07c..f600ecdab74a 100644 --- a/tests/ui/const-generics/issues/issue-71169.full.stderr +++ b/tests/ui/const-generics/issues/issue-71169.full.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn foo() {} | ^^^ the type must not depend on the parameter `LEN` - | - = note: const parameters may not be used in the type of const parameters error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-71169.min.stderr b/tests/ui/const-generics/issues/issue-71169.min.stderr index 2ecbc3379516..c04a710eee9c 100644 --- a/tests/ui/const-generics/issues/issue-71169.min.stderr +++ b/tests/ui/const-generics/issues/issue-71169.min.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn foo() {} | ^^^ the type must not depend on the parameter `LEN` - | - = note: const parameters may not be used in the type of const parameters error: `[u8; LEN]` is forbidden as the type of a const generic parameter --> $DIR/issue-71169.rs:5:38 diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr index b6460e0017fa..01bbe55415d4 100644 --- a/tests/ui/const-generics/issues/issue-71381.full.stderr +++ b/tests/ui/const-generics/issues/issue-71381.full.stderr @@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub fn call_me(&self) { | ^^^^ the type must not depend on the parameter `Args` - | - = note: type parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` - | - = note: type parameters may not be used in the type of const parameters error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr index 38d2cbe63683..2b0a671bc3fa 100644 --- a/tests/ui/const-generics/issues/issue-71381.min.stderr +++ b/tests/ui/const-generics/issues/issue-71381.min.stderr @@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub fn call_me(&self) { | ^^^^ the type must not depend on the parameter `Args` - | - = note: type parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` - | - = note: type parameters may not be used in the type of const parameters error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71381.rs:14:61 diff --git a/tests/ui/const-generics/issues/issue-71611.full.stderr b/tests/ui/const-generics/issues/issue-71611.full.stderr index 6f6a9fc21a69..e115630b64e3 100644 --- a/tests/ui/const-generics/issues/issue-71611.full.stderr +++ b/tests/ui/const-generics/issues/issue-71611.full.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn func(outer: A) { | ^ the type must not depend on the parameter `A` - | - = note: type parameters may not be used in the type of const parameters error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-71611.min.stderr b/tests/ui/const-generics/issues/issue-71611.min.stderr index 7252bfd1d6a7..b2e2e5cb445c 100644 --- a/tests/ui/const-generics/issues/issue-71611.min.stderr +++ b/tests/ui/const-generics/issues/issue-71611.min.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn func(outer: A) { | ^ the type must not depend on the parameter `A` - | - = note: type parameters may not be used in the type of const parameters error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71611.rs:5:21 diff --git a/tests/ui/const-generics/issues/issue-88997.stderr b/tests/ui/const-generics/issues/issue-88997.stderr index b49d52dd0bab..505ba0da2321 100644 --- a/tests/ui/const-generics/issues/issue-88997.stderr +++ b/tests/ui/const-generics/issues/issue-88997.stderr @@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | struct Range(T) | ^ the type must not depend on the parameter `T` - | - = note: type parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/issue-88997.rs:8:54 | LL | struct Range(T) | ^ the type must not depend on the parameter `T` - | - = note: type parameters may not be used in the type of const parameters error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-90364.stderr b/tests/ui/const-generics/issues/issue-90364.stderr index 6c00a654cde7..384ce5da3e20 100644 --- a/tests/ui/const-generics/issues/issue-90364.stderr +++ b/tests/ui/const-generics/issues/issue-90364.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Foo(T) | ^ the type must not depend on the parameter `T` - | - = note: type parameters may not be used in the type of const parameters error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0771.stderr b/tests/ui/error-codes/E0771.stderr index 5e829e6f6d2d..dfeaa347941c 100644 --- a/tests/ui/error-codes/E0771.stderr +++ b/tests/ui/error-codes/E0771.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn function_with_str<'a, const STRING: &'a str>() {} | ^^ the type must not depend on the parameter `'a` - | - = note: lifetime parameters may not be used in the type of const parameters warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/E0771.rs:1:30 diff --git a/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr new file mode 100644 index 000000000000..1377f845d164 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr @@ -0,0 +1,21 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/feature-gate-generic-const-parameter-types.rs:7:50 + | +LL | struct MyADT; + | ^^^ the type must not depend on the parameter `LEN` + +error: `[u8; LEN]` is forbidden as the type of a const generic parameter + --> $DIR/feature-gate-generic-const-parameter-types.rs:7:45 + | +LL | struct MyADT; + | ^^^^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` +help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + | +LL + #![feature(adt_const_params)] + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.rs b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.rs new file mode 100644 index 000000000000..cc374ea3eb2e --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.rs @@ -0,0 +1,11 @@ +//@ [feature] check-pass +//@ revisions: normal feature + +#![cfg_attr(feature, feature(adt_const_params, generic_const_parameter_types))] +#![cfg_attr(feature, expect(incomplete_features))] + +struct MyADT; +//[normal]~^ ERROR: the type of const parameters must not depend on other generic parameters +//[normal]~| ERROR: `[u8; LEN]` is forbidden as the type of a const generic parameter + +fn main() {} diff --git a/tests/ui/generic-const-items/wfcheck_err_leak_issue_118179.stderr b/tests/ui/generic-const-items/wfcheck_err_leak_issue_118179.stderr index 654004571dbb..2b28e29421c9 100644 --- a/tests/ui/generic-const-items/wfcheck_err_leak_issue_118179.stderr +++ b/tests/ui/generic-const-items/wfcheck_err_leak_issue_118179.stderr @@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | struct G>(T); | ^ the type must not depend on the parameter `T` - | - = note: type parameters may not be used in the type of const parameters error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr index b7effdc8d61d..7373ca8cf843 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.stderr +++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr @@ -9,8 +9,6 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | struct Bar Foo<'a>)>; | ^^ the type must not depend on the parameter `'a` - | - = note: lifetime parameters may not be used in the type of const parameters error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/unusual-rib-combinations.rs:11:15 diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs index 997bee1e6008..89e4b77b6cd4 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs @@ -3,6 +3,7 @@ trait Foo> { //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| ERROR cycle detected when computing type of `Foo::N` + //~| ERROR cycle detected when computing type of `Foo::N` fn func() {} } diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr index 733b729faf07..a381f2acdce4 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr @@ -13,7 +13,7 @@ LL | trait Foo> { | +++ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:9:20 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:20 | LL | trait Bar> {} | ^^^^^^ @@ -32,7 +32,7 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^ | note: ...which requires computing type of `Bar::M`... - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:9:11 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:11 | LL | trait Bar> {} | ^^^^^^^^^^^^^^^ @@ -44,6 +44,26 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 1 previous error; 2 warnings emitted +error[E0391]: cycle detected when computing type of `Foo::N` + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11 + | +LL | trait Foo> { + | ^^^^^^^^^^^^^^^ + | +note: ...which requires computing type of `Bar::M`... + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:11 + | +LL | trait Bar> {} + | ^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `Foo::N`, completing the cycle +note: cycle used when computing explicit predicates of trait `Foo` + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:1 + | +LL | trait Foo> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0391`. From adb5ecabdb09ff6f329bbf9b7721036db983f546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 28 Feb 2025 20:05:43 +0000 Subject: [PATCH 482/991] Tweak invalid RTN errors Make suggestions verbose. When encountering `method(type)` bound, suggest `method(..)` instead of `method()`. ``` error: argument types not allowed with return type notation --> $DIR/bad-inputs-and-output.rs:9:23 | LL | fn foo>() {} | ^^^^^ | help: remove the input types | LL - fn foo>() {} LL + fn foo>() {} | ``` When encountering both return type and arg list that isn't `..`, suggest replacing both. ``` error: return type not allowed with return type notation --> $DIR/bad-inputs-and-output.rs:12:25 | LL | fn bar (): Send>>() {} | ^^^^^^ | help: use the right argument notation and remove the return type | LL - fn bar (): Send>>() {} LL + fn bar>() {} | ``` When encountering a return type, suggest removing it including the leading whitespace. ``` error: return type not allowed with return type notation --> $DIR/bad-inputs-and-output.rs:24:45 | LL | fn bay_path() where T::method(..) -> (): Send {} | ^^^^^ | help: remove the return type | LL - fn bay_path() where T::method(..) -> (): Send {} LL + fn bay_path() where T::method(..): Send {} | ``` --- compiler/rustc_ast_lowering/messages.ftl | 4 +- compiler/rustc_ast_lowering/src/errors.rs | 21 +++++- compiler/rustc_ast_lowering/src/lib.rs | 32 +++++---- compiler/rustc_ast_lowering/src/path.rs | 34 ++++++---- compiler/rustc_parse/src/errors.rs | 3 +- compiler/rustc_parse/src/parser/path.rs | 5 +- .../bad-inputs-and-output.rs | 3 + .../bad-inputs-and-output.stderr | 68 ++++++++++++++++--- .../let-binding-init-expr-as-ty.stderr | 7 +- 9 files changed, 133 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 1b91c33742d8..5f1726f7f0aa 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -37,11 +37,11 @@ ast_lowering_bad_return_type_notation_inputs = .suggestion = remove the input types ast_lowering_bad_return_type_notation_needs_dots = return type notation arguments must be elided with `..` - .suggestion = add `..` + .suggestion = use the correct syntax by adding `..` to the arguments ast_lowering_bad_return_type_notation_output = return type not allowed with return type notation - .suggestion = remove the return type +ast_lowering_bad_return_type_notation_output_suggestion = use the right argument notation and remove the return type ast_lowering_bad_return_type_notation_position = return type notation not allowed in this position yet diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index f31e2db051d8..d402c5abc194 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -372,24 +372,39 @@ pub(crate) struct InclusiveRangeWithNoEnd { pub span: Span, } +#[derive(Subdiagnostic)] +#[multipart_suggestion( + ast_lowering_bad_return_type_notation_output_suggestion, + applicability = "machine-applicable", + style = "verbose" +)] +/// Given `T: Tr Ret>` or `T: Tr Ret>`, suggest `T: Tr`. +pub(crate) struct RTNSuggestion { + #[suggestion_part(code = "")] + pub output: Span, + #[suggestion_part(code = "(..)")] + pub input: Span, +} + #[derive(Diagnostic)] pub(crate) enum BadReturnTypeNotation { #[diag(ast_lowering_bad_return_type_notation_inputs)] Inputs { #[primary_span] - #[suggestion(code = "()", applicability = "maybe-incorrect")] + #[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")] span: Span, }, #[diag(ast_lowering_bad_return_type_notation_output)] Output { #[primary_span] - #[suggestion(code = "", applicability = "maybe-incorrect")] span: Span, + #[subdiagnostic] + suggestion: RTNSuggestion, }, #[diag(ast_lowering_bad_return_type_notation_needs_dots)] NeedsDots { #[primary_span] - #[suggestion(code = "(..)", applicability = "maybe-incorrect")] + #[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")] span: Span, }, #[diag(ast_lowering_bad_return_type_notation_position)] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1c69937eed07..13edcc10c9e2 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -926,19 +926,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if let Some(first_char) = constraint.ident.as_str().chars().next() && first_char.is_ascii_lowercase() { - let mut err = if !data.inputs.is_empty() { - self.dcx().create_err(errors::BadReturnTypeNotation::Inputs { - span: data.inputs_span, - }) - } else if let FnRetTy::Ty(ty) = &data.output { - self.dcx().create_err(errors::BadReturnTypeNotation::Output { - span: data.inputs_span.shrink_to_hi().to(ty.span), - }) - } else { - self.dcx().create_err(errors::BadReturnTypeNotation::NeedsDots { - span: data.inputs_span, - }) + tracing::info!(?data, ?data.inputs); + let err = match (&data.inputs[..], &data.output) { + ([_, ..], FnRetTy::Default(_)) => { + errors::BadReturnTypeNotation::Inputs { span: data.inputs_span } + } + ([], FnRetTy::Default(_)) => { + errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span } + } + // The case `T: Trait Ret>` is handled in the parser. + (_, FnRetTy::Ty(ty)) => { + let span = data.inputs_span.shrink_to_hi().to(ty.span); + errors::BadReturnTypeNotation::Output { + span, + suggestion: errors::RTNSuggestion { + output: span, + input: data.inputs_span, + }, + } + } }; + let mut err = self.dcx().create_err(err); if !self.tcx.features().return_type_notation() && self.tcx.sess.is_nightly_build() { diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 55d064773132..6b6244b05aa9 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -13,7 +13,7 @@ use tracing::{debug, instrument}; use super::errors::{ AsyncBoundNotOnTrait, AsyncBoundOnlyForFnTraits, BadReturnTypeNotation, - GenericTypeWithParentheses, UseAngleBrackets, + GenericTypeWithParentheses, RTNSuggestion, UseAngleBrackets, }; use super::{ AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition, @@ -268,19 +268,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } GenericArgs::Parenthesized(data) => match generic_args_mode { GenericArgsMode::ReturnTypeNotation => { - let mut err = if !data.inputs.is_empty() { - self.dcx().create_err(BadReturnTypeNotation::Inputs { - span: data.inputs_span, - }) - } else if let FnRetTy::Ty(ty) = &data.output { - self.dcx().create_err(BadReturnTypeNotation::Output { - span: data.inputs_span.shrink_to_hi().to(ty.span), - }) - } else { - self.dcx().create_err(BadReturnTypeNotation::NeedsDots { - span: data.inputs_span, - }) + tracing::info!(?data, ?data.inputs); + let err = match (&data.inputs[..], &data.output) { + ([_, ..], FnRetTy::Default(_)) => { + BadReturnTypeNotation::Inputs { span: data.inputs_span } + } + ([], FnRetTy::Default(_)) => { + BadReturnTypeNotation::NeedsDots { span: data.inputs_span } + } + // The case `T: Trait Ret>` is handled in the parser. + (_, FnRetTy::Ty(ty)) => { + let span = data.inputs_span.shrink_to_hi().to(ty.span); + BadReturnTypeNotation::Output { + span, + suggestion: RTNSuggestion { + output: span, + input: data.inputs_span, + }, + } + } }; + let mut err = self.dcx().create_err(err); if !self.tcx.features().return_type_notation() && self.tcx.sess.is_nightly_build() { diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 173c68b3a722..5bf1a11954ed 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2922,8 +2922,9 @@ pub(crate) struct AddBoxNew { #[diag(parse_bad_return_type_notation_output)] pub(crate) struct BadReturnTypeNotationOutput { #[primary_span] - #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")] pub span: Span, + #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")] + pub suggestion: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index c24305ea9a86..7698df3b5546 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -378,11 +378,14 @@ impl<'a> Parser<'a> { self.psess.gated_spans.gate(sym::return_type_notation, span); + let prev_lo = self.prev_token.span.shrink_to_hi(); if self.eat_noexpect(&token::RArrow) { let lo = self.prev_token.span; let ty = self.parse_ty()?; + let span = lo.to(ty.span); + let suggestion = prev_lo.to(ty.span); self.dcx() - .emit_err(errors::BadReturnTypeNotationOutput { span: lo.to(ty.span) }); + .emit_err(errors::BadReturnTypeNotationOutput { span, suggestion }); } P(ast::GenericArgs::ParenthesizedElided(span)) diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs index f00aaec1a8c2..90fd2c2b4f32 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -21,6 +21,9 @@ fn foo_path() where T::method(i32): Send {} fn bar_path() where T::method() -> (): Send {} //~^ ERROR return type not allowed with return type notation +fn bay_path() where T::method(..) -> (): Send {} +//~^ ERROR return type not allowed with return type notation + fn baz_path() where T::method(): Send {} //~^ ERROR return type notation arguments must be elided with `..` diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr index c6b9f3eff90e..bd02b7d6534a 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -1,17 +1,29 @@ +error: return type not allowed with return type notation + --> $DIR/bad-inputs-and-output.rs:24:45 + | +LL | fn bay_path() where T::method(..) -> (): Send {} + | ^^^^^ + | +help: remove the return type + | +LL - fn bay_path() where T::method(..) -> (): Send {} +LL + fn bay_path() where T::method(..): Send {} + | + error[E0575]: expected associated type, found associated function `Trait::method` - --> $DIR/bad-inputs-and-output.rs:27:36 + --> $DIR/bad-inputs-and-output.rs:30:36 | LL | fn foo_qualified() where ::method(i32): Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type error[E0575]: expected associated type, found associated function `Trait::method` - --> $DIR/bad-inputs-and-output.rs:30:36 + --> $DIR/bad-inputs-and-output.rs:33:36 | LL | fn bar_qualified() where ::method() -> (): Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type error[E0575]: expected associated type, found associated function `Trait::method` - --> $DIR/bad-inputs-and-output.rs:33:36 + --> $DIR/bad-inputs-and-output.rs:36:36 | LL | fn baz_qualified() where ::method(): Send {} | ^^^^^^^^^^^^^^^^^^^^^^ not a associated type @@ -20,38 +32,72 @@ error: argument types not allowed with return type notation --> $DIR/bad-inputs-and-output.rs:9:23 | LL | fn foo>() {} - | ^^^^^ help: remove the input types: `()` + | ^^^^^ + | +help: remove the input types + | +LL - fn foo>() {} +LL + fn foo>() {} + | error: return type not allowed with return type notation --> $DIR/bad-inputs-and-output.rs:12:25 | LL | fn bar (): Send>>() {} - | ^^^^^^ help: remove the return type + | ^^^^^^ + | +help: use the right argument notation and remove the return type + | +LL - fn bar (): Send>>() {} +LL + fn bar>() {} + | error: return type notation arguments must be elided with `..` --> $DIR/bad-inputs-and-output.rs:15:23 | LL | fn baz>() {} - | ^^ help: add `..`: `(..)` + | ^^ + | +help: use the correct syntax by adding `..` to the arguments + | +LL | fn baz>() {} + | ++ error: argument types not allowed with return type notation --> $DIR/bad-inputs-and-output.rs:18:40 | LL | fn foo_path() where T::method(i32): Send {} - | ^^^^^ help: remove the input types: `()` + | ^^^^^ + | +help: remove the input types + | +LL - fn foo_path() where T::method(i32): Send {} +LL + fn foo_path() where T::method(..): Send {} + | error: return type not allowed with return type notation --> $DIR/bad-inputs-and-output.rs:21:42 | LL | fn bar_path() where T::method() -> (): Send {} - | ^^^^^^ help: remove the return type + | ^^^^^^ + | +help: use the right argument notation and remove the return type + | +LL - fn bar_path() where T::method() -> (): Send {} +LL + fn bar_path() where T::method(..): Send {} + | error: return type notation arguments must be elided with `..` - --> $DIR/bad-inputs-and-output.rs:24:40 + --> $DIR/bad-inputs-and-output.rs:27:40 | LL | fn baz_path() where T::method(): Send {} - | ^^ help: add `..`: `(..)` + | ^^ + | +help: use the correct syntax by adding `..` to the arguments + | +LL | fn baz_path() where T::method(..): Send {} + | ++ -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0575`. diff --git a/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr b/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr index 83a5441e3c0c..19a0e4b17d02 100644 --- a/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr +++ b/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr @@ -10,11 +10,16 @@ error: argument types not allowed with return type notation --> $DIR/let-binding-init-expr-as-ty.rs:2:26 | LL | let foo: i32::from_be(num); - | ^^^^^ help: remove the input types: `()` + | ^^^^^ | = note: see issue #109417 for more information = help: add `#![feature(return_type_notation)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +help: remove the input types + | +LL - let foo: i32::from_be(num); +LL + let foo: i32::from_be(..); + | error: return type notation not allowed in this position yet --> $DIR/let-binding-init-expr-as-ty.rs:2:14 From 4c1f51bf6ecc68fb6eb4b90ea6b0d0b027146aee Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Fri, 28 Feb 2025 14:24:16 -0300 Subject: [PATCH 483/991] Fix link failure on AVR (incompatible ISA error) Fixes #137739. A reproducer of the issue is present there. I believe the root cause was introducing the avr-none target (which has no CPU by default) and trying to get the ISA revision from there. This commit uses the `target-cpu` option instead, which is already required to be present for the target. Co-authored-by: tones111 --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 236507ac0cd2..3aacbcde1a78 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -373,7 +373,11 @@ pub(crate) fn create_object_file(sess: &Session) -> Option { // Resolve the ISA revision and set // the appropriate EF_AVR_ARCH flag. - ef_avr_arch(&sess.target.options.cpu) + if let Some(ref cpu) = sess.opts.cg.target_cpu { + ef_avr_arch(cpu) + } else { + bug!("AVR CPU not explicitly specified") + } } Architecture::Csky => { let e_flags = match sess.target.options.abi.as_ref() { From 107d7ef767b1d4585515cc17db103a03d7a9364e Mon Sep 17 00:00:00 2001 From: Karol Zwolak Date: Fri, 28 Feb 2025 22:37:15 +0100 Subject: [PATCH 484/991] test(codegen): add looping_over_ne_bytes test for #133528 --- .../issues/looping-over-ne-bytes-133528.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/codegen/issues/looping-over-ne-bytes-133528.rs diff --git a/tests/codegen/issues/looping-over-ne-bytes-133528.rs b/tests/codegen/issues/looping-over-ne-bytes-133528.rs new file mode 100644 index 000000000000..35acf765d690 --- /dev/null +++ b/tests/codegen/issues/looping-over-ne-bytes-133528.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Copt-level=3 +//@ min-llvm-version: 20 +#![crate_type = "lib"] + +/// Ensure the function is properly optimized +/// In the issue #133528, the function was not getting optimized +/// whereas, a version with `bytes` wrapped into a `black_box` was optimized +/// It was probably a LLVM bug that was fixed in LLVM 20 + +// CHECK-LABEL: @looping_over_ne_bytes +// CHECK: icmp eq i64 %input, -1 +// CHECK-NEXT: ret i1 +#[no_mangle] +fn looping_over_ne_bytes(input: u64) -> bool { + let bytes = input.to_ne_bytes(); + bytes.iter().all(|x| *x == !0) +} From a8d78fec52aec04254ec602851c4fd7c8469c592 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Thu, 27 Feb 2025 23:38:19 -0800 Subject: [PATCH 485/991] Specialize OsString::push for strings When concatenating two WTF-8 strings, surrogate pairs at the boundaries need to be joined. However, since UTF-8 strings cannot contain surrogate halves, this check can be skipped when one string is UTF-8. Specialize `OsString::push` to use a more efficient concatenation in this case. Unfortunately, a specialization for `T: AsRef` conflicts with `T: AsRef`, so stamp out string types with a macro. --- library/std/src/ffi/os_str.rs | 25 ++++++++++++++++++++++++- library/std/src/sys/os_str/bytes.rs | 5 +++++ library/std/src/sys/os_str/wtf8.rs | 5 +++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index f4a02802336d..c0e659db307a 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -257,7 +257,30 @@ impl OsString { #[inline] #[rustc_confusables("append", "put")] pub fn push>(&mut self, s: T) { - self.inner.push_slice(&s.as_ref().inner) + trait SpecPushTo { + fn spec_push_to(&self, buf: &mut OsString); + } + + impl> SpecPushTo for T { + #[inline] + default fn spec_push_to(&self, buf: &mut OsString) { + buf.inner.push_slice(&self.as_ref().inner); + } + } + + // Use a more efficient implementation when the string is UTF-8. + macro spec_str($T:ty) { + impl SpecPushTo for $T { + #[inline] + fn spec_push_to(&self, buf: &mut OsString) { + buf.inner.push_str(self); + } + } + } + spec_str!(str); + spec_str!(String); + + s.spec_push_to(self) } /// Creates a new `OsString` with at least the given capacity. diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 1d337694944b..dfff2d3e5d31 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -139,6 +139,11 @@ impl Buf { self.inner.extend_from_slice(&s.inner) } + #[inline] + pub fn push_str(&mut self, s: &str) { + self.inner.extend_from_slice(s.as_bytes()); + } + #[inline] pub fn reserve(&mut self, additional: usize) { self.inner.reserve(additional) diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index 8acec6f949fc..a32f5d40f6a9 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -116,6 +116,11 @@ impl Buf { self.inner.push_wtf8(&s.inner) } + #[inline] + pub fn push_str(&mut self, s: &str) { + self.inner.push_str(s); + } + #[inline] pub fn reserve(&mut self, additional: usize) { self.inner.reserve(additional) From 83407b828bcf5c883b2ab50b958edbcba0738f6a Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Fri, 28 Feb 2025 13:31:15 -0800 Subject: [PATCH 486/991] Specialize constructing OsString from strings The WTF-8 version of `OsString` tracks whether it is known to be valid UTF-8 with its `is_known_utf8` field. Specialize `From>` so this can be set for UTF-8 string types. --- library/std/src/ffi/os_str.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index c0e659db307a..aa25ff5293c7 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -610,7 +610,30 @@ impl> From<&T> for OsString { /// Copies any value implementing [AsRef]<[OsStr]> /// into a newly allocated [`OsString`]. fn from(s: &T) -> OsString { - s.as_ref().to_os_string() + trait SpecToOsString { + fn spec_to_os_string(&self) -> OsString; + } + + impl> SpecToOsString for T { + #[inline] + default fn spec_to_os_string(&self) -> OsString { + self.as_ref().to_os_string() + } + } + + // Preserve the known-UTF-8 property for strings. + macro spec_str($T:ty) { + impl SpecToOsString for $T { + #[inline] + fn spec_to_os_string(&self) -> OsString { + OsString::from(String::from(self)) + } + } + } + spec_str!(str); + spec_str!(String); + + s.spec_to_os_string() } } From a8bff87cfb15396b4ddf80743652b7e234bd0100 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Fri, 28 Feb 2025 14:04:54 -0800 Subject: [PATCH 487/991] Stabilize [T]::split_off... methods This was previously known as the slice_take feature. --- library/core/src/slice/mod.rs | 34 +++++++--------------------------- library/coretests/tests/lib.rs | 1 - 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 7a2764206e8d..f991cc4ae2db 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -78,7 +78,7 @@ pub use raw::{from_raw_parts, from_raw_parts_mut}; /// Calculates the direction and split point of a one-sided range. /// -/// This is a helper function for `take` and `take_mut` that returns +/// This is a helper function for `split_off` and `split_off_mut` that returns /// the direction of the split (front or back) as well as the index at /// which to split. Returns `None` if the split index would overflow. #[inline] @@ -4313,8 +4313,6 @@ impl [T] { /// Splitting off the first three elements of a slice: /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &[_] = &['a', 'b', 'c', 'd']; /// let mut first_three = slice.split_off(..3).unwrap(); /// @@ -4325,8 +4323,6 @@ impl [T] { /// Splitting off the last two elements of a slice: /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &[_] = &['a', 'b', 'c', 'd']; /// let mut tail = slice.split_off(2..).unwrap(); /// @@ -4337,8 +4333,6 @@ impl [T] { /// Getting `None` when `range` is out of bounds: /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &[_] = &['a', 'b', 'c', 'd']; /// /// assert_eq!(None, slice.split_off(5..)); @@ -4349,7 +4343,7 @@ impl [T] { /// ``` #[inline] #[must_use = "method does not modify the slice if the range is out of bounds"] - #[unstable(feature = "slice_take", issue = "62280")] + #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] pub fn split_off<'a, R: OneSidedRange>( self: &mut &'a Self, range: R, @@ -4385,8 +4379,6 @@ impl [T] { /// Splitting off the first three elements of a slice: /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd']; /// let mut first_three = slice.split_off_mut(..3).unwrap(); /// @@ -4397,8 +4389,6 @@ impl [T] { /// Taking the last two elements of a slice: /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd']; /// let mut tail = slice.split_off_mut(2..).unwrap(); /// @@ -4409,8 +4399,6 @@ impl [T] { /// Getting `None` when `range` is out of bounds: /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd']; /// /// assert_eq!(None, slice.split_off_mut(5..)); @@ -4421,7 +4409,7 @@ impl [T] { /// ``` #[inline] #[must_use = "method does not modify the slice if the range is out of bounds"] - #[unstable(feature = "slice_take", issue = "62280")] + #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] pub fn split_off_mut<'a, R: OneSidedRange>( self: &mut &'a mut Self, range: R, @@ -4451,8 +4439,6 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &[_] = &['a', 'b', 'c']; /// let first = slice.split_off_first().unwrap(); /// @@ -4460,7 +4446,7 @@ impl [T] { /// assert_eq!(first, &'a'); /// ``` #[inline] - #[unstable(feature = "slice_take", issue = "62280")] + #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] pub fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> { let (first, rem) = self.split_first()?; *self = rem; @@ -4475,8 +4461,6 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &mut [_] = &mut ['a', 'b', 'c']; /// let first = slice.split_off_first_mut().unwrap(); /// *first = 'd'; @@ -4485,7 +4469,7 @@ impl [T] { /// assert_eq!(first, &'d'); /// ``` #[inline] - #[unstable(feature = "slice_take", issue = "62280")] + #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] pub fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> { let (first, rem) = mem::take(self).split_first_mut()?; *self = rem; @@ -4500,8 +4484,6 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &[_] = &['a', 'b', 'c']; /// let last = slice.split_off_last().unwrap(); /// @@ -4509,7 +4491,7 @@ impl [T] { /// assert_eq!(last, &'c'); /// ``` #[inline] - #[unstable(feature = "slice_take", issue = "62280")] + #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] pub fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> { let (last, rem) = self.split_last()?; *self = rem; @@ -4524,8 +4506,6 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_take)] - /// /// let mut slice: &mut [_] = &mut ['a', 'b', 'c']; /// let last = slice.split_off_last_mut().unwrap(); /// *last = 'd'; @@ -4534,7 +4514,7 @@ impl [T] { /// assert_eq!(last, &'d'); /// ``` #[inline] - #[unstable(feature = "slice_take", issue = "62280")] + #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] pub fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> { let (last, rem) = mem::take(self).split_last_mut()?; *self = rem; diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 4f21ae5013b6..b3c8e94806d4 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -73,7 +73,6 @@ #![feature(slice_internals)] #![feature(slice_partition_dedup)] #![feature(slice_split_once)] -#![feature(slice_take)] #![feature(split_array)] #![feature(split_as_slice)] #![feature(std_internals)] From f5851e704531d3941e84afbd998a506ffe37a3d5 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 20 Feb 2025 21:23:38 +0100 Subject: [PATCH 488/991] Clippy: skip check_host_compiler check in rustc testsuite This test only makes sense to run in the Clippy repo In the Rust repo the name of the host_compiler is dev, not nightly --- src/tools/clippy/tests/versioncheck.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/clippy/tests/versioncheck.rs b/src/tools/clippy/tests/versioncheck.rs index ea540d48a2b9..f6fc2354ca08 100644 --- a/src/tools/clippy/tests/versioncheck.rs +++ b/src/tools/clippy/tests/versioncheck.rs @@ -93,6 +93,11 @@ fn check_that_clippy_has_the_same_major_version_as_rustc() { #[test] fn check_host_compiler() { + // do not run this test inside the upstream rustc repo: + if option_env!("RUSTC_TEST_SUITE").is_some() { + return; + } + let version = rustc_tools_util::get_version_info!(); assert_eq!(version.host_compiler, Some("nightly".to_string())); } From 1e4bce2ee1f815a1c4a7250730cd9e3b732061f2 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 21 Feb 2025 17:42:48 +0100 Subject: [PATCH 489/991] Fix link to ty::Ty in clippy_utils --- src/tools/clippy/clippy_utils/src/ty/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index 2611fb8a78d8..6fdf4c244f8d 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -37,7 +37,7 @@ use crate::{def_path_def_ids, match_def_path, path_res}; mod type_certainty; pub use type_certainty::expr_type_is_certain; -/// Lower a [`hir::Ty`] to a [`rustc_middle::Ty`]. +/// Lower a [`hir::Ty`] to a [`rustc_middle::ty::Ty`]. pub fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { cx.maybe_typeck_results() .and_then(|results| { From 7bfea666528281d627fc01b3858e3742fafa0d7d Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 28 Feb 2025 23:28:53 +0100 Subject: [PATCH 490/991] Update Cargo.lock --- Cargo.lock | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e93af7926a2d..3c88ab582128 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -358,7 +358,7 @@ dependencies = [ "cargo_metadata 0.18.1", "directories", "rustc-build-sysroot", - "rustc_tools_util", + "rustc_tools_util 0.4.0", "rustc_version", "serde", "serde_json", @@ -522,7 +522,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clippy" -version = "0.1.86" +version = "0.1.87" dependencies = [ "anstream", "cargo_metadata 0.18.1", @@ -539,7 +539,7 @@ dependencies = [ "quote", "regex", "rinja", - "rustc_tools_util", + "rustc_tools_util 0.4.2", "serde", "serde_json", "syn 2.0.96", @@ -553,7 +553,7 @@ dependencies = [ [[package]] name = "clippy_config" -version = "0.1.86" +version = "0.1.87" dependencies = [ "clippy_utils", "itertools", @@ -578,7 +578,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.1.86" +version = "0.1.87" dependencies = [ "arrayvec", "cargo_metadata 0.18.1", @@ -601,7 +601,7 @@ dependencies = [ [[package]] name = "clippy_utils" -version = "0.1.86" +version = "0.1.87" dependencies = [ "arrayvec", "itertools", @@ -4454,6 +4454,10 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3316159ab19e19d1065ecc49278e87f767a9dae9fae80348d2b4d4fa4ae02d4d" +[[package]] +name = "rustc_tools_util" +version = "0.4.2" + [[package]] name = "rustc_trait_selection" version = "0.0.0" From 45492662c7671e477492eba7c919bc99f7031132 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 24 Feb 2025 21:56:26 +0100 Subject: [PATCH 491/991] correct the docs on `simd_` comparison operators these all also accept integer vectors as arguments --- library/core/src/intrinsics/simd.rs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 3bde183fefb7..3aec66e9961e 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -26,28 +26,28 @@ pub unsafe fn simd_extract(_x: T, _idx: u32) -> U; /// Adds two simd vectors elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_add(_x: T, _y: T) -> T; /// Subtracts `rhs` from `lhs` elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_sub(_lhs: T, _rhs: T) -> T; /// Multiplies two simd vectors elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_mul(_x: T, _y: T) -> T; /// Divides `lhs` by `rhs` elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. /// /// # Safety /// For integers, `rhs` must not contain any zero elements. @@ -58,7 +58,7 @@ pub unsafe fn simd_div(_lhs: T, _rhs: T) -> T; /// Returns remainder of two vectors elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. /// /// # Safety /// For integers, `rhs` must not contain any zero elements. @@ -116,8 +116,7 @@ pub unsafe fn simd_xor(_x: T, _y: T) -> T; /// Numerically casts a vector, elementwise. /// -/// `T` and `U` must be vectors of integer or floating point primitive types, and must have the -/// same length. +/// `T` and `U` must be vectors of integers or floats, and must have the same length. /// /// When casting floats to integers, the result is truncated. Out-of-bounds result lead to UB. /// When casting integers to floats, the result is rounded. @@ -138,8 +137,7 @@ pub unsafe fn simd_cast(_x: T) -> U; /// Numerically casts a vector, elementwise. /// -/// `T` and `U` be a vectors of integer or floating point primitive types, and must have the -/// same length. +/// `T` and `U` be a vectors of integers or floats, and must have the same length. /// /// Like `simd_cast`, but saturates float-to-integer conversions (NaN becomes 0). /// This matches regular `as` and is always safe. @@ -187,7 +185,7 @@ pub unsafe fn simd_fmax(_x: T, _y: T) -> T; /// Tests elementwise equality of two vectors. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -198,7 +196,7 @@ pub unsafe fn simd_eq(_x: T, _y: T) -> U; /// Tests elementwise inequality equality of two vectors. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -209,7 +207,7 @@ pub unsafe fn simd_ne(_x: T, _y: T) -> U; /// Tests if `x` is less than `y`, elementwise. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -220,7 +218,7 @@ pub unsafe fn simd_lt(_x: T, _y: T) -> U; /// Tests if `x` is less than or equal to `y`, elementwise. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -231,7 +229,7 @@ pub unsafe fn simd_le(_x: T, _y: T) -> U; /// Tests if `x` is greater than `y`, elementwise. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -242,7 +240,7 @@ pub unsafe fn simd_gt(_x: T, _y: T) -> U; /// Tests if `x` is greater than or equal to `y`, elementwise. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// From 854e9f48033e2cfe8615ed3b24ceccb137addd46 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 28 Feb 2025 22:46:54 +0100 Subject: [PATCH 492/991] intrinsics::simd: document that masks must be signed integer vectors this is because they may be widened, and that only works when sign extension is used: zero extension would produce invalid results --- library/core/src/intrinsics/simd.rs | 54 ++++++++++++++--------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 3aec66e9961e..cceb6b0917af 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -71,7 +71,7 @@ pub unsafe fn simd_rem(_lhs: T, _rhs: T) -> T; /// /// Shifts `lhs` left by `rhs`, shifting in sign bits for signed types. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. /// /// # Safety /// @@ -82,7 +82,7 @@ pub unsafe fn simd_shl(_lhs: T, _rhs: T) -> T; /// Shifts vector right elementwise, with UB on overflow. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. /// /// Shifts `lhs` right by `rhs`, shifting in sign bits for signed types. /// @@ -95,21 +95,21 @@ pub unsafe fn simd_shr(_lhs: T, _rhs: T) -> T; /// "Ands" vectors elementwise. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_and(_x: T, _y: T) -> T; /// "Ors" vectors elementwise. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_or(_x: T, _y: T) -> T; /// "Exclusive ors" vectors elementwise. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_xor(_x: T, _y: T) -> T; @@ -151,7 +151,7 @@ pub unsafe fn simd_as(_x: T) -> U; /// Negates a vector elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// Rust panics for `-::Min` due to overflow, but it is not UB with this intrinsic. #[rustc_intrinsic] @@ -185,7 +185,7 @@ pub unsafe fn simd_fmax(_x: T, _y: T) -> T; /// Tests elementwise equality of two vectors. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -196,7 +196,7 @@ pub unsafe fn simd_eq(_x: T, _y: T) -> U; /// Tests elementwise inequality equality of two vectors. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -207,7 +207,7 @@ pub unsafe fn simd_ne(_x: T, _y: T) -> U; /// Tests if `x` is less than `y`, elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -218,7 +218,7 @@ pub unsafe fn simd_lt(_x: T, _y: T) -> U; /// Tests if `x` is less than or equal to `y`, elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -229,7 +229,7 @@ pub unsafe fn simd_le(_x: T, _y: T) -> U; /// Tests if `x` is greater than `y`, elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -240,7 +240,7 @@ pub unsafe fn simd_gt(_x: T, _y: T) -> U; /// Tests if `x` is greater than or equal to `y`, elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -271,7 +271,7 @@ pub unsafe fn simd_shuffle(_x: T, _y: T, _idx: U) -> V; /// /// `U` must be a vector of pointers to the element type of `T`, with the same length as `T`. /// -/// `V` must be a vector of integers with the same length as `T` (but any element size). +/// `V` must be a vector of signed integers with the same length as `T` (but any element size). /// /// For each pointer in `ptr`, if the corresponding value in `mask` is `!0`, read the pointer. /// Otherwise if the corresponding value in `mask` is `0`, return the corresponding value from @@ -292,7 +292,7 @@ pub unsafe fn simd_gather(_val: T, _ptr: U, _mask: V) -> T; /// /// `U` must be a vector of pointers to the element type of `T`, with the same length as `T`. /// -/// `V` must be a vector of integers with the same length as `T` (but any element size). +/// `V` must be a vector of signed integers with the same length as `T` (but any element size). /// /// For each pointer in `ptr`, if the corresponding value in `mask` is `!0`, write the /// corresponding value in `val` to the pointer. @@ -316,7 +316,7 @@ pub unsafe fn simd_scatter(_val: T, _ptr: U, _mask: V); /// /// `U` must be a pointer to the element type of `T` /// -/// `V` must be a vector of integers with the same length as `T` (but any element size). +/// `V` must be a vector of signed integers with the same length as `T` (but any element size). /// /// For each element, if the corresponding value in `mask` is `!0`, read the corresponding /// pointer offset from `ptr`. @@ -339,7 +339,7 @@ pub unsafe fn simd_masked_load(_mask: V, _ptr: U, _val: T) -> T; /// /// `U` must be a pointer to the element type of `T` /// -/// `V` must be a vector of integers with the same length as `T` (but any element size). +/// `V` must be a vector of signed integers with the same length as `T` (but any element size). /// /// For each element, if the corresponding value in `mask` is `!0`, write the corresponding /// value in `val` to the pointer offset from `ptr`. @@ -373,7 +373,7 @@ pub unsafe fn simd_saturating_sub(_lhs: T, _rhs: T) -> T; /// Adds elements within a vector from left to right. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. /// @@ -385,7 +385,7 @@ pub unsafe fn simd_reduce_add_ordered(_x: T, _y: U) -> U; /// Adds elements within a vector in arbitrary order. May also be re-associated with /// unordered additions on the inputs/outputs. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -394,7 +394,7 @@ pub unsafe fn simd_reduce_add_unordered(_x: T) -> U; /// Multiplies elements within a vector from left to right. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. /// @@ -406,7 +406,7 @@ pub unsafe fn simd_reduce_mul_ordered(_x: T, _y: U) -> U; /// Multiplies elements within a vector in arbitrary order. May also be re-associated with /// unordered additions on the inputs/outputs. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -435,7 +435,7 @@ pub unsafe fn simd_reduce_any(_x: T) -> bool; /// Returns the maximum element of a vector. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. /// @@ -446,7 +446,7 @@ pub unsafe fn simd_reduce_max(_x: T) -> U; /// Returns the minimum element of a vector. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. /// @@ -457,7 +457,7 @@ pub unsafe fn simd_reduce_min(_x: T) -> U; /// Logical "ands" all elements together. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -466,7 +466,7 @@ pub unsafe fn simd_reduce_and(_x: T) -> U; /// Logical "ors" all elements together. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -475,7 +475,7 @@ pub unsafe fn simd_reduce_or(_x: T) -> U; /// Logical "exclusive ors" all elements together. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -521,9 +521,9 @@ pub unsafe fn simd_bitmask(_x: T) -> U; /// Selects elements from a mask. /// -/// `M` must be an integer vector. +/// `T` must be a vector. /// -/// `T` must be a vector with the same number of elements as `M`. +/// `M` must be a signed integer vector with the same length as `T` (but any element size). /// /// For each element, if the corresponding value in `mask` is `!0`, select the element from /// `if_true`. If the corresponding value in `mask` is `0`, select the element from From b1196717fcba13d8ff73ec06c3d8c5bee3b74ec9 Mon Sep 17 00:00:00 2001 From: Will Woods Date: Fri, 28 Feb 2025 17:30:53 -0800 Subject: [PATCH 493/991] Tweak BufReader::peek() doctest to expose bug in Buffer::read_more() This patch makes BufReader::peek()'s doctest call read_more() to refill the buffer before the inner reader hits EOF. This exposes a bug in read_more() that causes an out-of-bounds slice access and segfault. --- library/std/src/io/buffered/bufreader.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 8b46738ab8ae..697fb5974a3d 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -118,16 +118,16 @@ impl BufReader { /// #![feature(bufreader_peek)] /// use std::io::{Read, BufReader}; /// - /// let mut bytes = &b"oh, hello"[..]; + /// let mut bytes = &b"oh, hello there"[..]; /// let mut rdr = BufReader::with_capacity(6, &mut bytes); /// assert_eq!(rdr.peek(2).unwrap(), b"oh"); /// let mut buf = [0; 4]; /// rdr.read(&mut buf[..]).unwrap(); /// assert_eq!(&buf, b"oh, "); - /// assert_eq!(rdr.peek(2).unwrap(), b"he"); + /// assert_eq!(rdr.peek(5).unwrap(), b"hello"); /// let mut s = String::new(); /// rdr.read_to_string(&mut s).unwrap(); - /// assert_eq!(&s, "hello"); + /// assert_eq!(&s, "hello there"); /// assert_eq!(rdr.peek(1).unwrap().len(), 0); /// ``` #[unstable(feature = "bufreader_peek", issue = "128405")] From 6d07144613ffb54e6856bd5543acfe5e12eb3447 Mon Sep 17 00:00:00 2001 From: Will Woods Date: Fri, 28 Feb 2025 17:36:19 -0800 Subject: [PATCH 494/991] Fix logic error in Buffer::read_more() Buffer::read_more() is supposed to refill the buffer without discarding its contents, which are in the range `pos .. filled`. It mistakenly borrows the range `pos ..`, fills that, and then increments `filled` by the amount read. This overwrites the buffer's existing contents and sets `filled` to a too-large value that either exposes uninitialized bytes or walks off the end of the buffer entirely. This patch makes it correctly fill only the unfilled portion of the buffer, which should maintain all the type invariants and fix the test failure introduced in commit b1196717fcb. --- library/std/src/io/buffered/bufreader/buffer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 5251cc302cb4..9fd2472ebdfd 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -109,8 +109,8 @@ impl Buffer { /// Read more bytes into the buffer without discarding any of its contents pub fn read_more(&mut self, mut reader: impl Read) -> io::Result { - let mut buf = BorrowedBuf::from(&mut self.buf[self.pos..]); - let old_init = self.initialized - self.pos; + let mut buf = BorrowedBuf::from(&mut self.buf[self.filled..]); + let old_init = self.initialized - self.filled; unsafe { buf.set_init(old_init); } From 38b364b29d67e8518614d19e18d822786f94d220 Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 28 Feb 2025 21:14:06 -0600 Subject: [PATCH 495/991] rustc_fluent_macro: use CARGO_CRATE_NAME instead of CARGO_PKG_NAME fixes #137815 --- compiler/rustc_fluent_macro/src/fluent.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index d4604c27e6da..b04fd1b48f7a 100644 --- a/compiler/rustc_fluent_macro/src/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -78,8 +78,8 @@ fn failed(crate_name: &Ident) -> proc_macro::TokenStream { /// See [rustc_fluent_macro::fluent_messages]. pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let crate_name = std::env::var("CARGO_PKG_NAME") - // If `CARGO_PKG_NAME` is missing, then we're probably running in a test, so use + let crate_name = std::env::var("CARGO_CRATE_NAME") + // If `CARGO_CRATE_NAME` is missing, then we're probably running in a test, so use // `no_crate`. .unwrap_or_else(|_| "no_crate".to_string()) .replace("rustc_", ""); From dfb2e3566d167590635bb9faeeb0ca0d76c61108 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sat, 1 Mar 2025 03:57:58 +0900 Subject: [PATCH 496/991] Migrate `convert_bool_then` to `SyntaxEditor` Update assist docs --- .../src/handlers/convert_bool_then.rs | 82 +++++++---- .../src/ast/syntax_factory/constructors.rs | 138 +++++++++++++++--- .../syntax/src/syntax_editor/mapping.rs | 6 +- .../docs/book/src/assists_generated.md | 8 +- 4 files changed, 174 insertions(+), 60 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index 8d391c64ce61..151c71c0a767 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -8,12 +8,13 @@ use ide_db::{ }; use itertools::Itertools; use syntax::{ - ast::{self, edit::AstNodeEdit, make, HasArgList}, - ted, AstNode, SyntaxNode, + ast::{self, edit::AstNodeEdit, syntax_factory::SyntaxFactory, HasArgList}, + syntax_editor::SyntaxEditor, + AstNode, SyntaxNode, }; use crate::{ - utils::{invert_boolean_expression_legacy, unwrap_trivial_block}, + utils::{invert_boolean_expression, unwrap_trivial_block}, AssistContext, AssistId, AssistKind, Assists, }; @@ -76,9 +77,9 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> "Convert `if` expression to `bool::then` call", target, |builder| { - let closure_body = closure_body.clone_for_update(); + let closure_body = closure_body.clone_subtree(); + let mut editor = SyntaxEditor::new(closure_body.syntax().clone()); // Rewrite all `Some(e)` in tail position to `e` - let mut replacements = Vec::new(); for_each_tail_expr(&closure_body, &mut |e| { let e = match e { ast::Expr::BreakExpr(e) => e.expr(), @@ -88,12 +89,16 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> if let Some(ast::Expr::CallExpr(call)) = e { if let Some(arg_list) = call.arg_list() { if let Some(arg) = arg_list.args().next() { - replacements.push((call.syntax().clone(), arg.syntax().clone())); + editor.replace(call.syntax(), arg.syntax()); } } } }); - replacements.into_iter().for_each(|(old, new)| ted::replace(old, new)); + let edit = editor.finish(); + let closure_body = ast::Expr::cast(edit.new_root().clone()).unwrap(); + + let mut editor = builder.make_editor(expr.syntax()); + let make = SyntaxFactory::new(); let closure_body = match closure_body { ast::Expr::BlockExpr(block) => unwrap_trivial_block(block), e => e, @@ -119,11 +124,18 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> | ast::Expr::WhileExpr(_) | ast::Expr::YieldExpr(_) ); - let cond = if invert_cond { invert_boolean_expression_legacy(cond) } else { cond }; - let cond = if parenthesize { make::expr_paren(cond) } else { cond }; - let arg_list = make::arg_list(Some(make::expr_closure(None, closure_body))); - let mcall = make::expr_method_call(cond, make::name_ref("then"), arg_list); - builder.replace(target, mcall.to_string()); + let cond = if invert_cond { + invert_boolean_expression(&make, cond) + } else { + cond.clone_for_update() + }; + let cond = if parenthesize { make.expr_paren(cond).into() } else { cond }; + let arg_list = make.arg_list(Some(make.expr_closure(None, closure_body).into())); + let mcall = make.expr_method_call(cond, make.name_ref("then"), arg_list); + editor.replace(expr.syntax(), mcall.syntax()); + + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } @@ -173,16 +185,17 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> "Convert `bool::then` call to `if`", target, |builder| { - let closure_body = match closure_body { + let mapless_make = SyntaxFactory::without_mappings(); + let closure_body = match closure_body.reset_indent() { ast::Expr::BlockExpr(block) => block, - e => make::block_expr(None, Some(e)), + e => mapless_make.block_expr(None, Some(e)), }; - let closure_body = closure_body.clone_for_update(); + let closure_body = closure_body.clone_subtree(); + let mut editor = SyntaxEditor::new(closure_body.syntax().clone()); // Wrap all tails in `Some(...)` - let none_path = make::expr_path(make::ext::ident_path("None")); - let some_path = make::expr_path(make::ext::ident_path("Some")); - let mut replacements = Vec::new(); + let none_path = mapless_make.expr_path(mapless_make.ident_path("None")); + let some_path = mapless_make.expr_path(mapless_make.ident_path("Some")); for_each_tail_expr(&ast::Expr::BlockExpr(closure_body.clone()), &mut |e| { let e = match e { ast::Expr::BreakExpr(e) => e.expr(), @@ -190,28 +203,37 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> _ => Some(e.clone()), }; if let Some(expr) = e { - replacements.push(( + editor.replace( expr.syntax().clone(), - make::expr_call(some_path.clone(), make::arg_list(Some(expr))) + mapless_make + .expr_call(some_path.clone(), mapless_make.arg_list(Some(expr))) .syntax() - .clone_for_update(), - )); + .clone(), + ); } }); - replacements.into_iter().for_each(|(old, new)| ted::replace(old, new)); + let edit = editor.finish(); + let closure_body = ast::BlockExpr::cast(edit.new_root().clone()).unwrap(); + + let mut editor = builder.make_editor(mcall.syntax()); + let make = SyntaxFactory::new(); let cond = match &receiver { ast::Expr::ParenExpr(expr) => expr.expr().unwrap_or(receiver), _ => receiver, }; - let if_expr = make::expr_if( - cond, - closure_body.reset_indent(), - Some(ast::ElseBranch::Block(make::block_expr(None, Some(none_path)))), - ) - .indent(mcall.indent_level()); + let if_expr = make + .expr_if( + cond, + closure_body, + Some(ast::ElseBranch::Block(make.block_expr(None, Some(none_path)))), + ) + .indent(mcall.indent_level()) + .clone_for_update(); + editor.replace(mcall.syntax().clone(), if_expr.syntax().clone()); - builder.replace(target, if_expr.to_string()); + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 19c5c64e2184..85393ca5b4ce 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -129,7 +129,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.segments().map(|it| it.syntax().clone())); + builder.map_children(input, ast.segments().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -162,7 +162,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.pats().map(|it| it.syntax().clone())); + builder.map_children(input, ast.pats().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -175,7 +175,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -193,7 +193,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -230,7 +230,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); if let Some(rest_pat) = rest_pat { builder .map_node(rest_pat.syntax().clone(), ast.rest_pat().unwrap().syntax().clone()); @@ -315,10 +315,7 @@ impl SyntaxFactory { builder.map_node(last_stmt, ast_tail.syntax().clone()); } - builder.map_children( - input.into_iter(), - stmt_list.statements().map(|it| it.syntax().clone()), - ); + builder.map_children(input, stmt_list.statements().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -351,7 +348,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -454,7 +451,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax.clone()); - builder.map_children(input.into_iter(), ast.args().map(|it| it.syntax().clone())); + builder.map_children(input, ast.args().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -476,6 +473,31 @@ impl SyntaxFactory { ast.into() } + pub fn expr_closure( + &self, + pats: impl IntoIterator, + expr: ast::Expr, + ) -> ast::ClosureExpr { + let (args, input) = iterator_input(pats); + // FIXME: `make::expr_paren` should return a `ClosureExpr`, not just an `Expr` + let ast::Expr::ClosureExpr(ast) = make::expr_closure(args, expr.clone()).clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax.clone()); + builder.map_children( + input, + ast.param_list().unwrap().params().map(|param| param.syntax().clone()), + ); + builder.map_node(expr.syntax().clone(), ast.body().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn expr_return(&self, expr: Option) -> ast::ReturnExpr { let ast::Expr::ReturnExpr(ast) = make::expr_return(expr.clone()).clone_for_update() else { unreachable!() @@ -604,7 +626,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.arms().map(|it| it.syntax().clone())); + builder.map_children(input, ast.arms().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -727,6 +749,19 @@ impl SyntaxFactory { ast } + pub fn param(&self, pat: ast::Pat, ty: ast::Type) -> ast::Param { + let ast = make::param(pat.clone(), ty.clone()); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn generic_arg_list( &self, generic_args: impl IntoIterator, @@ -741,10 +776,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children( - input.into_iter(), - ast.generic_args().map(|arg| arg.syntax().clone()), - ); + builder.map_children(input, ast.generic_args().map(|arg| arg.syntax().clone())); builder.finish(&mut mapping); } @@ -761,7 +793,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -806,7 +838,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -901,7 +933,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.variants().map(|it| it.syntax().clone())); + builder.map_children(input, ast.variants().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -953,6 +985,69 @@ impl SyntaxFactory { ast } + pub fn fn_( + &self, + visibility: Option, + fn_name: ast::Name, + type_params: Option, + where_clause: Option, + params: ast::ParamList, + body: ast::BlockExpr, + ret_type: Option, + is_async: bool, + is_const: bool, + is_unsafe: bool, + is_gen: bool, + ) -> ast::Fn { + let ast = make::fn_( + visibility.clone(), + fn_name.clone(), + type_params.clone(), + where_clause.clone(), + params.clone(), + body.clone(), + ret_type.clone(), + is_async, + is_const, + is_unsafe, + is_gen, + ); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + + if let Some(visibility) = visibility { + builder.map_node( + visibility.syntax().clone(), + ast.visibility().unwrap().syntax().clone(), + ); + } + builder.map_node(fn_name.syntax().clone(), ast.name().unwrap().syntax().clone()); + if let Some(type_params) = type_params { + builder.map_node( + type_params.syntax().clone(), + ast.generic_param_list().unwrap().syntax().clone(), + ); + } + if let Some(where_clause) = where_clause { + builder.map_node( + where_clause.syntax().clone(), + ast.where_clause().unwrap().syntax().clone(), + ); + } + builder.map_node(params.syntax().clone(), ast.param_list().unwrap().syntax().clone()); + builder.map_node(body.syntax().clone(), ast.body().unwrap().syntax().clone()); + if let Some(ret_type) = ret_type { + builder + .map_node(ret_type.syntax().clone(), ast.ret_type().unwrap().syntax().clone()); + } + + builder.finish(&mut mapping); + } + + ast + } + pub fn token_tree( &self, delimiter: SyntaxKind, @@ -965,10 +1060,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children( - input.into_iter(), - ast.token_trees_and_tokens().filter_map(only_nodes), - ); + builder.map_children(input, ast.token_trees_and_tokens().filter_map(only_nodes)); builder.finish(&mut mapping); } diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs index 16bc55ed2d46..f71925a79558 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs @@ -239,10 +239,10 @@ impl SyntaxMappingBuilder { pub fn map_children( &mut self, - input: impl Iterator, - output: impl Iterator, + input: impl IntoIterator, + output: impl IntoIterator, ) { - for pairs in input.zip_longest(output) { + for pairs in input.into_iter().zip_longest(output) { let (input, output) = match pairs { itertools::EitherOrBoth::Both(l, r) => (l, r), itertools::EitherOrBoth::Left(_) => { diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 2d233ca62ad6..72cecc2b02db 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -419,7 +419,7 @@ Converts comments to documentation. ### `convert_bool_then_to_if` -**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L131) +**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L143) Converts a `bool::then` method call to an equivalent if expression. @@ -443,7 +443,7 @@ fn main() { ### `convert_closure_to_fn` -**Source:** [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L25) +**Source:** [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L27) This converts a closure to a freestanding function, changing all captures to parameters. @@ -527,7 +527,7 @@ impl TryFrom for Thing { ### `convert_if_to_bool_then` -**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L20) +**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L21) Converts an if expression into a corresponding `bool::then` call. @@ -2258,7 +2258,7 @@ fn bar() { ### `inline_local_variable` -**Source:** [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L17) +**Source:** [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L21) Inlines a local variable. From 340a24910fe3a7e5949eec766801c053dbd05de0 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 1 Mar 2025 12:53:11 +0800 Subject: [PATCH 497/991] triagebot: only ping me for constck Per the [Zulip thread](https://rust-lang.zulipchat.com/#narrow/channel/146212-t-compiler.2Fconst-eval/topic/rustbot.20pings). --- triagebot.toml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index f9eb09ff3438..7702d4133aca 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -706,7 +706,11 @@ cc = ["@antoyo", "@GuillaumeGomez"] [mentions."compiler/rustc_const_eval/src/"] message = "Some changes occurred to the CTFE machinery" -cc = ["@rust-lang/wg-const-eval"] +cc = ["@RalfJung", "@oli-obk", "@lcnr"] + +[mentions."compiler/rustc_const_eval/src/check_consts"] +message = "Some changes occurred to constck" +cc = ["@fee1-dead"] [mentions."compiler/rustc_const_eval/src/interpret"] message = "Some changes occurred to the CTFE / Miri interpreter" @@ -730,7 +734,7 @@ cc = ["@compiler-errors", "@lcnr"] [mentions."compiler/rustc_middle/src/mir/interpret"] message = "Some changes occurred to the CTFE / Miri interpreter" -cc = ["@rust-lang/miri", "@rust-lang/wg-const-eval"] +cc = ["@rust-lang/miri", "@RalfJung", "@oli-obk", "@lcnr"] [mentions."compiler/rustc_mir_transform/src/"] message = "Some changes occurred to MIR optimizations" @@ -803,7 +807,7 @@ message = """ Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter gets adapted for the changes, if necessary. """ -cc = ["@rust-lang/miri", "@rust-lang/wg-const-eval"] +cc = ["@rust-lang/miri", "@RalfJung", "@oli-obk", "@lcnr"] [mentions."library/portable-simd"] message = """ From 2f4b9ddf897a6d8a492a9b01ef84cd43b1f62ca1 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 1 Mar 2025 12:23:33 +0800 Subject: [PATCH 498/991] Update `const_conditions` and `explicit_implied_const_bounds` docs Move documentation to query definitions, and add docs to `explicit_implied_const_bounds`. --- .../src/collect/predicates_of.rs | 10 +++------- compiler/rustc_middle/src/query/mod.rs | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 5b511d270743..44e172a7b708 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -940,12 +940,6 @@ impl<'tcx> ItemCtxt<'tcx> { } } -/// Compute the conditions that need to hold for a conditionally-const item to be const. -/// That is, compute the set of `~const` where clauses for a given item. -/// -/// This query also computes the `~const` where clauses for associated types, which are -/// not "const", but which have item bounds which may be `~const`. These must hold for -/// the `~const` item bound to hold. pub(super) fn const_conditions<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, @@ -1063,7 +1057,9 @@ pub(super) fn explicit_implied_const_bounds<'tcx>( def_id: LocalDefId, ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { if !tcx.is_conditionally_const(def_id) { - bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}"); + bug!( + "explicit_implied_const_bounds invoked for item that is not conditionally const: {def_id:?}" + ); } let bounds = match tcx.opt_rpitit_info(def_id.to_def_id()) { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 46a960d9945e..1302027aabb3 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -748,6 +748,15 @@ rustc_queries! { } } + /// Compute the conditions that need to hold for a conditionally-const item to be const. + /// That is, compute the set of `~const` where clauses for a given item. + /// + /// This can be thought of as the `~const` equivalent of `predicates_of`. These are the + /// predicates that need to be proven at usage sites, and can be assumed at definition. + /// + /// This query also computes the `~const` where clauses for associated types, which are + /// not "const", but which have item bounds which may be `~const`. These must hold for + /// the `~const` item bound to hold. query const_conditions( key: DefId ) -> ty::ConstConditions<'tcx> { @@ -757,6 +766,11 @@ rustc_queries! { separate_provide_extern } + /// Compute the const bounds that are implied for a conditionally-const item. + /// + /// This can be though of as the `~const` equivalent of `explicit_item_bounds`. These + /// are the predicates that need to proven at definition sites, and can be assumed at + /// usage sites. query explicit_implied_const_bounds( key: DefId ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { From 11e7aaf6e4841274a8023020943e9458700ae3a3 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sat, 15 Feb 2025 22:36:11 +0000 Subject: [PATCH 499/991] jsondocck: minor cleanups - replace `OnceLock` with `LazyLock` - use `let..else` where applicable --- src/tools/jsondocck/src/main.rs | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index 7bfa7e3355d3..3f3a524217a0 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; use std::process::ExitCode; -use std::sync::OnceLock; +use std::sync::LazyLock; use std::{env, fs}; use regex::{Regex, RegexBuilder}; @@ -151,8 +151,7 @@ impl CommandKind { } } -static LINE_PATTERN: OnceLock = OnceLock::new(); -fn line_pattern() -> Regex { +static LINE_PATTERN: LazyLock = LazyLock::new(|| { RegexBuilder::new( r#" //@\s+ @@ -165,7 +164,7 @@ fn line_pattern() -> Regex { .unicode(true) .build() .unwrap() -} +}); fn print_err(msg: &str, lineno: usize) { eprintln!("Invalid command: {} on line {}", msg, lineno) @@ -184,21 +183,17 @@ fn get_commands(template: &str) -> Result, ()> { for (lineno, line) in file.split('\n').enumerate() { let lineno = lineno + 1; - let cap = match LINE_PATTERN.get_or_init(line_pattern).captures(line) { - Some(c) => c, - None => continue, + let Some(cap) = LINE_PATTERN.captures(line) else { + continue; }; - let negated = cap.name("negated").unwrap().as_str() == "!"; + let negated = &cap["negated"] == "!"; let args_str = &cap["args"]; - let args = match shlex::split(args_str) { - Some(args) => args, - None => { - print_err(&format!("Invalid arguments to shlex::split: `{args_str}`",), lineno); - errors = true; - continue; - } + let Some(args) = shlex::split(args_str) else { + print_err(&format!("Invalid arguments to shlex::split: `{args_str}`",), lineno); + errors = true; + continue; }; if let Some((kind, path)) = CommandKind::parse(&cap["cmd"], negated, &args) { From 94645f6d102b2e7e720ffa1c759069c378bfd219 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sat, 15 Feb 2025 22:49:00 +0000 Subject: [PATCH 500/991] jsondocck: catch and error on deprecated syntax --- src/tools/jsondocck/src/main.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index 3f3a524217a0..54249fbd9ae7 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -166,6 +166,18 @@ static LINE_PATTERN: LazyLock = LazyLock::new(|| { .unwrap() }); +static DEPRECATED_LINE_PATTERN: LazyLock = LazyLock::new(|| { + RegexBuilder::new( + r#" + //\s+@ + "#, + ) + .ignore_whitespace(true) + .unicode(true) + .build() + .unwrap() +}); + fn print_err(msg: &str, lineno: usize) { eprintln!("Invalid command: {} on line {}", msg, lineno) } @@ -183,6 +195,12 @@ fn get_commands(template: &str) -> Result, ()> { for (lineno, line) in file.split('\n').enumerate() { let lineno = lineno + 1; + if DEPRECATED_LINE_PATTERN.is_match(line) { + print_err("Deprecated command syntax, replace `// @` with `//@ `", lineno); + errors = true; + continue; + } + let Some(cap) = LINE_PATTERN.captures(line) else { continue; }; From 797ef6455e782ec0ec4b6dd725c8ec70746e3e2d Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sat, 15 Feb 2025 22:49:21 +0000 Subject: [PATCH 501/991] htmldocck: catch and error on deprecated syntax --- src/etc/htmldocck.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py index d6b594aca71a..06fc6518e3b1 100755 --- a/src/etc/htmldocck.py +++ b/src/etc/htmldocck.py @@ -297,10 +297,24 @@ LINE_PATTERN = re.compile( re.X | re.UNICODE, ) +DEPRECATED_LINE_PATTERN = re.compile( + r""" + //\s+@ +""", + re.X | re.UNICODE, +) + def get_commands(template): with io.open(template, encoding="utf-8") as f: for lineno, line in concat_multi_lines(f): + if DEPRECATED_LINE_PATTERN.search(line): + print_err( + lineno, + line, + "Deprecated command syntax, replace `// @` with `//@ `", + ) + continue m = LINE_PATTERN.search(line) if not m: continue From 32de3b95a6255f1a3cdcfd8871fe26163cc619d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 1 Mar 2025 19:00:38 +0800 Subject: [PATCH 502/991] Revert "Remove Win SDK 10.0.26100.0 from CI" This reverts commit 25617c7e695d716d0ecb3cf2366d371441505e47. --- .github/workflows/ci.yml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 949932b8e2aa..de144ee6104c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -179,20 +179,6 @@ jobs: - name: show the current environment run: src/ci/scripts/dump-environment.sh - # Temporary fix to unblock CI - # Remove the latest Windows SDK for 32-bit Windows MSVC builds. - # See issue https://github.com/rust-lang/rust/issues/137733 for more details. - - name: Remove Windows SDK 10.0.26100.0 - shell: powershell - if: ${{ matrix.name == 'i686-msvc-1' || matrix.name == 'i686-msvc-2' || matrix.name == 'dist-i686-msvc' }} - run: | - $kits = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots').KitsRoot10 - $sdk_version = "10.0.26100.0" - - foreach ($kind in 'Bin', 'Lib', 'Include') { - Remove-Item -Force -Recurse $kits\$kind\$sdk_version -ErrorAction Continue - } - - name: run the build # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. run: src/ci/scripts/run-build-from-ci.sh 2>&1 From 3a6f269f26454835aabac9055ef0cda820b048ec Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 1 Mar 2025 12:20:30 +0100 Subject: [PATCH 503/991] improve error message and testing of using an unsigned simd mask --- compiler/rustc_codegen_ssa/messages.ftl | 3 +- compiler/rustc_codegen_ssa/src/errors.rs | 1 + tests/ui/simd/intrinsic/generic-gather.rs | 52 +++++++++++++++++++ tests/ui/simd/intrinsic/generic-gather.stderr | 39 ++++++++++++++ tests/ui/simd/intrinsic/generic-select.rs | 4 +- tests/ui/simd/intrinsic/generic-select.stderr | 8 ++- 6 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 tests/ui/simd/intrinsic/generic-gather.rs create mode 100644 tests/ui/simd/intrinsic/generic-gather.stderr diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 22e262546c3a..f15d6fba5066 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -119,7 +119,8 @@ codegen_ssa_invalid_monomorphization_inserted_type = invalid monomorphization of codegen_ssa_invalid_monomorphization_invalid_bitmask = invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` -codegen_ssa_invalid_monomorphization_mask_type = invalid monomorphization of `{$name}` intrinsic: mask element type is `{$ty}`, expected `i_` +codegen_ssa_invalid_monomorphization_mask_type = invalid monomorphization of `{$name}` intrinsic: found mask element type is `{$ty}`, expected a signed integer type + .note = the mask may be widened, which only has the correct behavior for signed integers codegen_ssa_invalid_monomorphization_mismatched_lengths = invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}` diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 7e28961599f0..ccf6d12977f6 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -957,6 +957,7 @@ pub enum InvalidMonomorphization<'tcx> { }, #[diag(codegen_ssa_invalid_monomorphization_mask_type, code = E0511)] + #[note] MaskType { #[primary_span] span: Span, diff --git a/tests/ui/simd/intrinsic/generic-gather.rs b/tests/ui/simd/intrinsic/generic-gather.rs new file mode 100644 index 000000000000..118d80294830 --- /dev/null +++ b/tests/ui/simd/intrinsic/generic-gather.rs @@ -0,0 +1,52 @@ +//@ build-fail +//@ ignore-emscripten + +// Test that the simd_{gather,scatter} intrinsics produce ok-ish error +// messages when misused. + +#![feature(repr_simd, core_intrinsics)] +#![allow(non_camel_case_types)] + +use std::intrinsics::simd::{simd_gather, simd_scatter}; + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct x4(pub [T; 4]); + +fn main() { + let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.]; + + let default = x4([-3_f32, -3., -3., -3.]); + let s_strided = x4([0_f32, 2., -3., 6.]); + + let mask = x4([-1_i32, -1, 0, -1]); + let umask = x4([0u16; 4]); + let fmask = x4([0_f32; 4]); + + let pointer = x.as_mut_ptr(); + let pointers = + unsafe { x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]) }; + + unsafe { + simd_gather(default, mask, mask); + //~^ ERROR expected element type `i32` of second argument `x4` to be a pointer to the element type `f32` + + simd_gather(default, pointers, umask); + //~^ ERROR expected element type `u16` of third argument `x4` to be a signed integer type + + simd_gather(default, pointers, fmask); + //~^ ERROR expected element type `f32` of third argument `x4` to be a signed integer type + } + + unsafe { + let values = x4([42_f32, 43_f32, 44_f32, 45_f32]); + simd_scatter(values, mask, mask); + //~^ ERROR expected element type `i32` of second argument `x4` to be a pointer to the element type `f32` of the first argument `x4`, found `i32` != `*mut f32` + + simd_scatter(values, pointers, umask); + //~^ ERROR expected element type `u16` of third argument `x4` to be a signed integer type + + simd_scatter(values, pointers, fmask); + //~^ ERROR expected element type `f32` of third argument `x4` to be a signed integer type + } +} diff --git a/tests/ui/simd/intrinsic/generic-gather.stderr b/tests/ui/simd/intrinsic/generic-gather.stderr new file mode 100644 index 000000000000..81e10fc98752 --- /dev/null +++ b/tests/ui/simd/intrinsic/generic-gather.stderr @@ -0,0 +1,39 @@ +error[E0511]: invalid monomorphization of `simd_gather` intrinsic: expected element type `i32` of second argument `x4` to be a pointer to the element type `f32` of the first argument `x4`, found `i32` != `*_ f32` + --> $DIR/generic-gather.rs:31:9 + | +LL | simd_gather(default, mask, mask); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_gather` intrinsic: expected element type `u16` of third argument `x4` to be a signed integer type + --> $DIR/generic-gather.rs:34:9 + | +LL | simd_gather(default, pointers, umask); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_gather` intrinsic: expected element type `f32` of third argument `x4` to be a signed integer type + --> $DIR/generic-gather.rs:37:9 + | +LL | simd_gather(default, pointers, fmask); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_scatter` intrinsic: expected element type `i32` of second argument `x4` to be a pointer to the element type `f32` of the first argument `x4`, found `i32` != `*mut f32` + --> $DIR/generic-gather.rs:43:9 + | +LL | simd_scatter(values, mask, mask); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_scatter` intrinsic: expected element type `u16` of third argument `x4` to be a signed integer type + --> $DIR/generic-gather.rs:46:9 + | +LL | simd_scatter(values, pointers, umask); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_scatter` intrinsic: expected element type `f32` of third argument `x4` to be a signed integer type + --> $DIR/generic-gather.rs:49:9 + | +LL | simd_scatter(values, pointers, fmask); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0511`. diff --git a/tests/ui/simd/intrinsic/generic-select.rs b/tests/ui/simd/intrinsic/generic-select.rs index 917ad3ca6046..db14032f1f20 100644 --- a/tests/ui/simd/intrinsic/generic-select.rs +++ b/tests/ui/simd/intrinsic/generic-select.rs @@ -37,10 +37,10 @@ fn main() { //~^ ERROR mismatched lengths: mask length `8` != other vector length `4` simd_select(x, x, x); - //~^ ERROR mask element type is `u32`, expected `i_` + //~^ ERROR mask element type is `u32`, expected a signed integer type simd_select(z, z, z); - //~^ ERROR mask element type is `f32`, expected `i_` + //~^ ERROR mask element type is `f32`, expected a signed integer type simd_select(m4, 0u32, 1u32); //~^ ERROR found non-SIMD `u32` diff --git a/tests/ui/simd/intrinsic/generic-select.stderr b/tests/ui/simd/intrinsic/generic-select.stderr index c46584d117ce..b9af86515fde 100644 --- a/tests/ui/simd/intrinsic/generic-select.stderr +++ b/tests/ui/simd/intrinsic/generic-select.stderr @@ -4,17 +4,21 @@ error[E0511]: invalid monomorphization of `simd_select` intrinsic: mismatched le LL | simd_select(m8, x, x); | ^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `u32`, expected `i_` +error[E0511]: invalid monomorphization of `simd_select` intrinsic: found mask element type is `u32`, expected a signed integer type --> $DIR/generic-select.rs:39:9 | LL | simd_select(x, x, x); | ^^^^^^^^^^^^^^^^^^^^ + | + = note: the mask may be widened, which only has the correct behavior for signed integers -error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `f32`, expected `i_` +error[E0511]: invalid monomorphization of `simd_select` intrinsic: found mask element type is `f32`, expected a signed integer type --> $DIR/generic-select.rs:42:9 | LL | simd_select(z, z, z); | ^^^^^^^^^^^^^^^^^^^^ + | + = note: the mask may be widened, which only has the correct behavior for signed integers error[E0511]: invalid monomorphization of `simd_select` intrinsic: expected SIMD argument type, found non-SIMD `u32` --> $DIR/generic-select.rs:45:9 From 3786a7a90825d2edf34c1a4c08047559eaf402cc Mon Sep 17 00:00:00 2001 From: Slanterns Date: Sat, 1 Mar 2025 19:59:43 +0800 Subject: [PATCH 504/991] stabilize `box_uninit_write` --- library/alloc/src/boxed.rs | 4 +--- library/alloc/src/lib.rs | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index c3f5806e1aa9..9b19ab74edfd 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -937,8 +937,6 @@ impl Box, A> { /// # Examples /// /// ``` - /// #![feature(box_uninit_write)] - /// /// let big_box = Box::<[usize; 1024]>::new_uninit(); /// /// let mut array = [0; 1024]; @@ -954,7 +952,7 @@ impl Box, A> { /// assert_eq!(*x, i); /// } /// ``` - #[unstable(feature = "box_uninit_write", issue = "129397")] + #[stable(feature = "box_uninit_write", since = "CURRENT_RUSTC_VERSION")] #[inline] pub fn write(mut boxed: Self, value: T) -> Box { unsafe { diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 2e9dd9857153..cb93100f56cf 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -102,7 +102,6 @@ #![feature(assert_matches)] #![feature(async_fn_traits)] #![feature(async_iterator)] -#![feature(box_uninit_write)] #![feature(bstr)] #![feature(bstr_internals)] #![feature(char_max_len)] From 42f51d4fd42c95e0c51c3f8742d63db0548cd5a0 Mon Sep 17 00:00:00 2001 From: Frank King Date: Wed, 5 Feb 2025 18:58:29 +0800 Subject: [PATCH 505/991] Implment `#[cfg]` and `#[cfg_attr]` in `where` clauses --- compiler/rustc_ast/src/ast.rs | 2 + compiler/rustc_ast/src/ast_traits.rs | 15 +- compiler/rustc_ast/src/mut_visit.rs | 18 +- compiler/rustc_ast/src/visit.rs | 3 +- compiler/rustc_ast_lowering/src/item.rs | 1 + compiler/rustc_ast_passes/src/feature_gate.rs | 1 + .../rustc_ast_pretty/src/pprust/state/item.rs | 3 +- .../src/deriving/coerce_pointee.rs | 19 +- .../src/deriving/generic/mod.rs | 11 +- compiler/rustc_expand/src/base.rs | 16 + compiler/rustc_expand/src/expand.rs | 38 +- compiler/rustc_expand/src/placeholders.rs | 24 + compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_hir/src/target.rs | 5 +- compiler/rustc_hir_pretty/src/lib.rs | 1 + compiler/rustc_parse/src/parser/generics.rs | 65 +- compiler/rustc_passes/messages.ftl | 4 + compiler/rustc_passes/src/check_attr.rs | 29 +- compiler/rustc_passes/src/errors.rs | 8 + .../rustc_resolve/src/build_reduced_graph.rs | 8 + compiler/rustc_resolve/src/def_collector.rs | 8 + compiler/rustc_span/src/symbol.rs | 1 + .../clippy/clippy_utils/src/ast_utils/mod.rs | 27 +- src/tools/rustfmt/src/spanned.rs | 7 +- src/tools/rustfmt/src/types.rs | 35 +- .../tests/target/cfg_attribute_in_where.rs | 116 +++ .../feature-gate-where_clause_attrs.a.stderr | 883 ++++++++++++++++++ .../feature-gate-where_clause_attrs.b.stderr | 883 ++++++++++++++++++ .../feature-gate-where_clause_attrs.rs | 162 ++++ tests/ui/parser/bounds-lifetime-where.rs | 2 +- tests/ui/parser/bounds-lifetime-where.stderr | 4 +- ...ype-where-in-next-line-issue-126311.stderr | 2 +- tests/ui/stats/input-stats.stderr | 28 +- tests/ui/where-clauses/cfg_attribute.a.stderr | 288 ++++++ tests/ui/where-clauses/cfg_attribute.b.stderr | 288 ++++++ tests/ui/where-clauses/cfg_attribute.rs | 183 ++++ .../ui/where-clauses/unsupported_attribute.rs | 36 + .../unsupported_attribute.stderr | 158 ++++ 38 files changed, 3296 insertions(+), 88 deletions(-) create mode 100644 src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs create mode 100644 tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr create mode 100644 tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr create mode 100644 tests/ui/feature-gates/feature-gate-where_clause_attrs.rs create mode 100644 tests/ui/where-clauses/cfg_attribute.a.stderr create mode 100644 tests/ui/where-clauses/cfg_attribute.b.stderr create mode 100644 tests/ui/where-clauses/cfg_attribute.rs create mode 100644 tests/ui/where-clauses/unsupported_attribute.rs create mode 100644 tests/ui/where-clauses/unsupported_attribute.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5c44fda22624..a8d30949ea85 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -417,9 +417,11 @@ impl WhereClause { /// A single predicate in a where-clause. #[derive(Clone, Encodable, Decodable, Debug)] pub struct WherePredicate { + pub attrs: AttrVec, pub kind: WherePredicateKind, pub id: NodeId, pub span: Span, + pub is_placeholder: bool, } /// Predicate kind in where-clause. diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 4a2d95593850..a37c0f92b127 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -11,7 +11,7 @@ use crate::tokenstream::LazyAttrTokenStream; use crate::{ Arm, AssocItem, AttrItem, AttrKind, AttrVec, Attribute, Block, Crate, Expr, ExprField, FieldDef, ForeignItem, GenericParam, Item, NodeId, Param, Pat, PatField, Path, Stmt, StmtKind, - Ty, Variant, Visibility, + Ty, Variant, Visibility, WherePredicate, }; /// A utility trait to reduce boilerplate. @@ -79,6 +79,7 @@ impl_has_node_id!( Stmt, Ty, Variant, + WherePredicate, ); impl> HasNodeId for T { @@ -127,7 +128,16 @@ macro_rules! impl_has_tokens_none { } impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path, Ty, Visibility); -impl_has_tokens_none!(Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant); +impl_has_tokens_none!( + Arm, + ExprField, + FieldDef, + GenericParam, + Param, + PatField, + Variant, + WherePredicate +); impl> HasTokens for T { fn tokens(&self) -> Option<&LazyAttrTokenStream> { @@ -279,6 +289,7 @@ impl_has_attrs!( Param, PatField, Variant, + WherePredicate, ); impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility); diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 9be364e320b7..f14646b5a99a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -338,8 +338,11 @@ pub trait MutVisitor: Sized { walk_where_clause(self, where_clause); } - fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { - walk_where_predicate(self, where_predicate) + fn flat_map_where_predicate( + &mut self, + where_predicate: WherePredicate, + ) -> SmallVec<[WherePredicate; 1]> { + walk_flat_map_where_predicate(self, where_predicate) } fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) { @@ -1097,15 +1100,20 @@ fn walk_ty_alias_where_clauses(vis: &mut T, tawcs: &mut TyAliasWh fn walk_where_clause(vis: &mut T, wc: &mut WhereClause) { let WhereClause { has_where_token: _, predicates, span } = wc; - visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); + predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate)); vis.visit_span(span); } -pub fn walk_where_predicate(vis: &mut T, pred: &mut WherePredicate) { - let WherePredicate { kind, id, span } = pred; +pub fn walk_flat_map_where_predicate( + vis: &mut T, + mut pred: WherePredicate, +) -> SmallVec<[WherePredicate; 1]> { + let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = &mut pred; vis.visit_id(id); + visit_attrs(vis, attrs); vis.visit_where_predicate_kind(kind); vis.visit_span(span); + smallvec![pred] } pub fn walk_where_predicate_kind(vis: &mut T, kind: &mut WherePredicateKind) { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 1cb32b56875c..37139e664f3d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -833,7 +833,8 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>( visitor: &mut V, predicate: &'a WherePredicate, ) -> V::Result { - let WherePredicate { kind, id: _, span: _ } = predicate; + let WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate; + walk_list!(visitor, visit_attribute, attrs); visitor.visit_where_predicate_kind(kind) } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index a4fc4b3e3a12..c6909883a672 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1728,6 +1728,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> { let hir_id = self.lower_node_id(pred.id); let span = self.lower_span(pred.span); + self.lower_attrs(hir_id, &pred.attrs, span); let kind = self.arena.alloc(match &pred.kind { WherePredicateKind::BoundPredicate(WhereBoundPredicate { bound_generic_params, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 0f80e49320ed..de11fe770c5b 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -503,6 +503,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(unsafe_binders, "unsafe binder types are experimental"); gate_all!(contracts, "contracts are incomplete"); gate_all!(contracts_internals, "contract internal machinery is for internal use only"); + gate_all!(where_clause_attrs, "attributes in `where` clause are unstable"); if !visitor.features.never_patterns() { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index c10b5ad34e10..ced0cbd2fef6 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -735,7 +735,8 @@ impl<'a> State<'a> { } pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) { - let ast::WherePredicate { kind, id: _, span: _ } = predicate; + let ast::WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate; + self.print_outer_attributes(attrs); match kind { ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => { self.print_where_bound_predicate(where_bound_predicate); diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 5aed9f76f144..46b79e097808 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -300,13 +300,16 @@ pub(crate) fn expand_deriving_coerce_pointee( to_ty: &s_ty, rewritten: false, }; - let mut predicate = ast::WherePredicate { - kind: ast::WherePredicateKind::BoundPredicate(bound.clone()), - span: predicate.span, - id: ast::DUMMY_NODE_ID, - }; - substitution.visit_where_predicate(&mut predicate); + let mut kind = ast::WherePredicateKind::BoundPredicate(bound.clone()); + substitution.visit_where_predicate_kind(&mut kind); if substitution.rewritten { + let predicate = ast::WherePredicate { + attrs: predicate.attrs.clone(), + kind, + span: predicate.span, + id: ast::DUMMY_NODE_ID, + is_placeholder: false, + }; impl_generics.where_clause.predicates.push(predicate); } } @@ -388,8 +391,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> { } } - fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) { - match &mut where_predicate.kind { + fn visit_where_predicate_kind(&mut self, kind: &mut ast::WherePredicateKind) { + match kind { rustc_ast::WherePredicateKind::BoundPredicate(bound) => { bound .bound_generic_params diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 6b59ac258275..5402b5a1ae9f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -687,9 +687,11 @@ impl<'a> TraitDef<'a> { // and similarly for where clauses where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| { ast::WherePredicate { + attrs: clause.attrs.clone(), kind: clause.kind.clone(), id: ast::DUMMY_NODE_ID, span: clause.span.with_ctxt(ctxt), + is_placeholder: false, } })); @@ -744,8 +746,13 @@ impl<'a> TraitDef<'a> { }; let kind = ast::WherePredicateKind::BoundPredicate(predicate); - let predicate = - ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span }; + let predicate = ast::WherePredicate { + attrs: ThinVec::new(), + kind, + id: ast::DUMMY_NODE_ID, + span: self.span, + is_placeholder: false, + }; where_clause.predicates.push(predicate); } } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 4a250145308c..86b12f6be4e6 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -53,6 +53,7 @@ pub enum Annotatable { Param(ast::Param), FieldDef(ast::FieldDef), Variant(ast::Variant), + WherePredicate(ast::WherePredicate), Crate(ast::Crate), } @@ -71,6 +72,7 @@ impl Annotatable { Annotatable::Param(p) => p.span, Annotatable::FieldDef(sf) => sf.span, Annotatable::Variant(v) => v.span, + Annotatable::WherePredicate(wp) => wp.span, Annotatable::Crate(c) => c.spans.inner_span, } } @@ -89,6 +91,7 @@ impl Annotatable { Annotatable::Param(p) => p.visit_attrs(f), Annotatable::FieldDef(sf) => sf.visit_attrs(f), Annotatable::Variant(v) => v.visit_attrs(f), + Annotatable::WherePredicate(wp) => wp.visit_attrs(f), Annotatable::Crate(c) => c.visit_attrs(f), } } @@ -107,6 +110,7 @@ impl Annotatable { Annotatable::Param(p) => visitor.visit_param(p), Annotatable::FieldDef(sf) => visitor.visit_field_def(sf), Annotatable::Variant(v) => visitor.visit_variant(v), + Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp), Annotatable::Crate(c) => visitor.visit_crate(c), } } @@ -128,6 +132,7 @@ impl Annotatable { | Annotatable::Param(..) | Annotatable::FieldDef(..) | Annotatable::Variant(..) + | Annotatable::WherePredicate(..) | Annotatable::Crate(..) => panic!("unexpected annotatable"), } } @@ -223,6 +228,13 @@ impl Annotatable { } } + pub fn expect_where_predicate(self) -> ast::WherePredicate { + match self { + Annotatable::WherePredicate(wp) => wp, + _ => panic!("expected where predicate"), + } + } + pub fn expect_crate(self) -> ast::Crate { match self { Annotatable::Crate(krate) => krate, @@ -446,6 +458,10 @@ pub trait MacResult { None } + fn make_where_predicates(self: Box) -> Option> { + None + } + fn make_crate(self: Box) -> Option { // Fn-like macros cannot produce a crate. unreachable!() diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index e3f31ebeca3f..c523bcece723 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -227,6 +227,12 @@ ast_fragments! { Variants(SmallVec<[ast::Variant; 1]>) { "variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants; } + WherePredicates(SmallVec<[ast::WherePredicate; 1]>) { + "where predicate"; + many fn flat_map_where_predicate; + fn visit_where_predicate(); + fn make_where_predicates; + } Crate(ast::Crate) { "crate"; one fn visit_crate; fn visit_crate; fn make_crate; } } @@ -259,7 +265,8 @@ impl AstFragmentKind { | AstFragmentKind::GenericParams | AstFragmentKind::Params | AstFragmentKind::FieldDefs - | AstFragmentKind::Variants => SupportsMacroExpansion::No, + | AstFragmentKind::Variants + | AstFragmentKind::WherePredicates => SupportsMacroExpansion::No, } } @@ -290,6 +297,9 @@ impl AstFragmentKind { AstFragmentKind::Variants => { AstFragment::Variants(items.map(Annotatable::expect_variant).collect()) } + AstFragmentKind::WherePredicates => AstFragment::WherePredicates( + items.map(Annotatable::expect_where_predicate).collect(), + ), AstFragmentKind::Items => { AstFragment::Items(items.map(Annotatable::expect_item).collect()) } @@ -865,7 +875,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { | Annotatable::GenericParam(..) | Annotatable::Param(..) | Annotatable::FieldDef(..) - | Annotatable::Variant(..) => panic!("unexpected annotatable"), + | Annotatable::Variant(..) + | Annotatable::WherePredicate(..) => panic!("unexpected annotatable"), }; if self.cx.ecfg.features.proc_macro_hygiene() { return; @@ -1002,7 +1013,8 @@ pub fn parse_ast_fragment<'a>( | AstFragmentKind::GenericParams | AstFragmentKind::Params | AstFragmentKind::FieldDefs - | AstFragmentKind::Variants => panic!("unexpected AST fragment kind"), + | AstFragmentKind::Variants + | AstFragmentKind::WherePredicates => panic!("unexpected AST fragment kind"), }) } @@ -1414,6 +1426,19 @@ impl InvocationCollectorNode for ast::Variant { } } +impl InvocationCollectorNode for ast::WherePredicate { + const KIND: AstFragmentKind = AstFragmentKind::WherePredicates; + fn to_annotatable(self) -> Annotatable { + Annotatable::WherePredicate(self) + } + fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { + fragment.make_where_predicates() + } + fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { + walk_flat_map_where_predicate(visitor, self) + } +} + impl InvocationCollectorNode for ast::FieldDef { const KIND: AstFragmentKind = AstFragmentKind::FieldDefs; fn to_annotatable(self) -> Annotatable { @@ -2116,6 +2141,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { self.flat_map_node(node) } + fn flat_map_where_predicate( + &mut self, + node: ast::WherePredicate, + ) -> SmallVec<[ast::WherePredicate; 1]> { + self.flat_map_node(node) + } + fn flat_map_field_def(&mut self, node: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> { self.flat_map_node(node) } diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index e969f2d4fb55..3a470924c7f6 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -188,6 +188,19 @@ pub(crate) fn placeholder( vis, is_placeholder: true, }]), + AstFragmentKind::WherePredicates => { + AstFragment::WherePredicates(smallvec![ast::WherePredicate { + attrs: Default::default(), + id, + span, + kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { + bound_generic_params: Default::default(), + bounded_ty: ty(), + bounds: Default::default(), + }), + is_placeholder: true, + }]) + } } } @@ -267,6 +280,17 @@ impl MutVisitor for PlaceholderExpander { } } + fn flat_map_where_predicate( + &mut self, + predicate: ast::WherePredicate, + ) -> SmallVec<[ast::WherePredicate; 1]> { + if predicate.is_placeholder { + self.remove(predicate.id).make_where_predicates() + } else { + walk_flat_map_where_predicate(self, predicate) + } + } + fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { match item.kind { ast::ItemKind::MacCall(_) => self.remove(item.id).make_items(), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 66c26a541f17..7e2f40d7b6f4 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -659,6 +659,8 @@ declare_features! ( (unstable, unsized_tuple_coercion, "1.20.0", Some(42877)), /// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute. (unstable, used_with_arg, "1.60.0", Some(93798)), + /// Allows use of attributes in `where` clauses. + (unstable, where_clause_attrs, "CURRENT_RUSTC_VERSION", Some(115590)), /// Allows use of x86 `AMX` target-feature attributes and intrinsics (unstable, x86_amx_intrinsics, "1.81.0", Some(126622)), /// Allows use of the `xop` target-feature diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 70e95a84e68c..601898023fc3 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -56,6 +56,7 @@ pub enum Target { Param, PatField, ExprField, + WherePredicate, } impl Display for Target { @@ -96,7 +97,8 @@ impl Target { | Target::MacroDef | Target::Param | Target::PatField - | Target::ExprField => false, + | Target::ExprField + | Target::WherePredicate => false, } } @@ -217,6 +219,7 @@ impl Target { Target::Param => "function param", Target::PatField => "pattern field", Target::ExprField => "struct field", + Target::WherePredicate => "where predicate", } } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index b3377b487694..025f1f2f8ce0 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2385,6 +2385,7 @@ impl<'a> State<'a> { } fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) { + self.print_attrs_as_outer(self.attrs(predicate.hir_id)); match *predicate.kind { hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { bound_generic_params, diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 11f0e579de5a..c3f71dd8b306 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -367,34 +367,47 @@ impl<'a> Parser<'a> { loop { let where_sp = where_lo.to(self.prev_token.span); + let attrs = self.parse_outer_attributes()?; let pred_lo = self.token.span; - let kind = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { - let lifetime = self.expect_lifetime(); - // Bounds starting with a colon are mandatory, but possibly empty. - self.expect(exp!(Colon))?; - let bounds = self.parse_lt_param_bounds(); - ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate { - lifetime, - bounds, - }) - } else if self.check_type() { - match self.parse_ty_where_predicate_kind_or_recover_tuple_struct_body( - struct_, pred_lo, where_sp, - )? { - PredicateKindOrStructBody::PredicateKind(kind) => kind, - PredicateKindOrStructBody::StructBody(body) => { - tuple_struct_body = Some(body); - break; - } + let predicate = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { + for attr in &attrs { + self.psess.gated_spans.gate(sym::where_clause_attrs, attr.span); } - } else { - break; - }; - where_clause.predicates.push(ast::WherePredicate { - kind, - id: DUMMY_NODE_ID, - span: pred_lo.to(self.prev_token.span), - }); + let kind = if this.check_lifetime() && this.look_ahead(1, |t| !t.is_like_plus()) { + let lifetime = this.expect_lifetime(); + // Bounds starting with a colon are mandatory, but possibly empty. + this.expect(exp!(Colon))?; + let bounds = this.parse_lt_param_bounds(); + Some(ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate { + lifetime, + bounds, + })) + } else if this.check_type() { + match this.parse_ty_where_predicate_kind_or_recover_tuple_struct_body( + struct_, pred_lo, where_sp, + )? { + PredicateKindOrStructBody::PredicateKind(kind) => Some(kind), + PredicateKindOrStructBody::StructBody(body) => { + tuple_struct_body = Some(body); + None + } + } + } else { + None + }; + let predicate = kind.map(|kind| ast::WherePredicate { + attrs, + kind, + id: DUMMY_NODE_ID, + span: pred_lo.to(this.prev_token.span), + is_placeholder: false, + }); + Ok((predicate, Trailing::No, UsePreAttrPos::No)) + })?; + match predicate { + Some(predicate) => where_clause.predicates.push(predicate), + None => break, + } let prev_token = self.prev_token.span; let ate_comma = self.eat(exp!(Comma)); diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index b65430c34802..ed498d9d3442 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -779,6 +779,10 @@ passes_unstable_attr_for_already_stable_feature = .item = the stability attribute annotates this item .help = consider removing the attribute +passes_unsupported_attributes_in_where = + most attributes are not supported in `where` clauses + .help = only `#[cfg]` and `#[cfg_attr]` are supported + passes_unused = unused attribute .suggestion = remove this attribute diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5ada289cc209..d6c0edf5ae7b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -919,7 +919,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | Target::Arm | Target::ForeignMod | Target::Closure - | Target::Impl => Some(target.name()), + | Target::Impl + | Target::WherePredicate => Some(target.name()), Target::ExternCrate | Target::Use | Target::Static @@ -2614,6 +2615,32 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { intravisit::walk_item(self, item) } + fn visit_where_predicate(&mut self, where_predicate: &'tcx hir::WherePredicate<'tcx>) { + // FIXME(where_clause_attrs): Currently, as the following check shows, + // only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed + // if we allow more attributes (e.g., tool attributes and `allow/deny/warn`) + // in where clauses. After that, only `self.check_attributes` should be enough. + const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr]; + let spans = self + .tcx + .hir() + .attrs(where_predicate.hir_id) + .iter() + .filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym))) + .map(|attr| attr.span()) + .collect::>(); + if !spans.is_empty() { + self.tcx.dcx().emit_err(errors::UnsupportedAttributesInWhere { span: spans.into() }); + } + self.check_attributes( + where_predicate.hir_id, + where_predicate.span, + Target::WherePredicate, + None, + ); + intravisit::walk_where_predicate(self, where_predicate) + } + fn visit_generic_param(&mut self, generic_param: &'tcx hir::GenericParam<'tcx>) { let target = Target::from_generic_param(generic_param); self.check_attributes(generic_param.hir_id, generic_param.span, target, None); diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 9bb9b2353dc8..b8359c27e538 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1909,3 +1909,11 @@ pub(crate) struct RustcConstStableIndirectPairing { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(passes_unsupported_attributes_in_where)] +#[help] +pub(crate) struct UnsupportedAttributesInWhere { + #[primary_span] + pub span: MultiSpan, +} diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 87f7eda391d9..42fe01b1c84c 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1529,6 +1529,14 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { visit::walk_variant(self, variant); } + fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) { + if p.is_placeholder { + self.visit_invoc(p.id); + } else { + visit::walk_where_predicate(self, p); + } + } + fn visit_crate(&mut self, krate: &'a ast::Crate) { if krate.is_placeholder { self.visit_invoc_in_module(krate.id); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 75972a71c8e5..42f8424c76ab 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -285,6 +285,14 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { }); } + fn visit_where_predicate(&mut self, pred: &'a WherePredicate) { + if pred.is_placeholder { + self.visit_macro_invoc(pred.id) + } else { + visit::walk_where_predicate(self, pred) + } + } + fn visit_variant_data(&mut self, data: &'a VariantData) { // The assumption here is that non-`cfg` macro expansion cannot change field indices. // It currently holds because only inert attributes are accepted on fields, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 501c9039f2de..df5a9cd90421 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2233,6 +2233,7 @@ symbols! { wasm_abi, wasm_import_module, wasm_target_feature, + where_clause_attrs, while_let, windows, windows_subsystem, diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index ab5f97199ce3..4f024ecaf29e 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -682,19 +682,20 @@ pub fn eq_generics(l: &Generics, r: &Generics) -> bool { pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool { use WherePredicateKind::*; - match (&l.kind, &r.kind) { - (BoundPredicate(l), BoundPredicate(r)) => { - over(&l.bound_generic_params, &r.bound_generic_params, |l, r| { - eq_generic_param(l, r) - }) && eq_ty(&l.bounded_ty, &r.bounded_ty) - && over(&l.bounds, &r.bounds, eq_generic_bound) - }, - (RegionPredicate(l), RegionPredicate(r)) => { - eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, eq_generic_bound) - }, - (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty), - _ => false, - } + over(&l.attrs, &r.attrs, eq_attr) + && match (&l.kind, &r.kind) { + (BoundPredicate(l), BoundPredicate(r)) => { + over(&l.bound_generic_params, &r.bound_generic_params, |l, r| { + eq_generic_param(l, r) + }) && eq_ty(&l.bounded_ty, &r.bounded_ty) + && over(&l.bounds, &r.bounds, eq_generic_bound) + }, + (RegionPredicate(l), RegionPredicate(r)) => { + eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, eq_generic_bound) + }, + (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty), + _ => false, + } } pub fn eq_use_tree(l: &UseTree, r: &UseTree) -> bool { diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index e93eb53cd87f..507647566d41 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -58,6 +58,7 @@ implement_spanned!(ast::ExprField); implement_spanned!(ast::ForeignItem); implement_spanned!(ast::Item); implement_spanned!(ast::Local); +implement_spanned!(ast::WherePredicate); impl Spanned for ast::Stmt { fn span(&self) -> Span { @@ -149,12 +150,6 @@ impl Spanned for ast::FieldDef { } } -impl Spanned for ast::WherePredicate { - fn span(&self) -> Span { - self.span - } -} - impl Spanned for ast::FnRetTy { fn span(&self) -> Span { match *self { diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 0009490e86fe..281be9578199 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -463,8 +463,9 @@ impl Rewrite for ast::WherePredicate { } fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { + let attrs_str = self.attrs.rewrite_result(context, shape)?; // FIXME: dead spans? - let result = match self.kind { + let pred_str = &match self.kind { ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { ref bound_generic_params, ref bounded_ty, @@ -499,6 +500,38 @@ impl Rewrite for ast::WherePredicate { } }; + let mut result = String::with_capacity(attrs_str.len() + pred_str.len() + 1); + result.push_str(&attrs_str); + let pred_start = self.span.lo(); + let line_len = last_line_width(&attrs_str) + 1 + first_line_width(&pred_str); + if let Some(last_attr) = self.attrs.last().filter(|last_attr| { + contains_comment(context.snippet(mk_sp(last_attr.span.hi(), pred_start))) + }) { + result = combine_strs_with_missing_comments( + context, + &result, + &pred_str, + mk_sp(last_attr.span.hi(), pred_start), + Shape { + width: shape.width.min(context.config.inline_attribute_width()), + ..shape + }, + !last_attr.is_doc_comment(), + )?; + } else { + if !self.attrs.is_empty() { + if context.config.inline_attribute_width() < line_len + || self.attrs.len() > 1 + || self.attrs.last().is_some_and(|a| a.is_doc_comment()) + { + result.push_str(&shape.indent.to_string_with_newline(context.config)); + } else { + result.push(' '); + } + } + result.push_str(&pred_str); + } + Ok(result) } } diff --git a/src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs b/src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs new file mode 100644 index 000000000000..11f495b16299 --- /dev/null +++ b/src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs @@ -0,0 +1,116 @@ +// rustfmt-inline_attribute_width: 40 + +#![crate_type = "lib"] +#![feature(cfg_attribute_in_where)] +use std::marker::PhantomData; + +#[cfg(a)] +trait TraitA {} + +#[cfg(b)] +trait TraitB {} + +trait A +where + #[cfg = a_very_long_attribute_name] + T: TraitA, + #[cfg = another_very_long_attribute_name] + T: TraitB, +{ + type B + where + #[cfg = a] + // line comment after the attribute + U: TraitA, + #[cfg = b] + /* block comment after the attribute */ + U: TraitB, + #[cfg = a] // short + U: TraitA, + #[cfg = b] /* short */ U: TraitB; + + fn foo(&self) + where + /// line doc comment before the attribute + U: TraitA, + /** line doc block comment before the attribute */ + U: TraitB; +} + +impl A for T +where + #[doc = "line doc before the attribute"] + T: TraitA, + /** short doc */ + T: TraitB, +{ + type B + = () + where + #[doc = "short"] U: TraitA, + #[doc = "short"] + #[cfg = a] + U: TraitB; + + fn foo(&self) + where + #[cfg = a] + #[cfg = b] + U: TraitA, + /// line doc + #[cfg = c] + U: TraitB, + { + } +} + +struct C +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ + _t: PhantomData, +} + +union D +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ + _t: PhantomData, +} + +enum E +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ + E(PhantomData), +} + +#[allow(type_alias_bounds)] +type F +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, += T; + +impl C +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ + fn new() + where + #[cfg = a] U: TraitA, + #[cfg = b] U: TraitB, + { + } +} + +fn foo() +where + #[cfg = a] T: TraitA, + #[cfg = b] T: TraitB, +{ +} diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr b/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr new file mode 100644 index 000000000000..6a8f01bbcce1 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr @@ -0,0 +1,883 @@ +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:33:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:34:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:35:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:36:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:37:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:38:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:39:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:40:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:44:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:45:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:46:9 + | +LL | #[cfg(all())] U: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:47:9 + | +LL | #[cfg(any())] U: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:48:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:49:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:50:9 + | +LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:51:9 + | +LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:55:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:56:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:57:9 + | +LL | #[cfg(all())] U: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:58:9 + | +LL | #[cfg(any())] U: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:59:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:60:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:61:9 + | +LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:62:9 + | +LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:67:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:68:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:69:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:70:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:71:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:72:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:73:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:74:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:77:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:78:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:79:9 + | +LL | #[cfg(all())] U: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:80:9 + | +LL | #[cfg(any())] U: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:81:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:82:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:83:9 + | +LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:84:9 + | +LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:88:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:89:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:90:9 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:91:9 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:92:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:93:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:94:9 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:95:9 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:101:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:102:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:103:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:104:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:105:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:106:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:107:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:108:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:115:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:116:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:117:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:118:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:119:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:120:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:121:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:122:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:130:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:131:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:132:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:133:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:134:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:135:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:136:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:137:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:143:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:144:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:145:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:146:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:147:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:148:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:149:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:150:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:153:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:154:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:155:9 + | +LL | #[cfg(all())] U: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:156:9 + | +LL | #[cfg(any())] U: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:157:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:158:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:159:9 + | +LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:160:9 + | +LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 88 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr b/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr new file mode 100644 index 000000000000..6a8f01bbcce1 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr @@ -0,0 +1,883 @@ +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:33:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:34:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:35:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:36:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:37:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:38:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:39:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:40:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:44:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:45:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:46:9 + | +LL | #[cfg(all())] U: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:47:9 + | +LL | #[cfg(any())] U: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:48:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:49:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:50:9 + | +LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:51:9 + | +LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:55:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:56:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:57:9 + | +LL | #[cfg(all())] U: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:58:9 + | +LL | #[cfg(any())] U: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:59:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:60:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:61:9 + | +LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:62:9 + | +LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:67:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:68:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:69:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:70:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:71:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:72:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:73:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:74:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:77:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:78:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:79:9 + | +LL | #[cfg(all())] U: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:80:9 + | +LL | #[cfg(any())] U: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:81:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:82:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:83:9 + | +LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:84:9 + | +LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:88:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:89:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:90:9 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:91:9 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:92:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:93:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:94:9 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:95:9 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:101:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:102:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:103:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:104:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:105:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:106:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:107:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:108:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:115:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:116:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:117:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:118:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:119:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:120:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:121:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:122:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:130:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:131:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:132:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:133:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:134:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:135:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:136:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:137:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:143:5 + | +LL | #[cfg(a)] T: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:144:5 + | +LL | #[cfg(b)] T: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:145:5 + | +LL | #[cfg(all())] T: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:146:5 + | +LL | #[cfg(any())] T: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:147:5 + | +LL | #[cfg_attr(a, cfg(a))] T: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:148:5 + | +LL | #[cfg_attr(b, cfg(b))] T: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:149:5 + | +LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:150:5 + | +LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:153:9 + | +LL | #[cfg(a)] U: TraitA, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:154:9 + | +LL | #[cfg(b)] U: TraitB, + | ^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:155:9 + | +LL | #[cfg(all())] U: TraitAll, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:156:9 + | +LL | #[cfg(any())] U: TraitAny, + | ^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:157:9 + | +LL | #[cfg_attr(a, cfg(a))] U: TraitAA, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:158:9 + | +LL | #[cfg_attr(b, cfg(b))] U: TraitBB, + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:159:9 + | +LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: attributes in `where` clause are unstable + --> $DIR/feature-gate-where_clause_attrs.rs:160:9 + | +LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #115590 for more information + = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 88 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs b/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs new file mode 100644 index 000000000000..09c734a52de0 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs @@ -0,0 +1,162 @@ +//@ revisions: a b + +#![crate_type = "lib"] +use std::marker::PhantomData; + +#[cfg(a)] +trait TraitA {} + +#[cfg(b)] +trait TraitB {} + +#[cfg_attr(a, cfg(a))] +trait TraitAA {} + +#[cfg_attr(b, cfg(b))] +trait TraitBB {} + +#[cfg(all())] +trait TraitAll {} + +#[cfg(any())] +trait TraitAny {} + +#[cfg_attr(all(), cfg(all()))] +trait TraitAllAll {} + +#[cfg_attr(any(), cfg(any()))] +trait TraitAnyAny {} + + +trait A +where + #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable +{ + type B + where + #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable + + fn foo(&self) + where + #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable +} + +impl A for T +where + #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable +{ + type B = () where + #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable + + fn foo(&self) + where + #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + {} +} + +struct C +where + #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable +{ + _t: PhantomData, +} + +union D +where + #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable +{ + + _t: PhantomData, +} + +enum E +where + #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable +{ + E(PhantomData), +} + +impl C where + #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable +{ + fn new() where + #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable + #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable + #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + {} +} diff --git a/tests/ui/parser/bounds-lifetime-where.rs b/tests/ui/parser/bounds-lifetime-where.rs index 7ff75233d3a8..730be7139bec 100644 --- a/tests/ui/parser/bounds-lifetime-where.rs +++ b/tests/ui/parser/bounds-lifetime-where.rs @@ -5,6 +5,6 @@ type A where 'a:, = u8; // OK type A where 'a: 'b + 'c = u8; // OK type A where = u8; // OK type A where 'a: 'b + = u8; // OK -type A where , = u8; //~ ERROR expected one of `;`, `=`, `where`, lifetime, or type, found `,` +type A where , = u8; //~ ERROR expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,` fn main() {} diff --git a/tests/ui/parser/bounds-lifetime-where.stderr b/tests/ui/parser/bounds-lifetime-where.stderr index 9dd963afc796..5aadb5fff320 100644 --- a/tests/ui/parser/bounds-lifetime-where.stderr +++ b/tests/ui/parser/bounds-lifetime-where.stderr @@ -1,8 +1,8 @@ -error: expected one of `;`, `=`, `where`, lifetime, or type, found `,` +error: expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,` --> $DIR/bounds-lifetime-where.rs:8:14 | LL | type A where , = u8; - | ^ expected one of `;`, `=`, `where`, lifetime, or type + | ^ expected one of `#`, `;`, `=`, `where`, lifetime, or type error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr b/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr index 196a46d7ea54..6245f81d533b 100644 --- a/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr +++ b/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr @@ -2,7 +2,7 @@ error: return type should be specified after the function parameters --> $DIR/misplaced-return-type-where-in-next-line-issue-126311.rs:5:15 | LL | K: Clone, -> Result - | ^^ expected one of `{`, lifetime, or type + | ^^ expected one of `#`, `{`, lifetime, or type | help: place the return type after the function parameters | diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr index 9b1568fa1166..dbc9e7d254c8 100644 --- a/tests/ui/stats/input-stats.stderr +++ b/tests/ui/stats/input-stats.stderr @@ -8,8 +8,8 @@ ast-stats-1 ExprField 48 ( 0.7%) 1 48 ast-stats-1 Attribute 64 ( 1.0%) 2 32 ast-stats-1 - DocComment 32 ( 0.5%) 1 ast-stats-1 - Normal 32 ( 0.5%) 1 -ast-stats-1 WherePredicate 64 ( 1.0%) 1 64 -ast-stats-1 - BoundPredicate 64 ( 1.0%) 1 +ast-stats-1 WherePredicate 72 ( 1.1%) 1 72 +ast-stats-1 - BoundPredicate 72 ( 1.1%) 1 ast-stats-1 Local 80 ( 1.2%) 1 80 ast-stats-1 ForeignItem 88 ( 1.3%) 1 88 ast-stats-1 - Fn 88 ( 1.3%) 1 @@ -37,14 +37,14 @@ ast-stats-1 Expr 576 ( 8.6%) 8 72 ast-stats-1 - Match 72 ( 1.1%) 1 ast-stats-1 - Path 72 ( 1.1%) 1 ast-stats-1 - Struct 72 ( 1.1%) 1 -ast-stats-1 - Lit 144 ( 2.2%) 2 +ast-stats-1 - Lit 144 ( 2.1%) 2 ast-stats-1 - Block 216 ( 3.2%) 3 ast-stats-1 PathSegment 744 (11.1%) 31 24 ast-stats-1 Ty 896 (13.4%) 14 64 ast-stats-1 - Ptr 64 ( 1.0%) 1 ast-stats-1 - Ref 64 ( 1.0%) 1 ast-stats-1 - ImplicitSelf 128 ( 1.9%) 2 -ast-stats-1 - Path 640 ( 9.6%) 10 +ast-stats-1 - Path 640 ( 9.5%) 10 ast-stats-1 Item 1_224 (18.3%) 9 136 ast-stats-1 - Enum 136 ( 2.0%) 1 ast-stats-1 - ForeignMod 136 ( 2.0%) 1 @@ -53,7 +53,7 @@ ast-stats-1 - Trait 136 ( 2.0%) 1 ast-stats-1 - Fn 272 ( 4.1%) 2 ast-stats-1 - Use 408 ( 6.1%) 3 ast-stats-1 ---------------------------------------------------------------- -ast-stats-1 Total 6_696 116 +ast-stats-1 Total 6_704 116 ast-stats-1 ast-stats-2 POST EXPANSION AST STATS ast-stats-2 Name Accumulated Size Count Item Size @@ -62,8 +62,8 @@ ast-stats-2 Crate 40 ( 0.5%) 1 40 ast-stats-2 GenericArgs 40 ( 0.5%) 1 40 ast-stats-2 - AngleBracketed 40 ( 0.5%) 1 ast-stats-2 ExprField 48 ( 0.7%) 1 48 -ast-stats-2 WherePredicate 64 ( 0.9%) 1 64 -ast-stats-2 - BoundPredicate 64 ( 0.9%) 1 +ast-stats-2 WherePredicate 72 ( 1.0%) 1 72 +ast-stats-2 - BoundPredicate 72 ( 1.0%) 1 ast-stats-2 Local 80 ( 1.1%) 1 80 ast-stats-2 ForeignItem 88 ( 1.2%) 1 88 ast-stats-2 - Fn 88 ( 1.2%) 1 @@ -104,16 +104,16 @@ ast-stats-2 - Ptr 64 ( 0.9%) 1 ast-stats-2 - Ref 64 ( 0.9%) 1 ast-stats-2 - ImplicitSelf 128 ( 1.7%) 2 ast-stats-2 - Path 640 ( 8.7%) 10 -ast-stats-2 Item 1_496 (20.4%) 11 136 -ast-stats-2 - Enum 136 ( 1.9%) 1 -ast-stats-2 - ExternCrate 136 ( 1.9%) 1 -ast-stats-2 - ForeignMod 136 ( 1.9%) 1 -ast-stats-2 - Impl 136 ( 1.9%) 1 -ast-stats-2 - Trait 136 ( 1.9%) 1 +ast-stats-2 Item 1_496 (20.3%) 11 136 +ast-stats-2 - Enum 136 ( 1.8%) 1 +ast-stats-2 - ExternCrate 136 ( 1.8%) 1 +ast-stats-2 - ForeignMod 136 ( 1.8%) 1 +ast-stats-2 - Impl 136 ( 1.8%) 1 +ast-stats-2 - Trait 136 ( 1.8%) 1 ast-stats-2 - Fn 272 ( 3.7%) 2 ast-stats-2 - Use 544 ( 7.4%) 4 ast-stats-2 ---------------------------------------------------------------- -ast-stats-2 Total 7_344 127 +ast-stats-2 Total 7_352 127 ast-stats-2 hir-stats HIR STATS hir-stats Name Accumulated Size Count Item Size diff --git a/tests/ui/where-clauses/cfg_attribute.a.stderr b/tests/ui/where-clauses/cfg_attribute.a.stderr new file mode 100644 index 000000000000..0ede890eb44f --- /dev/null +++ b/tests/ui/where-clauses/cfg_attribute.a.stderr @@ -0,0 +1,288 @@ +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:32:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:43:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:54:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:66:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:76:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:87:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:100:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:114:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:129:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:144:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:155:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:165:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:178:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:32:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:35:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:66:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:69:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:100:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:103:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:114:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:117:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:129:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:132:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:144:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:147:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:155:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:158:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:178:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:181:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:43:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:46:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:54:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:57:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:76:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:79:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:87:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:90:9 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:165:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:168:9 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: aborting due to 39 previous errors + diff --git a/tests/ui/where-clauses/cfg_attribute.b.stderr b/tests/ui/where-clauses/cfg_attribute.b.stderr new file mode 100644 index 000000000000..0ede890eb44f --- /dev/null +++ b/tests/ui/where-clauses/cfg_attribute.b.stderr @@ -0,0 +1,288 @@ +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:32:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:43:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:54:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:66:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:76:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:87:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:100:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:114:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:129:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:144:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:155:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:165:11 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/cfg_attribute.rs:178:7 + | +LL | #[derive(Clone)] ():, + | ^^^^^^ not a non-macro attribute + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:32:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:35:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:66:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:69:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:100:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:103:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:114:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:117:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:129:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:132:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:144:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:147:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:155:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:158:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:178:5 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:181:5 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:43:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:46:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:54:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:57:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:76:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:79:9 + | +LL | #[rustfmt::skip] ():; + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:87:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:90:9 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:165:9 + | +LL | #[derive(Clone)] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/cfg_attribute.rs:168:9 + | +LL | #[rustfmt::skip] ():, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: aborting due to 39 previous errors + diff --git a/tests/ui/where-clauses/cfg_attribute.rs b/tests/ui/where-clauses/cfg_attribute.rs new file mode 100644 index 000000000000..8cbca0bee75d --- /dev/null +++ b/tests/ui/where-clauses/cfg_attribute.rs @@ -0,0 +1,183 @@ +//@ revisions: a b + +#![crate_type = "lib"] +#![feature(alloc_error_handler)] +#![feature(cfg_accessible)] +#![feature(cfg_eval)] +#![feature(custom_test_frameworks)] +#![feature(derive_const)] +#![feature(where_clause_attrs)] +#![allow(soft_unstable)] + +use std::marker::PhantomData; + +#[cfg(a)] +trait TraitA {} + +#[cfg(b)] +trait TraitB {} + +#[cfg_attr(a, cfg(a))] +trait TraitAA {} + +#[cfg_attr(b, cfg(b))] +trait TraitBB {} + +trait A +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, + #[cfg_attr(a, cfg(a))] T: TraitAA, + #[cfg_attr(b, cfg(b))] T: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses +{ + type B + where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB, + #[cfg_attr(a, cfg(a))] U: TraitAA, + #[cfg_attr(b, cfg(b))] U: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():; //~ ERROR most attributes are not supported in `where` clauses + + fn foo(&self) + where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB, + #[cfg_attr(a, cfg(a))] U: TraitAA, + #[cfg_attr(b, cfg(b))] U: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():; //~ ERROR most attributes are not supported in `where` clauses +} + +impl A for T +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, + #[cfg_attr(a, cfg(a))] T: TraitAA, + #[cfg_attr(b, cfg(b))] T: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses +{ + type B = () where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB, + #[cfg_attr(a, cfg(a))] U: TraitAA, + #[cfg_attr(b, cfg(b))] U: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():; //~ ERROR most attributes are not supported in `where` clauses + + fn foo(&self) + where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB, + #[cfg_attr(a, cfg(a))] U: TraitAA, + #[cfg_attr(b, cfg(b))] U: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses + {} +} + +struct C +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, + #[cfg_attr(a, cfg(a))] T: TraitAA, + #[cfg_attr(b, cfg(b))] T: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses +{ + _t: PhantomData, +} + +union D +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, + #[cfg_attr(a, cfg(a))] T: TraitAA, + #[cfg_attr(b, cfg(b))] T: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses +{ + + _t: PhantomData, +} + +enum E +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, + #[cfg_attr(a, cfg(a))] T: TraitAA, + #[cfg_attr(b, cfg(b))] T: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses +{ + E(PhantomData), +} + +#[allow(type_alias_bounds)] +type F +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, + #[cfg_attr(a, cfg(a))] T: TraitAA, + #[cfg_attr(b, cfg(b))] T: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses += T; + +impl C where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, + #[cfg_attr(a, cfg(a))] T: TraitAA, + #[cfg_attr(b, cfg(b))] T: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses +{ + fn new() where + #[cfg(a)] U: TraitA, + #[cfg(b)] U: TraitB, + #[cfg_attr(a, cfg(a))] U: TraitAA, + #[cfg_attr(b, cfg(b))] U: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses + {} +} + +fn foo() +where + #[cfg(a)] T: TraitA, + #[cfg(b)] T: TraitB, + #[cfg_attr(a, cfg(a))] T: TraitAA, + #[cfg_attr(b, cfg(b))] T: TraitBB, + #[derive(Clone)] ():, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses +{ +} diff --git a/tests/ui/where-clauses/unsupported_attribute.rs b/tests/ui/where-clauses/unsupported_attribute.rs new file mode 100644 index 000000000000..33128b383b99 --- /dev/null +++ b/tests/ui/where-clauses/unsupported_attribute.rs @@ -0,0 +1,36 @@ +#![crate_type = "lib"] +#![feature(alloc_error_handler)] +#![feature(cfg_accessible)] +#![feature(cfg_eval)] +#![feature(custom_test_frameworks)] +#![feature(derive_const)] +#![feature(where_clause_attrs)] +#![allow(soft_unstable)] + +trait Trait {} + +fn foo<'a, T>() +where + #[doc = "doc"] T: Trait, //~ ERROR most attributes are not supported in `where` clauses + #[doc = "doc"] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses + #[ignore] T: Trait, //~ ERROR most attributes are not supported in `where` clauses + #[ignore] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses + #[should_panic] T: Trait, //~ ERROR most attributes are not supported in `where` clauses + #[should_panic] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses + #[macro_use] T: Trait, //~ ERROR most attributes are not supported in `where` clauses + #[macro_use] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses + #[allow(unused)] T: Trait, //~ ERROR most attributes are not supported in `where` clauses + #[allow(unused)] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses + #[deprecated] T: Trait, //~ ERROR most attributes are not supported in `where` clauses + #[deprecated] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses + #[automatically_derived] T: Trait, //~ ERROR most attributes are not supported in `where` clauses + #[automatically_derived] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses + #[derive(Clone)] T: Trait, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[derive(Clone)] 'a: 'static, + //~^ ERROR most attributes are not supported in `where` clauses + //~| ERROR expected non-macro attribute, found attribute macro `derive` + #[rustfmt::skip] T: Trait, //~ ERROR most attributes are not supported in `where` clauses + #[rustfmt::skip] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses +{} diff --git a/tests/ui/where-clauses/unsupported_attribute.stderr b/tests/ui/where-clauses/unsupported_attribute.stderr new file mode 100644 index 000000000000..ecb28039f885 --- /dev/null +++ b/tests/ui/where-clauses/unsupported_attribute.stderr @@ -0,0 +1,158 @@ +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/unsupported_attribute.rs:28:7 + | +LL | #[derive(Clone)] T: Trait, + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/unsupported_attribute.rs:31:7 + | +LL | #[derive(Clone)] 'a: 'static, + | ^^^^^^ not a non-macro attribute + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:14:5 + | +LL | #[doc = "doc"] T: Trait, + | ^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:15:5 + | +LL | #[doc = "doc"] 'a: 'static, + | ^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:16:5 + | +LL | #[ignore] T: Trait, + | ^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:17:5 + | +LL | #[ignore] 'a: 'static, + | ^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:18:5 + | +LL | #[should_panic] T: Trait, + | ^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:19:5 + | +LL | #[should_panic] 'a: 'static, + | ^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:20:5 + | +LL | #[macro_use] T: Trait, + | ^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:21:5 + | +LL | #[macro_use] 'a: 'static, + | ^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:22:5 + | +LL | #[allow(unused)] T: Trait, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:23:5 + | +LL | #[allow(unused)] 'a: 'static, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:24:5 + | +LL | #[deprecated] T: Trait, + | ^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:25:5 + | +LL | #[deprecated] 'a: 'static, + | ^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:26:5 + | +LL | #[automatically_derived] T: Trait, + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:27:5 + | +LL | #[automatically_derived] 'a: 'static, + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:28:5 + | +LL | #[derive(Clone)] T: Trait, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:31:5 + | +LL | #[derive(Clone)] 'a: 'static, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:34:5 + | +LL | #[rustfmt::skip] T: Trait, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/unsupported_attribute.rs:35:5 + | +LL | #[rustfmt::skip] 'a: 'static, + | ^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: aborting due to 20 previous errors + From 4c939db0e775df21a0b409b7603eaaf0056e8f86 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Feb 2025 16:56:36 +0100 Subject: [PATCH 506/991] also skip abi_required_features check in rustdoc --- .../rustc_codegen_ssa/src/target_features.rs | 17 +++++++++++------ tests/rustdoc-ui/target-feature-stability.rs | 16 +++++++++++++--- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index a63e1877e453..95a5e96fe46e 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -87,12 +87,17 @@ pub(crate) fn from_target_feature_attr( // But ensure the ABI does not forbid enabling this. // Here we do assume that LLVM doesn't add even more implied features // we don't know about, at least no features that would have ABI effects! - if abi_feature_constraints.incompatible.contains(&name.as_str()) { - tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr { - span: item.span(), - feature: name.as_str(), - reason: "this feature is incompatible with the target ABI", - }); + // We skip this logic in rustdoc, where we want to allow all target features of + // all targets, so we can't check their ABI compatibility and anyway we are not + // generating code so "it's fine". + if !tcx.sess.opts.actually_rustdoc { + if abi_feature_constraints.incompatible.contains(&name.as_str()) { + tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr { + span: item.span(), + feature: name.as_str(), + reason: "this feature is incompatible with the target ABI", + }); + } } target_features.push(TargetFeature { name, implied: name != feature_sym }) } diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs index 4ade9690310e..17fa3ccfe3e8 100644 --- a/tests/rustdoc-ui/target-feature-stability.rs +++ b/tests/rustdoc-ui/target-feature-stability.rs @@ -1,9 +1,13 @@ //! This is a regression test for , ensuring -//! that we can use the `neon` target feature on ARM-32 targets in rustdoc despite there +//! that we can use the `neon` target feature on ARM32 targets in rustdoc despite there //! being a "forbidden" feature of the same name for aarch64, and rustdoc merging the //! target features of all targets. //@ check-pass -//@ compile-flags: --target armv7-unknown-linux-gnueabihf +//@ revisions: arm aarch64 +//@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf +//@[arm] needs-llvm-components: arm +//@[aarch64] compile-flags: --target aarch64-unknown-none-softfloat +//@[aarch64] needs-llvm-components: aarch64 #![crate_type = "lib"] #![feature(no_core, lang_items)] @@ -15,4 +19,10 @@ pub trait Sized {} // `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`. #[target_feature(enable = "fp-armv8")] -pub fn fun() {} +pub fn fun1() {} + +// This would usually be rejected as it changes the ABI. +// But we disable that check in rustdoc since we are building "for all targets" and the +// check can't really handle that. +#[target_feature(enable = "soft-float")] +pub fn fun2() {} From 08eeb8f3b24e7b507065b556010ad0e0d1a6a0f6 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 1 Mar 2025 16:54:40 +0100 Subject: [PATCH 507/991] Cleanup highlighting macro-def handling --- .../rust-analyzer/crates/hir/src/semantics.rs | 19 +- .../crates/ide/src/syntax_highlighting.rs | 341 ++++++++---------- .../ide/src/syntax_highlighting/escape.rs | 21 +- .../ide/src/syntax_highlighting/format.rs | 6 +- .../ide/src/syntax_highlighting/highlight.rs | 18 +- .../ide/src/syntax_highlighting/macro_.rs | 128 ------- .../test_data/highlight_doctest.html | 2 +- .../test_data/highlight_general.html | 2 +- 8 files changed, 197 insertions(+), 340 deletions(-) delete mode 100644 src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/macro_.rs diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index c9145f7d212d..bb67fa63a1d1 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -508,9 +508,7 @@ impl<'db> SemanticsImpl<'db> { }) } - pub fn is_derive_annotated(&self, adt: &ast::Adt) -> bool { - let file_id = self.find_file(adt.syntax()).file_id; - let adt = InFile::new(file_id, adt); + pub fn is_derive_annotated(&self, adt: InFile<&ast::Adt>) -> bool { self.with_ctx(|ctx| ctx.has_derives(adt)) } @@ -551,10 +549,8 @@ impl<'db> SemanticsImpl<'db> { res.is_empty().not().then_some(res) } - pub fn is_attr_macro_call(&self, item: &ast::Item) -> bool { - let file_id = self.find_file(item.syntax()).file_id; - let src = InFile::new(file_id, item); - self.with_ctx(|ctx| ctx.item_to_macro_call(src).is_some()) + pub fn is_attr_macro_call(&self, item: InFile<&ast::Item>) -> bool { + self.with_ctx(|ctx| ctx.item_to_macro_call(item).is_some()) } /// Expand the macro call with a different token tree, mapping the `token_to_map` down into the @@ -1526,8 +1522,13 @@ impl<'db> SemanticsImpl<'db> { self.analyze(field.syntax())?.resolve_record_pat_field(self.db, field) } + // FIXME: Replace this with `resolve_macro_call2` pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call); + self.resolve_macro_call2(macro_call) + } + + pub fn resolve_macro_call2(&self, macro_call: InFile<&ast::MacroCall>) -> Option { self.with_ctx(|ctx| { ctx.macro_call_to_macro_call(macro_call) .and_then(|call| macro_call_to_macro_id(ctx, call)) @@ -1538,8 +1539,8 @@ impl<'db> SemanticsImpl<'db> { }) } - pub fn is_proc_macro_call(&self, macro_call: &ast::MacroCall) -> bool { - self.resolve_macro_call(macro_call) + pub fn is_proc_macro_call(&self, macro_call: InFile<&ast::MacroCall>) -> bool { + self.resolve_macro_call2(macro_call) .is_some_and(|m| matches!(m.id, MacroId::ProcMacroId(..))) } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index 1853e3a34074..6c5e81ae667a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -7,7 +7,6 @@ mod escape; mod format; mod highlight; mod inject; -mod macro_; mod html; #[cfg(test)] @@ -15,14 +14,14 @@ mod tests; use std::ops::ControlFlow; -use hir::{InRealFile, Name, Semantics}; +use hir::{InFile, InRealFile, Name, Semantics}; use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind}; use span::EditionedFileId; use syntax::{ ast::{self, IsString}, AstNode, AstToken, NodeOrToken, SyntaxKind::*, - SyntaxNode, TextRange, WalkEvent, T, + SyntaxNode, SyntaxToken, TextRange, WalkEvent, T, }; use crate::{ @@ -30,7 +29,6 @@ use crate::{ escape::{highlight_escape_byte, highlight_escape_char, highlight_escape_string}, format::highlight_format_string, highlights::Highlights, - macro_::MacroHighlighter, tags::Highlight, }, FileId, HlMod, HlOperator, HlPunct, HlTag, @@ -221,7 +219,7 @@ pub(crate) fn highlight( Some(it) => it.krate(), None => return hl.to_vec(), }; - traverse(&mut hl, &sema, config, file_id, &root, krate, range_to_highlight); + traverse(&mut hl, &sema, config, InRealFile::new(file_id, &root), krate, range_to_highlight); hl.to_vec() } @@ -229,8 +227,7 @@ fn traverse( hl: &mut Highlights, sema: &Semantics<'_, RootDatabase>, config: HighlightConfig, - file_id: EditionedFileId, - root: &SyntaxNode, + InRealFile { file_id, value: root }: InRealFile<&SyntaxNode>, krate: hir::Crate, range_to_highlight: TextRange, ) { @@ -252,8 +249,6 @@ fn traverse( let mut tt_level = 0; let mut attr_or_derive_item = None; - let mut current_macro: Option = None; - let mut macro_highlighter = MacroHighlighter::default(); // FIXME: these are not perfectly accurate, we determine them by the real file's syntax tree // an attribute nested in a macro call will not emit `inside_attribute` @@ -263,7 +258,8 @@ fn traverse( // Walk all nodes, keeping track of whether we are inside a macro or not. // If in macro, expand it first and highlight the expanded code. - for event in root.preorder_with_tokens() { + let mut preorder = root.preorder_with_tokens(); + while let Some(event) = preorder.next() { use WalkEvent::{Enter, Leave}; let range = match &event { @@ -275,16 +271,11 @@ fn traverse( continue; } - // set macro and attribute highlighting states match event.clone() { - Enter(NodeOrToken::Node(node)) - if current_macro.is_none() && ast::TokenTree::can_cast(node.kind()) => - { + Enter(NodeOrToken::Node(node)) if ast::TokenTree::can_cast(node.kind()) => { tt_level += 1; } - Leave(NodeOrToken::Node(node)) - if current_macro.is_none() && ast::TokenTree::can_cast(node.kind()) => - { + Leave(NodeOrToken::Node(node)) if ast::TokenTree::can_cast(node.kind()) => { tt_level -= 1; } Enter(NodeOrToken::Node(node)) if ast::Attr::can_cast(node.kind()) => { @@ -297,28 +288,19 @@ fn traverse( Enter(NodeOrToken::Node(node)) => { if let Some(item) = ast::Item::cast(node.clone()) { match item { - ast::Item::MacroRules(mac) => { - macro_highlighter.init(); - current_macro = Some(mac.into()); - continue; - } - ast::Item::MacroDef(mac) => { - macro_highlighter.init(); - current_macro = Some(mac.into()); - continue; - } ast::Item::Fn(_) | ast::Item::Const(_) | ast::Item::Static(_) => { bindings_shadow_count.clear() } ast::Item::MacroCall(ref macro_call) => { inside_macro_call = true; - inside_proc_macro_call = sema.is_proc_macro_call(macro_call); + inside_proc_macro_call = + sema.is_proc_macro_call(InFile::new(file_id.into(), macro_call)); } _ => (), } if attr_or_derive_item.is_none() { - if sema.is_attr_macro_call(&item) { + if sema.is_attr_macro_call(InFile::new(file_id.into(), &item)) { attr_or_derive_item = Some(AttrOrDerive::Attr(item)); } else { let adt = match item { @@ -328,7 +310,10 @@ fn traverse( _ => None, }; match adt { - Some(adt) if sema.is_derive_annotated(&adt) => { + Some(adt) + if sema + .is_derive_annotated(InFile::new(file_id.into(), &adt)) => + { attr_or_derive_item = Some(AttrOrDerive::Derive(ast::Item::from(adt))); } @@ -340,16 +325,6 @@ fn traverse( } Leave(NodeOrToken::Node(node)) if ast::Item::can_cast(node.kind()) => { match ast::Item::cast(node.clone()) { - Some(ast::Item::MacroRules(mac)) => { - assert_eq!(current_macro, Some(mac.into())); - current_macro = None; - macro_highlighter = MacroHighlighter::default(); - } - Some(ast::Item::MacroDef(mac)) => { - assert_eq!(current_macro, Some(mac.into())); - current_macro = None; - macro_highlighter = MacroHighlighter::default(); - } Some(item) if attr_or_derive_item.as_ref().is_some_and(|it| *it.item() == item) => { @@ -379,12 +354,6 @@ fn traverse( } }; - if current_macro.is_some() { - if let Some(tok) = element.as_token() { - macro_highlighter.advance(tok); - } - } - let element = match element.clone() { NodeOrToken::Node(n) => match ast::NameLike::cast(n) { Some(n) => NodeOrToken::Node(n), @@ -392,7 +361,7 @@ fn traverse( }, NodeOrToken::Token(t) => NodeOrToken::Token(t), }; - let token = element.as_token().cloned(); + let original_token = element.as_token().cloned(); // Descending tokens into macros is expensive even if no descending occurs, so make sure // that we actually are in a position where descending is possible. @@ -405,144 +374,52 @@ fn traverse( let descended_element = if in_macro { // Attempt to descend tokens into macro-calls. - let res = match element { - NodeOrToken::Token(token) if token.kind() != COMMENT => { - let ranker = Ranker::from_token(&token); - - let mut t = None; - let mut r = 0; - sema.descend_into_macros_breakable( - InRealFile::new(file_id, token.clone()), - |tok, _ctx| { - // FIXME: Consider checking ctx transparency for being opaque? - let tok = tok.value; - let my_rank = ranker.rank_token(&tok); - - if my_rank >= Ranker::MAX_RANK { - // a rank of 0b1110 means that we have found a maximally interesting - // token so stop early. - t = Some(tok); - return ControlFlow::Break(()); - } - - // r = r.max(my_rank); - // t = Some(t.take_if(|_| r < my_rank).unwrap_or(tok)); - match &mut t { - Some(prev) if r < my_rank => { - *prev = tok; - r = my_rank; - } - Some(_) => (), - None => { - r = my_rank; - t = Some(tok) - } - } - ControlFlow::Continue(()) - }, - ); - - let token = t.unwrap_or(token); - match token.parent().and_then(ast::NameLike::cast) { - // Remap the token into the wrapping single token nodes - Some(parent) => match (token.kind(), parent.syntax().kind()) { - (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent), - (T![self] | T![super] | T![crate] | T![Self], NAME_REF) => { - NodeOrToken::Node(parent) - } - (INT_NUMBER, NAME_REF) => NodeOrToken::Node(parent), - (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent), - _ => NodeOrToken::Token(token), - }, - None => NodeOrToken::Token(token), - } - } - e => e, - }; - res + match element { + NodeOrToken::Token(token) => descend_token(sema, file_id, token), + n => n, + } } else { element }; - // FIXME: do proper macro def highlighting https://github.com/rust-lang/rust-analyzer/issues/6232 - // Skip metavariables from being highlighted to prevent keyword highlighting in them - if descended_element.as_token().and_then(|t| macro_highlighter.highlight(t)).is_some() { - continue; - } - // string highlight injections, note this does not use the descended element as proc-macros // can rewrite string literals which invalidates our indices - if let (Some(token), Some(descended_token)) = (token, descended_element.as_token()) { - if ast::String::can_cast(token.kind()) && ast::String::can_cast(descended_token.kind()) - { - let string = ast::String::cast(token); - let string_to_highlight = ast::String::cast(descended_token.clone()); - if let Some((string, expanded_string)) = string.zip(string_to_highlight) { - if string.is_raw() - && inject::ra_fixture(hl, sema, config, &string, &expanded_string).is_some() - { - continue; - } - highlight_format_string( - hl, - sema, - krate, - &string, - &expanded_string, - range, - file_id.edition(), - ); - - if !string.is_raw() { - highlight_escape_string(hl, &string, range.start()); - } - } - } else if ast::ByteString::can_cast(token.kind()) - && ast::ByteString::can_cast(descended_token.kind()) - { - if let Some(byte_string) = ast::ByteString::cast(token) { - if !byte_string.is_raw() { - highlight_escape_string(hl, &byte_string, range.start()); - } - } - } else if ast::CString::can_cast(token.kind()) - && ast::CString::can_cast(descended_token.kind()) - { - if let Some(c_string) = ast::CString::cast(token) { - if !c_string.is_raw() { - highlight_escape_string(hl, &c_string, range.start()); - } - } - } else if ast::Char::can_cast(token.kind()) - && ast::Char::can_cast(descended_token.kind()) - { - let Some(char) = ast::Char::cast(token) else { - continue; - }; - - highlight_escape_char(hl, &char, range.start()) - } else if ast::Byte::can_cast(token.kind()) - && ast::Byte::can_cast(descended_token.kind()) - { - let Some(byte) = ast::Byte::cast(token) else { - continue; - }; - - highlight_escape_byte(hl, &byte, range.start()) + if let (Some(original_token), Some(descended_token)) = + (original_token, descended_element.as_token()) + { + let control_flow = string_injections( + hl, + sema, + config, + file_id, + krate, + original_token, + descended_token, + ); + if control_flow.is_break() { + continue; } } let element = match descended_element { - NodeOrToken::Node(name_like) => highlight::name_like( - sema, - krate, - &mut bindings_shadow_count, - config.syntactic_name_ref_highlighting, - name_like, - file_id.edition(), - ), + NodeOrToken::Node(name_like) => { + let hl = highlight::name_like( + sema, + krate, + &mut bindings_shadow_count, + config.syntactic_name_ref_highlighting, + name_like, + file_id.edition(), + ); + if hl.is_some() && !in_macro { + // skip highlighting the contained token of our name-like node + // as that would potentially overwrite our result + preorder.skip_subtree(); + } + hl + } NodeOrToken::Token(token) => { - highlight::token(sema, token, file_id.edition()).zip(Some(None)) + highlight::token(sema, token, file_id.edition(), tt_level > 0).zip(Some(None)) } }; if let Some((mut highlight, binding_hash)) = element { @@ -551,13 +428,6 @@ fn traverse( // let the editor do its highlighting for these tokens instead continue; } - if highlight.tag == HlTag::UnresolvedReference - && matches!(attr_or_derive_item, Some(AttrOrDerive::Derive(_)) if inside_attribute) - { - // do not emit unresolved references in derive helpers if the token mapping maps to - // something unresolvable. FIXME: There should be a way to prevent that - continue; - } // apply config filtering if !filter_by_config(&mut highlight, config) { @@ -579,6 +449,115 @@ fn traverse( } } +fn string_injections( + hl: &mut Highlights, + sema: &Semantics<'_, RootDatabase>, + config: HighlightConfig, + file_id: EditionedFileId, + krate: hir::Crate, + token: SyntaxToken, + descended_token: &SyntaxToken, +) -> ControlFlow<()> { + if ast::String::can_cast(token.kind()) && ast::String::can_cast(descended_token.kind()) { + let string = ast::String::cast(token); + let string_to_highlight = ast::String::cast(descended_token.clone()); + if let Some((string, descended_string)) = string.zip(string_to_highlight) { + if string.is_raw() + && inject::ra_fixture(hl, sema, config, &string, &descended_string).is_some() + { + return ControlFlow::Break(()); + } + highlight_format_string(hl, sema, krate, &string, &descended_string, file_id.edition()); + + if !string.is_raw() { + highlight_escape_string(hl, &string); + } + } + } else if ast::ByteString::can_cast(token.kind()) + && ast::ByteString::can_cast(descended_token.kind()) + { + if let Some(byte_string) = ast::ByteString::cast(token) { + if !byte_string.is_raw() { + highlight_escape_string(hl, &byte_string); + } + } + } else if ast::CString::can_cast(token.kind()) && ast::CString::can_cast(descended_token.kind()) + { + if let Some(c_string) = ast::CString::cast(token) { + if !c_string.is_raw() { + highlight_escape_string(hl, &c_string); + } + } + } else if ast::Char::can_cast(token.kind()) && ast::Char::can_cast(descended_token.kind()) { + let Some(char) = ast::Char::cast(token) else { + return ControlFlow::Break(()); + }; + + highlight_escape_char(hl, &char) + } else if ast::Byte::can_cast(token.kind()) && ast::Byte::can_cast(descended_token.kind()) { + let Some(byte) = ast::Byte::cast(token) else { + return ControlFlow::Break(()); + }; + + highlight_escape_byte(hl, &byte) + } + ControlFlow::Continue(()) +} + +fn descend_token( + sema: &Semantics<'_, RootDatabase>, + file_id: EditionedFileId, + token: SyntaxToken, +) -> NodeOrToken { + if token.kind() == COMMENT { + return NodeOrToken::Token(token); + } + let ranker = Ranker::from_token(&token); + + let mut t = None; + let mut r = 0; + sema.descend_into_macros_breakable(InRealFile::new(file_id, token.clone()), |tok, _ctx| { + // FIXME: Consider checking ctx transparency for being opaque? + let tok = tok.value; + let my_rank = ranker.rank_token(&tok); + + if my_rank >= Ranker::MAX_RANK { + // a rank of 0b1110 means that we have found a maximally interesting + // token so stop early. + t = Some(tok); + return ControlFlow::Break(()); + } + + // r = r.max(my_rank); + // t = Some(t.take_if(|_| r < my_rank).unwrap_or(tok)); + match &mut t { + Some(prev) if r < my_rank => { + *prev = tok; + r = my_rank; + } + Some(_) => (), + None => { + r = my_rank; + t = Some(tok) + } + } + ControlFlow::Continue(()) + }); + + let token = t.unwrap_or(token); + match token.parent().and_then(ast::NameLike::cast) { + // Remap the token into the wrapping single token nodes + Some(parent) => match (token.kind(), parent.syntax().kind()) { + (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent), + (T![self] | T![super] | T![crate] | T![Self], NAME_REF) => NodeOrToken::Node(parent), + (INT_NUMBER, NAME_REF) => NodeOrToken::Node(parent), + (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent), + _ => NodeOrToken::Token(token), + }, + None => NodeOrToken::Token(token), + } +} + fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool { match &mut highlight.tag { HlTag::StringLiteral if !config.strings => return false, diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs index 552ce9cd8c3a..094f88f3a864 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs @@ -4,12 +4,9 @@ use crate::{HlRange, HlTag}; use syntax::ast::{Byte, Char, IsString}; use syntax::{AstToken, TextRange, TextSize}; -pub(super) fn highlight_escape_string( - stack: &mut Highlights, - string: &T, - start: TextSize, -) { +pub(super) fn highlight_escape_string(stack: &mut Highlights, string: &T) { let text = string.text(); + let start = string.syntax().text_range().start(); string.escaped_char_ranges(&mut |piece_range, char| { if text[piece_range.start().into()..].starts_with('\\') { let highlight = match char { @@ -25,7 +22,7 @@ pub(super) fn highlight_escape_string( }); } -pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start: TextSize) { +pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char) { if char.value().is_err() { // We do not emit invalid escapes highlighting here. The lexer would likely be in a bad // state and this token contains junk, since `'` is not a reliable delimiter (consider @@ -42,11 +39,14 @@ pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start: return; }; - let range = TextRange::at(start + TextSize::from(1), TextSize::from(text.len() as u32)); + let range = TextRange::at( + char.syntax().text_range().start() + TextSize::from(1), + TextSize::from(text.len() as u32), + ); stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) } -pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte, start: TextSize) { +pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte) { if byte.value().is_err() { // See `highlight_escape_char` for why no error highlighting here. return; @@ -61,6 +61,9 @@ pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte, start: return; }; - let range = TextRange::at(start + TextSize::from(2), TextSize::from(text.len() as u32)); + let range = TextRange::at( + byte.syntax().text_range().start() + TextSize::from(2), + TextSize::from(text.len() as u32), + ); stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs index 43a6bdad7e9b..c63043621c27 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs @@ -5,7 +5,7 @@ use ide_db::{ SymbolKind, }; use span::Edition; -use syntax::{ast, TextRange}; +use syntax::{ast, AstToken}; use crate::{ syntax_highlighting::{highlight::highlight_def, highlights::Highlights}, @@ -18,15 +18,15 @@ pub(super) fn highlight_format_string( krate: hir::Crate, string: &ast::String, expanded_string: &ast::String, - range: TextRange, edition: Edition, ) { if is_format_string(expanded_string) { + let start = string.syntax().text_range().start(); // FIXME: Replace this with the HIR info we have now. lex_format_specifiers(string, &mut |piece_range, kind| { if let Some(highlight) = highlight_format_specifier(kind) { stack.add(HlRange { - range: piece_range + range.start(), + range: piece_range + start, highlight: highlight.into(), binding_hash: None, }); diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index 194fde116011..316fa5b6e9e5 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs @@ -23,6 +23,7 @@ pub(super) fn token( sema: &Semantics<'_, RootDatabase>, token: SyntaxToken, edition: Edition, + in_tt: bool, ) -> Option { if let Some(comment) = ast::Comment::cast(token.clone()) { let h = HlTag::Comment; @@ -40,13 +41,20 @@ pub(super) fn token( INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(), BYTE => HlTag::ByteLiteral.into(), CHAR => HlTag::CharLiteral.into(), - IDENT if token.parent().and_then(ast::TokenTree::cast).is_some() => { + IDENT if in_tt => { // from this point on we are inside a token tree, this only happens for identifiers // that were not mapped down into macro invocations HlTag::None.into() } p if p.is_punct() => punctuation(sema, token, p), - k if k.is_keyword(edition) => keyword(sema, token, k)?, + k if k.is_keyword(edition) => { + if in_tt && token.prev_token().is_some_and(|t| t.kind() == T![$]) { + // we are likely within a macro definition where our keyword is a fragment name + HlTag::None.into() + } else { + keyword(sema, token, k)? + } + } _ => return None, }; Some(highlight) @@ -214,12 +222,6 @@ fn keyword( T![true] | T![false] => HlTag::BoolLiteral.into(), // crate is handled just as a token if it's in an `extern crate` T![crate] if parent_matches::(&token) => h, - // self, crate, super and `Self` are handled as either a Name or NameRef already, unless they - // are inside unmapped token trees - T![self] | T![crate] | T![super] | T![Self] if parent_matches::(&token) => { - return None - } - T![self] if parent_matches::(&token) => return None, T![ref] => match token.parent().and_then(ast::IdentPat::cast) { Some(ident) if sema.is_unsafe_ident_pat(&ident) => h | HlMod::Unsafe, _ => h, diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/macro_.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/macro_.rs deleted file mode 100644 index b441b4cc90eb..000000000000 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/macro_.rs +++ /dev/null @@ -1,128 +0,0 @@ -//! Syntax highlighting for macro_rules!. -use syntax::{SyntaxKind, SyntaxToken, TextRange, T}; - -use crate::{HlRange, HlTag}; - -#[derive(Default)] -pub(super) struct MacroHighlighter { - state: Option, -} - -impl MacroHighlighter { - pub(super) fn init(&mut self) { - self.state = Some(MacroMatcherParseState::default()); - } - - pub(super) fn advance(&mut self, token: &SyntaxToken) { - if let Some(state) = self.state.as_mut() { - update_macro_state(state, token); - } - } - - pub(super) fn highlight(&self, token: &SyntaxToken) -> Option { - if let Some(state) = self.state.as_ref() { - if matches!(state.rule_state, RuleState::Matcher | RuleState::Expander) { - if let Some(range) = is_metavariable(token) { - return Some(HlRange { - range, - highlight: HlTag::UnresolvedReference.into(), - binding_hash: None, - }); - } - } - } - None - } -} - -struct MacroMatcherParseState { - /// Opening and corresponding closing bracket of the matcher or expander of the current rule - paren_ty: Option<(SyntaxKind, SyntaxKind)>, - paren_level: usize, - rule_state: RuleState, - /// Whether we are inside the outer `{` `}` macro block that holds the rules - in_invoc_body: bool, -} - -impl Default for MacroMatcherParseState { - fn default() -> Self { - MacroMatcherParseState { - paren_ty: None, - paren_level: 0, - in_invoc_body: false, - rule_state: RuleState::None, - } - } -} - -#[derive(Copy, Clone, Debug, PartialEq)] -enum RuleState { - Matcher, - Expander, - Between, - None, -} - -impl RuleState { - fn transition(&mut self) { - *self = match self { - RuleState::Matcher => RuleState::Between, - RuleState::Expander => RuleState::None, - RuleState::Between => RuleState::Expander, - RuleState::None => RuleState::Matcher, - }; - } -} - -fn update_macro_state(state: &mut MacroMatcherParseState, tok: &SyntaxToken) { - if !state.in_invoc_body { - if tok.kind() == T!['{'] || tok.kind() == T!['('] { - state.in_invoc_body = true; - } - return; - } - - match state.paren_ty { - Some((open, close)) => { - if tok.kind() == open { - state.paren_level += 1; - } else if tok.kind() == close { - state.paren_level -= 1; - if state.paren_level == 0 { - state.rule_state.transition(); - state.paren_ty = None; - } - } - } - None => { - match tok.kind() { - T!['('] => { - state.paren_ty = Some((T!['('], T![')'])); - } - T!['{'] => { - state.paren_ty = Some((T!['{'], T!['}'])); - } - T!['['] => { - state.paren_ty = Some((T!['['], T![']'])); - } - _ => (), - } - if state.paren_ty.is_some() { - state.paren_level = 1; - state.rule_state.transition(); - } - } - } -} - -fn is_metavariable(token: &SyntaxToken) -> Option { - match token.kind() { - kind if kind.is_any_identifier() => { - if let Some(_dollar) = token.prev_token().filter(|t| t.kind() == T![$]) { - return Some(token.text_range()); - } - } - _ => (), - }; - None -} diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index eb77c14c2a57..5b5c51a3631b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html @@ -156,7 +156,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } /// ``` -/// macro_rules! noop { ($expr:expr) => { $expr }} +/// macro_rules! noop { ($expr:expr) => { $expr }} /// noop!(1); /// ``` macro_rules! noop { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index 9477d0d1b877..b5e950ffc23c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html @@ -151,7 +151,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let bar = Foo::baz; let baz = (-42,); - let baz = -baz.0; + let baz = -baz.0; let _ = !true; From b0e3526f322cdd200b38b03da4625e7d87a482dd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 1 Mar 2025 17:23:51 +0100 Subject: [PATCH 508/991] More precise macro modifiers for syntax highlighting --- .../hir-def/src/macro_expansion_tests/mod.rs | 10 +- .../crates/hir-expand/src/files.rs | 10 +- .../crates/hir-expand/src/lib.rs | 54 ++++---- src/tools/rust-analyzer/crates/hir/src/lib.rs | 49 ++++---- .../rust-analyzer/crates/ide-db/src/lib.rs | 6 +- .../rust-analyzer/crates/ide-db/src/search.rs | 4 +- .../rust-analyzer/crates/ide/src/doc_links.rs | 5 +- .../rust-analyzer/crates/ide/src/moniker.rs | 10 +- .../crates/ide/src/syntax_highlighting.rs | 50 +++----- .../test_data/highlight_asm.html | 20 +-- .../test_data/highlight_attributes.html | 18 +-- .../test_data/highlight_block_mod_items.html | 4 +- .../test_data/highlight_const.html | 4 +- .../test_data/highlight_doctest.html | 6 +- .../test_data/highlight_general.html | 8 +- .../test_data/highlight_injection.html | 2 +- .../test_data/highlight_issue_18089.html | 4 +- .../test_data/highlight_keywords_2015.html | 14 +-- .../test_data/highlight_keywords_2018.html | 14 +-- .../test_data/highlight_keywords_2021.html | 14 +-- .../test_data/highlight_keywords_2024.html | 14 +-- .../test_data/highlight_macros.html | 18 +-- .../test_data/highlight_strings.html | 116 +++++++++--------- .../test_data/highlight_unsafe.html | 8 +- 24 files changed, 231 insertions(+), 231 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index 408d03ff718e..a2d0ba3deb84 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -22,7 +22,7 @@ use hir_expand::{ db::ExpandDatabase, proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind}, span_map::SpanMapRef, - InFile, MacroCallKind, MacroFileId, MacroFileIdExt, + InFile, MacroCallKind, MacroFileId, MacroFileIdExt, MacroKind, }; use intern::Symbol; use itertools::Itertools; @@ -211,7 +211,11 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream if let Some(src) = src { if let Some(file_id) = src.file_id.macro_file() { - if file_id.is_attr_macro(&db) || file_id.is_custom_derive(&db) { + if let MacroKind::Derive + | MacroKind::DeriveBuiltIn + | MacroKind::Attr + | MacroKind::AttrBuiltIn = file_id.kind(&db) + { let call = file_id.call_node(&db); let mut show_spans = false; let mut show_ctxt = false; @@ -236,7 +240,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream for impl_id in def_map[local_id].scope.impls() { let src = impl_id.lookup(&db).source(&db); if let Some(macro_file) = src.file_id.macro_file() { - if macro_file.is_builtin_derive(&db) { + if let MacroKind::DeriveBuiltIn | MacroKind::Derive = macro_file.kind(&db) { let pp = pretty_print_macro_expansion( src.value.syntax().clone(), db.span_map(macro_file.into()).as_ref(), diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs index 13ddb0d4acce..f3bcc7726822 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs @@ -10,7 +10,7 @@ use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, use crate::{ db::{self, ExpandDatabase}, - map_node_range_up, map_node_range_up_rooted, span_for_offset, MacroFileIdExt, + map_node_range_up, map_node_range_up_rooted, span_for_offset, MacroFileIdExt, MacroKind, }; /// `InFile` stores a value of `T` inside a particular file/syntax tree. @@ -276,7 +276,11 @@ impl> InFile { HirFileIdRepr::FileId(file_id) => { return Some(InRealFile { file_id, value: self.value.borrow().clone() }) } - HirFileIdRepr::MacroFile(m) if m.is_attr_macro(db) => m, + HirFileIdRepr::MacroFile(m) + if matches!(m.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn) => + { + m + } _ => return None, }; @@ -453,7 +457,7 @@ impl InFile { } HirFileIdRepr::MacroFile(m) => m, }; - if !file_id.is_attr_macro(db) { + if !matches!(file_id.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn) { return None; } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index 2c664029f615..41603e3c92e3 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -416,6 +416,24 @@ impl HirFileIdExt for HirFileId { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum MacroKind { + /// `macro_rules!` or Macros 2.0 macro. + Declarative, + /// A built-in function-like macro. + DeclarativeBuiltIn, + /// A custom derive. + Derive, + /// A builtin-in derive. + DeriveBuiltIn, + /// A procedural attribute macro. + Attr, + /// A built-in attribute macro. + AttrBuiltIn, + /// A function-like procedural macro. + ProcMacro, +} + pub trait MacroFileIdExt { fn is_env_or_option_env(&self, db: &dyn ExpandDatabase) -> bool; fn is_include_like_macro(&self, db: &dyn ExpandDatabase) -> bool; @@ -427,15 +445,12 @@ pub trait MacroFileIdExt { fn expansion_info(self, db: &dyn ExpandDatabase) -> ExpansionInfo; - fn is_builtin_derive(&self, db: &dyn ExpandDatabase) -> bool; - fn is_custom_derive(&self, db: &dyn ExpandDatabase) -> bool; + fn kind(&self, db: &dyn ExpandDatabase) -> MacroKind; /// Return whether this file is an include macro fn is_include_macro(&self, db: &dyn ExpandDatabase) -> bool; fn is_eager(&self, db: &dyn ExpandDatabase) -> bool; - /// Return whether this file is an attr macro - fn is_attr_macro(&self, db: &dyn ExpandDatabase) -> bool; /// Return whether this file is the pseudo expansion of the derive attribute. /// See [`crate::builtin_attr_macro::derive_attr_expand`]. @@ -468,18 +483,18 @@ impl MacroFileIdExt for MacroFileId { ExpansionInfo::new(db, self) } - fn is_custom_derive(&self, db: &dyn ExpandDatabase) -> bool { - matches!( - db.lookup_intern_macro_call(self.macro_call_id).def.kind, - MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive) - ) - } - - fn is_builtin_derive(&self, db: &dyn ExpandDatabase) -> bool { - matches!( - db.lookup_intern_macro_call(self.macro_call_id).def.kind, - MacroDefKind::BuiltInDerive(..) - ) + fn kind(&self, db: &dyn ExpandDatabase) -> MacroKind { + match db.lookup_intern_macro_call(self.macro_call_id).def.kind { + MacroDefKind::Declarative(..) => MacroKind::Declarative, + MacroDefKind::BuiltIn(..) | MacroDefKind::BuiltInEager(..) => { + MacroKind::DeclarativeBuiltIn + } + MacroDefKind::BuiltInDerive(..) => MacroKind::DeriveBuiltIn, + MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive) => MacroKind::Derive, + MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr) => MacroKind::Attr, + MacroDefKind::ProcMacro(_, _, ProcMacroKind::Bang) => MacroKind::ProcMacro, + MacroDefKind::BuiltInAttr(..) => MacroKind::AttrBuiltIn, + } } fn is_include_macro(&self, db: &dyn ExpandDatabase) -> bool { @@ -507,13 +522,6 @@ impl MacroFileIdExt for MacroFileId { } } - fn is_attr_macro(&self, db: &dyn ExpandDatabase) -> bool { - matches!( - db.lookup_intern_macro_call(self.macro_call_id).def.kind, - MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr) - ) - } - fn is_derive_attr_pseudo_expansion(&self, db: &dyn ExpandDatabase) -> bool { let loc = db.lookup_intern_macro_call(self.macro_call_id); loc.def.is_attribute_derive() diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 727d31cffb51..55448d4ae868 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -142,7 +142,7 @@ pub use { name::Name, prettify_macro_expansion, proc_macro::{ProcMacros, ProcMacrosBuilder}, - tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt, + tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt, MacroKind, }, hir_ty::{ consteval::ConstEvalError, @@ -699,7 +699,10 @@ impl Module { let source_map = tree_source_maps.impl_(loc.id.value).item(); let node = &tree[loc.id.value]; let file_id = loc.id.file_id(); - if file_id.macro_file().is_some_and(|it| it.is_builtin_derive(db.upcast())) { + if file_id + .macro_file() + .is_some_and(|it| it.kind(db.upcast()) == MacroKind::DeriveBuiltIn) + { // these expansion come from us, diagnosing them is a waste of resources // FIXME: Once we diagnose the inputs to builtin derives, we should at least extract those diagnostics somehow continue; @@ -3049,20 +3052,6 @@ impl BuiltinType { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum MacroKind { - /// `macro_rules!` or Macros 2.0 macro. - Declarative, - /// A built-in or custom derive. - Derive, - /// A built-in function-like macro. - BuiltIn, - /// A procedural attribute macro. - Attr, - /// A function-like procedural macro. - ProcMacro, -} - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Macro { pub(crate) id: MacroId, @@ -3093,15 +3082,19 @@ impl Macro { match self.id { MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander { MacroExpander::Declarative => MacroKind::Declarative, - MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn, - MacroExpander::BuiltInAttr(_) => MacroKind::Attr, - MacroExpander::BuiltInDerive(_) => MacroKind::Derive, + MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => { + MacroKind::DeclarativeBuiltIn + } + MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn, + MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn, }, MacroId::MacroRulesId(it) => match it.lookup(db.upcast()).expander { MacroExpander::Declarative => MacroKind::Declarative, - MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn, - MacroExpander::BuiltInAttr(_) => MacroKind::Attr, - MacroExpander::BuiltInDerive(_) => MacroKind::Derive, + MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => { + MacroKind::DeclarativeBuiltIn + } + MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn, + MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn, }, MacroId::ProcMacroId(it) => match it.lookup(db.upcast()).kind { ProcMacroKind::CustomDerive => MacroKind::Derive, @@ -3112,10 +3105,10 @@ impl Macro { } pub fn is_fn_like(&self, db: &dyn HirDatabase) -> bool { - match self.kind(db) { - MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true, - MacroKind::Attr | MacroKind::Derive => false, - } + matches!( + self.kind(db), + MacroKind::Declarative | MacroKind::DeclarativeBuiltIn | MacroKind::ProcMacro + ) } pub fn is_builtin_derive(&self, db: &dyn HirDatabase) -> bool { @@ -3155,11 +3148,11 @@ impl Macro { } pub fn is_attr(&self, db: &dyn HirDatabase) -> bool { - matches!(self.kind(db), MacroKind::Attr) + matches!(self.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn) } pub fn is_derive(&self, db: &dyn HirDatabase) -> bool { - matches!(self.kind(db), MacroKind::Derive) + matches!(self.kind(db), MacroKind::Derive | MacroKind::DeriveBuiltIn) } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 3a29232d331f..96115eee6dc2 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -252,10 +252,10 @@ pub enum SymbolKind { impl From for SymbolKind { fn from(it: hir::MacroKind) -> Self { match it { - hir::MacroKind::Declarative | hir::MacroKind::BuiltIn => SymbolKind::Macro, + hir::MacroKind::Declarative | hir::MacroKind::DeclarativeBuiltIn => SymbolKind::Macro, hir::MacroKind::ProcMacro => SymbolKind::ProcMacro, - hir::MacroKind::Derive => SymbolKind::Derive, - hir::MacroKind::Attr => SymbolKind::Attribute, + hir::MacroKind::Derive | hir::MacroKind::DeriveBuiltIn => SymbolKind::Derive, + hir::MacroKind::Attr | hir::MacroKind::AttrBuiltIn => SymbolKind::Attribute, } } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index 7963e8ae4f78..02cd8b8bdf51 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -373,7 +373,9 @@ impl Definition { SearchScope::krate(db, module.krate()) } } - hir::MacroKind::BuiltIn => SearchScope::crate_graph(db), + hir::MacroKind::AttrBuiltIn + | hir::MacroKind::DeriveBuiltIn + | hir::MacroKind::DeclarativeBuiltIn => SearchScope::crate_graph(db), hir::MacroKind::Derive | hir::MacroKind::Attr | hir::MacroKind::ProcMacro => { SearchScope::reverse_dependencies(db, module.krate()) } diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index d88f7c5033e0..8d2ca33bf254 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -635,12 +635,13 @@ fn filename_and_frag_for_def( } Definition::Macro(mac) => match mac.kind(db) { hir::MacroKind::Declarative - | hir::MacroKind::BuiltIn + | hir::MacroKind::AttrBuiltIn + | hir::MacroKind::DeclarativeBuiltIn | hir::MacroKind::Attr | hir::MacroKind::ProcMacro => { format!("macro.{}.html", mac.name(db).as_str()) } - hir::MacroKind::Derive => { + hir::MacroKind::Derive | hir::MacroKind::DeriveBuiltIn => { format!("derive.{}.html", mac.name(db).as_str()) } }, diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs index 66ea49a98a08..25d12a4c0b4f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs +++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs @@ -184,11 +184,11 @@ pub(crate) fn def_to_kind(db: &RootDatabase, def: Definition) -> SymbolInformati match def { Definition::Macro(it) => match it.kind(db) { - MacroKind::Declarative => Macro, - MacroKind::Derive => Attribute, - MacroKind::BuiltIn => Macro, - MacroKind::Attr => Attribute, - MacroKind::ProcMacro => Macro, + MacroKind::Derive + | MacroKind::DeriveBuiltIn + | MacroKind::AttrBuiltIn + | MacroKind::Attr => Attribute, + MacroKind::Declarative | MacroKind::DeclarativeBuiltIn | MacroKind::ProcMacro => Macro, }, Definition::Field(..) | Definition::TupleField(..) => Field, Definition::Module(..) | Definition::Crate(..) => Module, diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index 6c5e81ae667a..1ce42205d5aa 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -14,7 +14,7 @@ mod tests; use std::ops::ControlFlow; -use hir::{InFile, InRealFile, Name, Semantics}; +use hir::{InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics}; use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind}; use span::EditionedFileId; use syntax::{ @@ -253,8 +253,6 @@ fn traverse( // FIXME: these are not perfectly accurate, we determine them by the real file's syntax tree // an attribute nested in a macro call will not emit `inside_attribute` let mut inside_attribute = false; - let mut inside_macro_call = false; - let mut inside_proc_macro_call = false; // Walk all nodes, keeping track of whether we are inside a macro or not. // If in macro, expand it first and highlight the expanded code. @@ -291,11 +289,6 @@ fn traverse( ast::Item::Fn(_) | ast::Item::Const(_) | ast::Item::Static(_) => { bindings_shadow_count.clear() } - ast::Item::MacroCall(ref macro_call) => { - inside_macro_call = true; - inside_proc_macro_call = - sema.is_proc_macro_call(InFile::new(file_id.into(), macro_call)); - } _ => (), } @@ -330,10 +323,6 @@ fn traverse( { attr_or_derive_item = None; } - Some(ast::Item::MacroCall(_)) => { - inside_macro_call = false; - inside_proc_macro_call = false; - } _ => (), } } @@ -375,17 +364,17 @@ fn traverse( let descended_element = if in_macro { // Attempt to descend tokens into macro-calls. match element { - NodeOrToken::Token(token) => descend_token(sema, file_id, token), - n => n, + NodeOrToken::Token(token) => descend_token(sema, InRealFile::new(file_id, token)), + n => InFile::new(file_id.into(), n), } } else { - element + InFile::new(file_id.into(), element) }; // string highlight injections, note this does not use the descended element as proc-macros // can rewrite string literals which invalidates our indices if let (Some(original_token), Some(descended_token)) = - (original_token, descended_element.as_token()) + (original_token, descended_element.value.as_token()) { let control_flow = string_injections( hl, @@ -401,7 +390,7 @@ fn traverse( } } - let element = match descended_element { + let element = match descended_element.value { NodeOrToken::Node(name_like) => { let hl = highlight::name_like( sema, @@ -437,8 +426,9 @@ fn traverse( if inside_attribute { highlight |= HlMod::Attribute } - if inside_macro_call && tt_level > 0 { - if inside_proc_macro_call { + if let Some(m) = descended_element.file_id.macro_file() { + if let MacroKind::ProcMacro | MacroKind::Attr | MacroKind::Derive = m.kind(sema.db) + { highlight |= HlMod::ProcMacro } highlight |= HlMod::Macro @@ -506,20 +496,18 @@ fn string_injections( fn descend_token( sema: &Semantics<'_, RootDatabase>, - file_id: EditionedFileId, - token: SyntaxToken, -) -> NodeOrToken { - if token.kind() == COMMENT { - return NodeOrToken::Token(token); + token: InRealFile, +) -> InFile> { + if token.value.kind() == COMMENT { + return token.map(NodeOrToken::Token).into(); } - let ranker = Ranker::from_token(&token); + let ranker = Ranker::from_token(&token.value); let mut t = None; let mut r = 0; - sema.descend_into_macros_breakable(InRealFile::new(file_id, token.clone()), |tok, _ctx| { + sema.descend_into_macros_breakable(token.clone(), |tok, _ctx| { // FIXME: Consider checking ctx transparency for being opaque? - let tok = tok.value; - let my_rank = ranker.rank_token(&tok); + let my_rank = ranker.rank_token(&tok.value); if my_rank >= Ranker::MAX_RANK { // a rank of 0b1110 means that we have found a maximally interesting @@ -544,8 +532,8 @@ fn descend_token( ControlFlow::Continue(()) }); - let token = t.unwrap_or(token); - match token.parent().and_then(ast::NameLike::cast) { + let token = t.unwrap_or_else(|| token.into()); + token.map(|token| match token.parent().and_then(ast::NameLike::cast) { // Remap the token into the wrapping single token nodes Some(parent) => match (token.kind(), parent.syntax().kind()) { (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent), @@ -555,7 +543,7 @@ fn descend_token( _ => NodeOrToken::Token(token), }, None => NodeOrToken::Token(token), - } + }) } fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html index 15a6386aa3c8..2bc22f960bd5 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html @@ -49,26 +49,26 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd unsafe { let foo = 1; let mut o = 0; - core::arch::asm!( + core::arch::asm!( "%input = OpLoad _ {0}", concat!("%result = ", "bar", " _ %input"), "OpStore {1} %result", in(reg) &foo, in(reg) &mut o, - ); + ); let thread_id: usize; - core::arch::asm!(" + core::arch::asm!(" mov {0}, gs:[0x30] mov {0}, [{0}+0x48] - ", out(reg) thread_id, options(pure, readonly, nostack)); + ", out(reg) thread_id, options(pure, readonly, nostack)); static UNMAP_BASE: usize; const MEM_RELEASE: usize; static VirtualFree: usize; const OffPtr: usize; const OffFn: usize; - core::arch::asm!(" + core::arch::asm!(" push {free_type} push {free_size} push {base} @@ -92,7 +92,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd base = sym UNMAP_BASE, options(noreturn), - ); + ); } } // taken from https://github.com/rust-embedded/cortex-m/blob/47921b51f8b960344fcfa1255a50a0d19efcde6d/cortex-m/src/asm.rs#L254-L274 @@ -101,19 +101,19 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd // Ensure thumb mode is set. let rv = (rv as u32) | 1; let msp = msp as u32; - core::arch::asm!( + core::arch::asm!( "mrs {tmp}, CONTROL", "bics {tmp}, {spsel}", "msr CONTROL, {tmp}", "isb", "msr MSP, {msp}", "bx {rv}", - // `out(reg) _` is not permitted in a `noreturn` asm! call, - // so instead use `in(reg) 0` and don't restore it afterwards. + // `out(reg) _` is not permitted in a `noreturn` asm! call, + // so instead use `in(reg) 0` and don't restore it afterwards. tmp = in(reg) 0, spsel = in(reg) 2, msp = in(reg) msp, rv = in(reg) rv, options(noreturn, nomem, nostack), - ); + ); }